diff --git a/.htaccess b/.htaccess new file mode 100644 index 0000000..0f89e7c --- /dev/null +++ b/.htaccess @@ -0,0 +1,9 @@ +AddDefaultCharset utf-8 + +RewriteEngine on +RewriteBase / + +RewriteCond %{REQUEST_FILENAME} !-f +RewriteCond %{REQUEST_FILENAME} !-d + +RewriteRule ^(.*)$ index.php \ No newline at end of file diff --git a/123.txt b/123.txt new file mode 100644 index 0000000..5a23112 --- /dev/null +++ b/123.txt @@ -0,0 +1,199 @@ +$print: +array(16) { + ["id"]=> + string(1) "4" + ["name"]=> + string(14) "MININT-15MK94U" + ["model"]=> + string(10) "HP LJ 3030" + ["unit"]=> + string(9) "0000-0445" + ["inventar"]=> + string(7) "3-21333" + ["sn"]=> + string(10) "CNBF033770" + ["floor"]=> + string(10) "9 этаж" + ["id_fl"]=> + string(1) "5" + ["department"]=> + string(18) "Аналитики" + ["id_dep"]=> + string(1) "9" + ["status"]=> + string(15) "В работе" + ["id_st"]=> + string(1) "1" + ["cartrige"]=> + string(3) "12a" + ["id_cart"]=> + string(1) "2" + ["img"]=> + string(0) "" + ["functions"]=> + array(4) { + [0]=> + array(3) { + ["id"]=> + string(1) "1" + ["name"]=> + string(12) "Печать" + ["description"]=> + NULL + } + [1]=> + array(3) { + ["id"]=> + string(1) "3" + ["name"]=> + string(34) "Сканирование на ПК" + ["description"]=> + NULL + } + [2]=> + array(3) { + ["id"]=> + string(1) "4" + ["name"]=> + string(40) "Сканирование на почту" + ["description"]=> + NULL + } + [3]=> + array(3) { + ["id"]=> + string(1) "5" + ["name"]=> + string(49) "Двустороннее сканирование" + ["description"]=> + NULL + } + } +} + + +$_POST: +array(11) { + ["name"]=> + string(15) "MININT-15MK94U1" + ["unit"]=> + string(10) "0000-04452" + ["model"]=> + string(11) "HP LJ 30303" + ["sn"]=> + string(11) "CNBF0337704" + ["inventar"]=> + string(8) "3-213335" + ["id_floor"]=> + string(1) "1" + ["id_department"]=> + string(1) "1" + ["id_cartrige"]=> + string(1) "1" + ["id_status"]=> + string(1) "2" + ["id_functions"]=> + array(3) { + [0]=> + string(1) "1" + [1]=> + string(1) "3" + [2]=> + string(1) "4" + } + ["submit"]=> + string(0) "" +} + +checking +$up: +array(10) { + [1]=> + array(3) { + ["object"]=> + string(23) "Имя принтера" + ["old_data"]=> + string(14) "MININT-15MK94U" + ["new_data"]=> + string(15) "MININT-15MK94U1" + } + [2]=> + array(3) { + ["object"]=> + string(29) "Модель принтера" + ["old_data"]=> + string(10) "HP LJ 3030" + ["new_data"]=> + string(11) "HP LJ 30303" + } + [3]=> + array(3) { + ["object"]=> + string(32) "Номер UNIT принтера" + ["old_data"]=> + string(9) "0000-0445" + ["new_data"]=> + string(10) "0000-04452" + } + [4]=> + array(3) { + ["object"]=> + string(50) "Инвентарный номер принтера" + ["old_data"]=> + string(7) "3-21333" + ["new_data"]=> + string(8) "3-213335" + } + [5]=> + array(3) { + ["object"]=> + string(44) "Серийный номер принтера" + ["old_data"]=> + string(10) "CNBF033770" + ["new_data"]=> + string(11) "CNBF0337704" + } + [6]=> + array(3) { + ["object"]=> + string(8) "Этаж" + ["old_data"]=> + string(1) "5" + ["new_data"]=> + string(1) "1" + } + [7]=> + array(3) { + ["object"]=> + string(10) "Отдел" + ["old_data"]=> + string(1) "9" + ["new_data"]=> + string(1) "1" + } + [8]=> + array(3) { + ["object"]=> + string(16) "Картридж" + ["old_data"]=> + string(1) "2" + ["new_data"]=> + string(1) "1" + } + [9]=> + array(3) { + ["object"]=> + string(12) "Статус" + ["old_data"]=> + string(1) "1" + ["new_data"]=> + string(1) "2" + } + [10]=> + array(2) { + ["object"]=> + string(29) "Функции удалили" + ["old_data"]=> + string(1) "5" + } +} diff --git a/components/Autoload.php b/components/Autoload.php new file mode 100644 index 0000000..fa62f0b --- /dev/null +++ b/components/Autoload.php @@ -0,0 +1,21 @@ + "дп", + "pm" => "пп", + "AM" => "ДП", + "PM" => "ПП", + "Monday" => "Понедельник", + "Mon" => "Пн", + "Tuesday" => "Вторник", + "Tue" => "Вт", + "Wednesday" => "Среда", + "Wed" => "Ср", + "Thursday" => "Четверг", + "Thu" => "Чт", + "Friday" => "Пятница", + "Fri" => "Пт", + "Saturday" => "Суббота", + "Sat" => "Сб", + "Sunday" => "Воскресенье", + "Sun" => "Вс", + "January" => "Января", + "Jan" => "Янв", + "February" => "Февраля", + "Feb" => "Фев", + "March" => "Марта", + "Mar" => "Мар", + "April" => "Апреля", + "Apr" => "Апр", + "May" => "Мая", + "May" => "Мая", + "June" => "Июня", + "Jun" => "Июн", + "July" => "Июля", + "Jul" => "Июл", + "August" => "Августа", + "Aug" => "Авг", + "September" => "Сентября", + "Sep" => "Сен", + "October" => "Октября", + "Oct" => "Окт", + "November" => "Ноября", + "Nov" => "Ноя", + "December" => "Декабря", + "Dec" => "Дек", + "st" => "ое", + "nd" => "ое", + "rd" => "е", + "th" => "ое" + ); + + + return strtr($date, $translate); + } + + +} diff --git a/components/Db.php b/components/Db.php new file mode 100644 index 0000000..d875b87 --- /dev/null +++ b/components/Db.php @@ -0,0 +1,26 @@ +exec('SET NAMES utf8'); //задаём кодировку ввода/вывода БД + + return $db; + } + +} + +?> \ No newline at end of file diff --git a/components/Icecast.php b/components/Icecast.php new file mode 100644 index 0000000..3381420 --- /dev/null +++ b/components/Icecast.php @@ -0,0 +1,28 @@ +prepare("UPDATE print set img=:img WHERE id = :id"); + $stmt->bindParam(':id', $id_prn, PDO::PARAM_INT); + $stmt->bindParam(':img', $link_img); + + return $stmt->execute(); + } + + public static function checkAndDeleteImg($id_prn){ + + $info_prn = Printer::getPrintByIDFullData($id_prn); + if(!$info_prn['img'] == ""){ + $filename = $info_prn['img']; + rename(ROOT.$filename, ROOT.$filename."_old"); //переименование старого изображения + //unlink(ROOT.$filename); //удаление старого изображения + //echo $info_prn['img']; + //echo ROOT.$filename."old"; + //var_dump($info_prn['img']); + return true; + }else return true; + } +} diff --git a/components/Ldap.php b/components/Ldap.php new file mode 100644 index 0000000..9604e42 --- /dev/null +++ b/components/Ldap.php @@ -0,0 +1,88 @@ +ldaphost = LDAP_HOST; + $this->ldapport = LDAP_PORT; + $this->base = LDAP_BASE; + $this->filter = LDAP_FILTER; + $this->domain = LDAP_DOMAIN; + }*/ + //put your code here + public static function LdapAuth($username, $pass){ + + $paramsPath = ROOT.'/config/ldap_config.php'; + $params = include($paramsPath); + + $login = $username.$params['ldap_domain']; + $password = $pass; + //подсоединяемся к LDAP серверу + $ldap = ldap_connect($params['ldap_host'], $params['ldap_port']) or die("Cant connect to LDAP Server"); + //Включаем LDAP протокол версии 3 + ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3); + if ($ldap){ + // Пытаемся войти в LDAP при помощи введенных логина и пароля + $bind = ldap_bind($ldap,$login,$password); + if ($bind) + { + // Проверим, является ли пользователь членом указанной группы. + $result = ldap_search($ldap,$params['ldap_base'],$params['ldap_filter'].$username);//"(||(memberOf=".$memberof.")(".$filter.$username."))" + // Получаем количество результатов предыдущей проверки + $result_ent = ldap_get_entries($ldap,$result); + //return $result_ent; + } + else + { + return ('Вы ввели неправильный логин или пароль. попробуйте еще раз
Вернуться назад'); + } + } + + // Если пользователь найден, то пропускаем его дальше и перебрасываем на main.php + if ($result_ent['count'] != 0) + { + $_SESSION['user_id'] = $username; + $_SESSION['name_en'] = $result_ent[0]['cn'][0]; + $_SESSION['name'] = $result_ent[0]['extensionattribute1'][0]; + $_SESSION['surname'] = $result_ent[0]['extensionattribute2'][0]; + $_SESSION['middle_name'] = $result_ent[0]['extensionattribute3'][0]; + $_SESSION['full_name'] = $result_ent[0]['extensionattribute4'][0]; + $_SESSION['city'] = $result_ent[0]['l'][0]; + $_SESSION['position'] = $result_ent[0]['title'][0]; + $_SESSION['department'] = $result_ent[0]['extensionattribute7'][0]; + $_SESSION['mail'] = $result_ent[0]['mail'][0]; + $_SESSION['phone'] = $result_ent[0]['telephonenumber'][0]; + $_SESSION['georol'] = $result_ent[0]['renaissancegeorole'][0]; + $_SESSION['photo'] = $result_ent[0]['jpegphoto'][0]; + /*Фото из ad + $photo = $result_ent[0]['jpegphoto'][0]; + $img = imagecreatefromstring($photo); + header("Content-type: image/jpeg"); + imagejpeg($img,NULL,100); + echo ""; + + echo "
";
+			var_dump($result_ent);
+			echo "
";*/ + //header('Location: main.php'); + //exit; + } + else + { + die('К сожалению, вам доступ закрыт
Вернуться назад'); + } + } + +} diff --git a/components/Mail.php b/components/Mail.php new file mode 100644 index 0000000..fafcc14 --- /dev/null +++ b/components/Mail.php @@ -0,0 +1,170 @@ + + + + Заказ картриджей + + +

Добрый день.
+ КБ «Ренессанс Кредит» (ООО)
+ Адрес: г. Курск, ул. Радищева 5.
+ Необходимы картриджи для:

+

'; + for($i=0; $i < count($list_print); $i++){ + if($list_print[$i]['is_color'] == 1){ + $message .= "".$list_print[$i]['model']." ".$list_print[$i]['unit']." (black) (2 шт.)
"; + $message .= "".$list_print[$i]['model']." ".$list_print[$i]['unit']." (blue) (2 шт.)
"; + $message .= "".$list_print[$i]['model']." ".$list_print[$i]['unit']." (yellow) (2 шт.)
"; + $message .= "".$list_print[$i]['model']." ".$list_print[$i]['unit']." (magenta) (2 шт.)
"; + }else $message .= "".$list_print[$i]['model']." ".$list_print[$i]['unit']." (2 шт.)
"; + } + + $message .= '

График работы: Пн-Пт. 9:00 - 18:00.
+ Контактные номера:
+ Захаренко Евгений
+ +7 (495) 783-46-00 доб. 15015
+ Защепкин Андрей
+ +7 (495) 783-46-00 доб. 15000
+ Галин Владислав
+ +7 (495) 783-46-00 доб. 15025

+ '; + $ord = self::getMail('Заказ картриджей', $message, $from); + (!$ord) ? $mess = "don't geting" : $mess = "OK"; + return $mess; + } + + + + + private static function getMail($subject, $message, $from){ + + $paramsPath = ROOT.'/config/unit_information.php'; + $params = include($paramsPath); + + // отправка нескольким адресатам + $to = $params['email_support'] . ', '; // кому отправляем + //$to .= 'friend2@yourmail.ru' . ', '; // Внимание! Так пишем второй и тд адреса + // не забываем запятую. Даже в последнем контакте лишней не будет + // Для начинающих! $to .= точка в этом случае для Дописывания в переменную + + // содержание письма + /*$subject = "Тема сообщения"; + $message = ' + + + + Тема страницы + + +

А здесь ваше сообщение

+ + ';*/ + + // устанавливаем тип сообщения Content-type, если хотим + $headers = 'MIME-Version: 1.0' . "\r\n"; + $headers .= "Content-type: text/html; charset=utf-8 \r\n"; + + // дополнительные данные + $headers .= "From: ".$from['name']." <".$from['email'].">\r\n"; // от кого + $headers .= "Cc: #ITKursk@rencredit.ru" . "\r\n"; // копия сообщения на этот адрес + //$headers .= "Bcc: yournick-archive@yourmail.ru\r\n"; // скрытая копия сообщения на этот + mail($to, $subject, $message, $headers); + + } + + public static function getLinkOrd($list_print){ + + $paramsPath = ROOT.'/config/unit_information.php'; + $params = include($paramsPath); + + // отправка нескольким адресатам + $to = $params['email_support']; // кому отправляем + $message = "КБ «Ренессанс Кредит» (ООО)%0aАдрес: г. Курск, ул. Радищева 5.%0aНеобходимы картриджи для:%0a%0a"; + for($i=0; $i < count($list_print); $i++){ + if($list_print[$i]['is_color'] == 1){ + $message .= "".$list_print[$i]['model']." ".$list_print[$i]['unit']." (black) (2 шт.)%0a"; + $message .= "".$list_print[$i]['model']." ".$list_print[$i]['unit']." (blue) (2 шт.)%0a"; + $message .= "".$list_print[$i]['model']." ".$list_print[$i]['unit']." (yellow) (2 шт.)%0a"; + $message .= "".$list_print[$i]['model']." ".$list_print[$i]['unit']." (magenta) (2 шт.)%0a"; + }else $message .= "".$list_print[$i]['model']." ".$list_print[$i]['unit']." (2 шт.)%0a"; + } + $message .= "%0aГрафик работы: Пн-Пт. 9:00 - 18:00.%0aКонтактные номера:%0aЗахаренко Евгений%0a+7 (495) 783-46-00 доб. 15015%0aЗащепкин Андрей%0a+7 (495) 783-46-00 доб. 15000%0aГалин Владислав%0a+7 (495) 783-46-00 доб. 15025"; + + $ord = self::getLinkMail("Заказ картриджей", $message, $to); + //(!$ord) ? $mess = "don't geting" : $mess = "OK"; + return $ord; + + } + + public static function getRequests($print_id, $description){ + + $paramsPath = ROOT.'/config/unit_information.php'; + $params = include($paramsPath); + $print = Printer::getPrintByID($print_id); + // отправка нескольким адресатам + $to = $params['email_support']; // кому отправляем + $message = "КБ «Ренессанс Кредит» (ООО)%0aАдрес: г. Курск, ул. Радищева 5.%0a%0a"; + $message .= "Проблемы с принтером ".$print['model']." ".$print['unit'].". ".$description."%0a"; + $message .= "%0aГрафик работы: Пн-Пт. 9:00 - 18:00.%0aКонтактные номера:%0aЗахаренко Евгений%0a+7 (495) 783-46-00 доб. 15015%0aЗащепкин Андрей%0a+7 (495) 783-46-00 доб. 15000%0aГалин Владислав%0a+7 (495) 783-46-00 доб. 15025"; + + $request = self::getLinkMail("Проблемы с принтером ".$print['model']." ".$print['unit'], $message, $to); + //(!$ord) ? $mess = "don't geting" : $mess = "OK"; + return $request; + } + + + private static function getLinkMail($subject, $body, $to){ + + $subject = "?subject=".$subject; + $body = "&body=".$body; + $cc = "&cc=%23ITKursk%40rencredit.ru"; + + $link = "Link"; + + return $link; + } +} +/*array(13) { + ["link"]=> + string(30) "http://prints.local/cartriges/" + ["user_id"]=> + string(12) "azashchepkin" + ["name_en"]=> + string(19) "Zashchepkin, Andrey" + ["name"]=> + string(16) "Защепкин" + ["surname"]=> + string(12) "Андрей" + ["middle_name"]=> + string(26) "Александрович" + ["full_name"]=> + string(56) "Защепкин Андрей Александрович" + ["city"]=> + string(10) "Курск" + ["position"]=> + string(62) "Специалист технической поддержки" + ["department"]=> + string(60) "Отдел информационных технологий" + ["mail"]=> + string(25) "azashchepkin@rencredit.ru" + ["phone"]=> + string(5) "15000" + ["georol"]=> + string(16) "GR.RC.Курск" +}*/ \ No newline at end of file diff --git a/components/Pagination.php b/components/Pagination.php new file mode 100644 index 0000000..611e55f --- /dev/null +++ b/components/Pagination.php @@ -0,0 +1,196 @@ +total = $total; + + # Устанавливаем количество записей на страницу + $this->limit = $limit; + + # Устанавливаем ключ в url + $this->index = $index; + + # Устанавливаем количество страниц + $this->amount = $this->amount(); + + # Устанавливаем номер текущей страницы + $this->setCurrentPage($currentPage); + } + + /** + * Для вывода ссылок + * + * @return HTML-код со ссылками навигации + */ + public function get() + { + # Для записи ссылок + $links = null; + + # Получаем ограничения для цикла + $limits = $this->limits(); + + $html = ''; + + # Возвращаем html + return $html; + } + + /** + * Для генерации HTML-кода ссылки + * @param integer $page - номер страницы + * + * @return + */ + private function generateHtml($page, $text = null) + { + # Если текст ссылки не указан + if (!$text) + # Указываем, что текст - цифра страницы + $text = $page; + + $currentURI = rtrim($_SERVER['REQUEST_URI'], '/') . '/'; + $currentURI = preg_replace('~/page-[0-9]+~', '', $currentURI); + # Формируем HTML код ссылки и возвращаем + return + '
  • ' . $text . '
  • '; + } + + /** + * Для получения, откуда стартовать + * + * @return массив с началом и концом отсчёта + */ + private function limits() + { + # Вычисляем ссылки слева (чтобы активная ссылка была посередине) + $left = $this->current_page - round($this->max / 2); + + # Вычисляем начало отсчёта + $start = $left > 0 ? $left : 1; + + # Если впереди есть как минимум $this->max страниц + if ($start + $this->max <= $this->amount) + # Назначаем конец цикла вперёд на $this->max страниц или просто на минимум + $end = $start > 1 ? $start + $this->max : $this->max; + else { + # Конец - общее количество страниц + $end = $this->amount; + + # Начало - минус $this->max от конца + $start = $this->amount - $this->max > 0 ? $this->amount - $this->max : 1; + } + + # Возвращаем + return + array($start, $end); + } + + /** + * Для установки текущей страницы + * + * @return + */ + private function setCurrentPage($currentPage) + { + # Получаем номер страницы + $this->current_page = $currentPage; + + # Если текущая страница боле нуля + if ($this->current_page > 0) { + # Если текунщая страница меньше общего количества страниц + if ($this->current_page > $this->amount) + # Устанавливаем страницу на последнюю + $this->current_page = $this->amount; + } else + # Устанавливаем страницу на первую + $this->current_page = 1; + } + + /** + * Для получеия общего числа страниц + * + * @return число страниц + */ + private function amount() + { + # Делим и возвращаем + return round($this->total / $this->limit); + } + +} diff --git a/components/Router.php b/components/Router.php new file mode 100644 index 0000000..ff78d53 --- /dev/null +++ b/components/Router.php @@ -0,0 +1,70 @@ +routes = require($routerPath); + } + + /* + * return request string + */ + private function getURI(){ + if(!empty($_SERVER['REQUEST_URI'])){ + return trim($_SERVER['REQUEST_URI'], '/'); + } + } + + public function run(){ + //получить строку запроса + $uri = $this->getURI(); + + //проверить наличие запроса в routes.php + + foreach($this->routes as $uriPattern => $path){ + + //сравниваем $urlPattern и $url + if(preg_match("~$uriPattern~", $uri)){ + + //получаем внутренний путь из внешнего согласно правилу + $internalRoute = preg_replace("~$uriPattern~", $path, $uri); + + //определить контлоллер, экшен и параметры + $segments = explode('/', $internalRoute); + + $controllerName = array_shift($segments).'Controller'; + $controllerName = ucfirst($controllerName); + + $actionName = 'action'.ucfirst(array_shift($segments)); + + $parameters = $segments; + + //подключить файл класса контроллера + + $controllerFile = ROOT.'/controllers/'.$controllerName.'.php'; + + if(file_exists($controllerFile)){ + include_once ($controllerFile); + } + + $controllerObject = new $controllerName; + + if(!method_exists($controllerObject,$actionName)) { + $er = $uri; + require_once (ROOT . TMPL . 'error.php'); + return true; + }; + + $result = call_user_func_array(array($controllerObject, $actionName),$parameters); + + if($result != null){ + break; + } + } + + } + } +} \ No newline at end of file diff --git a/config/Unit_information.php b/config/Unit_information.php new file mode 100644 index 0000000..b9fd87a --- /dev/null +++ b/config/Unit_information.php @@ -0,0 +1,13 @@ +'Unit', + 'email_support'=>'support@unit-org.ru', //support@unit-org.ru + 'number'=>'8800' +); diff --git a/config/db_params.php b/config/db_params.php new file mode 100644 index 0000000..5b74d18 --- /dev/null +++ b/config/db_params.php @@ -0,0 +1,17 @@ + 'localhost', + 'dbname' => 'db_prints', + 'user' => 'mysql', + 'password' => 'mysql', +); + + // $db->exec('SET NAMES utf8'); //задаём кодировку ввода/вывода БД*/ +?> \ No newline at end of file diff --git a/config/icecast.php b/config/icecast.php new file mode 100644 index 0000000..209468f --- /dev/null +++ b/config/icecast.php @@ -0,0 +1,12 @@ + 'dsk7681', + 'icecast_ip' => '10.20.4.219', + 'icecast_port' => '8000', +); diff --git a/config/ldap_config.php b/config/ldap_config.php new file mode 100644 index 0000000..3091695 --- /dev/null +++ b/config/ldap_config.php @@ -0,0 +1,15 @@ + 'LDAP_B7.RCCF.RU', //, LDAP_M1.RCCF.RU', + 'ldap_port' => '389', + 'ldap_base' => 'OU=Accounts, DC=rccf, DC=ru', + 'ldap_filter' => 'sAMAccountName=', + 'ldap_domain' => '@rccf.ru', +); diff --git a/config/routes.php b/config/routes.php new file mode 100644 index 0000000..b8e63e5 --- /dev/null +++ b/config/routes.php @@ -0,0 +1,70 @@ + 'images/upload', + 'user/login' => 'user/login', + 'user/logout' => 'user/logout', + 'printers' => 'printers/index', + 'printer/add' => 'printers/add', + 'printer/([0-9]+)' => 'printers/view/$1', + 'printer/edit/([0-9]+)' => 'printers/edit/$1', + 'cartriges/action' => 'cartriges/actions', + 'cartriges/orders' => 'cartriges/orders', + 'cartriges/reaction/([0-9]+)' => 'cartriges/reaction/$1', + 'cartriges/add/public/([0-9]+)' => 'cartriges/public/$1', + 'cartriges/add' => 'cartriges/add', + 'cartriges/Zeroning' => 'cartriges/Zeroning', + 'cartriges' => 'cartriges/index', + 'phonebook/admactiv/([0-9]+)' => 'phonebook/activ/$1', + 'phonebook/admsearch' => 'phonebook/admsearch', + 'phonebook/admedit' => 'phonebook/edit', + 'phonebook/admedit/([0-9]+)' => 'phonebook/edit/$1', + 'phonebook/admdelete/([0-9]+)' => 'phonebook/delete/$1', + 'phonebook/save' => 'phonebook/save', + 'phonebook/update' => 'phonebook/update', + 'phonebook/search' => 'phonebook/search', + 'phonebook' => 'phonebook/index', + 'unit/newactionrequest' => 'unit/newactionrequest', + 'unit/actionrequest/([0-9]+)' => 'unit/actionrequest/$1', + 'unit/actionrequest' => 'unit/actionrequest', + 'unit/createrequest' => 'unit/createrequest', + 'unit/requesttobase' => 'unit/requesttobase', + 'unit/requests/page-([0-9]+)' => 'unit/index/$1', + 'unit/requests' => 'unit/index', + 'unit' => 'unit/index', + + + //'radio/statistics/([=0-9]+)' => 'radio/statistics', + //'radio/statistics/?_=([0-9]+)' => 'radio/statistics', + 'radio/statistics' => 'radio/statistics', + 'radio' => 'radio/index', + + '' => 'site/index', + /*'product/([0-9]+)' => 'product/view/$1', + 'catalog' => 'catalog/index', + 'category/([0-9]+)/page-([0-9]+)' => 'catalog/category/$1/$2', + 'category/([0-9]+)' => 'catalog/category/$1', + 'cart/add/([0-9]+)' => 'cart/add/$1', + 'cart/addAjax/([0-9]+)' => 'cart/addAjax/$1', + 'cart' => 'cart/index', + 'user/register' => 'user/register', + 'user/login' => 'user/login', + 'user/logout' => 'user/logout', + 'cabinet/edit' => 'cabinet/edit', + 'cabinet' => 'cabinet/index', + 'contacts' => 'site/contact', + + 'news/([0-9]*)' => 'news/view', + 'news' => 'news/index', + 'articles' => 'articles/list', + 'news/archive' => 'news/archive', + + * 'news/([0-9]+)' => 'news/view/$1', + 'news' => 'news/index', */ +); \ No newline at end of file diff --git a/controllers/CartrigesController.php b/controllers/CartrigesController.php new file mode 100644 index 0000000..e01d3aa --- /dev/null +++ b/controllers/CartrigesController.php @@ -0,0 +1,144 @@ +"; + print_r ($_POST); + print_r ($_SESSION['user_id']); + echo "";*/ + + } + + require_once (ROOT . TMPL . 'cartriges.php'); + return true; + } + + public function actionActions(){ //действия с картриджами (доставка\замена) + + if(!isset($_POST['submit'])) @$_SESSION['link'] = $_SERVER['HTTP_REFERER']; + + $act_error = 0; + + $action = $_GET['act']; + + if(empty($action)) $act_error = 1; + + $title = self::$title."| Действия"; + + //echo "hello user ".$action."-action"; + + $cartriges = Cartriges::getActivCartriges(); + require_once (ROOT . TMPL . 'action_cartriges.php'); + return true; + } + + public static function actionAdd(){ //добавление картриджа + + $title = self::$title."| Добавление"; + + + if(isset($_POST['addcartrige'])){ + + echo "get add new cartrige in base"; + (!Cartriges::addCartriges($_POST)) ? $messages = "Картридж добавлен" : $messages = "error"; + $cartriges = Cartriges::getAllCartriges(); + } + else{ + $cartriges = Cartriges::getAllCartriges(); + } + $cartrridges_history = Cartriges::getHistoryCartridges(9); + require_once (ROOT . TMPL . 'addcartrige.php'); + return true; + } + + public function actionPublic($id){ + + //self::checkAdmin(); + + $pub = Cartriges::changeIsPublic($id); + //var_dump($_SESSION); + //var_dump($_POST); + //var_dump($_FILES); + //var_dump($id); + if($pub){ + header ('Location: '.DOMEN .'/cartriges/add'); + } + } + + + public static function actionReaction($id){ //активация\деактивация картриджа + + Cartriges::reactivCartriges($id); + + return true; + + } + + public static function actionOrders(){ //заказ картриджей + + $title = self::$title."| Заказ"; + if(user::checkAdmin() == true){ + $summ_cart = Cartriges::getSumAllCarteiges(); + $cartriges = Cartriges::getActivCartriges(); + + if(isset($_POST['submit'])){ + //show and running code for order + $list = Cartriges::orderCartriges($_POST); + $data_ord = json_encode($_POST); + /*$from = array( + 'name'=>''.$_SESSION["full_name"].'', + 'email'=>''.$_SESSION["mail"].'', + );*/ + $a = Mail::getLinkOrd($list); + //echo $a; + /*echo "
    ";
    +                var_dump($_SESSION);
    +                echo "
    ";*/ + } + $save = filter_input(INPUT_POST, 'save_order'); + if(isset($save)){ + $data = json_decode(filter_input(INPUT_POST, 'data'), true); + + $saving = Unit::saveOrder($_SESSION["user_id"], $data);//добавить в базу заявок + //var_dump($create_action); + if(!$saving){ + $message = "error"; + }else { + $message = "ok"; + //header("Location: ".$_SERVER['HTTP_REFERER'].""); + } + } + }else{ + $access = "Ошибка доступа"; + } + require_once (ROOT . TMPL . 'cartriges_order.php'); + return true; + } + + public static function actionZeroning(){ + Cartriges::resetToZero(); + } + +} diff --git a/controllers/ImagesController.php b/controllers/ImagesController.php new file mode 100644 index 0000000..01c5607 --- /dev/null +++ b/controllers/ImagesController.php @@ -0,0 +1,101 @@ +"; + var_dump($_SESSION); + echo "
    ----------------------
    "; + var_dump($_POST); + echo "
    ----------------------
    "; + var_dump($_FILES); + echo ""; + * + * + * array(13) { + ["link"]=> + string(35) "http://prints.local/printer/edit/49" + ["user_id"]=> + string(12) "azashchepkin" + ["name_en"]=> + string(19) "Zashchepkin, Andrey" + ["name"]=> + string(16) "Защепкин" + ["surname"]=> + string(12) "Андрей" + ["middle_name"]=> + string(26) "Александрович" + ["full_name"]=> + string(56) "Защепкин Андрей Александрович" + ["city"]=> + string(10) "Курск" + ["position"]=> + string(62) "Специалист технической поддержки" + ["department"]=> + string(60) "Отдел информационных технологий" + ["mail"]=> + string(25) "azashchepkin@rencredit.ru" + ["phone"]=> + string(5) "15000" + ["georol"]=> + string(16) "GR.RC.Курск" + } + + ---------------------- + array(2) { + ["print_id"]=> + string(2) "49" + ["upload"]=> + string(0) "" + } + + ---------------------- + array(1) { + ["img"]=> + array(5) { + ["name"]=> + string(13) "error wfm.png" + ["type"]=> + string(9) "image/png" + ["tmp_name"]=> + string(39) "C:\OpenServer\userdata\temp\php5D63.tmp" + ["error"]=> + int(0) + ["size"]=> + int(50663) + } + } + */ + } + + return true; + + } +} diff --git a/controllers/PhonebookController.php b/controllers/PhonebookController.php new file mode 100644 index 0000000..4791d2e --- /dev/null +++ b/controllers/PhonebookController.php @@ -0,0 +1,155 @@ +"; + var_dump($list); + echo "";*/ + + require_once (ROOT. TMPL. 'phonebook.php'); + + return true; + } + + public function actionSearch(){ + + $title = self::$title . " | Поиск"; + + if(!empty($_POST)){ + $searching = $_POST['searching']; + } + if(!empty($searching)){ + $value = Phonebook::gerResultSearch($searching); + } + /*echo "
    ";
    +        var_dump($list);
    +        echo "
    ";*/ + + require_once (ROOT. TMPL. 'phonebook_search.php'); + + return true; + } + + public function actionSave(){ + + Phonebook::getExcelList(); + + header("Location: ".$_SERVER['HTTP_REFERER'].""); + + } + + public function actionUpdate(){ + + $data = $_POST; + + $upd = Phonebook::save($data); + if(!empty($upd) || isset($upd['save'])){ + + if($upd){ + header("Location: ".$_SERVER['HTTP_REFERER'].""); + }else return false; + } + } + + public function actionAdmsearch(){ + + $title = self::$title . " | Поиск adm"; + + $error = false; + if(user::checkAdmin() == true){ + + if(isset($_POST['submit']) || !empty($_POST['searching'])){ + $searching = $_POST['searching']; + $list = Phonebook::gerResultSearch($searching, 1); + }else{ + $list = Phonebook::gelAllPhoneList(0); + } + }else{ + $error = "access denied"; + } + + $subardination = Phonebook::getSubordination(); + $parents = Phonebook::getParents(); + $departments = Phonebook::getDepatmnents(); + + require_once (ROOT. TMPL. 'phonebook_admsearch.php'); + + return true; + } + + public function actionActiv($id){ + + if(user::checkAdmin() == true){ + $pub = Phonebook::changeIsActiv($id); + //var_dump($_SESSION); + //var_dump($_POST); + //var_dump($_FILES); + //var_dump($id); + if($pub){ + header ('Location: http://'.DOMEN .'/phonebook/admsearch'); + } + }else $error = "access denied"; + + require_once (ROOT. TMPL. 'phonebook_admsearch.php'); + return true; + } + + public function actionAdd(){ + + if(user::checkAdmin() == true){ + + }else{ + $error = "access denied"; + } + + require_once (ROOT. TMPL. 'phonebook_add.php'); + + return true; + } + + public function actionEdit($id){ + + $title = self::$title . " | Редактирование"; + $message = false; + + if(user::checkAdmin() == true){ + if(isset($_POST['save'])){ + $update = Phonebook::save($_POST); + (!$update) ? $message = "Error" : $message = "Good"; + } + $info = Phonebook::getElementByID($id); + $subardination = Phonebook::getSubordination(); + $parents = Phonebook::getParents(); + $departments = Phonebook::getDepatmnents(); + }else{ + $error = "access denied"; + } + + require_once (ROOT. TMPL. 'phonebook_edit.php'); + + return true; + } + + public function actionDelete($id){ + + if(user::checkAdmin() == true){ + + }else{ + $error = "access denied"; + } + + require_once (ROOT. TMPL. 'phonebook_del.php'); + + return true; + } + + +} \ No newline at end of file diff --git a/controllers/PrintersController.php b/controllers/PrintersController.php new file mode 100644 index 0000000..e7d5303 --- /dev/null +++ b/controllers/PrintersController.php @@ -0,0 +1,159 @@ +"; + var_dump($status); + echo "";*/ + + return true; + } + + + public function actionAdd(){ + + $title = self::$title; + + if(isset($_POST['submit'])){ + + //echo "save!!!"; + + //insert in base new printer and geting her id + //forvard in page edit/[id] + $id = Printer::insertPrint($_POST, true); + //echo $id; + header("Location: /printer/edit/".$id); + /*$upbd = printer::updatePrint($print['id'], $_POST); + + $save = Printer::setHistoryChange($up, $print['id'], $_SESSION['user_id']); + if(!$upbd) $_SESSION['message'] = "Error"; + else $_SESSION['message'] = "good";*/ + }else{ + $title = self::$title." | Добавление"; + + //$printList = Printer::getListPrinters(); + + //if($printList == 0) $error = 1; + + $floor = Printer::getAllFloors(); + $department = Printer::getAllDepartments(); + $cartrige = Printer::getAllCartriges(); + $status = Printer::getAllStatuses(); + $functions = Printer::getAllFunctions(); + + require_once (ROOT. TMPL. 'add_prn.php'); + + + /*echo "
    ";
    +            var_dump($status);
    +            echo "
    ";*/ + + return true; + } + } + + public static function actionView($id){ + + $print = Printer::getPrintByID($id); + + $title = self::$title." | ".$print['name']; + + $history = Printer::getHistoryChangeByID($id); + + require_once (ROOT. TMPL. 'info.php'); + /*echo "
    ";
    +        var_dump($histiry);
    +        echo "
    ";*/ + return true; + } + + public static function actionEdit($id){ + + if(user::checkAdmin() == true){ + $floor = Printer::getAllFloors(); + $department = Printer::getAllDepartments(); + $cartrige = Printer::getAllCartriges(); + $status = Printer::getAllStatuses(); + $functions = Printer::getAllFunctions(); + $print = Printer::getPrintByIDFullData($id); + + $title = self::$title." | Редактирование | ".$print['name']; + + if(isset($_POST['submit'])){ + + /*echo "
    ";
    +                    var_dump($print);
    +                    echo "
    "; + echo "kek"; + echo "
    ";
    +                    var_dump($_POST);
    +                    echo "
    ";*/ + + $up = printer::checkDataUpdatePrint($print, $_POST); + + $upbd = printer::updatePrint($print['id'], $_POST); + + $save = Printer::setHistoryChange($up, $print['id'], $_SESSION['user_id']); + if(!$upbd) $_SESSION['message'] = "Error"; + else $_SESSION['message'] = "good"; + } + + /*if(isset($_POST['submitimg'])){ + echo "
    ";
    +                    var_dump($_SESSION);
    +                    echo "
    ----------------------
    "; + var_dump($_POST); + echo "
    "; + }*/ + $print = Printer::getPrintByIDFullData($id); + }else{ + $access = "Ошибка доступа"; + } + require_once (ROOT. TMPL. 'edit_print.php'); + + unset($_SESSION['message']); + + return true; + } + +} diff --git a/controllers/RadioController.php b/controllers/RadioController.php new file mode 100644 index 0000000..ba9fa94 --- /dev/null +++ b/controllers/RadioController.php @@ -0,0 +1,59 @@ +"; + var_dump($statistic); + echo "";*/ + //echo $this->host_ice .":". $this->port_ice; + + require_once (ROOT . TMPL . 'radio.php'); + return true; + } + + public function actionStatistics(){ + + $statistic = Radio::getStatistic(); + $string = " + + + + + "; + for($i=0; count($statistic)>$i; $i++){ + $string .= ""; + $string .= ""; + $string .=""; + $string .=""; + $string .=""; + $string .=""; + } + + $string .="
    Название Слушать + Слушателей
    сейчас
    Композиция
    ".$statistic[$i]['stream']."".$statistic[$i]['quantity_listens']."".$statistic[$i]['title']."
    "; + echo $string; + return true; + } + +} diff --git a/controllers/SiteController.php b/controllers/SiteController.php new file mode 100644 index 0000000..2edb9f0 --- /dev/null +++ b/controllers/SiteController.php @@ -0,0 +1,85 @@ +treeCategory(); // выбираем из базы список категорий и подкатегорий + $categories2 = category::create_tree($a, 0); // вызываем функцию и строим дерево + * + */ + + //$latestProduct = array(); + //$latestProduct = Product::getLatestProducts(); + $title = self::$title; + + $summ_cart = Cartriges::getSumAllCarteiges(); + + $printList = Printer::getRandPrint(3); + + require_once(ROOT . TMPL .'index.php'); + /*echo "Home
    "; + + if(user::checkAuth() == false){ + echo "Авторизуйтесь!!!"; + }else{ + echo ""; + + + echo "
    ";
    +            var_dump($_SESSION);
    +            echo "
    "; + echo "Exit"; + }*/ + + return true; + } + + public function actionContact(){ + + $userEmail = ''; + $userText = ''; + $result = false; + + if(isset($_POST['submit'])){ + + $userEmail = $_POST['userEmail']; + $userText = $_POST['userText']; + + $errors = false; + + if(!user::checkEmail($userEmail)){ + $errors[] = 'Not valid E-mail'; + } + + if($errors == false){ + $adminEmail = 'yaslonane@yandex.ru'; + $message = "Текст: {$userText}. От {$userEmail}"; + $subject = 'subject mail TEST'; + $result = mail($adminEmail, $subject, $message, "From: System message from zaa46.xyz "); /* {$userEmail} */ + $result = true; + } + } + + require (ROOT . TMPL . 'contact.php'); + + return true; + } + /* + * конец вывода главной страницы + */ +} diff --git a/controllers/UnitController.php b/controllers/UnitController.php new file mode 100644 index 0000000..dbd0171 --- /dev/null +++ b/controllers/UnitController.php @@ -0,0 +1,139 @@ +"; + var_dump($requests); + echo "";*/ + + require_once (ROOT. TMPL. 'requests.php'); + + return true; + } + + public function actionCreaterequest(){ + + $title = self::$title . " | Создание запроса"; + + $error = false; + $message = false; + + if(user::checkAdmin() == true){ + + $printers = Printer::getListPrinters('all'); + $create = filter_input(INPUT_POST,'create'); + if(isset($create)){ + $user_id = filter_input(INPUT_POST,'username'); + $print_id = filter_input(INPUT_POST,'print_id'); + $description = filter_input(INPUT_POST,'text'); + + $lnk = Mail::getRequests($print_id, $description); + + + } + $save = filter_input(INPUT_POST, 'save_request'); + if(isset($save)){ + $user = filter_input(INPUT_POST,'user_id'); + $print = filter_input(INPUT_POST,'print_id'); + $desc = filter_input(INPUT_POST,'description'); + $saving = Unit::setRequest($user, $print, $desc);//добавить в базу заявок + $create_action = Unit::createNewAction($saving, 0, $user); + //var_dump($create_action); + if(!$saving){ + $message = "error"; + }else { + $message = "ok"; + //header("Location: ".$_SERVER['HTTP_REFERER'].""); + } + } + }else{ + $error = "access denied"; + } + require_once (ROOT. TMPL. 'create_request.php'); + + /*echo "
    ";
    +        var_dump($status);
    +        echo "
    ";*/ + + return true; + } + + public function actionRequesttobase(){ + //$printers = Printer::getListPrinters('all'); + $save = filter_input(INPUT_POST, 'save_request'); + if(isset($save)){ + $user_id = filter_input(INPUT_POST,'user_id'); + $print_id = filter_input(INPUT_POST,'print_id'); + $description = filter_input(INPUT_POST,'description'); + $saving = Unit::setRequest($user_id, $print_id, $description);//добавить в базу заявок + if(!$saving){ + $message = "error"; + }else { + $message = "ok"; + header("Location: ".$_SERVER['HTTP_REFERER'].""); + } + } + echo $message; + return true; + /*echo "
    ";
    +        var_dump($status);
    +        echo "
    ";*/ + + } + + public function actionActionrequest($id = NULL){ + $title = self::$title . " | Действия по обращению"; + $error = ""; + if(user::checkAdmin() == true){ + //action if authorization is successful + if($id === NULL){ + header("Location: http://".DOMEN."/unit/requests"); + }else{ + $list = Unit::getRequestByID($id); + $act = Unit::getAllActionByIDRequest($id); + } + }else{ + $error = "access denied"; + } + //require_once (ROOT. TMPL. 'create_request.php'); + require_once (ROOT. TMPL. 'action_request.php'); + + return true; + } + + public function actionNewactionrequest(){ + + $act = Unit::setNewActions(); + + $docs = filter_input(INPUT_POST, 'docs'); + $request_id = filter_input(INPUT_POST, 'request_id'); + + $indoc = Unit::setNewDocs($act, $request_id, $docs); + + if($indoc == true) header("Location: http://".DOMEN."/unit/actionrequest/".$request_id.""); + + //return true; + } +} diff --git a/controllers/UserController.php b/controllers/UserController.php new file mode 100644 index 0000000..25da320 --- /dev/null +++ b/controllers/UserController.php @@ -0,0 +1,97 @@ + + php_flag engine Off + + + php_flag engine Off + + + php_flag engine Off + + + Options -ExecCGI + + +RemoveHandler .cgi .pl .py .pyc .pyo .phtml .php .php3 .php4 .php5 .php6 .pcgi .pcgi3 .pcgi4 .pcgi5 .pchi6 .inc +RemoveType .cgi .pl .py .pyc .pyo .phtml .php .php3 .php4 .php5 .php6 .pcgi .pcgi3 .pcgi4 .pcgi5 .pchi6 .inc +SetHandler None +SetHandler default-handler + +# Remove both lines below if you want to render HTML files from the upload folder +AddType text/plain .html +AddType text/plain .htm diff --git a/docs/.thumbs/files/aXP1ItlpsDE.jpg b/docs/.thumbs/files/aXP1ItlpsDE.jpg new file mode 100644 index 0000000..315eba9 Binary files /dev/null and b/docs/.thumbs/files/aXP1ItlpsDE.jpg differ diff --git a/docs/files/125/CS Agents.csv b/docs/files/125/CS Agents.csv new file mode 100644 index 0000000..f26ca27 --- /dev/null +++ b/docs/files/125/CS Agents.csv @@ -0,0 +1,575 @@ +"11973";", ";"50857";"Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"11901";", ";"50887";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"11983";", ";"50308";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11922";", ";"50817";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"25167";", ";"50017";"Activation";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11979";", ";"50030";"Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"11321";", ";"50417";"Loans+Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"10857";", ";"50138";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"11808";", ";"50483";"Loans+Card";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11265";", ";"50223";"Loans+Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"11742";", ";"50213";"Loans+Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"10322";", ";"50252";"Loans+Presell+Outsource";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11281";", ";"50387";"Loans+Card";"1011 CS Kursk Platform";"1 Avaya CMS"; +"10011";", ";"50191";"Loans+Card+Presell+Outsource";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11270";", ";"50051";"Loans+Card+Deposit+Clever";"1012 CS Penza Platform";"1 Avaya CMS"; +"128";", ";"50636";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"11874";", ";"50870";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11787";", ";"50833";"Loans+Card";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11891";", ";"50570";"Loans+Activation";"1012 CS Penza Platform";"1 Avaya CMS"; +"11734";", ";"50753";"Loans+Presell";"1012 CS Penza Platform";"1 Avaya CMS"; +"11238";", ";"50185";"Loans+Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"10367";", ";"50289";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"11438";", ";"50500";"Loans+Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"11730";", ";"50295";"Loans+Card+Activation+Metlife";"1011 CS Kursk Platform";"1 Avaya CMS"; +"10922";", ";"50668";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"11610";", ";"50739";"Loans+Card";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11040";", ";"50591";"Reception";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11918";", ";"50863";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"11348";", ";"50441";"Loans+Card+Activation+Metlife";"1011 CS Kursk Platform";"1 Avaya CMS"; +"10968";", ";"50550";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"10924";", ";"50666";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"11649";", ";"50413";"Loans+Card+Activation+Metl.+Cl.";"1012 CS Penza Platform";"1 Avaya CMS"; +"11027";", ";"50341";"Expert Written";"1013 CS Expert Platform";"1 Avaya CMS"; +"10892";", ";"50421";"Loans+Card+Deposit+Clever";"1011 CS Kursk Platform";"1 Avaya CMS"; +"195";", ";"50610";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"10183";", ";"50182";"Loans+Card+Activation+Metl.+Cl.";"1012 CS Penza Platform";"1 Avaya CMS"; +"11433";", ";"50371";"Loans+Card+Activation+Metl.+Cl.";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11819";", ";"50321";"Loans+Card";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11708";", ";"50055";"Loans+Card";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11690";", ";"50127";"Loans+Card+Activation+Clever";"1012 CS Penza Platform";"1 Avaya CMS"; +"11801";", ";"50357";"Presell+Out";"1015 CS Cross Out";"1 Avaya CMS"; +"2091";", ";"50627";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"11875";", 0.5";"50571";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11842";", ";"50838";"Loans+Activation";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11944";", ";"50782";"Loans";"1012 CS Penza Platform";"1 Avaya CMS"; +"11907";", ";"50892";"Presell+Out";"1015 CS Cross Out";"1 Avaya CMS"; +"11613";", ";"50683";"Loans+Card";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11867";", ";"50871";"Loans";"1012 CS Penza Platform";"1 Avaya CMS"; +"10697";", ";"50053";"Loans+Presell+Outsource";"1011 CS Kursk Platform";"1 Avaya CMS"; +"10913";", ";"50615";"Loans+Card+Presell+Outsource";"1011 CS Kursk Platform";"1 Avaya CMS"; +"122";", ";"50544";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"25225";", ";"50354";"Loans+Card (Easy)";"1012 CS Penza Platform";"1 Avaya CMS"; +"11989";", ";"50194";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11854";", 0.5";"50635";"Loans+Card";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11658";", ";"50755";"Loans+Card+Activation+Metlife";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11966";", ";"50432";"Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"11773";", ";"50079";"Loans+Card+Presell+Outsour.Easy";"1012 CS Penza Platform";"1 Avaya CMS"; +"11004";", ";"50715";"Expert Calls";"1013 CS Expert Platform";""; +"10";", ";"50584";"Loans";"1012 CS Penza Platform";"1 Avaya CMS"; +"10114";", ";"50042";"Loans+Card+Deposit+Clever";"1012 CS Penza Platform";"1 Avaya CMS"; +"25222";", ";"50367";"Loans+Card (Easy)";"1012 CS Penza Platform";"1 Avaya CMS"; +"11442";", 0.75";"50429";"Presell+Out";"1015 CS Cross Out";"1 Avaya CMS"; +"25229";", ";"50362";"Loans+Card (Easy)";"1012 CS Penza Platform";"1 Avaya CMS"; +"11920";", 0.75";"50804";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"10057";", ";"50109";"Loans+Card+Presell+Outsource";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11876";", ";"50869";"Loans+Card";"1011 CS Kursk Platform";"1 Avaya CMS"; +"10993";", ";"50527";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"8014";", ";"54037";"Loans CA Help CC";"8001 CA Penza";"1 Avaya CMS"; +"11148";", ";"50199";"Loans+Card+Activation+Clever";"1012 CS Penza Platform";"1 Avaya CMS"; +"11294";", ";"50397";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"11393";", ";"50065";"Loans+Card+Presell+Outsource";"1011 CS Kursk Platform";"1 Avaya CMS"; +"10300";", ";"50166";"Loans+Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"2108";", ";"50533";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"11933";", ";"50279";"Presell+Outsource";"";"1 Avaya CMS"; +"10751";", ";"50257";"Loans+Card+Presell+Outsource";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11955";", ";"50153";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"14";", ";"50608";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"11976";", ";"50038";"Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"10252";", ";"50003";"Loans+Card+Deposit+Activ.+Cl.";"1011 CS Kursk Platform";"1 Avaya CMS"; +"10075";", Exp.";"50130";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"11910";", ";"50549";"Presell+Out";"1015 CS Cross Out";"1 Avaya CMS"; +"11080";", ";"50270";"Expert Written";"1013 CS Expert Platform";"1 Avaya CMS"; +"10337";", ";"50091";"Loans+Card+Activation+Metl.+Cl.";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11288";", ";"50395";"Loans+Card+Activation+Metl.+Cl.";"1011 CS Kursk Platform";"1 Avaya CMS"; +"10241";", ";"50176";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"11464";", ";"50360";"Loans+Card+Activation+Metl.+Cl.";"1012 CS Penza Platform";"1 Avaya CMS"; +"11864";", ";"50864";"Loans+Card";"1012 CS Penza Platform";"1 Avaya CMS"; +"25228";", ";"50391";"Loans+Card (Easy)";"1012 CS Penza Platform";"1 Avaya CMS"; +"11930";", ";"50747";"Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"10994";", ";"50556";"Loans+Card+Activation+Metlife";"1012 CS Penza Platform";"1 Avaya CMS"; +"10316";", ";"50243";"Loans+Card+Activation+Metl.+Cl.";"1011 CS Kursk Platform";"1 Avaya CMS"; +"25212";", ";"50425";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11219";", ";"50312";"Loans+Card+Activation+Metl.+Cl.";"1012 CS Penza Platform";"1 Avaya CMS"; +"10049";", ";"50867";"Loans+Card+Deposit+Clever";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11400";", ";"50073";"Loans+Card+Presell (Easy)";"1012 CS Penza Platform";"1 Avaya CMS"; +"25199";", ";"50349";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"10325";", ";"50256";"Loans+Card+Activation+Metlife";"1011 CS Kursk Platform";"1 Avaya CMS"; +"10973";", ";"50602";"Loans+Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"11857";", ";"50849";"Loans+Card";"1012 CS Penza Platform";"1 Avaya CMS"; +"11082";", ";"50035";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"10215";", ";"50152";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"11399";", ";"50224";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"18";", ";"50537";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"11347";", ";"50439";"Loans+Presell+Outsource";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11844";", ";"50805";"Loans+Activation";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11418";", ";"50254";"Loans+Card+Presell+Outsource";"1011 CS Kursk Platform";"1 Avaya CMS"; +"10297";", ";"50209";"Loans+Card+Activation+Metl.+Cl.";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11605";", 0.75";"50642";"Loans";"1012 CS Penza Platform";"1 Avaya CMS"; +"10699";", ";"50498";"Expert Written";"1013 CS Expert Platform";"1 Avaya CMS"; +"10261";", ";"50234";"Loans+Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"11623";", ";"50119";"Presell+Out";"1015 CS Cross Out";"1 Avaya CMS"; +"11481";", ";"50649";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"10978";", ";"50286";"Loans+Card+Deposit+Clever";"1012 CS Penza Platform";"1 Avaya CMS"; +"10303";", ";"50136";"Expert Public";"1013 CS Expert Platform";"1 Avaya CMS"; +"11932";", ";"50446";"Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"164";", ";"50542";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"11429";", ";"50244";"Presell+Out";"1015 CS Cross Out";"1 Avaya CMS"; +"20";", ";"50613";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"10347";", ";"50272";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"11940";", ";"50227";"Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"20256";", ";"50573";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"11688";", ";"50779";"Loans+Card+Clever";"1012 CS Penza Platform";"1 Avaya CMS"; +"11670";", ";"50764";"Loans+Presell+Outsource";"1011 CS Kursk Platform";"1 Avaya CMS"; +"10988";", ";"50488";"Presell+Out";"1015 CS Cross Out";"1 Avaya CMS"; +"23";", ";"50545";"Presell+Out";"1015 CS Cross Out";"1 Avaya CMS"; +"11816";", ";"50302";"Presell+Out";"1015 CS Cross Out";"1 Avaya CMS"; +"10014";", ";"50010";"Loans+Card+Deposit+Activ.+Cl.";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11614";", ";"50671";"Loans+Card+Activation+Metlife";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11330";", ";"50430";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"10692";", ";"50048";"Loans+Card+Deposit+Activ.+Cl.";"1012 CS Penza Platform";"1 Avaya CMS"; +"11958";", ";"50365";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11783";", ";"50823";"Loans+Card+Presell+Outsour.Easy";"1012 CS Penza Platform";""; +"11413";", ";"50496";"Presell+Out";"1015 CS Cross Out";"1 Avaya CMS"; +"11701";", ";"50788";"Loans+Presell+Outsource";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11807";", ";"50465";"Loans+Card";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11631";", ";"50008";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"10053";", ";"50067";"Loans+Presell+Outsource";"1011 CS Kursk Platform";"1 Avaya CMS"; +"25227";", ";"50386";"Loans+Card (Easy)";"1012 CS Penza Platform";"1 Avaya CMS"; +"11676";", ";"50767";"Loans";"1012 CS Penza Platform";""; +"25181";", ";"50251";"Presell";"1012 CS Penza Platform";"1 Avaya CMS"; +"11405";", ";"50331";"Presell+Out";"1015 CS Cross Out";"1 Avaya CMS"; +"11401";", ";"50122";"Loans+Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"10223";", ";"50049";"Loans+Card+Deposit+Activ.+Cl.";"1012 CS Penza Platform";"1 Avaya CMS"; +"11525";", ";"50020";"Loans+Card+Presell+Outsource";"1011 CS Kursk Platform";"1 Avaya CMS"; +"26";", ";"50625";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"11988";", ";"50114";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11709";", ";"50478";"Loans+Card+Activation+Metlife";"1011 CS Kursk Platform";"1 Avaya CMS"; +"2041";", ";"50009";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"11902";", ";"50738";"Presell+Out+Outsource";"1015 CS Cross Out";""; +"27";", ";"50581";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"10025";", ";"50029";"Expert Written";"1013 CS Expert Platform";"1 Avaya CMS"; +"11878";", ";"50879";"Loans+Card";"1011 CS Kursk Platform";"1 Avaya CMS"; +"68";", ";"50621";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"11993";", ";"50477";"Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"29";", ";"50543";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"11941";", ";"50359";"Loans";"1012 CS Penza Platform";"1 Avaya CMS"; +"10026";", ";"50898";"Expert Public";"1013 CS Expert Platform";"1 Avaya CMS"; +"30";", ";"50603";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"11176";", ";"50041";"Loans+Card+Activation+Metl.+Cl.";"1012 CS Penza Platform";"1 Avaya CMS"; +"11444";", ";"50477";"Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"10820";", ";"50617";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"10017";", ";"50189";"Expert Written";"1013 CS Expert Platform";"1 Avaya CMS"; +"11782";", ";"50487";"Loans+Card+Presell+Outsour.Easy";"1012 CS Penza Platform";"1 Avaya CMS"; +"11950";", ";"50021";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11889";", ";"50389";"Loans+Activation";"1012 CS Penza Platform";"1 Avaya CMS"; +"11753";", ";"50812";"Loans+Card+Presell+Outsour.Easy";"1012 CS Penza Platform";"1 Avaya CMS"; +"11840";", ";"50131";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11663";", ";"50763";"Loans+Card+Activation+Metlife";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11616";", ";"50454";"Loans+Card+Activation+Metlife";"1011 CS Kursk Platform";"1 Avaya CMS"; +"32";", ";"50623";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"11625";", ";"50052";"Presell+Out";"1015 CS Cross Out";"1 Avaya CMS"; +"11866";", ";"50862";"Loans+Card";"1012 CS Penza Platform";"1 Avaya CMS"; +"11407";", ";"50085";"Presell+Out";"1015 CS Cross Out";"1 Avaya CMS"; +"11776";", ";"50348";"Loans+Card+Presell+Outsour.Easy";"1012 CS Penza Platform";"1 Avaya CMS"; +"11722";", ";"50792";"Loans+Card+Presell+Outsour.Easy";"1012 CS Penza Platform";"1 Avaya CMS"; +"11904";", ";"50748";"Presell+Out";"1015 CS Cross Out";"1 Avaya CMS"; +"11936";", ";"50785";"Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"10877";", ";"50237";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"2053";", ";"50096";"Loans";"1012 CS Penza Platform";"1 Avaya CMS"; +"10894";", ";"50654";"Loans+Presell+Outsource";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11828";", ";"50340";"Loans+Card";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11899";", ";"50381";"Loans+Card";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11345";", ";"50436";"Loans+Card+Activation+Metl.+Cl.";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11355";", ";"50247";"Loans+Card+Activation+Metl.+Cl.";"1011 CS Kursk Platform";"1 Avaya CMS"; +"10878";", ";"50356";"Loans+Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"11013";", ";"50710";"Expert Written";"1013 CS Expert Platform";"1 Avaya CMS"; +"11923";", 0.5";"50241";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11364";", ";"50464";"Loans+Card+Presell+Outsource";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11772";", ";"50319";"Loans+Card+Presell (Easy)";"1012 CS Penza Platform";"1 Avaya CMS"; +"11952";", ";"50416";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"10029";", 0.5";"50378";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11916";", ";"50890";"Presell+Out";"1015 CS Cross Out";""; +"11954";", ";"50339";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11823";", ";"50780";"Loans+Card";"1011 CS Kursk Platform";"1 Avaya CMS"; +"10919";", ";"50672";"Loans+Card+Deposit+Clever";"1011 CS Kursk Platform";"1 Avaya CMS"; +"2044";", ";"50555";"Presell+Out";"1015 CS Cross Out";""; +"11596";", ";"50512";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"11555";", ";"50698";"Loans+Card+Presell+Outsource";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11617";", ";"50643";"Loans+Card";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11762";", ";"50712";"Loans+Card+Presell+Outsour.Easy";"1012 CS Penza Platform";"1 Avaya CMS"; +"11648";", ";"50390";"Loans+Card";"1012 CS Penza Platform";"1 Avaya CMS"; +"11759";", ";"50802";"Loans+Card+Presell+Outsour.Easy";"1012 CS Penza Platform";"1 Avaya CMS"; +"11978";", ";"50326";"Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"11880";", ";"50868";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11725";", ";"50490";"Loans+Card+Presell+Outsour.Easy";"1012 CS Penza Platform";"1 Avaya CMS"; +"11956";", ";"50410";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"25165";", ";"50162";"Activation";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11635";", ";"50742";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"179";", ";"50565";"Loans";"1012 CS Penza Platform";"1 Avaya CMS"; +"11590";", ";"50076";"Loans+Card+Activation+Metlife";"1011 CS Kursk Platform";"1 Avaya CMS"; +"38";", ";"50592";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"11313";", ";"50174";"Loans+Card+Activation+Metl.+Cl.";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11850";", ";"50850";"Loans+Card";"1011 CS Kursk Platform";"1 Avaya CMS"; +"20630";", ";"50601";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"25226";", ";"50383";"Loans+Card (Easy)";"1012 CS Penza Platform";"1 Avaya CMS"; +"11656";", ";"50681";"Loans+Card+Activation+Metl.+Cl.";"1011 CS Kursk Platform";"1 Avaya CMS"; +"10982";", ";"50756";"Loans+Card+Activation+Clever";"1012 CS Penza Platform";"1 Avaya CMS"; +"10189";", ";"50201";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"10100";", ";"50039";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"11626";", ";"50447";"Presell+Out";"1015 CS Cross Out";"1 Avaya CMS"; +"11490";", ";"50140";"Loans+Card+Activation+Metl.+Cl.";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11892";", ";"50467";"Loans+Activation";"1012 CS Penza Platform";"1 Avaya CMS"; +"11799";", ";"50342";"Presell+Out";"1015 CS Cross Out";"1 Avaya CMS"; +"11049";", ";"50123";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"8028";", ";"54050";"Loans CA Help CC";"8001 CA Penza";"1 Avaya CMS"; +"11445";", 0.75";"50379";"Presell+Out";"1015 CS Cross Out";"1 Avaya CMS"; +"10781";", ";"50472";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"11505";", ";"50656";"Loans+Card+Activation+Metl.+Cl.";"1012 CS Penza Platform";"1 Avaya CMS"; +"11789";", 0.75";"50831";"Loans+Card+Activation+Metlife";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11912";", ";"50679";"Presell+Out";"1015 CS Cross Out";"1 Avaya CMS"; +"11491";", ";"50143";"Loans+Card+Activation+Metl.+Cl.";"1011 CS Kursk Platform";"1 Avaya CMS"; +"2140";", ";"50648";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"11604";", 0.5";"50735";"Loans";"1012 CS Penza Platform";"1 Avaya CMS"; +"11746";", ";"50664";"Loans+Card+Activation+Metlife";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11034";", ";"50154";"Expert Written";"1013 CS Expert Platform";"1 Avaya CMS"; +"11217";", ";"50299";"Loans+Card";"1012 CS Penza Platform";"1 Avaya CMS"; +"2055";", ";"50547";"Loans";"1012 CS Penza Platform";"1 Avaya CMS"; +"10971";", ";"50538";"Loans+Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"11446";", ";"";"";"1012 CS Penza Platform";""; +"11898";", 0.5";"50327";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"44";", ";"50588";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"11577";", ";"50734";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"11547";", ";"50523";"Loans+Card+Activation+Metl.+Cl.";"1011 CS Kursk Platform";"1 Avaya CMS"; +"2006";", ";"50535";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"11609";", ";"50737";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"11964";", ";"50514";"Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"11846";", 0.5";"50661";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11414";", ";"50236";"Loans+Card+Activation+Metl.+Cl.";"1011 CS Kursk Platform";"1 Avaya CMS"; +"46";", ";"50536";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"11924";", ";"50276";"Loans+Card";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11990";", ";"50139";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11685";", ";"50774";"Loans+Card";"1012 CS Penza Platform";"1 Avaya CMS"; +"25162";", ";"50229";"Presell";"1012 CS Penza Platform";"1 Avaya CMS"; +"11939";", ";"50240";"Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"11081";", ";"50207";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"11619";", ";"50693";"Loans+Card+Activation+Metlife";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11314";", ";"50214";"Loans+Card+Activation+Metl.+Cl.";"1011 CS Kursk Platform";"1 Avaya CMS"; +"10033";", ";"50278";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11126";", ";"50026";"Reception";"1011 CS Kursk Platform";"1 Avaya CMS"; +"10995";", ";"50557";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"11913";", ";"50882";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"11447";", ";"50499";"Loans+Card+Presell+Outsour.Easy";"1012 CS Penza Platform";"1 Avaya CMS"; +"11362";", ";"50455";"Loans+Card+Presell+Outsource";"1011 CS Kursk Platform";"1 Avaya CMS"; +"10070";", ";"50077";"Loans+Card+Deposit+Clever";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11906";", ";"50883";"Presell+Out";"1015 CS Cross Out";"1 Avaya CMS"; +"25178";", ";"50232";"Activation";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11879";", ";"50459";"Loans+Card";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11162";", ";"50197";"Loans+Card+Activation+Metl.+Cl.";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11298";", ";"50407";"Loans+Card+Activation+Metl.+Cl.";"1012 CS Penza Platform";"1 Avaya CMS"; +"25065";", ";"50539";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"10885";", ";"50576";"Loans+Presell+Outsource";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11607";", 0.5";"50680";"Loans";"1012 CS Penza Platform";"1 Avaya CMS"; +"11957";", ";"50440";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"244";", ";"50106";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"10357";", ";"50281";"Loans+Presell+Outsource";"1011 CS Kursk Platform";"1 Avaya CMS"; +"49";", ";"50566";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"11540";", ";"50685";"Loans+Card+Clever";"1012 CS Penza Platform";"1 Avaya CMS"; +"10983";", ";"50701";"Loans+Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"11371";", ";"50363";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"11017";", ";"50720";"Expert Written";"1013 CS Expert Platform";"1 Avaya CMS"; +"11747";", 0.9";"50796";"Loans+Presell+Outsource";"1011 CS Kursk Platform";"1 Avaya CMS"; +"10292";", ";"50186";"Loans+Presell+Outsource";"1011 CS Kursk Platform";"1 Avaya CMS"; +"25148";", ";"50815";"Presell+Out";"1015 CS Cross Out";"1 Avaya CMS"; +"10608";", ";"50444";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"25166";", ";"50148";"Activation";"1011 CS Kursk Platform";"1 Avaya CMS"; +"10445";", ";"50382";"Loans+Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"11818";", ";"50696";"Loans+Card";"1011 CS Kursk Platform";""; +"11271";", 0.75";"50101";"Loans+Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"11986";", ";"50203";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11822";", ";"50765";"Loans+Card";"1011 CS Kursk Platform";"1 Avaya CMS"; +"10779";", ";"50206";"Loans+Presell+Outsource";"1011 CS Kursk Platform";"1 Avaya CMS"; +"10018";", ";"50121";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"10027";", ";"50309";"Loans+Card";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11244";", ";"50061";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"11960";", ";"50163";"Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"54";", ";"50604";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"11718";", ";"50217";"Loans+Card";"1011 CS Kursk Platform";"1 Avaya CMS"; +"2033";", ";"50525";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"2048";", ";"50634";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"11127";", ";"50033";"Loans+Card+Presell+Outsource";"1011 CS Kursk Platform";"1 Avaya CMS"; +"2045";", ";"50013";"Loans";"1012 CS Penza Platform";"1 Avaya CMS"; +"11761";", ";"50358";"Loans+Card+Presell+Outsour.Easy";"1012 CS Penza Platform";"1 Avaya CMS"; +"11628";", ";"50088";"Presell+Out";"1015 CS Cross Out";"1 Avaya CMS"; +"11863";", ";"50861";"Loans+Card";"1012 CS Penza Platform";"1 Avaya CMS"; +"8043";", ";"54064";"Loans CA Help CC";"8001 CA Penza";"1 Avaya CMS"; +"11909";", ";"50777";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"11689";", ";"50486";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"25152";", ";"50196";"Presell";"1012 CS Penza Platform";"1 Avaya CMS"; +"57";", ";"50574";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"25232";", ";"50370";"Loans+Card (Easy)";"1012 CS Penza Platform";"1 Avaya CMS"; +"10305";", ";"50031";"Loans+Presell+Outsource";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11404";", ";"50159";"Expert Written";"1013 CS Expert Platform";"1 Avaya CMS"; +"59";", ";"50593";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"2037";", ";"50025";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"176";", ";"50630";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"11791";", ";"50485";"Loans+Card+Activation+Clever";"1012 CS Penza Platform";"1 Avaya CMS"; +"10343";", ";"50268";"Loans+Presell+Outsource";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11853";", ";"50855";"Loans+Card";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11068";", ";"50142";"Loans+Card+Presell+Outsource";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11078";", ";"50195";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"2035";", ";"50628";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"25169";", ";"50248";"Activation";"1011 CS Kursk Platform";"1 Avaya CMS"; +"10193";", ";"50205";"Loans+Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"11974";", ";"50027";"Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"25186";", ";"50293";"Presell";"1012 CS Penza Platform";"1 Avaya CMS"; +"42";", ";"50521";"Presell+Out";"1015 CS Cross Out";"1 Avaya CMS"; +"11949";", ";"50806";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11726";", ";"50730";"Loans+Card+Presell+Outsour.Easy";"1012 CS Penza Platform";"1 Avaya CMS"; +"10705";", ";"50516";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"11729";", ";"50629";"Loans+Card+Activation+Metlife";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11745";", ";"50726";"Loans+Card";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11926";", ";"50893";"Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"11790";", ";"50834";"Loans+Card";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11012";", ";"50709";"Expert Written";"1013 CS Expert Platform";"1 Avaya CMS"; +"61";", ";"50579";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"11652";", ";"50517";"Loans+Card+Clever";"1012 CS Penza Platform";"1 Avaya CMS"; +"152";", ";"50564";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"11826";", 0.5";"50423";"Loans+Card";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11291";", ";"50393";"Loans+Presell";"1011 CS Kursk Platform";"1 Avaya CMS"; +"10006";", ";"50754";"Expert Written";"1013 CS Expert Platform";"1 Avaya CMS"; +"10032";", ";"50037";"Loans+Card";"1011 CS Kursk Platform";"1 Avaya CMS"; +"25188";", ";"50322";"Loans+Card (Easy)";"1012 CS Penza Platform";"1 Avaya CMS"; +"11128";", ";"50068";"Loans+Card+Deposit+Clever";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11496";", ";"50366";"Loans+Card+Deposit+Clever";"1012 CS Penza Platform";"1 Avaya CMS"; +"11502";", ";"50374";"Loans+Card";"1012 CS Penza Platform";"1 Avaya CMS"; +"11862";", ";"50427";"Loans+Card";"1012 CS Penza Platform";"1 Avaya CMS"; +"11764";", ";"50700";"Loans+Card+Presell+Outsour.Easy";"1012 CS Penza Platform";"1 Avaya CMS"; +"11512";", ";"50510";"Loans+Card+Clever";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11678";", ";"50647";"Loans+Card+Clever";"1012 CS Penza Platform";"1 Avaya CMS"; +"11965";", ";"50814";"Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"11385";", ";"50258";"Loans+Card+Activation+Clever";"1012 CS Penza Platform";"1 Avaya CMS"; +"11784";", ";"50827";"Loans+Card+Presell (Easy)";"1012 CS Penza Platform";"1 Avaya CMS"; +"11308";", ";"50411";"Loans+Presell+Outsource";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11039";", ";"50294";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"11971";", ";"50046";"Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"25231";", ";"50392";"Loans+Card (Easy)";"1012 CS Penza Platform";"1 Avaya CMS"; +"2142";", ";"50600";"Loans+Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"11591";", ";"50094";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"25185";", ";"50125";"Presell";"1012 CS Penza Platform";"1 Avaya CMS"; +"11280";", ";"50385";"Loans+Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"11970";", ";"50851";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11315";", ";"50415";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"11682";", ";"50776";"Loans+Card+Activation+Metlife";"1011 CS Kursk Platform";"1 Avaya CMS"; +"10970";", ";"50519";"Loans+Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"11881";", ";"50865";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"10675";", ";"50481";"Expert Public";"1013 CS Expert Platform";"1 Avaya CMS"; +"11184";", ";"50178";"Loans+Presell+Outsource";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11406";", ";"50494";"Presell+Out";"1015 CS Cross Out";"1 Avaya CMS"; +"73";", ";"50546";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"11474";", ";"50598";"Loans";"1012 CS Penza Platform";"1 Avaya CMS"; +"2147";", ";"50158";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"11201";", ";"50280";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"11116";", ";"50301";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"11972";", ";"50854";"Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"11293";", ";"50401";"Loans+Card+Activation+Metl.+Cl.";"1012 CS Penza Platform";"1 Avaya CMS"; +"10760";", ";"50561";"Loans+Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"11684";", ";"50736";"Loans+Card";"1011 CS Kursk Platform";"1 Avaya CMS"; +"20623";", ";"50614";"Presell+Out";"1015 CS Cross Out";"1 Avaya CMS"; +"2004";", ";"50554";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"25200";", ";"50338";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"20608";", 0.75";"50522";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"25220";", ";"50456";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"25214";", ";"50451";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11882";", ";"50877";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11398";", ";"50002";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"10028";", ";"50198";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"25171";", ";"50269";"Activation";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11813";", ";"50719";"Presell+Out";"1015 CS Cross Out";"1 Avaya CMS"; +"25172";", ";"50245";"Activation";"1011 CS Kursk Platform";"1 Avaya CMS"; +"174";", ";"50548";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"11283";", ";"50620";"Expert Public";"1013 CS Expert Platform";"1 Avaya CMS"; +"25216";", ";"50424";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"25221";", ";"50722";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11639";", 0.75";"50260";"Loans+Card+Clever";"1012 CS Penza Platform";"1 Avaya CMS"; +"11943";", ";"50722";"Loans";"1012 CS Penza Platform";"1 Avaya CMS"; +"11968";", ";"50515";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11070";", ";"50155";"Loans+Card+Presell+Outsource";"1011 CS Kursk Platform";"1 Avaya CMS"; +"10034";", ";"50768";"Loans+Card+Presell+Outsource";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11359";", ";"50250";"Loans+Card+Presell+Outsource";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11934";", 0.75";"50056";"Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"11424";", ";"50263";"Loans+Presell";"1012 CS Penza Platform";"1 Avaya CMS"; +"25198";", ";"50343";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11323";", ";"50419";"Loans+Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"80";", ";"50637";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"11817";", ";"50528";"Loans+Card";"1011 CS Kursk Platform";"1 Avaya CMS"; +"10021";", ";"50445";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"10702";", ";"50502";"Loans+Card+Deposit+Activ.+Cl.";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11975";", ";"50511";"Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"163";", ";"50640";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"81";", ";"50618";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"25223";", ";"";"";"1012 CS Penza Platform";""; +"25187";", ";"50320";"Loans+Card (Easy)";"1012 CS Penza Platform";"1 Avaya CMS"; +"11071";", ";"50164";"Loans+Card+Deposit+Clever";"1011 CS Kursk Platform";"1 Avaya CMS"; +"25147";", ";"50769";"Presell+Out";"1015 CS Cross Out";"1 Avaya CMS"; +"11420";", ";"50120";"Presell+Out";"1015 CS Cross Out";"1 Avaya CMS"; +"11977";", ";"50860";"Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"11468";", ";"50388";"Loans+Card";"1012 CS Penza Platform";"1 Avaya CMS"; +"25215";", ";"50437";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"25230";", ";"50373";"Loans+Card (Easy)";"1012 CS Penza Platform";"1 Avaya CMS"; +"11317";", 0.5";"50422";"Loans+Card+Clever";"1012 CS Penza Platform";"1 Avaya CMS"; +"11396";", ";"50473";"Loans+Card+Presell+Outsource";"1011 CS Kursk Platform";"1 Avaya CMS"; +"25179";", ";"50125";"Presell";"1012 CS Penza Platform";"1 Avaya CMS"; +"11023";", ";"50723";"Expert Written";"1013 CS Expert Platform";"1 Avaya CMS"; +"2136";", 0.5";"50631";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"8058";", ";"54127";"Loans CA Help CC";"8001 CA Penza";"1 Avaya CMS"; +"2047";", ";"50622";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"11316";", ";"50128";"Loans+Card+Presell+Outsource";"1011 CS Kursk Platform";"1 Avaya CMS"; +"10050";", ";"50837";"Loans+Card+Deposit+Clever";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11851";", 0.5";"50859";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11600";", ";"50438";"Loans+Card+Activation+Metl.+Cl.";"1012 CS Penza Platform";"1 Avaya CMS"; +"11419";", ";"50111";"Presell+Out";"1015 CS Cross Out";"1 Avaya CMS"; +"11967";", ";"50853";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11959";", ";"50242";"Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"11629";", ";"50108";"Loans+Card+Presell+Outsour.Easy";"1012 CS Penza Platform";"1 Avaya CMS"; +"11999";", ";"50828";"Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"11024";", ";"50714";"Expert Written";"1013 CS Expert Platform";"1 Avaya CMS"; +"11800";", ";"50361";"Presell+Out";"1015 CS Cross Out";"1 Avaya CMS"; +"11694";", ";"50783";"Loans+Card+Clever";"1012 CS Penza Platform";"1 Avaya CMS"; +"11962";", ";"50828";"Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"11218";", ";"50311";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"11036";", ";"50267";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"2024";", ";"50599";"Loans";"1012 CS Penza Platform";"1 Avaya CMS"; +"11545";", ";"50695";"Loans+Card";"1012 CS Penza Platform";"1 Avaya CMS"; +"11299";", ";"50402";"Loans+Card+Deposit+Clever";"1012 CS Penza Platform";"1 Avaya CMS"; +"25183";", ";"50259";"Presell";"1012 CS Penza Platform";"1 Avaya CMS"; +"25196";", ";"50325";"Presell";"1012 CS Penza Platform";"1 Avaya CMS"; +"11329";", 0.5";"50431";"Loans+Card+Deposit+Clever";"1012 CS Penza Platform";"1 Avaya CMS"; +"11987";", ";"50172";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"10738";", ";"50552";"Loans+Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"11757";", ";"50808";"Loans+Card+Presell+Outsour.Easy";"1012 CS Penza Platform";"1 Avaya CMS"; +"25195";", ";"50330";"Presell";"1012 CS Penza Platform";"1 Avaya CMS"; +"11156";", ";"50177";"Loans+Card+Activation+Metl.+Cl.";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11295";", ";"50400";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"11267";", ";"50266";"Loans+Card+Deposit+Clever";"1012 CS Penza Platform";"1 Avaya CMS"; +"10614";", ";"50335";"Expert Written";"1013 CS Expert Platform";"1 Avaya CMS"; +"11448";", ";"50394";"Loans+Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"11492";", ";"50212";"Loans+Card+Activation+Metl.+Cl.";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11641";", ";"50743";"Loans+Activation";"1012 CS Penza Platform";"1 Avaya CMS"; +"90";", ";"50560";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"11937";", ";"50231";"Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"2145";", ";"50100";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"11982";", ";"50489";"Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"11425";", ";"50124";"Loans+Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"10280";", ";"50134";"Loans+Card+Deposit+Activ.+Cl.";"1012 CS Penza Platform";"1 Avaya CMS"; +"11361";", ";"50462";"Loans+Card+Presell+Outsource";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11896";", ";"50384";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"25224";", ";"50372";"Loans+Card (Easy)";"1012 CS Penza Platform";"1 Avaya CMS"; +"11763";", ";"50676";"Loans+Card+Presell+Outsour.Easy";"1012 CS Penza Platform";"1 Avaya CMS"; +"11740";", ";"50572";"Loans+Presell";"1012 CS Penza Platform";"1 Avaya CMS"; +"11202";", ";"50283";"Loans+Card+Presell+Outsource";"1011 CS Kursk Platform";"1 Avaya CMS"; +"151";", ";"50568";"Presell";"1012 CS Penza Platform";"1 Avaya CMS"; +"10024";", ";"50380";"Loans";"1011 CS Kursk Platform";""; +"25168";", ";"50288";"Activation";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11157";", ";"50179";"Loans+Card+Presell+Outsource";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11721";", ";"50794";"Loans+Card+Presell (Easy)";"1012 CS Penza Platform";"1 Avaya CMS"; +"10772";", ";"50345";"Loans+Presell+Outsource";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11927";", ";"50895";"Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"94";", ";"50638";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"11261";", ";"50092";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"10149";", ";"50063";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"11848";", ";"50034";"Loans+Activation";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11942";", ";"50540";"Loans";"1012 CS Penza Platform";"1 Avaya CMS"; +"11767";", ";"50791";"Loans+Card";"1011 CS Kursk Platform";"1 Avaya CMS"; +"4001";", ";"50220";"Loans";"1012 CS Penza Platform";"1 Avaya CMS"; +"11620";", ";"50408";"Loans+Card+Activation+Metlife";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11666";", ";"50323";"Loans+Card+Presell (Easy)";"1012 CS Penza Platform";"1 Avaya CMS"; +"10346";", ";"50271";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"11511";", ";"50513";"Loans+Card+Activation+Metl.+Cl.";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11820";", ";"50398";"Loans+Card";"1011 CS Kursk Platform";"1 Avaya CMS"; +"25173";", ";"50277";"Activation";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11919";", ";"50751";"Loans+Card";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11508";", ";"50594";"Loans+Card+Activation+Metlife";"1012 CS Penza Platform";"1 Avaya CMS"; +"10012";", ";"50305";"Loans+Card";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11827";", ";"50562";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11477";", ";"50452";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"11806";", ";"50558";"Loans+Card";"1011 CS Kursk Platform";"1 Avaya CMS"; +"10080";", ";"50167";"Loans+Card+Presell+Outsource";"1011 CS Kursk Platform";"1 Avaya CMS"; +"25213";", ";"50435";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11567";", ";"50347";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"12000";", ";"50060";"Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"10638";", ";"50457";"Loans+Card+Deposit+Activ.+Cl.";"1012 CS Penza Platform";"1 Avaya CMS"; +"11815";", ";"50686";"Presell+Out";"1015 CS Cross Out";"1 Avaya CMS"; +"11667";", ";"50403";"Presell+Out";"1015 CS Cross Out";"1 Avaya CMS"; +"10690";", ";"50306";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"11579";", 0.75";"50692";"Loans+Card+Clever";"1012 CS Penza Platform";"1 Avaya CMS"; +"25177";", ";"50303";"Activation";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11318";", ";"50165";"Loans+Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"11391";", ";"50482";"Loans+Card+Activation+Metl.+Cl.";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11643";", ";"50750";"Loans+Card";"1012 CS Penza Platform";"1 Avaya CMS"; +"11991";", ";"50060";"Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"11276";", ";"50333";"Loans+Card+Deposit+Clever";"1012 CS Penza Platform";"1 Avaya CMS"; +"11185";", ";"50175";"Loans+Card+Presell+Outsource";"1011 CS Kursk Platform";"1 Avaya CMS"; +"189";", ";"50590";"Presell+Out";"1015 CS Cross Out";"1 Avaya CMS"; +"11427";", 0.5";"50344";"Loans+Card+Presell+Outsour.Easy";"1012 CS Penza Platform";"1 Avaya CMS"; +"11928";", ";"50060";"Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"10427";", ";"50355";"Loans+Presell+Outsource";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11570";"Ը, ";"50160";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"139";", ";"50611";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"11186";", ";"50225";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"100";", ";"50595";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"10475";", ";"50069";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"11411";", ";"50495";"Presell+Out";"1015 CS Cross Out";"1 Avaya CMS"; +"11821";", ";"50265";"Loans+Card";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11824";", ";"50781";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11953";", ";"50531";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"25153";", ";"50208";"Presell";"1012 CS Penza Platform";"1 Avaya CMS"; +"11535";", 0.5";"50690";"Loans+Card+Clever";"1012 CS Penza Platform";""; +"25219";", ";"50453";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11621";", ";"50697";"Loans+Card+Clever";"1011 CS Kursk Platform";""; +"10095";", ";"50147";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"11595";", ";"50016";"Loans+Card+Activation+Metlife";"1012 CS Penza Platform";"1 Avaya CMS"; +"11845";", ";"50284";"Loans+Activation";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11187";", ";"50171";"Loans+Card+Presell+Outsource";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11528";", ";"50667";"Loans+Card+Activation+Metl.+Cl.";"1011 CS Kursk Platform";"1 Avaya CMS"; +"10376";", ";"50296";"Loans+Presell+Outsource";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11886";", ";"50530";"Loans+Card";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11449";", ";"50418";"Loans+Card+Presell+Outsour.Easy";"1012 CS Penza Platform";"1 Avaya CMS"; +"10987";", ";"50006";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"10022";", ";"50732";"Expert Written";"1013 CS Expert Platform";"1 Avaya CMS"; +"11172";", ";"50211";"Loans+Card+Activation+Metl.+Cl.";"1012 CS Penza Platform";"1 Avaya CMS"; +"11622";", ";"50721";"Loans+Card";"1011 CS Kursk Platform";""; +"11594";", 0.5";"50364";"Loans+Card";"1012 CS Penza Platform";"1 Avaya CMS"; +"11029";", ";"50707";"Expert Written";"1013 CS Expert Platform";"1 Avaya CMS"; +"11981";", ";"50104";"Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"11048";", ";"50011";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"11008";", ";"50716";"Expert Written";"1013 CS Expert Platform";"1 Avaya CMS"; +"108";", ";"50639";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"11543";", ";"50689";"Loans";"1012 CS Penza Platform";"1 Avaya CMS"; +"11030";", ";"50718";"Expert Written";"1013 CS Expert Platform";"1 Avaya CMS"; +"25197";", ";"50352";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11804";", ";"50255";"Loans+Card";"1011 CS Kursk Platform";"1 Avaya CMS"; +"11646";", ";"50058";"Loans";"1012 CS Penza Platform";"1 Avaya CMS"; +"11744";", ";"50745";"Loans+Card+Activation+Metlife";"1011 CS Kursk Platform";"1 Avaya CMS"; +"10921";", ";"50674";"Loans+Card+Presell+Outsource";"1011 CS Kursk Platform";"1 Avaya CMS"; +"25193";", ";"50336";"Presell";"1012 CS Penza Platform";"1 Avaya CMS"; +"25146";", ";"50659";"Presell+Out";"1015 CS Cross Out";"1 Avaya CMS"; +"2141";", ";"50578";"Loans";"1012 CS Penza Platform";"1 Avaya CMS"; +"11644";", ";"50461";"Loans";"1012 CS Penza Platform";"1 Avaya CMS"; +"11961";", ";"50062";"Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"10120";", ";"50169";"Loans+Card+Deposit+Activ.+Cl.";"1012 CS Penza Platform";"1 Avaya CMS"; +"11760";", ";"50221";"Loans+Card+Presell (Easy)";"1012 CS Penza Platform";"1 Avaya CMS"; +"2002";", ";"50609";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"11297";", 0.5";"50404";"Loans+Card+Deposit+Clever";"1012 CS Penza Platform";"1 Avaya CMS"; +"11032";", ";"50705";"Expert Written";"1013 CS Expert Platform";"1 Avaya CMS"; +"11033";", ";"50708";"Expert Written";"1013 CS Expert Platform";"1 Avaya CMS"; +"11645";", ";"50729";"Expert Calls";"1013 CS Expert Platform";"1 Avaya CMS"; +"11947";", ";"50711";"Loans";"1012 CS Penza Platform";"1 Avaya CMS"; +"110";", ";"50524";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"11374";", ";"50081";"Loans+Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"11814";", ";"50246";"Presell+Out";"1015 CS Cross Out";"1 Avaya CMS"; +"20651";", ";"50596";"Loans+Presell+Outsource";"1012 CS Penza Platform";"1 Avaya CMS"; +"141";", ";"50520";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"11140";", ";"50110";"Reception";"1011 CS Kursk Platform";"1 Avaya CMS"; +"20642";", ";"50641";"Presell+Out+Outsource";"1015 CS Cross Out";"1 Avaya CMS"; +"25218";", ";"50426";"Loans";"1011 CS Kursk Platform";"1 Avaya CMS"; diff --git a/docs/files/125/CS TotalCount.csv b/docs/files/125/CS TotalCount.csv new file mode 100644 index 0000000..3ec4396 --- /dev/null +++ b/docs/files/125/CS TotalCount.csv @@ -0,0 +1,4 @@ + 391 + 104 + 75 + 5 diff --git a/docs/files/aXP1ItlpsDE.jpg b/docs/files/aXP1ItlpsDE.jpg new file mode 100644 index 0000000..f7359b3 Binary files /dev/null and b/docs/files/aXP1ItlpsDE.jpg differ diff --git a/docs/files/audio13-895.txt b/docs/files/audio13-895.txt new file mode 100644 index 0000000..0fe01b5 --- /dev/null +++ b/docs/files/audio13-895.txt @@ -0,0 +1 @@ +03ARzCQLZWY3pj1lF1k0nTWwjp2whL31yX=jOk430bzC5m8Cdal1SQopBwnQv1X1ZkPnb2NVzsZncxQjsF3Q7ACGDR3Q41kOEk=J0vFdG6I2NDzCr5Ttj1chWQVzvwVGF30hIdwf9vwjzC5bh1jal1CMc92Mmp2wZhL31X1kQ3Q3Q3Q3E1l1k0nTWwjG3NXzeBGDY31X=jOk=xNtfHBwhG3NXzBGDY31dX7jaJtj1mzC5bejQOke2QIFv0hI31X1GkPcLWw3RCPktj1fAamQh9sQoF3wkbk156I2GXR3GyL2GfTSkQD6dwyL2GfTfMjFZ3Nyp2wV9B56L2MXfzsNkTWwWTSQD6dwbXisNXHv1l1f0XR3a0cLWwjzC5L1jOk7sWsD6WQfF2w6I2ND5zC5btj16I2GXR3Geop30kbSykZ2OiGjiQI1kOk1mwXRWNvzZ31XejOkZBMv630D56WQfF2wkbk1T1kOAk03Nkbk13Q3Q3Q3QQktj1fRdwnY31X=Tj5btj1hRFMJzC5fb8Cal1fwyG3NkXvONkisNXHmsXzBGDY3G1X=jOk1xNtHBwhG23NXzBGDY31X1kQ3tQ3Q3Q31l1k0nTWwEjG3NkbCYctj1tzCb5RpuYl1fGkbk1i6duQmN2Yktj1XT2NyRzmwXRWNkbSal1CMBkbk1i6uQmN2YktjD1iFWwXR60nTWwjzKC5Jtj1bRdGD6WQfSF2wkbfaDAjOk=WsZXT2Nkbfal1CG3pdywD6WQfF2wkbSODANjOk=WsiFWwXzfUlY1SQD6dwfF3NXR3GhyT30cLWNkbSykZ2ZOiGjQI1kOkbdwhR460nTWwjzC5Ttj1thzC5k1jNLija81kO6kZ2NnTWsfRdwnY3e1XajOkAmwcL2MvzfsNozC5Ttj1hRFwXkF31Xij5btj1hRFQZhRdwkbk1i6uQmN2hYktj1LFdwbR60nThWwjzfUl1SQD6dwyzT30cLWNkbCal1k0bbHsGkbSyb=jOk0vi1X1CQLZWY3pj1l1rk0nTWwjzC5Jtj1tszC5k1j1l1kwn6dGdVYmwbzC5btj1nzfYUl1SQopBwnQmsDprv0yT30cLWNkbk1b31kOk1mwXRWNcL2QQoIWwjzC5kN3Q3Q3NQ3zkOk1mwXRWNDpd2QfYW0kbSyk=j1lY1kwnY2Mkbk1i6uQSmN2Yktj1fRdwnY3r1X1xYotj1cQ2QXLd2MvzsNozC5ctj1oaRdGcR3ND6WQfF2wkkbCYTtj1chWQVzv4wVG30hI31gVj1rY62NkRpQo6dGyT30c9LWNkbk1n6dQIF314l1SwkbfaTtj1WR6YwVG30hI2QoF3wkbbSODAjOk1xNtHBwhSG3NcL2QoIWwjzC5yTtj1cQ2QXL2Mvzs9NoT30cLWNkbk1JZdxYTcCaktj1i6W0kBbCODAjOk=xNtHBwfhG3NcL2QoIWwjzC95kev0ktj1vL2NXzeC5kN3Q3Q3Q3zkOkY1mwXRWNvzdGDp2wfoRWNkbSyJ=jOk0vF1X1CQLZWY3pj1l1bk0nTWwjzC5ctj1trzC5k1j1l1kwn6dGfVYmwbzC5btj1nzfQUl1kwIzmsXzBGDYY31XZjal1CGtG2M65hdGIRdwf9vwjzfUrT \ No newline at end of file diff --git a/docs/files/exceles.xls b/docs/files/exceles.xls new file mode 100644 index 0000000..56c5c10 Binary files /dev/null and b/docs/files/exceles.xls differ diff --git a/docs/files/gh.docx b/docs/files/gh.docx new file mode 100644 index 0000000..d8c0314 Binary files /dev/null and b/docs/files/gh.docx differ diff --git a/docs/files/localhost.sql b/docs/files/localhost.sql new file mode 100644 index 0000000..2eb324d --- /dev/null +++ b/docs/files/localhost.sql @@ -0,0 +1,399 @@ +-- phpMyAdmin SQL Dump +-- version 4.5.4.1deb2ubuntu2 +-- http://www.phpmyadmin.net +-- +-- Хост: localhost +-- Время создания: Окт 14 2016 г., 16:11 +-- Версия сервера: 5.7.15-0ubuntu0.16.04.1 +-- Версия PHP: 7.0.8-0ubuntu0.16.04.3 + +SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; +SET time_zone = "+00:00"; + + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8mb4 */; + +-- +-- База данных: `print` +-- +DROP DATABASE `print`; +CREATE DATABASE IF NOT EXISTS `print` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; +USE `print`; + +-- -------------------------------------------------------- + +-- +-- Структура таблицы `cartridges` +-- + +DROP TABLE IF EXISTS `cartridges`; +CREATE TABLE `cartridges` ( + `id` int(11) NOT NULL, + `date` date NOT NULL, + `k_sp3500xe` tinyint(4) NOT NULL, + `k_12` tinyint(4) DEFAULT NULL, + `k_285` tinyint(4) DEFAULT NULL, + `k_505` tinyint(4) DEFAULT NULL, + `k_5945` tinyint(4) DEFAULT NULL, + `k_209` tinyint(4) DEFAULT NULL, + `k_83` tinyint(4) DEFAULT NULL, + `k_oki_drum` tinyint(4) DEFAULT NULL, + `k_oki_tuba` tinyint(4) DEFAULT NULL, + `k_color` tinyint(4) DEFAULT NULL, + `k_205` tinyint(4) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Дамп данных таблицы `cartridges` +-- + +INSERT INTO `cartridges` (`id`, `date`, `k_sp3500xe`, `k_12`, `k_285`, `k_505`, `k_5945`, `k_209`, `k_83`, `k_oki_drum`, `k_oki_tuba`, `k_color`, `k_205`) VALUES +(188, '2016-05-31', 0, 12, 6, 4, 3, 4, 4, 2, 2, 1, 5), +(189, '2016-05-31', 0, 0, -2, 0, 0, 0, 0, 0, 0, 0, 0), +(190, '2016-06-06', 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0), +(191, '2016-06-06', 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), +(192, '2016-06-08', 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0), +(193, '2016-06-08', 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0), +(194, '2016-06-10', 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0), +(195, '0000-00-00', -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), +(196, '2016-06-09', 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0), +(197, '2016-06-14', 0, -2, -1, 0, 0, 0, 0, 0, 0, 0, 0), +(198, '2016-06-14', 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0), +(199, '2016-06-15', 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0), +(200, '2016-06-15', 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), +(201, '2016-06-16', 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0), +(202, '2016-06-16', 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0), +(203, '2016-06-16', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), +(204, '2016-06-16', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), +(205, '2016-06-16', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), +(206, '2016-06-16', 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0), +(207, '2016-06-20', 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0), +(208, '2016-06-22', 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0), +(209, '2016-06-22', 0, 0, 6, 1, 0, 2, 0, 0, 0, 0, 0), +(210, '2016-06-22', 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0), +(211, '2016-06-23', 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0), +(212, '2016-06-24', 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0), +(213, '2016-06-28', 0, 0, -2, 0, 0, 0, 0, 0, 0, 0, 0), +(214, '2016-06-28', 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0), +(215, '2016-06-29', -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0), +(216, '2016-06-29', 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), +(217, '2016-06-29', -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), +(218, '2016-06-29', 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0), +(219, '2016-06-29', 0, 0, -2, 0, 0, -1, 0, 0, 0, 0, 0), +(220, '2016-07-01', 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0), +(221, '2016-07-01', 0, 0, 4, 2, 0, 0, 0, 0, 0, 0, 0), +(222, '2016-07-04', 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0), +(223, '2016-07-06', 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0), +(224, '2016-07-07', 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0), +(225, '2016-07-08', 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0), +(226, '2016-07-08', 0, 0, -2, 0, 0, 0, 0, 0, 0, 0, 0), +(227, '2016-07-11', 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0), +(228, '2016-07-12', 0, 0, 4, 0, 2, 0, 0, 0, 0, 0, 0), +(229, '0000-00-00', 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0), +(230, '2016-07-12', 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0), +(231, '2016-07-13', 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0), +(232, '2016-07-18', 0, 0, -4, 0, 0, 0, 0, 0, 0, 0, 0), +(233, '2016-07-18', -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), +(234, '2016-07-18', -1, 0, -6, 0, 0, 0, 0, 0, 0, 0, 0), +(235, '2016-07-18', 1, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0), +(236, '0000-00-00', 1, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0), +(237, '2016-07-19', 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0), +(238, '2016-07-19', 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0), +(239, '2016-07-25', 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0), +(240, '2016-07-27', 0, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0), +(241, '2016-07-27', 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), +(242, '2016-07-25', 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0), +(243, '2016-07-28', 0, -3, 0, 0, 0, 0, 0, 0, 0, 0, 0), +(244, '2016-07-28', 0, 0, 0, -2, 0, 0, 0, 0, 0, 0, 0), +(245, '2016-07-28', 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0), +(246, '2016-07-29', 0, 4, 6, 2, 0, 0, 2, 0, 0, 0, 0), +(247, '0000-00-00', 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0), +(248, '0000-00-00', 0, 0, 0, 0, 0, -3, 0, 0, 0, 0, 0), +(249, '2016-07-29', 0, 2, 1, 0, 0, 4, 0, 0, 0, 0, 0), +(250, '2016-08-01', 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0), +(251, '2016-08-04', 0, -1, 0, 0, 0, -1, 0, 0, 0, 0, 0), +(252, '2016-08-05', 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0), +(253, '2016-08-05', 0, 0, -6, 0, 0, -4, 0, 0, 0, 0, 0), +(254, '2016-08-09', -1, 1, 9, 1, 0, 6, 0, 0, 0, 0, 0), +(255, '2016-08-15', 0, -1, 0, 0, 0, -1, 0, 0, 0, -1, 0), +(256, '2016-08-16', 0, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0), +(257, '2016-08-19', 0, 0, 0, 2, 0, 4, 0, 0, 0, 2, 0), +(258, '0000-00-00', 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), +(259, '0000-00-00', 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0), +(260, '2016-08-22', -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), +(261, '2016-08-24', 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), +(262, '0000-00-00', 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0), +(263, '2016-08-24', -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), +(264, '2016-08-25', 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0), +(265, '2016-08-29', 0, -1, 0, 0, 0, -2, 0, 0, 0, 0, 0), +(266, '2016-08-29', 0, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0), +(267, '2016-08-31', 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), +(268, '2016-09-02', 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0), +(269, '2016-09-06', 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0), +(270, '2016-09-07', -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), +(271, '2016-09-12', 0, 6, -2, 1, 3, -5, -2, 0, 1, 0, 0), +(272, '2016-09-16', 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0), +(273, '2016-09-16', 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0), +(274, '2016-09-16', 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0); + +-- -------------------------------------------------------- + +-- +-- Структура таблицы `cartriges` +-- + +DROP TABLE IF EXISTS `cartriges`; +CREATE TABLE `cartriges` ( + `id` int(11) NOT NULL, + `name` varchar(50) NOT NULL, + `action` tinyint(1) NOT NULL DEFAULT '1' +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Дамп данных таблицы `cartriges` +-- + +INSERT INTO `cartriges` (`id`, `name`, `action`) VALUES +(1, 'sp3500xe', 1), +(2, '12a', 1), +(3, '285a', 1), +(4, '505', 1), +(5, '5945', 1), +(6, '209', 1), +(7, '83', 1), +(8, 'oki drum', 1), +(9, 'oki tuba', 1), +(10, 'color', 1), +(11, '205', 1); + +-- -------------------------------------------------------- + +-- +-- Структура таблицы `departments` +-- + +DROP TABLE IF EXISTS `departments`; +CREATE TABLE `departments` ( + `id` int(11) NOT NULL, + `name` char(50) CHARACTER SET utf8 DEFAULT '0', + `action` tinyint(1) NOT NULL DEFAULT '1' +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; + +-- +-- Дамп данных таблицы `departments` +-- + +INSERT INTO `departments` (`id`, `name`, `action`) VALUES +(1, 'склад', 1), +(2, 'IT', 1), +(3, 'АХО', 1), +(4, 'Директор', 1), +(5, 'СБ', 1), +(6, 'HR_(админы)', 1), +(7, 'HR', 1), +(8, 'ОРП', 0), +(9, 'Аналитики', 1), +(10, 'ГОК', 1), +(11, 'Call-Center', 1), +(12, 'Collection', 1), +(13, 'BackOffice', 1), +(14, 'ОСКО', 1), +(15, 'Переговорка', 1); + +-- -------------------------------------------------------- + +-- +-- Структура таблицы `floor` +-- + +DROP TABLE IF EXISTS `floor`; +CREATE TABLE `floor` ( + `id` int(11) NOT NULL, + `name` varchar(50) NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Дамп данных таблицы `floor` +-- + +INSERT INTO `floor` (`id`, `name`) VALUES +(1, '1 этаж'), +(2, '2 этаж'), +(3, '3 этаж'), +(4, '4 этаж'), +(5, '9 этаж'); + +-- -------------------------------------------------------- + +-- +-- Структура таблицы `print` +-- + +DROP TABLE IF EXISTS `print`; +CREATE TABLE `print` ( + `id` int(11) NOT NULL, + `name` char(50) NOT NULL DEFAULT '0', + `model` char(50) NOT NULL DEFAULT '0', + `sn` char(50) NOT NULL DEFAULT '0', + `floor` char(50) DEFAULT NULL, + `unit` varchar(50) NOT NULL DEFAULT '0', + `inventar` varchar(50) NOT NULL DEFAULT '0', + `kartrig` char(50) NOT NULL DEFAULT '0', + `department` char(50) DEFAULT NULL, + `status` int(11) NOT NULL, + `functionals` tinytext, + `img` varchar(255) NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Дамп данных таблицы `print` +-- + +INSERT INTO `print` (`id`, `name`, `model`, `sn`, `floor`, `unit`, `inventar`, `kartrig`, `department`, `status`, `functionals`, `img`) VALUES +(1, 'PRN0175', 'HP LJM1212', 'CNG9D5K03G', '1', '0055-7357', 'аренда', '85A', 'ГОК', 1, 'Печать, ксерокопия', ''), +(2, 'DSK0173', 'HP LJ 3030', 'CNBF180826', '1', '0000-0297', '3-21191', '12A', 'ГОК', 1, 'Печать, ксерокопия', ''), +(3, 'dsk96579', 'HP LJ 3030', 'CNBF181260', '4', '0003-3724', '3-21445', '12A', 'ОСКО', 1, '', ''), +(4, 'MININT-15MK94U', 'HP LJ 3030', 'CNBF033770', '5', '0000-0445', '3-21333', '12A', 'Аналитики', 1, '', ''), +(5, 'PRN0089', 'HP LJM4345', 'CN1N137307', '4', '0046-0980', '1-14040', 'Q5945A', 'Collection', 1, '', ''), +(6, 'PRN0082', 'oki mb460', 'AL08036096', '1', '0040-1056', 'аренда', 'туба polytoner PTO-460', 'ГОК', 1, '', ''), +(7, 'PRN0082', 'Samsung SCX-4824FN', 'sn-none', '1', '0040-4552', 'аренда', '209', '', 4, '', ''), +(8, 'dsk0000', 'HP LJ 3020', 'CNBF043705', '2', '0000-0176', '3-21441', '12A', 'none', 3, NULL, ''), +(9, 'DKUR0151', 'HP LJ 3030', 'CNBF033911', '2', '0000-5280', '3-21330', '12A', 'СБ', 1, NULL, ''), +(10, 'dsk0000', 'HP LJ 3030', 'CNBF105587', '2', '0000-3949', '3-21338', '12A', 'Call-Center', 3, '', ''), +(11, 'PRN0085', 'HP LJM1212', 'CNG9C8B03X', '2', '0006-7042', 'аренда', '85A', 'АХО', 1, NULL, ''), +(12, 'PRN0084', 'oki mb460', 'AL09039882', '', '0040-1058', 'аренда', 'туба polytoner PTO-460', '', 5, '', ''), +(13, 'prn0104', 'HP LJ 3055', 'CNCJ135105', '4', '0004-1742', 'аренда', '12A', 'Collection', 1, NULL, ''), +(14, 'PRN0116', 'Samsung SCX-4833', 'Z5P7BJIC40005MY', '1', '0043-8500', 'аренда', '205', 'Call-Center', 1, '', ''), +(15, 'PRN0032', 'Samsung SCX-4824FN', '6568BALZB01062M', '2', '0006-0514', 'аренда', '209', 'Call-Center', 1, '', ''), +(16, 'PRN0083', 'oki mb460', 'al03029587', '4', '0040-1057', 'аренда', 'туба polytoner PTO-460', 'Call-Center', 1, '', ''), +(17, 'PRN0084', 'Samsung SCX-4824FN', 'sn-none', '2', '0005-4938', 'аренда', '209', 'Call-Center', 4, NULL, ''), +(19, 'PRN0141', 'HP LJM1212', 'CNG9D8M19R', '2', '0050-9235', 'аренда', '85A', 'Call-Center', 1, '', ''), +(20, 'PRN0092', 'HP Color LaserJet CP2025n', 'CNHSN03557', '3', '0007-3604', '3-26541', 'color', 'IT', 1, NULL, ''), +(21, 'PRN0117', 'Samsung SCX-5637FR', 'Z5W3BJIC700002H', '3', '0043-8502', 'аренда', '205', 'OpenSpaсe', 1, 'печать, сканирование на e-mail, ксерокопия', 'scx5637.jpeg'), +(22, 'dsk0981', 'HP LJ 3030', 'CNBF180698', '4', '0000-0062', '3-21332', '12A', 'Collection', 1, NULL, ''), +(23, 'dsk1550', 'HP LJ 3030', 'CNBF145994', '4', '0000-0162', '3-21280', '12A', 'Переговорка', 1, NULL, ''), +(24, 'prn0091', 'HP LJM1212', 'CNG9C8B044', '4', '0006-7041', 'аренда', '85A', 'Директор', 1, NULL, ''), +(25, 'PRN0120', 'Samsung SCX-5637FR', 'Z5W3BJDC60003QD', '1', '0043-8440', 'аренда', '205', 'Call-Center', 1, '', ''), +(26, 'DSK4719', 'HP LJ 3020', 'CNBF012454', '5', '0000-5428', '3-21202', '12A', 'BackOffice', 1, NULL, ''), +(27, 'PRN0173', 'HP LJM1212', 'CNJ8F3N4R4', '2', '0053-3585', 'аренда', '85A', 'Call-Center', 1, NULL, ''), +(28, 'PRN0090', 'HP LJM4345', 'CNDVB33GBG', '1', '0005-4922', '1-14064', 'Q5945A', 'ГОК', 1, '', ''), +(29, 'PRN0047', 'HP LJ 2035', 'CNCK514977', '5', '0006-0613', 'аренда', '505А', 'BackOffice', 1, NULL, ''), +(31, 'PRN0111', 'Samsung SCX-4833', 'Z5P7BJIC4000CQA', '', '0043-8439', 'аренда', '205', '', 3, '', ''), +(32, 'PRN0115', 'Samsung SCX-4833', 'Z5P7BJIC40005EW', '', '0043-8501', 'аренда', '205', '', 5, '', ''), +(33, 'dsk0651', 'HP LJ 3030', 'CNBF146225', '5', '0045-5575', '3-21256', '12A', 'HR', 1, NULL, ''), +(34, 'PRN0094', 'Samsung SCX-4824FN', '6568BALZB01138X', '5', '0006-0627', 'аренда', '209', 'HR_(админы)', 1, NULL, ''), +(35, 'PRN0178', 'HP LJ M1522', 'VNHTB1HGY1', '', '0005-2237', '3-26756', '36A', '', 3, '', ''), +(36, 'dsk0000', 'HP LJ 3030', 'CNBF105615', 'none', '0000-0652', '3-21206', '12A', 'none', 3, NULL, ''), +(37, 'dsk0000', 'HP LJ 3030', 'CNBF170999', 'none', '0000-0409', '3-21247', '12A', 'none', 3, NULL, ''), +(38, 'dsk0000', 'HP LJ 3030', 'CNBF160377', 'none', '0000-2888', '?', '12A', 'none', 3, NULL, ''), +(39, 'prn0083', 'Samsung SCX-4824FN', '-', '2', '-', '-', '209', 'Call-Center', 4, NULL, ''), +(40, 'prn0180', 'HP LJM1212', 'CNG9D8R04N', '2', '0043-8493', '?', '85A', 'Call-Center', 1, NULL, ''), +(41, 'PRN0185', 'Ricoh Aficio SP 3510SF', 'T332Q602704', '2', '0045-1758', 'аренда', 'sp3500xe', 'Call-Center', 1, NULL, ''), +(42, 'prn0183', 'HP m127fn', 'CNB9H5Y7S1', '5', '0072-9776', 'аренда', '83a', 'HR', 1, '', ''), +(43, 'prn0115', 'Samsung scx-4833fp', 'Z5P7BJIC4001F9W', '5', '0040-1219', '', '205', 'BackOffice', 1, '', ''); + +-- -------------------------------------------------------- + +-- +-- Структура таблицы `status` +-- + +DROP TABLE IF EXISTS `status`; +CREATE TABLE `status` ( + `id` int(11) NOT NULL, + `name` char(50) NOT NULL DEFAULT '0' +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Дамп данных таблицы `status` +-- + +INSERT INTO `status` (`id`, `name`) VALUES +(1, 'В работе'), +(2, 'В ремонте'), +(3, 'На складе (рабочий)'), +(4, 'На складе (списан)'), +(6, 'Подмена (установлен)'), +(7, 'Подмена (снят)'); + +-- +-- Индексы сохранённых таблиц +-- + +-- +-- Индексы таблицы `cartridges` +-- +ALTER TABLE `cartridges` + ADD PRIMARY KEY (`id`); + +-- +-- Индексы таблицы `cartriges` +-- +ALTER TABLE `cartriges` + ADD PRIMARY KEY (`id`); + +-- +-- Индексы таблицы `departments` +-- +ALTER TABLE `departments` + ADD PRIMARY KEY (`id`); + +-- +-- Индексы таблицы `floor` +-- +ALTER TABLE `floor` + ADD PRIMARY KEY (`id`); + +-- +-- Индексы таблицы `print` +-- +ALTER TABLE `print` + ADD PRIMARY KEY (`id`), + ADD KEY `status` (`status`); + +-- +-- Индексы таблицы `status` +-- +ALTER TABLE `status` + ADD PRIMARY KEY (`id`); + +-- +-- AUTO_INCREMENT для сохранённых таблиц +-- + +-- +-- AUTO_INCREMENT для таблицы `cartridges` +-- +ALTER TABLE `cartridges` + MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=275; +-- +-- AUTO_INCREMENT для таблицы `cartriges` +-- +ALTER TABLE `cartriges` + MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=12; +-- +-- AUTO_INCREMENT для таблицы `departments` +-- +ALTER TABLE `departments` + MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=16; +-- +-- AUTO_INCREMENT для таблицы `floor` +-- +ALTER TABLE `floor` + MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=6; +-- +-- AUTO_INCREMENT для таблицы `print` +-- +ALTER TABLE `print` + MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=44; +-- +-- AUTO_INCREMENT для таблицы `status` +-- +ALTER TABLE `status` + MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=8; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; diff --git a/docs/files/nas/1503182017.msg b/docs/files/nas/1503182017.msg new file mode 100644 index 0000000..615afad Binary files /dev/null and b/docs/files/nas/1503182017.msg differ diff --git a/docs/files/nas/171820032018.msg b/docs/files/nas/171820032018.msg new file mode 100644 index 0000000..0c1246c Binary files /dev/null and b/docs/files/nas/171820032018.msg differ diff --git a/docs/files/nas/171820032018.pdf b/docs/files/nas/171820032018.pdf new file mode 100644 index 0000000..15cad47 Binary files /dev/null and b/docs/files/nas/171820032018.pdf differ diff --git a/docs/files/nas/Scan f001.pdf b/docs/files/nas/Scan f001.pdf new file mode 100644 index 0000000..894e10f Binary files /dev/null and b/docs/files/nas/Scan f001.pdf differ diff --git a/docs/files/nas/Scan00716344.pdf b/docs/files/nas/Scan00716344.pdf new file mode 100644 index 0000000..3a3dea7 Binary files /dev/null and b/docs/files/nas/Scan00716344.pdf differ diff --git a/docs/files/nas/Scan1503182017.pdf b/docs/files/nas/Scan1503182017.pdf new file mode 100644 index 0000000..51cf159 Binary files /dev/null and b/docs/files/nas/Scan1503182017.pdf differ diff --git a/docs/files/nas/closed-270220181856.pdf b/docs/files/nas/closed-270220181856.pdf new file mode 100644 index 0000000..ded1701 Binary files /dev/null and b/docs/files/nas/closed-270220181856.pdf differ diff --git a/docs/files/nas/request-270220181856.msg b/docs/files/nas/request-270220181856.msg new file mode 100644 index 0000000..c2a8626 Binary files /dev/null and b/docs/files/nas/request-270220181856.msg differ diff --git a/docs/files/nas/request.msg b/docs/files/nas/request.msg new file mode 100644 index 0000000..d9b37f0 Binary files /dev/null and b/docs/files/nas/request.msg differ diff --git a/docs/files/sea.log b/docs/files/sea.log new file mode 100644 index 0000000..5aaa388 --- /dev/null +++ b/docs/files/sea.log @@ -0,0 +1,10 @@ +Self Extractor execution begins. +Window class registered. +Extracting files. +Dialog: Preparing to install... +Extracting to: \\dsk1111\d$\Install\Nice\Nice WFM +Self Extractor execution begins. +Window class registered. +Extracting files. +Dialog: Preparing to install... +Extracting to: \\dsk1111\d$\Install\Nice\Nice WFM diff --git a/docs/files/Заявка .msg b/docs/files/Заявка .msg new file mode 100644 index 0000000..d002292 Binary files /dev/null and b/docs/files/Заявка .msg differ diff --git a/images/print/1212.png b/images/print/1212.png new file mode 100644 index 0000000..bdf4712 Binary files /dev/null and b/images/print/1212.png differ diff --git a/images/print/2035.png b/images/print/2035.png new file mode 100644 index 0000000..a40a6a1 Binary files /dev/null and b/images/print/2035.png differ diff --git a/images/print/3030.png b/images/print/3030.png new file mode 100644 index 0000000..f8c150d Binary files /dev/null and b/images/print/3030.png differ diff --git a/images/print/3055.png b/images/print/3055.png new file mode 100644 index 0000000..f8c150d Binary files /dev/null and b/images/print/3055.png differ diff --git a/images/print/4345.png b/images/print/4345.png new file mode 100644 index 0000000..b84d34f Binary files /dev/null and b/images/print/4345.png differ diff --git a/images/print/4555.jpg b/images/print/4555.jpg new file mode 100644 index 0000000..dc8d00f Binary files /dev/null and b/images/print/4555.jpg differ diff --git a/images/print/4824.png b/images/print/4824.png new file mode 100644 index 0000000..360dee4 Binary files /dev/null and b/images/print/4824.png differ diff --git a/images/print/4833.png b/images/print/4833.png new file mode 100644 index 0000000..5cd525c Binary files /dev/null and b/images/print/4833.png differ diff --git a/images/print/5637.png b/images/print/5637.png new file mode 100644 index 0000000..5bd77fa Binary files /dev/null and b/images/print/5637.png differ diff --git a/images/print/color3.png b/images/print/color3.png new file mode 100644 index 0000000..474d304 Binary files /dev/null and b/images/print/color3.png differ diff --git a/images/print/color9.png b/images/print/color9.png new file mode 100644 index 0000000..62d70d9 Binary files /dev/null and b/images/print/color9.png differ diff --git a/images/print/error wfm.png b/images/print/error wfm.png new file mode 100644 index 0000000..4deee66 Binary files /dev/null and b/images/print/error wfm.png differ diff --git a/images/print/m127.png b/images/print/m127.png new file mode 100644 index 0000000..17cb260 Binary files /dev/null and b/images/print/m127.png differ diff --git a/images/print/oki.png b/images/print/oki.png new file mode 100644 index 0000000..d1b6b60 Binary files /dev/null and b/images/print/oki.png differ diff --git a/images/print/ricoh.png b/images/print/ricoh.png new file mode 100644 index 0000000..b4523c5 Binary files /dev/null and b/images/print/ricoh.png differ diff --git a/images/print/scx5637.jpeg_old b/images/print/scx5637.jpeg_old new file mode 100644 index 0000000..d492a0d Binary files /dev/null and b/images/print/scx5637.jpeg_old differ diff --git a/images/products/product1.jpg b/images/products/product1.jpg new file mode 100644 index 0000000..fe1f6ca Binary files /dev/null and b/images/products/product1.jpg differ diff --git a/images/products/product2.jpg b/images/products/product2.jpg new file mode 100644 index 0000000..0c494a6 Binary files /dev/null and b/images/products/product2.jpg differ diff --git a/images/products/product3.jpg b/images/products/product3.jpg new file mode 100644 index 0000000..868d880 Binary files /dev/null and b/images/products/product3.jpg differ diff --git a/images/products/product4.jpg b/images/products/product4.jpg new file mode 100644 index 0000000..51d763b Binary files /dev/null and b/images/products/product4.jpg differ diff --git a/images/products/product5.jpg b/images/products/product5.jpg new file mode 100644 index 0000000..c78e6e4 Binary files /dev/null and b/images/products/product5.jpg differ diff --git a/images/products/product6.jpg b/images/products/product6.jpg new file mode 100644 index 0000000..7f21bd0 Binary files /dev/null and b/images/products/product6.jpg differ diff --git a/img/new.png b/img/new.png new file mode 100644 index 0000000..3563363 Binary files /dev/null and b/img/new.png differ diff --git a/img/not_img_print.png b/img/not_img_print.png new file mode 100644 index 0000000..ff85994 Binary files /dev/null and b/img/not_img_print.png differ diff --git a/img/rgb.png b/img/rgb.png new file mode 100644 index 0000000..deff143 Binary files /dev/null and b/img/rgb.png differ diff --git a/index.php b/index.php new file mode 100644 index 0000000..ead257c --- /dev/null +++ b/index.php @@ -0,0 +1,34 @@ +run(); // \ No newline at end of file diff --git a/js/multiselect.js b/js/multiselect.js new file mode 100644 index 0000000..efff597 --- /dev/null +++ b/js/multiselect.js @@ -0,0 +1,48 @@ +var MultiSelect = (function (GLOB) { + // Добавить элементы в поле назначения: + function moveItems(btn, srcSelect, dstSelect) { + btn.onclick = function () { + var i; + for (i = srcSelect.options.length - 1; i >= 0; i -= 1) { + if (srcSelect.options[i].selected) { + dstSelect.add(new Option(srcSelect.options[i].text, srcSelect.options[i].value)); + srcSelect.remove(i); + } + } + }; + } + // Подготовка данных к отправке: + function formSubmit(element) { + // Ф-ция делает все элеметы спика select выбраными: + function makeSelect(element) { + var i; + for (i = 0; i < element.options.length; i += 1) { + element.options[i].selected = true; + } + } + // Ниже мы всего лишь кроссбрауз. устанавливаем слушатель + // события отправки формы: + if (GLOB.document.addEventListener) { + element.form.addEventListener("submit", function () { + makeSelect(element); + }, true); + } else if (GLOB.document.attachEvent) { + element.form.attachEvent("onsubmit", function () { + makeSelect(element); + }); + } else { + element.form.onsubmit = function () { + makeSelect(element); + }; + } + } + return function (srcSelect, dstSelect, takeBtn, dropBtn) { + return { + init : function (srcSelect, dstSelect, takeBtn, dropBtn) { + moveItems(takeBtn, srcSelect, dstSelect); + moveItems(dropBtn, dstSelect, srcSelect); + formSubmit(dstSelect); + } + }.init(srcSelect, dstSelect, takeBtn, dropBtn); + }; +}(this)); \ No newline at end of file diff --git a/js/search_phonebook.js b/js/search_phonebook.js new file mode 100644 index 0000000..199955a --- /dev/null +++ b/js/search_phonebook.js @@ -0,0 +1,30 @@ +$(function(){ + +//Живой поиск +$('.searching').bind("change keyup input click", function() { + if(this.value.length >= 2){ + $.ajax({ + type: 'post', + url: "phonebook/search", //Путь к обработчику + data: {'searching':this.value}, + response: 'text', + success: function(data){ + $(".search_result").html(data).fadeIn(); //Выводим полученые данные в списке + } + }); + } +}); + +/*$(".search_result").hover(function(){ + $(".who").blur(); //Убираем фокус с input +}) + +//При выборе результата поиска, прячем список и заносим выбранный результат в input +$(".search_result").on("click", "li", function(){ + s_user = $(this).text(); + //$(".who").val(s_user).attr('disabled', 'disabled'); //деактивируем input, если нужно + $(".search_result").fadeOut(); +})*/ + +}) + diff --git a/lib/.3254htaccess b/lib/.3254htaccess new file mode 100644 index 0000000..48dd490 --- /dev/null +++ b/lib/.3254htaccess @@ -0,0 +1,21 @@ + + php_flag engine Off + + + php_flag engine Off + + + php_flag engine Off + + + Options -ExecCGI + + +RemoveHandler .cgi .pl .py .pyc .pyo .phtml .php .php3 .php4 .php5 .php6 .pcgi .pcgi3 .pcgi4 .pcgi5 .pchi6 .inc +RemoveType .cgi .pl .py .pyc .pyo .phtml .php .php3 .php4 .php5 .php6 .pcgi .pcgi3 .pcgi4 .pcgi5 .pchi6 .inc +SetHandler None +SetHandler default-handler + +# Remove both lines below if you want to render HTML files from the upload folder +AddType text/plain .html +AddType text/plain .htm diff --git a/lib/ckfinder/CHANGELOG.html b/lib/ckfinder/CHANGELOG.html new file mode 100644 index 0000000..8355ff5 --- /dev/null +++ b/lib/ckfinder/CHANGELOG.html @@ -0,0 +1,85 @@ + + + + + CKFinder Changelog + + +

    CKFinder Changelog

    +

    CKFinder

    +

    Copyright (c) 2007-2016, CKSource - Frederico Knabben. All rights reserved.

    +

    Version 3.4.1

    +

    New Features

    + +

    Fixed Issues

    + +

    Localization Updates

    + +

    Version 3.4

    +

    New Features

    + +

    Fixed Issues

    + +

    Localization Updates

    + +

    Version 3.3.1

    +

    Fixed Issues

    + +

    Version 3.3

    +

    New Features

    + +

    Backward Incompatible Changes

    + +

    Fixed Issues

    + +

    Localization Updates

    + +

    Version 3.2.1

    +

    Fixed Issues

    + +

    Version 3.2

    +

    New Features

    + +

    Fixed Issues

    + +

    Localization Updates

    + +

    Version 3.1

    +

    Security Updates

    +

    As a result of security testing and hacking that we did on CKFinder 3 we discovered some potential security concerns in the server-side part of the application. +These issues affected actions that only authenticated users could perform solely in locations specified in your CKFinder backends configuration, but since +in some cases it was possible to skip ACL checks or file extension checks, an upgrade is highly recommended.

    +

    New Features

    + +

    Backward Incompatible Changes

    + +

    Fixed Issues

    + +

    Localization Updates

    + +

    Version 3.0

    +

    A brand new version of CKFinder, currently available only for PHP. For an overview of new features, see the announcement about CKFinder 3.0 for PHP.

    + + + + \ No newline at end of file diff --git a/lib/ckfinder/LICENSE.html b/lib/ckfinder/LICENSE.html new file mode 100644 index 0000000..4ac2f0c --- /dev/null +++ b/lib/ckfinder/LICENSE.html @@ -0,0 +1,295 @@ + + + + + CKFinder License + + +

    CKFinder License Agreement, Version 3.1

    + +

    This document (“Agreement”) is a legal agreement between You, either an individual or a Legal Entity, and + CKSource sp. z o.o. sp.k., with its registered office in Warsaw, at ul. Zygmunta Słomińskiego 15 lok. 508, 00-195 + Warsaw, Poland, NIP number 5252621537, REGON: 361766395 (“CKSource”), covering Your permissions to + reproduce and distribute the Software under the License terms defined hereby.

    + +

    1. Definitions

    + +

    “Agreement Name” shall mean the name used to reference this Agreement in any context, which + is “CKFinder License Agreement 3.1” or “CKFinder License 3.1”.

    + +

    “Software” or “CKFinder” shall mean the copyrighted material owned by CKSource, + subject to the terms of this License. The Software is publicly, uniquely, and in its entirety recognizable + by the “CKFinder” name (“Software Name”).

    + +

    “Software Release” or “Release” shall mean a set of files distributed by CKSource, or + anyone authorized to distribute it, that represents the Software. A Release is uniquely identified by the + Software Name and a code. Such code is generally referenced as the Software version or revision number, or a + combination of both.

    + +

    “Release Date” shall mean the day that CKSource started distributing a Release.

    + +

    “Product” shall mean a single computer program or one or more websites (“Program”) + (i) owned by You, or (ii) to which the owner grants You the permission to act in behalf of the owner for the + purposes of this Agreement. A Program family or a group of Programs does not constitute a Product for the + scope of this Agreement. A Program that goes in competition with the Software in the marketplace does not + constitute a valid Product for the scope of this Agreement.

    + +

    “Development Server” shall mean a computer with one or more computer central processing units + (CPU’s) that operates for the exclusive purpose of software development or software testing.

    + +

    “Development Activity” shall mean the act of interacting with the Software or one of its + Releases, in any number of Products owned or produced by You, with the intent of installation, + customization, configuration, testing, documentation, or any other software development activity related to + the Software.

    + +

    “Developer” shall mean an authorized person designated by You to perform Development + Activities.

    + +

    “Production Website” shall mean a Product with the Software installed, which already had + Development Activities performed, and that has been delivered to end-users for production usage. Maintenance + activities performed on Production Websites, excluding software development activities related to the + Software, are not considered Development Activities.

    + +

    “Hostname” shall mean a unique name by which a website is reachable in a network. This includes, + but is not limited to, a website IP address. (For example, if a website is reachable by the Internet + address “http://www.example.com/”, the Hostname + is “www.example.com”.)

    + +

    “Legal Entity” shall mean the union of the acting entity and all other entities that control, are + controlled by, or are under common control of that entity. For the purposes of this definition, "control" + means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by + contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) + beneficial ownership of such entity.

    + +

    “Effective Date” means the date on which the Legal Evidence is made effective.

    + +

    “You” (or “Your”) shall mean an individual or a Legal Entity exercising permissions + granted by the License and accepting this Agreement.

    + +

    2. Grant of License

    + +

    Subject to the terms of this Agreement, CKSource hereby grants You, in one of the License Models described in + Section 4, a non-exclusive, perpetual, irrevocable, royalty free, worldwide license (“License”) + to use, reproduce, modify, and distribute a Software Release in a collective work assembled with the + Product.

    + +

    You should carefully read the following terms and conditions before using, installing, copying, or + distributing the Software. Unless otherwise agreed in writing by CKSource, your use, installation, copying, + or distribution of the Software indicates your acceptance of this License.

    + +

    3. Scope of License

    + +

    All rights of any kind to the Software, which are not expressly granted in this Agreement, are entirely and + exclusively reserved to and by CKSource. The Software is protected by applicable national and international + laws and treaties.

    + +

    You may use, install, copy, and distribute the Software solely as provided in this Agreement. You may not + rent, lease, loan, sublicense, reverse engineer, decompile, disassemble, or create derivative works based on + the Software, in whole or in part, nor permit anyone else to do so.

    + +

    It is agreed that in exchange for the license set forth herein, you will pay a license fee (“License + Fee”). The fee value will be specified by CKSource at the moment of the purchase.

    + +

    4. License Models

    + +

    The Software may be assembled with the Product and redistributed in respect of one, and only one, of the + following models (“License Models”) of Your choice:

    + + + +

    A valid Developer license is required for every single Developer Person. Developer licenses cannot be shared + among different Developer Persons. Non-Development Activities on Production Websites do not require + Developer licenses.

    + +

    License Fee values may differ depending on the license model.

    + +

    5. Unlicensed Copies

    + +

    If You did not pay License Fee, You may use unlicensed copies of CKFinder for the exclusive purpose of + demonstration. In this case You will be using CKFinder in "demo mode". Without derogating from the + forgoing, You may not use CKFinder in "demo mode" for commercial purposes. CKFinder shall only be + used for evaluation purposes and may not be used or disclosed for any other purposes, including, without + limitation, for external distribution. You may not remove the demo notices from the interface nor disable + the ability to display such notices or otherwise modify CKFinder. Product support, if any, is not offered + for CKFinder in "demo mode".

    + +

    6. Agreement Acceptance

    + +

    This Agreement is automatically accepted by both parties as long as You are in possession of legal evidence (“Legal + Evidence”) that the acceptance has taken place. The Legal Evidence can be represented by (i) a copy of + this Agreement signed by You and CKSource or (ii) a valid Certificate of License Ownership, provided by + CKSource and addressed to You. The Legal Evidence must precisely indicate this Agreement Name, the Software + Name, the License Model You have chosen, and the following restrictive information, if applicable:

    + + + +

    Legal Evidences for different combinations of License Models, Sites, and Products will not restrict each + other and will not interfere in the rights granted to You by each of them.

    + +

    Legal Evidences are not transferable to different Sites and Products.

    + +

    7. Limitation on Releases

    + +

    This agreement is valid for all Releases of the Software with Release Dates within or before the 365 days + that follow the Effective Date (“Upgrade Period”). CKSource has no obligation to provide you any + Release that is not released for general distribution to other CKSource licensees. Nothing in this Agreement + shall be construed to obligate CKSource to provide additional Releases to You under any circumstances.

    + +

    8. Support

    + +

    CKSource shall provide support for Developers covered by valid Developer licenses for the period of 365 days + following the Effective Date (“Support Period”). Support shall be limited to electronic + messaging access. CKSource shall keep You informed, either per CKSource readiness or by following your + request, including changes to it, about the rules and procedures that You must perform to enjoy support + under the terms of this Agreement. Support topics shall be limited to the following (each a “Support + Request”):

    + + + +

    The number of Support Requests that CKSource is entitled to accept from You is limited to 2 per month if You + have chosen the Basic license model, or 5 per month if You have chosen the Professional license model. + CKSource may refuse Support Requests that exceed these limits.

    + +

    CKSource is not in any way obliged to perform bug fixing or custom development activities as a result of a + Support Request.

    + +

    9. License Key

    + +

    Following a valid License purchase, a unique license key (the "License Key") may be provided to + You, which allows Software activation. The License Key is subject to the restrictions set forth in this + License and may not be disclosed or distributed in any way. The disclosure or distribution of the License + Key shall constitute a breach of this License, the effect of which shall be the automatic termination and + revocation of any and all rights granted herein.

    + +

    10. Source Code

    + +

    The original source code ("Source Code") of the Software may be distributed by CKSource alongside + its executable version, or as an integral part of it. You may modify and compile the Source Code. The Source + Code or its modified version can be copied and distributed exclusively within the scope of this license, as + defined in the "License Model" terms of this license, as long as a valid license has been + purchased for the distribution target. CKSource retains all rights over the Source Code and all its modified + versions. Redistributions of the Source Code and modified versions of it must contain the original headers + and copyright notices. Modifications to the Source Code must be explicitly and entirely identified in the + Source Code files. This section of the license supersedes all modification restrictions imposed by other + sections. You are not allowed to remove copyright notices nor make changes to the license validation code + present in the Source Code.

    + +

    11. License Fee

    + +

    In consideration for the License granted in this Agreement during the term of this Agreement, You agreed to + pay to CKSource a one time fee (“License Fee”).

    + +

    In consideration for the Software upgrades access and support services provided during the Upgrade Period and + Support Period, You shall pay a yearly fee (“Annual Support and Upgrade Fee”).

    + +

    The License Fee and the Annual Support and Upgrade Fee amount shall be specified by CKSource at the moment of + the purchase as a single unified price.

    + +

    The fees listed in this Agreement do not include taxes. If CKSource is required to pay any sales, use, + property, excise, value added, gross receipts, withholding or other taxes levied on the Software or support + under this Agreement or on Your use thereof, then such taxes shall be billed to and paid by You. This + Section does not apply to taxes based on CKSource net income, franchise taxes or CKSource’s employer + contributions and taxes.

    + +

    You understand that CKSource uses third-party paying agents to process selected payments. You understand that + until payments are not received and verified by the paying agent, this Agreement is not valid.

    + +

    All payments made hereunder are nonrefundable. You may not withhold or set off any amounts due under this + Agreement. Failure to pay any fee when due shall constitute a material breach of this Agreement. In + addition, if You fail to make any payments when due for support, upon written notice to You, CKSource shall + cease providing support.

    + +

    12. Automatic Renewal

    + +

    You may opt to automatically extend the expiration date for both the Upgrade Period and Support Period by + successive cycles of 365 days (each one a “Renewal”). In such case, you agree to pay a fee for + each Renewal at the beginning of each cycle. The annual Renewal fee shall be informed by CKSource at the + moment of the purchase and optionally agreed by you.

    + +

    If you opted to have automatic Renewals, CKSource shall send you a payment request for the Renewal fee at any + moment following the first day of each Renewal period. You shall perform the full payment in 30 calendar + days following the payment request.

    + +

    Both parties can discontinue the automatic Renewals by written notification to the other party before the + beginning of extension cycles.

    + +

    13. Reservation of Rights and Ownership

    + +

    CKSource reserves all rights not expressly granted to You in this Agreement. The Software is protected by + copyright and other intellectual property laws and treaties. CKSource owns the title, copyright, and other + intellectual property rights in the Software. The Software is licensed, not sold. This Agreement does not + grant you any rights to the Software's trademarks or services.

    + +

    14. Termination

    + +

    Without prejudice to any other rights, this Agreement automatically terminates if You fail to comply with the + terms and conditions of this Agreement. You may terminate this Agreement at any time without cause. In case + of termination, in any circumstance, payments issued by You will not be reimbursed.

    + +

    You shall immediately discontinue distribution of Product, assembled with the Software, upon expiration or + termination of this Agreement.

    + +

    15. Warranty

    + +

    CKSource warrants that it has full title and ownership to the Software and has the authority to grant the + license hereunder. To the best of CKSource's knowledge the Software does not infringe upon the + intellectual property rights of any third party and that CKSource did not receive any notice regarding any + alleged infringement thereof.

    + +

    16. Disclaimer of Warranties

    + +

    With the exclusion of warranties explicitly mentioned in Section 15, the Software and its related material + are provided “AS IS” and without warranty of any kind. CKSource expressly disclaims all other + warranties, expressed or implied, including, but not limited to, the implied warranties of merchantability + and fitness for a particular purpose.

    + +

    17. Exclusion of Incidental, Consequential and Certain Other Damages

    + +

    TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL CKSOURCE BE LIABLE FOR ANY SPECIAL, + INCIDENTAL, PUNITIVE, INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, BUT NOT LIMITED TO, DAMAGES + FOR LOSS OF PROFITS OR CONFIDENTIAL OR OTHER INFORMATION, FOR BUSINESS INTERRUPTION, FOR PERSONAL INJURY, + FOR LOSS OF PRIVACY, FOR FAILURE TO MEET ANY DUTY INCLUDING OF GOOD FAITH OR OF REASONABLE CARE, FOR + NEGLIGENCE, AND FOR ANY OTHER PECUNIARY OR OTHER LOSS WHATSOEVER) ARISING OUT OF OR IN ANY WAY RELATED TO + THE USE OF OR INABILITY TO USE THE SOFTWARE, THE PROVISION OF OR FAILURE TO PROVIDE SUPPORT OR OTHER + SERVICES, INFORMATON, SOFTWARE, AND RELATED CONTENT THROUGH THE SOFTWARE OR OTHERWISE ARISING OUT OF THE USE + OF THE SOFTWARE, OR OTHERWISE UNDER OR IN CONNECTION WITH ANY PROVISION OF THIS AGREEMENT, EVEN IN THE EVENT + OF THE FAULT, TORT (INCLUDING NEGLIGENCE), MISREPRESENTATION, STRICT LIABILITY, BREACH OF CONTRACT, AND EVEN + IF THE OWNER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

    + +

    18. Limitation of Liability

    + +

    In no event shall CKSource’s liability exceed the license fee paid, if any.

    + +

    19. Governing Law and Venue

    + +

    This Agreement shall be construed and controlled by the laws of Poland, and You and CKSource further consent + to exclusive jurisdiction by the courts of Poland.

    + +

    END OF AGREEMENT TERMS

    + + + \ No newline at end of file diff --git a/lib/ckfinder/README.html b/lib/ckfinder/README.html new file mode 100644 index 0000000..3254e11 --- /dev/null +++ b/lib/ckfinder/README.html @@ -0,0 +1,42 @@ + + + + + CKFinder Readme + + +

    CKFinder 3 for PHP

    +

    Thank you for choosing CKFinder.

    +

    Feedback

    +

    Use https://github.com/ckfinder/ckfinder/issues to report issues in CKFinder 3 (and its documentation) or submit +feature requests.

    +

    If you are unsure what information to provide when reporting a bug, check http://docs.cksource.com/ckfinder3/#!/guide/dev_issues_readme

    +

    Translations

    +

    In order to submit translations for CKFinder please visit https://github.com/ckfinder/ckfinder-translations

    +

    Documentation

    +

    CKFinder is made from two parts: the client side part and the server side connector(s).

    +

    The client side part is common across all distributions (PHP and ASP.NET, Java in the future), while +the server side parts are different for each language, that's why there are multiple documentation websites available.

    +

    CKFinder 3 Documentation - http://docs.cksource.com/ckfinder3/

    +

    This website contains documentation about the client side part of CKFinder, common for all versions of CKFinder 3 +and includes information about:

    + +

    CKFinder 3 for PHP Documentation - http://docs.cksource.com/ckfinder3-php/

    +

    This website contains documentation about the PHP connector for CKFinder 3 and includes information about:

    + +

    License

    +

    Copyright (c) 2007-2016, CKSource - Frederico Knabben. All rights reserved.

    +

    To purchase a license for CKFinder visit http://cksource.com/ckfinder

    + + + \ No newline at end of file diff --git a/lib/ckfinder/ckfinder.html b/lib/ckfinder/ckfinder.html new file mode 100644 index 0000000..103d4db --- /dev/null +++ b/lib/ckfinder/ckfinder.html @@ -0,0 +1,21 @@ + + + + + + + CKFinder 3 - File Browser + + + + + + + + + diff --git a/lib/ckfinder/ckfinder.js b/lib/ckfinder/ckfinder.js new file mode 100644 index 0000000..b96546c --- /dev/null +++ b/lib/ckfinder/ckfinder.js @@ -0,0 +1,21 @@ +/*! + Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved. + For licensing, see LICENSE.html or http://cksource.com/ckfinder/license + */ +var CKFinder=function(){function __internalInit(e){return e=e||{},e[S("\rjj}~_vgfwp}")]=S("\n_dd}/yb2r4qszw9l~nnwpN\x01ME\x04fmaAGNN^\r\x1d"),e[S("\x11zvxyy")]=S('?\b$./+e "$%%|/;>\f\r\x1bC\x17\x04\x02G\x1c\x01\v\x1fL\x14\x01\x1aP\x10\0\x16T\x01\x04\x0e\x11\x17\x1d[\b\x12^\x1cr`ah$jsu(hz{`dmndx}}486`}9jnh=rpTR\x02LB\x05CANFX_\fYA\x0fSCWR@P\x16^L\x17\x1a')+S("\x11E|ayr7avo;ptuz\0UM\x03C@R\x07I\tLYIH\x0el{w[]PPD\x17TPY^RN[\0`\x07'&(e 5-,j?#m=:2<;'t,9\"*y.)=3-3\x01\x15\v\f\nDF\x0f\x1c\x1d\x1aQCB\n\0\x13\x02\\\x10\x1f\x06\x19\x02\n\x1a\x1fU\x1f\x12\x13Pcjdjjacu;&)*#j{ftt=wqcIcjxthp|jvOOQ"),e[S("(@YoI@A")]=!0,e}function internalCKFinderInit(e,t,n){var i=t.getElementsByTagName(S("+DHOK"))[0],r=t.createElement(S("&TK[C[X"));r[S(r.innerText?"D,()-;\x1e.49":"-GA^T@{`xz")]=n+S(';\x12~uy)/&&6k\x194-=?;dm9&>5=$xu28;,7>2)~v[")%\r\v\x02\x02\x1aG\x19\x1f\r\x1f\x1aG')+JSON.stringify(e)+S("\x13=."),i.appendChild(r)}function configOrDefault(e,t){return e?e:t}function createUrlParams(e){var t=[];for(var n in e)t.push(encodeURIComponent(n)+"="+encodeURIComponent(e[n]));return"?"+t.join("&")}function extendObject(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);return e}function getCookie(e){e=e.toLowerCase();for(var t=window.document.cookie.split(";"),n=0;n1?i[1]:"";if(r===e)return decodeURIComponent(o)}return null}function setCookie(e,t){window.document.cookie=encodeURIComponent(e)+"="+encodeURIComponent(t)+S("?{1#7,xi")}function updateIOSConfig(e,t){e._iosWidgetHeight=parseInt(getComputedStyle(t).height),e._iosWidgetWidth=parseInt(getComputedStyle(t).width)}function checkOnInit(e,t){var n=t.navigator.userAgent;if((n.indexOf(S("\x15[DQ\\:"))>0||n.indexOf(S("/dC[WQ[B\x18"))>0||n.indexOf(S("\x14Prp}6"))>0)&&t.addEventListener(S("%ELN@DOI_|JQUK"),function(e){setTimeout(function(){var t=e.detail.ckfinder,n=getCookie(S("$FMd[[L\x7fCFKA"));n||(n=t.request(S("\x12pggp-\x7f|nOsv{q")),setCookie(S("%ELkZXMxBEJ^"),n)),t.request(S("\x0fy\x7ffvf{w{\"ziiz'mzTqCQAKRpAGND[yADU_"),{token:n})},1e3)}),e&&!e._omitCheckOnInit&&"function"==typeof e.onInit){var i=e.onInit;delete e.onInit,t.addEventListener(S("\nhgkgatt`Aqtrn"),function(t){e._initCalled||(e._initCalled=!0,i(t.detail.ckfinder))})}}function S(e){for(var t="",n=e.charCodeAt(0),i=1;i200&&(M.style.width=t+S("\x16g`")),n>200&&(M.style.height=n+S("4EN"))):h&&(t=l+(T-r.x),n=u-(D-r.y),t>200&&(M.style.width=t+S("&WP"),C.style.left=x-(T-r.x)+S("?09")),n>200&&(M.style.height=n+S("._H")))}function s(){I.parentNode===M&&M.removeChild(I),f=!1,h=!1,n(document,[S("8TUNOXSP6$"),S("'\\F_HD@AYU")],o),n(document,[S("2^[@ERMI"),S('>K/4!+!+"')],s)}function a(e){e.preventDefault();var n=i(e);T=n.x,D=n.y,l=M.clientWidth,u=M.clientHeight,M.appendChild(I),t(document,[S("\x14xybk|wtjx"),S("5BXMZRVSK[")],o),t(document,[S("\x14xybk|ok"),S("?4.7 , (#")],s)}if(e=e||{},!Modal.div){Modal.heightAdded=48,Modal.widthAdded=2;var l,u,c=Math.min(configOrDefault(e.width,1e3),window.innerWidth-Modal.widthAdded),d=Math.min(configOrDefault(e.height,700),window.innerHeight-Modal.heightAdded),f=!1,h=!1,g=!1,p=0,v=0,m=e.width,w=e.height;e.width=e.height=S("Ewwxl");var C=Modal.div=document.createElement(S('E".>'));C.id=S("+OFH\x02]^VRX"),C.style.position=S("&AAQOO"),C.style.top=(document.documentElement.clientHeight-Modal.heightAdded)/2-d/2+S("?09"),C.style.left=(document.documentElement.clientWidth-Modal.widthAdded)/2-c/2+S("\x17ha"),C.style.background=S("\x111urs"),C.style.border=S("+\x1d]V\x0fC^^ZP\x15\x15VYX"),C.style.boxShadow=S("\r=\x7fh1!cl5#g`9h|~|6/\f\x11\x0e\x13\b\x15\b\x15\x01"),C.style.borderTopLeftRadius=C.style.borderTopRightRadius=S(",\x18^W"),C.style.zIndex=8999,C.innerHTML=S("\x13(q\x7fa8p~&>~uy\rLMGEI\vOMHNN^\x0f\x0e\\DH^V\t\x17UBJJUI\x06\x1dSP6$yc&*4#-;g?#=c#57&~&42>-*`n,%e\x7f\x02\x0e\x10\x07\x01\x17K\x13\x07\x19G\x19\x05\n\x06\x1b]\x03\x13\x17\x1d\0\x05MM\t\x02@\\\x1f\x1f\x1ckfplqkb=(|xg$io{q+{~urs8ko}0dpr$B@QF\x12\x11\nwl\x10\x1eI{ZIK]gKP\x06Y@UR\tSvo\tIv)\0m\x13#*~${\x13$\x02\x04%:-\x17d(\x03\x07\x1f93\x10\v-\x145e(;S\x05Q/\n\x06\x1c+\x05P\x131\x15U\x17\"40\x05?G;D-\x010\x1d\x1fN\x11\x15\x1bGf;Jn@qJK\\cBKebnGu}wP%\x7fZLXmQOTy{MMNG\x14oPBl\x19CfolYfttU~g|QTpsVX\x0ekG[-\x17\0 w\x07*\x1e{\x1b\x19\x12\x14\x1f>-*a;19l#\r\v\x10q\x185\x1c9\x0f'\x19\x12\x01\t3\x0e\x04\x03\r\x132;?\x1e5'DB:3\x19\x1d'+3\x14\x18\x11;\x153XWhY6fr]:_\x7fQTGfkWGyZ}Wxtu_qzKKk{fwWB|w\\w{c\x1bH\x1e{Wz\x03sZj\x06cfUTo@aotYZ\x04\x04{\n.\x04*\x0e!\v\x7f\x06\x18}'\x02\x13\x04;\x1a\x1c2/\x07\v\x10-\x11\x0f\x149:4([*\x0e \x11*+<\x03;\v\x02\t&30\x15#<;F\x15K8\x1d\x19N'\x13\x1c2W2SWLqM[@mh?_xlS xq&m`tr)sR.D-EJEOm]lAD\x1b{\\Ho\x1cXLwwXRlg\x03gkpBrU\x05\x15|)\0%\n\x07\x04~${\x1b<(\x0f\x0f8\x15=\v(\t\f\x04o\x1e2\x1c-\x16\x1f\b7\x16(/R\x01W$\x12>ZP\x19\t_$W&\x19?\x1a)33\x1d./(\x13243N\x1d3@va7Gn^:e:nX=gBCXdCszq^\\nly[qkEwg[q\x17oN}oEFIB|\x05lYpUc|\x7fZn\vh]^x\rWr\x03\b%&\x10u/\n\v\0-/~!%+\x176k\x1a>\x10?\x1e\x1f16:\v91;$Q\v.7,\x01=\x05\x05\x19\t(]\x07\v(;\x0187;\x18\x14\x15?\x117$+\x14%2bvY6Ss]PCboK[eDCXu_n!]G[ `\x7fq~56\x1bCMQ@@T\nJF^_C@\x14\x1e@I\x12@[Y_S\x18\x1aY\x02_\x04]\x06{)'*#-2}{|:3ll'\" > '5;\"lzg")+S('9\x06Z\x1cNJF,$\x7fa"))&')+S("\x1c!moAO\x02J@\x18\x04DCO\x07FCIOC\x1dCW@]OS\x1aPXT_PX\x13L7cb00<*\"uk)>>>!=jq!$y'3$1#?`|*7;\x14\tXCS\x15\x1e\\H\x01\x0f\x02\v\x05\x1aUPF\x02\vOU\x12\x1e\v\t\x16\x1a\x05G^\x1dlnah?%`kgh~1,akid*2q{grrj4v~zi$?\x13QZ\x03WJJNL\t\tOHI\x15\x0fR^@WQG\x1bUWMNTQ\x07\x1e\f09b0+)/#hj./(vlql~!#5;h")+S('\x19&hl|p?IE\x1f\x01GN@\nEFNJ@\0\\JCXHV\x19]WY\\U_\x16OX\x1c\x1f35;/!xd$=;9$>wn<5| 6\'<,2cy-28)6e@V\x12\x1b_E\x0e\x02\x01\x0e\x02\x1fVMY\x1f\bJR\x17\x1d\x06\x06\x1b\x19\0@[\x1e\x11\x11\x1ck:"ehjgs2)xbkez40s}appd:jp}sh\'>,PY\x02PKIOC\b\nNOH\x16\x0eM_CVVF\x18TXLMUV\x06\x1d\rO8a1,(,"gk-./wops\x7f""2:k')+S("!\x1e\f@LP\x19"),document.body.appendChild(C),CKFinder.widget(S(")I@J\0C@TP^\x1eVZRN"),e),Modal.footer=document.getElementById(S("+OFH\x02]^VRX\x18PXWM_I")),window.addEventListener(S("\x17wks~ri\x7fkINL@LDH@M"),function(){Modal.maximized||setTimeout(function(){c=Math.min(configOrDefault(m,1e3),document.documentElement.clientWidth-Modal.widthAdded),d=Math.min(configOrDefault(w,700),document.documentElement.clientHeight-Modal.heightAdded);var e=document.getElementById(S('?#*$n)*"&$d($(4'));e.style.width=c+S("\x19jc"),e.style.height=d+S(">O8"),C.style.top=(document.documentElement.clientHeight-Modal.heightAdded)/2-d/2+S("\v|u"),C.style.left=(document.documentElement.clientWidth-Modal.widthAdded)/2-c/2+S("C4=")},100)});var y=document.getElementById(S("2P_S\x1bZW][W\x11^RP3$"));t(y,[S("\nh`dmd"),S("@5-6'-#),")],function(e){e.stopPropagation(),e.preventDefault(),Modal.close()});var b=Modal.header=document.getElementById(S("\x19ypz0spD@N\x0eL@GCM[")),x=C.offsetLeft,F=C.offsetTop;t(b,[S("'EF_XIIAX^"),S("0E]FW]ECYKN")],function(e){e.preventDefault(),g=!0;var n=i(e);p=n.x,v=n.y,x=p-C.offsetLeft,F=v-C.offsetTop,M.appendChild(I),t(document,[S(" LMVW@KH^L"),S("\x18mun\x7fuspVD")],r)}),t(b,[S("/]^G@Q@F"),S("4AYB[Q_UX")],function(){g=!1,I.parentNode===M&&M.removeChild(I),n(document,[S("\x16zwli~qrhz"),S("*_CXMG]^DV")],r)});var _=document.getElementById(S('?#*$n)*"&$d8.?$4*}93=093z+<')),E=document.getElementById(S("\x0el{w?~{qw{5k\x7fhug{2H@LGH@\vT_")),M=Modal.body=document.getElementById(S("\x1b\x7fvx2MNFBH\bDHLP")),I=document.createElement(S("\x1bxth"));I.style.position=S(":Z^NQS55'"),I.style.top=I.style.right=I.style.bottom=I.style.left=0,I.style.zIndex=1e5,t(_,[S("\nfcx}jt~e}"),S("*_CXMGCESA@")],function(e){f=!0,a(e)}),t(E,[S("\vab{|uu}dz"),S("&SG\\IC_YO]D")],function(e){x=C.offsetLeft,h=!0,a(e)});var T,D}},close:function(){Modal.div&&(document.body.removeChild(Modal.div),Modal.div=null,Modal.maximized&&(document.documentElement.style.overflow=Modal.preDocumentOverflow,document.documentElement.style.width=Modal.preDocumentWidth,document.documentElement.style.height=Modal.preDocumentHeight))},maximize:function(e){e?(Modal.preDocumentOverflow=document.documentElement.style.overflow,Modal.preDocumentWidth=document.documentElement.style.width,Modal.preDocumentHeight=document.documentElement.style.height,document.documentElement.style.overflow=S("\x13||rs}w"),document.documentElement.style.width=0,document.documentElement.style.height=0,Modal.preLeft=Modal.div.style.left,Modal.preTop=Modal.div.style.top,Modal.preWidth=Modal.body.style.width,Modal.preHeight=Modal.body.style.height,Modal.preBorder=Modal.div.style.border,Modal.div.style.left=Modal.div.style.top=Modal.div.style.right=Modal.div.style.bottom=0,Modal.body.style.width=S(",\x1c\x1e\x1f\x15"),Modal.body.style.height=S("\v==>*"),Modal.div.style.border="",Modal.header.style.display=S("5XXV\\"),Modal.footer.style.display=S(";RRPZ"),Modal.maximized=!0):(document.documentElement.style.overflow=Modal.preDocumentOverflow,document.documentElement.style.width=Modal.preDocumentWidth,document.documentElement.style.height=Modal.preDocumentHeight,Modal.div.style.right=Modal.div.style.bottom="",Modal.div.style.left=Modal.preLeft,Modal.div.style.top=Modal.preTop,Modal.div.style.border=Modal.preBorder,Modal.body.style.width=Modal.preWidth,Modal.body.style.height=Modal.preHeight,Modal.header.style.display=S("'JEEHG"),Modal.footer.style.display=S("@#.,'."),Modal.maximized=!1)}},_r=/(window|S("A0&5j4"))/,ckfPopupWindow;return{basePath:basePath,connector:connector,_connectors:connectors,modal:function(e){return e===S(":XPRMZ")?Modal.close():e===S("/FXAZVYS")?!!Modal.div:e===S("\x18t{cupweE")?Modal.maximize(!0):e===S("\x1bqtpvMHXF")?Modal.maximize(!1):void Modal.open(e)},config:function(e){CKFinder._config=e},widget:function(e,t){function n(e){return e+(/^[0-9]+$/.test(e)?S(":KD"):"")}if(t=t||{},!e)throw S("\x1aUs=$,"),i),r.setAttribute(S("7K\\[VPXML"),S("\x0e|up\x7f\x7fqfe")),r.setAttribute(S("(ZIYCABF^V"),S("9[NHR")),r.setAttribute(S("D1'%!'..4"),configOrDefault(t.tabindex,0)),r.attachEvent?r.attachEvent(S("#KKJHIM"),function(){internalCKFinderInit(t,r.contentDocument,S("\x1ak}o{qT"))}):r.onload=function(){/iPad|iPhone|iPod/.test(navigator.platform)&&(updateIOSConfig(t,r),r.contentWindow.addEventListener(S("<^UY)/&&6\x17#&,0"),function(e){e.detail.ckfinder.on(S('\x15c~"k\x7fhug{'),function(e){updateIOSConfig(e.finder.config,r)},null,null,1)})),internalCKFinderInit(t,r.contentDocument,S("'XHXNBY"))};var o=document.getElementById(e);if(!o)throw S(',neiY_VVF\x1bA^\\^_O\x14\x14\x04\x1f#.7/ e(( /<<"<;rq1<:!39,dx,59*7]\x05\x07\x15\r\x06\x03J\x1f\0\x0e\x1f\x04A\x07\x01\x19\x05\x1b\x12\x18X\x05\x14\x19\x15\x1fFMQ\v\fes/pgdjfjeo6bb,1')+S(".\x13DXF_Q\vu|~PT_YO\x1e\f`lb\x05-)#g\n;%vn8:)}ipmhz%4*0*/b")+S("Dy5$: :?r")+S("C3,(#'>d\"?\x0e\x05\t9?66&\x059'-)g/.(;d")+S("&PAGND[\x03AA\\^SW\tSCY[MSTR\x15\x17\x1f;")+S("Abcde\x05\f\x0e $/)?`<$0 '|u!>6=5,r2.:\x0e\x04\x10M'. \x0e\x06\r\x0f\x19B2\x1e\0\0\x04\x02<\x04\x01\x1f\x18\x16\nZRG")+"}"+S("/\f\x1eAPF\\FC\x06")+S('\x1d"0BNFZ\x1a')+S("\f1!gd|~-")),r.close(),ckfPopupWindow.focus())}e=e||{},window.CKFinder._popupOptions=e;var n=isIE9()?window.CKFinder.basePath+S("\x0fsztzzqse6qnvp"):S(")KICXZ\x15R]S]_"),i=S("\x1fLNABPLII\x15GE\x07AH@ZRP@\x0eZZ\x1aCWVVY]O\x03Q/m&&4 (#-'>v5(=c=8<:9<,6:5?f22r2\x0f\x05\x03\x0fY\x1c\x03\x14D\b\x06\x1c\r\x14\x1d=\x11\x18\x01\x16\x10H\x0f\x12\vU\b\x1e\x0f\x14\x04\x1ebmg>}`u+{jxd`alnbb/jqf");i+=S("\x16;op~ot ")+configOrDefault(e.width,1e3),i+=S("Bo, / =w")+configOrDefault(e.height,700),i+=S('\v ya\x7f-$"'),i+=S("\v akid,##$"),"undefined"==typeof ckfPopupWindow||ckfPopupWindow.closed||ckfPopupWindow.close();var r;try{var o=S("\fNEI@~bfd")+Date.now();ckfPopupWindow=window.open(n,o,i,!0)}catch(e){return}return/iPad|iPhone|iPod/.test(navigator.platform)?setTimeout(t,100):t(),ckfPopupWindow},start:function(e){if(!e){var t=window.opener,n={};e={};var i=window.location.search.substring(1);if(i)for(var r=i.split("&"),o=0;o-1&&(!e[n]||!t(e[n],n,e));n-=1);}}function hasProp(e,t){return hasOwn.call(e,t)}function getOwn(e,t){return hasProp(e,t)&&e[t]}function eachProp(e,t){var n;for(n in e)if(hasProp(e,n)&&t(e[n],n))break}function mixin(e,t,n,i){return t&&eachProp(t,function(t,r){!n&&hasProp(e,r)||(!i||"object"!=typeof t||!t||isArray(t)||isFunction(t)||t instanceof RegExp?e[r]=t:(e[r]||(e[r]={}),mixin(e[r],t,n,i)))}),e}function bind(e,t){return function(){return t.apply(e,arguments)}}function scripts(){return document.getElementsByTagName(S("B0'7/7<"))}function defaultOnError(e){throw e}function getGlobal(e){if(!e)return e;var t=global;return each(e.split("."),function(e){t=t[e]}),t}function makeError(e,t,n,i){var r=new Error(t+S("=4W452ykj4\"9<#9)'=a?#5|0:5$w<()3/-q\b\x15\x0f\x0fG")+e);return r.requireType=e,r.requireModules=i,n&&(r.originalError=n),r}function newContext(e){function t(e){var t,n;for(t=0;t0&&(e.splice(t-1,2),t-=2)}}function n(e,n,i){var r,o,s,a,l,u,c,d,f,S,h,g,p=n&&n.split("/"),v=F.map,m=v&&v["*"];if(e&&(e=e.split("/"),c=e.length-1,F.nodeIdCompat&&jsSuffixRegExp.test(e[c])&&(e[c]=e[c].replace(jsSuffixRegExp,"")),"."===e[0].charAt(0)&&p&&(g=p.slice(0,p.length-1),e=g.concat(e)),t(e),e=e.join("/")),i&&v&&(p||m)){s=e.split("/");e:for(a=s.length;a>0;a-=1){if(u=s.slice(0,a).join("/"),p)for(l=p.length;l>0;l-=1)if(o=getOwn(v,p.slice(0,l).join("/")),o&&(o=getOwn(o,u))){d=o,f=a;break e}!S&&m&&getOwn(m,u)&&(S=getOwn(m,u),h=a)}!d&&S&&(d=S,f=h),d&&(s.splice(0,f,d),e=s.join("/"))}return r=getOwn(F.pkgs,e),r?r:e}function i(e){isBrowser&&each(scripts(),function(t){if(t.getAttribute(S("1)return t.shift(),y.require.undef(e),y.makeRequire(null,{skipMap:!0})([e]),!0}function o(e){var t,n=e?e.indexOf("!"):-1;return n>-1&&(t=e.substring(0,n),e=e.substring(n+1,e.length)),[t,e]}function s(e,t,i,r){var s,a,l,u,c=null,d=t?t.name:null,f=e,h=!0,g="";return e||(h=!1,e="_@r"+(O+=1)),u=o(e),c=u[0],e=u[1],c&&(c=n(c,d,r),a=getOwn(T,c)),e&&(c?g=a&&a.normalize?a.normalize(e,function(e){return n(e,d,r)}):e.indexOf("!")===-1?n(e,d,r):e:(g=n(e,d,r),u=o(g),c=u[0],g=u[1],i=!0,s=y.nameToUrl(g))),l=!c||a||i?"":S("\x1dAjNOMQIDJNRLN")+(A+=1),{prefix:c,name:g,parentMap:t,unnormalized:!!l,url:s,originalName:f,isDefine:h,id:(c?c+"!"+g:g)+l}}function a(e){var t=e.id,n=getOwn(_,t);return n||(n=_[t]=new y.Module(e)),n}function l(e,t,n){var i=e.id,r=getOwn(_,i);!hasProp(T,i)||r&&!r.defineEmitComplete?(r=a(e),r.error&&t===S("\nn~\x7fa}")?n(r.error):r.on(t,n)):"defined"===t&&n(T[i])}function u(e,t){var n=e.requireModules,i=!1;t?t(e):(each(n,function(t){var n=getOwn(_,t);n&&(n.error=e,n.events.error&&(i=!0,n.emit(S("\x16rjkui"),e)))}),i||req.onError(e))}function c(){globalDefQueue.length&&(each(globalDefQueue,function(e){var t=e[0];"string"==typeof t&&(y.defQueueMap[t]=!0),I.push(e)}),globalDefQueue=[])}function d(e){delete _[e],delete E[e]}function f(e,t,n){var i=e.map.id;e.error?e.emit(S("E#5:&8"),e.error):(t[i]=!0,each(e.depMaps,function(i,r){var o=i.id,s=getOwn(_,o);!s||e.depMatched[r]||n[o]||(getOwn(t,o)?(e.defineDep(r,T[o]),e.check()):f(s,t,n))}),n[i]=!0)}function h(){var e,t,n=1e3*F.waitSeconds,o=n&&y.startTime+n<(new Date).getTime(),s=[],a=[],l=!1,c=!0;if(!w){if(w=!0,eachProp(E,function(e){var n=e.map,u=n.id;if(e.enabled&&(n.isDefine||a.push(e),!e.error))if(!e.inited&&o)r(u)?(t=!0,l=!0):(s.push(u),i(u));else if(!e.inited&&e.fetched&&n.isDefine&&(l=!0,!n.prefix))return c=!1}),o&&s.length)return e=makeError(S("(]CFIB[["),S("\x19Vt}y>kILGLQQ\x06AG[\nFCI[CUB\b\x13")+s,null,s),e.contextName=y.contextName,u(e);c&&each(a,function(e){f(e,{},{})}),o&&!t||!l||!isBrowser&&!isWebWorker||x||(x=setTimeout(function(){x=0,h()},50)),w=!1}}function g(e){hasProp(T,e[0])||a(s(e[0],null,!0)).init(e[1],e[2])}function p(e,t,n,i){e.detachEvent&&!isOpera?i&&e.detachEvent(i,t):e.removeEventListener(n,t,!1)}function v(e){var t=e.currentTarget||e.srcElement;return p(t,y.onScriptLoad,S('@--" '),S(".@^CWRPLECYM_XT\\PX%")),p(t,y.onScriptError,S("7]KHTN")),{node:t,id:t&&t.getAttribute(S("\x13ptbv5k\x7fjitlzMNFVH@"))}}function m(){var e;for(c();I.length;){if(e=I.shift(),null===e[0])return u(makeError(S("A/*7('3+!"),S('B\x0e-6+&<*".(m/!??+>; %w<<<228vv@\f\r\x07\x11\t\x03]H')+e[e.length-1]));g(e)}y.defQueueMap={}}var w,C,y,b,x,F={waitSeconds:7,baseUrl:S(" \x0f\r"),paths:{},bundles:{},pkgs:{},shim:{},config:{}},_={},E={},M={},I=[],T={},D={},P={},O=1,A=1;return b={require:function(e){return e.require?e.require:e.require=y.makeRequire(e.map)},exports:function(e){if(e.usingExports=!0,e.map.isDefine)return e.exports?T[e.map.id]=e.exports:e.exports=T[e.map.id]={}},module:function(e){return e.module?e.module:e.module={id:e.map.id,uri:e.map.url,config:function(){return getOwn(F.config,e.map.id)||{}},exports:e.exports||(e.exports={})}}},C=function(e){this.events=getOwn(M,e.id)||{},this.map=e,this.shim=getOwn(F.shim,e.id),this.depExports=[],this.depMaps=[],this.depMatched=[],this.pluginMaps={},this.depCount=0},C.prototype={init:function(e,t,n,i){i=i||{},this.inited||(this.factory=t,n?this.on(S("\x1a~noqm"),n):this.events.error&&(n=bind(this,function(e){this.emit(S(".JBC]A"),e)})),this.depMaps=e&&e.slice(0),this.errback=n,this.inited=!0,this.ignore=i.ignore,i.enabled||this.enabled?this.enable():this.check())},defineDep:function(e,t){this.depMatched[e]||(this.depMatched[e]=!0,this.depCount-=1,this.depExports[e]=t)},fetch:function(){if(!this.fetched){this.fetched=!0,y.startTime=(new Date).getTime();var e=this.map;return this.shim?void y.makeRequire(this.map,{enableBuildCallback:!0})(this.shim.deps||[],bind(this,function(){return e.prefix?this.callPlugin():this.load()})):e.prefix?this.callPlugin():this.load()}},load:function(){var e=this.map.url;D[e]||(D[e]=!0,y.load(this.map.id,e))},check:function(){if(this.enabled&&!this.enabling){var e,t,n=this.map.id,i=this.depExports,r=this.exports,o=this.factory;if(this.inited){if(this.error)this.emit(S(" DPQKW"),this.error);else if(!this.defining){if(this.defining=!0,this.depCount<1&&!this.defined){if(isFunction(o)){try{r=y.execCb(n,o,i,r)}catch(t){e=t}if(this.map.isDefine&&void 0===r&&(t=this.module,t?r=t.exports:this.usingExports&&(r=this.exports)),e){if(this.events.error&&this.map.isDefine||req.onError!==defaultOnError)return e.requireMap=this.map,e.requireModules=this.map.isDefine?[this.map.id]:null,e.requireType=S(this.map.isDefine?"\rjjvx|v":"\v~h\x7fzycw"),u(this.error=e);"undefined"!=typeof console&&console.error?console.error(e):req.onError(e)}}else r=o;if(this.exports=r,this.map.isDefine&&!this.ignore&&(T[n]=r,req.onResourceLoad)){var s=[];each(this.depMaps,function(e){s.push(e.normalizedMap||e)}),req.onResourceLoad(y,this.map,s)}d(n),this.defined=!0}this.defining=!1,this.defined&&!this.defineEmitted&&(this.defineEmitted=!0,this.emit("defined",this.exports),this.defineEmitComplete=!0)}}else hasProp(y.defQueueMap,n)||this.fetch()}},callPlugin:function(){var e=this.map,t=e.id,i=s(e.prefix);this.depMaps.push(i),l(i,"defined",bind(this,function(i){var r,o,c,f=getOwn(P,this.map.id),h=this.map.name,g=this.map.parentMap?this.map.parentMap.name:null,p=y.makeRequire(e.parentMap,{enableBuildCallback:!0});return this.map.unnormalized?(i.normalize&&(h=i.normalize(h,function(e){return n(e,g,!0)})||""),o=s(e.prefix+"!"+h,this.map.parentMap),l(o,"defined",bind(this,function(e){this.map.normalizedMap=o,this.init([],function(){return e},null,{enabled:!0,ignore:!0})})),c=getOwn(_,o.id),void(c&&(this.depMaps.push(o),this.events.error&&c.on(S("\fh|}\x7fc"),bind(this,function(e){this.emit(S("'M[XD^"),e)})),c.enable()))):f?(this.map.url=y.nameToUrl(f),void this.load()):(r=bind(this,function(e){this.init([],function(){return e},null,{enabled:!0})}),r.error=bind(this,function(e){this.inited=!0,this.error=e,e.requireModules=[t],eachProp(_,function(e){0===e.map.id.indexOf(t+S("D\x1a3)&&8&-!'555"))&&d(e.map.id)}),u(e)}),r.fromText=bind(this,function(n,i){var o=e.name,l=s(o),c=useInteractive;i&&(n=i),c&&(useInteractive=!1),a(l),hasProp(F.config,t)&&(F.config[o]=F.config[t]);try{req.exec(n)}catch(e){return u(makeError(S("\x14sdxum\x7fchxh~L"),S("\x1eyRNOwA]R\x07M_KG\fKA]\x10")+t+S("\x1d>yAHNF@\x1f\x06")+e,e,[t]))}c&&(useInteractive=!0),this.depMaps.push(l),y.completeLoad(o),p([o],r)}),void i.load(e.name,p,r,F))})),y.enable(i,this),this.pluginMaps[i.id]=i},enable:function(){E[this.map.id]=this,this.enabled=!0,this.enabling=!0,each(this.depMaps,bind(this,function(e,t){var n,i,r;if("string"==typeof e){if(e=s(e,this.map.isDefine?this.map:this.map.parentMap,!1,!this.skipMap),this.depMaps[t]=e,r=getOwn(b,e.id))return void(this.depExports[t]=r(this));this.depCount+=1,l(e,"defined",bind(this,function(e){this.undefed||(this.defineDep(t,e),this.check())})),this.errback?l(e,S("\x13qgdxj"),bind(this,this.errback)):this.events.error&&l(e,S(">Z23-1"),bind(this,function(e){this.emit(S("\x1byolpR"),e)}))}n=e.id,i=_[n],hasProp(b,n)||!i||i.enabled||y.enable(e,this)})),eachProp(this.pluginMaps,bind(this,function(e){var t=getOwn(_,e.id);t&&!t.enabled&&y.enable(e,this)})),this.enabling=!1,this.check()},on:function(e,t){var n=this.events[e];n||(n=this.events[e]=[]),n.push(t)},emit:function(e,t){each(this.events[e],function(e){e(t)}),e===S("\x13qgdxj")&&delete this.events[e]}},y={config:F,contextName:e,registry:_,defined:T,urlFetched:D,defQueue:I,defQueueMap:{},Module:C,makeModuleMap:s,nextTick:req.nextTick,onError:u,configure:function(e){e.baseUrl&&"/"!==e.baseUrl.charAt(e.baseUrl.length-1)&&(e.baseUrl+="/");var t=F.shim,n={paths:!0,bundles:!0,config:!0,map:!0};eachProp(e,function(e,t){n[t]?(F[t]||(F[t]={}),mixin(F[t],e,!0,!0)):F[t]=e}),e.bundles&&eachProp(e.bundles,function(e,t){each(e,function(e){e!==t&&(P[e]=t)})}),e.shim&&(eachProp(e.shim,function(e,n){isArray(e)&&(e={deps:e}),!e.exports&&!e.init||e.exportsFn||(e.exportsFn=y.makeShimExports(e)),t[n]=e}),F.shim=t),e.packages&&each(e.packages,function(e){var t,n;e="string"==typeof e?{name:e}:e,n=e.name,t=e.location,t&&(F.paths[n]=e.location),F.pkgs[n]=e.name+"/"+(e.main||S("6ZYPT")).replace(currDirRegExp,"").replace(jsSuffixRegExp,"")}),eachProp(_,function(e,t){e.inited||e.map.unnormalized||(e.map=s(t,null,!0))}),(e.deps||e.callback)&&y.require(e.deps||[],e.callback)},makeShimExports:function(e){function t(){var t;return e.init&&(t=e.init.apply(global,arguments)),t||e.exports&&getGlobal(e.exports)}return t},makeRequire:function(t,r){function o(n,i,l){var c,d,f;return r.enableBuildCallback&&i&&isFunction(i)&&(i.__requireJsBuild=!0),"string"==typeof n?isFunction(i)?u(makeError(S("6({?20+\x05\x19\x16YD')+e+(t?"":S("7\x16\x19oHY\x1dLZ14+1!m\x1d\x1aa"))))):(m(),y.nextTick(function(){m(),f=a(s(null,t)),f.skipMap=r.skipMap,f.init(n,i,l,{enabled:!0}),h()}),o)}return r=r||{},mixin(o,{isBrowser:isBrowser,toUrl:function(e){var i,r=e.lastIndexOf("."),o=e.split("/")[0],s="."===o||".."===o;return r!==-1&&(!s||r>1)&&(i=e.substring(r,e.length),e=e.substring(0,r)),y.nameToUrl(n(e,t&&t.id,!0),i,!0)},defined:function(e){return hasProp(T,s(e,t,!1,!0).id)},specified:function(e){return e=s(e,t,!1,!0).id,hasProp(T,e)||hasProp(_,e)}}),t||(o.undef=function(e){c();var n=s(e,t,!0),r=getOwn(_,e);r.undefed=!0,i(e),delete T[e],delete D[n.url],delete M[e],eachReverse(I,function(t,n){t[0]===e&&I.splice(n,1)}),delete y.defQueueMap[e],r&&(r.events.defined&&(M[e]=r.events),d(e))}),o},enable:function(e){var t=getOwn(_,e.id);t&&a(e).enable()},completeLoad:function(e){var t,n,i,o=getOwn(F.shim,e)||{},s=o.exports;for(c();I.length;){if(n=I.shift(),null===n[0]){if(n[0]=e,t)break;t=!0}else n[0]===e&&(t=!0);g(n)}if(y.defQueueMap={},i=getOwn(_,e),!t&&!hasProp(T,e)&&i&&!i.inited){if(!(!F.enforceDefine||s&&getGlobal(s)))return r(e)?void 0:u(makeError(S("=PP$$$** "),S('B\r+e"". $.l./#0;o-=1)if(s=r.slice(0,o).join("/"),l=getOwn(i,s)){isArray(l)&&(l=l[0]),r.splice(0,o,l);break}a=r.join("/"),a+=t||(/^data\:|\?/.test(a)||n?"":".js"),a=("/"===a.charAt(0)||a.match(/^[\w\+\.\-]+:/)?"":F.baseUrl)+a}return F.urlArgs?a+((a.indexOf("?")===-1?"?":"&")+F.urlArgs):a},load:function(e,t){req.load(y,e,t)},execCb:function(e,t,n,i){return t.apply(i,n)},onScriptLoad:function(e){if(e.type===S("3XZWS")||readyRegExp.test((e.currentTarget||e.srcElement).readyState)){interactiveScript=null;var t=v(e);y.completeLoad(t.id)}},onScriptError:function(e){var t=v(e);if(!r(t.id)){var n=[];return eachProp(_,function(e,i){0!==i.indexOf("_@r")&&each(e.depMaps,function(e){return e.id===t.id&&n.push(i),!0})}),u(makeError(S("\x1elCSKSP@TUG["),S("5eTJPJO\x1cXLM/3b%+7fe")+t.id+(n.length?S("\x1b>1>qEDFF@\x05D^\x12\t")+n.join(S("0\x1d\x12")):'"'),e,[t.id]))}}},y.require=y.makeRequire(),y}function getInteractiveScript(){return interactiveScript&&interactiveScript.readyState===S("\fd`{ucsp`|`r")?interactiveScript:(eachReverse(scripts(),function(e){if(e.readyState===S('B**1#5)*>":('))return interactiveScript=e}),interactiveScript)}var req,s,head,baseElement,dataMain,src,interactiveScript,currentlyAddingScript,mainScript,subPath,version=S("\x1f\x12\x0f\x13\r\x16\x17"),commentRegExp=/(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/gm,cjsRequireRegExp=/[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,jsSuffixRegExp=/\.js$/,currDirRegExp=/^\.\//,op=Object.prototype,ostring=op.toString,hasOwn=op.hasOwnProperty,ap=Array.prototype,isBrowser=!("undefined"==typeof window||"undefined"==typeof navigator||!window.document),isWebWorker=!isBrowser&&"undefined"!=typeof importScripts,readyRegExp=isBrowser&&navigator.platform===S(".\x7f|pk``tb~ww\x1a\b")?/^complete$/:/^(complete|loaded)$/,defContextName="_",isOpera="undefined"!=typeof opera&&opera.toString()===S(",vAMZTQG\x14zFRJXg"),contexts={},cfg={},globalDefQueue=[],useInteractive=!1;if("undefined"==typeof define){if("undefined"!=typeof requirejs){if(isFunction(requirejs))return;cfg=requirejs,requirejs=void 0}"undefined"==typeof require||isFunction(require)||(cfg=require,require=void 0),req=requirejs=function(e,t,n,i){var r,o,s=defContextName;return isArray(e)||"string"==typeof e||(o=e,isArray(t)?(e=t,t=n,n=i):e=[]),o&&o.context&&(s=o.context),r=getOwn(contexts,s),r||(r=contexts[s]=req.s.newContext(s)),o&&r.configure(o),r.require(e,t,n)},req.config=function(e){return req(e)},req.nextTick="undefined"!=typeof setTimeout?function(e){setTimeout(e,4)}:function(e){e()},require||(require=req),req.version=version,req.jsExtRegExp=/^\/|:|\?|\.js$/, +req.isBrowser=isBrowser,s=req.s={contexts:contexts,newContext:newContext},req({}),each([S("'\\F\x7fY@"),S("9OUXXX"),"defined",S("3GESTQ_S^X")],function(e){req[e]=function(){var t=contexts[defContextName];return t.require[e].apply(t,arguments)}}),isBrowser&&(head=s.head=document.getElementsByTagName(S("\x1btx\x7f{"))[0],baseElement=document.getElementsByTagName(S(":Y]N["))[0],baseElement&&(head=s.head=baseElement.parentNode)),req.onError=defaultOnError,req.createNode=function(e,t,n){var i=e.xhtml?document.createElementNS(S("7PMNK\x06\x12\x11H76l4wk)5/f{ruta78%??"),S("\fezb|+apf|fc")):document.createElement(S("4FUEQIN"));return i.type=e.scriptType||S('B7!=2h"(<*?.<& %'),i.charset=S("\x10dfu9-"),i.async=!0,i},req.load=function(e,t,n){var i,r=e&&e.config||{};if(isBrowser)return i=req.createNode(r,t,n),r.onNodeCreated&&r.onNodeCreated(i,r,t,n),i.setAttribute(S("$AGSI\x04XN]XG]UR]]@PNC"),e.contextName),i.setAttribute(S("-1?0:-1:t?0:-1}function n(e){var t=this.cache,n=typeof e;if("boolean"==n||null==e)t[e]=!0;else{"number"!=n&&"string"!=n&&(n="object");var i="number"==n?e:m+e,r=t[n]||(t[n]={});"object"==n?(r[i]||(r[i]=[])).push(e):r[i]=!0}}function i(e){return e.charCodeAt(0)}function r(e,t){for(var n=e.criteria,i=t.criteria,r=-1,o=n.length;++ra||"undefined"==typeof s)return 1;if(s=w&&s===e,u=[];if(l){var d=o(i);d?(s=t,i=d):l=!1}for(;++r-1});return r.pop(),o.pop(),w&&(u(r),u(o)),s}function ie(e,t,n,i,r){(jn(t)?Ge:ui)(t,function(t,o){var s,a,l=t,u=e[o];if(t&&((a=jn(t))||ci(t))){for(var c=i.length;c--;)if(s=i[c]==t){u=r[c];break}if(!s){var d;n&&(l=n(u,t),(d="undefined"!=typeof l)&&(u=l)),d||(u=a?jn(u)?u:[]:ci(u)?u:{}),i.push(t),r.push(u),d||ie(u,t,n,i,r)}}else n&&(l=n(u,t),"undefined"==typeof l&&(l=t)),"undefined"!=typeof l&&(u=l);e[o]=u})}function re(e,t){return e+On(Zn()*(t-e+1))}function oe(n,i,r){var s=-1,l=ue(),d=n?n.length:0,f=[],S=!i&&d>=w&&l===e,h=r||S?a():f;if(S){var g=o(h);l=t,h=g}for(;++s3&&"function"==typeof t[n-2])var i=G(t[--n-1],t[n--],2);else n>2&&"function"==typeof t[n-1]&&(i=t[--n]);for(var r=d(arguments,1,n),o=-1,s=a(),l=a();++o-1:"number"==typeof o?s=(Ke(e)?e.indexOf(t,n):r(e,t,n))>-1:ui(e,function(e){if(++i>=n)return!(s=e===t)}),s}function Qe(e,t,n){var i=!0;t=g.createCallback(t,n,3);var r=-1,o=e?e.length:0;if("number"==typeof o)for(;++ro&&(o=l)}else t=null==t&&Ke(e)?i:g.createCallback(t,n,3),Ge(e,function(e,n,i){var s=t(e,n,i);s>r&&(r=s,o=e)});return o}function nt(e,t,n){var r=1/0,o=r;if("function"!=typeof t&&n&&n[t]===e&&(t=null),null==t&&jn(e))for(var s=-1,a=e.length;++s=w&&o(i?n[i]:f)))}var h=n[0],g=-1,p=h?h.length:0,v=[];e:for(;++g>>1;n(e[s])1?arguments:arguments[0],t=-1,n=e?tt(hi(e,S("\x1fLDLDPM"))):0,i=gn(n<0?0:n);++t2?ae(e,17,d(arguments,2),null,t):ae(e,1,null,null,t)}function Kt(e){for(var t=arguments.length>1?te(arguments,!0,!1,1):ye(e),n=-1,i=t.length;++n2?ae(t,19,d(arguments,2),null,e):ae(t,3,null,null,e)}function Bt(){for(var e=arguments,t=e.length;t--;)if(!De(e[t]))throw new Fn;return function(){for(var t=arguments,n=e.length;n--;)t=[e[n].apply(this,t)];return t[0]}}function qt(e,t){return t="number"==typeof t?t:+t||e.length,ae(e,4,null,null,null,t)}function Nt(e,t,n){var i,r,o,s,a,l,u,c=0,d=!1,f=!0;if(!De(e))throw new Fn;if(t=Xn(0,t)||0,n===!0){var g=!0;f=!1}else Pe(n)&&(g=n.leading,d=S("=S^8\x16#*0")in n&&(Xn(t,n.maxWait)||0),f=S("%RUI@FBBJ")in n?n.trailing:f);var p=function(){var n=t-(pi()-s);if(n<=0){r&&Pn(r);var d=u;r=l=u=h,d&&(c=pi(),o=e.apply(a,i),l||r||(i=a=null))}else l=Hn(p,n)},v=function(){l&&Pn(l),r=l=u=h,(f||d!==t)&&(c=pi(),o=e.apply(a,i),l||r||(i=a=null))};return function(){if(i=arguments,s=pi(),a=this,u=f&&(l||!g),d===!1)var n=g&&!l;else{r||g||(c=s);var S=d-(s-c),h=S<=0;h?(r&&(r=Pn(r)),c=s,o=e.apply(a,i)):r||(r=Hn(v,S))}return h&&l?l=Pn(l):l||t===d||(l=Hn(p,t)),n&&(h=!0,o=e.apply(a,i)),!h||l||r||(i=a=null),o}}function Lt(e){if(!De(e))throw new Fn;var t=d(arguments,1);return Hn(function(){e.apply(h,t)},1)}function $t(e,t){if(!De(e))throw new Fn;var n=d(arguments,2);return Hn(function(){e.apply(h,n)},t)}function Ut(e,t){if(!De(e))throw new Fn;var n=function(){var i=n.cache,r=t?t.apply(this,arguments):m+arguments[0];return Vn.call(i,r)?i[r]:i[r]=e.apply(this,arguments)};return n.cache={},n}function Wt(e){var t,n;if(!De(e))throw new Fn;return function(){return t?n:(t=!0,n=e.apply(this,arguments),e=null,n)}}function kt(e){return ae(e,16,d(arguments,1))}function Xt(e){return ae(e,32,null,d(arguments,1))}function Qt(e,t,n){var i=!0,r=!0;if(!De(e))throw new Fn;return n===!1?i=!1:Pe(n)&&(i=S("-BJQU[]S")in n?n.leading:i,r=S(">K2 +/-+!")in n?n.trailing:r),k.leading=i,k.maxWait=t,k.trailing=r,Nt(e,t,k)}function zt(e,t){return ae(t,16,[e])}function Zt(e){return function(){return e}}function Yt(e,t,n){var i=typeof e;if(null==e||"function"==i)return G(e,t,n);if("object"!=i)return nn(e);var r=ti(e),o=r[0],s=e[o];return 1!=r.length||s!==s||Pe(s)?function(t){for(var n=r.length,i=!1;n--&&(i=ne(t[r[n]],e[r[n]],null,!0)););return i}:function(e){var t=e[o];return s===t&&(0!==s||1/s==1/t)}}function Gt(e){return null==e?"":xn(e).replace(oi,le)}function Jt(e){return e}function jt(e,t,n){var i=!0,r=t&&ye(t);t&&(n||r.length)||(null==n&&(n=t),o=p,t=e,e=g,r=ye(t)),n===!1?i=!1:Pe(n)&&S("\x1axt|wq")in n&&(i=n.chain);var o=e,s=De(o);Ge(r,function(n){var r=e[n]=t[n];s&&(o.prototype[n]=function(){var t=this.__chain__,n=this.__wrapped__,s=[n];Kn.apply(s,arguments);var a=r.apply(e,s);if(i||t){if(n===a&&Pe(a))return this;a=new o(a),a.__chain__=t}return a})})}function en(){return n._=Mn,this}function tn(){}function nn(e){return function(t){return t[e]}}function rn(e,t,n){var i=null==e,r=null==t;if(null==n&&("boolean"==typeof e&&r?(n=e,e=1):r||"boolean"!=typeof t||(n=t,r=!0)),i&&r&&(t=1),e=+e||0,r?(t=e,e=0):t=+t||0,n||e%1||t%1){var o=Zn();return Qn(e+o*(t-e+parseFloat(S(".\x1eU\x1c")+((o+"").length-1))),t)}return re(e,t)}function on(e,t){if(e){var n=e[t];return De(n)?e[t]():n}}function sn(e,t,n){var i=g.templateSettings;e=xn(e||""),n=ai({},n,i);var r,o=ai({},n.imports,i.imports),a=ti(o),l=We(o),u=0,c=n.interpolate||D,d=S("\x10NMc4>+7?"),f=bn((n.escape||D).source+"|"+c.source+"|"+(c===I?_:D).source+"|"+(n.evaluate||D).source+S("\x1f\\\x05"),"g");e.replace(f,function(t,n,i,o,a,l){return i||(i=o),d+=e.slice(u,l).replace(O,s),n&&(d+=S("\x15173\x13EDy5")+n+S("\x1c4>4*\x06")),a&&(r=!0,d+=S("\x133.\x1c")+a+S("\x1c&\x14@\x7fQ\x02\b\x19\x05\x01")),i&&(d+=S("\x1b;=5\x15\b\t}|P\x05\x1b\x07\0")+i+S("#\r\f\x06\x1a\x15\tD^@A\x0e\x10\x10\x16\x15\x13\x0e\x15ihL\x10\x1a\x106\x1a")),u=l+t.length,t}),d+=S('%\x01\x1c"');var p=n.variable,v=p;v||(p=S("\x1dq}J"),d=S("\x12d}a~70")+p+S("\x11;3o\x1f")+d+S(">5=K")),d=(r?d.replace(b,""):d).replace(x,S("\x18=+")).replace(F,S("\n/=6")),d=S("7^LTXHTQQh")+p+S("=\x17\x1f;K")+(v?"":p+S("\x167de:3")+p+S("%\x06\x1a\bRW\x02\x17'"))+S("\rxnb1ML`96HGi:&<:93\0~}F\x04\x18\x06x\x06LYHM]K")+(r?S("3\x18\x15ihR\x19\x07\x1b}OL^9o21+1)319/e&\"'!k[")+S("\x17~ltxhtqq\0QPJJQ\x0e\x0e\bR\nts]\x0e\x04\r\x11ml^\x1bUVTU\x12ZNZKR%/60hea`ai7A"):S("\x16,\x12"))+d+S("D7#3=;$k\x13\x12>E-");var m=S("\x1f*\x0e\b)\v\n\x05\x07[F_YOH{}|\f")+(n.sourceURL||S(">\x10,.&\"7-i3-$:'-9+`#>'!70\r")+R++ +"]")+S(":1\x16\x12");try{var w=mn(a,S("?2$666+f")+d+m).apply(h,l)}catch(e){throw e.source=d,e}return t?w(t):(w.source=d,w)}function an(e,t,n){e=(e=+e)>-1?e:0;var i=-1,r=gn(e);for(t=G(t,n,1);++i/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:I,variable:"",imports:{_:g}},Ln||(Y=function(){function e(){}return function(t){if(Pe(t)){e.prototype=t;var i=new e;e.prototype=null}return i||n.Object()}}());var Jn=Nn?function(e,t){X.value=t,Nn(e,S("\x17GFxrryZ~T@}|"),X),X.value=null}:tn,jn=$n||function(e){return e&&"object"==typeof e&&"number"==typeof e.length&&In.call(e)==K||!1},ei=function(e){var t,n=e,i=[];if(!n)return i;if(!Q[typeof e])return i;for(t in n)Vn.call(n,t)&&i.push(t);return i},ti=kn?function(e){return Pe(e)?kn(e):[]}:ei,ni={"&":S(">\x19!,2x"),"<":S("\x125xa-"),">":S(">\x19'5y"),'"':S("9\x1cJIRJ\x04"),"'":S("\x1c;=,\x19\x1a")},ii=xe(ni),ri=bn("("+ti(ii).join("|")+")","g"),oi=bn("["+ti(ni).join("")+"]","g"),si=function(e,t,n){var i,r=e,o=r;if(!r)return o;var s=arguments,a=0,l="number"==typeof n?2:s.length;if(l>3&&"function"==typeof s[l-2])var u=G(s[--l-1],s[l--],2);else l>2&&"function"==typeof s[l-1]&&(u=s[--l]);for(;++a#:!"'),g.prototype.chain=fn,g.prototype.toString=Sn,g.prototype.value=hn,g.prototype.valueOf=hn,Ge([S("\x15|xqw"),S("\x14eyg"),S("$VNNN]")],function(e){var t=_n[e];g.prototype[e]=function(){var e=this.__chain__,n=t.apply(this.__wrapped__,arguments);return e?new p(n,e):n}}),Ge([S("5FBKQ"),S("\x16+-\x82\ufedc")+S("@KO\u206b\u206d")+S("1\u16b2\u183d\u2034\u2034\u2034\u2034\u203c\u203c\u203c\u203c\u2034\u2034\u2034\u2010\u201f\u3041"),b=/\b__p \+= '';/g,x=/\b(__p \+=) '' \+/g,F=/(__e\(.*?\)|\b__t\)) \+\n'';/g,_=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,E=/\w*$/,M=/^\s*function[ \n\r\t]+\w/,I=/<%=([\s\S]+?)%>/g,T=RegExp(S("\rPT")+y+S('\x17E3*04"#1\x04\b')),D=/($^)/,P=/\bthis\b/,O=/['\n\r\t\u2028\u2029\\]/g,A=[S("!cQVD_"),S("?\x02.-/!$("),S("0uSGQ"),S("#bPHD\\@EE"),S("$hGS@"),S('"mQHDBZ'),S("8vXQY^J"),S("\r\\jwTjc"),S("E\x153: $,"),"_",S(";]IJ^#)\x075!+2"),S("*H@HO]dX_V[@B"),S("A+0\x02,(.<,"),S("9SHr\\p"),S("$UGU[LcEX"),S("/CTFg]XSXMM")],R=0,V=S(")qDNGKLD\x11sAS@[RVMIf"),K="[object Array]",H=S(")qDNGKLD\x11p\\[YSVVd"),B=S(" zMAN@ES\bmK_Ip"),q="[object Function]",N=S("\x15Mxzs\x7fxh=PjMCGQy"),L=S("\x1eDOCHFGQ\x06hJCOHXp"),$=S(",vAMZTQG\x14gSP}AJf"),U=S(":`S_TZ#5b\x1007/)/\x14"),W={};W[q]=!1,W[V]=W[K]=W[H]=W[B]=W[N]=W[L]=W[$]=W[U]=!0;var k={leading:!1,maxWait:0,trailing:!1},X={configurable:!1,enumerable:!1,value:null,writable:!1},Q={boolean:!1,function:!0,object:!0,number:!1,string:!1,undefined:!1},z={"\\":"\\","'":"'","\n":"n","\r":"r","\t":"t","\u2028":S("A7qtw~"),"\u2029":S("":S(")\f\b\x1a\x1f\x15"),'"':S("Ad`wq}"),"'":S("?fbqz\x7f"),"/":S("4\x13\x15\x03\x0f\x02")},n=e?/[&<>"'\/]/g:/&(?!#?\w+;)|<|>|"|'|\//g;return function(e){return e?e.toString().replace(n,function(e){return t[e]||e}):""}},n=function(){return this||(0,eval)(S("\x0e{xxa"))}(),"undefined"!=typeof module&&module.exports?module.exports=i:"function"==typeof CKFinder.define&&CKFinder.define.amd?CKFinder.define(S(";XRj"),[],function(){return i}):n.doT=i;var r={start:S("\x1b;66"),end:S("'\x01\x02\r"),startencode:S("Aeh!+%(,,\x02\x1f\x01\x01f")},o={start:S(":\x1c\x07RKKk|j"),end:S("-\x07\x14_DF\x18\t\x12"),startencode:S("5\x11\fWLN\x10\x01XP\\/%'\v\x10\b\no")},s=/$^/;i.template=function(a,l,u){l=l||i.templateSettings;var c,d,f=l.append?r:o,h=0;a=l.use||l.define?e(l,a,u||{}):a,a=(S("1DRF\x15YBL\x04\x1d")+(l.strip?a.replace(/(^|\r|\n)\t* +| +\t*(\r|\n|$)/g," ").replace(/\r|\n|\t|\/\*[\s\S]*?\*\//g,""):a).replace(/'|\\/g,S("E\x1acn")).replace(l.interpolate||s,function(e,n){return f.start+t(n)+f.end}).replace(l.encode||s,function(e,n){return c=!0,f.startencode+t(n)+f.end}).replace(l.conditional||s,function(e,n,i){return n?i?S("?gz?&(6#g!/b")+t(i)+S(",\x04U@EE\x19\x0e\x13"):S("2\x14\x0fHS[K\\ATII\x15\x02g"):i?S("\n,7dh'")+t(i)+S("$\f]H]]\x01\x16\v"):S(".\b\vL]F@\x1e\v\x10")}).replace(l.iterate||s,function(e,n,i,r){return n?(h+=1,d=r||"i"+h,n=t(n),S("$\x02\x1dQI[\nJ^_")+h+"="+n+S("\x1c&wy\b@PQ")+h+S("\r'tfp`3")+i+","+d+S(";\x01\x10\x0f\x13,")+h+S("\x17%xhi")+h+S("\x12=xpxplq7*'jvvLD\n")+d+S("6\vT")+h+S("7\x11B")+i+S(">\x02!30")+h+"["+d+S("\x119.%H-xmm1&;")):S("Ea|5i7k#8:dmv")}).replace(l.evaluate||s,function(e,n){return S("!\x05\x18")+t(n)+S(")E^X\x06\x13\b")})+S("Ea|:,>>>#n %%i")).replace(/\n/g,S("\fQ`")).replace(/\t/g,S("\rR{")).replace(/\r/g,S("\x17Dk")).replace(/(\s|;|\}|^|\{)out\+='';/g,S("5\x12\x06")).replace(/\+''/g,""),c&&(l.selfcontained||!n||n._encodeHTML||(n._encodeHTML=i.encodeHTMLSource(l.doNotSkipEncoded)),a=S("\x11drf5sy{v~~TISS\0\x1c\x02W]UCHN\tuNBNAKUyf~x\x15\x17\n\x05\x19\x1dNRY[Y)/''ceyg\x17,$(#)+\x07\x04\x1c\x1esnu~")+i.encodeHTMLSource.toString()+"("+(l.doNotSkipEncoded||"")+S("+\x05\x04\x15")+a);try{return new Function(l.varname,a)}catch(e){throw"undefined"!=typeof console&&console.log(S("\x15Uxmu~;rrj?CSGBP@\x06F\b]OF\\AO[U\x11TFZVB^WW\0\x1b")+a),e}},i.compile=function(e,t){return i.template(e,null,t)}}(),function(e,t){if("function"==typeof CKFinder.define&&CKFinder.define.amd)CKFinder.define(S("\x15tv{rxtrx"),[S('"VJACU[JEYI'),S("*A]XK]I"),S("&BPYEYX^")],function(n,i,r){e.Backbone=t(e,r,n,i)});else if("undefined"!=typeof exports){var n=require(S("\r{att``wzdr"));t(e,exports,n)}else e.Backbone=t(e,{},e._,e.jQuery||e.Zepto||e.ender||e.$)}(this,function(e,t,n,i){var r=e.Backbone,o=[],s=(o.push,o.slice);o.splice;t.VERSION=S("Cukwiz"),t.$=i,t.noConflict=function(){return e.Backbone=r,this},t.emulateHTTP=!1,t.emulateJSON=!1;var a=t.Events={on:function(e,t,n){if(!u(this,"on",e,[t,n])||!t)return this;this._events||(this._events={});var i=this._events[e]||(this._events[e]=[]);return i.push({callback:t,context:n,ctx:n||this}),this},once:function(e,t,i){if(!u(this,S("\x0f\x7f\x7fqv"),e,[t,i])||!t)return this;var r=this,o=n.once(function(){r.off(e,o),t.apply(this,arguments)});return o._callback=t,this.on(e,o,i)},off:function(e,t,i){var r,o,s,a,l,c,d,f;if(!this._events||!u(this,S("2\\RS"),e,[t,i]))return this;if(!e&&!t&&!i)return this._events=void 0,this;for(a=e?[e]:n.keys(this._events),l=0,c=a.length;lX%5"),e)},fetch:function(e){e=e?n.clone(e):{},void 0===e.parse&&(e.parse=!0);var t=e.success,i=this;return e.success=function(n){var r=S(e.reset?"1@VGPB":"8J_O");i[r](n,e),t&&t(i,n,e),i.trigger(S("&TQGI"),i,n,e)},B(this,e),this.sync(S(")XNMI"),this,e)},create:function(e,t){if(t=t?n.clone(t):{},!(e=this._prepareModel(e,t)))return!1;t.wait||this.add(e,t);var i=this,r=t.success;return t.success=function(e,n){t.wait&&i.add(e,t),r&&r(e,n,t)},e.save(null,t),e},parse:function(e,t){return e},clone:function(){return new this.constructor(this.models)},_reset:function(){this.length=0,this.models=[],this._byId={}},_prepareModel:function(e,t){if(e instanceof f)return e;t=t?n.clone(t):{},t.collection=this;var i=new this.model(e,t);return i.validationError?(this.trigger(S(":RRK_S)%"),this,i.validationError,t),!1):i},_addReference:function(e,t){this._byId[e.cid]=e,null!=e.id&&(this._byId[e.id]=e),e.collection||(e.collection=this),e.on(S("-OC\\"),this._onModelEvent,this)},_removeReference:function(e,t){this===e.collection&&delete e.collection,e.off(S("8XVW"),this._onModelEvent,this)},_onModelEvent:function(e,t,n,i){(e!==S(" @FG")&&e!==S("\x1aiypqiE")||n===this)&&(e===S("\x1fDDQWVJ_")&&this.remove(t,i),t&&e===S("\x18zrzrz{%")+t.idAttribute&&(delete this._byId[t.previous(t.idAttribute)],null!=t.id&&(this._byId[t.id]=t)),this.trigger.apply(this,arguments))}});var m=[S("\nmc\x7fKnsy"),S("%CFKA"),S("\x14xwg"),S("\fnac|tqg"),S("\x1fRDFVG@"),S('B%+)"+'),S("D,(--*>"),S("\x1aiyyk|EsKDLQ"),S("\x15pxt}h"),S("*MECJ"),S("(MO_INZ"),S("\fkgcdt`"),S("#W@JBK]"),S("\f\x7fkeurf"),S('"FR@T^'),S("\x13uyz"),S("3GZ[R"),S("\x16vv`"),S(".F^R^FPP"),S("+OB@[QX\\@"),S("\x1evNWMHA"),S("#ID^"),S("#ILH"),S("+XBo]BPK"),S("=MV:$"),S("5P^JJN"),S("\x1asy|z"),S("0ESXQ"),S("-GAYE[RX"),S("\nyi~z"),S("'\\HCG"),S("D!4(8"),S(">S!26"),S("\x0exyez|aa"),S(".KYWTVFPXT]"),S("%OILLRdJ"),S("%UO]OLGI"),S("-BNCE{]PPNx^"),S("\x10xaVyebn"),S("A!+%,("),S('"PEHVKM')];n.each(m,function(e){g.prototype[e]=function(){var t=s.call(arguments);return t.unshift(this.models),n[e].apply(n,t)}});var w=[S('"DVJSWjP'),S("\fnaz~ePj"),S(".\\_CFqM"),S("\x13}{rr`[c")];n.each(w,function(e){g.prototype[e]=function(t,i){var r=n.isFunction(t)?t:function(e){return e.get(t)};return n[e](this.models,r,i)}});var C=t.View=function(e){this.cid=n.uniqueId(S("\x1eiIDU")),e||(e={}),n.extend(this,n.pick(e,b)),this._ensureElement(),this.initialize.apply(this,arguments),this.delegateEvents()},y=/^(\S+)\s*(.*)$/,b=[S("\nfcikc"),S("\x16twuv~\x7fiwpN"),S("3QY"),S("2ZP"),S("#EQRUAK__I^"),S("(JFJ_^`N]T"),S("\x1ekAFlBI@"),S("\x1cxhzNUQ")];n.extend(C.prototype,a,{tagName:S("+HDX"),$:function(e){return this.$el.find(e)},initialize:function(){},render:function(){return this},remove:function(){return this.$el.remove(),this.stopListening(),this},setElement:function(e,n){return this.$el&&this.undelegateEvents(),this.$el=e instanceof t.$?e:t.$(e),this.el=this.$el[0],n!==!1&&this.delegateEvents(),this},delegateEvents:function(e){if(!e&&!(e=n.result(this,S("7]O_UHN"))))return this;this.undelegateEvents();for(var t in e){var i=e[t];if(n.isFunction(i)||(i=this[e[t]]),i){var r=t.match(y),o=r[1],s=r[2];i=n.bind(i,this),o+=S("2\x1dPPZR_XN^yK[Q42")+this.cid,""===s?this.$el.on(o,i):this.$el.on(o,s,i)}}return this},undelegateEvents:function(){return this.$el.off(S("1\x1cWQYSPYM_~JXPK3")+this.cid),this},_ensureElement:function(){if(this.el)this.setElement(n.result(this,S("#AI")),!1);else{var e=n.extend({},n.result(this,S("1SG@G_UMM_H")));this.id&&(e.id=n.result(this,S("9S_"))),this.className&&(e[S("9YW]NM")]=n.result(this,S("+OAO\\C\x7fS^Q")));var i=t.$("<"+n.result(this,S("1FRS{WZ]"))+">").attr(e);this.setElement(i,!1)}}}),t.sync=function(e,i,r){var o=F[e];n.defaults(r||(r={}),{emulateHTTP:t.emulateHTTP,emulateJSON:t.emulateJSON});var s={type:o,dataType:S("&M[FD")};if(r.url||(s.url=n.result(i,S("\x0fec~"))||H()),null!=r.data||!i||e!==S("2PFPWC]")&&e!==S("\x1chn{AUG")&&e!==S("B3%1%/")||(s.contentType=S("\fl~\x7f|xqr`|yy7sitr"),s.data=JSON.stringify(r.attrs||i.toJSON(r))),r.emulateJSON&&(s.contentType=S("&FXYFBOLZF__\x1dK\x19BA@\x15_UIQ\x10KM,$, +!##"),s.data=s.data?{model:s.data}:{}),r.emulateHTTP&&(o===S("\x12CAA")||o===S("=zz\f\x04\x16\x06")||o===S("E\x16\x06\x1c\n\x02"))){s.type=S("\x1cMQLt"),r.emulateJSON&&(s.data._method=o);var a=r.beforeSend;r.beforeSend=function(e){if(e.setRequestHeader(S("6o\x15qnol\x10sZ4)-'i\n0\":;#/)"),o),a)return a.apply(this,arguments)}}s.type===S("\x0eHUE")||r.emulateJSON||(s.processData=!1),s.type===S("\x13DTBTP")&&x&&(s.xhr=function(){return new ActiveXObject(S("\x16Zqzhtorxk\x0eyoolqrw"))});var l=r.xhr=t.ajax(n.extend(s,r));return i.trigger(S("1@VE@SDL"),i,l,r),l};var x=!("undefined"==typeof window||!window.ActiveXObject||window.XMLHttpRequest&&(new XMLHttpRequest).dispatchEvent),F={create:S("+|b}{"),update:S("E\x16\x12\x1c"),patch:S("\r^NDRZ"),delete:S("=zz\f\x04\x16\x06"),read:S("\x0fWTF")};t.ajax=function(){return t.$.ajax.apply(t.$,arguments)};var _=t.Router=function(e){e||(e={}),e.routes&&(this.routes=e.routes),this._bindRoutes(),this.initialize.apply(this,arguments)},E=/\((.*?)\)/g,M=/(\(\?)?:\w+/g,I=/\*\w+/g,T=/[\-{}\[\]+?.,\\\^$|#\s]/g;n.extend(_.prototype,a,{initialize:function(){},route:function(e,i,r){n.isRegExp(e)||(e=this._routeToRegExp(e)),n.isFunction(i)&&(r=i,i=""),r||(r=this[i]);var o=this;return t.history.route(e,function(n){var s=o._extractParameters(e,n);o.execute(r,s),o.trigger.apply(o,[S("%TH]]O\x11")+i].concat(s)),o.trigger(S("&UG\\^N"),i,s),t.history.trigger(S("\f\x7fazdt"),o,i,s)}),this},execute:function(e,t){e&&e.apply(this,t)},navigate:function(e,n){return t.history.navigate(e,n),this},_bindRoutes:function(){if(this.routes){this.routes=n.result(this,S("\x18kunhxm"));for(var e,t=n.keys(this.routes);null!=(e=t.pop());)this.route(e,this.routes[e])}},_routeToRegExp:function(e){return e=e.replace(T,S("6k\x1c\x1f")).replace(E,S("8\x11\x05\x01\x18\f\x17\0")).replace(M,function(e,t){return t?e:S("0\x19im\x1b\nk\x1c\x11")}).replace(I,S("\v$VP0M;-:")),new RegExp("^"+e+S("Aj|~\x19yo\x13\x159\x17\x1f\x10dfynv"))},_extractParameters:function(e,t){var i=e.exec(t).slice(1);return n.map(i,function(e,t){return t===i.length-1?e||null:e?decodeURIComponent(e):null})}});var D=t.History=function(){this.handlers=[],n.bindAll(this,S("/SYWP_`D[")),"undefined"!=typeof window&&(this.location=window.location,this.history=window.history)},P=/^[#\/]|\s+$/g,O=/^\/+|\/+$/g,A=/msie [\w.]+/,R=/\/$/,V=/#.*$/;D.started=!1,n.extend(D.prototype,a,{interval:50,atRoot:function(){return this.location.pathname.replace(/[^\/]$/,S("$\x01\0\b"))===this.root},getHash:function(e){var t=(e||this).location.href.match(/#(.*)$/);return t?t[1]:""},getFragment:function(e,t){if(null==e)if(this._hasPushState||!this._wantsHashChange||t){e=decodeURI(this.location.pathname+this.location.search);var n=this.root.replace(R,"");e.indexOf(n)||(e=e.slice(n.length))}else e=this.getHash();return e.replace(P,"")},start:function(e){if(D.started)throw new Error(S("0sSP_WYY]\x17RROIQM9a*\"7e'+:,+/5m,*5?r 4$#=="));D.started=!0,this.options=n.extend({root:"/"},this.options,e),this.root=this.options.root,this._wantsHashChange=this.options.hashChange!==!1,this._wantsPushState=!!this.options.pushState,this._hasPushState=!!(this.options.pushState&&this.history&&this.history.pushState);var i=this.getFragment(),r=document.documentMode,o=A.exec(navigator.userAgent.toLowerCase())&&(!r||r<=7);if(this.root=("/"+this.root+"/").replace(O,"/"),o&&this._wantsHashChange){var s=t.$(S("-\x12FVCS^Q\x15EE[\x04\x18Q]K_L#3+30\x7fveh=+)%#**(lp~ewh"));this.iframe=s.hide().appendTo(S("\x1fBNFZ"))[0].contentWindow,this.navigate(i)}this._hasPushState?t.$(window).on(S("\x1dnpPRVBP@"),this.checkUrl):this._wantsHashChange&&S("'GGBJ_EMGQ_UV")in window&&!o?t.$(window).on(S("9RZOU]W!/%&"),this.checkUrl):this._wantsHashChange&&(this._checkUrlInterval=setInterval(this.checkUrl,this.interval)),this.fragment=i;var a=this.location;if(this._wantsHashChange&&this._wantsPushState){if(!this._hasPushState&&!this.atRoot())return this.fragment=this.getFragment(null,!0),this.location.replace(this.root+"#"+this.fragment),!0;this._hasPushState&&this.atRoot()&&a.hash&&(this.fragment=this.getHash().replace(P,""),this.history.replaceState({},document.title,this.root+this.fragment))}if(!this.options.silent)return this.loadUrl()},stop:function(){t.$(window).off(S("\x11b|dfbvl|"),this.checkUrl).off(S("\x16\x7fyjrxt|pxE"),this.checkUrl),this._checkUrlInterval&&clearInterval(this._checkUrlInterval),D.started=!1},route:function(e,t){this.handlers.unshift({route:e,callback:t})},checkUrl:function(e){var t=this.getFragment();return t===this.fragment&&this.iframe&&(t=this.getFragment(this.getHash(this.iframe))),t!==this.fragment&&(this.iframe&&this.navigate(t),void this.loadUrl())},loadUrl:function(e){return e=this.fragment=this.getFragment(e),n.any(this.handlers,function(t){if(t.route.test(e))return t.callback(e),!0})},navigate:function(e,t){if(!D.started)return!1;t&&t!==!0||(t={trigger:!!t});var n=this.root+(e=this.getFragment(e||""));if(e=e.replace(V,""),this.fragment!==e){if(this.fragment=e,""===e&&"/"!==n&&(n=n.slice(0,-1)),this._hasPushState)this.history[S(t.replace?"@3'3($%\"\x1b=+?)":'=?!7! ,v8*y<.2>*6\x0f\x0fB\x0e\x11\x16\x12G\n\fJ\x18\x1c\b\r\x06\x16\x18\x17\x17"))},B=function(e,t){var n=t.error;t.error=function(i){n&&n(e,i,t),e.trigger(S("E#5:&8"),e,i,t)}};return t}),CKFinder.define(S('B\0\x0f\x03/),,8d\x0f" )96'),[],function(){"use strict";var e={id:"",configPath:S("7[VT]UZ\x10U3"),language:"",languages:{bg:1,bs:1,ca:1,cs:1,cy:1,da:1,de:1,"de-ch":1,el:1,en:1,eo:1,es:1,"es-mx":1,et:1,eu:1,fa:1,fi:1,fr:1,gu:1,he:1,hi:1,hr:1,hu:1,it:1,ja:1,ko:1,ku:1,lt:1,lv:1,nb:1,nl:1,nn:1,no:1,pl:1,"pt-br":1,ro:1,ru:1,sk:1,sl:1,sr:1,sv:1,tr:1,uk:1,vi:1,"zh-cn":1,"zh-tw":1},defaultLanguage:S(",H@"),removeModules:"",plugins:"",tabIndex:0,resourceType:null,type:null,startupPath:"",startupFolderExpanded:!0,readOnly:!1,readOnlyExclude:"",connectorPath:"",connectorLanguage:S("%VOX"),pass:"",connectorInfo:"",dialogMinWidth:S("?qy'."),dialogMinHeight:S("6\x03]T"),dialogFocusItem:!0,dialogOverlaySwatch:!1,loaderOverlaySwatch:!1,width:S("\x1e.\x10\x11\x07"),height:400,fileIcons:{default:S("\x14`x|vvmu2mpx"),folder:S("(MCYINZ@BH\x1cCZR"),"7z":S("#\x13_\bWFN"),accdb:S(';]^]Z32l3*"'),avi:S("8OS_YR\x10O.&"),bmp:S("E)1l3*"')},fileIconsPath:S("E5,!'9d/\"<*\x7f7;?1x?477)t"),fileIconsSizes:S("%\x14\x12\x1e\x05\x1b\x19\x14\x01\x18\x1b\x1c\x05\n\x1f\x07\x07\x1a\x05\n\x15\v\r"),defaultDisplayFileName:!0,defaultDisplayDate:!0,defaultDisplayFileSize:!0,defaultViewType:S("(]B^AO@NY]A"),defaultSortBy:S("\x16yyt\x7f"),defaultSortByOrder:S("C%6%"),listViewIconSize:22,compactViewIconSize:22,thumbnailDelay:50,thumbnailDefaultSize:150,thumbnailMinSize:null,thumbnailMaxSize:null,thumbnailSizeStep:2,thumbnailClasses:{120:S("\x1fSLCOH"),180:S("=SZ$(7.")},chooseFiles:!1,chooseFilesOnDblClick:!0,chooseFilesClosePopup:!0,resizeImages:!0,rememberLastFolder:!0,skin:S("\x19wtssq"),swatch:"a",displayFoldersPanel:!0,jquery:S("/\\XP@\x1b_GB]KC\x15VN"),jqueryMobile:S("$IOE[\x06@ZYH\\V\x1e\\]Q]YS\x19RJ"),jqueryMobileStructureCSS:S(":WU_M\x10*07&6=0;u--)if(l[u].priority<=o)return l.splice(u+1,0,s),{removeListener:a};l.unshift(s)}return{removeListener:a}},once:function(){var e=arguments[1];return arguments[1]=function(t){return t.removeListener(),e.apply(this,arguments)},this.on.apply(this,arguments)},fire:function(){var e=0,n=function(){e=1},i=0,r=function(){i=1};return function(o,s,a){var l,u,c,d,f=t(this)[o],S=e,h=i;if(e=0,i=0,f&&(c=f.listeners,c.length))for(c=c.slice(0),l=0;l=0&&r.listeners.splice(i,1))},removeAllListeners:function(){var e,n=t(this);for(e in n)delete n[e]},hasListeners:function(e){var n=t(this)[e];return n&&n.listeners.length>0}},e}),CKFinder.define(S("6ts\x7fSUXXL\x10\x155+/k\x102.$"),[S("\n~bik}cr}aq")],function(e){"use strict";var t={url:function(e){return/^(http(s)?:)?\/\/.+/i.test(e)?e:CKFinder.require.toUrl(e)},asyncArrayTraverse:function(e,t,n){var i,r=50,o=10,s=0;n||(n=null),t=t.bind(n),(i=function(){for(var n,a=0,l=(new Date).getTime();;){if(n=e.item?e.item(s):e[s],!n||t(n,s,e)===!1)return;if(s+=1,a+=1,a>=o&&(new Date).getTime()-l>r)return setTimeout(i,r)}}).call()},isPopup:function(){return window!==window.parent&&!!window.opener||window.isCKFinderPopup},isModal:function(){return window.parent.CKFinder&&window.parent.CKFinder.modal&&window.parent.CKFinder.modal(S(" WKPMGJB"))},isWidget:function(){return window!==window.parent&&!window.opener},toGet:function(t){var n="";return e.forOwn(t,function(e,i){n+="&"+encodeURIComponent(i)+"="+encodeURIComponent(t[i])}),n.substring(1)},cssEntities:function(e){return e.replace(/\(/g,S('"\x05\x07\x1c\x14\x1c\x0e\n\x1e\x1b\x17')).replace(/\)/g,S("$\x03\x05\x1e\x1a\x12\f\b\x18\x1c\x15"))},jsCssEntities:function(e){return e.replace(/\(/g,S("\x153% ")).replace(/\)/g,S("4\x10\x04\x0e"))},getUrlParams:function(){var e={};return window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi,function(t,n,i){e[n]=i}),e},parentFolder:function(e){return e.split("/").slice(0,-1).join("/")},isShortcut:function(t,n){var i=n.split("+"),r=!!t.ctrlKey||!!t.metaKey,o=!!t.altKey,s=!!t.shiftKey,a=r===!!e.contains(i,S("\x17{mhw")),l=o===!!e.contains(i,S('B"(1')),u=s===!!e.contains(i,S("'[ACMX"));return a&&l&&u},randomString:function(e,t){t||(t=S("4TTT\\\\\\\\TTTT,,,,4444<<<<444\x7facagacaoa"));for(var n="",i=0;i":S("Ad$0~"),'"':S("Be50)3s"),"'":S("'\x0e\n\x1a\x18\x15\x16")};return e.replace(/[&<>"']/g,function(e){return t[e]})}};return t}),CKFinder.define(S('3w~p^V]_I\x13hJV,n\x0e"*"'),[S(">J.%'17&)5-"),S("D/72-;3"),S("\x1fCJD|CIIEIE")],function(e,t,n){"use strict";function i(e,t,i,o){function s(t){o(e,JSON.parse(t))}function a(){o(e)}e||(e=r.getSupportedLanguage(navigator.userLanguage||navigator.language,i)),i[t]||(t=S("?%/"));var l,u=S("\x10}s}s:")+t+S(".\x01ZB]]");i[e]&&(l=S("\ngmci ")+e+S("Eh-;&$")),l||(l=u),n.require([S("\x17l|bo=")+n.require.toUrl(l)+S("(\x16\\N^\x10DCIIP\x02")],s,a)}var r={loadPluginLang:function(t,i,r,o){var s,a=r.lang.split(",");if(e.indexOf(a,t)>=0)s=t;else{if(!(e.indexOf(a,i)>=0))return void o({});s=i}n.require([S("\n\x7fiuz.")+n.require.toUrl(r.path)+S(":W]SY\x10")+s+S("#\nOUHF")],function(e){var t;try{t=JSON.parse(e)}catch(e){t={}}o(t)},function(){o({})})}, +init:function(n){var r=new t.Deferred;return i(n.language,n.defaultLanguage,n.languages,function(t,n){if(!n)return void r.reject();var i=n;i.formatDate=function(){var e=S("\vW*")+i.units.dateAmPm.join(S("\x17?5="))+S("5\x11j"),t=i.units.dateFormat.replace(/dd|mm|yyyy|hh|HH|MM|aa|d|m|yy|h|H|M|a/g,function(t){var n={d:S("\x14qwn6k\x7fkp|}z\b\x0e|\x13\v\t\x01\0\x01"),dd:S(":_]D"),m:S("\vab`{x?`vdywt}15E,228\x07\b"),mm:S("\x1dspNUJ"),yy:S("$\\CFZ\x07Y^N^Z]\x18\x03\x1b"),yyyy:S("0HWRF"),H:S("&OG\\X\x05^H^CQRW\x1b\x1bk\x06\x18\x14\x1e\x1d\x12"),HH:S("D-)2:"),h:S('7HXHHYtPKha*,17fnhtwvl}nivq"2&&3\x1e6-r{140*\x14\x04BJDX[ZHYJT')+S("8\x19\x1d\n\x0e\x1a\x1e")+":"+S("#\x04\r\x06\x0f\bAE^^\r\x12\x12\x10\0\0\x13\v\x15^XMK\x1a\x01\x1c\x15\x1e\x17`)-66ekgy{jblfn~`arzz!9\x04,+35;uwq\x13\x14\0\x10\x10\x17NGYICKEC\x1c\n\0\x1d\x13\x10\x11]Y)HVV\\[T^V"),hh:S("\x153*w@\f\v\r\x11\x11\x03GAIWVQM^OO")+S("(\t\r\x1a\x1e\n\x0e")+":"+S("Abkdmf/'<8kppn~bqms<:#%xczs|u~7\x0f\x14\x10CIEWUH@J@L\\^_PX\\\x07\x1b&\x02\x05\x11\x17\x1dSUS\r\nbrvq,%7'!)#+%"),M:S('C),(2<,d9)=".34z|\ney{\x7f~s'),MM:S("\x1erIOWWA"),a:e+S("\x11I3|zce8%:*.=!?\x10\x01\x18\x03\x15\x05{\tKAKYmY\x06\x1f\x19"),aa:e+S("\x18B:sshl?\x1c\x01\x13\x11\x04\x1a\x06\x17\b\x13\n\x1a\fp")};return S("\v+!")+n[t]+S("\x185=")});return t="'"+t+"'",t=t.replace(/('',)|,''$/g,""),new Function(S("\x13mpwe"),S("(DEEXE"),S("0USJ"),S("=VP53"),S("*FEC[[U"),S(",_K[EC\\\x13o")+t+S("3i\x1b\\XQW\x12\x19\x1e\x14\x05"))}(),i.formatDateString=function(t){return t=t||"",e.isNumber(t)&&(t=t.toString()),t.length<12?"":i.formatDate(t.substr(0,4),t.substr(4,2),t.substr(6,2),t.substr(8,2),t.substr(10,2))},i.formatFileSize=function(e){var t=1024,n=t*t,r=n*t;return e>=r?i.units.gb.replace(S("@:1*> ;"),(e/r).toFixed(1)):e>=n?i.units.mb.replace(S(";GNWE%<"),(e/n).toFixed(1)):e>=t?i.units.kb.replace(S("\x0etcxhvi"),(e/t).toFixed(1)):S("4NE^B\\G\x1b~").replace(S("(RYBVHS"),e)},i.formatTransfer=function(e){return i.units.sizePerSecond.replace(S("\x12hg|lre"),i.formatFileSize(parseInt(e)))},i.formatFilesCount=function(e){return i.files[S(1===e?"\x11q|a{bXv|":"\x12p{`xcUxtb")].replace(S("#_FIRF]W"),e)},r.resolve(i)}),r.promise()},getSupportedLanguage:function(e,t){if(!e)return!1;var n=e.toLowerCase().match(/([a-z]+)(?:-([a-z]+))?/),i=n[1],r=n[2];return t[i+"-"+r]?i=i+"-"+r:t[i]||(i=!1),i}};return r}),CKFinder.define(S("8zq}USZZ2n\x177-)i\f-0\t$(("),{up:38,down:40,left:37,right:39,backspace:8,tab:9,enter:13,space:32,escape:27,end:35,home:36,delete:46,menu:93,slash:191,a:65,r:82,u:85,f2:113,f5:116,f7:118,f8:119,f9:120,f10:121}),CKFinder.define(S("%eln@DOI_\x01zy\x1egz|TU\\K"),[S("?5/&&66%(:,"),S(".EADWAM"),S("\x12P_S\x7fy||h4Iiws\x0fjGZgJBB"),S("(JAM\x01G_ZUCK\x1eYZT^T\\")],function(e,t,n){"use strict";function i(){var n=[S("6CJXTHUIWP.")];e.forEach(n,function(e){o(e)&&t(S("\x10s}wm")).addClass(S(" BIE\tCCF\\\\XN\x01N]\\\x1d")+e)})}function r(e){var n=void 0===document.documentMode,i=window.chrome;n&&!i?t(window).on(S("\x1eyOBWPMK"),function(t){t.target===window&&setTimeout(function(){e.fire(S("\x1anu'xpCTQ"),null,e)},a)}).on(S("\fkaleb}f`"),function(t){t.target===window&&e.fire(S("2F]\x0fT[MK"),null,e)}):window.addEventListener?(window.addEventListener(S("\x1a}s~kl"),function(){setTimeout(function(){e.fire(S("\x1chw%FNAVW"),null,e)},a)},!1),window.addEventListener(S("\x1ayphl"),function(){e.fire(S("\x18ls!~qkm"),null,e)},!1)):(window.attachEvent(S("%@HK\\Y"),function(){setTimeout(function(){e.fire(S("\fxg5v~qfg"),null,e)},a)}),window.attachEvent(S(":YPHL"),function(){e.fire(S("6BQ\x03XWIO"),null,e)}))}function o(e){var t=document.body||document.documentElement,n=t.style;if("string"==typeof n[e])return!0;var i=[S("D\b)="),S("!UFFNOS"),S("\fZkm{xf"),S(",fF[]]"),"O",S("\x10|a")];e=e.charAt(0).toUpperCase()+e.substr(1);for(var r=0;r-1&&o.addClass(S("3W^P\x1aQ\\")),t(S("'")),e.setHandler(S('B6-\x7f!"<\x04%/)'),function(){var n,i,r=window.matchMedia?function(){return void 0===i&&(i=S("\x1c5s~X\fUJ@QN\x1d\b")+e.config.uiModeThreshold+S(".J]\x18")),window.matchMedia(i).matches}:function(){return void 0===n&&(n=parseFloat(t(S("\niciw")).css(S(";ZRPKm2+9!")))*e.config.uiModeThreshold),window.innerWidth<=n};return function(){return S(r.call(this)?"*FCOGCU":"C 5,<&:")}}());var a=e.request(S("\x12f}/qrlTu\x7fy"));s(o,null,a),t(window).bind(S("\x14a~ewmnwyylzSHXF"),function(){var t=e.request(S("5C^\x02^_OqRZZ")),n=a!==t;n&&(s(o,a,t),a=t),e.fire(S("\x12f}/drkp`~"),{modeChanged:n,mode:a},e)});var l=t.event.special.swipe.start;t.event.special.swipe.start=function(e){var t=l(e);return t.ckfOrigin=e.originalEvent.type,t},t(window).bind(S("C72/7-%/-8"),function(t){0!==t.swipestart.ckfOrigin.indexOf(S("\x19wtin{"))&&e.fire(S("/EX\b@C\\FRT\\\\O"),{evt:t},e)}),t(window).bind(S('A14-5#5!."?'),function(t){0!==t.swipestart.ckfOrigin.indexOf(S("E+(=:/"))&&e.fire(S("']@\x10X[D^JBXU[@"),{evt:t},e)}),e.setHandler(S("/S]]@QeYGMI"),function(){e.util.isPopup()?window.close():window.top&&window.top.CKFinder&&window.top.CKFinder.modal&&window.top.CKFinder.modal(S("6TTVI^"))}),t(document).on(S(";OXRZ#517%72"),S("\x15Msjx}|}\x7frz}"),function(e){e.preventDefault(),e.dragDrop&&e.dragDrop()}),e.once(S("5WGH\x03H^]YG"),function(e){e.finder.request(S("\x13\x7fpo-tpioys"),{key:n.space}),e.finder.on(S("&LMPND[C\x14")+n.space,function(e){e.data.evt.preventDefault()})})}}}),CKFinder.define(S("/sztZZQSE\x17iVN[TPLo\x11.6#,("),[S("\x0ez~uwagvye}"),S("2YE@SEA"),S("'JHI@NB@J")],function(e,t,n){"use strict";function i(){}return i.extend=n.Model.extend,e.extend(i.prototype,{addCss:function(e){t(S("\x17$jnbpx ")).text(e).appendTo(S("8Q_ZX"))},init:function(){}}),i}),CKFinder.define(S(",neiY_VVF\x1af[M^SUO\x12nS5&+-7"),[S("\x1ejNEGQWFIUM"),S("&MY\\OYU"),S("\x1d|~CJ@LJ@"),S("\x1aXW[wqDDP\ftIS@AGY\x04|A[HY_"),S("\vOFHf~uwa;@b~t6Vzrz")],function(e,t,n,i,r){"use strict";function o(e,t,n){function i(){t.init(e),e._plugins.add(t),n.loaded=!0,e.fire(S('>O,4%**\x7f4")-3'),{plugin:t},e)}return t.path=e.util.parentFolder(n.url)+"/",t.lang?void r.loadPluginLang(e.lang.langCode,e.config.defaultLanguage,t,function(t){t.name&&t.values&&(e.lang[t.name]=t.values),i()}):void i()}var s=n.Collection.extend({load:function(t){function n(){var n=e.countBy(r,S("\x19vt}y{{"));n.undefined||(t.fire(S("0A^FS\\X\rYUViY\\ZF"),null,t),n.false&&e.forEach(e.where(r,{loaded:!1}),function(e){t.fire(S("\x1dnsUFKM\x1eIIFLlXYC_"),{configKey:e.config,url:e.url})}))}var r=[],s=t.config.plugins;return s.length<1?void t.fire(S(")ZGYJGA\nP^_fPWSA"),null,t):(e.isString(s)&&(s=s.split(",")),e.forEach(s,function(e){var t=e;e.search("/")===-1&&(t=CKFinder.require.toUrl(S('"SHPANFZ\x05')+e+"/"+e+".js")),r.push({config:e,url:t,loaded:void 0})}),t.on(S("\x1dnsUFKM\x1eWCFLP"),function(){n()}),void e.forEach(r,function(e){CKFinder.require([e.url],function(n){var r=i.extend(n);o(t,new r,e)},function(){e.loaded=!1,n()})}))}});return s}),CKFinder.define(S("1qxr\\XS]K\x15vSYKS%2m\x0077 \x13'\"/%\x01, .74 |\x17&$1\f61>2\x10?1\x01\x06\x07\x11"),[],function(){"use strict";function e(e){e.setHandler(S("\x17{jh}&z{ktNIFJ"),t),e.setHandler(S("\x1ctpkESLBH\x1fETZO\x10XIY~NBT\\Gc\\XSWNnTWXP"),function(e){a=e.token})}function t(){if(a)return a;var e=n(o);return e.length!=s&&(e=r(s),i(o,e)),e}function n(e){e=e.toLowerCase();for(var t=window.document.cookie.split(";"),n=0;n1?i[1]:"";if(r===e)return decodeURIComponent(o)}return""}function i(e,t){window.document.cookie=encodeURIComponent(e)+"="+encodeURIComponent(t)+S("\x12(dtb\x7f%6")}function r(e){var t=S("4TTT\\\\\\\\TTTT,,,,4444<<<<444\x7facagacaoa"),n=[],i="";if(window.crypto&&window.crypto.getRandomValues)n=new Uint8Array(e),window.crypto.getRandomValues(n);else for(var r=0;r.5?s.toUpperCase():s}return i}var o=S("D&-\x04;;,\x1f#&+!"),s=40,a=null;return e}),CKFinder.define(S('"`ocOILLX\x04aBJZ\\TA\x1cwZXY]ZNTN\x12jM!/13+72'),[S("\x1dtnUDPZ"),S('"VJACU[JEYI')],function(e,t){"use strict";function n(e,t){this.url=e,this.config=t,this.onDone=o,this.onFail=o,this.request=null}function i(t){var n,i;n=new XDomainRequest,i=null,t.config.type===S("\f}a|d")&&(i=e.param(t.config.post)),n.open(t.config.type,t.url),n.onload=function(){t.onDone(this.responseText)},n.onprogress=o,n.ontimeout=o,n.onerror=function(){t.onFail()},t.request=n,setTimeout(function(){n.send(i)},0)}function r(n){var i,r;i=new XMLHttpRequest,r=null,i.open(n.config.type,n.url,!0),i.onreadystatechange=function(){4===this.readyState&&n.onDone(this.responseText)},i.onerror=function(){n.onFail()},t.isFunction(n.config.uploadProgress)&&i.upload&&(i.upload.onprogress=n.config.uploadProgress),t.isFunction(n.config.uploadEnd)&&i.upload&&(i.upload.onload=n.config.uploadEnd),n.config.type===S("(YEXX")&&(r=e.param(t.extend(n.config.post)),i.setRequestHeader(S("\x1b_rpkEOV\x0ep\\VB"),S("!CSTIODI]CDB\x02V\x02GFE\x1eRZDZ\x15LHWYS]P$$&"))),i.send(r),n.request=i}var o=function(){};return n.prototype.done=function(e){this.onDone=e},n.prototype.fail=function(e){this.onFail=e},n.prototype.send=function(){window.XMLHttpRequest?r(this):i(this)},n.prototype.abort=function(){this.request&&this.request.abort()},n}),CKFinder.define(S("\fNEIy\x7fvvf:[x|lv~o2]pNOG@PJT\bkFDEINZ@B"),[S("?5/&&66%(:,"),S(")@ZYH\\V"),S("=]T&\x1e%/+''+"),S('+ofhF^UWA\x1bxYSMU_H\x13~QQ.$!7+7i\x13:($8<"<;')],function(e,t,n,i){"use strict";function r(e){function t(e){if(/^(http(s)?:)?\/\/.+/i.test(e))return e;0!==e.indexOf("/")&&(e="/"+e);var t=window.parent?window.parent.location:window.location,n=t.protocol+S(">\x10o")+t.host;return n+e}var i=e.config;this.finder=e,this.config=i,i.connectorPath?this.baseUrl=t(i.connectorPath):(this.baseUrl=n._connectors[n.connector],"/"!==this.baseUrl.charAt(0)&&(this.baseUrl=n.require.toUrl(S("1\x1c\x1c")+this.baseUrl)),this.baseUrl=t(this.baseUrl)),e.setHandlers({"command:send":{callback:s,context:this},"command:url":{callback:function(e){return o.call(this,e.command,e.params,e.folder)},context:this}})}function o(t,n,i){var r=this.finder,o=r.config,s={command:t,lang:r.lang.langCode},a=o.connectorInfo;if(i&&(s.type=i.get(S("9H^ORKM#$\x16:4 ")),s.currentFolder=i.getPath(),s.hash=i.getHash()),o.pass.length){var l=o.pass.split(",");e.forEach(l,function(e){s[e]=r.config[e]})}o.id&&(s.id=o.id);var u=this.baseUrl+"?"+r.util.toGet(e.extend(s,n));return a.length>0&&(u+="&"+a),u}function s(n){var r=this.finder,s=n.name,l=t.Deferred(),u={name:s,response:{error:{number:109}}};if(e.has(n,S("\x14vyyl|bo"))&&(u.context=n.context),r.fire(S(":XSPS^.%x!!#)5-"),n,r)&&r.fire(S("C'*+*)'.q.(( \"4h")+s,n,r)){var c=e.extend({type:S("%AB\\"),post:{}},n),d={};d.type=c.type,c.type===S("1B\\GA")&&(c.post.ckCsrfToken=r.request(S("&D[[L\x11KHZ{_ZW]")),d.post=c.sendPostAsJson?{jsonData:JSON.stringify(c.post)}:c.post),c.uploadProgress&&(d.uploadProgress=c.uploadProgress),c.uploadEnd&&(d.uploadEnd=c.uploadEnd);var f=o.call(this,s,n.params,n.folder),h=new i(f,d);return h.done(function(t){var i,o,c=!1;try{o=JSON.parse(t),i={name:s,response:o,rawResponse:t},c=!0}catch(e){var d=u;return d.response.error.message=t,a(s,d,r),void l.reject(d)}c&&l.resolve(o),e.has(n,S("\x12p{{br`m"))&&(i.context=n.context),!o||o.error?r.fire(S("3WZ[ZYW^\x01YOLP2{")+s,i,r)&&(n.context&&n.context.silentConnectorErrors||r.fire(S(":XSPS^.%x&67)5"),i,r)):r.fire(S(";_RSR!/&y+.|")+s,i,r),r.fire(S("B +(+&&-p**9+="),i,r),r.fire(S("\x1fCNONEKB\x1dIO^N^\x17")+s,i,r)}),h.fail(function(){a(s,u,r),l.reject(u)}),h.send(),n.returnTransport?h:l.promise()}}function a(e,t,n){n.fire(S("\fnab}p|w.pdewk ")+e,t,n)&&n.fire(S("\x18zuvq|p{\x1aDPQKW"),t,n),n.fire(S("\x16twtwzry$~FUGQ"),t,n),n.fire(S("B +(+&&-p**9+=j")+e,t,n)}return r}),function(e,t){if("function"==typeof CKFinder.define&&CKFinder.define.amd)CKFinder.define(S(".BQC[\\ZPBC]"),[S("\x11prw~txv|"),S("\x1ejNEGQWFIUM")],function(n,i){return e.Marionette=e.Mn=t(e,n,i)});else if("undefined"!=typeof exports){var n=require(S("!@BGNDHFL")),i=require(S(".Z^UWAGVYE]"));module.exports=t(e,n,i)}else e.Marionette=e.Mn=t(e,e.Backbone,e._)}(this,function(e,t,n){"use strict";!function(e,t){var n=e.ChildViewContainer;return e.ChildViewContainer=function(e,t){var n=function(e){this._views={},this._indexByModel={},this._indexByCustom={},this._updateLength(),t.each(e,this.add,this)};t.extend(n.prototype,{add:function(e,t){var n=e.cid;return this._views[n]=e,e.model&&(this._indexByModel[e.model.cid]=n),t&&(this._indexByCustom[t]=n),this._updateLength(),this},findByModel:function(e){return this.findByModelCid(e.cid)},findByModelCid:function(e){var t=this._indexByModel[e];return this.findByCid(t)},findByCustom:function(e){var t=this._indexByCustom[e];return this.findByCid(t)},findByIndex:function(e){return t.values(this._views)[e]},findByCid:function(e){return this._views[e]},remove:function(e){var n=e.cid;return e.model&&delete this._indexByModel[e.model.cid],t.any(this._indexByCustom,function(e,t){if(e===n)return delete this._indexByCustom[t],!0},this),delete this._views[n],this._updateLength(),this},call:function(e){this.apply(e,t.tail(arguments))},apply:function(e,n){t.each(this._views,function(i){t.isFunction(i[e])&&i[e].apply(i,n||[])})},_updateLength:function(){this.length=t.size(this._views)}});var i=[S("@'-1\x01$%/"),S("8\\[XT"),S("\x1cp\x7fo"),S("\nmecj"),S(":_YI[\\4"),S("\fkgcdt`"),S("=MZ,$!7"),S("#V@LBK]"),S("$@PBZP"),S("4TZ["),S("&TGDO"),S("9[UE"),S("-GAS]GWQ"),S("5UXVM[RRN"),S("\x1arrkqtE"),S("\x1ekO`PQE\\"),S("0W[AGA"),S("B**,2.)%"),S('E4";='),S("\x1aw}nj"),S("\x1fWHVKKPR"),S("9SHyPNK9"),S("\v|a{l{"),S("\x1emEEW@A")];return t.each(i,function(e){n.prototype[e]=function(){var n=t.values(this._views),i=[n].concat(t.toArray(arguments));return t[e].apply(t,i)}}),n}(e,t),e.ChildViewContainer.VERSION=S("7\b\x17\v\x15\r\f"),e.ChildViewContainer.noConflict=function(){return e.ChildViewContainer=n,this},e.ChildViewContainer}(t,n),function(e,t){var n=e.Wreqr,i=e.Wreqr={};return e.Wreqr.VERSION=S("\x14$8$6/"),e.Wreqr.noConflict=function(){return e.Wreqr=n,this},i.Handlers=function(e,t){var n=function(e){this.options=e,this._wreqrHandlers={},t.isFunction(this.initialize)&&this.initialize(e)};return n.extend=e.Model.extend,t.extend(n.prototype,e.Events,{setHandlers:function(e){t.each(e,function(e,n){var i=null;t.isObject(e)&&!t.isFunction(e)&&(i=e.context,e=e.callback),this.setHandler(n,e,i)},this)},setHandler:function(e,t,n){var i={callback:t,context:n};this._wreqrHandlers[e]=i,this.trigger(S("C,$(#$,8q-)*"),e,t,n)},hasHandler:function(e){return!!this._wreqrHandlers[e]},getHandler:function(e){var t=this._wreqrHandlers[e];if(t)return function(){return t.callback.apply(t.context,arguments)}},removeHandler:function(e){delete this._wreqrHandlers[e]},removeAllHandlers:function(){this._wreqrHandlers={}}}),n}(e,t),i.CommandStorage=function(){var n=function(e){this.options=e,this._commands={},t.isFunction(this.initialize)&&this.initialize(e)};return t.extend(n.prototype,e.Events,{getCommands:function(e){var t=this._commands[e];return t||(t={command:e,instances:[]},this._commands[e]=t),t},addCommand:function(e,t){var n=this.getCommands(e);n.instances.push(t)},clearCommands:function(e){var t=this.getCommands(e);t.instances=[]}}),n}(),i.Commands=function(e,t){return e.Handlers.extend({storageType:e.CommandStorage,constructor:function(t){this.options=t||{},this._initializeStorage(this.options),this.on(S("#LDHCDLX\x11MIJ"),this._executeCommands,this),e.Handlers.prototype.constructor.apply(this,arguments)},execute:function(e){e=arguments[0];var n=t.rest(arguments);this.hasHandler(e)?this.getHandler(e).apply(this,n):this.storage.addCommand(e,n)},_executeCommands:function(e,n,i){var r=this.storage.getCommands(e);t.each(r.instances,function(e){n.apply(i,e)}),this.storage.clearCommands(e)},_initializeStorage:function(e){var n,i=e.storageType||this.storageType;n=t.isFunction(i)?new i:i,this.storage=n}})}(i,t),i.RequestResponse=function(e,t){return e.Handlers.extend({request:function(e){if(this.hasHandler(e))return this.getHandler(e).apply(this,t.rest(arguments))}})}(i,t),i.EventAggregator=function(e,t){var n=function(){};return n.extend=e.Model.extend,t.extend(n.prototype,e.Events),n}(e,t),i.Channel=function(n){var i=function(t){this.vent=new e.Wreqr.EventAggregator,this.reqres=new e.Wreqr.RequestResponse,this.commands=new e.Wreqr.Commands,this.channelName=t};return t.extend(i.prototype,{reset:function(){return this.vent.off(),this.vent.stopListening(),this.reqres.removeAllHandlers(),this.commands.removeAllHandlers(),this},connectEvents:function(e,t){return this._connect(S(";JXPK"),e,t),this},connectCommands:function(e,t){return this._connect(S("<^QR- ,'7"),e,t),this},connectRequests:function(e,t){return this._connect(S("1@VEGSD"),e,t),this},_connect:function(e,n,i){if(n){i=i||this;var r=e===S("\n}icz")?"on":S("\x12`qa^vv}v~n");t.each(n,function(n,o){this[e][r](o,t.bind(n,i))},this)}}}),i}(i),i.radio=function(e,t){var n=function(){this._channels={},this.vent={},this.commands={},this.reqres={},this._proxyMethods()};t.extend(n.prototype,{channel:function(e){if(!e)throw new Error(S("\vOeoa~t~3y`ec8k\x7fxythz\0@\x02MEHC"));return this._getChannel(e)},_getChannel:function(t){var n=this._channels[t];return n||(n=new e.Channel(t),this._channels[t]=n),n},_proxyMethods:function(){t.each([S(",[KAD"),S('@"-.)$(#;'),S(",_K^BTA")],function(e){t.each(i[e],function(t){this[e][t]=r(this,e,t)},this)},this)}});var i={vent:["on",S("\x12|rs"),S("2GF\\QP]K"),S("\x19uu\x7fx"),S("5ECWIvROI[Q)/%"),S("\x0f|xagq{Bx"),S("!NJWQCI|FeEOH")],commands:[S(" DZFGPRB"),S("\x12`qa^vv}v~n"),S("\x11av`]wy|u\x7fio"),S(")XNABXJxP\\WXPD"),S("4GSZWO_zPQv^.%.&66")],reqres:[S("\x17j|knynj"),S(".\\UEzRZQZRJ"),S("0BWG|TXST\\HH"),S("\x0fbt\x7f|bp^vv}v~n"),S("\x19h~qrhzaMNkEKBKM[Y")]},r=function(e,n,i){return function(r){var o=e._getChannel(r)[n];return o[i].apply(o,t.rest(arguments))}};return new n}(i,t),e.Wreqr}(t,n);var i=e.Marionette,r=e.Mn,o=t.Marionette={};o.VERSION=S("\x1b.3*1\x17"),o.noConflict=function(){return e.Marionette=i,e.Mn=r,this},t.Marionette=o,o.Deferred=t.$.Deferred,o.extend=t.Model.extend,o.isNodeAttached=function(e){return t.$.contains(document.documentElement,e)},o.mergeOptions=function(e,t){e&&n.extend(this,n.pick(e,t))},o.getOption=function(e,t){if(e&&t)return e.options&&void 0!==e.options[t]?e.options[t]:e[t]},o.proxyGetOption=function(e){return o.getOption(this,e)},o._getValue=function(e,t,i){return n.isFunction(e)&&(e=i?e.apply(t,i):e.call(t)),e},o.normalizeMethods=function(e){return n.reduce(e,function(e,t,i){return n.isFunction(t)||(t=this[t]),t&&(e[i]=t),e},{},this)},o.normalizeUIString=function(e,t){return e.replace(/@ui\.[a-zA-Z-_$0-9]*/g,function(e){return t[e.slice(4)]})},o.normalizeUIKeys=function(e,t){return n.reduce(e,function(e,n,i){var r=o.normalizeUIString(i,t);return e[r]=n,e},{})},o.normalizeUIValues=function(e,t,i){return n.each(e,function(r,s){n.isString(r)?e[s]=o.normalizeUIString(r,t):n.isObject(r)&&n.isArray(i)&&(n.extend(r,o.normalizeUIValues(n.pick(r,i),t)),n.each(i,function(e){var i=r[e];n.isString(i)&&(r[e]=o.normalizeUIString(i,t))}))}),e},o.actAsCollection=function(e,t){var i=[S(")LD^hOLX"),S("A'\"'-"),S("\x18t{k"),S("\rhf~u"),S("\x1e{EUG@P"),S("1TZXASE"),S("+_HBJSE"),S("A0&. %3"),S('"FR@T^'),S("\x1azpq"),S("\x18juvy"),S("(HDR"),S(".F^R^FPP"),S('E%(&=+"">'),S(";USHP+$"),S(">K/\x0001%<"),S("\x18\x7fsioi"),S("6^VPNR]Q"),S("&UMZ^"),S("!NBWQ"),S("\x13c|b\x7fwln"),S("\x11{`Qxfca"),S("B3(0%,")];n.each(i,function(i){e[i]=function(){var e=n.values(n.result(this,t)),r=[e].concat(n.toArray(arguments));return n[i].apply(n,r)}})};var s=o.deprecate=function(e,t){n.isObject(e)&&(e=e.prev+S("\v,d}/w~{}s5bx8{\x7f;nxspVDF\x03MK\x06S@L\nMYY[]U\x1f\x12")+S("7hU_ZOX\x1eJ3$b")+e.next+S("5\x16^VJN^]Y\x10")+(e.url?S("/\x10bWV\x0e\x15")+e.url:"")),void 0!==t&&t||s._cache[e]||(s._warn(S('A\x06&47#$)=#$"m9."?;=3ov')+e),s._cache[e]=!0)};s._console="undefined"!=typeof console?console:{},s._warn=function(){var e=s._console.warn||s._console.log||function(){};return e.apply(s._console,arguments)},s._cache={},o._triggerMethod=function(){function e(e,t,n){return n.toUpperCase()}var t=/(^|:)(\w)/gi;return function(i,r,o){var s=arguments.length<3;s&&(o=r,r=o[0]);var a,l="on"+r.replace(t,e),u=i[l];return n.isFunction(u)&&(a=u.apply(i,s?n.rest(o):o)),n.isFunction(i.trigger)&&(s+o.length>1?i.trigger.apply(i,s?o:[r].concat(n.drop(o,0))):i.trigger(r)),a}}(),o.triggerMethod=function(e){return o._triggerMethod(this,arguments)},o.triggerMethodOn=function(e){var t=n.isFunction(e.triggerMethod)?e.triggerMethod:o.triggerMethod;return t.apply(e,n.rest(arguments))},o.MonitorDOMRefresh=function(e){function t(){e._isShown=!0,i()}function n(){e._isRendered=!0,i()}function i(){e._isShown&&e._isRendered&&o.isNodeAttached(e.el)&&o.triggerMethodOn(e,S("\x0ek\x7f|(aqsdrkq"),e)}e._isDomRefreshMonitored||(e._isDomRefreshMonitored=!0,e.on({show:t,render:n}))},function(e){function t(t,i,r,o){var s=o.split(/\s+/);n.each(s,function(n){var o=t[n];if(!o)throw new e.Error(S("2~QA^X\\\x19\x18")+n+S('-\f\x0fGPA\x13WZXQQ^OIYY\x1e^3a#-d 0"&=j#-#*#5#~s6 "w<6?(|31+@\x04\x1a\n\x17\x11H'));t.listenTo(i,r,o)})}function i(e,t,n,i){e.listenTo(t,n,i)}function r(e,t,i,r){var o=r.split(/\s+/);n.each(o,function(n){var r=e[n];e.stopListening(t,i,r)})}function o(e,t,n,i){e.stopListening(t,n,i)}function s(t,i,r,o,s){if(i&&r){if(!n.isObject(r))throw new e.Error({message:S("*iECJF^VA\x13Y@EC\x18[_\x1b]S\x1eP\"+' 0e)5h/?%/9' >\x7f"),url:S('A/"6,))-=>.b+;!3%;<:&x?,46x1<,6\x0f\x0f\x07\x17\x10\0\x04\x0e\x06\r\x0f\x05\x18\x04\x1a\x16\x15\x07\x17\x1d\0\x06')});r=e._getValue(r,t),n.each(r,function(e,r){n.isFunction(e)?o(t,i,r,e):s(t,i,r,e)})}}e.bindEntityEvents=function(e,n,r){s(e,n,r,i,t)},e.unbindEntityEvents=function(e,t,n){s(e,t,n,o,r)},e.proxyBindEntityEvents=function(t,n){return e.bindEntityEvents(this,t,n)},e.proxyUnbindEntityEvents=function(t,n){return e.unbindEntityEvents(this,t,n)}}(o);var a=[S("9^^O^LV05+,*"),S("1TZXPxVU\\"),S("\x1cqwqEoWNF@T"),S(" OCNA"),S("=SZ32#$!"),"number"];return o.Error=o.extend.call(Error,{urlRoot:S('\x13|abg"65v}owpNDVWAOU\tKFG\x04HBM\\\x1fG')+o.VERSION+"/",constructor:function(e,t){n.isObject(e)?(t=e,e=t.message):t||(t={});var i=Error.call(this,e);n.extend(this,n.pick(i,a),n.pick(t,a)),this.captureStackTrace(),t.url&&(this.url=this.urlRoot+t.url)},captureStackTrace:function(){Error.captureStackTrace&&Error.captureStackTrace(this,o.Error)},toString:function(){return this.name+S("Byd")+this.message+(this.url?S("\x101Avq/6")+this.url:"")}}),o.Error.extend=o.extend,o.Callbacks=function(){this._deferred=o.Deferred(),this._callbacks=[]},n.extend(o.Callbacks.prototype,{add:function(e,t){var i=n.result(this._deferred,S("\x13dgyzqj\x7f"));this._callbacks.push({cb:e,ctx:t}),i.then(function(n){t&&(n.context=t),e.call(n.context,n.options)})},run:function(e,t){this._deferred.resolve({options:e,context:t})},reset:function(){var e=this._callbacks;this._deferred=o.Deferred(),this._callbacks=[],n.each(e,function(e){this.add(e.cb,e.ctx)},this)}}),o.Controller=function(e){this.options=e||{},n.isFunction(this.initialize)&&this.initialize(this.options)},o.Controller.extend=o.extend,n.extend(o.Controller.prototype,t.Events,{destroy:function(){return o._triggerMethod(this,S("\x1b~xxpRD\x18GAVRUGP"),arguments),o._triggerMethod(this,S("@%'007)>"),arguments),this.stopListening(),this.off(),this},triggerMethod:o.triggerMethod,mergeOptions:o.mergeOptions,getOption:o.proxyGetOption}),o.Object=function(e){this.options=n.extend({},n.result(this,S(">P05+,*6")),e),this.initialize.apply(this,arguments)},o.Object.extend=o.extend,n.extend(o.Object.prototype,t.Events,{initialize:function(){},destroy:function(e){return e=e||{},this.triggerMethod(S("5TR^VH^\x06Y[L43-:"),e),this.triggerMethod(S("A&&714(1"),e),this.stopListening(),this},triggerMethod:o.triggerMethod,mergeOptions:o.mergeOptions,getOption:o.proxyGetOption,bindEntityEvents:o.proxyBindEntityEvents,unbindEntityEvents:o.proxyUnbindEntityEvents}),o.Region=o.Object.extend({constructor:function(e){if(this.options=e||{},this.el=this.getOption(S("0T^")),this.el=this.el instanceof t.$?this.el[0]:this.el,!this.el)throw new o.Error({name:S("\x10_}VxPdewk"),message:S("&fF\t\bN@\x0f\x0eBEBF\x13VP\x16DH\\YRZT[[`'-1d$f5-.#$\"c")});this.$el=this.getEl(this.el),o.Object.call(this,e)},show:function(e,t){if(this._ensureElement()){this._ensureViewIsIntact(e),o.MonitorDOMRefresh(e);var i=t||{},r=e!==this.currentView,s=!!i.preventDestroy,a=!!i.forceShow,l=!!this.currentView,u=r&&!s,c=r||a;if(l&&this.triggerMethod(S("+NHH@BT\b@CTFxMM"),this.currentView,this,t),this.currentView&&r&&delete this.currentView._parent,u?this.empty():l&&c&&this.currentView.off(S("\x0ekubfa{l"),this.empty,this),c){e.once(S("6S]JNISD"),this.empty,this),e._parent=this,this._renderView(e),l&&this.triggerMethod(S("\x1fBDDLV@\x1cT_HZ"),e,this,t),this.triggerMethod(S("D'#!';/q?%!8"),e,this,t),o.triggerMethodOn(e,S("7Z\\\\TNX\x04L(.5"),e,this,t),l&&this.triggerMethod(S("\x12`ctfXmm"),this.currentView,this,t);var d=o.isNodeAttached(this.el),f=[],h=n.extend({triggerBeforeAttach:this.triggerBeforeAttach,triggerAttach:this.triggerAttach},i);return d&&h.triggerBeforeAttach&&(f=this._displayedViews(e),this._triggerAttach(f,S('E$".&8.v'))),this.attachHtml(e),this.currentView=e,d&&h.triggerAttach&&(f=this._displayedViews(e),this._triggerAttach(f)),l&&this.triggerMethod(S("\x0e|gpb"),e,this,t),this.triggerMethod(S("\x12`|za"),e,this,t),o.triggerMethodOn(e,S("\f~f`g"),e,this,t),this}return this}},triggerBeforeAttach:!0,triggerAttach:!0,_triggerAttach:function(e,t){var i=(t||"")+S(".NDESP\\");n.each(e,function(e){o.triggerMethodOn(e,i,e,this)},this)},_displayedViews:function(e){return n.union([e],n.result(e,S("\x18F}~hS{lTDFuM@QT"))||[])},_renderView:function(e){e.supportsRenderLifecycle||o.triggerMethodOn(e,S("\niika}u+`vzqse"),e),e.render(),e.supportsRenderLifecycle||o.triggerMethodOn(e,S("\x12aq{rrj"),e)},_ensureElement:function(){if(n.isObject(this.el)||(this.$el=this.getEl(this.el),this.el=this.$el[0]),!this.$el||0===this.$el.length){if(this.getOption(S("*J@AAX}XA@][QrT")))return!1;throw new o.Error(S(")kE\f\x0fKC\x12\x11")+this.$el.selector+S('>\x1f-417d >.;=j""m\n\0\x1d'))}return!0},_ensureViewIsIntact:function(e){if(!e)throw new o.Error({name:S("9lRYJpP4\x17#/-!"),message:S("\n_dh.yyte3dted}}:ro=kqDDDJJ@B\x07IGN\vXEK]UW]AQ\x15_YNXVRX\x13\x1ef/4b.162g8(98l,n994%s=;%#979>|)1\x7f\x13\t\r\x14J")});if(e.isDestroyed)throw new o.Error({name:S("\x16Aq|m_ynjmOXGGaWTHZ"),message:S(",{GJG\x11\x1aP]Q\f\x17\x1a")+e.cid+S(")\b\x02\fEO\\\x10P^AQTRN\x18[_^R\x1dZZ350,= \"g)'.k/, !?%r11u#$==t")})},getEl:function(e){return t.$(e,o._getValue(this.options.parentEl,this))},attachHtml:function(e){this.$el.contents().detach(),this.el.appendChild(e.el)},empty:function(e){var t=this.currentView,n=e||{},i=!!n.preventDestroy;return t?(t.off(S("#@@USZFS"),this.empty,this),this.triggerMethod(S("D'#!';/q) >;)"),t),i||this._destroyView(),this.triggerMethod(S("9_VLIG"),t),delete this.currentView,i&&this.$el.contents().detach(),this):this},_destroyView:function(){var e=this.currentView;e.isDestroyed||(e.supportsDestroyLifecycle||o.triggerMethodOn(e,S("C& (:,p/)>:=?("),e),e.destroy?e.destroy():(e.remove(),e.isDestroyed=!0),e.supportsDestroyLifecycle||o.triggerMethodOn(e,S("6S]JNISD"),e))},attachView:function(e){return this.currentView&&delete this.currentView._parent,e._parent=this,this.currentView=e,this},hasView:function(){return!!this.currentView},reset:function(){return this.empty(),this.$el&&(this.el=this.$el.selector),delete this.$el,this}},{buildRegion:function(e,t){if(n.isString(e))return this._buildRegionFromSelector(e,t);if(e.selector||e.el||e.regionClass)return this._buildRegionFromObject(e,t);if(n.isFunction(e))return this._buildRegionFromRegionClass(e);throw new o.Error({message:S("9sVLOQO%3b1!\"/(&i)$\"+'(%#3'=:8w, *>r"),url:S("\x16zykstrxjkE\x0fPFCLII\x06A^F@\x0e\\JWX]]\x19VYY^P]NN\\JV//o7=5#4")})},_buildRegionFromSelector:function(e,t){return new t({el:e})},_buildRegionFromObject:function(e,t){var i=e.regionClass||t,r=n.omit(e,S("/CT^VWAYE"),S("\x16e}~str^r~SR"));return e.selector&&!r.el&&(r.el=e.selector),new i(r)},_buildRegionFromRegionClass:function(e){return new e}}),o.RegionManager=o.Controller.extend({constructor:function(e){this._regions={},this.length=0,o.Controller.call(this,e),this.addRegions(this.getOption(S("+^HIF__A")))},addRegions:function(e,t){return e=o._getValue(e,this,arguments),n.reduce(e,function(e,i,r){return n.isString(i)&&(i={selector:i}),i.selector&&(i=n.defaults({},i,t)),e[r]=this.addRegion(r,i),e},{},this)},addRegion:function(e,t){var n;return n=t instanceof o.Region?t:o.Region.buildRegion(t,o.Region),this.triggerMethod(S(">]%'-1!\x7f'#,s8.+$!!"),e,n),n._parent=this,this._store(e,n),this.triggerMethod(S("&FLM\x10YIJG@^"),e,n),n},get:function(e){return this._regions[e]},getRegions:function(){return n.clone(this._regions)},removeRegion:function(e){var t=this._regions[e];return this._remove(e,t),t},removeRegions:function(){var e=this.getRegions();return n.each(this._regions,function(e,t){this._remove(t,e)},this),e},emptyRegions:function(){var e=this.getRegions();return n.invoke(e,S("\x0fu|bgm")),e},destroy:function(){return this.removeRegions(),o.Controller.prototype.destroy.apply(this,arguments)},_store:function(e,t){this._regions[e]||this.length++,this._regions[e]=t},_remove:function(e,t){this.triggerMethod(S('E$".&8.v?+"?\'7i&01>77'),e,t),t.empty(),t.stopListening(),delete t._parent,delete this._regions[e],this.length--,this.triggerMethod(S("\v~hc`ft(aqr\x7fxv"),e,t)}}),o.actAsCollection(o.RegionManager.prototype,S('D\x1a4"/ %%?')),o.TemplateCache=function(e){this.templateId=e},n.extend(o.TemplateCache,{templateCaches:{},get:function(e,t){var n=this.templateCaches[e];return n||(n=new o.TemplateCache(e),this.templateCaches[e]=n),n.load(t)},clear:function(){var e,t=n.toArray(arguments),i=t.length;if(i>0)for(e=0;e|!/,,0e4"&-/9l9&*p%7>$97#=y)22>;\x7f\t\x15\x11C\x02\x04\n\x14\rEJ\x05\x19\x01\x02O\x1f\x03R\x06\x1a\x11\x13\x11\x11\x17\x1f\x1fR')});var i=n.isFunction(e)?e:o.TemplateCache.get(e);return i(t)}},o.View=t.View.extend({isDestroyed:!1,supportsRenderLifecycle:!0,supportsDestroyLifecycle:!0,constructor:function(e){this.render=n.bind(this.render,this),e=o._getValue(e,this),this.options=n.extend({},n.result(this,S("\x0e``e{|zf")),e),this._behaviors=o.Behaviors(this),t.View.call(this,this.options),o.MonitorDOMRefresh(this)},getTemplate:function(){return this.getOption(S("#P@KWDH^N"))},serializeModel:function(e){return e.toJSON.apply(e,n.rest(arguments))},mixinTemplateHelpers:function(e){e=e||{};var t=this.getOption(S("'\\LG[@LZJxT^CQGE"));return t=o._getValue(t,this),n.extend(e,t)},normalizeUIKeys:function(e){var t=n.result(this,S("2lA\\t^V]SU[N"));return o.normalizeUIKeys(e,t||n.result(this,S("\vyd")))},normalizeUIValues:function(e,t){var i=n.result(this,S("5C^")),r=n.result(this,S("\x1aDit\\vNEKMCV")); +return o.normalizeUIValues(e,r||i,t)},configureTriggers:function(){if(this.triggers){var e=this.normalizeUIKeys(n.result(this,S("#PWO@OLXX")));return n.reduce(e,function(e,t,n){return e[n]=this._buildViewTrigger(t),e},{},this)}},delegateEvents:function(e){return this._delegateDOMEvents(e),this.bindEntityEvents(this.model,this.getOption(S("\nfcikcUgw}`f"))),this.bindEntityEvents(this.collection,this.getOption(S("#GJJKMJ^BCCkYU_F@"))),n.each(this._behaviors,function(e){e.bindEntityEvents(this.model,e.getOption(S("0\\]WQYsA]WNH"))),e.bindEntityEvents(this.collection,e.getOption(S("3WZZ[]ZNRSS{I%/60")))},this),this},_delegateDOMEvents:function(e){var i=o._getValue(e||this.events,this);i=this.normalizeUIKeys(i),n.isUndefined(e)&&(this.events=i);var r={},s=n.result(this,S("\niieoyy~`Vbpxck"))||{},a=this.configureTriggers(),l=n.result(this,S("\x10sw{uc\x7fxjMhr{z{mS"))||{};n.extend(r,s,i,a,l),t.View.prototype.delegateEvents.call(this,r)},undelegateEvents:function(){return t.View.prototype.undelegateEvents.apply(this,arguments),this.unbindEntityEvents(this.model,this.getOption(S("3YZRRT|L^RIM"))),this.unbindEntityEvents(this.collection,this.getOption(S("\x12p{yzr{mstrXhzNUQ"))),n.each(this._behaviors,function(e){e.unbindEntityEvents(this.model,e.getOption(S("\x13yzrrt\\l~rim"))),e.unbindEntityEvents(this.collection,e.getOption(S("\x17{vvwy~jvOOgUAKRT")))},this),this},_ensureViewIsIntact:function(){if(this.isDestroyed)throw new o.Error({name:S("\x16Aq|m_ynjmOXGGaWTHZ"),message:S(".yYTE\x13\x1cV_S\x02\x19\x18")+this.cid+S('\x1f\x02\b\x02KEV\x06FD[OJHT\x0eMUT\\\x13PPECJVC^X\x1d_Q$a!"*+)3h+/k9>++~')})},destroy:function(){if(this.isDestroyed)return this;var e=n.toArray(arguments);return this.triggerMethod.apply(this,[S("\niika}u+vvgadxa")].concat(e)),this.isDestroyed=!0,this.triggerMethod.apply(this,[S("3PPECJVC")].concat(e)),this.unbindUIElements(),this.isRendered=!1,this.remove(),n.invoke(this._behaviors,S('"GAVRUGP'),e),this},bindUIElements:function(){this._bindUIElements(),n.invoke(this._behaviors,this._bindUIElements)},_bindUIElements:function(){if(this.ui){this._uiBindings||(this._uiBindings=this.ui);var e=n.result(this,S("*tYDlF^U[]SF"));this.ui={},n.each(e,function(e,t){this.ui[t]=this.$(e)},this)}},unbindUIElements:function(){this._unbindUIElements(),n.invoke(this._behaviors,this._unbindUIElements)},_unbindUIElements:function(){this.ui&&this._uiBindings&&(n.each(this.ui,function(e,t){delete this.ui[t]},this),this.ui=this._uiBindings,delete this._uiBindings)},_buildViewTrigger:function(e){var t=n.defaults({},e,{preventDefault:!0,stopPropagation:!0}),i=n.isObject(e)?t.event:e;return function(e){e&&(e.preventDefault&&t.preventDefault&&e.preventDefault(),e.stopPropagation&&t.stopPropagation&&e.stopPropagation());var n={view:this,model:this.model,collection:this.collection};this.triggerMethod(i,n)}},setElement:function(){var e=t.View.prototype.setElement.apply(this,arguments);return n.invoke(this._behaviors,S("+\\_AWIg[VCeDXH\\HOUXM"),this),e},triggerMethod:function(){var e=o._triggerMethod(this,arguments);return this._triggerEventOnBehaviors(arguments),this._triggerEventOnParentLayout(arguments[0],n.rest(arguments)),e},_triggerEventOnBehaviors:function(e){for(var t=o._triggerMethod,n=this._behaviors,i=0,r=n&&n.length;i'),message:S("\x1d]~NOMW\x04WCILLX\vXEK\x0fDT_CXTBR\x18JSU_X\x1eV4a+0d+3+$i%9l8 +57;=11x")});var t=this.mixinTemplateHelpers(this.serializeData()),n=o.Renderer.render(e,t,this);return this.attachElContent(n),this}},attachElContent:function(e){return this.$el.html(e),this}}),o.CollectionView=o.View.extend({childViewEventPrefix:S("+OEGCTG[VC"),sort:!0,constructor:function(e){this.once(S("\v~h`kuc"),this._initialEvents),this._initChildViewStorage(),o.View.apply(this,arguments),this.on({"before:show":this._onBeforeShowCalled,show:this._onShowCalled,"before:attach":this._onBeforeAttachCalled,attach:this._onAttachCalled}),this.initRenderBuffer()},initRenderBuffer:function(){this._bufferedChildren=[]},startBuffering:function(){this.initRenderBuffer(),this.isBuffering=!0},endBuffering:function(){var e,t=this._isShown&&o.isNodeAttached(this.el);this.isBuffering=!1,this._isShown&&this._triggerMethodMany(this._bufferedChildren,this,S("7Z\\\\TNX\x04L(.5")),t&&this._triggerBeforeAttach&&(e=this._getNestedViews(),this._triggerMethodMany(e,this,S("3VPPXJ\\\0ZHI_\\("))),this.attachBuffer(this,this._createBuffer()),t&&this._triggerAttach&&(e=this._getNestedViews(),this._triggerMethodMany(e,this,S("\njxyolx"))),this._isShown&&this._triggerMethodMany(this._bufferedChildren,this,S("$VNH_")),this.initRenderBuffer()},_triggerMethodMany:function(e,t,i){var r=n.drop(arguments,3);n.each(e,function(e){o.triggerMethodOn.apply(e,[e,i,e,t].concat(r))})},_initialEvents:function(){this.collection&&(this.listenTo(this.collection,S(",LJK"),this._onCollectionAdd),this.listenTo(this.collection,S("([OFC[K"),this._onCollectionRemove),this.listenTo(this.collection,S("=LZ3$6"),this.render),this.getOption(S("\r}`be"))&&this.listenTo(this.collection,S("1A\\FA"),this._sortViews))},_onCollectionAdd:function(e,t,i){var r=void 0!==i.at&&(i.index||t.indexOf(e));if((this.getOption(S('B%-)2":'))||r===!1)&&(r=n.indexOf(this._filteredSortedModels(r),e)),this._shouldAddChild(e,r)){this.destroyEmptyView();var o=this.getChildView(e);this.addChild(e,o,r)}},_onCollectionRemove:function(e){var t=this.children.findByModel(e);this.removeChildView(t),this.checkEmpty()},_onBeforeShowCalled:function(){this._triggerBeforeAttach=this._triggerAttach=!1,this.children.each(function(e){o.triggerMethodOn(e,S("\x16u}\x7fuiy'mwOV"),e)})},_onShowCalled:function(){this.children.each(function(e){o.triggerMethodOn(e,S(",^F@G"),e)})},_onBeforeAttachCalled:function(){this._triggerBeforeAttach=!0},_onAttachCalled:function(){this._triggerAttach=!0},render:function(){return this._ensureViewIsIntact(),this.triggerMethod(S(';^XXP2$x1!+"":'),this),this._renderChildren(),this.isRendered=!0,this.triggerMethod(S("\x1bnxp{ES"),this),this},reorder:function(){var e=this.children,t=this._filteredSortedModels();if(!t.length&&this._showingEmptyView)return this;var i=n.some(t,function(t){return!e.findByModel(t)});if(i)this.render();else{var r=n.map(t,function(t,n){var i=e.findByModel(t);return i._index=n,i.el}),o=e.filter(function(e){return!n.contains(r,e.el)});this.triggerMethod(S("%DBNFXN\x16_K@BUWA")),this._appendReorderedChildren(r),n.each(o,this.removeChildView,this),this.checkEmpty(),this.triggerMethod(S("@3',6!#5"))}},resortView:function(){o.getOption(this,S("\r|j\x7fcvvfZxDwkn"))?this.reorder():this.render()},_sortViews:function(){var e=this._filteredSortedModels(),t=n.find(e,function(e,t){var n=this.children.findByModel(e);return!n||n._index!==t},this);t&&this.resortView()},_emptyViewIndex:-1,_appendReorderedChildren:function(e){this.$el.append(e)},_renderChildren:function(){this.destroyEmptyView(),this.destroyChildren({checkEmpty:!1}),this.isEmpty(this.collection)?this.showEmptyView():(this.triggerMethod(S("\x18{\x7f}so{%RDLGAW\x1cDGEFNOYG@^"),this),this.startBuffering(),this.showCollection(),this.endBuffering(),this.triggerMethod(S("\x18k\x7fuxxl%CNNOAFRNGG"),this),this.children.isEmpty()&&this.getOption(S("\vjdb{uc"))&&this.showEmptyView())},showCollection:function(){var e,t=this._filteredSortedModels();n.each(t,function(t,n){e=this.getChildView(t),this.addChild(t,e,n)},this)},_filteredSortedModels:function(e){var t=this.getViewComparator(),i=this.collection.models;if(e=Math.min(Math.max(e,0),i.length-1),t){var r;e&&(r=i[e],i=i.slice(0,e).concat(i.slice(e+1))),i=this._sortModelsBy(i,t),r&&i.splice(e,0,r)}return this.getOption(S("\x10w{\x7f`pd"))&&(i=n.filter(i,function(e,t){return this._shouldAddChild(e,t)},this)),i},_sortModelsBy:function(e,t){return"string"==typeof t?n.sortBy(e,function(e){return e.get(t)},this):1===t.length?n.sortBy(e,t,this):e.sort(n.bind(t,this))},showEmptyView:function(){var e=this.getEmptyView();if(e&&!this._showingEmptyView){this.triggerMethod(S("\x14wsqwk\x7f!nxp{ES\x18FIUR^")),this._showingEmptyView=!0;var n=new t.Model;this.addEmptyView(n,e),this.triggerMethod(S("5DRV]_I\x06XSO48"))}},destroyEmptyView:function(){this._showingEmptyView&&(this.triggerMethod(S("\x17z||tnx$mELMUA\x1fCJX]S")),this.destroyChildren(),delete this._showingEmptyView,this.triggerMethod(S("%TBEF\\N\x16HC_DH")))},getEmptyView:function(){return this.getOption(S("\x11w~daoAq|m"))},addEmptyView:function(e,t){var i,r=this._isShown&&!this.isBuffering&&o.isNodeAttached(this.el),s=this.getOption(S("D +7<0\x1c\"):\x01?$8=='"))||this.getOption(S(".LXX^Wb\\S@wINRSSM"));n.isFunction(s)&&(s=s.call(this,e,this._emptyViewIndex));var a=this.buildChildView(e,t,s);a._parent=this,this.proxyChildEvents(a),a.once(S("\x18k\x7fuxxl"),function(){this._isShown&&o.triggerMethodOn(a,S("%DBNFXN\x16^F@G"),a),r&&this._triggerBeforeAttach&&(i=this._getViewAndNested(a),this._triggerMethodMany(i,this,S("4WSQWK_\x01]IJ^#)")))},this),this.children.add(a),this.renderChildView(a,this._emptyViewIndex),r&&this._triggerAttach&&(i=this._getViewAndNested(a),this._triggerMethodMany(i,this,S("\x1c|jkABJ"))),this._isShown&&o.triggerMethodOn(a,S("\nxdby"),a)},getChildView:function(e){var t=this.getOption(S("\x11q{}yrAq|m"));if(!t)throw new o.Error({name:S("*eCnFF\\UdZQBsEJVH"),message:S('<|\x1e\x1d#)+/ \x13/"?kj&9>:o24r $05>>0??')});return t},addChild:function(e,t,n){var i=this.getOption(S("\rmgy}vE}paXhmstrn"));i=o._getValue(i,this,[e,n]);var r=this.buildChildView(e,t,i);return this._updateIndices(r,!0,n),this.triggerMethod(S("&EMOEYI\x17OKT\vQ[]YR"),r),this._addChildView(r,n),this.triggerMethod(S("/QUV\tW]_[\\"),r),r._parent=this,r},_updateIndices:function(e,t,n){this.getOption(S(">L/36"))&&(t&&(e._index=n),this.children.each(function(n){n._index>=e._index&&(n._index+=t?1:-1)}))},_addChildView:function(e,t){var n,i=this._isShown&&!this.isBuffering&&o.isNodeAttached(this.el);this.proxyChildEvents(e),e.once(S("&UMGNN^"),function(){this._isShown&&!this.isBuffering&&o.triggerMethodOn(e,S("=\\Z&.0&~6.(?"),e),i&&this._triggerBeforeAttach&&(n=this._getViewAndNested(e),this._triggerMethodMany(n,this,S(":YY[QM%{#70$%/")))},this),this.children.add(e),this.renderChildView(e,t),i&&this._triggerAttach&&(n=this._getViewAndNested(e),this._triggerMethodMany(n,this,S("\x1c|jkABJ"))),this._isShown&&!this.isBuffering&&o.triggerMethodOn(e,S("\x1dmwOV"),e)},renderChildView:function(e,t){return e.supportsRenderLifecycle||o.triggerMethodOn(e,S("\x12qqsye}#h~ry{m"),e),e.render(),e.supportsRenderLifecycle||o.triggerMethodOn(e,S("\x13fpxs}k"),e),this.attachHtml(this,e,t),e},buildChildView:function(e,t,i){var r=n.extend({model:e},i),s=new t(r);return o.MonitorDOMRefresh(s),s},removeChildView:function(e){return e?(this.triggerMethod(S("#F@@HZL\x10YI@AYU\vQ[]YR"),e),e.supportsDestroyLifecycle||o.triggerMethodOn(e,S("\x18{\x7f}so{%DDQWVJ_"),e),e.destroy?e.destroy():e.remove(),e.supportsDestroyLifecycle||o.triggerMethodOn(e,S("\x13ppecjvc"),e),delete e._parent,this.stopListening(e),this.children.remove(e),this.triggerMethod(S("2AQXYA]\x03YSUQZ"),e),this._updateIndices(e,!1),e):e},isEmpty:function(){return!this.collection||0===this.collection.length},checkEmpty:function(){this.isEmpty(this.collection)&&this.showEmptyView()},attachBuffer:function(e,t){e.$el.append(t)},_createBuffer:function(){var e=document.createDocumentFragment();return n.each(this._bufferedChildren,function(t){e.appendChild(t.el)}),e},attachHtml:function(e,t,n){e.isBuffering?e._bufferedChildren.splice(n,0,t):e._insertBefore(t,n)||e._insertAfter(t)},_insertBefore:function(e,t){var n,i=this.getOption(S("\r}`be"))&&t\x1b>((&("));this.listenTo(e,S("\x1azpq"),function(){var i=n.toArray(arguments),r=i[0],o=this.normalizeMethods(n.result(this,S("'KACGHhXJ^EA")));i[0]=t+":"+r,i.splice(1,0,e),"undefined"!=typeof o&&n.isFunction(o[r])&&o[r].apply(this,i.slice(1)),this.triggerMethod.apply(this,i)})},_getImmediateChildren:function(){return n.values(this.children._views)},_getViewAndNested:function(e){return[e].concat(n.result(e,S("/oVWGzPEC]]lRYJM"))||[])},getViewComparator:function(){return this.getOption(S("(_CN[nAB@P@R@ZD"))}}),o.CompositeView=o.CollectionView.extend({constructor:function(){o.CollectionView.apply(this,arguments)},_initialEvents:function(){this.collection&&(this.listenTo(this.collection,S("=_[$"),this._onCollectionAdd),this.listenTo(this.collection,S("\x16e}tumy"),this._onCollectionRemove),this.listenTo(this.collection,S("\x1co{lEU"),this._renderChildren),this.getOption(S("A1,61"))&&this.listenTo(this.collection,S("\x18juih"),this._sortViews))},getChildView:function(e){var t=this.getOption(S("7[QSWXkWZ7"))||this.constructor;return t},serializeData:function(){var e={};return this.model&&(e=n.partial(this.serializeModel,this.model).apply(this,arguments)),e},render:function(){return this._ensureViewIsIntact(),this._isRendering=!0,this.resetChildViewContainer(),this.triggerMethod(S("\x1e}EGMQA\x1fTBFMOY"),this),this._renderTemplate(),this._renderChildren(),this._isRendering=!1,this.isRendered=!0,this.triggerMethod(S("=LZ.%'1"),this),this},_renderChildren:function(){(this.isRendered||this._isRendering)&&o.CollectionView.prototype._renderChildren.call(this)},_renderTemplate:function(){var e={};e=this.serializeData(),e=this.mixinTemplateHelpers(e),this.triggerMethod(S("\x1ayy{qmE\x1bPFJACU\x12]OF\\AO[U"));var t=this.getTemplate(),n=o.Renderer.render(t,e,this);this.attachElContent(n),this.bindUIElements(),this.triggerMethod(S("\x0e}u\x7fvvf/bruivzhx"))},attachElContent:function(e){return this.$el.html(e),this},attachBuffer:function(e,t){var n=this.getChildViewContainer(e);n.append(t)},_insertAfter:function(e){var t=this.getChildViewContainer(this,e);t.append(e.el)},_appendReorderedChildren:function(e){var t=this.getChildViewContainer(this);t.append(e)},getChildViewContainer:function(e,t){if(e.$childViewContainer)return e.$childViewContainer;var n,i=o.getOption(e,S("\x1d}wIMFuM@QdGG^JECK]"));if(i){var r=o._getValue(i,e);if(n="@"===r.charAt(0)&&e.ui?e.ui[r.substr(4)]:e.$(r),n.length<=0)throw new o.Error({name:S("\x0eLxx~wB|s`[vto}tpzRlKPWLH@m[XD^"),message:S('9nSY\x1dMO%"+%- "gj*"" )\x18&5&\x11<:!7>6<(y|*?,@\x0f\r\x17D\x03\t\x12\x06\rPK')+e.childViewContainer})}else n=e.$el;return e.$childViewContainer=n,n},resetChildViewContainer:function(){this.$childViewContainer&&(this.$childViewContainer=void 0)}}),o.LayoutView=o.ItemView.extend({regionClass:o.Region,options:{destroyImmediate:!1},childViewEventPrefix:S("#GMOKL_CN["),constructor:function(e){e=e||{},this._firstRender=!0,this._initializeRegions(e),o.ItemView.call(this,e)},render:function(){return this._ensureViewIsIntact(),this._firstRender?this._firstRender=!1:this._reInitializeRegions(),o.ItemView.prototype.render.apply(this,arguments)},destroy:function(){return this.isDestroyed?this:(this.getOption(S("%BB[]XDUdCBUU[R@P"))===!0&&this.$el.remove(),this.regionManager.destroy(),o.ItemView.prototype.destroy.apply(this,arguments))},showChildView:function(e,t,i){var r=this.getRegion(e);return r.show.apply(r,n.rest(arguments))},getChildView:function(e){return this.getRegion(e).currentView},addRegion:function(e,t){var n={};return n[e]=t,this._buildRegions(n)[e]},addRegions:function(e){return this.regions=n.extend({},this.regions,e),this._buildRegions(e)},removeRegion:function(e){return delete this.regions[e],this.regionManager.removeRegion(e)},getRegion:function(e){return this.regionManager.get(e)},getRegions:function(){return this.regionManager.getRegions()},_buildRegions:function(e){var t={regionClass:this.getOption(S("5DR_PUU\x7fQ_L3")),parentEl:n.partial(n.result,this,S("4PZ"))};return this.regionManager.addRegions(e,t)},_initializeRegions:function(e){var t;this._initRegionManager(),t=o._getValue(this.regions,this,[e])||{};var i=this.getOption.call(e,S(",_KHY^\\@"));i=o._getValue(i,this,[e]),n.extend(t,i),t=this.normalizeUIValues(t,[S("\x11avxpucwk"),S("@$.")]),this.addRegions(t)},_reInitializeRegions:function(){this.regionManager.invoke(S("@3'0!1"))},getRegionManager:function(){return new o.RegionManager},_initRegionManager:function(){this.regionManager=this.getRegionManager(),this.regionManager._parent=this,this.listenTo(this.regionManager,S("@#'%+7#})-.q>()&??"),function(e){this.triggerMethod(S(" CGEKWC\x1dIMN\x11^HIF__"),e)}),this.listenTo(this.regionManager,S("3UQR\rJ\\]RSS"),function(e,t){this[e]=t,this.triggerMethod(S('C%!"}:,-"##'),e,t)}),this.listenTo(this.regionManager,S("<_[Y/3'y6 +(>,p9)*' >"),function(e){this.triggerMethod(S("\x10swu{gs-j|wtjx$mEFKLJ"),e)}),this.listenTo(this.regionManager,S("9H^QRHZz3'$-*("),function(e,t){delete this[e],this.triggerMethod(S("\nyi`ayu+`vs|yy"),e,t)})},_getImmediateChildren:function(){return n.chain(this.regionManager.getRegions()).pluck(S("D&35:,$?\x1a$+8")).compact().value()}}),o.Behavior=o.Object.extend({constructor:function(e,t){this.view=t,this.defaults=n.result(this,S("C &=%>8"))||{},this.options=n.extend({},this.defaults,e),this.ui=n.extend({},n.result(t,S("%SN")),n.result(this,S("']@"))),o.Object.apply(this,arguments)},$:function(){return this.view.$.apply(this.view,arguments)},destroy:function(){return this.stopListening(),this},proxyViewProperties:function(e){this.$el=e.$el,this.el=e.el}}),o.Behaviors=function(e,t){function n(e,i){return t.isObject(e.behaviors)?(i=n.parseBehaviors(e,i||t.result(e,S("\x16u}q{murll"))),n.wrap(e,i,t.keys(s)),i):{}}function i(e,t){this._view=e,this._behaviors=t,this._triggers={}}function r(e){return e._uiBindings||e.ui}var o=/^(\S+)\s*(.*)$/,s={behaviorTriggers:function(e,t){var n=new i(this,t);return n.buildBehaviorTriggers()},behaviorEvents:function(n,i){var s={};return t.each(i,function(n,i){var a={},l=t.clone(t.result(n,S("3QCSYLJ")))||{};l=e.normalizeUIKeys(l,r(n));var u=0;t.each(l,function(e,r){var s=r.match(o),l=s[1]+"."+[this.cid,i,u++," "].join(""),c=s[2],d=l+c,f=t.isFunction(e)?e:n[e];f&&(a[d]=t.bind(f,n))},this),s=t.extend(s,a)},this),s}};return t.extend(n,{behaviorsLookup:function(){throw new e.Error({message:S("B\x1a+0f*=:>k(((&>4r$<0$2x 5..}<:\b\0\x14\n\v\x17\x15G\t\x1b\x0fK\x1f\x19\x01\x1d\x15\x15\\"),url:S("$HGUAFDNXYK\x01RTZRB\\YEK\x17ROQQ\x1d]%)#5-*44$&% 9=")})},getBehaviorClass:function(t,i){return t.behaviorClass?t.behaviorClass:e._getValue(n.behaviorsLookup,this,[t,i])[i]},parseBehaviors:function(e,i){return t.chain(i).map(function(i,r){var o=n.getBehaviorClass(i,r),s=new o(i,e),a=n.parseBehaviors(e,t.result(s,S(".MUYSE]ZDD")));return[s].concat(a)}).flatten().value()},wrap:function(e,n,i){t.each(i,function(i){e[i]=t.partial(s[i],e[i],n)})}}),t.extend(i.prototype,{buildBehaviorTriggers:function(){return t.each(this._behaviors,this._buildTriggerHandlersForBehavior,this),this._triggers},_buildTriggerHandlersForBehavior:function(n,i){var o=t.clone(t.result(n,S("\x16cjp}|yom")))||{};o=e.normalizeUIKeys(o,r(n)),t.each(o,t.bind(this._setHandlerForBehavior,this,n,i))},_setHandlerForBehavior:function(e,t,n,i){var r=i.replace(/^\S+/,function(e){return e+"."+S("*IIEOYY^@GF\\QP]KI")+t});this._triggers[r]=this._view._buildViewTrigger(n)}}),n}(o,n),o.AppRouter=t.Router.extend({constructor:function(e){this.options=e||{},t.Router.apply(this,arguments);var n=this.getOption(S(":ZLMlP55'0")),i=this._getController();this.processAppRoutes(i,n),this.on(S("\x19htii{"),this._processOnRoute,this)},appRoute:function(e,t){var n=this._getController();this._addAppRoute(n,e,t)},_processOnRoute:function(e,t){if(n.isFunction(this.onRoute)){var i=n.invert(this.getOption(S("@ 23\x16*33-:")))[e];this.onRoute(e,i,t)}},processAppRoutes:function(e,t){if(t){var i=n.keys(t).reverse();n.each(i,function(n){this._addAppRoute(e,n,t[n])},this)}},_getController:function(){return this.getOption(S("\rm`~e`|xyse"))},_addAppRoute:function(e,t,i){var r=e[i];if(!r)throw new o.Error(S('"nAQNHL\t\b')+i+S('2\x11\x14BWD\x18WUO\x1c[QJ.%b,*e2/-i)$"9< <=7!'));this.route(t,i,n.bind(r,e))},mergeOptions:o.mergeOptions,getOption:o.proxyGetOption,triggerMethod:o.triggerMethod,bindEntityEvents:o.proxyBindEntityEvents,unbindEntityEvents:o.proxyUnbindEntityEvents}),o.Application=o.Object.extend({constructor:function(e){this._initializeRegions(e),this._initCallbacks=new o.Callbacks,this.submodules={},n.extend(this,e),this._initChannel(),o.Object.apply(this,arguments)},execute:function(){this.commands.execute.apply(this.commands,arguments)},request:function(){return this.reqres.request.apply(this.reqres,arguments)},addInitializer:function(e){this._initCallbacks.add(e)},start:function(e){this.triggerMethod(S("<_[Y/3'y71'5<"),e),this._initCallbacks.run(e,this),this.triggerMethod(S(",^ZNBE"),e)},addRegions:function(e){return this._regionManager.addRegions(e)},emptyRegions:function(){return this._regionManager.emptyRegions()},removeRegion:function(e){return this._regionManager.removeRegion(e)},getRegion:function(e){return this._regionManager.get(e)},getRegions:function(){return this._regionManager.getRegions()},module:function(e,t){var i=o.Module.getClass(t),r=n.toArray(arguments);return r.unshift(this),i.create.apply(i,r)},getRegionManager:function(){return new o.RegionManager},_initializeRegions:function(e){var t=n.isFunction(this.regions)?this.regions(e):this.regions||{};this._initRegionManager();var i=o.getOption(e,S("%TBO@EE_"));return n.isFunction(i)&&(i=i.call(this,e)),n.extend(t,i),this.addRegions(t),this},_initRegionManager:function(){this._regionManager=this.getRegionManager(),this._regionManager._parent=this,this.listenTo(this._regionManager,S("\x14wsqwk\x7f!}yz%RDEJKK"),function(){o._triggerMethod(this,S("'JLLD^H\x14NTU\bAQR_XV"),arguments)}),this.listenTo(this._regionManager,S("1SWP\x0fDR_PUU"),function(e,t){this[e]=t,o._triggerMethod(this,S('D$"#r;/,%" '),arguments)}),this.listenTo(this._regionManager,S("\x14wsqwk\x7f!nxspVD\x18QABOHF"),function(){o._triggerMethod(this,S('B!!#)5-s8.!"8*j#74=:8'),arguments)}),this.listenTo(this._regionManager,S("1@VYZ@R\x02K_\\URP"),function(e){delete this[e],o._triggerMethod(this,S("\x12aqxya}#h~{tqq"),arguments)})},_initChannel:function(){this.channelName=n.result(this,S(")ICMC@J\\\x7fS^Q"))||S("=YS/##/"),this.channel=n.result(this,S("\x12p|txy}u"))||t.Wreqr.radio.channel(this.channelName),this.vent=n.result(this,S("\f{kad"))||this.channel.vent,this.commands=n.result(this,S("#GJKJIGNX"))||this.channel.commands,this.reqres=n.result(this,S("\x15drik\x7fh"))||this.channel.reqres}}),o.Module=function(e,t,i){this.moduleName=e,this.options=n.extend({},this.options,i),this.initialize=i.initialize||this.initialize,this.submodules={},this._setupInitializersAndFinalizers(),this.app=t,n.isFunction(this.initialize)&&this.initialize(e,t,this.options)},o.Module.extend=o.extend,n.extend(o.Module.prototype,t.Events,{startWithParent:!0,initialize:function(){},addInitializer:function(e){this._initializerCallbacks.add(e)},addFinalizer:function(e){this._finalizerCallbacks.add(e)},start:function(e){this._isInitialized||(n.each(this.submodules,function(t){t.startWithParent&&t.start(e)}),this.triggerMethod(S("2QQSYE]\x03IO]OJ"),e),this._initializerCallbacks.run(e,this),this._isInitialized=!0,this.triggerMethod(S("/im,c=/]*>\s*([\s\S]+)\s*<\/body>/im,d="undefined"!=typeof location&&location.href,f=d&&location.protocol&&location.protocol.replace(/\:/,""),h=d&&location.hostname,g=d&&(location.port||void 0),p={},v=e.config&&e.config()||{};return i={version:S("\x1b.3.1\x11\x14"),strip:function(e){if(e){e=e.replace(u,"");var t=e.match(c);t&&(e=t[1])}else e="";return e},jsEscape:function(e){return e.replace(/(['\\])/g,S("%z\x03\x19")).replace(/[\f]/g,S("!~E")).replace(/[\b]/g,S("\x0eSr")).replace(/[\n]/g,S(">c.")).replace(/[\t]/g,S(")v_")).replace(/[\r]/g,S("?\x1c3")).replace(/[\u2028]/g,S(">c5srq|")).replace(/[\u2029]/g,S("\x16Km+*)%"))},createXhr:v.createXhr||function(){var e,t,n;if("undefined"!=typeof XMLHttpRequest)return new XMLHttpRequest;if("undefined"!=typeof ActiveXObject)for(t=0;t<3;t+=1){n=l[t];try{e=new ActiveXObject(n)}catch(e){}if(e){l=[n];break}}return e},parseName:function(e){var t,n,i,r=!1,o=e.lastIndexOf("."),s=0===e.indexOf(S("7\x16\x16"))||0===e.indexOf(S("/\x1e\x1f\x1d"));return o!==-1&&(!s||o>1)?(t=e.substring(0,o),n=e.substring(o+1)):t=e,i=n||t,o=i.indexOf("!"),o!==-1&&(r=i.substring(o+1)===S("*XX_G_"),i=i.substring(0,o),n?n=i:t=i),{moduleName:t,ext:n,strip:r}},xdRegExp:/^((\w+)\:)?\/\/([^\/\\]+)/,useXhr:function(e,t,r,o){var s,a,l,u=i.xdRegExp.exec(e);return!u||(s=u[2],a=u[3],a=a.split(":"),l=a[1],a=a[0],(!s||s===t)&&(!a||a.toLowerCase()===r.toLowerCase())&&(!l&&!a||n(s,l,t,o)))},finishLoad:function(e,t,n,r){n=t?i.strip(n):n,v.isBuild&&(p[e]=n),r(n)},load:function(e,t,n,r){if(r&&r.isBuild&&!r.inlineText)return void n();v.isBuild=r&&r.isBuild;var o=i.parseName(e),s=o.moduleName+(o.ext?"."+o.ext:""),a=t.toUrl(s),l=v.useXhr||i.useXhr;return 0===a.indexOf(S("\x1fELRW]\x1f"))?void n():void(!d||l(a,f,h,g)?i.get(a,function(t){i.finishLoad(e,o.strip,t,n)},function(e){n.error&&n.error(e)}):t([s],function(e){i.finishLoad(o.moduleName+"."+o.ext,o.strip,e,n)}))},write:function(e,t,n,r){if(p.hasOwnProperty(t)){var o=i.jsEscape(p[t]);n.asModule(e+"!"+t,S('1VVR\\XR\x10_OU_IWP.ajjd>f5-=?9"mi')+o+S("Cc~;nsC"))}},writeFile:function(e,t,n,r,o){var s=i.parseName(t),a=s.ext?"."+s.ext:"",l=s.moduleName+a,u=n.toUrl(s.moduleName+a)+".js";i.load(l,n,function(t){var n=function(e){return r(u,e)};n.asModule=function(e,t){return r.asModule(e,u,t)},i.write(e,l,n,o)},o)}},v.env===S("\x13zzrr")||!v.env&&"undefined"!=typeof process&&process.versions&&process.versions.node&&!process.versions[S("\fcaku399&&r<600?(o=new Error(e+S(':\x1btijo`26"005}h')+r),o.xhr=s,n&&n(o)):t(s.responseText),v.onXhrComplete&&v.onXhrComplete(s,e))},s.send(null)}:v.env===S(">M((,,")||!v.env&&"undefined"!=typeof Packages&&"undefined"!=typeof java?i.get=function(e,t){var n,i,r=S("\x1ejTG\x0f\x1b"),o=new java.io.File(e),s=java.lang.System.getProperty(S("\x14y\x7fy}7i~l|l~TNP")),a=new java.io.BufferedReader(new java.io.InputStreamReader(new java.io.FileInputStream(o),r)),l="";try{for(n=new java.lang.StringBuffer,i=a.readLine(),i&&i.length()&&65279===i.charAt(0)&&(i=i.substring(1)),null!==i&&n.append(i);null!==(i=a.readLine());)n.append(s),n.append(i);l=String(n.toString())}finally{a.close()}t(l)}:(v.env===S("\x1bdm}pNOG@P")||!v.env&&"undefined"!=typeof Components&&Components.classes&&Components.interfaces)&&(o=Components.classes,s=Components.interfaces,Components.utils[S("\x16~uiuih")](S(")XN_B[]ST\b\x1c\x1bRDR\x17TU_IQ[Lo\x07+/!\x102.$:d!? ")),a=S("\fMc`jx~\x7fu;ye\x7f6mrryqhS\fPFCLUSZP\x07@IT\x15\x1e")in o,i.get=function(e,t){var n,i,r,l={};a&&(e=e.replace(/\//g,"\\")),r=new FileUtils.File(e);try{n=o[S("8yWTFTRS!o-1#j(\"<>%9'b(&<4\x7f::%##u*.)9<3dQ")].createInstance(s.nsIFileInputStream),n.init(r,1,0,!1),i=o[S('.o]^HZXYW\x19WK]\x14USJSo"--2 43-;g""=;;}"&!14;li')].createInstance(s.nsIConverterInputStream),i.init(n,S("cukua%{zi{cj!ig|qs~vp(4cjl\x7f9gf!b]\x01FBPD\vDCO\x07EM@K\x12\x12JI\x0e\x14\\B\x19VXW^\x1c@C\x1d`:9|d,2i$ $ \r9:=93''1&v*%\"!%|4*q\f\b\f\b%\x11\x12\x15\x01\v\x1f\x1f\t\x1eNU\x11\x05\x06\x01\x1d\x17\x03\x03\x1d\x04\x07\0\x07@\x1f\vtskaqqc)fhgnqp3-kj/r`ad~zln~2k\x7fsUD_^\x06^]YUTQP\x13PS\x11:8;HO\b\x16^L\x17VZ^XR\x1f=\0\x0f\x1c"),[S("\r{att``wzdr"),S(".EADWAM"),S("$fmaAGNN^\x02xFUFA\x1cvTER\x17zUVLRMV4$\x14*!2"),S("<~uy)/&&6j\x10.->9d\x0e,=*\x7f\x18&69\x03?2/"),S("\x1bhxfk\x01bieMKBBZ\x06~NA]BNDTA\x1cwZXC]ANvYSK\x10\x03.,7!=2\n-'?\x028(#a4>&"),S("(jamECJJB\x1egG]Y\x19|]@yTXX")],function(e,t,n,i,r,o){"use strict";function s(e,t){var n=e.x,i=e.y,r=t.height(),o=t.width();return{x:parseInt(n+(window.innerWidth=0?l:r.length-1].focus()),u.keyCode===o.down&&(u.stopPropagation(),u.preventDefault(),r=a.$el.find("a").not(S(".\x01EX\x1f@@TBR\x15]SH]_RZ$")),s=e.indexOf(r,t.$el.find("a").get(0)),l=s+1,r[l<=r.length-1?l:0].focus()),u.keyCode!==o.enter&&u.keyCode!==o.space||(a.destroy(),t.model.get(S("D,5\x06+=#=)"))&&i(n)),u.keyCode===o.escape&&(u.stopPropagation(),u.preventDefault(),a.destroy())})},getChildView:function(e){var t={contextmenu:function(e){e.preventDefault(),e.stopPropagation()}};e.get(S("(MC]EIK]"))||(t[S("\x15u{qzq;}")]=function(e){this.trigger(S("\x15\x7fc}tywu~uzD"),{evt:e,view:this,model:this.model})},t[S("\x1duzYEMTJ\x05G")]=function(e){this.trigger(S("8PN^QV[F$.5-"),{evt:e,view:this,model:this.model})});var n={name:S("0r]]@PNCu\\TNuI[R"),finder:this.finder,template:r,events:t,tagName:S("!NJ"),modelEvents:{"change:active":S("\x0fbt|wqg")}};return e.get(S("\x0ftxdzppd"))&&(n.attributes={"data-role":S("4Y_DL\x14^RJTZZ2")}),i.extend(n)}});return a}),CKFinder.define(S("\x1b_VXvNEGQ\vhIC]EOX\x03nAADTJGyPXB\x17zUUHXFK\r$,6"),[S("']GNN^^M@BT"),S(")HJOFL@^T"),S("7{r|RRY[Mo\f-'1)#4g\n%%8(6;\x1d4<&{\x03?2/*u\x1833*:\x18\x15/\x06\n\x100\x0e\r\x1e")],function(e,t,n){"use strict";function i(e){function t(){n.lastView&&n.lastView.destroy()}this.finder=e,e.setHandler(S("\x13wzxc}anVysk"),r,this);var n=this;e.on(S(" TK\x19FISU"),t),e.on(S("+YD\x14]UB[IQ"),t),e.on(S("E5/';>(99=u<8!'n239=+;7"),function(e){e.data.shortcuts.add({label:e.finder.lang.shortcuts.general.showContextMenu,shortcuts:S("\x16lkqs}h`5dF\x10\x12^")})},null,null,50)}function r(e){var i=this,r=i.finder,o=new t.Collection,s={groups:o,context:e.context};if(r.fire(S("\nhcczjhe_vz`"),s,r)&&r.fire(S("\x18zuuhxfkmDLV\x1e")+e.name,s,r)){o.forEach(function(n){var i=new t.Collection;r.fire(S("4VYYL\\BOqXPJz")+e.name+":"+n.get(S("+BLCJ")),{items:i,context:e.context},r),n.set(S("\x1fIUGNW"),i)});var a=new t.Collection;o.forEach(function(e){var t=e.get(S("#MQCJ["));t.length&&(a.length&&a.add({divider:!0}),a.add(t.models))}),i.lastView&&i.lastView.destroy();var l=!(!e.evt||!e.evt.clientX)&&{x:e.evt.clientX,y:e.evt.clientY},u=e.positionToEl?e.positionToEl:null;r.request(S("&AGJ_X\x16_KBU\\PVF")),i.lastView=new n({finder:r,className:S("(JAM\x01NAADTJGYPXB"),collection:a,position:l,positionToEl:u,forView:e.view}),i.lastView.on(S("\x1cy{lTSMZ"),function(){r.request(S("&AGJ_X\x16_K\\D^@V"))}),i.lastView.render()}}return i}),CKFinder.define(S(',neiY_VVF\x1a{X\\\\VH\x13{QS$$00\x07**+-*>"##'),[S("(KKHGOAAU"),S('@\x02\t\x05-+"":f\x07$(("<\x7f\x17=?00$')],function(e,t){"use strict";var n=e.Collection.extend({model:t,initialize:function(){this.on(S("\x1fCICMC@\x1cIIDO"),this.sort)},comparator:function(e,t){return e.get(S(":U]P[")).localeCompare(t.get(S("@/#.!")))}});return n}),CKFinder.define(S("=}t\x06(,'!7i\n'-/'?b\b <57!"),[S(" CC@OGIIM"),S("6ts\x7fSUXXL\x10\r.&&(6i\x01'%..>>\r <=70 <99")],function(e,t){"use strict";var n=e.Model.extend({defaults:{name:"",hasChildren:!1,resourceType:"",isRoot:!1,parent:null,isPending:!1,"view:isFolder":!0},initialize:function(){function e(){o.set(S("(AKXoEGCTCW]"),!!o.get(S("\x15u\x7fqu~iys")).length)}this.set(S(">Q!,'"),this.get(S('"MEHC')).toString(),{silent:!0}),this.set(S("3W]_[\\K_U"),new t,{silent:!0});var n=this.get(S("\x1c~vvLEPFJ"));n.on(S("\rmgq\x7fuv"),e),n.on(S(",_KB_GW"),e),this.on(S("E%/)'-.v.&&<5 6:"),function(t,n){n&&(n.on(S("\x1fCICMC@"),e),n.on(S("#V@KH^L"),e))});var i=this.get(S("6VTUULYY{G4$,0-*(4"));i&&"string"==typeof i&&this.set(S('@ ./+2##\r1>.">\' >"'),i.split(","),{silent:!0});var r=this.get(S("\x1fAMNLS@BbP]OE_DAAC"));r&&"string"==typeof r&&this.set(S("\x18xvwsj{{eYVFJVOHFZ"),i.split(","),{silent:!0});var o=this},getPath:function(e){var t,n;return t=this.get(S(":K]O[Q4")),n=t?t.getPath(e).toString()+this.get(S("!LBI@"))+"/":"/",this.get(S("\x1aroOqpT"))&&e&&e.full&&(n=this.get(S("\x16e}junn~{KYQG"))+":"+n),n},getHash:function(){if(this.has(S("\x1bt|mw")))return this.get(S(">W!2*"));var e=this.get(S('C4$4"&='));return e.getHash()},getUrl:function(){if(this.has(S("=KM,")))return this.get(S("*^^A"));var e=this.get(S("\x13dtdrvm"));if(!e)return!1;var t=e.getUrl();return t&&t+encodeURIComponent(this.get(S("$KGJM")))+"/"},isPath:function(e,t){return e===this.getPath()&&t===this.get(S(",_K\\_D@PQaOG]"))},getResourceType:function(){for(var e=this;!e.get(S("!KPvJIS"));)e=e.get(S("\x10asaq{b"));return e}},{isValidName:function(e){var t=/[\\\/:\*\?"<>\|]/;return!t.test(e)}});return n}),CKFinder.define(S("9N^DI\x1f|\v\x07+- 4h\x1c,'; ,:*#~\x14<813%+v\x1c409;-.\0\x0f\x06 \f\x07\v\x07\x0e>\x0e\x01\x1d\x02\x0e\x04\x14\\\x17\x1b\x01"),[],function(){return S(")\x16MC_C\x0fQRFZ[[\v\x15\x1b\x1b\x0415\x01R^\"$.}NLO<3hj\"8c*&1==4\x190%$9>?{! TVi]\v\r\x14\x10\x12G\x06\b\x07\x0eQO\0\n\x077\x1d\x1f\x10\x10\x049\x19\x14\x1fY\\\v\x1f\x13ud?!\x7f~''a}$mcajjb_s~q5kj:9nz~tp{EY\x1f\x01\x15\x07\x06FZ@K\x06^H_ZYCWW\t\x17BEM\\\x18\x1bXTL\x02b 77+gxMAue'-/+#n[n|2:$:fSf+|>2>\x13\x12_A\x01\x17\x14\b\x1aD\x07\x0e\x1f\x1e\x0f\b\x15SLO[\x05H}")}),CKFinder.define(S("2p\x7fs_Y\\\\H\x14qRZJ,$1l\x02**#-;9d\x1a$+8#~\x14<813%\x1687>\x184?3\x0f\x064\n\x01\x12"),[S("\x14V]Qqw~~n2HvEVQ\ffDUB\x07`^NA{GJG"),S("%eln@DOI_\x01b_UW_G\x1apXT]_I"),S(' UG[P\x04eln@DOI_\x01{U\\B_UASD\x17\x7fUWXXLLo\x07-/ 4\t)$/\x0f%," 7\x057>$97#=w>4(')],function(e,t,n){"use strict";return e.extend({name:S("3rZZS]KtZQXzV!--$\x12,#0"),template:n,ui:{error:S("\r jbc}a9xsdkx}~"),folderName:S(',D@_EEi]UXS\n\x1aW_LzRR[%3\f") d\x1a')},events:{"input @ui.folderName":function(){var e=this.ui.folderName.val().toString().trim();t.isValidName(e)?this.model.unset(S(":^NOQM")):this.model.set(S("9_INRL"),this.finder.lang.errors.folderInvalidCharacters),this.model.set(S("5PXT]_Ir\\SZ"),e)},submit:function(e){this.trigger(S("\x18joyqtj%FNPN")),e.preventDefault()}},modelEvents:{"change:error":function(e,t){t?(this.ui.error.show(),this.ui.error.html(t)):this.ui.error.hide()}}})}),CKFinder.define(S("+ofhF^UWA\x1bxYSMU_H\x13~LZ!5'\x05+)\"\":f\t9),:*\x16>>71'"),[S("3VTU\\ZVT^"),S("6ts\x7fSUXXL\x10\r.&6( 5h\x0e&&/)?=`\x0687$'z\x1084=?)\x12<3:$\b\x03\x0f\v\x020\x0e\r\x1e")],function(e,t){"use strict";function n(n){n.setHandler(S("D#)+,,8q/?+.$4"),function(i){var r=i.parent,o=i.newFolderName;if(o)n.request(S("\x17tv{\x7fyo$lHNU"),{text:n.lang.common.pleaseWait}),n.request(S("%EHEDKEH\x17]J^U"),{name:S(".lBTSGQsY[\\\\H"),type:S("\x17hvio"),folder:r,params:{newFolderName:o},context:{folder:r}});else{var s=new e.Model({dialogMessage:n.lang.folders.newNameLabel,folderName:i.newFolderName,error:!1}),a=n.request(S("0U[RXZQ"),{view:new t({finder:n,model:s}),name:S("\rM}upfvRzzs}k"),title:n.lang.common.newNameDialogTitle,context:{parent:r}});s.on(S("\x19ys}syz\x1aDPQKW"),function(e,t){t?a.disableButton(S("%IL")):a.enableButton(S('"LO'))})}}),n.on(S("/TXS_[R\ftJ\\[OY{QS$$0y+."),function(e){var t=e.data.view.model;if(!t.get(S("2VFGYE"))){var i=t.get(S("\x1bzrr{ESlBI@"));e.finder.request(S(";XT_S/&x'!625'0")),n.request(S(";ZRR[%3x 6 '3-"),{parent:e.data.context.parent,newFolderName:i})}}),n.on(S('@"--0 >3\x05,$>v+!#44 i11?#'),function(e){var t=e.finder,n=e.data.context.folder;e.data.items.add({name:S("!aQADRBnFFOI_"),label:t.lang.folders.newSubfolder,isActive:n.get(S("!C@H")).folderCreate,icon:S('?#*$n"**#-;g*()'),action:function(){t.request(S("$CIKLLX\x11O_KNDT"),{parent:n})}})}),n.on(S("+XBACRP@\tFPERL\x03wZUS\x04Y/-&&6"),function(e){var t=e.data.folder;t.get(S("+MNB")).folderCreate&&e.data.toolbar.push({type:S("\x12qaabxv"),name:S("\x1fcSGBP@`HDMOY"),priority:70,icon:S('@")%i#)+,,8f-)*'),label:e.finder.lang.folders.newSubfolder,action:function(){n.request(S("$CIKLLX\x11O_KNDT"),{parent:t})}})}),n.on(S("\x1c~qrM@LG\x1eD@SM[\x10h^HO[Uw]_PPD"),i)}function i(e){function t(e){e.data.context.parent.cid===n.cid&&(e.data.response.error||n.trigger(S("\x17mp ~dm\x7fqD")),e.finder.removeListener(S("\x14vyzuxt\x7f&|xkES\x18dAQ`HDMOY_"),t))}var n=e.data.context.folder;e.finder.request(S(";PR_[%3x+-!#")),e.data.response.error||(n.set(S(",EO\\sY[_PGSY"),!0),e.finder.once(S("C'*+*)'.q-+:*\"k\x156 \x139;<<(("),t),e.finder.request(S("\x0fs~\x7f~u{r-k|t\x7f"),{name:S("1uV@sY[\\\\HH"),folder:n,context:{parent:n}},null,null,30))}return n}),CKFinder.define(S('\x12gqmb6[R\\rry{m\x0fuGNTIGSMZ\x05oIAK[Uw[_Q\x1arRT\\N^zTRZ\x0530,6k"(<'),[],function(){return S("\x14nm(8pn5qny?]\\\x1eS\x1a^]\x1a\b@^\x05A^I\x0fML\x0e\x1cD\vML\x07DG1\0HR\x01J:9=d,2i-;8$>>nu5# <&u+*d53e'&c\x7f\x05\x13\x10\f\x16E\x1b\x1aTF\x06\x02R\x16\x15\x11\r\fxO[\0\x1aIr")}),CKFinder.define(S("1qxr\\XS]K\x15vSYKS%2m\x07!)#3-\x0f#')b\n*<4&6\x12<:2"),[S("$PHCM[YHC_K"),S(":Y]^U]//'"),S("(]OSX\fmdvX\\WQG\x19c]TJW]I[Lo\x05'/!1#\x01!%/d\b(\"*$4\x14:80\x13%*6(u82*"),S("\x12P_S\x7fy||h4Iiws\x0fjGZgJBB")],function(e,t,n,i){"use strict";function r(e){this.finder=e,e.setHandler(S("2U]YSD\x02]_WYI["),o,this),e.on(S("\fign|~u)Ppzrl|\\rpx]pNGKQI\x1fIL"),l),e.on(S("\x1d}pMLCM@\x1fGA\\LX\x11hHBJDTtZXPE"),u),e.on(S("\x14vyzuxt\x7f&xlmOS\x18gAICSMoCGI^"),c),e.on(S("\x12p{{br`mW~rh$yIMG"),function(e){e.data.groups.add({name:S('C *"<,')})},null,null,40),e.on(S("A!,*1#?<\x04/%9w(&<4h7193#="),a,this),e.on(S(';HRQS" 0y6 5"1?n.lang.files.deleteConfirmation.replace(S("\x14nuxmwnf"),i.length):n.lang.files.fileDeleteConfirmation.replace(S("\x11i}uxsj"),function(){return n.util.escapeHtml(i[0].get(S(";R\\SZ")))}),void n.request(S('D!/&$&-q/" )9#?'),{name:S('E\x02"$,>.\n$"*\x13><5=\';'),msg:t,context:{files:i}})):void n.request(S("\x15r~yuu|&tpyO"),{msg:n.lang.errors.deleteFilePermissions})}function s(e){var t=e.finder.request(S("1T\\XQSE\x02^_O}^JV6$"));t.get(S("\x10pq\x7f")).fileDelete&&e.data.toolbar.push({type:S(";^HJK//"),name:S("\x12Wqysc}_swyn"),priority:10,icon:S(",NEI\x1dW[_Q\x18RRT\\N^"),label:e.finder.lang.common.delete,action:function(){e.finder.request(S(",KGCUB\bWQYSC]"),{files:e.finder.request(S("\x15p~t|i!{xjLEMG@P@B")).toArray()})}})}function a(e){var t=this,n=t.finder,i=n.request(S("'N@FN_\x17IJDbW_QVBR\\")),r=i.length>1;e.data.items.add({name:S("\x0eKu}wgqS\x7f{}j"),label:n.lang.common.delete,isActive:e.data.context.file.get(S("1T\\XQSE")).get(S("\x16v{u")).fileDelete,icon:S("=]T&l$*( k#-%/?)"),action:function(){n.request(S("1TZXPE\r\\\\V^HX"),{files:r?i:[e.data.context.file]})}})}function l(n){var i=n.data.context.files,r=[],o=n.finder;i instanceof t.Collection&&(i=i.toArray()),e.forEach(i,function(e){var t=e.get(S("?&..'!7"));r.push({name:e.get(S("\fcobu")),type:t.get(S("/BTA\\AGURl@J^")),folder:t.getPath()})});var s=o.request(S("\x1fFNNGAW\x1c@M]kHXDXJ"));o.request(S(" MMB@@T\x1d[AE\\"),{text:o.lang.common.pleaseWait}),o.request(S(" BMNIDHC\x12ZOEH"),{name:S("(mOGIYKiY]W@"),type:S(">O/26"),post:{files:r},sendPostAsJson:!0,folder:s,context:{files:i}})}function u(t){var n=t.data.response;t.finder.request(S("4YYV\\\\H\x01TTZZ")),n.error||(e.forEach(t.data.context.files,function(e){var t=e.get(S("\fkactt`"));t.get(S("\x10rzzxqdrv")).remove(e)}),t.finder.fire(S("\x1dxvLDQ\x19@@JB\\LN"),{files:t.data.context.files},t.finder))}function c(i){var r=i.data.response;if(r.error.number===f){i.cancel();var o=!!r.deleted,s=i.finder.lang.errors.codes[f],a=[];e.forEach(r.error.errors,function(e){a.push(e.name+S("\x1a!<")+i.finder.lang.errors.codes[e.number]),117===e.number&&(o=!0)}),i.finder.request(S("B'-$*(/"),{name:S("D\x01#+-=/\r%!+<\x15# <&&"),title:i.finder.lang.errors.operationCompleted,template:n,templateModel:new t.Model({deleted:r.deleted,errors:a,msg:s}),buttons:[S("\x1dqtcMMPA")]}),o&&i.finder.request(S("\x10w}\x7fppd-j||iynvYIMGP"))}}function d(e){e.on(S("\x1dxvLD\x18HA\\BH_G"),function(t){if(t.data.evt.keyCode===i.delete&&e.util.isShortcut(t.data.evt,"")){var n=e.request(S("\x10w{\x7fqf,p}mI~px}kEE")),r=n.length>1?n.toArray():[t.data.file];e.request(S("0W[_QF\fS]U_OY"),{files:r})}}),e.on(S(" RJLVQER\\Z\x10GE^Z\x15VX^VG"),function(e){e.data.shortcuts.add({label:e.finder.lang.shortcuts.files.delete,shortcuts:S("+WIKCM")})},null,null,30)}var f=302;return r}),CKFinder.define(S("\x16TS_suxxl0mNFVH@U\blLFNXHh@\\UWA\x1bqS[]M_}SQZZ2"),[S("\x13W^P~v}\x7fi3HjvL\x0eiF]fICM")],function(e){"use strict";function t(e){e.on(S("$AOFDFM\x11hHBJDTt\\XQSE{VT]UOS\x05/*"),function(t){var n=t.data.context.folder;e.request(S("3XZWS]K\0HTRI"),{text:e.lang.common.pleaseWait}),e.request(S("(JEFAL@K\nBW]P"),{name:S(",iKCUEWu[YRRJ"),type:S("/@^AG"),folder:n,context:{folder:n}},e)}),e.on(S("=]P-,#- \x7f'!<,8q\b(\"*$4\x14<813%"),function(t){var n=t.data.response,i=t.data.context.folder;if(e.request(S("\x1aws|zzR\x1bJJ@@")),!n.error){var r=i.get(S('C4$4"&='));i.unset(S("\f}o}u\x7ff")),r.get(S("4V^^T]H^R")).remove(i);var o=e.request(S('7^VV_YO\x04X%5\x03 0,0"'));o.cid===i.cid&&e.request(S("#BJJCM[\x10XIAKLD"),{folder:r}),e.fire(S("=XP,%'1~!#+-=//"),{folder:i})}}),e.on(S("\vxbacrp`)fperl#Wzus$yOMFFV"),function(t){var n=t.data.folder;!n.get(S("\x11{`Fzyc"))&&n.get(S("1SPX")).folderDelete&&t.data.toolbar.push({type:S("1PF@AYY"),name:S("!fFH@RBnFFOI_"),priority:20,icon:S("\x16ts\x7f7}sqzzR\fFFH@RB"),label:t.finder.lang.common.delete,action:function(){e.request(S(")LD@IK]\nUW_QAS"),{folder:n})}})}),e.on(S('B ++2"0=\x07."8t)?=66&'),function(e){e.data.groups.add({name:S("&CMEO_I")})},null,null,20),e.on(S(";_RPK%96\x0e!+3}.&&/)?t+5=7'1"),function(e){var t=e.finder,n=e.data.context.folder,i=n.get(S("?)2\x10,+1")),r=n.get(S("\x1fABN"));e.data.items.add({name:S("\x10Uw\x7fqasQwu~~n"),label:t.lang.common.delete,isActive:!i&&r.folderDelete,icon:S(".L[W\x1fU[YRRJ\x14^^PXJZ"),action:function(){t.request(S("\x0fv~~wqg,s}u\x7foy"),{folder:n})}})}),e.setHandler(S('C"**#-;p/)!+;5'),function(t){var n=t.folder;e.request(S('"GMDJHO\x13IDBKG]]'),{name:S(">{%-'7!\x03)+,,8\b##(&\"<"),context:{folder:n},msg:e.lang.folders.deleteConfirmation.replace(S("7CW[VY@"),function(){return e.util.escapeHtml(n.get(S("0_S^Q")))})})}),n(e)}function n(t){t.on(S("\x10w}\x7fppd-s|c\x7fsjp"),function(n){n.data.folder.get(S("\x0efcC}|`"))||n.data.evt.keyCode===e.delete&&n.finder.util.isShortcut(n.data.evt,"")&&(n.data.evt.preventDefault(),n.data.evt.stopPropagation(),t.request(S("$CIKLLX\x11HHBJDT"),{folder:n.data.folder}))}),t.on(S("\x16dpvho\x7fhjl\x1aMKPP\x1f@HDMOY_"),function(e){e.data.shortcuts.add({label:e.finder.lang.shortcuts.folders.delete,shortcuts:S("$^BBDT")})},null,null,30)}return t}),CKFinder.define(S('>|\v\x07+- 4h\x1e /+'),[S("\x13ytd~ww\x7fohx"),S('"`ocOILLX\x04zDKXC\x1epRGP\x19tWTWTR')],function(e,t){"use strict";var n=e.LayoutView,i=n.extend(t.proto),r=i.extend({constructor:function(n){t.util.construct.call(this,n),e.LayoutView.prototype.constructor.apply(this,Array.prototype.slice.call(arguments))}});return r}),CKFinder.define(S("%eln@DOI_\x01yYTE@\x1bwWD]\x16yTPQ[\\4(--\x12,#0"),[S("\x1biszzRRALV@"),S("6ZYKSTRXJK%"),S(";\x7fvxV.%'1k\x13/\"?:e\t->+`\x13>?>;;")],function(e,t,n){"use strict";var i=t.CollectionView,r=i.extend(n.proto),o=r.extend({constructor:function(e){n.util.construct.call(this,e),i.prototype.constructor.apply(this,Array.prototype.slice.call(arguments))},buildChildView:function(t,n,i){var r=e.extend({model:t,finder:this.finder},i);return new n(r)}});return o}),CKFinder.define(S(",neiY_VVF\x1a{X\\LV^O\x12zV!--$7j\x10.->9d\b$/#?6\x10& !99\x0e0?,"),[S("=}t\x06(,'!7i\x12< &d\x07(7\f?57"),S("+ofhF^UWA\x1bc_ROJ\x15y]N[\x10\t5'.\x12,#0")],function(e,t){"use strict";return t.extend({name:S(" eKBHJAe]]^DB"),tagName:S(" CWWPJH"),template:S(".TK\f\x12Z@\x1bZVZ\\V\x1bA@"),attributes:{tabindex:1},events:{click:function(){this.trigger(S("\x0frdfg{{"))},keydown:function(t){t.keyCode!==e.enter&&t.keyCode!==e.space||(t.preventDefault(),this.trigger(S(".MEEF\\Z")))}},onRender:function(){this.$el.attr(S('"GEQG\nAGFBBH'),!0).attr(S("$AGSI\x04I@J\0LZDE]]"),this.model.get(S("!LBI@")))}})}),CKFinder.define(S('@\x02\t\x05-+"":f\x07$(8"*#~\x16:5990+v\f29*-p$\b\x03\x0f\v\x02$\x12\x1c\x1d\x05\x05\x1f;\x07\n\x07'),[S("1G]PPDD[VH^"),S("\x1ay}~u}OOG"),S("\x15U\\^pt\x7fyo1IIDUP\vgGTM\x06iD@AKLDX]]b\\S@"),S("4v}qQW^^N\x12sP$4.&7j\x02.)%%,?b\x18&5&!|\x10<7;7>\x18.()116\b\x07\x14")],function(e,t,n,i){"use strict";function r(n,i){var r=new t.Collection;return e.forEach(n,function(t){var n=e.isString(t)?t:t.name;r.push(e.extend({icons:{},label:n,name:n,event:n.toLocaleLowerCase()},e.isString(t)?i[n]:t))}),r}return n.extend({name:S('D\x01/&$&-\t99: >"'),childView:i,initialize:function(e){this.collection=r(e.buttons,{ok:{label:this.finder.lang.common.ok,icons:{primary:S("\x13a|;~{vt6\x7fu{|K")}},okClose:{label:this.finder.lang.common.ok,icons:{primary:S("\x1ejI\fK@KK\vD@LI@")},event:S(":TW")},cancel:{label:this.finder.lang.common.cancel,icons:{primary:S("\x0ezy<{p{{;ttvi~")}}})}})}),CKFinder.define(S("@5';0d\x05\f\x0e $/)?a\x1b5<\"?5!3$w\x1d3:029,O%\v\x02\b\n\x01+\t\x10\x05\x1e\x18C\n\0\x04"),[],function(){return S(">D;~b*0k2.<%/k10r+9'r75!7z*66>a\x7f6:\x01\x05\x07\x11FE\x05\v\t\x1a\x19VN\x18\x07B\x04\x18\x06\x1f\x11WHK\x10HD\0\x07@^\x16t/vjpic'ut6$d<03?u{e*nm(ed\x10'xth?IE\x1f\x01GN@\nL@KGCJ\x03L__FVZAE\x1aCB\x07\x1bUI\x10V$a?>fe%+):9vn.%)}5;28:1z;64/93*,@\x1a\x19^D\f\x12I\v\x06\x04\x1f\t\x03\x1a,\x1c\x10\x01\0:\x14\x1b\x12X\x04\x07YBAQ\x1biw<\t\x7f~9'a}$cm~Lzde}}g5kj$}sm<~r~SR\x1f\x01QL\vDGG^NBY\x0eL[W\x1fW]TZX_\x14XNHIQQ3cb* xd$#/g/%,\" 7|0& !99+t! a}7+N\b\x06C\x19\x18DYTF\x0e\x02\x1aS\x15\x14O\f\x0fy")}),CKFinder.define(S("&dcoCEHH\\\0}^VFXPE\x18|P[WSZM\x10\x16('47j\x02.)%%,\x1a$+8"),[S("\x1dkqDDPPGJTB"),S("?*07&6<"),S("0ryu][RRJ\x16oOUQ\x11t%8\x01, "),S("2p\x7fs_Y\\\\H\x14jT[H3n\0\"7 i\v)0%>8\x1b'*'"),S('!ahbLHCM[\x05fCI[CUB\x1dw]TZX_J\x15mUXILo\x05+"(*!\x05==>$">\x18&5&'),S('2GQMB\x16{r|RRY[Mo\x15\'.4)\'3-:e\x0f%," 7"}\x17=4:8?\x15;"3(*q\x04\x0e\x16')],function(e,t,n,i,r,o){"use strict";var s=20,a=i.extend({template:o,className:S(".L[W\x1fW]TZX_"),ui:{title:S("$\vSN\x05]C_@H\x14IYCAG")},attributes:{role:S("D!/&$&-")},regions:function(e){return{contents:S(">\x1c#*$n ,'+'.g(##:*>%!~")+e.id,buttons:S("\x0f3ryu9q\x7fvtv}6~hjkOOQ\x0e")+e.id}},initialize:function(){this.listenTo(this.contents,S("D6.(?"),function(){this.$el.trigger(S("\x1e|RDCWA"))},this),t(S("\x187or1mqoUQ\x0f@KKRFAGOY")).remove()},onRender:function(){var t=e.uniqueId(),i=S("/SZT\x1eP\\W[W^\x17W]_[Sm")+t;this.$el.attr(S("\x16sym{6hu{rE"),this.finder.config.swatch).attr(S("#EWOF\x05EKIIABJTSK"),i).attr(S('@ 0*%h"";*8".(*-)'),this.regions.contents.replace("#","")).appendTo(S("\x18{u\x7fe")),this.options.ariaLabelId&&this.$el.attr(S('"BVLG\nDHHN@AKKRH'),this.$el.attr(S('<\\LV!l."& *+--(2'))+" "+this.regions.contents.replace("#","")),this.ui.title.attr({id:i,"aria-live":S("!RLHLRB")}),this.contents.show(this.getOption(S("\x18ptuyoHvEV"))),this._addButtons(),this.$el.trigger(S("E%5-(>.")),this.$el.popup(this._getUiConfig()),this.$el.parent().addClass(S(":NU\x10ZV!--$i5)7=9"));try{this.$el.popup(S("7WI_U"),this.options.uiOpen||{})}catch(e){}this.$el.find(S('2\x1dW^P\x1a\\P[WSZ\x13]556,*6f%==>$"\x16*.$0\x7f0?3{5--.42`|0\v"\x0e\f\x17\0D:DG\t\0\n@\n\x06\x11\x1d\x1d\x14Y\x17\x03\x03\f\x16\x14\b\\\x1f\v\vtnlX`drf%jam!o{{d~|.6z}5E')).first().focus();var r=this.getOption(S("\x0ei\x7frg`]asz"));if(r){var o=e.isString(r)?r:S("\x17qwjnh1>kEYVBV@G\v\bZOGINZ"),s=this.$el.find(o).first();s.length&&s.focus()}return this.options.restrictHeight&&this.restrictHeight(),this.$el.on(S("2XQLRXOW"),function(e){e.keyCode!==n.tab&&e.stopPropagation()}),this},onDestroy:function(){try{this.$el.popup(S("(JFD_H")),this.$el.off(S("-EJIU]DZ")),this.$el.remove()}catch(e){}},getButton:function(e){return this.$el.popup(S(";KTZX%5")).find(S("\x1d|jTUMM\x7fAGSI\x04I@J\0LZDE]]\t\x17")+e+S("\x1e=}"))},enableButton:function(e){this.getButton(e).removeClass(S("3A\\\x1bDLXN^\x11YWL!#.& ")).attr(S("'I[CJ\x01IG\\QS^VP"),S("@'#/7 "))},disableButton:function(e){this.getButton(e).addClass(S(")_B\x01^ZNDT\x1fW]FWUT\\^")).attr(S("1SA]T\x1bSQJ[YPXZ"),S("0E@FQ"))},restrictHeight:function(){if(!this.isDestroyed){var e=t(window).height()-this.ui.title.outerHeight()-this.buttons.$el.outerHeight()-this.$el.parent().position().top-s;this.contents.$el.css(S('=S^8l*&-".3'),parseInt(e,10)+S("2CL"))}},_fixTopOffset:function(){var e=this.$el.parent().css(S("\x16cwi")),t=parseInt(e)-(window.scrollY||window.pageYOffset);this.$el.parent().css(S("!VLT"),t)},_addButtons:function(){var e=this.getOption(S(":YIIJP.2"));if(e){var t=this,n=new r({finder:this.finder,buttons:e});this.listenTo(n,S(" BJJHAPNM^\x10IYYZ@^"),function(e){var n=e.model.get(S("\x10tdvza")),i=e.model.get(S("?. /&"));i!==S("\rmn~rw\x7f")&&i!==S("5Y\\{UUHY")||t.destroy(),t.finder.fire(S("\x1e{I@NLC\x1f")+t.getOption(S("\x13p|w{w~"))+":"+n,t.getOption(S("*H@DMDtPFR")),t.finder)}),this.buttons.show(n)}},_getUiConfig:function(){function t(e,t,n){i[e]&&i[e].apply(t,n)}var n=this,i={},r=this.getOption(S("\x15c~Winrssm"));r&&e.forEach([S("2PFPWC]"),S('B""1#5+%%8)'),S(">]%'-1!5)4!=#$\"")],function(e){i[e]=r[e],delete r[e]});var o={create:function(){n.contents.$el.css({minWidth:n.getOption(S(")GBBzGKDY")),minHeight:n.getOption(S("\x1erIOjFMBNS")),maxHeight:window.innerHeight}),t(S("-M]UPFV"),this,arguments)},afterclose:function(){n.destroy(),n.finder.fire(S("0U[RXZQ\r[UUHY\x07")+n.getOption(S("8]SZPRY")),{context:n.context,me:n}),t(S('=_Y4$0 (*5"'),this,arguments)},afteropen:function(){n._fixTopOffset(),t(S('B""1#5\'9/%'),this,arguments)},beforeposition:function(e,i){r&&r.positionTo&&(delete i.x,delete i.y,i.positionTo=r.positionTo),setTimeout(function(){n.options.restrictHeight&&n.restrictHeight()},0),t(S("\x12qqsye}iuhuiwpN"),this,arguments)}},s=n.finder.config.dialogOverlaySwatch;return s&&(o.overlayTheme=e.isBoolean(s)?n.finder.config.swatch:s),e.extend(o,r)}});return a}),CKFinder.define(S("\x1c^UYIOFFV\npNM^Y\x04aH]\\QVWe]PA"),[S("\x14`xs}kixso{"),S("C&$%,*&$."),S(")i`jD@KUC\x1de]PAD\x17{[HY\x12wK%,\x14*!2")],function(e,t,n){"use strict";var i=n.extend({name:S('>r%21"# \x10.->'),className:S("*HGK\x03BUBARSP"),template:S("'\x14ZZJB\rGK\r\x13IH\t\x15_C\x16P^\x1bA@\x1c\x01;:\x7fc-1h*;.j61qa< 0955<\n4;("),S("#gn`NFMOY\x03{GJGB\x1dqUFS\x18qM_VjT[H"),S(",neiY_VVF\x1a`^]NI\x14qXML!&'\x15- 1")],function(e,t,n,i,r,o,s){"use strict";function a(e){this.finder=e,e.setHandlers({dialog:{callback:l,context:this},"dialog:info":{callback:u,context:this},"dialog:confirm":{callback:c,context:this},"dialog:destroy":h}),e.request(S("=UZ9{.*71#)"),{key:i.escape}),e.on(S("\x1etEXWS\x1e\x17\x11"),function(e){var n,i;i=t(S("\x1f\x0eBIE\tAOFDFM")),i.length&&(n=e.data.evt,n.preventDefault(),n.stopPropagation(),h())},null,null,20)}function l(t){var n=this.finder;if(h(),!t.name)throw S("8w[VY\x1dN^2 /&0 4g%<9?l/+o#!70=3?2\x02!,)*\x7f\x146: \x1c;6?<\x16:%2++N\x05\r\x17"),[],function(){return S("\r2kyg2pxted%;ypz0{v\rVPBTUCU\n\x17 \"\x10IGY\x10XV\x0e\x16V]Q\x15\\S\x16LO[I)$5ad&*&;:wi/&(b58\x7f#&0 >=.xe`r:6\x16_hjX\x01\x0f\x11H\0\x0eVN\x0e\x05\t]\x14\x1b^\x15\x16\x02\x1e\x17\x17\tY\\\x1e\x12\x1esr?!gn`*m`'hccz}\x7f}a3a|;uw}c6gf#?IU\fPSDRD@\tWV\x0e\x13\x12\0TXD\r>\t\x19SQO\x041")}),CKFinder.define(S('-mdvX\\WQG\x19zW]OWYN\x11z$(6\n)$!"g\x1f#.;>a\n48&\x1a9412\x148#4))'),[S("\x0fSZTzzqse7Os~kn1]ARG\fhD_H]]|BIZ"),S("\x1ekEYV\x02gn`NFMOY\x03yKB@]SGQF\x19r\\PNrQ\\YZo\x04&*0\f+&/,\x06*5\";;~5='")],function(e,t){"use strict";return e.extend({name:S("6r\\PNrQ\\YZ\f ;,11"),template:t,regions:{preview:S("-\rL[W\x1fV]\x18FE]OS^K"),actions:S("\x0f3ryu9p\x7f:yznrssm")},templateHelpers:function(){return{swatch:this.finder.config.swatch}},onActionsExpand:function(){this.preview.$el.addClass(S(")I@J\0KF\x1dA@VB\\S@\x15K__I^[["))},onActionsCollapse:function(){this.preview.$el.removeClass(S("\x1b\x7fvx2EH\x0fSV@PNM^\x07YII[LUU"))}})}),CKFinder.define(S('$QC_\\\bi`jD@KUC\x1dgQXF[YM_H\x13xZV4\b/"# i\x0e%(-.\x1c?+994%}0:"'),[],function(){return S("\x1c!}~NWCP\x04FJF[Z\x17\tOFH\x02UX\x1fPU[@VK\x1b\x04\x07\x13^_Q6 1}N")}),CKFinder.define(S("7{r|RRY[Mo\f-'1)#4g\f.\"8\x04#.74}\x05=0!$w\x107:;8\x0e-\x05\x17\v\x06\x133\x0f\x02\x1f"),[S("=}t\x06(,'!7i\x11!,=8c\x0f/<5~\x1b'18\0>=."),S("D1#?:("8!+o-,n|\x115(o +)*&8:#) (c'506::2{#7>=79")).attr(S(" UCAMKBBP"),this.model.get(S("\x13`tt~v}\x7fc"))),this.ui.heading.attr(S("$DTNI\x04OS\\L@KUU"),S(",KOCCT")),this.isExpanded=!1;var e=this.model.get(S("$LB"));this.$el.find(S("\x1c3kv\rBMOHDVTAKFN\x01NAADT\\G")).attr({id:e+S('?m5#!4$("$'),role:S("6CY[JZRXR"),"aria-labelledby":e+S("/\x1dESQ")})},"keydown .ui-collapsible-heading-toggle":function(e){if(e.keyCode===n.space||e.keyCode===n.enter){e.stopPropagation(),e.preventDefault();var t=S(this.$el.find(S('"\rQL\vDGEFJ\\^GM\\T')).collapsible(S(".@@E[\\Z"),S("\rm`|}scgpr"))?"B&<5'),":"9YTPQ_O3$");this.$el.find(S('\v"xg"s~~\x7fuee~zu\x7f')).collapsible(t)}},"keydown [tabindex]":function(e){e.keyCode===n.tab&&(!this.isExpanded&&e.target===this.ui.heading.find(S("$\vSN\x05JEG@L^\\YS^V\x19]SV\\PT\\\x11IQX'-'")).get(0)||this.ui.controls.find(S('"xPDDNFMOSq')).last().get(0)===e.target)&&this.trigger(S("@5#!\x16 72-:>"),e)}},initialize:function(){this.model.set(S("?)%"),e.uniqueId())},collapse:function(){this.$el.find(S(";\x12HW\x12#../%55.*%/")).collapsible(S(";_RRS!11&"))},onRender:function(){this.action.show(this.model.get(S(" UMLH")).getView(this.finder)),this.$el.attr(S("!FBPD\vDCO\x07NE\0Z@_]"),this.model.get(S('"WKJJ')).get(S("*EM@K")))}})}),CKFinder.define(S(";\x7fvxV.%'1k\b)#=%/8c\b*&$\x18?230y\x011<-(s\x1c=+\t\x0e\f\x102\f\x03\x10"),[S("\x18sknyog"),S("\x13W^P~v}\x7fi3KwzWR\raEVC\bkFFGINZF__dZQB"),S("7{r|RRY[Mo\f-'1)#4g\f.\"8\x04#.74}\x05=0!$w\x189/520\t\t\x04\x15")],function(e,t,n){"use strict";function i(t,n){var i=t===S("'LLY@XB^");e(S('@o!("h#.e*%%8?!##q|&=x5845;+/4<3\x05L\n\x06\x05\x01\x0f\t\x0fD\x1e\x04\v\n\x02\n')).toggleClass(S("#QL\vDG[DN^\0OC\\\x11GZ\x19WBY\x15PYTR\x10PP4$:7"),!i).toggleClass(S(n.lang.dir===S("!NWV")?'29=35;p*0\x07\x06\x0e\x06")).first().focus()}})}),CKFinder.define(S("C\x07\x0e\0.&-/9c\0!+%=7 {\x102>,\x107:;8q\x12\x0f\x05\x07\x0f\x17J#\x03\x01\x1d#\x06\r\n\v+\x11\x05\x13"),[S("\x1b~|}tBNLF")],function(e){"use strict";var t=e.Model.extend({defaults:{file:null,caman:null,imagePreview:"",fullImagePreview:"",actions:null},initialize:function(){this.set(S("\njoyg`~b"),new e.Collection)}});return t}),CKFinder.define(S("$fmaAGNN^\x02c@TD^VG\x1asSQMsV]Z[\x10\x14.-/7j\x12('%"),[S('"AEFMEGGO')],function(e){"use strict";return e.Model.extend({getActionData:function(){return new e.Model({})},saveDeferred:function(e,t){return t},getView:function(e){var t=this.get(S("A4*!2\x05+):9")),n=new t({finder:e,model:this.getActionData()});return this.set(S("'^@O\\"),n),n}})}),CKFinder.define(S("4ASOL\x18ypzTP[%3m\x17!(6+)=/8c\b*&$\x18?230y\x14*6*u82*"),[],function(){return S('\x1b ywi\0BNBWV\x1b\x05KBL\x06ID\x03LB^B\x1eWZXCJVVH\x11TPO551azOO{$((. sDFY*)nt<"y48432(\x18)+9>*\r\x01\x15\v\fD\x18\x1bG\v\x01\x0f\b\x07\b\nRR\x12\x1a\x16\x17\x1e\x13\x13Z\x02\x01D\x01\0^\x1bauc.mfiixfy6.vu00xf=xtxp6}si< #?\x07MVQ\x03X[KMO^PW\x12\x11RMC[T\\AML\x07DG\x19\x0277\x03o-#!!)xMAu(>89!!p86nv6=1u<3v?/1/M\0\x12\x13\b\x1cDG\x1c\b\b\x02\x02\t\v\x17MS\t\bIU\x1f\x03V\r\x1b\x19\x15\x13\x1a\x1ax!\x7f~&%bf|h\'bob`22ryu9a\x7fts;:\x7f}i\x7f2IBMMTJU\x1a\nRQ\x14\fDZ\x01\\P\\T\x1aQ_E\x18\x04\x07\x1b\x1bQJMg9#!="),ui:{keepAspectRatio:S('1[]D@BlVXW^\x01\x1f]T&\x020,4\x0e#"8\b9;).:\x1d1%;?<(')},triggers:{"click @ui.apply":S(">^01.:")},events:{"change @ui.keepAspectRatio":function(e){e.stopPropagation(),e.preventDefault(),this.model.set(S("(BON\\l]_URFaUA_X"),this.ui.keepAspectRatio.is(S("1\bP\\PU\\]]")))},"keyup @ui.keepAspectRatio":function(t){t.keyCode!==e.space&&t.keyCode!==e.enter||(t.preventDefault(),t.stopPropagation(),this.ui.keepAspectRatio.prop(S("\x1fCIG@O@B"),!this.ui.keepAspectRatio.is(S("3\x0eV^R[R__"))).checkboxradio(S("i)'->=rr295y0?z;+5+q/;,\t\x1b\x07AD\x11\x07\x05\x01\x07\x0e\x0e\x14PL\x14\vLR\x1a\0[\x02\x16\x1a\x10\x14\x1f\x19\x05^T 0\"~y'8;'mc}2\x07\x073txd3wywdk$8xw{3zI\fAQKU\vNFOE\t\x12\x11\x01KYG\f9\b\x1aR^N\x07")}),CKFinder.define(S("\x1e\\kgKM@@T\beFN^@H]\0uU[G}XWP]\x16lRYJM\x10\x033-3\x06*>\x11!,="),[S("\x14\x7fgb}kc"),S('1qxr\\XS]K\x15mUXILo\x03#0!j\x0f3-$\x1c"):'),S('"WA]R\x06kblBBIK]\x1feW^DYWC]J\x15~XTJv- %&k\x064(8\v%3b)!;')],function(e,t,n){"use strict";var i=t.extend({name:S('"`VJVeGQ|BIZ'),className:S("6TS_\x17^U\x10]M/1o46$6"),template:n,ui:{cropBox:S("&\tKBL\x06ID\x03LB^B"),cropResize:S(")\x04HGK\x03JY\x1cQA[E\x1bE]JSAY"),cropInfo:S("\r l{w?v}8uewi7rr{q")},events:{"vmousedown @ui.cropBox":S("$JHjG\\YNhBYA"),"vmouseup @ui.cropBox":S("\x10~|^{`erMi"),"vmousedown @ui.cropResize":S("\x1dqqmNWPAaIPFfDyI^GUU"),"vmouseup @ui.cropResize":S(':TRpQJ3$\x173\v+\x14"; 0.')},modelEvents:{change:S("/EAVR@PfXKPNRSS"),"change:keepAspectRatio":function(){if(this.model.get(S("/[TWCuFFR[MhZHTQ"))){var e=this.model.get(S("-\\J^UWA|P_PPM")),t=this.model.get(S("-CNHcW]PPD\x7f]P]SH")),n=this.model.get(S("\x10|skFpxs}kMrxiv")),i=t-this.model.get(S("?2$,'!7\x1f")),r=n-this.model.get(S("\nyicjjbI"));e>i&&(e=i);var o=parseInt(e*n/t,10);o>r&&(o=r,e=parseInt(o*t/n,10)),this.model.set({renderWidth:o,renderHeight:e})}}},onRender:function(){var e;e=this.model.get(S("\x13wtxayj")),this.$el.css({width:this.model.get(S("\x15{v`K\x7fuxxlHIEVK")),height:this.model.get(S(":V]ElZ.%'1\f / ="))}),this.ui.cropBox.css({backgroundImage:S("\x1ejRM\n")+e.toDataURL()+")",backgroundSize:this.model.get(S("=S^8\x13'- 4\x10!->#"))+S("D5>g")+this.model.get(S(":V]ElZ.%'1\f / ="))+S("\x1ble")}),this.updatePosition()},onMouseDown:function(t){var n=this;t.stopPropagation(),e(window).on(S("\n}ab{|u|}eq"),{model:n.model,view:n,moveStart:{x:t.clientX-n.model.get(S("\x12aq{rrjA")),y:t.clientY-n.model.get(S("#V@HCM[s"))}},n.mouseMove),e(window).one(S("&QEF_XIX^"),function(){n.onMouseUp()})},onMouseUp:function(t){t&&t.stopPropagation(),e(window).off(S("C2()2;,'$:("),this.mouseMove)},mouseMove:function(e){var t,n,i,r,o,s,a,l;t=e.data.model,n=e.data.view.ui.cropBox,i=e.clientX-e.data.moveStart.x,r=e.clientY-e.data.moveStart.y,o=n.outerWidth(),s=n.outerHeight(),a=t.get(S('@,#;\x16 (#-;\x1d"(9&'))-o,l=t.get(S('"NE]tBFMOYdHGHXE'))-s,i=i<0?0:i,r=r<0?0:r,i=i>a?a:i,r=r>l?l:r,t.set({renderX:i,renderY:r})},onMouseDownOnResize:function(t){var n=this;t.stopPropagation(),e(window).on(S("$SKH]ZOFC[K"),{model:n.model,view:n,moveStart:{x:t.clientX-n.model.get(S("5DRV]_IkTZK(")),y:t.clientY-n.model.get(S("%TBFMOYdHGHXE"))}},n.mouseResize),e(window).one(S("!TNKPUB]Y"),function(){n.onMouseUpOnResize()})},onMouseUpOnResize:function(){e(window).off(S(";JPQJ3$/,2 "),this.mouseResize)},mouseResize:function(e){var t,n,i,r,o,s;t=e.data.model,n=t.get(S("1_ZZvDXH")),i=e.clientX-e.data.moveStart.x,r=e.clientY-e.data.moveStart.y,o=t.get(S("\x1av}eLzNEGQsLBS@"))-t.get(S(",_KATT@k")),s=t.get(S("B.%=\x14\"&-/9\x04('(8%"))-t.get(S("8K_UXXLf")),r=rR!9\x10&*!#5\x1f .?$"))/t.get(S('o?o:i,r=r>s?s:r,t.set({renderWidth:i,renderHeight:r})},updatePosition:function(){var e=this.model.get(S("\x1co{qDDP{")),t=this.model.get(S("\nyicjjbH")),n=(this.ui.cropBox.outerWidth()-this.ui.cropBox.width())/2;this.ui.cropBox.css({top:t+S("\x14en"),left:e+S("$U^"),width:this.model.get(S("D7#),,8\x1c%):'"))-2*n+S("*[T"),height:this.model.get(S("\x1bnxp{ESjFMBNS"))-2*n+S("=NG"),backgroundPosition:-e-n+S("'XQ\n")+(-t-n)+S("\x10aj")}),this.ui.cropInfo.text(this.model.get(S("$ROC\\A"))+"x"+this.model.get(S("\x14}s~\x7fqn"))),this.ui.cropInfo.attr(S("0USGU\x18U\\^\x14JTOTJV//"),this.model.get("x")+","+this.model.get("y"))}});return i}),CKFinder.define(S("(jamECJJB\x1e\x7f\\P@ZRK\x16\x7f_UIwR!&'l\x10*)+;f\t9#=\x1a ?="),[S("$GGDCKEEI"),S("\x16}il\x7fie"),S("\x0fSZTzzqse7Tu\x7fiq{l\x0fdFJPlKFOL\x05\x7fCBB\\\x1fe]\\X"),S("\x13W^P~v}\x7fi3Pq{UMGP\v`BN\\`GJKH\x01yYTE@\x1bvDXHoS^K"),S("1qxr\\XS]K\x15vSYKS%2m\x06 ,2\x0e%(-.c\x1b'*'\"}\x10&:&\x157!\f29*")],function(e,t,n,i,r){"use strict";return n.extend({defaults:{name:S("'k[E["),viewClass:i,view:null,isVisible:!1},initialize:function(){function n(e){var t,n,i;i=e.get(S("\x14gsy||hLuyjw")),n=e.get(S("#V@HCM[bNEJF[")),t=e.get(S("=WR!&'\x14-!2/"))/e.get(S("\x1erAYpFJACU\x7f@N_D")),e.set(S("\x1ehIEVK"),parseInt(i*t,10)),e.set(S(")BNEJF["),parseInt(n*t,10)),e.set("x",parseInt(e.get(S("!PFJACUp"))*t,10)),e.set("y",parseInt(e.get(S("&UMGNN^t"))*t,10))}function i(){r.get(S("\x1bunHvSH@OA"))&&(r.closeCropBox(),r.openCropBox())}this.viewModel=new e.Model({x:0,y:0,width:0,height:0,renderWidth:0,renderHeight:0,maxWidth:0,maxHeight:0,imageWidth:0,imageHeight:0,keepAspectRatio:!1,tabindex:this.get(S("E2&* $/)5"))}),this.viewModel.on(S('@"*"*"#}:,$/)?\x19&4%:'),n),this.viewModel.on(S("\x1fCICMC@\x1cUMGNN^eKFWYF"),n),this.viewModel.on(S('>\\( ,$!\x7f4"&-/9\x14'),n),this.viewModel.on(S("\rmgq\x7fuv.gsy||hB"),n),this.collection.on(S("2ZYTQR|XNZ\x06O[^$8"),function(){var e,n,i,r,o,s;e=this.get(S("@$&*0\f+&/,\x0e*8,")),s=e.get(S("\x13wt{vv")).renderingCanvas,n=t(s).width(),i=t(s).height(),r=parseInt(n/2,10),o=parseInt(i/2,10),this.viewModel.set({canvas:e.get(S("\rmn}p|")).renderingCanvas,minCrop:10,x:e.get(S("1[^URS`Q]NS")),y:e.get(S("\x0fy|stq]s~\x7fqn")),renderX:parseInt((n-r)/2,10),renderY:parseInt((i-o)/2,10),width:e.get(S("\x0fy|stqB\x7fslq")),height:e.get(S(":RQ\\YZ\b$+$,1")),renderWidth:r,renderHeight:o,maxRenderWidth:n,maxRenderHeight:i,imageWidth:e.get(S("C-(' -\0$-#")).width,imageHeight:e.get(S("1[^URS~V_U")).height}),this.get(S(" WKFS")).on(S("\x10pbcxl"),function(){this.cropView()},this)},this),this.on(S("/UIBRZQ"),this.openCropBox,this),this.on(S('@"-/($64-'),this.closeCropBox,this);var r=this;this.collection.on(S("\x1djpOM\x18QAVCS\x12HL_I_"),i),this.collection.on(S(";IT\x04M%2+9!"),i)},cropView:function(){var e=this.get(S("2VP\\B~UX]^x\\J^")),t=e.get(S("7[XWZR")).renderingCanvas,n=t.width/this.viewModel.get(S("&JIQxNBIK]gXVG\\"));e.get(S('A!")$(')).crop(parseInt(n*this.viewModel.get(S("3FPXS]KmRXIV")),10),parseInt(n*this.viewModel.get(S(';NXP[%3\n&-".3')),10),parseInt(n*this.viewModel.get(S(">M%/&&6\x1d")),10),parseInt(n*this.viewModel.get(S("\v~h`kucK")),10)),this.collection.requestThrottler();var i=!1;e.get(S("-OLDX]]G")).forEach(function(e){e.get(S("E2('%"))===S(";nRJ^4$")&&(i=!i)}),n=(i?e.get(S("\x10x\x7frsp^rq~ro")):e.get(S("\x0fy|stqB\x7fslq")))/this.viewModel.get(S("9WZDo[Q$$0\x14-!2/")),e.get(S("'IJ^BCC]")).push({tool:this.get(S("$KGJM")),data:{width:parseInt(n*this.viewModel.get(S("=LZ.%'1\x13,\"3 ")),10),height:parseInt(n*this.viewModel.get(S("%TBFMOYdHGHXE")),10),x:parseInt(n*this.viewModel.get(S("\x1co{qDDP{")),10),y:parseInt(n*this.viewModel.get(S(" SGM@@T~")),10)}}),this.closeCropBox()},openCropBox:function(){var e=this.get(S("\x18|~rhTs~GDfBPD")).get(S("#GDKFF")).renderingCanvas,n=t(e).width(),i=t(e).height(),o=parseInt(n/2,10),s=parseInt(i/2,10);this.viewModel.set({maxRenderWidth:n,maxRenderHeight:i,renderWidth:o,renderHeight:s,renderX:parseInt((n-o)/2,10),renderY:parseInt((i-s)/2,10)}),this.cropBox=new r({finder:this.collection.finder,model:this.viewModel}),this.cropBox.render().$el.appendTo(t(this.get(S("8\\^RHtS^'$\x06\"0$")).get(S("*HM@OA")).renderingCanvas).parent()),this.set(S("\x1dwlvHQJFIC"),!0)},closeCropBox:function(){this.cropBox&&this.cropBox.destroy(),this.set(S("@(1\x15-6/%$,"),!1)},saveDeferred:function(e,n){var i,r;return i=new t.Deferred,r=i.promise(),n.then(function(t){t.crop(e.width,e.height,e.x,e.y).render(function(){i.resolve(this)})}),r},getActionData:function(){return this.viewModel}})}),CKFinder.define(S("\x17l|bo=^UYIOFFV\nrBEYFJXH]\0uU[G}XWP]\x16hTH\\JZn%-7"),[],function(){return S("7\x04]SM\x1c^R^32\x7fa'. j- g9#9/;5|1<:!$84*w22-++\x13C\\imY\x04\x12\x1c\x1d\x05\x05L\x04\nRR\x12\x19\x15Y\x10\x1fZ\n\x16\x0e\x1a\b\x18S\x1enuk`hjel\x7f`yn.-znrx|wqm+5cb';ui0kACKM@@^\x07UT\b\vHLZN\x1dXQ\\Z\b\x14TS_\x17ISI_K%l.&\"1dg,(>*a$- >!= iw-,gy3/r1?1\x07O\x06\n\x16E[ZHN\x06\x1f\x1eJ\x13\x12\x1c\x14\x14\x07\x0f\x0eIH\x05\x04\b\x12\x1b\x15\n\x04{>\x7f~&;}|5)c\x7f\"aoaw?ww}a_zy~\x7f5nrj~TDcMPLeKGJA\\E^K\x0fML\x0e\x1cV@BCWW\x0415\x01\\J45--d,\"zj*!-a('b\">&2 0{44690+4-:BA\x16\x02\x06\f\b\x03\r\x11WI\x17\x16SO\x19\x05\\\x07\x15\x17\x1f\x19\x1c\x1c\x02[\x01\0\\_d`vb)lehf4(hgk#}\x7fesgq8d~\x7fqn99)#!<21ts03=96:'/.i*%{d '`~6\x14O\x0e\x02\n\x02H\x02\f\0\x1e\"\x01\f\t\n^\x03\x1d\x07\x15\x01\x134\x14\x16\x19\x10\v\x14\r\x1a |\x7f?+gss|fd5\x061!kyg,\x19")}),CKFinder.define(S("%eln@DOI_\x01b_UG_QF\x19r\\PNrQ\\YZo\x17+&36i\x15'=+?)\x1b'*'"),[S("3w~p^V]_I\x13hJV,n\t&=\x06)#-"),S('9ypzTP[%3m\x15- 14g\v+8)b\x07;5<\x04:1"'),S("\x0e{uif2W^P~v}\x7fi3I{rPMCWAV\tbL@^bALIJ\x1fc]GUAS\x19\\VN")],function(e,t,n){"use strict";return t.extend({name:S("+~BZNDTdZQB"),template:n,ui:{clockwise:S('9\x19XW[\x13Z)l0,0$2"e*&$/&9'),antiClockwise:S("#\x07FMA\x05LC\x06^BZNDT\x1fRZA_TTVYPKTMZ")},events:{"click @ui.clockwise":S('B,*\x06*(+"="?('),"click @ui.antiClockwise":S("+CCoADXq_[V]@QJ_"),"keydown @ui.clockwise":function(t){t.keyCode!==e.space&&t.keyCode!==e.enter||this.onClockwise()},"keydown @ui.antiClockwise":function(t){t.keyCode!==e.space&&t.keyCode!==e.enter||this.onAntiClockwise()}},onClockwise:function(){this.model.unset(S(";P\\MK\x12.6\"0,))\t'-')"),{silent:!0}),this.model.set(S("\v`l}{B~fr`|yyYw}wy"),90)},onAntiClockwise:function(){this.model.unset(S("\x0ecqbfA{awcqvtZrzrz"),{silent:!0}),this.model.set(S("B/%62\x15'=+?%\" \x0e>6>6"),-90)}})}),CKFinder.define(S("\x1d]TfHLGAW\tjGM_GI^\x01jTXFzYTQR\x17mUTPN\x11m/5#7!\x11)($"),[S("'BX_N^T"),S("\x1fB@AHFJHB"),S(" bieMKBBZ\x06gDHXBJC\x1ewW]A\x7fZY^_\x14hRQS3n\x16,+)"),S('@\x02\t\x05-+"":f\x07$(8"*#~\x177=!\x1f:9>?t\n4;(\x13N0\f\x10\x04\x12\x02>\0\x0f\x1c')],function(e,t,n,i){"use strict";return n.extend({defaults:{name:S("0c]GUAS"),viewClass:i,view:null,rotationApplied:!1},initialize:function(){function e(){var e=n.get(S("+IIG[y\\STQqWCY")).get(S(">^#5+,*6"));e.remove(e.where({tool:n.get(S("9TZQX"))})),n.viewModel.set(S("\x1e~NFNF"),0),n.viewModel.set(S('"OEVRuG]K_EB@n^V^V'),0)}var n=this;this.viewModel=new t.Model({angle:0,lastRotationAngle:0,tabindex:this.get(S(".[QS[]PPN"))}),this.viewModel.on(S("&D@HDLI\x17BNCE`\\@TB^WW{U[Q["),function(e,t){this.get(S(",HJFDx_RSPrVLX")).get(S("C%&2.''9")).push({tool:this.get(S("\x10\x7fs~q")),data:t}),this.set(S("\x13fzbvlpuu]mnsIDF"),!1),this.collection.requestThrottler()},this),this.collection.on(S("\x1bhulpTUNF"),function(e){this.get(S("A0,0$2.''\v;5p86\f\x15\x07\x11F[lnT\x05\v\t\t\x01N\f\x1c\x10\x01\0IW\x15\x1c\x1eT\x1f\x12Q\x1b\x17\x13tdp.mfii(|c&ny`/ex?q`{;~{vt6pxxk\0TK\x0eMFII\x05RQ\x16\fKGCDT@\x1d]VYY\x18DG\x19\x1c[QM}c98ye .$=/9b#/\"5q/.vk-,ey<20);-N\r\x03\x01\x01\tF\x1a\x15UE\x07\r\x0f\v\x03N{{O\x1d\x1b\x06\x02\fY\x19\x17\x1d\x0e\rB\"bie)`o*n`f\x7fi\x7f#||xvvf76yyt\x7f&>fe\"\0GKOP@T\tFHGN\fPS\r\x10XV\x0e\x16NM\n\x18_SWHXL\x11. /&d8;eh$#%qo54mq4:8!3%v:55:49q\r\b\fC\x19\x18Dma`JKL\0\x0f\x17MS\t\bIU\x10\x1e\x14\r\x1f\tR\x1e\x11\x11fhe-id~'ut(+\x7fyk\x7f-3ih)5p~tm\x7fi2~qqFHE\rWQCW\bTW\t\f[OCET\x0f\x11ON\v\x17^PVOYO\x10\\//$*#k/)!=j61on;)!7nv'79?=."),S("\x1djzXU\x03`ocOILLX\x04xHC_\\PFVG\x1asSQMsV]Z[\x10\x01%(671h#'=")],function(e,t,n,i){"use strict";var r=100;return n.extend({isSliding:!1,applyFilterInterval:null,lastFilterEvent:null,name:S("5wSRLIOjT[H"),template:i,events:{"slidestart .ckf-ei-filter-slider":S(",B@|\\XVVgAWEL"),"slidestop .ckf-ei-filter-slider":S('@.,\x10(,""\x1b=%;'),"change .ckf-ei-filter-slider":S("$JHaAE^N^"),"keyup .ckf-ei-filter-slider":S("\x1crpYIMVFV")},initialize:function(){this.model.get(S("%GD\\@\\NjDB[UCA")).on(S("([OXIY"),function(){this.render()},this)},onSlideStart:function(){this.isSliding=!0},onSlideStop:function(e){this.isSliding=!1,this.applyFilters(e)},onRender:function(){this.$el.trigger(S(">\\2$#7!"))},onFilter:function(e){var t=this;t.isSliding||(this.lastFilterEvent=e,this.applyFilterInterval||(this.applyFilterInterval=setInterval(function(){Date.now()-t.lastFilterEvent.timeStamp>100&&(t.applyFilters(t.lastFilterEvent),clearInterval(t.applyFilterInterval),t.applyFilterInterval=null)},r)))},applyFilters:function(n){var i,r,o;o=this.model.get(S("\x15wtlpl~ZtrkESQ")),r=e(n.currentTarget).data(S("@'+/0 4")),i=o.where({filter:r})[0],i||(i=new t.Model({filter:r}),o.push(i)),i.set(S(">I!-7&"),e(n.currentTarget).val())}})}),CKFinder.define(S('+ofhF^UWA\x1bxYSMU_H\x13xZV4\b/"# i\x13\'&&8c\f*%%"&\x07;::'),[S("0[CFQGO"),S("\x17zxyp~rpz"),S("6BV]_IO^QM%"),S("E\x05\f\x0e $/)?a\x02?5'?1&y\x12<0.\x121<9:O5\r\f\b\x16I3\x07\x06\x06"),S('*hgkGATT@\x1cyZRBT\\I\x14yYWK\t,#$!j\x10.->9d\r)$:#%\x04:1"')],function(e,t,n,i,r){"use strict";return i.extend({defaults:function(){var e=this.collection.finder.config,t=[{name:S('?"3+$,1(";:'),icon:S("1QXR\x18TEQ^RORXML"),config:{min:-100,max:100,step:1,init:0}},{name:S("\x12p{{beyjn"),icon:S("\x0fszt>wzxcjxio"),config:{min:-100,max:100,step:1,init:0}},{name:S("/CPFFFTB^WW"),icon:S(" BIE\tVGS][K_EB@"),config:{min:-100,max:100,step:1,init:0}},{name:S("\x13b|teywy~"),icon:S(':XW[\x13I)#0"*&#'),config:{min:-100,max:100,step:1,init:0}},{name:S("\x1ezXQMPQWC"),icon:S("$FMA\x05LR[C^[]U"),config:{min:-100,max:100,step:1,init:0}},{name:S(",E[J"),icon:S("\nhgk#get"),config:{min:0,max:100,step:1,init:0}},{name:S("3GPF^Y"),icon:S("?#*$n7 6.)"),config:{min:0,max:100,step:1,init:0}},{name:S("\x0ehq|\x7fr"),icon:S("\x1c~uy\rFCNID"),config:{min:0,max:10,step:.1,init:1}},{name:S("2][\\ER"),icon:S("\x1c~uy\rOMJW@"),config:{min:0,max:100,step:1,init:0}},{name:S("\x19ywum"),icon:S("E%,.d)'%="),config:{min:0,max:100,step:1,init:0}},{name:S('A1+%76"&'),icon:S("\x1e|KG\x0fPLDTWMG"),config:{min:0,max:100,step:1,init:0}},{name:S("8JNZ_V|S53"),icon:S("7[R\\\x16^QKM"),config:{min:0,max:20,step:1,init:0}}],i=n.filter(t,function(t){return n.contains(e.editImageAdjustments,t.name)});return{name:S("<|ZU526"),viewClass:r,view:null,filters:i}},initialize:function(){function e(){var e=n.get(S('q1?5&%jz:1=q87r\x10\x13\x07\x10\x01\x11DG\f\b\x1e\nA\x1d\x1c\n\x03\x14\x06NV\x0e\rJX\t\b\x1e\x0f\x18\nQn`of$x{%(}kiecjjh,0ho(6~l7nz~tp{EY\x02^Y\x07\x18-!\x15CFK\rMCQBA\x0e\x16V]Q\x15\\S\x16LO[L%5o36 0.->hk-!:rr*)nt%$2+<.u0<<:\fA\x1f\x1eFEIYH\x12\x11VL\x1d\x1c\n\x03\x14\x06]\x18\x14\x14\x12\x14Y\x07\x06vAQ\x1duuvlj;\f|swwv\x06")}),CKFinder.define(S("?\x03\n\x04**!#5g\x04%/9!+<\x7f\x146: \x1c;6?\0\x0f\x1c"),[S("5CY\\\\HH_RLZ"),S("+F\\[JBH"),S("=}t\x06(,'!7i\x12< &d\x07(7\f?57"),S("%eln@DOI_\x01yYTE@\x1bwWD]\x16sOYPhV%6"),S("&SMQ^\nofhF^UWA\x1baSZHU[OYN\x11z$(6\n)$!\"g\x198.?(:<~5='")],function(e,t,n,i,r){"use strict";var o=240,s=80;return i.extend({name:S("6gJ\\I^HNhV%6"),template:r,events:{"click .ckf-ei-preset":S("\x19uuLo{lEU"),"keydown .ckf-ei-preset":function(e){e.keyCode!==n.space&&e.keyCode!==n.enter||this.onPreset(e)}},onRender:function(){function n(){if(d.length){var e,r;e=t(d.shift()),r=e.data(S("\x12cfperl")),l("#"+u,i,function(){this.revert(!1),this[r]().render(function(){e.find(S("\x10x\x7ft")).attr(S("\x19ii\x7f"),this.toBase64()),n()})})}else c.remove()}var i,r=this.model.get(S("\x15p~t|"));if(this.finder.config.initConfigInfo.thumbs){var a;e.forEach(this.finder.config.initConfigInfo.thumbs,function(e){var t=parseInt(e.split("x")[0]);!a&&t>=o&&(a=t)}),a&&(i=this.finder.request(S("6QQU_\x01[XJk(4/!"),{file:r}))}i&&this.finder.config.initConfigInfo.thumbs||(i=this.finder.request(S("!KNEBC\x1dX[O]EHYzB]"),{file:r,maxWidth:o,maxHeight:s,noCache:!0}));var l=this.model.get(S("<~_R!/")),u=e.uniqueId(S("4V]Q\x15")),c=t(S("B\x7f'$(1):t")).attr(S("\x15\x7fs"),u).attr(S("2D]QB_"),o).attr(S("\x0eguxu{`"),o).css(S("D!/48%+2"),S("\x0f~~|v")).appendTo(S("%DHLP")),d=this.$el.find(S("4\x1bU\\^\x14_R\x11MLZ3$6")).toArray();n()},onPreset:function(e){this.model.set(S("5WTLPL^"),t(e.currentTarget).data(S("/@CW@QA")))}})}),CKFinder.define(S('1qxr\\XS]K\x15vSYKS%2m\x06 ,2\x0e%(-.c\x19! <"}\x03&0%2,*\x0e431'),[S("@+36!7?"),S("#QKBBZZID^H"),S("%DFKBHDBH"),S("4v}qQW^^N\x12sP$4.&7j\x03#!=\x03&-*+`\x04>=?'z\x02875"),S("5u|~PT_YO\x11r/%7/!6i\x02, >\x02!,)*\x7f\x07;6#&y\x07*<)>(.\b6\x05\x16")],function(e,t,n,i,r){"use strict";return i.extend({defaults:function(){var e,n,i;return e=this.collection.finder.config,n=[{name:S("A!/%7/31")},{name:S("\x0el\x7f\x7fqvzadvl|")},{name:S("\x1c~lpSRrQKFCT[")},{name:S("5Q[WNSU[nKQ")},{name:S("-I]E_UJ")},{name:S("7PX@Bx\\GL")},{name:S("C, +.&.=*5")},{name:S("C, 4\n)#/884")},{name:S("@+#150#4")},{name:S("&KGDE")},{name:S(".C_GW")},{name:S("@/-00$* !(")},{name:S("!MO@gIH\\")},{name:S("\x14zdvv~\x7fKyxr")},{name:S("$UOI@FFN")},{name:S("I)/6"# ')}],i=t.filter(n,function(n){return t.contains(e.editImagePresets,n.name)}),{name:S("\r^}ubwgg"),viewClass:r,view:null,presets:i}},initialize:function(){function e(){var e=t.get(S("3QQ_CqT[\\Yy_K!")).get(S("C%&2.''9"));i.set(S("\x15wtlpl~"),null),e.remove(e.where({tool:t.get(S("\x12}uxs"))}))}var t=this,i=new n.Model({Caman:this.get(S('"`EHGI')),active:null,presets:this.get(S("\r~}ubwgg")),tabindex:this.get(S("(]KIECJJH"))});i.on(S("&D@HDLI\x17OLDXDV"),function(e,n){var i,r;n&&(t.collection.resetTool(S("$dBM]Z^")),i=t.get(S('? ("),function(e){var n=t.viewModel.get(S("E'$< <."));n&&e[n]()}),t.collection.on(S("\vxbac*cw`qa,")+t.get(S("\x15xvu|")),e),t.collection.on(S("'\\FEG\x16_K\\UE\bRXY"),e),this.on(S('5U_YW]^\x06XZV4\b/"# \x02&<('),function(e,t){i.set(S(" GKOA"),t.get(S("?&(.&")))}),this.viewModel=i},saveDeferred:function(t,n){var i,r;return i=new e.Deferred,r=i.promise(),n.then(function(e){e[t]().render(function(){i.resolve(this)})}),r},getActionData:function(){return this.viewModel}})}),CKFinder.define(S(';HXFKa\x02\t\x05-+"":f\x1e.!=".$4!|\x111?#\x114;<9r\f:\x13\b\x18\x06J\x01\t\x13'),[],function(){return S('-\x12KYG\x12PXTED\x05\x1bOR\x11ZLV$l#azOO{, /4$:M\x02\r\r\x10\x17\t\v\x1bD\x03\x05\x1c\x18\x1a\x1cROxz}I\x1f\x19\b\f\x0e[\x12\x1c\x13\x1a=#ahbWctaso\\eizg21drx`s*:ba&iAMWF\x19\x07]\\\x15\tC_\x02IG\\@]SJ|P_PPM\x1aFA\x1f\x1eK!#+- >zj21vl$:a$00::13/x$\'ybWWV\\\x11B\0\b\x04\x15\x14UK\t\0\n@\v\x06]\x03\x17\0\x1d\x0f\x13Z\x1b\x16\x14\x0f\x0e\x12\x12\f-ug{p\'8|s4*bx#bn~v523y3>*3%\x002 <9w%$939>5:\x04\\@\0\f\0\x05\f\r\rH\x10\x17R\x13\x12P\x15\x13\x07\x15X\x1f\x14\x17\x17\n\x14\x0f@\\\x04{>"jp+jffn$oe\x7f.2-15\x7f`g1jeu\x7f}hfe \x1f\\_QMBNSSR\x15VQ\x0f\x10%\f\x1e^RVPZ\t2\x05XNHIQQ`(&~f&-!e,#f>(=&*4\x7f2$%:.zy.:>40;\x05\x19_A\x1f\x1e[G\x01\x1dD\x1f\r\x0f\x07\x01\x14\x14\nS\t\bTW\x1c\x18\x0e\x1aQ\x14\x1d\x10n< `oc+saja),io{q<{p{{fxk$8`g">vT\x0fNBJB\bCA[\n\x16\x11\r\tCDC\x15NIYSQLBA\x04\x03@CM)&*7?>y:5kt07pn&$\x7f>2:2x2<0.\x121<9:N\0\x12\x13\b\x1cF\x1a\x15UE\t\x19\x19\x1a\0\x1eOx')}),CKFinder.define(S("0ryu][RRJ\x16wTXHRZ3n\x07'-1\x0f*)./d\x1a$+8#~\x006'<,2\x0e0?,"),[S("\vOFHf~uwa;@b~t6Q~e^q{E"),S("\x14V]Qqw~~n2HvEVQ\ffDUB\x07`^NA{GJG"),S(" UG[P\x04eln@DOI_\x01{U\\B_UASD\x17|^RHtS^'$m\x11!6/=-g.$8")],function(e,t,n){"use strict";return t.extend({name:S("\x1bNxmvZDtJAR"),template:n,className:S(';_VX\x12%(o1!6/=-d)$"9< <"'),ui:{width:S(';USNJ4\x1a,") {e+",\x19)>\'55\x06;7 =t\n'),height:S("6^VIOOgS_R%|` /#\x14\"; 0.\x04('(8%p\x0e"),keepAspectRatio:S("\x1dwqPTVxJDKB\x15\vI@J\x7fK\\YKWxQPFvKI_XHo_K).`\x1e"),apply:S("\x146u|~4\x7fr1o{lI[G\x0eEUVKQ")},triggers:{"click @ui.apply":S("\ro\x7f`}k")},events:{"change @ui.width":S("%II\x7f@N_D"),"change @ui.height":S("2\\Z}S^_QN"),"change @ui.keepAspectRatio":S("D*(\x06;9/(8\x1f/;9>"),"keyup @ui.keepAspectRatio":function(t){t.keyCode!==e.space&&t.keyCode!==e.enter||(t.preventDefault(),t.stopPropagation(),this.ui.keepAspectRatio.prop(S("\x1b\x7fu{|KDF"),!this.ui.keepAspectRatio.is(S(".\x15SYWP_PR"))).checkboxradio(S("\x1dlzFSGPL")).trigger(S("7[Q[U[X")))},"keydown @ui.apply":function(t){t.keyCode!==e.space&&t.keyCode!==e.enter||this.trigger(S("\x0fqab\x7fm"))}},modelEvents:{"change:realWidth":S(">M%/&&6"),"change:displayWidth":S("$VCS\x7f@N_D"),"change:displayHeight":S(":HYIvZ)&*7")},onRender:function(){this.$el.trigger(S("%EUMH^N"))},onAspectRatio:function(){var e=this.ui.keepAspectRatio.is(S("6\r[Q_XWXZ"));this.model.set(S("@*'&4\x0457-*>\x19-9' "),e),e&&this.onWidth()},onWidth:function(){if(!this.dontRender){var e=this.model.get(S("@%+04)'>\x1f .?$"));if(!(e<0)){var t=parseInt(this.ui.width.val(),10);(isNaN(t)||t<=0)&&(t=1);var n=this.model.get(S("#V@GK\x7f@N_D"));t>n&&(t=n);var i=this.model.get(S("+HD]_\\PK{Q\\Q_L"));if(this.model.get(S('"HA@Vf[YOHX\x7fO[Y^'))){var r=n/this.model.get(S("2AQTZ\x7f]P]SH"));i=parseInt(t/r,10)}i<=0&&(i=1),this.updateSizes(t,i)}}},onHeight:function(){if(!this.dontRender){var e=this.model.get(S("\x1e{IRROE\\nBANB_"));if(!(e<0)){var t=parseInt(this.ui.height.val(),10),n=this.model.get(S(">M% .\v!,!/<"));(isNaN(t)||t<=0)&&(t=1),t>n&&(t=n);var i=this.model.get(S(".KYBB_ULa^\\MR"));if(this.model.get(S("%MBMYkX\\HM[bPFZ["))){var r=this.model.get(S(".]UP^d]QB_"))/n;i=parseInt(t*r,10)}i<=0&&(i=1),this.updateSizes(i,t)}}},updateSizes:function(e,t){this.model.set({displayWidth:e,displayHeight:t}),this.dontRender=!0,this.ui.width.val(e),this.ui.height.val(t),this.dontRender=!1},setWidth:function(){this.ui.width.val(this.model.get(S("\x10u{`dywnOp~ot")))},setHeight:function(){this.ui.height.val(this.model.get(S("\x1fDHQSHD_oM@MCX")))},focusButton:function(){this.ui.apply.focus()}})}),CKFinder.define(S("'kblBBIK]\x1f|]WAYSD\x17|^RHtS^'$m\x17+**4g\x1b/8%7+\x1b?>>"),[S("+F\\[JBH"),S("+NLMDR^\\V"),S("6ts\x7fSUXXL\x10\r.&6( 5h\r-#?\x05 /(5~\x06<;9%x\f657"),S("\x1c^UYIOFFV\nkHL\\FN_\x02kKYE{^URS\x18nP_LO\x12lZ3(8&\x12,#0")],function(e,t,n,i){"use strict";var r=t.Model.extend({defaults:{realWidth:-1,realHeight:-1,displayWidth:-1,displayHeight:-1,renderWidth:-1,renderHeight:-1,maxRenderWidth:-1,maxRenderHeight:-1,keepAspectRatio:!0}});return n.extend({defaults:{name:S(")xN_DTJ"),viewClass:i,view:null},initialize:function(){this.viewModel=new r({tabindex:this.get(S("\x1fT@@JJAC_"))}),this.collection.on(S("\x15\x7fzy~\x7f_}i\x7f%RDCG]"),function(){ +var e=this.get(S(",HJFDx_RSPrVLX"));this.viewModel.set({realWidth:e.get(S("C-(' -\x1e#/8%")),realHeight:e.get(S("\x17qt{|yU{vGIV")),displayWidth:e.get(S("4\\[V_\\mRXIV")),displayHeight:e.get(S("E/*)./\x03)$)'$")),renderWidth:e.get(S("\x1emEOFFVrOC\\A")),renderHeight:e.get(S("E4\"&-/9\x04('(8%")),maxRenderWidth:e.get(S("2AQ[RRJnS_HU")),maxRenderHeight:e.get(S(")XNBIK]xT[T\\A"))}),this.get(S("$SOB_")).on(S("\x1e~PQNZ"),function(){this.resizeView()},this)},this),this.collection.on(S("%RHGE\x10YI^K[\nP^_"),function(){var e,t;e=this.get(S(")OOEYgBQVWwUAW")),t=e.get(S("\x11{~urs^v\x7fu")),this.viewModel.set({realWidth:t.width,realHeight:t.height,displayWidth:t.width,displayHeight:t.height,renderWidth:e.get(S("'ZLDOI_yFTEZ")),renderHeight:e.get(S("2AQ[RRJq_R[UJ")),maxRenderWidth:e.get(S("1@VZQSEoP^OT")),maxRenderHeight:e.get(S("\x14gsy||hSytywT"))})},this)},resizeView:function(){var e,t,n,i=this.viewModel,r=this.get(S("+IIG[y\\STQqWCY")),o=i.get(S("8]SHLQ_F\x17(&7,")),s=i.get(S("5R^KIVZEu[V')6")),a=i.get(S(".BQI`VZQSEoP^OT")),l=i.get(S("\rcnhCw}ppd_}p}sh"));s>l||o>a?(e=s>o?l/s:a/o,t=parseInt(e*s,10),n=parseInt(e*o,10)):(n=o,t=s),i.set({realWidth:o,realHeight:s}),r.get(S(" @AWMJHT")).push({tool:this.get(S("\nem`k")),data:{width:o,height:s}}),r.set({imageWidth:o,imageHeight:s}),r.get(S(":X]P_Q")).resize({width:n,height:t}),this.collection.requestThrottler(),this.get(S("\x15`~}n")).focusButton()},saveDeferred:function(t,n){var i=new e.Deferred,r=i.promise();return n.then(function(e){e.resize({width:t.width,height:t.height}).render(function(){i.resolve(this)})}),r},getActionData:function(){return this.viewModel}})}),CKFinder.define(S('/sztZZQSE\x17tU_IQ[Lo\x04&*0\f+&/,e\x1f#""<'),[S("B6*!#5;*%9)"),S("\vf|{jbh"),S("\x12quv}uww\x7f"),S("\fNEIy\x7fvvf:[x|lv~o2[{IUkNEBC\b|FEG_\x02m]_Af\\[Y"),S('"`ocOILLX\x04aBJZ\\TA\x1cqQ_CqT[\\Y\x12jP/-1l\x16*2&<,\x1e$#!'),S("\x1d]TfHLGAW\tjGM_GI^\x01jTXFzYTQR\x17mUTPN\x11~$+700\x11)($"),S("\rMDVx|wqg9Zw}owyn1ZDHVjIDAB\x07}ED@^\x01\x7fBTAV@FbXWU"),S("7{r|RRY[Mo\f-'1)#4g\f.\"8\x04#.74}\x07;::$w\v?(5';\v\x0f\x0e\x0e")],function(e,t,n,i,r,o,s,a){"use strict";return n.Collection.extend({initialize:function(){this.needRender=!1,this.isRendering=!1,this.on(S("*JHI"),function(e){e.set(S("\x17vxw~"),e.get(S("A6,+)")).get(S("6YYT_")))})},setupDefault:function(t,n){this.finder=t,this.Caman=n;var l=40;this.add({title:t.lang.editImage.resize,icon:S("1QXR\x18DRKP@^"),tool:new a({tabindex:l},{collection:this}),tabindex:l}),this.add({title:t.lang.editImage.crop,icon:S(")I@J\0M]_A"),tool:new i({tabindex:l+=10},{collection:this}),tabindex:l}),this.add({title:t.lang.editImage.rotate,icon:S("#GN@\nZF^JXH"),tool:new r({tabindex:l+=10},{collection:this}),tabindex:l});var u=t.config.editImageAdjustments;if(u&&u.length){var c=new o({tabindex:l+=10},{collection:this});this.add({title:t.lang.editImage.adjust,icon:S("!AHB\bGCB\\Y_"),tool:c,tabindex:l}),e.forEach(c.get(S("\vjdb{uca")),function(e){e.label=t.lang.editImage.filters[e.name]})}var d=t.config.editImagePresets;if(d&&d.length){var f=new s({Caman:n,tabindex:l+=10},{collection:this});this.add({title:t.lang.editImage.presets,icon:S("+OFH\x02@CW@QAE"),tool:f,tabindex:l}),e.forEach(f.get(S("1BAQFSCK")),function(e){e.label=t.lang.editImage.preset[e.name]})}return this},setImageData:function(e){this.editImageData=e,e.on(S(".LXP\\TQ\x0fDRV]_ItXWX(5"),function(){this.checkReady()},this),this.forEach(function(t){t.get(S("\x1bhrqs")).set(S("(LNBXdCNWTvR@T"),e)})},setImageInfo:function(e){this.editImageData.set(S("\x1dwrAFGjJCI"),e),this.editImageData.set(S('D,+&/,\x1d"(9&'),e.width),this.editImageData.set(S("5_ZY^_sYTYW4"),e.height),this.checkReady()},checkReady:function(){this.editImageData&&this.editImageData.has(S("B*)$!\"\x01',$"))&&this.editImageData.has(S("#V@HCM[}BHYF"))&&this.trigger(S("\fdcnwtVr`t,e}x~b"))},resetTool:function(e){var t;e?this.trigger(S(";HRQSz3'0!1|")+e):(this.trigger(S("\x0e{\x7f~~)fperl#{wp")),t=this.editImageData.get(S("\x1e|ALCM")),t.reset(),t.render(),this.editImageData.get(S('?!"6*++5')).reset()),this.trigger(S("\fya`|+`vgpb-y\x7fn~n"))},doSave:function(n){var i=this,r=e.uniqueId(S('"F@LR\nADKLI\0MN^GS@')),o=t(S("'\x14JKEZL]\x11")).attr(S("\x16~|"),r).css(S("&CAZZGMT"),S("$KIIM")).appendTo(S("E$(,0")),s=this.editImageData.get(S("\x11sp`|yyk")),a=this.Caman,l=new t.Deferred,u=new t.Deferred,c=l.promise();return a("#"+r,n,function(){var e=this,t=s.findWhere({tool:S("'iM@^_Y")});t&&(s.remove(t),s.push(t));var n=s.findWhere({tool:S("\x0e_btav`f")});n&&(s.remove(n),s.push(n)),s.forEach(function(e){var t=this.findWhere({name:e.get(S("\n\x7fcbb"))}).get(S("\x16cwvv"));c=t.saveDeferred(e.get(S("\x1fD@VB")),c)},i),c.then(function(){u.resolve(e.toBase64()),o.remove()}),l.resolve(e)}),u.promise()},requestThrottler:function(){var e=this;this.needRender=!0,this.throttleID||(this.throttleID=setInterval(function(){if(e.needRender&&!e.isRendering){e.isRendering=!0;var t=e.editImageData.get(S("\x13wt{vv"));try{t.revert(!1)}catch(e){}e.trigger(S("+XE\\@DE^V"),t),t.render(function(){return!1}),e.isRendering=!1,e.needRender=!1}},200))},destroy:function(){this.throttleID&&clearInterval(this.throttleID)},hasDataToSave:function(){return!!this.editImageData.get(S("\x1b}~jvOOQ")).length}})}),CKFinder.define(S("A\x01\b\x02,(#-;e\b# # >~\x1f<00:$w\t(4;/;,\x13,\r\x07\x01\t"),[S("9XZ_V\\P.$")],function(e){"use strict";var t=e.Model.extend({defaults:{state:S("\x14z}"),message:"",value:0},stateOk:function(){this.set(S("\x18jnzhx"),S("4Z]"))},stateError:function(){this.set(S(".\\DPFV"),S("\x1d{mRNP"))},stateIndeterminate:function(){this.set(S(">L4 6&"),S("3][RRL\\HVUS_K%"))}});return t}),CKFinder.define(S("*hgkGATT@\x1cyZRBT\\I\x14yYWK\t,#$!j\v(,,&8c\x1d< 7#7 '\x1893=5"),[S("!ahbLHCM[\x05hC@C@^\x1e\x7f\\PPZD\x17iHT[O[L3\f-'!)")],function(e){"use strict";var t=e.extend({defaults:{value:0,state:S("3[^"),message:"",eta:"",speed:"",bytes:0,bytesTotal:0,time:0,transfer:""},initialize:function(){this.on(S("\x1b\x7fu\x7fqGD"),function(e){var t,n;if(e.changed.time&&(t=e.previous(S("!VJI@")))){var i=e.get(S(",YGBU"))-t,r=e.get(S("*IUYK\\"))-e.previous(S("D'?3-:"));n=(r/i).toFixed(1),this.set({eta:((e.get(S("\rlvdtaG{aw{"))-e.get(S('C&<2";')))/(100*n)).toFixed(),speed:n})}})}});return t}),CKFinder.define(S("\x18m\x7fch<]TfHLGAW\tsMDZGMYK\\\x1fr]^YZX\x18hKU\\NXMLn%-7"),[],function(){return S("(\x15NBZ\rMCQBA\x0e\x16V]Q\x15IHT[O[L3l/&76' -i10smo&$\x7f?6'&70=y'&?68r\b\b\x06\x07\x01\v\x1d\x1cW\x14\x17IR\x16\x15RP\x18\x06]\x19\x10\x05\x04\x19\x1e\x1f[\x01\0BPdht=\x0e9bn~)igm~}22ryu9edx\x7fk\x7fho0imAQ\x02@OC\vWZFMYI^]\x02KJ\x0f\x13]A\x18DLXN^\x1c@C\x1d`3-/!xd7:&-9)>=-1#ps5'?6u/;7)800\x17\\@\x18\x1fXF\x0e\x1cG\x1c\n\0\x18\vO\r\fPS\x15\x07\x1f\x16U\x0f\x1b\x17\t\x18\x13\x16n< 3&%guah'}ma{j}pj.6$&':'\x10\x12 ywi\0BNBWV\x1b\x05KBL\x06\\_AHBTA@\x19WWE\x1a\x19IOEQ[\x02b6+'0-|<3tj\"8c8.<$7s)(slzydgs97)^k^L\0\f\x10Yb")}),CKFinder.define(S('B\0\x0f\x03/),,8d\x0f"#"??}\x05=0!$w\t(4;/;,\x137\v\x06\x13'),[S("\nHGKgatt`"),modelEvents:{"change:message":S("\x0feavr`p[rkj{|y"),"change:state":S("$PVCI]OxXLZJ"),"change:value":S("3AERVL\\lZPH[")},ui:{bar:S('"\rGN@\nX[EL^H]\\\x1dSSA'),message:S('Dk%,.d:9#*<*#"\x7f>1&%6?<'),wrap:S(".\x01SZT\x1eDGYPJ\\IH\x11JL^0")},onRender:function(){this.$el.trigger(S(">\\2$#7!"))},updateMessage:function(e,t){this.ui.message.text(t).toggleClass(S("\x14v}q5qs\x7fxxp"),!t)},updateState:function(e,t){this.ui.wrap.toggleClass(S("6TS_\x17KNRYM%21n+."),t===S("\x0f\x7fz")).toggleClass(S("/SZT\x1eDGYPJ\\IH\x11XLM/3"),t===S("6RJKUI")).toggleClass(S('5U\\^\x14JISZLZ32o**!#3-;\'"",:*'),t===S("0X\\WQASEUPTZHX"))},updateValue:function(e,t){this.isDestroyed||(this.ui.bar.css({width:t+"%"}),this.ui.wrap.attr(S("\x1b}ow~\rWCOQ@HH_"),t))}});return n}),CKFinder.define(S("3@PNC\x19zq}USZZ2n\x16&)5*&<,9d\t)';\x19<341z\x06%7>(>/.\x1a6\x01\r\r\x04J\x01\t\x13"),[],function(){return S("\x11.w}c6~|$8xw{3zI\fRQKBTB[Z\b\x15\x10\x02JFF\x0f8\x0fP\\@\x17[U[HO\0\x1c\\+'o&-h25)'9-)?lq+*os=!x#*84(:8,\x7f\x1d\x1c^L\0\f\x10Ybc")}),CKFinder.define(S('8zq}USZZ2n\x0f, 0*";f\x0f/%9\x07"167|\x02<3 +v\n)3:,:\x13\x12&\n\x05\t\t\0>\0\x0f\x1c'),[S("\r{att``wzdr"),S("$OWRM[S"),S('@\x02\t\x05-+"":f\x1c"):=`\x120!6{\x197.7,.\r58)'),S('3w~p^V]_I\x13~QR-.,l\x12,#0;f\x1a9#*<*#"\x04:1"'),S(':OYEJ\x1e\x03\n\x04**!#5g\x1d/&s\r,0\x07\x13\x07\x10\x17!\x0f\x06\x04\x06\rE\b\x02\x1a')],function(e,t,n,i,r){"use strict";var o=n.extend({name:S(")oOEYgBQVWcFZQE]JI\x7fU\\RP'\x17+&3"),template:r,regions:{progress:S("\x199xw{3zI\fRQKBTB[Z")},ui:{transfer:S("\x0e!szt>q|;cjxthzxl")},modelEvents:{change:S("7MI^ZHXjM!/1%!7")},onRender:function(){this.$el.trigger(S("E%5-(>.")),this.progress.show(new i({finder:this.finder,model:this.model}))},updateTransfer:function(){this.ui.transfer.text(this.model.get(S('@50"*6 ":')))}});return o}),CKFinder.define(S('@\x02\t\x05-+"":f\x07$(("<\x7f\x17;?1'),[S("4WWTS[UUY")],function(e){"use strict";var t=e.Model.extend({defaults:{name:"",date:"",size:-1,folder:null,"view:isFolder":!1},initialize:function(){this._extenstion=!1,this.on(S("\x1e|H@LDA\x1fHFEL"),function(){this._extenstion=!1},this)},getExtension:function(){return this._extension||(this._extenstion=this.constructor.extensionFromFileName(this.get(S("!LBI@")))),this._extenstion},getUrl:function(){if(!this.has(S("\x18lhw"))){var e=this.get(S("<[QS$$0")).getUrl();this.set(S("\x0ezb}"),e&&e+encodeURIComponent(this.get(S(")DJAH"))),{silent:!0})}return this.get(S("A71("))},isImage:function(){return this.constructor.isExtensionOfImage(this.getExtension())},refresh:function(){this.trigger(S("\x1dlzFSGPL"),this)}},{invalidCharacters:S("6=d\x19\x15\x1b\x06\x1d\x14\x1f\x7fa`cxexg4"),isValidName:function(e){var t=/[\\\/:\*\?"<>\|]/;return!t.test(e)},isExtensionOfImage:function(e){return/jpeg|jpg|gif|png/.test(e.toLowerCase())},extensionFromFileName:function(e){return e.substr(e.lastIndexOf(".")+1)},trimFileName:function(e){var t=e.lastIndexOf(".");return t<0?e.trim():e.substr(0,t).trim()+"."+e.substr(t+1).trim()}});return t}),CKFinder.define(S("\x19n~di?\\kgKM@@T\b|LG[@LZJC\x1ewW]A\x7fZY^_\x14\x7fRPY)3/\x07-$*(/g.$8"),[],function(){return S("1IH\v\x15\x17^L\x17UUPDqI%351-1#g54v'-/+#n[rstu-,ey3/r1?1\x07O\x07\x07\r\x11/\n\t\x0e\x0fE\x1f\f\x18\n4\x18\x13\x1f\x1b\x129\x01\x1d\v\r\t\x15\t\x1b_}|\b\n8lhw}}*\x7fmogattj.6$47l`j~!?}wEBIAK]\x04\x07FHGN\x11\x0fMDVtVZ@|[V_\\uMYOIM)5'ad>=xh >e#;+='#;'1u+*;1?878:bB\x02\n\x06\x07\x0e\x03\x03J\x12\x11T\x11\x10PeL^\x1e\x12\x16\x10\x1aIr\x02\x01D\x01\0tCdht#gigt{4(meakaq|w>}{fbl4{iy|?\0\x1dQSEK\x06DDHYX\x11\x0fHF\\T\\RYP\x1bR@M_UOTQQm-#!!)dyf21jl$:a5)&6:&?86y'&`r-/\x01\x0f\\iDEFGHIJKP\t\x07\x19P\x12\x1e\x12\x07\x06KU\r\x10W\x12\x12\r\v\v-ug{p%sn%keou gaxt`z`5c~5zuirxl2AMN\x03QL\vT@HND[\0GACTF\x11\n?\x16\x17\x18\x1932\0TPO55b7%'/),,2vn|lo40&2y08?979>8`|+\x12\x14\x07AD\x11\x1f\x17\rTH\x1f\t\x15\x1aMP\x1f\x13\x1e\x11HT\x14\x13\x1f?\x1f\x15\t7\x12afgEmicIido),{ocet/1on77qm4u}p{?]\\\0\x03EWOF\x05[OZYD\\JT\f\x10GF@S\x15\x18]SI\x01\x1f_J4.`ck{Lghijklmns\x7f5;%j_vwxyft84(ajkBCDEZ\x17H\n\x06\n\x1f\x1eSM\x13\x1a\x14^\x11\x1c[\x14\x17\x17\x1c\x12\x0e\x10S\x1arsmq$`tug{'fi~}nwt0-(:f)\x12%5\x7fuk \x15")}),CKFinder.define(S("C\x07\x0e\0.&-/9c\0!+%=7 {\x102>,\x107:;8q\t\t\x04\x15\x10K&\t\t\x0e\0\x18\x06(\x04\x0f\x03\x1f\x16$\x1a\x11\x02"),[S("\vOFHf~uwa;C\x7froj5Y}n{0iUGNrLCP"),S("D\x06\r\x01!'..>b\x03 44> {\x13?;="),S("3@PNC\x19zq}USZZ2n\x16&)5*&<,9d\t)';\x19<341z\x1586?3)1\x197>\f\x0e\x05M\0\n\x12")],function(e,t,n){"use strict";return e.extend({name:S("D\0\".<\0'*+(\r >7;!9\x11?646="),template:n,className:S("\x1e|KG\x0fFM\bEUGY\x07HCCZ]_]A"),ui:{error:S("!\f@OC\vBA\x04IDBKG]]\x1cWAFZD"),overwrite:S("\rga`dfHzt{r%;ypzXzvThOBC@iQM[]YEYK\rm"),fileName:S("\x1arrmkk{OCNA\x18\x04DCOoOEYgBQVWu]YSyYT_\x19a"),fileNameInputArea:S("Dk .$,$*!(c&>!''y4$29")},events:{"change @ui.overwrite":function(e){e.stopPropagation(),e.preventDefault();var t=this.ui.overwrite.is(S(")\x10HDHMDUU"));t?(this.model.set(S("@/#.!"),this.model.get(S("\x17wks|us\x7fsn@OF"))),this.model.unset(S("\x1ezRSMQ")),this.ui.fileNameInputArea.hide().attr(S("9[IU\\\x13W)%&&*"),S(",Y\\ZU"))):this.ui.fileNameInputArea.show().removeAttr(S("&FZ@K\x06DDJKU_")),this.model.set(S("7WO_IKOWK%"),t)},"input @ui.fileName":function(){var e=this.ui.fileName.val().toString();if(t.isValidName(e))this.model.unset(S(" DPQKW"));else{var n=this.finder.lang.errors.fileInvalidCharacters.replace(S("-UKYBS_XZAR\\zRZN\\]K%31>"),t.invalidCharacters);this.model.set(S("\x19\x7finrl"),n)}this.model.set(S(" OCNA"),e)}},modelEvents:{"change:error":function(e,t){t?(this.ui.fileName.attr(S("\x17yksz1tpiAMKG"),S("\n\x7f~xk")),this.ui.error.show().removeAttr(S("\x10p`zu8~~|}\x7fu")).html(t)):(this.ui.error.hide().attr(S("!CQMD\vOAMNNB"),S("6CJL_")),this.ui.fileName.removeAttr(S("(HXBM\0GAFP^ZP")))}}})}),CKFinder.define(S("\nHGKgatt`('),S("*A]XK]I"),S("!@BGNDHFL"),S("*hgkGATT@\x1cyZRBT\\I\x14yYWK\t,#$!j\x10.->9d\t)';\x19<341\x197.7,."),S(' bieMKBBZ\x06gDHXBJC\x1ewW]A\x7fZY^_\x14jT[H3n\v.%"#\x17:,<"):\x18&5&'),S('8zq}USZZ2n\x0f, 0*";f\x0f/%9\x07"167|\x02<3 +v\x1b8(411\x137\v\x06\x13'),S("\fNEIy\x7fvvf:[x|lv~o2[{IUkNEBC\beFNN@^\x01jTXFzYTQR|XNZ"),S("\x0eL[W{}ppd8Uv~npxm0eEKWmHG@M\x06~DCA]"),S('-mdvX\\WQG\x19zW]OWYN\x11z$(6\n)$!"g\x04%/)!=`\0#=4&0%$\x156>>0'),S("\x10RYU}{rrj6WtxhrzS\x0egGMQoJINO\x04zDKXC\x1ebA[RDRKJ~R]QQX\x16('4"),S(' bieMKBBZ\x06gDHXBJC\x1ewW]A\x7fZY^_\x14jT[H3n\x01,*#/5%\r#* ")\x1994%')],function(e,t,n,i,r,o,s,a,l,u,c){"use strict";function d(e){var t=this;this.finder=e,e.on(S(";_RPK%96\x0e!+3}. &.v(*&$"),f,this),e.on(S("?4.-/&$4}:,9.8w\x03.9?h5=93"),function(n){var i=n.data.file;C(i)&&n.data.toolbar.push({type:S("C&023''"),name:S("*nHDZf]PUV"),priority:50,icon:S("\fnei=w{\x7fq8ssqm"),label:n.finder.lang.common.edit,action:function(){h(t,e.request(S("\x1bztrzS\x1bEFPvCKMJ^NH")).first())}})}),e.on(S("[) .,#\x7f%(&/#9!"),{name:S("\x12P{{p~jt_\x7fuiWrAFGf\\LR"),msg:e.lang.editImage.confirmExit}):void e.request(S("\x15fv\x7f| \x7fynjmOX"),{name:S("%cCA]cFMJK")})}}),t.data.toolbar.push({type:S("/DTJG"),name:S("\x1dXvLDLBI@"),className:S('0RYU\x19P_\x1aLVUW^\\L\x12&(.&*$+"'),label:e.util.escapeHtml(t.data.tools.editImageData.get(S(".IY]W")).get(S("/^P_V")))}),t.data.toolbar.push({name:S("\x17Kxl~"),label:e.lang.editImage.save,icon:S("'KBL\x06_LXJ"),alignment:S("A1&'*(#);3"),alwaysVisible:!0,type:S("+NXZ[__"),action:function(){v(i,t.data.tools)}}),this.resetButton=new n.Model({name:S('E\x14";,>'),label:e.lang.editImage.reset,icon:S(")I@J\0\\JCTF"),alignment:S("&TMJEEHL\\V"),alwaysVisible:!0,isDisabled:!0,type:S("C&023''"),action:function(){t.data.tools.resetTool()}}),t.data.toolbar.push(this.resetButton)},this,null,40),e.on(S('@%+"(*!}\r-#?\x05 /(5\x12==2<$:b61'),function(n){var i=n.data.context;if(!i.viewModel.get(S("\x12vfgye"))){var r=i.viewModel.get(S('"MEHC')),o=r+"."+i.viewModel.get(S('"F\\QCI[@EE')),s=i.viewModel.get(S("\x1crhzRVPJP@"));return!s&&e.request(S("5P^T\\I\x01[XJ|530&*1")).where({name:o}).length?void i.viewModel.set(S("?%30,6"),n.finder.lang.editImage.saveDialogFileExists):void m(t,i.tools,i.viewModel.get(S("\x1dqsDoCNA"))!==o&&o)}}),e.on(S("2W]TZX_\x03yTR[WM-\x04&*0\f+&/,\x0f3%9t ;"),function(){e.request(S("1BRSP\fS]JNISD"),{name:S("7}]SOuP_X%")})}),e.on(S("\x1c~qrM@LG\x1e@TUG[\x10xM[Kf]PUV"),function(){e.request(S("\x18i{|y'zzSUPL]"),{name:S("9\x7f_UIwR!&'")})},null,null,5)}function f(e){var t=this,n=e.data.context.file.get(S('C"**#-;')).get(S("#EFJ"));C(e.data.context.file)&&e.data.items.add({name:S("\fHjfdX\x7frsp"),label:t.finder.lang.common.edit,isActive:n.fileView&&n.fileRename,icon:S("\x1c~uy\rGKOA\bCCA]"),action:function(){h(t,e.data.context.file)}})}function h(t,n){if(e.isUndefined(y)){var i=CKFinder.require.toUrl(t.finder.config.caman||S("\fagmc>qrytx"))+S("\r ec.dvf(|{aax*");CKFinder.require([i],function(e){y=e||window.Caman,g(t,n)})}else g(t,n)}function g(e,t){var n=e.finder,l=new a;l.setupDefault(n,y),l.on(S("\x17lqhthirz"),function(){n.fire(S("+IIG[y\\STQ\x0fDRV]_IlO[I)$5"),{actions:f.get(S("D$%3!&$8")).clone()},n)});var u=new i({finder:n}),c=new r({finder:n}),d=new o({finder:n,collection:l});n.once(S("\n{mjk5cy}d.Pr~lPwz{x"),function(){u.preview.show(c),u.actions.show(d),u.$el.trigger(S("1QAQTBR")),n.request(S("#PJIKJHX\x11^H]JD"),{name:S("\x15SsqmSv}z{"),context:{tools:l}});var e=y(c.ui.canvas.selector,f.get(S("3]XWP]iH^JT[H")),function(){n.request(S("=RP!%'1~-/#-")),d.focusFirst(),f.set({renderWidth:c.ui.canvas.width(),renderHeight:c.ui.canvas.height()})});f.set(S(":X]P_Q"),e)});var f=new s({file:t,imagePreview:n.request(S("0X_RSP\fGJ\\LRYJkM,"),{file:t,maxWidth:.8*window.innerWidth,maxHeight:.8*window.innerHeight,noCache:!0}),fullImagePreview:n.request(S("\x1bup\x7fxE\x1bRQASOB_|XG"),{file:t,maxWidth:1e6,maxHeight:1e6,noCache:!0})});l.setImageData(f);var h=f.get(S("&FK]CDB^"));h.on(S("\x18x~\x7f"),function(){e.resetButton&&e.resetButton.set(S('=WL\x04(1"&)##'),!1)}),h.on(S("A0&7 2"),function(){e.resetButton&&e.resetButton.set(S("*B_iG\\QS^VP"),!0)}),n.request(S("4YYV\\\\H\x01OUQH"),{text:n.lang.editImage.loading}),n.request(S("-M@]\\S]P\x0fERV]"),{name:S("-gBQVWzZSY"),folder:t.get(S("\x1eyOMFFV")),params:{fileName:t.get(S("\x1eqALG"))}}).done(function(e){function i(){l.trigger(S("#QL\x1cUMZCQI"))}if(e.error&&117===e.error.number)return n.once(S('?#./.%+"}-;8$>w\x07"167\x1a:39'),function(e){e.cancel()}),n.request(S(">S/ &&6\x7f..,,")),n.request(S(" GMO@@T\x1dZLLYI^FiY]W@")),void n.request(S("4Q_VTV]\x01USXP"),{msg:n.lang.errors.missingFile});var r={width:e.width,height:e.height,size:e.size};t.set(S("R)/+.-?##"),t)}var i=!1;e.request(S("3]F{V@PWRFXZ"))||(e.request(S("\x1bq|fvMHXF")),i=!0),e.once(S("\x19wrrtsvZDF"),t),e.once(S("7HX]^\x06Y[L43-:~\0\".<\0'*+("),n)}function v(e,t){if(t.hasDataToSave()){var i=e.finder,r=t.editImageData.get(S("!DJH@")),o=r.getExtension(),s=r.get(S('C*$+"'));if(o){var a=s.lastIndexOf("."+o);a>0&&(s=s.substr(0,a))}var l=r.get(S("4SY[\\\\H")).get(S("D$%+")).fileDelete,u=new n.Model({onlyOverwrite:!l,overwrite:l,oldName:r.get(S("5XVU\\")),name:s,originalName:s,extension:o,tools:t,error:!1}),d=i.request(S("9^R]QQX"),{view:new c({finder:i,model:u}),title:i.lang.editImage.saveDialogTitle,name:S("#aAOSaDKLInAAVX@^"),buttons:[S("6XS"),S("#GDHDME")],context:{viewModel:u,tools:t}});u.on(S("\x1fCICMC@\x1cBZ[EY"),function(e,t){t?d.disableButton(S(":TW")):d.enableButton(S("/_Z"))})}}function m(e,t,n){function i(){c&&c.abort(),r.request(S("C ,'+'.p/)>:=?("))}var r=e.finder,o=t.editImageData,s=new l,a=new u({finder:r,model:s});if(r.request(S('?$(#/+"'),{view:a,title:r.lang.editImage.saveDialogTitle,name:S(";yYWK\t,#$!\x16'1-\x198$+?+<#"),buttons:[S("'KHDHIA")]}),r.on(S("\x1fDHCOKB\x1cbL@^bALIJcPDVdGYPJ\\IH\x06^_Q#$."),i),s.set(S("3YPEDY^_"),r.lang.editImage.downloadAction),!window.URL||!window.URL.createObjectURL)return s.stateIndeterminate(),void w(o.get(S("1TFXY\x7fZY^_kNXHV%6")),t,r,s,n);s.set({bytes:0,bytesTotal:0,value:0,time:(new Date).getTime()});var c=new XMLHttpRequest;c.onprogress=function(e){e.lengthComputable&&(s.set({state:S("\nec\x7fcn|"),bytes:e.loaded,bytesTotal:e.total,value:e.loaded/e.total*b,time:(new Date).getTime()}),s.set(S("\x15beywi}yo"),r.lang.formatTransfer(s.get(S("\x0fcawvp"))))),e.lengthComputable||s.set({value:x,state:S("\fd`kueway|xvl|"),transfer:""})},c.onload=function(){return r.removeListener(S("#@LGKGN\x10nHDZf]PUVgT@RhKU\\NXMLz\"#-' *"),i),200!==this.status?(r.request(S("$CIKLLX\x11^HH]UBZu]YSD")),r.request(S("9JZ[X\x04[%261+<"),{name:S("B\x06 ,2\x0e%(-.")}),void r.request(S("\x14q\x7fvtv}!usxp"),{msg:r.lang.errors.missingFile})):(s.set({value:b,eta:!1,speed:!1,time:0}),void w(window.URL.createObjectURL(new Blob([this.response])),t,r,s,n))},c.open(S("7\x7f|n"),o.get(S("\x1a}iqrVM@EFtWCQAL]")),!0),c.responseType=S("\x10p`aultb~\x7f\x7fi"),c.send(null)}function w(e,t,n,i,r){i.set({value:b,message:n.lang.editImage.transformationAction}),t.doSave(e).then(function(e){function o(){l&&l.abort(),n.request(S("\x14q\x7fvtv}!xxmkRN["))}i.set({value:F,message:n.lang.editImage.uploadAction});var s=t.editImageData.get(S("B%-)#")),a=s.get(S('C"**#-;'));n.once(S("\x19ytqp\x7fqD\x1bCEP@T\x1d{H\\Ne@OHU"),function(e){e.data.response.error||(i.set({state:S("\x0f~~`~uy"),value:E,message:""}),s.set({date:e.data.response.date,size:e.data.response.size}),n.once(S("\x1eoAFG\x19WMIP\x12dKBB"),function(){e.data.context.isFileNameChanged?n.request(S('B%+)"":s8.*?+<8\x17;?1&')):s.refresh()}),n.request(S("\x1ak}z{%DDQWVJ_"),{name:S("+iIG[y\\STQ")}))}),i.set({bytes:0,bytesTotal:0,value:F,message:n.lang.editImage.uploadAction,time:(new Date).getTime()}),n.on(S(".KYP^\\S\x0fsSQMsV]Z[l!7'\x136*!5-:9q/, ,5="),o);var l=n.request(S("\x1c~qrM@LG\x1eVCIL"),{name:S("\x1bO|hziLCDA"),type:S("+\\B]["),folder:a,params:{fileName:r?r:s.get(S("\r`n}t"))},post:{content:e},context:{file:s,isFileNameChanged:!!r},returnTransport:!0,uploadProgress:function(e){e.lengthComputable&&(i.set({bytes:e.loaded,bytesTotal:e.total,value:e.loaded/e.total*(_-F)+F,time:(new Date).getTime()}),i.set(S("'\\[KE_KK]"),n.lang.formatTransfer(i.get(S("\x1fSQGF@"))))),e.lengthComputable||i.set({state:S("\x10x|wqaseuptzhx"),transfer:!1})},uploadEnd:function(){i.set(S("\f~zndt"),S("=PP2,#/")),n.removeListener(S("0U[RXZQ\r}]SOuP_X%\x12#5!\x154(/;/8?w-.>27?"),o)}});t.destroy()})}function C(e){return e.isImage()&&e.get(S("E ($-/9")).get(S("D$%+")).fileRename&&e.get(S("(OEGHH\\")).get(S(" @AO")).fileUpload}var y,b=33,x=20,F=35,_=98,E=100;return d}),CKFinder.define(S("\x18ZQ]uszzR\x0eoL@PJB[\x06lB@Hj@G_^\\UQ\x19qQU_\x7fSJPS/ &"),[S("+YCJJBBQ\\FP"),S("\x14\x7fgb}kc")],function(e,t){"use strict";function n(n){var o=e.uniqueId(S("#GN@\nLF]E@BOK\x1dW@RYP"));n.setHandler(S(">Y)-'y *1)$&+/"),function(e){var i=e.file.get(S("7^VV_YO")),r=n.request(S(")IDA@OAT\vGAX"),{command:S("\x11V|c{zxy}\\rpx"),folder:i,params:{fileName:e.file.get(S("\x11|ryp"))}}),s=t("#"+o);s.length||(s=t(S("\x0f,xtauxs)")),s.attr(S("1[W"),o),s.css(S('E".;9&*5'),S("\x11||zp")),s.on(S("\v`bok"),function(){var e=t(s.get(0).contentDocument).text();if(e.length)try{var i=JSON.parse(e);i.error&&117===i.error.number&&(n.request(S(" GMO@@T\x1dZLLYI^FiY]W@")),n.request(S("\x0ftxs\x7f{r,~v\x7fu"),{msg:n.lang.errors.missingFile}))}catch(e){}}),t(S("\x17zv~b")).append(s)),s.attr(S("%UUK"),r)}),n.on(S('\x10e}|xwwe"k\x7fhyi$RAHL\x19BLJB'),i),n.on(S("\x15uxvm\x7fchP{qU\x1bDJH@"),function(e){e.data.groups.add({name:S("#RLCP")})},null,null,20),n.on(S("\nhcczjhe_vz`,qqu\x7f!jt{h"),r,null,null,20)}function i(e){var t={name:S('~uy\rGKOA\bVUM_CN[\0\\@_E\x10\x13GAO[]\x04\x18KSNWK).,y",>",r>$4v~|g9swzquc!]ow~L\r\x02kAIPB\\@IJ\0\rzNX^_R\x18\x15`RJ][U]\x11\x1eL!/1n7 4..rhk8,,&>57+iwfux+579`|>\x10\x11\x0e\n\x07\x04\x12\x0e\x07\x07HUfdR\v\x19\x07R\x10\x18\x14\x05\x04E[\x19\x10\x1aP\x18\x16ld/sv`pnm~(+\x7fywcu,0c{f\x7fcqvt!}\x7fmpLTVF\x1fQIW\x12\x19\x11GIKZ\x15\0\nP\\@AYZ\x02\v_V\x07OWX(5xs\x7f(\'5/ $q-8: kslo{1?!fSSg84(\x7f\x03\r\x03\x10\x17XD\x04\x03\x0fG\r\x05\x01\vB\0\x03\x17\x05\x1d\x10\x01Z\x11\x17\x1c\x14^wwvsu{oa8$wgzc\x7feb`5qsa|x`br#u\x7f}h\'.$BNVWKH\x1c\x17\x13[CLDY\x14\x1f\v\\SAS\\X\rYLNT\x07^QS/3x`"# |*() +?!:>5hpdefl(8>?539ePOW\x06\tEW\x02\x05R\x07\n\x14@\x06\n\x19\x16\x1a\x07NG\x13\x1aC\x15\x13\x15\x19P\x16\x1aifjw>4cj3oeex }fjt("qx-5&\x13\x13\x12 ywi\0BNBWV\x1b\x05KBL\x06JDBJ\x1dA@VB\\S@\x15PT]S\x10P^-$`c71?+-th- "/;j=75 ntidv>2*cTVi]\x06\n\x12E\x05\v\t\x1a\x19VN\x0e\x05\t]\x17\x1b\x1f\x11X\x06\x05\x1d\x0f\x13\x1e\vP\x17\x11fn/`kphs*)y\x7fuak22w~|ua,eq~ro\'? #\x0fEKU\x1a//\x1b\x07MC]\x12\'\'\x13RDFG[[\x16TTXIH\x01\x1f]T&l$*( k7:,<"):c-%%&<:x&%=/x{/)\'3\x05\\@\x13\v\x16\x0f\x13\x01\x06\x04Q\r\x0f\x1d\0\x1c\x04\x06\x16O\x01\x19\x07BLJ^G\x1f\x1f\x1ckfplqkb=d`dnm\x7f#hbpvzq{b?lv:ysijpM\r\x02\0BC@\x07\x18\x05\n\bI\x19K\x1bU\x05\x12\x02\x04\x05\x13\x1e\x03[UIXXL\x122 &*16|i{xx~) u-?#66&og\' y)404:\x7fC\x03T\x01R\x07P\\\n\x06\x12F\x1f\x05\x0f\v\x1f\x06HCTD\x06\x0fXIZ\t\x1b\x1f\x1fW247/$732$)8>9!.?>$;?4%6\'8+jcuefryk{u\x7fx$qOOG\x18@LUWDHS\x11ECBF^T\x1fQXZU\\\x03O_IHT]^,l#/-"(}% ./ (umnw>2% 9ldv8.()11^kk_\x06\x10\x12\x13\x07\x07J\b\0\f\x1d\x1cMS\x11\x18\x12X\x10\x1e\x14\x1cW\v\x0e\x18\b\x16ev/aqqrhf$dnty,/cek\x7fq(4gwjsourp%ACQLHPRB\x13]E[\x16\x18\x1e\n\vSSP_RDXMW^\x01PTPZ!3o$6$".-\'>c8"n-?%&<9yvt>?<{lq~|\x05U\x07W\x01QFVXYOBW\x0f\x01\x1d\x14\x14\0^\x06\x14\x12\x1e\r\n@UOLLJel9akwbbz3;{t-}`|xv37w u.{, ~rf2SICGKR\x1c\x17\b\x18ZS\f\x1d\x0e]WSS\x1b\x06\0\x03\x1b\x18\v\x0f\x0e\x10\x1d\f\numbsjpokhyj{l\x7f>7p#515}dbmuziihr\x7fRTWODUHV]@J\x02\x02\x1e\v\x1b\\QBSE\x05\x0eWHY\b\x1c\x1e\x1cVM54.#603+(;?> ->!!$;3}{erl"xtd0mvZHLD\x1eGIULLX\x06NBV\x14S^^\\F\x0f\x15\x04\v\n\x01]SSJ\x123(8&~tti}92p*" ;}&7:3="m:66?g171\x05L\n\x06\r\x02\x0e\x13RXDX\t\0U\x02\x11\x03\x15\x1a\x1aOC\x07\0YI\v\x04F\x0e\x1edekmc?3wp);;|u5{uif>g}wswn +<,ng\0\x11\x02\0B\x16@\x14N\x1a\x11\x06[HLDYE\x1fRDESVJXTXY\x07PP.$yn)*('),S("D/72-;3"),S("$AIs"),S('E$&+"($"('),S('A\x01\b\x02,(#-;e\x1e8$"`\x1b4+\x10;13'),S('(]OSX\fmdvX\\WQG\x19c]TJW]I[Lo\x07+/!\x154"> /=_.last?(_.current=_.last,w.hide()):w.show(),o=_.files[_.current],s=o.url,a=o.name,l=a.substr(a.lastIndexOf(".")+1),u=i.fire(S(" GKOA\x1fVUM_CN["),{templateData:{fileIcon:function(){var e=t(f).width(),n=t(f).height();return i.request(S("\x1fFHNF\x1eBCSaJEE"),{size:e>n?e:n,file:o.file})},fileName:a},file:o.file,url:s,extension:l,template:x},i),y.text(o.name),b.text(_.current+1+S("+\f\x02\x0e")+_.files.length),i.request(S("\x1c{wsER\x18GAVCKMJ^j@A")),i.request(S("\x18\x7fswyn$lEMG@P"),{files:c[_.current]}),r=t(n.template(u.template)(u.templateData),f), +u.events&&e.forEach(u.events,function(e,t){r.on(t,e)}),m.append(r),e.isFunction(u.afterRender)&&u.afterRender(r),i.request(S("\x17~vyno'jmAQ"),{node:p})}function l(e,t){m.html(""),e.stopPropagation(),_.current+=t,a()}function u(){F&&F.remove(),p.remove();var e=c[_.current];e.trigger(S("\x17~vyno"),e)}var c=i.request(S("%@NDLY\x11KHZkYBB_ULSS")).where({"view:isFolder":!1}),d=[],f=window.top.document,h=n.template(o),g=0,p=t(h(),f);p.attr(S('E".:'),i.lang.dir);var m=p.find(S("\x1a5\x7fvx2FHNF\tUTB^@O\\")),w=p.find(S('-\0L[W\x1fU]YS\x1aHK_MUXI\x12"467++k)-1>')),C=p.find(S("3\x1aV]Q\x15_SWY\x10NM%7+&3h$2<=%%a=<*&")),y=p.find(S("\x11!%t\x7f"))):(w.css(S(".CUWF"),S("2\x03\x1a\0SZ")),C.css(S("$WO@@]"),S("\x17(7/~q"))),c.forEach(function(e,t){var n=e.getUrl(),i=e.get(S("3ZT[R"));d.push({url:n,name:i,file:e}),i===s&&(g=t)});var F,_={files:d,current:g,last:d.length-1};i.util.isWidget()&&(F=t(v).appendTo(t(S("#FJB^"),f))),p.append(m).append(C).append(w).appendTo(t(S("8[U_E"),f)),p.focus(),p.on(S("*H@DMD"),function(){u()}),t(p).on(S("?+$;'+2("),function(e){e.keyCode===r.left&&l(e,i.lang.dir===S("4YBE")?-1:1),e.keyCode===r.right&&l(e,i.lang.dir===S("\x15zcj")?1:-1),e.keyCode===r.escape&&(e.stopPropagation(),u())}),C.on(S("\x0el|xqx"),function(e){l(e,-1)}),w.on(S("\rmcyry"),function(e){l(e,1)}),a()}function u(e,t,n){var i=document.createElement(e);return!!i.canPlayType&&""!==i.canPlayType(t[n])}function c(e){return u(S("\x17yl~rs"),{flac:S("#EPBNG\x06LGMN"),mp3:S("'I\\NBC\x02C_UV"),ogg:S("D$3#!&e$+*"),opus:S("5WB\\PU\x14SZY\x04`\"-'!&5zj&:>?"),wav:S(")K^HDA\0GPD"),weba:S("5WB\\PU\x14KX\\R")},e)}function d(e){return u(S('C2,""\''),{mp4:S(".YYUW\\\x1bXF\x03"),ogv:S("$SOCMF\x05DKJ"),webm:S("3B\\RRW\x16M^^P")},e)}var f=S("\x0elq}q;%%&284:-yp7"),h=S('=]^,"jrtucgeix.!d'),g=S("\x0e\x7f\x7fb{g}zx-y{itphjz\x1b")+S("B7+5|ws")+S("-BJVE\b\x03\x0f")+S('"AKQRHE\x13\x1a\x10')+S("\x14g\x7fppm +'")+S(".BQCUZZ\x0fWBLV\x01")+S('\x0ebqi?d}qb\x7f"')+f+";"+S("5[V@\x14R^UZVKz")+h+";",p=g+S("5A^\\MR\x01")+f+S("7\x03Q_R[UJ\x05")+h+";",v=S("\x11.``lzr&")+S("3\x1aV]Q\x15_SWY\x10NM%7+&3h4('=jq*\"-:#}|0?3{115?v,/;)\t\x04\x15N\x16\n\t\x13R\x0f\x05\b\x19\x1eNA\x13\x1a\x14^\x12\x1c\x1a\x12U\t\b\x1e\n\x14\x1b\b z")+S("9\x17LY_UV4l ,
    /\0\x11\x02\x11T]\x06\x04noio\x1f\x1f\x0e\x0eY\\B\\FAWYL\x02')+"}"+S("Ezh;=3')s"),m=S('2\x0f]XQ\x17YUN\x06\x1eFE\x1e`(6m",*"\x06(\'.l03mp" 0iw-,ey3/r;73\x05(\x01\f\nMOG\x15\x14HK\x1f\x19\x17\x03\x15LP')+g+S("\v.3")+S("\x13(|{p8xvo!fe>\0HV\rBLJBfHGN\fPS\r\x10B@P\t\x17ML\x05\x19SO\x12HLS`=.x{/)'3\x05\\@\x07\r\x16\x16\v\t\x10P\x05\x03\x03\vT")+g+S("%\x04\x19"),w=S(")\x16JYIG@\x10B@P\t\x17ML\x05\x19SO\x12HLS`lRB\x1f\x01_^\x1b\x07A]\x04^^A\x0eRM\x13\x12@@LZR\x05\x1b")+p+S("+\x0e\x13"),b=S("\f1gbw1s\x7f`(4lc$:rh3xvLDlBI@\x06ZU\v\nX^N\x13\rKJ\x0f\x13]A\x18QQU_r_RP\x17ia?>fe531%/vn")+g+S("$\x07\x18")+S("@}+%6$+\"h:8(qo54mq;'z $;x$'y|.*&\f\x04_A\0\f\x15\x17\x04\b\x13Q\x02\x02\0\nK")+p+S("Cf{"),x=S("\x10-{~s5w{l$8`g >vT\x0fDJH@hFEL\nVQ\x0f\x0e\\BR\x0f\x11ON\v\x17QM\x14]UQ[v#.,kme;:ji9?5!+rr")+g+S('\x1a9"');return a}),CKFinder.define(S("7{r|RRY[Mo\f-'1)#4g\x0f#')>a\t9=7 \x12<:#=+"),[S("\x12quv}uww\x7f")],function(e){"use strict";return{attachTo:function(t){var n=new e.Collection;return n.search=function(e){var i;t.length&&(""===e?(i=t.toArray(),n.isFiltered=!1,n.filter=e):(i=t.filter(function(t){return new RegExp(e.replace(/[\\^$*+?.()|[\]{}-]/g,S("=b\x1bf")),S(",JG")).test(t.get(S("D+'*-")))}),n.isFiltered=!0),n.reset(i))},n.listenTo(t,S("*YI^K["),function(){n.reset(t.toArray()),n.isFiltered=!1}),n.listenTo(t,S("&UMDE]I"),function(e){n.remove(e)}),n.listenTo(t,S("<\\Z["),function(e){n.add(e)}),n.isFiltered=!1,n.comparators={},n.sortFiledName=void 0,n.sortAscending=!0,n.on(S("\x18zrzrz{%N@OF"),function(){n.sortFiledName===S("\x1fN@OF")&&n.sort()}),n.comparator=function(e,t){if(!this.sortFiledName||!this.comparators[this.sortFiledName])return 1;if(e.get(S("\x1bjt{h\x1aHQeKIBBZ"))===t.get(S("\x1amuxi%IRdLHACU"))){if(e.get(S("'^@O\\\x16D]i_]VVF"))===!1){var n=this.comparators[this.sortFiledName],i=n(e,t);return 0===i?i:this.isSortAscending?i:-i}return e.get(S("B-%(#")).localeCompare(t.get(S(" OCNA")))}return e.get(S("\x0ffxwd.|eQwu~~n"))?-1:1},n.addComparator=function(e,t){this.comparators[e]=t},n.sortByField=function(e){this.sortFiledName=e,this.sort()},n.sortAscending=function(){this.isSortAscending=!0,this.sort()},n.sortDescending=function(){this.isSortAscending=!1,this.sort()},n.addComparator(S("?. /&"),function(e,t){return e.get(S("\x19tzqx")).localeCompare(t.get(S("\x18w{vy")))}),n.addComparator(S(" RKYA"),function(e,t){var n=e.get(S("=MV:$")),i=t.get(S(" RKYA"));return n===i?0:n>i?1:-1}),n.addComparator(S("\x1e{AUG"),function(e,t){return e.get(S(";X\\JZ")).localeCompare(t.get(S(":_]I[")))}),n}}}),CKFinder.define(S('A6&<1g\x04\x03\x0f#%((<`\x044?#84"2+v\x1c208-p#\t\r\f\x17\x004\x02\x1b\0\x10\x0e\b$\x03\x0e\x17\x14;\x07\x11\x18X\x13\x17\r'),[],function(){return S("\x12/xttrt'\x10\x12gf#?IU\fOEGCK\bTW!%\x11]_Q_\x12PXTED\x05\x1bYPZ\x10]W/.1&i7#4!3//a$#.74\x7f =/3uf\"!f|4*q\x13\b\x18\x06D\x18\x1b[G\x1a\x1a\n\x02SdfL\x18\x1c\x03\x01\x01V\x03\x01\t\x1fF^\x0f\x1f\x1bin #jdkb5+i`jNf`\x7fbwAqf\x7fm}}8;h||vNEG[\x19\x07\x17\x05\b_KGYH\x13\rKJ\x0f\x13]A\x18YYT_\x1bA@\x1c5Iabcd>=xhh#?b$=\x0e3%;%1u+*<0):>1;;]C\x06\n\x17\x04\x04\v\r\rH\x10\x17R\x13\x12\v\nMS\x1d\x01X\x1e\v=\x1f\x1d\x1d\b\x12\v |\x7f#gmcdcln6.nfjszww6nm(ed:\x7f}i\x7f2IBMMTJU\x1a\nRQ\x14\fDZ\x01\\P\\T\x1aQ_E\x18\x04\x07\x06\x1c\x1fRK2c?>( 332ut10<&79&(/j+*zgPgs1?=\x05\r\\i")}),CKFinder.define(S('B7!=2f\v\x02\f"")+=\x7f\x057>$97#=*u\x1d51;,O"\n\f\v\x16\x035\r\x1a\x03\x11\t\t\'\x02\x11\x16\x17:\x1a\x05\x03\x031\r\x1f\x16R\x19\x11\v'),[],function(){return S("2\x0fXTTRT\x0702GF\x03\x1f)5l/%+!i+!%$?(\x1c*#8(60\x1c;6?q/;,\t\x1b\x07\x07I\f\v\x06\x0f\fG\b\x19\x1e\x1a\0\x1d\\\x14\x1a\x11\x19\x12\x04X\f\x13V\x0f\t\x1f\ve,fjwddkmm(5\x06\x042kyg2pxted%;ypz0}wONQF\tWCTASOO\x01DCNWT\x1fPAFBXU\x14XWS^U\x1d~KKJx)'%-%j( ,=q/;,\t\x1b\x07\x07I\f\v\x06\x0f\fG\x07\r\x0f\v\x03RO%\x1a\x10\x01\x1eKW\x15\x1b\x19\x19\x11@u\t=-gms8\r\x015nbz-mcqba.6v}q5zrtsn{2RDQJ^@B\nADKLI\0MZCE]^\x19WZX[R\x1aXW[\x13\\(.-0!h4\"; 0.(`'\"167~=;&\",{dQUTb6\x0e\x11\x17\x17D\x11\x1f\x17\rTH\x1f\t\x15\x1aMP\x1f\x13\x1e\x11HT\x14\x13\x1f9\x0e\x0f\t\x11\x12Whfwl'&sikcehhv22 03p|evzu\x7f\x7f!?zvS@@OAA\x04\x07^HF^I\x10\fTK\f\x12Z@\x1bA^\\MR\x1bA@\x1c\x01JH~l ,0yB@v/%;n,<0! iw5<>t9332-:M\x13\x07\x10\r\x1f\x03\x03E\0\x07\n\v\bC\f\x05\x02\x06\x1c\x19X\x14\x1b\x17\x1a\x11YBwwvq/;,\t\x1b\x07\x07I\f\v\x06\x0f\fG\b\x19\x1e\x1a\0\x1d\\\x10\x1f\x1b\x16\x1dW\x1b\x12\x1cV\x1f\x15\x11\x10sd/qavo}mm'balij=x|caa4)\x12\x10\x13'usnjT\x01VZT@\x1b\x05\\LR_\x0e\r@N]T\x0f\x11W^PtMJNTQu[V')6ad1'%!'..4pl~rq6:'44;==gy84->\x02\r\x07\x07FE\x10\x06\x04\x1c\x0fVN\x16\x15RP\x18\x06]\x1c\x10\x1f\x10\x10\rZ\x06\x01_@u\t=-gms8\r4&nbz3\x04")}),CKFinder.define(S("\vOFHf~uwa;Xysmu\x7fh3[wsER\ruM@QT\x07jBDC^K}UB[IQQ\x7fZY^_mUXI"),[S("\x11g}ppdd{vh~"),S("5\\FM\\HB"),S('2p\x7fs_Y\\\\H\x14iIWSo\n\':\x07*""'),S("\rMDVx|wqg9Aq|mh3_\x7flE\x0eaLHICD\\@EEzDKX"),S("\rMDVx|wqg9Aq|mh3_\x7flE\x0ekWAHpNM^"),S('3@PNC\x19zq}USZZ2n\x16&)5*&<,9d\n$"*#~\x11;;:%2\n<)2&8:\x16\r\0\x05\x06-\x11\x03\nF\r\x05\x1f'),S('+XHV[\x11ryu][RRJ\x16n^QMR^4$1l\x02,*";f\t##"=*\x024!:.02\x1e58=>\x153.*\x14(\x16\x06\tK\x02\b\x1c')],function(e,t,n,i,r,o,s){"use strict";var a=i.extend({name:S("\vOb`{uif^q{c"),template:"",tagName:S("\x19|tnp"),events:{'change [name="ckfChooseResized"]':function(e){var n=t(e.currentTarget).val();n===S(" ~}@QVRHE")?(this.$el.find(S("&\tKBL\x06OEA@CT\x1fAQF_M]]\x17RQ\\YZm\"700*+j. /'(>")).removeClass(S("\x11gz9fbvl|7\x7fun\x7f}LDF")),this.$el.find(S("?n\")%i&.(':/f>(=&*46~=870=t35,(*\x7f\t\x0f\x12\x16\x10")).textinput(S("/U_SQXP")).removeAttr(S("2W]FWUT\\^")).first().focus()):(this.$el.find(S(":\x15_VX\x12#)-,7 k5-:#1))c&=056y6#$,67v:4;3\x04\x12")).addClass(S("*^E\0][QEW\x1eP\\EVZU__")),this.$el.find(S("0\x1fQXR\x18U_WVI^\x11O[L);''i,+&/,g\"\"=;;p8<#!!")).textinput(S("\x0ekybsqxp")).attr(S("\fig|qs~vp"),S("@%+0%'*\",")))}},childEvents:{keydown:function(e,t){if(t.evt.keyCode===n.down||t.evt.keyCode===n.up||t.evt.keyCode===n.tab){if(t.evt.preventDefault(),t.evt.stopPropagation(),t.evt.keyCode===n.down||t.evt.keyCode===n.up){var i=this.collection.where({isActive:!0}),r=i.indexOf(e.model),o=r+(t.evt.keyCode===n.down?1:-1);o<0&&(o=i.length-1),o>i.length-1&&(o=0);var s=this.children.findByModel(i[o]);s&&s.focus()}t.evt.keyCode===n.tab&&e.$el.closest(S(';\x12^UYm%+"(*!')).find(S("\x16L|xnz1~uy\rCWWPJHz")).eq(this.finder.util.isShortcut(t.evt,S("7KQS]H"))?-1:0).focus()}}},collectionEvents:{reset:function(){this.$el.html("")}},onRender:function(){var e=this;setTimeout(function(){e.$el.enhanceWithin()},0)},getChildView:function(e){var t={name:S(".lX^]@QgSDQC__uI[R"),finder:this.finder,template:o,tagName:S("7\\PL"),events:{'keydown input[type="radio"]':function(e){this.trigger(S("\x0f{tkw{bx"),{evt:e})}},focus:function(){this.$el.find(S("&NFY__")).focus()}};return e.get(S("8ZOHHRS"))&&this.addCustomSizeViewConfig(t),r.extend(t)},addCustomSizeViewConfig:function(e){e.name=S("\x16TpvuhyO{lI[GGgPUSGDc_I@"),e.className=S('"@OC\vD@FEXI\0\\JCXHVP\x18_ZY^_\x16_HMK/,'),e.template=s,e.tagName=S("\x14q\x7fa"),e.ui={width:S("*BB][[k_S^Q\b\x14TS_yNOIQR\x17(&7,g\x1b"),height:S("#z\x04")},e.setSize=function(e,t){var n=e<=0?1:e,i=t<=0?1:t;this.ui.height.val(n),this.ui.width.val(i),this.model.set({size:i+"x"+n})},e.events[S("!KMTPR\x07h\\C\x05[DJ[X")]=function(){var e=this.model.get(S(":LUYJW")),t=this.model.get(S("\vdhghxe")),n=t,i=this.ui.width.val();i.length||(i=1);var r=parseInt(i);r/'),[S("%SILLXXOB\\J"),S("+F\\[JBH"),S("<__\\+#--!"),S(',neiY_VVF\x1a{X\\LV^O\x12xV,$1l\x12,#0;f\t##"=*\x024!:.02\x1e58=>\n4;(')],function(e,t,n,i){"use strict";function r(e){this.finder=e,this.isEnabled=e.config.chooseFiles,e.config.ckeditor&&(e.on(S("\x16qqu\x7fh&~vpORG"),function(t){var n=t.data.files.pop();e.request(S("\x1dxvLD\x18DAQsUD"),{file:n}).then(function(){var t={fileUrl:n.getUrl(),fileSize:n.get(S("\x1elI[G")),fileDate:n.get(S("\x18}{oy"))};e.config.ckeditor.callback(t.fileUrl,t)})}),e.on(S("4S_[]\x03YSSRMZz3'0-?##\x01$+,)"),function(t){var n=t.data.file,i={fileUrl:t.data.resizedUrl,fileSize:0,fileDate:n.get(S("$AGSM"))};e.config.ckeditor.callback(t.data.resizedUrl,i)})),this.isEnabled&&(e.on(S("\nhcczjhe_vz`,qqu\x7f"),function(e){e.data.groups.add({name:S("+OEA@CT")})},null,null,10),e.on(S("$FII\\LR_aH@Z\nW[_Q\x0fU_WVI^"),o),e.on(S("6"),s),e.on(S(".[_^^QUG\fE]J_O\x06p_V.{$*( 5"),a),e.on(S("%EHEDKEH\x17AD\nbSEQ|[V_\\"),function(e){e.data.context.file.set(S("\x17qt{|yO{lI[GgEQG"),new n.Model)}),e.setHandlers({"image:getResized":{callback:c,context:this},"image:resize":{callback:d,context:this},"image:getResizedUrl":{callback:g,context:this},"files:choose":{context:this,callback:function(t){l(e,t.files)}},"internal:file:choose":{context:this,callback:function(t){w(e,t.file)}}})),e.setHandlers({"file:getUrl":{callback:h,context:this},"file:getProxyUrl":{callback:f,context:this}}),e.on(S("*HC@CN^U\bRRASE\x02~_OzTRZ\x153."),function(e){e.data.context.thumbnail||e.data.context.file.set(S("2FFY"),e.data.response.url),e.data.context.dfd.resolve(e.data.response.url)}),e.on(S("D!/&$&-q\x0f%! #4\x006'<,2<\x107:;8d0\v"),function(t){var n=t.data.view.getSelected();m(e,n.get(S("*EM@K")),n.get(S("'[@PN")),t.data.context.file),e.request(S("'L@KGCJ\x14KUBFA[L"))})}function o(e){function t(){new n.Model({name:S("\x11Q{{zerJ|irfxzVM@EF"),label:e.finder.lang.chooseResizedImage.title,isActive:i.get(S("A$,(!#5")).get(S("7YZV")).imageResize||y(i),icon:S("\x16ts\x7f7xtrqlE\fPFWL\\BL"),action:function(){u(e.finder,i)}}).set(S("3UVB^N\\"),y(i))}var i=e.data.context.file;if(e.data.items.add({name:S("0rZ\\[FS"),label:e.finder.lang.common.choose,isActive:i.get(S("\x12u{yrrj")).get(S("0PQ_")).fileView,icon:S("\x15u|~4yssrmz"),action:function(){var t=e.finder.request(S(" GKOAV\x1c@M]yN@HM[UU"));t.length>1?l(e.finder,t):w(e.finder,i)}}),i.isImage()&&e.finder.config.resizeImages){var r=i.has(S("C-(' -\x1b/8%7+\v1%3"))&&i.get(S(",DCNWT`VG\\LR|XNZ")).has(S("B,6,!.&(&\x18%7+"));r||i.once(S("\x19ys}syz\x1aHOBC@tB[@PNhLZN"),t),e.data.items.add(new n.Model({name:S("\nHdba|uCw`}ossQt{|y"),label:e.finder.lang.chooseResizedImage.title,isActive:i.get(S("2U[YRRJ")).get(S("\x1c|}s")).imageResize||y(i),icon:S("\x0fszt>w}yxk|7iynweEE"),action:function(){u(e.finder,i)}}))}}function s(e){function t(){w(e.finder,i)}var i=e.data.file;if(C(e,t),i.isImage()&&e.finder.config.resizeImages){var r=i.has(S("*BALIJbTAZNPrVLX"))&&i.get(S("\rgbqvwAqf\x7fm}]{o}")).has(S("\x1atntyvN@NpM_C")),o=new n.Model({name:S("C\x07-)(;,\x18.?$4*4\x18?230"),type:S("\x0frdfg{{"),priority:E,alignment:S("C47/*);3"),icon:S(".L[W\x1fP\\ZYD]\x14H^OTDZ$"),label:e.finder.lang.chooseResizedImage.title,isDisabled:!(i.get(S("9\\TPY[M")).get(S("0PQ_")).imageResize||y(i)),action:function(){u(e.finder,i)}});r||(i.once(S(':XT\\PX%{+.%"#\x15-:#1)\t/;1'),function(){o.set(S("#MVbN[HHGII"),!y(i))}),e.finder.request(S("$LKFOL\x10LIY|JCXHVP"),{file:i})),e.data.toolbar.push(o)}}function a(e){function t(){l(e.finder,e.finder.request(S("\x18\x7fswyn$xEUqFH@ESMM")))}C(e,t)}function l(e,t){var n=t.clone();n.forEach(function(t){!t.getUrl()&&t.get(S("&AGENN^")).getResourceType().get(S("\x1anoxNmOY[`KHKFFM"))&&t.set(S(".ZB]"),e.request(S("\x0fvx~v.rscHkuceHls"),{file:t}))}),e.fire(S("\x1eyIMGP\x1eFNHGZO"),{files:n},e),x(e)}function u(e,t){var r=new n.Collection,o=e.config.initConfigInfo.images;p(r,e,t,o),t.on(S("\x12p|txp}#sv}z{MERKYAaGSI"),function(){r.reset(),p(r,e,t,o)}),e.request(S("\rjfq}}t"),{title:e.lang.chooseResizedImage.title,name:S("\x1fcIMLW@tB[@PNHdCNWT"),buttons:[S("%IL"),S("+OL@LU]")],view:new i({finder:e,collection:r}),context:{file:t}})}function c(i){var r=this.finder,o=i.file,s=new t.Deferred;if(o.has(S(")CFMJK}UB[IQqWCY"))&&o.get(S("7QT[\\Yo[L);'\x07%1'")).has(S("\vc\x7fghy\x7fs\x7fG|lr")))s.resolve(o);else{var a=o.get(S("\x17~vv\x7fyo"));r.once(S("D&)*%($/v,(;5#h\x141!\x042+0 >8\x143>\x07\x04\x11"),function(t){var i=t.data.context.file,r=new n.Model;t.data.response.resized&&r.set(S("\x0fbtaznpr"),t.data.response.resized),t.data.response.originalSize&&r.set(S("*D^DIF^P^`]OS"),t.data.response.originalSize),e.forEach(t.data.response.resized,function(t,n){if(n===_)return void e.forEach(t,function(e){var t=e.name?e.name:e,i=t.match(I);if(i){var o={fileName:t};e.url&&(o.url=e.url),r.set(b(n,i[1]),o,{silent:!0})}});var i={fileName:t.name?t.name:t};t.url&&(i.url=t.url),r.set(b(n),i,{silent:!0})}),i.set(S("\x1dwrAFGqAVO]MmK_M"),r),t.data.context.dfd.resolve(i)});var l={fileName:o.get(S("5XVU\\"))};e.isArray(r.config.resizeImages)&&r.config.resizeImages.length&&(l.sizes=r.config.resizeImages.join(",")),r.request(S("\x14vyzuxt\x7f&n{qD"),{name:S(' "\x0e%(-.?'),folder:a,params:l,context:{dfd:s,file:o}})}return s.promise()}function d(e){var i=this.finder,r=e.file,o=new t.Deferred,s=e.size;if(!e.name)throw S('C\x10-#g,(>*b#/"5q"2&4;2,<({5.~-\x05\x10\x17\n\x16\0\x02');if(e.name===_){if(!e.size)throw S('-zGU\x11VR@T\x18DQC_\x1bL\\L^-$6&6e/4h;/:9$<*4q%;1;v"+04<|\x7f%1\x01\f\x07\x1eFK').replace(S("4NXVU\\G"),_);s=e.size}else{if(!i.config.initConfigInfo.images.sizes[e.name])throw S('>k($b-%(#gj2$*!(3mp8!s::"w;64=5:+-\x05\x05B\x05\v\x17F\x15\r\x1a\x03\x11\t\tN\x06\x1d\x10\x15\x16\x07').replace(S("\x1deqALG^"),e.name);s=i.config.initConfigInfo.images.sizes[e.name]}if(r.has(S("2ZYTQRj\\IRFXz^4 "))&&r.get(S("\rgbqvwAqf\x7fm}]{o}")).has(S(">M%2+9!!\x135$")+s))o.resolve(r);else{var a=r.get(S(".I_]VVF"));i.once(S("5UXUT[UX\x07_Y4$0y\r(' -\x1b/8%7+"),function(t){var i=t.data.context.file,r=t.data.response.url,o=i.get(S("7QT[\\Yo[L);'\x07%1'"));if(o||(o=new n.Model,i.set(S("\rgbqvwAqf\x7fm}]{o}"),o)),e.save){var s=o.get(S("*YI^GUUU"));s||(s={},o.set(S('A0&7,<",'),s)),s.__custom||(s.__custom=[]),s.__custom.push(r.match(T)[0])}o.set(b(e.name,e.size),{url:r}),t.data.context.dfd.resolve(i)}),i.request(S("A!,)('),s9.\")"),{name:S("7qT[\\Yo[L);'"),folder:a,type:S("=NP35"),params:{fileName:r.get(S("\x1fN@OF")),size:s},context:{dfd:o,file:r}})}return o.promise()}function f(t){var n=this.finder,i=t.file,r=e.extend({fileName:i.get(S("\r`n}t"))},t.params);return t.cache?r.cache=t.cache:n.config.initConfigInfo.proxyCache&&(r.cache=n.config.initConfigInfo.proxyCache),n.request(S(";_RSR!/&y17*"),{command:S("+|_AWI"),params:r,folder:i.get(S("\x15pxt}\x7fi"))})}function h(e){var n=this.finder,i=e.file,r=new t.Deferred,o=i.getUrl();return i.get(S("\x18\x7fuwxxl")).getResourceType().get(S(":NOXnM/9;\0+(+&&-"))&&(o=n.request(S("(OCGI\x17IJDa@\\LLcET"),e)),o?r.resolve(o):n.request(S("<^QR- ,'~6#),"),{name:S("8~_OzTRZ\x153."),folder:i.get(S(" GMO@@T")),params:{fileName:i.get(S('"MEHC'))},context:{dfd:r,file:i}}),r.promise()}function g(e){var n=this.finder,i=e.file,r=new t.Deferred;return n.request(S("\x16twtwzry$lEOF"),{name:S("\x1dYzTgKOApTK"),folder:i.get(S("\x19|tpy{m")),params:{fileName:i.get(S("\x1au}p{")),thumbnail:e.thumbnail},context:{dfd:r,file:i,thumbnail:e.thumbnail}}),r.promise()}function p(t,n,i,r){var o=i.get(S("7QT[\\Yo[L);'\x07%1'")),s=o&&o.get(S("\nd~dif~p~@}os"))||"",a=i.get(S(".I_]VVF")).get(S("\x10pq\x7f")).imageResize,l=i.get(S("$CIKLLX")).get(S("0PQ_")).imageResizeCustom,u=t.add({label:n.lang.chooseResizedImage.originalSize,size:s,name:S(")EYEJGAQ]"),isActive:!0,isDefault:!1}),c=o&&o.get(S("\f\x7fk|ykww")),d=!0;if(e.forEach(r.sizes,function(i,r){var o=i,l=a;if(!e.isArray(n.config.resizeImages)||!n.config.resizeImages.length||e.contains(n.config.resizeImages,r)){if(c&&c[r]){var u=c[r].match(I);2===u.length&&(o=u[1]),l=!0}else if(s){var f=s.split("x"),S=i.split("x"),h=parseInt(S[0]),g=parseInt(S[1]),p=parseInt(f[0]),m=parseInt(f[1]),w=v(h,g,p,m);p<=w.width&&m<=w.height?l=!1:o=w.width+"x"+w.height}t.add({label:n.lang.chooseResizedImage.sizes[r]?n.lang.chooseResizedImage.sizes[r]:r,size:o,name:r,isActive:l,isDefault:d&&l}),d=!1}}),c&&c.__custom){var f=[];e.forEach(c.__custom,function(e){var t=e.match(I);t&&(t=t[1],f.push({label:t,size:t,width:parseInt(t.split("x")[0]),name:_+"_"+t,url:e,isActive:!0}))}),e.chain(f).sortBy(S("\ryftez")).forEach(function(e){t.add(e)})}if(l){var h=0,g=0;if(s){var p=s.split("x");h=p[0],g=p[1]}t.add({name:_,custom:!0,isActive:l,isDefault:!1,width:h,height:g,size:h+"x"+g})}t.findWhere({isDefault:!0})||u.set(S("\ve~Jjvpg\x7f`"),!0)}function v(e,t,n,i){var r={width:e,height:t},o=e/n,s=t/i;return 1===o&&1===s||(os&&(r.width=parseInt(Math.round(n*s)))),r.height<=0&&(r.height=1),r.width<=0&&(r.width=1),r}function m(e,t,n,i,r){function o(t,n){e.request(S("\rb`quwa.}\x7fs}")),e.fire(S('"EMIC\x1dKAED_H\x14]UB[IQQ\x7fZY^_'),{file:t,resizedUrl:n},e),x(e)}if(t===S("9UIUZWQ!-"))return void w(e,i);0===t.indexOf(_+"_")&&(t=_);var s=i.get(S("\x1cts~GDpFWL\\BlH^J")),a=b(t,n);if(s&&s.has(a)){var l=s.get(a),u={file:i};if(l.url)return void o(i,l.url);var c=S("\x18\x7fswy'yzTtPO");return t!==S("@.0*#,(&$")&&l.fileName&&(c=S("\x1dwrAFG\x19C@RuMZCQII{]\\"),u.thumbnail=l.fileName),F(e),void e.request(c,u).then(function(e){o(i,e)})}F(e),e.request(S("C-(' -s8.?$4*"),{file:i,size:n,name:t,save:r}).then(function(e){o(e,e.get(S("\x17qt{|yO{lI[GgEQG")).get(a).url)})}function w(e,t){var i=t.getUrl(),r=new n.Collection([t]);return i?void l(e,r):(F(e),void e.request(S("\vjdbj*vwgAgz"),{file:t}).then(function(){e.request(S("\x1aws|zzR\x1bJJ@@")),l(e,r)}))}function C(e,t){e.data.toolbar.push({name:S("\x16Tpvuhy"),type:S("\x14wcclvt"),priority:M,icon:S("\x0fszt>w}yxk|"),label:e.finder.lang.common.choose,action:t})}function y(t){var n=t.get(S(".I_]VVF")).get(S("/QR^")),i=t.has(S(">V- %&\x16 5.2,\x0e*8,"))&&!!e.size(t.get(S("!KNEBCuMZCQIiO[Q")).get(S("\x14gsdqc\x7f\x7f")));return n.imageResize||n.imageResizeCustom||i}function b(e,t){var n;return n=e===_?S("*YI^GUUUgAXjUBKMUV")+t:S("\x13fpe~b|~NnqA")+e}function x(e){e.config.chooseFilesClosePopup&&e.request(S("\x0el|~avDzfbh"))}function F(e){e.request(S("-B@QUWA\x0eF^XO"),{text:e.lang.files.gettingFileData+" "+e.lang.common.pleaseWait})}var _=S("$zyD]Z^DA"),E=100,M=110,I=S("\f%U?=(O8lN&:!D12G3CDA\fXb\t\x7f{\\\x19\x05\x1fV\b"),T=S("\x1953GC1B\v\x05\v");return r}),CKFinder.define(S("*hgkGATT@\x1cb\\S@K\x16xZOX\x11v.26\"*1i\x04'%&./9' >\x07;6#"),[S("4@XS]KIXSO["),S("\x18sknyog"),S("\x14xweqvt~hi{"),S("\vOFHf~uwa;C\x7froj5Y}n{0cNONKK")],function(e,t,n,i){"use strict";var r=n.CollectionView,o=r.extend(i.proto),s=o.extend({constructor:function(e){i.util.construct.call(this,e),r.prototype.constructor.apply(this,Array.prototype.slice.call(arguments))},_renderChildren:function(){this.destroyEmptyView(),this.attachCollectionHTML(""),this.isEmpty(this.collection)?this.showEmptyView():(this.triggerMethod(S("\x13vppxj| iyszzR\x1bALHICD\\@EE"),this),this._showInstantCollection(),this.triggerMethod(S("?2$,'!7|$'%&./9' >"),this),this.children.isEmpty()&&this.getOption(S("$COK\\LX"))&&this.showEmptyView())},_onCollectionAdd:function(e,n){var i=n.indexOf(e),r=this.getChildViews(),o=t(this.instantRenderChild(e));this.destroyEmptyView(),i>=r.length?this.$el.append(o):o.insertBefore(r.eq(i)),this.triggerMethod(S("7[QSWXKWZ7{0&*!#5"))},_onCollectionRemove:function(e){var t=this.getChildViewElement(e).remove();this.removeChildView(t),this.checkEmpty()},_sortViews:function(){var t=this._filteredSortedModels(),n=e.find(t,function(e,t){var n=this.getChildViewElement(e);if(n.length){var i=this.getChildViews().index(n);return i!==t}},this);n&&this.resortView()},_showInstantCollection:function(){var t=this._filteredSortedModels(),i=[],r=this.getOption(S("2P\\\\ZSnP_LsMJV//1"));r=n._getValue(r,this,[void 0,0]),e.each(t,function(e,t){i.push(this.getPreRenderer(e).preRender(e,r,t))},this),this.attachCollectionHTML(i.join(""))},buildChildView:function(t,i,r){var o=e.extend({model:t,finder:this.finder},r),s=new i(o);return n.MonitorDOMRefresh(s),s},getChildViewElement:function(e){return this.$(document.getElementById(e.cid))},attachCollectionHTML:function(e){this.el.innerHTML=e},getPreRenderer:function(){throw S("\x17Vvn;upnsELGMP@B")},getChildViews:function(){throw S("\x14[yc8pwkpxszNUGG")},instantRenderChild:function(){throw S("&iG]\nBA]BJ]T\\GQQ")}});return s}),CKFinder.define(S(",neiY_VVF\x1a{X\\LV^O\x12xV,$1l\x12,#0;f\t$! !!\x7f\x17;?1&\0>=.\x172$40"),[S(':NRY[M3"-1!'),S("6]IL_IE"),S("\x1b_VXvNEGQ\vpRND\x06aNUnAKU")],function(e,t,n){"use strict";function i(e){return S("0RZZXQ@^]N\0")+S(e.get(S("\f{gjg+{`Rzzs}k"))?"(OEGHH\\":",KGCU")+":"}var r=700,o=500,s={getMethods:function(){return{shouldFocusFirstChild:function(){if(this.el===document.activeElement&&this.collection.length){var e=this.collection.first();return e.trigger(S("8_UXIN"),e),!0}return!1},getEmptyViewData:function(){var e,t=!1;if(this.collection.isLoading){var n=this.finder.lang.files.loadingFilesPane;e={title:this.finder.lang.common.pleaseWait+" "+n.title,text:n.text},t=!0}else e=this.collection.isFiltered?this.finder.lang.files.filterFilesEmpty:this.finder.lang.files.emptyFilesPane;return{title:e.title,text:e.text,displayLoader:t}},updateHeightForBorders:function(e){var t=parseInt(getComputedStyle(this.el).getPropertyValue(S("*[MIJF^V\x1fG[E"))),n=parseInt(getComputedStyle(this.el).getPropertyValue(S("/@PVW][Q\x1aZVNOSP"))),i=parseInt(getComputedStyle(this.el).getPropertyValue(S("\x13vzds}k7osm3hIEVK"))),r=parseInt(getComputedStyle(this.el).getPropertyValue(S("\x1aysozzR\f@LPQIJ\x05^COXE"))),o=e.height-t-n-i-r;return this.$el.css({"min-height":o}),o},checkDoubleTap:function(e){var n=e.currentTarget.id,r=t(e.currentTarget),s=r.data(S("D&-!e $f8\";,8|3'")),a=e.timeStamp;r.data(S("C'. j!'g?#8-'}0&"),a);var l=s&&a-s1:##"));s&&clearTimeout(s);var a=this;s=setTimeout(function(){if(o.data(S('\vofh"y\x7f?g{`u\x7f'))){var t=a.collection.get(n);if(!t)return;a.trigger(i(t)+S("\rb`~vf|av~"),{evt:e,model:t}),o.data(S("\x11qxr8\x7fy5mun\x7fu"),!1)}o.data(S("(JAM\x01D@\x02D^GP\\\x18B^U\\UNH"),void 0)},r),o.data(S("\x17{r|6us3kOTAK\tQOJMF__"),s)},touchend:function(e){var n=e.currentTarget.id,r=t(e.currentTarget);if(this.checkDoubleTap(e),r.data(S("7[R\\\x16US\x13K/4!+"))){var o=this.collection.get(n);if(!o)return;this.trigger(i(o)+S("2PX\\U\\"),{evt:e,model:o})}r.data(S('"@OC\vNF\x04^DYNF'),!1)},touchcancel:function(e){t(e.currentTarget).data(S("(JAM\x01D@\x02D^GP\\"),!1)},touchmove:function(e){t(e.currentTarget).data(S("\x1fCJD\x0eMK\vSG\\IC"),!1)},contextmenu:function(e){var n=e.currentTarget.id,r=this.collection.get(n),o=t(e.currentTarget);o.data(S("\x1fCJD\x0eMK\vSG\\IC"))?e.preventDefault():this.trigger(i(r)+S("\x0fs~|gqmbz}wo"),{evt:e,model:r,el:document.getElementById(n)})},click:function(e){var t=e.currentTarget.id,n=this.collection.get(t);this.trigger(i(n)+S("\x1c~rvCJ"),{evt:e,model:n,el:document.getElementById(t)})},dblclick:function(e){var t=this.collection.get(e.currentTarget.id);this.trigger(i(t)+S("2*}=3\x01\x12\x11^F\x10\x0fJ\x04\x06\v\x0f\t\x1fN\x1a\x19\\\x1e\x1c\x15\x11\x13\x05U\x0f\x1f\t\x1e\x12\r\x1a tk.gjhsmg~+yd#m\x7fuk>on+7qm4hk|j|H\x01_^\x04PO\nKFXEI_\x03N\\]\x10\r><\nDHXT\x1b_Q_L3|`6-h/$''g'#,*&>6pmhz%'97dQUa6n^\x1a\x19^D\f\x12I\x1c\0\x1e\x07\tM\x13\x12L^\x1aBJ\x7fJX\x1c\x10\fEv\x06\x05@?|\x7f\t8aoq(jfj\x7f~3-szt>r|zrk4suzr3}OE[\x03QL\vDGG^NBY\x0eZY\x1cP\\PL\x1bLC\x04\x1aRH\x13MH!5!+d8;g= g(#? *\"|3?8wh]Qe2ib&%b@\b\x16M\x10\f\x12\v\rI\x17\x16PB\x06]N{{\b\x0fJV\x1e\fW\x1e\x12\x0f\r\x12\x1eyMmb``t'ut6{2vu20xf=`pnc8dg'3m d[\x1e_^.\x19\tCA_\x14!WV\x11RM;")}),CKFinder.define(S("D\x06\r\x01!'..>b\x03 4$>6'z\x10>4<)t\n4;(\x13N!\f\t\b\t\tG/\x03\x07\t\x1e'\x01\x16\x1e$\x1a\x11\x02"),[S("\x1b~|}tBNLF"),S('1qxr\\XS]K\x15mUXILo\x03#0!j\x0f3-$\x1c"):'),S("\x0e{uif2W^P~v}\x7fi3I{rPMCWAV\taAEOX\x03kGCUB{]RZ\x18SWM")],function(e,t,n){"use strict";var i=t.extend({name:S("4s_[]JsUZRhV%6"),template:n,className:S("\x19ypz0xvLDQ\x0eMK@H"),templateHelpers:function(){return{swatch:this.finder.config.swatch}},initialize:function(){this.model=new e.Model({title:this.title,text:this.text,displayLoader:this.displayLoader})}});return i}),CKFinder.define(S("\x0fdtjg5V]Qqw~~n2JzMQNBP@U\bn@FN_\x02hF\\TdZQB\x18SWM"),[],function(){return S("\x18%{;to{y\x1d\x03HBRDUDZ@Z_\x16[AFT\x19\x02\x1a\x16\x15U[YJI\x06\x1e^UYm'+/!6k.&'/9l8'b2%>$`|rQCB\x07\x16\x04\x01\0\t\v\x06\x0eQO\x1a\x1d\x05\x14PS\x06\x1a\x1a\x12E[\x16\x12\x0f\t\x17\vel #ewof%ekiia3-kj33}a8yyt\x7f;a`*4;(]C\x19\x18YE\x0f\x13F\r\x18\n\v=\x1c\n\x06\x18\x17\x04=\x11V\n\x05[Z\x1f\x1d\t\x1fRcjd.rlcp5+qp1-g{>r{w4hk5&\x13\x13'upy?IE\x1f\x01_^\x1b\x07A]\x04O^LI\x7fBTDZQB\x7fS\x18DG\x19\x1c^R^32\x7fa1,k+!d>#9 ,mp0>'iwtw++9f~&%b@\b\x16M\x03\0\x12.\v\x06\x04CEM\x13\x12RQ\x16\x01\x15\x12\x11\x16\x1a\x15\x1fF^\t\f\ne#\"geqg*kbl&h\x7foh=a`vb|s`%;a`!=wk\x0eEPBCuTB^@O\\eI\x0eRM\x13\x1d\r>a\x7f%$AA\v\x17J\v\x07\n\rI\x17\x16NM\n\x06\x02LP\x12\x01\x01\x19UF\x02\x01Z\\\x14\nQn`of$x{;'a85wv1rm\x1b\x1b\x1a(e6sjx}|}\x7frz\x1d\x03VQQ@\x04\x07AM\x17\tWV\x0f\x0fYE\x1cWQFUEQINRSSw[`=.gy'&c\x7f\t\x15L\x07\x16\x04\x017\x1a\f\x1c\x02\t\x1a'\vP\f\x0fQJ\x7f\x7f~q\x02\x01D\\\x14\nQdhqshd\x7fCi}o+qput11{g:ywy\x7f7|tnp\x7fkd@VFwQTNFN\x02\vEY\0KQEW\x13\x1d\x15KJCB\x05FA776I:9|d,2i, 9; ,7\x1c9+7s)(\\^QPS 'b~6\x14O\x06\n\x17\x15\n\x06\x11-\v\x1f\tM\x13\x12L\x13\0M\x0f\x0eI\n\x05ssrut\x05\x04!!kw*igio'ld~`o{Vx~vG|lr09so2nweE\x01\b\x03\x15\x15\x14\x13\b\0\nVQ''&9JI\fIH<>1\x05\x15K\x0277\x03o%+5zOO<3v76Fqa.n[")}),CKFinder.define(S("E\x05\f\x0e $/)?a\x02?5'?1&y\x1115?(s\v7:\x17\x12M7\f\x10\v\x05\x06\b\x03\x07\x1f;\x07\n\x07^4\x1a\x18\x10$\x12\x16\x1d\x1f\t\x19\x0f"),[S("\x11fvla7TS_suxxl0tDOSHDRB[\x06lB@H]\0vX^Vb\\S@\x16]UO")],function(e){"use strict";function t(e,t){this.finder=e,this.renderer=t}return t.prototype.preRender=function(t,n){var i=this.finder,r={lazyThumb:n.lazyThumb, +displayName:n.displayName,displaySize:n.displaySize,displayDate:n.displayDate,descriptionId:S("$FMA\x05OCGI\0JJCR\x1f")+t.cid,dragPreviewId:S("$FMA\x05MXJK\0^]UG\x1f")+t.cid,getIcon:function(){return i.request(S("1TZXP\fP]MsXSS"),{size:n.thumbSize,file:t})}},o=S("(\x15FB\fDJ\x12\x12")+t.cid+S(":\x19\x1c^R^32\x7fa'. j. &.a$:*=q':y9?z08)v(5+2\x02")+S(t.isImage()?"-\x0eL[W\x1f_UOO\x1aLQOV^":'?`")%i#/+-d#(##')+'"'+(n.mode===S("\rbfce")?"":S("\f-}{i}w.6b\x7fslq ")+n.thumbSize+S("3DM\r_]P]SH\x07")+n.thumbSize+S("/@I\t\x11"))+S("Ab'%1'j!*%%qo(.<\"7qt'9;=dx+.8-:\x0e\x15\x03\x17\r\n\bE")+">";return o+=this.renderer.render(t,S("3r\\ZRlQOV^"),e,r),o+=S("\x1a'3qw!")},t}),CKFinder.define(S('\x1djzXU\x03`ocOILLX\x04xHC_\\PFVG\x1ap^T\\I\x14zRR[%3\v-\x02,*"f-%?'),[],function(){return S('\x14)w7{u{ho <|KG\x0fEMICT\x05@DEI_\x0eZY\x1cPGZ\x17\x16CY[SUXXF\x02blsad!4&/.+) (sm60> 1wv39-;v?68r\x04\x13\r\x13YG\x12\x15\x1d\fHUfdR\x06\x1d\x16R\x10\x18\x14\x05\x04E[\x0f\x12Q\x11\x17Rtiwnf\'&fd}7)wv//ye<\x7fuws{8ef;ui0qALG\x03YX\x04\x07[[I\x16\x0eVU\x12\x10XF\x1dSPB~[VT\x13\x15\x1dCBba&"0$k$#/g/>">rr% &1wh]RPf?5+~<\f\0\x11\x10YG\x05\f\x0eD\f\x02\0\bC\v\x15\x02\x11S\x01\x1c[\x15\x19\vW\0\x07@^\x16t/aljco`&z}jxnf/ml0-\x1e\x1c\x1f+p+:ouirz\x1d\x03YX\x05\x05OS\x06EKIIA\x0eSL\x11[G\x1a[WZ]\x19GF\x1e\x1dZ^4 o /#k#:&:vn9<:5sl(/tv>,w6:>82\x7f\x1c\x1dB\n\x10K\b\x06\x05\fJ\x16\x11QA\x07BOxzHZ\x12\x1e\x0eGpGS\x1c@u')}),CKFinder.define(S("\x19YPZtp{ES\rnKASKMZ\x05mEAK\\\x1fg[VCF\x19cPLWYR\\WS3\x17+&3j\0($-/9\x1e( +5#7!"),[S("@5';0d\x05\f\x0e $/)?a\x1b5<\"?5!3$w\x1f379.q\x19\x0f\r\x06\x06\x16,\b!\x01\x05\x0fE\b\x02\x1a")],function(e){"use strict";function t(e,t){this.finder=e,this.renderer=t}return t.prototype.preRender=function(t,n){var i=this.finder,r={lazyThumb:n.lazyThumb,displayName:n.displayName,displaySize:n.displaySize,displayDate:n.displayDate,descriptionId:S("\x17{r|6ztrz\rEGPG\b")+t.cid,dragPreviewId:S("$FMA\x05MXJK\0^]UG\x1f")+t.cid,getIcon:function(){return i.request(S("E ($-/9v*+;\x192=="),{size:n.thumbSize,folder:t})}};return S("2\x0fX\\\x16^\\\x04\x18")+t.cid+S('\x1103wywdk$8xw{3yIMG\x0eMQCJ\bJAM\x01KACTT@@\x19\\BRU\x1b\x1a_]I_\x12)"--yg &$:/il?!#5lp#&0%26-;/520}')+(n.mode===S("5Z^KM")?"":S("(\tY_UAK\x12\x12F[W@]\f")+n.thumbSize+S("\x10aj(|p\x7fppm ")+n.thumbSize+S(""+this.renderer.render(t,S("\x14Sy{||hOths}"),e,r)+S('\v0"bf.')},t}),CKFinder.define(S("*hgkGATT@\x1caA_[\x17mRISIJS%31"),[S(".&"),S("0ryu][RRJ\x16wTXHRZ3n\x04*( 5h\x1e /a\t9=7 {\x03?2/*u\x0f4(3=\x0e\0\v\x0f\x173\x0f\x02\x1fF,\x02\0\b<\n\x1e\x15\x17\x01\x11\x07"),S("<~uy)/&&6j\v(,<&.?b\b&<4!|\x02<3 +v\x0e3)0<1\x01\b\x0e\x102\f\x03\x10G/\x05\x07\b\b\x1c=\x15\x1f\x16\x16\x06\x10\x04"),S("\x16TS_suxxl0uUKO\vqNUG]^GI_]")],function(e,t,n,i,r,o,s,a,l){"use strict";var u=1e3,c=400,d=500,f={name:S("\x1ftIWNFKGNDZ|BIZ"),reorderOnSort:!0,className:S("'KBL\x06JDBJC\x1cDZQB\x16TS_\x17]UQ[Lm7+&3h$(:-/9?m;&}3=7-x?90<(2("),attributes:{"data-role":S("\x1fLHQWRLCP"),tabindex:30,role:S("\x1awunj")},tagName:S("\x0fe}"),invertKeys:!1,collectionEvents:{change:function(t){var i=t.changed;if(i.name||i.date||i.size){var r=this.getChildViewElement(t),o=this.getOption(S("'KACGH{GJG~BG]ZXD"));o=n._getValue(o,this,[void 0,0]);var s=e.defaults(o,{lazyThumb:this.finder.request(S("4S_[]\x03]^HiVJ-#"),{file:t,size:o.thumbSizeString})});r.replaceWith(this.getPreRenderer(t).preRender(t,s)),this.triggerMethod(S("5U_QU^MUXI\x052$,'!7"));var a=this.getOption(S("#@LUWDHShCCHFW")).get(S(")^CY@L|YKW"));this.getOption(S("-JFCA^RMvYY^P]")).get(S("+ABJJ"))===S("1F[AXTD")&&this.resizeThumbs(a)}}},initialize:function(e){var t=this;if(e.displayConfig.set({mode:S("0][@@"),thumbSizeString:null,currentThumbConfigSize:0,thumbClassName:""}),e.mode===S("0EZFYWE")){var n=t.getOption(S("6SQJJW]D}P.'+$")).get(S(';HUKR"\x12+9!'));this.calculateThumbSizeConfig(n),this.resizeThumbs(n),this.applyBiggerThumbs(n),t.setThumbsMode()}else t.setListMode();r.attachModelEvents(this.collection,this),t.on(S("\fkgcu+t|w`er|"),function(e){var t=this;setTimeout(function(){var n=t.$el.closest(S("1iWUAW\x1aJVV^\x01\x1fN^'$`\x1e")),i=parseInt(t.$el.offset().top),r=t.collection.indexOf(e),o=t.getThumbsInRow();if(r=a&&window.scrollTo(0,n.outerHeight())},20)}),t.once(S("%TBFMOY"),function(){t.$el.trigger(S('A!1!$2"')),t.$el.attr(S("\ro}yp?\x7fuws{"),t.finder.lang.files.filesPaneTitle)}),t.once(S("+_EAX"),function(){function e(e){t.trigger(S("2PX\\U\\"),{evt:e})}var n=t.$el.closest(S("'\x06JAM\x01]OHU\x1c@VS\\YYK"));n.on(S("C')/$#"),e),t.once(S(".KUBFA[L"),function(){n.off(S("<^RV#*"),e)})}),t.on(S("\x1dlzNEGQ"),function(){var e=t.finder.request(S('5PXT]_I\x06Z[K\x01"6*2 ')),n=e&&e.cid;t.finder.config.displayFoldersPanel||t.lastFolderCid||t.focus(),t.lastFolderCid=n,t.getOption(S('E".;9&*5\x0e!!685')).get(S("\x0eb\x7fuw"))===S("$IOT\\")?t.setListMode():t.setThumbsMode()}),t.on(S("2^UM_ZQC_"),t.updateHeightForBorders,t)},childViewOptions:function(){return this.getOption(S("(MCX\\AOVs^\\U]R")).toJSON()},applySizeClass:function(t){var n=this,i=!1;e.forEach(n.finder.config.thumbnailClasses,function(e,r){!i&&t=t}),r=e.isEmpty(i)?e.max(n):e.min(i),o=this.getOption(S('9^ROMR^9\x02--",!')).get(S("\x1ekHTOAJDOKkFDMEJ]"))[r];return this.getOption(S("\x10u{`dywn[vt}uz")).set(S("\x14a~bu{IrfxMkRHLD"),o.thumb),this.getOption(S(")NB_]BNIr]]R\\Q")).set(S("%ERZ[OEXyFZ]Sq\\ZS_PkP@^"),r),o}},resizeThumbs:function(e){this.$el.find(S("(\x07I@J\0HF\\T\x1fZ@P[")).css({width:e+S(";LE"),height:e+S("7HA")});var t=this;setTimeout(function(){t.trigger(S('=MV:$\x173 $2"r(,?)?'))},c)},applyBiggerThumbs:function(e){var n=this;if(e&&n.getOption(S("\x1fDHQSHD_dGGLBK")).get(S("?-.&&"))===S(">K(4/!7")){e=parseInt(e,10),this.applySizeClass(e);var i=this.getOption(S("@%+04)'>\v&$-%*")).get(S("\x1e|USPFJQrO]DHhCCHFWb[IQ"));if(!i||e>i){var r=this.calculateThumbSizeConfig(e);l.getOrCreate(S("\nmeak|*cw`}os"),function(){n.$el.find(S("%JN")).not(S("3\x1aV]Q\x15_SWY\x10W\\//")).addClass(S('A!("h*&20g?$8#-')),n.$el.find(S('D)/i+",f*$"*}81<:')).each(function(){t(this).find(S("%OJO")).attr(S("C77%"),n.finder.request(S("\rhf|t(tqa_tww"),{size:e,file:n.collection.get(this.id)}))}),n.$el.find(S('D)/i+",f*""+5#!~=!3:x07<')).attr(S("=MM#"),n.finder.request(S('C"**#-;p,)9\x07,??'),{size:e})),n.children.invoke(S(".[BXUTQG"),S("3G\\LRmI^ZHX"),{thumbSize:e,thumbSizeString:r.thumb}),n.trigger(S("\x1ahug{JPECWA\x1fGA\\LX"))}).runAfter(d)}else setTimeout(function(){n.trigger(S("\nxewkZ`usgq/wql|h"))},c)}},setListMode:function(){this.getOption(S("-JFCA^RMvYY^P]")).set(S("%~ =#::')),n.data(S("\x19ypz0zzSBPJTQOHF\x04^BAHAZD"),void 0)},u);n.data(S('E%,.d..?.<& %;<:x">5<5.('),i)},"mouseleave img":function(e){var n=t(e.currentTarget).closest(S("3X\\")),i=n.data(S("*HGK\x03KUBQA]EB^WW\x17OUP[P55"));i&&(clearTimeout(i),n.data(S("5U\\^\x14^^O^LV05+,*h2.%,%>8"),void 0)),n.removeClass(S("\x1axw{3yIMG\x0eWMIP\x05]B^AO"))}},r.getEvents(S("\x1bpt")));var h=i.extend(f);return h}),CKFinder.define(S('\x1aoyej>cjdJJACU\x07}OF\\AO[UB\x1du]YSD\x17uSHH\x12xV,$\v ++\x05"$%d/#9'),[],function(){return S("9\x06RQZ\x1eV$|`8?xf.a\x7f*-\x15\x04@C\0\x04\x12\x06E\n\x01\rA\t\x1c\x0e\x17\\\x02\x01\x11\x03\x1f\x12\x0fDX\0\x07@^\x16t/fqebVum\x7fcn{Dj/ml03`|b{}$8`g<>vT\x0fLBI@\x06ZU\v\x14!%\x11]_Q_\x12W]G\v\x15YLNT\x1e\x1d]S!21~f&-!e/#')>c&>?7!vk-,yy3/r3?2\x05A\x1f\x1eXJ\x15\x17\t\x07TaPB\x0fQz")}),CKFinder.define(S("5u|~PT_YO\x11r/%7/!6i\x01!%/8c\x1b'*'\"}\x1f=&\"\x011<-t\x1a42:2\x0e\x151\x01\v\x02\x02\x1a\f\x18"),[S("8LT_YOM\\/3'"),S("\x0fdtjg5V]Qqw~~n2JzMQNBP@U\bn@FN_\x02bFCE\x1du]YS~[VTxYQR\x11$.6"),S("\x11fvla7TS_suxxl0tDOSHDRB[\x06lB@H]\0|XAG\x1bs_[]w[VY~[S,o&,0")],function(e,t,n){"use strict";function i(e,t){this.finder=e,this.renderer=t}return i.prototype.preRender=function(i,r){var o=this.finder,s=this.renderer,a={lazyThumb:r.lazyThumb,displayName:r.displayName,displaySize:r.displaySize,displayDate:r.displayDate,descriptionId:S("%ELN\x04LB@H\x03KUBQ\x1e")+i.cid,dragPreviewId:S("%ELN\x04NYMJ\x03_BTD\x1e")+i.cid,getIcon:function(){return o.request(S("A$*( | -=\x03(##"),{size:r.listViewIconSize,file:i})}},l=S('"\x1fPW\x06NL\x14\b')+i.cid+S("4\x17\x16TTXIH\x01\x1f]T&l$*( k.<,'ir");return r.collection.forEach(function(r){var u=r.get(S("\x10\x7fs~q"));if(u===S("\x0fyr}}"))return void(l+=s.render(i,S('C\x02,*"\x01*%%\x0f("#\x0687$'),S("\x0e3du,")+t+S("\x18%5ox#"),a));if(u===S(">Q!,'"))return void(l+=s.render(i,S("<{WS%\x0f#.!\x06#+$\x1f#.;"),S("2\x0f@Q\x16TTXIH\x01\x1f]T&l$*( 5j$ 9?a;'*'|1<8x865\r%!+\x1c9+7{t<"y+0 >|w~nPSVCME\x1b\x1aTF\x1e\x0fR'),a));if(u===S("$@KW\\P"))return void(l+=s.render(i,S("\x1cXsoTXaFHIpNM^"),S('Cx1"ytf>/r'),a));var c={template:void 0,templateHelpers:void 0};o.fire(S("\x12\x7f}fbAq|m!ztrz\x1aBMOQHH\x1d")+u,c),l+=c.template&&c.template.length?s.render(i,S("3w@ECWT|RPX}Z,-\x14*!2k")+u,c.template,e.extend({},a,c.templateHelpers)):s.render(i,S("\nNa}zvSt~\x7fB|s`"),S(")\x16_H\x13\x12\0DU\f"),a)}),l+=S(">\x03o50}")},i}),CKFinder.define(S("\x11fvla7TS_suxxl0tDOSHDRB[\x06lB@H]\0|XAG\x1bsY[\\\\Hu]P[|%-.m *2"),[],function(){return S("\n7m-mcqba.6`\x7f:zmt9\x03o5&}"),a));if(u===S("\x19tzqx"))return void(l+=s.render(i,S("2u]YSyYT_xYQRi)$5"),S("\x0e3du2pxted%;ypz0xvLDQ\x0eHLUS\x05_CN[\0M@\\\x1c\\RYP\x16BQ\x14XTXD\x13V.)'1-1dy")+n+S(",\x11\x01[T\x0f"),a));if(u===S("\x13qxfca")||u===S("\x0e|ykw")||u===S("1VR@P"))return void(l+=s.render(i,S("\rKb`ekPqyzAq|m"),S("\x0f,ev-(:bs&"),a));var c={template:void 0,templateHelpers:void 0};o.fire(S("\nge~zYyte)rzzs}k xsqkrN\x1b")+u,c),l+=c.template&&c.template.length?s.render(i,S(";\x7fHMK/,\x04,(!#5\v,&'\x1a$+8}")+u,c.template,e.extend({},a,c.templateHelpers)):s.render(i,S("*nA]ZVsT^_b\\S@"),S("!\x1eW@\x1b\x1a\b\\M\x14"),a)}),l+=S("\x1e#\x0fUP\x1d")},i}),CKFinder.define(S(",YKWD\x10qxr\\XS]K\x15oYPNS!5'0k\x03/+-:e\x07%>:`\x1c8!'\x02<3 v=5/"),[],function(){return S('\n7xllcu1q\x7fufe*:zq}1{wsER\x0fUM@Q\x07KBL\x06JDBJC\x1c^ZGA\x1bAQ\\M\x19\x027\x02K($#\'zOO{<;tAED54.q;\'z69;-44(r01;\x05\r\x11C^E\x05\b\x04\x1c\x07\x05L\x10\x13eyx{O\0\x1d\r\fGY\x19\x14\x10\b\x13\x11.fgw,\'uhz}(",ps/tpfr9v}q5juih e?"<;\x12(r.)__^QPSg/-?1@\x02\x0e\x02\x17\x16[E\v\x02\fF\n\x04\x02\n\x03\\\x1e\x1a\x07\x01[\x01\x11\x1c\rV\x0f\x12\f\ves =\x7f~9\'a}$xc\x7fzMi^`wqg6*%$:<}n}8\0\\_X_\x18\x06N\\\x07KXO\rSRKJ\r\f\x14\\B\x19KVHO~DqM$$0cyx{go-/8/jn2-*)nt<"y<<)8| #$\x1b^\x1f\x1eXJ\x15\x17\t\x07Taedgf\v\nM\x0e\t\x7f\x7f~qEU\x0f\x14Ctv\tzy}yx\f\x0e4&~y2\x072 dywrp+\x1c+l{u\x7fe#"0TCMG]\x1b,\x1b\x07]KI@H\x10%')}),CKFinder.define(S('\x1ci{gT\0ahbLHCM[\x05\x7fI@^CQEW@\x1bs_[]J\x15}UQ[L\t/$,\r+\n.;=\x1c"):`+?%'),[],function(){return S("3\bAR\t20\x06_UK\x1e\\, 10yg%,.d,\" (=b9?4k9$c-?5+~/.kw1-t(+<*<\bA\x1f\x1eD\x10\x0fJ\v\x06\x18\x05\t\x1fC\x0e\x1c\x1dPM~|\x7fK\x10KD\0\x07@^\x16t/vjpic'ut6$d?0\x05\x19\x18ih+5\x7fc6}shlq\x7fflNCGAW\x06ZU\x15Z\x15WV\x13\x0fYE\x1cGQMB\x17ED\x06\x14L\x03ED\x7f.gPgs):aj")}),CKFinder.define(S("+ofhF^UWA\x1bxYSMU_H\x13{WS%2m\x15- 14g\x05#88\x1b'*'"),[S("?5/&&66%(:,"),S(":QMH[M9"),S("/RPQXVZXR"),S('@,#1-*("<=/'),S("\x19YPZtp{ES\ruM@QT\x07kKXI\x02gACES]@\x1auXTU_XHTQQ\x16('4"),S("5u|~PT_YO\x11r/%7/!6i\x01!%/8c\x1b'*'\"}\x10;8;86v\x1c208-\t\t\x04\x15.\r\x1d\x0f\t"),S("\x1c^UYIOFFV\nkHL\\FN_\x02hF\\TA\x1cb\\S@K\x16vROIhV%6m\x05-)#\x15'>\x18.\")+=5#"),S("\x14V]Qqw~~n2SpDTNFW\n`NDLY\x04zDKXC\x1e~ZGA`^]N\x15}SQZZ2\x13-4\x16 (#-;/9"),S('@\x02\t\x05-+"":f\x07$(8"*#~\x14:80%x\x0e0?,/r\x1d0\r\f\r\rK#\x0f\v\r\x1a#\x05\n\x028\x06\x15\x06'),S("\x16c}an:_VXvNEGQ\vqCJXEK_I^\x01iY]W@\x1by_DL\x16vROIhV%6l'+1"),S("6C]AN\x1a\x7fvxV.%'1k\x11#*8%+?)>a\t9=7 {\x13?;=*\x135:2\x171,\b\x11\x172\f\x03\x10F\r\x05\x1f")],function(e,t,n,i,r,o,s,a,l,u,c){"use strict";var d={name:S("\x11^zga@~}n"),attributes:{tabindex:30},tagName:S("?$(4"),className:S("(JAM\x01KGCUB\x1fE]PA\x1aZVH_YOM\x1f5(o!+!?j!'\".>$:"),reorderOnSort:!0,childViewContainer:S("\x13`wysa"),template:u,invertKeys:!0,initialize:function(e){this.columns=new n.Collection([],{comparator:S("\v|\x7fg`bxfj")}),this.model=new n.Model,o.attachModelEvents(this.collection,this),this.model.set(S("\x1azo~"),S("\x1c;=&\x16\x14\x12\x18")),this.model.set(S("D!#4+"),S("\x1b:>')\x16\x11\x19")),this.updateColumns(),this.listenTo(e.displayConfig,S("\x16tpxt|y'mpRU`Z"),this.updateSortIndicator),this.listenTo(e.displayConfig,S("B ,$( -s9$>9\f6\x1f#66&"),this.updateSortIndicator),this.on(S("\x0f}pjzy|lr"),this.updateHeightForBorders,this)},childViewOptions:function(){var e=this.getOption(S("6SQJJW]D}P.'+$")).toJSON();return e.collection=this.columns,e},onBeforeRender:function(){this.updateColumns()},isEmpty:function(){var e=!this.collection.length;return this.$el.toggleClass(S("(JAM\x01KGCUB\x1f_]FB\x1a]TJOE"),e),e},getEmptyView:function(){var e=this.getEmptyViewData();return l.extend({title:e.title,text:e.text,displayLoader:e.displayLoader,displayInfo:!this.finder.config.readOnly,template:c,tagName:S(" UP"),className:""})},updateColumns:function(){var e=new n.Collection,t=this.getOption(S("'L@Y[@LWl__TZS")).get(S("\x15z~kmLryjW|OOqJ^@"))-4+S("!R[");e.add({name:S("D,%(&"),label:"",priority:10,width:t}),e.add({name:S("/^P_V"),label:this.finder.lang.settings.displayName,priority:20,sort:S("9TZQX")}),this.getOption(S("/TXACXTOtWW\\R[")).get(S("'L@Y[@LW|YKW"))&&e.add({name:S(":HUG["),label:this.finder.lang.settings.displaySize,priority:30,sort:S("5E^B\\")}),this.getOption(S("1VZGEZVAzUUZTY")).get(S("!FJWUJFQmK_I"))&&e.add({name:S("9^ZHX"),label:this.finder.lang.settings.displayDate,priority:40,sort:S("\x0ftpfv")}),this.finder.fire(S('7TPIOjT[Hz"-/1((4'),{columns:e}),this.columns.reset(e.toArray()),this.model.set(S("=]P,4/-7"),this.columns),this.model.set(S("D6)5<\v3"),this.getOption(S("\x0ftxacxtoTww|r{")).get(S("B0+72\x051"))),this.model.set(S("\x1cnqmTc[lVACU"),this.getOption(S("$AOTXEKRoB@IYV")).get(S("0B]A@wOxJ]_I")))},getThumbsInRow:function(){return 1},updateSortIndicator:function(){var e=this.getOption(S("\x19~romr~YbMMBLA")).get(S("\f~a}dSk")),t=this.getOption(S("$AOTXEKRoB@IYV")).get(S(";ORLK\x028\r1 4"));this.$el.find(S("A6+dk%,.d,\" (=b<8!'y#?2/t)4.);-")).html(t===S("\x10pap")?this.model.get(S("\fl}l")):this.model.get(S("\x15rrkz"))).appendTo(this.$el.find(S("+XEuKQES\x1eW^P\x1aKVHO\x01\x1f")+e+S("\x0e-M")))},getPreRenderer:function(e){return e.get(S("#RLCP\x12@YmCAJJB"))?new a(this.finder,this.finder.renderer):new s(this.finder,this.finder.renderer)},attachCollectionHTML:function(e){var t=this.finder.renderer.render(this.model,S("'d@Y_zDKX"),u,{}),n=t.indexOf(S("\x1f\x1c\x0eVAKA_\x19"));this.el.innerHTML=t.substring(0,n)+e+t.substring(n)},getChildViewElement:function(e){return this.$(document.getElementById(e.cid))},getChildViews:function(){return this.$(S('D1"'))},instantRenderChild:function(t){var n=this.getOption(S("%EOAEN}EHY`@E[\\ZF"));n=i._getValue(n,this,[void 0,0]);var r=e.defaults(n,{lazyThumb:this.finder.request(S(")LB@H\x14HUEf[AXT"),{file:t,size:n.thumbSizeString})});return this.getPreRenderer(t).preRender(t,r)}},f=o.getMethods();e.extend(d,f),d.events=e.extend({selectstart:function(e){e.preventDefault(),e.stopPropagation()},"mousedown th[data-ckf-sort]":function(e){e.stopPropagation(),e.stopImmediatePropagation(),e.preventDefault();var n=t(e.currentTarget).attr(S("#@DRF\x05JAM\x01^A]D")),i=this.getOption(S("'L@Y[@LWl__TZS")).get(S("?3.07\x06<"));if(n===i){var r=this.getOption(S("\x1e{IRROE\\eHFOCL")).get(S("'[FX_nTa]TT@"));this.finder.request(S("\x19i~hiwqGR\x18PAQpFD\\O"),{group:S("?&(.&7"),name:S(" RMQPg_hZMOY"),value:S(r===S("-O\\S")?"#@@UD":"C%6%")})}else this.finder.request(S("4FSCLPT\\O\x07MZ4\x17#/1 "),{group:S("*MEAK\\"),name:S("\r}`bePj"),value:n})},"dragstart .ckf-folder-item":function(e){e.preventDefault()},"dragend .ckf-folder-item":function(e){e.preventDefault()},"ckfdrop .ckf-folder-item":function(e){e.stopPropagation();var n=this.collection.get(e.currentTarget.id);this.trigger(S(".LXX^WB\\S@\x02_UWXXL\x05$3-3"),{evt:e,model:n,el:t(e.target).find(S('\n%ofh"vx~vg8\x7fyv|h'))})}},o.getEvents(S("\x11fa")));var h=r.extend(d);return h}),CKFinder.define(S("#P@^S\tjamECJJB\x1efVYEZVL\\I\x14zTRZ3n\x01,)5'$wRDD\x1e\x06OGQIZIYE]Z\x15F^[W\x1c\x05\x1f\x15\x18M[YUSZZ8|`nugf#:(-,-/"*ms&!!0tw<8.:q>59M\x05\x10\x02\x03H\x16\x15\r\x1f\x03\x0e\x1bPL\x14\vLR\x1a\0[\x12\x05\x19\x1e*\t\x19\v\x17\x1awHf#yx$\'|`~gi0,tk02z`;xvu|:fa?>{AUC\x0eGN@\n^@O\\\x11\x0fUT\r\x11[G\x1aV_S\x18DG\x19\x027\x1e\x1f`a~*)"f.,th07pn&$\x7f6!52\x06%=/3>+\x14:\x7f\x1d\x1c@C\x05\t\x12ZJKJ\x18\x1e\x0eSM\v\nOS\x1d\x01X\x10\x1d\r3\x18\x13\x13VV |\x7f!$atfonki`h3-dcgv65rvlx7xw{3{R@E\x0eTWCQAL]\x16\x0eVU\x12\x10XF\x1dPGWPhK_MUXIv$a?>feiyB@v8<, o48 nv4##7{z80<-,]C@]\x1f\x1eGG\x01\x1dD\x05\r\0\vO\r\fN\\\x07\x05\x17\x19FsFT\x1dCt')}),CKFinder.define(S("=}t\x06(,'!7i\n'-?')>a\t9=7 {\x03?2/*u\x1830.>\x03\x154\n\x01\x12I!\x01\x05\x0f9\t\x03\n\n\x02\x14\0"),[S("6C]AN\x1a\x7fvxV.%'1k\x11#*8%+?)>a\t9=7 {\x169:(89/s\x1b73\x05O\x06\f\x10")],function(e){"use strict";function t(e,t){this.finder=e,this.renderer=t}return t.prototype.preRender=function(t,n){var i=this.finder,r={lazyThumb:n.lazyThumb,displayName:n.displayName,displaySize:n.displaySize,displayDate:n.displayDate,descriptionId:S('E%,.d," (c+5"1~')+t.cid,dragPreviewId:S("#GN@\nL[KL\x01]\\JF\x1c")+t.cid,getIcon:function(){return i.request(S("$COKM\x13MNXdM@^"),{size:n.compactViewIconSize,file:t})}},o=S("\x1f\x1cMK\x03MA\x1b\x05")+t.cid+S('6\x15\x18ZVZON\x03\x1d#*$n",*"e >.!on=?=7nv%$2+<4/=)70\x0eC\\');return o+=this.renderer.render(t,S(")iDA]OLDw[_Q"),e,r),o+=S(":\x07\x13QW\x01")},t}),CKFinder.define(S(';HXFKa\x02\t\x05-+"":f\x1e.!=".$4!|\x12<:2+v\x1941-?<\x14N$\f\b\x01\x03\x15F\r\x05\x1f'),[],function(){return S(' \x1dC\x03GIGT[\x14\b^E\0L[^\x13\x12[FPP\n\x1aS[M]N]M)16y2*/#`ycil9/-9?66,htzi{z?.<98\x01\x03\x0e\x06YG\0\x06\x04\x1a\x0fIL\x19\x07\x1b\x1c\x14OQ\x0f\x0eWW\x11\rT\x15\x1d\x10\x1b_}| =\x0e%&\'(5cfk-gk-3ih)5\x7fc6}hz{MlzVHGTmA\x06ZU\v\nJ@Y\x13\r\x12\x11AAW\b\x14LC\x04\x1aRH\x13YZ4\b!,*mog54hk(?/(700?1ht195)>~}qajh^\x10\x14\x04\bG\f\0\x18VN\f\x1b\x1b\x1fSR\x10\x18\x14\x05\x04E[XE\x07\x06__iu,oegck(uv+ey aq|w3ih*8ki{u"\x17"0A\x1f(')}),CKFinder.define(S('!ahbLHCM[\x05fCI[CUB\x1du]YSD\x17oS^KN\x11|/,2"\'1\x10.->e\r#!**"\x037=00$2*'),[S(")^NTY\x0fl{w[]PPD\x18l\\WKP\\JZ3n\x04*( 5h\v&';-.:`\x16>>71'x37-")],function(e){"use strict";function t(e,t){this.finder=e,this.renderer=t}return t.prototype.preRender=function(t,n){var i=this.finder,r={lazyThumb:n.lazyThumb,displayName:n.displayName,displaySize:n.displaySize,displayDate:n.displayDate,descriptionId:S("-MDV\x1cTZXP\x1bS]JY\x16")+t.cid,dragPreviewId:S("9YPZ\x10ZM!&o36 0j")+t.cid,getIcon:function(){return i.request(S(",KACTT@\tSPB~[VT"),{size:n.compactViewIconSize,folder:t})}},o=S("\x1e#LH\x02J@\x18\x04")+t.cid+S("\x1547{u{ho <|KG\x0fEKIBBZ\x04C_I@\f\x0fB^^V\t\x17FE]J_UH\\JV//`}");return o+=this.renderer.render(t,S("?\x03./3%&2\x01'%..>"),e,r),o+=S("\x1a'3qw!")},t}),CKFinder.define(S("\x10RYU}{rrj6WtxhrzS\x0edJH@U\b~@O\\_\x02m@]ASP@c_RO"),[S("\x1chp{ESQ@KWC"),S("\x19pjixlf"),S(';^\\]T".,&'),S("\x17uxhrss{kTD"),S("\x0eL[W{}ppd8Np\x7flo2\\~SD\rjJVRFF]\x05hCABJSE[\\Zc_RO"),S("=}t\x06(,'!7i\n'-?')>a\t9=7 {\x03?2/*u\x183030\x0eN$\n\b\0\x151\x01\f\x1d&\x05\x15\x07\x01"),S(' bieMKBBZ\x06gDHXBJC\x1etZXPE\x18nP_LO\x12}P-1# 0\x13/"?f\f" (\x1c*>57!1\''),S("\x16TS_suxxl0mNFVH@U\bn@FN_\x02xFUFA\x1cwZ[GYZNmUXI\x10\x06..'!7\x14\"&-/9)?"),S("\x1e\\kgKM@@T\beFN^@H]\0vX^VG\x1a`^]NI\x14\x7fRSR//m\x05-)#4\x01',$\x1a$+8")],function(e,t,n,i,r,o,s,a,l){"use strict";var u={name:S("?\x03./3%&2\x11!,="),attributes:{tabindex:30},tagName:S("8LV"),className:S("\x17{r|6ztrzS\fTJAR\vEG[NN^^\x0eL[W\x1fU]YSD\x15ZUVL\\]K`4+n&*\">e $#)?';"),reorderOnSort:!0,invertKeys:!0,initialize:function(e){this.columns=new n.Collection([],{comparator:S("D54.';#?5")}),this.model=new n.Model,o.attachModelEvents(this.collection,this),this.model.set(S("8XIX"),S("\x1b:>')\x15\x11\x19")),this.model.set(S("\x1e{ERA"),S("+\n\x0e\x17\x19\x06\x01\t")),this.updateColumns(),this.listenTo(e.displayConfig,S("\x0fsys}sp,dwknYe"),this.updateSortIndicator),this.listenTo(e.displayConfig,S("0RZRZRS\rKVHO~DqM$$0"),this.updateSortIndicator),this.on(S('"NE]OJASO'),function(e){var t=this.updateHeightForBorders(e);if(this.$el.css({height:""}),this.collection.length){this.$el.css({height:t});var n=Math.round(this.$el.width()/this.getChildViews().first().outerWidth());if(n*this.getThumbsInRow()<=this.collection.length){var i=Math.ceil(this.collection.length/n);this.$el.css({height:i*this.getChildViews().first().outerHeight()})}}},this)},childViewOptions:function(){var e=this.getOption(S("\x16sqjjw}d]pNGKD")).toJSON();return e.collection=this.columns,e},onBeforeRender:function(){this.updateColumns()},isEmpty:function(){var e=!this.collection.length;return this.$el.toggleClass(S("+OFH\x02VX^VG\x18Z^KM\x17^QMJF"),e),e},getEmptyView:function(){var e=this.getEmptyViewData();return l.extend({title:e.title,text:e.text,displayLoader:e.displayLoader,displayInfo:!this.finder.config.readOnly})},updateColumns:function(){var e=new n.Collection;e.add({name:S("\x18pytr"),label:"",priority:10}),e.add({name:S("\x19tzqx"),label:this.finder.lang.settings.displayName,priority:20,sort:S("\x17vxw~")}),this.getOption(S("\x1fDHQSHD_dGGLBK")).get(S("9^ROMR^9\x12+9!"))&&e.add({name:S("\x0fcxhv"),label:this.finder.lang.settings.displaySize,priority:30,sort:S("%UNRL")}),this.getOption(S(")NB_]BNIr]]R\\Q")).get(S(")NB_]BNIuSGQ"))&&e.add({name:S(":_]I["),label:this.finder.lang.settings.displayDate,priority:40,sort:S("\x17|xn~")}),this.finder.fire(S("\v`d}{Fxwd.vy{mtth"),{columns:e}),this.columns.reset(e.toArray()),this.model.set(S("!ALHPKI["),this.columns),this.model.set(S("\v\x7fb|{Rh"),this.getOption(S("'L@Y[@LWl__TZS")).get(S("\x1borlkbX"))),this.model.set(S("\x13gzdcZ`Uixxl"),this.getOption(S("+HD]_\\PKp[[P^_")).get(S("\x1ahsoj]YnPGAW")))},getThumbsInRow:function(){if(!this.collection.length)return 1;var e=this.getChildViewElement(this.collection.first());if(!e.length)return 1;var t,n,i=e.offset().left,r=1;for(t=1;tw~p:kvho")),i=this.getOption(S('8]SHLQ_F\x03.,%-"')).get(S("\x16dwknYe"));if(n===i){var r=this.getOption(S("%BN[YFJUnAAVXU")).get(S("1A\\FAtNwK^^N"));this.finder.request(S("\x1fSDVWMKAT\x12ZO_zLBZU"),{group:S("-HF\\TA"),name:S('"PKWReQfXOI_'),value:S(r===S(".NCR")?"9^^O^":"\x1azo~")})}else this.finder.request(S("7K\\NOUSYLz2'7\x12$*2-"),{group:S("5P^T\\I"),name:S("7KVHO~D"),value:n})},"dragstart .ckf-folder-item":function(e){e.preventDefault()},"dragend .ckf-folder-item":function(e){e.preventDefault()},"ckfdrop .ckf-folder-item":function(e){e.stopPropagation();var n=this.collection.get(e.currentTarget.id);this.trigger(S("\x14v~~t}lryj$yOMFFV\x1fBUGY"),{evt:e,model:n,el:t(e.target).find(S("\x1c3}tF\fDJH@U\nAGDN^"))})}},o.getEvents(S("2_]")));var d=r.extend(u);return d}),CKFinder.define(S("\rMDVx|wqg9Zw}owyn1YIMGP\viG]QeEJHH\\"),[S("']GNN^^M@BT"),S(")@ZYH\\V"),S("-LNSZP\\ZP")],function(e,t,n){"use strict";function i(e){this.finder=e,this.items=new n.Collection}function r(n,i,r,s){var a=s.$el.find(S("\r l{w?\x7fuoo:lqov~"));e.chain(a).filter(function(e){return o(e,i)&&!t(e).data(S("\x0fszt>xtln5msvyrkk"))}).each(function(e,a){var l=t(e),u=setTimeout(function(){if(!o(e,i))return l.data(S("\x1b\x7fvx2L@XZ\tQOJMF__"),!1),void clearTimeout(u);var n=s.getOption(S("4Q_DHU[B\x7fRPY)&")).get(S("\x1ekHTOAwL\\B{]XBBJ")),a=r.request(S("=XV,$x$!1\x12/=$("),{file:s.collection.get(e.id),size:n});l.find(S('"JIB')).after(t(S("\x15*~u~:hhdrz\x1d\x03FJWUJFQ\x13DDBH\x15\r\x0e")).on(S("/\\^SW"),function(){var e=t(this);e.prev(S("(@GL")).attr(S("@20 "),e.attr(S("\x1fSSA"))),e.remove(),l.removeClass(S("4V]Q\x15U[AE\x10JW5, ")),l.data(S("6TS_\x17W]GG\x124(/&+02"),!1)}).attr(S("#WWE"),r.util.jsCssEntities(a)))},a*n);l.data(S(" BIE\tIG]Q\x04^BAHAZD"),u)})}function o(e,t){var n=e.getBoundingClientRect(),i=n.top+n.height-t;return i>=0&&n.top<=(window.innerHeight||document.documentElement.clientHeight)}var s=100;return i.prototype.registerView=function(e){function n(){i&&clearTimeout(i),i=setTimeout(function(){var n=t(S("0\x1fGZ\x19EWP]\x14[XHTHZ`o7*i-#&,,8")).height()||0;r(a.config.thumbnailDelay,n,a,e)},s)}var i,o=this,a=o.finder;e.on(S("7J\\T_YO"),n),e.once(S("7KQUL"),function(){this.finder.util.isWidget()&&/iPad|iPhone|iPod/.test(navigator.platform)&&e.$el.closest(S("C\x1f!'3)d) *`>.74oq\x194?9z\x04")).on(S("D6%5'%&"),n)}),e.on(S("\x14v~~t}lryj$mEOFFV"),n),e.on(S("\x1botdzuQFBP@\x1cFN]OY"),n),t(document).on(S("0BQA[YZ"),n),t(window).on(S("\f\x7fk|ykw"),n),this.throttle=n},i.prototype.disable=function(){t(document).off(S("\f~m}\x7f}~"),this.throttle),t(window).off(S("!PFWL\\B"),this.throttle)},i}),CKFinder.define(S('(jamECJJB\x1e\x7f\\P@ZRK\x16|RPXM\x10\x16(\'47j\x10.->\x07*",)*"'),[S("0D\\WQGETWK_"),S("*A]XK]I"),S("(jamECJJB\x1egG]Y\x19|]@yTXX"),S("\x16TS_suxxl0mNFVH@U\bn@FN_\x02xFUFA\x1c`]CZZW[RPNhV%6"),S(" bieMKBBZ\x06gDHXBJC\x1etZXPE\x18nP_LO\x12rV35\x14*!2"),S("&dcoCEHH\\\0}^VFXPE\x18~PV^O\x12hV%61l\x07*+7)*>\x1d%(9"),S("\x1fcjdJJACU\x07dEOYAK\\\x1fw[_QF\x19{YCCwS\\ZZ2")],function(e,t,n,i,r,o,s){ +"use strict";function a(e){var t;e.data.modeChanged&&(e.data.mode===S("D!#4#=%;")?(this.view.setThumbsMode(),e.finder.request(S(" RGWPLH@[\x13OEMOBJ"),{group:S(" GKOAV"),name:S("\x11f{axtDqc\x7f")}),t=e.finder.request(S(":HYIJV.&1y# 2\x11)%?."),{group:S(" GKOAV"),name:S("\x13`}czzJsay")}),this.view.resizeThumbs(t),this.view.applyBiggerThumbs(t)):(e.finder.request(S("\x1ahyijvNFQ\x19@LUFJEO"),{group:S("%@NDLY"),name:S("3@]CZZjSAY")}),this.view.setListMode()))}function l(e){var t=e.data.value;this.view.resizeThumbs(t),this.view.applyBiggerThumbs(t)}function u(e,n){function i(e){e.preventDefault(),e.stopPropagation()}function r(e){t(document).off(S("\x18tunoxspVD"),o),t(document).off(S("3YZCD]LJ"),r),setTimeout(function(){document.removeEventListener(S(";_QW\\+"),i,!0)},50),u.remove();var n=t(e.target);if(n.data(S("'KBL\x06H_A_")))n.trigger(new t.Event(S("C'. #:&:"),{ckfFilesSelection:!0}));else{var s=n.closest(S("(rNJXL\x03L[W\x1fWFZFj"));s.length&&s.trigger(new t.Event(S("\x12p\x7fsrewi"),{ckfFilesSelection:!0}))}}function o(e){s(u,e)}function s(e,n){var i=t(n.target);i.data(S("1QXR\x18REWI"))&&i.trigger(S("-MDVU@RSZ@RJ")),e.css({top:n.originalEvent.clientY+10,left:n.originalEvent.clientX+10})}var a=n.request(S("&AAEOX\x16JK[cT^VWASS")),l=a.length;e.originalEvent.stopPropagation(),e.originalEvent.preventDefault();var u=t(S("\x18%~rj=}sARQ\x1e\x06FMA\x05MXJK\x0f\x10")),c="#"+t(e.target).attr(S('\nomyo"szt>pgwp5ih~jt{h')),d=S("\x14)\x7fz\x7f9{wh <=\0RP@\x19\x07")+t(c).attr(S("1?u.append(t(d).addClass(S("-MDV\x1cVAUR\x1bQQKIO"))).append(t(d).addClass(S("1QXR\x18REY^\x17HY^QQ$"))).append(t(d).addClass(S("\x1e|KG\x0fGVDA\n\\ACYH"))).append(S("\x0f,u{e4vzvkj'9\x7fvx2DSCD\tLHAG\v\x14")+l+S("@}m'-3x")):u.append(t(d)),u.appendTo(S("2Q[QO")),s(u,e),u.on(S("3YZCD]TUMY"),o),u.on(S("\x13yzcd}lj"),r),t(document).on(S("6ZWLI^QRHZ"),o),t(document).one(S("\x14xybk|ok"),r),document.addEventListener(S("'KECHG"),i,!0)}var c=function(t,i){this.finder=t,this.config=i;var r=this;t.on(S("\x16d}mnrrzm%CICMC@\x1cAAEOX"),function(t){i.set(t.data.settings),e.contains([S("*OE^^CQHvR@P"),S("\x12w}ff{y`Tzqx"),S(":_UNNS!8\x11*> ")],t.data.changed)&&r.view.render()}),t.request(S("#O@_\x1dD@Y_IC"),{key:n.f9}),t.on(S('E-"1-%<"w')+n.f9,function(e){t.util.isShortcut(e.data.evt,S("0P^G"))&&(e.data.evt.preventDefault(),e.data.evt.stopPropagation(),r.view.$el.focus())}),t.on(S('"PLJTSK\\^X\x16AG\\D\vUVZPDVT'),function(e){e.data.shortcuts.add({label:e.finder.lang.shortcuts.general.focusFilesPane,shortcuts:S("'SHF_Q\x06UI\tL")})},null,null,40)};return c.prototype.createView=function(n){function c(e){e.evt.preventDefault(),f.request(S('A$,(!#5r&:."\x1d/;8'),{path:e.model.getPath({full:!0})})}var d,f=this.finder,h={finder:f,collection:n,displayConfig:this.config},g=this.config.get(S("&QAL]\x7fU]K"));if(g===S("@5*6)'(&!%9")){f.request(S("\fxg5wtf^{qs"))===S("\x0fttax`zf")&&f.request(S('7K\\NOUSYLz$,"&)#'),{group:S(")LB@H]"),name:S("\x0fdyg~vF\x7fm}")}),d=new i(e.extend(h,{mode:S(f.request(S("C1,| -=\x07$(("))===S("\x1cy{lKUMS")?"\n\x7fdxcmc":"\x1fLHQW")}));var p=new s(f);p.registerView(d),f.on(S("*^E\x17\\JCXHV"),a,this),f.on(S("#W@RSAGMX\x16NFN^VW\tR\\ZRK\x03NSIP\\l);'"),l,this),d.on(S("\x10uw``gyn"),function(){p.disable()})}else if(g===S("1^ZGA"))f.request(S("\x1fSDVWMKAT\x12MCXMOBJ"),{group:S("\x12u}ysd"),name:S("-ZGE\\P`]OS")}),f.request(S("\x16d}mnrrzm%DHQBFIC"),{group:S("\x10w{\x7fqf"),name:S("\x14q\x7fdhu{bR|sz")}),d=new r(h);else{if(g!==S("\x1c~qrP@AW"))throw S(":lNRPX`7+&3e2>8,");f.request(S("@2'70,( ;s.\"?,,#5"),{group:S("\x12u}ysd"),name:S("*_DXCMcXHV")}),f.request(S("\nxiyzf~va)p|evzu\x7f"),{group:S("D#/+-:"),name:S("\rjfca~rm[wz}")}),f.request(S("A1&01/)/:p/%>/-<4"),{group:S("\x17~pv~o"),name:S("\vhd}\x7f|pkWuas")}),f.request(S(" RGWPLH@[\x13NB_LLCU"),{group:S("*MEAK\\"),name:S("6SQJJW]DmV:$")}),d=new o(h)}return d.on(S("\x14v~~t}lryj$yIMG\x19GJHSMQ^FIC["),function(e){e.evt.preventDefault(),f.request(S('>\\//6&<1\v"&<'),{name:S("\vjdbj"),evt:e.evt,positionToEl:t(e.el),context:{file:e.model}})}),d.on(S('"@LLJC^@O\\\x16KACTT@\tWZXC]ANVYSK'),function(e){e.evt.preventDefault(),f.request(S("\x17{vtoyejREOW"),{name:S("\x16qwu~~n"),evt:e.evt,positionToEl:e.el,context:{folder:e.model}})}),d.on(S("*HDDBKFXWD\x0eS_[]\x03Q^EYQH."),function(e){f.fire(S("A$*( |,-0.$;#"),{evt:e.evt,file:e.model,source:S("\nmeak|`p|v")},f)}),d.on(S("\x16tppv\x7fjt{h\x1aGKOA\x1fBUINY_M_Z"),function(e){var t=f.request(S(";ZTRZ3{%&0\x16#+-*>.("));t.contains(e.model)||(f.request(S(":]UQ[Lz%'0!)#$<\b&'")),f.request(S("\vjdbjc+avxpuc"),{files:[e.model]})),u(e.evt,f)}),d.on(S("&D@@FOZDKX\nW]_PPD\rS\\C_SJP"),function(e){f.fire(S("\x10w}\x7fppd-s|c\x7fsjp"),{evt:e.evt,folder:e.model,source:S("\x1dxvLDQSEKC")},f)}),d.on(S("$FNNDM\\BIZ\x14I_]VVF\x0fU[QZQ"),function(e){e.model.get(S("\x12zgGyxl"))||f.request(S("|\v\x07+- 4h\x1d=#'c\x06+6\x13>66")],function(e,t,n){"use strict";function i(e,n,i){function r(t){o.isInSelectionMode&&(t.data.toolbar.push({name:S("=}S% 0\x10!)#$< %%"),type:S(",O[[D^\\"),priority:105,icon:S("\x0el{w?pu{urt"),iconOnly:!0,title:t.finder.lang.common.choose,action:function(){o.isInSelectionMode=!1,t.finder.request(S("\nmeak|*vwgGpzr{m\x7f\x7f")).length?t.finder.request(S("'N@FN_\x17JJCT^VWAw[T")):t.finder.request(S("7LVUW^\\L\x052$1&0"),{name:S("!oBMK"),event:S("7^VV_YO"),context:{folder:t.finder.request(S(",KACTT@\tSPBv[MSMY"))}})}}),t.data.toolbar.push({name:S("\x1e\\LDCQw@JBK]CDByKWD"),type:S("=JZ85"),priority:100,label:e.lang.formatFilesCount(e.request(S("2U]YSD\x02^_OoXRZ#5''")).length)}))}this.filesModule=n,this.finder=e,this.selectedFiles=new t.Collection,this.displayedFiles=i,this.lastFolderCid=null,this.isInSelectionMode=!1,this.invertKeys=!1,this.focusedFile=null,this.rangeSelectionStart=l;var o=this;e.on(S("A6,+)$&:s8.?(:u\x1d0;=n39;<<("),r,null,null,20),e.on(S("\x19ntsq|~R\x1bPFW@R\x1deHCE\x16KGCU"),r,null,null,20),e.on(S(';HRQS" 0y6 5"Y/-&&6\x7f!"<\b)?%;+')),r=i&&i.cid,o=!n||n===r;o&&e.fire(S("\fkgcub(`qystl|~"),{files:t.getSelectedFiles(),folders:t.getSelectedFolders()},e),t.filesModule.view.shouldFocusFirstChild(),t.lastFolderCid=r}function o(t){var i=t.evt,o=i.keyCode,a=this.finder.lang.dir===S("\x11~gf"),l=a?n.left:n.right,u=a?n.right:n.left,c=n.down,d=n.up;if(this.invertKeys&&(l=n.up,u=n.down,d=a?n.left:n.right,c=a?n.right:n.left),e.contains([n.space,l,u,d,c,n.end,n.home],o)){i.preventDefault(),i.stopPropagation();var f,h=this.displayedFiles.indexOf(this.focusedFile);if(o===n.space&&(f=h,this.selectedFiles.length>1))return s(this),this.resetRangeSelection(),void r(this.finder,this);var g={isAddToRange:!!i.shiftKey};o===n.end&&(f=this.displayedFiles.length-1),o===n.home&&(f=0),o===d&&(f=h-this.filesModule.view.getThumbsInRow()),o===l&&(f=h-1),o===u&&(f=h+1),o===c&&(f=h+this.filesModule.view.getThumbsInRow()),this.selectFiles(f,g)}}function s(e){e.selectedFiles.forEach(function(e){e.trigger(S("\vhh}j|tqgqq"),e)}),e.selectedFiles.reset([],{silent:!0})}function a(e){e.request(S('E-"1s&"?9+!'),{key:n.a}),e.on(S("%MBQME\\B\x17")+n.a,function(e){e.finder.util.isShortcut(e.data.evt,S("\x0fse`\x7f"))&&(e.data.evt.preventDefault(),e.finder.request(S("&AAEOX\x16^KCURFrXY")))}),e.on(S("\x0fcy}a`vcck#vroi$yIMGP"),function(e){e.data.shortcuts.add({label:e.finder.lang.shortcuts.files.selectAll,shortcuts:S("&\\K]XGQ\x06UNM")}),e.data.shortcuts.add({label:e.finder.lang.shortcuts.files.addToSelectionLeft,shortcuts:S('"XWMOA\\T\x01P@HH[qC@\\CH')}),e.data.shortcuts.add({label:e.finder.lang.shortcuts.files.addToSelectionRight,shortcuts:S("7CJRRZIC\x14;3+$,1\x075:&=6")}),e.data.shortcuts.add({label:e.finder.lang.shortcuts.files.addToSelectionAbove,shortcuts:S('"XWMOA\\T\x01PY]o]B^EN')}),e.data.shortcuts.add({label:e.finder.lang.shortcuts.files.addToSelectionBelow,shortcuts:S("\x13of~~~mg0gyqhN`PQKR[")})},null,null,50)}var l=-1;return i.prototype.resetRangeSelection=function(){this.rangeSelectionStart=l},i.prototype.selectFiles=function(t,n){var i=this,r=this.displayedFiles,o=i.displayedFiles.indexOf(i.focusedFile),a=e.extend({},n),u=r.at(t);if(u){if(a.resetSelection&&s(i),a.isAddToRange||this.resetRangeSelection(),o||(o=0),o===t&&!a.forceSelect||a.isToggle)return this.filesSelectToggleHandler({files:[u]}),void this.focusFile(u);var c={files:u};if(a.isAddToRange){this.rangeSelectionStart===l&&(this.rangeSelectionStart=o);var d=t>this.rangeSelectionStart?this.rangeSelectionStart:t,f=t>this.rangeSelectionStart?t:this.rangeSelectionStart;c={files:r.slice(d,f+1)}}s(i),this.filesSelectHandler(c),this.focusFile(u)}},i.prototype.filesSelectHandler=function(t){e.isArray(t.files)||(t.files=[t.files]),this.selectedFiles.add(t.files),1===t.files.length&&(this.focusedFile=t.files[0]),r(this.finder,this)},i.prototype.filesSelectToggleHandler=function(t){e.isArray(t.files)&&(e.forEach(t.files,function(e){this.selectedFiles.indexOf(e)<0?this.selectedFiles.add(e):(e.trigger(S("6S]J_WY^JZ$"),e),this.selectedFiles.remove(e))},this),r(this.finder,this))},i.prototype.getSelectedFiles=function(){return new t.Collection(this.selectedFiles.where({"view:isFolder":!1}))},i.prototype.getSelectedFolders=function(){return new t.Collection(this.selectedFiles.where({"view:isFolder":!0}))},i.prototype.registerHandlers=function(){var e=this,t=e.finder,n=e.filesModule;e.selectedFiles.on(S("\x19h~oxj"),function(){r(t,e)}),n.view.on(S(")IGENE"),function(e){e.evt.stopPropagation(),t.request(S("\x14s\x7f{}j \x7fyn{sEBVbHI"))}),t.setHandlers({"files:select":{callback:this.filesSelectHandler,context:this},"files:select:toggle":{callback:this.filesSelectToggleHandler,context:this},"files:getSelected":{callback:this.getSelectedFiles,context:this},"files:selectAll":function(){e.selectedFiles.reset(n.files.toArray()),e.selectedFiles.forEach(function(e){e.trigger(S("\x1ahyq{|TDF"),e)}),r(t,e)},"files:deselectAll":function(){e.selectedFiles.length&&(e.selectedFiles.forEach(function(e){e.trigger(S("@%'0!)#$<,."),e)}),e.selectedFiles.reset())}}),t.on(S(")LD@IK]\nBW_QVBR\\"),function(){e.isInSelectionMode=!1},null,null,1),t.on(S(">Y/-&&6\x7f!\"<\x0f#')>t.6%7!"),function(){e.isInSelectionMode=!1,e.selectedFiles.reset(),e.resetRangeSelection()}),t.on(S("\x19|rpxm%SDNFGQCC"),function(e){e.data.files.forEach(function(e){e.trigger(S("9I^PX]K%%"),e)})}),a(t),t.on(S("+_EA]DRGGG\x0fZ^KM\0\\YS[M!-"),function(e){e.data.shortcuts.add({label:e.finder.lang.shortcuts.general.nextItem,shortcuts:S("5MEQ^RO}OLP7<>8 *1)\t;8$;0")}),e.data.shortcuts.add({label:e.finder.lang.shortcuts.general.previousItem,shortcuts:S("B8( 3\t;8$;024%!\x13!&:!*")}),e.data.shortcuts.add({label:e.finder.lang.shortcuts.general.firstItem,shortcuts:S("\vweabul")}),e.data.shortcuts.add({label:e.finder.lang.shortcuts.general.lastItem,shortcuts:S(">D%/&>")})},null,null,80)},i.prototype.registerView=function(e){function t(e){e.evt.preventDefault(),e.evt.stopPropagation();var t={isAddToRange:!1,isToggle:!0};i.isInSelectionMode||(e.model.get(S("\x0eyyte)}fPxt}\x7fi"))&&!e.evt.shiftKey?(t.isToggle=!1,t.forceSelection=!0,t.resetSelection=!0):(t.isAddToRange=!!e.evt.shiftKey,t.isToggle=!!e.evt.ctrlKey||!!e.evt.metaKey)),i.selectFiles(i.displayedFiles.indexOf(e.model),t)}this.finder;e.on(S("1Q[]YRAQ\\M\x01ZTRZz\".*'."),t),e.on(S("/SY[_PC_RO\x03\\TPY[Mz\".*'."),t),e.on(S(" BJJHAPNM^\x10MEAK\x15\\^\\T@ZCTP"),function(e){i.isInSelectionMode||(i.isInSelectionMode=!0,i.selectFiles(i.displayedFiles.indexOf(e.model),{isAddToRange:!1,isToggle:!0,resetSelection:!0}))}),e.on(S(">\\((.'2,#0r/%'((/\x1e?<\b\x04'),[S("\x16bv}\x7fio~qmE"),S("6UYZQYSS[")],function(e,t){"use strict";function n(e){this.maxFiles=e&&e.maxFiles||100,this.cache=new i}var i=t.Collection.extend({sort:S("\x0ez`usgqq"),initialize:function(){this.on(S("\x12rpq"),function(){var e=0;this.forEach(function(t){e+=t.get(S("\nmeak|")).length}),this.size=e},this),this.on(S("\x12aqxya}"),function(){var e=0;this.forEach(function(t){e+=t.get(S("\x1a}uq{l")).length}),this.size=e},this)}});return n.prototype.add=function(e,t,n){var i=this.cache.findWhere({cid:e});i&&this.cache.remove(i);var r={cid:e,files:t,response:n,updated:(new Date).getTime()};for(this.cache.add(r);this.cache.size>this.maxFiles&&this.cache.length>1;)this.cache.shift()},n.prototype.get=function(e){var t=this.cache.findWhere({cid:e});return!!t&&t.toJSON()},n}),CKFinder.define(S("\x0eL[W{}ppd8Uv~npxm0fHNFW\npNM^Y\x04zDKXs^\\U]R"),[S("\vycjjbbq|fp"),S("7ZXYP^RPZ")],function(e,t){"use strict";var n=t.Model.extend({defaults:{isInitialized:!1,areThumbnailsResizable:!1,serverThumbs:[],thumbnailConfigs:{},thumbnailMinSize:null,thumbnailMaxSize:null,thumbnailSizeStep:1,listViewIconSize:32,compactViewIconSize:32},updateThumbsConfig:function(t,n){e.forEach(t,function(e){var t=e.split("x"),n=t[0]>t[1]?t[0]:t[1];this.get(S("\r}jbgwa@}czzj")).push(parseInt(n,10)),this.get(S("3@]CZZW[RP~QQ&(%0"))[n]={width:t[0],height:t[1],thumb:e}},this);var i=parseInt(n.thumbnailMaxSize,10),r=parseInt(n.thumbnailMinSize,10);this.get(S("-]JBGWA`]CZZJ")).length&&(r||(r=e.min(this.get(S("3GPDA]KnSIP\\L")))),i||(i=e.max(this.get(S(";OXLI%3\x16+1($4"))))),this.set(S("#EWCs@\\GIBLGCCcW@]OWUT\\"),!(!r||!i));var o=e.max(this.get(S("(ZOYZH\\{XD_QG")));this.set(S("1F[AXTYYPVv]EmV:$"),i>o?o:i),this.set(S("/DYG^V[W^TtSUoTDZ"),r),this.set(S("=JW5, -%,*\x14!3/\x188(>"),n.thumbnailSizeStep),this.set(S("\x1cqwlTwKFSlEHFzCQI"),n.listViewIconSize),this.set(S("C'*+7)*>\x1d%(9\x063><\0=/3"),n.compactViewIconSize)},createSettings:function(e,t,n){var i={list:e.settings.viewTypeList,thumbnails:e.settings.viewTypeThumbnails},r=S('"@KISJFZ')in document.body.style||S(">H%#)*0\x06)+=$$8")in document.body.style||S("E\v(2\n%'9 <")in document.body.style;r&&(i.compact=e.settings.viewTypeCompact);var o={group:S("A$*( 5"),label:e.settings.title,settings:[{name:S('"GMVVKIPdJAH'),label:e.settings.displayName,type:S("!AKAFMEGQ"),defaultValue:t.defaultDisplayFileName},{name:S("\x19~romr~YeCWA"),label:e.settings.displayDate,type:S("\x0elxtqxvzn"),defaultValue:t.defaultDisplayDate},{name:S("\x11vzgezvaJsay"),label:e.settings.displaySize,type:S(";_U[\\+#-;"),defaultValue:t.defaultDisplayFileSize},{name:S("*]EHY{IAW"),label:e.settings.viewType,type:S("K(4/!*$/+\x1b 0.\x1f9+?"))}),o.settings.push(s),o}});return n}),CKFinder.define(S("\x0fSZTzzqse7Tu\x7fiq{l\x0fgKOAV\taAEOX"),[S("\x13a{rrjjytnx"),S("1XBAPDN"),S("\x18{{xw\x7fqqE"),S("\x14V]Qqw~~n2SpDDNP\vcOKM"),S(':xw{WQ$$0l\t*""$:e\r#!**"'),S("\x1e\\kgKM@@T\b}]CG\x03fKVs^VV"),S("%eln@DOI_\x01b_UG_QF\x19qQU_H\x13{WS%2\x04*(1#5"),S("9ypzTP[%3m\x0e+!3+-:e\r%!+<\x7f\x12:<;&3\x1115?("),S("\"`ocOILLX\x04aBJZ\\TA\x1cr\\ZRK\x16lRYJM\x10\x16('4\t$(&/,8"),S("3w~p^V]_I\x13pQ[5-'0k\x03/+-:e\x18)!+,$8==\x1c4834<("),S('2p\x7fs_Y\\\\H\x14qRZJ,$1l\x02,*";f\f" (=\f12:6'),S("6ts\x7fSUXXL\x10\r.&6( 5h\x0e &.?b\x18&5&!|\x02<3 \x1b64=5:")],function(e,t,n,i,r,o,s,a,l,u,c,d){"use strict";function f(i){var r=this;r.finder=i,r.initDfd=new t.Deferred,r.config=new d,r.files=new n.Collection,r.displayedFiles=s.attachTo(r.files),r.displayedFiles.isLoading=!0,r.filesCache=new c({maxFiles:2e3}),r.viewManager=new l(i,r.config),new a(i),i.once(S("\x1d}pMLCM@\x1fIL\x12`DBX"),F,r,null,30),i.setHandlers({"file:getThumb":{callback:m,context:r},"file:getIcon":{callback:C,context:r},"folder:getIcon":{callback:w,context:r},"files:filter":{callback:v,context:r},"file:getActive":function(){return r.selection.focusedFile},"files:getCurrent":function(){return r.files.clone()},"files:getDisplayed":function(){return r.displayedFiles.clone()},"folder:getFiles":{callback:p,context:r},"folder:refreshFiles":{callback:b,context:r},"resources:show":{callback:x,context:r}}),i.on(S("\x1fCNLWA]RjMG_\x11JDBJ"),function(e){e.data.groups.add({name:S(":^XTJ")})},null,null,30),i.on(S("3R\\ZRK\x03^^PXJZ$"),function(t){var n=r.files.length;if(e.forEach(t.data.files,function(e){var t=r.files.indexOf(e);t0&&(n-=1),r.files.remove(t.data.files),r.finder.request(S("'N@FN_\x17JJCT^VWAw[T")),r.files.length){var i=r.files.at(n);r.selection.focusFile(i)}else r.view.focus()}),i.config.displayFoldersPanel||(i.on(S("@'-/ 4},,&.8(*"),function(e){r.files.remove(e.data.folder),r.finder.request(S("\x11tzxpe-||i~px}kaMN"))}),i.on(S("\x18zuvq|p{\x1a@DWAW\x1c`M]lD@IK]C"),function(e){r.doAfterInit(function(){var t=i.request(S("\nmcajjb+uv`Tucqo\x7f"));if(t&&t.isPath(e.data.response.currentFolder.path,e.data.response.resourceType)){r.files.add(t.get(S("&D@@FO^H@")).toArray());var n=r.filesCache.get(t.cid);r.filesCache.add(t.cid,r.files.toArray(),n?n.response:"")}})},null,null,30)),i.on(S("'KFGFMCJ\x15QWFVF\x0fqRL\x7fSWYN"),_,this),i.on(S("A$*( |#*%)'%.%"),g,r),i.on(S("2U]YS\r\\[VO]M"),g,r),i.on(S("\x16qqu\x7f!wxg{OVL"),function(e){i.util.isShortcut(e.data.evt,"")&&e.data.evt.keyCode===o.enter&&(e.stop(),e.data.evt.preventDefault(),g.call(r,e))}),i.on(S("!ALIHGIL\x13OY^B\\\x15bT\\RYPp^T\\"),M,null,null,5),i.on(S('"PLJTSK\\^X\x16AG\\D'),function(e){e.data.groups.add({name:S("\vjdbjc"),priority:20,label:e.finder.lang.files.filesPaneTitle})}),i.on(S("#BJJCM[\x10XIAKLDTV"),function(e){var t=e.data.folder,n=e.data.previousFolder;t!==n?e.finder.request(S("E ($-/9v*+;\x168>6'"),{folder:t}):r.displayedFiles.search("")}),i.on(S("\x16d}mnrrzm%CICMC@\x1cAAEOX\x16[GJGeKCQ"),function(e){r.viewManager.destroy(e.data.previousValue,i),r.view=r.viewManager.createView(r.displayedFiles),r.selection.registerView(r.view)}),i.on(S("9I^HIWQ'2x ,$( -s,\" (=u#> '\x16,"),function(e){r.displayedFiles.sortByField(e.data.value),r.config.set(S("\x19itni\\f"),e.data.value)}),i.on(S("@2'70,( ;s)#-#)*j7;?1&l$7+.\x19%\x12,;\x05\x13"),function(e){r.config.set(S("+_B\\[rH}APPD"),e.data.value),e.data.value===S("\x15wd{")?r.displayedFiles.sortAscending():r.displayedFiles.sortDescending()}),T(i)}function h(e){var t,n,i;for(i="",t=S("\x14$$$,,,,$$_]cegecmllddd{}\x7f}{egekmo"),n=0;n=0)return e.toString();for(var t=o.length,n=t-1;e>parseInt(o[--t])&&t>=0;)n=t;return o[n]}var o=t.config.fileIconsSizes.split(",");n=n.toLocaleLowerCase();var s=t.config.fileIcons[e.has(t.config.fileIcons,n)?n:S("2WQSWBTM")],a=S("'\x17_OY\x11GBVHS\x03");return t.util.url(t.config.fileIconsPath+r(i)+"/"+s+a)}function b(t){var n=this.finder;n.request(S(".C_PVVF\x0fE_WN"),{text:n.lang.files.filesRefresh});var i=n.request(S("\x1eyOMFFV\x1fAB\\hI_E[K")),r=n.request(S("\x12p{x{vv} hysz"),{name:S("\x14Rsc^pv~o"),folder:i,context:e.extend({folder:i},t&&t.context)});return r.then(function(){n.request(S("$IIFLLX\x11DDJJ"))}),r}function x(){var e=this,t=e.finder;e.doAfterInit(function(){t.fire(S("7J\\ITIO]Z3{1++2|%-/%9)"),{resources:e.resources},t),e.files.reset(t.request(S('?2$1,17%";s-.8')).toArray()),t.config.rememberLastFolder&&t.request(S("\x11av`a\x7fy\x7fj hyiH~LTG"),{group:S("\x10w}\x7fppdd"),name:S("4YWDL\x7fUWXXL"),value:"/"}),t.fire(S(",_K\\_D@PQF\fDPVM"),{resources:e.resources},t)})}function F(e){var t=this,n=t.finder;V=V||function(e){return function(t){return e.charCodeAt(t)}}(h(n.config.initConfigInfo.c)),e.data.response.thumbs&&t.config.updateThumbsConfig(e.data.response.thumbs,n.config);var i=n.request(S("#W@RSAGMX\x16IKIY_W"),t.config.createSettings(n.lang,n.config,n.request(S("-[F\nVWGyZRR"))===S("4QSDSMUK")));if(function(){var e=V(4)-V(0);V(4)-V(0),0>e&&(e=V(4)-V(0)+33),D=e<4}(),t.config.set(i),t.config.get(S("\x11f{axtDqc\x7f"))&&t.config.get(S("\f{gjgEkcq"))===S('t.config.get(S("\x18mrnq\x7fp~IMoB\\vO]M"))?o=t.config.get(S("\x15b\x7fmtxu}trRAYqJ^@")):r>>0))*c+u*i%33*d)%l-1>=12*(f[t.s(S(" FFUaTOMvDBS"))]()%2e3)+f[t.s(S(";[YHq+*0,"))]()}var t={s:function(e){for(var t="",n=0;ne&&(e=V(5)-V(1)+33),P=e-1<=0}(),t.selection.registerHandlers(),t.selection.registerView(t.view),function(){function e(e,t){var n=e-t;return 0>n&&(n=e-t+33),n}function t(e,t,n){var i=window.opener?window.opener:window.top,r=0,o=i[S("-B@SPFZ[[")][S(")BD_Y@N]T")].toLocaleLowerCase();if(0===t){var s=S("-pXGFn\x1d");o=o.replace(new RegExp(s),"")}if(1===t&&(o=("."+o.replace(new RegExp(S("E\x180?>\x16e")),"")).search(new RegExp(S("?\x1co")+n+"$"))>=0&&n),2===t)return!0;for(var a=0;a>>0)}R=t(V(7),e(V(4),V(0)),n.config.initConfigInfo.s)}(),t.initDfd.resolve(),function(){function e(e,t){for(var n=0,i=0;i<10;i++)n+=e.charCodeAt(i);for(;n>33;){var r=n.toString().split("");n=0;for(var o=0;o\x84\x05\r\x0f"),S("\x15\x84x}~7")][S("\x14xwg")](t)[S(">U/(,")](" "),e.request(S("\fign|~u)}{px"),n)})},100),K=!0}}(o),!t.data.response.error&&s&&s.isPath(r.currentFolder.path,r.resourceType)){var a=r.files,l=[];o.config.displayFoldersPanel||s.get(S("\x1b\x7fuwsDSGM")).forEach(function(e){l.push(e)});var u=n.filesCache.get(s.cid);if(!u||u.response!==t.data.rawResponse){var c=n.files.filter(function(t){if(t.get(S(';JT[Hz(1\x05+)"":')))return!1;var n=e.findWhere(a,{name:t.get(S("\fcobu"))});return!n||(t.set(n),n.isParsed=!0,!1)});n.displayedFiles.isLoading=!1,c&&n.files.remove(c);var d=n.files.length>0;e.forEach(a,function(e){if(!e.isParsed){var t=new i(e);t.set(S("\x17~vv\x7fyo"),s),t.set(S("3W\\R"),t.cid),d?n.files.add(t):l.push(t)}}),d||n.files.reset(l),n.filesCache.add(s.cid,n.files.toArray(),t.data.rawResponse)}o.fire(S("\vjbbkuc(tqaP~t|i!}{jzR"),{folder:s},o),setTimeout(function(){(window.scrollY||window.pageYOffset)&&window.scrollTo(0,0)},20)}}function E(e){var t=this;e.on(S(';L\\YZz"0&%1#}\x05(#%'),function(e){e.finder.request(S("\x1djpOM@BV\x1fEUMH^N"),{name:S("\x17Uxsu"),page:S(",`OF^")})}),e.on(S("B1!6)2:*/8v>& '"),function(){e.request(S("/D^]_VTD\rJ\\I^H"),{name:S("\x15[vqw"),event:S("\x12aqfybjz\x7fh")})}),e.on(S("$COKMZ\x10XIAKLDTV"),function(e){var t=e.data.files;if(!t.length){var n=e.finder.request(S("'NFFOI_\x14HUEsP@\\@R"));return n?void(!e.finder.config.displayFoldersPanel&&e.data.folders.length||e.finder.request(S("1F\\[YTVJ\x03H^OXJ"),{name:S("(dKBB"),event:S("/V^^WQG"),context:{folder:n}})):void e.finder.request(S("#PJIKJHX\x11^H]JD"),{name:S(".bQX\\"),event:S("\x16e}junn~{l")})}return t.length>1?void e.finder.request(S("\x1fTNMOFDT\x1dZLYNX"),{name:S(",`OF^"),event:S("\x14s\x7f{}j"),context:{files:t}}):void e.finder.request(S("/D^]_VTD\rJ\\I^H"),{name:S("E\v&!'"),event:S("?&(.&"),context:{file:t.at(0)}})},t)}function M(e){117===e.data.response.error.number&&(e.cancel(),e.finder.request(S("\x16sqxvt{'wqFN"),{msg:e.finder.lang.errors.missingFile}),e.finder.request(S("&AGENN^\x17\\JVCW@\\s_[]J")))}function I(e){e.data.evt.preventDefault(),e.data.evt.stopPropagation();var t=e.finder.request(S("\rh`|uwa.rscYznrjx"));e.finder.request(S("\x15pxt}\x7fi&o{yRDQKbLJB[")),e.finder.request(S('=]P-,#- \x7f5"&-'),{name:S(".hUEt\\XQSEK"),folder:t,context:{parent:t}})}function T(e){e.request(S("8R_B\x06QWL4$,"),{key:o.f5}),e.request(S("'CLS\x11@D][U_"),{key:o.r}),e.on(S("1YVMQY@V\x03")+o.f5,function(t){(e.util.isShortcut(t.data.evt,"")||e.util.isShortcut(t.data.evt,S("\x1c~jmL"))||e.util.isShortcut(t.data.evt,S("%UOAO^"))||e.util.isShortcut(t.data.evt,S("\x10rfax>e\x7fq\x7fn")))&&I(t)}),e.on(S("\n`itj`g\x7f(")+o.r,function(t){(e.util.isShortcut(t.data.evt,S("\x1axhor"))||e.util.isShortcut(t.data.evt,S(">\\43.h7-/!<")))&&I(t)}),e.on(S('4F^XJMYNHN\x04S)26y",*";'),function(e){e.data.shortcuts.add({label:e.finder.lang.shortcuts.files.refresh,shortcuts:S("-UI\x05LNHWAD[E\x12AIA")})},null,null,60)}f.prototype.doAfterInit=function(e){this.initDfd.promise().done(e)};var D,P,O,A,R,V,K=!1;return f}),CKFinder.define(S("\x1aoyej>cjdJJACU\x07}OF\\AO[UB\x1du[YRRJJ\x15}SQZZ2\x150&!\v)#-\x1f#.;c* $"),[],function(){return S("*\x17M\r\\@\\T\x0f\x11@GSRQM_V\x1e\x1d]S!21~f&-!e/%'((<<}% 61x:6:<6{'&a\x7fA\b\x16M\f\x04\x15$\0\0\x06\x0f\x1e\b\0O\r\f\x11\x18\x12X\x10\x18\x14\x1d\x1f\t\x0fP\n\red/mk(eoaenyicut/lo14awuqw~~d <2\x11\x03\x02GEQG\nKBL\x06H_A_\r\x13FAAP\x14\t20\x06HL\\P\x01;:cc-1h+)+/'l12o9%|=583w%$ft/-?1^k^L\x05[l[\tI\t\x07\r\x1e\x1dRR\x12\x19\x15Y\x13\x19\x1b\x1c\x1c\b\bQ\t\f\x1ae,g{tdhcm{*pw2..ye<{ufU\x7fqu~iys>b]BIE\tCIKLLXX\x01Y\\JU\x1c\\\\\x19V^^T]H^RFE\0=<`c $2&e )$\"pl,%\"&<9wv39-;v5>11\x10\x0e\x11^F\v\t\x13\r\x11\x1eIRQA\x0eN{N\x17\x1d\x03V\x14\x14\x18\t\bA_\x1d\x14f,dlhacu{$~yih#m\x7fuk1*\x1f\x1f+mu:\x7f}i\x7f2RNNF\x19\x07JN[]\\BIZ\f\x0fCEK_Q\b\x14SQJJW]D\x04Q//'xf{zh=%tApb*&&oX")}),CKFinder.define(S(',neiY_VVF\x1a{X\\LV^O\x12xP,%\'17j\x10.->9d\n""+5#\x06!10\x188<<\f29*'),[S("\vycjjbbq|fp"),S("&dcoCEHH\\\0fXWDG\x1atVK\\\x15xSPNP3(6&\x12,#0"),S("/DTJG\x15v}qQW^^N\x12jZ-1.\"0 5h\x0e&&/)?=`\x16>>71'\x02%=<\x14488\b6\x05\x16L\x07\v\x11"),S("5u|~PT_YO\x11j4(.l\x0f ?\x04'-/"),S('C\'. j"8?.>4c"?3;?1')],function(e,t,n,i){"use strict";var r=t.extend({name:S("(oEGHH\\{BTW}[QS"),tagName:S("#HL"),className:S("E%,.d,$ )+=#|&!10"),childViewContainer:S("\x0ez|+tzffb"),template:n,bubbleEvents:[S("?&..'!7|\"09+%("),S("7^VV_YO\x04\\,(!("),S(">Y/-&&6\x7f%(&=/38 +!%"),S('>Y/-&&6\x7f-"1-%<"'),S("@'-/ 4},;%;"),S("\x1bzrr{ES\x18AACIUM\x13XNABXJ\nRZZXQ"),S("\x18j\x7fwy~jzD\x1b@FBJTB"),S("\x11t|w`e")],modelEvents:{selected:S("=QQ\r.&&(\x16#+-*>.("),deselected:S("'LLYN@HM["),change:S("*DB`AKU]q[U[QR"),"ui:expand":S("\x11wkdtxs")},onBeforeRemoveChild:function(e){this.trigger(S("=XP,%'1~'#!';/q>(# &4h0<<:3"),{origin:this,removedView:e})},collectionEvents:{remove:function(){0===this.collection.length&&this.collapse()},sort:S("9H^SOZZ2")},attributes:{role:S("\x1blo{lEOVBPLII")},ui:{subTree:S("\r{c*w{aga"),expander:S("\x11\x05)2\x11&( %3--"),!0),this.expandParents(),this.focus()},deselect:function(){this.ui.label.removeClass(S("!WJ\tGRI\x05HI_E[K")),this.model.set(this.viewMetadataPrefix+S("/\nXA`QYSTL\\^"),!1),this.children.call(S(")NN_HBJSE"))},onModelChange:function(t){var n=this,i=!1,r=[S('"MEHC'),S("#TDTBF]")];if(e.keys(t.changed).forEach(function(t){e.contains(r,t)&&(i=!0)}),e.isUndefined(t.changed.hasChildren)||t.changed.hasChildren||(i=!0),t.get(S("D-'4\v!#'(?+!"))||t.set(n.viewMetadataPrefix+S("&\x1dAZoS\\L@KUU"),!1,{silent:!0}),i){var o=!!this.$el.find(S(".\x15V^QFG")).length;n.render(),o&&this.ui.label.focus()}else t.changed.hasChildren&&(n.ui.label.removeClass(S("C'. j.&&/)?=b$#76y;9z;1378/;1")),n.ui.expander.removeClass(S("'KBL\x06JBBKUCA\x1e@GSR\x15WU\x16_UWS$3'-"))),n.refreshUI()},onRender:function(){var t=this;t.refreshUI(),t.model.get(t.viewMetadataPrefix+S("3\x0e\\Er@I[UXXZ"))?t.expand():t.collapse(),t.model.get(t.viewMetadataPrefix+S("6\rQJi^PX]K%%"))&&this.ui.label.addClass(S("\x13a|;ulw7z\x7fiwiE")),this.ui.label.attr(S("\x16vjp{6pxhzL"),this.calculateLevel());var n=this.$el.attr(S("(@N"))||e.uniqueId();this.ui.label.attr(S("\x0fqc{r9ywu}uv~x\x7fg"),n),this.ui.label.find(S("=MO!/")).attr(S("(+b5)"2:13%')).removeClass(S("\\+'o76 #j-1:*\")++")),this.model.set(this.viewMetadataPrefix+S("\x1e%IRg[TDHCMM"),!0),this.model.set(this.viewMetadataPrefix+S("7\x02PI~DM_Q$(,$"),!1),this.refreshUI()},requestExpand:function(){this.refreshUI(),this.ui.expander.hasClass(this.options.collapsedIcon)?(this.ui.expander.removeClass(this.options.collapsedIcon).addClass(this.options.workingIcon).addClass(S("\x1e|KG\x0fWV@C\nDFKOECI")),this.model.get(S("\x18q{h_uwsDSGM"))&&this.model.get(S(",NFF\\U@VZ")).length&&this.expand(),this.model.get(S("\nhddbkbt|")).length||this.model.set(this.viewMetadataPrefix+S("'\x12@YnT]OATX\\T"),!0),this.trigger(S("%@HDMOY\x16HV_Q_V"),{view:this})):(this.collapse(),this.trigger(S('\x11t|xqse"zuwp|nlE'),{view:this}))},next:function(){var e=this.parentView.collection,t=e.indexOf(this.model);return t+1===e.length?null:this.parentView.children.findByModel(e.at(t+1))},prev:function(){var e=this.parentView.collection,t=e.indexOf(this.model);return 0===t?null:this.parentView.children.findByModel(e.at(t-1))},focus:function(){this.ui.label.focus(),this.trigger(S("6QWZOH"),{origin:this})},expandParents:function(){for(var e=this;e.parentView&&e.parentView.expand;)e=e.parentView,e.expand()},calculateLevel:function(){for(var e=1,t=this.model,n=this.model.get(S("D5'5-'>"));n;)e+=1,t=n,n=t.get(S("*[M_KAD"));return e},triggerContextMenu:function(e){this.trigger(S("\x15pxt}\x7fi&~qqTDZWI@HR"),{evt:e,view:this,model:this.model})},getLabel:function(){return this.ui.label}});return r}),CKFinder.define(S(")i`jD@KUC\x1d~[QC[]J\x15}SQZZ22m\x15- 14g\x0f%'((<<\x04#76\x02<3 "),[S("\vOFHf~uwa;C\x7froj5Y}n{0cNOSKVOSM\x7fCN["),S(':xw{WQ$$0l\t*"2$,9d\n""+5#!|\x02<3 +v\x1c409;-4\x13\x07\x06*\n\x02\x02>\0\x0f\x1c'),S("*hgkGATT@\x1caA_[\x17r_B\x7fRZZ")],function(e,t,n){"use strict";function i(e,t){function i(){t.evt.preventDefault(),t.evt.stopPropagation()}var l=t.view,u=t.evt.keyCode,c=t.model,d=c.get(l.viewMetadataPrefix+S("6\rQJ\x7fCL\\P[%%")),f=c.get(S(">W!2\x01+-)\"5-'"));u===n.up&&(i(),a(l)),u===(this.finder.lang.dir===S("\rb{b")?n.right:n.left)&&(i(),r(f,d,l)),u===n.down&&(i(),o(f,d,l)),u===(this.finder.lang.dir===S("\x1bpil")?n.left:n.right)&&(i(),s(f,d,l))}function r(e,t,n){if(e){if(e&&!t)return void n.requestExpand();var i=n.children.first();i&&i.focus()}}function o(e,t,n){if(e&&t)return void n.children.findByModel(n.collection.first()).focus();var i=n.next();if(i||!n.model.get(S("\x0efcC}|`"))){var r;if(!i){for(r=n.parentView,i=r.next();!i&&!r.model.get(S("\x0fyb@|{a"));)i=r.next(),r=r.parentView;!i&&r.model.get(S("\fd}]\x7f~f"))&&(i=r.next())}i&&i.focus()}}function s(e,t,n){e&&t?n.collapse():n.model.get(S("B*7\x17)(<"))||n.parentView.focus()}function a(e){var t=e.prev();if(t)for(;t.model.get(e.viewMetadataPrefix+S("$\x1fOTmQZJBIKK"))&&t.model.get(S("6TPPV_NXP")).length>0;)t=t.children.findByModel(t.collection.last());else e.model.get(S("9SHnRQK"))||(t=e.parentView);t&&t.focus()}function l(e,t){var n=e.model;if(!n.get(S("'KACGH_KA")).length)return e;var i=n.get(S("\x1axttr{RDL")).findWhere({name:t.shift()});return i?l(e.children.findByModel(i),t):e}var u=e.extend({name:S(";zRR[%31\x176 #"),childView:t,tagName:S("-[C"),className:S("3W^P\x1aLK_^"),attributes:{role:S("B76 #"),"data-role":S("9VROIHV%6"),tabindex:20},template:"",events:{keydown:function(e){if(e.keyCode===n.tab&&(this.finder.util.isShortcut(e,"")||this.finder.util.isShortcut(e,S("\x0fcy{u`"))))return void this.trigger(S("C/ ?#'>$q8,,"),e);var t;if(e.keyCode===n.up||e.keyCode===n.end)for(t=this.children.last();t.model.get(t.viewMetadataPrefix+S("By-6\x03?8($/))"))&&t.model.get(S("+OEGCTCW]")).length>0;)t=t.children.findByModel(t.collection.last());e.keyCode!==n.down&&e.keyCode!==n.home||(t=this.children.first()),t&&(e.stopPropagation(),e.preventDefault(),t.focus())},focus:function(e){e.target===e.currentTarget&&(e.preventDefault(),e.stopPropagation(),this.findFolderToFocus().focus())}},childEvents:{"folder:keydown":i,"selected:before":function(){this.children.call(S("\x11vvgpzr{m"))},focus:function(e,t){this.lastFocusedPath=t.origin.model.getPath({full:!0})},"folder:before:remove:child":function(e,t){var n=t.origin.model.getPath({full:!0})+t.removedView.model.get(S("$KGJM"))+"/";n===this.lastFocusedPath&&t.origin.focus()}},initialize:function(e){this.viewMetadataPrefix=e.viewMetadataPrefix||S("\x12e}pa")},onRender:function(){this.$el.attr(S("!CQMD\vKIKOG"),this.finder.lang.folders.treeTitle)},childViewOptions:function(){return{viewMetadataPrefix:this.viewMetadataPrefix}},onAddChild:function(e){e.parentView=this,this.refreshUI()},refreshUI:function(){this.$el.listview().listview(S("0CWUFPE_"))},findFolderToFocus:function(){var e=this.children.first();if(this.lastFocusedPath){var t=this.lastFocusedPath.split(":"),n=t[0],i=t[1],r=this.children.findByModel(this.collection.findWhere({name:n}));if(e=r,"/"!==i){var o=i.replace(/^\//,"").split("/").filter(function(e){return!!e.length});e=l(r,o)}}return e}});return u}),CKFinder.define(S("\x12P_S\x7fy||h4QrzjLDQ\fbLJB[dE]InA_I\x1e\x7f\\PPZD\x17tUMY~QO9\x05#7%"),[S("\n~bik}cr}aq"),S('E$&+"($"(')],function(e,t){"use strict";return t.Model.extend({defaults:{done:0,lastCommandResponse:!1},initialize:function(){this.set({fileExistsErrors:new t.Collection,otherErrors:[]})},processResponse:function(t){this.set(S("\x12\x7fufbE}jjtrn{"),{done:this.get(S("4AOG]"))===S("\vOb~v")?t.copied:t.moved,response:t});var n=this.get(S("\x16sww\x7f")),i=parseInt(this.get(S("\x1ekYQG"))===S("\x0fS~bj")?t.copied:t.moved);if(this.set(S("\x18}uuy"),n+i),t.error&&(300===t.error.number||301===t.error.number)){var r=this.get(S("\rhf|tWk}fbd]khtnn")),o=this.get(S("\x17wmr~nXlmOSQ"));e.forEach(t.error.errors,function(t){if(115===t.number)r.push(t);else{var n=e.findWhere(o,{number:t.number});n||(n={number:t.number,files:[]},o.push(n)),n.files.push(t.name)}})}},hasFileExistErrors:function(){return!!this.get(S("%@NDLoSE^Z\\uC@\\FF")).length},hasOtherErrors:function(){return!!this.get(S("$JROM[oY^B\\\\")).length},nextError:function(){var e=this.get(S("0W[_QpN^KMI~NOQM3")).shift();return this.set(S("E%2:;/%8"),e),e},getFilesForPost:function(e){var t=[];if(t.push(this.get(S("\x1c~kmRDLW")).toJSON()),e)for(;this.hasFileExistErrors();)t.push(this.nextError().toJSON());return t},addErrorMessages:function(t){e.forEach(this.get(S("+CYFJBt@A[GE")),function(e){e.msg=t[e.number]})}})}),CKFinder.define(S("3@PNC\x19zq}USZZ2n\x16&)5*&<,9d\n$\"*#\x1c=%1\x169'!v\x19332-:&\x0e\x0e\x07\x01\x17H\x03\x07\x1d"),[],function(){return S('A~\'-3f#)=+f>""*ms:6513%zgPR`5la\x1b\x1a_C\r\x11H\v\t\x07\rE\n\x02\x02\v\x15\x03\x01]\x10\x10\x05\x03\x11\x17\x1b\x0f\x15\x12\x109omffv%{z4&b92\x07\x073q1q\x7fufe*:ls6~ip?UH\x0f@KWHBZ\x04KG@\r[F\x1dSF]\x19\\UXV\x14TTHXFK`4+n-&))e*!-a//,;sr:0ht43?w63+;r\x03\x0e\x12\x1aI\x06\n\b\x1b\fHK\x18\x04\x1a\x03\x15LP\b\x0fHV\x1e\fW\x16\x1a\x12\x1aP\x1cololj+ekgzo+qp,/dppzzqso%;++>#"0A\x1f(\x1f\vAOQ\x16#\x16OE[\x0eFT\f\x10P_S\x1bZWO_\x16_RNFm"--0 (3jwvd($8qZ')}),CKFinder.define(S('\x18ZQ]uszzR\x0eoL@PJB[\x06lB@H]b_GWp[EO\x18nP_LO\x12}W/.1&\x02**#-;\x06*5";;'),[S("\vOFHf~uwa;C\x7froj5Y}n{0l@[LQQpNM^"),S('.[UIF\x12w~p^V]_I\x13i[R0-#7!6i\x01!%/8\x01"8*\x13>"*{\x16>87*?\x1d31::\x12O\x06\f\x10')],function(e,t){"use strict";return e.extend({name:S("*hDBA\\Uw]_PPDsQXVT[q_F/46\x15- 1"),template:t,regions:{content:S("(\nI@J\0C@FT\x1fP[EO\x1a[VTOYSJ")},ui:{close:S("#\x07FMA\x05DE]I\0M@@H\x1fPXZER")}})}),CKFinder.define(S('&dcoCEHH\\\0}^VFXPE\x18~PV^OpQI%\x02-3=j\x10.->9d\x01"8*\x13>"*\x10<7;7>\x16:%2++'),[S("\x11QXR|xs}k5Muxil\x0fcCPA\njFQF__zDKX")],function(e){"use strict";return e.extend({name:S("9wTJX}P08\x06*%)) \x04(3$99\x18&5&"),template:S("2\x0fP\\@\t\x04\x16^RJ\x03"),regions:{content:S("\x1a\x7fuk")}})}),CKFinder.define(S("3@PNC\x19zq}USZZ2n\x16&)5*&<,9d\n$\"*#\x1c=%1\x169'!v\x174*8\x1d0\x10\x18$\n\b\0'\x04\x1c\0\x05\x05\x1f9\v\x02\0\x1d\x13\x07\x11[\x12\x18\f"),[],function(){return S("\x1f\x1cI\x11\x03GIGT[\x14\bHGK\x03B_GW\x1eWZFN\x15_SWYS_R%c|8?xf.>?+!$\x7f56 }vp687>{}w\x7f\x1d\x1c^L\fVXmT\x19J\b\0\f\x1d\x1cMS\x11\x18\x12X\x1b\x18\x0e\x1cW\x18\x13\r\x07Resplv'8|s4*bx#bn~vv`bcww8;uy#=CJD\x0eIJPB\x05ZAB\\\x0f\x10TK\f\x12Z@\x1bZVV^\x14XSPSP.o1(-5f:5ue)99: >oXYh1?!x:6:/.c}\x03\n\x04N\t\n\x10\x02E\n\x05\x1b\x15@\r\x07\x15\x12\x19\x11\x1b\rTIrpF\x17\x1d\x1f\x1b\x13>\v\v\n8lhw}}*em`k22a`|wpedYuv982aj]M\x07\r\x13Xmb\x12\x11TL\x04\x1aA\x03\x19\x1d\x047\x14\x18\x14\x1d\x15Z\x06\x01wB\x1biw\"`hdut5+\x7fb!j|ft|L@QP\x19\x07SN\x05KFDOF\x03N\x12\x0f\x0eW]C\b\vZLNOSS\x1eV$|` /#k*'?/f/, ,5=pm/.kw1-t7=39q\x03\x0e\x0f\x0e\v\vH\x04\t\x07\t\x0e\0M\x13\x12L^\x10\x06\0\x01\x19\x19FEU\x1f\x15\v@C/eku:\x0f:(l`|5\x06vu0ml\x18")}),CKFinder.define(S(")i`jD@KUC\x1d~[QC[]J\x15}UQ[L\r.4&\x07*6>g\x1f#.;>a\x02?'7\x10;%/\x1115?\x1a?)70\x0e\x124\n\x01\x12"),[S("\x0eL[W{}ppd8Np\x7flo2\\~SD\rjP@KqAL]"),S('+XHV[\x11ryu][RRJ\x16n^QMR^4$1l\x02,*";\x04%=)\x0e!?)~\x1f<"0\x158( \x1c208\x1f<\x14\b\r\r\x171\x03\n\x18\x05\v\x1f\tC\n\0\x04')],function(e,t){"use strict";return e.extend({name:S(".b_GWp[EOrJKUIOkWZ7"),template:t,ui:{processAll:S("8bTZQX\x03\x1d03- !65\x06$%h\x16"),overwrite:S("$\x06ELN\x04GDZH\x03@FT@DF\\BR"),skip:S("\f.mdv<\x7f|bp;dspj"),rename:S("\x111p\x7fs;zwo\x7f6nxp~MD"),cancel:S("Df%,.d'$:(c,1?168")},onRender:function(){this.$el.enhanceWithin()}})}),CKFinder.define(S("=JZ85c\0\x0f\x03/),,8d\x18(#?<0&6'z\x10>4<)\x163+;\x1c\x0f\x11\x1bL)\n\x10\x02+\x06\x1a\x12>\b\x1d\x1a\x1c\x05&\x16\x19\x05\x1a\x16\f\x1cT\x1f\x13\t"),[],function(){return S("Ez7v21vl$:a=\"5s)(jx(gPg4/`U\\\x11B\0\b\x04\x15\x14UK\t\0\n@\x03\0\x06\x14_\x10\x1b\x05\x0fZ\x1e\x18\x13\x17\t\x0f\x1b\f-ukwh`&ra$hdht#f~ywa}a4)cb';ui0zRSMQWqOSDL\nVQ\x11\x01_\x0e;\x0eW]C\x16TTXIH\x01\x1f]T&l/,2 k$'93f*,'#%#7 vk\\^#\"${5)p0\x14\t\x07\x11!\x17\x14\b\x1a\x1aPK\t\x1f\x1c\0\x026\0\x1c\x01\x05V\n\x05ssr@\r@\x04{<\"fvwiuO{e~|#c|w1on(:f)\x12\x10\x13'iq \x15)(YXZ\x05CUZFXl^B[_\x1eW[_QF\f\x17]KHTN\x1dCBJHKJx)/y32wk)?< \"q/.hz:>fSSR'& \"\x1dkkjXJ\x13\vVcc\x10\x17\x13\x13\x12zM]\x17\x1d\x03H}\x03\x02E[\x15\tP\fhnu@ekebd)wv\x061jff1q\x7fufe*:ls6{ow{\rRMOK\x07\x18-!\x15NBZ\rMCQBA\x0e\x16@_\x1aZUUXW\x10_\x1d~}&*2{z%==>$\"m'+ms182x;8.\x1f2.&O7\v\x06\x13\x16I*\x07\x1f\x0f(\x03\x1d\x17=\x15\x02\x07\x1f\0#\x1f\x12\x0f'),[S("\x18ZQ]uszzR\x0etJARU\bjHYN\x03dZJ]g[VC"),S("\x1ekEYV\x02gn`NFMOY\x03yKB@]SGQF\x19qQU_HqRHZ\x03.2:k\b)1-\n%;5\x1f+<%=&\x0718&;9-?u82*")],function(e,t){"use strict";return e.extend({name:S("D\b)1-\n%;5\x1f+<%=&\x05=0!"),template:t,className:S(" BIE\tHIQM\x04ID\\T\x03]UBG_@"),ui:{ok:S("\x18:ypz0spVD\x0f@KU_\nGB")},onRender:function(){this.$el.enhanceWithin()}})}),CKFinder.define(S("!ahbLHCM[\x05fCI[CUB\x1du]YSDuVL^\x7fRNFo\x07+/!6\v(>,\t$<4"),[S("\x1dkqDDPPGJTB"),S("\x19pjixlf"),S("%DFKBHDBH"),S(",neiY_VVF\x1a`^]NI\x14qXML!&'\x15- 1"),S('1qxr\\XS]K\x15vSYKS%2m\x05+)""::e\x1d%(9<\x7f\x17=?00$$\f+?>\n4;('),S('-mdvX\\WQG\x19zW]OWYN\x11y)-\'0\t*0"\v&:2c\0!+5=!|\x19: 2\x1b6*"\x18<*>'),S('1qxr\\XS]K\x15vSYKS%2m\x05-)#4\x05&<.\x0f">6\x7f\x07;6#&y\x14065(9\x1b13\x04\x04\x10/\x05\x1c\t\x12\x1c'),S('\x1d]TfHLGAW\tjGM_GI^\x01iY]W@yZ@R{VJB\x13kWZ72m\x0e+3#\x04\'93\x0f%," 7\x1d3*; "'),S('2p\x7fs_Y\\\\H\x14qRZJ,$1l\x02,*";\x04%=)\x0e!?)~\x04:1"%x\x156,>\x1f2.&&\b\x0e\x06%\x06\x12\x0e\x07\x07\x19=\x05\b\x19'),S('.l{w[]PPD\x18uV^NPXM\x10\x06(.&7\b)1-\n%;5b\x18&5&!|\x19: 2\x1b6*"\x0e8-*\f\x154\n\x01\x12'),S("9ypzTP[%3m\x160,*h\x03,3\b#)+")],function(e,t,n,i,r,o,s,a,l,u,c){"use strict";function d(e){function t(t){e.setHandler(S("1TZXPE\r")+t.toLowerCase(),function(n){f(n,t,e)}),e.on(S("\x11q|yxwy|#{}hxl%")+t+S("\x13R|zrk"),function(e){g(e,t,n,t===S("4xYA]"))}),e.on(S("6TWTWZRY\x04Z23-1~")+t+S("\x1dXvLDQ"),p),e.on(S('0E]\\XWWE\x02K_HYI\x04r!(,y",*";'),function(e){m(e,t,n)}),e.on(S("4AYXT[[I\x06O[L%5x\x0e%,(}. &."),function(e){m(e,t,n)})}var n=this;n.finder=e,e.on(S("\x13rzzs}k \x7fnrn"),w,n),e.on(S("\vob`{uif^q{c-~vv\x7fyoZmOQ"),function(e){e.data.groups.add({name:S("D()1-\n%;5")})}),e.on(S("\x0el\x7f\x7ffvla[rvl }sqzzRePLT\x1fKH^LiD\\T"),C),t(S("5uXH@")),t(S("'eF\\N"))}function f(e,t,i){var r=[],s=e.files instanceof n.Collection?e.files:new n.Collection(e.files);s.forEach(function(t){var n=t.get(S("9\\TPY[M"));r.push({options:e.options?e.options:"",name:t.get(S("1\\RYP")),type:n.get(S("=LZ3.71' \x12>8,")),folder:n.getPath()})});var a=new o({type:t,currentFolder:e.toFolder,lastIndex:i.request(S('=XV,$1y# 2\x04=;8."9')).indexOf(e.files.last()),postFiles:r});h(i,r,a)}function h(t,n,i,r){r&&e.forEach(n,function(e,t){n[t].options=r});var o=i.get(S("\x11fjdp")),s=n.length,a=t.lang[o.toLowerCase()][S(1===s?"\x0e`~tTzxpAvqm":"0\\S]Ms_[]JmZUI")].replace(S("5MTWLTOA"),s)+" "+t.lang.common.pleaseWait;t.request(S("&KGHNN^\x17]G_F"),{text:a}),t.request(S(")IDA@OAT\vAVZQ"),{name:o+S(" gKOAV"),type:S("6GWJN"),post:{files:n},sendPostAsJson:!0,folder:i.get(S("\x1b\x7fhlmEOVeKIBBZ")),context:{moveCopyData:i}})}function g(t,n,i,r){function s(){i.finder.request(S("\x0e\x7fqvw)ppecjvc"),{name:x}),i.finder.request(S("8]SZPRY\x05$$176*?"))}var a=[103,116],c=t.data.response;if(!c.error||!e.contains(a,c.error.number)){var d=i.finder,f=t.data.context,g=f&&f.moveCopyData?f.moveCopyData:new o;g.get(S("\x10ekcq"))||g.set(S("9NBLX"),n),g.processResponse(t.data.response),d.request(S("C(*'#-;p#%)+"));var p,m=d.lang[g.get(S("%R^XL")).toLowerCase()].operationSummary;if(g.set(S("\x15{d\x7f"),m.replace(S("\x17czunric"),g.get(S("@%--!")))),g.set(S("\x11wafzddLpnwy"),d.lang[g.get(S("\x0fdhbv")).toLowerCase()].errorDialogTitle),g.set(S(".\\X^EpU[URT"),y(d)),!g.hasFileExistErrors()){d.request(S("5FV_\\\0_YNJM/8"),{name:_}),d.request(S("?0 %&~!#4<;%2"),{name:x});var w=g.hasFileExistErrors()?d.lang.errors.operationCompleted:d.lang[g.get(S(";HDNZ")).toLowerCase()].operation;return g.hasOtherErrors()&&(g.set(S(" LQD"),d.lang.errors.operationCompleted+" "+g.get(S("'EZM"))),p=new u({finder:d,model:g,events:{"click @ui.ok":function(){i.finder.request(S("E6&/,p/)>:=?("),{name:F}),i.finder.request(S("\vhdoc\x7fv(wqfbew`"))}},className:function(){return this.finder.request(S("7MP\0\\YIsP$$"))==S("6ZW[SWY")?S("2F]\x18UXVM_UH"):""}}),g.addErrorMessages(d.lang.errors.codes)),p?y(d)?(d.request(S("E6&/,p(>(/;5"),{view:p,title:w,name:F,uiOptions:{dialog:d.request(S("\vyd4hue_|pp"))!==S("\x18tuyuq{"),theme:d.config.swatch,overlayTheme:d.config.swatch}}),d.request(S(";L\\YZz2*,3"),{name:F}),d.request(S("0ASTQ\x0fRRKMHTE"),{name:x})):d.request(S("'L@KGCJ"),{name:g.get(S("\n\x7fu}k"))+S("\x12@avurkj"),title:w,buttons:[S(".@[r^\\GP")],minWidth:S("Dqvw81"),view:p}):d.request(S("9^R]QQXz(,%+"),{title:w,msg:g.get(S("\rc|w")),name:S("%kH^LiD\\T}Z]\\SAM|XQW")}),void(r&&(n===S(";qRHZ")&&b(d),d.request(S(",KACTT@\tFPPE]JR}UQ[L"))))}g.nextError(),g.addErrorMessages(d.lang.errors.codes);var C=v(g,d,n);C.content.show(new l({finder:d,model:g,events:{"click @ui.skip":function(){this.model.hasFileExistErrors()&&!this.ui.processAll.is(S("9\0XTX]T%%"))?(this.model.nextError(),this.render()):s()},"click @ui.overwrite":function(){h(i.finder,this.model.getFilesForPost(this.ui.processAll.is(S("\x16-{q\x7fxwxz"))),this.model,S("-AYUCEA]AS"))},"click @ui.rename":function(){h(i.finder,this.model.getFilesForPost(this.ui.processAll.is(S('C~&."+"//'))),this.model,S('=_J4.0&*$+"'))},"click @ui.cancel":s},className:function(){return this.finder.request(S("?5(x$!1\v(,,"))==S('=SP"(.&')?S("\x1ejI\fALJQCI\\"):""}}))}}function p(e){var t=e.data.response;switch(t.error.number){case 300:case 301:e.cancel();break;case 116:e.cancel(),e.finder.request(S("/\\^SWQG\f_Q]_")),e.finder.request(S("D!/&$&-q%#( "),{msg:e.finder.lang.errors.missingFolder});var n=e.data.context.moveCopyData.get(S(" BWQV@HSnFFOI_")),i=n.get(S("\v|l|j~e"));i.get(S("\x1b\x7fuwsDSGM")).remove(n);var r=e.finder.request(S("&AGENN^\x17IJDpQG]CS"));r===n&&e.finder.request(S("/V^^WQG\fXH\\Tk]IV"),{path:i.getPath({full:!0}),expand:!0});break;case 103:e.cancel(),e.finder.request(S("\x1bpr\x7f{ES\x18KMAC")),e.finder.request(S("C ,'+'.p\"\"+!"),{msg:e.finder.lang.errors.codes[103]})}}function v(e,t,n){var i=e.get(S("\x1dhvEV"));if(!i){i=new a({finder:t});var r=t.lang[n.toLowerCase()+S('>p0$0"0,))')];y(t)?(t.request(S('m\x7fxE\x03\x7f")).find(S("B`'. j%&<.a.!?)|1?;&3")).focus():i.$el.closest(S('?n")%i!/&$&-')).find(S('Eh$#/g/%," 7|0& !99+')).find(S("8\x17OR\x11_JQ")).focus()});var o=e.data.file?e.finder.lang[t.toLowerCase()].oneFileDialogTitle:e.finder.lang[t.toLowerCase()].manyFilesDialogTitle.replace(S("\x1f[BMVJQ["),e.data.files.length);if(y(n.finder)){n.finder.on(S("/@PUV\x0eF^XO\x03")+_,function(){i.refreshUI()});var a=new s({finder:n.finder,events:{"click @ui.close":function(){n.finder.request(S('@1#$!\x7f"";=8$5'),{name:_})}}});a.on(S("\x10bz|c"),function(){this.content.show(i)}),n.finder.request(S("$UG@M\x13IYILZJ"),{view:a,title:o,name:_,className:S('A!("h+(>,g(#=7b483?;2'),uiOptions:{theme:n.finder.config.swatch,overlayTheme:n.finder.config.swatch}}),n.finder.request(S("\v|lij*bz|c"),{name:_})}else n.finder.request(S("-1&&o-1&&o>=0;)o--;var s=n.at(o);e.once(S("!FJEII@\x12JFD_H\x14b_GWp[EOdMTWZNDwQ&."),function(){var n=e.request(S("8_SWYN\x04X%5\x01667#)<"));s&&n.indexOf(s)>-1?(s.trigger(S("\x13rzubk"),s),e.request(S("+JDBJC\vAVXPUC"),{files:[s]})):t(S("Al /#k!!%/8a;'*'")).focus()})}var x=S("+aBXJs^BJp\\W[W^jZ[X"),F=S("\x0eB\x7fgwP{eoDmzy~onZvAMMDtDAB"),_=S("@\x02*,+6#\x01'%..>");return d}),CKFinder.define(S("5u|~PT_YO\x11r/%7/!6i\x01'*?8\x01, .74 |\x12:5\"+\x14;5=:;-"),[S("\vf|{jbh"),S("\x12fzqsekzuiy"),S("\x11QXR|xs}k5Nhtr0kD[`KAC")],function(e,t,n){"use strict";function i(i){var o=[];i.setHandlers({"focus:remember":function(){o.push(document.activeElement)},"focus:restore":function(){e(o.pop()).focus()},"focus:next":function(e){r(e,1)},"focus:prev":function(e){r(e,-1)},"focus:trap":function(i){i.node&&i.node.on(S("#O@_CG^D"),function(i){var r=i.keyCode;if(r===n.tab){i.preventDefault(),i.stopPropagation();var o=e(this).find(S('+wYOMY_VVLh\x1a^VIOO\x10\\\x12]556,*i5"$,)?')).not(S("=o.length?a=0:a<0&&(a=o.length-1),o.eq(a).focus()}})}})}function r(n,i){var r=0,o=t.chain(e(S("%}SIKCEHHVr"))).filter(function(t){var n=e(t);if(parseInt(n.attr(S("-ZNRX\\WQM")))<0)return!1;if(n.closest(S(";\x12^UYm1#$!")).length)return n.closest(S(" \x0fAHB\bVFOL")).hasClass(S("E3.e9+,)`/,$8$6"));var i=n.closest(S("Bm1,k7)'/'"));if(i.length){var r=!i.hasClass(S("\x17mp7k}s{s\rBNLW@B")),o=n.hasClass(S("\x16ts\x7f7onx{"));return o&&e(S("%DHLP")).hasClass(S('<^UYm4+n)*""e-/8\'9!?'))?e(S("\x0eTtpfr9v}q5i{|y =o.length||s<0))return n.event.preventDefault(),n.event.stopPropagation(),e(o[s]).focus()}return i}),CKFinder.define(S("\x18ZQ]uszzR\x0eoL@@JT\x07{OXCX\\LUeKCQ"),[S("A7- 44+&8."),S("0SSP_WYY]"),S('@\x02\t\x05-+"":f\x07$(("<\x7f\x17=?00$')],function(e,t,n){"use strict";var i;return i=n.extend({initialize:function(){n.prototype.initialize.call(this);var e=this.get(S(".N\\]]DQQsOL\\THURPL"));e&&"string"==typeof e&&this.set(S("\x1d\x7fsLNUF@`^SMGYBCC]"),e.split(","),{silent:!0});var t=this.get(S('?!-.,3 "\x020=/%?$!!#'));t&&"string"==typeof t&&this.set(S('A#/(*1",\f2?)#=&??!'),e.split(","),{silent:!0})},isAllowedExtension:function(t){t=t.toLocaleLowerCase();var n=this.get(S("+MAB@GTVvLASYKPUUO")),i=this.get(S("\fikaytvVlasykpuuo")),r=n&&!e.contains(n,t),o=i&&e.contains(i,t);return!(r||o)},isOperationTracked:function(t){var n=this.get(S("\x15beyzq~xRnzR@VJKKU"));return!!n&&e.contains(n,t)}})}),CKFinder.define(S("4ASOL\x18ypzTP[%3m\x17!(6+)=/8c\x0f<*151!!84$w\x1b(>=9=-\x15\f\0\x10J\x01\t\x13"),[],function(){return S("*\x17M\rMCQBA\x0e\x16@_\x1aZMT@G\x02\x1eV4o!667#).%76sym{6\x7fvx2DSMS\x19\x07RU]L\b\x15WV\x0f\x0fYE\x1c_UWS[\x18EF\x1bUI\x10Q!,'c98zh)w@")}),CKFinder.define(S('\x17[R\\rry{m\x0flMGQICT\x07oEGHH\\\\\x1fg[VCF\x19uJ\\[__OKR"\x17+&3'),[S("*A]XK]I"),S(">|\v\x07+- 4h\x1e /#"0UM\x1c'),childViewContainer:S("&RD"),attributes:{role:S("!LBRLAF\\@EE")},childView:n,ui:{container:S("C1)|!!;9?")},events:{touchstart:function(e){e.stopPropagation()},keydown:function(t){if(t.keyCode===r.tab&&(this.finder.util.isShortcut(t,"")||this.finder.util.isShortcut(t,S(":HTTXK"))))return void this.finder.request(S(this.finder.util.isShortcut(t,"")?"D#)$=:p%)5:":"8_UXIN\x04O2$4"),{node:this.ui.container,event:t});var n;return e.contains([r.left,r.end,r.right,r.home],t.keyCode)?(t.stopPropagation(),t.preventDefault(),n=t.keyCode===r.left||t.keyCode===r.end?this.children.last():this.children.first(),void n.focus()):void(t.keyCode!==r.up&&t.keyCode!==r.down||t.preventDefault())},"focus @ui.container":function(e){e.target===this.ui.container.get(0)&&(e.stopPropagation(),this.children.first().focus())}},initialize:function(){function e(e,t,n,i){e.preventDefault(),e.stopPropagation(),i.collection.last().cid!==n.cid&&t.request(S("9\\TPY[Mz.2&*\x15'3 "),{path:n.get(S("\x0e\x7fqez")) +})}this.listenTo(this.collection,S("!PFW@R"),function(){this.$el[S(this.collection.length?"\nxdby":"9RRXX")]()}),this.on(S("&D@@FOZDKX\nZWJPZAY"),function(t,n){var i=n.evt;if(i.keyCode===r.left||i.keyCode===r.right){i.stopPropagation(),i.preventDefault();var o=this.collection.indexOf(n.model);o=i.keyCode===(this.finder.lang.dir===S("\x14ybe")?r.left:r.right)?o<=0?0:o-1:o>=this.collection.length-1?o:o+1,this.children.findByModel(this.collection.at(o)).focus()}i.keyCode!==r.space&&i.keyCode!==r.enter||e(i,this.finder,n.model,this)},this),this.on(S("2P\\\\ZSNP_L\x06^RV#*"),function(t,n){e(n.evt,this.finder,n.model,this)},this)},onRenderCollection:function(){this.$childViewContainer.attr(S("\x1d}sARQ"),S("9YPZ\x10XP,%'17h$5-(.(>8#-#|5!=1v43?w=31::\x12\x12O\x01\x16\0\x07\x03\v\x1b\x1f\x06\x0e\x1eC\b\x02\x18\x16^")+this.collection.length);var e=this.$childViewContainer.prop(S("3GVDXTUmRXIV"))-this.$childViewContainer.width();e&&this.$childViewContainer.scrollLeft(e)},focus:function(){this.ui.container.focus(),setTimeout(function(){window.scrollTo(0,0)},0)}});return o}),CKFinder.define(S("D\x06\r\x01!'..>b\x03 4$>6'z\x1084=?)/r\x1c-\x05\0\x06\0\x16\x10\v\x05\x1b"),[S("!HRQ@T^"),S("\x0emqryq{{s"),S("\x1fcjdJJACU\x07dEOYAK\\\x1fw]_PPDD\x17oS^KN\x11}2$#''73**:\x1c\"):")],function(e,t,n){"use strict";function i(e,t){var i=new n({finder:e,collection:t});return e.on(S("(YKLI\x17]G_F\b~U\\X"),function(){e.request(S("9JZ[X\x04^$%\x10&#,))"),{page:S("\vAlga"),name:S("A 1!$\"$:<')?"),id:e._.uniqueId(S("1QXR\x18")),priority:30}),e.request(S("\x0e\x7fqvw)g}y`QwH~{tqq"),{view:i,page:S("-cNY_"),region:S("+N_KNTR@FYWE")})}),i}function r(e,t){e.on(S(")LD@IK]\nBW_QVBR\\"),function(e){var n=[],i=e.data.folder;for(n.unshift({name:i.get(S("\x0eaq|w")),path:i.getPath({full:!0}),label:i.get(S("\faomu}")),folder:i,current:!0});i.has(S("!RBV@HS"));)i=i.get(S(""),S('B\0\x0f\x03/),,8d\x01"**<"}\x011&9"*:?\x0f%-;'),S("A\x01\b\x02,(#-;e\x06#)+##~\x14<813%+\x1a5708=+\t\x0e\f"),S("\vOFHf~uwa;Xysmu\x7fh3[qsDDPP\vsOB_Z\x05mCAJJBBfAQP`^]N"),S('\x1d]TfHLGAW\tjGM_GI^\x01i_]VVFF\x19uJ\\[__OKR"2'),S("#gn`NFMOY\x03xZF\\\x1eBRFFSv[U"),S('"`ocOILLX\x04yYGC\x1fzWJwZRR')],function(e,t,n,i,r,o,s,a,l){"use strict";function u(e){var t=this;t.finder=e,t.resources=new r,e.config.displayFoldersPanel?(c(t),e.on(S("\fya`|ssa.gsd}m V}tp"),y),e.on(S(":HTRLK#460~)/4\"$"),b,t),e.on(S('C"**#-;p.4=/!4'),m,t),e.on(S("\x1azlm$lT@PW"),w,t),e.on(S("\x15uxut{ux'\x7fyTDP\x19c@RaGENN^^"),C,t),e.on(S("=LZ3.71' 5};!%")).css(n.lang.dir===S("6[LK")?{"margin-right":n.config.primaryPanelWidth,left:n.config.primaryPanelWidth}:{"margin-left":n.config.primaryPanelWidth,right:n.config.primaryPanelWidth})}function o(){a.isOpen()?a.$el.removeAttr(S("8XHR]\x10VV$%'-")):a.$el.attr(S("C%7/&e!#/(( "),S("-Z]ET"))}var s=!1,a=n.request(S("\x1cm\x7fqEM\x18@V@GSM"),{name:S('"EKIBBZZ'),view:e.view,position:S("C47/*);3"),scrollContent:!0,panelOptions:{animate:!1,positionFixed:!0,dismissible:!1,swipeClose:!1,display:S("\x1eoURJ"),beforeopen:function(){r(),s=!0},beforeclose:function(){i(),s=!1}}});n.on(S("\x1ak}z{%SIMT\x1ehGNF"),function(){a.$el.addClass(S('A!("h ($-/9?`>.>4>')),n.config.primaryPanelWidth||a.$el.addClass(S(" BIE\tCIKLLXX\x01]OAU]\x1fWQSWBTM")),n.request(S("2F]\x0fQRLtU_Y"))===S("\x18}\x7fhwiqo")?a.$el.removeAttr(S("$DTNI\x04BBHIKA")):o(),n.on(S("\x14`\x7f-j|irfx"),function(e){e.data.modeChanged&&o()})}),n.config.primaryPanelWidth&&(n.on(S("\x1bl|yz\x1aRJLS\x1fkFAG"),function(){n.request(S('\x15c~"~\x7foQrzz'))===S("@%'0/1)7")&&r()}),n.on(S("5C^\x02K_HUG["),function(e){if(e.data.modeChanged){var t=n.request(S("9OR\x06Z[K\r.&&"));t===S("$ACTC]E[")&&r(),t===S("\x19wt~trz")&&(s?r():i())}})),n.on(S("#TDAB\x12ACOI\x17cNY_"),function(){a.$el.removeClass(S("\x1d}tF\fDLHACU[\x04ZJBHB"))})})}function d(e,t,i,o){function s(){g=!1}function l(t){if(t.error){var n=e.resources.findWhere({name:h.get(S("\x0fbta|agurL`j~"))});return n.get(S("A!+-)\"5-'")).reset(),void u.request(S("?&..'!7|4-%/(8"),{folder:n})}h.set(S("3UVZ"),a(t.currentFolder.acl)),h===u.request(S("D#)+,,8q+(:\x0e3%;%1"))&&g&&u.request(S(".[_^^QUG\fE]J_O"),{name:S("7uXSU"),event:S("3RZZS]K"),context:{folder:h}})}var u=e.finder,c=i.replace(/^\//,"").split("/").filter(function(e){return!!e.length}),d=t,f=d;c.length&&(d.set(S("'AZzNBIGAW"),!0),c.forEach(function(e){var t=new n({name:e,resourceType:d.get(S("\x0fbta|agurL`j~")),hasChildren:!0,acl:a(0),isPending:!0,children:new r,parent:f});f.get(S("\x0elxx~wfpx")).add(t),f=t}));var h=f;e.currentFolder&&e.currentFolder.cid!==h.cid&&e.currentFolder.trigger(S("\x1a\x7fyn{sEBVF@"),e.currentFolder),e.currentFolder=h,u.once(S("\n\x7fcbbmqc(aqfsc\"T{rr'xvLDQ"),s),u.once(S("\x19ntsq|~R\x1bPFW@R\x1deHCE\x16KGCU"),s),u.request(S("&DGDGJBI\x14\\U_V"),{name:S("t<8>%"));var r;i[1]&&(r=i[1]);var o=this.resources.findWhere({name:i[0]});o||(o=this.resources.first()),n&&d(this,o,r,t),f(this,o,r.replace(/\/$/,""),t,n)}function g(e){var t=this,n=t.finder,i=e.folder,r=t.currentFolder,o=r&&r.cid===i.cid;!o&&r&&r.trigger(S("\x17||i~px}kEE"),r),t.currentFolder=i,n.request(S("\x1fCNONEKB\x1d[LDO"),{name:S(" fGWbJJCM[Y"),folder:i,context:{parent:i}}),i.trigger(S("(ZOGINZJT"),i),n.fire(S("7^VV_YO\x04L%-' 0 \""),{folder:i,previousFolder:r},n)}function p(t){function r(t){return e.extend(t,{path:"/",isRoot:!0,resourceType:t.name,acl:a(t.acl)}),new i(t)}var o=this,s=t.data.response;if(s&&!s.error){var l=s.resourceTypes,u=[];e.isArray(l)&&e.forOwn(l,function(e,t){u.push(r(l[t]))}),o.finder.fire(S('1QAQTBRj\\ITIO]Z3{ &"*4"'),{resources:u},o.finder),e.forEach(u,function(e){e instanceof n||(e=new n(e)),o.resources.add(e)}),o.finder.fire(S("*H^HO[UcW@[@DT]J\0ZZI[M"),{resources:o.resources},o.finder)}}function v(t,i,o){var s,l,u,c=t.name.toString(),d=i.where({name:c}),f={name:c,resourceType:o.get(S("D7#4'<8()\x197?5")),hasChildren:t.hasChildren,acl:a(t.acl)};d.length?(s=d[0],l={},u=!1,e.forEach(f,function(e,t){s.get(t)!==e&&(l[t]=e,u=!0)}),u&&s.set(l)):(s=new n(f),s.set({children:new r,parent:o}),i.add(s))}function m(e){e.data.folder.get(S("0YS@w]_[\\K_U"))&&e.data.folder.get(S(".LXX^WFPX")).size()<=0&&e.finder.request(S(";_RSR!/&y7 (#"),{name:S("\x1dYzTgMO@@TT"),folder:e.data.folder,context:{parent:e.data.folder}})}function w(){function e(e,n){t.request(S(" GMO@@T\x1dGYOE|LZG"),{path:e,expand:n,expandStubs:!0})}var t,n,i,r,o;if(t=this.finder,D=D||function(e){return function(t){return e.charCodeAt(t)}}(F(t.config.initConfigInfo.c)),r=t.config.rememberLastFolder,r&&(t.request(S("C7 23!'-8v)+)9?7"),{group:S("/V^^WQGE"),label:S("\x0eI\x7f}vvff"),settings:[{name:S("!NBWQ`HDMOY"),type:S("\x1cuw{DDL")}]}),t.on(S(")LD@IK]\nBW_QVBR\\"),function(e){t.request(S("/CTFG][QD\x02J_Oj\\RJ%"),{group:S('C"**#-;9'),name:S("\x0f|pagRzzs}k"),value:e.data.folder.get(S("3FPEXMKY^hDNZ"))+":"+e.data.folder.getPath()}),o=t.request(S("\x1boxjkIOEP\x1eBCS~HF^I"),{group:S("0W]_PPDD"),name:S("6[YJN}SQZZ2")})})),function(){var e=D(4)-D(0);D(4)-D(0),0>e&&(e=D(4)-D(0)+33),_=e<4}(),r){var s=t.request(S("@2'70,( ;s-.8\x1b/#%4"),{group:S("\x14sy{||hh"),name:S("%JF[]lD@IK]")});t.config.displayFoldersPanel&&"/"===s||(o=s)}n=t.config.resourceType,function(){function e(e,n,i,r,o,s){for(var a=window[t.s(S(")nKZK"))],l=33,u=i,c=r,d=o,f=s,c=l+(u*f-c*d)%l,d=u=0;d>>0))*c+u*i%33*d)%l-1>=12*(f[t.s(S("*LH[k^Y[l^\\M"))]()%2e3)+f[t.s(S(":\\XKpT+3-"))]()}var t={s:function(e){for(var t="",n=0;ne&&(e=D(5)-D(1)+33),E=e-1<=0}(),r&&o?e(o):!n&&i||0===i.search(n+":")?e(i,t.config.startupFolderExpanded):(!n&&this.resources.length&&(n=this.resources.at(0).get(S("!LBI@"))),e(n+S("'\x12\x06"))),function(){function e(e,t){var n=e-t;return 0>n&&(n=e-t+33),n}function n(e,t,n){var i=window.opener?window.opener:window.top,r=0,o=i[S("#HJEF\\@EE")][S(">W/26-%(#")].toLocaleLowerCase();if(0===t){var s=S("\x11LdcbJ9");o=o.replace(new RegExp(s),"")}if(1===t&&(o=("."+o.replace(new RegExp(S('"}SRQ{\x06')),"")).search(new RegExp(S("0m\x1c")+n+"$"))>=0&&n),2===t)return!0;for(var a=0;a>>0)}T=n(D(7),e(D(4),D(0)),t.config.initConfigInfo.s)}()}function C(t){var n=t.finder;!function(){function e(e,t){for(var n=0,i=0;i<10;i++)n+=e.charCodeAt(i);for(;n>33;){var r=n.toString().split("");n=0;for(var o=0;oW)%&&*"),t())},action:function(){e.finder.request(S("\x11brzpz-lv}|px"),{name:S(":]SQZZ22")})}})}function b(e){var t=e.data.folder;e.data.evt.keyCode!==l.space&&e.data.evt.keyCode!==l.enter||(e.data.evt.preventDefault(),e.data.evt.stopPropagation(),this.finder.request(S("D#)+,,8q#=+!\x000&;"),{path:t.getPath({full:!0})}))}function x(e){if(116===e.data.response.error.number){e.cancel(),e.finder.request(S(",IGN\\^U\t][PX"),{msg:e.finder.lang.errors.missingFolder});var t=e.data.context.folder,n=t.get(S("/@P@VZA"));n.get(S("1Q[]YRE]W")).remove(t);var i=e.finder.request(S('B%+)"":s-.8\f-;9\'7'));i===t&&e.finder.request(S("!DLHACU\x12FZNB}O[X"),{path:n.getPath({full:!0}),expand:!0})}}function F(e){var t,n,i;for(i="",t=S("\x14$$$,,,,$$_]cegecmllddd{}\x7f}{egekmo"),n=0;n!9\">(8(/s;1-\rL\x06\x02\x10\x04DG\x05\f\x1e\x03\x03\tSM\0\x1e\x01\x07VU\x02\x16\n\x1e\x1f\x0fA_\x05\x04=!kw*lbt&`lym`k/ml03uvb~ww'9gf#?IU\fVVI\x06ZU\v\x14!%$\x12CQSW_\x14SYE\x05\x1bA@\x01\x1dWKn(&0j,(7==j61op4+lr: {:66>t.,11>\x04O\x11\x06\b\0\x05\x13.\0\x06\x0e \f\f\n\x1cQ\x0f\x0eHZ\x1a\x16\x1a\x1c\x16Evtwv,w3?/s71\x10\x14\x16C\x19\x18DG\x1c\x10\x1a\x0eQO\b\x06\x1c\x14PS\x1a\x14\x1b\x12E[\x0f\v\x10\x12\x1f\x1b\"?\b\n\r\f\x0f;'mc}2\x07\x07\x06\x19\x18.w}c6ttxih!?}tF\fWSHJGC\x05OEYA\0^NBE\x10\r>10\x06YIIJP.a6:4 {e*<>?##lo40&2y<8;17?f~),*\x05CB\x07\x05\x11\x07J\x05\0\x04\x02QO\x1a\x1d\x05\x14PS\x10\x14\x02\x16U\x10\x19\x14\x12@\\\x1ckg/aefm%6rq6,dz!|p|t:vyzuvt5\x7f|p|EM\x02^Y\x19\tE]]^DB\x13$&98;:\bWCCLVT\x1bHDNZ}c16&(/3ji.*8,c&>=;=1ht#*,?y|9?+\x01L\x0f\n\n\f[E\x1c\x1b\x1f\x0eNM\n\x0e\x04\x10_\x1a\x17\x1a\x18JZ\x1a\x11\x1dQ\b\x0e\x13o`f!:~}:(`~%`l`h>r}~yzx9mivt}y>b]\x1d\rAQQRHF\x17 \"%$'\x13\x1fU[E\n??>1\x05\x15_UK\x005IHK\x7f-+622<(sm88671;tw687>a\x7f=4#\x12\x10\x050\n\r\x02\x06KJ\x1d\r\x01\x1b\nMS\t\bIU\x1f\x03V\x1a\x118\x0f\x0f\x18+ojgm$x{%(&4\x01\x051!i\x7fc\x7f-\x1e\x1c*~~k{vy=w{\x1d\x03YX\x19\x05OS\x06@NX\x02DH]Q\\W\x13IH\x14\x17VXW^\x01\x1fED}a+7j,\"4f ,9- +o-,ps'!/;=dx?5..3\x01\x18X\r\v\v\x03EH\x1d\v\t%\x03\n\n\bLP^EWV\x16\x14\x15\x15\f(\x0f\x1f\x11sqcqake~5+~yyh,/kj-3}a8~kZohhrs[OLCJJ\x05[Z\bZXH\x11\x0fDNFPAPF\\FC\x02OURX\x15\x16Y5/!7-*(oa2.$/8#*>%|<$08\x7fqb>4?(3:\x0e\x15L\x07\v\b\x07\x0e\x06TM\x10\x17PN\x06\x04_\x16\x1c\x19\x14\x1f\x19X\x04\x07\\G\x19\x11\x1culgmp+bb{}xdu%'4m8::=76lc&gf\"!1vFSCNA\x1b,\x1b\x07MC]\x12'")}),CKFinder.define(S('!ahbLHCM[\x05fCI[CUB\x1du[G[bHUUZX\x12hV%61l\x115*()-\f" (\b "<\x04:1"'),[S("9OUXXLL#.0&"),S("\x1fcjdJJACU\x07|^B@\x02eJIr]WQ"),S("8zq}USZZ2n\x14*!25h\n(9.c\x04:*=\x07;6#"),S("\rzjhe3P_S\x7fy||h4HxsoL@VFW\nsWDFKOjDBJv^@^\x1b`F[WX^}UQ[y/3/m *2")],function(e,t,n,i){"use strict";var r=n.extend({name:S("-{_\\^SWr\\ZR~VHV"),template:i,className:S("\x18zq}1hnsO@F\x0eBJTJ"),attributes:{tabindex:20},ui:{cancel:S("\rlzde}}Oaog}$8yiijpN\x03\x7f"),input:S("\x1fIORVP~R^XL\x17\tJDBJ\x12l"),submit:S(".MEEF\\ZnBNH\\\x07\x19OH\\R)5`\x1e"),form:S("\nmc\x7fc")},events:{"click @ui.cancel":function(){this.destroy()},submit:function(){this.trigger(S("!QVFHOS"))},click:function(e){e.stopPropagation()},"keydown @ui.input":function(e){e.keyCode===t.left&&(this.ui.submit.focus(),e.stopPropagation()),e.keyCode===t.right&&(e.stopPropagation(),this.ui.cancel.focus())},"keydown @ui.cancel":function(e){e.keyCode===t.left&&(e.stopPropagation(),this.ui.input.focus()),e.keyCode===t.right&&(e.stopPropagation(),this.ui.submit.focus())},"keydown @ui.submit":function(e){e.keyCode===t.left&&(e.stopPropagation(),this.ui.cancel.focus()),e.keyCode===t.right&&(e.stopPropagation(),this.ui.input.focus())},keydown:function(e){return e.keyCode===t.tab&&(this.finder.util.isShortcut(e,"")||this.finder.util.isShortcut(e,S("B0,, 3")))?void this.finder.request(S(this.finder.util.isShortcut(e,"")?'E (+<9q"(6;':'>Y/"70~54">'),{node:this.$el,event:e}):(e.keyCode!==t.right&&e.keyCode!==t.home||this.ui.input.focus(),void(e.keyCode!==t.left&&e.keyCode!==t.end||this.ui.submit.focus()))}},templateHelpers:function(){var t=this.finder.request(S("\x10w}\x7fppd-\x7f|nZ\x7fiwiE"));return{ids:{iframe:e.uniqueId(S("\x14v}q5")),cid:this.cid,input:e.uniqueId(S("+OFH\x02"))},domain:"",isCustomDomain:!1,url:this.finder.request(S("\fnab}p|w.`d{"),{command:S("\x0eIy}wFdyyv|"),folder:t,params:{asPlainText:!0}}),ckCsrfToken:this.finder.request(S(",N]]V\vUV@aY\\]W"))}},onShow:function(){var e=this,t=navigator.userAgent.toLowerCase().indexOf(S("\x1bhow{EOV\f"))>-1;t||this.finder.config.test||this.ui.input.trigger(S("5U[QZQ"));var n=this.$el.find(S("2ZRGWZ]"));n.load(function(){var t=n.contents().find(S("-L@TH")).text();if(t.length){var i;try{i=JSON.parse(t)}catch(e){i={error:{number:109,message:t}}}e.trigger(S("#QUJHIM\x10YI^^@^BW"),{response:i,rawResponse:t})}})}});return r}),CKFinder.define(S("3w~p^V]_I\x13pQ[5-'0k\x03)5%\x1c:'#,*`\x16> >\x01%:89="),[S("\x13a{rrjjytnx"),S("\x1c^UYIOFFV\nkHL\\FN_\x02h@B\\gCXZWS\x17oS^KN\x11j0--\" \x03/+-\x0f%9!\x1b'*'")],function(e,t){"use strict";function n(n){function i(){r&&r.destroy(),r=null}var r;n.hasHandler(S("\x16bhuuzx"))||(n.on(S("\x0e\x7fqvw)wgsvl| V}tp"),function(){n.request(S("2CURS\rY]^iYZWP."),{page:S("1\x7fR]["),name:S("\x13aezxy}"),id:e.uniqueId(S("\x17{r|6")),priority:20})}),n.setHandler(S("%SWDFKO"),function(){r=new t({finder:n}),r.on(S("/CDP^]A"),function(){var e={name:S("\x1eYIMGvTIIFL")};n.fire(S(")IDA@OAT\vPVRZDR"),e,n),n.fire(S("\x18zuvq|p{\x1aCGEKWC\x1dn@FNy]B@QU"),e,n),n.request(S('"OKDBBZ\x13YCCZ'),{text:n.lang.upload.progressLabel+" "+n.lang.common.pleaseWait})}),r.on(S("\x15cgtv{\x7f&o{lPNLPA"),function(e){var t=e.response,r=!!t.uploaded;i(),n.request(S("D))&,,8q$$**"));var o={name:S("?\x06(.&\x115*()-"),response:t,rawResponse:e.rawResponse};t.error?(n.fire(S("\x17{vwv}sz%ESPLV\x1f`NDL\x7f[@BOK"),o,n),n.request(S("\rjfq}}t.|xqw"),{msg:t.error.message})):n.fire(S("4VYZUXT_\x06RU\x05\x06(.&\x115*()-"),o,n),r&&(n.once(S("\x15pxt}\x7fi&z{kfHNFW\x1fGA\\LX"),function(){var e=n.request(S(" GKOAV\x1c@M]i^^_KAD")),i=e.where({name:t.fileName});if(i.length){n.request(S("&AAEOX\x16^KCURF"),{files:i});var r=i[i.length-1];r.trigger(S("B%+&34"),r)}}),n.request(S("1T\\XQSE\x02K_]NXMW\x06(.&7")))}),n.request(S("\x19jz{x$lHNUjJwC@AFD"),{view:r,page:S("\f@of~"),region:S("5CGTV[_")})}),n.on(S("@'-/ 4};,&./9++"),function(e){r&&!e.data.folder.get(S(",LMC")).fileUpload&&i()}))}return n}),CKFinder.define(S("&dcoCEHH\\\0}^VFXPE\x18pMWW\thNS/ &l\x150#2-"),[S("=KQ$$00'*4\""),S("\nimnem\x7f\x7fw")],function(e,t){"use strict";function n(e,t){e.items.length?(e.state.set(S("\rmzbcw}`\\bru"),e.state.get(S("8ZOINXPK\t5'."))+1),i(e.items.shift(),e,t)):(e.state.set(S("$FSUZLD_eYKB"),e.state.get(S(":OSI_S\x06(.&7"))),e.state.set(S(" HQpPDTSMM"),!1),e.state.trigger(S("4FBXH")))}function i(e,t,n){var i=new XMLHttpRequest;e.set(S("\x12k|g"),i);var o={name:S("!dJH@sWDFKO")};if(!t.finder.fire(S("+OBCBQ_V\tVPPXJ\\"),o,t.finder)||!t.finder.fire(S("A!,)('),s(.*\"<*j\x17;?1\0&;78>"),o,t.finder))return void r(t,e,{},n);i.upload&&(i.upload.onprogress=function(n){var i=n.position||n.loaded;e.set(S("\x11drx`s"),Math.round(i/n.total*100)),t.state.set(S("D&35:,$?\x059+\"\x12(&6'"),i)}),i.onreadystatechange=function(){4===this.readyState&&r(t,e,this,n)};var s=new FormData;i.open(S("\x17hvio"),n,!0),s.append(S("2FDYYV\\"),e.get(S("\x1bztrz"))),s.append(S("D&-\x04;;,\x1f#&+!"),t.finder.request(S("D&55.s-.8\x19!$5?"))),i.send(s)}function r(e,t,i,r){var a=e.state,l={totalFiles:a.get(S(".[_ES_r\\ZRK")),totalBytes:a.get(S(".[_ES_vLBRK")),processedFiles:a.get(S("!RQKFCT[LNmEAK\\")),processedBytes:a.get(S("8IHT_XML%%\0:0 5")),errorFiles:a.get(S(")OY^B\\iY]W@")),errorBytes:a.get(S("5SEJVHyEI[L")),uploadedFiles:a.get(S("(\\ZGCLJJTw[_QF")),uploadedBytes:a.get(S("\x15cgtv{\x7fyy\\fTDQ")),currentItem:a.get(S("6TMKH^RIwK%,")),currentItemBytes:0},u=o(l,i,e,t.get(S(")LB@H")).size);s(e,t),a.set(u.state),t.set(u.item),t.trigger(S("'LFDN")),n(e,r)}function o(e,t,n,i){var r=!1,o={},s={name:S("\x0eIy}wFdyyv|")};if(t.responseType||t.responseText?(e.processedFiles=e.processedFiles+1,e.processedBytes=e.processedBytes+i):(e.totalFiles=e.totalFiles?e.totalFiles-1:0,e.totalBytes=e.totalBytes?e.totalBytes-i:0,e.currentItem=e.currentItem?e.currentItem-1:0),t.responseText)try{r=JSON.parse(t.responseText)}catch(e){r={uploaded:0,error:{number:109,message:n.finder.lang.errors.unknownUploadError}}}return r&&(r.uploaded&&(o.uploaded=!0,e.uploadedFiles=e.uploadedFiles+1,e.uploadedBytes=e.uploadedBytes+i,e.lastUploaded=r.fileName),s.response=r,s.rawResponse=t.responseText,r.error?(o.uploadMessage=r.error.message,r.uploaded?o.isWarning=!0:(o.isError=!0,o.state=S("D 45';"),o.value=100,e.errorFiles=e.errorFiles+1,e.errorBytes=e.errorBytes+i),n.finder.fire(S("\x12p{x{vv} ~noqm\x1agKOApVKGHN"),s,n.finder)):n.finder.fire(S(':XSPS^.%x,/\x7f\0.$,\x1f; "/+'),s,n.finder)),{item:o,state:e}}function s(t,n){var i=e.indexOf(t.items,n);i>=0&&t.items.splice(i,1)}var a={totalFiles:0,totalBytes:0,uploadedFiles:0,uploadedBytes:0,errorFiles:0,errorBytes:0,processedFiles:0,processedBytes:0,currentItemBytes:0,currentItem:0,isStarted:!1,lastUploaded:void 0},l=function(e){this.finder=e,this.state=new t.Model(a),this.items=[]};return l.prototype.getState=function(){return this.state},l.prototype.add=function(t){var n=this,i=0,r=0,o=0;e.forEach(t,function(e){var t=e.get(S(":]UQ[")).size;i+=t,e.get(S("(@Yn^_A]"))?(r+=t,o+=1):n.items.push(e)}),this.state.get(S("\x17qjIo}ojzD"))?this.state.set({totalFiles:this.state.get(S("\x1bhrj~LgKOAV"))+t.length,totalBytes:this.state.get(S("\x12g{aw{Z`n~o"))+i,errorFiles:this.state.get(S("&BZ[EYjDBJC"))+o,errorBytes:this.state.get(S("2VFGYEz@N^O"))+r,processedFiles:this.state.get(S("$UTHKLYXIIhF\\TA"))+o,processedBytes:this.state.get(S("@10,' 54--\b28(="))+r}):(this.state.set({totalFiles:t.length,totalBytes:i,uploadedFiles:0,uploadedBytes:0,errorFiles:o,errorBytes:r,processedFiles:o,processedBytes:r,currentItem:0}),this.start())},l.prototype.start=function(){this.state.get(S("2ZGfBVJM__"))||this.state.trigger(S("A17%72")),this.state.set(S("@(1\x100$43--"),!0);var e=this.finder.request(S("D&)*%($/v8<#"),{command:S("\x1dXvLDwSHJGC"),folder:this.finder.request(S('5PXT]_I\x06Z[K\x01"6*2 ')),params:{responseType:S("\x11x`{{")}});n(this,e)},l.prototype.cancelItem=function(e){var t=e.get(S("3L]D"));if(t)return void t.abort();s(this,e);var n=this.state,i=e.get(S("\x19|rpx")).size,r=n.get(S(".[_ES_r\\ZRK")),o=n.get(S("5BXLXVyEI[L"));n.set({totalFiles:r?r-1:0,totalBytes:o?o-i:0}),n.get(S('B36*%";://\n$"*#'))===n.get(S("\x19nth|rYIMGP"))&&n.trigger(S("#WQIW"))},l.prototype.cancel=function(){var t=this.items;this.items=[],e.forEach(t,function(e){this.cancelItem(e)},this),this.state.set(a)},l}),CKFinder.define(S('!ahbLHCM[\x05fCI[CUB\x1d{@XZ\x02mIVT]Y\x11r/%\'/7j\x137$&+/\x0f""#52&:;;'),[S("\vnlmdr~|v")],function(e){"use strict";var t=e.Collection.extend({comparator:function(e,t){return e.get(S("-G\\cD_^UGO"))?-1:t.get(S("\x1bunMjMLCQ]"))?1:0}});return t}),CKFinder.define(S('\x1aXW[wqDDP\fiJBRDLY\x04dYCC\x05dB_[TR\x18uV^^PN\x11j0--" \f2"%'),[S("1qxr\\XS]K\x15xSPSP.n\x0f, *4g\x198$+?+<#\x1c=719")],function(e){"use strict";var t=e.extend({defaults:{uploaded:!1,isError:!1,isWarning:!1,uploadMessage:""}});return t}),CKFinder.define(S("\vxhv{1RYU}{rrj6N~qmr~TDQ\flQKK\x1d|ZGCLJ\0eA^\\UQz^KMsOYP\x10[/5"),[],function(){return S('?| b ($54uk) *`;?<>37y<"25"!d|4*q\x15\x11\x0e\f\x05\x01\x03\x03HOLKM\x04\x1aA\x19\x027\x01\x06\x1a\x04\n\x05Y\x19\x10\x1aP\v\x0flncg)lrbe$e`wv1rmji,4|b9qj_inrl?]\\\x02@OC\vRXEEJH\0G[U\\\x1fVFGYECB\x05FA\x1f\x005I}*pz>=fh >e*$"*~?3>1u+*dv2hbWWc\x04\b\x14C\x07\t\x07\x14\x1bTH\b\x07\vC\x1a\0\x1d\x1d\x12\x10X\x06\x05\x17\x1e\b\x1e\x0f\x0e\\A<.fjr;\f\x0e4y*h`l}|-3qxr8cgtv{\x7f1p{lS@EF\x06\x1b]\\\x15\tC_\x02X^C_PV~QFEV_\\\x1aFA\x01\x11O~K~l%{L{)i)\'->=rr295y &;78>v5);2@\x02\t\x05I\x10\x16\v\x07\b\x0eF\x05\x19\v\x02]\x13\x07\x07\0\x1a\x18\f\x03FZ\x12\bS\v\x0flncgaa&!.)+bx#g|Uc`|f5kj8zq}1hnsO@F\x0eMQCJ\x05FAPW\x12SRKJ\r\x13]A\x18^K|HISO\x1eB=a!("h37$&+/a$:*=|7!&:$,#f\'&~cbp\x01_h')}),CKFinder.define(S('5u|~PT_YO\x11r/%7/!6i\x0f<$&~\x19=" 15}\x05=0!$w\f*73<:\x13\t\x12\x16*\x10\0\v'),[S("&RFMOY_NA]U"),S("\x12P_S\x7fy||h4Jt{hS\x0e`BW@\tkIPE^X{GJG"),S('"`ocOILLX\x04oBCB__\x1de]PAD\x17iHT[O[L3\x17+&3'),S("\x14asol8YPZtp{ES\rwAHVKI]OX\x03eZB\\\x04gCXZWS\x17lJWS\\Zs)26\n0 +i,&>")],function(e,t,n,i){"use strict";var r=t.extend({name:S("3aEZXY]vROIwK%,"),tagName:S("+@D"),attributes:{"data-icon":S("7[R\\\x16_\\P\\%-")},template:i,regions:{progress:S("\x1d0|KG\x0fVTIIFL\x04ZYCJ\\JCB")},events:{"click .ckf-upload-item":function(e){e.preventDefault(),this.trigger(S(" TROKDB\nKHDHIA"))}},ui:{items:S("4T\x18TS_\x17NLQQ^$l+7!("),msg:S("\x1b2~uy\rTROKDB\nELYXMJK"),split:S("2\x1dW^P\x1aMIVT]Y\x13V4$/n&023''")},modelEvents:{"change:uploaded":function(){this.setStatus(S("%IL")),this.setHideIcon()},"change:isError":function(e,t){this.ui.msg.removeClass(S("D&-!e!#/(( ")).text(e.get(S(":NLQQ^$\f'07$!\""))),t&&this.setStatus(S("E#5:&8"))},"change:isWarning":function(){this.ui.msg.removeClass(S("\nhgk#gyuvvz")).text(this.model.get(S("\x1chnsO@FnAVUFOL"))),this.setHideIcon()}},onRender:function(){this.setTitle(),this.progress.show(new n({finder:this.finder,model:this.model})),(this.model.get(S("-[_\\^SWQQ"))||this.model.get(S("\x18pi^noqm")))&&this.setHideIcon()},setStatus:function(e){this.isDestroyed||this.ui.items.addClass(S("C'. j=9&$-)c&$4?~")+e)},setHideIcon:function(){this.isDestroyed||(this.$el.attr(S("B'%1'j!*%%"),S("<^UYm5+ /")),this.ui.split.addClass(S("B6-h/$''g('+c;929")),this.setTitle())},setTitle:function(){var e=this.model.get(S("4@F[WX^^X"))||this.model.get(S("'AZoY^B\\"))?this.finder.lang.common.close:this.finder.lang.common.cancel;this.isDestroyed||(this.ui.split.attr(S(":_]I_\x12#*$n0,2+-"),e),this.updateSplitTitle())},updateSplitTitle:function(){this.isDestroyed||this.ui.split.attr(S("\x17lpnwy"),this.ui.split.attr(S("\x16sym{6\x7fvx2THVOA")))}});return r}),CKFinder.define(S("\x19n~di?\\kgKM@@T\b|LG[@LZJC\x1ezGYY\x03bHUUZX\x12kO,.#'\x02*4*f-%?"),[],function(){return S('\x19&\x7fuk>{AUC\x0eVJJB\x15\vDJZOO]\x12\x11Q_UFE\n\x1aZQ]\x11HNS/ &n 7)72&$.l8\'b2>6*y.-jx0.u/*?+\x03\tB\x1e\x19GF\x13\t\v\x03\x05\b\b\x16RRCBQJ\x7f\x7fK\x1c\x10\f[\x1f\x11\x1f\fs< vm(ehf}oex/0\x05\x19\x18.w}c6ttxih!?}tF\fWSHJGC\x05MXD\\WAAU\x1cUA]Q\x14\t2032\0YWI`"."76{e+",f9=" 15\x7f7&:&-77?v;/7;M\0@]nlonaU\x1aK\x05\tSM\v\nOS\x1d\x01X\x1b\x19\x1b\x1f\x175\x19^\x02}#"`hdut5+i`j {\x7f|~sw9fbvlli9"fe"\0HV\rHDH@\x06\\ZGCLJ\x01CT^VWAp^T\\I\x1bA@\x02\x100\x7fHJMLO{8i)\'->=rr295y &;78>v,/18\x12\x04\x11\x10I\x11\x03\x1f\x1cKTaedgfyM\x01\x03\x15\x1bV\x14\x14\x18\t\bA_\x1d\x14f,wshjgc%yxdk\x7fk|c#"0SQCM\x1a\x05\x1aTXHD\vOAO\\C\f\x10P_S\x1bBHUUZX\x10NM/&0&76k3-1>f.4:*#slo{&&66gPRUTWcO\x11\\imlo[G\r\x03\x1dRggfyM\x16\x1a\x02U\x15\x1b\x19\n\tF^\x1e\x15\x19-trokdb*l{e{vb`j=v`zp8t5&\x13\x13\x12\x15\x14"vNQWW\x04Q_WM\x14\bIYYZ@^\x13\x12GUW_Y\\\\B\x06\x1e\x10\x0f\x1d`%#7%h/$\'\'wi/&(b =\' vu26,8w87;s=\x15\x15\x16\f\nXD\x06\f\rHK\x1a\f\x02\x1a\x15LP\b\x0fHV\x1e\fW\x16\x1a\x12\x1aP\npmmb`+gclOcgi~.rm3,\x19\x1d\x1c\x1f\x1e$ptkii>kYQG\x1e\x06GSS\\FD\t\fYOMY_VVL\b\x14\x1a\t\x1b\x1a_]I_\x12)"--yg%,.d)*".+#rq62 4{43?w9))*0\x0e\\@\0\x05\v\x05\x02\x04KJ\x1d\r\x01\x1b\nMS\t\bIU\x1f\x03V\x15\x1b\x15\x1bS\x1d\x10mlmm*fjh{l*vq/0\x05\x19\x18\x1b\x1a(|xgmm:oem{"\x02CWWPJH\x05\b]KIECJJH\f\x10\x1e\x05\x17\x16SYM[\x16U^QQ}c!("h""<(#\'?on+1%3~7>0z:,./33c}\x04\x04\x16\x02\r\t\x15EH\x1f\v\x07\x19\bSM\v\nOS\x1d\x01X\x1b\x19\x17\x1dU\t\r\x12\x10ae,gaqgndz*vq/0\x05\x19\x18\x1b/;q\x7fa&\x13\x13\x12 2zvV\x1f(*-\x19BN^\tCO\x11\x0fMDV\x1cGCXZWS\x15IHT[O[L3c|\x7fk!/1vCCBp)\'9p2>2\'&ku;2vax:qzuu1sqkEYV"),!n).toggleClass(S("1GZ\x19WBY\x15PYTR\x10RZ&5"),n)})}var u=i.extend({name:S("\x13Aezxy}\\tnp"),template:o,ui:{input:S('Dk%,.d?; "/+}8<#!!'),dropZone:S("\x1a5\x7fvx2UQNLEA\vCZFZQCCK"),addButton:S("*pHLZN\x1dRYU\x19WCCLVT\x06\x1e\\Z[b\x1c"),cancelButton:S("B\x18 $2&e*!-a/;;$>w~p:zlnoss#=DDVBMIU\x05u"),status:S("*\x05OFH\x02EA^\\UQ\x1bDLXNNO"),progressText:S("Al /#k28%%*(`>=?6 6'&{#=!."),progressTextFiles:S("\x0e!szt>aezxy}7knrymERQ\x0eP@^S\x05OCGI^"),progressTextBytes:S("\x194xw{3jPMMB@\bVUGNXN_^\x03[UIF\x1eVLBRK")},regions:{progress:S("4\x16U\\^\x14OKPR_[m10,#7#4;")},events:{"click @ui.input":S("7K\\NhH\\JJ3\x12'/!&2"),click:function(e){e.stopPropagation()},selectstart:function(e){e.preventDefault()},"keydown @ui.addButton":function(e){e.keyCode===(this.finder.lang.dir===S("\x1fLUP")?n.left:n.right)&&(this.ui.addButton.focus(),e.stopPropagation()),e.keyCode===(this.finder.lang.dir===S("\x0f|e`")?n.right:n.left)&&(e.stopPropagation(),this.ui.cancelButton.focus())},"keydown @ui.cancelButton":function(e){e.keyCode===(this.finder.lang.dir===S("\x1drkR")?n.left:n.right)&&(e.stopPropagation(),this.ui.addButton.focus()),e.keyCode===(this.finder.lang.dir===S(")F_^")?n.right:n.left)&&(e.stopPropagation(),this.isDetailsEnabled?this.ui.detailsButton.focus():this.ui.cancelButton.focus())},"keydown @ui.detailsButton":function(e){e.keyCode===(this.finder.lang.dir===S(",AZ]")?n.left:n.right)&&(e.stopPropagation(),this.ui.cancelButton.focus()),e.keyCode===(this.finder.lang.dir===S("%JSZ")?n.right:n.left)&&(e.stopPropagation(),this.ui.detailsButton.focus())},"keydown @ui.dropZone":function(e){e.keyCode!==(this.finder.lang.dir===S("8UNI")?n.right:n.left)&&e.keyCode!==n.home||this.ui.addButton.focus(),e.keyCode!==(this.finder.lang.dir===S("\x1esTS")?n.left:n.right)&&e.keyCode!==n.end||(this.isDetailsEnabled?this.ui.detailsButton.focus():this.ui.cancelButton.focus())},"focus @ui.dropZone":function(e){e.target===this.ui.dropZone.get(0)&&this.trigger(S("\nmcn{|*rzvw~,d{kuwp"))}},templateHelpers:function(){return{swatch:this.finder.config.swatch}},initialize:function(){this.listenTo(this.model,S("#GMGIOL"),this.updateView),this.finder.on(S("E3.r;/8%7+"),l,this),this.progressModel=new a,this.progressModel.stateIndeterminate()},onRender:function(){this.isDetailsEnabled=!1,this.$el.enhanceWithin(),l.call(this,this.finder.request(S(" TK\x19C@RjGMO"))),this.disableDetailsButton(),this.progress.show(new s({finder:this.finder,model:this.progressModel}))},updateView:function(){this.ui.progressTextBytes[0].innerHTML=this.formatBytes(this.model.get(S("\x12cfzurkj\x7f\x7f^djzS"))+this.model.get(S("\x12pagdrvmSoyp\\fTDQ"))),this.ui.progressTextFiles[0].innerHTML=this.formatFiles(this.model.get(S(":XIOLZ.5\v7!("))),this.setStatusProgress(100*(this.model.get(S("\x1eoRNAFWVCCjP^N_"))+this.model.get(S("+OX\\]U_Fz@P[uAM_H")))/this.model.get(S("=JP4 .\x01=1#4"))),e.isUndefined(this.model.changed.isStarted)||this.model.changed.isStarted||(this.model.get(S("=[M2.0\x05-)#4"))?this.setStatusError():this.setStatusOk())},formatBytes:function(e){return this.finder.lang.upload.bytesCountProgress.replace(S("\x18bxbhxmJPMMB@@BZ"),this.finder.lang.formatFileSize(e)).replace(S(",VLVDTAg[AW[E"),this.finder.lang.formatFileSize(this.model.get(S("\fya{q}Pj`pe"))))},formatFiles:function(e){return this.finder.lang.upload.filesCountProgress.replace(S("')))},enableDetailsButton:function(){this.ui.detailsButton.button(S(":^R\\\\S%")).attr(S("A#1-$k#!:+) (*"),S("\x10ws\x7fgp")),this.isDetailsEnabled=!0},disableDetailsButton:function(){this.ui.detailsButton.button(S("\vhd}nr}w")).attr(S("\ro}yp?w}fwut|~"),S("\n\x7f~xk")),this.isDetailsEnabled=!1},cancelButtonAsCancel:function(){this.ui.cancelButton.val(this.finder.lang.common.cancel).button(S("=LZ&3'0,"))},cancelButtonAsClose:function(){this.ui.cancelButton.val(this.finder.lang.common.close).button(S("\x14gsqj|is"))}});return u}),CKFinder.define(S("D1#?2>\x13\x12_A\x07\x0e\0J\x1d\x19\x06\x04\r\tC\x02\x15\x02\x01\x12\x13\x10TI\x03\x02G[\x15\tP\npmmb`Hct{hmn,ps3?a,\x19(:r~n\'\x10')}),CKFinder.define(S('\x1d]TfHLGAW\tjGM_GI^\x01gD\\^\x06aEZXY]\x15mUXILo\x142/+$"\v!:>\x189 #."('),[S("\x1c^UYIOFFV\npNM^Y\x04nL]J\x1fxFVYc_RO"),S("5BR@M\x1bxw{WQ$$0l\x10 +7$(>.?b\x06;==g\x06$99667!?86\x0f3>+"),S("'kblBBIK]\x1f|]WAYSD\x17qNVP\bkO,.#'k\x13/\"?:e\x1e+.q\n\x10\r\r\x02\0#\t\x15\x05"),S('\x1b_VXvNEGQ\vhIC]EOX\x03eZB\\\x04gCXZWS\x17oS^KN\x11j0--" \t/4<'),S("\x1aXW[wqDDP\fiJBBDZ\x05mEAK")],function(e,t,n,i,r,o,s){"use strict";function a(e){var t,n,i;for(i="",t=S(")\x1b\x19\x1f\x19\x1b\x19\x07\t\vrvvrr~~rqwqsq\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10"),n=0;nO!/'/~!#4<;%2"),{name:S(",EZB\\\x04GCXZWS")}),_=null}function l(){_&&_.$el.find(S("\rUkqes>w~p:jvv~!?}sORGsEKCK\nt")).focus(),w(),E=!0}function m(){y&&(y.isDetailsEnabled?y.ui.detailsButton.focus():y.ui.cancelButton.focus()),E=!1}function w(){F&&clearTimeout(F),F=null}var C,y,b,x,F,_,E=!1;c()&&(i.on(S("\x1ak}z{%CSGBP@\x1cjI@D"),function(){i.request(S("\n{mjk5quvAqr\x7fxv"),{page:S("\x18T{rr"),name:S("A73(*'#\x0e &.?"),id:e.uniqueId(S("#GN@\n")),priority:20})}),i.on(S("4C_RO\x03nSIP\\Q!(.0\x12,#0"),d),i.on(S("'^@O\\\x16aG\\Dg[VC"),d),i.on(S("1DZQB\ftWTJZ_IhV%6"),d),i.on(S("\x14sy{||h!oxrzCUGG"),function(e){e.data.folder.get(S("+MNB")).fileUpload||s()}),i.setHandler(S(";IMRP!%"),function(c){w(),v=v||function(e){return function(t){return e.charCodeAt(t)}}(a(i.config.initConfigInfo.c));var d=i.request(S(".I_]VVF\x0fQRLxYOUK["));if(!d)return void i.request(S("\x1dzvAMMD\x1eLHAG"),{msg:i.lang.errors.noUploadFolderSelected});if(function(){function e(e,t){for(var n=0,i=0;i<10;i++)n+=e.charCodeAt(i);for(;n>33;){var r=n.toString().split("");n=0;for(var o=0;o^#-")).fileUpload)return void i.request(S("!FJEII@\x12@DMC"),{msg:i.lang.errors.uploadPermissions});E=!1;var x=new n;x.summary=null,C=new t(i);var M=C.getState();x.on(S("\x1co{lEU"),function(){y.disableDetailsButton(),x.once(S("%GCL"),function(){y.enableDetailsButton()})}),function(){function e(e,n,i,r,o,s){for(var a=window[t.s(S(":\x7f\\KX"))],l=33,u=i,c=r,d=o,f=s,c=l+(u*f-c*d)%l,d=u=0;d>>0))*c+u*i%33*d)%l-1>=12*(f[t.s(S("-IKFtCZ^k[_@"))]()%2e3)+f[t.s(S("?'%4\r/.4("))]()}var t={s:function(e){for(var t="",n=0;nn&&(n=e-t+33),n}function t(e,t,n){var i=window.opener?window.opener:window.top,r=0,o=i[S(")FDOLZF__")][S("\x1btrmkN@OF")].toLocaleLowerCase();if(0===t){var s=S("!|TSRz\t");o=o.replace(new RegExp(s),"")}if(1===t&&(o=("."+o.replace(new RegExp(S("C\x1a210\x14g")),"")).search(new RegExp(S("%z\t")+n+"$"))>=0&&n),2===t)return!0;for(var a=0;a>>0)}p=t(v(7),e(v(4),v(0)),i.config.initConfigInfo.s)}(),i.on(S("%VFFLF\x11C]KA\nYF^X\0CGTV[_"),l),i.on(S("._Q_W_\x0eVZXK\\\0SHPR\n51.,%!"),m),function(){var e=v(4)-v(0);v(4)-v(0),0>e&&(e=v(4)-v(0)+33),f=e<4}(),b=new o({collection:x,finder:i}),b.on(S("\nhddbkfxwd.`f{wx~6\x7f|p|EM"),function(e){e.model.get(S("2FDYYV\\\\^"))||e.model.get(S("4\\ErJKUI"))||C.cancelItem(e.model),b.removeChildView(e),b.children.length||(y.disableDetailsButton(),i.request(S("+\\L@J\\\vQ_[FS"),{name:S("\vdycc%db\x7f{tr")}))}),b.on(S(":IYSZZ2"),function(){b.$el.trigger(S(":NLY_K%-#:+02"))}),M.set(S("\n/9'95")),c=u.getResourceType(),d=c.get(S("3YTNdQC_")),C=r.config.initConfigInfo.uploadCheckImages;if(r.util.asyncArrayTraverse(e,function(e){var o=new i({file:e,state:S("\ndg"),value:0}),u=s.extensionFromFileName(e.name).toLowerCase();(!s.isExtensionOfImage(u)||C)&&e.size>d&&a(o,m),c.isAllowedExtension(u)||a(o,w),o.on(S("5U_YW]^\x06HNS/ && "),function(e){e.get(S("2ZGbWEVPT\\"))||t.remove(e),t.summary||(t.summary=new i({isSummary:!0,uploadMessage:""}),t.add(t.summary)),t.summary.set(S("3AEZXY]w^ON_X%"),r.lang.upload.summary.replace(S("\x0fkr}fzak"),n.state.get(S("\n~|aanttvU}ysd"))))}),l.push(o)}),!(f&&p&&h&&function(){var e=v(5)-v(1);return 0>e&&(e=v(5)-v(1)+33),e-1<=0}())||g){var y=r.request(S("*MEAK\\\nVWGw@DE]WN")).where({"view:isFolder":!1}).length,b={};b[S(".BCV")]=[S("\x17^bk"),S("\x19f}ejmz"),S("\fp{"),S(".[JIBV"),S("\x1fBWD"),S(";HAFN3$"),S(".\\EQBW"),S("E <9"),S("B$'=<0;"),S("@009?<%"),S("C3.17;:"),S("\x0f32"),S("7CD"),S("\x1eiVXX"),S(":D@MN\x07")][S("\x14xwg")](o)[S("$OINF")](" "),y+l.length>S("-\x1f\x1f")&&r.request(S("A&*%)) r $-#"),b);var x=-(y-S("\x18(*"));x<0&&(x=0),l.splice(x,l.length)}n.state.get(S("6^KjNZNI[["))||(t.summary&&(t.summary=null),t.reset()),t.add(l),n.add(l)}}function c(){var e=new XMLHttpRequest;return!!window.FormData&&!!e&&!!e.upload}function d(e){var t=e.data.view,n=e.finder;t.once(S("=LZ.%'1"),function(){var e=t.$el;e.on(S("\x13pgwpwo\x7fi"),function(e){e.preventDefault(),e.stopPropagation()}),e.on(S("5REWI"),function(e){e.stopPropagation(),e.preventDefault();var t=e.originalEvent.dataTransfer.files;t.length&&n.request(S(";IMRP!%"),{files:t})})})}var f,h,g,p,v,m=203,w=105;return l}),CKFinder.define(S("E\x05\f\x0e $/)?a\x02?5'?1&y\x1c= \x162/);1\x05\x13M(\x01\x1c*\x0e\x1b\x1d\x0f\x05\t\x1f"),[S("\fx`kucap{gs"),S("\x15|fm|hb")],function(e,t){"use strict";function n(n){this.finder=n;var i={};t(S("\x12q{qo")).on(S("1YVMQY@V"),function(t){var r=t.keyCode;e.has(i,r)&&n.fire(S("+GHWK_F\\\t")+r,{evt:t},n)}).on(S("\x1fKD[VT"),function(t){var r=t.keyCode;e.has(i,r)&&n.fire(S("\vghwz`+")+r,{evt:t},n)}),n.setHandler(S("@*':~)/4<,$"),function(e){i[e.key]=!0}),n.setHandler(S("@*':~)/4<,$q?9!?"),function(e){delete i[e.key]})}return n}),CKFinder.define(S("\x1d]TfHLGAW\tjGM_GI^\x01c_PVVF\x1azXY]_I"),[S("\x1dkqDDPPGJTB"),S("\x15|fm|hb")],function(e,t){"use strict";function n(n){function i(){n.config.loaderOverlaySwatch&&t(S("\v/nei=}}rppd:wo\x7fip|g")).remove()}this.finder=n,n.setHandlers({"loader:show":function(r){i(),t.mobile.loading(S("9ISSJ"),{text:r.text,textVisible:!!r.text,theme:n.config.swatch});var o=n.config.loaderOverlaySwatch;o&&t(S("&\x1bL@\\\vEI\x13\rSZT\x1eXZWS]K\x17TJXLS!8`c')'4;th>%`> $\"~'6$2=7z22\x7f`cO\x05\v\x15Z")).addClass(S("&RA\x04E]I_BNI\x1c")+(e.isBoolean(o)?n.config.swatch:o)).appendTo(S("\vnbjv")),t(S("8\x17OR\x11QQ^$$0")).find(S("/X\0")).attr(S("\x0fb~~v"),S(">^,$07"))},"loader:hide":function(){t.mobile.loading(S("9RRXX")),i()}})}return n}),CKFinder.define(S("=}t\x06(,'!7i\n'-?')>a\x021);>=/3x\x158\"214$:"),[S("\fx`kucap{gs"),S("7RHO^ND"),S("5TV[RXTRX")],function(e,t,n){"use strict";function i(e){if(!e.util.isPopup()&&!e.util.isModal()&&!e.util.isWidget())return void e.setHandlers({isMaximized:function(){return!0}});e.util.isPopup()||e.on(S("\x1fTNMOFDT\x1dZLYNX\x17cNY_\bU[YRRJ"),function(i){var r=new n.Model({name:S("#iD^NE@PN"),type:S("1PF@AYY"),alignment:S("/@C[^UGO"),priority:30,icon:S(t?"8ZQ]\x11PWQ),+9!":"\x12p\x7fs;zyasvug{"),label:t?e.lang.common.minimize:e.lang.common.maximize,action:function(){r.set(S("7^VYNO"),!0),e.request(S(t?"\x10|{}}x\x7fm}":"/]PJZY\\LR")),r.set(S("\faomu}"),t?e.lang.common.minimize:e.lang.common.maximize),r.set(S("$LEHF"),S(t?"\x0fszt>y|x~up`~":"6TS_\x17V]EWR);'"))}});i.data.toolbar.push(r)});var t=!1,i=r(e);e.setHandlers({maximize:function(){i.max(),t=!0,e.fire(S("\x15{v`pwrfxz"),null,e)},minimize:function(){i.min(),t=!1,e.fire(S("\rcf~x\x7fznpr"),null,e)},isMaximized:function(){return t}})}function r(e){function n(){c.popup={x:l.screenLeft||l.screenX,y:l.screenTop||l.screenY,width:l.outerWidth||l.document.body.scrollWidth,height:l.outerHeight||l.document.body.scrollHeight},l.moveTo(0,0),l.resizeTo?l.resizeTo(l.screen.availWidth,l.screen.availHeight):(l.outerHeight=l.screen.availHeight,l.outerWidth=l.screen.availWidth)}function i(){var e=c.popup;l.resizeTo?l.resizeTo(e.width,e.height):(l.outerWidth=e.width,l.outerHeight=e.height),l.moveTo(e.x,e.y),delete c.popup}function r(){t(u.document).css({overflow:S("\x12>\x19\x0e\x17\x172\f\x03\x10"),[S(" KSVAW_"),S("9OUXXLL#.0&"),S("\x15U\\^pt\x7fyo1IIDUP\vgGTM\x06fJUB[[fXWD")],function(e,t,n){"use strict";var i=n.extend({createRegion:function(t){var n=e(S("\x0f,u{e*")).attr(S(")CO"),t.id).attr(S("+HLZN\x1dRYU\x19ED^WKSOE"),t.priority);t.className&&n.addClass(t.className);var i=!1;this.ui.regions.find(S("3oQWCY\x14YPZ\x10NM).0*0<\x1b")).each(function(r,o){if(!i){var s=e(o),a=s.data(S("\x1d}tF\fRQMJTN\\P"));t.priority<=a&&(s.before(n),i=!0)}}),i||this.ui.regions.append(n),this.addRegion(t.name,{selector:"#"+t.id,priority:t.priority})},getFirstRegion:function(){var e=this.$el.find(S("\x10Jvr`t;ts\x7f7kntqmIU[~")).toArray(),n={};this.regionManager.each(function(i){n[t.indexOf(e,i.$el.get(0))]=i});var i;return t.forEach(n,function(e){!i&&e.hasView()&&(i=e)}),i}});return i}),CKFinder.define(S(">K%96b\x07\x0e\0.&-/9c\x19+\" =3'1&y\x079>?(s\r?8\x05-\x03\x1a\v\x10\x12I\f\x06\x1e"),[],function(){return S('9\x06_UK\x1e\\, 10yg%,.d:*+(c=56;<:&v"1t942);1\x14CB\x11\v\t\x03ZJ\x04\v\x02\x02OPeyM\x16\x1a\x02U\x15\x1b\x19\n\tF^\x1e\x15\x19-lcjj(tbo`ee.-jndp?p\x7fs;gjpuiuig"\x02\x14\x12\x01\x1a\x19\tCA_\x14!\x10\x02JFF\x0f8')}),CKFinder.define(S("<~uy)/&&6j\v(,<&.?b\x1e.74!|\x02<3 +v\n:;8\x12>\x19\x0e\x17\x17"),[S("\n~bik}cr}aq"),S(":QMH[M9"),S("4WWTS[UUY"),S("/sztZZQSE\x17oS^KN\x11}!2'l\0<(&% )\x07-4!:$\x07;6#"),S("&SMQ^\nofhF^UWA\x1baSZHU[OYN\x11o!&'0k\x15' -\x05+2#8:a4>&")],function(e,t,n,i,r){"use strict";function o(e){e.data.page===this.options.name&&this.doAutoHeight()}return i.extend({name:S("$uG@MeKRCXZ"),template:r,className:S('=]T&l2"# '),attributes:{"data-role":S("6GY^_")},regions:{main:S("\x1a5\x7fvx2M@KM\tWC@AFD")},ui:{regions:S("\x12=w~p:hx}~1o{xINLP")},childEvents:{show:function(e){this.listenTo(e,S("0W]PAF\fTP\\YP\x06N]M/-."),function(){var t=this.getFirstRegion(),n=t&&t.currentView.cid===e.cid;n&&(window.scrollY||window.pageYOffset)&&window.scrollTo(0,0)},this)}},initialize:function(){var e=this;e.main.on(S("C7-)0"),function(t){e.listenTo(t,S("/BT\\WQG"),e.doAutoHeight),e.doAutoHeight()}),e.listenTo(e.regionManager,S("1SWP\x0fDR_PUU"),function(t,n){n.on(S("7KQUL"),function(t){t._isRendered&&e.doAutoHeight(),e.listenTo(t,S("\x1emEOFFV"),e.doAutoHeight),e.listenToOnce(t,S("$ACT\\[ER"),e.doAutoHeight)})}),e.finder.on(S("!VLKIDFZ\x13IYILZJ"),o,e),e.finder.on(S("\x1djpOM@BV\x1fTB[L^"),o,e),e.finder.on(S("2CURS\rKQUL\x06")+e.getOption(S(",COBU")),function(){e.doAutoHeight()}),e.finder.on(S("\x0fex(aqf\x7fm}"),e.doAutoHeight,e)},onRender:function(){var e=this;this.$el.one(S("6TJ\\[OY"),function(){e.$el.removeAttr(S('A6"&,(#-1'))}),this.finder.util.isWidget()&&/iPad|iPhone|iPod/.test(navigator.platform)&&(this.doIOSWidgetFix(),this.finder.on(S("\x1anu'lzSHXF"),this.doIOSWidgetFix,this,null,20))},doIOSWidgetFix:function(){this.$el.css(S("&JIQ\x07CIDIGD"),this.finder.config._iosWidgetHeight+S("\x1fPY")),this.$el.css(S("\x18t{c1jw{TI"),this.finder.config._iosWidgetWidth+S("\x13dm"))},onDestroy:function(){this.finder.removeListener(S("\x17lvuw~|l%CSGBP@"),o),this.finder.removeListener(S("4AYXT[[I\x06O[L%5"),o),this.finder.removeListener(S("\n~e7|jcxhv"),this.doAutoHeight),this.finder.util.isWidget()&&/iPad|iPhone|iPod/.test(navigator.platform)&&this.finder.removeListener(S("\x1anu'lzSHXF"),this.doIOSWidgetFix)},setAutoHeightRegion:function(e){this.autoHeightRegion=e},doAutoHeight:function(){function n(e){var t=i.$el.find(e);t.length&&t.toolbar().toolbar(S(":NLY_K%\x11#$!\x15'#, $,"))}var i=this;setTimeout(function(){t.mobile.resetActivePageHeight(),n(S("C\x1f!'3)d) *`: ?=02&\b")),n(S("5mSYM[\x16NRRZ}c$,+1#5j\x14"));var r=i.regionManager.get(i.autoHeightRegion);if(r&&r.currentView){var o=i.calculateMinHeight();e.forEach(i.regionManager.without(r),function(e){var t=e.$el.outerHeight();o-=t}),r.$el.css({"min-height":o+S("\x1cmf")}),r.currentView.trigger(S("C)$>.% 0."),{height:o})}},10)},calculateMinHeight:function(){var e=parseInt(getComputedStyle(this.el).getPropertyValue(S("\x1fP@FGMKA\n\\FZ"))),t=parseInt(getComputedStyle(this.el).getPropertyValue(S("\x19jzxywqG\f@LPQIJ"))),n=parseInt(getComputedStyle(this.el).getPropertyValue(S("\foa}tt`>`zf:op~ot"))),i=parseInt(getComputedStyle(this.el).getPropertyValue(S("2Q[GRRJ\x14XTHIQRm6+'0-")));return window.innerHeight-e-t-n-i}})}),CKFinder.define(S('@\x02\t\x05-+"":f\x07$(8"*#~\x02230%x\b8=>/'),[S("\x0fe\x7fvvffuxj|"),S("?*07&6<"),S("\x1fcjdJJACU\x07dEOYAK\\\x1faSTQF\x19aQ\\MH\x13m_X%\r#:+02")],function(e,t,n){"use strict";function i(e){this.finder=e,this.pages={},this.pageStack=[],this.started=!1}var r=50,o=S('2\tYZT^T\\\x17K]Z[\\//6"-+#5');return i.prototype={getHandlers:function(){var e=this;return t(S("(KEOU")).on(S("3DTQR[VTO]TPZ2#'%+7#/!-/"),function(n,i){var r=i.prevPage&&!!i.prevPage.length&&t(i.prevPage[0]).data(S("3W^PgY^_"));r&&(e.finder.fire(S("!RBC@\x1cOAMO"),{page:r},e.finder),e.finder.fire(S("%VFOL\x10CEIK\x15")+r,e.finder))}).on(S("?0 %&'*(3) $.>>& '"),function(n,i){var r=t(i.toPage[0]).data(S("\fnei@puv"));e.currentPage=r,e.finder.fire(S("\x16gy~\x7f!ouqh\x1a")+r,e.finder),e.finder.fire(S("\r~nwt(`|za"),{page:r},e.finder)}),{"page:current":{callback:this.pageCurrentHandler,context:this},"page:create":{callback:this.pageCreateHandler,context:this},"page:show":{callback:this.pageShowHandler,context:this},"page:hide":{callback:this.pageHideHandler,context:this},"page:destroy":{callback:this.pageDestroyHandler,context:this},"page:addRegion":{callback:this.pageAddRegionHandler,context:this},"page:showInRegion":{callback:this.pageShowInRegionHandler,context:this}}},setFinder:function(e){this.finder=e},pageCurrentHandler:function(){return this.getCurrentPage()},pageDestroyHandler:function(e){function n(){s&&(s.destroy(),r.fire(S("\x11brsp,s}jnisd"),{page:e.name},r),r.fire(S("\n{mjk5ttagfzo-")+e.name,null,r),delete i.pages[e.name])}var i,r,s,a,l;i=this,r=this.finder,s=this.getPage(e.name),e.name===this.getCurrentPage()?(t(o).one(S("\x0f`puvwzxcypt~nnvpW"),n),l=this.popPrevPage(),a=this.getPage(l),a&&this.showPage(a)):n()},pageHideHandler:function(e){var t,n;e.name===this.getCurrentPage()&&(t=this.popPrevPage(),n=this.getPage(t),this.showPage(n))},pageCreateHandler:function(i){var r=e.extend({},i.uiOptions),o=this,s=i.name;if(!this.pages[s]){var a=new n({finder:this.finder,name:s,attributes:e.extend({},n.prototype.attributes,{"data-ckf-page":s}),className:n.prototype.className+(i.className?" "+i.className:"")});i.mainRegionAutoHeight&&a.setAutoHeightRegion(S("\x1erAHL")),this.pages[s]=a,a.render(),a.$el.attr(S("*OMYO\x02DYW^Q"),this.finder.config.swatch),a.$el.appendTo(S("B!+!?")),this.started||(r.create=function(){t.mobile.initializePage(),o.started=!0}),a.$el.page(r),i.view&&a.main.show(i.view),this.finder.fire(S("\x18i{|y'}mE@VF\x1e")+i.name,{},this.finder)}},pageShowHandler:function(e){var t=this.getPage(e.name);if(t){var n=this.getCurrentPage();n&&n!==e.name&&(this.pageStack.push(n),this.finder.fire(S("6GY^_\x01TTZZz")+n,null,this.finder)),this.showPage(t)}},pageAddRegionHandler:function(e){var t=this.getPage(e.page);return!!t&&(t.createRegion({name:e.name,id:e.id,priority:e.priority?e.priority:r,className:e.className}),!0)},pageShowInRegionHandler:function(e){var t=this.getPage(e.page);t[e.region].show(e.view),t[e.region].$el.trigger(S("C'7#&<,"))},showPage:function(e){t(o).pagecontainer(S("%EOIGMN"),e.$el),this.currentPage=e.attributes[S(':_]I_\x12#*$n4$!"')],e.$el.trigger(S(" BPFEQC")).trigger(S("\x1fUQFBP@JFQF__"))},getCurrentPage:function(){return this.currentPage},getPage:function(e){return this.pages[e]},popPrevPage:function(){for(;this.pageStack.length;){var e=this.pageStack.pop();if(this.getPage(e))return e}return this.pageStack=[],!1}},i}),CKFinder.define(S(">K%96b\x07\x0e\0.&-/9c\x19+\" =3'1&y\x0797?7/r\x0e>\x0e\x04\x0e/\x05\x1c\t\x12\x1cG\x0e\x04\x18"),[],function(){return S("#_^\x19\x07A]\x04H@B]JrDFG[[\x16JE3\x06_UK\x1eM/-'~f'')&,8il)/;1| <80ku0<;?9/|\x7f\x03\r\x03\x10\x17XD\x04\x03\x0fG\x1f\x03\x02\x02\r\x11\x03_\x1a\0\x10\x1b\x04ZGpr@\x1f\v\vtnl#`drf%jam!\x7facu,0pxzerHxt~p?>{AUC\x0eMFII\x15\vI@J\0MN^RW_\x16\x15RVLX\x17R_RPO/2\x7fa**2\"0=hk8$:#5lp(/hv>,w6:2:p<\x0f\f\x0f\f\nK\x05\v\x07\x1a\x0fK\x11\x10LQ\v\nOS\x1d\x01X\x1b\x19\x17\x1dU\x1f\x12\x13\x12oo,`hjub(tw7#o{{d~|-\x1e)9sqo$\x11gf!b]+\x1eGMS\x06DDHYX\x11\x0fMDV\x1cBRZPZ\x1a[VTOYSJLb\x7f~l ,0yB")}),CKFinder.define(S(" bieMKBBZ\x06gDHXBJC\x1ebRZPZD\x17oS^KN\x11o!/'/\x12,#0"),[S(")i`jD@KUC\x1df@\\Z\x18s\\CxSY["),S("/sztZZQSE\x17oS^KN\x11}!2'l\b$?(==\x1c\"):"),S('(]OSX\fmdvX\\WQG\x19c]TJW]I[Lo\x11#-!)5h\x18($. \x01/6?$&}0:"')],function(e,t,n){"use strict";var i=t.extend({name:S("1bRZPZ{Y@UNH"),template:n,regions:{contents:S("$\vELN\x04ZJBHB\x02S^\\GQ[BD")},events:{'click [data-ckf-role="closePanel"]':function(){this.hide()},'keydown [data-ckf-role="closePanel"]':function(t){t.keyCode!==e.enter&&t.keyCode!==e.space||this.hide()},panelclose:function(){this.trigger(S("6TTVI^X")),this.$el.attr(S("5WEQX\x17SUYZZ."),S("\x12gf`s")),this._isOpen=!1},panelopen:function(){this.trigger(S("*D\\H@JT")),this.$el.removeAttr(S("6VJP[\x16TTZ[%/")),this._isOpen=!0},keydown:function(t){t.keyCode===e.escape&&(t.stopPropagation(),this.hide())}},templateHelpers:function(){return{closeButton:!!this.options.closeButton}},initialize:function(e){function t(){var t=this.$el.find(S("\x10?gz9ewy}u7rrs{m"));if(t.length){var n=getComputedStyle(t[0]).getPropertyValue(S("\x13dtrsqw}6hrn")),i=0;if(e.closeButton){var r=this.$el.find(S("2hPTBV\x15KUWY\0\x1cW% &&6g\x1b"));r.length&&(i=r.outerHeight())}this.contents.$el.css({height:this.$el.height()-parseInt(n)-i+S("\f}v"),overflow:S("0PGG[")})}}this._isOpen=!1,this.$el.attr(S(':_]I_\x12#*$n4$("$'),e.name).attr(S("+HLZN\x1dA]@]A_XV"),e.position).attr(S("\x14qwcy4nsyp{"),this.finder.config.swatch).attr(S("1SA]T\x1b_Q]^^R"),S("8MHNY")).attr(S("$AGSI\x04NB_]BNI"),e.display).addClass(S("!AHB\bVFFLF\x06")+e.position);var n=this;e.overrideWidth&&(this.$el.css({width:e.overrideWidth}),this.$el.on(S("\x1eoAOGOF@@HZLE[IC"),function(){n.$el.css({width:e.overrideWidth})}),e.display===S("?/7'1($?")&&(this.$el.on(S("\x15fvv|vyy{qmEBNLW@"),function(){n.$el.css(e.position===S("\x13xppc")?{left:0,transform:S("\fy|n~b~r`p%s04")+n.finder.config.secondaryPanelWidth+S("&\v\b\x19\x06\v\x1c\x04")}:{right:0,transform:S("\x12gftxdtxn~/y6")+n.finder.config.secondaryPanelWidth+S("\x0e#0!>3$<")})}),this.$el.on(S('C4$("$*&$?('),function(){n.$el.css(e.position===S(".CUWF")?{left:"",transform:""}:{right:"",transform:""})}))),e.scrollContent&&(this.contents.on(S("\x1cnvpW"),t,this),this.finder.on(S("1F\\[YTVJ\x03YIY\\JZ"),t,this),this.finder.on(S(")^DCALNB\vVVGADXA"),t,this),this.finder.on(S("6BQ\x03H^OTDZ"),t,this),this.on(S("$ACT\\[ER"),function(){this.finder.removeListener(S("7LVUW^\\L\x05#3'\"0 "),t),this.finder.removeListener(S('=JP/- "6\x7f"";=8$5'),t),this.finder.removeListener(S("5C^\x02K_HUG["),t)},this))},display:function(){this.$el.panel(S("\x0f\x7faw}"))},toggle:function(){this.$el.panel(S("\x16cw~}wy"))},hide:function(){this.$el.panel().panel(S("\x11q\x7f{fs"))},isOpen:function(){return this._isOpen}});return i}),CKFinder.define(S('B\0\x0f\x03/),,8d\x01"*:<4!|\x044824*u\v=3;3\x13'),[S("']GNN^^M@BT"),S("8SKNYOG"),S("/sztZZQSE\x17oS^KN\x11}!2'l\r1#*\x1e /<"),S("!ahbLHCM[\x05}EHY\\\x1fsS@Q\x1azVAVOOjT[H"),S("\x14V]Qqw~~n2SpDTNFW\nvFFLFX\x03{GJGB\x1dcU[S[nP_L"),S("8zq}USZZ2n\x177-)i\f-0\t$((")],function(e,t,n,i,r,o){"use strict";function s(){this.panels={},this.opened=null}return s.prototype={getHandlers:function(){return{"panel:create":{callback:this.panelCreateHandler,context:this},"panel:open":{callback:this.panelOpenHandler,context:this},"panel:close":{callback:this.panelCloseHandler,context:this},"panel:toggle":{callback:this.panelToggleHandler,context:this},"panel:destroy":{callback:this.panelDestroyHandler,context:this}}},setFinder:function(e){this.finder=e,e.request(S("!IF]\x1fJN[]OE"),{key:o.escape}),e.on(S("\x0f{tkfd/")+o.escape,function(e){e.data.evt.stopPropagation()},null,null,30),e.on(S(">J){14-5#+-/>"),function(e){this.onSwipe(S(":WY[J"),e)},this,null,10),e.on(S('E3.r:="<(<&79&'),function(e){this.onSwipe(S("\x12a}r~c"),e)},this,null,10)},panelCreateHandler:function(e){var t,n=this.finder,i=S(e.position===S("\f}|f}p`j")?n.lang.dir===S("\x1fLUP")?"%JBN]":";NTYW4":n.lang.dir===S("\x0ecdc")?"=LV')6":"D)#!<"),o=e.position===S("%VUADKYU")?n.config.primaryPanelWidth:n.config.secondaryPanelWidth,s={finder:n,position:i,closeButton:e.closeButton,name:e.name,scrollContent:!!e.scrollContent,overrideWidth:o,display:e.panelOptions&&e.panelOptions.display?e.panelOptions.display:S("$JPBZEKR")};e.scrollContent&&(t=S("3W^P\x1aHXT^P\x10M\\2../%'*\"")),e.className&&(t=(t?t+" ":"")+e.className),t&&(s.className=t);var a=new r(s);return a.on(S("!AOKVCC"),function(){n.fire(S("\x19jzrxr%CMMPA\x1f")+e.name,null,n),this.opened=null},this),a.on(S("\x1crnzNDF"),function(){n.fire(S(",]OAU]\b\\DPX\r")+e.name,null,n),this.opened=e.name},this),a.render(),a.$el.appendTo(S('C&*">')).panel(e.panelOptions||{}).trigger(S("\x15ue}xn~")),a.contents.show(e.view),a.on(S("\x1fDDQWVJ_"),function(){n.fire(S("1BRZPZ\r\\\\IONRG\x05")+e.name,null,n),delete a[e.name]}),this.panels[e.name]=a,this.finder.request(S("\x16qwzoh&il~P"),{node:a.$el}),a},panelOpenHandler:function(e){var t=this.panels[e.name];t&&t.display()},panelToggleHandler:function(e){this.panels[e.name]&&this.panels[e.name].toggle()},panelCloseHandler:function(e){ +this.panels[e.name]&&this.panels[e.name].hide()},panelDestroyHandler:function(e){this.panels[e.name]&&(this.panels[e.name].hide(),this.panels[e.name].destroy(),delete this.panels[e.name])},onSwipe:function(e,t){var n=this.panels[this.opened];n&&n.getOption(S("!RLWLRNGG"))===e&&(t.cancel(),n.hide())}},s}),CKFinder.define(S('\x13`pnc9ZQ]uszzR\x0evFIUJF\\LY\x04jDBJC\x1etZXPxVU\\~R]QQX\x14$/3($2"f-%?'),[],function(){return S("=\x02Y/3/c%&2.''wioopEYm>260:iRPS '|~6\x14O\x06\n\x05\t\t\0%\f\x19\x18\r\n\vO\r\fxz}I\x1f\x19\b\f\x0e[\b\x1c\x1c\x16neg{9'7%(gkfi0,aufTzxpXvu|8;j|rjE\x1c\0X_\x04\x06N\\\x07LB@H`N]T\x12NI\x17\x16VJP[\x16NXOJ)3''yg25=,hk($6\x1a4;2\x1c0;73:\b6\x05\x16'),[S(":xw{WQ$$0l\x12,#0;f\b*?(a\x06$4?\x05=0!"),S("(jamECJJB\x1e\x7f\\PPZD\x17\x7fSWY"),S(">K%96b\x07\x0e\0.&-/9c\x19+\" =3'1&y\x1115?(s\x1b73\x05/\x03\x0e\x01!\x0f\x06\x04\x06\r?\t\0\x1e\x03\x11\x05\x17]\x10\x1a\x02")],function(e,t,n){"use strict";return e.extend({name:S("9|RPXp^-$\x06*%)) \x1e /<"),template:n,ui:{error:S(":\x15YOLP2l/&76' -"),fileName:S('"JJUSSsGKFI\x10\fAUFtZXPxVU\\\x18f')},events:{"input @ui.fileName":function(){var e=this.ui.fileName.val().toString();if(e=t.trimFileName(e),!e.length)return void this.model.set(S("\fh|}\x7fc"),this.finder.lang.errors.fileNameNotEmpty);if(!t.isValidName(e)){var n=this.finder.lang.errors.fileInvalidCharacters.replace(S("&\\L@YJ@AAXUUq[UGWTL\\HHA"),t.invalidCharacters);return void this.model.set(S("\x1d{mRNP"),n)}this.model.unset(S("\x13qgdxj"));var i=t.extensionFromFileName(this.model.get(S("\x15yeq~su}qXvLDlBI@"))).toLowerCase(),r=t.extensionFromFileName(e).toLowerCase();if(i!==r){var o=this.model.get(S("$WCTG\\XHIyW_U"));if(!o.isAllowedExtension(r))return void this.model.set(S('"FVWIU'),this.finder.lang.errors.incorrectExtension);this.model.set(S("\x14pnc}wirss]wAOEF@"),!0)}else this.model.set(S("2VLASYKPUU\x7fU_Q'$&"),!1);this.model.set(S("\x1eyIMGmEHC"),e)},submit:function(e){this.trigger(S(">L5#/*0\x7f (:$")),e.preventDefault()}},modelEvents:{"change:error":function(e,t){t?(this.ui.fileName.attr(S("A#1-$k.&?+'%)"),S("\x1djmUD")),this.ui.error.show().removeAttr(S('"BVLG\n@@NOIC')).html(t)):(this.ui.error.hide().attr(S(",L\\FQ\x1cZZPQSY"),S("0E@FQ")),this.ui.fileName.removeAttr(S("'I[CJ\x01D@YQ][W")))}}})}),CKFinder.define(S("\x14V]Qqw~~n2SpDTNFW\ntBFHGNjDBJ\x1fcW]UXSqQU_"),[S("\x19xz\x7fv|pND"),S("\x18ZQ]uszzR\x0eoL@@JT\x07oCGI"),S("E\x05\f\x0e $/)?a\x1a$8>|\x1f0/\x147=?"),S("\x14V]Qqw~~n2SpDTNFW\n`NDLY\x04zDKXC\x1etZXPxVU\\~R]QQX\x16('4")],function(e,t,n,i){"use strict";function r(e){this.finder=e,e.setHandler(S("@'+/!\x7f4\"&('."),s,this),e.on(S("?#.,7!=2\n-'?q*$\"*j46: "),o,this,null,50),e.on(S("\x1c{wsE\x1bIF]AIPF"),function(t){t.data.evt.keyCode===n.f2&&e.request(S(':]UQ[\x052$,") '),{file:t.data.file})}),e.on(S("4AYXT[[I\x06O[L%5x\x0e%,(}. &."),function(e){e.data.file.get(S("\x17~vv\x7fyo")).get(S("E'$$")).fileRename&&e.data.toolbar.push({name:S("+~H@N]TtZXP"),type:S("\x15tblmuu"),priority:30,icon:S('?#*$n",*"e;/%- +'),label:e.finder.lang.common.rename,action:function(){e.finder.request(S(">Y)-'y6 (&%,"),{file:e.finder.request(S("*MEAK\\\nVWGgPZR[M__")).toArray()[0]})}})}),e.on(S("\x1e{I@NLC\x1ftBFHGNjDBJ\n^Y"),function(t){var n=t.data.view.model;if(!n.get(S(",H\\]_C"))){var i=t.data.context.file,r=n.get(S("*MEAKaQ\\W")),o=i.get(S("\x10\x7fs~q")),s={file:i,newFileName:r};t.finder.request(S("\x16sqxvt{'zzSUPL]")),n.get(S("\x14pnc}wirss]wAOEF@"))?e.request(S("=ZV!--$~&)). 8&"),{name:S("8K_U]P[y)-'\0++ .:$"),msg:e.lang.files.fileRenameExtensionConfirmation,context:s}):r!==o&&a(s,e)}}),e.on(S("\x14q\x7fvtv}!nxp~MDdJH@eHFOCYA\x17AD"),function(t){a(t.data.context,e)}),l(e)}function o(e){var t=this,n=e.data.context.file,i=n.get(S("\x19|tpy{m")).get(S("=_\\,"));e.data.items.add({name:S("({OEM@KiY]W"),label:t.finder.lang.common.rename,isActive:i.fileRename,icon:S("/SZT\x1eR\\ZR\x15K_U]P["),action:function(){t.finder.request(S(")LB@H\x14]U_S^Q"),{file:n})}})}function s(t){var n=this.finder,r=n.lang,o=t.file.get(S(" GMO@@T"));if(!o.get(S("+MNB")).fileRename)return void n.request(S("\x13p|w{w~ rr{q"),{msg:n.lang.errors.renameFilePermissions});var s=new e.Model({dialogMessage:n.lang.files.fileRenameLabel,fileName:t.file.get(S("\x1au}p{")).trim(),originalFileName:t.file.get(S("\fcobu")),resourceType:o.getResourceType(),extensionChanged:!1,error:!1}),a=n.request(S("D!/&$&-"),{view:new i({finder:n,model:s}),name:S("7j\\TZQXxV,$"),title:r.common.rename,context:{file:t.file}});s.on(S("\x10rzrzrs-}khtn"),function(e,t){t?a.disableButton(S("5Y\\")):a.enableButton(S("6XS"))})}function a(e,t){var n=e.file,i=n.get(S("%@HDMOY")),r={fileName:n.get(S("\x1cs\x7frE")),newFileName:e.newFileName};t.request(S(";PR_[%3x0,*1"),{text:t.lang.common.pleaseWait}),t.once(S(",NAB]P\\W\x0eTPC]K\0iYS_R%\x07+/!"),function(e){t.request(S("E*()-/9v%'+5"));var i=e.data.response;i.error||n.set(S(",COBU"),i.newName);var r=t.request(S("&AAEOX\x16JK[sD@AQ[B")).where({name:i.newName}).pop();r&&r.trigger(S("0W]PAF"),r)}),t.request(S(" BMNIDHC\x12ZOEH"),{name:S("\x12Aq{wz}_swy"),folder:i,params:r,type:S("\x14eydl")})}function l(e){e.on(S("4S_[]\x03Q^EYQH."),function(t){t.data.evt.keyCode===n.f2&&e.request(S(':]UQ[\x052$,") '),{file:t.data.file})}),e.on(S("\x10bz|faublj wunj%FHNFW"),function(e){e.data.shortcuts.add({label:e.finder.lang.shortcuts.files.rename,shortcuts:S("-UI\x02L")})},null,null,20)}return r}),CKFinder.define(S("\x14V]Qqw~~n2SpDTNFW\niWM[K_EB@\0\x7fAWAUA_XV"),[],function(){"use strict";function e(e){this.finder=e,this.id=e.util.randomString(16)}var t=3e3;return e.prototype.getId=function(){return this.id},e.prototype.trackProgress=function(e){var n=this,i=!0;this.probingInterval=setInterval(function(){i&&(i=!1,n.finder.request(S(",NAB]P\\W\x0eFSY\\"),{name:S("%iWM[K_EB@"),params:{operationId:n.id}}).done(function(t){i=!0,e&&e(t)}))},t)},e.prototype.abort=function(){this.finish(),this.finder.request(S("/S^_^U[R\rK\\T_"),{name:S("\x0f_awaua\x7fxv"),params:{operationId:this.id,abort:!0}})},e.prototype.finish=function(){this.probingInterval&&(clearInterval(this.probingInterval),this.probingInterval=null)},e}),CKFinder.define(S("=}t\x06(,'!7i\n'-?')>a\x1d5?3>1\x139;<<(t\x0e80>\r\x04$\f\b\x01\x03\x15"),[S(';^\\]T".,&'),S('9ypzTP[%3m\x0e+!3+-:e\r#!**""}\x05=0!$w\x1f5788,\x11\x01\f\x07\'\r\x04\n\b\x0f?\x03\x0e\x1b'),S("*hgkGATT@\x1caA_[\x17r_B\x7fRZZ"),S("2p\x7fs_Y\\\\H\x14qRZJ,$1l\v5#5)=#$\"b\x01?5#3'=:8"),S("\x10RYU}{rrj6Ytqpqq\x0flMGAIU\bx[EL^H]\\}^VVX"),S("\x1aXW[wqDDP\fgJKJGG\x05}EHY\\\x1fa@\\SGSDKoS^K")],function(e,t,n,i,r,o){"use strict";function s(n){n.setHandler(S("$CIKLLX\x11^H@N]T"),function(s){var a=s.folder,u=s.newFolderName;if(u){var c=a.getResourceType(),d={type:a.get(S(",_K\\_D@PQaOG]")),currentFolder:a.getPath(),newFolderName:u};if(c.isOperationTracked(S("%tBFHGNjBBKUC"))){var f=new i(n);d.operationId=f.getId();var h=new r({message:n.lang.common.pleaseWait}),g=new o({finder:n,model:h});n.request(S("\vhdoc\x7fv"),{view:g,title:n.lang.common.rename,name:S(".}U_S^QsY[\\\\HkNRYM%21"),buttons:[{name:S('B"&*43'),label:n.lang.common.abort}]});var p=function(){f.abort(),n.request(S('\x11vzuyyp"}\x7fhhoqf'))};n.on(S("\x17|p{wsz$MEOCNAcIKLLX{^BI]UBA\tUWYEL"),p),f.trackProgress(function(e){e.current&&e.total&&h.set(S("/FP^FQ"),e.current/e.total*100)}),n.once(S("\x17{vwv}sz%OJ\x18qAKGJMoEGHH\\"),function(){h.set(S("\x17nxvny"),100),setTimeout(function(){n.request(S(")NBMAAH\nUW@@GYN"))},l)}),n.once(S('@"-.)$(#r(,?)?t\x1d5?3>1\x139;<<('),function(){f.finish(),n.removeListener(S("$AOFDFM\x11~H@N]Tt\\XQSEhKU\\NXMLz ,61"),p)})}else n.request(S("\x12\x7f{trrj#issj"),{text:n.lang.common.pleaseWait});n.request(S("\x15uxut{ux'mzNE"),{name:S('D\x17#))$/\r#!**"'),type:S("\x12c{fb"),params:d,context:{folder:a,newFolderName:u}})}else{var v=new e.Model({dialogMessage:n.lang.folderRename,folderName:a.get(S("\x1fN@OF")).trim(),error:!1}),m=n.request(S("\x19~r}qqx"),{view:new t({finder:n,model:v}),name:S("\x15Drvxw~Zrr{ES"),title:n.lang.common.rename,context:{folder:a}});v.on(S("\x0fsys}sp,rjkui"),function(e,t){t?m.disableButton(S("@.)")):m.enableButton(S("-AD"))})}}),n.on(S("*OELB@W\v`VZT[R~VV_YO\x04P+"),function(e){var t=e.data.view.model;if(!t.get(S("$@TUG["))){var i=t.get(S(';ZRR[%3\f") '));e.finder.request(S("+HDOC_V\bWQFBEW@")),n.request(S(">Y/-&&6\x7f4\"&('."),{folder:e.data.context.folder,newFolderName:i})}}),n.on(S("\x19ytqp\x7fqD\x1bCEP@T\x1dzLDJAHh@\\UWA"),function(e){n.request(S("1^\\UQSE\x02QS_Y"));var t=e.data.response;if(!t.error&&!t.aborted){var i=e.data.context.folder;i.set(S("\x1dp~MD"),e.data.context.newFolderName),n.fire(S("&AGENN^\x17]J\\TQGQQ"),{folder:i},n),i.trigger(S("#W@JBK]OO"),i)}}),n.on(S("\x0el\x7f\x7ffvla[rvl }sqzzR\x1bGGMQ"),function(e){var t=e.finder,n=e.data.context.folder,i=n.get(S('"JWwIH\\')),r=n.get(S("A# ("));e.data.items.add({name:S('"qAKGJMoEGHH\\'),label:t.lang.common.rename,isActive:!i&&r.folderRename,icon:S("2P_S\x1bQWU^^N\x10LZ. /&"),action:function(){t.request(S("0W]_PPD\rJ\\TZQX"),{folder:n})}})}),n.on(S("?4.-/&$4}:,9.8w\x03.9?h5;922*"),function(e){var t=e.data.folder;!t.get(S("B*7\x17)(<"))&&t.get(S("\flmc")).folderRename&&e.data.toolbar.push({name:S("B\x11!+'*-\x0f%'((<"),type:S("\x15tblmuu"),priority:30,label:e.finder.lang.common.rename,icon:S("-MDV\x1cT\\XQSE\x15K_U]P["),action:function(){n.request(S(':]SQZZ2{0&*$+"'),{folder:t})}})}),a(n)}function a(e){e.on(S("0W]_PPD\rS\\C_SJP"),function(t){t.data.folder.get(S("D,5\x15'&>"))||t.data.evt.keyCode===n.f2&&t.finder.util.isShortcut(t.data.evt,"")&&(t.data.evt.preventDefault(),t.data.evt.stopPropagation(),e.request(S("3RZZS]K\0IYS_R%"),{folder:t.data.folder}))}),e.on(S("6DPVHO_HJLz-+00\x7f ($-/9?"),function(e){e.data.shortcuts.add({label:e.finder.lang.common.rename,shortcuts:S("\x17c\x7f(f")})},null,null,20)}var l=1e3;return s}),CKFinder.define(S("D\x06\r\x01!'..>b\x03 4$>6'z\x10>4-?)\x1a42:\x13N$\n\b\x11\x03\x15.\0\x06\x0e\x1f"),[S("8]Uo"),S("?- 0*++#3<,"),S("\x13W^P~v}\x7fi3HjvL\x0eiF]fICM")],function(e,t,n){"use strict";function i(i){var o="",s={"input input":function(){var e=this.$el.find(S("9SULHJ")).val();o!==e&&i.request(S("?&(.&7\x7f .$=/9"),{text:e}),o=e},"keydown input":function(e){e.keyCode===n.tab&&(i.util.isShortcut(e,"")||i.util.isShortcut(e,S("\x1dmwIGV")))&&i.request(S(i.util.isShortcut(e,"")?";ZR]J3{,&<1":'"EKFST\x12YXNZ'),{node:this.$el.find(S("\x1fIORVP")),event:e}),e.stopPropagation()}};r()&&(s[S("2XQLCG\x18PTKII")]=function(e){e.keyCode!==n.backspace&&e.keyCode!==n.delete||this.$el.find(S("3][FBL")).trigger(S("\x1evNQWW"))}),i.on(S("#PJIKJHX\x11^H]JD\v\x7fR][\fQWU^^N"),function(n){n.data.toolbar.push({name:S(">y)-6&6"),type:S("1QFGAYZ"),priority:50,alignment:S("\x1dmzCNLGEW_"),alwaysVisible:!0,view:t.ItemView.extend({className:S("\x15u|~4|rpxm2FHNWAW"),template:e.template(S("6\vQWJNH\x1dJF0$\x7fa0 >3ji)'->=rr295y!984;;)q4*:\rL\x04\f\x07\x10\x15\x06\n\x05\x0fIL\x19\x0f\r\x19\x1f\x16\x16\fHTFH[Z\v\x10\x1c\x1d\x1ahnngaw;%sr7+ey \x7f|pqv|zzs}k:fa?>iAMWF\x19\x07]\\\x15\tC_\x02[OCET\x12NI\x17\x16SYM[\x16LO[I%/6n\"*%2;d0$# sm$#'6vk")),events:s}),placeholder:i.lang.files.filterPlaceholder,value:o})}),i.on(S(" GMO@@T\x1d[LFNOYKK"),function(){o=""},null,null,5)}function r(){var e,t,n=-1;return navigator.appName==S("\x18TsxnrmpFU\x02jJQCUFL^\viU^C_CWA")&&(e=navigator.userAgent,t=new RegExp(S("8tiry\x1d\x16dpl{\x1e?tj:\x13gzfu\x105\x7f|,{")),null!==t.exec(e)&&(n=parseFloat(RegExp.$1))),9===n}return i}),CKFinder.define(S('-mdvX\\WQG\x19zW]OWYN\x11l%56**"5h\x1e /\x7fs~q5kj:\x13:;<=z~T@\x0fJGJHWGZ\x17\tWV\x11\x0fYE\x1c_U[Q\x19\\PH\x1b\x01\0\x1e\x18,50d98*".=10sr32"85; .-h%$x{\'&a\x7f\t\x15L\x15\x05\t\x13\x02H\x14\x17\b\x04\b\r\x04\x15\x15OQ\x17\x1d\x13\x14\x13\x1c\x1eY\x07\x06A\x02}?yx9%os&ekiia.rm-=\x7fuws{&\x13')}),CKFinder.define(S("\nHGKgatt`c,84186:.'),ui:{checkbox:S("\x1busnjT")},events:{"change input":function(){this._isExt=!0,this.model.set(S("%PFD\\O"),!!(this.ui.checkbox.is(S(")\x10HDHMDUU"))?1:0)),this._isExt=!1},"keyup input":function(e){e.keyCode!==n.enter&&e.keyCode!==n.space||(e.preventDefault(),e.stopPropagation(),this.ui.checkbox.prop(S("\x13w}sts|~"),!this.ui.checkbox.is(S("\x1d$|HDAHAA"))).checkboxradio(S("2AQSDRKQ")).trigger(S("*HDL@HU")))},checkboxradiocreate:function(){this.model.get(S("#MVcIIKFNH"))||this.disable()},"mousedown label":function(){var e=this;setTimeout(function(){e._parent.fixFocus(),e.focus()},0)},"mouseup label":function(){var e=this;setTimeout(function(){e._parent.fixFocus(),e.focus()},0)},"focus input":function(e){e.stopPropagation()}},modelEvents:{"change:value":function(e,t){this._isExt||this.ui.checkbox.prop(S("7[Q_XWXZ"),t).checkboxradio(S(">M%'0&7-"))}},focus:function(){this.ui.checkbox.focus()},enable:function(){this.ui.checkbox.checkboxradio(S(",H@NR]W")).removeAttr(S("\vxllf~uwk")).removeAttr(S("<\\LV!l&*7$$+--"))},disable:function(){this.ui.checkbox.checkboxradio(S("%BN[HHGI")).attr(S("9NZ^TP[%9"),-1).attr(S("3UG_V\x15]SH]_RZ$"),!0).removeClass(S("2F]\x18PX[LI"))}});return o}),CKFinder.define(S("\x1fTDZW\x05fmaAGNN^\x02zJ]A^R@PE\x18k\\NOUSYLo\x13#'-*h#'="),[],function(){return S("A~/%'#+v21vl$:a<0068u+*dv6:>82aj\x1a\x19C\r\x11H8F\f\v\b\x04E\x07\x1b^\x10\x06\x07\x06\x1c\x14\x02\f\x1c\tU\x13\r\n\x16ooq/$csik}cdb%a\x7fdx}}Xttrt5:tliwpNwCOQ@\x0f\\\bTW!\x10D@_EE\x12]UXS\n\x1aBA\x06\x1cTJ\x11. /&d8;eh .vn65rp8&}:4;2x$' '`~0\x10\x15\v\f\n3\x07\v\x1d\fJ\x16\x11OdfPQR\x05\x15\x19\x03\x12E[\x01\0A]\x11\x0fthmmRdjrm)wv.-ut/1{g:cw{m|:&!=qoTHMMrDJRM\tWVOEKL[TV\x0e\x16V^R[R__\x1eFE\0=!nv.-hx0.u0<08N\x05\v\x11DX[GO\x05\x1e\x19K\x10\x13\x03\x15\x17\x06\b\x0fJI\n\x05\v\x13\x1c\x14\t\x05\x04?|\x7f!\x0e\f&'(}s{i0,}qu{|6+\x1c+txx~p=xpR\x1c\0X_\x18\x06N\\\x07DJAH\x0eRMJI\x0e\x14ZFCQVTm]QKZ`=zh&:?%\" \x03137?t(+kw5;991`U\x1b\x1aB\x1eM^F\x1a\x15c")}),CKFinder.define(S(':xw{WQ$$0l\t*"2$,9d\x1f(:;9?5 {\x03?2/*u\t=9706\b\x07\x14'),[S(".Z^UWAGVYE]"),S("6]IL_IE"),S("\x14V]Qqw~~n2KkIM\rhA\\eHLL"),S("=}t\x06(,'!7i\n'-?')>a\x1c5%&::2%x\x0e0?,/r\r:\x14\x15\v\r\x033\x0f\x02\x1f"),S("\x17l|bo=^UYIOFFV\nrBEYFJXH]\0cTFG][QD\x17k[_UR\x10[/5")],function(e,t,n,i,r){"use strict";var o=i.extend({name:S(",\x7fOKY^aV@A_Y_"),template:r,templateHelpers:{_:e},events:{"change input":function(e){this._isExt=!0,this.model.set(S(".YQ]GV"),t(e.currentTarget).val()),this._isExt=!1},"keyup input":function(e){e.keyCode!==n.enter&&e.keyCode!==n.space||(e.preventDefault(),e.stopPropagation(),this.$el.find(S("E/)8<>")).each(function(){t(this).prop(S("\x12p|pu|}}"),this===e.target).checkboxradio(S("\x12aqsdrkq"))}),t(e.target).trigger(S(">\\( ,$!")))},"focus input":function(e){e.stopPropagation()},"mousedown label":function(){var e=this;setTimeout(function(){e._parent.fixFocus(),e.focus()},0)},"mouseup label":function(){var e=this;setTimeout(function(){e._parent.fixFocus(),e.focus()},0)}},modelEvents:{"change:value":function(){this._isExt||(this.render(),this.$el.enhanceWithin())}},focus:function(){this.$el.find(S(":RRMKK\x1b7#/1 {e")+this.model.get(S(">I!-7&"))+S("5\x14j")).focus()},enable:function(){this.$el.find(S('"JJUSS')).each(function(){t(this).checkboxradio(S("#AKGEDL")).removeAttr(S("6CY[SUXXF")).removeAttr(S("2RF\\W\x1a\\PIZ^Q[["))})},disable:function(){this.$el.find(S("\x15\x7fyhln")).each(function(){t(this).checkboxradio(S("\x1dzvS@@OA")).attr(S('"WEGOILLR'),-1).attr(S(",L\\FQ\x1cVZGTT[]]"),!0)})}});return o}),CKFinder.define(S("\x14asol8YPZtp{ES\rwAHVKI]OX\x03~K[DX\\TG\x1aeRT\\YO\x12YQK"),[],function(){return S("!\x1eOEGCK\x16RQ\x16\fDZ\x01\\PPVX\x15KJ\x04\x16VZ^XR\x01J}1&( %3h=3;)pl;5)&qt;7:=dx '`~6\x14O\f\x02\t\0F\x1a\x15KJ\x1d\r\x01\x1b\nMS\t\bIU\x1f\x03V\x0f\x1b\x17\t\x18^\x02}#<\t\r~}'a}$T\"holx9{g:tbcjpxnhxm1OQVJKKU\v\bO_EOYG@^\x19\\RYP\x1a\x17S\\C\x12G\x1dCBJH~,41/(&i<* 8+rr*)nt>3.x$'y|&%`@\b\x16M\x12\x04\n\x12\rIWVL\x06\v\x16P\f\x0f\0\x11\x19\x13\x14\f\x1c\x1eF^\x0e\x1b\x13ebvf`'}|7tw5wv3/~p\x7fv4hk+7vjourp!*(YX\x04X\x0f\x1c\bTW!\x10\x02]J\\TQG\n?")}),CKFinder.define(S("?\x03\n\x04**!#5g\x04%/9!+<\x7f\x027' <80+v\f29*-p3\x04\x0e\x06\x07\x110\x0e\r\x1e"),[S("""*'),template:i,templateHelpers:{_:e},ui:{select:S("!QFH@ES")},events:{"change select":function(){this._isExt=!0,this.model.set(S("0GS_AP"),t(this.ui.select).val()),this._isExt=!1;var e=this;setTimeout(function(){e.focus()},10)}},modelEvents:{"change:value":function(e,t){this._isExt||(this.ui.select.val(t),this.ui.select.selectmenu(S(";NXXM%2*")))}},focus:function(){this.ui.select.focus()},enable:function(){this.ui.select.select(S("\x0ej~pp\x7fq")).removeAttr(S("1FRV\\XS]A")).removeAttr(S("$DTNI\x04NB_LLCUU")).parent().removeClass(S("8LS\x16OI_K%l&*7$$+--"))},disable:function(){this.ui.select.select(S("\rjfcpp\x7fq")).attr(S("'\\HHBBIKW"),-1).attr(S('9[IU\\\x13[)2#!( "'),!0).parent().addClass(S("9OR\x11NJ^4$o'-6'%$,."))}});return r}),CKFinder.define(S("\x10ewk`4U\\^pt\x7fyo1KELROEQCT\x07zO_XD@HC\x1efVLA\x18SWM"),[],function(){return S("'SR\x17\vEY\0CQSW_\x14HK\vQWJNH\x1dJF0$\x7fa0 >3ji$*!(sm+*os=!x994?{! |\x7f\x16\0\x0e\x16\x01XD\x1c\x13TJ\x02\x18C\x18\x0e\x1c\x04\x17S\t\bTW\x1c\x10\bF^\x1c\v\vo#<\t")}),CKFinder.define(S("9ypzTP[%3m\x0e+!3+-:e\x18)9:&>6!|\x02<3 +v\x0e>$)\b6\x05\x16"),[S("\vycjjbbq|fp"),S("?*07&6<"),S("\x0eL[W{}ppd8Uv~npxm0sDVWMKAT\x07\x7fCN[^\x01|UEFZZR`^]N"),S("8M_CH\x1c}t\x06(,'!7i\x13-$:'-9+<\x7f\x027' <80+v\x0e>$)p;\x0f\x15")],function(e,t,n,i){"use strict";var r=n.extend({tagName:S("\x1esACGO"),name:S("\x1aOyejLEUVJJB"),template:i,ui:{input:S("4\\XGMM")},events:{"change input":function(e){this._isExt=!0,this.model.set(S("0GS_AP"),t(e.currentTarget).val()),this._isExt=!1}},modelEvents:{"change:value":function(e,t){this._isExt||this.ui.input.val(t)}},focus:function(){this.$el.find(S("*BB][[")).first().focus()},enable:function(){this.ui.input.textinput(S("\x1d{qACNF")).removeAttr(S("\x1ao}\x7fwqDDZ")).removeAttr(S("A#1-$k#!:+) (*"))},disable:function(){this.ui.input.textinput(S("!FJWDDKM")).attr(S("#PDDNFMOS"),-1).attr(S('?!3+"i!/4)+&.('),!0)}});return r}),CKFinder.define(S("\x18m\x7fch<]TfHLGAW\tsMDZGMYK\\\x1fbWG@\\XPK\x16hZRZ[\x11$.6"),[],function(){return S('@}."& *g.&8vn65rp8&}:4;2x$\'yb&%b@\b\x16M\b\x04\x04\x02\x04I\x17\x16PB\x02\x0e\x12\x14\x1eM~I\x1f\x19\b\f\x0e[\b\x04\x0e\x1a=#pbjbc%(gkfi0,tk,2z`;xvu|:fa?>vD\x1c\0X_\x18\x06N\\\x07DJAH\x0eRM\x13\x12^][\v\x15CB\x07\x1bUI\x10^450*&02";g\'""m32r[[stu;6 dx \'`~6\x14O\x03\x17\x10\x17\x0f\x05\x1d\x1d\x0f\x18B\0\x0f\x17P\f\x0fQT\x06\x02\x12\bDX\0\x07@^\x16t/cwpwoe}}ox"~zj`1on65`vtl\x7f&>fe"\0HV\rRDJRM\tWV\x0e\x13$')}),CKFinder.define(S("(jamECJJB\x1e\x7f\\P@ZRK\x16i^HIWQ'2m\x15- 14g\x1b+%+(\x18&5&"),[S("\x19ouxxllCNPF"),S("\fg\x7fzuck"),S("#gn`NFMOY\x03`AKE]W@\x1bfSCLPT\\O\x12hV%61l\x17 23!'-\x1d%(9"),S("\x14asol8YPZtp{ES\rwAHVKI]OX\x03~K[DX\\TG\x1adVV^_\x15XRJ")],function(e,t,n,i){"use strict";var r=n.extend({tagName:S("\noe{"),name:S("\r\\n~vw@qab~v~"),template:i,events:{"change input":function(e){this._isExt=!0,this.model.set(S("@7#/1 "),parseFloat(t(e.currentTarget).val())),this._isExt=!1},slidecreate:function(){this.$el.find(S("Al6-h5+!-/9a%/!4=7")).attr(S("?4 **!#?"),"0"),this.model.get(S("*B_h@NR]WW"))||this.disable()}},modelEvents:{"change:value":function(e,t){this._isExt||this.$el.find(S(":RRMKK")).val(t).slider(S("\x1bnxxmERJ"))}},focus:function(){this.$el.find(S("\x1busnjT")).first().focus()},enable:function(){this.$el.find(S("?)/260")).slider(S(";YS_],$")).removeAttr(S(")^JND@KUI")).removeAttr(S("\x1d\x7fmI@\x0fGMVGEDLN"))},disable:function(){this.$el.find(S("\x0fy\x7fbf`")).slider(S("1VZGTT[]")).attr(S("'\\HHBBIKW"),-1).attr(S(";]OW^m%+0%'*\","),!0)}});return r}),CKFinder.define(S('C0 >3i\n\x01\r%#**"~\x0669%:6,<)t\x0f8*+\t\x0f\x05\x10K6\x03\x13\x1c\0\x04\f\x1f*\x1c\0\x05\x01\\\x17\x1b\x01'),[],function(){return S('Cx#/"$-9.8m:.28<71-kuuhxeVTb3\x05\x06\x07\r\0[\x1d\x1cUI\x03\x1fB\x01\x0f\r\x15\x1dR\x0e\tIY\x1b\x1d\x1e\x1f\x15\x18Ctv6!|\x02<3 +v\x1939>5=\x0f\x194\n\x01\x12"),S("\x11QXR|xs}k5VsyksER\rpAQRNFNY\x04zDKXC\x1e`RP\\YaQ\\M"),S('\x1c^UYIOFFV\nkHL\\FN_\x02}JDE[]SF\x19aQ\\MH\x13n[S%"6\x15- 1'),S("\x0eL[W{}ppd8Uv~npxm0sDVWMKAT\x07\x7fCN[^\x01{UIFe]PA"),S('8zq}USZZ2n\x0f, 0*";f\x19.89\'!7"}\x05=0!$w\v;5;8\b6\x05\x16'),S("D1#?")).get(0)&&(e.preventDefault(),e.stopPropagation(),this.fixFocus(),this.focus())}},initialize:function(e){this.collection=e.model.get(S("6D]MNRRZM"))},addChild:function(t){t.get(S("\x10ekcq"))!==S("+DDJKU_")&&e.CollectionView.prototype.addChild.apply(this,arguments)},getChildView:function(e){var t={checkbox:n,range:s,text:o,select:r,radio:i},a=e.get(S("#P\\VB"));return t[a]||(a=S("/DTJG")),t[a]},focus:function(){var e=this.children.findByModel(this.collection.filter(function(e){return e.get(S('=WL\x05/#!( "'))&&e.get(S("+XT^J"))!==S("\x10y{wppx")}).shift());e&&e.focus()},fixFocus:function(){this.$(S("\x1a5it3yOBWP")).removeClass(S("2F]\x18PX[LI"))}});return l}),CKFinder.define(S("\x0fSZTzzqse7Tu\x7fiq{l\x0frGWPLH@[\x06|BIZ]\0cTFG][QDnP_L"),[S("D\x06\r\x01!'..>b\x18&5&!|\x164%2w\x1a5708=+\t\x0e\f5\r\0\x11"),S("+ofhF^UWA\x1bxYSMU_H\x13n[K4(,$7j\x10.->9d\x1f(:;9?5 \x13'9\"(\x0f3>+")],function(e,t){"use strict";return e.extend({name:S("D\x16#3< $,?\x1b'*'"),childView:t,collectionEvents:{focus:function(){var e=this.children.findByModel(this.collection.first());e&&e.focus()}},onShow:function(){this.$el.parent().trigger(S("\x17{k\x7fzhx"))},onRender:function(){this.$el.enhanceWithin()}})}),CKFinder.define(S("7{r|RRY[Mo\f-'1)#4g\x1a/?8$ (#~\x1f<00:$w\n?/(408"),[S("&EIJAICCK")],function(e){"use strict";var t=e.Model.extend({defaults:{type:S("C0 >3"),value:"",label:""}});return t}),CKFinder.define(S("\x1aXW[wqDDP\fiJBRDLY\x04\x7fHZ[Y_U@\x1bxYS]UI\x14oXJK)/%0\x037)28"),[S("\rlnszp|zp"),S("#gn`NFMOY\x03`AKE]W@\x1bfSCLPT\\O\x12sP$$.0k\x16#3< $,")],function(e,t){"use strict";var n=e.Model.extend({defaults:{displayTitle:"",title:"",group:""},initialize:function(){var n=this,i=new(e.Collection.extend({model:t}));i.on(S("\x1fCICMC@"),function(){n.trigger(S(" BJBJBC"))}),this.set(S("\x1boxjkIOEP"),i)},getSettings:function(){var e={};return this.get(S("\x1ahyijvNFQ")).forEach(function(t){e[t.get(S(",COBU"))]=t.get(S("E0&$a\x1c5%&::2%'),[S("=KQ$$00'*4\""),S("8[[XW_QQ%"),S(".l{w[]PPD\x18uV^NPXM\x10\x13$67-+!4g\x1f#.;>a\x1c5%&::2%\x011<-"),S("\x18ZQ]uszzR\x0eoL@PJB[\x06yNXYGAWB\x1d~[QS[K\x16i^HIWQ'2\x117+7' -"),S("4v}qQW^^N\x12sP$4.&7j\x15\"<=#%+>a\x02?57?'z\x10>4-?)99\r:\x14\x15\v\r\x03\x16")],function(e,t,n,i,r){"use strict";function o(e){var t,n,i;for(i="",t=S(">\x0errvvrr~~\t\v\t\x0f\t\v\t\x07\x1a\x1a\x1e\x1e\x1a\x05\x07\x05\v\r\x0f\r\v\x05\x07\x05"),n=0;ne&&(e=f(4)-f(0)+33),a=e<4}(),i||(m.add({label:t.label,group:t.group}),i=g(t.group)),function(){function e(e,n,i,r,o,s){for(var a=window[t.s(S("\x16Sxo|"))],l=33,u=i,c=r,d=o,f=s,c=l+(u*f-c*d)%l,d=u=0;d>>0))*c+u*i%33*d)%l-1>=12*(f[t.s(S("\x18~~mYlwu~LJ["))]()%2e3)+f[t.s(S("\x18~~mRvumO"))]()}var t={s:function(e){for(var t="",n=0;ne&&(e=f(5)-f(1)+33),l=e-1<=0}(),function(){function e(e,t){var n=e-t;return 0>n&&(n=e-t+33),n}function t(e,t,n){var i=window.opener?window.opener:window.top,r=0,o=i[S(" MM@EQOHF")][S(";TRMK. /&")].toLocaleLowerCase();if(0===t){var s=S(">a765\x1fj");o=o.replace(new RegExp(s),"")}if(1===t&&(o=("."+o.replace(new RegExp(S("3jBA@d\x17")),"")).search(new RegExp(S("\x16K6")+n+"$"))>=0&&n),2===t)return!0;for(var a=0;a>>0)}d=t(f(7),e(f(4),f(0)),s.config.initConfigInfo.s)}(),e.forEach(t.settings,function(i){var o,s;i=e.extend({},{isEnabled:!0},i),s=r.findWhere({name:i.name}),s&&m.remove(s),m.hasValueInStorage(t.group,i.name)?i.value=m.getValueFromStorage(t.group,i.name):i.value=i.defaultValue,o=r.add(i),o.on(S("/SYS]SP\fAYUO^"),n)}),function(){function e(e,t){for(var n=0,i=0;i<10;i++)n+=e.charCodeAt(i);for(;n>33;){var r=n.toString().split("");n=0;for(var o=0;ol)return!0;if(0===t||e.get(S("D6.(:=)>8>")).length+t<=l)return!1;var i=(2-u)*l,r=n.indexOf(e),s=n.reduce(function(e,t,n){return n=s}var o=new t.Collection;e.forEach(i,function(e){o.add({column:e,groups:new t.Collection,size:0})});var s=n.reduce(function(e,t){return e+t.get(S("2@\\ZDC[LNH")).length},0),a=o.length,l=Math.ceil(s/a),u=0,c=s;return n.forEach(function(e){u6*j_")}),CKFinder.define(S("2GQMB\x16{r|RRY[Mo\x15'.4)'3-:e\x18$\"<;3$& {\x06>8*-9.(s:0\x14"),[],function(){return S("-\x12[T\x11Q_UFE\n\x1aZQ]\x11NVP25!606k,-09irG54.q;'z&>8*-9.(.d;\x05\x07\v\r\r\x11\x0f\b\x06I\x17\x16fdR\x1c\0\x10\x1cS\x17\x19\x17\x04\vDX\x18\x17\x1bS\fhnpwgprt%zbd~ymzd1gz9wwe5ptsyowk\x02\x1f(*_^X\x07LLLBBDZF__\bXQL\f^\x18DG@G\x02\x1eV`\x7fbsd8;a&+9;wfh!2\"\"h/.i*%e198cTV\x1b\x1a]C\r\x11H\f\r\x10\x190L\x06\v\x16P,R\x0e\t\x7f\x7f~D\n\n\x1a\x12]\x1d\x13arq>&fma%zbd~ymzdb?aqtrrj4uupdk10r`#!3=j__^d**:2},0\f\x04_A\x14\x17\x03\x14\r\x07\x1e\n\x18\x04\x01\x01RQ\x13\x01\x1d\x14[\x1f\x11\x1d\x1e\x1e\x12@\\\vrtg!:\x0f\x0f\x0e\x01rq4,dz!|p|t:f~xjmynhn0tEXQbFGTB^@K_EB@\\k\x11[G\x1a^SNKb\x1aPYD\x1ebn%+04)'>h\x14j61GGFYX)(iu?#v5;5;s-7\x0f\x13\x16\0\x11\x11\x15I\x03\f\x13\x18-\x0f\f\x1d\x15\x07\x1b\x12\0\x1c\x19\x19\v\"Z\x12\bS\x15\x1ayrY#o`\x7f'U'nb\x7f}bni1O3ih\x1c\x1e\x11\x10a`#\"cb*(+*-^]\x1a\b@^\x05GHW\\k\x11YVM\x15k\x19\\PIKP\\G\x1f=5\x05=0!"),[S("\x1d]TfHLGAW\tqAL]X\x03oO\\U\x1e{GQX`^]N"),S("\vOFHf~uwa;C\x7froj5Y}n{0cNNOAFRNGG|BIZ"),S("6ts\x7fSUXXL\x10\x16('47j\x04&;,e\b# > #8&6\x02<3 "),S("8M_CH\x1c}t\x06(,'!7i\x13-$:'-9+<\x7f\x02:<&!5\",*u\x1c.2+/N\x05\r\x17"),S("\x1ci{gT\0ahbLHCM[\x05\x7fI@^CQEW@\x1bf^XJMYNHN\x11l(.07'02i,&>")],function(e,t,n,i,r){"use strict";var o=e.extend({name:S(" rJLVQER\\\x7fCN["),tagName:S("\n\x7f~"),template:r,templateHelpers:function(){return{keys:this.getOption(S("(BOR_"))}}}),s=n.extend({name:S("\x19Issoj|UUQdVJSW~@O\\"),childViewContainer:S(")^ICIW"),childView:o,tagName:S("@5#!( "),className:S("C'. j;!%98.;;#"),template:i,initialize:function(e){this.collection=e.model.get(S("9ISSOJ\\551"))},childViewOptions:function(){return{keys:this.getOption(S("7S\\CH"))}}}),a=t.extend({name:S("\x1cNvpRUAVPVeHD\\GEzDKX"),template:"",childView:s,initialize:function(e){this.collection=e.model.get(S("\x11ua{`fd")),this.once(S("\r|j~uwa"),function(){this.$el.addClass(S("?5(o!(*%,e")+this.model.get(S("C'**2%'")))},this)},childViewOptions:function(){return{keys:this.getOption(S("\x1apydm"))}}}),l=t.extend({name:S("%uOG[^HYY]cYBFZZR"),childView:a,className:S('A7*i"4.,d(k9$c=5""<:&?!=y90:p-7\x0f\x13\x16\0\x11\x11\x15J\f\0\v\x07\x03\n'),template:"",childViewOptions:function(){return{keys:this.getOption(S("\x1etEXQ"))}}});return l}),CKFinder.define(S("<~uy)/&&6j\v(,<&.?b\x1d'?#&0!!%x\v15)(>++\x13"),[S("\vycjjbbq|fp"),S("\x1d|~CJ@LJ@"),S("\x14V]Qqw~~n2KkIM\rhA\\eHLL"),S('7{r|RRY[Mo\f-\'1)#4g\x1a"$>9-:$"}\x1e;13;+v\t33/*<\x15\x15\x11'),S("(jamECJJB\x1e\x7f\\P@ZRK\x16iSSOJ\\551l\x12,#0;f\x19##?:,%%!\x17=4:8?\x0f3>+"),S("\x13W^P~v}\x7fi3KwzWR\raEVC\bkFFGINZF__dZQB"),S("\x15U\\^pt\x7fyo1IIDUP\vgGTM\x06iDA]A\\YEWe]PA")],function(e,t,n,i,r){"use strict";function o(o){o.request(S("!IF]\x1fJN[]OE"),{key:n.slash}),o.on(S("\x11yvmqy`v#")+n.slash,function(n){if(n.finder.util.isShortcut(n.data.evt,S("\x13g}\x7fql"))){var s=i.createCollection();n.finder.fire(S("#WMIU\\J___\x17BFCE"),{groups:s},n.finder);var a={esc:{display:S("\nn\x7fn"),text:o.lang.shortcuts.keys.escape},del:{display:S(")NN@"),text:o.lang.shortcuts.keys.delete},ctrl:{display:S("\x12p`gz"),text:o.lang.shortcuts.keys.ctrl},downArrow:{display:S("\x1a=x|lm\x1b"),text:o.lang.shortcuts.keys.downArrow},leftArrow:{display:S("4\x13ZVJK\x01"),text:o.lang.shortcuts.keys.leftArrow},question:{display:"?",text:o.lang.shortcuts.keys.question},rightArrow:{display:S("0\x17@RFG\r"),text:o.lang.shortcuts.keys.rightArrow},upArrow:{display:S("\v*xo}b*"),text:o.lang.shortcuts.keys.upArrow}};s.forEach(function(e){var i=new t.Collection;n.finder.fire(S('C7-)5<*???w"&#%h')+e.get(S("\r`n}t")),{keys:a,shortcuts:i},n.finder),e.set(S("\x17kquih~kkS"),i)}),s.forEach(function(t){t.get(S("\x12`|zdc{lnh")).forEach(function(t){var n=[];e.forEach(t.get(S("2@\\ZDC[LNH")).split("|"),function(e){n.push(e.replace(/{|}/g,"").split("+"))}),t.set(S("\x1fSIMQPFSS["),n)})}),n.finder.request(S("2W]TZX_"),{name:S("\x1cNvpRUAVPVbNIEEL"),title:n.finder.lang.shortcuts.title,view:new r({finder:o,collection:i.createColumns(s,["a","b","c"]),keys:a}),buttons:[S("D*-\x04$&9.")],restrictHeight:!0})}}),o.on(S("\x15e\x7fwknxiim%LHQW\x1eBCIM[KG"),function(e){e.data.shortcuts.add({label:e.finder.lang.shortcuts.general.listShortcuts,shortcuts:S("|\v\x07+- 4h\x1e /"),attributes:{"data-role":S("9\\TSI[M"),"data-position":S("-HFHTV"),"data-tap-toggle":S(":]]QMZ"),role:S("\x1dmkAUWP"),tabindex:50},ui:{regions:S('7\x16ZQ]\x11NJ^441n&$4j:,-"##=')},events:{keydown:function(e){e.keyCode===t.tab&&(this.finder.util.isShortcut(e,"")||this.finder.util.isShortcut(e,S("\x0e|xxtg")))&&this.finder.request(S(this.finder.util.isShortcut(e,"")?"\x17~vyno'pzXU":"\vjbmzc+baqc"),{node:this.$el,event:e})}},initialize:function(e){this.once(S("\v~h`kuc"),function(){this.$el.attr(S('"BVLG\nDHHN@'),e.label)},this)},onRender:function(){var t=this;setTimeout(function(){t.$el.toolbar(),t.$el.toolbar(S(';IMZ^4$\x12"# \x16&,-#%+')),e.mobile.resetActivePageHeight()},0)}});return i}),CKFinder.define(S("\x1e\\kgKM@@T\beFN^@H]\0cESGAFtVJ\x16iO]IKL\x02 0"),[S("-D^ET@J"),S("@## /'))-"),S('A\x01\b\x02,(#-;e\x06#);#5"}\0 4""+\x1b;)s\v7:\x17\x12M0\x10\x04\x12\x12\x1b+\v\x19:\x04\v\x18')],function(e,t,n){"use strict";function i(e){this.bars=new t.Collection;var i=this;i.finder=e,e.setHandlers({"statusBar:create":function(t){if(!t.name)throw S('#v@WRMZ^\v_YO[EBpRF\x15UE]XN^\x1cS[Z$2b-%(#g8(8*!(:*"');if(!t.page)throw S('B\x11!43";=j88,::#\x133!n6$29-?{28;;\x13A\x12\x02\x03\0F\x17\t\x1b\v\x06\t\x19\v\x1d');var r=new n({finder:i.finder,name:t.name,label:t.label});return i.bars.add({name:t.name,page:t.page,bar:r}),r.render().$el.appendTo(S('>d$ 6"i&-!e9+,)pl')+t.page+S(":\x19a")),e.fire(S("&T\\H^^_oO]\nR@VUAS"),{name:t.name,page:t.page},e),r},"statusBar:destroy":function(t){var n=i.bars.findWhere({name:t.name});n&&(e.fire(S(",^ZNDDAqUG\fS]JNISD\x04")+t.name,null,e),n.get(S("\x16uyk")).destroy(),i.bars.remove(n))},"statusBar:addRegion":function(e){var t=i.bars.findWhere({name:e.name});t&&t.get(S("$GGU")).createRegion({id:e.id,name:e.id,priority:e.priority?e.priority:50})},"statusBar:showView":function(e){var t=i.bars.findWhere({name:e.name});t&&t.get(S("\x11prf"))[e.region].show(e.view)}})}return i}),CKFinder.define(S("\x1c^UYIOFFV\nkHL\\FN_\x02z@_]PRFF\x19aQ\\MH\x13iQP,##1\x06023''\x1c\"):"),[S("]556,*"),name:S("1f\\[YTVJpN^Q\x7fKK4.,"),template:S("$^]\x1a\b@^\x05@LLJ\\\x11ON"),modelEvents:{"change:isDisabled":function(e){e.get(S("!KP`LUFJEOO"))?this.$el.addClass(S(".ZY\x1cAGUAS\x1a\\PIZ^Q[[")).attr(S("/QC[R\x19Q_DY[V^X"),S("4ADB]")):this.$el.removeClass(S("D0/j;=+?)`*�?11")).attr(S("2RF\\W\x1a\\PIZ^Q[["),S("%@FDZO"))},focus:function(){this.$el.focus()}},events:{click:S("\x1bnhp^CUKLJ"),keydown:function(e){this.trigger(S("\x0efdt\x7fxqlrxow"),{evt:e,view:this,model:this.model})},keyup:function(e){e.preventDefault(),e.stopPropagation()},focus:function(){this.$el.attr(S("=J^\"(,'!="),1)},blur:function(){this.$el.attr(S("\vxllf~uwk"),-1)}},onRender:function(){this.$el.button()},runAction:function(){var t=this.model.get(S("5WTLPUU"));e.isFunction(t)&&t(this)}});return n}),CKFinder.define(S("=}t\x06(,'!7i\n'-?')>a\x1b?>>15'%x\x0e0?,/r\n0\x0f\r\0\x02\x163\x0f\x02\x1f"),[S("\x13a{rrjjytnx"),S("\x1bvlkzRX"),S("\vOFHf~uwa;C\x7froj5Y}n{0cNOSKVOSM\x7fCN["),S(")i`jD@KUC\x1de]PAD\x17{[HY\x12wK%,\x14*!2"),S('$fmaAGNN^\x02c@TD^VG\x1abXWUXZNN\x11i)$50k\x11)($++9\x0e8:;??\x04:1"'),S("\x11QXR|xs}k5Nhtr0kD[`KAC")],function(e,t,n,i,r,o){"use strict";function s(t,n){var i=t.finder.request(S("D0/}/,>\x06#)+")),o=[S("!AHB\bRHGEHJ^\0G[U\\"),S(">\\+'o7+**%);g)99: >"),S(")I@J\0Z@_]PRF\x18_C]T\x17]S^KL!#.&d0/j*=$k9$c,?#<6&x7;4")];n.has(S("%EKIZYeM@K"))&&o.push(n.get(S("-MCQBA}UXS"))),i!==S("\x1fDDQHPJV")||n.get(S(":R_RPp.-;"))?o.push(S("D0/j*=$f%.!!}?='1-\"")):o.push(S('gawc}4~ro||sEE")),s[S("\x13ug\x7fv5}sh}\x7frzD")]=S("\x10e`fq")),n.has(S("D$23: (>8(="))&&(s=e.extend(s,n.get(S("&F\\]XBNXZJC")))),r.extend({attributes:s,className:o.join(" ")})}function a(e,t){var n=S('7[R\\\x16HRQS" 0n-1#*h*!-a9! <33!y!3/,');return t.has(S('>\\, 10\n$+"'))&&(n+=" "+t.get(S('"@HDUTfHGN'))),i.extend({finder:e.finder,name:S("'|FEGNL\\fDT_gQMB"),tagName:S("2W]C"),template:S("/KJ\x0f\x13]A\x18[Y[_W\x1c@C"),className:n,attributes:{"data-ckf-name":t.get(S("?. /&"))}})}function l(e,t){return t.set({attributes:{"data-show-more":!0},alwaysVisible:!0}),s(e,t)}function u(t,n){var r=t.finder.request(S("!WJ\x1eBCSeFNN")),s=[S("\x19ypz0jpOM@BV\bOSMD"),S("B /#k3'&&)-?c-%%&<:"),S("0RYU\x19AYXT[[I\x11TJZ-l$,'05&*%/k9$c-$?r&=x58*7?)q<23")];n.has(S("-MCQBA}UXS"))&&s.push(n.get(S("3WYWDKw[VY"))),r!==S('"GAVMSGY')||n.get(S("\nbob`@~}k"))?s.push(S("\x1dkv\rCVM\tLEHF\x04DDXHV[")):s.push(S("\x12f}8tcv4sxss3")+S(t.finder.lang.dir===S("E*3:")?"\x14ysql":"&UANB_")),s.push(S("\x15c~5pytr0")+n.get(S(")CHCC")));var a={"data-ckf-name":n.get(S("\x12}uxs")),title:n.get(S("&KIKOG")),tabindex:-1,href:n.get(S("\x18qh~z")),role:S("\x0frdfg{{")};return n.get(S("*B_iG\\QS^VP"))&&(s.push(S("\r{f=bfr`p;sqj{ypxz")),a[S("6VJP[\x16XTM^\"-''")]=S("K91'"));if(n===S("/CY]DyZDR")||e.get(S("D$*0)09\x1d%>'-<4")))return void(n===S("B0,*1\n';/")&&(a=e));var l=t.children.findByModelCid(e.cid),u=Math.ceil(l.$el.outerWidth(!0));e.get(S("\x1fHHFGAK"))?d(l):u+r>=o?(n===S("\x17zlnoss")&&(i+=1),d(l),e.set(S("\x16dpvmVso{"),!0)):r+=u,i||(s=l)}),i&&(a.set(S("E..,-/%"),!1),n.show(),n.removeAttr(S("2RF\\W\x1aPP^_YS")),s&&r+Math.ceil(n.outerWidth(!0))>o&&(d(s),s.model.set(S("\x1dmwOVoLV@"),!0))),t.$el.find(S("\x1e1CJD\x0ePJIKJHX\x06EYKB")).removeClass(m);var l=t.collection.findWhere({focus:!0});if(l){var u=t.children.findByModelCid(l.cid);u&&u.$el.focus()}}}function d(e){e.$el.hide(),e.$el.attr(S(")KYEL\x03GYUVVZ"),S('C073"')),e.trigger(S("%NNLMOE"))}function f(e){var t=e.get(S("+MAYNIBdZG\\T[]"))?v:0;return t-e.get(S(">O2(-1-1?"))}function h(e){e.model.get(S("\x1azptyqMDLW"))!==S("&WZ@GJ^T")&&e.$el.addClass(S("\x17{r|6hrqsB@P\x0eW@EHFMKYU")),e.model.get(S("\rzv`t"))===S("0RG@@Z[")&&e.$el.addClass(S("6TS_\x17OSRR]!3o*0 +")),e.model.get(S('"BHRG^[\x7fCXEOBJ'))&&e.$el.attr(S(">[!5#n'. j)%=*5>c99\";180"),S("-Z]ET"))}function g(e){var t=e.collection.filter(function(e){return!(e.get(S("'@@NOIC"))===!0||e.get(S('C0<6"'))===S("\x10rg``z{")||e.get(S("=JF0$"))===S("\x0fdtjg"))}),n=[],i=[];return t.forEach(function(t){t.get(S("E'+!.$&)#:"))===S(e.finder.lang.dir===S(",AZ]")?"C47/*);3":" RG@KKBFZP")?n.push(t):i.unshift(t)}),n.concat(i)}var p,v=9e5,m=S(">\\+'o7+**%);g\"8(#b88671;");return p=n.extend({name:S("@\x15-,(''5\x1e /<"),attributes:{"data-role":S(":SY\\ZZ2"),role:S("\rln~\x7fwa")},childViewContainer:S("\x169{r|6hrqsB@P\x0eMQCJ["),template:S("\x0e3txd3`tt~v}\x7fc!?//\x02\x01AOEVU\x1a\nJAM\x01YA@\\SSA\x19\\BRUJ\x18\x1bNRRZ}c6,+)$&:ktwc)'9n"),events:{keydown:function(e){var t=e.keyCode;if(t===o.tab&&this.finder.util.isShortcut(e,""))return void this.finder.request(S("\x0fv~qfg/xr`m"),{node:this.ui.items,event:e});if(t>=o.left&&t<=o.down||t===o.home||t===o.end){e.stopPropagation(),e.preventDefault();var n=g(this);if(!n.length)return;var i=this.finder.lang.dir===S("\x1esTS")?o.end:o.home,r=t===o.left||t===o.up||t===i?n.length-1:0;this.children.findByModel(n[r]).$el.focus()}},"focus @ui.items":function(e){if(e.target===e.currentTarget){e.preventDefault(),e.stopPropagation();var t=g(this);if(t.length){var n=this.finder.lang.dir===S("#HQT")?0:t.length-1;this.children.findByModel(t[n]).$el.focus()}}}},ui:{items:S("&\tKBL\x06XBACRP@\x1e]ASZK")},onRender:function(){var e=this;setTimeout(function(){e.$el.toolbar(e.toolbarOptions),e.$el.toolbar(S("@42'%1#\x17)./\x1b-)*&>6")),t.mobile.resetActivePageHeight(),e.$el.attr(S("*OMYO\x02SZT\x1e@ZY[ZXH"),e.name),e.finder.fire(S("\fya`|ssa.vdrym\x7f"),{name:e.name,page:e.page},e.finder)},0)},initialize:function(t){var n=this;n.name=t.name,n.page=t.page,n.toolbarOptions={position:S("\x11tzlpr"),tapToggle:!1,updatePagePadding:!0},n.on(S('9H^RY[Mz"-/( %3!&$'),function(){n.$el.addClass(S(":XW[\x13K/..!%7"))}),n.on(S("\x0fqefrw}Tb~\x7f\x7fi"),c,n),n.on(S(':XTTR[6(\'4~,2"%"/2("9!'),function(t,i){var r,s,a=i.evt;if(a.keyCode===o.up||a.keyCode===o.left||a.keyCode===o.down||a.keyCode===o.right){a.stopPropagation(),a.preventDefault();var l=g(n);r=e.indexOf(l,t.model),a.keyCode===o.down||a.keyCode===o.right?(s=r+1,s=s<=l.length-1?s:0):(s=r-1,s=s>=0?s:l.length-1),this.children.findByModel(l[s]).$el.focus()}a.keyCode!==o.enter&&a.keyCode!==o.space||(a.stopPropagation(),a.preventDefault(),e.isFunction(t.runAction)&&t.runAction())})},getChildView:function(e){var t=e.get(S("\n\x7fu}k"));return t===S("=]J35-.")?e.get(S(";JT[H")):t===S("/CY]DyZDR")?l(this,e):t===S("-ZJHE")?a(this,e):t===S("\x15z~vr7yiijpN")?u(this,e):s(this,e)},focus:function(){t(this.childViewContainer).focus()}})}),CKFinder.define(S("\x0eL[W{}ppd8Uv~npxm0tNMOFDTT\x07}ED@OO]"),[S("\x1ejNEGQWFIUM"),S("1XBAPDN"),S("\x11prw~txv|"),S("7{r|RRY[Mo\f-'1)#4g\x1d%$ //=#~\x04:1\"%x\f657><,\t\t\x04\x15"),S("\x13W^P~v}\x7fi3Pq{UMGP\vfII\\LR_aH@Z\x1fg[VCF\x19tWWN^DIsZ.4\x14*!2")],function(e,t,n,i,r){"use strict";function o(e,t){this.name=t,this.finder=e,this.currentToolbar=new l}var s=30,a=n.Model.extend({defaults:{type:S("\x15tblmuu"),alignment:S("E65!$+95"),priority:s,alwaysVisible:!1}}),l=n.Collection.extend({model:a,comparator:function(e,t){var n=e.get(S(";]QWX.,'-0"));if(n!==t.get(S(".N\\XU]YPXC")))return n===S("C47/*);3")?-1:1;var i=e.get(S("\x1akntqmIU[")),r=t.get(S("C47/(: >2"));if(i===r)return 0;var o=n===S("$UTNEHXR")?1:-1;return iyzdr5o\x7fiht}~L"),iconOnly:!0,type:S("\x11a{{b[xj|"),label:o.finder.lang.common.showMore,priority:-10,hidden:!0,action:function(){var e=new n.Collection;o.currentToolbar.chain().filter(function(e){return!!e.get(S("/CY]DyZDR"))}).forEach(function(t){e.push({action:t.get(S("\x1e~CUKLJ")),isActive:!0,icon:t.get(S(".FS^\\")),label:t.get(S("$IGEME")),hidden:!1})});var t=o.toolbarView.children.findByModel(o.currentToolbar.findWhere({type:S("\x1ahtriROSG")}));o.currentToolbar.showMore=new r({finder:o.finder,collection:e,positionToEl:t.$el}).render(),o.currentToolbar.showMore.once(S("?$$176*?"),function(){o.currentToolbar.showMore=!1,t.$el.focus()})}}),o.currentToolbar.reset(s.toolbar.toArray())},o.prototype.init=function(e,t){var n=this;n.toolbarView=new i({finder:e,collection:n.currentToolbar,name:n.name,page:t}),n.toolbarView.on(S("=]W)-&5- 1} ./)#"),function(e){e.model.set(S(">W)%&&*"),!0)}),n.toolbarView.render().$el.prependTo(S(":`X\\J^m\")%i5' -th")+t+S("\x198F"))},o.prototype.destroy=function(){this.toolbarView.destroy(),this.currentToolbar.reset()},o.prototype.redraw=function(){this.currentToolbar.forEach(function(t){if(t.get(S(")^R\\H"))!==S("\v\x7feax]~`v")&&t.set(S(" IKG@@H"),!1),t.has(S("7WWh^XO_H"))){var n=t.get(S("\x13{{Dr|k{l"));e.isFunction(n)&&n.call(t)}}),this.toolbarView.render()},o.prototype.hideMore=function(){this.currentToolbar.showMore&&this.currentToolbar.showMore.destroy()},o}),CKFinder.define(S("-mdvX\\WQG\x19zW]OWYN\x11k/..!%75h\x1c&%'.,<<"),[S(";VLKZ28"),S("B6*!#5;*%9)"),S("\x0frpqxvzxr"),S('A\x01\b\x02,(#-;e\x06#);#5"}\x07;::59+)t\b213\x02\0\x10'),S("\x1c^UYIOFFV\nsSAE\x05`ITm@TT")],function(e,t,n,i,r){"use strict";function o(){this.toolbars=new n.Collection}function s(e){e.get(S("\x11f|{ytvj")).destroy(),this.toolbars.remove(e),this.finder.fire(S('\x10e}|xwwe"}\x7fhhoqf'),{name:e.get(S("\r`n}t"))},this.finder)}function a(t){t.request(S(":PYD\x04S)26&*"),{key:r.f7}),t.on(S(">T%8&,3+|")+r.f7,function(n){t.util.isShortcut(n.data.evt,S("\x1azpi"))&&(n.data.evt.preventDefault(),n.data.evt.stopPropagation(),e(S(";\x12HW\x120 %&i$%3!?/kb.%)}%=<877%u0.>1.")).focus())}),t.on(S("\x17kquih~kkS\x1bNJWQ\x1c@MGOYMA"),function(e){e.data.shortcuts.add({label:e.finder.lang.shortcuts.general.focusToolbar,shortcuts:S('"XEIRZ\x03RL\x1cQ')})},null,null,20)}var l=S(":XW[\x13K/..!%7k1!:#) (");return o.prototype={getHandlers:function(){return{"toolbar:create":{callback:this.toolbarCreateHandler,context:this},"toolbar:reset":{callback:this.toolbarResetHandler,context:this},"toolbar:destroy":{callback:this.toolbarDestroyHandler,context:this}}},setFinder:function(n){function i(t){o.toolbars.where({page:t}).forEach(function(e){e.get(S("\x12g{zzuyk")).redraw()}),r=e(document).width()}this.finder=n,a(n);var r=0;n.on(S("2F]\x0fDRKP@^"),function(){var t=e(document).width();if(r!==t){var o=n.request(S("/@PUV\x0eVCEJ\\TO"));i(o)}}),n.on(S("']@\x10I@X\\"),function(){o.toolbars.where({page:n.request(S("\r~nwt(pagdrvm"))}).forEach(function(e){e.get(S("1F\\[YTVJ")).hideMore()})});var o=this;n.on(S("\x15fv\x7f| htri"),function(t){var n=t.data.page;i(n),o.toolbars.where({page:n}).length?e(S("*ICIW")).addClass(l):e(S("\x1d|pDX")).removeClass(l)}),n.on(S("\x16gy~\x7f!xxmkRN["),function(e){t.forEach(this.toolbars.where({page:e.data.page}),s,this)},this)},toolbarCreateHandler:function(t){this.toolbarDestroyHandler(t);var n=new i(this.finder,t.name);this.toolbars.add({page:t.page,name:t.name,toolbar:n}),n.init(this.finder,t.page);var r=this.finder.request(S("6GY^_\x01_HLM%/6"));t.page===r&&e(S("!@L@\\")).addClass(l)},toolbarDestroyHandler:function(t){var n=this.toolbars.where({name:t.name})[0];n&&(s.call(this,n),n.page===this.finder.request(S("%VFOL\x10HY_\\J^E"))&&e(S("\x1d|pDX")).removeClass(l))},toolbarResetHandler:function(e){var n=this.toolbars.where({name:e.name})[0];if(n){var i=t.extend({},e.context);n.get(S("\x14ayxt{{i")).reset(e.event,i)}}},o}),CKFinder.define(S("\x13W^P~v}\x7fi3Pq{UMGP\vpVKGHNmEAKmEEF\\Z\x1acGTV[_zTRZ\x02467++"),[S("\x14V]Qqw~~n2KkIM\rhA\\eHLL")],function(e){"use strict";function t(e){e.on(S("(]ED@OO]\nCW@QA\fzYPT\x01ZRR[%3"),n),e.on(S("\x1fTNMOFDT\x1dZLYNX\x17cNY_\bU]YS"),n),e.on(S("\x15bxwuxzn'lzSDV\x19iDOI\x12OCGI^"),n),i(e)}function n(e){var t=e.finder.request(S("\x1fFNNGAW\x1c@M]kHXDXJ"));t.get(S(",LMC")).fileUpload&&e.data.toolbar.push({name:S("-{_\\^SW"),type:S("\x18{oohrp"),priority:80,icon:S("\x16ts\x7f7nlqq~D"),label:e.finder.lang.common.upload,action:function(){e.finder.request(S("\vy}b`qu"))}})}function i(t){t.request(S("=UZ9{.*71#)"),{key:e.u}),t.on(S("\ffkvt~e}.")+e.u,function(e){t.util.isShortcut(e.data.evt,S("\x11s\x7f`"))&&t.request(S("\x1chnsO@F"))}),t.on(S("/CY]A@VCCK\x03VROI\x04Y)-'0"),function(e){e.data.shortcuts.add({label:e.finder.lang.shortcuts.files.upload,shortcuts:S("\x14nw{ld1`i`")})},null,null,40)}return t}),CKFinder.define(S("\x14V]Qqw~~n2SpDTNFW\nkHL\\FN_"),[S("3A[RRJJYTNX"),S('>]!")!++#'),S("\rMDVx|wqg9Zw}owyn1\\SSDwKNCIeHDJKH\\\0sB@U`Z]RVt[U]Z[M"),S("\x0eL[W{}ppd8Uv~npxm0cNLMAFRHZ\x06iDBCKLD^@"),S("\nHGKgatt`a\t?2' \x19486?<(t\x1a2=*\x13,\x03\r\x05\x02\x03\x15"),S("&dcoCEHH\\\0}^VFXPE\x18~VV_YOM\x10\x06..'!75"),S("\x12P_S\x7fy||h4QrzjLDQ\fbJTJ}YFDMI\x01i_C_fDYYV\\"),S("\vOFHf~uwa;Xysmu\x7fh3UjrL\x14wSHJGC\x07a^F@\x18{_\\^SW"),S("\fNEIy\x7fvvf:[x|lv~o2UzYmKPP@HBZ\x06aNUaG\\DT\\VF"),S("%eln@DOI_\x01b_UG_QF\x19{WX^^N\x12rP!%'1"),S("B\0\x0f\x03/),,8d\x01\"*:<4!|\x194.>50 >s\x10?'\t\f\v\x19\x01"),S("-mdvX\\WQG\x19zW]OWYN\x11o!&'0k\x15' -:"),S("3w~p^V]_I\x13pQ[5-'0k\x15')-%9d\x1c, *<\""),S("(jamECJJB\x1e\x7f\\P@ZRK\x16h^R\\SZ\x06(.&k\x17#))$/\r%!+"),S("\x12P_S\x7fy||h4QrzjLDQ\fv@HFELlD@IK]\x1fcW]UXSqWU^^N"),S("'kblBBIK]\x1f|]WAYSD\x17\x7fSWHXLy)-'0k\x03/+<,8\r%!+<"),S('5u|~PT_YO\x11r/%7/!6i\x14-=>""*=`\x034&\'=;1$'),S("\x0eL[W{}ppd8Uv~npxm0sIMQPFSS[\x06yCC_ZLEEA"),S("1qxr\\XS]K\x15vSYKS%2m\x100$22;\v+9c\x1e:.$$!\x115'"),S("\nHGKgatt`?##")],function(e,t,n,i,r,o,s,a,l,u,c,d,f,h,g,p,v,m,w,C,y,b,x,F,_,E,M,I,T,D,P){"use strict";function O(t,n,i){if(R[t]&&(!i||!e.contains(i,t))){var r=new R[t](n.finder);n.add(r),r.getHandlers&&n.finder.setHandlers(r.getHandlers()),r.setFinder&&r.setFinder(n.finder)}}var A=[S("\x1c^lzAUGeKIBBZ"),S("\x16S}u\x7foy[wsE"),S("\x1a_yq{kEgMO@@T"),S("\x1d[{IUkNEBC"),S("\x10W{\x7fqf[xn|Ytld"),S("\x17^vhvImrpAE"),S(';tISSu\x142/+$"'),S("B\x11!+'*-\x0f#')"),S("\x16E}w{vy[qsDDP"),S("3aEZXY]|RPX|J45--")],R={CsrfTokenManager:n,Connector:i,ContextMenu:r,CreateFolder:o,DeleteFile:s,DeleteFolder:a,Dialogs:l,EditImage:u,FileDownload:c,FilePreview:d,Files:f,FilesMoveCopy:h,Folders:p,FocusManager:g,FormUpload:v,Html5Upload:m,KeyListener:w,Loader:C,Maximize:y,Pages:b,Panels:x,RenameFile:F,RenameFolder:_,FilterFiles:E,Settings:M,Shortcuts:I,StatusBar:T,Toolbars:D,UploadFileButton:P},V=t.Collection.extend({init:function(t){var n=this;n.finder=t;var i=t.config.readOnlyExclude.length?t.config.readOnlyExclude.split(","):[],r=!!t.config.readOnly&&e.union(A,i);t.config.removeModules&&(r=e.union(r?r:[],t.config.removeModules.split(","))),O(S("\x1eSO@FFV"),n,r),O(S("\x13RzubkT{u}z{m"),n,r),O(S("@\n':\b,53-'/9"),n,r),O(S("-m\\BWf\\_PXzYW[\\YO"),n,r),O(S("\x18Zuurx}kOS"),n,r),O(S("'{L^_ECI\\"),n,r),O(S("(yKEIA]"),n,r),O(S("\x13P|w{w~i"),n,r),O(S("A\x01,*1#?<\x04/%9"),n,r),O(S("\r^nwta"),n,r),O(S("&sGFFIM_]"),n,r),O(S("\x1dMkAUWPfDT"),n,r),O(S("@\x07+/!6"),n,r),O(S("\x1c[qsDDPP"),n,r),O(S('D\x064")=/\r#!**"'),n,r),O(S("+hHBJDTt\\XQSE"),n,r),O(S("B\x11!+'*-\x0f%'((<"),n,r),O(S("E\0.$,9\x06#;+\f?!+"),n,r),O(S("8k_U]P[y)-'"),n,r),O(S("\vHhbjdtTzxp"),n,r),O(S('\x12[`xz"Mivt}y'),n,r),O(S("'nFXFy]B@QU"),n,r),O(S('"vTIIFLoCGIo[[D^\\'),n,r),O(S("-hF\\EWAr\\ZRK"),n,r),O(S("\x1eRAYKNM_C"),n,r),O(S("0w[_QeDRNP_L"),n,r),O(S("\x1bZtrzdNUMHJGC"),n,r),O(S("\x0eJtxfZytqr"),n,r),O(S("4f^XJMYNHN"),n,r)}});return V}),CKFinder.define(S("%eln@DOI_\x01yYTE@\x1baSZHU[OY~_\\($"),[S(";ISZZ22!,6 "),S("\x1cyqK")],function(e,t){"use strict";function n(e){this.finder=e,this._templates={}}return n.prototype.has=function(e){return!!this.get(e)},n.prototype.get=function(e){return this._templates[e]},n.prototype.compile=function(n,i,r){e.isFunction(r)&&(r=r.call(this));var o={imports:r,name:n,template:i};this.finder.fire(S("\fykb`}sgq"),o,this.finder),this.finder.fire(S("\x1bhxsoL@VF\x1e")+n,o,this.finder);var s=t.template(o.template,null,o.imports);return this._templates[n]=s,s},n}),CKFinder.define(S('.l{w[]PPD\x18nP_LO\x12jZ-1."0 \x14"&-/9)?'),[S("2FZQSEKZUIY"),S("B.%7/(&,>?)")],function(e,t){"use strict";function n(e){this.finder=e}return n.prototype.render=function(n,i,r,o){var s;if(s=this.finder.templateCache.has(i)?this.finder.templateCache.get(i):this.finder.templateCache.compile(i,r,{}),!s)throw new t.Error({name:S('"vJACAAGOOxHC_\\PFVqGDXJ'),message:S('3wTXYWM\x1aIYSZZ2a6+!e2"%9&*8(n<9?16t<"w1*z5)12\x7f\x0f\x13B\x16\n\x01\x03\x01\x01\x07\x0f\x0fB')});var a=e.extend(this.mixinTemplateHelpers(n.toJSON(),o));return t.Renderer.render(s,a)},n.prototype.mixinTemplateHelpers=function(t,n){return t=t||{},e.extend(t,{lang:this.finder.lang,config:this.finder.config},n)},n}),CKFinder.define(S("\x1aXW[wqDDP\feUVKAJK_EB@"),[S("#QKBBZZID^H"),S("\x10{cfqgo"),S("\x10u}G"),S("\x1b~|}tBNLF"),S(" bieMKBBZ\x06iDBKGH"),S('"`ocOILLX\x04i[KAD'),S("(jamECJJB\x1egG]Y\x19bLPV"),S(">|\v\x07+- 4h\x1d=#'c\x01/!7"),S("'kblBBIK]\x1fd{\x1ca|~V[RI"),S("\x0fSZTzzqse7Ivn{tpl\x0fqNVCLHT"),S('8zq}USZZ2n\x0f, 0*";f\x07$(8"*#'),S("\x17[R\\rry{m\x0fwKFSV\tsMDZGMYKlQRZV"),S("\x1b_VXvNEGQ\vsOB_Z\x05\x7fI@^CQEWaQ[RRJ\\H")],function(e,t,n,i,r,o,s,a,l,u,c,d,f){"use strict";function h(){var e,t,n;n=this,g(n),n._modules.init(n),t=n.config.resourceType,e={name:S("\x10X|z`")},t&&(e.params={type:t}),n.once(S("\x15uxut{ux'qt\x1ahLJP"),function(e){n.config.initConfigInfo=e.data.response},null,null,1),n.once(S("\x1axsps~NE\x18LO\x1foIA]"),function(){n.fire(S("+M]^\x15CESA@"),{},n)},null,null,999),n.once(S("\vobcbq\x7fv){~,P}m\\rpxm"),function(){n.fire(S("3UEF\rJ\\[_E"),{},n)},null,null,999),n.fire(S("2RDE\f[WX^^X"),{},n),n.request(S("C'*+*)'.q?( +"),e)}function g(t){var n,i=t.config,r={ckfinder:t},o=S("\x19ypztp{ESpFEA_");try{n=new CustomEvent(o,{detail:r})}catch(e){n=document.createEvent(S("\x12Vbpxc")),n.initEvent(o,!0,!1),n.detail=r}window.dispatchEvent(n),e.isFunction(i.onInit)?i.onInit(t):"object"==typeof i.onInit&&i.onInit.call(void 0,t)}function p(e){var t,n=e.data.response.error.number;t=e.data.response.error.message?e.data.response.error.message:n&&this.lang.errors.codes[n]?this.lang.errors.codes[n]:this.lang.errors.unknown.replace(S("C?+3**,86"),n),this.request(S("-JFQ]]T\x0e\\XQW"),{msg:t,name:S("+oBCBQ_VvFGYE")})}return n.templateSettings.doNotSkipEncoded=!0,{start:function(r){r.type&&(r.resourceType=r.type);var g={_reqres:new i.Wreqr.RequestResponse,_plugins:new u,_modules:new c,config:r,util:s,Backbone:i,_:e,doT:n};return g.templateCache=new d(g),g.renderer=new f(g),g.hasHandler=function(){return this._reqres.hasHandler.apply(g._reqres,arguments)},g.getHandler=function(){return this._reqres.getHandler.apply(g._reqres,arguments)},g.setHandler=function(){return this._reqres.setHandler.apply(g._reqres,arguments)},g.setHandlers=function(){return this._reqres.setHandlers.apply(g._reqres,arguments)},g.request=function(){return this._reqres.request.apply(g._reqres,arguments)},e.extend(g,o.prototype),g.on(S("\x16twtwzry$zRSMQ"),p,g),g.on(S("\x19ytqp\x7fqD\x1bGQVJT\x1daGC_"),function(){t(S("\x0fxe\x7f\x7f")).removeClass(S("4@_\x1aUVXRPX\x13M%/&&6,( "))}),g.on(S("?!12y!74(:"),function(e){alert(S("2p[@ZS\x18WUO\x1cNJ^25b\0\x0f\x03/),,8ql")+e.data.msg)}),g.on(S("\x12`|zdc{lnh&qwlT"),function(e){e.data.groups.add({name:S("\x19}~rxl~L"),priority:10,label:e.finder.lang.shortcuts.general.title})}),g.on(S(';OUQM4"777\x7f*.;=p,)#+=1='),function(e){e.data.shortcuts.add({label:e.finder.lang.shortcuts.general.action,shortcuts:S("?;$,7!7;")}),e.data.shortcuts.add({label:e.finder.lang.shortcuts.general.focusNext,shortcuts:S('@:6"&8')}),e.data.shortcuts.add({label:e.finder.lang.common.close,shortcuts:S("(ROXOP")})},null,null,60),g.once(S("\x0e\x7f|duzz/w{tK\x7fzxd"),h,g),a.init(g.config).fail(function(){g.fire(S("%GWX\x13OY^B\\"),{msg:S("/|P\\TATQR\x18_SWY\x1dWL`,+07,( h&8k.?!$5?")},g)}).done(function(t){g.lang=t;var n=r.skin;n.indexOf("/")<0&&(n=S("A1(-+5h")+n+S(" \x0eQHMK")),window.CKFinder.require([n],function(t){e.isFunction(t.init)&&(t.path=g.util.parentFolder(n)+"/",t.init(g)),l.init(g),g._plugins.load(g)})}),g}}}),CKFinder.define(S(";OVWQ3n(21 4>e$%)%!+`#:;="),{config:function(e){return e.iconsCSS||(e.iconsCSS=S(";OVWQ3n(21 4>e$%)%!+`92=='{5$+")),e.themeCSS||(e.themeCSS=S("\x1esICQ\fNTSBZP\x04FCOGCU\x1fF[QXS\x19[JI")),e},init:function(){CKFinder.require([S('C.43":0')],function(e){e(S("\x13vzrn")).addClass(S("2F]\x18_TWW\x17ZPI"))})}});CKFinder.define(S("6DSPTH\x13PQP..m0/,("),{config:function(e){return e.swatch="a",e.dialogOverlaySwatch=!0,e.loaderOverlaySwatch=!0,e.themeCSS||(e.themeCSS=S(".\\[X\\@\x1bXYXVV\x15XW[WQ$$0m'65")),e.iconsCSS||(e.iconsCSS=S("0BYZZF\x19ZWVTT\x13T]P.2l 76")),e},init:function(){CKFinder.require([S("\x1euQTGQ]")],function(e){e(S("\x0em\x7fuk")).addClass(S(",XG\x02Q]F\x1e]VYY"))})}});window.CKFinder=window.CKFinder||{},window.CKFinder.require=CKFinder.require||window.require||require,window.CKFinder.requirejs=CKFinder.requirejs||window.requirejs||requirejs,window.CKFinder.define=CKFinder.define||window.define||define,window.CKFinder.basePath&&window.CKFinder.requirejs.config({baseUrl:window.CKFinder.basePath}),window.CKFinder.requirejs.config({waitSeconds:0}),window.CKFinder.define(S("\x1e|KG}DHJDFD"),function(){return window.CKFinder});var event,eventType=S("\x12p\x7fs\x7fy||hIylkvRDpFEA_");try{event=new CustomEvent(eventType)}catch(e){event=document.createEvent(S("/uGW]@")),event.initEvent(eventType,!0,!1)}window.dispatchEvent(event),window.CKFinder.start=function(e){function t(e){[e.jqueryMobileStructureCSS,e.coreCSS,e.jqueryMobileIconsCSS,e.iconsCSS,e.themeCSS].forEach(function(e){if(e){var t=window.document.createElement(S(".CY_Y"));t.setAttribute(S(",_KC"),S("\x15ecau\x7fhtx{k")),t.setAttribute(S(" IPFB"),CKFinder.require.toUrl(e)+S("\x19%myo#uLXZA\x15")),window.document.head.appendChild(t)}})}e=e||{},window.CKFinder.require([S("-[ATT@@WZDR"),S("\x1c^UYIOFFV\neHFOCL"),S("E\x05\f\x0e $/)?a\x1a$8>|\x01!?;")],function(n,i,r){function o(e,t,i){var o,a,l=[S("3]Q"),S("\x17l`j~"),S("#V@UH][INxT^J"),S("6[YW]xSY["),S("$fmbL@^D^"),S("\x17[R_\x7fuiqmfTL@jPK")];if(a=n.pick(r.getUrlParams(),l),a.langCode&&(a.language=a.langCode),a.type&&(a.resourceType=a.type),a.CKEditor){a.chooseFiles=!0;var u=a.CKEditorFuncNum;a.ckeditor={id:a.CKEditor,funcNumber:u,callback:function(e,t){window.opener.CKEDITOR.tools.callFunction(u,e,t),window.close()}}}delete a.langCode,delete a.CKEditor,delete a.CKEditorFuncNum;var c;c=window!==window.parent&&window.opener||window.isCKFinderPopup?window.opener:window.parent.CKFinder&&window.parent.CKFinder.modal&&window.parent.CKFinder.modal(S(",[G\\YS^V"))||window!==window.parent&&!window.opener?window.parent:window, +o=n.extend({},e,t,c.CKFinder?c.CKFinder._config:{},i,a),s(o,function(e){e.start(o)})}function s(e,i){var r=e.skin;r.indexOf("/")<0&&(r=S("/CZ[]G\x1a")+r+S(")\x05XGD@")),window.CKFinder.require([r],function(i){var r=n.isFunction(i.config)?i.config(e):i.config;t(n.extend(e,r))}),window.jQuery&&/1|2\.[0-9]+.[0-9]+/.test(window.jQuery.fn.jquery)?a(e,i):window.CKFinder.require([window.CKFinder.require.toUrl(e.jquery)+S("7\x07O_I\x01WRF8#s")],function(){a(e,i)})}function a(e,t){window.CKFinder.define(S("A(21 4>"),function(){return window.jQuery}),window.jQuery(window.document).bind(S("\x19wt~trzIOKW"),function(){window.jQuery.mobile.linkBindingEnabled=!1,window.jQuery.mobile.hashListeningEnabled=!1,window.jQuery.mobile.autoInitializePage=!1,window.jQuery.mobile.ignoreContentEnabled=!0}),window.CKFinder.require([window.CKFinder.require.toUrl(e.jqueryMobile)+S("8\x06L^N\0TS99 r")],function(){window.CKFinder.define(S("0RYU\x19_GB]KC\x16QR\\V,$"),function(){return window.jQuery.mobile}),window.CKFinder.require([S("6ts\x7fSUXXL\x10\x0112/-&'3!&$")],t)})}var l=n.isUndefined(e.configPath)?i.configPath:e.configPath;return l?void window.CKFinder.require([window.CKFinder.require.toUrl(l)],function(t){o(i,t,e)},function(){o(i,{},e)}):void o(i,{},e)})}}}}(); \ No newline at end of file diff --git a/lib/ckfinder/config.js b/lib/ckfinder/config.js new file mode 100644 index 0000000..63df7c8 --- /dev/null +++ b/lib/ckfinder/config.js @@ -0,0 +1,14 @@ +/* + Copyright (c) 2007-2016, CKSource - Frederico Knabben. All rights reserved. + For licensing, see LICENSE.html or http://cksource.com/ckfinder/license + */ + +var config = {}; + +// Set your configuration options below. + +// Examples: +// config.language = 'pl'; +// config.skin = 'jquery-mobile'; + +CKFinder.define( config ); diff --git a/lib/ckfinder/config.php b/lib/ckfinder/config.php new file mode 100644 index 0000000..086dca9 --- /dev/null +++ b/lib/ckfinder/config.php @@ -0,0 +1,175 @@ + 'default', + 'tags' => '.ckfinder/tags', + 'logs' => '.ckfinder/logs', + 'cache' => '.ckfinder/cache', + 'thumbs' => '.ckfinder/cache/thumbs', +); + +/*============================ Images and Thumbnails ==================================*/ +// http://docs.cksource.com/ckfinder3-php/configuration.html#configuration_options_images + +$config['images'] = array( + 'maxWidth' => 1600, + 'maxHeight' => 1200, + 'quality' => 80, + 'sizes' => array( + 'small' => array('width' => 480, 'height' => 320, 'quality' => 80), + 'medium' => array('width' => 600, 'height' => 480, 'quality' => 80), + 'large' => array('width' => 800, 'height' => 600, 'quality' => 80) + ) +); + +/*=================================== Backends ========================================*/ +// http://docs.cksource.com/ckfinder3-php/configuration.html#configuration_options_backends + +$config['backends'][] = array( + 'name' => 'default', + 'adapter' => 'local', + 'baseUrl' => '/ckfinder/userfiles/', +// 'root' => '', // Can be used to explicitly set the CKFinder user files directory. + 'chmodFiles' => 0777, + 'chmodFolders' => 0755, + 'filesystemEncoding' => 'UTF-8', +); + +/*================================ Resource Types =====================================*/ +// http://docs.cksource.com/ckfinder3-php/configuration.html#configuration_options_resourceTypes + +$config['defaultResourceTypes'] = ''; + +$config['resourceTypes'][] = array( + 'name' => 'Files', // Single quotes not allowed. + 'directory' => 'files', + 'maxSize' => 0, + 'allowedExtensions' => '7z,aiff,asf,avi,bmp,csv,doc,docx,fla,flv,gif,gz,gzip,jpeg,jpg,mid,mov,mp3,mp4,mpc,mpeg,mpg,ods,odt,pdf,png,ppt,pptx,pxd,qt,ram,rar,rm,rmi,rmvb,rtf,sdc,sitd,swf,sxc,sxw,tar,tgz,tif,tiff,txt,vsd,wav,wma,wmv,xls,xlsx,zip', + 'deniedExtensions' => '', + 'backend' => 'default' +); + +$config['resourceTypes'][] = array( + 'name' => 'Images', + 'directory' => 'images', + 'maxSize' => 0, + 'allowedExtensions' => 'bmp,gif,jpeg,jpg,png', + 'deniedExtensions' => '', + 'backend' => 'default' +); + +/*================================ Access Control =====================================*/ +// http://docs.cksource.com/ckfinder3-php/configuration.html#configuration_options_roleSessionVar + +$config['roleSessionVar'] = 'CKFinder_UserRole'; + +// http://docs.cksource.com/ckfinder3-php/configuration.html#configuration_options_accessControl +$config['accessControl'][] = array( + 'role' => '*', + 'resourceType' => '*', + 'folder' => '/', + + 'FOLDER_VIEW' => true, + 'FOLDER_CREATE' => true, + 'FOLDER_RENAME' => true, + 'FOLDER_DELETE' => true, + + 'FILE_VIEW' => true, + 'FILE_CREATE' => true, + 'FILE_RENAME' => true, + 'FILE_DELETE' => true, + + 'IMAGE_RESIZE' => true, + 'IMAGE_RESIZE_CUSTOM' => true +); + + +/*================================ Other Settings =====================================*/ +// http://docs.cksource.com/ckfinder3-php/configuration.html + +$config['overwriteOnUpload'] = false; +$config['checkDoubleExtension'] = true; +$config['disallowUnsafeCharacters'] = false; +$config['secureImageUploads'] = true; +$config['checkSizeAfterScaling'] = true; +$config['htmlExtensions'] = array('html', 'htm', 'xml', 'js'); +$config['hideFolders'] = array('.*', 'CVS', '__thumbs'); +$config['hideFiles'] = array('.*'); +$config['forceAscii'] = false; +$config['xSendfile'] = false; + +// http://docs.cksource.com/ckfinder3-php/configuration.html#configuration_options_debug +$config['debug'] = false; + +/*==================================== Plugins ========================================*/ +// http://docs.cksource.com/ckfinder3-php/configuration.html#configuration_options_plugins + +$config['pluginsDirectory'] = __DIR__ . '/plugins'; +$config['plugins'] = array(); + +/*================================ Cache settings =====================================*/ +// http://docs.cksource.com/ckfinder3-php/configuration.html#configuration_options_cache + +$config['cache'] = array( + 'imagePreview' => 24 * 3600, + 'thumbnails' => 24 * 3600 * 365, + 'proxyCommand' => 0 +); + +/*============================ Temp Directory settings ================================*/ +// http://docs.cksource.com/ckfinder3-php/configuration.html#configuration_options_tempDirectory + +$config['tempDirectory'] = sys_get_temp_dir(); + +/*============================ Session Cause Performance Issues =======================*/ +// http://docs.cksource.com/ckfinder3-php/configuration.html#configuration_options_sessionWriteClose + +$config['sessionWriteClose'] = true; + +/*================================= CSRF protection ===================================*/ +// http://docs.cksource.com/ckfinder3-php/configuration.html#configuration_options_csrfProtection + +$config['csrfProtection'] = true; + +/*============================== End of Configuration =================================*/ + +// Config must be returned - do not change it. +return $config; diff --git a/lib/ckfinder/core/connector/php/connector.php b/lib/ckfinder/core/connector/php/connector.php new file mode 100644 index 0000000..537698b --- /dev/null +++ b/lib/ckfinder/core/connector/php/connector.php @@ -0,0 +1,20 @@ +run(); diff --git a/lib/ckfinder/core/connector/php/vendor/autoload.php b/lib/ckfinder/core/connector/php/vendor/autoload.php new file mode 100644 index 0000000..c875cf7 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/autoload.php @@ -0,0 +1,7 @@ +addAlias('_aws', self::getDefaultServiceDefinition()) + ->addAlias('_sdk1', __DIR__ . '/Resources/sdk1-config.php'); + + return $loader->load($config, $globalParameters); + } + + /** + * Get the full path to the default service builder definition file + * + * @return string + */ + public static function getDefaultServiceDefinition() + { + return __DIR__ . '/Resources/aws-config.php'; + } + + /** + * Returns the configuration for the service builder + * + * @return array + */ + public function getConfig() + { + return $this->builderConfig; + } + + /** + * Enables the facades for the clients defined in the service builder + * + * @param string|null $namespace The namespace that the facades should be mounted to. Defaults to global namespace + * + * @return Aws + * @deprecated "Facades" are being removed in version 3.0 of the SDK. + */ + public function enableFacades($namespace = null) + { + Facade::mountFacades($this, $namespace); + + return $this; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Client/AbstractClient.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Client/AbstractClient.php new file mode 100644 index 0000000..f0d6c30 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Client/AbstractClient.php @@ -0,0 +1,283 @@ +get(Options::BASE_URL), $config); + $this->credentials = $credentials; + $this->signature = $signature; + $this->aggregator = new DuplicateAggregator(); + + // Make sure the user agent is prefixed by the SDK version + $this->setUserAgent('aws-sdk-php2/' . Aws::VERSION, true); + + // Add the event listener so that requests are signed before they are sent + $dispatcher = $this->getEventDispatcher(); + $dispatcher->addSubscriber(new SignatureListener($credentials, $signature)); + + if ($backoff = $config->get(Options::BACKOFF)) { + $dispatcher->addSubscriber($backoff, -255); + } + } + + public function __call($method, $args) + { + if (substr($method, 0, 3) === 'get' && substr($method, -8) === 'Iterator') { + // Allow magic method calls for iterators (e.g. $client->getIterator($params)) + $commandOptions = isset($args[0]) ? $args[0] : null; + $iteratorOptions = isset($args[1]) ? $args[1] : array(); + return $this->getIterator(substr($method, 3, -8), $commandOptions, $iteratorOptions); + } elseif (substr($method, 0, 9) == 'waitUntil') { + // Allow magic method calls for waiters (e.g. $client->waitUntil($params)) + return $this->waitUntil(substr($method, 9), isset($args[0]) ? $args[0]: array()); + } else { + return parent::__call(ucfirst($method), $args); + } + } + + /** + * Get an endpoint for a specific region from a service description + * @deprecated This function will no longer be updated to work with new regions. + */ + public static function getEndpoint(ServiceDescriptionInterface $description, $region, $scheme) + { + try { + $service = $description->getData('endpointPrefix'); + $provider = RulesEndpointProvider::fromDefaults(); + $result = $provider(array( + 'service' => $service, + 'region' => $region, + 'scheme' => $scheme + )); + return $result['endpoint']; + } catch (\InvalidArgumentException $e) { + throw new InvalidArgumentException($e->getMessage(), 0, $e); + } + } + + public function getCredentials() + { + return $this->credentials; + } + + public function setCredentials(CredentialsInterface $credentials) + { + $formerCredentials = $this->credentials; + $this->credentials = $credentials; + + // Dispatch an event that the credentials have been changed + $this->dispatch('client.credentials_changed', array( + 'credentials' => $credentials, + 'former_credentials' => $formerCredentials, + )); + + return $this; + } + + public function getSignature() + { + return $this->signature; + } + + public function getRegions() + { + return $this->serviceDescription->getData('regions'); + } + + public function getRegion() + { + return $this->getConfig(Options::REGION); + } + + public function setRegion($region) + { + $config = $this->getConfig(); + $formerRegion = $config->get(Options::REGION); + $global = $this->serviceDescription->getData('globalEndpoint'); + $provider = $config->get('endpoint_provider'); + + if (!$provider) { + throw new \RuntimeException('No endpoint provider configured'); + } + + // Only change the region if the service does not have a global endpoint + if (!$global || $this->serviceDescription->getData('namespace') === 'S3') { + + $endpoint = call_user_func( + $provider, + array( + 'scheme' => $config->get(Options::SCHEME), + 'region' => $region, + 'service' => $config->get(Options::SERVICE) + ) + ); + + $this->setBaseUrl($endpoint['endpoint']); + $config->set(Options::BASE_URL, $endpoint['endpoint']); + $config->set(Options::REGION, $region); + + // Update the signature if necessary + $signature = $this->getSignature(); + if ($signature instanceof EndpointSignatureInterface) { + /** @var EndpointSignatureInterface $signature */ + $signature->setRegionName($region); + } + + // Dispatch an event that the region has been changed + $this->dispatch('client.region_changed', array( + 'region' => $region, + 'former_region' => $formerRegion, + )); + } + + return $this; + } + + public function waitUntil($waiter, array $input = array()) + { + $this->getWaiter($waiter, $input)->wait(); + + return $this; + } + + public function getWaiter($waiter, array $input = array()) + { + return $this->getWaiterFactory()->build($waiter) + ->setClient($this) + ->setConfig($input); + } + + public function setWaiterFactory(WaiterFactoryInterface $waiterFactory) + { + $this->waiterFactory = $waiterFactory; + + return $this; + } + + public function getWaiterFactory() + { + if (!$this->waiterFactory) { + $clientClass = get_class($this); + // Use a composite factory that checks for classes first, then config waiters + $this->waiterFactory = new CompositeWaiterFactory(array( + new WaiterClassFactory(substr($clientClass, 0, strrpos($clientClass, '\\')) . '\\Waiter') + )); + if ($this->getDescription()) { + $waiterConfig = $this->getDescription()->getData('waiters') ?: array(); + $this->waiterFactory->addFactory(new WaiterConfigFactory($waiterConfig)); + } + } + + return $this->waiterFactory; + } + + public function getApiVersion() + { + return $this->serviceDescription->getApiVersion(); + } + + /** + * {@inheritdoc} + * @throws \Aws\Common\Exception\TransferException + */ + public function send($requests) + { + try { + return parent::send($requests); + } catch (CurlException $e) { + $wrapped = new TransferException($e->getMessage(), null, $e); + $wrapped->setCurlHandle($e->getCurlHandle()) + ->setCurlInfo($e->getCurlInfo()) + ->setError($e->getError(), $e->getErrorNo()) + ->setRequest($e->getRequest()); + throw $wrapped; + } + } + + /** + * Ensures that the duplicate query string aggregator is used so that + * query string values are sent over the wire as foo=bar&foo=baz. + * {@inheritdoc} + */ + public function createRequest( + $method = 'GET', + $uri = null, + $headers = null, + $body = null, + array $options = array() + ) { + $request = parent::createRequest($method, $uri, $headers, $body, $options); + $request->getQuery()->setAggregator($this->aggregator); + return $request; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Client/AwsClientInterface.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Client/AwsClientInterface.php new file mode 100644 index 0000000..4c0579f --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Client/AwsClientInterface.php @@ -0,0 +1,118 @@ + 'https'); + + /** + * @var array Default client requirements + */ + protected static $commonConfigRequirements = array(Options::SERVICE_DESCRIPTION); + + /** + * @var string The namespace of the client + */ + protected $clientNamespace; + + /** + * @var array The config options + */ + protected $config = array(); + + /** + * @var array The config defaults + */ + protected $configDefaults = array(); + + /** + * @var array The config requirements + */ + protected $configRequirements = array(); + + /** + * @var ExceptionParserInterface The Parser interface for the client + */ + protected $exceptionParser; + + /** + * @var array Array of configuration data for iterators available for the client + */ + protected $iteratorsConfig = array(); + + /** @var string */ + private $clientClass; + + /** @var string */ + private $serviceName; + + /** + * Factory method for creating the client builder + * + * @param string $namespace The namespace of the client + * + * @return ClientBuilder + */ + public static function factory($namespace = null) + { + return new static($namespace); + } + + /** + * Constructs a client builder + * + * @param string $namespace The namespace of the client + */ + public function __construct($namespace = null) + { + $this->clientNamespace = $namespace; + + // Determine service and class name + $this->clientClass = 'Aws\Common\Client\DefaultClient'; + + if ($this->clientNamespace) { + $this->serviceName = substr($this->clientNamespace, strrpos($this->clientNamespace, '\\') + 1); + $this->clientClass = $this->clientNamespace . '\\' . $this->serviceName . 'Client'; + } + } + + /** + * Sets the config options + * + * @param array|Collection $config The config options + * + * @return ClientBuilder + */ + public function setConfig($config) + { + $this->config = $this->processArray($config); + + return $this; + } + + /** + * Sets the config options' defaults + * + * @param array|Collection $defaults The default values + * + * @return ClientBuilder + */ + public function setConfigDefaults($defaults) + { + $this->configDefaults = $this->processArray($defaults); + + return $this; + } + + /** + * Sets the required config options + * + * @param array|Collection $required The required config options + * + * @return ClientBuilder + */ + public function setConfigRequirements($required) + { + $this->configRequirements = $this->processArray($required); + + return $this; + } + + /** + * Sets the exception parser. If one is not provided the builder will use + * the default XML exception parser. + * + * @param ExceptionParserInterface $parser The exception parser + * + * @return ClientBuilder + */ + public function setExceptionParser(ExceptionParserInterface $parser) + { + $this->exceptionParser = $parser; + + return $this; + } + + /** + * Set the configuration for the client's iterators + * + * @param array $config Configuration data for client's iterators + * + * @return ClientBuilder + */ + public function setIteratorsConfig(array $config) + { + $this->iteratorsConfig = $config; + + return $this; + } + + /** + * Performs the building logic using all of the parameters that have been + * set and falling back to default values. Returns an instantiate service + * client with credentials prepared and plugins attached. + * + * @return AwsClientInterface + * @throws InvalidArgumentException + */ + public function build() + { + // Resolve configuration + $config = Collection::fromConfig( + $this->config, + array_merge(self::$commonConfigDefaults, $this->configDefaults), + (self::$commonConfigRequirements + $this->configRequirements) + ); + + if ($config[Options::VERSION] === 'latest') { + $config[Options::VERSION] = constant("{$this->clientClass}::LATEST_API_VERSION"); + } + + if (!isset($config['endpoint_provider'])) { + $config['endpoint_provider'] = RulesEndpointProvider::fromDefaults(); + } + + // Resolve the endpoint, signature, and credentials + $description = $this->updateConfigFromDescription($config); + $signature = $this->getSignature($description, $config); + $credentials = $this->getCredentials($config); + $this->extractHttpConfig($config); + + // Resolve exception parser + if (!$this->exceptionParser) { + $this->exceptionParser = new DefaultXmlExceptionParser(); + } + + // Resolve backoff strategy + $backoff = $config->get(Options::BACKOFF); + if ($backoff === null) { + $retries = isset($config[Options::BACKOFF_RETRIES]) ? $config[Options::BACKOFF_RETRIES] : 3; + $backoff = $this->createDefaultBackoff($retries); + $config->set(Options::BACKOFF, $backoff); + } + + if ($backoff) { + $this->addBackoffLogger($backoff, $config); + } + + /** @var AwsClientInterface $client */ + $client = new $this->clientClass($credentials, $signature, $config); + $client->setDescription($description); + + // Add exception marshaling so that more descriptive exception are thrown + if ($this->clientNamespace) { + $exceptionFactory = new NamespaceExceptionFactory( + $this->exceptionParser, + "{$this->clientNamespace}\\Exception", + "{$this->clientNamespace}\\Exception\\{$this->serviceName}Exception" + ); + $client->addSubscriber(new ExceptionListener($exceptionFactory)); + } + + // Add the UserAgentPlugin to append to the User-Agent header of requests + $client->addSubscriber(new UserAgentListener()); + + // Filters used for the cache plugin + $client->getConfig()->set( + 'params.cache.key_filter', + 'header=date,x-amz-date,x-amz-security-token,x-amzn-authorization' + ); + + // Set the iterator resource factory based on the provided iterators config + $client->setResourceIteratorFactory(new AwsResourceIteratorFactory( + $this->iteratorsConfig, + new ResourceIteratorClassFactory($this->clientNamespace . '\\Iterator') + )); + + // Disable parameter validation if needed + if ($config->get(Options::VALIDATION) === false) { + $params = $config->get('command.params') ?: array(); + $params['command.disable_validation'] = true; + $config->set('command.params', $params); + } + + return $client; + } + + /** + * Add backoff logging to the backoff plugin if needed + * + * @param BackoffPlugin $plugin Backoff plugin + * @param Collection $config Configuration settings + * + * @throws InvalidArgumentException + */ + protected function addBackoffLogger(BackoffPlugin $plugin, Collection $config) + { + // The log option can be set to `debug` or an instance of a LogAdapterInterface + if ($logger = $config->get(Options::BACKOFF_LOGGER)) { + $format = $config->get(Options::BACKOFF_LOGGER_TEMPLATE); + if ($logger === 'debug') { + $logger = new ClosureLogAdapter(function ($message) { + trigger_error($message . "\n"); + }); + } elseif (!($logger instanceof LogAdapterInterface)) { + throw new InvalidArgumentException( + Options::BACKOFF_LOGGER . ' must be set to `debug` or an instance of ' + . 'Guzzle\\Common\\Log\\LogAdapterInterface' + ); + } + // Create the plugin responsible for logging exponential backoff retries + $logPlugin = new BackoffLogger($logger); + // You can specify a custom format or use the default + if ($format) { + $logPlugin->setTemplate($format); + } + $plugin->addSubscriber($logPlugin); + } + } + + /** + * Ensures that an array (e.g. for config data) is actually in array form + * + * @param array|Collection $array The array data + * + * @return array + * @throws InvalidArgumentException if the arg is not an array or Collection + */ + protected function processArray($array) + { + if ($array instanceof Collection) { + $array = $array->getAll(); + } + + if (!is_array($array)) { + throw new InvalidArgumentException('The config must be provided as an array or Collection.'); + } + + return $array; + } + + /** + * Update a configuration object from a service description + * + * @param Collection $config Config to update + * + * @return ServiceDescription + * @throws InvalidArgumentException + */ + protected function updateConfigFromDescription(Collection $config) + { + $description = $config->get(Options::SERVICE_DESCRIPTION); + if (!($description instanceof ServiceDescription)) { + // Inject the version into the sprintf template if it is a string + if (is_string($description)) { + $description = sprintf($description, $config->get(Options::VERSION)); + } + $description = ServiceDescription::factory($description); + $config->set(Options::SERVICE_DESCRIPTION, $description); + } + + if (!$config->get(Options::SERVICE)) { + $config->set(Options::SERVICE, $description->getData('endpointPrefix')); + } + + if ($iterators = $description->getData('iterators')) { + $this->setIteratorsConfig($iterators); + } + + $this->handleRegion($config); + $this->handleEndpoint($config); + + return $description; + } + + /** + * Return an appropriate signature object for a a client based on the + * "signature" configuration setting, or the default signature specified in + * a service description. The signature can be set to a valid signature + * version identifier string or an instance of Aws\Common\Signature\SignatureInterface. + * + * @param ServiceDescription $description Description that holds a signature option + * @param Collection $config Configuration options + * + * @return SignatureInterface + * @throws InvalidArgumentException + */ + protected function getSignature(ServiceDescription $description, Collection $config) + { + // If a custom signature has not been provided, then use the default + // signature setting specified in the service description. + $signature = $config->get(Options::SIGNATURE) ?: $description->getData('signatureVersion'); + + if (is_string($signature)) { + if ($signature == 'v4') { + $signature = new SignatureV4(); + } elseif ($signature == 'v2') { + $signature = new SignatureV2(); + } elseif ($signature == 'v3https') { + $signature = new SignatureV3Https(); + } else { + throw new InvalidArgumentException("Invalid signature type: {$signature}"); + } + } elseif (!($signature instanceof SignatureInterface)) { + throw new InvalidArgumentException('The provided signature is not ' + . 'a signature version string or an instance of ' + . 'Aws\\Common\\Signature\\SignatureInterface'); + } + + // Allow a custom service name or region value to be provided + if ($signature instanceof EndpointSignatureInterface) { + + // Determine the service name to use when signing + $signature->setServiceName($config->get(Options::SIGNATURE_SERVICE) + ?: $description->getData('signingName') + ?: $description->getData('endpointPrefix')); + + // Determine the region to use when signing requests + $signature->setRegionName($config->get(Options::SIGNATURE_REGION) ?: $config->get(Options::REGION)); + } + + return $signature; + } + + protected function getCredentials(Collection $config) + { + $credentials = $config->get(Options::CREDENTIALS); + + if (is_array($credentials)) { + $credentials = Credentials::factory($credentials); + } elseif ($credentials === false) { + $credentials = new NullCredentials(); + } elseif (!$credentials instanceof CredentialsInterface) { + $credentials = Credentials::factory($config); + } + + return $credentials; + } + + private function handleRegion(Collection $config) + { + // Make sure a valid region is set + $region = $config[Options::REGION]; + $description = $config[Options::SERVICE_DESCRIPTION]; + $global = $description->getData('globalEndpoint'); + + if (!$global && !$region) { + throw new InvalidArgumentException( + 'A region is required when using ' . $description->getData('serviceFullName') + ); + } elseif ($global && !$region) { + $config[Options::REGION] = 'us-east-1'; + } + } + + private function handleEndpoint(Collection $config) + { + // Alias "endpoint" with "base_url" for forwards compatibility. + if ($config['endpoint']) { + $config[Options::BASE_URL] = $config['endpoint']; + return; + } + + if ($config[Options::BASE_URL]) { + return; + } + + $endpoint = call_user_func( + $config['endpoint_provider'], + array( + 'scheme' => $config[Options::SCHEME], + 'region' => $config[Options::REGION], + 'service' => $config[Options::SERVICE] + ) + ); + + $config[Options::BASE_URL] = $endpoint['endpoint']; + + // Set a signature if one was not explicitly provided. + if (!$config->hasKey(Options::SIGNATURE) + && isset($endpoint['signatureVersion']) + ) { + $config->set(Options::SIGNATURE, $endpoint['signatureVersion']); + } + + // The the signing region if endpoint rule specifies one. + if (isset($endpoint['credentialScope'])) { + $scope = $endpoint['credentialScope']; + if (isset($scope['region'])) { + $config->set(Options::SIGNATURE_REGION, $scope['region']); + } + } + } + + private function createDefaultBackoff($retries = 3) + { + return new BackoffPlugin( + // Retry failed requests up to 3 times if it is determined that the request can be retried + new TruncatedBackoffStrategy($retries, + // Retry failed requests with 400-level responses due to throttling + new ThrottlingErrorChecker($this->exceptionParser, + // Retry failed requests due to transient network or cURL problems + new CurlBackoffStrategy(null, + // Retry failed requests with 500-level responses + new HttpBackoffStrategy(array(500, 503, 509), + // Retry requests that failed due to expired credentials + new ExpiredCredentialsChecker($this->exceptionParser, + new ExponentialBackoffStrategy() + ) + ) + ) + ) + ) + ); + } + + private function extractHttpConfig(Collection $config) + { + $http = $config['http']; + + if (!is_array($http)) { + return; + } + + if (isset($http['verify'])) { + $config[Options::SSL_CERT] = $http['verify']; + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Client/DefaultClient.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Client/DefaultClient.php new file mode 100644 index 0000000..277f088 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Client/DefaultClient.php @@ -0,0 +1,67 @@ +setConfig($config) + ->setConfigDefaults(array(Options::SCHEME => 'https')) + ->build(); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Client/ExpiredCredentialsChecker.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Client/ExpiredCredentialsChecker.php new file mode 100644 index 0000000..05b8445 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Client/ExpiredCredentialsChecker.php @@ -0,0 +1,80 @@ + true, + 'ExpiredTokenException' => true, + 'ExpiredToken' => true + ); + + /** + * @var ExceptionParserInterface Exception parser used to parse exception responses + */ + protected $exceptionParser; + + public function __construct(ExceptionParserInterface $exceptionParser, BackoffStrategyInterface $next = null) { + $this->exceptionParser = $exceptionParser; + $this->next = $next; + } + + public function makesDecision() + { + return true; + } + + protected function getDelay($retries, RequestInterface $request, Response $response = null, HttpException $e = null) + { + if ($response && $response->isClientError()) { + + $parts = $this->exceptionParser->parse($request, $response); + if (!isset($this->retryable[$parts['code']]) || !$request->getClient()) { + return null; + } + + /** @var AwsClientInterface $client */ + $client = $request->getClient(); + // Only retry if the credentials can be refreshed + if (!($client->getCredentials() instanceof AbstractRefreshableCredentials)) { + return null; + } + + // Resign the request using new credentials + $client->getSignature()->signRequest($request, $client->getCredentials()->setExpiration(-1)); + + // Retry immediately with no delay + return 0; + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Client/ThrottlingErrorChecker.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Client/ThrottlingErrorChecker.php new file mode 100644 index 0000000..a35cbcb --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Client/ThrottlingErrorChecker.php @@ -0,0 +1,75 @@ + true, + 'Throttling' => true, + 'ThrottlingException' => true, + 'ProvisionedThroughputExceededException' => true, + 'RequestThrottled' => true, + ); + + /** + * @var ExceptionParserInterface Exception parser used to parse exception responses + */ + protected $exceptionParser; + + public function __construct(ExceptionParserInterface $exceptionParser, BackoffStrategyInterface $next = null) + { + $this->exceptionParser = $exceptionParser; + if ($next) { + $this->setNext($next); + } + } + + /** + * {@inheritdoc} + */ + public function makesDecision() + { + return true; + } + + /** + * {@inheritdoc} + */ + protected function getDelay( + $retries, + RequestInterface $request, + Response $response = null, + HttpException $e = null + ) { + if ($response && $response->isClientError()) { + $parts = $this->exceptionParser->parse($request, $response); + return isset(self::$throttlingExceptions[$parts['code']]) ? true : null; + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Client/UploadBodyListener.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Client/UploadBodyListener.php new file mode 100644 index 0000000..10cd825 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Client/UploadBodyListener.php @@ -0,0 +1,95 @@ +commands = $commands; + $this->bodyParameter = (string) $bodyParameter; + $this->sourceParameter = (string) $sourceParameter; + } + + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents() + { + return array('command.before_prepare' => array('onCommandBeforePrepare')); + } + + /** + * Converts filenames and file handles into EntityBody objects before the command is validated + * + * @param Event $event Event emitted + * @throws InvalidArgumentException + */ + public function onCommandBeforePrepare(Event $event) + { + /** @var Command $command */ + $command = $event['command']; + if (in_array($command->getName(), $this->commands)) { + // Get the interesting parameters + $source = $command->get($this->sourceParameter); + $body = $command->get($this->bodyParameter); + + // If a file path is passed in then get the file handle + if (is_string($source) && file_exists($source)) { + $body = fopen($source, 'r'); + } + + // Prepare the body parameter and remove the source file parameter + if (null !== $body) { + $command->remove($this->sourceParameter); + $command->set($this->bodyParameter, EntityBody::factory($body)); + } else { + throw new InvalidArgumentException("You must specify a non-null value for the {$this->bodyParameter} or {$this->sourceParameter} parameters."); + } + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Client/UserAgentListener.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Client/UserAgentListener.php new file mode 100644 index 0000000..cc7e312 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Client/UserAgentListener.php @@ -0,0 +1,61 @@ + 'onBeforeSend'); + } + + /** + * Adds strings to the User-Agent header using the `ua.append` parameter of a command + * + * @param Event $event Event emitted + */ + public function onBeforeSend(Event $event) + { + $command = $event['command']; + if ($userAgentAppends = $command->get(self::OPTION)) { + $request = $command->getRequest(); + $userAgent = (string) $request->getHeader('User-Agent'); + foreach ((array) $userAgentAppends as $append) { + $append = ' ' . $append; + if (strpos($userAgent, $append) === false) { + $userAgent .= $append; + } + } + $request->setHeader('User-Agent', $userAgent); + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Command/AwsQueryVisitor.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Command/AwsQueryVisitor.php new file mode 100644 index 0000000..a335c7b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Command/AwsQueryVisitor.php @@ -0,0 +1,120 @@ +fqname = $command->getName(); + $query = array(); + $this->customResolver($value, $param, $query, $param->getWireName()); + $request->addPostFields($query); + } + + /** + * Map nested parameters into the location_key based parameters + * + * @param array $value Value to map + * @param Parameter $param Parameter that holds information about the current key + * @param array $query Built up query string values + * @param string $prefix String to prepend to sub query values + */ + protected function customResolver($value, Parameter $param, array &$query, $prefix = '') + { + switch ($param->getType()) { + case 'object': + $this->resolveObject($param, $value, $prefix, $query); + break; + case 'array': + $this->resolveArray($param, $value, $prefix, $query); + break; + default: + $query[$prefix] = $param->filter($value); + } + } + + /** + * Custom handling for objects + * + * @param Parameter $param Parameter for the object + * @param array $value Value that is set for this parameter + * @param string $prefix Prefix for the resulting key + * @param array $query Query string array passed by reference + */ + protected function resolveObject(Parameter $param, array $value, $prefix, array &$query) + { + // Maps are implemented using additional properties + $hasAdditionalProperties = ($param->getAdditionalProperties() instanceof Parameter); + $additionalPropertyCount = 0; + + foreach ($value as $name => $v) { + if ($subParam = $param->getProperty($name)) { + // if the parameter was found by name as a regular property + $key = $prefix . '.' . $subParam->getWireName(); + $this->customResolver($v, $subParam, $query, $key); + } elseif ($hasAdditionalProperties) { + // Handle map cases like &Attribute.1.Name=&Attribute.1.Value= + $additionalPropertyCount++; + $data = $param->getData(); + $keyName = isset($data['keyName']) ? $data['keyName'] : 'key'; + $valueName = isset($data['valueName']) ? $data['valueName'] : 'value'; + $query["{$prefix}.{$additionalPropertyCount}.{$keyName}"] = $name; + $newPrefix = "{$prefix}.{$additionalPropertyCount}.{$valueName}"; + if (is_array($v)) { + $this->customResolver($v, $param->getAdditionalProperties(), $query, $newPrefix); + } else { + $query[$newPrefix] = $param->filter($v); + } + } + } + } + + /** + * Custom handling for arrays + * + * @param Parameter $param Parameter for the object + * @param array $value Value that is set for this parameter + * @param string $prefix Prefix for the resulting key + * @param array $query Query string array passed by reference + */ + protected function resolveArray(Parameter $param, array $value, $prefix, array &$query) + { + static $serializeEmpty = array( + 'SetLoadBalancerPoliciesForBackendServer' => 1, + 'SetLoadBalancerPoliciesOfListener' => 1, + 'UpdateStack' => 1 + ); + + // For BC, serialize empty lists for specific operations + if (!$value) { + if (isset($serializeEmpty[$this->fqname])) { + if (substr($prefix, -7) === '.member') { + $prefix = substr($prefix, 0, -7); + } + $query[$prefix] = ''; + } + return; + } + + $offset = $param->getData('offset') ?: 1; + foreach ($value as $index => $v) { + $index += $offset; + if (is_array($v) && $items = $param->getItems()) { + $this->customResolver($v, $items, $query, $prefix . '.' . $index); + } else { + $query[$prefix . '.' . $index] = $param->filter($v); + } + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Command/JsonCommand.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Command/JsonCommand.php new file mode 100644 index 0000000..15ad593 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Command/JsonCommand.php @@ -0,0 +1,47 @@ +request->getBody()) { + $this->request->setBody('{}'); + } + + // Never send the Expect header when interacting with a JSON query service + $this->request->removeHeader('Expect'); + + // Always send JSON requests as a raw string rather than using streams to avoid issues with + // cURL error code 65: "necessary data rewind wasn't possible". + // This could be removed after PHP addresses https://bugs.php.net/bug.php?id=47204 + $this->request->getCurlOptions()->set(CurlHandle::BODY_AS_STRING, true); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Command/QueryCommand.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Command/QueryCommand.php new file mode 100644 index 0000000..63eb8e8 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Command/QueryCommand.php @@ -0,0 +1,53 @@ +getRequestSerializer()->addVisitor('aws.query', self::$queryVisitor); + $this->getResponseParser()->addVisitor('xml', self::$xmlVisitor); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Command/XmlResponseLocationVisitor.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Command/XmlResponseLocationVisitor.php new file mode 100644 index 0000000..ad229fd --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Command/XmlResponseLocationVisitor.php @@ -0,0 +1,74 @@ +getOperation(); + if ($operation->getServiceDescription()->getData('resultWrapped')) { + $wrappingNode = $operation->getName() . 'Result'; + if (isset($result[$wrappingNode])) { + $result = $result[$wrappingNode] + $result; + unset($result[$wrappingNode]); + } + } + } + + /** + * Accounts for wrapper nodes + * {@inheritdoc} + */ + public function visit( + CommandInterface $command, + Response $response, + Parameter $param, + &$value, + $context = null + ) { + parent::visit($command, $response, $param, $value, $context); + + // Account for wrapper nodes (e.g. RDS, ElastiCache, etc) + if ($param->getData('wrapper')) { + $wireName = $param->getWireName(); + $value += $value[$wireName]; + unset($value[$wireName]); + } + } + + /** + * Filter used when converting XML maps into associative arrays in service descriptions + * + * @param array $value Value to filter + * @param string $entryName Name of each entry + * @param string $keyName Name of each key + * @param string $valueName Name of each value + * + * @return array Returns the map of the XML data + */ + public static function xmlMap($value, $entryName, $keyName, $valueName) + { + $result = array(); + foreach ($value as $entry) { + $result[$entry[$keyName]] = $entry[$valueName]; + } + + return $result; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Credentials/AbstractCredentialsDecorator.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Credentials/AbstractCredentialsDecorator.php new file mode 100644 index 0000000..b3a1df9 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Credentials/AbstractCredentialsDecorator.php @@ -0,0 +1,136 @@ +credentials = $credentials; + } + + /** + * {@inheritdoc} + */ + public function serialize() + { + return $this->credentials->serialize(); + } + + /** + * {@inheritdoc} + */ + public function unserialize($serialized) + { + $this->credentials = new Credentials('', ''); + $this->credentials->unserialize($serialized); + } + + /** + * {@inheritdoc} + */ + public function getAccessKeyId() + { + return $this->credentials->getAccessKeyId(); + } + + /** + * {@inheritdoc} + */ + public function getSecretKey() + { + return $this->credentials->getSecretKey(); + } + + /** + * {@inheritdoc} + */ + public function getSecurityToken() + { + return $this->credentials->getSecurityToken(); + } + + /** + * {@inheritdoc} + */ + public function getExpiration() + { + return $this->credentials->getExpiration(); + } + + /** + * {@inheritdoc} + */ + public function isExpired() + { + return $this->credentials->isExpired(); + } + + /** + * {@inheritdoc} + */ + public function setAccessKeyId($key) + { + $this->credentials->setAccessKeyId($key); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function setSecretKey($secret) + { + $this->credentials->setSecretKey($secret); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function setSecurityToken($token) + { + $this->credentials->setSecurityToken($token); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function setExpiration($timestamp) + { + $this->credentials->setExpiration($timestamp); + + return $this; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Credentials/AbstractRefreshableCredentials.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Credentials/AbstractRefreshableCredentials.php new file mode 100644 index 0000000..ebd957d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Credentials/AbstractRefreshableCredentials.php @@ -0,0 +1,95 @@ +credentials->isExpired()) { + $this->refresh(); + } + + return new Credentials( + $this->credentials->getAccessKeyId(), + $this->credentials->getSecretKey(), + $this->credentials->getSecurityToken(), + $this->credentials->getExpiration() + ); + } + + /** + * {@inheritdoc} + */ + public function getAccessKeyId() + { + if ($this->credentials->isExpired()) { + $this->refresh(); + } + + return $this->credentials->getAccessKeyId(); + } + + /** + * {@inheritdoc} + */ + public function getSecretKey() + { + if ($this->credentials->isExpired()) { + $this->refresh(); + } + + return $this->credentials->getSecretKey(); + } + + /** + * {@inheritdoc} + */ + public function getSecurityToken() + { + if ($this->credentials->isExpired()) { + $this->refresh(); + } + + return $this->credentials->getSecurityToken(); + } + + /** + * {@inheritdoc} + */ + public function serialize() + { + if ($this->credentials->isExpired()) { + $this->refresh(); + } + + return $this->credentials->serialize(); + } + + /** + * Attempt to get new credentials + */ + abstract protected function refresh(); +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Credentials/CacheableCredentials.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Credentials/CacheableCredentials.php new file mode 100644 index 0000000..44e6cf3 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Credentials/CacheableCredentials.php @@ -0,0 +1,74 @@ +cache = $cache; + $this->cacheKey = $cacheKey; + + parent::__construct($credentials); + } + + /** + * Attempt to get new credentials from cache or from the adapted object + */ + protected function refresh() + { + if (!$cache = $this->cache->fetch($this->cacheKey)) { + // The credentials were not found, so try again and cache if new + $this->credentials->getAccessKeyId(); + if (!$this->credentials->isExpired()) { + // The credentials were updated, so cache them + $this->cache->save($this->cacheKey, $this->credentials, $this->credentials->getExpiration() - time()); + } + } else { + // The credentials were found in cache, so update the adapter object + // if the cached credentials are not expired + if (!$cache->isExpired()) { + $this->credentials->setAccessKeyId($cache->getAccessKeyId()); + $this->credentials->setSecretKey($cache->getSecretKey()); + $this->credentials->setSecurityToken($cache->getSecurityToken()); + $this->credentials->setExpiration($cache->getExpiration()); + } + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Credentials/Credentials.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Credentials/Credentials.php new file mode 100644 index 0000000..bc95334 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Credentials/Credentials.php @@ -0,0 +1,352 @@ + null, + Options::SECRET => null, + Options::TOKEN => null, + Options::TOKEN_TTD => null, + Options::PROFILE => null, + Options::CREDENTIALS_CACHE => null, + Options::CREDENTIALS_CACHE_KEY => null, + Options::CREDENTIALS_CLIENT => null + ); + } + + /** + * Factory method for creating new credentials. This factory method will + * create the appropriate credentials object with appropriate decorators + * based on the passed configuration options. + * + * @param array $config Options to use when instantiating the credentials + * + * @return CredentialsInterface + * @throws InvalidArgumentException If the caching options are invalid + * @throws RuntimeException If using the default cache and APC is disabled + */ + public static function factory($config = array()) + { + // Add default key values + foreach (self::getConfigDefaults() as $key => $value) { + if (!isset($config[$key])) { + $config[$key] = $value; + } + } + + // Set up the cache + $cache = $config[Options::CREDENTIALS_CACHE]; + $cacheKey = $config[Options::CREDENTIALS_CACHE_KEY] ?: + 'credentials_' . ($config[Options::KEY] ?: crc32(gethostname())); + + if ( + $cacheKey && + $cache instanceof CacheAdapterInterface && + $cached = self::createFromCache($cache, $cacheKey) + ) { + return $cached; + } + + // Create the credentials object + if (!$config[Options::KEY] || !$config[Options::SECRET]) { + $credentials = self::createFromEnvironment($config); + } else { + // Instantiate using short or long term credentials + $credentials = new static( + $config[Options::KEY], + $config[Options::SECRET], + $config[Options::TOKEN], + $config[Options::TOKEN_TTD] + ); + } + + // Check if the credentials are refreshable, and if so, configure caching + $cache = $config[Options::CREDENTIALS_CACHE]; + if ($cacheKey && $cache) { + $credentials = self::createCache($credentials, $cache, $cacheKey); + } + + return $credentials; + } + + /** + * Create credentials from the credentials ini file in the HOME directory. + * + * @param string|null $profile Pass a specific profile to use. If no + * profile is specified we will attempt to use + * the value specified in the AWS_PROFILE + * environment variable. If AWS_PROFILE is not + * set, the "default" profile is used. + * @param string|null $filename Pass a string to specify the location of the + * credentials files. If null is passed, the + * SDK will attempt to find the configuration + * file at in your HOME directory at + * ~/.aws/credentials. + * @return CredentialsInterface + * @throws \RuntimeException if the file cannot be found, if the file is + * invalid, or if the profile is invalid. + */ + public static function fromIni($profile = null, $filename = null) + { + if (!$filename) { + $filename = self::getHomeDir() . '/.aws/credentials'; + } + + if (!$profile) { + $profile = self::getEnvVar(self::ENV_PROFILE) ?: 'default'; + } + + if (!is_readable($filename) || ($data = parse_ini_file($filename, true)) === false) { + throw new \RuntimeException("Invalid AWS credentials file: {$filename}."); + } + + if (!isset($data[$profile]['aws_access_key_id']) || !isset($data[$profile]['aws_secret_access_key'])) { + throw new \RuntimeException("Invalid AWS credentials profile {$profile} in {$filename}."); + } + + return new self( + $data[$profile]['aws_access_key_id'], + $data[$profile]['aws_secret_access_key'], + isset($data[$profile]['aws_security_token']) + ? $data[$profile]['aws_security_token'] + : null + ); + } + + /** + * Constructs a new BasicAWSCredentials object, with the specified AWS + * access key and AWS secret key + * + * @param string $accessKeyId AWS access key ID + * @param string $secretAccessKey AWS secret access key + * @param string $token Security token to use + * @param int $expiration UNIX timestamp for when credentials expire + */ + public function __construct($accessKeyId, $secretAccessKey, $token = null, $expiration = null) + { + $this->key = trim($accessKeyId); + $this->secret = trim($secretAccessKey); + $this->token = $token; + $this->ttd = $expiration; + } + + public function serialize() + { + return json_encode(array( + Options::KEY => $this->key, + Options::SECRET => $this->secret, + Options::TOKEN => $this->token, + Options::TOKEN_TTD => $this->ttd + )); + } + + public function unserialize($serialized) + { + $data = json_decode($serialized, true); + $this->key = $data[Options::KEY]; + $this->secret = $data[Options::SECRET]; + $this->token = $data[Options::TOKEN]; + $this->ttd = $data[Options::TOKEN_TTD]; + } + + public function getAccessKeyId() + { + return $this->key; + } + + public function getSecretKey() + { + return $this->secret; + } + + public function getSecurityToken() + { + return $this->token; + } + + public function getExpiration() + { + return $this->ttd; + } + + public function isExpired() + { + return $this->ttd !== null && time() >= $this->ttd; + } + + public function setAccessKeyId($key) + { + $this->key = $key; + + return $this; + } + + public function setSecretKey($secret) + { + $this->secret = $secret; + + return $this; + } + + public function setSecurityToken($token) + { + $this->token = $token; + + return $this; + } + + public function setExpiration($timestamp) + { + $this->ttd = $timestamp; + + return $this; + } + + /** + * When no keys are provided, attempt to create them based on the + * environment or instance profile credentials. + * + * @param array|Collection $config + * + * @return CredentialsInterface + */ + private static function createFromEnvironment($config) + { + // Get key and secret from ENV variables + $envKey = self::getEnvVar(self::ENV_KEY); + if (!($envSecret = self::getEnvVar(self::ENV_SECRET))) { + // Use AWS_SECRET_ACCESS_KEY if AWS_SECRET_KEY was not set + $envSecret = self::getEnvVar(self::ENV_SECRET_ACCESS_KEY); + } + + // Use credentials from the environment variables if available + if ($envKey && $envSecret) { + return new static($envKey, $envSecret); + } + + try { + // Use credentials from the INI file in HOME directory if available + return self::fromIni($config[Options::PROFILE]); + } catch (\RuntimeException $e) { + // Otherwise, try using instance profile credentials (available on EC2 instances) + return new RefreshableInstanceProfileCredentials( + new static('', '', '', 1), + $config[Options::CREDENTIALS_CLIENT] + ); + } + } + + private static function createFromCache(CacheAdapterInterface $cache, $cacheKey) + { + $cached = $cache->fetch($cacheKey); + if ($cached instanceof CredentialsInterface && !$cached->isExpired()) { + return new CacheableCredentials($cached, $cache, $cacheKey); + } + + return null; + } + + private static function createCache(CredentialsInterface $credentials, $cache, $cacheKey) + { + if ($cache === 'true' || $cache === true) { + // If no cache adapter was provided, then create one for the user + // @codeCoverageIgnoreStart + if (!extension_loaded('apc')) { + throw new RequiredExtensionNotLoadedException('PHP has not been compiled with APC. Unable to cache ' + . 'the credentials.'); + } elseif (!class_exists('Doctrine\Common\Cache\ApcCache')) { + throw new RuntimeException( + 'Cannot set ' . Options::CREDENTIALS_CACHE . ' to true because the Doctrine cache component is ' + . 'not installed. Either install doctrine/cache or pass in an instantiated ' + . 'Guzzle\Cache\CacheAdapterInterface object' + ); + } + // @codeCoverageIgnoreEnd + $cache = new DoctrineCacheAdapter(new \Doctrine\Common\Cache\ApcCache()); + } elseif (!($cache instanceof CacheAdapterInterface)) { + throw new InvalidArgumentException('Unable to utilize caching with the specified options'); + } + + // Decorate the credentials with a cache + return new CacheableCredentials($credentials, $cache, $cacheKey); + } + + private static function getHomeDir() + { + // On Linux/Unix-like systems, use the HOME environment variable + if ($homeDir = self::getEnvVar('HOME')) { + return $homeDir; + } + + // Get the HOMEDRIVE and HOMEPATH values for Windows hosts + $homeDrive = self::getEnvVar('HOMEDRIVE'); + $homePath = self::getEnvVar('HOMEPATH'); + + return ($homeDrive && $homePath) ? $homeDrive . $homePath : null; + } + + /** + * Fetches the value of an environment variable by checking $_SERVER and getenv(). + * + * @param string $var Name of the environment variable + * + * @return mixed|null + */ + private static function getEnvVar($var) + { + return isset($_SERVER[$var]) ? $_SERVER[$var] : getenv($var); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Credentials/CredentialsInterface.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Credentials/CredentialsInterface.php new file mode 100644 index 0000000..dd43037 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Credentials/CredentialsInterface.php @@ -0,0 +1,96 @@ +setClient($client); + } + + public function setClient(InstanceMetadataClient $client = null) + { + $this->customClient = null !== $client; + $this->client = $client ?: InstanceMetadataClient::factory(); + } + + public function serialize() + { + $serializable = array( + 'credentials' => parent::serialize(), + 'customClient' => $this->customClient, + ); + + if ($this->customClient) { + $serializable['client'] = serialize($this->client); + } + + return json_encode($serializable); + } + + public function unserialize($value) + { + $serialized = json_decode($value, true); + parent::unserialize($serialized['credentials']); + $this->customClient = $serialized['customClient']; + $this->client = $this->customClient ? + unserialize($serialized['client']) + : InstanceMetadataClient::factory(); + } + + /** + * Attempt to get new credentials from the instance profile + * + * @throws InstanceProfileCredentialsException On error + */ + protected function refresh() + { + $credentials = $this->client->getInstanceProfileCredentials(); + // Expire the token 5 minutes early to pre-fetch before expiring. + $this->credentials->setAccessKeyId($credentials->getAccessKeyId()) + ->setSecretKey($credentials->getSecretKey()) + ->setSecurityToken($credentials->getSecurityToken()) + ->setExpiration($credentials->getExpiration() - 300); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Enum.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Enum.php new file mode 100644 index 0000000..7f4d356 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Enum.php @@ -0,0 +1,55 @@ +getConstants(); + } + + return self::$cache[$class]; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Enum/ClientOptions.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Enum/ClientOptions.php new file mode 100644 index 0000000..abc42f7 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Enum/ClientOptions.php @@ -0,0 +1,167 @@ +factory = $factory; + } + + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents() + { + return array('request.error' => array('onRequestError', -1)); + } + + /** + * Throws a more meaningful request exception if available + * + * @param Event $event Event emitted + */ + public function onRequestError(Event $event) + { + $e = $this->factory->fromResponse($event['request'], $event['response']); + $event->stopPropagation(); + throw $e; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Exception/InstanceProfileCredentialsException.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Exception/InstanceProfileCredentialsException.php new file mode 100644 index 0000000..fb1dcf1 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Exception/InstanceProfileCredentialsException.php @@ -0,0 +1,50 @@ +statusCode = $code; + } + + /** + * Get the error response code from the service + * + * @return string|null + */ + public function getStatusCode() + { + return $this->statusCode; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Exception/InvalidArgumentException.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Exception/InvalidArgumentException.php new file mode 100644 index 0000000..4360a00 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Exception/InvalidArgumentException.php @@ -0,0 +1,22 @@ +getMessage(), + 0, + $exception + ); + + $this->state = $state; + } + + /** + * Get the state of the transfer + * + * @return TransferStateInterface + */ + public function getState() + { + return $this->state; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Exception/NamespaceExceptionFactory.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Exception/NamespaceExceptionFactory.php new file mode 100644 index 0000000..6489069 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Exception/NamespaceExceptionFactory.php @@ -0,0 +1,103 @@ +parser = $parser; + $this->baseNamespace = $baseNamespace; + $this->defaultException = $defaultException; + } + + /** + * {@inheritdoc} + */ + public function fromResponse(RequestInterface $request, Response $response) + { + $parts = $this->parser->parse($request, $response); + + // Removing leading 'AWS.' and embedded periods + $className = $this->baseNamespace . '\\' . str_replace(array('AWS.', '.'), '', $parts['code']); + if (substr($className, -9) !== 'Exception') { + $className .= 'Exception'; + } + + $className = class_exists($className) ? $className : $this->defaultException; + + return $this->createException($className, $request, $response, $parts); + } + + /** + * Create an prepare an exception object + * + * @param string $className Name of the class to create + * @param RequestInterface $request Request + * @param Response $response Response received + * @param array $parts Parsed exception data + * + * @return \Exception + */ + protected function createException($className, RequestInterface $request, Response $response, array $parts) + { + $class = new $className($parts['message']); + + if ($class instanceof ServiceResponseException) { + $class->setExceptionCode($parts['code']); + $class->setExceptionType($parts['type']); + $class->setResponse($response); + $class->setRequest($request); + $class->setRequestId($parts['request_id']); + } + + return $class; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Exception/OutOfBoundsException.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Exception/OutOfBoundsException.php new file mode 100644 index 0000000..6738c0c --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Exception/OutOfBoundsException.php @@ -0,0 +1,22 @@ + null, + 'message' => null, + 'type' => $response->isClientError() ? 'client' : 'server', + 'request_id' => (string) $response->getHeader('x-amzn-RequestId'), + 'parsed' => null + ); + + // Parse the json and normalize key casings + if (null !== $json = json_decode($response->getBody(true), true)) { + $data['parsed'] = array_change_key_case($json); + } + + // Do additional, protocol-specific parsing and return the result + $data = $this->doParse($data, $response); + + // Remove "Fault" suffix from exception names + if (isset($data['code']) && strpos($data['code'], 'Fault')) { + $data['code'] = preg_replace('/^([a-zA-Z]+)Fault$/', '$1', $data['code']); + } + + return $data; + } + + /** + * Pull relevant exception data out of the parsed json + * + * @param array $data The exception data + * @param Response $response The response from the service containing the error + * + * @return array + */ + abstract protected function doParse(array $data, Response $response); +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Exception/Parser/DefaultXmlExceptionParser.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Exception/Parser/DefaultXmlExceptionParser.php new file mode 100644 index 0000000..9656760 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Exception/Parser/DefaultXmlExceptionParser.php @@ -0,0 +1,109 @@ + null, + 'message' => null, + 'type' => $response->isClientError() ? 'client' : 'server', + 'request_id' => null, + 'parsed' => null + ); + + $body = $response->getBody(true); + + if (!$body) { + $this->parseHeaders($request, $response, $data); + return $data; + } + + try { + $xml = new \SimpleXMLElement($body); + $this->parseBody($xml, $data); + return $data; + } catch (\Exception $e) { + // Gracefully handle parse errors. This could happen when the + // server responds with a non-XML response (e.g., private beta + // services). + $data['code'] = 'PhpInternalXmlParseError'; + $data['message'] = 'A non-XML response was received'; + return $data; + } + } + + /** + * Parses additional exception information from the response headers + * + * @param RequestInterface $request Request that was issued + * @param Response $response The response from the request + * @param array $data The current set of exception data + */ + protected function parseHeaders(RequestInterface $request, Response $response, array &$data) + { + $data['message'] = $response->getStatusCode() . ' ' . $response->getReasonPhrase(); + if ($requestId = $response->getHeader('x-amz-request-id')) { + $data['request_id'] = $requestId; + $data['message'] .= " (Request-ID: $requestId)"; + } + } + + /** + * Parses additional exception information from the response body + * + * @param \SimpleXMLElement $body The response body as XML + * @param array $data The current set of exception data + */ + protected function parseBody(\SimpleXMLElement $body, array &$data) + { + $data['parsed'] = $body; + + $namespaces = $body->getDocNamespaces(); + if (isset($namespaces[''])) { + // Account for the default namespace being defined and PHP not being able to handle it :( + $body->registerXPathNamespace('ns', $namespaces['']); + $prefix = 'ns:'; + } else { + $prefix = ''; + } + + if ($tempXml = $body->xpath("//{$prefix}Code[1]")) { + $data['code'] = (string) $tempXml[0]; + } + + if ($tempXml = $body->xpath("//{$prefix}Message[1]")) { + $data['message'] = (string) $tempXml[0]; + } + + $tempXml = $body->xpath("//{$prefix}RequestId[1]"); + if (empty($tempXml)) { + $tempXml = $body->xpath("//{$prefix}RequestID[1]"); + } + if (isset($tempXml[0])) { + $data['request_id'] = (string) $tempXml[0]; + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Exception/Parser/ExceptionParserInterface.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Exception/Parser/ExceptionParserInterface.php new file mode 100644 index 0000000..1b25d96 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Exception/Parser/ExceptionParserInterface.php @@ -0,0 +1,42 @@ +getHeader('x-amzn-ErrorType')) { + $data['code'] = substr($code, 0, strpos($code, ':')); + } + + return $data; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Exception/RequiredExtensionNotLoadedException.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Exception/RequiredExtensionNotLoadedException.php new file mode 100644 index 0000000..c4a072c --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Exception/RequiredExtensionNotLoadedException.php @@ -0,0 +1,22 @@ +exceptionCode = $code; + } + + /** + * Get the exception code + * + * @return string|null + */ + public function getExceptionCode() + { + return $this->exceptionCode; + } + + /** + * Set the exception type + * + * @param string $type Exception type + */ + public function setExceptionType($type) + { + $this->exceptionType = $type; + } + + /** + * Get the exception type (one of client or server) + * + * @return string|null + */ + public function getExceptionType() + { + return $this->exceptionType; + } + + /** + * Set the request ID + * + * @param string $id Request ID + */ + public function setRequestId($id) + { + $this->requestId = $id; + } + + /** + * Get the Request ID + * + * @return string|null + */ + public function getRequestId() + { + return $this->requestId; + } + + /** + * Set the associated response + * + * @param Response $response Response + */ + public function setResponse(Response $response) + { + $this->response = $response; + } + + /** + * Get the associated response object + * + * @return Response|null + */ + public function getResponse() + { + return $this->response; + } + + /** + * Set the associated request + * + * @param RequestInterface $request + */ + public function setRequest(RequestInterface $request) + { + $this->request = $request; + } + + /** + * Get the associated request object + * + * @return RequestInterface|null + */ + public function getRequest() + { + return $this->request; + } + + /** + * Get the status code of the response + * + * @return int|null + */ + public function getStatusCode() + { + return $this->response ? $this->response->getStatusCode() : null; + } + + /** + * Cast to a string + * + * @return string + */ + public function __toString() + { + $message = get_class($this) . ': ' + . 'AWS Error Code: ' . $this->getExceptionCode() . ', ' + . 'Status Code: ' . $this->getStatusCode() . ', ' + . 'AWS Request ID: ' . $this->getRequestId() . ', ' + . 'AWS Error Type: ' . $this->getExceptionType() . ', ' + . 'AWS Error Message: ' . $this->getMessage(); + + // Add the User-Agent if available + if ($this->request) { + $message .= ', ' . 'User-Agent: ' . $this->request->getHeader('User-Agent'); + } + + return $message; + } + + /** + * Get the request ID of the error. This value is only present if a + * response was received, and is not present in the event of a networking + * error. + * + * Same as `getRequestId()` method, but matches the interface for SDKv3. + * + * @return string|null Returns null if no response was received + */ + public function getAwsRequestId() + { + return $this->requestId; + } + + /** + * Get the AWS error type. + * + * Same as `getExceptionType()` method, but matches the interface for SDKv3. + * + * @return string|null Returns null if no response was received + */ + public function getAwsErrorType() + { + return $this->exceptionType; + } + + /** + * Get the AWS error code. + * + * Same as `getExceptionCode()` method, but matches the interface for SDKv3. + * + * @return string|null Returns null if no response was received + */ + public function getAwsErrorCode() + { + return $this->exceptionCode; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Exception/TransferException.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Exception/TransferException.php new file mode 100644 index 0000000..47aa80d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Exception/TransferException.php @@ -0,0 +1,24 @@ +getConfig() as $service) { + if (isset($service['alias'], $service['class'])) { + $facadeClass = __NAMESPACE__ . '\\' . $service['alias']; + $facadeAlias = ltrim($targetNamespace . '\\' . $service['alias'], '\\'); + if (!class_exists($facadeAlias) && class_exists($facadeClass)) { + // @codeCoverageIgnoreStart + class_alias($facadeClass, $facadeAlias); + // @codeCoverageIgnoreEnd + } + } + } + } + + /** + * Returns the instance of the client that the facade operates on + * + * @return \Aws\Common\Client\AwsClientInterface + */ + public static function getClient() + { + return self::$serviceBuilder->get(static::getServiceBuilderKey()); + } + + public static function __callStatic($method, $args) + { + return call_user_func_array(array(self::getClient(), $method), $args); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Facade/FacadeInterface.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Facade/FacadeInterface.php new file mode 100644 index 0000000..c00c32d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Facade/FacadeInterface.php @@ -0,0 +1,34 @@ +context = hash_init($algorithm); + } + + /** + * {@inheritdoc} + */ + public function addData($data) + { + if (!$this->context) { + throw new LogicException('You may not add more data to a finalized chunk hash.'); + } + + hash_update($this->context, $data); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function getHash($returnBinaryForm = false) + { + if (!$this->hash) { + $this->hashRaw = hash_final($this->context, true); + $this->hash = HashUtils::binToHex($this->hashRaw); + $this->context = null; + } + + return $returnBinaryForm ? $this->hashRaw : $this->hash; + } + + /** + * {@inheritdoc} + */ + public function __clone() + { + if ($this->context) { + $this->context = hash_copy($this->context); + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Hash/ChunkHashInterface.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Hash/ChunkHashInterface.php new file mode 100644 index 0000000..5fcf9a5 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Hash/ChunkHashInterface.php @@ -0,0 +1,52 @@ +checksums = $inBinaryForm ? $checksums : array_map('Aws\Common\Hash\HashUtils::hexToBin', $checksums); + + // Pre-calculate hash + $treeHash->getHash(); + + return $treeHash; + } + + /** + * Create a tree hash from a content body + * + * @param string|resource|EntityBody $content Content to create a tree hash for + * @param string $algorithm A valid hash algorithm name as returned by `hash_algos()` + * + * @return TreeHash + */ + public static function fromContent($content, $algorithm = self::DEFAULT_ALGORITHM) + { + $treeHash = new self($algorithm); + + // Read the data in 1MB chunks and add to tree hash + $content = EntityBody::factory($content); + while ($data = $content->read(Size::MB)) { + $treeHash->addData($data); + } + + // Pre-calculate hash + $treeHash->getHash(); + + return $treeHash; + } + + /** + * Validates an entity body with a tree hash checksum + * + * @param string|resource|EntityBody $content Content to create a tree hash for + * @param string $checksum The checksum to use for validation + * @param string $algorithm A valid hash algorithm name as returned by `hash_algos()` + * + * @return bool + */ + public static function validateChecksum($content, $checksum, $algorithm = self::DEFAULT_ALGORITHM) + { + $treeHash = self::fromContent($content, $algorithm); + + return ($checksum === $treeHash->getHash()); + } + + /** + * {@inheritdoc} + */ + public function __construct($algorithm = self::DEFAULT_ALGORITHM) + { + HashUtils::validateAlgorithm($algorithm); + $this->algorithm = $algorithm; + } + + /** + * {@inheritdoc} + * @throws LogicException if the root tree hash is already calculated + * @throws InvalidArgumentException if the data is larger than 1MB + */ + public function addData($data) + { + // Error if hash is already calculated + if ($this->hash) { + throw new LogicException('You may not add more data to a finalized tree hash.'); + } + + // Make sure that only 1MB chunks or smaller get passed in + if (strlen($data) > Size::MB) { + throw new InvalidArgumentException('The chunk of data added is too large for tree hashing.'); + } + + // Store the raw hash of this data segment + $this->checksums[] = hash($this->algorithm, $data, true); + + return $this; + } + + /** + * Add a checksum to the tree hash directly + * + * @param string $checksum The checksum to add + * @param bool $inBinaryForm Whether or not the checksum is already in binary form + * + * @return self + * @throws LogicException if the root tree hash is already calculated + */ + public function addChecksum($checksum, $inBinaryForm = false) + { + // Error if hash is already calculated + if ($this->hash) { + throw new LogicException('You may not add more checksums to a finalized tree hash.'); + } + + // Convert the checksum to binary form if necessary + $this->checksums[] = $inBinaryForm ? $checksum : HashUtils::hexToBin($checksum); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function getHash($returnBinaryForm = false) + { + if (!$this->hash) { + // Perform hashes up the tree to arrive at the root checksum of the tree hash + $hashes = $this->checksums; + while (count($hashes) > 1) { + $sets = array_chunk($hashes, 2); + $hashes = array(); + foreach ($sets as $set) { + $hashes[] = (count($set) === 1) ? $set[0] : hash($this->algorithm, $set[0] . $set[1], true); + } + } + + $this->hashRaw = $hashes[0]; + $this->hash = HashUtils::binToHex($this->hashRaw); + } + + return $returnBinaryForm ? $this->hashRaw : $this->hash; + } + + /** + * @return array Array of raw checksums composing the tree hash + */ + public function getChecksums() + { + return $this->checksums; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/HostNameUtils.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/HostNameUtils.php new file mode 100644 index 0000000..4b791aa --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/HostNameUtils.php @@ -0,0 +1,85 @@ +getHost(), -14) != '.amazonaws.com') { + return self::DEFAULT_REGION; + } + + $serviceAndRegion = substr($url->getHost(), 0, -14); + // Special handling for S3 regions + $separator = strpos($serviceAndRegion, 's3') === 0 ? '-' : '.'; + $separatorPos = strpos($serviceAndRegion, $separator); + + // If don't detect a separator, then return the default region + if ($separatorPos === false) { + return self::DEFAULT_REGION; + } + + $region = substr($serviceAndRegion, $separatorPos + 1); + + // All GOV regions currently use the default GOV region + if ($region == 'us-gov') { + return self::DEFAULT_GOV_REGION; + } + + return $region; + } + + /** + * Parse the AWS service name from a URL + * + * @param Url $url HTTP URL + * + * @return string Returns a service name (or empty string) + * @link http://docs.aws.amazon.com/general/latest/gr/rande.html + */ + public static function parseServiceName(Url $url) + { + // The service name is the first part of the host + $parts = explode('.', $url->getHost(), 2); + + // Special handling for S3 + if (stripos($parts[0], 's3') === 0) { + return 's3'; + } + + return $parts[0]; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/InstanceMetadata/InstanceMetadataClient.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/InstanceMetadata/InstanceMetadataClient.php new file mode 100644 index 0000000..229be15 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/InstanceMetadata/InstanceMetadataClient.php @@ -0,0 +1,102 @@ + 'http://169.254.169.254/{version}/', + 'version' => 'latest', + 'request.options' => array( + 'connect_timeout' => 5, + 'timeout' => 10 + ) + ), array('base_url', 'version')); + + return new self($config); + } + + /** + * Constructor override + */ + public function __construct(Collection $config) + { + $this->setConfig($config); + $this->setBaseUrl($config->get(Options::BASE_URL)); + $this->defaultHeaders = new Collection(); + $this->setRequestFactory(RequestFactory::getInstance()); + } + + /** + * Get instance profile credentials + * + * @return Credentials + * @throws InstanceProfileCredentialsException + */ + public function getInstanceProfileCredentials() + { + try { + $request = $this->get('meta-data/iam/security-credentials/'); + $credentials = trim($request->send()->getBody(true)); + $result = $this->get("meta-data/iam/security-credentials/{$credentials}")->send()->json(); + } catch (\Exception $e) { + $message = sprintf('Error retrieving credentials from the instance profile metadata server. When you are' + . ' not running inside of Amazon EC2, you must provide your AWS access key ID and secret access key in' + . ' the "key" and "secret" options when creating a client or provide an instantiated' + . ' Aws\\Common\\Credentials\\CredentialsInterface object. (%s)', $e->getMessage()); + throw new InstanceProfileCredentialsException($message, $e->getCode()); + } + + // Ensure that the status code was successful + if ($result['Code'] !== 'Success') { + $e = new InstanceProfileCredentialsException('Unexpected response code: ' . $result['Code']); + $e->setStatusCode($result['Code']); + throw $e; + } + + return new Credentials( + $result['AccessKeyId'], + $result['SecretAccessKey'], + $result['Token'], + strtotime($result['Expiration']) + ); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/InstanceMetadata/Waiter/ServiceAvailable.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/InstanceMetadata/Waiter/ServiceAvailable.php new file mode 100644 index 0000000..ac305c3 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/InstanceMetadata/Waiter/ServiceAvailable.php @@ -0,0 +1,50 @@ +client->get(); + try { + $request->getCurlOptions()->set(CURLOPT_CONNECTTIMEOUT, 10) + ->set(CURLOPT_TIMEOUT, 10); + $request->send(); + + return true; + } catch (CurlException $e) { + return false; + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Iterator/AwsResourceIterator.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Iterator/AwsResourceIterator.php new file mode 100644 index 0000000..cdd8119 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Iterator/AwsResourceIterator.php @@ -0,0 +1,169 @@ +lastResult; + } + + /** + * {@inheritdoc} + * This AWS specific version of the resource iterator provides a default implementation of the typical AWS iterator + * process. It relies on configuration and extension to implement the operation-specific logic of handling results + * and nextTokens. This method will loop until resources are acquired or there are no more iterations available. + */ + protected function sendRequest() + { + do { + // Prepare the request including setting the next token + $this->prepareRequest(); + if ($this->nextToken) { + $this->applyNextToken(); + } + + // Execute the request and handle the results + $this->command->add(Ua::OPTION, Ua::ITERATOR); + $this->lastResult = $this->command->getResult(); + $resources = $this->handleResults($this->lastResult); + $this->determineNextToken($this->lastResult); + + // If no resources collected, prepare to reiterate before yielding + if ($reiterate = empty($resources) && $this->nextToken) { + $this->command = clone $this->originalCommand; + } + } while ($reiterate); + + return $resources; + } + + protected function prepareRequest() + { + // Get the limit parameter key to set + $limitKey = $this->get('limit_key'); + if ($limitKey && ($limit = $this->command->get($limitKey))) { + $pageSize = $this->calculatePageSize(); + + // If the limit of the command is different than the pageSize of the iterator, use the smaller value + if ($limit && $pageSize) { + $realLimit = min($limit, $pageSize); + $this->command->set($limitKey, $realLimit); + } + } + } + + protected function handleResults(Model $result) + { + $results = array(); + + // Get the result key that contains the results + if ($resultKey = $this->get('result_key')) { + $results = $this->getValueFromResult($result, $resultKey) ?: array(); + } + + return $results; + } + + protected function applyNextToken() + { + // Get the token parameter key to set + if ($tokenParam = $this->get('input_token')) { + // Set the next token. Works with multi-value tokens + if (is_array($tokenParam)) { + if (is_array($this->nextToken) && count($tokenParam) === count($this->nextToken)) { + foreach (array_combine($tokenParam, $this->nextToken) as $param => $token) { + $this->command->set($param, $token); + } + } else { + throw new RuntimeException('The definition of the iterator\'s token parameter and the actual token ' + . 'value are not compatible.'); + } + } else { + $this->command->set($tokenParam, $this->nextToken); + } + } + } + + protected function determineNextToken(Model $result) + { + $this->nextToken = null; + + // If the value of "more_results" is true or there is no "more_results" to check, then try to get the next token + $moreKey = $this->get('more_results'); + if ($moreKey === null || $this->getValueFromResult($result, $moreKey)) { + // Get the token key to check + if ($tokenKey = $this->get('output_token')) { + // Get the next token's value. Works with multi-value tokens + if (is_array($tokenKey)) { + $this->nextToken = array(); + foreach ($tokenKey as $key) { + $this->nextToken[] = $this->getValueFromResult($result, $key); + } + } else { + $this->nextToken = $this->getValueFromResult($result, $tokenKey); + } + } + } + } + + /** + * Extracts the value from the result using Collection::getPath. Also adds some additional logic for keys that need + * to access n-1 indexes (e.g., ImportExport, Kinesis). The n-1 logic only works for the known cases. We will switch + * to a jmespath implementation in the future to cover all cases + * + * @param Model $result + * @param string $key + * + * @return mixed|null + */ + protected function getValueFromResult(Model $result, $key) + { + // Special handling for keys that need to access n-1 indexes + if (strpos($key, '#') !== false) { + $keyParts = explode('#', $key, 2); + $items = $result->getPath(trim($keyParts[0], '/')); + if ($items && is_array($items)) { + $index = count($items) - 1; + $key = strtr($key, array('#' => $index)); + } + } + + // Get the value + return $result->getPath($key); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Iterator/AwsResourceIteratorFactory.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Iterator/AwsResourceIteratorFactory.php new file mode 100644 index 0000000..ce668a2 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Iterator/AwsResourceIteratorFactory.php @@ -0,0 +1,106 @@ + null, + 'output_token' => null, + 'limit_key' => null, + 'result_key' => null, + 'more_results' => null, + ); + + /** + * @var array Legacy configuration options mapped to their new names + */ + private static $legacyConfigOptions = array( + 'token_param' => 'input_token', + 'token_key' => 'output_token', + 'limit_param' => 'limit_key', + 'more_key' => 'more_results', + ); + + /** + * @var array Iterator configuration for each iterable operation + */ + protected $config; + + /** + * @var ResourceIteratorFactoryInterface Another factory that will be used first to instantiate the iterator + */ + protected $primaryIteratorFactory; + + /** + * @param array $config An array of configuration values for the factory + * @param ResourceIteratorFactoryInterface $primaryIteratorFactory Another factory to use for chain of command + */ + public function __construct(array $config, ResourceIteratorFactoryInterface $primaryIteratorFactory = null) + { + $this->primaryIteratorFactory = $primaryIteratorFactory; + $this->config = array(); + foreach ($config as $name => $operation) { + $this->config[$name] = $operation + self::$defaultIteratorConfig; + } + } + + public function build(CommandInterface $command, array $options = array()) + { + // Get the configuration data for the command + $commandName = $command->getName(); + $commandSupported = isset($this->config[$commandName]); + $options = $this->translateLegacyConfigOptions($options); + $options += $commandSupported ? $this->config[$commandName] : array(); + + // Instantiate the iterator using the primary factory (if one was provided) + if ($this->primaryIteratorFactory && $this->primaryIteratorFactory->canBuild($command)) { + $iterator = $this->primaryIteratorFactory->build($command, $options); + } elseif (!$commandSupported) { + throw new InvalidArgumentException("Iterator was not found for {$commandName}."); + } else { + // Instantiate a generic AWS resource iterator + $iterator = new AwsResourceIterator($command, $options); + } + + return $iterator; + } + + public function canBuild(CommandInterface $command) + { + if ($this->primaryIteratorFactory) { + return $this->primaryIteratorFactory->canBuild($command); + } else { + return isset($this->config[$command->getName()]); + } + } + + /** + * @param array $config The config for a single operation + * + * @return array The modified config with legacy options translated + */ + private function translateLegacyConfigOptions($config) + { + foreach (self::$legacyConfigOptions as $legacyOption => $newOption) { + if (isset($config[$legacyOption])) { + $config[$newOption] = $config[$legacyOption]; + unset($config[$legacyOption]); + } + } + + return $config; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Model/MultipartUpload/AbstractTransfer.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Model/MultipartUpload/AbstractTransfer.php new file mode 100644 index 0000000..751b558 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Model/MultipartUpload/AbstractTransfer.php @@ -0,0 +1,270 @@ +client = $client; + $this->state = $state; + $this->source = $source; + $this->options = $options; + + $this->init(); + + $this->partSize = $this->calculatePartSize(); + } + + public function __invoke() + { + return $this->upload(); + } + + /** + * {@inheritdoc} + */ + public static function getAllEvents() + { + return array( + self::BEFORE_PART_UPLOAD, + self::AFTER_UPLOAD, + self::BEFORE_PART_UPLOAD, + self::AFTER_PART_UPLOAD, + self::AFTER_ABORT, + self::AFTER_COMPLETE + ); + } + + /** + * {@inheritdoc} + */ + public function abort() + { + $command = $this->getAbortCommand(); + $result = $command->getResult(); + + $this->state->setAborted(true); + $this->stop(); + $this->dispatch(self::AFTER_ABORT, $this->getEventData($command)); + + return $result; + } + + /** + * {@inheritdoc} + */ + public function stop() + { + $this->stopped = true; + + return $this->state; + } + + /** + * {@inheritdoc} + */ + public function getState() + { + return $this->state; + } + + /** + * Get the array of options associated with the transfer + * + * @return array + */ + public function getOptions() + { + return $this->options; + } + + /** + * Set an option on the transfer + * + * @param string $option Name of the option + * @param mixed $value Value to set + * + * @return self + */ + public function setOption($option, $value) + { + $this->options[$option] = $value; + + return $this; + } + + /** + * Get the source body of the upload + * + * @return EntityBodyInterface + */ + public function getSource() + { + return $this->source; + } + + /** + * {@inheritdoc} + * @throws MultipartUploadException when an error is encountered. Use getLastException() to get more information. + * @throws RuntimeException when attempting to upload an aborted transfer + */ + public function upload() + { + if ($this->state->isAborted()) { + throw new RuntimeException('The transfer has been aborted and cannot be uploaded'); + } + + $this->stopped = false; + $eventData = $this->getEventData(); + $this->dispatch(self::BEFORE_UPLOAD, $eventData); + + try { + $this->transfer(); + $this->dispatch(self::AFTER_UPLOAD, $eventData); + + if ($this->stopped) { + return null; + } else { + $result = $this->complete(); + $this->dispatch(self::AFTER_COMPLETE, $eventData); + } + } catch (\Exception $e) { + throw new MultipartUploadException($this->state, $e); + } + + return $result; + } + + /** + * Get an array used for event notifications + * + * @param OperationCommand $command Command to include in event data + * + * @return array + */ + protected function getEventData(OperationCommand $command = null) + { + $data = array( + 'transfer' => $this, + 'source' => $this->source, + 'options' => $this->options, + 'client' => $this->client, + 'part_size' => $this->partSize, + 'state' => $this->state + ); + + if ($command) { + $data['command'] = $command; + } + + return $data; + } + + /** + * Hook to initialize the transfer + */ + protected function init() {} + + /** + * Determine the upload part size based on the size of the source data and + * taking into account the acceptable minimum and maximum part sizes. + * + * @return int The part size + */ + abstract protected function calculatePartSize(); + + /** + * Complete the multipart upload + * + * @return Model Returns the result of the complete multipart upload command + */ + abstract protected function complete(); + + /** + * Hook to implement in subclasses to perform the actual transfer + */ + abstract protected function transfer(); + + /** + * Fetches the abort command fom the concrete implementation + * + * @return OperationCommand + */ + abstract protected function getAbortCommand(); +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Model/MultipartUpload/AbstractTransferState.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Model/MultipartUpload/AbstractTransferState.php new file mode 100644 index 0000000..06d6c84 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Model/MultipartUpload/AbstractTransferState.php @@ -0,0 +1,164 @@ +uploadId = $uploadId; + } + + /** + * {@inheritdoc} + */ + public function getUploadId() + { + return $this->uploadId; + } + + /** + * Get a data value from the transfer state's uploadId + * + * @param string $key Key to retrieve (e.g. Bucket, Key, UploadId, etc) + * + * @return string|null + */ + public function getFromId($key) + { + $params = $this->uploadId->toParams(); + + return isset($params[$key]) ? $params[$key] : null; + } + + /** + * {@inheritdoc} + */ + public function getPart($partNumber) + { + return isset($this->parts[$partNumber]) ? $this->parts[$partNumber] : null; + } + + /** + * {@inheritdoc} + */ + public function addPart(UploadPartInterface $part) + { + $partNumber = $part->getPartNumber(); + $this->parts[$partNumber] = $part; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function hasPart($partNumber) + { + return isset($this->parts[$partNumber]); + } + + /** + * {@inheritdoc} + */ + public function getPartNumbers() + { + return array_keys($this->parts); + } + + /** + * {@inheritdoc} + */ + public function setAborted($aborted) + { + $this->aborted = (bool) $aborted; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function isAborted() + { + return $this->aborted; + } + + /** + * {@inheritdoc} + */ + public function count() + { + return count($this->parts); + } + + /** + * {@inheritdoc} + */ + public function getIterator() + { + return new \ArrayIterator($this->parts); + } + + /** + * {@inheritdoc} + */ + public function serialize() + { + return serialize(get_object_vars($this)); + } + + /** + * {@inheritdoc} + */ + public function unserialize($serialized) + { + $data = unserialize($serialized); + foreach (get_object_vars($this) as $property => $oldValue) { + if (array_key_exists($property, $data)) { + $this->{$property} = $data[$property]; + } else { + throw new RuntimeException("The {$property} property could be restored during unserialization."); + } + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Model/MultipartUpload/AbstractUploadBuilder.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Model/MultipartUpload/AbstractUploadBuilder.php new file mode 100644 index 0000000..8690d5c --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Model/MultipartUpload/AbstractUploadBuilder.php @@ -0,0 +1,148 @@ +client = $client; + + return $this; + } + + /** + * Set the state of the upload. This is useful for resuming from a previously started multipart upload. + * You must use a local file stream as the data source if you wish to resume from a previous upload. + * + * @param TransferStateInterface|string $state Pass a TransferStateInterface object or the ID of the initiated + * multipart upload. When an ID is passed, the builder will create a + * state object using the data from a ListParts API response. + * + * @return $this + */ + public function resumeFrom($state) + { + $this->state = $state; + + return $this; + } + + /** + * Set the data source of the transfer + * + * @param resource|string|EntityBody $source Source of the transfer. Pass a string to transfer from a file on disk. + * You can also stream from a resource returned from fopen or a Guzzle + * {@see EntityBody} object. + * + * @return $this + * @throws InvalidArgumentException when the source cannot be found or opened + */ + public function setSource($source) + { + // Use the contents of a file as the data source + if (is_string($source)) { + if (!file_exists($source)) { + throw new InvalidArgumentException("File does not exist: {$source}"); + } + // Clear the cache so that we send accurate file sizes + clearstatcache(true, $source); + $source = fopen($source, 'r'); + } + + $this->source = EntityBody::factory($source); + + if ($this->source->isSeekable() && $this->source->getSize() == 0) { + throw new InvalidArgumentException('Empty body provided to upload builder'); + } + + return $this; + } + + /** + * Specify the headers to set on the upload + * + * @param array $headers Headers to add to the uploaded object + * + * @return $this + */ + public function setHeaders(array $headers) + { + $this->headers = $headers; + + return $this; + } + + /** + * Build the appropriate uploader based on the builder options + * + * @return TransferInterface + */ + abstract public function build(); + + /** + * Initiate the multipart upload + * + * @return TransferStateInterface + */ + abstract protected function initiateMultipartUpload(); +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Model/MultipartUpload/AbstractUploadId.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Model/MultipartUpload/AbstractUploadId.php new file mode 100644 index 0000000..da79521 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Model/MultipartUpload/AbstractUploadId.php @@ -0,0 +1,89 @@ +loadData($data); + + return $uploadId; + } + + /** + * {@inheritdoc} + */ + public function toParams() + { + return $this->data; + } + + /** + * {@inheritdoc} + */ + public function serialize() + { + return serialize($this->data); + } + + /** + * {@inheritdoc} + */ + public function unserialize($serialized) + { + $this->loadData(unserialize($serialized)); + } + + /** + * Loads an array of data into the UploadId by extracting only the needed keys + * + * @param array $data Data to load + * + * @throws InvalidArgumentException if a required key is missing + */ + protected function loadData($data) + { + $data = array_replace(static::$expectedValues, array_intersect_key($data, static::$expectedValues)); + foreach ($data as $key => $value) { + if (isset($data[$key])) { + $this->data[$key] = $data[$key]; + } else { + throw new InvalidArgumentException("A required key [$key] was missing from the UploadId."); + } + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Model/MultipartUpload/AbstractUploadPart.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Model/MultipartUpload/AbstractUploadPart.php new file mode 100644 index 0000000..1cf4c6d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Model/MultipartUpload/AbstractUploadPart.php @@ -0,0 +1,101 @@ +loadData($data); + + return $part; + } + + /** + * {@inheritdoc} + */ + public function getPartNumber() + { + return $this->partNumber; + } + + /** + * {@inheritdoc} + */ + public function toArray() + { + $array = array(); + foreach (static::$keyMap as $key => $property) { + $array[$key] = $this->{$property}; + } + + return $array; + } + + /** + * {@inheritdoc} + */ + public function serialize() + { + return serialize($this->toArray()); + } + + /** + * {@inheritdoc} + */ + public function unserialize($serialized) + { + $this->loadData(unserialize($serialized)); + } + + /** + * Loads an array of data into the upload part by extracting only the needed keys + * + * @param array|\Traversable $data Data to load into the upload part value object + * + * @throws InvalidArgumentException if a required key is missing + */ + protected function loadData($data) + { + foreach (static::$keyMap as $key => $property) { + if (isset($data[$key])) { + $this->{$property} = $data[$key]; + } else { + throw new InvalidArgumentException("A required key [$key] was missing from the upload part."); + } + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Model/MultipartUpload/TransferInterface.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Model/MultipartUpload/TransferInterface.php new file mode 100644 index 0000000..1fc1ae9 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Model/MultipartUpload/TransferInterface.php @@ -0,0 +1,66 @@ + 'Aws\Common\Aws', + 'services' => array( + + 'default_settings' => array( + 'params' => array() + ), + + 'autoscaling' => array( + 'alias' => 'AutoScaling', + 'extends' => 'default_settings', + 'class' => 'Aws\AutoScaling\AutoScalingClient' + ), + + 'cloudformation' => array( + 'alias' => 'CloudFormation', + 'extends' => 'default_settings', + 'class' => 'Aws\CloudFormation\CloudFormationClient' + ), + + 'cloudfront' => array( + 'alias' => 'CloudFront', + 'extends' => 'default_settings', + 'class' => 'Aws\CloudFront\CloudFrontClient' + ), + + 'cloudfront_20120505' => array( + 'extends' => 'cloudfront', + 'params' => array( + 'version' => '2012-05-05' + ) + ), + + 'cloudhsm' => array( + 'alias' => 'CloudHsm', + 'extends' => 'default_settings', + 'class' => 'Aws\CloudHsm\CloudHsmClient' + ), + + 'cloudsearch' => array( + 'alias' => 'CloudSearch', + 'extends' => 'default_settings', + 'class' => 'Aws\CloudSearch\CloudSearchClient' + ), + + 'cloudsearch_20110201' => array( + 'extends' => 'cloudsearch', + 'params' => array( + 'version' => '2011-02-01' + ) + ), + + 'cloudsearchdomain' => array( + 'alias' => 'CloudSearchDomain', + 'extends' => 'default_settings', + 'class' => 'Aws\CloudSearchDomain\CloudSearchDomainClient' + ), + + 'cloudtrail' => array( + 'alias' => 'CloudTrail', + 'extends' => 'default_settings', + 'class' => 'Aws\CloudTrail\CloudTrailClient' + ), + + 'cloudwatch' => array( + 'alias' => 'CloudWatch', + 'extends' => 'default_settings', + 'class' => 'Aws\CloudWatch\CloudWatchClient' + ), + + 'cloudwatchlogs' => array( + 'alias' => 'CloudWatchLogs', + 'extends' => 'default_settings', + 'class' => 'Aws\CloudWatchLogs\CloudWatchLogsClient' + ), + + 'cognito-identity' => array( + 'alias' => 'CognitoIdentity', + 'extends' => 'default_settings', + 'class' => 'Aws\CognitoIdentity\CognitoIdentityClient' + ), + + 'cognitoidentity' => array('extends' => 'cognito-identity'), + + 'cognito-sync' => array( + 'alias' => 'CognitoSync', + 'extends' => 'default_settings', + 'class' => 'Aws\CognitoSync\CognitoSyncClient' + ), + + 'cognitosync' => array('extends' => 'cognito-sync'), + + 'codecommit' => array( + 'alias' => 'CodeCommit', + 'extends' => 'default_settings', + 'class' => 'Aws\CodeCommit\CodeCommitClient' + ), + + 'codedeploy' => array( + 'alias' => 'CodeDeploy', + 'extends' => 'default_settings', + 'class' => 'Aws\CodeDeploy\CodeDeployClient' + ), + + 'codepipeline' => array( + 'alias' => 'CodePipeline', + 'extends' => 'default_settings', + 'class' => 'Aws\CodePipeline\CodePipelineClient' + ), + + 'config' => array( + 'alias' => 'ConfigService', + 'extends' => 'default_settings', + 'class' => 'Aws\ConfigService\ConfigServiceClient' + ), + + 'datapipeline' => array( + 'alias' => 'DataPipeline', + 'extends' => 'default_settings', + 'class' => 'Aws\DataPipeline\DataPipelineClient' + ), + + 'devicefarm' => array( + 'alias' => 'DeviceFarm', + 'extends' => 'default_settings', + 'class' => 'Aws\DeviceFarm\DeviceFarmClient' + ), + + 'directconnect' => array( + 'alias' => 'DirectConnect', + 'extends' => 'default_settings', + 'class' => 'Aws\DirectConnect\DirectConnectClient' + ), + + 'ds' => array( + 'alias' => 'DirectoryService', + 'extends' => 'default_settings', + 'class' => 'Aws\DirectoryService\DirectoryServiceClient' + ), + + 'dynamodb' => array( + 'alias' => 'DynamoDb', + 'extends' => 'default_settings', + 'class' => 'Aws\DynamoDb\DynamoDbClient' + ), + + 'dynamodb_20111205' => array( + 'extends' => 'dynamodb', + 'params' => array( + 'version' => '2011-12-05' + ) + ), + + 'dynamodbstreams' => array( + 'alias' => 'DynamoDbStreams', + 'extends' => 'default_settings', + 'class' => 'Aws\DynamoDbStreams\DynamoDbStreamsClient' + ), + + 'ec2' => array( + 'alias' => 'Ec2', + 'extends' => 'default_settings', + 'class' => 'Aws\Ec2\Ec2Client' + ), + + 'ecs' => array( + 'alias' => 'Ecs', + 'extends' => 'default_settings', + 'class' => 'Aws\Ecs\EcsClient' + ), + + 'elasticache' => array( + 'alias' => 'ElastiCache', + 'extends' => 'default_settings', + 'class' => 'Aws\ElastiCache\ElastiCacheClient' + ), + + 'elasticbeanstalk' => array( + 'alias' => 'ElasticBeanstalk', + 'extends' => 'default_settings', + 'class' => 'Aws\ElasticBeanstalk\ElasticBeanstalkClient' + ), + + 'efs' => array( + 'alias' => 'Efs', + 'extends' => 'default_settings', + 'class' => 'Aws\Efs\EfsClient' + ), + + 'elasticloadbalancing' => array( + 'alias' => 'ElasticLoadBalancing', + 'extends' => 'default_settings', + 'class' => 'Aws\ElasticLoadBalancing\ElasticLoadBalancingClient' + ), + + 'elastictranscoder' => array( + 'alias' => 'ElasticTranscoder', + 'extends' => 'default_settings', + 'class' => 'Aws\ElasticTranscoder\ElasticTranscoderClient' + ), + + 'emr' => array( + 'alias' => 'Emr', + 'extends' => 'default_settings', + 'class' => 'Aws\Emr\EmrClient' + ), + + 'glacier' => array( + 'alias' => 'Glacier', + 'extends' => 'default_settings', + 'class' => 'Aws\Glacier\GlacierClient' + ), + + 'kinesis' => array( + 'alias' => 'Kinesis', + 'extends' => 'default_settings', + 'class' => 'Aws\Kinesis\KinesisClient' + ), + + 'kms' => array( + 'alias' => 'Kms', + 'extends' => 'default_settings', + 'class' => 'Aws\Kms\KmsClient' + ), + + 'lambda' => array( + 'alias' => 'Lambda', + 'extends' => 'default_settings', + 'class' => 'Aws\Lambda\LambdaClient' + ), + + 'iam' => array( + 'alias' => 'Iam', + 'extends' => 'default_settings', + 'class' => 'Aws\Iam\IamClient' + ), + + 'importexport' => array( + 'alias' => 'ImportExport', + 'extends' => 'default_settings', + 'class' => 'Aws\ImportExport\ImportExportClient' + ), + + 'machinelearning' => array( + 'alias' => 'MachineLearning', + 'extends' => 'default_settings', + 'class' => 'Aws\MachineLearning\MachineLearningClient' + ), + + 'opsworks' => array( + 'alias' => 'OpsWorks', + 'extends' => 'default_settings', + 'class' => 'Aws\OpsWorks\OpsWorksClient' + ), + + 'rds' => array( + 'alias' => 'Rds', + 'extends' => 'default_settings', + 'class' => 'Aws\Rds\RdsClient' + ), + + 'redshift' => array( + 'alias' => 'Redshift', + 'extends' => 'default_settings', + 'class' => 'Aws\Redshift\RedshiftClient' + ), + + 'route53' => array( + 'alias' => 'Route53', + 'extends' => 'default_settings', + 'class' => 'Aws\Route53\Route53Client' + ), + + 'route53domains' => array( + 'alias' => 'Route53Domains', + 'extends' => 'default_settings', + 'class' => 'Aws\Route53Domains\Route53DomainsClient' + ), + + 's3' => array( + 'alias' => 'S3', + 'extends' => 'default_settings', + 'class' => 'Aws\S3\S3Client' + ), + + 'sdb' => array( + 'alias' => 'SimpleDb', + 'extends' => 'default_settings', + 'class' => 'Aws\SimpleDb\SimpleDbClient' + ), + + 'ses' => array( + 'alias' => 'Ses', + 'extends' => 'default_settings', + 'class' => 'Aws\Ses\SesClient' + ), + + 'sns' => array( + 'alias' => 'Sns', + 'extends' => 'default_settings', + 'class' => 'Aws\Sns\SnsClient' + ), + + 'sqs' => array( + 'alias' => 'Sqs', + 'extends' => 'default_settings', + 'class' => 'Aws\Sqs\SqsClient' + ), + + 'ssm' => array( + 'alias' => 'Ssm', + 'extends' => 'default_settings', + 'class' => 'Aws\Ssm\SsmClient' + ), + + 'storagegateway' => array( + 'alias' => 'StorageGateway', + 'extends' => 'default_settings', + 'class' => 'Aws\StorageGateway\StorageGatewayClient' + ), + + 'sts' => array( + 'alias' => 'Sts', + 'extends' => 'default_settings', + 'class' => 'Aws\Sts\StsClient' + ), + + 'support' => array( + 'alias' => 'Support', + 'extends' => 'default_settings', + 'class' => 'Aws\Support\SupportClient' + ), + + 'swf' => array( + 'alias' => 'Swf', + 'extends' => 'default_settings', + 'class' => 'Aws\Swf\SwfClient' + ), + + 'workspaces' => array( + 'alias' => 'WorkSpaces', + 'extends' => 'default_settings', + 'class' => 'Aws\WorkSpaces\WorkSpacesClient' + ), + ) +); diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Resources/public-endpoints.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Resources/public-endpoints.php new file mode 100644 index 0000000..d939f1f --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Resources/public-endpoints.php @@ -0,0 +1,79 @@ + 2, + 'endpoints' => array( + '*/*' => array( + 'endpoint' => '{service}.{region}.amazonaws.com' + ), + 'cn-north-1/*' => array( + 'endpoint' => '{service}.{region}.amazonaws.com.cn', + 'signatureVersion' => 'v4' + ), + 'us-gov-west-1/iam' => array( + 'endpoint' => 'iam.us-gov.amazonaws.com' + ), + 'us-gov-west-1/sts' => array( + 'endpoint' => 'sts.us-gov-west-1.amazonaws.com' + ), + 'us-gov-west-1/s3' => array( + 'endpoint' => 's3-{region}.amazonaws.com' + ), + '*/cloudfront' => array( + 'endpoint' => 'cloudfront.amazonaws.com', + 'credentialScope' => array( + 'region' => 'us-east-1' + ) + ), + '*/iam' => array( + 'endpoint' => 'iam.amazonaws.com', + 'credentialScope' => array( + 'region' => 'us-east-1' + ) + ), + '*/importexport' => array( + 'endpoint' => 'importexport.amazonaws.com', + 'credentialScope' => array( + 'region' => 'us-east-1' + ) + ), + '*/route53' => array( + 'endpoint' => 'route53.amazonaws.com', + 'credentialScope' => array( + 'region' => 'us-east-1' + ) + ), + '*/sts' => array( + 'endpoint' => 'sts.amazonaws.com', + 'credentialScope' => array( + 'region' => 'us-east-1' + ) + ), + 'us-east-1/sdb' => array( + 'endpoint' => 'sdb.amazonaws.com' + ), + 'us-east-1/s3' => array( + 'endpoint' => 's3.amazonaws.com' + ), + 'us-west-1/s3' => array( + 'endpoint' => 's3-{region}.amazonaws.com' + ), + 'us-west-2/s3' => array( + 'endpoint' => 's3-{region}.amazonaws.com' + ), + 'eu-west-1/s3' => array( + 'endpoint' => 's3-{region}.amazonaws.com' + ), + 'ap-southeast-1/s3' => array( + 'endpoint' => 's3-{region}.amazonaws.com' + ), + 'ap-southeast-2/s3' => array( + 'endpoint' => 's3-{region}.amazonaws.com' + ), + 'ap-northeast-1/s3' => array( + 'endpoint' => 's3-{region}.amazonaws.com' + ), + 'sa-east-1/s3' => array( + 'endpoint' => 's3-{region}.amazonaws.com' + ) + ) +); diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Resources/sdk1-config.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Resources/sdk1-config.php new file mode 100644 index 0000000..a5121ab --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Resources/sdk1-config.php @@ -0,0 +1,138 @@ + array('_aws'), + 'services' => array( + + 'sdk1_settings' => array( + 'extends' => 'default_settings', + 'params' => array( + 'certificate_authority' => false + ) + ), + + 'v1.autoscaling' => array( + 'extends' => 'sdk1_settings', + 'class' => 'AmazonAS' + ), + + 'v1.cloudformation' => array( + 'extends' => 'sdk1_settings', + 'class' => 'AmazonCloudFormation' + ), + + 'v1.cloudfront' => array( + 'extends' => 'sdk1_settings', + 'class' => 'AmazonCloudFront' + ), + + 'v1.cloudsearch' => array( + 'extends' => 'sdk1_settings', + 'class' => 'AmazonCloudSearch' + ), + + 'v1.cloudwatch' => array( + 'extends' => 'sdk1_settings', + 'class' => 'AmazonCloudWatch' + ), + + 'v1.dynamodb' => array( + 'extends' => 'sdk1_settings', + 'class' => 'AmazonDynamoDB' + ), + + 'v1.ec2' => array( + 'extends' => 'sdk1_settings', + 'class' => 'AmazonEC2' + ), + + 'v1.elasticache' => array( + 'extends' => 'sdk1_settings', + 'class' => 'AmazonElastiCache' + ), + + 'v1.elasticbeanstalk' => array( + 'extends' => 'sdk1_settings', + 'class' => 'AmazonElasticBeanstalk' + ), + + 'v1.elb' => array( + 'extends' => 'sdk1_settings', + 'class' => 'AmazonELB' + ), + + 'v1.emr' => array( + 'extends' => 'sdk1_settings', + 'class' => 'AmazonEMR' + ), + + 'v1.iam' => array( + 'extends' => 'sdk1_settings', + 'class' => 'AmazonIAM' + ), + + 'v1.importexport' => array( + 'extends' => 'sdk1_settings', + 'class' => 'AmazonImportExport' + ), + + 'v1.rds' => array( + 'extends' => 'sdk1_settings', + 'class' => 'AmazonRDS' + ), + + 'v1.s3' => array( + 'extends' => 'sdk1_settings', + 'class' => 'AmazonS3' + ), + + 'v1.sdb' => array( + 'extends' => 'sdk1_settings', + 'class' => 'AmazonSDB' + ), + + 'v1.ses' => array( + 'extends' => 'sdk1_settings', + 'class' => 'AmazonSES' + ), + + 'v1.sns' => array( + 'extends' => 'sdk1_settings', + 'class' => 'AmazonSNS' + ), + + 'v1.sqs' => array( + 'extends' => 'sdk1_settings', + 'class' => 'AmazonSQS' + ), + + 'v1.storagegateway' => array( + 'extends' => 'sdk1_settings', + 'class' => 'AmazonStorageGateway' + ), + + 'v1.sts' => array( + 'extends' => 'sdk1_settings', + 'class' => 'AmazonSTS' + ), + + 'v1.swf' => array( + 'extends' => 'sdk1_settings', + 'class' => 'AmazonSWF' + ) + ) +); diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/RulesEndpointProvider.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/RulesEndpointProvider.php new file mode 100644 index 0000000..ec57cb8 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/RulesEndpointProvider.php @@ -0,0 +1,67 @@ +patterns = $patterns; + } + + /** + * Creates and returns the default RulesEndpointProvider based on the + * public rule sets. + * + * @return self + */ + public static function fromDefaults() + { + return new self(require __DIR__ . '/Resources/public-endpoints.php'); + } + + public function __invoke(array $args = array()) + { + if (!isset($args['service'])) { + throw new \InvalidArgumentException('Requires a "service" value'); + } + + if (!isset($args['region'])) { + throw new \InvalidArgumentException('Requires a "region" value'); + } + + foreach ($this->getKeys($args['region'], $args['service']) as $key) { + if (isset($this->patterns['endpoints'][$key])) { + return $this->expand($this->patterns['endpoints'][$key], $args); + } + } + + throw new \RuntimeException('Could not resolve endpoint'); + } + + private function expand(array $config, array $args) + { + $scheme = isset($args['scheme']) ? $args['scheme'] : 'https'; + $config['endpoint'] = $scheme . '://' . str_replace( + array('{service}', '{region}'), + array($args['service'], $args['region']), + $config['endpoint'] + ); + + return $config; + } + + private function getKeys($region, $service) + { + return array("$region/$service", "$region/*", "*/$service", "*/*"); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Signature/AbstractSignature.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Signature/AbstractSignature.php new file mode 100644 index 0000000..2d25d87 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Signature/AbstractSignature.php @@ -0,0 +1,44 @@ +credentials = $credentials; + $this->signature = $signature; + } + + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents() + { + return array( + 'request.before_send' => array('onRequestBeforeSend', -255), + 'client.credentials_changed' => array('onCredentialsChanged') + ); + } + + /** + * Updates the listener with new credentials if the client is updated + * + * @param Event $event Event emitted + */ + public function onCredentialsChanged(Event $event) + { + $this->credentials = $event['credentials']; + } + + /** + * Signs requests before they are sent + * + * @param Event $event Event emitted + */ + public function onRequestBeforeSend(Event $event) + { + $creds = $this->credentials instanceof AbstractRefreshableCredentials + ? $this->credentials->getCredentials() + : $this->credentials; + + if(!$creds instanceof NullCredentials) { + $this->signature->signRequest($event['request'], $creds); + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Signature/SignatureV2.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Signature/SignatureV2.php new file mode 100644 index 0000000..c900287 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Signature/SignatureV2.php @@ -0,0 +1,109 @@ +getTimestamp(true); + + // set values we need in CanonicalizedParameterString + $this->addParameter($request, 'Timestamp', gmdate('c', $timestamp)); + $this->addParameter($request, 'SignatureVersion', '2'); + $this->addParameter($request, 'SignatureMethod', 'HmacSHA256'); + $this->addParameter($request, 'AWSAccessKeyId', $credentials->getAccessKeyId()); + + if ($token = $credentials->getSecurityToken()) { + $this->addParameter($request, 'SecurityToken', $token); + } + + // Get the path and ensure it's absolute + $path = '/' . ltrim($request->getUrl(true)->normalizePath()->getPath(), '/'); + + // build string to sign + $sign = $request->getMethod() . "\n" + . $request->getHost() . "\n" + . $path . "\n" + . $this->getCanonicalizedParameterString($request); + + // Add the string to sign to the request for debugging purposes + $request->getParams()->set('aws.string_to_sign', $sign); + + $signature = base64_encode( + hash_hmac( + 'sha256', + $sign, + $credentials->getSecretKey(), + true + ) + ); + + $this->addParameter($request, 'Signature', $signature); + } + + /** + * Add a parameter key and value to the request according to type + * + * @param RequestInterface $request The request + * @param string $key The name of the parameter + * @param string $value The value of the parameter + */ + public function addParameter(RequestInterface $request, $key, $value) + { + if ($request->getMethod() == 'POST') { + $request->setPostField($key, $value); + } else { + $request->getQuery()->set($key, $value); + } + } + + /** + * Get the canonicalized query/parameter string for a request + * + * @param RequestInterface $request Request used to build canonicalized string + * + * @return string + */ + private function getCanonicalizedParameterString(RequestInterface $request) + { + if ($request->getMethod() == 'POST') { + $params = $request->getPostFields()->toArray(); + } else { + $params = $request->getQuery()->toArray(); + } + + // Don't resign a previous signature value + unset($params['Signature']); + uksort($params, 'strcmp'); + + $str = ''; + foreach ($params as $key => $val) { + $str .= rawurlencode($key) . '=' . rawurlencode($val) . '&'; + } + + return substr($str, 0, -1); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Signature/SignatureV3Https.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Signature/SignatureV3Https.php new file mode 100644 index 0000000..be0514e --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Signature/SignatureV3Https.php @@ -0,0 +1,52 @@ +hasHeader('date') && !$request->hasHeader('x-amz-date')) { + $request->setHeader('Date', gmdate(DateFormat::RFC1123, $this->getTimestamp())); + } + + // Add the security token if one is present + if ($credentials->getSecurityToken()) { + $request->setHeader('x-amz-security-token', $credentials->getSecurityToken()); + } + + // Determine the string to sign + $stringToSign = (string) ($request->getHeader('Date') ?: $request->getHeader('x-amz-date')); + $request->getParams()->set('aws.string_to_sign', $stringToSign); + + // Calculate the signature + $signature = base64_encode(hash_hmac('sha256', $stringToSign, $credentials->getSecretKey(), true)); + + // Add the authorization header to the request + $headerFormat = 'AWS3-HTTPS AWSAccessKeyId=%s,Algorithm=HmacSHA256,Signature=%s'; + $request->setHeader('X-Amzn-Authorization', sprintf($headerFormat, $credentials->getAccessKeyId(), $signature)); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Signature/SignatureV4.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Signature/SignatureV4.php new file mode 100644 index 0000000..2137760 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Signature/SignatureV4.php @@ -0,0 +1,477 @@ +serviceName = $serviceName; + $this->regionName = $regionName; + } + + /** + * Set the service name instead of inferring it from a request URL + * + * @param string $service Name of the service used when signing + * + * @return self + */ + public function setServiceName($service) + { + $this->serviceName = $service; + + return $this; + } + + /** + * Set the region name instead of inferring it from a request URL + * + * @param string $region Name of the region used when signing + * + * @return self + */ + public function setRegionName($region) + { + $this->regionName = $region; + + return $this; + } + + /** + * Set the maximum number of computed hashes to cache + * + * @param int $maxCacheSize Maximum number of hashes to cache + * + * @return self + */ + public function setMaxCacheSize($maxCacheSize) + { + $this->maxCacheSize = $maxCacheSize; + + return $this; + } + + public function signRequest(RequestInterface $request, CredentialsInterface $credentials) + { + $timestamp = $this->getTimestamp(); + $longDate = gmdate(DateFormat::ISO8601, $timestamp); + $shortDate = substr($longDate, 0, 8); + + // Remove any previously set Authorization headers so that retries work + $request->removeHeader('Authorization'); + + // Requires a x-amz-date header or Date + if ($request->hasHeader('x-amz-date') || !$request->hasHeader('Date')) { + $request->setHeader('x-amz-date', $longDate); + } else { + $request->setHeader('Date', gmdate(DateFormat::RFC1123, $timestamp)); + } + + // Add the security token if one is present + if ($credentials->getSecurityToken()) { + $request->setHeader('x-amz-security-token', $credentials->getSecurityToken()); + } + + // Parse the service and region or use one that is explicitly set + $region = $this->regionName; + $service = $this->serviceName; + if (!$region || !$service) { + $url = Url::factory($request->getUrl()); + $region = $region ?: HostNameUtils::parseRegionName($url); + $service = $service ?: HostNameUtils::parseServiceName($url); + } + + $credentialScope = $this->createScope($shortDate, $region, $service); + $payload = $this->getPayload($request); + $signingContext = $this->createSigningContext($request, $payload); + $signingContext['string_to_sign'] = $this->createStringToSign( + $longDate, + $credentialScope, + $signingContext['canonical_request'] + ); + + // Calculate the signing key using a series of derived keys + $signingKey = $this->getSigningKey($shortDate, $region, $service, $credentials->getSecretKey()); + $signature = hash_hmac('sha256', $signingContext['string_to_sign'], $signingKey); + + $request->setHeader('Authorization', "AWS4-HMAC-SHA256 " + . "Credential={$credentials->getAccessKeyId()}/{$credentialScope}, " + . "SignedHeaders={$signingContext['signed_headers']}, Signature={$signature}"); + + // Add debug information to the request + $request->getParams()->set('aws.signature', $signingContext); + } + + public function createPresignedUrl( + RequestInterface $request, + CredentialsInterface $credentials, + $expires + ) { + $request = $this->createPresignedRequest($request, $credentials); + $query = $request->getQuery(); + $httpDate = gmdate(DateFormat::ISO8601, $this->getTimestamp()); + $shortDate = substr($httpDate, 0, 8); + $scope = $this->createScope( + $shortDate, + $this->regionName, + $this->serviceName + ); + $this->addQueryValues($scope, $request, $credentials, $expires); + $payload = $this->getPresignedPayload($request); + $context = $this->createSigningContext($request, $payload); + $stringToSign = $this->createStringToSign( + $httpDate, + $scope, + $context['canonical_request'] + ); + $key = $this->getSigningKey( + $shortDate, + $this->regionName, + $this->serviceName, + $credentials->getSecretKey() + ); + $query['X-Amz-Signature'] = hash_hmac('sha256', $stringToSign, $key); + + return $request->getUrl(); + } + + /** + * Converts a POST request to a GET request by moving POST fields into the + * query string. + * + * Useful for pre-signing query protocol requests. + * + * @param EntityEnclosingRequestInterface $request Request to clone + * + * @return RequestInterface + * @throws \InvalidArgumentException if the method is not POST + */ + public static function convertPostToGet(EntityEnclosingRequestInterface $request) + { + if ($request->getMethod() !== 'POST') { + throw new \InvalidArgumentException('Expected a POST request but ' + . 'received a ' . $request->getMethod() . ' request.'); + } + + $cloned = RequestFactory::getInstance() + ->cloneRequestWithMethod($request, 'GET'); + + // Move POST fields to the query if they are present + foreach ($request->getPostFields() as $name => $value) { + $cloned->getQuery()->set($name, $value); + } + + return $cloned; + } + + /** + * Get the payload part of a signature from a request. + * + * @param RequestInterface $request + * + * @return string + */ + protected function getPayload(RequestInterface $request) + { + // Calculate the request signature payload + if ($request->hasHeader('x-amz-content-sha256')) { + // Handle streaming operations (e.g. Glacier.UploadArchive) + return (string) $request->getHeader('x-amz-content-sha256'); + } + + if ($request instanceof EntityEnclosingRequestInterface) { + if ($request->getMethod() == 'POST' && count($request->getPostFields())) { + return hash('sha256', (string) $request->getPostFields()); + } elseif ($body = $request->getBody()) { + return Stream::getHash($request->getBody(), 'sha256'); + } + } + + return self::DEFAULT_PAYLOAD; + } + + /** + * Get the payload of a request for use with pre-signed URLs. + * + * @param RequestInterface $request + * + * @return string + */ + protected function getPresignedPayload(RequestInterface $request) + { + return $this->getPayload($request); + } + + protected function createCanonicalizedPath(RequestInterface $request) + { + $doubleEncoded = rawurlencode(ltrim($request->getPath(), '/')); + + return '/' . str_replace('%2F', '/', $doubleEncoded); + } + + private function createStringToSign($longDate, $credentialScope, $creq) + { + return "AWS4-HMAC-SHA256\n{$longDate}\n{$credentialScope}\n" + . hash('sha256', $creq); + } + + private function createPresignedRequest( + RequestInterface $request, + CredentialsInterface $credentials + ) { + // POST requests can be sent as GET requests instead by moving the + // POST fields into the query string. + if ($request instanceof EntityEnclosingRequestInterface + && $request->getMethod() === 'POST' + && strpos($request->getHeader('Content-Type'), 'application/x-www-form-urlencoded') === 0 + ) { + $sr = RequestFactory::getInstance() + ->cloneRequestWithMethod($request, 'GET'); + // Move POST fields to the query if they are present + foreach ($request->getPostFields() as $name => $value) { + $sr->getQuery()->set($name, $value); + } + } else { + $sr = clone $request; + } + + // Make sure to handle temporary credentials + if ($token = $credentials->getSecurityToken()) { + $sr->setHeader('X-Amz-Security-Token', $token); + $sr->getQuery()->set('X-Amz-Security-Token', $token); + } + + $this->moveHeadersToQuery($sr); + + return $sr; + } + + /** + * Create the canonical representation of a request + * + * @param RequestInterface $request Request to canonicalize + * @param string $payload Request payload (typically the value + * of the x-amz-content-sha256 header. + * + * @return array Returns an array of context information including: + * - canonical_request + * - signed_headers + */ + private function createSigningContext(RequestInterface $request, $payload) + { + $signable = array( + 'host' => true, + 'date' => true, + 'content-md5' => true + ); + + // Normalize the path as required by SigV4 and ensure it's absolute + $canon = $request->getMethod() . "\n" + . $this->createCanonicalizedPath($request) . "\n" + . $this->getCanonicalizedQueryString($request) . "\n"; + + $canonHeaders = array(); + + foreach ($request->getHeaders()->getAll() as $key => $values) { + $key = strtolower($key); + if (isset($signable[$key]) || substr($key, 0, 6) === 'x-amz-') { + $values = $values->toArray(); + if (count($values) == 1) { + $values = $values[0]; + } else { + sort($values); + $values = implode(',', $values); + } + $canonHeaders[$key] = $key . ':' . preg_replace('/\s+/', ' ', $values); + } + } + + ksort($canonHeaders); + $signedHeadersString = implode(';', array_keys($canonHeaders)); + $canon .= implode("\n", $canonHeaders) . "\n\n" + . $signedHeadersString . "\n" + . $payload; + + return array( + 'canonical_request' => $canon, + 'signed_headers' => $signedHeadersString + ); + } + + /** + * Get a hash for a specific key and value. If the hash was previously + * cached, return it + * + * @param string $shortDate Short date + * @param string $region Region name + * @param string $service Service name + * @param string $secretKey Secret Access Key + * + * @return string + */ + private function getSigningKey($shortDate, $region, $service, $secretKey) + { + $cacheKey = $shortDate . '_' . $region . '_' . $service . '_' . $secretKey; + + // Retrieve the hash form the cache or create it and add it to the cache + if (!isset($this->hashCache[$cacheKey])) { + // When the cache size reaches the max, then just clear the cache + if (++$this->cacheSize > $this->maxCacheSize) { + $this->hashCache = array(); + $this->cacheSize = 0; + } + $dateKey = hash_hmac('sha256', $shortDate, 'AWS4' . $secretKey, true); + $regionKey = hash_hmac('sha256', $region, $dateKey, true); + $serviceKey = hash_hmac('sha256', $service, $regionKey, true); + $this->hashCache[$cacheKey] = hash_hmac('sha256', 'aws4_request', $serviceKey, true); + } + + return $this->hashCache[$cacheKey]; + } + + /** + * Get the canonicalized query string for a request + * + * @param RequestInterface $request + * @return string + */ + private function getCanonicalizedQueryString(RequestInterface $request) + { + $queryParams = $request->getQuery()->getAll(); + unset($queryParams['X-Amz-Signature']); + if (empty($queryParams)) { + return ''; + } + + $qs = ''; + ksort($queryParams); + foreach ($queryParams as $key => $values) { + if (is_array($values)) { + sort($values); + } elseif ($values === 0) { + $values = array('0'); + } elseif (!$values) { + $values = array(''); + } + + foreach ((array) $values as $value) { + if ($value === QueryString::BLANK) { + $value = ''; + } + $qs .= rawurlencode($key) . '=' . rawurlencode($value) . '&'; + } + } + + return substr($qs, 0, -1); + } + + private function convertExpires($expires) + { + if ($expires instanceof \DateTime) { + $expires = $expires->getTimestamp(); + } elseif (!is_numeric($expires)) { + $expires = strtotime($expires); + } + + $duration = $expires - time(); + + // Ensure that the duration of the signature is not longer than a week + if ($duration > 604800) { + throw new \InvalidArgumentException('The expiration date of a ' + . 'signature version 4 presigned URL must be less than one ' + . 'week'); + } + + return $duration; + } + + private function createScope($shortDate, $region, $service) + { + return $shortDate + . '/' . $region + . '/' . $service + . '/aws4_request'; + } + + private function addQueryValues( + $scope, + RequestInterface $request, + CredentialsInterface $credentials, + $expires + ) { + $credential = $credentials->getAccessKeyId() . '/' . $scope; + + // Set query params required for pre-signed URLs + $request->getQuery() + ->set('X-Amz-Algorithm', 'AWS4-HMAC-SHA256') + ->set('X-Amz-Credential', $credential) + ->set('X-Amz-Date', gmdate('Ymd\THis\Z', $this->getTimestamp())) + ->set('X-Amz-SignedHeaders', 'Host') + ->set('X-Amz-Expires', $this->convertExpires($expires)); + } + + private function moveHeadersToQuery(RequestInterface $request) + { + $query = $request->getQuery(); + + foreach ($request->getHeaders() as $name => $header) { + if (substr($name, 0, 5) == 'x-amz') { + $query[$header->getName()] = (string) $header; + } + if ($name !== 'host') { + $request->removeHeader($name); + } + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Waiter/AbstractResourceWaiter.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Waiter/AbstractResourceWaiter.php new file mode 100644 index 0000000..5334848 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Waiter/AbstractResourceWaiter.php @@ -0,0 +1,53 @@ +client = $client; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function wait() + { + if (!$this->client) { + throw new RuntimeException('No client has been specified on the waiter'); + } + + parent::wait(); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Waiter/AbstractWaiter.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Waiter/AbstractWaiter.php new file mode 100644 index 0000000..09dbea1 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Waiter/AbstractWaiter.php @@ -0,0 +1,146 @@ +config[self::MAX_ATTEMPTS]) ? $this->config[self::MAX_ATTEMPTS] : 10; + } + + /** + * Get the amount of time in seconds to delay between attempts + * + * @return int + */ + public function getInterval() + { + return isset($this->config[self::INTERVAL]) ? $this->config[self::INTERVAL] : 0; + } + + /** + * {@inheritdoc} + */ + public function setMaxAttempts($maxAttempts) + { + $this->config[self::MAX_ATTEMPTS] = $maxAttempts; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function setInterval($interval) + { + $this->config[self::INTERVAL] = $interval; + + return $this; + } + + /** + * Set config options associated with the waiter + * + * @param array $config Options to set + * + * @return self + */ + public function setConfig(array $config) + { + if (isset($config['waiter.before_attempt'])) { + $this->getEventDispatcher()->addListener('waiter.before_attempt', $config['waiter.before_attempt']); + unset($config['waiter.before_attempt']); + } + + if (isset($config['waiter.before_wait'])) { + $this->getEventDispatcher()->addListener('waiter.before_wait', $config['waiter.before_wait']); + unset($config['waiter.before_wait']); + } + + $this->config = $config; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function wait() + { + $this->attempts = 0; + + do { + $this->dispatch('waiter.before_attempt', array( + 'waiter' => $this, + 'config' => $this->config, + )); + + if ($this->doWait()) { + break; + } + + if (++$this->attempts >= $this->getMaxAttempts()) { + throw new RuntimeException('Wait method never resolved to true after ' . $this->attempts . ' attempts'); + } + + $this->dispatch('waiter.before_wait', array( + 'waiter' => $this, + 'config' => $this->config, + )); + + if ($this->getInterval()) { + usleep($this->getInterval() * 1000000); + } + + } while (1); + } + + /** + * Method to implement in subclasses + * + * @return bool Return true when successful, false on failure + */ + abstract protected function doWait(); +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Waiter/CallableWaiter.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Waiter/CallableWaiter.php new file mode 100644 index 0000000..a205e06 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Waiter/CallableWaiter.php @@ -0,0 +1,82 @@ +callable = $callable; + + return $this; + } + + /** + * Set additional context for the callable function. This data will be passed into the callable function as the + * second argument + * + * @param array $context Additional context + * + * @return self + */ + public function setContext(array $context) + { + $this->context = $context; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function doWait() + { + if (!$this->callable) { + throw new RuntimeException('No callable was specified for the wait method'); + } + + return call_user_func($this->callable, $this->attempts, $this->context); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Waiter/CompositeWaiterFactory.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Waiter/CompositeWaiterFactory.php new file mode 100644 index 0000000..5278e49 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Waiter/CompositeWaiterFactory.php @@ -0,0 +1,90 @@ +factories = $factories; + } + + /** + * {@inheritdoc} + */ + public function build($waiter) + { + if (!($factory = $this->getFactory($waiter))) { + throw new InvalidArgumentException("Waiter was not found matching {$waiter}."); + } + + return $factory->build($waiter); + } + + /** + * {@inheritdoc} + */ + public function canBuild($waiter) + { + return (bool) $this->getFactory($waiter); + } + + /** + * Add a factory to the composite factory + * + * @param WaiterFactoryInterface $factory Factory to add + * + * @return self + */ + public function addFactory(WaiterFactoryInterface $factory) + { + $this->factories[] = $factory; + + return $this; + } + + /** + * Get the factory that matches the waiter name + * + * @param string $waiter Name of the waiter + * + * @return WaiterFactoryInterface|bool + */ + protected function getFactory($waiter) + { + foreach ($this->factories as $factory) { + if ($factory->canBuild($waiter)) { + return $factory; + } + } + + return false; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Waiter/ConfigResourceWaiter.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Waiter/ConfigResourceWaiter.php new file mode 100644 index 0000000..8ef0577 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Waiter/ConfigResourceWaiter.php @@ -0,0 +1,225 @@ +waiterConfig = $waiterConfig; + $this->setInterval($waiterConfig->get(WaiterConfig::INTERVAL)); + $this->setMaxAttempts($waiterConfig->get(WaiterConfig::MAX_ATTEMPTS)); + } + + /** + * {@inheritdoc} + */ + public function setConfig(array $config) + { + foreach ($config as $key => $value) { + if (substr($key, 0, 7) == 'waiter.') { + $this->waiterConfig->set(substr($key, 7), $value); + } + } + + if (!isset($config[self::INTERVAL])) { + $config[self::INTERVAL] = $this->waiterConfig->get(WaiterConfig::INTERVAL); + } + + if (!isset($config[self::MAX_ATTEMPTS])) { + $config[self::MAX_ATTEMPTS] = $this->waiterConfig->get(WaiterConfig::MAX_ATTEMPTS); + } + + return parent::setConfig($config); + } + + /** + * Get the waiter's configuration data + * + * @return WaiterConfig + */ + public function getWaiterConfig() + { + return $this->waiterConfig; + } + + /** + * {@inheritdoc} + */ + protected function doWait() + { + $params = $this->config; + // remove waiter settings from the operation's input + foreach (array_keys($params) as $key) { + if (substr($key, 0, 7) == 'waiter.') { + unset($params[$key]); + } + } + + $operation = $this->client->getCommand($this->waiterConfig->get(WaiterConfig::OPERATION), $params); + + try { + return $this->checkResult($this->client->execute($operation)); + } catch (ValidationException $e) { + throw new InvalidArgumentException( + $this->waiterConfig->get(WaiterConfig::WAITER_NAME) . ' waiter validation failed: ' . $e->getMessage(), + $e->getCode(), + $e + ); + } catch (ServiceResponseException $e) { + + // Check if this exception satisfies a success or failure acceptor + $transition = $this->checkErrorAcceptor($e); + if (null !== $transition) { + return $transition; + } + + // Check if this exception should be ignored + foreach ((array) $this->waiterConfig->get(WaiterConfig::IGNORE_ERRORS) as $ignore) { + if ($e->getExceptionCode() == $ignore) { + // This exception is ignored, so it counts as a failed attempt rather than a fast-fail + return false; + } + } + + // Allow non-ignore exceptions to bubble through + throw $e; + } + } + + /** + * Check if an exception satisfies a success or failure acceptor + * + * @param ServiceResponseException $e + * + * @return bool|null Returns true for success, false for failure, and null for no transition + */ + protected function checkErrorAcceptor(ServiceResponseException $e) + { + if ($this->waiterConfig->get(WaiterConfig::SUCCESS_TYPE) == 'error') { + if ($e->getExceptionCode() == $this->waiterConfig->get(WaiterConfig::SUCCESS_VALUE)) { + // Mark as a success + return true; + } + } + + // Mark as an attempt + return null; + } + + /** + * Check to see if the response model satisfies a success or failure state + * + * @param Model $result Result model + * + * @return bool + * @throws RuntimeException + */ + protected function checkResult(Model $result) + { + // Check if the result evaluates to true based on the path and output model + if ($this->waiterConfig->get(WaiterConfig::SUCCESS_TYPE) == 'output' && + $this->checkPath( + $result, + $this->waiterConfig->get(WaiterConfig::SUCCESS_PATH), + $this->waiterConfig->get(WaiterConfig::SUCCESS_VALUE) + ) + ) { + return true; + } + + // It did not finish waiting yet. Determine if we need to fail-fast based on the failure acceptor. + if ($this->waiterConfig->get(WaiterConfig::FAILURE_TYPE) == 'output') { + $failureValue = $this->waiterConfig->get(WaiterConfig::FAILURE_VALUE); + if ($failureValue) { + $key = $this->waiterConfig->get(WaiterConfig::FAILURE_PATH); + if ($this->checkPath($result, $key, $failureValue, false)) { + // Determine which of the results triggered the failure + $triggered = array_intersect( + (array) $this->waiterConfig->get(WaiterConfig::FAILURE_VALUE), + array_unique((array) $result->getPath($key)) + ); + // fast fail because the failure case was satisfied + throw new RuntimeException( + 'A resource entered into an invalid state of "' + . implode(', ', $triggered) . '" while waiting with the "' + . $this->waiterConfig->get(WaiterConfig::WAITER_NAME) . '" waiter.' + ); + } + } + } + + return false; + } + + /** + * Check to see if the path of the output key is satisfied by the value + * + * @param Model $model Result model + * @param string $key Key to check + * @param string $checkValue Compare the key to the value + * @param bool $all Set to true to ensure all value match or false to only match one + * + * @return bool + */ + protected function checkPath(Model $model, $key = null, $checkValue = array(), $all = true) + { + // If no key is set, then just assume true because the request succeeded + if (!$key) { + return true; + } + + if (!($result = $model->getPath($key))) { + return false; + } + + $total = $matches = 0; + foreach ((array) $result as $value) { + $total++; + foreach ((array) $checkValue as $check) { + if ($value == $check) { + $matches++; + break; + } + } + } + + // When matching all values, ensure that the match count matches the total count + if ($all && $total != $matches) { + return false; + } + + return $matches > 0; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Waiter/ResourceWaiterInterface.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Waiter/ResourceWaiterInterface.php new file mode 100644 index 0000000..07cf41d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Waiter/ResourceWaiterInterface.php @@ -0,0 +1,34 @@ + CamelCase). + */ +class WaiterClassFactory implements WaiterFactoryInterface +{ + /** + * @var array List of namespaces used to look for classes + */ + protected $namespaces; + + /** + * @var InflectorInterface Inflector used to inflect class names + */ + protected $inflector; + + /** + * @param array|string $namespaces Namespaces of waiter objects + * @param InflectorInterface $inflector Inflector used to resolve class names + */ + public function __construct($namespaces = array(), InflectorInterface $inflector = null) + { + $this->namespaces = (array) $namespaces; + $this->inflector = $inflector ?: Inflector::getDefault(); + } + + /** + * Registers a namespace to check for Waiters + * + * @param string $namespace Namespace which contains Waiter classes + * + * @return self + */ + public function registerNamespace($namespace) + { + array_unshift($this->namespaces, $namespace); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function build($waiter) + { + if (!($className = $this->getClassName($waiter))) { + throw new InvalidArgumentException("Waiter was not found matching {$waiter}."); + } + + return new $className(); + } + + /** + * {@inheritdoc} + */ + public function canBuild($waiter) + { + return $this->getClassName($waiter) !== null; + } + + /** + * Get the name of a waiter class + * + * @param string $waiter Waiter name + * + * @return string|null + */ + protected function getClassName($waiter) + { + $waiterName = $this->inflector->camel($waiter); + + // Determine the name of the class to load + $className = null; + foreach ($this->namespaces as $namespace) { + $potentialClassName = $namespace . '\\' . $waiterName; + if (class_exists($potentialClassName)) { + return $potentialClassName; + } + } + + return null; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Waiter/WaiterConfig.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Waiter/WaiterConfig.php new file mode 100644 index 0000000..7c10f5a --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Waiter/WaiterConfig.php @@ -0,0 +1,67 @@ +data = $data; + $this->extractConfig(); + } + + /** + * Create the command configuration variables + */ + protected function extractConfig() + { + // Populate success.* and failure.* if specified in acceptor.* + foreach ($this->data as $key => $value) { + if (substr($key, 0, 9) == 'acceptor.') { + $name = substr($key, 9); + if (!isset($this->data["success.{$name}"])) { + $this->data["success.{$name}"] = $value; + } + if (!isset($this->data["failure.{$name}"])) { + $this->data["failure.{$name}"] = $value; + } + unset($this->data[$key]); + } + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Waiter/WaiterConfigFactory.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Waiter/WaiterConfigFactory.php new file mode 100644 index 0000000..cb92149 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Waiter/WaiterConfigFactory.php @@ -0,0 +1,98 @@ +config = $config; + $this->inflector = $inflector ?: Inflector::getDefault(); + } + + /** + * {@inheritdoc} + */ + public function build($waiter) + { + return new ConfigResourceWaiter($this->getWaiterConfig($waiter)); + } + + /** + * {@inheritdoc} + */ + public function canBuild($waiter) + { + return isset($this->config[$waiter]) || isset($this->config[$this->inflector->camel($waiter)]); + } + + /** + * Get waiter configuration data, taking __default__ and extensions into account + * + * @param string $name Waiter name + * + * @return WaiterConfig + * @throws InvalidArgumentException + */ + protected function getWaiterConfig($name) + { + if (!$this->canBuild($name)) { + throw new InvalidArgumentException('No waiter found matching "' . $name . '"'); + } + + // inflect the name if needed + $name = isset($this->config[$name]) ? $name : $this->inflector->camel($name); + $waiter = new WaiterConfig($this->config[$name]); + $waiter['name'] = $name; + + // Always use __default__ as the basis if it's set + if (isset($this->config['__default__'])) { + $parentWaiter = new WaiterConfig($this->config['__default__']); + $waiter = $parentWaiter->overwriteWith($waiter); + } + + // Allow for configuration extensions + if (isset($this->config[$name]['extends'])) { + $waiter = $this->getWaiterConfig($this->config[$name]['extends'])->overwriteWith($waiter); + } + + return $waiter; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Waiter/WaiterFactoryInterface.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Waiter/WaiterFactoryInterface.php new file mode 100644 index 0000000..b9bf0f4 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/Common/Waiter/WaiterFactoryInterface.php @@ -0,0 +1,41 @@ + array('onCommandBeforePrepare', -255)); + } + + /** + * An event handler for constructing ACP definitions. + * + * @param Event $event The event to respond to. + * + * @throws InvalidArgumentException + */ + public function onCommandBeforePrepare(Event $event) + { + /** @var \Guzzle\Service\Command\AbstractCommand $command */ + $command = $event['command']; + $operation = $command->getOperation(); + if ($operation->hasParam('ACP') && $command->hasKey('ACP')) { + if ($acp = $command->get('ACP')) { + // Ensure that the correct object was passed + if (!($acp instanceof Acp)) { + throw new InvalidArgumentException('ACP must be an instance of Aws\S3\Model\Acp'); + } + + // Check if the user specified both an ACP and Grants + if ($command->hasKey('Grants')) { + throw new InvalidArgumentException( + 'Use either the ACP parameter or the Grants parameter. Do not use both.' + ); + } + + // Add the correct headers/body based parameters to the command + if ($operation->hasParam('Grants')) { + $command->overwriteWith($acp->toArray()); + } else { + $acp->updateCommand($command); + } + } + + // Remove the ACP parameter + $command->remove('ACP'); + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/BucketStyleListener.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/BucketStyleListener.php new file mode 100644 index 0000000..5d7bbde --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/BucketStyleListener.php @@ -0,0 +1,89 @@ + true); + + public static function getSubscribedEvents() + { + return array('command.after_prepare' => array('onCommandAfterPrepare', -255)); + } + + /** + * Changes how buckets are referenced in the HTTP request + * + * @param Event $event Event emitted + */ + public function onCommandAfterPrepare(Event $event) + { + $command = $event['command']; + $bucket = $command['Bucket']; + $request = $command->getRequest(); + $pathStyle = false; + + // Skip operations that do not need the bucket moved to the host. + if (isset(self::$exclusions[$command->getName()])) { + return; + } + + if ($key = $command['Key']) { + // Modify the command Key to account for the {/Key*} explosion into an array + if (is_array($key)) { + $command['Key'] = $key = implode('/', $key); + } + } + + // Set the key and bucket on the request + $request->getParams()->set('bucket', $bucket)->set('key', $key); + + // Switch to virtual if PathStyle is disabled, or not a DNS compatible bucket name, or the scheme is + // http, or the scheme is https and there are no dots in the host header (avoids SSL issues) + if (!$command['PathStyle'] && $command->getClient()->isValidBucketName($bucket) + && !($command->getRequest()->getScheme() == 'https' && strpos($bucket, '.')) + ) { + // Switch to virtual hosted bucket + $request->setHost($bucket . '.' . $request->getHost()); + $request->setPath(preg_replace("#^/{$bucket}#", '', $request->getPath())); + } else { + $pathStyle = true; + } + + if (!$bucket) { + $request->getParams()->set('s3.resource', '/'); + } elseif ($pathStyle) { + // Path style does not need a trailing slash + $request->getParams()->set( + 's3.resource', + '/' . rawurlencode($bucket) . ($key ? ('/' . S3Client::encodeKey($key)) : '') + ); + } else { + // Bucket style needs a trailing slash + $request->getParams()->set( + 's3.resource', + '/' . rawurlencode($bucket) . ($key ? ('/' . S3Client::encodeKey($key)) : '/') + ); + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Command/S3Command.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Command/S3Command.php new file mode 100644 index 0000000..d0d3b24 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Command/S3Command.php @@ -0,0 +1,65 @@ +client->createPresignedUrl($this->prepare(), $expires); + } + + /** + * {@inheritdoc} + */ + protected function process() + { + $request = $this->getRequest(); + $response = $this->getResponse(); + + // Dispatch an error if a 301 redirect occurred + if ($response->getStatusCode() == 301) { + $this->getClient()->getEventDispatcher()->dispatch('request.error', new Event(array( + 'request' => $this->getRequest(), + 'response' => $response + ))); + } + + parent::process(); + + // Set the GetObject URL if using the PutObject operation + if ($this->result instanceof Model && $this->getName() == 'PutObject') { + $this->result->set('ObjectURL', $request->getUrl()); + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Enum/CannedAcl.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Enum/CannedAcl.php new file mode 100644 index 0000000..da47045 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Enum/CannedAcl.php @@ -0,0 +1,32 @@ +errors = $errors; + } + + /** + * Get the errored objects + * + * @return array Returns an array of associative arrays, each containing + * a 'Code', 'Message', and 'Key' key. + */ + public function getErrors() + { + return $this->errors; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Exception/EntityTooLargeException.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Exception/EntityTooLargeException.php new file mode 100644 index 0000000..66e6da9 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Exception/EntityTooLargeException.php @@ -0,0 +1,22 @@ +getStatusCode() === 301) { + $data['type'] = 'client'; + if (isset($data['message'], $data['parsed'])) { + $data['message'] = rtrim($data['message'], '.') . ': "' . $data['parsed']->Endpoint . '".'; + } + } + + return $data; + } + + /** + * {@inheritdoc} + */ + protected function parseHeaders(RequestInterface $request, Response $response, array &$data) + { + parent::parseHeaders($request, $response, $data); + + // Get the request + $status = $response->getStatusCode(); + $method = $request->getMethod(); + + // Attempt to determine code for 403s and 404s + if ($status === 403) { + $data['code'] = 'AccessDenied'; + } elseif ($method === 'HEAD' && $status === 404) { + $path = explode('/', trim($request->getPath(), '/')); + $host = explode('.', $request->getHost()); + $bucket = (count($host) === 4) ? $host[0] : array_shift($path); + $object = array_shift($path); + + if ($bucket && $object) { + $data['code'] = 'NoSuchKey'; + } elseif ($bucket) { + $data['code'] = 'NoSuchBucket'; + } + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Exception/PermanentRedirectException.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Exception/PermanentRedirectException.php new file mode 100644 index 0000000..d2af820 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Exception/PermanentRedirectException.php @@ -0,0 +1,22 @@ +setNext($next); + } + } + + public function makesDecision() + { + return true; + } + + protected function getDelay( + $retries, + RequestInterface $request, + Response $response = null, + HttpException $e = null + ) { + if ($response && $request->getMethod() === 'POST' + && $request instanceof EntityEnclosingRequestInterface + && $response->getStatusCode() == 200 + && strpos($request->getBody(), 'getBody(), 'get('Buckets') ?: array(); + + // If only the names_only set, change arrays to a string + if ($this->get('names_only')) { + foreach ($buckets as &$bucket) { + $bucket = $bucket['Name']; + } + } + + return $buckets; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Iterator/ListMultipartUploadsIterator.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Iterator/ListMultipartUploadsIterator.php new file mode 100644 index 0000000..592aa0a --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Iterator/ListMultipartUploadsIterator.php @@ -0,0 +1,46 @@ +get('Uploads') ?: array(); + + // If there are prefixes and we want them, merge them in + if ($this->get('return_prefixes') && $result->hasKey('CommonPrefixes')) { + $uploads = array_merge($uploads, $result->get('CommonPrefixes')); + } + + return $uploads; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Iterator/ListObjectVersionsIterator.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Iterator/ListObjectVersionsIterator.php new file mode 100644 index 0000000..991a77e --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Iterator/ListObjectVersionsIterator.php @@ -0,0 +1,48 @@ +get('Versions') ?: array(); + $deleteMarkers = $result->get('DeleteMarkers') ?: array(); + $versions = array_merge($versions, $deleteMarkers); + + // If there are prefixes and we want them, merge them in + if ($this->get('return_prefixes') && $result->hasKey('CommonPrefixes')) { + $versions = array_merge($versions, $result->get('CommonPrefixes')); + } + + return $versions; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Iterator/ListObjectsIterator.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Iterator/ListObjectsIterator.php new file mode 100644 index 0000000..852b2a9 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Iterator/ListObjectsIterator.php @@ -0,0 +1,68 @@ +get('Contents') ?: array(); + $numObjects = count($objects); + $lastKey = $numObjects ? $objects[$numObjects - 1]['Key'] : false; + if ($lastKey && !$result->hasKey($this->get('output_token'))) { + $result->set($this->get('output_token'), $lastKey); + } + + // Closure for getting the name of an object or prefix + $getName = function ($object) { + return isset($object['Key']) ? $object['Key'] : $object['Prefix']; + }; + + // If common prefixes returned (i.e. a delimiter was set) and they need to be returned, there is more to do + if ($this->get('return_prefixes') && $result->hasKey('CommonPrefixes')) { + // Collect and format the prefixes to include with the objects + $objects = array_merge($objects, $result->get('CommonPrefixes')); + + // Sort the objects and prefixes to maintain alphabetical order, but only if some of each were returned + if ($this->get('sort_results') && $lastKey && $objects) { + usort($objects, function ($object1, $object2) use ($getName) { + return strcmp($getName($object1), $getName($object2)); + }); + } + } + + // If only the names are desired, iterate through the results and convert the arrays to the object/prefix names + if ($this->get('names_only')) { + $objects = array_map($getName, $objects); + } + + return $objects; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Iterator/OpendirIterator.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Iterator/OpendirIterator.php new file mode 100644 index 0000000..82c0153 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Iterator/OpendirIterator.php @@ -0,0 +1,86 @@ +filePrefix = $filePrefix; + $this->dirHandle = $dirHandle; + $this->next(); + } + + public function __destruct() + { + if ($this->dirHandle) { + closedir($this->dirHandle); + } + } + + public function rewind() + { + $this->key = 0; + rewinddir($this->dirHandle); + } + + public function current() + { + return $this->currentFile; + } + + public function next() + { + if ($file = readdir($this->dirHandle)) { + $this->currentFile = new \SplFileInfo($this->filePrefix . $file); + } else { + $this->currentFile = false; + } + + $this->key++; + } + + public function key() + { + return $this->key; + } + + public function valid() + { + return $this->currentFile !== false; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Model/Acp.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Model/Acp.php new file mode 100644 index 0000000..9ddc3dd --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Model/Acp.php @@ -0,0 +1,243 @@ +setOwner($owner); + $this->setGrants($grants); + } + + /** + * Create an Acp object from an array. This can be used to create an ACP from a response to a GetObject/Bucket ACL + * operation. + * + * @param array $data Array of ACP data + * + * @return Acp + */ + public static function fromArray(array $data) + { + $builder = new AcpBuilder(); + $builder->setOwner((string) $data['Owner']['ID'], $data['Owner']['DisplayName']); + + // Add each Grantee to the ACP + foreach ($data['Grants'] as $grant) { + $permission = $grant['Permission']; + + // Determine the type for response bodies that are missing the Type parameter + if (!isset($grant['Grantee']['Type'])) { + if (isset($grant['Grantee']['ID'])) { + $grant['Grantee']['Type'] = 'CanonicalUser'; + } elseif (isset($grant['Grantee']['URI'])) { + $grant['Grantee']['Type'] = 'Group'; + } else { + $grant['Grantee']['Type'] = 'AmazonCustomerByEmail'; + } + } + + switch ($grant['Grantee']['Type']) { + case 'Group': + $builder->addGrantForGroup($permission, $grant['Grantee']['URI']); + break; + case 'AmazonCustomerByEmail': + $builder->addGrantForEmail($permission, $grant['Grantee']['EmailAddress']); + break; + case 'CanonicalUser': + $builder->addGrantForUser( + $permission, + $grant['Grantee']['ID'], + $grant['Grantee']['DisplayName'] + ); + } + } + + return $builder->build(); + } + + /** + * Set the owner of the ACP policy + * + * @param Grantee $owner ACP policy owner + * + * @return $this + * + * @throws InvalidArgumentException if the grantee does not have an ID set + */ + public function setOwner(Grantee $owner) + { + if (!$owner->isCanonicalUser()) { + throw new InvalidArgumentException('The owner must have an ID set.'); + } + + $this->owner = $owner; + + return $this; + } + + /** + * Get the owner of the ACP policy + * + * @return Grantee + */ + public function getOwner() + { + return $this->owner; + } + + /** + * Set the grants for the ACP + * + * @param array|\Traversable $grants List of grants for the ACP + * + * @return $this + * + * @throws InvalidArgumentException + */ + public function setGrants($grants = array()) + { + $this->grants = new \SplObjectStorage(); + + if ($grants) { + if (is_array($grants) || $grants instanceof \Traversable) { + /** @var Grant $grant */ + foreach ($grants as $grant) { + $this->addGrant($grant); + } + } else { + throw new InvalidArgumentException('Grants must be passed in as an array or Traversable object.'); + } + } + + return $this; + } + + /** + * Get all of the grants + * + * @return \SplObjectStorage + */ + public function getGrants() + { + return $this->grants; + } + + /** + * Add a Grant + * + * @param Grant $grant Grant to add + * + * @return $this + */ + public function addGrant(Grant $grant) + { + if (count($this->grants) < 100) { + $this->grants->attach($grant); + } else { + throw new OverflowException('An ACP may contain up to 100 grants.'); + } + + return $this; + } + + /** + * Get the total number of attributes + * + * @return int + */ + public function count() + { + return count($this->grants); + } + + /** + * Returns the grants for iteration + * + * @return \SplObjectStorage + */ + public function getIterator() + { + return $this->grants; + } + + /** + * Applies grant headers to a command's parameters + * + * @param AbstractCommand $command Command to be updated + * + * @return $this + */ + public function updateCommand(AbstractCommand $command) + { + $parameters = array(); + foreach ($this->grants as $grant) { + /** @var Grant $grant */ + $parameters = array_merge_recursive($parameters, $grant->getParameterArray()); + } + + foreach ($parameters as $name => $values) { + $command->set($name, implode(', ', (array) $values)); + } + + return $this; + } + + /** + * {@inheritdoc} + */ + public function toArray() + { + $grants = array(); + foreach ($this->grants as $grant) { + $grants[] = $grant->toArray(); + } + + return array( + 'Owner' => array( + 'ID' => $this->owner->getId(), + 'DisplayName' => $this->owner->getDisplayName() + ), + 'Grants' => $grants + ); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Model/AcpBuilder.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Model/AcpBuilder.php new file mode 100644 index 0000000..b6d1be7 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Model/AcpBuilder.php @@ -0,0 +1,134 @@ +owner = new Grantee($id, $displayName ?: $id, GranteeType::USER); + + return $this; + } + + /** + * Create and store a Grant with a CanonicalUser Grantee for the ACL + * + * @param string $permission Permission for the Grant + * @param string $id Grantee identifier + * @param string $displayName Grantee display name + * + * @return $this + */ + public function addGrantForUser($permission, $id, $displayName = null) + { + $grantee = new Grantee($id, $displayName ?: $id, GranteeType::USER); + $this->addGrant($permission, $grantee); + + return $this; + } + + /** + * Create and store a Grant with a AmazonCustomerByEmail Grantee for the ACL + * + * @param string $permission Permission for the Grant + * @param string $email Grantee email address + * + * @return $this + */ + public function addGrantForEmail($permission, $email) + { + $grantee = new Grantee($email, null, GranteeType::EMAIL); + $this->addGrant($permission, $grantee); + + return $this; + } + + /** + * Create and store a Grant with a Group Grantee for the ACL + * + * @param string $permission Permission for the Grant + * @param string $group Grantee group + * + * @return $this + */ + public function addGrantForGroup($permission, $group) + { + $grantee = new Grantee($group, null, GranteeType::GROUP); + $this->addGrant($permission, $grantee); + + return $this; + } + + /** + * Create and store a Grant for the ACL + * + * @param string $permission Permission for the Grant + * @param Grantee $grantee The Grantee for the Grant + * + * @return $this + */ + public function addGrant($permission, Grantee $grantee) + { + $this->grants[] = new Grant($grantee, $permission); + + return $this; + } + + /** + * Builds the ACP and returns it + * + * @return Acp + */ + public function build() + { + return new Acp($this->owner, $this->grants); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Model/ClearBucket.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Model/ClearBucket.php new file mode 100644 index 0000000..09982d8 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Model/ClearBucket.php @@ -0,0 +1,189 @@ +client = $client; + $this->bucket = $bucket; + } + + /** + * {@inheritdoc} + */ + public static function getAllEvents() + { + return array(self::AFTER_DELETE, self::BEFORE_CLEAR, self::AFTER_CLEAR); + } + + /** + * Set the bucket that is to be cleared + * + * @param string $bucket Name of the bucket to clear + * + * @return $this + */ + public function setBucket($bucket) + { + $this->bucket = $bucket; + + return $this; + } + + /** + * Get the iterator used to yield the keys to be deleted. A default iterator + * will be created and returned if no iterator has been explicitly set. + * + * @return \Iterator + */ + public function getIterator() + { + if (!$this->iterator) { + $this->iterator = $this->client->getIterator('ListObjectVersions', array( + 'Bucket' => $this->bucket + )); + } + + return $this->iterator; + } + + /** + * Sets a different iterator to use than the default iterator. This can be helpful when you wish to delete + * only specific keys from a bucket (e.g. keys that match a certain prefix or delimiter, or perhaps keys that + * pass through a filtered, decorated iterator). + * + * @param \Iterator $iterator Iterator used to yield the keys to be deleted + * + * @return $this + */ + public function setIterator(\Iterator $iterator) + { + $this->iterator = $iterator; + + return $this; + } + + /** + * Set the MFA token to send with each request + * + * @param string $mfa MFA token to send with each request. The value is the concatenation of the authentication + * device's serial number, a space, and the value displayed on your authentication device. + * + * @return $this + */ + public function setMfa($mfa) + { + $this->mfa = $mfa; + + return $this; + } + + /** + * Clear the bucket + * + * @return int Returns the number of deleted keys + * @throws ExceptionCollection + */ + public function clear() + { + $that = $this; + $batch = DeleteObjectsBatch::factory($this->client, $this->bucket, $this->mfa); + $batch = new NotifyingBatch($batch, function ($items) use ($that) { + $that->dispatch(ClearBucket::AFTER_DELETE, array('keys' => $items)); + }); + $batch = new FlushingBatch(new ExceptionBufferingBatch($batch), 1000); + + // Let any listeners know that the bucket is about to be cleared + $this->dispatch(self::BEFORE_CLEAR, array( + 'iterator' => $this->getIterator(), + 'batch' => $batch, + 'mfa' => $this->mfa + )); + + $deleted = 0; + foreach ($this->getIterator() as $object) { + if (isset($object['VersionId'])) { + $versionId = $object['VersionId'] == 'null' ? null : $object['VersionId']; + } else { + $versionId = null; + } + $batch->addKey($object['Key'], $versionId); + $deleted++; + } + $batch->flush(); + + // If any errors were encountered, then throw an ExceptionCollection + if (count($batch->getExceptions())) { + $e = new ExceptionCollection(); + foreach ($batch->getExceptions() as $exception) { + $e->add($exception->getPrevious()); + } + throw $e; + } + + // Let any listeners know that the bucket was cleared + $this->dispatch(self::AFTER_CLEAR, array('deleted' => $deleted)); + + return $deleted; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Model/DeleteObjectsBatch.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Model/DeleteObjectsBatch.php new file mode 100644 index 0000000..ab6425b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Model/DeleteObjectsBatch.php @@ -0,0 +1,87 @@ + %s, VersionId => %s] and call flush when the objects + * should be deleted. + */ +class DeleteObjectsBatch extends AbstractBatchDecorator +{ + /** + * Factory for creating a DeleteObjectsBatch + * + * @param AwsClientInterface $client Client used to transfer requests + * @param string $bucket Bucket that contains the objects to delete + * @param string $mfa MFA token to use with the request + * + * @return static + */ + public static function factory(AwsClientInterface $client, $bucket, $mfa = null) + { + $batch = BatchBuilder::factory() + ->createBatchesWith(new BatchSizeDivisor(1000)) + ->transferWith(new DeleteObjectsTransfer($client, $bucket, $mfa)) + ->build(); + + return new static($batch); + } + + /** + * Add an object to be deleted + * + * @param string $key Key of the object + * @param string $versionId VersionID of the object + * + * @return $this + */ + public function addKey($key, $versionId = null) + { + return $this->add(array( + 'Key' => $key, + 'VersionId' => $versionId + )); + } + + /** + * {@inheritdoc} + */ + public function add($item) + { + if ($item instanceof AbstractCommand && $item->getName() == 'DeleteObject') { + $item = array( + 'Key' => $item['Key'], + 'VersionId' => $item['VersionId'] + ); + } + + if (!is_array($item) || (!isset($item['Key']))) { + throw new InvalidArgumentException('Item must be a DeleteObject command or array containing a Key and VersionId key.'); + } + + return parent::add($item); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Model/DeleteObjectsTransfer.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Model/DeleteObjectsTransfer.php new file mode 100644 index 0000000..5918ff1 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Model/DeleteObjectsTransfer.php @@ -0,0 +1,133 @@ +client = $client; + $this->bucket = $bucket; + $this->mfa = $mfa; + } + + /** + * Set a new MFA token value + * + * @param string $token MFA token + * + * @return $this + */ + public function setMfa($token) + { + $this->mfa = $token; + + return $this; + } + + /** + * {@inheritdoc} + * @throws OverflowException if a batch has more than 1000 items + * @throws InvalidArgumentException when an invalid batch item is encountered + */ + public function transfer(array $batch) + { + if (empty($batch)) { + return; + } + + if (count($batch) > 1000) { + throw new OverflowException('Batches should be divided into chunks of no larger than 1000 keys'); + } + + $del = array(); + $command = $this->client->getCommand('DeleteObjects', array( + 'Bucket' => $this->bucket, + Ua::OPTION => Ua::BATCH + )); + + if ($this->mfa) { + $command->getRequestHeaders()->set('x-amz-mfa', $this->mfa); + } + + foreach ($batch as $object) { + // Ensure that the batch item is valid + if (!is_array($object) || !isset($object['Key'])) { + throw new InvalidArgumentException('Invalid batch item encountered: ' . var_export($batch, true)); + } + $del[] = array( + 'Key' => $object['Key'], + 'VersionId' => isset($object['VersionId']) ? $object['VersionId'] : null + ); + } + + $command['Objects'] = $del; + + $command->execute(); + $this->processResponse($command); + } + + /** + * Process the response of the DeleteMultipleObjects request + * + * @paramCommandInterface $command Command executed + */ + protected function processResponse(CommandInterface $command) + { + $result = $command->getResult(); + + // Ensure that the objects were deleted successfully + if (!empty($result['Errors'])) { + $errors = $result['Errors']; + throw new DeleteMultipleObjectsException($errors); + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Model/Grant.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Model/Grant.php new file mode 100644 index 0000000..2e35f05 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Model/Grant.php @@ -0,0 +1,139 @@ + 'GrantRead', + Permission::WRITE => 'GrantWrite', + Permission::READ_ACP => 'GrantReadACP', + Permission::WRITE_ACP => 'GrantWriteACP', + Permission::FULL_CONTROL => 'GrantFullControl' + ); + + /** + * @var Grantee The grantee affected by the grant + */ + protected $grantee; + + /** + * @var string The permission set by the grant + */ + protected $permission; + + /** + * Constructs an ACL + * + * @param Grantee $grantee Affected grantee + * @param string $permission Permission applied + */ + public function __construct(Grantee $grantee, $permission) + { + $this->setGrantee($grantee); + $this->setPermission($permission); + } + + /** + * Set the grantee affected by the grant + * + * @param Grantee $grantee Affected grantee + * + * @return $this + */ + public function setGrantee(Grantee $grantee) + { + $this->grantee = $grantee; + + return $this; + } + + /** + * Get the grantee affected by the grant + * + * @return Grantee + */ + public function getGrantee() + { + return $this->grantee; + } + + /** + * Set the permission set by the grant + * + * @param string $permission Permission applied + * + * @return $this + * + * @throws InvalidArgumentException + */ + public function setPermission($permission) + { + $valid = Permission::values(); + if (!in_array($permission, $valid)) { + throw new InvalidArgumentException('The permission must be one of ' + . 'the following: ' . implode(', ', $valid) . '.'); + } + + $this->permission = $permission; + + return $this; + } + + /** + * Get the permission set by the grant + * + * @return string + */ + public function getPermission() + { + return $this->permission; + } + + /** + * Returns an array of the operation parameter and value to set on the operation + * + * @return array + */ + public function getParameterArray() + { + return array( + self::$parameterMap[$this->permission] => $this->grantee->getHeaderValue() + ); + } + + /** + * {@inheritdoc} + */ + public function toArray() + { + return array( + 'Grantee' => $this->grantee->toArray(), + 'Permission' => $this->permission + ); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Model/Grantee.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Model/Grantee.php new file mode 100644 index 0000000..7634b84 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Model/Grantee.php @@ -0,0 +1,245 @@ + 'id', + GranteeType::EMAIL => 'emailAddress', + GranteeType::GROUP => 'uri' + ); + + /** + * @var string The account ID, email, or URL identifying the grantee + */ + protected $id; + + /** + * @var string The display name of the grantee + */ + protected $displayName; + + /** + * @var string The type of the grantee (CanonicalUser or Group) + */ + protected $type; + + /** + * Constructs a Grantee + * + * @param string $id Grantee identifier + * @param string $displayName Grantee display name + * @param string $expectedType The expected type of the grantee + */ + public function __construct($id, $displayName = null, $expectedType = null) + { + $this->type = GranteeType::USER; + $this->setId($id, $expectedType); + $this->setDisplayName($displayName); + } + + /** + * Sets the account ID, email, or URL identifying the grantee + * + * @param string $id Grantee identifier + * @param string $expectedType The expected type of the grantee + * + * @return Grantee + * + * @throws UnexpectedValueException if $expectedType is set and the grantee + * is not of that type after instantiation + * @throws InvalidArgumentException when the ID provided is not a string + */ + public function setId($id, $expectedType = null) + { + if (in_array($id, Group::values())) { + $this->type = GranteeType::GROUP; + } elseif (!is_string($id)) { + throw new InvalidArgumentException('The grantee ID must be provided as a string value.'); + } + + if (strpos($id, '@') !== false) { + $this->type = GranteeType::EMAIL; + } + + if ($expectedType && $expectedType !== $this->type) { + throw new UnexpectedValueException('The type of the grantee after ' + . 'setting the ID did not match the specified, expected type "' + . $expectedType . '" but received "' . $this->type . '".'); + } + + $this->id = $id; + + return $this; + } + + /** + * Gets the grantee identifier + * + * @return string + */ + public function getId() + { + return $this->id; + } + + /** + * Gets the grantee email address (if it is set) + * + * @return null|string + */ + public function getEmailAddress() + { + return $this->isAmazonCustomerByEmail() ? $this->id : null; + } + + /** + * Gets the grantee URI (if it is set) + * + * @return null|string + */ + public function getGroupUri() + { + return $this->isGroup() ? $this->id : null; + } + + /** + * Sets the display name of the grantee + * + * @param string $displayName Grantee name + * + * @return Grantee + * + * @throws LogicException when the grantee type not CanonicalUser + */ + public function setDisplayName($displayName) + { + if ($this->type === GranteeType::USER) { + if (empty($displayName) || !is_string($displayName)) { + $displayName = $this->id; + } + $this->displayName = $displayName; + } else { + if ($displayName) { + throw new LogicException('The display name can only be set ' + . 'for grantees specified by ID.'); + } + } + + return $this; + } + + /** + * Gets the grantee display name + * + * @return string + */ + public function getDisplayName() + { + return $this->displayName; + } + + /** + * Gets the grantee type (determined by ID) + * + * @return string + */ + public function getType() + { + return $this->type; + } + + /** + * Returns true if this grantee object represents a canonical user by ID + * + * @return bool + */ + public function isCanonicalUser() + { + return ($this->type === GranteeType::USER); + } + + /** + * Returns true if this grantee object represents a customer by email + * + * @return bool + */ + public function isAmazonCustomerByEmail() + { + return ($this->type === GranteeType::EMAIL); + } + + /** + * Returns true if this grantee object represents a group by URL + * + * @return bool + */ + public function isGroup() + { + return ($this->type === GranteeType::GROUP); + } + + /** + * Returns the value used in headers to specify this grantee + * + * @return string + */ + public function getHeaderValue() + { + $key = static::$headerMap[$this->type]; + + return "{$key}=\"{$this->id}\""; + } + + /** + * {@inheritdoc} + */ + public function toArray() + { + $result = array( + 'Type' => $this->type + ); + + switch ($this->type) { + case GranteeType::USER: + $result['ID'] = $this->id; + $result['DisplayName'] = $this->displayName; + break; + case GranteeType::EMAIL: + $result['EmailAddress'] = $this->id; + break; + case GranteeType::GROUP: + $result['URI'] = $this->id; + } + + return $result; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Model/MultipartUpload/AbstractTransfer.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Model/MultipartUpload/AbstractTransfer.php new file mode 100644 index 0000000..b1a5734 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Model/MultipartUpload/AbstractTransfer.php @@ -0,0 +1,103 @@ +options = array_replace(array( + 'min_part_size' => self::MIN_PART_SIZE, + 'part_md5' => true + ), $this->options); + + // Make sure the part size can be calculated somehow + if (!$this->options['min_part_size'] && !$this->source->getContentLength()) { + throw new RuntimeException('The ContentLength of the data source could not be determined, and no ' + . 'min_part_size option was provided'); + } + } + + /** + * {@inheritdoc} + */ + protected function calculatePartSize() + { + $partSize = $this->source->getContentLength() + ? (int) ceil(($this->source->getContentLength() / self::MAX_PARTS)) + : self::MIN_PART_SIZE; + $partSize = max($this->options['min_part_size'], $partSize); + $partSize = min($partSize, self::MAX_PART_SIZE); + $partSize = max($partSize, self::MIN_PART_SIZE); + + return $partSize; + } + + /** + * {@inheritdoc} + */ + protected function complete() + { + /** @var UploadPart $part */ + $parts = array(); + foreach ($this->state as $part) { + $parts[] = array( + 'PartNumber' => $part->getPartNumber(), + 'ETag' => $part->getETag(), + ); + } + + $params = $this->state->getUploadId()->toParams(); + $params[Ua::OPTION] = Ua::MULTIPART_UPLOAD; + $params['Parts'] = $parts; + $command = $this->client->getCommand('CompleteMultipartUpload', $params); + + return $command->getResult(); + } + + /** + * {@inheritdoc} + */ + protected function getAbortCommand() + { + $params = $this->state->getUploadId()->toParams(); + $params[Ua::OPTION] = Ua::MULTIPART_UPLOAD; + + /** @var OperationCommand $command */ + $command = $this->client->getCommand('AbortMultipartUpload', $params); + + return $command; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Model/MultipartUpload/ParallelTransfer.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Model/MultipartUpload/ParallelTransfer.php new file mode 100644 index 0000000..b42c3c4 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Model/MultipartUpload/ParallelTransfer.php @@ -0,0 +1,124 @@ +source->isLocal() || $this->source->getWrapper() != 'plainfile') { + throw new RuntimeException('The source data must be a local file stream when uploading in parallel.'); + } + + if (empty($this->options['concurrency'])) { + throw new RuntimeException('The `concurrency` option must be specified when instantiating.'); + } + } + + /** + * {@inheritdoc} + */ + protected function transfer() + { + $totalParts = (int) ceil($this->source->getContentLength() / $this->partSize); + $concurrency = min($totalParts, $this->options['concurrency']); + $partsToSend = $this->prepareParts($concurrency); + $eventData = $this->getEventData(); + + while (!$this->stopped && count($this->state) < $totalParts) { + + $currentTotal = count($this->state); + $commands = array(); + + for ($i = 0; $i < $concurrency && $i + $currentTotal < $totalParts; $i++) { + + // Move the offset to the correct position + $partsToSend[$i]->setOffset(($currentTotal + $i) * $this->partSize); + + // @codeCoverageIgnoreStart + if ($partsToSend[$i]->getContentLength() == 0) { + break; + } + // @codeCoverageIgnoreEnd + + $params = $this->state->getUploadId()->toParams(); + $eventData['command'] = $this->client->getCommand('UploadPart', array_replace($params, array( + 'PartNumber' => count($this->state) + 1 + $i, + 'Body' => $partsToSend[$i], + 'ContentMD5' => (bool) $this->options['part_md5'], + Ua::OPTION => Ua::MULTIPART_UPLOAD + ))); + $commands[] = $eventData['command']; + // Notify any listeners of the part upload + $this->dispatch(self::BEFORE_PART_UPLOAD, $eventData); + } + + // Allow listeners to stop the transfer if needed + if ($this->stopped) { + break; + } + + // Execute each command, iterate over the results, and add to the transfer state + /** @var \Guzzle\Service\Command\OperationCommand $command */ + foreach ($this->client->execute($commands) as $command) { + $this->state->addPart(UploadPart::fromArray(array( + 'PartNumber' => $command['PartNumber'], + 'ETag' => $command->getResponse()->getEtag(), + 'Size' => (int) $command->getRequest()->getBody()->getContentLength(), + 'LastModified' => gmdate(DateFormat::RFC2822) + ))); + $eventData['command'] = $command; + // Notify any listeners the the part was uploaded + $this->dispatch(self::AFTER_PART_UPLOAD, $eventData); + } + } + } + + /** + * Prepare the entity body handles to use while transferring + * + * @param int $concurrency Number of parts to prepare + * + * @return array Parts to send + */ + protected function prepareParts($concurrency) + { + $url = $this->source->getUri(); + // Use the source EntityBody as the first part + $parts = array(new ReadLimitEntityBody($this->source, $this->partSize)); + // Open EntityBody handles for each part to upload in parallel + for ($i = 1; $i < $concurrency; $i++) { + $parts[] = new ReadLimitEntityBody(new EntityBody(fopen($url, 'r')), $this->partSize); + } + + return $parts; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Model/MultipartUpload/SerialTransfer.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Model/MultipartUpload/SerialTransfer.php new file mode 100644 index 0000000..2840dd5 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Model/MultipartUpload/SerialTransfer.php @@ -0,0 +1,86 @@ +stopped && !$this->source->isConsumed()) { + + if ($this->source->getContentLength() && $this->source->isSeekable()) { + // If the stream is seekable and the Content-Length known, then stream from the data source + $body = new ReadLimitEntityBody($this->source, $this->partSize, $this->source->ftell()); + } else { + // We need to read the data source into a temporary buffer before streaming + $body = EntityBody::factory(); + while ($body->getContentLength() < $this->partSize + && $body->write( + $this->source->read(max(1, min(10 * Size::KB, $this->partSize - $body->getContentLength()))) + )); + } + + // @codeCoverageIgnoreStart + if ($body->getContentLength() == 0) { + break; + } + // @codeCoverageIgnoreEnd + + $params = $this->state->getUploadId()->toParams(); + $command = $this->client->getCommand('UploadPart', array_replace($params, array( + 'PartNumber' => count($this->state) + 1, + 'Body' => $body, + 'ContentMD5' => (bool) $this->options['part_md5'], + Ua::OPTION => Ua::MULTIPART_UPLOAD + ))); + + // Notify observers that the part is about to be uploaded + $eventData = $this->getEventData(); + $eventData['command'] = $command; + $this->dispatch(self::BEFORE_PART_UPLOAD, $eventData); + + // Allow listeners to stop the transfer if needed + if ($this->stopped) { + break; + } + + $response = $command->getResponse(); + + $this->state->addPart(UploadPart::fromArray(array( + 'PartNumber' => $command['PartNumber'], + 'ETag' => $response->getEtag(), + 'Size' => $body->getContentLength(), + 'LastModified' => gmdate(DateFormat::RFC2822) + ))); + + // Notify observers that the part was uploaded + $this->dispatch(self::AFTER_PART_UPLOAD, $eventData); + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Model/MultipartUpload/TransferState.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Model/MultipartUpload/TransferState.php new file mode 100644 index 0000000..c63663f --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Model/MultipartUpload/TransferState.php @@ -0,0 +1,41 @@ +getIterator('ListParts', $uploadId->toParams()) as $part) { + $transferState->addPart(UploadPart::fromArray($part)); + } + + return $transferState; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Model/MultipartUpload/UploadBuilder.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Model/MultipartUpload/UploadBuilder.php new file mode 100644 index 0000000..e30f23a --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Model/MultipartUpload/UploadBuilder.php @@ -0,0 +1,297 @@ +setOption('Bucket', $bucket); + } + + /** + * Set the key of the object + * + * @param string $key Key of the object to upload + * + * @return $this + */ + public function setKey($key) + { + return $this->setOption('Key', $key); + } + + /** + * Set the minimum acceptable part size + * + * @param int $minSize Minimum acceptable part size in bytes + * + * @return $this + */ + public function setMinPartSize($minSize) + { + $this->minPartSize = (int) max((int) $minSize, AbstractTransfer::MIN_PART_SIZE); + + return $this; + } + + /** + * Set the concurrency level to use when uploading parts. This affects how + * many parts are uploaded in parallel. You must use a local file as your + * data source when using a concurrency greater than 1 + * + * @param int $concurrency Concurrency level + * + * @return $this + */ + public function setConcurrency($concurrency) + { + $this->concurrency = $concurrency; + + return $this; + } + + /** + * Explicitly set the MD5 hash of the entire body + * + * @param string $md5 MD5 hash of the entire body + * + * @return $this + */ + public function setMd5($md5) + { + $this->md5 = $md5; + + return $this; + } + + /** + * Set to true to have the builder calculate the MD5 hash of the entire data + * source before initiating a multipart upload (this could be an expensive + * operation). This setting can ony be used with seekable data sources. + * + * @param bool $calculateMd5 Set to true to calculate the MD5 hash of the body + * + * @return $this + */ + public function calculateMd5($calculateMd5) + { + $this->calculateEntireMd5 = (bool) $calculateMd5; + + return $this; + } + + /** + * Specify whether or not to calculate the MD5 hash of each uploaded part. + * This setting defaults to true. + * + * @param bool $usePartMd5 Set to true to calculate the MD5 has of each part + * + * @return $this + */ + public function calculatePartMd5($usePartMd5) + { + $this->calculatePartMd5 = (bool) $usePartMd5; + + return $this; + } + + /** + * Set the ACP to use on the object + * + * @param Acp $acp ACP to set on the object + * + * @return $this + */ + public function setAcp(Acp $acp) + { + return $this->setOption('ACP', $acp); + } + + /** + * Set an option to pass to the initial CreateMultipartUpload operation + * + * @param string $name Option name + * @param string $value Option value + * + * @return $this + */ + public function setOption($name, $value) + { + $this->commandOptions[$name] = $value; + + return $this; + } + + /** + * Add an array of options to pass to the initial CreateMultipartUpload operation + * + * @param array $options Array of CreateMultipartUpload operation parameters + * + * @return $this + */ + public function addOptions(array $options) + { + $this->commandOptions = array_replace($this->commandOptions, $options); + + return $this; + } + + /** + * Set an array of transfer options to apply to the upload transfer object + * + * @param array $options Transfer options + * + * @return $this + */ + public function setTransferOptions(array $options) + { + $this->transferOptions = $options; + + return $this; + } + + /** + * {@inheritdoc} + * @throws InvalidArgumentException when attempting to resume a transfer using a non-seekable stream + * @throws InvalidArgumentException when missing required properties (bucket, key, client, source) + */ + public function build() + { + if ($this->state instanceof TransferState) { + $this->commandOptions = array_replace($this->commandOptions, $this->state->getUploadId()->toParams()); + } + + if (!isset($this->commandOptions['Bucket']) || !isset($this->commandOptions['Key']) + || !$this->client || !$this->source + ) { + throw new InvalidArgumentException('You must specify a Bucket, Key, client, and source.'); + } + + if ($this->state && !$this->source->isSeekable()) { + throw new InvalidArgumentException('You cannot resume a transfer using a non-seekable source.'); + } + + // If no state was set, then create one by initiating or loading a multipart upload + if (is_string($this->state)) { + $this->state = TransferState::fromUploadId($this->client, UploadId::fromParams(array( + 'Bucket' => $this->commandOptions['Bucket'], + 'Key' => $this->commandOptions['Key'], + 'UploadId' => $this->state + ))); + } elseif (!$this->state) { + $this->state = $this->initiateMultipartUpload(); + } + + $options = array_replace(array( + 'min_part_size' => $this->minPartSize, + 'part_md5' => (bool) $this->calculatePartMd5, + 'concurrency' => $this->concurrency + ), $this->transferOptions); + + return $this->concurrency > 1 + ? new ParallelTransfer($this->client, $this->state, $this->source, $options) + : new SerialTransfer($this->client, $this->state, $this->source, $options); + } + + /** + * {@inheritdoc} + */ + protected function initiateMultipartUpload() + { + // Determine Content-Type + if (!isset($this->commandOptions['ContentType'])) { + if ($mimeType = $this->source->getContentType()) { + $this->commandOptions['ContentType'] = $mimeType; + } + } + + $params = array_replace(array( + Ua::OPTION => Ua::MULTIPART_UPLOAD, + 'command.headers' => $this->headers, + 'Metadata' => array() + ), $this->commandOptions); + + // Calculate the MD5 hash if none was set and it is asked of the builder + if ($this->calculateEntireMd5) { + $this->md5 = $this->source->getContentMd5(); + } + + // If an MD5 is specified, then add it to the custom headers of the request + // so that it will be returned when downloading the object from Amazon S3 + if ($this->md5) { + $params['Metadata']['x-amz-Content-MD5'] = $this->md5; + } + + $result = $this->client->getCommand('CreateMultipartUpload', $params)->execute(); + // Create a new state based on the initiated upload + $params['UploadId'] = $result['UploadId']; + + return new TransferState(UploadId::fromParams($params)); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Model/MultipartUpload/UploadId.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Model/MultipartUpload/UploadId.php new file mode 100644 index 0000000..9d5f384 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Model/MultipartUpload/UploadId.php @@ -0,0 +1,35 @@ + false, + 'Key' => false, + 'UploadId' => false + ); +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Model/MultipartUpload/UploadPart.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Model/MultipartUpload/UploadPart.php new file mode 100644 index 0000000..e0ded33 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Model/MultipartUpload/UploadPart.php @@ -0,0 +1,74 @@ + 'partNumber', + 'ETag' => 'eTag', + 'LastModified' => 'lastModified', + 'Size' => 'size' + ); + + /** + * @var string The ETag for this part + */ + protected $eTag; + + /** + * @var string The last modified date + */ + protected $lastModified; + + /** + * @var int The size (or content-length) in bytes of the upload body + */ + protected $size; + + /** + * @return string + */ + public function getETag() + { + return $this->eTag; + } + + /** + * @return string + */ + public function getLastModified() + { + return $this->lastModified; + } + + /** + * @return int + */ + public function getSize() + { + return $this->size; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Model/PostObject.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Model/PostObject.php new file mode 100644 index 0000000..0aa2dbc --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Model/PostObject.php @@ -0,0 +1,275 @@ + tag attributes as an array + */ + protected $formAttributes; + + /** + * @var array The form's elements as an array + */ + protected $formInputs; + + /** + * @var string The raw json policy + */ + protected $jsonPolicy; + + /** + * Constructs the PostObject + * + * The options array accepts the following keys: + * + * - acl: The access control setting to apply to the uploaded file. Accepts any of the + * CannedAcl constants + * - Cache-Control: The Cache-Control HTTP header value to apply to the uploaded file + * - Content-Disposition: The Content-Disposition HTTP header value to apply to the uploaded file + * - Content-Encoding: The Content-Encoding HTTP header value to apply to the uploaded file + * - Content-Type: The Content-Type HTTP header value to apply to the uploaded file. The default + * value is `application/octet-stream` + * - Expires: The Expires HTTP header value to apply to the uploaded file + * - key: The location where the file should be uploaded to. The default value is + * `^${filename}` which will use the name of the uploaded file + * - policy: A raw policy in JSON format. By default, the PostObject creates one for you + * - policy_callback: A callback used to modify the policy before encoding and signing it. The + * method signature for the callback should accept an array of the policy data as + * the 1st argument, (optionally) the PostObject as the 2nd argument, and return + * the policy data with the desired modifications. + * - success_action_redirect: The URI for Amazon S3 to redirect to upon successful upload + * - success_action_status: The status code for Amazon S3 to return upon successful upload + * - ttd: The expiration time for the generated upload form data + * - x-amz-meta-*: Any custom meta tag that should be set to the object + * - x-amz-server-side-encryption: The server-side encryption mechanism to use + * - x-amz-storage-class: The storage setting to apply to the object + * - x-amz-server-side​-encryption​-customer-algorithm: The SSE-C algorithm + * - x-amz-server-side​-encryption​-customer-key: The SSE-C customer secret key + * - x-amz-server-side​-encryption​-customer-key-MD5: The MD5 hash of the SSE-C customer secret key + * + * For the Cache-Control, Content-Disposition, Content-Encoding, + * Content-Type, Expires, and key options, to use a "starts-with" comparison + * instead of an equals comparison, prefix the value with a ^ (carat) + * character + * + * @param S3Client $client + * @param $bucket + * @param array $options + */ + public function __construct(S3Client $client, $bucket, array $options = array()) + { + $this->setClient($client); + $this->setBucket($bucket); + parent::__construct($options); + } + + /** + * Analyzes the provided data and turns it into useful data that can be + * consumed and used to build an upload form + * + * @return PostObject + */ + public function prepareData() + { + // Validate required options + $options = Collection::fromConfig($this->data, array( + 'ttd' => '+1 hour', + 'key' => '^${filename}', + )); + + // Format ttd option + $ttd = $options['ttd']; + $ttd = is_numeric($ttd) ? (int) $ttd : strtotime($ttd); + unset($options['ttd']); + + // If a policy or policy callback were provided, extract those from the options + $rawJsonPolicy = $options['policy']; + $policyCallback = $options['policy_callback']; + unset($options['policy'], $options['policy_callback']); + + // Setup policy document + $policy = array( + 'expiration' => gmdate(DateFormat::ISO8601_S3, $ttd), + 'conditions' => array(array('bucket' => $this->bucket)) + ); + + // Configure the endpoint/action + $url = Url::factory($this->client->getBaseUrl()); + if ($url->getScheme() === 'https' && strpos($this->bucket, '.') !== false) { + // Use path-style URLs + $url->setPath($this->bucket); + } else { + // Use virtual-style URLs + $url->setHost($this->bucket . '.' . $url->getHost()); + } + + // Setup basic form + $this->formAttributes = array( + 'action' => (string) $url, + 'method' => 'POST', + 'enctype' => 'multipart/form-data' + ); + $this->formInputs = array( + 'AWSAccessKeyId' => $this->client->getCredentials()->getAccessKeyId() + ); + + // Add success action status + $status = (int) $options->get('success_action_status'); + if ($status && in_array($status, array(200, 201, 204))) { + $this->formInputs['success_action_status'] = (string) $status; + $policy['conditions'][] = array( + 'success_action_status' => (string) $status + ); + unset($options['success_action_status']); + } + + // Add other options + foreach ($options as $key => $value) { + $value = (string) $value; + if ($value[0] === '^') { + $value = substr($value, 1); + $this->formInputs[$key] = $value; + $value = preg_replace('/\$\{(\w*)\}/', '', $value); + $policy['conditions'][] = array('starts-with', '$' . $key, $value); + } else { + $this->formInputs[$key] = $value; + $policy['conditions'][] = array($key => $value); + } + } + + // Handle the policy + $policy = is_callable($policyCallback) ? $policyCallback($policy, $this) : $policy; + $this->jsonPolicy = $rawJsonPolicy ?: json_encode($policy); + $this->applyPolicy(); + + return $this; + } + + /** + * Sets the S3 client + * + * @param S3Client $client + * + * @return PostObject + */ + public function setClient(S3Client $client) + { + $this->client = $client; + + return $this; + } + + /** + * Gets the S3 client + * + * @return S3Client + */ + public function getClient() + { + return $this->client; + } + + /** + * Sets the bucket and makes sure it is a valid bucket name + * + * @param string $bucket + * + * @return PostObject + */ + public function setBucket($bucket) + { + $this->bucket = $bucket; + + return $this; + } + + /** + * Gets the bucket name + * + * @return string + */ + public function getBucket() + { + return $this->bucket; + } + + /** + * Gets the form attributes as an array + * + * @return array + */ + public function getFormAttributes() + { + return $this->formAttributes; + } + + /** + * Gets the form inputs as an array + * + * @return array + */ + public function getFormInputs() + { + return $this->formInputs; + } + + /** + * Gets the raw JSON policy + * + * @return string + */ + public function getJsonPolicy() + { + return $this->jsonPolicy; + } + + /** + * Handles the encoding, singing, and injecting of the policy + */ + protected function applyPolicy() + { + $jsonPolicy64 = base64_encode($this->jsonPolicy); + $this->formInputs['policy'] = $jsonPolicy64; + + $this->formInputs['signature'] = base64_encode(hash_hmac( + 'sha1', + $jsonPolicy64, + $this->client->getCredentials()->getSecretKey(), + true + )); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Resources/s3-2006-03-01.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Resources/s3-2006-03-01.php new file mode 100644 index 0000000..381a410 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Resources/s3-2006-03-01.php @@ -0,0 +1,5769 @@ + '2006-03-01', + 'endpointPrefix' => 's3', + 'serviceFullName' => 'Amazon Simple Storage Service', + 'serviceAbbreviation' => 'Amazon S3', + 'serviceType' => 'rest-xml', + 'timestampFormat' => 'rfc822', + 'globalEndpoint' => 's3.amazonaws.com', + 'signatureVersion' => 's3', + 'namespace' => 'S3', + 'regions' => array( + 'us-east-1' => array( + 'http' => true, + 'https' => true, + 'hostname' => 's3.amazonaws.com', + ), + 'us-west-1' => array( + 'http' => true, + 'https' => true, + 'hostname' => 's3-us-west-1.amazonaws.com', + ), + 'us-west-2' => array( + 'http' => true, + 'https' => true, + 'hostname' => 's3-us-west-2.amazonaws.com', + ), + 'eu-west-1' => array( + 'http' => true, + 'https' => true, + 'hostname' => 's3-eu-west-1.amazonaws.com', + ), + 'eu-central-1' => array( + 'http' => true, + 'https' => true, + 'hostname' => 's3-eu-central-1.amazonaws.com', + ), + 'ap-northeast-1' => array( + 'http' => true, + 'https' => true, + 'hostname' => 's3-ap-northeast-1.amazonaws.com', + ), + 'ap-southeast-1' => array( + 'http' => true, + 'https' => true, + 'hostname' => 's3-ap-southeast-1.amazonaws.com', + ), + 'ap-southeast-2' => array( + 'http' => true, + 'https' => true, + 'hostname' => 's3-ap-southeast-2.amazonaws.com', + ), + 'sa-east-1' => array( + 'http' => true, + 'https' => true, + 'hostname' => 's3-sa-east-1.amazonaws.com', + ), + 'cn-north-1' => array( + 'http' => true, + 'https' => true, + 'hostname' => 's3.cn-north-1.amazonaws.com.cn', + ), + 'us-gov-west-1' => array( + 'http' => true, + 'https' => true, + 'hostname' => 's3-us-gov-west-1.amazonaws.com', + ), + ), + 'operations' => array( + 'AbortMultipartUpload' => array( + 'httpMethod' => 'DELETE', + 'uri' => '/{Bucket}{/Key*}', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'AbortMultipartUploadOutput', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadAbort.html', + 'parameters' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + 'Key' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + 'minLength' => 1, + 'filters' => array( + 'Aws\\S3\\S3Client::explodeKey', + ), + ), + 'UploadId' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'query', + 'sentAs' => 'uploadId', + ), + 'RequestPayer' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-request-payer', + ), + ), + 'errorResponses' => array( + array( + 'reason' => 'The specified multipart upload does not exist.', + 'class' => 'NoSuchUploadException', + ), + ), + ), + 'CompleteMultipartUpload' => array( + 'httpMethod' => 'POST', + 'uri' => '/{Bucket}{/Key*}', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'CompleteMultipartUploadOutput', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadComplete.html', + 'data' => array( + 'xmlRoot' => array( + 'name' => 'CompleteMultipartUpload', + 'namespaces' => array( + 'http://s3.amazonaws.com/doc/2006-03-01/', + ), + ), + ), + 'parameters' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + 'Key' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + 'minLength' => 1, + 'filters' => array( + 'Aws\\S3\\S3Client::explodeKey', + ), + ), + 'Parts' => array( + 'type' => 'array', + 'location' => 'xml', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'CompletedPart', + 'type' => 'object', + 'sentAs' => 'Part', + 'properties' => array( + 'ETag' => array( + 'type' => 'string', + ), + 'PartNumber' => array( + 'type' => 'numeric', + ), + ), + ), + ), + 'UploadId' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'query', + 'sentAs' => 'uploadId', + ), + 'RequestPayer' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-request-payer', + ), + 'command.expects' => array( + 'static' => true, + 'default' => 'application/xml', + ), + ), + ), + 'CopyObject' => array( + 'httpMethod' => 'PUT', + 'uri' => '/{Bucket}{/Key*}', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'CopyObjectOutput', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectCOPY.html', + 'data' => array( + 'xmlRoot' => array( + 'name' => 'CopyObjectRequest', + 'namespaces' => array( + 'http://s3.amazonaws.com/doc/2006-03-01/', + ), + ), + ), + 'parameters' => array( + 'ACL' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-acl', + ), + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + 'CacheControl' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'Cache-Control', + ), + 'ContentDisposition' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'Content-Disposition', + ), + 'ContentEncoding' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'Content-Encoding', + ), + 'ContentLanguage' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'Content-Language', + ), + 'ContentType' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'Content-Type', + ), + 'CopySource' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-copy-source', + ), + 'CopySourceIfMatch' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-copy-source-if-match', + ), + 'CopySourceIfModifiedSince' => array( + 'type' => array( + 'object', + 'string', + 'integer', + ), + 'format' => 'date-time-http', + 'location' => 'header', + 'sentAs' => 'x-amz-copy-source-if-modified-since', + ), + 'CopySourceIfNoneMatch' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-copy-source-if-none-match', + ), + 'CopySourceIfUnmodifiedSince' => array( + 'type' => array( + 'object', + 'string', + 'integer', + ), + 'format' => 'date-time-http', + 'location' => 'header', + 'sentAs' => 'x-amz-copy-source-if-unmodified-since', + ), + 'Expires' => array( + 'type' => array( + 'object', + 'string', + 'integer', + ), + 'format' => 'date-time-http', + 'location' => 'header', + ), + 'GrantFullControl' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-grant-full-control', + ), + 'GrantRead' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-grant-read', + ), + 'GrantReadACP' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-grant-read-acp', + ), + 'GrantWriteACP' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-grant-write-acp', + ), + 'Key' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + 'minLength' => 1, + 'filters' => array( + 'Aws\\S3\\S3Client::explodeKey', + ), + ), + 'Metadata' => array( + 'type' => 'object', + 'location' => 'header', + 'sentAs' => 'x-amz-meta-', + 'additionalProperties' => array( + 'type' => 'string', + ), + ), + 'MetadataDirective' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-metadata-directive', + ), + 'ServerSideEncryption' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption', + ), + 'StorageClass' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-storage-class', + ), + 'WebsiteRedirectLocation' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-website-redirect-location', + ), + 'SSECustomerAlgorithm' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption-customer-algorithm', + ), + 'SSECustomerKey' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption-customer-key', + ), + 'SSECustomerKeyMD5' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption-customer-key-MD5', + ), + 'SSEKMSKeyId' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption-aws-kms-key-id', + ), + 'CopySourceSSECustomerAlgorithm' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-copy-source-server-side-encryption-customer-algorithm', + ), + 'CopySourceSSECustomerKey' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-copy-source-server-side-encryption-customer-key', + ), + 'CopySourceSSECustomerKeyMD5' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-copy-source-server-side-encryption-customer-key-MD5', + ), + 'RequestPayer' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-request-payer', + ), + 'ACP' => array( + 'type' => 'object', + 'additionalProperties' => true, + ), + 'command.expects' => array( + 'static' => true, + 'default' => 'application/xml', + ), + ), + 'errorResponses' => array( + array( + 'reason' => 'The source object of the COPY operation is not in the active tier and is only stored in Amazon Glacier.', + 'class' => 'ObjectNotInActiveTierErrorException', + ), + ), + ), + 'CreateBucket' => array( + 'httpMethod' => 'PUT', + 'uri' => '/{Bucket}', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'CreateBucketOutput', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUT.html', + 'data' => array( + 'xmlRoot' => array( + 'name' => 'CreateBucketConfiguration', + 'namespaces' => array( + 'http://s3.amazonaws.com/doc/2006-03-01/', + ), + ), + ), + 'parameters' => array( + 'ACL' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-acl', + ), + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + 'LocationConstraint' => array( + 'type' => 'string', + 'location' => 'xml', + ), + 'GrantFullControl' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-grant-full-control', + ), + 'GrantRead' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-grant-read', + ), + 'GrantReadACP' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-grant-read-acp', + ), + 'GrantWrite' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-grant-write', + ), + 'GrantWriteACP' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-grant-write-acp', + ), + 'ACP' => array( + 'type' => 'object', + 'additionalProperties' => true, + ), + ), + 'errorResponses' => array( + array( + 'reason' => 'The requested bucket name is not available. The bucket namespace is shared by all users of the system. Please select a different name and try again.', + 'class' => 'BucketAlreadyExistsException', + ), + ), + ), + 'CreateMultipartUpload' => array( + 'httpMethod' => 'POST', + 'uri' => '/{Bucket}{/Key*}?uploads', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'CreateMultipartUploadOutput', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadInitiate.html', + 'data' => array( + 'xmlRoot' => array( + 'name' => 'CreateMultipartUploadRequest', + 'namespaces' => array( + 'http://s3.amazonaws.com/doc/2006-03-01/', + ), + ), + ), + 'parameters' => array( + 'ACL' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-acl', + ), + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + 'CacheControl' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'Cache-Control', + ), + 'ContentDisposition' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'Content-Disposition', + ), + 'ContentEncoding' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'Content-Encoding', + ), + 'ContentLanguage' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'Content-Language', + ), + 'ContentType' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'Content-Type', + ), + 'Expires' => array( + 'type' => array( + 'object', + 'string', + 'integer', + ), + 'format' => 'date-time-http', + 'location' => 'header', + ), + 'GrantFullControl' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-grant-full-control', + ), + 'GrantRead' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-grant-read', + ), + 'GrantReadACP' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-grant-read-acp', + ), + 'GrantWriteACP' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-grant-write-acp', + ), + 'Key' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + 'minLength' => 1, + 'filters' => array( + 'Aws\\S3\\S3Client::explodeKey', + ), + ), + 'Metadata' => array( + 'type' => 'object', + 'location' => 'header', + 'sentAs' => 'x-amz-meta-', + 'additionalProperties' => array( + 'type' => 'string', + ), + ), + 'ServerSideEncryption' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption', + ), + 'StorageClass' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-storage-class', + ), + 'WebsiteRedirectLocation' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-website-redirect-location', + ), + 'SSECustomerAlgorithm' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption-customer-algorithm', + ), + 'SSECustomerKey' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption-customer-key', + ), + 'SSECustomerKeyMD5' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption-customer-key-MD5', + ), + 'SSEKMSKeyId' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption-aws-kms-key-id', + ), + 'RequestPayer' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-request-payer', + ), + 'ACP' => array( + 'type' => 'object', + 'additionalProperties' => true, + ), + 'command.expects' => array( + 'static' => true, + 'default' => 'application/xml', + ), + ), + ), + 'DeleteBucket' => array( + 'httpMethod' => 'DELETE', + 'uri' => '/{Bucket}', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'DeleteBucketOutput', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketDELETE.html', + 'parameters' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + ), + ), + 'DeleteBucketCors' => array( + 'httpMethod' => 'DELETE', + 'uri' => '/{Bucket}?cors', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'DeleteBucketCorsOutput', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketDELETEcors.html', + 'parameters' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + ), + ), + 'DeleteBucketLifecycle' => array( + 'httpMethod' => 'DELETE', + 'uri' => '/{Bucket}?lifecycle', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'DeleteBucketLifecycleOutput', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketDELETElifecycle.html', + 'parameters' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + ), + ), + 'DeleteBucketPolicy' => array( + 'httpMethod' => 'DELETE', + 'uri' => '/{Bucket}?policy', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'DeleteBucketPolicyOutput', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketDELETEpolicy.html', + 'parameters' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + ), + ), + 'DeleteBucketReplication' => array( + 'httpMethod' => 'DELETE', + 'uri' => '/{Bucket}?replication', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'DeleteBucketReplicationOutput', + 'responseType' => 'model', + 'parameters' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + ), + ), + 'DeleteBucketTagging' => array( + 'httpMethod' => 'DELETE', + 'uri' => '/{Bucket}?tagging', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'DeleteBucketTaggingOutput', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketDELETEtagging.html', + 'parameters' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + ), + ), + 'DeleteBucketWebsite' => array( + 'httpMethod' => 'DELETE', + 'uri' => '/{Bucket}?website', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'DeleteBucketWebsiteOutput', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketDELETEwebsite.html', + 'parameters' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + ), + ), + 'DeleteObject' => array( + 'httpMethod' => 'DELETE', + 'uri' => '/{Bucket}{/Key*}', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'DeleteObjectOutput', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectDELETE.html', + 'parameters' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + 'Key' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + 'minLength' => 1, + 'filters' => array( + 'Aws\\S3\\S3Client::explodeKey', + ), + ), + 'MFA' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-mfa', + ), + 'VersionId' => array( + 'type' => 'string', + 'location' => 'query', + 'sentAs' => 'versionId', + ), + 'RequestPayer' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-request-payer', + ), + ), + ), + 'DeleteObjects' => array( + 'httpMethod' => 'POST', + 'uri' => '/{Bucket}?delete', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'DeleteObjectsOutput', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/multiobjectdeleteapi.html', + 'data' => array( + 'xmlRoot' => array( + 'name' => 'Delete', + 'namespaces' => array( + 'http://s3.amazonaws.com/doc/2006-03-01/', + ), + ), + 'contentMd5' => true, + ), + 'parameters' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + 'Objects' => array( + 'required' => true, + 'type' => 'array', + 'location' => 'xml', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'ObjectIdentifier', + 'type' => 'object', + 'sentAs' => 'Object', + 'properties' => array( + 'Key' => array( + 'required' => true, + 'type' => 'string', + 'minLength' => 1, + ), + 'VersionId' => array( + 'type' => 'string', + ), + ), + ), + ), + 'Quiet' => array( + 'type' => 'boolean', + 'format' => 'boolean-string', + 'location' => 'xml', + ), + 'MFA' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-mfa', + ), + 'RequestPayer' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-request-payer', + ), + 'command.expects' => array( + 'static' => true, + 'default' => 'application/xml', + ), + ), + ), + 'GetBucketAcl' => array( + 'httpMethod' => 'GET', + 'uri' => '/{Bucket}?acl', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'GetBucketAclOutput', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGETacl.html', + 'parameters' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + 'command.expects' => array( + 'static' => true, + 'default' => 'application/xml', + ), + ), + ), + 'GetBucketCors' => array( + 'httpMethod' => 'GET', + 'uri' => '/{Bucket}?cors', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'GetBucketCorsOutput', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGETcors.html', + 'parameters' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + 'command.expects' => array( + 'static' => true, + 'default' => 'application/xml', + ), + ), + ), + 'GetBucketLifecycle' => array( + 'httpMethod' => 'GET', + 'uri' => '/{Bucket}?lifecycle', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'GetBucketLifecycleOutput', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGETlifecycle.html', + 'parameters' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + 'command.expects' => array( + 'static' => true, + 'default' => 'application/xml', + ), + ), + ), + 'GetBucketLifecycleConfiguration' => array( + 'httpMethod' => 'GET', + 'uri' => '/{Bucket}?lifecycle', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'GetBucketLifecycleConfigurationOutput', + 'responseType' => 'model', + 'parameters' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + 'command.expects' => array( + 'static' => true, + 'default' => 'application/xml', + ), + ), + ), + 'GetBucketLocation' => array( + 'httpMethod' => 'GET', + 'uri' => '/{Bucket}?location', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'GetBucketLocationOutput', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGETlocation.html', + 'parameters' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + ), + ), + 'GetBucketLogging' => array( + 'httpMethod' => 'GET', + 'uri' => '/{Bucket}?logging', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'GetBucketLoggingOutput', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGETlogging.html', + 'parameters' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + 'command.expects' => array( + 'static' => true, + 'default' => 'application/xml', + ), + ), + ), + 'GetBucketNotification' => array( + 'httpMethod' => 'GET', + 'uri' => '/{Bucket}?notification', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'NotificationConfigurationDeprecated', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGETnotification.html', + 'parameters' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + 'command.expects' => array( + 'static' => true, + 'default' => 'application/xml', + ), + ), + ), + 'GetBucketNotificationConfiguration' => array( + 'httpMethod' => 'GET', + 'uri' => '/{Bucket}?notification', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'NotificationConfiguration', + 'responseType' => 'model', + 'parameters' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + 'command.expects' => array( + 'static' => true, + 'default' => 'application/xml', + ), + ), + ), + 'GetBucketPolicy' => array( + 'httpMethod' => 'GET', + 'uri' => '/{Bucket}?policy', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'GetBucketPolicyOutput', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGETpolicy.html', + 'parameters' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + ), + ), + 'GetBucketReplication' => array( + 'httpMethod' => 'GET', + 'uri' => '/{Bucket}?replication', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'GetBucketReplicationOutput', + 'responseType' => 'model', + 'parameters' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + 'command.expects' => array( + 'static' => true, + 'default' => 'application/xml', + ), + ), + ), + 'GetBucketRequestPayment' => array( + 'httpMethod' => 'GET', + 'uri' => '/{Bucket}?requestPayment', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'GetBucketRequestPaymentOutput', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/RESTrequestPaymentGET.html', + 'parameters' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + 'command.expects' => array( + 'static' => true, + 'default' => 'application/xml', + ), + ), + ), + 'GetBucketTagging' => array( + 'httpMethod' => 'GET', + 'uri' => '/{Bucket}?tagging', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'GetBucketTaggingOutput', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGETtagging.html', + 'parameters' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + 'command.expects' => array( + 'static' => true, + 'default' => 'application/xml', + ), + ), + ), + 'GetBucketVersioning' => array( + 'httpMethod' => 'GET', + 'uri' => '/{Bucket}?versioning', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'GetBucketVersioningOutput', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGETversioningStatus.html', + 'parameters' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + 'command.expects' => array( + 'static' => true, + 'default' => 'application/xml', + ), + ), + ), + 'GetBucketWebsite' => array( + 'httpMethod' => 'GET', + 'uri' => '/{Bucket}?website', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'GetBucketWebsiteOutput', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGETwebsite.html', + 'parameters' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + 'command.expects' => array( + 'static' => true, + 'default' => 'application/xml', + ), + ), + ), + 'GetObject' => array( + 'httpMethod' => 'GET', + 'uri' => '/{Bucket}{/Key*}', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'GetObjectOutput', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectGET.html', + 'parameters' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + 'IfMatch' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'If-Match', + ), + 'IfModifiedSince' => array( + 'type' => array( + 'object', + 'string', + 'integer', + ), + 'format' => 'date-time-http', + 'location' => 'header', + 'sentAs' => 'If-Modified-Since', + ), + 'IfNoneMatch' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'If-None-Match', + ), + 'IfUnmodifiedSince' => array( + 'type' => array( + 'object', + 'string', + 'integer', + ), + 'format' => 'date-time-http', + 'location' => 'header', + 'sentAs' => 'If-Unmodified-Since', + ), + 'Key' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + 'minLength' => 1, + 'filters' => array( + 'Aws\\S3\\S3Client::explodeKey', + ), + ), + 'Range' => array( + 'type' => 'string', + 'location' => 'header', + ), + 'ResponseCacheControl' => array( + 'type' => 'string', + 'location' => 'query', + 'sentAs' => 'response-cache-control', + ), + 'ResponseContentDisposition' => array( + 'type' => 'string', + 'location' => 'query', + 'sentAs' => 'response-content-disposition', + ), + 'ResponseContentEncoding' => array( + 'type' => 'string', + 'location' => 'query', + 'sentAs' => 'response-content-encoding', + ), + 'ResponseContentLanguage' => array( + 'type' => 'string', + 'location' => 'query', + 'sentAs' => 'response-content-language', + ), + 'ResponseContentType' => array( + 'type' => 'string', + 'location' => 'query', + 'sentAs' => 'response-content-type', + ), + 'ResponseExpires' => array( + 'type' => array( + 'object', + 'string', + 'integer', + ), + 'format' => 'date-time-http', + 'location' => 'query', + 'sentAs' => 'response-expires', + ), + 'VersionId' => array( + 'type' => 'string', + 'location' => 'query', + 'sentAs' => 'versionId', + ), + 'SSECustomerAlgorithm' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption-customer-algorithm', + ), + 'SSECustomerKey' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption-customer-key', + ), + 'SSECustomerKeyMD5' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption-customer-key-MD5', + ), + 'RequestPayer' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-request-payer', + ), + 'SaveAs' => array( + 'location' => 'response_body', + ), + ), + 'errorResponses' => array( + array( + 'reason' => 'The specified key does not exist.', + 'class' => 'NoSuchKeyException', + ), + ), + ), + 'GetObjectAcl' => array( + 'httpMethod' => 'GET', + 'uri' => '/{Bucket}{/Key*}?acl', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'GetObjectAclOutput', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectGETacl.html', + 'parameters' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + 'Key' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + 'minLength' => 1, + 'filters' => array( + 'Aws\\S3\\S3Client::explodeKey', + ), + ), + 'VersionId' => array( + 'type' => 'string', + 'location' => 'query', + 'sentAs' => 'versionId', + ), + 'RequestPayer' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-request-payer', + ), + 'command.expects' => array( + 'static' => true, + 'default' => 'application/xml', + ), + ), + 'errorResponses' => array( + array( + 'reason' => 'The specified key does not exist.', + 'class' => 'NoSuchKeyException', + ), + ), + ), + 'GetObjectTorrent' => array( + 'httpMethod' => 'GET', + 'uri' => '/{Bucket}{/Key*}?torrent', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'GetObjectTorrentOutput', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectGETtorrent.html', + 'parameters' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + 'Key' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + 'minLength' => 1, + 'filters' => array( + 'Aws\\S3\\S3Client::explodeKey', + ), + ), + 'RequestPayer' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-request-payer', + ), + ), + ), + 'HeadBucket' => array( + 'httpMethod' => 'HEAD', + 'uri' => '/{Bucket}', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'HeadBucketOutput', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketHEAD.html', + 'parameters' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + ), + 'errorResponses' => array( + array( + 'reason' => 'The specified bucket does not exist.', + 'class' => 'NoSuchBucketException', + ), + ), + ), + 'HeadObject' => array( + 'httpMethod' => 'HEAD', + 'uri' => '/{Bucket}{/Key*}', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'HeadObjectOutput', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectHEAD.html', + 'parameters' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + 'IfMatch' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'If-Match', + ), + 'IfModifiedSince' => array( + 'type' => array( + 'object', + 'string', + 'integer', + ), + 'format' => 'date-time-http', + 'location' => 'header', + 'sentAs' => 'If-Modified-Since', + ), + 'IfNoneMatch' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'If-None-Match', + ), + 'IfUnmodifiedSince' => array( + 'type' => array( + 'object', + 'string', + 'integer', + ), + 'format' => 'date-time-http', + 'location' => 'header', + 'sentAs' => 'If-Unmodified-Since', + ), + 'Key' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + 'minLength' => 1, + 'filters' => array( + 'Aws\\S3\\S3Client::explodeKey', + ), + ), + 'Range' => array( + 'type' => 'string', + 'location' => 'header', + ), + 'VersionId' => array( + 'type' => 'string', + 'location' => 'query', + 'sentAs' => 'versionId', + ), + 'SSECustomerAlgorithm' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption-customer-algorithm', + ), + 'SSECustomerKey' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption-customer-key', + ), + 'SSECustomerKeyMD5' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption-customer-key-MD5', + ), + 'RequestPayer' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-request-payer', + ), + ), + 'errorResponses' => array( + array( + 'reason' => 'The specified key does not exist.', + 'class' => 'NoSuchKeyException', + ), + ), + ), + 'ListBuckets' => array( + 'httpMethod' => 'GET', + 'uri' => '/', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'ListBucketsOutput', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/RESTServiceGET.html', + 'parameters' => array( + 'command.expects' => array( + 'static' => true, + 'default' => 'application/xml', + ), + ), + ), + 'ListMultipartUploads' => array( + 'httpMethod' => 'GET', + 'uri' => '/{Bucket}?uploads', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'ListMultipartUploadsOutput', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadListMPUpload.html', + 'parameters' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + 'Delimiter' => array( + 'type' => 'string', + 'location' => 'query', + 'sentAs' => 'delimiter', + ), + 'EncodingType' => array( + 'type' => 'string', + 'location' => 'query', + 'sentAs' => 'encoding-type', + ), + 'KeyMarker' => array( + 'type' => 'string', + 'location' => 'query', + 'sentAs' => 'key-marker', + ), + 'MaxUploads' => array( + 'type' => 'numeric', + 'location' => 'query', + 'sentAs' => 'max-uploads', + ), + 'Prefix' => array( + 'type' => 'string', + 'location' => 'query', + 'sentAs' => 'prefix', + ), + 'UploadIdMarker' => array( + 'type' => 'string', + 'location' => 'query', + 'sentAs' => 'upload-id-marker', + ), + 'command.expects' => array( + 'static' => true, + 'default' => 'application/xml', + ), + ), + ), + 'ListObjectVersions' => array( + 'httpMethod' => 'GET', + 'uri' => '/{Bucket}?versions', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'ListObjectVersionsOutput', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGETVersion.html', + 'parameters' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + 'Delimiter' => array( + 'type' => 'string', + 'location' => 'query', + 'sentAs' => 'delimiter', + ), + 'EncodingType' => array( + 'type' => 'string', + 'location' => 'query', + 'sentAs' => 'encoding-type', + ), + 'KeyMarker' => array( + 'type' => 'string', + 'location' => 'query', + 'sentAs' => 'key-marker', + ), + 'MaxKeys' => array( + 'type' => 'numeric', + 'location' => 'query', + 'sentAs' => 'max-keys', + ), + 'Prefix' => array( + 'type' => 'string', + 'location' => 'query', + 'sentAs' => 'prefix', + ), + 'VersionIdMarker' => array( + 'type' => 'string', + 'location' => 'query', + 'sentAs' => 'version-id-marker', + ), + 'command.expects' => array( + 'static' => true, + 'default' => 'application/xml', + ), + ), + ), + 'ListObjects' => array( + 'httpMethod' => 'GET', + 'uri' => '/{Bucket}', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'ListObjectsOutput', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGET.html', + 'parameters' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + 'Delimiter' => array( + 'type' => 'string', + 'location' => 'query', + 'sentAs' => 'delimiter', + ), + 'EncodingType' => array( + 'type' => 'string', + 'location' => 'query', + 'sentAs' => 'encoding-type', + ), + 'Marker' => array( + 'type' => 'string', + 'location' => 'query', + 'sentAs' => 'marker', + ), + 'MaxKeys' => array( + 'type' => 'numeric', + 'location' => 'query', + 'sentAs' => 'max-keys', + ), + 'Prefix' => array( + 'type' => 'string', + 'location' => 'query', + 'sentAs' => 'prefix', + ), + 'command.expects' => array( + 'static' => true, + 'default' => 'application/xml', + ), + ), + 'errorResponses' => array( + array( + 'reason' => 'The specified bucket does not exist.', + 'class' => 'NoSuchBucketException', + ), + ), + ), + 'ListParts' => array( + 'httpMethod' => 'GET', + 'uri' => '/{Bucket}{/Key*}', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'ListPartsOutput', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadListParts.html', + 'parameters' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + 'Key' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + 'minLength' => 1, + 'filters' => array( + 'Aws\\S3\\S3Client::explodeKey', + ), + ), + 'MaxParts' => array( + 'type' => 'numeric', + 'location' => 'query', + 'sentAs' => 'max-parts', + ), + 'PartNumberMarker' => array( + 'type' => 'numeric', + 'location' => 'query', + 'sentAs' => 'part-number-marker', + ), + 'UploadId' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'query', + 'sentAs' => 'uploadId', + ), + 'RequestPayer' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-request-payer', + ), + 'command.expects' => array( + 'static' => true, + 'default' => 'application/xml', + ), + ), + ), + 'PutBucketAcl' => array( + 'httpMethod' => 'PUT', + 'uri' => '/{Bucket}?acl', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'PutBucketAclOutput', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTacl.html', + 'data' => array( + 'xmlRoot' => array( + 'name' => 'AccessControlPolicy', + 'namespaces' => array( + 'http://s3.amazonaws.com/doc/2006-03-01/', + ), + ), + ), + 'parameters' => array( + 'ACL' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-acl', + ), + 'Grants' => array( + 'type' => 'array', + 'location' => 'xml', + 'sentAs' => 'AccessControlList', + 'items' => array( + 'name' => 'Grant', + 'type' => 'object', + 'properties' => array( + 'Grantee' => array( + 'type' => 'object', + 'properties' => array( + 'DisplayName' => array( + 'type' => 'string', + ), + 'EmailAddress' => array( + 'type' => 'string', + ), + 'ID' => array( + 'type' => 'string', + ), + 'Type' => array( + 'required' => true, + 'type' => 'string', + 'sentAs' => 'xsi:type', + 'data' => array( + 'xmlAttribute' => true, + 'xmlNamespace' => 'http://www.w3.org/2001/XMLSchema-instance', + ), + ), + 'URI' => array( + 'type' => 'string', + ), + ), + ), + 'Permission' => array( + 'type' => 'string', + ), + ), + ), + ), + 'Owner' => array( + 'type' => 'object', + 'location' => 'xml', + 'properties' => array( + 'DisplayName' => array( + 'type' => 'string', + ), + 'ID' => array( + 'type' => 'string', + ), + ), + ), + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + 'GrantFullControl' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-grant-full-control', + ), + 'GrantRead' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-grant-read', + ), + 'GrantReadACP' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-grant-read-acp', + ), + 'GrantWrite' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-grant-write', + ), + 'GrantWriteACP' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-grant-write-acp', + ), + 'ACP' => array( + 'type' => 'object', + 'additionalProperties' => true, + ), + ), + ), + 'PutBucketCors' => array( + 'httpMethod' => 'PUT', + 'uri' => '/{Bucket}?cors', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'PutBucketCorsOutput', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTcors.html', + 'data' => array( + 'xmlRoot' => array( + 'name' => 'CORSConfiguration', + 'namespaces' => array( + 'http://s3.amazonaws.com/doc/2006-03-01/', + ), + ), + 'contentMd5' => true, + ), + 'parameters' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + 'CORSRules' => array( + 'required' => true, + 'type' => 'array', + 'location' => 'xml', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'CORSRule', + 'type' => 'object', + 'sentAs' => 'CORSRule', + 'properties' => array( + 'AllowedHeaders' => array( + 'type' => 'array', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'AllowedHeader', + 'type' => 'string', + 'sentAs' => 'AllowedHeader', + ), + ), + 'AllowedMethods' => array( + 'required' => true, + 'type' => 'array', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'AllowedMethod', + 'type' => 'string', + 'sentAs' => 'AllowedMethod', + ), + ), + 'AllowedOrigins' => array( + 'required' => true, + 'type' => 'array', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'AllowedOrigin', + 'type' => 'string', + 'sentAs' => 'AllowedOrigin', + ), + ), + 'ExposeHeaders' => array( + 'type' => 'array', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'ExposeHeader', + 'type' => 'string', + 'sentAs' => 'ExposeHeader', + ), + ), + 'MaxAgeSeconds' => array( + 'type' => 'numeric', + ), + ), + ), + ), + ), + ), + 'PutBucketLifecycle' => array( + 'httpMethod' => 'PUT', + 'uri' => '/{Bucket}?lifecycle', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'PutBucketLifecycleOutput', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTlifecycle.html', + 'data' => array( + 'xmlRoot' => array( + 'name' => 'LifecycleConfiguration', + 'namespaces' => array( + 'http://s3.amazonaws.com/doc/2006-03-01/', + ), + ), + 'contentMd5' => true, + ), + 'parameters' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + 'Rules' => array( + 'required' => true, + 'type' => 'array', + 'location' => 'xml', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'Rule', + 'type' => 'object', + 'sentAs' => 'Rule', + 'properties' => array( + 'Expiration' => array( + 'type' => 'object', + 'properties' => array( + 'Date' => array( + 'type' => array( + 'object', + 'string', + 'integer', + ), + 'format' => 'date-time', + ), + 'Days' => array( + 'type' => 'numeric', + ), + ), + ), + 'ID' => array( + 'type' => 'string', + ), + 'Prefix' => array( + 'required' => true, + 'type' => 'string', + ), + 'Status' => array( + 'required' => true, + 'type' => 'string', + ), + 'Transition' => array( + 'type' => 'object', + 'properties' => array( + 'Date' => array( + 'type' => array( + 'object', + 'string', + 'integer', + ), + 'format' => 'date-time', + ), + 'Days' => array( + 'type' => 'numeric', + ), + 'StorageClass' => array( + 'type' => 'string', + ), + ), + ), + 'NoncurrentVersionTransition' => array( + 'type' => 'object', + 'properties' => array( + 'NoncurrentDays' => array( + 'type' => 'numeric', + ), + 'StorageClass' => array( + 'type' => 'string', + ), + ), + ), + 'NoncurrentVersionExpiration' => array( + 'type' => 'object', + 'properties' => array( + 'NoncurrentDays' => array( + 'type' => 'numeric', + ), + ), + ), + ), + ), + ), + ), + ), + 'PutBucketLifecycleConfiguration' => array( + 'httpMethod' => 'PUT', + 'uri' => '/{Bucket}?lifecycle', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'PutBucketLifecycleConfigurationOutput', + 'responseType' => 'model', + 'data' => array( + 'xmlRoot' => array( + 'name' => 'LifecycleConfiguration', + 'namespaces' => array( + 'http://s3.amazonaws.com/doc/2006-03-01/', + ), + ), + ), + 'parameters' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + 'Rules' => array( + 'required' => true, + 'type' => 'array', + 'location' => 'xml', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'LifecycleRule', + 'type' => 'object', + 'sentAs' => 'Rule', + 'properties' => array( + 'Expiration' => array( + 'type' => 'object', + 'properties' => array( + 'Date' => array( + 'type' => array( + 'object', + 'string', + 'integer', + ), + 'format' => 'date-time-http', + ), + 'Days' => array( + 'type' => 'numeric', + ), + ), + ), + 'ID' => array( + 'type' => 'string', + ), + 'Prefix' => array( + 'required' => true, + 'type' => 'string', + ), + 'Status' => array( + 'required' => true, + 'type' => 'string', + ), + 'Transitions' => array( + 'type' => 'array', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'Transition', + 'type' => 'object', + 'sentAs' => 'Transition', + 'properties' => array( + 'Date' => array( + 'type' => array( + 'object', + 'string', + 'integer', + ), + 'format' => 'date-time-http', + ), + 'Days' => array( + 'type' => 'numeric', + ), + 'StorageClass' => array( + 'type' => 'string', + ), + ), + ), + ), + 'NoncurrentVersionTransitions' => array( + 'type' => 'array', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'NoncurrentVersionTransition', + 'type' => 'object', + 'sentAs' => 'NoncurrentVersionTransition', + 'properties' => array( + 'NoncurrentDays' => array( + 'type' => 'numeric', + ), + 'StorageClass' => array( + 'type' => 'string', + ), + ), + ), + ), + 'NoncurrentVersionExpiration' => array( + 'type' => 'object', + 'properties' => array( + 'NoncurrentDays' => array( + 'type' => 'numeric', + ), + ), + ), + ), + ), + ), + ), + ), + 'PutBucketLogging' => array( + 'httpMethod' => 'PUT', + 'uri' => '/{Bucket}?logging', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'PutBucketLoggingOutput', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTlogging.html', + 'data' => array( + 'xmlRoot' => array( + 'name' => 'BucketLoggingStatus', + 'namespaces' => array( + 'http://s3.amazonaws.com/doc/2006-03-01/', + ), + ), + 'xmlAllowEmpty' => true, + ), + 'parameters' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + 'LoggingEnabled' => array( + 'type' => 'object', + 'location' => 'xml', + 'properties' => array( + 'TargetBucket' => array( + 'type' => 'string', + ), + 'TargetGrants' => array( + 'type' => 'array', + 'items' => array( + 'name' => 'Grant', + 'type' => 'object', + 'properties' => array( + 'Grantee' => array( + 'type' => 'object', + 'properties' => array( + 'DisplayName' => array( + 'type' => 'string', + ), + 'EmailAddress' => array( + 'type' => 'string', + ), + 'ID' => array( + 'type' => 'string', + ), + 'Type' => array( + 'required' => true, + 'type' => 'string', + 'sentAs' => 'xsi:type', + 'data' => array( + 'xmlAttribute' => true, + 'xmlNamespace' => 'http://www.w3.org/2001/XMLSchema-instance', + ), + ), + 'URI' => array( + 'type' => 'string', + ), + ), + ), + 'Permission' => array( + 'type' => 'string', + ), + ), + ), + ), + 'TargetPrefix' => array( + 'type' => 'string', + ), + ), + ), + ), + ), + 'PutBucketNotification' => array( + 'httpMethod' => 'PUT', + 'uri' => '/{Bucket}?notification', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'PutBucketNotificationOutput', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTnotification.html', + 'data' => array( + 'xmlRoot' => array( + 'name' => 'NotificationConfiguration', + 'namespaces' => array( + 'http://s3.amazonaws.com/doc/2006-03-01/', + ), + ), + 'xmlAllowEmpty' => true, + ), + 'parameters' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + 'TopicConfiguration' => array( + 'type' => 'object', + 'location' => 'xml', + 'properties' => array( + 'Id' => array( + 'type' => 'string', + ), + 'Events' => array( + 'type' => 'array', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'Event', + 'type' => 'string', + ), + ), + 'Event' => array( + 'type' => 'string', + ), + 'Topic' => array( + 'type' => 'string', + ), + ), + ), + 'QueueConfiguration' => array( + 'type' => 'object', + 'location' => 'xml', + 'properties' => array( + 'Id' => array( + 'type' => 'string', + ), + 'Event' => array( + 'type' => 'string', + ), + 'Events' => array( + 'type' => 'array', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'Event', + 'type' => 'string', + ), + ), + 'Queue' => array( + 'type' => 'string', + ), + ), + ), + 'CloudFunctionConfiguration' => array( + 'type' => 'object', + 'location' => 'xml', + 'properties' => array( + 'Id' => array( + 'type' => 'string', + ), + 'Event' => array( + 'type' => 'string', + ), + 'Events' => array( + 'type' => 'array', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'Event', + 'type' => 'string', + ), + ), + 'CloudFunction' => array( + 'type' => 'string', + ), + 'InvocationRole' => array( + 'type' => 'string', + ), + ), + ), + ), + ), + 'PutBucketNotificationConfiguration' => array( + 'httpMethod' => 'PUT', + 'uri' => '/{Bucket}?notification', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'PutBucketNotificationConfigurationOutput', + 'responseType' => 'model', + 'data' => array( + 'xmlRoot' => array( + 'name' => 'NotificationConfiguration', + 'namespaces' => array( + 'http://s3.amazonaws.com/doc/2006-03-01/', + ), + ), + ), + 'parameters' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + 'TopicConfigurations' => array( + 'type' => 'array', + 'location' => 'xml', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'TopicConfiguration', + 'type' => 'object', + 'sentAs' => 'TopicConfiguration', + 'properties' => array( + 'Id' => array( + 'type' => 'string', + ), + 'TopicArn' => array( + 'required' => true, + 'type' => 'string', + 'sentAs' => 'Topic', + ), + 'Events' => array( + 'required' => true, + 'type' => 'array', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'Event', + 'type' => 'string', + 'sentAs' => 'Event', + ), + ), + 'Filter' => array( + 'type' => 'object', + 'properties' => array( + 'Key' => array( + 'type' => 'object', + 'sentAs' => 'S3Key', + 'properties' => array( + 'FilterRules' => array( + 'type' => 'array', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'FilterRule', + 'type' => 'object', + 'sentAs' => 'FilterRule', + 'properties' => array( + 'Name' => array( + 'type' => 'string', + ), + 'Value' => array( + 'type' => 'string', + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + 'QueueConfigurations' => array( + 'type' => 'array', + 'location' => 'xml', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'QueueConfiguration', + 'type' => 'object', + 'sentAs' => 'QueueConfiguration', + 'properties' => array( + 'Id' => array( + 'type' => 'string', + ), + 'QueueArn' => array( + 'required' => true, + 'type' => 'string', + 'sentAs' => 'Queue', + ), + 'Events' => array( + 'required' => true, + 'type' => 'array', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'Event', + 'type' => 'string', + 'sentAs' => 'Event', + ), + ), + 'Filter' => array( + 'type' => 'object', + 'properties' => array( + 'Key' => array( + 'type' => 'object', + 'sentAs' => 'S3Key', + 'properties' => array( + 'FilterRules' => array( + 'type' => 'array', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'FilterRule', + 'type' => 'object', + 'sentAs' => 'FilterRule', + 'properties' => array( + 'Name' => array( + 'type' => 'string', + ), + 'Value' => array( + 'type' => 'string', + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + 'LambdaFunctionConfigurations' => array( + 'type' => 'array', + 'location' => 'xml', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'LambdaFunctionConfiguration', + 'type' => 'object', + 'sentAs' => 'CloudFunctionConfiguration', + 'properties' => array( + 'Id' => array( + 'type' => 'string', + ), + 'LambdaFunctionArn' => array( + 'required' => true, + 'type' => 'string', + 'sentAs' => 'CloudFunction', + ), + 'Events' => array( + 'required' => true, + 'type' => 'array', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'Event', + 'type' => 'string', + 'sentAs' => 'Event', + ), + ), + 'Filter' => array( + 'type' => 'object', + 'properties' => array( + 'Key' => array( + 'type' => 'object', + 'sentAs' => 'S3Key', + 'properties' => array( + 'FilterRules' => array( + 'type' => 'array', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'FilterRule', + 'type' => 'object', + 'sentAs' => 'FilterRule', + 'properties' => array( + 'Name' => array( + 'type' => 'string', + ), + 'Value' => array( + 'type' => 'string', + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + 'PutBucketPolicy' => array( + 'httpMethod' => 'PUT', + 'uri' => '/{Bucket}?policy', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'PutBucketPolicyOutput', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTpolicy.html', + 'data' => array( + 'xmlRoot' => array( + 'name' => 'PutBucketPolicyRequest', + 'namespaces' => array( + 'http://s3.amazonaws.com/doc/2006-03-01/', + ), + ), + ), + 'parameters' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + 'Policy' => array( + 'required' => true, + 'type' => array( + 'string', + 'object', + ), + 'location' => 'body', + ), + ), + ), + 'PutBucketReplication' => array( + 'httpMethod' => 'PUT', + 'uri' => '/{Bucket}?replication', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'PutBucketReplicationOutput', + 'responseType' => 'model', + 'data' => array( + 'xmlRoot' => array( + 'name' => 'ReplicationConfiguration', + 'namespaces' => array( + 'http://s3.amazonaws.com/doc/2006-03-01/', + ), + ), + ), + 'parameters' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + 'Role' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'xml', + ), + 'Rules' => array( + 'required' => true, + 'type' => 'array', + 'location' => 'xml', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'ReplicationRule', + 'type' => 'object', + 'sentAs' => 'Rule', + 'properties' => array( + 'ID' => array( + 'type' => 'string', + ), + 'Prefix' => array( + 'required' => true, + 'type' => 'string', + ), + 'Status' => array( + 'required' => true, + 'type' => 'string', + ), + 'Destination' => array( + 'required' => true, + 'type' => 'object', + 'properties' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + ), + 'StorageClass' => array( + 'type' => 'string', + ), + ), + ), + ), + ), + ), + ), + ), + 'PutBucketRequestPayment' => array( + 'httpMethod' => 'PUT', + 'uri' => '/{Bucket}?requestPayment', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'PutBucketRequestPaymentOutput', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/RESTrequestPaymentPUT.html', + 'data' => array( + 'xmlRoot' => array( + 'name' => 'RequestPaymentConfiguration', + 'namespaces' => array( + 'http://s3.amazonaws.com/doc/2006-03-01/', + ), + ), + ), + 'parameters' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + 'Payer' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'xml', + ), + ), + ), + 'PutBucketTagging' => array( + 'httpMethod' => 'PUT', + 'uri' => '/{Bucket}?tagging', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'PutBucketTaggingOutput', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTtagging.html', + 'data' => array( + 'xmlRoot' => array( + 'name' => 'Tagging', + 'namespaces' => array( + 'http://s3.amazonaws.com/doc/2006-03-01/', + ), + ), + 'contentMd5' => true, + ), + 'parameters' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + 'TagSet' => array( + 'required' => true, + 'type' => 'array', + 'location' => 'xml', + 'items' => array( + 'name' => 'Tag', + 'type' => 'object', + 'properties' => array( + 'Key' => array( + 'required' => true, + 'type' => 'string', + 'minLength' => 1, + ), + 'Value' => array( + 'required' => true, + 'type' => 'string', + ), + ), + ), + ), + ), + ), + 'PutBucketVersioning' => array( + 'httpMethod' => 'PUT', + 'uri' => '/{Bucket}?versioning', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'PutBucketVersioningOutput', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTVersioningStatus.html', + 'data' => array( + 'xmlRoot' => array( + 'name' => 'VersioningConfiguration', + 'namespaces' => array( + 'http://s3.amazonaws.com/doc/2006-03-01/', + ), + ), + ), + 'parameters' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + 'MFA' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-mfa', + ), + 'MFADelete' => array( + 'type' => 'string', + 'location' => 'xml', + 'sentAs' => 'MfaDelete', + ), + 'Status' => array( + 'type' => 'string', + 'location' => 'xml', + ), + ), + ), + 'PutBucketWebsite' => array( + 'httpMethod' => 'PUT', + 'uri' => '/{Bucket}?website', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'PutBucketWebsiteOutput', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTwebsite.html', + 'data' => array( + 'xmlRoot' => array( + 'name' => 'WebsiteConfiguration', + 'namespaces' => array( + 'http://s3.amazonaws.com/doc/2006-03-01/', + ), + ), + 'xmlAllowEmpty' => true, + ), + 'parameters' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + 'ErrorDocument' => array( + 'type' => 'object', + 'location' => 'xml', + 'properties' => array( + 'Key' => array( + 'required' => true, + 'type' => 'string', + 'minLength' => 1, + ), + ), + ), + 'IndexDocument' => array( + 'type' => 'object', + 'location' => 'xml', + 'properties' => array( + 'Suffix' => array( + 'required' => true, + 'type' => 'string', + ), + ), + ), + 'RedirectAllRequestsTo' => array( + 'type' => 'object', + 'location' => 'xml', + 'properties' => array( + 'HostName' => array( + 'required' => true, + 'type' => 'string', + ), + 'Protocol' => array( + 'type' => 'string', + ), + ), + ), + 'RoutingRules' => array( + 'type' => 'array', + 'location' => 'xml', + 'items' => array( + 'name' => 'RoutingRule', + 'type' => 'object', + 'properties' => array( + 'Condition' => array( + 'type' => 'object', + 'properties' => array( + 'HttpErrorCodeReturnedEquals' => array( + 'type' => 'string', + ), + 'KeyPrefixEquals' => array( + 'type' => 'string', + ), + ), + ), + 'Redirect' => array( + 'required' => true, + 'type' => 'object', + 'properties' => array( + 'HostName' => array( + 'type' => 'string', + ), + 'HttpRedirectCode' => array( + 'type' => 'string', + ), + 'Protocol' => array( + 'type' => 'string', + ), + 'ReplaceKeyPrefixWith' => array( + 'type' => 'string', + ), + 'ReplaceKeyWith' => array( + 'type' => 'string', + ), + ), + ), + ), + ), + ), + ), + ), + 'PutObject' => array( + 'httpMethod' => 'PUT', + 'uri' => '/{Bucket}{/Key*}', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'PutObjectOutput', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPUT.html', + 'data' => array( + 'xmlRoot' => array( + 'name' => 'PutObjectRequest', + 'namespaces' => array( + 'http://s3.amazonaws.com/doc/2006-03-01/', + ), + ), + ), + 'parameters' => array( + 'ACL' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-acl', + ), + 'Body' => array( + 'type' => array( + 'string', + 'object', + ), + 'location' => 'body', + ), + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + 'CacheControl' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'Cache-Control', + ), + 'ContentDisposition' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'Content-Disposition', + ), + 'ContentEncoding' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'Content-Encoding', + ), + 'ContentLanguage' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'Content-Language', + ), + 'ContentLength' => array( + 'type' => 'numeric', + 'location' => 'header', + 'sentAs' => 'Content-Length', + ), + 'ContentMD5' => array( + 'type' => array( + 'string', + 'boolean', + ), + 'location' => 'header', + 'sentAs' => 'Content-MD5', + ), + 'ContentType' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'Content-Type', + ), + 'Expires' => array( + 'type' => array( + 'object', + 'string', + 'integer', + ), + 'format' => 'date-time-http', + 'location' => 'header', + ), + 'GrantFullControl' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-grant-full-control', + ), + 'GrantRead' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-grant-read', + ), + 'GrantReadACP' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-grant-read-acp', + ), + 'GrantWriteACP' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-grant-write-acp', + ), + 'Key' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + 'minLength' => 1, + 'filters' => array( + 'Aws\\S3\\S3Client::explodeKey', + ), + ), + 'Metadata' => array( + 'type' => 'object', + 'location' => 'header', + 'sentAs' => 'x-amz-meta-', + 'additionalProperties' => array( + 'type' => 'string', + ), + ), + 'ServerSideEncryption' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption', + ), + 'StorageClass' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-storage-class', + ), + 'WebsiteRedirectLocation' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-website-redirect-location', + ), + 'SSECustomerAlgorithm' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption-customer-algorithm', + ), + 'SSECustomerKey' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption-customer-key', + ), + 'SSECustomerKeyMD5' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption-customer-key-MD5', + ), + 'SSEKMSKeyId' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption-aws-kms-key-id', + ), + 'RequestPayer' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-request-payer', + ), + 'ACP' => array( + 'type' => 'object', + 'additionalProperties' => true, + ), + ), + ), + 'PutObjectAcl' => array( + 'httpMethod' => 'PUT', + 'uri' => '/{Bucket}{/Key*}?acl', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'PutObjectAclOutput', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPUTacl.html', + 'data' => array( + 'xmlRoot' => array( + 'name' => 'AccessControlPolicy', + 'namespaces' => array( + 'http://s3.amazonaws.com/doc/2006-03-01/', + ), + ), + ), + 'parameters' => array( + 'ACL' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-acl', + ), + 'Grants' => array( + 'type' => 'array', + 'location' => 'xml', + 'sentAs' => 'AccessControlList', + 'items' => array( + 'name' => 'Grant', + 'type' => 'object', + 'properties' => array( + 'Grantee' => array( + 'type' => 'object', + 'properties' => array( + 'DisplayName' => array( + 'type' => 'string', + ), + 'EmailAddress' => array( + 'type' => 'string', + ), + 'ID' => array( + 'type' => 'string', + ), + 'Type' => array( + 'required' => true, + 'type' => 'string', + 'sentAs' => 'xsi:type', + 'data' => array( + 'xmlAttribute' => true, + 'xmlNamespace' => 'http://www.w3.org/2001/XMLSchema-instance', + ), + ), + 'URI' => array( + 'type' => 'string', + ), + ), + ), + 'Permission' => array( + 'type' => 'string', + ), + ), + ), + ), + 'Owner' => array( + 'type' => 'object', + 'location' => 'xml', + 'properties' => array( + 'DisplayName' => array( + 'type' => 'string', + ), + 'ID' => array( + 'type' => 'string', + ), + ), + ), + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + 'GrantFullControl' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-grant-full-control', + ), + 'GrantRead' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-grant-read', + ), + 'GrantReadACP' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-grant-read-acp', + ), + 'GrantWrite' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-grant-write', + ), + 'GrantWriteACP' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-grant-write-acp', + ), + 'Key' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + 'minLength' => 1, + 'filters' => array( + 'Aws\\S3\\S3Client::explodeKey', + ), + ), + 'RequestPayer' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-request-payer', + ), + 'ACP' => array( + 'type' => 'object', + 'additionalProperties' => true, + ), + ), + 'errorResponses' => array( + array( + 'reason' => 'The specified key does not exist.', + 'class' => 'NoSuchKeyException', + ), + ), + ), + 'RestoreObject' => array( + 'httpMethod' => 'POST', + 'uri' => '/{Bucket}{/Key*}?restore', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'RestoreObjectOutput', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectRestore.html', + 'data' => array( + 'xmlRoot' => array( + 'name' => 'RestoreRequest', + 'namespaces' => array( + 'http://s3.amazonaws.com/doc/2006-03-01/', + ), + ), + ), + 'parameters' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + 'Key' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + 'minLength' => 1, + 'filters' => array( + 'Aws\\S3\\S3Client::explodeKey', + ), + ), + 'VersionId' => array( + 'type' => 'string', + 'location' => 'query', + 'sentAs' => 'versionId', + ), + 'Days' => array( + 'required' => true, + 'type' => 'numeric', + 'location' => 'xml', + ), + 'RequestPayer' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-request-payer', + ), + ), + 'errorResponses' => array( + array( + 'reason' => 'This operation is not allowed against this storage tier', + 'class' => 'ObjectAlreadyInActiveTierErrorException', + ), + ), + ), + 'UploadPart' => array( + 'httpMethod' => 'PUT', + 'uri' => '/{Bucket}{/Key*}', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'UploadPartOutput', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadUploadPart.html', + 'data' => array( + 'xmlRoot' => array( + 'name' => 'UploadPartRequest', + 'namespaces' => array( + 'http://s3.amazonaws.com/doc/2006-03-01/', + ), + ), + ), + 'parameters' => array( + 'Body' => array( + 'type' => array( + 'string', + 'object', + ), + 'location' => 'body', + ), + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + 'ContentLength' => array( + 'type' => 'numeric', + 'location' => 'header', + 'sentAs' => 'Content-Length', + ), + 'ContentMD5' => array( + 'type' => array( + 'string', + 'boolean', + ), + 'location' => 'header', + 'sentAs' => 'Content-MD5', + ), + 'Key' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + 'minLength' => 1, + 'filters' => array( + 'Aws\\S3\\S3Client::explodeKey', + ), + ), + 'PartNumber' => array( + 'required' => true, + 'type' => 'numeric', + 'location' => 'query', + 'sentAs' => 'partNumber', + ), + 'UploadId' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'query', + 'sentAs' => 'uploadId', + ), + 'ServerSideEncryption' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption', + ), + 'SSECustomerAlgorithm' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption-customer-algorithm', + ), + 'SSECustomerKey' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption-customer-key', + ), + 'SSECustomerKeyMD5' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption-customer-key-MD5', + ), + 'RequestPayer' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-request-payer', + ), + ), + ), + 'UploadPartCopy' => array( + 'httpMethod' => 'PUT', + 'uri' => '/{Bucket}{/Key*}', + 'class' => 'Aws\\S3\\Command\\S3Command', + 'responseClass' => 'UploadPartCopyOutput', + 'responseType' => 'model', + 'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadUploadPartCopy.html', + 'data' => array( + 'xmlRoot' => array( + 'name' => 'UploadPartCopyRequest', + 'namespaces' => array( + 'http://s3.amazonaws.com/doc/2006-03-01/', + ), + ), + ), + 'parameters' => array( + 'Bucket' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + ), + 'CopySource' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-copy-source', + ), + 'CopySourceIfMatch' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-copy-source-if-match', + ), + 'CopySourceIfModifiedSince' => array( + 'type' => array( + 'object', + 'string', + 'integer', + ), + 'format' => 'date-time-http', + 'location' => 'header', + 'sentAs' => 'x-amz-copy-source-if-modified-since', + ), + 'CopySourceIfNoneMatch' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-copy-source-if-none-match', + ), + 'CopySourceIfUnmodifiedSince' => array( + 'type' => array( + 'object', + 'string', + 'integer', + ), + 'format' => 'date-time-http', + 'location' => 'header', + 'sentAs' => 'x-amz-copy-source-if-unmodified-since', + ), + 'CopySourceRange' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-copy-source-range', + ), + 'Key' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'uri', + 'minLength' => 1, + 'filters' => array( + 'Aws\\S3\\S3Client::explodeKey', + ), + ), + 'PartNumber' => array( + 'required' => true, + 'type' => 'numeric', + 'location' => 'query', + 'sentAs' => 'partNumber', + ), + 'UploadId' => array( + 'required' => true, + 'type' => 'string', + 'location' => 'query', + 'sentAs' => 'uploadId', + ), + 'SSECustomerAlgorithm' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption-customer-algorithm', + ), + 'SSECustomerKey' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption-customer-key', + ), + 'SSECustomerKeyMD5' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption-customer-key-MD5', + ), + 'CopySourceSSECustomerAlgorithm' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-copy-source-server-side-encryption-customer-algorithm', + ), + 'CopySourceSSECustomerKey' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-copy-source-server-side-encryption-customer-key', + ), + 'CopySourceSSECustomerKeyMD5' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-copy-source-server-side-encryption-customer-key-MD5', + ), + 'RequestPayer' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-request-payer', + ), + 'command.expects' => array( + 'static' => true, + 'default' => 'application/xml', + ), + ), + ), + ), + 'models' => array( + 'AbortMultipartUploadOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'RequestCharged' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-request-charged', + ), + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'CompleteMultipartUploadOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'Location' => array( + 'type' => 'string', + 'location' => 'xml', + ), + 'Bucket' => array( + 'type' => 'string', + 'location' => 'xml', + ), + 'Key' => array( + 'type' => 'string', + 'location' => 'xml', + ), + 'Expiration' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-expiration', + ), + 'ETag' => array( + 'type' => 'string', + 'location' => 'xml', + ), + 'ServerSideEncryption' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption', + ), + 'VersionId' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-version-id', + ), + 'SSEKMSKeyId' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption-aws-kms-key-id', + ), + 'RequestCharged' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-request-charged', + ), + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'CopyObjectOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'ETag' => array( + 'type' => 'string', + 'location' => 'xml', + ), + 'LastModified' => array( + 'type' => 'string', + 'location' => 'xml', + ), + 'Expiration' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-expiration', + ), + 'CopySourceVersionId' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-copy-source-version-id', + ), + 'VersionId' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-version-id', + ), + 'ServerSideEncryption' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption', + ), + 'SSECustomerAlgorithm' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption-customer-algorithm', + ), + 'SSECustomerKeyMD5' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption-customer-key-MD5', + ), + 'SSEKMSKeyId' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption-aws-kms-key-id', + ), + 'RequestCharged' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-request-charged', + ), + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'CreateBucketOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'Location' => array( + 'type' => 'string', + 'location' => 'header', + ), + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'CreateMultipartUploadOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'Bucket' => array( + 'type' => 'string', + 'location' => 'xml', + 'sentAs' => 'Bucket', + ), + 'Key' => array( + 'type' => 'string', + 'location' => 'xml', + ), + 'UploadId' => array( + 'type' => 'string', + 'location' => 'xml', + ), + 'ServerSideEncryption' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption', + ), + 'SSECustomerAlgorithm' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption-customer-algorithm', + ), + 'SSECustomerKeyMD5' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption-customer-key-MD5', + ), + 'SSEKMSKeyId' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption-aws-kms-key-id', + ), + 'RequestCharged' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-request-charged', + ), + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'DeleteBucketOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'DeleteBucketCorsOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'DeleteBucketLifecycleOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'DeleteBucketPolicyOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'DeleteBucketReplicationOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'DeleteBucketTaggingOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'DeleteBucketWebsiteOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'DeleteObjectOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'DeleteMarker' => array( + 'type' => 'boolean', + 'location' => 'header', + 'sentAs' => 'x-amz-delete-marker', + ), + 'VersionId' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-version-id', + ), + 'RequestCharged' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-request-charged', + ), + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'DeleteObjectsOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'Deleted' => array( + 'type' => 'array', + 'location' => 'xml', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'DeletedObject', + 'type' => 'object', + 'properties' => array( + 'Key' => array( + 'type' => 'string', + ), + 'VersionId' => array( + 'type' => 'string', + ), + 'DeleteMarker' => array( + 'type' => 'boolean', + ), + 'DeleteMarkerVersionId' => array( + 'type' => 'string', + ), + ), + ), + ), + 'RequestCharged' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-request-charged', + ), + 'Errors' => array( + 'type' => 'array', + 'location' => 'xml', + 'sentAs' => 'Error', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'Error', + 'type' => 'object', + 'sentAs' => 'Error', + 'properties' => array( + 'Key' => array( + 'type' => 'string', + ), + 'VersionId' => array( + 'type' => 'string', + ), + 'Code' => array( + 'type' => 'string', + ), + 'Message' => array( + 'type' => 'string', + ), + ), + ), + ), + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'GetBucketAclOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'Owner' => array( + 'type' => 'object', + 'location' => 'xml', + 'properties' => array( + 'DisplayName' => array( + 'type' => 'string', + ), + 'ID' => array( + 'type' => 'string', + ), + ), + ), + 'Grants' => array( + 'type' => 'array', + 'location' => 'xml', + 'sentAs' => 'AccessControlList', + 'items' => array( + 'name' => 'Grant', + 'type' => 'object', + 'sentAs' => 'Grant', + 'properties' => array( + 'Grantee' => array( + 'type' => 'object', + 'properties' => array( + 'DisplayName' => array( + 'type' => 'string', + ), + 'EmailAddress' => array( + 'type' => 'string', + ), + 'ID' => array( + 'type' => 'string', + ), + 'Type' => array( + 'type' => 'string', + 'sentAs' => 'xsi:type', + 'data' => array( + 'xmlAttribute' => true, + 'xmlNamespace' => 'http://www.w3.org/2001/XMLSchema-instance', + ), + ), + 'URI' => array( + 'type' => 'string', + ), + ), + ), + 'Permission' => array( + 'type' => 'string', + ), + ), + ), + ), + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'GetBucketCorsOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'CORSRules' => array( + 'type' => 'array', + 'location' => 'xml', + 'sentAs' => 'CORSRule', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'CORSRule', + 'type' => 'object', + 'sentAs' => 'CORSRule', + 'properties' => array( + 'AllowedHeaders' => array( + 'type' => 'array', + 'sentAs' => 'AllowedHeader', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'AllowedHeader', + 'type' => 'string', + 'sentAs' => 'AllowedHeader', + ), + ), + 'AllowedMethods' => array( + 'type' => 'array', + 'sentAs' => 'AllowedMethod', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'AllowedMethod', + 'type' => 'string', + 'sentAs' => 'AllowedMethod', + ), + ), + 'AllowedOrigins' => array( + 'type' => 'array', + 'sentAs' => 'AllowedOrigin', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'AllowedOrigin', + 'type' => 'string', + 'sentAs' => 'AllowedOrigin', + ), + ), + 'ExposeHeaders' => array( + 'type' => 'array', + 'sentAs' => 'ExposeHeader', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'ExposeHeader', + 'type' => 'string', + 'sentAs' => 'ExposeHeader', + ), + ), + 'MaxAgeSeconds' => array( + 'type' => 'numeric', + ), + ), + ), + ), + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'GetBucketLifecycleOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'Rules' => array( + 'type' => 'array', + 'location' => 'xml', + 'sentAs' => 'Rule', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'Rule', + 'type' => 'object', + 'sentAs' => 'Rule', + 'properties' => array( + 'Expiration' => array( + 'type' => 'object', + 'properties' => array( + 'Date' => array( + 'type' => 'string', + ), + 'Days' => array( + 'type' => 'numeric', + ), + ), + ), + 'ID' => array( + 'type' => 'string', + ), + 'Prefix' => array( + 'type' => 'string', + ), + 'Status' => array( + 'type' => 'string', + ), + 'Transition' => array( + 'type' => 'object', + 'properties' => array( + 'Date' => array( + 'type' => 'string', + ), + 'Days' => array( + 'type' => 'numeric', + ), + 'StorageClass' => array( + 'type' => 'string', + ), + ), + ), + 'NoncurrentVersionTransition' => array( + 'type' => 'object', + 'properties' => array( + 'NoncurrentDays' => array( + 'type' => 'numeric', + ), + 'StorageClass' => array( + 'type' => 'string', + ), + ), + ), + 'NoncurrentVersionExpiration' => array( + 'type' => 'object', + 'properties' => array( + 'NoncurrentDays' => array( + 'type' => 'numeric', + ), + ), + ), + ), + ), + ), + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'GetBucketLifecycleConfigurationOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'Rules' => array( + 'type' => 'array', + 'location' => 'xml', + 'sentAs' => 'Rule', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'LifecycleRule', + 'type' => 'object', + 'sentAs' => 'Rule', + 'properties' => array( + 'Expiration' => array( + 'type' => 'object', + 'properties' => array( + 'Date' => array( + 'type' => 'string', + ), + 'Days' => array( + 'type' => 'numeric', + ), + ), + ), + 'ID' => array( + 'type' => 'string', + ), + 'Prefix' => array( + 'type' => 'string', + ), + 'Status' => array( + 'type' => 'string', + ), + 'Transitions' => array( + 'type' => 'array', + 'sentAs' => 'Transition', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'Transition', + 'type' => 'object', + 'sentAs' => 'Transition', + 'properties' => array( + 'Date' => array( + 'type' => 'string', + ), + 'Days' => array( + 'type' => 'numeric', + ), + 'StorageClass' => array( + 'type' => 'string', + ), + ), + ), + ), + 'NoncurrentVersionTransitions' => array( + 'type' => 'array', + 'sentAs' => 'NoncurrentVersionTransition', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'NoncurrentVersionTransition', + 'type' => 'object', + 'sentAs' => 'NoncurrentVersionTransition', + 'properties' => array( + 'NoncurrentDays' => array( + 'type' => 'numeric', + ), + 'StorageClass' => array( + 'type' => 'string', + ), + ), + ), + ), + 'NoncurrentVersionExpiration' => array( + 'type' => 'object', + 'properties' => array( + 'NoncurrentDays' => array( + 'type' => 'numeric', + ), + ), + ), + ), + ), + ), + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'GetBucketLocationOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'Location' => array( + 'type' => 'string', + 'location' => 'body', + 'filters' => array( + 'strval', + 'strip_tags', + 'trim', + ), + ), + ), + ), + 'GetBucketLoggingOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'LoggingEnabled' => array( + 'type' => 'object', + 'location' => 'xml', + 'properties' => array( + 'TargetBucket' => array( + 'type' => 'string', + ), + 'TargetGrants' => array( + 'type' => 'array', + 'items' => array( + 'name' => 'Grant', + 'type' => 'object', + 'sentAs' => 'Grant', + 'properties' => array( + 'Grantee' => array( + 'type' => 'object', + 'properties' => array( + 'DisplayName' => array( + 'type' => 'string', + ), + 'EmailAddress' => array( + 'type' => 'string', + ), + 'ID' => array( + 'type' => 'string', + ), + 'Type' => array( + 'type' => 'string', + 'sentAs' => 'xsi:type', + 'data' => array( + 'xmlAttribute' => true, + 'xmlNamespace' => 'http://www.w3.org/2001/XMLSchema-instance', + ), + ), + 'URI' => array( + 'type' => 'string', + ), + ), + ), + 'Permission' => array( + 'type' => 'string', + ), + ), + ), + ), + 'TargetPrefix' => array( + 'type' => 'string', + ), + ), + ), + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'NotificationConfigurationDeprecated' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'TopicConfiguration' => array( + 'type' => 'object', + 'location' => 'xml', + 'properties' => array( + 'Id' => array( + 'type' => 'string', + ), + 'Events' => array( + 'type' => 'array', + 'sentAs' => 'Event', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'Event', + 'type' => 'string', + 'sentAs' => 'Event', + ), + ), + 'Event' => array( + 'type' => 'string', + ), + 'Topic' => array( + 'type' => 'string', + ), + ), + ), + 'QueueConfiguration' => array( + 'type' => 'object', + 'location' => 'xml', + 'properties' => array( + 'Id' => array( + 'type' => 'string', + ), + 'Event' => array( + 'type' => 'string', + ), + 'Events' => array( + 'type' => 'array', + 'sentAs' => 'Event', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'Event', + 'type' => 'string', + 'sentAs' => 'Event', + ), + ), + 'Queue' => array( + 'type' => 'string', + ), + ), + ), + 'CloudFunctionConfiguration' => array( + 'type' => 'object', + 'location' => 'xml', + 'properties' => array( + 'Id' => array( + 'type' => 'string', + ), + 'Event' => array( + 'type' => 'string', + ), + 'Events' => array( + 'type' => 'array', + 'sentAs' => 'Event', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'Event', + 'type' => 'string', + 'sentAs' => 'Event', + ), + ), + 'CloudFunction' => array( + 'type' => 'string', + ), + 'InvocationRole' => array( + 'type' => 'string', + ), + ), + ), + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'NotificationConfiguration' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'TopicConfigurations' => array( + 'type' => 'array', + 'location' => 'xml', + 'sentAs' => 'TopicConfiguration', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'TopicConfiguration', + 'type' => 'object', + 'sentAs' => 'TopicConfiguration', + 'properties' => array( + 'Id' => array( + 'type' => 'string', + ), + 'TopicArn' => array( + 'type' => 'string', + 'sentAs' => 'Topic', + ), + 'Events' => array( + 'type' => 'array', + 'sentAs' => 'Event', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'Event', + 'type' => 'string', + 'sentAs' => 'Event', + ), + ), + 'Filter' => array( + 'type' => 'object', + 'properties' => array( + 'Key' => array( + 'type' => 'object', + 'sentAs' => 'S3Key', + 'properties' => array( + 'FilterRules' => array( + 'type' => 'array', + 'sentAs' => 'FilterRule', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'FilterRule', + 'type' => 'object', + 'sentAs' => 'FilterRule', + 'properties' => array( + 'Name' => array( + 'type' => 'string', + ), + 'Value' => array( + 'type' => 'string', + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + 'QueueConfigurations' => array( + 'type' => 'array', + 'location' => 'xml', + 'sentAs' => 'QueueConfiguration', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'QueueConfiguration', + 'type' => 'object', + 'sentAs' => 'QueueConfiguration', + 'properties' => array( + 'Id' => array( + 'type' => 'string', + ), + 'QueueArn' => array( + 'type' => 'string', + 'sentAs' => 'Queue', + ), + 'Events' => array( + 'type' => 'array', + 'sentAs' => 'Event', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'Event', + 'type' => 'string', + 'sentAs' => 'Event', + ), + ), + 'Filter' => array( + 'type' => 'object', + 'properties' => array( + 'Key' => array( + 'type' => 'object', + 'sentAs' => 'S3Key', + 'properties' => array( + 'FilterRules' => array( + 'type' => 'array', + 'sentAs' => 'FilterRule', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'FilterRule', + 'type' => 'object', + 'sentAs' => 'FilterRule', + 'properties' => array( + 'Name' => array( + 'type' => 'string', + ), + 'Value' => array( + 'type' => 'string', + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + 'LambdaFunctionConfigurations' => array( + 'type' => 'array', + 'location' => 'xml', + 'sentAs' => 'CloudFunctionConfiguration', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'LambdaFunctionConfiguration', + 'type' => 'object', + 'sentAs' => 'CloudFunctionConfiguration', + 'properties' => array( + 'Id' => array( + 'type' => 'string', + ), + 'LambdaFunctionArn' => array( + 'type' => 'string', + 'sentAs' => 'CloudFunction', + ), + 'Events' => array( + 'type' => 'array', + 'sentAs' => 'Event', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'Event', + 'type' => 'string', + 'sentAs' => 'Event', + ), + ), + 'Filter' => array( + 'type' => 'object', + 'properties' => array( + 'Key' => array( + 'type' => 'object', + 'sentAs' => 'S3Key', + 'properties' => array( + 'FilterRules' => array( + 'type' => 'array', + 'sentAs' => 'FilterRule', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'FilterRule', + 'type' => 'object', + 'sentAs' => 'FilterRule', + 'properties' => array( + 'Name' => array( + 'type' => 'string', + ), + 'Value' => array( + 'type' => 'string', + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'GetBucketPolicyOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'Policy' => array( + 'type' => 'string', + 'instanceOf' => 'Guzzle\\Http\\EntityBody', + 'location' => 'body', + ), + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'GetBucketReplicationOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'Role' => array( + 'type' => 'string', + 'location' => 'xml', + ), + 'Rules' => array( + 'type' => 'array', + 'location' => 'xml', + 'sentAs' => 'Rule', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'ReplicationRule', + 'type' => 'object', + 'sentAs' => 'Rule', + 'properties' => array( + 'ID' => array( + 'type' => 'string', + ), + 'Prefix' => array( + 'type' => 'string', + ), + 'Status' => array( + 'type' => 'string', + ), + 'Destination' => array( + 'type' => 'object', + 'properties' => array( + 'Bucket' => array( + 'type' => 'string', + ), + 'StorageClass' => array( + 'type' => 'string', + ), + ), + ), + ), + ), + ), + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'GetBucketRequestPaymentOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'Payer' => array( + 'type' => 'string', + 'location' => 'xml', + ), + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'GetBucketTaggingOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'TagSet' => array( + 'type' => 'array', + 'location' => 'xml', + 'items' => array( + 'name' => 'Tag', + 'type' => 'object', + 'sentAs' => 'Tag', + 'properties' => array( + 'Key' => array( + 'type' => 'string', + ), + 'Value' => array( + 'type' => 'string', + ), + ), + ), + ), + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'GetBucketVersioningOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'Status' => array( + 'type' => 'string', + 'location' => 'xml', + ), + 'MFADelete' => array( + 'type' => 'string', + 'location' => 'xml', + 'sentAs' => 'MfaDelete', + ), + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'GetBucketWebsiteOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'RedirectAllRequestsTo' => array( + 'type' => 'object', + 'location' => 'xml', + 'properties' => array( + 'HostName' => array( + 'type' => 'string', + ), + 'Protocol' => array( + 'type' => 'string', + ), + ), + ), + 'IndexDocument' => array( + 'type' => 'object', + 'location' => 'xml', + 'properties' => array( + 'Suffix' => array( + 'type' => 'string', + ), + ), + ), + 'ErrorDocument' => array( + 'type' => 'object', + 'location' => 'xml', + 'properties' => array( + 'Key' => array( + 'type' => 'string', + ), + ), + ), + 'RoutingRules' => array( + 'type' => 'array', + 'location' => 'xml', + 'items' => array( + 'name' => 'RoutingRule', + 'type' => 'object', + 'sentAs' => 'RoutingRule', + 'properties' => array( + 'Condition' => array( + 'type' => 'object', + 'properties' => array( + 'HttpErrorCodeReturnedEquals' => array( + 'type' => 'string', + ), + 'KeyPrefixEquals' => array( + 'type' => 'string', + ), + ), + ), + 'Redirect' => array( + 'type' => 'object', + 'properties' => array( + 'HostName' => array( + 'type' => 'string', + ), + 'HttpRedirectCode' => array( + 'type' => 'string', + ), + 'Protocol' => array( + 'type' => 'string', + ), + 'ReplaceKeyPrefixWith' => array( + 'type' => 'string', + ), + 'ReplaceKeyWith' => array( + 'type' => 'string', + ), + ), + ), + ), + ), + ), + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'GetObjectOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'Body' => array( + 'type' => 'string', + 'instanceOf' => 'Guzzle\\Http\\EntityBody', + 'location' => 'body', + ), + 'DeleteMarker' => array( + 'type' => 'boolean', + 'location' => 'header', + 'sentAs' => 'x-amz-delete-marker', + ), + 'AcceptRanges' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'accept-ranges', + ), + 'Expiration' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-expiration', + ), + 'Restore' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-restore', + ), + 'LastModified' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'Last-Modified', + ), + 'ContentLength' => array( + 'type' => 'numeric', + 'location' => 'header', + 'sentAs' => 'Content-Length', + ), + 'ETag' => array( + 'type' => 'string', + 'location' => 'header', + ), + 'MissingMeta' => array( + 'type' => 'numeric', + 'location' => 'header', + 'sentAs' => 'x-amz-missing-meta', + ), + 'VersionId' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-version-id', + ), + 'CacheControl' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'Cache-Control', + ), + 'ContentDisposition' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'Content-Disposition', + ), + 'ContentEncoding' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'Content-Encoding', + ), + 'ContentLanguage' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'Content-Language', + ), + 'ContentRange' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'Content-Range', + ), + 'ContentType' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'Content-Type', + ), + 'Expires' => array( + 'type' => 'string', + 'location' => 'header', + ), + 'WebsiteRedirectLocation' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-website-redirect-location', + ), + 'ServerSideEncryption' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption', + ), + 'Metadata' => array( + 'type' => 'object', + 'location' => 'header', + 'sentAs' => 'x-amz-meta-', + 'additionalProperties' => array( + 'type' => 'string', + ), + ), + 'SSECustomerAlgorithm' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption-customer-algorithm', + ), + 'SSECustomerKeyMD5' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption-customer-key-MD5', + ), + 'SSEKMSKeyId' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption-aws-kms-key-id', + ), + 'StorageClass' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-storage-class', + ), + 'RequestCharged' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-request-charged', + ), + 'ReplicationStatus' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-replication-status', + ), + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'GetObjectAclOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'Owner' => array( + 'type' => 'object', + 'location' => 'xml', + 'properties' => array( + 'DisplayName' => array( + 'type' => 'string', + ), + 'ID' => array( + 'type' => 'string', + ), + ), + ), + 'Grants' => array( + 'type' => 'array', + 'location' => 'xml', + 'sentAs' => 'AccessControlList', + 'items' => array( + 'name' => 'Grant', + 'type' => 'object', + 'sentAs' => 'Grant', + 'properties' => array( + 'Grantee' => array( + 'type' => 'object', + 'properties' => array( + 'DisplayName' => array( + 'type' => 'string', + ), + 'EmailAddress' => array( + 'type' => 'string', + ), + 'ID' => array( + 'type' => 'string', + ), + 'Type' => array( + 'type' => 'string', + 'sentAs' => 'xsi:type', + 'data' => array( + 'xmlAttribute' => true, + 'xmlNamespace' => 'http://www.w3.org/2001/XMLSchema-instance', + ), + ), + 'URI' => array( + 'type' => 'string', + ), + ), + ), + 'Permission' => array( + 'type' => 'string', + ), + ), + ), + ), + 'RequestCharged' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-request-charged', + ), + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'GetObjectTorrentOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'Body' => array( + 'type' => 'string', + 'instanceOf' => 'Guzzle\\Http\\EntityBody', + 'location' => 'body', + ), + 'RequestCharged' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-request-charged', + ), + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'HeadBucketOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'HeadObjectOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'DeleteMarker' => array( + 'type' => 'boolean', + 'location' => 'header', + 'sentAs' => 'x-amz-delete-marker', + ), + 'AcceptRanges' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'accept-ranges', + ), + 'Expiration' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-expiration', + ), + 'Restore' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-restore', + ), + 'LastModified' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'Last-Modified', + ), + 'ContentLength' => array( + 'type' => 'numeric', + 'location' => 'header', + 'sentAs' => 'Content-Length', + ), + 'ETag' => array( + 'type' => 'string', + 'location' => 'header', + ), + 'MissingMeta' => array( + 'type' => 'numeric', + 'location' => 'header', + 'sentAs' => 'x-amz-missing-meta', + ), + 'VersionId' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-version-id', + ), + 'CacheControl' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'Cache-Control', + ), + 'ContentDisposition' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'Content-Disposition', + ), + 'ContentEncoding' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'Content-Encoding', + ), + 'ContentLanguage' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'Content-Language', + ), + 'ContentType' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'Content-Type', + ), + 'Expires' => array( + 'type' => 'string', + 'location' => 'header', + ), + 'WebsiteRedirectLocation' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-website-redirect-location', + ), + 'ServerSideEncryption' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption', + ), + 'Metadata' => array( + 'type' => 'object', + 'location' => 'header', + 'sentAs' => 'x-amz-meta-', + 'additionalProperties' => array( + 'type' => 'string', + ), + ), + 'SSECustomerAlgorithm' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption-customer-algorithm', + ), + 'SSECustomerKeyMD5' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption-customer-key-MD5', + ), + 'SSEKMSKeyId' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption-aws-kms-key-id', + ), + 'StorageClass' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-storage-class', + ), + 'RequestCharged' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-request-charged', + ), + 'ReplicationStatus' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-replication-status', + ), + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'ListBucketsOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'Buckets' => array( + 'type' => 'array', + 'location' => 'xml', + 'items' => array( + 'name' => 'Bucket', + 'type' => 'object', + 'sentAs' => 'Bucket', + 'properties' => array( + 'Name' => array( + 'type' => 'string', + ), + 'CreationDate' => array( + 'type' => 'string', + ), + ), + ), + ), + 'Owner' => array( + 'type' => 'object', + 'location' => 'xml', + 'properties' => array( + 'DisplayName' => array( + 'type' => 'string', + ), + 'ID' => array( + 'type' => 'string', + ), + ), + ), + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'ListMultipartUploadsOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'Bucket' => array( + 'type' => 'string', + 'location' => 'xml', + ), + 'KeyMarker' => array( + 'type' => 'string', + 'location' => 'xml', + ), + 'UploadIdMarker' => array( + 'type' => 'string', + 'location' => 'xml', + ), + 'NextKeyMarker' => array( + 'type' => 'string', + 'location' => 'xml', + ), + 'Prefix' => array( + 'type' => 'string', + 'location' => 'xml', + ), + 'Delimiter' => array( + 'type' => 'string', + 'location' => 'xml', + ), + 'NextUploadIdMarker' => array( + 'type' => 'string', + 'location' => 'xml', + ), + 'MaxUploads' => array( + 'type' => 'numeric', + 'location' => 'xml', + ), + 'IsTruncated' => array( + 'type' => 'boolean', + 'location' => 'xml', + ), + 'Uploads' => array( + 'type' => 'array', + 'location' => 'xml', + 'sentAs' => 'Upload', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'MultipartUpload', + 'type' => 'object', + 'sentAs' => 'Upload', + 'properties' => array( + 'UploadId' => array( + 'type' => 'string', + ), + 'Key' => array( + 'type' => 'string', + ), + 'Initiated' => array( + 'type' => 'string', + ), + 'StorageClass' => array( + 'type' => 'string', + ), + 'Owner' => array( + 'type' => 'object', + 'properties' => array( + 'DisplayName' => array( + 'type' => 'string', + ), + 'ID' => array( + 'type' => 'string', + ), + ), + ), + 'Initiator' => array( + 'type' => 'object', + 'properties' => array( + 'ID' => array( + 'type' => 'string', + ), + 'DisplayName' => array( + 'type' => 'string', + ), + ), + ), + ), + ), + ), + 'CommonPrefixes' => array( + 'type' => 'array', + 'location' => 'xml', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'CommonPrefix', + 'type' => 'object', + 'properties' => array( + 'Prefix' => array( + 'type' => 'string', + ), + ), + ), + ), + 'EncodingType' => array( + 'type' => 'string', + 'location' => 'xml', + ), + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'ListObjectVersionsOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'IsTruncated' => array( + 'type' => 'boolean', + 'location' => 'xml', + ), + 'KeyMarker' => array( + 'type' => 'string', + 'location' => 'xml', + ), + 'VersionIdMarker' => array( + 'type' => 'string', + 'location' => 'xml', + ), + 'NextKeyMarker' => array( + 'type' => 'string', + 'location' => 'xml', + ), + 'NextVersionIdMarker' => array( + 'type' => 'string', + 'location' => 'xml', + ), + 'Versions' => array( + 'type' => 'array', + 'location' => 'xml', + 'sentAs' => 'Version', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'ObjectVersion', + 'type' => 'object', + 'sentAs' => 'Version', + 'properties' => array( + 'ETag' => array( + 'type' => 'string', + ), + 'Size' => array( + 'type' => 'numeric', + ), + 'StorageClass' => array( + 'type' => 'string', + ), + 'Key' => array( + 'type' => 'string', + ), + 'VersionId' => array( + 'type' => 'string', + ), + 'IsLatest' => array( + 'type' => 'boolean', + ), + 'LastModified' => array( + 'type' => 'string', + ), + 'Owner' => array( + 'type' => 'object', + 'properties' => array( + 'DisplayName' => array( + 'type' => 'string', + ), + 'ID' => array( + 'type' => 'string', + ), + ), + ), + ), + ), + ), + 'DeleteMarkers' => array( + 'type' => 'array', + 'location' => 'xml', + 'sentAs' => 'DeleteMarker', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'DeleteMarkerEntry', + 'type' => 'object', + 'sentAs' => 'DeleteMarker', + 'properties' => array( + 'Owner' => array( + 'type' => 'object', + 'properties' => array( + 'DisplayName' => array( + 'type' => 'string', + ), + 'ID' => array( + 'type' => 'string', + ), + ), + ), + 'Key' => array( + 'type' => 'string', + ), + 'VersionId' => array( + 'type' => 'string', + ), + 'IsLatest' => array( + 'type' => 'boolean', + ), + 'LastModified' => array( + 'type' => 'string', + ), + ), + ), + ), + 'Name' => array( + 'type' => 'string', + 'location' => 'xml', + ), + 'Prefix' => array( + 'type' => 'string', + 'location' => 'xml', + ), + 'Delimiter' => array( + 'type' => 'string', + 'location' => 'xml', + ), + 'MaxKeys' => array( + 'type' => 'numeric', + 'location' => 'xml', + ), + 'CommonPrefixes' => array( + 'type' => 'array', + 'location' => 'xml', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'CommonPrefix', + 'type' => 'object', + 'properties' => array( + 'Prefix' => array( + 'type' => 'string', + ), + ), + ), + ), + 'EncodingType' => array( + 'type' => 'string', + 'location' => 'xml', + ), + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'ListObjectsOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'IsTruncated' => array( + 'type' => 'boolean', + 'location' => 'xml', + ), + 'Marker' => array( + 'type' => 'string', + 'location' => 'xml', + ), + 'NextMarker' => array( + 'type' => 'string', + 'location' => 'xml', + ), + 'Contents' => array( + 'type' => 'array', + 'location' => 'xml', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'Object', + 'type' => 'object', + 'properties' => array( + 'Key' => array( + 'type' => 'string', + ), + 'LastModified' => array( + 'type' => 'string', + ), + 'ETag' => array( + 'type' => 'string', + ), + 'Size' => array( + 'type' => 'numeric', + ), + 'StorageClass' => array( + 'type' => 'string', + ), + 'Owner' => array( + 'type' => 'object', + 'properties' => array( + 'DisplayName' => array( + 'type' => 'string', + ), + 'ID' => array( + 'type' => 'string', + ), + ), + ), + ), + ), + ), + 'Name' => array( + 'type' => 'string', + 'location' => 'xml', + ), + 'Prefix' => array( + 'type' => 'string', + 'location' => 'xml', + ), + 'Delimiter' => array( + 'type' => 'string', + 'location' => 'xml', + ), + 'MaxKeys' => array( + 'type' => 'numeric', + 'location' => 'xml', + ), + 'CommonPrefixes' => array( + 'type' => 'array', + 'location' => 'xml', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'CommonPrefix', + 'type' => 'object', + 'properties' => array( + 'Prefix' => array( + 'type' => 'string', + ), + ), + ), + ), + 'EncodingType' => array( + 'type' => 'string', + 'location' => 'xml', + ), + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'ListPartsOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'Bucket' => array( + 'type' => 'string', + 'location' => 'xml', + ), + 'Key' => array( + 'type' => 'string', + 'location' => 'xml', + ), + 'UploadId' => array( + 'type' => 'string', + 'location' => 'xml', + ), + 'PartNumberMarker' => array( + 'type' => 'numeric', + 'location' => 'xml', + ), + 'NextPartNumberMarker' => array( + 'type' => 'numeric', + 'location' => 'xml', + ), + 'MaxParts' => array( + 'type' => 'numeric', + 'location' => 'xml', + ), + 'IsTruncated' => array( + 'type' => 'boolean', + 'location' => 'xml', + ), + 'Parts' => array( + 'type' => 'array', + 'location' => 'xml', + 'sentAs' => 'Part', + 'data' => array( + 'xmlFlattened' => true, + ), + 'items' => array( + 'name' => 'Part', + 'type' => 'object', + 'sentAs' => 'Part', + 'properties' => array( + 'PartNumber' => array( + 'type' => 'numeric', + ), + 'LastModified' => array( + 'type' => 'string', + ), + 'ETag' => array( + 'type' => 'string', + ), + 'Size' => array( + 'type' => 'numeric', + ), + ), + ), + ), + 'Initiator' => array( + 'type' => 'object', + 'location' => 'xml', + 'properties' => array( + 'ID' => array( + 'type' => 'string', + ), + 'DisplayName' => array( + 'type' => 'string', + ), + ), + ), + 'Owner' => array( + 'type' => 'object', + 'location' => 'xml', + 'properties' => array( + 'DisplayName' => array( + 'type' => 'string', + ), + 'ID' => array( + 'type' => 'string', + ), + ), + ), + 'StorageClass' => array( + 'type' => 'string', + 'location' => 'xml', + ), + 'RequestCharged' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-request-charged', + ), + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'PutBucketAclOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'PutBucketCorsOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'PutBucketLifecycleOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'PutBucketLifecycleConfigurationOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'PutBucketLoggingOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'PutBucketNotificationOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'PutBucketNotificationConfigurationOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'PutBucketPolicyOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'PutBucketReplicationOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'PutBucketRequestPaymentOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'PutBucketTaggingOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'PutBucketVersioningOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'PutBucketWebsiteOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'PutObjectOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'Expiration' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-expiration', + ), + 'ETag' => array( + 'type' => 'string', + 'location' => 'header', + ), + 'ServerSideEncryption' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption', + ), + 'VersionId' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-version-id', + ), + 'SSECustomerAlgorithm' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption-customer-algorithm', + ), + 'SSECustomerKeyMD5' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption-customer-key-MD5', + ), + 'SSEKMSKeyId' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption-aws-kms-key-id', + ), + 'RequestCharged' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-request-charged', + ), + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + 'ObjectURL' => array( + ), + ), + ), + 'PutObjectAclOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'RequestCharged' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-request-charged', + ), + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'RestoreObjectOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'RequestCharged' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-request-charged', + ), + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'UploadPartOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'ServerSideEncryption' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption', + ), + 'ETag' => array( + 'type' => 'string', + 'location' => 'header', + ), + 'SSECustomerAlgorithm' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption-customer-algorithm', + ), + 'SSECustomerKeyMD5' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption-customer-key-MD5', + ), + 'SSEKMSKeyId' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption-aws-kms-key-id', + ), + 'RequestCharged' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-request-charged', + ), + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + 'UploadPartCopyOutput' => array( + 'type' => 'object', + 'additionalProperties' => true, + 'properties' => array( + 'CopySourceVersionId' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-copy-source-version-id', + ), + 'ETag' => array( + 'type' => 'string', + 'location' => 'xml', + ), + 'LastModified' => array( + 'type' => 'string', + 'location' => 'xml', + ), + 'ServerSideEncryption' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption', + ), + 'SSECustomerAlgorithm' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption-customer-algorithm', + ), + 'SSECustomerKeyMD5' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption-customer-key-MD5', + ), + 'SSEKMSKeyId' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-server-side-encryption-aws-kms-key-id', + ), + 'RequestCharged' => array( + 'type' => 'string', + 'location' => 'header', + 'sentAs' => 'x-amz-request-charged', + ), + 'RequestId' => array( + 'location' => 'header', + 'sentAs' => 'x-amz-request-id', + ), + ), + ), + ), + 'iterators' => array( + 'ListBuckets' => array( + 'result_key' => 'Buckets', + ), + 'ListMultipartUploads' => array( + 'limit_key' => 'MaxUploads', + 'more_results' => 'IsTruncated', + 'output_token' => array( + 'NextKeyMarker', + 'NextUploadIdMarker', + ), + 'input_token' => array( + 'KeyMarker', + 'UploadIdMarker', + ), + 'result_key' => array( + 'Uploads', + 'CommonPrefixes', + ), + ), + 'ListObjectVersions' => array( + 'more_results' => 'IsTruncated', + 'limit_key' => 'MaxKeys', + 'output_token' => array( + 'NextKeyMarker', + 'NextVersionIdMarker', + ), + 'input_token' => array( + 'KeyMarker', + 'VersionIdMarker', + ), + 'result_key' => array( + 'Versions', + 'DeleteMarkers', + 'CommonPrefixes', + ), + ), + 'ListObjects' => array( + 'more_results' => 'IsTruncated', + 'limit_key' => 'MaxKeys', + 'output_token' => 'NextMarker', + 'input_token' => 'Marker', + 'result_key' => array( + 'Contents', + 'CommonPrefixes', + ), + ), + 'ListParts' => array( + 'more_results' => 'IsTruncated', + 'limit_key' => 'MaxParts', + 'output_token' => 'NextPartNumberMarker', + 'input_token' => 'PartNumberMarker', + 'result_key' => 'Parts', + ), + ), + 'waiters' => array( + '__default__' => array( + 'interval' => 5, + 'max_attempts' => 20, + ), + 'BucketExists' => array( + 'operation' => 'HeadBucket', + 'success.type' => 'output', + 'ignore_errors' => array( + 'NoSuchBucket', + ), + ), + 'BucketNotExists' => array( + 'operation' => 'HeadBucket', + 'success.type' => 'error', + 'success.value' => 'NoSuchBucket', + ), + 'ObjectExists' => array( + 'operation' => 'HeadObject', + 'success.type' => 'output', + 'ignore_errors' => array( + 'NoSuchKey', + ), + ), + 'ObjectNotExists' => array( + 'operation' => 'HeadObject', + 'success.type' => 'error', + 'success.value' => 'NoSuchKey' + ), + ), +); diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/ResumableDownload.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/ResumableDownload.php new file mode 100644 index 0000000..6d99677 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/ResumableDownload.php @@ -0,0 +1,176 @@ +params = $params; + $this->client = $client; + $this->params['Bucket'] = $bucket; + $this->params['Key'] = $key; + + // If a string is passed, then assume that the download should stream to a file on disk + if (is_string($target)) { + if (!($target = fopen($target, 'a+'))) { + throw new RuntimeException("Unable to open {$target} for writing"); + } + // Always append to the file + fseek($target, 0, SEEK_END); + } + + // Get the metadata and Content-MD5 of the object + $this->target = EntityBody::factory($target); + } + + /** + * Get the bucket of the download + * + * @return string + */ + public function getBucket() + { + return $this->params['Bucket']; + } + + /** + * Get the key of the download + * + * @return string + */ + public function getKey() + { + return $this->params['Key']; + } + + /** + * Get the file to which the contents are downloaded + * + * @return string + */ + public function getFilename() + { + return $this->target->getUri(); + } + + /** + * Download the remainder of the object from Amazon S3 + * + * Performs a message integrity check if possible + * + * @return Model + */ + public function __invoke() + { + $command = $this->client->getCommand('HeadObject', $this->params); + $this->meta = $command->execute(); + + if ($this->target->ftell() >= $this->meta['ContentLength']) { + return false; + } + + $this->meta['ContentMD5'] = (string) $command->getResponse()->getHeader('Content-MD5'); + + // Use a ReadLimitEntityBody so that rewinding the stream after an error does not cause the file pointer + // to enter an inconsistent state with the data being downloaded + $this->params['SaveAs'] = new ReadLimitEntityBody( + $this->target, + $this->meta['ContentLength'], + $this->target->ftell() + ); + + $result = $this->getRemaining(); + $this->checkIntegrity(); + + return $result; + } + + /** + * Send the command to get the remainder of the object + * + * @return Model + */ + protected function getRemaining() + { + $current = $this->target->ftell(); + $targetByte = $this->meta['ContentLength'] - 1; + $this->params['Range'] = "bytes={$current}-{$targetByte}"; + + // Set the starting offset so that the body is never seeked to before this point in the event of a retry + $this->params['SaveAs']->setOffset($current); + $command = $this->client->getCommand('GetObject', $this->params); + + return $command->execute(); + } + + /** + * Performs an MD5 message integrity check if possible + * + * @throws UnexpectedValueException if the message does not validate + */ + protected function checkIntegrity() + { + if ($this->target->isReadable() && $expected = $this->meta['ContentMD5']) { + $actual = $this->target->getContentMd5(); + if ($actual != $expected) { + throw new UnexpectedValueException( + "Message integrity check failed. Expected {$expected} but got {$actual}." + ); + } + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/S3Client.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/S3Client.php new file mode 100644 index 0000000..c17dd6c --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/S3Client.php @@ -0,0 +1,696 @@ + 'ListBuckets', + 'GetBucket' => 'ListObjects', + 'PutBucket' => 'CreateBucket', + + // SDK 1.x Aliases + 'GetBucketHeaders' => 'HeadBucket', + 'GetObjectHeaders' => 'HeadObject', + 'SetBucketAcl' => 'PutBucketAcl', + 'CreateObject' => 'PutObject', + 'DeleteObjects' => 'DeleteMultipleObjects', + 'PutObjectCopy' => 'CopyObject', + 'SetObjectAcl' => 'PutObjectAcl', + 'GetLogs' => 'GetBucketLogging', + 'GetVersioningStatus' => 'GetBucketVersioning', + 'SetBucketPolicy' => 'PutBucketPolicy', + 'CreateBucketNotification' => 'PutBucketNotification', + 'GetBucketNotifications' => 'GetBucketNotification', + 'CopyPart' => 'UploadPartCopy', + 'CreateWebsiteConfig' => 'PutBucketWebsite', + 'GetWebsiteConfig' => 'GetBucketWebsite', + 'DeleteWebsiteConfig' => 'DeleteBucketWebsite', + 'CreateObjectExpirationConfig' => 'PutBucketLifecycle', + 'GetObjectExpirationConfig' => 'GetBucketLifecycle', + 'DeleteObjectExpirationConfig' => 'DeleteBucketLifecycle', + ); + + protected $directory = __DIR__; + + /** + * Factory method to create a new Amazon S3 client using an array of configuration options. + * + * @param array|Collection $config Client configuration data + * + * @return S3Client + * @link http://docs.aws.amazon.com/aws-sdk-php/v2/guide/configuration.html#client-configuration-options + */ + public static function factory($config = array()) + { + $exceptionParser = new S3ExceptionParser(); + + // Configure the custom exponential backoff plugin for retrying S3 specific errors + if (!isset($config[Options::BACKOFF])) { + $retries = isset($config[Options::BACKOFF_RETRIES]) ? $config[Options::BACKOFF_RETRIES] : 3; + $config[Options::BACKOFF] = static::createBackoffPlugin($exceptionParser, $retries); + } + + $config[Options::SIGNATURE] = $signature = static::createSignature($config); + + $client = ClientBuilder::factory(__NAMESPACE__) + ->setConfig($config) + ->setConfigDefaults(array( + Options::VERSION => self::LATEST_API_VERSION, + Options::SERVICE_DESCRIPTION => __DIR__ . '/Resources/s3-%s.php' + )) + ->setExceptionParser($exceptionParser) + ->setIteratorsConfig(array( + 'more_key' => 'IsTruncated', + 'operations' => array( + 'ListBuckets', + 'ListMultipartUploads' => array( + 'limit_param' => 'MaxUploads', + 'token_param' => array('KeyMarker', 'UploadIdMarker'), + 'token_key' => array('NextKeyMarker', 'NextUploadIdMarker'), + ), + 'ListObjects' => array( + 'limit_param' => 'MaxKeys', + 'token_param' => 'Marker', + 'token_key' => 'NextMarker', + ), + 'ListObjectVersions' => array( + 'limit_param' => 'MaxKeys', + 'token_param' => array('KeyMarker', 'VersionIdMarker'), + 'token_key' => array('nextKeyMarker', 'nextVersionIdMarker'), + ), + 'ListParts' => array( + 'limit_param' => 'MaxParts', + 'result_key' => 'Parts', + 'token_param' => 'PartNumberMarker', + 'token_key' => 'NextPartNumberMarker', + ), + ) + )) + ->build(); + + // Use virtual hosted buckets when possible + $client->addSubscriber(new BucketStyleListener()); + // Ensure that ACP headers are applied when needed + $client->addSubscriber(new AcpListener()); + // Validate and add required Content-MD5 hashes (e.g. DeleteObjects) + $client->addSubscriber(new S3Md5Listener($signature)); + + // Allow for specifying bodies with file paths and file handles + $client->addSubscriber(new UploadBodyListener(array('PutObject', 'UploadPart'))); + + // Ensures that if a SSE-CPK key is provided, the key and md5 are formatted correctly + $client->addSubscriber(new SseCpkListener); + + // Add aliases for some S3 operations + $default = CompositeFactory::getDefaultChain($client); + $default->add( + new AliasFactory($client, static::$commandAliases), + 'Guzzle\Service\Command\Factory\ServiceDescriptionFactory' + ); + $client->setCommandFactory($default); + + return $client; + } + + /** + * Create an Amazon S3 specific backoff plugin + * + * @param S3ExceptionParser $exceptionParser + * + * @return BackoffPlugin + */ + private static function createBackoffPlugin(S3ExceptionParser $exceptionParser, $retries = 3) + { + return new BackoffPlugin( + new TruncatedBackoffStrategy($retries, + new IncompleteMultipartUploadChecker( + new CurlBackoffStrategy(null, + new HttpBackoffStrategy(null, + new SocketTimeoutChecker( + new ExpiredCredentialsChecker($exceptionParser, + new ExponentialBackoffStrategy() + ) + ) + ) + ) + ) + ) + ); + } + + /** + * Create an appropriate signature based on the configuration settings + * + * @param $config + * + * @return \Aws\Common\Signature\SignatureInterface + * @throws InvalidArgumentException + */ + private static function createSignature($config) + { + $currentValue = isset($config[Options::SIGNATURE]) ? $config[Options::SIGNATURE] : null; + + // Force v4 if no value is provided, a region is in the config, and + // the region starts with "cn-" or "eu-central-". + $requiresV4 = !$currentValue + && isset($config['region']) + && (strpos($config['region'], 'eu-central-') === 0 + || strpos($config['region'], 'cn-') === 0); + + // Use the Amazon S3 signature V4 when the value is set to "v4" or when + // the value is not set and the region starts with "cn-". + if ($currentValue == 'v4' || $requiresV4) { + // Force SignatureV4 for specific regions or if specified in the config + $currentValue = new S3SignatureV4('s3'); + } elseif (!$currentValue || $currentValue == 's3') { + // Use the Amazon S3 signature by default + $currentValue = new S3Signature(); + } + + // A region is require with v4 + if ($currentValue instanceof SignatureV4 && !isset($config['region'])) { + throw new InvalidArgumentException('A region must be specified ' + . 'when using signature version 4'); + } + + return $currentValue; + } + + /** + * Determine if a string is a valid name for a DNS compatible Amazon S3 + * bucket, meaning the bucket can be used as a subdomain in a URL (e.g., + * ".s3.amazonaws.com"). + * + * @param string $bucket The name of the bucket to check. + * + * @return bool TRUE if the bucket name is valid or FALSE if it is invalid. + */ + public static function isValidBucketName($bucket) + { + $bucketLen = strlen($bucket); + if ($bucketLen < 3 || $bucketLen > 63 || + // Cannot look like an IP address + preg_match('/(\d+\.){3}\d+$/', $bucket) || + // Cannot include special characters, must start and end with lower alnum + !preg_match('/^[a-z0-9]([a-z0-9\-\.]*[a-z0-9])?$/', $bucket) + ) { + return false; + } + + return true; + } + + /** + * Create a pre-signed URL for a request + * + * @param RequestInterface $request Request to generate the URL for. Use the factory methods of the client to + * create this request object + * @param int|string|\DateTime $expires The time at which the URL should expire. This can be a Unix timestamp, a + * PHP DateTime object, or a string that can be evaluated by strtotime + * + * @return string + * @throws InvalidArgumentException if the request is not associated with this client object + */ + public function createPresignedUrl(RequestInterface $request, $expires) + { + if ($request->getClient() !== $this) { + throw new InvalidArgumentException('The request object must be associated with the client. Use the ' + . '$client->get(), $client->head(), $client->post(), $client->put(), etc. methods when passing in a ' + . 'request object'); + } + + return $this->signature->createPresignedUrl($request, $this->credentials, $expires); + } + + /** + * Returns the URL to an object identified by its bucket and key. If an expiration time is provided, the URL will + * be signed and set to expire at the provided time. + * + * Note: This method does not ensure that the generated URL is valid. For example, the bucket referenced may not + * exist, the key referenced may not exist, and the URL might include parameters that require it to be signed. + * If you need to use parameters that require a signed URL (e.g., ResponseCacheControl), then you must sign the + * URL either by providing an $expires argument or by signing the URL returned by this method in some other + * manner. + * + * @param string $bucket The name of the bucket where the object is located + * @param string $key The key of the object + * @param mixed $expires The time at which the URL should expire + * @param array $args Arguments to the GetObject command. Additionally you can specify a "Scheme" if you would + * like the URL to use a different scheme than what the client is configured to use + * + * @return string The URL to the object + */ + public function getObjectUrl($bucket, $key, $expires = null, array $args = array()) + { + $command = $this->getCommand('GetObject', $args + array('Bucket' => $bucket, 'Key' => $key)); + + if ($command->hasKey('Scheme')) { + $scheme = $command['Scheme']; + $request = $command->remove('Scheme')->prepare()->setScheme($scheme)->setPort(null); + } else { + $request = $command->prepare(); + } + + return $expires ? $this->createPresignedUrl($request, $expires) : $request->getUrl(); + } + + /** + * Helper used to clear the contents of a bucket. Use the {@see ClearBucket} object directly + * for more advanced options and control. + * + * @param string $bucket Name of the bucket to clear. + * + * @return int Returns the number of deleted keys + */ + public function clearBucket($bucket) + { + $clear = new ClearBucket($this, $bucket); + + return $clear->clear(); + } + + /** + * Determines whether or not a bucket exists by name + * + * @param string $bucket The name of the bucket + * @param bool $accept403 Set to true if 403s are acceptable + * @param array $options Additional options to add to the executed command + * + * @return bool + */ + public function doesBucketExist($bucket, $accept403 = true, array $options = array()) + { + return $this->checkExistenceWithCommand( + $this->getCommand('HeadBucket', array_merge($options, array( + 'Bucket' => $bucket + ))), $accept403 + ); + } + + /** + * Determines whether or not an object exists by name + * + * @param string $bucket The name of the bucket + * @param string $key The key of the object + * @param array $options Additional options to add to the executed command + * + * @return bool + */ + public function doesObjectExist($bucket, $key, array $options = array()) + { + return $this->checkExistenceWithCommand( + $this->getCommand('HeadObject', array_merge($options, array( + 'Bucket' => $bucket, + 'Key' => $key + ))) + ); + } + + /** + * Determines whether or not a bucket policy exists for a bucket + * + * @param string $bucket The name of the bucket + * @param array $options Additional options to add to the executed command + * + * @return bool + */ + public function doesBucketPolicyExist($bucket, array $options = array()) + { + return $this->checkExistenceWithCommand( + $this->getCommand('GetBucketPolicy', array_merge($options, array( + 'Bucket' => $bucket + ))) + ); + } + + /** + * Raw URL encode a key and allow for '/' characters + * + * @param string $key Key to encode + * + * @return string Returns the encoded key + */ + public static function encodeKey($key) + { + return str_replace('%2F', '/', rawurlencode($key)); + } + + /** + * Explode a prefixed key into an array of values + * + * @param string $key Key to explode + * + * @return array Returns the exploded + */ + public static function explodeKey($key) + { + // Remove a leading slash if one is found + return explode('/', $key && $key[0] == '/' ? substr($key, 1) : $key); + } + + /** + * Register the Amazon S3 stream wrapper and associates it with this client object + * + * @return $this + */ + public function registerStreamWrapper() + { + StreamWrapper::register($this); + + return $this; + } + + /** + * Upload a file, stream, or string to a bucket. If the upload size exceeds the specified threshold, the upload + * will be performed using parallel multipart uploads. + * + * @param string $bucket Bucket to upload the object + * @param string $key Key of the object + * @param mixed $body Object data to upload. Can be a Guzzle\Http\EntityBodyInterface, stream resource, or + * string of data to upload. + * @param string $acl ACL to apply to the object + * @param array $options Custom options used when executing commands: + * - params: Custom parameters to use with the upload. The parameters must map to a PutObject + * or InitiateMultipartUpload operation parameters. + * - min_part_size: Minimum size to allow for each uploaded part when performing a multipart upload. + * - concurrency: Maximum number of concurrent multipart uploads. + * - before_upload: Callback to invoke before each multipart upload. The callback will receive a + * Guzzle\Common\Event object with context. + * + * @see Aws\S3\Model\MultipartUpload\UploadBuilder for more options and customization + * @return \Guzzle\Service\Resource\Model Returns the modeled result of the performed operation + */ + public function upload($bucket, $key, $body, $acl = 'private', array $options = array()) + { + $body = EntityBody::factory($body); + $options = Collection::fromConfig(array_change_key_case($options), array( + 'min_part_size' => AbstractMulti::MIN_PART_SIZE, + 'params' => array(), + 'concurrency' => $body->getWrapper() == 'plainfile' ? 3 : 1 + )); + + if ($body->getSize() < $options['min_part_size']) { + // Perform a simple PutObject operation + return $this->putObject(array( + 'Bucket' => $bucket, + 'Key' => $key, + 'Body' => $body, + 'ACL' => $acl + ) + $options['params']); + } + + // Perform a multipart upload if the file is large enough + $transfer = UploadBuilder::newInstance() + ->setBucket($bucket) + ->setKey($key) + ->setMinPartSize($options['min_part_size']) + ->setConcurrency($options['concurrency']) + ->setClient($this) + ->setSource($body) + ->setTransferOptions($options->toArray()) + ->addOptions($options['params']) + ->setOption('ACL', $acl) + ->build(); + + if ($options['before_upload']) { + $transfer->getEventDispatcher()->addListener( + AbstractTransfer::BEFORE_PART_UPLOAD, + $options['before_upload'] + ); + } + + return $transfer->upload(); + } + + /** + * Recursively uploads all files in a given directory to a given bucket. + * + * @param string $directory Full path to a directory to upload + * @param string $bucket Name of the bucket + * @param string $keyPrefix Virtual directory key prefix to add to each upload + * @param array $options Associative array of upload options + * - params: Array of parameters to use with each PutObject operation performed during the transfer + * - base_dir: Base directory to remove from each object key + * - force: Set to true to upload every file, even if the file is already in Amazon S3 and has not changed + * - concurrency: Maximum number of parallel uploads (defaults to 10) + * - debug: Set to true or an fopen resource to enable debug mode to print information about each upload + * - multipart_upload_size: When the size of a file exceeds this value, the file will be uploaded using a + * multipart upload. + * + * @see Aws\S3\S3Sync\S3Sync for more options and customization + */ + public function uploadDirectory($directory, $bucket, $keyPrefix = null, array $options = array()) + { + $options = Collection::fromConfig( + $options, + array( + 'base_dir' => realpath($directory) ?: $directory + ) + ); + + $builder = $options['builder'] ?: UploadSyncBuilder::getInstance(); + $builder->uploadFromDirectory($directory) + ->setClient($this) + ->setBucket($bucket) + ->setKeyPrefix($keyPrefix) + ->setConcurrency($options['concurrency'] ?: 5) + ->setBaseDir($options['base_dir']) + ->force($options['force']) + ->setOperationParams($options['params'] ?: array()) + ->enableDebugOutput($options['debug']); + + if ($options->hasKey('multipart_upload_size')) { + $builder->setMultipartUploadSize($options['multipart_upload_size']); + } + + $builder->build()->transfer(); + } + + /** + * Downloads a bucket to the local filesystem + * + * @param string $directory Directory to download to + * @param string $bucket Bucket to download from + * @param string $keyPrefix Only download objects that use this key prefix + * @param array $options Associative array of download options + * - params: Array of parameters to use with each GetObject operation performed during the transfer + * - base_dir: Base directory to remove from each object key when storing in the local filesystem + * - force: Set to true to download every file, even if the file is already on the local filesystem and has not + * changed + * - concurrency: Maximum number of parallel downloads (defaults to 10) + * - debug: Set to true or a fopen resource to enable debug mode to print information about each download + * - allow_resumable: Set to true to allow previously interrupted downloads to be resumed using a Range GET + */ + public function downloadBucket($directory, $bucket, $keyPrefix = '', array $options = array()) + { + $options = new Collection($options); + $builder = $options['builder'] ?: DownloadSyncBuilder::getInstance(); + $builder->setDirectory($directory) + ->setClient($this) + ->setBucket($bucket) + ->setKeyPrefix($keyPrefix) + ->setConcurrency($options['concurrency'] ?: 10) + ->setBaseDir($options['base_dir']) + ->force($options['force']) + ->setOperationParams($options['params'] ?: array()) + ->enableDebugOutput($options['debug']); + + if ($options['allow_resumable']) { + $builder->allowResumableDownloads(); + } + + $builder->build()->transfer(); + } + + /** + * Deletes objects from Amazon S3 that match the result of a ListObjects operation. For example, this allows you + * to do things like delete all objects that match a specific key prefix. + * + * @param string $bucket Bucket that contains the object keys + * @param string $prefix Optionally delete only objects under this key prefix + * @param string $regex Delete only objects that match this regex + * @param array $options Options used when deleting the object: + * - before_delete: Callback to invoke before each delete. The callback will receive a + * Guzzle\Common\Event object with context. + * + * @see Aws\S3\S3Client::listObjects + * @see Aws\S3\Model\ClearBucket For more options or customization + * @return int Returns the number of deleted keys + * @throws RuntimeException if no prefix and no regex is given + */ + public function deleteMatchingObjects($bucket, $prefix = '', $regex = '', array $options = array()) + { + if (!$prefix && !$regex) { + throw new RuntimeException('A prefix or regex is required, or use S3Client::clearBucket().'); + } + + $clear = new ClearBucket($this, $bucket); + $iterator = $this->getIterator('ListObjects', array('Bucket' => $bucket, 'Prefix' => $prefix)); + + if ($regex) { + $iterator = new FilterIterator($iterator, function ($current) use ($regex) { + return preg_match($regex, $current['Key']); + }); + } + + $clear->setIterator($iterator); + if (isset($options['before_delete'])) { + $clear->getEventDispatcher()->addListener(ClearBucket::BEFORE_CLEAR, $options['before_delete']); + } + + return $clear->clear(); + } + + /** + * Determines whether or not a resource exists using a command + * + * @param CommandInterface $command Command used to poll for the resource + * @param bool $accept403 Set to true if 403s are acceptable + * + * @return bool + * @throws S3Exception|\Exception if there is an unhandled exception + */ + protected function checkExistenceWithCommand(CommandInterface $command, $accept403 = false) + { + try { + $command->execute(); + $exists = true; + } catch (AccessDeniedException $e) { + $exists = (bool) $accept403; + } catch (S3Exception $e) { + $exists = false; + if ($e->getResponse()->getStatusCode() >= 500) { + // @codeCoverageIgnoreStart + throw $e; + // @codeCoverageIgnoreEnd + } + } + + return $exists; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/S3Md5Listener.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/S3Md5Listener.php new file mode 100644 index 0000000..7558c47 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/S3Md5Listener.php @@ -0,0 +1,73 @@ + 'onCommandAfterPrepare'); + } + + public function __construct(SignatureInterface $signature) + { + $this->signature = $signature; + } + + public function onCommandAfterPrepare(Event $event) + { + $command = $event['command']; + $operation = $command->getOperation(); + + if ($operation->getData('contentMd5')) { + // Add the MD5 if it is required for all signers + $this->addMd5($command); + } elseif ($operation->hasParam('ContentMD5')) { + $value = $command['ContentMD5']; + // Add a computed MD5 if the parameter is set to true or if + // not using Signature V4 and the value is not set (null). + if ($value === true || + ($value === null && !($this->signature instanceof SignatureV4)) + ) { + $this->addMd5($command); + } + } + } + + private function addMd5(CommandInterface $command) + { + $request = $command->getRequest(); + $body = $request->getBody(); + if ($body && $body->getSize() > 0) { + if (false !== ($md5 = $body->getContentMd5(true, true))) { + $request->setHeader('Content-MD5', $md5); + } + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/S3Signature.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/S3Signature.php new file mode 100644 index 0000000..ef9a86b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/S3Signature.php @@ -0,0 +1,266 @@ +signableQueryString); + + // Add the security token header if one is being used by the credentials + if ($token = $credentials->getSecurityToken()) { + $request->setHeader('x-amz-security-token', $token); + } + + $request->removeHeader('x-amz-date'); + $request->setHeader('Date', gmdate(\DateTime::RFC2822)); + + $stringToSign = $this->createCanonicalizedString($request); + $request->getParams()->set('aws.string_to_sign', $stringToSign); + + $request->setHeader( + 'Authorization', + 'AWS ' . $credentials->getAccessKeyId() . ':' . $this->signString($stringToSign, $credentials) + ); + } + + public function createPresignedUrl( + RequestInterface $request, + CredentialsInterface $credentials, + $expires + ) { + if ($expires instanceof \DateTime) { + $expires = $expires->getTimestamp(); + } elseif (!is_numeric($expires)) { + $expires = strtotime($expires); + } + + // Operate on a clone of the request, so the original is not altered + $request = clone $request; + + // URL encoding already occurs in the URI template expansion. Undo that and encode using the same encoding as + // GET object, PUT object, etc. + $path = S3Client::encodeKey(rawurldecode($request->getPath())); + $request->setPath($path); + + // Make sure to handle temporary credentials + if ($token = $credentials->getSecurityToken()) { + $request->setHeader('x-amz-security-token', $token); + $request->getQuery()->set('x-amz-security-token', $token); + } + + // Set query params required for pre-signed URLs + $request->getQuery() + ->set('AWSAccessKeyId', $credentials->getAccessKeyId()) + ->set('Expires', $expires) + ->set('Signature', $this->signString( + $this->createCanonicalizedString($request, $expires), + $credentials + )); + + // Move X-Amz-* headers to the query string + foreach ($request->getHeaders() as $name => $header) { + $name = strtolower($name); + if (strpos($name, 'x-amz-') === 0) { + $request->getQuery()->set($name, (string) $header); + $request->removeHeader($name); + } + } + + return $request->getUrl(); + } + + public function signString($string, CredentialsInterface $credentials) + { + return base64_encode(hash_hmac('sha1', $string, $credentials->getSecretKey(), true)); + } + + public function createCanonicalizedString(RequestInterface $request, $expires = null) + { + $buffer = $request->getMethod() . "\n"; + + // Add the interesting headers + foreach ($this->signableHeaders as $header) { + $buffer .= (string) $request->getHeader($header) . "\n"; + } + + // Choose dates from left to right based on what's set + $date = $expires ?: (string) $request->getHeader('date'); + + $buffer .= "{$date}\n" + . $this->createCanonicalizedAmzHeaders($request) + . $this->createCanonicalizedResource($request); + + return $buffer; + } + + /** + * Create a canonicalized AmzHeaders string for a signature. + * + * @param RequestInterface $request Request from which to gather headers + * + * @return string Returns canonicalized AMZ headers. + */ + private function createCanonicalizedAmzHeaders(RequestInterface $request) + { + $headers = array(); + foreach ($request->getHeaders() as $name => $header) { + $name = strtolower($name); + if (strpos($name, 'x-amz-') === 0) { + $value = trim((string) $header); + if ($value || $value === '0') { + $headers[$name] = $name . ':' . $value; + } + } + } + + if (!$headers) { + return ''; + } + + ksort($headers); + + return implode("\n", $headers) . "\n"; + } + + /** + * Create a canonicalized resource for a request + * + * @param RequestInterface $request Request for the resource + * + * @return string + */ + private function createCanonicalizedResource(RequestInterface $request) + { + $buffer = $request->getParams()->get('s3.resource'); + // When sending a raw HTTP request (e.g. $client->get()) + if (null === $buffer) { + $bucket = $request->getParams()->get('bucket') ?: $this->parseBucketName($request); + // Use any specified bucket name, the parsed bucket name, or no bucket name when interacting with GetService + $buffer = $bucket ? "/{$bucket}" : ''; + // Remove encoding from the path and use the S3 specific encoding + $path = S3Client::encodeKey(rawurldecode($request->getPath())); + // if the bucket was path style, then ensure that the bucket wasn't duplicated in the resource + $buffer .= preg_replace("#^/{$bucket}/{$bucket}#", "/{$bucket}", $path); + } + + // Remove double slashes + $buffer = str_replace('//', '/', $buffer); + + // Add sub resource parameters + $query = $request->getQuery(); + $first = true; + foreach ($this->signableQueryString as $key) { + if ($query->hasKey($key)) { + $value = $query[$key]; + $buffer .= $first ? '?' : '&'; + $first = false; + $buffer .= $key; + // Don't add values for empty sub-resources + if ($value !== '' && + $value !== false && + $value !== null && + $value !== QueryString::BLANK + ) { + $buffer .= "={$value}"; + } + } + } + + return $buffer; + } + + /** + * Parse the bucket name from a request object + * + * @param RequestInterface $request Request to parse + * + * @return string + */ + private function parseBucketName(RequestInterface $request) + { + $baseUrl = Url::factory($request->getClient()->getBaseUrl()); + $baseHost = $baseUrl->getHost(); + $host = $request->getHost(); + + if (strpos($host, $baseHost) === false) { + // Does not contain the base URL, so it's either a redirect, CNAME, or using a different region + $baseHost = ''; + // For every known S3 host, check if that host is present on the request + $regions = $request->getClient()->getDescription()->getData('regions'); + foreach ($regions as $region) { + if (strpos($host, $region['hostname']) !== false) { + // This host matches the request host. Tells use the region and endpoint-- we can derive the bucket + $baseHost = $region['hostname']; + break; + } + } + // If no matching base URL was found, then assume that this is a CNAME, and the CNAME is the bucket + if (!$baseHost) { + return $host; + } + } + + // Remove the baseURL from the host of the request to attempt to determine the bucket name + return trim(str_replace($baseHost, '', $request->getHost()), ' .'); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/S3SignatureInterface.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/S3SignatureInterface.php new file mode 100644 index 0000000..0b7e940 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/S3SignatureInterface.php @@ -0,0 +1,24 @@ +hasHeader('x-amz-content-sha256')) { + $request->setHeader( + 'x-amz-content-sha256', + $this->getPayload($request) + ); + } + + parent::signRequest($request, $credentials); + } + + /** + * Override used to allow pre-signed URLs to be created for an + * in-determinate request payload. + */ + protected function getPresignedPayload(RequestInterface $request) + { + return 'UNSIGNED-PAYLOAD'; + } + + /** + * Amazon S3 does not double-encode the path component in the canonical req + */ + protected function createCanonicalizedPath(RequestInterface $request) + { + return '/' . ltrim($request->getPath(), '/'); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/SocketTimeoutChecker.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/SocketTimeoutChecker.php new file mode 100644 index 0000000..ede2b96 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/SocketTimeoutChecker.php @@ -0,0 +1,71 @@ +setNext($next); + } + } + + /** + * {@inheridoc} + */ + public function makesDecision() + { + return true; + } + + /** + * {@inheritdoc} + */ + protected function getDelay( + $retries, + RequestInterface $request, + Response $response = null, + HttpException $e = null + ) { + if ($response + && $response->getStatusCode() == 400 + && strpos($response->getBody(), self::ERR) + ) { + return true; + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/SseCpkListener.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/SseCpkListener.php new file mode 100644 index 0000000..c1a9260 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/SseCpkListener.php @@ -0,0 +1,68 @@ + 'onCommandBeforePrepare'); + } + + public function onCommandBeforePrepare(Event $event) + { + /** @var CommandInterface $command */ + $command = $event['command']; + + // Allows only HTTPS connections when using SSE-C + if ($command['SSECustomerKey'] || + $command['CopySourceSSECustomerKey'] + ) { + $this->validateScheme($command); + } + + // Prepare the normal SSE-CPK headers + if ($command['SSECustomerKey']) { + $this->prepareSseParams($command); + } + + // If it's a copy operation, prepare the SSE-CPK headers for the source. + if ($command['CopySourceSSECustomerKey']) { + $this->prepareSseParams($command, true); + } + } + + private function validateScheme(CommandInterface $command) + { + if ($command->getClient()->getConfig('scheme') !== 'https') { + throw new RuntimeException('You must configure your S3 client to ' + . 'use HTTPS in order to use the SSE-C features.'); + } + } + + private function prepareSseParams( + CommandInterface $command, + $isCopy = false + ) { + $prefix = $isCopy ? 'CopySource' : ''; + + // Base64 encode the provided key + $key = $command[$prefix . 'SSECustomerKey']; + $command[$prefix . 'SSECustomerKey'] = base64_encode($key); + + // Base64 the provided MD5 or, generate an MD5 if not provided + if ($md5 = $command[$prefix . 'SSECustomerKeyMD5']) { + $command[$prefix . 'SSECustomerKeyMD5'] = base64_encode($md5); + } else { + $command[$prefix . 'SSECustomerKeyMD5'] = base64_encode(md5($key, true)); + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/StreamWrapper.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/StreamWrapper.php new file mode 100644 index 0000000..b191ef2 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/StreamWrapper.php @@ -0,0 +1,907 @@ +/" files with PHP streams, supporting "r", "w", "a", "x". + * + * # Supported stream related PHP functions: + * - fopen, fclose, fread, fwrite, fseek, ftell, feof, fflush + * - opendir, closedir, readdir, rewinddir + * - copy, rename, unlink + * - mkdir, rmdir, rmdir (recursive) + * - file_get_contents, file_put_contents + * - file_exists, filesize, is_file, is_dir + * + * # Opening "r" (read only) streams: + * + * Read only streams are truly streaming by default and will not allow you to seek. This is because data + * read from the stream is not kept in memory or on the local filesystem. You can force a "r" stream to be seekable + * by setting the "seekable" stream context option true. This will allow true streaming of data from Amazon S3, but + * will maintain a buffer of previously read bytes in a 'php://temp' stream to allow seeking to previously read bytes + * from the stream. + * + * You may pass any GetObject parameters as 's3' stream context options. These options will affect how the data is + * downloaded from Amazon S3. + * + * # Opening "w" and "x" (write only) streams: + * + * Because Amazon S3 requires a Content-Length header, write only streams will maintain a 'php://temp' stream to buffer + * data written to the stream until the stream is flushed (usually by closing the stream with fclose). + * + * You may pass any PutObject parameters as 's3' stream context options. These options will affect how the data is + * uploaded to Amazon S3. + * + * When opening an "x" stream, the file must exist on Amazon S3 for the stream to open successfully. + * + * # Opening "a" (write only append) streams: + * + * Similar to "w" streams, opening append streams requires that the data be buffered in a "php://temp" stream. Append + * streams will attempt to download the contents of an object in Amazon S3, seek to the end of the object, then allow + * you to append to the contents of the object. The data will then be uploaded using a PutObject operation when the + * stream is flushed (usually with fclose). + * + * You may pass any GetObject and/or PutObject parameters as 's3' stream context options. These options will affect how + * the data is downloaded and uploaded from Amazon S3. + * + * Stream context options: + * + * - "seekable": Set to true to create a seekable "r" (read only) stream by using a php://temp stream buffer + * - For "unlink" only: Any option that can be passed to the DeleteObject operation + */ +class StreamWrapper +{ + /** + * @var resource|null Stream context (this is set by PHP when a context is used) + */ + public $context; + + /** + * @var S3Client Client used to send requests + */ + protected static $client; + + /** + * @var string Mode the stream was opened with + */ + protected $mode; + + /** + * @var EntityBody Underlying stream resource + */ + protected $body; + + /** + * @var array Current parameters to use with the flush operation + */ + protected $params; + + /** + * @var ListObjectsIterator Iterator used with opendir() and subsequent readdir() calls + */ + protected $objectIterator; + + /** + * @var string The bucket that was opened when opendir() was called + */ + protected $openedBucket; + + /** + * @var string The prefix of the bucket that was opened with opendir() + */ + protected $openedBucketPrefix; + + /** + * @var array The next key to retrieve when using a directory iterator. Helps for fast directory traversal. + */ + protected static $nextStat = array(); + + /** + * Register the 's3://' stream wrapper + * + * @param S3Client $client Client to use with the stream wrapper + */ + public static function register(S3Client $client) + { + if (in_array('s3', stream_get_wrappers())) { + stream_wrapper_unregister('s3'); + } + + stream_wrapper_register('s3', get_called_class(), STREAM_IS_URL); + static::$client = $client; + } + + /** + * Close the stream + */ + public function stream_close() + { + $this->body = null; + } + + /** + * @param string $path + * @param string $mode + * @param int $options + * @param string $opened_path + * + * @return bool + */ + public function stream_open($path, $mode, $options, &$opened_path) + { + // We don't care about the binary flag + $this->mode = $mode = rtrim($mode, 'bt'); + $this->params = $params = $this->getParams($path); + $errors = array(); + + if (!$params['Key']) { + $errors[] = 'Cannot open a bucket. You must specify a path in the form of s3://bucket/key'; + } + + if (strpos($mode, '+')) { + $errors[] = 'The Amazon S3 stream wrapper does not allow simultaneous reading and writing.'; + } + + if (!in_array($mode, array('r', 'w', 'a', 'x'))) { + $errors[] = "Mode not supported: {$mode}. Use one 'r', 'w', 'a', or 'x'."; + } + + // When using mode "x" validate if the file exists before attempting to read + if ($mode == 'x' && static::$client->doesObjectExist($params['Bucket'], $params['Key'], $this->getOptions())) { + $errors[] = "{$path} already exists on Amazon S3"; + } + + if (!$errors) { + if ($mode == 'r') { + return $this->openReadStream($params, $errors); + } elseif ($mode == 'a') { + return $this->openAppendStream($params, $errors); + } else { + return $this->openWriteStream($params, $errors); + } + } + + return $this->triggerError($errors); + } + + /** + * @return bool + */ + public function stream_eof() + { + return $this->body->feof(); + } + + /** + * @return bool + */ + public function stream_flush() + { + if ($this->mode == 'r') { + return false; + } + + $this->body->rewind(); + $params = $this->params; + $params['Body'] = $this->body; + + // Attempt to guess the ContentType of the upload based on the + // file extension of the key + if (!isset($params['ContentType']) && + ($type = Mimetypes::getInstance()->fromFilename($params['Key'])) + ) { + $params['ContentType'] = $type; + } + + try { + static::$client->putObject($params); + return true; + } catch (\Exception $e) { + return $this->triggerError($e->getMessage()); + } + } + + /** + * Read data from the underlying stream + * + * @param int $count Amount of bytes to read + * + * @return string + */ + public function stream_read($count) + { + return $this->body->read($count); + } + + /** + * Seek to a specific byte in the stream + * + * @param int $offset Seek offset + * @param int $whence Whence (SEEK_SET, SEEK_CUR, SEEK_END) + * + * @return bool + */ + public function stream_seek($offset, $whence = SEEK_SET) + { + return $this->body->seek($offset, $whence); + } + + /** + * Get the current position of the stream + * + * @return int Returns the current position in the stream + */ + public function stream_tell() + { + return $this->body->ftell(); + } + + /** + * Write data the to the stream + * + * @param string $data + * + * @return int Returns the number of bytes written to the stream + */ + public function stream_write($data) + { + return $this->body->write($data); + } + + /** + * Delete a specific object + * + * @param string $path + * @return bool + */ + public function unlink($path) + { + try { + $this->clearStatInfo($path); + static::$client->deleteObject($this->getParams($path)); + return true; + } catch (\Exception $e) { + return $this->triggerError($e->getMessage()); + } + } + + /** + * @return array + */ + public function stream_stat() + { + $stat = fstat($this->body->getStream()); + // Add the size of the underlying stream if it is known + if ($this->mode == 'r' && $this->body->getSize()) { + $stat[7] = $stat['size'] = $this->body->getSize(); + } + + return $stat; + } + + /** + * Provides information for is_dir, is_file, filesize, etc. Works on buckets, keys, and prefixes + * + * @param string $path + * @param int $flags + * + * @return array Returns an array of stat data + * @link http://www.php.net/manual/en/streamwrapper.url-stat.php + */ + public function url_stat($path, $flags) + { + // Check if this path is in the url_stat cache + if (isset(static::$nextStat[$path])) { + return static::$nextStat[$path]; + } + + $parts = $this->getParams($path); + + if (!$parts['Key']) { + // Stat "directories": buckets, or "s3://" + if (!$parts['Bucket'] || static::$client->doesBucketExist($parts['Bucket'])) { + return $this->formatUrlStat($path); + } else { + return $this->triggerError("File or directory not found: {$path}", $flags); + } + } + + try { + try { + $result = static::$client->headObject($parts)->toArray(); + if (substr($parts['Key'], -1, 1) == '/' && $result['ContentLength'] == 0) { + // Return as if it is a bucket to account for console bucket objects (e.g., zero-byte object "foo/") + return $this->formatUrlStat($path); + } else { + // Attempt to stat and cache regular object + return $this->formatUrlStat($result); + } + } catch (NoSuchKeyException $e) { + // Maybe this isn't an actual key, but a prefix. Do a prefix listing of objects to determine. + $result = static::$client->listObjects(array( + 'Bucket' => $parts['Bucket'], + 'Prefix' => rtrim($parts['Key'], '/') . '/', + 'MaxKeys' => 1 + )); + if (!$result['Contents'] && !$result['CommonPrefixes']) { + return $this->triggerError("File or directory not found: {$path}", $flags); + } + // This is a directory prefix + return $this->formatUrlStat($path); + } + } catch (\Exception $e) { + return $this->triggerError($e->getMessage(), $flags); + } + } + + /** + * Support for mkdir(). + * + * @param string $path Directory which should be created. + * @param int $mode Permissions. 700-range permissions map to ACL_PUBLIC. 600-range permissions map to + * ACL_AUTH_READ. All other permissions map to ACL_PRIVATE. Expects octal form. + * @param int $options A bitwise mask of values, such as STREAM_MKDIR_RECURSIVE. + * + * @return bool + * @link http://www.php.net/manual/en/streamwrapper.mkdir.php + */ + public function mkdir($path, $mode, $options) + { + $params = $this->getParams($path); + if (!$params['Bucket']) { + return false; + } + + if (!isset($params['ACL'])) { + $params['ACL'] = $this->determineAcl($mode); + } + + return !isset($params['Key']) || $params['Key'] === '/' + ? $this->createBucket($path, $params) + : $this->createPseudoDirectory($path, $params); + } + + /** + * Remove a bucket from Amazon S3 + * + * @param string $path the directory path + * @param int $options A bitwise mask of values + * + * @return bool true if directory was successfully removed + * @link http://www.php.net/manual/en/streamwrapper.rmdir.php + */ + public function rmdir($path, $options) + { + $params = $this->getParams($path); + if (!$params['Bucket']) { + return $this->triggerError('You cannot delete s3://. Please specify a bucket.'); + } + + try { + + if (!$params['Key']) { + static::$client->deleteBucket(array('Bucket' => $params['Bucket'])); + $this->clearStatInfo($path); + return true; + } + + // Use a key that adds a trailing slash if needed. + $prefix = rtrim($params['Key'], '/') . '/'; + + $result = static::$client->listObjects(array( + 'Bucket' => $params['Bucket'], + 'Prefix' => $prefix, + 'MaxKeys' => 1 + )); + + // Check if the bucket contains keys other than the placeholder + if ($result['Contents']) { + foreach ($result['Contents'] as $key) { + if ($key['Key'] == $prefix) { + continue; + } + return $this->triggerError('Psuedo folder is not empty'); + } + return $this->unlink(rtrim($path, '/') . '/'); + } + + return $result['CommonPrefixes'] + ? $this->triggerError('Pseudo folder contains nested folders') + : true; + + } catch (\Exception $e) { + return $this->triggerError($e->getMessage()); + } + } + + /** + * Support for opendir(). + * + * The opendir() method of the Amazon S3 stream wrapper supports a stream + * context option of "listFilter". listFilter must be a callable that + * accepts an associative array of object data and returns true if the + * object should be yielded when iterating the keys in a bucket. + * + * @param string $path The path to the directory (e.g. "s3://dir[]") + * @param string $options Whether or not to enforce safe_mode (0x04). Unused. + * + * @return bool true on success + * @see http://www.php.net/manual/en/function.opendir.php + */ + public function dir_opendir($path, $options) + { + // Reset the cache + $this->clearStatInfo(); + $params = $this->getParams($path); + $delimiter = $this->getOption('delimiter'); + $filterFn = $this->getOption('listFilter'); + + if ($delimiter === null) { + $delimiter = '/'; + } + + if ($params['Key']) { + $params['Key'] = rtrim($params['Key'], $delimiter) . $delimiter; + } + + $this->openedBucket = $params['Bucket']; + $this->openedBucketPrefix = $params['Key']; + $operationParams = array('Bucket' => $params['Bucket'], 'Prefix' => $params['Key']); + + if ($delimiter) { + $operationParams['Delimiter'] = $delimiter; + } + + $objectIterator = static::$client->getIterator('ListObjects', $operationParams, array( + 'return_prefixes' => true, + 'sort_results' => true + )); + + // Filter our "/" keys added by the console as directories, and ensure + // that if a filter function is provided that it passes the filter. + $this->objectIterator = new FilterIterator( + $objectIterator, + function ($key) use ($filterFn) { + // Each yielded results can contain a "Key" or "Prefix" + return (!$filterFn || call_user_func($filterFn, $key)) && + (!isset($key['Key']) || substr($key['Key'], -1, 1) !== '/'); + } + ); + + $this->objectIterator->next(); + + return true; + } + + /** + * Close the directory listing handles + * + * @return bool true on success + */ + public function dir_closedir() + { + $this->objectIterator = null; + + return true; + } + + /** + * This method is called in response to rewinddir() + * + * @return boolean true on success + */ + public function dir_rewinddir() + { + $this->clearStatInfo(); + $this->objectIterator->rewind(); + + return true; + } + + /** + * This method is called in response to readdir() + * + * @return string Should return a string representing the next filename, or false if there is no next file. + * + * @link http://www.php.net/manual/en/function.readdir.php + */ + public function dir_readdir() + { + // Skip empty result keys + if (!$this->objectIterator->valid()) { + return false; + } + + $current = $this->objectIterator->current(); + if (isset($current['Prefix'])) { + // Include "directories". Be sure to strip a trailing "/" + // on prefixes. + $prefix = rtrim($current['Prefix'], '/'); + $result = str_replace($this->openedBucketPrefix, '', $prefix); + $key = "s3://{$this->openedBucket}/{$prefix}"; + $stat = $this->formatUrlStat($prefix); + } else { + // Remove the prefix from the result to emulate other + // stream wrappers. + $result = str_replace($this->openedBucketPrefix, '', $current['Key']); + $key = "s3://{$this->openedBucket}/{$current['Key']}"; + $stat = $this->formatUrlStat($current); + } + + // Cache the object data for quick url_stat lookups used with + // RecursiveDirectoryIterator. + static::$nextStat = array($key => $stat); + $this->objectIterator->next(); + + return $result; + } + + /** + * Called in response to rename() to rename a file or directory. Currently only supports renaming objects. + * + * @param string $path_from the path to the file to rename + * @param string $path_to the new path to the file + * + * @return bool true if file was successfully renamed + * @link http://www.php.net/manual/en/function.rename.php + */ + public function rename($path_from, $path_to) + { + $partsFrom = $this->getParams($path_from); + $partsTo = $this->getParams($path_to); + $this->clearStatInfo($path_from); + $this->clearStatInfo($path_to); + + if (!$partsFrom['Key'] || !$partsTo['Key']) { + return $this->triggerError('The Amazon S3 stream wrapper only supports copying objects'); + } + + try { + // Copy the object and allow overriding default parameters if desired, but by default copy metadata + static::$client->copyObject($this->getOptions() + array( + 'Bucket' => $partsTo['Bucket'], + 'Key' => $partsTo['Key'], + 'CopySource' => '/' . $partsFrom['Bucket'] . '/' . rawurlencode($partsFrom['Key']), + 'MetadataDirective' => 'COPY' + )); + // Delete the original object + static::$client->deleteObject(array( + 'Bucket' => $partsFrom['Bucket'], + 'Key' => $partsFrom['Key'] + ) + $this->getOptions()); + } catch (\Exception $e) { + return $this->triggerError($e->getMessage()); + } + + return true; + } + + /** + * Cast the stream to return the underlying file resource + * + * @param int $cast_as STREAM_CAST_FOR_SELECT or STREAM_CAST_AS_STREAM + * + * @return resource + */ + public function stream_cast($cast_as) + { + return $this->body->getStream(); + } + + /** + * Get the stream context options available to the current stream + * + * @return array + */ + protected function getOptions() + { + $context = $this->context ?: stream_context_get_default(); + $options = stream_context_get_options($context); + + return isset($options['s3']) ? $options['s3'] : array(); + } + + /** + * Get a specific stream context option + * + * @param string $name Name of the option to retrieve + * + * @return mixed|null + */ + protected function getOption($name) + { + $options = $this->getOptions(); + + return isset($options[$name]) ? $options[$name] : null; + } + + /** + * Get the bucket and key from the passed path (e.g. s3://bucket/key) + * + * @param string $path Path passed to the stream wrapper + * + * @return array Hash of 'Bucket', 'Key', and custom params + */ + protected function getParams($path) + { + $parts = explode('/', substr($path, 5), 2); + + $params = $this->getOptions(); + unset($params['seekable']); + + return array( + 'Bucket' => $parts[0], + 'Key' => isset($parts[1]) ? $parts[1] : null + ) + $params; + } + + /** + * Serialize and sign a command, returning a request object + * + * @param CommandInterface $command Command to sign + * + * @return RequestInterface + */ + protected function getSignedRequest($command) + { + $request = $command->prepare(); + $request->dispatch('request.before_send', array('request' => $request)); + + return $request; + } + + /** + * Initialize the stream wrapper for a read only stream + * + * @param array $params Operation parameters + * @param array $errors Any encountered errors to append to + * + * @return bool + */ + protected function openReadStream(array $params, array &$errors) + { + // Create the command and serialize the request + $request = $this->getSignedRequest(static::$client->getCommand('GetObject', $params)); + // Create a stream that uses the EntityBody object + $factory = $this->getOption('stream_factory') ?: new PhpStreamRequestFactory(); + $this->body = $factory->fromRequest($request, array(), array('stream_class' => 'Guzzle\Http\EntityBody')); + + // Headers are placed in the "wrapper_data" array. The array of headers + // is simply an array of header lines of which the first line is the + // status line of the HTTP response. + $headers = $this->body->getMetaData('wrapper_data'); + + if ($headers && isset($headers[0])) { + $statusParts = explode(' ', $headers[0]); + $status = $statusParts[1]; + if ($status != 200) { + return $this->triggerError('Cannot open file: ' . $this->body); + } + } + + // Wrap the body in a caching entity body if seeking is allowed + if ($this->getOption('seekable')) { + $this->body = new CachingEntityBody($this->body); + } + + return true; + } + + /** + * Initialize the stream wrapper for a write only stream + * + * @param array $params Operation parameters + * @param array $errors Any encountered errors to append to + * + * @return bool + */ + protected function openWriteStream(array $params, array &$errors) + { + $this->body = new EntityBody(fopen('php://temp', 'r+')); + + return true; + } + + /** + * Initialize the stream wrapper for an append stream + * + * @param array $params Operation parameters + * @param array $errors Any encountered errors to append to + * + * @return bool + */ + protected function openAppendStream(array $params, array &$errors) + { + try { + // Get the body of the object + $this->body = static::$client->getObject($params)->get('Body'); + $this->body->seek(0, SEEK_END); + } catch (S3Exception $e) { + // The object does not exist, so use a simple write stream + $this->openWriteStream($params, $errors); + } + + return true; + } + + /** + * Trigger one or more errors + * + * @param string|array $errors Errors to trigger + * @param mixed $flags If set to STREAM_URL_STAT_QUIET, then no error or exception occurs + * + * @return bool Returns false + * @throws RuntimeException if throw_errors is true + */ + protected function triggerError($errors, $flags = null) + { + if ($flags & STREAM_URL_STAT_QUIET) { + // This is triggered with things like file_exists() + + if ($flags & STREAM_URL_STAT_LINK) { + // This is triggered for things like is_link() + return $this->formatUrlStat(false); + } + return false; + } + + // This is triggered when doing things like lstat() or stat() + trigger_error(implode("\n", (array) $errors), E_USER_WARNING); + + return false; + } + + /** + * Prepare a url_stat result array + * + * @param string|array $result Data to add + * + * @return array Returns the modified url_stat result + */ + protected function formatUrlStat($result = null) + { + static $statTemplate = array( + 0 => 0, 'dev' => 0, + 1 => 0, 'ino' => 0, + 2 => 0, 'mode' => 0, + 3 => 0, 'nlink' => 0, + 4 => 0, 'uid' => 0, + 5 => 0, 'gid' => 0, + 6 => -1, 'rdev' => -1, + 7 => 0, 'size' => 0, + 8 => 0, 'atime' => 0, + 9 => 0, 'mtime' => 0, + 10 => 0, 'ctime' => 0, + 11 => -1, 'blksize' => -1, + 12 => -1, 'blocks' => -1, + ); + + $stat = $statTemplate; + $type = gettype($result); + + // Determine what type of data is being cached + if ($type == 'NULL' || $type == 'string') { + // Directory with 0777 access - see "man 2 stat". + $stat['mode'] = $stat[2] = 0040777; + } elseif ($type == 'array' && isset($result['LastModified'])) { + // ListObjects or HeadObject result + $stat['mtime'] = $stat[9] = $stat['ctime'] = $stat[10] = strtotime($result['LastModified']); + $stat['size'] = $stat[7] = (isset($result['ContentLength']) ? $result['ContentLength'] : $result['Size']); + // Regular file with 0777 access - see "man 2 stat". + $stat['mode'] = $stat[2] = 0100777; + } + + return $stat; + } + + /** + * Clear the next stat result from the cache + * + * @param string $path If a path is specific, clearstatcache() will be called + */ + protected function clearStatInfo($path = null) + { + static::$nextStat = array(); + if ($path) { + clearstatcache(true, $path); + } + } + + /** + * Creates a bucket for the given parameters. + * + * @param string $path Stream wrapper path + * @param array $params A result of StreamWrapper::getParams() + * + * @return bool Returns true on success or false on failure + */ + private function createBucket($path, array $params) + { + if (static::$client->doesBucketExist($params['Bucket'])) { + return $this->triggerError("Directory already exists: {$path}"); + } + + try { + static::$client->createBucket($params); + $this->clearStatInfo($path); + return true; + } catch (\Exception $e) { + return $this->triggerError($e->getMessage()); + } + } + + /** + * Creates a pseudo-folder by creating an empty "/" suffixed key + * + * @param string $path Stream wrapper path + * @param array $params A result of StreamWrapper::getParams() + * + * @return bool + */ + private function createPseudoDirectory($path, array $params) + { + // Ensure the path ends in "/" and the body is empty. + $params['Key'] = rtrim($params['Key'], '/') . '/'; + $params['Body'] = ''; + + // Fail if this pseudo directory key already exists + if (static::$client->doesObjectExist($params['Bucket'], $params['Key'])) { + return $this->triggerError("Directory already exists: {$path}"); + } + + try { + static::$client->putObject($params); + $this->clearStatInfo($path); + return true; + } catch (\Exception $e) { + return $this->triggerError($e->getMessage()); + } + } + + /** + * Determine the most appropriate ACL based on a file mode. + * + * @param int $mode File mode + * + * @return string + */ + private function determineAcl($mode) + { + $mode = decoct($mode); + + if ($mode >= 700 && $mode <= 799) { + return 'public-read'; + } + + if ($mode >= 600 && $mode <= 699) { + return 'authenticated-read'; + } + + return 'private'; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Sync/AbstractSync.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Sync/AbstractSync.php new file mode 100644 index 0000000..ac5bbbe --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Sync/AbstractSync.php @@ -0,0 +1,127 @@ +options = Collection::fromConfig( + $options, + array('concurrency' => 10), + array('client', 'bucket', 'iterator', 'source_converter') + ); + $this->init(); + } + + public static function getAllEvents() + { + return array(self::BEFORE_TRANSFER, self::AFTER_TRANSFER); + } + + /** + * Begin transferring files + */ + public function transfer() + { + // Pull out chunks of uploads to upload in parallel + $iterator = new ChunkedIterator($this->options['iterator'], $this->options['concurrency']); + foreach ($iterator as $files) { + $this->transferFiles($files); + } + } + + /** + * Create a command or special transfer action for the + * + * @param \SplFileInfo $file File used to build the transfer + * + * @return CommandInterface|callable + */ + abstract protected function createTransferAction(\SplFileInfo $file); + + /** + * Hook to initialize subclasses + * @codeCoverageIgnore + */ + protected function init() {} + + /** + * Process and transfer a group of files + * + * @param array $files Files to transfer + */ + protected function transferFiles(array $files) + { + // Create the base event data object + $event = array('sync' => $this, 'client' => $this->options['client']); + + $commands = array(); + foreach ($files as $file) { + if ($action = $this->createTransferAction($file)) { + $event = array('command' => $action, 'file' => $file) + $event; + $this->dispatch(self::BEFORE_TRANSFER, $event); + if ($action instanceof CommandInterface) { + $commands[] = $action; + } elseif (is_callable($action)) { + $action(); + $this->dispatch(self::AFTER_TRANSFER, $event); + } + } + } + + $this->transferCommands($commands); + } + + /** + * Transfer an array of commands in parallel + * + * @param array $commands Commands to transfer + */ + protected function transferCommands(array $commands) + { + if ($commands) { + $this->options['client']->execute($commands); + // Notify listeners that each command finished + $event = array('sync' => $this, 'client' => $this->options['client']); + foreach ($commands as $command) { + $event['command'] = $command; + $this->dispatch(self::AFTER_TRANSFER, $event); + } + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Sync/AbstractSyncBuilder.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Sync/AbstractSyncBuilder.php new file mode 100644 index 0000000..1308c3d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Sync/AbstractSyncBuilder.php @@ -0,0 +1,434 @@ +bucket = $bucket; + + return $this; + } + + /** + * Set the Amazon S3 client object that will send requests + * + * @param S3Client $client Amazon S3 client + * + * @return $this + */ + public function setClient(S3Client $client) + { + $this->client = $client; + + return $this; + } + + /** + * Set a custom iterator that returns \SplFileInfo objects for the source data + * + * @param \Iterator $iterator + * + * @return $this + */ + public function setSourceIterator(\Iterator $iterator) + { + $this->sourceIterator = $iterator; + + return $this; + } + + /** + * Set a custom object key provider instead of building one internally + * + * @param FileNameConverterInterface $converter Filename to object key provider + * + * @return $this + */ + public function setSourceFilenameConverter(FilenameConverterInterface $converter) + { + $this->sourceConverter = $converter; + + return $this; + } + + /** + * Set a custom object key provider instead of building one internally + * + * @param FileNameConverterInterface $converter Filename to object key provider + * + * @return $this + */ + public function setTargetFilenameConverter(FilenameConverterInterface $converter) + { + $this->targetConverter = $converter; + + return $this; + } + + /** + * Set the base directory of the files being transferred. The base directory is removed from each file path before + * converting the file path to an object key or vice versa. + * + * @param string $baseDir Base directory, which will be deleted from each uploaded object key + * + * @return $this + */ + public function setBaseDir($baseDir) + { + $this->baseDir = $baseDir; + + return $this; + } + + /** + * Specify a prefix to prepend to each Amazon S3 object key or the prefix where object are stored in a bucket + * + * Can be used to upload files to a pseudo sub-folder key or only download files from a pseudo sub-folder + * + * @param string $keyPrefix Prefix for each uploaded key + * + * @return $this + */ + public function setKeyPrefix($keyPrefix) + { + // Removing leading slash + $this->keyPrefix = ltrim($keyPrefix, '/'); + + return $this; + } + + /** + * Specify the delimiter used for the targeted filesystem (default delimiter is "/") + * + * @param string $delimiter Delimiter to use to separate paths + * + * @return $this + */ + public function setDelimiter($delimiter) + { + $this->delimiter = $delimiter; + + return $this; + } + + /** + * Specify an array of operation parameters to apply to each operation executed by the sync object + * + * @param array $params Associative array of PutObject (upload) GetObject (download) parameters + * + * @return $this + */ + public function setOperationParams(array $params) + { + $this->params = $params; + + return $this; + } + + /** + * Set the number of files that can be transferred concurrently + * + * @param int $concurrency Number of concurrent transfers + * + * @return $this + */ + public function setConcurrency($concurrency) + { + $this->concurrency = $concurrency; + + return $this; + } + + /** + * Set to true to force transfers even if a file already exists and has not changed + * + * @param bool $force Set to true to force transfers without checking if it has changed + * + * @return $this + */ + public function force($force = false) + { + $this->forcing = (bool) $force; + + return $this; + } + + /** + * Enable debug mode + * + * @param bool|resource $enabledOrResource Set to true or false to enable or disable debug output. Pass an opened + * fopen resource to write to instead of writing to standard out. + * @return $this + */ + public function enableDebugOutput($enabledOrResource = true) + { + $this->debug = $enabledOrResource; + + return $this; + } + + /** + * Add a filename filter that uses a regular expression to filter out files that you do not wish to transfer. + * + * @param string $search Regular expression search (in preg_match format). Any filename that matches this regex + * will not be transferred. + * @return $this + */ + public function addRegexFilter($search) + { + $this->assertFileIteratorSet(); + $this->sourceIterator = new FilterIterator($this->sourceIterator, function ($i) use ($search) { + return !preg_match($search, (string) $i); + }); + $this->sourceIterator->rewind(); + + return $this; + } + + /** + * Builds a UploadSync or DownloadSync object + * + * @return AbstractSync + */ + public function build() + { + $this->validateRequirements(); + $this->sourceConverter = $this->sourceConverter ?: $this->getDefaultSourceConverter(); + $this->targetConverter = $this->targetConverter ?: $this->getDefaultTargetConverter(); + + // Only wrap the source iterator in a changed files iterator if we are not forcing the transfers + if (!$this->forcing) { + $this->sourceIterator->rewind(); + $this->sourceIterator = new ChangedFilesIterator( + new \NoRewindIterator($this->sourceIterator), + $this->getTargetIterator(), + $this->sourceConverter, + $this->targetConverter + ); + $this->sourceIterator->rewind(); + } + + $sync = $this->specificBuild(); + + if ($this->params) { + $this->addCustomParamListener($sync); + } + + if ($this->debug) { + $this->addDebugListener($sync, is_bool($this->debug) ? STDOUT : $this->debug); + } + + return $sync; + } + + /** + * Hook to implement in subclasses + * + * @return AbstractSync + */ + abstract protected function specificBuild(); + + /** + * @return \Iterator + */ + abstract protected function getTargetIterator(); + + /** + * @return FilenameConverterInterface + */ + abstract protected function getDefaultSourceConverter(); + + /** + * @return FilenameConverterInterface + */ + abstract protected function getDefaultTargetConverter(); + + /** + * Add a listener to the sync object to output debug information while transferring + * + * @param AbstractSync $sync Sync object to listen to + * @param resource $resource Where to write debug messages + */ + abstract protected function addDebugListener(AbstractSync $sync, $resource); + + /** + * Validate that the builder has the minimal requirements + * + * @throws RuntimeException if the builder is not configured completely + */ + protected function validateRequirements() + { + if (!$this->client) { + throw new RuntimeException('No client was provided'); + } + if (!$this->bucket) { + throw new RuntimeException('No bucket was provided'); + } + $this->assertFileIteratorSet(); + } + + /** + * Ensure that the base file iterator has been provided + * + * @throws RuntimeException + */ + protected function assertFileIteratorSet() + { + // Interesting... Need to use isset because: Object of class GlobIterator could not be converted to boolean + if (!isset($this->sourceIterator)) { + throw new RuntimeException('A source file iterator must be specified'); + } + } + + /** + * Wraps a generated iterator in a filter iterator that removes directories + * + * @param \Iterator $iterator Iterator to wrap + * + * @return \Iterator + * @throws UnexpectedValueException + */ + protected function filterIterator(\Iterator $iterator) + { + $f = new FilterIterator($iterator, function ($i) { + if (!$i instanceof \SplFileInfo) { + throw new UnexpectedValueException('All iterators for UploadSync must return SplFileInfo objects'); + } + return $i->isFile(); + }); + + $f->rewind(); + + return $f; + } + + /** + * Add the custom param listener to a transfer object + * + * @param HasDispatcherInterface $sync + */ + protected function addCustomParamListener(HasDispatcherInterface $sync) + { + $params = $this->params; + $sync->getEventDispatcher()->addListener( + UploadSync::BEFORE_TRANSFER, + function (Event $e) use ($params) { + if ($e['command'] instanceof CommandInterface) { + $e['command']->overwriteWith($params); + } + } + ); + } + + /** + * Create an Amazon S3 file iterator based on the given builder settings + * + * @return OpendirIterator + */ + protected function createS3Iterator() + { + // Ensure that the stream wrapper is registered + $this->client->registerStreamWrapper(); + + // Calculate the opendir() bucket and optional key prefix location + $dir = "s3://{$this->bucket}"; + if ($this->keyPrefix) { + $dir .= '/' . ltrim($this->keyPrefix, '/ '); + } + + // Use opendir so that we can pass stream context to the iterator + $dh = opendir($dir, stream_context_create(array( + 's3' => array( + 'delimiter' => '', + 'listFilter' => function ($obj) { + // Ensure that we do not try to download a glacier object. + return !isset($obj['StorageClass']) || + $obj['StorageClass'] != 'GLACIER'; + } + ) + ))); + + // Add the trailing slash for the OpendirIterator concatenation + if (!$this->keyPrefix) { + $dir .= '/'; + } + + return $this->filterIterator(new \NoRewindIterator(new OpendirIterator($dh, $dir))); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Sync/ChangedFilesIterator.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Sync/ChangedFilesIterator.php new file mode 100644 index 0000000..dc3e07c --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Sync/ChangedFilesIterator.php @@ -0,0 +1,130 @@ +targetIterator = $targetIterator; + $this->sourceConverter = $sourceConverter; + $this->targetConverter = $targetConverter; + parent::__construct($sourceIterator); + } + + public function accept() + { + $current = $this->current(); + $key = $this->sourceConverter->convert($this->normalize($current)); + + if (!($data = $this->getTargetData($key))) { + return true; + } + + // Ensure the Content-Length matches and it hasn't been modified since the mtime + return $current->getSize() != $data[0] || $current->getMTime() > $data[1]; + } + + /** + * Returns an array of the files from the target iterator that were not found in the source iterator + * + * @return array + */ + public function getUnmatched() + { + return array_keys($this->cache); + } + + /** + * Get key information from the target iterator for a particular filename + * + * @param string $key Target iterator filename + * + * @return array|bool Returns an array of data, or false if the key is not in the iterator + */ + protected function getTargetData($key) + { + $key = $this->cleanKey($key); + + if (isset($this->cache[$key])) { + $result = $this->cache[$key]; + unset($this->cache[$key]); + return $result; + } + + $it = $this->targetIterator; + + while ($it->valid()) { + $value = $it->current(); + $data = array($value->getSize(), $value->getMTime()); + $filename = $this->targetConverter->convert($this->normalize($value)); + $filename = $this->cleanKey($filename); + + if ($filename == $key) { + return $data; + } + + $this->cache[$filename] = $data; + $it->next(); + } + + return false; + } + + private function normalize($current) + { + $asString = (string) $current; + + return strpos($asString, 's3://') === 0 + ? $asString + : $current->getRealPath(); + } + + private function cleanKey($key) + { + return ltrim($key, '/'); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Sync/DownloadSync.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Sync/DownloadSync.php new file mode 100644 index 0000000..560ccdf --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Sync/DownloadSync.php @@ -0,0 +1,95 @@ +getPathname(); + list($bucket, $key) = explode('/', substr($sourceFilename, 5), 2); + $filename = $this->options['source_converter']->convert($sourceFilename); + $this->createDirectory($filename); + + // Some S3 buckets contains nested files under the same name as a directory + if (is_dir($filename)) { + return false; + } + + // Allow a previously interrupted download to resume + if (file_exists($filename) && $this->options['resumable']) { + return new ResumableDownload($this->options['client'], $bucket, $key, $filename); + } + + return $this->options['client']->getCommand('GetObject', array( + 'Bucket' => $bucket, + 'Key' => $key, + 'SaveAs' => $filename + )); + } + + /** + * @codeCoverageIgnore + */ + protected function createDirectory($filename) + { + $directory = dirname($filename); + // Some S3 clients create empty files to denote directories. Remove these so that we can create the directory. + if (is_file($directory) && filesize($directory) == 0) { + unlink($directory); + } + // Create the directory if it does not exist + if (!is_dir($directory) && !mkdir($directory, 0777, true)) { + $errors = error_get_last(); + throw new RuntimeException('Could not create directory: ' . $directory . ' - ' . $errors['message']); + } + } + + protected function filterCommands(array $commands) + { + // Build a list of all of the directories in each command so that we don't attempt to create an empty dir in + // the same parallel transfer as attempting to create a file in that dir + $dirs = array(); + foreach ($commands as $command) { + $parts = array_values(array_filter(explode('/', $command['SaveAs']))); + for ($i = 0, $total = count($parts); $i < $total; $i++) { + $dir = ''; + for ($j = 0; $j < $i; $j++) { + $dir .= '/' . $parts[$j]; + } + if ($dir && !in_array($dir, $dirs)) { + $dirs[] = $dir; + } + } + } + + return array_filter($commands, function ($command) use ($dirs) { + return !in_array($command['SaveAs'], $dirs); + }); + } + + protected function transferCommands(array $commands) + { + parent::transferCommands($this->filterCommands($commands)); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Sync/DownloadSyncBuilder.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Sync/DownloadSyncBuilder.php new file mode 100644 index 0000000..d9cd044 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Sync/DownloadSyncBuilder.php @@ -0,0 +1,129 @@ +directory = $directory; + + return $this; + } + + /** + * Call this function to allow partial downloads to be resumed if the download was previously interrupted + * + * @return self + */ + public function allowResumableDownloads() + { + $this->resumable = true; + + return $this; + } + + protected function specificBuild() + { + $sync = new DownloadSync(array( + 'client' => $this->client, + 'bucket' => $this->bucket, + 'iterator' => $this->sourceIterator, + 'source_converter' => $this->sourceConverter, + 'target_converter' => $this->targetConverter, + 'concurrency' => $this->concurrency, + 'resumable' => $this->resumable, + 'directory' => $this->directory + )); + + return $sync; + } + + protected function getTargetIterator() + { + if (!$this->directory) { + throw new RuntimeException('A directory is required'); + } + + if (!is_dir($this->directory) && !mkdir($this->directory, 0777, true)) { + // @codeCoverageIgnoreStart + throw new RuntimeException('Unable to create root download directory: ' . $this->directory); + // @codeCoverageIgnoreEnd + } + + return $this->filterIterator( + new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->directory)) + ); + } + + protected function getDefaultSourceConverter() + { + return new KeyConverter( + "s3://{$this->bucket}/{$this->baseDir}", + $this->directory . DIRECTORY_SEPARATOR, $this->delimiter + ); + } + + protected function getDefaultTargetConverter() + { + return new KeyConverter("s3://{$this->bucket}/{$this->baseDir}", '', $this->delimiter); + } + + protected function assertFileIteratorSet() + { + $this->sourceIterator = $this->sourceIterator ?: $this->createS3Iterator(); + } + + protected function addDebugListener(AbstractSync $sync, $resource) + { + $sync->getEventDispatcher()->addListener(UploadSync::BEFORE_TRANSFER, function (Event $e) use ($resource) { + if ($e['command'] instanceof CommandInterface) { + $from = $e['command']['Bucket'] . '/' . $e['command']['Key']; + $to = $e['command']['SaveAs'] instanceof EntityBodyInterface + ? $e['command']['SaveAs']->getUri() + : $e['command']['SaveAs']; + fwrite($resource, "Downloading {$from} -> {$to}\n"); + } elseif ($e['command'] instanceof ResumableDownload) { + $from = $e['command']->getBucket() . '/' . $e['command']->getKey(); + $to = $e['command']->getFilename(); + fwrite($resource, "Resuming {$from} -> {$to}\n"); + } + }); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Sync/FilenameConverterInterface.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Sync/FilenameConverterInterface.php new file mode 100644 index 0000000..ded2cfb --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Sync/FilenameConverterInterface.php @@ -0,0 +1,32 @@ +baseDir = (string) $baseDir; + $this->prefix = $prefix; + $this->delimiter = $delimiter; + } + + public function convert($filename) + { + $key = $filename; + + // Remove base directory from the key (only the first occurrence) + if ($this->baseDir && (false !== $pos = strpos($filename, $this->baseDir))) { + $key = substr_replace($key, '', $pos, strlen($this->baseDir)); + } + + // Replace Windows directory separators to become Unix style, and convert that to the custom dir separator + $key = str_replace('/', $this->delimiter, str_replace('\\', '/', $key)); + + // Add the key prefix and remove double slashes that are not in the protocol (e.g. prefixed with ":") + $delim = preg_quote($this->delimiter); + $key = preg_replace( + "#(?delimiter, + $this->prefix . $key + ); + + return $key; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Sync/UploadSync.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Sync/UploadSync.php new file mode 100644 index 0000000..31b81e6 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Sync/UploadSync.php @@ -0,0 +1,86 @@ +options['multipart_upload_size']) { + $this->options['multipart_upload_size'] = AbstractTransfer::MIN_PART_SIZE; + } + } + + protected function createTransferAction(\SplFileInfo $file) + { + // Open the file for reading + $filename = $file->getRealPath() ?: $file->getPathName(); + + if (!($resource = fopen($filename, 'r'))) { + // @codeCoverageIgnoreStart + throw new RuntimeException('Could not open ' . $file->getPathname() . ' for reading'); + // @codeCoverageIgnoreEnd + } + + $key = $this->options['source_converter']->convert($filename); + $body = EntityBody::factory($resource); + + // Determine how the ACL should be applied + if ($acl = $this->options['acl']) { + $aclType = is_string($this->options['acl']) ? 'ACL' : 'ACP'; + } else { + $acl = 'private'; + $aclType = 'ACL'; + } + + // Use a multi-part upload if the file is larger than the cutoff size and is a regular file + if ($body->getWrapper() == 'plainfile' && $file->getSize() >= $this->options['multipart_upload_size']) { + $builder = UploadBuilder::newInstance() + ->setBucket($this->options['bucket']) + ->setKey($key) + ->setMinPartSize($this->options['multipart_upload_size']) + ->setOption($aclType, $acl) + ->setClient($this->options['client']) + ->setSource($body) + ->setConcurrency($this->options['concurrency']); + + $this->dispatch( + self::BEFORE_MULTIPART_BUILD, + array('builder' => $builder, 'file' => $file) + ); + + return $builder->build(); + } + + return $this->options['client']->getCommand('PutObject', array( + 'Bucket' => $this->options['bucket'], + 'Key' => $key, + 'Body' => $body, + $aclType => $acl + )); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Sync/UploadSyncBuilder.php b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Sync/UploadSyncBuilder.php new file mode 100644 index 0000000..8f7907c --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/aws/aws-sdk-php/src/Aws/S3/Sync/UploadSyncBuilder.php @@ -0,0 +1,190 @@ +baseDir = realpath($path); + $this->sourceIterator = $this->filterIterator(new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator( + $path, + FI::SKIP_DOTS | FI::UNIX_PATHS | FI::FOLLOW_SYMLINKS + ))); + + return $this; + } + + /** + * Set a glob expression that will match files to upload to Amazon S3 + * + * @param string $glob Glob expression + * + * @return $this + * @link http://www.php.net/manual/en/function.glob.php + */ + public function uploadFromGlob($glob) + { + $this->sourceIterator = $this->filterIterator( + new \GlobIterator($glob, FI::SKIP_DOTS | FI::UNIX_PATHS | FI::FOLLOW_SYMLINKS) + ); + + return $this; + } + + /** + * Set a canned ACL to apply to each uploaded object + * + * @param string $acl Canned ACL for each upload + * + * @return $this + */ + public function setAcl($acl) + { + $this->acp = $acl; + + return $this; + } + + /** + * Set an Access Control Policy to apply to each uploaded object + * + * @param Acp $acp Access control policy + * + * @return $this + */ + public function setAcp(Acp $acp) + { + $this->acp = $acp; + + return $this; + } + + /** + * Set the multipart upload size threshold. When the size of a file exceeds this value, the file will be uploaded + * using a multipart upload. + * + * @param int $size Size threshold + * + * @return $this + */ + public function setMultipartUploadSize($size) + { + $this->multipartUploadSize = $size; + + return $this; + } + + protected function specificBuild() + { + $sync = new UploadSync(array( + 'client' => $this->client, + 'bucket' => $this->bucket, + 'iterator' => $this->sourceIterator, + 'source_converter' => $this->sourceConverter, + 'target_converter' => $this->targetConverter, + 'concurrency' => $this->concurrency, + 'multipart_upload_size' => $this->multipartUploadSize, + 'acl' => $this->acp + )); + + return $sync; + } + + protected function addCustomParamListener(HasDispatcherInterface $sync) + { + // Handle the special multi-part upload event + parent::addCustomParamListener($sync); + $params = $this->params; + $sync->getEventDispatcher()->addListener( + UploadSync::BEFORE_MULTIPART_BUILD, + function (Event $e) use ($params) { + foreach ($params as $k => $v) { + $e['builder']->setOption($k, $v); + } + } + ); + } + + protected function getTargetIterator() + { + return $this->createS3Iterator(); + } + + protected function getDefaultSourceConverter() + { + return new KeyConverter($this->baseDir, $this->keyPrefix . $this->delimiter, $this->delimiter); + } + + protected function getDefaultTargetConverter() + { + return new KeyConverter('s3://' . $this->bucket . '/', '', DIRECTORY_SEPARATOR); + } + + protected function addDebugListener(AbstractSync $sync, $resource) + { + $sync->getEventDispatcher()->addListener(UploadSync::BEFORE_TRANSFER, function (Event $e) use ($resource) { + + $c = $e['command']; + + if ($c instanceof CommandInterface) { + $uri = $c['Body']->getUri(); + $size = $c['Body']->getSize(); + fwrite($resource, "Uploading {$uri} -> {$c['Key']} ({$size} bytes)\n"); + return; + } + + // Multipart upload + $body = $c->getSource(); + $totalSize = $body->getSize(); + $progress = 0; + fwrite($resource, "Beginning multipart upload: " . $body->getUri() . ' -> '); + fwrite($resource, $c->getState()->getFromId('Key') . " ({$totalSize} bytes)\n"); + + $c->getEventDispatcher()->addListener( + AbstractTransfer::BEFORE_PART_UPLOAD, + function ($e) use (&$progress, $totalSize, $resource) { + $command = $e['command']; + $size = $command['Body']->getContentLength(); + $percentage = number_format(($progress / $totalSize) * 100, 2); + fwrite($resource, "- Part {$command['PartNumber']} ({$size} bytes, {$percentage}%)\n"); + $progress += $size; + } + ); + }); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/config.template.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/config.template.php new file mode 100644 index 0000000..086dca9 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/config.template.php @@ -0,0 +1,175 @@ + 'default', + 'tags' => '.ckfinder/tags', + 'logs' => '.ckfinder/logs', + 'cache' => '.ckfinder/cache', + 'thumbs' => '.ckfinder/cache/thumbs', +); + +/*============================ Images and Thumbnails ==================================*/ +// http://docs.cksource.com/ckfinder3-php/configuration.html#configuration_options_images + +$config['images'] = array( + 'maxWidth' => 1600, + 'maxHeight' => 1200, + 'quality' => 80, + 'sizes' => array( + 'small' => array('width' => 480, 'height' => 320, 'quality' => 80), + 'medium' => array('width' => 600, 'height' => 480, 'quality' => 80), + 'large' => array('width' => 800, 'height' => 600, 'quality' => 80) + ) +); + +/*=================================== Backends ========================================*/ +// http://docs.cksource.com/ckfinder3-php/configuration.html#configuration_options_backends + +$config['backends'][] = array( + 'name' => 'default', + 'adapter' => 'local', + 'baseUrl' => '/ckfinder/userfiles/', +// 'root' => '', // Can be used to explicitly set the CKFinder user files directory. + 'chmodFiles' => 0777, + 'chmodFolders' => 0755, + 'filesystemEncoding' => 'UTF-8', +); + +/*================================ Resource Types =====================================*/ +// http://docs.cksource.com/ckfinder3-php/configuration.html#configuration_options_resourceTypes + +$config['defaultResourceTypes'] = ''; + +$config['resourceTypes'][] = array( + 'name' => 'Files', // Single quotes not allowed. + 'directory' => 'files', + 'maxSize' => 0, + 'allowedExtensions' => '7z,aiff,asf,avi,bmp,csv,doc,docx,fla,flv,gif,gz,gzip,jpeg,jpg,mid,mov,mp3,mp4,mpc,mpeg,mpg,ods,odt,pdf,png,ppt,pptx,pxd,qt,ram,rar,rm,rmi,rmvb,rtf,sdc,sitd,swf,sxc,sxw,tar,tgz,tif,tiff,txt,vsd,wav,wma,wmv,xls,xlsx,zip', + 'deniedExtensions' => '', + 'backend' => 'default' +); + +$config['resourceTypes'][] = array( + 'name' => 'Images', + 'directory' => 'images', + 'maxSize' => 0, + 'allowedExtensions' => 'bmp,gif,jpeg,jpg,png', + 'deniedExtensions' => '', + 'backend' => 'default' +); + +/*================================ Access Control =====================================*/ +// http://docs.cksource.com/ckfinder3-php/configuration.html#configuration_options_roleSessionVar + +$config['roleSessionVar'] = 'CKFinder_UserRole'; + +// http://docs.cksource.com/ckfinder3-php/configuration.html#configuration_options_accessControl +$config['accessControl'][] = array( + 'role' => '*', + 'resourceType' => '*', + 'folder' => '/', + + 'FOLDER_VIEW' => true, + 'FOLDER_CREATE' => true, + 'FOLDER_RENAME' => true, + 'FOLDER_DELETE' => true, + + 'FILE_VIEW' => true, + 'FILE_CREATE' => true, + 'FILE_RENAME' => true, + 'FILE_DELETE' => true, + + 'IMAGE_RESIZE' => true, + 'IMAGE_RESIZE_CUSTOM' => true +); + + +/*================================ Other Settings =====================================*/ +// http://docs.cksource.com/ckfinder3-php/configuration.html + +$config['overwriteOnUpload'] = false; +$config['checkDoubleExtension'] = true; +$config['disallowUnsafeCharacters'] = false; +$config['secureImageUploads'] = true; +$config['checkSizeAfterScaling'] = true; +$config['htmlExtensions'] = array('html', 'htm', 'xml', 'js'); +$config['hideFolders'] = array('.*', 'CVS', '__thumbs'); +$config['hideFiles'] = array('.*'); +$config['forceAscii'] = false; +$config['xSendfile'] = false; + +// http://docs.cksource.com/ckfinder3-php/configuration.html#configuration_options_debug +$config['debug'] = false; + +/*==================================== Plugins ========================================*/ +// http://docs.cksource.com/ckfinder3-php/configuration.html#configuration_options_plugins + +$config['pluginsDirectory'] = __DIR__ . '/plugins'; +$config['plugins'] = array(); + +/*================================ Cache settings =====================================*/ +// http://docs.cksource.com/ckfinder3-php/configuration.html#configuration_options_cache + +$config['cache'] = array( + 'imagePreview' => 24 * 3600, + 'thumbnails' => 24 * 3600 * 365, + 'proxyCommand' => 0 +); + +/*============================ Temp Directory settings ================================*/ +// http://docs.cksource.com/ckfinder3-php/configuration.html#configuration_options_tempDirectory + +$config['tempDirectory'] = sys_get_temp_dir(); + +/*============================ Session Cause Performance Issues =======================*/ +// http://docs.cksource.com/ckfinder3-php/configuration.html#configuration_options_sessionWriteClose + +$config['sessionWriteClose'] = true; + +/*================================= CSRF protection ===================================*/ +// http://docs.cksource.com/ckfinder3-php/configuration.html#configuration_options_csrfProtection + +$config['csrfProtection'] = true; + +/*============================== End of Configuration =================================*/ + +// Config must be returned - do not change it. +return $config; diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Acl/Acl.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Acl/Acl.php new file mode 100644 index 0000000..11420cf --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Acl/Acl.php @@ -0,0 +1,275 @@ +[folderPath][role][resourceType] => MaskBuilder + * + * @var array $entries + */ + protected $rules = array(); + + /** + * @brief The role context interface. + * + * By default an instance of SessionRoleContext is used as a role context. + * You can easily add a new class that implements RoleContextInterface to + * better fit your application. + * + * @var RoleContextInterface $roleContext + */ + protected $roleContext = null; + + /** + * @brief Cache for computed masks. + * + * This array contains computed mask results to avoid double checks + * for the same path. + * + * @var array $cachedResults + */ + protected $cachedResults = array(); + + /** + * Constructor. + * + * @param RoleContextInterface $roleContext + */ + public function __construct(RoleContextInterface $roleContext) + { + $this->roleContext = $roleContext; + } + + /** + * Sets rules for Access Control Lists using configuration nodes. + * + * It is assumed that Acl configuration nodes used here have the following form: + * + * @code + * array( + * 'role' => 'foo', + * 'resourceType' => 'Images', + * 'folder' => '/bar', + * + * // Permissions + * 'FOLDER_VIEW' => true, + * 'FOLDER_CREATE' => true, + * 'FOLDER_RENAME' => true, + * 'FOLDER_DELETE' => true, + * + * 'FILE_VIEW' => true, + * 'FILE_CREATE' => true, + * 'FILE_RENAME' => true, + * 'FILE_DELETE' => true + * ) + * @endcode + * + * If any permission is missing, it is inherited from the parent folder. + * + * @param array $aclConfigNodes Access Control Lists configuration nodes + * + */ + public function setRules($aclConfigNodes) + { + foreach ($aclConfigNodes as $node) { + $role = isset($node['role']) ? $node['role'] : "*"; + + $resourceType = isset($node['resourceType']) ? $node['resourceType'] : "*"; + + $folder = isset($node['folder']) ? $node['folder'] : "/"; + + $permissions = Permission::getAll(); + + foreach ($permissions as $permissionName => $permissionValue) { + if (isset($node[$permissionName])) { + $allow = (bool) $node[$permissionName]; + + if ($allow) { + $this->allow($resourceType, $folder, $permissionValue, $role); + } else { + $this->disallow($resourceType, $folder, $permissionValue, $role); + } + } + } + } + } + + /** + * Allows a permission for a given role. + * + * @param string $resourceType + * @param string $folderPath + * @param int $permission + * @param string $role + * + * @return $this|Acl + */ + public function allow($resourceType, $folderPath, $permission, $role) + { + $folderPath = Path::normalize($folderPath); + + if (!isset($this->rules[$folderPath][$role][$resourceType])) { + $this->rules[$folderPath][$role][$resourceType] = new MaskBuilder(); + } + + /* @var $ruleMask MaskBuilder */ + $ruleMask = $this->rules[$folderPath][$role][$resourceType]; + + $ruleMask->allow($permission); + + return $this; + } + + /** + * Disallows a permission for a given role. + * + * @param string $resourceType + * @param string $folderPath + * @param int $permission + * @param string $role + * + * @return $this|Acl + */ + public function disallow($resourceType, $folderPath, $permission, $role) + { + $folderPath = Path::normalize($folderPath); + + if (!isset($this->rules[$folderPath][$role][$resourceType])) { + $this->rules[$folderPath][$role][$resourceType] = new MaskBuilder(); + } + + /* @var $ruleMask MaskBuilder */ + $ruleMask = $this->rules[$folderPath][$role][$resourceType]; + + $ruleMask->disallow($permission); + + return $this; + } + + /** + * Checks if a given role has a permission. + * + * @param string $resourceType + * @param string $folderPath + * @param int $permission + * @param string|null $role + * + * @return bool + */ + public function isAllowed($resourceType, $folderPath, $permission, $role = null) + { + $mask = $this->getComputedMask($resourceType, $folderPath, $role); + + return ($mask & $permission) === $permission; + } + + /** + * Returns a computed mask. + * + * @param string $resourceType + * @param string $folderPath + * @param string|null $role + * + * @return int + */ + public function getComputedMask($resourceType, $folderPath, $role = null) + { + $computedMask = 0; + + $role = $role ?: $this->roleContext->getRole(); + + $folderPath = trim($folderPath, "/"); + + if (isset($this->cachedResults[$resourceType][$folderPath])) { + return $this->cachedResults[$resourceType][$folderPath]; + } + + $pathParts = explode("/", $folderPath); + + $currentPath = "/"; + + $pathPartsCount = count($pathParts); + + for ($i = -1; $i < $pathPartsCount; $i++) { + if ($i >= 0) { + if (!strlen($pathParts[$i])) { + continue; + } + + if (array_key_exists($currentPath . '*/', $this->rules)) { + $computedMask = $this->mergePathComputedMask($computedMask, $resourceType, $role, $currentPath . '*/'); + } + + $currentPath .= $pathParts[$i] . '/'; + } + + if (array_key_exists($currentPath, $this->rules)) { + $computedMask = $this->mergePathComputedMask($computedMask, $resourceType, $role, $currentPath); + } + } + + $this->cachedResults[$resourceType][$folderPath] = $computedMask; + + return $computedMask; + } + + /** + * Merges permission masks to allow permission inheritance from parent folders. + * + * @param int $currentMask the current mask numeric value + * @param string $resourceType the resource type identifier + * @param string $role the user role name + * @param string $folderPath the folder path + * + * @return int computed mask numeric value + */ + protected function mergePathComputedMask($currentMask, $resourceType, $role, $folderPath) + { + $folderRules = $this->rules[$folderPath]; + + $possibleRules = array( + array('*', '*'), + array('*', $resourceType), + array($role, '*'), + array($role, $resourceType), + ); + + foreach ($possibleRules as $rule) { + list($role, $resourceType) = $rule; + + if (isset($folderRules[$role][$resourceType])) { + /* @var $ruleMask MaskBuilder */ + $ruleMask = $folderRules[$role][$resourceType]; + + $currentMask = $ruleMask->mergeRules($currentMask); + } + } + + return $currentMask; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Acl/AclInterface.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Acl/AclInterface.php new file mode 100644 index 0000000..6b133cc --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Acl/AclInterface.php @@ -0,0 +1,78 @@ +maskAllowed |= $permission; + + return $this; + } + + /** + * Enables the permission bit in the mask for disallowed permissions. + * + * @param int $permission permission numeric value + * + * @see Permission + * + * @return MaskBuilder $this + */ + public function disallow($permission) + { + $this->maskDisallowed |= $permission; + + return $this; + } + + /** + * Merges mask permission rules to input mask numeric value. + * + * Modifies input mask numeric value to enable bits set in $maskAllowed + * and disable bits set in $maskDisallowed. + * + * @param int $inputMask mask numeric value + * + * @return int computed mask value + * + * @see Acl::getComputedMask() + */ + public function mergeRules($inputMask) + { + $inputMask |= $this->maskAllowed; + $inputMask &= ~$this->maskDisallowed; + + return $inputMask; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Acl/Permission.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Acl/Permission.php new file mode 100644 index 0000000..a2ce160 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Acl/Permission.php @@ -0,0 +1,74 @@ + value + */ + public static function getAll() + { + $ref = new \ReflectionClass(__CLASS__); + + return $ref->getConstants(); + } + + /** + * Returns a numeric value for the passed permission name. + * + * @param string $name permission constant name + * + * @return int permission value + * + * @throws \InvalidArgumentException when the permission with a given name was not found. + */ + public static function byName($name) + { + $formattedName = sprintf('static::%s', strtoupper($name)); + + if (!defined($formattedName)) { + throw new \InvalidArgumentException(sprintf('The permission "%s" doesn\'t exist', $name)); + } + + return constant($formattedName); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Acl/User/RoleContextInterface.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Acl/User/RoleContextInterface.php new file mode 100644 index 0000000..7a0c272 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Acl/User/RoleContextInterface.php @@ -0,0 +1,34 @@ +sessionRoleField = $sessionRoleField; + } + + /** + * Returns the role name of the current user. + * + * @return null|string + */ + public function getRole() + { + if (strlen($this->sessionRoleField) && isset($_SESSION[$this->sessionRoleField])) { + return (string) $_SESSION[$this->sessionRoleField]; + } + + return null; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Authentication/AuthenticationInterface.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Authentication/AuthenticationInterface.php new file mode 100644 index 0000000..d46635e --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Authentication/AuthenticationInterface.php @@ -0,0 +1,28 @@ +authCallable = $authCallable; + } + + /** + * @return bool `true` if the current user was successfully authenticated within CKFinder. + */ + public function authenticate() + { + return call_user_func($this->authCallable); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Backend/Adapter/AwsS3.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Backend/Adapter/AwsS3.php new file mode 100644 index 0000000..e839d51 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Backend/Adapter/AwsS3.php @@ -0,0 +1,146 @@ +app = $app; + } + + /** + * Emulates changing of directory name. + * + * @param string $path + * @param string $newPath + * + * @return bool + */ + public function renameDirectory($path, $newPath) + { + $sourcePath = $this->applyPathPrefix(rtrim($path, '/') . '/'); + + $objectsIterator = $this->client->getIterator('listObjects', [ + 'Bucket' => $this->bucket, + 'Prefix' => $sourcePath, + ]); + + $objects = array_filter(iterator_to_array($objectsIterator), function ($v) { + return isset($v['Key']); + }); + + if (!empty($objects)) { + + /* @var OperationManager $operation */ + $operation = $this->app['operation']; + + $operation->start(); + + $total = count($objects); + $current = 0; + + foreach ($objects as $entry) { + $this->client->copyObject(array( + 'Bucket' => $this->bucket, + 'Key' => $this->replacePath($entry['Key'], $path, $newPath), + 'CopySource' => urlencode($this->bucket . '/' . $entry['Key']), + )); + + if ($operation->isAborted()) { + // Delete target folder in case if operation was aborted + $targetPath = $this->applyPathPrefix(rtrim($newPath, '/') . '/'); + + $this->client->deleteMatchingObjects($this->bucket, $targetPath); + + return true; + } + + $operation->updateStatus(array('total' => $total, 'current' => ++$current)); + } + + $this->client->deleteMatchingObjects($this->bucket, $sourcePath); + } + + return true; + } + + /** + * Helper method that replaces a part of the key (path). + * + * @param string $objectPath the bucket-relative object path + * @param string $path the old backend-relative path + * @param string $newPath the new backend-relative path + * + * @return string the new bucket-relative path + */ + protected function replacePath($objectPath, $path, $newPath) + { + $objectPath = $this->removePathPrefix($objectPath); + $newPath = trim($newPath, '/') . '/'; + $path = trim($path, '/') . '/'; + + return $this->applyPathPrefix($newPath . substr($objectPath, strlen($path))); + } + + /** + * Returns a direct link to a file stored on S3. + * + * @param string $path + * + * @return string + */ + public function getFileUrl($path) + { + $objectPath = $this->applyPathPrefix($path); + + return $this->client->getObjectUrl($this->bucket, $objectPath); + } + + /** + * Returns the file MIME type. + * + * @param string $path + * + * @return array|false|null|string + */ + public function getMimeType($path) + { + $ext = pathinfo($path, PATHINFO_EXTENSION); + + $mimeType = MimeType::detectByFileExtension($ext); + + return $mimeType ? array('mimetype' => $mimeType) : parent::getMimetype($path); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Backend/Adapter/Azure.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Backend/Adapter/Azure.php new file mode 100644 index 0000000..13c5ab3 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Backend/Adapter/Azure.php @@ -0,0 +1,71 @@ +applyPathPrefix(rtrim($path, '/') . '/'); + + $options = new ListBlobsOptions(); + $options->setPrefix($sourcePath); + + /** @var \WindowsAzure\Blob\Models\ListBlobsResult $listResults */ + $listResults = $this->client->listBlobs($this->container, $options); + + foreach ($listResults->getBlobs() as $blob) { + /** @var \WindowsAzure\Blob\Models\Blob $blob */ + $this->client->copyBlob( + $this->container, + $this->replacePath($blob->getName(), $path, $newPath), + $this->container, + $blob->getName() + ); + $this->client->deleteBlob($this->container, $blob->getName()); + } + + return true; + } + + /** + * Helper method that replaces a part of the key (path). + * + * @param string $objectPath the bucket-relative object path + * @param string $path the old backend-relative path + * @param string $newPath the new backend-relative path + * + * @return string the new bucket-relative path + */ + protected function replacePath($objectPath, $path, $newPath) + { + $objectPath = $this->removePathPrefix($objectPath); + $newPath = trim($newPath, '/') . '/'; + $path = trim($path, '/') . '/'; + + return $this->applyPathPrefix($newPath . substr($objectPath, strlen($path))); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Backend/Adapter/Cache/Storage/Memory.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Backend/Adapter/Cache/Storage/Memory.php new file mode 100644 index 0000000..2130731 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Backend/Adapter/Cache/Storage/Memory.php @@ -0,0 +1,36 @@ +cache[$path]['contents']) && $this->cache[$path]['contents'] !== false) { + return $this->cache[$path]; + } + + return false; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Backend/Adapter/Dropbox.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Backend/Adapter/Dropbox.php new file mode 100644 index 0000000..c89319f --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Backend/Adapter/Dropbox.php @@ -0,0 +1,63 @@ +backendConfig = $backendConfig; + + parent::__construct($client, isset($backendConfig['root']) ? $backendConfig['root'] : null); + } + + /** + * Returns a direct link to a file stored in Dropbox. + * + * @param string $path + * + * @return string + */ + public function getFileUrl($path) + { + $shareableLink = $this->client->createShareableLink($this->applyPathPrefix($path)); + + if (substr($shareableLink, -5) === '?dl=0') { + $shareableLink[strlen($shareableLink)-1] = '1'; + } + + return $shareableLink; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Backend/Adapter/EmulateRenameDirectoryInterface.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Backend/Adapter/EmulateRenameDirectoryInterface.php new file mode 100644 index 0000000..1a8b753 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Backend/Adapter/EmulateRenameDirectoryInterface.php @@ -0,0 +1,27 @@ +backendConfig = $backendConfig; + + if (!isset($backendConfig['root']) || empty($backendConfig['root'])) { + $baseUrl = $backendConfig['baseUrl']; + $baseUrl = preg_replace("|^http(s)?://[^/]+|i", "", $baseUrl); + $backendConfig['root'] = Path::combine(Utils::getRootPath(), Utils::decodeURLParts($baseUrl)); + } + + if (!is_dir($backendConfig['root'])) { + @mkdir($backendConfig['root'], $backendConfig['chmodFolders'], true); + if (!is_dir($backendConfig['root'])) { + throw new FolderNotFoundException(sprintf('The root folder of backend "%s" not found (%s)', $backendConfig['name'], $backendConfig['root'])); + } + } + + if (!is_readable($backendConfig['root'])) { + throw new AccessDeniedException(sprintf('The root folder of backend "%s" is not readable (%s)', $backendConfig['name'], $backendConfig['root'])); + } + + parent::__construct($backendConfig['root']); + } + + /** + * Creates a directory. + * + * @param string $dirname + * @param FSConfig $config + * + * @return array|bool|false + * + */ + public function createDir($dirname, FSConfig $config) + { + $location = $this->applyPathPrefix($dirname); + $umask = umask(0); + + $chmodFolders = $this->backendConfig['chmodFolders']; + + if (!is_dir($location) && !mkdir($location, $chmodFolders, true)) { + $return = false; + } else { + $return = array('path' => $dirname, 'type' => 'dir'); + } + + umask($umask); + + return $return; + } + + /** + * Writes a file. + * + * @param string $path + * @param string $contents + * @param FSConfig $config + * + * @return array|bool + */ + public function write($path, $contents, FSConfig $config) + { + $location = $this->applyPathPrefix($path); + $this->ensureDirectory(dirname($location)); + + $result = parent::write($path, $contents, $config); + + $chmodFiles = $this->backendConfig['chmodFiles']; + + $oldUmask = umask(0); + chmod($location, $chmodFiles); + umask($oldUmask); + + return $result; + } + + /** + * Writes a file using stream. + * + * @param string $path + * @param resource $resource + * @param FSConfig $config + * + * @return array|bool + */ + public function writeStream($path, $resource, FSConfig $config) + { + $location = $this->applyPathPrefix($path); + $this->ensureDirectory(dirname($location)); + + $result = parent::writeStream($path, $resource, $config); + + $chmodFiles = $this->backendConfig['chmodFiles']; + + $oldUmask = umask(0); + chmod($location, $chmodFiles); + umask($oldUmask); + + return $result; + } + + /** + * Ensures that the root directory exists. + * + * @param string $root root directory path + * + * @return string real path to root + */ + protected function ensureDirectory($root) + { + if (!is_dir($root)) { + $oldUmask = umask(0); + mkdir($root, $this->backendConfig['chmodFolders'], true); + umask($oldUmask); + } + + return realpath($root); + } + + /** + * Checks whether a file or directory is present. + * + * @param string $path + * + * @return bool + */ + public function has($path) + { + $location = $this->applyPathPrefix($path); + + return is_file($location) || is_dir($location); + } + + /** + * Converts file or directory names to the file system encoding. + * + * @param string $fileName + * + * @return mixed|string + */ + public function convertToFilesystemEncoding($fileName) + { + $encoding = $this->backendConfig['filesystemEncoding']; + + if (null === $encoding || strcasecmp($encoding, "UTF-8") == 0 || strcasecmp($encoding, "UTF8") == 0) { + return $fileName; + } + + if (!function_exists("iconv")) { + if (strcasecmp($encoding, "ISO-8859-1") == 0 || strcasecmp($encoding, "ISO8859-1") == 0 || strcasecmp($encoding, "Latin1") == 0) { + return str_replace("\0", "_", utf8_decode($fileName)); + } elseif (function_exists('mb_convert_encoding')) { + /** + * @todo check whether charset is supported - mb_list_encodings + */ + $encoded = @mb_convert_encoding($fileName, $encoding, 'UTF-8'); + if (@mb_strlen($fileName, "UTF-8") != @mb_strlen($encoded, $encoding)) { + return str_replace("\0", "_", preg_replace("/[^[:ascii:]]/u", "_", $fileName)); + } else { + return str_replace("\0", "_", $encoded); + } + } else { + return str_replace("\0", "_", preg_replace("/[^[:ascii:]]/u", "_", $fileName)); + } + } + + $converted = @iconv("UTF-8", $encoding . "//IGNORE//TRANSLIT", $fileName); + if ($converted === false) { + return str_replace("\0", "_", preg_replace("/[^[:ascii:]]/u", "_", $fileName)); + } + + return $converted; + } + + /** + * Creates a stream for writing to a file. + * + * @param string $path + * + * @return resource + */ + public function createWriteStream($path) + { + $location = $this->applyPathPrefix($path); + $this->ensureDirectory(dirname($location)); + $chmodFiles = $this->backendConfig['chmodFiles']; + + if (!$stream = fopen($location, 'a+')) { + return false; + } + + $oldUmask = umask(0); + chmod($location, $chmodFiles); + umask($oldUmask); + + return $stream; + } + + /** + * Checks if the directory contains subdirectories. + * + * @param Backend $backend + * @param ResourceType $resourceType + * @param string $clientPath + * @param Acl $acl + * + * @return bool + */ + public function containsDirectories(Backend $backend, ResourceType $resourceType, $clientPath, Acl $acl) + { + $location = rtrim($this->applyPathPrefix(Path::combine($resourceType->getDirectory(), $clientPath)), '/\\') . '/'; + + if (!is_dir($location) || (false === $fh = @opendir($location))) { + return false; + } + + $hasChildren = false; + $resourceTypeName = $resourceType->getName(); + $clientPath = rtrim($clientPath, '/\\') . '/'; + + while (false !== ($filename = readdir($fh))) { + if ($filename == '.' || $filename == '..') { + continue; + } + + if (is_dir($location . $filename)) { + if (!$acl->isAllowed($resourceTypeName, $clientPath . $filename, Permission::FOLDER_VIEW)) { + continue; + } + if ($backend->isHiddenFolder($filename)) { + continue; + } + $hasChildren = true; + break; + } + } + + closedir($fh); + + return $hasChildren; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Backend/Backend.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Backend/Backend.php new file mode 100644 index 0000000..cdfa05d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Backend/Backend.php @@ -0,0 +1,467 @@ +app = $app; + $this->backendConfig = $backendConfig; + $this->acl = $app['acl']; + $this->ckConfig = $app['config']; + + parent::__construct($adapter, $filesystemConfig); + + $this->addPlugin(new GetWithMetadata()); + } + + /** + * Returns the name of the backend. + * + * @return string name of the backend + */ + public function getName() + { + return $this->backendConfig['name']; + } + + /** + * Returns an array of commands that should use operation tracking. + * + * @return array + */ + public function getTrackedOperations() + { + return isset($this->backendConfig['trackedOperations']) ? $this->backendConfig['trackedOperations'] : array(); + } + + /** + * Returns a path based on the resource type and the resource type relative path. + * + * @param ResourceType $resourceType the resource type + * @param string $path the resource type relative path + * + * @return string path to be used with the backend adapter. + */ + public function buildPath(ResourceType $resourceType, $path) + { + return Path::combine($resourceType->getDirectory(), $path); + } + + /** + * Returns a filtered list of directories for a given resource type and path. + * + * @param ResourceType $resourceType + * @param string $path + * @param bool $recursive + * + * @return array + */ + public function directories(ResourceType $resourceType, $path = '', $recursive = false) + { + $directoryPath = $this->buildPath($resourceType, $path); + $contents = $this->listContents($directoryPath, $recursive); + + foreach ($contents as &$entry) { + $entry['acl'] = $this->acl->getComputedMask($resourceType->getName(), Path::combine($path, $entry['basename'])); + } + + return array_filter($contents, function ($v) { + return isset($v['type']) && + $v['type'] === 'dir' && + !$this->isHiddenFolder($v['basename']) && + $v['acl'] & Permission::FOLDER_VIEW; + }); + } + + /** + * Returns a filtered list of files for a given resource type and path. + * + * @param ResourceType $resourceType + * @param string $path + * @param bool $recursive + * + * @return array + */ + public function files(ResourceType $resourceType, $path = '', $recursive = false) + { + $directoryPath = $this->buildPath($resourceType, $path); + $contents = $this->listContents($directoryPath, $recursive); + + return array_filter($contents, function ($v) use ($resourceType) { + return isset($v['type']) && + $v['type'] === 'file' && + !$this->isHiddenFile($v['basename']) && + $resourceType->isAllowedExtension(isset($v['extension']) ? $v['extension'] : ''); + }); + } + + /** + * Check if the directory for a given path contains subdirectories. + * + * @param ResourceType $resourceType + * @param string $path + * + * @return bool `true` if the directory contains subdirectories. + */ + public function containsDirectories(ResourceType $resourceType, $path = '') + { + $baseAdapter = $this->getBaseAdapter(); + if (method_exists($baseAdapter, 'containsDirectories')) { + return $baseAdapter->containsDirectories($this, $resourceType, $path, $this->acl); + } + + $directoryPath = $this->buildPath($resourceType, $path); + $contents = $this->listContents($directoryPath); + + foreach ($contents as $entry) { + if ($entry['type'] === 'dir' && + !$this->isHiddenFolder($entry['basename']) && + $this->acl->isAllowed($resourceType->getName(), Path::combine($path, $entry['basename']), Permission::FOLDER_VIEW) + ) { + return true; + } + } + + return false; + } + + /** + * Checks if the file with a given name is hidden. + * + * @param string $fileName + * + * @return bool `true` if the file is hidden. + */ + public function isHiddenFile($fileName) + { + $hideFilesRegex = $this->ckConfig->getHideFilesRegex(); + + if ($hideFilesRegex) { + return (bool) preg_match($hideFilesRegex, $fileName); + } + + return false; + } + + /** + * Checks if the directory with a given name is hidden. + * + * @param string $folderName + * + * @return bool `true` if the directory is hidden. + */ + public function isHiddenFolder($folderName) + { + $hideFoldersRegex = $this->ckConfig->getHideFoldersRegex(); + + if ($hideFoldersRegex) { + return (bool) preg_match($hideFoldersRegex, $folderName); + } + + return false; + } + + /** + * Checks if the path is hidden. + * + * @param string $path + * + * @return bool `true` if the path is hidden. + */ + public function isHiddenPath($path) + { + $pathParts = explode('/', trim($path, '/')); + if ($pathParts) { + foreach ($pathParts as $part) { + if ($this->isHiddenFolder($part)) { + return true; + } + } + } + + return false; + } + + /** + * Deletes a directory. + * + * @param string $dirname + * + * @return bool + */ + public function deleteDir($dirname) + { + $baseAdapter = $this->getBaseAdapter(); + + // For FTP first remove recursively all directory contents + if ($baseAdapter instanceof Ftp) { + $this->deleteContents($dirname); + } + + return parent::deleteDir($dirname); + } + + /** + * Delete all contents of the given directory. + * + * @param string $dirname + */ + public function deleteContents($dirname) + { + $contents = $this->listContents($dirname); + + foreach ($contents as $entry) { + if ($entry['type'] === 'dir') { + $this->deleteContents($entry['path']); + $this->deleteDir($entry['path']); + } else { + $this->delete($entry['path']); + } + } + } + + /** + * Checks if a backend contains a directory. + * + * The Backend::has() method is not always reliable and may + * work differently for various adapters. Checking for directory + * should be done with this method. + * + * @param string $directoryPath + * + * @return bool + */ + public function hasDirectory($directoryPath) + { + $pathParts = array_filter(explode('/', $directoryPath), 'strlen'); + $dirName = array_pop($pathParts); + $contents = $this->listContents(implode('/', $pathParts)); + + foreach ($contents as $c) { + if (isset($c['type']) && isset($c['basename']) && $c['type'] === 'dir' && $c['basename'] === $dirName) { + return true; + } + } + } + + /** + * Returns a URL to a file. + * + * If the useProxyCommand option is set for a backend, the returned + * URL will point to the CKFinder connector Proxy command. + * + * @param ResourceType $resourceType the file resource type + * @param string $folderPath the resource-type relative folder path + * @param string $fileName the file name + * @param string|null $thumbnailFileName the thumbnail file name - if the file is a thumbnail + * + * @return string|null URL to a file or `null` if the backend does not support it. + */ + public function getFileUrl(ResourceType $resourceType, $folderPath, $fileName, $thumbnailFileName = null) + { + if (isset($this->backendConfig['useProxyCommand'])) { + $connectorUrl = $this->app->getConnectorUrl(); + + $queryParameters = array( + 'command' => 'Proxy', + 'type' => $resourceType->getName(), + 'currentFolder' => $folderPath, + 'fileName' => $fileName + ); + + if ($thumbnailFileName) { + $queryParameters['thumbnail'] = $thumbnailFileName; + } + + $proxyCacheLifetime = (int) $this->ckConfig->get('cache.proxyCommand'); + + if ($proxyCacheLifetime > 0) { + $queryParameters['cache'] = $proxyCacheLifetime; + } + + return $connectorUrl . '?' . http_build_query($queryParameters, '', '&'); + } + + $path = $thumbnailFileName + ? Path::combine($resourceType->getDirectory(), $folderPath, ResizedImage::DIR, $fileName, $thumbnailFileName) + : Path::combine($resourceType->getDirectory(), $folderPath, $fileName); + + if (isset($this->backendConfig['baseUrl'])) { + return Path::combine($this->backendConfig['baseUrl'], Utils::encodeURLParts($path)); + } + + $baseAdapter = $this->getBaseAdapter(); + + if (method_exists($baseAdapter, 'getFileUrl')) { + return $baseAdapter->getFileUrl($path); + } + + return null; + } + + /** + * Returns the base URL used to build the direct URL to files stored + * in this backend. + * + * @return string|null base URL or `null` if the base URL for a backend + * was not defined. + */ + public function getBaseUrl() + { + if (isset($this->backendConfig['baseUrl']) && !$this->usesProxyCommand()) { + return $this->backendConfig['baseUrl']; + } + + return null; + } + + /** + * Returns the root directory defined for the backend. + * + * @return string|null root directory or `null` if the root directory + * was not defined. + */ + public function getRootDirectory() + { + if (isset($this->backendConfig['root'])) { + return $this->backendConfig['root']; + } + + return null; + } + + /** + * Returns a Boolean value telling if the backend uses the Proxy command. + * + * @return bool + */ + public function usesProxyCommand() + { + return isset($this->backendConfig['useProxyCommand']) && $this->backendConfig['useProxyCommand']; + } + + /** + * Creates a stream for writing. + * + * @param string $path file path + * + * @return resource|null a stream to a file or `null` if the backend does not + * support writing streams. + */ + public function createWriteStream($path) + { + $baseAdapter = $this->getBaseAdapter(); + + if (method_exists($baseAdapter, 'createWriteStream')) { + return $baseAdapter->createWriteStream($path); + } + + return null; + } + + /** + * Renames the object for a given path. + * + * @param string $path + * @param string $newpath + * + * @return bool `true` on success, `false` on failure. + */ + public function rename($path, $newpath) + { + $baseAdapter = $this->getBaseAdapter(); + + if (($baseAdapter instanceof EmulateRenameDirectoryInterface) && $this->hasDirectory($path)) { + return $baseAdapter->renameDirectory($path, $newpath); + } + + return parent::rename($path, $newpath); + } + + /** + * Returns a base adapter used by this backend. + * + * The used adapter might be decorated with CachedAdapter. In this + * case the returned adapter is the internal one used by CachedAdapter. + * + * @return AdapterInterface + */ + public function getBaseAdapter() + { + if ($this->adapter instanceof CachedAdapter) { + return $this->adapter->getAdapter(); + } + + return $this->adapter; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Backend/BackendFactory.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Backend/BackendFactory.php new file mode 100644 index 0000000..2bdf38e --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Backend/BackendFactory.php @@ -0,0 +1,266 @@ + array('RenameFolder') + ); + + /** + * The CKFinder application container. + * + * @var CKFinder $app + */ + protected $app; + + /** + * Access Control Lists. + * + * @var AclInterface $acl + */ + protected $acl; + + /** + * Configuration. + * + * @var Config $config + */ + protected $config; + + /** + * Constructor. + * + * @param CKFinder $app + */ + public function __construct(CKFinder $app) + { + $this->app = $app; + $this->acl = $app['acl']; + $this->config = $app['config']; + + $this->registerDefaultAdapters(); + } + + protected function registerDefaultAdapters() + { + $this->registerAdapter('local', function ($backendConfig) { + return $this->createBackend($backendConfig, new LocalFilesystemAdapter($backendConfig)); + }); + + $this->registerAdapter('ftp', function ($backendConfig) { + + $configurable = array('host', 'port', 'username', 'password', 'ssl', 'timeout', 'root', 'permPrivate', 'permPublic', 'passive'); + + $config = array_intersect_key($backendConfig, array_flip($configurable)); + + return $this->createBackend($backendConfig, new FtpAdapter($config)); + }); + + $this->registerAdapter('dropbox', function ($backendConfig) { + + $client = new DropboxClient($backendConfig['token'], $backendConfig['username']); + + return $this->createBackend($backendConfig, new DropboxAdapter($client, $backendConfig)); + }); + + $this->registerAdapter('s3', function ($backendConfig) { + $clientConfig = array( + 'key' => $backendConfig['key'], + 'secret' => $backendConfig['secret'], + ); + + if (isset($backendConfig['region'])) { + $clientConfig['region'] = $backendConfig['region']; + } + + $client = S3Client::factory($clientConfig); + + $filesystemConfig = array( + 'visibility' => isset($backendConfig['visibility']) ? $backendConfig['visibility'] : 'private' + ); + + $prefix = isset($backendConfig['root']) ? trim($backendConfig['root'], '/ ') : null; + + return $this->createBackend($backendConfig, new AwsS3Adapter($client, $backendConfig['bucket'], $prefix), $filesystemConfig); + }); + + $this->registerAdapter('azure', function ($backendConfig) { + $endpoint = sprintf('DefaultEndpointsProtocol=https;AccountName=%s;AccountKey=%s', $backendConfig['account'], $backendConfig['key']); + $blobRestProxy = ServicesBuilder::getInstance()->createBlobService($endpoint); + + $prefix = isset($backendConfig['root']) ? trim($backendConfig['root'], '/ ') : null; + + return $this->createBackend($backendConfig, new AzureAdapter($blobRestProxy, $backendConfig['container'], $prefix)); + }); + } + + /** + * @param string $adapterName + * @param callable $instantiationCallback + */ + public function registerAdapter($adapterName, callable $instantiationCallback) + { + $this->registeredAdapters[$adapterName] = $instantiationCallback; + } + + /** + * Creates a backend file system. + * + * @param array $backendConfig + * @param AdapterInterface $adapter + * @param array|null $filesystemConfig + * @param CacheInterface|null $cache + * + * @return Backend + */ + public function createBackend(array $backendConfig, AdapterInterface $adapter, array $filesystemConfig = null, CacheInterface $cache = null) + { + if ($adapter instanceof ContainerAwareInterface) { + $adapter->setContainer($this->app); + } + + if (null === $cache) { + $cache = new MemoryCache(); + } + + $cachedAdapter = new CachedAdapter($adapter, $cache); + + if (array_key_exists($backendConfig['adapter'], static::$trackedOperations)) { + $backendConfig['trackedOperations'] = static::$trackedOperations[$backendConfig['adapter']]; + } + + return new Backend($backendConfig, $this->app, $cachedAdapter, $filesystemConfig); + } + + /** + * Returns the backend object by name. + * + * @param string $backendName + * + * @return Backend + * + * @throws \InvalidArgumentException + * @throws CKFinderException + */ + public function getBackend($backendName) + { + if (isset($this->backends[$backendName])) { + return $this->backends[$backendName]; + } + + $backendConfig = $this->config->getBackendNode($backendName); + $adapterName = $backendConfig['adapter']; + + if (!isset($this->registeredAdapters[$adapterName])) { + throw new \InvalidArgumentException(sprintf('Backends adapter "%s" not found. Please check configuration file.', $adapterName)); + } + + if (!is_callable($this->registeredAdapters[$adapterName])) { + throw new \InvalidArgumentException(sprintf('Backend instantiation callback for adapter "%s" is not a callable.', $adapterName)); + } + + $backend = call_user_func($this->registeredAdapters[$adapterName], $backendConfig); + + if (!$backend instanceof Backend) { + throw new CKFinderException(sprintf('The instantiation callback for adapter "%s" didn\'t return a valid Backend object.', $adapterName)); + } + + $this->backends[$backendName] = $backend; + + return $backend; + } + + /** + * Returns the backend object for a given private directory identifier. + * + * @param string $privateDirIdentifier + * + * @return Backend + */ + public function getPrivateDirBackend($privateDirIdentifier) + { + $privateDirConfig = $this->config->get('privateDir'); + + if (!array_key_exists($privateDirIdentifier, $privateDirConfig)) { + throw new \InvalidArgumentException(sprintf('Private dir with identifier %s not found. Please check configuration file.', $privateDirIdentifier)); + } + + $privateDir = $privateDirConfig[$privateDirIdentifier]; + + $backend = null; + + if (is_array($privateDir) && array_key_exists('backend', $privateDir)) { + $backend = $this->getBackend($privateDir['backend']); + } else { + $backend = $this->getBackend($privateDirConfig['backend']); + } + + // Create a default .htaccess to disable access to current private directory + $privateDirPath = $this->config->getPrivateDirPath($privateDirIdentifier); + $htaccessPath = Path::combine($privateDirPath, '.htaccess'); + if (!$backend->has($htaccessPath)) { + $backend->write($htaccessPath, "Order Deny,Allow\nDeny from all\n"); + } + + return $backend; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/CKFinder.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/CKFinder.php new file mode 100644 index 0000000..f493eee --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/CKFinder.php @@ -0,0 +1,614 @@ +Pimple + * so it also serves as a dependency injection container. + * + * @copyright 2016 CKSource - Frederico Knabben + */ +class CKFinder extends Container implements HttpKernelInterface +{ + const VERSION = '3.3.0'; + + const COMMANDS_NAMESPACE = 'CKSource\\CKFinder\\Command\\'; + const PLUGINS_NAMESPACE = 'CKSource\\CKFinder\\Plugin\\'; + + const CHARS = '123456789ABCDEFGHJKLMNPQRSTUVWXYZ'; + + protected $plugins = array(); + + protected $booted = false; + + /** + * Constructor. + * + * @param array|string $config an array containing configuration options or a path + * to the configuration file. + * + * @see config.php + */ + public function __construct($config) + { + parent::__construct(); + + $app = $this; + + $this['config'] = function () use ($config) { + return new Config($config); + }; + + $this['authentication'] = function () use ($app) { + $config = $app['config']; + + return new CallableAuthentication($config->get('authentication')); + }; + + $this['exception_handler'] = function () use ($app) { + return new ExceptionHandler($app['translator'], $app['debug'], $app['logger']); + }; + + $this['dispatcher'] = function () use ($app) { + $eventDispatcher = new EventDispatcher(); + + $eventDispatcher->addListener(KernelEvents::VIEW, array($this, 'createResponse'), -512); + $eventDispatcher->addListener(KernelEvents::RESPONSE, array($this, 'afterCommand'), -512); + + $eventDispatcher->addSubscriber($app['exception_handler']); + + return $eventDispatcher; + }; + + $this['resolver'] = function () use ($app) { + $commandResolver = new CommandResolver($app); + $commandResolver->setCommandsNamespace(CKFinder::COMMANDS_NAMESPACE); + $commandResolver->setPluginsNamespace(CKFinder::PLUGINS_NAMESPACE); + + return $commandResolver; + }; + + $this['request_stack'] = function () { + return new RequestStack(); + }; + + $this['request_transformer'] = function () { + return new JsonTransformer(); + }; + + $this['working_folder'] = function () use ($app) { + $workingFolder = new WorkingFolder($app); + + $this['dispatcher']->addSubscriber($workingFolder); + + return $workingFolder; + }; + + $this['operation'] = function () use ($app) { + return new OperationManager($app); + }; + + $this['kernel'] = function () use ($app) { + return new HttpKernel($app['dispatcher'], $app['resolver'], $app['request_stack']); + }; + + $this['acl'] = function () use ($app) { + $config = $app['config']; + + $roleContext = new SessionRoleContext($config->get('roleSessionVar')); + + $acl = new Acl($roleContext); + $acl->setRules($config->get('accessControl')); + + return $acl; + }; + + $this['backend_factory'] = function () use ($app) { + return new BackendFactory($app); + }; + + $this['resource_type_factory'] = function () use ($app) { + return new ResourceTypeFactory($app); + }; + + $this['thumbnail_repository'] = function () use ($app) { + return new ThumbnailRepository($app); + }; + + $this['resized_image_repository'] = function () use ($app) { + return new ResizedImageRepository($app); + }; + + $this['cache'] = function () use ($app) { + $cacheBackend = $app['backend_factory']->getPrivateDirBackend('cache'); + $cacheDir = $app['config']->getPrivateDirPath('cache') . '/data'; + + return new CacheManager(new BackendAdapter($cacheBackend, $cacheDir)); + }; + + $this['translator'] = function () { + return new Translator(); + }; + + $this['debug'] = $app['config']->get('debug'); + + $this['logger'] = function () use ($app) { + $logger = new Logger('CKFinder'); + + if ($app['config']->isDebugLoggerEnabled('firephp')) { + $logger->pushHandler(new FirePHPHandler()); + } + + if ($app['config']->isDebugLoggerEnabled('error_log')) { + $logger->pushHandler(new ErrorLogHandler()); + } + + return $logger; + }; + + if ($app['config']->get('csrfProtection')) { + $config = $app['config']; + + $this['csrf_token_validator'] = function () use ($config) { + return new DoubleSubmitCookieTokenValidator(); + }; + } + } + + /** + * Checks authentication. + */ + public function checkAuth() + { + /* @var $authentication \CKSource\CKFinder\Authentication\AuthenticationInterface */ + $authentication = $this['authentication']; + + if (!$authentication->authenticate()) { + ini_set('display_errors', 0); + throw new CKFinderException('CKFinder is disabled', Error::CONNECTOR_DISABLED); + } + } + + /** + * Validates the CSRF token. + * + * @param Request $request + * + * @throws InvalidCsrfTokenException + */ + public function checkCsrfToken(Request $request) + { + if ($request->getMethod() === Request::METHOD_GET) { + return; + } + + /* @var $csrfTokenValidator \CKSource\CKFinder\Security\Csrf\TokenValidatorInterface */ + $csrfTokenValidator = $this['csrf_token_validator']; + + if (!$csrfTokenValidator->validate($request)) { + throw new InvalidCsrfTokenException(); + } + } + + /** + * Creates a response. + * + * @param GetResponseForControllerResultEvent $event + */ + public function createResponse(GetResponseForControllerResultEvent $event) + { + /* @var $dispatcher EventDispatcher */ + $dispatcher = $this['dispatcher']; + + $commandName = $event->getRequest()->get('command'); + $eventName = CKFinderEvent::CREATE_RESPONSE_PREFIX . lcfirst($commandName); + $dispatcher->dispatch($eventName, $event); + + $controllerResult = $event->getControllerResult(); + $event->setResponse(JsonResponse::create($controllerResult)); + } + + /** + * Fires `afterCommand` events. + * + * @param FilterResponseEvent $event + * + * @return \Symfony\Component\HttpFoundation\Response|static + */ + public function afterCommand(FilterResponseEvent $event) + { + /* @var $dispatcher EventDispatcher */ + $dispatcher = $this['dispatcher']; + + $commandName = $event->getRequest()->get('command'); + $eventName = CKFinderEvent::AFTER_COMMAND_PREFIX . lcfirst($commandName); + $afterCommandEvent = new AfterCommandEvent($this, $commandName, $event->getResponse()); + $dispatcher->dispatch($eventName, $afterCommandEvent); + + // #161 Clear any garbage from the output + Response::closeOutputBuffers(0, false); + + $event->setResponse($afterCommandEvent->getResponse()); + } + + /** + * Registers a listener for an event. + * + * @param string $eventName event name + * @param callable $listener listener callable + * @param int $priority priority + */ + public function on($eventName, $listener, $priority = 0) + { + /* @var $dispatcher EventDispatcher */ + $dispatcher = $this['dispatcher']; + + $dispatcher->addListener($eventName, $listener, $priority); + } + + /** + * Main method used to handle a request by CKFinder. + * + * @param Request $request request object + */ + public function run(Request $request = null) + { + $request = null === $request ? Request::createFromGlobals() : $request; + + /* @var $kernel HttpKernel */ + $kernel = $this['kernel']; + + $response = $this->handle($request); + $response->send(); + + $kernel->terminate($request, $response); + } + + /** + * Returns the BackedFactory service. + * + * @return BackendFactory + */ + public function getBackendFactory() + { + return $this['backend_factory']; + } + + /** + * Returns the ACL service. + * + * @return Acl + */ + public function getAcl() + { + return $this['acl']; + } + + /** + * Returns the current WorkingFolder object. + * + * @return WorkingFolder + */ + public function getWorkingFolder() + { + return $this['working_folder']; + } + + /** + * Shorthand for debugging using the defined logger. + * + * @param string $message + * @param array $context + */ + public function debug($message, array $context = array()) + { + $logger = $this['logger']; + + if ($logger) { + $logger->debug($message, $context); + } + } + + /** + * Registers plugins defined in the configuration file. + * + * @throws \LogicException in case the plugin was not found or is invalid. + */ + protected function registerPlugins() + { + $pluginsEntries = $this['config']->get('plugins'); + $pluginsDirectory = $this['config']->get('pluginsDirectory'); + + foreach ($pluginsEntries as $pluginInfo) { + if (is_array($pluginInfo)) { + $pluginName = ucfirst($pluginInfo['name']); + if (isset($pluginInfo['path'])) { + require_once $pluginInfo['path']; + } + } else { + $pluginName = ucfirst($pluginInfo); + } + + $pluginPath = Path::combine($pluginsDirectory, $pluginName, $pluginName . '.php'); + + if (file_exists($pluginPath) && is_readable($pluginPath)) { + require_once $pluginPath; + } + + $pluginClassName = CKFinder::PLUGINS_NAMESPACE . $pluginName . '\\' . $pluginName; + + if (!class_exists($pluginClassName)) { + throw new InvalidPluginException(sprintf('CKFinder plugin "%s" not found (%s)', $pluginName, $pluginClassName), array('pluginName' => $pluginName)); + } + + $pluginObject = new $pluginClassName($this); + + if ($pluginObject instanceof PluginInterface) { + $this->registerPlugin($pluginObject); + } else { + throw new InvalidPluginException(sprintf('CKFinder plugin class must implement %sPluginInterface', CKFinder::PLUGINS_NAMESPACE), array('pluginName' => $pluginName)); + } + } + } + + /** + * Registers the plugin. + * + * @param PluginInterface $plugin + */ + public function registerPlugin(PluginInterface $plugin) + { + $plugin->setContainer($this); + + $pluginNameParts = explode('\\', get_class($plugin)); + $pluginName = end($pluginNameParts); + + $this['config']->extend($pluginName, $plugin->getDefaultConfig()); + + if ($plugin instanceof EventSubscriberInterface) { + $this['dispatcher']->addSubscriber($plugin); + } + + $this->plugins[$pluginName] = $plugin; + } + + /** + * Returns an array containing all registered plugins. + * + * @return array array of PluginInterface-s + */ + public function getPlugins() + { + return $this->plugins; + } + + /** + * Returns a plugin by the name. + * + * @param string $name plugin name + * + * @return null|PluginInterface + * + */ + public function getPlugin($name) + { + if (isset($this->plugins[$name])) { + return $this->plugins[$name]; + } + + return null; + } + + /** + * Checks PHP requirements. + * + * @throws CKFinderException + */ + protected function checkRequirements() + { + $errorMessage = 'The PHP installation does not meet the minimum system requirements for CKFinder. %s Please refer to CKFinder documentation for more details.'; + + if (version_compare(PHP_VERSION, '5.4.0') < 0) { + throw new CKFinderException(sprintf($errorMessage, 'Your PHP version is too old. CKFinder 3.x requires PHP 5.4+.'), Error::CUSTOM_ERROR); + } + + $missingExtensions = array(); + + if (!function_exists('gd_info')) { + $missingExtensions[] = 'GD'; + } + + if (!function_exists('finfo_file')) { + $missingExtensions[] = 'Fileinfo'; + } + + if (!empty($missingExtensions)) { + throw new CKFinderException(sprintf($errorMessage, 'Missing PHP extensions: ' . implode(', ', $missingExtensions) . '.'), Error::CUSTOM_ERROR); + } + } + + /** + * Prepares application environment before the Request is dispatched. + * + * @param Request $request + * + * @throws CKFinderException + * @throws InvalidPluginException + */ + public function boot(Request $request) + { + if ($this->booted) { + return; + } + + $this->booted = true; + + $config = $this['config']; + + $this->checkRequirements(); + + if ($config->get('debug') && $config->isDebugLoggerEnabled('ckfinder_log')) { + $this->registerStreamLogger(); + } + + $this->checkAuth(); + + if ($config->get('csrfProtection')) { + $this->checkCsrfToken($request); + } + + $this->registerPlugins(); + + $commandName = (string) $request->query->get('command'); + + if ($config->get('sessionWriteClose') && $commandName !== 'Init' && session_status() === PHP_SESSION_ACTIVE) { + session_write_close(); + } + } + + /** + * Registers a stream handler for error logging. + */ + public function registerStreamLogger() + { + $app = $this; + + /* @var $logsBackend \CKSource\CKFinder\Backend\Backend */ + $logsBackend = $app['backend_factory']->getPrivateDirBackend('logs'); + + $adapter = $logsBackend->getBaseAdapter(); + + if ($adapter instanceof LocalFSAdapter) { + $logsDir = $app['config']->getPrivateDirPath('logs'); + + $errorLogPath = Path::combine($logsDir, 'error.log'); + + $logPath = $adapter->applyPathPrefix($errorLogPath); + + $app['logger']->pushHandler(new StreamHandler($logPath)); + } + } + + /** + * @param Request $request + * @param int $type + * @param bool $catch + * + * @return \Symfony\Component\HttpFoundation\Response + * @throws \Exception + */ + public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true) + { + /* @var $kernel HttpKernel */ + $kernel = $this['kernel']; + + /* @var $requestTransformer \CKSource\CKFinder\Request\Transformer\TransformerInterface */ + $requestTransformer = $this['request_transformer']; + + if ($requestTransformer) { + $request = $requestTransformer->transform($request); + } + + // Handle early exceptions + if (!$this->booted) { + try { + $this->boot($request); + } catch (\Exception $e) { + $this['request_stack']->push($request); + $kernel->terminateWithException($e); + exit; + } + } + + return $kernel->handle($request, $type, $catch); + } + + /** + * Returns the current request object. + * + * @return Request + */ + public function getRequest() + { + /* @var $requestStack RequestStack */ + $requestStack = $this['request_stack']; + + return $requestStack->getCurrentRequest(); + } + + /** + * Returns the resized image repository. + * + * @return ResizedImageRepository + */ + public function getResizedImageRepository() + { + return $this['resized_image_repository']; + } + + /** + * Returns the connector URL based on the current request. + * + * @param bool|true $full if set to `true`, the returned URL contains the scheme and host. + * + * @return string + */ + public function getConnectorUrl($full = true) + { + $request = $this->getRequest(); + + return ($full ? $request->getSchemeAndHttpHost() : '').$request->getBaseUrl(); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Cache/Adapter/AdapterInterface.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Cache/Adapter/AdapterInterface.php new file mode 100644 index 0000000..a6bbe49 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Cache/Adapter/AdapterInterface.php @@ -0,0 +1,64 @@ +backend = $backend; + $this->cachePath = $path; + } + + /** + * Creates backend-relative path for cache file for given key + * + * @param string $key + * @param bool $prefix + * + * @return string + */ + public function createCachePath($key, $prefix = false) + { + return Path::combine($this->cachePath, trim($key, '/') . ($prefix ? '' : '.cache')); + } + + /** + * Sets the value in cache under given key + * + * @param string $key + * @param mixed $value + * + * @return bool true if successful + */ + public function set($key, $value) + { + return $this->backend->put($this->createCachePath($key), serialize($value)); + } + + /** + * Returns value under given key from cache + * + * @param string $key + * + * @return null|array + */ + public function get($key) + { + $cachePath = $this->createCachePath($key); + + if (!$this->backend->has($cachePath)) { + return null; + } + + return unserialize($this->backend->read($cachePath)); + } + + /** + * Deletes value under given key from cache + * + * @param string $key + * + * @return bool true if successful + */ + public function delete($key) + { + $cachePath = $this->createCachePath($key); + + if (!$this->backend->has($cachePath)) { + return false; + } + + $this->backend->delete($cachePath); + + $dirs = explode('/', dirname($cachePath)); + + do { + $dirPath = implode('/', $dirs); + $contents = $this->backend->listContents($dirPath); + + if (!empty($contents)) { + break; + } + + $this->backend->deleteDir($dirPath); + array_pop($dirs); + } while (!empty($dirs)); + } + + /** + * Deletes all cache entries with given key prefix + * + * @param string $keyPrefix + * + * @return bool true if successful + */ + public function deleteByPrefix($keyPrefix) + { + $cachePath = $this->createCachePath($keyPrefix, true); + if ($this->backend->hasDirectory($cachePath)) { + return $this->backend->deleteDir($cachePath); + } + + return false; + } + + /** + * Changes prefix for all entries given key prefix + * + * @param string $sourcePrefix + * @param string $targetPrefix + * + * @return bool true if successful + */ + public function changePrefix($sourcePrefix, $targetPrefix) + { + $sourceCachePath = $this->createCachePath($sourcePrefix, true); + + if (!$this->backend->hasDirectory($sourceCachePath)) { + return false; + } + + $targetCachePath = $this->createCachePath($targetPrefix, true); + + return $this->backend->rename($sourceCachePath, $targetCachePath); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Cache/CacheManager.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Cache/CacheManager.php new file mode 100644 index 0000000..1bad908 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Cache/CacheManager.php @@ -0,0 +1,132 @@ +adapter = $adapter; + } + + /** + * Sets the value in cache for a given key. + * + * @param string $key + * @param mixed $value + * + * @return bool `true` if successful. + */ + public function set($key, $value) + { + return $this->adapter->set($key, $value); + } + + /** + * Returns the value for a given key from cache. + * + * @param string $key + * + * @return array + */ + public function get($key) + { + return $this->adapter->get($key); + } + + /** + * Deletes the value under a given key from cache. + * + * @param string $key + * + * @return bool `true` if successful. + */ + public function delete($key) + { + return $this->adapter->delete($key); + } + + /** + * Copies the value for a given key to another key. + * + * @param string $sourceKey + * @param string $targetKey + * + * @return bool `true` if successful. + */ + public function copy($sourceKey, $targetKey) + { + $value = $this->adapter->get($sourceKey); + + if (null === $value) { + return false; + } + + return $this->adapter->set($targetKey, $value); + } + + /** + * Moves the value for a given key to another key. + * + * @param string $sourceKey + * @param string $targetKey + * + * @return bool `true` if successful. + */ + public function move($sourceKey, $targetKey) + { + return $this->copy($sourceKey, $targetKey) && $this->delete($sourceKey); + } + + /** + * Deletes all cache entries with a given key prefix. + * + * @param string $keyPrefix + * + * @return bool `true` if successful. + */ + public function deleteByPrefix($keyPrefix) + { + return $this->adapter->deleteByPrefix($keyPrefix); + } + + /** + * Changes the prefix for all entries given a key prefix. + * + * @param string $sourcePrefix + * @param string $targetPrefix + * + * @return bool `true` if successful. + */ + public function changePrefix($sourcePrefix, $targetPrefix) + { + return $this->adapter->changePrefix($sourcePrefix, $targetPrefix); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/CommandAbstract.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/CommandAbstract.php new file mode 100644 index 0000000..756ad9f --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/CommandAbstract.php @@ -0,0 +1,104 @@ +setContainer($app); + } + + /** + * Injects dependency injection container to the command scope. + * + * @param CKFinder $app + */ + public function setContainer(CKFinder $app) + { + $this->app = $app; + } + + /** + * Checks permissions required by the command before it is executed. + * + * @throws \Exception if access is restricted. + */ + public function checkPermissions() + { + if (!empty($this->requires)) { + $workingFolder = $this->app->getWorkingFolder(); + + $aclMask = $workingFolder->getAclMask(); + + $requiredPermissionsMask = array_sum($this->requires); + + if (($aclMask & $requiredPermissionsMask) !== $requiredPermissionsMask) { + throw new UnauthorizedException(); + } + } + } + + /** + * Returns the name of the request method required by the command. + * + * @return string + */ + public function getRequestMethod() + { + return $this->requestMethod; + } + + /** + * This method is not defined as abstract to allow for parameter injection. + * @see CKSource\CKFinder\CommandResolver::getArguments() + */ + // public abstract function execute(); +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/CopyFiles.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/CopyFiles.php new file mode 100644 index 0000000..0228b96 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/CopyFiles.php @@ -0,0 +1,101 @@ +request->get('files'); + + $copied = 0; + + $errors = array(); + + // Initial validation + foreach ($copiedFiles as $arr) { + if (!isset($arr['name'], $arr['type'], $arr['folder'])) { + throw new InvalidRequestException(); + } + + if (!$acl->isAllowed($arr['type'], $arr['folder'], Permission::FILE_VIEW)) { + throw new UnauthorizedException(); + } + } + + foreach ($copiedFiles as $arr) { + if (empty($arr['name'])) { + continue; + } + + $name = $arr['name']; + $type = $arr['type']; + $folder = $arr['folder']; + + $resourceType = $resourceTypeFactory->getResourceType($type); + + $copiedFile = new CopiedFile($name, $folder, $resourceType, $this->app); + + $options = isset($arr['options']) ? $arr['options'] : ''; + + $copiedFile->setCopyOptions($options); + + + if ($copiedFile->isValid()) { + $copyFileEvent = new CopyFileEvent($this->app, $copiedFile); + $dispatcher->dispatch(CKFinderEvent::COPY_FILE, $copyFileEvent); + + if (!$copyFileEvent->isPropagationStopped()) { + if ($copiedFile->doCopy()) { + $copied++; + } + } + } + + $errors = array_merge($errors, $copiedFile->getErrors()); + } + + $data = array('copied' => $copied); + + if (!empty($errors)) { + $data['error'] = array( + 'number' => Error::COPY_FAILED, + 'errors' => $errors + ); + } + + return $data; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/CreateFolder.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/CreateFolder.php new file mode 100644 index 0000000..5d50c87 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/CreateFolder.php @@ -0,0 +1,47 @@ +query->get('newFolderName', ''); + + $createFolderEvent = new CreateFolderEvent($this->app, $workingFolder, $newFolderName); + + $dispatcher->dispatch(CKFinderEvent::CREATE_FOLDER, $createFolderEvent); + + $created = false; + + if (!$createFolderEvent->isPropagationStopped()) { + $newFolderName = $createFolderEvent->getNewFolderName(); + $created = $workingFolder->createDir($newFolderName); + } + + return array('newFolder' => $newFolderName, 'created' => (int) $created); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/DeleteFiles.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/DeleteFiles.php new file mode 100644 index 0000000..23559f3 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/DeleteFiles.php @@ -0,0 +1,94 @@ +request->get('files'); + + $deleted = 0; + + $errors = array(); + + // Initial validation + foreach ($deletedFiles as $arr) { + if (!isset($arr['name'], $arr['type'], $arr['folder'])) { + throw new InvalidRequestException('Invalid request'); + } + + if (!$acl->isAllowed($arr['type'], $arr['folder'], Permission::FILE_DELETE)) { + throw new UnauthorizedException(); + } + } + + foreach ($deletedFiles as $arr) { + if (empty($arr['name'])) { + continue; + } + + $name = $arr['name']; + $type = $arr['type']; + $folder = $arr['folder']; + + $resourceType = $resourceTypeFactory->getResourceType($type); + + $deletedFile = new DeletedFile($name, $folder, $resourceType, $this->app); + + if ($deletedFile->isValid()) { + $deleteFileEvent = new DeleteFileEvent($this->app, $deletedFile); + $dispatcher->dispatch(CKFinderEvent::DELETE_FILE, $deleteFileEvent); + + if (!$deleteFileEvent->isPropagationStopped()) { + if ($deletedFile->doDelete()) { + $deleted++; + } + } + } + + $errors = array_merge($errors, $deletedFile->getErrors()); + } + + $data = array('deleted' => $deleted); + + if (!empty($errors)) { + $data['error'] = array( + 'number' => Error::DELETE_FAILED, + 'errors' => $errors + ); + } + + return $data; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/DeleteFolder.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/DeleteFolder.php new file mode 100644 index 0000000..6b2768b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/DeleteFolder.php @@ -0,0 +1,55 @@ +getClientCurrentFolder() === '/') { + throw new InvalidRequestException('Cannot delete resource type root folder'); + } + + $deleteFolderEvent = new DeleteFolderEvent($this->app, $workingFolder); + + $dispatcher->dispatch(CKFinderEvent::DELETE_FOLDER, $deleteFolderEvent); + + $deleted = false; + + if (!$deleteFolderEvent->isPropagationStopped()) { + $deleted = $workingFolder->delete(); + } + + if (!$deleted) { + throw new AccessDeniedException(); + } + + return array('deleted' => (int) $deleted); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/DownloadFile.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/DownloadFile.php new file mode 100644 index 0000000..536545b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/DownloadFile.php @@ -0,0 +1,85 @@ +query->get('fileName'); + + $downloadedFile = new DownloadedFile($fileName, $this->app); + + $downloadedFile->isValid(); + + $downloadedFileEvent = new DownloadFileEvent($this->app, $downloadedFile); + + $dispatcher->dispatch(CKFinderEvent::DOWNLOAD_FILE, $downloadedFileEvent); + + if ($downloadedFileEvent->isPropagationStopped()) { + throw new AccessDeniedException(); + } + + $response = new StreamedResponse(); + + $response->headers->set('Cache-Control', 'cache, must-revalidate'); + $response->headers->set('Pragma', 'public'); + $response->headers->set('Expires', '0'); + + if ($request->get('format') === 'text') { + $response->headers->set('Content-Type', 'text/plain; charset=utf-8'); + } else { + $userAgent = !empty($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : ''; + $encodedName = str_replace("\"", "\\\"", $fileName); + if (strpos($userAgent, 'MSIE') !== false) { + $encodedName = str_replace(array("+", "%2E"), array(" ", "."), urlencode($encodedName)); + } + $response->headers->set('Content-Type', 'application/octet-stream; name="' . $fileName . '"'); + $response->headers->set('Content-Disposition', 'attachment; filename="' . $encodedName. '"'); + } + + $response->headers->set('Content-Length', $downloadedFile->getSize()); + + $fileStream = $workingFolder->readStream($downloadedFile->getFilename()); + $chunkSize = 1024 * 100; // how many bytes per chunk + + $response->setCallback(function () use ($fileStream, $chunkSize) { + if ($fileStream === false) { + return false; + } + while (!feof($fileStream)) { + echo fread($fileStream, $chunkSize); + flush(); + @set_time_limit(8); + } + + return true; + }); + + return $response; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/FileUpload.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/FileUpload.php new file mode 100644 index 0000000..89682e3 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/FileUpload.php @@ -0,0 +1,173 @@ +get('asPlainText')) { + $uploadEvents = array( + CKFinderEvent::AFTER_COMMAND_FILE_UPLOAD, + CKFinderEvent::AFTER_COMMAND_QUICK_UPLOAD + ); + + foreach ($uploadEvents as $eventName) { + $dispatcher->addListener($eventName, function (AfterCommandEvent $event) { + $response = $event->getResponse(); + $response->headers->set('Content-Type', 'text/plain'); + }); + } + } + + $uploaded = 0; + + $warningErrorCode = null; + $upload = $request->files->get('upload'); + + if (null === $upload) { + throw new InvalidUploadException(); + } + + $uploadedFile = new UploadedFile($upload, $this->app); + + if (!$uploadedFile->isValid()) { + throw new InvalidUploadException($uploadedFile->getErrorMessage()); + } + + $uploadedFile->sanitizeFilename(); + + if ($uploadedFile->wasRenamed()) { + $warningErrorCode = Error::UPLOADED_INVALID_NAME_RENAMED; + } + + if (!$uploadedFile->hasValidFilename() || $uploadedFile->isHiddenFile()) { + throw new InvalidNameException(); + } + + if (!$uploadedFile->hasAllowedExtension()) { + throw new InvalidExtensionException(); + } + + // Autorename if required + $overwriteOnUpload = $config->get('overwriteOnUpload'); + if (!$overwriteOnUpload && $uploadedFile->autorename()) { + $warningErrorCode = Error::UPLOADED_FILE_RENAMED; + } + + $fileName = $uploadedFile->getFilename(); + + if (!$uploadedFile->isAllowedHtmlFile() && $uploadedFile->containsHtml()) { + throw new InvalidUploadException('HTML detected in disallowed file type', Error::UPLOADED_WRONG_HTML_FILE); + } + + if ($config->get('secureImageUploads') && $uploadedFile->isImage() && !$uploadedFile->isValidImage()) { + throw new InvalidUploadException('Invalid upload: corrupted image', Error::UPLOADED_CORRUPT); + } + + $maxFileSize = $workingFolder->getResourceType()->getMaxSize(); + + if (!$config->get('checkSizeAfterScaling') && $maxFileSize && $uploadedFile->getSize() > $maxFileSize) { + throw new InvalidUploadException('Uploaded file is too big', Error::UPLOADED_TOO_BIG); + } + + if (Image::isSupportedExtension($uploadedFile->getExtension())) { + $imagesConfig = $config->get('images'); + $image = Image::create($uploadedFile->getContents()); + + if ($imagesConfig['maxWidth'] && $image->getWidth() > $imagesConfig['maxWidth'] || + $imagesConfig['maxHeight'] && $image->getHeight() > $imagesConfig['maxHeight']) { + $image->resize($imagesConfig['maxWidth'], $imagesConfig['maxHeight'], $imagesConfig['quality']); + $imageData = $image->getData(); + $uploadedFile->save($imageData); + } + + $cache->set( + Path::combine( + $workingFolder->getResourceType()->getName(), + $workingFolder->getClientCurrentFolder(), + $fileName), + $image->getInfo() + ); + + unset($imageData); + unset($image); + } + + if ($maxFileSize && $uploadedFile->getSize() > $maxFileSize) { + throw new InvalidUploadException('Uploaded file is too big', Error::UPLOADED_TOO_BIG); + } + + $event = new FileUploadEvent($this->app, $uploadedFile); + $dispatcher->dispatch(CKFinderEvent::FILE_UPLOAD, $event); + + if (!$event->isPropagationStopped()) { + $uploadedFileStream = $uploadedFile->getContentsStream(); + $uploaded = (int) $workingFolder->putStream($fileName, $uploadedFileStream, $uploadedFile->getMimeType()); + + fclose($uploadedFileStream); + + if ($overwriteOnUpload) { + $thumbsRepository->deleteThumbnails( + $workingFolder->getResourceType(), + $workingFolder->getClientCurrentFolder(), + $fileName + ); + } + + if (!$uploaded) { + $warningErrorCode = Error::ACCESS_DENIED; + } + } + + $responseData = array( + 'fileName' => $fileName, + 'uploaded' => $uploaded + ); + + if ($warningErrorCode) { + $errorMessage = $this->app['translator']->translateErrorMessage($warningErrorCode, array('name' => $fileName)); + $responseData['error'] = array( + 'number' => $warningErrorCode, + 'message' => $errorMessage + ); + } + + return $responseData; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/GetFileUrl.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/GetFileUrl.php new file mode 100644 index 0000000..db6e5f5 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/GetFileUrl.php @@ -0,0 +1,46 @@ +get('fileName'); + $thumbnail = (string) $request->get('thumbnail'); + + $fileNames = (array) $request->get('fileNames'); + + if (!empty($fileNames)) { + $urls = array(); + + foreach ($fileNames as $fileName) { + $urls[$fileName] = $workingFolder->getFileUrl($fileName); + } + + return array('urls' => $urls); + } + + return array( + 'url' => $workingFolder->getFileUrl($fileName, $thumbnail) + ); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/GetFiles.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/GetFiles.php new file mode 100644 index 0000000..c743131 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/GetFiles.php @@ -0,0 +1,49 @@ +listFiles(); + + $data->files = array(); + + foreach ($files as $file) { + $fileObject = array( + 'name' => $file['basename'], + 'date' => Utils::formatDate($file['timestamp']), + 'size' => Utils::formatSize($file['size']) + ); + + $data->files[] = $fileObject; + } + + // Sort files + usort($data->files, function ($a, $b) { + return strnatcasecmp($a['name'], $b['name']); + }); + + return $data; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/GetFolders.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/GetFolders.php new file mode 100644 index 0000000..36dea6b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/GetFolders.php @@ -0,0 +1,51 @@ +listDirectories(); + + $data = new \stdClass(); + $data->folders = array(); + + $backend = $workingFolder->getBackend(); + + $resourceType = $workingFolder->getResourceType(); + + foreach ($directories as $directory) { + $data->folders[] = array( + 'name' => $directory['basename'], + 'hasChildren' => $backend->containsDirectories($resourceType, Path::combine($workingFolder->getClientCurrentFolder(), $directory['basename'])), + 'acl' => $directory['acl'] + ); + } + + // Sort folders + usort($data->folders, function ($a, $b) { + return strnatcasecmp($a['name'], $b['name']); + }); + + return $data; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/GetResizedImages.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/GetResizedImages.php new file mode 100644 index 0000000..07f9801 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/GetResizedImages.php @@ -0,0 +1,74 @@ +get('fileName'); + $sizes = (string) $request->get('sizes'); + + $ext = pathinfo($fileName, PATHINFO_EXTENSION); + + if (!Image::isSupportedExtension($ext)) { + throw new InvalidRequestException('Invalid file extension'); + } + + if ($sizes) { + $sizes = explode(',', $sizes); + if (array_diff($sizes, array_keys($config->get('images.sizes')))) { + throw new InvalidRequestException(sprintf('Invalid size requested')); + } + } + + $data = array(); + + $cachedInfo = $cache->get( + Path::combine( + $workingFolder->getResourceType()->getName(), + $workingFolder->getClientCurrentFolder(), + $fileName + ) + ); + + if ($cachedInfo && isset($cachedInfo['width']) && isset($cachedInfo['height'])) { + $data['originalSize'] = sprintf("%dx%d", $cachedInfo['width'], $cachedInfo['height']); + } + + $resizedImages = $resizedImageRepository->getResizedImagesList( + $workingFolder->getResourceType(), + $workingFolder->getClientCurrentFolder(), + $fileName, + $sizes ?: array() + ); + + $data['resized'] = $resizedImages; + + return $data; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/ImageEdit.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/ImageEdit.php new file mode 100644 index 0000000..72eb5b0 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/ImageEdit.php @@ -0,0 +1,153 @@ +get('fileName'); + $newFileName = (string) $request->get('newFileName'); + + $editedImage = new EditedImage($fileName, $this->app, $newFileName); + + $resourceType = $workingFolder->getResourceType(); + + if (null === $newFileName) { + $resourceTypeName = $resourceType->getName(); + $path = $workingFolder->getClientCurrentFolder(); + + if (!$acl->isAllowed($resourceTypeName, $path, Permission::FILE_DELETE)) { + throw new UnauthorizedException(sprintf('Unauthorized: no FILE_DELETE permission in %s:%s', $resourceTypeName, $path)); + } + } + + if (!Image::isSupportedExtension($editedImage->getExtension())) { + throw new InvalidExtensionException('Unsupported image type or not image file'); + } + + $image = Image::create($editedImage->getContents()); + + $actions = (array) $request->get('actions'); + + if (empty($actions)) { + throw new InvalidRequestException(); + } + + foreach ($actions as $actionInfo) { + if (!isset($actionInfo['action'])) { + throw new InvalidRequestException('ImageEdit: action name missing'); + } + + switch ($actionInfo['action']) { + case self::OPERATION_CROP: + if (!Utils::arrayContainsKeys($actionInfo, array('x', 'y', 'width', 'height'))) { + throw new InvalidRequestException(); + } + $x = $actionInfo['x']; + $y = $actionInfo['y']; + $width = $actionInfo['width']; + $height = $actionInfo['height']; + $image->crop($x, $y, $width, $height); + break; + + case self::OPERATION_ROTATE: + if (!isset($actionInfo['angle'])) { + throw new InvalidRequestException(); + } + $degrees = $actionInfo['angle']; + $bgcolor = isset($actionInfo['bgcolor']) ? $actionInfo['bgcolor'] : 0; + $image->rotate($degrees, $bgcolor); + break; + + case self::OPERATION_RESIZE: + if (!Utils::arrayContainsKeys($actionInfo, array('width', 'height'))) { + throw new InvalidRequestException(); + } + + $imagesConfig = $config->get('images'); + + $width = $imagesConfig['maxWidth'] && $actionInfo['width'] > $imagesConfig['maxWidth'] ? $imagesConfig['maxWidth'] : $actionInfo['width']; + $height = $imagesConfig['maxHeight'] && $actionInfo['height'] > $imagesConfig['maxHeight'] ? $imagesConfig['maxHeight'] : $actionInfo['height']; + $image->resize((int) $width, (int) $height, $imagesConfig['quality']); + break; + } + } + + $editFileEvent = new EditFileEvent($this->app, $editedImage); + + $editedImage->setNewContents($image->getData()); + $editedImage->setNewDimensions($image->getWidth(), $image->getHeight()); + + if (!$editedImage->isValid()) { + throw new InvalidUploadException('Invalid file provided'); + } + + $dispatcher->dispatch(CKFinderEvent::EDIT_IMAGE, $editFileEvent); + + $saved = false; + + if (!$editFileEvent->isPropagationStopped()) { + $saved = $editedImage->save($editFileEvent->getNewContents()); + + //Remove thumbnails and resized images in case if file is overwritten + if ($newFileName === null && $saved) { + $thumbnailRepository->deleteThumbnails($resourceType, $workingFolder->getClientCurrentFolder(), $fileName); + $resizedImageRepository->deleteResizedImages($resourceType, $workingFolder->getClientCurrentFolder(), $fileName); + } + } + + return array( + 'saved' => (int) $saved, + 'date' => Utils::formatDate(time()) + ); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/ImageInfo.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/ImageInfo.php new file mode 100644 index 0000000..0764e8b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/ImageInfo.php @@ -0,0 +1,76 @@ +get('fileName'); + + if (null === $fileName || !File::isValidName($fileName, $config->get('disallowUnsafeCharacters'))) { + throw new InvalidRequestException('Invalid file name'); + } + + if (!Image::isSupportedExtension(pathinfo($fileName, PATHINFO_EXTENSION))) { + throw new InvalidNameException('Invalid source file name'); + } + + if (!$workingFolder->containsFile($fileName)) { + throw new FileNotFoundException(); + } + + $cachePath = Path::combine( + $workingFolder->getResourceType()->getName(), + $workingFolder->getClientCurrentFolder(), + $fileName + ); + + $imageInfo = array(); + + $cachedInfo = $cache->get($cachePath); + + if ($cachedInfo && isset($cachedInfo['width']) && isset($cachedInfo['height'])) { + $imageInfo = $cachedInfo; + } else { + $file = new DownloadedFile($fileName, $this->app); + + if ($file->isValid()) { + $image = Image::create($file->getContents()); + $imageInfo = $image->getInfo(); + $cache->set($cachePath, $imageInfo); + } + } + + return $imageInfo; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/ImagePreview.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/ImagePreview.php new file mode 100644 index 0000000..08bf682 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/ImagePreview.php @@ -0,0 +1,123 @@ +query->get('fileName'); + list($requestedWidth, $requestedHeight) = Image::parseSize((string) $request->get('size')); + + $downloadedFile = new DownloadedFile($fileName, $this->app); + $downloadedFile->isValid(); + + if (!Image::isSupportedExtension(pathinfo($fileName, PATHINFO_EXTENSION), $config->get('thumbnails.bmpSupported'))) { + throw new InvalidExtensionException('Unsupported image type or not image file'); + } + + Utils::removeSessionCacheHeaders(); + + $response = new Response(); + $response->setPublic(); + $response->setEtag(dechex($downloadedFile->getTimestamp()) . "-" . dechex($downloadedFile->getSize())); + + $lastModificationDate = new \DateTime(); + $lastModificationDate->setTimestamp($downloadedFile->getTimestamp()); + + $response->setLastModified($lastModificationDate); + + if ($response->isNotModified($request)) { + return $response; + } + + $imagePreviewCacheExpires = (int) $config->get('cache.imagePreview'); + + if ($imagePreviewCacheExpires > 0) { + $response->setMaxAge($imagePreviewCacheExpires); + + $expireTime = new \DateTime(); + $expireTime->modify('+' . $imagePreviewCacheExpires . 'seconds'); + $response->setExpires($expireTime); + } + + $cachedInfoPath = Path::combine( + $workingFolder->getResourceType()->getName(), + $workingFolder->getClientCurrentFolder(), + $fileName + ); + + $cachedInfo = $cache->get($cachedInfoPath); + + $resultImage = null; + + // Try to reuse existing resized image + if ($cachedInfo && isset($cachedInfo['width']) && isset($cachedInfo['height'])) { + // Fix received aspect ratio + $size = Image::calculateAspectRatio($requestedWidth, $requestedHeight, $cachedInfo['width'], $cachedInfo['height']); + $resizedImage = $resizedImageRepository->getResizedImageBySize( + $workingFolder->getResourceType(), + $workingFolder->getClientCurrentFolder(), + $fileName, + $size['width'], + $size['height'] + ); + if ($resizedImage) { + $resultImage = Image::create($resizedImage->getImageData()); + } + } + + // Fallback - get and resize the original image + if (null === $resultImage) { + $resultImage = Image::create($downloadedFile->getContents(), $config->get('thumbnails.bmpSupported')); + $cache->set($cachedInfoPath, $resultImage->getInfo()); + $resultImage->resize($requestedWidth, $requestedHeight); + } + + $mimeType = $resultImage->getMimeType(); + + if (in_array($mimeType, array('image/bmp', 'image/x-ms-bmp'))) { + $mimeType = 'image/jpeg'; // Image::getData() by default converts resized images to JPG + } + + $response->headers->set('Content-Type', $mimeType. '; name="' . $downloadedFile->getFileName() . '"'); + $response->setContent($resultImage->getData()); + + return $response; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/ImageResize.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/ImageResize.php new file mode 100644 index 0000000..3fbf6d0 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/ImageResize.php @@ -0,0 +1,64 @@ +query->get('fileName'); + + if (null === $fileName || !File::isValidName($fileName, $config->get('disallowUnsafeCharacters'))) { + throw new InvalidRequestException('Invalid file name'); + } + + $ext = strtolower(pathinfo($fileName, PATHINFO_EXTENSION)); + + if (!Image::isSupportedExtension($ext)) { + throw new InvalidNameException('Invalid source file name'); + } + + if (!$workingFolder->containsFile($fileName)) { + throw new FileNotFoundException(); + } + + list($requestedWidth, $requestedHeight) = Image::parseSize((string) $request->query->get('size')); + + $resizedImage = $resizedImageRepository->getResizedImage( + $workingFolder->getResourceType(), + $workingFolder->getClientCurrentFolder(), + $fileName, + $requestedWidth, + $requestedHeight + ); + + return array('url' => $resizedImage->getUrl()); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/Init.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/Init.php new file mode 100644 index 0000000..49bc206 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/Init.php @@ -0,0 +1,183 @@ +enabled = true; + + $ln = ''; + $lc = str_replace('-', '', ($config->get('licenseKey') ?: $config->get('LicenseKey')) . ' '); + $pos = strpos(CKFinder::CHARS, $lc[2]) % 5; + + if ($pos == 1 || $pos == 2) { + $ln = $config->get('licenseName') ?: $config->get('LicenseName'); + } + + $data->s = $ln; + $data->c = trim($lc[1] . $lc[8] . $lc[17] . $lc[22] . $lc[3] . $lc[13] . $lc[11] . $lc[20] . $lc[5] . $lc[24] . $lc[27]); + + // Thumbnails + $thumbnailsConfig = $config->get('thumbnails'); + + $thumbnailsEnabled = (bool) $thumbnailsConfig['enabled']; + + if ($thumbnailsEnabled) { + $sizes = array(); + foreach ($thumbnailsConfig['sizes'] as $sizeInfo) { + $sizes[] = sprintf("%dx%d", $sizeInfo['width'], $sizeInfo['height']); + } + + $data->thumbs = $sizes; + } + + // Images + $imagesConfig = $config->get('images'); + + $images = array( + 'max' => $imagesConfig['maxWidth'] . 'x' . $imagesConfig['maxHeight'] + ); + + if (isset($imagesConfig['sizes'])) { + $resize = array(); + + foreach ($imagesConfig['sizes'] as $name => $sizeInfo) { + $resize[$name] = $sizeInfo['width'] . 'x' . $sizeInfo['height']; + } + + $images['sizes'] = $resize; + } + + $data->images = $images; + + $resourceTypesNames = $config->getDefaultResourceTypes() ? : $config->getResourceTypes(); + + $data->resourceTypes = array(); + + if (!empty($resourceTypesNames)) { + $phpMaxSize = 0; + + $maxUpload = Utils::returnBytes(ini_get('upload_max_filesize')); + if ($maxUpload) { + $phpMaxSize = $maxUpload; + } + + $maxPost = Utils::returnBytes(ini_get('post_max_size')); + if ($maxPost) { + $phpMaxSize = $phpMaxSize ? min($phpMaxSize, $maxPost) : $maxPost; + } + + //ini_get('memory_limit') only works if compiled with "--enable-memory-limit" + $memoryLimit = Utils::returnBytes(@ini_get('memory_limit')); + if ($memoryLimit && $memoryLimit != -1) { + $phpMaxSize = $phpMaxSize ? min($phpMaxSize, $memoryLimit) : $memoryLimit; + } + + $data->uploadMaxSize = $phpMaxSize; + $data->uploadCheckImages = !$config->get('checkSizeAfterScaling'); + + $requestedType = (string) $request->query->get('type'); + + foreach ($resourceTypesNames as $resourceTypeName) { + if ($requestedType && $requestedType !== $resourceTypeName) { + continue; + } + + $aclMask = $acl->getComputedMask($resourceTypeName, '/'); + + if (!(Permission::FOLDER_VIEW & $aclMask)) { + continue; + } + + $resourceType = $resourceTypeFactory->getResourceType($resourceTypeName); + + $resourceTypeObject = array( + 'name' => $resourceTypeName, + 'allowedExtensions' => implode(",", $resourceType->getAllowedExtensions()), + 'deniedExtensions' => implode(",", $resourceType->getDeniedExtensions()), + 'hash' => $resourceType->getHash(), + 'acl' => $aclMask, + 'maxSize' => $resourceType->getMaxSize() ? min($resourceType->getMaxSize(), $phpMaxSize) : $phpMaxSize + ); + + $resourceTypeBackend = $resourceType->getBackend(); + + if ($resourceType->isLazyLoaded()) { + $resourceTypeObject['hasChildren'] = false; + $resourceTypeObject['lazyLoad'] = true; + } else { + $resourceTypeObject['hasChildren'] = $resourceTypeBackend->containsDirectories($resourceType, $resourceType->getDirectory()); + } + + if ($label = $resourceType->getLabel()) { + $resourceTypeObject['label'] = $label; + } + + $useProxyCommand = $resourceTypeBackend->usesProxyCommand(); + + if ($useProxyCommand) { + $resourceTypeObject['useProxyCommand'] = true; + } else { + $baseUrl = $resourceTypeBackend->getBaseUrl(); + + if ($baseUrl) { + $resourceTypeObject['url'] = rtrim(Path::combine($baseUrl, $resourceType->getDirectory()), '/') . '/'; + } + } + + + $trackedOperations = $resourceTypeBackend->getTrackedOperations(); + + if (!empty($trackedOperations)) { + $resourceTypeObject['trackedOperations'] = $trackedOperations; + } + + $data->resourceTypes[] = $resourceTypeObject; + } + } + + $enabledPlugins = $config->get('plugins'); + + if (!empty($enabledPlugins)) { + $data->plugins = $enabledPlugins; + } + + $proxyCacheLifetime = (int) $config->get('cache.proxyCommand'); + + if ($proxyCacheLifetime) { + $data->proxyCache = $proxyCacheLifetime; + } + + return $data; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/MoveFiles.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/MoveFiles.php new file mode 100644 index 0000000..eaadcd1 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/MoveFiles.php @@ -0,0 +1,101 @@ +request->get('files'); + + $moved = 0; + + $errors = array(); + + // Initial validation + foreach ($movedFiles as $arr) { + if (!isset($arr['name'], $arr['type'], $arr['folder'])) { + throw new InvalidRequestException('Invalid request'); + } + + if (!$acl->isAllowed($arr['type'], $arr['folder'], Permission::FILE_VIEW | Permission::FILE_DELETE)) { + throw new UnauthorizedException('Unauthorized'); + } + } + + foreach ($movedFiles as $arr) { + if (empty($arr['name'])) { + continue; + } + + $name = $arr['name']; + $type = $arr['type']; + $folder = $arr['folder']; + + $resourceType = $resourceTypeFactory->getResourceType($type); + + $movedFile = new MovedFile($name, $folder, $resourceType, $this->app); + + $options = isset($arr['options']) ? $arr['options'] : ''; + + $movedFile->setCopyOptions($options); + + + if ($movedFile->isValid()) { + $moveFileEvent = new MoveFileEvent($this->app, $movedFile); + $dispatcher->dispatch(CKFinderEvent::MOVE_FILE, $moveFileEvent); + + if (!$moveFileEvent->isPropagationStopped()) { + if ($movedFile->doMove()) { + $moved++; + } + } + } + + $errors = array_merge($errors, $movedFile->getErrors()); + } + + $data = array('moved' => $moved); + + if (!empty($errors)) { + $data['error'] = array( + 'number' => Error::MOVE_FAILED, + 'errors' => $errors + ); + } + + return $data; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/Operation.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/Operation.php new file mode 100644 index 0000000..6a1d408 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/Operation.php @@ -0,0 +1,34 @@ +query->get('operationId'); + + /* @var \CKSource\CKFinder\Operation\OperationManager $operation */ + $operation = $this->app['operation']; + + if ($request->query->get('abort')) { + $operation->abort($operationId); + } + + return $operation->getStatus($operationId); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/Proxy.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/Proxy.php new file mode 100644 index 0000000..624c474 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/Proxy.php @@ -0,0 +1,128 @@ +query->get('fileName'); + $thumbnailFileName = (string) $request->query->get('thumbnail'); + + if (!File::isValidName($fileName, $config->get('disallowUnsafeCharacters'))) { + throw new InvalidRequestException(sprintf('Invalid file name: %s', $fileName)); + } + + $cacheLifetime = (int) $request->query->get('cache'); + + if (!$workingFolder->containsFile($fileName)) { + throw new FileNotFoundException(); + } + + if ($thumbnailFileName) { + if (!File::isValidName($thumbnailFileName, $config->get('disallowUnsafeCharacters'))) { + throw new InvalidRequestException(sprintf('Invalid resized image file name: %s', $fileName)); + } + + if (!$workingFolder->getResourceType()->isAllowedExtension(pathinfo($thumbnailFileName, PATHINFO_EXTENSION))) { + throw new InvalidExtensionException(); + } + + $resizedImageRespository = $this->app->getResizedImageRepository(); + $file = $resizedImageRespository->getExistingResizedImage( + $workingFolder->getResourceType(), + $workingFolder->getClientCurrentFolder(), + $fileName, + $thumbnailFileName + ); + $dataStream = $file->readStream(); + } else { + $file = new DownloadedFile($fileName, $this->app); + $file->isValid(); + $dataStream = $workingFolder->readStream($file->getFilename()); + } + + $proxyDownload = new ProxyDownloadEvent($this->app, $file); + + $dispatcher->dispatch(CKFinderEvent::PROXY_DOWNLOAD, $proxyDownload); + + if ($proxyDownload->isPropagationStopped()) { + throw new AccessDeniedException(); + } + + $response = new StreamedResponse(); + $response->headers->set('Content-Type', $file->getMimeType()); + $response->headers->set('Content-Length', $file->getSize()); + $response->headers->set('Content-Disposition', 'inline; filename="' . $fileName. '"'); + + if ($cacheLifetime > 0) { + Utils::removeSessionCacheHeaders(); + + $response->setPublic(); + $response->setEtag(dechex($file->getTimestamp()) . "-" . dechex($file->getSize())); + + $lastModificationDate = new \DateTime(); + $lastModificationDate->setTimestamp($file->getTimestamp()); + + $response->setLastModified($lastModificationDate); + + if ($response->isNotModified($request)) { + return $response; + } + + $response->setMaxAge($cacheLifetime); + + $expireTime = new \DateTime(); + $expireTime->modify('+' . $cacheLifetime . 'seconds'); + $response->setExpires($expireTime); + } + + $chunkSize = 1024 * 100; + + $response->setCallback(function () use ($dataStream, $chunkSize) { + if ($dataStream === false) { + return false; + } + while (!feof($dataStream)) { + echo fread($dataStream, $chunkSize); + flush(); + @set_time_limit(8); + } + + return true; + }); + + return $response; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/QuickUpload.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/QuickUpload.php new file mode 100644 index 0000000..14a5d28 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/QuickUpload.php @@ -0,0 +1,82 @@ +on(KernelEvents::RESPONSE, array($this, 'onQuickUploadResponse')); + } + + public function execute(Request $request, WorkingFolder $workingFolder, EventDispatcher $dispatcher, Config $config, CacheManager $cache, ThumbnailRepository $thumbsRepository) + { + // Don't add info about current folder to this command response + $workingFolder->omitResponseInfo(); + + $responseData = parent::execute($request, $workingFolder, $dispatcher, $config, $cache, $thumbsRepository); + + // Get url to a file + if (isset($responseData['fileName'])) { + $responseData['url'] = $workingFolder->getFileUrl($responseData['fileName']); + } + + return $responseData; + } + + public function onQuickUploadResponse(FilterResponseEvent $event) + { + $request = $event->getRequest(); + + if ($request->get('responseType') === 'json') { + return; + } + + $response = $event->getResponse(); + + $funcNum = (string) $request->get('CKEditorFuncNum'); + $funcNum = preg_replace('/[^0-9]/', '', $funcNum); + + if ($response instanceof JsonResponse) { + $responseData = $response->getData(); + + $fileUrl = isset($responseData['url']) ? $responseData['url'] : ''; + $errorMessage = isset($responseData['error']['message']) ? $responseData['error']['message'] : ''; + + ob_start(); + ?> + + setResponse(Response::create(ob_get_clean())); + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/RenameFile.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/RenameFile.php new file mode 100644 index 0000000..baa79e6 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/RenameFile.php @@ -0,0 +1,68 @@ +query->get('fileName'); + $newFileName = (string) $request->query->get('newFileName'); + + if (null === $fileName || null === $newFileName) { + throw new InvalidNameException('Invalid file name'); + } + + $renamedFile = new RenamedFile( + $newFileName, + $fileName, + $workingFolder->getClientCurrentFolder(), + $workingFolder->getResourceType(), + $this->app + ); + + $renamed = false; + + if ($renamedFile->isValid()) { + $renamedFileEvent = new RenameFileEvent($this->app, $renamedFile); + + $dispatcher->dispatch(CKFinderEvent::RENAME_FILE, $renamedFileEvent); + + if (!$renamedFileEvent->isPropagationStopped()) { + $renamed = $renamedFile->doRename(); + } + } + + return array( + 'name' => $fileName, + 'newName' => $renamedFile->getNewFileName(), + 'renamed' => (int) $renamed + ); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/RenameFolder.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/RenameFolder.php new file mode 100644 index 0000000..61486bc --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/RenameFolder.php @@ -0,0 +1,52 @@ +getClientCurrentFolder() === '/') { + throw new InvalidRequestException('Cannot rename resource type root folder'); + } + + $newFolderName = (string) $request->query->get('newFolderName'); + + $renameFolderEvent = new RenameFolderEvent($this->app, $workingFolder, $newFolderName); + + $dispatcher->dispatch(CKFinderEvent::RENAME_FOLDER, $renameFolderEvent); + + if (!$renameFolderEvent->isPropagationStopped()) { + $newFolderName = $renameFolderEvent->getNewFolderName(); + + return $workingFolder->rename($newFolderName); + } + + return array('renamed' => 0); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/SaveImage.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/SaveImage.php new file mode 100644 index 0000000..9e5b32d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/SaveImage.php @@ -0,0 +1,142 @@ +query->get('fileName'); + + $editedImage = new EditedImage($fileName, $this->app); + + $saveAsNew = false; + + if (!$editedImage->exists()) { + $saveAsNew = true; + $editedImage->saveAsNew(true); + } else { + // If file exists check for FILE_DELETE permission + $resourceTypeName = $workingFolder->getResourceType()->getName(); + $path = $workingFolder->getClientCurrentFolder(); + + if (!$acl->isAllowed($resourceTypeName, $path, Permission::FILE_DELETE)) { + throw new UnauthorizedException(sprintf('Unauthorized: no FILE_DELETE permission in %s:%s', $resourceTypeName, $path)); + } + } + + if (!Image::isSupportedExtension($editedImage->getExtension())) { + throw new InvalidExtensionException('Unsupported image type or not image file'); + } + + $imageFormat = Image::mimeTypeFromExtension($editedImage->getExtension()); + + $uploadedData = (string) $request->request->get('content'); + + if (null === $uploadedData || strpos($uploadedData, 'data:image/png;base64,') !== 0) { + throw new InvalidUploadException('Invalid upload. Expected base64 encoded PNG image.'); + } + + $data = explode(',', $uploadedData); + $data = isset($data[1]) ? base64_decode($data[1]) : false; + + if (!$data) { + throw new InvalidUploadException(); + } + + try { + $uploadedImage = Image::create($data); + } catch (\Exception $e) { + // No need to check if secureImageUploads is enabled - image must be valid here + throw new InvalidUploadException('Invalid upload: corrupted image', Error::UPLOADED_CORRUPT, array(), $e); + } + + $imagesConfig = $config->get('images'); + + if ($imagesConfig['maxWidth'] && $uploadedImage->getWidth() > $imagesConfig['maxWidth'] || + $imagesConfig['maxHeight'] && $uploadedImage->getHeight() > $imagesConfig['maxHeight']) { + $uploadedImage->resize($imagesConfig['maxWidth'], $imagesConfig['maxHeight'], $imagesConfig['quality']); + } + + $editedImage->setNewContents($uploadedImage->getData($imageFormat)); + $editedImage->setNewDimensions($uploadedImage->getWidth(), $uploadedImage->getHeight()); + + if (!$editedImage->isValid()) { + throw new InvalidUploadException('Invalid file provided'); + } + + $editFileEvent = new EditFileEvent($this->app, $editedImage); + + $imageInfo = $uploadedImage->getInfo(); + + $cache->set( + Path::combine( + $workingFolder->getResourceType()->getName(), + $workingFolder->getClientCurrentFolder(), + $fileName), + $uploadedImage->getInfo() + ); + + $dispatcher->dispatch(CKFinderEvent::SAVE_IMAGE, $editFileEvent); + + $saved = false; + + if (!$editFileEvent->isPropagationStopped()) { + $saved = $editedImage->save($editFileEvent->getNewContents()); + + if (!$saved) { + throw new AccessDeniedException("Couldn't save image file"); + } + + //Remove thumbnails and resized images in case if file is overwritten + if (!$saveAsNew && $saved) { + $resourceType = $workingFolder->getResourceType(); + $thumbnailRepository->deleteThumbnails($resourceType, $workingFolder->getClientCurrentFolder(), $fileName); + $resizedImageRepository->deleteResizedImages($resourceType, $workingFolder->getClientCurrentFolder(), $fileName); + } + } + + return array( + 'saved' => (int) $saved, + 'date' => Utils::formatDate(time()), + 'size' => Utils::formatSize($imageInfo['size']) + ); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/Thumbnail.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/Thumbnail.php new file mode 100644 index 0000000..d4121c4 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Command/Thumbnail.php @@ -0,0 +1,93 @@ +get('thumbnails.enabled')) { + throw new CKFinderException('Thumbnails feature is disabled', Error::THUMBNAILS_DISABLED); + } + + $fileName = (string) $request->get('fileName'); + + $ext = strtolower(pathinfo($fileName, PATHINFO_EXTENSION)); + + if (!Image::isSupportedExtension($ext, $thumbnailRepository->isBitmapSupportEnabled())) { + throw new InvalidNameException('Invalid source file name'); + } + + if (null === $fileName || !File::isValidName($fileName, $config->get('disallowUnsafeCharacters'))) { + throw new InvalidRequestException('Invalid file name'); + } + + if (!$workingFolder->containsFile($fileName)) { + throw new FileNotFoundException(); + } + + list($requestedWidth, $requestedHeight) = Image::parseSize((string) $request->get('size')); + + $thumbnail = $thumbnailRepository->getThumbnail($workingFolder->getResourceType(), + $workingFolder->getClientCurrentFolder(), $fileName, $requestedWidth, $requestedHeight); + + Utils::removeSessionCacheHeaders(); + + $response = new Response(); + $response->setPublic(); + $response->setEtag(dechex($thumbnail->getTimestamp()) . "-" . dechex($thumbnail->getSize())); + + $lastModificationDate = new \DateTime(); + $lastModificationDate->setTimestamp($thumbnail->getTimestamp()); + + $response->setLastModified($lastModificationDate); + + if ($response->isNotModified($request)) { + return $response; + } + + $thumbnailsCacheExpires = (int) $config->get('cache.thumbnails'); + + if ($thumbnailsCacheExpires > 0) { + $response->setMaxAge($thumbnailsCacheExpires); + + $expireTime = new \DateTime(); + $expireTime->modify('+' . $thumbnailsCacheExpires . 'seconds'); + $response->setExpires($expireTime); + } + + $response->headers->set('Content-Type', $thumbnail->getMimeType() . '; name="' . $thumbnail->getFileName() . '"'); + $response->setContent($thumbnail->getImageData()); + + return $response; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/CommandResolver.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/CommandResolver.php new file mode 100644 index 0000000..ca03e5a --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/CommandResolver.php @@ -0,0 +1,236 @@ +$_GET['command'] request variable. + * + * @copyright 2016 CKSource - Frederico Knabben + */ +class CommandResolver implements ControllerResolverInterface +{ + /** + * The name of the method to execute in commands classes. + */ + const COMMAND_EXECUTE_METHOD = 'execute'; + + /** + * The commands class namespace. + * + * @var string $commandsNamespace + */ + protected $commandsNamespace; + + /** + * The plugins class namespace. + * + * @var string $pluginsNamespace + */ + protected $pluginsNamespace; + + /** + * The app instance. + * + * @var CKFinder $app + */ + protected $app; + + /** + * Constructor. + * + * @param CKFinder $app + */ + public function __construct(CKFinder $app) + { + $this->app = $app; + } + + /** + * Sets the namespace used to resolve commands. + * + * @param string $namespace + */ + public function setCommandsNamespace($namespace) + { + $this->commandsNamespace = $namespace; + } + + /** + * Sets the namespace used to resolve plugin commands. + * + * @param string $namespace + */ + public function setPluginsNamespace($namespace) + { + $this->pluginsNamespace = $namespace; + } + + /** + * This method looks for a 'command' request attribute. An appropriate class + * is then instantiated and used to build a callable. + * + * @param Request $request current Request instance + * + * @return callable Callable built to execute the command. + * + * @throws InvalidCommandException if a valid command cannot be found. + * @throws MethodNotAllowedException if a command was called using an invalid HTTP method. + */ + public function getController(Request $request) + { + $commandName = ucfirst((string) $request->get('command')); + + /* @var Command\CommandAbstract $commandObject */ + $commandObject = null; + + // First check for regular command class + $commandClassName = $this->commandsNamespace . $commandName; + + if (class_exists($commandClassName)) { + $reflectedClass = new \ReflectionClass($commandClassName); + if (!$reflectedClass->isInstantiable()) { + throw new InvalidCommandException(sprintf('CKFinder command class %s is not instantiable', $commandClassName)); + } + $commandObject = new $commandClassName($this->app); + } + + // If not found - check if command plugin with given name exists + if (null === $commandObject) { + $plugin = $this->app->getPlugin($commandName); + if ($plugin instanceof CommandAbstract) { + $commandObject = $plugin; + } + } + + if (null === $commandObject) { + throw new InvalidCommandException(sprintf('CKFinder command %s not found', $commandName)); + } + + if (!$commandObject instanceof CommandAbstract) { + throw new InvalidCommandException(sprintf("CKFinder command must be a subclass of CommandAbstract (%s given)", get_class($commandObject))); + } + + if (!method_exists($commandObject, self::COMMAND_EXECUTE_METHOD)) { + throw new InvalidCommandException(sprintf("CKFinder command class %s doesn't contain required 'execute' method", $commandClassName)); + } + + if ($commandObject->getRequestMethod() !== $request->getMethod()) { + throw new MethodNotAllowedException(sprintf('CKFinder command %s expects to be called with %s HTTP request. Actual method: %s', + $commandName, $commandObject->getRequestMethod(), $request->getMethod())); + } + + /* @var $dispatcher \Symfony\Component\EventDispatcher\EventDispatcher */ + $dispatcher = $this->app['dispatcher']; + $beforeCommandEvent = new BeforeCommandEvent($this->app, $commandName, $commandObject); + + $eventName = CKFinderEvent::BEFORE_COMMAND_PREFIX . lcfirst($commandName); + + $dispatcher->dispatch($eventName, $beforeCommandEvent); + + $commandObject = $beforeCommandEvent->getCommandObject(); + + + $commandObject->checkPermissions(); + + return array($commandObject, self::COMMAND_EXECUTE_METHOD); + } + + /** + * This method is used to inject objects to controllers. + * It depends on arguments taken by the executed controller callable. + * + * Supported injected types: + * Request - current request object + * CKFinder - application object + * EventDispatcher - event dispatcher + * Config - Config object + * Acl - Acl object + * BackendManager - BackendManager object + * ResourceTypeFactory - ResourceTypeFactory object + * WorkingFolder - WorkingFolder object + * + * @param Request $request request object + * @param callable $command + * + * @return array arguments used during the command callable execution + */ + public function getArguments(Request $request, $command) + { + $r = new \ReflectionMethod($command[0], $command[1]); + + $parameters = $r->getParameters(); + + $arguments = array(); + + foreach ($parameters as $param) { + /* @var $param \ReflectionParameter */ + if ($reflectionClass = $param->getClass()) { + if ($reflectionClass->isInstance($this->app)) { + $arguments[] = $this->app; + } elseif ($reflectionClass->isInstance($request)) { + $arguments[] = $request; + } elseif ($reflectionClass->isInstance($this->app['dispatcher'])) { + $arguments[] = $this->app['dispatcher']; + } elseif ($reflectionClass->isInstance($this->app['config'])) { + $arguments[] = $this->app['config']; + } + + // Don't check isInstance to avoid unnecessary instantiation + $classShortName = $reflectionClass->getShortName(); + + switch ($classShortName) { + case 'BackendFactory': + $arguments[] = $this->app['backend_factory']; + break; + case 'ResourceTypeFactory': + $arguments[] = $this->app['resource_type_factory']; + break; + case 'Acl': + $arguments[] = $this->app['acl']; + break; + case 'WorkingFolder': + $arguments[] = $this->app['working_folder']; + break; + case 'ThumbnailRepository': + $arguments[] = $this->app['thumbnail_repository']; + break; + case 'ResizedImageRepository': + $arguments[] = $this->app['resized_image_repository']; + break; + case 'CacheManager': + $arguments[] = $this->app['cache']; + break; + } + } else { + $arguments[] = null; + } + } + + return $arguments; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Config.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Config.php new file mode 100644 index 0000000..afadebe --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Config.php @@ -0,0 +1,535 @@ +Important: If you use a PHP file to store your config, remember to use + * the return statement inside the file scope to return + * the array. + * + * @param array|string $config + * + * @throws InvalidConfigException if config was not loaded properly. + */ + public function __construct($config) + { + setlocale(LC_ALL, "en_US.utf8"); + + // Check if default timezone was set + try { + new \DateTime(); + } catch (\Exception $e) { + date_default_timezone_set('UTC'); + } + + if (is_string($config) && is_readable($config)) { + $options = require $config; + } else { + $options = $config; + } + + if (!is_array($options)) { + throw new InvalidConfigException("Couldn't load configuration. Please check configuration file."); + } + + $this->options = $this->mergeDefaultOptions($options); + + $this->validate(); + $this->process(); + } + + /** + * Merges default or missing configuration options. + * + * @param array $options options passed to CKFinder + * + * @return array + */ + protected function mergeDefaultOptions($options) + { + $defaults = array( + 'authentication' => function () { + return false; + }, + 'licenseName' => '', + 'licenseKey' => '', + 'privateDir' => array( + 'backend' => 'default', + 'tags' => '.ckfinder/tags', + 'logs' => '.ckfinder/logs', + 'cache' => '.ckfinder/cache', + 'thumbs' => '.ckfinder/cache/thumbs' + ), + 'images' => array( + 'maxWidth' => 500, + 'maxHeight' => 400, + 'quality' => 80, + 'sizes' => array( + 'small' => array('width' => 480, 'height' => 320, 'quality' => 80), + 'medium' => array('width' => 600, 'height' => 480, 'quality' => 80), + 'large' => array('width' => 800, 'height' => 600, 'quality' => 80) + ), + 'threshold' => array('pixels'=> 80, 'percent' => 10) + ), + 'thumbnails' => array( + 'enabled' => true, + 'sizes' => array( + array('width' => '150', 'height' => '150', 'quality' => 80), + array('width' => '300', 'height' => '300', 'quality' => 80), + array('width' => '500', 'height' => '500', 'quality' => 80), + ), + 'bmpSupported' => true, + ), + 'backends' => array( + array( + 'name' => 'default', + 'adapter' => 'local', + 'baseUrl' => '/userfiles/', + 'chmodFiles' => 0777, + 'chmodFolders' => 0777, + 'filesystemEncoding' => 'UTF-8' + ), + ), + 'defaultResourceTypes' => '', + 'resourceTypes' =>array( + array( + 'name' => 'Files', + 'directory' => 'files', + 'maxSize' => 0, + 'allowedExtensions' => '7z,aiff,asf,avi,bmp,csv,doc,docx,fla,flv,gif,gz,gzip,jpeg,jpg,mid,mov,mp3,mp4,mpc,mpeg,mpg,ods,odt,pdf,png,ppt,pptx,pxd,qt,ram,rar,rm,rmi,rmvb,rtf,sdc,sitd,swf,sxc,sxw,tar,tgz,tif,tiff,txt,vsd,wav,wma,wmv,xls,xlsx,zip', + 'deniedExtensions' => '', + 'backend' => 'default' + ), + array( + 'name' => 'Images', + 'directory' => 'images', + 'maxSize' => 0, + 'allowedExtensions' => 'bmp,gif,jpeg,jpg,png', + 'deniedExtensions' => '', + 'backend' => 'default' + ) + ), + 'roleSessionVar' => 'CKFinder_UserRole', + 'accessControl' => array( + array( + 'role' => '*', + 'resourceType' => '*', + 'folder' => '/', + + 'FOLDER_VIEW' => true, + 'FOLDER_CREATE' => true, + 'FOLDER_RENAME' => true, + 'FOLDER_DELETE' => true, + + 'FILE_VIEW' => true, + 'FILE_CREATE' => true, + 'FILE_RENAME' => true, + 'FILE_DELETE' => true, + + 'IMAGE_RESIZE' => true, + 'IMAGE_RESIZE_CUSTOM' => true + ), + ), + 'overwriteOnUpload' => false, + 'checkDoubleExtension' => true, + 'disallowUnsafeCharacters' => false, + 'secureImageUploads' => true, + 'checkSizeAfterScaling' => true, + 'htmlExtensions' => array('html', 'htm', 'xml', 'js'), + 'hideFolders' => array(".*", "CVS", "__thumbs"), + 'hideFiles' => array(".*"), + 'forceAscii' => false, + 'xSendfile' => false, + 'debug' => false, + 'pluginsDirectory' => __DIR__ . '/plugins', + 'plugins' => array(), + 'debugLoggers' => array('ckfinder_log', 'error_log', 'firephp'), + 'tempDirectory' => sys_get_temp_dir(), + 'sessionWriteClose' => true, + 'csrfProtection' => true + ); + + $options = array_merge($defaults, $options); + + foreach (array('privateDir', 'images', 'thumbnails') as $key) { + $options[$key] = array_merge($defaults[$key], $options[$key]); + } + + $resourceTypeDefaults = array( + 'name' => '', + 'directory' => '', + 'maxSize' => 0, + 'allowedExtensions' => '', + 'deniedExtensions' => '', + 'backend' => 'default' + ); + + foreach ($options['resourceTypes'] as &$resourceType) { + $resourceType = array_merge($resourceTypeDefaults, $resourceType); + } + + $localBackendDefaults = array( + 'chmodFiles' => 0755, + 'chmodFolders' => 0755, + 'filesystemEncoding' => 'UTF-8' + ); + + foreach ($options['backends'] as &$backend) { + if ($backend['adapter'] === 'local') { + $backend = array_merge($localBackendDefaults, $backend); + } + } + + $cacheDefaults = array( + 'imagePreview' => 24 * 3600, + 'thumbnails' => 24 * 3600 * 365, + 'proxyCommand' => 0 + ); + + $options['cache'] = array_replace($cacheDefaults, isset($options['cache']) ? $options['cache'] : array()); + + // #205 Backward compatibility for old debug_loggers option + if (isset($options['debug_loggers'])) { + $options['debugLoggers'] = $options['debug_loggers']; + } + + return $options; + } + + /** + * Returns the configuration node under the path defined in the parameter. + * + * For easier access to nested configuration options the config `$name` + * parameter can be passed also as a dot-separated path. + * For example, to check if thumbnails are enabled you can use: + * + * $config->get('thumbnails.enabled') + * + * @param string $name config node name + * + * @return mixed config node value + * + */ + public function get($name) + { + if (isset($this->options[$name])) { + return $this->options[$name]; + } + + $keys = explode('.', $name); + $array = $this->options; + + do { + $key = array_shift($keys); + if (isset($array[$key])) { + if ($keys) { + if (is_array($array[$key])) { + $array = $array[$key]; + } else { + break; + } + } else { + return $array[$key]; + } + } else { + break; + } + } while ($keys); + + return null; + } + + /** + * Validates the config array structure. + * + * @throws InvalidConfigException if config structure is invalid. + */ + protected function validate() + { + $checkMissingNodes = function (array $required, array $actual, $prefix = '') { + $missing = array_keys(array_diff_key(array_flip($required), $actual)); + + if (!empty($missing)) { + throw new InvalidConfigException(sprintf( + "CKFinder configuration doesn't contain all required fields. " . + "Please check configuration file. Missing fields: %s", + ($prefix ? "{$prefix}: " : '') . implode(', ', $missing))); + } + }; + + $requiredRootNodes = array('authentication', 'licenseName', 'licenseKey', 'privateDir', 'images', + 'backends', 'defaultResourceTypes', 'resourceTypes', 'roleSessionVar', 'accessControl', + 'checkDoubleExtension', 'disallowUnsafeCharacters', 'secureImageUploads', 'checkSizeAfterScaling', + 'htmlExtensions', 'hideFolders', 'hideFiles', 'forceAscii', 'xSendfile', 'debug', 'pluginsDirectory', 'plugins'); + + $checkMissingNodes($requiredRootNodes, $this->options); + $checkMissingNodes(array('backend', 'tags', 'logs', 'cache', 'thumbs'), $this->options['privateDir'], '[privateDir]'); + $checkMissingNodes(array('maxWidth', 'maxHeight', 'quality'), $this->options['images'], '[images]'); + + $backends = array(); + + foreach ($this->options['backends'] as $i => $backendConfig) { + $checkMissingNodes(array('name', 'adapter'), $backendConfig, "[backends][{$i}]"); + $backends[] = $backendConfig['name']; + } + + foreach ($this->options['resourceTypes'] as $i => $resourceTypeConfig) { + $checkMissingNodes(array('name', 'directory', 'maxSize', 'allowedExtensions', 'deniedExtensions', 'backend'), + $resourceTypeConfig, "[resourceTypes][{$i}]"); + + if (!in_array($resourceTypeConfig['backend'], $backends)) { + throw new InvalidConfigException("Backend '{$resourceTypeConfig['backend']}' is not defined: [resourceTypes][{$i}]"); + } + } + + foreach ($this->options['accessControl'] as $i => $aclConfig) { + $checkMissingNodes(array('role', 'resourceType', 'folder'), $aclConfig, "[accessControl][{$i}]"); + } + + if (!is_callable($this->options['authentication'])) { + throw new InvalidConfigException("CKFinder Authentication config field must be a PHP callable"); + } + + if (!is_writable($this->options['tempDirectory'])) { + throw new InvalidConfigException("The temporary folder is not writable for CKFinder"); + } + } + + /** + * Processes the configuration array. + */ + protected function process() + { + $this->options['defaultResourceTypes'] = + array_filter( + array_map('trim', + explode(',', $this->options['defaultResourceTypes']) + ), + 'strlen'); + + + $formatToArray = function ($input) { + $input = is_array($input) ? $input : explode(',', $input); + + return + array_filter( + array_map('strtolower', + array_map('trim', $input) + ), + 'strlen'); + }; + + foreach ($this->options['resourceTypes'] as $resourceTypeKey => $resourceTypeConfig) { + $resourceTypeConfig['allowedExtensions'] = $formatToArray($resourceTypeConfig['allowedExtensions']); + $resourceTypeConfig['deniedExtensions'] = $formatToArray($resourceTypeConfig['deniedExtensions']); + $resourceTypeConfig['maxSize'] = Utils::returnBytes((string) $resourceTypeConfig['maxSize']); + + $this->options['resourceTypes'][$resourceTypeConfig['name']] = $resourceTypeConfig; + + if ($resourceTypeKey !== $resourceTypeConfig['name']) { + unset($this->options['resourceTypes'][$resourceTypeKey]); + } + } + + foreach ($this->options['backends'] as $backendKey => $backendConfig) { + $this->options['backends'][$backendConfig['name']] = $backendConfig; + + if ($backendKey !== $backendConfig['name']) { + unset($this->options['backends'][$backendKey]); + } + } + + $this->options['htmlExtensions'] = $formatToArray($this->options['htmlExtensions']); + } + + /** + * Returns the default resource types names. + * + * @return array + */ + public function getDefaultResourceTypes() + { + return $this->options['defaultResourceTypes']; + } + + /** + * Returns all defined resource types names. + * + * @return array + */ + public function getResourceTypes() + { + return array_keys($this->options['resourceTypes']); + } + + /** + * Returns the configuration node for a given resource type. + * + * @param string $resourceType resource type name + * + * @return array configuration node for the resource type + * + * @throws InvalidResourceTypeException if the resource type does not exist + */ + public function getResourceTypeNode($resourceType) + { + if (array_key_exists($resourceType, $this->options['resourceTypes'])) { + return $this->options['resourceTypes'][$resourceType]; + } else { + throw new InvalidResourceTypeException("Invalid resource type: {$resourceType}"); + } + } + + /** + * Returns the regex used for hidden files check. + * @return string + */ + public function getHideFilesRegex() + { + static $hideFilesRegex; + + if (!isset($hideFilesRegex)) { + $hideFilesConfig = $this->options['hideFiles']; + + if ($hideFilesConfig && is_array($hideFilesConfig)) { + $hideFilesRegex = join("|", $hideFilesConfig); + $hideFilesRegex = strtr($hideFilesRegex, array("?" => "__QMK__", "*" => "__AST__", "|" => "__PIP__")); + $hideFilesRegex = preg_quote($hideFilesRegex, "/"); + $hideFilesRegex = strtr($hideFilesRegex, array("__QMK__" => ".", "__AST__" => ".*", "__PIP__" => "|")); + $hideFilesRegex = "/^(?:" . $hideFilesRegex . ")$/uim"; + } else { + $hideFilesRegex = ""; + } + } + + return $hideFilesRegex; + } + + /** + * Returns the regex used for hidden folders check. + * @return string + */ + public function getHideFoldersRegex() + { + static $hideFoldersRegex; + + if (!isset($hideFoldersRegex)) { + $hideFoldersConfig = $this->options['hideFolders']; + + if ($hideFoldersConfig && is_array($hideFoldersConfig)) { + $hideFoldersRegex = join("|", $hideFoldersConfig); + $hideFoldersRegex = strtr($hideFoldersRegex, array("?" => "__QMK__", "*" => "__AST__", "|" => "__PIP__")); + $hideFoldersRegex = preg_quote($hideFoldersRegex, "/"); + $hideFoldersRegex = strtr($hideFoldersRegex, array("__QMK__" => ".", "__AST__" => ".*", "__PIP__" => "|")); + $hideFoldersRegex = "/^(?:" . $hideFoldersRegex . ")$/uim"; + } else { + $hideFoldersRegex = ""; + } + } + + return $hideFoldersRegex; + } + + /** + * If the config node does not exist, creates the node with a given name and values. + * Otherwise extends the config node with additional (default) values. + * + * @param string $nodeName + * @param array $values + */ + public function extend($nodeName, array $values) + { + if (!isset($this->options[$nodeName])) { + $this->options[$nodeName] = $values; + } else { + $this->options[$nodeName] = array_replace_recursive($values, $this->options[$nodeName]); + } + } + + /** + * Returns the backend-relative private directory path. + * + * @param string $privateDirIdentifier + * + * @return mixed + */ + public function getPrivateDirPath($privateDirIdentifier) + { + if (!array_key_exists($privateDirIdentifier, $this->options['privateDir'])) { + throw new \InvalidArgumentException(sprintf('Private dir with identifier %s not found. Please check configuration file.', $privateDirIdentifier)); + } + + $privateDir = $this->options['privateDir'][$privateDirIdentifier]; + + if (is_array($privateDir) && array_key_exists('path', $privateDir)) { + return $privateDir['path']; + } + + return $privateDir; + } + + /** + * Checks if the debug logger with a given name is enabled. + * @param string $loggerName debug logger name + * + * @return bool `true` if enabled + */ + public function isDebugLoggerEnabled($loggerName) + { + return in_array($loggerName, $this->options['debugLoggers']); + } + + /** + * Returns backend configuration by name. + * + * @param string $backendName + * + * @return array backend configuration node + * + * @throws \InvalidArgumentException + */ + public function getBackendNode($backendName) + { + if (array_key_exists($backendName, $this->options['backends'])) { + return $this->options['backends'][$backendName]; + } else { + throw new \InvalidArgumentException(sprintf('Backend %s not found. Please check configuration file.', $backendName)); + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/ContainerAwareInterface.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/ContainerAwareInterface.php new file mode 100644 index 0000000..35486f6 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/ContainerAwareInterface.php @@ -0,0 +1,26 @@ +commandName = $commandName; + $this->response = $response; + + parent::__construct($app); + } + + /** + * Returns the response object received from the command. + * + * @return Response + */ + public function getResponse() + { + return $this->response; + } + + /** + * Sets the response to be returned. + * + * @param Response $response + */ + public function setResponse(Response $response) + { + $this->response = $response; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Event/BeforeCommandEvent.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Event/BeforeCommandEvent.php new file mode 100644 index 0000000..cbae027 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Event/BeforeCommandEvent.php @@ -0,0 +1,83 @@ +commandName = $commandName; + $this->commandObject = $commandObject; + + parent::__construct($app); + } + + /** + * Returns the command object. + * + * @return CommandAbstract + */ + public function getCommandObject() + { + return $this->commandObject; + } + + /** + * Sets the object of the command to be executed. + * + * @param CommandAbstract $commandObject + */ + public function setCommandObject(CommandAbstract $commandObject) + { + $this->commandObject = $commandObject; + } + + /** + * Returns the name of the command. + * + * @return string command name + */ + public function getCommandName() + { + return $this->commandName; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Event/CKFinderEvent.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Event/CKFinderEvent.php new file mode 100644 index 0000000..dae3b13 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Event/CKFinderEvent.php @@ -0,0 +1,145 @@ +app = $app; + } + + /** + * Returns the application dependency injection container. + * + * @return CKFinder + */ + public function getContainer() + { + return $this->app; + } + + /** + * Returns the current request object. + * + * @return Request|null + */ + public function getRequest() + { + return $this->app['request_stack']->getCurrentRequest(); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Event/CopyFileEvent.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Event/CopyFileEvent.php new file mode 100644 index 0000000..261c45c --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Event/CopyFileEvent.php @@ -0,0 +1,64 @@ +copiedFile = $copiedFile; + + parent::__construct($app); + } + + /** + * Returns the copied file object. + * + * @return CopiedFile + * + * @deprecated Please use getFile() instead. + */ + public function getCopiedFile() + { + return $this->copiedFile; + } + + /** + * Returns the copied file object. + * + * @return CopiedFile + */ + public function getFile() + { + return $this->copiedFile; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Event/CreateFolderEvent.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Event/CreateFolderEvent.php new file mode 100644 index 0000000..1ebb786 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Event/CreateFolderEvent.php @@ -0,0 +1,83 @@ +workingFolder = $workingFolder; + $this->newFolderName = $newFolderName; + + parent::__construct($app); + } + + /** + * Returns the working folder where the new folder is going to be created. + * + * @return WorkingFolder + */ + public function getWorkingFolder() + { + return $this->workingFolder; + } + + /** + * Returns the name of the new folder. + * + * @return string + */ + public function getNewFolderName() + { + return $this->newFolderName; + } + + /** + * Sets the name for the new folder. + * + * @param string $newFolderName + */ + public function setNewFolderName($newFolderName) + { + $this->newFolderName = $newFolderName; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Event/DeleteFileEvent.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Event/DeleteFileEvent.php new file mode 100644 index 0000000..3a5307f --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Event/DeleteFileEvent.php @@ -0,0 +1,64 @@ +deletedFile = $deletedFile; + + parent::__construct($app); + } + + /** + * Returns the deleted file object. + * + * @return DeletedFile + * + * @deprecated Please use getFile() instead. + */ + public function getDeletedFile() + { + return $this->deletedFile; + } + + /** + * Returns the deleted file object. + * + * @return DeletedFile + */ + public function getFile() + { + return $this->deletedFile; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Event/DeleteFolderEvent.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Event/DeleteFolderEvent.php new file mode 100644 index 0000000..cefe24d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Event/DeleteFolderEvent.php @@ -0,0 +1,54 @@ +workingFolder = $workingFolder; + + parent::__construct($app); + } + + /** + * Returns the working folder that is going to be deleted. + * + * @return WorkingFolder + */ + public function getWorkingFolder() + { + return $this->workingFolder; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Event/DownloadFileEvent.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Event/DownloadFileEvent.php new file mode 100644 index 0000000..855df2d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Event/DownloadFileEvent.php @@ -0,0 +1,64 @@ +downloadedFile = $downloadedFile; + + parent::__construct($app); + } + + /** + * Returns the downloaded file object. + * + * @return DownloadedFile + * + * @deprecated Please use getFile() instead. + */ + public function getDownloadedFile() + { + return $this->downloadedFile; + } + + /** + * Returns the downloaded file object. + * + * @return DownloadedFile + */ + public function getFile() + { + return $this->downloadedFile; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Event/EditFileEvent.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Event/EditFileEvent.php new file mode 100644 index 0000000..d7b04a8 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Event/EditFileEvent.php @@ -0,0 +1,89 @@ +editedFile = $editedFile; + + parent::__construct($app); + } + + /** + * Returns the edited file object. + * + * @return EditedFile + * + * @deprecated Please use getFile() instead. + */ + public function getEditedFile() + { + return $this->editedFile; + } + + /** + * Returns the edited file object. + * + * @return EditedFile + */ + public function getFile() + { + return $this->editedFile; + } + + /** + * Returns new contents of the edited file. + * + * @return string + */ + public function getNewContents() + { + return $this->editedFile->getNewContents(); + } + + /** + * Sets new contents for the edited file. + * + * @param string $newContents + */ + public function setNewContents($newContents) + { + $this->editedFile->setNewContents($newContents); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Event/FileUploadEvent.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Event/FileUploadEvent.php new file mode 100644 index 0000000..0b54e76 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Event/FileUploadEvent.php @@ -0,0 +1,64 @@ +uploadedFile = $uploadedFile; + + parent::__construct($app); + } + + /** + * Returns the uploaded file object. + * + * @return UploadedFile + * + * @deprecated Please use getFile() instead. + */ + public function getUploadedFile() + { + return $this->uploadedFile; + } + + /** + * Returns the uploaded file object. + * + * @return UploadedFile + */ + public function getFile() + { + return $this->uploadedFile; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Event/MoveFileEvent.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Event/MoveFileEvent.php new file mode 100644 index 0000000..28d672a --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Event/MoveFileEvent.php @@ -0,0 +1,64 @@ +movedFile = $movedFile; + + parent::__construct($app); + } + + /** + * Returns the moved file object. + * + * @return MovedFile + * + * @deprecated Please use getFile() instead. + */ + public function getMovedFile() + { + return $this->movedFile; + } + + /** + * Returns the moved file object. + * + * @return MovedFile + */ + public function getFile() + { + return $this->movedFile; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Event/ProxyDownloadEvent.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Event/ProxyDownloadEvent.php new file mode 100644 index 0000000..36f95a7 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Event/ProxyDownloadEvent.php @@ -0,0 +1,53 @@ +downloadedFile = $downloadedFile; + + parent::__construct($app); + } + + /** + * Returns the downloaded file object. + * + * @return DownloadedFile|ResizedImage + */ + public function getFile() + { + return $this->downloadedFile; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Event/RenameFileEvent.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Event/RenameFileEvent.php new file mode 100644 index 0000000..0eaed7f --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Event/RenameFileEvent.php @@ -0,0 +1,64 @@ +renamedFile = $renamedFile; + + parent::__construct($app); + } + + /** + * Returns the renamed file object. + * + * @return RenamedFile + * + * @deprecated Please use getFile() instead. + */ + public function getRenamedFile() + { + return $this->renamedFile; + } + + /** + * Returns the renamed file object. + * + * @return RenamedFile + */ + public function getFile() + { + return $this->renamedFile; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Event/RenameFolderEvent.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Event/RenameFolderEvent.php new file mode 100644 index 0000000..02992a6 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Event/RenameFolderEvent.php @@ -0,0 +1,83 @@ +workingFolder = $workingFolder; + $this->newFolderName = $newFolderName; + + parent::__construct($app); + } + + /** + * Returns the working folder where the new folder is going to be renamed. + * + * @return WorkingFolder + */ + public function getWorkingFolder() + { + return $this->workingFolder; + } + + /** + * Returns the new name of the folder. + * + * @return string + */ + public function getNewFolderName() + { + return $this->newFolderName; + } + + /** + * Sets the new name for the folder. + * + * @param string $newFolderName + */ + public function setNewFolderName($newFolderName) + { + $this->newFolderName = $newFolderName; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Event/ResizeImageEvent.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Event/ResizeImageEvent.php new file mode 100644 index 0000000..1ce3f6f --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Event/ResizeImageEvent.php @@ -0,0 +1,60 @@ +resizedImage = $resizedImage; + } + + /** + * Returns the resized image object. + * + * @return ResizedImageAbstract + */ + public function getResizedImage() + { + return $this->resizedImage; + } + + /** + * Sets the resized image object. + * + * @param ResizedImageAbstract $resizedImage + */ + public function setResizedImage(ResizedImageAbstract $resizedImage) + { + $this->resizedImage = $resizedImage; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Exception/AccessDeniedException.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Exception/AccessDeniedException.php new file mode 100644 index 0000000..1803cad --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Exception/AccessDeniedException.php @@ -0,0 +1,43 @@ +parameters = $parameters; + + parent::__construct($message, $code, $previous); + } + + /** + * Returns parameters used for replacements during translation. + * + * @return array + */ + public function getParameters() + { + return $this->parameters; + } + + /** + * Returns the HTTP status code for this exception. + * + * @return int HTTP status code for exception + */ + public function getHttpStatusCode() + { + return $this->httpStatusCode; + } + + /** + * Sets the HTTP status code for this exception. + * + * @param int $httpStatusCode + * + * @return $this + */ + public function setHttpStatusCode($httpStatusCode) + { + $this->httpStatusCode = $httpStatusCode; + + return $this; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Exception/FileNotFoundException.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Exception/FileNotFoundException.php new file mode 100644 index 0000000..130ed2d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Exception/FileNotFoundException.php @@ -0,0 +1,42 @@ +translator = $translator; + $this->debug = $debug; + $this->logger = $logger; + + if ($debug) { + set_error_handler(array($this, 'errorHandler')); + } + } + + public function onCKFinderError(GetResponseForExceptionEvent $event) + { + $exception = $event->getException(); + + $exceptionCode = $exception->getCode() ?: Error::UNKNOWN; + + $replacements = array(); + + $httpStatusCode = 200; + + if ($exception instanceof CKFinderException) { + $replacements = $exception->getParameters(); + $httpStatusCode = $exception->getHttpStatusCode(); + } + + $message = + $exceptionCode === Error::CUSTOM_ERROR + ? $exception->getMessage() + : $this->translator->translateErrorMessage($exceptionCode, $replacements); + + $response = JsonResponse::create()->withError($exceptionCode, $message); + + $event->setException(new HttpException($httpStatusCode)); + + $event->setResponse($response); + + if ($this->debug && $this->logger) { + $this->logger->error($exception); + } + + if (filter_var(ini_get('display_errors'), FILTER_VALIDATE_BOOLEAN)) { + throw $exception; + } + } + + /** + * Custom error handler to catch all errors in the debug mode. + * + * @param int $errno + * @param string $errstr + * @param string $errfile + * @param int $errline + * + * @throws \Exception + */ + public function errorHandler($errno, $errstr, $errfile, $errline) + { + $wrapperException = new \ErrorException($errstr, 0, $errno, $errfile, $errline); + $this->logger->warning($wrapperException); + + if (filter_var(ini_get('display_errors'), FILTER_VALIDATE_BOOLEAN)) { + throw $wrapperException; + } + } + + /** + * Returns all events and callbacks. + * + * @see EventSubscriberInterface + * + * @return array + */ + public static function getSubscribedEvents() + { + return array(KernelEvents::EXCEPTION => array('onCKFinderError', -255)); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Filesystem/File/CopiedFile.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Filesystem/File/CopiedFile.php new file mode 100644 index 0000000..4515b50 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Filesystem/File/CopiedFile.php @@ -0,0 +1,278 @@ +targetFolder = $app['working_folder']; + + $this->sourceFileName = $fileName; + + parent::__construct($fileName, $folder, $resourceType, $app); + } + + /** + * Returns the target folder for a copied file. + * + * @return WorkingFolder + */ + public function getTargetFolder() + { + return $this->targetFolder; + } + + public function getFileName() + { + return $this->sourceFileName; + } + + /** + * Sets copy options. + * + * @param string $copyOptions + * + * @see CopiedFile::$copyOptions + */ + public function setCopyOptions($copyOptions) + { + $this->copyOptions = $copyOptions; + } + + /** + * Checks if the file has an extension allowed in both source and target ResourceTypes. + * + * @return bool `true` if the file has an extension allowed in source and target directories. + */ + public function hasAllowedExtension() + { + if (strpos($this->fileName, '.') === false) { + return true; + } + + $extension = $this->getExtension(); + + return parent::hasAllowedExtension() && + $this->targetFolder->getResourceType()->isAllowedExtension($extension); + } + + /** + * Checks if the copied file size does not exceed the file size limit set for the target folder. + * + * @return bool + */ + public function hasAllowedSize() + { + $filePath = $this->getFilePath(); + $backend = $this->resourceType->getBackend(); + + if (!$backend->has($filePath)) { + return false; + } + + $fileMetadata = $backend->getMetadata($filePath); + + $fileSize = $fileMetadata['size']; + + $maxSize = $this->targetFolder->getResourceType()->getMaxSize(); + + if ($maxSize && $fileSize > $maxSize) { + return false; + } + + return true; + } + + /** + * @copydoc File::autorename() + */ + public function autorename(Backend $backend = null, $path = '') + { + return parent::autorename($this->targetFolder->getBackend(), $this->targetFolder->getPath()); + } + + /** + * Copies the current file. + * + * @return bool `true` if the file was copied successfully. + * + * @throws \Exception + */ + public function doCopy() + { + $originalFileStream = $this->getContentsStream(); + + // Don't copy file to itself + if ($this->targetFolder->getBackend() === $this->resourceType->getBackend() && + $this->targetFolder->getPath() === $this->getPath()) { + $this->addError(Error::SOURCE_AND_TARGET_PATH_EQUAL); + + return false; + } + + $targetFilename = $this->getTargetFilename(); + + if ($this->targetFolder->containsFile($targetFilename) && strpos($this->copyOptions, 'overwrite') === false) { + $this->addError(Error::ALREADY_EXIST); + + return false; + } + + if ($this->targetFolder->putStream($targetFilename, $originalFileStream)) { + $resizedImageRepository = $this->resourceType->getResizedImageRepository(); + $resizedImageRepository->copyResizedImages( + $this->resourceType, $this->folder, $this->sourceFileName, + $this->targetFolder->getResourceType(), $this->targetFolder->getClientCurrentFolder(), $targetFilename + ); + + $this->getCache()->copy( + Path::combine($this->resourceType->getName(), $this->folder, $this->sourceFileName), + Path::combine($this->targetFolder->getResourceType()->getName(), $this->targetFolder->getClientCurrentFolder(), $targetFilename) + ); + + return true; + } else { + $this->addError(Error::ACCESS_DENIED); + + return false; + } + } + + /** + * Returns the target file name of the copied file. + * + * @return string + */ + public function getTargetFilename() + { + if ($this->targetFolder->containsFile($this->getFilename()) && + strpos($this->copyOptions, 'overwrite') === false && + strpos($this->copyOptions, 'autorename') !== false) { + $this->autorename(); + } + + return $this->fileName; + } + + /** + * Returns the source file name of the copied file. + * + * @return string + */ + public function getSourceFilename() + { + return $this->sourceFileName; + } + + /** + * Returns the target path of the copied file. + * + * @return string + */ + public function getTargetFilePath() + { + return Path::combine($this->getTargetFolder()->getPath(), $this->getTargetFilename()); + } + + /** + * Returns the source file name of the copied file. + * + * @return string + */ + public function getSourceFilePath() + { + return Path::combine($this->getPath(), $this->sourceFileName); + } + + /** + * Validates the copied file. + * + * @return bool `true` if the copied file is valid and ready to be copied. + * + * @throws \Exception + */ + public function isValid() + { + if (!$this->hasValidFilename() || !$this->hasValidPath()) { + throw new InvalidRequestException('Invalid filename or path'); + } + + if (!$this->hasAllowedExtension()) { + $this->addError(Error::INVALID_EXTENSION); + + return false; + } + + if ($this->isHidden() || $this->hasHiddenPath()) { + throw new InvalidRequestException('Copied file is hidden'); + } + + if (!$this->exists()) { + $this->addError(Error::FILE_NOT_FOUND); + + return false; + } + + if (!$this->hasAllowedSize()) { + $this->addError(Error::UPLOADED_TOO_BIG); + + return false; + } + + return true; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Filesystem/File/DeletedFile.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Filesystem/File/DeletedFile.php new file mode 100644 index 0000000..e3722cf --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Filesystem/File/DeletedFile.php @@ -0,0 +1,73 @@ +resourceType->getBackend()->delete($this->getFilePath())) { + $this->deleteThumbnails(); + $this->deleteResizedImages(); + $this->getCache()->delete(Path::combine($this->resourceType->getName(), $this->folder, $this->getFilename())); + + return true; + } else { + $this->addError(Error::ACCESS_DENIED); + + return false; + } + } + + public function isValid() + { + if (!$this->hasValidFilename() || !$this->hasValidPath()) { + throw new InvalidRequestException('Invalid filename or path'); + } + + if (!$this->hasAllowedExtension()) { + throw new InvalidExtensionException(); + } + + if ($this->isHidden() || $this->hasHiddenPath()) { + throw new InvalidRequestException('Deleted file is hidden'); + } + + if (!$this->exists()) { + $this->addError(Error::FILE_NOT_FOUND); + + return false; + } + + return true; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Filesystem/File/DownloadedFile.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Filesystem/File/DownloadedFile.php new file mode 100644 index 0000000..68930d7 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Filesystem/File/DownloadedFile.php @@ -0,0 +1,117 @@ +workingFolder = $app['working_folder']; + + parent::__construct($fileName, $this->workingFolder->getClientCurrentFolder(), $this->workingFolder->getResourceType(), $app); + } + + /** + * Returns the folder of the downloaded file. + * + * @return WorkingFolder + */ + public function getWorkingFolder() + { + return $this->workingFolder; + } + + /** + * Validates the downloaded file. + * + * @throws \Exception + * + * @return boolean `true` if the file passed validation. + */ + public function isValid() + { + if (!$this->hasValidFilename()) { + throw new InvalidNameException('Invalid file name'); + } + + if (!$this->hasAllowedExtension()) { + throw new InvalidExtensionException(); + } + + if ($this->isHidden() || !$this->exists()) { + throw new FileNotFoundException(); + } + + return true; + } + + /** + * Checks if the file extension is allowed. + * + * @return bool `true` if an extension is allowed. + */ + public function hasAllowedExtension() + { + if (strpos($this->fileName, '.') === false) { + return true; + } + + $extension = $this->getExtension(); + + return $this->workingFolder->getResourceType()->isAllowedExtension($extension); + } + + /** + * Checks if the file is hidden. + * + * @return bool `true` if the file is hidden. + */ + public function isHidden() + { + return $this->workingFolder->getBackend()->isHiddenFile($this->fileName); + } + + /** + * Checks if the file exists. + * + * @return bool `true` if the file exists. + */ + public function exists() + { + return $this->workingFolder->containsFile($this->fileName); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Filesystem/File/EditedFile.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Filesystem/File/EditedFile.php new file mode 100644 index 0000000..5d4f2c9 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Filesystem/File/EditedFile.php @@ -0,0 +1,234 @@ +workingFolder = $app['working_folder']; + $this->newFileName = $newFileName; + + parent::__construct($fileName, $this->workingFolder->getClientCurrentFolder(), $this->workingFolder->getResourceType(), $app); + } + + /** + * Validates the file. + * + * @return bool `true` if the file passed validation. + * + * @throws AlreadyExistsException + * @throws FileNotFoundException + * @throws InvalidExtensionException + * @throws InvalidNameException + * @throws InvalidRequestException + * @throws InvalidUploadException + */ + public function isValid() + { + if ($this->newFileName) { + if (!File::isValidName($this->newFileName, $this->config->get('disallowUnsafeCharacters'))) { + throw new InvalidNameException('Invalid file name'); + } + + if ($this->resourceType->getBackend()->isHiddenFile($this->newFileName)) { + throw new InvalidRequestException('New provided file name is hidden'); + } + + if (!$this->resourceType->isAllowedExtension($this->getNewExtension())) { + throw new InvalidExtensionException(); + } + + if ($this->config->get('checkDoubleExtension') && !$this->areValidDoubleExtensions($this->newFileName)) { + throw new InvalidExtensionException(); + } + + if ($this->workingFolder->containsFile($this->newFileName)) { + throw new AlreadyExistsException('File already exists'); + } + } + + if (!$this->hasValidFilename() || !$this->hasValidPath()) { + throw new InvalidRequestException('Invalid filename or path'); + } + + if ($this->isHidden() || $this->hasHiddenPath()) { + throw new InvalidRequestException('Edited file is hidden'); + } + + if ($this->config->get('checkDoubleExtension') && !$this->areValidDoubleExtensions()) { + throw new InvalidExtensionException(); + } + + if (!$this->resourceType->isAllowedExtension($this->getExtension())) { + throw new InvalidExtensionException(); + } + + if (!$this->saveAsNew && !$this->exists()) { + throw new FileNotFoundException(); + } + + if ($this->newContents) { + if (Utils::containsHtml(substr($this->newContents, 0, 1024)) && + !in_array(strtolower($this->newFileName ? $this->getNewExtension() : $this->getExtension()), $this->config->get('htmlExtensions'))) { + throw new InvalidUploadException('HTML detected in disallowed file type', Error::UPLOADED_WRONG_HTML_FILE); + } + + $maxFileSize = $this->resourceType->getMaxSize(); + + if ($maxFileSize && strlen($this->newContents) > $maxFileSize) { + throw new InvalidUploadException('Uploaded file is too big', Error::UPLOADED_TOO_BIG); + } + } + + return true; + } + + /** + * Checks double extensions in a given file name. + * + * @param null|string $fileName file name or null if the current file name is checked. + * + * @return bool `true` if extensions are allowed for the current resource type. + */ + protected function areValidDoubleExtensions($fileName = null) + { + $extensions = $this->getExtensions($fileName); + + foreach ($extensions as $ext) { + if (!$this->resourceType->isAllowedExtension($ext)) { + return false; + } + } + + return true; + } + + /** + * Returns the new file name of the edited file. + * + * @return null|string the new file name of the edited file. + */ + public function getNewFilename() + { + return $this->newFileName; + } + + /** + * Returns the new file extension. + */ + public function getNewExtension() + { + return $this->newFileName ? pathinfo($this->newFileName, PATHINFO_EXTENSION) : null; + } + + /** + * Sets the flag if the edited file is saved as new and does not exist in the file system yet. + * + * @param bool $saveAsNew + */ + public function saveAsNew($saveAsNew) + { + $this->saveAsNew = $saveAsNew; + } + + /** + * Sets new file contents. + * + * @param string $contents new file contents + * @param string|null $filePath optional path if new contents should be saved in a new file. + * + * @return bool + */ + public function save($contents, $filePath = null) + { + return parent::save($contents, $this->newFileName ? Path::combine($this->getPath(), $this->newFileName) : null); + } + + /** + * Sets new contents for the edited file. + * + * @param string $newContents + */ + public function setNewContents($newContents) + { + $this->newContents = $newContents; + } + + /** + * Returns new contents set for the edited file. + * + * @return string + */ + public function getNewContents() + { + return $this->newContents; + } + + /** + * Returns the folder of the edited file. + * + * @return WorkingFolder + */ + public function getWorkingFolder() + { + return $this->workingFolder; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Filesystem/File/EditedImage.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Filesystem/File/EditedImage.php new file mode 100644 index 0000000..cef3e83 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Filesystem/File/EditedImage.php @@ -0,0 +1,62 @@ +newWidth = $newWidth; + $this->newHeight = $newHeight; + } + + /** + * @copydoc EditedFile::isValid() + */ + public function isValid() + { + $imagesConfig = $this->config->get('images'); + + if ($imagesConfig['maxWidth'] && $this->newWidth > $imagesConfig['maxWidth'] || + $imagesConfig['maxHeight'] && $this->newHeight > $imagesConfig['maxHeight']) { + throw new InvalidUploadException('The image dimensions exceeds images.maxWidth or images.maxHeight'); + } + + return parent::isValid(); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Filesystem/File/ExistingFile.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Filesystem/File/ExistingFile.php new file mode 100644 index 0000000..7590301 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Filesystem/File/ExistingFile.php @@ -0,0 +1,342 @@ +folder = $folder; + $this->resourceType = $resourceType; + + parent::__construct($fileName, $app); + } + + /** + * Returns backend-relative folder path (i.e. a path with a prepended resource type directory). + * + * @return string backend-relative path + */ + public function getPath() + { + return Path::combine($this->resourceType->getDirectory(), $this->folder); + } + + /** + * Returns backend-relative file path. + * + * @return string file path + */ + public function getFilePath() + { + return Path::combine($this->getPath(), $this->getFilename()); + } + + /** + * Checks if the current file folder path is valid. + * + * @return bool `true` if the path is valid. + */ + public function hasValidPath() + { + return Path::isValid($this->getPath()); + } + + /** + * Returns the resource type of the file. + * + * @return ResourceType + */ + public function getResourceType() + { + return $this->resourceType; + } + + /** + * Checks if the current file has an extension allowed in its resource type. + * + * @return bool `true` if the file has an allowed exception. + */ + public function hasAllowedExtension() + { + if (strpos($this->getFilename(), '.') === false) { + return true; + } + + $extension = $this->getExtension(); + + return $this->resourceType->isAllowedExtension($extension); + } + + /** + * Checks if the current file is hidden. + * + * @return bool `true` if the file is hidden. + */ + public function isHidden() + { + return $this->resourceType->getBackend()->isHiddenFile($this->getFilename()); + } + + /** + * Checks if the current file has a hidden path (i.e. if any of the parent folders is hidden). + * + * @return bool `true` if the path is hidden. + */ + public function hasHiddenPath() + { + return $this->resourceType->getBackend()->isHiddenPath($this->getPath()); + } + + /** + * Checks if the current file exists. + * + * @return bool `true` if the file exists. + */ + public function exists() + { + $filePath = $this->getFilePath(); + $backend = $this->resourceType->getBackend(); + + if (!$backend->has($filePath)) { + return false; + } + + $fileMetadata = $backend->getMetadata($filePath); + + return isset($fileMetadata['type']) && $fileMetadata['type'] === 'file'; + } + + /** + * Returns file contents stream. + * + * @return resource contents stream + */ + public function getContentsStream() + { + $filePath = $this->getFilePath(); + + return $this->resourceType->getBackend()->readStream($filePath); + } + + /** + * Returns file contents. + * + * @return resource contents stream + */ + public function getContents() + { + $filePath = $this->getFilePath(); + + return $this->resourceType->getBackend()->read($filePath); + } + + /** + * Sets new file contents. + * + * @param string $contents file contents + * @param string $filePath path to save the file + * + * @return bool `true` if saved successfully. + * + * @throws \Exception if content size is too big. + */ + public function save($contents, $filePath = null) + { + $filePath = $filePath ?: $this->getFilePath(); + + $maxSize = $this->resourceType->getMaxSize(); + + $contentsSize = strlen($contents); + + if ($maxSize && $contentsSize > $maxSize) { + throw new InvalidUploadException('New file contents is too big for resource type limit', Error::UPLOADED_TOO_BIG); + } + + $saved = $this->resourceType->getBackend()->put($filePath, $contents); + + if ($saved) { + $this->deleteThumbnails(); + } + + return $saved; + } + + /** + * Adds an error to the array of errors of the current file. + * + * @param int $number error number + * + * @see Error + */ + public function addError($number) + { + $this->errors[] = array( + 'number' => $number, + 'name' => $this->getFilename(), + 'type' => $this->resourceType->getName(), + 'folder' => $this->folder + ); + } + + /** + * Returns an array of errors that occurred during file processing. + * + * @return array + */ + public function getErrors() + { + return $this->errors; + } + + /** + * Removes the thumbnail generated for the current file. + * + * @return `true` if the thumbnail was found and deleted. + */ + public function deleteThumbnails() + { + $extension = $this->getExtension(); + + if (Image::isSupportedExtension($extension) || ($extension === 'bmp' && $this->config->get('thumbnails.bmpSupported'))) { + $thumbsRepository = $this->resourceType->getThumbnailRepository(); + + return $thumbsRepository->deleteThumbnails($this->resourceType, $this->folder, $this->getFilename()); + } + + return false; + } + + /** + * Removes resized images generated for the current file. + * + * @return `true` if resized images were found and deleted. + */ + public function deleteResizedImages() + { + $extension = $this->getExtension(); + + if (Image::isSupportedExtension($extension)) { + $resizedImageRepository = $this->resourceType->getResizedImageRepository(); + + return $resizedImageRepository->deleteResizedImages($this->resourceType, $this->folder, $this->getFilename()); + } + + return false; + } + + /** + * Returns last modification time. + * + * @return int Unix timestamp + */ + public function getTimestamp() + { + $metadata = $this->getMetadata(); + + return $metadata['timestamp']; + } + + + /** + * Returns file MIME type. + * + * @return string file MIME type. + */ + public function getMimeType() + { + $metadata = $this->getMetadata(); + + return $metadata['mimetype']; + } + + /** + * Returns file size. + * + * @return int size in bytes. + */ + public function getSize() + { + $metadata = $this->getMetadata(); + + return $metadata['size']; + } + + /** + * Returns file metadata. + * + * @return array + */ + public function getMetadata() + { + if (null === $this->metadata) { + $filePath = $this->getFilePath(); + + $this->metadata = $this->resourceType->getBackend()->getWithMetadata($filePath, array('mimetype', 'timestamp')); + } + + return $this->metadata; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Filesystem/File/File.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Filesystem/File/File.php new file mode 100644 index 0000000..b813df1 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Filesystem/File/File.php @@ -0,0 +1,225 @@ +fileName = $fileName; + $this->config = $app['config']; + $this->app = $app; + } + + /** + * Validates current file name. + * + * @return bool `true` if the file name is valid. + */ + public function hasValidFilename() + { + return static::isValidName($this->fileName, $this->config->get('disallowUnsafeCharacters')); + } + + /** + * Returns current file name. + * + * @return string + */ + public function getFilename() + { + return $this->fileName; + } + + /** + * Returns current file extension. + * + * @return string + */ + public function getExtension() + { + return strtolower(pathinfo($this->fileName, PATHINFO_EXTENSION)); + } + + /** + * Returns a list of current file extensions. + * + * For example for a file named `file.foo.bar.baz` it will return an array containing + * `['foo', 'bar', 'baz']`. + * + * @param null $newFileName the file name to check if it is different than the current file name (for example for validation of + * a new file name in edited files). + * + * @return array + */ + public function getExtensions($newFileName = null) + { + $fileName = $newFileName ?: $this->fileName; + + if (strpos($fileName, '.') === false) { + return true; + } + + $pieces = explode('.', $fileName); + + array_shift($pieces); // Remove file base name + + return array_map('strtolower', $pieces); + } + + /** + * Renames the current file by adding a number to the file name. + * + * Renaming is done by adding a number in parenthesis provided that the file name does + * not collide with any other file existing in the target backend/path. + * For example, if the target backend path contains a file named `foo.txt` + * and the current file name is `foo.txt`, this method will change the current file + * name to `foo(1).txt`. + * + * @param Backend $backend target backend + * @param string $path target backend-relative path + * + * @return bool `true` if file was renamed. + */ + public function autorename(Backend $backend = null, $path = '') + { + $filePath = Path::combine($path, $this->fileName); + + if (!$backend->has($filePath)) { + return false; + } + + $pieces = explode('.', $this->fileName); + $basename = array_shift($pieces); + $extension = implode('.', $pieces); + + $i = 0; + while (true) { + $i++; + $this->fileName = "{$basename}({$i}).{$extension}"; + + $filePath = Path::combine($path, $this->fileName); + + if (!$backend->has($filePath)) { + break; + } + } + + return true; + } + + /** + * Check whether `$fileName` is a valid file name. Returns `true` on success. + * + * @param string $fileName + * @param bool $disallowUnsafeCharacters + * + * @return boolean `true` if `$fileName` is a valid file name. + */ + public static function isValidName($fileName, $disallowUnsafeCharacters = true) + { + if (null === $fileName || !strlen(trim($fileName)) || substr($fileName, -1, 1) == "." || false !== strpos($fileName, "..")) { + return false; + } + + if (preg_match(',[[:cntrl:]]|[/\\\\:\*\?\"\<\>\|],', $fileName)) { + return false; + } + + if ($disallowUnsafeCharacters) { + if (strpos($fileName, ";") !== false) { + return false; + } + } + + return true; + } + + /** + * Checks if the current file has an image extension. + * + * @return bool `true` if the file name has an image extension. + */ + public function isImage() + { + $imagesExtensions = array('gif', 'jpeg', 'jpg', 'png', 'psd', 'bmp', 'tiff', 'tif', + 'swc', 'iff', 'jpc', 'jp2', 'jpx', 'jb2', 'xbm', 'wbmp'); + + return in_array($this->getExtension(), $imagesExtensions); + } + + /** + * Secures the file name from unsafe characters. + * + * @param string $fileName + * @param bool $disallowUnsafeCharacters + * + * @return string + */ + public static function secureName($fileName, $disallowUnsafeCharacters) + { + $fileName = str_replace(array(":", "*", "?", "|", "/"), "_", $fileName); + + if ($disallowUnsafeCharacters) { + $fileName = str_replace(";", "_", $fileName); + } + + return $fileName; + } + + /** + * @return CacheManager + */ + public function getCache() + { + return $this->app['cache']; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Filesystem/File/MovedFile.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Filesystem/File/MovedFile.php new file mode 100644 index 0000000..a372f0b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Filesystem/File/MovedFile.php @@ -0,0 +1,64 @@ +getFilePath(); + $originalFileName = $this->getFilename(); // Save original file name - it may be autorenamed when copied + + if (parent::doCopy()) { + // Remove source file + $this->deleteThumbnails(); + $this->resourceType->getResizedImageRepository()->deleteResizedImages($this->resourceType, $this->folder, $originalFileName); + $this->getCache()->delete(Path::combine($this->resourceType->getName(), $this->folder, $originalFileName)); + + return $this->resourceType->getBackend()->delete($originalFilePath); + } + + return false; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Filesystem/File/RenamedFile.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Filesystem/File/RenamedFile.php new file mode 100644 index 0000000..dbbcc8d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Filesystem/File/RenamedFile.php @@ -0,0 +1,158 @@ +newFileName = static::secureName($newFileName, $this->config->get('disallowUnsafeCharacters')); + + if ($this->config->get('checkDoubleExtension')) { + $this->newFileName = Utils::replaceDisallowedExtensions($this->newFileName, $resourceType); + } + } + + /** + * Returns the new file name of the renamed file. + * + * @return string + */ + public function getNewFileName() + { + return $this->newFileName; + } + + /** + * Returns the new path of the renamed file. + * + * @return string + */ + public function getNewFilePath() + { + return Path::combine($this->getPath(), $this->getNewFileName()); + } + + /** + * Sets the new file name of the renamed file. + * + * @param string $newFileName + */ + public function setNewFileName($newFileName) + { + $this->newFileName = $newFileName; + } + + /** + * Renames the current file. + * + * @return bool `true` if the file was renamed successfully. + * + * @throws \Exception + */ + public function doRename() + { + $oldPath = Path::combine($this->getPath(), $this->getFilename()); + $newPath = Path::combine($this->getPath(), $this->newFileName); + + $backend = $this->resourceType->getBackend(); + + if ($backend->has($newPath)) { + throw new AlreadyExistsException('Target file already exists'); + } + + $this->deleteThumbnails(); + $this->resourceType->getResizedImageRepository()->renameResizedImages( + $this->resourceType, + $this->folder, + $this->getFilename(), + $this->newFileName + ); + + $this->getCache()->move( + Path::combine($this->resourceType->getName(), $this->folder, $this->getFilename()), + Path::combine($this->resourceType->getName(), $this->folder, $this->newFileName)); + + return $backend->rename($oldPath, $newPath); + } + + /** + * Validates the renamed file. + * + * @return bool + * + * @throws \Exception + */ + public function isValid() + { + $newExtension = pathinfo($this->newFileName, PATHINFO_EXTENSION); + + if (!$this->hasAllowedExtension()) { + throw new InvalidRequestException('Invalid source file extension'); + } + + if (!$this->resourceType->isAllowedExtension($newExtension)) { + throw new InvalidExtensionException('Invalid target file extension'); + } + + if (!$this->hasValidFilename() || $this->isHidden()) { + throw new InvalidRequestException('Invalid source file name'); + } + + if (!File::isValidName($this->newFileName, $this->config->get('disallowUnsafeCharacters')) || + $this->resourceType->getBackend()->isHiddenFile($this->newFileName)) { + throw new InvalidNameException('Invalid target file name'); + } + + if (!$this->exists()) { + throw new FileNotFoundException(); + } + + return true; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Filesystem/File/UploadedFile.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Filesystem/File/UploadedFile.php new file mode 100644 index 0000000..fdba5f1 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Filesystem/File/UploadedFile.php @@ -0,0 +1,294 @@ +getClientOriginalName(), $app); + + $this->uploadedFile = $uploadedFile; + $this->workingFolder = $app['working_folder']; + + $this->tempFilePath = tempnam($this->config->get('tempDirectory'), 'ckf'); + $pathinfo = pathinfo($this->tempFilePath); + + if (!is_writable($this->tempFilePath)) { + throw new InvalidUploadException('The temporary folder is not writable for CKFinder'); + } + + try { + $uploadedFile->move($pathinfo['dirname'], $pathinfo['basename']); + } catch (\Exception $e) { + $errorMessage = $uploadedFile->getErrorMessage(); + switch ($uploadedFile->getError()) { + case UPLOAD_ERR_INI_SIZE: + case UPLOAD_ERR_FORM_SIZE: + throw new InvalidUploadException($errorMessage, Error::UPLOADED_TOO_BIG, array(), $e); + + case UPLOAD_ERR_PARTIAL: + case UPLOAD_ERR_NO_FILE: + throw new InvalidUploadException($errorMessage, Error::UPLOADED_CORRUPT, array(), $e); + + case UPLOAD_ERR_NO_TMP_DIR: + throw new InvalidUploadException($errorMessage, Error::UPLOADED_NO_TMP_DIR, array(), $e); + + case UPLOAD_ERR_CANT_WRITE: + case UPLOAD_ERR_EXTENSION: + throw new AccessDeniedException($errorMessage, array(), $e); + } + } + } + + /** + * Checks if the file was uploaded properly. + * + * @return bool `true` if upload is valid. + */ + public function isValid() + { + return $this->uploadedFile && $this->tempFilePath && is_readable($this->tempFilePath) && is_writable($this->tempFilePath); + } + + /** + * Sanitizes current file name using options set in Config. + */ + public function sanitizeFilename() + { + $this->fileName = static::secureName($this->fileName, $this->config->get('disallowUnsafeCharacters')); + + $resourceType = $this->workingFolder->getResourceType(); + + if ($this->config->get('checkDoubleExtension')) { + $this->fileName = Utils::replaceDisallowedExtensions($this->fileName, $resourceType); + } + } + + /** + * Checks if the file extension is allowed in the target folder. + * + * @return bool `true` if an extension is allowed in the target folder. + */ + public function hasAllowedExtension() + { + if (strpos($this->fileName, '.') === false) { + return true; + } + + return $this->workingFolder->getResourceType()->isAllowedExtension($this->getExtension()); + } + + /** + * @copydoc File::autorename() + */ + public function autorename(Backend $backend = null, $path = '') + { + return parent::autorename($this->workingFolder->getBackend(), $this->workingFolder->getPath()); + } + + /** + * Checks if the file was renamed. + * + * @return bool `true` if the file was renamed. + */ + public function wasRenamed() + { + return $this->fileName != $this->uploadedFile->getClientOriginalName(); + } + + /** + * Check if the current file name is defined as hidden in configuration settings. + * + * @return bool `true` if the file name is hidden. + */ + public function isHiddenFile() + { + return $this->workingFolder->getBackend()->isHiddenFile($this->fileName); + } + + /** + * Returns the upload error. + * + * If the upload was successful, the `UPLOAD_ERR_OK` constant is returned. + * Otherwise one of the other `UPLOAD_ERR_XXX` constants is returned. + * + * @return int upload error + */ + public function getError() + { + return $this->uploadedFile->getError(); + } + + /** + * Returns the upload error message. + * + * @return string upload error + */ + public function getErrorMessage() + { + return $this->uploadedFile->getErrorMessage(); + } + + /** + * Returns uploaded file contents. + * + * @return string uploaded file data + */ + public function getContents() + { + return file_get_contents($this->tempFilePath); + } + + /** + * Returns contents stream for the uploaded file. + * + * @return resource + */ + public function getContentsStream() + { + return fopen($this->tempFilePath, 'r'); + } + + /** + * Returns uploaded file size in bytes. + * + * @return int file size in bytes + */ + public function getSize() + { + clearstatcache(); + + return filesize($this->tempFilePath); + } + + /** + * Returns uploaded file MIME type. + * + * @return string + */ + public function getMimeType() + { + $guesser = MimeTypeGuesser::getInstance(); + + return $guesser->guess($this->tempFilePath); + } + + /** + * Detects HTML in the first KB to prevent against a potential security issue with + * IE/Safari/Opera file type auto detection bug. + * Returns `true` if a file contains insecure HTML code at the beginning. + * + * @return boolean `true` if the uploaded file contains HTML in the first 1024 bytes. + */ + public function containsHtml() + { + $fp = fopen($this->tempFilePath, 'rb'); + $chunk = fread($fp, 1024); + fclose($fp); + + return Utils::containsHtml($chunk); + } + + /** + * Checks if a file with the current extension is allowed to contain any HTML/JS. + * + * @return bool `true` if a file is allowed to contain HTML chunks. + */ + public function isAllowedHtmlFile() + { + return in_array(strtolower($this->getExtension()), $this->config->get('htmlExtensions')); + } + + /** + * Checks if the file is a valid image. + * + * Internally `getimagesize` is used for validation. + * + * @return bool `true` if the file is a valid image. + */ + public function isValidImage() + { + if (@getimagesize($this->tempFilePath) === false) { + return false ; + } + + return true; + } + + /** + * Saves the data as new file contents. + * + * @param string $data new file contents + */ + public function save($data) + { + file_put_contents($this->tempFilePath, $data); + } + + /** + * Destructor: Removes the temporary file, if required. + */ + public function __destruct() + { + if (file_exists($this->tempFilePath)) { + unlink($this->tempFilePath); + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Filesystem/Folder/Folder.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Filesystem/Folder/Folder.php new file mode 100644 index 0000000..01b0c4a --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Filesystem/Folder/Folder.php @@ -0,0 +1,68 @@ +resourceType = $resourceType; + $this->path = Path::combine($resourceType->getDirectory(), $path); + } + + /** + * Checks whether `$folderName` is a valid folder name. Returns `true` on success. + * + * @param string $folderName + * @param bool $disallowUnsafeCharacters + * + * @return boolean + */ + public static function isValidName($folderName, $disallowUnsafeCharacters) + { + if ($disallowUnsafeCharacters) { + if (strpos($folderName, ".") !== false) { + return false; + } + } + + return File::isValidName($folderName, $disallowUnsafeCharacters); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Filesystem/Folder/WorkingFolder.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Filesystem/Folder/WorkingFolder.php new file mode 100644 index 0000000..be634c2 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Filesystem/Folder/WorkingFolder.php @@ -0,0 +1,549 @@ +app = $app; + + /* @var $request \Symfony\Component\HttpFoundation\Request */ + $request = $app['request_stack']->getCurrentRequest(); + + $resourceType = $app['resource_type_factory']->getResourceType((string) $request->get('type')); + + $this->clientCurrentFolder = Path::normalize(trim((string) $request->get('currentFolder'))); + + if (!Path::isValid($this->clientCurrentFolder)) { + throw new InvalidNameException('Invalid path'); + } + + $resourceTypeDirectory = $resourceType->getDirectory(); + + parent::__construct($resourceType, $this->clientCurrentFolder); + + $this->backend = $this->resourceType->getBackend(); + $this->thumbnailRepository = $app['thumbnail_repository']; + + $backend = $this->getBackend(); + + // Check if folder path is not hidden + if ($backend->isHiddenPath($this->getClientCurrentFolder())) { + throw new InvalidRequestException('Hidden folder path used'); + } + + // Check if resource type folder exists - if not then create it + $currentCommand = (string) $request->query->get('command'); + $omitForCommands = array('Thumbnail'); + + if (!in_array($currentCommand, $omitForCommands) && + !empty($resourceTypeDirectory) && + !$backend->hasDirectory($this->path)) { + if ($this->clientCurrentFolder === '/') { + @$backend->createDir($resourceTypeDirectory); + + if (!$backend->hasDirectory($resourceTypeDirectory)) { + throw new AccessDeniedException("Couldn't create resource type directory. Please check permissions."); + } + } else { + throw new FolderNotFoundException(); + } + } + } + + /** + * Returns the ResourceType object for the current working folder. + * + * @return ResourceType + */ + public function getResourceType() + { + return $this->resourceType; + } + + /** + * Returns the name of the current resource type. + * + * @return string + */ + public function getResourceTypeName() + { + return $this->resourceType->getName(); + } + + /** + * Returns the client current folder path. + * + * @return string + */ + public function getClientCurrentFolder() + { + return $this->clientCurrentFolder; + } + + /** + * Returns the backend relative path with the resource type directory prefix. + * + * @return string + */ + public function getPath() + { + return $this->path; + } + + /** + * Returns the backend assigned for the current resource type. + * + * @return Backend + */ + public function getBackend() + { + return $this->resourceType->getBackend(); + } + + /** + * Returns the thumbnails repository object. + * + * @return ThumbnailRepository + */ + public function getThumbnailsRepository() + { + return $this->thumbnailRepository; + } + + /** + * Lists directories in the current working folder. + * + * @return array list of directories + */ + public function listDirectories() + { + return $this->getBackend()->directories($this->getResourceType(), $this->getClientCurrentFolder()); + } + + /** + * Lists files in the current working folder. + * + * @return array list of files + */ + public function listFiles() + { + return $this->getBackend()->files($this->getResourceType(), $this->getClientCurrentFolder()); + } + + /** + * Returns ACL mask computed for the current user and the current working folder. + * + * @return int + */ + public function getAclMask() + { + if (null === $this->aclMask) { + $this->aclMask = $this->app->getAcl()->getComputedMask($this->getResourceTypeName(), $this->getClientCurrentFolder()); + } + + return $this->aclMask; + } + + /** + * Creates a directory with a given name in the working folder. + * + * @param string $dirname directory name + * + * @return bool `true` if the folder was created successfully. + * + * @throws AccessDeniedException + * @throws AlreadyExistsException + * @throws InvalidNameException + */ + public function createDir($dirname) + { + $backend = $this->getBackend(); + + if (!Folder::isValidName($dirname, $this->app['config']->get('disallowUnsafeCharacters')) || $backend->isHiddenFolder($dirname)) { + throw new InvalidNameException('Invalid folder name'); + } + + $dirPath = Path::combine($this->getPath(), $dirname); + + if ($backend->hasDirectory($dirPath)) { + throw new AlreadyExistsException('Folder already exists'); + } + + $result = $backend->createDir($dirPath); + + if (!$result) { + throw new AccessDeniedException("Couldn't create new folder. Please check permissions."); + } + + return $result; + } + + /** + * Creates a file inside the current working folder. + * + * @param string $fileName file name + * @param string $data file data + * + * @return bool `true` if created successfully. + */ + public function write($fileName, $data) + { + $backend = $this->getBackend(); + $filePath = Path::combine($this->getPath(), $fileName); + + return $backend->write($filePath, $data); + } + + /** + * Creates a file inside the current working folder using the stream. + * + * @param string $fileName file name + * @param resource $resource file data stream + * + * @return bool `true` if created successfully. + */ + public function writeStream($fileName, $resource) + { + $backend = $this->getBackend(); + $filePath = Path::combine($this->getPath(), $fileName); + + return $backend->writeStream($filePath, $resource); + } + + /** + * Creates or updates a file inside the current working folder using the stream. + * + * @param string $fileName file name + * @param resource $resource file data stream + * @param string $mimeType file MIME type + * + * @return bool `true` if updated successfully. + */ + public function putStream($fileName, $resource, $mimeType = null) + { + $backend = $this->getBackend(); + $filePath = Path::combine($this->getPath(), $fileName); + + if (!$mimeType) { + $ext = strtolower(pathinfo($fileName, PATHINFO_EXTENSION)); + $mimeType = MimeType::detectByFileExtension($ext); + } + + $options = $mimeType ? array('mimetype' => $mimeType) : array(); + + return $backend->putStream($filePath, $resource, $options); + } + + /** + * Checks if the current working folder contains a file with a given name. + * + * @param string $fileName + * + * @return bool + */ + public function containsFile($fileName) + { + $backend = $this->getBackend(); + + if (!File::isValidName($fileName, $this->app['config']->get('disallowUnsafeCharacters')) || + $backend->isHiddenFolder($this->getClientCurrentFolder()) || + $backend->isHiddenFile($fileName) || + !$this->resourceType->isAllowedExtension(pathinfo($fileName, PATHINFO_EXTENSION))) { + return false; + } + + $filePath = Path::combine($this->getPath(), $fileName); + + return $backend->has($filePath); + } + + /** + * Returns contents of the file with a given name. + * + * @param string $fileName + * + * @return string + */ + public function read($fileName) + { + $backend = $this->getBackend(); + $filePath = Path::combine($this->getPath(), $fileName); + + return $backend->read($filePath); + } + + /** + * Returns contents stream of the file with a given name. + * + * @param string $fileName + * + * @return resource + */ + public function readStream($fileName) + { + $backend = $this->getBackend(); + $filePath = Path::combine($this->getPath(), $fileName); + + return $backend->readStream($filePath); + } + + /** + * Deletes the current working folder. + * + * @return bool `true` if the deletion was successful + */ + public function delete() + { + // Delete related thumbs path + $this->thumbnailRepository->deleteThumbnails($this->resourceType, $this->getClientCurrentFolder()); + + $this->app['cache']->deleteByPrefix(Path::combine($this->resourceType->getName(), $this->getClientCurrentFolder())); + + return $this->getBackend()->deleteDir($this->getPath()); + } + + /** + * Renames the current working folder. + * + * @param string $newName new folder name + * + * @return array containing newName and newPath + * + * @throws AccessDeniedException + * @throws AlreadyExistsException + * @throws InvalidNameException + */ + public function rename($newName) + { + $disallowUnsafeCharacters = $this->app['config']->get('disallowUnsafeCharacters'); + + if (!Folder::isValidName($newName, $disallowUnsafeCharacters) || $this->backend->isHiddenFolder($newName)) { + throw new InvalidNameException('Invalid folder name'); + } + + $newBackendPath = dirname($this->getPath()) . '/' . $newName; + + if ($this->backend->has($newBackendPath)) { + throw new AlreadyExistsException('File already exists'); + } + + $newClientPath = Path::normalize(dirname($this->getClientCurrentFolder()) . '/' . $newName); + + if (!$this->getBackend()->rename($this->getPath(), $newBackendPath)) { + throw new AccessDeniedException(); + } + + /* @var OperationManager $currentRequestOperation */ + $currentRequestOperation = $this->app['operation']; + + if ($currentRequestOperation->isAborted()) { + // Don't continue in this case, no need to touch thumbs and cache entries + return array('aborted' => true); + } + + // Delete related thumbs path + $this->thumbnailRepository->deleteThumbnails($this->resourceType, $this->getClientCurrentFolder()); + + $this->app['cache']->changePrefix( + Path::combine($this->resourceType->getName(), $this->getClientCurrentFolder()), + Path::combine($this->resourceType->getName(), $newClientPath)); + + return array( + 'newName' => $newName, + 'newPath' => $newClientPath, + 'renamed' => 1 + ); + } + + /** + * Returns the URL to a given file. + * + * @param string $fileName + * @param string|null $thumbnailFileName + * + * @throws FileNotFoundException + * @throws InvalidExtensionException + * @throws InvalidRequestException + * + * @return null|string + */ + public function getFileUrl($fileName, $thumbnailFileName = null) + { + $config = $this->app['config']; + + if (!File::isValidName($fileName, $config->get('disallowUnsafeCharacters'))) { + throw new InvalidRequestException('Invalid file name'); + } + + if ($thumbnailFileName) { + if (!File::isValidName($thumbnailFileName, $config->get('disallowUnsafeCharacters'))) { + throw new InvalidRequestException('Invalid thumbnail file name'); + } + + if (!$this->resourceType->isAllowedExtension(pathinfo($thumbnailFileName, PATHINFO_EXTENSION))) { + throw new InvalidExtensionException('Invalid thumbnail file name'); + } + } + + if (!$this->containsFile($fileName)) { + throw new FileNotFoundException(); + } + + return $this->backend->getFileUrl($this->resourceType, $this->getClientCurrentFolder(), $fileName, $thumbnailFileName); + } + + /** + * @return ResizedImageRepository + */ + public function getResizedImageRepository() + { + return $this->app['resized_image_repository']; + } + + /** + * Tells the current WorkingFolder object to not add the current folder + * to the response. + * + * By default the WorkingFolder object acts as an event subscriber and + * listens for the `KernelEvents::RESPONSE` event. The response given is + * then modified by adding information about the current folder. + * + * @see WorkingFolder::addCurrentFolderInfo() + */ + public function omitResponseInfo() + { + $this->app['dispatcher']->removeSubscriber($this); + } + + /** + * Adds the current folder information to the response. + * + * @param FilterResponseEvent $event + */ + public function addCurrentFolderInfo(FilterResponseEvent $event) + { + /* @var JsonResponse $response */ + $response = $event->getResponse(); + + if ($response instanceof JsonResponse) { + $responseData = (array) $response->getData(); + + $responseData = array( + 'resourceType' => $this->getResourceTypeName(), + 'currentFolder' => array( + 'path' => $this->getClientCurrentFolder(), + 'acl' => $this->getAclMask() + ) + ) + $responseData; + + $baseUrl = $this->backend->getBaseUrl(); + + if (null !== $baseUrl) { + $folderUrl = Path::combine($baseUrl, Utils::encodeURLParts(Path::combine($this->resourceType->getDirectory(), $this->getClientCurrentFolder()))); + $responseData['currentFolder']['url'] = rtrim($folderUrl, '/') . '/'; + } + + $response->setData($responseData); + } + } + + /** + * Returns listeners for the event dispatcher. + * + * @return array subscribed events + */ + public static function getSubscribedEvents() + { + return array(KernelEvents::RESPONSE => array('addCurrentFolderInfo', 512)); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Filesystem/Path.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Filesystem/Path.php new file mode 100644 index 0000000..165acce --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Filesystem/Path.php @@ -0,0 +1,122 @@ +\|]),'; + + /** + * Checks if a given path is valid. + * + * @param string $path path to be validated + * + * @return bool true if the path is valid. + */ + public static function isValid($path) + { + return !preg_match(static::REGEX_INVALID_PATH, $path); + } + + /** + * Normalizes the path so it starts and ends end with a "/". + * + * @param string $path input path + * + * @return string normalized path + */ + public static function normalize($path) + { + if (!strlen($path)) { + $path = '/'; + } elseif ($path !== '/') { + $path = '/' . trim($path, '/') . '/'; + } + + return $path; + } + + /** + * This function behaves similarly to `System.IO.Path.Combine` in C#, the only difference is that it also + * accepts null values and treats them as an empty string. + * + * @param string [$arg1, $arg2, ...] + * + * @return string + */ + public static function combine() + { + $args = func_get_args(); + + if (!count($args)) { + return null; + } + + $result = array_shift($args); + + $isDirSeparator = function ($char) { + return $char === '/' || $char === '\\'; + }; + + $argsCount = count($args); + + for ($i = 0; $i < $argsCount; $i++) { + $path1 = $result; + $path2 = $args[$i]; + + if (null === $path1) { + $path1 = ''; + } + + if (null === $path2) { + $path2 = ''; + } + + if (!strlen($path2)) { + if (strlen($path1)) { + $_lastCharP1 = substr($path1, -1, 1); + if (!$isDirSeparator($_lastCharP1)) { + $path1 .= '/'; + } + } + } else { + $_firstCharP2 = substr($path2, 0, 1); + if (strlen($path1)) { + if (strpos($path2, $path1) === 0) { + $result = $path2; + continue; + } + $_lastCharP1 = substr($path1, -1, 1); + if (!$isDirSeparator($_lastCharP1) && !$isDirSeparator($_firstCharP2)) { + $path1 .= '/'; + } elseif ($isDirSeparator($_lastCharP1) && $isDirSeparator($_firstCharP2)) { + $path2 = substr($path2, 1); + } + } else { + $result = $path2; + continue; + } + } + + $result = $path1 . $path2; + } + + + return $result; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Image.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Image.php new file mode 100644 index 0000000..7e09f00 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Image.php @@ -0,0 +1,704 @@ + 'image/gif', + 'jpg' => 'image/jpeg', + 'jpeg' => 'image/jpeg', + 'bmp' => 'image/bmp', + 'png' => 'image/png', + 'wbmp' => 'image/wbmp' + ); + + $extension = strtolower($extension); + + return array_key_exists($extension, $extensionMimeTypeMap) ? $extensionMimeTypeMap[$extension] : null; + } + + /** + * Constructor. + * + * @param string $imageData image data + * @param bool $bmpSupport `true` if bitmaps are supported (be aware of poor efficiency!). + * + * @throws CKFinderException in case the image could not be initialized properly. + */ + + public function __construct($imageData, $bmpSupport = false) + { + if (!extension_loaded('gd')) { + throw new CKFinderException('PHP GD library not found'); + } + + $imgInfo = @getimagesizefromstring($imageData); + + if ($imgInfo === false) { + throw new CKFinderException('Unsupported image type'); + } + + $this->width = isset($imgInfo[0]) ? $imgInfo[0] : 0; + $this->height = isset($imgInfo[1]) ? $imgInfo[1] : 0; + $this->mime = isset($imgInfo['mime']) ? $imgInfo['mime'] : ''; + $this->bits = isset($imgInfo['bits']) ? $imgInfo['bits'] : 8; + $this->channels = isset($imgInfo['channels']) ? $imgInfo['channels'] : 3; + $this->dataSize = strlen($imageData); + + if (!$this->width || !$this->height || !$this->mime) { + throw new CKFinderException('Unsupported image type'); + } + + $this->setMemory($this->width, $this->height, $this->bits, $this->channels); + + $gdSupportedTypes = @imagetypes(); + + $supportedFormats = array( + 'image/gif' => $gdSupportedTypes & IMG_GIF, + 'image/jpeg' => $gdSupportedTypes & IMG_JPG, + 'image/png' => $gdSupportedTypes & IMG_PNG, + 'image/wbmp' => $gdSupportedTypes & IMG_WBMP, + 'image/bmp' => $bmpSupport && ($gdSupportedTypes & IMG_JPG), + 'image/x-ms-bmp' => $bmpSupport && ($gdSupportedTypes & IMG_JPG) + ); + + if (!array_key_exists($this->mime, $supportedFormats) || !$supportedFormats[$this->mime]) { + throw new CKFinderException('Unsupported image type: ' . $this->mime); + } + + if ($this->mime === 'image/bmp' || $this->mime === 'image/x-ms-bmp') { + $this->gdImage = $this->createFromBmp($imageData); + } else { + $this->gdImage = imagecreatefromstring($imageData); + } + + if (!is_resource($this->gdImage)) { + throw new CKFinderException('Unsupported image type (not resource): ' . $this->mime); + } + + unset($imageData); + } + + /** + * Returns the aspect ratio size as associative array: + * @code + * array + * ( + * [width] => 80 + * [heigth] => 120 + * ) + * @endcode + * + * @param int $maxWidth requested width + * @param int $maxHeight requested height + * @param int $actualWidth original width + * @param int $actualHeight original height + * @param bool $useHigherFactor defines which factor should be used to calculate the new + * size. For example: + * - original image size 800x400 + * - calculateAspectRatio(300, 200, 800, 400, false) will return 300x150 + * - calculateAspectRatio(300, 200, 800, 400, true) will return 400x200 + * + * @return array + */ + public static function calculateAspectRatio($maxWidth, $maxHeight, $actualWidth, $actualHeight, $useHigherFactor = false) + { + $oSize = array('width' => $maxWidth, 'height' => $maxHeight); + + // Calculates the X and Y resize factors + $iFactorX = (float) $maxWidth / (float) $actualWidth; + $iFactorY = (float) $maxHeight / (float) $actualHeight; + + // If some dimension have to be resized + if ($iFactorX != 1 || $iFactorY != 1) { + if ($useHigherFactor) { + // Uses the higher Factor to change the opposite size + if ($iFactorX > $iFactorY) { + $oSize['height'] = (int) round($actualHeight * $iFactorX); + } elseif ($iFactorX < $iFactorY) { + $oSize['width'] = (int) round($actualWidth * $iFactorY); + } + } else { + // Uses the lower Factor to change the opposite size + if ($iFactorX < $iFactorY) { + $oSize['height'] = (int) round($actualHeight * $iFactorX); + } elseif ($iFactorX > $iFactorY) { + $oSize['width'] = (int) round($actualWidth * $iFactorY); + } + } + } + + if ($oSize['height'] <= 0) { + $oSize['height'] = 1; + } + + if ($oSize['width'] <= 0) { + $oSize['width'] = 1; + } + + // Returns the Size + return $oSize; + } + + + /** + * @link http://pl.php.net/manual/pl/function.imagecreatefromjpeg.php + * function posted by e dot a dot schultz at gmail dot com + * + * @param $imageWidth + * @param $imageHeight + * @param $imageBits + * @param $imageChannels + * + * @return bool + */ + public function setMemory($imageWidth, $imageHeight, $imageBits, $imageChannels) + { + $MB = 1048576; // number of bytes in 1M + $K64 = 65536; // number of bytes in 64K + $TWEAKFACTOR = 2.4; // Or whatever works for you + $memoryNeeded = round(($imageWidth * $imageHeight + * $imageBits + * $imageChannels / 8 + + $K64 + ) * $TWEAKFACTOR + ) + 3 * $MB; + + //ini_get('memory_limit') only works if compiled with "--enable-memory-limit" also + //Default memory limit is 8MB so well stick with that. + //To find out what yours is, view your php.ini file. + $memoryLimit = Utils::returnBytes(@ini_get('memory_limit')) / $MB; + // There are no memory limits, nothing to do + if ($memoryLimit == -1) { + return true; + } + if (!$memoryLimit) { + $memoryLimit = 8; + } + + $memoryLimitMB = $memoryLimit * $MB; + if (function_exists('memory_get_usage')) { + if (memory_get_usage() + $memoryNeeded > $memoryLimitMB) { + $newLimit = $memoryLimit + ceil((memory_get_usage() + + $memoryNeeded + - $memoryLimitMB + ) / $MB + ); + if (@ini_set('memory_limit', $newLimit . 'M') === false) { + return false; + } + } + } else { + if ($memoryNeeded + 3 * $MB > $memoryLimitMB) { + $newLimit = $memoryLimit + ceil((3 * $MB + + $memoryNeeded + - $memoryLimitMB + ) / $MB + ); + if (false === @ini_set('memory_limit', $newLimit . 'M')) { + return false; + } + } + } + + return true; + } + + /** + * @link http://pl.php.net/manual/en/function.imagecopyresampled.php + * Replacement to `imagecopyresampled` that will deliver results that are almost identical except + * MUCH faster (very typically 30 times faster). + * + * @static + * @access public + * @param resource $dstImage + * @param resource $srcImage + * @param int $dstX + * @param int $dstY + * @param int $srcX + * @param int $srcY + * @param int $dstW + * @param int $dstH + * @param int $srcW + * @param int $srcH + * @param int $quality + * + * @return boolean + */ + public function fastCopyResampled(&$dstImage, $srcImage, $dstX, $dstY, $srcX, $srcY, $dstW, $dstH, $srcW, $srcH, $quality = 3) + { + if (empty($srcImage) || empty($dstImage)) { + return false; + } + + if ($quality <= 1) { + $temp = imagecreatetruecolor($dstW + 1, $dstH + 1); + imagecopyresized($temp, $srcImage, $dstX, $dstY, $srcX, $srcY, $dstW + 1, $dstH + 1, $srcW, $srcH); + imagecopyresized($dstImage, $temp, 0, 0, 0, 0, $dstW, $dstH, $dstW, $dstH); + imagedestroy($temp); + } elseif ($quality < 5 && (($dstW * $quality) < $srcW || ($dstH * $quality) < $srcH)) { + $tmpW = $dstW * $quality; + $tmpH = $dstH * $quality; + $temp = imagecreatetruecolor($tmpW + 1, $tmpH + 1); + imagecopyresized($temp, $srcImage, 0, 0, $srcX, $srcY, $tmpW + 1, $tmpH + 1, $srcW, $srcH); + imagecopyresampled($dstImage, $temp, $dstX, $dstY, 0, 0, $dstW, $dstH, $tmpW, $tmpH); + imagedestroy($temp); + } else { + imagecopyresampled($dstImage, $srcImage, $dstX, $dstY, $srcX, $srcY, $dstW, $dstH, $srcW, $srcH); + } + + return true; + } + + /** + * Source: http://pl.php.net/imagecreate + * (optimized for speed and memory usage, but yet not very efficient). + * + * @param string $data bitmap data + * + * @return resource + */ + public function createFromBmp($data) + { + $stream = fopen('php://temp', 'r+'); + fwrite($stream, $data); + rewind($stream); + + //20 seconds seems to be a reasonable value to not kill a server and process images up to 1680x1050 + @set_time_limit(20); + + if (!is_resource($stream)) { + return false; + } + + $FILE = unpack("vfile_type/Vfile_size/Vreserved/Vbitmap_offset", fread($stream, 14)); + if ($FILE['file_type'] != 19778) { + return false; + } + + $BMP = unpack('Vheader_size/Vwidth/Vheight/vplanes/vbits_per_pixel' . + '/Vcompression/Vsize_bitmap/Vhoriz_resolution' . + '/Vvert_resolution/Vcolors_used/Vcolors_important', fread($stream, 40)); + + $BMP['colors'] = pow(2, $BMP['bits_per_pixel']); + + if ($BMP['size_bitmap'] == 0) { + $BMP['size_bitmap'] = $FILE['file_size'] - $FILE['bitmap_offset']; + } + + $BMP['bytes_per_pixel'] = $BMP['bits_per_pixel'] / 8; + $BMP['bytes_per_pixel2'] = ceil($BMP['bytes_per_pixel']); + $BMP['decal'] = ($BMP['width'] * $BMP['bytes_per_pixel'] / 4); + $BMP['decal'] -= floor($BMP['width'] * $BMP['bytes_per_pixel'] / 4); + $BMP['decal'] = 4 - (4 * $BMP['decal']); + + if ($BMP['decal'] == 4) { + $BMP['decal'] = 0; + } + + $PALETTE = array(); + if ($BMP['colors'] < 16777216) { + $PALETTE = unpack('V' . $BMP['colors'], fread($stream, $BMP['colors'] * 4)); + } + + //2048x1536px@24bit don't even try to process larger files as it will probably fail + if ($BMP['size_bitmap'] > 3 * 2048 * 1536) { + return false; + } + + $IMG = fread($stream, $BMP['size_bitmap']); + fclose($stream); + $VIDE = chr(0); + + $res = imagecreatetruecolor($BMP['width'], $BMP['height']); + $P = 0; + $Y = $BMP['height'] - 1; + + $line_length = $BMP['bytes_per_pixel'] * $BMP['width']; + + if ($BMP['bits_per_pixel'] == 24) { + while ($Y >= 0) { + $X = 0; + $temp = unpack("C*", substr($IMG, $P, $line_length)); + + while ($X < $BMP['width']) { + $offset = $X * 3; + imagesetpixel($res, $X++, $Y, ($temp[$offset + 3] << 16) + ($temp[$offset + 2] << 8) + $temp[$offset + 1]); + } + $Y--; + $P += $line_length + $BMP['decal']; + } + } elseif ($BMP['bits_per_pixel'] == 8) { + while ($Y >= 0) { + $X = 0; + + $temp = unpack("C*", substr($IMG, $P, $line_length)); + + while ($X < $BMP['width']) { + imagesetpixel($res, $X++, $Y, $PALETTE[$temp[$X] + 1]); + } + $Y--; + $P += $line_length + $BMP['decal']; + } + } elseif ($BMP['bits_per_pixel'] == 4) { + while ($Y >= 0) { + $X = 0; + $i = 1; + $low = true; + + $temp = unpack("C*", substr($IMG, $P, $line_length)); + + while ($X < $BMP['width']) { + if ($low) { + $index = $temp[$i] >> 4; + } else { + $index = $temp[$i++] & 0x0F; + } + $low = !$low; + + imagesetpixel($res, $X++, $Y, $PALETTE[$index + 1]); + } + $Y--; + $P += $line_length + $BMP['decal']; + } + } elseif ($BMP['bits_per_pixel'] == 1) { + $COLOR = unpack("n", $VIDE . substr($IMG, floor($P), 1)); + if (($P * 8) % 8 == 0) { + $COLOR[1] = $COLOR[1] >> 7; + } elseif (($P * 8) % 8 == 1) { + $COLOR[1] = ($COLOR[1] & 0x40) >> 6; + } elseif (($P * 8) % 8 == 2) { + $COLOR[1] = ($COLOR[1] & 0x20) >> 5; + } elseif (($P * 8) % 8 == 3) { + $COLOR[1] = ($COLOR[1] & 0x10) >> 4; + } elseif (($P * 8) % 8 == 4) { + $COLOR[1] = ($COLOR[1] & 0x8) >> 3; + } elseif (($P * 8) % 8 == 5) { + $COLOR[1] = ($COLOR[1] & 0x4) >> 2; + } elseif (($P * 8) % 8 == 6) { + $COLOR[1] = ($COLOR[1] & 0x2) >> 1; + } elseif (($P * 8) % 8 == 7) { + $COLOR[1] = ($COLOR[1] & 0x1); + } + $COLOR[1] = $PALETTE[$COLOR[1] + 1]; + } else { + return false; + } + + return $res; + } + + /** + * Resizes an image to a given size keeping the aspect ratio. + * + * @param int $maxWidth maximum width + * @param int $maxHeight maximum height + * @param int $quality quality + * @param bool $useHigherFactor + * + * @return Image $this + */ + public function resize($maxWidth, $maxHeight, $quality = 80, $useHigherFactor = false) + { + $maxWidth = (int) $maxWidth ?: $this->width; + $maxHeight = (int) $maxHeight ?: $this->height; + + if ($this->width <= $maxWidth && $this->height <= $maxHeight) { + return $this; + } + + $targetSize = static::calculateAspectRatio($maxWidth, $maxHeight, $this->width, $this->height, $useHigherFactor); + + $targetWidth = $targetSize['width']; + $targetHeight = $targetSize['height']; + + $targetImage = imagecreatetruecolor($targetWidth, $targetHeight); + + if ($this->mime === 'image/png') { + $bg = imagecolorallocatealpha($targetImage, 255, 255, 255, 127); + imagefill($targetImage, 0, 0, $bg); + imagealphablending($targetImage, false); + imagesavealpha($targetImage, true); + } + + $this->fastCopyResampled($targetImage, $this->gdImage, 0, 0, 0, 0, $targetWidth, $targetHeight, + $this->width, $this->height, (int)max(floor($quality / 20), 6)); + + imagedestroy($this->gdImage); + $this->gdImage = $targetImage; + $this->width = $targetWidth; + $this->height = $targetHeight; + + return $this; + } + + /** + * Returns image data. + * + * @param string $format returned image format mimetype (current image mimetype is used if not set). + * + * @return string image data + */ + public function getData($format = null) + { + $mime = $format ?: $this->mime; + + ob_start(); + + switch ($mime) { + case 'image/gif': + imagegif($this->gdImage); + break; + case 'image/jpeg': + case 'image/bmp': + case 'image/x-ms-bmp': + imagejpeg($this->gdImage); + break; + case 'image/png': + imagealphablending($this->gdImage, false); + imagesavealpha($this->gdImage, true); + imagepng($this->gdImage); + break; + case 'image/wbmp': + imagewbmp($this->gdImage); + break; + } + + $this->dataSize = ob_get_length(); + + return ob_get_clean(); + } + + /** + * Returns GD image resource. + * + * @return resource GD image resource + */ + public function getGDImage() + { + return $this->gdImage; + } + + /** + * Returns the size of image data produced by the `getData()` method. + * + * @return int image data size in bytes + */ + public function getDataSize() + { + return $this->dataSize; + } + + /** + * Returns image width in pixels. + * + * @return int image width + */ + public function getWidth() + { + return $this->width; + } + + /** + * Returns image height in pixels. + * + * @return int image height + */ + public function getHeight() + { + return $this->height; + } + + /** + * Returns image MIME type. + * + * @return string MIME type + */ + public function getMimeType() + { + return $this->mime; + } + + public function crop($x, $y, $width, $height) + { + $targetImage = imagecreatetruecolor($width, $height); + + if ($this->mime === 'image/png') { + $bg = imagecolorallocatealpha($targetImage, 255, 255, 255, 127); + imagefill($targetImage, 0, 0, $bg); + imagealphablending($targetImage, false); + imagesavealpha($targetImage, true); + } + + imagecopy($targetImage, $this->gdImage, 0, 0, $x, $y, $width, $height); + + imagedestroy($this->gdImage); + $this->gdImage = $targetImage; + $this->width = $width; + $this->height = $height; + + return $this; + } + + public function rotate($degrees, $bgcolor = 0) + { + if ($this->mime === 'image/png') { + imagesavealpha($this->gdImage, true); + $bgcolor = imagecolorallocatealpha($this->gdImage, 0, 0, 0, 127); + } + + $this->gdImage = imagerotate($this->gdImage, $degrees, $bgcolor); + $this->width = imagesx($this->gdImage); + $this->height = imagesy($this->gdImage); + + return $this; + } + + public function getInfo() + { + $info = array( + 'width' => $this->getWidth(), + 'height' => $this->getHeight(), + 'size' => $this->getDataSize() + ); + + return $info; + } + + public function __destruct() + { + if (is_resource($this->gdImage)) { + imagedestroy($this->gdImage); + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Operation/OperationManager.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Operation/OperationManager.php new file mode 100644 index 0000000..abc5202 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Operation/OperationManager.php @@ -0,0 +1,294 @@ +app = $app; + $this->tempDirectory = $app['config']->get('tempDirectory'); + } + + /** + * Validates the operation ID. + * + * @param string $operationId + * + * @return bool `true` if the operation ID format is valid. + */ + protected function isValidOperationId($operationId) + { + return (bool) preg_match('/^[a-z0-9]{16}$/', $operationId); + } + + /** + * Starts a time consuming operation in the current request. + + * @return bool `true` if operation tracking was started. + */ + public function start() + { + $request = $this->app->getRequest(); + $operationId = (string) $request->query->get('operationId'); + + if (null === $operationId || !$this->isValidOperationId($operationId)) { + return false; + } + + if (!mkdir($this->getFilePath($operationId, null))) { + return false; + } + + $this->startedOperationId = $operationId; + $this->startTime = time(); + + ignore_user_abort(); + + // Session needs to be closed to not block probing requests + session_write_close(); + + return true; + } + + /** + * Aborts an operation with a given ID. + * + * @param string $operationId + * + * @return bool `true` if the operation was aborted. + */ + public function abort($operationId) + { + if (!$this->isValidOperationId($operationId) || !$this->operationStarted($operationId)) { + return false; + } + + file_put_contents($this->getFilePath($operationId, 'abort'), serialize(true)); + + return true; + } + + /** + * Checks if the operation started in the current request was aborted. + * + * @return bool `true` if the operation was aborted. + */ + public function isAborted() + { + if (!$this->startedOperationId) { + return false; + } + + clearstatcache(); + + return $this->operationStarted($this->startedOperationId) && + file_exists($this->getFilePath($this->startedOperationId, 'abort')); + } + + /** + * Updates the status of the current operation. + * + * @param array $status data describing the operation status. + */ + public function updateStatus(array $status) + { + if ($this->startedOperationId) { + $currentTime = time(); + + if ($currentTime - $this->lastUpdateTime >= self::UPDATE_STATUS_INTERVAL) { + $this->extendExecutionTime($currentTime); + + $this->lastUpdateTime = $currentTime; + + file_put_contents($this->getFilePath($this->startedOperationId), serialize($status)); + } + } + } + + /** + * Extends the execution time of the script. + * + * @param int $currentTime current timestamp + */ + protected function extendExecutionTime($currentTime) + { + if ($currentTime - $this->lastExtendExecutionTime >= self::EXTEND_EXECUTION_INTERVAL) { + set_time_limit(30); + + $this->lastExtendExecutionTime = $currentTime; + + // Emit some whitespaces for Nginx + FPM configuration to avoid 504 Gateway Timeout error + if (function_exists('fastcgi_finish_request')) { + // Clear the buffer to remove any garbage before flushing + Response::closeOutputBuffers(0, false); + echo ' '; + @ob_end_flush(); + @flush(); + } + } + } + + /** + * Returns the status of the current operation. + * + * @param string $operationId + * + * @return array operation status data + */ + public function getStatus($operationId) + { + if ($this->isValidOperationId($operationId)) { + $filePath = $this->getFilePath($operationId); + if (file_exists($filePath)) { + return unserialize(file_get_contents($filePath)); + } + } + + return null; + } + + /** + * Returns a path for a file located in the current operation temporary directory. + * + * @param string $operationId + * @param string $file + * + * @return string file path + */ + protected function getFilePath($operationId, $file = 'status') + { + return Path::combine($this->tempDirectory, 'ckf-operation-' . $operationId, $file); + } + + /** + * Checks if a temporary directory for an operation with a given ID exists. + * + * @param string $operationId + * + * @return bool `true` if the directory exists - the operation was started. + */ + protected function operationStarted($operationId) + { + $directoryPath = $this->getFilePath($operationId, null); + + return is_dir($directoryPath); + } + + /** + * Adds information about aborting to the long running request response. + */ + public function addInfoToResponse() + { + $this->app->on(KernelEvents::RESPONSE, function (FilterResponseEvent $event) { + $response = $event->getResponse(); + + if ($response instanceof JsonResponse) { + $responseData = (array) $response->getData(); + $responseData = array('aborted' => $this->isAborted()) + $responseData; + $response->setData($responseData); + } + }, 512); + } + + /** + * Destructor to remove temporary files if the operation was started for the current request. + */ + public function __destruct() + { + if ($this->startedOperationId) { + $directoryPath = $this->getFilePath($this->startedOperationId, null); + $toRemove = array( + $statusFilePath = Path::combine($directoryPath, 'status'), + $abortFilePath = Path::combine($directoryPath, 'abort') + ); + + foreach ($toRemove as $filePath) { + if (file_exists($filePath)) { + unlink($filePath); + } + } + + if (is_dir($directoryPath)) { + rmdir($directoryPath); + } + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Plugin/PluginInterface.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Plugin/PluginInterface.php new file mode 100644 index 0000000..d3b3be4 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Plugin/PluginInterface.php @@ -0,0 +1,40 @@ +isMethod('POST')) { + return $request; + } + + // Transform only if POST request contains jsonData field + $jsonData = $request->request->get('jsonData'); + + if (null === $jsonData) { + return $request; + } + + $jsonParameters = json_decode((string) $jsonData, true); + + if (is_array($jsonParameters)) { + $request->request->add($jsonParameters); + $request->request->remove('jsonData'); + } + + return $request; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Request/Transformer/TransformerInterface.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Request/Transformer/TransformerInterface.php new file mode 100644 index 0000000..aa17187 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Request/Transformer/TransformerInterface.php @@ -0,0 +1,35 @@ +resizedImageRepository = $resizedImageRepository; + + $backend = $this->backend = $sourceFileResourceType->getBackend(); + + // Check if there's info about source image in cache + $app = $this->resizedImageRepository->getContainer(); + + + if (!$forceRequestedSize) { + $cacheKey = Path::combine($sourceFileResourceType->getName(), $sourceFileDir, $sourceFileName); + + $cachedInfo = $app['cache']->get($cacheKey); + + // No info cached, get original image + if (null === $cachedInfo || !isset($cachedInfo['width']) || !isset($cachedInfo['height'])) { + $sourceFilePath = Path::combine($sourceFileResourceType->getDirectory(), $sourceFileDir, $sourceFileName); + + if ($backend->isHiddenFile($sourceFileName) || !$backend->has($sourceFilePath)) { + throw new FileNotFoundException('ResizedImage::create(): Source file not found'); + } + + $originalImage = $this->image = Image::create($backend->read($sourceFilePath)); + + $app['cache']->set($cacheKey, $originalImage->getInfo()); + + $originalImageWidth = $originalImage->getWidth(); + $originalImageHeight = $originalImage->getHeight(); + } else { + $originalImageWidth = $cachedInfo['width']; + $originalImageHeight = $cachedInfo['height']; + } + + $targetSize = Image::calculateAspectRatio($requestedWidth, $requestedHeight, $originalImageWidth, $originalImageHeight); + + if ($targetSize['width'] >= $originalImageWidth || $targetSize['height'] >= $originalImageHeight) { + $this->width = $originalImageWidth; + $this->height = $originalImageHeight; + $this->requestedSizeIsValid = false; + } else { + $this->width = $targetSize['width']; + $this->height = $targetSize['height']; + } + } else { + $this->width = $requestedWidth; + $this->height = $requestedHeight; + } + + $this->resizedImageFileName = static::createFilename($sourceFileName, $this->width, $this->height); + } + + public static function createFilename($fileName, $width, $height) + { + $pathInfo = pathinfo($fileName); + + return sprintf("%s__%dx%d%s", $pathInfo['filename'], $width, $height, isset($pathInfo['extension']) ? '.' . $pathInfo['extension'] : ''); + } + + public static function getSizeFromFilename($resizedImageFileName) + { + $pathInfo = pathinfo($resizedImageFileName); + + preg_match('/^.*__(\d+)x(\d+)$/', $pathInfo['filename'], $matches); + + if (count($matches) === 3) { + return array( + 'width' => (int) $matches[1], + 'height' => (int) $matches[2] + ); + } + + return null; + } + + /** + * Returns the directory of the resized image. + * + * @return string + */ + public function getDirectory() + { + return Path::combine($this->sourceFileResourceType->getDirectory(), + $this->sourceFileDir, + ResizedImage::DIR, + $this->sourceFileName + ); + } + + /** + * Creates a resized image. + */ + public function create() + { + if (null === $this->image) { + $sourceFilePath = Path::combine($this->sourceFileResourceType->getDirectory(), $this->sourceFileDir, $this->sourceFileName); + + if ($this->backend->isHiddenFile($this->sourceFileName) || !$this->backend->has($sourceFilePath)) { + throw new FileNotFoundException('ResizedImage::create(): Source file not found'); + } + + $this->image = Image::create($this->backend->read($sourceFilePath)); + } + + $this->image->resize($this->width, $this->height); + $this->resizedImageData = $this->image->getData(); + $this->resizedImageSize = $this->image->getDataSize(); + $this->resizedImageMimeType = $this->image->getMimeType(); + } + + /** + * Returns the direct URL to the resized image. + * + * @return string + */ + public function getUrl() + { + $backend = $this->sourceFileResourceType->getBackend(); + + /** + * In case the requested size is bigger than the size of the original image, + * the resized version was not created. + * This is a fallback that returns the URL to the original image. + */ + if (!$this->requestedSizeIsValid()) { + return $backend->getFileUrl($this->getResourceType(), $this->sourceFileDir, $this->sourceFileName); + } + + return $backend->getFileUrl($this->sourceFileResourceType, $this->sourceFileDir, $this->sourceFileName, $this->getFileName()); + } + + /** + * Checks if the size requested for the resized image is valid. + * + * @return bool `true` if the requested size is valid. + */ + public function requestedSizeIsValid() + { + return $this->requestedSizeIsValid; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/ResizedImage/ResizedImageAbstract.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/ResizedImage/ResizedImageAbstract.php new file mode 100644 index 0000000..cd6e7f0 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/ResizedImage/ResizedImageAbstract.php @@ -0,0 +1,280 @@ +sourceFileResourceType = $sourceFileResourceType; + $this->sourceFileDir = $sourceFileDir; + $this->sourceFileName = $sourceFileName; + $this->requestedWidth = $requestedWidth; + $this->requestedHeight = $requestedHeight; + + $this->backend = $sourceFileResourceType->getBackend(); + } + + /** + * Returns the resized image resource type. + * + * @return ResourceType + */ + public function getResourceType() + { + return $this->sourceFileResourceType; + } + + /** + * Returns the resized image file name. + * + * @return string + */ + public function getFileName() + { + return $this->resizedImageFileName; + } + + /** + * Returns the backend-relative resized image file path. + * + * @return string + */ + public function getFilePath() + { + return Path::combine($this->getDirectory(), $this->getFileName()); + } + + /** + * Returns the resized image MIME type. + * + * @return string + */ + public function getMimeType() + { + return $this->resizedImageMimeType; + } + + /** + * Returns a timestamp of the last modification of this resized image. + * + * @return int timestamp + */ + public function getTimestamp() + { + return $this->timestamp; + } + + /** + * Returns the resized image size in bytes. + * + * @return int + */ + public function getSize() + { + return $this->resizedImageSize; + } + + /** + * Returns the resized image binary data. + * + * @return string binary image date + */ + public function getImageData() + { + return $this->resizedImageData; + } + + /** + * Sets the image data. + * + * @param string $imageData binary image data + */ + public function setImageData($imageData) + { + $image = Image::create($imageData); + + $this->resizedImageSize = strlen($imageData); + $this->resizedImageMimeType = $image->getMimeType(); + $this->resizedImageData = $imageData; + + unset($image); + } + + /** + * Checks if the resized image already exists. + * + * @return bool + */ + public function exists() + { + return $this->backend->has($this->getFilePath()); + } + + /** + * Saves the resized image in the backend. + * + * @return bool `true` if saved successfully. + */ + public function save() + { + if (!$this->backend->hasDirectory($this->getDirectory())) { + $this->backend->createDir($this->getDirectory()); + } + + $saved = $this->backend->put($this->getFilePath(), $this->resizedImageData, array('mimetype' => $this->getMimeType())); + + if ($saved) { + $this->timestamp = time(); + } + + return $saved; + } + + /** + * Loads an existing resized image from a backend. + */ + public function load() + { + $thumbnailMetadata = $this->backend->getWithMetadata($this->getFilePath(), array('mimetype', 'timestamp')); + $this->timestamp = $thumbnailMetadata['timestamp']; + $this->resizedImageSize = $thumbnailMetadata['size']; + $this->resizedImageMimeType = $thumbnailMetadata['mimetype']; + + $this->resizedImageData = $this->backend->read($this->getFilePath()); + } + + /** + * Returns image data stream. + * + * @return bool|false|resource + * + * @throws CKFinderException + */ + public function readStream() + { + if (null === $this->resizedImageData) { + throw new CKFinderException('The resized image was not loaded from a backend yet. Please use ResizedImage::load() first.'); + } + + // The image should be already loaded the memory, no need to read stream from backend + $stream = fopen('php://temp', 'r+'); + fwrite($stream, $this->resizedImageData); + rewind($stream); + + return $stream; + } + + /** + * Creates the resized image. + */ + abstract public function create(); + + /** + * Returns a directory path for the resized image. + */ + abstract public function getDirectory(); +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/ResizedImage/ResizedImageRepository.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/ResizedImage/ResizedImageRepository.php new file mode 100644 index 0000000..9db5e81 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/ResizedImage/ResizedImageRepository.php @@ -0,0 +1,422 @@ +config = $app['config']; + $this->acl = $app['acl']; + $this->dispatcher = $app['dispatcher']; + $this->app = $app; + } + + /** + * Returns a resized image for the provided source file. + * + * If an appropriate resized version already exists, it is reused. + * + * @param ResourceType $sourceFileResourceType + * @param string $sourceFileDir + * @param string $sourceFileName + * @param int $requestedWidth + * @param int $requestedHeight + * + * @return ResizedImage + * + * @throws \Exception + */ + public function getResizedImage(ResourceType $sourceFileResourceType, $sourceFileDir, $sourceFileName, $requestedWidth, $requestedHeight) + { + $resizedImage = new ResizedImage( + $this, + $sourceFileResourceType, + $sourceFileDir, + $sourceFileName, + $requestedWidth, + $requestedHeight + ); + + if (!$this->acl->isAllowed($sourceFileResourceType->getName(), $sourceFileDir, Permission::IMAGE_RESIZE_CUSTOM) && + !$this->isSizeAllowedInConfig($requestedWidth, $requestedHeight)) { + throw new UnauthorizedException('Provided size is not allowed in images.sizes configuration'); + } + + if (!$resizedImage->exists() && $resizedImage->requestedSizeIsValid()) { + $resizedImage->create(); + + $resizeImageEvent = new ResizeImageEvent($this->app, $resizedImage); + $this->dispatcher->dispatch(CKFinderEvent::CREATE_RESIZED_IMAGE, $resizeImageEvent); + + if (!$resizeImageEvent->isPropagationStopped()) { + $resizedImage = $resizeImageEvent->getResizedImage(); + $resizedImage->save(); + } + } + + return $resizedImage; + } + + /** + * Returns an existing resized image. + * + * @param ResourceType $sourceFileResourceType + * @param string $sourceFileDir + * @param string $sourceFileName + * @param string $thumbnailFileName + * + * @return ResizedImage + * + * @throws FileNotFoundException + */ + public function getExistingResizedImage(ResourceType $sourceFileResourceType, $sourceFileDir, $sourceFileName, $thumbnailFileName) + { + $size = ResizedImage::getSizeFromFilename($thumbnailFileName); + + $resizedImage = new ResizedImage( + $this, + $sourceFileResourceType, + $sourceFileDir, + $sourceFileName, + $size['width'], + $size['height'], + true + ); + + if (!$resizedImage->exists()) { + throw new FileNotFoundException('Resized image not found'); + } + + $resizedImage->load(); + + return $resizedImage; + } + + /** + * @return CKFinder + */ + public function getContainer() + { + return $this->app; + } + + /** + * Checks if the provided image size is allowed in the configuration. + * + * This is checked when `Permission::IMAGE_RESIZE_CUSTOM` + * is not allowed in the source file folder. + * + * @param int $width + * @param int $height + * + * @return bool `true` if the provided size is allowed in the configuration. + */ + protected function isSizeAllowedInConfig($width, $height) + { + $configSizes = $this->config->get('images.sizes'); + + foreach ($configSizes as $size) { + if ($size['width'] === $width && $size['height'] === $height) { + return true; + } + } + + return false; + } + + /** + * Returns the size name defined in the configuration, where width + * or height are equal to those given in parameters. + * + * Resized images keep the original image aspect ratio. + * When an image is resized using the size from the configuration, + * at least one of the borders has the same length. + * + * @param int $width + * @param int $height + * + * @return bool `true` if the size from the configuration was used. + */ + protected function getSizeNameFromConfig($width, $height) + { + $configSizes = $this->config->get('images.sizes'); + + foreach ($configSizes as $sizeName => $size) { + if ($size['width'] === $width || $size['height'] === $height) { + return $sizeName; + } + } + + return null; + } + + /** + * Deletes all resized images for a given file. + * + * @param ResourceType $sourceFileResourceType + * @param string $sourceFilePath + * @param string $sourceFileName + * + * @return bool `true` if deleted + */ + public function deleteResizedImages(ResourceType $sourceFileResourceType, $sourceFilePath, $sourceFileName) + { + $resizedImagesPath = Path::combine($sourceFileResourceType->getDirectory(), $sourceFilePath, ResizedImage::DIR, $sourceFileName); + + $backend = $sourceFileResourceType->getBackend(); + + if ($backend->hasDirectory($resizedImagesPath)) { + return $backend->deleteDir($resizedImagesPath); + } + + return false; + } + + /** + * Copies all resized images for a given file. + * + * @param ResourceType $sourceFileResourceType + * @param string $sourceFilePath + * @param string $sourceFileName + * @param ResourceType $targetFileResourceType + * @param string $targetFilePath + * @param string $targetFileName + */ + public function copyResizedImages(ResourceType $sourceFileResourceType, $sourceFilePath, $sourceFileName, + ResourceType $targetFileResourceType, $targetFilePath, $targetFileName) + { + $sourceResizedImagesPath = Path::combine($sourceFileResourceType->getDirectory(), $sourceFilePath, ResizedImage::DIR, $sourceFileName); + $targetResizedImagesPath = Path::combine($targetFileResourceType->getDirectory(), $targetFilePath, ResizedImage::DIR, $targetFileName); + + $sourceBackend = $sourceFileResourceType->getBackend(); + $targetBackend = $targetFileResourceType->getBackend(); + + if ($sourceBackend->hasDirectory($sourceResizedImagesPath)) { + $resizedImages = $sourceBackend->listContents($sourceResizedImagesPath); + + foreach ($resizedImages as $resizedImage) { + if (!isset($resizedImage['path'])) { + continue; + } + + $resizedImageStream = $sourceBackend->readStream($resizedImage['path']); + + $sourceImageSize = ResizedImage::getSizeFromFilename($resizedImage['basename']); + $targetImageFilename = ResizedImage::createFilename($targetFileName, $sourceImageSize['width'], $sourceImageSize['height']); + + $targetBackend->putStream(Path::combine($targetResizedImagesPath, $targetImageFilename), $resizedImageStream); + } + } + } + + /** + * Renames all resized images created for a given file. + * + * @param ResourceType $sourceFileResourceType + * @param string $sourceFilePath + * @param string $originalSourceFileName + * @param string $newSourceFileName + */ + public function renameResizedImages(ResourceType $sourceFileResourceType, $sourceFilePath, $originalSourceFileName, $newSourceFileName) + { + $resizedImagesDir = Path::combine($sourceFileResourceType->getDirectory(), $sourceFilePath, ResizedImage::DIR); + $resizedImagesPath = Path::combine($resizedImagesDir, $originalSourceFileName); + $newResizedImagesPath = Path::combine($resizedImagesDir, $newSourceFileName); + + $backend = $sourceFileResourceType->getBackend(); + + if ($backend->hasDirectory($resizedImagesPath)) { + if ($backend->rename($resizedImagesPath, $newResizedImagesPath)) { + $resizedImages = $backend->listContents($newResizedImagesPath); + + foreach ($resizedImages as $resizedImage) { + if (!isset($resizedImage['path'])) { + continue; + } + + $sourceImageSize = ResizedImage::getSizeFromFilename($resizedImage['basename']); + $newResizedImageFilename = ResizedImage::createFilename($newSourceFileName, $sourceImageSize['width'], $sourceImageSize['height']); + + $backend->rename($resizedImage['path'], Path::combine($newResizedImagesPath, $newResizedImageFilename)); + } + } + } + } + + /** + * Returns a list of resized images generated for a given file. + * + * @param ResourceType $sourceFileResourceType source file resource type + * @param string $sourceFilePath source file backend-relative path + * @param string $sourceFileName source file name + * @param array $filterSizes array containing names of sizes defined + * in the `images.sizes` configuration + * + * @return array + */ + public function getResizedImagesList(ResourceType $sourceFileResourceType, $sourceFilePath, $sourceFileName, $filterSizes = array()) + { + $resizedImagesPath = Path::combine($sourceFileResourceType->getDirectory(), $sourceFilePath, ResizedImage::DIR, $sourceFileName); + + $backend = $sourceFileResourceType->getBackend(); + + $resizedImages = array(); + + if (!$backend->hasDirectory($resizedImagesPath)) { + return $resizedImages; + } + + $resizedImagesFiles = array_filter( + $backend->listContents($resizedImagesPath), + function ($v) { + return isset($v['type']) && $v['type'] === 'file'; + } + ); + + foreach ($resizedImagesFiles as $resizedImage) { + $size = ResizedImage::getSizeFromFilename($resizedImage['basename']); + + if ($sizeName = $this->getSizeNameFromConfig($size['width'], $size['height'])) { + if (empty($filterSizes) || in_array($sizeName, $filterSizes)) { + $resizedImages[$sizeName] = $this->createNodeValue($resizedImage); + } + continue; + } + + if (empty($filterSizes)) { + if (!isset($resizedImages['__custom'])) { + $resizedImages['__custom'] = array(); + } + + $resizedImages['__custom'][] = $this->createNodeValue($resizedImage); + } + } + + return $resizedImages; + } + + protected function createNodeValue($resizedImage) + { + if (isset($resizedImage['url'])) { + return array( + 'name' => $resizedImage['basename'], + 'url' => $resizedImage['url'] + ); + } + + return $resizedImage['basename']; + } + + /** + * @param ResourceType $sourceFileResourceType + * @param string $sourceFilePath + * @param string $sourceFileName + * @param int $width + * @param int $height + * + * @return ResizedImage|null + */ + public function getResizedImageBySize(ResourceType $sourceFileResourceType, $sourceFilePath, $sourceFileName, $width, $height) + { + $resizedImagesPath = Path::combine($sourceFileResourceType->getDirectory(), $sourceFilePath, ResizedImage::DIR, $sourceFileName); + + $backend = $sourceFileResourceType->getBackend(); + + if (!$backend->hasDirectory($resizedImagesPath)) { + return null; + } + + $resizedImagesFiles = array_filter( + $backend->listContents($resizedImagesPath), + function ($v) { + return isset($v['type']) && $v['type'] === 'file'; + } + ); + + $thresholdPixels = $this->config->get('images.threshold.pixels'); + $thresholdPercent = (float) $this->config->get('images.threshold.percent') / 100; + + foreach ($resizedImagesFiles as $resizedImage) { + $resizedImageSize = ResizedImage::getSizeFromFilename($resizedImage['basename']); + $resizedImageWidth = $resizedImageSize['width']; + $resizedImageHeight = $resizedImageSize['height']; + if ($resizedImageWidth >= $width && ($resizedImageWidth <= $width + $thresholdPixels || $resizedImageWidth <= $width + $width * $thresholdPercent) + && $resizedImageHeight >= $height && ($resizedImageHeight <= $height + $thresholdPixels || $resizedImageHeight <= $height + $height * $thresholdPercent)) { + $resizedImage = new ResizedImage( + $this, + $sourceFileResourceType, + $sourceFilePath, + $sourceFileName, + $resizedImageWidth, + $resizedImageHeight + ); + + if ($resizedImage->exists()) { + $resizedImage->load(); + + return $resizedImage; + } + } + } + + return null; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/ResourceType/ResourceType.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/ResourceType/ResourceType.php new file mode 100644 index 0000000..732db91 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/ResourceType/ResourceType.php @@ -0,0 +1,113 @@ +name = $name; + $this->configNode = $configNode; + $this->backend = $backend; + $this->thumbnailRepository = $thumbnailRepository; + $this->resizedImageRepository = $resizedImageRepository; + } + + public function getName() + { + return $this->name; + } + + public function getDirectory() + { + return $this->configNode['directory']; + } + + public function getBackend() + { + return $this->backend; + } + + public function getThumbnailRepository() + { + return $this->thumbnailRepository; + } + + public function getResizedImageRepository() + { + return $this->resizedImageRepository; + } + + public function getMaxSize() + { + return $this->configNode['maxSize']; + } + + public function getAllowedExtensions() + { + return $this->configNode['allowedExtensions']; + } + + public function getDeniedExtensions() + { + return $this->configNode['deniedExtensions']; + } + + public function getLabel() + { + return isset($this->configNode['label']) ? $this->configNode['label'] : null; + } + + public function isLazyLoaded() + { + return isset($this->configNode['lazyLoad']) && $this->configNode['lazyLoad']; + } + + public function isAllowedExtension($extension) + { + $extension = strtolower(ltrim($extension, '.')); + + $allowed = $this->configNode['allowedExtensions']; + $denied = $this->configNode['deniedExtensions']; + + if (!empty($allowed) && !in_array($extension, $allowed) || + !empty($denied) && in_array($extension, $denied)) { + return false; + } + + return true; + } + + /** + * Returns the resource type hash. + * + * @return string hash string + */ + public function getHash() + { + return substr(md5($this->configNode['name'] . $this->configNode['backend'] . $this->configNode['directory'] . $this->backend->getBaseUrl() . $this->backend->getRootDirectory()), 0, 16); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/ResourceType/ResourceTypeFactory.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/ResourceType/ResourceTypeFactory.php new file mode 100644 index 0000000..c40977f --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/ResourceType/ResourceTypeFactory.php @@ -0,0 +1,56 @@ +app = $app; + $this->config = $app['config']; + $this->backendFactory = $app['backend_factory']; + $this->thumbnailRepository = $app['thumbnail_repository']; + $this->resizedImageRepository = $app['resized_image_repository']; + } + + /** + * Returns the resource type object with a given name. + * + * @param string $name resource type name + * + * @return ResourceType + */ + public function getResourceType($name) + { + if (!$this->offsetExists($name)) { + $resourceTypeConfig = $this->config->getResourceTypeNode($name); + $backend = $this->backendFactory->getBackend($resourceTypeConfig['backend']); + + $this[$name] = new ResourceType($name, $resourceTypeConfig, $backend, $this->thumbnailRepository, $this->resizedImageRepository); + } + + return $this[$name]; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Response/JsonResponse.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Response/JsonResponse.php new file mode 100644 index 0000000..21d13e3 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Response/JsonResponse.php @@ -0,0 +1,67 @@ +rawData = $data; + } + + public function getData() + { + return $this->rawData; + } + + public function setData($data = array()) + { + $this->rawData = $data; + + return parent::setData($this->rawData); + } + + public function withError($errorNumber, $errorMessage = null) + { + $errorData = array('number' => $errorNumber); + + if ($errorMessage) { + $errorData['message'] = $errorMessage; + } + + $data = (array) $this->rawData; + + $data = array('error' => $errorData) + $data; + + $this->setData($data); + + return $this; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Security/Csrf/DoubleSubmitCookieTokenValidator.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Security/Csrf/DoubleSubmitCookieTokenValidator.php new file mode 100644 index 0000000..b726f7c --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Security/Csrf/DoubleSubmitCookieTokenValidator.php @@ -0,0 +1,80 @@ +tokenParamName = $tokenParamName; + $this->tokenCookieName = $tokenCookieName; + $this->minTokenLength = $minTokenLength; + } + + /** + * Checks if the request contains a valid CSRF token. + * + * @param Request $request + * + * @return bool `true` if the token is valid, `false` otherwise. + */ + public function validate(Request $request) + { + $paramToken = trim((string) $request->get($this->tokenParamName)); + $cookieToken = trim((string) $request->cookies->get($this->tokenCookieName)); + + if (strlen($paramToken) >= $this->minTokenLength && strlen($cookieToken) >= $this->minTokenLength) { + return $paramToken === $cookieToken; + } + + return false; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Security/Csrf/TokenValidatorInterface.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Security/Csrf/TokenValidatorInterface.php new file mode 100644 index 0000000..06e5083 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Security/Csrf/TokenValidatorInterface.php @@ -0,0 +1,34 @@ + '150', 'height' => '150', 'quality' => 80) + * + * @var array $adjustedSizeInfo + */ + protected $adjustedSizeInfo; + + /** + * @param ThumbnailRepository $thumbnailRepository + * @param ResourceType $sourceFileResourceType + * @param string $sourceFileDir + * @param string $sourceFileName + * @param int $requestedWidth + * @param int $requestedHeight + */ + public function __construct(ThumbnailRepository $thumbnailRepository, ResourceType $sourceFileResourceType, $sourceFileDir, $sourceFileName, $requestedWidth, $requestedHeight) + { + parent::__construct($sourceFileResourceType, $sourceFileDir, $sourceFileName, $requestedWidth, $requestedHeight); + + $this->thumbnailRepository = $thumbnailRepository; + + $this->adjustDimensions(); + $this->backend = $thumbnailRepository->getThumbnailBackend(); + + $width = $this->adjustedSizeInfo['width']; + $height = $this->adjustedSizeInfo['height']; + + $this->resizedImageFileName = ResizedImage::createFilename($sourceFileName, $width, $height); + } + + /** + * Adjusts thumbnail dimensions. + * + * Dimensions passed in `$requestedWidth` and `$requestedHeight` + * are adjusted to one of the allowed sizes. The smallest allowed + * thumbnail size that is bigger than the requested one is used. + */ + protected function adjustDimensions() + { + $allowedSizes = $this->thumbnailRepository->getAllowedSizes(); + + $this->adjustedSizeInfo = end($allowedSizes); + + foreach ($allowedSizes as $sizeInfo) { + if ($sizeInfo['width'] >= $this->requestedWidth && $sizeInfo['height'] >= $this->requestedHeight) { + $this->adjustedSizeInfo = $sizeInfo; + break; + } + } + } + + /** + * Returns backend-relative thumbnails directory. + * + * @return string + */ + public function getDirectory() + { + return Path::combine( + $this->thumbnailRepository->getThumbnailsPath(), + $this->sourceFileResourceType->getName(), + $this->sourceFileDir, + $this->sourceFileName); + } + + /** + * Creates a thumbnail. + * + * @return bool + * + * @throws \Exception + */ + public function create() + { + $sourceBackend = $this->sourceFileResourceType->getBackend(); + $sourceFilePath = Path::combine($this->sourceFileResourceType->getDirectory(), $this->sourceFileDir, $this->sourceFileName); + + if ($sourceBackend->isHiddenFile($this->sourceFileName) || !$sourceBackend->has($sourceFilePath)) { + throw new FileNotFoundException('Thumbnail::create(): Source file not found'); + } + + $image = Image::create($sourceBackend->read($sourceFilePath), $this->thumbnailRepository->isBitmapSupportEnabled()); + + // Update cached info about image + $app = $this->thumbnailRepository->getContainer(); + $app['cache']->set( + Path::combine($this->sourceFileResourceType->getName(), $this->sourceFileDir, $this->sourceFileName), + $image->getInfo() + ); + + $image->resize($this->adjustedSizeInfo['width'], $this->adjustedSizeInfo['height'], $this->adjustedSizeInfo['quality']); + + $this->resizedImageData = $image->getData(); + $this->resizedImageSize = $image->getDataSize(); + $this->resizedImageMimeType = $image->getMimeType(); + + unset($image); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Thumbnail/ThumbnailRepository.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Thumbnail/ThumbnailRepository.php new file mode 100644 index 0000000..ea92e7f --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Thumbnail/ThumbnailRepository.php @@ -0,0 +1,178 @@ +app = $app; + $this->config = $app['config']; + $this->thumbsBackend = $app['backend_factory']->getPrivateDirBackend('thumbs'); + $this->dispatcher = $app['dispatcher']; + } + + /** + * Returns the Backend object where thumbnails are stored. + * + * @return Backend + */ + public function getThumbnailBackend() + { + return $this->thumbsBackend; + } + + /** + * @return CKFinder + */ + public function getContainer() + { + return $this->app; + } + + /** + * Returns backend-relative directory path where + * thumbnails are stored. + * + * @return string + */ + public function getThumbnailsPath() + { + return $this->config->getPrivateDirPath('thumbs'); + } + + /** + * Returns an array of allowed sizes for thumbnails. + * + * @return array + */ + public function getAllowedSizes() + { + return $this->config->get('thumbnails.sizes'); + } + + /** + * Returns information about bitmap support for thumbnails. If bitmap + * support is disabled, thumbnails for bitmaps will not be generated. + * + * @return bool `true` if bitmap support is enabled. + */ + public function isBitmapSupportEnabled() + { + return $this->config->get('thumbnails.bmpSupported'); + } + + /** + * Returns a thumbnail object for a given file defined by the resource type, + * path and file name. + * The real size of the thumbnail image will be adjusted to one of the sizes + * allowed by the thumbnail configuration. + * + * @param ResourceType $resourceType source file resource type + * @param string $path source file directory path + * @param string $fileName source file name + * @param int $requestedWidth requested thumbnail height + * @param int $requestedHeight requested thumbnail height + * + * @return Thumbnail + * + * @throws \Exception + */ + public function getThumbnail(ResourceType $resourceType, $path, $fileName, $requestedWidth, $requestedHeight) + { + $thumbnail = new Thumbnail($this, $resourceType, $path, $fileName, $requestedWidth, $requestedHeight); + + if (!$thumbnail->exists()) { + $thumbnail->create(); + + $createThumbnailEvent = new ResizeImageEvent($this->app, $thumbnail); + $this->dispatcher->dispatch(CKFinderEvent::CREATE_THUMBNAIL, $createThumbnailEvent); + + if (!$createThumbnailEvent->isPropagationStopped()) { + $thumbnail = $createThumbnailEvent->getResizedImage(); + $thumbnail->save(); + } + } else { + $thumbnail->load(); + } + + return $thumbnail; + } + + /** + * Deletes all thumbnails under the given path defined by the resource type, + * path and file name. + * + * @param ResourceType $resourceType + * @param string $path + * @param string $fileName + * + * @return bool `true` if deleted successfully + */ + public function deleteThumbnails(ResourceType $resourceType, $path, $fileName = null) + { + $path = Path::combine($this->getThumbnailsPath(), $resourceType->getName(), $path, $fileName); + + if ($this->thumbsBackend->has($path)) { + return $this->thumbsBackend->deleteDir($path); + } + + return false; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Translator.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Translator.php new file mode 100644 index 0000000..e4b1a40 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Translator.php @@ -0,0 +1,85 @@ +setLocale($locale); + } + + /** + * Sets locale for translations. + * + * @param string $locale + */ + protected function setLocale($locale) + { + if (null === $locale || !preg_match('/^[a-z\-]{2,5}$/', $locale) || !file_exists(__DIR__ . "/locales/{$locale}.json")) { + $locale = 'en'; + } + + if (null === $this->translations) { + $this->translations = json_decode(file_get_contents(__DIR__ . "/locales/{$locale}.json"), true); + } + } + + /** + * Translates an error message for a given error code. + * + * @param int $errorNumber error number + * @param array $replacements array of replacements to use in the translated message. + * + * @return string + */ + public function translateErrorMessage($errorNumber, $replacements = array()) + { + $errorMessage = ''; + + if ($errorNumber) { + if (isset($this->translations['errors'][$errorNumber])) { + $errorMessage = $this->translations['errors'][$errorNumber]; + + foreach ($replacements as $from => $to) { + $errorMessage = str_replace('{' . $from . '}', $to, $errorMessage); + } + } else { + $errorMessage = str_replace('{number}', $errorNumber, $this->translations['errorUnknown']); + } + } + + return $errorMessage; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Utils.php b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Utils.php new file mode 100644 index 0000000..1478a18 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Utils.php @@ -0,0 +1,307 @@ +$_SERVER['SCRIPT_FILENAME'] will contain the relative path specified by the user. + */ + public static function getRootPath() + { + if (isset($_SERVER['SCRIPT_FILENAME'])) { + $sRealPath = dirname($_SERVER['SCRIPT_FILENAME']); + } else { + /** + * realpath — Returns canonicalized absolute pathname + */ + $sRealPath = realpath('.'); + } + + $sRealPath = static::trimPathTrailingSlashes($sRealPath); + + /** + * The file name of the currently executing script, relative to the document root. + * For instance, $_SERVER['PHP_SELF'] in a script at the address `http://example.com/test.php/foo.bar` + * would be `/test.php/foo.bar`. + */ + $sSelfPath = dirname($_SERVER['PHP_SELF']); + $sSelfPath = static::trimPathTrailingSlashes($sSelfPath); + + return static::trimPathTrailingSlashes(substr($sRealPath, 0, strlen($sRealPath) - strlen($sSelfPath))); + } + + /** + * @param string $path + * + * @return string + */ + protected static function trimPathTrailingSlashes($path) + { + return rtrim($path, DIRECTORY_SEPARATOR . '/\\'); + } + + /** + * Checks if an array contains all specified keys. + * + * @param array $array + * @param array $keys + * + * @return `true` if the array has all required keys, `false` otherwise. + */ + public static function arrayContainsKeys(array $array, array $keys) + { + return count(array_intersect_key(array_flip($keys), $array)) === count($keys); + } + + /** + * Simulates the `encodeURIComponent()` function available in JavaScript. + * + * @param string $str + * + * @return string + */ + public static function encodeURLComponent($str) + { + $revert = array('%21'=>'!', '%2A'=>'*', '%27'=>"'", '%28'=>'(', '%29'=>')'); + + return strtr(rawurlencode($str), $revert); + } + + /** + * Decodes the URL component. + * + * @param string $str + * + * @return string + */ + public static function decodeURLComponent($str) + { + return rawurldecode($str); + } + + /** + * Decodes URL parts. + * + * @param string $str + * + * @return string + */ + public static function decodeURLParts($str) + { + return static::decodeURLComponent($str); + } + + /** + * Encodes URL parts. + * + * @param string $str + * + * @return string + */ + public static function encodeURLParts($str) + { + $revert = array('%2F'=>'/'); + + return strtr(static::encodeURLComponent($str), $revert); + } + + /** + * Returns a formatted date string generated for a given timestamp. + * + * @param int $timestamp + * + * @return string + */ + public static function formatDate($timestamp) + { + return date('YmdHis', $timestamp); + } + + /** + * Returns formatted file size. + * + * @param int $size size in bytes + * + * @return int + */ + public static function formatSize($size) + { + $size = (int) $size; + + return ($size && $size < 1024) ? 1 : (int) round($size / 1024); + } + + /** + * Removes any cache headers that might be set by the session cache limiter. + * See @link http://php.net/manual/en/function.session-cache-limiter.php + */ + public static function removeSessionCacheHeaders() + { + $headersToRemove = array('Expires', 'Cache-Control', 'Last-Modified', 'Pragma'); + + foreach ($headersToRemove as $header) { + header_remove($header); + } + } + + /** + * Checks if a given data chunk contains HTML-like data. + * + * If the `mbstring` extension is available, additionally the following encodings are checked: + * UTF-7, UTF-16BE, UTF-16LE, UTF-32BE, UTF-32LE. + * + * @param string $chunk + * + * @return bool `true` if the provided code chunk contains HTML-like data. + */ + public static function containsHtml($chunk) + { + if (extension_loaded('mbstring')) { + $encodingsToCheck = array('UTF-7', 'UTF-16BE', 'UTF-16LE', 'UTF-32BE', 'UTF-32LE'); + $supportedEncodings = mb_list_encodings(); + + foreach ($encodingsToCheck as $encodingFrom) { + if (!in_array($encodingFrom, $supportedEncodings)) { + continue; + } + + $chunkUtf8 = mb_convert_encoding($chunk, 'UTF-8', $encodingFrom); + + if (static::containsHtmlUTF8($chunkUtf8)) { + return true; + } + } + } + + return static::containsHtmlUTF8($chunk); + } + + /** + * Checks if a given data chunk contains HTML-like data (assuming that the given chunk is encoded as UTF-8). + * + * @param string $chunk + * + * @return bool + */ + public static function containsHtmlUTF8($chunk) + { + if (!$chunk) { + return false; + } + + $chunk = strtolower($chunk); + + $chunk = trim($chunk); + + if (preg_match("/isAllowedExtension($ext) ? '.' : '_'; + $basename .= $ext; + } + + // Add the last extension to the final name. + return $basename . '.' . $lastExtension; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/bg.json b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/bg.json new file mode 100644 index 0000000..c27d9f5 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/bg.json @@ -0,0 +1,33 @@ +{ + "errorUnknown": "Не е възможно да се извърши заявката. (ГРЕШКА {number})", + "errors": { + "10": "Невалидна команда.", + "11": "Типът на ресурса не е определен в заявката.", + "12": "Заявеният тип на ресурса не е намерен.", + "13": "The connector configuration file is invalid.", + "14": "Invalid connector plugin: {pluginName}.", + "102": "Невалиден файл или име на папка.", + "103": "Не е възможно да се извърши действието заради проблем с идентификацията.", + "104": "Не е възможно да се извърши действието заради проблем с правата.", + "105": "Невалидно файлово разширение.", + "109": "Невалидна заявка.", + "110": "Неизвестна грешка.", + "111": "It was not possible to complete the request due to resulting file size.", + "115": "Файл или папка със същото име вече съществува.", + "116": "Папката не е намерена, опреснете и опитайте отново.", + "117": "Файлът не е намерен, опреснете и опитайте отново.", + "118": "Пътищата за цел и източник трябва да са еднакви.", + "201": "Файл с такова име съществува, каченият файл е преименуван на \"{name}\".", + "202": "Невалиден файл.", + "203": "Невалиден файл. Размерът е прекалено голям.", + "204": "Каченият файл е повреден.", + "205": "Няма временна папка за качените файлове.", + "206": "Качването е спряно заради проблеми със сигурността. Файлът съдържа HTML данни.", + "207": "Каченият файл е преименуван на \"{name}\".", + "300": "Преместването на файловете пропадна.", + "301": "Копирането на файловете пропадна.", + "302": "Deleting file(s) failed.", + "500": "Файловият браузър е изключен заради проблеми със сигурността. Моля свържете се с Вашия системен администратор и проверете конфигурацията.", + "501": "Поддръжката за миниатюри е изключена." + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/ca.json b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/ca.json new file mode 100644 index 0000000..1725e3b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/ca.json @@ -0,0 +1,33 @@ +{ + "errorUnknown": "No ha estat possible completar la solicitut. (Error {number})", + "errors": { + "10": "Ordre incorrecte.", + "11": "El tipus de recurs no ha estat especificat a la solicitut.", + "12": "El tipus de recurs solicitat no és vàlid.", + "13": "The connector configuration file is invalid.", + "14": "Invalid connector plugin: {pluginName}.", + "102": "Nom de fitxer o carpeta no vàlids.", + "103": "No s'ha pogut completar la solicitut degut a les restriccions d'autorització.", + "104": "No s'ha pogut completar la solicitut degut a les restriccions en el sistema de fitxers.", + "105": "La extensió del fitxer no es vàlida.", + "109": "Petició invàlida.", + "110": "Error desconegut.", + "111": "No ha estat possible completar l'operació a causa de la grandària del fitxer resultant.", + "115": "Ja existeix un fitxer o carpeta amb aquest nom.", + "116": "No s'ha trobat la carpeta. Si us plau, actualitzi i torni-ho a provar.", + "117": "No s'ha trobat el fitxer. Si us plau, actualitzi i torni-ho a provar.", + "118": "Les rutes origen i destí són iguals.", + "201": "Ja existeix un fitxer amb aquest nom. El fitxer pujat ha estat renombrat com a \"{name}\".", + "202": "Fitxer invàlid.", + "203": "Fitxer invàlid. El pes és massa gran.", + "204": "El fitxer pujat està corrupte.", + "205": "La carpeta temporal no està disponible en el servidor per poder realitzar pujades.", + "206": "La pujada s'ha cancel·lat per raons de seguretat. El fitxer conté codi HTML.", + "207": "El fitxer pujat ha estat renombrat com a \"{name}\".", + "300": "Ha fallat el moure el(s) fitxer(s).", + "301": "Ha fallat el copiar el(s) fitxer(s).", + "302": "Deleting file(s) failed.", + "500": "El navegador de fitxers està deshabilitat per raons de seguretat. Si us plau, contacti amb l'administrador del sistema i comprovi el fitxer de configuració de CKFinder.", + "501": "El suport per a icones està deshabilitat." + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/cs.json b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/cs.json new file mode 100644 index 0000000..196f73e --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/cs.json @@ -0,0 +1,33 @@ +{ + "errorUnknown": "Příkaz nebylo možné dokončit. (Chyba {number})", + "errors": { + "10": "Neplatný příkaz.", + "11": "Typ zdroje nebyl v požadavku určen.", + "12": "Požadovaný typ zdroje není platný.", + "13": "Soubor s nastavením konektoru je neplatný.", + "14": "Neplatný zásuvný model konektoru: {pluginName}.", + "102": "Špatné název souboru, nebo složky.", + "103": "Nebylo možné příkaz dokončit kvůli omezení oprávnění.", + "104": "Nebylo možné příkaz dokončit kvůli omezení oprávnění souborového systému.", + "105": "Neplatná přípona souboru.", + "109": "Neplatný požadavek.", + "110": "Neznámá chyba.", + "111": "Požadavek nemohl být splněn kvůli výsledné velikosti souboru.", + "115": "Soubor nebo složka se stejným názvem již existuje.", + "116": "Složka nenalezena, prosím obnovte a zkuste znovu.", + "117": "Soubor nenalezen, prosím obnovte seznam souborů a zkuste znovu.", + "118": "Cesty zdroje a cíle jsou stejné.", + "201": "Soubor se stejným názvem je již dostupný, nahraný soubor byl přejmenován na \"{name}\".", + "202": "Neplatný soubor.", + "203": "Neplatný soubor. Velikost souboru je příliš velká.", + "204": "Nahraný soubor je poškozen.", + "205": "Na serveru není dostupná dočasná složka pro nahrávání.", + "206": "Nahrávání zrušeno z bezpečnostních důvodů. Soubor obsahuje data podobná HTML.", + "207": "Nahraný soubor byl přejmenován na \"{name}\".", + "300": "Přesunování souboru(ů) selhalo.", + "301": "Kopírování souboru(ů) selhalo.", + "302": "Mazání souborů selhalo.", + "500": "Průzkumník souborů je z bezpečnostních důvodů zakázán. Sdělte to prosím správci systému a zkontrolujte soubor nastavení CKFinder.", + "501": "Podpora náhledů je zakázána." + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/cy.json b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/cy.json new file mode 100644 index 0000000..f084dfa --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/cy.json @@ -0,0 +1,33 @@ +{ + "errorUnknown": "Does dim modd cwblhau'r cais. (Gwall {number})", + "errors": { + "10": "Gorchymyn annilys.", + "11": "Doedd math yr adnodd heb ei benodi yn y cais.", + "12": "Dyw math yr adnodd ddim yn ddilys.", + "13": "The connector configuration file is invalid.", + "14": "Invalid connector plugin: {pluginName}.", + "102": "Enw ffeil neu ffolder annilys.", + "103": "Doedd dim modd cwblhau'r cais oherwydd cyfyngiadau awdurdodi.", + "104": "Doedd dim modd cwblhau'r cais oherwydd cyfyngiadau i hawliau'r system ffeilio.", + "105": "Estyniad ffeil annilys.", + "109": "Cais annilys.", + "110": "Gwall anhysbys.", + "111": "It was not possible to complete the request due to resulting file size.", + "115": "Mae ffeil neu ffolder gyda'r un enw yn bodoli yn barod.", + "116": "Methu â darganfod y ffolder. Adfywiwch a cheisio eto.", + "117": "Methu â darganfod y ffeil. Adfywiwch y rhestr ffeiliau a cheisio eto.", + "118": "Mae'r llwybrau gwreiddiol a tharged yn unfath.", + "201": "Mae ffeil â'r enw hwnnw yn bodoli yn barod. Cafodd y ffeil a lanlwythwyd ei hailenwi i \"{name}\".", + "202": "Ffeil annilys.", + "203": "Ffeil annilys. Mae maint y ffeil yn rhy fawr.", + "204": "Mae'r ffeil a lanwythwyd wedi chwalu.", + "205": "Does dim ffolder dros dro ar gael er mwyn lanlwytho ffeiliau iddo ar y gweinydd hwn.", + "206": "Cafodd y lanlwythiad ei ddiddymu oherwydd rhesymau diogelwch. Mae'r ffeil yn cynnwys data yn debyg i HTML.", + "207": "Cafodd y ffeil a lanlwythwyd ei hailenwi i \"{name}\".", + "300": "Methodd symud y ffeil(iau).", + "301": "Methodd copïo'r ffeil(iau).", + "302": "Deleting file(s) failed.", + "500": "Cafodd y porwr ffeiliau ei anallogi oherwydd rhesymau diogelwch. Cysylltwch â'ch gweinyddwr system a gwirio'ch ffeil ffurfwedd CKFinder.", + "501": "Mae cynhaliaeth bawdluniau wedi'i hanalluogi." + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/da.json b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/da.json new file mode 100644 index 0000000..a68d201 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/da.json @@ -0,0 +1,33 @@ +{ + "errorUnknown": "Det var ikke muligt at fuldføre handlingen. (Fejl: {number})", + "errors": { + "10": "Ugyldig handling.", + "11": "Ressourcetypen blev ikke angivet i anmodningen.", + "12": "Ressourcetypen er ikke gyldig.", + "13": "Konfigurationsfilen er ikke gyldig.", + "14": "Ugyldig connector plugin: {pluginName}.", + "102": "Ugyldig fil eller mappenavn.", + "103": "Det var ikke muligt at fuldføre handlingen på grund af en begrænsning i rettigheder.", + "104": "Det var ikke muligt at fuldføre handlingen på grund af en begrænsning i filsystem rettigheder.", + "105": "Ugyldig filtype.", + "109": "Ugyldig anmodning.", + "110": "Ukendt fejl.", + "111": "Det var ikke muligt at fuldføre handlingent possible på grund af filstørrelsen.", + "115": "En fil eller mappe med det samme navn eksisterer allerede.", + "116": "Mappen blev ikke fundet. Opdatér listen eller prøv igen.", + "117": "Filen blev ikke fundet. Opdatér listen eller prøv igen.", + "118": "Originalplacering og destination er ens.", + "201": "En fil med det samme filnavn eksisterer allerede. Den uploadede fil er blevet omdøbt til \"{name}\".", + "202": "Ugyldig fil.", + "203": "Ugyldig fil. Filstørrelsen er for stor.", + "204": "Den uploadede fil er korrupt.", + "205": "Der er ikke en midlertidig mappe til upload til rådighed på serveren.", + "206": "Upload annulleret af sikkerhedsmæssige årsager. Filen indeholder HTML-lignende data.", + "207": "Den uploadede fil er blevet omdøbt til \"{name}\".", + "300": "Flytning af fil(er) fejlede.", + "301": "Kopiering af fil(er) fejlede.", + "302": "Sletning af file(s) fejlede.", + "500": "Filbrowseren er deaktiveret af sikkerhedsmæssige årsager. Kontakt systemadministratoren eller kontrollér CKFinders konfigurationsfil.", + "501": "Understøttelse af thumbnails er deaktiveret." + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/de.json b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/de.json new file mode 100644 index 0000000..4f36077 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/de.json @@ -0,0 +1,33 @@ +{ + "errorUnknown": "Ihre Anfrage konnte nicht bearbeitet werden. (Fehler {number})", + "errors": { + "10": "Unbekannter Befehl.", + "11": "Der Ressourcentyp wurde nicht spezifiziert.", + "12": "Der Ressourcentyp ist nicht gültig.", + "13": "Der Connector-Konfigurationsdatei ist ungültig.", + "14": "Invalid connector plugin: {pluginName}.", + "102": "Ungültiger Datei oder Verzeichnisname.", + "103": "Ihre Anfrage konnte wegen Authorisierungseinschränkungen nicht durchgeführt werden.", + "104": "Ihre Anfrage konnte wegen Dateisystemeinschränkungen nicht durchgeführt werden.", + "105": "Ungültige Dateierweiterung.", + "109": "Unbekannte Anfrage.", + "110": "Unbekannter Fehler.", + "111": "Es war nicht möglich die Anforderung aufgrund resultierende Dateigröße vervollständigen.", + "115": "Es existiert bereits eine Datei oder ein Ordner mit dem gleichen Namen.", + "116": "Verzeichnis nicht gefunden. Bitte aktualisieren Sie die Anzeige und versuchen es noch einmal.", + "117": "Datei nicht gefunden. Bitte aktualisieren Sie die Dateiliste und versuchen es noch einmal.", + "118": "Quell- und Zielpfad sind gleich.", + "201": "Es existiert bereits eine Datei unter gleichem Namen. Die hochgeladene Datei wurde unter \"{name}\" gespeichert.", + "202": "Ungültige Datei.", + "203": "ungültige Datei. Die Dateigröße ist zu groß.", + "204": "Die hochgeladene Datei ist korrupt.", + "205": "Es existiert kein temp. Ordner für das Hochladen auf den Server.", + "206": "Das Hochladen wurde aus Sicherheitsgründen abgebrochen. Die Datei enthält HTML-Daten.", + "207": "Die hochgeladene Datei wurde unter \"{name}\" gespeichert.", + "300": "Verschieben der Dateien fehlgeschlagen.", + "301": "Kopieren der Dateien fehlgeschlagen.", + "302": "Löschen der Dateien fehlgeschlagen.", + "500": "Der Dateibrowser wurde aus Sicherheitsgründen deaktiviert. Bitte benachrichtigen Sie Ihren Systemadministrator und prüfen Sie die Konfigurationsdatei.", + "501": "Die Miniaturansicht wurde deaktivert." + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/el.json b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/el.json new file mode 100644 index 0000000..2f4c2bf --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/el.json @@ -0,0 +1,33 @@ +{ + "errorUnknown": "Η ενέργεια δεν ήταν δυνατόν να εκτελεστεί. (Σφάλμα {number})", + "errors": { + "10": "Λανθασμένη Εντολή.", + "11": "Ο τύπος πόρου (resource type) δεν ήταν δυνατόν να προσδιοριστεί.", + "12": "Ο τύπος πόρου (resource type) δεν είναι έγκυρος.", + "13": "Το αρχείο ρυθμίσεων της λειτουργίας σύνδεσης είναι άκυρο.", + "14": "Άκυρο πρόσθετο (plugin) σύνδεσης: {pluginName}.", + "102": "Το όνομα αρχείου ή φακέλου δεν είναι έγκυρο.", + "103": "Δεν ήταν δυνατή η εκτέλεση της ενέργειας λόγω έλλειψης δικαιωμάτων ασφαλείας.", + "104": "Δεν ήταν δυνατή η εκτέλεση της ενέργειας λόγω περιορισμών του συστήματος αρχείων.", + "105": "Λανθασμένη επέκταση αρχείου.", + "109": "Λανθασμένη ενέργεια.", + "110": "Άγνωστο λάθος.", + "111": "Δεν ήταν δυνατή η ολοκλήρωση της ενέργειας λόγω του μεγέθους αρχείου που προκύπτει.", + "115": "Το αρχείο ή φάκελος υπάρχει ήδη.", + "116": "Ο φάκελος δεν βρέθηκε. Παρακαλούμε ανανεώστε τη σελίδα και προσπαθήστε ξανά.", + "117": "Το αρχείο δεν βρέθηκε. Παρακαλούμε ανανεώστε τη σελίδα και προσπαθήστε ξανά.", + "118": "Η αρχική και τελική διαδρομή είναι ίδιες.", + "201": "Ένα αρχείο με την ίδια ονομασία υπάρχει ήδη. Το μεταφορτωμένο αρχείο μετονομάστηκε σε \"{name}\".", + "202": "Λανθασμένο αρχείο.", + "203": "Λανθασμένο αρχείο. Το μέγεθος του αρχείου είναι πολύ μεγάλο.", + "204": "Το μεταφορτωμένο αρχείο είναι χαλασμένο.", + "205": "Δεν υπάρχει προσωρινός φάκελος για να χρησιμοποιηθεί για τις μεταφορτώσεις των αρχείων.", + "206": "Η μεταφόρτωση ακυρώθηκε για λόγους ασφαλείας. Το αρχείο περιέχει δεδομένα μορφής HTML.", + "207": "Το μεταφορτωμένο αρχείο μετονομάστηκε σε \"{name}\".", + "300": "Η μετακίνηση των αρχείων απέτυχε.", + "301": "Η αντιγραφή των αρχείων απέτυχε.", + "302": "Η διαγραφή αρχείων απέτυχε.", + "500": "Ο πλοηγός αρχείων έχει απενεργοποιηθεί για λόγους ασφαλείας. Παρακαλούμε επικοινωνήστε με τον διαχειριστή της ιστοσελίδας και ελέγξτε το αρχείο ρυθμίσεων του πλοηγού (CKFinder).", + "501": "Η υποστήριξη των μικρογραφιών έχει απενεργοποιηθεί." + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/en.json b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/en.json new file mode 100644 index 0000000..6a59dcf --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/en.json @@ -0,0 +1,33 @@ +{ + "errorUnknown": "It was not possible to complete the request. (Error {number})", + "errors": { + "10": "Invalid command.", + "11": "The resource type was not specified in the request.", + "12": "The requested resource type is invalid.", + "13": "The connector configuration file is invalid.", + "14": "Invalid connector plugin: {pluginName}.", + "102": "Invalid file or folder name.", + "103": "It was not possible to complete the request due to authorization restrictions.", + "104": "It was not possible to complete the request due to file system permission restrictions.", + "105": "Invalid file extension.", + "109": "Invalid request.", + "110": "Unknown error.", + "111": "It was not possible to complete the request due to resulting file size.", + "115": "A file or folder with the same name already exists.", + "116": "Folder not found. Please refresh and try again.", + "117": "File not found. Please refresh the files list and try again.", + "118": "Source and target paths are equal.", + "201": "A file with the same name already exists. The uploaded file was renamed to \"{name}\".", + "202": "Invalid file.", + "203": "Invalid file. The file size is too big.", + "204": "The uploaded file is corrupt.", + "205": "No temporary folder is available for upload on the server.", + "206": "Upload canceled due to security reasons. The file contains HTML-like data.", + "207": "The uploaded file was renamed to \"{name}\".", + "300": "Moving file(s) failed.", + "301": "Copying file(s) failed.", + "302": "Deleting file(s) failed.", + "500": "The file browser is disabled for security reasons. Please contact your system administrator and check the CKFinder configuration file.", + "501": "Thumbnail support is disabled." + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/eo.json b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/eo.json new file mode 100644 index 0000000..d5bbfb2 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/eo.json @@ -0,0 +1,33 @@ +{ + "errorUnknown": "Ne eblis plenumi la peton. (Eraro {number})", + "errors": { + "10": "Nevalida komando.", + "11": "La risurctipo ne estas indikita en la komando.", + "12": "La risurctipo ne estas valida.", + "13": "La konektila agordodosiero estas ne valida.", + "14": "Nevalida konektilo: {pluginName}.", + "102": "La dosier- aŭ dosierujnomo ne estas valida.", + "103": "Ne eblis plenumi la peton pro rajtaj limigoj.", + "104": "Ne eblis plenumi la peton pro atingopermesaj limigoj.", + "105": "Nevalida dosiernoma finaĵo.", + "109": "Nevalida peto.", + "110": "Nekonata eraro.", + "111": "Ne eblis plenumi la peton pro dosiergrando.", + "115": "Dosiero aŭ dosierujo kun tiu nomo jam ekzistas.", + "116": "Tiu dosierujo ne ekzistas. Bonvolu aktualigi kaj reprovi.", + "117": "Tiu dosiero ne ekzistas. Bonvolu aktualigi kaj reprovi.", + "118": "La vojoj al la fonto kaj al la celo estas samaj.", + "201": "Dosiero kun la sama nomo jam ekzistas. La alŝutita dosiero estas renomita al \"{name}\".", + "202": "Nevalida dosiero.", + "203": "Nevalida dosiero. La grando estas tro alta.", + "204": "La alŝutita dosiero estas difektita.", + "205": "Neniu provizora dosierujo estas disponebla por alŝuto al la servilo.", + "206": "Alŝuto nuligita pro kialoj pri sekureco. La dosiero entenas datenojn de HTMLtipo.", + "207": "La alŝutita dosiero estas renomita al \"{name}\".", + "300": "La movo de la dosieroj malsukcesis.", + "301": "La kopio de la dosieroj malsukcesis.", + "302": "La forigo de la dosiero malsukcesis.", + "500": "La dosieradministra sistemo estas malvalidigita. Kontaktu vian administranton kaj kontrolu la agordodosieron de CKFinder.", + "501": "La eblo de miniaturoj estas malvalidigita." + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/es-mx.json b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/es-mx.json new file mode 100644 index 0000000..7366ba6 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/es-mx.json @@ -0,0 +1,33 @@ +{ + "errorUnknown": "No ha sido posible completar la solicitud. (Error {number})", + "errors": { + "10": "Comando incorrecto.", + "11": "El tipo de recurso no ha sido especificado en la solicitud.", + "12": "El tipo de recurso solicitado no es válido.", + "13": "The connector configuration file is invalid.", + "14": "Invalid connector plugin: {pluginName}.", + "102": "Nombre de archivo o carpeta no válido.", + "103": "No se ha podido completar la solicitud debido a las restricciones de autorización.", + "104": "No ha sido posible completar la solicitud debido a restricciones en el sistema de archivos.", + "105": "La extensión del archivo no es válida.", + "109": "Petición inválida.", + "110": "Error desconocido.", + "111": "It was not possible to complete the request due to resulting file size.", + "115": "Ya existe un archivo o carpeta con ese nombre.", + "116": "No se ha encontrado la carpeta. Por favor, actualice y pruebe de nuevo.", + "117": "No se ha encontrado el archivo. Por favor, actualice la lista de archivos y pruebe de nuevo.", + "118": "Las rutas origen y destino son iguales.", + "201": "Ya existía un archivo con ese nombre. El archivo subido ha sido renombrado como \"{name}\".", + "202": "Archivo inválido.", + "203": "Archivo inválido. El tamaño es demasiado grande.", + "204": "El archivo subido está corrupto.", + "205": "La carpeta temporal no está disponible en el servidor para las subidas.", + "206": "La subida se ha cancelado por razones de seguridad. El archivo contenía código HTML.", + "207": "El archivo subido ha sido renombrado como \"{name}\".", + "300": "Ha fallado el mover el(los) archivo(s).", + "301": "Ha fallado el copiar el(los) archivo(s).", + "302": "Deleting file(s) failed.", + "500": "El navegador de archivos está deshabilitado por razones de seguridad. Por favor, contacte con el administrador de su sistema y compruebe el archivo de configuración de CKFinder.", + "501": "El soporte para iconos está deshabilitado." + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/es.json b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/es.json new file mode 100644 index 0000000..2285b71 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/es.json @@ -0,0 +1,33 @@ +{ + "errorUnknown": "No ha sido posible completar la solicitud. (Error {number})", + "errors": { + "10": "Comando incorrecto.", + "11": "El tipo de recurso no ha sido especificado en la solicitud.", + "12": "El tipo de recurso solicitado no es válido.", + "13": "El archivo de configuración del conector no es válido.", + "14": "Plugin del conector inválido: {pluginName}.", + "102": "Nombre de fichero o carpeta no válido.", + "103": "No se ha podido completar la solicitud debido a las restricciones de autorización.", + "104": "No ha sido posible completar la solicitud debido a restricciones en el sistema de ficheros.", + "105": "La extensión del archivo no es válida.", + "109": "Petición inválida.", + "110": "Error desconocido.", + "111": "No fué posible completar la petición debido al tamaño del fichero.", + "115": "Ya existe un fichero o carpeta con ese nombre.", + "116": "No se ha encontrado la carpeta. Por favor, actualice y pruebe de nuevo.", + "117": "No se ha encontrado el fichero. Por favor, actualice la lista de ficheros y pruebe de nuevo.", + "118": "Las rutas origen y destino son iguales.", + "201": "Ya existía un fichero con ese nombre. El fichero subido ha sido renombrado como \"{name}\".", + "202": "Fichero inválido.", + "203": "Fichero inválido. El tamaño es demasiado grande.", + "204": "El fichero subido está corrupto.", + "205": "La carpeta temporal no está disponible en el servidor para las subidas.", + "206": "La subida se ha cancelado por razones de seguridad. El fichero contenía código HTML.", + "207": "El fichero subido ha sido renombrado como \"{name}\".", + "300": "Ha fallado el mover el(los) fichero(s).", + "301": "Ha fallado el copiar el(los) fichero(s).", + "302": "Ha fallado la eliminación de el\/los fichero(s).", + "500": "El navegador de archivos está deshabilitado por razones de seguridad. Por favor, contacte con el administrador de su sistema y compruebe el fichero de configuración de CKFinder.", + "501": "El soporte para iconos está deshabilitado." + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/et.json b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/et.json new file mode 100644 index 0000000..7b098f3 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/et.json @@ -0,0 +1,33 @@ +{ + "errorUnknown": "Päringu täitmine polnud võimalik. (Viga {number})", + "errors": { + "10": "Vigane käsk.", + "11": "Allika liik polnud päringus määratud.", + "12": "Päritud liik pole sobiv.", + "13": "Konnektori seadistusfail on vigane.", + "14": "Vigane konnektorplugin: {pluginName}.", + "102": "Sobimatu faili või kausta nimi.", + "103": "Piiratud õiguste tõttu polnud võimalik päringut lõpetada.", + "104": "Failisüsteemi piiratud õiguste tõttu polnud võimalik päringut lõpetada.", + "105": "Sobimatu faililaiend.", + "109": "Vigane päring.", + "110": "Tundmatu viga.", + "111": "Päringut polnud võimalik täita tekkiva faili suuruse tõttu.", + "115": "Sellenimeline fail või kaust on juba olemas.", + "116": "Kausta ei leitud. Palun värskenda lehte ja proovi uuesti.", + "117": "Faili ei leitud. Palun värskenda lehte ja proovi uuesti.", + "118": "Lähte- ja sihtasukoht on sama.", + "201": "Samanimeline fail on juba olemas. Üles laaditud faili nimeks pandi \"{name}\".", + "202": "Vigane fail.", + "203": "Vigane fail. Fail on liiga suur.", + "204": "Üleslaaditud fail on rikutud.", + "205": "Serverisse üleslaadimiseks pole ühtegi ajutiste failide kataloogi.", + "206": "Üleslaadimine katkestati turvakaalutlustel. Fail sisaldab HTMLi sarnaseid andmeid.", + "207": "Üleslaaditud faili nimeks pandi \"{name}\".", + "300": "Faili(de) liigutamine nurjus.", + "301": "Faili(de) kopeerimine nurjus.", + "302": "Faili(de) kustutamine nurjus.", + "500": "Failide sirvija on turvakaalutlustel keelatud. Palun võta ühendust oma süsteemi administraatoriga ja kontrolli CKFinderi seadistusfaili.", + "501": "Pisipiltide tugi on keelatud." + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/eu.json b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/eu.json new file mode 100644 index 0000000..ac863a9 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/eu.json @@ -0,0 +1,33 @@ +{ + "errorUnknown": "Ezin izan da eskaera burutu. (Errorea {number})", + "errors": { + "10": "Komando baliogabea.", + "11": "Ez da baliabide mota zehaztu eskaeran.", + "12": "Eskatutako baliabide mota baliogabea da.", + "13": "Konektorearen konfigurazio-fitxategia baliogabea da.", + "14": "Konektorearen plugin baliogabea: {pluginName}.", + "102": "Fitxategi edo karpetaren izen baliogabea.", + "103": "Ezin izan da eskaera burutu autorizazio murrizketen ondorioz.", + "104": "Ezin izan da eskaera burutu fitxategi-sistemako baimen murrizketen ondorioz.", + "105": "Fitxategi-luzapen baliogabea.", + "109": "Eskaera baliogabea.", + "110": "Errore ezezaguna.", + "111": "Ezin izan da eskaera burutu lortzen den fitxategiaren tamainaren ondorioz.", + "115": "Izen bereko fitxategi edo karpeta bat existitzen da dagoeneko.", + "116": "Ez da karpeta aurkitu. Mesedez freskatu eta saiatu berriz.", + "117": "Ez da fitxategia aurkitu. Mesedez freskatu fitxategi-zerrenda eta saiatu berriz.", + "118": "Iturburu eta helburuko bideak berdinak dira.", + "201": "Izen bereko fitxategi bat existitzen da dagoeneko. Kargatutako fitxategia honela berrizendatu da: \"{name}\".", + "202": "Fitxategi baliogabea.", + "203": "Fitxategi baliogabea. Fitxategi-tamaina handiegia da.", + "204": "Kargatutako fitxategia hondatuta dago.", + "205": "Zerbitzarian ez dago fitxategiak kargatzeko aldi baterako karpetarik erabilgarri.", + "206": "Segurtasun-arrazoiak direla eta, karga bertan behera geratu da. Fitxategiak HTML bezalako datuak dauzka.", + "207": "Kargatutako fitxategia honela berrizendatu da: \"{name}\".", + "300": "Fitxategia(k) lekuz aldatzeak huts egin du.", + "301": "Fitxategia(k) kopiatzeak huts egin du.", + "302": "Fitxategia(k) ezabatzeak huts egin du.", + "500": "Segurtasun-arrazoiak direla eta, fitxategi-arakatzailea desgaituta dago. Jarri sistemaren administratzailearekin harremanetan eta egiaztatu CKFinder konfigurazio-fitxategia.", + "501": "Koadro txikien euskarria desgaituta dago." + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/fa.json b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/fa.json new file mode 100644 index 0000000..a8139e6 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/fa.json @@ -0,0 +1,33 @@ +{ + "errorUnknown": "امکان تکمیل درخواست فوق وجود ندارد (خطا: {number})", + "errors": { + "10": "دستور نامعتبر.", + "11": "نوع منبع در درخواست تعریف نشده است.", + "12": "نوع منبع درخواست شده معتبر نیست.", + "13": "پیکربندی فایل اتصال نامعتبر است.", + "14": "افزونه‌ی اتصال نامعتبر: {pluginName}.", + "102": "نام فایل یا پوشه نامعتبر است.", + "103": "امکان کامل کردن این درخواست بخاطر محدودیت اختیارات وجود ندارد.", + "104": "امکان کامل کردن این درخواست بخاطر محدودیت دسترسی وجود ندارد.", + "105": "پسوند فایل نامعتبر است.", + "109": "درخواست نامعتبر است.", + "110": "خطای ناشناخته.", + "111": "انجام این عمل به دلیل اندازه‌ی فایل ممکن نیست.", + "115": "فایل یا پوشه ای با این نام وجود دارد", + "116": "پوشه یافت نشد. لطفا بروزرسانی کرده و مجددا تلاش کنید.", + "117": "فایل یافت نشد. لطفا فهرست فایلها را بروزرسانی کرده و مجددا تلاش کنید.", + "118": "منبع و مقصد مسیر یکی است.", + "201": "یک فایل با همان نام از قبل موجود است. فایل آپلود شده به \"{name}\" تغییر نام یافت.", + "202": "فایل نامعتبر", + "203": "فایل نامعتبر. اندازه فایل بیش از حد بزرگ است.", + "204": "فایل آپلود شده خراب است.", + "205": "هیچ پوشه موقتی برای آپلود فایل در سرور موجود نیست.", + "206": "آپلود به دلایل امنیتی متوقف شد. فایل محتوی اطلاعات HTML است.", + "207": "فایل آپلود شده به \"{name}\" تغییر نام یافت.", + "300": "انتقال فایل‌(ها) شکست خورد.", + "301": "کپی فایل‌(ها) شکست خورد.", + "302": "حذف فایل‌(ها) شکست خورد.", + "500": "مرورگر فایل به دلایل امنیتی غیر فعال است. لطفا با مدیر سامانه تماس بگیرید تا تنظیمات این بخش را بررسی نماید.", + "501": "پشتیبانی از تصاویر کوچک غیرفعال شده است" + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/fi.json b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/fi.json new file mode 100644 index 0000000..2453a01 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/fi.json @@ -0,0 +1,33 @@ +{ + "errorUnknown": "Pyyntöä ei voitu suorittaa. (Virhe {number})", + "errors": { + "10": "Virheellinen komento.", + "11": "Pyynnön resurssityyppi on määrittelemättä.", + "12": "Pyynnön resurssityyppi on virheellinen.", + "13": "The connector configuration file is invalid.", + "14": "Invalid connector plugin: {pluginName}.", + "102": "Virheellinen tiedosto- tai kansionimi.", + "103": "Oikeutesi eivät riitä pyynnön suorittamiseen.", + "104": "Tiedosto-oikeudet eivät riitä pyynnön suorittamiseen.", + "105": "Virheellinen tiedostotarkenne.", + "109": "Virheellinen pyyntö.", + "110": "Tuntematon virhe.", + "111": "It was not possible to complete the request due to resulting file size.", + "115": "Samanniminen tiedosto tai kansio on jo olemassa.", + "116": "Kansiota ei löydy. Yritä uudelleen kansiopäivityksen jälkeen.", + "117": "Tiedostoa ei löydy. Yritä uudelleen kansiopäivityksen jälkeen.", + "118": "Lähde- ja kohdekansio on sama!", + "201": "Samanniminen tiedosto on jo olemassa. Palvelimelle ladattu tiedosto on nimetty: \"{name}\".", + "202": "Virheellinen tiedosto.", + "203": "Virheellinen tiedosto. Tiedostokoko on liian suuri.", + "204": "Palvelimelle ladattu tiedosto on vioittunut.", + "205": "Väliaikaishakemistoa ei ole määritetty palvelimelle lataamista varten.", + "206": "Palvelimelle lataaminen on peruttu turvallisuussyistä. Tiedosto sisältää HTML-tyylistä dataa.", + "207": "Palvelimelle ladattu tiedosto on nimetty: \"{name}\".", + "300": "Tiedostosiirto epäonnistui.", + "301": "Tiedostokopiointi epäonnistui.", + "302": "Deleting file(s) failed.", + "500": "Tiedostoselain on kytketty käytöstä turvallisuussyistä. Pyydä pääkäyttäjää tarkastamaan CKFinderin asetustiedosto.", + "501": "Esikatselukuvien tuki on kytketty toiminnasta." + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/fr.json b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/fr.json new file mode 100644 index 0000000..c570c6b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/fr.json @@ -0,0 +1,33 @@ +{ + "errorUnknown": "La demande n'a pas abouti. (Erreur {number})", + "errors": { + "10": "Commande invalide.", + "11": "Le type de ressource n'a pas été spécifié dans la commande.", + "12": "Le type de ressource n'est pas valide.", + "13": "Le fichier de configuration du connecteur n'est pas valide.", + "14": "Connecteur plugin invalide: {pluginName}.", + "102": "Nom de fichier ou de dossier invalide.", + "103": "La demande n'a pas abouti: problème d'autorisations.", + "104": "La demande n'a pas abouti: problème de restrictions de permissions.", + "105": "Extension de fichier invalide.", + "109": "Demande invalide.", + "110": "Erreur inconnue.", + "111": "Il n'a pas été possible d'exécuter la requête à cause de la taille du fichier résultant.", + "115": "Un fichier ou un dossier avec ce nom existe déjà.", + "116": "Ce dossier n'existe pas. Veuillez rafraîchir la page et réessayer.", + "117": "Ce fichier n'existe pas. Veuillez rafraîchir la page et réessayer.", + "118": "Les chemins vers la source et la cible sont les mêmes.", + "201": "Un fichier avec ce nom existe déjà. Le fichier téléversé a été renommé en \"{name}\".", + "202": "Fichier invalide.", + "203": "Fichier invalide. La taille est trop grande.", + "204": "Le fichier téléversé est corrompu.", + "205": "Aucun dossier temporaire n'est disponible sur le serveur.", + "206": "Envoi interrompu pour raisons de sécurité. Le fichier contient des données de type HTML.", + "207": "Le fichier téléchargé a été renommé \"{name}\".", + "300": "Le déplacement des fichiers a échoué.", + "301": "La copie des fichiers a échoué.", + "302": "L'effacement des fichiers à échoué.", + "500": "L'interface de gestion des fichiers est désactivé. Contactez votre administrateur et vérifier le fichier de configuration de CKFinder.", + "501": "La fonction \"miniatures\" est désactivée." + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/gu.json b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/gu.json new file mode 100644 index 0000000..b7e5c5b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/gu.json @@ -0,0 +1,33 @@ +{ + "errorUnknown": "તમારી રીક્વેસ્ટ માન્ય નથી. (એરર {number})", + "errors": { + "10": "કમાંડ માન્ય નથી.", + "11": "તમારી રીક્વેસ્ટ માન્ય નથી.", + "12": "તમારી રીક્વેસ્ટ રિસોર્સ માન્ય નથી.", + "13": "The connector configuration file is invalid.", + "14": "Invalid connector plugin: {pluginName}.", + "102": "ફાઈલ અથવા ફોલ્ડરનું નામ માન્ય નથી.", + "103": "ઓથોરીટી ન હોવાને કારણે, તમારી રીક્વેસ્ટ માન્ય નથી..", + "104": "સિસ્ટમ પરમીસન ન હોવાને કારણે, તમારી રીક્વેસ્ટ માન્ય નથી.", + "105": "ફાઈલ એક્ષટેનસન માન્ય નથી.", + "109": "ઇનવેલીડ રીક્વેસ્ટ.", + "110": "અન્નોન એરર.", + "111": "It was not possible to complete the request due to resulting file size.", + "115": "એજ નામ વાળું ફાઈલ અથવા ફોલ્ડર છે.", + "116": "ફોલ્ડર નથી. રીફ્રેશ દબાવી ફરી પ્રયત્ન કરો.", + "117": "ફાઈલ નથી. રીફ્રેશ દબાવી ફરી પ્રયત્ન કરો..", + "118": "સોર્સ અને ટાર્ગેટ ના પાથ સરખા નથી.", + "201": "એજ નામ વાળી ફાઈલ છે. અપલોડ કરેલી નવી ફાઈલનું નામ \"{name}\".", + "202": "ફાઈલ માન્ય નથી.", + "203": "ફાઈલ માન્ય નથી. ફાઈલની સાઈઝ ઘણી મોટી છે.", + "204": "અપલોડ કરેલી ફાઈલ કરપ્ટ છે.", + "205": "સર્વર પર અપલોડ કરવા માટે ટેમ્પરરી ફોલ્ડર નથી.", + "206": "સિક્યોરીટીના કારણે અપલોડ કેન્સલ કરેલ છે. ફાઈલમાં HTML જેવો ડેટા છે.", + "207": "અપલોડ ફાઈલનું નવું નામ \"{name}\".", + "300": "ફાઈલ મુવ શક્ય નથી.", + "301": "ફાઈલ કોપી શક્ય નથી.", + "302": "Deleting file(s) failed.", + "500": "સિક્યોરીટીના કારણે ફાઈલ બ્રાઉઝર બંધ કરેલ છે. તમારા સિક્યોરીટી એડ્મીનીસ્ટેટરની મદદથી CKFinder કોન્ફીગ્યુંરેષન ફાઈલ તપાસો.", + "501": "થમ્બનેલનો સપોર્ટ બંધ કરેલો છે." + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/he.json b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/he.json new file mode 100644 index 0000000..4535dc7 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/he.json @@ -0,0 +1,33 @@ +{ + "errorUnknown": "לא היה ניתן להשלים את הבקשה. (שגיאה {number})", + "errors": { + "10": "הוראה לא תקינה.", + "11": "סוג המשאב לא צויין בבקשה לשרת.", + "12": "סוג המשאב המצויין לא תקין.", + "13": "The connector configuration file is invalid.", + "14": "Invalid connector plugin: {pluginName}.", + "102": "שם הקובץ או התיקיה לא תקין.", + "103": "לא היה ניתן להשלים את הבקשה בשל הרשאות מוגבלות.", + "104": "לא היה ניתן להשלים את הבקשה בשל הרשאות מערכת קבצים מוגבלות.", + "105": "סיומת הקובץ לא תקינה.", + "109": "בקשה לא תקינה.", + "110": "שגיאה לא ידועה.", + "111": "לא ניתן היה להשלים את הבקשה בשל הגודל החריג של הקובץ הנוצר.", + "115": "כבר קיים\/ת קובץ או תיקיה באותו השם.", + "116": "התיקיה לא נמצאה. נא לרענן ולנסות שוב.", + "117": "הקובץ לא נמצא. נא לרענן ולנסות שוב.", + "118": "כתובות המקור והיעד זהות.", + "201": "קובץ עם אותו השם כבר קיים. שם הקובץ שהועלה שונה ל \"{name}\"", + "202": "הקובץ לא תקין.", + "203": "הקובץ לא תקין. גודל הקובץ גדול מדי.", + "204": "הקובץ המועלה לא תקין", + "205": "לא קיימת בשרת תיקיה זמנית להעלאת קבצים.", + "206": "ההעלאה בוטלה מסיבות אבטחה. הקובץ מכיל תוכן שדומה ל-HTML.", + "207": "שם הקובץ שהועלה שונה ל \"{name}\"", + "300": "העברת הקבצים נכשלה.", + "301": "העתקת הקבצים נכשלה.", + "302": "Deleting file(s) failed.", + "500": "דפדפן הקבצים מנוטרל מסיבות אבטחה. יש לפנות למנהל המערכת ולבדוק את קובץ התצורה של CKFinder.", + "501": "התמיכה בתמונות מוקטנות מבוטלת." + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/hi.json b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/hi.json new file mode 100644 index 0000000..4ff15d3 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/hi.json @@ -0,0 +1,33 @@ +{ + "errorUnknown": "आपकी रिक्वेस्ट क्मप्लित नही कर सकते. (एरर {number})", + "errors": { + "10": "इन्वेलीड कमांड.", + "11": "यह रिसोर्स टाईप उपलब्ध नहीं है.", + "12": "यह रिसोर्स टाईप वेलिड नही हैं.", + "13": "The connector configuration file is invalid.", + "14": "Invalid connector plugin: {pluginName}.", + "102": "फाएल या फोल्डर का नाम वेलिड नहीं है.", + "103": "ओथोरिसेसंन रिस्त्रिक्सं की वजह से, आपकी रिक्वेस्ट पूरी नही कर सकते.", + "104": "सिस्टम परमिशन रिस्त्रिक्सं की वजह से, आपकी रिक्वेस्ट पूरी नही कर सकते..", + "105": "फाएल एक्स्त्न्सं गलत है.", + "109": "इन्वेलीड रिक्वेस्ट.", + "110": "अननोन एरर.", + "111": "It was not possible to complete the request due to resulting file size.", + "115": "सेम नाम का फाएल या फोल्डर मोजूद है.", + "116": "फोल्डर नही मिला. रिफ्रेस करके वापिस प्रयत्न करे.", + "117": "फाएल नही मिला. फाएल लिस्टको रिफ्रेस करके वापिस प्रयत्न करे.", + "118": "सोर्स और टारगेट के पाथ एक जैसे है.", + "201": "वहि नाम की फाएल मोजोद है. अपलोड फाएल का नया नाम \"{name}\".", + "202": "इन्वेलीड फाएल.", + "203": "इन्वेलीड फाएल. फाएल बहुत बड़ी है.", + "204": "अपलोडकी गयी फाएल करप्ट हो गयी है.", + "205": "फाएल अपलोड करनेके लिये, सर्वरपे टेम्पररी फोल्डर उपलब्थ नही है..", + "206": "सिक्योरिटी कारण वष, फाएल अपलोड केन्सल किया है. फाएलमें HTML-जैसे डेटा है.", + "207": "अपलोडेड फाएल का नया नाम \"{name}\".", + "300": "फाएल मूव नहीं कर सके.", + "301": "फाएल कोपी नहीं कर सके.", + "302": "Deleting file(s) failed.", + "500": "सिक्योरिटी कारण वष, फाएल ब्राउजर डिसेबल किया गया है. आपके सिस्टम एडमिनिस्ट्रेटर का सम्पर्क करे और CKFinder कोंफिग्युरेसन फाएल तपासे.", + "501": "थम्बनेल सपोर्ट डिसेबल किया है." + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/hr.json b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/hr.json new file mode 100644 index 0000000..e638cd2 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/hr.json @@ -0,0 +1,33 @@ +{ + "errorUnknown": "Nije moguće završiti zahtjev. (Greška {number})", + "errors": { + "10": "Nepoznata naredba.", + "11": "Nije navedena vrsta u zahtjevu.", + "12": "Zatražena vrsta nije važeća.", + "13": "Connector konfiguracijski fajl nije valjan.", + "14": "Connector plugin nije ispravan: {pluginName}.", + "102": "Neispravan naziv datoteke ili direktorija.", + "103": "Nije moguće izvršiti zahtjev zbog ograničenja pristupa.", + "104": "Nije moguće izvršiti zahtjev zbog ograničenja postavki sustava.", + "105": "Nedozvoljena vrsta datoteke.", + "109": "Nedozvoljen zahtjev.", + "110": "Nepoznata greška.", + "111": "Nije moguće izvršiti zahtjev zbog resulting veličine datoteke.", + "115": "Datoteka ili direktorij s istim nazivom već postoji.", + "116": "Direktorij nije pronađen. Osvježite stranicu i pokušajte ponovo.", + "117": "Datoteka nije pronađena. Osvježite listu datoteka i pokušajte ponovo.", + "118": "Putanje izvora i odredišta su jednake.", + "201": "Datoteka s istim nazivom već postoji. Poslana datoteka je promijenjena u \"{name}\".", + "202": "Neispravna datoteka.", + "203": "Neispravna datoteka. Veličina datoteke je prevelika.", + "204": "Poslana datoteka je neispravna.", + "205": "Ne postoji privremeni direktorij za slanje na server.", + "206": "Slanje je poništeno zbog sigurnosnih postavki. Naziv datoteke sadrži HTML podatke.", + "207": "Poslana datoteka je promjenjena u \"{name}\".", + "300": "Premještanje datoteke(a) nije uspjelo.", + "301": "Kopiranje datoteke(a) nije uspjelo.", + "302": "Brisanje datoteke(a) nije uspjelo.", + "500": "Pretraživanje datoteka nije dozvoljeno iz sigurnosnih razloga. Molimo kontaktirajte administratora sustava kako bi provjerili postavke CKFinder konfiguracijske datoteke.", + "501": "Podrška za sličice je onemogućena." + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/hu.json b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/hu.json new file mode 100644 index 0000000..26e5297 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/hu.json @@ -0,0 +1,33 @@ +{ + "errorUnknown": "A parancsot nem sikerült végrehajtani. (Hiba: {number})", + "errors": { + "10": "Érvénytelen parancs.", + "11": "A fájl típusa nem lett a kérés során beállítva.", + "12": "A kívánt fájl típus érvénytelen.", + "13": "A kapcsolati konfiguráció érvénytelen.", + "14": "Érvénytelen kapcsolati plugin: {pluginName}.", + "102": "Érvénytelen fájl vagy könyvtárnév.", + "103": "Hitelesítési problémák miatt nem sikerült a kérést teljesíteni.", + "104": "Jogosultsági problémák miatt nem sikerült a kérést teljesíteni.", + "105": "Érvénytelen fájl kiterjesztés.", + "109": "Érvénytelen kérés.", + "110": "Ismeretlen hiba.", + "111": "A kérés nem teljesíthető a létrejövő fájl mérete miatt.", + "115": "A fálj vagy mappa már létezik ezen a néven.", + "116": "Mappa nem található. Kérem frissítsen és próbálja újra.", + "117": "Fájl nem található. Kérem frissítsen és próbálja újra.", + "118": "A forrás és a cél azonos.", + "201": "Ilyen nevű fájl már létezett. A feltöltött fájl a következőre lett átnevezve: \"{name}\".", + "202": "Érvénytelen fájl.", + "203": "Érvénytelen fájl. A fájl mérete túl nagy.", + "204": "A feltöltött fájl hibás.", + "205": "A szerveren nem található a feltöltéshez ideiglenes mappa.", + "206": "A fájl feltötése biztonsági okból megszakadt. A fájl HTML adatokat tartalmaz.", + "207": "El fichero subido ha sido renombrado como \"{name}\".", + "300": "A fájl(ok) áthelyezése sikertelen.", + "301": "A fájl(ok) másolása sikertelen.", + "302": "A fájl(ok) törlése sikertelen.", + "500": "A fájl-tallózó biztonsági okok miatt nincs engedélyezve. Kérem vegye fel a kapcsolatot a rendszer üzemeltetőjével és ellenőrizze a CKFinder konfigurációs fájlt.", + "501": "A bélyegkép támogatás nincs engedélyezve." + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/id.json b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/id.json new file mode 100644 index 0000000..6a59dcf --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/id.json @@ -0,0 +1,33 @@ +{ + "errorUnknown": "It was not possible to complete the request. (Error {number})", + "errors": { + "10": "Invalid command.", + "11": "The resource type was not specified in the request.", + "12": "The requested resource type is invalid.", + "13": "The connector configuration file is invalid.", + "14": "Invalid connector plugin: {pluginName}.", + "102": "Invalid file or folder name.", + "103": "It was not possible to complete the request due to authorization restrictions.", + "104": "It was not possible to complete the request due to file system permission restrictions.", + "105": "Invalid file extension.", + "109": "Invalid request.", + "110": "Unknown error.", + "111": "It was not possible to complete the request due to resulting file size.", + "115": "A file or folder with the same name already exists.", + "116": "Folder not found. Please refresh and try again.", + "117": "File not found. Please refresh the files list and try again.", + "118": "Source and target paths are equal.", + "201": "A file with the same name already exists. The uploaded file was renamed to \"{name}\".", + "202": "Invalid file.", + "203": "Invalid file. The file size is too big.", + "204": "The uploaded file is corrupt.", + "205": "No temporary folder is available for upload on the server.", + "206": "Upload canceled due to security reasons. The file contains HTML-like data.", + "207": "The uploaded file was renamed to \"{name}\".", + "300": "Moving file(s) failed.", + "301": "Copying file(s) failed.", + "302": "Deleting file(s) failed.", + "500": "The file browser is disabled for security reasons. Please contact your system administrator and check the CKFinder configuration file.", + "501": "Thumbnail support is disabled." + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/it.json b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/it.json new file mode 100644 index 0000000..8071abd --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/it.json @@ -0,0 +1,33 @@ +{ + "errorUnknown": "Non è stato possibile completare la richiesta (errore {number}).", + "errors": { + "10": "Comando non valido.", + "11": "Il tipo di risorsa non è stato specificato nella richiesta.", + "12": "Il tipo di risorsa richiesto non è valido.", + "13": "La configurazione del connettore non è valida.", + "14": "Estensione del connettore non valida: {pluginName}.", + "102": "Il nome del file o della cartella non è valido.", + "103": "Non è stato possibile completare la richiesta a causa di restrizioni di autorizzazione.", + "104": "Non è stato possibile completare la richiesta a causa di restrizioni nei permessi del file system.", + "105": "L'estensione del file non è valida.", + "109": "Richiesta non valida.", + "110": "Errore sconosciuto.", + "111": "Non è stato possibile completare la richiesta a causa della dimensione finale del file.", + "115": "Esiste già un file o una cartella con lo stesso nome.", + "116": "Cartella non trovata. Aggiornare e riprovare.", + "117": "File non trovato. Aggiornare la lista dei file e riprovare.", + "118": "Il percorso di origine e quello di destinazione sono uguali.", + "201": "Un file con lo stesso nome esiste già. Il file caricato è stato rinominato in \"{name}\".", + "202": "File non valido.", + "203": "File non valido. Il file è troppo grande.", + "204": "Il file caricato è corrotto.", + "205": "Non è disponibile alcuna cartella temporanea per il caricamento dei file sul server.", + "206": "Caricamento annullato per motivi di sicurezza. Il file contiene dati in formato HTML.", + "207": "Il file caricato è stato rinominato in \"{name}\".", + "300": "Non è stato possibile spostare i file.", + "301": "Non è stato possibile copiare i file.", + "302": "Non è stato possibile eliminare i file.", + "500": "Il gestore dei file è disabilitato per motivi di sicurezza. Contattare l'amministratore del sistema e verificare la configurazione di CKFinder.", + "501": "Il supporto alle miniature non è attivo." + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/ja.json b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/ja.json new file mode 100644 index 0000000..cd2ef1f --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/ja.json @@ -0,0 +1,33 @@ +{ + "errorUnknown": "リクエストの処理に失敗しました。 (Error {number})", + "errors": { + "10": "不正なコマンドです。", + "11": "リソースタイプが特定できませんでした。", + "12": "要求されたリソースのタイプが正しくありません。", + "13": "The connector configuration file is invalid.", + "14": "Invalid connector plugin: {pluginName}.", + "102": "ファイル名\/フォルダ名が正しくありません。", + "103": "リクエストを完了できませんでした。認証エラーです。", + "104": "リクエストを完了できませんでした。ファイルのパーミッションが許可されていません。", + "105": "拡張子が正しくありません。", + "109": "不正なリクエストです。", + "110": "不明なエラーが発生しました。", + "111": "It was not possible to complete the request due to resulting file size.", + "115": "同じ名前のファイル\/フォルダがすでに存在しています。", + "116": "フォルダが見つかりませんでした。ページを更新して再度お試し下さい。", + "117": "ファイルが見つかりませんでした。ページを更新して再度お試し下さい。", + "118": "対象が移動元と同じ場所を指定されています。", + "201": "同じ名前のファイルがすでに存在しています。\"{name}\" にリネームして保存されました。", + "202": "不正なファイルです。", + "203": "ファイルのサイズが大きすぎます。", + "204": "アップロードされたファイルは壊れています。", + "205": "サーバ内の一時作業フォルダが利用できません。", + "206": "セキュリティ上の理由からアップロードが取り消されました。このファイルにはHTMLに似たデータが含まれています。", + "207": "ファイルは \"{name}\" にリネームして保存されました。", + "300": "ファイルの移動に失敗しました。", + "301": "ファイルのコピーに失敗しました。", + "302": "Deleting file(s) failed.", + "500": "ファイルブラウザはセキュリティ上の制限から無効になっています。システム担当者に連絡をして、CKFinderの設定をご確認下さい。", + "501": "サムネイル機能は無効になっています。" + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/ko.json b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/ko.json new file mode 100644 index 0000000..6e7d779 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/ko.json @@ -0,0 +1,33 @@ +{ + "errorUnknown": "요청을 완료할 수 없었습니다. (오류 {number})", + "errors": { + "10": "올바르지 않은 명령.", + "11": "요청에서 리소스 유형이 특정되지 않았습니다.", + "12": "요청한 리소스 유형이 올바르지 않습니다.", + "13": "연결 설정 파일이 올바르지 않습니다.", + "14": "올바르지 않은 연결 플러그인: {pluginName}.", + "102": "올바르지 않은 파일 또는 폴더 이름.", + "103": "인증 제한 때문에 작업을 완료할 수 없었습니다.", + "104": "파일 시스템 권한 제한 때문에 작업을 완료할 수 없었습니다.", + "105": "올바르지 않은 파일 확장자.", + "109": "올바르지 않은 요청.", + "110": "알 수 없는 오류.", + "111": "파일 크기 때문에 요청을 완료할 수 없습니다.", + "115": "이미 같은 이름의 파일이나 폴더가 존재합니다.", + "116": "폴더를 찾지 못하였습니다. 새로고침을 해 보시고 다시 시도해 주십시오.", + "117": "파일을 찾지 못하였습니다. 새로고침을 해 보시고 다시 시도해 주십시오.", + "118": "원본 폴더와 대상 폴더가 동일합니다.", + "201": "이미 같은 이름의 파일이 존재합니다. 해당 업로드 파일의 이름이 \"{name}\" 로 변경되었습니다.", + "202": "올바르지 않은 파일.", + "203": "올바르지 않은 파일. 파일 용량이 너무 큽니다.", + "204": "업로드한 파일이 손상되어 있습니다.", + "205": "서버에 업로드를 위한 임시 폴더가 사용가능하지 않습니다.", + "206": "보안상의 이유로 업로드가 중단되었습니다. 해당 파일은 HTML 같은 데이터가 포함되어 있습니다.", + "207": "업로드한 파일의 이름이 \"{name}\" 로 변경되었습니다.", + "300": "파일 이동 실패.", + "301": "파일 복사 실패.", + "302": "파일 삭제 실패.", + "500": "파일 브라우저가 보안상의 이유로 비활성화 되어있습니다. 당신의 시스템 관리자에게 연락을 해 보시고 CKFinder의 설정 파일을 확인해 주십시오.", + "501": "미리 보기 지원이 비활성화 되어 있습니다." + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/ku.json b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/ku.json new file mode 100644 index 0000000..54e590e --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/ku.json @@ -0,0 +1,33 @@ +{ + "errorUnknown": "ئەستەم بوو داواکاریەکەت بە تەواوی جێبەجێبکرێت. (هەڵە {number})", + "errors": { + "10": "فەرمانێکی نادروست.", + "11": "جۆری کەرستەکە دەستنیشان نەکراوە لە داواکاریەکە.", + "12": "جۆری کەرستەی داواکراو نادرووستە.", + "13": "شێوەپێدانی لکێنەری پەرگەکە نادروستە.", + "14": "پێوەکاری لکێنەر نادرووستە: {pluginName}.", + "102": "ناوێکی نادروستی پەڕگە یان بوخچە.", + "103": "ئەستەم بوو لە جێبەجێکردنی داواکاریەکەت دەربارەی ڕێگەپێدانی سنووری.", + "104": "ئەستەم بوو لە جێبەجێکردنی داواکاریەکەت دەربارەی ڕێگەپێدانی سنووری سیستەم.", + "105": "پێوەکاری پەڕگە نادروستە.", + "109": "داوایەکی نادروست.", + "110": "هەڵەی نەناسراو.", + "111": "ئەستەم بوو لە جێبەجێکردنی داواکاریەکەت دەربارەی ئەنجامی قەبارەی پەڕگەکە.", + "115": "ئەم ناوە پێشوتر هەیە لە پەرگە یان لە بوخچە.", + "116": "بوخچەکە نەدرۆزراوە. تکایە دووبارە هەوڵبدەوە.", + "117": "پەرگە نەدرۆزراوە. تکایە لیستی پەڕگەکان نوێبکەوەو ئینجا دووبارە هەوڵبدەوە.", + "118": "سەرچاوەو ئامانجی ڕێڕەوە یەکسانن.", + "201": "پەڕگەیەک بەهەمان ناو هەیە. پەڕگەی بارکراو ناوەکەی خۆکارانە گۆڕدرا بۆ \"{name}\".", + "202": "پەڕگەی نادروست.", + "203": "پەڕگەی نادروست. قەبارەی پەڕگەکە زۆر گەورەیە.", + "204": "پەڕگەی بارکراو تێکدرا.", + "205": "کاتی بارکردنی بوخچە بەردەست نیە لەسەر ئەم سێرڤەرە.", + "206": "بارکردنەکە هەڵوەشیندراوە بۆهۆی پارێزگاری. پەڕگەکە زانیاری HTML لەخۆدەگرێت.", + "207": "پەڕگەی بارکراو ناوەکەی گۆڕدرا بۆ \"{name}\".", + "300": "گواستنەوەی پەرگە سەرکەوتونەبوو.", + "301": "کۆپیکردنی پەڕگەکە سەرکەوتونەبوو.", + "302": "سڕینەوەی پەرگەکە سەرکەوتونەبوو.", + "500": "گەڕۆککردنی پەڕگەکان ناچالاککراوە. بەهۆیی پارێزی. تکایە پەیوەندی بکە بە بەڕێوەبەری سیستمەکە بۆ پشکنینی شێوەپێدانی پەرگەی CKFinder.", + "501": "پشتیوانکردنی وێنۆچکە ناچالاککراوە." + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/lt.json b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/lt.json new file mode 100644 index 0000000..1595fc1 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/lt.json @@ -0,0 +1,33 @@ +{ + "errorUnknown": "Užklausos įvykdyti nepavyko. (Klaida {number})", + "errors": { + "10": "Neteisinga komanda.", + "11": "Resurso rūšis nenurodyta užklausoje.", + "12": "Neteisinga resurso rūšis.", + "13": "The connector configuration file is invalid.", + "14": "Invalid connector plugin: {pluginName}.", + "102": "Netinkamas failas arba segtuvo pavadinimas.", + "103": "Nepavyko įvykdyti užklausos dėl autorizavimo apribojimų.", + "104": "Nepavyko įvykdyti užklausos dėl failų sistemos leidimų apribojimų.", + "105": "Netinkamas failo plėtinys.", + "109": "Netinkama užklausa.", + "110": "Nežinoma klaida.", + "111": "It was not possible to complete the request due to resulting file size.", + "115": "Failas arba segtuvas su tuo pačiu pavadinimu jau yra.", + "116": "Segtuvas nerastas. Pabandykite atnaujinti.", + "117": "Failas nerastas. Pabandykite atnaujinti failų sąrašą.", + "118": "Šaltinio ir nurodomos vietos nuorodos yra vienodos.", + "201": "Failas su tuo pačiu pavadinimu jau tra. Įkeltas failas buvo pervadintas į \"{name}\"", + "202": "Netinkamas failas", + "203": "Netinkamas failas. Failo apimtis yra per didelė.", + "204": "Įkeltas failas yra pažeistas.", + "205": "Nėra laikinojo segtuvo skirto failams įkelti.", + "206": "Įkėlimas bus nutrauktas dėl saugumo sumetimų. Šiame faile yra HTML duomenys.", + "207": "Įkeltas failas buvo pervadintas į \"{name}\"", + "300": "Failų perkėlimas nepavyko.", + "301": "Failų kopijavimas nepavyko.", + "302": "Deleting file(s) failed.", + "500": "Failų naršyklė yra išjungta dėl saugumo nustaymų. Prašau susisiekti su sistemų administratoriumi ir patikrinkite CKFinder konfigūracinį failą.", + "501": "Miniatiūrų palaikymas išjungtas." + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/lv.json b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/lv.json new file mode 100644 index 0000000..cbfac03 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/lv.json @@ -0,0 +1,33 @@ +{ + "errorUnknown": "Nebija iespējams pabeigt pieprasījumu. (Kļūda {number})", + "errors": { + "10": "Nederīga komanda.", + "11": "Resursa veids netika norādīts pieprasījumā.", + "12": "Pieprasītais resursa veids nav derīgs.", + "13": "Savienojuma konfigurācijas fails nav korekts.", + "14": "Nekorekts savienojuma spraudnis: {pluginName}.", + "102": "Nederīgs faila vai mapes nosaukums.", + "103": "Nav iespējams pabeigt pieprasījumu, autorizācijas aizliegumu dēļ.", + "104": "Nav iespējams pabeigt pieprasījumu, failu sistēmas atļauju ierobežojumu dēļ.", + "105": "Neatļauts faila paplašinājums.", + "109": "Nederīgs pieprasījums.", + "110": "Nezināma kļūda.", + "111": "Pieprasījums neizdevās, dēļ rezultāta faila izmēra.", + "115": "Fails vai mape ar šādu nosaukumu jau pastāv.", + "116": "Mape nav atrasta. Lūdzu pārlādējiet šo logu un mēģiniet vēlreiz.", + "117": "Fails nav atrasts. Lūdzu pārlādējiet failu sarakstu un mēģiniet vēlreiz.", + "118": "Abas mapes ir viena un tā pati.", + "201": "Fails ar šādu nosaukumu jau eksistē. Augšupielādētais fails tika pārsaukts par \"{name}\".", + "202": "Nederīgs fails.", + "203": "Nederīgs fails. Faila izmērs pārsniedz pieļaujamo.", + "204": "Augšupielādētais fails ir bojāts.", + "205": "Neviena pagaidu mape nav pieejama priekš augšupielādēšanas uz servera.", + "206": "Augšupielāde atcelta drošības apsvērumu dēļ. Fails satur HTML veida datus.", + "207": "Augšupielādētais fails tika pārsaukts par \"{name}\".", + "300": "Pārvietot failu(s) neizdevās.", + "301": "Pārkopēt failu(s) neizdevās.", + "302": "Dzēst failu(s) neizdevās.", + "500": "Failu pārlūks ir atslēgts drošības apsvērumu dēļ. Lūdzu sazinieties ar šīs sistēmas tehnisko administratoru vai pārbaudiet CKFinder konfigurācijas failu.", + "501": "Sīkbilžu atbalsts ir atslēgts." + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/nb.json b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/nb.json new file mode 100644 index 0000000..0536bea --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/nb.json @@ -0,0 +1,33 @@ +{ + "errorUnknown": "Det var ikke mulig å utføre forespørselen. (Feil {number})", + "errors": { + "10": "Ugyldig kommando.", + "11": "Ressurstypen ble ikke spesifisert i forespørselen.", + "12": "Ugyldig ressurstype.", + "13": "Konfigurasjonsfilen for forbindelsen er ugyldig.", + "14": "Ugyldig programvareutvidelse: {pluginName}.", + "102": "Ugyldig fil- eller mappenavn.", + "103": "Kunne ikke utføre forespørselen grunnet manglende tilgang.", + "104": "Kunne ikke utføre forespørselen grunnet manglende tilgang til filsystemet.", + "105": "Ugyldig filtype.", + "109": "Ugyldig forespørsel.", + "110": "Ukjent feil.", + "111": "Det var ikke mulig å fullføre handlingen på grunn av filstørrelsen.", + "115": "Det finnes allerede en fil eller mappe med dette navnet.", + "116": "Kunne ikke finne mappen. Last vinduet på nytt og prøv igjen.", + "117": "Kunne ikke finne filen. Last vinduet på nytt og prøv igjen.", + "118": "Kilde- og mål-bane er like.", + "201": "Det fantes allerede en fil med dette navnet. Den opplastede filens navn har blitt endret til \"{name}\".", + "202": "Ugyldig fil.", + "203": "Ugyldig fil. Filen er for stor.", + "204": "Den opplastede filen er korrupt.", + "205": "Det finnes ingen midlertidig mappe for filopplastinger.", + "206": "Opplastingen ble avbrutt av sikkerhetshensyn. Filen inneholder HTML-aktige data.", + "207": "Den opplastede filens navn har blitt endret til \"{name}\".", + "300": "Klarte ikke å flytte fil(er).", + "301": "Klarte ikke å kopiere fil(er).", + "302": "Sletting av fil(er) feilet.", + "500": "Filvelgeren ikke tilgjengelig av sikkerhetshensyn. Kontakt systemansvarlig og be ham sjekke CKFinders konfigurasjonsfil.", + "501": "Funksjon for miniatyrbilder er skrudd av." + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/nl.json b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/nl.json new file mode 100644 index 0000000..b5a4317 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/nl.json @@ -0,0 +1,33 @@ +{ + "errorUnknown": "Het was niet mogelijk om deze actie uit te voeren. (Fout {number})", + "errors": { + "10": "Ongeldig commando.", + "11": "Het bestandstype komt niet voor in de aanvraag.", + "12": "Het gevraagde brontype is niet geldig.", + "13": "The connector configuration file is invalid.", + "14": "Invalid connector plugin: {pluginName}.", + "102": "Ongeldige bestands- of mapnaam.", + "103": "Het verzoek kon niet worden voltooid vanwege autorisatie beperkingen.", + "104": "Het verzoek kon niet worden voltooid door beperkingen in de rechten op het bestandssysteem.", + "105": "Ongeldige bestandsextensie.", + "109": "Ongeldige aanvraag.", + "110": "Onbekende fout.", + "111": "It was not possible to complete the request due to resulting file size.", + "115": "Er bestaat al een bestand of map met deze naam.", + "116": "Map niet gevonden, vernieuw de mappenlijst of kies een andere map.", + "117": "Bestand niet gevonden, vernieuw de mappenlijst of kies een andere map.", + "118": "Bron- en doelmap zijn gelijk.", + "201": "Er bestaat al een bestand met dezelfde naam. Het geüploade bestand is hernoemd naar: \"{name}\".", + "202": "Ongeldige bestand.", + "203": "Ongeldige bestand. Het bestand is te groot.", + "204": "De geüploade file is kapot.", + "205": "Er is geen hoofdmap gevonden.", + "206": "Het uploaden van het bestand is om veiligheidsredenen afgebroken. Er is HTML code in het bestand aangetroffen.", + "207": "Het geüploade bestand is hernoemd naar: \"{name}\".", + "300": "Bestand(en) verplaatsen is mislukt.", + "301": "Bestand(en) kopiëren is mislukt.", + "302": "Deleting file(s) failed.", + "500": "Het uploaden van een bestand is momenteel niet mogelijk. Contacteer de beheerder en controleer het CKFinder configuratiebestand.", + "501": "De ondersteuning voor miniatuurafbeeldingen is uitgeschakeld." + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/nn.json b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/nn.json new file mode 100644 index 0000000..ada2ea5 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/nn.json @@ -0,0 +1,33 @@ +{ + "errorUnknown": "Det var ikke mulig å utføre forespørselen. (Feil {number})", + "errors": { + "10": "Ugyldig kommando.", + "11": "Ressurstypen ble ikke spesifisert i forepørselen.", + "12": "Ugyldig ressurstype.", + "13": "The connector configuration file is invalid.", + "14": "Invalid connector plugin: {pluginName}.", + "102": "Ugyldig fil- eller mappenavn.", + "103": "Kunne ikke utføre forespørselen pga manglende autorisasjon.", + "104": "Kunne ikke utføre forespørselen pga manglende tilgang til filsystemet.", + "105": "Ugyldig filtype.", + "109": "Ugyldig forespørsel.", + "110": "Ukjent feil.", + "111": "It was not possible to complete the request due to resulting file size.", + "115": "Det finnes allerede en fil eller mappe med dette navnet.", + "116": "Kunne ikke finne mappen. Oppdater vinduet og prøv igjen.", + "117": "Kunne ikke finne filen. Oppdater vinduet og prøv igjen.", + "118": "Kilde- og mål-bane er like.", + "201": "Det fantes allerede en fil med dette navnet. Den opplastede filens navn har blitt endret til \"{name}\".", + "202": "Ugyldig fil.", + "203": "Ugyldig fil. Filen er for stor.", + "204": "Den opplastede filen er korrupt.", + "205": "Det finnes ingen midlertidig mappe for filopplastinger.", + "206": "Opplastingen ble avbrutt av sikkerhetshensyn. Filen inneholder HTML-aktig data.", + "207": "Den opplastede filens navn har blitt endret til \"{name}\".", + "300": "Klarte ikke å flytte fil(er).", + "301": "Klarte ikke å kopiere fil(er).", + "302": "Deleting file(s) failed.", + "500": "Filvelgeren ikke tilgjengelig av sikkerhetshensyn. Kontakt systemansvarlig og be han sjekke CKFinder's konfigurasjonsfil.", + "501": "Funksjon for minityrbilder er skrudd av." + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/pl.json b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/pl.json new file mode 100644 index 0000000..49678e5 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/pl.json @@ -0,0 +1,33 @@ +{ + "errorUnknown": "Wykonanie operacji zakończyło się niepowodzeniem. (Błąd {number})", + "errors": { + "10": "Nieprawidłowe polecenie (command).", + "11": "Brak wymaganego parametru: typ danych (resource type).", + "12": "Nieprawidłowy typ danych (resource type).", + "13": "Plik konfiguracyjny connectora jest nieprawidłowy.", + "14": "Nieprawidłowy plugin: {pluginName}.", + "102": "Nieprawidłowa nazwa pliku lub folderu.", + "103": "Wykonanie operacji nie jest możliwe: brak uprawnień.", + "104": "Wykonanie operacji nie powiodło się z powodu niewystarczających uprawnień do systemu plików.", + "105": "Nieprawidłowe rozszerzenie.", + "109": "Nieprawidłowe żądanie.", + "110": "Niezidentyfikowany błąd.", + "111": "Wykonanie operacji nie powiodło się z powodu zbyt dużego rozmiaru pliku wynikowego.", + "115": "Plik lub folder o podanej nazwie już istnieje.", + "116": "Nie znaleziono folderu. Odśwież panel i spróbuj ponownie.", + "117": "Nie znaleziono pliku. Odśwież listę plików i spróbuj ponownie.", + "118": "Ścieżki źródłowa i docelowa są jednakowe.", + "201": "Plik o podanej nazwie już istnieje. Nazwa przesłanego pliku została zmieniona na \"{name}\".", + "202": "Nieprawidłowy plik.", + "203": "Nieprawidłowy plik. Plik przekracza dozwolony rozmiar.", + "204": "Przesłany plik jest uszkodzony.", + "205": "Brak folderu tymczasowego na serwerze do przesyłania plików.", + "206": "Przesyłanie pliku zakończyło się niepowodzeniem z powodów bezpieczeństwa. Plik zawiera dane przypominające HTML.", + "207": "Nazwa przesłanego pliku została zmieniona na \"{name}\".", + "300": "Przenoszenie nie powiodło się.", + "301": "Kopiowanie nie powiodło się.", + "302": "Usuwanie nie powiodło się.", + "500": "Menedżer plików jest wyłączony z powodów bezpieczeństwa. Skontaktuj się z administratorem oraz sprawdź plik konfiguracyjny CKFindera.", + "501": "Tworzenie miniatur jest wyłączone." + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/pt-br.json b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/pt-br.json new file mode 100644 index 0000000..59760cf --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/pt-br.json @@ -0,0 +1,33 @@ +{ + "errorUnknown": "Não foi possível completer o seu pedido. (Erro {number})", + "errors": { + "10": "Comando inválido.", + "11": "O tipo de recurso não foi especificado na solicitação.", + "12": "O tipo de recurso solicitado não é válido.", + "13": "O arquivo de configuração do conector não é válido.", + "14": "Plugin para o conector inválido: {pluginName}.", + "102": "Nome do arquivo ou pasta inválido.", + "103": "Não foi possível completar a solicitação por restrições de acesso.", + "104": "Não foi possível completar a solicitação por restrições de acesso do sistema de arquivos.", + "105": "Extensão de arquivo inválida.", + "109": "Solicitação inválida.", + "110": "Erro desconhecido.", + "111": "Impossível completar o pedido devido ao tamanho final do arquivo.", + "115": "Um arquivo ou pasta já existe com esse nome.", + "116": "Pasta não encontrada. Atualize e tente novamente.", + "117": "Arquivo não encontrado. Atualize a lista de arquivos e tente novamente.", + "118": "A origem e o destino são os mesmos.", + "201": "Um arquivo com o mesmo nome já está disponível. O arquivo enviado foi renomeado para \"{name}\".", + "202": "Arquivo inválido.", + "203": "Arquivo inválido. O tamanho é muito grande.", + "204": "O arquivo enviado está corrompido.", + "205": "Nenhuma pasta temporária para envio está disponível no servidor.", + "206": "Transmissão cancelada por razões de segurança. O arquivo contém dados HTML.", + "207": "O arquivo enviado foi renomeado para \"{name}\".", + "300": "Não foi possível mover o(s) arquivo(s).", + "301": "Não foi possível copiar o(s) arquivo(s).", + "302": "Não for possível apagar o(s) arquivo(s).", + "500": "A navegação de arquivos está desativada por razões de segurança. Contacte o administrador do sistema para controlar as configurações do CKFinder.", + "501": "O suporte a miniaturas está desabilitado." + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/ro.json b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/ro.json new file mode 100644 index 0000000..e37a1e6 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/ro.json @@ -0,0 +1,33 @@ +{ + "errorUnknown": "Nu a fost posibilă finalizarea cererii. (Eroare {number})", + "errors": { + "10": "Comandă invalidă.", + "11": "Tipul de resursă nu a fost specificat în cerere.", + "12": "Tipul de resursă cerut nu este valid.", + "13": "The connector configuration file is invalid.", + "14": "Invalid connector plugin: {pluginName}.", + "102": "Nume fișier sau nume dosar invalid.", + "103": "Nu a fost posibiliă finalizarea cererii din cauza restricțiilor de autorizare.", + "104": "Nu a fost posibiliă finalizarea cererii din cauza restricțiilor de permisiune la sistemul de fișiere.", + "105": "Extensie fișier invalidă.", + "109": "Cerere invalidă.", + "110": "Eroare necunoscută.", + "111": "It was not possible to complete the request due to resulting file size.", + "115": "Există deja un fișier sau un dosar cu același nume.", + "116": "Dosar negăsit. Te rog împrospătează și încearcă din nou.", + "117": "Fișier negăsit. Te rog împrospătează lista de fișiere și încearcă din nou.", + "118": "Calea sursei și a țintei sunt egale.", + "201": "Un fișier cu același nume este deja disponibil. Fișierul încărcat a fost redenumit cu \"{name}\".", + "202": "Fișier invalid.", + "203": "Fișier invalid. Mărimea fișierului este prea mare.", + "204": "Fișierul încărcat este corupt.", + "205": "Niciun dosar temporar nu este disponibil pentru încărcarea pe server.", + "206": "Încărcare anulată din motive de securitate. Fișierul conține date asemănătoare cu HTML.", + "207": "Fișierul încărcat a fost redenumit cu \"{name}\".", + "300": "Mutare fișier(e) eșuată.", + "301": "Copiere fișier(e) eșuată.", + "302": "Deleting file(s) failed.", + "500": "Browser-ul de fișiere este dezactivat din motive de securitate. Te rog contactează administratorul de sistem și verifică configurarea de fișiere CKFinder.", + "501": "Funcționalitatea de creat thumbnails este dezactivată." + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/ru.json b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/ru.json new file mode 100644 index 0000000..7315b51 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/ru.json @@ -0,0 +1,33 @@ +{ + "errorUnknown": "Невозможно завершить запрос. (Ошибка {number})", + "errors": { + "10": "Неверная команда.", + "11": "Тип ресурса не указан в запросе.", + "12": "Неверный запрошенный тип ресурса.", + "13": "Ошибка в конфигурационном файле.", + "14": "Ошибка в плагине: {pluginName}.", + "102": "Неверное имя файла или папки.", + "103": "Невозможно завершить запрос из-за ограничений авторизации.", + "104": "Невозможно завершить запрос из-за ограничения разрешений файловой системы.", + "105": "Неверное расширение файла.", + "109": "Неверный запрос.", + "110": "Неизвестная ошибка.", + "111": "Невозможно завершить запрос из-за размера конечного файла.", + "115": "Файл или папка с таким именем уже существует.", + "116": "Папка не найдена. Пожалуйста, обновите вид папок и попробуйте еще раз.", + "117": "Файл не найден. Пожалуйста, обновите список файлов и попробуйте еще раз.", + "118": "Исходное расположение файла совпадает с указанным.", + "201": "Файл с таким именем уже существует. Загруженный файл был переименован в \"{name}\".", + "202": "Неверный файл.", + "203": "Неверный файл. Размер файла слишком большой.", + "204": "Загруженный файл поврежден.", + "205": "Недоступна временная папка для загрузки файлов на сервер.", + "206": "Загрузка отменена из-за соображений безопасности. Файл содержит похожие на HTML данные.", + "207": "Загруженный файл был переименован в \"{name}\".", + "300": "Произошла ошибка при перемещении файла(ов).", + "301": "Произошла ошибка при копировании файла(ов).", + "302": "Произошла ошибка при удалении файла(ов).", + "500": "Браузер файлов отключен из-за соображений безопасности. Пожалуйста, сообщите вашему системному администратру и проверьте конфигурационный файл CKFinder.", + "501": "Поддержка миниатюр отключена." + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/sk.json b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/sk.json new file mode 100644 index 0000000..3225ccc --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/sk.json @@ -0,0 +1,33 @@ +{ + "errorUnknown": "Server nemohol dokončiť spracovanie požiadavky. (Chyba {number})", + "errors": { + "10": "Neplatný príkaz.", + "11": "V požiadavke nebol špecifikovaný typ súboru.", + "12": "Nepodporovaný typ súboru.", + "13": "The connector configuration file is invalid.", + "14": "Invalid connector plugin: {pluginName}.", + "102": "Neplatný názov súboru alebo adresára.", + "103": "Nebolo možné dokončiť spracovanie požiadavky kvôli nepostačujúcej úrovni oprávnení.", + "104": "Nebolo možné dokončiť spracovanie požiadavky kvôli obmedzeniam v prístupových právach k súborom.", + "105": "Neplatná prípona súboru.", + "109": "Neplatná požiadavka.", + "110": "Neidentifikovaná chyba.", + "111": "It was not possible to complete the request due to resulting file size.", + "115": "Zadaný súbor alebo adresár už existuje.", + "116": "Adresár nebol nájdený. Aktualizujte obsah adresára (Znovunačítať) a skúste znovu.", + "117": "Súbor nebol nájdený. Aktualizujte obsah adresára (Znovunačítať) a skúste znovu.", + "118": "Zdrojové a cieľové cesty sú rovnaké.", + "201": "Súbor so zadaným názvom už existuje. Prekopírovaný súbor bol premenovaný na \"{name}\".", + "202": "Neplatný súbor.", + "203": "Neplatný súbor - súbor presahuje maximálnu povolenú veľkosť.", + "204": "Kopírovaný súbor je poškodený.", + "205": "Server nemá špecifikovaný dočasný adresár pre kopírované súbory.", + "206": "Kopírovanie prerušené kvôli nedostatočnému zabezpečeniu. Súbor obsahuje HTML data.", + "207": "Prekopírovaný súbor bol premenovaný na \"{name}\".", + "300": "Presunutie súborov zlyhalo.", + "301": "Kopírovanie súborov zlyhalo.", + "302": "Deleting file(s) failed.", + "500": "Prehliadanie súborov je zakázané kvôli bezpečnosti. Kontaktujte prosím administrátora a overte nastavenia v konfiguračnom súbore pre CKFinder.", + "501": "Momentálne nie je zapnutá podpora pre generáciu miniobrázkov." + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/sl.json b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/sl.json new file mode 100644 index 0000000..68be5fb --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/sl.json @@ -0,0 +1,33 @@ +{ + "errorUnknown": "Prišlo je do napake. (Napaka {number})", + "errors": { + "10": "Napačen ukaz.", + "11": "V poizvedbi ni bil jasen tip (resource type).", + "12": "Tip datoteke ni primeren.", + "13": "The connector configuration file is invalid.", + "14": "Invalid connector plugin: {pluginName}.", + "102": "Napačno ime mape ali datoteke.", + "103": "Vašega ukaza se ne da izvesti zaradi težav z avtorizacijo.", + "104": "Vašega ukaza se ne da izvesti zaradi težav z nastavitvami pravic v datotečnem sistemu.", + "105": "Napačna končnica datoteke.", + "109": "Napačna zahteva.", + "110": "Neznana napaka.", + "111": "It was not possible to complete the request due to resulting file size.", + "115": "Datoteka ali mapa s tem imenom že obstaja.", + "116": "Mapa ni najdena. Prosimo osvežite okno in poskusite znova.", + "117": "Datoteka ni najdena. Prosimo osvežite seznam datotek in poskusite znova.", + "118": "Začetna in končna pot je ista.", + "201": "Datoteka z istim imenom že obstaja. Naložena datoteka je bila preimenovana v \"{name}\".", + "202": "Neprimerna datoteka.", + "203": "Datoteka je prevelika in zasede preveč prostora.", + "204": "Naložena datoteka je okvarjena.", + "205": "Na strežniku ni na voljo začasna mapa za prenos datotek.", + "206": "Nalaganje je bilo prekinjeno zaradi varnostnih razlogov. Datoteka vsebuje podatke, ki spominjajo na HTML kodo.", + "207": "Naložena datoteka je bila preimenovana v \"{name}\".", + "300": "Premikanje datotek(e) ni uspelo.", + "301": "Kopiranje datotek(e) ni uspelo.", + "302": "Deleting file(s) failed.", + "500": "Brskalnik je onemogočen zaradi varnostnih razlogov. Prosimo kontaktirajte upravljalca spletnih strani.", + "501": "Ni podpore za majhne sličice (predogled)." + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/sr.json b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/sr.json new file mode 100644 index 0000000..1aab778 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/sr.json @@ -0,0 +1,33 @@ +{ + "errorUnknown": "Није могуће изавршити захтев. (Грешка {number})", + "errors": { + "10": "Непозната наредба.", + "11": "Није наведена врста у захтеву.", + "12": "Затражена врста није важећа.", + "13": "Неисправна датотека за конфигурацију конектора.", + "14": "Неисправан конектор за прикључење: {pluginName}.", + "102": "Неисправан назив датотеке или фасцикле.", + "103": "Није могуће извршити захтев због ограничења приступа.", + "104": "Није могуће извршити захтев због ограничења поставке система.", + "105": "Недозвољена врста датотеке.", + "109": "Недозвољен захтев.", + "110": "Непозната грешка.", + "111": "Није могуће извршити захтев због резултујуће величине датотеке.", + "115": "Датотека или фасцикла са истим називом већ постоји.", + "116": "Фасцикла није пронађена. Освежите страницу и покушајте поново.", + "117": "Датотека није пронађена. Освежите листу датотека и покушајте поново.", + "118": "Путања извора и одредишта су исте.", + "201": "Датотека са истим називом већ постоји. Учитана датотека је промењена у \"{name}\".", + "202": "Неисправна датотека.", + "203": "Неисправна датотека. Величина датотеке је превелика.", + "204": "Учитана датотека је неисправна.", + "205": "Не постоји привремена фасцикла за учитавање на серверe.", + "206": "Слање је поништено због сигурносних поставки. Назив датотеке садржи HTML податке.", + "207": "Учитана датотека је промењена у \"{name}\".", + "300": "Премештање датотеке(а) није успело.", + "301": "Копирање датотеке(а) није успело.", + "302": "Брисање датотеке(а) није успело.", + "500": "Претраживање датотека није дозвољено из сигурносних разлога. Молимо контактирајте администратора система како би проверили поставке CKFinder конфигурационе датотеке.", + "501": "Подршка за приказ није омогућена." + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/sv.json b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/sv.json new file mode 100644 index 0000000..6bbed2a --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/sv.json @@ -0,0 +1,33 @@ +{ + "errorUnknown": "Begäran kunde inte utföras eftersom ett fel uppstod. (Fel {number})", + "errors": { + "10": "Ogiltig begäran.", + "11": "Resursens typ var inte specificerad i förfrågan.", + "12": "Den efterfrågade resurstypen är inte giltig.", + "13": "The connector configuration file is invalid.", + "14": "Invalid connector plugin: {pluginName}.", + "102": "Ogiltigt fil- eller mappnamn.", + "103": "Begäran kunde inte utföras p.g.a. restriktioner av rättigheterna.", + "104": "Begäran kunde inte utföras p.g.a. restriktioner av rättigheter i filsystemet.", + "105": "Ogiltig filändelse.", + "109": "Ogiltig begäran.", + "110": "Okänt fel.", + "111": "It was not possible to complete the request due to resulting file size.", + "115": "En fil eller mapp med aktuellt namn finns redan.", + "116": "Mappen kunde inte hittas. Var god uppdatera sidan och försök igen.", + "117": "Filen kunde inte hittas. Var god uppdatera sidan och försök igen.", + "118": "Sökväg till källa och mål är identisk.", + "201": "En fil med aktuellt namn fanns redan. Den uppladdade filen har döpts om till \"{name}\".", + "202": "Ogiltig fil.", + "203": "Ogiltig fil. Filen var för stor.", + "204": "Den uppladdade filen var korrupt.", + "205": "En tillfällig mapp för uppladdning är inte tillgänglig på servern.", + "206": "Uppladdningen stoppades av säkerhetsskäl. Filen innehåller HTML-liknande data.", + "207": "Den uppladdade filen har döpts om till \"{name}\".", + "300": "Flytt av fil(er) misslyckades.", + "301": "Kopiering av fil(er) misslyckades.", + "302": "Radering av fil(er) misslyckades.", + "500": "Filhanteraren har stoppats av säkerhetsskäl. Var god kontakta administratören för att kontrollera konfigurationsfilen för CKFinder.", + "501": "Stöd för tumnaglar har stängts av." + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/tr.json b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/tr.json new file mode 100644 index 0000000..c135d98 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/tr.json @@ -0,0 +1,33 @@ +{ + "errorUnknown": "İsteğinizi yerine getirmek mümkün değil. (Hata {number})", + "errors": { + "10": "Geçersiz komut.", + "11": "İstekte kaynak türü belirtilmemiş.", + "12": "Talep edilen kaynak türü geçersiz.", + "13": "The connector configuration file is invalid.", + "14": "Invalid connector plugin: {pluginName}.", + "102": "Geçersiz dosya ya da klasör adı.", + "103": "Kimlik doğrulama kısıtlamaları nedeni ile talebinizi yerine getiremiyoruz.", + "104": "Dosya sistemi kısıtlamaları nedeni ile talebinizi yerine getiremiyoruz.", + "105": "Geçersiz dosya uzantısı.", + "109": "Geçersiz istek.", + "110": "Bilinmeyen hata.", + "111": "It was not possible to complete the request due to resulting file size.", + "115": "Aynı isimde bir dosya ya da klasör zaten var.", + "116": "Klasör bulunamadı. Lütfen yenileyin ve tekrar deneyin.", + "117": "Dosya bulunamadı. Lütfen dosya listesini yenileyin ve tekrar deneyin.", + "118": "Kaynak ve hedef yol aynı!", + "201": "Aynı ada sahip bir dosya zaten var. Yüklenen dosyanın adı \"{name}\" olarak değiştirildi.", + "202": "Geçersiz dosya", + "203": "Geçersiz dosya. Dosya boyutu çok büyük.", + "204": "Yüklenen dosya bozuk.", + "205": "Dosyaları yüklemek için gerekli geçici klasör sunucuda bulunamadı.", + "206": "Güvenlik nedeni ile yükleme iptal edildi. Dosya HTML benzeri veri içeriyor.", + "207": "Yüklenen dosyanın adı \"{name}\" olarak değiştirildi.", + "300": "Dosya taşıma işlemi başarısız.", + "301": "Dosya kopyalama işlemi başarısız.", + "302": "Deleting file(s) failed.", + "500": "Güvenlik nedeni ile dosya gezgini devredışı bırakıldı. Lütfen sistem yöneticiniz ile irtibata geçin ve CKFinder yapılandırma dosyasını kontrol edin.", + "501": "Önizleme desteği devredışı." + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/vi.json b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/vi.json new file mode 100644 index 0000000..ef3b9d4 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/vi.json @@ -0,0 +1,33 @@ +{ + "errorUnknown": "Không thể hoàn tất yêu cầu. (Lỗi {number})", + "errors": { + "10": "Lệnh không hợp lệ.", + "11": "Kiểu tài nguyên không được chỉ định trong yêu cầu.", + "12": "Kiểu tài nguyên yêu cầu không hợp lệ.", + "13": "The connector configuration file is invalid.", + "14": "Invalid connector plugin: {pluginName}.", + "102": "Tên tập tin hay thư mục không hợp lệ.", + "103": "Không thể hoàn tất yêu cầu vì giới hạn quyền.", + "104": "Không thể hoàn tất yêu cầu vì giới hạn quyền của hệ thống tập tin.", + "105": "Phần mở rộng tập tin không hợp lệ.", + "109": "Yêu cầu không hợp lệ.", + "110": "Lỗi không xác định.", + "111": "It was not possible to complete the request due to resulting file size.", + "115": "Tập tin hoặc thư mục cùng tên đã tồn tại.", + "116": "Không thấy thư mục. Hãy làm tươi và thử lại.", + "117": "Không thấy tập tin. Hãy làm tươi và thử lại.", + "118": "Đường dẫn nguồn và đích giống nhau.", + "201": "Tập tin cùng tên đã tồn tại. Tập tin vừa tải lên được đổi tên thành \"{name}\".", + "202": "Tập tin không hợp lệ.", + "203": "Tập tin không hợp lệ. Dung lượng quá lớn.", + "204": "Tập tin tải lên bị hỏng.", + "205": "Không có thư mục tạm để tải tập tin.", + "206": "Huỷ tải lên vì lí do bảo mật. Tập tin chứa dữ liệu giống HTML.", + "207": "Tập tin được đổi tên thành \"{name}\".", + "300": "Di chuyển tập tin thất bại.", + "301": "Chép tập tin thất bại.", + "302": "Deleting file(s) failed.", + "500": "Trình duyệt tập tin bị vô hiệu vì lí do bảo mật. Xin liên hệ quản trị hệ thống và kiểm tra tập tin cấu hình CKFinder.", + "501": "Chức năng hỗ trợ ảnh mẫu bị vô hiệu." + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/zh-cn.json b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/zh-cn.json new file mode 100644 index 0000000..a395013 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/zh-cn.json @@ -0,0 +1,33 @@ +{ + "errorUnknown": "请求的操作未能完成。(错误 {number})", + "errors": { + "10": "无效的指令。", + "11": "文件类型不在许可范围之内。", + "12": "文件类型无效。", + "13": "无效的连接器设置文件。", + "14": "无效的连接器插件: {pluginName}。", + "102": "无效的文件名或文件夹名称。", + "103": "由于作者限制,该请求不能完成。", + "104": "由于文件系统的限制,该请求不能完成。", + "105": "无效的扩展名。", + "109": "无效请求。", + "110": "未知错误。", + "111": "由于文件大小原因,此请求无法完成。", + "115": "存在重名的文件或文件夹。", + "116": "文件夹不存在,请刷新后再试。", + "117": "文件不存在,请刷新列表后再试。", + "118": "目标位置与当前位置相同。", + "201": "文件与现有的重名,新上传的文件改名为 \"{name}\"。", + "202": "无效的文件。", + "203": "无效的文件,文件尺寸太大。", + "204": "上传文件已损失。", + "205": "服务器中的上传临时文件夹无效。", + "206": "因为安全原因,上传中断。上传文件包含不能 HTML 类型数据。", + "207": "新上传的文件改名为 \"{name}\"。", + "300": "移动文件失败。", + "301": "复制文件失败。", + "302": "删除文件失败。", + "500": "因为安全原因,文件不可浏览。请联系系统管理员并检查 CKFinder 配置文件。", + "501": "不支持缩略图方式。" + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/zh-tw.json b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/zh-tw.json new file mode 100644 index 0000000..a29be83 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/locales/zh-tw.json @@ -0,0 +1,33 @@ +{ + "errorUnknown": "無法連接到伺服器 ! (錯誤代碼 {number})", + "errors": { + "10": "不合法的指令.", + "11": "連接過程中 , 未指定資源形態 !", + "12": "連接過程中出現不合法的資源形態 !", + "13": "The connector configuration file is invalid.", + "14": "Invalid connector plugin: {pluginName}.", + "102": "不合法的檔案或目錄名稱 !", + "103": "無法連接:可能是使用者權限設定錯誤 !", + "104": "無法連接:可能是伺服器檔案權限設定錯誤 !", + "105": "無法上傳:不合法的副檔名 !", + "109": "不合法的請求 !", + "110": "不明錯誤 !", + "111": "It was not possible to complete the request due to resulting file size.", + "115": "檔案或目錄名稱重複 !", + "116": "找不到目錄 ! 請先重新整理 , 然後再試一次 !", + "117": "找不到檔案 ! 請先重新整理 , 然後再試一次 !", + "118": "Source and target paths are equal.", + "201": "伺服器上已有相同的檔案名稱 ! 您上傳的檔案名稱將會自動更改為 \"{name}\".", + "202": "不合法的檔案 !", + "203": "不合法的檔案 ! 檔案大小超過預設值 !", + "204": "您上傳的檔案已經損毀 !", + "205": "伺服器上沒有預設的暫存目錄 !", + "206": "檔案上傳程序因為安全因素已被系統自動取消 ! 可能是上傳的檔案內容包含 HTML 碼 !", + "207": "您上傳的檔案名稱將會自動更改為 \"{name}\".", + "300": "Moving file(s) failed.", + "301": "Copying file(s) failed.", + "302": "Deleting file(s) failed.", + "500": "因為安全因素 , 檔案瀏覽器已被停用 ! 請聯絡您的系統管理者並檢查 CKFinder 的設定檔 config.php !", + "501": "縮圖預覽功能已被停用 !" + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/composer/ClassLoader.php b/lib/ckfinder/core/connector/php/vendor/composer/ClassLoader.php new file mode 100644 index 0000000..ff6ecfb --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/composer/ClassLoader.php @@ -0,0 +1,413 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Autoload; + +/** + * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. + * + * $loader = new \Composer\Autoload\ClassLoader(); + * + * // register classes with namespaces + * $loader->add('Symfony\Component', __DIR__.'/component'); + * $loader->add('Symfony', __DIR__.'/framework'); + * + * // activate the autoloader + * $loader->register(); + * + * // to enable searching the include path (eg. for PEAR packages) + * $loader->setUseIncludePath(true); + * + * In this example, if you try to use a class in the Symfony\Component + * namespace or one of its children (Symfony\Component\Console for instance), + * the autoloader will first look for the class under the component/ + * directory, and it will then fallback to the framework/ directory if not + * found before giving up. + * + * This class is loosely based on the Symfony UniversalClassLoader. + * + * @author Fabien Potencier + * @author Jordi Boggiano + * @see http://www.php-fig.org/psr/psr-0/ + * @see http://www.php-fig.org/psr/psr-4/ + */ +class ClassLoader +{ + // PSR-4 + private $prefixLengthsPsr4 = array(); + private $prefixDirsPsr4 = array(); + private $fallbackDirsPsr4 = array(); + + // PSR-0 + private $prefixesPsr0 = array(); + private $fallbackDirsPsr0 = array(); + + private $useIncludePath = false; + private $classMap = array(); + + private $classMapAuthoritative = false; + + public function getPrefixes() + { + if (!empty($this->prefixesPsr0)) { + return call_user_func_array('array_merge', $this->prefixesPsr0); + } + + return array(); + } + + public function getPrefixesPsr4() + { + return $this->prefixDirsPsr4; + } + + public function getFallbackDirs() + { + return $this->fallbackDirsPsr0; + } + + public function getFallbackDirsPsr4() + { + return $this->fallbackDirsPsr4; + } + + public function getClassMap() + { + return $this->classMap; + } + + /** + * @param array $classMap Class to filename map + */ + public function addClassMap(array $classMap) + { + if ($this->classMap) { + $this->classMap = array_merge($this->classMap, $classMap); + } else { + $this->classMap = $classMap; + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, either + * appending or prepending to the ones previously set for this prefix. + * + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories + */ + public function add($prefix, $paths, $prepend = false) + { + if (!$prefix) { + if ($prepend) { + $this->fallbackDirsPsr0 = array_merge( + (array) $paths, + $this->fallbackDirsPsr0 + ); + } else { + $this->fallbackDirsPsr0 = array_merge( + $this->fallbackDirsPsr0, + (array) $paths + ); + } + + return; + } + + $first = $prefix[0]; + if (!isset($this->prefixesPsr0[$first][$prefix])) { + $this->prefixesPsr0[$first][$prefix] = (array) $paths; + + return; + } + if ($prepend) { + $this->prefixesPsr0[$first][$prefix] = array_merge( + (array) $paths, + $this->prefixesPsr0[$first][$prefix] + ); + } else { + $this->prefixesPsr0[$first][$prefix] = array_merge( + $this->prefixesPsr0[$first][$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, either + * appending or prepending to the ones previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories + * + * @throws \InvalidArgumentException + */ + public function addPsr4($prefix, $paths, $prepend = false) + { + if (!$prefix) { + // Register directories for the root namespace. + if ($prepend) { + $this->fallbackDirsPsr4 = array_merge( + (array) $paths, + $this->fallbackDirsPsr4 + ); + } else { + $this->fallbackDirsPsr4 = array_merge( + $this->fallbackDirsPsr4, + (array) $paths + ); + } + } elseif (!isset($this->prefixDirsPsr4[$prefix])) { + // Register directories for a new namespace. + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } elseif ($prepend) { + // Prepend directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + (array) $paths, + $this->prefixDirsPsr4[$prefix] + ); + } else { + // Append directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + $this->prefixDirsPsr4[$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, + * replacing any others previously set for this prefix. + * + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 base directories + */ + public function set($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr0 = (array) $paths; + } else { + $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, + * replacing any others previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories + * + * @throws \InvalidArgumentException + */ + public function setPsr4($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr4 = (array) $paths; + } else { + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } + } + + /** + * Turns on searching the include path for class files. + * + * @param bool $useIncludePath + */ + public function setUseIncludePath($useIncludePath) + { + $this->useIncludePath = $useIncludePath; + } + + /** + * Can be used to check if the autoloader uses the include path to check + * for classes. + * + * @return bool + */ + public function getUseIncludePath() + { + return $this->useIncludePath; + } + + /** + * Turns off searching the prefix and fallback directories for classes + * that have not been registered with the class map. + * + * @param bool $classMapAuthoritative + */ + public function setClassMapAuthoritative($classMapAuthoritative) + { + $this->classMapAuthoritative = $classMapAuthoritative; + } + + /** + * Should class lookup fail if not found in the current class map? + * + * @return bool + */ + public function isClassMapAuthoritative() + { + return $this->classMapAuthoritative; + } + + /** + * Registers this instance as an autoloader. + * + * @param bool $prepend Whether to prepend the autoloader or not + */ + public function register($prepend = false) + { + spl_autoload_register(array($this, 'loadClass'), true, $prepend); + } + + /** + * Unregisters this instance as an autoloader. + */ + public function unregister() + { + spl_autoload_unregister(array($this, 'loadClass')); + } + + /** + * Loads the given class or interface. + * + * @param string $class The name of the class + * @return bool|null True if loaded, null otherwise + */ + public function loadClass($class) + { + if ($file = $this->findFile($class)) { + includeFile($file); + + return true; + } + } + + /** + * Finds the path to the file where the class is defined. + * + * @param string $class The name of the class + * + * @return string|false The path if found, false otherwise + */ + public function findFile($class) + { + // work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731 + if ('\\' == $class[0]) { + $class = substr($class, 1); + } + + // class map lookup + if (isset($this->classMap[$class])) { + return $this->classMap[$class]; + } + if ($this->classMapAuthoritative) { + return false; + } + + $file = $this->findFileWithExtension($class, '.php'); + + // Search for Hack files if we are running on HHVM + if ($file === null && defined('HHVM_VERSION')) { + $file = $this->findFileWithExtension($class, '.hh'); + } + + if ($file === null) { + // Remember that this class does not exist. + return $this->classMap[$class] = false; + } + + return $file; + } + + private function findFileWithExtension($class, $ext) + { + // PSR-4 lookup + $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; + + $first = $class[0]; + if (isset($this->prefixLengthsPsr4[$first])) { + foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) { + if (0 === strpos($class, $prefix)) { + foreach ($this->prefixDirsPsr4[$prefix] as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) { + return $file; + } + } + } + } + } + + // PSR-4 fallback dirs + foreach ($this->fallbackDirsPsr4 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { + return $file; + } + } + + // PSR-0 lookup + if (false !== $pos = strrpos($class, '\\')) { + // namespaced class name + $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) + . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); + } else { + // PEAR-like class name + $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; + } + + if (isset($this->prefixesPsr0[$first])) { + foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { + if (0 === strpos($class, $prefix)) { + foreach ($dirs as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + } + } + } + + // PSR-0 fallback dirs + foreach ($this->fallbackDirsPsr0 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + + // PSR-0 include paths. + if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { + return $file; + } + } +} + +/** + * Scope isolated include. + * + * Prevents access to $this/self from included files. + */ +function includeFile($file) +{ + include $file; +} diff --git a/lib/ckfinder/core/connector/php/vendor/composer/LICENSE b/lib/ckfinder/core/connector/php/vendor/composer/LICENSE new file mode 100644 index 0000000..1a28124 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/composer/LICENSE @@ -0,0 +1,21 @@ + +Copyright (c) 2016 Nils Adermann, Jordi Boggiano + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/lib/ckfinder/core/connector/php/vendor/composer/autoload_classmap.php b/lib/ckfinder/core/connector/php/vendor/composer/autoload_classmap.php new file mode 100644 index 0000000..2d3805e --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/composer/autoload_classmap.php @@ -0,0 +1,110 @@ + $vendorDir . '/pear-pear.php.net/Archive_Tar/Archive/Tar.php', + 'Console_Getopt' => $vendorDir . '/pear-pear.php.net/Console_Getopt/Console/Getopt.php', + 'HTTP_Request2' => $vendorDir . '/pear-pear.php.net/HTTP_Request2/HTTP/Request2.php', + 'HTTP_Request2_Adapter' => $vendorDir . '/pear-pear.php.net/HTTP_Request2/HTTP/Request2/Adapter.php', + 'HTTP_Request2_Adapter_Curl' => $vendorDir . '/pear-pear.php.net/HTTP_Request2/HTTP/Request2/Adapter/Curl.php', + 'HTTP_Request2_Adapter_Mock' => $vendorDir . '/pear-pear.php.net/HTTP_Request2/HTTP/Request2/Adapter/Mock.php', + 'HTTP_Request2_Adapter_Socket' => $vendorDir . '/pear-pear.php.net/HTTP_Request2/HTTP/Request2/Adapter/Socket.php', + 'HTTP_Request2_ConnectionException' => $vendorDir . '/pear-pear.php.net/HTTP_Request2/HTTP/Request2/Exception.php', + 'HTTP_Request2_CookieJar' => $vendorDir . '/pear-pear.php.net/HTTP_Request2/HTTP/Request2/CookieJar.php', + 'HTTP_Request2_Exception' => $vendorDir . '/pear-pear.php.net/HTTP_Request2/HTTP/Request2/Exception.php', + 'HTTP_Request2_LogicException' => $vendorDir . '/pear-pear.php.net/HTTP_Request2/HTTP/Request2/Exception.php', + 'HTTP_Request2_MessageException' => $vendorDir . '/pear-pear.php.net/HTTP_Request2/HTTP/Request2/Exception.php', + 'HTTP_Request2_MultipartBody' => $vendorDir . '/pear-pear.php.net/HTTP_Request2/HTTP/Request2/MultipartBody.php', + 'HTTP_Request2_NotImplementedException' => $vendorDir . '/pear-pear.php.net/HTTP_Request2/HTTP/Request2/Exception.php', + 'HTTP_Request2_Observer_Log' => $vendorDir . '/pear-pear.php.net/HTTP_Request2/HTTP/Request2/Observer/Log.php', + 'HTTP_Request2_Observer_UncompressingDownload' => $vendorDir . '/pear-pear.php.net/HTTP_Request2/HTTP/Request2/Observer/UncompressingDownload.php', + 'HTTP_Request2_Response' => $vendorDir . '/pear-pear.php.net/HTTP_Request2/HTTP/Request2/Response.php', + 'HTTP_Request2_SOCKS5' => $vendorDir . '/pear-pear.php.net/HTTP_Request2/HTTP/Request2/SOCKS5.php', + 'HTTP_Request2_SocketWrapper' => $vendorDir . '/pear-pear.php.net/HTTP_Request2/HTTP/Request2/SocketWrapper.php', + 'Mail_mime' => $vendorDir . '/pear-pear.php.net/Mail_Mime/Mail/mime.php', + 'Mail_mimeDecode' => $vendorDir . '/pear-pear.php.net/Mail_mimeDecode/Mail/mimeDecode.php', + 'Mail_mimePart' => $vendorDir . '/pear-pear.php.net/Mail_Mime/Mail/mimePart.php', + 'Net_URL2' => $vendorDir . '/pear-pear.php.net/Net_URL2/Net/URL2.php', + 'OS_Guess' => $vendorDir . '/pear-pear.php.net/PEAR/OS/Guess.php', + 'PEAR' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR.php', + 'PEAR_Autoloader' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Autoloader.php', + 'PEAR_Builder' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Builder.php', + 'PEAR_ChannelFile' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/ChannelFile.php', + 'PEAR_ChannelFile_Parser' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/ChannelFile/Parser.php', + 'PEAR_Command' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Command.php', + 'PEAR_Command_Auth' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Command/Auth.php', + 'PEAR_Command_Build' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Command/Build.php', + 'PEAR_Command_Channels' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Command/Channels.php', + 'PEAR_Command_Common' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Command/Common.php', + 'PEAR_Command_Config' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Command/Config.php', + 'PEAR_Command_Install' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Command/Install.php', + 'PEAR_Command_Mirror' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Command/Mirror.php', + 'PEAR_Command_Package' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Command/Package.php', + 'PEAR_Command_Pickle' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Command/Pickle.php', + 'PEAR_Command_Registry' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Command/Registry.php', + 'PEAR_Command_Remote' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Command/Remote.php', + 'PEAR_Command_Test' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Command/Test.php', + 'PEAR_Common' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Common.php', + 'PEAR_Config' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Config.php', + 'PEAR_Dependency2' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Dependency2.php', + 'PEAR_DependencyDB' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/DependencyDB.php', + 'PEAR_Downloader' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Downloader.php', + 'PEAR_Downloader_Package' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Downloader/Package.php', + 'PEAR_Error' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR.php', + 'PEAR_ErrorStack' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/ErrorStack.php', + 'PEAR_Exception' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Exception.php', + 'PEAR_Frontend' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Frontend.php', + 'PEAR_Frontend_CLI' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Frontend/CLI.php', + 'PEAR_Installer' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Installer.php', + 'PEAR_Installer_Role' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Installer/Role.php', + 'PEAR_Installer_Role_Cfg' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Installer/Role/Cfg.php', + 'PEAR_Installer_Role_Common' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Installer/Role/Common.php', + 'PEAR_Installer_Role_Data' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Installer/Role/Data.php', + 'PEAR_Installer_Role_Doc' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Installer/Role/Doc.php', + 'PEAR_Installer_Role_Ext' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Installer/Role/Ext.php', + 'PEAR_Installer_Role_Man' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Installer/Role/Man.php', + 'PEAR_Installer_Role_Php' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Installer/Role/Php.php', + 'PEAR_Installer_Role_Script' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Installer/Role/Script.php', + 'PEAR_Installer_Role_Src' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Installer/Role/Src.php', + 'PEAR_Installer_Role_Test' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Installer/Role/Test.php', + 'PEAR_Installer_Role_Www' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Installer/Role/Www.php', + 'PEAR_PackageFile' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/PackageFile.php', + 'PEAR_PackageFile_Generator_v1' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/PackageFile/Generator/v1.php', + 'PEAR_PackageFile_Generator_v2' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/PackageFile/Generator/v2.php', + 'PEAR_PackageFile_Parser_v1' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/PackageFile/Parser/v1.php', + 'PEAR_PackageFile_Parser_v2' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/PackageFile/Parser/v2.php', + 'PEAR_PackageFile_v1' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/PackageFile/v1.php', + 'PEAR_PackageFile_v2' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/PackageFile/v2.php', + 'PEAR_PackageFile_v2_Validator' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/PackageFile/v2/Validator.php', + 'PEAR_PackageFile_v2_rw' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/PackageFile/v2/rw.php', + 'PEAR_Packager' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Packager.php', + 'PEAR_REST' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/REST.php', + 'PEAR_REST_10' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/REST/10.php', + 'PEAR_REST_11' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/REST/11.php', + 'PEAR_REST_13' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/REST/13.php', + 'PEAR_Registry' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Registry.php', + 'PEAR_RunTest' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/RunTest.php', + 'PEAR_Task_Common' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Task/Common.php', + 'PEAR_Task_Postinstallscript' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Task/Postinstallscript.php', + 'PEAR_Task_Postinstallscript_rw' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Task/Postinstallscript/rw.php', + 'PEAR_Task_Replace' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Task/Replace.php', + 'PEAR_Task_Replace_rw' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Task/Replace/rw.php', + 'PEAR_Task_Unixeol' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Task/Unixeol.php', + 'PEAR_Task_Unixeol_rw' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Task/Unixeol/rw.php', + 'PEAR_Task_Windowseol' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Task/Windowseol.php', + 'PEAR_Task_Windowseol_rw' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Task/Windowseol/rw.php', + 'PEAR_Validate' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Validate.php', + 'PEAR_Validator_PECL' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Validator/PECL.php', + 'PEAR_XMLParser' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/XMLParser.php', + 'SessionHandlerInterface' => $vendorDir . '/symfony/http-foundation/Resources/stubs/SessionHandlerInterface.php', + 'Structures_Graph' => $vendorDir . '/pear-pear.php.net/Structures_Graph/Structures/Graph.php', + 'Structures_Graph_Manipulator_AcyclicTest' => $vendorDir . '/pear-pear.php.net/Structures_Graph/Structures/Graph/Manipulator/AcyclicTest.php', + 'Structures_Graph_Manipulator_TopologicalSorter' => $vendorDir . '/pear-pear.php.net/Structures_Graph/Structures/Graph/Manipulator/TopologicalSorter.php', + 'Structures_Graph_Node' => $vendorDir . '/pear-pear.php.net/Structures_Graph/Structures/Graph/Node.php', + 'System' => $vendorDir . '/pear-pear.php.net/PEAR/System.php', + 'XML_Util' => $vendorDir . '/pear-pear.php.net/XML_Util/XML/Util.php', +); diff --git a/lib/ckfinder/core/connector/php/vendor/composer/autoload_files.php b/lib/ckfinder/core/connector/php/vendor/composer/autoload_files.php new file mode 100644 index 0000000..315ab83 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/composer/autoload_files.php @@ -0,0 +1,10 @@ + $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php', +); diff --git a/lib/ckfinder/core/connector/php/vendor/composer/autoload_namespaces.php b/lib/ckfinder/core/connector/php/vendor/composer/autoload_namespaces.php new file mode 100644 index 0000000..d7cc83c --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/composer/autoload_namespaces.php @@ -0,0 +1,16 @@ + array($vendorDir . '/microsoft/windowsazure'), + 'Pimple' => array($vendorDir . '/pimple/pimple/src'), + 'Guzzle\\Tests' => array($vendorDir . '/guzzle/guzzle/tests'), + 'Guzzle' => array($vendorDir . '/guzzle/guzzle/src'), + 'Dropbox' => array($vendorDir . '/dropbox/dropbox-sdk/lib'), + 'CKSource' => array($vendorDir . '/cksource/ckfinder/src'), + 'Aws' => array($vendorDir . '/aws/aws-sdk-php/src'), +); diff --git a/lib/ckfinder/core/connector/php/vendor/composer/autoload_psr4.php b/lib/ckfinder/core/connector/php/vendor/composer/autoload_psr4.php new file mode 100644 index 0000000..2713a38 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/composer/autoload_psr4.php @@ -0,0 +1,23 @@ + array($vendorDir . '/symfony/polyfill-mbstring'), + 'Symfony\\Component\\HttpKernel\\' => array($vendorDir . '/symfony/http-kernel'), + 'Symfony\\Component\\HttpFoundation\\' => array($vendorDir . '/symfony/http-foundation'), + 'Symfony\\Component\\EventDispatcher\\' => array($vendorDir . '/symfony/event-dispatcher'), + 'Symfony\\Component\\Debug\\' => array($vendorDir . '/symfony/debug'), + 'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'), + 'Psr\\Cache\\' => array($vendorDir . '/psr/cache/src'), + 'Monolog\\' => array($vendorDir . '/monolog/monolog/src/Monolog'), + 'League\\Flysystem\\Dropbox\\' => array($vendorDir . '/league/flysystem-dropbox/src'), + 'League\\Flysystem\\Cached\\' => array($vendorDir . '/league/flysystem-cached-adapter/src'), + 'League\\Flysystem\\Azure\\' => array($vendorDir . '/league/flysystem-azure/src'), + 'League\\Flysystem\\AwsS3v2\\' => array($vendorDir . '/league/flysystem-aws-s3-v2/src'), + 'League\\Flysystem\\' => array($vendorDir . '/league/flysystem/src'), + 'CKSource\\CKFinder\\Plugin\\' => array($vendorDir . '/cksource/ckfinder/plugins'), +); diff --git a/lib/ckfinder/core/connector/php/vendor/composer/autoload_real.php b/lib/ckfinder/core/connector/php/vendor/composer/autoload_real.php new file mode 100644 index 0000000..41d65cb --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/composer/autoload_real.php @@ -0,0 +1,74 @@ += 50600 && !defined('HHVM_VERSION'); + if ($useStaticLoader) { + require_once __DIR__ . '/autoload_static.php'; + + call_user_func(\Composer\Autoload\ComposerStaticInitc8ccb46a47efb4379a7eebb3f851e19d::getInitializer($loader)); + } else { + $map = require __DIR__ . '/autoload_namespaces.php'; + foreach ($map as $namespace => $path) { + $loader->set($namespace, $path); + } + + $map = require __DIR__ . '/autoload_psr4.php'; + foreach ($map as $namespace => $path) { + $loader->setPsr4($namespace, $path); + } + + $classMap = require __DIR__ . '/autoload_classmap.php'; + if ($classMap) { + $loader->addClassMap($classMap); + } + } + + $loader->register(true); + + if ($useStaticLoader) { + $includeFiles = Composer\Autoload\ComposerStaticInitc8ccb46a47efb4379a7eebb3f851e19d::$files; + } else { + $includeFiles = require __DIR__ . '/autoload_files.php'; + } + foreach ($includeFiles as $fileIdentifier => $file) { + composerRequirec8ccb46a47efb4379a7eebb3f851e19d($fileIdentifier, $file); + } + + return $loader; + } +} + +function composerRequirec8ccb46a47efb4379a7eebb3f851e19d($fileIdentifier, $file) +{ + if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { + require $file; + + $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/composer/autoload_static.php b/lib/ckfinder/core/connector/php/vendor/composer/autoload_static.php new file mode 100644 index 0000000..9e4a5df --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/composer/autoload_static.php @@ -0,0 +1,267 @@ + __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php', + ); + + public static $prefixLengthsPsr4 = array ( + 'S' => + array ( + 'Symfony\\Polyfill\\Mbstring\\' => 26, + 'Symfony\\Component\\HttpKernel\\' => 29, + 'Symfony\\Component\\HttpFoundation\\' => 33, + 'Symfony\\Component\\EventDispatcher\\' => 34, + 'Symfony\\Component\\Debug\\' => 24, + ), + 'P' => + array ( + 'Psr\\Log\\' => 8, + 'Psr\\Cache\\' => 10, + ), + 'M' => + array ( + 'Monolog\\' => 8, + ), + 'L' => + array ( + 'League\\Flysystem\\Dropbox\\' => 25, + 'League\\Flysystem\\Cached\\' => 24, + 'League\\Flysystem\\Azure\\' => 23, + 'League\\Flysystem\\AwsS3v2\\' => 25, + 'League\\Flysystem\\' => 17, + ), + 'C' => + array ( + 'CKSource\\CKFinder\\Plugin\\' => 25, + ), + ); + + public static $prefixDirsPsr4 = array ( + 'Symfony\\Polyfill\\Mbstring\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring', + ), + 'Symfony\\Component\\HttpKernel\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/http-kernel', + ), + 'Symfony\\Component\\HttpFoundation\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/http-foundation', + ), + 'Symfony\\Component\\EventDispatcher\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/event-dispatcher', + ), + 'Symfony\\Component\\Debug\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/debug', + ), + 'Psr\\Log\\' => + array ( + 0 => __DIR__ . '/..' . '/psr/log/Psr/Log', + ), + 'Psr\\Cache\\' => + array ( + 0 => __DIR__ . '/..' . '/psr/cache/src', + ), + 'Monolog\\' => + array ( + 0 => __DIR__ . '/..' . '/monolog/monolog/src/Monolog', + ), + 'League\\Flysystem\\Dropbox\\' => + array ( + 0 => __DIR__ . '/..' . '/league/flysystem-dropbox/src', + ), + 'League\\Flysystem\\Cached\\' => + array ( + 0 => __DIR__ . '/..' . '/league/flysystem-cached-adapter/src', + ), + 'League\\Flysystem\\Azure\\' => + array ( + 0 => __DIR__ . '/..' . '/league/flysystem-azure/src', + ), + 'League\\Flysystem\\AwsS3v2\\' => + array ( + 0 => __DIR__ . '/..' . '/league/flysystem-aws-s3-v2/src', + ), + 'League\\Flysystem\\' => + array ( + 0 => __DIR__ . '/..' . '/league/flysystem/src', + ), + 'CKSource\\CKFinder\\Plugin\\' => + array ( + 0 => __DIR__ . '/..' . '/cksource/ckfinder/plugins', + ), + ); + + public static $prefixesPsr0 = array ( + 'W' => + array ( + 'WindowsAzure\\' => + array ( + 0 => __DIR__ . '/..' . '/microsoft/windowsazure', + ), + ), + 'P' => + array ( + 'Pimple' => + array ( + 0 => __DIR__ . '/..' . '/pimple/pimple/src', + ), + ), + 'G' => + array ( + 'Guzzle\\Tests' => + array ( + 0 => __DIR__ . '/..' . '/guzzle/guzzle/tests', + ), + 'Guzzle' => + array ( + 0 => __DIR__ . '/..' . '/guzzle/guzzle/src', + ), + ), + 'D' => + array ( + 'Dropbox' => + array ( + 0 => __DIR__ . '/..' . '/dropbox/dropbox-sdk/lib', + ), + ), + 'C' => + array ( + 'CKSource' => + array ( + 0 => __DIR__ . '/..' . '/cksource/ckfinder/src', + ), + ), + 'A' => + array ( + 'Aws' => + array ( + 0 => __DIR__ . '/..' . '/aws/aws-sdk-php/src', + ), + ), + ); + + public static $classMap = array ( + 'Archive_Tar' => __DIR__ . '/..' . '/pear-pear.php.net/Archive_Tar/Archive/Tar.php', + 'Console_Getopt' => __DIR__ . '/..' . '/pear-pear.php.net/Console_Getopt/Console/Getopt.php', + 'HTTP_Request2' => __DIR__ . '/..' . '/pear-pear.php.net/HTTP_Request2/HTTP/Request2.php', + 'HTTP_Request2_Adapter' => __DIR__ . '/..' . '/pear-pear.php.net/HTTP_Request2/HTTP/Request2/Adapter.php', + 'HTTP_Request2_Adapter_Curl' => __DIR__ . '/..' . '/pear-pear.php.net/HTTP_Request2/HTTP/Request2/Adapter/Curl.php', + 'HTTP_Request2_Adapter_Mock' => __DIR__ . '/..' . '/pear-pear.php.net/HTTP_Request2/HTTP/Request2/Adapter/Mock.php', + 'HTTP_Request2_Adapter_Socket' => __DIR__ . '/..' . '/pear-pear.php.net/HTTP_Request2/HTTP/Request2/Adapter/Socket.php', + 'HTTP_Request2_ConnectionException' => __DIR__ . '/..' . '/pear-pear.php.net/HTTP_Request2/HTTP/Request2/Exception.php', + 'HTTP_Request2_CookieJar' => __DIR__ . '/..' . '/pear-pear.php.net/HTTP_Request2/HTTP/Request2/CookieJar.php', + 'HTTP_Request2_Exception' => __DIR__ . '/..' . '/pear-pear.php.net/HTTP_Request2/HTTP/Request2/Exception.php', + 'HTTP_Request2_LogicException' => __DIR__ . '/..' . '/pear-pear.php.net/HTTP_Request2/HTTP/Request2/Exception.php', + 'HTTP_Request2_MessageException' => __DIR__ . '/..' . '/pear-pear.php.net/HTTP_Request2/HTTP/Request2/Exception.php', + 'HTTP_Request2_MultipartBody' => __DIR__ . '/..' . '/pear-pear.php.net/HTTP_Request2/HTTP/Request2/MultipartBody.php', + 'HTTP_Request2_NotImplementedException' => __DIR__ . '/..' . '/pear-pear.php.net/HTTP_Request2/HTTP/Request2/Exception.php', + 'HTTP_Request2_Observer_Log' => __DIR__ . '/..' . '/pear-pear.php.net/HTTP_Request2/HTTP/Request2/Observer/Log.php', + 'HTTP_Request2_Observer_UncompressingDownload' => __DIR__ . '/..' . '/pear-pear.php.net/HTTP_Request2/HTTP/Request2/Observer/UncompressingDownload.php', + 'HTTP_Request2_Response' => __DIR__ . '/..' . '/pear-pear.php.net/HTTP_Request2/HTTP/Request2/Response.php', + 'HTTP_Request2_SOCKS5' => __DIR__ . '/..' . '/pear-pear.php.net/HTTP_Request2/HTTP/Request2/SOCKS5.php', + 'HTTP_Request2_SocketWrapper' => __DIR__ . '/..' . '/pear-pear.php.net/HTTP_Request2/HTTP/Request2/SocketWrapper.php', + 'Mail_mime' => __DIR__ . '/..' . '/pear-pear.php.net/Mail_Mime/Mail/mime.php', + 'Mail_mimeDecode' => __DIR__ . '/..' . '/pear-pear.php.net/Mail_mimeDecode/Mail/mimeDecode.php', + 'Mail_mimePart' => __DIR__ . '/..' . '/pear-pear.php.net/Mail_Mime/Mail/mimePart.php', + 'Net_URL2' => __DIR__ . '/..' . '/pear-pear.php.net/Net_URL2/Net/URL2.php', + 'OS_Guess' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/OS/Guess.php', + 'PEAR' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR.php', + 'PEAR_Autoloader' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Autoloader.php', + 'PEAR_Builder' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Builder.php', + 'PEAR_ChannelFile' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/ChannelFile.php', + 'PEAR_ChannelFile_Parser' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/ChannelFile/Parser.php', + 'PEAR_Command' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Command.php', + 'PEAR_Command_Auth' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Command/Auth.php', + 'PEAR_Command_Build' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Command/Build.php', + 'PEAR_Command_Channels' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Command/Channels.php', + 'PEAR_Command_Common' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Command/Common.php', + 'PEAR_Command_Config' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Command/Config.php', + 'PEAR_Command_Install' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Command/Install.php', + 'PEAR_Command_Mirror' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Command/Mirror.php', + 'PEAR_Command_Package' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Command/Package.php', + 'PEAR_Command_Pickle' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Command/Pickle.php', + 'PEAR_Command_Registry' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Command/Registry.php', + 'PEAR_Command_Remote' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Command/Remote.php', + 'PEAR_Command_Test' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Command/Test.php', + 'PEAR_Common' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Common.php', + 'PEAR_Config' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Config.php', + 'PEAR_Dependency2' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Dependency2.php', + 'PEAR_DependencyDB' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/DependencyDB.php', + 'PEAR_Downloader' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Downloader.php', + 'PEAR_Downloader_Package' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Downloader/Package.php', + 'PEAR_Error' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR.php', + 'PEAR_ErrorStack' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/ErrorStack.php', + 'PEAR_Exception' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Exception.php', + 'PEAR_Frontend' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Frontend.php', + 'PEAR_Frontend_CLI' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Frontend/CLI.php', + 'PEAR_Installer' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Installer.php', + 'PEAR_Installer_Role' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Installer/Role.php', + 'PEAR_Installer_Role_Cfg' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Installer/Role/Cfg.php', + 'PEAR_Installer_Role_Common' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Installer/Role/Common.php', + 'PEAR_Installer_Role_Data' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Installer/Role/Data.php', + 'PEAR_Installer_Role_Doc' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Installer/Role/Doc.php', + 'PEAR_Installer_Role_Ext' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Installer/Role/Ext.php', + 'PEAR_Installer_Role_Man' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Installer/Role/Man.php', + 'PEAR_Installer_Role_Php' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Installer/Role/Php.php', + 'PEAR_Installer_Role_Script' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Installer/Role/Script.php', + 'PEAR_Installer_Role_Src' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Installer/Role/Src.php', + 'PEAR_Installer_Role_Test' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Installer/Role/Test.php', + 'PEAR_Installer_Role_Www' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Installer/Role/Www.php', + 'PEAR_PackageFile' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/PackageFile.php', + 'PEAR_PackageFile_Generator_v1' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/PackageFile/Generator/v1.php', + 'PEAR_PackageFile_Generator_v2' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/PackageFile/Generator/v2.php', + 'PEAR_PackageFile_Parser_v1' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/PackageFile/Parser/v1.php', + 'PEAR_PackageFile_Parser_v2' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/PackageFile/Parser/v2.php', + 'PEAR_PackageFile_v1' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/PackageFile/v1.php', + 'PEAR_PackageFile_v2' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/PackageFile/v2.php', + 'PEAR_PackageFile_v2_Validator' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/PackageFile/v2/Validator.php', + 'PEAR_PackageFile_v2_rw' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/PackageFile/v2/rw.php', + 'PEAR_Packager' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Packager.php', + 'PEAR_REST' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/REST.php', + 'PEAR_REST_10' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/REST/10.php', + 'PEAR_REST_11' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/REST/11.php', + 'PEAR_REST_13' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/REST/13.php', + 'PEAR_Registry' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Registry.php', + 'PEAR_RunTest' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/RunTest.php', + 'PEAR_Task_Common' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Task/Common.php', + 'PEAR_Task_Postinstallscript' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Task/Postinstallscript.php', + 'PEAR_Task_Postinstallscript_rw' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Task/Postinstallscript/rw.php', + 'PEAR_Task_Replace' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Task/Replace.php', + 'PEAR_Task_Replace_rw' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Task/Replace/rw.php', + 'PEAR_Task_Unixeol' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Task/Unixeol.php', + 'PEAR_Task_Unixeol_rw' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Task/Unixeol/rw.php', + 'PEAR_Task_Windowseol' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Task/Windowseol.php', + 'PEAR_Task_Windowseol_rw' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Task/Windowseol/rw.php', + 'PEAR_Validate' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Validate.php', + 'PEAR_Validator_PECL' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Validator/PECL.php', + 'PEAR_XMLParser' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/XMLParser.php', + 'SessionHandlerInterface' => __DIR__ . '/..' . '/symfony/http-foundation/Resources/stubs/SessionHandlerInterface.php', + 'Structures_Graph' => __DIR__ . '/..' . '/pear-pear.php.net/Structures_Graph/Structures/Graph.php', + 'Structures_Graph_Manipulator_AcyclicTest' => __DIR__ . '/..' . '/pear-pear.php.net/Structures_Graph/Structures/Graph/Manipulator/AcyclicTest.php', + 'Structures_Graph_Manipulator_TopologicalSorter' => __DIR__ . '/..' . '/pear-pear.php.net/Structures_Graph/Structures/Graph/Manipulator/TopologicalSorter.php', + 'Structures_Graph_Node' => __DIR__ . '/..' . '/pear-pear.php.net/Structures_Graph/Structures/Graph/Node.php', + 'System' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/System.php', + 'XML_Util' => __DIR__ . '/..' . '/pear-pear.php.net/XML_Util/XML/Util.php', + ); + + public static function getInitializer(ClassLoader $loader) + { + return \Closure::bind(function () use ($loader) { + $loader->prefixLengthsPsr4 = ComposerStaticInitc8ccb46a47efb4379a7eebb3f851e19d::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInitc8ccb46a47efb4379a7eebb3f851e19d::$prefixDirsPsr4; + $loader->prefixesPsr0 = ComposerStaticInitc8ccb46a47efb4379a7eebb3f851e19d::$prefixesPsr0; + $loader->classMap = ComposerStaticInitc8ccb46a47efb4379a7eebb3f851e19d::$classMap; + + }, null, ClassLoader::class); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/composer/include_paths.php b/lib/ckfinder/core/connector/php/vendor/composer/include_paths.php new file mode 100644 index 0000000..17c4657 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/composer/include_paths.php @@ -0,0 +1,18 @@ +=5.0.0.0" + }, + "replace": { + "pear-pear/mail_mime": "== 1.10.0.0" + }, + "type": "pear-library", + "installation-source": "dist", + "autoload": { + "classmap": [ + "" + ] + }, + "include-path": [ + "/" + ], + "license": [ + "BSD Style" + ], + "description": "Mail_Mime provides classes to deal with the creation and manipulation of MIME messages.\nIt allows people to create e-mail messages consisting of:\n* Text Parts\n* HTML Parts\n* Inline HTML Images\n* Attachments\n* Attached messages\n\nIt supports big messages, base64 and quoted-printable encodings and\nnon-ASCII characters in filenames, subjects, recipients, etc. encoded\nusing RFC2047 and/or RFC2231." + }, + { + "name": "pear-pear.php.net/Mail_mimeDecode", + "version": "1.5.6", + "version_normalized": "1.5.6.0", + "dist": { + "type": "file", + "url": "https://pear.php.net/get/Mail_mimeDecode-1.5.6.tgz", + "reference": null, + "shasum": null + }, + "require": { + "pear-pear.php.net/mail_mime": ">1.4.0.0", + "php": ">=4.3.0.0" + }, + "replace": { + "pear-pear/mail_mimedecode": "== 1.5.6.0" + }, + "type": "pear-library", + "installation-source": "dist", + "autoload": { + "classmap": [ + "" + ] + }, + "include-path": [ + "/" + ], + "license": [ + "BSD Style" + ], + "description": "Provides a class to deal with the decoding and interpreting of mime messages.\n This package used to be part of the Mail_Mime package, but has been split off." + }, + { + "name": "pear-pear.php.net/Net_URL2", + "version": "2.2.1", + "version_normalized": "2.2.1.0", + "dist": { + "type": "file", + "url": "https://pear.php.net/get/Net_URL2-2.2.1.tgz", + "reference": null, + "shasum": null + }, + "require": { + "php": ">=5.1.4.0" + }, + "replace": { + "pear-pear/net_url2": "== 2.2.1.0" + }, + "type": "pear-library", + "installation-source": "dist", + "autoload": { + "classmap": [ + "" + ] + }, + "include-path": [ + "/" + ], + "license": [ + "BSD-3-Clause" + ], + "description": "Provides parsing of URLs into their constituent parts (scheme, host, path etc.), URL generation, and resolving of\n relative URLs." + }, + { + "name": "pear-pear.php.net/XML_Util", + "version": "1.3.0", + "version_normalized": "1.3.0.0", + "dist": { + "type": "file", + "url": "https://pear.php.net/get/XML_Util-1.3.0.tgz", + "reference": null, + "shasum": null + }, + "require": { + "ext-pcre": "*", + "php": ">=5.3.0.0" + }, + "replace": { + "pear-pear/xml_util": "== 1.3.0.0" + }, + "type": "pear-library", + "installation-source": "dist", + "autoload": { + "classmap": [ + "" + ] + }, + "include-path": [ + "/" + ], + "license": [ + "BSD License" + ], + "description": "Selection of methods that are often needed when working with XML documents. Functionality includes creating of attribute lists from arrays, creation of tags, validation of XML names and more." + }, + { + "name": "pear-pear.php.net/Console_Getopt", + "version": "1.4.1", + "version_normalized": "1.4.1.0", + "dist": { + "type": "file", + "url": "https://pear.php.net/get/Console_Getopt-1.4.1.tgz", + "reference": null, + "shasum": null + }, + "require": { + "php": ">=5.4.0.0" + }, + "replace": { + "pear-pear/console_getopt": "== 1.4.1.0" + }, + "type": "pear-library", + "installation-source": "dist", + "autoload": { + "classmap": [ + "" + ] + }, + "include-path": [ + "/" + ], + "license": [ + "BSD-2-Clause" + ], + "description": "This is a PHP implementation of \"getopt\" supporting both\nshort and long options." + }, + { + "name": "pear-pear.php.net/Structures_Graph", + "version": "1.1.1", + "version_normalized": "1.1.1.0", + "dist": { + "type": "file", + "url": "https://pear.php.net/get/Structures_Graph-1.1.1.tgz", + "reference": null, + "shasum": null + }, + "require": { + "php": ">=5.3.0.0" + }, + "replace": { + "pear-pear/structures_graph": "== 1.1.1.0" + }, + "type": "pear-library", + "installation-source": "dist", + "autoload": { + "classmap": [ + "" + ] + }, + "include-path": [ + "/" + ], + "license": [ + "LGPL-3.0+" + ], + "description": "Structures_Graph is a package for creating and manipulating graph datastructures. It allows building of directed\nand undirected graphs, with data and metadata stored in nodes. The library provides functions for graph traversing\nas well as for characteristic extraction from the graph topology." + }, + { + "name": "pear-pear.php.net/Archive_Tar", + "version": "1.4.2", + "version_normalized": "1.4.2.0", + "dist": { + "type": "file", + "url": "https://pear.php.net/get/Archive_Tar-1.4.2.tgz", + "reference": null, + "shasum": null + }, + "require": { + "php": ">=5.2.0.0" + }, + "replace": { + "pear-pear/archive_tar": "== 1.4.2.0" + }, + "type": "pear-library", + "installation-source": "dist", + "autoload": { + "classmap": [ + "" + ] + }, + "include-path": [ + "/" + ], + "license": [ + "New BSD License" + ], + "description": "This class provides handling of tar files in PHP.\nIt supports creating, listing, extracting and adding to tar files.\nGzip support is available if PHP has the zlib extension built-in or\nloaded. Bz2 compression is also supported with the bz2 extension loaded." + }, + { + "name": "pear-pear.php.net/PEAR", + "version": "1.10.1", + "version_normalized": "1.10.1.0", + "dist": { + "type": "file", + "url": "https://pear.php.net/get/PEAR-1.10.1.tgz", + "reference": null, + "shasum": null + }, + "require": { + "ext-pcre": "*", + "ext-xml": "*", + "pear-pear.php.net/archive_tar": ">=1.4.0.0", + "pear-pear.php.net/console_getopt": ">=1.4.1.0", + "pear-pear.php.net/structures_graph": ">=1.1.0.0", + "pear-pear.php.net/xml_util": ">=1.3.0.0", + "php": ">=5.4.0.0" + }, + "conflict": { + "pear-pear.php.net/pear_frontend_gtk": "<0.4.0.0", + "pear-pear.php.net/pear_frontend_web": "<=0.4.0.0" + }, + "replace": { + "pear-pear/pear": "== 1.10.1.0" + }, + "type": "pear-library", + "installation-source": "dist", + "autoload": { + "classmap": [ + "" + ] + }, + "include-path": [ + "/" + ], + "license": [ + "New BSD License" + ], + "description": "The PEAR package contains:\n * the PEAR installer, for creating, distributing\n and installing packages\n * the PEAR_Exception PHP5 error handling mechanism\n * the PEAR_ErrorStack advanced error handling mechanism\n * the PEAR_Error error handling mechanism\n * the OS_Guess class for retrieving info about the OS\n where PHP is running on\n * the System class for quick handling of common operations\n with files and directories\n * the PEAR base class\n Features in a nutshell:\n * full support for channels\n * pre-download dependency validation\n * new package.xml 2.0 format allows tremendous flexibility while maintaining BC\n * support for optional dependency groups and limited support for sub-packaging\n * robust dependency support\n * full dependency validation on uninstall\n * remote install for hosts with only ftp access - no more problems with\n restricted host installation\n * full support for mirroring\n * support for bundling several packages into a single tarball\n * support for static dependencies on a url-based package\n * support for custom file roles and installation tasks" + }, + { + "name": "pear-pear.php.net/HTTP_Request2", + "version": "2.3.0", + "version_normalized": "2.3.0.0", + "dist": { + "type": "file", + "url": "https://pear.php.net/get/HTTP_Request2-2.3.0.tgz", + "reference": null, + "shasum": null + }, + "require": { + "pear-pear.php.net/net_url2": ">=2.2.0.0", + "pear-pear.php.net/pear": ">=1.9.2.0", + "php": ">=5.2.0.0" + }, + "replace": { + "pear-pear/http_request2": "== 2.3.0.0" + }, + "type": "pear-library", + "installation-source": "dist", + "autoload": { + "classmap": [ + "" + ] + }, + "include-path": [ + "/" + ], + "license": [ + "BSD 3-Clause License" + ], + "description": "PHP5 rewrite of HTTP_Request package (with parts of HTTP_Client). Provides\ncleaner API and pluggable Adapters:\n * Socket adapter, based on old HTTP_Request code,\n * Curl adapter, wraps around PHP's cURL extension,\n * Mock adapter, to use for testing packages dependent on HTTP_Request2.\nSupports POST requests with data and file uploads, basic and digest\nauthentication, cookies, managing cookies across requests, proxies, gzip and\ndeflate encodings, redirects, monitoring the request progress with Observers..." + }, + { + "name": "microsoft/windowsazure", + "version": "v0.4.0", + "version_normalized": "0.4.0.0", + "source": { + "type": "git", + "url": "https://github.com/Azure/azure-sdk-for-php.git", + "reference": "61d4e12495358491f62cc5bd8716335b0b313488" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Azure/azure-sdk-for-php/zipball/61d4e12495358491f62cc5bd8716335b0b313488", + "reference": "61d4e12495358491f62cc5bd8716335b0b313488", + "shasum": "" + }, + "require": { + "pear-pear/http_request2": "*", + "pear-pear/mail_mime": "*", + "pear-pear/mail_mimedecode": "*" + }, + "time": "2014-01-23 05:45:10", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-0": { + "WindowsAzure\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Azure PHP SDK", + "email": "azurephpsdk@microsoft.com" + } + ], + "description": "This project provides a set of PHP client libraries that make it easy to access Windows Azure tables, blobs, queues, service runtime and service management APIs.", + "keywords": [ + "azure", + "php", + "sdk" + ] + }, + { + "name": "league/flysystem", + "version": "1.0.27", + "version_normalized": "1.0.27.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/flysystem.git", + "reference": "50e2045ed70a7e75a5e30bc3662904f3b67af8a9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/50e2045ed70a7e75a5e30bc3662904f3b67af8a9", + "reference": "50e2045ed70a7e75a5e30bc3662904f3b67af8a9", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "conflict": { + "league/flysystem-sftp": "<1.0.6" + }, + "require-dev": { + "ext-fileinfo": "*", + "mockery/mockery": "~0.9", + "phpspec/phpspec": "^2.2", + "phpunit/phpunit": "~4.8" + }, + "suggest": { + "ext-fileinfo": "Required for MimeType", + "league/flysystem-aws-s3-v2": "Allows you to use S3 storage with AWS SDK v2", + "league/flysystem-aws-s3-v3": "Allows you to use S3 storage with AWS SDK v3", + "league/flysystem-azure": "Allows you to use Windows Azure Blob storage", + "league/flysystem-cached-adapter": "Flysystem adapter decorator for metadata caching", + "league/flysystem-copy": "Allows you to use Copy.com storage", + "league/flysystem-dropbox": "Allows you to use Dropbox storage", + "league/flysystem-eventable-filesystem": "Allows you to use EventableFilesystem", + "league/flysystem-rackspace": "Allows you to use Rackspace Cloud Files", + "league/flysystem-sftp": "Allows you to use SFTP server storage via phpseclib", + "league/flysystem-webdav": "Allows you to use WebDAV storage", + "league/flysystem-ziparchive": "Allows you to use ZipArchive adapter" + }, + "time": "2016-08-10 08:55:11", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "League\\Flysystem\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frenky.net" + } + ], + "description": "Filesystem abstraction: Many filesystems, one API.", + "keywords": [ + "Cloud Files", + "WebDAV", + "abstraction", + "aws", + "cloud", + "copy.com", + "dropbox", + "file systems", + "files", + "filesystem", + "filesystems", + "ftp", + "rackspace", + "remote", + "s3", + "sftp", + "storage" + ] + }, + { + "name": "league/flysystem-azure", + "version": "dev-master", + "version_normalized": "9999999-dev", + "source": { + "type": "git", + "url": "https://github.com/zaak/flysystem-azure", + "reference": "d6556e9aea541e50577ae0f48164e482622ff099" + }, + "require": { + "league/flysystem": "~1.0", + "microsoft/windowsazure": "~0.4.0", + "pear-pear.php.net/http_request2": "*", + "pear-pear.php.net/mail_mime": "*", + "pear-pear.php.net/mail_mimedecode": "*", + "php": ">=5.4.0" + }, + "require-dev": { + "mockery/mockery": "~0.9", + "phpunit/phpunit": "~4.0" + }, + "time": "2016-01-22 10:39:07", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "installation-source": "source", + "autoload": { + "psr-4": { + "League\\Flysystem\\Azure\\": "src/" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frenky.net" + } + ], + "description": "Flysystem adapter for Windows Azure" + }, + { + "name": "psr/cache", + "version": "1.0.0", + "version_normalized": "1.0.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "9e66031f41fbbdda45ee11e93c45d480ccba3eb3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/cache/zipball/9e66031f41fbbdda45ee11e93c45d480ccba3eb3", + "reference": "9e66031f41fbbdda45ee11e93c45d480ccba3eb3", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "time": "2015-12-11 02:52:07", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for caching libraries", + "keywords": [ + "cache", + "psr", + "psr-6" + ] + }, + { + "name": "league/flysystem-cached-adapter", + "version": "1.0.3", + "version_normalized": "1.0.3.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/flysystem-cached-adapter.git", + "reference": "f006cb3c355ae596c72ba8ca4cf3aa4bb545bc0c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/flysystem-cached-adapter/zipball/f006cb3c355ae596c72ba8ca4cf3aa4bb545bc0c", + "reference": "f006cb3c355ae596c72ba8ca4cf3aa4bb545bc0c", + "shasum": "" + }, + "require": { + "league/flysystem": "~1.0", + "psr/cache": "1.0.0" + }, + "require-dev": { + "henrikbjorn/phpspec-code-coverage": "~1.0@dev", + "mockery/mockery": "~0.9", + "phpspec/phpspec": "~2.1", + "phpunit/phpunit": "~4.1", + "predis/predis": "~1.0", + "tedivm/stash": "~0.12" + }, + "suggest": { + "ext-phpredis": "Pure C implemented extension for PHP" + }, + "time": "2016-01-25 08:21:11", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "League\\Flysystem\\Cached\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "frankdejonge", + "email": "info@frenky.net" + } + ], + "description": "An adapter decorator to enable meta-data caching." + }, + { + "name": "symfony/event-dispatcher", + "version": "2.7.x-dev", + "version_normalized": "2.7.9999999.9999999-dev", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "2b096845cbe49f4616dc90494e1a68d48e9bba23" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/2b096845cbe49f4616dc90494e1a68d48e9bba23", + "reference": "2b096845cbe49f4616dc90494e1a68d48e9bba23", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~2.0,>=2.0.5", + "symfony/dependency-injection": "~2.6", + "symfony/expression-language": "~2.6", + "symfony/stopwatch": "~2.3" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "time": "2016-08-09 09:00:18", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "installation-source": "source", + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony EventDispatcher Component", + "homepage": "https://symfony.com" + }, + { + "name": "guzzle/guzzle", + "version": "dev-master", + "version_normalized": "9999999-dev", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle3.git", + "reference": "b3f5050cb6270c7a728a0b74ac2de50a262b3e02" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle3/zipball/b3f5050cb6270c7a728a0b74ac2de50a262b3e02", + "reference": "b3f5050cb6270c7a728a0b74ac2de50a262b3e02", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "php": ">=5.3.3", + "symfony/event-dispatcher": "~2.1" + }, + "replace": { + "guzzle/batch": "self.version", + "guzzle/cache": "self.version", + "guzzle/common": "self.version", + "guzzle/http": "self.version", + "guzzle/inflection": "self.version", + "guzzle/iterator": "self.version", + "guzzle/log": "self.version", + "guzzle/parser": "self.version", + "guzzle/plugin": "self.version", + "guzzle/plugin-async": "self.version", + "guzzle/plugin-backoff": "self.version", + "guzzle/plugin-cache": "self.version", + "guzzle/plugin-cookie": "self.version", + "guzzle/plugin-curlauth": "self.version", + "guzzle/plugin-error-response": "self.version", + "guzzle/plugin-history": "self.version", + "guzzle/plugin-log": "self.version", + "guzzle/plugin-md5": "self.version", + "guzzle/plugin-mock": "self.version", + "guzzle/plugin-oauth": "self.version", + "guzzle/service": "self.version", + "guzzle/stream": "self.version" + }, + "require-dev": { + "doctrine/cache": "~1.3", + "monolog/monolog": "~1.0", + "phpunit/phpunit": "3.7.*", + "psr/log": "~1.0", + "symfony/class-loader": "~2.1", + "zendframework/zend-cache": "2.*,<2.3", + "zendframework/zend-log": "2.*,<2.3" + }, + "suggest": { + "guzzlehttp/guzzle": "Guzzle 5 has moved to a new package name. The package you have installed, Guzzle 3, is deprecated." + }, + "time": "2015-04-29 17:06:53", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.9-dev" + } + }, + "installation-source": "source", + "autoload": { + "psr-0": { + "Guzzle": "src/", + "Guzzle\\Tests": "tests/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Guzzle Community", + "homepage": "https://github.com/guzzle/guzzle/contributors" + } + ], + "description": "PHP HTTP client. This library is deprecated in favor of https://packagist.org/packages/guzzlehttp/guzzle", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" + ], + "abandoned": "guzzlehttp/guzzle" + }, + { + "name": "aws/aws-sdk-php", + "version": "2.8.31", + "version_normalized": "2.8.31.0", + "source": { + "type": "git", + "url": "https://github.com/aws/aws-sdk-php.git", + "reference": "64fa4b07f056e338a5f0f29eece75babaa83af68" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/64fa4b07f056e338a5f0f29eece75babaa83af68", + "reference": "64fa4b07f056e338a5f0f29eece75babaa83af68", + "shasum": "" + }, + "require": { + "guzzle/guzzle": "~3.7", + "php": ">=5.3.3" + }, + "require-dev": { + "doctrine/cache": "~1.0", + "ext-openssl": "*", + "monolog/monolog": "~1.4", + "phpunit/phpunit": "~4.0", + "phpunit/phpunit-mock-objects": "2.3.1", + "symfony/yaml": "~2.1" + }, + "suggest": { + "doctrine/cache": "Adds support for caching of credentials and responses", + "ext-apc": "Allows service description opcode caching, request and response caching, and credentials caching", + "ext-openssl": "Allows working with CloudFront private distributions and verifying received SNS messages", + "monolog/monolog": "Adds support for logging HTTP requests and responses", + "symfony/yaml": "Eases the ability to write manifests for creating jobs in AWS Import/Export" + }, + "time": "2016-07-25 18:03:20", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-0": { + "Aws": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Amazon Web Services", + "homepage": "http://aws.amazon.com" + } + ], + "description": "AWS SDK for PHP - Use Amazon Web Services in your PHP project", + "homepage": "http://aws.amazon.com/sdkforphp", + "keywords": [ + "amazon", + "aws", + "cloud", + "dynamodb", + "ec2", + "glacier", + "s3", + "sdk" + ] + }, + { + "name": "league/flysystem-aws-s3-v2", + "version": "1.0.3", + "version_normalized": "1.0.3.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/flysystem-aws-s3-v2.git", + "reference": "e464a35e34abed572c76b76aa2f278d178e141c6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/flysystem-aws-s3-v2/zipball/e464a35e34abed572c76b76aa2f278d178e141c6", + "reference": "e464a35e34abed572c76b76aa2f278d178e141c6", + "shasum": "" + }, + "require": { + "aws/aws-sdk-php": "~2.7", + "league/flysystem": "~1.0", + "php": ">=5.4.0" + }, + "require-dev": { + "mockery/mockery": "0.9.*", + "phpunit/phpunit": "~4.0" + }, + "time": "2015-10-15 15:55:48", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "League\\Flysystem\\AwsS3v2\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frenky.net" + } + ], + "description": "Flysystem adapter for AWS S3 SDK v2" + }, + { + "name": "dropbox/dropbox-sdk", + "version": "v1.1.7", + "version_normalized": "1.1.7.0", + "source": { + "type": "git", + "url": "https://github.com/dropbox/dropbox-sdk-php.git", + "reference": "0f1a178ca9c0271bca6426dde8f5a2241578deae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dropbox/dropbox-sdk-php/zipball/0f1a178ca9c0271bca6426dde8f5a2241578deae", + "reference": "0f1a178ca9c0271bca6426dde8f5a2241578deae", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "php": ">= 5.3" + }, + "require-dev": { + "apigen/apigen": "4.1.2", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "2.0.0RC3" + }, + "time": "2016-08-08 23:48:49", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-0": { + "Dropbox": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Dropbox SDK for PHP", + "keywords": [ + "dropbox" + ] + }, + { + "name": "league/flysystem-dropbox", + "version": "1.0.0", + "version_normalized": "1.0.0.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/flysystem-dropbox.git", + "reference": "96c37124590bef6277c0e68a12e2dc40e5f82baa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/flysystem-dropbox/zipball/96c37124590bef6277c0e68a12e2dc40e5f82baa", + "reference": "96c37124590bef6277c0e68a12e2dc40e5f82baa", + "shasum": "" + }, + "require": { + "dropbox/dropbox-sdk": "~1.1", + "league/flysystem": "~1.0", + "php": ">=5.4.0" + }, + "require-dev": { + "mockery/mockery": "0.9.*", + "phpunit/phpunit": "~4.0" + }, + "time": "2015-05-30 09:18:29", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "League\\Flysystem\\Dropbox\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frenky.net" + } + ], + "description": "Flysystem adapter for Dropbox" + }, + { + "name": "psr/log", + "version": "dev-master", + "version_normalized": "9999999-dev", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "5277094ed527a1c4477177d102fe4c53551953e0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/5277094ed527a1c4477177d102fe4c53551953e0", + "reference": "5277094ed527a1c4477177d102fe4c53551953e0", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "time": "2016-09-19 16:02:08", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "source", + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ] + }, + { + "name": "pimple/pimple", + "version": "dev-master", + "version_normalized": "9999999-dev", + "source": { + "type": "git", + "url": "https://github.com/silexphp/Pimple.git", + "reference": "44515c40a4c4effc53c1e6c0e7158f711473dc98" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/silexphp/Pimple/zipball/44515c40a4c4effc53c1e6c0e7158f711473dc98", + "reference": "44515c40a4c4effc53c1e6c0e7158f711473dc98", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "time": "2016-09-10 19:36:25", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "installation-source": "source", + "autoload": { + "psr-0": { + "Pimple": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Pimple, a simple Dependency Injection Container", + "homepage": "http://pimple.sensiolabs.org", + "keywords": [ + "container", + "dependency injection" + ] + }, + { + "name": "symfony/polyfill-mbstring", + "version": "dev-master", + "version_normalized": "9999999-dev", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "53ad9faffe141fbe8f98cd6a7fd9a5e84513f56c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/53ad9faffe141fbe8f98cd6a7fd9a5e84513f56c", + "reference": "53ad9faffe141fbe8f98cd6a7fd9a5e84513f56c", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "time": "2016-08-30 17:06:17", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "installation-source": "source", + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ] + }, + { + "name": "symfony/http-foundation", + "version": "2.7.x-dev", + "version_normalized": "2.7.9999999.9999999-dev", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-foundation.git", + "reference": "4b590c1e6f8045befac815b41a924b9b815f97bd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/4b590c1e6f8045befac815b41a924b9b815f97bd", + "reference": "4b590c1e6f8045befac815b41a924b9b815f97bd", + "shasum": "" + }, + "require": { + "php": ">=5.3.9", + "symfony/polyfill-mbstring": "~1.1" + }, + "require-dev": { + "symfony/expression-language": "~2.4" + }, + "time": "2016-09-06 09:29:51", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "installation-source": "source", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpFoundation\\": "" + }, + "classmap": [ + "Resources/stubs" + ], + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony HttpFoundation Component", + "homepage": "https://symfony.com" + }, + { + "name": "symfony/debug", + "version": "2.8.x-dev", + "version_normalized": "2.8.9999999.9999999-dev", + "source": { + "type": "git", + "url": "https://github.com/symfony/debug.git", + "reference": "8c29235936a47473af16fb91c7c4b7b193c5693c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/debug/zipball/8c29235936a47473af16fb91c7c4b7b193c5693c", + "reference": "8c29235936a47473af16fb91c7c4b7b193c5693c", + "shasum": "" + }, + "require": { + "php": ">=5.3.9", + "psr/log": "~1.0" + }, + "conflict": { + "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2" + }, + "require-dev": { + "symfony/class-loader": "~2.2|~3.0.0", + "symfony/http-kernel": "~2.3.24|~2.5.9|~2.6,>=2.6.2|~3.0.0" + }, + "time": "2016-09-06 10:55:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev" + } + }, + "installation-source": "source", + "autoload": { + "psr-4": { + "Symfony\\Component\\Debug\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Debug Component", + "homepage": "https://symfony.com" + }, + { + "name": "cksource/ckfinder", + "version": "dev-master", + "version_normalized": "9999999-dev", + "source": { + "type": "git", + "url": "git@github.com:cksource/ckfinder-connector-php.git", + "reference": "e0172e81317218a4649eb50814c4bb10c5706619" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/cksource/ckfinder-connector-php/zipball/e0172e81317218a4649eb50814c4bb10c5706619", + "reference": "e0172e81317218a4649eb50814c4bb10c5706619", + "shasum": "" + }, + "require": { + "aws/aws-sdk-php": "2.8.31", + "dropbox/dropbox-sdk": "~1.1.1", + "league/flysystem": "1.0.27", + "league/flysystem-aws-s3-v2": "1.0.3", + "league/flysystem-azure": "dev-master", + "league/flysystem-cached-adapter": "1.0.3", + "league/flysystem-dropbox": "1.0.0", + "microsoft/windowsazure": "0.4.0", + "monolog/monolog": "~1.4,>=1.4.1", + "pear-pear.php.net/http_request2": "*", + "pear-pear.php.net/mail_mime": "*", + "pear-pear.php.net/mail_mimedecode": "*", + "php": ">=5.4.0", + "pimple/pimple": "~3.0", + "symfony/event-dispatcher": ">=2.4,<=2.8-dev", + "symfony/http-foundation": ">=2.4,<=2.8-dev", + "symfony/http-kernel": ">=2.4,<=2.8-dev" + }, + "require-dev": { + "mikey179/vfsstream": "~1.4", + "phpunit/phpunit": "~4.0" + }, + "time": "2016-09-07 12:03:36", + "type": "library", + "installation-source": "source", + "autoload": { + "psr-0": { + "CKSource": "src/" + }, + "psr-4": { + "CKSource\\CKFinder\\Plugin\\": "plugins/" + } + }, + "scripts": { + "fix-code-style": [ + "php-cs-fixer fix" + ], + "build-doc": [ + "sh dev/doc/builddoc.sh" + ], + "update-locales": [ + "git subtree pull --prefix src/CKSource/CKFinder/locales translations master --squash" + ] + }, + "license": [ + "proprietary" + ], + "authors": [ + { + "name": "CKSource", + "homepage": "http://cksource.com" + } + ], + "description": "CKFinder PHP 5.3+ connector", + "support": { + "source": "https://github.com/cksource/ckfinder-connector-php/tree/master", + "issues": "https://github.com/cksource/ckfinder-connector-php/issues" + } + }, + { + "name": "monolog/monolog", + "version": "1.x-dev", + "version_normalized": "1.9999999.9999999.9999999-dev", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/monolog.git", + "reference": "dacec2fe1ead778f90d0149caa8f047a0856571b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/dacec2fe1ead778f90d0149caa8f047a0856571b", + "reference": "dacec2fe1ead778f90d0149caa8f047a0856571b", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "psr/log": "~1.0" + }, + "provide": { + "psr/log-implementation": "1.0.0" + }, + "require-dev": { + "aws/aws-sdk-php": "^2.4.9", + "doctrine/couchdb": "~1.0@dev", + "graylog2/gelf-php": "~1.0", + "jakub-onderka/php-parallel-lint": "0.9", + "php-amqplib/php-amqplib": "~2.4", + "php-console/php-console": "^3.1.3", + "phpunit/phpunit": "~4.5", + "phpunit/phpunit-mock-objects": "2.3.0", + "ruflin/elastica": ">=0.90 <3.0", + "sentry/sentry": "^0.13", + "swiftmailer/swiftmailer": "~5.3" + }, + "suggest": { + "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", + "doctrine/couchdb": "Allow sending log messages to a CouchDB server", + "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", + "ext-mongo": "Allow sending log messages to a MongoDB server", + "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", + "mongodb/mongodb": "Allow sending log messages to a MongoDB server via PHP Driver", + "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", + "php-console/php-console": "Allow sending log messages to Google Chrome", + "rollbar/rollbar": "Allow sending log messages to Rollbar", + "ruflin/elastica": "Allow sending log messages to an Elastic Search server", + "sentry/sentry": "Allow sending log messages to a Sentry server" + }, + "time": "2016-09-18 16:07:11", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "installation-source": "source", + "autoload": { + "psr-4": { + "Monolog\\": "src/Monolog" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Sends your logs to files, sockets, inboxes, databases and various web services", + "homepage": "http://github.com/Seldaek/monolog", + "keywords": [ + "log", + "logging", + "psr-3" + ] + }, + { + "name": "symfony/http-kernel", + "version": "2.7.x-dev", + "version_normalized": "2.7.9999999.9999999-dev", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-kernel.git", + "reference": "0f99ec91247e20f7b1a6d31dc80e70289bc2b17a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/0f99ec91247e20f7b1a6d31dc80e70289bc2b17a", + "reference": "0f99ec91247e20f7b1a6d31dc80e70289bc2b17a", + "shasum": "" + }, + "require": { + "php": ">=5.3.9", + "psr/log": "~1.0", + "symfony/debug": "~2.6,>=2.6.2", + "symfony/event-dispatcher": "~2.6,>=2.6.7", + "symfony/http-foundation": "~2.7.15|~2.8.8" + }, + "conflict": { + "symfony/config": "<2.7" + }, + "require-dev": { + "symfony/browser-kit": "~2.3", + "symfony/class-loader": "~2.1", + "symfony/config": "~2.7", + "symfony/console": "~2.3", + "symfony/css-selector": "~2.0,>=2.0.5", + "symfony/dependency-injection": "~2.2", + "symfony/dom-crawler": "~2.0,>=2.0.5", + "symfony/expression-language": "~2.4", + "symfony/finder": "~2.0,>=2.0.5", + "symfony/process": "~2.0,>=2.0.5", + "symfony/routing": "~2.2", + "symfony/stopwatch": "~2.3", + "symfony/templating": "~2.2", + "symfony/translation": "~2.0,>=2.0.5", + "symfony/var-dumper": "~2.6" + }, + "suggest": { + "symfony/browser-kit": "", + "symfony/class-loader": "", + "symfony/config": "", + "symfony/console": "", + "symfony/dependency-injection": "", + "symfony/finder": "", + "symfony/var-dumper": "" + }, + "time": "2016-09-14 19:08:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "installation-source": "source", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpKernel\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony HttpKernel Component", + "homepage": "https://symfony.com" + } +] diff --git a/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/AppInfo.php b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/AppInfo.php new file mode 100644 index 0000000..ba91bfe --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/AppInfo.php @@ -0,0 +1,228 @@ +app key (OAuth calls this the consumer key). You can + * create an app key and secret on the Dropbox developer website. + * + * @return string + */ + function getKey() { return $this->key; } + + /** @var string */ + private $key; + + /** + * Your Dropbox app secret (OAuth calls this the consumer secret). You can + * create an app key and secret on the Dropbox developer website. + * + * Make sure that this is kept a secret. Someone with your app secret can impesonate your + * application. People sometimes ask for help on the Dropbox API forums and + * copy/paste code that includes their app secret. Do not do that. + * + * @return string + */ + function getSecret() { return $this->secret; } + + /** @var string */ + private $secret; + + /** + * The set of servers your app will use. This defaults to the standard Dropbox servers + * {@link Host::getDefault}. + * + * @return Host + * + * @internal + */ + function getHost() { return $this->host; } + + /** @var Host */ + private $host; + + /** + * Constructor. + * + * @param string $key + * See {@link getKey()} + * @param string $secret + * See {@link getSecret()} + */ + function __construct($key, $secret) + { + self::checkKeyArg($key); + self::checkSecretArg($secret); + + $this->key = $key; + $this->secret = $secret; + + // The $host parameter is sort of internal. We don't include it in the param list because + // we don't want it to be included in the documentation. Use PHP arg list hacks to get at + // it. + $host = null; + if (\func_num_args() == 3) { + $host = \func_get_arg(2); + Host::checkArgOrNull("host", $host); + } + if ($host === null) { + $host = Host::getDefault(); + } + $this->host = $host; + } + + /** + * Loads a JSON file containing information about your app. At a minimum, the file must include + * the "key" and "secret" fields. Run 'php authorize.php' in the examples directory + * for details about what this file should look like. + * + * @param string $path + * Path to a JSON file + * + * @return AppInfo + * + * @throws AppInfoLoadException + */ + static function loadFromJsonFile($path) + { + list($rawJson, $appInfo) = self::loadFromJsonFileWithRaw($path); + return $appInfo; + } + + /** + * Loads a JSON file containing information about your app. At a minimum, the file must include + * the "key" and "secret" fields. Run 'php authorize.php' in the examples directory + * for details about what this file should look like. + * + * @param string $path + * Path to a JSON file + * + * @return array + * A list of two items. The first is a PHP array representation of the raw JSON, the second + * is an AppInfo object that is the parsed version of the JSON. + * + * @throws AppInfoLoadException + * + * @internal + */ + static function loadFromJsonFileWithRaw($path) + { + if (!file_exists($path)) { + throw new AppInfoLoadException("File doesn't exist: \"$path\""); + } + + $str = Util::stripUtf8Bom(file_get_contents($path)); + $jsonArr = json_decode($str, true, 10); + + if (is_null($jsonArr)) { + throw new AppInfoLoadException("JSON parse error: \"$path\""); + } + + $appInfo = self::loadFromJson($jsonArr); + + return array($jsonArr, $appInfo); + } + + /** + * Parses a JSON object to build an AppInfo object. If you would like to load this from a file, + * use the loadFromJsonFile() method. + * + * @param array $jsonArr Output from json_decode($str, true) + * + * @return AppInfo + * + * @throws AppInfoLoadException + */ + static function loadFromJson($jsonArr) + { + if (!is_array($jsonArr)) { + throw new AppInfoLoadException("Expecting JSON object, got something else"); + } + + $requiredKeys = array("key", "secret"); + foreach ($requiredKeys as $key) { + if (!array_key_exists($key, $jsonArr)) { + throw new AppInfoLoadException("Missing field \"$key\""); + } + + if (!is_string($jsonArr[$key])) { + throw new AppInfoLoadException("Expecting field \"$key\" to be a string"); + } + } + + // Check app_key and app_secret + $appKey = $jsonArr["key"]; + $appSecret = $jsonArr["secret"]; + + $tokenErr = self::getTokenPartError($appKey); + if (!is_null($tokenErr)) { + throw new AppInfoLoadException("Field \"key\" doesn't look like a valid app key: $tokenErr"); + } + + $tokenErr = self::getTokenPartError($appSecret); + if (!is_null($tokenErr)) { + throw new AppInfoLoadException("Field \"secret\" doesn't look like a valid app secret: $tokenErr"); + } + + try { + $host = Host::loadFromJson($jsonArr); + } + catch (HostLoadException $ex) { + throw new AppInfoLoadException($ex->getMessage()); + } + + return new AppInfo($appKey, $appSecret, $host); + } + + /** + * Use this to check that a function argument is of type `AppInfo` + * + * @internal + */ + static function checkArg($argName, $argValue) + { + if (!($argValue instanceof self)) Checker::throwError($argName, $argValue, __CLASS__); + } + + /** + * Use this to check that a function argument is either `null` or of type + * `AppInfo`. + * + * @internal + */ + static function checkArgOrNull($argName, $argValue) + { + if ($argValue === null) return; + if (!($argValue instanceof self)) Checker::throwError($argName, $argValue, __CLASS__); + } + + /** @internal */ + static function getTokenPartError($s) + { + if ($s === null) return "can't be null"; + if (strlen($s) === 0) return "can't be empty"; + if (strstr($s, ' ')) return "can't contain a space"; + return null; // 'null' means "no error" + } + + /** @internal */ + static function checkKeyArg($key) + { + $error = self::getTokenPartError($key); + if ($error === null) return; + throw new \InvalidArgumentException("Bad 'key': \"$key\": $error."); + } + + /** @internal */ + static function checkSecretArg($secret) + { + $error = self::getTokenPartError($secret); + if ($error === null) return; + throw new \InvalidArgumentException("Bad 'secret': \"$secret\": $error."); + } + +} diff --git a/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/AppInfoLoadException.php b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/AppInfoLoadException.php new file mode 100644 index 0000000..730a1e0 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/AppInfoLoadException.php @@ -0,0 +1,18 @@ +array = &$array; + $this->key = $key; + } + + /** + * Returns the entry's current value or `null` if nothing is set. + * + * @return object + */ + function get() + { + if (isset($this->array[$this->key])) { + return $this->array[$this->key]; + } else { + return null; + } + } + + /** + * Set the array entry to the given value. + * + * @param object $value + */ + function set($value) + { + $this->array[$this->key] = $value; + } + + /** + * Clear the entry. + */ + function clear() + { + unset($this->array[$this->key]); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/AuthBase.php b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/AuthBase.php new file mode 100644 index 0000000..2422388 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/AuthBase.php @@ -0,0 +1,75 @@ +appInfo; } + + /** @var AppInfo */ + protected $appInfo; + + /** + * An identifier for the API client, typically of the form "Name/Version". + * This is used to set the HTTP `User-Agent` header when making API requests. + * Example: `"PhotoEditServer/1.3"` + * + * If you're the author a higher-level library on top of the basic SDK, and the + * "Photo Edit" app's server code is using your library to access Dropbox, you should append + * your library's name and version to form the full identifier. For example, + * if your library is called "File Picker", you might set this field to: + * `"PhotoEditServer/1.3 FilePicker/0.1-beta"` + * + * The exact format of the `User-Agent` header is described in + * section 3.8 of the HTTP specification. + * + * Note that underlying HTTP client may append other things to the `User-Agent`, such as + * the name of the library being used to actually make the HTTP request (such as cURL). + * + * @return string + */ + function getClientIdentifier() { return $this->clientIdentifier; } + + /** @var string */ + protected $clientIdentifier; + + /** + * The locale of the user of your application. Some API calls return localized + * data and error messages; this "user locale" setting determines which locale + * the server should use to localize those strings. + * + * @return null|string + */ + function getUserLocale() { return $this->userLocale; } + + /** @var string */ + protected $userLocale; + + /** + * Constructor. + * + * @param AppInfo $appInfo + * See {@link getAppInfo()} + * @param string $clientIdentifier + * See {@link getClientIdentifier()} + * @param null|string $userLocale + * See {@link getUserLocale()} + */ + function __construct($appInfo, $clientIdentifier, $userLocale = null) + { + AppInfo::checkArg("appInfo", $appInfo); + Client::checkClientIdentifierArg("clientIdentifier", $clientIdentifier); + Checker::argStringNonEmptyOrNull("userLocale", $userLocale); + + $this->appInfo = $appInfo; + $this->clientIdentifier = $clientIdentifier; + $this->userLocale = $userLocale; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/AuthInfo.php b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/AuthInfo.php new file mode 100644 index 0000000..d020471 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/AuthInfo.php @@ -0,0 +1,75 @@ +getMessage()); + } + + return array($accessToken, $host); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/AuthInfoLoadException.php b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/AuthInfoLoadException.php new file mode 100644 index 0000000..820cda0 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/AuthInfoLoadException.php @@ -0,0 +1,18 @@ +accessToken; } + + /** @var AccessToken */ + private $accessToken; + + /** + * An identifier for the API client, typically of the form "Name/Version". + * This is used to set the HTTP `User-Agent` header when making API requests. + * Example: `"PhotoEditServer/1.3"` + * + * If you're the author a higher-level library on top of the basic SDK, and the + * "Photo Edit" app's server code is using your library to access Dropbox, you should append + * your library's name and version to form the full identifier. For example, + * if your library is called "File Picker", you might set this field to: + * `"PhotoEditServer/1.3 FilePicker/0.1-beta"` + * + * The exact format of the `User-Agent` header is described in + * section 3.8 of the HTTP specification. + * + * Note that underlying HTTP client may append other things to the `User-Agent`, such as + * the name of the library being used to actually make the HTTP request (such as cURL). + * + * @return string + */ + function getClientIdentifier() { return $this->clientIdentifier; } + + /** @var string */ + private $clientIdentifier; + + /** + * The locale of the user of your application. Some API calls return localized + * data and error messages; this "user locale" setting determines which locale + * the server should use to localize those strings. + * + * @return null|string + */ + function getUserLocale() { return $this->userLocale; } + + /** @var null|string */ + private $userLocale; + + /** + * The {@link Host} object that determines the hostnames we make requests to. + * + * @return Host + */ + function getHost() { return $this->host; } + + /** + * Constructor. + * + * @param string $accessToken + * See {@link getAccessToken()} + * @param string $clientIdentifier + * See {@link getClientIdentifier()} + * @param null|string $userLocale + * See {@link getUserLocale()} + */ + function __construct($accessToken, $clientIdentifier, $userLocale = null) + { + self::checkAccessTokenArg("accessToken", $accessToken); + self::checkClientIdentifierArg("clientIdentifier", $clientIdentifier); + Checker::argStringNonEmptyOrNull("userLocale", $userLocale); + + $this->accessToken = $accessToken; + $this->clientIdentifier = $clientIdentifier; + $this->userLocale = $userLocale; + + // The $host parameter is sort of internal. We don't include it in the param list because + // we don't want it to be included in the documentation. Use PHP arg list hacks to get at + // it. + $host = null; + if (\func_num_args() == 4) { + $host = \func_get_arg(3); + Host::checkArgOrNull("host", $host); + } + if ($host === null) { + $host = Host::getDefault(); + } + $this->host = $host; + + // These fields are redundant, but it makes these values a little more convenient + // to access. + $this->apiHost = $host->getApi(); + $this->contentHost = $host->getContent(); + } + + /** @var string */ + private $apiHost; + /** @var string */ + private $contentHost; + + /** + * Given a `$base` path for an API endpoint (for example, "/files"), append + * a Dropbox API file path to the end of that URL. Special characters in the file will + * be encoded properly. + * + * This is for endpoints like "/files" takes the path on the URL and not as a separate + * query or POST parameter. + * + * @param string $base + * @param string $path + * @return string + */ + function appendFilePath($base, $path) + { + return $base . "/auto/" . rawurlencode(substr($path, 1)); + } + + /** + * Make an API call to disable the access token that you constructed this `Client` + * with. After calling this, API calls made with this `Client` will fail. + * + * See /disable_access_token. + * + * @throws Exception + */ + function disableAccessToken() + { + $response = $this->doPost($this->apiHost, "1/disable_access_token"); + if ($response->statusCode !== 200) throw RequestUtil::unexpectedStatus($response); + } + + /** + * Make an API call to get basic account and quota information. + * + * + * $client = ... + * $accountInfo = $client->getAccountInfo(); + * print_r($accountInfo); + * + * + * @return array + * See /account/info. + * + * @throws Exception + */ + function getAccountInfo() + { + $response = $this->doGet($this->apiHost, "1/account/info"); + if ($response->statusCode !== 200) throw RequestUtil::unexpectedStatus($response); + return RequestUtil::parseResponseJson($response->body); + } + + /** + * Downloads a file from Dropbox. The file's contents are written to the + * given `$outStream` and the file's metadata is returned. + * + * + * $client = ...; + * $fd = fopen("./Frog.jpeg", "wb"); + * $metadata = $client->getFile("/Photos/Frog.jpeg", $fd); + * fclose($fd); + * print_r($metadata); + * + * + * @param string $path + * The path to the file on Dropbox (UTF-8). + * + * @param resource $outStream + * If the file exists, the file contents will be written to this stream. + * + * @param string|null $rev + * If you want the latest revision of the file at the given path, pass in `null`. + * If you want a specific version of a file, pass in value of the file metadata's "rev" field. + * + * @return null|array + * The metadata + * object for the file at the given $path and $rev, or `null` if the file + * doesn't exist, + * + * @throws Exception + */ + function getFile($path, $outStream, $rev = null) + { + Path::checkArgNonRoot("path", $path); + Checker::argResource("outStream", $outStream); + Checker::argStringNonEmptyOrNull("rev", $rev); + + $url = $this->buildUrlForGetOrPut( + $this->contentHost, + $this->appendFilePath("1/files", $path), + array("rev" => $rev)); + + $curl = $this->mkCurl($url); + $metadataCatcher = new DropboxMetadataHeaderCatcher($curl->handle); + $streamRelay = new CurlStreamRelay($curl->handle, $outStream); + + $response = $curl->exec(); + + if ($response->statusCode === 404) return null; + + if ($response->statusCode !== 200) { + $response->body = $streamRelay->getErrorBody(); + throw RequestUtil::unexpectedStatus($response); + } + + return $metadataCatcher->getMetadata(); + } + + /** + * Calling 'uploadFile' with `$numBytes` less than this value, will cause this SDK + * to use the standard /files_put endpoint. When `$numBytes` is greater than this + * value, we'll use the /chunked_upload endpoint. + * + * @var int + */ + private static $AUTO_CHUNKED_UPLOAD_THRESHOLD = 9863168; // 8 MB + + /** + * @var int + */ + private static $DEFAULT_CHUNK_SIZE = 4194304; // 4 MB + + /** + * Creates a file on Dropbox, using the data from `$inStream` for the file contents. + * + * + * use \Dropbox as dbx; + * $client = ...; + * $fd = fopen("./frog.jpeg", "rb"); + * $md1 = $client->uploadFile("/Photos/Frog.jpeg", + * dbx\WriteMode::add(), $fd); + * fclose($fd); + * print_r($md1); + * $rev = $md1["rev"]; + * + * // Re-upload with WriteMode::update(...), which will overwrite the + * // file if it hasn't been modified from our original upload. + * $fd = fopen("./frog-new.jpeg", "rb"); + * $md2 = $client->uploadFile("/Photos/Frog.jpeg", + * dbx\WriteMode::update($rev), $fd); + * fclose($fd); + * print_r($md2); + * + * + * @param string $path + * The Dropbox path to save the file to (UTF-8). + * + * @param WriteMode $writeMode + * What to do if there's already a file at the given path. + * + * @param resource $inStream + * The data to use for the file contents. + * + * @param int|null $numBytes + * You can pass in `null` if you don't know. If you do provide the size, we can + * perform a slightly more efficient upload (fewer network round-trips) for files smaller + * than 8 MB. + * + * @return mixed + * The self::$AUTO_CHUNKED_UPLOAD_THRESHOLD) { + $metadata = $this->_uploadFileChunked($path, $writeMode, $inStream, $numBytes, + self::$DEFAULT_CHUNK_SIZE); + } else { + $metadata = $this->_uploadFile($path, $writeMode, + function(Curl $curl) use ($inStream, $numBytes) { + $curl->set(CURLOPT_PUT, true); + $curl->set(CURLOPT_INFILE, $inStream); + $curl->set(CURLOPT_INFILESIZE, $numBytes); + }); + } + + return $metadata; + } + + /** + * Creates a file on Dropbox, using the given $data string as the file contents. + * + * + * use \Dropbox as dbx; + * $client = ...; + * $md = $client->uploadFileFromString("/Grocery List.txt", + * dbx\WriteMode::add(), + * "1. Coke\n2. Popcorn\n3. Toothpaste\n"); + * print_r($md); + * + * + * @param string $path + * The Dropbox path to save the file to (UTF-8). + * + * @param WriteMode $writeMode + * What to do if there's already a file at the given path. + * + * @param string $data + * The data to use for the contents of the file. + * + * @return mixed + * The _uploadFile($path, $writeMode, function(Curl $curl) use ($data) { + $curl->set(CURLOPT_CUSTOMREQUEST, "PUT"); + $curl->set(CURLOPT_POSTFIELDS, $data); + $curl->addHeader("Content-Type: application/octet-stream"); + }); + } + + /** + * Creates a file on Dropbox, using the data from `$inStream` as the file contents. + * + * This version of `uploadFile` splits uploads the file ~4MB chunks at a time and + * will retry a few times if one chunk fails to upload. Uses {@link chunkedUploadStart()}, + * {@link chunkedUploadContinue()}, and {@link chunkedUploadFinish()}. + * + * @param string $path + * The Dropbox path to save the file to (UTF-8). + * + * @param WriteMode $writeMode + * What to do if there's already a file at the given path. + * + * @param resource $inStream + * The data to use for the file contents. + * + * @param int|null $numBytes + * The number of bytes available from $inStream. + * You can pass in `null` if you don't know. + * + * @param int|null $chunkSize + * The number of bytes to upload in each chunk. You can omit this (or pass in + * `null` and the library will use a reasonable default. + * + * @return mixed + * The _uploadFileChunked($path, $writeMode, $inStream, $numBytes, $chunkSize); + } + + /** + * @param string $path + * + * @param WriteMode $writeMode + * What to do if there's already a file at the given path (UTF-8). + * + * @param resource $inStream + * The source of data to upload. + * + * @param int|null $numBytes + * You can pass in `null`. But if you know how many bytes you expect, pass in + * that value and this function will do a sanity check at the end to make sure the number of + * bytes read from `$inStream` matches up. + * + * @param int $chunkSize + * + * @return array + * The 0); + + $data = self::readFully($inStream, $chunkSize); + $len = strlen($data); + + $client = $this; + $uploadId = RequestUtil::runWithRetry(3, function() use ($data, $client) { + return $client->chunkedUploadStart($data); + }); + + $byteOffset = $len; + + while (!feof($inStream)) { + $data = self::readFully($inStream, $chunkSize); + $len = strlen($data); + + while (true) { + $r = RequestUtil::runWithRetry(3, + function() use ($client, $uploadId, $byteOffset, $data) { + return $client->chunkedUploadContinue($uploadId, $byteOffset, $data); + }); + + if ($r === true) { // Chunk got uploaded! + $byteOffset += $len; + break; + } + if ($r === false) { // Server didn't recognize our upload ID + // This is very unlikely since we're uploading all the chunks in sequence. + throw new Exception_BadResponse("Server forgot our uploadId"); + } + + // Otherwise, the server is at a different byte offset from us. + $serverByteOffset = $r; + assert($serverByteOffset !== $byteOffset); // chunkedUploadContinue ensures this. + // An earlier byte offset means the server has lost data we sent earlier. + if ($serverByteOffset < $byteOffset) throw new Exception_BadResponse( + "Server is at an ealier byte offset: us=$byteOffset, server=$serverByteOffset"); + $diff = $serverByteOffset - $byteOffset; + // If the server is past where we think it could possibly be, something went wrong. + if ($diff > $len) throw new Exception_BadResponse( + "Server is more than a chunk ahead: us=$byteOffset, server=$serverByteOffset"); + // The normal case is that the server is a bit further along than us because of a + // partially-uploaded chunk. Finish it off. + $byteOffset += $diff; + if ($diff === $len) break; // If the server is at the end, we're done. + $data = substr($data, $diff); + } + } + + if ($numBytes !== null && $byteOffset !== $numBytes) throw new \InvalidArgumentException( + "You passed numBytes=$numBytes but the stream had $byteOffset bytes."); + + $metadata = RequestUtil::runWithRetry(3, + function() use ($client, $uploadId, $path, $writeMode) { + return $client->chunkedUploadFinish($uploadId, $path, $writeMode); + }); + + return $metadata; + } + + /** + * Sometimes fread() returns less than the request number of bytes (for example, when reading + * from network streams). This function repeatedly calls fread until the requested number of + * bytes have been read or we've reached EOF. + * + * @param resource $inStream + * @param int $numBytes + * @throws StreamReadException + * @return string + */ + private static function readFully($inStream, $numBytes) + { + Checker::argNat("numBytes", $numBytes); + + $full = ''; + $bytesRemaining = $numBytes; + while (!feof($inStream) && $bytesRemaining > 0) { + $part = fread($inStream, $bytesRemaining); + if ($part === false) throw new StreamReadException("Error reading from \$inStream."); + $full .= $part; + $bytesRemaining -= strlen($part); + } + return $full; + } + + /** + * @param string $path + * @param WriteMode $writeMode + * @param callable $curlConfigClosure + * @return array + */ + private function _uploadFile($path, $writeMode, $curlConfigClosure) + { + Path::checkArg("path", $path); + WriteMode::checkArg("writeMode", $writeMode); + Checker::argCallable("curlConfigClosure", $curlConfigClosure); + + $url = $this->buildUrlForGetOrPut( + $this->contentHost, + $this->appendFilePath("1/files_put", $path), + $writeMode->getExtraParams()); + + $curl = $this->mkCurl($url); + + $curlConfigClosure($curl); + + $curl->set(CURLOPT_RETURNTRANSFER, true); + $response = $curl->exec(); + + if ($response->statusCode !== 200) throw RequestUtil::unexpectedStatus($response); + + return RequestUtil::parseResponseJson($response->body); + } + + /** + * Start a new chunked upload session and upload the first chunk of data. + * + * @param string $data + * The data to start off the chunked upload session. + * + * @return array + * A pair of `(string $uploadId, int $byteOffset)`. `$uploadId` + * is a unique identifier for this chunked upload session. You pass this in to + * {@link chunkedUploadContinue} and {@link chuunkedUploadFinish}. `$byteOffset` + * is the number of bytes that were successfully uploaded. + * + * @throws Exception + */ + function chunkedUploadStart($data) + { + Checker::argString("data", $data); + + $response = $this->_chunkedUpload(array(), $data); + + if ($response->statusCode === 404) { + throw new Exception_BadResponse("Got a 404, but we didn't send up an 'upload_id'"); + } + + $correction = self::_chunkedUploadCheckForOffsetCorrection($response); + if ($correction !== null) throw new Exception_BadResponse( + "Got an offset-correcting 400 response, but we didn't send an offset"); + + if ($response->statusCode !== 200) throw RequestUtil::unexpectedStatus($response); + + list($uploadId, $byteOffset) = self::_chunkedUploadParse200Response($response->body); + $len = strlen($data); + if ($byteOffset !== $len) throw new Exception_BadResponse( + "We sent $len bytes, but server returned an offset of $byteOffset"); + + return $uploadId; + } + + /** + * Append another chunk data to a previously-started chunked upload session. + * + * @param string $uploadId + * The unique identifier for the chunked upload session. This is obtained via + * {@link chunkedUploadStart}. + * + * @param int $byteOffset + * The number of bytes you think you've already uploaded to the given chunked upload + * session. The server will append the new chunk of data after that point. + * + * @param string $data + * The data to append to the existing chunked upload session. + * + * @return int|bool + * If `false`, it means the server didn't know about the given + * `$uploadId`. This may be because the chunked upload session has expired + * (they last around 24 hours). + * If `true`, the chunk was successfully uploaded. If an integer, it means + * you and the server don't agree on the current `$byteOffset`. The returned + * integer is the server's internal byte offset for the chunked upload session. You need + * to adjust your input to match. + * + * @throws Exception + */ + function chunkedUploadContinue($uploadId, $byteOffset, $data) + { + Checker::argStringNonEmpty("uploadId", $uploadId); + Checker::argNat("byteOffset", $byteOffset); + Checker::argString("data", $data); + + $response = $this->_chunkedUpload( + array("upload_id" => $uploadId, "offset" => $byteOffset), $data); + + if ($response->statusCode === 404) { + // The server doesn't know our upload ID. Maybe it expired? + return false; + } + + $correction = self::_chunkedUploadCheckForOffsetCorrection($response); + if ($correction !== null) { + list($correctedUploadId, $correctedByteOffset) = $correction; + if ($correctedUploadId !== $uploadId) throw new Exception_BadResponse( + "Corrective 400 upload_id mismatch: us=". + Util::q($uploadId)." server=".Util::q($correctedUploadId)); + if ($correctedByteOffset === $byteOffset) throw new Exception_BadResponse( + "Corrective 400 offset is the same as ours: $byteOffset"); + return $correctedByteOffset; + } + + if ($response->statusCode !== 200) throw RequestUtil::unexpectedStatus($response); + list($retUploadId, $retByteOffset) = self::_chunkedUploadParse200Response($response->body); + + $nextByteOffset = $byteOffset + strlen($data); + if ($uploadId !== $retUploadId) throw new Exception_BadResponse( + "upload_id mismatch: us=".Util::q($uploadId) .", server=".Util::q($uploadId)); + if ($nextByteOffset !== $retByteOffset) throw new Exception_BadResponse( + "next-offset mismatch: us=$nextByteOffset, server=$retByteOffset"); + + return true; + } + + /** + * @param string $body + * @return array + */ + private static function _chunkedUploadParse200Response($body) + { + $j = RequestUtil::parseResponseJson($body); + $uploadId = self::getField($j, "upload_id"); + $byteOffset = self::getField($j, "offset"); + return array($uploadId, $byteOffset); + } + + /** + * @param HttpResponse $response + * @return array|null + */ + private static function _chunkedUploadCheckForOffsetCorrection($response) + { + if ($response->statusCode !== 400) return null; + $j = json_decode($response->body, true, 10); + if ($j === null) return null; + if (!array_key_exists("upload_id", $j) || !array_key_exists("offset", $j)) return null; + $uploadId = $j["upload_id"]; + $byteOffset = $j["offset"]; + return array($uploadId, $byteOffset); + } + + /** + * Creates a file on Dropbox using the accumulated contents of the given chunked upload session. + * + * See /commit_chunked_upload. + * + * @param string $uploadId + * The unique identifier for the chunked upload session. This is obtained via + * {@link chunkedUploadStart}. + * + * @param string $path + * The Dropbox path to save the file to. + * + * @param WriteMode $writeMode + * What to do if there's already a file at the given path. + * + * @return array|null + * If `null`, it means the Dropbox server wasn't aware of the + * `$uploadId` you gave it. + * Otherwise, you get back the + * metadata object + * for the newly-created file. + * + * @throws Exception + */ + function chunkedUploadFinish($uploadId, $path, $writeMode) + { + Checker::argStringNonEmpty("uploadId", $uploadId); + Path::checkArgNonRoot("path", $path); + WriteMode::checkArg("writeMode", $writeMode); + + $params = array_merge(array("upload_id" => $uploadId), $writeMode->getExtraParams()); + + $response = $this->doPost( + $this->contentHost, + $this->appendFilePath("1/commit_chunked_upload", $path), + $params); + + if ($response->statusCode === 404) return null; + if ($response->statusCode !== 200) throw RequestUtil::unexpectedStatus($response); + + return RequestUtil::parseResponseJson($response->body); + } + + /** + * @param array $params + * @param string $data + * @return HttpResponse + */ + protected function _chunkedUpload($params, $data) + // Marked 'protected' so I can override it in testing. + { + $url = $this->buildUrlForGetOrPut( + $this->contentHost, "1/chunked_upload", $params); + + $curl = $this->mkCurl($url); + + // We can't use CURLOPT_PUT because it wants a stream, but we already have $data in memory. + $curl->set(CURLOPT_CUSTOMREQUEST, "PUT"); + $curl->set(CURLOPT_POSTFIELDS, $data); + $curl->addHeader("Content-Type: application/octet-stream"); + + $curl->set(CURLOPT_RETURNTRANSFER, true); + return $curl->exec(); + } + + /** + * Returns the metadata for whatever file or folder is at the given path. + * + * + * $client = ...; + * $md = $client->getMetadata("/Photos/Frog.jpeg"); + * print_r($md); + * + * + * @param string $path + * The Dropbox path to a file or folder (UTF-8). + * + * @return array|null + * If there is a file or folder at the given path, you'll get back the + * metadata object + * for that file or folder. If not, you'll get back `null`. + * + * @throws Exception + */ + function getMetadata($path) + { + Path::checkArg("path", $path); + + return $this->_getMetadata($path, array("list" => "false")); + } + + /** + * Returns the metadata for whatever file or folder is at the given path and, if it's a folder, + * also include the metadata for all the immediate children of that folder. + * + * + * $client = ...; + * $md = $client->getMetadataWithChildren("/Photos"); + * print_r($md); + * + * + * @param string $path + * The Dropbox path to a file or folder (UTF-8). + * + * @return array|null + * If there is a file or folder at the given path, you'll get back the + * metadata object + * for that file or folder, along with all immediate children if it's a folder. If not, + * you'll get back `null`. + * + * @throws Exception + */ + function getMetadataWithChildren($path) + { + Path::checkArg("path", $path); + + return $this->_getMetadata($path, array("list" => "true", "file_limit" => "25000")); + } + + /** + * @param string $path + * @param array $params + * @return array + */ + private function _getMetadata($path, $params) + { + $response = $this->doGet( + $this->apiHost, + $this->appendFilePath("1/metadata", $path), + $params); + + if ($response->statusCode === 404) return null; + if ($response->statusCode !== 200) throw RequestUtil::unexpectedStatus($response); + + $metadata = RequestUtil::parseResponseJson($response->body); + if (array_key_exists("is_deleted", $metadata) && $metadata["is_deleted"]) return null; + return $metadata; + } + + /** + * If you've previously retrieved the metadata for a folder and its children, this method will + * retrieve updated metadata only if something has changed. This is more efficient than + * calling {@link getMetadataWithChildren} if you have a cache of previous results. + * + * + * $client = ...; + * $md = $client->getMetadataWithChildren("/Photos"); + * print_r($md); + * assert($md["is_dir"], "expecting \"/Photos\" to be a folder"); + * + * sleep(10); + * + * // Now see if anything changed... + * list($changed, $new_md) = $client->getMetadataWithChildrenIfChanged( + * "/Photos", $md["hash"]); + * if ($changed) { + * echo "Folder changed.\n"; + * print_r($new_md); + * } else { + * echo "Folder didn't change.\n"; + * } + * + * + * @param string $path + * The Dropbox path to a folder (UTF-8). + * + * @param string $previousFolderHash + * The "hash" field from the previously retrieved folder metadata. + * + * @return array + * A `list(boolean $changed, array $metadata)`. If the metadata hasn't changed, + * you'll get `list(false, null)`. If the metadata of the folder or any of its + * children has changed, you'll get `list(true, $newMetadata)`. $metadata is a + * metadata object. + * + * @throws Exception + */ + function getMetadataWithChildrenIfChanged($path, $previousFolderHash) + { + Path::checkArg("path", $path); + Checker::argStringNonEmpty("previousFolderHash", $previousFolderHash); + + $params = array("list" => "true", "file_limit" => "25000", "hash" => $previousFolderHash); + + $response = $this->doGet( + $this->apiHost, + $this->appendFilePath("1/metadata", $path), + $params); + + if ($response->statusCode === 304) return array(false, null); + if ($response->statusCode === 404) return array(true, null); + if ($response->statusCode !== 200) throw RequestUtil::unexpectedStatus($response); + + $metadata = RequestUtil::parseResponseJson($response->body); + if (array_key_exists("is_deleted", $metadata) && $metadata["is_deleted"]) { + return array(true, null); + } + return array(true, $metadata); + } + + /** + * A way of letting you keep up with changes to files and folders in a user's Dropbox. + * + * @param string|null $cursor + * If this is the first time you're calling this, pass in `null`. Otherwise, + * pass in whatever cursor was returned by the previous call. + * + * @param string|null $pathPrefix + * If `null`, you'll get results for the entire folder (either the user's + * entire Dropbox or your App Folder). If you set `$path_prefix` to + * "/Photos/Vacation", you'll only get results for that path and any files and folders + * under it. + * + * @return array + * A delta page, which + * contains a list of changes to apply along with a new "cursor" that should be passed into + * future `getDelta` calls. If the "reset" field is `true`, you + * should clear your local state before applying the changes. If the "has_more" field is + * `true`, call `getDelta` immediately to get more results, otherwise + * wait a while (at least 5 minutes) before calling `getDelta` again. + * + * @throws Exception + */ + function getDelta($cursor = null, $pathPrefix = null) + { + Checker::argStringNonEmptyOrNull("cursor", $cursor); + Path::checkArgOrNull("pathPrefix", $pathPrefix); + + $response = $this->doPost($this->apiHost, "1/delta", array( + "cursor" => $cursor, + "path_prefix" => $pathPrefix)); + + if ($response->statusCode !== 200) throw RequestUtil::unexpectedStatus($response); + + return RequestUtil::parseResponseJson($response->body); + } + + /** + * Gets the metadata for all the file revisions (up to a limit) for a given path. + * + * See /revisions. + * + * @param string path + * The Dropbox path that you want file revision metadata for (UTF-8). + * + * @param int|null limit + * The maximum number of revisions to return. + * + * @return array|null + * A list of doGet( + $this->apiHost, + $this->appendFilePath("1/revisions", $path), + array("rev_limit" => $limit)); + + if ($response->statusCode === 406) return null; + if ($response->statusCode !== 200) throw RequestUtil::unexpectedStatus($response); + + return RequestUtil::parseResponseJson($response->body); + } + + /** + * Takes a copy of the file at the given revision and saves it over the current copy. This + * will create a new revision, but the file contents will match the revision you specified. + * + * See /restore. + * + * @param string $path + * The Dropbox path of the file to restore (UTF-8). + * + * @param string $rev + * The revision to restore the contents to. + * + * @return mixed + * The metadata + * object + * + * @throws Exception + */ + function restoreFile($path, $rev) + { + Path::checkArgNonRoot("path", $path); + Checker::argStringNonEmpty("rev", $rev); + + $response = $this->doPost( + $this->apiHost, + $this->appendFilePath("1/restore", $path), + array("rev" => $rev)); + + if ($response->statusCode === 404) return null; + if ($response->statusCode !== 200) throw RequestUtil::unexpectedStatus($response); + + return RequestUtil::parseResponseJson($response->body); + } + + /** + * Returns metadata for all files and folders whose filename matches the query string. + * + * See /search. + * + * @param string $basePath + * The path to limit the search to (UTF-8). Pass in "/" to search everything. + * + * @param string $query + * A space-separated list of substrings to search for. A file matches only if it contains + * all the substrings. + * + * @param int|null $limit + * The maximum number of results to return. + * + * @param bool $includeDeleted + * Whether to include deleted files in the results. + * + * @return mixed + * A list of doPost( + $this->apiHost, + $this->appendFilePath("1/search", $basePath), + array( + "query" => $query, + "file_limit" => $limit, + "include_deleted" => $includeDeleted, + )); + + if ($response->statusCode !== 200) throw RequestUtil::unexpectedStatus($response); + + return RequestUtil::parseResponseJson($response->body); + } + + /** + * Creates and returns a public link to a file or folder's "preview page". This link can be + * used without authentication. The preview page may contain a thumbnail or some other + * preview of the file, along with a download link to download the actual file. + * + * See /shares. + * + * @param string $path + * The Dropbox path to the file or folder you want to create a shareable link to (UTF-8). + * + * @return string + * The URL of the preview page. + * + * @throws Exception + */ + function createShareableLink($path) + { + Path::checkArg("path", $path); + + $response = $this->doPost( + $this->apiHost, + $this->appendFilePath("1/shares", $path), + array( + "short_url" => "false", + )); + + if ($response->statusCode === 404) return null; + if ($response->statusCode !== 200) throw RequestUtil::unexpectedStatus($response); + + $j = RequestUtil::parseResponseJson($response->body); + return self::getField($j, "url"); + } + + /** + * Creates and returns a direct link to a file. This link can be used without authentication. + * This link will expire in a few hours. + * + * See /media. + * + * @param string $path + * The Dropbox path to a file or folder (UTF-8). + * + * @return array + * A `list(string $url, \DateTime $expires)` where `$url` is a direct + * link to the requested file and `$expires` is a standard PHP + * `\DateTime` representing when `$url` will stop working. + * + * @throws Exception + */ + function createTemporaryDirectLink($path) + { + Path::checkArgNonRoot("path", $path); + + $response = $this->doPost( + $this->apiHost, + $this->appendFilePath("1/media", $path)); + + if ($response->statusCode === 404) return null; + if ($response->statusCode !== 200) throw RequestUtil::unexpectedStatus($response); + + $j = RequestUtil::parseResponseJson($response->body); + $url = self::getField($j, "url"); + $expires = self::parseDateTime(self::getField($j, "expires")); + return array($url, $expires); + } + + /** + * Creates and returns a "copy ref" to a file. A copy ref can be used to copy a file across + * different Dropbox accounts without downloading and re-uploading. + * + * For example: Create a `Client` using the access token from one account and call + * `createCopyRef`. Then, create a `Client` using the access token for + * another account and call `copyFromCopyRef` using the copy ref. (You need to use + * the same app key both times.) + * + * See /copy_ref. + * + * @param string path + * The Dropbox path of the file or folder you want to create a copy ref for (UTF-8). + * + * @return string + * The copy ref (just a string that you keep track of). + * + * @throws Exception + */ + function createCopyRef($path) + { + Path::checkArg("path", $path); + + $response = $this->doGet( + $this->apiHost, + $this->appendFilePath("1/copy_ref", $path)); + + if ($response->statusCode === 404) return null; + if ($response->statusCode !== 200) throw RequestUtil::unexpectedStatus($response); + + $j = RequestUtil::parseResponseJson($response->body); + return self::getField($j, "copy_ref"); + } + + /** + * Gets a thumbnail image representation of the file at the given path. + * + * See /thumbnails. + * + * @param string $path + * The path to the file you want a thumbnail for (UTF-8). + * + * @param string $format + * One of the two image formats: "jpeg" or "png". + * + * @param string $size + * One of the predefined image size names, as a string: + *
      + *
    • "xs" - 32x32
    • + *
    • "s" - 64x64
    • + *
    • "m" - 128x128
    • + *
    • "l" - 640x480
    • + *
    • "xl" - 1024x768
    • + *
    + * + * @return array|null + * If the file exists, you'll get `list(array $metadata, string $data)` where + * `$metadata` is the file's + * metadata object + * and $data is the raw data for the thumbnail image. If the file doesn't exist, you'll + * get `null`. + * + * @throws Exception + */ + function getThumbnail($path, $format, $size) + { + Path::checkArgNonRoot("path", $path); + Checker::argString("format", $format); + Checker::argString("size", $size); + if (!in_array($format, array("jpeg", "png"))) { + throw new \InvalidArgumentException("Invalid 'format': ".Util::q($format)); + } + if (!in_array($size, array("xs", "s", "m", "l", "xl"))) { + throw new \InvalidArgumentException("Invalid 'size': ".Util::q($size)); + } + + $url = $this->buildUrlForGetOrPut( + $this->contentHost, + $this->appendFilePath("1/thumbnails", $path), + array("size" => $size, "format" => $format)); + + $curl = $this->mkCurl($url); + $metadataCatcher = new DropboxMetadataHeaderCatcher($curl->handle); + + $curl->set(CURLOPT_RETURNTRANSFER, true); + $response = $curl->exec(); + + if ($response->statusCode === 404) return null; + if ($response->statusCode !== 200) throw RequestUtil::unexpectedStatus($response); + + $metadata = $metadataCatcher->getMetadata(); + return array($metadata, $response->body); + } + + /** + * Copies a file or folder to a new location + * + * See /fileops/copy. + * + * @param string $fromPath + * The Dropbox path of the file or folder you want to copy (UTF-8). + * + * @param string $toPath + * The destination Dropbox path (UTF-8). + * + * @return mixed + * The metadata + * object for the new file or folder. + * + * @throws Exception + */ + function copy($fromPath, $toPath) + { + Path::checkArg("fromPath", $fromPath); + Path::checkArgNonRoot("toPath", $toPath); + + $response = $this->doPost( + $this->apiHost, + "1/fileops/copy", + array( + "root" => "auto", + "from_path" => $fromPath, + "to_path" => $toPath, + )); + + if ($response->statusCode !== 200) throw RequestUtil::unexpectedStatus($response); + + return RequestUtil::parseResponseJson($response->body); + } + + /** + * Creates a file or folder based on an existing copy ref (possibly from a different Dropbox + * account). + * + * See /fileops/copy. + * + * @param string $copyRef + * A copy ref obtained via the {@link createCopyRef()} call. + * + * @param string $toPath + * The Dropbox path you want to copy the file or folder to (UTF-8). + * + * @return mixed + * The metadata + * object for the new file or folder. + * + * @throws Exception + */ + function copyFromCopyRef($copyRef, $toPath) + { + Checker::argStringNonEmpty("copyRef", $copyRef); + Path::checkArgNonRoot("toPath", $toPath); + + $response = $this->doPost( + $this->apiHost, + "1/fileops/copy", + array( + "root" => "auto", + "from_copy_ref" => $copyRef, + "to_path" => $toPath, + ) + ); + + if ($response->statusCode !== 200) throw RequestUtil::unexpectedStatus($response); + + return RequestUtil::parseResponseJson($response->body); + } + + /** + * Creates a folder. + * + * See /fileops/create_folder. + * + * @param string $path + * The Dropbox path at which to create the folder (UTF-8). + * + * @return array|null + * If successful, you'll get back the + * metadata object + * for the newly-created folder. If not successful, you'll get `null`. + * + * @throws Exception + */ + function createFolder($path) + { + Path::checkArgNonRoot("path", $path); + + $response = $this->doPost( + $this->apiHost, + "1/fileops/create_folder", + array( + "root" => "auto", + "path" => $path, + )); + + if ($response->statusCode === 403) return null; + if ($response->statusCode !== 200) throw RequestUtil::unexpectedStatus($response); + + return RequestUtil::parseResponseJson($response->body); + } + + /** + * Deletes a file or folder + * + * See /fileops/delete. + * + * @param string $path + * The Dropbox path of the file or folder to delete (UTF-8). + * + * @return mixed + * The metadata + * object for the deleted file or folder. + * + * @throws Exception + */ + function delete($path) + { + Path::checkArgNonRoot("path", $path); + + $response = $this->doPost( + $this->apiHost, + "1/fileops/delete", + array( + "root" => "auto", + "path" => $path, + )); + + if ($response->statusCode !== 200) throw RequestUtil::unexpectedStatus($response); + + return RequestUtil::parseResponseJson($response->body); + } + + /** + * Moves a file or folder to a new location. + * + * See /fileops/move. + * + * @param string $fromPath + * The source Dropbox path (UTF-8). + * + * @param string $toPath + * The destination Dropbox path (UTF-8). + * + * @return mixed + * The metadata + * object for the destination file or folder. + * + * @throws Exception + */ + function move($fromPath, $toPath) + { + Path::checkArgNonRoot("fromPath", $fromPath); + Path::checkArgNonRoot("toPath", $toPath); + + $response = $this->doPost( + $this->apiHost, + "1/fileops/move", + array( + "root" => "auto", + "from_path" => $fromPath, + "to_path" => $toPath, + )); + + if ($response->statusCode !== 200) throw RequestUtil::unexpectedStatus($response); + + return RequestUtil::parseResponseJson($response->body); + } + + /** + * Build a URL for making a GET or PUT request. Will add the "locale" + * parameter. + * + * @param string $host + * Either the "API" or "API content" hostname from {@link getHost()}. + * @param string $path + * The "path" part of the URL. For example, "/account/info". + * @param array|null $params + * URL parameters. For POST requests, do not put the parameters here. + * Include them in the request body instead. + * + * @return string + */ + function buildUrlForGetOrPut($host, $path, $params = null) + { + return RequestUtil::buildUrlForGetOrPut($this->userLocale, $host, $path, $params); + } + + /** + * Perform an OAuth-2-authorized GET request to the Dropbox API. Will automatically + * fill in "User-Agent" and "locale" as well. + * + * @param string $host + * Either the "API" or "API content" hostname from {@link getHost()}. + * @param string $path + * The "path" part of the URL. For example, "/account/info". + * @param array|null $params + * GET parameters. + * @return HttpResponse + * + * @throws Exception + */ + function doGet($host, $path, $params = null) + { + Checker::argString("host", $host); + Checker::argString("path", $path); + return RequestUtil::doGet($this->clientIdentifier, $this->accessToken, $this->userLocale, + $host, $path, $params); + } + + /** + * Perform an OAuth-2-authorized POST request to the Dropbox API. Will automatically + * fill in "User-Agent" and "locale" as well. + * + * @param string $host + * Either the "API" or "API content" hostname from {@link getHost()}. + * @param string $path + * The "path" part of the URL. For example, "/commit_chunked_upload". + * @param array|null $params + * POST parameters. + * @return HttpResponse + * + * @throws Exception + */ + function doPost($host, $path, $params = null) + { + Checker::argString("host", $host); + Checker::argString("path", $path); + return RequestUtil::doPost($this->clientIdentifier, $this->accessToken, $this->userLocale, + $host, $path, $params); + } + + /** + * Create a {@link Curl} object that is pre-configured with {@link getClientIdentifier()}, + * and the proper OAuth 2 "Authorization" header. + * + * @param string $url + * Generate this URL using {@link buildUrl()}. + * + * @return Curl + */ + function mkCurl($url) + { + return RequestUtil::mkCurlWithOAuth($this->clientIdentifier, $url, $this->accessToken); + } + + /** + * Parses date/time strings returned by the Dropbox API. The Dropbox API returns date/times + * formatted like: `"Sat, 21 Aug 2010 22:31:20 +0000"`. + * + * @param string $apiDateTimeString + * A date/time string returned by the API. + * + * @return \DateTime + * A standard PHP `\DateTime` instance. + * + * @throws Exception_BadResponse + * Thrown if `$apiDateTimeString` isn't correctly formatted. + */ + static function parseDateTime($apiDateTimeString) + { + $dt = \DateTime::createFromFormat(self::$dateTimeFormat, $apiDateTimeString); + if ($dt === false) throw new Exception_BadResponse( + "Bad date/time from server: ".Util::q($apiDateTimeString)); + return $dt; + } + + private static $dateTimeFormat = "D, d M Y H:i:s T"; + + /** + * @internal + */ + static function getField($j, $fieldName) + { + if (!array_key_exists($fieldName, $j)) throw new Exception_BadResponse( + "missing field \"$fieldName\" in ".Util::q($j)); + return $j[$fieldName]; + } + + /** + * Given an OAuth 2 access token, returns `null` if it is well-formed (though + * not necessarily valid). Otherwise, returns a string describing what's wrong with it. + * + * @param string $s + * + * @return string + */ + static function getAccessTokenError($s) + { + if ($s === null) return "can't be null"; + if (strlen($s) === 0) return "can't be empty"; + if (preg_match('@[^-=_~/A-Za-z0-9\.\+]@', $s) === 1) return "contains invalid character"; + return null; + } + + /** + * @internal + */ + static function checkAccessTokenArg($argName, $accessToken) + { + $error = self::getAccessTokenError($accessToken); + if ($error !== null) throw new \InvalidArgumentException("'$argName' invalid: $error"); + } + + /** + * @internal + */ + static function getClientIdentifierError($s) + { + if ($s === null) return "can't be null"; + if (strlen($s) === 0) return "can't be empty"; + if (preg_match('@[\x00-\x1f\x7f]@', $s) === 1) return "contains control character"; + return null; + } + + /** + * @internal + */ + static function checkClientIdentifierArg($argName, $accessToken) + { + $error = self::getClientIdentifierError($accessToken); + if ($error !== null) throw new \InvalidArgumentException("'$argName' invalid: $error"); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/Curl.php b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/Curl.php new file mode 100644 index 0000000..dcfe1fd --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/Curl.php @@ -0,0 +1,126 @@ +handle = curl_init($url); + + // NOTE: Though we turn on all the correct SSL settings, many PHP installations + // don't respect these settings. Run "examples/test-ssl.php" to run some basic + // SSL tests to see how well your PHP implementation behaves. + + // Use our own certificate list. + $this->set(CURLOPT_SSL_VERIFYPEER, true); // Enforce certificate validation + $this->set(CURLOPT_SSL_VERIFYHOST, 2); // Enforce hostname validation + + // Force the use of TLS (SSL v2 and v3 are not secure). + // TODO: Use "CURL_SSLVERSION_TLSv1" instead of "1" once we can rely on PHP 5.5+. + $this->set(CURLOPT_SSLVERSION, 1); + + // Limit the set of ciphersuites used. + global $sslCiphersuiteList; + if ($sslCiphersuiteList !== null) { + $this->set(CURLOPT_SSL_CIPHER_LIST, $sslCiphersuiteList); + } + + list($rootCertsFilePath, $rootCertsFolderPath) = RootCertificates::getPaths(); + // Certificate file. + $this->set(CURLOPT_CAINFO, $rootCertsFilePath); + // Certificate folder. If not specified, some PHP installations will use + // the system default, even when CURLOPT_CAINFO is specified. + $this->set(CURLOPT_CAPATH, $rootCertsFolderPath); + + // Limit vulnerability surface area. Supported in cURL 7.19.4+ + if (defined('CURLOPT_PROTOCOLS')) $this->set(CURLOPT_PROTOCOLS, CURLPROTO_HTTPS); + if (defined('CURLOPT_REDIR_PROTOCOLS')) $this->set(CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTPS); + } + + /** + * @param string $header + */ + function addHeader($header) + { + $this->headers[] = $header; + } + + function exec() + { + $this->set(CURLOPT_HTTPHEADER, $this->headers); + + $body = curl_exec($this->handle); + if ($body === false) { + throw new Exception_NetworkIO("Error executing HTTP request: " . curl_error($this->handle)); + } + + $statusCode = curl_getinfo($this->handle, CURLINFO_HTTP_CODE); + + return new HttpResponse($statusCode, $body); + } + + /** + * @param int $option + * @param mixed $value + */ + function set($option, $value) + { + curl_setopt($this->handle, $option, $value); + } + + function __destruct() + { + curl_close($this->handle); + } +} + +// Different cURL SSL backends use different names for ciphersuites. +$curlVersion = \curl_version(); +$curlSslBackend = $curlVersion['ssl_version']; +if (Util::startsWith($curlSslBackend, "NSS/")) { + // Can't figure out how to reliably set ciphersuites for NSS. + $sslCiphersuiteList = null; +} +else { + // Use the OpenSSL names for all other backends. We may have to + // refine this if users report errors. + $sslCiphersuiteList = + 'ECDHE-RSA-AES256-GCM-SHA384:'. + 'ECDHE-RSA-AES128-GCM-SHA256:'. + 'ECDHE-RSA-AES256-SHA384:'. + 'ECDHE-RSA-AES128-SHA256:'. + 'ECDHE-RSA-AES256-SHA:'. + 'ECDHE-RSA-AES128-SHA:'. + 'ECDHE-RSA-RC4-SHA:'. + 'DHE-RSA-AES256-GCM-SHA384:'. + 'DHE-RSA-AES128-GCM-SHA256:'. + 'DHE-RSA-AES256-SHA256:'. + 'DHE-RSA-AES128-SHA256:'. + 'DHE-RSA-AES256-SHA:'. + 'DHE-RSA-AES128-SHA:'. + 'AES256-GCM-SHA384:'. + 'AES128-GCM-SHA256:'. + 'AES256-SHA256:'. + 'AES128-SHA256:'. + 'AES256-SHA:'. + 'AES128-SHA'; +} diff --git a/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/CurlStreamRelay.php b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/CurlStreamRelay.php new file mode 100644 index 0000000..c42f18a --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/CurlStreamRelay.php @@ -0,0 +1,45 @@ +outStream = $outStream; + $this->errorData = array(); + $isError = null; + curl_setopt($ch, CURLOPT_WRITEFUNCTION, array($this, 'writeData')); + } + + function writeData($ch, $data) + { + if ($this->isError === null) { + $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); + $this->isError = ($statusCode !== 200); + } + + if ($this->isError) { + $this->errorData[] = $data; + } else { + fwrite($this->outStream, $data); + } + + return strlen($data); + } + + function getErrorBody() + { + return implode($this->errorData); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/DeserializeException.php b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/DeserializeException.php new file mode 100644 index 0000000..bb2fa23 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/DeserializeException.php @@ -0,0 +1,19 @@ +skippedFirstLine) { + $this->skippedFirstLine = true; + return strlen($header); + } + + // If we've encountered an error on a previous callback, then there's nothing left to do. + if ($this->error !== null) { + return strlen($header); + } + + // case-insensitive starts-with check. + $headerValue = Util::stripPrefix($header, "x-dropbox-metadata:"); + if ($headerValue === null) { + return strlen($header); + } + + if ($this->metadata !== null) { + $this->error = "Duplicate X-Dropbox-Metadata header"; + return strlen($header); + } + + $parsed = json_decode($headerValue, true, 10); + + if ($parsed === null) { + $this->error = "Bad JSON in X-Dropbox-Metadata header"; + return strlen($header); + } + + $this->metadata = $parsed; + return strlen($header); + } + + function getMetadata() + { + if ($this->error !== null) { + throw new Exception_BadResponse($this->error); + } + if ($this->metadata === null) { + throw new Exception_BadResponse("Missing X-Dropbox-Metadata header"); + } + return $this->metadata; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/Exception.php b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/Exception.php new file mode 100644 index 0000000..fcd0b61 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/Exception.php @@ -0,0 +1,16 @@ +statusCode = $statusCode; + } + + /** + * The HTTP status code returned by the Dropbox server. + * + * @return int + */ + public function getStatusCode() + { + return $this->statusCode; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/Exception/InvalidAccessToken.php b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/Exception/InvalidAccessToken.php new file mode 100644 index 0000000..bd9ac9b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/Exception/InvalidAccessToken.php @@ -0,0 +1,18 @@ +api = $api; + $this->content = $content; + $this->web = $web; + } + + /** + * Returns the host name of the main Dropbox API server. + * The default is "api.dropbox.com". + * + * @return string + */ + function getApi() { return $this->api; } + + /** + * Returns the host name of the Dropbox API content server. + * The default is "api-content.dropbox.com". + * + * @return string + */ + function getContent() { return $this->content; } + + /** + * Returns the host name of the Dropbox web server. Used during user authorization. + * The default is "www.dropbox.com". + * + * @return string + */ + function getWeb() { return $this->web; } + + /** + * Check that a function argument is of type `Host`. + * + * @internal + */ + static function checkArg($argName, $argValue) + { + if (!($argValue instanceof self)) Checker::throwError($argName, $argValue, __CLASS__); + } + + /** + * Check that a function argument is either `null` or of type + * `Host`. + * + * @internal + */ + static function checkArgOrNull($argName, $argValue) + { + if ($argValue === null) return; + if (!($argValue instanceof self)) Checker::throwError($argName, $argValue, __CLASS__); + } + + /** + * Loads a Host object from the 'auth_host' and 'host_suffix' fields of a JSON object. + * If those fields aren't present, return `null`. + * + * @return Host|null + * + * @throws HostLoadException + */ + static function loadFromJson($jsonObj) + { + // Check for the optional 'auth_host' and 'host_suffix' fields. + $authHost = null; + if (array_key_exists('auth_host', $jsonObj)) { + $authHost = $jsonObj["auth_host"]; + if (!is_string($authHost)) { + throw new HostLoadException("Optional field \"auth_host\" must be a string"); + } + } + $hostSuffix = null; + if (array_key_exists('host_suffix', $jsonObj)) { + $hostSuffix = $jsonObj["host_suffix"]; + if (!is_string($hostSuffix)) { + throw new HostLoadException("Optional field \"host_suffix\" must be a string"); + } + } + + if ($authHost === null && $hostSuffix === null) return null; + + if ($authHost === null) { + throw new HostLoadException("Can't provide \"host_suffix\" without providing \"auth_host\"."); + } + if ($hostSuffix === null) { + throw new HostLoadException("Can't provide \"auth_host\" without providing \"host_suffix\"."); + } + $api = "api".$hostSuffix; + $content = "content".$hostSuffix; + $web = $authHost; + return new Host($api, $content, $web); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/HostLoadException.php b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/HostLoadException.php new file mode 100644 index 0000000..f3ac39f --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/HostLoadException.php @@ -0,0 +1,18 @@ +statusCode = $statusCode; + $this->body = $body; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/OAuth1AccessToken.php b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/OAuth1AccessToken.php new file mode 100644 index 0000000..0d3517e --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/OAuth1AccessToken.php @@ -0,0 +1,61 @@ +key; } + + /** @var string */ + private $key; + + /** + * The OAuth 1 access token secret. + * + * Make sure that this is kept a secret. Someone with your app secret can impesonate your + * application. People sometimes ask for help on the Dropbox API forums and + * copy/paste code that includes their app secret. Do not do that. + * + * @return string + */ + function getSecret() { return $this->secret; } + + /** @var secret */ + private $secret; + + /** + * Constructor. + * + * @param string $key + * {@link getKey()} + * @param string $secret + * {@link getSecret()} + */ + function __construct($key, $secret) + { + AppInfo::checkKeyArg($key); + AppInfo::checkSecretArg($secret); + + $this->key = $key; + $this->secret = $secret; + } + + /** + * Use this to check that a function argument is of type `AppInfo` + * + * @internal + */ + static function checkArg($argName, $argValue) + { + if (!($argValue instanceof self)) Checker::throwError($argName, $argValue, __CLASS__); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/OAuth1Upgrader.php b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/OAuth1Upgrader.php new file mode 100644 index 0000000..d012ae6 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/OAuth1Upgrader.php @@ -0,0 +1,104 @@ + + * use \Dropbox as dbx; + * $appInfo = dbx\AppInfo::loadFromJsonFile(...); + * $clientIdentifier = "my-app/1.0"; + * $oauth1AccessToken = dbx\OAuth1AccessToken(...); + * + * $upgrader = new dbx\OAuth1AccessTokenUpgrader($appInfo, $clientIdentifier, ...); + * $oauth2AccessToken = $upgrader->getOAuth2AccessToken($oauth1AccessToken); + * $upgrader->disableOAuth1AccessToken($oauth1AccessToken); + * + */ +class OAuth1Upgrader extends AuthBase +{ + /** + * Given an existing active OAuth 1 access token, make a Dropbox API call to get a new OAuth 2 + * access token that represents the same user and app. + * + * See /oauth2/token_from_oauth1. + * + * @param OAuth1AccessToken $oauth1AccessToken + * + * @return string + * The OAuth 2 access token. + * + * @throws Exception + */ + function createOAuth2AccessToken($oauth1AccessToken) + { + OAuth1AccessToken::checkArg("oauth1AccessToken", $oauth1AccessToken); + + $response = self::doPost($oauth1AccessToken, "1/oauth2/token_from_oauth1"); + + if ($response->statusCode !== 200) throw RequestUtil::unexpectedStatus($response); + + $parts = RequestUtil::parseResponseJson($response->body); + + if (!array_key_exists('token_type', $parts) || !is_string($parts['token_type'])) { + throw new Exception_BadResponse("Missing \"token_type\" field."); + } + $tokenType = $parts['token_type']; + if (!array_key_exists('access_token', $parts) || !is_string($parts['access_token'])) { + throw new Exception_BadResponse("Missing \"access_token\" field."); + } + $accessToken = $parts['access_token']; + + if ($tokenType !== "Bearer" && $tokenType !== "bearer") { + throw new Exception_BadResponse("Unknown \"token_type\"; expecting \"Bearer\", got " + . Util::q($tokenType)); + } + + return $accessToken; + } + + /** + * Make a Dropbox API call to disable the given OAuth 1 access token. + * + * See /disable_access_token. + * + * @param OAuth1AccessToken $oauth1AccessToken + * + * @throws Exception + */ + function disableOAuth1AccessToken($oauth1AccessToken) + { + OAuth1AccessToken::checkArg("oauth1AccessToken", $oauth1AccessToken); + + $response = self::doPost($oauth1AccessToken, "1/disable_access_token"); + + if ($response->statusCode !== 200) throw RequestUtil::unexpectedStatus($response); + } + + /** + * @param OAuth1AccessToken $oauth1AccessToken + * @param string $path + * + * @return HttpResponse + * + * @throws Exception + */ + private function doPost($oauth1AccessToken, $path) + { + // Construct the OAuth 1 header. + $signature = rawurlencode($this->appInfo->getSecret()) . "&" . rawurlencode($oauth1AccessToken->getSecret()); + $authHeaderValue = "OAuth oauth_signature_method=\"PLAINTEXT\"" + . ", oauth_consumer_key=\"" . rawurlencode($this->appInfo->getKey()) . "\"" + . ", oauth_token=\"" . rawurlencode($oauth1AccessToken->getKey()) . "\"" + . ", oauth_signature=\"" . $signature . "\""; + + return RequestUtil::doPostWithSpecificAuth( + $this->clientIdentifier, $authHeaderValue, $this->userLocale, + $this->appInfo->getHost()->getApi(), + $path, + null); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/Path.php b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/Path.php new file mode 100644 index 0000000..45281f0 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/Path.php @@ -0,0 +1,171 @@ + + * Path::getName("/Misc/Notes.txt") // "Notes.txt" + * Path::getName("/Misc") // "Misc" + * Path::getName("/") // null + * + * + * @param string $path + * The full path you want to get the last component of. + * + * @return null|string + * The last component of `$path` or `null` if the given + * `$path` was `"/"`. + */ + static function getName($path) + { + Checker::argStringNonEmpty("path", $path); + + if ($path[0] !== "/") { + throw new \InvalidArgumentException("'path' must start with \"/\""); + } + $l = strlen($path); + if ($l === 1) return null; + if ($path[$l-1] === "/") { + throw new \InvalidArgumentException("'path' must not end with \"/\""); + } + + $lastSlash = strrpos($path, "/"); + return substr($path, $lastSlash+1); + } + + /** + * @internal + * + * @param string $argName + * @param mixed $value + * @throws \InvalidArgumentException + */ + static function checkArg($argName, $value) + { + Checker::argStringNonEmpty($argName, $value); + + $error = self::findError($value); + if ($error !== null) throw new \InvalidArgumentException("'$argName': bad path: $error: ".Util::q($value)); + } + + /** + * @internal + * + * @param string $argName + * @param mixed $value + * @throws \InvalidArgumentException + */ + static function checkArgOrNull($argName, $value) + { + if ($value === null) return; + self::checkArg($argName, $value); + } + + /** + * @internal + * + * @param string $argName + * @param mixed $value + * @throws \InvalidArgumentException + */ + static function checkArgNonRoot($argName, $value) + { + Checker::argStringNonEmpty($argName, $value); + + $error = self::findErrorNonRoot($value); + if ($error !== null) throw new \InvalidArgumentException("'$argName': bad path: $error: ".Util::q($value)); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/RequestUtil.php b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/RequestUtil.php new file mode 100644 index 0000000..d381d0e --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/RequestUtil.php @@ -0,0 +1,298 @@ + $value) { + Checker::argStringNonEmpty("key in 'params'", $key); + if ($value !== null) { + if (is_bool($value)) { + $value = $value ? "true" : "false"; + } + else if (is_int($value)) { + $value = (string) $value; + } + else if (!is_string($value)) { + throw new \InvalidArgumentException("params['$key'] is not a string, int, or bool"); + } + $url .= "&" . rawurlencode($key) . "=" . rawurlencode($value); + } + } + } + return $url; + } + + /** + * @param string $host + * @param string $path + * @return string + */ + static function buildUri($host, $path) + { + Checker::argStringNonEmpty("host", $host); + Checker::argStringNonEmpty("path", $path); + return "https://" . $host . "/" . $path; + } + + /** + * @param string $clientIdentifier + * @param string $url + * @return Curl + */ + static function mkCurl($clientIdentifier, $url) + { + $curl = new Curl($url); + + $curl->set(CURLOPT_CONNECTTIMEOUT, 10); + + // If the transfer speed is below 1kB/sec for 10 sec, abort. + $curl->set(CURLOPT_LOW_SPEED_LIMIT, 1024); + $curl->set(CURLOPT_LOW_SPEED_TIME, 10); + + //$curl->set(CURLOPT_VERBOSE, true); // For debugging. + // TODO: Figure out how to encode clientIdentifier (urlencode?) + $curl->addHeader("User-Agent: ".$clientIdentifier." Dropbox-PHP-SDK/".SdkVersion::VERSION); + + return $curl; + } + + /** + * @param string $clientIdentifier + * @param string $url + * @param string $authHeaderValue + * @return Curl + */ + static function mkCurlWithAuth($clientIdentifier, $url, $authHeaderValue) + { + $curl = self::mkCurl($clientIdentifier, $url); + $curl->addHeader("Authorization: $authHeaderValue"); + return $curl; + } + + /** + * @param string $clientIdentifier + * @param string $url + * @param string $accessToken + * @return Curl + */ + static function mkCurlWithOAuth($clientIdentifier, $url, $accessToken) + { + return self::mkCurlWithAuth($clientIdentifier, $url, "Bearer $accessToken"); + } + + static function buildPostBody($params) + { + if ($params === null) return ""; + + $pairs = array(); + foreach ($params as $key => $value) { + Checker::argStringNonEmpty("key in 'params'", $key); + if ($value !== null) { + if (is_bool($value)) { + $value = $value ? "true" : "false"; + } + else if (is_int($value)) { + $value = (string) $value; + } + else if (!is_string($value)) { + throw new \InvalidArgumentException("params['$key'] is not a string, int, or bool"); + } + $pairs[] = rawurlencode($key) . "=" . rawurlencode((string) $value); + } + } + return implode("&", $pairs); + } + + /** + * @param string $clientIdentifier + * @param string $accessToken + * @param string $userLocale + * @param string $host + * @param string $path + * @param array|null $params + * + * @return HttpResponse + * + * @throws Exception + */ + static function doPost($clientIdentifier, $accessToken, $userLocale, $host, $path, $params = null) + { + Checker::argStringNonEmpty("accessToken", $accessToken); + + $url = self::buildUri($host, $path); + + if ($params === null) $params = array(); + $params['locale'] = $userLocale; + + $curl = self::mkCurlWithOAuth($clientIdentifier, $url, $accessToken); + $curl->set(CURLOPT_POST, true); + $curl->set(CURLOPT_POSTFIELDS, self::buildPostBody($params)); + + $curl->set(CURLOPT_RETURNTRANSFER, true); + return $curl->exec(); + } + + /** + * @param string $clientIdentifier + * @param string $authHeaderValue + * @param string $userLocale + * @param string $host + * @param string $path + * @param array|null $params + * + * @return HttpResponse + * + * @throws Exception + */ + static function doPostWithSpecificAuth($clientIdentifier, $authHeaderValue, $userLocale, $host, $path, $params = null) + { + Checker::argStringNonEmpty("authHeaderValue", $authHeaderValue); + + $url = self::buildUri($host, $path); + + if ($params === null) $params = array(); + $params['locale'] = $userLocale; + + $curl = self::mkCurlWithAuth($clientIdentifier, $url, $authHeaderValue); + $curl->set(CURLOPT_POST, true); + $curl->set(CURLOPT_POSTFIELDS, self::buildPostBody($params)); + + $curl->set(CURLOPT_RETURNTRANSFER, true); + return $curl->exec(); + } + + /** + * @param string $clientIdentifier + * @param string $accessToken + * @param string $userLocale + * @param string $host + * @param string $path + * @param array|null $params + * + * @return HttpResponse + * + * @throws Exception + */ + static function doGet($clientIdentifier, $accessToken, $userLocale, $host, $path, $params = null) + { + Checker::argStringNonEmpty("accessToken", $accessToken); + + $url = self::buildUrlForGetOrPut($userLocale, $host, $path, $params); + + $curl = self::mkCurlWithOAuth($clientIdentifier, $url, $accessToken); + $curl->set(CURLOPT_HTTPGET, true); + $curl->set(CURLOPT_RETURNTRANSFER, true); + + return $curl->exec(); + } + + /** + * @param string $responseBody + * @return mixed + * @throws Exception_BadResponse + */ + static function parseResponseJson($responseBody) + { + $obj = json_decode($responseBody, true, 10); + if ($obj === null) { + throw new Exception_BadResponse("Got bad JSON from server: $responseBody"); + } + return $obj; + } + + static function unexpectedStatus($httpResponse) + { + $sc = $httpResponse->statusCode; + + $message = "HTTP status $sc"; + if (is_string($httpResponse->body)) { + // TODO: Maybe only include the first ~200 chars of the body? + $message .= "\n".$httpResponse->body; + } + + if ($sc === 400) return new Exception_BadRequest($message); + if ($sc === 401) return new Exception_InvalidAccessToken($message); + if ($sc === 500 || $sc === 502) return new Exception_ServerError($message); + if ($sc === 503) return new Exception_RetryLater($message); + if ($sc === 507) return new Exception_OverQuota($message); + + return new Exception_BadResponseCode("Unexpected $message", $sc); + } + + /** + * @param int $maxRetries + * The number of times to retry it the action if it fails with one of the transient + * API errors. A value of 1 means we'll try the action once and if it fails, we + * will retry once. + * + * @param callable $action + * The the action you want to retry. + * + * @return mixed + * Whatever is returned by the $action callable. + */ + static function runWithRetry($maxRetries, $action) + { + Checker::argNat("maxRetries", $maxRetries); + + $retryDelay = 1; + $numRetries = 0; + while (true) { + try { + return $action(); + } + // These exception types are the ones we think are possibly transient errors. + catch (Exception_NetworkIO $ex) { + $savedEx = $ex; + } + catch (Exception_ServerError $ex) { + $savedEx = $ex; + } + catch (Exception_RetryLater $ex) { + $savedEx = $ex; + } + + // We maxed out our retries. Propagate the last exception we got. + if ($numRetries >= $maxRetries) throw $savedEx; + + $numRetries++; + sleep($retryDelay); + $retryDelay *= 2; // Exponential back-off. + } + throw new \RuntimeException("unreachable"); + } + +} diff --git a/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/RootCertificates.php b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/RootCertificates.php new file mode 100644 index 0000000..c5f251b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/RootCertificates.php @@ -0,0 +1,144 @@ +getMessage()); + } + } + else { + if (substr(__DIR__, 0, 7) === 'phar://') { + throw new \Exception("The code appears to be running in a PHAR. You need to call \\Dropbox\\RootCertificates\\useExternalPaths() before making any API calls."); + } + $file = __DIR__.self::$originalPath; + $folder = \dirname($file); + } + self::$paths = array($file, $folder); + } + + return self::$paths; + } + + /** + * @param string $baseFolder + * + * @return string + */ + private static function createExternalCaFolder($baseFolder) + { + // This is hacky, but I can't find a simple way to do this. + + // This process isn't atomic, so give it three tries. + for ($i = 0; $i < 3; $i++) { + $path = \tempnam($baseFolder, "dropbox-php-sdk-trusted-certs-empty-dir"); + if ($path === false) { + throw new \Exception("Couldn't create temp file in folder ".Util::q($baseFolder)."."); + } + if (!\unlink($path)) { + throw new \Exception("Couldn't remove temp file to make way for temp dir: ".Util::q($path)); + } + // TODO: Figure out how to make the folder private on Windows. The '700' only works on Unix. + if (!\mkdir($path, 700)) { + // Someone snuck in between the unlink() and the mkdir() and stole our path. + throw new \Exception("Couldn't create temp dir: ".Util::q($path)); + } + \register_shutdown_function(function() use ($path) { + \rmdir($path); + }); + return $path; + } + + throw new \Exception("Unable to create temp dir in ".Util::q($baseFolder).", there's always something in the way."); + } + + /** + * @param string $baseFolder + * + * @return string + */ + private static function createExternalCaFile($baseFolder) + { + $path = \tempnam($baseFolder, "dropbox-php-sdk-trusted-certs"); + if ($path === false) { + throw new \Exception("Couldn't create temp file in folder ".Util::q($baseFolder)."."); + } + \register_shutdown_function(function() use ($path) { + \unlink($path); + }); + + // NOTE: Can't use the standard PHP copy(). That would clobber the locked-down + // permissions set by tempnam(). + self::copyInto(__DIR__.self::$originalPath, $path); + + return $path; + } + + /** + * @param string $src + * @param string $dest + */ + private static function copyInto($src, $dest) + { + $srcFd = \fopen($src, "r"); + if ($srcFd === false) { + throw new \Exception("Couldn't open " . Util::q($src) . " for reading."); + } + $destFd = \fopen($dest, "w"); + if ($destFd === false) { + \fclose($srcFd); + throw new \Exception("Couldn't open " . Util::q($dest) . " for writing."); + } + + \stream_copy_to_stream($srcFd, $destFd); + + fclose($srcFd); + if (!\fclose($destFd)) { + throw new \Exception("Error closing file ".Util::q($dest)."."); + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/SSLTester.php b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/SSLTester.php new file mode 100644 index 0000000..30cb76d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/SSLTester.php @@ -0,0 +1,128 @@ +set(CURLOPT_RETURNTRANSFER, true); + $curl->exec(); + return true; + } + + private static function testUntrustedCert($url) + { + return self::testDisallowed($url, 'Error executing HTTP request: SSL certificate problem, verify that the CA cert is OK'); + } + + private static function testHostnameMismatch($url) + { + return self::testDisallowed($url, 'Error executing HTTP request: SSL certificate problem: Invalid certificate chain'); + } + + private static function testDisallowed($url, $expectedExceptionMessage) + { + $curl = RequestUtil::mkCurl("test-ssl", $url); + $curl->set(CURLOPT_RETURNTRANSFER, true); + try { + $curl->exec(); + } + catch (Exception_NetworkIO $ex) { + if (strpos($ex->getMessage(), $expectedExceptionMessage) == 0) { + return true; + } else { + throw $ex; + } + } + return false; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/SdkVersion.php b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/SdkVersion.php new file mode 100644 index 0000000..ee72932 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/SdkVersion.php @@ -0,0 +1,13 @@ += 0) { + $s = openssl_random_pseudo_bytes($numBytes, $isCryptoStrong); + if ($isCryptoStrong) return $s; + } + + if (function_exists('mcrypt_create_iv')) { + return mcrypt_create_iv($numBytes); + } + + // Hopefully the above two options cover all our users. But if not, there are + // other platform-specific options we could add. + throw new \Exception("no suitable random number source available"); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/StreamReadException.php b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/StreamReadException.php new file mode 100644 index 0000000..fdc3cb7 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/StreamReadException.php @@ -0,0 +1,16 @@ += "\x20" and $c <= "\x7e") { + // Printable characters. + $r .= $c; + } + else { + // Generic hex escape code. + $r .= "\\x"; + $r .= \bin2hex($c); + } + } + $r .= "\""; + return $r; + } + + /** + * If the given string begins with the UTF-8 BOM (byte order mark), remove it and + * return whatever is left. Otherwise, return the original string untouched. + * + * Though it's not recommended for UTF-8 to have a BOM, the standard allows it to + * support software that isn't Unicode-aware. + * + * @param string $string + * A UTF-8 encoded string. + * + * @return string + */ + public static function stripUtf8Bom($string) + { + if (strlen($string) == 0) return $string; + + if (\substr_compare($string, "\xEF\xBB\xBF", 0, 3) === 0) { + $string = \substr($string, 3); + } + return $string; + } + + /** + * Return whether `$s` starts with `$prefix`. + * + * @param string $s + * @param string $prefix + * @param bool $caseInsensitive + * + * @return bool + */ + public static function startsWith($s, $prefix, $caseInsensitive = false) + { + // substr_compare errors if $main_str is zero-length, so handle that + // case specially here. + if (\strlen($s) == 0) { + return strlen($prefix) == 0; + } + + return \substr_compare($s, $prefix, 0, strlen($prefix), $caseInsensitive) == 0; + } + + /** + * If `$s` starts with `$prefix`, return `$s` with `$prefix` removed. Otherwise, + * return `null`. + * + * @param string $s + * @param string $prefix + * @param bool $caseInsensitive + * + * @return string|null + */ + public static function stripPrefix($s, $prefix, $caseInsensitive = false) + { + // substr_compare errors if $main_str is zero-length, so handle that + // case specially here. + if (strlen($s) == 0) { + if (strlen($prefix) == 0) { + return $s; + } else { + return null; + } + } + + $prefix_length = strlen($prefix); + if (\substr_compare($s, $prefix, 0, strlen($prefix), $caseInsensitive) == 0) { + return substr($s, $prefix_length); + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/ValueStore.php b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/ValueStore.php new file mode 100644 index 0000000..a97ac96 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/ValueStore.php @@ -0,0 +1,61 @@ + + * class MemcacheValueStore implements ValueStore + * { + * private $key; + * private $memcache; + * + * function __construct($memcache, $key) + * { + * $this->memcache = $memcache; + * $this->key = $key; + * } + * + * function get() + * { + * $value = $this->memcache->get($this->getKey()); + * return $value === false ? null : base64_decode($value); + * } + * + * function set($value) + * { + * $this->memcache->set($this->key, base64_encode($value)); + * } + * + * function clear() + * { + * $this->memcache->delete($this->key); + * } + * } + * + */ +interface ValueStore +{ + /** + * Returns the entry's current value or `null` if nothing is set. + * + * @return string + */ + function get(); + + /** + * Set the entry to the given value. + * + * @param string $value + */ + function set($value); + + /** + * Remove the value. + */ + function clear(); +} diff --git a/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/WebAuth.php b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/WebAuth.php new file mode 100644 index 0000000..a448ff1 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/WebAuth.php @@ -0,0 +1,278 @@ + + * use \Dropbox as dbx; + * + * function getWebAuth() + * { + * $appInfo = dbx\AppInfo::loadFromJsonFile(...); + * $clientIdentifier = "my-app/1.0"; + * $redirectUri = "https://example.org/dropbox-auth-finish"; + * $csrfTokenStore = new dbx\ArrayEntryStore($_SESSION, 'dropbox-auth-csrf-token'); + * return new dbx\WebAuth($appInfo, $clientIdentifier, $redirectUri, $csrfTokenStore, ...); + * } + * + * // ---------------------------------------------------------- + * // In the URL handler for "/dropbox-auth-start" + * + * $authorizeUrl = getWebAuth()->start(); + * header("Location: $authorizeUrl"); + * + * // ---------------------------------------------------------- + * // In the URL handler for "/dropbox-auth-finish" + * + * try { + * list($accessToken, $userId, $urlState) = getWebAuth()->finish($_GET); + * assert($urlState === null); // Since we didn't pass anything in start() + * } + * catch (dbx\WebAuthException_BadRequest $ex) { + * error_log("/dropbox-auth-finish: bad request: " . $ex->getMessage()); + * // Respond with an HTTP 400 and display error page... + * } + * catch (dbx\WebAuthException_BadState $ex) { + * // Auth session expired. Restart the auth process. + * header('Location: /dropbox-auth-start'); + * } + * catch (dbx\WebAuthException_Csrf $ex) { + * error_log("/dropbox-auth-finish: CSRF mismatch: " . $ex->getMessage()); + * // Respond with HTTP 403 and display error page... + * } + * catch (dbx\WebAuthException_NotApproved $ex) { + * error_log("/dropbox-auth-finish: not approved: " . $ex->getMessage()); + * } + * catch (dbx\WebAuthException_Provider $ex) { + * error_log("/dropbox-auth-finish: error redirect from Dropbox: " . $ex->getMessage()); + * } + * catch (dbx\Exception $ex) { + * error_log("/dropbox-auth-finish: error communicating with Dropbox API: " . $ex->getMessage()); + * } + * + * // We can now use $accessToken to make API requests. + * $client = dbx\Client($accessToken, ...); + * + * + */ +class WebAuth extends WebAuthBase +{ + /** + * The URI that the Dropbox server will redirect the user to after the user finishes + * authorizing your app. This URI must be HTTPS-based and + * pre-registered with Dropbox, + * though "localhost"-based and "127.0.0.1"-based URIs are allowed without pre-registration + * and can be either HTTP or HTTPS. + * + * @return string + */ + function getRedirectUri() { return $this->redirectUri; } + + /** @var string */ + private $redirectUri; + + /** + * A object that lets us save CSRF token string to the user's session. If you're using the + * standard PHP `$_SESSION`, you can pass in something like + * `new ArrayEntryStore($_SESSION, 'dropbox-auth-csrf-token')`. + * + * If you're not using $_SESSION, you might have to create your own class that provides + * the same `get()`/`set()`/`clear()` methods as + * {@link ArrayEntryStore}. + * + * @return ValueStore + */ + function getCsrfTokenStore() { return $this->csrfTokenStore; } + + /** @var object */ + private $csrfTokenStore; + + /** + * Constructor. + * + * @param AppInfo $appInfo + * See {@link getAppInfo()} + * @param string $clientIdentifier + * See {@link getClientIdentifier()} + * @param null|string $redirectUri + * See {@link getRedirectUri()} + * @param null|ValueStore $csrfTokenStore + * See {@link getCsrfTokenStore()} + * @param null|string $userLocale + * See {@link getUserLocale()} + */ + function __construct($appInfo, $clientIdentifier, $redirectUri, $csrfTokenStore, $userLocale = null) + { + parent::__construct($appInfo, $clientIdentifier, $userLocale); + + Checker::argStringNonEmpty("redirectUri", $redirectUri); + + $this->csrfTokenStore = $csrfTokenStore; + $this->redirectUri = $redirectUri; + } + + /** + * Starts the OAuth 2 authorization process, which involves redirecting the user to the + * returned authorization URL (a URL on the Dropbox website). When the user then + * either approves or denies your app access, Dropbox will redirect them to the + * `$redirectUri` given to constructor, at which point you should + * call {@link finish()} to complete the authorization process. + * + * This function will also save a CSRF token using the `$csrfTokenStore` given to + * the constructor. This CSRF token will be checked on {@link finish()} to prevent + * request forgery. + * + * See /oauth2/authorize. + * + * @param string|null $urlState + * Any data you would like to keep in the URL through the authorization process. + * This exact state will be returned to you by {@link finish()}. + * + * @param boolean|null $forceReapprove + * If a user has already approved your app, Dropbox may skip the "approve" step and + * redirect immediately to your callback URL. Setting this to `true` tells + * Dropbox to never skip the "approve" step. + * + * @return array + * The URL to redirect the user to. + * + * @throws Exception + */ + function start($urlState = null, $forceReapprove = false) + { + Checker::argStringOrNull("urlState", $urlState); + + $csrfToken = self::encodeCsrfToken(Security::getRandomBytes(16)); + $state = $csrfToken; + if ($urlState !== null) { + $state .= "|"; + $state .= $urlState; + } + $this->csrfTokenStore->set($csrfToken); + + return $this->_getAuthorizeUrl($this->redirectUri, $state, $forceReapprove); + } + + private static function encodeCsrfToken($string) + { + return strtr(base64_encode($string), '+/', '-_'); + } + + /** + * Call this after the user has visited the authorize URL ({@link start()}), approved your app, + * and was redirected to your redirect URI. + * + * See /oauth2/token. + * + * @param array $queryParams + * The query parameters on the GET request to your redirect URI. + * + * @return array + * A `list(string $accessToken, string $userId, string $urlState)`, where + * `$accessToken` can be used to construct a {@link Client}, `$userId` + * is the user ID of the user's Dropbox account, and `$urlState` is the + * value you originally passed in to {@link start()}. + * + * @throws Exception + * Thrown if there's an error getting the access token from Dropbox. + * @throws WebAuthException_BadRequest + * @throws WebAuthException_BadState + * @throws WebAuthException_Csrf + * @throws WebAuthException_NotApproved + * @throws WebAuthException_Provider + */ + function finish($queryParams) + { + Checker::argArray("queryParams", $queryParams); + + $csrfTokenFromSession = $this->csrfTokenStore->get(); + Checker::argStringOrNull("this->csrfTokenStore->get()", $csrfTokenFromSession); + + // Check well-formedness of request. + + if (!isset($queryParams['state'])) { + throw new WebAuthException_BadRequest("Missing query parameter 'state'."); + } + $state = $queryParams['state']; + Checker::argString("queryParams['state']", $state); + + $error = null; + $errorDescription = null; + if (isset($queryParams['error'])) { + $error = $queryParams['error']; + Checker::argString("queryParams['error']", $error); + if (isset($queryParams['error_description'])) { + $errorDescription = $queryParams['error_description']; + Checker::argString("queryParams['error_description']", $errorDescription); + } + } + + $code = null; + if (isset($queryParams['code'])) { + $code = $queryParams['code']; + Checker::argString("queryParams['code']", $code); + } + + if ($code !== null && $error !== null) { + throw new WebAuthException_BadRequest("Query parameters 'code' and 'error' are both set;". + " only one must be set."); + } + if ($code === null && $error === null) { + throw new WebAuthException_BadRequest("Neither query parameter 'code' or 'error' is set."); + } + + // Check CSRF token + + if ($csrfTokenFromSession === null) { + throw new WebAuthException_BadState(); + } + + $splitPos = strpos($state, "|"); + if ($splitPos === false) { + $givenCsrfToken = $state; + $urlState = null; + } else { + $givenCsrfToken = substr($state, 0, $splitPos); + $urlState = substr($state, $splitPos + 1); + } + if (!Security::stringEquals($csrfTokenFromSession, $givenCsrfToken)) { + throw new WebAuthException_Csrf("Expected ".Util::q($csrfTokenFromSession) . + ", got ".Util::q($givenCsrfToken) ."."); + } + $this->csrfTokenStore->clear(); + + // Check for error identifier + + if ($error !== null) { + if ($error === 'access_denied') { + // When the user clicks "Deny". + if ($errorDescription === null) { + throw new WebAuthException_NotApproved("No additional description from Dropbox."); + } else { + throw new WebAuthException_NotApproved("Additional description from Dropbox: $errorDescription"); + } + } else { + // All other errors. + $fullMessage = $error; + if ($errorDescription !== null) { + $fullMessage .= ": "; + $fullMessage .= $errorDescription; + } + throw new WebAuthException_Provider($fullMessage); + } + } + + // If everything went ok, make the network call to get an access token. + + list($accessToken, $userId) = $this->_finish($code, $this->redirectUri); + return array($accessToken, $userId, $urlState); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/WebAuthBase.php b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/WebAuthBase.php new file mode 100644 index 0000000..366bc32 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/WebAuthBase.php @@ -0,0 +1,67 @@ +userLocale, + $this->appInfo->getHost()->getWeb(), + "1/oauth2/authorize", + array( + "client_id" => $this->appInfo->getKey(), + "response_type" => "code", + "redirect_uri" => $redirectUri, + "state" => $state, + "force_reapprove" => $forceReapprove, + )); + } + + protected function _finish($code, $originalRedirectUri) + { + // This endpoint requires "Basic" auth. + $clientCredentials = $this->appInfo->getKey().":".$this->appInfo->getSecret(); + $authHeaderValue = "Basic ".base64_encode($clientCredentials); + + $response = RequestUtil::doPostWithSpecificAuth( + $this->clientIdentifier, $authHeaderValue, $this->userLocale, + $this->appInfo->getHost()->getApi(), + "1/oauth2/token", + array( + "grant_type" => "authorization_code", + "code" => $code, + "redirect_uri" => $originalRedirectUri, + )); + + if ($response->statusCode !== 200) throw RequestUtil::unexpectedStatus($response); + + $parts = RequestUtil::parseResponseJson($response->body); + + if (!array_key_exists('token_type', $parts) || !is_string($parts['token_type'])) { + throw new Exception_BadResponse("Missing \"token_type\" field."); + } + $tokenType = $parts['token_type']; + if (!array_key_exists('access_token', $parts) || !is_string($parts['access_token'])) { + throw new Exception_BadResponse("Missing \"access_token\" field."); + } + $accessToken = $parts['access_token']; + if (!array_key_exists('uid', $parts) || !is_string($parts['uid'])) { + throw new Exception_BadResponse("Missing \"uid\" string field."); + } + $userId = $parts['uid']; + + if ($tokenType !== "Bearer" && $tokenType !== "bearer") { + throw new Exception_BadResponse("Unknown \"token_type\"; expecting \"Bearer\", got " + .Util::q($tokenType)); + } + + return array($accessToken, $userId); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/WebAuthException/BadRequest.php b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/WebAuthException/BadRequest.php new file mode 100644 index 0000000..d77986f --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/WebAuthException/BadRequest.php @@ -0,0 +1,20 @@ + + * use \Dropbox as dbx; + * $appInfo = dbx\AppInfo::loadFromJsonFile(...); + * $clientIdentifier = "my-app/1.0"; + * $webAuth = new dbx\WebAuthNoRedirect($appInfo, $clientIdentifier, ...); + * + * $authorizeUrl = $webAuth->start(); + * + * print("1. Go to: $authorizeUrl\n"); + * print("2. Click "Allow" (you might have to log in first).\n"); + * print("3. Copy the authorization code.\n"); + * print("Enter the authorization code here: "); + * $code = \trim(\fgets(STDIN)); + * + * try { + * list($accessToken, $userId) = $webAuth->finish($code); + * } + * catch (dbx\Exception $ex) { + * print("Error communicating with Dropbox API: " . $ex->getMessage() . "\n"); + * } + * + * $client = dbx\Client($accessToken, $clientIdentifier, ...); + * + */ +class WebAuthNoRedirect extends WebAuthBase +{ + /** + * Returns the URL of the authorization page the user must visit. If the user approves + * your app, they will be shown the authorization code on the web page. They will need to + * copy/paste that code into your application so your app can pass it to + * {@link finish}. + * + * See /oauth2/authorize. + * + * @return string + * An authorization URL. Direct the user's browser to this URL. After the user decides + * whether to authorize your app or not, Dropbox will show the user an authorization code, + * which the user will need to give to your application (e.g. via copy/paste). + */ + function start() + { + return $this->_getAuthorizeUrl(null, null); + } + + /** + * Call this after the user has visited the authorize URL returned by {@link start()}, + * approved your app, was presented with an authorization code by Dropbox, and has copy/paste'd + * that authorization code into your app. + * + * See /oauth2/token. + * + * @param string $code + * The authorization code provided to the user by Dropbox. + * + * @return array + * A `list(string $accessToken, string $userId)`, where + * `$accessToken` can be used to construct a {@link Client} and + * `$userId` is the user ID of the user's Dropbox account. + * + * @throws Exception + * Thrown if there's an error getting the access token from Dropbox. + */ + function finish($code) + { + Checker::argStringNonEmpty("code", $code); + return $this->_finish($code, null); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/WriteMode.php b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/WriteMode.php new file mode 100644 index 0000000..23bd23d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/WriteMode.php @@ -0,0 +1,116 @@ +extraParams = $extraParams; + } + + /** + * @internal + */ + function getExtraParams() + { + return $this->extraParams; + } + + /** + * Returns a {@link WriteMode} for adding a new file. If a file at the specified path already + * exists, the new file will be renamed automatically. + * + * For example, if you're trying to upload a file to "/Notes/Groceries.txt", but there's + * already a file there, your file will be written to "/Notes/Groceries (1).txt". + * + * You can determine whether your file was renamed by checking the "path" field of the + * metadata object returned by the API call. + * + * @return WriteMode + */ + static function add() + { + if (self::$addInstance === null) { + self::$addInstance = new WriteMode(array("overwrite" => "false")); + } + return self::$addInstance; + } + private static $addInstance = null; + + /** + * Returns a {@link WriteMode} for forcing a file to be at a certain path. If there's already + * a file at that path, the existing file will be overwritten. If there's a folder at that + * path, however, it will not be overwritten and the API call will fail. + * + * @return WriteMode + */ + static function force() + { + if (self::$forceInstance === null) { + self::$forceInstance = new WriteMode(array("overwrite" => "true")); + } + return self::$forceInstance; + } + private static $forceInstance = null; + + /** + * Returns a {@link WriteMode} for updating an existing file. This is useful for when you + * have downloaded a file, made modifications, and want to save your modifications back to + * Dropbox. You need to specify the revision of the copy of the file you downloaded (it's + * the "rev" parameter of the file's metadata object). + * + * If, when you attempt to save, the revision of the file currently on Dropbox matches + * $revToReplace, the file on Dropbox will be overwritten with the new contents you provide. + * + * If the revision of the file currently on Dropbox doesn't match $revToReplace, Dropbox will + * create a new file and save your contents to that file. For example, if the original file + * path is "/Notes/Groceries.txt", the new file's path might be + * "/Notes/Groceries (conflicted copy).txt". + * + * You can determine whether your file was renamed by checking the "path" field of the + * metadata object returned by the API call. + * + * @param string $revToReplace + * @return WriteMode + */ + static function update($revToReplace) + { + return new WriteMode(array("parent_rev" => $revToReplace)); + } + + /** + * Check that a function argument is of type `WriteMode`. + * + * @internal + */ + static function checkArg($argName, $argValue) + { + if (!($argValue instanceof self)) Checker::throwError($argName, $argValue, __CLASS__); + } + + /** + * Check that a function argument is either `null` or of type + * `WriteMode`. + * + * @internal + */ + static function checkArgOrNull($argName, $argValue) + { + if ($argValue === null) return; + if (!($argValue instanceof self)) Checker::throwError($argName, $argValue, __CLASS__); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/autoload.php b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/autoload.php new file mode 100644 index 0000000..abb3cd8 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/autoload.php @@ -0,0 +1,31 @@ +/Dropbox/autoload.php" + +/** + * @internal + */ +function autoload($name) +{ + // If the name doesn't start with "Dropbox\", then its not once of our classes. + if (\substr_compare($name, "Dropbox\\", 0, 8) !== 0) return; + + // Take the "Dropbox\" prefix off. + $stem = \substr($name, 8); + + // Convert "\" and "_" to path separators. + $pathified_stem = \str_replace(array("\\", "_"), '/', $stem); + + $path = __DIR__ . "/" . $pathified_stem . ".php"; + if (\is_file($path)) { + require_once $path; + } +} + +\spl_autoload_register('Dropbox\autoload'); diff --git a/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/certs/trusted-certs.crt b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/certs/trusted-certs.crt new file mode 100644 index 0000000..00c2f2e --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/certs/trusted-certs.crt @@ -0,0 +1,1396 @@ +# DigiCert Assured ID Root CA.pem +# Certificate: +# Data: +# Version: 3 (0x2) +# Serial Number: +# 0c:e7:e0:e5:17:d8:46:fe:8f:e5:60:fc:1b:f0:30:39 +# Signature Algorithm: sha1WithRSAEncryption +# Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Assured ID Root CA +# Validity +# Not Before: Nov 10 00:00:00 2006 GMT +# Not After : Nov 10 00:00:00 2031 GMT +# Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Assured ID Root CA +# Subject Public Key Info: +# Public Key Algorithm: rsaEncryption +# Public-Key: (2048 bit) +# Modulus: +# 00:ad:0e:15:ce:e4:43:80:5c:b1:87:f3:b7:60:f9: +# 71:12:a5:ae:dc:26:94:88:aa:f4:ce:f5:20:39:28: +# 58:60:0c:f8:80:da:a9:15:95:32:61:3c:b5:b1:28: +# 84:8a:8a:dc:9f:0a:0c:83:17:7a:8f:90:ac:8a:e7: +# 79:53:5c:31:84:2a:f6:0f:98:32:36:76:cc:de:dd: +# 3c:a8:a2:ef:6a:fb:21:f2:52:61:df:9f:20:d7:1f: +# e2:b1:d9:fe:18:64:d2:12:5b:5f:f9:58:18:35:bc: +# 47:cd:a1:36:f9:6b:7f:d4:b0:38:3e:c1:1b:c3:8c: +# 33:d9:d8:2f:18:fe:28:0f:b3:a7:83:d6:c3:6e:44: +# c0:61:35:96:16:fe:59:9c:8b:76:6d:d7:f1:a2:4b: +# 0d:2b:ff:0b:72:da:9e:60:d0:8e:90:35:c6:78:55: +# 87:20:a1:cf:e5:6d:0a:c8:49:7c:31:98:33:6c:22: +# e9:87:d0:32:5a:a2:ba:13:82:11:ed:39:17:9d:99: +# 3a:72:a1:e6:fa:a4:d9:d5:17:31:75:ae:85:7d:22: +# ae:3f:01:46:86:f6:28:79:c8:b1:da:e4:57:17:c4: +# 7e:1c:0e:b0:b4:92:a6:56:b3:bd:b2:97:ed:aa:a7: +# f0:b7:c5:a8:3f:95:16:d0:ff:a1:96:eb:08:5f:18: +# 77:4f +# Exponent: 65537 (0x10001) +# X509v3 extensions: +# X509v3 Key Usage: critical +# Digital Signature, Certificate Sign, CRL Sign +# X509v3 Basic Constraints: critical +# CA:TRUE +# X509v3 Subject Key Identifier: +# 45:EB:A2:AF:F4:92:CB:82:31:2D:51:8B:A7:A7:21:9D:F3:6D:C8:0F +# X509v3 Authority Key Identifier: +# keyid:45:EB:A2:AF:F4:92:CB:82:31:2D:51:8B:A7:A7:21:9D:F3:6D:C8:0F +# +# Signature Algorithm: sha1WithRSAEncryption +# a2:0e:bc:df:e2:ed:f0:e3:72:73:7a:64:94:bf:f7:72:66:d8: +# 32:e4:42:75:62:ae:87:eb:f2:d5:d9:de:56:b3:9f:cc:ce:14: +# 28:b9:0d:97:60:5c:12:4c:58:e4:d3:3d:83:49:45:58:97:35: +# 69:1a:a8:47:ea:56:c6:79:ab:12:d8:67:81:84:df:7f:09:3c: +# 94:e6:b8:26:2c:20:bd:3d:b3:28:89:f7:5f:ff:22:e2:97:84: +# 1f:e9:65:ef:87:e0:df:c1:67:49:b3:5d:eb:b2:09:2a:eb:26: +# ed:78:be:7d:3f:2b:f3:b7:26:35:6d:5f:89:01:b6:49:5b:9f: +# 01:05:9b:ab:3d:25:c1:cc:b6:7f:c2:f1:6f:86:c6:fa:64:68: +# eb:81:2d:94:eb:42:b7:fa:8c:1e:dd:62:f1:be:50:67:b7:6c: +# bd:f3:f1:1f:6b:0c:36:07:16:7f:37:7c:a9:5b:6d:7a:f1:12: +# 46:60:83:d7:27:04:be:4b:ce:97:be:c3:67:2a:68:11:df:80: +# e7:0c:33:66:bf:13:0d:14:6e:f3:7f:1f:63:10:1e:fa:8d:1b: +# 25:6d:6c:8f:a5:b7:61:01:b1:d2:a3:26:a1:10:71:9d:ad:e2: +# c3:f9:c3:99:51:b7:2b:07:08:ce:2e:e6:50:b2:a7:fa:0a:45: +# 2f:a2:f0:f2 +-----BEGIN CERTIFICATE----- +MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv +b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl +cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c +JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP +mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+ +wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4 +VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/ +AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB +AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW +BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun +pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC +dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf +fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm +NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx +H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe ++o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g== +-----END CERTIFICATE----- +# DigiCert Global Root CA.pem +# Certificate: +# Data: +# Version: 3 (0x2) +# Serial Number: +# 08:3b:e0:56:90:42:46:b1:a1:75:6a:c9:59:91:c7:4a +# Signature Algorithm: sha1WithRSAEncryption +# Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root CA +# Validity +# Not Before: Nov 10 00:00:00 2006 GMT +# Not After : Nov 10 00:00:00 2031 GMT +# Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root CA +# Subject Public Key Info: +# Public Key Algorithm: rsaEncryption +# Public-Key: (2048 bit) +# Modulus: +# 00:e2:3b:e1:11:72:de:a8:a4:d3:a3:57:aa:50:a2: +# 8f:0b:77:90:c9:a2:a5:ee:12:ce:96:5b:01:09:20: +# cc:01:93:a7:4e:30:b7:53:f7:43:c4:69:00:57:9d: +# e2:8d:22:dd:87:06:40:00:81:09:ce:ce:1b:83:bf: +# df:cd:3b:71:46:e2:d6:66:c7:05:b3:76:27:16:8f: +# 7b:9e:1e:95:7d:ee:b7:48:a3:08:da:d6:af:7a:0c: +# 39:06:65:7f:4a:5d:1f:bc:17:f8:ab:be:ee:28:d7: +# 74:7f:7a:78:99:59:85:68:6e:5c:23:32:4b:bf:4e: +# c0:e8:5a:6d:e3:70:bf:77:10:bf:fc:01:f6:85:d9: +# a8:44:10:58:32:a9:75:18:d5:d1:a2:be:47:e2:27: +# 6a:f4:9a:33:f8:49:08:60:8b:d4:5f:b4:3a:84:bf: +# a1:aa:4a:4c:7d:3e:cf:4f:5f:6c:76:5e:a0:4b:37: +# 91:9e:dc:22:e6:6d:ce:14:1a:8e:6a:cb:fe:cd:b3: +# 14:64:17:c7:5b:29:9e:32:bf:f2:ee:fa:d3:0b:42: +# d4:ab:b7:41:32:da:0c:d4:ef:f8:81:d5:bb:8d:58: +# 3f:b5:1b:e8:49:28:a2:70:da:31:04:dd:f7:b2:16: +# f2:4c:0a:4e:07:a8:ed:4a:3d:5e:b5:7f:a3:90:c3: +# af:27 +# Exponent: 65537 (0x10001) +# X509v3 extensions: +# X509v3 Key Usage: critical +# Digital Signature, Certificate Sign, CRL Sign +# X509v3 Basic Constraints: critical +# CA:TRUE +# X509v3 Subject Key Identifier: +# 03:DE:50:35:56:D1:4C:BB:66:F0:A3:E2:1B:1B:C3:97:B2:3D:D1:55 +# X509v3 Authority Key Identifier: +# keyid:03:DE:50:35:56:D1:4C:BB:66:F0:A3:E2:1B:1B:C3:97:B2:3D:D1:55 +# +# Signature Algorithm: sha1WithRSAEncryption +# cb:9c:37:aa:48:13:12:0a:fa:dd:44:9c:4f:52:b0:f4:df:ae: +# 04:f5:79:79:08:a3:24:18:fc:4b:2b:84:c0:2d:b9:d5:c7:fe: +# f4:c1:1f:58:cb:b8:6d:9c:7a:74:e7:98:29:ab:11:b5:e3:70: +# a0:a1:cd:4c:88:99:93:8c:91:70:e2:ab:0f:1c:be:93:a9:ff: +# 63:d5:e4:07:60:d3:a3:bf:9d:5b:09:f1:d5:8e:e3:53:f4:8e: +# 63:fa:3f:a7:db:b4:66:df:62:66:d6:d1:6e:41:8d:f2:2d:b5: +# ea:77:4a:9f:9d:58:e2:2b:59:c0:40:23:ed:2d:28:82:45:3e: +# 79:54:92:26:98:e0:80:48:a8:37:ef:f0:d6:79:60:16:de:ac: +# e8:0e:cd:6e:ac:44:17:38:2f:49:da:e1:45:3e:2a:b9:36:53: +# cf:3a:50:06:f7:2e:e8:c4:57:49:6c:61:21:18:d5:04:ad:78: +# 3c:2c:3a:80:6b:a7:eb:af:15:14:e9:d8:89:c1:b9:38:6c:e2: +# 91:6c:8a:ff:64:b9:77:25:57:30:c0:1b:24:a3:e1:dc:e9:df: +# 47:7c:b5:b4:24:08:05:30:ec:2d:bd:0b:bf:45:bf:50:b9:a9: +# f3:eb:98:01:12:ad:c8:88:c6:98:34:5f:8d:0a:3c:c6:e9:d5: +# 95:95:6d:de +-----BEGIN CERTIFICATE----- +MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD +QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB +CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 +nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt +43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P +T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 +gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR +TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw +DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr +hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg +06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF +PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls +YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk +CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= +-----END CERTIFICATE----- +# DigiCert High Assurance EV Root CA.pem +# Certificate: +# Data: +# Version: 3 (0x2) +# Serial Number: +# 02:ac:5c:26:6a:0b:40:9b:8f:0b:79:f2:ae:46:25:77 +# Signature Algorithm: sha1WithRSAEncryption +# Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert High Assurance EV Root CA +# Validity +# Not Before: Nov 10 00:00:00 2006 GMT +# Not After : Nov 10 00:00:00 2031 GMT +# Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert High Assurance EV Root CA +# Subject Public Key Info: +# Public Key Algorithm: rsaEncryption +# Public-Key: (2048 bit) +# Modulus: +# 00:c6:cc:e5:73:e6:fb:d4:bb:e5:2d:2d:32:a6:df: +# e5:81:3f:c9:cd:25:49:b6:71:2a:c3:d5:94:34:67: +# a2:0a:1c:b0:5f:69:a6:40:b1:c4:b7:b2:8f:d0:98: +# a4:a9:41:59:3a:d3:dc:94:d6:3c:db:74:38:a4:4a: +# cc:4d:25:82:f7:4a:a5:53:12:38:ee:f3:49:6d:71: +# 91:7e:63:b6:ab:a6:5f:c3:a4:84:f8:4f:62:51:be: +# f8:c5:ec:db:38:92:e3:06:e5:08:91:0c:c4:28:41: +# 55:fb:cb:5a:89:15:7e:71:e8:35:bf:4d:72:09:3d: +# be:3a:38:50:5b:77:31:1b:8d:b3:c7:24:45:9a:a7: +# ac:6d:00:14:5a:04:b7:ba:13:eb:51:0a:98:41:41: +# 22:4e:65:61:87:81:41:50:a6:79:5c:89:de:19:4a: +# 57:d5:2e:e6:5d:1c:53:2c:7e:98:cd:1a:06:16:a4: +# 68:73:d0:34:04:13:5c:a1:71:d3:5a:7c:55:db:5e: +# 64:e1:37:87:30:56:04:e5:11:b4:29:80:12:f1:79: +# 39:88:a2:02:11:7c:27:66:b7:88:b7:78:f2:ca:0a: +# a8:38:ab:0a:64:c2:bf:66:5d:95:84:c1:a1:25:1e: +# 87:5d:1a:50:0b:20:12:cc:41:bb:6e:0b:51:38:b8: +# 4b:cb +# Exponent: 65537 (0x10001) +# X509v3 extensions: +# X509v3 Key Usage: critical +# Digital Signature, Certificate Sign, CRL Sign +# X509v3 Basic Constraints: critical +# CA:TRUE +# X509v3 Subject Key Identifier: +# B1:3E:C3:69:03:F8:BF:47:01:D4:98:26:1A:08:02:EF:63:64:2B:C3 +# X509v3 Authority Key Identifier: +# keyid:B1:3E:C3:69:03:F8:BF:47:01:D4:98:26:1A:08:02:EF:63:64:2B:C3 +# +# Signature Algorithm: sha1WithRSAEncryption +# 1c:1a:06:97:dc:d7:9c:9f:3c:88:66:06:08:57:21:db:21:47: +# f8:2a:67:aa:bf:18:32:76:40:10:57:c1:8a:f3:7a:d9:11:65: +# 8e:35:fa:9e:fc:45:b5:9e:d9:4c:31:4b:b8:91:e8:43:2c:8e: +# b3:78:ce:db:e3:53:79:71:d6:e5:21:94:01:da:55:87:9a:24: +# 64:f6:8a:66:cc:de:9c:37:cd:a8:34:b1:69:9b:23:c8:9e:78: +# 22:2b:70:43:e3:55:47:31:61:19:ef:58:c5:85:2f:4e:30:f6: +# a0:31:16:23:c8:e7:e2:65:16:33:cb:bf:1a:1b:a0:3d:f8:ca: +# 5e:8b:31:8b:60:08:89:2d:0c:06:5c:52:b7:c4:f9:0a:98:d1: +# 15:5f:9f:12:be:7c:36:63:38:bd:44:a4:7f:e4:26:2b:0a:c4: +# 97:69:0d:e9:8c:e2:c0:10:57:b8:c8:76:12:91:55:f2:48:69: +# d8:bc:2a:02:5b:0f:44:d4:20:31:db:f4:ba:70:26:5d:90:60: +# 9e:bc:4b:17:09:2f:b4:cb:1e:43:68:c9:07:27:c1:d2:5c:f7: +# ea:21:b9:68:12:9c:3c:9c:bf:9e:fc:80:5c:9b:63:cd:ec:47: +# aa:25:27:67:a0:37:f3:00:82:7d:54:d7:a9:f8:e9:2e:13:a3: +# 77:e8:1f:4a +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j +ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL +MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 +LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug +RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm ++9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW +PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM +xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB +Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3 +hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg +EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA +FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec +nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z +eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF +hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2 +Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe +vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep ++OkuE6N36B9K +-----END CERTIFICATE----- +# Entrust Root Certification Authority - EC1.pem +# Certificate: +# Data: +# Version: 3 (0x2) +# Serial Number: +# a6:8b:79:29:00:00:00:00:50:d0:91:f9 +# Signature Algorithm: ecdsa-with-SHA384 +# Issuer: C=US, O=Entrust, Inc., OU=See www.entrust.net/legal-terms, OU=(c) 2012 Entrust, Inc. - for authorized use only, CN=Entrust Root Certification Authority - EC1 +# Validity +# Not Before: Dec 18 15:25:36 2012 GMT +# Not After : Dec 18 15:55:36 2037 GMT +# Subject: C=US, O=Entrust, Inc., OU=See www.entrust.net/legal-terms, OU=(c) 2012 Entrust, Inc. - for authorized use only, CN=Entrust Root Certification Authority - EC1 +# Subject Public Key Info: +# Public Key Algorithm: id-ecPublicKey +# Public-Key: (384 bit) +# pub: +# 04:84:13:c9:d0:ba:6d:41:7b:e2:6c:d0:eb:55:5f: +# 66:02:1a:24:f4:5b:89:69:47:e3:b8:c2:7d:f1:f2: +# 02:c5:9f:a0:f6:5b:d5:8b:06:19:86:4f:53:10:6d: +# 07:24:27:a1:a0:f8:d5:47:19:61:4c:7d:ca:93:27: +# ea:74:0c:ef:6f:96:09:fe:63:ec:70:5d:36:ad:67: +# 77:ae:c9:9d:7c:55:44:3a:a2:63:51:1f:f5:e3:62: +# d4:a9:47:07:3e:cc:20 +# ASN1 OID: secp384r1 +# X509v3 extensions: +# X509v3 Key Usage: critical +# Certificate Sign, CRL Sign +# X509v3 Basic Constraints: critical +# CA:TRUE +# X509v3 Subject Key Identifier: +# B7:63:E7:1A:DD:8D:E9:08:A6:55:83:A4:E0:6A:50:41:65:11:42:49 +# Signature Algorithm: ecdsa-with-SHA384 +# 30:64:02:30:61:79:d8:e5:42:47:df:1c:ae:53:99:17:b6:6f: +# 1c:7d:e1:bf:11:94:d1:03:88:75:e4:8d:89:a4:8a:77:46:de: +# 6d:61:ef:02:f5:fb:b5:df:cc:fe:4e:ff:fe:a9:e6:a7:02:30: +# 5b:99:d7:85:37:06:b5:7b:08:fd:eb:27:8b:4a:94:f9:e1:fa: +# a7:8e:26:08:e8:7c:92:68:6d:73:d8:6f:26:ac:21:02:b8:99: +# b7:26:41:5b:25:60:ae:d0:48:1a:ee:06 +-----BEGIN CERTIFICATE----- +MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkG +A1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3 +d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVu +dHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEzMDEGA1UEAxMq +RW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRUMxMB4XDTEy +MTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYwFAYD +VQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0 +L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0g +Zm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBD +ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEVDMTB2MBAGByqGSM49AgEGBSuBBAAi +A2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHyAsWfoPZb1YsGGYZPUxBt +ByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef9eNi1KlH +Bz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O +BBYEFLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVC +R98crlOZF7ZvHH3hvxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nX +hTcGtXsI/esni0qU+eH6p44mCOh8kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G +-----END CERTIFICATE----- +# Entrust Root Certification Authority - G2.pem +# Certificate: +# Data: +# Version: 3 (0x2) +# Serial Number: 1246989352 (0x4a538c28) +# Signature Algorithm: sha256WithRSAEncryption +# Issuer: C=US, O=Entrust, Inc., OU=See www.entrust.net/legal-terms, OU=(c) 2009 Entrust, Inc. - for authorized use only, CN=Entrust Root Certification Authority - G2 +# Validity +# Not Before: Jul 7 17:25:54 2009 GMT +# Not After : Dec 7 17:55:54 2030 GMT +# Subject: C=US, O=Entrust, Inc., OU=See www.entrust.net/legal-terms, OU=(c) 2009 Entrust, Inc. - for authorized use only, CN=Entrust Root Certification Authority - G2 +# Subject Public Key Info: +# Public Key Algorithm: rsaEncryption +# Public-Key: (2048 bit) +# Modulus: +# 00:ba:84:b6:72:db:9e:0c:6b:e2:99:e9:30:01:a7: +# 76:ea:32:b8:95:41:1a:c9:da:61:4e:58:72:cf:fe: +# f6:82:79:bf:73:61:06:0a:a5:27:d8:b3:5f:d3:45: +# 4e:1c:72:d6:4e:32:f2:72:8a:0f:f7:83:19:d0:6a: +# 80:80:00:45:1e:b0:c7:e7:9a:bf:12:57:27:1c:a3: +# 68:2f:0a:87:bd:6a:6b:0e:5e:65:f3:1c:77:d5:d4: +# 85:8d:70:21:b4:b3:32:e7:8b:a2:d5:86:39:02:b1: +# b8:d2:47:ce:e4:c9:49:c4:3b:a7:de:fb:54:7d:57: +# be:f0:e8:6e:c2:79:b2:3a:0b:55:e2:50:98:16:32: +# 13:5c:2f:78:56:c1:c2:94:b3:f2:5a:e4:27:9a:9f: +# 24:d7:c6:ec:d0:9b:25:82:e3:cc:c2:c4:45:c5:8c: +# 97:7a:06:6b:2a:11:9f:a9:0a:6e:48:3b:6f:db:d4: +# 11:19:42:f7:8f:07:bf:f5:53:5f:9c:3e:f4:17:2c: +# e6:69:ac:4e:32:4c:62:77:ea:b7:e8:e5:bb:34:bc: +# 19:8b:ae:9c:51:e7:b7:7e:b5:53:b1:33:22:e5:6d: +# cf:70:3c:1a:fa:e2:9b:67:b6:83:f4:8d:a5:af:62: +# 4c:4d:e0:58:ac:64:34:12:03:f8:b6:8d:94:63:24: +# a4:71 +# Exponent: 65537 (0x10001) +# X509v3 extensions: +# X509v3 Key Usage: critical +# Certificate Sign, CRL Sign +# X509v3 Basic Constraints: critical +# CA:TRUE +# X509v3 Subject Key Identifier: +# 6A:72:26:7A:D0:1E:EF:7D:E7:3B:69:51:D4:6C:8D:9F:90:12:66:AB +# Signature Algorithm: sha256WithRSAEncryption +# 79:9f:1d:96:c6:b6:79:3f:22:8d:87:d3:87:03:04:60:6a:6b: +# 9a:2e:59:89:73:11:ac:43:d1:f5:13:ff:8d:39:2b:c0:f2:bd: +# 4f:70:8c:a9:2f:ea:17:c4:0b:54:9e:d4:1b:96:98:33:3c:a8: +# ad:62:a2:00:76:ab:59:69:6e:06:1d:7e:c4:b9:44:8d:98:af: +# 12:d4:61:db:0a:19:46:47:f3:eb:f7:63:c1:40:05:40:a5:d2: +# b7:f4:b5:9a:36:bf:a9:88:76:88:04:55:04:2b:9c:87:7f:1a: +# 37:3c:7e:2d:a5:1a:d8:d4:89:5e:ca:bd:ac:3d:6c:d8:6d:af: +# d5:f3:76:0f:cd:3b:88:38:22:9d:6c:93:9a:c4:3d:bf:82:1b: +# 65:3f:a6:0f:5d:aa:fc:e5:b2:15:ca:b5:ad:c6:bc:3d:d0:84: +# e8:ea:06:72:b0:4d:39:32:78:bf:3e:11:9c:0b:a4:9d:9a:21: +# f3:f0:9b:0b:30:78:db:c1:dc:87:43:fe:bc:63:9a:ca:c5:c2: +# 1c:c9:c7:8d:ff:3b:12:58:08:e6:b6:3d:ec:7a:2c:4e:fb:83: +# 96:ce:0c:3c:69:87:54:73:a4:73:c2:93:ff:51:10:ac:15:54: +# 01:d8:fc:05:b1:89:a1:7f:74:83:9a:49:d7:dc:4e:7b:8a:48: +# 6f:8b:45:f6 +-----BEGIN CERTIFICATE----- +MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50 +cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs +IEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz +dCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMDkwNzA3MTcy +NTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu +dHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt +dGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0 +aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP/vaCeb9zYQYKpSfYs1/T +RU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXzHHfV1IWN +cCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hW +wcKUs/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1 +U1+cPvQXLOZprE4yTGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0 +jaWvYkxN4FisZDQSA/i2jZRjJKRxAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ60B7vfec7aVHUbI2fkBJmqzAN +BgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5ZiXMRrEPR9RP/ +jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ +Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v +1fN2D807iDginWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4R +nAuknZoh8/CbCzB428Hch0P+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmH +VHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xOe4pIb4tF9g== +-----END CERTIFICATE----- +# Entrust Root Certification Authority.pem +# Certificate: +# Data: +# Version: 3 (0x2) +# Serial Number: 1164660820 (0x456b5054) +# Signature Algorithm: sha1WithRSAEncryption +# Issuer: C=US, O=Entrust, Inc., OU=www.entrust.net/CPS is incorporated by reference, OU=(c) 2006 Entrust, Inc., CN=Entrust Root Certification Authority +# Validity +# Not Before: Nov 27 20:23:42 2006 GMT +# Not After : Nov 27 20:53:42 2026 GMT +# Subject: C=US, O=Entrust, Inc., OU=www.entrust.net/CPS is incorporated by reference, OU=(c) 2006 Entrust, Inc., CN=Entrust Root Certification Authority +# Subject Public Key Info: +# Public Key Algorithm: rsaEncryption +# Public-Key: (2048 bit) +# Modulus: +# 00:b6:95:b6:43:42:fa:c6:6d:2a:6f:48:df:94:4c: +# 39:57:05:ee:c3:79:11:41:68:36:ed:ec:fe:9a:01: +# 8f:a1:38:28:fc:f7:10:46:66:2e:4d:1e:1a:b1:1a: +# 4e:c6:d1:c0:95:88:b0:c9:ff:31:8b:33:03:db:b7: +# 83:7b:3e:20:84:5e:ed:b2:56:28:a7:f8:e0:b9:40: +# 71:37:c5:cb:47:0e:97:2a:68:c0:22:95:62:15:db: +# 47:d9:f5:d0:2b:ff:82:4b:c9:ad:3e:de:4c:db:90: +# 80:50:3f:09:8a:84:00:ec:30:0a:3d:18:cd:fb:fd: +# 2a:59:9a:23:95:17:2c:45:9e:1f:6e:43:79:6d:0c: +# 5c:98:fe:48:a7:c5:23:47:5c:5e:fd:6e:e7:1e:b4: +# f6:68:45:d1:86:83:5b:a2:8a:8d:b1:e3:29:80:fe: +# 25:71:88:ad:be:bc:8f:ac:52:96:4b:aa:51:8d:e4: +# 13:31:19:e8:4e:4d:9f:db:ac:b3:6a:d5:bc:39:54: +# 71:ca:7a:7a:7f:90:dd:7d:1d:80:d9:81:bb:59:26: +# c2:11:fe:e6:93:e2:f7:80:e4:65:fb:34:37:0e:29: +# 80:70:4d:af:38:86:2e:9e:7f:57:af:9e:17:ae:eb: +# 1c:cb:28:21:5f:b6:1c:d8:e7:a2:04:22:f9:d3:da: +# d8:cb +# Exponent: 65537 (0x10001) +# X509v3 extensions: +# X509v3 Key Usage: critical +# Certificate Sign, CRL Sign +# X509v3 Basic Constraints: critical +# CA:TRUE +# X509v3 Private Key Usage Period: +# Not Before: Nov 27 20:23:42 2006 GMT, Not After: Nov 27 20:53:42 2026 GMT +# X509v3 Authority Key Identifier: +# keyid:68:90:E4:67:A4:A6:53:80:C7:86:66:A4:F1:F7:4B:43:FB:84:BD:6D +# +# X509v3 Subject Key Identifier: +# 68:90:E4:67:A4:A6:53:80:C7:86:66:A4:F1:F7:4B:43:FB:84:BD:6D +# 1.2.840.113533.7.65.0: +# 0...V7.1:4.0.... +# Signature Algorithm: sha1WithRSAEncryption +# 93:d4:30:b0:d7:03:20:2a:d0:f9:63:e8:91:0c:05:20:a9:5f: +# 19:ca:7b:72:4e:d4:b1:db:d0:96:fb:54:5a:19:2c:0c:08:f7: +# b2:bc:85:a8:9d:7f:6d:3b:52:b3:2a:db:e7:d4:84:8c:63:f6: +# 0f:cb:26:01:91:50:6c:f4:5f:14:e2:93:74:c0:13:9e:30:3a: +# 50:e3:b4:60:c5:1c:f0:22:44:8d:71:47:ac:c8:1a:c9:e9:9b: +# 9a:00:60:13:ff:70:7e:5f:11:4d:49:1b:b3:15:52:7b:c9:54: +# da:bf:9d:95:af:6b:9a:d8:9e:e9:f1:e4:43:8d:e2:11:44:3a: +# bf:af:bd:83:42:73:52:8b:aa:bb:a7:29:cf:f5:64:1c:0a:4d: +# d1:bc:aa:ac:9f:2a:d0:ff:7f:7f:da:7d:ea:b1:ed:30:25:c1: +# 84:da:34:d2:5b:78:83:56:ec:9c:36:c3:26:e2:11:f6:67:49: +# 1d:92:ab:8c:fb:eb:ff:7a:ee:85:4a:a7:50:80:f0:a7:5c:4a: +# 94:2e:5f:05:99:3c:52:41:e0:cd:b4:63:cf:01:43:ba:9c:83: +# dc:8f:60:3b:f3:5a:b4:b4:7b:ae:da:0b:90:38:75:ef:81:1d: +# 66:d2:f7:57:70:36:b3:bf:fc:28:af:71:25:85:5b:13:fe:1e: +# 7f:5a:b4:3c +-----BEGIN CERTIFICATE----- +MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0 +Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW +KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl +cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw +NTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw +NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy +ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV +BAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo +Nu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4 +4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9 +KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI +rb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi +94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB +sDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi +gA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo +kORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE +vW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA +A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t +O1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua +AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP +9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/ +eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m +0vdXcDazv/wor3ElhVsT/h5/WrQ8 +-----END CERTIFICATE----- +# Entrust.net Certification Authority (2048).pem +# Certificate: +# Data: +# Version: 3 (0x2) +# Serial Number: 946069240 (0x3863def8) +# Signature Algorithm: sha1WithRSAEncryption +# Issuer: O=Entrust.net, OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.), OU=(c) 1999 Entrust.net Limited, CN=Entrust.net Certification Authority (2048) +# Validity +# Not Before: Dec 24 17:50:51 1999 GMT +# Not After : Jul 24 14:15:12 2029 GMT +# Subject: O=Entrust.net, OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.), OU=(c) 1999 Entrust.net Limited, CN=Entrust.net Certification Authority (2048) +# Subject Public Key Info: +# Public Key Algorithm: rsaEncryption +# Public-Key: (2048 bit) +# Modulus: +# 00:ad:4d:4b:a9:12:86:b2:ea:a3:20:07:15:16:64: +# 2a:2b:4b:d1:bf:0b:4a:4d:8e:ed:80:76:a5:67:b7: +# 78:40:c0:73:42:c8:68:c0:db:53:2b:dd:5e:b8:76: +# 98:35:93:8b:1a:9d:7c:13:3a:0e:1f:5b:b7:1e:cf: +# e5:24:14:1e:b1:81:a9:8d:7d:b8:cc:6b:4b:03:f1: +# 02:0c:dc:ab:a5:40:24:00:7f:74:94:a1:9d:08:29: +# b3:88:0b:f5:87:77:9d:55:cd:e4:c3:7e:d7:6a:64: +# ab:85:14:86:95:5b:97:32:50:6f:3d:c8:ba:66:0c: +# e3:fc:bd:b8:49:c1:76:89:49:19:fd:c0:a8:bd:89: +# a3:67:2f:c6:9f:bc:71:19:60:b8:2d:e9:2c:c9:90: +# 76:66:7b:94:e2:af:78:d6:65:53:5d:3c:d6:9c:b2: +# cf:29:03:f9:2f:a4:50:b2:d4:48:ce:05:32:55:8a: +# fd:b2:64:4c:0e:e4:98:07:75:db:7f:df:b9:08:55: +# 60:85:30:29:f9:7b:48:a4:69:86:e3:35:3f:1e:86: +# 5d:7a:7a:15:bd:ef:00:8e:15:22:54:17:00:90:26: +# 93:bc:0e:49:68:91:bf:f8:47:d3:9d:95:42:c1:0e: +# 4d:df:6f:26:cf:c3:18:21:62:66:43:70:d6:d5:c0: +# 07:e1 +# Exponent: 65537 (0x10001) +# X509v3 extensions: +# X509v3 Key Usage: critical +# Certificate Sign, CRL Sign +# X509v3 Basic Constraints: critical +# CA:TRUE +# X509v3 Subject Key Identifier: +# 55:E4:81:D1:11:80:BE:D8:89:B9:08:A3:31:F9:A1:24:09:16:B9:70 +# Signature Algorithm: sha1WithRSAEncryption +# 3b:9b:8f:56:9b:30:e7:53:99:7c:7a:79:a7:4d:97:d7:19:95: +# 90:fb:06:1f:ca:33:7c:46:63:8f:96:66:24:fa:40:1b:21:27: +# ca:e6:72:73:f2:4f:fe:31:99:fd:c8:0c:4c:68:53:c6:80:82: +# 13:98:fa:b6:ad:da:5d:3d:f1:ce:6e:f6:15:11:94:82:0c:ee: +# 3f:95:af:11:ab:0f:d7:2f:de:1f:03:8f:57:2c:1e:c9:bb:9a: +# 1a:44:95:eb:18:4f:a6:1f:cd:7d:57:10:2f:9b:04:09:5a:84: +# b5:6e:d8:1d:3a:e1:d6:9e:d1:6c:79:5e:79:1c:14:c5:e3:d0: +# 4c:93:3b:65:3c:ed:df:3d:be:a6:e5:95:1a:c3:b5:19:c3:bd: +# 5e:5b:bb:ff:23:ef:68:19:cb:12:93:27:5c:03:2d:6f:30:d0: +# 1e:b6:1a:ac:de:5a:f7:d1:aa:a8:27:a6:fe:79:81:c4:79:99: +# 33:57:ba:12:b0:a9:e0:42:6c:93:ca:56:de:fe:6d:84:0b:08: +# 8b:7e:8d:ea:d7:98:21:c6:f3:e7:3c:79:2f:5e:9c:d1:4c:15: +# 8d:e1:ec:22:37:cc:9a:43:0b:97:dc:80:90:8d:b3:67:9b:6f: +# 48:08:15:56:cf:bf:f1:2b:7c:5e:9a:76:e9:59:90:c5:7c:83: +# 35:11:65:51 +-----BEGIN CERTIFICATE----- +MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML +RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp +bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5 +IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0yOTA3 +MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3 +LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp +YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG +A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq +K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe +sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX +MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT +XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/ +HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH +4QIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJKoZIhvcNAQEFBQADggEBADub +j1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPyT/4xmf3IDExo +U8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf +zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5b +u/8j72gZyxKTJ1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+ +bYQLCIt+jerXmCHG8+c8eS9enNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/Er +fF6adulZkMV8gzURZVE= +-----END CERTIFICATE----- +# GeoTrust Global CA.pem +# Certificate: +# Data: +# Version: 3 (0x2) +# Serial Number: 144470 (0x23456) +# Signature Algorithm: sha1WithRSAEncryption +# Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA +# Validity +# Not Before: May 21 04:00:00 2002 GMT +# Not After : May 21 04:00:00 2022 GMT +# Subject: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA +# Subject Public Key Info: +# Public Key Algorithm: rsaEncryption +# Public-Key: (2048 bit) +# Modulus: +# 00:da:cc:18:63:30:fd:f4:17:23:1a:56:7e:5b:df: +# 3c:6c:38:e4:71:b7:78:91:d4:bc:a1:d8:4c:f8:a8: +# 43:b6:03:e9:4d:21:07:08:88:da:58:2f:66:39:29: +# bd:05:78:8b:9d:38:e8:05:b7:6a:7e:71:a4:e6:c4: +# 60:a6:b0:ef:80:e4:89:28:0f:9e:25:d6:ed:83:f3: +# ad:a6:91:c7:98:c9:42:18:35:14:9d:ad:98:46:92: +# 2e:4f:ca:f1:87:43:c1:16:95:57:2d:50:ef:89:2d: +# 80:7a:57:ad:f2:ee:5f:6b:d2:00:8d:b9:14:f8:14: +# 15:35:d9:c0:46:a3:7b:72:c8:91:bf:c9:55:2b:cd: +# d0:97:3e:9c:26:64:cc:df:ce:83:19:71:ca:4e:e6: +# d4:d5:7b:a9:19:cd:55:de:c8:ec:d2:5e:38:53:e5: +# 5c:4f:8c:2d:fe:50:23:36:fc:66:e6:cb:8e:a4:39: +# 19:00:b7:95:02:39:91:0b:0e:fe:38:2e:d1:1d:05: +# 9a:f6:4d:3e:6f:0f:07:1d:af:2c:1e:8f:60:39:e2: +# fa:36:53:13:39:d4:5e:26:2b:db:3d:a8:14:bd:32: +# eb:18:03:28:52:04:71:e5:ab:33:3d:e1:38:bb:07: +# 36:84:62:9c:79:ea:16:30:f4:5f:c0:2b:e8:71:6b: +# e4:f9 +# Exponent: 65537 (0x10001) +# X509v3 extensions: +# X509v3 Basic Constraints: critical +# CA:TRUE +# X509v3 Subject Key Identifier: +# C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E +# X509v3 Authority Key Identifier: +# keyid:C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E +# +# Signature Algorithm: sha1WithRSAEncryption +# 35:e3:29:6a:e5:2f:5d:54:8e:29:50:94:9f:99:1a:14:e4:8f: +# 78:2a:62:94:a2:27:67:9e:d0:cf:1a:5e:47:e9:c1:b2:a4:cf: +# dd:41:1a:05:4e:9b:4b:ee:4a:6f:55:52:b3:24:a1:37:0a:eb: +# 64:76:2a:2e:2c:f3:fd:3b:75:90:bf:fa:71:d8:c7:3d:37:d2: +# b5:05:95:62:b9:a6:de:89:3d:36:7b:38:77:48:97:ac:a6:20: +# 8f:2e:a6:c9:0c:c2:b2:99:45:00:c7:ce:11:51:22:22:e0:a5: +# ea:b6:15:48:09:64:ea:5e:4f:74:f7:05:3e:c7:8a:52:0c:db: +# 15:b4:bd:6d:9b:e5:c6:b1:54:68:a9:e3:69:90:b6:9a:a5:0f: +# b8:b9:3f:20:7d:ae:4a:b5:b8:9c:e4:1d:b6:ab:e6:94:a5:c1: +# c7:83:ad:db:f5:27:87:0e:04:6c:d5:ff:dd:a0:5d:ed:87:52: +# b7:2b:15:02:ae:39:a6:6a:74:e9:da:c4:e7:bc:4d:34:1e:a9: +# 5c:4d:33:5f:92:09:2f:88:66:5d:77:97:c7:1d:76:13:a9:d5: +# e5:f1:16:09:11:35:d5:ac:db:24:71:70:2c:98:56:0b:d9:17: +# b4:d1:e3:51:2b:5e:75:e8:d5:d0:dc:4f:34:ed:c2:05:66:80: +# a1:cb:e6:33 +-----BEGIN CERTIFICATE----- +MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT +MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i +YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG +EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg +R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9 +9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq +fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv +iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU +1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+ +bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW +MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA +ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l +uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn +Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS +tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF +PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un +hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV +5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw== +-----END CERTIFICATE----- +# GeoTrust Primary Certification Authority - G2.pem +# Certificate: +# Data: +# Version: 3 (0x2) +# Serial Number: +# 3c:b2:f4:48:0a:00:e2:fe:eb:24:3b:5e:60:3e:c3:6b +# Signature Algorithm: ecdsa-with-SHA384 +# Issuer: C=US, O=GeoTrust Inc., OU=(c) 2007 GeoTrust Inc. - For authorized use only, CN=GeoTrust Primary Certification Authority - G2 +# Validity +# Not Before: Nov 5 00:00:00 2007 GMT +# Not After : Jan 18 23:59:59 2038 GMT +# Subject: C=US, O=GeoTrust Inc., OU=(c) 2007 GeoTrust Inc. - For authorized use only, CN=GeoTrust Primary Certification Authority - G2 +# Subject Public Key Info: +# Public Key Algorithm: id-ecPublicKey +# Public-Key: (384 bit) +# pub: +# 04:15:b1:e8:fd:03:15:43:e5:ac:eb:87:37:11:62: +# ef:d2:83:36:52:7d:45:57:0b:4a:8d:7b:54:3b:3a: +# 6e:5f:15:02:c0:50:a6:cf:25:2f:7d:ca:48:b8:c7: +# 50:63:1c:2a:21:08:7c:9a:36:d8:0b:fe:d1:26:c5: +# 58:31:30:28:25:f3:5d:5d:a3:b8:b6:a5:b4:92:ed: +# 6c:2c:9f:eb:dd:43:89:a2:3c:4b:48:91:1d:50:ec: +# 26:df:d6:60:2e:bd:21 +# ASN1 OID: secp384r1 +# X509v3 extensions: +# X509v3 Basic Constraints: critical +# CA:TRUE +# X509v3 Key Usage: critical +# Certificate Sign, CRL Sign +# X509v3 Subject Key Identifier: +# 15:5F:35:57:51:55:FB:25:B2:AD:03:69:FC:01:A3:FA:BE:11:55:D5 +# Signature Algorithm: ecdsa-with-SHA384 +# 30:64:02:30:64:96:59:a6:e8:09:de:8b:ba:fa:5a:88:88:f0: +# 1f:91:d3:46:a8:f2:4a:4c:02:63:fb:6c:5f:38:db:2e:41:93: +# a9:0e:e6:9d:dc:31:1c:b2:a0:a7:18:1c:79:e1:c7:36:02:30: +# 3a:56:af:9a:74:6c:f6:fb:83:e0:33:d3:08:5f:a1:9c:c2:5b: +# 9f:46:d6:b6:cb:91:06:63:a2:06:e7:33:ac:3e:a8:81:12:d0: +# cb:ba:d0:92:0b:b6:9e:96:aa:04:0f:8a +-----BEGIN CERTIFICATE----- +MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDEL +MAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChj +KSAyMDA3IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2 +MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 +eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1OVowgZgxCzAJBgNV +BAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykgMjAw +NyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNV +BAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH +MjB2MBAGByqGSM49AgEGBSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcL +So17VDs6bl8VAsBQps8lL33KSLjHUGMcKiEIfJo22Av+0SbFWDEwKCXzXV2juLal +tJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO +BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+EVXVMAoG +CCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGT +qQ7mndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBucz +rD6ogRLQy7rQkgu2npaqBA+K +-----END CERTIFICATE----- +# GeoTrust Primary Certification Authority - G3.pem +# Certificate: +# Data: +# Version: 3 (0x2) +# Serial Number: +# 15:ac:6e:94:19:b2:79:4b:41:f6:27:a9:c3:18:0f:1f +# Signature Algorithm: sha256WithRSAEncryption +# Issuer: C=US, O=GeoTrust Inc., OU=(c) 2008 GeoTrust Inc. - For authorized use only, CN=GeoTrust Primary Certification Authority - G3 +# Validity +# Not Before: Apr 2 00:00:00 2008 GMT +# Not After : Dec 1 23:59:59 2037 GMT +# Subject: C=US, O=GeoTrust Inc., OU=(c) 2008 GeoTrust Inc. - For authorized use only, CN=GeoTrust Primary Certification Authority - G3 +# Subject Public Key Info: +# Public Key Algorithm: rsaEncryption +# Public-Key: (2048 bit) +# Modulus: +# 00:dc:e2:5e:62:58:1d:33:57:39:32:33:fa:eb:cb: +# 87:8c:a7:d4:4a:dd:06:88:ea:64:8e:31:98:a5:38: +# 90:1e:98:cf:2e:63:2b:f0:46:bc:44:b2:89:a1:c0: +# 28:0c:49:70:21:95:9f:64:c0:a6:93:12:02:65:26: +# 86:c6:a5:89:f0:fa:d7:84:a0:70:af:4f:1a:97:3f: +# 06:44:d5:c9:eb:72:10:7d:e4:31:28:fb:1c:61:e6: +# 28:07:44:73:92:22:69:a7:03:88:6c:9d:63:c8:52: +# da:98:27:e7:08:4c:70:3e:b4:c9:12:c1:c5:67:83: +# 5d:33:f3:03:11:ec:6a:d0:53:e2:d1:ba:36:60:94: +# 80:bb:61:63:6c:5b:17:7e:df:40:94:1e:ab:0d:c2: +# 21:28:70:88:ff:d6:26:6c:6c:60:04:25:4e:55:7e: +# 7d:ef:bf:94:48:de:b7:1d:dd:70:8d:05:5f:88:a5: +# 9b:f2:c2:ee:ea:d1:40:41:6d:62:38:1d:56:06:c5: +# 03:47:51:20:19:fc:7b:10:0b:0e:62:ae:76:55:bf: +# 5f:77:be:3e:49:01:53:3d:98:25:03:76:24:5a:1d: +# b4:db:89:ea:79:e5:b6:b3:3b:3f:ba:4c:28:41:7f: +# 06:ac:6a:8e:c1:d0:f6:05:1d:7d:e6:42:86:e3:a5: +# d5:47 +# Exponent: 65537 (0x10001) +# X509v3 extensions: +# X509v3 Basic Constraints: critical +# CA:TRUE +# X509v3 Key Usage: critical +# Certificate Sign, CRL Sign +# X509v3 Subject Key Identifier: +# C4:79:CA:8E:A1:4E:03:1D:1C:DC:6B:DB:31:5B:94:3E:3F:30:7F:2D +# Signature Algorithm: sha256WithRSAEncryption +# 2d:c5:13:cf:56:80:7b:7a:78:bd:9f:ae:2c:99:e7:ef:da:df: +# 94:5e:09:69:a7:e7:6e:68:8c:bd:72:be:47:a9:0e:97:12:b8: +# 4a:f1:64:d3:39:df:25:34:d4:c1:cd:4e:81:f0:0f:04:c4:24: +# b3:34:96:c6:a6:aa:30:df:68:61:73:d7:f9:8e:85:89:ef:0e: +# 5e:95:28:4a:2a:27:8f:10:8e:2e:7c:86:c4:02:9e:da:0c:77: +# 65:0e:44:0d:92:fd:fd:b3:16:36:fa:11:0d:1d:8c:0e:07:89: +# 6a:29:56:f7:72:f4:dd:15:9c:77:35:66:57:ab:13:53:d8:8e: +# c1:40:c5:d7:13:16:5a:72:c7:b7:69:01:c4:7a:b1:83:01:68: +# 7d:8d:41:a1:94:18:c1:25:5c:fc:f0:fe:83:02:87:7c:0d:0d: +# cf:2e:08:5c:4a:40:0d:3e:ec:81:61:e6:24:db:ca:e0:0e:2d: +# 07:b2:3e:56:dc:8d:f5:41:85:07:48:9b:0c:0b:cb:49:3f:7d: +# ec:b7:fd:cb:8d:67:89:1a:ab:ed:bb:1e:a3:00:08:08:17:2a: +# 82:5c:31:5d:46:8a:2d:0f:86:9b:74:d9:45:fb:d4:40:b1:7a: +# aa:68:2d:86:b2:99:22:e1:c1:2b:c7:9c:f8:f3:5f:a8:82:12: +# eb:19:11:2d +-----BEGIN CERTIFICATE----- +MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCB +mDELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsT +MChjKSAyMDA4IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s +eTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhv +cml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIzNTk1OVowgZgxCzAJ +BgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg +MjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0 +BgNVBAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg +LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz ++uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5jK/BGvESyiaHAKAxJcCGVn2TAppMSAmUm +hsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdEc5IiaacDiGydY8hS2pgn +5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3CIShwiP/W +JmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exAL +DmKudlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZC +huOl1UcCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw +HQYDVR0OBBYEFMR5yo6hTgMdHNxr2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IB +AQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9cr5HqQ6XErhK8WTTOd8lNNTB +zU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbEAp7aDHdlDkQN +kv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD +AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUH +SJsMC8tJP33st/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2G +spki4cErx5z481+oghLrGREt +-----END CERTIFICATE----- +# GeoTrust Primary Certification Authority.pem +# Certificate: +# Data: +# Version: 3 (0x2) +# Serial Number: +# 18:ac:b5:6a:fd:69:b6:15:3a:63:6c:af:da:fa:c4:a1 +# Signature Algorithm: sha1WithRSAEncryption +# Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Primary Certification Authority +# Validity +# Not Before: Nov 27 00:00:00 2006 GMT +# Not After : Jul 16 23:59:59 2036 GMT +# Subject: C=US, O=GeoTrust Inc., CN=GeoTrust Primary Certification Authority +# Subject Public Key Info: +# Public Key Algorithm: rsaEncryption +# Public-Key: (2048 bit) +# Modulus: +# 00:be:b8:15:7b:ff:d4:7c:7d:67:ad:83:64:7b:c8: +# 42:53:2d:df:f6:84:08:20:61:d6:01:59:6a:9c:44: +# 11:af:ef:76:fd:95:7e:ce:61:30:bb:7a:83:5f:02: +# bd:01:66:ca:ee:15:8d:6f:a1:30:9c:bd:a1:85:9e: +# 94:3a:f3:56:88:00:31:cf:d8:ee:6a:96:02:d9:ed: +# 03:8c:fb:75:6d:e7:ea:b8:55:16:05:16:9a:f4:e0: +# 5e:b1:88:c0:64:85:5c:15:4d:88:c7:b7:ba:e0:75: +# e9:ad:05:3d:9d:c7:89:48:e0:bb:28:c8:03:e1:30: +# 93:64:5e:52:c0:59:70:22:35:57:88:8a:f1:95:0a: +# 83:d7:bc:31:73:01:34:ed:ef:46:71:e0:6b:02:a8: +# 35:72:6b:97:9b:66:e0:cb:1c:79:5f:d8:1a:04:68: +# 1e:47:02:e6:9d:60:e2:36:97:01:df:ce:35:92:df: +# be:67:c7:6d:77:59:3b:8f:9d:d6:90:15:94:bc:42: +# 34:10:c1:39:f9:b1:27:3e:7e:d6:8a:75:c5:b2:af: +# 96:d3:a2:de:9b:e4:98:be:7d:e1:e9:81:ad:b6:6f: +# fc:d7:0e:da:e0:34:b0:0d:1a:77:e7:e3:08:98:ef: +# 58:fa:9c:84:b7:36:af:c2:df:ac:d2:f4:10:06:70: +# 71:35 +# Exponent: 65537 (0x10001) +# X509v3 extensions: +# X509v3 Basic Constraints: critical +# CA:TRUE +# X509v3 Key Usage: critical +# Certificate Sign, CRL Sign +# X509v3 Subject Key Identifier: +# 2C:D5:50:41:97:15:8B:F0:8F:36:61:5B:4A:FB:6B:D9:99:C9:33:92 +# Signature Algorithm: sha1WithRSAEncryption +# 5a:70:7f:2c:dd:b7:34:4f:f5:86:51:a9:26:be:4b:b8:aa:f1: +# 71:0d:dc:61:c7:a0:ea:34:1e:7a:77:0f:04:35:e8:27:8f:6c: +# 90:bf:91:16:24:46:3e:4a:4e:ce:2b:16:d5:0b:52:1d:fc:1f: +# 67:a2:02:45:31:4f:ce:f3:fa:03:a7:79:9d:53:6a:d9:da:63: +# 3a:f8:80:d7:d3:99:e1:a5:e1:be:d4:55:71:98:35:3a:be:93: +# ea:ae:ad:42:b2:90:6f:e0:fc:21:4d:35:63:33:89:49:d6:9b: +# 4e:ca:c7:e7:4e:09:00:f7:da:c7:ef:99:62:99:77:b6:95:22: +# 5e:8a:a0:ab:f4:b8:78:98:ca:38:19:99:c9:72:9e:78:cd:4b: +# ac:af:19:a0:73:12:2d:fc:c2:41:ba:81:91:da:16:5a:31:b7: +# f9:b4:71:80:12:48:99:72:73:5a:59:53:c1:63:52:33:ed:a7: +# c9:d2:39:02:70:fa:e0:b1:42:66:29:aa:9b:51:ed:30:54:22: +# 14:5f:d9:ab:1d:c1:e4:94:f0:f8:f5:2b:f7:ea:ca:78:46:d6: +# b8:91:fd:a6:0d:2b:1a:14:01:3e:80:f0:42:a0:95:07:5e:6d: +# cd:cc:4b:a4:45:8d:ab:12:e8:b3:de:5a:e5:a0:7c:e8:0f:22: +# 1d:5a:e9:59 +-----BEGIN CERTIFICATE----- +MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBY +MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMo +R2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEx +MjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgxCzAJBgNVBAYTAlVTMRYwFAYDVQQK +Ew1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQcmltYXJ5IENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9 +AWbK7hWNb6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjA +ZIVcFU2Ix7e64HXprQU9nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE0 +7e9GceBrAqg1cmuXm2bgyxx5X9gaBGgeRwLmnWDiNpcB3841kt++Z8dtd1k7j53W +kBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGttm/81w7a4DSwDRp35+MI +mO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G +A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJ +KoZIhvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ1 +6CePbJC/kRYkRj5KTs4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl +4b7UVXGYNTq+k+qurUKykG/g/CFNNWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6K +oKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHaFloxt/m0cYASSJlyc1pZU8Fj +UjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG1riR/aYNKxoU +AT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk= +-----END CERTIFICATE----- +# Go Daddy Class 2 Certification Authority.pem +# Certificate: +# Data: +# Version: 3 (0x2) +# Serial Number: 0 (0x0) +# Signature Algorithm: sha1WithRSAEncryption +# Issuer: C=US, O=The Go Daddy Group, Inc., OU=Go Daddy Class 2 Certification Authority +# Validity +# Not Before: Jun 29 17:06:20 2004 GMT +# Not After : Jun 29 17:06:20 2034 GMT +# Subject: C=US, O=The Go Daddy Group, Inc., OU=Go Daddy Class 2 Certification Authority +# Subject Public Key Info: +# Public Key Algorithm: rsaEncryption +# Public-Key: (2048 bit) +# Modulus: +# 00:de:9d:d7:ea:57:18:49:a1:5b:eb:d7:5f:48:86: +# ea:be:dd:ff:e4:ef:67:1c:f4:65:68:b3:57:71:a0: +# 5e:77:bb:ed:9b:49:e9:70:80:3d:56:18:63:08:6f: +# da:f2:cc:d0:3f:7f:02:54:22:54:10:d8:b2:81:d4: +# c0:75:3d:4b:7f:c7:77:c3:3e:78:ab:1a:03:b5:20: +# 6b:2f:6a:2b:b1:c5:88:7e:c4:bb:1e:b0:c1:d8:45: +# 27:6f:aa:37:58:f7:87:26:d7:d8:2d:f6:a9:17:b7: +# 1f:72:36:4e:a6:17:3f:65:98:92:db:2a:6e:5d:a2: +# fe:88:e0:0b:de:7f:e5:8d:15:e1:eb:cb:3a:d5:e2: +# 12:a2:13:2d:d8:8e:af:5f:12:3d:a0:08:05:08:b6: +# 5c:a5:65:38:04:45:99:1e:a3:60:60:74:c5:41:a5: +# 72:62:1b:62:c5:1f:6f:5f:1a:42:be:02:51:65:a8: +# ae:23:18:6a:fc:78:03:a9:4d:7f:80:c3:fa:ab:5a: +# fc:a1:40:a4:ca:19:16:fe:b2:c8:ef:5e:73:0d:ee: +# 77:bd:9a:f6:79:98:bc:b1:07:67:a2:15:0d:dd:a0: +# 58:c6:44:7b:0a:3e:62:28:5f:ba:41:07:53:58:cf: +# 11:7e:38:74:c5:f8:ff:b5:69:90:8f:84:74:ea:97: +# 1b:af +# Exponent: 3 (0x3) +# X509v3 extensions: +# X509v3 Subject Key Identifier: +# D2:C4:B0:D2:91:D4:4C:11:71:B3:61:CB:3D:A1:FE:DD:A8:6A:D4:E3 +# X509v3 Authority Key Identifier: +# keyid:D2:C4:B0:D2:91:D4:4C:11:71:B3:61:CB:3D:A1:FE:DD:A8:6A:D4:E3 +# DirName:/C=US/O=The Go Daddy Group, Inc./OU=Go Daddy Class 2 Certification Authority +# serial:00 +# +# X509v3 Basic Constraints: +# CA:TRUE +# Signature Algorithm: sha1WithRSAEncryption +# 32:4b:f3:b2:ca:3e:91:fc:12:c6:a1:07:8c:8e:77:a0:33:06: +# 14:5c:90:1e:18:f7:08:a6:3d:0a:19:f9:87:80:11:6e:69:e4: +# 96:17:30:ff:34:91:63:72:38:ee:cc:1c:01:a3:1d:94:28:a4: +# 31:f6:7a:c4:54:d7:f6:e5:31:58:03:a2:cc:ce:62:db:94:45: +# 73:b5:bf:45:c9:24:b5:d5:82:02:ad:23:79:69:8d:b8:b6:4d: +# ce:cf:4c:ca:33:23:e8:1c:88:aa:9d:8b:41:6e:16:c9:20:e5: +# 89:9e:cd:3b:da:70:f7:7e:99:26:20:14:54:25:ab:6e:73:85: +# e6:9b:21:9d:0a:6c:82:0e:a8:f8:c2:0c:fa:10:1e:6c:96:ef: +# 87:0d:c4:0f:61:8b:ad:ee:83:2b:95:f8:8e:92:84:72:39:eb: +# 20:ea:83:ed:83:cd:97:6e:08:bc:eb:4e:26:b6:73:2b:e4:d3: +# f6:4c:fe:26:71:e2:61:11:74:4a:ff:57:1a:87:0f:75:48:2e: +# cf:51:69:17:a0:02:12:61:95:d5:d1:40:b2:10:4c:ee:c4:ac: +# 10:43:a6:a5:9e:0a:d5:95:62:9a:0d:cf:88:82:c5:32:0c:e4: +# 2b:9f:45:e6:0d:9f:28:9c:b1:b9:2a:5a:57:ad:37:0f:af:1d: +# 7f:db:bd:9f +-----BEGIN CERTIFICATE----- +MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh +MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE +YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3 +MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo +ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg +MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN +ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA +PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w +wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi +EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY +avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+ +YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE +sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h +/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5 +IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD +ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy +OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P +TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ +HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER +dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf +ReYNnyicsbkqWletNw+vHX/bvZ8= +-----END CERTIFICATE----- +# Go Daddy Root Certificate Authority - G2.pem +# Certificate: +# Data: +# Version: 3 (0x2) +# Serial Number: 0 (0x0) +# Signature Algorithm: sha256WithRSAEncryption +# Issuer: C=US, ST=Arizona, L=Scottsdale, O=GoDaddy.com, Inc., CN=Go Daddy Root Certificate Authority - G2 +# Validity +# Not Before: Sep 1 00:00:00 2009 GMT +# Not After : Dec 31 23:59:59 2037 GMT +# Subject: C=US, ST=Arizona, L=Scottsdale, O=GoDaddy.com, Inc., CN=Go Daddy Root Certificate Authority - G2 +# Subject Public Key Info: +# Public Key Algorithm: rsaEncryption +# Public-Key: (2048 bit) +# Modulus: +# 00:bf:71:62:08:f1:fa:59:34:f7:1b:c9:18:a3:f7: +# 80:49:58:e9:22:83:13:a6:c5:20:43:01:3b:84:f1: +# e6:85:49:9f:27:ea:f6:84:1b:4e:a0:b4:db:70:98: +# c7:32:01:b1:05:3e:07:4e:ee:f4:fa:4f:2f:59:30: +# 22:e7:ab:19:56:6b:e2:80:07:fc:f3:16:75:80:39: +# 51:7b:e5:f9:35:b6:74:4e:a9:8d:82:13:e4:b6:3f: +# a9:03:83:fa:a2:be:8a:15:6a:7f:de:0b:c3:b6:19: +# 14:05:ca:ea:c3:a8:04:94:3b:46:7c:32:0d:f3:00: +# 66:22:c8:8d:69:6d:36:8c:11:18:b7:d3:b2:1c:60: +# b4:38:fa:02:8c:ce:d3:dd:46:07:de:0a:3e:eb:5d: +# 7c:c8:7c:fb:b0:2b:53:a4:92:62:69:51:25:05:61: +# 1a:44:81:8c:2c:a9:43:96:23:df:ac:3a:81:9a:0e: +# 29:c5:1c:a9:e9:5d:1e:b6:9e:9e:30:0a:39:ce:f1: +# 88:80:fb:4b:5d:cc:32:ec:85:62:43:25:34:02:56: +# 27:01:91:b4:3b:70:2a:3f:6e:b1:e8:9c:88:01:7d: +# 9f:d4:f9:db:53:6d:60:9d:bf:2c:e7:58:ab:b8:5f: +# 46:fc:ce:c4:1b:03:3c:09:eb:49:31:5c:69:46:b3: +# e0:47 +# Exponent: 65537 (0x10001) +# X509v3 extensions: +# X509v3 Basic Constraints: critical +# CA:TRUE +# X509v3 Key Usage: critical +# Certificate Sign, CRL Sign +# X509v3 Subject Key Identifier: +# 3A:9A:85:07:10:67:28:B6:EF:F6:BD:05:41:6E:20:C1:94:DA:0F:DE +# Signature Algorithm: sha256WithRSAEncryption +# 99:db:5d:79:d5:f9:97:59:67:03:61:f1:7e:3b:06:31:75:2d: +# a1:20:8e:4f:65:87:b4:f7:a6:9c:bc:d8:e9:2f:d0:db:5a:ee: +# cf:74:8c:73:b4:38:42:da:05:7b:f8:02:75:b8:fd:a5:b1:d7: +# ae:f6:d7:de:13:cb:53:10:7e:8a:46:d1:97:fa:b7:2e:2b:11: +# ab:90:b0:27:80:f9:e8:9f:5a:e9:37:9f:ab:e4:df:6c:b3:85: +# 17:9d:3d:d9:24:4f:79:91:35:d6:5f:04:eb:80:83:ab:9a:02: +# 2d:b5:10:f4:d8:90:c7:04:73:40:ed:72:25:a0:a9:9f:ec:9e: +# ab:68:12:99:57:c6:8f:12:3a:09:a4:bd:44:fd:06:15:37:c1: +# 9b:e4:32:a3:ed:38:e8:d8:64:f3:2c:7e:14:fc:02:ea:9f:cd: +# ff:07:68:17:db:22:90:38:2d:7a:8d:d1:54:f1:69:e3:5f:33: +# ca:7a:3d:7b:0a:e3:ca:7f:5f:39:e5:e2:75:ba:c5:76:18:33: +# ce:2c:f0:2f:4c:ad:f7:b1:e7:ce:4f:a8:c4:9b:4a:54:06:c5: +# 7f:7d:d5:08:0f:e2:1c:fe:7e:17:b8:ac:5e:f6:d4:16:b2:43: +# 09:0c:4d:f6:a7:6b:b4:99:84:65:ca:7a:88:e2:e2:44:be:5c: +# f7:ea:1c:f5 +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT +EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp +ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz +NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH +EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE +AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD +E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH +/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy +DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh +GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR +tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA +AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX +WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu +9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr +gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo +2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO +LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI +4uJEvlz36hz1 +-----END CERTIFICATE----- +# Go Daddy Secure Certification Authority serialNumber=07969287.pem +# Certificate: +# Data: +# Version: 3 (0x2) +# Serial Number: 769 (0x301) +# Signature Algorithm: sha1WithRSAEncryption +# Issuer: C=US, O=The Go Daddy Group, Inc., OU=Go Daddy Class 2 Certification Authority +# Validity +# Not Before: Nov 16 01:54:37 2006 GMT +# Not After : Nov 16 01:54:37 2026 GMT +# Subject: C=US, ST=Arizona, L=Scottsdale, O=GoDaddy.com, Inc., OU=http://certificates.godaddy.com/repository, CN=Go Daddy Secure Certification Authority/serialNumber=07969287 +# Subject Public Key Info: +# Public Key Algorithm: rsaEncryption +# Public-Key: (2048 bit) +# Modulus: +# 00:c4:2d:d5:15:8c:9c:26:4c:ec:32:35:eb:5f:b8: +# 59:01:5a:a6:61:81:59:3b:70:63:ab:e3:dc:3d:c7: +# 2a:b8:c9:33:d3:79:e4:3a:ed:3c:30:23:84:8e:b3: +# 30:14:b6:b2:87:c3:3d:95:54:04:9e:df:99:dd:0b: +# 25:1e:21:de:65:29:7e:35:a8:a9:54:eb:f6:f7:32: +# 39:d4:26:55:95:ad:ef:fb:fe:58:86:d7:9e:f4:00: +# 8d:8c:2a:0c:bd:42:04:ce:a7:3f:04:f6:ee:80:f2: +# aa:ef:52:a1:69:66:da:be:1a:ad:5d:da:2c:66:ea: +# 1a:6b:bb:e5:1a:51:4a:00:2f:48:c7:98:75:d8:b9: +# 29:c8:ee:f8:66:6d:0a:9c:b3:f3:fc:78:7c:a2:f8: +# a3:f2:b5:c3:f3:b9:7a:91:c1:a7:e6:25:2e:9c:a8: +# ed:12:65:6e:6a:f6:12:44:53:70:30:95:c3:9c:2b: +# 58:2b:3d:08:74:4a:f2:be:51:b0:bf:87:d0:4c:27: +# 58:6b:b5:35:c5:9d:af:17:31:f8:0b:8f:ee:ad:81: +# 36:05:89:08:98:cf:3a:af:25:87:c0:49:ea:a7:fd: +# 67:f7:45:8e:97:cc:14:39:e2:36:85:b5:7e:1a:37: +# fd:16:f6:71:11:9a:74:30:16:fe:13:94:a3:3f:84: +# 0d:4f +# Exponent: 65537 (0x10001) +# X509v3 extensions: +# X509v3 Subject Key Identifier: +# FD:AC:61:32:93:6C:45:D6:E2:EE:85:5F:9A:BA:E7:76:99:68:CC:E7 +# X509v3 Authority Key Identifier: +# keyid:D2:C4:B0:D2:91:D4:4C:11:71:B3:61:CB:3D:A1:FE:DD:A8:6A:D4:E3 +# +# X509v3 Basic Constraints: critical +# CA:TRUE, pathlen:0 +# Authority Information Access: +# OCSP - URI:http://ocsp.godaddy.com +# +# X509v3 CRL Distribution Points: +# +# Full Name: +# URI:http://certificates.godaddy.com/repository/gdroot.crl +# +# X509v3 Certificate Policies: +# Policy: X509v3 Any Policy +# CPS: http://certificates.godaddy.com/repository +# +# X509v3 Key Usage: critical +# Certificate Sign, CRL Sign +# Signature Algorithm: sha1WithRSAEncryption +# d2:86:c0:ec:bd:f9:a1:b6:67:ee:66:0b:a2:06:3a:04:50:8e: +# 15:72:ac:4a:74:95:53:cb:37:cb:44:49:ef:07:90:6b:33:d9: +# 96:f0:94:56:a5:13:30:05:3c:85:32:21:7b:c9:c7:0a:a8:24: +# a4:90:de:46:d3:25:23:14:03:67:c2:10:d6:6f:0f:5d:7b:7a: +# cc:9f:c5:58:2a:c1:c4:9e:21:a8:5a:f3:ac:a4:46:f3:9e:e4: +# 63:cb:2f:90:a4:29:29:01:d9:72:2c:29:df:37:01:27:bc:4f: +# ee:68:d3:21:8f:c0:b3:e4:f5:09:ed:d2:10:aa:53:b4:be:f0: +# cc:59:0b:d6:3b:96:1c:95:24:49:df:ce:ec:fd:a7:48:91:14: +# 45:0e:3a:36:6f:da:45:b3:45:a2:41:c9:d4:d7:44:4e:3e:b9: +# 74:76:d5:a2:13:55:2c:c6:87:a3:b5:99:ac:06:84:87:7f:75: +# 06:fc:bf:14:4c:0e:cc:6e:c4:df:3d:b7:12:71:f4:e8:f1:51: +# 40:22:28:49:e0:1d:4b:87:a8:34:cc:06:a2:dd:12:5a:d1:86: +# 36:64:03:35:6f:6f:77:6e:eb:f2:85:50:98:5e:ab:03:53:ad: +# 91:23:63:1f:16:9c:cd:b9:b2:05:63:3a:e1:f4:68:1b:17:05: +# 35:95:53:ee +-----BEGIN CERTIFICATE----- +MIIE3jCCA8agAwIBAgICAwEwDQYJKoZIhvcNAQEFBQAwYzELMAkGA1UEBhMCVVMx +ITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g +RGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjExMTYw +MTU0MzdaFw0yNjExMTYwMTU0MzdaMIHKMQswCQYDVQQGEwJVUzEQMA4GA1UECBMH +QXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTEaMBgGA1UEChMRR29EYWRkeS5j +b20sIEluYy4xMzAxBgNVBAsTKmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5j +b20vcmVwb3NpdG9yeTEwMC4GA1UEAxMnR28gRGFkZHkgU2VjdXJlIENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5MREwDwYDVQQFEwgwNzk2OTI4NzCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBAMQt1RWMnCZM7DI161+4WQFapmGBWTtwY6vj3D3H +KrjJM9N55DrtPDAjhI6zMBS2sofDPZVUBJ7fmd0LJR4h3mUpfjWoqVTr9vcyOdQm +VZWt7/v+WIbXnvQAjYwqDL1CBM6nPwT27oDyqu9SoWlm2r4arV3aLGbqGmu75RpR +SgAvSMeYddi5Kcju+GZtCpyz8/x4fKL4o/K1w/O5epHBp+YlLpyo7RJlbmr2EkRT +cDCVw5wrWCs9CHRK8r5RsL+H0EwnWGu1NcWdrxcx+AuP7q2BNgWJCJjPOq8lh8BJ +6qf9Z/dFjpfMFDniNoW1fho3/Rb2cRGadDAW/hOUoz+EDU8CAwEAAaOCATIwggEu +MB0GA1UdDgQWBBT9rGEyk2xF1uLuhV+auud2mWjM5zAfBgNVHSMEGDAWgBTSxLDS +kdRMEXGzYcs9of7dqGrU4zASBgNVHRMBAf8ECDAGAQH/AgEAMDMGCCsGAQUFBwEB +BCcwJTAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuZ29kYWRkeS5jb20wRgYDVR0f +BD8wPTA7oDmgN4Y1aHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNvbS9yZXBv +c2l0b3J5L2dkcm9vdC5jcmwwSwYDVR0gBEQwQjBABgRVHSAAMDgwNgYIKwYBBQUH +AgEWKmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3NpdG9yeTAO +BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBANKGwOy9+aG2Z+5mC6IG +OgRQjhVyrEp0lVPLN8tESe8HkGsz2ZbwlFalEzAFPIUyIXvJxwqoJKSQ3kbTJSMU +A2fCENZvD117esyfxVgqwcSeIaha86ykRvOe5GPLL5CkKSkB2XIsKd83ASe8T+5o +0yGPwLPk9Qnt0hCqU7S+8MxZC9Y7lhyVJEnfzuz9p0iRFEUOOjZv2kWzRaJBydTX +RE4+uXR21aITVSzGh6O1mawGhId/dQb8vxRMDsxuxN89txJx9OjxUUAiKEngHUuH +qDTMBqLdElrRhjZkAzVvb3du6/KFUJheqwNTrZEjYx8WnM25sgVjOuH0aBsXBTWV +U+4= +-----END CERTIFICATE----- +# Thawte Premium Server CA.pem +# Certificate: +# Data: +# Version: 3 (0x2) +# Serial Number: 1 (0x1) +# Signature Algorithm: md5WithRSAEncryption +# Issuer: C=ZA, ST=Western Cape, L=Cape Town, O=Thawte Consulting cc, OU=Certification Services Division, CN=Thawte Premium Server CA/emailAddress=premium-server@thawte.com +# Validity +# Not Before: Aug 1 00:00:00 1996 GMT +# Not After : Dec 31 23:59:59 2020 GMT +# Subject: C=ZA, ST=Western Cape, L=Cape Town, O=Thawte Consulting cc, OU=Certification Services Division, CN=Thawte Premium Server CA/emailAddress=premium-server@thawte.com +# Subject Public Key Info: +# Public Key Algorithm: rsaEncryption +# Public-Key: (1024 bit) +# Modulus: +# 00:d2:36:36:6a:8b:d7:c2:5b:9e:da:81:41:62:8f: +# 38:ee:49:04:55:d6:d0:ef:1c:1b:95:16:47:ef:18: +# 48:35:3a:52:f4:2b:6a:06:8f:3b:2f:ea:56:e3:af: +# 86:8d:9e:17:f7:9e:b4:65:75:02:4d:ef:cb:09:a2: +# 21:51:d8:9b:d0:67:d0:ba:0d:92:06:14:73:d4:93: +# cb:97:2a:00:9c:5c:4e:0c:bc:fa:15:52:fc:f2:44: +# 6e:da:11:4a:6e:08:9f:2f:2d:e3:f9:aa:3a:86:73: +# b6:46:53:58:c8:89:05:bd:83:11:b8:73:3f:aa:07: +# 8d:f4:42:4d:e7:40:9d:1c:37 +# Exponent: 65537 (0x10001) +# X509v3 extensions: +# X509v3 Basic Constraints: critical +# CA:TRUE +# Signature Algorithm: md5WithRSAEncryption +# 26:48:2c:16:c2:58:fa:e8:16:74:0c:aa:aa:5f:54:3f:f2:d7: +# c9:78:60:5e:5e:6e:37:63:22:77:36:7e:b2:17:c4:34:b9:f5: +# 08:85:fc:c9:01:38:ff:4d:be:f2:16:42:43:e7:bb:5a:46:fb: +# c1:c6:11:1f:f1:4a:b0:28:46:c9:c3:c4:42:7d:bc:fa:ab:59: +# 6e:d5:b7:51:88:11:e3:a4:85:19:6b:82:4c:a4:0c:12:ad:e9: +# a4:ae:3f:f1:c3:49:65:9a:8c:c5:c8:3e:25:b7:94:99:bb:92: +# 32:71:07:f0:86:5e:ed:50:27:a6:0d:a6:23:f9:bb:cb:a6:07: +# 14:42 +-----BEGIN CERTIFICATE----- +MIIDJzCCApCgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBzjELMAkGA1UEBhMCWkEx +FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYD +VQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlv +biBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UEAxMYVGhhd3RlIFByZW1pdW0gU2Vy +dmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNlcnZlckB0aGF3dGUuY29t +MB4XDTk2MDgwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgc4xCzAJBgNVBAYTAlpB +MRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsG +A1UEChMUVGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRp +b24gU2VydmljZXMgRGl2aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNl +cnZlciBDQTEoMCYGCSqGSIb3DQEJARYZcHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNv +bTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0jY2aovXwlue2oFBYo847kkE +VdbQ7xwblRZH7xhINTpS9CtqBo87L+pW46+GjZ4X9560ZXUCTe/LCaIhUdib0GfQ +ug2SBhRz1JPLlyoAnFxODLz6FVL88kRu2hFKbgifLy3j+ao6hnO2RlNYyIkFvYMR +uHM/qgeN9EJN50CdHDcCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG +9w0BAQQFAAOBgQAmSCwWwlj66BZ0DKqqX1Q/8tfJeGBeXm43YyJ3Nn6yF8Q0ufUI +hfzJATj/Tb7yFkJD57taRvvBxhEf8UqwKEbJw8RCfbz6q1lu1bdRiBHjpIUZa4JM +pAwSremkrj/xw0llmozFyD4lt5SZu5IycQfwhl7tUCemDaYj+bvLpgcUQg== +-----END CERTIFICATE----- +# Thawte Primary Root CA - G2.pem +# Certificate: +# Data: +# Version: 3 (0x2) +# Serial Number: +# 35:fc:26:5c:d9:84:4f:c9:3d:26:3d:57:9b:ae:d7:56 +# Signature Algorithm: ecdsa-with-SHA384 +# Issuer: C=US, O=thawte, Inc., OU=(c) 2007 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA - G2 +# Validity +# Not Before: Nov 5 00:00:00 2007 GMT +# Not After : Jan 18 23:59:59 2038 GMT +# Subject: C=US, O=thawte, Inc., OU=(c) 2007 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA - G2 +# Subject Public Key Info: +# Public Key Algorithm: id-ecPublicKey +# Public-Key: (384 bit) +# pub: +# 04:a2:d5:9c:82:7b:95:9d:f1:52:78:87:fe:8a:16: +# bf:05:e6:df:a3:02:4f:0d:07:c6:00:51:ba:0c:02: +# 52:2d:22:a4:42:39:c4:fe:8f:ea:c9:c1:be:d4:4d: +# ff:9f:7a:9e:e2:b1:7c:9a:ad:a7:86:09:73:87:d1: +# e7:9a:e3:7a:a5:aa:6e:fb:ba:b3:70:c0:67:88:a2: +# 35:d4:a3:9a:b1:fd:ad:c2:ef:31:fa:a8:b9:f3:fb: +# 08:c6:91:d1:fb:29:95 +# ASN1 OID: secp384r1 +# X509v3 extensions: +# X509v3 Basic Constraints: critical +# CA:TRUE +# X509v3 Key Usage: critical +# Certificate Sign, CRL Sign +# X509v3 Subject Key Identifier: +# 9A:D8:00:30:00:E7:6B:7F:85:18:EE:8B:B6:CE:8A:0C:F8:11:E1:BB +# Signature Algorithm: ecdsa-with-SHA384 +# 30:66:02:31:00:dd:f8:e0:57:47:5b:a7:e6:0a:c3:bd:f5:80: +# 8a:97:35:0d:1b:89:3c:54:86:77:28:ca:a1:f4:79:de:b5:e6: +# 38:b0:f0:65:70:8c:7f:02:54:c2:bf:ff:d8:a1:3e:d9:cf:02: +# 31:00:c4:8d:94:fc:dc:53:d2:dc:9d:78:16:1f:15:33:23:53: +# 52:e3:5a:31:5d:9d:ca:ae:bd:13:29:44:0d:27:5b:a8:e7:68: +# 9c:12:f7:58:3f:2e:72:02:57:a3:8f:a1:14:2e +-----BEGIN CERTIFICATE----- +MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDEL +MAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMp +IDIwMDcgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAi +BgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMjAeFw0wNzExMDUwMDAw +MDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh +d3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBGb3Ig +YXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9v +dCBDQSAtIEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/ +BebfowJPDQfGAFG6DAJSLSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6 +papu+7qzcMBniKI11KOasf2twu8x+qi58/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUmtgAMADna3+FGO6Lts6K +DPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUNG4k8VIZ3 +KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41ox +XZ3Krr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg== +-----END CERTIFICATE----- +# Thawte Primary Root CA - G3.pem +# Certificate: +# Data: +# Version: 3 (0x2) +# Serial Number: +# 60:01:97:b7:46:a7:ea:b4:b4:9a:d6:4b:2f:f7:90:fb +# Signature Algorithm: sha256WithRSAEncryption +# Issuer: C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2008 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA - G3 +# Validity +# Not Before: Apr 2 00:00:00 2008 GMT +# Not After : Dec 1 23:59:59 2037 GMT +# Subject: C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2008 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA - G3 +# Subject Public Key Info: +# Public Key Algorithm: rsaEncryption +# Public-Key: (2048 bit) +# Modulus: +# 00:b2:bf:27:2c:fb:db:d8:5b:dd:78:7b:1b:9e:77: +# 66:81:cb:3e:bc:7c:ae:f3:a6:27:9a:34:a3:68:31: +# 71:38:33:62:e4:f3:71:66:79:b1:a9:65:a3:a5:8b: +# d5:8f:60:2d:3f:42:cc:aa:6b:32:c0:23:cb:2c:41: +# dd:e4:df:fc:61:9c:e2:73:b2:22:95:11:43:18:5f: +# c4:b6:1f:57:6c:0a:05:58:22:c8:36:4c:3a:7c:a5: +# d1:cf:86:af:88:a7:44:02:13:74:71:73:0a:42:59: +# 02:f8:1b:14:6b:42:df:6f:5f:ba:6b:82:a2:9d:5b: +# e7:4a:bd:1e:01:72:db:4b:74:e8:3b:7f:7f:7d:1f: +# 04:b4:26:9b:e0:b4:5a:ac:47:3d:55:b8:d7:b0:26: +# 52:28:01:31:40:66:d8:d9:24:bd:f6:2a:d8:ec:21: +# 49:5c:9b:f6:7a:e9:7f:55:35:7e:96:6b:8d:93:93: +# 27:cb:92:bb:ea:ac:40:c0:9f:c2:f8:80:cf:5d:f4: +# 5a:dc:ce:74:86:a6:3e:6c:0b:53:ca:bd:92:ce:19: +# 06:72:e6:0c:5c:38:69:c7:04:d6:bc:6c:ce:5b:f6: +# f7:68:9c:dc:25:15:48:88:a1:e9:a9:f8:98:9c:e0: +# f3:d5:31:28:61:11:6c:67:96:8d:39:99:cb:c2:45: +# 24:39 +# Exponent: 65537 (0x10001) +# X509v3 extensions: +# X509v3 Basic Constraints: critical +# CA:TRUE +# X509v3 Key Usage: critical +# Certificate Sign, CRL Sign +# X509v3 Subject Key Identifier: +# AD:6C:AA:94:60:9C:ED:E4:FF:FA:3E:0A:74:2B:63:03:F7:B6:59:BF +# Signature Algorithm: sha256WithRSAEncryption +# 1a:40:d8:95:65:ac:09:92:89:c6:39:f4:10:e5:a9:0e:66:53: +# 5d:78:de:fa:24:91:bb:e7:44:51:df:c6:16:34:0a:ef:6a:44: +# 51:ea:2b:07:8a:03:7a:c3:eb:3f:0a:2c:52:16:a0:2b:43:b9: +# 25:90:3f:70:a9:33:25:6d:45:1a:28:3b:27:cf:aa:c3:29:42: +# 1b:df:3b:4c:c0:33:34:5b:41:88:bf:6b:2b:65:af:28:ef:b2: +# f5:c3:aa:66:ce:7b:56:ee:b7:c8:cb:67:c1:c9:9c:1a:18:b8: +# c4:c3:49:03:f1:60:0e:50:cd:46:c5:f3:77:79:f7:b6:15:e0: +# 38:db:c7:2f:28:a0:0c:3f:77:26:74:d9:25:12:da:31:da:1a: +# 1e:dc:29:41:91:22:3c:69:a7:bb:02:f2:b6:5c:27:03:89:f4: +# 06:ea:9b:e4:72:82:e3:a1:09:c1:e9:00:19:d3:3e:d4:70:6b: +# ba:71:a6:aa:58:ae:f4:bb:e9:6c:b6:ef:87:cc:9b:bb:ff:39: +# e6:56:61:d3:0a:a7:c4:5c:4c:60:7b:05:77:26:7a:bf:d8:07: +# 52:2c:62:f7:70:63:d9:39:bc:6f:1c:c2:79:dc:76:29:af:ce: +# c5:2c:64:04:5e:88:36:6e:31:d4:40:1a:62:34:36:3f:35:01: +# ae:ac:63:a0 +-----BEGIN CERTIFICATE----- +MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCB +rjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf +Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw +MDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNV +BAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0wODA0MDIwMDAwMDBa +Fw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3Rl +LCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9u +MTgwNgYDVQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXpl +ZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEcz +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsr8nLPvb2FvdeHsbnndm +gcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2AtP0LMqmsywCPLLEHd5N/8 +YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC+BsUa0Lf +b1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS9 +9irY7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2S +zhkGcuYMXDhpxwTWvGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUk +OQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV +HQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJKoZIhvcNAQELBQADggEBABpA +2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweKA3rD6z8KLFIW +oCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu +t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7c +KUGRIjxpp7sC8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fM +m7v/OeZWYdMKp8RcTGB7BXcmer/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZu +MdRAGmI0Nj81Aa6sY6A= +-----END CERTIFICATE----- +# Thawte Primary Root CA.pem +# Certificate: +# Data: +# Version: 3 (0x2) +# Serial Number: +# 34:4e:d5:57:20:d5:ed:ec:49:f4:2f:ce:37:db:2b:6d +# Signature Algorithm: sha1WithRSAEncryption +# Issuer: C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2006 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA +# Validity +# Not Before: Nov 17 00:00:00 2006 GMT +# Not After : Jul 16 23:59:59 2036 GMT +# Subject: C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2006 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA +# Subject Public Key Info: +# Public Key Algorithm: rsaEncryption +# Public-Key: (2048 bit) +# Modulus: +# 00:ac:a0:f0:fb:80:59:d4:9c:c7:a4:cf:9d:a1:59: +# 73:09:10:45:0c:0d:2c:6e:68:f1:6c:5b:48:68:49: +# 59:37:fc:0b:33:19:c2:77:7f:cc:10:2d:95:34:1c: +# e6:eb:4d:09:a7:1c:d2:b8:c9:97:36:02:b7:89:d4: +# 24:5f:06:c0:cc:44:94:94:8d:02:62:6f:eb:5a:dd: +# 11:8d:28:9a:5c:84:90:10:7a:0d:bd:74:66:2f:6a: +# 38:a0:e2:d5:54:44:eb:1d:07:9f:07:ba:6f:ee:e9: +# fd:4e:0b:29:f5:3e:84:a0:01:f1:9c:ab:f8:1c:7e: +# 89:a4:e8:a1:d8:71:65:0d:a3:51:7b:ee:bc:d2:22: +# 60:0d:b9:5b:9d:df:ba:fc:51:5b:0b:af:98:b2:e9: +# 2e:e9:04:e8:62:87:de:2b:c8:d7:4e:c1:4c:64:1e: +# dd:cf:87:58:ba:4a:4f:ca:68:07:1d:1c:9d:4a:c6: +# d5:2f:91:cc:7c:71:72:1c:c5:c0:67:eb:32:fd:c9: +# 92:5c:94:da:85:c0:9b:bf:53:7d:2b:09:f4:8c:9d: +# 91:1f:97:6a:52:cb:de:09:36:a4:77:d8:7b:87:50: +# 44:d5:3e:6e:29:69:fb:39:49:26:1e:09:a5:80:7b: +# 40:2d:eb:e8:27:85:c9:fe:61:fd:7e:e6:7c:97:1d: +# d5:9d +# Exponent: 65537 (0x10001) +# X509v3 extensions: +# X509v3 Basic Constraints: critical +# CA:TRUE +# X509v3 Key Usage: critical +# Certificate Sign, CRL Sign +# X509v3 Subject Key Identifier: +# 7B:5B:45:CF:AF:CE:CB:7A:FD:31:92:1A:6A:B6:F3:46:EB:57:48:50 +# Signature Algorithm: sha1WithRSAEncryption +# 79:11:c0:4b:b3:91:b6:fc:f0:e9:67:d4:0d:6e:45:be:55:e8: +# 93:d2:ce:03:3f:ed:da:25:b0:1d:57:cb:1e:3a:76:a0:4c:ec: +# 50:76:e8:64:72:0c:a4:a9:f1:b8:8b:d6:d6:87:84:bb:32:e5: +# 41:11:c0:77:d9:b3:60:9d:eb:1b:d5:d1:6e:44:44:a9:a6:01: +# ec:55:62:1d:77:b8:5c:8e:48:49:7c:9c:3b:57:11:ac:ad:73: +# 37:8e:2f:78:5c:90:68:47:d9:60:60:e6:fc:07:3d:22:20:17: +# c4:f7:16:e9:c4:d8:72:f9:c8:73:7c:df:16:2f:15:a9:3e:fd: +# 6a:27:b6:a1:eb:5a:ba:98:1f:d5:e3:4d:64:0a:9d:13:c8:61: +# ba:f5:39:1c:87:ba:b8:bd:7b:22:7f:f6:fe:ac:40:79:e5:ac: +# 10:6f:3d:8f:1b:79:76:8b:c4:37:b3:21:18:84:e5:36:00:eb: +# 63:20:99:b9:e9:fe:33:04:bb:41:c8:c1:02:f9:44:63:20:9e: +# 81:ce:42:d3:d6:3f:2c:76:d3:63:9c:59:dd:8f:a6:e1:0e:a0: +# 2e:41:f7:2e:95:47:cf:bc:fd:33:f3:f6:0b:61:7e:7e:91:2b: +# 81:47:c2:27:30:ee:a7:10:5d:37:8f:5c:39:2b:e4:04:f0:7b: +# 8d:56:8c:68 +-----BEGIN CERTIFICATE----- +MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCB +qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf +Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw +MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV +BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3MDAwMDAwWhcNMzYw +NzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5j +LjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYG +A1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl +IG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsoPD7gFnUnMekz52hWXMJEEUMDSxuaPFs +W0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ1CRfBsDMRJSUjQJib+ta +3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGcq/gcfomk +6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6 +Sk/KaAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94J +NqR32HuHUETVPm4pafs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBA +MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XP +r87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUFAAOCAQEAeRHAS7ORtvzw6WfU +DW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeEuzLlQRHAd9mz +YJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX +xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2 +/qxAeeWsEG89jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/ +LHbTY5xZ3Y+m4Q6gLkH3LpVHz7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7 +jVaMaA== +-----END CERTIFICATE----- diff --git a/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/strict.php b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/strict.php new file mode 100644 index 0000000..1b4be63 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/dropbox/dropbox-sdk/lib/Dropbox/strict.php @@ -0,0 +1,13 @@ +decoratedBatch = $decoratedBatch; + } + + /** + * Allow decorators to implement custom methods + * + * @param string $method Missing method name + * @param array $args Method arguments + * + * @return mixed + * @codeCoverageIgnore + */ + public function __call($method, array $args) + { + return call_user_func_array(array($this->decoratedBatch, $method), $args); + } + + public function add($item) + { + $this->decoratedBatch->add($item); + + return $this; + } + + public function flush() + { + return $this->decoratedBatch->flush(); + } + + public function isEmpty() + { + return $this->decoratedBatch->isEmpty(); + } + + /** + * Trace the decorators associated with the batch + * + * @return array + */ + public function getDecorators() + { + $found = array($this); + if (method_exists($this->decoratedBatch, 'getDecorators')) { + $found = array_merge($found, $this->decoratedBatch->getDecorators()); + } + + return $found; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Batch/Batch.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Batch/Batch.php new file mode 100644 index 0000000..4d41c54 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Batch/Batch.php @@ -0,0 +1,92 @@ +transferStrategy = $transferStrategy; + $this->divisionStrategy = $divisionStrategy; + $this->queue = new \SplQueue(); + $this->queue->setIteratorMode(\SplQueue::IT_MODE_DELETE); + $this->dividedBatches = array(); + } + + public function add($item) + { + $this->queue->enqueue($item); + + return $this; + } + + public function flush() + { + $this->createBatches(); + + $items = array(); + foreach ($this->dividedBatches as $batchIndex => $dividedBatch) { + while ($dividedBatch->valid()) { + $batch = $dividedBatch->current(); + $dividedBatch->next(); + try { + $this->transferStrategy->transfer($batch); + $items = array_merge($items, $batch); + } catch (\Exception $e) { + throw new BatchTransferException($batch, $items, $e, $this->transferStrategy, $this->divisionStrategy); + } + } + // Keep the divided batch down to a minimum in case of a later exception + unset($this->dividedBatches[$batchIndex]); + } + + return $items; + } + + public function isEmpty() + { + return count($this->queue) == 0 && count($this->dividedBatches) == 0; + } + + /** + * Create batches for any queued items + */ + protected function createBatches() + { + if (count($this->queue)) { + if ($batches = $this->divisionStrategy->createBatches($this->queue)) { + // Convert arrays into iterators + if (is_array($batches)) { + $batches = new \ArrayIterator($batches); + } + $this->dividedBatches[] = $batches; + } + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Batch/BatchBuilder.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Batch/BatchBuilder.php new file mode 100644 index 0000000..ea99b4d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Batch/BatchBuilder.php @@ -0,0 +1,199 @@ + 'Guzzle\Batch\BatchRequestTransfer', + 'command' => 'Guzzle\Batch\BatchCommandTransfer' + ); + + /** + * Create a new instance of the BatchBuilder + * + * @return BatchBuilder + */ + public static function factory() + { + return new self(); + } + + /** + * Automatically flush the batch when the size of the queue reaches a certain threshold. Adds {@see FlushingBatch}. + * + * @param $threshold Number of items to allow in the queue before a flush + * + * @return BatchBuilder + */ + public function autoFlushAt($threshold) + { + $this->autoFlush = $threshold; + + return $this; + } + + /** + * Maintain a history of all items that have been transferred using the batch. Adds {@see HistoryBatch}. + * + * @return BatchBuilder + */ + public function keepHistory() + { + $this->history = true; + + return $this; + } + + /** + * Buffer exceptions thrown during transfer so that you can transfer as much as possible, and after a transfer + * completes, inspect each exception that was thrown. Enables the {@see ExceptionBufferingBatch} decorator. + * + * @return BatchBuilder + */ + public function bufferExceptions() + { + $this->exceptionBuffering = true; + + return $this; + } + + /** + * Notify a callable each time a batch flush completes. Enables the {@see NotifyingBatch} decorator. + * + * @param mixed $callable Callable function to notify + * + * @return BatchBuilder + * @throws InvalidArgumentException if the argument is not callable + */ + public function notify($callable) + { + $this->afterFlush = $callable; + + return $this; + } + + /** + * Configures the batch to transfer batches of requests. Associates a {@see \Guzzle\Http\BatchRequestTransfer} + * object as both the transfer and divisor strategy. + * + * @param int $batchSize Batch size for each batch of requests + * + * @return BatchBuilder + */ + public function transferRequests($batchSize = 50) + { + $className = self::$mapping['request']; + $this->transferStrategy = new $className($batchSize); + $this->divisorStrategy = $this->transferStrategy; + + return $this; + } + + /** + * Configures the batch to transfer batches commands. Associates as + * {@see \Guzzle\Service\Command\BatchCommandTransfer} as both the transfer and divisor strategy. + * + * @param int $batchSize Batch size for each batch of commands + * + * @return BatchBuilder + */ + public function transferCommands($batchSize = 50) + { + $className = self::$mapping['command']; + $this->transferStrategy = new $className($batchSize); + $this->divisorStrategy = $this->transferStrategy; + + return $this; + } + + /** + * Specify the strategy used to divide the queue into an array of batches + * + * @param BatchDivisorInterface $divisorStrategy Strategy used to divide a batch queue into batches + * + * @return BatchBuilder + */ + public function createBatchesWith(BatchDivisorInterface $divisorStrategy) + { + $this->divisorStrategy = $divisorStrategy; + + return $this; + } + + /** + * Specify the strategy used to transport the items when flush is called + * + * @param BatchTransferInterface $transferStrategy How items are transferred + * + * @return BatchBuilder + */ + public function transferWith(BatchTransferInterface $transferStrategy) + { + $this->transferStrategy = $transferStrategy; + + return $this; + } + + /** + * Create and return the instantiated batch + * + * @return BatchInterface + * @throws RuntimeException if no transfer strategy has been specified + */ + public function build() + { + if (!$this->transferStrategy) { + throw new RuntimeException('No transfer strategy has been specified'); + } + + if (!$this->divisorStrategy) { + throw new RuntimeException('No divisor strategy has been specified'); + } + + $batch = new Batch($this->transferStrategy, $this->divisorStrategy); + + if ($this->exceptionBuffering) { + $batch = new ExceptionBufferingBatch($batch); + } + + if ($this->afterFlush) { + $batch = new NotifyingBatch($batch, $this->afterFlush); + } + + if ($this->autoFlush) { + $batch = new FlushingBatch($batch, $this->autoFlush); + } + + if ($this->history) { + $batch = new HistoryBatch($batch); + } + + return $batch; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Batch/BatchClosureDivisor.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Batch/BatchClosureDivisor.php new file mode 100644 index 0000000..e0a2d95 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Batch/BatchClosureDivisor.php @@ -0,0 +1,39 @@ +callable = $callable; + $this->context = $context; + } + + public function createBatches(\SplQueue $queue) + { + return call_user_func($this->callable, $queue, $this->context); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Batch/BatchClosureTransfer.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Batch/BatchClosureTransfer.php new file mode 100644 index 0000000..9cbf1ab --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Batch/BatchClosureTransfer.php @@ -0,0 +1,40 @@ +callable = $callable; + $this->context = $context; + } + + public function transfer(array $batch) + { + return empty($batch) ? null : call_user_func($this->callable, $batch, $this->context); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Batch/BatchCommandTransfer.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Batch/BatchCommandTransfer.php new file mode 100644 index 0000000..d55ac7d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Batch/BatchCommandTransfer.php @@ -0,0 +1,75 @@ +batchSize = $batchSize; + } + + /** + * Creates batches by grouping commands by their associated client + * {@inheritdoc} + */ + public function createBatches(\SplQueue $queue) + { + $groups = new \SplObjectStorage(); + foreach ($queue as $item) { + if (!$item instanceof CommandInterface) { + throw new InvalidArgumentException('All items must implement Guzzle\Service\Command\CommandInterface'); + } + $client = $item->getClient(); + if (!$groups->contains($client)) { + $groups->attach($client, new \ArrayObject(array($item))); + } else { + $groups[$client]->append($item); + } + } + + $batches = array(); + foreach ($groups as $batch) { + $batches = array_merge($batches, array_chunk($groups[$batch]->getArrayCopy(), $this->batchSize)); + } + + return $batches; + } + + public function transfer(array $batch) + { + if (empty($batch)) { + return; + } + + // Get the client of the first found command + $client = reset($batch)->getClient(); + + // Keep a list of all commands with invalid clients + $invalid = array_filter($batch, function ($command) use ($client) { + return $command->getClient() !== $client; + }); + + if (!empty($invalid)) { + throw new InconsistentClientTransferException($invalid); + } + + $client->execute($batch); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Batch/BatchDivisorInterface.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Batch/BatchDivisorInterface.php new file mode 100644 index 0000000..0214f05 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Batch/BatchDivisorInterface.php @@ -0,0 +1,18 @@ +batchSize = $batchSize; + } + + /** + * Creates batches of requests by grouping requests by their associated curl multi object. + * {@inheritdoc} + */ + public function createBatches(\SplQueue $queue) + { + // Create batches by client objects + $groups = new \SplObjectStorage(); + foreach ($queue as $item) { + if (!$item instanceof RequestInterface) { + throw new InvalidArgumentException('All items must implement Guzzle\Http\Message\RequestInterface'); + } + $client = $item->getClient(); + if (!$groups->contains($client)) { + $groups->attach($client, array($item)); + } else { + $current = $groups[$client]; + $current[] = $item; + $groups[$client] = $current; + } + } + + $batches = array(); + foreach ($groups as $batch) { + $batches = array_merge($batches, array_chunk($groups[$batch], $this->batchSize)); + } + + return $batches; + } + + public function transfer(array $batch) + { + if ($batch) { + reset($batch)->getClient()->send($batch); + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Batch/BatchSizeDivisor.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Batch/BatchSizeDivisor.php new file mode 100644 index 0000000..67f90a5 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Batch/BatchSizeDivisor.php @@ -0,0 +1,47 @@ +size = $size; + } + + /** + * Set the size of each batch + * + * @param int $size Size of each batch + * + * @return BatchSizeDivisor + */ + public function setSize($size) + { + $this->size = $size; + + return $this; + } + + /** + * Get the size of each batch + * + * @return int + */ + public function getSize() + { + return $this->size; + } + + public function createBatches(\SplQueue $queue) + { + return array_chunk(iterator_to_array($queue, false), $this->size); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Batch/BatchTransferInterface.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Batch/BatchTransferInterface.php new file mode 100644 index 0000000..2e0b60d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Batch/BatchTransferInterface.php @@ -0,0 +1,16 @@ +batch = $batch; + $this->transferredItems = $transferredItems; + $this->transferStrategy = $transferStrategy; + $this->divisorStrategy = $divisorStrategy; + parent::__construct( + 'Exception encountered while transferring batch: ' . $exception->getMessage(), + $exception->getCode(), + $exception + ); + } + + /** + * Get the batch that we being sent when the exception occurred + * + * @return array + */ + public function getBatch() + { + return $this->batch; + } + + /** + * Get the items transferred at the point in which the exception was encountered + * + * @return array + */ + public function getTransferredItems() + { + return $this->transferredItems; + } + + /** + * Get the transfer strategy + * + * @return TransferStrategy + */ + public function getTransferStrategy() + { + return $this->transferStrategy; + } + + /** + * Get the divisor strategy + * + * @return DivisorStrategy + */ + public function getDivisorStrategy() + { + return $this->divisorStrategy; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Batch/ExceptionBufferingBatch.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Batch/ExceptionBufferingBatch.php new file mode 100644 index 0000000..d7a8928 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Batch/ExceptionBufferingBatch.php @@ -0,0 +1,50 @@ +decoratedBatch->isEmpty()) { + try { + $transferredItems = $this->decoratedBatch->flush(); + } catch (BatchTransferException $e) { + $this->exceptions[] = $e; + $transferredItems = $e->getTransferredItems(); + } + $items = array_merge($items, $transferredItems); + } + + return $items; + } + + /** + * Get the buffered exceptions + * + * @return array Array of BatchTransferException objects + */ + public function getExceptions() + { + return $this->exceptions; + } + + /** + * Clear the buffered exceptions + */ + public function clearExceptions() + { + $this->exceptions = array(); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Batch/FlushingBatch.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Batch/FlushingBatch.php new file mode 100644 index 0000000..367b684 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Batch/FlushingBatch.php @@ -0,0 +1,60 @@ +threshold = $threshold; + parent::__construct($decoratedBatch); + } + + /** + * Set the auto-flush threshold + * + * @param int $threshold The auto-flush threshold + * + * @return FlushingBatch + */ + public function setThreshold($threshold) + { + $this->threshold = $threshold; + + return $this; + } + + /** + * Get the auto-flush threshold + * + * @return int + */ + public function getThreshold() + { + return $this->threshold; + } + + public function add($item) + { + $this->decoratedBatch->add($item); + if (++$this->currentTotal >= $this->threshold) { + $this->currentTotal = 0; + $this->decoratedBatch->flush(); + } + + return $this; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Batch/HistoryBatch.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Batch/HistoryBatch.php new file mode 100644 index 0000000..e345fdc --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Batch/HistoryBatch.php @@ -0,0 +1,39 @@ +history[] = $item; + $this->decoratedBatch->add($item); + + return $this; + } + + /** + * Get the batch history + * + * @return array + */ + public function getHistory() + { + return $this->history; + } + + /** + * Clear the batch history + */ + public function clearHistory() + { + $this->history = array(); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Batch/NotifyingBatch.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Batch/NotifyingBatch.php new file mode 100644 index 0000000..96d04da --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Batch/NotifyingBatch.php @@ -0,0 +1,38 @@ +callable = $callable; + parent::__construct($decoratedBatch); + } + + public function flush() + { + $items = $this->decoratedBatch->flush(); + call_user_func($this->callable, $items); + + return $items; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Batch/composer.json b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Batch/composer.json new file mode 100644 index 0000000..12404d3 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Batch/composer.json @@ -0,0 +1,31 @@ +{ + "name": "guzzle/batch", + "description": "Guzzle batch component for batching requests, commands, or custom transfers", + "homepage": "http://guzzlephp.org/", + "keywords": ["batch", "HTTP", "REST", "guzzle"], + "license": "MIT", + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "require": { + "php": ">=5.3.2", + "guzzle/common": "self.version" + }, + "autoload": { + "psr-0": { "Guzzle\\Batch": "" } + }, + "suggest": { + "guzzle/http": "self.version", + "guzzle/service": "self.version" + }, + "target-dir": "Guzzle/Batch", + "extra": { + "branch-alias": { + "dev-master": "3.7-dev" + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Cache/AbstractCacheAdapter.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Cache/AbstractCacheAdapter.php new file mode 100644 index 0000000..a5c5271 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Cache/AbstractCacheAdapter.php @@ -0,0 +1,21 @@ +cache; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Cache/CacheAdapterFactory.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Cache/CacheAdapterFactory.php new file mode 100644 index 0000000..94e6234 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Cache/CacheAdapterFactory.php @@ -0,0 +1,117 @@ +newInstanceArgs($args); + } + } catch (\Exception $e) { + throw new RuntimeException($e->getMessage(), $e->getCode(), $e); + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Cache/CacheAdapterInterface.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Cache/CacheAdapterInterface.php new file mode 100644 index 0000000..970c9e2 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Cache/CacheAdapterInterface.php @@ -0,0 +1,55 @@ +callables = $callables; + } + + public function contains($id, array $options = null) + { + return call_user_func($this->callables['contains'], $id, $options); + } + + public function delete($id, array $options = null) + { + return call_user_func($this->callables['delete'], $id, $options); + } + + public function fetch($id, array $options = null) + { + return call_user_func($this->callables['fetch'], $id, $options); + } + + public function save($id, $data, $lifeTime = false, array $options = null) + { + return call_user_func($this->callables['save'], $id, $data, $lifeTime, $options); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Cache/DoctrineCacheAdapter.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Cache/DoctrineCacheAdapter.php new file mode 100644 index 0000000..e1aaf9f --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Cache/DoctrineCacheAdapter.php @@ -0,0 +1,41 @@ +cache = $cache; + } + + public function contains($id, array $options = null) + { + return $this->cache->contains($id); + } + + public function delete($id, array $options = null) + { + return $this->cache->delete($id); + } + + public function fetch($id, array $options = null) + { + return $this->cache->fetch($id); + } + + public function save($id, $data, $lifeTime = false, array $options = null) + { + return $this->cache->save($id, $data, $lifeTime !== false ? $lifeTime : 0); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Cache/NullCacheAdapter.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Cache/NullCacheAdapter.php new file mode 100644 index 0000000..68bd4af --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Cache/NullCacheAdapter.php @@ -0,0 +1,31 @@ +cache = $cache; + } + + public function contains($id, array $options = null) + { + return $this->cache->test($id); + } + + public function delete($id, array $options = null) + { + return $this->cache->remove($id); + } + + public function fetch($id, array $options = null) + { + return $this->cache->load($id); + } + + public function save($id, $data, $lifeTime = false, array $options = null) + { + return $this->cache->save($data, $id, array(), $lifeTime); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Cache/Zf2CacheAdapter.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Cache/Zf2CacheAdapter.php new file mode 100644 index 0000000..1fc18a5 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Cache/Zf2CacheAdapter.php @@ -0,0 +1,41 @@ +cache = $cache; + } + + public function contains($id, array $options = null) + { + return $this->cache->hasItem($id); + } + + public function delete($id, array $options = null) + { + return $this->cache->removeItem($id); + } + + public function fetch($id, array $options = null) + { + return $this->cache->getItem($id); + } + + public function save($id, $data, $lifeTime = false, array $options = null) + { + return $this->cache->setItem($id, $data); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Cache/composer.json b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Cache/composer.json new file mode 100644 index 0000000..a5d999b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Cache/composer.json @@ -0,0 +1,27 @@ +{ + "name": "guzzle/cache", + "description": "Guzzle cache adapter component", + "homepage": "http://guzzlephp.org/", + "keywords": ["cache", "adapter", "zf", "doctrine", "guzzle"], + "license": "MIT", + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "require": { + "php": ">=5.3.2", + "guzzle/common": "self.version" + }, + "autoload": { + "psr-0": { "Guzzle\\Cache": "" } + }, + "target-dir": "Guzzle/Cache", + "extra": { + "branch-alias": { + "dev-master": "3.7-dev" + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Common/AbstractHasDispatcher.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Common/AbstractHasDispatcher.php new file mode 100644 index 0000000..d1e842b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Common/AbstractHasDispatcher.php @@ -0,0 +1,49 @@ +eventDispatcher = $eventDispatcher; + + return $this; + } + + public function getEventDispatcher() + { + if (!$this->eventDispatcher) { + $this->eventDispatcher = new EventDispatcher(); + } + + return $this->eventDispatcher; + } + + public function dispatch($eventName, array $context = array()) + { + return $this->getEventDispatcher()->dispatch($eventName, new Event($context)); + } + + public function addSubscriber(EventSubscriberInterface $subscriber) + { + $this->getEventDispatcher()->addSubscriber($subscriber); + + return $this; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Common/Collection.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Common/Collection.php new file mode 100644 index 0000000..5cb1535 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Common/Collection.php @@ -0,0 +1,403 @@ +data = $data; + } + + /** + * Create a new collection from an array, validate the keys, and add default values where missing + * + * @param array $config Configuration values to apply. + * @param array $defaults Default parameters + * @param array $required Required parameter names + * + * @return self + * @throws InvalidArgumentException if a parameter is missing + */ + public static function fromConfig(array $config = array(), array $defaults = array(), array $required = array()) + { + $data = $config + $defaults; + + if ($missing = array_diff($required, array_keys($data))) { + throw new InvalidArgumentException('Config is missing the following keys: ' . implode(', ', $missing)); + } + + return new self($data); + } + + public function count() + { + return count($this->data); + } + + public function getIterator() + { + return new \ArrayIterator($this->data); + } + + public function toArray() + { + return $this->data; + } + + /** + * Removes all key value pairs + * + * @return Collection + */ + public function clear() + { + $this->data = array(); + + return $this; + } + + /** + * Get all or a subset of matching key value pairs + * + * @param array $keys Pass an array of keys to retrieve only a subset of key value pairs + * + * @return array Returns an array of all matching key value pairs + */ + public function getAll(array $keys = null) + { + return $keys ? array_intersect_key($this->data, array_flip($keys)) : $this->data; + } + + /** + * Get a specific key value. + * + * @param string $key Key to retrieve. + * + * @return mixed|null Value of the key or NULL + */ + public function get($key) + { + return isset($this->data[$key]) ? $this->data[$key] : null; + } + + /** + * Set a key value pair + * + * @param string $key Key to set + * @param mixed $value Value to set + * + * @return Collection Returns a reference to the object + */ + public function set($key, $value) + { + $this->data[$key] = $value; + + return $this; + } + + /** + * Add a value to a key. If a key of the same name has already been added, the key value will be converted into an + * array and the new value will be pushed to the end of the array. + * + * @param string $key Key to add + * @param mixed $value Value to add to the key + * + * @return Collection Returns a reference to the object. + */ + public function add($key, $value) + { + if (!array_key_exists($key, $this->data)) { + $this->data[$key] = $value; + } elseif (is_array($this->data[$key])) { + $this->data[$key][] = $value; + } else { + $this->data[$key] = array($this->data[$key], $value); + } + + return $this; + } + + /** + * Remove a specific key value pair + * + * @param string $key A key to remove + * + * @return Collection + */ + public function remove($key) + { + unset($this->data[$key]); + + return $this; + } + + /** + * Get all keys in the collection + * + * @return array + */ + public function getKeys() + { + return array_keys($this->data); + } + + /** + * Returns whether or not the specified key is present. + * + * @param string $key The key for which to check the existence. + * + * @return bool + */ + public function hasKey($key) + { + return array_key_exists($key, $this->data); + } + + /** + * Case insensitive search the keys in the collection + * + * @param string $key Key to search for + * + * @return bool|string Returns false if not found, otherwise returns the key + */ + public function keySearch($key) + { + foreach (array_keys($this->data) as $k) { + if (!strcasecmp($k, $key)) { + return $k; + } + } + + return false; + } + + /** + * Checks if any keys contains a certain value + * + * @param string $value Value to search for + * + * @return mixed Returns the key if the value was found FALSE if the value was not found. + */ + public function hasValue($value) + { + return array_search($value, $this->data); + } + + /** + * Replace the data of the object with the value of an array + * + * @param array $data Associative array of data + * + * @return Collection Returns a reference to the object + */ + public function replace(array $data) + { + $this->data = $data; + + return $this; + } + + /** + * Add and merge in a Collection or array of key value pair data. + * + * @param Collection|array $data Associative array of key value pair data + * + * @return Collection Returns a reference to the object. + */ + public function merge($data) + { + foreach ($data as $key => $value) { + $this->add($key, $value); + } + + return $this; + } + + /** + * Over write key value pairs in this collection with all of the data from an array or collection. + * + * @param array|\Traversable $data Values to override over this config + * + * @return self + */ + public function overwriteWith($data) + { + if (is_array($data)) { + $this->data = $data + $this->data; + } elseif ($data instanceof Collection) { + $this->data = $data->toArray() + $this->data; + } else { + foreach ($data as $key => $value) { + $this->data[$key] = $value; + } + } + + return $this; + } + + /** + * Returns a Collection containing all the elements of the collection after applying the callback function to each + * one. The Closure should accept three parameters: (string) $key, (string) $value, (array) $context and return a + * modified value + * + * @param \Closure $closure Closure to apply + * @param array $context Context to pass to the closure + * @param bool $static Set to TRUE to use the same class as the return rather than returning a Collection + * + * @return Collection + */ + public function map(\Closure $closure, array $context = array(), $static = true) + { + $collection = $static ? new static() : new self(); + foreach ($this as $key => $value) { + $collection->add($key, $closure($key, $value, $context)); + } + + return $collection; + } + + /** + * Iterates over each key value pair in the collection passing them to the Closure. If the Closure function returns + * true, the current value from input is returned into the result Collection. The Closure must accept three + * parameters: (string) $key, (string) $value and return Boolean TRUE or FALSE for each value. + * + * @param \Closure $closure Closure evaluation function + * @param bool $static Set to TRUE to use the same class as the return rather than returning a Collection + * + * @return Collection + */ + public function filter(\Closure $closure, $static = true) + { + $collection = ($static) ? new static() : new self(); + foreach ($this->data as $key => $value) { + if ($closure($key, $value)) { + $collection->add($key, $value); + } + } + + return $collection; + } + + public function offsetExists($offset) + { + return isset($this->data[$offset]); + } + + public function offsetGet($offset) + { + return isset($this->data[$offset]) ? $this->data[$offset] : null; + } + + public function offsetSet($offset, $value) + { + $this->data[$offset] = $value; + } + + public function offsetUnset($offset) + { + unset($this->data[$offset]); + } + + /** + * Set a value into a nested array key. Keys will be created as needed to set the value. + * + * @param string $path Path to set + * @param mixed $value Value to set at the key + * + * @return self + * @throws RuntimeException when trying to setPath using a nested path that travels through a scalar value + */ + public function setPath($path, $value) + { + $current =& $this->data; + $queue = explode('/', $path); + while (null !== ($key = array_shift($queue))) { + if (!is_array($current)) { + throw new RuntimeException("Trying to setPath {$path}, but {$key} is set and is not an array"); + } elseif (!$queue) { + $current[$key] = $value; + } elseif (isset($current[$key])) { + $current =& $current[$key]; + } else { + $current[$key] = array(); + $current =& $current[$key]; + } + } + + return $this; + } + + /** + * Gets a value from the collection using an array path (e.g. foo/baz/bar would retrieve bar from two nested arrays) + * Allows for wildcard searches which recursively combine matches up to the level at which the wildcard occurs. This + * can be useful for accepting any key of a sub-array and combining matching keys from each diverging path. + * + * @param string $path Path to traverse and retrieve a value from + * @param string $separator Character used to add depth to the search + * @param mixed $data Optional data to descend into (used when wildcards are encountered) + * + * @return mixed|null + */ + public function getPath($path, $separator = '/', $data = null) + { + if ($data === null) { + $data =& $this->data; + } + + $path = is_array($path) ? $path : explode($separator, $path); + while (null !== ($part = array_shift($path))) { + if (!is_array($data)) { + return null; + } elseif (isset($data[$part])) { + $data =& $data[$part]; + } elseif ($part != '*') { + return null; + } else { + // Perform a wildcard search by diverging and merging paths + $result = array(); + foreach ($data as $value) { + if (!$path) { + $result = array_merge_recursive($result, (array) $value); + } elseif (null !== ($test = $this->getPath($path, $separator, $value))) { + $result = array_merge_recursive($result, (array) $test); + } + } + return $result; + } + } + + return $data; + } + + /** + * Inject configuration settings into an input string + * + * @param string $input Input to inject + * + * @return string + * @deprecated + */ + public function inject($input) + { + Version::warn(__METHOD__ . ' is deprecated'); + $replace = array(); + foreach ($this->data as $key => $val) { + $replace['{' . $key . '}'] = $val; + } + + return strtr($input, $replace); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Common/Event.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Common/Event.php new file mode 100644 index 0000000..fad76a9 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Common/Event.php @@ -0,0 +1,52 @@ +context = $context; + } + + public function getIterator() + { + return new \ArrayIterator($this->context); + } + + public function offsetGet($offset) + { + return isset($this->context[$offset]) ? $this->context[$offset] : null; + } + + public function offsetSet($offset, $value) + { + $this->context[$offset] = $value; + } + + public function offsetExists($offset) + { + return isset($this->context[$offset]); + } + + public function offsetUnset($offset) + { + unset($this->context[$offset]); + } + + public function toArray() + { + return $this->context; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Common/Exception/BadMethodCallException.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Common/Exception/BadMethodCallException.php new file mode 100644 index 0000000..08d1c72 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Common/Exception/BadMethodCallException.php @@ -0,0 +1,5 @@ +shortMessage = $message; + } + + /** + * Set all of the exceptions + * + * @param array $exceptions Array of exceptions + * + * @return self + */ + public function setExceptions(array $exceptions) + { + $this->exceptions = array(); + foreach ($exceptions as $exception) { + $this->add($exception); + } + + return $this; + } + + /** + * Add exceptions to the collection + * + * @param ExceptionCollection|\Exception $e Exception to add + * + * @return ExceptionCollection; + */ + public function add($e) + { + $this->exceptions[] = $e; + if ($this->message) { + $this->message .= "\n"; + } + + $this->message .= $this->getExceptionMessage($e, 0); + + return $this; + } + + /** + * Get the total number of request exceptions + * + * @return int + */ + public function count() + { + return count($this->exceptions); + } + + /** + * Allows array-like iteration over the request exceptions + * + * @return \ArrayIterator + */ + public function getIterator() + { + return new \ArrayIterator($this->exceptions); + } + + /** + * Get the first exception in the collection + * + * @return \Exception + */ + public function getFirst() + { + return $this->exceptions ? $this->exceptions[0] : null; + } + + private function getExceptionMessage(\Exception $e, $depth = 0) + { + static $sp = ' '; + $prefix = $depth ? str_repeat($sp, $depth) : ''; + $message = "{$prefix}(" . get_class($e) . ') ' . $e->getFile() . ' line ' . $e->getLine() . "\n"; + + if ($e instanceof self) { + if ($e->shortMessage) { + $message .= "\n{$prefix}{$sp}" . str_replace("\n", "\n{$prefix}{$sp}", $e->shortMessage) . "\n"; + } + foreach ($e as $ee) { + $message .= "\n" . $this->getExceptionMessage($ee, $depth + 1); + } + } else { + $message .= "\n{$prefix}{$sp}" . str_replace("\n", "\n{$prefix}{$sp}", $e->getMessage()) . "\n"; + $message .= "\n{$prefix}{$sp}" . str_replace("\n", "\n{$prefix}{$sp}", $e->getTraceAsString()) . "\n"; + } + + return str_replace(getcwd(), '.', $message); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Common/Exception/GuzzleException.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Common/Exception/GuzzleException.php new file mode 100644 index 0000000..458e6f2 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Common/Exception/GuzzleException.php @@ -0,0 +1,8 @@ +=5.3.2", + "symfony/event-dispatcher": ">=2.1" + }, + "autoload": { + "psr-0": { "Guzzle\\Common": "" } + }, + "target-dir": "Guzzle/Common", + "extra": { + "branch-alias": { + "dev-master": "3.7-dev" + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/AbstractEntityBodyDecorator.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/AbstractEntityBodyDecorator.php new file mode 100644 index 0000000..5005a88 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/AbstractEntityBodyDecorator.php @@ -0,0 +1,221 @@ +body = $body; + } + + public function __toString() + { + return (string) $this->body; + } + + /** + * Allow decorators to implement custom methods + * + * @param string $method Missing method name + * @param array $args Method arguments + * + * @return mixed + */ + public function __call($method, array $args) + { + return call_user_func_array(array($this->body, $method), $args); + } + + public function close() + { + return $this->body->close(); + } + + public function setRewindFunction($callable) + { + $this->body->setRewindFunction($callable); + + return $this; + } + + public function rewind() + { + return $this->body->rewind(); + } + + public function compress($filter = 'zlib.deflate') + { + return $this->body->compress($filter); + } + + public function uncompress($filter = 'zlib.inflate') + { + return $this->body->uncompress($filter); + } + + public function getContentLength() + { + return $this->getSize(); + } + + public function getContentType() + { + return $this->body->getContentType(); + } + + public function getContentMd5($rawOutput = false, $base64Encode = false) + { + $hash = Stream::getHash($this, 'md5', $rawOutput); + + return $hash && $base64Encode ? base64_encode($hash) : $hash; + } + + public function getContentEncoding() + { + return $this->body->getContentEncoding(); + } + + public function getMetaData($key = null) + { + return $this->body->getMetaData($key); + } + + public function getStream() + { + return $this->body->getStream(); + } + + public function setStream($stream, $size = 0) + { + $this->body->setStream($stream, $size); + + return $this; + } + + public function detachStream() + { + $this->body->detachStream(); + + return $this; + } + + public function getWrapper() + { + return $this->body->getWrapper(); + } + + public function getWrapperData() + { + return $this->body->getWrapperData(); + } + + public function getStreamType() + { + return $this->body->getStreamType(); + } + + public function getUri() + { + return $this->body->getUri(); + } + + public function getSize() + { + return $this->body->getSize(); + } + + public function isReadable() + { + return $this->body->isReadable(); + } + + public function isRepeatable() + { + return $this->isSeekable() && $this->isReadable(); + } + + public function isWritable() + { + return $this->body->isWritable(); + } + + public function isConsumed() + { + return $this->body->isConsumed(); + } + + /** + * Alias of isConsumed() + * {@inheritdoc} + */ + public function feof() + { + return $this->isConsumed(); + } + + public function isLocal() + { + return $this->body->isLocal(); + } + + public function isSeekable() + { + return $this->body->isSeekable(); + } + + public function setSize($size) + { + $this->body->setSize($size); + + return $this; + } + + public function seek($offset, $whence = SEEK_SET) + { + return $this->body->seek($offset, $whence); + } + + public function read($length) + { + return $this->body->read($length); + } + + public function write($string) + { + return $this->body->write($string); + } + + public function readLine($maxLength = null) + { + return $this->body->readLine($maxLength); + } + + public function ftell() + { + return $this->body->ftell(); + } + + public function getCustomData($key) + { + return $this->body->getCustomData($key); + } + + public function setCustomData($key, $value) + { + $this->body->setCustomData($key, $value); + + return $this; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/CachingEntityBody.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/CachingEntityBody.php new file mode 100644 index 0000000..c65c136 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/CachingEntityBody.php @@ -0,0 +1,229 @@ +remoteStream = $body; + $this->body = new EntityBody(fopen('php://temp', 'r+')); + } + + /** + * Will give the contents of the buffer followed by the exhausted remote stream. + * + * Warning: Loads the entire stream into memory + * + * @return string + */ + public function __toString() + { + $pos = $this->ftell(); + $this->rewind(); + + $str = ''; + while (!$this->isConsumed()) { + $str .= $this->read(16384); + } + + $this->seek($pos); + + return $str; + } + + public function getSize() + { + return max($this->body->getSize(), $this->remoteStream->getSize()); + } + + /** + * {@inheritdoc} + * @throws RuntimeException When seeking with SEEK_END or when seeking past the total size of the buffer stream + */ + public function seek($offset, $whence = SEEK_SET) + { + if ($whence == SEEK_SET) { + $byte = $offset; + } elseif ($whence == SEEK_CUR) { + $byte = $offset + $this->ftell(); + } else { + throw new RuntimeException(__CLASS__ . ' supports only SEEK_SET and SEEK_CUR seek operations'); + } + + // You cannot skip ahead past where you've read from the remote stream + if ($byte > $this->body->getSize()) { + throw new RuntimeException( + "Cannot seek to byte {$byte} when the buffered stream only contains {$this->body->getSize()} bytes" + ); + } + + return $this->body->seek($byte); + } + + public function rewind() + { + return $this->seek(0); + } + + /** + * Does not support custom rewind functions + * + * @throws RuntimeException + */ + public function setRewindFunction($callable) + { + throw new RuntimeException(__CLASS__ . ' does not support custom stream rewind functions'); + } + + public function read($length) + { + // Perform a regular read on any previously read data from the buffer + $data = $this->body->read($length); + $remaining = $length - strlen($data); + + // More data was requested so read from the remote stream + if ($remaining) { + // If data was written to the buffer in a position that would have been filled from the remote stream, + // then we must skip bytes on the remote stream to emulate overwriting bytes from that position. This + // mimics the behavior of other PHP stream wrappers. + $remoteData = $this->remoteStream->read($remaining + $this->skipReadBytes); + + if ($this->skipReadBytes) { + $len = strlen($remoteData); + $remoteData = substr($remoteData, $this->skipReadBytes); + $this->skipReadBytes = max(0, $this->skipReadBytes - $len); + } + + $data .= $remoteData; + $this->body->write($remoteData); + } + + return $data; + } + + public function write($string) + { + // When appending to the end of the currently read stream, you'll want to skip bytes from being read from + // the remote stream to emulate other stream wrappers. Basically replacing bytes of data of a fixed length. + $overflow = (strlen($string) + $this->ftell()) - $this->remoteStream->ftell(); + if ($overflow > 0) { + $this->skipReadBytes += $overflow; + } + + return $this->body->write($string); + } + + /** + * {@inheritdoc} + * @link http://php.net/manual/en/function.fgets.php + */ + public function readLine($maxLength = null) + { + $buffer = ''; + $size = 0; + while (!$this->isConsumed()) { + $byte = $this->read(1); + $buffer .= $byte; + // Break when a new line is found or the max length - 1 is reached + if ($byte == PHP_EOL || ++$size == $maxLength - 1) { + break; + } + } + + return $buffer; + } + + public function isConsumed() + { + return $this->body->isConsumed() && $this->remoteStream->isConsumed(); + } + + /** + * Close both the remote stream and buffer stream + */ + public function close() + { + return $this->remoteStream->close() && $this->body->close(); + } + + public function setStream($stream, $size = 0) + { + $this->remoteStream->setStream($stream, $size); + } + + public function getContentType() + { + return $this->remoteStream->getContentType(); + } + + public function getContentEncoding() + { + return $this->remoteStream->getContentEncoding(); + } + + public function getMetaData($key = null) + { + return $this->remoteStream->getMetaData($key); + } + + public function getStream() + { + return $this->remoteStream->getStream(); + } + + public function getWrapper() + { + return $this->remoteStream->getWrapper(); + } + + public function getWrapperData() + { + return $this->remoteStream->getWrapperData(); + } + + public function getStreamType() + { + return $this->remoteStream->getStreamType(); + } + + public function getUri() + { + return $this->remoteStream->getUri(); + } + + /** + * Always retrieve custom data from the remote stream + * {@inheritdoc} + */ + public function getCustomData($key) + { + return $this->remoteStream->getCustomData($key); + } + + /** + * Always set custom data on the remote stream + * {@inheritdoc} + */ + public function setCustomData($key, $value) + { + $this->remoteStream->setCustomData($key, $value); + + return $this; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Client.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Client.php new file mode 100644 index 0000000..3d7298d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Client.php @@ -0,0 +1,524 @@ +setConfig($config ?: new Collection()); + $this->initSsl(); + $this->setBaseUrl($baseUrl); + $this->defaultHeaders = new Collection(); + $this->setRequestFactory(RequestFactory::getInstance()); + $this->userAgent = $this->getDefaultUserAgent(); + if (!$this->config[self::DISABLE_REDIRECTS]) { + $this->addSubscriber(new RedirectPlugin()); + } + } + + final public function setConfig($config) + { + if ($config instanceof Collection) { + $this->config = $config; + } elseif (is_array($config)) { + $this->config = new Collection($config); + } else { + throw new InvalidArgumentException('Config must be an array or Collection'); + } + + return $this; + } + + final public function getConfig($key = false) + { + return $key ? $this->config[$key] : $this->config; + } + + /** + * Set a default request option on the client that will be used as a default for each request + * + * @param string $keyOrPath request.options key (e.g. allow_redirects) or path to a nested key (e.g. headers/foo) + * @param mixed $value Value to set + * + * @return $this + */ + public function setDefaultOption($keyOrPath, $value) + { + $keyOrPath = self::REQUEST_OPTIONS . '/' . $keyOrPath; + $this->config->setPath($keyOrPath, $value); + + return $this; + } + + /** + * Retrieve a default request option from the client + * + * @param string $keyOrPath request.options key (e.g. allow_redirects) or path to a nested key (e.g. headers/foo) + * + * @return mixed|null + */ + public function getDefaultOption($keyOrPath) + { + $keyOrPath = self::REQUEST_OPTIONS . '/' . $keyOrPath; + + return $this->config->getPath($keyOrPath); + } + + final public function setSslVerification($certificateAuthority = true, $verifyPeer = true, $verifyHost = 2) + { + $opts = $this->config[self::CURL_OPTIONS] ?: array(); + + if ($certificateAuthority === true) { + // use bundled CA bundle, set secure defaults + $opts[CURLOPT_CAINFO] = __DIR__ . '/Resources/cacert.pem'; + $opts[CURLOPT_SSL_VERIFYPEER] = true; + $opts[CURLOPT_SSL_VERIFYHOST] = 2; + } elseif ($certificateAuthority === false) { + unset($opts[CURLOPT_CAINFO]); + $opts[CURLOPT_SSL_VERIFYPEER] = false; + $opts[CURLOPT_SSL_VERIFYHOST] = 0; + } elseif ($verifyPeer !== true && $verifyPeer !== false && $verifyPeer !== 1 && $verifyPeer !== 0) { + throw new InvalidArgumentException('verifyPeer must be 1, 0 or boolean'); + } elseif ($verifyHost !== 0 && $verifyHost !== 1 && $verifyHost !== 2) { + throw new InvalidArgumentException('verifyHost must be 0, 1 or 2'); + } else { + $opts[CURLOPT_SSL_VERIFYPEER] = $verifyPeer; + $opts[CURLOPT_SSL_VERIFYHOST] = $verifyHost; + if (is_file($certificateAuthority)) { + unset($opts[CURLOPT_CAPATH]); + $opts[CURLOPT_CAINFO] = $certificateAuthority; + } elseif (is_dir($certificateAuthority)) { + unset($opts[CURLOPT_CAINFO]); + $opts[CURLOPT_CAPATH] = $certificateAuthority; + } else { + throw new RuntimeException( + 'Invalid option passed to ' . self::SSL_CERT_AUTHORITY . ': ' . $certificateAuthority + ); + } + } + + $this->config->set(self::CURL_OPTIONS, $opts); + + return $this; + } + + public function createRequest($method = 'GET', $uri = null, $headers = null, $body = null, array $options = array()) + { + if (!$uri) { + $url = $this->getBaseUrl(); + } else { + if (!is_array($uri)) { + $templateVars = null; + } else { + list($uri, $templateVars) = $uri; + } + if (strpos($uri, '://')) { + // Use absolute URLs as-is + $url = $this->expandTemplate($uri, $templateVars); + } else { + $url = Url::factory($this->getBaseUrl())->combine($this->expandTemplate($uri, $templateVars)); + } + } + + // If default headers are provided, then merge them under any explicitly provided headers for the request + if (count($this->defaultHeaders)) { + if (!$headers) { + $headers = $this->defaultHeaders->toArray(); + } elseif (is_array($headers)) { + $headers += $this->defaultHeaders->toArray(); + } elseif ($headers instanceof Collection) { + $headers = $headers->toArray() + $this->defaultHeaders->toArray(); + } + } + + return $this->prepareRequest($this->requestFactory->create($method, (string) $url, $headers, $body), $options); + } + + public function getBaseUrl($expand = true) + { + return $expand ? $this->expandTemplate($this->baseUrl) : $this->baseUrl; + } + + public function setBaseUrl($url) + { + $this->baseUrl = $url; + + return $this; + } + + public function setUserAgent($userAgent, $includeDefault = false) + { + if ($includeDefault) { + $userAgent .= ' ' . $this->getDefaultUserAgent(); + } + $this->userAgent = $userAgent; + + return $this; + } + + /** + * Get the default User-Agent string to use with Guzzle + * + * @return string + */ + public function getDefaultUserAgent() + { + return 'Guzzle/' . Version::VERSION + . ' curl/' . CurlVersion::getInstance()->get('version') + . ' PHP/' . PHP_VERSION; + } + + public function get($uri = null, $headers = null, $options = array()) + { + // BC compat: $options can be a string, resource, etc to specify where the response body is downloaded + return is_array($options) + ? $this->createRequest('GET', $uri, $headers, null, $options) + : $this->createRequest('GET', $uri, $headers, $options); + } + + public function head($uri = null, $headers = null, array $options = array()) + { + return $this->createRequest('HEAD', $uri, $headers, null, $options); + } + + public function delete($uri = null, $headers = null, $body = null, array $options = array()) + { + return $this->createRequest('DELETE', $uri, $headers, $body, $options); + } + + public function put($uri = null, $headers = null, $body = null, array $options = array()) + { + return $this->createRequest('PUT', $uri, $headers, $body, $options); + } + + public function patch($uri = null, $headers = null, $body = null, array $options = array()) + { + return $this->createRequest('PATCH', $uri, $headers, $body, $options); + } + + public function post($uri = null, $headers = null, $postBody = null, array $options = array()) + { + return $this->createRequest('POST', $uri, $headers, $postBody, $options); + } + + public function options($uri = null, array $options = array()) + { + return $this->createRequest('OPTIONS', $uri, $options); + } + + public function send($requests) + { + if (!($requests instanceof RequestInterface)) { + return $this->sendMultiple($requests); + } + + try { + /** @var $requests RequestInterface */ + $this->getCurlMulti()->add($requests)->send(); + return $requests->getResponse(); + } catch (ExceptionCollection $e) { + throw $e->getFirst(); + } + } + + /** + * Set a curl multi object to be used internally by the client for transferring requests. + * + * @param CurlMultiInterface $curlMulti Multi object + * + * @return self + */ + public function setCurlMulti(CurlMultiInterface $curlMulti) + { + $this->curlMulti = $curlMulti; + + return $this; + } + + /** + * @return CurlMultiInterface|CurlMultiProxy + */ + public function getCurlMulti() + { + if (!$this->curlMulti) { + $this->curlMulti = new CurlMultiProxy( + self::MAX_HANDLES, + $this->getConfig('select_timeout') ?: self::DEFAULT_SELECT_TIMEOUT + ); + } + + return $this->curlMulti; + } + + public function setRequestFactory(RequestFactoryInterface $factory) + { + $this->requestFactory = $factory; + + return $this; + } + + /** + * Set the URI template expander to use with the client + * + * @param UriTemplateInterface $uriTemplate URI template expander + * + * @return self + */ + public function setUriTemplate(UriTemplateInterface $uriTemplate) + { + $this->uriTemplate = $uriTemplate; + + return $this; + } + + /** + * Expand a URI template while merging client config settings into the template variables + * + * @param string $template Template to expand + * @param array $variables Variables to inject + * + * @return string + */ + protected function expandTemplate($template, array $variables = null) + { + $expansionVars = $this->getConfig()->toArray(); + if ($variables) { + $expansionVars = $variables + $expansionVars; + } + + return $this->getUriTemplate()->expand($template, $expansionVars); + } + + /** + * Get the URI template expander used by the client + * + * @return UriTemplateInterface + */ + protected function getUriTemplate() + { + if (!$this->uriTemplate) { + $this->uriTemplate = ParserRegistry::getInstance()->getParser('uri_template'); + } + + return $this->uriTemplate; + } + + /** + * Send multiple requests in parallel + * + * @param array $requests Array of RequestInterface objects + * + * @return array Returns an array of Response objects + */ + protected function sendMultiple(array $requests) + { + $curlMulti = $this->getCurlMulti(); + foreach ($requests as $request) { + $curlMulti->add($request); + } + $curlMulti->send(); + + /** @var $request RequestInterface */ + $result = array(); + foreach ($requests as $request) { + $result[] = $request->getResponse(); + } + + return $result; + } + + /** + * Prepare a request to be sent from the Client by adding client specific behaviors and properties to the request. + * + * @param RequestInterface $request Request to prepare for the client + * @param array $options Options to apply to the request + * + * @return RequestInterface + */ + protected function prepareRequest(RequestInterface $request, array $options = array()) + { + $request->setClient($this)->setEventDispatcher(clone $this->getEventDispatcher()); + + if ($curl = $this->config[self::CURL_OPTIONS]) { + $request->getCurlOptions()->overwriteWith(CurlHandle::parseCurlConfig($curl)); + } + + if ($params = $this->config[self::REQUEST_PARAMS]) { + Version::warn('request.params is deprecated. Use request.options to add default request options.'); + $request->getParams()->overwriteWith($params); + } + + if ($this->userAgent && !$request->hasHeader('User-Agent')) { + $request->setHeader('User-Agent', $this->userAgent); + } + + if ($defaults = $this->config[self::REQUEST_OPTIONS]) { + $this->requestFactory->applyOptions($request, $defaults, RequestFactoryInterface::OPTIONS_AS_DEFAULTS); + } + + if ($options) { + $this->requestFactory->applyOptions($request, $options); + } + + $this->dispatch('client.create_request', array('client' => $this, 'request' => $request)); + + return $request; + } + + /** + * Initializes SSL settings + */ + protected function initSsl() + { + $authority = $this->config[self::SSL_CERT_AUTHORITY]; + + if ($authority === 'system') { + return; + } + + if ($authority === null) { + $authority = true; + } + + if ($authority === true && substr(__FILE__, 0, 7) == 'phar://') { + $authority = self::extractPharCacert(__DIR__ . '/Resources/cacert.pem'); + } + + $this->setSslVerification($authority); + } + + /** + * @deprecated + */ + public function getDefaultHeaders() + { + Version::warn(__METHOD__ . ' is deprecated. Use the request.options array to retrieve default request options'); + return $this->defaultHeaders; + } + + /** + * @deprecated + */ + public function setDefaultHeaders($headers) + { + Version::warn(__METHOD__ . ' is deprecated. Use the request.options array to specify default request options'); + if ($headers instanceof Collection) { + $this->defaultHeaders = $headers; + } elseif (is_array($headers)) { + $this->defaultHeaders = new Collection($headers); + } else { + throw new InvalidArgumentException('Headers must be an array or Collection'); + } + + return $this; + } + + /** + * @deprecated + */ + public function preparePharCacert($md5Check = true) + { + return sys_get_temp_dir() . '/guzzle-cacert.pem'; + } + + /** + * Copies the phar cacert from a phar into the temp directory. + * + * @param string $pharCacertPath Path to the phar cacert. For example: + * 'phar://aws.phar/Guzzle/Http/Resources/cacert.pem' + * + * @return string Returns the path to the extracted cacert file. + * @throws \RuntimeException Throws if the phar cacert cannot be found or + * the file cannot be copied to the temp dir. + */ + public static function extractPharCacert($pharCacertPath) + { + // Copy the cacert.pem file from the phar if it is not in the temp + // folder. + $certFile = sys_get_temp_dir() . '/guzzle-cacert.pem'; + + if (!file_exists($pharCacertPath)) { + throw new \RuntimeException("Could not find $pharCacertPath"); + } + + if (!file_exists($certFile) || + filesize($certFile) != filesize($pharCacertPath) + ) { + if (!copy($pharCacertPath, $certFile)) { + throw new \RuntimeException( + "Could not copy {$pharCacertPath} to {$certFile}: " + . var_export(error_get_last(), true) + ); + } + } + + return $certFile; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/ClientInterface.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/ClientInterface.php new file mode 100644 index 0000000..10e4de2 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/ClientInterface.php @@ -0,0 +1,223 @@ +getCurlOptions(); + $mediator = new RequestMediator($request, $requestCurlOptions->get('emit_io')); + $tempContentLength = null; + $method = $request->getMethod(); + $bodyAsString = $requestCurlOptions->get(self::BODY_AS_STRING); + + // Prepare url + $url = (string)$request->getUrl(); + if(($pos = strpos($url, '#')) !== false ){ + // strip fragment from url + $url = substr($url, 0, $pos); + } + + // Array of default cURL options. + $curlOptions = array( + CURLOPT_URL => $url, + CURLOPT_CONNECTTIMEOUT => 150, + CURLOPT_RETURNTRANSFER => false, + CURLOPT_HEADER => false, + CURLOPT_PORT => $request->getPort(), + CURLOPT_HTTPHEADER => array(), + CURLOPT_WRITEFUNCTION => array($mediator, 'writeResponseBody'), + CURLOPT_HEADERFUNCTION => array($mediator, 'receiveResponseHeader'), + CURLOPT_HTTP_VERSION => $request->getProtocolVersion() === '1.0' + ? CURL_HTTP_VERSION_1_0 : CURL_HTTP_VERSION_1_1, + // Verifies the authenticity of the peer's certificate + CURLOPT_SSL_VERIFYPEER => 1, + // Certificate must indicate that the server is the server to which you meant to connect + CURLOPT_SSL_VERIFYHOST => 2 + ); + + if (defined('CURLOPT_PROTOCOLS')) { + // Allow only HTTP and HTTPS protocols + $curlOptions[CURLOPT_PROTOCOLS] = CURLPROTO_HTTP | CURLPROTO_HTTPS; + } + + // Add CURLOPT_ENCODING if Accept-Encoding header is provided + if ($acceptEncodingHeader = $request->getHeader('Accept-Encoding')) { + $curlOptions[CURLOPT_ENCODING] = (string) $acceptEncodingHeader; + // Let cURL set the Accept-Encoding header, prevents duplicate values + $request->removeHeader('Accept-Encoding'); + } + + // Enable curl debug information if the 'debug' param was set + if ($requestCurlOptions->get('debug')) { + $curlOptions[CURLOPT_STDERR] = fopen('php://temp', 'r+'); + // @codeCoverageIgnoreStart + if (false === $curlOptions[CURLOPT_STDERR]) { + throw new RuntimeException('Unable to create a stream for CURLOPT_STDERR'); + } + // @codeCoverageIgnoreEnd + $curlOptions[CURLOPT_VERBOSE] = true; + } + + // Specify settings according to the HTTP method + if ($method == 'GET') { + $curlOptions[CURLOPT_HTTPGET] = true; + } elseif ($method == 'HEAD') { + $curlOptions[CURLOPT_NOBODY] = true; + // HEAD requests do not use a write function + unset($curlOptions[CURLOPT_WRITEFUNCTION]); + } elseif (!($request instanceof EntityEnclosingRequest)) { + $curlOptions[CURLOPT_CUSTOMREQUEST] = $method; + } else { + + $curlOptions[CURLOPT_CUSTOMREQUEST] = $method; + + // Handle sending raw bodies in a request + if ($request->getBody()) { + // You can send the body as a string using curl's CURLOPT_POSTFIELDS + if ($bodyAsString) { + $curlOptions[CURLOPT_POSTFIELDS] = (string) $request->getBody(); + // Allow curl to add the Content-Length for us to account for the times when + // POST redirects are followed by GET requests + if ($tempContentLength = $request->getHeader('Content-Length')) { + $tempContentLength = (int) (string) $tempContentLength; + } + // Remove the curl generated Content-Type header if none was set manually + if (!$request->hasHeader('Content-Type')) { + $curlOptions[CURLOPT_HTTPHEADER][] = 'Content-Type:'; + } + } else { + $curlOptions[CURLOPT_UPLOAD] = true; + // Let cURL handle setting the Content-Length header + if ($tempContentLength = $request->getHeader('Content-Length')) { + $tempContentLength = (int) (string) $tempContentLength; + $curlOptions[CURLOPT_INFILESIZE] = $tempContentLength; + } + // Add a callback for curl to read data to send with the request only if a body was specified + $curlOptions[CURLOPT_READFUNCTION] = array($mediator, 'readRequestBody'); + // Attempt to seek to the start of the stream + $request->getBody()->seek(0); + } + + } else { + + // Special handling for POST specific fields and files + $postFields = false; + if (count($request->getPostFiles())) { + $postFields = $request->getPostFields()->useUrlEncoding(false)->urlEncode(); + foreach ($request->getPostFiles() as $key => $data) { + $prefixKeys = count($data) > 1; + foreach ($data as $index => $file) { + // Allow multiple files in the same key + $fieldKey = $prefixKeys ? "{$key}[{$index}]" : $key; + $postFields[$fieldKey] = $file->getCurlValue(); + } + } + } elseif (count($request->getPostFields())) { + $postFields = (string) $request->getPostFields()->useUrlEncoding(true); + } + + if ($postFields !== false) { + if ($method == 'POST') { + unset($curlOptions[CURLOPT_CUSTOMREQUEST]); + $curlOptions[CURLOPT_POST] = true; + } + $curlOptions[CURLOPT_POSTFIELDS] = $postFields; + $request->removeHeader('Content-Length'); + } + } + + // If the Expect header is not present, prevent curl from adding it + if (!$request->hasHeader('Expect')) { + $curlOptions[CURLOPT_HTTPHEADER][] = 'Expect:'; + } + } + + // If a Content-Length header was specified but we want to allow curl to set one for us + if (null !== $tempContentLength) { + $request->removeHeader('Content-Length'); + } + + // Set custom cURL options + foreach ($requestCurlOptions->toArray() as $key => $value) { + if (is_numeric($key)) { + $curlOptions[$key] = $value; + } + } + + // Do not set an Accept header by default + if (!isset($curlOptions[CURLOPT_ENCODING])) { + $curlOptions[CURLOPT_HTTPHEADER][] = 'Accept:'; + } + + // Add any custom headers to the request. Empty headers will cause curl to not send the header at all. + foreach ($request->getHeaderLines() as $line) { + $curlOptions[CURLOPT_HTTPHEADER][] = $line; + } + + // Add the content-length header back if it was temporarily removed + if (null !== $tempContentLength) { + $request->setHeader('Content-Length', $tempContentLength); + } + + // Apply the options to a new cURL handle. + $handle = curl_init(); + + // Enable the progress function if the 'progress' param was set + if ($requestCurlOptions->get('progress')) { + // Wrap the function in a function that provides the curl handle to the mediator's progress function + // Using this rather than injecting the handle into the mediator prevents a circular reference + $curlOptions[CURLOPT_PROGRESSFUNCTION] = function () use ($mediator, $handle) { + $args = func_get_args(); + $args[] = $handle; + + // PHP 5.5 pushed the handle onto the start of the args + if (is_resource($args[0])) { + array_shift($args); + } + + call_user_func_array(array($mediator, 'progress'), $args); + }; + $curlOptions[CURLOPT_NOPROGRESS] = false; + } + + curl_setopt_array($handle, $curlOptions); + + return new static($handle, $curlOptions); + } + + /** + * Construct a new CurlHandle object that wraps a cURL handle + * + * @param resource $handle Configured cURL handle resource + * @param Collection|array $options Curl options to use with the handle + * + * @throws InvalidArgumentException + */ + public function __construct($handle, $options) + { + if (!is_resource($handle)) { + throw new InvalidArgumentException('Invalid handle provided'); + } + if (is_array($options)) { + $this->options = new Collection($options); + } elseif ($options instanceof Collection) { + $this->options = $options; + } else { + throw new InvalidArgumentException('Expected array or Collection'); + } + $this->handle = $handle; + } + + /** + * Destructor + */ + public function __destruct() + { + $this->close(); + } + + /** + * Close the curl handle + */ + public function close() + { + if (is_resource($this->handle)) { + curl_close($this->handle); + } + $this->handle = null; + } + + /** + * Check if the handle is available and still OK + * + * @return bool + */ + public function isAvailable() + { + return is_resource($this->handle); + } + + /** + * Get the last error that occurred on the cURL handle + * + * @return string + */ + public function getError() + { + return $this->isAvailable() ? curl_error($this->handle) : ''; + } + + /** + * Get the last error number that occurred on the cURL handle + * + * @return int + */ + public function getErrorNo() + { + if ($this->errorNo) { + return $this->errorNo; + } + + return $this->isAvailable() ? curl_errno($this->handle) : CURLE_OK; + } + + /** + * Set the curl error number + * + * @param int $error Error number to set + * + * @return CurlHandle + */ + public function setErrorNo($error) + { + $this->errorNo = $error; + + return $this; + } + + /** + * Get cURL curl_getinfo data + * + * @param int $option Option to retrieve. Pass null to retrieve all data as an array. + * + * @return array|mixed + */ + public function getInfo($option = null) + { + if (!is_resource($this->handle)) { + return null; + } + + if (null !== $option) { + return curl_getinfo($this->handle, $option) ?: null; + } + + return curl_getinfo($this->handle) ?: array(); + } + + /** + * Get the stderr output + * + * @param bool $asResource Set to TRUE to get an fopen resource + * + * @return string|resource|null + */ + public function getStderr($asResource = false) + { + $stderr = $this->getOptions()->get(CURLOPT_STDERR); + if (!$stderr) { + return null; + } + + if ($asResource) { + return $stderr; + } + + fseek($stderr, 0); + $e = stream_get_contents($stderr); + fseek($stderr, 0, SEEK_END); + + return $e; + } + + /** + * Get the URL that this handle is connecting to + * + * @return Url + */ + public function getUrl() + { + return Url::factory($this->options->get(CURLOPT_URL)); + } + + /** + * Get the wrapped curl handle + * + * @return resource|null Returns the cURL handle or null if it was closed + */ + public function getHandle() + { + return $this->isAvailable() ? $this->handle : null; + } + + /** + * Get the cURL setopt options of the handle. Changing values in the return object will have no effect on the curl + * handle after it is created. + * + * @return Collection + */ + public function getOptions() + { + return $this->options; + } + + /** + * Update a request based on the log messages of the CurlHandle + * + * @param RequestInterface $request Request to update + */ + public function updateRequestFromTransfer(RequestInterface $request) + { + if (!$request->getResponse()) { + return; + } + + // Update the transfer stats of the response + $request->getResponse()->setInfo($this->getInfo()); + + if (!$log = $this->getStderr(true)) { + return; + } + + // Parse the cURL stderr output for outgoing requests + $headers = ''; + fseek($log, 0); + while (($line = fgets($log)) !== false) { + if ($line && $line[0] == '>') { + $headers = substr(trim($line), 2) . "\r\n"; + while (($line = fgets($log)) !== false) { + if ($line[0] == '*' || $line[0] == '<') { + break; + } else { + $headers .= trim($line) . "\r\n"; + } + } + } + } + + // Add request headers to the request exactly as they were sent + if ($headers) { + $parsed = ParserRegistry::getInstance()->getParser('message')->parseRequest($headers); + if (!empty($parsed['headers'])) { + $request->setHeaders(array()); + foreach ($parsed['headers'] as $name => $value) { + $request->setHeader($name, $value); + } + } + if (!empty($parsed['version'])) { + $request->setProtocolVersion($parsed['version']); + } + } + } + + /** + * Parse the config and replace curl.* configurators into the constant based values so it can be used elsewhere + * + * @param array|Collection $config The configuration we want to parse + * + * @return array + */ + public static function parseCurlConfig($config) + { + $curlOptions = array(); + foreach ($config as $key => $value) { + if (is_string($key) && defined($key)) { + // Convert constants represented as string to constant int values + $key = constant($key); + } + if (is_string($value) && defined($value)) { + $value = constant($value); + } + $curlOptions[$key] = $value; + } + + return $curlOptions; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Curl/CurlMulti.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Curl/CurlMulti.php new file mode 100644 index 0000000..9e4e637 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Curl/CurlMulti.php @@ -0,0 +1,423 @@ + array('CURLM_BAD_HANDLE', 'The passed-in handle is not a valid CURLM handle.'), + CURLM_BAD_EASY_HANDLE => array('CURLM_BAD_EASY_HANDLE', "An easy handle was not good/valid. It could mean that it isn't an easy handle at all, or possibly that the handle already is in used by this or another multi handle."), + CURLM_OUT_OF_MEMORY => array('CURLM_OUT_OF_MEMORY', 'You are doomed.'), + CURLM_INTERNAL_ERROR => array('CURLM_INTERNAL_ERROR', 'This can only be returned if libcurl bugs. Please report it to us!') + ); + + /** @var float */ + protected $selectTimeout; + + public function __construct($selectTimeout = 1.0) + { + $this->selectTimeout = $selectTimeout; + $this->multiHandle = curl_multi_init(); + // @codeCoverageIgnoreStart + if ($this->multiHandle === false) { + throw new CurlException('Unable to create multi handle'); + } + // @codeCoverageIgnoreEnd + $this->reset(); + } + + public function __destruct() + { + if (is_resource($this->multiHandle)) { + curl_multi_close($this->multiHandle); + } + } + + public function add(RequestInterface $request) + { + $this->requests[] = $request; + // If requests are currently transferring and this is async, then the + // request must be prepared now as the send() method is not called. + $this->beforeSend($request); + $this->dispatch(self::ADD_REQUEST, array('request' => $request)); + + return $this; + } + + public function all() + { + return $this->requests; + } + + public function remove(RequestInterface $request) + { + $this->removeHandle($request); + if (($index = array_search($request, $this->requests, true)) !== false) { + $request = $this->requests[$index]; + unset($this->requests[$index]); + $this->requests = array_values($this->requests); + $this->dispatch(self::REMOVE_REQUEST, array('request' => $request)); + return true; + } + + return false; + } + + public function reset($hard = false) + { + // Remove each request + if ($this->requests) { + foreach ($this->requests as $request) { + $this->remove($request); + } + } + + $this->handles = new \SplObjectStorage(); + $this->requests = $this->resourceHash = $this->exceptions = $this->successful = array(); + } + + public function send() + { + $this->perform(); + $exceptions = $this->exceptions; + $successful = $this->successful; + $this->reset(); + + if ($exceptions) { + $this->throwMultiException($exceptions, $successful); + } + } + + public function count() + { + return count($this->requests); + } + + /** + * Build and throw a MultiTransferException + * + * @param array $exceptions Exceptions encountered + * @param array $successful Successful requests + * @throws MultiTransferException + */ + protected function throwMultiException(array $exceptions, array $successful) + { + $multiException = new MultiTransferException('Errors during multi transfer'); + + while ($e = array_shift($exceptions)) { + $multiException->addFailedRequestWithException($e['request'], $e['exception']); + } + + // Add successful requests + foreach ($successful as $request) { + if (!$multiException->containsRequest($request)) { + $multiException->addSuccessfulRequest($request); + } + } + + throw $multiException; + } + + /** + * Prepare for sending + * + * @param RequestInterface $request Request to prepare + * @throws \Exception on error preparing the request + */ + protected function beforeSend(RequestInterface $request) + { + try { + $state = $request->setState(RequestInterface::STATE_TRANSFER); + if ($state == RequestInterface::STATE_TRANSFER) { + $this->addHandle($request); + } else { + // Requests might decide they don't need to be sent just before + // transfer (e.g. CachePlugin) + $this->remove($request); + if ($state == RequestInterface::STATE_COMPLETE) { + $this->successful[] = $request; + } + } + } catch (\Exception $e) { + // Queue the exception to be thrown when sent + $this->removeErroredRequest($request, $e); + } + } + + private function addHandle(RequestInterface $request) + { + $handle = $this->createCurlHandle($request)->getHandle(); + $this->checkCurlResult( + curl_multi_add_handle($this->multiHandle, $handle) + ); + } + + /** + * Create a curl handle for a request + * + * @param RequestInterface $request Request + * + * @return CurlHandle + */ + protected function createCurlHandle(RequestInterface $request) + { + $wrapper = CurlHandle::factory($request); + $this->handles[$request] = $wrapper; + $this->resourceHash[(int) $wrapper->getHandle()] = $request; + + return $wrapper; + } + + /** + * Get the data from the multi handle + */ + protected function perform() + { + $event = new Event(array('curl_multi' => $this)); + + while ($this->requests) { + // Notify each request as polling + $blocking = $total = 0; + foreach ($this->requests as $request) { + ++$total; + $event['request'] = $request; + $request->getEventDispatcher()->dispatch(self::POLLING_REQUEST, $event); + // The blocking variable just has to be non-falsey to block the loop + if ($request->getParams()->hasKey(self::BLOCKING)) { + ++$blocking; + } + } + if ($blocking == $total) { + // Sleep to prevent eating CPU because no requests are actually pending a select call + usleep(500); + } else { + $this->executeHandles(); + } + } + } + + /** + * Execute and select curl handles + */ + private function executeHandles() + { + // The first curl_multi_select often times out no matter what, but is usually required for fast transfers + $selectTimeout = 0.001; + $active = false; + do { + while (($mrc = curl_multi_exec($this->multiHandle, $active)) == CURLM_CALL_MULTI_PERFORM); + $this->checkCurlResult($mrc); + $this->processMessages(); + if ($active && curl_multi_select($this->multiHandle, $selectTimeout) === -1) { + // Perform a usleep if a select returns -1: https://bugs.php.net/bug.php?id=61141 + usleep(150); + } + $selectTimeout = $this->selectTimeout; + } while ($active); + } + + /** + * Process any received curl multi messages + */ + private function processMessages() + { + while ($done = curl_multi_info_read($this->multiHandle)) { + $request = $this->resourceHash[(int) $done['handle']]; + try { + $this->processResponse($request, $this->handles[$request], $done); + $this->successful[] = $request; + } catch (\Exception $e) { + $this->removeErroredRequest($request, $e); + } + } + } + + /** + * Remove a request that encountered an exception + * + * @param RequestInterface $request Request to remove + * @param \Exception $e Exception encountered + */ + protected function removeErroredRequest(RequestInterface $request, \Exception $e = null) + { + $this->exceptions[] = array('request' => $request, 'exception' => $e); + $this->remove($request); + $this->dispatch(self::MULTI_EXCEPTION, array('exception' => $e, 'all_exceptions' => $this->exceptions)); + } + + /** + * Check for errors and fix headers of a request based on a curl response + * + * @param RequestInterface $request Request to process + * @param CurlHandle $handle Curl handle object + * @param array $curl Array returned from curl_multi_info_read + * + * @throws CurlException on Curl error + */ + protected function processResponse(RequestInterface $request, CurlHandle $handle, array $curl) + { + // Set the transfer stats on the response + $handle->updateRequestFromTransfer($request); + // Check if a cURL exception occurred, and if so, notify things + $curlException = $this->isCurlException($request, $handle, $curl); + + // Always remove completed curl handles. They can be added back again + // via events if needed (e.g. ExponentialBackoffPlugin) + $this->removeHandle($request); + + if (!$curlException) { + if ($this->validateResponseWasSet($request)) { + $state = $request->setState( + RequestInterface::STATE_COMPLETE, + array('handle' => $handle) + ); + // Only remove the request if it wasn't resent as a result of + // the state change + if ($state != RequestInterface::STATE_TRANSFER) { + $this->remove($request); + } + } + return; + } + + // Set the state of the request to an error + $state = $request->setState(RequestInterface::STATE_ERROR, array('exception' => $curlException)); + // Allow things to ignore the error if possible + if ($state != RequestInterface::STATE_TRANSFER) { + $this->remove($request); + } + + // The error was not handled, so fail + if ($state == RequestInterface::STATE_ERROR) { + /** @var CurlException $curlException */ + throw $curlException; + } + } + + /** + * Remove a curl handle from the curl multi object + * + * @param RequestInterface $request Request that owns the handle + */ + protected function removeHandle(RequestInterface $request) + { + if (isset($this->handles[$request])) { + $handle = $this->handles[$request]; + curl_multi_remove_handle($this->multiHandle, $handle->getHandle()); + unset($this->handles[$request]); + unset($this->resourceHash[(int) $handle->getHandle()]); + $handle->close(); + } + } + + /** + * Check if a cURL transfer resulted in what should be an exception + * + * @param RequestInterface $request Request to check + * @param CurlHandle $handle Curl handle object + * @param array $curl Array returned from curl_multi_info_read + * + * @return CurlException|bool + */ + private function isCurlException(RequestInterface $request, CurlHandle $handle, array $curl) + { + if (CURLM_OK == $curl['result'] || CURLM_CALL_MULTI_PERFORM == $curl['result']) { + return false; + } + + $handle->setErrorNo($curl['result']); + $e = new CurlException(sprintf('[curl] %s: %s [url] %s', + $handle->getErrorNo(), $handle->getError(), $handle->getUrl())); + $e->setCurlHandle($handle) + ->setRequest($request) + ->setCurlInfo($handle->getInfo()) + ->setError($handle->getError(), $handle->getErrorNo()); + + return $e; + } + + /** + * Throw an exception for a cURL multi response if needed + * + * @param int $code Curl response code + * @throws CurlException + */ + private function checkCurlResult($code) + { + if ($code != CURLM_OK && $code != CURLM_CALL_MULTI_PERFORM) { + throw new CurlException(isset($this->multiErrors[$code]) + ? "cURL error: {$code} ({$this->multiErrors[$code][0]}): cURL message: {$this->multiErrors[$code][1]}" + : 'Unexpected cURL error: ' . $code + ); + } + } + + /** + * @link https://github.com/guzzle/guzzle/issues/710 + */ + private function validateResponseWasSet(RequestInterface $request) + { + if ($request->getResponse()) { + return true; + } + + $body = $request instanceof EntityEnclosingRequestInterface + ? $request->getBody() + : null; + + if (!$body) { + $rex = new RequestException( + 'No response was received for a request with no body. This' + . ' could mean that you are saturating your network.' + ); + $rex->setRequest($request); + $this->removeErroredRequest($request, $rex); + } elseif (!$body->isSeekable() || !$body->seek(0)) { + // Nothing we can do with this. Sorry! + $rex = new RequestException( + 'The connection was unexpectedly closed. The request would' + . ' have been retried, but attempting to rewind the' + . ' request body failed.' + ); + $rex->setRequest($request); + $this->removeErroredRequest($request, $rex); + } else { + $this->remove($request); + // Add the request back to the batch to retry automatically. + $this->requests[] = $request; + $this->addHandle($request); + } + + return false; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Curl/CurlMultiInterface.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Curl/CurlMultiInterface.php new file mode 100644 index 0000000..0ead757 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Curl/CurlMultiInterface.php @@ -0,0 +1,58 @@ +maxHandles = $maxHandles; + $this->selectTimeout = $selectTimeout; + // You can get some weird "Too many open files" errors when sending a large amount of requests in parallel. + // These two statements autoload classes before a system runs out of file descriptors so that you can get back + // valuable error messages if you run out. + class_exists('Guzzle\Http\Message\Response'); + class_exists('Guzzle\Http\Exception\CurlException'); + } + + public function add(RequestInterface $request) + { + $this->queued[] = $request; + + return $this; + } + + public function all() + { + $requests = $this->queued; + foreach ($this->handles as $handle) { + $requests = array_merge($requests, $handle->all()); + } + + return $requests; + } + + public function remove(RequestInterface $request) + { + foreach ($this->queued as $i => $r) { + if ($request === $r) { + unset($this->queued[$i]); + return true; + } + } + + foreach ($this->handles as $handle) { + if ($handle->remove($request)) { + return true; + } + } + + return false; + } + + public function reset($hard = false) + { + $this->queued = array(); + $this->groups = array(); + foreach ($this->handles as $handle) { + $handle->reset(); + } + if ($hard) { + $this->handles = array(); + } + + return $this; + } + + public function send() + { + if ($this->queued) { + $group = $this->getAvailableHandle(); + // Add this handle to a list of handles than is claimed + $this->groups[] = $group; + while ($request = array_shift($this->queued)) { + $group->add($request); + } + try { + $group->send(); + array_pop($this->groups); + $this->cleanupHandles(); + } catch (\Exception $e) { + // Remove the group and cleanup if an exception was encountered and no more requests in group + if (!$group->count()) { + array_pop($this->groups); + $this->cleanupHandles(); + } + throw $e; + } + } + } + + public function count() + { + return count($this->all()); + } + + /** + * Get an existing available CurlMulti handle or create a new one + * + * @return CurlMulti + */ + protected function getAvailableHandle() + { + // Grab a handle that is not claimed + foreach ($this->handles as $h) { + if (!in_array($h, $this->groups, true)) { + return $h; + } + } + + // All are claimed, so create one + $handle = new CurlMulti($this->selectTimeout); + $handle->setEventDispatcher($this->getEventDispatcher()); + $this->handles[] = $handle; + + return $handle; + } + + /** + * Trims down unused CurlMulti handles to limit the number of open connections + */ + protected function cleanupHandles() + { + if ($diff = max(0, count($this->handles) - $this->maxHandles)) { + for ($i = count($this->handles) - 1; $i > 0 && $diff > 0; $i--) { + if (!count($this->handles[$i])) { + unset($this->handles[$i]); + $diff--; + } + } + $this->handles = array_values($this->handles); + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Curl/CurlVersion.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Curl/CurlVersion.php new file mode 100644 index 0000000..c3f99dd --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Curl/CurlVersion.php @@ -0,0 +1,66 @@ +version) { + $this->version = curl_version(); + } + + return $this->version; + } + + /** + * Get a specific type of curl information + * + * @param string $type Version information to retrieve. This value is one of: + * - version_number: cURL 24 bit version number + * - version: cURL version number, as a string + * - ssl_version_number: OpenSSL 24 bit version number + * - ssl_version: OpenSSL version number, as a string + * - libz_version: zlib version number, as a string + * - host: Information about the host where cURL was built + * - features: A bitmask of the CURL_VERSION_XXX constants + * - protocols: An array of protocols names supported by cURL + * + * @return string|float|bool if the $type is found, and false if not found + */ + public function get($type) + { + $version = $this->getAll(); + + return isset($version[$type]) ? $version[$type] : false; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Curl/RequestMediator.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Curl/RequestMediator.php new file mode 100644 index 0000000..e2c4878 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Curl/RequestMediator.php @@ -0,0 +1,149 @@ +request = $request; + $this->emitIo = $emitIo; + } + + /** + * Receive a response header from curl + * + * @param resource $curl Curl handle + * @param string $header Received header + * + * @return int + */ + public function receiveResponseHeader($curl, $header) + { + static $normalize = array("\r", "\n"); + $length = strlen($header); + $header = str_replace($normalize, '', $header); + + if (strpos($header, 'HTTP/') === 0) { + + $startLine = explode(' ', $header, 3); + list($protocol, $version) = explode('/', trim($startLine[0])); + $code = $startLine[1]; + $status = isset($startLine[2]) ? $startLine[2] : ''; + + // Only download the body of the response to the specified response + // body when a successful response is received. + if ($code >= 200 && $code < 300) { + $body = $this->request->getResponseBody(); + } else { + $body = EntityBody::factory(); + } + + $response = new Response($code, null, $body); + $response->setProtocol($protocol, $version); + $response->setStatus($code, $status); + $this->request->startResponse($response); + + $this->request->dispatch('request.receive.status_line', array( + 'request' => $this, + 'line' => $header, + 'status_code' => $code, + 'reason_phrase' => $status + )); + + } elseif ($pos = strpos($header, ':')) { + $this->request->getResponse()->addHeader( + trim(substr($header, 0, $pos)), + trim(substr($header, $pos + 1)) + ); + } + + return $length; + } + + /** + * Received a progress notification + * + * @param int $downloadSize Total download size + * @param int $downloaded Amount of bytes downloaded + * @param int $uploadSize Total upload size + * @param int $uploaded Amount of bytes uploaded + * @param resource $handle CurlHandle object + */ + public function progress($downloadSize, $downloaded, $uploadSize, $uploaded, $handle = null) + { + $this->request->dispatch('curl.callback.progress', array( + 'request' => $this->request, + 'handle' => $handle, + 'download_size' => $downloadSize, + 'downloaded' => $downloaded, + 'upload_size' => $uploadSize, + 'uploaded' => $uploaded + )); + } + + /** + * Write data to the response body of a request + * + * @param resource $curl Curl handle + * @param string $write Data that was received + * + * @return int + */ + public function writeResponseBody($curl, $write) + { + if ($this->emitIo) { + $this->request->dispatch('curl.callback.write', array( + 'request' => $this->request, + 'write' => $write + )); + } + + if ($response = $this->request->getResponse()) { + return $response->getBody()->write($write); + } else { + // Unexpected data received before response headers - abort transfer + return 0; + } + } + + /** + * Read data from the request body and send it to curl + * + * @param resource $ch Curl handle + * @param resource $fd File descriptor + * @param int $length Amount of data to read + * + * @return string + */ + public function readRequestBody($ch, $fd, $length) + { + if (!($body = $this->request->getBody())) { + return ''; + } + + $read = (string) $body->read($length); + if ($this->emitIo) { + $this->request->dispatch('curl.callback.read', array('request' => $this->request, 'read' => $read)); + } + + return $read; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/EntityBody.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/EntityBody.php new file mode 100644 index 0000000..b60d170 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/EntityBody.php @@ -0,0 +1,201 @@ +rewindFunction = $callable; + + return $this; + } + + public function rewind() + { + return $this->rewindFunction ? call_user_func($this->rewindFunction, $this) : parent::rewind(); + } + + /** + * Create a new EntityBody from a string + * + * @param string $string String of data + * + * @return EntityBody + */ + public static function fromString($string) + { + $stream = fopen('php://temp', 'r+'); + if ($string !== '') { + fwrite($stream, $string); + rewind($stream); + } + + return new static($stream); + } + + public function compress($filter = 'zlib.deflate') + { + $result = $this->handleCompression($filter); + $this->contentEncoding = $result ? $filter : false; + + return $result; + } + + public function uncompress($filter = 'zlib.inflate') + { + $offsetStart = 0; + + // When inflating gzipped data, the first 10 bytes must be stripped + // if a gzip header is present + if ($filter == 'zlib.inflate') { + // @codeCoverageIgnoreStart + if (!$this->isReadable() || ($this->isConsumed() && !$this->isSeekable())) { + return false; + } + // @codeCoverageIgnoreEnd + if (stream_get_contents($this->stream, 3, 0) === "\x1f\x8b\x08") { + $offsetStart = 10; + } + } + + $this->contentEncoding = false; + + return $this->handleCompression($filter, $offsetStart); + } + + public function getContentLength() + { + return $this->getSize(); + } + + public function getContentType() + { + return $this->getUri() ? Mimetypes::getInstance()->fromFilename($this->getUri()) : null; + } + + public function getContentMd5($rawOutput = false, $base64Encode = false) + { + if ($hash = self::getHash($this, 'md5', $rawOutput)) { + return $hash && $base64Encode ? base64_encode($hash) : $hash; + } else { + return false; + } + } + + /** + * Calculate the MD5 hash of an entity body + * + * @param EntityBodyInterface $body Entity body to calculate the hash for + * @param bool $rawOutput Whether or not to use raw output + * @param bool $base64Encode Whether or not to base64 encode raw output (only if raw output is true) + * + * @return bool|string Returns an MD5 string on success or FALSE on failure + * @deprecated This will be deprecated soon + * @codeCoverageIgnore + */ + public static function calculateMd5(EntityBodyInterface $body, $rawOutput = false, $base64Encode = false) + { + Version::warn(__CLASS__ . ' is deprecated. Use getContentMd5()'); + return $body->getContentMd5($rawOutput, $base64Encode); + } + + public function setStreamFilterContentEncoding($streamFilterContentEncoding) + { + $this->contentEncoding = $streamFilterContentEncoding; + + return $this; + } + + public function getContentEncoding() + { + return strtr($this->contentEncoding, array( + 'zlib.deflate' => 'gzip', + 'bzip2.compress' => 'compress' + )) ?: false; + } + + protected function handleCompression($filter, $offsetStart = 0) + { + // @codeCoverageIgnoreStart + if (!$this->isReadable() || ($this->isConsumed() && !$this->isSeekable())) { + return false; + } + // @codeCoverageIgnoreEnd + + $handle = fopen('php://temp', 'r+'); + $filter = @stream_filter_append($handle, $filter, STREAM_FILTER_WRITE); + if (!$filter) { + return false; + } + + // Seek to the offset start if possible + $this->seek($offsetStart); + while ($data = fread($this->stream, 8096)) { + fwrite($handle, $data); + } + + fclose($this->stream); + $this->stream = $handle; + stream_filter_remove($filter); + $stat = fstat($this->stream); + $this->size = $stat['size']; + $this->rebuildCache(); + $this->seek(0); + + // Remove any existing rewind function as the underlying stream has been replaced + $this->rewindFunction = null; + + return true; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/EntityBodyInterface.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/EntityBodyInterface.php new file mode 100644 index 0000000..e640f57 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/EntityBodyInterface.php @@ -0,0 +1,73 @@ +isClientError()) { + $label = 'Client error response'; + $class = __NAMESPACE__ . '\\ClientErrorResponseException'; + } elseif ($response->isServerError()) { + $label = 'Server error response'; + $class = __NAMESPACE__ . '\\ServerErrorResponseException'; + } else { + $label = 'Unsuccessful response'; + $class = __CLASS__; + } + + $message = $label . PHP_EOL . implode(PHP_EOL, array( + '[status code] ' . $response->getStatusCode(), + '[reason phrase] ' . $response->getReasonPhrase(), + '[url] ' . $request->getUrl(), + )); + + $e = new $class($message); + $e->setResponse($response); + $e->setRequest($request); + + return $e; + } + + /** + * Set the response that caused the exception + * + * @param Response $response Response to set + */ + public function setResponse(Response $response) + { + $this->response = $response; + } + + /** + * Get the response that caused the exception + * + * @return Response + */ + public function getResponse() + { + return $this->response; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Exception/ClientErrorResponseException.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Exception/ClientErrorResponseException.php new file mode 100644 index 0000000..04d7ddc --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Exception/ClientErrorResponseException.php @@ -0,0 +1,8 @@ +curlError = $error; + $this->curlErrorNo = $number; + + return $this; + } + + /** + * Set the associated curl handle + * + * @param CurlHandle $handle Curl handle + * + * @return self + */ + public function setCurlHandle(CurlHandle $handle) + { + $this->handle = $handle; + + return $this; + } + + /** + * Get the associated cURL handle + * + * @return CurlHandle|null + */ + public function getCurlHandle() + { + return $this->handle; + } + + /** + * Get the associated cURL error message + * + * @return string|null + */ + public function getError() + { + return $this->curlError; + } + + /** + * Get the associated cURL error number + * + * @return int|null + */ + public function getErrorNo() + { + return $this->curlErrorNo; + } + + /** + * Returns curl information about the transfer + * + * @return array + */ + public function getCurlInfo() + { + return $this->curlInfo; + } + + /** + * Set curl transfer information + * + * @param array $info Array of curl transfer information + * + * @return self + * @link http://php.net/manual/en/function.curl-getinfo.php + */ + public function setCurlInfo(array $info) + { + $this->curlInfo = $info; + + return $this; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Exception/HttpException.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Exception/HttpException.php new file mode 100644 index 0000000..ee87295 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Exception/HttpException.php @@ -0,0 +1,10 @@ +successfulRequests, $this->failedRequests); + } + + /** + * Add to the array of successful requests + * + * @param RequestInterface $request Successful request + * + * @return self + */ + public function addSuccessfulRequest(RequestInterface $request) + { + $this->successfulRequests[] = $request; + + return $this; + } + + /** + * Add to the array of failed requests + * + * @param RequestInterface $request Failed request + * + * @return self + */ + public function addFailedRequest(RequestInterface $request) + { + $this->failedRequests[] = $request; + + return $this; + } + + /** + * Add to the array of failed requests and associate with exceptions + * + * @param RequestInterface $request Failed request + * @param \Exception $exception Exception to add and associate with + * + * @return self + */ + public function addFailedRequestWithException(RequestInterface $request, \Exception $exception) + { + $this->add($exception) + ->addFailedRequest($request) + ->exceptionForRequest[spl_object_hash($request)] = $exception; + + return $this; + } + + /** + * Get the Exception that caused the given $request to fail + * + * @param RequestInterface $request Failed command + * + * @return \Exception|null + */ + public function getExceptionForFailedRequest(RequestInterface $request) + { + $oid = spl_object_hash($request); + + return isset($this->exceptionForRequest[$oid]) ? $this->exceptionForRequest[$oid] : null; + } + + /** + * Set all of the successful requests + * + * @param array Array of requests + * + * @return self + */ + public function setSuccessfulRequests(array $requests) + { + $this->successfulRequests = $requests; + + return $this; + } + + /** + * Set all of the failed requests + * + * @param array Array of requests + * + * @return self + */ + public function setFailedRequests(array $requests) + { + $this->failedRequests = $requests; + + return $this; + } + + /** + * Get an array of successful requests sent in the multi transfer + * + * @return array + */ + public function getSuccessfulRequests() + { + return $this->successfulRequests; + } + + /** + * Get an array of failed requests sent in the multi transfer + * + * @return array + */ + public function getFailedRequests() + { + return $this->failedRequests; + } + + /** + * Check if the exception object contains a request + * + * @param RequestInterface $request Request to check + * + * @return bool + */ + public function containsRequest(RequestInterface $request) + { + return in_array($request, $this->failedRequests, true) || in_array($request, $this->successfulRequests, true); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Exception/RequestException.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Exception/RequestException.php new file mode 100644 index 0000000..274df2c --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Exception/RequestException.php @@ -0,0 +1,39 @@ +request = $request; + + return $this; + } + + /** + * Get the request that caused the exception + * + * @return RequestInterface + */ + public function getRequest() + { + return $this->request; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Exception/ServerErrorResponseException.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Exception/ServerErrorResponseException.php new file mode 100644 index 0000000..f0f7cfe --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Exception/ServerErrorResponseException.php @@ -0,0 +1,8 @@ +eventDispatcher = $eventDispatcher; + + return $this; + } + + public function getEventDispatcher() + { + if (!$this->eventDispatcher) { + $this->eventDispatcher = new EventDispatcher(); + } + + return $this->eventDispatcher; + } + + public function dispatch($eventName, array $context = array()) + { + return $this->getEventDispatcher()->dispatch($eventName, new Event($context)); + } + + /** + * {@inheritdoc} + * @codeCoverageIgnore + */ + public function addSubscriber(EventSubscriberInterface $subscriber) + { + $this->getEventDispatcher()->addSubscriber($subscriber); + + return $this; + } + + public function read($length) + { + $event = array( + 'body' => $this, + 'length' => $length, + 'read' => $this->body->read($length) + ); + $this->dispatch('body.read', $event); + + return $event['read']; + } + + public function write($string) + { + $event = array( + 'body' => $this, + 'write' => $string, + 'result' => $this->body->write($string) + ); + $this->dispatch('body.write', $event); + + return $event['result']; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Message/AbstractMessage.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Message/AbstractMessage.php new file mode 100644 index 0000000..0d066ff --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Message/AbstractMessage.php @@ -0,0 +1,220 @@ +params = new Collection(); + $this->headerFactory = new HeaderFactory(); + $this->headers = new HeaderCollection(); + } + + /** + * Set the header factory to use to create headers + * + * @param HeaderFactoryInterface $factory + * + * @return self + */ + public function setHeaderFactory(HeaderFactoryInterface $factory) + { + $this->headerFactory = $factory; + + return $this; + } + + public function getParams() + { + return $this->params; + } + + public function addHeader($header, $value) + { + if (isset($this->headers[$header])) { + $this->headers[$header]->add($value); + } elseif ($value instanceof HeaderInterface) { + $this->headers[$header] = $value; + } else { + $this->headers[$header] = $this->headerFactory->createHeader($header, $value); + } + + return $this; + } + + public function addHeaders(array $headers) + { + foreach ($headers as $key => $value) { + $this->addHeader($key, $value); + } + + return $this; + } + + public function getHeader($header) + { + return $this->headers[$header]; + } + + public function getHeaders() + { + return $this->headers; + } + + public function getHeaderLines() + { + $headers = array(); + foreach ($this->headers as $value) { + $headers[] = $value->getName() . ': ' . $value; + } + + return $headers; + } + + public function setHeader($header, $value) + { + unset($this->headers[$header]); + $this->addHeader($header, $value); + + return $this; + } + + public function setHeaders(array $headers) + { + $this->headers->clear(); + foreach ($headers as $key => $value) { + $this->addHeader($key, $value); + } + + return $this; + } + + public function hasHeader($header) + { + return isset($this->headers[$header]); + } + + public function removeHeader($header) + { + unset($this->headers[$header]); + + return $this; + } + + /** + * @deprecated Use $message->getHeader()->parseParams() + * @codeCoverageIgnore + */ + public function getTokenizedHeader($header, $token = ';') + { + Version::warn(__METHOD__ . ' is deprecated. Use $message->getHeader()->parseParams()'); + if ($this->hasHeader($header)) { + $data = new Collection(); + foreach ($this->getHeader($header)->parseParams() as $values) { + foreach ($values as $key => $value) { + if ($value === '') { + $data->set($data->count(), $key); + } else { + $data->add($key, $value); + } + } + } + return $data; + } + } + + /** + * @deprecated + * @codeCoverageIgnore + */ + public function setTokenizedHeader($header, $data, $token = ';') + { + Version::warn(__METHOD__ . ' is deprecated.'); + return $this; + } + + /** + * @deprecated + * @codeCoverageIgnore + */ + public function getCacheControlDirective($directive) + { + Version::warn(__METHOD__ . ' is deprecated. Use $message->getHeader(\'Cache-Control\')->getDirective()'); + if (!($header = $this->getHeader('Cache-Control'))) { + return null; + } + + return $header->getDirective($directive); + } + + /** + * @deprecated + * @codeCoverageIgnore + */ + public function hasCacheControlDirective($directive) + { + Version::warn(__METHOD__ . ' is deprecated. Use $message->getHeader(\'Cache-Control\')->hasDirective()'); + if ($header = $this->getHeader('Cache-Control')) { + return $header->hasDirective($directive); + } else { + return false; + } + } + + /** + * @deprecated + * @codeCoverageIgnore + */ + public function addCacheControlDirective($directive, $value = true) + { + Version::warn(__METHOD__ . ' is deprecated. Use $message->getHeader(\'Cache-Control\')->addDirective()'); + if (!($header = $this->getHeader('Cache-Control'))) { + $this->addHeader('Cache-Control', ''); + $header = $this->getHeader('Cache-Control'); + } + + $header->addDirective($directive, $value); + + return $this; + } + + /** + * @deprecated + * @codeCoverageIgnore + */ + public function removeCacheControlDirective($directive) + { + Version::warn(__METHOD__ . ' is deprecated. Use $message->getHeader(\'Cache-Control\')->removeDirective()'); + if ($header = $this->getHeader('Cache-Control')) { + $header->removeDirective($directive); + } + + return $this; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Message/EntityEnclosingRequest.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Message/EntityEnclosingRequest.php new file mode 100644 index 0000000..212850a --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Message/EntityEnclosingRequest.php @@ -0,0 +1,247 @@ +postFields = new QueryString(); + parent::__construct($method, $url, $headers); + } + + /** + * @return string + */ + public function __toString() + { + // Only attempt to include the POST data if it's only fields + if (count($this->postFields) && empty($this->postFiles)) { + return parent::__toString() . (string) $this->postFields; + } + + return parent::__toString() . $this->body; + } + + public function setState($state, array $context = array()) + { + parent::setState($state, $context); + if ($state == self::STATE_TRANSFER && !$this->body && !count($this->postFields) && !count($this->postFiles)) { + $this->setHeader('Content-Length', 0)->removeHeader('Transfer-Encoding'); + } + + return $this->state; + } + + public function setBody($body, $contentType = null) + { + $this->body = EntityBody::factory($body); + + // Auto detect the Content-Type from the path of the request if possible + if ($contentType === null && !$this->hasHeader('Content-Type')) { + $contentType = $this->body->getContentType(); + } + + if ($contentType) { + $this->setHeader('Content-Type', $contentType); + } + + // Always add the Expect 100-Continue header if the body cannot be rewound. This helps with redirects. + if (!$this->body->isSeekable() && $this->expectCutoff !== false) { + $this->setHeader('Expect', '100-Continue'); + } + + // Set the Content-Length header if it can be determined + $size = $this->body->getContentLength(); + if ($size !== null && $size !== false) { + $this->setHeader('Content-Length', $size); + if ($size > $this->expectCutoff) { + $this->setHeader('Expect', '100-Continue'); + } + } elseif (!$this->hasHeader('Content-Length')) { + if ('1.1' == $this->protocolVersion) { + $this->setHeader('Transfer-Encoding', 'chunked'); + } else { + throw new RequestException( + 'Cannot determine Content-Length and cannot use chunked Transfer-Encoding when using HTTP/1.0' + ); + } + } + + return $this; + } + + public function getBody() + { + return $this->body; + } + + /** + * Set the size that the entity body of the request must exceed before adding the Expect: 100-Continue header. + * + * @param int|bool $size Cutoff in bytes. Set to false to never send the expect header (even with non-seekable data) + * + * @return self + */ + public function setExpectHeaderCutoff($size) + { + $this->expectCutoff = $size; + if ($size === false || !$this->body) { + $this->removeHeader('Expect'); + } elseif ($this->body && $this->body->getSize() && $this->body->getSize() > $size) { + $this->setHeader('Expect', '100-Continue'); + } + + return $this; + } + + public function configureRedirects($strict = false, $maxRedirects = 5) + { + $this->getParams()->set(RedirectPlugin::STRICT_REDIRECTS, $strict); + if ($maxRedirects == 0) { + $this->getParams()->set(RedirectPlugin::DISABLE, true); + } else { + $this->getParams()->set(RedirectPlugin::MAX_REDIRECTS, $maxRedirects); + } + + return $this; + } + + public function getPostField($field) + { + return $this->postFields->get($field); + } + + public function getPostFields() + { + return $this->postFields; + } + + public function setPostField($key, $value) + { + $this->postFields->set($key, $value); + $this->processPostFields(); + + return $this; + } + + public function addPostFields($fields) + { + $this->postFields->merge($fields); + $this->processPostFields(); + + return $this; + } + + public function removePostField($field) + { + $this->postFields->remove($field); + $this->processPostFields(); + + return $this; + } + + public function getPostFiles() + { + return $this->postFiles; + } + + public function getPostFile($fieldName) + { + return isset($this->postFiles[$fieldName]) ? $this->postFiles[$fieldName] : null; + } + + public function removePostFile($fieldName) + { + unset($this->postFiles[$fieldName]); + $this->processPostFields(); + + return $this; + } + + public function addPostFile($field, $filename = null, $contentType = null, $postname = null) + { + $data = null; + + if ($field instanceof PostFileInterface) { + $data = $field; + } elseif (is_array($filename)) { + // Allow multiple values to be set in a single key + foreach ($filename as $file) { + $this->addPostFile($field, $file, $contentType); + } + return $this; + } elseif (!is_string($filename)) { + throw new RequestException('The path to a file must be a string'); + } elseif (!empty($filename)) { + // Adding an empty file will cause cURL to error out + $data = new PostFile($field, $filename, $contentType, $postname); + } + + if ($data) { + if (!isset($this->postFiles[$data->getFieldName()])) { + $this->postFiles[$data->getFieldName()] = array($data); + } else { + $this->postFiles[$data->getFieldName()][] = $data; + } + $this->processPostFields(); + } + + return $this; + } + + public function addPostFiles(array $files) + { + foreach ($files as $key => $file) { + if ($file instanceof PostFileInterface) { + $this->addPostFile($file, null, null, false); + } elseif (is_string($file)) { + // Convert non-associative array keys into 'file' + if (is_numeric($key)) { + $key = 'file'; + } + $this->addPostFile($key, $file, null, false); + } else { + throw new RequestException('File must be a string or instance of PostFileInterface'); + } + } + + return $this; + } + + /** + * Determine what type of request should be sent based on post fields + */ + protected function processPostFields() + { + if (!$this->postFiles) { + $this->removeHeader('Expect')->setHeader('Content-Type', self::URL_ENCODED); + } else { + $this->setHeader('Content-Type', self::MULTIPART); + if ($this->expectCutoff !== false) { + $this->setHeader('Expect', '100-Continue'); + } + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Message/EntityEnclosingRequestInterface.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Message/EntityEnclosingRequestInterface.php new file mode 100644 index 0000000..49ad459 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Message/EntityEnclosingRequestInterface.php @@ -0,0 +1,137 @@ + filenames where filename can be a string or PostFileInterface + * + * @return self + */ + public function addPostFiles(array $files); + + /** + * Configure how redirects are handled for the request + * + * @param bool $strict Set to true to follow strict RFC compliance when redirecting POST requests. Most + * browsers with follow a 301-302 redirect for a POST request with a GET request. This is + * the default behavior of Guzzle. Enable strict redirects to redirect these responses + * with a POST rather than a GET request. + * @param int $maxRedirects Specify the maximum number of allowed redirects. Set to 0 to disable redirects. + * + * @return self + */ + public function configureRedirects($strict = false, $maxRedirects = 5); +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Message/Header.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Message/Header.php new file mode 100644 index 0000000..50597b2 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Message/Header.php @@ -0,0 +1,182 @@ +header = trim($header); + $this->glue = $glue; + + foreach ((array) $values as $value) { + foreach ((array) $value as $v) { + $this->values[] = $v; + } + } + } + + public function __toString() + { + return implode($this->glue . ' ', $this->toArray()); + } + + public function add($value) + { + $this->values[] = $value; + + return $this; + } + + public function getName() + { + return $this->header; + } + + public function setName($name) + { + $this->header = $name; + + return $this; + } + + public function setGlue($glue) + { + $this->glue = $glue; + + return $this; + } + + public function getGlue() + { + return $this->glue; + } + + /** + * Normalize the header to be a single header with an array of values. + * + * If any values of the header contains the glue string value (e.g. ","), then the value will be exploded into + * multiple entries in the header. + * + * @return self + */ + public function normalize() + { + $values = $this->toArray(); + + for ($i = 0, $total = count($values); $i < $total; $i++) { + if (strpos($values[$i], $this->glue) !== false) { + // Explode on glue when the glue is not inside of a comma + foreach (preg_split('/' . preg_quote($this->glue) . '(?=([^"]*"[^"]*")*[^"]*$)/', $values[$i]) as $v) { + $values[] = trim($v); + } + unset($values[$i]); + } + } + + $this->values = array_values($values); + + return $this; + } + + public function hasValue($searchValue) + { + return in_array($searchValue, $this->toArray()); + } + + public function removeValue($searchValue) + { + $this->values = array_values(array_filter($this->values, function ($value) use ($searchValue) { + return $value != $searchValue; + })); + + return $this; + } + + public function toArray() + { + return $this->values; + } + + public function count() + { + return count($this->toArray()); + } + + public function getIterator() + { + return new \ArrayIterator($this->toArray()); + } + + public function parseParams() + { + $params = $matches = array(); + $callback = array($this, 'trimHeader'); + + // Normalize the header into a single array and iterate over all values + foreach ($this->normalize()->toArray() as $val) { + $part = array(); + foreach (preg_split('/;(?=([^"]*"[^"]*")*[^"]*$)/', $val) as $kvp) { + if (!preg_match_all('/<[^>]+>|[^=]+/', $kvp, $matches)) { + continue; + } + $pieces = array_map($callback, $matches[0]); + $part[$pieces[0]] = isset($pieces[1]) ? $pieces[1] : ''; + } + if ($part) { + $params[] = $part; + } + } + + return $params; + } + + /** + * @deprecated + * @codeCoverageIgnore + */ + public function hasExactHeader($header) + { + Version::warn(__METHOD__ . ' is deprecated'); + return $this->header == $header; + } + + /** + * @deprecated + * @codeCoverageIgnore + */ + public function raw() + { + Version::warn(__METHOD__ . ' is deprecated. Use toArray()'); + return $this->toArray(); + } + + /** + * Trim a header by removing excess spaces and wrapping quotes + * + * @param $str + * + * @return string + */ + protected function trimHeader($str) + { + static $trimmed = "\"' \n\t"; + + return trim($str, $trimmed); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Message/Header/CacheControl.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Message/Header/CacheControl.php new file mode 100644 index 0000000..77789e5 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Message/Header/CacheControl.php @@ -0,0 +1,121 @@ +directives = null; + } + + public function removeValue($searchValue) + { + parent::removeValue($searchValue); + $this->directives = null; + } + + /** + * Check if a specific cache control directive exists + * + * @param string $param Directive to retrieve + * + * @return bool + */ + public function hasDirective($param) + { + $directives = $this->getDirectives(); + + return isset($directives[$param]); + } + + /** + * Get a specific cache control directive + * + * @param string $param Directive to retrieve + * + * @return string|bool|null + */ + public function getDirective($param) + { + $directives = $this->getDirectives(); + + return isset($directives[$param]) ? $directives[$param] : null; + } + + /** + * Add a cache control directive + * + * @param string $param Directive to add + * @param string $value Value to set + * + * @return self + */ + public function addDirective($param, $value) + { + $directives = $this->getDirectives(); + $directives[$param] = $value; + $this->updateFromDirectives($directives); + + return $this; + } + + /** + * Remove a cache control directive by name + * + * @param string $param Directive to remove + * + * @return self + */ + public function removeDirective($param) + { + $directives = $this->getDirectives(); + unset($directives[$param]); + $this->updateFromDirectives($directives); + + return $this; + } + + /** + * Get an associative array of cache control directives + * + * @return array + */ + public function getDirectives() + { + if ($this->directives === null) { + $this->directives = array(); + foreach ($this->parseParams() as $collection) { + foreach ($collection as $key => $value) { + $this->directives[$key] = $value === '' ? true : $value; + } + } + } + + return $this->directives; + } + + /** + * Updates the header value based on the parsed directives + * + * @param array $directives Array of cache control directives + */ + protected function updateFromDirectives(array $directives) + { + $this->directives = $directives; + $this->values = array(); + + foreach ($directives as $key => $value) { + $this->values[] = $value === true ? $key : "{$key}={$value}"; + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Message/Header/HeaderCollection.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Message/Header/HeaderCollection.php new file mode 100644 index 0000000..8c7f6ae --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Message/Header/HeaderCollection.php @@ -0,0 +1,108 @@ +headers = $headers; + } + + public function __clone() + { + foreach ($this->headers as &$header) { + $header = clone $header; + } + } + + /** + * Clears the header collection + */ + public function clear() + { + $this->headers = array(); + } + + /** + * Set a header on the collection + * + * @param HeaderInterface $header Header to add + * + * @return self + */ + public function add(HeaderInterface $header) + { + $this->headers[strtolower($header->getName())] = $header; + + return $this; + } + + /** + * Get an array of header objects + * + * @return array + */ + public function getAll() + { + return $this->headers; + } + + /** + * Alias of offsetGet + */ + public function get($key) + { + return $this->offsetGet($key); + } + + public function count() + { + return count($this->headers); + } + + public function offsetExists($offset) + { + return isset($this->headers[strtolower($offset)]); + } + + public function offsetGet($offset) + { + $l = strtolower($offset); + + return isset($this->headers[$l]) ? $this->headers[$l] : null; + } + + public function offsetSet($offset, $value) + { + $this->add($value); + } + + public function offsetUnset($offset) + { + unset($this->headers[strtolower($offset)]); + } + + public function getIterator() + { + return new \ArrayIterator($this->headers); + } + + public function toArray() + { + $result = array(); + foreach ($this->headers as $header) { + $result[$header->getName()] = $header->toArray(); + } + + return $result; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Message/Header/HeaderFactory.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Message/Header/HeaderFactory.php new file mode 100644 index 0000000..0273be5 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Message/Header/HeaderFactory.php @@ -0,0 +1,26 @@ + 'Guzzle\Http\Message\Header\CacheControl', + 'link' => 'Guzzle\Http\Message\Header\Link', + ); + + public function createHeader($header, $value = null) + { + $lowercase = strtolower($header); + + return isset($this->mapping[$lowercase]) + ? new $this->mapping[$lowercase]($header, $value) + : new Header($header, $value); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Message/Header/HeaderFactoryInterface.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Message/Header/HeaderFactoryInterface.php new file mode 100644 index 0000000..9457cf6 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Message/Header/HeaderFactoryInterface.php @@ -0,0 +1,19 @@ +", "rel=\"{$rel}\""); + + foreach ($params as $k => $v) { + $values[] = "{$k}=\"{$v}\""; + } + + return $this->add(implode('; ', $values)); + } + + /** + * Check if a specific link exists for a given rel attribute + * + * @param string $rel rel value + * + * @return bool + */ + public function hasLink($rel) + { + return $this->getLink($rel) !== null; + } + + /** + * Get a specific link for a given rel attribute + * + * @param string $rel Rel value + * + * @return array|null + */ + public function getLink($rel) + { + foreach ($this->getLinks() as $link) { + if (isset($link['rel']) && $link['rel'] == $rel) { + return $link; + } + } + + return null; + } + + /** + * Get an associative array of links + * + * For example: + * Link: ; rel=front; type="image/jpeg", ; rel=back; type="image/jpeg" + * + * + * var_export($response->getLinks()); + * array( + * array( + * 'url' => 'http:/.../front.jpeg', + * 'rel' => 'back', + * 'type' => 'image/jpeg', + * ) + * ) + * + * + * @return array + */ + public function getLinks() + { + $links = $this->parseParams(); + + foreach ($links as &$link) { + $key = key($link); + unset($link[$key]); + $link['url'] = trim($key, '<> '); + } + + return $links; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Message/MessageInterface.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Message/MessageInterface.php new file mode 100644 index 0000000..62bcd43 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Message/MessageInterface.php @@ -0,0 +1,102 @@ +fieldName = $fieldName; + $this->setFilename($filename); + $this->postname = $postname ? $postname : basename($filename); + $this->contentType = $contentType ?: $this->guessContentType(); + } + + public function setFieldName($name) + { + $this->fieldName = $name; + + return $this; + } + + public function getFieldName() + { + return $this->fieldName; + } + + public function setFilename($filename) + { + // Remove leading @ symbol + if (strpos($filename, '@') === 0) { + $filename = substr($filename, 1); + } + + if (!is_readable($filename)) { + throw new InvalidArgumentException("Unable to open {$filename} for reading"); + } + + $this->filename = $filename; + + return $this; + } + + public function setPostname($postname) + { + $this->postname = $postname; + + return $this; + } + + public function getFilename() + { + return $this->filename; + } + + public function getPostname() + { + return $this->postname; + } + + public function setContentType($type) + { + $this->contentType = $type; + + return $this; + } + + public function getContentType() + { + return $this->contentType; + } + + public function getCurlValue() + { + // PHP 5.5 introduced a CurlFile object that deprecates the old @filename syntax + // See: https://wiki.php.net/rfc/curl-file-upload + if (function_exists('curl_file_create')) { + return curl_file_create($this->filename, $this->contentType, $this->postname); + } + + // Use the old style if using an older version of PHP + $value = "@{$this->filename};filename=" . $this->postname; + if ($this->contentType) { + $value .= ';type=' . $this->contentType; + } + + return $value; + } + + /** + * @deprecated + * @codeCoverageIgnore + */ + public function getCurlString() + { + Version::warn(__METHOD__ . ' is deprecated. Use getCurlValue()'); + return $this->getCurlValue(); + } + + /** + * Determine the Content-Type of the file + */ + protected function guessContentType() + { + return Mimetypes::getInstance()->fromFilename($this->filename) ?: 'application/octet-stream'; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Message/PostFileInterface.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Message/PostFileInterface.php new file mode 100644 index 0000000..7f0779d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Message/PostFileInterface.php @@ -0,0 +1,83 @@ +method = strtoupper($method); + $this->curlOptions = new Collection(); + $this->setUrl($url); + + if ($headers) { + // Special handling for multi-value headers + foreach ($headers as $key => $value) { + // Deal with collisions with Host and Authorization + if ($key == 'host' || $key == 'Host') { + $this->setHeader($key, $value); + } elseif ($value instanceof HeaderInterface) { + $this->addHeader($key, $value); + } else { + foreach ((array) $value as $v) { + $this->addHeader($key, $v); + } + } + } + } + + $this->setState(self::STATE_NEW); + } + + public function __clone() + { + if ($this->eventDispatcher) { + $this->eventDispatcher = clone $this->eventDispatcher; + } + $this->curlOptions = clone $this->curlOptions; + $this->params = clone $this->params; + $this->url = clone $this->url; + $this->response = $this->responseBody = null; + $this->headers = clone $this->headers; + + $this->setState(RequestInterface::STATE_NEW); + $this->dispatch('request.clone', array('request' => $this)); + } + + /** + * Get the HTTP request as a string + * + * @return string + */ + public function __toString() + { + return $this->getRawHeaders() . "\r\n\r\n"; + } + + /** + * Default method that will throw exceptions if an unsuccessful response is received. + * + * @param Event $event Received + * @throws BadResponseException if the response is not successful + */ + public static function onRequestError(Event $event) + { + $e = BadResponseException::factory($event['request'], $event['response']); + $event['request']->setState(self::STATE_ERROR, array('exception' => $e) + $event->toArray()); + throw $e; + } + + public function setClient(ClientInterface $client) + { + $this->client = $client; + + return $this; + } + + public function getClient() + { + return $this->client; + } + + public function getRawHeaders() + { + $protocolVersion = $this->protocolVersion ?: '1.1'; + + return trim($this->method . ' ' . $this->getResource()) . ' ' + . strtoupper(str_replace('https', 'http', $this->url->getScheme())) + . '/' . $protocolVersion . "\r\n" . implode("\r\n", $this->getHeaderLines()); + } + + public function setUrl($url) + { + if ($url instanceof Url) { + $this->url = $url; + } else { + $this->url = Url::factory($url); + } + + // Update the port and host header + $this->setPort($this->url->getPort()); + + if ($this->url->getUsername() || $this->url->getPassword()) { + $this->setAuth($this->url->getUsername(), $this->url->getPassword()); + // Remove the auth info from the URL + $this->url->setUsername(null); + $this->url->setPassword(null); + } + + return $this; + } + + public function send() + { + if (!$this->client) { + throw new RuntimeException('A client must be set on the request'); + } + + return $this->client->send($this); + } + + public function getResponse() + { + return $this->response; + } + + public function getQuery($asString = false) + { + return $asString + ? (string) $this->url->getQuery() + : $this->url->getQuery(); + } + + public function getMethod() + { + return $this->method; + } + + public function getScheme() + { + return $this->url->getScheme(); + } + + public function setScheme($scheme) + { + $this->url->setScheme($scheme); + + return $this; + } + + public function getHost() + { + return $this->url->getHost(); + } + + public function setHost($host) + { + $this->url->setHost($host); + $this->setPort($this->url->getPort()); + + return $this; + } + + public function getProtocolVersion() + { + return $this->protocolVersion; + } + + public function setProtocolVersion($protocol) + { + $this->protocolVersion = $protocol; + + return $this; + } + + public function getPath() + { + return '/' . ltrim($this->url->getPath(), '/'); + } + + public function setPath($path) + { + $this->url->setPath($path); + + return $this; + } + + public function getPort() + { + return $this->url->getPort(); + } + + public function setPort($port) + { + $this->url->setPort($port); + + // Include the port in the Host header if it is not the default port for the scheme of the URL + $scheme = $this->url->getScheme(); + if ($port && (($scheme == 'http' && $port != 80) || ($scheme == 'https' && $port != 443))) { + $this->headers['host'] = $this->headerFactory->createHeader('Host', $this->url->getHost() . ':' . $port); + } else { + $this->headers['host'] = $this->headerFactory->createHeader('Host', $this->url->getHost()); + } + + return $this; + } + + public function getUsername() + { + return $this->username; + } + + public function getPassword() + { + return $this->password; + } + + public function setAuth($user, $password = '', $scheme = CURLAUTH_BASIC) + { + static $authMap = array( + 'basic' => CURLAUTH_BASIC, + 'digest' => CURLAUTH_DIGEST, + 'ntlm' => CURLAUTH_NTLM, + 'any' => CURLAUTH_ANY + ); + + // If we got false or null, disable authentication + if (!$user) { + $this->password = $this->username = null; + $this->removeHeader('Authorization'); + $this->getCurlOptions()->remove(CURLOPT_HTTPAUTH); + return $this; + } + + if (!is_numeric($scheme)) { + $scheme = strtolower($scheme); + if (!isset($authMap[$scheme])) { + throw new InvalidArgumentException($scheme . ' is not a valid authentication type'); + } + $scheme = $authMap[$scheme]; + } + + $this->username = $user; + $this->password = $password; + + // Bypass CURL when using basic auth to promote connection reuse + if ($scheme == CURLAUTH_BASIC) { + $this->getCurlOptions()->remove(CURLOPT_HTTPAUTH); + $this->setHeader('Authorization', 'Basic ' . base64_encode($this->username . ':' . $this->password)); + } else { + $this->getCurlOptions() + ->set(CURLOPT_HTTPAUTH, $scheme) + ->set(CURLOPT_USERPWD, $this->username . ':' . $this->password); + } + + return $this; + } + + public function getResource() + { + $resource = $this->getPath(); + if ($query = (string) $this->url->getQuery()) { + $resource .= '?' . $query; + } + + return $resource; + } + + public function getUrl($asObject = false) + { + return $asObject ? clone $this->url : (string) $this->url; + } + + public function getState() + { + return $this->state; + } + + public function setState($state, array $context = array()) + { + $oldState = $this->state; + $this->state = $state; + + switch ($state) { + case self::STATE_NEW: + $this->response = null; + break; + case self::STATE_TRANSFER: + if ($oldState !== $state) { + // Fix Content-Length and Transfer-Encoding collisions + if ($this->hasHeader('Transfer-Encoding') && $this->hasHeader('Content-Length')) { + $this->removeHeader('Transfer-Encoding'); + } + $this->dispatch('request.before_send', array('request' => $this)); + } + break; + case self::STATE_COMPLETE: + if ($oldState !== $state) { + $this->processResponse($context); + $this->responseBody = null; + } + break; + case self::STATE_ERROR: + if (isset($context['exception'])) { + $this->dispatch('request.exception', array( + 'request' => $this, + 'response' => isset($context['response']) ? $context['response'] : $this->response, + 'exception' => isset($context['exception']) ? $context['exception'] : null + )); + } + } + + return $this->state; + } + + public function getCurlOptions() + { + return $this->curlOptions; + } + + public function startResponse(Response $response) + { + $this->state = self::STATE_TRANSFER; + $response->setEffectiveUrl((string) $this->getUrl()); + $this->response = $response; + + return $this; + } + + public function setResponse(Response $response, $queued = false) + { + $response->setEffectiveUrl((string) $this->url); + + if ($queued) { + $ed = $this->getEventDispatcher(); + $ed->addListener('request.before_send', $f = function ($e) use ($response, &$f, $ed) { + $e['request']->setResponse($response); + $ed->removeListener('request.before_send', $f); + }, -9999); + } else { + $this->response = $response; + // If a specific response body is specified, then use it instead of the response's body + if ($this->responseBody && !$this->responseBody->getCustomData('default') && !$response->isRedirect()) { + $this->getResponseBody()->write((string) $this->response->getBody()); + } else { + $this->responseBody = $this->response->getBody(); + } + $this->setState(self::STATE_COMPLETE); + } + + return $this; + } + + public function setResponseBody($body) + { + // Attempt to open a file for writing if a string was passed + if (is_string($body)) { + // @codeCoverageIgnoreStart + if (!($body = fopen($body, 'w+'))) { + throw new InvalidArgumentException('Could not open ' . $body . ' for writing'); + } + // @codeCoverageIgnoreEnd + } + + $this->responseBody = EntityBody::factory($body); + + return $this; + } + + public function getResponseBody() + { + if ($this->responseBody === null) { + $this->responseBody = EntityBody::factory()->setCustomData('default', true); + } + + return $this->responseBody; + } + + /** + * Determine if the response body is repeatable (readable + seekable) + * + * @return bool + * @deprecated Use getResponseBody()->isSeekable() + * @codeCoverageIgnore + */ + public function isResponseBodyRepeatable() + { + Version::warn(__METHOD__ . ' is deprecated. Use $request->getResponseBody()->isRepeatable()'); + return !$this->responseBody ? true : $this->responseBody->isRepeatable(); + } + + public function getCookies() + { + if ($cookie = $this->getHeader('Cookie')) { + $data = ParserRegistry::getInstance()->getParser('cookie')->parseCookie($cookie); + return $data['cookies']; + } + + return array(); + } + + public function getCookie($name) + { + $cookies = $this->getCookies(); + + return isset($cookies[$name]) ? $cookies[$name] : null; + } + + public function addCookie($name, $value) + { + if (!$this->hasHeader('Cookie')) { + $this->setHeader('Cookie', "{$name}={$value}"); + } else { + $this->getHeader('Cookie')->add("{$name}={$value}"); + } + + // Always use semicolons to separate multiple cookie headers + $this->getHeader('Cookie')->setGlue(';'); + + return $this; + } + + public function removeCookie($name) + { + if ($cookie = $this->getHeader('Cookie')) { + foreach ($cookie as $cookieValue) { + if (strpos($cookieValue, $name . '=') === 0) { + $cookie->removeValue($cookieValue); + } + } + } + + return $this; + } + + public function setEventDispatcher(EventDispatcherInterface $eventDispatcher) + { + $this->eventDispatcher = $eventDispatcher; + $this->eventDispatcher->addListener('request.error', array(__CLASS__, 'onRequestError'), -255); + + return $this; + } + + public function getEventDispatcher() + { + if (!$this->eventDispatcher) { + $this->setEventDispatcher(new EventDispatcher()); + } + + return $this->eventDispatcher; + } + + public function dispatch($eventName, array $context = array()) + { + $context['request'] = $this; + + return $this->getEventDispatcher()->dispatch($eventName, new Event($context)); + } + + public function addSubscriber(EventSubscriberInterface $subscriber) + { + $this->getEventDispatcher()->addSubscriber($subscriber); + + return $this; + } + + /** + * Get an array containing the request and response for event notifications + * + * @return array + */ + protected function getEventArray() + { + return array( + 'request' => $this, + 'response' => $this->response + ); + } + + /** + * Process a received response + * + * @param array $context Contextual information + * @throws RequestException|BadResponseException on unsuccessful responses + */ + protected function processResponse(array $context = array()) + { + if (!$this->response) { + // If no response, then processResponse shouldn't have been called + $e = new RequestException('Error completing request'); + $e->setRequest($this); + throw $e; + } + + $this->state = self::STATE_COMPLETE; + + // A request was sent, but we don't know if we'll send more or if the final response will be successful + $this->dispatch('request.sent', $this->getEventArray() + $context); + + // Some response processors will remove the response or reset the state (example: ExponentialBackoffPlugin) + if ($this->state == RequestInterface::STATE_COMPLETE) { + + // The request completed, so the HTTP transaction is complete + $this->dispatch('request.complete', $this->getEventArray()); + + // If the response is bad, allow listeners to modify it or throw exceptions. You can change the response by + // modifying the Event object in your listeners or calling setResponse() on the request + if ($this->response->isError()) { + $event = new Event($this->getEventArray()); + $this->getEventDispatcher()->dispatch('request.error', $event); + // Allow events of request.error to quietly change the response + if ($event['response'] !== $this->response) { + $this->response = $event['response']; + } + } + + // If a successful response was received, dispatch an event + if ($this->response->isSuccessful()) { + $this->dispatch('request.success', $this->getEventArray()); + } + } + } + + /** + * @deprecated Use Guzzle\Plugin\Cache\DefaultCanCacheStrategy + * @codeCoverageIgnore + */ + public function canCache() + { + Version::warn(__METHOD__ . ' is deprecated. Use Guzzle\Plugin\Cache\DefaultCanCacheStrategy.'); + if (class_exists('Guzzle\Plugin\Cache\DefaultCanCacheStrategy')) { + $canCache = new \Guzzle\Plugin\Cache\DefaultCanCacheStrategy(); + return $canCache->canCacheRequest($this); + } else { + return false; + } + } + + /** + * @deprecated Use the history plugin (not emitting a warning as this is built-into the RedirectPlugin for now) + * @codeCoverageIgnore + */ + public function setIsRedirect($isRedirect) + { + $this->isRedirect = $isRedirect; + + return $this; + } + + /** + * @deprecated Use the history plugin + * @codeCoverageIgnore + */ + public function isRedirect() + { + Version::warn(__METHOD__ . ' is deprecated. Use the HistoryPlugin to track this.'); + return $this->isRedirect; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Message/RequestFactory.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Message/RequestFactory.php new file mode 100644 index 0000000..ba00a76 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Message/RequestFactory.php @@ -0,0 +1,359 @@ +methods = array_flip(get_class_methods(__CLASS__)); + } + + public function fromMessage($message) + { + $parsed = ParserRegistry::getInstance()->getParser('message')->parseRequest($message); + + if (!$parsed) { + return false; + } + + $request = $this->fromParts($parsed['method'], $parsed['request_url'], + $parsed['headers'], $parsed['body'], $parsed['protocol'], + $parsed['version']); + + // EntityEnclosingRequest adds an "Expect: 100-Continue" header when using a raw request body for PUT or POST + // requests. This factory method should accurately reflect the message, so here we are removing the Expect + // header if one was not supplied in the message. + if (!isset($parsed['headers']['Expect']) && !isset($parsed['headers']['expect'])) { + $request->removeHeader('Expect'); + } + + return $request; + } + + public function fromParts( + $method, + array $urlParts, + $headers = null, + $body = null, + $protocol = 'HTTP', + $protocolVersion = '1.1' + ) { + return $this->create($method, Url::buildUrl($urlParts), $headers, $body) + ->setProtocolVersion($protocolVersion); + } + + public function create($method, $url, $headers = null, $body = null, array $options = array()) + { + $method = strtoupper($method); + + if ($method == 'GET' || $method == 'HEAD' || $method == 'TRACE') { + // Handle non-entity-enclosing request methods + $request = new $this->requestClass($method, $url, $headers); + if ($body) { + // The body is where the response body will be stored + $type = gettype($body); + if ($type == 'string' || $type == 'resource' || $type == 'object') { + $request->setResponseBody($body); + } + } + } else { + // Create an entity enclosing request by default + $request = new $this->entityEnclosingRequestClass($method, $url, $headers); + if ($body || $body === '0') { + // Add POST fields and files to an entity enclosing request if an array is used + if (is_array($body) || $body instanceof Collection) { + // Normalize PHP style cURL uploads with a leading '@' symbol + foreach ($body as $key => $value) { + if (is_string($value) && substr($value, 0, 1) == '@') { + $request->addPostFile($key, $value); + unset($body[$key]); + } + } + // Add the fields if they are still present and not all files + $request->addPostFields($body); + } else { + // Add a raw entity body body to the request + $request->setBody($body, (string) $request->getHeader('Content-Type')); + if ((string) $request->getHeader('Transfer-Encoding') == 'chunked') { + $request->removeHeader('Content-Length'); + } + } + } + } + + if ($options) { + $this->applyOptions($request, $options); + } + + return $request; + } + + /** + * Clone a request while changing the method. Emulates the behavior of + * {@see Guzzle\Http\Message\Request::clone}, but can change the HTTP method. + * + * @param RequestInterface $request Request to clone + * @param string $method Method to set + * + * @return RequestInterface + */ + public function cloneRequestWithMethod(RequestInterface $request, $method) + { + // Create the request with the same client if possible + if ($request->getClient()) { + $cloned = $request->getClient()->createRequest($method, $request->getUrl(), $request->getHeaders()); + } else { + $cloned = $this->create($method, $request->getUrl(), $request->getHeaders()); + } + + $cloned->getCurlOptions()->replace($request->getCurlOptions()->toArray()); + $cloned->setEventDispatcher(clone $request->getEventDispatcher()); + // Ensure that that the Content-Length header is not copied if changing to GET or HEAD + if (!($cloned instanceof EntityEnclosingRequestInterface)) { + $cloned->removeHeader('Content-Length'); + } elseif ($request instanceof EntityEnclosingRequestInterface) { + $cloned->setBody($request->getBody()); + } + $cloned->getParams()->replace($request->getParams()->toArray()); + $cloned->dispatch('request.clone', array('request' => $cloned)); + + return $cloned; + } + + public function applyOptions(RequestInterface $request, array $options = array(), $flags = self::OPTIONS_NONE) + { + // Iterate over each key value pair and attempt to apply a config using function visitors + foreach ($options as $key => $value) { + $method = "visit_{$key}"; + if (isset($this->methods[$method])) { + $this->{$method}($request, $value, $flags); + } + } + } + + protected function visit_headers(RequestInterface $request, $value, $flags) + { + if (!is_array($value)) { + throw new InvalidArgumentException('headers value must be an array'); + } + + if ($flags & self::OPTIONS_AS_DEFAULTS) { + // Merge headers in but do not overwrite existing values + foreach ($value as $key => $header) { + if (!$request->hasHeader($key)) { + $request->setHeader($key, $header); + } + } + } else { + $request->addHeaders($value); + } + } + + protected function visit_body(RequestInterface $request, $value, $flags) + { + if ($request instanceof EntityEnclosingRequestInterface) { + $request->setBody($value); + } else { + throw new InvalidArgumentException('Attempting to set a body on a non-entity-enclosing request'); + } + } + + protected function visit_allow_redirects(RequestInterface $request, $value, $flags) + { + if ($value === false) { + $request->getParams()->set(RedirectPlugin::DISABLE, true); + } + } + + protected function visit_auth(RequestInterface $request, $value, $flags) + { + if (!is_array($value)) { + throw new InvalidArgumentException('auth value must be an array'); + } + + $request->setAuth($value[0], isset($value[1]) ? $value[1] : null, isset($value[2]) ? $value[2] : 'basic'); + } + + protected function visit_query(RequestInterface $request, $value, $flags) + { + if (!is_array($value)) { + throw new InvalidArgumentException('query value must be an array'); + } + + if ($flags & self::OPTIONS_AS_DEFAULTS) { + // Merge query string values in but do not overwrite existing values + $query = $request->getQuery(); + $query->overwriteWith(array_diff_key($value, $query->toArray())); + } else { + $request->getQuery()->overwriteWith($value); + } + } + + protected function visit_cookies(RequestInterface $request, $value, $flags) + { + if (!is_array($value)) { + throw new InvalidArgumentException('cookies value must be an array'); + } + + foreach ($value as $name => $v) { + $request->addCookie($name, $v); + } + } + + protected function visit_events(RequestInterface $request, $value, $flags) + { + if (!is_array($value)) { + throw new InvalidArgumentException('events value must be an array'); + } + + foreach ($value as $name => $method) { + if (is_array($method)) { + $request->getEventDispatcher()->addListener($name, $method[0], $method[1]); + } else { + $request->getEventDispatcher()->addListener($name, $method); + } + } + } + + protected function visit_plugins(RequestInterface $request, $value, $flags) + { + if (!is_array($value)) { + throw new InvalidArgumentException('plugins value must be an array'); + } + + foreach ($value as $plugin) { + $request->addSubscriber($plugin); + } + } + + protected function visit_exceptions(RequestInterface $request, $value, $flags) + { + if ($value === false || $value === 0) { + $dispatcher = $request->getEventDispatcher(); + foreach ($dispatcher->getListeners('request.error') as $listener) { + if (is_array($listener) && $listener[0] == 'Guzzle\Http\Message\Request' && $listener[1] = 'onRequestError') { + $dispatcher->removeListener('request.error', $listener); + break; + } + } + } + } + + protected function visit_save_to(RequestInterface $request, $value, $flags) + { + $request->setResponseBody($value); + } + + protected function visit_params(RequestInterface $request, $value, $flags) + { + if (!is_array($value)) { + throw new InvalidArgumentException('params value must be an array'); + } + + $request->getParams()->overwriteWith($value); + } + + protected function visit_timeout(RequestInterface $request, $value, $flags) + { + if (defined('CURLOPT_TIMEOUT_MS')) { + $request->getCurlOptions()->set(CURLOPT_TIMEOUT_MS, $value * 1000); + } else { + $request->getCurlOptions()->set(CURLOPT_TIMEOUT, $value); + } + } + + protected function visit_connect_timeout(RequestInterface $request, $value, $flags) + { + if (defined('CURLOPT_CONNECTTIMEOUT_MS')) { + $request->getCurlOptions()->set(CURLOPT_CONNECTTIMEOUT_MS, $value * 1000); + } else { + $request->getCurlOptions()->set(CURLOPT_CONNECTTIMEOUT, $value); + } + } + + protected function visit_debug(RequestInterface $request, $value, $flags) + { + if ($value) { + $request->getCurlOptions()->set(CURLOPT_VERBOSE, true); + } + } + + protected function visit_verify(RequestInterface $request, $value, $flags) + { + $curl = $request->getCurlOptions(); + if ($value === true || is_string($value)) { + $curl[CURLOPT_SSL_VERIFYHOST] = 2; + $curl[CURLOPT_SSL_VERIFYPEER] = true; + if ($value !== true) { + $curl[CURLOPT_CAINFO] = $value; + } + } elseif ($value === false) { + unset($curl[CURLOPT_CAINFO]); + $curl[CURLOPT_SSL_VERIFYHOST] = 0; + $curl[CURLOPT_SSL_VERIFYPEER] = false; + } + } + + protected function visit_proxy(RequestInterface $request, $value, $flags) + { + $request->getCurlOptions()->set(CURLOPT_PROXY, $value, $flags); + } + + protected function visit_cert(RequestInterface $request, $value, $flags) + { + if (is_array($value)) { + $request->getCurlOptions()->set(CURLOPT_SSLCERT, $value[0]); + $request->getCurlOptions()->set(CURLOPT_SSLCERTPASSWD, $value[1]); + } else { + $request->getCurlOptions()->set(CURLOPT_SSLCERT, $value); + } + } + + protected function visit_ssl_key(RequestInterface $request, $value, $flags) + { + if (is_array($value)) { + $request->getCurlOptions()->set(CURLOPT_SSLKEY, $value[0]); + $request->getCurlOptions()->set(CURLOPT_SSLKEYPASSWD, $value[1]); + } else { + $request->getCurlOptions()->set(CURLOPT_SSLKEY, $value); + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Message/RequestFactoryInterface.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Message/RequestFactoryInterface.php new file mode 100644 index 0000000..6088f10 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Message/RequestFactoryInterface.php @@ -0,0 +1,105 @@ + 'Continue', + 101 => 'Switching Protocols', + 102 => 'Processing', + 200 => 'OK', + 201 => 'Created', + 202 => 'Accepted', + 203 => 'Non-Authoritative Information', + 204 => 'No Content', + 205 => 'Reset Content', + 206 => 'Partial Content', + 207 => 'Multi-Status', + 208 => 'Already Reported', + 226 => 'IM Used', + 300 => 'Multiple Choices', + 301 => 'Moved Permanently', + 302 => 'Found', + 303 => 'See Other', + 304 => 'Not Modified', + 305 => 'Use Proxy', + 307 => 'Temporary Redirect', + 308 => 'Permanent Redirect', + 400 => 'Bad Request', + 401 => 'Unauthorized', + 402 => 'Payment Required', + 403 => 'Forbidden', + 404 => 'Not Found', + 405 => 'Method Not Allowed', + 406 => 'Not Acceptable', + 407 => 'Proxy Authentication Required', + 408 => 'Request Timeout', + 409 => 'Conflict', + 410 => 'Gone', + 411 => 'Length Required', + 412 => 'Precondition Failed', + 413 => 'Request Entity Too Large', + 414 => 'Request-URI Too Long', + 415 => 'Unsupported Media Type', + 416 => 'Requested Range Not Satisfiable', + 417 => 'Expectation Failed', + 422 => 'Unprocessable Entity', + 423 => 'Locked', + 424 => 'Failed Dependency', + 425 => 'Reserved for WebDAV advanced collections expired proposal', + 426 => 'Upgrade required', + 428 => 'Precondition Required', + 429 => 'Too Many Requests', + 431 => 'Request Header Fields Too Large', + 500 => 'Internal Server Error', + 501 => 'Not Implemented', + 502 => 'Bad Gateway', + 503 => 'Service Unavailable', + 504 => 'Gateway Timeout', + 505 => 'HTTP Version Not Supported', + 506 => 'Variant Also Negotiates (Experimental)', + 507 => 'Insufficient Storage', + 508 => 'Loop Detected', + 510 => 'Not Extended', + 511 => 'Network Authentication Required', + ); + + /** @var EntityBodyInterface The response body */ + protected $body; + + /** @var string The reason phrase of the response (human readable code) */ + protected $reasonPhrase; + + /** @var string The status code of the response */ + protected $statusCode; + + /** @var array Information about the request */ + protected $info = array(); + + /** @var string The effective URL that returned this response */ + protected $effectiveUrl; + + /** @var array Cacheable response codes (see RFC 2616:13.4) */ + protected static $cacheResponseCodes = array(200, 203, 206, 300, 301, 410); + + /** + * Create a new Response based on a raw response message + * + * @param string $message Response message + * + * @return self|bool Returns false on error + */ + public static function fromMessage($message) + { + $data = ParserRegistry::getInstance()->getParser('message')->parseResponse($message); + if (!$data) { + return false; + } + + $response = new static($data['code'], $data['headers'], $data['body']); + $response->setProtocol($data['protocol'], $data['version']) + ->setStatus($data['code'], $data['reason_phrase']); + + // Set the appropriate Content-Length if the one set is inaccurate (e.g. setting to X) + $contentLength = (string) $response->getHeader('Content-Length'); + $actualLength = strlen($data['body']); + if (strlen($data['body']) > 0 && $contentLength != $actualLength) { + $response->setHeader('Content-Length', $actualLength); + } + + return $response; + } + + /** + * Construct the response + * + * @param string $statusCode The response status code (e.g. 200, 404, etc) + * @param ToArrayInterface|array $headers The response headers + * @param string|resource|EntityBodyInterface $body The body of the response + * + * @throws BadResponseException if an invalid response code is given + */ + public function __construct($statusCode, $headers = null, $body = null) + { + parent::__construct(); + $this->setStatus($statusCode); + $this->body = EntityBody::factory($body !== null ? $body : ''); + + if ($headers) { + if (is_array($headers)) { + $this->setHeaders($headers); + } elseif ($headers instanceof ToArrayInterface) { + $this->setHeaders($headers->toArray()); + } else { + throw new BadResponseException('Invalid headers argument received'); + } + } + } + + /** + * @return string + */ + public function __toString() + { + return $this->getMessage(); + } + + public function serialize() + { + return json_encode(array( + 'status' => $this->statusCode, + 'body' => (string) $this->body, + 'headers' => $this->headers->toArray() + )); + } + + public function unserialize($serialize) + { + $data = json_decode($serialize, true); + $this->__construct($data['status'], $data['headers'], $data['body']); + } + + /** + * Get the response entity body + * + * @param bool $asString Set to TRUE to return a string of the body rather than a full body object + * + * @return EntityBodyInterface|string + */ + public function getBody($asString = false) + { + return $asString ? (string) $this->body : $this->body; + } + + /** + * Set the response entity body + * + * @param EntityBodyInterface|string $body Body to set + * + * @return self + */ + public function setBody($body) + { + $this->body = EntityBody::factory($body); + + return $this; + } + + /** + * Set the protocol and protocol version of the response + * + * @param string $protocol Response protocol + * @param string $version Protocol version + * + * @return self + */ + public function setProtocol($protocol, $version) + { + $this->protocol = $protocol; + $this->protocolVersion = $version; + + return $this; + } + + /** + * Get the protocol used for the response (e.g. HTTP) + * + * @return string + */ + public function getProtocol() + { + return $this->protocol; + } + + /** + * Get the HTTP protocol version + * + * @return string + */ + public function getProtocolVersion() + { + return $this->protocolVersion; + } + + /** + * Get a cURL transfer information + * + * @param string $key A single statistic to check + * + * @return array|string|null Returns all stats if no key is set, a single stat if a key is set, or null if a key + * is set and not found + * @link http://www.php.net/manual/en/function.curl-getinfo.php + */ + public function getInfo($key = null) + { + if ($key === null) { + return $this->info; + } elseif (array_key_exists($key, $this->info)) { + return $this->info[$key]; + } else { + return null; + } + } + + /** + * Set the transfer information + * + * @param array $info Array of cURL transfer stats + * + * @return self + */ + public function setInfo(array $info) + { + $this->info = $info; + + return $this; + } + + /** + * Set the response status + * + * @param int $statusCode Response status code to set + * @param string $reasonPhrase Response reason phrase + * + * @return self + * @throws BadResponseException when an invalid response code is received + */ + public function setStatus($statusCode, $reasonPhrase = '') + { + $this->statusCode = (int) $statusCode; + + if (!$reasonPhrase && isset(self::$statusTexts[$this->statusCode])) { + $this->reasonPhrase = self::$statusTexts[$this->statusCode]; + } else { + $this->reasonPhrase = $reasonPhrase; + } + + return $this; + } + + /** + * Get the response status code + * + * @return integer + */ + public function getStatusCode() + { + return $this->statusCode; + } + + /** + * Get the entire response as a string + * + * @return string + */ + public function getMessage() + { + $message = $this->getRawHeaders(); + + // Only include the body in the message if the size is < 2MB + $size = $this->body->getSize(); + if ($size < 2097152) { + $message .= (string) $this->body; + } + + return $message; + } + + /** + * Get the the raw message headers as a string + * + * @return string + */ + public function getRawHeaders() + { + $headers = 'HTTP/1.1 ' . $this->statusCode . ' ' . $this->reasonPhrase . "\r\n"; + $lines = $this->getHeaderLines(); + if (!empty($lines)) { + $headers .= implode("\r\n", $lines) . "\r\n"; + } + + return $headers . "\r\n"; + } + + /** + * Get the response reason phrase- a human readable version of the numeric + * status code + * + * @return string + */ + public function getReasonPhrase() + { + return $this->reasonPhrase; + } + + /** + * Get the Accept-Ranges HTTP header + * + * @return string Returns what partial content range types this server supports. + */ + public function getAcceptRanges() + { + return (string) $this->getHeader('Accept-Ranges'); + } + + /** + * Calculate the age of the response + * + * @return integer + */ + public function calculateAge() + { + $age = $this->getHeader('Age'); + + if ($age === null && $this->getDate()) { + $age = time() - strtotime($this->getDate()); + } + + return $age === null ? null : (int) (string) $age; + } + + /** + * Get the Age HTTP header + * + * @return integer|null Returns the age the object has been in a proxy cache in seconds. + */ + public function getAge() + { + return (string) $this->getHeader('Age'); + } + + /** + * Get the Allow HTTP header + * + * @return string|null Returns valid actions for a specified resource. To be used for a 405 Method not allowed. + */ + public function getAllow() + { + return (string) $this->getHeader('Allow'); + } + + /** + * Check if an HTTP method is allowed by checking the Allow response header + * + * @param string $method Method to check + * + * @return bool + */ + public function isMethodAllowed($method) + { + $allow = $this->getHeader('Allow'); + if ($allow) { + foreach (explode(',', $allow) as $allowable) { + if (!strcasecmp(trim($allowable), $method)) { + return true; + } + } + } + + return false; + } + + /** + * Get the Cache-Control HTTP header + * + * @return string + */ + public function getCacheControl() + { + return (string) $this->getHeader('Cache-Control'); + } + + /** + * Get the Connection HTTP header + * + * @return string + */ + public function getConnection() + { + return (string) $this->getHeader('Connection'); + } + + /** + * Get the Content-Encoding HTTP header + * + * @return string|null + */ + public function getContentEncoding() + { + return (string) $this->getHeader('Content-Encoding'); + } + + /** + * Get the Content-Language HTTP header + * + * @return string|null Returns the language the content is in. + */ + public function getContentLanguage() + { + return (string) $this->getHeader('Content-Language'); + } + + /** + * Get the Content-Length HTTP header + * + * @return integer Returns the length of the response body in bytes + */ + public function getContentLength() + { + return (int) (string) $this->getHeader('Content-Length'); + } + + /** + * Get the Content-Location HTTP header + * + * @return string|null Returns an alternate location for the returned data (e.g /index.htm) + */ + public function getContentLocation() + { + return (string) $this->getHeader('Content-Location'); + } + + /** + * Get the Content-Disposition HTTP header + * + * @return string|null Returns the Content-Disposition header + */ + public function getContentDisposition() + { + return (string) $this->getHeader('Content-Disposition'); + } + + /** + * Get the Content-MD5 HTTP header + * + * @return string|null Returns a Base64-encoded binary MD5 sum of the content of the response. + */ + public function getContentMd5() + { + return (string) $this->getHeader('Content-MD5'); + } + + /** + * Get the Content-Range HTTP header + * + * @return string Returns where in a full body message this partial message belongs (e.g. bytes 21010-47021/47022). + */ + public function getContentRange() + { + return (string) $this->getHeader('Content-Range'); + } + + /** + * Get the Content-Type HTTP header + * + * @return string Returns the mime type of this content. + */ + public function getContentType() + { + return (string) $this->getHeader('Content-Type'); + } + + /** + * Checks if the Content-Type is of a certain type. This is useful if the + * Content-Type header contains charset information and you need to know if + * the Content-Type matches a particular type. + * + * @param string $type Content type to check against + * + * @return bool + */ + public function isContentType($type) + { + return stripos($this->getHeader('Content-Type'), $type) !== false; + } + + /** + * Get the Date HTTP header + * + * @return string|null Returns the date and time that the message was sent. + */ + public function getDate() + { + return (string) $this->getHeader('Date'); + } + + /** + * Get the ETag HTTP header + * + * @return string|null Returns an identifier for a specific version of a resource, often a Message digest. + */ + public function getEtag() + { + return (string) $this->getHeader('ETag'); + } + + /** + * Get the Expires HTTP header + * + * @return string|null Returns the date/time after which the response is considered stale. + */ + public function getExpires() + { + return (string) $this->getHeader('Expires'); + } + + /** + * Get the Last-Modified HTTP header + * + * @return string|null Returns the last modified date for the requested object, in RFC 2822 format + * (e.g. Tue, 15 Nov 1994 12:45:26 GMT) + */ + public function getLastModified() + { + return (string) $this->getHeader('Last-Modified'); + } + + /** + * Get the Location HTTP header + * + * @return string|null Used in redirection, or when a new resource has been created. + */ + public function getLocation() + { + return (string) $this->getHeader('Location'); + } + + /** + * Get the Pragma HTTP header + * + * @return Header|null Returns the implementation-specific headers that may have various effects anywhere along + * the request-response chain. + */ + public function getPragma() + { + return (string) $this->getHeader('Pragma'); + } + + /** + * Get the Proxy-Authenticate HTTP header + * + * @return string|null Authentication to access the proxy (e.g. Basic) + */ + public function getProxyAuthenticate() + { + return (string) $this->getHeader('Proxy-Authenticate'); + } + + /** + * Get the Retry-After HTTP header + * + * @return int|null If an entity is temporarily unavailable, this instructs the client to try again after a + * specified period of time. + */ + public function getRetryAfter() + { + return (string) $this->getHeader('Retry-After'); + } + + /** + * Get the Server HTTP header + * + * @return string|null A name for the server + */ + public function getServer() + { + return (string) $this->getHeader('Server'); + } + + /** + * Get the Set-Cookie HTTP header + * + * @return string|null An HTTP cookie. + */ + public function getSetCookie() + { + return (string) $this->getHeader('Set-Cookie'); + } + + /** + * Get the Trailer HTTP header + * + * @return string|null The Trailer general field value indicates that the given set of header fields is present in + * the trailer of a message encoded with chunked transfer-coding. + */ + public function getTrailer() + { + return (string) $this->getHeader('Trailer'); + } + + /** + * Get the Transfer-Encoding HTTP header + * + * @return string|null The form of encoding used to safely transfer the entity to the user + */ + public function getTransferEncoding() + { + return (string) $this->getHeader('Transfer-Encoding'); + } + + /** + * Get the Vary HTTP header + * + * @return string|null Tells downstream proxies how to match future request headers to decide whether the cached + * response can be used rather than requesting a fresh one from the origin server. + */ + public function getVary() + { + return (string) $this->getHeader('Vary'); + } + + /** + * Get the Via HTTP header + * + * @return string|null Informs the client of proxies through which the response was sent. + */ + public function getVia() + { + return (string) $this->getHeader('Via'); + } + + /** + * Get the Warning HTTP header + * + * @return string|null A general warning about possible problems with the entity body + */ + public function getWarning() + { + return (string) $this->getHeader('Warning'); + } + + /** + * Get the WWW-Authenticate HTTP header + * + * @return string|null Indicates the authentication scheme that should be used to access the requested entity + */ + public function getWwwAuthenticate() + { + return (string) $this->getHeader('WWW-Authenticate'); + } + + /** + * Checks if HTTP Status code is a Client Error (4xx) + * + * @return bool + */ + public function isClientError() + { + return $this->statusCode >= 400 && $this->statusCode < 500; + } + + /** + * Checks if HTTP Status code is Server OR Client Error (4xx or 5xx) + * + * @return boolean + */ + public function isError() + { + return $this->isClientError() || $this->isServerError(); + } + + /** + * Checks if HTTP Status code is Information (1xx) + * + * @return bool + */ + public function isInformational() + { + return $this->statusCode < 200; + } + + /** + * Checks if HTTP Status code is a Redirect (3xx) + * + * @return bool + */ + public function isRedirect() + { + return $this->statusCode >= 300 && $this->statusCode < 400; + } + + /** + * Checks if HTTP Status code is Server Error (5xx) + * + * @return bool + */ + public function isServerError() + { + return $this->statusCode >= 500 && $this->statusCode < 600; + } + + /** + * Checks if HTTP Status code is Successful (2xx | 304) + * + * @return bool + */ + public function isSuccessful() + { + return ($this->statusCode >= 200 && $this->statusCode < 300) || $this->statusCode == 304; + } + + /** + * Check if the response can be cached based on the response headers + * + * @return bool Returns TRUE if the response can be cached or false if not + */ + public function canCache() + { + // Check if the response is cacheable based on the code + if (!in_array((int) $this->getStatusCode(), self::$cacheResponseCodes)) { + return false; + } + + // Make sure a valid body was returned and can be cached + if ((!$this->getBody()->isReadable() || !$this->getBody()->isSeekable()) + && ($this->getContentLength() > 0 || $this->getTransferEncoding() == 'chunked')) { + return false; + } + + // Never cache no-store resources (this is a private cache, so private + // can be cached) + if ($this->getHeader('Cache-Control') && $this->getHeader('Cache-Control')->hasDirective('no-store')) { + return false; + } + + return $this->isFresh() || $this->getFreshness() === null || $this->canValidate(); + } + + /** + * Gets the number of seconds from the current time in which this response is still considered fresh + * + * @return int|null Returns the number of seconds + */ + public function getMaxAge() + { + if ($header = $this->getHeader('Cache-Control')) { + // s-max-age, then max-age, then Expires + if ($age = $header->getDirective('s-maxage')) { + return $age; + } + if ($age = $header->getDirective('max-age')) { + return $age; + } + } + + if ($this->getHeader('Expires')) { + return strtotime($this->getExpires()) - time(); + } + + return null; + } + + /** + * Check if the response is considered fresh. + * + * A response is considered fresh when its age is less than or equal to the freshness lifetime (maximum age) of the + * response. + * + * @return bool|null + */ + public function isFresh() + { + $fresh = $this->getFreshness(); + + return $fresh === null ? null : $fresh >= 0; + } + + /** + * Check if the response can be validated against the origin server using a conditional GET request. + * + * @return bool + */ + public function canValidate() + { + return $this->getEtag() || $this->getLastModified(); + } + + /** + * Get the freshness of the response by returning the difference of the maximum lifetime of the response and the + * age of the response (max-age - age). + * + * Freshness values less than 0 mean that the response is no longer fresh and is ABS(freshness) seconds expired. + * Freshness values of greater than zero is the number of seconds until the response is no longer fresh. A NULL + * result means that no freshness information is available. + * + * @return int + */ + public function getFreshness() + { + $maxAge = $this->getMaxAge(); + $age = $this->calculateAge(); + + return $maxAge && $age ? ($maxAge - $age) : null; + } + + /** + * Parse the JSON response body and return an array + * + * @return array|string|int|bool|float + * @throws RuntimeException if the response body is not in JSON format + */ + public function json() + { + $data = json_decode((string) $this->body, true); + if (JSON_ERROR_NONE !== json_last_error()) { + throw new RuntimeException('Unable to parse response body into JSON: ' . json_last_error()); + } + + return $data === null ? array() : $data; + } + + /** + * Parse the XML response body and return a \SimpleXMLElement. + * + * In order to prevent XXE attacks, this method disables loading external + * entities. If you rely on external entities, then you must parse the + * XML response manually by accessing the response body directly. + * + * @return \SimpleXMLElement + * @throws RuntimeException if the response body is not in XML format + * @link http://websec.io/2012/08/27/Preventing-XXE-in-PHP.html + */ + public function xml() + { + $errorMessage = null; + $internalErrors = libxml_use_internal_errors(true); + $disableEntities = libxml_disable_entity_loader(true); + libxml_clear_errors(); + + try { + $xml = new \SimpleXMLElement((string) $this->body ?: '', LIBXML_NONET); + if ($error = libxml_get_last_error()) { + $errorMessage = $error->message; + } + } catch (\Exception $e) { + $errorMessage = $e->getMessage(); + } + + libxml_clear_errors(); + libxml_use_internal_errors($internalErrors); + libxml_disable_entity_loader($disableEntities); + + if ($errorMessage) { + throw new RuntimeException('Unable to parse response body into XML: ' . $errorMessage); + } + + return $xml; + } + + /** + * Get the redirect count of this response + * + * @return int + */ + public function getRedirectCount() + { + return (int) $this->params->get(RedirectPlugin::REDIRECT_COUNT); + } + + /** + * Set the effective URL that resulted in this response (e.g. the last redirect URL) + * + * @param string $url The effective URL + * + * @return self + */ + public function setEffectiveUrl($url) + { + $this->effectiveUrl = $url; + + return $this; + } + + /** + * Get the effective URL that resulted in this response (e.g. the last redirect URL) + * + * @return string + */ + public function getEffectiveUrl() + { + return $this->effectiveUrl; + } + + /** + * @deprecated + * @codeCoverageIgnore + */ + public function getPreviousResponse() + { + Version::warn(__METHOD__ . ' is deprecated. Use the HistoryPlugin.'); + return null; + } + + /** + * @deprecated + * @codeCoverageIgnore + */ + public function setRequest($request) + { + Version::warn(__METHOD__ . ' is deprecated'); + return $this; + } + + /** + * @deprecated + * @codeCoverageIgnore + */ + public function getRequest() + { + Version::warn(__METHOD__ . ' is deprecated'); + return null; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Mimetypes.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Mimetypes.php new file mode 100644 index 0000000..d71586a --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Mimetypes.php @@ -0,0 +1,962 @@ + 'text/vnd.in3d.3dml', + '3g2' => 'video/3gpp2', + '3gp' => 'video/3gpp', + '7z' => 'application/x-7z-compressed', + 'aab' => 'application/x-authorware-bin', + 'aac' => 'audio/x-aac', + 'aam' => 'application/x-authorware-map', + 'aas' => 'application/x-authorware-seg', + 'abw' => 'application/x-abiword', + 'ac' => 'application/pkix-attr-cert', + 'acc' => 'application/vnd.americandynamics.acc', + 'ace' => 'application/x-ace-compressed', + 'acu' => 'application/vnd.acucobol', + 'acutc' => 'application/vnd.acucorp', + 'adp' => 'audio/adpcm', + 'aep' => 'application/vnd.audiograph', + 'afm' => 'application/x-font-type1', + 'afp' => 'application/vnd.ibm.modcap', + 'ahead' => 'application/vnd.ahead.space', + 'ai' => 'application/postscript', + 'aif' => 'audio/x-aiff', + 'aifc' => 'audio/x-aiff', + 'aiff' => 'audio/x-aiff', + 'air' => 'application/vnd.adobe.air-application-installer-package+zip', + 'ait' => 'application/vnd.dvb.ait', + 'ami' => 'application/vnd.amiga.ami', + 'apk' => 'application/vnd.android.package-archive', + 'application' => 'application/x-ms-application', + 'apr' => 'application/vnd.lotus-approach', + 'asa' => 'text/plain', + 'asax' => 'application/octet-stream', + 'asc' => 'application/pgp-signature', + 'ascx' => 'text/plain', + 'asf' => 'video/x-ms-asf', + 'ashx' => 'text/plain', + 'asm' => 'text/x-asm', + 'asmx' => 'text/plain', + 'aso' => 'application/vnd.accpac.simply.aso', + 'asp' => 'text/plain', + 'aspx' => 'text/plain', + 'asx' => 'video/x-ms-asf', + 'atc' => 'application/vnd.acucorp', + 'atom' => 'application/atom+xml', + 'atomcat' => 'application/atomcat+xml', + 'atomsvc' => 'application/atomsvc+xml', + 'atx' => 'application/vnd.antix.game-component', + 'au' => 'audio/basic', + 'avi' => 'video/x-msvideo', + 'aw' => 'application/applixware', + 'axd' => 'text/plain', + 'azf' => 'application/vnd.airzip.filesecure.azf', + 'azs' => 'application/vnd.airzip.filesecure.azs', + 'azw' => 'application/vnd.amazon.ebook', + 'bat' => 'application/x-msdownload', + 'bcpio' => 'application/x-bcpio', + 'bdf' => 'application/x-font-bdf', + 'bdm' => 'application/vnd.syncml.dm+wbxml', + 'bed' => 'application/vnd.realvnc.bed', + 'bh2' => 'application/vnd.fujitsu.oasysprs', + 'bin' => 'application/octet-stream', + 'bmi' => 'application/vnd.bmi', + 'bmp' => 'image/bmp', + 'book' => 'application/vnd.framemaker', + 'box' => 'application/vnd.previewsystems.box', + 'boz' => 'application/x-bzip2', + 'bpk' => 'application/octet-stream', + 'btif' => 'image/prs.btif', + 'bz' => 'application/x-bzip', + 'bz2' => 'application/x-bzip2', + 'c' => 'text/x-c', + 'c11amc' => 'application/vnd.cluetrust.cartomobile-config', + 'c11amz' => 'application/vnd.cluetrust.cartomobile-config-pkg', + 'c4d' => 'application/vnd.clonk.c4group', + 'c4f' => 'application/vnd.clonk.c4group', + 'c4g' => 'application/vnd.clonk.c4group', + 'c4p' => 'application/vnd.clonk.c4group', + 'c4u' => 'application/vnd.clonk.c4group', + 'cab' => 'application/vnd.ms-cab-compressed', + 'car' => 'application/vnd.curl.car', + 'cat' => 'application/vnd.ms-pki.seccat', + 'cc' => 'text/x-c', + 'cct' => 'application/x-director', + 'ccxml' => 'application/ccxml+xml', + 'cdbcmsg' => 'application/vnd.contact.cmsg', + 'cdf' => 'application/x-netcdf', + 'cdkey' => 'application/vnd.mediastation.cdkey', + 'cdmia' => 'application/cdmi-capability', + 'cdmic' => 'application/cdmi-container', + 'cdmid' => 'application/cdmi-domain', + 'cdmio' => 'application/cdmi-object', + 'cdmiq' => 'application/cdmi-queue', + 'cdx' => 'chemical/x-cdx', + 'cdxml' => 'application/vnd.chemdraw+xml', + 'cdy' => 'application/vnd.cinderella', + 'cer' => 'application/pkix-cert', + 'cfc' => 'application/x-coldfusion', + 'cfm' => 'application/x-coldfusion', + 'cgm' => 'image/cgm', + 'chat' => 'application/x-chat', + 'chm' => 'application/vnd.ms-htmlhelp', + 'chrt' => 'application/vnd.kde.kchart', + 'cif' => 'chemical/x-cif', + 'cii' => 'application/vnd.anser-web-certificate-issue-initiation', + 'cil' => 'application/vnd.ms-artgalry', + 'cla' => 'application/vnd.claymore', + 'class' => 'application/java-vm', + 'clkk' => 'application/vnd.crick.clicker.keyboard', + 'clkp' => 'application/vnd.crick.clicker.palette', + 'clkt' => 'application/vnd.crick.clicker.template', + 'clkw' => 'application/vnd.crick.clicker.wordbank', + 'clkx' => 'application/vnd.crick.clicker', + 'clp' => 'application/x-msclip', + 'cmc' => 'application/vnd.cosmocaller', + 'cmdf' => 'chemical/x-cmdf', + 'cml' => 'chemical/x-cml', + 'cmp' => 'application/vnd.yellowriver-custom-menu', + 'cmx' => 'image/x-cmx', + 'cod' => 'application/vnd.rim.cod', + 'com' => 'application/x-msdownload', + 'conf' => 'text/plain', + 'cpio' => 'application/x-cpio', + 'cpp' => 'text/x-c', + 'cpt' => 'application/mac-compactpro', + 'crd' => 'application/x-mscardfile', + 'crl' => 'application/pkix-crl', + 'crt' => 'application/x-x509-ca-cert', + 'cryptonote' => 'application/vnd.rig.cryptonote', + 'cs' => 'text/plain', + 'csh' => 'application/x-csh', + 'csml' => 'chemical/x-csml', + 'csp' => 'application/vnd.commonspace', + 'css' => 'text/css', + 'cst' => 'application/x-director', + 'csv' => 'text/csv', + 'cu' => 'application/cu-seeme', + 'curl' => 'text/vnd.curl', + 'cww' => 'application/prs.cww', + 'cxt' => 'application/x-director', + 'cxx' => 'text/x-c', + 'dae' => 'model/vnd.collada+xml', + 'daf' => 'application/vnd.mobius.daf', + 'dataless' => 'application/vnd.fdsn.seed', + 'davmount' => 'application/davmount+xml', + 'dcr' => 'application/x-director', + 'dcurl' => 'text/vnd.curl.dcurl', + 'dd2' => 'application/vnd.oma.dd2+xml', + 'ddd' => 'application/vnd.fujixerox.ddd', + 'deb' => 'application/x-debian-package', + 'def' => 'text/plain', + 'deploy' => 'application/octet-stream', + 'der' => 'application/x-x509-ca-cert', + 'dfac' => 'application/vnd.dreamfactory', + 'dic' => 'text/x-c', + 'dir' => 'application/x-director', + 'dis' => 'application/vnd.mobius.dis', + 'dist' => 'application/octet-stream', + 'distz' => 'application/octet-stream', + 'djv' => 'image/vnd.djvu', + 'djvu' => 'image/vnd.djvu', + 'dll' => 'application/x-msdownload', + 'dmg' => 'application/octet-stream', + 'dms' => 'application/octet-stream', + 'dna' => 'application/vnd.dna', + 'doc' => 'application/msword', + 'docm' => 'application/vnd.ms-word.document.macroenabled.12', + 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'dot' => 'application/msword', + 'dotm' => 'application/vnd.ms-word.template.macroenabled.12', + 'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template', + 'dp' => 'application/vnd.osgi.dp', + 'dpg' => 'application/vnd.dpgraph', + 'dra' => 'audio/vnd.dra', + 'dsc' => 'text/prs.lines.tag', + 'dssc' => 'application/dssc+der', + 'dtb' => 'application/x-dtbook+xml', + 'dtd' => 'application/xml-dtd', + 'dts' => 'audio/vnd.dts', + 'dtshd' => 'audio/vnd.dts.hd', + 'dump' => 'application/octet-stream', + 'dvi' => 'application/x-dvi', + 'dwf' => 'model/vnd.dwf', + 'dwg' => 'image/vnd.dwg', + 'dxf' => 'image/vnd.dxf', + 'dxp' => 'application/vnd.spotfire.dxp', + 'dxr' => 'application/x-director', + 'ecelp4800' => 'audio/vnd.nuera.ecelp4800', + 'ecelp7470' => 'audio/vnd.nuera.ecelp7470', + 'ecelp9600' => 'audio/vnd.nuera.ecelp9600', + 'ecma' => 'application/ecmascript', + 'edm' => 'application/vnd.novadigm.edm', + 'edx' => 'application/vnd.novadigm.edx', + 'efif' => 'application/vnd.picsel', + 'ei6' => 'application/vnd.pg.osasli', + 'elc' => 'application/octet-stream', + 'eml' => 'message/rfc822', + 'emma' => 'application/emma+xml', + 'eol' => 'audio/vnd.digital-winds', + 'eot' => 'application/vnd.ms-fontobject', + 'eps' => 'application/postscript', + 'epub' => 'application/epub+zip', + 'es3' => 'application/vnd.eszigno3+xml', + 'esf' => 'application/vnd.epson.esf', + 'et3' => 'application/vnd.eszigno3+xml', + 'etx' => 'text/x-setext', + 'exe' => 'application/x-msdownload', + 'exi' => 'application/exi', + 'ext' => 'application/vnd.novadigm.ext', + 'ez' => 'application/andrew-inset', + 'ez2' => 'application/vnd.ezpix-album', + 'ez3' => 'application/vnd.ezpix-package', + 'f' => 'text/x-fortran', + 'f4v' => 'video/x-f4v', + 'f77' => 'text/x-fortran', + 'f90' => 'text/x-fortran', + 'fbs' => 'image/vnd.fastbidsheet', + 'fcs' => 'application/vnd.isac.fcs', + 'fdf' => 'application/vnd.fdf', + 'fe_launch' => 'application/vnd.denovo.fcselayout-link', + 'fg5' => 'application/vnd.fujitsu.oasysgp', + 'fgd' => 'application/x-director', + 'fh' => 'image/x-freehand', + 'fh4' => 'image/x-freehand', + 'fh5' => 'image/x-freehand', + 'fh7' => 'image/x-freehand', + 'fhc' => 'image/x-freehand', + 'fig' => 'application/x-xfig', + 'fli' => 'video/x-fli', + 'flo' => 'application/vnd.micrografx.flo', + 'flv' => 'video/x-flv', + 'flw' => 'application/vnd.kde.kivio', + 'flx' => 'text/vnd.fmi.flexstor', + 'fly' => 'text/vnd.fly', + 'fm' => 'application/vnd.framemaker', + 'fnc' => 'application/vnd.frogans.fnc', + 'for' => 'text/x-fortran', + 'fpx' => 'image/vnd.fpx', + 'frame' => 'application/vnd.framemaker', + 'fsc' => 'application/vnd.fsc.weblaunch', + 'fst' => 'image/vnd.fst', + 'ftc' => 'application/vnd.fluxtime.clip', + 'fti' => 'application/vnd.anser-web-funds-transfer-initiation', + 'fvt' => 'video/vnd.fvt', + 'fxp' => 'application/vnd.adobe.fxp', + 'fxpl' => 'application/vnd.adobe.fxp', + 'fzs' => 'application/vnd.fuzzysheet', + 'g2w' => 'application/vnd.geoplan', + 'g3' => 'image/g3fax', + 'g3w' => 'application/vnd.geospace', + 'gac' => 'application/vnd.groove-account', + 'gdl' => 'model/vnd.gdl', + 'geo' => 'application/vnd.dynageo', + 'gex' => 'application/vnd.geometry-explorer', + 'ggb' => 'application/vnd.geogebra.file', + 'ggt' => 'application/vnd.geogebra.tool', + 'ghf' => 'application/vnd.groove-help', + 'gif' => 'image/gif', + 'gim' => 'application/vnd.groove-identity-message', + 'gmx' => 'application/vnd.gmx', + 'gnumeric' => 'application/x-gnumeric', + 'gph' => 'application/vnd.flographit', + 'gqf' => 'application/vnd.grafeq', + 'gqs' => 'application/vnd.grafeq', + 'gram' => 'application/srgs', + 'gre' => 'application/vnd.geometry-explorer', + 'grv' => 'application/vnd.groove-injector', + 'grxml' => 'application/srgs+xml', + 'gsf' => 'application/x-font-ghostscript', + 'gtar' => 'application/x-gtar', + 'gtm' => 'application/vnd.groove-tool-message', + 'gtw' => 'model/vnd.gtw', + 'gv' => 'text/vnd.graphviz', + 'gxt' => 'application/vnd.geonext', + 'h' => 'text/x-c', + 'h261' => 'video/h261', + 'h263' => 'video/h263', + 'h264' => 'video/h264', + 'hal' => 'application/vnd.hal+xml', + 'hbci' => 'application/vnd.hbci', + 'hdf' => 'application/x-hdf', + 'hh' => 'text/x-c', + 'hlp' => 'application/winhlp', + 'hpgl' => 'application/vnd.hp-hpgl', + 'hpid' => 'application/vnd.hp-hpid', + 'hps' => 'application/vnd.hp-hps', + 'hqx' => 'application/mac-binhex40', + 'hta' => 'application/octet-stream', + 'htc' => 'text/html', + 'htke' => 'application/vnd.kenameaapp', + 'htm' => 'text/html', + 'html' => 'text/html', + 'hvd' => 'application/vnd.yamaha.hv-dic', + 'hvp' => 'application/vnd.yamaha.hv-voice', + 'hvs' => 'application/vnd.yamaha.hv-script', + 'i2g' => 'application/vnd.intergeo', + 'icc' => 'application/vnd.iccprofile', + 'ice' => 'x-conference/x-cooltalk', + 'icm' => 'application/vnd.iccprofile', + 'ico' => 'image/x-icon', + 'ics' => 'text/calendar', + 'ief' => 'image/ief', + 'ifb' => 'text/calendar', + 'ifm' => 'application/vnd.shana.informed.formdata', + 'iges' => 'model/iges', + 'igl' => 'application/vnd.igloader', + 'igm' => 'application/vnd.insors.igm', + 'igs' => 'model/iges', + 'igx' => 'application/vnd.micrografx.igx', + 'iif' => 'application/vnd.shana.informed.interchange', + 'imp' => 'application/vnd.accpac.simply.imp', + 'ims' => 'application/vnd.ms-ims', + 'in' => 'text/plain', + 'ini' => 'text/plain', + 'ipfix' => 'application/ipfix', + 'ipk' => 'application/vnd.shana.informed.package', + 'irm' => 'application/vnd.ibm.rights-management', + 'irp' => 'application/vnd.irepository.package+xml', + 'iso' => 'application/octet-stream', + 'itp' => 'application/vnd.shana.informed.formtemplate', + 'ivp' => 'application/vnd.immervision-ivp', + 'ivu' => 'application/vnd.immervision-ivu', + 'jad' => 'text/vnd.sun.j2me.app-descriptor', + 'jam' => 'application/vnd.jam', + 'jar' => 'application/java-archive', + 'java' => 'text/x-java-source', + 'jisp' => 'application/vnd.jisp', + 'jlt' => 'application/vnd.hp-jlyt', + 'jnlp' => 'application/x-java-jnlp-file', + 'joda' => 'application/vnd.joost.joda-archive', + 'jpe' => 'image/jpeg', + 'jpeg' => 'image/jpeg', + 'jpg' => 'image/jpeg', + 'jpgm' => 'video/jpm', + 'jpgv' => 'video/jpeg', + 'jpm' => 'video/jpm', + 'js' => 'text/javascript', + 'json' => 'application/json', + 'kar' => 'audio/midi', + 'karbon' => 'application/vnd.kde.karbon', + 'kfo' => 'application/vnd.kde.kformula', + 'kia' => 'application/vnd.kidspiration', + 'kml' => 'application/vnd.google-earth.kml+xml', + 'kmz' => 'application/vnd.google-earth.kmz', + 'kne' => 'application/vnd.kinar', + 'knp' => 'application/vnd.kinar', + 'kon' => 'application/vnd.kde.kontour', + 'kpr' => 'application/vnd.kde.kpresenter', + 'kpt' => 'application/vnd.kde.kpresenter', + 'ksp' => 'application/vnd.kde.kspread', + 'ktr' => 'application/vnd.kahootz', + 'ktx' => 'image/ktx', + 'ktz' => 'application/vnd.kahootz', + 'kwd' => 'application/vnd.kde.kword', + 'kwt' => 'application/vnd.kde.kword', + 'lasxml' => 'application/vnd.las.las+xml', + 'latex' => 'application/x-latex', + 'lbd' => 'application/vnd.llamagraphics.life-balance.desktop', + 'lbe' => 'application/vnd.llamagraphics.life-balance.exchange+xml', + 'les' => 'application/vnd.hhe.lesson-player', + 'lha' => 'application/octet-stream', + 'link66' => 'application/vnd.route66.link66+xml', + 'list' => 'text/plain', + 'list3820' => 'application/vnd.ibm.modcap', + 'listafp' => 'application/vnd.ibm.modcap', + 'log' => 'text/plain', + 'lostxml' => 'application/lost+xml', + 'lrf' => 'application/octet-stream', + 'lrm' => 'application/vnd.ms-lrm', + 'ltf' => 'application/vnd.frogans.ltf', + 'lvp' => 'audio/vnd.lucent.voice', + 'lwp' => 'application/vnd.lotus-wordpro', + 'lzh' => 'application/octet-stream', + 'm13' => 'application/x-msmediaview', + 'm14' => 'application/x-msmediaview', + 'm1v' => 'video/mpeg', + 'm21' => 'application/mp21', + 'm2a' => 'audio/mpeg', + 'm2v' => 'video/mpeg', + 'm3a' => 'audio/mpeg', + 'm3u' => 'audio/x-mpegurl', + 'm3u8' => 'application/vnd.apple.mpegurl', + 'm4a' => 'audio/mp4', + 'm4u' => 'video/vnd.mpegurl', + 'm4v' => 'video/mp4', + 'ma' => 'application/mathematica', + 'mads' => 'application/mads+xml', + 'mag' => 'application/vnd.ecowin.chart', + 'maker' => 'application/vnd.framemaker', + 'man' => 'text/troff', + 'mathml' => 'application/mathml+xml', + 'mb' => 'application/mathematica', + 'mbk' => 'application/vnd.mobius.mbk', + 'mbox' => 'application/mbox', + 'mc1' => 'application/vnd.medcalcdata', + 'mcd' => 'application/vnd.mcd', + 'mcurl' => 'text/vnd.curl.mcurl', + 'mdb' => 'application/x-msaccess', + 'mdi' => 'image/vnd.ms-modi', + 'me' => 'text/troff', + 'mesh' => 'model/mesh', + 'meta4' => 'application/metalink4+xml', + 'mets' => 'application/mets+xml', + 'mfm' => 'application/vnd.mfmp', + 'mgp' => 'application/vnd.osgeo.mapguide.package', + 'mgz' => 'application/vnd.proteus.magazine', + 'mid' => 'audio/midi', + 'midi' => 'audio/midi', + 'mif' => 'application/vnd.mif', + 'mime' => 'message/rfc822', + 'mj2' => 'video/mj2', + 'mjp2' => 'video/mj2', + 'mlp' => 'application/vnd.dolby.mlp', + 'mmd' => 'application/vnd.chipnuts.karaoke-mmd', + 'mmf' => 'application/vnd.smaf', + 'mmr' => 'image/vnd.fujixerox.edmics-mmr', + 'mny' => 'application/x-msmoney', + 'mobi' => 'application/x-mobipocket-ebook', + 'mods' => 'application/mods+xml', + 'mov' => 'video/quicktime', + 'movie' => 'video/x-sgi-movie', + 'mp2' => 'audio/mpeg', + 'mp21' => 'application/mp21', + 'mp2a' => 'audio/mpeg', + 'mp3' => 'audio/mpeg', + 'mp4' => 'video/mp4', + 'mp4a' => 'audio/mp4', + 'mp4s' => 'application/mp4', + 'mp4v' => 'video/mp4', + 'mpc' => 'application/vnd.mophun.certificate', + 'mpe' => 'video/mpeg', + 'mpeg' => 'video/mpeg', + 'mpg' => 'video/mpeg', + 'mpg4' => 'video/mp4', + 'mpga' => 'audio/mpeg', + 'mpkg' => 'application/vnd.apple.installer+xml', + 'mpm' => 'application/vnd.blueice.multipass', + 'mpn' => 'application/vnd.mophun.application', + 'mpp' => 'application/vnd.ms-project', + 'mpt' => 'application/vnd.ms-project', + 'mpy' => 'application/vnd.ibm.minipay', + 'mqy' => 'application/vnd.mobius.mqy', + 'mrc' => 'application/marc', + 'mrcx' => 'application/marcxml+xml', + 'ms' => 'text/troff', + 'mscml' => 'application/mediaservercontrol+xml', + 'mseed' => 'application/vnd.fdsn.mseed', + 'mseq' => 'application/vnd.mseq', + 'msf' => 'application/vnd.epson.msf', + 'msh' => 'model/mesh', + 'msi' => 'application/x-msdownload', + 'msl' => 'application/vnd.mobius.msl', + 'msty' => 'application/vnd.muvee.style', + 'mts' => 'model/vnd.mts', + 'mus' => 'application/vnd.musician', + 'musicxml' => 'application/vnd.recordare.musicxml+xml', + 'mvb' => 'application/x-msmediaview', + 'mwf' => 'application/vnd.mfer', + 'mxf' => 'application/mxf', + 'mxl' => 'application/vnd.recordare.musicxml', + 'mxml' => 'application/xv+xml', + 'mxs' => 'application/vnd.triscape.mxs', + 'mxu' => 'video/vnd.mpegurl', + 'n-gage' => 'application/vnd.nokia.n-gage.symbian.install', + 'n3' => 'text/n3', + 'nb' => 'application/mathematica', + 'nbp' => 'application/vnd.wolfram.player', + 'nc' => 'application/x-netcdf', + 'ncx' => 'application/x-dtbncx+xml', + 'ngdat' => 'application/vnd.nokia.n-gage.data', + 'nlu' => 'application/vnd.neurolanguage.nlu', + 'nml' => 'application/vnd.enliven', + 'nnd' => 'application/vnd.noblenet-directory', + 'nns' => 'application/vnd.noblenet-sealer', + 'nnw' => 'application/vnd.noblenet-web', + 'npx' => 'image/vnd.net-fpx', + 'nsf' => 'application/vnd.lotus-notes', + 'oa2' => 'application/vnd.fujitsu.oasys2', + 'oa3' => 'application/vnd.fujitsu.oasys3', + 'oas' => 'application/vnd.fujitsu.oasys', + 'obd' => 'application/x-msbinder', + 'oda' => 'application/oda', + 'odb' => 'application/vnd.oasis.opendocument.database', + 'odc' => 'application/vnd.oasis.opendocument.chart', + 'odf' => 'application/vnd.oasis.opendocument.formula', + 'odft' => 'application/vnd.oasis.opendocument.formula-template', + 'odg' => 'application/vnd.oasis.opendocument.graphics', + 'odi' => 'application/vnd.oasis.opendocument.image', + 'odm' => 'application/vnd.oasis.opendocument.text-master', + 'odp' => 'application/vnd.oasis.opendocument.presentation', + 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', + 'odt' => 'application/vnd.oasis.opendocument.text', + 'oga' => 'audio/ogg', + 'ogg' => 'audio/ogg', + 'ogv' => 'video/ogg', + 'ogx' => 'application/ogg', + 'onepkg' => 'application/onenote', + 'onetmp' => 'application/onenote', + 'onetoc' => 'application/onenote', + 'onetoc2' => 'application/onenote', + 'opf' => 'application/oebps-package+xml', + 'oprc' => 'application/vnd.palm', + 'org' => 'application/vnd.lotus-organizer', + 'osf' => 'application/vnd.yamaha.openscoreformat', + 'osfpvg' => 'application/vnd.yamaha.openscoreformat.osfpvg+xml', + 'otc' => 'application/vnd.oasis.opendocument.chart-template', + 'otf' => 'application/x-font-otf', + 'otg' => 'application/vnd.oasis.opendocument.graphics-template', + 'oth' => 'application/vnd.oasis.opendocument.text-web', + 'oti' => 'application/vnd.oasis.opendocument.image-template', + 'otp' => 'application/vnd.oasis.opendocument.presentation-template', + 'ots' => 'application/vnd.oasis.opendocument.spreadsheet-template', + 'ott' => 'application/vnd.oasis.opendocument.text-template', + 'oxt' => 'application/vnd.openofficeorg.extension', + 'p' => 'text/x-pascal', + 'p10' => 'application/pkcs10', + 'p12' => 'application/x-pkcs12', + 'p7b' => 'application/x-pkcs7-certificates', + 'p7c' => 'application/pkcs7-mime', + 'p7m' => 'application/pkcs7-mime', + 'p7r' => 'application/x-pkcs7-certreqresp', + 'p7s' => 'application/pkcs7-signature', + 'p8' => 'application/pkcs8', + 'pas' => 'text/x-pascal', + 'paw' => 'application/vnd.pawaafile', + 'pbd' => 'application/vnd.powerbuilder6', + 'pbm' => 'image/x-portable-bitmap', + 'pcf' => 'application/x-font-pcf', + 'pcl' => 'application/vnd.hp-pcl', + 'pclxl' => 'application/vnd.hp-pclxl', + 'pct' => 'image/x-pict', + 'pcurl' => 'application/vnd.curl.pcurl', + 'pcx' => 'image/x-pcx', + 'pdb' => 'application/vnd.palm', + 'pdf' => 'application/pdf', + 'pfa' => 'application/x-font-type1', + 'pfb' => 'application/x-font-type1', + 'pfm' => 'application/x-font-type1', + 'pfr' => 'application/font-tdpfr', + 'pfx' => 'application/x-pkcs12', + 'pgm' => 'image/x-portable-graymap', + 'pgn' => 'application/x-chess-pgn', + 'pgp' => 'application/pgp-encrypted', + 'php' => 'text/x-php', + 'phps' => 'application/x-httpd-phps', + 'pic' => 'image/x-pict', + 'pkg' => 'application/octet-stream', + 'pki' => 'application/pkixcmp', + 'pkipath' => 'application/pkix-pkipath', + 'plb' => 'application/vnd.3gpp.pic-bw-large', + 'plc' => 'application/vnd.mobius.plc', + 'plf' => 'application/vnd.pocketlearn', + 'pls' => 'application/pls+xml', + 'pml' => 'application/vnd.ctc-posml', + 'png' => 'image/png', + 'pnm' => 'image/x-portable-anymap', + 'portpkg' => 'application/vnd.macports.portpkg', + 'pot' => 'application/vnd.ms-powerpoint', + 'potm' => 'application/vnd.ms-powerpoint.template.macroenabled.12', + 'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template', + 'ppam' => 'application/vnd.ms-powerpoint.addin.macroenabled.12', + 'ppd' => 'application/vnd.cups-ppd', + 'ppm' => 'image/x-portable-pixmap', + 'pps' => 'application/vnd.ms-powerpoint', + 'ppsm' => 'application/vnd.ms-powerpoint.slideshow.macroenabled.12', + 'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow', + 'ppt' => 'application/vnd.ms-powerpoint', + 'pptm' => 'application/vnd.ms-powerpoint.presentation.macroenabled.12', + 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', + 'pqa' => 'application/vnd.palm', + 'prc' => 'application/x-mobipocket-ebook', + 'pre' => 'application/vnd.lotus-freelance', + 'prf' => 'application/pics-rules', + 'ps' => 'application/postscript', + 'psb' => 'application/vnd.3gpp.pic-bw-small', + 'psd' => 'image/vnd.adobe.photoshop', + 'psf' => 'application/x-font-linux-psf', + 'pskcxml' => 'application/pskc+xml', + 'ptid' => 'application/vnd.pvi.ptid1', + 'pub' => 'application/x-mspublisher', + 'pvb' => 'application/vnd.3gpp.pic-bw-var', + 'pwn' => 'application/vnd.3m.post-it-notes', + 'pya' => 'audio/vnd.ms-playready.media.pya', + 'pyv' => 'video/vnd.ms-playready.media.pyv', + 'qam' => 'application/vnd.epson.quickanime', + 'qbo' => 'application/vnd.intu.qbo', + 'qfx' => 'application/vnd.intu.qfx', + 'qps' => 'application/vnd.publishare-delta-tree', + 'qt' => 'video/quicktime', + 'qwd' => 'application/vnd.quark.quarkxpress', + 'qwt' => 'application/vnd.quark.quarkxpress', + 'qxb' => 'application/vnd.quark.quarkxpress', + 'qxd' => 'application/vnd.quark.quarkxpress', + 'qxl' => 'application/vnd.quark.quarkxpress', + 'qxt' => 'application/vnd.quark.quarkxpress', + 'ra' => 'audio/x-pn-realaudio', + 'ram' => 'audio/x-pn-realaudio', + 'rar' => 'application/x-rar-compressed', + 'ras' => 'image/x-cmu-raster', + 'rb' => 'text/plain', + 'rcprofile' => 'application/vnd.ipunplugged.rcprofile', + 'rdf' => 'application/rdf+xml', + 'rdz' => 'application/vnd.data-vision.rdz', + 'rep' => 'application/vnd.businessobjects', + 'res' => 'application/x-dtbresource+xml', + 'resx' => 'text/xml', + 'rgb' => 'image/x-rgb', + 'rif' => 'application/reginfo+xml', + 'rip' => 'audio/vnd.rip', + 'rl' => 'application/resource-lists+xml', + 'rlc' => 'image/vnd.fujixerox.edmics-rlc', + 'rld' => 'application/resource-lists-diff+xml', + 'rm' => 'application/vnd.rn-realmedia', + 'rmi' => 'audio/midi', + 'rmp' => 'audio/x-pn-realaudio-plugin', + 'rms' => 'application/vnd.jcp.javame.midlet-rms', + 'rnc' => 'application/relax-ng-compact-syntax', + 'roff' => 'text/troff', + 'rp9' => 'application/vnd.cloanto.rp9', + 'rpss' => 'application/vnd.nokia.radio-presets', + 'rpst' => 'application/vnd.nokia.radio-preset', + 'rq' => 'application/sparql-query', + 'rs' => 'application/rls-services+xml', + 'rsd' => 'application/rsd+xml', + 'rss' => 'application/rss+xml', + 'rtf' => 'application/rtf', + 'rtx' => 'text/richtext', + 's' => 'text/x-asm', + 'saf' => 'application/vnd.yamaha.smaf-audio', + 'sbml' => 'application/sbml+xml', + 'sc' => 'application/vnd.ibm.secure-container', + 'scd' => 'application/x-msschedule', + 'scm' => 'application/vnd.lotus-screencam', + 'scq' => 'application/scvp-cv-request', + 'scs' => 'application/scvp-cv-response', + 'scurl' => 'text/vnd.curl.scurl', + 'sda' => 'application/vnd.stardivision.draw', + 'sdc' => 'application/vnd.stardivision.calc', + 'sdd' => 'application/vnd.stardivision.impress', + 'sdkd' => 'application/vnd.solent.sdkm+xml', + 'sdkm' => 'application/vnd.solent.sdkm+xml', + 'sdp' => 'application/sdp', + 'sdw' => 'application/vnd.stardivision.writer', + 'see' => 'application/vnd.seemail', + 'seed' => 'application/vnd.fdsn.seed', + 'sema' => 'application/vnd.sema', + 'semd' => 'application/vnd.semd', + 'semf' => 'application/vnd.semf', + 'ser' => 'application/java-serialized-object', + 'setpay' => 'application/set-payment-initiation', + 'setreg' => 'application/set-registration-initiation', + 'sfd-hdstx' => 'application/vnd.hydrostatix.sof-data', + 'sfs' => 'application/vnd.spotfire.sfs', + 'sgl' => 'application/vnd.stardivision.writer-global', + 'sgm' => 'text/sgml', + 'sgml' => 'text/sgml', + 'sh' => 'application/x-sh', + 'shar' => 'application/x-shar', + 'shf' => 'application/shf+xml', + 'sig' => 'application/pgp-signature', + 'silo' => 'model/mesh', + 'sis' => 'application/vnd.symbian.install', + 'sisx' => 'application/vnd.symbian.install', + 'sit' => 'application/x-stuffit', + 'sitx' => 'application/x-stuffitx', + 'skd' => 'application/vnd.koan', + 'skm' => 'application/vnd.koan', + 'skp' => 'application/vnd.koan', + 'skt' => 'application/vnd.koan', + 'sldm' => 'application/vnd.ms-powerpoint.slide.macroenabled.12', + 'sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide', + 'slt' => 'application/vnd.epson.salt', + 'sm' => 'application/vnd.stepmania.stepchart', + 'smf' => 'application/vnd.stardivision.math', + 'smi' => 'application/smil+xml', + 'smil' => 'application/smil+xml', + 'snd' => 'audio/basic', + 'snf' => 'application/x-font-snf', + 'so' => 'application/octet-stream', + 'spc' => 'application/x-pkcs7-certificates', + 'spf' => 'application/vnd.yamaha.smaf-phrase', + 'spl' => 'application/x-futuresplash', + 'spot' => 'text/vnd.in3d.spot', + 'spp' => 'application/scvp-vp-response', + 'spq' => 'application/scvp-vp-request', + 'spx' => 'audio/ogg', + 'src' => 'application/x-wais-source', + 'sru' => 'application/sru+xml', + 'srx' => 'application/sparql-results+xml', + 'sse' => 'application/vnd.kodak-descriptor', + 'ssf' => 'application/vnd.epson.ssf', + 'ssml' => 'application/ssml+xml', + 'st' => 'application/vnd.sailingtracker.track', + 'stc' => 'application/vnd.sun.xml.calc.template', + 'std' => 'application/vnd.sun.xml.draw.template', + 'stf' => 'application/vnd.wt.stf', + 'sti' => 'application/vnd.sun.xml.impress.template', + 'stk' => 'application/hyperstudio', + 'stl' => 'application/vnd.ms-pki.stl', + 'str' => 'application/vnd.pg.format', + 'stw' => 'application/vnd.sun.xml.writer.template', + 'sub' => 'image/vnd.dvb.subtitle', + 'sus' => 'application/vnd.sus-calendar', + 'susp' => 'application/vnd.sus-calendar', + 'sv4cpio' => 'application/x-sv4cpio', + 'sv4crc' => 'application/x-sv4crc', + 'svc' => 'application/vnd.dvb.service', + 'svd' => 'application/vnd.svd', + 'svg' => 'image/svg+xml', + 'svgz' => 'image/svg+xml', + 'swa' => 'application/x-director', + 'swf' => 'application/x-shockwave-flash', + 'swi' => 'application/vnd.aristanetworks.swi', + 'sxc' => 'application/vnd.sun.xml.calc', + 'sxd' => 'application/vnd.sun.xml.draw', + 'sxg' => 'application/vnd.sun.xml.writer.global', + 'sxi' => 'application/vnd.sun.xml.impress', + 'sxm' => 'application/vnd.sun.xml.math', + 'sxw' => 'application/vnd.sun.xml.writer', + 't' => 'text/troff', + 'tao' => 'application/vnd.tao.intent-module-archive', + 'tar' => 'application/x-tar', + 'tcap' => 'application/vnd.3gpp2.tcap', + 'tcl' => 'application/x-tcl', + 'teacher' => 'application/vnd.smart.teacher', + 'tei' => 'application/tei+xml', + 'teicorpus' => 'application/tei+xml', + 'tex' => 'application/x-tex', + 'texi' => 'application/x-texinfo', + 'texinfo' => 'application/x-texinfo', + 'text' => 'text/plain', + 'tfi' => 'application/thraud+xml', + 'tfm' => 'application/x-tex-tfm', + 'thmx' => 'application/vnd.ms-officetheme', + 'tif' => 'image/tiff', + 'tiff' => 'image/tiff', + 'tmo' => 'application/vnd.tmobile-livetv', + 'torrent' => 'application/x-bittorrent', + 'tpl' => 'application/vnd.groove-tool-template', + 'tpt' => 'application/vnd.trid.tpt', + 'tr' => 'text/troff', + 'tra' => 'application/vnd.trueapp', + 'trm' => 'application/x-msterminal', + 'tsd' => 'application/timestamped-data', + 'tsv' => 'text/tab-separated-values', + 'ttc' => 'application/x-font-ttf', + 'ttf' => 'application/x-font-ttf', + 'ttl' => 'text/turtle', + 'twd' => 'application/vnd.simtech-mindmapper', + 'twds' => 'application/vnd.simtech-mindmapper', + 'txd' => 'application/vnd.genomatix.tuxedo', + 'txf' => 'application/vnd.mobius.txf', + 'txt' => 'text/plain', + 'u32' => 'application/x-authorware-bin', + 'udeb' => 'application/x-debian-package', + 'ufd' => 'application/vnd.ufdl', + 'ufdl' => 'application/vnd.ufdl', + 'umj' => 'application/vnd.umajin', + 'unityweb' => 'application/vnd.unity', + 'uoml' => 'application/vnd.uoml+xml', + 'uri' => 'text/uri-list', + 'uris' => 'text/uri-list', + 'urls' => 'text/uri-list', + 'ustar' => 'application/x-ustar', + 'utz' => 'application/vnd.uiq.theme', + 'uu' => 'text/x-uuencode', + 'uva' => 'audio/vnd.dece.audio', + 'uvd' => 'application/vnd.dece.data', + 'uvf' => 'application/vnd.dece.data', + 'uvg' => 'image/vnd.dece.graphic', + 'uvh' => 'video/vnd.dece.hd', + 'uvi' => 'image/vnd.dece.graphic', + 'uvm' => 'video/vnd.dece.mobile', + 'uvp' => 'video/vnd.dece.pd', + 'uvs' => 'video/vnd.dece.sd', + 'uvt' => 'application/vnd.dece.ttml+xml', + 'uvu' => 'video/vnd.uvvu.mp4', + 'uvv' => 'video/vnd.dece.video', + 'uvva' => 'audio/vnd.dece.audio', + 'uvvd' => 'application/vnd.dece.data', + 'uvvf' => 'application/vnd.dece.data', + 'uvvg' => 'image/vnd.dece.graphic', + 'uvvh' => 'video/vnd.dece.hd', + 'uvvi' => 'image/vnd.dece.graphic', + 'uvvm' => 'video/vnd.dece.mobile', + 'uvvp' => 'video/vnd.dece.pd', + 'uvvs' => 'video/vnd.dece.sd', + 'uvvt' => 'application/vnd.dece.ttml+xml', + 'uvvu' => 'video/vnd.uvvu.mp4', + 'uvvv' => 'video/vnd.dece.video', + 'uvvx' => 'application/vnd.dece.unspecified', + 'uvx' => 'application/vnd.dece.unspecified', + 'vcd' => 'application/x-cdlink', + 'vcf' => 'text/x-vcard', + 'vcg' => 'application/vnd.groove-vcard', + 'vcs' => 'text/x-vcalendar', + 'vcx' => 'application/vnd.vcx', + 'vis' => 'application/vnd.visionary', + 'viv' => 'video/vnd.vivo', + 'vor' => 'application/vnd.stardivision.writer', + 'vox' => 'application/x-authorware-bin', + 'vrml' => 'model/vrml', + 'vsd' => 'application/vnd.visio', + 'vsf' => 'application/vnd.vsf', + 'vss' => 'application/vnd.visio', + 'vst' => 'application/vnd.visio', + 'vsw' => 'application/vnd.visio', + 'vtu' => 'model/vnd.vtu', + 'vxml' => 'application/voicexml+xml', + 'w3d' => 'application/x-director', + 'wad' => 'application/x-doom', + 'wav' => 'audio/x-wav', + 'wax' => 'audio/x-ms-wax', + 'wbmp' => 'image/vnd.wap.wbmp', + 'wbs' => 'application/vnd.criticaltools.wbs+xml', + 'wbxml' => 'application/vnd.wap.wbxml', + 'wcm' => 'application/vnd.ms-works', + 'wdb' => 'application/vnd.ms-works', + 'weba' => 'audio/webm', + 'webm' => 'video/webm', + 'webp' => 'image/webp', + 'wg' => 'application/vnd.pmi.widget', + 'wgt' => 'application/widget', + 'wks' => 'application/vnd.ms-works', + 'wm' => 'video/x-ms-wm', + 'wma' => 'audio/x-ms-wma', + 'wmd' => 'application/x-ms-wmd', + 'wmf' => 'application/x-msmetafile', + 'wml' => 'text/vnd.wap.wml', + 'wmlc' => 'application/vnd.wap.wmlc', + 'wmls' => 'text/vnd.wap.wmlscript', + 'wmlsc' => 'application/vnd.wap.wmlscriptc', + 'wmv' => 'video/x-ms-wmv', + 'wmx' => 'video/x-ms-wmx', + 'wmz' => 'application/x-ms-wmz', + 'woff' => 'application/x-font-woff', + 'wpd' => 'application/vnd.wordperfect', + 'wpl' => 'application/vnd.ms-wpl', + 'wps' => 'application/vnd.ms-works', + 'wqd' => 'application/vnd.wqd', + 'wri' => 'application/x-mswrite', + 'wrl' => 'model/vrml', + 'wsdl' => 'application/wsdl+xml', + 'wspolicy' => 'application/wspolicy+xml', + 'wtb' => 'application/vnd.webturbo', + 'wvx' => 'video/x-ms-wvx', + 'x32' => 'application/x-authorware-bin', + 'x3d' => 'application/vnd.hzn-3d-crossword', + 'xap' => 'application/x-silverlight-app', + 'xar' => 'application/vnd.xara', + 'xbap' => 'application/x-ms-xbap', + 'xbd' => 'application/vnd.fujixerox.docuworks.binder', + 'xbm' => 'image/x-xbitmap', + 'xdf' => 'application/xcap-diff+xml', + 'xdm' => 'application/vnd.syncml.dm+xml', + 'xdp' => 'application/vnd.adobe.xdp+xml', + 'xdssc' => 'application/dssc+xml', + 'xdw' => 'application/vnd.fujixerox.docuworks', + 'xenc' => 'application/xenc+xml', + 'xer' => 'application/patch-ops-error+xml', + 'xfdf' => 'application/vnd.adobe.xfdf', + 'xfdl' => 'application/vnd.xfdl', + 'xht' => 'application/xhtml+xml', + 'xhtml' => 'application/xhtml+xml', + 'xhvml' => 'application/xv+xml', + 'xif' => 'image/vnd.xiff', + 'xla' => 'application/vnd.ms-excel', + 'xlam' => 'application/vnd.ms-excel.addin.macroenabled.12', + 'xlc' => 'application/vnd.ms-excel', + 'xlm' => 'application/vnd.ms-excel', + 'xls' => 'application/vnd.ms-excel', + 'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroenabled.12', + 'xlsm' => 'application/vnd.ms-excel.sheet.macroenabled.12', + 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'xlt' => 'application/vnd.ms-excel', + 'xltm' => 'application/vnd.ms-excel.template.macroenabled.12', + 'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template', + 'xlw' => 'application/vnd.ms-excel', + 'xml' => 'application/xml', + 'xo' => 'application/vnd.olpc-sugar', + 'xop' => 'application/xop+xml', + 'xpi' => 'application/x-xpinstall', + 'xpm' => 'image/x-xpixmap', + 'xpr' => 'application/vnd.is-xpr', + 'xps' => 'application/vnd.ms-xpsdocument', + 'xpw' => 'application/vnd.intercon.formnet', + 'xpx' => 'application/vnd.intercon.formnet', + 'xsl' => 'application/xml', + 'xslt' => 'application/xslt+xml', + 'xsm' => 'application/vnd.syncml+xml', + 'xspf' => 'application/xspf+xml', + 'xul' => 'application/vnd.mozilla.xul+xml', + 'xvm' => 'application/xv+xml', + 'xvml' => 'application/xv+xml', + 'xwd' => 'image/x-xwindowdump', + 'xyz' => 'chemical/x-xyz', + 'yaml' => 'text/yaml', + 'yang' => 'application/yang', + 'yin' => 'application/yin+xml', + 'yml' => 'text/yaml', + 'zaz' => 'application/vnd.zzazz.deck+xml', + 'zip' => 'application/zip', + 'zir' => 'application/vnd.zul', + 'zirz' => 'application/vnd.zul', + 'zmm' => 'application/vnd.handheld-entertainment+xml' + ); + + /** + * Get a singleton instance of the class + * + * @return self + * @codeCoverageIgnore + */ + public static function getInstance() + { + if (!self::$instance) { + self::$instance = new self(); + } + + return self::$instance; + } + + /** + * Get a mimetype value from a file extension + * + * @param string $extension File extension + * + * @return string|null + * + */ + public function fromExtension($extension) + { + $extension = strtolower($extension); + + return isset($this->mimetypes[$extension]) ? $this->mimetypes[$extension] : null; + } + + /** + * Get a mimetype from a filename + * + * @param string $filename Filename to generate a mimetype from + * + * @return string|null + */ + public function fromFilename($filename) + { + return $this->fromExtension(pathinfo($filename, PATHINFO_EXTENSION)); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/QueryAggregator/CommaAggregator.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/QueryAggregator/CommaAggregator.php new file mode 100644 index 0000000..4b4e49d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/QueryAggregator/CommaAggregator.php @@ -0,0 +1,20 @@ +isUrlEncoding()) { + return array($query->encodeValue($key) => implode(',', array_map(array($query, 'encodeValue'), $value))); + } else { + return array($key => implode(',', $value)); + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/QueryAggregator/DuplicateAggregator.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/QueryAggregator/DuplicateAggregator.php new file mode 100644 index 0000000..1bf1730 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/QueryAggregator/DuplicateAggregator.php @@ -0,0 +1,22 @@ +isUrlEncoding()) { + return array($query->encodeValue($key) => array_map(array($query, 'encodeValue'), $value)); + } else { + return array($key => $value); + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/QueryAggregator/PhpAggregator.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/QueryAggregator/PhpAggregator.php new file mode 100644 index 0000000..133ea2b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/QueryAggregator/PhpAggregator.php @@ -0,0 +1,27 @@ + $v) { + $k = "{$key}[{$k}]"; + if (is_array($v)) { + $ret = array_merge($ret, self::aggregate($k, $v, $query)); + } else { + $ret[$query->encodeValue($k)] = $query->encodeValue($v); + } + } + + return $ret; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/QueryAggregator/QueryAggregatorInterface.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/QueryAggregator/QueryAggregatorInterface.php new file mode 100644 index 0000000..72bee62 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/QueryAggregator/QueryAggregatorInterface.php @@ -0,0 +1,22 @@ +add($key, $value); + $foundDuplicates = true; + } elseif ($paramIsPhpStyleArray) { + $q[$key] = array($value); + } else { + $q[$key] = $value; + } + } else { + // Uses false by default to represent keys with no trailing "=" sign. + $q->add($key, false); + } + } + + // Use the duplicate aggregator if duplicates were found and not using PHP style arrays + if ($foundDuplicates && !$foundPhpStyle) { + $q->setAggregator(new DuplicateAggregator()); + } + + return $q; + } + + /** + * Convert the query string parameters to a query string string + * + * @return string + * @throws RuntimeException + */ + public function __toString() + { + if (!$this->data) { + return ''; + } + + $queryList = array(); + foreach ($this->prepareData($this->data) as $name => $value) { + $queryList[] = $this->convertKvp($name, $value); + } + + return implode($this->fieldSeparator, $queryList); + } + + /** + * Get the query string field separator + * + * @return string + */ + public function getFieldSeparator() + { + return $this->fieldSeparator; + } + + /** + * Get the query string value separator + * + * @return string + */ + public function getValueSeparator() + { + return $this->valueSeparator; + } + + /** + * Returns the type of URL encoding used by the query string + * + * One of: false, "RFC 3986", or "application/x-www-form-urlencoded" + * + * @return bool|string + */ + public function getUrlEncoding() + { + return $this->urlEncode; + } + + /** + * Returns true or false if using URL encoding + * + * @return bool + */ + public function isUrlEncoding() + { + return $this->urlEncode !== false; + } + + /** + * Provide a function for combining multi-valued query string parameters into a single or multiple fields + * + * @param null|QueryAggregatorInterface $aggregator Pass in a QueryAggregatorInterface object to handle converting + * deeply nested query string variables into a flattened array. + * Pass null to use the default PHP style aggregator. For legacy + * reasons, this function accepts a callable that must accepts a + * $key, $value, and query object. + * @return self + * @see \Guzzle\Http\QueryString::aggregateUsingComma() + */ + public function setAggregator(QueryAggregatorInterface $aggregator = null) + { + // Use the default aggregator if none was set + if (!$aggregator) { + if (!self::$defaultAggregator) { + self::$defaultAggregator = new PhpAggregator(); + } + $aggregator = self::$defaultAggregator; + } + + $this->aggregator = $aggregator; + + return $this; + } + + /** + * Set whether or not field names and values should be rawurlencoded + * + * @param bool|string $encode Set to TRUE to use RFC 3986 encoding (rawurlencode), false to disable encoding, or + * form_urlencoding to use application/x-www-form-urlencoded encoding (urlencode) + * @return self + */ + public function useUrlEncoding($encode) + { + $this->urlEncode = ($encode === true) ? self::RFC_3986 : $encode; + + return $this; + } + + /** + * Set the query string separator + * + * @param string $separator The query string separator that will separate fields + * + * @return self + */ + public function setFieldSeparator($separator) + { + $this->fieldSeparator = $separator; + + return $this; + } + + /** + * Set the query string value separator + * + * @param string $separator The query string separator that will separate values from fields + * + * @return self + */ + public function setValueSeparator($separator) + { + $this->valueSeparator = $separator; + + return $this; + } + + /** + * Returns an array of url encoded field names and values + * + * @return array + */ + public function urlEncode() + { + return $this->prepareData($this->data); + } + + /** + * URL encodes a value based on the url encoding type of the query string object + * + * @param string $value Value to encode + * + * @return string + */ + public function encodeValue($value) + { + if ($this->urlEncode == self::RFC_3986) { + return rawurlencode($value); + } elseif ($this->urlEncode == self::FORM_URLENCODED) { + return urlencode($value); + } else { + return (string) $value; + } + } + + /** + * Url encode parameter data and convert nested query strings into a flattened hash. + * + * @param array $data The data to encode + * + * @return array Returns an array of encoded values and keys + */ + protected function prepareData(array $data) + { + // If no aggregator is present then set the default + if (!$this->aggregator) { + $this->setAggregator(null); + } + + $temp = array(); + foreach ($data as $key => $value) { + if ($value === false || $value === null) { + // False and null will not include the "=". Use an empty string to include the "=". + $temp[$this->encodeValue($key)] = $value; + } elseif (is_array($value)) { + $temp = array_merge($temp, $this->aggregator->aggregate($key, $value, $this)); + } else { + $temp[$this->encodeValue($key)] = $this->encodeValue($value); + } + } + + return $temp; + } + + /** + * Converts a key value pair that can contain strings, nulls, false, or arrays + * into a single string. + * + * @param string $name Name of the field + * @param mixed $value Value of the field + * @return string + */ + private function convertKvp($name, $value) + { + if ($value === self::BLANK || $value === null || $value === false) { + return $name; + } elseif (!is_array($value)) { + return $name . $this->valueSeparator . $value; + } + + $result = ''; + foreach ($value as $v) { + $result .= $this->convertKvp($name, $v) . $this->fieldSeparator; + } + + return rtrim($result, $this->fieldSeparator); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/ReadLimitEntityBody.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/ReadLimitEntityBody.php new file mode 100644 index 0000000..ef28273 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/ReadLimitEntityBody.php @@ -0,0 +1,122 @@ +setLimit($limit)->setOffset($offset); + } + + /** + * Returns only a subset of the decorated entity body when cast as a string + * {@inheritdoc} + */ + public function __toString() + { + if (!$this->body->isReadable() || + (!$this->body->isSeekable() && $this->body->isConsumed()) + ) { + return ''; + } + + $originalPos = $this->body->ftell(); + $this->body->seek($this->offset); + $data = ''; + while (!$this->feof()) { + $data .= $this->read(1048576); + } + $this->body->seek($originalPos); + + return (string) $data ?: ''; + } + + public function isConsumed() + { + return $this->body->isConsumed() || + ($this->body->ftell() >= $this->offset + $this->limit); + } + + /** + * Returns the Content-Length of the limited subset of data + * {@inheritdoc} + */ + public function getContentLength() + { + $length = $this->body->getContentLength(); + + return $length === false + ? $this->limit + : min($this->limit, min($length, $this->offset + $this->limit) - $this->offset); + } + + /** + * Allow for a bounded seek on the read limited entity body + * {@inheritdoc} + */ + public function seek($offset, $whence = SEEK_SET) + { + return $whence === SEEK_SET + ? $this->body->seek(max($this->offset, min($this->offset + $this->limit, $offset))) + : false; + } + + /** + * Set the offset to start limiting from + * + * @param int $offset Offset to seek to and begin byte limiting from + * + * @return self + */ + public function setOffset($offset) + { + $this->body->seek($offset); + $this->offset = $offset; + + return $this; + } + + /** + * Set the limit of bytes that the decorator allows to be read from the stream + * + * @param int $limit Total number of bytes to allow to be read from the stream + * + * @return self + */ + public function setLimit($limit) + { + $this->limit = $limit; + + return $this; + } + + public function read($length) + { + // Check if the current position is less than the total allowed bytes + original offset + $remaining = ($this->offset + $this->limit) - $this->body->ftell(); + if ($remaining > 0) { + // Only return the amount of requested data, ensuring that the byte limit is not exceeded + return $this->body->read(min($remaining, $length)); + } else { + return false; + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/RedirectPlugin.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/RedirectPlugin.php new file mode 100644 index 0000000..1a824b8 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/RedirectPlugin.php @@ -0,0 +1,250 @@ + array('onRequestSent', 100), + 'request.clone' => 'cleanupRequest', + 'request.before_send' => 'cleanupRequest' + ); + } + + /** + * Clean up the parameters of a request when it is cloned + * + * @param Event $event Event emitted + */ + public function cleanupRequest(Event $event) + { + $params = $event['request']->getParams(); + unset($params[self::REDIRECT_COUNT]); + unset($params[self::PARENT_REQUEST]); + } + + /** + * Called when a request receives a redirect response + * + * @param Event $event Event emitted + */ + public function onRequestSent(Event $event) + { + $response = $event['response']; + $request = $event['request']; + + // Only act on redirect requests with Location headers + if (!$response || $request->getParams()->get(self::DISABLE)) { + return; + } + + // Trace the original request based on parameter history + $original = $this->getOriginalRequest($request); + + // Terminating condition to set the effective response on the original request + if (!$response->isRedirect() || !$response->hasHeader('Location')) { + if ($request !== $original) { + // This is a terminating redirect response, so set it on the original request + $response->getParams()->set(self::REDIRECT_COUNT, $original->getParams()->get(self::REDIRECT_COUNT)); + $original->setResponse($response); + $response->setEffectiveUrl($request->getUrl()); + } + return; + } + + $this->sendRedirectRequest($original, $request, $response); + } + + /** + * Get the original request that initiated a series of redirects + * + * @param RequestInterface $request Request to get the original request from + * + * @return RequestInterface + */ + protected function getOriginalRequest(RequestInterface $request) + { + $original = $request; + // The number of redirects is held on the original request, so determine which request that is + while ($parent = $original->getParams()->get(self::PARENT_REQUEST)) { + $original = $parent; + } + + return $original; + } + + /** + * Create a redirect request for a specific request object + * + * Takes into account strict RFC compliant redirection (e.g. redirect POST with POST) vs doing what most clients do + * (e.g. redirect POST with GET). + * + * @param RequestInterface $request Request being redirected + * @param RequestInterface $original Original request + * @param int $statusCode Status code of the redirect + * @param string $location Location header of the redirect + * + * @return RequestInterface Returns a new redirect request + * @throws CouldNotRewindStreamException If the body needs to be rewound but cannot + */ + protected function createRedirectRequest( + RequestInterface $request, + $statusCode, + $location, + RequestInterface $original + ) { + $redirectRequest = null; + $strict = $original->getParams()->get(self::STRICT_REDIRECTS); + + // Switch method to GET for 303 redirects. 301 and 302 redirects also switch to GET unless we are forcing RFC + // compliance to emulate what most browsers do. NOTE: IE only switches methods on 301/302 when coming from a POST. + if ($request instanceof EntityEnclosingRequestInterface && ($statusCode == 303 || (!$strict && $statusCode <= 302))) { + $redirectRequest = RequestFactory::getInstance()->cloneRequestWithMethod($request, 'GET'); + } else { + $redirectRequest = clone $request; + } + + $redirectRequest->setIsRedirect(true); + // Always use the same response body when redirecting + $redirectRequest->setResponseBody($request->getResponseBody()); + + $location = Url::factory($location); + // If the location is not absolute, then combine it with the original URL + if (!$location->isAbsolute()) { + $originalUrl = $redirectRequest->getUrl(true); + // Remove query string parameters and just take what is present on the redirect Location header + $originalUrl->getQuery()->clear(); + $location = $originalUrl->combine((string) $location, true); + } + + $redirectRequest->setUrl($location); + + // Add the parent request to the request before it sends (make sure it's before the onRequestClone event too) + $redirectRequest->getEventDispatcher()->addListener( + 'request.before_send', + $func = function ($e) use (&$func, $request, $redirectRequest) { + $redirectRequest->getEventDispatcher()->removeListener('request.before_send', $func); + $e['request']->getParams()->set(RedirectPlugin::PARENT_REQUEST, $request); + } + ); + + // Rewind the entity body of the request if needed + if ($redirectRequest instanceof EntityEnclosingRequestInterface && $redirectRequest->getBody()) { + $body = $redirectRequest->getBody(); + // Only rewind the body if some of it has been read already, and throw an exception if the rewind fails + if ($body->ftell() && !$body->rewind()) { + throw new CouldNotRewindStreamException( + 'Unable to rewind the non-seekable entity body of the request after redirecting. cURL probably ' + . 'sent part of body before the redirect occurred. Try adding acustom rewind function using on the ' + . 'entity body of the request using setRewindFunction().' + ); + } + } + + return $redirectRequest; + } + + /** + * Prepare the request for redirection and enforce the maximum number of allowed redirects per client + * + * @param RequestInterface $original Original request + * @param RequestInterface $request Request to prepare and validate + * @param Response $response The current response + * + * @return RequestInterface + */ + protected function prepareRedirection(RequestInterface $original, RequestInterface $request, Response $response) + { + $params = $original->getParams(); + // This is a new redirect, so increment the redirect counter + $current = $params[self::REDIRECT_COUNT] + 1; + $params[self::REDIRECT_COUNT] = $current; + // Use a provided maximum value or default to a max redirect count of 5 + $max = isset($params[self::MAX_REDIRECTS]) ? $params[self::MAX_REDIRECTS] : $this->defaultMaxRedirects; + + // Throw an exception if the redirect count is exceeded + if ($current > $max) { + $this->throwTooManyRedirectsException($original, $max); + return false; + } else { + // Create a redirect request based on the redirect rules set on the request + return $this->createRedirectRequest( + $request, + $response->getStatusCode(), + trim($response->getLocation()), + $original + ); + } + } + + /** + * Send a redirect request and handle any errors + * + * @param RequestInterface $original The originating request + * @param RequestInterface $request The current request being redirected + * @param Response $response The response of the current request + * + * @throws BadResponseException|\Exception + */ + protected function sendRedirectRequest(RequestInterface $original, RequestInterface $request, Response $response) + { + // Validate and create a redirect request based on the original request and current response + if ($redirectRequest = $this->prepareRedirection($original, $request, $response)) { + try { + $redirectRequest->send(); + } catch (BadResponseException $e) { + $e->getResponse(); + if (!$e->getResponse()) { + throw $e; + } + } + } + } + + /** + * Throw a too many redirects exception for a request + * + * @param RequestInterface $original Request + * @param int $max Max allowed redirects + * + * @throws TooManyRedirectsException when too many redirects have been issued + */ + protected function throwTooManyRedirectsException(RequestInterface $original, $max) + { + $original->getEventDispatcher()->addListener( + 'request.complete', + $func = function ($e) use (&$func, $original, $max) { + $original->getEventDispatcher()->removeListener('request.complete', $func); + $str = "{$max} redirects were issued for this request:\n" . $e['request']->getRawHeaders(); + throw new TooManyRedirectsException($str); + } + ); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Resources/cacert.pem b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Resources/cacert.pem new file mode 100644 index 0000000..18ce703 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Resources/cacert.pem @@ -0,0 +1,3870 @@ +## +## Bundle of CA Root Certificates +## +## Certificate data from Mozilla downloaded on: Wed Aug 13 21:49:32 2014 +## +## This is a bundle of X.509 certificates of public Certificate Authorities +## (CA). These were automatically extracted from Mozilla's root certificates +## file (certdata.txt). This file can be found in the mozilla source tree: +## http://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt +## +## It contains the certificates in PEM format and therefore +## can be directly used with curl / libcurl / php_curl, or with +## an Apache+mod_ssl webserver for SSL client authentication. +## Just configure this file as the SSLCACertificateFile. +## +## Conversion done with mk-ca-bundle.pl verison 1.22. +## SHA1: bf2c15b3019e696660321d2227d942936dc50aa7 +## + + +GTE CyberTrust Global Root +========================== +-----BEGIN CERTIFICATE----- +MIICWjCCAcMCAgGlMA0GCSqGSIb3DQEBBAUAMHUxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9HVEUg +Q29ycG9yYXRpb24xJzAlBgNVBAsTHkdURSBDeWJlclRydXN0IFNvbHV0aW9ucywgSW5jLjEjMCEG +A1UEAxMaR1RFIEN5YmVyVHJ1c3QgR2xvYmFsIFJvb3QwHhcNOTgwODEzMDAyOTAwWhcNMTgwODEz +MjM1OTAwWjB1MQswCQYDVQQGEwJVUzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQL +Ex5HVEUgQ3liZXJUcnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0 +IEdsb2JhbCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVD6C28FCc6HrHiM3dFw4u +sJTQGz0O9pTAipTHBsiQl8i4ZBp6fmw8U+E3KHNgf7KXUwefU/ltWJTSr41tiGeA5u2ylc9yMcql +HHK6XALnZELn+aks1joNrI1CqiQBOeacPwGFVw1Yh0X404Wqk2kmhXBIgD8SFcd5tB8FLztimQID +AQABMA0GCSqGSIb3DQEBBAUAA4GBAG3rGwnpXtlR22ciYaQqPEh346B8pt5zohQDhT37qw4wxYMW +M4ETCJ57NE7fQMh017l93PR2VX2bY1QY6fDq81yx2YtCHrnAlU66+tXifPVoYb+O7AWXX1uw16OF +NMQkpw0PlZPvy5TYnh+dXIVtx6quTx8itc2VrbqnzPmrC3p/ +-----END CERTIFICATE----- + +Thawte Server CA +================ +-----BEGIN CERTIFICATE----- +MIIDEzCCAnygAwIBAgIBATANBgkqhkiG9w0BAQQFADCBxDELMAkGA1UEBhMCWkExFTATBgNVBAgT +DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29uc3Vs +dGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcGA1UE +AxMQVGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5j +b20wHhcNOTYwODAxMDAwMDAwWhcNMjAxMjMxMjM1OTU5WjCBxDELMAkGA1UEBhMCWkExFTATBgNV +BAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29u +c3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcG +A1UEAxMQVGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0 +ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANOkUG7I/1Zr5s9dtuoMaHVHoqrC2oQl +/Kj0R1HahbUgdJSGHg91yekIYfUGbTBuFRkC6VLAYttNmZ7iagxEOM3+vuNkCXDF/rFrKbYvScg7 +1CcEJRCXL+eQbcAoQpnXTEPew/UhbVSfXcNY4cDk2VuwuNy0e982OsK1ZiIS1ocNAgMBAAGjEzAR +MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAB/pMaVz7lcxG7oWDTSEwjsrZqG9J +GubaUeNgcGyEYRGhGshIPllDfU+VPaGLtwtimHp1it2ITk6eQNuozDJ0uW8NxuOzRAvZim+aKZuZ +GCg70eNAKJpaPNW15yAbi8qkq43pUdniTCxZqdq5snUb9kLy78fyGPmJvKP/iiMucEc= +-----END CERTIFICATE----- + +Thawte Premium Server CA +======================== +-----BEGIN CERTIFICATE----- +MIIDJzCCApCgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBzjELMAkGA1UEBhMCWkExFTATBgNVBAgT +DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29uc3Vs +dGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UE +AxMYVGhhd3RlIFByZW1pdW0gU2VydmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNlcnZl +ckB0aGF3dGUuY29tMB4XDTk2MDgwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgc4xCzAJBgNVBAYT +AlpBMRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsGA1UEChMU +VGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRpb24gU2VydmljZXMgRGl2 +aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNlcnZlciBDQTEoMCYGCSqGSIb3DQEJARYZ +cHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0jY2 +aovXwlue2oFBYo847kkEVdbQ7xwblRZH7xhINTpS9CtqBo87L+pW46+GjZ4X9560ZXUCTe/LCaIh +Udib0GfQug2SBhRz1JPLlyoAnFxODLz6FVL88kRu2hFKbgifLy3j+ao6hnO2RlNYyIkFvYMRuHM/ +qgeN9EJN50CdHDcCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQQFAAOBgQAm +SCwWwlj66BZ0DKqqX1Q/8tfJeGBeXm43YyJ3Nn6yF8Q0ufUIhfzJATj/Tb7yFkJD57taRvvBxhEf +8UqwKEbJw8RCfbz6q1lu1bdRiBHjpIUZa4JMpAwSremkrj/xw0llmozFyD4lt5SZu5IycQfwhl7t +UCemDaYj+bvLpgcUQg== +-----END CERTIFICATE----- + +Equifax Secure CA +================= +-----BEGIN CERTIFICATE----- +MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJVUzEQMA4GA1UE +ChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 +MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoT +B0VxdWlmYXgxLTArBgNVBAsTJEVxdWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCB +nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPR +fM6fBeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+AcJkVV5MW +8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kCAwEAAaOCAQkwggEFMHAG +A1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UE +CxMkRXF1aWZheCBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoG +A1UdEAQTMBGBDzIwMTgwODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvS +spXXR9gjIBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQFMAMB +Af8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUAA4GBAFjOKer89961 +zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y7qj/WsjTVbJmcVfewCHrPSqnI0kB +BIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee95 +70+sB3c4 +-----END CERTIFICATE----- + +Verisign Class 3 Public Primary Certification Authority +======================================================= +-----BEGIN CERTIFICATE----- +MIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzELMAkGA1UEBhMCVVMx +FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmltYXJ5 +IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVow +XzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAz +IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUA +A4GNADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhEBarsAx94 +f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/isI19wKTakyYbnsZogy1Ol +hec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0GCSqGSIb3DQEBAgUAA4GBALtMEivPLCYA +TxQT3ab7/AoRhIzzKBxnki98tsX63/Dolbwdj2wsqFHMc9ikwFPwTtYmwHYBV4GSXiHx0bH/59Ah +WM1pF+NEHJwZRDmJXNycAA9WjQKZ7aKQRUzkuxCkPfAyAw7xzvjoyVGM5mKf5p/AfbdynMk2Omuf +Tqj/ZA1k +-----END CERTIFICATE----- + +Verisign Class 3 Public Primary Certification Authority - G2 +============================================================ +-----BEGIN CERTIFICATE----- +MIIDAjCCAmsCEH3Z/gfPqB63EHln+6eJNMYwDQYJKoZIhvcNAQEFBQAwgcExCzAJBgNVBAYTAlVT +MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMgUHJpbWFy +eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln +biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz +dCBOZXR3b3JrMB4XDTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVT +MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMgUHJpbWFy +eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln +biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz +dCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMXtERXVxp0KvTuWpMmR9ZmDCO +FoUgRm1HP9SFIIThbbP4pO0M8RcPO/mn+SXXwc+EY/J8Y8+iR/LGWzOOZEAEaMGAuWQcRXfH2G71 +lSk8UOg013gfqLptQ5GVj0VXXn7F+8qkBOvqlzdUMG+7AUcyM83cV5tkaWH4mx0ciU9cZwIDAQAB +MA0GCSqGSIb3DQEBBQUAA4GBAFFNzb5cy5gZnBWyATl4Lk0PZ3BwmcYQWpSkU01UbSuvDV1Ai2TT +1+7eVmGSX6bEHRBhNtMsJzzoKQm5EWR0zLVznxxIqbxhAe7iF6YM40AIOw7n60RzKprxaZLvcRTD +Oaxxp5EJb+RxBrO6WVcmeQD2+A2iMzAo1KpYoJ2daZH9 +-----END CERTIFICATE----- + +GlobalSign Root CA +================== +-----BEGIN CERTIFICATE----- +MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkGA1UEBhMCQkUx +GTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jvb3QgQ0ExGzAZBgNVBAMTEkds +b2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAwMDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNV +BAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYD +VQQDExJHbG9iYWxTaWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDa +DuaZjc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavpxy0Sy6sc +THAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp1Wrjsok6Vjk4bwY8iGlb +Kk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdGsnUOhugZitVtbNV4FpWi6cgKOOvyJBNP +c1STE4U6G7weNLWLBYy5d4ux2x8gkasJU26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrX +gzT/LCrBbBlDSgeF59N89iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0BAQUF +AAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOzyj1hTdNGCbM+w6Dj +Y1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE38NflNUVyRRBnMRddWQVDf9VMOyG +j/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymPAbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhH +hm4qxFYxldBniYUr+WymXUadDKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveC +X4XSQRjbgbMEHMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== +-----END CERTIFICATE----- + +GlobalSign Root CA - R2 +======================= +-----BEGIN CERTIFICATE----- +MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4GA1UECxMXR2xv +YmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh +bFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT +aWduIFJvb3QgQ0EgLSBSMjETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln +bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6 +ErPLv4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8eoLrvozp +s6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklqtTleiDTsvHgMCJiEbKjN +S7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzdC9XZzPnqJworc5HGnRusyMvo4KD0L5CL +TfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pazq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6C +ygPCm48CAwEAAaOBnDCBmTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQUm+IHV2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5nbG9i +YWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG3lm0mi3f3BmGLjAN +BgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4GsJ0/WwbgcQ3izDJr86iw8bmEbTUsp +9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu +01yiPqFbQfXf5WRDLenVOavSot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG7 +9G+dwfCMNYxdAfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7 +TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg== +-----END CERTIFICATE----- + +ValiCert Class 1 VA +=================== +-----BEGIN CERTIFICATE----- +MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRp +b24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs +YXNzIDEgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZh +bGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNTIy +MjM0OFoXDTE5MDYyNTIyMjM0OFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0 +d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDEg +UG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0 +LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3DQEBAQUA +A4GNADCBiQKBgQDYWYJ6ibiWuqYvaG9YLqdUHAZu9OqNSLwxlBfw8068srg1knaw0KWlAdcAAxIi +GQj4/xEjm84H9b9pGib+TunRf50sQB1ZaG6m+FiwnRqP0z/x3BkGgagO4DrdyFNFCQbmD3DD+kCm +DuJWBQ8YTfwggtFzVXSNdnKgHZ0dwN0/cQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFBoPUn0LBwG +lN+VYH+Wexf+T3GtZMjdd9LvWVXoP+iOBSoh8gfStadS/pyxtuJbdxdA6nLWI8sogTLDAHkY7FkX +icnGah5xyf23dKUlRWnFSKsZ4UWKJWsZ7uW7EvV/96aNUcPwnXS3qT6gpf+2SQMT2iLM7XGCK5nP +Orf1LXLI +-----END CERTIFICATE----- + +ValiCert Class 2 VA +=================== +-----BEGIN CERTIFICATE----- +MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRp +b24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs +YXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZh +bGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAw +MTk1NFoXDTE5MDYyNjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0 +d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIg +UG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0 +LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3DQEBAQUA +A4GNADCBiQKBgQDOOnHK5avIWZJV16vYdA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVC +CSRrCl6zfN1SLUzm1NZ9WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7Rf +ZHM047QSv4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9vUJSZ +SWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTuIYEZoDJJKPTEjlbV +UjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwCW/POuZ6lcg5Ktz885hZo+L7tdEy8 +W9ViH0Pd +-----END CERTIFICATE----- + +RSA Root Certificate 1 +====================== +-----BEGIN CERTIFICATE----- +MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRp +b24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs +YXNzIDMgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZh +bGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAw +MjIzM1oXDTE5MDYyNjAwMjIzM1owgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0 +d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDMg +UG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0 +LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3DQEBAQUA +A4GNADCBiQKBgQDjmFGWHOjVsQaBalfDcnWTq8+epvzzFlLWLU2fNUSoLgRNB0mKOCn1dzfnt6td +3zZxFJmP3MKS8edgkpfs2Ejcv8ECIMYkpChMMFp2bbFc893enhBxoYjHW5tBbcqwuI4V7q0zK89H +BFx1cQqYJJgpp0lZpd34t0NiYfPT4tBVPwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFa7AliEZwgs +3x/be0kz9dNnnfS0ChCzycUs4pJqcXgn8nCDQtM+z6lU9PHYkhaM0QTLS6vJn0WuPIqpsHEzXcjF +V9+vqDWzf4mH6eglkrh/hXqu1rweN1gqZ8mRzyqBPu3GOd/APhmcGcwTTYJBtYze4D1gCCAPRX5r +on+jjBXu +-----END CERTIFICATE----- + +Verisign Class 3 Public Primary Certification Authority - G3 +============================================================ +-----BEGIN CERTIFICATE----- +MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV +UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv +cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl +IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw +CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy +dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv +cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkg +Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAMu6nFL8eB8aHm8bN3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1 +EUGO+i2tKmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGukxUc +cLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBmCC+Vk7+qRy+oRpfw +EuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJXwzw3sJ2zq/3avL6QaaiMxTJ5Xpj +055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWuimi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA +ERSWwauSCPc/L8my/uRan2Te2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5f +j267Cz3qWhMeDGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC +/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565pF4ErWjfJXir0 +xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGtTxzhT5yvDwyd93gN2PQ1VoDa +t20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ== +-----END CERTIFICATE----- + +Verisign Class 4 Public Primary Certification Authority - G3 +============================================================ +-----BEGIN CERTIFICATE----- +MIIEGjCCAwICEQDsoKeLbnVqAc/EfMwvlF7XMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV +UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv +cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl +IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw +CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy +dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv +cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDQgUHVibGljIFByaW1hcnkg +Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAK3LpRFpxlmr8Y+1GQ9Wzsy1HyDkniYlS+BzZYlZ3tCD5PUPtbut8XzoIfzk6AzufEUiGXaS +tBO3IFsJ+mGuqPKljYXCKtbeZjbSmwL0qJJgfJxptI8kHtCGUvYynEFYHiK9zUVilQhu0GbdU6LM +8BDcVHOLBKFGMzNcF0C5nk3T875Vg+ixiY5afJqWIpA7iCXy0lOIAgwLePLmNxdLMEYH5IBtptiW +Lugs+BGzOA1mppvqySNb247i8xOOGlktqgLw7KSHZtzBP/XYufTsgsbSPZUd5cBPhMnZo0QoBmrX +Razwa2rvTl/4EYIeOGM0ZlDUPpNz+jDDZq3/ky2X7wMCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA +j/ola09b5KROJ1WrIhVZPMq1CtRK26vdoV9TxaBXOcLORyu+OshWv8LZJxA6sQU8wHcxuzrTBXtt +mhwwjIDLk5Mqg6sFUYICABFna/OIYUdfA5PVWw3g8dShMjWFsjrbsIKr0csKvE+MW8VLADsfKoKm +fjaF3H48ZwC15DtS4KjrXRX5xm3wrR0OhbepmnMUWluPQSjA1egtTaRezarZ7c7c2NU8Qh0XwRJd +RTjDOPP8hS6DRkiy1yBfkjaP53kPmF6Z6PDQpLv1U70qzlmwr25/bLvSHgCwIe34QWKCudiyxLtG +UPMxxY8BqHTr9Xgn2uf3ZkPznoM+IKrDNWCRzg== +-----END CERTIFICATE----- + +Entrust.net Secure Server CA +============================ +-----BEGIN CERTIFICATE----- +MIIE2DCCBEGgAwIBAgIEN0rSQzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMCVVMxFDASBgNV +BAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5uZXQvQ1BTIGluY29ycC4gYnkg +cmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRl +ZDE6MDgGA1UEAxMxRW50cnVzdC5uZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhv +cml0eTAeFw05OTA1MjUxNjA5NDBaFw0xOTA1MjUxNjM5NDBaMIHDMQswCQYDVQQGEwJVUzEUMBIG +A1UEChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5jb3JwLiBi +eSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBFbnRydXN0Lm5ldCBMaW1p +dGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQDNKIM0VBuJ8w+vN5Ex/68xYMmo6LIQ +aO2f55M28Qpku0f1BBc/I0dNxScZgSYMVHINiC3ZH5oSn7yzcdOAGT9HZnuMNSjSuQrfJNqc1lB5 +gXpa0zf3wkrYKZImZNHkmGw6AIr1NJtl+O3jEP/9uElY3KDegjlrgbEWGWG5VLbmQwIBA6OCAdcw +ggHTMBEGCWCGSAGG+EIBAQQEAwIABzCCARkGA1UdHwSCARAwggEMMIHeoIHboIHYpIHVMIHSMQsw +CQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5l +dC9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBF +bnRydXN0Lm5ldCBMaW1pdGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENl +cnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMCmgJ6AlhiNodHRwOi8vd3d3LmVu +dHJ1c3QubmV0L0NSTC9uZXQxLmNybDArBgNVHRAEJDAigA8xOTk5MDUyNTE2MDk0MFqBDzIwMTkw +NTI1MTYwOTQwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAU8BdiE1U9s/8KAGv7UISX8+1i0Bow +HQYDVR0OBBYEFPAXYhNVPbP/CgBr+1CEl/PtYtAaMAwGA1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EA +BAwwChsEVjQuMAMCBJAwDQYJKoZIhvcNAQEFBQADgYEAkNwwAvpkdMKnCqV8IY00F6j7Rw7/JXyN +Ewr75Ji174z4xRAN95K+8cPV1ZVqBLssziY2ZcgxxufuP+NXdYR6Ee9GTxj005i7qIcyunL2POI9 +n9cd2cNgQ4xYDiKWL2KjLB+6rQXvqzJ4h6BUcxm1XAX5Uj5tLUUL9wqT6u0G+bI= +-----END CERTIFICATE----- + +Entrust.net Premium 2048 Secure Server CA +========================================= +-----BEGIN CERTIFICATE----- +MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChMLRW50cnVzdC5u +ZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBpbmNvcnAuIGJ5IHJlZi4gKGxp +bWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNV +BAMTKkVudHJ1c3QubmV0IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQx +NzUwNTFaFw0yOTA3MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3 +d3d3LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTEl +MCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5u +ZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgpMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEArU1LqRKGsuqjIAcVFmQqK0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOL +Gp18EzoOH1u3Hs/lJBQesYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSr +hRSGlVuXMlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVTXTzW +nLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/HoZdenoVve8AjhUi +VBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH4QIDAQABo0IwQDAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJ +KoZIhvcNAQEFBQADggEBADubj1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPy +T/4xmf3IDExoU8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf +zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5bu/8j72gZyxKT +J1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+bYQLCIt+jerXmCHG8+c8eS9e +nNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/ErfF6adulZkMV8gzURZVE= +-----END CERTIFICATE----- + +Baltimore CyberTrust Root +========================= +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJRTESMBAGA1UE +ChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYDVQQDExlCYWx0aW1vcmUgQ3li +ZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoXDTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMC +SUUxEjAQBgNVBAoTCUJhbHRpbW9yZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFs +dGltb3JlIEN5YmVyVHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKME +uyKrmD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjrIZ3AQSsB +UnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeKmpYcqWe4PwzV9/lSEy/C +G9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSuXmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9 +XbIGevOF6uvUA65ehD5f/xXtabz5OTZydc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjpr +l3RjM71oGDHweI12v/yejl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoI +VDaGezq1BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEB +BQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT929hkTI7gQCvlYpNRh +cL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3WgxjkzSswF07r51XgdIGn9w/xZchMB5 +hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsa +Y71k5h+3zvDyny67G7fyUIhzksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9H +RCwBXbsdtTLSR9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp +-----END CERTIFICATE----- + +Equifax Secure Global eBusiness CA +================================== +-----BEGIN CERTIFICATE----- +MIICkDCCAfmgAwIBAgIBATANBgkqhkiG9w0BAQQFADBaMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT +RXF1aWZheCBTZWN1cmUgSW5jLjEtMCsGA1UEAxMkRXF1aWZheCBTZWN1cmUgR2xvYmFsIGVCdXNp +bmVzcyBDQS0xMB4XDTk5MDYyMTA0MDAwMFoXDTIwMDYyMTA0MDAwMFowWjELMAkGA1UEBhMCVVMx +HDAaBgNVBAoTE0VxdWlmYXggU2VjdXJlIEluYy4xLTArBgNVBAMTJEVxdWlmYXggU2VjdXJlIEds +b2JhbCBlQnVzaW5lc3MgQ0EtMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuucXkAJlsTRV +PEnCUdXfp9E3j9HngXNBUmCbnaEXJnitx7HoJpQytd4zjTov2/KaelpzmKNc6fuKcxtc58O/gGzN +qfTWK8D3+ZmqY6KxRwIP1ORROhI8bIpaVIRw28HFkM9yRcuoWcDNM50/o5brhTMhHD4ePmBudpxn +hcXIw2ECAwEAAaNmMGQwEQYJYIZIAYb4QgEBBAQDAgAHMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0j +BBgwFoAUvqigdHJQa0S3ySPY+6j/s1draGwwHQYDVR0OBBYEFL6ooHRyUGtEt8kj2Puo/7NXa2hs +MA0GCSqGSIb3DQEBBAUAA4GBADDiAVGqx+pf2rnQZQ8w1j7aDRRJbpGTJxQx78T3LUX47Me/okEN +I7SS+RkAZ70Br83gcfxaz2TE4JaY0KNA4gGK7ycH8WUBikQtBmV1UsCGECAhX2xrD2yuCRyv8qIY +NMR1pHMc8Y3c7635s3a0kr/clRAevsvIO1qEYBlWlKlV +-----END CERTIFICATE----- + +Equifax Secure eBusiness CA 1 +============================= +-----BEGIN CERTIFICATE----- +MIICgjCCAeugAwIBAgIBBDANBgkqhkiG9w0BAQQFADBTMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT +RXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNzIENB +LTEwHhcNOTkwNjIxMDQwMDAwWhcNMjAwNjIxMDQwMDAwWjBTMQswCQYDVQQGEwJVUzEcMBoGA1UE +ChMTRXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNz +IENBLTEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vGbwXt3fek6lfWg0XTzQaDJj0ItlZ +1MRoRvC0NcWFAyDGr0WlIVFFQesWWDYyb+JQYmT5/VGcqiTZ9J2DKocKIdMSODRsjQBuWqDZQu4a +IZX5UkxVWsUPOE9G+m34LjXWHXzr4vCwdYDIqROsvojvOm6rXyo4YgKwEnv+j6YDAgMBAAGjZjBk +MBEGCWCGSAGG+EIBAQQEAwIABzAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFEp4MlIR21kW +Nl7fwRQ2QGpHfEyhMB0GA1UdDgQWBBRKeDJSEdtZFjZe38EUNkBqR3xMoTANBgkqhkiG9w0BAQQF +AAOBgQB1W6ibAxHm6VZMzfmpTMANmvPMZWnmJXbMWbfWVMMdzZmsGd20hdXgPfxiIKeES1hl8eL5 +lSE/9dR+WB5Hh1Q+WKG1tfgq73HnvMP2sUlG4tega+VWeponmHxGYhTnyfxuAxJ5gDgdSIKN/Bf+ +KpYrtWKmpj29f5JZzVoqgrI3eQ== +-----END CERTIFICATE----- + +AddTrust Low-Value Services Root +================================ +-----BEGIN CERTIFICATE----- +MIIEGDCCAwCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQGEwJTRTEUMBIGA1UEChML +QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYDVQQDExhBZGRU +cnVzdCBDbGFzcyAxIENBIFJvb3QwHhcNMDAwNTMwMTAzODMxWhcNMjAwNTMwMTAzODMxWjBlMQsw +CQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBO +ZXR3b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQCWltQhSWDia+hBBwzexODcEyPNwTXH+9ZOEQpnXvUGW2ulCDtbKRY6 +54eyNAbFvAWlA3yCyykQruGIgb3WntP+LVbBFc7jJp0VLhD7Bo8wBN6ntGO0/7Gcrjyvd7ZWxbWr +oulpOj0OM3kyP3CCkplhbY0wCI9xP6ZIVxn4JdxLZlyldI+Yrsj5wAYi56xz36Uu+1LcsRVlIPo1 +Zmne3yzxbrww2ywkEtvrNTVokMsAsJchPXQhI2U0K7t4WaPW4XY5mqRJjox0r26kmqPZm9I4XJui +GMx1I4S+6+JNM3GOGvDC+Mcdoq0Dlyz4zyXG9rgkMbFjXZJ/Y/AlyVMuH79NAgMBAAGjgdIwgc8w +HQYDVR0OBBYEFJWxtPCUtr3H2tERCSG+wa9J/RB7MAsGA1UdDwQEAwIBBjAPBgNVHRMBAf8EBTAD +AQH/MIGPBgNVHSMEgYcwgYSAFJWxtPCUtr3H2tERCSG+wa9J/RB7oWmkZzBlMQswCQYDVQQGEwJT +RTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEw +HwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBACxt +ZBsfzQ3duQH6lmM0MkhHma6X7f1yFqZzR1r0693p9db7RcwpiURdv0Y5PejuvE1Uhh4dbOMXJ0Ph +iVYrqW9yTkkz43J8KiOavD7/KCrto/8cI7pDVwlnTUtiBi34/2ydYB7YHEt9tTEv2dB8Xfjea4MY +eDdXL+gzB2ffHsdrKpV2ro9Xo/D0UrSpUwjP4E/TelOL/bscVjby/rK25Xa71SJlpz/+0WatC7xr +mYbvP33zGDLKe8bjq2RGlfgmadlVg3sslgf/WSxEo8bl6ancoWOAWiFeIc9TVPC6b4nbqKqVz4vj +ccweGyBECMB6tkD9xOQ14R0WHNC8K47Wcdk= +-----END CERTIFICATE----- + +AddTrust External Root +====================== +-----BEGIN CERTIFICATE----- +MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEUMBIGA1UEChML +QWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYD +VQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEw +NDgzOFowbzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRU +cnVzdCBFeHRlcm5hbCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0Eg +Um9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvtH7xsD821 ++iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9uMq/NzgtHj6RQa1wVsfw +Tz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzXmk6vBbOmcZSccbNQYArHE504B4YCqOmo +aSYYkKtMsE8jqzpPhNjfzp/haW+710LXa0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy +2xSoRcRdKn23tNbE7qzNE0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv7 +7+ldU9U0WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYDVR0P +BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0Jvf6xCZU7wO94CTL +VBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEmMCQGA1UECxMdQWRk +VHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsxIjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENB +IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZl +j7DYd7usQWxHYINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5 +6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvCNr4TDea9Y355 +e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEXc4g/VhsxOBi0cQ+azcgOno4u +G+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5amnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ= +-----END CERTIFICATE----- + +AddTrust Public Services Root +============================= +-----BEGIN CERTIFICATE----- +MIIEFTCCAv2gAwIBAgIBATANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJTRTEUMBIGA1UEChML +QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSAwHgYDVQQDExdBZGRU +cnVzdCBQdWJsaWMgQ0EgUm9vdDAeFw0wMDA1MzAxMDQxNTBaFw0yMDA1MzAxMDQxNTBaMGQxCzAJ +BgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5l +dHdvcmsxIDAeBgNVBAMTF0FkZFRydXN0IFB1YmxpYyBDQSBSb290MIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEA6Rowj4OIFMEg2Dybjxt+A3S72mnTRqX4jsIMEZBRpS9mVEBV6tsfSlbu +nyNu9DnLoblv8n75XYcmYZ4c+OLspoH4IcUkzBEMP9smcnrHAZcHF/nXGCwwfQ56HmIexkvA/X1i +d9NEHif2P0tEs7c42TkfYNVRknMDtABp4/MUTu7R3AnPdzRGULD4EfL+OHn3Bzn+UZKXC1sIXzSG +Aa2Il+tmzV7R/9x98oTaunet3IAIx6eH1lWfl2royBFkuucZKT8Rs3iQhCBSWxHveNCD9tVIkNAw +HM+A+WD+eeSI8t0A65RF62WUaUC6wNW0uLp9BBGo6zEFlpROWCGOn9Bg/QIDAQABo4HRMIHOMB0G +A1UdDgQWBBSBPjfYkrAfd59ctKtzquf2NGAv+jALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zCBjgYDVR0jBIGGMIGDgBSBPjfYkrAfd59ctKtzquf2NGAv+qFopGYwZDELMAkGA1UEBhMCU0Ux +FDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRUcnVzdCBUVFAgTmV0d29yazEgMB4G +A1UEAxMXQWRkVHJ1c3QgUHVibGljIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBAAP3FUr4 +JNojVhaTdt02KLmuG7jD8WS6IBh4lSknVwW8fCr0uVFV2ocC3g8WFzH4qnkuCRO7r7IgGRLlk/lL ++YPoRNWyQSW/iHVv/xD8SlTQX/D67zZzfRs2RcYhbbQVuE7PnFylPVoAjgbjPGsye/Kf8Lb93/Ao +GEjwxrzQvzSAlsJKsW2Ox5BF3i9nrEUEo3rcVZLJR2bYGozH7ZxOmuASu7VqTITh4SINhwBk/ox9 +Yjllpu9CtoAlEmEBqCQTcAARJl/6NVDFSMwGR+gn2HCNX2TmoUQmXiLsks3/QppEIW1cxeMiHV9H +EufOX1362KqxMy3ZdvJOOjMMK7MtkAY= +-----END CERTIFICATE----- + +AddTrust Qualified Certificates Root +==================================== +-----BEGIN CERTIFICATE----- +MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJTRTEUMBIGA1UEChML +QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSMwIQYDVQQDExpBZGRU +cnVzdCBRdWFsaWZpZWQgQ0EgUm9vdDAeFw0wMDA1MzAxMDQ0NTBaFw0yMDA1MzAxMDQ0NTBaMGcx +CzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQ +IE5ldHdvcmsxIzAhBgNVBAMTGkFkZFRydXN0IFF1YWxpZmllZCBDQSBSb290MIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5B6a/twJWoekn0e+EV+vhDTbYjx5eLfpMLXsDBwqxBb/4Oxx +64r1EW7tTw2R0hIYLUkVAcKkIhPHEWT/IhKauY5cLwjPcWqzZwFZ8V1G87B4pfYOQnrjfxvM0PC3 +KP0q6p6zsLkEqv32x7SxuCqg+1jxGaBvcCV+PmlKfw8i2O+tCBGaKZnhqkRFmhJePp1tUvznoD1o +L/BLcHwTOK28FSXx1s6rosAx1i+f4P8UWfyEk9mHfExUE+uf0S0R+Bg6Ot4l2ffTQO2kBhLEO+GR +wVY18BTcZTYJbqukB8c10cIDMzZbdSZtQvESa0NvS3GU+jQd7RNuyoB/mC9suWXY6QIDAQABo4HU +MIHRMB0GA1UdDgQWBBQ5lYtii1zJ1IC6WA+XPxUIQ8yYpzALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zCBkQYDVR0jBIGJMIGGgBQ5lYtii1zJ1IC6WA+XPxUIQ8yYp6FrpGkwZzELMAkGA1UE +BhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRUcnVzdCBUVFAgTmV0d29y +azEjMCEGA1UEAxMaQWRkVHJ1c3QgUXVhbGlmaWVkIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQAD +ggEBABmrder4i2VhlRO6aQTvhsoToMeqT2QbPxj2qC0sVY8FtzDqQmodwCVRLae/DLPt7wh/bDxG +GuoYQ992zPlmhpwsaPXpF/gxsxjE1kh9I0xowX67ARRvxdlu3rsEQmr49lx95dr6h+sNNVJn0J6X +dgWTP5XHAeZpVTh/EGGZyeNfpso+gmNIquIISD6q8rKFYqa0p9m9N5xotS1WfbC3P6CxB9bpT9ze +RXEwMn8bLgn5v1Kh7sKAPgZcLlVAwRv1cEWw3F369nJad9Jjzc9YiQBCYz95OdBEsIJuQRno3eDB +iFrRHnGTHyQwdOUeqN48Jzd/g66ed8/wMLH/S5noxqE= +-----END CERTIFICATE----- + +Entrust Root Certification Authority +==================================== +-----BEGIN CERTIFICATE----- +MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMCVVMxFjAUBgNV +BAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0Lm5ldC9DUFMgaXMgaW5jb3Jw +b3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMWKGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsG +A1UEAxMkRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0 +MloXDTI2MTEyNzIwNTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMu +MTkwNwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSByZWZlcmVu +Y2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNVBAMTJEVudHJ1c3QgUm9v +dCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +ALaVtkNC+sZtKm9I35RMOVcF7sN5EUFoNu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYsz +A9u3g3s+IIRe7bJWKKf44LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOww +Cj0Yzfv9KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGIrb68 +j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi94DkZfs0Nw4pgHBN +rziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOBsDCBrTAOBgNVHQ8BAf8EBAMCAQYw +DwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAigA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1 +MzQyWjAfBgNVHSMEGDAWgBRokORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DH +hmak8fdLQ/uEvW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA +A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9tO1KzKtvn1ISM +Y/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6ZuaAGAT/3B+XxFNSRuzFVJ7yVTa +v52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTS +W3iDVuycNsMm4hH2Z0kdkquM++v/eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0 +tHuu2guQOHXvgR1m0vdXcDazv/wor3ElhVsT/h5/WrQ8 +-----END CERTIFICATE----- + +RSA Security 2048 v3 +==================== +-----BEGIN CERTIFICATE----- +MIIDYTCCAkmgAwIBAgIQCgEBAQAAAnwAAAAKAAAAAjANBgkqhkiG9w0BAQUFADA6MRkwFwYDVQQK +ExBSU0EgU2VjdXJpdHkgSW5jMR0wGwYDVQQLExRSU0EgU2VjdXJpdHkgMjA0OCBWMzAeFw0wMTAy +MjIyMDM5MjNaFw0yNjAyMjIyMDM5MjNaMDoxGTAXBgNVBAoTEFJTQSBTZWN1cml0eSBJbmMxHTAb +BgNVBAsTFFJTQSBTZWN1cml0eSAyMDQ4IFYzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAt49VcdKA3XtpeafwGFAyPGJn9gqVB93mG/Oe2dJBVGutn3y+Gc37RqtBaB4Y6lXIL5F4iSj7 +Jylg/9+PjDvJSZu1pJTOAeo+tWN7fyb9Gd3AIb2E0S1PRsNO3Ng3OTsor8udGuorryGlwSMiuLgb +WhOHV4PR8CDn6E8jQrAApX2J6elhc5SYcSa8LWrg903w8bYqODGBDSnhAMFRD0xS+ARaqn1y07iH +KrtjEAMqs6FPDVpeRrc9DvV07Jmf+T0kgYim3WBU6JU2PcYJk5qjEoAAVZkZR73QpXzDuvsf9/UP ++Ky5tfQ3mBMY3oVbtwyCO4dvlTlYMNpuAWgXIszACwIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/ +MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBQHw1EwpKrpRa41JPr/JCwz0LGdjDAdBgNVHQ4E +FgQUB8NRMKSq6UWuNST6/yQsM9CxnYwwDQYJKoZIhvcNAQEFBQADggEBAF8+hnZuuDU8TjYcHnmY +v/3VEhF5Ug7uMYm83X/50cYVIeiKAVQNOvtUudZj1LGqlk2iQk3UUx+LEN5/Zb5gEydxiKRz44Rj +0aRV4VCT5hsOedBnvEbIvz8XDZXmxpBp3ue0L96VfdASPz0+f00/FGj1EVDVwfSQpQgdMWD/YIwj +VAqv/qFuxdF6Kmh4zx6CCiC0H63lhbJqaHVOrSU3lIW+vaHU6rcMSzyd6BIA8F+sDeGscGNz9395 +nzIlQnQFgCi/vcEkllgVsRch6YlL2weIZ/QVrXA+L02FO8K32/6YaCOJ4XQP3vTFhGMpG8zLB8kA +pKnXwiJPZ9d37CAFYd4= +-----END CERTIFICATE----- + +GeoTrust Global CA +================== +-----BEGIN CERTIFICATE----- +MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVTMRYwFAYDVQQK +Ew1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9iYWwgQ0EwHhcNMDIwNTIxMDQw +MDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5j +LjEbMBkGA1UEAxMSR2VvVHJ1c3QgR2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEA2swYYzD99BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjo +BbdqfnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDviS2Aelet +8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU1XupGc1V3sjs0l44U+Vc +T4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+bw8HHa8sHo9gOeL6NlMTOdReJivbPagU +vTLrGAMoUgRx5aszPeE4uwc2hGKceeoWMPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTAD +AQH/MB0GA1UdDgQWBBTAephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVk +DBF9qn1luMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKInZ57Q +zxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfStQWVYrmm3ok9Nns4 +d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcFPseKUgzbFbS9bZvlxrFUaKnjaZC2 +mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Unhw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6p +XE0zX5IJL4hmXXeXxx12E6nV5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvm +Mw== +-----END CERTIFICATE----- + +GeoTrust Global CA 2 +==================== +-----BEGIN CERTIFICATE----- +MIIDZjCCAk6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN +R2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFsIENBIDIwHhcNMDQwMzA0MDUw +MDAwWhcNMTkwMzA0MDUwMDAwWjBEMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5j +LjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFsIENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQDvPE1APRDfO1MA4Wf+lGAVPoWI8YkNkMgoI5kF6CsgncbzYEbYwbLVjDHZ3CB5JIG/ +NTL8Y2nbsSpr7iFY8gjpeMtvy/wWUsiRxP89c96xPqfCfWbB9X5SJBri1WeR0IIQ13hLTytCOb1k +LUCgsBDTOEhGiKEMuzozKmKY+wCdE1l/bztyqu6mD4b5BWHqZ38MN5aL5mkWRxHCJ1kDs6ZgwiFA +Vvqgx306E+PsV8ez1q6diYD3Aecs9pYrEw15LNnA5IZ7S4wMcoKK+xfNAGw6EzywhIdLFnopsk/b +HdQL82Y3vdj2V7teJHq4PIu5+pIaGoSe2HSPqht/XvT+RSIhAgMBAAGjYzBhMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFHE4NvICMVNHK266ZUapEBVYIAUJMB8GA1UdIwQYMBaAFHE4NvICMVNH +K266ZUapEBVYIAUJMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQUFAAOCAQEAA/e1K6tdEPx7 +srJerJsOflN4WT5CBP51o62sgU7XAotexC3IUnbHLB/8gTKY0UvGkpMzNTEv/NgdRN3ggX+d6Yvh +ZJFiCzkIjKx0nVnZellSlxG5FntvRdOW2TF9AjYPnDtuzywNA0ZF66D0f0hExghAzN4bcLUprbqL +OzRldRtxIR0sFAqwlpW41uryZfspuk/qkZN0abby/+Ea0AzRdoXLiiW9l14sbxWZJue2Kf8i7MkC +x1YAzUm5s2x7UwQa4qjJqhIFI8LO57sEAszAR6LkxCkvW0VXiVHuPOtSCP8HNR6fNWpHSlaY0VqF +H4z1Ir+rzoPz4iIprn2DQKi6bA== +-----END CERTIFICATE----- + +GeoTrust Universal CA +===================== +-----BEGIN CERTIFICATE----- +MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN +R2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVyc2FsIENBMB4XDTA0MDMwNDA1 +MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IElu +Yy4xHjAcBgNVBAMTFUdlb1RydXN0IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIP +ADCCAgoCggIBAKYVVaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9t +JPi8cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTTQjOgNB0e +RXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFhF7em6fgemdtzbvQKoiFs +7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2vc7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d +8Lsrlh/eezJS/R27tQahsiFepdaVaH/wmZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7V +qnJNk22CDtucvc+081xdVHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3Cga +Rr0BHdCXteGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZf9hB +Z3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfReBi9Fi1jUIxaS5BZu +KGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+nhutxx9z3SxPGWX9f5NAEC7S8O08 +ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0 +XG0D08DYj3rWMB8GA1UdIwQYMBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIB +hjANBgkqhkiG9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc +aanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fXIwjhmF7DWgh2 +qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzynANXH/KttgCJwpQzgXQQpAvvL +oJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0zuzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsK +xr2EoyNB3tZ3b4XUhRxQ4K5RirqNPnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxF +KyDuSN/n3QmOGKjaQI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2 +DFKWkoRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9ER/frslK +xfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQtDF4JbAiXfKM9fJP/P6EU +p8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/SfuvmbJxPgWp6ZKy7PtXny3YuxadIwVyQD8vI +P/rmMuGNG2+k5o7Y+SlIis5z/iw= +-----END CERTIFICATE----- + +GeoTrust Universal CA 2 +======================= +-----BEGIN CERTIFICATE----- +MIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN +R2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIwHhcNMDQwMzA0 +MDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3Qg +SW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0 +DE81WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUGFF+3Qs17 +j1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdqXbboW0W63MOhBW9Wjo8Q +JqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxLse4YuU6W3Nx2/zu+z18DwPw76L5GG//a +QMJS9/7jOvdqdzXQ2o3rXhhqMcceujwbKNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2 +WP0+GfPtDCapkzj4T8FdIgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP +20gaXT73y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRthAAn +ZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgocQIgfksILAAX/8sgC +SqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4Lt1ZrtmhN79UNdxzMk+MBB4zsslG +8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2 ++/CfXGJx7Tz0RzgQKzAfBgNVHSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8E +BAMCAYYwDQYJKoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z +dXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQL1EuxBRa3ugZ +4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgrFg5fNuH8KrUwJM/gYwx7WBr+ +mbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSoag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpq +A1Ihn0CoZ1Dy81of398j9tx4TuaYT1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpg +Y+RdM4kX2TGq2tbzGDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiP +pm8m1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJVOCiNUW7d +FGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH6aLcr34YEoP9VhdBLtUp +gn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwXQMAJKOSLakhT2+zNVVXxxvjpoixMptEm +X36vWkzaH6byHCx+rgIW0lbQL1dTR+iS +-----END CERTIFICATE----- + +America Online Root Certification Authority 1 +============================================= +-----BEGIN CERTIFICATE----- +MIIDpDCCAoygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT +QW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBPbmxpbmUgUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eSAxMB4XDTAyMDUyODA2MDAwMFoXDTM3MTExOTIwNDMwMFowYzELMAkG +A1UEBhMCVVMxHDAaBgNVBAoTE0FtZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2Eg +T25saW5lIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAKgv6KRpBgNHw+kqmP8ZonCaxlCyfqXfaE0bfA+2l2h9LaaLl+lkhsmj76CG +v2BlnEtUiMJIxUo5vxTjWVXlGbR0yLQFOVwWpeKVBeASrlmLojNoWBym1BW32J/X3HGrfpq/m44z +DyL9Hy7nBzbvYjnF3cu6JRQj3gzGPTzOggjmZj7aUTsWOqMFf6Dch9Wc/HKpoH145LcxVR5lu9Rh +sCFg7RAycsWSJR74kEoYeEfffjA3PlAb2xzTa5qGUwew76wGePiEmf4hjUyAtgyC9mZweRrTT6PP +8c9GsEsPPt2IYriMqQkoO3rHl+Ee5fSfwMCuJKDIodkP1nsmgmkyPacCAwEAAaNjMGEwDwYDVR0T +AQH/BAUwAwEB/zAdBgNVHQ4EFgQUAK3Zo/Z59m50qX8zPYEX10zPM94wHwYDVR0jBBgwFoAUAK3Z +o/Z59m50qX8zPYEX10zPM94wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBBQUAA4IBAQB8itEf +GDeC4Liwo+1WlchiYZwFos3CYiZhzRAW18y0ZTTQEYqtqKkFZu90821fnZmv9ov761KyBZiibyrF +VL0lvV+uyIbqRizBs73B6UlwGBaXCBOMIOAbLjpHyx7kADCVW/RFo8AasAFOq73AI25jP4BKxQft +3OJvx8Fi8eNy1gTIdGcL+oiroQHIb/AUr9KZzVGTfu0uOMe9zkZQPXLjeSWdm4grECDdpbgyn43g +Kd8hdIaC2y+CMMbHNYaz+ZZfRtsMRf3zUMNvxsNIrUam4SdHCh0Om7bCd39j8uB9Gr784N/Xx6ds +sPmuujz9dLQR6FgNgLzTqIA6me11zEZ7 +-----END CERTIFICATE----- + +America Online Root Certification Authority 2 +============================================= +-----BEGIN CERTIFICATE----- +MIIFpDCCA4ygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT +QW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBPbmxpbmUgUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eSAyMB4XDTAyMDUyODA2MDAwMFoXDTM3MDkyOTE0MDgwMFowYzELMAkG +A1UEBhMCVVMxHDAaBgNVBAoTE0FtZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2Eg +T25saW5lIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMjCCAiIwDQYJKoZIhvcNAQEBBQAD +ggIPADCCAgoCggIBAMxBRR3pPU0Q9oyxQcngXssNt79Hc9PwVU3dxgz6sWYFas14tNwC206B89en +fHG8dWOgXeMHDEjsJcQDIPT/DjsS/5uN4cbVG7RtIuOx238hZK+GvFciKtZHgVdEglZTvYYUAQv8 +f3SkWq7xuhG1m1hagLQ3eAkzfDJHA1zEpYNI9FdWboE2JxhP7JsowtS013wMPgwr38oE18aO6lhO +qKSlGBxsRZijQdEt0sdtjRnxrXm3gT+9BoInLRBYBbV4Bbkv2wxrkJB+FFk4u5QkE+XRnRTf04JN +RvCAOVIyD+OEsnpD8l7eXz8d3eOyG6ChKiMDbi4BFYdcpnV1x5dhvt6G3NRI270qv0pV2uh9UPu0 +gBe4lL8BPeraunzgWGcXuVjgiIZGZ2ydEEdYMtA1fHkqkKJaEBEjNa0vzORKW6fIJ/KD3l67Xnfn +6KVuY8INXWHQjNJsWiEOyiijzirplcdIz5ZvHZIlyMbGwcEMBawmxNJ10uEqZ8A9W6Wa6897Gqid +FEXlD6CaZd4vKL3Ob5Rmg0gp2OpljK+T2WSfVVcmv2/LNzGZo2C7HK2JNDJiuEMhBnIMoVxtRsX6 +Kc8w3onccVvdtjc+31D1uAclJuW8tf48ArO3+L5DwYcRlJ4jbBeKuIonDFRH8KmzwICMoCfrHRnj +B453cMor9H124HhnAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFE1FwWg4u3Op +aaEg5+31IqEjFNeeMB8GA1UdIwQYMBaAFE1FwWg4u3OpaaEg5+31IqEjFNeeMA4GA1UdDwEB/wQE +AwIBhjANBgkqhkiG9w0BAQUFAAOCAgEAZ2sGuV9FOypLM7PmG2tZTiLMubekJcmnxPBUlgtk87FY +T15R/LKXeydlwuXK5w0MJXti4/qftIe3RUavg6WXSIylvfEWK5t2LHo1YGwRgJfMqZJS5ivmae2p ++DYtLHe/YUjRYwu5W1LtGLBDQiKmsXeu3mnFzcccobGlHBD7GL4acN3Bkku+KVqdPzW+5X1R+FXg +JXUjhx5c3LqdsKyzadsXg8n33gy8CNyRnqjQ1xU3c6U1uPx+xURABsPr+CKAXEfOAuMRn0T//Zoy +zH1kUQ7rVyZ2OuMeIjzCpjbdGe+n/BLzJsBZMYVMnNjP36TMzCmT/5RtdlwTCJfy7aULTd3oyWgO +ZtMADjMSW7yV5TKQqLPGbIOtd+6Lfn6xqavT4fG2wLHqiMDn05DpKJKUe2h7lyoKZy2FAjgQ5ANh +1NolNscIWC2hp1GvMApJ9aZphwctREZ2jirlmjvXGKL8nDgQzMY70rUXOm/9riW99XJZZLF0Kjhf +GEzfz3EEWjbUvy+ZnOjZurGV5gJLIaFb1cFPj65pbVPbAZO1XB4Y3WRayhgoPmMEEf0cjQAPuDff +Z4qdZqkCapH/E8ovXYO8h5Ns3CRRFgQlZvqz2cK6Kb6aSDiCmfS/O0oxGfm/jiEzFMpPVF/7zvuP +cX/9XhmgD0uRuMRUvAawRY8mkaKO/qk= +-----END CERTIFICATE----- + +Visa eCommerce Root +=================== +-----BEGIN CERTIFICATE----- +MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBrMQswCQYDVQQG +EwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2Ug +QXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2 +WhcNMjIwNjI0MDAxNjEyWjBrMQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMm +VmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNv +bW1lcmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h2mCxlCfL +F9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4ElpF7sDPwsRROEW+1QK8b +RaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdVZqW1LS7YgFmypw23RuwhY/81q6UCzyr0 +TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI +/k4+oKsGGelT84ATB+0tvz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzs +GHxBvfaLdXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEG +MB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUFAAOCAQEAX/FBfXxc +CLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcRzCSs00Rsca4BIGsDoo8Ytyk6feUW +YFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pz +zkWKsKZJ/0x9nXGIxHYdkFsd7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBu +YQa7FkKMcPcw++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt +398znM/jra6O1I7mT1GvFpLgXPYHDw== +-----END CERTIFICATE----- + +Certum Root CA +============== +-----BEGIN CERTIFICATE----- +MIIDDDCCAfSgAwIBAgIDAQAgMA0GCSqGSIb3DQEBBQUAMD4xCzAJBgNVBAYTAlBMMRswGQYDVQQK +ExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBDQTAeFw0wMjA2MTExMDQ2Mzla +Fw0yNzA2MTExMDQ2MzlaMD4xCzAJBgNVBAYTAlBMMRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8u +by4xEjAQBgNVBAMTCUNlcnR1bSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6x +wS7TT3zNJc4YPk/EjG+AanPIW1H4m9LcuwBcsaD8dQPugfCI7iNS6eYVM42sLQnFdvkrOYCJ5JdL +kKWoePhzQ3ukYbDYWMzhbGZ+nPMJXlVjhNWo7/OxLjBos8Q82KxujZlakE403Daaj4GIULdtlkIJ +89eVgw1BS7Bqa/j8D35in2fE7SZfECYPCE/wpFcozo+47UX2bu4lXapuOb7kky/ZR6By6/qmW6/K +Uz/iDsaWVhFu9+lmqSbYf5VT7QqFiLpPKaVCjF62/IUgAKpoC6EahQGcxEZjgoi2IrHu/qpGWX7P +NSzVttpd90gzFFS269lvzs2I1qsb2pY7HVkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkq +hkiG9w0BAQUFAAOCAQEAuI3O7+cUus/usESSbLQ5PqKEbq24IXfS1HeCh+YgQYHu4vgRt2PRFze+ +GXYkHAQaTOs9qmdvLdTN/mUxcMUbpgIKumB7bVjCmkn+YzILa+M6wKyrO7Do0wlRjBCDxjTgxSvg +GrZgFCdsMneMvLJymM/NzD+5yCRCFNZX/OYmQ6kd5YCQzgNUKD73P9P4Te1qCjqTE5s7FCMTY5w/ +0YcneeVMUeMBrYVdGjux1XMQpNPyvG5k9VpWkKjHDkx0Dy5xO/fIR/RpbxXyEV6DHpx8Uq79AtoS +qFlnGNu8cN2bsWntgM6JQEhqDjXKKWYVIZQs6GAqm4VKQPNriiTsBhYscw== +-----END CERTIFICATE----- + +Comodo AAA Services root +======================== +-----BEGIN CERTIFICATE----- +MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS +R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg +TGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAw +MFoXDTI4MTIzMTIzNTk1OVowezELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hl +c3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNV +BAMMGEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQuaBtDFcCLNSS1UY8y2bmhG +C1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe3M/vg4aijJRPn2jymJBGhCfHdr/jzDUs +i14HZGWCwEiwqJH5YZ92IFCokcdmtet4YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszW +Y19zjNoFmag4qMsXeDZRrOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjH +Ypy+g8cmez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQUoBEK +Iz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wewYDVR0f +BHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNl +cy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29tb2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2Vz +LmNybDANBgkqhkiG9w0BAQUFAAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm +7l3sAg9g1o1QGE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz +Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2G9w84FoVxp7Z +8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsil2D4kF501KKaU73yqWjgom7C +12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== +-----END CERTIFICATE----- + +Comodo Secure Services root +=========================== +-----BEGIN CERTIFICATE----- +MIIEPzCCAyegAwIBAgIBATANBgkqhkiG9w0BAQUFADB+MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS +R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg +TGltaXRlZDEkMCIGA1UEAwwbU2VjdXJlIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAw +MDAwMFoXDTI4MTIzMTIzNTk1OVowfjELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFu +Y2hlc3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxJDAi +BgNVBAMMG1NlY3VyZSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAMBxM4KK0HDrc4eCQNUd5MvJDkKQ+d40uaG6EfQlhfPMcm3ye5drswfxdySRXyWP +9nQ95IDC+DwN879A6vfIUtFyb+/Iq0G4bi4XKpVpDM3SHpR7LZQdqnXXs5jLrLxkU0C8j6ysNstc +rbvd4JQX7NFc0L/vpZXJkMWwrPsbQ996CF23uPJAGysnnlDOXmWCiIxe004MeuoIkbY2qitC++rC +oznl2yY4rYsK7hljxxwk3wN42ubqwUcaCwtGCd0C/N7Lh1/XMGNooa7cMqG6vv5Eq2i2pRcV/b3V +p6ea5EQz6YiO/O1R65NxTq0B50SOqy3LqP4BSUjwwN3HaNiS/j0CAwEAAaOBxzCBxDAdBgNVHQ4E +FgQUPNiTiMLAggnMAZkGkyDpnnAJY08wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8w +gYEGA1UdHwR6MHgwO6A5oDeGNWh0dHA6Ly9jcmwuY29tb2RvY2EuY29tL1NlY3VyZUNlcnRpZmlj +YXRlU2VydmljZXMuY3JsMDmgN6A1hjNodHRwOi8vY3JsLmNvbW9kby5uZXQvU2VjdXJlQ2VydGlm +aWNhdGVTZXJ2aWNlcy5jcmwwDQYJKoZIhvcNAQEFBQADggEBAIcBbSMdflsXfcFhMs+P5/OKlFlm +4J4oqF7Tt/Q05qo5spcWxYJvMqTpjOev/e/C6LlLqqP05tqNZSH7uoDrJiiFGv45jN5bBAS0VPmj +Z55B+glSzAVIqMk/IQQezkhr/IXownuvf7fM+F86/TXGDe+X3EyrEeFryzHRbPtIgKvcnDe4IRRL +DXE97IMzbtFuMhbsmMcWi1mmNKsFVy2T96oTy9IT4rcuO81rUBcJaD61JlfutuC23bkpgHl9j6Pw +pCikFcSF9CfUa7/lXORlAnZUtOM3ZiTTGWHIUhDlizeauan5Hb/qmZJhlv8BzaFfDbxxvA6sCx1H +RR3B7Hzs/Sk= +-----END CERTIFICATE----- + +Comodo Trusted Services root +============================ +-----BEGIN CERTIFICATE----- +MIIEQzCCAyugAwIBAgIBATANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS +R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg +TGltaXRlZDElMCMGA1UEAwwcVHJ1c3RlZCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczAeFw0wNDAxMDEw +MDAwMDBaFw0yODEyMzEyMzU5NTlaMH8xCzAJBgNVBAYTAkdCMRswGQYDVQQIDBJHcmVhdGVyIE1h +bmNoZXN0ZXIxEDAOBgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoMEUNvbW9kbyBDQSBMaW1pdGVkMSUw +IwYDVQQDDBxUcnVzdGVkIENlcnRpZmljYXRlIFNlcnZpY2VzMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEA33FvNlhTWvI2VFeAxHQIIO0Yfyod5jWaHiWsnOWWfnJSoBVC21ndZHoa0Lh7 +3TkVvFVIxO06AOoxEbrycXQaZ7jPM8yoMa+j49d/vzMtTGo87IvDktJTdyR0nAducPy9C1t2ul/y +/9c3S0pgePfw+spwtOpZqqPOSC+pw7ILfhdyFgymBwwbOM/JYrc/oJOlh0Hyt3BAd9i+FHzjqMB6 +juljatEPmsbS9Is6FARW1O24zG71++IsWL1/T2sr92AkWCTOJu80kTrV44HQsvAEAtdbtz6SrGsS +ivnkBbA7kUlcsutT6vifR4buv5XAwAaf0lteERv0xwQ1KdJVXOTt6wIDAQABo4HJMIHGMB0GA1Ud +DgQWBBTFe1i97doladL3WRaoszLAeydb9DAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zCBgwYDVR0fBHwwejA8oDqgOIY2aHR0cDovL2NybC5jb21vZG9jYS5jb20vVHJ1c3RlZENlcnRp +ZmljYXRlU2VydmljZXMuY3JsMDqgOKA2hjRodHRwOi8vY3JsLmNvbW9kby5uZXQvVHJ1c3RlZENl +cnRpZmljYXRlU2VydmljZXMuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQDIk4E7ibSvuIQSTI3S8Ntw +uleGFTQQuS9/HrCoiWChisJ3DFBKmwCL2Iv0QeLQg4pKHBQGsKNoBXAxMKdTmw7pSqBYaWcOrp32 +pSxBvzwGa+RZzG0Q8ZZvH9/0BAKkn0U+yNj6NkZEUD+Cl5EfKNsYEYwq5GWDVxISjBc/lDb+XbDA +BHcTuPQV1T84zJQ6VdCsmPW6AF/ghhmBeC8owH7TzEIK9a5QoNE+xqFx7D+gIIxmOom0jtTYsU0l +R+4viMi14QVFwL4Ucd56/Y57fU0IlqUSc/AtyjcndBInTMu2l+nZrghtWjlA3QVHdWpaIbOjGM9O +9y5Xt5hwXsjEeLBi +-----END CERTIFICATE----- + +QuoVadis Root CA +================ +-----BEGIN CERTIFICATE----- +MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJCTTEZMBcGA1UE +ChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 +eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAz +MTkxODMzMzNaFw0yMTAzMTcxODMzMzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRp +cyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQD +EyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Ypli4kVEAkOPcahdxYTMuk +J0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2DrOpm2RgbaIr1VxqYuvXtdj182d6UajtL +F8HVj71lODqV0D1VNk7feVcxKh7YWWVJWCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeL +YzcS19Dsw3sgQUSj7cugF+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWen +AScOospUxbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCCAk4w +PQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVvdmFkaXNvZmZzaG9y +ZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREwggENMIIBCQYJKwYBBAG+WAABMIH7 +MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNlIG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmlj +YXRlIGJ5IGFueSBwYXJ0eSBhc3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJs +ZSBzdGFuZGFyZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh +Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYIKwYBBQUHAgEW +Fmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3TKbkGGew5Oanwl4Rqy+/fMIGu +BgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rqy+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkw +FwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5MS4wLAYDVQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6 +tlCLMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSkfnIYj9lo +fFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf87C9TqnN7Az10buYWnuul +LsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1RcHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2x +gI4JVrmcGmD+XcHXetwReNDWXcG31a0ymQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi +5upZIof4l/UO/erMkqQWxFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi +5nrQNiOKSnQ2+Q== +-----END CERTIFICATE----- + +QuoVadis Root CA 2 +================== +-----BEGIN CERTIFICATE----- +MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoT +EFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJvb3QgQ0EgMjAeFw0wNjExMjQx +ODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4IC +DwAwggIKAoICAQCaGMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6 +XJxgFyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55JWpzmM+Yk +lvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bBrrcCaoF6qUWD4gXmuVbB +lDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp+ARz8un+XJiM9XOva7R+zdRcAitMOeGy +lZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt +66/3FsvbzSUr5R/7mp/iUcw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1Jdxn +wQ5hYIizPtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og/zOh +D7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UHoycR7hYQe7xFSkyy +BNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuIyV77zGHcizN300QyNQliBJIWENie +J0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1Ud +DgQWBBQahGK8SEwzJQTU7tD2A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGU +a6FJpEcwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT +ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2fBluornFdLwUv +Z+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzng/iN/Ae42l9NLmeyhP3ZRPx3 +UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2BlfF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodm +VjB3pjd4M1IQWK4/YY7yarHvGH5KWWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK ++JDSV6IZUaUtl0HaB0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrW +IozchLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPRTUIZ3Ph1 +WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWDmbA4CD/pXvk1B+TJYm5X +f6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0ZohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II +4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8 +VCLAAVBpQ570su9t+Oza8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u +-----END CERTIFICATE----- + +QuoVadis Root CA 3 +================== +-----BEGIN CERTIFICATE----- +MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoT +EFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJvb3QgQ0EgMzAeFw0wNjExMjQx +OTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4IC +DwAwggIKAoICAQDMV0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNgg +DhoB4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUrH556VOij +KTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd8lyyBTNvijbO0BNO/79K +DDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9CabwvvWhDFlaJKjdhkf2mrk7AyxRllDdLkgbv +BNDInIjbC3uBr7E9KsRlOni27tyAsdLTmZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwp +p5ijJUMv7/FfJuGITfhebtfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8 +nT8KKdjcT5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDtWAEX +MJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZc6tsgLjoC2SToJyM +Gf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A4iLItLRkT9a6fUg+qGkM17uGcclz +uD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYDVR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHT +BgkrBgEEAb5YAAMwgcUwgZMGCCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmlj +YXRlIGNvbnN0aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0 +aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVudC4wLQYIKwYB +BQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2NwczALBgNVHQ8EBAMCAQYwHQYD +VR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4GA1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4 +ywLQoUmkRzBFMQswCQYDVQQGEwJCTTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UE +AxMSUXVvVmFkaXMgUm9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZV +qyM07ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSemd1o417+s +hvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd+LJ2w/w4E6oM3kJpK27z +POuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2 +Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadNt54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp +8kokUvd0/bpO5qgdAm6xDYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBC +bjPsMZ57k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6szHXu +g/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0jWy10QJLZYxkNc91p +vGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeTmJlglFwjz1onl14LBQaTNx47aTbr +qZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK4SVhM7JZG+Ju1zdXtg2pEto= +-----END CERTIFICATE----- + +Security Communication Root CA +============================== +-----BEGIN CERTIFICATE----- +MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP +U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw +HhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP +U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw +8yl89f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJDKaVv0uM +DPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9Ms+k2Y7CI9eNqPPYJayX +5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/NQV3Is00qVUarH9oe4kA92819uZKAnDfd +DJZkndwi92SL32HeFZRSFaB9UslLqCHJxrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2 +JChzAgMBAAGjPzA9MB0GA1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYw +DwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vGkl3g +0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfrUj94nK9NrvjVT8+a +mCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5Bw+SUEmK3TGXX8npN6o7WWWXlDLJ +s58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJUJRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ +6rBK+1YWc26sTfcioU+tHXotRSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAi +FL39vmwLAw== +-----END CERTIFICATE----- + +Sonera Class 2 Root CA +====================== +-----BEGIN CERTIFICATE----- +MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEPMA0GA1UEChMG +U29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAxMDQwNjA3Mjk0MFoXDTIxMDQw +NjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNVBAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJh +IENsYXNzMiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3 +/Ei9vX+ALTU74W+oZ6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybT +dXnt5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s3TmVToMG +f+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2EjvOr7nQKV0ba5cTppCD8P +tOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu8nYybieDwnPz3BjotJPqdURrBGAgcVeH +nfO+oJAjPYok4doh28MCAwEAAaMzMDEwDwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITT +XjwwCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt +0jSv9zilzqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/3DEI +cbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvDFNr450kkkdAdavph +Oe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6Tk6ezAyNlNzZRZxe7EJQY670XcSx +EtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLH +llpwrN9M +-----END CERTIFICATE----- + +Staat der Nederlanden Root CA +============================= +-----BEGIN CERTIFICATE----- +MIIDujCCAqKgAwIBAgIEAJiWijANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJOTDEeMBwGA1UE +ChMVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSYwJAYDVQQDEx1TdGFhdCBkZXIgTmVkZXJsYW5kZW4g +Um9vdCBDQTAeFw0wMjEyMTcwOTIzNDlaFw0xNTEyMTYwOTE1MzhaMFUxCzAJBgNVBAYTAk5MMR4w +HAYDVQQKExVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xJjAkBgNVBAMTHVN0YWF0IGRlciBOZWRlcmxh +bmRlbiBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmNK1URF6gaYUmHFt +vsznExvWJw56s2oYHLZhWtVhCb/ekBPHZ+7d89rFDBKeNVU+LCeIQGv33N0iYfXCxw719tV2U02P +jLwYdjeFnejKScfST5gTCaI+Ioicf9byEGW07l8Y1Rfj+MX94p2i71MOhXeiD+EwR+4A5zN9RGca +C1Hoi6CeUJhoNFIfLm0B8mBF8jHrqTFoKbt6QZ7GGX+UtFE5A3+y3qcym7RHjm+0Sq7lr7HcsBth +vJly3uSJt3omXdozSVtSnA71iq3DuD3oBmrC1SoLbHuEvVYFy4ZlkuxEK7COudxwC0barbxjiDn6 +22r+I/q85Ej0ZytqERAhSQIDAQABo4GRMIGOMAwGA1UdEwQFMAMBAf8wTwYDVR0gBEgwRjBEBgRV +HSAAMDwwOgYIKwYBBQUHAgEWLmh0dHA6Ly93d3cucGtpb3ZlcmhlaWQubmwvcG9saWNpZXMvcm9v +dC1wb2xpY3kwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSofeu8Y6R0E3QA7Jbg0zTBLL9s+DAN +BgkqhkiG9w0BAQUFAAOCAQEABYSHVXQ2YcG70dTGFagTtJ+k/rvuFbQvBgwp8qiSpGEN/KtcCFtR +EytNwiphyPgJWPwtArI5fZlmgb9uXJVFIGzmeafR2Bwp/MIgJ1HI8XxdNGdphREwxgDS1/PTfLbw +MVcoEoJz6TMvplW0C5GUR5z6u3pCMuiufi3IvKwUv9kP2Vv8wfl6leF9fpb8cbDCTMjfRTTJzg3y +nGQI0DvDKcWy7ZAEwbEpkcUwb8GpcjPM/l0WFywRaed+/sWDCN+83CI6LiBpIzlWYGeQiy52OfsR +iJf2fL1LuCAWZwWN4jvBcj+UlTfHXbme2JOhF4//DGYVwSR8MnwDHTuhWEUykw== +-----END CERTIFICATE----- + +TDC Internet Root CA +==================== +-----BEGIN CERTIFICATE----- +MIIEKzCCAxOgAwIBAgIEOsylTDANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJESzEVMBMGA1UE +ChMMVERDIEludGVybmV0MR0wGwYDVQQLExRUREMgSW50ZXJuZXQgUm9vdCBDQTAeFw0wMTA0MDUx +NjMzMTdaFw0yMTA0MDUxNzAzMTdaMEMxCzAJBgNVBAYTAkRLMRUwEwYDVQQKEwxUREMgSW50ZXJu +ZXQxHTAbBgNVBAsTFFREQyBJbnRlcm5ldCBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAxLhAvJHVYx/XmaCLDEAedLdInUaMArLgJF/wGROnN4NrXceO+YQwzho7+vvOi20j +xsNuZp+Jpd/gQlBn+h9sHvTQBda/ytZO5GhgbEaqHF1j4QeGDmUApy6mcca8uYGoOn0a0vnRrEvL +znWv3Hv6gXPU/Lq9QYjUdLP5Xjg6PEOo0pVOd20TDJ2PeAG3WiAfAzc14izbSysseLlJ28TQx5yc +5IogCSEWVmb/Bexb4/DPqyQkXsN/cHoSxNK1EKC2IeGNeGlVRGn1ypYcNIUXJXfi9i8nmHj9eQY6 +otZaQ8H/7AQ77hPv01ha/5Lr7K7a8jcDR0G2l8ktCkEiu7vmpwIDAQABo4IBJTCCASEwEQYJYIZI +AYb4QgEBBAQDAgAHMGUGA1UdHwReMFwwWqBYoFakVDBSMQswCQYDVQQGEwJESzEVMBMGA1UEChMM +VERDIEludGVybmV0MR0wGwYDVQQLExRUREMgSW50ZXJuZXQgUm9vdCBDQTENMAsGA1UEAxMEQ1JM +MTArBgNVHRAEJDAigA8yMDAxMDQwNTE2MzMxN1qBDzIwMjEwNDA1MTcwMzE3WjALBgNVHQ8EBAMC +AQYwHwYDVR0jBBgwFoAUbGQBx/2FbazI2p5QCIUItTxWqFAwHQYDVR0OBBYEFGxkAcf9hW2syNqe +UAiFCLU8VqhQMAwGA1UdEwQFMAMBAf8wHQYJKoZIhvZ9B0EABBAwDhsIVjUuMDo0LjADAgSQMA0G +CSqGSIb3DQEBBQUAA4IBAQBOQ8zR3R0QGwZ/t6T609lN+yOfI1Rb5osvBCiLtSdtiaHsmGnc540m +gwV5dOy0uaOXwTUA/RXaOYE6lTGQ3pfphqiZdwzlWqCE/xIWrG64jcN7ksKsLtB9KOy282A4aW8+ +2ARVPp7MVdK6/rtHBNcK2RYKNCn1WBPVT8+PVkuzHu7TmHnaCB4Mb7j4Fifvwm899qNLPg7kbWzb +O0ESm70NRyN/PErQr8Cv9u8btRXE64PECV90i9kR+8JWsTz4cMo0jUNAE4z9mQNUecYu6oah9jrU +Cbz0vGbMPVjQV0kK7iXiQe4T+Zs4NNEA9X7nlB38aQNiuJkFBT1reBK9sG9l +-----END CERTIFICATE----- + +UTN DATACorp SGC Root CA +======================== +-----BEGIN CERTIFICATE----- +MIIEXjCCA0agAwIBAgIQRL4Mi1AAIbQR0ypoBqmtaTANBgkqhkiG9w0BAQUFADCBkzELMAkGA1UE +BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl +IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xGzAZ +BgNVBAMTElVUTiAtIERBVEFDb3JwIFNHQzAeFw05OTA2MjQxODU3MjFaFw0xOTA2MjQxOTA2MzBa +MIGTMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4w +HAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRy +dXN0LmNvbTEbMBkGA1UEAxMSVVROIC0gREFUQUNvcnAgU0dDMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEA3+5YEKIrblXEjr8uRgnn4AgPLit6E5Qbvfa2gI5lBZMAHryv4g+OGQ0SR+ys +raP6LnD43m77VkIVni5c7yPeIbkFdicZD0/Ww5y0vpQZY/KmEQrrU0icvvIpOxboGqBMpsn0GFlo +wHDyUwDAXlCCpVZvNvlK4ESGoE1O1kduSUrLZ9emxAW5jh70/P/N5zbgnAVssjMiFdC04MwXwLLA +9P4yPykqlXvY8qdOD1R8oQ2AswkDwf9c3V6aPryuvEeKaq5xyh+xKrhfQgUL7EYw0XILyulWbfXv +33i+Ybqypa4ETLyorGkVl73v67SMvzX41MPRKA5cOp9wGDMgd8SirwIDAQABo4GrMIGoMAsGA1Ud +DwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRTMtGzz3/64PGgXYVOktKeRR20TzA9 +BgNVHR8ENjA0MDKgMKAuhixodHRwOi8vY3JsLnVzZXJ0cnVzdC5jb20vVVROLURBVEFDb3JwU0dD +LmNybDAqBgNVHSUEIzAhBggrBgEFBQcDAQYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMA0GCSqGSIb3 +DQEBBQUAA4IBAQAnNZcAiosovcYzMB4p/OL31ZjUQLtgyr+rFywJNn9Q+kHcrpY6CiM+iVnJowft +Gzet/Hy+UUla3joKVAgWRcKZsYfNjGjgaQPpxE6YsjuMFrMOoAyYUJuTqXAJyCyjj98C5OBxOvG0 +I3KgqgHf35g+FFCgMSa9KOlaMCZ1+XtgHI3zzVAmbQQnmt/VDUVHKWss5nbZqSl9Mt3JNjy9rjXx +EZ4du5A/EkdOjtd+D2JzHVImOBwYSf0wdJrE5SIv2MCN7ZF6TACPcn9d2t0bi0Vr591pl6jFVkwP +DPafepE39peC4N1xaf92P2BNPM/3mfnGV/TJVTl4uix5yaaIK/QI +-----END CERTIFICATE----- + +UTN USERFirst Hardware Root CA +============================== +-----BEGIN CERTIFICATE----- +MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCBlzELMAkGA1UE +BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl +IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAd +BgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgx +OTIyWjCBlzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0 +eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVz +ZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdhcmUwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlI +wrthdBKWHTxqctU8EGc6Oe0rE81m65UJM6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFd +tqdt++BxF2uiiPsA3/4aMXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8 +i4fDidNdoI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqIDsjf +Pe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9KsyoUhbAgMBAAGjgbkw +gbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFKFyXyYbKJhDlV0HN9WF +lp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNF +UkZpcnN0LUhhcmR3YXJlLmNybDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUF +BwMGBggrBgEFBQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM +//bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28GpgoiskliCE7/yMgUsogW +XecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gECJChicsZUN/KHAG8HQQZexB2 +lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kn +iCrVWFCVH/A7HFe7fRQ5YiuayZSSKqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67 +nfhmqA== +-----END CERTIFICATE----- + +Camerfirma Chambers of Commerce Root +==================================== +-----BEGIN CERTIFICATE----- +MIIEvTCCA6WgAwIBAgIBADANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJFVTEnMCUGA1UEChMe +QUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1i +ZXJzaWduLm9yZzEiMCAGA1UEAxMZQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdDAeFw0wMzA5MzAx +NjEzNDNaFw0zNzA5MzAxNjEzNDRaMH8xCzAJBgNVBAYTAkVVMScwJQYDVQQKEx5BQyBDYW1lcmZp +cm1hIFNBIENJRiBBODI3NDMyODcxIzAhBgNVBAsTGmh0dHA6Ly93d3cuY2hhbWJlcnNpZ24ub3Jn +MSIwIAYDVQQDExlDaGFtYmVycyBvZiBDb21tZXJjZSBSb290MIIBIDANBgkqhkiG9w0BAQEFAAOC +AQ0AMIIBCAKCAQEAtzZV5aVdGDDg2olUkfzIx1L4L1DZ77F1c2VHfRtbunXF/KGIJPov7coISjlU +xFF6tdpg6jg8gbLL8bvZkSM/SAFwdakFKq0fcfPJVD0dBmpAPrMMhe5cG3nCYsS4No41XQEMIwRH +NaqbYE6gZj3LJgqcQKH0XZi/caulAGgq7YN6D6IUtdQis4CwPAxaUWktWBiP7Zme8a7ileb2R6jW +DA+wWFjbw2Y3npuRVDM30pQcakjJyfKl2qUMI/cjDpwyVV5xnIQFUZot/eZOKjRa3spAN2cMVCFV +d9oKDMyXroDclDZK9D7ONhMeU+SsTjoF7Nuucpw4i9A5O4kKPnf+dQIBA6OCAUQwggFAMBIGA1Ud +EwEB/wQIMAYBAf8CAQwwPAYDVR0fBDUwMzAxoC+gLYYraHR0cDovL2NybC5jaGFtYmVyc2lnbi5v +cmcvY2hhbWJlcnNyb290LmNybDAdBgNVHQ4EFgQU45T1sU3p26EpW1eLTXYGduHRooowDgYDVR0P +AQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzAnBgNVHREEIDAegRxjaGFtYmVyc3Jvb3RAY2hh +bWJlcnNpZ24ub3JnMCcGA1UdEgQgMB6BHGNoYW1iZXJzcm9vdEBjaGFtYmVyc2lnbi5vcmcwWAYD +VR0gBFEwTzBNBgsrBgEEAYGHLgoDATA+MDwGCCsGAQUFBwIBFjBodHRwOi8vY3BzLmNoYW1iZXJz +aWduLm9yZy9jcHMvY2hhbWJlcnNyb290Lmh0bWwwDQYJKoZIhvcNAQEFBQADggEBAAxBl8IahsAi +fJ/7kPMa0QOx7xP5IV8EnNrJpY0nbJaHkb5BkAFyk+cefV/2icZdp0AJPaxJRUXcLo0waLIJuvvD +L8y6C98/d3tGfToSJI6WjzwFCm/SlCgdbQzALogi1djPHRPH8EjX1wWnz8dHnjs8NMiAT9QUu/wN +UPf6s+xCX6ndbcj0dc97wXImsQEcXCz9ek60AcUFV7nnPKoF2YjpB0ZBzu9Bga5Y34OirsrXdx/n +ADydb47kMgkdTXg0eDQ8lJsm7U9xxhl6vSAiSFr+S30Dt+dYvsYyTnQeaN2oaFuzPu5ifdmA6Ap1 +erfutGWaIZDgqtCYvDi1czyL+Nw= +-----END CERTIFICATE----- + +Camerfirma Global Chambersign Root +================================== +-----BEGIN CERTIFICATE----- +MIIExTCCA62gAwIBAgIBADANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJFVTEnMCUGA1UEChMe +QUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1i +ZXJzaWduLm9yZzEgMB4GA1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwHhcNMDMwOTMwMTYx +NDE4WhcNMzcwOTMwMTYxNDE4WjB9MQswCQYDVQQGEwJFVTEnMCUGA1UEChMeQUMgQ2FtZXJmaXJt +YSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEg +MB4GA1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwggEgMA0GCSqGSIb3DQEBAQUAA4IBDQAw +ggEIAoIBAQCicKLQn0KuWxfH2H3PFIP8T8mhtxOviteePgQKkotgVvq0Mi+ITaFgCPS3CU6gSS9J +1tPfnZdan5QEcOw/Wdm3zGaLmFIoCQLfxS+EjXqXd7/sQJ0lcqu1PzKY+7e3/HKE5TWH+VX6ox8O +by4o3Wmg2UIQxvi1RMLQQ3/bvOSiPGpVeAp3qdjqGTK3L/5cPxvusZjsyq16aUXjlg9V9ubtdepl +6DJWk0aJqCWKZQbua795B9Dxt6/tLE2Su8CoX6dnfQTyFQhwrJLWfQTSM/tMtgsL+xrJxI0DqX5c +8lCrEqWhz0hQpe/SyBoT+rB/sYIcd2oPX9wLlY/vQ37mRQklAgEDo4IBUDCCAUwwEgYDVR0TAQH/ +BAgwBgEB/wIBDDA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3JsLmNoYW1iZXJzaWduLm9yZy9j +aGFtYmVyc2lnbnJvb3QuY3JsMB0GA1UdDgQWBBRDnDafsJ4wTcbOX60Qq+UDpfqpFDAOBgNVHQ8B +Af8EBAMCAQYwEQYJYIZIAYb4QgEBBAQDAgAHMCoGA1UdEQQjMCGBH2NoYW1iZXJzaWducm9vdEBj +aGFtYmVyc2lnbi5vcmcwKgYDVR0SBCMwIYEfY2hhbWJlcnNpZ25yb290QGNoYW1iZXJzaWduLm9y +ZzBbBgNVHSAEVDBSMFAGCysGAQQBgYcuCgEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly9jcHMuY2hh +bWJlcnNpZ24ub3JnL2Nwcy9jaGFtYmVyc2lnbnJvb3QuaHRtbDANBgkqhkiG9w0BAQUFAAOCAQEA +PDtwkfkEVCeR4e3t/mh/YV3lQWVPMvEYBZRqHN4fcNs+ezICNLUMbKGKfKX0j//U2K0X1S0E0T9Y +gOKBWYi+wONGkyT+kL0mojAt6JcmVzWJdJYY9hXiryQZVgICsroPFOrGimbBhkVVi76SvpykBMdJ +PJ7oKXqJ1/6v/2j1pReQvayZzKWGVwlnRtvWFsJG8eSpUPWP0ZIV018+xgBJOm5YstHRJw0lyDL4 +IBHNfTIzSJRUTN3cecQwn+uOuFW114hcxWokPbLTBQNRxgfvzBRydD1ucs4YKIxKoHflCStFREes +t2d/AYoFWpO+ocH/+OcOZ6RHSXZddZAa9SaP8A== +-----END CERTIFICATE----- + +NetLock Notary (Class A) Root +============================= +-----BEGIN CERTIFICATE----- +MIIGfTCCBWWgAwIBAgICAQMwDQYJKoZIhvcNAQEEBQAwga8xCzAJBgNVBAYTAkhVMRAwDgYDVQQI +EwdIdW5nYXJ5MREwDwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6 +dG9uc2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9j +ayBLb3pqZWd5em9pIChDbGFzcyBBKSBUYW51c2l0dmFueWtpYWRvMB4XDTk5MDIyNDIzMTQ0N1oX +DTE5MDIxOTIzMTQ0N1owga8xCzAJBgNVBAYTAkhVMRAwDgYDVQQIEwdIdW5nYXJ5MREwDwYDVQQH +EwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6dG9uc2FnaSBLZnQuMRowGAYD +VQQLExFUYW51c2l0dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9jayBLb3pqZWd5em9pIChDbGFz +cyBBKSBUYW51c2l0dmFueWtpYWRvMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvHSM +D7tM9DceqQWC2ObhbHDqeLVu0ThEDaiDzl3S1tWBxdRL51uUcCbbO51qTGL3cfNk1mE7PetzozfZ +z+qMkjvN9wfcZnSX9EUi3fRc4L9t875lM+QVOr/bmJBVOMTtplVjC7B4BPTjbsE/jvxReB+SnoPC +/tmwqcm8WgD/qaiYdPv2LD4VOQ22BFWoDpggQrOxJa1+mm9dU7GrDPzr4PN6s6iz/0b2Y6LYOph7 +tqyF/7AlT3Rj5xMHpQqPBffAZG9+pyeAlt7ULoZgx2srXnN7F+eRP2QM2EsiNCubMvJIH5+hCoR6 +4sKtlz2O1cH5VqNQ6ca0+pii7pXmKgOM3wIDAQABo4ICnzCCApswDgYDVR0PAQH/BAQDAgAGMBIG +A1UdEwEB/wQIMAYBAf8CAQQwEQYJYIZIAYb4QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaC +Ak1GSUdZRUxFTSEgRXplbiB0YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFub3MgU3pv +bGdhbHRhdGFzaSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBhbGFwamFuIGtlc3p1bHQu +IEEgaGl0ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExvY2sgS2Z0LiB0ZXJtZWtmZWxlbG9zc2Vn +LWJpenRvc2l0YXNhIHZlZGkuIEEgZGlnaXRhbGlzIGFsYWlyYXMgZWxmb2dhZGFzYW5hayBmZWx0 +ZXRlbGUgYXogZWxvaXJ0IGVsbGVub3J6ZXNpIGVsamFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFz +IGxlaXJhc2EgbWVndGFsYWxoYXRvIGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGphbiBh +IGh0dHBzOi8vd3d3Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJoZXRvIGF6IGVsbGVu +b3J6ZXNAbmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBPUlRBTlQhIFRoZSBpc3N1YW5jZSBh +bmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGlzIHN1YmplY3QgdG8gdGhlIE5ldExvY2sg +Q1BTIGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFp +bCBhdCBjcHNAbmV0bG9jay5uZXQuMA0GCSqGSIb3DQEBBAUAA4IBAQBIJEb3ulZv+sgoA0BO5TE5 +ayZrU3/b39/zcT0mwBQOxmd7I6gMc90Bu8bKbjc5VdXHjFYgDigKDtIqpLBJUsY4B/6+CgmM0ZjP +ytoUMaFP0jn8DxEsQ8Pdq5PHVT5HfBgaANzze9jyf1JsIPQLX2lS9O74silg6+NJMSEN1rUQQeJB +CWziGppWS3cC9qCbmieH6FUpccKQn0V4GuEVZD3QDtigdp+uxdAu6tYPVuxkf1qbFFgBJ34TUMdr +KuZoPL9coAob4Q566eKAw+np9v1sEZ7Q5SgnK1QyQhSCdeZK8CtmdWOMovsEPoMOmzbwGOQmIMOM +8CgHrTwXZoi1/baI +-----END CERTIFICATE----- + +NetLock Business (Class B) Root +=============================== +-----BEGIN CERTIFICATE----- +MIIFSzCCBLSgAwIBAgIBaTANBgkqhkiG9w0BAQQFADCBmTELMAkGA1UEBhMCSFUxETAPBgNVBAcT +CEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0b25zYWdpIEtmdC4xGjAYBgNV +BAsTEVRhbnVzaXR2YW55a2lhZG9rMTIwMAYDVQQDEylOZXRMb2NrIFV6bGV0aSAoQ2xhc3MgQikg +VGFudXNpdHZhbnlraWFkbzAeFw05OTAyMjUxNDEwMjJaFw0xOTAyMjAxNDEwMjJaMIGZMQswCQYD +VQQGEwJIVTERMA8GA1UEBxMIQnVkYXBlc3QxJzAlBgNVBAoTHk5ldExvY2sgSGFsb3phdGJpenRv +bnNhZ2kgS2Z0LjEaMBgGA1UECxMRVGFudXNpdHZhbnlraWFkb2sxMjAwBgNVBAMTKU5ldExvY2sg +VXpsZXRpIChDbGFzcyBCKSBUYW51c2l0dmFueWtpYWRvMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB +iQKBgQCx6gTsIKAjwo84YM/HRrPVG/77uZmeBNwcf4xKgZjupNTKihe5In+DCnVMm8Bp2GQ5o+2S +o/1bXHQawEfKOml2mrriRBf8TKPV/riXiK+IA4kfpPIEPsgHC+b5sy96YhQJRhTKZPWLgLViqNhr +1nGTLbO/CVRY7QbrqHvcQ7GhaQIDAQABo4ICnzCCApswEgYDVR0TAQH/BAgwBgEB/wIBBDAOBgNV +HQ8BAf8EBAMCAAYwEQYJYIZIAYb4QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaCAk1GSUdZ +RUxFTSEgRXplbiB0YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFub3MgU3pvbGdhbHRh +dGFzaSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBhbGFwamFuIGtlc3p1bHQuIEEgaGl0 +ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExvY2sgS2Z0LiB0ZXJtZWtmZWxlbG9zc2VnLWJpenRv +c2l0YXNhIHZlZGkuIEEgZGlnaXRhbGlzIGFsYWlyYXMgZWxmb2dhZGFzYW5hayBmZWx0ZXRlbGUg +YXogZWxvaXJ0IGVsbGVub3J6ZXNpIGVsamFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFzIGxlaXJh +c2EgbWVndGFsYWxoYXRvIGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGphbiBhIGh0dHBz +Oi8vd3d3Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJoZXRvIGF6IGVsbGVub3J6ZXNA +bmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBPUlRBTlQhIFRoZSBpc3N1YW5jZSBhbmQgdGhl +IHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGlzIHN1YmplY3QgdG8gdGhlIE5ldExvY2sgQ1BTIGF2 +YWlsYWJsZSBhdCBodHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFpbCBhdCBj +cHNAbmV0bG9jay5uZXQuMA0GCSqGSIb3DQEBBAUAA4GBAATbrowXr/gOkDFOzT4JwG06sPgzTEdM +43WIEJessDgVkcYplswhwG08pXTP2IKlOcNl40JwuyKQ433bNXbhoLXan3BukxowOR0w2y7jfLKR +stE3Kfq51hdcR0/jHTjrn9V7lagonhVK0dHQKwCXoOKSNitjrFgBazMpUIaD8QFI +-----END CERTIFICATE----- + +NetLock Express (Class C) Root +============================== +-----BEGIN CERTIFICATE----- +MIIFTzCCBLigAwIBAgIBaDANBgkqhkiG9w0BAQQFADCBmzELMAkGA1UEBhMCSFUxETAPBgNVBAcT +CEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0b25zYWdpIEtmdC4xGjAYBgNV +BAsTEVRhbnVzaXR2YW55a2lhZG9rMTQwMgYDVQQDEytOZXRMb2NrIEV4cHJlc3N6IChDbGFzcyBD +KSBUYW51c2l0dmFueWtpYWRvMB4XDTk5MDIyNTE0MDgxMVoXDTE5MDIyMDE0MDgxMVowgZsxCzAJ +BgNVBAYTAkhVMREwDwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6 +dG9uc2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE0MDIGA1UEAxMrTmV0TG9j +ayBFeHByZXNzeiAoQ2xhc3MgQykgVGFudXNpdHZhbnlraWFkbzCBnzANBgkqhkiG9w0BAQEFAAOB +jQAwgYkCgYEA6+ywbGGKIyWvYCDj2Z/8kwvbXY2wobNAOoLO/XXgeDIDhlqGlZHtU/qdQPzm6N3Z +W3oDvV3zOwzDUXmbrVWg6dADEK8KuhRC2VImESLH0iDMgqSaqf64gXadarfSNnU+sYYJ9m5tfk63 +euyucYT2BDMIJTLrdKwWRMbkQJMdf60CAwEAAaOCAp8wggKbMBIGA1UdEwEB/wQIMAYBAf8CAQQw +DgYDVR0PAQH/BAQDAgAGMBEGCWCGSAGG+EIBAQQEAwIABzCCAmAGCWCGSAGG+EIBDQSCAlEWggJN +RklHWUVMRU0hIEV6ZW4gdGFudXNpdHZhbnkgYSBOZXRMb2NrIEtmdC4gQWx0YWxhbm9zIFN6b2xn +YWx0YXRhc2kgRmVsdGV0ZWxlaWJlbiBsZWlydCBlbGphcmFzb2sgYWxhcGphbiBrZXN6dWx0LiBB +IGhpdGVsZXNpdGVzIGZvbHlhbWF0YXQgYSBOZXRMb2NrIEtmdC4gdGVybWVrZmVsZWxvc3NlZy1i +aXp0b3NpdGFzYSB2ZWRpLiBBIGRpZ2l0YWxpcyBhbGFpcmFzIGVsZm9nYWRhc2FuYWsgZmVsdGV0 +ZWxlIGF6IGVsb2lydCBlbGxlbm9yemVzaSBlbGphcmFzIG1lZ3RldGVsZS4gQXogZWxqYXJhcyBs +ZWlyYXNhIG1lZ3RhbGFsaGF0byBhIE5ldExvY2sgS2Z0LiBJbnRlcm5ldCBob25sYXBqYW4gYSBo +dHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIGNpbWVuIHZhZ3kga2VyaGV0byBheiBlbGxlbm9y +emVzQG5ldGxvY2submV0IGUtbWFpbCBjaW1lbi4gSU1QT1JUQU5UISBUaGUgaXNzdWFuY2UgYW5k +IHRoZSB1c2Ugb2YgdGhpcyBjZXJ0aWZpY2F0ZSBpcyBzdWJqZWN0IHRvIHRoZSBOZXRMb2NrIENQ +UyBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cubmV0bG9jay5uZXQvZG9jcyBvciBieSBlLW1haWwg +YXQgY3BzQG5ldGxvY2submV0LjANBgkqhkiG9w0BAQQFAAOBgQAQrX/XDDKACtiG8XmYta3UzbM2 +xJZIwVzNmtkFLp++UOv0JhQQLdRmF/iewSf98e3ke0ugbLWrmldwpu2gpO0u9f38vf5NNwgMvOOW +gyL1SRt/Syu0VMGAfJlOHdCM7tCs5ZL6dVb+ZKATj7i4Fp1hBWeAyNDYpQcCNJgEjTME1A== +-----END CERTIFICATE----- + +XRamp Global CA Root +==================== +-----BEGIN CERTIFICATE----- +MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCBgjELMAkGA1UE +BhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2Vj +dXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwHhcNMDQxMTAxMTcxNDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMx +HjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkg +U2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3Jp +dHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS638eMpSe2OAtp87ZOqCwu +IR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCPKZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMx +foArtYzAQDsRhtDLooY2YKTVMIJt2W7QDxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FE +zG+gSqmUsE3a56k0enI4qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqs +AxcZZPRaJSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNViPvry +xS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud +EwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASsjVy16bYbMDYGA1UdHwQvMC0wK6Ap +oCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMC +AQEwDQYJKoZIhvcNAQEFBQADggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc +/Kh4ZzXxHfARvbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt +qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLaIR9NmXmd4c8n +nxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSyi6mx5O+aGtA9aZnuqCij4Tyz +8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQO+7ETPTsJ3xCwnR8gooJybQDJbw= +-----END CERTIFICATE----- + +Go Daddy Class 2 CA +=================== +-----BEGIN CERTIFICATE----- +MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMY +VGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkG +A1UEBhMCVVMxITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g +RGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQAD +ggENADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCAPVYYYwhv +2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6wwdhFJ2+qN1j3hybX2C32 +qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXiEqITLdiOr18SPaAIBQi2XKVlOARFmR6j +YGB0xUGlcmIbYsUfb18aQr4CUWWoriMYavx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmY +vLEHZ6IVDd2gWMZEewo+YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0O +BBYEFNLEsNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h/t2o +atTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMu +MTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwG +A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wim +PQoZ+YeAEW5p5JYXMP80kWNyOO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKt +I3lpjbi2Tc7PTMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ +HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mERdEr/VxqHD3VI +Ls9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5CufReYNnyicsbkqWletNw+vHX/b +vZ8= +-----END CERTIFICATE----- + +Starfield Class 2 CA +==================== +-----BEGIN CERTIFICATE----- +MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzElMCMGA1UEChMc +U3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZpZWxkIENsYXNzIDIg +Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQwNjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBo +MQswCQYDVQQGEwJVUzElMCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAG +A1UECxMpU3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqG +SIb3DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf8MOh2tTY +bitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN+lq2cwQlZut3f+dZxkqZ +JRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVm +epsZGD3/cVE8MC5fvj13c7JdBmzDI1aaK4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSN +F4Azbl5KXZnJHoe0nRrA1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HF +MIHCMB0GA1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fRzt0f +hvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNo +bm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBDbGFzcyAyIENlcnRpZmljYXRpb24g +QXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGs +afPzWdqbAYcaT1epoXkJKtv3L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLM +PUxA2IGvd56Deruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl +xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynpVSJYACPq4xJD +KVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEYWQPJIrSPnNVeKtelttQKbfi3 +QBFGmh95DmK/D5fs4C8fF5Q= +-----END CERTIFICATE----- + +StartCom Certification Authority +================================ +-----BEGIN CERTIFICATE----- +MIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMN +U3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmlu +ZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0 +NjM2WhcNMzYwOTE3MTk0NjM2WjB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRk +LjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMg +U3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw +ggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZkpMyONvg45iPwbm2xPN1y +o4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rfOQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/ +Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/CJi/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/d +eMotHweXMAEtcnn6RtYTKqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt +2PZE4XNiHzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMMAv+Z +6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w+2OqqGwaVLRcJXrJ +osmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/ +untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVc +UjyJthkqcwEKDwOzEmDyei+B26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT +37uMdBNSSwIDAQABo4ICUjCCAk4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAa4wHQYDVR0OBBYE +FE4L7xqkQFulF2mHMMo0aEPQQa7yMGQGA1UdHwRdMFswLKAqoCiGJmh0dHA6Ly9jZXJ0LnN0YXJ0 +Y29tLm9yZy9zZnNjYS1jcmwuY3JsMCugKaAnhiVodHRwOi8vY3JsLnN0YXJ0Y29tLm9yZy9zZnNj +YS1jcmwuY3JsMIIBXQYDVR0gBIIBVDCCAVAwggFMBgsrBgEEAYG1NwEBATCCATswLwYIKwYBBQUH +AgEWI2h0dHA6Ly9jZXJ0LnN0YXJ0Y29tLm9yZy9wb2xpY3kucGRmMDUGCCsGAQUFBwIBFilodHRw +Oi8vY2VydC5zdGFydGNvbS5vcmcvaW50ZXJtZWRpYXRlLnBkZjCB0AYIKwYBBQUHAgIwgcMwJxYg +U3RhcnQgQ29tbWVyY2lhbCAoU3RhcnRDb20pIEx0ZC4wAwIBARqBl0xpbWl0ZWQgTGlhYmlsaXR5 +LCByZWFkIHRoZSBzZWN0aW9uICpMZWdhbCBMaW1pdGF0aW9ucyogb2YgdGhlIFN0YXJ0Q29tIENl +cnRpZmljYXRpb24gQXV0aG9yaXR5IFBvbGljeSBhdmFpbGFibGUgYXQgaHR0cDovL2NlcnQuc3Rh +cnRjb20ub3JnL3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilT +dGFydENvbSBGcmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQUFAAOC +AgEAFmyZ9GYMNPXQhV59CuzaEE44HF7fpiUFS5Eyweg78T3dRAlbB0mKKctmArexmvclmAk8jhvh +3TaHK0u7aNM5Zj2gJsfyOZEdUauCe37Vzlrk4gNXcGmXCPleWKYK34wGmkUWFjgKXlf2Ysd6AgXm +vB618p70qSmD+LIU424oh0TDkBreOKk8rENNZEXO3SipXPJzewT4F+irsfMuXGRuczE6Eri8sxHk +fY+BUZo7jYn0TZNmezwD7dOaHZrzZVD1oNB1ny+v8OqCQ5j4aZyJecRDjkZy42Q2Eq/3JR44iZB3 +fsNrarnDy0RLrHiQi+fHLB5LEUTINFInzQpdn4XBidUaePKVEFMy3YCEZnXZtWgo+2EuvoSoOMCZ +EoalHmdkrQYuL6lwhceWD3yJZfWOQ1QOq92lgDmUYMA0yZZwLKMS9R9Ie70cfmu3nZD0Ijuu+Pwq +yvqCUqDvr0tVk+vBtfAii6w0TiYiBKGHLHVKt+V9E9e4DGTANtLJL4YSjCMJwRuCO3NJo2pXh5Tl +1njFmUNj403gdy3hZZlyaQQaRwnmDwFWJPsfvw55qVguucQJAX6Vum0ABj6y6koQOdjQK/W/7HW/ +lwLFCRsI3FU34oH7N4RDYiDK51ZLZer+bMEkkyShNOsF/5oirpt9P/FlUQqmMGqz9IgcgA38coro +g14= +-----END CERTIFICATE----- + +Taiwan GRCA +=========== +-----BEGIN CERTIFICATE----- +MIIFcjCCA1qgAwIBAgIQH51ZWtcvwgZEpYAIaeNe9jANBgkqhkiG9w0BAQUFADA/MQswCQYDVQQG +EwJUVzEwMC4GA1UECgwnR292ZXJubWVudCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4X +DTAyMTIwNTEzMjMzM1oXDTMyMTIwNTEzMjMzM1owPzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dv +dmVybm1lbnQgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQAD +ggIPADCCAgoCggIBAJoluOzMonWoe/fOW1mKydGGEghU7Jzy50b2iPN86aXfTEc2pBsBHH8eV4qN +w8XRIePaJD9IK/ufLqGU5ywck9G/GwGHU5nOp/UKIXZ3/6m3xnOUT0b3EEk3+qhZSV1qgQdW8or5 +BtD3cCJNtLdBuTK4sfCxw5w/cP1T3YGq2GN49thTbqGsaoQkclSGxtKyyhwOeYHWtXBiCAEuTk8O +1RGvqa/lmr/czIdtJuTJV6L7lvnM4T9TjGxMfptTCAtsF/tnyMKtsc2AtJfcdgEWFelq16TheEfO +htX7MfP6Mb40qij7cEwdScevLJ1tZqa2jWR+tSBqnTuBto9AAGdLiYa4zGX+FVPpBMHWXx1E1wov +J5pGfaENda1UhhXcSTvxls4Pm6Dso3pdvtUqdULle96ltqqvKKyskKw4t9VoNSZ63Pc78/1Fm9G7 +Q3hub/FCVGqY8A2tl+lSXunVanLeavcbYBT0peS2cWeqH+riTcFCQP5nRhc4L0c/cZyu5SHKYS1t +B6iEfC3uUSXxY5Ce/eFXiGvviiNtsea9P63RPZYLhY3Naye7twWb7LuRqQoHEgKXTiCQ8P8NHuJB +O9NAOueNXdpm5AKwB1KYXA6OM5zCppX7VRluTI6uSw+9wThNXo+EHWbNxWCWtFJaBYmOlXqYwZE8 +lSOyDvR5tMl8wUohAgMBAAGjajBoMB0GA1UdDgQWBBTMzO/MKWCkO7GStjz6MmKPrCUVOzAMBgNV +HRMEBTADAQH/MDkGBGcqBwAEMTAvMC0CAQAwCQYFKw4DAhoFADAHBgVnKgMAAAQUA5vwIhP/lSg2 +09yewDL7MTqKUWUwDQYJKoZIhvcNAQEFBQADggIBAECASvomyc5eMN1PhnR2WPWus4MzeKR6dBcZ +TulStbngCnRiqmjKeKBMmo4sIy7VahIkv9Ro04rQ2JyftB8M3jh+Vzj8jeJPXgyfqzvS/3WXy6Tj +Zwj/5cAWtUgBfen5Cv8b5Wppv3ghqMKnI6mGq3ZW6A4M9hPdKmaKZEk9GhiHkASfQlK3T8v+R0F2 +Ne//AHY2RTKbxkaFXeIksB7jSJaYV0eUVXoPQbFEJPPB/hprv4j9wabak2BegUqZIJxIZhm1AHlU +D7gsL0u8qV1bYH+Mh6XgUmMqvtg7hUAV/h62ZT/FS9p+tXo1KaMuephgIqP0fSdOLeq0dDzpD6Qz +DxARvBMB1uUO07+1EqLhRSPAzAhuYbeJq4PjJB7mXQfnHyA+z2fI56wwbSdLaG5LKlwCCDTb+Hbk +Z6MmnD+iMsJKxYEYMRBWqoTvLQr/uB930r+lWKBi5NdLkXWNiYCYfm3LU05er/ayl4WXudpVBrkk +7tfGOB5jGxI7leFYrPLfhNVfmS8NVVvmONsuP3LpSIXLuykTjx44VbnzssQwmSNOXfJIoRIM3BKQ +CZBUkQM8R+XVyWXgt0t97EfTsws+rZ7QdAAO671RrcDeLMDDav7v3Aun+kbfYNucpllQdSNpc5Oy ++fwC00fmcc4QAu4njIT/rEUNE1yDMuAlpYYsfPQS +-----END CERTIFICATE----- + +Swisscom Root CA 1 +================== +-----BEGIN CERTIFICATE----- +MIIF2TCCA8GgAwIBAgIQXAuFXAvnWUHfV8w/f52oNjANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQG +EwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0YWwgQ2VydGlmaWNhdGUgU2Vy +dmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3QgQ0EgMTAeFw0wNTA4MTgxMjA2MjBaFw0yNTA4 +MTgyMjA2MjBaMGQxCzAJBgNVBAYTAmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGln +aXRhbCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAxMIIC +IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0LmwqAzZuz8h+BvVM5OAFmUgdbI9m2BtRsiM +MW8Xw/qabFbtPMWRV8PNq5ZJkCoZSx6jbVfd8StiKHVFXqrWW/oLJdihFvkcxC7mlSpnzNApbjyF +NDhhSbEAn9Y6cV9Nbc5fuankiX9qUvrKm/LcqfmdmUc/TilftKaNXXsLmREDA/7n29uj/x2lzZAe +AR81sH8A25Bvxn570e56eqeqDFdvpG3FEzuwpdntMhy0XmeLVNxzh+XTF3xmUHJd1BpYwdnP2IkC +b6dJtDZd0KTeByy2dbcokdaXvij1mB7qWybJvbCXc9qukSbraMH5ORXWZ0sKbU/Lz7DkQnGMU3nn +7uHbHaBuHYwadzVcFh4rUx80i9Fs/PJnB3r1re3WmquhsUvhzDdf/X/NTa64H5xD+SpYVUNFvJbN +cA78yeNmuk6NO4HLFWR7uZToXTNShXEuT46iBhFRyePLoW4xCGQMwtI89Tbo19AOeCMgkckkKmUp +WyL3Ic6DXqTz3kvTaI9GdVyDCW4pa8RwjPWd1yAv/0bSKzjCL3UcPX7ape8eYIVpQtPM+GP+HkM5 +haa2Y0EQs3MevNP6yn0WR+Kn1dCjigoIlmJWbjTb2QK5MHXjBNLnj8KwEUAKrNVxAmKLMb7dxiNY +MUJDLXT5xp6mig/p/r+D5kNXJLrvRjSq1xIBOO0CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYw +HQYDVR0hBBYwFDASBgdghXQBUwABBgdghXQBUwABMBIGA1UdEwEB/wQIMAYBAf8CAQcwHwYDVR0j +BBgwFoAUAyUv3m+CATpcLNwroWm1Z9SM0/0wHQYDVR0OBBYEFAMlL95vggE6XCzcK6FptWfUjNP9 +MA0GCSqGSIb3DQEBBQUAA4ICAQA1EMvspgQNDQ/NwNurqPKIlwzfky9NfEBWMXrrpA9gzXrzvsMn +jgM+pN0S734edAY8PzHyHHuRMSG08NBsl9Tpl7IkVh5WwzW9iAUPWxAaZOHHgjD5Mq2eUCzneAXQ +MbFamIp1TpBcahQq4FJHgmDmHtqBsfsUC1rxn9KVuj7QG9YVHaO+htXbD8BJZLsuUBlL0iT43R4H +VtA4oJVwIHaM190e3p9xxCPvgxNcoyQVTSlAPGrEqdi3pkSlDfTgnXceQHAm/NrZNuR55LU/vJtl +vrsRls/bxig5OgjOR1tTWsWZ/l2p3e9M1MalrQLmjAcSHm8D0W+go/MpvRLHUKKwf4ipmXeascCl +OS5cfGniLLDqN2qk4Vrh9VDlg++luyqI54zb/W1elxmofmZ1a3Hqv7HHb6D0jqTsNFFbjCYDcKF3 +1QESVwA12yPeDooomf2xEG9L/zgtYE4snOtnta1J7ksfrK/7DZBaZmBwXarNeNQk7shBoJMBkpxq +nvy5JMWzFYJ+vq6VK+uxwNrjAWALXmmshFZhvnEX/h0TD/7Gh0Xp/jKgGg0TpJRVcaUWi7rKibCy +x/yP2FS1k2Kdzs9Z+z0YzirLNRWCXf9UIltxUvu3yf5gmwBBZPCqKuy2QkPOiWaByIufOVQDJdMW +NY6E0F/6MBr1mmz0DlP5OlvRHA== +-----END CERTIFICATE----- + +DigiCert Assured ID Root CA +=========================== +-----BEGIN CERTIFICATE----- +MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQw +IgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzEx +MTEwMDAwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL +ExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0Ew +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7cJpSIqvTO +9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYPmDI2dsze3Tyoou9q+yHy +UmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW +/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpy +oeb6pNnVFzF1roV9Iq4/AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whf +GHdPAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRF +66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzANBgkq +hkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRCdWKuh+vy1dneVrOfzM4UKLkNl2Bc +EkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTffwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38Fn +SbNd67IJKusm7Xi+fT8r87cmNW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i +8b5QZ7dsvfPxH2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe ++o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g== +-----END CERTIFICATE----- + +DigiCert Global Root CA +======================= +-----BEGIN CERTIFICATE----- +MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBhMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw +HgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBDQTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAw +MDAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 +dy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsBCSDMAZOn +TjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97nh6Vfe63SKMI2tavegw5 +BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt43C/dxC//AH2hdmoRBBYMql1GNXRor5H +4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7PT19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y +7vrTC0LUq7dBMtoM1O/4gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQAB +o2MwYTAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbRTLtm +8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUwDQYJKoZIhvcNAQEF +BQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/EsrhMAtudXH/vTBH1jLuG2cenTnmCmr +EbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIt +tep3Sp+dWOIrWcBAI+0tKIJFPnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886 +UAb3LujEV0lsYSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk +CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= +-----END CERTIFICATE----- + +DigiCert High Assurance EV Root CA +================================== +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBsMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSsw +KQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5jZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAw +MFoXDTMxMTExMDAwMDAwMFowbDELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ +MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFu +Y2UgRVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm+9S75S0t +Mqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTWPNt0OKRKzE0lgvdKpVMS +OO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEMxChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3 +MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFBIk5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQ +NAQTXKFx01p8VdteZOE3hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUe +h10aUAsgEsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMB +Af8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaAFLE+w2kD+L9HAdSY +JhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3NecnzyIZgYIVyHbIUf4KmeqvxgydkAQ +V8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6zeM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFp +myPInngiK3BD41VHMWEZ71jFhS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkK +mNEVX58Svnw2Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe +vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep+OkuE6N36B9K +-----END CERTIFICATE----- + +Certplus Class 2 Primary CA +=========================== +-----BEGIN CERTIFICATE----- +MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAwPTELMAkGA1UE +BhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFzcyAyIFByaW1hcnkgQ0EwHhcN +OTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2Vy +dHBsdXMxGzAZBgNVBAMTEkNsYXNzIDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBANxQltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR +5aiRVhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyLkcAbmXuZ +Vg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCdEgETjdyAYveVqUSISnFO +YFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yasH7WLO7dDWWuwJKZtkIvEcupdM5i3y95e +e++U8Rs+yskhwcWYAqqi9lt3m/V+llU0HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRME +CDAGAQH/AgEKMAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJ +YIZIAYb4QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMuY29t +L0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/AN9WM2K191EBkOvD +P9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8yfFC82x/xXp8HVGIutIKPidd3i1R +TtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMRFcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+ +7UCmnYR0ObncHoUW2ikbhiMAybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW +//1IMwrh3KWBkJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7 +l7+ijrRU +-----END CERTIFICATE----- + +DST Root CA X3 +============== +-----BEGIN CERTIFICATE----- +MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/MSQwIgYDVQQK +ExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMTDkRTVCBSb290IENBIFgzMB4X +DTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVowPzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1 +cmUgVHJ1c3QgQ28uMRcwFQYDVQQDEw5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmT +rE4Orz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEqOLl5CjH9 +UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9bxiqKqy69cK3FCxolkHRy +xXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40d +utolucbY38EVAjqr2m7xPi71XAicPNaDaeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0T +AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQ +MA0GCSqGSIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69ikug +dB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXrAvHRAosZy5Q6XkjE +GB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZzR8srzJmwN0jP41ZL9c8PDHIyh8bw +RLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubS +fZGL+T0yjWW06XyxV3bqxbYoOb8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ +-----END CERTIFICATE----- + +DST ACES CA X6 +============== +-----BEGIN CERTIFICATE----- +MIIECTCCAvGgAwIBAgIQDV6ZCtadt3js2AdWO4YV2TANBgkqhkiG9w0BAQUFADBbMQswCQYDVQQG +EwJVUzEgMB4GA1UEChMXRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QxETAPBgNVBAsTCERTVCBBQ0VT +MRcwFQYDVQQDEw5EU1QgQUNFUyBDQSBYNjAeFw0wMzExMjAyMTE5NThaFw0xNzExMjAyMTE5NTha +MFsxCzAJBgNVBAYTAlVTMSAwHgYDVQQKExdEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdDERMA8GA1UE +CxMIRFNUIEFDRVMxFzAVBgNVBAMTDkRTVCBBQ0VTIENBIFg2MIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEAuT31LMmU3HWKlV1j6IR3dma5WZFcRt2SPp/5DgO0PWGSvSMmtWPuktKe1jzI +DZBfZIGxqAgNTNj50wUoUrQBJcWVHAx+PhCEdc/BGZFjz+iokYi5Q1K7gLFViYsx+tC3dr5BPTCa +pCIlF3PoHuLTrCq9Wzgh1SpL11V94zpVvddtawJXa+ZHfAjIgrrep4c9oW24MFbCswKBXy314pow +GCi4ZtPLAZZv6opFVdbgnf9nKxcCpk4aahELfrd755jWjHZvwTvbUJN+5dCOHze4vbrGn2zpfDPy +MjwmR/onJALJfh1biEITajV8fTXpLmaRcpPVMibEdPVTo7NdmvYJywIDAQABo4HIMIHFMA8GA1Ud +EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgHGMB8GA1UdEQQYMBaBFHBraS1vcHNAdHJ1c3Rkc3Qu +Y29tMGIGA1UdIARbMFkwVwYKYIZIAWUDAgEBATBJMEcGCCsGAQUFBwIBFjtodHRwOi8vd3d3LnRy +dXN0ZHN0LmNvbS9jZXJ0aWZpY2F0ZXMvcG9saWN5L0FDRVMtaW5kZXguaHRtbDAdBgNVHQ4EFgQU +CXIGThhDD+XWzMNqizF7eI+og7gwDQYJKoZIhvcNAQEFBQADggEBAKPYjtay284F5zLNAdMEA+V2 +5FYrnJmQ6AgwbN99Pe7lv7UkQIRJ4dEorsTCOlMwiPH1d25Ryvr/ma8kXxug/fKshMrfqfBfBC6t +Fr8hlxCBPeP/h40y3JTlR4peahPJlJU90u7INJXQgNStMgiAVDzgvVJT11J8smk/f3rPanTK+gQq +nExaBqXpIK1FZg9p8d2/6eMyi/rgwYZNcjwu2JN4Cir42NInPRmJX1p7ijvMDNpRrscL9yuwNwXs +vFcj4jjSm2jzVhKIT0J8uDHEtdvkyCE06UgRNe76x5JXxZ805Mf29w4LTJxoeHtxMcfrHuBnQfO3 +oKfN5XozNmr6mis= +-----END CERTIFICATE----- + +TURKTRUST Certificate Services Provider Root 1 +============================================== +-----BEGIN CERTIFICATE----- +MIID+zCCAuOgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBtzE/MD0GA1UEAww2VMOcUktUUlVTVCBF +bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGDAJUUjEP +MA0GA1UEBwwGQU5LQVJBMVYwVAYDVQQKDE0oYykgMjAwNSBUw5xSS1RSVVNUIEJpbGdpIMSwbGV0 +acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLjAeFw0wNTA1MTMx +MDI3MTdaFw0xNTAzMjIxMDI3MTdaMIG3MT8wPQYDVQQDDDZUw5xSS1RSVVNUIEVsZWt0cm9uaWsg +U2VydGlmaWthIEhpem1ldCBTYcSfbGF5xLFjxLFzxLExCzAJBgNVBAYMAlRSMQ8wDQYDVQQHDAZB +TktBUkExVjBUBgNVBAoMTShjKSAyMDA1IFTDnFJLVFJVU1QgQmlsZ2kgxLBsZXRpxZ9pbSB2ZSBC +aWxpxZ9pbSBHw7x2ZW5sacSfaSBIaXptZXRsZXJpIEEuxZ4uMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEAylIF1mMD2Bxf3dJ7XfIMYGFbazt0K3gNfUW9InTojAPBxhEqPZW8qZSwu5GX +yGl8hMW0kWxsE2qkVa2kheiVfrMArwDCBRj1cJ02i67L5BuBf5OI+2pVu32Fks66WJ/bMsW9Xe8i +Si9BB35JYbOG7E6mQW6EvAPs9TscyB/C7qju6hJKjRTP8wrgUDn5CDX4EVmt5yLqS8oUBt5CurKZ +8y1UiBAG6uEaPj1nH/vO+3yC6BFdSsG5FOpU2WabfIl9BJpiyelSPJ6c79L1JuTm5Rh8i27fbMx4 +W09ysstcP4wFjdFMjK2Sx+F4f2VsSQZQLJ4ywtdKxnWKWU51b0dewQIDAQABoxAwDjAMBgNVHRME +BTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQAV9VX/N5aAWSGk/KEVTCD21F/aAyT8z5Aa9CEKmu46 +sWrv7/hg0Uw2ZkUd82YCdAR7kjCo3gp2D++Vbr3JN+YaDayJSFvMgzbC9UZcWYJWtNX+I7TYVBxE +q8Sn5RTOPEFhfEPmzcSBCYsk+1Ql1haolgxnB2+zUEfjHCQo3SqYpGH+2+oSN7wBGjSFvW5P55Fy +B0SFHljKVETd96y5y4khctuPwGkplyqjrhgjlxxBKot8KsF8kOipKMDTkcatKIdAaLX/7KfS0zgY +nNN9aV3wxqUeJBujR/xpB2jn5Jq07Q+hh4cCzofSSE7hvP/L8XKSRGQDJereW26fyfJOrN3H +-----END CERTIFICATE----- + +TURKTRUST Certificate Services Provider Root 2 +============================================== +-----BEGIN CERTIFICATE----- +MIIEPDCCAySgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvjE/MD0GA1UEAww2VMOcUktUUlVTVCBF +bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJUUjEP +MA0GA1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUg +QmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLiAoYykgS2FzxLFtIDIwMDUwHhcN +MDUxMTA3MTAwNzU3WhcNMTUwOTE2MTAwNzU3WjCBvjE/MD0GA1UEAww2VMOcUktUUlVTVCBFbGVr +dHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJUUjEPMA0G +A1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmls +acWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLiAoYykgS2FzxLFtIDIwMDUwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCpNn7DkUNMwxmYCMjHWHtPFoylzkkBH3MOrHUTpvqe +LCDe2JAOCtFp0if7qnefJ1Il4std2NiDUBd9irWCPwSOtNXwSadktx4uXyCcUHVPr+G1QRT0mJKI +x+XlZEdhR3n9wFHxwZnn3M5q+6+1ATDcRhzviuyV79z/rxAc653YsKpqhRgNF8k+v/Gb0AmJQv2g +QrSdiVFVKc8bcLyEVK3BEx+Y9C52YItdP5qtygy/p1Zbj3e41Z55SZI/4PGXJHpsmxcPbe9TmJEr +5A++WXkHeLuXlfSfadRYhwqp48y2WBmfJiGxxFmNskF1wK1pzpwACPI2/z7woQ8arBT9pmAPAgMB +AAGjQzBBMB0GA1UdDgQWBBTZN7NOBf3Zz58SFq62iS/rJTqIHDAPBgNVHQ8BAf8EBQMDBwYAMA8G +A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAHJglrfJ3NgpXiOFX7KzLXb7iNcX/ntt +Rbj2hWyfIvwqECLsqrkw9qtY1jkQMZkpAL2JZkH7dN6RwRgLn7Vhy506vvWolKMiVW4XSf/SKfE4 +Jl3vpao6+XF75tpYHdN0wgH6PmlYX63LaL4ULptswLbcoCb6dxriJNoaN+BnrdFzgw2lGh1uEpJ+ +hGIAF728JRhX8tepb1mIvDS3LoV4nZbcFMMsilKbloxSZj2GFotHuFEJjOp9zYhys2AzsfAKRO8P +9Qk3iCQOLGsgOqL6EfJANZxEaGM7rDNvY7wsu/LSy3Z9fYjYHcgFHW68lKlmjHdxx/qR+i9Rnuk5 +UrbnBEI= +-----END CERTIFICATE----- + +SwissSign Gold CA - G2 +====================== +-----BEGIN CERTIFICATE----- +MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAkNIMRUw +EwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2lnbiBHb2xkIENBIC0gRzIwHhcN +MDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBFMQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dp +c3NTaWduIEFHMR8wHQYDVQQDExZTd2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0B +AQEFAAOCAg8AMIICCgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUq +t2/876LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+bbqBHH5C +jCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c6bM8K8vzARO/Ws/BtQpg +vd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqEemA8atufK+ze3gE/bk3lUIbLtK/tREDF +ylqM2tIrfKjuvqblCqoOpd8FUrdVxyJdMmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvR +AiTysybUa9oEVeXBCsdtMDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuend +jIj3o02yMszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69yFGkO +peUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPiaG59je883WX0XaxR +7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxMgI93e2CaHt+28kgeDrpOVG2Y4OGi +GqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUWyV7lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64 +OfPAeGZe6Drn8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov +L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe645R88a7A3hfm +5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczOUYrHUDFu4Up+GC9pWbY9ZIEr +44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOf +Mke6UiI0HTJ6CVanfCU2qT1L2sCCbwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6m +Gu6uLftIdxf+u+yvGPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxp +mo/a77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCChdiDyyJk +vC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid392qgQmwLOM7XdVAyksLf +KzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEppLd6leNcG2mqeSz53OiATIgHQv2ieY2Br +NU0LbbqhPcCT4H8js1WtciVORvnSFu+wZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6Lqj +viOvrv1vA+ACOzB2+httQc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ +-----END CERTIFICATE----- + +SwissSign Silver CA - G2 +======================== +-----BEGIN CERTIFICATE----- +MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCQ0gxFTAT +BgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMB4X +DTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0NlowRzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3 +aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG +9w0BAQEFAAOCAg8AMIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644 +N0MvFz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7brYT7QbNHm ++/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieFnbAVlDLaYQ1HTWBCrpJH +6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH6ATK72oxh9TAtvmUcXtnZLi2kUpCe2Uu +MGoM9ZDulebyzYLs2aFK7PayS+VFheZteJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5h +qAaEuSh6XzjZG6k4sIN/c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5 +FZGkECwJMoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRHHTBs +ROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTfjNFusB3hB48IHpmc +celM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb65i/4z3GcRm25xBWNOHkDRUjvxF3X +CO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQUF6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRB +tjpbO8tFnb0cwpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0 +cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBAHPGgeAn0i0P +4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShpWJHckRE1qTodvBqlYJ7YH39F +kWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L +3XWgwF15kIwb4FDm3jH+mHtwX6WQ2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx +/uNncqCxv1yL5PqZIseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFa +DGi8aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2Xem1ZqSqP +e97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQRdAtq/gsD/KNVV4n+Ssuu +WxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJ +DIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ub +DgEj8Z+7fNzcbBGXJbLytGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u +-----END CERTIFICATE----- + +GeoTrust Primary Certification Authority +======================================== +-----BEGIN CERTIFICATE----- +MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQG +EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMoR2VvVHJ1c3QgUHJpbWFyeSBD +ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjExMjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgx +CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQ +cmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9AWbK7hWN +b6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjAZIVcFU2Ix7e64HXprQU9 +nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE07e9GceBrAqg1cmuXm2bgyxx5X9gaBGge +RwLmnWDiNpcB3841kt++Z8dtd1k7j53WkBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGt +tm/81w7a4DSwDRp35+MImO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJKoZI +hvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ16CePbJC/kRYkRj5K +Ts4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl4b7UVXGYNTq+k+qurUKykG/g/CFN +NWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6KoKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHa +Floxt/m0cYASSJlyc1pZU8FjUjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG +1riR/aYNKxoUAT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk= +-----END CERTIFICATE----- + +thawte Primary Root CA +====================== +-----BEGIN CERTIFICATE----- +MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCBqTELMAkGA1UE +BhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2 +aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv +cml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3 +MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwg +SW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMv +KGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMT +FnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCs +oPD7gFnUnMekz52hWXMJEEUMDSxuaPFsW0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ +1CRfBsDMRJSUjQJib+ta3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGc +q/gcfomk6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6Sk/K +aAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94JNqR32HuHUETVPm4p +afs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYD +VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XPr87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUF +AAOCAQEAeRHAS7ORtvzw6WfUDW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeE +uzLlQRHAd9mzYJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX +xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2/qxAeeWsEG89 +jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/LHbTY5xZ3Y+m4Q6gLkH3LpVH +z7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7jVaMaA== +-----END CERTIFICATE----- + +VeriSign Class 3 Public Primary Certification Authority - G5 +============================================================ +-----BEGIN CERTIFICATE----- +MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE +BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO +ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk +IHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCB +yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2ln +biBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBh +dXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmlt +YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQCvJAgIKXo1nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKz +j/i5Vbext0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIzSdhD +Y2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQGBO+QueQA5N06tRn/ +Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+rCpSx4/VBEnkjWNHiDxpg8v+R70r +fk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/ +BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2Uv +Z2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy +aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKvMzEzMA0GCSqG +SIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzEp6B4Eq1iDkVwZMXnl2YtmAl+ +X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKE +KQsTb47bDN0lAtukixlE0kF6BWlKWE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiC +Km0oHw0LxOXnGiYZ4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vE +ZV8NhnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq +-----END CERTIFICATE----- + +SecureTrust CA +============== +-----BEGIN CERTIFICATE----- +MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBIMQswCQYDVQQG +EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xFzAVBgNVBAMTDlNlY3VyZVRy +dXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIzMTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAe +BgNVBAoTF1NlY3VyZVRydXN0IENvcnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQX +OZEzZum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO0gMdA+9t +DWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIaowW8xQmxSPmjL8xk037uH +GFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b +01k/unK8RCSc43Oz969XL0Imnal0ugBS8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmH +ursCAwEAAaOBnTCBmjATBgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCegJYYj +aHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ +KoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt36Z3q059c4EVlew3KW+JwULKUBRSu +SceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHf +mbx8IVQr5Fiiu1cprp6poxkmD5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZ +nMUFdAvnZyPSCPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR +3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE= +-----END CERTIFICATE----- + +Secure Global CA +================ +-----BEGIN CERTIFICATE----- +MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQG +EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBH +bG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkxMjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEg +MB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwg +Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jx +YDiJiQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa/FHtaMbQ +bqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJjnIFHovdRIWCQtBJwB1g +8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnIHmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYV +HDGA76oYa8J719rO+TMg1fW9ajMtgQT7sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi +0XPnj3pDAgMBAAGjgZ0wgZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud +EwEB/wQFMAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCswKaAn +oCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsGAQQBgjcVAQQDAgEA +MA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0LURYD7xh8yOOvaliTFGCRsoTciE6+ +OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXOH0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cn +CDpOGR86p1hcF895P4vkp9MmI50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/5 +3CYNv6ZHdAbYiNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc +f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW +-----END CERTIFICATE----- + +COMODO Certification Authority +============================== +-----BEGIN CERTIFICATE----- +MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCBgTELMAkGA1UE +BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG +A1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNVBAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1 +dGhvcml0eTAeFw0wNjEyMDEwMDAwMDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEb +MBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFD +T01PRE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3UcEbVASY06m/weaKXTuH ++7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI2GqGd0S7WWaXUF601CxwRM/aN5VCaTww +xHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV +4EajcNxo2f8ESIl33rXp+2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA +1KGzqSX+DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5OnKVI +rLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW/zAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6gPKA6hjhodHRwOi8vY3JsLmNvbW9k +b2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOC +AQEAPpiem/Yb6dc5t3iuHXIYSdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CP +OGEIqB6BCsAvIC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/ +RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4zJVSk/BwJVmc +IGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5ddBA6+C4OmF4O5MBKgxTMVBbkN ++8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IBZQ== +-----END CERTIFICATE----- + +Network Solutions Certificate Authority +======================================= +-----BEGIN CERTIFICATE----- +MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQG +EwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydOZXR3b3Jr +IFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMx +MjM1OTU5WjBiMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu +MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwzc7MEL7xx +jOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPPOCwGJgl6cvf6UDL4wpPT +aaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rlmGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXT +crA/vGp97Eh/jcOrqnErU2lBUzS1sLnFBgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc +/Qzpf14Dl847ABSHJ3A4qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMB +AAGjgZcwgZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwubmV0c29sc3NsLmNv +bS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3JpdHkuY3JsMA0GCSqGSIb3DQEBBQUA +A4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc86fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q +4LqILPxFzBiwmZVRDuwduIj/h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/ +GGUsyfJj4akH/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv +wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHNpGxlaKFJdlxD +ydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey +-----END CERTIFICATE----- + +WellsSecure Public Root Certificate Authority +============================================= +-----BEGIN CERTIFICATE----- +MIIEvTCCA6WgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoM +F1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYw +NAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcN +MDcxMjEzMTcwNzU0WhcNMjIxMjE0MDAwNzU0WjCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoMF1dl +bGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYD +VQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDub7S9eeKPCCGeOARBJe+rWxxTkqxtnt3CxC5FlAM1 +iGd0V+PfjLindo8796jE2yljDpFoNoqXjopxaAkH5OjUDk/41itMpBb570OYj7OeUt9tkTmPOL13 +i0Nj67eT/DBMHAGTthP796EfvyXhdDcsHqRePGj4S78NuR4uNuip5Kf4D8uCdXw1LSLWwr8L87T8 +bJVhHlfXBIEyg1J55oNjz7fLY4sR4r1e6/aN7ZVyKLSsEmLpSjPmgzKuBXWVvYSV2ypcm44uDLiB +K0HmOFafSZtsdvqKXfcBeYF8wYNABf5x/Qw/zE5gCQ5lRxAvAcAFP4/4s0HvWkJ+We/SlwxlAgMB +AAGjggE0MIIBMDAPBgNVHRMBAf8EBTADAQH/MDkGA1UdHwQyMDAwLqAsoCqGKGh0dHA6Ly9jcmwu +cGtpLndlbGxzZmFyZ28uY29tL3dzcHJjYS5jcmwwDgYDVR0PAQH/BAQDAgHGMB0GA1UdDgQWBBQm +lRkQ2eihl5H/3BnZtQQ+0nMKajCBsgYDVR0jBIGqMIGngBQmlRkQ2eihl5H/3BnZtQQ+0nMKaqGB +i6SBiDCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRww +GgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMg +Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHmCAQEwDQYJKoZIhvcNAQEFBQADggEBALkVsUSRzCPI +K0134/iaeycNzXK7mQDKfGYZUMbVmO2rvwNa5U3lHshPcZeG1eMd/ZDJPHV3V3p9+N701NX3leZ0 +bh08rnyd2wIDBSxxSyU+B+NemvVmFymIGjifz6pBA4SXa5M4esowRBskRDPQ5NHcKDj0E0M1NSlj +qHyita04pO2t/caaH/+Xc/77szWnk4bGdpEA5qxRFsQnMlzbc9qlk1eOPm01JghZ1edE13YgY+es +E2fDbbFwRnzVlhE9iW9dqKHrjQrawx0zbKPqZxmamX9LPYNRKh3KL4YMon4QLSvUFpULB6ouFJJJ +tylv2G0xffX8oRAHh84vWdw+WNs= +-----END CERTIFICATE----- + +COMODO ECC Certification Authority +================================== +-----BEGIN CERTIFICATE----- +MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTELMAkGA1UEBhMC +R0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE +ChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwHhcNMDgwMzA2MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0Ix +GzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR +Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRo +b3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSRFtSrYpn1PlILBs5BAH+X +4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0JcfRK9ChQtP6IHG4/bC8vCVlbpVsLM5ni +wz2J+Wos77LTBumjQjBAMB0GA1UdDgQWBBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VG +FAkK+qDmfQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdvGDeA +U/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= +-----END CERTIFICATE----- + +IGC/A +===== +-----BEGIN CERTIFICATE----- +MIIEAjCCAuqgAwIBAgIFORFFEJQwDQYJKoZIhvcNAQEFBQAwgYUxCzAJBgNVBAYTAkZSMQ8wDQYD +VQQIEwZGcmFuY2UxDjAMBgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdQTS9TR0ROMQ4wDAYDVQQLEwVE +Q1NTSTEOMAwGA1UEAxMFSUdDL0ExIzAhBgkqhkiG9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2LmZy +MB4XDTAyMTIxMzE0MjkyM1oXDTIwMTAxNzE0MjkyMlowgYUxCzAJBgNVBAYTAkZSMQ8wDQYDVQQI +EwZGcmFuY2UxDjAMBgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdQTS9TR0ROMQ4wDAYDVQQLEwVEQ1NT +STEOMAwGA1UEAxMFSUdDL0ExIzAhBgkqhkiG9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2LmZyMIIB +IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsh/R0GLFMzvABIaIs9z4iPf930Pfeo2aSVz2 +TqrMHLmh6yeJ8kbpO0px1R2OLc/mratjUMdUC24SyZA2xtgv2pGqaMVy/hcKshd+ebUyiHDKcMCW +So7kVc0dJ5S/znIq7Fz5cyD+vfcuiWe4u0dzEvfRNWk68gq5rv9GQkaiv6GFGvm/5P9JhfejcIYy +HF2fYPepraX/z9E0+X1bF8bc1g4oa8Ld8fUzaJ1O/Id8NhLWo4DoQw1VYZTqZDdH6nfK0LJYBcNd +frGoRpAxVs5wKpayMLh35nnAvSk7/ZR3TL0gzUEl4C7HG7vupARB0l2tEmqKm0f7yd1GQOGdPDPQ +tQIDAQABo3cwdTAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBRjAVBgNVHSAEDjAMMAoGCCqB +egF5AQEBMB0GA1UdDgQWBBSjBS8YYFDCiQrdKyFP/45OqDAxNjAfBgNVHSMEGDAWgBSjBS8YYFDC +iQrdKyFP/45OqDAxNjANBgkqhkiG9w0BAQUFAAOCAQEABdwm2Pp3FURo/C9mOnTgXeQp/wYHE4RK +q89toB9RlPhJy3Q2FLwV3duJL92PoF189RLrn544pEfMs5bZvpwlqwN+Mw+VgQ39FuCIvjfwbF3Q +MZsyK10XZZOYYLxuj7GoPB7ZHPOpJkL5ZB3C55L29B5aqhlSXa/oovdgoPaN8In1buAKBQGVyYsg +Crpa/JosPL3Dt8ldeCUFP1YUmwza+zpI/pdpXsoQhvdOlgQITeywvl3cO45Pwf2aNjSaTFR+FwNI +lQgRHAdvhQh+XU3Endv7rs6y0bO4g2wdsrN58dhwmX7wEwLOXt1R0982gaEbeC9xs/FZTEYYKKuF +0mBWWg== +-----END CERTIFICATE----- + +Security Communication EV RootCA1 +================================= +-----BEGIN CERTIFICATE----- +MIIDfTCCAmWgAwIBAgIBADANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJKUDElMCMGA1UEChMc +U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEqMCgGA1UECxMhU2VjdXJpdHkgQ29tbXVuaWNh +dGlvbiBFViBSb290Q0ExMB4XDTA3MDYwNjAyMTIzMloXDTM3MDYwNjAyMTIzMlowYDELMAkGA1UE +BhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xKjAoBgNVBAsTIVNl +Y3VyaXR5IENvbW11bmljYXRpb24gRVYgUm9vdENBMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBALx/7FebJOD+nLpCeamIivqA4PUHKUPqjgo0No0c+qe1OXj/l3X3L+SqawSERMqm4miO +/VVQYg+kcQ7OBzgtQoVQrTyWb4vVog7P3kmJPdZkLjjlHmy1V4qe70gOzXppFodEtZDkBp2uoQSX +WHnvIEqCa4wiv+wfD+mEce3xDuS4GBPMVjZd0ZoeUWs5bmB2iDQL87PRsJ3KYeJkHcFGB7hj3R4z +ZbOOCVVSPbW9/wfrrWFVGCypaZhKqkDFMxRldAD5kd6vA0jFQFTcD4SQaCDFkpbcLuUCRarAX1T4 +bepJz11sS6/vmsJWXMY1VkJqMF/Cq/biPT+zyRGPMUzXn0kCAwEAAaNCMEAwHQYDVR0OBBYEFDVK +9U2vP9eCOKyrcWUXdYydVZPmMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqG +SIb3DQEBBQUAA4IBAQCoh+ns+EBnXcPBZsdAS5f8hxOQWsTvoMpfi7ent/HWtWS3irO4G8za+6xm +iEHO6Pzk2x6Ipu0nUBsCMCRGef4Eh3CXQHPRwMFXGZpppSeZq51ihPZRwSzJIxXYKLerJRO1RuGG +Av8mjMSIkh1W/hln8lXkgKNrnKt34VFxDSDbEJrbvXZ5B3eZKK2aXtqxT0QsNY6llsf9g/BYxnnW +mHyojf6GPgcWkuF75x3sM3Z+Qi5KhfmRiWiEA4Glm5q+4zfFVKtWOxgtQaQM+ELbmaDgcm+7XeEW +T1MKZPlO9L9OVL14bIjqv5wTJMJwaaJ/D8g8rQjJsJhAoyrniIPtd490 +-----END CERTIFICATE----- + +OISTE WISeKey Global Root GA CA +=============================== +-----BEGIN CERTIFICATE----- +MIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCBijELMAkGA1UE +BhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHlyaWdodCAoYykgMjAwNTEiMCAG +A1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBH +bG9iYWwgUm9vdCBHQSBDQTAeFw0wNTEyMTExNjAzNDRaFw0zNzEyMTExNjA5NTFaMIGKMQswCQYD +VQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEbMBkGA1UECxMSQ29weXJpZ2h0IChjKSAyMDA1MSIw +IAYDVQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5 +IEdsb2JhbCBSb290IEdBIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy0+zAJs9 +Nt350UlqaxBJH+zYK7LG+DKBKUOVTJoZIyEVRd7jyBxRVVuuk+g3/ytr6dTqvirdqFEr12bDYVxg +Asj1znJ7O7jyTmUIms2kahnBAbtzptf2w93NvKSLtZlhuAGio9RN1AU9ka34tAhxZK9w8RxrfvbD +d50kc3vkDIzh2TbhmYsFmQvtRTEJysIA2/dyoJaqlYfQjse2YXMNdmaM3Bu0Y6Kff5MTMPGhJ9vZ +/yxViJGg4E8HsChWjBgbl0SOid3gF27nKu+POQoxhILYQBRJLnpB5Kf+42TMwVlxSywhp1t94B3R +LoGbw9ho972WG6xwsRYUC9tguSYBBQIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUswN+rja8sHnR3JQmthG+IbJphpQwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ +KoZIhvcNAQEFBQADggEBAEuh/wuHbrP5wUOxSPMowB0uyQlB+pQAHKSkq0lPjz0e701vvbyk9vIm +MMkQyh2I+3QZH4VFvbBsUfk2ftv1TDI6QU9bR8/oCy22xBmddMVHxjtqD6wU2zz0c5ypBd8A3HR4 ++vg1YFkCExh8vPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa +hNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZiFj4A4xylNoEY +okxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ/L7fCg0= +-----END CERTIFICATE----- + +Microsec e-Szigno Root CA +========================= +-----BEGIN CERTIFICATE----- +MIIHqDCCBpCgAwIBAgIRAMy4579OKRr9otxmpRwsDxEwDQYJKoZIhvcNAQEFBQAwcjELMAkGA1UE +BhMCSFUxETAPBgNVBAcTCEJ1ZGFwZXN0MRYwFAYDVQQKEw1NaWNyb3NlYyBMdGQuMRQwEgYDVQQL +EwtlLVN6aWdubyBDQTEiMCAGA1UEAxMZTWljcm9zZWMgZS1Temlnbm8gUm9vdCBDQTAeFw0wNTA0 +MDYxMjI4NDRaFw0xNzA0MDYxMjI4NDRaMHIxCzAJBgNVBAYTAkhVMREwDwYDVQQHEwhCdWRhcGVz +dDEWMBQGA1UEChMNTWljcm9zZWMgTHRkLjEUMBIGA1UECxMLZS1Temlnbm8gQ0ExIjAgBgNVBAMT +GU1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQDtyADVgXvNOABHzNuEwSFpLHSQDCHZU4ftPkNEU6+r+ICbPHiN1I2uuO/TEdyB5s87lozWbxXG +d36hL+BfkrYn13aaHUM86tnsL+4582pnS4uCzyL4ZVX+LMsvfUh6PXX5qqAnu3jCBspRwn5mS6/N +oqdNAoI/gqyFxuEPkEeZlApxcpMqyabAvjxWTHOSJ/FrtfX9/DAFYJLG65Z+AZHCabEeHXtTRbjc +QR/Ji3HWVBTji1R4P770Yjtb9aPs1ZJ04nQw7wHb4dSrmZsqa/i9phyGI0Jf7Enemotb9HI6QMVJ +PqW+jqpx62z69Rrkav17fVVA71hu5tnVvCSrwe+3AgMBAAGjggQ3MIIEMzBnBggrBgEFBQcBAQRb +MFkwKAYIKwYBBQUHMAGGHGh0dHBzOi8vcmNhLmUtc3ppZ25vLmh1L29jc3AwLQYIKwYBBQUHMAKG +IWh0dHA6Ly93d3cuZS1zemlnbm8uaHUvUm9vdENBLmNydDAPBgNVHRMBAf8EBTADAQH/MIIBcwYD +VR0gBIIBajCCAWYwggFiBgwrBgEEAYGoGAIBAQEwggFQMCgGCCsGAQUFBwIBFhxodHRwOi8vd3d3 +LmUtc3ppZ25vLmh1L1NaU1ovMIIBIgYIKwYBBQUHAgIwggEUHoIBEABBACAAdABhAG4A+gBzAO0A +dAB2AOEAbgB5ACAA6QByAHQAZQBsAG0AZQB6AOkAcwDpAGgAZQB6ACAA6QBzACAAZQBsAGYAbwBn +AGEAZADhAHMA4QBoAG8AegAgAGEAIABTAHoAbwBsAGcA4QBsAHQAYQB0APMAIABTAHoAbwBsAGcA +4QBsAHQAYQB0AOEAcwBpACAAUwB6AGEAYgDhAGwAeQB6AGEAdABhACAAcwB6AGUAcgBpAG4AdAAg +AGsAZQBsAGwAIABlAGwAagDhAHIAbgBpADoAIABoAHQAdABwADoALwAvAHcAdwB3AC4AZQAtAHMA +egBpAGcAbgBvAC4AaAB1AC8AUwBaAFMAWgAvMIHIBgNVHR8EgcAwgb0wgbqggbeggbSGIWh0dHA6 +Ly93d3cuZS1zemlnbm8uaHUvUm9vdENBLmNybIaBjmxkYXA6Ly9sZGFwLmUtc3ppZ25vLmh1L0NO +PU1pY3Jvc2VjJTIwZS1Temlnbm8lMjBSb290JTIwQ0EsT1U9ZS1Temlnbm8lMjBDQSxPPU1pY3Jv +c2VjJTIwTHRkLixMPUJ1ZGFwZXN0LEM9SFU/Y2VydGlmaWNhdGVSZXZvY2F0aW9uTGlzdDtiaW5h +cnkwDgYDVR0PAQH/BAQDAgEGMIGWBgNVHREEgY4wgYuBEGluZm9AZS1zemlnbm8uaHWkdzB1MSMw +IQYDVQQDDBpNaWNyb3NlYyBlLVN6aWduw7MgUm9vdCBDQTEWMBQGA1UECwwNZS1TemlnbsOzIEhT +WjEWMBQGA1UEChMNTWljcm9zZWMgS2Z0LjERMA8GA1UEBxMIQnVkYXBlc3QxCzAJBgNVBAYTAkhV +MIGsBgNVHSMEgaQwgaGAFMegSXUWYYTbMUuE0vE3QJDvTtz3oXakdDByMQswCQYDVQQGEwJIVTER +MA8GA1UEBxMIQnVkYXBlc3QxFjAUBgNVBAoTDU1pY3Jvc2VjIEx0ZC4xFDASBgNVBAsTC2UtU3pp +Z25vIENBMSIwIAYDVQQDExlNaWNyb3NlYyBlLVN6aWdubyBSb290IENBghEAzLjnv04pGv2i3Gal +HCwPETAdBgNVHQ4EFgQUx6BJdRZhhNsxS4TS8TdAkO9O3PcwDQYJKoZIhvcNAQEFBQADggEBANMT +nGZjWS7KXHAM/IO8VbH0jgdsZifOwTsgqRy7RlRw7lrMoHfqaEQn6/Ip3Xep1fvj1KcExJW4C+FE +aGAHQzAxQmHl7tnlJNUb3+FKG6qfx1/4ehHqE5MAyopYse7tDk2016g2JnzgOsHVV4Lxdbb9iV/a +86g4nzUGCM4ilb7N1fy+W955a9x6qWVmvrElWl/tftOsRm1M9DKHtCAE4Gx4sHfRhUZLphK3dehK +yVZs15KrnfVJONJPU+NVkBHbmJbGSfI+9J8b4PeI3CVimUTYc78/MPMMNz7UwiiAc7EBt51alhQB +S6kRnSlqLtBdgcDPsiBDxwPgN05dCtxZICU= +-----END CERTIFICATE----- + +Certigna +======== +-----BEGIN CERTIFICATE----- +MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNVBAYTAkZSMRIw +EAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4XDTA3MDYyOTE1MTMwNVoXDTI3 +MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwI +Q2VydGlnbmEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7q +XOEm7RFHYeGifBZ4QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyH +GxnygQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbwzBfsV1/p +ogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q130yGLMLLGq/jj8UEYkg +DncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKf +Irjxwo1p3Po6WAbfAgMBAAGjgbwwgbkwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQ +tCRZvgHyUtVF9lo53BEwZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJ +BgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzjAQ/J +SP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG9w0BAQUFAAOCAQEA +hQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8hbV6lUmPOEvjvKtpv6zf+EwLHyzs+ +ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFncfca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1klu +PBS1xp81HlDQwY9qcEQCYsuuHWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY +1gkIl2PlwS6wt0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw +WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg== +-----END CERTIFICATE----- + +AC Ra\xC3\xADz Certic\xC3\xA1mara S.A. +====================================== +-----BEGIN CERTIFICATE----- +MIIGZjCCBE6gAwIBAgIPB35Sk3vgFeNX8GmMy+wMMA0GCSqGSIb3DQEBBQUAMHsxCzAJBgNVBAYT +AkNPMUcwRQYDVQQKDD5Tb2NpZWRhZCBDYW1lcmFsIGRlIENlcnRpZmljYWNpw7NuIERpZ2l0YWwg +LSBDZXJ0aWPDoW1hcmEgUy5BLjEjMCEGA1UEAwwaQUMgUmHDrXogQ2VydGljw6FtYXJhIFMuQS4w +HhcNMDYxMTI3MjA0NjI5WhcNMzAwNDAyMjE0MjAyWjB7MQswCQYDVQQGEwJDTzFHMEUGA1UECgw+ +U29jaWVkYWQgQ2FtZXJhbCBkZSBDZXJ0aWZpY2FjacOzbiBEaWdpdGFsIC0gQ2VydGljw6FtYXJh +IFMuQS4xIzAhBgNVBAMMGkFDIFJhw616IENlcnRpY8OhbWFyYSBTLkEuMIICIjANBgkqhkiG9w0B +AQEFAAOCAg8AMIICCgKCAgEAq2uJo1PMSCMI+8PPUZYILrgIem08kBeGqentLhM0R7LQcNzJPNCN +yu5LF6vQhbCnIwTLqKL85XXbQMpiiY9QngE9JlsYhBzLfDe3fezTf3MZsGqy2IiKLUV0qPezuMDU +2s0iiXRNWhU5cxh0T7XrmafBHoi0wpOQY5fzp6cSsgkiBzPZkc0OnB8OIMfuuzONj8LSWKdf/WU3 +4ojC2I+GdV75LaeHM/J4Ny+LvB2GNzmxlPLYvEqcgxhaBvzz1NS6jBUJJfD5to0EfhcSM2tXSExP +2yYe68yQ54v5aHxwD6Mq0Do43zeX4lvegGHTgNiRg0JaTASJaBE8rF9ogEHMYELODVoqDA+bMMCm +8Ibbq0nXl21Ii/kDwFJnmxL3wvIumGVC2daa49AZMQyth9VXAnow6IYm+48jilSH5L887uvDdUhf +HjlvgWJsxS3EF1QZtzeNnDeRyPYL1epjb4OsOMLzP96a++EjYfDIJss2yKHzMI+ko6Kh3VOz3vCa +Mh+DkXkwwakfU5tTohVTP92dsxA7SH2JD/ztA/X7JWR1DhcZDY8AFmd5ekD8LVkH2ZD6mq093ICK +5lw1omdMEWux+IBkAC1vImHFrEsm5VoQgpukg3s0956JkSCXjrdCx2bD0Omk1vUgjcTDlaxECp1b +czwmPS9KvqfJpxAe+59QafMCAwEAAaOB5jCB4zAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE +AwIBBjAdBgNVHQ4EFgQU0QnQ6dfOeXRU+Tows/RtLAMDG2gwgaAGA1UdIASBmDCBlTCBkgYEVR0g +ADCBiTArBggrBgEFBQcCARYfaHR0cDovL3d3dy5jZXJ0aWNhbWFyYS5jb20vZHBjLzBaBggrBgEF +BQcCAjBOGkxMaW1pdGFjaW9uZXMgZGUgZ2FyYW507WFzIGRlIGVzdGUgY2VydGlmaWNhZG8gc2Ug +cHVlZGVuIGVuY29udHJhciBlbiBsYSBEUEMuMA0GCSqGSIb3DQEBBQUAA4ICAQBclLW4RZFNjmEf +AygPU3zmpFmps4p6xbD/CHwso3EcIRNnoZUSQDWDg4902zNc8El2CoFS3UnUmjIz75uny3XlesuX +EpBcunvFm9+7OSPI/5jOCk0iAUgHforA1SBClETvv3eiiWdIG0ADBaGJ7M9i4z0ldma/Jre7Ir5v +/zlXdLp6yQGVwZVR6Kss+LGGIOk/yzVb0hfpKv6DExdA7ohiZVvVO2Dpezy4ydV/NgIlqmjCMRW3 +MGXrfx1IebHPOeJCgBbT9ZMj/EyXyVo3bHwi2ErN0o42gzmRkBDI8ck1fj+404HGIGQatlDCIaR4 +3NAvO2STdPCWkPHv+wlaNECW8DYSwaN0jJN+Qd53i+yG2dIPPy3RzECiiWZIHiCznCNZc6lEc7wk +eZBWN7PGKX6jD/EpOe9+XCgycDWs2rjIdWb8m0w5R44bb5tNAlQiM+9hup4phO9OSzNHdpdqy35f +/RWmnkJDW2ZaiogN9xa5P1FlK2Zqi9E4UqLWRhH6/JocdJ6PlwsCT2TG9WjTSy3/pDceiz+/RL5h +RqGEPQgnTIEgd4kI6mdAXmwIUV80WoyWaM3X94nCHNMyAK9Sy9NgWyo6R35rMDOhYil/SrnhLecU +Iw4OGEfhefwVVdCx/CVxY3UzHCMrr1zZ7Ud3YA47Dx7SwNxkBYn8eNZcLCZDqQ== +-----END CERTIFICATE----- + +TC TrustCenter Class 2 CA II +============================ +-----BEGIN CERTIFICATE----- +MIIEqjCCA5KgAwIBAgIOLmoAAQACH9dSISwRXDswDQYJKoZIhvcNAQEFBQAwdjELMAkGA1UEBhMC +REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNVBAsTGVRDIFRydXN0Q2VudGVy +IENsYXNzIDIgQ0ExJTAjBgNVBAMTHFRDIFRydXN0Q2VudGVyIENsYXNzIDIgQ0EgSUkwHhcNMDYw +MTEyMTQzODQzWhcNMjUxMjMxMjI1OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1 +c3RDZW50ZXIgR21iSDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQTElMCMGA1UE +AxMcVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBAKuAh5uO8MN8h9foJIIRszzdQ2Lu+MNF2ujhoF/RKrLqk2jftMjWQ+nEdVl//OEd+DFw +IxuInie5e/060smp6RQvkL4DUsFJzfb95AhmC1eKokKguNV/aVyQMrKXDcpK3EY+AlWJU+MaWss2 +xgdW94zPEfRMuzBwBJWl9jmM/XOBCH2JXjIeIqkiRUuwZi4wzJ9l/fzLganx4Duvo4bRierERXlQ +Xa7pIXSSTYtZgo+U4+lK8edJsBTj9WLL1XK9H7nSn6DNqPoByNkN39r8R52zyFTfSUrxIan+GE7u +SNQZu+995OKdy1u2bv/jzVrndIIFuoAlOMvkaZ6vQaoahPUCAwEAAaOCATQwggEwMA8GA1UdEwEB +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTjq1RMgKHbVkO3kUrL84J6E1wIqzCB +7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRydXN0Y2VudGVyLmRlL2NybC92Mi90 +Y19jbGFzc18yX2NhX0lJLmNybIaBn2xkYXA6Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBU +cnVzdENlbnRlciUyMENsYXNzJTIwMiUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21i +SCxPVT1yb290Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u +TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEAjNfffu4bgBCzg/XbEeprS6iSGNn3Bzn1LL4G +dXpoUxUc6krtXvwjshOg0wn/9vYua0Fxec3ibf2uWWuFHbhOIprtZjluS5TmVfwLG4t3wVMTZonZ +KNaL80VKY7f9ewthXbhtvsPcW3nS7Yblok2+XnR8au0WOB9/WIFaGusyiC2y8zl3gK9etmF1Kdsj +TYjKUCjLhdLTEKJZbtOTVAB6okaVhgWcqRmY5TFyDADiZ9lA4CQze28suVyrZZ0srHbqNZn1l7kP +JOzHdiEoZa5X6AeIdUpWoNIFOqTmjZKILPPy4cHGYdtBxceb9w4aUUXCYWvcZCcXjFq32nQozZfk +vQ== +-----END CERTIFICATE----- + +TC TrustCenter Class 3 CA II +============================ +-----BEGIN CERTIFICATE----- +MIIEqjCCA5KgAwIBAgIOSkcAAQAC5aBd1j8AUb8wDQYJKoZIhvcNAQEFBQAwdjELMAkGA1UEBhMC +REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNVBAsTGVRDIFRydXN0Q2VudGVy +IENsYXNzIDMgQ0ExJTAjBgNVBAMTHFRDIFRydXN0Q2VudGVyIENsYXNzIDMgQ0EgSUkwHhcNMDYw +MTEyMTQ0MTU3WhcNMjUxMjMxMjI1OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1 +c3RDZW50ZXIgR21iSDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQTElMCMGA1UE +AxMcVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBALTgu1G7OVyLBMVMeRwjhjEQY0NVJz/GRcekPewJDRoeIMJWHt4bNwcwIi9v8Qbxq63W +yKthoy9DxLCyLfzDlml7forkzMA5EpBCYMnMNWju2l+QVl/NHE1bWEnrDgFPZPosPIlY2C8u4rBo +6SI7dYnWRBpl8huXJh0obazovVkdKyT21oQDZogkAHhg8fir/gKya/si+zXmFtGt9i4S5Po1auUZ +uV3bOx4a+9P/FRQI2AlqukWdFHlgfa9Aigdzs5OW03Q0jTo3Kd5c7PXuLjHCINy+8U9/I1LZW+Jk +2ZyqBwi1Rb3R0DHBq1SfqdLDYmAD8bs5SpJKPQq5ncWg/jcCAwEAAaOCATQwggEwMA8GA1UdEwEB +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTUovyfs8PYA9NXXAek0CSnwPIA1DCB +7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRydXN0Y2VudGVyLmRlL2NybC92Mi90 +Y19jbGFzc18zX2NhX0lJLmNybIaBn2xkYXA6Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBU +cnVzdENlbnRlciUyMENsYXNzJTIwMyUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21i +SCxPVT1yb290Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u +TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEANmDkcPcGIEPZIxpC8vijsrlNirTzwppVMXzE +O2eatN9NDoqTSheLG43KieHPOh6sHfGcMrSOWXaiQYUlN6AT0PV8TtXqluJucsG7Kv5sbviRmEb8 +yRtXW+rIGjs/sFGYPAfaLFkB2otE6OF0/ado3VS6g0bsyEa1+K+XwDsJHI/OcpY9M1ZwvJbL2NV9 +IJqDnxrcOfHFcqMRA/07QlIp2+gB95tejNaNhk4Z+rwcvsUhpYeeeC422wlxo3I0+GzjBgnyXlal +092Y+tTmBvTwtiBjS+opvaqCZh77gaqnN60TGOaSw4HBM7uIHqHn4rS9MWwOUT1v+5ZWgOI2F9Hc +5A== +-----END CERTIFICATE----- + +TC TrustCenter Universal CA I +============================= +-----BEGIN CERTIFICATE----- +MIID3TCCAsWgAwIBAgIOHaIAAQAC7LdggHiNtgYwDQYJKoZIhvcNAQEFBQAweTELMAkGA1UEBhMC +REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxJDAiBgNVBAsTG1RDIFRydXN0Q2VudGVy +IFVuaXZlcnNhbCBDQTEmMCQGA1UEAxMdVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBIEkwHhcN +MDYwMzIyMTU1NDI4WhcNMjUxMjMxMjI1OTU5WjB5MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMg +VHJ1c3RDZW50ZXIgR21iSDEkMCIGA1UECxMbVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBMSYw +JAYDVQQDEx1UQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0EgSTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAKR3I5ZEr5D0MacQ9CaHnPM42Q9e3s9B6DGtxnSRJJZ4Hgmgm5qVSkr1YnwC +qMqs+1oEdjneX/H5s7/zA1hV0qq34wQi0fiU2iIIAI3TfCZdzHd55yx4Oagmcw6iXSVphU9VDprv +xrlE4Vc93x9UIuVvZaozhDrzznq+VZeujRIPFDPiUHDDSYcTvFHe15gSWu86gzOSBnWLknwSaHtw +ag+1m7Z3W0hZneTvWq3zwZ7U10VOylY0Ibw+F1tvdwxIAUMpsN0/lm7mlaoMwCC2/T42J5zjXM9O +gdwZu5GQfezmlwQek8wiSdeXhrYTCjxDI3d+8NzmzSQfO4ObNDqDNOMCAwEAAaNjMGEwHwYDVR0j +BBgwFoAUkqR1LKSevoFE63n8isWVpesQdXMwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AYYwHQYDVR0OBBYEFJKkdSyknr6BROt5/IrFlaXrEHVzMA0GCSqGSIb3DQEBBQUAA4IBAQAo0uCG +1eb4e/CX3CJrO5UUVg8RMKWaTzqwOuAGy2X17caXJ/4l8lfmXpWMPmRgFVp/Lw0BxbFg/UU1z/Cy +vwbZ71q+s2IhtNerNXxTPqYn8aEt2hojnczd7Dwtnic0XQ/CNnm8yUpiLe1r2X1BQ3y2qsrtYbE3 +ghUJGooWMNjsydZHcnhLEEYUjl8Or+zHL6sQ17bxbuyGssLoDZJz3KL0Dzq/YSMQiZxIQG5wALPT +ujdEWBF6AmqI8Dc08BnprNRlc/ZpjGSUOnmFKbAWKwyCPwacx/0QK54PLLae4xW/2TYcuiUaUj0a +7CIMHOCkoj3w6DnPgcB77V0fb8XQC9eY +-----END CERTIFICATE----- + +Deutsche Telekom Root CA 2 +========================== +-----BEGIN CERTIFICATE----- +MIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEcMBoGA1UEChMT +RGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRlcjEjMCEG +A1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENBIDIwHhcNOTkwNzA5MTIxMTAwWhcNMTkwNzA5 +MjM1OTAwWjBxMQswCQYDVQQGEwJERTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0G +A1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBS +b290IENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrC6M14IspFLEUha88EOQ5 +bzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1cOs7TuKhCQN/Po7qCWWqSG6wcmtoI +KyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1MjwrrFDa1sPeg5TKqAyZMg4ISFZbavva4VhY +AUlfckE8FQYBjl2tqriTtM2e66foai1SNNs671x1Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aK +Se5TBY8ZTNXeWHmb0mocQqvF1afPaA+W5OFhmHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTV +jlsB9WoHtxa2bkp/AgMBAAGjQjBAMB0GA1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAPBgNV +HRMECDAGAQH/AgEFMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAlGRZrTlk5ynr +E/5aw4sTV8gEJPB0d8Bg42f76Ymmg7+Wgnxu1MM9756AbrsptJh6sTtU6zkXR34ajgv8HzFZMQSy +zhfzLMdiNlXiItiJVbSYSKpk+tYcNthEeFpaIzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8 +rZ7/gFnkm0W09juwzTkZmDLl6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4G +dyd1Lx+4ivn+xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU +Cm26OWMohpLzGITY+9HPBVZkVw== +-----END CERTIFICATE----- + +ComSign Secured CA +================== +-----BEGIN CERTIFICATE----- +MIIDqzCCApOgAwIBAgIRAMcoRwmzuGxFjB36JPU2TukwDQYJKoZIhvcNAQEFBQAwPDEbMBkGA1UE +AxMSQ29tU2lnbiBTZWN1cmVkIENBMRAwDgYDVQQKEwdDb21TaWduMQswCQYDVQQGEwJJTDAeFw0w +NDAzMjQxMTM3MjBaFw0yOTAzMTYxNTA0NTZaMDwxGzAZBgNVBAMTEkNvbVNpZ24gU2VjdXJlZCBD +QTEQMA4GA1UEChMHQ29tU2lnbjELMAkGA1UEBhMCSUwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQDGtWhfHZQVw6QIVS3joFd67+l0Kru5fFdJGhFeTymHDEjWaueP1H5XJLkGieQcPOqs +49ohgHMhCu95mGwfCP+hUH3ymBvJVG8+pSjsIQQPRbsHPaHA+iqYHU4Gk/v1iDurX8sWv+bznkqH +7Rnqwp9D5PGBpX8QTz7RSmKtUxvLg/8HZaWSLWapW7ha9B20IZFKF3ueMv5WJDmyVIRD9YTC2LxB +kMyd1mja6YJQqTtoz7VdApRgFrFD2UNd3V2Hbuq7s8lr9gOUCXDeFhF6K+h2j0kQmHe5Y1yLM5d1 +9guMsqtb3nQgJT/j8xH5h2iGNXHDHYwt6+UarA9z1YJZQIDTAgMBAAGjgacwgaQwDAYDVR0TBAUw +AwEB/zBEBgNVHR8EPTA7MDmgN6A1hjNodHRwOi8vZmVkaXIuY29tc2lnbi5jby5pbC9jcmwvQ29t +U2lnblNlY3VyZWRDQS5jcmwwDgYDVR0PAQH/BAQDAgGGMB8GA1UdIwQYMBaAFMFL7XC29z58ADsA +j8c+DkWfHl3sMB0GA1UdDgQWBBTBS+1wtvc+fAA7AI/HPg5Fnx5d7DANBgkqhkiG9w0BAQUFAAOC +AQEAFs/ukhNQq3sUnjO2QiBq1BW9Cav8cujvR3qQrFHBZE7piL1DRYHjZiM/EoZNGeQFsOY3wo3a +BijJD4mkU6l1P7CW+6tMM1X5eCZGbxs2mPtCdsGCuY7e+0X5YxtiOzkGynd6qDwJz2w2PQ8KRUtp +FhpFfTMDZflScZAmlaxMDPWLkz/MdXSFmLr/YnpNH4n+rr2UAJm/EaXc4HnFFgt9AmEd6oX5AhVP +51qJThRv4zdLhfXBPGHg/QVBspJ/wx2g0K5SZGBrGMYmnNj1ZOQ2GmKfig8+/21OGVZOIJFsnzQz +OjRXUDpvgV4GxvU+fE6OK85lBi5d0ipTdF7Tbieejw== +-----END CERTIFICATE----- + +Cybertrust Global Root +====================== +-----BEGIN CERTIFICATE----- +MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYGA1UEChMPQ3li +ZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBSb290MB4XDTA2MTIxNTA4 +MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQD +ExZDeWJlcnRydXN0IEdsb2JhbCBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA ++Mi8vRRQZhP/8NN57CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW +0ozSJ8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2yHLtgwEZL +AfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iPt3sMpTjr3kfb1V05/Iin +89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNzFtApD0mpSPCzqrdsxacwOUBdrsTiXSZT +8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAYXSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2 +MDSgMqAwhi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3JsMB8G +A1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUAA4IBAQBW7wojoFRO +lZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMjWqd8BfP9IjsO0QbE2zZMcwSO5bAi +5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUxXOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2 +hO0j9n0Hq0V+09+zv+mKts2oomcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+T +X3EJIrduPuocA06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW +WL1WMRJOEcgh4LMRkWXbtKaIOM5V +-----END CERTIFICATE----- + +ePKI Root Certification Authority +================================= +-----BEGIN CERTIFICATE----- +MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQG +EwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0ZC4xKjAoBgNVBAsMIWVQS0kg +Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMx +MjdaMF4xCzAJBgNVBAYTAlRXMSMwIQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEq +MCgGA1UECwwhZVBLSSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0B +AQEFAAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAHSyZbCUNs +IZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAhijHyl3SJCRImHJ7K2RKi +lTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3XDZoTM1PRYfl61dd4s5oz9wCGzh1NlDiv +qOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX +12ruOzjjK9SXDrkb5wdJfzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0O +WQqraffAsgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uUWH1+ +ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLSnT0IFaUQAS2zMnao +lQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pHdmX2Os+PYhcZewoozRrSgx4hxyy/ +vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJipNiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXi +Zo1jDiVN1Rmy5nk3pyKdVDECAwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/Qkqi +MAwGA1UdEwQFMAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH +ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGBuvl2ICO1J2B0 +1GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6YlPwZpVnPDimZI+ymBV3QGypzq +KOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkPJXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdV +xrsStZf0X4OFunHB2WyBEXYKCrC/gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEP +NXubrjlpC2JgQCA2j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+r +GNm65ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUBo2M3IUxE +xJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS/jQ6fbjpKdx2qcgw+BRx +gMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2zGp1iro2C6pSe3VkQw63d4k3jMdXH7Ojy +sP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTEW9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmOD +BCEIZ43ygknQW/2xzQ+DhNQ+IIX3Sj0rnP0qCglN6oH4EZw= +-----END CERTIFICATE----- + +T\xc3\x9c\x42\xC4\xB0TAK UEKAE K\xC3\xB6k Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1 - S\xC3\xBCr\xC3\xBCm 3 +============================================================================================================================= +-----BEGIN CERTIFICATE----- +MIIFFzCCA/+gAwIBAgIBETANBgkqhkiG9w0BAQUFADCCASsxCzAJBgNVBAYTAlRSMRgwFgYDVQQH +DA9HZWJ6ZSAtIEtvY2FlbGkxRzBFBgNVBAoMPlTDvHJraXllIEJpbGltc2VsIHZlIFRla25vbG9q +aWsgQXJhxZ90xLFybWEgS3VydW11IC0gVMOcQsSwVEFLMUgwRgYDVQQLDD9VbHVzYWwgRWxla3Ry +b25payB2ZSBLcmlwdG9sb2ppIEFyYcWfdMSxcm1hIEVuc3RpdMO8c8O8IC0gVUVLQUUxIzAhBgNV +BAsMGkthbXUgU2VydGlmaWthc3lvbiBNZXJrZXppMUowSAYDVQQDDEFUw5xCxLBUQUsgVUVLQUUg +S8O2ayBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSAtIFPDvHLDvG0gMzAeFw0wNzA4 +MjQxMTM3MDdaFw0xNzA4MjExMTM3MDdaMIIBKzELMAkGA1UEBhMCVFIxGDAWBgNVBAcMD0dlYnpl +IC0gS29jYWVsaTFHMEUGA1UECgw+VMO8cmtpeWUgQmlsaW1zZWwgdmUgVGVrbm9sb2ppayBBcmHF +n3TEsXJtYSBLdXJ1bXUgLSBUw5xCxLBUQUsxSDBGBgNVBAsMP1VsdXNhbCBFbGVrdHJvbmlrIHZl +IEtyaXB0b2xvamkgQXJhxZ90xLFybWEgRW5zdGl0w7xzw7wgLSBVRUtBRTEjMCEGA1UECwwaS2Ft +dSBTZXJ0aWZpa2FzeW9uIE1lcmtlemkxSjBIBgNVBAMMQVTDnELEsFRBSyBVRUtBRSBLw7ZrIFNl +cnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIC0gU8O8csO8bSAzMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAim1L/xCIOsP2fpTo6iBkcK4hgb46ezzb8R1Sf1n68yJMlaCQvEhO +Eav7t7WNeoMojCZG2E6VQIdhn8WebYGHV2yKO7Rm6sxA/OOqbLLLAdsyv9Lrhc+hDVXDWzhXcLh1 +xnnRFDDtG1hba+818qEhTsXOfJlfbLm4IpNQp81McGq+agV/E5wrHur+R84EpW+sky58K5+eeROR +6Oqeyjh1jmKwlZMq5d/pXpduIF9fhHpEORlAHLpVK/swsoHvhOPc7Jg4OQOFCKlUAwUp8MmPi+oL +hmUZEdPpCSPeaJMDyTYcIW7OjGbxmTDY17PDHfiBLqi9ggtm/oLL4eAagsNAgQIDAQABo0IwQDAd +BgNVHQ4EFgQUvYiHyY/2pAoLquvF/pEjnatKijIwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF +MAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAB18+kmPNOm3JpIWmgV050vQbTlswyb2zrgxvMTfvCr4 +N5EY3ATIZJkrGG2AA1nJrvhY0D7twyOfaTyGOBye79oneNGEN3GKPEs5z35FBtYt2IpNeBLWrcLT +y9LQQfMmNkqblWwM7uXRQydmwYj3erMgbOqwaSvHIOgMA8RBBZniP+Rr+KCGgceExh/VS4ESshYh +LBOhgLJeDEoTniDYYkCrkOpkSi+sDQESeUWoL4cZaMjihccwsnX5OD+ywJO0a+IDRM5noN+J1q2M +dqMTw5RhK2vZbMEHCiIHhWyFJEapvj+LeISCfiQMnf2BN+MlqO02TpUsyZyQ2uypQjyttgI= +-----END CERTIFICATE----- + +Buypass Class 2 CA 1 +==================== +-----BEGIN CERTIFICATE----- +MIIDUzCCAjugAwIBAgIBATANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU +QnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3MgQ2xhc3MgMiBDQSAxMB4XDTA2 +MTAxMzEwMjUwOVoXDTE2MTAxMzEwMjUwOVowSzELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBh +c3MgQVMtOTgzMTYzMzI3MR0wGwYDVQQDDBRCdXlwYXNzIENsYXNzIDIgQ0EgMTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAIs8B0XY9t/mx8q6jUPFR42wWsE425KEHK8T1A9vNkYgxC7M +cXA0ojTTNy7Y3Tp3L8DrKehc0rWpkTSHIln+zNvnma+WwajHQN2lFYxuyHyXA8vmIPLXl18xoS83 +0r7uvqmtqEyeIWZDO6i88wmjONVZJMHCR3axiFyCO7srpgTXjAePzdVBHfCuuCkslFJgNJQ72uA4 +0Z0zPhX0kzLFANq1KWYOOngPIVJfAuWSeyXTkh4vFZ2B5J2O6O+JzhRMVB0cgRJNcKi+EAUXfh/R +uFdV7c27UsKwHnjCTTZoy1YmwVLBvXb3WNVyfh9EdrsAiR0WnVE1703CVu9r4Iw7DekCAwEAAaNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUP42aWYv8e3uco684sDntkHGA1sgwDgYDVR0P +AQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQAVGn4TirnoB6NLJzKyQJHyIdFkhb5jatLPgcIV +1Xp+DCmsNx4cfHZSldq1fyOhKXdlyTKdqC5Wq2B2zha0jX94wNWZUYN/Xtm+DKhQ7SLHrQVMdvvt +7h5HZPb3J31cKA9FxVxiXqaakZG3Uxcu3K1gnZZkOb1naLKuBctN518fV4bVIJwo+28TOPX2EZL2 +fZleHwzoq0QkKXJAPTZSr4xYkHPB7GEseaHsh7U/2k3ZIQAw3pDaDtMaSKk+hQsUi4y8QZ5q9w5w +wDX3OaJdZtB7WZ+oRxKaJyOkLY4ng5IgodcVf/EuGO70SH8vf/GhGLWhC5SgYiAynB321O+/TIho +-----END CERTIFICATE----- + +Buypass Class 3 CA 1 +==================== +-----BEGIN CERTIFICATE----- +MIIDUzCCAjugAwIBAgIBAjANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU +QnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3MgQ2xhc3MgMyBDQSAxMB4XDTA1 +MDUwOTE0MTMwM1oXDTE1MDUwOTE0MTMwM1owSzELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBh +c3MgQVMtOTgzMTYzMzI3MR0wGwYDVQQDDBRCdXlwYXNzIENsYXNzIDMgQ0EgMTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAKSO13TZKWTeXx+HgJHqTjnmGcZEC4DVC69TB4sSveZn8AKx +ifZgisRbsELRwCGoy+Gb72RRtqfPFfV0gGgEkKBYouZ0plNTVUhjP5JW3SROjvi6K//zNIqeKNc0 +n6wv1g/xpC+9UrJJhW05NfBEMJNGJPO251P7vGGvqaMU+8IXF4Rs4HyI+MkcVyzwPX6UvCWThOia +AJpFBUJXgPROztmuOfbIUxAMZTpHe2DC1vqRycZxbL2RhzyRhkmr8w+gbCZ2Xhysm3HljbybIR6c +1jh+JIAVMYKWsUnTYjdbiAwKYjT+p0h+mbEwi5A3lRyoH6UsjfRVyNvdWQrCrXig9IsCAwEAAaNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUOBTmyPCppAP0Tj4io1vy1uCtQHQwDgYDVR0P +AQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQABZ6OMySU9E2NdFm/soT4JXJEVKirZgCFPBdy7 +pYmrEzMqnji3jG8CcmPHc3ceCQa6Oyh7pEfJYWsICCD8igWKH7y6xsL+z27sEzNxZy5p+qksP2bA +EllNC1QCkoS72xLvg3BweMhT+t/Gxv/ciC8HwEmdMldg0/L2mSlf56oBzKwzqBwKu5HEA6BvtjT5 +htOzdlSY9EqBs1OdTUDs5XcTRa9bqh/YL0yCe/4qxFi7T/ye/QNlGioOw6UgFpRreaaiErS7GqQj +el/wroQk5PMr+4okoyeYZdowdXb8GZHo2+ubPzK/QJcHJrrM85SFSnonk8+QQtS4Wxam58tAA915 +-----END CERTIFICATE----- + +EBG Elektronik Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1 +========================================================================== +-----BEGIN CERTIFICATE----- +MIIF5zCCA8+gAwIBAgIITK9zQhyOdAIwDQYJKoZIhvcNAQEFBQAwgYAxODA2BgNVBAMML0VCRyBF +bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMTcwNQYDVQQKDC5FQkcg +QmlsacWfaW0gVGVrbm9sb2ppbGVyaSB2ZSBIaXptZXRsZXJpIEEuxZ4uMQswCQYDVQQGEwJUUjAe +Fw0wNjA4MTcwMDIxMDlaFw0xNjA4MTQwMDMxMDlaMIGAMTgwNgYDVQQDDC9FQkcgRWxla3Ryb25p +ayBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsTE3MDUGA1UECgwuRUJHIEJpbGnFn2lt +IFRla25vbG9qaWxlcmkgdmUgSGl6bWV0bGVyaSBBLsWeLjELMAkGA1UEBhMCVFIwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQDuoIRh0DpqZhAy2DE4f6en5f2h4fuXd7hxlugTlkaDT7by +X3JWbhNgpQGR4lvFzVcfd2NR/y8927k/qqk153nQ9dAktiHq6yOU/im/+4mRDGSaBUorzAzu8T2b +gmmkTPiab+ci2hC6X5L8GCcKqKpE+i4stPtGmggDg3KriORqcsnlZR9uKg+ds+g75AxuetpX/dfr +eYteIAbTdgtsApWjluTLdlHRKJ2hGvxEok3MenaoDT2/F08iiFD9rrbskFBKW5+VQarKD7JK/oCZ +TqNGFav4c0JqwmZ2sQomFd2TkuzbqV9UIlKRcF0T6kjsbgNs2d1s/OsNA/+mgxKb8amTD8UmTDGy +Y5lhcucqZJnSuOl14nypqZoaqsNW2xCaPINStnuWt6yHd6i58mcLlEOzrz5z+kI2sSXFCjEmN1Zn +uqMLfdb3ic1nobc6HmZP9qBVFCVMLDMNpkGMvQQxahByCp0OLna9XvNRiYuoP1Vzv9s6xiQFlpJI +qkuNKgPlV5EQ9GooFW5Hd4RcUXSfGenmHmMWOeMRFeNYGkS9y8RsZteEBt8w9DeiQyJ50hBs37vm +ExH8nYQKE3vwO9D8owrXieqWfo1IhR5kX9tUoqzVegJ5a9KK8GfaZXINFHDk6Y54jzJ0fFfy1tb0 +Nokb+Clsi7n2l9GkLqq+CxnCRelwXQIDAJ3Zo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB +/wQEAwIBBjAdBgNVHQ4EFgQU587GT/wWZ5b6SqMHwQSny2re2kcwHwYDVR0jBBgwFoAU587GT/wW +Z5b6SqMHwQSny2re2kcwDQYJKoZIhvcNAQEFBQADggIBAJuYml2+8ygjdsZs93/mQJ7ANtyVDR2t +FcU22NU57/IeIl6zgrRdu0waypIN30ckHrMk2pGI6YNw3ZPX6bqz3xZaPt7gyPvT/Wwp+BVGoGgm +zJNSroIBk5DKd8pNSe/iWtkqvTDOTLKBtjDOWU/aWR1qeqRFsIImgYZ29fUQALjuswnoT4cCB64k +XPBfrAowzIpAoHMEwfuJJPaaHFy3PApnNgUIMbOv2AFoKuB4j3TeuFGkjGwgPaL7s9QJ/XvCgKqT +bCmYIai7FvOpEl90tYeY8pUm3zTvilORiF0alKM/fCL414i6poyWqD1SNGKfAB5UVUJnxk1Gj7sU +RT0KlhaOEKGXmdXTMIXM3rRyt7yKPBgpaP3ccQfuJDlq+u2lrDgv+R4QDgZxGhBM/nV+/x5XOULK +1+EVoVZVWRvRo68R2E7DpSvvkL/A7IITW43WciyTTo9qKd+FPNMN4KIYEsxVL0e3p5sC/kH2iExt +2qkBR4NkJ2IQgtYSe14DHzSpyZH+r11thie3I6p1GMog57AP14kOpmciY/SDQSsGS7tY1dHXt7kQ +Y9iJSrSq3RZj9W6+YKH47ejWkE8axsWgKdOnIaj1Wjz3x0miIZpKlVIglnKaZsv30oZDfCK+lvm9 +AahH3eU7QPl1K5srRmSGjR70j/sHd9DqSaIcjVIUpgqT +-----END CERTIFICATE----- + +certSIGN ROOT CA +================ +-----BEGIN CERTIFICATE----- +MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYTAlJPMREwDwYD +VQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTAeFw0wNjA3MDQxNzIwMDRa +Fw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UE +CxMQY2VydFNJR04gUk9PVCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7I +JUqOtdu0KBuqV5Do0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHH +rfAQUySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5dRdY4zTW2 +ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQOA7+j0xbm0bqQfWwCHTD +0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwvJoIQ4uNllAoEwF73XVv4EOLQunpL+943 +AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B +Af8EBAMCAcYwHQYDVR0OBBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IB +AQA+0hyJLjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecYMnQ8 +SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ44gx+FkagQnIl6Z0 +x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6IJd1hJyMctTEHBDa0GpC9oHRxUIlt +vBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNwi/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7Nz +TogVZ96edhBiIL5VaZVDADlN9u6wWk5JRFRYX0KD +-----END CERTIFICATE----- + +CNNIC ROOT +========== +-----BEGIN CERTIFICATE----- +MIIDVTCCAj2gAwIBAgIESTMAATANBgkqhkiG9w0BAQUFADAyMQswCQYDVQQGEwJDTjEOMAwGA1UE +ChMFQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1QwHhcNMDcwNDE2MDcwOTE0WhcNMjcwNDE2MDcw +OTE0WjAyMQswCQYDVQQGEwJDTjEOMAwGA1UEChMFQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1Qw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDTNfc/c3et6FtzF8LRb+1VvG7q6KR5smzD +o+/hn7E7SIX1mlwhIhAsxYLO2uOabjfhhyzcuQxauohV3/2q2x8x6gHx3zkBwRP9SFIhxFXf2tiz +VHa6dLG3fdfA6PZZxU3Iva0fFNrfWEQlMhkqx35+jq44sDB7R3IJMfAw28Mbdim7aXZOV/kbZKKT +VrdvmW7bCgScEeOAH8tjlBAKqeFkgjH5jCftppkA9nCTGPihNIaj3XrCGHn2emU1z5DrvTOTn1Or +czvmmzQgLx3vqR1jGqCA2wMv+SYahtKNu6m+UjqHZ0gNv7Sg2Ca+I19zN38m5pIEo3/PIKe38zrK +y5nLAgMBAAGjczBxMBEGCWCGSAGG+EIBAQQEAwIABzAfBgNVHSMEGDAWgBRl8jGtKvf33VKWCscC +wQ7vptU7ETAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIB/jAdBgNVHQ4EFgQUZfIxrSr3991S +lgrHAsEO76bVOxEwDQYJKoZIhvcNAQEFBQADggEBAEs17szkrr/Dbq2flTtLP1se31cpolnKOOK5 +Gv+e5m4y3R6u6jW39ZORTtpC4cMXYFDy0VwmuYK36m3knITnA3kXr5g9lNvHugDnuL8BV8F3RTIM +O/G0HAiw/VGgod2aHRM2mm23xzy54cXZF/qD1T0VoDy7HgviyJA/qIYM/PmLXoXLT1tLYhFHxUV8 +BS9BsZ4QaRuZluBVeftOhpm4lNqGOGqTo+fLbuXf6iFViZx9fX+Y9QCJ7uOEwFyWtcVG6kbghVW2 +G8kS1sHNzYDzAgE8yGnLRUhj2JTQ7IUOO04RZfSCjKY9ri4ilAnIXOo8gV0WKgOXFlUJ24pBgp5m +mxE= +-----END CERTIFICATE----- + +ApplicationCA - Japanese Government +=================================== +-----BEGIN CERTIFICATE----- +MIIDoDCCAoigAwIBAgIBMTANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJKUDEcMBoGA1UEChMT +SmFwYW5lc2UgR292ZXJubWVudDEWMBQGA1UECxMNQXBwbGljYXRpb25DQTAeFw0wNzEyMTIxNTAw +MDBaFw0xNzEyMTIxNTAwMDBaMEMxCzAJBgNVBAYTAkpQMRwwGgYDVQQKExNKYXBhbmVzZSBHb3Zl +cm5tZW50MRYwFAYDVQQLEw1BcHBsaWNhdGlvbkNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAp23gdE6Hj6UG3mii24aZS2QNcfAKBZuOquHMLtJqO8F6tJdhjYq+xpqcBrSGUeQ3DnR4 +fl+Kf5Sk10cI/VBaVuRorChzoHvpfxiSQE8tnfWuREhzNgaeZCw7NCPbXCbkcXmP1G55IrmTwcrN +wVbtiGrXoDkhBFcsovW8R0FPXjQilbUfKW1eSvNNcr5BViCH/OlQR9cwFO5cjFW6WY2H/CPek9AE +jP3vbb3QesmlOmpyM8ZKDQUXKi17safY1vC+9D/qDihtQWEjdnjDuGWk81quzMKq2edY3rZ+nYVu +nyoKb58DKTCXKB28t89UKU5RMfkntigm/qJj5kEW8DOYRwIDAQABo4GeMIGbMB0GA1UdDgQWBBRU +WssmP3HMlEYNllPqa0jQk/5CdTAOBgNVHQ8BAf8EBAMCAQYwWQYDVR0RBFIwUKROMEwxCzAJBgNV +BAYTAkpQMRgwFgYDVQQKDA/ml6XmnKzlm73mlL/lupwxIzAhBgNVBAsMGuOCouODl+ODquOCseOD +vOOCt+ODp+ODs0NBMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADlqRHZ3ODrs +o2dGD/mLBqj7apAxzn7s2tGJfHrrLgy9mTLnsCTWw//1sogJhyzjVOGjprIIC8CFqMjSnHH2HZ9g +/DgzE+Ge3Atf2hZQKXsvcJEPmbo0NI2VdMV+eKlmXb3KIXdCEKxmJj3ekav9FfBv7WxfEPjzFvYD +io+nEhEMy/0/ecGc/WLuo89UDNErXxc+4z6/wCs+CZv+iKZ+tJIX/COUgb1up8WMwusRRdv4QcmW +dupwX3kSa+SjB1oF7ydJzyGfikwJcGapJsErEU4z0g781mzSDjJkaP+tBXhfAx2o45CsJOAPQKdL +rosot4LKGAfmt1t06SAZf7IbiVQ= +-----END CERTIFICATE----- + +GeoTrust Primary Certification Authority - G3 +============================================= +-----BEGIN CERTIFICATE----- +MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UE +BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA4IEdlb1RydXN0 +IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFy +eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIz +NTk1OVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAo +YykgMjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMT +LUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz+uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5j +K/BGvESyiaHAKAxJcCGVn2TAppMSAmUmhsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdE +c5IiaacDiGydY8hS2pgn5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3C +IShwiP/WJmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exALDmKu +dlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZChuOl1UcCAwEAAaNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMR5yo6hTgMdHNxr +2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IBAQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9 +cr5HqQ6XErhK8WTTOd8lNNTBzU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbE +Ap7aDHdlDkQNkv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD +AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUHSJsMC8tJP33s +t/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2Gspki4cErx5z481+oghLrGREt +-----END CERTIFICATE----- + +thawte Primary Root CA - G2 +=========================== +-----BEGIN CERTIFICATE----- +MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDELMAkGA1UEBhMC +VVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMpIDIwMDcgdGhhd3RlLCBJbmMu +IC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3Qg +Q0EgLSBHMjAeFw0wNzExMDUwMDAwMDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEV +MBMGA1UEChMMdGhhd3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBG +b3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAt +IEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/BebfowJPDQfGAFG6DAJS +LSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6papu+7qzcMBniKI11KOasf2twu8x+qi5 +8/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU +mtgAMADna3+FGO6Lts6KDPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUN +G4k8VIZ3KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41oxXZ3K +rr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg== +-----END CERTIFICATE----- + +thawte Primary Root CA - G3 +=========================== +-----BEGIN CERTIFICATE----- +MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCBrjELMAkGA1UE +BhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2 +aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv +cml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0w +ODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh +d3RlLCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9uMTgwNgYD +VQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIG +A1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAsr8nLPvb2FvdeHsbnndmgcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2At +P0LMqmsywCPLLEHd5N/8YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC ++BsUa0Lfb1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS99irY +7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2SzhkGcuYMXDhpxwTW +vGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUkOQIDAQABo0IwQDAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJ +KoZIhvcNAQELBQADggEBABpA2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweK +A3rD6z8KLFIWoCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu +t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7cKUGRIjxpp7sC +8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fMm7v/OeZWYdMKp8RcTGB7BXcm +er/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZuMdRAGmI0Nj81Aa6sY6A= +-----END CERTIFICATE----- + +GeoTrust Primary Certification Authority - G2 +============================================= +-----BEGIN CERTIFICATE----- +MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA3IEdlb1RydXN0IElu +Yy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBD +ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1 +OVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg +MjAwNyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMTLUdl +b1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjB2MBAGByqGSM49AgEG +BSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcLSo17VDs6bl8VAsBQps8lL33KSLjHUGMc +KiEIfJo22Av+0SbFWDEwKCXzXV2juLaltJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYD +VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+ +EVXVMAoGCCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGTqQ7m +ndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBuczrD6ogRLQy7rQkgu2 +npaqBA+K +-----END CERTIFICATE----- + +VeriSign Universal Root Certification Authority +=============================================== +-----BEGIN CERTIFICATE----- +MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCBvTELMAkGA1UE +BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO +ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk +IHVzZSBvbmx5MTgwNgYDVQQDEy9WZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9u +IEF1dGhvcml0eTAeFw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJV +UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv +cmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl +IG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj +1mCOkdeQmIN65lgZOIzF9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGP +MiJhgsWHH26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+HLL72 +9fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN/BMReYTtXlT2NJ8I +AfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPTrJ9VAMf2CGqUuV/c4DPxhGD5WycR +tPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0G +CCsGAQUFBwEMBGEwX6FdoFswWTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2O +a8PPgGrUSBgsexkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud +DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4sAPmLGd75JR3 +Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+seQxIcaBlVZaDrHC1LGmWazx +Y8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTx +P/jgdFcrGJ2BtMQo2pSXpXDrrB2+BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+P +wGZsY6rp2aQW9IHRlRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4 +mJO37M2CYfE45k+XmCpajQ== +-----END CERTIFICATE----- + +VeriSign Class 3 Public Primary Certification Authority - G4 +============================================================ +-----BEGIN CERTIFICATE----- +MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjELMAkGA1UEBhMC +VVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3 +b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVz +ZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjEL +MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBU +cnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRo +b3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5 +IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8 +Utpkmw4tXNherJI9/gHmGUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGz +rl0Bp3vefLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEw +HzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVyaXNpZ24u +Y29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMWkf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMD +A2gAMGUCMGYhDBgmYFo4e1ZC4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIx +AJw9SDkjOVgaFRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA== +-----END CERTIFICATE----- + +NetLock Arany (Class Gold) Főtanúsítvány +============================================ +-----BEGIN CERTIFICATE----- +MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQGEwJIVTERMA8G +A1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3MDUGA1UECwwuVGFuw7pzw610 +dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBB +cmFueSAoQ2xhc3MgR29sZCkgRsWRdGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgx +MjA2MTUwODIxWjCBpzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxO +ZXRMb2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlmaWNhdGlv +biBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNzIEdvbGQpIEbFkXRhbsO6 +c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxCRec75LbRTDofTjl5Bu +0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrTlF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw +/HpYzY6b7cNGbIRwXdrzAZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAk +H3B5r9s5VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRGILdw +fzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2BJtr+UBdADTHLpl1 +neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAGAQH/AgEEMA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2MU9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwW +qZw8UQCgwBEIBaeZ5m8BiFRhbvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTta +YtOUZcTh5m2C+C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC +bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2FuLjbvrW5Kfna +NwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2XjG4Kvte9nHfRCaexOYNkbQu +dZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= +-----END CERTIFICATE----- + +Staat der Nederlanden Root CA - G2 +================================== +-----BEGIN CERTIFICATE----- +MIIFyjCCA7KgAwIBAgIEAJiWjDANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJOTDEeMBwGA1UE +CgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFhdCBkZXIgTmVkZXJsYW5kZW4g +Um9vdCBDQSAtIEcyMB4XDTA4MDMyNjExMTgxN1oXDTIwMDMyNTExMDMxMFowWjELMAkGA1UEBhMC +TkwxHjAcBgNVBAoMFVN0YWF0IGRlciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5l +ZGVybGFuZGVuIFJvb3QgQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMVZ +5291qj5LnLW4rJ4L5PnZyqtdj7U5EILXr1HgO+EASGrP2uEGQxGZqhQlEq0i6ABtQ8SpuOUfiUtn +vWFI7/3S4GCI5bkYYCjDdyutsDeqN95kWSpGV+RLufg3fNU254DBtvPUZ5uW6M7XxgpT0GtJlvOj +CwV3SPcl5XCsMBQgJeN/dVrlSPhOewMHBPqCYYdu8DvEpMfQ9XQ+pV0aCPKbJdL2rAQmPlU6Yiil +e7Iwr/g3wtG61jj99O9JMDeZJiFIhQGp5Rbn3JBV3w/oOM2ZNyFPXfUib2rFEhZgF1XyZWampzCR +OME4HYYEhLoaJXhena/MUGDWE4dS7WMfbWV9whUYdMrhfmQpjHLYFhN9C0lK8SgbIHRrxT3dsKpI +CT0ugpTNGmXZK4iambwYfp/ufWZ8Pr2UuIHOzZgweMFvZ9C+X+Bo7d7iscksWXiSqt8rYGPy5V65 +48r6f1CGPqI0GAwJaCgRHOThuVw+R7oyPxjMW4T182t0xHJ04eOLoEq9jWYv6q012iDTiIJh8BIi +trzQ1aTsr1SIJSQ8p22xcik/Plemf1WvbibG/ufMQFxRRIEKeN5KzlW/HdXZt1bv8Hb/C3m1r737 +qWmRRpdogBQ2HbN/uymYNqUg+oJgYjOk7Na6B6duxc8UpufWkjTYgfX8HV2qXB72o007uPc5AgMB +AAGjgZcwgZQwDwYDVR0TAQH/BAUwAwEB/zBSBgNVHSAESzBJMEcGBFUdIAAwPzA9BggrBgEFBQcC +ARYxaHR0cDovL3d3dy5wa2lvdmVyaGVpZC5ubC9wb2xpY2llcy9yb290LXBvbGljeS1HMjAOBgNV +HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJFoMocVHYnitfGsNig0jQt8YojrMA0GCSqGSIb3DQEBCwUA +A4ICAQCoQUpnKpKBglBu4dfYszk78wIVCVBR7y29JHuIhjv5tLySCZa59sCrI2AGeYwRTlHSeYAz ++51IvuxBQ4EffkdAHOV6CMqqi3WtFMTC6GY8ggen5ieCWxjmD27ZUD6KQhgpxrRW/FYQoAUXvQwj +f/ST7ZwaUb7dRUG/kSS0H4zpX897IZmflZ85OkYcbPnNe5yQzSipx6lVu6xiNGI1E0sUOlWDuYaN +kqbG9AclVMwWVxJKgnjIFNkXgiYtXSAfea7+1HAWFpWD2DU5/1JddRwWxRNVz0fMdWVSSt7wsKfk +CpYL+63C4iWEst3kvX5ZbJvw8NjnyvLplzh+ib7M+zkXYT9y2zqR2GUBGR2tUKRXCnxLvJxxcypF +URmFzI79R6d0lR2o0a9OF7FpJsKqeFdbxU2n5Z4FF5TKsl+gSRiNNOkmbEgeqmiSBeGCc1qb3Adb +CG19ndeNIdn8FCCqwkXfP+cAslHkwvgFuXkajDTznlvkN1trSt8sV4pAWja63XVECDdCcAz+3F4h +oKOKwJCcaNpQ5kUQR3i2TtJlycM33+FCY7BXN0Ute4qcvwXqZVUz9zkQxSgqIXobisQk+T8VyJoV +IPVVYpbtbZNQvOSqeK3Zywplh6ZmwcSBo3c6WB4L7oOLnR7SUqTMHW+wmG2UMbX4cQrcufx9MmDm +66+KAQ== +-----END CERTIFICATE----- + +CA Disig +======== +-----BEGIN CERTIFICATE----- +MIIEDzCCAvegAwIBAgIBATANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQGEwJTSzETMBEGA1UEBxMK +QnJhdGlzbGF2YTETMBEGA1UEChMKRGlzaWcgYS5zLjERMA8GA1UEAxMIQ0EgRGlzaWcwHhcNMDYw +MzIyMDEzOTM0WhcNMTYwMzIyMDEzOTM0WjBKMQswCQYDVQQGEwJTSzETMBEGA1UEBxMKQnJhdGlz +bGF2YTETMBEGA1UEChMKRGlzaWcgYS5zLjERMA8GA1UEAxMIQ0EgRGlzaWcwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQCS9jHBfYj9mQGp2HvycXXxMcbzdWb6UShGhJd4NLxs/LxFWYgm +GErENx+hSkS943EE9UQX4j/8SFhvXJ56CbpRNyIjZkMhsDxkovhqFQ4/61HhVKndBpnXmjxUizkD +Pw/Fzsbrg3ICqB9x8y34dQjbYkzo+s7552oftms1grrijxaSfQUMbEYDXcDtab86wYqg6I7ZuUUo +hwjstMoVvoLdtUSLLa2GDGhibYVW8qwUYzrG0ZmsNHhWS8+2rT+MitcE5eN4TPWGqvWP+j1scaMt +ymfraHtuM6kMgiioTGohQBUgDCZbg8KpFhXAJIJdKxatymP2dACw30PEEGBWZ2NFAgMBAAGjgf8w +gfwwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUjbJJaJ1yCCW5wCf1UJNWSEZx+Y8wDgYDVR0P +AQH/BAQDAgEGMDYGA1UdEQQvMC2BE2Nhb3BlcmF0b3JAZGlzaWcuc2uGFmh0dHA6Ly93d3cuZGlz +aWcuc2svY2EwZgYDVR0fBF8wXTAtoCugKYYnaHR0cDovL3d3dy5kaXNpZy5zay9jYS9jcmwvY2Ff +ZGlzaWcuY3JsMCygKqAohiZodHRwOi8vY2EuZGlzaWcuc2svY2EvY3JsL2NhX2Rpc2lnLmNybDAa +BgNVHSAEEzARMA8GDSuBHpGT5goAAAABAQEwDQYJKoZIhvcNAQEFBQADggEBAF00dGFMrzvY/59t +WDYcPQuBDRIrRhCA/ec8J9B6yKm2fnQwM6M6int0wHl5QpNt/7EpFIKrIYwvF/k/Ji/1WcbvgAa3 +mkkp7M5+cTxqEEHA9tOasnxakZzArFvITV734VP/Q3f8nktnbNfzg9Gg4H8l37iYC5oyOGwwoPP/ +CBUz91BKez6jPiCp3C9WgArtQVCwyfTssuMmRAAOb54GvCKWU3BlxFAKRmukLyeBEicTXxChds6K +ezfqwzlhA5WYOudsiCUI/HloDYd9Yvi0X/vF2Ey9WLw/Q1vUHgFNPGO+I++MzVpQuGhU+QqZMxEA +4Z7CRneC9VkGjCFMhwnN5ag= +-----END CERTIFICATE----- + +Juur-SK +======= +-----BEGIN CERTIFICATE----- +MIIE5jCCA86gAwIBAgIEO45L/DANBgkqhkiG9w0BAQUFADBdMRgwFgYJKoZIhvcNAQkBFglwa2lA +c2suZWUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKExlBUyBTZXJ0aWZpdHNlZXJpbWlza2Vza3VzMRAw +DgYDVQQDEwdKdXVyLVNLMB4XDTAxMDgzMDE0MjMwMVoXDTE2MDgyNjE0MjMwMVowXTEYMBYGCSqG +SIb3DQEJARYJcGtpQHNrLmVlMQswCQYDVQQGEwJFRTEiMCAGA1UEChMZQVMgU2VydGlmaXRzZWVy +aW1pc2tlc2t1czEQMA4GA1UEAxMHSnV1ci1TSzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAIFxNj4zB9bjMI0TfncyRsvPGbJgMUaXhvSYRqTCZUXP00B841oiqBB4M8yIsdOBSvZiF3tf +TQou0M+LI+5PAk676w7KvRhj6IAcjeEcjT3g/1tf6mTll+g/mX8MCgkzABpTpyHhOEvWgxutr2TC ++Rx6jGZITWYfGAriPrsfB2WThbkasLnE+w0R9vXW+RvHLCu3GFH+4Hv2qEivbDtPL+/40UceJlfw +UR0zlv/vWT3aTdEVNMfqPxZIe5EcgEMPPbgFPtGzlc3Yyg/CQ2fbt5PgIoIuvvVoKIO5wTtpeyDa +Tpxt4brNj3pssAki14sL2xzVWiZbDcDq5WDQn/413z8CAwEAAaOCAawwggGoMA8GA1UdEwEB/wQF +MAMBAf8wggEWBgNVHSAEggENMIIBCTCCAQUGCisGAQQBzh8BAQEwgfYwgdAGCCsGAQUFBwICMIHD +HoHAAFMAZQBlACAAcwBlAHIAdABpAGYAaQBrAGEAYQB0ACAAbwBuACAAdgDkAGwAagBhAHMAdABh +AHQAdQBkACAAQQBTAC0AaQBzACAAUwBlAHIAdABpAGYAaQB0AHMAZQBlAHIAaQBtAGkAcwBrAGUA +cwBrAHUAcwAgAGEAbABhAG0ALQBTAEsAIABzAGUAcgB0AGkAZgBpAGsAYQBhAHQAaQBkAGUAIABr +AGkAbgBuAGkAdABhAG0AaQBzAGUAawBzMCEGCCsGAQUFBwIBFhVodHRwOi8vd3d3LnNrLmVlL2Nw +cy8wKwYDVR0fBCQwIjAgoB6gHIYaaHR0cDovL3d3dy5zay5lZS9qdXVyL2NybC8wHQYDVR0OBBYE +FASqekej5ImvGs8KQKcYP2/v6X2+MB8GA1UdIwQYMBaAFASqekej5ImvGs8KQKcYP2/v6X2+MA4G +A1UdDwEB/wQEAwIB5jANBgkqhkiG9w0BAQUFAAOCAQEAe8EYlFOiCfP+JmeaUOTDBS8rNXiRTHyo +ERF5TElZrMj3hWVcRrs7EKACr81Ptcw2Kuxd/u+gkcm2k298gFTsxwhwDY77guwqYHhpNjbRxZyL +abVAyJRld/JXIWY7zoVAtjNjGr95HvxcHdMdkxuLDF2FvZkwMhgJkVLpfKG6/2SSmuz+Ne6ML678 +IIbsSt4beDI3poHSna9aEhbKmVv8b20OxaAehsmR0FyYgl9jDIpaq9iVpszLita/ZEuOyoqysOkh +Mp6qqIWYNIE5ITuoOlIyPfZrN4YGWhWY3PARZv40ILcD9EEQfTmEeZZyY7aWAuVrua0ZTbvGRNs2 +yyqcjg== +-----END CERTIFICATE----- + +Hongkong Post Root CA 1 +======================= +-----BEGIN CERTIFICATE----- +MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoT +DUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMB4XDTAzMDUx +NTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25n +IFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1 +ApzQjVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEnPzlTCeqr +auh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjhZY4bXSNmO7ilMlHIhqqh +qZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9nnV0ttgCXjqQesBCNnLsak3c78QA3xMY +V18meMjWCnl3v/evt3a5pQuEF10Q6m/hq5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNV +HRMBAf8ECDAGAQH/AgEDMA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7i +h9legYsCmEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI37pio +l7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clBoiMBdDhViw+5Lmei +IAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJsEhTkYY2sEJCehFC78JZvRZ+K88ps +T/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpOfMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilT +c4afU9hDDl3WY4JxHYB0yvbiAmvZWg== +-----END CERTIFICATE----- + +SecureSign RootCA11 +=================== +-----BEGIN CERTIFICATE----- +MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDErMCkGA1UEChMi +SmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoGA1UEAxMTU2VjdXJlU2lnbiBS +b290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSsw +KQYDVQQKEyJKYXBhbiBDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1 +cmVTaWduIFJvb3RDQTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvL +TJszi1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8h9uuywGO +wvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOVMdrAG/LuYpmGYz+/3ZMq +g6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rP +O7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitA +bpSACW22s293bzUIUPsCh8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZX +t94wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAKCh +OBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xmKbabfSVSSUOrTC4r +bnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQX5Ucv+2rIrVls4W6ng+4reV6G4pQ +Oh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWrQbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01 +y8hSyn+B/tlr0/cR7SXf+Of5pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061 +lgeLKBObjBmNQSdJQO7e5iNEOdyhIta6A/I= +-----END CERTIFICATE----- + +ACEDICOM Root +============= +-----BEGIN CERTIFICATE----- +MIIFtTCCA52gAwIBAgIIYY3HhjsBggUwDQYJKoZIhvcNAQEFBQAwRDEWMBQGA1UEAwwNQUNFRElD +T00gUm9vdDEMMAoGA1UECwwDUEtJMQ8wDQYDVQQKDAZFRElDT00xCzAJBgNVBAYTAkVTMB4XDTA4 +MDQxODE2MjQyMloXDTI4MDQxMzE2MjQyMlowRDEWMBQGA1UEAwwNQUNFRElDT00gUm9vdDEMMAoG +A1UECwwDUEtJMQ8wDQYDVQQKDAZFRElDT00xCzAJBgNVBAYTAkVTMIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEA/5KV4WgGdrQsyFhIyv2AVClVYyT/kGWbEHV7w2rbYgIB8hiGtXxaOLHk +WLn709gtn70yN78sFW2+tfQh0hOR2QetAQXW8713zl9CgQr5auODAKgrLlUTY4HKRxx7XBZXehuD +YAQ6PmXDzQHe3qTWDLqO3tkE7hdWIpuPY/1NFgu3e3eM+SW10W2ZEi5PGrjm6gSSrj0RuVFCPYew +MYWveVqc/udOXpJPQ/yrOq2lEiZmueIM15jO1FillUAKt0SdE3QrwqXrIhWYENiLxQSfHY9g5QYb +m8+5eaA9oiM/Qj9r+hwDezCNzmzAv+YbX79nuIQZ1RXve8uQNjFiybwCq0Zfm/4aaJQ0PZCOrfbk +HQl/Sog4P75n/TSW9R28MHTLOO7VbKvU/PQAtwBbhTIWdjPp2KOZnQUAqhbm84F9b32qhm2tFXTT +xKJxqvQUfecyuB+81fFOvW8XAjnXDpVCOscAPukmYxHqC9FK/xidstd7LzrZlvvoHpKuE1XI2Sf2 +3EgbsCTBheN3nZqk8wwRHQ3ItBTutYJXCb8gWH8vIiPYcMt5bMlL8qkqyPyHK9caUPgn6C9D4zq9 +2Fdx/c6mUlv53U3t5fZvie27k5x2IXXwkkwp9y+cAS7+UEaeZAwUswdbxcJzbPEHXEUkFDWug/Fq +TYl6+rPYLWbwNof1K1MCAwEAAaOBqjCBpzAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKaz +4SsrSbbXc6GqlPUB53NlTKxQMA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUprPhKytJttdzoaqU +9QHnc2VMrFAwRAYDVR0gBD0wOzA5BgRVHSAAMDEwLwYIKwYBBQUHAgEWI2h0dHA6Ly9hY2VkaWNv +bS5lZGljb21ncm91cC5jb20vZG9jMA0GCSqGSIb3DQEBBQUAA4ICAQDOLAtSUWImfQwng4/F9tqg +aHtPkl7qpHMyEVNEskTLnewPeUKzEKbHDZ3Ltvo/Onzqv4hTGzz3gvoFNTPhNahXwOf9jU8/kzJP +eGYDdwdY6ZXIfj7QeQCM8htRM5u8lOk6e25SLTKeI6RF+7YuE7CLGLHdztUdp0J/Vb77W7tH1Pwk +zQSulgUV1qzOMPPKC8W64iLgpq0i5ALudBF/TP94HTXa5gI06xgSYXcGCRZj6hitoocf8seACQl1 +ThCojz2GuHURwCRiipZ7SkXp7FnFvmuD5uHorLUwHv4FB4D54SMNUI8FmP8sX+g7tq3PgbUhh8oI +KiMnMCArz+2UW6yyetLHKKGKC5tNSixthT8Jcjxn4tncB7rrZXtaAWPWkFtPF2Y9fwsZo5NjEFIq +nxQWWOLcpfShFosOkYuByptZ+thrkQdlVV9SH686+5DdaaVbnG0OLLb6zqylfDJKZ0DcMDQj3dcE +I2bw/FWAp/tmGYI1Z2JwOV5vx+qQQEQIHriy1tvuWacNGHk0vFQYXlPKNFHtRQrmjseCNj6nOGOp +MCwXEGCSn1WHElkQwg9naRHMTh5+Spqtr0CodaxWkHS4oJyleW/c6RrIaQXpuvoDs3zk4E7Czp3o +tkYNbn5XOmeUwssfnHdKZ05phkOTOPu220+DkdRgfks+KzgHVZhepA== +-----END CERTIFICATE----- + +Verisign Class 3 Public Primary Certification Authority +======================================================= +-----BEGIN CERTIFICATE----- +MIICPDCCAaUCEDyRMcsf9tAbDpq40ES/Er4wDQYJKoZIhvcNAQEFBQAwXzELMAkGA1UEBhMCVVMx +FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmltYXJ5 +IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2MDEyOTAwMDAwMFoXDTI4MDgwMjIzNTk1OVow +XzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAz +IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUA +A4GNADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhEBarsAx94 +f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/isI19wKTakyYbnsZogy1Ol +hec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBABByUqkFFBky +CEHwxWsKzH4PIRnN5GfcX6kb5sroc50i2JhucwNhkcV8sEVAbkSdjbCxlnRhLQ2pRdKkkirWmnWX +bj9T/UWZYB2oK0z5XqcJ2HUw19JlYD1n1khVdWk/kfVIC0dpImmClr7JyDiGSnoscxlIaU5rfGW/ +D/xwzoiQ +-----END CERTIFICATE----- + +Microsec e-Szigno Root CA 2009 +============================== +-----BEGIN CERTIFICATE----- +MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYDVQQGEwJIVTER +MA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jv +c2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o +dTAeFw0wOTA2MTYxMTMwMThaFw0yOTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UE +BwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUt +U3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvPkd6mJviZpWNwrZuuyjNA +fW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tccbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG +0IMZfcChEhyVbUr02MelTTMuhTlAdX4UfIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKA +pxn1ntxVUwOXewdI/5n7N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm +1HxdrtbCxkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1+rUC +AwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTLD8bf +QkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAbBgNVHREE +FDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqGSIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0o +lZMEyL/azXm4Q5DwpL7v8u8hmLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfX +I/OMn74dseGkddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775 +tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c2Pm2G2JwCz02 +yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5tHMN1Rq41Bab2XD0h7lbwyYIi +LXpUq3DDfSJlgnCW +-----END CERTIFICATE----- + +E-Guven Kok Elektronik Sertifika Hizmet Saglayicisi +=================================================== +-----BEGIN CERTIFICATE----- +MIIDtjCCAp6gAwIBAgIQRJmNPMADJ72cdpW56tustTANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQG +EwJUUjEoMCYGA1UEChMfRWxla3Ryb25payBCaWxnaSBHdXZlbmxpZ2kgQS5TLjE8MDoGA1UEAxMz +ZS1HdXZlbiBLb2sgRWxla3Ryb25payBTZXJ0aWZpa2EgSGl6bWV0IFNhZ2xheWljaXNpMB4XDTA3 +MDEwNDExMzI0OFoXDTE3MDEwNDExMzI0OFowdTELMAkGA1UEBhMCVFIxKDAmBgNVBAoTH0VsZWt0 +cm9uaWsgQmlsZ2kgR3V2ZW5saWdpIEEuUy4xPDA6BgNVBAMTM2UtR3V2ZW4gS29rIEVsZWt0cm9u +aWsgU2VydGlmaWthIEhpem1ldCBTYWdsYXlpY2lzaTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBAMMSIJ6wXgBljU5Gu4Bc6SwGl9XzcslwuedLZYDBS75+PNdUMZTe1RK6UxYC6lhj71vY +8+0qGqpxSKPcEC1fX+tcS5yWCEIlKBHMilpiAVDV6wlTL/jDj/6z/P2douNffb7tC+Bg62nsM+3Y +jfsSSYMAyYuXjDtzKjKzEve5TfL0TW3H5tYmNwjy2f1rXKPlSFxYvEK+A1qBuhw1DADT9SN+cTAI +JjjcJRFHLfO6IxClv7wC90Nex/6wN1CZew+TzuZDLMN+DfIcQ2Zgy2ExR4ejT669VmxMvLz4Bcpk +9Ok0oSy1c+HCPujIyTQlCFzz7abHlJ+tiEMl1+E5YP6sOVkCAwEAAaNCMEAwDgYDVR0PAQH/BAQD +AgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJ/uRLOU1fqRTy7ZVZoEVtstxNulMA0GCSqG +SIb3DQEBBQUAA4IBAQB/X7lTW2M9dTLn+sR0GstG30ZpHFLPqk/CaOv/gKlR6D1id4k9CnU58W5d +F4dvaAXBlGzZXd/aslnLpRCKysw5zZ/rTt5S/wzw9JKp8mxTq5vSR6AfdPebmvEvFZ96ZDAYBzwq +D2fK/A+JYZ1lpTzlvBNbCNvj/+27BrtqBrF6T2XGgv0enIu1De5Iu7i9qgi0+6N8y5/NkHZchpZ4 +Vwpm+Vganf2XKWDeEaaQHBkc7gGWIjQ0LpH5t8Qn0Xvmv/uARFoW5evg1Ao4vOSR49XrXMGs3xtq +fJ7lddK2l4fbzIcrQzqECK+rPNv3PGYxhrCdU3nt+CPeQuMtgvEP5fqX +-----END CERTIFICATE----- + +GlobalSign Root CA - R3 +======================= +-----BEGIN CERTIFICATE----- +MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4GA1UECxMXR2xv +YmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh +bFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT +aWduIFJvb3QgQ0EgLSBSMzETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln +bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWt +iHL8RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsTgHeMCOFJ +0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmmKPZpO/bLyCiR5Z2KYVc3 +rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zdQQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjl +OCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZXriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2 +xmmFghcCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE +FI/wS3+oLkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZURUm7 +lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMpjjM5RcOO5LlXbKr8 +EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK6fBdRoyV3XpYKBovHd7NADdBj+1E +bddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQXmcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18 +YIvDQVETI53O9zJrlAGomecsMx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7r +kpeDMdmztcpHWD9f +-----END CERTIFICATE----- + +Autoridad de Certificacion Firmaprofesional CIF A62634068 +========================================================= +-----BEGIN CERTIFICATE----- +MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UEBhMCRVMxQjBA +BgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2 +MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEyMzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIw +QAYDVQQDDDlBdXRvcmlkYWQgZGUgQ2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBB +NjI2MzQwNjgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDD +Utd9thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQMcas9UX4P +B99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefGL9ItWY16Ck6WaVICqjaY +7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15iNA9wBj4gGFrO93IbJWyTdBSTo3OxDqqH +ECNZXyAFGUftaI6SEspd/NYrspI8IM/hX68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyI +plD9amML9ZMWGxmPsu2bm8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctX +MbScyJCyZ/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirjaEbsX +LZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/TKI8xWVvTyQKmtFLK +bpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF6NkBiDkal4ZkQdU7hwxu+g/GvUgU +vzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVhOSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1Ud +EwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNH +DhpkLzCBpgYDVR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp +cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBvACAAZABlACAA +bABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBlAGwAbwBuAGEAIAAwADgAMAAx +ADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx +51tkljYyGOylMnfX40S2wBEqgLk9am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qk +R71kMrv2JYSiJ0L1ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaP +T481PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS3a/DTg4f +Jl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5kSeTy36LssUzAKh3ntLFl +osS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF3dvd6qJ2gHN99ZwExEWN57kci57q13XR +crHedUTnQn3iV2t93Jm8PYMo6oCTjcVMZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoR +saS8I8nkvof/uZS2+F0gStRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTD +KCOM/iczQ0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQBjLMi +6Et8Vcad+qMUu2WFbm5PEn4KPJ2V +-----END CERTIFICATE----- + +Izenpe.com +========== +-----BEGIN CERTIFICATE----- +MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4MQswCQYDVQQG +EwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wHhcNMDcxMjEz +MTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMu +QS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ +03rKDx6sp4boFmVqscIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAK +ClaOxdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6HLmYRY2xU ++zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFXuaOKmMPsOzTFlUFpfnXC +PCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQDyCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxT +OTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbK +F7jJeodWLBoBHmy+E60QrLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK +0GqfvEyNBjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8Lhij+ +0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIBQFqNeb+Lz0vPqhbB +leStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+HMh3/1uaD7euBUbl8agW7EekFwID +AQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2luZm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+ +SVpFTlBFIFMuQS4gLSBDSUYgQTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBG +NjIgUzgxQzBBBgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx +MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0O +BBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUAA4ICAQB4pgwWSp9MiDrAyw6l +Fn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWblaQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbga +kEyrkgPH7UIBzg/YsfqikuFgba56awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8q +hT/AQKM6WfxZSzwoJNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Cs +g1lwLDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCTVyvehQP5 +aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGkLhObNA5me0mrZJfQRsN5 +nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJbUjWumDqtujWTI6cfSN01RpiyEGjkpTHC +ClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZo +Q0iy2+tzJOeRf1SktoA+naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1Z +WrOZyGlsQyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw== +-----END CERTIFICATE----- + +Chambers of Commerce Root - 2008 +================================ +-----BEGIN CERTIFICATE----- +MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYDVQQGEwJFVTFD +MEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNv +bS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMu +QS4xKTAnBgNVBAMTIENoYW1iZXJzIG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEy +Mjk1MFoXDTM4MDczMTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNl +ZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIwEAYDVQQF +EwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJl +cnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC +AQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW928sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKA +XuFixrYp4YFs8r/lfTJqVKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorj +h40G072QDuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR5gN/ +ikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfLZEFHcpOrUMPrCXZk +NNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05aSd+pZgvMPMZ4fKecHePOjlO+Bd5g +D2vlGts/4+EhySnB8esHnFIbAURRPHsl18TlUlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331 +lubKgdaX8ZSD6e2wsWsSaR6s+12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ +0wlf2eOKNcx5Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj +ya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAxhduub+84Mxh2 +EQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNVHQ4EFgQU+SSsD7K1+HnA+mCI +G8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1+HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJ +BgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNh +bWVyZmlybWEuY29tL2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENh +bWVyZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDiC +CQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUH +AgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZIhvcNAQEFBQADggIBAJASryI1 +wqM58C7e6bXpeHxIvj99RZJe6dqxGfwWPJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH +3qLPaYRgM+gQDROpI9CF5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbU +RWpGqOt1glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaHFoI6 +M6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2pSB7+R5KBWIBpih1 +YJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MDxvbxrN8y8NmBGuScvfaAFPDRLLmF +9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QGtjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcK +zBIKinmwPQN/aUv0NCB9szTqjktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvG +nrDQWzilm1DefhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg +OGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZd0jQ +-----END CERTIFICATE----- + +Global Chambersign Root - 2008 +============================== +-----BEGIN CERTIFICATE----- +MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYDVQQGEwJFVTFD +MEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNv +bS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMu +QS4xJzAlBgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMx +NDBaFw0zODA3MzExMjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUg +Y3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJ +QTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD +aGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDf +VtPkOpt2RbQT2//BthmLN0EYlVJH6xedKYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXf +XjaOcNFccUMd2drvXNL7G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0 +ZJJ0YPP2zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4ddPB +/gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyGHoiMvvKRhI9lNNgA +TH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2Id3UwD2ln58fQ1DJu7xsepeY7s2M +H/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3VyJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfe +Ox2YItaswTXbo6Al/3K1dh3ebeksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSF +HTynyQbehP9r6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh +wZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsogzCtLkykPAgMB +AAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQWBBS5CcqcHtvTbDprru1U8VuT +BjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDprru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UE +BhMCRVUxQzBBBgNVBAcTOk1hZHJpZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJm +aXJtYS5jb20vYWRkcmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJm +aXJtYSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiCCQDJzdPp +1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUHAgEWHGh0 +dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZIhvcNAQEFBQADggIBAICIf3DekijZBZRG +/5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZUohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6 +ReAJ3spED8IXDneRRXozX1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/s +dZ7LoR/xfxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVza2Mg +9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yydYhz2rXzdpjEetrHH +foUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMdSqlapskD7+3056huirRXhOukP9Du +qqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9OAP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETr +P3iZ8ntxPjzxmKfFGBI/5rsoM0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVq +c5iJWzouE4gev8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z +09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B +-----END CERTIFICATE----- + +Go Daddy Root Certificate Authority - G2 +======================================== +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT +B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoTEUdvRGFkZHkuY29tLCBJbmMu +MTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 +MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 +b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8G +A1UEAxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKDE6bFIEMBO4Tx5oVJnyfq +9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD ++qK+ihVqf94Lw7YZFAXK6sOoBJQ7RnwyDfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutd +fMh8+7ArU6SSYmlRJQVhGkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMl +NAJWJwGRtDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEAAaNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFDqahQcQZyi27/a9 +BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmXWWcDYfF+OwYxdS2hII5PZYe096ac +vNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r +5N9ss4UXnT3ZJE95kTXWXwTrgIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYV +N8Gb5DKj7Tjo2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO +LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI4uJEvlz36hz1 +-----END CERTIFICATE----- + +Starfield Root Certificate Authority - G2 +========================================= +-----BEGIN CERTIFICATE----- +MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT +B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s +b2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVsZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0 +eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAw +DgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQg +VGVjaG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZpY2F0ZSBB +dXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL3twQP89o/8ArFv +W59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMgnLRJdzIpVv257IzdIvpy3Cdhl+72WoTs +bhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNk +N3mSwOxGXn/hbVNMYq/NHwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7Nf +ZTD4p7dNdloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0HZbU +JtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0GCSqGSIb3DQEBCwUAA4IBAQARWfol +TwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjUsHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx +4mcujJUDJi5DnUox9g61DLu34jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUw +F5okxBDgBPfg8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K +pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1mMpYjn0q7pBZ +c2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 +-----END CERTIFICATE----- + +Starfield Services Root Certificate Authority - G2 +================================================== +-----BEGIN CERTIFICATE----- +MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMxEDAOBgNVBAgT +B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s +b2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVsZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRl +IEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNV +BAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxT +dGFyZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2VydmljZXMg +Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20pOsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2 +h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm28xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4Pa +hHQUw2eeBGg6345AWh1KTs9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLP +LJGmpufehRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk6mFB +rMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAwDwYDVR0TAQH/BAUw +AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+qAdcwKziIorhtSpzyEZGDMA0GCSqG +SIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMIbw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPP +E95Dz+I0swSdHynVv/heyNXBve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTy +xQGjhdByPq1zqwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd +iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn0q23KXB56jza +YyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCNsSi6 +-----END CERTIFICATE----- + +AffirmTrust Commercial +====================== +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UEBhMCVVMxFDAS +BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMB4XDTEw +MDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly +bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6Eqdb +DuKPHx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yrba0F8PrV +C8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPALMeIrJmqbTFeurCA+ukV6 +BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1yHp52UKqK39c/s4mT6NmgTWvRLpUHhww +MmWd5jyTXlBOeuM61G7MGvv50jeuJCqrVwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNV +HQ4EFgQUnZPGU4teyq8/nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AQYwDQYJKoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYGXUPG +hi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNjvbz4YYCanrHOQnDi +qX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivtZ8SOyUOyXGsViQK8YvxO8rUzqrJv +0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9gN53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0kh +sUlHRUe072o0EclNmsxZt9YCnlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8= +-----END CERTIFICATE----- + +AffirmTrust Networking +====================== +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UEBhMCVVMxFDAS +BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMB4XDTEw +MDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly +bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SE +Hi3yYJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbuakCNrmreI +dIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRLQESxG9fhwoXA3hA/Pe24 +/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gb +h+0t+nvujArjqWaJGctB+d1ENmHP4ndGyH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNV +HQ4EFgQUBx/S55zawm6iQLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AQYwDQYJKoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfOtDIu +UFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzuQY0x2+c06lkh1QF6 +12S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZLgo/bNjR9eUJtGxUAArgFU2HdW23 +WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4uolu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9 +/ZFvgrG+CJPbFEfxojfHRZ48x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s= +-----END CERTIFICATE----- + +AffirmTrust Premium +=================== +-----BEGIN CERTIFICATE----- +MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UEBhMCVVMxFDAS +BgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMB4XDTEwMDEy +OTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRy +dXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A +MIICCgKCAgEAxBLfqV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtn +BKAQJG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ+jjeRFcV +5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrSs8PhaJyJ+HoAVt70VZVs ++7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmd +GPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d770O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5R +p9EixAqnOEhss/n/fauGV+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NI +S+LI+H+SqHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S5u04 +6uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4IaC1nEWTJ3s7xgaVY5 +/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TXOwF0lkLgAOIua+rF7nKsu7/+6qqo ++Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYEFJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByv +MiPIs0laUZx2KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg +Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B8OWycvpEgjNC +6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQMKSOyARiqcTtNd56l+0OOF6S +L5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK ++4w1IX2COPKpVJEZNZOUbWo6xbLQu4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmV +BtWVyuEklut89pMFu+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFg +IxpHYoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8GKa1qF60 +g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaORtGdFNrHF+QFlozEJLUb +zxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6eKeC2uAloGRwYQw== +-----END CERTIFICATE----- + +AffirmTrust Premium ECC +======================= +-----BEGIN CERTIFICATE----- +MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMCVVMxFDASBgNV +BAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQcmVtaXVtIEVDQzAeFw0xMDAx +MjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJBgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1U +cnVzdDEgMB4GA1UEAwwXQWZmaXJtVHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAAQNMF4bFZ0D0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQ +N8O9ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0GA1UdDgQW +BBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAK +BggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/VsaobgxCd05DhT1wV/GzTjxi+zygk8N53X +57hG8f2h4nECMEJZh0PUUd+60wkyWs6Iflc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKM +eQ== +-----END CERTIFICATE----- + +Certum Trusted Network CA +========================= +-----BEGIN CERTIFICATE----- +MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBMMSIwIAYDVQQK +ExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBUcnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIy +MTIwNzM3WhcNMjkxMjMxMTIwNzM3WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBU +ZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +MSIwIAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rHUV+rpDKmYYe2bg+G0jAC +l/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LMTXPb865Px1bVWqeWifrzq2jUI4ZZJ88J +J7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVUBBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4 +fOQtf/WsX+sWn7Et0brMkUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0 +cvW0QM8xAcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNVHRMB +Af8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNVHQ8BAf8EBAMCAQYw +DQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15ysHhE49wcrwn9I0j6vSrEuVUEtRCj +jSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfLI9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1 +mS1FhIrlQgnXdAIv94nYmem8J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5aj +Zt3hrvJBW8qYVoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI +03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw= +-----END CERTIFICATE----- + +Certinomis - Autorité Racine +============================= +-----BEGIN CERTIFICATE----- +MIIFnDCCA4SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJGUjETMBEGA1UEChMK +Q2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxJjAkBgNVBAMMHUNlcnRpbm9taXMg +LSBBdXRvcml0w6kgUmFjaW5lMB4XDTA4MDkxNzA4Mjg1OVoXDTI4MDkxNzA4Mjg1OVowYzELMAkG +A1UEBhMCRlIxEzARBgNVBAoTCkNlcnRpbm9taXMxFzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMSYw +JAYDVQQDDB1DZXJ0aW5vbWlzIC0gQXV0b3JpdMOpIFJhY2luZTCCAiIwDQYJKoZIhvcNAQEBBQAD +ggIPADCCAgoCggIBAJ2Fn4bT46/HsmtuM+Cet0I0VZ35gb5j2CN2DpdUzZlMGvE5x4jYF1AMnmHa +wE5V3udauHpOd4cN5bjr+p5eex7Ezyh0x5P1FMYiKAT5kcOrJ3NqDi5N8y4oH3DfVS9O7cdxbwly +Lu3VMpfQ8Vh30WC8Tl7bmoT2R2FFK/ZQpn9qcSdIhDWerP5pqZ56XjUl+rSnSTV3lqc2W+HN3yNw +2F1MpQiD8aYkOBOo7C+ooWfHpi2GR+6K/OybDnT0K0kCe5B1jPyZOQE51kqJ5Z52qz6WKDgmi92N +jMD2AR5vpTESOH2VwnHu7XSu5DaiQ3XV8QCb4uTXzEIDS3h65X27uK4uIJPT5GHfceF2Z5c/tt9q +c1pkIuVC28+BA5PY9OMQ4HL2AHCs8MF6DwV/zzRpRbWT5BnbUhYjBYkOjUjkJW+zeL9i9Qf6lSTC +lrLooyPCXQP8w9PlfMl1I9f09bze5N/NgL+RiH2nE7Q5uiy6vdFrzPOlKO1Enn1So2+WLhl+HPNb +xxaOu2B9d2ZHVIIAEWBsMsGoOBvrbpgT1u449fCfDu/+MYHB0iSVL1N6aaLwD4ZFjliCK0wi1F6g +530mJ0jfJUaNSih8hp75mxpZuWW/Bd22Ql095gBIgl4g9xGC3srYn+Y3RyYe63j3YcNBZFgCQfna +4NH4+ej9Uji29YnfAgMBAAGjWzBZMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G +A1UdDgQWBBQNjLZh2kS40RR9w759XkjwzspqsDAXBgNVHSAEEDAOMAwGCiqBegFWAgIAAQEwDQYJ +KoZIhvcNAQEFBQADggIBACQ+YAZ+He86PtvqrxyaLAEL9MW12Ukx9F1BjYkMTv9sov3/4gbIOZ/x +WqndIlgVqIrTseYyCYIDbNc/CMf4uboAbbnW/FIyXaR/pDGUu7ZMOH8oMDX/nyNTt7buFHAAQCva +R6s0fl6nVjBhK4tDrP22iCj1a7Y+YEq6QpA0Z43q619FVDsXrIvkxmUP7tCMXWY5zjKn2BCXwH40 +nJ+U8/aGH88bc62UeYdocMMzpXDn2NU4lG9jeeu/Cg4I58UvD0KgKxRA/yHgBcUn4YQRE7rWhh1B +CxMjidPJC+iKunqjo3M3NYB9Ergzd0A4wPpeMNLytqOx1qKVl4GbUu1pTP+A5FPbVFsDbVRfsbjv +JL1vnxHDx2TCDyhihWZeGnuyt++uNckZM6i4J9szVb9o4XVIRFb7zdNIu0eJOqxp9YDG5ERQL1TE +qkPFMTFYvZbF6nVsmnWxTfj3l/+WFvKXTej28xH5On2KOG4Ey+HTRRWqpdEdnV1j6CTmNhTih60b +WfVEm/vXd3wfAXBioSAaosUaKPQhA+4u2cGA6rnZgtZbdsLLO7XSAPCjDuGtbkD326C00EauFddE +wk01+dIL8hf2rGbVJLJP0RyZwG71fet0BLj5TXcJ17TPBzAJ8bgAVtkXFhYKK4bfjwEZGuW7gmP/ +vgt2Fl43N+bYdJeimUV5 +-----END CERTIFICATE----- + +Root CA Generalitat Valenciana +============================== +-----BEGIN CERTIFICATE----- +MIIGizCCBXOgAwIBAgIEO0XlaDANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJFUzEfMB0GA1UE +ChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UECxMGUEtJR1ZBMScwJQYDVQQDEx5Sb290 +IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmEwHhcNMDEwNzA2MTYyMjQ3WhcNMjEwNzAxMTUyMjQ3 +WjBoMQswCQYDVQQGEwJFUzEfMB0GA1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UE +CxMGUEtJR1ZBMScwJQYDVQQDEx5Sb290IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmEwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGKqtXETcvIorKA3Qdyu0togu8M1JAJke+WmmmO3I2 +F0zo37i7L3bhQEZ0ZQKQUgi0/6iMweDHiVYQOTPvaLRfX9ptI6GJXiKjSgbwJ/BXufjpTjJ3Cj9B +ZPPrZe52/lSqfR0grvPXdMIKX/UIKFIIzFVd0g/bmoGlu6GzwZTNVOAydTGRGmKy3nXiz0+J2ZGQ +D0EbtFpKd71ng+CT516nDOeB0/RSrFOyA8dEJvt55cs0YFAQexvba9dHq198aMpunUEDEO5rmXte +JajCq+TA81yc477OMUxkHl6AovWDfgzWyoxVjr7gvkkHD6MkQXpYHYTqWBLI4bft75PelAgxAgMB +AAGjggM7MIIDNzAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9vY3NwLnBraS5n +dmEuZXMwEgYDVR0TAQH/BAgwBgEB/wIBAjCCAjQGA1UdIASCAiswggInMIICIwYKKwYBBAG/VQIB +ADCCAhMwggHoBggrBgEFBQcCAjCCAdoeggHWAEEAdQB0AG8AcgBpAGQAYQBkACAAZABlACAAQwBl +AHIAdABpAGYAaQBjAGEAYwBpAPMAbgAgAFIAYQDtAHoAIABkAGUAIABsAGEAIABHAGUAbgBlAHIA +YQBsAGkAdABhAHQAIABWAGEAbABlAG4AYwBpAGEAbgBhAC4ADQAKAEwAYQAgAEQAZQBjAGwAYQBy +AGEAYwBpAPMAbgAgAGQAZQAgAFAAcgDhAGMAdABpAGMAYQBzACAAZABlACAAQwBlAHIAdABpAGYA +aQBjAGEAYwBpAPMAbgAgAHEAdQBlACAAcgBpAGcAZQAgAGUAbAAgAGYAdQBuAGMAaQBvAG4AYQBt +AGkAZQBuAHQAbwAgAGQAZQAgAGwAYQAgAHAAcgBlAHMAZQBuAHQAZQAgAEEAdQB0AG8AcgBpAGQA +YQBkACAAZABlACAAQwBlAHIAdABpAGYAaQBjAGEAYwBpAPMAbgAgAHMAZQAgAGUAbgBjAHUAZQBu +AHQAcgBhACAAZQBuACAAbABhACAAZABpAHIAZQBjAGMAaQDzAG4AIAB3AGUAYgAgAGgAdAB0AHAA +OgAvAC8AdwB3AHcALgBwAGsAaQAuAGcAdgBhAC4AZQBzAC8AYwBwAHMwJQYIKwYBBQUHAgEWGWh0 +dHA6Ly93d3cucGtpLmd2YS5lcy9jcHMwHQYDVR0OBBYEFHs100DSHHgZZu90ECjcPk+yeAT8MIGV +BgNVHSMEgY0wgYqAFHs100DSHHgZZu90ECjcPk+yeAT8oWykajBoMQswCQYDVQQGEwJFUzEfMB0G +A1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UECxMGUEtJR1ZBMScwJQYDVQQDEx5S +b290IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmGCBDtF5WgwDQYJKoZIhvcNAQEFBQADggEBACRh +TvW1yEICKrNcda3FbcrnlD+laJWIwVTAEGmiEi8YPyVQqHxK6sYJ2fR1xkDar1CdPaUWu20xxsdz +Ckj+IHLtb8zog2EWRpABlUt9jppSCS/2bxzkoXHPjCpaF3ODR00PNvsETUlR4hTJZGH71BTg9J63 +NI8KJr2XXPR5OkowGcytT6CYirQxlyric21+eLj4iIlPsSKRZEv1UN4D2+XFducTZnV+ZfsBn5OH +iJ35Rld8TWCvmHMTI6QgkYH60GFmuH3Rr9ZvHmw96RH9qfmCIoaZM3Fa6hlXPZHNqcCjbgcTpsnt ++GijnsNacgmHKNHEc8RzGF9QdRYxn7fofMM= +-----END CERTIFICATE----- + +A-Trust-nQual-03 +================ +-----BEGIN CERTIFICATE----- +MIIDzzCCAregAwIBAgIDAWweMA0GCSqGSIb3DQEBBQUAMIGNMQswCQYDVQQGEwJBVDFIMEYGA1UE +Cgw/QS1UcnVzdCBHZXMuIGYuIFNpY2hlcmhlaXRzc3lzdGVtZSBpbSBlbGVrdHIuIERhdGVudmVy +a2VociBHbWJIMRkwFwYDVQQLDBBBLVRydXN0LW5RdWFsLTAzMRkwFwYDVQQDDBBBLVRydXN0LW5R +dWFsLTAzMB4XDTA1MDgxNzIyMDAwMFoXDTE1MDgxNzIyMDAwMFowgY0xCzAJBgNVBAYTAkFUMUgw +RgYDVQQKDD9BLVRydXN0IEdlcy4gZi4gU2ljaGVyaGVpdHNzeXN0ZW1lIGltIGVsZWt0ci4gRGF0 +ZW52ZXJrZWhyIEdtYkgxGTAXBgNVBAsMEEEtVHJ1c3QtblF1YWwtMDMxGTAXBgNVBAMMEEEtVHJ1 +c3QtblF1YWwtMDMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtPWFuA/OQO8BBC4SA +zewqo51ru27CQoT3URThoKgtUaNR8t4j8DRE/5TrzAUjlUC5B3ilJfYKvUWG6Nm9wASOhURh73+n +yfrBJcyFLGM/BWBzSQXgYHiVEEvc+RFZznF/QJuKqiTfC0Li21a8StKlDJu3Qz7dg9MmEALP6iPE +SU7l0+m0iKsMrmKS1GWH2WrX9IWf5DMiJaXlyDO6w8dB3F/GaswADm0yqLaHNgBid5seHzTLkDx4 +iHQF63n1k3Flyp3HaxgtPVxO59X4PzF9j4fsCiIvI+n+u33J4PTs63zEsMMtYrWacdaxaujs2e3V +cuy+VwHOBVWf3tFgiBCzAgMBAAGjNjA0MA8GA1UdEwEB/wQFMAMBAf8wEQYDVR0OBAoECERqlWdV +eRFPMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAVdRU0VlIXLOThaq/Yy/kgM40 +ozRiPvbY7meIMQQDbwvUB/tOdQ/TLtPAF8fGKOwGDREkDg6lXb+MshOWcdzUzg4NCmgybLlBMRmr +sQd7TZjTXLDR8KdCoLXEjq/+8T/0709GAHbrAvv5ndJAlseIOrifEXnzgGWovR/TeIGgUUw3tKZd +JXDRZslo+S4RFGjxVJgIrCaSD96JntT6s3kr0qN51OyLrIdTaEJMUVF0HhsnLuP1Hyl0Te2v9+GS +mYHovjrHF1D2t8b8m7CKa9aIA5GPBnc6hQLdmNVDeD/GMBWsm2vLV7eJUYs66MmEDNuxUCAKGkq6 +ahq97BvIxYSazQ== +-----END CERTIFICATE----- + +TWCA Root Certification Authority +================================= +-----BEGIN CERTIFICATE----- +MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJ +VEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMzWhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQG +EwJUVzESMBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NB +IFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFEAcK0HMMx +QhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HHK3XLfJ+utdGdIzdjp9xC +oi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeXRfwZVzsrb+RH9JlF/h3x+JejiB03HFyP +4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/zrX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1r +y+UPizgN7gr8/g+YnzAx3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIB +BjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkqhkiG +9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeCMErJk/9q56YAf4lC +mtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdlsXebQ79NqZp4VKIV66IIArB6nCWlW +QtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62Dlhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVY +T0bf+215WfKEIlKuD8z7fDvnaspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocny +Yh0igzyXxfkZYiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw== +-----END CERTIFICATE----- + +Security Communication RootCA2 +============================== +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDElMCMGA1UEChMc +U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMeU2VjdXJpdHkgQ29tbXVuaWNh +dGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoXDTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMC +SlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3Vy +aXR5IENvbW11bmljYXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +ANAVOVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGrzbl+dp++ ++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVMVAX3NuRFg3sUZdbcDE3R +3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQhNBqyjoGADdH5H5XTz+L62e4iKrFvlNV +spHEfbmwhRkGeC7bYRr6hfVKkaHnFtWOojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1K +EOtOghY6rCcMU/Gt1SSwawNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8 +QIH4D5csOPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEB +CwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpFcoJxDjrSzG+ntKEj +u/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXcokgfGT+Ok+vx+hfuzU7jBBJV1uXk +3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6q +tnRGEmyR7jTV7JqR50S+kDFy1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29 +mvVXIwAHIRc/SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 +-----END CERTIFICATE----- + +EC-ACC +====== +-----BEGIN CERTIFICATE----- +MIIFVjCCBD6gAwIBAgIQ7is969Qh3hSoYqwE893EATANBgkqhkiG9w0BAQUFADCB8zELMAkGA1UE +BhMCRVMxOzA5BgNVBAoTMkFnZW5jaWEgQ2F0YWxhbmEgZGUgQ2VydGlmaWNhY2lvIChOSUYgUS0w +ODAxMTc2LUkpMSgwJgYDVQQLEx9TZXJ2ZWlzIFB1YmxpY3MgZGUgQ2VydGlmaWNhY2lvMTUwMwYD +VQQLEyxWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAoYykwMzE1MDMGA1UE +CxMsSmVyYXJxdWlhIEVudGl0YXRzIGRlIENlcnRpZmljYWNpbyBDYXRhbGFuZXMxDzANBgNVBAMT +BkVDLUFDQzAeFw0wMzAxMDcyMzAwMDBaFw0zMTAxMDcyMjU5NTlaMIHzMQswCQYDVQQGEwJFUzE7 +MDkGA1UEChMyQWdlbmNpYSBDYXRhbGFuYSBkZSBDZXJ0aWZpY2FjaW8gKE5JRiBRLTA4MDExNzYt +SSkxKDAmBgNVBAsTH1NlcnZlaXMgUHVibGljcyBkZSBDZXJ0aWZpY2FjaW8xNTAzBgNVBAsTLFZl +Z2V1IGh0dHBzOi8vd3d3LmNhdGNlcnQubmV0L3ZlcmFycmVsIChjKTAzMTUwMwYDVQQLEyxKZXJh +cnF1aWEgRW50aXRhdHMgZGUgQ2VydGlmaWNhY2lvIENhdGFsYW5lczEPMA0GA1UEAxMGRUMtQUND +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsyLHT+KXQpWIR4NA9h0X84NzJB5R85iK +w5K4/0CQBXCHYMkAqbWUZRkiFRfCQ2xmRJoNBD45b6VLeqpjt4pEndljkYRm4CgPukLjbo73FCeT +ae6RDqNfDrHrZqJyTxIThmV6PttPB/SnCWDaOkKZx7J/sxaVHMf5NLWUhdWZXqBIoH7nF2W4onW4 +HvPlQn2v7fOKSGRdghST2MDk/7NQcvJ29rNdQlB50JQ+awwAvthrDk4q7D7SzIKiGGUzE3eeml0a +E9jD2z3Il3rucO2n5nzbcc8tlGLfbdb1OL4/pYUKGbio2Al1QnDE6u/LDsg0qBIimAy4E5S2S+zw +0JDnJwIDAQABo4HjMIHgMB0GA1UdEQQWMBSBEmVjX2FjY0BjYXRjZXJ0Lm5ldDAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUoMOLRKo3pUW/l4Ba0fF4opvpXY0wfwYD +VR0gBHgwdjB0BgsrBgEEAfV4AQMBCjBlMCwGCCsGAQUFBwIBFiBodHRwczovL3d3dy5jYXRjZXJ0 +Lm5ldC92ZXJhcnJlbDA1BggrBgEFBQcCAjApGidWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5l +dC92ZXJhcnJlbCAwDQYJKoZIhvcNAQEFBQADggEBAKBIW4IB9k1IuDlVNZyAelOZ1Vr/sXE7zDkJ +lF7W2u++AVtd0x7Y/X1PzaBB4DSTv8vihpw3kpBWHNzrKQXlxJ7HNd+KDM3FIUPpqojlNcAZQmNa +Al6kSBg6hW/cnbw/nZzBh7h6YQjpdwt/cKt63dmXLGQehb+8dJahw3oS7AwaboMMPOhyRp/7SNVe +l+axofjk70YllJyJ22k4vuxcDlbHZVHlUIiIv0LVKz3l+bqeLrPK9HOSAgu+TGbrIP65y7WZf+a2 +E/rKS03Z7lNGBjvGTq2TWoF+bCpLagVFjPIhpDGQh2xlnJ2lYJU6Un/10asIbvPuW/mIPX64b24D +5EI= +-----END CERTIFICATE----- + +Hellenic Academic and Research Institutions RootCA 2011 +======================================================= +-----BEGIN CERTIFICATE----- +MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1IxRDBCBgNVBAoT +O0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9y +aXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25z +IFJvb3RDQSAyMDExMB4XDTExMTIwNjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYT +AkdSMUQwQgYDVQQKEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25z +IENlcnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNo +IEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +AKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPzdYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI +1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJfel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa +71HFK9+WXesyHgLacEnsbgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u +8yBRQlqD75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSPFEDH +3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNVHRMBAf8EBTADAQH/ +MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp5dgTBCPuQSUwRwYDVR0eBEAwPqA8 +MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQub3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQu +b3JnMA0GCSqGSIb3DQEBBQUAA4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVt +XdMiKahsog2p6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8 +TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7dIsXRSZMFpGD +/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8AcysNnq/onN694/BtZqhFLKPM58N +7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXIl7WdmplNsDz4SgCbZN2fOUvRJ9e4 +-----END CERTIFICATE----- + +Actalis Authentication Root CA +============================== +-----BEGIN CERTIFICATE----- +MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UEBhMCSVQxDjAM +BgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UE +AwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDky +MjExMjIwMlowazELMAkGA1UEBhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlz +IFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290 +IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNvUTufClrJ +wkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX4ay8IMKx4INRimlNAJZa +by/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9KK3giq0itFZljoZUj5NDKd45RnijMCO6 +zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1f +YVEiVRvjRuPjPdA1YprbrxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2 +oxgkg4YQ51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2Fbe8l +EfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxeKF+w6D9Fz8+vm2/7 +hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4Fv6MGn8i1zeQf1xcGDXqVdFUNaBr8 +EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbnfpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5 +jF66CyCU3nuDuP/jVo23Eek7jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLY +iDrIn3hm7YnzezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt +ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQALe3KHwGCmSUyI +WOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70jsNjLiNmsGe+b7bAEzlgqqI0 +JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDzWochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKx +K3JCaKygvU5a2hi/a5iB0P2avl4VSM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+ +Xlff1ANATIGk0k9jpwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC +4yyXX04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+OkfcvHlXHo +2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7RK4X9p2jIugErsWx0Hbhz +lefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btUZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXem +OR/qnuOf0GZvBeyqdn6/axag67XH/JJULysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9 +vwGYT7JZVEc+NHt4bVaTLnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg== +-----END CERTIFICATE----- + +Trustis FPS Root CA +=================== +-----BEGIN CERTIFICATE----- +MIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQG +EwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQLExNUcnVzdGlzIEZQUyBSb290 +IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTExMzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNV +BAoTD1RydXN0aXMgTGltaXRlZDEcMBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQ +RUN+AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihHiTHcDnlk +H5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjjvSkCqPoc4Vu5g6hBSLwa +cY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zt +o3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlBOrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEA +AaNTMFEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAd +BgNVHQ4EFgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01GX2c +GE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmWzaD+vkAMXBJV+JOC +yinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP41BIy+Q7DsdwyhEQsb8tGD+pmQQ9P +8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZEf1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHV +l/9D7S3B2l0pKoU/rGXuhg8FjZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYl +iB6XzCGcKQENZetX2fNXlrtIzYE= +-----END CERTIFICATE----- + +StartCom Certification Authority +================================ +-----BEGIN CERTIFICATE----- +MIIHhzCCBW+gAwIBAgIBLTANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMN +U3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmlu +ZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0 +NjM3WhcNMzYwOTE3MTk0NjM2WjB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRk +LjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMg +U3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw +ggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZkpMyONvg45iPwbm2xPN1y +o4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rfOQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/ +Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/CJi/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/d +eMotHweXMAEtcnn6RtYTKqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt +2PZE4XNiHzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMMAv+Z +6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w+2OqqGwaVLRcJXrJ +osmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/ +untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVc +UjyJthkqcwEKDwOzEmDyei+B26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT +37uMdBNSSwIDAQABo4ICEDCCAgwwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD +VR0OBBYEFE4L7xqkQFulF2mHMMo0aEPQQa7yMB8GA1UdIwQYMBaAFE4L7xqkQFulF2mHMMo0aEPQ +Qa7yMIIBWgYDVR0gBIIBUTCCAU0wggFJBgsrBgEEAYG1NwEBATCCATgwLgYIKwYBBQUHAgEWImh0 +dHA6Ly93d3cuc3RhcnRzc2wuY29tL3BvbGljeS5wZGYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cu +c3RhcnRzc2wuY29tL2ludGVybWVkaWF0ZS5wZGYwgc8GCCsGAQUFBwICMIHCMCcWIFN0YXJ0IENv +bW1lcmNpYWwgKFN0YXJ0Q29tKSBMdGQuMAMCAQEagZZMaW1pdGVkIExpYWJpbGl0eSwgcmVhZCB0 +aGUgc2VjdGlvbiAqTGVnYWwgTGltaXRhdGlvbnMqIG9mIHRoZSBTdGFydENvbSBDZXJ0aWZpY2F0 +aW9uIEF1dGhvcml0eSBQb2xpY3kgYXZhaWxhYmxlIGF0IGh0dHA6Ly93d3cuc3RhcnRzc2wuY29t +L3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilTdGFydENvbSBG +cmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQsFAAOCAgEAjo/n3JR5 +fPGFf59Jb2vKXfuM/gTFwWLRfUKKvFO3lANmMD+x5wqnUCBVJX92ehQN6wQOQOY+2IirByeDqXWm +N3PH/UvSTa0XQMhGvjt/UfzDtgUx3M2FIk5xt/JxXrAaxrqTi3iSSoX4eA+D/i+tLPfkpLst0OcN +Org+zvZ49q5HJMqjNTbOx8aHmNrs++myziebiMMEofYLWWivydsQD032ZGNcpRJvkrKTlMeIFw6T +tn5ii5B/q06f/ON1FE8qMt9bDeD1e5MNq6HPh+GlBEXoPBKlCcWw0bdT82AUuoVpaiF8H3VhFyAX +e2w7QSlc4axa0c2Mm+tgHRns9+Ww2vl5GKVFP0lDV9LdJNUso/2RjSe15esUBppMeyG7Oq0wBhjA +2MFrLH9ZXF2RsXAiV+uKa0hK1Q8p7MZAwC+ITGgBF3f0JBlPvfrhsiAhS90a2Cl9qrjeVOwhVYBs +HvUwyKMQ5bLmKhQxw4UtjJixhlpPiVktucf3HMiKf8CdBUrmQk9io20ppB+Fq9vlgcitKj1MXVuE +JnHEhV5xJMqlG2zYYdMa4FTbzrqpMrUi9nNBCV24F10OD5mQ1kfabwo6YigUZ4LZ8dCAWZvLMdib +D4x3TrVoivJs9iQOLWxwxXPR3hTQcY+203sC9uO41Alua551hDnmfyWl8kgAwKQB2j8= +-----END CERTIFICATE----- + +StartCom Certification Authority G2 +=================================== +-----BEGIN CERTIFICATE----- +MIIFYzCCA0ugAwIBAgIBOzANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJJTDEWMBQGA1UEChMN +U3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg +RzIwHhcNMTAwMTAxMDEwMDAxWhcNMzkxMjMxMjM1OTAxWjBTMQswCQYDVQQGEwJJTDEWMBQGA1UE +ChMNU3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3Jp +dHkgRzIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2iTZbB7cgNr2Cu+EWIAOVeq8O +o1XJJZlKxdBWQYeQTSFgpBSHO839sj60ZwNq7eEPS8CRhXBF4EKe3ikj1AENoBB5uNsDvfOpL9HG +4A/LnooUCri99lZi8cVytjIl2bLzvWXFDSxu1ZJvGIsAQRSCb0AgJnooD/Uefyf3lLE3PbfHkffi +Aez9lInhzG7TNtYKGXmu1zSCZf98Qru23QumNK9LYP5/Q0kGi4xDuFby2X8hQxfqp0iVAXV16iul +Q5XqFYSdCI0mblWbq9zSOdIxHWDirMxWRST1HFSr7obdljKF+ExP6JV2tgXdNiNnvP8V4so75qbs +O+wmETRIjfaAKxojAuuKHDp2KntWFhxyKrOq42ClAJ8Em+JvHhRYW6Vsi1g8w7pOOlz34ZYrPu8H +vKTlXcxNnw3h3Kq74W4a7I/htkxNeXJdFzULHdfBR9qWJODQcqhaX2YtENwvKhOuJv4KHBnM0D4L +nMgJLvlblnpHnOl68wVQdJVznjAJ85eCXuaPOQgeWeU1FEIT/wCc976qUM/iUUjXuG+v+E5+M5iS +FGI6dWPPe/regjupuznixL0sAA7IF6wT700ljtizkC+p2il9Ha90OrInwMEePnWjFqmveiJdnxMa +z6eg6+OGCtP95paV1yPIN93EfKo2rJgaErHgTuixO/XWb/Ew1wIDAQABo0IwQDAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUS8W0QGutHLOlHGVuRjaJhwUMDrYwDQYJ +KoZIhvcNAQELBQADggIBAHNXPyzVlTJ+N9uWkusZXn5T50HsEbZH77Xe7XRcxfGOSeD8bpkTzZ+K +2s06Ctg6Wgk/XzTQLwPSZh0avZyQN8gMjgdalEVGKua+etqhqaRpEpKwfTbURIfXUfEpY9Z1zRbk +J4kd+MIySP3bmdCPX1R0zKxnNBFi2QwKN4fRoxdIjtIXHfbX/dtl6/2o1PXWT6RbdejF0mCy2wl+ +JYt7ulKSnj7oxXehPOBKc2thz4bcQ///If4jXSRK9dNtD2IEBVeC2m6kMyV5Sy5UGYvMLD0w6dEG +/+gyRr61M3Z3qAFdlsHB1b6uJcDJHgoJIIihDsnzb02CVAAgp9KP5DlUFy6NHrgbuxu9mk47EDTc +nIhT76IxW1hPkWLIwpqazRVdOKnWvvgTtZ8SafJQYqz7Fzf07rh1Z2AQ+4NQ+US1dZxAF7L+/Xld +blhYXzD8AK6vM8EOTmy6p6ahfzLbOOCxchcKK5HsamMm7YnUeMx0HgX4a/6ManY5Ka5lIxKVCCIc +l85bBu4M4ru8H0ST9tg4RQUh7eStqxK2A6RCLi3ECToDZ2mEmuFZkIoohdVddLHRDiBYmxOlsGOm +7XtH/UVVMKTumtTm4ofvmMkyghEpIrwACjFeLQ/Ajulrso8uBtjRkcfGEvRM/TAXw8HaOFvjqerm +obp573PYtlNXLfbQ4ddI +-----END CERTIFICATE----- + +Buypass Class 2 Root CA +======================= +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU +QnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3MgQ2xhc3MgMiBSb290IENBMB4X +DTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1owTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1 +eXBhc3MgQVMtOTgzMTYzMzI3MSAwHgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIw +DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1 +g1Lr6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPVL4O2fuPn +9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC911K2GScuVr1QGbNgGE41b +/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHxMlAQTn/0hpPshNOOvEu/XAFOBz3cFIqU +CqTqc/sLUegTBxj6DvEr0VQVfTzh97QZQmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeff +awrbD02TTqigzXsu8lkBarcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgI +zRFo1clrUs3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLiFRhn +Bkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRSP/TizPJhk9H9Z2vX +Uq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN9SG9dKpN6nIDSdvHXx1iY8f93ZHs +M+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxPAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD +VR0OBBYEFMmAd+BikoL1RpzzuvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsF +AAOCAgEAU18h9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s +A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3tOluwlN5E40EI +osHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo+fsicdl9sz1Gv7SEr5AcD48S +aq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYd +DnkM/crqJIByw5c/8nerQyIKx+u2DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWD +LfJ6v9r9jv6ly0UsH8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0 +oyLQI+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK75t98biGC +wWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h3PFaTWwyI0PurKju7koS +CTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPzY11aWOIv4x3kqdbQCtCev9eBCfHJxyYN +rJgWVqA= +-----END CERTIFICATE----- + +Buypass Class 3 Root CA +======================= +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU +QnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3MgQ2xhc3MgMyBSb290IENBMB4X +DTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFowTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1 +eXBhc3MgQVMtOTgzMTYzMzI3MSAwHgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIw +DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRH +sJ8YZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3EN3coTRiR +5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9tznDDgFHmV0ST9tD+leh +7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX0DJq1l1sDPGzbjniazEuOQAnFN44wOwZ +ZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH +2xc519woe2v1n/MuwU8XKhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV +/afmiSTYzIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvSO1UQ +RwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D34xFMFbG02SrZvPA +Xpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgPK9Dx2hzLabjKSWJtyNBjYt1gD1iq +j6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD +VR0OBBYEFEe4zf/lb+74suwvTg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsF +AAOCAgEAACAjQTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV +cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXSIGrs/CIBKM+G +uIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2HJLw5QY33KbmkJs4j1xrG0aG +Q0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsaO5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8 +ZORK15FTAaggiG6cX0S5y2CBNOxv033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2 +KSb12tjE8nVhz36udmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz +6MkEkbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg413OEMXbug +UZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvDu79leNKGef9JOxqDDPDe +eOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq4/g7u9xN12TyUb7mqqta6THuBrxzvxNi +Cp/HuZc= +-----END CERTIFICATE----- + +T-TeleSec GlobalRoot Class 3 +============================ +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoM +IlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBU +cnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgx +MDAxMTAyOTU2WhcNMzMxMDAxMjM1OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lz +dGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBD +ZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN8ELg63iIVl6bmlQdTQyK +9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/RLyTPWGrTs0NvvAgJ1gORH8EGoel15YU +NpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZF +iP0Zf3WHHx+xGwpzJFu5ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W +0eDrXltMEnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGjQjBA +MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1A/d2O2GCahKqGFPr +AyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOyWL6ukK2YJ5f+AbGwUgC4TeQbIXQb +fsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzT +ucpH9sry9uetuUg/vBa3wW306gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7h +P0HHRwA11fXT91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml +e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4pTpPDpFQUWw== +-----END CERTIFICATE----- + +EE Certification Centre Root CA +=============================== +-----BEGIN CERTIFICATE----- +MIIEAzCCAuugAwIBAgIQVID5oHPtPwBMyonY43HmSjANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQG +EwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1czEoMCYGA1UEAwwfRUUgQ2Vy +dGlmaWNhdGlvbiBDZW50cmUgUm9vdCBDQTEYMBYGCSqGSIb3DQEJARYJcGtpQHNrLmVlMCIYDzIw +MTAxMDMwMTAxMDMwWhgPMjAzMDEyMTcyMzU5NTlaMHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlB +UyBTZXJ0aWZpdHNlZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRy +ZSBSb290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWUwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQDIIMDs4MVLqwd4lfNE7vsLDP90jmG7sWLqI9iroWUyeuuOF0+W2Ap7kaJjbMeM +TC55v6kF/GlclY1i+blw7cNRfdCT5mzrMEvhvH2/UpvObntl8jixwKIy72KyaOBhU8E2lf/slLo2 +rpwcpzIP5Xy0xm90/XsY6KxX7QYgSzIwWFv9zajmofxwvI6Sc9uXp3whrj3B9UiHbCe9nyV0gVWw +93X2PaRka9ZP585ArQ/dMtO8ihJTmMmJ+xAdTX7Nfh9WDSFwhfYggx/2uh8Ej+p3iDXE/+pOoYtN +P2MbRMNE1CV2yreN1x5KZmTNXMWcg+HCCIia7E6j8T4cLNlsHaFLAgMBAAGjgYowgYcwDwYDVR0T +AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBLyWj7qVhy/zQas8fElyalL1BSZ +MEUGA1UdJQQ+MDwGCCsGAQUFBwMCBggrBgEFBQcDAQYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEF +BQcDCAYIKwYBBQUHAwkwDQYJKoZIhvcNAQEFBQADggEBAHv25MANqhlHt01Xo/6tu7Fq1Q+e2+Rj +xY6hUFaTlrg4wCQiZrxTFGGVv9DHKpY5P30osxBAIWrEr7BSdxjhlthWXePdNl4dp1BUoMUq5KqM +lIpPnTX/dqQGE5Gion0ARD9V04I8GtVbvFZMIi5GQ4okQC3zErg7cBqklrkar4dBGmoYDQZPxz5u +uSlNDUmJEYcyW+ZLBMjkXOZ0c5RdFpgTlf7727FE5TpwrDdr5rMzcijJs1eg9gIWiAYLtqZLICjU +3j2LrTcFU3T+bsy8QxdxXvnFzBqpYe73dgzzcvRyrc9yAjYHR8/vGVCJYMzpJJUPwssd8m92kMfM +dcGWxZ0= +-----END CERTIFICATE----- + +TURKTRUST Certificate Services Provider Root 2007 +================================================= +-----BEGIN CERTIFICATE----- +MIIEPTCCAyWgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvzE/MD0GA1UEAww2VMOcUktUUlVTVCBF +bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJUUjEP +MA0GA1UEBwwGQW5rYXJhMV4wXAYDVQQKDFVUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUg +QmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLiAoYykgQXJhbMSxayAyMDA3MB4X +DTA3MTIyNTE4MzcxOVoXDTE3MTIyMjE4MzcxOVowgb8xPzA9BgNVBAMMNlTDnFJLVFJVU1QgRWxl +a3Ryb25payBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsTELMAkGA1UEBhMCVFIxDzAN +BgNVBAcMBkFua2FyYTFeMFwGA1UECgxVVMOcUktUUlVTVCBCaWxnaSDEsGxldGnFn2ltIHZlIEJp +bGnFn2ltIEfDvHZlbmxpxJ9pIEhpem1ldGxlcmkgQS7Fni4gKGMpIEFyYWzEsWsgMjAwNzCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKu3PgqMyKVYFeaK7yc9SrToJdPNM8Ig3BnuiD9N +YvDdE3ePYakqtdTyuTFYKTsvP2qcb3N2Je40IIDu6rfwxArNK4aUyeNgsURSsloptJGXg9i3phQv +KUmi8wUG+7RP2qFsmmaf8EMJyupyj+sA1zU511YXRxcw9L6/P8JorzZAwan0qafoEGsIiveGHtya +KhUG9qPw9ODHFNRRf8+0222vR5YXm3dx2KdxnSQM9pQ/hTEST7ruToK4uT6PIzdezKKqdfcYbwnT +rqdUKDT74eA7YH2gvnmJhsifLfkKS8RQouf9eRbHegsYz85M733WB2+Y8a+xwXrXgTW4qhe04MsC +AwEAAaNCMEAwHQYDVR0OBBYEFCnFkKslrxHkYb+j/4hhkeYO/pyBMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQAQDdr4Ouwo0RSVgrESLFF6QSU2TJ/s +Px+EnWVUXKgWAkD6bho3hO9ynYYKVZ1WKKxmLNA6VpM0ByWtCLCPyA8JWcqdmBzlVPi5RX9ql2+I +aE1KBiY3iAIOtsbWcpnOa3faYjGkVh+uX4132l32iPwa2Z61gfAyuOOI0JzzaqC5mxRZNTZPz/OO +Xl0XrRWV2N2y1RVuAE6zS89mlOTgzbUF2mNXi+WzqtvALhyQRNsaXRik7r4EW5nVcV9VZWRi1aKb +BFmGyGJ353yCRWo9F7/snXUMrqNvWtMvmDb08PUZqxFdyKbjKlhqQgnDvZImZjINXQhVdP+MmNAK +poRq0Tl9 +-----END CERTIFICATE----- + +D-TRUST Root Class 3 CA 2 2009 +============================== +-----BEGIN CERTIFICATE----- +MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQK +DAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTAe +Fw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NThaME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxE +LVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOAD +ER03UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42tSHKXzlA +BF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9RySPocq60vFYJfxLLHLGv +KZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsMlFqVlNpQmvH/pStmMaTJOKDfHR+4CS7z +p+hnUquVH+BGPtikw8paxTGA6Eian5Rp/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUC +AwEAAaOCARowggEWMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ +4PGEMA4GA1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVjdG9y +eS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUyMENBJTIwMiUyMDIw +MDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRlcmV2b2NhdGlvbmxpc3QwQ6BBoD+G +PWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAw +OS5jcmwwDQYJKoZIhvcNAQELBQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm +2H6NMLVwMeniacfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0 +o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4KzCUqNQT4YJEV +dT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8PIWmawomDeCTmGCufsYkl4ph +X5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3YJohw1+qRzT65ysCQblrGXnRl11z+o+I= +-----END CERTIFICATE----- + +D-TRUST Root Class 3 CA 2 EV 2009 +================================= +-----BEGIN CERTIFICATE----- +MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQK +DAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAw +OTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUwNDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQK +DAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAw +OTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfS +egpnljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM03TP1YtHh +zRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6ZqQTMFexgaDbtCHu39b+T +7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lRp75mpoo6Kr3HGrHhFPC+Oh25z1uxav60 +sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure35 +11H3a6UCAwEAAaOCASQwggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyv +cop9NteaHNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFwOi8v +ZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xhc3MlMjAzJTIwQ0El +MjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1ERT9jZXJ0aWZpY2F0ZXJldm9jYXRp +b25saXN0MEagRKBChkBodHRwOi8vd3d3LmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xh +c3NfM19jYV8yX2V2XzIwMDkuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+ +PPoeUSbrh/Yp3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05 +nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNFCSuGdXzfX2lX +ANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7naxpeG0ILD5EJt/rDiZE4OJudA +NCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqXKVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVv +w9y4AyHqnxbxLFS1 +-----END CERTIFICATE----- + +PSCProcert +========== +-----BEGIN CERTIFICATE----- +MIIJhjCCB26gAwIBAgIBCzANBgkqhkiG9w0BAQsFADCCAR4xPjA8BgNVBAMTNUF1dG9yaWRhZCBk +ZSBDZXJ0aWZpY2FjaW9uIFJhaXogZGVsIEVzdGFkbyBWZW5lem9sYW5vMQswCQYDVQQGEwJWRTEQ +MA4GA1UEBxMHQ2FyYWNhczEZMBcGA1UECBMQRGlzdHJpdG8gQ2FwaXRhbDE2MDQGA1UEChMtU2lz +dGVtYSBOYWNpb25hbCBkZSBDZXJ0aWZpY2FjaW9uIEVsZWN0cm9uaWNhMUMwQQYDVQQLEzpTdXBl +cmludGVuZGVuY2lhIGRlIFNlcnZpY2lvcyBkZSBDZXJ0aWZpY2FjaW9uIEVsZWN0cm9uaWNhMSUw +IwYJKoZIhvcNAQkBFhZhY3JhaXpAc3VzY2VydGUuZ29iLnZlMB4XDTEwMTIyODE2NTEwMFoXDTIw +MTIyNTIzNTk1OVowgdExJjAkBgkqhkiG9w0BCQEWF2NvbnRhY3RvQHByb2NlcnQubmV0LnZlMQ8w +DQYDVQQHEwZDaGFjYW8xEDAOBgNVBAgTB01pcmFuZGExKjAoBgNVBAsTIVByb3ZlZWRvciBkZSBD +ZXJ0aWZpY2Fkb3MgUFJPQ0VSVDE2MDQGA1UEChMtU2lzdGVtYSBOYWNpb25hbCBkZSBDZXJ0aWZp +Y2FjaW9uIEVsZWN0cm9uaWNhMQswCQYDVQQGEwJWRTETMBEGA1UEAxMKUFNDUHJvY2VydDCCAiIw +DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANW39KOUM6FGqVVhSQ2oh3NekS1wwQYalNo97BVC +wfWMrmoX8Yqt/ICV6oNEolt6Vc5Pp6XVurgfoCfAUFM+jbnADrgV3NZs+J74BCXfgI8Qhd19L3uA +3VcAZCP4bsm+lU/hdezgfl6VzbHvvnpC2Mks0+saGiKLt38GieU89RLAu9MLmV+QfI4tL3czkkoh +RqipCKzx9hEC2ZUWno0vluYC3XXCFCpa1sl9JcLB/KpnheLsvtF8PPqv1W7/U0HU9TI4seJfxPmO +EO8GqQKJ/+MMbpfg353bIdD0PghpbNjU5Db4g7ayNo+c7zo3Fn2/omnXO1ty0K+qP1xmk6wKImG2 +0qCZyFSTXai20b1dCl53lKItwIKOvMoDKjSuc/HUtQy9vmebVOvh+qBa7Dh+PsHMosdEMXXqP+UH +0quhJZb25uSgXTcYOWEAM11G1ADEtMo88aKjPvM6/2kwLkDd9p+cJsmWN63nOaK/6mnbVSKVUyqU +td+tFjiBdWbjxywbk5yqjKPK2Ww8F22c3HxT4CAnQzb5EuE8XL1mv6JpIzi4mWCZDlZTOpx+FIyw +Bm/xhnaQr/2v/pDGj59/i5IjnOcVdo/Vi5QTcmn7K2FjiO/mpF7moxdqWEfLcU8UC17IAggmosvp +r2uKGcfLFFb14dq12fy/czja+eevbqQ34gcnAgMBAAGjggMXMIIDEzASBgNVHRMBAf8ECDAGAQH/ +AgEBMDcGA1UdEgQwMC6CD3N1c2NlcnRlLmdvYi52ZaAbBgVghl4CAqASDBBSSUYtRy0yMDAwNDAz +Ni0wMB0GA1UdDgQWBBRBDxk4qpl/Qguk1yeYVKIXTC1RVDCCAVAGA1UdIwSCAUcwggFDgBStuyId +xuDSAaj9dlBSk+2YwU2u06GCASakggEiMIIBHjE+MDwGA1UEAxM1QXV0b3JpZGFkIGRlIENlcnRp +ZmljYWNpb24gUmFpeiBkZWwgRXN0YWRvIFZlbmV6b2xhbm8xCzAJBgNVBAYTAlZFMRAwDgYDVQQH +EwdDYXJhY2FzMRkwFwYDVQQIExBEaXN0cml0byBDYXBpdGFsMTYwNAYDVQQKEy1TaXN0ZW1hIE5h +Y2lvbmFsIGRlIENlcnRpZmljYWNpb24gRWxlY3Ryb25pY2ExQzBBBgNVBAsTOlN1cGVyaW50ZW5k +ZW5jaWEgZGUgU2VydmljaW9zIGRlIENlcnRpZmljYWNpb24gRWxlY3Ryb25pY2ExJTAjBgkqhkiG +9w0BCQEWFmFjcmFpekBzdXNjZXJ0ZS5nb2IudmWCAQowDgYDVR0PAQH/BAQDAgEGME0GA1UdEQRG +MESCDnByb2NlcnQubmV0LnZloBUGBWCGXgIBoAwMClBTQy0wMDAwMDKgGwYFYIZeAgKgEgwQUklG +LUotMzE2MzUzNzMtNzB2BgNVHR8EbzBtMEagRKBChkBodHRwOi8vd3d3LnN1c2NlcnRlLmdvYi52 +ZS9sY3IvQ0VSVElGSUNBRE8tUkFJWi1TSEEzODRDUkxERVIuY3JsMCOgIaAfhh1sZGFwOi8vYWNy +YWl6LnN1c2NlcnRlLmdvYi52ZTA3BggrBgEFBQcBAQQrMCkwJwYIKwYBBQUHMAGGG2h0dHA6Ly9v +Y3NwLnN1c2NlcnRlLmdvYi52ZTBBBgNVHSAEOjA4MDYGBmCGXgMBAjAsMCoGCCsGAQUFBwIBFh5o +dHRwOi8vd3d3LnN1c2NlcnRlLmdvYi52ZS9kcGMwDQYJKoZIhvcNAQELBQADggIBACtZ6yKZu4Sq +T96QxtGGcSOeSwORR3C7wJJg7ODU523G0+1ng3dS1fLld6c2suNUvtm7CpsR72H0xpkzmfWvADmN +g7+mvTV+LFwxNG9s2/NkAZiqlCxB3RWGymspThbASfzXg0gTB1GEMVKIu4YXx2sviiCtxQuPcD4q +uxtxj7mkoP3YldmvWb8lK5jpY5MvYB7Eqvh39YtsL+1+LrVPQA3uvFd359m21D+VJzog1eWuq2w1 +n8GhHVnchIHuTQfiSLaeS5UtQbHh6N5+LwUeaO6/u5BlOsju6rEYNxxik6SgMexxbJHmpHmJWhSn +FFAFTKQAVzAswbVhltw+HoSvOULP5dAssSS830DD7X9jSr3hTxJkhpXzsOfIt+FTvZLm8wyWuevo +5pLtp4EJFAv8lXrPj9Y0TzYS3F7RNHXGRoAvlQSMx4bEqCaJqD8Zm4G7UaRKhqsLEQ+xrmNTbSjq +3TNWOByyrYDT13K9mmyZY+gAu0F2BbdbmRiKw7gSXFbPVgx96OLP7bx0R/vu0xdOIk9W/1DzLuY5 +poLWccret9W6aAjtmcz9opLLabid+Qqkpj5PkygqYWwHJgD/ll9ohri4zspV4KuxPX+Y1zMOWj3Y +eMLEYC/HYvBhkdI4sPaeVdtAgAUSM84dkpvRabP/v/GSCmE1P93+hvS84Bpxs2Km +-----END CERTIFICATE----- + +China Internet Network Information Center EV Certificates Root +============================================================== +-----BEGIN CERTIFICATE----- +MIID9zCCAt+gAwIBAgIESJ8AATANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMCQ04xMjAwBgNV +BAoMKUNoaW5hIEludGVybmV0IE5ldHdvcmsgSW5mb3JtYXRpb24gQ2VudGVyMUcwRQYDVQQDDD5D +aGluYSBJbnRlcm5ldCBOZXR3b3JrIEluZm9ybWF0aW9uIENlbnRlciBFViBDZXJ0aWZpY2F0ZXMg +Um9vdDAeFw0xMDA4MzEwNzExMjVaFw0zMDA4MzEwNzExMjVaMIGKMQswCQYDVQQGEwJDTjEyMDAG +A1UECgwpQ2hpbmEgSW50ZXJuZXQgTmV0d29yayBJbmZvcm1hdGlvbiBDZW50ZXIxRzBFBgNVBAMM +PkNoaW5hIEludGVybmV0IE5ldHdvcmsgSW5mb3JtYXRpb24gQ2VudGVyIEVWIENlcnRpZmljYXRl +cyBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm35z7r07eKpkQ0H1UN+U8i6y +jUqORlTSIRLIOTJCBumD1Z9S7eVnAztUwYyZmczpwA//DdmEEbK40ctb3B75aDFk4Zv6dOtouSCV +98YPjUesWgbdYavi7NifFy2cyjw1l1VxzUOFsUcW9SxTgHbP0wBkvUCZ3czY28Sf1hNfQYOL+Q2H +klY0bBoQCxfVWhyXWIQ8hBouXJE0bhlffxdpxWXvayHG1VA6v2G5BY3vbzQ6sm8UY78WO5upKv23 +KzhmBsUs4qpnHkWnjQRmQvaPK++IIGmPMowUc9orhpFjIpryp9vOiYurXccUwVswah+xt54ugQEC +7c+WXmPbqOY4twIDAQABo2MwYTAfBgNVHSMEGDAWgBR8cks5x8DbYqVPm6oYNJKiyoOCWTAPBgNV +HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUfHJLOcfA22KlT5uqGDSSosqD +glkwDQYJKoZIhvcNAQEFBQADggEBACrDx0M3j92tpLIM7twUbY8opJhJywyA6vPtI2Z1fcXTIWd5 +0XPFtQO3WKwMVC/GVhMPMdoG52U7HW8228gd+f2ABsqjPWYWqJ1MFn3AlUa1UeTiH9fqBk1jjZaM +7+czV0I664zBechNdn3e9rG3geCg+aF4RhcaVpjwTj2rHO3sOdwHSPdj/gauwqRcalsyiMXHM4Ws +ZkJHwlgkmeHlPuV1LI5D1l08eB6olYIpUNHRFrrvwb562bTYzB5MRuF3sTGrvSrIzo9uoV1/A3U0 +5K2JRVRevq4opbs/eHnrc7MKDf2+yfdWrPa37S+bISnHOLaVxATywy39FCqQmbkHzJ8= +-----END CERTIFICATE----- + +Swisscom Root CA 2 +================== +-----BEGIN CERTIFICATE----- +MIIF2TCCA8GgAwIBAgIQHp4o6Ejy5e/DfEoeWhhntjANBgkqhkiG9w0BAQsFADBkMQswCQYDVQQG +EwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0YWwgQ2VydGlmaWNhdGUgU2Vy +dmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3QgQ0EgMjAeFw0xMTA2MjQwODM4MTRaFw0zMTA2 +MjUwNzM4MTRaMGQxCzAJBgNVBAYTAmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGln +aXRhbCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAyMIIC +IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAlUJOhJ1R5tMJ6HJaI2nbeHCOFvErjw0DzpPM +LgAIe6szjPTpQOYXTKueuEcUMncy3SgM3hhLX3af+Dk7/E6J2HzFZ++r0rk0X2s682Q2zsKwzxNo +ysjL67XiPS4h3+os1OD5cJZM/2pYmLcX5BtS5X4HAB1f2uY+lQS3aYg5oUFgJWFLlTloYhyxCwWJ +wDaCFCE/rtuh/bxvHGCGtlOUSbkrRsVPACu/obvLP+DHVxxX6NZp+MEkUp2IVd3Chy50I9AU/SpH +Wrumnf2U5NGKpV+GY3aFy6//SSj8gO1MedK75MDvAe5QQQg1I3ArqRa0jG6F6bYRzzHdUyYb3y1a +SgJA/MTAtukxGggo5WDDH8SQjhBiYEQN7Aq+VRhxLKX0srwVYv8c474d2h5Xszx+zYIdkeNL6yxS +NLCK/RJOlrDrcH+eOfdmQrGrrFLadkBXeyq96G4DsguAhYidDMfCd7Camlf0uPoTXGiTOmekl9Ab +mbeGMktg2M7v0Ax/lZ9vh0+Hio5fCHyqW/xavqGRn1V9TrALacywlKinh/LTSlDcX3KwFnUey7QY +Ypqwpzmqm59m2I2mbJYV4+by+PGDYmy7Velhk6M99bFXi08jsJvllGov34zflVEpYKELKeRcVVi3 +qPyZ7iVNTA6z00yPhOgpD/0QVAKFyPnlw4vP5w8CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYw +HQYDVR0hBBYwFDASBgdghXQBUwIBBgdghXQBUwIBMBIGA1UdEwEB/wQIMAYBAf8CAQcwHQYDVR0O +BBYEFE0mICKJS9PVpAqhb97iEoHF8TwuMB8GA1UdIwQYMBaAFE0mICKJS9PVpAqhb97iEoHF8Twu +MA0GCSqGSIb3DQEBCwUAA4ICAQAyCrKkG8t9voJXiblqf/P0wS4RfbgZPnm3qKhyN2abGu2sEzsO +v2LwnN+ee6FTSA5BesogpxcbtnjsQJHzQq0Qw1zv/2BZf82Fo4s9SBwlAjxnffUy6S8w5X2lejjQ +82YqZh6NM4OKb3xuqFp1mrjX2lhIREeoTPpMSQpKwhI3qEAMw8jh0FcNlzKVxzqfl9NX+Ave5XLz +o9v/tdhZsnPdTSpxsrpJ9csc1fV5yJmz/MFMdOO0vSk3FQQoHt5FRnDsr7p4DooqzgB53MBfGWcs +a0vvaGgLQ+OswWIJ76bdZWGgr4RVSJFSHMYlkSrQwSIjYVmvRRGFHQEkNI/Ps/8XciATwoCqISxx +OQ7Qj1zB09GOInJGTB2Wrk9xseEFKZZZ9LuedT3PDTcNYtsmjGOpI99nBjx8Oto0QuFmtEYE3saW +mA9LSHokMnWRn6z3aOkquVVlzl1h0ydw2Df+n7mvoC5Wt6NlUe07qxS/TFED6F+KBZvuim6c779o ++sjaC+NCydAXFJy3SuCvkychVSa1ZC+N8f+mQAWFBVzKBxlcCxMoTFh/wqXvRdpg065lYZ1Tg3TC +rvJcwhbtkj6EPnNgiLx29CzP0H1907he0ZESEOnN3col49XtmS++dYFLJPlFRpTJKSFTnCZFqhMX +5OfNeOI5wSsSnqaeG8XmDtkx2Q== +-----END CERTIFICATE----- + +Swisscom Root EV CA 2 +===================== +-----BEGIN CERTIFICATE----- +MIIF4DCCA8igAwIBAgIRAPL6ZOJ0Y9ON/RAdBB92ylgwDQYJKoZIhvcNAQELBQAwZzELMAkGA1UE +BhMCY2gxETAPBgNVBAoTCFN3aXNzY29tMSUwIwYDVQQLExxEaWdpdGFsIENlcnRpZmljYXRlIFNl +cnZpY2VzMR4wHAYDVQQDExVTd2lzc2NvbSBSb290IEVWIENBIDIwHhcNMTEwNjI0MDk0NTA4WhcN +MzEwNjI1MDg0NTA4WjBnMQswCQYDVQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsT +HERpZ2l0YWwgQ2VydGlmaWNhdGUgU2VydmljZXMxHjAcBgNVBAMTFVN3aXNzY29tIFJvb3QgRVYg +Q0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMT3HS9X6lds93BdY7BxUglgRCgz +o3pOCvrY6myLURYaVa5UJsTMRQdBTxB5f3HSek4/OE6zAMaVylvNwSqD1ycfMQ4jFrclyxy0uYAy +Xhqdk/HoPGAsp15XGVhRXrwsVgu42O+LgrQ8uMIkqBPHoCE2G3pXKSinLr9xJZDzRINpUKTk4Rti +GZQJo/PDvO/0vezbE53PnUgJUmfANykRHvvSEaeFGHR55E+FFOtSN+KxRdjMDUN/rhPSays/p8Li +qG12W0OfvrSdsyaGOx9/5fLoZigWJdBLlzin5M8J0TbDC77aO0RYjb7xnglrPvMyxyuHxuxenPaH +Za0zKcQvidm5y8kDnftslFGXEBuGCxobP/YCfnvUxVFkKJ3106yDgYjTdLRZncHrYTNaRdHLOdAG +alNgHa/2+2m8atwBz735j9m9W8E6X47aD0upm50qKGsaCnw8qyIL5XctcfaCNYGu+HuB5ur+rPQa +m3Rc6I8k9l2dRsQs0h4rIWqDJ2dVSqTjyDKXZpBy2uPUZC5f46Fq9mDU5zXNysRojddxyNMkM3Ox +bPlq4SjbX8Y96L5V5jcb7STZDxmPX2MYWFCBUWVv8p9+agTnNCRxunZLWB4ZvRVgRaoMEkABnRDi +xzgHcgplwLa7JSnaFp6LNYth7eVxV4O1PHGf40+/fh6Bn0GXAgMBAAGjgYYwgYMwDgYDVR0PAQH/ +BAQDAgGGMB0GA1UdIQQWMBQwEgYHYIV0AVMCAgYHYIV0AVMCAjASBgNVHRMBAf8ECDAGAQH/AgED +MB0GA1UdDgQWBBRF2aWBbj2ITY1x0kbBbkUe88SAnTAfBgNVHSMEGDAWgBRF2aWBbj2ITY1x0kbB +bkUe88SAnTANBgkqhkiG9w0BAQsFAAOCAgEAlDpzBp9SSzBc1P6xXCX5145v9Ydkn+0UjrgEjihL +j6p7jjm02Vj2e6E1CqGdivdj5eu9OYLU43otb98TPLr+flaYC/NUn81ETm484T4VvwYmneTwkLbU +wp4wLh/vx3rEUMfqe9pQy3omywC0Wqu1kx+AiYQElY2NfwmTv9SoqORjbdlk5LgpWgi/UOGED1V7 +XwgiG/W9mR4U9s70WBCCswo9GcG/W6uqmdjyMb3lOGbcWAXH7WMaLgqXfIeTK7KK4/HsGOV1timH +59yLGn602MnTihdsfSlEvoqq9X46Lmgxk7lq2prg2+kupYTNHAq4Sgj5nPFhJpiTt3tm7JFe3VE/ +23MPrQRYCd0EApUKPtN236YQHoA96M2kZNEzx5LH4k5E4wnJTsJdhw4Snr8PyQUQ3nqjsTzyP6Wq +J3mtMX0f/fwZacXduT98zca0wjAefm6S139hdlqP65VNvBFuIXxZN5nQBrz5Bm0yFqXZaajh3DyA +HmBR3NdUIR7KYndP+tiPsys6DXhyyWhBWkdKwqPrGtcKqzwyVcgKEZzfdNbwQBUdyLmPtTbFr/gi +uMod89a2GQ+fYWVq6nTIfI/DT11lgh/ZDYnadXL77/FHZxOzyNEZiCcmmpl5fx7kLD977vHeTYuW +l8PVP3wbI+2ksx0WckNLIOFZfsLorSa/ovc= +-----END CERTIFICATE----- + +CA Disig Root R1 +================ +-----BEGIN CERTIFICATE----- +MIIFaTCCA1GgAwIBAgIJAMMDmu5QkG4oMA0GCSqGSIb3DQEBBQUAMFIxCzAJBgNVBAYTAlNLMRMw +EQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMuMRkwFwYDVQQDExBDQSBEaXNp +ZyBSb290IFIxMB4XDTEyMDcxOTA5MDY1NloXDTQyMDcxOTA5MDY1NlowUjELMAkGA1UEBhMCU0sx +EzARBgNVBAcTCkJyYXRpc2xhdmExEzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERp +c2lnIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCqw3j33Jijp1pedxiy +3QRkD2P9m5YJgNXoqqXinCaUOuiZc4yd39ffg/N4T0Dhf9Kn0uXKE5Pn7cZ3Xza1lK/oOI7bm+V8 +u8yN63Vz4STN5qctGS7Y1oprFOsIYgrY3LMATcMjfF9DCCMyEtztDK3AfQ+lekLZWnDZv6fXARz2 +m6uOt0qGeKAeVjGu74IKgEH3G8muqzIm1Cxr7X1r5OJeIgpFy4QxTaz+29FHuvlglzmxZcfe+5nk +CiKxLU3lSCZpq+Kq8/v8kiky6bM+TR8noc2OuRf7JT7JbvN32g0S9l3HuzYQ1VTW8+DiR0jm3hTa +YVKvJrT1cU/J19IG32PK/yHoWQbgCNWEFVP3Q+V8xaCJmGtzxmjOZd69fwX3se72V6FglcXM6pM6 +vpmumwKjrckWtc7dXpl4fho5frLABaTAgqWjR56M6ly2vGfb5ipN0gTco65F97yLnByn1tUD3AjL +LhbKXEAz6GfDLuemROoRRRw1ZS0eRWEkG4IupZ0zXWX4Qfkuy5Q/H6MMMSRE7cderVC6xkGbrPAX +ZcD4XW9boAo0PO7X6oifmPmvTiT6l7Jkdtqr9O3jw2Dv1fkCyC2fg69naQanMVXVz0tv/wQFx1is +XxYb5dKj6zHbHzMVTdDypVP1y+E9Tmgt2BLdqvLmTZtJ5cUoobqwWsagtQIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUiQq0OJMa5qvum5EY+fU8PjXQ +04IwDQYJKoZIhvcNAQEFBQADggIBADKL9p1Kyb4U5YysOMo6CdQbzoaz3evUuii+Eq5FLAR0rBNR +xVgYZk2C2tXck8An4b58n1KeElb21Zyp9HWc+jcSjxyT7Ff+Bw+r1RL3D65hXlaASfX8MPWbTx9B +LxyE04nH4toCdu0Jz2zBuByDHBb6lM19oMgY0sidbvW9adRtPTXoHqJPYNcHKfyyo6SdbhWSVhlM +CrDpfNIZTUJG7L399ldb3Zh+pE3McgODWF3vkzpBemOqfDqo9ayk0d2iLbYq/J8BjuIQscTK5Gfb +VSUZP/3oNn6z4eGBrxEWi1CXYBmCAMBrTXO40RMHPuq2MU/wQppt4hF05ZSsjYSVPCGvxdpHyN85 +YmLLW1AL14FABZyb7bq2ix4Eb5YgOe2kfSnbSM6C3NQCjR0EMVrHS/BsYVLXtFHCgWzN4funodKS +ds+xDzdYpPJScWc/DIh4gInByLUfkmO+p3qKViwaqKactV2zY9ATIKHrkWzQjX2v3wvkF7mGnjix +lAxYjOBVqjtjbZqJYLhkKpLGN/R+Q0O3c+gB53+XD9fyexn9GtePyfqFa3qdnom2piiZk4hA9z7N +UaPK6u95RyG1/jLix8NRb76AdPCkwzryT+lf3xkK8jsTQ6wxpLPn6/wY1gGp8yqPNg7rtLG8t0zJ +a7+h89n07eLw4+1knj0vllJPgFOL +-----END CERTIFICATE----- + +CA Disig Root R2 +================ +-----BEGIN CERTIFICATE----- +MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNVBAYTAlNLMRMw +EQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMuMRkwFwYDVQQDExBDQSBEaXNp +ZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQyMDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sx +EzARBgNVBAcTCkJyYXRpc2xhdmExEzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERp +c2lnIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbC +w3OeNcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNHPWSb6Wia +xswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3Ix2ymrdMxp7zo5eFm1tL7 +A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbeQTg06ov80egEFGEtQX6sx3dOy1FU+16S +GBsEWmjGycT6txOgmLcRK7fWV8x8nhfRyyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqV +g8NTEQxzHQuyRpDRQjrOQG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa +5Beny912H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJQfYE +koopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUDi/ZnWejBBhG93c+A +Ak9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORsnLMOPReisjQS1n6yqEm70XooQL6i +Fh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5u +Qu0wDQYJKoZIhvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM +tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqfGopTpti72TVV +sRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkblvdhuDvEK7Z4bLQjb/D907Je +dR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka+elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W8 +1k/BfDxujRNt+3vrMNDcTa/F1balTFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjx +mHHEt38OFdAlab0inSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01 +utI3gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18DrG5gPcFw0 +sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3OszMOl6W8KjptlwlCFtaOg +UxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8xL4ysEr3vQCj8KWefshNPZiTEUxnpHikV +7+ZtsH8tZ/3zbBt1RqPlShfppNcL +-----END CERTIFICATE----- + +ACCVRAIZ1 +========= +-----BEGIN CERTIFICATE----- +MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UEAwwJQUNDVlJB +SVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQswCQYDVQQGEwJFUzAeFw0xMTA1 +MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQBgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwH +UEtJQUNDVjENMAsGA1UECgwEQUNDVjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4IC +DwAwggIKAoICAQCbqau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gM +jmoYHtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWoG2ioPej0 +RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpAlHPrzg5XPAOBOp0KoVdD +aaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhrIA8wKFSVf+DuzgpmndFALW4ir50awQUZ +0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDG +WuzndN9wrqODJerWx5eHk6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs7 +8yM2x/474KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMOm3WR +5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpacXpkatcnYGMN285J +9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPluUsXQA+xtrn13k/c4LOsOxFwYIRK +Q26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYIKwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRw +Oi8vd3d3LmFjY3YuZXMvZmlsZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEu +Y3J0MB8GCCsGAQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2 +VuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeTVfZW6oHlNsyM +Hj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIGCCsGAQUFBwICMIIBFB6CARAA +QQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUAcgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBh +AO0AegAgAGQAZQAgAGwAYQAgAEEAQwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUA +YwBuAG8AbABvAGcA7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBj +AHQAcgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAAQwBQAFMA +IABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUAczAwBggrBgEFBQcCARYk +aHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2MuaHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0 +dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRtaW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2 +MV9kZXIuY3JsMA4GA1UdDwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZI +hvcNAQEFBQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdpD70E +R9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gUJyCpZET/LtZ1qmxN +YEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+mAM/EKXMRNt6GGT6d7hmKG9Ww7Y49 +nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepDvV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJ +TS+xJlsndQAJxGJ3KQhfnlmstn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3 +sCPdK6jT2iWH7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h +I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szAh1xA2syVP1Xg +Nce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xFd3+YJ5oyXSrjhO7FmGYvliAd +3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2HpPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3p +EfbRD0tVNEYqi4Y7 +-----END CERTIFICATE----- + +TWCA Global Root CA +=================== +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcxEjAQBgNVBAoT +CVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMTVFdDQSBHbG9iYWwgUm9vdCBD +QTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQK +EwlUQUlXQU4tQ0ExEDAOBgNVBAsTB1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3Qg +Q0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2C +nJfF10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz0ALfUPZV +r2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfChMBwqoJimFb3u/Rk28OKR +Q4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbHzIh1HrtsBv+baz4X7GGqcXzGHaL3SekV +tTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1W +KKD+u4ZqyPpcC1jcxkt2yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99 +sy2sbZCilaLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYPoA/p +yJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQABDzfuBSO6N+pjWxn +kjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcEqYSjMq+u7msXi7Kx/mzhkIyIqJdI +zshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMC +AQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6g +cFGn90xHNcgL1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn +LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WFH6vPNOw/KP4M +8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNoRI2T9GRwoD2dKAXDOXC4Ynsg +/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlg +lPx4mI88k1HtQJAH32RjJMtOcQWh15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryP +A9gK8kxkRr05YuWW6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3m +i4TWnsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5jwa19hAM8 +EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWzaGHQRiapIVJpLesux+t3 +zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmyKwbQBM0= +-----END CERTIFICATE----- + +TeliaSonera Root CA v1 +====================== +-----BEGIN CERTIFICATE----- +MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAwNzEUMBIGA1UE +CgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJvb3QgQ0EgdjEwHhcNMDcxMDE4 +MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYDVQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwW +VGVsaWFTb25lcmEgUm9vdCBDQSB2MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+ +6yfwIaPzaSZVfp3FVRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA +3GV17CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+XZ75Ljo1k +B1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+/jXh7VB7qTCNGdMJjmhn +Xb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxH +oLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkmdtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3 +F0fUTPHSiXk+TT2YqGHeOh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJ +oWjiUIMusDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4pgd7 +gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fsslESl1MpWtTwEhDc +TwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQarMCpgKIv7NHfirZ1fpoeDVNAgMB +AAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qW +DNXr+nuqF+gTEjANBgkqhkiG9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNm +zqjMDfz1mgbldxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx +0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1TjTQpgcmLNkQfW +pb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBedY2gea+zDTYa4EzAvXUYNR0PV +G6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpc +c41teyWRyu5FrgZLAMzTsVlQ2jqIOylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOT +JsjrDNYmiLbAJM+7vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2 +qReWt88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcnHL/EVlP6 +Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVxSK236thZiNSQvxaz2ems +WWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY= +-----END CERTIFICATE----- + +E-Tugra Certification Authority +=============================== +-----BEGIN CERTIFICATE----- +MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNVBAYTAlRSMQ8w +DQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamls +ZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN +ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMw +NTEyMDk0OFoXDTIzMDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmEx +QDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxl +cmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQD +DB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEFAAOCAg8A +MIICCgKCAgEA4vU/kwVRHoViVF56C/UYB4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vd +hQd2h8y/L5VMzH2nPbxHD5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5K +CKpbknSFQ9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEoq1+g +ElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3Dk14opz8n8Y4e0ypQ +BaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcHfC425lAcP9tDJMW/hkd5s3kc91r0 +E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsutdEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gz +rt48Ue7LE3wBf4QOXVGUnhMMti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAq +jqFGOjGY5RH8zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn +rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUXU8u3Zg5mTPj5 +dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6Jyr+zE7S6E5UMA8GA1UdEwEB +/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEG +MA0GCSqGSIb3DQEBCwUAA4ICAQAFNzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAK +kEh47U6YA5n+KGCRHTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jO +XKqYGwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c77NCR807 +VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3+GbHeJAAFS6LrVE1Uweo +a2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WKvJUawSg5TB9D0pH0clmKuVb8P7Sd2nCc +dlqMQ1DujjByTd//SffGqWfZbawCEeI6FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEV +KV0jq9BgoRJP3vQXzTLlyb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gT +Dx4JnW2PAJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpDy4Q0 +8ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8dNL/+I5c30jn6PQ0G +C7TbO6Orb1wdtn7os4I07QZcJA== +-----END CERTIFICATE----- + +T-TeleSec GlobalRoot Class 2 +============================ +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoM +IlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBU +cnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgx +MDAxMTA0MDE0WhcNMzMxMDAxMjM1OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lz +dGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBD +ZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUdAqSzm1nzHoqvNK38DcLZ +SBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiCFoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/F +vudocP05l03Sx5iRUKrERLMjfTlH6VJi1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx970 +2cu+fjOlbpSD8DT6IavqjnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGV +WOHAD3bZwI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGjQjBA +MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/WSA2AHmgoCJrjNXy +YdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhyNsZt+U2e+iKo4YFWz827n+qrkRk4 +r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPACuvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNf +vNoBYimipidx5joifsFvHZVwIEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR +3p1m0IvVVGb6g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN +9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlPBSeOE6Fuwg== +-----END CERTIFICATE----- + +Atos TrustedRoot 2011 +===================== +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UEAwwVQXRvcyBU +cnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0xMTA3MDcxNDU4 +MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMMFUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsG +A1UECgwEQXRvczELMAkGA1UEBhMCREUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCV +hTuXbyo7LjvPpvMpNb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr +54rMVD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+SZFhyBH+ +DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ4J7sVaE3IqKHBAUsR320 +HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0Lcp2AMBYHlT8oDv3FdU9T1nSatCQujgKR +z3bFmx5VdJx4IbHwLfELn8LVlhgf8FQieowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7R +l+lwrrw7GWzbITAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZ +bNshMBgGA1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB +CwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8jvZfza1zv7v1Apt+h +k6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kPDpFrdRbhIfzYJsdHt6bPWHJxfrrh +TZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pcmaHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a9 +61qn8FYiqTxlVMYVqL2Gns2Dlmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G +3mB/ufNPRJLvKrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed +-----END CERTIFICATE----- + diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/StaticClient.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/StaticClient.php new file mode 100644 index 0000000..dbd4c18 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/StaticClient.php @@ -0,0 +1,157 @@ +createRequest($method, $url, null, null, $options); + + if (isset($options['stream'])) { + if ($options['stream'] instanceof StreamRequestFactoryInterface) { + return $options['stream']->fromRequest($request); + } elseif ($options['stream'] == true) { + $streamFactory = new PhpStreamRequestFactory(); + return $streamFactory->fromRequest($request); + } + } + + return $request->send(); + } + + /** + * Send a GET request + * + * @param string $url URL of the request + * @param array $options Array of request options + * + * @return \Guzzle\Http\Message\Response + * @see Guzzle::request for a list of available options + */ + public static function get($url, $options = array()) + { + return self::request('GET', $url, $options); + } + + /** + * Send a HEAD request + * + * @param string $url URL of the request + * @param array $options Array of request options + * + * @return \Guzzle\Http\Message\Response + * @see Guzzle::request for a list of available options + */ + public static function head($url, $options = array()) + { + return self::request('HEAD', $url, $options); + } + + /** + * Send a DELETE request + * + * @param string $url URL of the request + * @param array $options Array of request options + * + * @return \Guzzle\Http\Message\Response + * @see Guzzle::request for a list of available options + */ + public static function delete($url, $options = array()) + { + return self::request('DELETE', $url, $options); + } + + /** + * Send a POST request + * + * @param string $url URL of the request + * @param array $options Array of request options + * + * @return \Guzzle\Http\Message\Response + * @see Guzzle::request for a list of available options + */ + public static function post($url, $options = array()) + { + return self::request('POST', $url, $options); + } + + /** + * Send a PUT request + * + * @param string $url URL of the request + * @param array $options Array of request options + * + * @return \Guzzle\Http\Message\Response + * @see Guzzle::request for a list of available options + */ + public static function put($url, $options = array()) + { + return self::request('PUT', $url, $options); + } + + /** + * Send a PATCH request + * + * @param string $url URL of the request + * @param array $options Array of request options + * + * @return \Guzzle\Http\Message\Response + * @see Guzzle::request for a list of available options + */ + public static function patch($url, $options = array()) + { + return self::request('PATCH', $url, $options); + } + + /** + * Send an OPTIONS request + * + * @param string $url URL of the request + * @param array $options Array of request options + * + * @return \Guzzle\Http\Message\Response + * @see Guzzle::request for a list of available options + */ + public static function options($url, $options = array()) + { + return self::request('OPTIONS', $url, $options); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Url.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Url.php new file mode 100644 index 0000000..6a4e772 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/Url.php @@ -0,0 +1,554 @@ + null, 'host' => null, 'path' => null, 'port' => null, 'query' => null, + 'user' => null, 'pass' => null, 'fragment' => null); + + if (false === ($parts = parse_url($url))) { + throw new InvalidArgumentException('Was unable to parse malformed url: ' . $url); + } + + $parts += $defaults; + + // Convert the query string into a QueryString object + if ($parts['query'] || 0 !== strlen($parts['query'])) { + $parts['query'] = QueryString::fromString($parts['query']); + } + + return new static($parts['scheme'], $parts['host'], $parts['user'], + $parts['pass'], $parts['port'], $parts['path'], $parts['query'], + $parts['fragment']); + } + + /** + * Build a URL from parse_url parts. The generated URL will be a relative URL if a scheme or host are not provided. + * + * @param array $parts Array of parse_url parts + * + * @return string + */ + public static function buildUrl(array $parts) + { + $url = $scheme = ''; + + if (isset($parts['scheme'])) { + $scheme = $parts['scheme']; + $url .= $scheme . ':'; + } + + if (isset($parts['host'])) { + $url .= '//'; + if (isset($parts['user'])) { + $url .= $parts['user']; + if (isset($parts['pass'])) { + $url .= ':' . $parts['pass']; + } + $url .= '@'; + } + + $url .= $parts['host']; + + // Only include the port if it is not the default port of the scheme + if (isset($parts['port']) + && !(($scheme == 'http' && $parts['port'] == 80) || ($scheme == 'https' && $parts['port'] == 443)) + ) { + $url .= ':' . $parts['port']; + } + } + + // Add the path component if present + if (isset($parts['path']) && 0 !== strlen($parts['path'])) { + // Always ensure that the path begins with '/' if set and something is before the path + if ($url && $parts['path'][0] != '/' && substr($url, -1) != '/') { + $url .= '/'; + } + $url .= $parts['path']; + } + + // Add the query string if present + if (isset($parts['query'])) { + $url .= '?' . $parts['query']; + } + + // Ensure that # is only added to the url if fragment contains anything. + if (isset($parts['fragment'])) { + $url .= '#' . $parts['fragment']; + } + + return $url; + } + + /** + * Create a new URL from URL parts + * + * @param string $scheme Scheme of the URL + * @param string $host Host of the URL + * @param string $username Username of the URL + * @param string $password Password of the URL + * @param int $port Port of the URL + * @param string $path Path of the URL + * @param QueryString|array|string $query Query string of the URL + * @param string $fragment Fragment of the URL + */ + public function __construct($scheme, $host, $username = null, $password = null, $port = null, $path = null, QueryString $query = null, $fragment = null) + { + $this->scheme = $scheme; + $this->host = $host; + $this->port = $port; + $this->username = $username; + $this->password = $password; + $this->fragment = $fragment; + if (!$query) { + $this->query = new QueryString(); + } else { + $this->setQuery($query); + } + $this->setPath($path); + } + + /** + * Clone the URL + */ + public function __clone() + { + $this->query = clone $this->query; + } + + /** + * Returns the URL as a URL string + * + * @return string + */ + public function __toString() + { + return self::buildUrl($this->getParts()); + } + + /** + * Get the parts of the URL as an array + * + * @return array + */ + public function getParts() + { + $query = (string) $this->query; + + return array( + 'scheme' => $this->scheme, + 'user' => $this->username, + 'pass' => $this->password, + 'host' => $this->host, + 'port' => $this->port, + 'path' => $this->getPath(), + 'query' => $query !== '' ? $query : null, + 'fragment' => $this->fragment, + ); + } + + /** + * Set the host of the request. + * + * @param string $host Host to set (e.g. www.yahoo.com, yahoo.com) + * + * @return Url + */ + public function setHost($host) + { + if (strpos($host, ':') === false) { + $this->host = $host; + } else { + list($host, $port) = explode(':', $host); + $this->host = $host; + $this->setPort($port); + } + + return $this; + } + + /** + * Get the host part of the URL + * + * @return string + */ + public function getHost() + { + return $this->host; + } + + /** + * Set the scheme part of the URL (http, https, ftp, etc) + * + * @param string $scheme Scheme to set + * + * @return Url + */ + public function setScheme($scheme) + { + if ($this->scheme == 'http' && $this->port == 80) { + $this->port = null; + } elseif ($this->scheme == 'https' && $this->port == 443) { + $this->port = null; + } + + $this->scheme = $scheme; + + return $this; + } + + /** + * Get the scheme part of the URL + * + * @return string + */ + public function getScheme() + { + return $this->scheme; + } + + /** + * Set the port part of the URL + * + * @param int $port Port to set + * + * @return Url + */ + public function setPort($port) + { + $this->port = $port; + + return $this; + } + + /** + * Get the port part of the URl. Will return the default port for a given scheme if no port has been set. + * + * @return int|null + */ + public function getPort() + { + if ($this->port) { + return $this->port; + } elseif ($this->scheme == 'http') { + return 80; + } elseif ($this->scheme == 'https') { + return 443; + } + + return null; + } + + /** + * Set the path part of the URL + * + * @param array|string $path Path string or array of path segments + * + * @return Url + */ + public function setPath($path) + { + static $pathReplace = array(' ' => '%20', '?' => '%3F'); + if (is_array($path)) { + $path = '/' . implode('/', $path); + } + + $this->path = strtr($path, $pathReplace); + + return $this; + } + + /** + * Normalize the URL so that double slashes and relative paths are removed + * + * @return Url + */ + public function normalizePath() + { + if (!$this->path || $this->path == '/' || $this->path == '*') { + return $this; + } + + $results = array(); + $segments = $this->getPathSegments(); + foreach ($segments as $segment) { + if ($segment == '..') { + array_pop($results); + } elseif ($segment != '.' && $segment != '') { + $results[] = $segment; + } + } + + // Combine the normalized parts and add the leading slash if needed + $this->path = ($this->path[0] == '/' ? '/' : '') . implode('/', $results); + + // Add the trailing slash if necessary + if ($this->path != '/' && end($segments) == '') { + $this->path .= '/'; + } + + return $this; + } + + /** + * Add a relative path to the currently set path. + * + * @param string $relativePath Relative path to add + * + * @return Url + */ + public function addPath($relativePath) + { + if ($relativePath != '/' && is_string($relativePath) && strlen($relativePath) > 0) { + // Add a leading slash if needed + if ($relativePath[0] != '/') { + $relativePath = '/' . $relativePath; + } + $this->setPath(str_replace('//', '/', $this->path . $relativePath)); + } + + return $this; + } + + /** + * Get the path part of the URL + * + * @return string + */ + public function getPath() + { + return $this->path; + } + + /** + * Get the path segments of the URL as an array + * + * @return array + */ + public function getPathSegments() + { + return array_slice(explode('/', $this->getPath()), 1); + } + + /** + * Set the password part of the URL + * + * @param string $password Password to set + * + * @return Url + */ + public function setPassword($password) + { + $this->password = $password; + + return $this; + } + + /** + * Get the password part of the URL + * + * @return null|string + */ + public function getPassword() + { + return $this->password; + } + + /** + * Set the username part of the URL + * + * @param string $username Username to set + * + * @return Url + */ + public function setUsername($username) + { + $this->username = $username; + + return $this; + } + + /** + * Get the username part of the URl + * + * @return null|string + */ + public function getUsername() + { + return $this->username; + } + + /** + * Get the query part of the URL as a QueryString object + * + * @return QueryString + */ + public function getQuery() + { + return $this->query; + } + + /** + * Set the query part of the URL + * + * @param QueryString|string|array $query Query to set + * + * @return Url + */ + public function setQuery($query) + { + if (is_string($query)) { + $output = null; + parse_str($query, $output); + $this->query = new QueryString($output); + } elseif (is_array($query)) { + $this->query = new QueryString($query); + } elseif ($query instanceof QueryString) { + $this->query = $query; + } + + return $this; + } + + /** + * Get the fragment part of the URL + * + * @return null|string + */ + public function getFragment() + { + return $this->fragment; + } + + /** + * Set the fragment part of the URL + * + * @param string $fragment Fragment to set + * + * @return Url + */ + public function setFragment($fragment) + { + $this->fragment = $fragment; + + return $this; + } + + /** + * Check if this is an absolute URL + * + * @return bool + */ + public function isAbsolute() + { + return $this->scheme && $this->host; + } + + /** + * Combine the URL with another URL. Follows the rules specific in RFC 3986 section 5.4. + * + * @param string $url Relative URL to combine with + * @param bool $strictRfc3986 Set to true to use strict RFC 3986 compliance when merging paths. When first + * released, Guzzle used an incorrect algorithm for combining relative URL paths. In + * order to not break users, we introduced this flag to allow the merging of URLs based + * on strict RFC 3986 section 5.4.1. This means that "http://a.com/foo/baz" merged with + * "bar" would become "http://a.com/foo/bar". When this value is set to false, it would + * become "http://a.com/foo/baz/bar". + * @return Url + * @throws InvalidArgumentException + * @link http://tools.ietf.org/html/rfc3986#section-5.4 + */ + public function combine($url, $strictRfc3986 = false) + { + $url = self::factory($url); + + // Use the more absolute URL as the base URL + if (!$this->isAbsolute() && $url->isAbsolute()) { + $url = $url->combine($this); + } + + // Passing a URL with a scheme overrides everything + if ($buffer = $url->getScheme()) { + $this->scheme = $buffer; + $this->host = $url->getHost(); + $this->port = $url->getPort(); + $this->username = $url->getUsername(); + $this->password = $url->getPassword(); + $this->path = $url->getPath(); + $this->query = $url->getQuery(); + $this->fragment = $url->getFragment(); + return $this; + } + + // Setting a host overrides the entire rest of the URL + if ($buffer = $url->getHost()) { + $this->host = $buffer; + $this->port = $url->getPort(); + $this->username = $url->getUsername(); + $this->password = $url->getPassword(); + $this->path = $url->getPath(); + $this->query = $url->getQuery(); + $this->fragment = $url->getFragment(); + return $this; + } + + $path = $url->getPath(); + $query = $url->getQuery(); + + if (!$path) { + if (count($query)) { + $this->addQuery($query, $strictRfc3986); + } + } else { + if ($path[0] == '/') { + $this->path = $path; + } elseif ($strictRfc3986) { + $this->path .= '/../' . $path; + } else { + $this->path .= '/' . $path; + } + $this->normalizePath(); + $this->addQuery($query, $strictRfc3986); + } + + $this->fragment = $url->getFragment(); + + return $this; + } + + private function addQuery(QueryString $new, $strictRfc386) + { + if (!$strictRfc386) { + $new->merge($this->query); + } + + $this->query = $new; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/composer.json b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/composer.json new file mode 100644 index 0000000..9384a5b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Http/composer.json @@ -0,0 +1,32 @@ +{ + "name": "guzzle/http", + "description": "HTTP libraries used by Guzzle", + "homepage": "http://guzzlephp.org/", + "keywords": ["http client", "http", "client", "Guzzle", "curl"], + "license": "MIT", + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "require": { + "php": ">=5.3.2", + "guzzle/common": "self.version", + "guzzle/parser": "self.version", + "guzzle/stream": "self.version" + }, + "suggest": { + "ext-curl": "*" + }, + "autoload": { + "psr-0": { "Guzzle\\Http": "" } + }, + "target-dir": "Guzzle/Http", + "extra": { + "branch-alias": { + "dev-master": "3.7-dev" + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Inflection/Inflector.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Inflection/Inflector.php new file mode 100644 index 0000000..c699773 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Inflection/Inflector.php @@ -0,0 +1,38 @@ + array(), + 'camel' => array() + ); + + /** @var int Max entries per cache */ + protected $maxCacheSize; + + /** @var InflectorInterface Decorated inflector */ + protected $decoratedInflector; + + /** + * @param InflectorInterface $inflector Inflector being decorated + * @param int $maxCacheSize Maximum number of cached items to hold per cache + */ + public function __construct(InflectorInterface $inflector, $maxCacheSize = 500) + { + $this->decoratedInflector = $inflector; + $this->maxCacheSize = $maxCacheSize; + } + + public function snake($word) + { + if (!isset($this->cache['snake'][$word])) { + $this->pruneCache('snake'); + $this->cache['snake'][$word] = $this->decoratedInflector->snake($word); + } + + return $this->cache['snake'][$word]; + } + + /** + * Converts strings from snake_case to upper CamelCase + * + * @param string $word Value to convert into upper CamelCase + * + * @return string + */ + public function camel($word) + { + if (!isset($this->cache['camel'][$word])) { + $this->pruneCache('camel'); + $this->cache['camel'][$word] = $this->decoratedInflector->camel($word); + } + + return $this->cache['camel'][$word]; + } + + /** + * Prune one of the named caches by removing 20% of the cache if it is full + * + * @param string $cache Type of cache to prune + */ + protected function pruneCache($cache) + { + if (count($this->cache[$cache]) == $this->maxCacheSize) { + $this->cache[$cache] = array_slice($this->cache[$cache], $this->maxCacheSize * 0.2); + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Inflection/PreComputedInflector.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Inflection/PreComputedInflector.php new file mode 100644 index 0000000..db37e4f --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Inflection/PreComputedInflector.php @@ -0,0 +1,59 @@ + array(), + 'camel' => array() + ); + + /** @var InflectorInterface Decorated inflector */ + protected $decoratedInflector; + + /** + * @param InflectorInterface $inflector Inflector being decorated + * @param array $snake Hash of pre-computed camel to snake + * @param array $camel Hash of pre-computed snake to camel + * @param bool $mirror Mirror snake and camel reflections + */ + public function __construct(InflectorInterface $inflector, array $snake = array(), array $camel = array(), $mirror = false) + { + if ($mirror) { + $camel = array_merge(array_flip($snake), $camel); + $snake = array_merge(array_flip($camel), $snake); + } + + $this->decoratedInflector = $inflector; + $this->mapping = array( + 'snake' => $snake, + 'camel' => $camel + ); + } + + public function snake($word) + { + return isset($this->mapping['snake'][$word]) + ? $this->mapping['snake'][$word] + : $this->decoratedInflector->snake($word); + } + + /** + * Converts strings from snake_case to upper CamelCase + * + * @param string $word Value to convert into upper CamelCase + * + * @return string + */ + public function camel($word) + { + return isset($this->mapping['camel'][$word]) + ? $this->mapping['camel'][$word] + : $this->decoratedInflector->camel($word); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Inflection/composer.json b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Inflection/composer.json new file mode 100644 index 0000000..93f9e7b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Inflection/composer.json @@ -0,0 +1,26 @@ +{ + "name": "guzzle/inflection", + "description": "Guzzle inflection component", + "homepage": "http://guzzlephp.org/", + "keywords": ["inflection", "guzzle"], + "license": "MIT", + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "require": { + "php": ">=5.3.2" + }, + "autoload": { + "psr-0": { "Guzzle\\Inflection": "" } + }, + "target-dir": "Guzzle/Inflection", + "extra": { + "branch-alias": { + "dev-master": "3.7-dev" + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Iterator/AppendIterator.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Iterator/AppendIterator.php new file mode 100644 index 0000000..1b6bd7e --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Iterator/AppendIterator.php @@ -0,0 +1,19 @@ +getArrayIterator()->append($iterator); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Iterator/ChunkedIterator.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Iterator/ChunkedIterator.php new file mode 100644 index 0000000..d76cdd4 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Iterator/ChunkedIterator.php @@ -0,0 +1,56 @@ +chunkSize = $chunkSize; + } + + public function rewind() + { + parent::rewind(); + $this->next(); + } + + public function next() + { + $this->chunk = array(); + for ($i = 0; $i < $this->chunkSize && parent::valid(); $i++) { + $this->chunk[] = parent::current(); + parent::next(); + } + } + + public function current() + { + return $this->chunk; + } + + public function valid() + { + return (bool) $this->chunk; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Iterator/FilterIterator.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Iterator/FilterIterator.php new file mode 100644 index 0000000..b103367 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Iterator/FilterIterator.php @@ -0,0 +1,36 @@ +callback = $callback; + } + + public function accept() + { + return call_user_func($this->callback, $this->current()); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Iterator/MapIterator.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Iterator/MapIterator.php new file mode 100644 index 0000000..7e586bd --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Iterator/MapIterator.php @@ -0,0 +1,34 @@ +callback = $callback; + } + + public function current() + { + return call_user_func($this->callback, parent::current()); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Iterator/MethodProxyIterator.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Iterator/MethodProxyIterator.php new file mode 100644 index 0000000..de4ab03 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Iterator/MethodProxyIterator.php @@ -0,0 +1,27 @@ +getInnerIterator(); + while ($i instanceof \OuterIterator) { + $i = $i->getInnerIterator(); + } + + return call_user_func_array(array($i, $name), $args); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Iterator/README.md b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Iterator/README.md new file mode 100644 index 0000000..8bb7e08 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Iterator/README.md @@ -0,0 +1,25 @@ +Guzzle Iterator +=============== + +Provides useful Iterators and Iterator decorators + +- ChunkedIterator: Pulls out chunks from an inner iterator and yields the chunks as arrays +- FilterIterator: Used when PHP 5.4's CallbackFilterIterator is not available +- MapIterator: Maps values before yielding +- MethodProxyIterator: Proxies missing method calls to the innermost iterator + +### Installing via Composer + +```bash +# Install Composer +curl -sS https://getcomposer.org/installer | php + +# Add Guzzle as a dependency +php composer.phar require guzzle/iterator:~3.0 +``` + +After installing, you need to require Composer's autoloader: + +```php +require 'vendor/autoload.php'; +``` diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Iterator/composer.json b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Iterator/composer.json new file mode 100644 index 0000000..ee17379 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Iterator/composer.json @@ -0,0 +1,27 @@ +{ + "name": "guzzle/iterator", + "description": "Provides helpful iterators and iterator decorators", + "keywords": ["iterator", "guzzle"], + "homepage": "http://guzzlephp.org/", + "license": "MIT", + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "require": { + "php": ">=5.3.2", + "guzzle/common": ">=2.8.0" + }, + "autoload": { + "psr-0": { "Guzzle\\Iterator": "/" } + }, + "target-dir": "Guzzle/Iterator", + "extra": { + "branch-alias": { + "dev-master": "3.7-dev" + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Log/AbstractLogAdapter.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Log/AbstractLogAdapter.php new file mode 100644 index 0000000..7f6271b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Log/AbstractLogAdapter.php @@ -0,0 +1,16 @@ +log; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Log/ArrayLogAdapter.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Log/ArrayLogAdapter.php new file mode 100644 index 0000000..a70fc8d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Log/ArrayLogAdapter.php @@ -0,0 +1,34 @@ +logs[] = array('message' => $message, 'priority' => $priority, 'extras' => $extras); + } + + /** + * Get logged entries + * + * @return array + */ + public function getLogs() + { + return $this->logs; + } + + /** + * Clears logged entries + */ + public function clearLogs() + { + $this->logs = array(); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Log/ClosureLogAdapter.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Log/ClosureLogAdapter.php new file mode 100644 index 0000000..d4bb73f --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Log/ClosureLogAdapter.php @@ -0,0 +1,23 @@ +log = $logObject; + } + + public function log($message, $priority = LOG_INFO, $extras = array()) + { + call_user_func($this->log, $message, $priority, $extras); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Log/LogAdapterInterface.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Log/LogAdapterInterface.php new file mode 100644 index 0000000..d7ac4ea --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Log/LogAdapterInterface.php @@ -0,0 +1,18 @@ +>>>>>>>\n{request}\n<<<<<<<<\n{response}\n--------\n{curl_stderr}"; + const SHORT_FORMAT = '[{ts}] "{method} {resource} {protocol}/{version}" {code}'; + + /** + * @var string Template used to format log messages + */ + protected $template; + + /** + * @param string $template Log message template + */ + public function __construct($template = self::DEFAULT_FORMAT) + { + $this->template = $template ?: self::DEFAULT_FORMAT; + } + + /** + * Set the template to use for logging + * + * @param string $template Log message template + * + * @return self + */ + public function setTemplate($template) + { + $this->template = $template; + + return $this; + } + + /** + * Returns a formatted message + * + * @param RequestInterface $request Request that was sent + * @param Response $response Response that was received + * @param CurlHandle $handle Curl handle associated with the message + * @param array $customData Associative array of custom template data + * + * @return string + */ + public function format( + RequestInterface $request, + Response $response = null, + CurlHandle $handle = null, + array $customData = array() + ) { + $cache = $customData; + + return preg_replace_callback( + '/{\s*([A-Za-z_\-\.0-9]+)\s*}/', + function (array $matches) use ($request, $response, $handle, &$cache) { + + if (array_key_exists($matches[1], $cache)) { + return $cache[$matches[1]]; + } + + $result = ''; + switch ($matches[1]) { + case 'request': + $result = (string) $request; + break; + case 'response': + $result = (string) $response; + break; + case 'req_body': + $result = $request instanceof EntityEnclosingRequestInterface + ? (string) $request->getBody() : ''; + break; + case 'res_body': + $result = $response ? $response->getBody(true) : ''; + break; + case 'ts': + $result = gmdate('c'); + break; + case 'method': + $result = $request->getMethod(); + break; + case 'url': + $result = (string) $request->getUrl(); + break; + case 'resource': + $result = $request->getResource(); + break; + case 'protocol': + $result = 'HTTP'; + break; + case 'version': + $result = $request->getProtocolVersion(); + break; + case 'host': + $result = $request->getHost(); + break; + case 'hostname': + $result = gethostname(); + break; + case 'port': + $result = $request->getPort(); + break; + case 'code': + $result = $response ? $response->getStatusCode() : ''; + break; + case 'phrase': + $result = $response ? $response->getReasonPhrase() : ''; + break; + case 'connect_time': + $result = $handle && $handle->getInfo(CURLINFO_CONNECT_TIME) + ? $handle->getInfo(CURLINFO_CONNECT_TIME) + : ($response ? $response->getInfo('connect_time') : ''); + break; + case 'total_time': + $result = $handle && $handle->getInfo(CURLINFO_TOTAL_TIME) + ? $handle->getInfo(CURLINFO_TOTAL_TIME) + : ($response ? $response->getInfo('total_time') : ''); + break; + case 'curl_error': + $result = $handle ? $handle->getError() : ''; + break; + case 'curl_code': + $result = $handle ? $handle->getErrorNo() : ''; + break; + case 'curl_stderr': + $result = $handle ? $handle->getStderr() : ''; + break; + default: + if (strpos($matches[1], 'req_header_') === 0) { + $result = $request->getHeader(substr($matches[1], 11)); + } elseif ($response && strpos($matches[1], 'res_header_') === 0) { + $result = $response->getHeader(substr($matches[1], 11)); + } + } + + $cache[$matches[1]] = $result; + return $result; + }, + $this->template + ); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Log/MonologLogAdapter.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Log/MonologLogAdapter.php new file mode 100644 index 0000000..6afe7b6 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Log/MonologLogAdapter.php @@ -0,0 +1,34 @@ + Logger::DEBUG, + LOG_INFO => Logger::INFO, + LOG_WARNING => Logger::WARNING, + LOG_ERR => Logger::ERROR, + LOG_CRIT => Logger::CRITICAL, + LOG_ALERT => Logger::ALERT + ); + + public function __construct(Logger $logObject) + { + $this->log = $logObject; + } + + public function log($message, $priority = LOG_INFO, $extras = array()) + { + $this->log->addRecord(self::$mapping[$priority], $message, $extras); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Log/PsrLogAdapter.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Log/PsrLogAdapter.php new file mode 100644 index 0000000..38a2b60 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Log/PsrLogAdapter.php @@ -0,0 +1,36 @@ + LogLevel::DEBUG, + LOG_INFO => LogLevel::INFO, + LOG_WARNING => LogLevel::WARNING, + LOG_ERR => LogLevel::ERROR, + LOG_CRIT => LogLevel::CRITICAL, + LOG_ALERT => LogLevel::ALERT + ); + + public function __construct(LoggerInterface $logObject) + { + $this->log = $logObject; + } + + public function log($message, $priority = LOG_INFO, $extras = array()) + { + $this->log->log(self::$mapping[$priority], $message, $extras); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Log/Zf1LogAdapter.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Log/Zf1LogAdapter.php new file mode 100644 index 0000000..0ea8e3b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Log/Zf1LogAdapter.php @@ -0,0 +1,24 @@ +log = $logObject; + Version::warn(__CLASS__ . ' is deprecated'); + } + + public function log($message, $priority = LOG_INFO, $extras = array()) + { + $this->log->log($message, $priority, $extras); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Log/Zf2LogAdapter.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Log/Zf2LogAdapter.php new file mode 100644 index 0000000..863f6a1 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Log/Zf2LogAdapter.php @@ -0,0 +1,21 @@ +log = $logObject; + } + + public function log($message, $priority = LOG_INFO, $extras = array()) + { + $this->log->log($priority, $message, $extras); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Log/composer.json b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Log/composer.json new file mode 100644 index 0000000..a8213e8 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Log/composer.json @@ -0,0 +1,29 @@ +{ + "name": "guzzle/log", + "description": "Guzzle log adapter component", + "homepage": "http://guzzlephp.org/", + "keywords": ["log", "adapter", "guzzle"], + "license": "MIT", + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "require": { + "php": ">=5.3.2" + }, + "autoload": { + "psr-0": { "Guzzle\\Log": "" } + }, + "suggest": { + "guzzle/http": "self.version" + }, + "target-dir": "Guzzle/Log", + "extra": { + "branch-alias": { + "dev-master": "3.7-dev" + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Parser/Cookie/CookieParser.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Parser/Cookie/CookieParser.php new file mode 100644 index 0000000..4349eeb --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Parser/Cookie/CookieParser.php @@ -0,0 +1,131 @@ + 'Domain', + 'path' => 'Path', + 'max_age' => 'Max-Age', + 'expires' => 'Expires', + 'version' => 'Version', + 'secure' => 'Secure', + 'port' => 'Port', + 'discard' => 'Discard', + 'comment' => 'Comment', + 'comment_url' => 'Comment-Url', + 'http_only' => 'HttpOnly' + ); + + public function parseCookie($cookie, $host = null, $path = null, $decode = false) + { + // Explode the cookie string using a series of semicolons + $pieces = array_filter(array_map('trim', explode(';', $cookie))); + + // The name of the cookie (first kvp) must include an equal sign. + if (empty($pieces) || !strpos($pieces[0], '=')) { + return false; + } + + // Create the default return array + $data = array_merge(array_fill_keys(array_keys(self::$cookieParts), null), array( + 'cookies' => array(), + 'data' => array(), + 'path' => null, + 'http_only' => false, + 'discard' => false, + 'domain' => $host + )); + $foundNonCookies = 0; + + // Add the cookie pieces into the parsed data array + foreach ($pieces as $part) { + + $cookieParts = explode('=', $part, 2); + $key = trim($cookieParts[0]); + + if (count($cookieParts) == 1) { + // Can be a single value (e.g. secure, httpOnly) + $value = true; + } else { + // Be sure to strip wrapping quotes + $value = trim($cookieParts[1], " \n\r\t\0\x0B\""); + if ($decode) { + $value = urldecode($value); + } + } + + // Only check for non-cookies when cookies have been found + if (!empty($data['cookies'])) { + foreach (self::$cookieParts as $mapValue => $search) { + if (!strcasecmp($search, $key)) { + $data[$mapValue] = $mapValue == 'port' ? array_map('trim', explode(',', $value)) : $value; + $foundNonCookies++; + continue 2; + } + } + } + + // If cookies have not yet been retrieved, or this value was not found in the pieces array, treat it as a + // cookie. IF non-cookies have been parsed, then this isn't a cookie, it's cookie data. Cookies then data. + $data[$foundNonCookies ? 'data' : 'cookies'][$key] = $value; + } + + // Calculate the expires date + if (!$data['expires'] && $data['max_age']) { + $data['expires'] = time() + (int) $data['max_age']; + } + + // Check path attribute according RFC6265 http://tools.ietf.org/search/rfc6265#section-5.2.4 + // "If the attribute-value is empty or if the first character of the + // attribute-value is not %x2F ("/"): + // Let cookie-path be the default-path. + // Otherwise: + // Let cookie-path be the attribute-value." + if (!$data['path'] || substr($data['path'], 0, 1) !== '/') { + $data['path'] = $this->getDefaultPath($path); + } + + return $data; + } + + /** + * Get default cookie path according to RFC 6265 + * http://tools.ietf.org/search/rfc6265#section-5.1.4 Paths and Path-Match + * + * @param string $path Request uri-path + * + * @return string + */ + protected function getDefaultPath($path) { + // "The user agent MUST use an algorithm equivalent to the following algorithm + // to compute the default-path of a cookie:" + + // "2. If the uri-path is empty or if the first character of the uri-path is not + // a %x2F ("/") character, output %x2F ("/") and skip the remaining steps. + if (empty($path) || substr($path, 0, 1) !== '/') { + return '/'; + } + + // "3. If the uri-path contains no more than one %x2F ("/") character, output + // %x2F ("/") and skip the remaining step." + if ($path === "/") { + return $path; + } + + $rightSlashPos = strrpos($path, '/'); + if ($rightSlashPos === 0) { + return "/"; + } + + // "4. Output the characters of the uri-path from the first character up to, + // but not including, the right-most %x2F ("/")." + return substr($path, 0, $rightSlashPos); + + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Parser/Cookie/CookieParserInterface.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Parser/Cookie/CookieParserInterface.php new file mode 100644 index 0000000..d21ffe2 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Parser/Cookie/CookieParserInterface.php @@ -0,0 +1,33 @@ + $requestUrl, + 'scheme' => 'http' + ); + + // Check for the Host header + if (isset($parts['headers']['Host'])) { + $urlParts['host'] = $parts['headers']['Host']; + } elseif (isset($parts['headers']['host'])) { + $urlParts['host'] = $parts['headers']['host']; + } else { + $urlParts['host'] = null; + } + + if (false === strpos($urlParts['host'], ':')) { + $urlParts['port'] = ''; + } else { + $hostParts = explode(':', $urlParts['host']); + $urlParts['host'] = trim($hostParts[0]); + $urlParts['port'] = (int) trim($hostParts[1]); + if ($urlParts['port'] == 443) { + $urlParts['scheme'] = 'https'; + } + } + + // Check if a query is present + $path = $urlParts['path']; + $qpos = strpos($path, '?'); + if ($qpos) { + $urlParts['query'] = substr($path, $qpos + 1); + $urlParts['path'] = substr($path, 0, $qpos); + } else { + $urlParts['query'] = ''; + } + + return $urlParts; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Parser/Message/MessageParser.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Parser/Message/MessageParser.php new file mode 100644 index 0000000..efc1aa3 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Parser/Message/MessageParser.php @@ -0,0 +1,110 @@ +parseMessage($message); + + // Parse the protocol and protocol version + if (isset($parts['start_line'][2])) { + $startParts = explode('/', $parts['start_line'][2]); + $protocol = strtoupper($startParts[0]); + $version = isset($startParts[1]) ? $startParts[1] : '1.1'; + } else { + $protocol = 'HTTP'; + $version = '1.1'; + } + + $parsed = array( + 'method' => strtoupper($parts['start_line'][0]), + 'protocol' => $protocol, + 'version' => $version, + 'headers' => $parts['headers'], + 'body' => $parts['body'] + ); + + $parsed['request_url'] = $this->getUrlPartsFromMessage(isset($parts['start_line'][1]) ? $parts['start_line'][1] : '' , $parsed); + + return $parsed; + } + + public function parseResponse($message) + { + if (!$message) { + return false; + } + + $parts = $this->parseMessage($message); + list($protocol, $version) = explode('/', trim($parts['start_line'][0])); + + return array( + 'protocol' => $protocol, + 'version' => $version, + 'code' => $parts['start_line'][1], + 'reason_phrase' => isset($parts['start_line'][2]) ? $parts['start_line'][2] : '', + 'headers' => $parts['headers'], + 'body' => $parts['body'] + ); + } + + /** + * Parse a message into parts + * + * @param string $message Message to parse + * + * @return array + */ + protected function parseMessage($message) + { + $startLine = null; + $headers = array(); + $body = ''; + + // Iterate over each line in the message, accounting for line endings + $lines = preg_split('/(\\r?\\n)/', $message, -1, PREG_SPLIT_DELIM_CAPTURE); + for ($i = 0, $totalLines = count($lines); $i < $totalLines; $i += 2) { + + $line = $lines[$i]; + + // If two line breaks were encountered, then this is the end of body + if (empty($line)) { + if ($i < $totalLines - 1) { + $body = implode('', array_slice($lines, $i + 2)); + } + break; + } + + // Parse message headers + if (!$startLine) { + $startLine = explode(' ', $line, 3); + } elseif (strpos($line, ':')) { + $parts = explode(':', $line, 2); + $key = trim($parts[0]); + $value = isset($parts[1]) ? trim($parts[1]) : ''; + if (!isset($headers[$key])) { + $headers[$key] = $value; + } elseif (!is_array($headers[$key])) { + $headers[$key] = array($headers[$key], $value); + } else { + $headers[$key][] = $value; + } + } + } + + return array( + 'start_line' => $startLine, + 'headers' => $headers, + 'body' => $body + ); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Parser/Message/MessageParserInterface.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Parser/Message/MessageParserInterface.php new file mode 100644 index 0000000..cc44808 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Parser/Message/MessageParserInterface.php @@ -0,0 +1,27 @@ + $parts->requestMethod, + 'protocol' => 'HTTP', + 'version' => number_format($parts->httpVersion, 1), + 'headers' => $parts->headers, + 'body' => $parts->body + ); + + $parsed['request_url'] = $this->getUrlPartsFromMessage($parts->requestUrl, $parsed); + + return $parsed; + } + + public function parseResponse($message) + { + if (!$message) { + return false; + } + + $parts = http_parse_message($message); + + return array( + 'protocol' => 'HTTP', + 'version' => number_format($parts->httpVersion, 1), + 'code' => $parts->responseCode, + 'reason_phrase' => $parts->responseStatus, + 'headers' => $parts->headers, + 'body' => $parts->body + ); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Parser/ParserRegistry.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Parser/ParserRegistry.php new file mode 100644 index 0000000..f838683 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Parser/ParserRegistry.php @@ -0,0 +1,75 @@ + 'Guzzle\\Parser\\Message\\MessageParser', + 'cookie' => 'Guzzle\\Parser\\Cookie\\CookieParser', + 'url' => 'Guzzle\\Parser\\Url\\UrlParser', + 'uri_template' => 'Guzzle\\Parser\\UriTemplate\\UriTemplate', + ); + + /** + * @return self + * @codeCoverageIgnore + */ + public static function getInstance() + { + if (!self::$instance) { + self::$instance = new static; + } + + return self::$instance; + } + + public function __construct() + { + // Use the PECL URI template parser if available + if (extension_loaded('uri_template')) { + $this->mapping['uri_template'] = 'Guzzle\\Parser\\UriTemplate\\PeclUriTemplate'; + } + } + + /** + * Get a parser by name from an instance + * + * @param string $name Name of the parser to retrieve + * + * @return mixed|null + */ + public function getParser($name) + { + if (!isset($this->instances[$name])) { + if (!isset($this->mapping[$name])) { + return null; + } + $class = $this->mapping[$name]; + $this->instances[$name] = new $class(); + } + + return $this->instances[$name]; + } + + /** + * Register a custom parser by name with the register + * + * @param string $name Name or handle of the parser to register + * @param mixed $parser Instantiated parser to register + */ + public function registerParser($name, $parser) + { + $this->instances[$name] = $parser; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Parser/UriTemplate/PeclUriTemplate.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Parser/UriTemplate/PeclUriTemplate.php new file mode 100644 index 0000000..b0764e8 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Parser/UriTemplate/PeclUriTemplate.php @@ -0,0 +1,26 @@ + true, '#' => true, '.' => true, '/' => true, ';' => true, '?' => true, '&' => true + ); + + /** @var array Delimiters */ + private static $delims = array( + ':', '/', '?', '#', '[', ']', '@', '!', '$', '&', '\'', '(', ')', '*', '+', ',', ';', '=' + ); + + /** @var array Percent encoded delimiters */ + private static $delimsPct = array( + '%3A', '%2F', '%3F', '%23', '%5B', '%5D', '%40', '%21', '%24', '%26', '%27', '%28', '%29', '%2A', '%2B', '%2C', + '%3B', '%3D' + ); + + public function expand($template, array $variables) + { + if ($this->regex == self::DEFAULT_PATTERN && false === strpos($template, '{')) { + return $template; + } + + $this->template = $template; + $this->variables = $variables; + + return preg_replace_callback($this->regex, array($this, 'expandMatch'), $this->template); + } + + /** + * Set the regex patten used to expand URI templates + * + * @param string $regexPattern + */ + public function setRegex($regexPattern) + { + $this->regex = $regexPattern; + } + + /** + * Parse an expression into parts + * + * @param string $expression Expression to parse + * + * @return array Returns an associative array of parts + */ + private function parseExpression($expression) + { + // Check for URI operators + $operator = ''; + + if (isset(self::$operatorHash[$expression[0]])) { + $operator = $expression[0]; + $expression = substr($expression, 1); + } + + $values = explode(',', $expression); + foreach ($values as &$value) { + $value = trim($value); + $varspec = array(); + $substrPos = strpos($value, ':'); + if ($substrPos) { + $varspec['value'] = substr($value, 0, $substrPos); + $varspec['modifier'] = ':'; + $varspec['position'] = (int) substr($value, $substrPos + 1); + } elseif (substr($value, -1) == '*') { + $varspec['modifier'] = '*'; + $varspec['value'] = substr($value, 0, -1); + } else { + $varspec['value'] = (string) $value; + $varspec['modifier'] = ''; + } + $value = $varspec; + } + + return array( + 'operator' => $operator, + 'values' => $values + ); + } + + /** + * Process an expansion + * + * @param array $matches Matches met in the preg_replace_callback + * + * @return string Returns the replacement string + */ + private function expandMatch(array $matches) + { + static $rfc1738to3986 = array( + '+' => '%20', + '%7e' => '~' + ); + + $parsed = self::parseExpression($matches[1]); + $replacements = array(); + + $prefix = $parsed['operator']; + $joiner = $parsed['operator']; + $useQueryString = false; + if ($parsed['operator'] == '?') { + $joiner = '&'; + $useQueryString = true; + } elseif ($parsed['operator'] == '&') { + $useQueryString = true; + } elseif ($parsed['operator'] == '#') { + $joiner = ','; + } elseif ($parsed['operator'] == ';') { + $useQueryString = true; + } elseif ($parsed['operator'] == '' || $parsed['operator'] == '+') { + $joiner = ','; + $prefix = ''; + } + + foreach ($parsed['values'] as $value) { + + if (!array_key_exists($value['value'], $this->variables) || $this->variables[$value['value']] === null) { + continue; + } + + $variable = $this->variables[$value['value']]; + $actuallyUseQueryString = $useQueryString; + $expanded = ''; + + if (is_array($variable)) { + + $isAssoc = $this->isAssoc($variable); + $kvp = array(); + foreach ($variable as $key => $var) { + + if ($isAssoc) { + $key = rawurlencode($key); + $isNestedArray = is_array($var); + } else { + $isNestedArray = false; + } + + if (!$isNestedArray) { + $var = rawurlencode($var); + if ($parsed['operator'] == '+' || $parsed['operator'] == '#') { + $var = $this->decodeReserved($var); + } + } + + if ($value['modifier'] == '*') { + if ($isAssoc) { + if ($isNestedArray) { + // Nested arrays must allow for deeply nested structures + $var = strtr(http_build_query(array($key => $var)), $rfc1738to3986); + } else { + $var = $key . '=' . $var; + } + } elseif ($key > 0 && $actuallyUseQueryString) { + $var = $value['value'] . '=' . $var; + } + } + + $kvp[$key] = $var; + } + + if (empty($variable)) { + $actuallyUseQueryString = false; + } elseif ($value['modifier'] == '*') { + $expanded = implode($joiner, $kvp); + if ($isAssoc) { + // Don't prepend the value name when using the explode modifier with an associative array + $actuallyUseQueryString = false; + } + } else { + if ($isAssoc) { + // When an associative array is encountered and the explode modifier is not set, then the + // result must be a comma separated list of keys followed by their respective values. + foreach ($kvp as $k => &$v) { + $v = $k . ',' . $v; + } + } + $expanded = implode(',', $kvp); + } + + } else { + if ($value['modifier'] == ':') { + $variable = substr($variable, 0, $value['position']); + } + $expanded = rawurlencode($variable); + if ($parsed['operator'] == '+' || $parsed['operator'] == '#') { + $expanded = $this->decodeReserved($expanded); + } + } + + if ($actuallyUseQueryString) { + if (!$expanded && $joiner != '&') { + $expanded = $value['value']; + } else { + $expanded = $value['value'] . '=' . $expanded; + } + } + + $replacements[] = $expanded; + } + + $ret = implode($joiner, $replacements); + if ($ret && $prefix) { + return $prefix . $ret; + } + + return $ret; + } + + /** + * Determines if an array is associative + * + * @param array $array Array to check + * + * @return bool + */ + private function isAssoc(array $array) + { + return (bool) count(array_filter(array_keys($array), 'is_string')); + } + + /** + * Removes percent encoding on reserved characters (used with + and # modifiers) + * + * @param string $string String to fix + * + * @return string + */ + private function decodeReserved($string) + { + return str_replace(self::$delimsPct, self::$delims, $string); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Parser/UriTemplate/UriTemplateInterface.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Parser/UriTemplate/UriTemplateInterface.php new file mode 100644 index 0000000..c81d515 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Parser/UriTemplate/UriTemplateInterface.php @@ -0,0 +1,21 @@ +utf8 = $utf8; + } + + public function parseUrl($url) + { + Version::warn(__CLASS__ . ' is deprecated. Just use parse_url()'); + + static $defaults = array('scheme' => null, 'host' => null, 'path' => null, 'port' => null, 'query' => null, + 'user' => null, 'pass' => null, 'fragment' => null); + + $parts = parse_url($url); + + // Need to handle query parsing specially for UTF-8 requirements + if ($this->utf8 && isset($parts['query'])) { + $queryPos = strpos($url, '?'); + if (isset($parts['fragment'])) { + $parts['query'] = substr($url, $queryPos + 1, strpos($url, '#') - $queryPos - 1); + } else { + $parts['query'] = substr($url, $queryPos + 1); + } + } + + return $parts + $defaults; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Parser/Url/UrlParserInterface.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Parser/Url/UrlParserInterface.php new file mode 100644 index 0000000..89ac4b3 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Parser/Url/UrlParserInterface.php @@ -0,0 +1,19 @@ +=5.3.2" + }, + "autoload": { + "psr-0": { "Guzzle\\Parser": "" } + }, + "target-dir": "Guzzle/Parser", + "extra": { + "branch-alias": { + "dev-master": "3.7-dev" + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Async/AsyncPlugin.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Async/AsyncPlugin.php new file mode 100644 index 0000000..ae59418 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Async/AsyncPlugin.php @@ -0,0 +1,84 @@ + 'onBeforeSend', + 'request.exception' => 'onRequestTimeout', + 'request.sent' => 'onRequestSent', + 'curl.callback.progress' => 'onCurlProgress' + ); + } + + /** + * Event used to ensure that progress callback are emitted from the curl handle's request mediator. + * + * @param Event $event + */ + public function onBeforeSend(Event $event) + { + // Ensure that progress callbacks are dispatched + $event['request']->getCurlOptions()->set('progress', true); + } + + /** + * Event emitted when a curl progress function is called. When the amount of data uploaded == the amount of data to + * upload OR any bytes have been downloaded, then time the request out after 1ms because we're done with + * transmitting the request, and tell curl not download a body. + * + * @param Event $event + */ + public function onCurlProgress(Event $event) + { + if ($event['handle'] && + ($event['downloaded'] || (isset($event['uploaded']) && $event['upload_size'] === $event['uploaded'])) + ) { + // Timeout after 1ms + curl_setopt($event['handle'], CURLOPT_TIMEOUT_MS, 1); + // Even if the response is quick, tell curl not to download the body. + // - Note that we can only perform this shortcut if the request transmitted a body so as to ensure that the + // request method is not converted to a HEAD request before the request was sent via curl. + if ($event['uploaded']) { + curl_setopt($event['handle'], CURLOPT_NOBODY, true); + } + } + } + + /** + * Event emitted when a curl exception occurs. Ignore the exception and set a mock response. + * + * @param Event $event + */ + public function onRequestTimeout(Event $event) + { + if ($event['exception'] instanceof CurlException) { + $event['request']->setResponse(new Response(200, array( + 'X-Guzzle-Async' => 'Did not wait for the response' + ))); + } + } + + /** + * Event emitted when a request completes because it took less than 1ms. Add an X-Guzzle-Async header to notify the + * caller that there is no body in the message. + * + * @param Event $event + */ + public function onRequestSent(Event $event) + { + // Let the caller know this was meant to be async + $event['request']->getResponse()->setHeader('X-Guzzle-Async', 'Did not wait for the response'); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Async/composer.json b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Async/composer.json new file mode 100644 index 0000000..dc3fc5b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Async/composer.json @@ -0,0 +1,27 @@ +{ + "name": "guzzle/plugin-async", + "description": "Guzzle async request plugin", + "homepage": "http://guzzlephp.org/", + "keywords": ["plugin", "guzzle"], + "license": "MIT", + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "require": { + "php": ">=5.3.2", + "guzzle/http": "self.version" + }, + "autoload": { + "psr-0": { "Guzzle\\Plugin\\Async": "" } + }, + "target-dir": "Guzzle/Plugin/Async", + "extra": { + "branch-alias": { + "dev-master": "3.7-dev" + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Backoff/AbstractBackoffStrategy.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Backoff/AbstractBackoffStrategy.php new file mode 100644 index 0000000..0a85983 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Backoff/AbstractBackoffStrategy.php @@ -0,0 +1,91 @@ +next = $next; + } + + /** + * Get the next backoff strategy in the chain + * + * @return AbstractBackoffStrategy|null + */ + public function getNext() + { + return $this->next; + } + + public function getBackoffPeriod( + $retries, + RequestInterface $request, + Response $response = null, + HttpException $e = null + ) { + $delay = $this->getDelay($retries, $request, $response, $e); + if ($delay === false) { + // The strategy knows that this must not be retried + return false; + } elseif ($delay === null) { + // If the strategy is deferring a decision and the next strategy will not make a decision then return false + return !$this->next || !$this->next->makesDecision() + ? false + : $this->next->getBackoffPeriod($retries, $request, $response, $e); + } elseif ($delay === true) { + // if the strategy knows that it must retry but is deferring to the next to determine the delay + if (!$this->next) { + return 0; + } else { + $next = $this->next; + while ($next->makesDecision() && $next->getNext()) { + $next = $next->getNext(); + } + return !$next->makesDecision() ? $next->getBackoffPeriod($retries, $request, $response, $e) : 0; + } + } else { + return $delay; + } + } + + /** + * Check if the strategy does filtering and makes decisions on whether or not to retry. + * + * Strategies that return false will never retry if all of the previous strategies in a chain defer on a backoff + * decision. + * + * @return bool + */ + abstract public function makesDecision(); + + /** + * Implement the concrete strategy + * + * @param int $retries Number of retries of the request + * @param RequestInterface $request Request that was sent + * @param Response $response Response that was received. Note that there may not be a response + * @param HttpException $e Exception that was encountered if any + * + * @return bool|int|null Returns false to not retry or the number of seconds to delay between retries. Return true + * or null to defer to the next strategy if available, and if not, return 0. + */ + abstract protected function getDelay( + $retries, + RequestInterface $request, + Response $response = null, + HttpException $e = null + ); +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Backoff/AbstractErrorCodeBackoffStrategy.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Backoff/AbstractErrorCodeBackoffStrategy.php new file mode 100644 index 0000000..6ebee6c --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Backoff/AbstractErrorCodeBackoffStrategy.php @@ -0,0 +1,40 @@ +errorCodes = array_fill_keys($codes ?: static::$defaultErrorCodes, 1); + $this->next = $next; + } + + /** + * Get the default failure codes to retry + * + * @return array + */ + public static function getDefaultFailureCodes() + { + return static::$defaultErrorCodes; + } + + public function makesDecision() + { + return true; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Backoff/BackoffLogger.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Backoff/BackoffLogger.php new file mode 100644 index 0000000..ec54c28 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Backoff/BackoffLogger.php @@ -0,0 +1,76 @@ +logger = $logger; + $this->formatter = $formatter ?: new MessageFormatter(self::DEFAULT_FORMAT); + } + + public static function getSubscribedEvents() + { + return array(BackoffPlugin::RETRY_EVENT => 'onRequestRetry'); + } + + /** + * Set the template to use for logging + * + * @param string $template Log message template + * + * @return self + */ + public function setTemplate($template) + { + $this->formatter->setTemplate($template); + + return $this; + } + + /** + * Called when a request is being retried + * + * @param Event $event Event emitted + */ + public function onRequestRetry(Event $event) + { + $this->logger->log($this->formatter->format( + $event['request'], + $event['response'], + $event['handle'], + array( + 'retries' => $event['retries'], + 'delay' => $event['delay'] + ) + )); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Backoff/BackoffPlugin.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Backoff/BackoffPlugin.php new file mode 100644 index 0000000..99ace05 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Backoff/BackoffPlugin.php @@ -0,0 +1,126 @@ +strategy = $strategy; + } + + /** + * Retrieve a basic truncated exponential backoff plugin that will retry HTTP errors and cURL errors + * + * @param int $maxRetries Maximum number of retries + * @param array $httpCodes HTTP response codes to retry + * @param array $curlCodes cURL error codes to retry + * + * @return self + */ + public static function getExponentialBackoff( + $maxRetries = 3, + array $httpCodes = null, + array $curlCodes = null + ) { + return new self(new TruncatedBackoffStrategy($maxRetries, + new HttpBackoffStrategy($httpCodes, + new CurlBackoffStrategy($curlCodes, + new ExponentialBackoffStrategy() + ) + ) + )); + } + + public static function getAllEvents() + { + return array(self::RETRY_EVENT); + } + + public static function getSubscribedEvents() + { + return array( + 'request.sent' => 'onRequestSent', + 'request.exception' => 'onRequestSent', + CurlMultiInterface::POLLING_REQUEST => 'onRequestPoll' + ); + } + + /** + * Called when a request has been sent and isn't finished processing + * + * @param Event $event + */ + public function onRequestSent(Event $event) + { + $request = $event['request']; + $response = $event['response']; + $exception = $event['exception']; + + $params = $request->getParams(); + $retries = (int) $params->get(self::RETRY_PARAM); + $delay = $this->strategy->getBackoffPeriod($retries, $request, $response, $exception); + + if ($delay !== false) { + // Calculate how long to wait until the request should be retried + $params->set(self::RETRY_PARAM, ++$retries) + ->set(self::DELAY_PARAM, microtime(true) + $delay); + // Send the request again + $request->setState(RequestInterface::STATE_TRANSFER); + $this->dispatch(self::RETRY_EVENT, array( + 'request' => $request, + 'response' => $response, + 'handle' => ($exception && $exception instanceof CurlException) ? $exception->getCurlHandle() : null, + 'retries' => $retries, + 'delay' => $delay + )); + } + } + + /** + * Called when a request is polling in the curl multi object + * + * @param Event $event + */ + public function onRequestPoll(Event $event) + { + $request = $event['request']; + $delay = $request->getParams()->get(self::DELAY_PARAM); + + // If the duration of the delay has passed, retry the request using the pool + if (null !== $delay && microtime(true) >= $delay) { + // Remove the request from the pool and then add it back again. This is required for cURL to know that we + // want to retry sending the easy handle. + $request->getParams()->remove(self::DELAY_PARAM); + // Rewind the request body if possible + if ($request instanceof EntityEnclosingRequestInterface && $request->getBody()) { + $request->getBody()->seek(0); + } + $multi = $event['curl_multi']; + $multi->remove($request); + $multi->add($request); + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Backoff/BackoffStrategyInterface.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Backoff/BackoffStrategyInterface.php new file mode 100644 index 0000000..4e590db --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Backoff/BackoffStrategyInterface.php @@ -0,0 +1,30 @@ +callback = $callback; + $this->decision = (bool) $decision; + $this->next = $next; + } + + public function makesDecision() + { + return $this->decision; + } + + protected function getDelay($retries, RequestInterface $request, Response $response = null, HttpException $e = null) + { + return call_user_func($this->callback, $retries, $request, $response, $e); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Backoff/ConstantBackoffStrategy.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Backoff/ConstantBackoffStrategy.php new file mode 100644 index 0000000..061d2a4 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Backoff/ConstantBackoffStrategy.php @@ -0,0 +1,34 @@ +delay = $delay; + } + + public function makesDecision() + { + return false; + } + + protected function getDelay($retries, RequestInterface $request, Response $response = null, HttpException $e = null) + { + return $this->delay; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Backoff/CurlBackoffStrategy.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Backoff/CurlBackoffStrategy.php new file mode 100644 index 0000000..a584ed4 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Backoff/CurlBackoffStrategy.php @@ -0,0 +1,28 @@ +errorCodes[$e->getErrorNo()]) ? true : null; + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Backoff/ExponentialBackoffStrategy.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Backoff/ExponentialBackoffStrategy.php new file mode 100644 index 0000000..fb2912d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Backoff/ExponentialBackoffStrategy.php @@ -0,0 +1,25 @@ +isSuccessful()) { + return false; + } else { + return isset($this->errorCodes[$response->getStatusCode()]) ? true : null; + } + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Backoff/LinearBackoffStrategy.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Backoff/LinearBackoffStrategy.php new file mode 100644 index 0000000..b35e8a4 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Backoff/LinearBackoffStrategy.php @@ -0,0 +1,36 @@ +step = $step; + } + + public function makesDecision() + { + return false; + } + + protected function getDelay($retries, RequestInterface $request, Response $response = null, HttpException $e = null) + { + return $retries * $this->step; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Backoff/ReasonPhraseBackoffStrategy.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Backoff/ReasonPhraseBackoffStrategy.php new file mode 100644 index 0000000..4fd73fe --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Backoff/ReasonPhraseBackoffStrategy.php @@ -0,0 +1,25 @@ +errorCodes[$response->getReasonPhrase()]) ? true : null; + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Backoff/TruncatedBackoffStrategy.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Backoff/TruncatedBackoffStrategy.php new file mode 100644 index 0000000..3608f35 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Backoff/TruncatedBackoffStrategy.php @@ -0,0 +1,36 @@ +max = $maxRetries; + $this->next = $next; + } + + public function makesDecision() + { + return true; + } + + protected function getDelay($retries, RequestInterface $request, Response $response = null, HttpException $e = null) + { + return $retries < $this->max ? null : false; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Backoff/composer.json b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Backoff/composer.json new file mode 100644 index 0000000..91c122c --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Backoff/composer.json @@ -0,0 +1,28 @@ +{ + "name": "guzzle/plugin-backoff", + "description": "Guzzle backoff retry plugins", + "homepage": "http://guzzlephp.org/", + "keywords": ["plugin", "guzzle"], + "license": "MIT", + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "require": { + "php": ">=5.3.2", + "guzzle/http": "self.version", + "guzzle/log": "self.version" + }, + "autoload": { + "psr-0": { "Guzzle\\Plugin\\Backoff": "" } + }, + "target-dir": "Guzzle/Plugin/Backoff", + "extra": { + "branch-alias": { + "dev-master": "3.7-dev" + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Cache/CacheKeyProviderInterface.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Cache/CacheKeyProviderInterface.php new file mode 100644 index 0000000..7790f88 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Cache/CacheKeyProviderInterface.php @@ -0,0 +1,11 @@ + new DefaultCacheStorage($options)); + } elseif ($options instanceof CacheStorageInterface) { + $options = array('storage' => $options); + } elseif ($options) { + $options = array('storage' => new DefaultCacheStorage(CacheAdapterFactory::fromCache($options))); + } elseif (!class_exists('Doctrine\Common\Cache\ArrayCache')) { + // @codeCoverageIgnoreStart + throw new InvalidArgumentException('No cache was provided and Doctrine is not installed'); + // @codeCoverageIgnoreEnd + } + } + + $this->autoPurge = isset($options['auto_purge']) ? $options['auto_purge'] : false; + + // Add a cache storage if a cache adapter was provided + $this->storage = isset($options['storage']) + ? $options['storage'] + : new DefaultCacheStorage(new DoctrineCacheAdapter(new ArrayCache())); + + if (!isset($options['can_cache'])) { + $this->canCache = new DefaultCanCacheStrategy(); + } else { + $this->canCache = is_callable($options['can_cache']) + ? new CallbackCanCacheStrategy($options['can_cache']) + : $options['can_cache']; + } + + // Use the provided revalidation strategy or the default + $this->revalidation = isset($options['revalidation']) + ? $options['revalidation'] + : new DefaultRevalidation($this->storage, $this->canCache); + } + + public static function getSubscribedEvents() + { + return array( + 'request.before_send' => array('onRequestBeforeSend', -255), + 'request.sent' => array('onRequestSent', 255), + 'request.error' => array('onRequestError', 0), + 'request.exception' => array('onRequestException', 0), + ); + } + + /** + * Check if a response in cache will satisfy the request before sending + * + * @param Event $event + */ + public function onRequestBeforeSend(Event $event) + { + $request = $event['request']; + $request->addHeader('Via', sprintf('%s GuzzleCache/%s', $request->getProtocolVersion(), Version::VERSION)); + + if (!$this->canCache->canCacheRequest($request)) { + switch ($request->getMethod()) { + case 'PURGE': + $this->purge($request); + $request->setResponse(new Response(200, array(), 'purged')); + break; + case 'PUT': + case 'POST': + case 'DELETE': + case 'PATCH': + if ($this->autoPurge) { + $this->purge($request); + } + } + return; + } + + if ($response = $this->storage->fetch($request)) { + $params = $request->getParams(); + $params['cache.lookup'] = true; + $response->setHeader( + 'Age', + time() - strtotime($response->getDate() ? : $response->getLastModified() ?: 'now') + ); + // Validate that the response satisfies the request + if ($this->canResponseSatisfyRequest($request, $response)) { + if (!isset($params['cache.hit'])) { + $params['cache.hit'] = true; + } + $request->setResponse($response); + } + } + } + + /** + * If possible, store a response in cache after sending + * + * @param Event $event + */ + public function onRequestSent(Event $event) + { + $request = $event['request']; + $response = $event['response']; + + if ($request->getParams()->get('cache.hit') === null && + $this->canCache->canCacheRequest($request) && + $this->canCache->canCacheResponse($response) + ) { + $this->storage->cache($request, $response); + } + + $this->addResponseHeaders($request, $response); + } + + /** + * If possible, return a cache response on an error + * + * @param Event $event + */ + public function onRequestError(Event $event) + { + $request = $event['request']; + + if (!$this->canCache->canCacheRequest($request)) { + return; + } + + if ($response = $this->storage->fetch($request)) { + $response->setHeader( + 'Age', + time() - strtotime($response->getLastModified() ? : $response->getDate() ?: 'now') + ); + + if ($this->canResponseSatisfyFailedRequest($request, $response)) { + $request->getParams()->set('cache.hit', 'error'); + $this->addResponseHeaders($request, $response); + $event['response'] = $response; + $event->stopPropagation(); + } + } + } + + /** + * If possible, set a cache response on a cURL exception + * + * @param Event $event + * + * @return null + */ + public function onRequestException(Event $event) + { + if (!$event['exception'] instanceof CurlException) { + return; + } + + $request = $event['request']; + if (!$this->canCache->canCacheRequest($request)) { + return; + } + + if ($response = $this->storage->fetch($request)) { + $response->setHeader('Age', time() - strtotime($response->getDate() ? : 'now')); + if (!$this->canResponseSatisfyFailedRequest($request, $response)) { + return; + } + $request->getParams()->set('cache.hit', 'error'); + $request->setResponse($response); + $this->addResponseHeaders($request, $response); + $event->stopPropagation(); + } + } + + /** + * Check if a cache response satisfies a request's caching constraints + * + * @param RequestInterface $request Request to validate + * @param Response $response Response to validate + * + * @return bool + */ + public function canResponseSatisfyRequest(RequestInterface $request, Response $response) + { + $responseAge = $response->calculateAge(); + $reqc = $request->getHeader('Cache-Control'); + $resc = $response->getHeader('Cache-Control'); + + // Check the request's max-age header against the age of the response + if ($reqc && $reqc->hasDirective('max-age') && + $responseAge > $reqc->getDirective('max-age')) { + return false; + } + + // Check the response's max-age header + if ($response->isFresh() === false) { + $maxStale = $reqc ? $reqc->getDirective('max-stale') : null; + if (null !== $maxStale) { + if ($maxStale !== true && $response->getFreshness() < (-1 * $maxStale)) { + return false; + } + } elseif ($resc && $resc->hasDirective('max-age') + && $responseAge > $resc->getDirective('max-age') + ) { + return false; + } + } + + if ($this->revalidation->shouldRevalidate($request, $response)) { + try { + return $this->revalidation->revalidate($request, $response); + } catch (CurlException $e) { + $request->getParams()->set('cache.hit', 'error'); + return $this->canResponseSatisfyFailedRequest($request, $response); + } + } + + return true; + } + + /** + * Check if a cache response satisfies a failed request's caching constraints + * + * @param RequestInterface $request Request to validate + * @param Response $response Response to validate + * + * @return bool + */ + public function canResponseSatisfyFailedRequest(RequestInterface $request, Response $response) + { + $reqc = $request->getHeader('Cache-Control'); + $resc = $response->getHeader('Cache-Control'); + $requestStaleIfError = $reqc ? $reqc->getDirective('stale-if-error') : null; + $responseStaleIfError = $resc ? $resc->getDirective('stale-if-error') : null; + + if (!$requestStaleIfError && !$responseStaleIfError) { + return false; + } + + if (is_numeric($requestStaleIfError) && $response->getAge() - $response->getMaxAge() > $requestStaleIfError) { + return false; + } + + if (is_numeric($responseStaleIfError) && $response->getAge() - $response->getMaxAge() > $responseStaleIfError) { + return false; + } + + return true; + } + + /** + * Purge all cache entries for a given URL + * + * @param string $url URL to purge + */ + public function purge($url) + { + // BC compatibility with previous version that accepted a Request object + $url = $url instanceof RequestInterface ? $url->getUrl() : $url; + $this->storage->purge($url); + } + + /** + * Add the plugin's headers to a response + * + * @param RequestInterface $request Request + * @param Response $response Response to add headers to + */ + protected function addResponseHeaders(RequestInterface $request, Response $response) + { + $params = $request->getParams(); + $response->setHeader('Via', sprintf('%s GuzzleCache/%s', $request->getProtocolVersion(), Version::VERSION)); + + $lookup = ($params['cache.lookup'] === true ? 'HIT' : 'MISS') . ' from GuzzleCache'; + if ($header = $response->getHeader('X-Cache-Lookup')) { + // Don't add duplicates + $values = $header->toArray(); + $values[] = $lookup; + $response->setHeader('X-Cache-Lookup', array_unique($values)); + } else { + $response->setHeader('X-Cache-Lookup', $lookup); + } + + if ($params['cache.hit'] === true) { + $xcache = 'HIT from GuzzleCache'; + } elseif ($params['cache.hit'] == 'error') { + $xcache = 'HIT_ERROR from GuzzleCache'; + } else { + $xcache = 'MISS from GuzzleCache'; + } + + if ($header = $response->getHeader('X-Cache')) { + // Don't add duplicates + $values = $header->toArray(); + $values[] = $xcache; + $response->setHeader('X-Cache', array_unique($values)); + } else { + $response->setHeader('X-Cache', $xcache); + } + + if ($response->isFresh() === false) { + $response->addHeader('Warning', sprintf('110 GuzzleCache/%s "Response is stale"', Version::VERSION)); + if ($params['cache.hit'] === 'error') { + $response->addHeader('Warning', sprintf('111 GuzzleCache/%s "Revalidation failed"', Version::VERSION)); + } + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Cache/CacheStorageInterface.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Cache/CacheStorageInterface.php new file mode 100644 index 0000000..f3d9154 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Cache/CacheStorageInterface.php @@ -0,0 +1,43 @@ +requestCallback = $requestCallback; + $this->responseCallback = $responseCallback; + } + + public function canCacheRequest(RequestInterface $request) + { + return $this->requestCallback + ? call_user_func($this->requestCallback, $request) + : parent::canCacheRequest($request); + } + + public function canCacheResponse(Response $response) + { + return $this->responseCallback + ? call_user_func($this->responseCallback, $response) + : parent::canCacheResponse($response); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Cache/CanCacheStrategyInterface.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Cache/CanCacheStrategyInterface.php new file mode 100644 index 0000000..6e01a8e --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Cache/CanCacheStrategyInterface.php @@ -0,0 +1,30 @@ +getParams()->get(self::CACHE_KEY); + + if (!$key) { + + $cloned = clone $request; + $cloned->removeHeader('Cache-Control'); + + // Check to see how and if the key should be filtered + foreach (explode(';', $request->getParams()->get(self::CACHE_KEY_FILTER)) as $part) { + $pieces = array_map('trim', explode('=', $part)); + if (isset($pieces[1])) { + foreach (array_map('trim', explode(',', $pieces[1])) as $remove) { + if ($pieces[0] == 'header') { + $cloned->removeHeader($remove); + } elseif ($pieces[0] == 'query') { + $cloned->getQuery()->remove($remove); + } + } + } + } + + $raw = (string) $cloned; + $key = 'GZ' . md5($raw); + $request->getParams()->set(self::CACHE_KEY, $key)->set(self::CACHE_KEY_RAW, $raw); + } + + return $key; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Cache/DefaultCacheStorage.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Cache/DefaultCacheStorage.php new file mode 100644 index 0000000..26d7a8b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Cache/DefaultCacheStorage.php @@ -0,0 +1,266 @@ +cache = CacheAdapterFactory::fromCache($cache); + $this->defaultTtl = $defaultTtl; + $this->keyPrefix = $keyPrefix; + } + + public function cache(RequestInterface $request, Response $response) + { + $currentTime = time(); + + $overrideTtl = $request->getParams()->get('cache.override_ttl'); + if ($overrideTtl) { + $ttl = $overrideTtl; + } else { + $maxAge = $response->getMaxAge(); + if ($maxAge !== null) { + $ttl = $maxAge; + } else { + $ttl = $this->defaultTtl; + } + } + + if ($cacheControl = $response->getHeader('Cache-Control')) { + $stale = $cacheControl->getDirective('stale-if-error'); + if ($stale === true) { + $ttl += $ttl; + } else if (is_numeric($stale)) { + $ttl += $stale; + } + } + + // Determine which manifest key should be used + $key = $this->getCacheKey($request); + $persistedRequest = $this->persistHeaders($request); + $entries = array(); + + if ($manifest = $this->cache->fetch($key)) { + // Determine which cache entries should still be in the cache + $vary = $response->getVary(); + foreach (unserialize($manifest) as $entry) { + // Check if the entry is expired + if ($entry[4] < $currentTime) { + continue; + } + $entry[1]['vary'] = isset($entry[1]['vary']) ? $entry[1]['vary'] : ''; + if ($vary != $entry[1]['vary'] || !$this->requestsMatch($vary, $entry[0], $persistedRequest)) { + $entries[] = $entry; + } + } + } + + // Persist the response body if needed + $bodyDigest = null; + if ($response->getBody() && $response->getBody()->getContentLength() > 0) { + $bodyDigest = $this->getBodyKey($request->getUrl(), $response->getBody()); + $this->cache->save($bodyDigest, (string) $response->getBody(), $ttl); + } + + array_unshift($entries, array( + $persistedRequest, + $this->persistHeaders($response), + $response->getStatusCode(), + $bodyDigest, + $currentTime + $ttl + )); + + $this->cache->save($key, serialize($entries)); + } + + public function delete(RequestInterface $request) + { + $key = $this->getCacheKey($request); + if ($entries = $this->cache->fetch($key)) { + // Delete each cached body + foreach (unserialize($entries) as $entry) { + if ($entry[3]) { + $this->cache->delete($entry[3]); + } + } + $this->cache->delete($key); + } + } + + public function purge($url) + { + foreach (array('GET', 'HEAD', 'POST', 'PUT', 'DELETE') as $method) { + $this->delete(new Request($method, $url)); + } + } + + public function fetch(RequestInterface $request) + { + $key = $this->getCacheKey($request); + if (!($entries = $this->cache->fetch($key))) { + return null; + } + + $match = null; + $headers = $this->persistHeaders($request); + $entries = unserialize($entries); + foreach ($entries as $index => $entry) { + if ($this->requestsMatch(isset($entry[1]['vary']) ? $entry[1]['vary'] : '', $headers, $entry[0])) { + $match = $entry; + break; + } + } + + if (!$match) { + return null; + } + + // Ensure that the response is not expired + $response = null; + if ($match[4] < time()) { + $response = -1; + } else { + $response = new Response($match[2], $match[1]); + if ($match[3]) { + if ($body = $this->cache->fetch($match[3])) { + $response->setBody($body); + } else { + // The response is not valid because the body was somehow deleted + $response = -1; + } + } + } + + if ($response === -1) { + // Remove the entry from the metadata and update the cache + unset($entries[$index]); + if ($entries) { + $this->cache->save($key, serialize($entries)); + } else { + $this->cache->delete($key); + } + return null; + } + + return $response; + } + + /** + * Hash a request URL into a string that returns cache metadata + * + * @param RequestInterface $request + * + * @return string + */ + protected function getCacheKey(RequestInterface $request) + { + // Allow cache.key_filter to trim down the URL cache key by removing generate query string values (e.g. auth) + if ($filter = $request->getParams()->get('cache.key_filter')) { + $url = $request->getUrl(true); + foreach (explode(',', $filter) as $remove) { + $url->getQuery()->remove(trim($remove)); + } + } else { + $url = $request->getUrl(); + } + + return $this->keyPrefix . md5($request->getMethod() . ' ' . $url); + } + + /** + * Create a cache key for a response's body + * + * @param string $url URL of the entry + * @param EntityBodyInterface $body Response body + * + * @return string + */ + protected function getBodyKey($url, EntityBodyInterface $body) + { + return $this->keyPrefix . md5($url) . $body->getContentMd5(); + } + + /** + * Determines whether two Request HTTP header sets are non-varying + * + * @param string $vary Response vary header + * @param array $r1 HTTP header array + * @param array $r2 HTTP header array + * + * @return bool + */ + private function requestsMatch($vary, $r1, $r2) + { + if ($vary) { + foreach (explode(',', $vary) as $header) { + $key = trim(strtolower($header)); + $v1 = isset($r1[$key]) ? $r1[$key] : null; + $v2 = isset($r2[$key]) ? $r2[$key] : null; + if ($v1 !== $v2) { + return false; + } + } + } + + return true; + } + + /** + * Creates an array of cacheable and normalized message headers + * + * @param MessageInterface $message + * + * @return array + */ + private function persistHeaders(MessageInterface $message) + { + // Headers are excluded from the caching (see RFC 2616:13.5.1) + static $noCache = array( + 'age' => true, + 'connection' => true, + 'keep-alive' => true, + 'proxy-authenticate' => true, + 'proxy-authorization' => true, + 'te' => true, + 'trailers' => true, + 'transfer-encoding' => true, + 'upgrade' => true, + 'set-cookie' => true, + 'set-cookie2' => true + ); + + // Clone the response to not destroy any necessary headers when caching + $headers = $message->getHeaders()->getAll(); + $headers = array_diff_key($headers, $noCache); + // Cast the headers to a string + $headers = array_map(function ($h) { return (string) $h; }, $headers); + + return $headers; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Cache/DefaultCanCacheStrategy.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Cache/DefaultCanCacheStrategy.php new file mode 100644 index 0000000..3ca1fbf --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Cache/DefaultCanCacheStrategy.php @@ -0,0 +1,32 @@ +getMethod() != RequestInterface::GET && $request->getMethod() != RequestInterface::HEAD) { + return false; + } + + // Never cache requests when using no-store + if ($request->hasHeader('Cache-Control') && $request->getHeader('Cache-Control')->hasDirective('no-store')) { + return false; + } + + return true; + } + + public function canCacheResponse(Response $response) + { + return $response->isSuccessful() && $response->canCache(); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Cache/DefaultRevalidation.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Cache/DefaultRevalidation.php new file mode 100644 index 0000000..af33234 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Cache/DefaultRevalidation.php @@ -0,0 +1,174 @@ +storage = $cache; + $this->canCache = $canCache ?: new DefaultCanCacheStrategy(); + } + + public function revalidate(RequestInterface $request, Response $response) + { + try { + $revalidate = $this->createRevalidationRequest($request, $response); + $validateResponse = $revalidate->send(); + if ($validateResponse->getStatusCode() == 200) { + return $this->handle200Response($request, $validateResponse); + } elseif ($validateResponse->getStatusCode() == 304) { + return $this->handle304Response($request, $validateResponse, $response); + } + } catch (BadResponseException $e) { + $this->handleBadResponse($e); + } + + // Other exceptions encountered in the revalidation request are ignored + // in hopes that sending a request to the origin server will fix it + return false; + } + + public function shouldRevalidate(RequestInterface $request, Response $response) + { + if ($request->getMethod() != RequestInterface::GET) { + return false; + } + + $reqCache = $request->getHeader('Cache-Control'); + $resCache = $response->getHeader('Cache-Control'); + + $revalidate = $request->getHeader('Pragma') == 'no-cache' || + ($reqCache && ($reqCache->hasDirective('no-cache') || $reqCache->hasDirective('must-revalidate'))) || + ($resCache && ($resCache->hasDirective('no-cache') || $resCache->hasDirective('must-revalidate'))); + + // Use the strong ETag validator if available and the response contains no Cache-Control directive + if (!$revalidate && !$resCache && $response->hasHeader('ETag')) { + $revalidate = true; + } + + return $revalidate; + } + + /** + * Handles a bad response when attempting to revalidate + * + * @param BadResponseException $e Exception encountered + * + * @throws BadResponseException + */ + protected function handleBadResponse(BadResponseException $e) + { + // 404 errors mean the resource no longer exists, so remove from + // cache, and prevent an additional request by throwing the exception + if ($e->getResponse()->getStatusCode() == 404) { + $this->storage->delete($e->getRequest()); + throw $e; + } + } + + /** + * Creates a request to use for revalidation + * + * @param RequestInterface $request Request + * @param Response $response Response to revalidate + * + * @return RequestInterface returns a revalidation request + */ + protected function createRevalidationRequest(RequestInterface $request, Response $response) + { + $revalidate = clone $request; + $revalidate->removeHeader('Pragma')->removeHeader('Cache-Control'); + + if ($response->getLastModified()) { + $revalidate->setHeader('If-Modified-Since', $response->getLastModified()); + } + + if ($response->getEtag()) { + $revalidate->setHeader('If-None-Match', $response->getEtag()); + } + + // Remove any cache plugins that might be on the request to prevent infinite recursive revalidations + $dispatcher = $revalidate->getEventDispatcher(); + foreach ($dispatcher->getListeners() as $eventName => $listeners) { + foreach ($listeners as $listener) { + if (is_array($listener) && $listener[0] instanceof CachePlugin) { + $dispatcher->removeListener($eventName, $listener); + } + } + } + + return $revalidate; + } + + /** + * Handles a 200 response response from revalidating. The server does not support validation, so use this response. + * + * @param RequestInterface $request Request that was sent + * @param Response $validateResponse Response received + * + * @return bool Returns true if valid, false if invalid + */ + protected function handle200Response(RequestInterface $request, Response $validateResponse) + { + $request->setResponse($validateResponse); + if ($this->canCache->canCacheResponse($validateResponse)) { + $this->storage->cache($request, $validateResponse); + } + + return false; + } + + /** + * Handle a 304 response and ensure that it is still valid + * + * @param RequestInterface $request Request that was sent + * @param Response $validateResponse Response received + * @param Response $response Original cached response + * + * @return bool Returns true if valid, false if invalid + */ + protected function handle304Response(RequestInterface $request, Response $validateResponse, Response $response) + { + static $replaceHeaders = array('Date', 'Expires', 'Cache-Control', 'ETag', 'Last-Modified'); + + // Make sure that this response has the same ETag + if ($validateResponse->getEtag() != $response->getEtag()) { + return false; + } + + // Replace cached headers with any of these headers from the + // origin server that might be more up to date + $modified = false; + foreach ($replaceHeaders as $name) { + if ($validateResponse->hasHeader($name)) { + $modified = true; + $response->setHeader($name, $validateResponse->getHeader($name)); + } + } + + // Store the updated response in cache + if ($modified && $this->canCache->canCacheResponse($response)) { + $this->storage->cache($request, $response); + } + + return true; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Cache/DenyRevalidation.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Cache/DenyRevalidation.php new file mode 100644 index 0000000..88b86f3 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Cache/DenyRevalidation.php @@ -0,0 +1,19 @@ +=5.3.2", + "guzzle/http": "self.version", + "guzzle/cache": "self.version" + }, + "autoload": { + "psr-0": { "Guzzle\\Plugin\\Cache": "" } + }, + "target-dir": "Guzzle/Plugin/Cache", + "extra": { + "branch-alias": { + "dev-master": "3.7-dev" + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Cookie/Cookie.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Cookie/Cookie.php new file mode 100644 index 0000000..5218e5f --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Cookie/Cookie.php @@ -0,0 +1,538 @@ + '', + 'value' => '', + 'domain' => '', + 'path' => '/', + 'expires' => null, + 'max_age' => 0, + 'comment' => null, + 'comment_url' => null, + 'port' => array(), + 'version' => null, + 'secure' => false, + 'discard' => false, + 'http_only' => false + ); + + $this->data = array_merge($defaults, $data); + // Extract the expires value and turn it into a UNIX timestamp if needed + if (!$this->getExpires() && $this->getMaxAge()) { + // Calculate the expires date + $this->setExpires(time() + (int) $this->getMaxAge()); + } elseif ($this->getExpires() && !is_numeric($this->getExpires())) { + $this->setExpires(strtotime($this->getExpires())); + } + } + + /** + * Get the cookie as an array + * + * @return array + */ + public function toArray() + { + return $this->data; + } + + /** + * Get the cookie name + * + * @return string + */ + public function getName() + { + return $this->data['name']; + } + + /** + * Set the cookie name + * + * @param string $name Cookie name + * + * @return Cookie + */ + public function setName($name) + { + return $this->setData('name', $name); + } + + /** + * Get the cookie value + * + * @return string + */ + public function getValue() + { + return $this->data['value']; + } + + /** + * Set the cookie value + * + * @param string $value Cookie value + * + * @return Cookie + */ + public function setValue($value) + { + return $this->setData('value', $value); + } + + /** + * Get the domain + * + * @return string|null + */ + public function getDomain() + { + return $this->data['domain']; + } + + /** + * Set the domain of the cookie + * + * @param string $domain + * + * @return Cookie + */ + public function setDomain($domain) + { + return $this->setData('domain', $domain); + } + + /** + * Get the path + * + * @return string + */ + public function getPath() + { + return $this->data['path']; + } + + /** + * Set the path of the cookie + * + * @param string $path Path of the cookie + * + * @return Cookie + */ + public function setPath($path) + { + return $this->setData('path', $path); + } + + /** + * Maximum lifetime of the cookie in seconds + * + * @return int|null + */ + public function getMaxAge() + { + return $this->data['max_age']; + } + + /** + * Set the max-age of the cookie + * + * @param int $maxAge Max age of the cookie in seconds + * + * @return Cookie + */ + public function setMaxAge($maxAge) + { + return $this->setData('max_age', $maxAge); + } + + /** + * The UNIX timestamp when the cookie expires + * + * @return mixed + */ + public function getExpires() + { + return $this->data['expires']; + } + + /** + * Set the unix timestamp for which the cookie will expire + * + * @param int $timestamp Unix timestamp + * + * @return Cookie + */ + public function setExpires($timestamp) + { + return $this->setData('expires', $timestamp); + } + + /** + * Version of the cookie specification. RFC 2965 is 1 + * + * @return mixed + */ + public function getVersion() + { + return $this->data['version']; + } + + /** + * Set the cookie version + * + * @param string|int $version Version to set + * + * @return Cookie + */ + public function setVersion($version) + { + return $this->setData('version', $version); + } + + /** + * Get whether or not this is a secure cookie + * + * @return null|bool + */ + public function getSecure() + { + return $this->data['secure']; + } + + /** + * Set whether or not the cookie is secure + * + * @param bool $secure Set to true or false if secure + * + * @return Cookie + */ + public function setSecure($secure) + { + return $this->setData('secure', (bool) $secure); + } + + /** + * Get whether or not this is a session cookie + * + * @return null|bool + */ + public function getDiscard() + { + return $this->data['discard']; + } + + /** + * Set whether or not this is a session cookie + * + * @param bool $discard Set to true or false if this is a session cookie + * + * @return Cookie + */ + public function setDiscard($discard) + { + return $this->setData('discard', $discard); + } + + /** + * Get the comment + * + * @return string|null + */ + public function getComment() + { + return $this->data['comment']; + } + + /** + * Set the comment of the cookie + * + * @param string $comment Cookie comment + * + * @return Cookie + */ + public function setComment($comment) + { + return $this->setData('comment', $comment); + } + + /** + * Get the comment URL of the cookie + * + * @return string|null + */ + public function getCommentUrl() + { + return $this->data['comment_url']; + } + + /** + * Set the comment URL of the cookie + * + * @param string $commentUrl Cookie comment URL for more information + * + * @return Cookie + */ + public function setCommentUrl($commentUrl) + { + return $this->setData('comment_url', $commentUrl); + } + + /** + * Get an array of acceptable ports this cookie can be used with + * + * @return array + */ + public function getPorts() + { + return $this->data['port']; + } + + /** + * Set a list of acceptable ports this cookie can be used with + * + * @param array $ports Array of acceptable ports + * + * @return Cookie + */ + public function setPorts(array $ports) + { + return $this->setData('port', $ports); + } + + /** + * Get whether or not this is an HTTP only cookie + * + * @return bool + */ + public function getHttpOnly() + { + return $this->data['http_only']; + } + + /** + * Set whether or not this is an HTTP only cookie + * + * @param bool $httpOnly Set to true or false if this is HTTP only + * + * @return Cookie + */ + public function setHttpOnly($httpOnly) + { + return $this->setData('http_only', $httpOnly); + } + + /** + * Get an array of extra cookie data + * + * @return array + */ + public function getAttributes() + { + return $this->data['data']; + } + + /** + * Get a specific data point from the extra cookie data + * + * @param string $name Name of the data point to retrieve + * + * @return null|string + */ + public function getAttribute($name) + { + return array_key_exists($name, $this->data['data']) ? $this->data['data'][$name] : null; + } + + /** + * Set a cookie data attribute + * + * @param string $name Name of the attribute to set + * @param string $value Value to set + * + * @return Cookie + */ + public function setAttribute($name, $value) + { + $this->data['data'][$name] = $value; + + return $this; + } + + /** + * Check if the cookie matches a path value + * + * @param string $path Path to check against + * + * @return bool + */ + public function matchesPath($path) + { + // RFC6265 http://tools.ietf.org/search/rfc6265#section-5.1.4 + // A request-path path-matches a given cookie-path if at least one of + // the following conditions holds: + + // o The cookie-path and the request-path are identical. + if ($path == $this->getPath()) { + return true; + } + + $pos = stripos($path, $this->getPath()); + if ($pos === 0) { + // o The cookie-path is a prefix of the request-path, and the last + // character of the cookie-path is %x2F ("/"). + if (substr($this->getPath(), -1, 1) === "/") { + return true; + } + + // o The cookie-path is a prefix of the request-path, and the first + // character of the request-path that is not included in the cookie- + // path is a %x2F ("/") character. + if (substr($path, strlen($this->getPath()), 1) === "/") { + return true; + } + } + + return false; + } + + /** + * Check if the cookie matches a domain value + * + * @param string $domain Domain to check against + * + * @return bool + */ + public function matchesDomain($domain) + { + // Remove the leading '.' as per spec in RFC 6265: http://tools.ietf.org/html/rfc6265#section-5.2.3 + $cookieDomain = ltrim($this->getDomain(), '.'); + + // Domain not set or exact match. + if (!$cookieDomain || !strcasecmp($domain, $cookieDomain)) { + return true; + } + + // Matching the subdomain according to RFC 6265: http://tools.ietf.org/html/rfc6265#section-5.1.3 + if (filter_var($domain, FILTER_VALIDATE_IP)) { + return false; + } + + return (bool) preg_match('/\.' . preg_quote($cookieDomain, '/') . '$/i', $domain); + } + + /** + * Check if the cookie is compatible with a specific port + * + * @param int $port Port to check + * + * @return bool + */ + public function matchesPort($port) + { + return count($this->getPorts()) == 0 || in_array($port, $this->getPorts()); + } + + /** + * Check if the cookie is expired + * + * @return bool + */ + public function isExpired() + { + return $this->getExpires() && time() > $this->getExpires(); + } + + /** + * Check if the cookie is valid according to RFC 6265 + * + * @return bool|string Returns true if valid or an error message if invalid + */ + public function validate() + { + // Names must not be empty, but can be 0 + $name = $this->getName(); + if (empty($name) && !is_numeric($name)) { + return 'The cookie name must not be empty'; + } + + // Check if any of the invalid characters are present in the cookie name + if (strpbrk($name, self::getInvalidCharacters()) !== false) { + return 'The cookie name must not contain invalid characters: ' . $name; + } + + // Value must not be empty, but can be 0 + $value = $this->getValue(); + if (empty($value) && !is_numeric($value)) { + return 'The cookie value must not be empty'; + } + + // Domains must not be empty, but can be 0 + // A "0" is not a valid internet domain, but may be used as server name in a private network + $domain = $this->getDomain(); + if (empty($domain) && !is_numeric($domain)) { + return 'The cookie domain must not be empty'; + } + + return true; + } + + /** + * Set a value and return the cookie object + * + * @param string $key Key to set + * @param string $value Value to set + * + * @return Cookie + */ + private function setData($key, $value) + { + $this->data[$key] = $value; + + return $this; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Cookie/CookieJar/ArrayCookieJar.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Cookie/CookieJar/ArrayCookieJar.php new file mode 100644 index 0000000..6b67503 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Cookie/CookieJar/ArrayCookieJar.php @@ -0,0 +1,237 @@ +strictMode = $strictMode; + } + + /** + * Enable or disable strict mode on the cookie jar + * + * @param bool $strictMode Set to true to throw exceptions when invalid cookies are added. False to ignore them. + * + * @return self + */ + public function setStrictMode($strictMode) + { + $this->strictMode = $strictMode; + } + + public function remove($domain = null, $path = null, $name = null) + { + $cookies = $this->all($domain, $path, $name, false, false); + $this->cookies = array_filter($this->cookies, function (Cookie $cookie) use ($cookies) { + return !in_array($cookie, $cookies, true); + }); + + return $this; + } + + public function removeTemporary() + { + $this->cookies = array_filter($this->cookies, function (Cookie $cookie) { + return !$cookie->getDiscard() && $cookie->getExpires(); + }); + + return $this; + } + + public function removeExpired() + { + $currentTime = time(); + $this->cookies = array_filter($this->cookies, function (Cookie $cookie) use ($currentTime) { + return !$cookie->getExpires() || $currentTime < $cookie->getExpires(); + }); + + return $this; + } + + public function all($domain = null, $path = null, $name = null, $skipDiscardable = false, $skipExpired = true) + { + return array_values(array_filter($this->cookies, function (Cookie $cookie) use ( + $domain, + $path, + $name, + $skipDiscardable, + $skipExpired + ) { + return false === (($name && $cookie->getName() != $name) || + ($skipExpired && $cookie->isExpired()) || + ($skipDiscardable && ($cookie->getDiscard() || !$cookie->getExpires())) || + ($path && !$cookie->matchesPath($path)) || + ($domain && !$cookie->matchesDomain($domain))); + })); + } + + public function add(Cookie $cookie) + { + // Only allow cookies with set and valid domain, name, value + $result = $cookie->validate(); + if ($result !== true) { + if ($this->strictMode) { + throw new InvalidCookieException($result); + } else { + $this->removeCookieIfEmpty($cookie); + return false; + } + } + + // Resolve conflicts with previously set cookies + foreach ($this->cookies as $i => $c) { + + // Two cookies are identical, when their path, domain, port and name are identical + if ($c->getPath() != $cookie->getPath() || + $c->getDomain() != $cookie->getDomain() || + $c->getPorts() != $cookie->getPorts() || + $c->getName() != $cookie->getName() + ) { + continue; + } + + // The previously set cookie is a discard cookie and this one is not so allow the new cookie to be set + if (!$cookie->getDiscard() && $c->getDiscard()) { + unset($this->cookies[$i]); + continue; + } + + // If the new cookie's expiration is further into the future, then replace the old cookie + if ($cookie->getExpires() > $c->getExpires()) { + unset($this->cookies[$i]); + continue; + } + + // If the value has changed, we better change it + if ($cookie->getValue() !== $c->getValue()) { + unset($this->cookies[$i]); + continue; + } + + // The cookie exists, so no need to continue + return false; + } + + $this->cookies[] = $cookie; + + return true; + } + + /** + * Serializes the cookie cookieJar + * + * @return string + */ + public function serialize() + { + // Only serialize long term cookies and unexpired cookies + return json_encode(array_map(function (Cookie $cookie) { + return $cookie->toArray(); + }, $this->all(null, null, null, true, true))); + } + + /** + * Unserializes the cookie cookieJar + */ + public function unserialize($data) + { + $data = json_decode($data, true); + if (empty($data)) { + $this->cookies = array(); + } else { + $this->cookies = array_map(function (array $cookie) { + return new Cookie($cookie); + }, $data); + } + } + + /** + * Returns the total number of stored cookies + * + * @return int + */ + public function count() + { + return count($this->cookies); + } + + /** + * Returns an iterator + * + * @return \ArrayIterator + */ + public function getIterator() + { + return new \ArrayIterator($this->cookies); + } + + public function addCookiesFromResponse(Response $response, RequestInterface $request = null) + { + if ($cookieHeader = $response->getHeader('Set-Cookie')) { + $parser = ParserRegistry::getInstance()->getParser('cookie'); + foreach ($cookieHeader as $cookie) { + if ($parsed = $request + ? $parser->parseCookie($cookie, $request->getHost(), $request->getPath()) + : $parser->parseCookie($cookie) + ) { + // Break up cookie v2 into multiple cookies + foreach ($parsed['cookies'] as $key => $value) { + $row = $parsed; + $row['name'] = $key; + $row['value'] = $value; + unset($row['cookies']); + $this->add(new Cookie($row)); + } + } + } + } + } + + public function getMatchingCookies(RequestInterface $request) + { + // Find cookies that match this request + $cookies = $this->all($request->getHost(), $request->getPath()); + // Remove ineligible cookies + foreach ($cookies as $index => $cookie) { + if (!$cookie->matchesPort($request->getPort()) || ($cookie->getSecure() && $request->getScheme() != 'https')) { + unset($cookies[$index]); + } + }; + + return $cookies; + } + + /** + * If a cookie already exists and the server asks to set it again with a null value, the + * cookie must be deleted. + * + * @param \Guzzle\Plugin\Cookie\Cookie $cookie + */ + private function removeCookieIfEmpty(Cookie $cookie) + { + $cookieValue = $cookie->getValue(); + if ($cookieValue === null || $cookieValue === '') { + $this->remove($cookie->getDomain(), $cookie->getPath(), $cookie->getName()); + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Cookie/CookieJar/CookieJarInterface.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Cookie/CookieJar/CookieJarInterface.php new file mode 100644 index 0000000..7faa7d2 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Cookie/CookieJar/CookieJarInterface.php @@ -0,0 +1,85 @@ +filename = $cookieFile; + $this->load(); + } + + /** + * Saves the file when shutting down + */ + public function __destruct() + { + $this->persist(); + } + + /** + * Save the contents of the data array to the file + * + * @throws RuntimeException if the file cannot be found or created + */ + protected function persist() + { + if (false === file_put_contents($this->filename, $this->serialize())) { + // @codeCoverageIgnoreStart + throw new RuntimeException('Unable to open file ' . $this->filename); + // @codeCoverageIgnoreEnd + } + } + + /** + * Load the contents of the json formatted file into the data array and discard any unsaved state + */ + protected function load() + { + $json = file_get_contents($this->filename); + if (false === $json) { + // @codeCoverageIgnoreStart + throw new RuntimeException('Unable to open file ' . $this->filename); + // @codeCoverageIgnoreEnd + } + + $this->unserialize($json); + $this->cookies = $this->cookies ?: array(); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Cookie/CookiePlugin.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Cookie/CookiePlugin.php new file mode 100644 index 0000000..df3210e --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Cookie/CookiePlugin.php @@ -0,0 +1,70 @@ +cookieJar = $cookieJar ?: new ArrayCookieJar(); + } + + public static function getSubscribedEvents() + { + return array( + 'request.before_send' => array('onRequestBeforeSend', 125), + 'request.sent' => array('onRequestSent', 125) + ); + } + + /** + * Get the cookie cookieJar + * + * @return CookieJarInterface + */ + public function getCookieJar() + { + return $this->cookieJar; + } + + /** + * Add cookies before a request is sent + * + * @param Event $event + */ + public function onRequestBeforeSend(Event $event) + { + $request = $event['request']; + if (!$request->getParams()->get('cookies.disable')) { + $request->removeHeader('Cookie'); + // Find cookies that match this request + foreach ($this->cookieJar->getMatchingCookies($request) as $cookie) { + $request->addCookie($cookie->getName(), $cookie->getValue()); + } + } + } + + /** + * Extract cookies from a sent request + * + * @param Event $event + */ + public function onRequestSent(Event $event) + { + $this->cookieJar->addCookiesFromResponse($event['response'], $event['request']); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Cookie/Exception/InvalidCookieException.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Cookie/Exception/InvalidCookieException.php new file mode 100644 index 0000000..b1fa6fd --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Cookie/Exception/InvalidCookieException.php @@ -0,0 +1,7 @@ +=5.3.2", + "guzzle/http": "self.version" + }, + "autoload": { + "psr-0": { "Guzzle\\Plugin\\Cookie": "" } + }, + "target-dir": "Guzzle/Plugin/Cookie", + "extra": { + "branch-alias": { + "dev-master": "3.7-dev" + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/CurlAuth/CurlAuthPlugin.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/CurlAuth/CurlAuthPlugin.php new file mode 100644 index 0000000..610e60c --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/CurlAuth/CurlAuthPlugin.php @@ -0,0 +1,46 @@ +getConfig()->setPath('request.options/auth', array('user', 'pass', 'Basic|Digest'); + */ +class CurlAuthPlugin implements EventSubscriberInterface +{ + private $username; + private $password; + private $scheme; + + /** + * @param string $username HTTP basic auth username + * @param string $password Password + * @param int $scheme Curl auth scheme + */ + public function __construct($username, $password, $scheme=CURLAUTH_BASIC) + { + Version::warn(__CLASS__ . " is deprecated. Use \$client->getConfig()->setPath('request.options/auth', array('user', 'pass', 'Basic|Digest');"); + $this->username = $username; + $this->password = $password; + $this->scheme = $scheme; + } + + public static function getSubscribedEvents() + { + return array('client.create_request' => array('onRequestCreate', 255)); + } + + /** + * Add basic auth + * + * @param Event $event + */ + public function onRequestCreate(Event $event) + { + $event['request']->setAuth($this->username, $this->password, $this->scheme); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/CurlAuth/composer.json b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/CurlAuth/composer.json new file mode 100644 index 0000000..edc8b24 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/CurlAuth/composer.json @@ -0,0 +1,27 @@ +{ + "name": "guzzle/plugin-curlauth", + "description": "Guzzle cURL authorization plugin", + "homepage": "http://guzzlephp.org/", + "keywords": ["plugin", "curl", "guzzle"], + "license": "MIT", + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "require": { + "php": ">=5.3.2", + "guzzle/http": "self.version" + }, + "autoload": { + "psr-0": { "Guzzle\\Plugin\\CurlAuth": "" } + }, + "target-dir": "Guzzle/Plugin/CurlAuth", + "extra": { + "branch-alias": { + "dev-master": "3.7-dev" + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/ErrorResponse/ErrorResponseExceptionInterface.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/ErrorResponse/ErrorResponseExceptionInterface.php new file mode 100644 index 0000000..5dce8bd --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/ErrorResponse/ErrorResponseExceptionInterface.php @@ -0,0 +1,22 @@ + array('onCommandBeforeSend', -1)); + } + + /** + * Adds a listener to requests before they sent from a command + * + * @param Event $event Event emitted + */ + public function onCommandBeforeSend(Event $event) + { + $command = $event['command']; + if ($operation = $command->getOperation()) { + if ($operation->getErrorResponses()) { + $request = $command->getRequest(); + $request->getEventDispatcher() + ->addListener('request.complete', $this->getErrorClosure($request, $command, $operation)); + } + } + } + + /** + * @param RequestInterface $request Request that received an error + * @param CommandInterface $command Command that created the request + * @param Operation $operation Operation that defines the request and errors + * + * @return \Closure Returns a closure + * @throws ErrorResponseException + */ + protected function getErrorClosure(RequestInterface $request, CommandInterface $command, Operation $operation) + { + return function (Event $event) use ($request, $command, $operation) { + $response = $event['response']; + foreach ($operation->getErrorResponses() as $error) { + if (!isset($error['class'])) { + continue; + } + if (isset($error['code']) && $response->getStatusCode() != $error['code']) { + continue; + } + if (isset($error['reason']) && $response->getReasonPhrase() != $error['reason']) { + continue; + } + $className = $error['class']; + $errorClassInterface = __NAMESPACE__ . '\\ErrorResponseExceptionInterface'; + if (!class_exists($className)) { + throw new ErrorResponseException("{$className} does not exist"); + } elseif (!(in_array($errorClassInterface, class_implements($className)))) { + throw new ErrorResponseException("{$className} must implement {$errorClassInterface}"); + } + throw $className::fromCommand($command, $response); + } + }; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/ErrorResponse/Exception/ErrorResponseException.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/ErrorResponse/Exception/ErrorResponseException.php new file mode 100644 index 0000000..1d89e40 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/ErrorResponse/Exception/ErrorResponseException.php @@ -0,0 +1,7 @@ +=5.3.2", + "guzzle/service": "self.version" + }, + "autoload": { + "psr-0": { "Guzzle\\Plugin\\ErrorResponse": "" } + }, + "target-dir": "Guzzle/Plugin/ErrorResponse", + "extra": { + "branch-alias": { + "dev-master": "3.7-dev" + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/History/HistoryPlugin.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/History/HistoryPlugin.php new file mode 100644 index 0000000..7375e89 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/History/HistoryPlugin.php @@ -0,0 +1,163 @@ + array('onRequestSent', 9999)); + } + + /** + * Convert to a string that contains all request and response headers + * + * @return string + */ + public function __toString() + { + $lines = array(); + foreach ($this->transactions as $entry) { + $response = isset($entry['response']) ? $entry['response'] : ''; + $lines[] = '> ' . trim($entry['request']) . "\n\n< " . trim($response) . "\n"; + } + + return implode("\n", $lines); + } + + /** + * Add a request to the history + * + * @param RequestInterface $request Request to add + * @param Response $response Response of the request + * + * @return HistoryPlugin + */ + public function add(RequestInterface $request, Response $response = null) + { + if (!$response && $request->getResponse()) { + $response = $request->getResponse(); + } + + $this->transactions[] = array('request' => $request, 'response' => $response); + if (count($this->transactions) > $this->getlimit()) { + array_shift($this->transactions); + } + + return $this; + } + + /** + * Set the max number of requests to store + * + * @param int $limit Limit + * + * @return HistoryPlugin + */ + public function setLimit($limit) + { + $this->limit = (int) $limit; + + return $this; + } + + /** + * Get the request limit + * + * @return int + */ + public function getLimit() + { + return $this->limit; + } + + /** + * Get all of the raw transactions in the form of an array of associative arrays containing + * 'request' and 'response' keys. + * + * @return array + */ + public function getAll() + { + return $this->transactions; + } + + /** + * Get the requests in the history + * + * @return \ArrayIterator + */ + public function getIterator() + { + // Return an iterator just like the old iteration of the HistoryPlugin for BC compatibility (use getAll()) + return new \ArrayIterator(array_map(function ($entry) { + $entry['request']->getParams()->set('actual_response', $entry['response']); + return $entry['request']; + }, $this->transactions)); + } + + /** + * Get the number of requests in the history + * + * @return int + */ + public function count() + { + return count($this->transactions); + } + + /** + * Get the last request sent + * + * @return RequestInterface + */ + public function getLastRequest() + { + $last = end($this->transactions); + + return $last['request']; + } + + /** + * Get the last response in the history + * + * @return Response|null + */ + public function getLastResponse() + { + $last = end($this->transactions); + + return isset($last['response']) ? $last['response'] : null; + } + + /** + * Clears the history + * + * @return HistoryPlugin + */ + public function clear() + { + $this->transactions = array(); + + return $this; + } + + public function onRequestSent(Event $event) + { + $this->add($event['request'], $event['response']); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/History/composer.json b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/History/composer.json new file mode 100644 index 0000000..ba0bf2c --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/History/composer.json @@ -0,0 +1,27 @@ +{ + "name": "guzzle/plugin-history", + "description": "Guzzle history plugin", + "homepage": "http://guzzlephp.org/", + "keywords": ["plugin", "guzzle"], + "license": "MIT", + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "require": { + "php": ">=5.3.2", + "guzzle/http": "self.version" + }, + "autoload": { + "psr-0": { "Guzzle\\Plugin\\History": "" } + }, + "target-dir": "Guzzle/Plugin/History", + "extra": { + "branch-alias": { + "dev-master": "3.7-dev" + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Log/LogPlugin.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Log/LogPlugin.php new file mode 100644 index 0000000..cabdea8 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Log/LogPlugin.php @@ -0,0 +1,161 @@ +logAdapter = $logAdapter; + $this->formatter = $formatter instanceof MessageFormatter ? $formatter : new MessageFormatter($formatter); + $this->wireBodies = $wireBodies; + } + + /** + * Get a log plugin that outputs full request, response, and curl error information to stderr + * + * @param bool $wireBodies Set to false to disable request/response body output when they use are not repeatable + * @param resource $stream Stream to write to when logging. Defaults to STDERR when it is available + * + * @return self + */ + public static function getDebugPlugin($wireBodies = true, $stream = null) + { + if ($stream === null) { + if (defined('STDERR')) { + $stream = STDERR; + } else { + $stream = fopen('php://output', 'w'); + } + } + + return new self(new ClosureLogAdapter(function ($m) use ($stream) { + fwrite($stream, $m . PHP_EOL); + }), "# Request:\n{request}\n\n# Response:\n{response}\n\n# Errors: {curl_code} {curl_error}", $wireBodies); + } + + public static function getSubscribedEvents() + { + return array( + 'curl.callback.write' => array('onCurlWrite', 255), + 'curl.callback.read' => array('onCurlRead', 255), + 'request.before_send' => array('onRequestBeforeSend', 255), + 'request.sent' => array('onRequestSent', 255) + ); + } + + /** + * Event triggered when curl data is read from a request + * + * @param Event $event + */ + public function onCurlRead(Event $event) + { + // Stream the request body to the log if the body is not repeatable + if ($wire = $event['request']->getParams()->get('request_wire')) { + $wire->write($event['read']); + } + } + + /** + * Event triggered when curl data is written to a response + * + * @param Event $event + */ + public function onCurlWrite(Event $event) + { + // Stream the response body to the log if the body is not repeatable + if ($wire = $event['request']->getParams()->get('response_wire')) { + $wire->write($event['write']); + } + } + + /** + * Called before a request is sent + * + * @param Event $event + */ + public function onRequestBeforeSend(Event $event) + { + if ($this->wireBodies) { + $request = $event['request']; + // Ensure that curl IO events are emitted + $request->getCurlOptions()->set('emit_io', true); + // We need to make special handling for content wiring and non-repeatable streams. + if ($request instanceof EntityEnclosingRequestInterface && $request->getBody() + && (!$request->getBody()->isSeekable() || !$request->getBody()->isReadable()) + ) { + // The body of the request cannot be recalled so logging the body will require us to buffer it + $request->getParams()->set('request_wire', EntityBody::factory()); + } + if (!$request->getResponseBody()->isRepeatable()) { + // The body of the response cannot be recalled so logging the body will require us to buffer it + $request->getParams()->set('response_wire', EntityBody::factory()); + } + } + } + + /** + * Triggers the actual log write when a request completes + * + * @param Event $event + */ + public function onRequestSent(Event $event) + { + $request = $event['request']; + $response = $event['response']; + $handle = $event['handle']; + + if ($wire = $request->getParams()->get('request_wire')) { + $request = clone $request; + $request->setBody($wire); + } + + if ($wire = $request->getParams()->get('response_wire')) { + $response = clone $response; + $response->setBody($wire); + } + + // Send the log message to the adapter, adding a category and host + $priority = $response && $response->isError() ? LOG_ERR : LOG_DEBUG; + $message = $this->formatter->format($request, $response, $handle); + $this->logAdapter->log($message, $priority, array( + 'request' => $request, + 'response' => $response, + 'handle' => $handle + )); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Log/composer.json b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Log/composer.json new file mode 100644 index 0000000..130e6da --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Log/composer.json @@ -0,0 +1,28 @@ +{ + "name": "guzzle/plugin-log", + "description": "Guzzle log plugin for over the wire logging", + "homepage": "http://guzzlephp.org/", + "keywords": ["plugin", "log", "guzzle"], + "license": "MIT", + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "require": { + "php": ">=5.3.2", + "guzzle/http": "self.version", + "guzzle/log": "self.version" + }, + "autoload": { + "psr-0": { "Guzzle\\Plugin\\Log": "" } + }, + "target-dir": "Guzzle/Plugin/Log", + "extra": { + "branch-alias": { + "dev-master": "3.7-dev" + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Md5/CommandContentMd5Plugin.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Md5/CommandContentMd5Plugin.php new file mode 100644 index 0000000..8512424 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Md5/CommandContentMd5Plugin.php @@ -0,0 +1,57 @@ +contentMd5Param = $contentMd5Param; + $this->validateMd5Param = $validateMd5Param; + } + + public static function getSubscribedEvents() + { + return array('command.before_send' => array('onCommandBeforeSend', -255)); + } + + public function onCommandBeforeSend(Event $event) + { + $command = $event['command']; + $request = $command->getRequest(); + + // Only add an MD5 is there is a MD5 option on the operation and it has a payload + if ($request instanceof EntityEnclosingRequestInterface && $request->getBody() + && $command->getOperation()->hasParam($this->contentMd5Param)) { + // Check if an MD5 checksum value should be passed along to the request + if ($command[$this->contentMd5Param] === true) { + if (false !== ($md5 = $request->getBody()->getContentMd5(true, true))) { + $request->setHeader('Content-MD5', $md5); + } + } + } + + // Check if MD5 validation should be used with the response + if ($command[$this->validateMd5Param] === true) { + $request->addSubscriber(new Md5ValidatorPlugin(true, false)); + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Md5/Md5ValidatorPlugin.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Md5/Md5ValidatorPlugin.php new file mode 100644 index 0000000..5d7a378 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Md5/Md5ValidatorPlugin.php @@ -0,0 +1,88 @@ +contentLengthCutoff = $contentLengthCutoff; + $this->contentEncoded = $contentEncoded; + } + + public static function getSubscribedEvents() + { + return array('request.complete' => array('onRequestComplete', 255)); + } + + /** + * {@inheritdoc} + * @throws UnexpectedValueException + */ + public function onRequestComplete(Event $event) + { + $response = $event['response']; + + if (!$contentMd5 = $response->getContentMd5()) { + return; + } + + $contentEncoding = $response->getContentEncoding(); + if ($contentEncoding && !$this->contentEncoded) { + return false; + } + + // Make sure that the size of the request is under the cutoff size + if ($this->contentLengthCutoff) { + $size = $response->getContentLength() ?: $response->getBody()->getSize(); + if (!$size || $size > $this->contentLengthCutoff) { + return; + } + } + + if (!$contentEncoding) { + $hash = $response->getBody()->getContentMd5(); + } elseif ($contentEncoding == 'gzip') { + $response->getBody()->compress('zlib.deflate'); + $hash = $response->getBody()->getContentMd5(); + $response->getBody()->uncompress(); + } elseif ($contentEncoding == 'compress') { + $response->getBody()->compress('bzip2.compress'); + $hash = $response->getBody()->getContentMd5(); + $response->getBody()->uncompress(); + } else { + return; + } + + if ($contentMd5 !== $hash) { + throw new UnexpectedValueException( + "The response entity body may have been modified over the wire. The Content-MD5 " + . "received ({$contentMd5}) did not match the calculated MD5 hash ({$hash})." + ); + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Md5/composer.json b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Md5/composer.json new file mode 100644 index 0000000..0602d06 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Md5/composer.json @@ -0,0 +1,27 @@ +{ + "name": "guzzle/plugin-md5", + "description": "Guzzle MD5 plugins", + "homepage": "http://guzzlephp.org/", + "keywords": ["plugin", "guzzle"], + "license": "MIT", + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "require": { + "php": ">=5.3.2", + "guzzle/http": "self.version" + }, + "autoload": { + "psr-0": { "Guzzle\\Plugin\\Md5": "" } + }, + "target-dir": "Guzzle/Plugin/Md5", + "extra": { + "branch-alias": { + "dev-master": "3.7-dev" + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Mock/MockPlugin.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Mock/MockPlugin.php new file mode 100644 index 0000000..2440578 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Mock/MockPlugin.php @@ -0,0 +1,245 @@ +readBodies = $readBodies; + $this->temporary = $temporary; + if ($items) { + foreach ($items as $item) { + if ($item instanceof \Exception) { + $this->addException($item); + } else { + $this->addResponse($item); + } + } + } + } + + public static function getSubscribedEvents() + { + // Use a number lower than the CachePlugin + return array('request.before_send' => array('onRequestBeforeSend', -999)); + } + + public static function getAllEvents() + { + return array('mock.request'); + } + + /** + * Get a mock response from a file + * + * @param string $path File to retrieve a mock response from + * + * @return Response + * @throws InvalidArgumentException if the file is not found + */ + public static function getMockFile($path) + { + if (!file_exists($path)) { + throw new InvalidArgumentException('Unable to open mock file: ' . $path); + } + + return Response::fromMessage(file_get_contents($path)); + } + + /** + * Set whether or not to consume the entity body of a request when a mock + * response is used + * + * @param bool $readBodies Set to true to read and consume entity bodies + * + * @return self + */ + public function readBodies($readBodies) + { + $this->readBodies = $readBodies; + + return $this; + } + + /** + * Returns the number of remaining mock responses + * + * @return int + */ + public function count() + { + return count($this->queue); + } + + /** + * Add a response to the end of the queue + * + * @param string|Response $response Response object or path to response file + * + * @return MockPlugin + * @throws InvalidArgumentException if a string or Response is not passed + */ + public function addResponse($response) + { + if (!($response instanceof Response)) { + if (!is_string($response)) { + throw new InvalidArgumentException('Invalid response'); + } + $response = self::getMockFile($response); + } + + $this->queue[] = $response; + + return $this; + } + + /** + * Add an exception to the end of the queue + * + * @param CurlException $e Exception to throw when the request is executed + * + * @return MockPlugin + */ + public function addException(CurlException $e) + { + $this->queue[] = $e; + + return $this; + } + + /** + * Clear the queue + * + * @return MockPlugin + */ + public function clearQueue() + { + $this->queue = array(); + + return $this; + } + + /** + * Returns an array of mock responses remaining in the queue + * + * @return array + */ + public function getQueue() + { + return $this->queue; + } + + /** + * Check if this is a temporary plugin + * + * @return bool + */ + public function isTemporary() + { + return $this->temporary; + } + + /** + * Get a response from the front of the list and add it to a request + * + * @param RequestInterface $request Request to mock + * + * @return self + * @throws CurlException When request.send is called and an exception is queued + */ + public function dequeue(RequestInterface $request) + { + $this->dispatch('mock.request', array('plugin' => $this, 'request' => $request)); + + $item = array_shift($this->queue); + if ($item instanceof Response) { + if ($this->readBodies && $request instanceof EntityEnclosingRequestInterface) { + $request->getEventDispatcher()->addListener('request.sent', $f = function (Event $event) use (&$f) { + while ($data = $event['request']->getBody()->read(8096)); + // Remove the listener after one-time use + $event['request']->getEventDispatcher()->removeListener('request.sent', $f); + }); + } + $request->setResponse($item); + } elseif ($item instanceof CurlException) { + // Emulates exceptions encountered while transferring requests + $item->setRequest($request); + $state = $request->setState(RequestInterface::STATE_ERROR, array('exception' => $item)); + // Only throw if the exception wasn't handled + if ($state == RequestInterface::STATE_ERROR) { + throw $item; + } + } + + return $this; + } + + /** + * Clear the array of received requests + */ + public function flush() + { + $this->received = array(); + } + + /** + * Get an array of requests that were mocked by this plugin + * + * @return array + */ + public function getReceivedRequests() + { + return $this->received; + } + + /** + * Called when a request is about to be sent + * + * @param Event $event + * @throws \OutOfBoundsException When queue is empty + */ + public function onRequestBeforeSend(Event $event) + { + if (!$this->queue) { + throw new \OutOfBoundsException('Mock queue is empty'); + } + + $request = $event['request']; + $this->received[] = $request; + // Detach the filter from the client so it's a one-time use + if ($this->temporary && count($this->queue) == 1 && $request->getClient()) { + $request->getClient()->getEventDispatcher()->removeSubscriber($this); + } + $this->dequeue($request); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Mock/composer.json b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Mock/composer.json new file mode 100644 index 0000000..f8201e3 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Mock/composer.json @@ -0,0 +1,27 @@ +{ + "name": "guzzle/plugin-mock", + "description": "Guzzle Mock plugin", + "homepage": "http://guzzlephp.org/", + "keywords": ["mock", "plugin", "guzzle"], + "license": "MIT", + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "require": { + "php": ">=5.3.2", + "guzzle/http": "self.version" + }, + "autoload": { + "psr-0": { "Guzzle\\Plugin\\Mock": "" } + }, + "target-dir": "Guzzle/Plugin/Mock", + "extra": { + "branch-alias": { + "dev-master": "3.7-dev" + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Oauth/OauthPlugin.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Oauth/OauthPlugin.php new file mode 100644 index 0000000..95e0c3e --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Oauth/OauthPlugin.php @@ -0,0 +1,306 @@ +config = Collection::fromConfig($config, array( + 'version' => '1.0', + 'request_method' => self::REQUEST_METHOD_HEADER, + 'consumer_key' => 'anonymous', + 'consumer_secret' => 'anonymous', + 'signature_method' => 'HMAC-SHA1', + 'signature_callback' => function($stringToSign, $key) { + return hash_hmac('sha1', $stringToSign, $key, true); + } + ), array( + 'signature_method', 'signature_callback', 'version', + 'consumer_key', 'consumer_secret' + )); + } + + public static function getSubscribedEvents() + { + return array( + 'request.before_send' => array('onRequestBeforeSend', -1000) + ); + } + + /** + * Request before-send event handler + * + * @param Event $event Event received + * @return array + * @throws \InvalidArgumentException + */ + public function onRequestBeforeSend(Event $event) + { + $timestamp = $this->getTimestamp($event); + $request = $event['request']; + $nonce = $this->generateNonce($request); + $authorizationParams = $this->getOauthParams($timestamp, $nonce); + $authorizationParams['oauth_signature'] = $this->getSignature($request, $timestamp, $nonce); + + switch ($this->config['request_method']) { + case self::REQUEST_METHOD_HEADER: + $request->setHeader( + 'Authorization', + $this->buildAuthorizationHeader($authorizationParams) + ); + break; + case self::REQUEST_METHOD_QUERY: + foreach ($authorizationParams as $key => $value) { + $request->getQuery()->set($key, $value); + } + break; + default: + throw new \InvalidArgumentException(sprintf( + 'Invalid consumer method "%s"', + $this->config['request_method'] + )); + } + + return $authorizationParams; + } + + /** + * Builds the Authorization header for a request + * + * @param array $authorizationParams Associative array of authorization parameters + * + * @return string + */ + private function buildAuthorizationHeader($authorizationParams) + { + $authorizationString = 'OAuth '; + foreach ($authorizationParams as $key => $val) { + if ($val) { + $authorizationString .= $key . '="' . urlencode($val) . '", '; + } + } + + return substr($authorizationString, 0, -2); + } + + /** + * Calculate signature for request + * + * @param RequestInterface $request Request to generate a signature for + * @param integer $timestamp Timestamp to use for nonce + * @param string $nonce + * + * @return string + */ + public function getSignature(RequestInterface $request, $timestamp, $nonce) + { + $string = $this->getStringToSign($request, $timestamp, $nonce); + $key = urlencode($this->config['consumer_secret']) . '&' . urlencode($this->config['token_secret']); + + return base64_encode(call_user_func($this->config['signature_callback'], $string, $key)); + } + + /** + * Calculate string to sign + * + * @param RequestInterface $request Request to generate a signature for + * @param int $timestamp Timestamp to use for nonce + * @param string $nonce + * + * @return string + */ + public function getStringToSign(RequestInterface $request, $timestamp, $nonce) + { + $params = $this->getParamsToSign($request, $timestamp, $nonce); + + // Convert booleans to strings. + $params = $this->prepareParameters($params); + + // Build signing string from combined params + $parameterString = clone $request->getQuery(); + $parameterString->replace($params); + + $url = Url::factory($request->getUrl())->setQuery('')->setFragment(null); + + return strtoupper($request->getMethod()) . '&' + . rawurlencode($url) . '&' + . rawurlencode((string) $parameterString); + } + + /** + * Get the oauth parameters as named by the oauth spec + * + * @param $timestamp + * @param $nonce + * @return Collection + */ + protected function getOauthParams($timestamp, $nonce) + { + $params = new Collection(array( + 'oauth_consumer_key' => $this->config['consumer_key'], + 'oauth_nonce' => $nonce, + 'oauth_signature_method' => $this->config['signature_method'], + 'oauth_timestamp' => $timestamp, + )); + + // Optional parameters should not be set if they have not been set in the config as + // the parameter may be considered invalid by the Oauth service. + $optionalParams = array( + 'callback' => 'oauth_callback', + 'token' => 'oauth_token', + 'verifier' => 'oauth_verifier', + 'version' => 'oauth_version' + ); + + foreach ($optionalParams as $optionName => $oauthName) { + if (isset($this->config[$optionName]) == true) { + $params[$oauthName] = $this->config[$optionName]; + } + } + + return $params; + } + + /** + * Get all of the parameters required to sign a request including: + * * The oauth params + * * The request GET params + * * The params passed in the POST body (with a content-type of application/x-www-form-urlencoded) + * + * @param RequestInterface $request Request to generate a signature for + * @param integer $timestamp Timestamp to use for nonce + * @param string $nonce + * + * @return array + */ + public function getParamsToSign(RequestInterface $request, $timestamp, $nonce) + { + $params = $this->getOauthParams($timestamp, $nonce); + + // Add query string parameters + $params->merge($request->getQuery()); + + // Add POST fields to signing string if required + if ($this->shouldPostFieldsBeSigned($request)) + { + $params->merge($request->getPostFields()); + } + + // Sort params + $params = $params->toArray(); + uksort($params, 'strcmp'); + + return $params; + } + + /** + * Decide whether the post fields should be added to the base string that Oauth signs. + * This implementation is correct. Non-conformant APIs may require that this method be + * overwritten e.g. the Flickr API incorrectly adds the post fields when the Content-Type + * is 'application/x-www-form-urlencoded' + * + * @param $request + * @return bool Whether the post fields should be signed or not + */ + public function shouldPostFieldsBeSigned($request) + { + if (!$this->config->get('disable_post_params') && + $request instanceof EntityEnclosingRequestInterface && + false !== strpos($request->getHeader('Content-Type'), 'application/x-www-form-urlencoded')) + { + return true; + } + + return false; + } + + /** + * Returns a Nonce Based on the unique id and URL. This will allow for multiple requests in parallel with the same + * exact timestamp to use separate nonce's. + * + * @param RequestInterface $request Request to generate a nonce for + * + * @return string + */ + public function generateNonce(RequestInterface $request) + { + return sha1(uniqid('', true) . $request->getUrl()); + } + + /** + * Gets timestamp from event or create new timestamp + * + * @param Event $event Event containing contextual information + * + * @return int + */ + public function getTimestamp(Event $event) + { + return $event['timestamp'] ?: time(); + } + + /** + * Convert booleans to strings, removed unset parameters, and sorts the array + * + * @param array $data Data array + * + * @return array + */ + protected function prepareParameters($data) + { + ksort($data); + foreach ($data as $key => &$value) { + switch (gettype($value)) { + case 'NULL': + unset($data[$key]); + break; + case 'array': + $data[$key] = self::prepareParameters($value); + break; + case 'boolean': + $data[$key] = $value ? 'true' : 'false'; + break; + } + } + + return $data; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Oauth/composer.json b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Oauth/composer.json new file mode 100644 index 0000000..c9766ba --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/Oauth/composer.json @@ -0,0 +1,27 @@ +{ + "name": "guzzle/plugin-oauth", + "description": "Guzzle OAuth plugin", + "homepage": "http://guzzlephp.org/", + "keywords": ["oauth", "plugin", "guzzle"], + "license": "MIT", + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "require": { + "php": ">=5.3.2", + "guzzle/http": "self.version" + }, + "autoload": { + "psr-0": { "Guzzle\\Plugin\\Oauth": "" } + }, + "target-dir": "Guzzle/Plugin/Oauth", + "extra": { + "branch-alias": { + "dev-master": "3.7-dev" + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/composer.json b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/composer.json new file mode 100644 index 0000000..2bbe64c --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Plugin/composer.json @@ -0,0 +1,44 @@ +{ + "name": "guzzle/plugin", + "description": "Guzzle plugin component containing all Guzzle HTTP plugins", + "homepage": "http://guzzlephp.org/", + "keywords": ["http", "client", "plugin", "extension", "guzzle"], + "license": "MIT", + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "require": { + "php": ">=5.3.2", + "guzzle/http": "self.version" + }, + "suggest": { + "guzzle/cache": "self.version", + "guzzle/log": "self.version" + }, + "autoload": { + "psr-0": { "Guzzle\\Plugin": "" } + }, + "target-dir": "Guzzle/Plugin", + "replace": { + "guzzle/plugin-async": "self.version", + "guzzle/plugin-backoff": "self.version", + "guzzle/plugin-cache": "self.version", + "guzzle/plugin-cookie": "self.version", + "guzzle/plugin-curlauth": "self.version", + "guzzle/plugin-error-response": "self.version", + "guzzle/plugin-history": "self.version", + "guzzle/plugin-log": "self.version", + "guzzle/plugin-md5": "self.version", + "guzzle/plugin-mock": "self.version", + "guzzle/plugin-oauth": "self.version" + }, + "extra": { + "branch-alias": { + "dev-master": "3.7-dev" + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/AbstractConfigLoader.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/AbstractConfigLoader.php new file mode 100644 index 0000000..cd06f57 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/AbstractConfigLoader.php @@ -0,0 +1,177 @@ + 'JSON_ERROR_NONE - No errors', + JSON_ERROR_DEPTH => 'JSON_ERROR_DEPTH - Maximum stack depth exceeded', + JSON_ERROR_STATE_MISMATCH => 'JSON_ERROR_STATE_MISMATCH - Underflow or the modes mismatch', + JSON_ERROR_CTRL_CHAR => 'JSON_ERROR_CTRL_CHAR - Unexpected control character found', + JSON_ERROR_SYNTAX => 'JSON_ERROR_SYNTAX - Syntax error, malformed JSON', + JSON_ERROR_UTF8 => 'JSON_ERROR_UTF8 - Malformed UTF-8 characters, possibly incorrectly encoded' + ); + + public function load($config, array $options = array()) + { + // Reset the array of loaded files because this is a new config + $this->loadedFiles = array(); + + if (is_string($config)) { + $config = $this->loadFile($config); + } elseif (!is_array($config)) { + throw new InvalidArgumentException('Unknown type passed to configuration loader: ' . gettype($config)); + } else { + $this->mergeIncludes($config); + } + + return $this->build($config, $options); + } + + /** + * Add an include alias to the loader + * + * @param string $filename Filename to alias (e.g. _foo) + * @param string $alias Actual file to use (e.g. /path/to/foo.json) + * + * @return self + */ + public function addAlias($filename, $alias) + { + $this->aliases[$filename] = $alias; + + return $this; + } + + /** + * Remove an alias from the loader + * + * @param string $alias Alias to remove + * + * @return self + */ + public function removeAlias($alias) + { + unset($this->aliases[$alias]); + + return $this; + } + + /** + * Perform the parsing of a config file and create the end result + * + * @param array $config Configuration data + * @param array $options Options to use when building + * + * @return mixed + */ + protected abstract function build($config, array $options); + + /** + * Load a configuration file (can load JSON or PHP files that return an array when included) + * + * @param string $filename File to load + * + * @return array + * @throws InvalidArgumentException + * @throws RuntimeException when the JSON cannot be parsed + */ + protected function loadFile($filename) + { + if (isset($this->aliases[$filename])) { + $filename = $this->aliases[$filename]; + } + + switch (pathinfo($filename, PATHINFO_EXTENSION)) { + case 'js': + case 'json': + $level = error_reporting(0); + $json = file_get_contents($filename); + error_reporting($level); + + if ($json === false) { + $err = error_get_last(); + throw new InvalidArgumentException("Unable to open {$filename}: " . $err['message']); + } + + $config = json_decode($json, true); + // Throw an exception if there was an error loading the file + if ($error = json_last_error()) { + $message = isset(self::$jsonErrors[$error]) ? self::$jsonErrors[$error] : 'Unknown error'; + throw new RuntimeException("Error loading JSON data from {$filename}: ({$error}) - {$message}"); + } + break; + case 'php': + if (!is_readable($filename)) { + throw new InvalidArgumentException("Unable to open {$filename} for reading"); + } + $config = require $filename; + if (!is_array($config)) { + throw new InvalidArgumentException('PHP files must return an array of configuration data'); + } + break; + default: + throw new InvalidArgumentException('Unknown file extension: ' . $filename); + } + + // Keep track of this file being loaded to prevent infinite recursion + $this->loadedFiles[$filename] = true; + + // Merge include files into the configuration array + $this->mergeIncludes($config, dirname($filename)); + + return $config; + } + + /** + * Merges in all include files + * + * @param array $config Config data that contains includes + * @param string $basePath Base path to use when a relative path is encountered + * + * @return array Returns the merged and included data + */ + protected function mergeIncludes(&$config, $basePath = null) + { + if (!empty($config['includes'])) { + foreach ($config['includes'] as &$path) { + // Account for relative paths + if ($path[0] != DIRECTORY_SEPARATOR && !isset($this->aliases[$path]) && $basePath) { + $path = "{$basePath}/{$path}"; + } + // Don't load the same files more than once + if (!isset($this->loadedFiles[$path])) { + $this->loadedFiles[$path] = true; + $config = $this->mergeData($this->loadFile($path), $config); + } + } + } + } + + /** + * Default implementation for merging two arrays of data (uses array_merge_recursive) + * + * @param array $a Original data + * @param array $b Data to merge into the original and overwrite existing values + * + * @return array + */ + protected function mergeData(array $a, array $b) + { + return array_merge_recursive($a, $b); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Builder/ServiceBuilder.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Builder/ServiceBuilder.php new file mode 100644 index 0000000..38150db --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Builder/ServiceBuilder.php @@ -0,0 +1,189 @@ +load($config, $globalParameters); + } + + /** + * @param array $serviceBuilderConfig Service configuration settings: + * - name: Name of the service + * - class: Client class to instantiate using a factory method + * - params: array of key value pair configuration settings for the builder + */ + public function __construct(array $serviceBuilderConfig = array()) + { + $this->builderConfig = $serviceBuilderConfig; + } + + public static function getAllEvents() + { + return array('service_builder.create_client'); + } + + public function unserialize($serialized) + { + $this->builderConfig = json_decode($serialized, true); + } + + public function serialize() + { + return json_encode($this->builderConfig); + } + + /** + * Attach a plugin to every client created by the builder + * + * @param EventSubscriberInterface $plugin Plugin to attach to each client + * + * @return self + */ + public function addGlobalPlugin(EventSubscriberInterface $plugin) + { + $this->plugins[] = $plugin; + + return $this; + } + + /** + * Get data from the service builder without triggering the building of a service + * + * @param string $name Name of the service to retrieve + * + * @return array|null + */ + public function getData($name) + { + return isset($this->builderConfig[$name]) ? $this->builderConfig[$name] : null; + } + + public function get($name, $throwAway = false) + { + if (!isset($this->builderConfig[$name])) { + + // Check to see if arbitrary data is being referenced + if (isset($this->clients[$name])) { + return $this->clients[$name]; + } + + // Check aliases and return a match if found + foreach ($this->builderConfig as $actualName => $config) { + if (isset($config['alias']) && $config['alias'] == $name) { + return $this->get($actualName, $throwAway); + } + } + throw new ServiceNotFoundException('No service is registered as ' . $name); + } + + if (!$throwAway && isset($this->clients[$name])) { + return $this->clients[$name]; + } + + $builder =& $this->builderConfig[$name]; + + // Convert references to the actual client + foreach ($builder['params'] as &$v) { + if (is_string($v) && substr($v, 0, 1) == '{' && substr($v, -1) == '}') { + $v = $this->get(trim($v, '{} ')); + } + } + + // Get the configured parameters and merge in any parameters provided for throw-away clients + $config = $builder['params']; + if (is_array($throwAway)) { + $config = $throwAway + $config; + } + + $client = $builder['class']::factory($config); + + if (!$throwAway) { + $this->clients[$name] = $client; + } + + if ($client instanceof ClientInterface) { + foreach ($this->plugins as $plugin) { + $client->addSubscriber($plugin); + } + // Dispatch an event letting listeners know a client was created + $this->dispatch('service_builder.create_client', array('client' => $client)); + } + + return $client; + } + + public function set($key, $service) + { + if (is_array($service) && isset($service['class']) && isset($service['params'])) { + $this->builderConfig[$key] = $service; + } else { + $this->clients[$key] = $service; + } + + return $this; + } + + public function offsetSet($offset, $value) + { + $this->set($offset, $value); + } + + public function offsetUnset($offset) + { + unset($this->builderConfig[$offset]); + unset($this->clients[$offset]); + } + + public function offsetExists($offset) + { + return isset($this->builderConfig[$offset]) || isset($this->clients[$offset]); + } + + public function offsetGet($offset) + { + return $this->get($offset); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Builder/ServiceBuilderInterface.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Builder/ServiceBuilderInterface.php new file mode 100644 index 0000000..4fc310a --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Builder/ServiceBuilderInterface.php @@ -0,0 +1,40 @@ + &$service) { + + $service['params'] = isset($service['params']) ? $service['params'] : array(); + + // Check if this client builder extends another client + if (!empty($service['extends'])) { + + // Make sure that the service it's extending has been defined + if (!isset($services[$service['extends']])) { + throw new ServiceNotFoundException( + "{$name} is trying to extend a non-existent service: {$service['extends']}" + ); + } + + $extended = &$services[$service['extends']]; + + // Use the correct class attribute + if (empty($service['class'])) { + $service['class'] = isset($extended['class']) ? $extended['class'] : ''; + } + if ($extendsParams = isset($extended['params']) ? $extended['params'] : false) { + $service['params'] = $service['params'] + $extendsParams; + } + } + + // Overwrite default values with global parameter values + if (!empty($options)) { + $service['params'] = $options + $service['params']; + } + + $service['class'] = isset($service['class']) ? $service['class'] : ''; + } + + return new $class($services); + } + + protected function mergeData(array $a, array $b) + { + $result = $b + $a; + + // Merge services using a recursive union of arrays + if (isset($a['services']) && $b['services']) { + + // Get a union of the services of the two arrays + $result['services'] = $b['services'] + $a['services']; + + // Merge each service in using a union of the two arrays + foreach ($result['services'] as $name => &$service) { + + // By default, services completely override a previously defined service unless it extends itself + if (isset($a['services'][$name]['extends']) + && isset($b['services'][$name]['extends']) + && $b['services'][$name]['extends'] == $name + ) { + $service += $a['services'][$name]; + // Use the `extends` attribute of the parent + $service['extends'] = $a['services'][$name]['extends']; + // Merge parameters using a union if both have parameters + if (isset($a['services'][$name]['params'])) { + $service['params'] += $a['services'][$name]['params']; + } + } + } + } + + return $result; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/CachingConfigLoader.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/CachingConfigLoader.php new file mode 100644 index 0000000..26f8360 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/CachingConfigLoader.php @@ -0,0 +1,46 @@ +loader = $loader; + $this->cache = $cache; + } + + public function load($config, array $options = array()) + { + if (!is_string($config)) { + $key = false; + } else { + $key = 'loader_' . crc32($config); + if ($result = $this->cache->fetch($key)) { + return $result; + } + } + + $result = $this->loader->load($config, $options); + if ($key) { + $this->cache->save($key, $result); + } + + return $result; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Client.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Client.php new file mode 100644 index 0000000..3e5f8e5 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Client.php @@ -0,0 +1,297 @@ +getCommand($method, isset($args[0]) ? $args[0] : array())->getResult(); + } + + public function getCommand($name, array $args = array()) + { + // Add global client options to the command + if ($options = $this->getConfig(self::COMMAND_PARAMS)) { + $args += $options; + } + + if (!($command = $this->getCommandFactory()->factory($name, $args))) { + throw new InvalidArgumentException("Command was not found matching {$name}"); + } + + $command->setClient($this); + $this->dispatch('client.command.create', array('client' => $this, 'command' => $command)); + + return $command; + } + + /** + * Set the command factory used to create commands by name + * + * @param CommandFactoryInterface $factory Command factory + * + * @return self + */ + public function setCommandFactory(CommandFactoryInterface $factory) + { + $this->commandFactory = $factory; + + return $this; + } + + /** + * Set the resource iterator factory associated with the client + * + * @param ResourceIteratorFactoryInterface $factory Resource iterator factory + * + * @return self + */ + public function setResourceIteratorFactory(ResourceIteratorFactoryInterface $factory) + { + $this->resourceIteratorFactory = $factory; + + return $this; + } + + public function getIterator($command, array $commandOptions = null, array $iteratorOptions = array()) + { + if (!($command instanceof CommandInterface)) { + $command = $this->getCommand($command, $commandOptions ?: array()); + } + + return $this->getResourceIteratorFactory()->build($command, $iteratorOptions); + } + + public function execute($command) + { + if ($command instanceof CommandInterface) { + $this->send($this->prepareCommand($command)); + $this->dispatch('command.after_send', array('command' => $command)); + return $command->getResult(); + } elseif (is_array($command) || $command instanceof \Traversable) { + return $this->executeMultiple($command); + } else { + throw new InvalidArgumentException('Command must be a command or array of commands'); + } + } + + public function setDescription(ServiceDescriptionInterface $service) + { + $this->serviceDescription = $service; + + if ($this->getCommandFactory() && $this->getCommandFactory() instanceof CompositeFactory) { + $this->commandFactory->add(new Command\Factory\ServiceDescriptionFactory($service)); + } + + // If a baseUrl was set on the description, then update the client + if ($baseUrl = $service->getBaseUrl()) { + $this->setBaseUrl($baseUrl); + } + + return $this; + } + + public function getDescription() + { + return $this->serviceDescription; + } + + /** + * Set the inflector used with the client + * + * @param InflectorInterface $inflector Inflection object + * + * @return self + */ + public function setInflector(InflectorInterface $inflector) + { + $this->inflector = $inflector; + + return $this; + } + + /** + * Get the inflector used with the client + * + * @return self + */ + public function getInflector() + { + if (!$this->inflector) { + $this->inflector = Inflector::getDefault(); + } + + return $this->inflector; + } + + /** + * Prepare a command for sending and get the RequestInterface object created by the command + * + * @param CommandInterface $command Command to prepare + * + * @return RequestInterface + */ + protected function prepareCommand(CommandInterface $command) + { + // Set the client and prepare the command + $request = $command->setClient($this)->prepare(); + // Set the state to new if the command was previously executed + $request->setState(RequestInterface::STATE_NEW); + $this->dispatch('command.before_send', array('command' => $command)); + + return $request; + } + + /** + * Execute multiple commands in parallel + * + * @param array|Traversable $commands Array of CommandInterface objects to execute + * + * @return array Returns an array of the executed commands + * @throws Exception\CommandTransferException + */ + protected function executeMultiple($commands) + { + $requests = array(); + $commandRequests = new \SplObjectStorage(); + + foreach ($commands as $command) { + $request = $this->prepareCommand($command); + $commandRequests[$request] = $command; + $requests[] = $request; + } + + try { + $this->send($requests); + foreach ($commands as $command) { + $this->dispatch('command.after_send', array('command' => $command)); + } + return $commands; + } catch (MultiTransferException $failureException) { + // Throw a CommandTransferException using the successful and failed commands + $e = CommandTransferException::fromMultiTransferException($failureException); + + // Remove failed requests from the successful requests array and add to the failures array + foreach ($failureException->getFailedRequests() as $request) { + if (isset($commandRequests[$request])) { + $e->addFailedCommand($commandRequests[$request]); + unset($commandRequests[$request]); + } + } + + // Always emit the command after_send events for successful commands + foreach ($commandRequests as $success) { + $e->addSuccessfulCommand($commandRequests[$success]); + $this->dispatch('command.after_send', array('command' => $commandRequests[$success])); + } + + throw $e; + } + } + + protected function getResourceIteratorFactory() + { + if (!$this->resourceIteratorFactory) { + // Build the default resource iterator factory if one is not set + $clientClass = get_class($this); + $prefix = substr($clientClass, 0, strrpos($clientClass, '\\')); + $this->resourceIteratorFactory = new ResourceIteratorClassFactory(array( + "{$prefix}\\Iterator", + "{$prefix}\\Model" + )); + } + + return $this->resourceIteratorFactory; + } + + /** + * Get the command factory associated with the client + * + * @return CommandFactoryInterface + */ + protected function getCommandFactory() + { + if (!$this->commandFactory) { + $this->commandFactory = CompositeFactory::getDefaultChain($this); + } + + return $this->commandFactory; + } + + /** + * @deprecated + * @codeCoverageIgnore + */ + public function enableMagicMethods($isEnabled) + { + Version::warn(__METHOD__ . ' is deprecated'); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/ClientInterface.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/ClientInterface.php new file mode 100644 index 0000000..814154f --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/ClientInterface.php @@ -0,0 +1,68 @@ +operation = $operation ?: $this->createOperation(); + foreach ($this->operation->getParams() as $name => $arg) { + $currentValue = $this[$name]; + $configValue = $arg->getValue($currentValue); + // If default or static values are set, then this should always be updated on the config object + if ($currentValue !== $configValue) { + $this[$name] = $configValue; + } + } + + $headers = $this[self::HEADERS_OPTION]; + if (!$headers instanceof Collection) { + $this[self::HEADERS_OPTION] = new Collection((array) $headers); + } + + // You can set a command.on_complete option in your parameters to set an onComplete callback + if ($onComplete = $this['command.on_complete']) { + unset($this['command.on_complete']); + $this->setOnComplete($onComplete); + } + + // Set the hidden additional parameters + if (!$this[self::HIDDEN_PARAMS]) { + $this[self::HIDDEN_PARAMS] = array( + self::HEADERS_OPTION, + self::RESPONSE_PROCESSING, + self::HIDDEN_PARAMS, + self::REQUEST_OPTIONS + ); + } + + $this->init(); + } + + /** + * Custom clone behavior + */ + public function __clone() + { + $this->request = null; + $this->result = null; + } + + /** + * Execute the command in the same manner as calling a function + * + * @return mixed Returns the result of {@see AbstractCommand::execute} + */ + public function __invoke() + { + return $this->execute(); + } + + public function getName() + { + return $this->operation->getName(); + } + + /** + * Get the API command information about the command + * + * @return OperationInterface + */ + public function getOperation() + { + return $this->operation; + } + + public function setOnComplete($callable) + { + if (!is_callable($callable)) { + throw new InvalidArgumentException('The onComplete function must be callable'); + } + + $this->onComplete = $callable; + + return $this; + } + + public function execute() + { + if (!$this->client) { + throw new CommandException('A client must be associated with the command before it can be executed.'); + } + + return $this->client->execute($this); + } + + public function getClient() + { + return $this->client; + } + + public function setClient(ClientInterface $client) + { + $this->client = $client; + + return $this; + } + + public function getRequest() + { + if (!$this->request) { + throw new CommandException('The command must be prepared before retrieving the request'); + } + + return $this->request; + } + + public function getResponse() + { + if (!$this->isExecuted()) { + $this->execute(); + } + + return $this->request->getResponse(); + } + + public function getResult() + { + if (!$this->isExecuted()) { + $this->execute(); + } + + if (null === $this->result) { + $this->process(); + // Call the onComplete method if one is set + if ($this->onComplete) { + call_user_func($this->onComplete, $this); + } + } + + return $this->result; + } + + public function setResult($result) + { + $this->result = $result; + + return $this; + } + + public function isPrepared() + { + return $this->request !== null; + } + + public function isExecuted() + { + return $this->request !== null && $this->request->getState() == 'complete'; + } + + public function prepare() + { + if (!$this->isPrepared()) { + if (!$this->client) { + throw new CommandException('A client must be associated with the command before it can be prepared.'); + } + + // If no response processing value was specified, then attempt to use the highest level of processing + if (!isset($this[self::RESPONSE_PROCESSING])) { + $this[self::RESPONSE_PROCESSING] = self::TYPE_MODEL; + } + + // Notify subscribers of the client that the command is being prepared + $this->client->dispatch('command.before_prepare', array('command' => $this)); + + // Fail on missing required arguments, and change parameters via filters + $this->validate(); + // Delegate to the subclass that implements the build method + $this->build(); + + // Add custom request headers set on the command + if ($headers = $this[self::HEADERS_OPTION]) { + foreach ($headers as $key => $value) { + $this->request->setHeader($key, $value); + } + } + + // Add any curl options to the request + if ($options = $this[Client::CURL_OPTIONS]) { + $this->request->getCurlOptions()->overwriteWith(CurlHandle::parseCurlConfig($options)); + } + + // Set a custom response body + if ($responseBody = $this[self::RESPONSE_BODY]) { + $this->request->setResponseBody($responseBody); + } + + $this->client->dispatch('command.after_prepare', array('command' => $this)); + } + + return $this->request; + } + + /** + * Set the validator used to validate and prepare command parameters and nested JSON schemas. If no validator is + * set, then the command will validate using the default {@see SchemaValidator}. + * + * @param ValidatorInterface $validator Validator used to prepare and validate properties against a JSON schema + * + * @return self + */ + public function setValidator(ValidatorInterface $validator) + { + $this->validator = $validator; + + return $this; + } + + public function getRequestHeaders() + { + return $this[self::HEADERS_OPTION]; + } + + /** + * Initialize the command (hook that can be implemented in subclasses) + */ + protected function init() {} + + /** + * Create the request object that will carry out the command + */ + abstract protected function build(); + + /** + * Hook used to create an operation for concrete commands that are not associated with a service description + * + * @return OperationInterface + */ + protected function createOperation() + { + return new Operation(array('name' => get_class($this))); + } + + /** + * Create the result of the command after the request has been completed. + * Override this method in subclasses to customize this behavior + */ + protected function process() + { + $this->result = $this[self::RESPONSE_PROCESSING] != self::TYPE_RAW + ? DefaultResponseParser::getInstance()->parse($this) + : $this->request->getResponse(); + } + + /** + * Validate and prepare the command based on the schema and rules defined by the command's Operation object + * + * @throws ValidationException when validation errors occur + */ + protected function validate() + { + // Do not perform request validation/transformation if it is disable + if ($this[self::DISABLE_VALIDATION]) { + return; + } + + $errors = array(); + $validator = $this->getValidator(); + foreach ($this->operation->getParams() as $name => $schema) { + $value = $this[$name]; + if (!$validator->validate($schema, $value)) { + $errors = array_merge($errors, $validator->getErrors()); + } elseif ($value !== $this[$name]) { + // Update the config value if it changed and no validation errors were encountered + $this->data[$name] = $value; + } + } + + // Validate additional parameters + $hidden = $this[self::HIDDEN_PARAMS]; + + if ($properties = $this->operation->getAdditionalParameters()) { + foreach ($this->toArray() as $name => $value) { + // It's only additional if it isn't defined in the schema + if (!$this->operation->hasParam($name) && !in_array($name, $hidden)) { + // Always set the name so that error messages are useful + $properties->setName($name); + if (!$validator->validate($properties, $value)) { + $errors = array_merge($errors, $validator->getErrors()); + } elseif ($value !== $this[$name]) { + $this->data[$name] = $value; + } + } + } + } + + if (!empty($errors)) { + $e = new ValidationException('Validation errors: ' . implode("\n", $errors)); + $e->setErrors($errors); + throw $e; + } + } + + /** + * Get the validator used to prepare and validate properties. If no validator has been set on the command, then + * the default {@see SchemaValidator} will be used. + * + * @return ValidatorInterface + */ + protected function getValidator() + { + if (!$this->validator) { + $this->validator = SchemaValidator::getInstance(); + } + + return $this->validator; + } + + /** + * Get array of any validation errors + * If no validator has been set then return false + */ + public function getValidationErrors() + { + if (!$this->validator) { + return false; + } + + return $this->validator->getErrors(); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/ClosureCommand.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/ClosureCommand.php new file mode 100644 index 0000000..cb6ac40 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/ClosureCommand.php @@ -0,0 +1,41 @@ +request = $closure($this, $this->operation); + + if (!$this->request || !$this->request instanceof RequestInterface) { + throw new UnexpectedValueException('Closure command did not return a RequestInterface object'); + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/CommandInterface.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/CommandInterface.php new file mode 100644 index 0000000..fbb61d2 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/CommandInterface.php @@ -0,0 +1,128 @@ +stopPropagation(); + } + + /** + * Get the created object + * + * @return mixed + */ + public function getResult() + { + return $this['result']; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/DefaultRequestSerializer.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/DefaultRequestSerializer.php new file mode 100644 index 0000000..2dc4acd --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/DefaultRequestSerializer.php @@ -0,0 +1,169 @@ +factory = $factory; + } + + /** + * Add a location visitor to the serializer + * + * @param string $location Location to associate with the visitor + * @param RequestVisitorInterface $visitor Visitor to attach + * + * @return self + */ + public function addVisitor($location, RequestVisitorInterface $visitor) + { + $this->factory->addRequestVisitor($location, $visitor); + + return $this; + } + + public function prepare(CommandInterface $command) + { + $request = $this->createRequest($command); + // Keep an array of visitors found in the operation + $foundVisitors = array(); + $operation = $command->getOperation(); + + // Add arguments to the request using the location attribute + foreach ($operation->getParams() as $name => $arg) { + /** @var $arg \Guzzle\Service\Description\Parameter */ + $location = $arg->getLocation(); + // Skip 'uri' locations because they've already been processed + if ($location && $location != 'uri') { + // Instantiate visitors as they are detected in the properties + if (!isset($foundVisitors[$location])) { + $foundVisitors[$location] = $this->factory->getRequestVisitor($location); + } + // Ensure that a value has been set for this parameter + $value = $command[$name]; + if ($value !== null) { + // Apply the parameter value with the location visitor + $foundVisitors[$location]->visit($command, $request, $arg, $value); + } + } + } + + // Serialize additional parameters + if ($additional = $operation->getAdditionalParameters()) { + if ($visitor = $this->prepareAdditionalParameters($operation, $command, $request, $additional)) { + $foundVisitors[$additional->getLocation()] = $visitor; + } + } + + // Call the after method on each visitor found in the operation + foreach ($foundVisitors as $visitor) { + $visitor->after($command, $request); + } + + return $request; + } + + /** + * Serialize additional parameters + * + * @param OperationInterface $operation Operation that owns the command + * @param CommandInterface $command Command to prepare + * @param RequestInterface $request Request to serialize + * @param Parameter $additional Additional parameters + * + * @return null|RequestVisitorInterface + */ + protected function prepareAdditionalParameters( + OperationInterface $operation, + CommandInterface $command, + RequestInterface $request, + Parameter $additional + ) { + if (!($location = $additional->getLocation())) { + return; + } + + $visitor = $this->factory->getRequestVisitor($location); + $hidden = $command[$command::HIDDEN_PARAMS]; + + foreach ($command->toArray() as $key => $value) { + // Ignore values that are null or built-in command options + if ($value !== null + && !in_array($key, $hidden) + && !$operation->hasParam($key) + ) { + $additional->setName($key); + $visitor->visit($command, $request, $additional, $value); + } + } + + return $visitor; + } + + /** + * Create a request for the command and operation + * + * @param CommandInterface $command Command to create a request for + * + * @return RequestInterface + */ + protected function createRequest(CommandInterface $command) + { + $operation = $command->getOperation(); + $client = $command->getClient(); + $options = $command[AbstractCommand::REQUEST_OPTIONS] ?: array(); + + // If the command does not specify a template, then assume the base URL of the client + if (!($uri = $operation->getUri())) { + return $client->createRequest($operation->getHttpMethod(), $client->getBaseUrl(), null, null, $options); + } + + // Get the path values and use the client config settings + $variables = array(); + foreach ($operation->getParams() as $name => $arg) { + if ($arg->getLocation() == 'uri') { + if (isset($command[$name])) { + $variables[$name] = $arg->filter($command[$name]); + if (!is_array($variables[$name])) { + $variables[$name] = (string) $variables[$name]; + } + } + } + } + + return $client->createRequest($operation->getHttpMethod(), array($uri, $variables), null, null, $options); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/DefaultResponseParser.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/DefaultResponseParser.php new file mode 100644 index 0000000..4fe3803 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/DefaultResponseParser.php @@ -0,0 +1,55 @@ +getRequest()->getResponse(); + + // Account for hard coded content-type values specified in service descriptions + if ($contentType = $command['command.expects']) { + $response->setHeader('Content-Type', $contentType); + } else { + $contentType = (string) $response->getHeader('Content-Type'); + } + + return $this->handleParsing($command, $response, $contentType); + } + + protected function handleParsing(CommandInterface $command, Response $response, $contentType) + { + $result = $response; + if ($result->getBody()) { + if (stripos($contentType, 'json') !== false) { + $result = $result->json(); + } elseif (stripos($contentType, 'xml') !== false) { + $result = $result->xml(); + } + } + + return $result; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/Factory/AliasFactory.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/Factory/AliasFactory.php new file mode 100644 index 0000000..1c5ce07 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/Factory/AliasFactory.php @@ -0,0 +1,39 @@ +client = $client; + $this->aliases = $aliases; + } + + public function factory($name, array $args = array()) + { + if (isset($this->aliases[$name])) { + try { + return $this->client->getCommand($this->aliases[$name], $args); + } catch (InvalidArgumentException $e) { + return null; + } + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/Factory/CompositeFactory.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/Factory/CompositeFactory.php new file mode 100644 index 0000000..e5c8844 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/Factory/CompositeFactory.php @@ -0,0 +1,154 @@ +getDescription()) { + $factories[] = new ServiceDescriptionFactory($description); + } + $factories[] = new ConcreteClassFactory($client); + + return new static($factories); + } + + /** + * @param array $factories Array of command factories + */ + public function __construct(array $factories = array()) + { + $this->factories = $factories; + } + + /** + * Add a command factory to the chain + * + * @param FactoryInterface $factory Factory to add + * @param string|FactoryInterface $before Insert the new command factory before a command factory class or object + * matching a class name. + * @return CompositeFactory + */ + public function add(FactoryInterface $factory, $before = null) + { + $pos = null; + + if ($before) { + foreach ($this->factories as $i => $f) { + if ($before instanceof FactoryInterface) { + if ($f === $before) { + $pos = $i; + break; + } + } elseif (is_string($before)) { + if ($f instanceof $before) { + $pos = $i; + break; + } + } + } + } + + if ($pos === null) { + $this->factories[] = $factory; + } else { + array_splice($this->factories, $i, 0, array($factory)); + } + + return $this; + } + + /** + * Check if the chain contains a specific command factory + * + * @param FactoryInterface|string $factory Factory to check + * + * @return bool + */ + public function has($factory) + { + return (bool) $this->find($factory); + } + + /** + * Remove a specific command factory from the chain + * + * @param string|FactoryInterface $factory Factory to remove by name or instance + * + * @return CompositeFactory + */ + public function remove($factory = null) + { + if (!($factory instanceof FactoryInterface)) { + $factory = $this->find($factory); + } + + $this->factories = array_values(array_filter($this->factories, function($f) use ($factory) { + return $f !== $factory; + })); + + return $this; + } + + /** + * Get a command factory by class name + * + * @param string|FactoryInterface $factory Command factory class or instance + * + * @return null|FactoryInterface + */ + public function find($factory) + { + foreach ($this->factories as $f) { + if ($factory === $f || (is_string($factory) && $f instanceof $factory)) { + return $f; + } + } + } + + /** + * Create a command using the associated command factories + * + * @param string $name Name of the command + * @param array $args Command arguments + * + * @return CommandInterface + */ + public function factory($name, array $args = array()) + { + foreach ($this->factories as $factory) { + $command = $factory->factory($name, $args); + if ($command) { + return $command; + } + } + } + + public function count() + { + return count($this->factories); + } + + public function getIterator() + { + return new \ArrayIterator($this->factories); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/Factory/ConcreteClassFactory.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/Factory/ConcreteClassFactory.php new file mode 100644 index 0000000..0e93dea --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/Factory/ConcreteClassFactory.php @@ -0,0 +1,47 @@ +client = $client; + $this->inflector = $inflector ?: Inflector::getDefault(); + } + + public function factory($name, array $args = array()) + { + // Determine the class to instantiate based on the namespace of the current client and the default directory + $prefix = $this->client->getConfig('command.prefix'); + if (!$prefix) { + // The prefix can be specified in a factory method and is cached + $prefix = implode('\\', array_slice(explode('\\', get_class($this->client)), 0, -1)) . '\\Command\\'; + $this->client->getConfig()->set('command.prefix', $prefix); + } + + $class = $prefix . str_replace(' ', '\\', ucwords(str_replace('.', ' ', $this->inflector->camel($name)))); + + // Create the concrete command if it exists + if (class_exists($class)) { + return new $class($args); + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/Factory/FactoryInterface.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/Factory/FactoryInterface.php new file mode 100644 index 0000000..35c299d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/Factory/FactoryInterface.php @@ -0,0 +1,21 @@ +map = $map; + } + + public function factory($name, array $args = array()) + { + if (isset($this->map[$name])) { + $class = $this->map[$name]; + + return new $class($args); + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/Factory/ServiceDescriptionFactory.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/Factory/ServiceDescriptionFactory.php new file mode 100644 index 0000000..b943a5b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/Factory/ServiceDescriptionFactory.php @@ -0,0 +1,71 @@ +setServiceDescription($description); + $this->inflector = $inflector; + } + + /** + * Change the service description used with the factory + * + * @param ServiceDescriptionInterface $description Service description to use + * + * @return FactoryInterface + */ + public function setServiceDescription(ServiceDescriptionInterface $description) + { + $this->description = $description; + + return $this; + } + + /** + * Returns the service description + * + * @return ServiceDescriptionInterface + */ + public function getServiceDescription() + { + return $this->description; + } + + public function factory($name, array $args = array()) + { + $command = $this->description->getOperation($name); + + // If a command wasn't found, then try to uppercase the first letter and try again + if (!$command) { + $command = $this->description->getOperation(ucfirst($name)); + // If an inflector was passed, then attempt to get the command using snake_case inflection + if (!$command && $this->inflector) { + $command = $this->description->getOperation($this->inflector->snake($name)); + } + } + + if ($command) { + $class = $command->getClass(); + return new $class($args, $command, $this->description); + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/AbstractRequestVisitor.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/AbstractRequestVisitor.php new file mode 100644 index 0000000..adcfca1 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/AbstractRequestVisitor.php @@ -0,0 +1,69 @@ +resolveRecursively($value, $param) + : $param->filter($value); + } + + /** + * Map nested parameters into the location_key based parameters + * + * @param array $value Value to map + * @param Parameter $param Parameter that holds information about the current key + * + * @return array Returns the mapped array + */ + protected function resolveRecursively(array $value, Parameter $param) + { + foreach ($value as $name => &$v) { + switch ($param->getType()) { + case 'object': + if ($subParam = $param->getProperty($name)) { + $key = $subParam->getWireName(); + $value[$key] = $this->prepareValue($v, $subParam); + if ($name != $key) { + unset($value[$name]); + } + } elseif ($param->getAdditionalProperties() instanceof Parameter) { + $v = $this->prepareValue($v, $param->getAdditionalProperties()); + } + break; + case 'array': + if ($items = $param->getItems()) { + $v = $this->prepareValue($v, $items); + } + break; + } + } + + return $param->filter($value); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/BodyVisitor.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/BodyVisitor.php new file mode 100644 index 0000000..168d780 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/BodyVisitor.php @@ -0,0 +1,58 @@ +filter($value); + $entityBody = EntityBody::factory($value); + $request->setBody($entityBody); + $this->addExpectHeader($request, $entityBody, $param->getData('expect_header')); + // Add the Content-Encoding header if one is set on the EntityBody + if ($encoding = $entityBody->getContentEncoding()) { + $request->setHeader('Content-Encoding', $encoding); + } + } + + /** + * Add the appropriate expect header to a request + * + * @param EntityEnclosingRequestInterface $request Request to update + * @param EntityBodyInterface $body Entity body of the request + * @param string|int $expect Expect header setting + */ + protected function addExpectHeader(EntityEnclosingRequestInterface $request, EntityBodyInterface $body, $expect) + { + // Allow the `expect` data parameter to be set to remove the Expect header from the request + if ($expect === false) { + $request->removeHeader('Expect'); + } elseif ($expect !== true) { + // Default to using a MB as the point in which to start using the expect header + $expect = $expect ?: 1048576; + // If the expect_header value is numeric then only add if the size is greater than the cutoff + if (is_numeric($expect) && $body->getSize()) { + if ($body->getSize() < $expect) { + $request->removeHeader('Expect'); + } else { + $request->setHeader('Expect', '100-Continue'); + } + } + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/HeaderVisitor.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/HeaderVisitor.php new file mode 100644 index 0000000..2a53754 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/HeaderVisitor.php @@ -0,0 +1,44 @@ +filter($value); + if ($param->getType() == 'object' && $param->getAdditionalProperties() instanceof Parameter) { + $this->addPrefixedHeaders($request, $param, $value); + } else { + $request->setHeader($param->getWireName(), $value); + } + } + + /** + * Add a prefixed array of headers to the request + * + * @param RequestInterface $request Request to update + * @param Parameter $param Parameter object + * @param array $value Header array to add + * + * @throws InvalidArgumentException + */ + protected function addPrefixedHeaders(RequestInterface $request, Parameter $param, $value) + { + if (!is_array($value)) { + throw new InvalidArgumentException('An array of mapped headers expected, but received a single value'); + } + $prefix = $param->getSentAs(); + foreach ($value as $headerName => $headerValue) { + $request->setHeader($prefix . $headerName, $headerValue); + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/JsonVisitor.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/JsonVisitor.php new file mode 100644 index 0000000..757e1c5 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/JsonVisitor.php @@ -0,0 +1,63 @@ +data = new \SplObjectStorage(); + } + + /** + * Set the Content-Type header to add to the request if JSON is added to the body. This visitor does not add a + * Content-Type header unless you specify one here. + * + * @param string $header Header to set when JSON is added (e.g. application/json) + * + * @return self + */ + public function setContentTypeHeader($header = 'application/json') + { + $this->jsonContentType = $header; + + return $this; + } + + public function visit(CommandInterface $command, RequestInterface $request, Parameter $param, $value) + { + if (isset($this->data[$command])) { + $json = $this->data[$command]; + } else { + $json = array(); + } + $json[$param->getWireName()] = $this->prepareValue($value, $param); + $this->data[$command] = $json; + } + + public function after(CommandInterface $command, RequestInterface $request) + { + if (isset($this->data[$command])) { + // Don't overwrite the Content-Type if one is set + if ($this->jsonContentType && !$request->hasHeader('Content-Type')) { + $request->setHeader('Content-Type', $this->jsonContentType); + } + + $request->setBody(json_encode($this->data[$command])); + unset($this->data[$command]); + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/PostFieldVisitor.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/PostFieldVisitor.php new file mode 100644 index 0000000..975850b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/PostFieldVisitor.php @@ -0,0 +1,18 @@ +setPostField($param->getWireName(), $this->prepareValue($value, $param)); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/PostFileVisitor.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/PostFileVisitor.php new file mode 100644 index 0000000..0853ebe --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/PostFileVisitor.php @@ -0,0 +1,24 @@ +filter($value); + if ($value instanceof PostFileInterface) { + $request->addPostFile($value); + } else { + $request->addPostFile($param->getWireName(), $value); + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/QueryVisitor.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/QueryVisitor.php new file mode 100644 index 0000000..315877a --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/QueryVisitor.php @@ -0,0 +1,18 @@ +getQuery()->set($param->getWireName(), $this->prepareValue($value, $param)); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/RequestVisitorInterface.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/RequestVisitorInterface.php new file mode 100644 index 0000000..14e0b2d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/RequestVisitorInterface.php @@ -0,0 +1,31 @@ +setResponseBody($value); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/XmlVisitor.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/XmlVisitor.php new file mode 100644 index 0000000..5b71487 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/XmlVisitor.php @@ -0,0 +1,252 @@ +data = new \SplObjectStorage(); + } + + /** + * Change the content-type header that is added when XML is found + * + * @param string $header Header to set when XML is found + * + * @return self + */ + public function setContentTypeHeader($header) + { + $this->contentType = $header; + + return $this; + } + + public function visit(CommandInterface $command, RequestInterface $request, Parameter $param, $value) + { + $xml = isset($this->data[$command]) + ? $this->data[$command] + : $this->createRootElement($param->getParent()); + $this->addXml($xml, $param, $value); + + $this->data[$command] = $xml; + } + + public function after(CommandInterface $command, RequestInterface $request) + { + $xml = null; + + // If data was found that needs to be serialized, then do so + if (isset($this->data[$command])) { + $xml = $this->finishDocument($this->data[$command]); + unset($this->data[$command]); + } else { + // Check if XML should always be sent for the command + $operation = $command->getOperation(); + if ($operation->getData('xmlAllowEmpty')) { + $xmlWriter = $this->createRootElement($operation); + $xml = $this->finishDocument($xmlWriter); + } + } + + if ($xml) { + // Don't overwrite the Content-Type if one is set + if ($this->contentType && !$request->hasHeader('Content-Type')) { + $request->setHeader('Content-Type', $this->contentType); + } + $request->setBody($xml); + } + } + + /** + * Create the root XML element to use with a request + * + * @param Operation $operation Operation object + * + * @return \XMLWriter + */ + protected function createRootElement(Operation $operation) + { + static $defaultRoot = array('name' => 'Request'); + // If no root element was specified, then just wrap the XML in 'Request' + $root = $operation->getData('xmlRoot') ?: $defaultRoot; + // Allow the XML declaration to be customized with xmlEncoding + $encoding = $operation->getData('xmlEncoding'); + + $xmlWriter = $this->startDocument($encoding); + + $xmlWriter->startElement($root['name']); + // Create the wrapping element with no namespaces if no namespaces were present + if (!empty($root['namespaces'])) { + // Create the wrapping element with an array of one or more namespaces + foreach ((array) $root['namespaces'] as $prefix => $uri) { + $nsLabel = 'xmlns'; + if (!is_numeric($prefix)) { + $nsLabel .= ':'.$prefix; + } + $xmlWriter->writeAttribute($nsLabel, $uri); + } + } + return $xmlWriter; + } + + /** + * Recursively build the XML body + * + * @param \XMLWriter $xmlWriter XML to modify + * @param Parameter $param API Parameter + * @param mixed $value Value to add + */ + protected function addXml(\XMLWriter $xmlWriter, Parameter $param, $value) + { + if ($value === null) { + return; + } + + $value = $param->filter($value); + $type = $param->getType(); + $name = $param->getWireName(); + $prefix = null; + $namespace = $param->getData('xmlNamespace'); + if (false !== strpos($name, ':')) { + list($prefix, $name) = explode(':', $name, 2); + } + + if ($type == 'object' || $type == 'array') { + if (!$param->getData('xmlFlattened')) { + $xmlWriter->startElementNS(null, $name, $namespace); + } + if ($param->getType() == 'array') { + $this->addXmlArray($xmlWriter, $param, $value); + } elseif ($param->getType() == 'object') { + $this->addXmlObject($xmlWriter, $param, $value); + } + if (!$param->getData('xmlFlattened')) { + $xmlWriter->endElement(); + } + return; + } + if ($param->getData('xmlAttribute')) { + $this->writeAttribute($xmlWriter, $prefix, $name, $namespace, $value); + } else { + $this->writeElement($xmlWriter, $prefix, $name, $namespace, $value); + } + } + + /** + * Write an attribute with namespace if used + * + * @param \XMLWriter $xmlWriter XMLWriter instance + * @param string $prefix Namespace prefix if any + * @param string $name Attribute name + * @param string $namespace The uri of the namespace + * @param string $value The attribute content + */ + protected function writeAttribute($xmlWriter, $prefix, $name, $namespace, $value) + { + if (empty($namespace)) { + $xmlWriter->writeAttribute($name, $value); + } else { + $xmlWriter->writeAttributeNS($prefix, $name, $namespace, $value); + } + } + + /** + * Write an element with namespace if used + * + * @param \XMLWriter $xmlWriter XML writer resource + * @param string $prefix Namespace prefix if any + * @param string $name Element name + * @param string $namespace The uri of the namespace + * @param string $value The element content + */ + protected function writeElement(\XMLWriter $xmlWriter, $prefix, $name, $namespace, $value) + { + $xmlWriter->startElementNS($prefix, $name, $namespace); + if (strpbrk($value, '<>&')) { + $xmlWriter->writeCData($value); + } else { + $xmlWriter->writeRaw($value); + } + $xmlWriter->endElement(); + } + + /** + * Create a new xml writer and start a document + * + * @param string $encoding document encoding + * + * @return \XMLWriter the writer resource + */ + protected function startDocument($encoding) + { + $xmlWriter = new \XMLWriter(); + $xmlWriter->openMemory(); + $xmlWriter->startDocument('1.0', $encoding); + + return $xmlWriter; + } + + /** + * End the document and return the output + * + * @param \XMLWriter $xmlWriter + * + * @return \string the writer resource + */ + protected function finishDocument($xmlWriter) + { + $xmlWriter->endDocument(); + + return $xmlWriter->outputMemory(); + } + + /** + * Add an array to the XML + */ + protected function addXmlArray(\XMLWriter $xmlWriter, Parameter $param, &$value) + { + if ($items = $param->getItems()) { + foreach ($value as $v) { + $this->addXml($xmlWriter, $items, $v); + } + } + } + + /** + * Add an object to the XML + */ + protected function addXmlObject(\XMLWriter $xmlWriter, Parameter $param, &$value) + { + $noAttributes = array(); + // add values which have attributes + foreach ($value as $name => $v) { + if ($property = $param->getProperty($name)) { + if ($property->getData('xmlAttribute')) { + $this->addXml($xmlWriter, $property, $v); + } else { + $noAttributes[] = array('value' => $v, 'property' => $property); + } + } + } + // now add values with no attributes + foreach ($noAttributes as $element) { + $this->addXml($xmlWriter, $element['property'], $element['value']); + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/AbstractResponseVisitor.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/AbstractResponseVisitor.php new file mode 100644 index 0000000..d87eeb9 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/AbstractResponseVisitor.php @@ -0,0 +1,26 @@ +getName()] = $param->filter($response->getBody()); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/HeaderVisitor.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/HeaderVisitor.php new file mode 100644 index 0000000..0f8737c --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/HeaderVisitor.php @@ -0,0 +1,50 @@ +getType() == 'object' && $param->getAdditionalProperties() instanceof Parameter) { + $this->processPrefixedHeaders($response, $param, $value); + } else { + $value[$param->getName()] = $param->filter((string) $response->getHeader($param->getWireName())); + } + } + + /** + * Process a prefixed header array + * + * @param Response $response Response that contains the headers + * @param Parameter $param Parameter object + * @param array $value Value response array to modify + */ + protected function processPrefixedHeaders(Response $response, Parameter $param, &$value) + { + // Grab prefixed headers that should be placed into an array with the prefix stripped + if ($prefix = $param->getSentAs()) { + $container = $param->getName(); + $len = strlen($prefix); + // Find all matching headers and place them into the containing element + foreach ($response->getHeaders()->toArray() as $key => $header) { + if (stripos($key, $prefix) === 0) { + // Account for multi-value headers + $value[$container][substr($key, $len)] = count($header) == 1 ? end($header) : $header; + } + } + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/JsonVisitor.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/JsonVisitor.php new file mode 100644 index 0000000..a609ebd --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/JsonVisitor.php @@ -0,0 +1,93 @@ +getResponse()->json(); + } + + public function visit( + CommandInterface $command, + Response $response, + Parameter $param, + &$value, + $context = null + ) { + $name = $param->getName(); + $key = $param->getWireName(); + if (isset($value[$key])) { + $this->recursiveProcess($param, $value[$key]); + if ($key != $name) { + $value[$name] = $value[$key]; + unset($value[$key]); + } + } + } + + /** + * Recursively process a parameter while applying filters + * + * @param Parameter $param API parameter being validated + * @param mixed $value Value to validate and process. The value may change during this process. + */ + protected function recursiveProcess(Parameter $param, &$value) + { + if ($value === null) { + return; + } + + if (is_array($value)) { + $type = $param->getType(); + if ($type == 'array') { + foreach ($value as &$item) { + $this->recursiveProcess($param->getItems(), $item); + } + } elseif ($type == 'object' && !isset($value[0])) { + // On the above line, we ensure that the array is associative and not numerically indexed + $knownProperties = array(); + if ($properties = $param->getProperties()) { + foreach ($properties as $property) { + $name = $property->getName(); + $key = $property->getWireName(); + $knownProperties[$name] = 1; + if (isset($value[$key])) { + $this->recursiveProcess($property, $value[$key]); + if ($key != $name) { + $value[$name] = $value[$key]; + unset($value[$key]); + } + } + } + } + + // Remove any unknown and potentially unsafe properties + if ($param->getAdditionalProperties() === false) { + $value = array_intersect_key($value, $knownProperties); + } elseif (($additional = $param->getAdditionalProperties()) !== true) { + // Validate and filter additional properties + foreach ($value as &$v) { + $this->recursiveProcess($additional, $v); + } + } + } + } + + $value = $param->filter($value); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/ReasonPhraseVisitor.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/ReasonPhraseVisitor.php new file mode 100644 index 0000000..1b10ebc --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/ReasonPhraseVisitor.php @@ -0,0 +1,23 @@ +getName()] = $response->getReasonPhrase(); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/ResponseVisitorInterface.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/ResponseVisitorInterface.php new file mode 100644 index 0000000..033f40c --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/ResponseVisitorInterface.php @@ -0,0 +1,46 @@ +getName()] = $response->getStatusCode(); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/XmlVisitor.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/XmlVisitor.php new file mode 100644 index 0000000..bb7124b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/XmlVisitor.php @@ -0,0 +1,151 @@ +getResponse()->xml()), true); + } + + public function visit( + CommandInterface $command, + Response $response, + Parameter $param, + &$value, + $context = null + ) { + $sentAs = $param->getWireName(); + $name = $param->getName(); + if (isset($value[$sentAs])) { + $this->recursiveProcess($param, $value[$sentAs]); + if ($name != $sentAs) { + $value[$name] = $value[$sentAs]; + unset($value[$sentAs]); + } + } + } + + /** + * Recursively process a parameter while applying filters + * + * @param Parameter $param API parameter being processed + * @param mixed $value Value to validate and process. The value may change during this process. + */ + protected function recursiveProcess(Parameter $param, &$value) + { + $type = $param->getType(); + + if (!is_array($value)) { + if ($type == 'array') { + // Cast to an array if the value was a string, but should be an array + $this->recursiveProcess($param->getItems(), $value); + $value = array($value); + } + } elseif ($type == 'object') { + $this->processObject($param, $value); + } elseif ($type == 'array') { + $this->processArray($param, $value); + } elseif ($type == 'string' && gettype($value) == 'array') { + $value = ''; + } + + if ($value !== null) { + $value = $param->filter($value); + } + } + + /** + * Process an array + * + * @param Parameter $param API parameter being parsed + * @param mixed $value Value to process + */ + protected function processArray(Parameter $param, &$value) + { + // Convert the node if it was meant to be an array + if (!isset($value[0])) { + // Collections fo nodes are sometimes wrapped in an additional array. For example: + // 12 should become: + // array('Items' => array(array('a' => 1), array('a' => 2)) + // Some nodes are not wrapped. For example: 12 + // should become array('Foo' => array(array('a' => 1), array('a' => 2)) + if ($param->getItems() && isset($value[$param->getItems()->getWireName()])) { + // Account for the case of a collection wrapping wrapped nodes: Items => Item[] + $value = $value[$param->getItems()->getWireName()]; + // If the wrapped node only had one value, then make it an array of nodes + if (!isset($value[0]) || !is_array($value)) { + $value = array($value); + } + } elseif (!empty($value)) { + // Account for repeated nodes that must be an array: Foo => Baz, Foo => Baz, but only if the + // value is set and not empty + $value = array($value); + } + } + + foreach ($value as &$item) { + $this->recursiveProcess($param->getItems(), $item); + } + } + + /** + * Process an object + * + * @param Parameter $param API parameter being parsed + * @param mixed $value Value to process + */ + protected function processObject(Parameter $param, &$value) + { + // Ensure that the array is associative and not numerically indexed + if (!isset($value[0]) && ($properties = $param->getProperties())) { + $knownProperties = array(); + foreach ($properties as $property) { + $name = $property->getName(); + $sentAs = $property->getWireName(); + $knownProperties[$name] = 1; + if ($property->getData('xmlAttribute')) { + $this->processXmlAttribute($property, $value); + } elseif (isset($value[$sentAs])) { + $this->recursiveProcess($property, $value[$sentAs]); + if ($name != $sentAs) { + $value[$name] = $value[$sentAs]; + unset($value[$sentAs]); + } + } + } + + // Remove any unknown and potentially unsafe properties + if ($param->getAdditionalProperties() === false) { + $value = array_intersect_key($value, $knownProperties); + } + } + } + + /** + * Process an XML attribute property + * + * @param Parameter $property Property to process + * @param array $value Value to process and update + */ + protected function processXmlAttribute(Parameter $property, array &$value) + { + $sentAs = $property->getWireName(); + if (isset($value['@attributes'][$sentAs])) { + $value[$property->getName()] = $value['@attributes'][$sentAs]; + unset($value['@attributes'][$sentAs]); + if (empty($value['@attributes'])) { + unset($value['@attributes']); + } + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/VisitorFlyweight.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/VisitorFlyweight.php new file mode 100644 index 0000000..74cb628 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/VisitorFlyweight.php @@ -0,0 +1,138 @@ + 'Guzzle\Service\Command\LocationVisitor\Request\BodyVisitor', + 'request.header' => 'Guzzle\Service\Command\LocationVisitor\Request\HeaderVisitor', + 'request.json' => 'Guzzle\Service\Command\LocationVisitor\Request\JsonVisitor', + 'request.postField' => 'Guzzle\Service\Command\LocationVisitor\Request\PostFieldVisitor', + 'request.postFile' => 'Guzzle\Service\Command\LocationVisitor\Request\PostFileVisitor', + 'request.query' => 'Guzzle\Service\Command\LocationVisitor\Request\QueryVisitor', + 'request.response_body' => 'Guzzle\Service\Command\LocationVisitor\Request\ResponseBodyVisitor', + 'request.responseBody' => 'Guzzle\Service\Command\LocationVisitor\Request\ResponseBodyVisitor', + 'request.xml' => 'Guzzle\Service\Command\LocationVisitor\Request\XmlVisitor', + 'response.body' => 'Guzzle\Service\Command\LocationVisitor\Response\BodyVisitor', + 'response.header' => 'Guzzle\Service\Command\LocationVisitor\Response\HeaderVisitor', + 'response.json' => 'Guzzle\Service\Command\LocationVisitor\Response\JsonVisitor', + 'response.reasonPhrase' => 'Guzzle\Service\Command\LocationVisitor\Response\ReasonPhraseVisitor', + 'response.statusCode' => 'Guzzle\Service\Command\LocationVisitor\Response\StatusCodeVisitor', + 'response.xml' => 'Guzzle\Service\Command\LocationVisitor\Response\XmlVisitor' + ); + + /** @var array Array of mappings of location names to classes */ + protected $mappings; + + /** @var array Cache of instantiated visitors */ + protected $cache = array(); + + /** + * @return self + * @codeCoverageIgnore + */ + public static function getInstance() + { + if (!self::$instance) { + self::$instance = new self(); + } + + return self::$instance; + } + + /** + * @param array $mappings Array mapping request.name and response.name to location visitor classes. Leave null to + * use the default values. + */ + public function __construct(array $mappings = null) + { + $this->mappings = $mappings === null ? self::$defaultMappings : $mappings; + } + + /** + * Get an instance of a request visitor by location name + * + * @param string $visitor Visitor name + * + * @return RequestVisitorInterface + */ + public function getRequestVisitor($visitor) + { + return $this->getKey('request.' . $visitor); + } + + /** + * Get an instance of a response visitor by location name + * + * @param string $visitor Visitor name + * + * @return ResponseVisitorInterface + */ + public function getResponseVisitor($visitor) + { + return $this->getKey('response.' . $visitor); + } + + /** + * Add a response visitor to the factory by name + * + * @param string $name Name of the visitor + * @param RequestVisitorInterface $visitor Visitor to add + * + * @return self + */ + public function addRequestVisitor($name, RequestVisitorInterface $visitor) + { + $this->cache['request.' . $name] = $visitor; + + return $this; + } + + /** + * Add a response visitor to the factory by name + * + * @param string $name Name of the visitor + * @param ResponseVisitorInterface $visitor Visitor to add + * + * @return self + */ + public function addResponseVisitor($name, ResponseVisitorInterface $visitor) + { + $this->cache['response.' . $name] = $visitor; + + return $this; + } + + /** + * Get a visitor by key value name + * + * @param string $key Key name to retrieve + * + * @return mixed + * @throws InvalidArgumentException + */ + private function getKey($key) + { + if (!isset($this->cache[$key])) { + if (!isset($this->mappings[$key])) { + list($type, $name) = explode('.', $key); + throw new InvalidArgumentException("No {$type} visitor has been mapped for {$name}"); + } + $this->cache[$key] = new $this->mappings[$key]; + } + + return $this->cache[$key]; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/OperationCommand.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/OperationCommand.php new file mode 100644 index 0000000..0748b5a --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/OperationCommand.php @@ -0,0 +1,89 @@ +responseParser = $parser; + + return $this; + } + + /** + * Set the request serializer used with the command + * + * @param RequestSerializerInterface $serializer Request serializer + * + * @return self + */ + public function setRequestSerializer(RequestSerializerInterface $serializer) + { + $this->requestSerializer = $serializer; + + return $this; + } + + /** + * Get the request serializer used with the command + * + * @return RequestSerializerInterface + */ + public function getRequestSerializer() + { + if (!$this->requestSerializer) { + // Use the default request serializer if none was found + $this->requestSerializer = DefaultRequestSerializer::getInstance(); + } + + return $this->requestSerializer; + } + + /** + * Get the response parser used for the operation + * + * @return ResponseParserInterface + */ + public function getResponseParser() + { + if (!$this->responseParser) { + // Use the default response parser if none was found + $this->responseParser = OperationResponseParser::getInstance(); + } + + return $this->responseParser; + } + + protected function build() + { + // Prepare and serialize the request + $this->request = $this->getRequestSerializer()->prepare($this); + } + + protected function process() + { + // Do not process the response if 'command.response_processing' is set to 'raw' + $this->result = $this[self::RESPONSE_PROCESSING] == self::TYPE_RAW + ? $this->request->getResponse() + : $this->getResponseParser()->parse($this); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/OperationResponseParser.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/OperationResponseParser.php new file mode 100644 index 0000000..ca00bc0 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/OperationResponseParser.php @@ -0,0 +1,195 @@ +factory = $factory; + $this->schemaInModels = $schemaInModels; + } + + /** + * Add a location visitor to the command + * + * @param string $location Location to associate with the visitor + * @param ResponseVisitorInterface $visitor Visitor to attach + * + * @return self + */ + public function addVisitor($location, ResponseVisitorInterface $visitor) + { + $this->factory->addResponseVisitor($location, $visitor); + + return $this; + } + + protected function handleParsing(CommandInterface $command, Response $response, $contentType) + { + $operation = $command->getOperation(); + $type = $operation->getResponseType(); + $model = null; + + if ($type == OperationInterface::TYPE_MODEL) { + $model = $operation->getServiceDescription()->getModel($operation->getResponseClass()); + } elseif ($type == OperationInterface::TYPE_CLASS) { + return $this->parseClass($command); + } + + if (!$model) { + // Return basic processing if the responseType is not model or the model cannot be found + return parent::handleParsing($command, $response, $contentType); + } elseif ($command[AbstractCommand::RESPONSE_PROCESSING] != AbstractCommand::TYPE_MODEL) { + // Returns a model with no visiting if the command response processing is not model + return new Model(parent::handleParsing($command, $response, $contentType)); + } else { + // Only inject the schema into the model if "schemaInModel" is true + return new Model($this->visitResult($model, $command, $response), $this->schemaInModels ? $model : null); + } + } + + /** + * Parse a class object + * + * @param CommandInterface $command Command to parse into an object + * + * @return mixed + * @throws ResponseClassException + */ + protected function parseClass(CommandInterface $command) + { + // Emit the operation.parse_class event. If a listener injects a 'result' property, then that will be the result + $event = new CreateResponseClassEvent(array('command' => $command)); + $command->getClient()->getEventDispatcher()->dispatch('command.parse_response', $event); + if ($result = $event->getResult()) { + return $result; + } + + $className = $command->getOperation()->getResponseClass(); + if (!method_exists($className, 'fromCommand')) { + throw new ResponseClassException("{$className} must exist and implement a static fromCommand() method"); + } + + return $className::fromCommand($command); + } + + /** + * Perform transformations on the result array + * + * @param Parameter $model Model that defines the structure + * @param CommandInterface $command Command that performed the operation + * @param Response $response Response received + * + * @return array Returns the array of result data + */ + protected function visitResult(Parameter $model, CommandInterface $command, Response $response) + { + $foundVisitors = $result = $knownProps = array(); + $props = $model->getProperties(); + + foreach ($props as $schema) { + if ($location = $schema->getLocation()) { + // Trigger the before method on the first found visitor of this type + if (!isset($foundVisitors[$location])) { + $foundVisitors[$location] = $this->factory->getResponseVisitor($location); + $foundVisitors[$location]->before($command, $result); + } + } + } + + // Visit additional properties when it is an actual schema + if (($additional = $model->getAdditionalProperties()) instanceof Parameter) { + $this->visitAdditionalProperties($model, $command, $response, $additional, $result, $foundVisitors); + } + + // Apply the parameter value with the location visitor + foreach ($props as $schema) { + $knownProps[$schema->getName()] = 1; + if ($location = $schema->getLocation()) { + $foundVisitors[$location]->visit($command, $response, $schema, $result); + } + } + + // Remove any unknown and potentially unsafe top-level properties + if ($additional === false) { + $result = array_intersect_key($result, $knownProps); + } + + // Call the after() method of each found visitor + foreach ($foundVisitors as $visitor) { + $visitor->after($command); + } + + return $result; + } + + protected function visitAdditionalProperties( + Parameter $model, + CommandInterface $command, + Response $response, + Parameter $additional, + &$result, + array &$foundVisitors + ) { + // Only visit when a location is specified + if ($location = $additional->getLocation()) { + if (!isset($foundVisitors[$location])) { + $foundVisitors[$location] = $this->factory->getResponseVisitor($location); + $foundVisitors[$location]->before($command, $result); + } + // Only traverse if an array was parsed from the before() visitors + if (is_array($result)) { + // Find each additional property + foreach (array_keys($result) as $key) { + // Check if the model actually knows this property. If so, then it is not additional + if (!$model->getProperty($key)) { + // Set the name to the key so that we can parse it with each visitor + $additional->setName($key); + $foundVisitors[$location]->visit($command, $response, $additional, $result); + } + } + // Reset the additionalProperties name to null + $additional->setName(null); + } + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/RequestSerializerInterface.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/RequestSerializerInterface.php new file mode 100644 index 0000000..60b9334 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Command/RequestSerializerInterface.php @@ -0,0 +1,21 @@ + true, 'httpMethod' => true, 'uri' => true, 'class' => true, 'responseClass' => true, + 'responseType' => true, 'responseNotes' => true, 'notes' => true, 'summary' => true, 'documentationUrl' => true, + 'deprecated' => true, 'data' => true, 'parameters' => true, 'additionalParameters' => true, + 'errorResponses' => true + ); + + /** @var array Parameters */ + protected $parameters = array(); + + /** @var Parameter Additional parameters schema */ + protected $additionalParameters; + + /** @var string Name of the command */ + protected $name; + + /** @var string HTTP method */ + protected $httpMethod; + + /** @var string This is a short summary of what the operation does */ + protected $summary; + + /** @var string A longer text field to explain the behavior of the operation. */ + protected $notes; + + /** @var string Reference URL providing more information about the operation */ + protected $documentationUrl; + + /** @var string HTTP URI of the command */ + protected $uri; + + /** @var string Class of the command object */ + protected $class; + + /** @var string This is what is returned from the method */ + protected $responseClass; + + /** @var string Type information about the response */ + protected $responseType; + + /** @var string Information about the response returned by the operation */ + protected $responseNotes; + + /** @var bool Whether or not the command is deprecated */ + protected $deprecated; + + /** @var array Array of errors that could occur when running the command */ + protected $errorResponses; + + /** @var ServiceDescriptionInterface */ + protected $description; + + /** @var array Extra operation information */ + protected $data; + + /** + * Builds an Operation object using an array of configuration data: + * - name: (string) Name of the command + * - httpMethod: (string) HTTP method of the operation + * - uri: (string) URI template that can create a relative or absolute URL + * - class: (string) Concrete class that implements this command + * - parameters: (array) Associative array of parameters for the command. {@see Parameter} for information. + * - summary: (string) This is a short summary of what the operation does + * - notes: (string) A longer text field to explain the behavior of the operation. + * - documentationUrl: (string) Reference URL providing more information about the operation + * - responseClass: (string) This is what is returned from the method. Can be a primitive, PSR-0 compliant + * class name, or model. + * - responseNotes: (string) Information about the response returned by the operation + * - responseType: (string) One of 'primitive', 'class', 'model', or 'documentation'. If not specified, this + * value will be automatically inferred based on whether or not there is a model matching the + * name, if a matching PSR-0 compliant class name is found, or set to 'primitive' by default. + * - deprecated: (bool) Set to true if this is a deprecated command + * - errorResponses: (array) Errors that could occur when executing the command. Array of hashes, each with a + * 'code' (the HTTP response code), 'reason' (response reason phrase or description of the + * error), and 'class' (a custom exception class that would be thrown if the error is + * encountered). + * - data: (array) Any extra data that might be used to help build or serialize the operation + * - additionalParameters: (null|array) Parameter schema to use when an option is passed to the operation that is + * not in the schema + * + * @param array $config Array of configuration data + * @param ServiceDescriptionInterface $description Service description used to resolve models if $ref tags are found + */ + public function __construct(array $config = array(), ServiceDescriptionInterface $description = null) + { + $this->description = $description; + + // Get the intersection of the available properties and properties set on the operation + foreach (array_intersect_key($config, self::$properties) as $key => $value) { + $this->{$key} = $value; + } + + $this->class = $this->class ?: self::DEFAULT_COMMAND_CLASS; + $this->deprecated = (bool) $this->deprecated; + $this->errorResponses = $this->errorResponses ?: array(); + $this->data = $this->data ?: array(); + + if (!$this->responseClass) { + $this->responseClass = 'array'; + $this->responseType = 'primitive'; + } elseif ($this->responseType) { + // Set the response type to perform validation + $this->setResponseType($this->responseType); + } else { + // A response class was set and no response type was set, so guess what the type is + $this->inferResponseType(); + } + + // Parameters need special handling when adding + if ($this->parameters) { + foreach ($this->parameters as $name => $param) { + if ($param instanceof Parameter) { + $param->setName($name)->setParent($this); + } elseif (is_array($param)) { + $param['name'] = $name; + $this->addParam(new Parameter($param, $this->description)); + } + } + } + + if ($this->additionalParameters) { + if ($this->additionalParameters instanceof Parameter) { + $this->additionalParameters->setParent($this); + } elseif (is_array($this->additionalParameters)) { + $this->setadditionalParameters(new Parameter($this->additionalParameters, $this->description)); + } + } + } + + public function toArray() + { + $result = array(); + // Grab valid properties and filter out values that weren't set + foreach (array_keys(self::$properties) as $check) { + if ($value = $this->{$check}) { + $result[$check] = $value; + } + } + // Remove the name property + unset($result['name']); + // Parameters need to be converted to arrays + $result['parameters'] = array(); + foreach ($this->parameters as $key => $param) { + $result['parameters'][$key] = $param->toArray(); + } + // Additional parameters need to be cast to an array + if ($this->additionalParameters instanceof Parameter) { + $result['additionalParameters'] = $this->additionalParameters->toArray(); + } + + return $result; + } + + public function getServiceDescription() + { + return $this->description; + } + + public function setServiceDescription(ServiceDescriptionInterface $description) + { + $this->description = $description; + + return $this; + } + + public function getParams() + { + return $this->parameters; + } + + public function getParamNames() + { + return array_keys($this->parameters); + } + + public function hasParam($name) + { + return isset($this->parameters[$name]); + } + + public function getParam($param) + { + return isset($this->parameters[$param]) ? $this->parameters[$param] : null; + } + + /** + * Add a parameter to the command + * + * @param Parameter $param Parameter to add + * + * @return self + */ + public function addParam(Parameter $param) + { + $this->parameters[$param->getName()] = $param; + $param->setParent($this); + + return $this; + } + + /** + * Remove a parameter from the command + * + * @param string $name Name of the parameter to remove + * + * @return self + */ + public function removeParam($name) + { + unset($this->parameters[$name]); + + return $this; + } + + public function getHttpMethod() + { + return $this->httpMethod; + } + + /** + * Set the HTTP method of the command + * + * @param string $httpMethod Method to set + * + * @return self + */ + public function setHttpMethod($httpMethod) + { + $this->httpMethod = $httpMethod; + + return $this; + } + + public function getClass() + { + return $this->class; + } + + /** + * Set the concrete class of the command + * + * @param string $className Concrete class name + * + * @return self + */ + public function setClass($className) + { + $this->class = $className; + + return $this; + } + + public function getName() + { + return $this->name; + } + + /** + * Set the name of the command + * + * @param string $name Name of the command + * + * @return self + */ + public function setName($name) + { + $this->name = $name; + + return $this; + } + + public function getSummary() + { + return $this->summary; + } + + /** + * Set a short summary of what the operation does + * + * @param string $summary Short summary of the operation + * + * @return self + */ + public function setSummary($summary) + { + $this->summary = $summary; + + return $this; + } + + public function getNotes() + { + return $this->notes; + } + + /** + * Set a longer text field to explain the behavior of the operation. + * + * @param string $notes Notes on the operation + * + * @return self + */ + public function setNotes($notes) + { + $this->notes = $notes; + + return $this; + } + + public function getDocumentationUrl() + { + return $this->documentationUrl; + } + + /** + * Set the URL pointing to additional documentation on the command + * + * @param string $docUrl Documentation URL + * + * @return self + */ + public function setDocumentationUrl($docUrl) + { + $this->documentationUrl = $docUrl; + + return $this; + } + + public function getResponseClass() + { + return $this->responseClass; + } + + /** + * Set what is returned from the method. Can be a primitive, class name, or model. For example: 'array', + * 'Guzzle\\Foo\\Baz', or 'MyModelName' (to reference a model by ID). + * + * @param string $responseClass Type of response + * + * @return self + */ + public function setResponseClass($responseClass) + { + $this->responseClass = $responseClass; + $this->inferResponseType(); + + return $this; + } + + public function getResponseType() + { + return $this->responseType; + } + + /** + * Set qualifying information about the responseClass. One of 'primitive', 'class', 'model', or 'documentation' + * + * @param string $responseType Response type information + * + * @return self + * @throws InvalidArgumentException + */ + public function setResponseType($responseType) + { + static $types = array( + self::TYPE_PRIMITIVE => true, + self::TYPE_CLASS => true, + self::TYPE_MODEL => true, + self::TYPE_DOCUMENTATION => true + ); + if (!isset($types[$responseType])) { + throw new InvalidArgumentException('responseType must be one of ' . implode(', ', array_keys($types))); + } + + $this->responseType = $responseType; + + return $this; + } + + public function getResponseNotes() + { + return $this->responseNotes; + } + + /** + * Set notes about the response of the operation + * + * @param string $notes Response notes + * + * @return self + */ + public function setResponseNotes($notes) + { + $this->responseNotes = $notes; + + return $this; + } + + public function getDeprecated() + { + return $this->deprecated; + } + + /** + * Set whether or not the command is deprecated + * + * @param bool $isDeprecated Set to true to mark as deprecated + * + * @return self + */ + public function setDeprecated($isDeprecated) + { + $this->deprecated = $isDeprecated; + + return $this; + } + + public function getUri() + { + return $this->uri; + } + + /** + * Set the URI template of the command + * + * @param string $uri URI template to set + * + * @return self + */ + public function setUri($uri) + { + $this->uri = $uri; + + return $this; + } + + public function getErrorResponses() + { + return $this->errorResponses; + } + + /** + * Add an error to the command + * + * @param string $code HTTP response code + * @param string $reason HTTP response reason phrase or information about the error + * @param string $class Exception class associated with the error + * + * @return self + */ + public function addErrorResponse($code, $reason, $class) + { + $this->errorResponses[] = array('code' => $code, 'reason' => $reason, 'class' => $class); + + return $this; + } + + /** + * Set all of the error responses of the operation + * + * @param array $errorResponses Hash of error name to a hash containing a code, reason, class + * + * @return self + */ + public function setErrorResponses(array $errorResponses) + { + $this->errorResponses = $errorResponses; + + return $this; + } + + public function getData($name) + { + return isset($this->data[$name]) ? $this->data[$name] : null; + } + + /** + * Set a particular data point on the operation + * + * @param string $name Name of the data value + * @param mixed $value Value to set + * + * @return self + */ + public function setData($name, $value) + { + $this->data[$name] = $value; + + return $this; + } + + /** + * Get the additionalParameters of the operation + * + * @return Parameter|null + */ + public function getAdditionalParameters() + { + return $this->additionalParameters; + } + + /** + * Set the additionalParameters of the operation + * + * @param Parameter|null $parameter Parameter to set + * + * @return self + */ + public function setAdditionalParameters($parameter) + { + if ($this->additionalParameters = $parameter) { + $this->additionalParameters->setParent($this); + } + + return $this; + } + + /** + * Infer the response type from the responseClass value + */ + protected function inferResponseType() + { + static $primitives = array('array' => 1, 'boolean' => 1, 'string' => 1, 'integer' => 1, '' => 1); + if (isset($primitives[$this->responseClass])) { + $this->responseType = self::TYPE_PRIMITIVE; + } elseif ($this->description && $this->description->hasModel($this->responseClass)) { + $this->responseType = self::TYPE_MODEL; + } else { + $this->responseType = self::TYPE_CLASS; + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Description/OperationInterface.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Description/OperationInterface.php new file mode 100644 index 0000000..4de41bd --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Description/OperationInterface.php @@ -0,0 +1,159 @@ +getModel($data['$ref'])) { + $data = $model->toArray() + $data; + } + } elseif (isset($data['extends'])) { + // If this parameter extends from another parameter then start with the actual data + // union in the parent's data (e.g. actual supersedes parent) + if ($extends = $description->getModel($data['extends'])) { + $data += $extends->toArray(); + } + } + } + + // Pull configuration data into the parameter + foreach ($data as $key => $value) { + $this->{$key} = $value; + } + + $this->serviceDescription = $description; + $this->required = (bool) $this->required; + $this->data = (array) $this->data; + + if ($this->filters) { + $this->setFilters((array) $this->filters); + } + + if ($this->type == 'object' && $this->additionalProperties === null) { + $this->additionalProperties = true; + } + } + + /** + * Convert the object to an array + * + * @return array + */ + public function toArray() + { + static $checks = array('required', 'description', 'static', 'type', 'format', 'instanceOf', 'location', 'sentAs', + 'pattern', 'minimum', 'maximum', 'minItems', 'maxItems', 'minLength', 'maxLength', 'data', 'enum', + 'filters'); + + $result = array(); + + // Anything that is in the `Items` attribute of an array *must* include it's name if available + if ($this->parent instanceof self && $this->parent->getType() == 'array' && isset($this->name)) { + $result['name'] = $this->name; + } + + foreach ($checks as $c) { + if ($value = $this->{$c}) { + $result[$c] = $value; + } + } + + if ($this->default !== null) { + $result['default'] = $this->default; + } + + if ($this->items !== null) { + $result['items'] = $this->getItems()->toArray(); + } + + if ($this->additionalProperties !== null) { + $result['additionalProperties'] = $this->getAdditionalProperties(); + if ($result['additionalProperties'] instanceof self) { + $result['additionalProperties'] = $result['additionalProperties']->toArray(); + } + } + + if ($this->type == 'object' && $this->properties) { + $result['properties'] = array(); + foreach ($this->getProperties() as $name => $property) { + $result['properties'][$name] = $property->toArray(); + } + } + + return $result; + } + + /** + * Get the default or static value of the command based on a value + * + * @param string $value Value that is currently set + * + * @return mixed Returns the value, a static value if one is present, or a default value + */ + public function getValue($value) + { + if ($this->static || ($this->default !== null && $value === null)) { + return $this->default; + } + + return $value; + } + + /** + * Run a value through the filters OR format attribute associated with the parameter + * + * @param mixed $value Value to filter + * + * @return mixed Returns the filtered value + */ + public function filter($value) + { + // Formats are applied exclusively and supersed filters + if ($this->format) { + return SchemaFormatter::format($this->format, $value); + } + + // Convert Boolean values + if ($this->type == 'boolean' && !is_bool($value)) { + $value = filter_var($value, FILTER_VALIDATE_BOOLEAN); + } + + // Apply filters to the value + if ($this->filters) { + foreach ($this->filters as $filter) { + if (is_array($filter)) { + // Convert complex filters that hold value place holders + foreach ($filter['args'] as &$data) { + if ($data == '@value') { + $data = $value; + } elseif ($data == '@api') { + $data = $this; + } + } + $value = call_user_func_array($filter['method'], $filter['args']); + } else { + $value = call_user_func($filter, $value); + } + } + } + + return $value; + } + + /** + * Get the name of the parameter + * + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * Get the key of the parameter, where sentAs will supersede name if it is set + * + * @return string + */ + public function getWireName() + { + return $this->sentAs ?: $this->name; + } + + /** + * Set the name of the parameter + * + * @param string $name Name to set + * + * @return self + */ + public function setName($name) + { + $this->name = $name; + + return $this; + } + + /** + * Get the type(s) of the parameter + * + * @return string|array + */ + public function getType() + { + return $this->type; + } + + /** + * Set the type(s) of the parameter + * + * @param string|array $type Type of parameter or array of simple types used in a union + * + * @return self + */ + public function setType($type) + { + $this->type = $type; + + return $this; + } + + /** + * Get if the parameter is required + * + * @return bool + */ + public function getRequired() + { + return $this->required; + } + + /** + * Set if the parameter is required + * + * @param bool $isRequired Whether or not the parameter is required + * + * @return self + */ + public function setRequired($isRequired) + { + $this->required = (bool) $isRequired; + + return $this; + } + + /** + * Get the default value of the parameter + * + * @return string|null + */ + public function getDefault() + { + return $this->default; + } + + /** + * Set the default value of the parameter + * + * @param string|null $default Default value to set + * + * @return self + */ + public function setDefault($default) + { + $this->default = $default; + + return $this; + } + + /** + * Get the description of the parameter + * + * @return string|null + */ + public function getDescription() + { + return $this->description; + } + + /** + * Set the description of the parameter + * + * @param string $description Description + * + * @return self + */ + public function setDescription($description) + { + $this->description = $description; + + return $this; + } + + /** + * Get the minimum acceptable value for an integer + * + * @return int|null + */ + public function getMinimum() + { + return $this->minimum; + } + + /** + * Set the minimum acceptable value for an integer + * + * @param int|null $min Minimum + * + * @return self + */ + public function setMinimum($min) + { + $this->minimum = $min; + + return $this; + } + + /** + * Get the maximum acceptable value for an integer + * + * @return int|null + */ + public function getMaximum() + { + return $this->maximum; + } + + /** + * Set the maximum acceptable value for an integer + * + * @param int $max Maximum + * + * @return self + */ + public function setMaximum($max) + { + $this->maximum = $max; + + return $this; + } + + /** + * Get the minimum allowed length of a string value + * + * @return int + */ + public function getMinLength() + { + return $this->minLength; + } + + /** + * Set the minimum allowed length of a string value + * + * @param int|null $min Minimum + * + * @return self + */ + public function setMinLength($min) + { + $this->minLength = $min; + + return $this; + } + + /** + * Get the maximum allowed length of a string value + * + * @return int|null + */ + public function getMaxLength() + { + return $this->maxLength; + } + + /** + * Set the maximum allowed length of a string value + * + * @param int $max Maximum length + * + * @return self + */ + public function setMaxLength($max) + { + $this->maxLength = $max; + + return $this; + } + + /** + * Get the maximum allowed number of items in an array value + * + * @return int|null + */ + public function getMaxItems() + { + return $this->maxItems; + } + + /** + * Set the maximum allowed number of items in an array value + * + * @param int $max Maximum + * + * @return self + */ + public function setMaxItems($max) + { + $this->maxItems = $max; + + return $this; + } + + /** + * Get the minimum allowed number of items in an array value + * + * @return int + */ + public function getMinItems() + { + return $this->minItems; + } + + /** + * Set the minimum allowed number of items in an array value + * + * @param int|null $min Minimum + * + * @return self + */ + public function setMinItems($min) + { + $this->minItems = $min; + + return $this; + } + + /** + * Get the location of the parameter + * + * @return string|null + */ + public function getLocation() + { + return $this->location; + } + + /** + * Set the location of the parameter + * + * @param string|null $location Location of the parameter + * + * @return self + */ + public function setLocation($location) + { + $this->location = $location; + + return $this; + } + + /** + * Get the sentAs attribute of the parameter that used with locations to sentAs an attribute when it is being + * applied to a location. + * + * @return string|null + */ + public function getSentAs() + { + return $this->sentAs; + } + + /** + * Set the sentAs attribute + * + * @param string|null $name Name of the value as it is sent over the wire + * + * @return self + */ + public function setSentAs($name) + { + $this->sentAs = $name; + + return $this; + } + + /** + * Retrieve a known property from the parameter by name or a data property by name. When not specific name value + * is specified, all data properties will be returned. + * + * @param string|null $name Specify a particular property name to retrieve + * + * @return array|mixed|null + */ + public function getData($name = null) + { + if (!$name) { + return $this->data; + } + + if (isset($this->data[$name])) { + return $this->data[$name]; + } elseif (isset($this->{$name})) { + return $this->{$name}; + } + + return null; + } + + /** + * Set the extra data properties of the parameter or set a specific extra property + * + * @param string|array|null $nameOrData The name of a specific extra to set or an array of extras to set + * @param mixed|null $data When setting a specific extra property, specify the data to set for it + * + * @return self + */ + public function setData($nameOrData, $data = null) + { + if (is_array($nameOrData)) { + $this->data = $nameOrData; + } else { + $this->data[$nameOrData] = $data; + } + + return $this; + } + + /** + * Get whether or not the default value can be changed + * + * @return mixed|null + */ + public function getStatic() + { + return $this->static; + } + + /** + * Set to true if the default value cannot be changed + * + * @param bool $static True or false + * + * @return self + */ + public function setStatic($static) + { + $this->static = (bool) $static; + + return $this; + } + + /** + * Get an array of filters used by the parameter + * + * @return array + */ + public function getFilters() + { + return $this->filters ?: array(); + } + + /** + * Set the array of filters used by the parameter + * + * @param array $filters Array of functions to use as filters + * + * @return self + */ + public function setFilters(array $filters) + { + $this->filters = array(); + foreach ($filters as $filter) { + $this->addFilter($filter); + } + + return $this; + } + + /** + * Add a filter to the parameter + * + * @param string|array $filter Method to filter the value through + * + * @return self + * @throws InvalidArgumentException + */ + public function addFilter($filter) + { + if (is_array($filter)) { + if (!isset($filter['method'])) { + throw new InvalidArgumentException('A [method] value must be specified for each complex filter'); + } + } + + if (!$this->filters) { + $this->filters = array($filter); + } else { + $this->filters[] = $filter; + } + + return $this; + } + + /** + * Get the parent object (an {@see OperationInterface} or {@see Parameter} + * + * @return OperationInterface|Parameter|null + */ + public function getParent() + { + return $this->parent; + } + + /** + * Set the parent object of the parameter + * + * @param OperationInterface|Parameter|null $parent Parent container of the parameter + * + * @return self + */ + public function setParent($parent) + { + $this->parent = $parent; + + return $this; + } + + /** + * Get the properties of the parameter + * + * @return array + */ + public function getProperties() + { + if (!$this->propertiesCache) { + $this->propertiesCache = array(); + foreach (array_keys($this->properties) as $name) { + $this->propertiesCache[$name] = $this->getProperty($name); + } + } + + return $this->propertiesCache; + } + + /** + * Get a specific property from the parameter + * + * @param string $name Name of the property to retrieve + * + * @return null|Parameter + */ + public function getProperty($name) + { + if (!isset($this->properties[$name])) { + return null; + } + + if (!($this->properties[$name] instanceof self)) { + $this->properties[$name]['name'] = $name; + $this->properties[$name] = new static($this->properties[$name], $this->serviceDescription); + $this->properties[$name]->setParent($this); + } + + return $this->properties[$name]; + } + + /** + * Remove a property from the parameter + * + * @param string $name Name of the property to remove + * + * @return self + */ + public function removeProperty($name) + { + unset($this->properties[$name]); + $this->propertiesCache = null; + + return $this; + } + + /** + * Add a property to the parameter + * + * @param Parameter $property Properties to set + * + * @return self + */ + public function addProperty(Parameter $property) + { + $this->properties[$property->getName()] = $property; + $property->setParent($this); + $this->propertiesCache = null; + + return $this; + } + + /** + * Get the additionalProperties value of the parameter + * + * @return bool|Parameter|null + */ + public function getAdditionalProperties() + { + if (is_array($this->additionalProperties)) { + $this->additionalProperties = new static($this->additionalProperties, $this->serviceDescription); + $this->additionalProperties->setParent($this); + } + + return $this->additionalProperties; + } + + /** + * Set the additionalProperties value of the parameter + * + * @param bool|Parameter|null $additional Boolean to allow any, an Parameter to specify a schema, or false to disallow + * + * @return self + */ + public function setAdditionalProperties($additional) + { + $this->additionalProperties = $additional; + + return $this; + } + + /** + * Set the items data of the parameter + * + * @param Parameter|null $items Items to set + * + * @return self + */ + public function setItems(Parameter $items = null) + { + if ($this->items = $items) { + $this->items->setParent($this); + } + + return $this; + } + + /** + * Get the item data of the parameter + * + * @return Parameter|null + */ + public function getItems() + { + if (is_array($this->items)) { + $this->items = new static($this->items, $this->serviceDescription); + $this->items->setParent($this); + } + + return $this->items; + } + + /** + * Get the class that the parameter must implement + * + * @return null|string + */ + public function getInstanceOf() + { + return $this->instanceOf; + } + + /** + * Set the class that the parameter must be an instance of + * + * @param string|null $instanceOf Class or interface name + * + * @return self + */ + public function setInstanceOf($instanceOf) + { + $this->instanceOf = $instanceOf; + + return $this; + } + + /** + * Get the enum of strings that are valid for the parameter + * + * @return array|null + */ + public function getEnum() + { + return $this->enum; + } + + /** + * Set the enum of strings that are valid for the parameter + * + * @param array|null $enum Array of strings or null + * + * @return self + */ + public function setEnum(array $enum = null) + { + $this->enum = $enum; + + return $this; + } + + /** + * Get the regex pattern that must match a value when the value is a string + * + * @return string + */ + public function getPattern() + { + return $this->pattern; + } + + /** + * Set the regex pattern that must match a value when the value is a string + * + * @param string $pattern Regex pattern + * + * @return self + */ + public function setPattern($pattern) + { + $this->pattern = $pattern; + + return $this; + } + + /** + * Get the format attribute of the schema + * + * @return string + */ + public function getFormat() + { + return $this->format; + } + + /** + * Set the format attribute of the schema + * + * @param string $format Format to set (e.g. date, date-time, timestamp, time, date-time-http) + * + * @return self + */ + public function setFormat($format) + { + $this->format = $format; + + return $this; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Description/SchemaFormatter.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Description/SchemaFormatter.php new file mode 100644 index 0000000..7f47fc9 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Description/SchemaFormatter.php @@ -0,0 +1,156 @@ +setTimezone(self::getUtcTimeZone())->format($format); + } + + throw new InvalidArgumentException('Date/Time values must be either a string, integer, or DateTime object'); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Description/SchemaValidator.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Description/SchemaValidator.php new file mode 100644 index 0000000..b045422 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Description/SchemaValidator.php @@ -0,0 +1,291 @@ +castIntegerToStringType = $castIntegerToStringType; + } + + public function validate(Parameter $param, &$value) + { + $this->errors = array(); + $this->recursiveProcess($param, $value); + + if (empty($this->errors)) { + return true; + } else { + sort($this->errors); + return false; + } + } + + /** + * Get the errors encountered while validating + * + * @return array + */ + public function getErrors() + { + return $this->errors ?: array(); + } + + /** + * Recursively validate a parameter + * + * @param Parameter $param API parameter being validated + * @param mixed $value Value to validate and validate. The value may change during this validate. + * @param string $path Current validation path (used for error reporting) + * @param int $depth Current depth in the validation validate + * + * @return bool Returns true if valid, or false if invalid + */ + protected function recursiveProcess(Parameter $param, &$value, $path = '', $depth = 0) + { + // Update the value by adding default or static values + $value = $param->getValue($value); + + $required = $param->getRequired(); + // if the value is null and the parameter is not required or is static, then skip any further recursion + if ((null === $value && !$required) || $param->getStatic()) { + return true; + } + + $type = $param->getType(); + // Attempt to limit the number of times is_array is called by tracking if the value is an array + $valueIsArray = is_array($value); + // If a name is set then update the path so that validation messages are more helpful + if ($name = $param->getName()) { + $path .= "[{$name}]"; + } + + if ($type == 'object') { + + // Objects are either associative arrays, ToArrayInterface, or some other object + if ($param->getInstanceOf()) { + $instance = $param->getInstanceOf(); + if (!($value instanceof $instance)) { + $this->errors[] = "{$path} must be an instance of {$instance}"; + return false; + } + } + + // Determine whether or not this "value" has properties and should be traversed + $traverse = $temporaryValue = false; + + // Convert the value to an array + if (!$valueIsArray && $value instanceof ToArrayInterface) { + $value = $value->toArray(); + } + + if ($valueIsArray) { + // Ensure that the array is associative and not numerically indexed + if (isset($value[0])) { + $this->errors[] = "{$path} must be an array of properties. Got a numerically indexed array."; + return false; + } + $traverse = true; + } elseif ($value === null) { + // Attempt to let the contents be built up by default values if possible + $value = array(); + $temporaryValue = $valueIsArray = $traverse = true; + } + + if ($traverse) { + + if ($properties = $param->getProperties()) { + // if properties were found, the validate each property of the value + foreach ($properties as $property) { + $name = $property->getName(); + if (isset($value[$name])) { + $this->recursiveProcess($property, $value[$name], $path, $depth + 1); + } else { + $current = null; + $this->recursiveProcess($property, $current, $path, $depth + 1); + // Only set the value if it was populated with something + if (null !== $current) { + $value[$name] = $current; + } + } + } + } + + $additional = $param->getAdditionalProperties(); + if ($additional !== true) { + // If additional properties were found, then validate each against the additionalProperties attr. + $keys = array_keys($value); + // Determine the keys that were specified that were not listed in the properties of the schema + $diff = array_diff($keys, array_keys($properties)); + if (!empty($diff)) { + // Determine which keys are not in the properties + if ($additional instanceOf Parameter) { + foreach ($diff as $key) { + $this->recursiveProcess($additional, $value[$key], "{$path}[{$key}]", $depth); + } + } else { + // if additionalProperties is set to false and there are additionalProperties in the values, then fail + foreach ($diff as $prop) { + $this->errors[] = sprintf('%s[%s] is not an allowed property', $path, $prop); + } + } + } + } + + // A temporary value will be used to traverse elements that have no corresponding input value. + // This allows nested required parameters with default values to bubble up into the input. + // Here we check if we used a temp value and nothing bubbled up, then we need to remote the value. + if ($temporaryValue && empty($value)) { + $value = null; + $valueIsArray = false; + } + } + + } elseif ($type == 'array' && $valueIsArray && $param->getItems()) { + foreach ($value as $i => &$item) { + // Validate each item in an array against the items attribute of the schema + $this->recursiveProcess($param->getItems(), $item, $path . "[{$i}]", $depth + 1); + } + } + + // If the value is required and the type is not null, then there is an error if the value is not set + if ($required && $value === null && $type != 'null') { + $message = "{$path} is " . ($param->getType() ? ('a required ' . implode(' or ', (array) $param->getType())) : 'required'); + if ($param->getDescription()) { + $message .= ': ' . $param->getDescription(); + } + $this->errors[] = $message; + return false; + } + + // Validate that the type is correct. If the type is string but an integer was passed, the class can be + // instructed to cast the integer to a string to pass validation. This is the default behavior. + if ($type && (!$type = $this->determineType($type, $value))) { + if ($this->castIntegerToStringType && $param->getType() == 'string' && is_integer($value)) { + $value = (string) $value; + } else { + $this->errors[] = "{$path} must be of type " . implode(' or ', (array) $param->getType()); + } + } + + // Perform type specific validation for strings, arrays, and integers + if ($type == 'string') { + + // Strings can have enums which are a list of predefined values + if (($enum = $param->getEnum()) && !in_array($value, $enum)) { + $this->errors[] = "{$path} must be one of " . implode(' or ', array_map(function ($s) { + return '"' . addslashes($s) . '"'; + }, $enum)); + } + // Strings can have a regex pattern that the value must match + if (($pattern = $param->getPattern()) && !preg_match($pattern, $value)) { + $this->errors[] = "{$path} must match the following regular expression: {$pattern}"; + } + + $strLen = null; + if ($min = $param->getMinLength()) { + $strLen = strlen($value); + if ($strLen < $min) { + $this->errors[] = "{$path} length must be greater than or equal to {$min}"; + } + } + if ($max = $param->getMaxLength()) { + if (($strLen ?: strlen($value)) > $max) { + $this->errors[] = "{$path} length must be less than or equal to {$max}"; + } + } + + } elseif ($type == 'array') { + + $size = null; + if ($min = $param->getMinItems()) { + $size = count($value); + if ($size < $min) { + $this->errors[] = "{$path} must contain {$min} or more elements"; + } + } + if ($max = $param->getMaxItems()) { + if (($size ?: count($value)) > $max) { + $this->errors[] = "{$path} must contain {$max} or fewer elements"; + } + } + + } elseif ($type == 'integer' || $type == 'number' || $type == 'numeric') { + if (($min = $param->getMinimum()) && $value < $min) { + $this->errors[] = "{$path} must be greater than or equal to {$min}"; + } + if (($max = $param->getMaximum()) && $value > $max) { + $this->errors[] = "{$path} must be less than or equal to {$max}"; + } + } + + return empty($this->errors); + } + + /** + * From the allowable types, determine the type that the variable matches + * + * @param string $type Parameter type + * @param mixed $value Value to determine the type + * + * @return string|bool Returns the matching type on + */ + protected function determineType($type, $value) + { + foreach ((array) $type as $t) { + if ($t == 'string' && (is_string($value) || (is_object($value) && method_exists($value, '__toString')))) { + return 'string'; + } elseif ($t == 'object' && (is_array($value) || is_object($value))) { + return 'object'; + } elseif ($t == 'array' && is_array($value)) { + return 'array'; + } elseif ($t == 'integer' && is_integer($value)) { + return 'integer'; + } elseif ($t == 'boolean' && is_bool($value)) { + return 'boolean'; + } elseif ($t == 'number' && is_numeric($value)) { + return 'number'; + } elseif ($t == 'numeric' && is_numeric($value)) { + return 'numeric'; + } elseif ($t == 'null' && !$value) { + return 'null'; + } elseif ($t == 'any') { + return 'any'; + } + } + + return false; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Description/ServiceDescription.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Description/ServiceDescription.php new file mode 100644 index 0000000..286e65e --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Description/ServiceDescription.php @@ -0,0 +1,271 @@ +load($config, $options); + } + + /** + * @param array $config Array of configuration data + */ + public function __construct(array $config = array()) + { + $this->fromArray($config); + } + + public function serialize() + { + return json_encode($this->toArray()); + } + + public function unserialize($json) + { + $this->operations = array(); + $this->fromArray(json_decode($json, true)); + } + + public function toArray() + { + $result = array( + 'name' => $this->name, + 'apiVersion' => $this->apiVersion, + 'baseUrl' => $this->baseUrl, + 'description' => $this->description + ) + $this->extraData; + $result['operations'] = array(); + foreach ($this->getOperations() as $name => $operation) { + $result['operations'][$operation->getName() ?: $name] = $operation->toArray(); + } + if (!empty($this->models)) { + $result['models'] = array(); + foreach ($this->models as $id => $model) { + $result['models'][$id] = $model instanceof Parameter ? $model->toArray(): $model; + } + } + + return array_filter($result); + } + + public function getBaseUrl() + { + return $this->baseUrl; + } + + /** + * Set the baseUrl of the description + * + * @param string $baseUrl Base URL of each operation + * + * @return self + */ + public function setBaseUrl($baseUrl) + { + $this->baseUrl = $baseUrl; + + return $this; + } + + public function getOperations() + { + foreach (array_keys($this->operations) as $name) { + $this->getOperation($name); + } + + return $this->operations; + } + + public function hasOperation($name) + { + return isset($this->operations[$name]); + } + + public function getOperation($name) + { + // Lazily retrieve and build operations + if (!isset($this->operations[$name])) { + return null; + } + + if (!($this->operations[$name] instanceof Operation)) { + $this->operations[$name] = new Operation($this->operations[$name], $this); + } + + return $this->operations[$name]; + } + + /** + * Add a operation to the service description + * + * @param OperationInterface $operation Operation to add + * + * @return self + */ + public function addOperation(OperationInterface $operation) + { + $this->operations[$operation->getName()] = $operation->setServiceDescription($this); + + return $this; + } + + public function getModel($id) + { + if (!isset($this->models[$id])) { + return null; + } + + if (!($this->models[$id] instanceof Parameter)) { + $this->models[$id] = new Parameter($this->models[$id] + array('name' => $id), $this); + } + + return $this->models[$id]; + } + + public function getModels() + { + // Ensure all models are converted into parameter objects + foreach (array_keys($this->models) as $id) { + $this->getModel($id); + } + + return $this->models; + } + + public function hasModel($id) + { + return isset($this->models[$id]); + } + + /** + * Add a model to the service description + * + * @param Parameter $model Model to add + * + * @return self + */ + public function addModel(Parameter $model) + { + $this->models[$model->getName()] = $model; + + return $this; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function getName() + { + return $this->name; + } + + public function getDescription() + { + return $this->description; + } + + public function getData($key) + { + return isset($this->extraData[$key]) ? $this->extraData[$key] : null; + } + + public function setData($key, $value) + { + $this->extraData[$key] = $value; + + return $this; + } + + /** + * Initialize the state from an array + * + * @param array $config Configuration data + * @throws InvalidArgumentException + */ + protected function fromArray(array $config) + { + // Keep a list of default keys used in service descriptions that is later used to determine extra data keys + static $defaultKeys = array('name', 'models', 'apiVersion', 'baseUrl', 'description'); + // Pull in the default configuration values + foreach ($defaultKeys as $key) { + if (isset($config[$key])) { + $this->{$key} = $config[$key]; + } + } + + // Account for the Swagger name for Guzzle's baseUrl + if (isset($config['basePath'])) { + $this->baseUrl = $config['basePath']; + } + + // Ensure that the models and operations properties are always arrays + $this->models = (array) $this->models; + $this->operations = (array) $this->operations; + + // We want to add operations differently than adding the other properties + $defaultKeys[] = 'operations'; + + // Create operations for each operation + if (isset($config['operations'])) { + foreach ($config['operations'] as $name => $operation) { + if (!($operation instanceof Operation) && !is_array($operation)) { + throw new InvalidArgumentException('Invalid operation in service description: ' + . gettype($operation)); + } + $this->operations[$name] = $operation; + } + } + + // Get all of the additional properties of the service description and store them in a data array + foreach (array_diff(array_keys($config), $defaultKeys) as $key) { + $this->extraData[$key] = $config[$key]; + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Description/ServiceDescriptionInterface.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Description/ServiceDescriptionInterface.php new file mode 100644 index 0000000..5983e58 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Description/ServiceDescriptionInterface.php @@ -0,0 +1,106 @@ + $op) { + $name = $op['name'] = isset($op['name']) ? $op['name'] : $name; + // Extend other operations + if (!empty($op['extends'])) { + $this->resolveExtension($name, $op, $operations); + } + $op['parameters'] = isset($op['parameters']) ? $op['parameters'] : array(); + $operations[$name] = $op; + } + } + + return new ServiceDescription(array( + 'apiVersion' => isset($config['apiVersion']) ? $config['apiVersion'] : null, + 'baseUrl' => isset($config['baseUrl']) ? $config['baseUrl'] : null, + 'description' => isset($config['description']) ? $config['description'] : null, + 'operations' => $operations, + 'models' => isset($config['models']) ? $config['models'] : null + ) + $config); + } + + /** + * @param string $name Name of the operation + * @param array $op Operation value array + * @param array $operations Currently loaded operations + * @throws DescriptionBuilderException when extending a non-existent operation + */ + protected function resolveExtension($name, array &$op, array &$operations) + { + $resolved = array(); + $original = empty($op['parameters']) ? false: $op['parameters']; + $hasClass = !empty($op['class']); + foreach ((array) $op['extends'] as $extendedCommand) { + if (empty($operations[$extendedCommand])) { + throw new DescriptionBuilderException("{$name} extends missing operation {$extendedCommand}"); + } + $toArray = $operations[$extendedCommand]; + $resolved = empty($resolved) + ? $toArray['parameters'] + : array_merge($resolved, $toArray['parameters']); + + $op = $op + $toArray; + if (!$hasClass && isset($toArray['class'])) { + $op['class'] = $toArray['class']; + } + } + $op['parameters'] = $original ? array_merge($resolved, $original) : $resolved; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Description/ValidatorInterface.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Description/ValidatorInterface.php new file mode 100644 index 0000000..94ca77d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Description/ValidatorInterface.php @@ -0,0 +1,28 @@ +getMessage(), $e->getCode(), $e->getPrevious()); + $ce->setSuccessfulRequests($e->getSuccessfulRequests()); + + $alreadyAddedExceptions = array(); + foreach ($e->getFailedRequests() as $request) { + if ($re = $e->getExceptionForFailedRequest($request)) { + $alreadyAddedExceptions[] = $re; + $ce->addFailedRequestWithException($request, $re); + } else { + $ce->addFailedRequest($request); + } + } + + // Add any exceptions that did not map to a request + if (count($alreadyAddedExceptions) < count($e)) { + foreach ($e as $ex) { + if (!in_array($ex, $alreadyAddedExceptions)) { + $ce->add($ex); + } + } + } + + return $ce; + } + + /** + * Get all of the commands in the transfer + * + * @return array + */ + public function getAllCommands() + { + return array_merge($this->successfulCommands, $this->failedCommands); + } + + /** + * Add to the array of successful commands + * + * @param CommandInterface $command Successful command + * + * @return self + */ + public function addSuccessfulCommand(CommandInterface $command) + { + $this->successfulCommands[] = $command; + + return $this; + } + + /** + * Add to the array of failed commands + * + * @param CommandInterface $command Failed command + * + * @return self + */ + public function addFailedCommand(CommandInterface $command) + { + $this->failedCommands[] = $command; + + return $this; + } + + /** + * Get an array of successful commands + * + * @return array + */ + public function getSuccessfulCommands() + { + return $this->successfulCommands; + } + + /** + * Get an array of failed commands + * + * @return array + */ + public function getFailedCommands() + { + return $this->failedCommands; + } + + /** + * Get the Exception that caused the given $command to fail + * + * @param CommandInterface $command Failed command + * + * @return \Exception|null + */ + public function getExceptionForFailedCommand(CommandInterface $command) + { + return $this->getExceptionForFailedRequest($command->getRequest()); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Exception/DescriptionBuilderException.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Exception/DescriptionBuilderException.php new file mode 100644 index 0000000..1407e56 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Exception/DescriptionBuilderException.php @@ -0,0 +1,7 @@ +invalidCommands = $commands; + parent::__construct( + 'Encountered commands in a batch transfer that use inconsistent clients. The batching ' . + 'strategy you use with a command transfer must divide command batches by client.' + ); + } + + /** + * Get the invalid commands + * + * @return array + */ + public function getCommands() + { + return $this->invalidCommands; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Exception/ResponseClassException.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Exception/ResponseClassException.php new file mode 100644 index 0000000..d59ff21 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Exception/ResponseClassException.php @@ -0,0 +1,9 @@ +errors = $errors; + } + + /** + * Get any validation errors + * + * @return array + */ + public function getErrors() + { + return $this->errors; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/AbstractResourceIteratorFactory.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/AbstractResourceIteratorFactory.php new file mode 100644 index 0000000..21140e7 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/AbstractResourceIteratorFactory.php @@ -0,0 +1,37 @@ +canBuild($command)) { + throw new InvalidArgumentException('Iterator was not found for ' . $command->getName()); + } + + $className = $this->getClassName($command); + + return new $className($command, $options); + } + + public function canBuild(CommandInterface $command) + { + return (bool) $this->getClassName($command); + } + + /** + * Get the name of the class to instantiate for the command + * + * @param CommandInterface $command Command that is associated with the iterator + * + * @return string + */ + abstract protected function getClassName(CommandInterface $command); +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/CompositeResourceIteratorFactory.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/CompositeResourceIteratorFactory.php new file mode 100644 index 0000000..2efc133 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/CompositeResourceIteratorFactory.php @@ -0,0 +1,67 @@ +factories = $factories; + } + + public function build(CommandInterface $command, array $options = array()) + { + if (!($factory = $this->getFactory($command))) { + throw new InvalidArgumentException('Iterator was not found for ' . $command->getName()); + } + + return $factory->build($command, $options); + } + + public function canBuild(CommandInterface $command) + { + return $this->getFactory($command) !== false; + } + + /** + * Add a factory to the composite factory + * + * @param ResourceIteratorFactoryInterface $factory Factory to add + * + * @return self + */ + public function addFactory(ResourceIteratorFactoryInterface $factory) + { + $this->factories[] = $factory; + + return $this; + } + + /** + * Get the factory that matches the command object + * + * @param CommandInterface $command Command retrieving the iterator for + * + * @return ResourceIteratorFactoryInterface|bool + */ + protected function getFactory(CommandInterface $command) + { + foreach ($this->factories as $factory) { + if ($factory->canBuild($command)) { + return $factory; + } + } + + return false; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/MapResourceIteratorFactory.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/MapResourceIteratorFactory.php new file mode 100644 index 0000000..c71ca9d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/MapResourceIteratorFactory.php @@ -0,0 +1,34 @@ +map = $map; + } + + public function getClassName(CommandInterface $command) + { + $className = $command->getName(); + + if (isset($this->map[$className])) { + return $this->map[$className]; + } elseif (isset($this->map['*'])) { + // If a wildcard was added, then always use that + return $this->map['*']; + } + + return null; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/Model.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/Model.php new file mode 100644 index 0000000..2322434 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/Model.php @@ -0,0 +1,64 @@ +data = $data; + $this->structure = $structure; + } + + /** + * Get the structure of the model + * + * @return Parameter + */ + public function getStructure() + { + return $this->structure ?: new Parameter(); + } + + /** + * Provides debug information about the model object + * + * @return string + */ + public function __toString() + { + $output = 'Debug output of '; + if ($this->structure) { + $output .= $this->structure->getName() . ' '; + } + $output .= 'model'; + $output = str_repeat('=', strlen($output)) . "\n" . $output . "\n" . str_repeat('=', strlen($output)) . "\n\n"; + $output .= "Model data\n-----------\n\n"; + $output .= "This data can be retrieved from the model object using the get() method of the model " + . "(e.g. \$model->get(\$key)) or accessing the model like an associative array (e.g. \$model['key']).\n\n"; + $lines = array_slice(explode("\n", trim(print_r($this->toArray(), true))), 2, -1); + $output .= implode("\n", $lines); + + if ($this->structure) { + $output .= "\n\nModel structure\n---------------\n\n"; + $output .= "The following JSON document defines how the model was parsed from an HTTP response into the " + . "associative array structure you see above.\n\n"; + $output .= ' ' . json_encode($this->structure->toArray()) . "\n\n"; + } + + return $output . "\n"; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/ResourceIterator.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/ResourceIterator.php new file mode 100644 index 0000000..e141524 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/ResourceIterator.php @@ -0,0 +1,254 @@ +originalCommand = $command; + + // Parse options from the array of options + $this->data = $data; + $this->limit = array_key_exists('limit', $data) ? $data['limit'] : 0; + $this->pageSize = array_key_exists('page_size', $data) ? $data['page_size'] : false; + } + + /** + * Get all of the resources as an array (Warning: this could issue a large number of requests) + * + * @return array + */ + public function toArray() + { + return iterator_to_array($this, false); + } + + public function setLimit($limit) + { + $this->limit = $limit; + $this->resetState(); + + return $this; + } + + public function setPageSize($pageSize) + { + $this->pageSize = $pageSize; + $this->resetState(); + + return $this; + } + + /** + * Get an option from the iterator + * + * @param string $key Key of the option to retrieve + * + * @return mixed|null Returns NULL if not set or the value if set + */ + public function get($key) + { + return array_key_exists($key, $this->data) ? $this->data[$key] : null; + } + + /** + * Set an option on the iterator + * + * @param string $key Key of the option to set + * @param mixed $value Value to set for the option + * + * @return ResourceIterator + */ + public function set($key, $value) + { + $this->data[$key] = $value; + + return $this; + } + + public function current() + { + return $this->resources ? current($this->resources) : false; + } + + public function key() + { + return max(0, $this->iteratedCount - 1); + } + + public function count() + { + return $this->retrievedCount; + } + + /** + * Get the total number of requests sent + * + * @return int + */ + public function getRequestCount() + { + return $this->requestCount; + } + + /** + * Rewind the Iterator to the first element and send the original command + */ + public function rewind() + { + // Use the original command + $this->command = clone $this->originalCommand; + $this->resetState(); + $this->next(); + } + + public function valid() + { + return !$this->invalid && (!$this->resources || $this->current() || $this->nextToken) + && (!$this->limit || $this->iteratedCount < $this->limit + 1); + } + + public function next() + { + $this->iteratedCount++; + + // Check if a new set of resources needs to be retrieved + $sendRequest = false; + if (!$this->resources) { + $sendRequest = true; + } else { + // iterate over the internal array + $current = next($this->resources); + $sendRequest = $current === false && $this->nextToken && (!$this->limit || $this->iteratedCount < $this->limit + 1); + } + + if ($sendRequest) { + + $this->dispatch('resource_iterator.before_send', array( + 'iterator' => $this, + 'resources' => $this->resources + )); + + // Get a new command object from the original command + $this->command = clone $this->originalCommand; + // Send a request and retrieve the newly loaded resources + $this->resources = $this->sendRequest(); + $this->requestCount++; + + // If no resources were found, then the last request was not needed + // and iteration must stop + if (empty($this->resources)) { + $this->invalid = true; + } else { + // Add to the number of retrieved resources + $this->retrievedCount += count($this->resources); + // Ensure that we rewind to the beginning of the array + reset($this->resources); + } + + $this->dispatch('resource_iterator.after_send', array( + 'iterator' => $this, + 'resources' => $this->resources + )); + } + } + + /** + * Retrieve the NextToken that can be used in other iterators. + * + * @return string Returns a NextToken + */ + public function getNextToken() + { + return $this->nextToken; + } + + /** + * Returns the value that should be specified for the page size for a request that will maintain any hard limits, + * but still honor the specified pageSize if the number of items retrieved + pageSize < hard limit + * + * @return int Returns the page size of the next request. + */ + protected function calculatePageSize() + { + if ($this->limit && $this->iteratedCount + $this->pageSize > $this->limit) { + return 1 + ($this->limit - $this->iteratedCount); + } + + return (int) $this->pageSize; + } + + /** + * Reset the internal state of the iterator without triggering a rewind() + */ + protected function resetState() + { + $this->iteratedCount = 0; + $this->retrievedCount = 0; + $this->nextToken = false; + $this->resources = null; + $this->invalid = false; + } + + /** + * Send a request to retrieve the next page of results. Hook for subclasses to implement. + * + * @return array Returns the newly loaded resources + */ + abstract protected function sendRequest(); +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/ResourceIteratorApplyBatched.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/ResourceIteratorApplyBatched.php new file mode 100644 index 0000000..6aa3615 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/ResourceIteratorApplyBatched.php @@ -0,0 +1,111 @@ +iterator = $iterator; + $this->callback = $callback; + Version::warn(__CLASS__ . ' is deprecated'); + } + + /** + * Apply the callback to the contents of the resource iterator + * + * @param int $perBatch The number of records to group per batch transfer + * + * @return int Returns the number of iterated resources + */ + public function apply($perBatch = 50) + { + $this->iterated = $this->batches = $batches = 0; + $that = $this; + $it = $this->iterator; + $callback = $this->callback; + + $batch = BatchBuilder::factory() + ->createBatchesWith(new BatchSizeDivisor($perBatch)) + ->transferWith(new BatchClosureTransfer(function (array $batch) use ($that, $callback, &$batches, $it) { + $batches++; + $that->dispatch('iterator_batch.before_batch', array('iterator' => $it, 'batch' => $batch)); + call_user_func_array($callback, array($it, $batch)); + $that->dispatch('iterator_batch.after_batch', array('iterator' => $it, 'batch' => $batch)); + })) + ->autoFlushAt($perBatch) + ->build(); + + $this->dispatch('iterator_batch.created_batch', array('batch' => $batch)); + + foreach ($this->iterator as $resource) { + $this->iterated++; + $batch->add($resource); + } + + $batch->flush(); + $this->batches = $batches; + + return $this->iterated; + } + + /** + * Get the total number of batches sent + * + * @return int + */ + public function getBatchCount() + { + return $this->batches; + } + + /** + * Get the total number of iterated resources + * + * @return int + */ + public function getIteratedCount() + { + return $this->iterated; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/ResourceIteratorClassFactory.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/ResourceIteratorClassFactory.php new file mode 100644 index 0000000..2fd9980 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/ResourceIteratorClassFactory.php @@ -0,0 +1,60 @@ + AbcFoo). + */ +class ResourceIteratorClassFactory extends AbstractResourceIteratorFactory +{ + /** @var array List of namespaces used to look for classes */ + protected $namespaces; + + /** @var InflectorInterface Inflector used to determine class names */ + protected $inflector; + + /** + * @param string|array $namespaces List of namespaces for iterator objects + * @param InflectorInterface $inflector Inflector used to resolve class names + */ + public function __construct($namespaces = array(), InflectorInterface $inflector = null) + { + $this->namespaces = (array) $namespaces; + $this->inflector = $inflector ?: Inflector::getDefault(); + } + + /** + * Registers a namespace to check for Iterators + * + * @param string $namespace Namespace which contains Iterator classes + * + * @return self + */ + public function registerNamespace($namespace) + { + array_unshift($this->namespaces, $namespace); + + return $this; + } + + protected function getClassName(CommandInterface $command) + { + $iteratorName = $this->inflector->camel($command->getName()) . 'Iterator'; + + // Determine the name of the class to load + foreach ($this->namespaces as $namespace) { + $potentialClassName = $namespace . '\\' . $iteratorName; + if (class_exists($potentialClassName)) { + return $potentialClassName; + } + } + + return false; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/ResourceIteratorFactoryInterface.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/ResourceIteratorFactoryInterface.php new file mode 100644 index 0000000..8b4e8db --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/ResourceIteratorFactoryInterface.php @@ -0,0 +1,30 @@ +=5.3.2", + "guzzle/cache": "self.version", + "guzzle/http": "self.version", + "guzzle/inflection": "self.version" + }, + "autoload": { + "psr-0": { "Guzzle\\Service": "" } + }, + "target-dir": "Guzzle/Service", + "extra": { + "branch-alias": { + "dev-master": "3.7-dev" + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Stream/PhpStreamRequestFactory.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Stream/PhpStreamRequestFactory.php new file mode 100644 index 0000000..d115fd8 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Stream/PhpStreamRequestFactory.php @@ -0,0 +1,284 @@ +contextOptions = stream_context_get_options($context); + $this->context = $context; + } elseif (is_array($context) || !$context) { + $this->contextOptions = $context; + $this->createContext($params); + } elseif ($context) { + throw new InvalidArgumentException('$context must be an array or resource'); + } + + // Dispatch the before send event + $request->dispatch('request.before_send', array( + 'request' => $request, + 'context' => $this->context, + 'context_options' => $this->contextOptions + )); + + $this->setUrl($request); + $this->addDefaultContextOptions($request); + $this->addSslOptions($request); + $this->addBodyOptions($request); + $this->addProxyOptions($request); + + // Create the file handle but silence errors + return $this->createStream($params) + ->setCustomData('request', $request) + ->setCustomData('response_headers', $this->getLastResponseHeaders()); + } + + /** + * Set an option on the context and the internal options array + * + * @param string $wrapper Stream wrapper name of http + * @param string $name Context name + * @param mixed $value Context value + * @param bool $overwrite Set to true to overwrite an existing value + */ + protected function setContextValue($wrapper, $name, $value, $overwrite = false) + { + if (!isset($this->contextOptions[$wrapper])) { + $this->contextOptions[$wrapper] = array($name => $value); + } elseif (!$overwrite && isset($this->contextOptions[$wrapper][$name])) { + return; + } + $this->contextOptions[$wrapper][$name] = $value; + stream_context_set_option($this->context, $wrapper, $name, $value); + } + + /** + * Create a stream context + * + * @param array $params Parameter array + */ + protected function createContext(array $params) + { + $options = $this->contextOptions; + $this->context = $this->createResource(function () use ($params, $options) { + return stream_context_create($options, $params); + }); + } + + /** + * Get the last response headers received by the HTTP request + * + * @return array + */ + public function getLastResponseHeaders() + { + return $this->lastResponseHeaders; + } + + /** + * Adds the default context options to the stream context options + * + * @param RequestInterface $request Request + */ + protected function addDefaultContextOptions(RequestInterface $request) + { + $this->setContextValue('http', 'method', $request->getMethod()); + $headers = $request->getHeaderLines(); + + // "Connection: close" is required to get streams to work in HTTP 1.1 + if (!$request->hasHeader('Connection')) { + $headers[] = 'Connection: close'; + } + + $this->setContextValue('http', 'header', $headers); + $this->setContextValue('http', 'protocol_version', $request->getProtocolVersion()); + $this->setContextValue('http', 'ignore_errors', true); + } + + /** + * Set the URL to use with the factory + * + * @param RequestInterface $request Request that owns the URL + */ + protected function setUrl(RequestInterface $request) + { + $this->url = $request->getUrl(true); + + // Check for basic Auth username + if ($request->getUsername()) { + $this->url->setUsername($request->getUsername()); + } + + // Check for basic Auth password + if ($request->getPassword()) { + $this->url->setPassword($request->getPassword()); + } + } + + /** + * Add SSL options to the stream context + * + * @param RequestInterface $request Request + */ + protected function addSslOptions(RequestInterface $request) + { + if ($request->getCurlOptions()->get(CURLOPT_SSL_VERIFYPEER)) { + $this->setContextValue('ssl', 'verify_peer', true, true); + if ($cafile = $request->getCurlOptions()->get(CURLOPT_CAINFO)) { + $this->setContextValue('ssl', 'cafile', $cafile, true); + } + } else { + $this->setContextValue('ssl', 'verify_peer', false, true); + } + } + + /** + * Add body (content) specific options to the context options + * + * @param RequestInterface $request + */ + protected function addBodyOptions(RequestInterface $request) + { + // Add the content for the request if needed + if (!($request instanceof EntityEnclosingRequestInterface)) { + return; + } + + if (count($request->getPostFields())) { + $this->setContextValue('http', 'content', (string) $request->getPostFields(), true); + } elseif ($request->getBody()) { + $this->setContextValue('http', 'content', (string) $request->getBody(), true); + } + + // Always ensure a content-length header is sent + if (isset($this->contextOptions['http']['content'])) { + $headers = isset($this->contextOptions['http']['header']) ? $this->contextOptions['http']['header'] : array(); + $headers[] = 'Content-Length: ' . strlen($this->contextOptions['http']['content']); + $this->setContextValue('http', 'header', $headers, true); + } + } + + /** + * Add proxy parameters to the context if needed + * + * @param RequestInterface $request Request + */ + protected function addProxyOptions(RequestInterface $request) + { + if ($proxy = $request->getCurlOptions()->get(CURLOPT_PROXY)) { + $this->setContextValue('http', 'proxy', $proxy); + } + } + + /** + * Create the stream for the request with the context options + * + * @param array $params Parameters of the stream + * + * @return StreamInterface + */ + protected function createStream(array $params) + { + $http_response_header = null; + $url = $this->url; + $context = $this->context; + $fp = $this->createResource(function () use ($context, $url, &$http_response_header) { + return fopen((string) $url, 'r', false, $context); + }); + + // Determine the class to instantiate + $className = isset($params['stream_class']) ? $params['stream_class'] : __NAMESPACE__ . '\\Stream'; + + /** @var $stream StreamInterface */ + $stream = new $className($fp); + + // Track the response headers of the request + if (isset($http_response_header)) { + $this->lastResponseHeaders = $http_response_header; + $this->processResponseHeaders($stream); + } + + return $stream; + } + + /** + * Process response headers + * + * @param StreamInterface $stream + */ + protected function processResponseHeaders(StreamInterface $stream) + { + // Set the size on the stream if it was returned in the response + foreach ($this->lastResponseHeaders as $header) { + if ((stripos($header, 'Content-Length:')) === 0) { + $stream->setSize(trim(substr($header, 15))); + } + } + } + + /** + * Create a resource and check to ensure it was created successfully + * + * @param callable $callback Closure to invoke that must return a valid resource + * + * @return resource + * @throws RuntimeException on error + */ + protected function createResource($callback) + { + $errors = null; + set_error_handler(function ($_, $msg, $file, $line) use (&$errors) { + $errors[] = array( + 'message' => $msg, + 'file' => $file, + 'line' => $line + ); + return true; + }); + $resource = call_user_func($callback); + restore_error_handler(); + + if (!$resource) { + $message = 'Error creating resource. '; + foreach ($errors as $err) { + foreach ($err as $key => $value) { + $message .= "[$key] $value" . PHP_EOL; + } + } + throw new RuntimeException(trim($message)); + } + + return $resource; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Stream/Stream.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Stream/Stream.php new file mode 100644 index 0000000..12bed26 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Stream/Stream.php @@ -0,0 +1,289 @@ + array( + 'r' => true, 'w+' => true, 'r+' => true, 'x+' => true, 'c+' => true, + 'rb' => true, 'w+b' => true, 'r+b' => true, 'x+b' => true, 'c+b' => true, + 'rt' => true, 'w+t' => true, 'r+t' => true, 'x+t' => true, 'c+t' => true, 'a+' => true + ), + 'write' => array( + 'w' => true, 'w+' => true, 'rw' => true, 'r+' => true, 'x+' => true, 'c+' => true, + 'wb' => true, 'w+b' => true, 'r+b' => true, 'x+b' => true, 'c+b' => true, + 'w+t' => true, 'r+t' => true, 'x+t' => true, 'c+t' => true, 'a' => true, 'a+' => true + ) + ); + + /** + * @param resource $stream Stream resource to wrap + * @param int $size Size of the stream in bytes. Only pass if the size cannot be obtained from the stream. + * + * @throws InvalidArgumentException if the stream is not a stream resource + */ + public function __construct($stream, $size = null) + { + $this->setStream($stream, $size); + } + + /** + * Closes the stream when the helper is destructed + */ + public function __destruct() + { + $this->close(); + } + + public function __toString() + { + if (!$this->isReadable() || (!$this->isSeekable() && $this->isConsumed())) { + return ''; + } + + $originalPos = $this->ftell(); + $body = stream_get_contents($this->stream, -1, 0); + $this->seek($originalPos); + + return $body; + } + + public function close() + { + if (is_resource($this->stream)) { + fclose($this->stream); + } + $this->cache[self::IS_READABLE] = false; + $this->cache[self::IS_WRITABLE] = false; + } + + /** + * Calculate a hash of a Stream + * + * @param StreamInterface $stream Stream to calculate the hash for + * @param string $algo Hash algorithm (e.g. md5, crc32, etc) + * @param bool $rawOutput Whether or not to use raw output + * + * @return bool|string Returns false on failure or a hash string on success + */ + public static function getHash(StreamInterface $stream, $algo, $rawOutput = false) + { + $pos = $stream->ftell(); + if (!$stream->seek(0)) { + return false; + } + + $ctx = hash_init($algo); + while (!$stream->feof()) { + hash_update($ctx, $stream->read(8192)); + } + + $out = hash_final($ctx, (bool) $rawOutput); + $stream->seek($pos); + + return $out; + } + + public function getMetaData($key = null) + { + $meta = stream_get_meta_data($this->stream); + + return !$key ? $meta : (array_key_exists($key, $meta) ? $meta[$key] : null); + } + + public function getStream() + { + return $this->stream; + } + + public function setStream($stream, $size = null) + { + if (!is_resource($stream)) { + throw new InvalidArgumentException('Stream must be a resource'); + } + + $this->size = $size; + $this->stream = $stream; + $this->rebuildCache(); + + return $this; + } + + public function detachStream() + { + $this->stream = null; + + return $this; + } + + public function getWrapper() + { + return $this->cache[self::WRAPPER_TYPE]; + } + + public function getWrapperData() + { + return $this->getMetaData('wrapper_data') ?: array(); + } + + public function getStreamType() + { + return $this->cache[self::STREAM_TYPE]; + } + + public function getUri() + { + return $this->cache['uri']; + } + + public function getSize() + { + if ($this->size !== null) { + return $this->size; + } + + // If the stream is a file based stream and local, then use fstat + clearstatcache(true, $this->cache['uri']); + $stats = fstat($this->stream); + if (isset($stats['size'])) { + $this->size = $stats['size']; + return $this->size; + } elseif ($this->cache[self::IS_READABLE] && $this->cache[self::SEEKABLE]) { + // Only get the size based on the content if the the stream is readable and seekable + $pos = $this->ftell(); + $this->size = strlen((string) $this); + $this->seek($pos); + return $this->size; + } + + return false; + } + + public function isReadable() + { + return $this->cache[self::IS_READABLE]; + } + + public function isRepeatable() + { + return $this->cache[self::IS_READABLE] && $this->cache[self::SEEKABLE]; + } + + public function isWritable() + { + return $this->cache[self::IS_WRITABLE]; + } + + public function isConsumed() + { + return feof($this->stream); + } + + public function feof() + { + return $this->isConsumed(); + } + + public function isLocal() + { + return $this->cache[self::IS_LOCAL]; + } + + public function isSeekable() + { + return $this->cache[self::SEEKABLE]; + } + + public function setSize($size) + { + $this->size = $size; + + return $this; + } + + public function seek($offset, $whence = SEEK_SET) + { + return $this->cache[self::SEEKABLE] ? fseek($this->stream, $offset, $whence) === 0 : false; + } + + public function read($length) + { + return fread($this->stream, $length); + } + + public function write($string) + { + // We can't know the size after writing anything + $this->size = null; + + return fwrite($this->stream, $string); + } + + public function ftell() + { + return ftell($this->stream); + } + + public function rewind() + { + return $this->seek(0); + } + + public function readLine($maxLength = null) + { + if (!$this->cache[self::IS_READABLE]) { + return false; + } else { + return $maxLength ? fgets($this->getStream(), $maxLength) : fgets($this->getStream()); + } + } + + public function setCustomData($key, $value) + { + $this->customData[$key] = $value; + + return $this; + } + + public function getCustomData($key) + { + return isset($this->customData[$key]) ? $this->customData[$key] : null; + } + + /** + * Reprocess stream metadata + */ + protected function rebuildCache() + { + $this->cache = stream_get_meta_data($this->stream); + $this->cache[self::IS_LOCAL] = stream_is_local($this->stream); + $this->cache[self::IS_READABLE] = isset(self::$readWriteHash['read'][$this->cache['mode']]); + $this->cache[self::IS_WRITABLE] = isset(self::$readWriteHash['write'][$this->cache['mode']]); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Stream/StreamInterface.php b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Stream/StreamInterface.php new file mode 100644 index 0000000..6d7dc37 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/guzzle/guzzle/src/Guzzle/Stream/StreamInterface.php @@ -0,0 +1,218 @@ +=5.3.2", + "guzzle/common": "self.version" + }, + "suggest": { + "guzzle/http": "To convert Guzzle request objects to PHP streams" + }, + "autoload": { + "psr-0": { "Guzzle\\Stream": "" } + }, + "target-dir": "Guzzle/Stream", + "extra": { + "branch-alias": { + "dev-master": "3.7-dev" + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/league/flysystem-aws-s3-v2/src/AwsS3Adapter.php b/lib/ckfinder/core/connector/php/vendor/league/flysystem-aws-s3-v2/src/AwsS3Adapter.php new file mode 100644 index 0000000..0b77507 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/league/flysystem-aws-s3-v2/src/AwsS3Adapter.php @@ -0,0 +1,619 @@ + 'raw_contents', + 'ContentLength' => 'size', + 'ContentType' => 'mimetype', + 'Size' => 'size', + 'StorageClass' => 'storage_class', + ]; + + /** + * @var array + */ + protected static $metaOptions = [ + 'CacheControl', + 'Expires', + 'StorageClass', + 'ServerSideEncryption', + 'Metadata', + 'ACL', + 'ContentType', + 'ContentDisposition', + 'ContentLanguage', + 'ContentEncoding', + ]; + + /** + * @var string bucket name + */ + protected $bucket; + + /** + * @var S3Client S3 Client + */ + protected $client; + + /** + * @var array default options[ + * Multipart=1024 Mb - After what size should multipart be used + * MinPartSize=32 Mb - Minimum size of parts for each part + * Concurrency=3 - If multipart is used, how many concurrent connections should be used + * ] + */ + protected $options = [ + 'Multipart' => 1024, + 'MinPartSize' => 32, + 'Concurrency' => 3, + ]; + + /** + * @var UploadBuilder Used to upload object using a multipart transfer + */ + protected $uploadBuilder; + + /** + * Constructor. + * + * @param S3Client $client + * @param string $bucket + * @param string $prefix + * @param array $options + * @param UploadBuilder $uploadBuilder + */ + public function __construct( + S3Client $client, + $bucket, + $prefix = null, + array $options = [], + UploadBuilder $uploadBuilder = null + ) { + $this->client = $client; + $this->bucket = $bucket; + $this->setPathPrefix($prefix); + $this->options = array_merge($this->options, $options); + $this->setUploadBuilder($uploadBuilder); + } + + /** + * Get the S3Client bucket. + * + * @return string + */ + public function getBucket() + { + return $this->bucket; + } + + /** + * Get the S3Client instance. + * + * @return S3Client + */ + public function getClient() + { + return $this->client; + } + + /** + * {@inheritdoc} + */ + public function has($path) + { + $location = $this->applyPathPrefix($path); + + return $this->client->doesObjectExist($this->bucket, $location); + } + + /** + * {@inheritdoc} + */ + public function write($path, $contents, Config $config) + { + $options = $this->getOptions( + $path, + [ + 'Body' => $contents, + 'ContentType' => Util::guessMimeType($path, $contents), + 'ContentLength' => Util::contentSize($contents), + ], + $config + ); + + return $this->writeObject($options); + } + + /** + * {@inheritdoc} + */ + public function writeStream($path, $resource, Config $config) + { + $options = ['Body' => $resource]; + $options['ContentLength'] = Util::getStreamSize($resource); + $options = $this->getOptions($path, $options, $config); + + return $this->writeObject($options); + } + + /** + * Write an object to S3. + * + * @param array $options + * + * @return array file metadata + */ + protected function writeObject(array $options) + { + $multipartLimit = $this->mbToBytes($options['Multipart']); + + // If we don't know the stream size, we have to assume we need to upload using multipart, otherwise it might fail. + if ($options['ContentLength'] > $multipartLimit) { + $result = $this->putObjectMultipart($options); + } else { + $result = $this->client->putObject($options); + } + + if ($result === false) { + return false; + } + + if (! is_string($options['Body'])) { + unset($options['Body']); + } + + return $this->normalizeResponse($options); + } + + /** + * {@inheritdoc} + */ + public function update($path, $contents, Config $config) + { + if (! $config->has('visibility') && ! $config->has('ACL')) { + $config->set('ACL', $this->getObjectACL($path)); + } + + return $this->write($path, $contents, $config); + } + + /** + * {@inheritdoc} + */ + public function updateStream($path, $resource, Config $config) + { + if (! $config->has('visibility') && ! $config->has('ACL')) { + $config->set('ACL', $this->getObjectACL($path)); + } + + return $this->writeStream($path, $resource, $config); + } + + /** + * {@inheritdoc} + */ + public function read($path) + { + $result = $this->readObject($path); + $result['contents'] = (string) $result['raw_contents']; + unset($result['raw_contents']); + + return $result; + } + + /** + * {@inheritdoc} + */ + public function readStream($path) + { + $result = $this->readObject($path); + $result['stream'] = $result['raw_contents']->getStream(); + rewind($result['stream']); + // Ensure the EntityBody object destruction doesn't close the stream + $result['raw_contents']->detachStream(); + unset($result['raw_contents']); + + return $result; + } + + /** + * Read an object from the S3Client. + * + * @param string $path + * + * @return array + */ + protected function readObject($path) + { + $options = $this->getOptions($path); + $result = $this->client->getObject($options); + + return $this->normalizeResponse($result->getAll(), $path); + } + + /** + * {@inheritdoc} + */ + public function rename($path, $newpath) + { + $this->copy($path, $newpath); + $this->delete($path); + + return true; + } + + /** + * {@inheritdoc} + */ + public function copy($path, $newpath) + { + $options = $this->getOptions($newpath, [ + 'Bucket' => $this->bucket, + 'CopySource' => urlencode($this->bucket.'/'.$this->applyPathPrefix($path)), + 'ACL' => $this->getObjectACL($path), + 'StorageClass' => $this->getStorageClass($path), + ]); + + $this->client->copyObject($options); + + return true; + } + + /** + * {@inheritdoc} + */ + public function delete($path) + { + $options = $this->getOptions($path); + $this->client->deleteObject($options); + + return ! $this->has($path); + } + + /** + * {@inheritdoc} + */ + public function deleteDir($path) + { + $prefix = rtrim($this->applyPathPrefix($path), '/').'/'; + + return (bool) $this->client->deleteMatchingObjects($this->bucket, $prefix); + } + + /** + * {@inheritdoc} + */ + public function createDir($path, Config $config) + { + $result = $this->write(rtrim($path, '/').'/', '', $config); + + if (! $result) { + return false; + } + + return ['path' => $path, 'type' => 'dir']; + } + + /** + * {@inheritdoc} + */ + public function getMetadata($path) + { + $options = $this->getOptions($path); + $result = $this->client->headObject($options); + + return $this->normalizeResponse($result->getAll(), $path); + } + + /** + * {@inheritdoc} + */ + public function getMimetype($path) + { + return $this->getMetadata($path); + } + + /** + * {@inheritdoc} + */ + public function getSize($path) + { + return $this->getMetadata($path); + } + + /** + * {@inheritdoc} + */ + public function getTimestamp($path) + { + return $this->getMetadata($path); + } + + /** + * {@inheritdoc} + */ + public function getVisibility($path) + { + $options = $this->getOptions($path); + $result = $this->client->getObjectAcl($options)->getAll(); + $visibility = AdapterInterface::VISIBILITY_PRIVATE; + + foreach ($result['Grants'] as $grant) { + if (isset($grant['Grantee']['URI']) && $grant['Grantee']['URI'] === Group::ALL_USERS && $grant['Permission'] === Permission::READ) { + $visibility = AdapterInterface::VISIBILITY_PUBLIC; + break; + } + } + + return compact('visibility'); + } + + /** + * The the ACL visibility. + * + * @param string $path + * + * @return string + */ + protected function getObjectACL($path) + { + $metadata = $this->getVisibility($path); + + return $metadata['visibility'] === AdapterInterface::VISIBILITY_PUBLIC ? 'public-read' : 'private'; + } + + /** + * Return an object's storage class. + * + * @param $path + * @return string + */ + public function getStorageClass($path) + { + $metadata = $this->getMetadata($path); + + return !empty($metadata['storage_class']) ? $metadata['storage_class'] : StorageClass::STANDARD; + } + + /** + * {@inheritdoc} + */ + public function setVisibility($path, $visibility) + { + $options = $this->getOptions($path, [ + 'ACL' => $visibility === AdapterInterface::VISIBILITY_PUBLIC ? 'public-read' : 'private', + ]); + + $this->client->putObjectAcl($options); + + return compact('visibility'); + } + + /** + * {@inheritdoc} + */ + public function listContents($dirname = '', $recursive = false) + { + $dirname = rtrim($dirname, '/') . '/'; + + $commandOptions = [ + 'Bucket' => $this->bucket, + 'Prefix' => $this->applyPathPrefix($dirname) + ]; + + $iteratorOptions = []; + + if (!$recursive) { + $commandOptions['Delimiter'] = '/'; + $iteratorOptions['return_prefixes'] = true; + } + + $objectsIterator = $this->client->getIterator('listObjects', $commandOptions, $iteratorOptions); + + $contents = iterator_to_array($objectsIterator); + $result = array_map([$this, 'normalizeResponse'], $contents); + $result = array_filter($result, function ($value) { + return $value['path'] !== false; + }); + + return Util::emulateDirectories($result); + } + + /** + * Normalize a result from AWS. + * + * @param array $object + * @param string $path + * + * @return array file metadata + */ + protected function normalizeResponse(array $object, $path = null) + { + $result = ['path' => $path ?: $this->removePathPrefix(isset($object['Key']) ? $object['Key'] : $object['Prefix'])]; + $result['dirname'] = Util::dirname($result['path']); + + if (isset($object['LastModified'])) { + $result['timestamp'] = strtotime($object['LastModified']); + } + + if (substr($result['path'], -1) === '/') { + $result['type'] = 'dir'; + $result['path'] = rtrim($result['path'], '/'); + + return $result; + } + + $result = array_merge($result, Util::map($object, static::$resultMap), ['type' => 'file']); + + return $result; + } + + /** + * Get options for a AWS call. + * + * @param string $path + * @param array $options + * @param Config $config + * + * @return array AWS options + */ + protected function getOptions($path, array $options = [], Config $config = null) + { + $options = array_merge($this->options, $options); + $options['Key'] = $this->applyPathPrefix($path); + $options['Bucket'] = $this->bucket; + + if ($config) { + $options = array_merge($options, $this->getOptionsFromConfig($config)); + } + + return $options; + } + + /** + * Retrieve options from a Config instance. + * + * @param Config $config + * + * @return array + */ + protected function getOptionsFromConfig(Config $config) + { + $options = []; + + foreach (static::$metaOptions as $option) { + if (! $config->has($option)) { + continue; + } + $options[$option] = $config->get($option); + } + + if ($visibility = $config->get('visibility')) { + // For local reference + $options['visibility'] = $visibility; + // For external reference + $options['ACL'] = $visibility === AdapterInterface::VISIBILITY_PUBLIC ? 'public-read' : 'private'; + } + + if ($mimetype = $config->get('mimetype')) { + // For local reference + $options['mimetype'] = $mimetype; + // For external reference + $options['ContentType'] = $mimetype; + } + + return $options; + } + + /** + * Sends an object to a bucket using a multipart transfer, possibly also using concurrency. + * + * @param array $options Can have: [Body, Bucket, Key, MinPartSize, Concurrency, ContentType, ACL, Metadata] + * + * @return bool + */ + protected function putObjectMultipart(array $options) + { + // Prepare the upload parameters. + /** @var UploadBuilder $uploadBuilder */ + $uploadBuilder = $this->getUploadBuilder(); + + $uploadBuilder->setBucket($options['Bucket']) + // This options are always set in the $options array, so we don't need to check for them + ->setKey($options['Key']) + ->setMinPartSize($options['MinPartSize']) + ->setConcurrency($options['Concurrency']) + ->setSource($options['Body']) // these 2 methods must be the last to be called because they return + ->setClient($this->client); // AbstractUploadBuilder, which makes IDE and CI complain. + + foreach (static::$metaOptions as $option) { + if (! array_key_exists($option, $options)) { + continue; + } + $uploadBuilder->setOption($option, $options[$option]); + } + + $uploader = $uploadBuilder->build(); + + return $this->upload($uploader); + } + + /** + * Perform the upload. Abort the upload if something goes wrong. + * + * @param AbstractTransfer $uploader + * + * @return bool + */ + protected function upload(AbstractTransfer $uploader) + { + try { + $uploader->upload(); + } catch (MultipartUploadException $e) { + $uploader->abort(); + + return false; + } + + return true; + } + + /** + * Convert megabytes to bytes. + * + * @param int $megabytes + * + * @return int + */ + protected function mbToBytes($megabytes) + { + return $megabytes * 1024 * 1024; + } + + /** + * Set the S3 UploadBuilder. + * + * @param UploadBuilder $uploadBuilder + * + * @return $this + */ + public function setUploadBuilder(UploadBuilder $uploadBuilder = null) + { + $this->uploadBuilder = $uploadBuilder; + + return $this; + } + + /** + * Get the S3 UploadBuilder. + * + * @return UploadBuilder + */ + public function getUploadBuilder() + { + if (! $this->uploadBuilder) { + $this->uploadBuilder = UploadBuilder::newInstance(); + } + + return $this->uploadBuilder; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/league/flysystem-azure/src/Adapter.php b/lib/ckfinder/core/connector/php/vendor/league/flysystem-azure/src/Adapter.php new file mode 100644 index 0000000..a3bdd5c --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/league/flysystem-azure/src/Adapter.php @@ -0,0 +1,11 @@ +client = $azureClient; + $this->container = $container; + $this->setPathPrefix($prefix); + } + + /** + * @inheritdoc + */ + public function write($path, $contents, Config $config) + { + return $this->upload($path, $contents, $config); + } + + /** + * @inheritdoc + */ + public function writeStream($path, $resource, Config $config) + { + return $this->upload($path, $resource, $config); + } + + /** + * @inheritdoc + */ + public function update($path, $contents, Config $config) + { + return $this->upload($path, $contents, $config); + } + + /** + * @inheritdoc + */ + public function updateStream($path, $resource, Config $config) + { + return $this->upload($path, $resource, $config); + } + + /** + * @inheritdoc + */ + public function rename($path, $newpath) + { + $this->copy($path, $newpath); + + return $this->delete($path); + } + + public function copy($path, $newpath) + { + $path = $this->applyPathPrefix($path); + $newpath = $this->applyPathPrefix($newpath); + + $this->client->copyBlob($this->container, $newpath, $this->container, $path); + + return true; + } + + /** + * @inheritdoc + */ + public function delete($path) + { + $path = $this->applyPathPrefix($path); + + $this->client->deleteBlob($this->container, $path); + + return true; + } + + /** + * @inheritdoc + */ + public function deleteDir($dirname) + { + $dirname = $this->applyPathPrefix($dirname); + + $options = new ListBlobsOptions(); + $options->setPrefix($dirname . '/'); + + /** @var ListBlobsResult $listResults */ + $listResults = $this->client->listBlobs($this->container, $options); + + foreach ($listResults->getBlobs() as $blob) { + /** @var \WindowsAzure\Blob\Models\Blob $blob */ + $this->client->deleteBlob($this->container, $blob->getName()); + } + + return true; + } + + /** + * @inheritdoc + */ + public function createDir($dirname, Config $config) + { + $this->write(rtrim($dirname, '/') . '/', ' ', $config); + + return ['path' => $dirname, 'type' => 'dir']; + } + + /** + * @inheritdoc + */ + public function has($path) + { + $path = $this->applyPathPrefix($path); + + try { + $this->client->getBlobMetadata($this->container, $path); + } catch (ServiceException $e) { + if ($e->getCode() !== 404) { + throw $e; + } + + return false; + } + + return true; + } + + /** + * @inheritdoc + */ + public function read($path) + { + $path = $this->applyPathPrefix($path); + + /** @var \WindowsAzure\Blob\Models\GetBlobResult $blobResult */ + $blobResult = $this->client->getBlob($this->container, $path); + $properties = $blobResult->getProperties(); + $content = $this->streamContentsToString($blobResult->getContentStream()); + + return $this->normalizeBlobProperties($path, $properties) + ['contents' => $content]; + } + + /** + * @inheritdoc + */ + public function readStream($path) + { + $path = $this->applyPathPrefix($path); + + /** @var \WindowsAzure\Blob\Models\GetBlobResult $blobResult */ + $blobResult = $this->client->getBlob($this->container, $path); + $properties = $blobResult->getProperties(); + + return $this->normalizeBlobProperties($path, $properties) + ['stream' => $blobResult->getContentStream()]; + } + + /** + * @inheritdoc + */ + public function listContents($directory = '', $recursive = false) + { + $directory = $this->applyPathPrefix($directory); + + // Append trailing slash only for directory other than root (which after normalization is an empty string). + // Listing for / doesn't work properly otherwise. + if (strlen($directory)) { + $directory = rtrim($directory, '/') . '/'; + } + + $options = new ListBlobsOptions(); + $options->setPrefix($directory); + + if (!$recursive) { + $options->setDelimiter('/'); + } + + /** @var ListBlobsResult $listResults */ + $listResults = $this->client->listBlobs($this->container, $options); + + $contents = []; + + foreach ($listResults->getBlobs() as $blob) { + $contents[] = $this->normalizeBlobProperties($blob->getName(), $blob->getProperties()); + } + + if (!$recursive) { + $contents = array_merge($contents, array_map([$this, 'normalizeBlobPrefix'], $listResults->getBlobPrefixes())); + } + + return Util::emulateDirectories($contents); + } + + /** + * @inheritdoc + */ + public function getMetadata($path) + { + $path = $this->applyPathPrefix($path); + + /** @var \WindowsAzure\Blob\Models\GetBlobPropertiesResult $result */ + $result = $this->client->getBlobProperties($this->container, $path); + + return $this->normalizeBlobProperties($path, $result->getProperties()); + } + + /** + * @inheritdoc + */ + public function getSize($path) + { + return $this->getMetadata($path); + } + + /** + * @inheritdoc + */ + public function getMimetype($path) + { + return $this->getMetadata($path); + } + + /** + * @inheritdoc + */ + public function getTimestamp($path) + { + return $this->getMetadata($path); + } + + /** + * Builds the normalized output array. + * + * @param string $path + * @param int $timestamp + * @param mixed $content + * + * @return array + */ + protected function normalize($path, $timestamp, $content = null) + { + $data = [ + 'path' => $path, + 'timestamp' => (int) $timestamp, + 'dirname' => Util::dirname($path), + 'type' => 'file', + ]; + + if (is_string($content)) { + $data['contents'] = $content; + } + + return $data; + } + + /** + * Builds the normalized output array from a Blob object. + * + * @param string $path + * @param BlobProperties $properties + * + * @return array + */ + protected function normalizeBlobProperties($path, BlobProperties $properties) + { + if (substr($path, -1) === '/') { + return ['type' => 'dir', 'path' => $this->removePathPrefix(rtrim($path, '/'))]; + } + + $path = $this->removePathPrefix($path); + + return [ + 'path' => $path, + 'timestamp' => (int) $properties->getLastModified()->format('U'), + 'dirname' => Util::dirname($path), + 'mimetype' => $properties->getContentType(), + 'size' => $properties->getContentLength(), + 'type' => 'file', + ]; + } + + /** + * Builds the normalized output array from a BlobPrefix object. + * + * @param BlobPrefix $blobPrefix + * + * @return array + */ + protected function normalizeBlobPrefix(BlobPrefix $blobPrefix) + { + return ['type' => 'dir', 'path' => $this->removePathPrefix(rtrim($blobPrefix->getName(), '/'))]; + } + + /** + * Retrieves content streamed by Azure into a string. + * + * @param resource $resource + * + * @return string + */ + protected function streamContentsToString($resource) + { + return stream_get_contents($resource); + } + + /** + * Upload a file. + * + * @param string $path Path + * @param mixed $contents Either a string or a stream. + * @param Config $config Config + * + * @return array + */ + protected function upload($path, $contents, Config $config) + { + $path = $this->applyPathPrefix($path); + + $options = new CreateBlobOptions(); + + if ($mimetype = $config->get('mimetype')) { + $options->setContentType($mimetype); + } + + /** @var \WindowsAzure\Blob\Models\CopyBlobResult $result */ + $result = $this->client->createBlockBlob($this->container, $path, $contents, $options); + + return $this->normalize($path, $result->getLastModified()->format('U'), $contents); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/league/flysystem-cached-adapter/src/CacheInterface.php b/lib/ckfinder/core/connector/php/vendor/league/flysystem-cached-adapter/src/CacheInterface.php new file mode 100644 index 0000000..de3ab3d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/league/flysystem-cached-adapter/src/CacheInterface.php @@ -0,0 +1,101 @@ +adapter = $adapter; + $this->cache = $cache; + $this->cache->load(); + } + + /** + * {@inheritdoc} + */ + public function getAdapter() + { + return $this->adapter; + } + + /** + * {@inheritdoc} + */ + public function write($path, $contents, Config $config) + { + $result = $this->adapter->write($path, $contents, $config); + + if ($result !== false) { + $this->cache->updateObject($path, $result + compact('path', 'contents'), true); + } + + return $result; + } + + /** + * {@inheritdoc} + */ + public function writeStream($path, $resource, Config $config) + { + $result = $this->adapter->writeStream($path, $resource, $config); + + if ($result !== false) { + $contents = false; + $this->cache->updateObject($path, $result + compact('path', 'contents'), true); + } + + return $result; + } + + /** + * {@inheritdoc} + */ + public function update($path, $contents, Config $config) + { + $result = $this->adapter->update($path, $contents, $config); + + if ($result !== false) { + $this->cache->updateObject($path, $result + compact('path', 'contents'), true); + } + + return $result; + } + + /** + * {@inheritdoc} + */ + public function updateStream($path, $resource, Config $config) + { + $result = $this->adapter->updateStream($path, $resource, $config); + + if ($result !== false) { + $contents = false; + $this->cache->updateObject($path, $result + compact('path', 'contents'), true); + } + + return $result; + } + + /** + * {@inheritdoc} + */ + public function rename($path, $newPath) + { + $result = $this->adapter->rename($path, $newPath); + + if ($result !== false) { + $this->cache->rename($path, $newPath); + } + + return $result; + } + + /** + * {@inheritdoc} + */ + public function copy($path, $newpath) + { + $result = $this->adapter->copy($path, $newpath); + + if ($result !== false) { + $this->cache->copy($path, $newpath); + } + + return $result; + } + + /** + * {@inheritdoc} + */ + public function delete($path) + { + $result = $this->adapter->delete($path); + + if ($result !== false) { + $this->cache->delete($path); + } + + return $result; + } + + /** + * {@inheritdoc} + */ + public function deleteDir($dirname) + { + $result = $this->adapter->deleteDir($dirname); + + if ($result !== false) { + $this->cache->deleteDir($dirname); + } + + return $result; + } + + /** + * {@inheritdoc} + */ + public function createDir($dirname, Config $config) + { + $result = $this->adapter->createDir($dirname, $config); + + if ($result !== false) { + $type = 'dir'; + $path = $dirname; + $this->cache->updateObject($dirname, compact('path', 'type'), true); + } + + return $result; + } + + /** + * {@inheritdoc} + */ + public function setVisibility($path, $visibility) + { + $result = $this->adapter->setVisibility($path, $visibility); + + if ($result !== false) { + $this->cache->updateObject($path, compact('path', 'visibility'), true); + } + + return $result; + } + + /** + * {@inheritdoc} + */ + public function has($path) + { + $cacheHas = $this->cache->has($path); + + if ($cacheHas !== null) { + return $cacheHas; + } + + $adapterResponse = $this->adapter->has($path); + + if (! $adapterResponse) { + $this->cache->storeMiss($path); + } else { + $cacheEntry = is_array($adapterResponse) ? $adapterResponse : compact('path'); + $this->cache->updateObject($path, $cacheEntry, true); + } + + return $adapterResponse; + } + + /** + * {@inheritdoc} + */ + public function read($path) + { + return $this->callWithFallback('read', $path); + } + + /** + * {@inheritdoc} + */ + public function readStream($path) + { + return $this->adapter->readStream($path); + } + + /** + * {@inheritdoc} + */ + public function listContents($directory = '', $recursive = false) + { + if ($this->cache->isComplete($directory, $recursive)) { + return $this->cache->listContents($directory, $recursive); + } + + $result = $this->adapter->listContents($directory, $recursive); + + if ($result) { + $this->cache->storeContents($directory, $result, $recursive); + } + + return $result; + } + + /** + * {@inheritdoc} + */ + public function getMetadata($path) + { + return $this->callWithFallback('getMetadata', $path); + } + + /** + * {@inheritdoc} + */ + public function getSize($path) + { + return $this->callWithFallback('getSize', $path); + } + + /** + * {@inheritdoc} + */ + public function getMimetype($path) + { + return $this->callWithFallback('getMimetype', $path); + } + + /** + * {@inheritdoc} + */ + public function getTimestamp($path) + { + return $this->callWithFallback('getTimestamp', $path); + } + + /** + * {@inheritdoc} + */ + public function getVisibility($path) + { + return $this->callWithFallback('getVisibility', $path); + } + + /** + * Call a method and cache the response. + * + * @param string $method + * @param string $path + * + * @return mixed + */ + protected function callWithFallback($method, $path) + { + $result = $this->cache->{$method}($path); + + if ($result !== false) { + return $result; + } + + $result = $this->adapter->{$method}($path); + + if ($result) { + $object = $result + compact('path'); + $this->cache->updateObject($path, $object, true); + } + + return $result; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/league/flysystem-cached-adapter/src/Storage/AbstractCache.php b/lib/ckfinder/core/connector/php/vendor/league/flysystem-cached-adapter/src/Storage/AbstractCache.php new file mode 100644 index 0000000..8195c3d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/league/flysystem-cached-adapter/src/Storage/AbstractCache.php @@ -0,0 +1,407 @@ +autosave) { + $this->save(); + } + } + + /** + * Get the autosave setting. + * + * @return bool autosave + */ + public function getAutosave() + { + return $this->autosave; + } + + /** + * Get the autosave setting. + * + * @param bool $autosave + */ + public function setAutosave($autosave) + { + $this->autosave = $autosave; + } + + /** + * Store the contents listing. + * + * @param string $directory + * @param array $contents + * @param bool $recursive + * + * @return array contents listing + */ + public function storeContents($directory, array $contents, $recursive = false) + { + $directories = [$directory]; + + foreach ($contents as $index => $object) { + $this->updateObject($object['path'], $object); + $object = $this->cache[$object['path']]; + + if ($recursive && (empty($directory) || strpos($object['dirname'], $directory) !== false)) { + $directories[] = $object['dirname']; + } + } + + foreach ($directories as $directory) { + $this->setComplete($directory, $recursive); + } + + $this->autosave(); + } + + /** + * Update the metadata for an object. + * + * @param string $path object path + * @param array $object object metadata + * @param bool $autosave whether to trigger the autosave routine + */ + public function updateObject($path, array $object, $autosave = false) + { + if (! $this->has($path)) { + $this->cache[$path] = Util::pathinfo($path); + } + + $this->cache[$path] = array_merge($this->cache[$path], $object); + + if ($autosave) { + $this->autosave(); + } + + $this->ensureParentDirectories($path); + } + + /** + * Store object hit miss. + * + * @param string $path + */ + public function storeMiss($path) + { + $this->cache[$path] = false; + $this->autosave(); + } + + /** + * Get the contents listing. + * + * @param string $dirname + * @param bool $recursive + * + * @return array contents listing + */ + public function listContents($dirname = '', $recursive = false) + { + $result = []; + + foreach ($this->cache as $object) { + if ($object['dirname'] !== $dirname) { + continue; + } + + $result[] = $object; + + if ($recursive && $object['type'] === 'dir') { + $result = array_merge($result, $this->listContents($object['path'], true)); + } + } + + return $result; + } + + /** + * {@inheritdoc} + */ + public function has($path) + { + if (array_key_exists($path, $this->cache)) { + return $this->cache[$path] !== false; + } + + if ($this->isComplete(Util::dirname($path), false)) { + return false; + } + } + + /** + * {@inheritdoc} + */ + public function read($path) + { + if (isset($this->cache[$path]['contents'])) { + return $this->cache[$path]; + } + + return false; + } + + /** + * {@inheritdoc} + */ + public function readStream($path) + { + return false; + } + + /** + * {@inheritdoc} + */ + public function rename($path, $newpath) + { + if ($this->has($path)) { + $object = $this->cache[$path]; + unset($this->cache[$path]); + $object['path'] = $newpath; + $object = array_merge($object, Util::pathinfo($newpath)); + $this->cache[$newpath] = $object; + $this->autosave(); + } + } + + /** + * {@inheritdoc} + */ + public function copy($path, $newpath) + { + if ($this->has($path)) { + $object = $this->cache[$path]; + $object = array_merge($object, Util::pathinfo($newpath)); + $this->updateObject($newpath, $object, true); + } + } + + /** + * {@inheritdoc} + */ + public function delete($path) + { + $this->storeMiss($path); + } + + /** + * {@inheritdoc} + */ + public function deleteDir($dirname) + { + foreach ($this->cache as $path => $object) { + if (strpos($path, $dirname) === 0) { + unset($this->cache[$path]); + } + } + + if (isset($this->complete[$dirname])) { + unset($this->complete[$dirname]); + } + + $this->autosave(); + } + + /** + * {@inheritdoc} + */ + public function getMimetype($path) + { + if (isset($this->cache[$path]['mimetype'])) { + return $this->cache[$path]; + } + + if (! $result = $this->read($path)) { + return false; + } + + $mimetype = Util::guessMimeType($path, $result['contents']); + $this->cache[$path]['mimetype'] = $mimetype; + + return $this->cache[$path]; + } + + /** + * {@inheritdoc} + */ + public function getSize($path) + { + if (isset($this->cache[$path]['size'])) { + return $this->cache[$path]; + } + + return false; + } + + /** + * {@inheritdoc} + */ + public function getTimestamp($path) + { + if (isset($this->cache[$path]['timestamp'])) { + return $this->cache[$path]; + } + + return false; + } + + /** + * {@inheritdoc} + */ + public function getVisibility($path) + { + if (isset($this->cache[$path]['visibility'])) { + return $this->cache[$path]; + } + + return false; + } + + /** + * {@inheritdoc} + */ + public function getMetadata($path) + { + if (isset($this->cache[$path]['type'])) { + return $this->cache[$path]; + } + + return false; + } + + /** + * {@inheritdoc} + */ + public function isComplete($dirname, $recursive) + { + if (! array_key_exists($dirname, $this->complete)) { + return false; + } + + if ($recursive && $this->complete[$dirname] !== 'recursive') { + return false; + } + + return true; + } + + /** + * {@inheritdoc} + */ + public function setComplete($dirname, $recursive) + { + $this->complete[$dirname] = $recursive ? 'recursive' : true; + } + + /** + * Filter the contents from a listing. + * + * @param array $contents object listing + * + * @return array filtered contents + */ + public function cleanContents(array $contents) + { + $cachedProperties = array_flip([ + 'path', 'dirname', 'basename', 'extension', 'filename', + 'size', 'mimetype', 'visibility', 'timestamp', 'type', + ]); + + foreach ($contents as $path => $object) { + if (is_array($object)) { + $contents[$path] = array_intersect_key($object, $cachedProperties); + } + } + + return $contents; + } + + /** + * {@inheritdoc} + */ + public function flush() + { + $this->cache = []; + $this->complete = []; + $this->autosave(); + } + + /** + * {@inheritdoc} + */ + public function autosave() + { + if ($this->autosave) { + $this->save(); + } + } + + /** + * Retrieve serialized cache data. + * + * @return string serialized data + */ + public function getForStorage() + { + $cleaned = $this->cleanContents($this->cache); + + return json_encode([$cleaned, $this->complete]); + } + + /** + * Load from serialized cache data. + * + * @param string $json + */ + public function setFromStorage($json) + { + list($cache, $complete) = json_decode($json, true); + + if (json_last_error() === JSON_ERROR_NONE && is_array($cache) && is_array($complete)) { + $this->cache = $cache; + $this->complete = $complete; + } + } + + /** + * Ensure parent directories of an object. + * + * @param string $path object path + */ + public function ensureParentDirectories($path) + { + $object = $this->cache[$path]; + + while ($object['dirname'] !== '' && ! isset($this->cache[$object['dirname']])) { + $object = Util::pathinfo($object['dirname']); + $object['type'] = 'dir'; + $this->cache[$object['path']] = $object; + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/league/flysystem-cached-adapter/src/Storage/Adapter.php b/lib/ckfinder/core/connector/php/vendor/league/flysystem-cached-adapter/src/Storage/Adapter.php new file mode 100644 index 0000000..3aa8b1a --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/league/flysystem-cached-adapter/src/Storage/Adapter.php @@ -0,0 +1,115 @@ +adapter = $adapter; + $this->file = $file; + $this->setExpire($expire); + } + + /** + * Set the expiration time in seconds. + * + * @param int $expire relative expiration time + */ + protected function setExpire($expire) + { + if ($expire) { + $this->expire = $this->getTime($expire); + } + } + + /** + * Get expiration time in seconds. + * + * @param int $time relative expiration time + * + * @return int actual expiration time + */ + protected function getTime($time = 0) + { + return intval(microtime(true)) + $time; + } + + /** + * {@inheritdoc} + */ + public function setFromStorage($json) + { + list($cache, $complete, $expire) = json_decode($json, true); + + if (! $expire || $expire > $this->getTime()) { + $this->cache = $cache; + $this->complete = $complete; + } else { + $this->adapter->delete($this->file); + } + } + + /** + * {@inheritdoc} + */ + public function load() + { + if ($this->adapter->has($this->file)) { + $file = $this->adapter->read($this->file); + if ($file && !empty($file['contents'])) { + $this->setFromStorage($file['contents']); + } + } + } + + /** + * {@inheritdoc} + */ + public function getForStorage() + { + $cleaned = $this->cleanContents($this->cache); + + return json_encode([$cleaned, $this->complete, $this->expire]); + } + + /** + * {@inheritdoc} + */ + public function save() + { + $config = new Config(); + $contents = $this->getForStorage(); + + if ($this->adapter->has($this->file)) { + $this->adapter->update($this->file, $contents, $config); + } else { + $this->adapter->write($this->file, $contents, $config); + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/league/flysystem-cached-adapter/src/Storage/Memcached.php b/lib/ckfinder/core/connector/php/vendor/league/flysystem-cached-adapter/src/Storage/Memcached.php new file mode 100644 index 0000000..f67d271 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/league/flysystem-cached-adapter/src/Storage/Memcached.php @@ -0,0 +1,59 @@ +key = $key; + $this->expire = $expire; + $this->memcached = $memcached; + } + + /** + * {@inheritdoc} + */ + public function load() + { + $contents = $this->memcached->get($this->key); + + if ($contents !== false) { + $this->setFromStorage($contents); + } + } + + /** + * {@inheritdoc} + */ + public function save() + { + $contents = $this->getForStorage(); + $expiration = $this->expire === null ? 0 : time() + $this->expire; + $this->memcached->set($this->key, $contents, $expiration); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/league/flysystem-cached-adapter/src/Storage/Memory.php b/lib/ckfinder/core/connector/php/vendor/league/flysystem-cached-adapter/src/Storage/Memory.php new file mode 100644 index 0000000..d0914fa --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/league/flysystem-cached-adapter/src/Storage/Memory.php @@ -0,0 +1,22 @@ +client = $client ?: new Redis(); + $this->key = $key; + $this->expire = $expire; + } + + /** + * {@inheritdoc} + */ + public function load() + { + $contents = $this->client->get($this->key); + + if ($contents !== false) { + $this->setFromStorage($contents); + } + } + + /** + * {@inheritdoc} + */ + public function save() + { + $contents = $this->getForStorage(); + $this->client->set($this->key, $contents); + + if ($this->expire !== null) { + $this->client->expire($this->key, $this->expire); + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/league/flysystem-cached-adapter/src/Storage/Predis.php b/lib/ckfinder/core/connector/php/vendor/league/flysystem-cached-adapter/src/Storage/Predis.php new file mode 100644 index 0000000..8a29574 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/league/flysystem-cached-adapter/src/Storage/Predis.php @@ -0,0 +1,75 @@ +client = $client ?: new Client(); + $this->key = $key; + $this->expire = $expire; + } + + /** + * {@inheritdoc} + */ + public function load() + { + if (($contents = $this->executeCommand('get', [$this->key])) !== null) { + $this->setFromStorage($contents); + } + } + + /** + * {@inheritdoc} + */ + public function save() + { + $contents = $this->getForStorage(); + $this->executeCommand('set', [$this->key, $contents]); + + if ($this->expire !== null) { + $this->executeCommand('expire', [$this->key, $this->expire]); + } + } + + /** + * Execute a Predis command. + * + * @param string $name + * @param array $arguments + * + * @return string + */ + protected function executeCommand($name, array $arguments) + { + $command = $this->client->createCommand($name, $arguments); + + return $this->client->executeCommand($command); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/league/flysystem-cached-adapter/src/Storage/Psr6Cache.php b/lib/ckfinder/core/connector/php/vendor/league/flysystem-cached-adapter/src/Storage/Psr6Cache.php new file mode 100644 index 0000000..43be87e --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/league/flysystem-cached-adapter/src/Storage/Psr6Cache.php @@ -0,0 +1,59 @@ +pool = $pool; + $this->key = $key; + $this->expire = $expire; + } + + /** + * {@inheritdoc} + */ + public function save() + { + $item = $this->pool->getItem($this->key); + $item->set($this->getForStorage()); + $item->expiresAfter($this->expire); + $this->pool->save($item); + } + + /** + * {@inheritdoc} + */ + public function load() + { + $item = $this->pool->getItem($this->key); + if ($item->isHit()) { + $this->setFromStorage($item->get()); + } + } +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/league/flysystem-cached-adapter/src/Storage/Stash.php b/lib/ckfinder/core/connector/php/vendor/league/flysystem-cached-adapter/src/Storage/Stash.php new file mode 100644 index 0000000..e05b832 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/league/flysystem-cached-adapter/src/Storage/Stash.php @@ -0,0 +1,60 @@ +key = $key; + $this->expire = $expire; + $this->pool = $pool; + } + + /** + * {@inheritdoc} + */ + public function load() + { + $item = $this->pool->getItem($this->key); + $contents = $item->get(); + + if ($item->isMiss() === false) { + $this->setFromStorage($contents); + } + } + + /** + * {@inheritdoc} + */ + public function save() + { + $contents = $this->getForStorage(); + $item = $this->pool->getItem($this->key); + $item->set($contents, $this->expire); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/league/flysystem-dropbox/src/DropboxAdapter.php b/lib/ckfinder/core/connector/php/vendor/league/flysystem-dropbox/src/DropboxAdapter.php new file mode 100644 index 0000000..7f766fa --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/league/flysystem-dropbox/src/DropboxAdapter.php @@ -0,0 +1,334 @@ + 'size', + 'mime_type' => 'mimetype', + ]; + + /** + * @var Client + */ + protected $client; + + /** + * Constructor. + * + * @param Client $client + * @param string $prefix + */ + public function __construct(Client $client, $prefix = null) + { + $this->client = $client; + $this->setPathPrefix($prefix); + } + + /** + * {@inheritdoc} + */ + public function has($path) + { + return $this->getMetadata($path); + } + + /** + * {@inheritdoc} + */ + public function write($path, $contents, Config $config) + { + return $this->upload($path, $contents, WriteMode::add()); + } + + /** + * {@inheritdoc} + */ + public function writeStream($path, $resource, Config $config) + { + return $this->uploadStream($path, $resource, WriteMode::add()); + } + + /** + * {@inheritdoc} + */ + public function update($path, $contents, Config $config) + { + return $this->upload($path, $contents, WriteMode::force()); + } + + /** + * {@inheritdoc} + */ + public function updateStream($path, $resource, Config $config) + { + return $this->uploadStream($path, $resource, WriteMode::force()); + } + + /** + * {@inheritdoc} + */ + public function read($path) + { + if (! $object = $this->readStream($path)) { + return false; + } + + $object['contents'] = stream_get_contents($object['stream']); + fclose($object['stream']); + unset($object['stream']); + + return $object; + } + + /** + * {@inheritdoc} + */ + public function readStream($path) + { + $stream = fopen('php://temp', 'w+'); + $location = $this->applyPathPrefix($path); + + if (! $this->client->getFile($location, $stream)) { + fclose($stream); + + return false; + } + + rewind($stream); + + return compact('stream'); + } + + /** + * {@inheritdoc} + */ + public function rename($path, $newpath) + { + $path = $this->applyPathPrefix($path); + $newpath = $this->applyPathPrefix($newpath); + + try { + $this->client->move($path, $newpath); + } catch (Exception $e) { + return false; + } + + return true; + } + + /** + * {@inheritdoc} + */ + public function copy($path, $newpath) + { + $path = $this->applyPathPrefix($path); + $newpath = $this->applyPathPrefix($newpath); + + try { + $this->client->copy($path, $newpath); + } catch (Exception $e) { + return false; + } + + return true; + } + + /** + * {@inheritdoc} + */ + public function delete($path) + { + $location = $this->applyPathPrefix($path); + + return $this->client->delete($location); + } + + /** + * {@inheritdoc} + */ + public function deleteDir($path) + { + return $this->delete($path); + } + + /** + * {@inheritdoc} + */ + public function createDir($path, Config $config) + { + $location = $this->applyPathPrefix($path); + $result = $this->client->createFolder($location); + + if ($result === null) { + return false; + } + + return $this->normalizeResponse($result, $path); + } + + /** + * {@inheritdoc} + */ + public function getMetadata($path) + { + $location = $this->applyPathPrefix($path); + $object = $this->client->getMetadata($location); + + if (! $object) { + return false; + } + + return $this->normalizeResponse($object, $path); + } + + /** + * {@inheritdoc} + */ + public function getMimetype($path) + { + return $this->getMetadata($path); + } + + /** + * {@inheritdoc} + */ + public function getSize($path) + { + return $this->getMetadata($path); + } + + /** + * {@inheritdoc} + */ + public function getTimestamp($path) + { + return $this->getMetadata($path); + } + + /** + * {@inheritdoc} + */ + public function getClient() + { + return $this->client; + } + + /** + * {@inheritdoc} + */ + public function listContents($directory = '', $recursive = false) + { + $listing = []; + $directory = trim($directory, '/.'); + $location = $this->applyPathPrefix($directory); + + if (! $result = $this->client->getMetadataWithChildren($location)) { + return []; + } + + foreach ($result['contents'] as $object) { + $path = $this->removePathPrefix($object['path']); + $listing[] = $this->normalizeResponse($object, $path); + + if ($recursive && $object['is_dir']) { + $listing = array_merge($listing, $this->listContents($path, true)); + } + } + + return $listing; + } + + /** + * Apply the path prefix. + * + * @param string $path + * + * @return string prefixed path + */ + public function applyPathPrefix($path) + { + $path = parent::applyPathPrefix($path); + + return '/'.rtrim($path, '/'); + } + + /** + * Do the actual upload of a string file. + * + * @param string $path + * @param string $contents + * @param WriteMode $mode + * + * @return array|false file metadata + */ + protected function upload($path, $contents, WriteMode $mode) + { + $location = $this->applyPathPrefix($path); + + if (! $result = $this->client->uploadFileFromString($location, $mode, $contents)) { + return false; + } + + return $this->normalizeResponse($result, $path); + } + + /** + * Do the actual upload of a file resource. + * + * @param string $path + * @param resource $resource + * @param WriteMode $mode + * + * @return array|false file metadata + */ + protected function uploadStream($path, $resource, WriteMode $mode) + { + $location = $this->applyPathPrefix($path); + + // If size is zero, consider it unknown. + $size = Util::getStreamSize($resource) ?: null; + + if (! $result = $this->client->uploadFile($location, $mode, $resource, $size)) { + return false; + } + + return $this->normalizeResponse($result, $path); + } + + /** + * Normalize a Dropbox response. + * + * @param $response + * @param string $path + * + * @return array + */ + protected function normalizeResponse(array $response, $path = null) + { + $result = ['path' => trim($path ?: $response['path'], '/')]; + + if (isset($response['modified'])) { + $result['timestamp'] = strtotime($response['modified']); + } + + $result = array_merge($result, Util::map($response, static::$resultMap)); + $result['type'] = $response['is_dir'] ? 'dir' : 'file'; + + return $result; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Adapter/AbstractAdapter.php b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Adapter/AbstractAdapter.php new file mode 100644 index 0000000..e2cbebe --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Adapter/AbstractAdapter.php @@ -0,0 +1,86 @@ +pathSeparator) . $this->pathSeparator; + } + + $this->pathPrefix = $is_empty ? null : $prefix; + } + + /** + * Get the path prefix. + * + * @return string path prefix + */ + public function getPathPrefix() + { + return $this->pathPrefix; + } + + /** + * Prefix a path. + * + * @param string $path + * + * @return string prefixed path + */ + public function applyPathPrefix($path) + { + $path = ltrim($path, '\\/'); + + if (strlen($path) === 0) { + return $this->getPathPrefix() ?: ''; + } + + if ($prefix = $this->getPathPrefix()) { + $path = $prefix . $path; + } + + return $path; + } + + /** + * Remove a path prefix. + * + * @param string $path + * + * @return string path without the prefix + */ + public function removePathPrefix($path) + { + $pathPrefix = $this->getPathPrefix(); + + if ($pathPrefix === null) { + return $path; + } + + return substr($path, strlen($pathPrefix)); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Adapter/AbstractFtpAdapter.php b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Adapter/AbstractFtpAdapter.php new file mode 100644 index 0000000..312cd9c --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Adapter/AbstractFtpAdapter.php @@ -0,0 +1,628 @@ +setConfig($config); + } + + /** + * Set the config. + * + * @param array $config + * + * @return $this + */ + public function setConfig(array $config) + { + foreach ($this->configurable as $setting) { + if ( ! isset($config[$setting])) { + continue; + } + + $method = 'set' . ucfirst($setting); + + if (method_exists($this, $method)) { + $this->$method($config[$setting]); + } + } + + return $this; + } + + /** + * Returns the host. + * + * @return string + */ + public function getHost() + { + return $this->host; + } + + /** + * Set the host. + * + * @param string $host + * + * @return $this + */ + public function setHost($host) + { + $this->host = $host; + + return $this; + } + + /** + * Set the public permission value. + * + * @param int $permPublic + * + * @return $this + */ + public function setPermPublic($permPublic) + { + $this->permPublic = $permPublic; + + return $this; + } + + /** + * Set the private permission value. + * + * @param int $permPrivate + * + * @return $this + */ + public function setPermPrivate($permPrivate) + { + $this->permPrivate = $permPrivate; + + return $this; + } + + /** + * Returns the ftp port. + * + * @return int + */ + public function getPort() + { + return $this->port; + } + + /** + * Returns the root folder to work from. + * + * @return string + */ + public function getRoot() + { + return $this->root; + } + + /** + * Set the ftp port. + * + * @param int|string $port + * + * @return $this + */ + public function setPort($port) + { + $this->port = (int) $port; + + return $this; + } + + /** + * Set the root folder to work from. + * + * @param string $root + * + * @return $this + */ + public function setRoot($root) + { + $this->root = rtrim($root, '\\/') . $this->separator; + + return $this; + } + + /** + * Returns the ftp username. + * + * @return string username + */ + public function getUsername() + { + return empty($this->username) ? 'anonymous' : $this->username; + } + + /** + * Set ftp username. + * + * @param string $username + * + * @return $this + */ + public function setUsername($username) + { + $this->username = $username; + + return $this; + } + + /** + * Returns the password. + * + * @return string password + */ + public function getPassword() + { + return $this->password; + } + + /** + * Set the ftp password. + * + * @param string $password + * + * @return $this + */ + public function setPassword($password) + { + $this->password = $password; + + return $this; + } + + /** + * Returns the amount of seconds before the connection will timeout. + * + * @return int + */ + public function getTimeout() + { + return $this->timeout; + } + + /** + * Set the amount of seconds before the connection should timeout. + * + * @param int $timeout + * + * @return $this + */ + public function setTimeout($timeout) + { + $this->timeout = (int) $timeout; + + return $this; + } + + /** + * Return the FTP system type. + * + * @return string + */ + public function getSystemType() + { + return $this->systemType; + } + + /** + * Set the FTP system type (windows or unix). + * + * @param string $systemType + * + * @return $this + */ + public function setSystemType($systemType) + { + $this->systemType = strtolower($systemType); + + return $this; + } + + /** + * @inheritdoc + */ + public function listContents($directory = '', $recursive = false) + { + return $this->listDirectoryContents($directory, $recursive); + } + + abstract protected function listDirectoryContents($directory, $recursive = false); + + /** + * Normalize a directory listing. + * + * @param array $listing + * @param string $prefix + * + * @return array directory listing + */ + protected function normalizeListing(array $listing, $prefix = '') + { + $base = $prefix; + $result = []; + $listing = $this->removeDotDirectories($listing); + + while ($item = array_shift($listing)) { + if (preg_match('#^.*:$#', $item)) { + $base = trim($item, ':'); + continue; + } + + $result[] = $this->normalizeObject($item, $base); + } + + return $this->sortListing($result); + } + + /** + * Sort a directory listing. + * + * @param array $result + * + * @return array sorted listing + */ + protected function sortListing(array $result) + { + $compare = function ($one, $two) { + return strnatcmp($one['path'], $two['path']); + }; + + usort($result, $compare); + + return $result; + } + + /** + * Normalize a file entry. + * + * @param string $item + * @param string $base + * + * @return array normalized file array + * + * @throws NotSupportedException + */ + protected function normalizeObject($item, $base) + { + $systemType = $this->systemType ?: $this->detectSystemType($item); + + if ($systemType === 'unix') { + return $this->normalizeUnixObject($item, $base); + } elseif ($systemType === 'windows') { + return $this->normalizeWindowsObject($item, $base); + } + + throw NotSupportedException::forFtpSystemType($systemType); + } + + /** + * Normalize a Unix file entry. + * + * @param string $item + * @param string $base + * + * @return array normalized file array + */ + protected function normalizeUnixObject($item, $base) + { + $item = preg_replace('#\s+#', ' ', trim($item), 7); + + if (count(explode(' ', $item, 9)) !== 9) { + throw new RuntimeException("Metadata can't be parsed from item '$item' , not enough parts."); + } + + list($permissions, /* $number */, /* $owner */, /* $group */, $size, /* $month */, /* $day */, /* $time*/, $name) = explode(' ', $item, 9); + $type = $this->detectType($permissions); + $path = empty($base) ? $name : $base . $this->separator . $name; + + if ($type === 'dir') { + return compact('type', 'path'); + } + + $permissions = $this->normalizePermissions($permissions); + $visibility = $permissions & 0044 ? AdapterInterface::VISIBILITY_PUBLIC : AdapterInterface::VISIBILITY_PRIVATE; + $size = (int) $size; + + return compact('type', 'path', 'visibility', 'size'); + } + + /** + * Normalize a Windows/DOS file entry. + * + * @param string $item + * @param string $base + * + * @return array normalized file array + */ + protected function normalizeWindowsObject($item, $base) + { + $item = preg_replace('#\s+#', ' ', trim($item), 3); + + if (count(explode(' ', $item, 4)) !== 4) { + throw new RuntimeException("Metadata can't be parsed from item '$item' , not enough parts."); + } + + list($date, $time, $size, $name) = explode(' ', $item, 4); + $path = empty($base) ? $name : $base . $this->separator . $name; + + // Check for the correct date/time format + $format = strlen($date) === 8 ? 'm-d-yH:iA' : 'Y-m-dH:i'; + $dt = DateTime::createFromFormat($format, $date . $time); + $timestamp = $dt ? $dt->getTimestamp() : (int) strtotime("$date $time"); + + if ($size === '') { + $type = 'dir'; + + return compact('type', 'path', 'timestamp'); + } + + $type = 'file'; + $visibility = AdapterInterface::VISIBILITY_PUBLIC; + $size = (int) $size; + + return compact('type', 'path', 'visibility', 'size', 'timestamp'); + } + + /** + * Get the system type from a listing item. + * + * @param string $item + * + * @return string the system type + */ + protected function detectSystemType($item) + { + return preg_match('/^[0-9]{2,4}-[0-9]{2}-[0-9]{2}/', $item) ? 'windows' : 'unix'; + } + + /** + * Get the file type from the permissions. + * + * @param string $permissions + * + * @return string file type + */ + protected function detectType($permissions) + { + return substr($permissions, 0, 1) === 'd' ? 'dir' : 'file'; + } + + /** + * Normalize a permissions string. + * + * @param string $permissions + * + * @return int + */ + protected function normalizePermissions($permissions) + { + // remove the type identifier + $permissions = substr($permissions, 1); + + // map the string rights to the numeric counterparts + $map = ['-' => '0', 'r' => '4', 'w' => '2', 'x' => '1']; + $permissions = strtr($permissions, $map); + + // split up the permission groups + $parts = str_split($permissions, 3); + + // convert the groups + $mapper = function ($part) { + return array_sum(str_split($part)); + }; + + // get the sum of the groups + return array_sum(array_map($mapper, $parts)); + } + + /** + * Filter out dot-directories. + * + * @param array $list + * + * @return array + */ + public function removeDotDirectories(array $list) + { + $filter = function ($line) { + if ( ! empty($line) && ! preg_match('#.* \.(\.)?$|^total#', $line)) { + return true; + } + + return false; + }; + + return array_filter($list, $filter); + } + + /** + * @inheritdoc + */ + public function has($path) + { + return $this->getMetadata($path); + } + + /** + * @inheritdoc + */ + public function getSize($path) + { + return $this->getMetadata($path); + } + + /** + * @inheritdoc + */ + public function getVisibility($path) + { + return $this->getMetadata($path); + } + + /** + * Ensure a directory exists. + * + * @param string $dirname + */ + public function ensureDirectory($dirname) + { + if ( ! empty($dirname) && ! $this->has($dirname)) { + $this->createDir($dirname, new Config()); + } + } + + /** + * @return mixed + */ + public function getConnection() + { + if ( ! $this->isConnected()) { + $this->disconnect(); + $this->connect(); + } + + return $this->connection; + } + + /** + * Get the public permission value. + * + * @return int + */ + public function getPermPublic() + { + return $this->permPublic; + } + + /** + * Get the private permission value. + * + * @return int + */ + public function getPermPrivate() + { + return $this->permPrivate; + } + + /** + * Disconnect on destruction. + */ + public function __destruct() + { + $this->disconnect(); + } + + /** + * Establish a connection. + */ + abstract public function connect(); + + /** + * Close the connection. + */ + abstract public function disconnect(); + + /** + * Check if a connection is active. + * + * @return bool + */ + abstract public function isConnected(); +} diff --git a/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Adapter/Ftp.php b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Adapter/Ftp.php new file mode 100644 index 0000000..21b6e24 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Adapter/Ftp.php @@ -0,0 +1,505 @@ +transferMode = $mode; + + return $this; + } + + /** + * Set if Ssl is enabled. + * + * @param bool $ssl + * + * @return $this + */ + public function setSsl($ssl) + { + $this->ssl = (bool) $ssl; + + return $this; + } + + /** + * Set if passive mode should be used. + * + * @param bool $passive + */ + public function setPassive($passive = true) + { + $this->passive = $passive; + } + + /** + * @param bool $ignorePassiveAddress + */ + public function setIgnorePassiveAddress($ignorePassiveAddress) + { + $this->ignorePassiveAddress = $ignorePassiveAddress; + } + + /** + * @param bool $recurseManually + */ + public function setRecurseManually($recurseManually) + { + $this->recurseManually = $recurseManually; + } + + /** + * Connect to the FTP server. + */ + public function connect() + { + if ($this->ssl) { + $this->connection = ftp_ssl_connect($this->getHost(), $this->getPort(), $this->getTimeout()); + } else { + $this->connection = ftp_connect($this->getHost(), $this->getPort(), $this->getTimeout()); + } + + if ( ! $this->connection) { + throw new RuntimeException('Could not connect to host: ' . $this->getHost() . ', port:' . $this->getPort()); + } + + $this->login(); + $this->setConnectionPassiveMode(); + $this->setConnectionRoot(); + } + + /** + * Set the connections to passive mode. + * + * @throws RuntimeException + */ + protected function setConnectionPassiveMode() + { + if (is_bool($this->ignorePassiveAddress) && defined('FTP_USEPASVADDRESS')) { + ftp_set_option($this->connection, FTP_USEPASVADDRESS, ! $this->ignorePassiveAddress); + } + + if ( ! ftp_pasv($this->connection, $this->passive)) { + throw new RuntimeException( + 'Could not set passive mode for connection: ' . $this->getHost() . '::' . $this->getPort() + ); + } + } + + /** + * Set the connection root. + */ + protected function setConnectionRoot() + { + $root = $this->getRoot(); + $connection = $this->connection; + + if (empty($root) === false && ! ftp_chdir($connection, $root)) { + throw new RuntimeException('Root is invalid or does not exist: ' . $this->getRoot()); + } + + // Store absolute path for further reference. + // This is needed when creating directories and + // initial root was a relative path, else the root + // would be relative to the chdir'd path. + $this->root = ftp_pwd($connection); + } + + /** + * Login. + * + * @throws RuntimeException + */ + protected function login() + { + set_error_handler( + function () { + } + ); + $isLoggedIn = ftp_login($this->connection, $this->getUsername(), $this->getPassword()); + restore_error_handler(); + + if ( ! $isLoggedIn) { + $this->disconnect(); + throw new RuntimeException( + 'Could not login with connection: ' . $this->getHost() . '::' . $this->getPort( + ) . ', username: ' . $this->getUsername() + ); + } + } + + /** + * Disconnect from the FTP server. + */ + public function disconnect() + { + if ($this->isConnected()) { + ftp_close($this->connection); + } + + $this->connection = null; + } + + /** + * @inheritdoc + */ + public function write($path, $contents, Config $config) + { + $stream = fopen('php://temp', 'w+b'); + fwrite($stream, $contents); + rewind($stream); + $result = $this->writeStream($path, $stream, $config); + fclose($stream); + + if ($result === false) { + return false; + } + + $result['contents'] = $contents; + $result['mimetype'] = Util::guessMimeType($path, $contents); + + return $result; + } + + /** + * @inheritdoc + */ + public function writeStream($path, $resource, Config $config) + { + $this->ensureDirectory(Util::dirname($path)); + + if ( ! ftp_fput($this->getConnection(), $path, $resource, $this->transferMode)) { + return false; + } + + if ($visibility = $config->get('visibility')) { + $this->setVisibility($path, $visibility); + } + + return compact('path', 'visibility'); + } + + /** + * @inheritdoc + */ + public function update($path, $contents, Config $config) + { + return $this->write($path, $contents, $config); + } + + /** + * @inheritdoc + */ + public function updateStream($path, $resource, Config $config) + { + return $this->writeStream($path, $resource, $config); + } + + /** + * @inheritdoc + */ + public function rename($path, $newpath) + { + return ftp_rename($this->getConnection(), $path, $newpath); + } + + /** + * @inheritdoc + */ + public function delete($path) + { + return ftp_delete($this->getConnection(), $path); + } + + /** + * @inheritdoc + */ + public function deleteDir($dirname) + { + $connection = $this->getConnection(); + $contents = array_reverse($this->listDirectoryContents($dirname)); + + foreach ($contents as $object) { + if ($object['type'] === 'file') { + if ( ! ftp_delete($connection, $object['path'])) { + return false; + } + } elseif ( ! ftp_rmdir($connection, $object['path'])) { + return false; + } + } + + return ftp_rmdir($connection, $dirname); + } + + /** + * @inheritdoc + */ + public function createDir($dirname, Config $config) + { + $connection = $this->getConnection(); + $directories = explode('/', $dirname); + + foreach ($directories as $directory) { + if (false === $this->createActualDirectory($directory, $connection)) { + $this->setConnectionRoot(); + + return false; + } + + ftp_chdir($connection, $directory); + } + + $this->setConnectionRoot(); + + return ['path' => $dirname]; + } + + /** + * Create a directory. + * + * @param string $directory + * @param resource $connection + * + * @return bool + */ + protected function createActualDirectory($directory, $connection) + { + // List the current directory + $listing = ftp_nlist($connection, '.') ?: []; + + foreach ($listing as $key => $item) { + if (preg_match('~^\./.*~', $item)) { + $listing[$key] = substr($item, 2); + } + } + + if (in_array($directory, $listing)) { + return true; + } + + return (boolean) ftp_mkdir($connection, $directory); + } + + /** + * @inheritdoc + */ + public function getMetadata($path) + { + $connection = $this->getConnection(); + + if ($path === '') { + return ['type' => 'dir', 'path' => '']; + } + + if (@ftp_chdir($connection, $path) === true) { + $this->setConnectionRoot(); + + return ['type' => 'dir', 'path' => $path]; + } + + $listing = ftp_rawlist($connection, '-A ' . str_replace('*', '\\*', $path)); + + if (empty($listing)) { + return false; + } + + if (preg_match('/.* not found/', $listing[0])) { + return false; + } + + if (preg_match('/^total [0-9]*$/', $listing[0])) { + array_shift($listing); + } + + return $this->normalizeObject($listing[0], ''); + } + + /** + * @inheritdoc + */ + public function getMimetype($path) + { + if ( ! $metadata = $this->getMetadata($path)) { + return false; + } + + $metadata['mimetype'] = MimeType::detectByFilename($path); + + return $metadata; + } + + /** + * @inheritdoc + */ + public function getTimestamp($path) + { + $timestamp = ftp_mdtm($this->getConnection(), $path); + + return ($timestamp !== -1) ? ['timestamp' => $timestamp] : false; + } + + /** + * @inheritdoc + */ + public function read($path) + { + if ( ! $object = $this->readStream($path)) { + return false; + } + + $object['contents'] = stream_get_contents($object['stream']); + fclose($object['stream']); + unset($object['stream']); + + return $object; + } + + /** + * @inheritdoc + */ + public function readStream($path) + { + $stream = fopen('php://temp', 'w+b'); + $result = ftp_fget($this->getConnection(), $stream, $path, $this->transferMode); + rewind($stream); + + if ( ! $result) { + fclose($stream); + + return false; + } + + return compact('stream'); + } + + /** + * @inheritdoc + */ + public function setVisibility($path, $visibility) + { + $mode = $visibility === AdapterInterface::VISIBILITY_PUBLIC ? $this->getPermPublic() : $this->getPermPrivate(); + + if ( ! ftp_chmod($this->getConnection(), $mode, $path)) { + return false; + } + + return compact('visibility'); + } + + /** + * @inheritdoc + * + * @param string $directory + */ + protected function listDirectoryContents($directory, $recursive = true) + { + $directory = str_replace('*', '\\*', $directory); + + if ($recursive && $this->recurseManually) { + return $this->listDirectoryContentsRecursive($directory); + } + + $options = $recursive ? '-alnR' : '-aln'; + $listing = ftp_rawlist($this->getConnection(), $options . ' ' . $directory); + + return $listing ? $this->normalizeListing($listing, $directory) : []; + } + + /** + * @inheritdoc + * + * @param string $directory + */ + protected function listDirectoryContentsRecursive($directory) + { + $listing = $this->normalizeListing(ftp_rawlist($this->getConnection(), '-aln' . ' ' . $directory) ?: []); + $output = []; + + foreach ($listing as $directory) { + $output[] = $directory; + if ($directory['type'] !== 'dir') continue; + + $output = array_merge($output, $this->listDirectoryContentsRecursive($directory['path'])); + } + + return $output; + } + + /** + * Check if the connection is open. + * + * @return bool + * @throws ErrorException + */ + public function isConnected() + { + try { + return is_resource($this->connection) && ftp_rawlist($this->connection, '/') !== false; + } catch (ErrorException $e) { + fclose($this->connection); + $this->connection = null; + + if (strpos($e->getMessage(), 'ftp_rawlist') === false) { + throw $e; + } + + return false; + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Adapter/Ftpd.php b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Adapter/Ftpd.php new file mode 100644 index 0000000..91d0cd8 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Adapter/Ftpd.php @@ -0,0 +1,36 @@ +getConnection(), 'STAT ' . $path)) || count($object) < 3) { + return false; + } + + if (substr($object[1], 0, 5) === "ftpd:") { + return false; + } + + return $this->normalizeObject($object[1], ''); + } + + /** + * @inheritdoc + */ + protected function listDirectoryContents($directory, $recursive = true) + { + $listing = ftp_rawlist($this->getConnection(), $directory, $recursive); + + if ($listing === false || ( ! empty($listing) && substr($listing[0], 0, 5) === "ftpd:")) { + return []; + } + + return $this->normalizeListing($listing, $directory); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Adapter/Local.php b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Adapter/Local.php new file mode 100644 index 0000000..fc6081e --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Adapter/Local.php @@ -0,0 +1,514 @@ + [ + 'public' => 0644, + 'private' => 0600, + ], + 'dir' => [ + 'public' => 0755, + 'private' => 0700, + ] + ]; + + /** + * @var string + */ + protected $pathSeparator = DIRECTORY_SEPARATOR; + + /** + * @var array + */ + protected $permissionMap; + + /** + * @var int + */ + protected $writeFlags; + /** + * @var int + */ + private $linkHandling; + + /** + * Constructor. + * + * @param string $root + * @param int $writeFlags + * @param int $linkHandling + * @param array $permissions + */ + public function __construct($root, $writeFlags = LOCK_EX, $linkHandling = self::DISALLOW_LINKS, array $permissions = []) + { + $root = is_link($root) ? realpath($root) : $root; + $this->permissionMap = array_replace_recursive(static::$permissions, $permissions); + $realRoot = $this->ensureDirectory($root); + + if ( ! is_dir($realRoot) || ! is_readable($realRoot)) { + throw new LogicException('The root path ' . $root . ' is not readable.'); + } + + $this->setPathPrefix($realRoot); + $this->writeFlags = $writeFlags; + $this->linkHandling = $linkHandling; + } + + /** + * Ensure the root directory exists. + * + * @param string $root root directory path + * + * @return string real path to root + * + * @throws Exception in case the root directory can not be created + */ + protected function ensureDirectory($root) + { + if ( ! is_dir($root)) { + $umask = umask(0); + @mkdir($root, $this->permissionMap['dir']['public'], true); + umask($umask); + + if ( ! is_dir($root)) { + throw new Exception(sprintf('Impossible to create the root directory "%s".', $root)); + } + } + + return realpath($root); + } + + /** + * @inheritdoc + */ + public function has($path) + { + $location = $this->applyPathPrefix($path); + + return file_exists($location); + } + + /** + * @inheritdoc + */ + public function write($path, $contents, Config $config) + { + $location = $this->applyPathPrefix($path); + $this->ensureDirectory(dirname($location)); + + if (($size = file_put_contents($location, $contents, $this->writeFlags)) === false) { + return false; + } + + $type = 'file'; + $result = compact('contents', 'type', 'size', 'path'); + + if ($visibility = $config->get('visibility')) { + $result['visibility'] = $visibility; + $this->setVisibility($path, $visibility); + } + + return $result; + } + + /** + * @inheritdoc + */ + public function writeStream($path, $resource, Config $config) + { + $location = $this->applyPathPrefix($path); + $this->ensureDirectory(dirname($location)); + $stream = fopen($location, 'w+b'); + + if ( ! $stream) { + return false; + } + + stream_copy_to_stream($resource, $stream); + + if ( ! fclose($stream)) { + return false; + } + + if ($visibility = $config->get('visibility')) { + $this->setVisibility($path, $visibility); + } + + return compact('path', 'visibility'); + } + + /** + * @inheritdoc + */ + public function readStream($path) + { + $location = $this->applyPathPrefix($path); + $stream = fopen($location, 'rb'); + + return compact('stream', 'path'); + } + + /** + * @inheritdoc + */ + public function updateStream($path, $resource, Config $config) + { + return $this->writeStream($path, $resource, $config); + } + + /** + * @inheritdoc + */ + public function update($path, $contents, Config $config) + { + $location = $this->applyPathPrefix($path); + $mimetype = Util::guessMimeType($path, $contents); + $size = file_put_contents($location, $contents, $this->writeFlags); + + if ($size === false) { + return false; + } + + return compact('path', 'size', 'contents', 'mimetype'); + } + + /** + * @inheritdoc + */ + public function read($path) + { + $location = $this->applyPathPrefix($path); + $contents = file_get_contents($location); + + if ($contents === false) { + return false; + } + + return compact('contents', 'path'); + } + + /** + * @inheritdoc + */ + public function rename($path, $newpath) + { + $location = $this->applyPathPrefix($path); + $destination = $this->applyPathPrefix($newpath); + $parentDirectory = $this->applyPathPrefix(Util::dirname($newpath)); + $this->ensureDirectory($parentDirectory); + + return rename($location, $destination); + } + + /** + * @inheritdoc + */ + public function copy($path, $newpath) + { + $location = $this->applyPathPrefix($path); + $destination = $this->applyPathPrefix($newpath); + $this->ensureDirectory(dirname($destination)); + + return copy($location, $destination); + } + + /** + * @inheritdoc + */ + public function delete($path) + { + $location = $this->applyPathPrefix($path); + + return unlink($location); + } + + /** + * @inheritdoc + */ + public function listContents($directory = '', $recursive = false) + { + $result = []; + $location = $this->applyPathPrefix($directory) . $this->pathSeparator; + + if ( ! is_dir($location)) { + return []; + } + + $iterator = $recursive ? $this->getRecursiveDirectoryIterator($location) : $this->getDirectoryIterator($location); + + foreach ($iterator as $file) { + $path = $this->getFilePath($file); + + if (preg_match('#(^|/|\\\\)\.{1,2}$#', $path)) { + continue; + } + + $result[] = $this->normalizeFileInfo($file); + } + + return array_filter($result); + } + + /** + * @inheritdoc + */ + public function getMetadata($path) + { + $location = $this->applyPathPrefix($path); + $info = new SplFileInfo($location); + + return $this->normalizeFileInfo($info); + } + + /** + * @inheritdoc + */ + public function getSize($path) + { + return $this->getMetadata($path); + } + + /** + * @inheritdoc + */ + public function getMimetype($path) + { + $location = $this->applyPathPrefix($path); + $finfo = new Finfo(FILEINFO_MIME_TYPE); + $mimetype = $finfo->file($location); + + if (in_array($mimetype, ['application/octet-stream', 'inode/x-empty'])) { + $mimetype = Util\MimeType::detectByFilename($location); + } + + return ['mimetype' => $mimetype]; + } + + /** + * @inheritdoc + */ + public function getTimestamp($path) + { + return $this->getMetadata($path); + } + + /** + * @inheritdoc + */ + public function getVisibility($path) + { + $location = $this->applyPathPrefix($path); + clearstatcache(false, $location); + $permissions = octdec(substr(sprintf('%o', fileperms($location)), -4)); + $visibility = $permissions & 0044 ? AdapterInterface::VISIBILITY_PUBLIC : AdapterInterface::VISIBILITY_PRIVATE; + + return compact('visibility'); + } + + /** + * @inheritdoc + */ + public function setVisibility($path, $visibility) + { + $location = $this->applyPathPrefix($path); + $type = is_dir($location) ? 'dir' : 'file'; + $success = chmod($location, $this->permissionMap[$type][$visibility]); + + if ($success === false) { + return false; + } + + return compact('visibility'); + } + + /** + * @inheritdoc + */ + public function createDir($dirname, Config $config) + { + $location = $this->applyPathPrefix($dirname); + $umask = umask(0); + $visibility = $config->get('visibility', 'public'); + + if ( ! is_dir($location) && ! mkdir($location, $this->permissionMap['dir'][$visibility], true)) { + $return = false; + } else { + $return = ['path' => $dirname, 'type' => 'dir']; + } + + umask($umask); + + return $return; + } + + /** + * @inheritdoc + */ + public function deleteDir($dirname) + { + $location = $this->applyPathPrefix($dirname); + + if ( ! is_dir($location)) { + return false; + } + + $contents = $this->getRecursiveDirectoryIterator($location, RecursiveIteratorIterator::CHILD_FIRST); + + /** @var SplFileInfo $file */ + foreach ($contents as $file) { + $this->guardAgainstUnreadableFileInfo($file); + $this->deleteFileInfoObject($file); + } + + return rmdir($location); + } + + /** + * @param SplFileInfo $file + */ + protected function deleteFileInfoObject(SplFileInfo $file) + { + switch ($file->getType()) { + case 'dir': + rmdir($file->getRealPath()); + break; + case 'link': + unlink($file->getPathname()); + break; + default: + unlink($file->getRealPath()); + } + } + + /** + * Normalize the file info. + * + * @param SplFileInfo $file + * + * @return array + */ + protected function normalizeFileInfo(SplFileInfo $file) + { + if ( ! $file->isLink()) { + return $this->mapFileInfo($file); + } + + if ($this->linkHandling & self::DISALLOW_LINKS) { + throw NotSupportedException::forLink($file); + } + } + + /** + * Get the normalized path from a SplFileInfo object. + * + * @param SplFileInfo $file + * + * @return string + */ + protected function getFilePath(SplFileInfo $file) + { + $location = $file->getPathname(); + $path = $this->removePathPrefix($location); + + return trim(str_replace('\\', '/', $path), '/'); + } + + /** + * @param string $path + * @param int $mode + * + * @return RecursiveIteratorIterator + */ + protected function getRecursiveDirectoryIterator($path, $mode = RecursiveIteratorIterator::SELF_FIRST) + { + return new RecursiveIteratorIterator( + new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS), + $mode + ); + } + + /** + * @param string $path + * + * @return DirectoryIterator + */ + protected function getDirectoryIterator($path) + { + $iterator = new DirectoryIterator($path); + + return $iterator; + } + + /** + * @param SplFileInfo $file + * + * @return array + */ + protected function mapFileInfo(SplFileInfo $file) + { + $normalized = [ + 'type' => $file->getType(), + 'path' => $this->getFilePath($file), + ]; + + $normalized['timestamp'] = $file->getMTime(); + + if ($normalized['type'] === 'file') { + $normalized['size'] = $file->getSize(); + } + + return $normalized; + } + + /** + * @inheritdoc + */ + public function applyPathPrefix($path) + { + $prefixedPath = parent::applyPathPrefix($path); + + return str_replace('/', DIRECTORY_SEPARATOR, $prefixedPath); + } + + /** + * @param SplFileInfo $file + * + * @throws UnreadableFileException + */ + protected function guardAgainstUnreadableFileInfo(SplFileInfo $file) + { + if ( ! $file->isReadable()) { + throw UnreadableFileException::forFileInfo($file); + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Adapter/NullAdapter.php b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Adapter/NullAdapter.php new file mode 100644 index 0000000..2527087 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Adapter/NullAdapter.php @@ -0,0 +1,144 @@ +get('visibility')) { + $result['visibility'] = $visibility; + } + + return $result; + } + + /** + * @inheritdoc + */ + public function update($path, $contents, Config $config) + { + return false; + } + + /** + * @inheritdoc + */ + public function read($path) + { + return false; + } + + /** + * @inheritdoc + */ + public function rename($path, $newpath) + { + return false; + } + + /** + * @inheritdoc + */ + public function delete($path) + { + return false; + } + + /** + * @inheritdoc + */ + public function listContents($directory = '', $recursive = false) + { + return []; + } + + /** + * @inheritdoc + */ + public function getMetadata($path) + { + return false; + } + + /** + * @inheritdoc + */ + public function getSize($path) + { + return false; + } + + /** + * @inheritdoc + */ + public function getMimetype($path) + { + return false; + } + + /** + * @inheritdoc + */ + public function getTimestamp($path) + { + return false; + } + + /** + * @inheritdoc + */ + public function getVisibility($path) + { + return false; + } + + /** + * @inheritdoc + */ + public function setVisibility($path, $visibility) + { + return compact('visibility'); + } + + /** + * @inheritdoc + */ + public function createDir($dirname, Config $config) + { + return ['path' => $dirname, 'type' => 'dir']; + } + + /** + * @inheritdoc + */ + public function deleteDir($dirname) + { + return false; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Adapter/Polyfill/NotSupportingVisibilityTrait.php b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Adapter/Polyfill/NotSupportingVisibilityTrait.php new file mode 100644 index 0000000..fc0a747 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Adapter/Polyfill/NotSupportingVisibilityTrait.php @@ -0,0 +1,33 @@ +readStream($path); + + if ($response === false || ! is_resource($response['stream'])) { + return false; + } + + $result = $this->writeStream($newpath, $response['stream'], new Config()); + + if ($result !== false && is_resource($response['stream'])) { + fclose($response['stream']); + } + + return $result !== false; + } + + // Required abstract method + + /** + * @param string $path + */ + abstract public function readStream($path); + + /** + * @param string $path + */ + abstract public function writeStream($path, $resource, Config $config); +} diff --git a/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Adapter/Polyfill/StreamedReadingTrait.php b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Adapter/Polyfill/StreamedReadingTrait.php new file mode 100644 index 0000000..2b31c01 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Adapter/Polyfill/StreamedReadingTrait.php @@ -0,0 +1,44 @@ +read($path)) { + return false; + } + + $stream = fopen('php://temp', 'w+b'); + fwrite($stream, $data['contents']); + rewind($stream); + $data['stream'] = $stream; + unset($data['contents']); + + return $data; + } + + /** + * Reads a file. + * + * @param string $path + * + * @return array|false + * + * @see League\Flysystem\ReadInterface::read() + */ + abstract public function read($path); +} diff --git a/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Adapter/Polyfill/StreamedTrait.php b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Adapter/Polyfill/StreamedTrait.php new file mode 100644 index 0000000..8042496 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Adapter/Polyfill/StreamedTrait.php @@ -0,0 +1,9 @@ +stream($path, $resource, $config, 'write'); + } + + /** + * Update a file using a stream. + * + * @param string $path + * @param resource $resource + * @param Config $config Config object or visibility setting + * + * @return mixed false of file metadata + */ + public function updateStream($path, $resource, Config $config) + { + return $this->stream($path, $resource, $config, 'update'); + } + + // Required abstract methods + abstract public function write($pash, $contents, Config $config); + abstract public function update($pash, $contents, Config $config); +} diff --git a/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Adapter/SynologyFtp.php b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Adapter/SynologyFtp.php new file mode 100644 index 0000000..fe0d344 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Adapter/SynologyFtp.php @@ -0,0 +1,8 @@ +settings = $settings; + } + + /** + * Get a setting. + * + * @param string $key + * @param mixed $default + * + * @return mixed config setting or default when not found + */ + public function get($key, $default = null) + { + if ( ! array_key_exists($key, $this->settings)) { + return $this->getDefault($key, $default); + } + + return $this->settings[$key]; + } + + /** + * Check if an item exists by key. + * + * @param string $key + * + * @return bool + */ + public function has($key) + { + return array_key_exists($key, $this->settings); + } + + /** + * Try to retrieve a default setting from a config fallback. + * + * @param string $key + * @param mixed $default + * + * @return mixed config setting or default when not found + */ + protected function getDefault($key, $default) + { + if ( ! $this->fallback) { + return $default; + } + + return $this->fallback->get($key, $default); + } + + /** + * Set a setting. + * + * @param string $key + * @param mixed $value + * + * @return $this + */ + public function set($key, $value) + { + $this->settings[$key] = $value; + + return $this; + } + + /** + * Set the fallback. + * + * @param Config $fallback + * + * @return $this + */ + public function setFallback(Config $fallback) + { + $this->fallback = $fallback; + + return $this; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/ConfigAwareTrait.php b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/ConfigAwareTrait.php new file mode 100644 index 0000000..202d605 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/ConfigAwareTrait.php @@ -0,0 +1,49 @@ +config = $config ? Util::ensureConfig($config) : new Config; + } + + /** + * Get the Config. + * + * @return Config config object + */ + public function getConfig() + { + return $this->config; + } + + /** + * Convert a config array to a Config object with the correct fallback. + * + * @param array $config + * + * @return Config + */ + protected function prepareConfig(array $config) + { + $config = new Config($config); + $config->setFallback($this->getConfig()); + + return $config; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Directory.php b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Directory.php new file mode 100644 index 0000000..6ba744b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Directory.php @@ -0,0 +1,28 @@ +filesystem->deleteDir($this->path); + } + + /** + * List the directory contents. + * + * @param bool $recursive + * + * @return array|bool directory contents or false + */ + public function getContents($recursive = false) + { + return $this->filesystem->listContents($this->path, $recursive); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Exception.php b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Exception.php new file mode 100644 index 0000000..d4a9907 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Exception.php @@ -0,0 +1,8 @@ +filesystem->has($this->path); + } + + /** + * Read the file. + * + * @return string file contents + */ + public function read() + { + return $this->filesystem->read($this->path); + } + + /** + * Read the file as a stream. + * + * @return resource file stream + */ + public function readStream() + { + return $this->filesystem->readStream($this->path); + } + + /** + * Write the new file. + * + * @param string $content + * + * @return bool success boolean + */ + public function write($content) + { + return $this->filesystem->write($this->path, $content); + } + + /** + * Write the new file using a stream. + * + * @param resource $resource + * + * @return bool success boolean + */ + public function writeStream($resource) + { + return $this->filesystem->writeStream($this->path, $resource); + } + + /** + * Update the file contents. + * + * @param string $content + * + * @return bool success boolean + */ + public function update($content) + { + return $this->filesystem->update($this->path, $content); + } + + /** + * Update the file contents with a stream. + * + * @param resource $resource + * + * @return bool success boolean + */ + public function updateStream($resource) + { + return $this->filesystem->updateStream($this->path, $resource); + } + + /** + * Create the file or update if exists. + * + * @param string $content + * + * @return bool success boolean + */ + public function put($content) + { + return $this->filesystem->put($this->path, $content); + } + + /** + * Create the file or update if exists using a stream. + * + * @param resource $resource + * + * @return bool success boolean + */ + public function putStream($resource) + { + return $this->filesystem->putStream($this->path, $resource); + } + + /** + * Rename the file. + * + * @param string $newpath + * + * @return bool success boolean + */ + public function rename($newpath) + { + if ($this->filesystem->rename($this->path, $newpath)) { + $this->path = $newpath; + + return true; + } + + return false; + } + + /** + * Copy the file. + * + * @param string $newpath + * + * @return File|false new file or false + */ + public function copy($newpath) + { + if ($this->filesystem->copy($this->path, $newpath)) { + return new File($this->filesystem, $newpath); + } + + return false; + } + + /** + * Get the file's timestamp. + * + * @return int unix timestamp + */ + public function getTimestamp() + { + return $this->filesystem->getTimestamp($this->path); + } + + /** + * Get the file's mimetype. + * + * @return string mimetime + */ + public function getMimetype() + { + return $this->filesystem->getMimetype($this->path); + } + + /** + * Get the file's visibility. + * + * @return string visibility + */ + public function getVisibility() + { + return $this->filesystem->getVisibility($this->path); + } + + /** + * Get the file's metadata. + * + * @return array + */ + public function getMetadata() + { + return $this->filesystem->getMetadata($this->path); + } + + /** + * Get the file size. + * + * @return int file size + */ + public function getSize() + { + return $this->filesystem->getSize($this->path); + } + + /** + * Delete the file. + * + * @return bool success boolean + */ + public function delete() + { + return $this->filesystem->delete($this->path); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/FileExistsException.php b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/FileExistsException.php new file mode 100644 index 0000000..c82e20c --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/FileExistsException.php @@ -0,0 +1,37 @@ +path = $path; + + parent::__construct('File already exists at path: ' . $this->getPath(), $code, $previous); + } + + /** + * Get the path which was found. + * + * @return string + */ + public function getPath() + { + return $this->path; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/FileNotFoundException.php b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/FileNotFoundException.php new file mode 100644 index 0000000..989df69 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/FileNotFoundException.php @@ -0,0 +1,37 @@ +path = $path; + + parent::__construct('File not found at path: ' . $this->getPath(), $code, $previous); + } + + /** + * Get the path which was not found. + * + * @return string + */ + public function getPath() + { + return $this->path; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Filesystem.php b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Filesystem.php new file mode 100644 index 0000000..7a85fde --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Filesystem.php @@ -0,0 +1,404 @@ +adapter = $adapter; + $this->setConfig($config); + } + + /** + * Get the Adapter. + * + * @return AdapterInterface adapter + */ + public function getAdapter() + { + return $this->adapter; + } + + /** + * @inheritdoc + */ + public function has($path) + { + $path = Util::normalizePath($path); + + return strlen($path) === 0 ? false : (bool) $this->getAdapter()->has($path); + } + + /** + * @inheritdoc + */ + public function write($path, $contents, array $config = []) + { + $path = Util::normalizePath($path); + $this->assertAbsent($path); + $config = $this->prepareConfig($config); + + return (bool) $this->getAdapter()->write($path, $contents, $config); + } + + /** + * @inheritdoc + */ + public function writeStream($path, $resource, array $config = []) + { + if ( ! is_resource($resource)) { + throw new InvalidArgumentException(__METHOD__ . ' expects argument #2 to be a valid resource.'); + } + + $path = Util::normalizePath($path); + $this->assertAbsent($path); + $config = $this->prepareConfig($config); + + Util::rewindStream($resource); + + return (bool) $this->getAdapter()->writeStream($path, $resource, $config); + } + + /** + * @inheritdoc + */ + public function put($path, $contents, array $config = []) + { + $path = Util::normalizePath($path); + $config = $this->prepareConfig($config); + + if ($this->has($path)) { + return (bool) $this->getAdapter()->update($path, $contents, $config); + } + + return (bool) $this->getAdapter()->write($path, $contents, $config); + } + + /** + * @inheritdoc + */ + public function putStream($path, $resource, array $config = []) + { + if ( ! is_resource($resource)) { + throw new InvalidArgumentException(__METHOD__ . ' expects argument #2 to be a valid resource.'); + } + + $path = Util::normalizePath($path); + $config = $this->prepareConfig($config); + Util::rewindStream($resource); + + if ($this->has($path)) { + return (bool) $this->getAdapter()->updateStream($path, $resource, $config); + } + + return (bool) $this->getAdapter()->writeStream($path, $resource, $config); + } + + /** + * @inheritdoc + */ + public function readAndDelete($path) + { + $path = Util::normalizePath($path); + $this->assertPresent($path); + $contents = $this->read($path); + + if ($contents === false) { + return false; + } + + $this->delete($path); + + return $contents; + } + + /** + * @inheritdoc + */ + public function update($path, $contents, array $config = []) + { + $path = Util::normalizePath($path); + $config = $this->prepareConfig($config); + + $this->assertPresent($path); + + return (bool) $this->getAdapter()->update($path, $contents, $config); + } + + /** + * @inheritdoc + */ + public function updateStream($path, $resource, array $config = []) + { + if ( ! is_resource($resource)) { + throw new InvalidArgumentException(__METHOD__ . ' expects argument #2 to be a valid resource.'); + } + + $path = Util::normalizePath($path); + $config = $this->prepareConfig($config); + $this->assertPresent($path); + Util::rewindStream($resource); + + return (bool) $this->getAdapter()->updateStream($path, $resource, $config); + } + + /** + * @inheritdoc + */ + public function read($path) + { + $path = Util::normalizePath($path); + $this->assertPresent($path); + + if ( ! ($object = $this->getAdapter()->read($path))) { + return false; + } + + return $object['contents']; + } + + /** + * @inheritdoc + */ + public function readStream($path) + { + $path = Util::normalizePath($path); + $this->assertPresent($path); + + if ( ! $object = $this->getAdapter()->readStream($path)) { + return false; + } + + return $object['stream']; + } + + /** + * @inheritdoc + */ + public function rename($path, $newpath) + { + $path = Util::normalizePath($path); + $newpath = Util::normalizePath($newpath); + $this->assertPresent($path); + $this->assertAbsent($newpath); + + return (bool) $this->getAdapter()->rename($path, $newpath); + } + + /** + * @inheritdoc + */ + public function copy($path, $newpath) + { + $path = Util::normalizePath($path); + $newpath = Util::normalizePath($newpath); + $this->assertPresent($path); + $this->assertAbsent($newpath); + + return $this->getAdapter()->copy($path, $newpath); + } + + /** + * @inheritdoc + */ + public function delete($path) + { + $path = Util::normalizePath($path); + $this->assertPresent($path); + + return $this->getAdapter()->delete($path); + } + + /** + * @inheritdoc + */ + public function deleteDir($dirname) + { + $dirname = Util::normalizePath($dirname); + + if ($dirname === '') { + throw new RootViolationException('Root directories can not be deleted.'); + } + + return (bool) $this->getAdapter()->deleteDir($dirname); + } + + /** + * @inheritdoc + */ + public function createDir($dirname, array $config = []) + { + $dirname = Util::normalizePath($dirname); + $config = $this->prepareConfig($config); + + return (bool) $this->getAdapter()->createDir($dirname, $config); + } + + /** + * @inheritdoc + */ + public function listContents($directory = '', $recursive = false) + { + $directory = Util::normalizePath($directory); + $contents = $this->getAdapter()->listContents($directory, $recursive); + + return (new ContentListingFormatter($directory, $recursive))->formatListing($contents); + } + + /** + * @inheritdoc + */ + public function getMimetype($path) + { + $path = Util::normalizePath($path); + $this->assertPresent($path); + + if ( ! $object = $this->getAdapter()->getMimetype($path)) { + return false; + } + + return $object['mimetype']; + } + + /** + * @inheritdoc + */ + public function getTimestamp($path) + { + $path = Util::normalizePath($path); + $this->assertPresent($path); + + if ( ! $object = $this->getAdapter()->getTimestamp($path)) { + return false; + } + + return $object['timestamp']; + } + + /** + * @inheritdoc + */ + public function getVisibility($path) + { + $path = Util::normalizePath($path); + $this->assertPresent($path); + + if (($object = $this->getAdapter()->getVisibility($path)) === false) { + return false; + } + + return $object['visibility']; + } + + /** + * @inheritdoc + */ + public function getSize($path) + { + $path = Util::normalizePath($path); + + if (($object = $this->getAdapter()->getSize($path)) === false || ! isset($object['size'])) { + return false; + } + + return (int) $object['size']; + } + + /** + * @inheritdoc + */ + public function setVisibility($path, $visibility) + { + $path = Util::normalizePath($path); + + return (bool) $this->getAdapter()->setVisibility($path, $visibility); + } + + /** + * @inheritdoc + */ + public function getMetadata($path) + { + $path = Util::normalizePath($path); + $this->assertPresent($path); + + return $this->getAdapter()->getMetadata($path); + } + + /** + * @inheritdoc + */ + public function get($path, Handler $handler = null) + { + $path = Util::normalizePath($path); + + if ( ! $handler) { + $metadata = $this->getMetadata($path); + $handler = $metadata['type'] === 'file' ? new File($this, $path) : new Directory($this, $path); + } + + $handler->setPath($path); + $handler->setFilesystem($this); + + return $handler; + } + + /** + * Assert a file is present. + * + * @param string $path path to file + * + * @throws FileNotFoundException + * + * @return void + */ + public function assertPresent($path) + { + if ($this->config->get('disable_asserts', false) === false && ! $this->has($path)) { + throw new FileNotFoundException($path); + } + } + + /** + * Assert a file is absent. + * + * @param string $path path to file + * + * @throws FileExistsException + * + * @return void + */ + public function assertAbsent($path) + { + if ($this->config->get('disable_asserts', false) === false && $this->has($path)) { + throw new FileExistsException($path); + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/FilesystemInterface.php b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/FilesystemInterface.php new file mode 100644 index 0000000..d631443 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/FilesystemInterface.php @@ -0,0 +1,276 @@ +path = $path; + $this->filesystem = $filesystem; + } + + /** + * Check whether the entree is a directory. + * + * @return bool + */ + public function isDir() + { + return $this->getType() === 'dir'; + } + + /** + * Check whether the entree is a file. + * + * @return bool + */ + public function isFile() + { + return $this->getType() === 'file'; + } + + /** + * Retrieve the entree type (file|dir). + * + * @return string file or dir + */ + public function getType() + { + $metadata = $this->filesystem->getMetadata($this->path); + + return $metadata['type']; + } + + /** + * Set the Filesystem object. + * + * @param FilesystemInterface $filesystem + * + * @return $this + */ + public function setFilesystem(FilesystemInterface $filesystem) + { + $this->filesystem = $filesystem; + + return $this; + } + + /** + * Retrieve the Filesystem object. + * + * @return FilesystemInterface + */ + public function getFilesystem() + { + return $this->filesystem; + } + + /** + * Set the entree path. + * + * @param string $path + * + * @return $this + */ + public function setPath($path) + { + $this->path = $path; + + return $this; + } + + /** + * Retrieve the entree path. + * + * @return string path + */ + public function getPath() + { + return $this->path; + } + + /** + * Plugins pass-through. + * + * @param string $method + * @param array $arguments + * + * @return mixed + */ + public function __call($method, array $arguments) + { + array_unshift($arguments, $this->path); + $callback = [$this->filesystem, $method]; + + try { + return call_user_func_array($callback, $arguments); + } catch (BadMethodCallException $e) { + throw new BadMethodCallException( + 'Call to undefined method ' + . get_called_class() + . '::' . $method + ); + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/MountManager.php b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/MountManager.php new file mode 100644 index 0000000..e95f822 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/MountManager.php @@ -0,0 +1,271 @@ +mountFilesystems($filesystems); + } + + /** + * Mount filesystems. + * + * @param array $filesystems [:prefix => Filesystem,] + * + * @return $this + */ + public function mountFilesystems(array $filesystems) + { + foreach ($filesystems as $prefix => $filesystem) { + $this->mountFilesystem($prefix, $filesystem); + } + + return $this; + } + + /** + * Mount filesystems. + * + * @param string $prefix + * @param FilesystemInterface $filesystem + * + * @return $this + */ + public function mountFilesystem($prefix, FilesystemInterface $filesystem) + { + if ( ! is_string($prefix)) { + throw new InvalidArgumentException(__METHOD__ . ' expects argument #1 to be a string.'); + } + + $this->filesystems[$prefix] = $filesystem; + + return $this; + } + + /** + * Get the filesystem with the corresponding prefix. + * + * @param string $prefix + * + * @throws LogicException + * + * @return FilesystemInterface + */ + public function getFilesystem($prefix) + { + if ( ! isset($this->filesystems[$prefix])) { + throw new LogicException('No filesystem mounted with prefix ' . $prefix); + } + + return $this->filesystems[$prefix]; + } + + /** + * Retrieve the prefix from an arguments array. + * + * @param array $arguments + * + * @return array [:prefix, :arguments] + */ + public function filterPrefix(array $arguments) + { + if (empty($arguments)) { + throw new LogicException('At least one argument needed'); + } + + $path = array_shift($arguments); + + if ( ! is_string($path)) { + throw new InvalidArgumentException('First argument should be a string'); + } + + if ( ! preg_match('#^.+\:\/\/.*#', $path)) { + throw new InvalidArgumentException('No prefix detected in path: ' . $path); + } + + list($prefix, $path) = explode('://', $path, 2); + array_unshift($arguments, $path); + + return [$prefix, $arguments]; + } + + /** + * @param string $directory + * @param bool $recursive + * + * @return array + */ + public function listContents($directory = '', $recursive = false) + { + list($prefix, $arguments) = $this->filterPrefix([$directory]); + $filesystem = $this->getFilesystem($prefix); + $directory = array_shift($arguments); + $result = $filesystem->listContents($directory, $recursive); + + foreach ($result as &$file) { + $file['filesystem'] = $prefix; + } + + return $result; + } + + /** + * Call forwarder. + * + * @param string $method + * @param array $arguments + * + * @return mixed + */ + public function __call($method, $arguments) + { + list($prefix, $arguments) = $this->filterPrefix($arguments); + + return $this->invokePluginOnFilesystem($method, $arguments, $prefix); + } + + /** + * @param $from + * @param $to + * @param array $config + * + * @return bool + */ + public function copy($from, $to, array $config = []) + { + list($prefixFrom, $arguments) = $this->filterPrefix([$from]); + + $fsFrom = $this->getFilesystem($prefixFrom); + $buffer = call_user_func_array([$fsFrom, 'readStream'], $arguments); + + if ($buffer === false) { + return false; + } + + list($prefixTo, $arguments) = $this->filterPrefix([$to]); + + $fsTo = $this->getFilesystem($prefixTo); + $result = call_user_func_array([$fsTo, 'writeStream'], array_merge($arguments, [$buffer, $config])); + + if (is_resource($buffer)) { + fclose($buffer); + } + + return $result; + } + + /** + * List with plugin adapter. + * + * @param array $keys + * @param string $directory + * @param bool $recursive + */ + public function listWith(array $keys = [], $directory = '', $recursive = false) + { + list($prefix, $arguments) = $this->filterPrefix([$directory]); + $directory = $arguments[0]; + $arguments = [$keys, $directory, $recursive]; + + return $this->invokePluginOnFilesystem('listWith', $arguments, $prefix); + } + + /** + * Move a file. + * + * @param $from + * @param $to + * @param array $config + * + * @return bool + */ + public function move($from, $to, array $config = []) + { + $copied = $this->copy($from, $to, $config); + + if ($copied) { + return $this->delete($from); + } + + return false; + } + + /** + * Invoke a plugin on a filesystem mounted on a given prefix. + * + * @param $method + * @param $arguments + * @param $prefix + * + * @return mixed + */ + public function invokePluginOnFilesystem($method, $arguments, $prefix) + { + $filesystem = $this->getFilesystem($prefix); + + try { + return $this->invokePlugin($method, $arguments, $filesystem); + } catch (PluginNotFoundException $e) { + // Let it pass, it's ok, don't panic. + } + + $callback = [$filesystem, $method]; + + return call_user_func_array($callback, $arguments); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/NotSupportedException.php b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/NotSupportedException.php new file mode 100644 index 0000000..08f47f7 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/NotSupportedException.php @@ -0,0 +1,37 @@ +getPathname()); + } + + /** + * Create a new exception for a link. + * + * @param string $systemType + * + * @return static + */ + public static function forFtpSystemType($systemType) + { + $message = "The FTP system type '$systemType' is currently not supported."; + + return new static($message); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Plugin/AbstractPlugin.php b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Plugin/AbstractPlugin.php new file mode 100644 index 0000000..0d56789 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Plugin/AbstractPlugin.php @@ -0,0 +1,24 @@ +filesystem = $filesystem; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Plugin/EmptyDir.php b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Plugin/EmptyDir.php new file mode 100644 index 0000000..9502333 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Plugin/EmptyDir.php @@ -0,0 +1,34 @@ +filesystem->listContents($dirname, false); + + foreach ($listing as $item) { + if ($item['type'] === 'dir') { + $this->filesystem->deleteDir($item['path']); + } else { + $this->filesystem->delete($item['path']); + } + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Plugin/ForcedCopy.php b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Plugin/ForcedCopy.php new file mode 100644 index 0000000..d2fc379 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Plugin/ForcedCopy.php @@ -0,0 +1,42 @@ +filesystem->delete($newpath); + } catch (FileNotFoundException $e) { + // The destination path does not exist. That's ok. + $deleted = true; + } + + if ($deleted) { + return $this->filesystem->copy($path, $newpath); + } + + return false; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Plugin/ForcedRename.php b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Plugin/ForcedRename.php new file mode 100644 index 0000000..7c081b6 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Plugin/ForcedRename.php @@ -0,0 +1,42 @@ +filesystem->delete($newpath); + } catch (FileNotFoundException $e) { + // The destination path does not exist. That's ok. + $deleted = true; + } + + if ($deleted) { + return $this->filesystem->rename($path, $newpath); + } + + return false; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Plugin/GetWithMetadata.php b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Plugin/GetWithMetadata.php new file mode 100644 index 0000000..781dd24 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Plugin/GetWithMetadata.php @@ -0,0 +1,49 @@ +filesystem->getMetadata($path); + + if ( ! $object) { + return false; + } + + $keys = array_diff($metadata, array_keys($object)); + + foreach ($keys as $key) { + if ( ! method_exists($this->filesystem, $method = 'get' . ucfirst($key))) { + throw new InvalidArgumentException('Could not fetch metadata: ' . $key); + } + + $object[$key] = $this->filesystem->{$method}($path); + } + + return $object; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Plugin/ListFiles.php b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Plugin/ListFiles.php new file mode 100644 index 0000000..9669fe7 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Plugin/ListFiles.php @@ -0,0 +1,35 @@ +filesystem->listContents($directory, $recursive); + + $filter = function ($object) { + return $object['type'] === 'file'; + }; + + return array_values(array_filter($contents, $filter)); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Plugin/ListPaths.php b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Plugin/ListPaths.php new file mode 100644 index 0000000..514bdf0 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Plugin/ListPaths.php @@ -0,0 +1,36 @@ +filesystem->listContents($directory, $recursive); + + foreach ($contents as $object) { + $result[] = $object['path']; + } + + return $result; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Plugin/ListWith.php b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Plugin/ListWith.php new file mode 100644 index 0000000..7d773e6 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Plugin/ListWith.php @@ -0,0 +1,60 @@ +filesystem->listContents($directory, $recursive); + + foreach ($contents as $index => $object) { + if ($object['type'] === 'file') { + $missingKeys = array_diff($keys, array_keys($object)); + $contents[$index] = array_reduce($missingKeys, [$this, 'getMetadataByName'], $object); + } + } + + return $contents; + } + + /** + * Get a meta-data value by key name. + * + * @param array $object + * @param $key + * + * @return array + */ + protected function getMetadataByName(array $object, $key) + { + $method = 'get' . ucfirst($key); + + if ( ! method_exists($this->filesystem, $method)) { + throw new \InvalidArgumentException('Could not get meta-data for key: ' . $key); + } + + $object[$key] = $this->filesystem->{$method}($object['path']); + + return $object; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Plugin/PluggableTrait.php b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Plugin/PluggableTrait.php new file mode 100644 index 0000000..a63734f --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Plugin/PluggableTrait.php @@ -0,0 +1,92 @@ +plugins[$plugin->getMethod()] = $plugin; + + return $this; + } + + /** + * Find a specific plugin. + * + * @param string $method + * + * @throws LogicException + * + * @return PluginInterface $plugin + */ + protected function findPlugin($method) + { + if ( ! isset($this->plugins[$method])) { + throw new PluginNotFoundException('Plugin not found for method: ' . $method); + } + + if ( ! method_exists($this->plugins[$method], 'handle')) { + throw new LogicException(get_class($this->plugins[$method]) . ' does not have a handle method.'); + } + + return $this->plugins[$method]; + } + + /** + * Invoke a plugin by method name. + * + * @param string $method + * @param array $arguments + * + * @return mixed + */ + protected function invokePlugin($method, array $arguments, FilesystemInterface $filesystem) + { + $plugin = $this->findPlugin($method); + $plugin->setFilesystem($filesystem); + $callback = [$plugin, 'handle']; + + return call_user_func_array($callback, $arguments); + } + + /** + * Plugins pass-through. + * + * @param string $method + * @param array $arguments + * + * @throws BadMethodCallException + * + * @return mixed + */ + public function __call($method, array $arguments) + { + try { + return $this->invokePlugin($method, $arguments, $this); + } catch (PluginNotFoundException $e) { + throw new BadMethodCallException( + 'Call to undefined method ' + . get_class($this) + . '::' . $method + ); + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Plugin/PluginNotFoundException.php b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Plugin/PluginNotFoundException.php new file mode 100644 index 0000000..fd1d7e7 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Plugin/PluginNotFoundException.php @@ -0,0 +1,10 @@ +getRealPath() + ) + ); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Util.php b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Util.php new file mode 100644 index 0000000..977ffa9 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Util.php @@ -0,0 +1,288 @@ + $to) { + if ( ! isset($object[$from])) { + continue; + } + + $result[$to] = $object[$from]; + } + + return $result; + } + + /** + * Normalize path. + * + * @param string $path + * + * @throws LogicException + * + * @return string + */ + public static function normalizePath($path) + { + // Remove any kind of funky unicode whitespace + $normalized = preg_replace('#\p{C}+|^\./#u', '', $path); + $normalized = static::normalizeRelativePath($normalized); + + if (preg_match('#/\.{2}|^\.{2}/|^\.{2}$#', $normalized)) { + throw new LogicException( + 'Path is outside of the defined root, path: [' . $path . '], resolved: [' . $normalized . ']' + ); + } + + $normalized = preg_replace('#\\\{2,}#', '\\', trim($normalized, '\\')); + $normalized = preg_replace('#/{2,}#', '/', trim($normalized, '/')); + + return $normalized; + } + + /** + * Normalize relative directories in a path. + * + * @param string $path + * + * @return string + */ + public static function normalizeRelativePath($path) + { + // Path remove self referring paths ("/./"). + $path = preg_replace('#/\.(?=/)|^\./|(/|^)\./?$#', '', $path); + + // Regex for resolving relative paths + $regex = '#/*[^/\.]+/\.\.#Uu'; + + while (preg_match($regex, $path)) { + $path = preg_replace($regex, '', $path); + } + + return $path; + } + + /** + * Normalize prefix. + * + * @param string $prefix + * @param string $separator + * + * @return string normalized path + */ + public static function normalizePrefix($prefix, $separator) + { + return rtrim($prefix, $separator) . $separator; + } + + /** + * Get content size. + * + * @param string $contents + * + * @return int content size + */ + public static function contentSize($contents) + { + return defined('MB_OVERLOAD_STRING') ? mb_strlen($contents, '8bit') : strlen($contents); + } + + /** + * Guess MIME Type based on the path of the file and it's content. + * + * @param string $path + * @param string|resource $content + * + * @return string|null MIME Type or NULL if no extension detected + */ + public static function guessMimeType($path, $content) + { + $mimeType = MimeType::detectByContent($content); + + if ( ! (empty($mimeType) || in_array($mimeType, ['application/x-empty', 'text/plain', 'text/x-asm']))) { + return $mimeType; + } + + return MimeType::detectByFilename($path); + } + + /** + * Emulate directories. + * + * @param array $listing + * + * @return array listing with emulated directories + */ + public static function emulateDirectories(array $listing) + { + $directories = []; + $listedDirectories = []; + + foreach ($listing as $object) { + list($directories, $listedDirectories) = static::emulateObjectDirectories( + $object, + $directories, + $listedDirectories + ); + } + + $directories = array_diff(array_unique($directories), array_unique($listedDirectories)); + + foreach ($directories as $directory) { + $listing[] = static::pathinfo($directory) + ['type' => 'dir']; + } + + return $listing; + } + + /** + * Ensure a Config instance. + * + * @param null|array|Config $config + * + * @return Config config instance + * + * @throw LogicException + */ + public static function ensureConfig($config) + { + if ($config === null) { + return new Config(); + } + + if ($config instanceof Config) { + return $config; + } + + if (is_array($config)) { + return new Config($config); + } + + throw new LogicException('A config should either be an array or a Flysystem\Config object.'); + } + + /** + * Rewind a stream. + * + * @param resource $resource + */ + public static function rewindStream($resource) + { + if (ftell($resource) !== 0 && static::isSeekableStream($resource)) { + rewind($resource); + } + } + + public static function isSeekableStream($resource) + { + $metadata = stream_get_meta_data($resource); + + return $metadata['seekable']; + } + + /** + * Get the size of a stream. + * + * @param resource $resource + * + * @return int stream size + */ + public static function getStreamSize($resource) + { + $stat = fstat($resource); + + return $stat['size']; + } + + /** + * Emulate the directories of a single object. + * + * @param array $object + * @param array $directories + * @param array $listedDirectories + * + * @return array + */ + protected static function emulateObjectDirectories(array $object, array $directories, array $listedDirectories) + { + if ($object['type'] === 'dir') { + $listedDirectories[] = $object['path']; + } + + if (empty($object['dirname'])) { + return [$directories, $listedDirectories]; + } + + $parent = $object['dirname']; + + while ( ! empty($parent) && ! in_array($parent, $directories)) { + $directories[] = $parent; + $parent = static::dirname($parent); + } + + if (isset($object['type']) && $object['type'] === 'dir') { + $listedDirectories[] = $object['path']; + + return [$directories, $listedDirectories]; + } + + return [$directories, $listedDirectories]; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Util/ContentListingFormatter.php b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Util/ContentListingFormatter.php new file mode 100644 index 0000000..db453c4 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Util/ContentListingFormatter.php @@ -0,0 +1,119 @@ +directory = $directory; + $this->recursive = $recursive; + } + + /** + * Format contents listing. + * + * @param array $listing + * + * @return array + */ + public function formatListing(array $listing) + { + $listing = array_values( + array_map( + [$this, 'addPathInfo'], + array_filter($listing, [$this, 'isEntryOutOfScope']) + ) + ); + + return $this->sortListing($listing); + } + + private function addPathInfo(array $entry) + { + return $entry + Util::pathinfo($entry['path']); + } + + /** + * Determine if the entry is out of scope. + * + * @param array $entry + * + * @return bool + */ + private function isEntryOutOfScope(array $entry) + { + if (empty($entry['path']) && $entry['path'] !== '0') { + return false; + } + + if ($this->recursive) { + return $this->residesInDirectory($entry); + } + + return $this->isDirectChild($entry); + } + + /** + * Check if the entry resides within the parent directory. + * + * @param $entry + * + * @return bool + */ + private function residesInDirectory(array $entry) + { + if ($this->directory === '') { + return true; + } + + return strpos($entry['path'], $this->directory . '/') === 0; + } + + /** + * Check if the entry is a direct child of the directory. + * + * @param $entry + * + * @return bool + */ + private function isDirectChild(array $entry) + { + return Util::dirname($entry['path']) === $this->directory; + } + + /** + * @param array $listing + * + * @return array + */ + private function sortListing(array $listing) + { + usort( + $listing, + function ($a, $b) { + return strcasecmp($a['path'], $b['path']); + } + ); + + return $listing; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Util/MimeType.php b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Util/MimeType.php new file mode 100644 index 0000000..cb0d1da --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Util/MimeType.php @@ -0,0 +1,213 @@ +buffer($content); + + return $mimeType ?: null; + } + + /** + * Detects MIME Type based on file extension. + * + * @param string $extension + * + * @return string|null MIME Type or NULL if no extension detected + */ + public static function detectByFileExtension($extension) + { + static $extensionToMimeTypeMap; + + if (! $extensionToMimeTypeMap) { + $extensionToMimeTypeMap = static::getExtensionToMimeTypeMap(); + } + + if (isset($extensionToMimeTypeMap[$extension])) { + return $extensionToMimeTypeMap[$extension]; + } + + return 'text/plain'; + } + + /** + * @param string $filename + * + * @return string + */ + public static function detectByFilename($filename) + { + $extension = pathinfo($filename, PATHINFO_EXTENSION); + + return empty($extension) ? 'text/plain' : static::detectByFileExtension($extension); + } + + /** + * @return array Map of file extension to MIME Type + */ + public static function getExtensionToMimeTypeMap() + { + return [ + 'hqx' => 'application/mac-binhex40', + 'cpt' => 'application/mac-compactpro', + 'csv' => 'text/x-comma-separated-values', + 'bin' => 'application/octet-stream', + 'dms' => 'application/octet-stream', + 'lha' => 'application/octet-stream', + 'lzh' => 'application/octet-stream', + 'exe' => 'application/octet-stream', + 'class' => 'application/octet-stream', + 'psd' => 'application/x-photoshop', + 'so' => 'application/octet-stream', + 'sea' => 'application/octet-stream', + 'dll' => 'application/octet-stream', + 'oda' => 'application/oda', + 'pdf' => 'application/pdf', + 'ai' => 'application/pdf', + 'eps' => 'application/postscript', + 'ps' => 'application/postscript', + 'smi' => 'application/smil', + 'smil' => 'application/smil', + 'mif' => 'application/vnd.mif', + 'xls' => 'application/vnd.ms-excel', + 'ppt' => 'application/powerpoint', + 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', + 'wbxml' => 'application/wbxml', + 'wmlc' => 'application/wmlc', + 'dcr' => 'application/x-director', + 'dir' => 'application/x-director', + 'dxr' => 'application/x-director', + 'dvi' => 'application/x-dvi', + 'gtar' => 'application/x-gtar', + 'gz' => 'application/x-gzip', + 'gzip' => 'application/x-gzip', + 'php' => 'application/x-httpd-php', + 'php4' => 'application/x-httpd-php', + 'php3' => 'application/x-httpd-php', + 'phtml' => 'application/x-httpd-php', + 'phps' => 'application/x-httpd-php-source', + 'js' => 'application/javascript', + 'swf' => 'application/x-shockwave-flash', + 'sit' => 'application/x-stuffit', + 'tar' => 'application/x-tar', + 'tgz' => 'application/x-tar', + 'z' => 'application/x-compress', + 'xhtml' => 'application/xhtml+xml', + 'xht' => 'application/xhtml+xml', + 'zip' => 'application/x-zip', + 'rar' => 'application/x-rar', + 'mid' => 'audio/midi', + 'midi' => 'audio/midi', + 'mpga' => 'audio/mpeg', + 'mp2' => 'audio/mpeg', + 'mp3' => 'audio/mpeg', + 'aif' => 'audio/x-aiff', + 'aiff' => 'audio/x-aiff', + 'aifc' => 'audio/x-aiff', + 'ram' => 'audio/x-pn-realaudio', + 'rm' => 'audio/x-pn-realaudio', + 'rpm' => 'audio/x-pn-realaudio-plugin', + 'ra' => 'audio/x-realaudio', + 'rv' => 'video/vnd.rn-realvideo', + 'wav' => 'audio/x-wav', + 'jpg' => 'image/jpeg', + 'jpeg' => 'image/jpeg', + 'jpe' => 'image/jpeg', + 'png' => 'image/png', + 'gif' => 'image/gif', + 'bmp' => 'image/bmp', + 'tiff' => 'image/tiff', + 'tif' => 'image/tiff', + 'svg' => 'image/svg+xml', + 'css' => 'text/css', + 'html' => 'text/html', + 'htm' => 'text/html', + 'shtml' => 'text/html', + 'txt' => 'text/plain', + 'text' => 'text/plain', + 'log' => 'text/plain', + 'rtx' => 'text/richtext', + 'rtf' => 'text/rtf', + 'xml' => 'application/xml', + 'xsl' => 'application/xml', + 'mpeg' => 'video/mpeg', + 'mpg' => 'video/mpeg', + 'mpe' => 'video/mpeg', + 'qt' => 'video/quicktime', + 'mov' => 'video/quicktime', + 'avi' => 'video/x-msvideo', + 'movie' => 'video/x-sgi-movie', + 'doc' => 'application/msword', + 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'dot' => 'application/msword', + 'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'word' => 'application/msword', + 'xl' => 'application/excel', + 'eml' => 'message/rfc822', + 'json' => 'application/json', + 'pem' => 'application/x-x509-user-cert', + 'p10' => 'application/x-pkcs10', + 'p12' => 'application/x-pkcs12', + 'p7a' => 'application/x-pkcs7-signature', + 'p7c' => 'application/pkcs7-mime', + 'p7m' => 'application/pkcs7-mime', + 'p7r' => 'application/x-pkcs7-certreqresp', + 'p7s' => 'application/pkcs7-signature', + 'crt' => 'application/x-x509-ca-cert', + 'crl' => 'application/pkix-crl', + 'der' => 'application/x-x509-ca-cert', + 'kdb' => 'application/octet-stream', + 'pgp' => 'application/pgp', + 'gpg' => 'application/gpg-keys', + 'sst' => 'application/octet-stream', + 'csr' => 'application/octet-stream', + 'rsa' => 'application/x-pkcs7', + 'cer' => 'application/pkix-cert', + '3g2' => 'video/3gpp2', + '3gp' => 'video/3gp', + 'mp4' => 'video/mp4', + 'm4a' => 'audio/x-m4a', + 'f4v' => 'video/mp4', + 'webm' => 'video/webm', + 'aac' => 'audio/x-acc', + 'm4u' => 'application/vnd.mpegurl', + 'm3u' => 'text/plain', + 'xspf' => 'application/xspf+xml', + 'vlc' => 'application/videolan', + 'wmv' => 'video/x-ms-wmv', + 'au' => 'audio/x-au', + 'ac3' => 'audio/ac3', + 'flac' => 'audio/x-flac', + 'ogg' => 'audio/ogg', + 'kmz' => 'application/vnd.google-earth.kmz', + 'kml' => 'application/vnd.google-earth.kml+xml', + 'ics' => 'text/calendar', + 'zsh' => 'text/x-scriptzsh', + '7zip' => 'application/x-7z-compressed', + 'cdr' => 'application/cdr', + 'wma' => 'audio/x-ms-wma', + 'jar' => 'application/java-archive', + ]; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Util/StreamHasher.php b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Util/StreamHasher.php new file mode 100644 index 0000000..8dc96ca --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/league/flysystem/src/Util/StreamHasher.php @@ -0,0 +1,36 @@ +algo = $algo; + } + + /** + * @param $resource + * + * @return string + */ + public function hash($resource) + { + rewind($resource); + $context = hash_init($this->algo); + hash_update_stream($context, $resource); + fclose($resource); + + return hash_final($context); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/BlobRestProxy.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/BlobRestProxy.php new file mode 100644 index 0000000..5794c64 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/BlobRestProxy.php @@ -0,0 +1,2433 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Validate; +use WindowsAzure\Common\Models\ServiceProperties; +use WindowsAzure\Common\Internal\ServiceRestProxy; +use WindowsAzure\Blob\Internal\IBlob; +use WindowsAzure\Blob\Models\BlobServiceOptions; +use WindowsAzure\Common\Models\GetServicePropertiesResult; +use WindowsAzure\Blob\Models\ListContainersOptions; +use WindowsAzure\Blob\Models\ListContainersResult; +use WindowsAzure\Blob\Models\CreateContainerOptions; +use WindowsAzure\Blob\Models\GetContainerPropertiesResult; +use WindowsAzure\Blob\Models\GetContainerACLResult; +use WindowsAzure\Blob\Models\SetContainerMetadataOptions; +use WindowsAzure\Blob\Models\DeleteContainerOptions; +use WindowsAzure\Blob\Models\ListBlobsOptions; +use WindowsAzure\Blob\Models\ListBlobsResult; +use WindowsAzure\Blob\Models\BlobType; +use WindowsAzure\Blob\Models\Block; +use WindowsAzure\Blob\Models\CreateBlobOptions; +use WindowsAzure\Blob\Models\BlobProperties; +use WindowsAzure\Blob\Models\GetBlobPropertiesOptions; +use WindowsAzure\Blob\Models\GetBlobPropertiesResult; +use WindowsAzure\Blob\Models\SetBlobPropertiesOptions; +use WindowsAzure\Blob\Models\SetBlobPropertiesResult; +use WindowsAzure\Blob\Models\GetBlobMetadataOptions; +use WindowsAzure\Blob\Models\GetBlobMetadataResult; +use WindowsAzure\Blob\Models\SetBlobMetadataOptions; +use WindowsAzure\Blob\Models\SetBlobMetadataResult; +use WindowsAzure\Blob\Models\GetBlobOptions; +use WindowsAzure\Blob\Models\GetBlobResult; +use WindowsAzure\Blob\Models\DeleteBlobOptions; +use WindowsAzure\Blob\Models\LeaseMode; +use WindowsAzure\Blob\Models\AcquireLeaseOptions; +use WindowsAzure\Blob\Models\AcquireLeaseResult; +use WindowsAzure\Blob\Models\CreateBlobPagesOptions; +use WindowsAzure\Blob\Models\CreateBlobPagesResult; +use WindowsAzure\Blob\Models\PageWriteOption; +use WindowsAzure\Blob\Models\ListPageBlobRangesOptions; +use WindowsAzure\Blob\Models\ListPageBlobRangesResult; +use WindowsAzure\Blob\Models\CreateBlobBlockOptions; +use WindowsAzure\Blob\Models\CommitBlobBlocksOptions; +use WindowsAzure\Blob\Models\BlockList; +use WindowsAzure\Blob\Models\ListBlobBlocksOptions; +use WindowsAzure\Blob\Models\ListBlobBlocksResult; +use WindowsAzure\Blob\Models\CopyBlobOptions; +use WindowsAzure\Blob\Models\CreateBlobSnapshotOptions; +use WindowsAzure\Blob\Models\CreateBlobSnapshotResult; +use WindowsAzure\Blob\Models\PageRange; +use WindowsAzure\Blob\Models\CopyBlobResult; +use WindowsAzure\Blob\Models\BreakLeaseResult; + +/** + * This class constructs HTTP requests and receive HTTP responses for blob + * service layer. + * + * @category Microsoft + * @package WindowsAzure\Blob + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class BlobRestProxy extends ServiceRestProxy implements IBlob +{ + /** + * @var int Defaults to 32MB + */ + private $_SingleBlobUploadThresholdInBytes = 33554432 ; + + /** + * Get the value for SingleBlobUploadThresholdInBytes + * + * @return int + */ + public function getSingleBlobUploadThresholdInBytes() + { + return $this->_SingleBlobUploadThresholdInBytes; + } + + /** + * Set the value for SingleBlobUploadThresholdInBytes, Max 64MB + * + * @param int $val The max size to send as a single blob block + * + * @return none + */ + public function setSingleBlobUploadThresholdInBytes($val) + { + if ($val > 67108864) { + // What should the proper action here be? + $val = 67108864; + } elseif ($val < 1) { + // another spot that could use looking at + $val = 33554432; + } + $this->_SingleBlobUploadThresholdInBytes = $val; + } + + /** + * Gets the copy blob source name with specified parameters. + * + * @param string $containerName The name of the container. + * @param string $blobName The name of the blob. + * @param Models\CopyBlobOptions $options The optional parameters. + * + * @return string + */ + private function _getCopyBlobSourceName($containerName, $blobName, $options) + { + $sourceName = '/' . $this->getAccountName(); + $sourceName .= '/' . $this->_createPath($containerName, $blobName); + + if (!is_null($options->getSourceSnapshot())) { + $sourceName .= '?snapshot=' . $options->getSourceSnapshot(); + } + + return $sourceName; + } + + /** + * Creates URI path for blob. + * + * @param string $container The container name. + * @param string $blob The blob name. + * + * @return string + */ + private function _createPath($container, $blob) + { + $encodedBlob = urlencode($blob); + // Unencode the forward slashes to match what the server expects. + $encodedBlob = str_replace('%2F', '/', $encodedBlob); + // Unencode the backward slashes to match what the server expects. + $encodedBlob = str_replace('%5C', '/', $encodedBlob); + // Re-encode the spaces (encoded as space) to the % encoding. + $encodedBlob = str_replace('+', '%20', $encodedBlob); + + // Empty container means accessing default container + if (empty($container)) { + return $encodedBlob; + } else { + return $container . '/' . $encodedBlob; + } + } + + /** + * Creates GetBlobPropertiesResult from headers array. + * + * @param array $headers The HTTP response headers array. + * + * @return GetBlobPropertiesResult + */ + private function _getBlobPropertiesResultFromResponse($headers) + { + $result = new GetBlobPropertiesResult(); + $properties = new BlobProperties(); + $d = $headers[Resources::LAST_MODIFIED]; + $bType = $headers[Resources::X_MS_BLOB_TYPE]; + $cLength = intval($headers[Resources::CONTENT_LENGTH]); + $lStatus = Utilities::tryGetValue($headers, Resources::X_MS_LEASE_STATUS); + $cType = Utilities::tryGetValue($headers, Resources::CONTENT_TYPE); + $cMD5 = Utilities::tryGetValue($headers, Resources::CONTENT_MD5); + $cEncoding = Utilities::tryGetValue($headers, Resources::CONTENT_ENCODING); + $cLanguage = Utilities::tryGetValue($headers, Resources::CONTENT_LANGUAGE); + $cControl = Utilities::tryGetValue($headers, Resources::CACHE_CONTROL); + $etag = $headers[Resources::ETAG]; + $metadata = $this->getMetadataArray($headers); + + if (array_key_exists(Resources::X_MS_BLOB_SEQUENCE_NUMBER, $headers)) { + $sNumber = intval($headers[Resources::X_MS_BLOB_SEQUENCE_NUMBER]); + $properties->setSequenceNumber($sNumber); + } + + $properties->setBlobType($bType); + $properties->setCacheControl($cControl); + $properties->setContentEncoding($cEncoding); + $properties->setContentLanguage($cLanguage); + $properties->setContentLength($cLength); + $properties->setContentMD5($cMD5); + $properties->setContentType($cType); + $properties->setETag($etag); + $properties->setLastModified(Utilities::rfc1123ToDateTime($d)); + $properties->setLeaseStatus($lStatus); + + $result->setProperties($properties); + $result->setMetadata($metadata); + + return $result; + } + + /** + * Helper method for getContainerProperties and getContainerMetadata. + * + * @param string $container The container name. + * @param Models\BlobServiceOptions $options The optional parameters. + * @param string $operation The operation string. Should be + * 'metadata' to get metadata. + * + * @return Models\GetContainerPropertiesResult + */ + private function _getContainerPropertiesImpl($container, $options = null, + $operation = null + ) { + Validate::isString($container, 'container'); + + $method = Resources::HTTP_GET; + $headers = array(); + $queryParams = array(); + $postParams = array(); + $path = $container; + $statusCode = Resources::STATUS_OK; + + if (is_null($options)) { + $options = new BlobServiceOptions(); + } + + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_REST_TYPE, + 'container' + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_COMP, + $operation + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + + $response = $this->send( + $method, + $headers, + $queryParams, + $postParams, + $path, + $statusCode + ); + + $result = new GetContainerPropertiesResult(); + $metadata = $this->getMetadataArray($response->getHeader()); + $date = $response->getHeader(Resources::LAST_MODIFIED); + $date = Utilities::rfc1123ToDateTime($date); + $result->setETag($response->getHeader(Resources::ETAG)); + $result->setMetadata($metadata); + $result->setLastModified($date); + + return $result; + } + + /** + * Adds optional create blob headers. + * + * @param CreateBlobOptions $options The optional parameters. + * @param array $headers The HTTP request headers. + * + * @return array + */ + private function _addCreateBlobOptionalHeaders($options, $headers) + { + $contentType = $options->getContentType(); + $metadata = $options->getMetadata(); + $blobContentType = $options->getBlobContentType(); + $blobContentEncoding = $options->getBlobContentEncoding(); + $blobContentLanguage = $options->getBlobContentLanguage(); + $blobContentMD5 = $options->getBlobContentMD5(); + $blobCacheControl = $options->getBlobCacheControl(); + $leaseId = $options->getLeaseId(); + + if (!is_null($contentType)) { + $this->addOptionalHeader( + $headers, + Resources::CONTENT_TYPE, + $options->getContentType() + ); + } else { + $this->addOptionalHeader( + $headers, + Resources::CONTENT_TYPE, + Resources::BINARY_FILE_TYPE + ); + } + $headers = $this->addMetadataHeaders($headers, $metadata); + $headers = $this->addOptionalAccessConditionHeader( + $headers, $options->getAccessCondition() + ); + + $this->addOptionalHeader( + $headers, + Resources::CONTENT_ENCODING, + $options->getContentEncoding() + ); + $this->addOptionalHeader( + $headers, + Resources::CONTENT_LANGUAGE, + $options->getContentLanguage() + ); + $this->addOptionalHeader( + $headers, + Resources::CONTENT_MD5, + $options->getContentMD5() + ); + $this->addOptionalHeader( + $headers, + Resources::CACHE_CONTROL, + $options->getCacheControl() + ); + + $this->addOptionalHeader( + $headers, + Resources::X_MS_LEASE_ID, + $leaseId + ); + $this->addOptionalHeader( + $headers, + Resources::X_MS_BLOB_CONTENT_TYPE, + $blobContentType + ); + $this->addOptionalHeader( + $headers, + Resources::X_MS_BLOB_CONTENT_ENCODING, + $blobContentEncoding + ); + $this->addOptionalHeader( + $headers, + Resources::X_MS_BLOB_CONTENT_LANGUAGE, + $blobContentLanguage + ); + $this->addOptionalHeader( + $headers, + Resources::X_MS_BLOB_CONTENT_MD5, + $blobContentMD5 + ); + $this->addOptionalHeader( + $headers, + Resources::X_MS_BLOB_CACHE_CONTROL, + $blobCacheControl + ); + + return $headers; + } + + /** + * Adds Range header to the headers array. + * + * @param array $headers The HTTP request headers. + * @param integer $start The start byte. + * @param integer $end The end byte. + * + * @return array + */ + private function _addOptionalRangeHeader($headers, $start, $end) + { + if (!is_null($start) || !is_null($end)) { + $range = $start . '-' . $end; + $rangeValue = 'bytes=' . $range; + $this->addOptionalHeader($headers, Resources::RANGE, $rangeValue); + } + + return $headers; + } + + /** + * Does the actual work for leasing a blob. + * + * @param string $leaseAction The lease action string. + * @param string $container The container name. + * @param string $blob The blob to lease name. + * @param string $leaseId The existing lease id. + * @param BlobServiceOptions $options The optional parameters. + * @param AccessCondition $accessCondition The access conditions. + * + * @return array + */ + private function _putLeaseImpl($leaseAction, $container, $blob, $leaseId, + $options, $accessCondition = null + ) { + Validate::isString($blob, 'blob'); + Validate::notNullOrEmpty($blob, 'blob'); + Validate::isString($container, 'container'); + + $method = Resources::HTTP_PUT; + $headers = array(); + $queryParams = array(); + $postParams = array(); + $path = $this->_createPath($container, $blob); + $statusCode = Resources::EMPTY_STRING; + + switch ($leaseAction) { + case LeaseMode::ACQUIRE_ACTION: + $statusCode = Resources::STATUS_CREATED; + break; + case LeaseMode::RENEW_ACTION: + $statusCode = Resources::STATUS_OK; + break; + case LeaseMode::RELEASE_ACTION: + $statusCode = Resources::STATUS_OK; + break; + case LeaseMode::BREAK_ACTION: + $statusCode = Resources::STATUS_ACCEPTED; + break; + default: + throw new \Exception(Resources::NOT_IMPLEMENTED_MSG); + } + + if (!is_null($options)) { + $options = new BlobServiceOptions(); + } + + $headers = $this->addOptionalAccessConditionHeader( + $headers, $accessCondition + ); + + $this->addOptionalHeader($headers, Resources::X_MS_LEASE_ID, $leaseId); + $this->addOptionalHeader( + $headers, + Resources::X_MS_LEASE_ACTION, + $leaseAction + ); + $this->addOptionalQueryParam($queryParams, Resources::QP_COMP, 'lease'); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + + $response = $this->send( + $method, + $headers, + $queryParams, + $postParams, + $path, + $statusCode + ); + + return $response->getHeader(); + } + + /** + * Does actual work for create and clear blob pages. + * + * @param string $action Either clear or create. + * @param string $container The container name. + * @param string $blob The blob name. + * @param PageRange $range The page ranges. + * @param string|resource $content The content stream. + * @param CreateBlobPagesOptions $options The optional parameters. + * + * @return CreateBlobPagesResult + */ + private function _updatePageBlobPagesImpl($action, $container, $blob, $range, + $content, $options = null + ) { + Validate::isString($blob, 'blob'); + Validate::notNullOrEmpty($blob, 'blob'); + Validate::isString($container, 'container'); + Validate::isTrue( + $range instanceof PageRange, + sprintf( + Resources::INVALID_PARAM_MSG, + 'range', + get_class(new PageRange()) + ) + ); + Validate::isTrue( + is_string($content) || is_resource($content), + sprintf(Resources::INVALID_PARAM_MSG, 'content', 'string|resource') + ); + + $method = Resources::HTTP_PUT; + $headers = array(); + $queryParams = array(); + $postParams = array(); + $path = $this->_createPath($container, $blob); + $statusCode = Resources::STATUS_CREATED; + // If read file failed for any reason it will throw an exception. + $body = is_resource($content) ? stream_get_contents($content) : $content; + + if (is_null($options)) { + $options = new CreateBlobPagesOptions(); + } + + $headers = $this->_addOptionalRangeHeader( + $headers, $range->getStart(), $range->getEnd() + ); + + $headers = $this->addOptionalAccessConditionHeader( + $headers, $options->getAccessCondition() + ); + + $this->addOptionalHeader( + $headers, + Resources::X_MS_LEASE_ID, + $options->getLeaseId() + ); + $this->addOptionalHeader( + $headers, + Resources::CONTENT_MD5, + $options->getContentMD5() + ); + $this->addOptionalHeader( + $headers, + Resources::X_MS_PAGE_WRITE, + $action + ); + $this->addOptionalHeader( + $headers, + Resources::CONTENT_TYPE, + Resources::URL_ENCODED_CONTENT_TYPE + ); + $this->addOptionalQueryParam($queryParams, Resources::QP_COMP, 'page'); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + + $response = $this->send( + $method, + $headers, + $queryParams, + $postParams, + $path, + $statusCode, + $body + ); + + return CreateBlobPagesResult::create($response->getHeader()); + } + + /** + * Gets the properties of the Blob service. + * + * @param Models\BlobServiceOptions $options The optional parameters. + * + * @return WindowsAzure\Common\Models\GetServicePropertiesResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/hh452239.aspx + */ + public function getServiceProperties($options = null) + { + $method = Resources::HTTP_GET; + $headers = array(); + $queryParams = array(); + $postParams = array(); + $path = Resources::EMPTY_STRING; + $statusCode = Resources::STATUS_OK; + + if (is_null($options)) { + $options = new BlobServiceOptions(); + } + + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_REST_TYPE, + 'service' + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_COMP, + 'properties' + ); + + $response = $this->send( + $method, + $headers, + $queryParams, + $postParams, + $path, + $statusCode + ); + $parsed = $this->dataSerializer->unserialize($response->getBody()); + + return GetServicePropertiesResult::create($parsed); + } + + /** + * Sets the properties of the Blob service. + * + * It's recommended to use getServiceProperties, alter the returned object and + * then use setServiceProperties with this altered object. + * + * @param ServiceProperties $serviceProperties The service properties. + * @param Models\BlobServiceOptions $options The optional parameters. + * + * @return none + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/hh452235.aspx + */ + public function setServiceProperties($serviceProperties, $options = null) + { + Validate::isTrue( + $serviceProperties instanceof ServiceProperties, + Resources::INVALID_SVC_PROP_MSG + ); + + $method = Resources::HTTP_PUT; + $headers = array(); + $queryParams = array(); + $postParams = array(); + $statusCode = Resources::STATUS_ACCEPTED; + $path = Resources::EMPTY_STRING; + $body = $serviceProperties->toXml($this->dataSerializer); + + if (is_null($options)) { + $options = new BlobServiceOptions(); + } + + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_REST_TYPE, + 'service' + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_COMP, + 'properties' + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + $this->addOptionalHeader( + $headers, + Resources::CONTENT_TYPE, + Resources::URL_ENCODED_CONTENT_TYPE + ); + + $this->send( + $method, + $headers, + $queryParams, + $postParams, + $path, + $statusCode, + $body + ); + } + + /** + * Lists all of the containers in the given storage account. + * + * @param Models\ListContainersOptions $options The optional parameters. + * + * @return WindowsAzure\Blob\Models\ListContainersResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179352.aspx + */ + public function listContainers($options = null) + { + $method = Resources::HTTP_GET; + $headers = array(); + $queryParams = array(); + $postParams = array(); + $path = Resources::EMPTY_STRING; + $statusCode = Resources::STATUS_OK; + + if (is_null($options)) { + $options = new ListContainersOptions(); + } + + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_COMP, + 'list' + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_PREFIX, + $options->getPrefix() + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_MARKER, + $options->getMarker() + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_MAX_RESULTS, + $options->getMaxResults() + ); + $isInclude = $options->getIncludeMetadata(); + $isInclude = $isInclude ? 'metadata' : null; + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_INCLUDE, + $isInclude + ); + + $response = $this->send( + $method, + $headers, + $queryParams, + $postParams, + $path, + $statusCode + ); + + $parsed = $this->dataSerializer->unserialize($response->getBody()); + + return ListContainersResult::create($parsed); + } + + /** + * Creates a new container in the given storage account. + * + * @param string $container The container name. + * @param Models\CreateContainerOptions $options The optional parameters. + * + * @return none + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179468.aspx + */ + public function createContainer($container, $options = null) + { + Validate::isString($container, 'container'); + Validate::notNullOrEmpty($container, 'container'); + + $method = Resources::HTTP_PUT; + $headers = array(); + $postParams = array(); + $queryParams = array(Resources::QP_REST_TYPE => 'container'); + $path = $container; + $statusCode = Resources::STATUS_CREATED; + + if (is_null($options)) { + $options = new CreateContainerOptions(); + } + + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + + $metadata = $options->getMetadata(); + $headers = $this->generateMetadataHeaders($metadata); + $this->addOptionalHeader( + $headers, + Resources::X_MS_BLOB_PUBLIC_ACCESS, + $options->getPublicAccess() + ); + + $this->send( + $method, + $headers, + $queryParams, + $postParams, + $path, + $statusCode + ); + } + + /** + * Creates a new container in the given storage account. + * + * @param string $container The container name. + * @param Models\DeleteContainerOptions $options The optional parameters. + * + * @return none + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179408.aspx + */ + public function deleteContainer($container, $options = null) + { + Validate::isString($container, 'container'); + Validate::notNullOrEmpty($container, 'container'); + + $method = Resources::HTTP_DELETE; + $headers = array(); + $postParams = array(); + $queryParams = array(); + $path = $container; + $statusCode = Resources::STATUS_ACCEPTED; + + if (is_null($options)) { + $options = new DeleteContainerOptions(); + } + + $headers = $this->addOptionalAccessConditionHeader( + $headers, $options->getAccessCondition() + ); + + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_REST_TYPE, + 'container' + ); + + $this->send( + $method, + $headers, + $queryParams, + $postParams, + $path, + $statusCode + ); + } + + /** + * Returns all properties and metadata on the container. + * + * @param string $container name + * @param Models\BlobServiceOptions $options optional parameters + * + * @return Models\GetContainerPropertiesResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179370.aspx + */ + public function getContainerProperties($container, $options = null) + { + return $this->_getContainerPropertiesImpl($container, $options); + } + + /** + * Returns only user-defined metadata for the specified container. + * + * @param string $container name + * @param Models\BlobServiceOptions $options optional parameters + * + * @return Models\GetContainerPropertiesResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691976.aspx + */ + public function getContainerMetadata($container, $options = null) + { + return $this->_getContainerPropertiesImpl($container, $options, 'metadata'); + } + + /** + * Gets the access control list (ACL) and any container-level access policies + * for the container. + * + * @param string $container The container name. + * @param Models\BlobServiceOptions $options The optional parameters. + * + * @return Models\GetContainerAclResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179469.aspx + */ + public function getContainerAcl($container, $options = null) + { + Validate::isString($container, 'container'); + + $method = Resources::HTTP_GET; + $headers = array(); + $postParams = array(); + $queryParams = array(); + $path = $container; + $statusCode = Resources::STATUS_OK; + + if (is_null($options)) { + $options = new BlobServiceOptions(); + } + + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_REST_TYPE, + 'container' + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_COMP, + 'acl' + ); + + $response = $this->send( + $method, + $headers, + $queryParams, + $postParams, + $path, + $statusCode + ); + + $access = $response->getHeader(Resources::X_MS_BLOB_PUBLIC_ACCESS); + $etag = $response->getHeader(Resources::ETAG); + $modified = $response->getHeader(Resources::LAST_MODIFIED); + $modifiedDate = Utilities::convertToDateTime($modified); + $parsed = $this->dataSerializer->unserialize($response->getBody()); + + return GetContainerAclResult::create($access, $etag, $modifiedDate, $parsed); + } + + /** + * Sets the ACL and any container-level access policies for the container. + * + * @param string $container name + * @param Models\ContainerAcl $acl access control list for container + * @param Models\BlobServiceOptions $options optional parameters + * + * @return none + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179391.aspx + */ + public function setContainerAcl($container, $acl, $options = null) + { + Validate::isString($container, 'container'); + Validate::notNullOrEmpty($acl, 'acl'); + + $method = Resources::HTTP_PUT; + $headers = array(); + $postParams = array(); + $queryParams = array(); + $path = $container; + $statusCode = Resources::STATUS_OK; + $body = $acl->toXml($this->dataSerializer); + + if (is_null($options)) { + $options = new BlobServiceOptions(); + } + + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_REST_TYPE, + 'container' + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_COMP, + 'acl' + ); + $this->addOptionalHeader( + $headers, + Resources::X_MS_BLOB_PUBLIC_ACCESS, + $acl->getPublicAccess() + ); + $this->addOptionalHeader( + $headers, + Resources::CONTENT_TYPE, + Resources::URL_ENCODED_CONTENT_TYPE + ); + + $this->send( + $method, + $headers, + $queryParams, + $postParams, + $path, + $statusCode, + $body + ); + } + + /** + * Sets metadata headers on the container. + * + * @param string $container name + * @param array $metadata metadata key/value pair. + * @param Models\SetContainerMetadataOptions $options optional parameters + * + * @return none + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179362.aspx + */ + public function setContainerMetadata($container, $metadata, $options = null) + { + Validate::isString($container, 'container'); + $this->validateMetadata($metadata); + + $method = Resources::HTTP_PUT; + $headers = $this->generateMetadataHeaders($metadata); + $postParams = array(); + $queryParams = array(); + $path = $container; + $statusCode = Resources::STATUS_OK; + + if (is_null($options)) { + $options = new SetContainerMetadataOptions(); + } + + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_REST_TYPE, + 'container' + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_COMP, + 'metadata' + ); + + $headers = $this->addOptionalAccessConditionHeader( + $headers, + $options->getAccessCondition() + ); + + $this->send( + $method, + $headers, + $queryParams, + $postParams, + $path, + $statusCode + ); + } + + /** + * Lists all of the blobs in the given container. + * + * @param string $container The container name. + * @param Models\ListBlobsOptions $options The optional parameters. + * + * @return Models\ListBlobsResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd135734.aspx + */ + public function listBlobs($container, $options = null) + { + Validate::isString($container, 'container'); + + $method = Resources::HTTP_GET; + $headers = array(); + $postParams = array(); + $queryParams = array(); + $path = $container; + $statusCode = Resources::STATUS_OK; + + if (is_null($options)) { + $options = new ListBlobsOptions(); + } + + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_REST_TYPE, + 'container' + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_COMP, + 'list' + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_PREFIX, + str_replace('\\', '/', $options->getPrefix()) + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_MARKER, + $options->getMarker() + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_DELIMITER, + $options->getDelimiter() + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_MAX_RESULTS, + $options->getMaxResults() + ); + + $includeMetadata = $options->getIncludeMetadata(); + $includeSnapshots = $options->getIncludeSnapshots(); + $includeUncommittedBlobs = $options->getIncludeUncommittedBlobs(); + + $includeValue = $this->groupQueryValues( + array( + $includeMetadata ? 'metadata' : null, + $includeSnapshots ? 'snapshots' : null, + $includeUncommittedBlobs ? 'uncommittedblobs' : null + ) + ); + + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_INCLUDE, + $includeValue + ); + + $response = $this->send( + $method, + $headers, + $queryParams, + $postParams, + $path, + $statusCode + ); + + $parsed = $this->dataSerializer->unserialize($response->getBody()); + + return ListBlobsResult::create($parsed); + } + + /** + * Creates a new page blob. Note that calling createPageBlob to create a page + * blob only initializes the blob. + * To add content to a page blob, call createBlobPages method. + * + * @param string $container The container name. + * @param string $blob The blob name. + * @param integer $length Specifies the maximum size for the + * page blob, up to 1 TB. The page blob size must be aligned to a 512-byte + * boundary. + * @param Models\CreateBlobOptions $options The optional parameters. + * + * @return CopyBlobResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179451.aspx + */ + public function createPageBlob($container, $blob, $length, $options = null) + { + Validate::isString($container, 'container'); + Validate::isString($blob, 'blob'); + Validate::notNullOrEmpty($blob, 'blob'); + Validate::isInteger($length, 'length'); + Validate::notNull($length, 'length'); + + $method = Resources::HTTP_PUT; + $headers = array(); + $postParams = array(); + $queryParams = array(); + $path = $this->_createPath($container, $blob); + $statusCode = Resources::STATUS_CREATED; + + if (is_null($options)) { + $options = new CreateBlobOptions(); + } + + $this->addOptionalHeader( + $headers, + Resources::X_MS_BLOB_TYPE, + BlobType::PAGE_BLOB + ); + $this->addOptionalHeader( + $headers, + Resources::X_MS_BLOB_CONTENT_LENGTH, + $length + ); + $this->addOptionalHeader( + $headers, + Resources::X_MS_BLOB_SEQUENCE_NUMBER, + $options->getSequenceNumber() + ); + $headers = $this->_addCreateBlobOptionalHeaders($options, $headers); + + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + + $response = $this->send( + $method, + $headers, + $queryParams, + $postParams, + $path, + $statusCode + ); + + return CopyBlobResult::create($response->getHeader()); + } + + /** + * Creates a new block blob or updates the content of an existing block blob. + * + * Updating an existing block blob overwrites any existing metadata on the blob. + * Partial updates are not supported with createBlockBlob the content of the + * existing blob is overwritten with the content of the new blob. To perform a + * partial update of the content o f a block blob, use the createBlockList + * method. + * Note that the default content type is application/octet-stream. + * + * @param string $container The name of the container. + * @param string $blob The name of the blob. + * @param string|resource $content The content of the blob. + * @param Models\CreateBlobOptions $options The optional parameters. + * + * @return CopyBlobResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179451.aspx + */ + public function createBlockBlob($container, $blob, $content, $options = null) + { + Validate::isString($container, 'container'); + Validate::isString($blob, 'blob'); + Validate::notNullOrEmpty($blob, 'blob'); + Validate::isTrue( + is_string($content) || is_resource($content), + sprintf(Resources::INVALID_PARAM_MSG, 'content', 'string|resource') + ); + + $method = Resources::HTTP_PUT; + $headers = array(); + $postParams = array(); + $queryParams = array(); + $bodySize = 0; + $path = $this->_createPath($container, $blob); + $statusCode = Resources::STATUS_CREATED; + + if (is_null($options)) { + $options = new CreateBlobOptions(); + } + + if (is_resource($content)) { + $cStat = fstat($content); + // if the resource is a remote file, $cStat will be false + if ($cStat) { + $bodySize = $cStat['size']; + } + } else { + $bodySize = strlen($content); + } + + // if we have a size we can try to one shot this, else failsafe on block upload + if ($bodySize && $bodySize <= $this->_SingleBlobUploadThresholdInBytes) { + $headers = $this->_addCreateBlobOptionalHeaders($options, $headers); + + $this->addOptionalHeader( + $headers, + Resources::X_MS_BLOB_TYPE, + BlobType::BLOCK_BLOB + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + + // If read file failed for any reason it will throw an exception. + $body = is_resource($content) ? stream_get_contents($content) : $content; + + $response = $this->send( + $method, + $headers, + $queryParams, + $postParams, + $path, + $statusCode, + $body + ); + } else { + // This is for large or failsafe upload + $end = 0; + $counter = 0; + $body = ''; + $blockIds = array(); + // if threshold is lower than 4mb, honor threshold, else use 4mb + $blockSize = ($this->_SingleBlobUploadThresholdInBytes < 4194304) ? $this->_SingleBlobUploadThresholdInBytes : 4194304; + while(!$end) { + if (is_resource($content)) { + $body = fread($content, $blockSize); + if (feof($content)) { + $end = 1; + } + } else { + if (strlen($content) <= $blockSize) { + $body = $content; + $end = 1; + } else { + $body = substr($content, 0, $blockSize); + $content = substr_replace($content, '', 0, $blockSize); + } + } + $block = new Block(); + $block->setBlockId(base64_encode(str_pad($counter++, '0', 6))); + $block->setType('Uncommitted'); + array_push($blockIds, $block); + $this->createBlobBlock($container, $blob, $block->getBlockId(), $body); + } + $response = $this->commitBlobBlocks($container, $blob, $blockIds, $options); + } + return CopyBlobResult::create($response->getHeader()); + } + + /** + * Clears a range of pages from the blob. + * + * @param string $container name of the container + * @param string $blob name of the blob + * @param Models\PageRange $range Can be up to the value of the + * blob's full size. Note that ranges must be aligned to 512 (0-511, 512-1023) + * @param Models\CreateBlobPagesOptions $options optional parameters + * + * @return Models\CreateBlobPagesResult. + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691975.aspx + */ + public function clearBlobPages($container, $blob, $range, $options = null) + { + return $this->_updatePageBlobPagesImpl( + PageWriteOption::CLEAR_OPTION, + $container, + $blob, + $range, + Resources::EMPTY_STRING, + $options + ); + } + + /** + * Creates a range of pages to a page blob. + * + * @param string $container name of the container + * @param string $blob name of the blob + * @param Models\PageRange $range Can be up to 4 MB in size + * Note that ranges must be aligned to 512 (0-511, 512-1023) + * @param string $content the blob contents. + * @param Models\CreateBlobPagesOptions $options optional parameters + * + * @return Models\CreateBlobPagesResult. + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691975.aspx + */ + public function createBlobPages($container, $blob, $range, $content, + $options = null + ) { + return $this->_updatePageBlobPagesImpl( + PageWriteOption::UPDATE_OPTION, + $container, + $blob, + $range, + $content, + $options + ); + } + + /** + * Creates a new block to be committed as part of a block blob. + * + * @param string $container name of the container + * @param string $blob name of the blob + * @param string $blockId must be less than or equal to + * 64 bytes in size. For a given blob, the length of the value specified for the + * blockid parameter must be the same size for each block. + * @param string $content the blob block contents + * @param Models\CreateBlobBlockOptions $options optional parameters + * + * @return none + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd135726.aspx + */ + public function createBlobBlock($container, $blob, $blockId, $content, + $options = null + ) { + Validate::isString($container, 'container'); + Validate::isString($blob, 'blob'); + Validate::notNullOrEmpty($blob, 'blob'); + Validate::isString($blockId, 'blockId'); + Validate::notNullOrEmpty($blockId, 'blockId'); + Validate::isTrue( + is_string($content) || is_resource($content), + sprintf(Resources::INVALID_PARAM_MSG, 'content', 'string|resource') + ); + + $method = Resources::HTTP_PUT; + $headers = array(); + $postParams = array(); + $queryParams = array(); + $path = $this->_createPath($container, $blob); + $statusCode = Resources::STATUS_CREATED; + $body = $content; + + if (is_null($options)) { + $options = new CreateBlobBlockOptions(); + } + + $this->addOptionalHeader( + $headers, + Resources::X_MS_LEASE_ID, + $options->getLeaseId() + ); + $this->addOptionalHeader( + $headers, + Resources::CONTENT_MD5, + $options->getContentMD5() + ); + $this->addOptionalHeader( + $headers, + Resources::CONTENT_TYPE, + Resources::URL_ENCODED_CONTENT_TYPE + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_COMP, + 'block' + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_BLOCKID, + base64_encode($blockId) + ); + + $response = $this->send( + $method, + $headers, + $queryParams, + $postParams, + $path, + $statusCode, + $body + ); + + return CopyBlobResult::create($response->getHeader()); + } + + /** + * This method writes a blob by specifying the list of block IDs that make up the + * blob. In order to be written as part of a blob, a block must have been + * successfully written to the server in a prior createBlobBlock method. + * + * You can call Put Block List to update a blob by uploading only those blocks + * that have changed, then committing the new and existing blocks together. + * You can do this by specifying whether to commit a block from the committed + * block list or from the uncommitted block list, or to commit the most recently + * uploaded version of the block, whichever list it may belong to. + * + * @param string $container The container name. + * @param string $blob The blob name. + * @param Models\BlockList|array $blockList The block entries. + * @param Models\CommitBlobBlocksOptions $options The optional parameters. + * + * @return CopyBlobResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179467.aspx + */ + public function commitBlobBlocks($container, $blob, $blockList, $options = null) + { + Validate::isString($container, 'container'); + Validate::isString($blob, 'blob'); + Validate::notNullOrEmpty($blob, 'blob'); + Validate::isTrue( + $blockList instanceof BlockList || is_array($blockList), + sprintf( + Resources::INVALID_PARAM_MSG, + 'blockList', + get_class(new BlockList()) + ) + ); + + $method = Resources::HTTP_PUT; + $headers = array(); + $postParams = array(); + $queryParams = array(); + $path = $this->_createPath($container, $blob); + $statusCode = Resources::STATUS_CREATED; + $isArray = is_array($blockList); + $blockList = $isArray ? BlockList::create($blockList) : $blockList; + $body = $blockList->toXml($this->dataSerializer); + + if (is_null($options)) { + $options = new CommitBlobBlocksOptions(); + } + + $blobContentType = $options->getBlobContentType(); + $blobContentEncoding = $options->getBlobContentEncoding(); + $blobContentLanguage = $options->getBlobContentLanguage(); + $blobContentMD5 = $options->getBlobContentMD5(); + $blobCacheControl = $options->getBlobCacheControl(); + $leaseId = $options->getLeaseId(); + $contentType = Resources::URL_ENCODED_CONTENT_TYPE; + + $metadata = $options->getMetadata(); + $headers = $this->generateMetadataHeaders($metadata); + $headers = $this->addOptionalAccessConditionHeader( + $headers, $options->getAccessCondition() + ); + + $this->addOptionalHeader( + $headers, + Resources::X_MS_LEASE_ID, + $leaseId + ); + $this->addOptionalHeader( + $headers, + Resources::X_MS_BLOB_CACHE_CONTROL, + $blobCacheControl + ); + $this->addOptionalHeader( + $headers, + Resources::X_MS_BLOB_CONTENT_TYPE, + $blobContentType + ); + $this->addOptionalHeader( + $headers, + Resources::X_MS_BLOB_CONTENT_ENCODING, + $blobContentEncoding + ); + $this->addOptionalHeader( + $headers, + Resources::X_MS_BLOB_CONTENT_LANGUAGE, + $blobContentLanguage + ); + $this->addOptionalHeader( + $headers, + Resources::X_MS_BLOB_CONTENT_MD5, + $blobContentMD5 + ); + $this->addOptionalHeader( + $headers, + Resources::CONTENT_TYPE, + $contentType + ); + + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_COMP, + 'blocklist' + ); + + return $this->send( + $method, + $headers, + $queryParams, + $postParams, + $path, + $statusCode, + $body + ); + } + + /** + * Retrieves the list of blocks that have been uploaded as part of a block blob. + * + * There are two block lists maintained for a blob: + * 1) Committed Block List: The list of blocks that have been successfully + * committed to a given blob with commitBlobBlocks. + * 2) Uncommitted Block List: The list of blocks that have been uploaded for a + * blob using Put Block (REST API), but that have not yet been committed. + * These blocks are stored in Windows Azure in association with a blob, but do + * not yet form part of the blob. + * + * @param string $container name of the container + * @param string $blob name of the blob + * @param Models\ListBlobBlocksOptions $options optional parameters + * + * @return Models\ListBlobBlocksResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179400.aspx + */ + public function listBlobBlocks($container, $blob, $options = null) + { + Validate::isString($container, 'container'); + Validate::isString($blob, 'blob'); + Validate::notNullOrEmpty($blob, 'blob'); + + $method = Resources::HTTP_GET; + $headers = array(); + $postParams = array(); + $queryParams = array(); + $path = $this->_createPath($container, $blob); + $statusCode = Resources::STATUS_OK; + + if (is_null($options)) { + $options = new ListBlobBlocksOptions(); + } + + $this->addOptionalHeader( + $headers, + Resources::X_MS_LEASE_ID, + $options->getLeaseId() + ); + + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_BLOCK_LIST_TYPE, + $options->getBlockListType() + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_SNAPSHOT, + $options->getSnapshot() + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_COMP, + 'blocklist' + ); + + $response = $this->send( + $method, + $headers, + $queryParams, + $postParams, + $path, + $statusCode + ); + + $parsed = $this->dataSerializer->unserialize($response->getBody()); + + return ListBlobBlocksResult::create($response->getHeader(), $parsed); + } + + /** + * Returns all properties and metadata on the blob. + * + * @param string $container name of the container + * @param string $blob name of the blob + * @param Models\GetBlobPropertiesOptions $options optional parameters + * + * @return Models\GetBlobPropertiesResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179394.aspx + */ + public function getBlobProperties($container, $blob, $options = null) + { + Validate::isString($container, 'container'); + Validate::isString($blob, 'blob'); + Validate::notNullOrEmpty($blob, 'blob'); + + $method = Resources::HTTP_HEAD; + $headers = array(); + $postParams = array(); + $queryParams = array(); + $path = $this->_createPath($container, $blob); + $statusCode = Resources::STATUS_OK; + + if (is_null($options)) { + $options = new GetBlobPropertiesOptions(); + } + + $headers = $this->addOptionalAccessConditionHeader( + $headers, $options->getAccessCondition() + ); + + $this->addOptionalHeader( + $headers, + Resources::X_MS_LEASE_ID, + $options->getLeaseId() + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_SNAPSHOT, + $options->getSnapshot() + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + + $response = $this->send( + $method, + $headers, + $queryParams, + $postParams, + $path, + $statusCode + ); + + return $this->_getBlobPropertiesResultFromResponse($response->getHeader()); + } + + /** + * Returns all properties and metadata on the blob. + * + * @param string $container name of the container + * @param string $blob name of the blob + * @param Models\GetBlobMetadataOptions $options optional parameters + * + * @return Models\GetBlobMetadataResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179350.aspx + */ + public function getBlobMetadata($container, $blob, $options = null) + { + Validate::isString($container, 'container'); + Validate::isString($blob, 'blob'); + Validate::notNullOrEmpty($blob, 'blob'); + + $method = Resources::HTTP_HEAD; + $headers = array(); + $postParams = array(); + $queryParams = array(); + $path = $this->_createPath($container, $blob); + $statusCode = Resources::STATUS_OK; + + if (is_null($options)) { + $options = new GetBlobMetadataOptions(); + } + + $headers = $this->addOptionalAccessConditionHeader( + $headers, $options->getAccessCondition() + ); + + $this->addOptionalHeader( + $headers, + Resources::X_MS_LEASE_ID, + $options->getLeaseId() + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_SNAPSHOT, + $options->getSnapshot() + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_COMP, + 'metadata' + ); + + $response = $this->send( + $method, + $headers, + $queryParams, + $postParams, + $path, + $statusCode + ); + $metadata = $this->getMetadataArray($response->getHeader()); + + return GetBlobMetadataResult::create($response->getHeader(), $metadata); + } + + /** + * Returns a list of active page ranges for a page blob. Active page ranges are + * those that have been populated with data. + * + * @param string $container name of the container + * @param string $blob name of the blob + * @param Models\ListPageBlobRangesOptions $options optional parameters + * + * @return Models\ListPageBlobRangesResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691973.aspx + */ + public function listPageBlobRanges($container, $blob, $options = null) + { + Validate::isString($container, 'container'); + Validate::isString($blob, 'blob'); + Validate::notNullOrEmpty($blob, 'blob'); + + $method = Resources::HTTP_GET; + $headers = array(); + $queryParams = array(); + $postParams = array(); + $path = $this->_createPath($container, $blob); + $statusCode = Resources::STATUS_OK; + + if (is_null($options)) { + $options = new ListPageBlobRangesOptions(); + } + + $headers = $this->addOptionalAccessConditionHeader( + $headers, $options->getAccessCondition() + ); + + $headers = $this->_addOptionalRangeHeader( + $headers, $options->getRangeStart(), $options->getRangeEnd() + ); + + $this->addOptionalHeader( + $headers, + Resources::X_MS_LEASE_ID, + $options->getLeaseId() + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_SNAPSHOT, + $options->getSnapshot() + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_COMP, + 'pagelist' + ); + + $response = $this->send( + $method, + $headers, + $queryParams, + $postParams, + $path, + $statusCode + ); + $parsed = $this->dataSerializer->unserialize($response->getBody()); + + return ListPageBlobRangesResult::create($response->getHeader(), $parsed); + } + + /** + * Sets system properties defined for a blob. + * + * @param string $container name of the container + * @param string $blob name of the blob + * @param Models\SetBlobPropertiesOptions $options optional parameters + * + * @return Models\SetBlobPropertiesResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691966.aspx + */ + public function setBlobProperties($container, $blob, $options = null) + { + Validate::isString($container, 'container'); + Validate::isString($blob, 'blob'); + Validate::notNullOrEmpty($blob, 'blob'); + + $method = Resources::HTTP_PUT; + $headers = array(); + $postParams = array(); + $queryParams = array(); + $path = $this->_createPath($container, $blob); + $statusCode = Resources::STATUS_OK; + + if (is_null($options)) { + $options = new SetBlobPropertiesOptions(); + } + + $blobContentType = $options->getBlobContentType(); + $blobContentEncoding = $options->getBlobContentEncoding(); + $blobContentLanguage = $options->getBlobContentLanguage(); + $blobContentLength = $options->getBlobContentLength(); + $blobContentMD5 = $options->getBlobContentMD5(); + $blobCacheControl = $options->getBlobCacheControl(); + $leaseId = $options->getLeaseId(); + $sNumberAction = $options->getSequenceNumberAction(); + $sNumber = $options->getSequenceNumber(); + + $headers = $this->addOptionalAccessConditionHeader( + $headers, $options->getAccessCondition() + ); + + $this->addOptionalHeader( + $headers, + Resources::X_MS_LEASE_ID, + $leaseId + ); + $this->addOptionalHeader( + $headers, + Resources::X_MS_BLOB_CACHE_CONTROL, + $blobCacheControl + ); + $this->addOptionalHeader( + $headers, + Resources::X_MS_BLOB_CONTENT_TYPE, + $blobContentType + ); + $this->addOptionalHeader( + $headers, + Resources::X_MS_BLOB_CONTENT_ENCODING, + $blobContentEncoding + ); + $this->addOptionalHeader( + $headers, + Resources::X_MS_BLOB_CONTENT_LANGUAGE, + $blobContentLanguage + ); + $this->addOptionalHeader( + $headers, + Resources::X_MS_BLOB_CONTENT_LENGTH, + $blobContentLength + ); + $this->addOptionalHeader( + $headers, + Resources::X_MS_BLOB_CONTENT_MD5, + $blobContentMD5 + ); + $this->addOptionalHeader( + $headers, + Resources::X_MS_BLOB_SEQUENCE_NUMBER_ACTION, + $sNumberAction + ); + $this->addOptionalHeader( + $headers, + Resources::X_MS_BLOB_SEQUENCE_NUMBER, + $sNumber + ); + + $this->addOptionalQueryParam($queryParams, Resources::QP_COMP, 'properties'); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + + $response = $this->send( + $method, + $headers, + $queryParams, + $postParams, + $path, + $statusCode + ); + + return SetBlobPropertiesResult::create($response->getHeader()); + } + + /** + * Sets metadata headers on the blob. + * + * @param string $container name of the container + * @param string $blob name of the blob + * @param array $metadata key/value pair representation + * @param Models\SetBlobMetadataOptions $options optional parameters + * + * @return Models\SetBlobMetadataResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179414.aspx + */ + public function setBlobMetadata($container, $blob, $metadata, $options = null) + { + Validate::isString($container, 'container'); + Validate::isString($blob, 'blob'); + Validate::notNullOrEmpty($blob, 'blob'); + $this->validateMetadata($metadata); + + $method = Resources::HTTP_PUT; + $headers = array(); + $postParams = array(); + $queryParams = array(); + $path = $this->_createPath($container, $blob); + $statusCode = Resources::STATUS_OK; + + if (is_null($options)) { + $options = new SetBlobMetadataOptions(); + } + + $headers = $this->addOptionalAccessConditionHeader( + $headers, $options->getAccessCondition() + ); + $headers = $this->addMetadataHeaders($headers, $metadata); + + $this->addOptionalHeader( + $headers, + Resources::X_MS_LEASE_ID, + $options->getLeaseId() + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_COMP, + 'metadata' + ); + + $response = $this->send( + $method, + $headers, + $queryParams, + $postParams, + $path, + $statusCode + ); + + return SetBlobMetadataResult::create($response->getHeader()); + } + + /** + * Reads or downloads a blob from the system, including its metadata and + * properties. + * + * @param string $container name of the container + * @param string $blob name of the blob + * @param Models\GetBlobOptions $options optional parameters + * + * @return Models\GetBlobResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179440.aspx + */ + public function getBlob($container, $blob, $options = null) + { + Validate::isString($container, 'container'); + Validate::isString($blob, 'blob'); + + $method = Resources::HTTP_GET; + $headers = array(); + $postParams = array(); + $queryParams = array(); + $path = $this->_createPath($container, $blob); + $statusCode = array( + Resources::STATUS_OK, + Resources::STATUS_PARTIAL_CONTENT + ); + + if (is_null($options)) { + $options = new GetBlobOptions(); + } + + $getMD5 = $options->getComputeRangeMD5(); + $headers = $this->addOptionalAccessConditionHeader( + $headers, $options->getAccessCondition() + ); + $headers = $this->_addOptionalRangeHeader( + $headers, $options->getRangeStart(), $options->getRangeEnd() + ); + + $this->addOptionalHeader( + $headers, + Resources::X_MS_LEASE_ID, + $options->getLeaseId() + ); + $this->addOptionalHeader( + $headers, + Resources::X_MS_RANGE_GET_CONTENT_MD5, + $getMD5 ? 'true' : null + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_SNAPSHOT, + $options->getSnapshot() + ); + + $response = $this->send( + $method, + $headers, + $queryParams, + $postParams, + $path, + $statusCode + ); + $metadata = $this->getMetadataArray($response->getHeader()); + + return GetBlobResult::create( + $response->getHeader(), + $response->getBody(), + $metadata + ); + } + + /** + * Deletes a blob or blob snapshot. + * + * Note that if the snapshot entry is specified in the $options then only this + * blob snapshot is deleted. To delete all blob snapshots, do not set Snapshot + * and just set getDeleteSnaphotsOnly to true. + * + * @param string $container name of the container + * @param string $blob name of the blob + * @param Models\DeleteBlobOptions $options optional parameters + * + * @return none + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179413.aspx + */ + public function deleteBlob($container, $blob, $options = null) + { + Validate::isString($container, 'container'); + Validate::isString($blob, 'blob'); + Validate::notNullOrEmpty($blob, 'blob'); + + $method = Resources::HTTP_DELETE; + $headers = array(); + $postParams = array(); + $queryParams = array(); + $path = $this->_createPath($container, $blob); + $statusCode = Resources::STATUS_ACCEPTED; + + if (is_null($options)) { + $options = new DeleteBlobOptions(); + } + + if (is_null($options->getSnapshot())) { + $delSnapshots = $options->getDeleteSnaphotsOnly() ? 'only' : 'include'; + $this->addOptionalHeader( + $headers, + Resources::X_MS_DELETE_SNAPSHOTS, + $delSnapshots + ); + } else { + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_SNAPSHOT, + $options->getSnapshot() + ); + } + + $headers = $this->addOptionalAccessConditionHeader( + $headers, $options->getAccessCondition() + ); + + $this->addOptionalHeader( + $headers, + Resources::X_MS_LEASE_ID, + $options->getLeaseId() + ); + + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + + $this->send( + $method, + $headers, + $queryParams, + $postParams, + $path, + $statusCode + ); + } + + /** + * Creates a snapshot of a blob. + * + * @param string $container The name of the container. + * @param string $blob The name of the blob. + * @param Models\CreateBlobSnapshotOptions $options The optional parameters. + * + * @return Models\CreateBlobSnapshotResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691971.aspx + */ + public function createBlobSnapshot($container, $blob, $options = null) + { + Validate::isString($container, 'container'); + Validate::isString($blob, 'blob'); + Validate::notNullOrEmpty($blob, 'blob'); + + $method = Resources::HTTP_PUT; + $headers = array(); + $postParams = array(); + $queryParams = array(); + $path = $this->_createPath($container, $blob); + $expectedStatusCode = Resources::STATUS_CREATED; + + if (is_null($options)) { + $options = new CreateBlobSnapshotOptions(); + } + + $queryParams[Resources::QP_COMP] = 'snapshot'; + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + + $headers = $this->addOptionalAccessConditionHeader( + $headers, + $options->getAccessCondition() + ); + $headers = $this->addMetadataHeaders($headers, $options->getMetadata()); + $this->addOptionalHeader( + $headers, + Resources::X_MS_LEASE_ID, + $options->getLeaseId() + ); + + $response = $this->send( + $method, + $headers, + $queryParams, + $postParams, + $path, + $expectedStatusCode + ); + + return CreateBlobSnapshotResult::create($response->getHeader()); + } + + /** + * Copies a source blob to a destination blob within the same storage account. + * + * @param string $destinationContainer name of the destination + * container + * @param string $destinationBlob name of the destination + * blob + * @param string $sourceContainer name of the source + * container + * @param string $sourceBlob name of the source + * blob + * @param Models\CopyBlobOptions $options optional parameters + * + * @return CopyBlobResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd894037.aspx + */ + public function copyBlob( + $destinationContainer, + $destinationBlob, + $sourceContainer, + $sourceBlob, + $options = null + ) { + + $method = Resources::HTTP_PUT; + $headers = array(); + $postParams = array(); + $queryParams = array(); + $destinationBlobPath = $this->_createPath( + $destinationContainer, + $destinationBlob + ); + $statusCode = Resources::STATUS_CREATED; + + if (is_null($options)) { + $options = new CopyBlobOptions(); + } + + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + + $sourceBlobPath = $this->_getCopyBlobSourceName( + $sourceContainer, + $sourceBlob, + $options + ); + + $headers = $this->addOptionalAccessConditionHeader( + $headers, + $options->getAccessCondition() + ); + + $headers = $this->addOptionalSourceAccessConditionHeader( + $headers, + $options->getSourceAccessCondition() + ); + + $this->addOptionalHeader( + $headers, + Resources::X_MS_COPY_SOURCE, + $sourceBlobPath + ); + + $headers = $this->addMetadataHeaders($headers, $options->getMetadata()); + + $this->addOptionalHeader( + $headers, + Resources::X_MS_LEASE_ID, + $options->getLeaseId() + ); + + $this->addOptionalHeader( + $headers, + Resources::X_MS_SOURCE_LEASE_ID, + $options->getSourceLeaseId() + ); + + $response = $this->send( + $method, + $headers, + $queryParams, + $postParams, + $destinationBlobPath, + $statusCode + ); + + return CopyBlobResult::create($response->getHeader()); + } + + /** + * Establishes an exclusive one-minute write lock on a blob. To write to a locked + * blob, a client must provide a lease ID. + * + * @param string $container name of the container + * @param string $blob name of the blob + * @param Models\AcquireLeaseOptions $options optional parameters + * + * @return Models\AcquireLeaseResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691972.aspx + */ + public function acquireLease($container, $blob, $options = null) + { + $headers = $this->_putLeaseImpl( + LeaseMode::ACQUIRE_ACTION, + $container, + $blob, + null /* leaseId */, + is_null($options) ? new AcquireLeaseOptions() : $options, + is_null($options) ? null : $options->getAccessCondition() + ); + + return AcquireLeaseResult::create($headers); + } + + /** + * Renews an existing lease + * + * @param string $container name of the container + * @param string $blob name of the blob + * @param string $leaseId lease id when acquiring + * @param Models\BlobServiceOptions $options optional parameters + * + * @return Models\AcquireLeaseResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691972.aspx + */ + public function renewLease($container, $blob, $leaseId, $options = null) + { + $headers = $this->_putLeaseImpl( + LeaseMode::RENEW_ACTION, + $container, + $blob, + $leaseId, + is_null($options) ? new BlobServiceOptions() : $options + ); + + return AcquireLeaseResult::create($headers); + } + + /** + * Frees the lease if it is no longer needed so that another client may + * immediately acquire a lease against the blob. + * + * @param string $container name of the container + * @param string $blob name of the blob + * @param string $leaseId lease id when acquiring + * @param Models\BlobServiceOptions $options optional parameters + * + * @return none + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691972.aspx + */ + public function releaseLease($container, $blob, $leaseId, $options = null) + { + $this->_putLeaseImpl( + LeaseMode::RELEASE_ACTION, + $container, + $blob, + $leaseId, + is_null($options) ? new BlobServiceOptions() : $options + ); + } + + /** + * Ends the lease but ensure that another client cannot acquire a new lease until + * the current lease period has expired. + * + * @param string $container name of the container + * @param string $blob name of the blob + * @param Models\BlobServiceOptions $options optional parameters + * + * @return BreakLeaseResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691972.aspx + */ + public function breakLease($container, $blob, $options = null) + { + $headers = $this->_putLeaseImpl( + LeaseMode::BREAK_ACTION, + $container, + $blob, + null, + is_null($options) ? new BlobServiceOptions() : $options + ); + + return BreakLeaseResult::create($headers); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Internal/IBlob.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Internal/IBlob.php new file mode 100644 index 0000000..d3e9917 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Internal/IBlob.php @@ -0,0 +1,491 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Internal; +use WindowsAzure\Common\Internal\FilterableService; + +/** + * This interface has all REST APIs provided by Windows Azure for Blob service. + * + * @category Microsoft + * @package WindowsAzure\Blob\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd135733.aspx + */ +interface IBlob extends FilterableService +{ + /** + * Gets the properties of the Blob service. + * + * @param Models\BlobServiceOptions $options optional blob service options. + * + * @return WindowsAzure\Common\Models\GetServicePropertiesResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/hh452239.aspx + */ + public function getServiceProperties($options = null); + + /** + * Sets the properties of the Blob service. + * + * @param ServiceProperties $serviceProperties new service properties + * @param Models\BlobServiceOptions $options optional parameters + * + * @return none. + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/hh452235.aspx + */ + public function setServiceProperties($serviceProperties, $options = null); + + /** + * Lists all of the containers in the given storage account. + * + * @param Models\ListContainersOptions $options optional parameters + * + * @return WindowsAzure\Blob\Models\ListContainersResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179352.aspx + */ + public function listContainers($options = null); + + /** + * Creates a new container in the given storage account. + * + * @param string $container name + * @param Models\CreateContainerOptions $options optional parameters + * + * @return none. + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179468.aspx + */ + public function createContainer($container, $options = null); + + /** + * Creates a new container in the given storage account. + * + * @param string $container name + * @param Models\DeleteContainerOptions $options optional parameters + * + * @return none. + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179408.aspx + */ + public function deleteContainer($container, $options = null); + + /** + * Returns all properties and metadata on the container. + * + * @param string $container name + * @param Models\BlobServiceOptions $options optional parameters + * + * @return Models\GetContainerPropertiesResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179370.aspx + */ + public function getContainerProperties($container, $options = null); + + /** + * Returns only user-defined metadata for the specified container. + * + * @param string $container name + * @param Models\BlobServiceOptions $options optional parameters + * + * @return Models\GetContainerPropertiesResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691976.aspx + */ + public function getContainerMetadata($container, $options = null); + + /** + * Gets the access control list (ACL) and any container-level access policies + * for the container. + * + * @param string $container name + * @param Models\BlobServiceOptions $options optional parameters + * + * @return Models\GetContainerAclResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179469.aspx + */ + public function getContainerAcl($container, $options = null); + + /** + * Sets the ACL and any container-level access policies for the container. + * + * @param string $container name + * @param Models\ContainerAcl $acl access control list for container + * @param Models\BlobServiceOptions $options optional parameters + * + * @return none. + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179391.aspx + */ + public function setContainerAcl($container, $acl, $options = null); + + /** + * Sets metadata headers on the container. + * + * @param string $container name + * @param array $metadata metadata key/value pair. + * @param Models\SetContainerMetadataOptions $options optional parameters + * + * @return none. + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179362.aspx + */ + public function setContainerMetadata($container, $metadata, $options = null); + + /** + * Lists all of the blobs in the given container. + * + * @param string $container name + * @param Models\ListBlobsOptions $options optional parameters + * + * @return Models\ListBlobsResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd135734.aspx + */ + public function listBlobs($container, $options = null); + + /** + * Creates a new page blob. Note that calling createPageBlob to create a page + * blob only initializes the blob. + * To add content to a page blob, call createBlobPages method. + * + * @param string $container name of the container + * @param string $blob name of the blob + * @param int $length specifies the maximum size for the + * page blob, up to 1 TB. The page blob size must be aligned to a 512-byte + * boundary. + * @param Models\CreateBlobOptions $options optional parameters + * + * @return CopyBlobResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179451.aspx + */ + public function createPageBlob($container, $blob, $length, $options = null); + + /** + * Creates a new block blob or updates the content of an existing block blob. + * Updating an existing block blob overwrites any existing metadata on the blob. + * Partial updates are not supported with createBlockBlob; the content of the + * existing blob is overwritten with the content of the new blob. To perform a + * partial update of the content of a block blob, use the createBlockList method. + * + * @param string $container name of the container + * @param string $blob name of the blob + * @param string $content content of the blob + * @param Models\CreateBlobOptions $options optional parameters + * + * @return CopyBlobResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179451.aspx + */ + public function createBlockBlob($container, $blob, $content, $options = null); + + /** + * Clears a range of pages from the blob. + * + * @param string $container name of the container + * @param string $blob name of the blob + * @param Models\PageRange $range Can be up to the value of the + * blob's full size. + * @param Models\CreateBlobPagesOptions $options optional parameters + * + * @return Models\CreateBlobPagesResult. + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691975.aspx + */ + public function clearBlobPages($container, $blob, $range, $options = null); + + /** + * Creates a range of pages to a page blob. + * + * @param string $container name of the container + * @param string $blob name of the blob + * @param Models\PageRange $range Can be up to 4 MB in size + * @param string $content the blob contents + * @param Models\CreateBlobPagesOptions $options optional parameters + * + * @return Models\CreateBlobPagesResult. + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691975.aspx + */ + public function createBlobPages($container, $blob, $range, $content, + $options = null + ); + + /** + * Creates a new block to be committed as part of a block blob. + * + * @param string $container name of the container + * @param string $blob name of the blob + * @param string $blockId must be less than or equal to + * 64 bytes in size. For a given blob, the length of the value specified for the + * blockid parameter must be the same size for each block. + * @param string $content the blob block contents + * @param Models\CreateBlobBlockOptions $options optional parameters + * + * @return none. + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd135726.aspx + */ + public function createBlobBlock($container, $blob, $blockId, $content, + $options = null + ); + + /** + * This method writes a blob by specifying the list of block IDs that make up the + * blob. In order to be written as part of a blob, a block must have been + * successfully written to the server in a prior createBlobBlock method. + * + * You can call Put Block List to update a blob by uploading only those blocks + * that have changed, then committing the new and existing blocks together. + * You can do this by specifying whether to commit a block from the committed + * block list or from the uncommitted block list, or to commit the most recently + * uploaded version of the block, whichever list it may belong to. + * + * @param string $container name of the container + * @param string $blob name of the blob + * @param Models\BlockList $blockList the block list entries + * @param Models\CommitBlobBlocksOptions $options optional parameters + * + * @return none. + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179467.aspx + */ + public function commitBlobBlocks($container, $blob, $blockList, $options = null); + + /** + * Retrieves the list of blocks that have been uploaded as part of a block blob. + * + * There are two block lists maintained for a blob: + * 1) Committed Block List: The list of blocks that have been successfully + * committed to a given blob with commitBlobBlocks. + * 2) Uncommitted Block List: The list of blocks that have been uploaded for a + * blob using Put Block (REST API), but that have not yet been committed. + * These blocks are stored in Windows Azure in association with a blob, but do + * not yet form part of the blob. + * + * @param string $container name of the container + * @param string $blob name of the blob + * @param Models\ListBlobBlocksOptions $options optional parameters + * + * @return Models\ListBlobBlocksResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179400.aspx + */ + public function listBlobBlocks($container, $blob, $options = null); + + /** + * Returns all properties and metadata on the blob. + * + * @param string $container name of the container + * @param string $blob name of the blob + * @param Models\GetBlobPropertiesOptions $options optional parameters + * + * @return Models\GetBlobPropertiesResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179394.aspx + */ + public function getBlobProperties($container, $blob, $options = null); + + /** + * Returns all properties and metadata on the blob. + * + * @param string $container name of the container + * @param string $blob name of the blob + * @param Models\GetBlobMetadataOptions $options optional parameters + * + * @return Models\GetBlobMetadataResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179350.aspx + */ + public function getBlobMetadata($container, $blob, $options = null); + + /** + * Returns a list of active page ranges for a page blob. Active page ranges are + * those that have been populated with data. + * + * @param string $container name of the container + * @param string $blob name of the blob + * @param Models\ListPageBlobRangesOptions $options optional parameters + * + * @return Models\ListPageBlobRangesResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691973.aspx + */ + public function listPageBlobRanges($container, $blob, $options = null); + + /** + * Sets system properties defined for a blob. + * + * @param string $container name of the container + * @param string $blob name of the blob + * @param Models\SetBlobPropertiesOptions $options optional parameters + * + * @return Models\SetBlobPropertiesResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691966.aspx + */ + public function setBlobProperties($container, $blob, $options = null); + + /** + * Sets metadata headers on the blob. + * + * @param string $container name of the container + * @param string $blob name of the blob + * @param array $metadata key/value pair representation + * @param Models\SetBlobMetadataOptions $options optional parameters + * + * @return Models\SetBlobMetadataResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179414.aspx + */ + public function setBlobMetadata($container, $blob, $metadata, $options = null); + + /** + * Reads or downloads a blob from the system, including its metadata and + * properties. + * + * @param string $container name of the container + * @param string $blob name of the blob + * @param Models\GetBlobOptions $options optional parameters + * + * @return Models\GetBlobResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179440.aspx + */ + public function getBlob($container, $blob, $options = null); + + /** + * Deletes a blob or blob snapshot. + * + * Note that if the snapshot entry is specified in the $options then only this + * blob snapshot is deleted. To delete all blob snapshots, do not set Snapshot + * and just set getDeleteSnaphotsOnly to true. + * + * @param string $container name of the container + * @param string $blob name of the blob + * @param Models\DeleteBlobOptions $options optional parameters + * + * @return none + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179413.aspx + */ + public function deleteBlob($container, $blob, $options = null); + + /** + * Creates a snapshot of a blob. + * + * @param string $container name of the container + * @param string $blob name of the blob + * @param Models\CreateBlobSnapshotOptions $options optional parameters + * + * @return Models\CreateBlobSnapshotResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691971.aspx + */ + public function createBlobSnapshot($container, $blob, $options = null); + + /** + * Copies a source blob to a destination blob within the same storage account. + * + * @param string $destinationContainer name of container + * @param string $destinationBlob name of blob + * @param string $sourceContainer name of container + * @param string $sourceBlob name of blob + * @param Models\CopyBlobOptions $options optional parameters + * + * @return CopyBlobResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd894037.aspx + */ + public function copyBlob($destinationContainer, $destinationBlob, + $sourceContainer, $sourceBlob, $options = null + ); + + /** + * Establishes an exclusive one-minute write lock on a blob. To write to a locked + * blob, a client must provide a lease ID. + * + * @param string $container name of the container + * @param string $blob name of the blob + * @param Models\AcquireLeaseOptions $options optional parameters + * + * @return Models\AcquireLeaseResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691972.aspx + */ + public function acquireLease($container, $blob, $options = null); + + /** + * Renews an existing lease + * + * @param string $container name of the container + * @param string $blob name of the blob + * @param string $leaseId lease id when acquiring + * @param Models\BlobServiceOptions $options optional parameters + * + * @return Models\AcquireLeaseResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691972.aspx + */ + public function renewLease($container, $blob, $leaseId, $options = null); + + /** + * Frees the lease if it is no longer needed so that another client may + * immediately acquire a lease against the blob. + * + * @param string $container name of the container + * @param string $blob name of the blob + * @param string $leaseId lease id when acquiring + * @param Models\BlobServiceOptions $options optional parameters + * + * @return none + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691972.aspx + */ + public function releaseLease($container, $blob, $leaseId, $options = null); + + /** + * Ends the lease but ensure that another client cannot acquire a new lease until + * the current lease period has expired. + * + * @param string $container name of the container + * @param string $blob name of the blob + * @param Models\BlobServiceOptions $options optional parameters + * + * @return none + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691972.aspx + */ + public function breakLease($container, $blob, $options = null); +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/AccessCondition.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/AccessCondition.php new file mode 100644 index 0000000..de9bdbc --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/AccessCondition.php @@ -0,0 +1,247 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Validate; +use WindowsAzure\Common\Internal\WindowsAzureUtilities; + +/** + * Represents a set of access conditions to be used for operations against the + * storage services. + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class AccessCondition +{ + /** + * Represents the header type. + * + * @var string + */ + private $_header = Resources::EMPTY_STRING; + + /** + * Represents the header value. + * + * @var string + */ + private $_value; + + /** + * Constructor + * + * @param string $headerType header name + * @param string $value header value + */ + protected function __construct($headerType, $value) + { + $this->setHeader($headerType); + $this->setValue($value); + } + + /** + * Specifies that no access condition is set. + * + * @return \WindowsAzure\Blob\Models\AccessCondition + */ + public static function none() + { + return new AccessCondition(Resources::EMPTY_STRING, null); + } + + /** + * Returns an access condition such that an operation will be performed only if + * the resource's ETag value matches the specified ETag value. + *

    + * Setting this access condition modifies the request to include the HTTP + * If-Match conditional header. If this access condition is set, the + * operation is performed only if the ETag of the resource matches the specified + * ETag. + *

    + * For more information, see + * + * Specifying Conditional Headers for Blob Service Operations. + * + * @param string $etag a string that represents the ETag value to check. + * + * @return \WindowsAzure\Blob\Models\AccessCondition + */ + public static function ifMatch($etag) + { + return new AccessCondition(Resources::IF_MATCH, $etag); + } + + /** + * Returns an access condition such that an operation will be performed only if + * the resource has been modified since the specified time. + *

    + * Setting this access condition modifies the request to include the HTTP + * If-Modified-Since conditional header. If this access condition is set, + * the operation is performed only if the resource has been modified since the + * specified time. + *

    + * For more information, see + * + * Specifying Conditional Headers for Blob Service Operations. + * + * @param \DateTime $lastModified date that represents the last-modified + * time to check for the resource. + * + * @return \WindowsAzure\Blob\Models\AccessCondition + */ + public static function ifModifiedSince($lastModified) + { + Validate::isDate($lastModified); + return new AccessCondition( + Resources::IF_MODIFIED_SINCE, + $lastModified + ); + } + + /** + * Returns an access condition such that an operation will be performed only if + * the resource's ETag value does not match the specified ETag value. + *

    + * Setting this access condition modifies the request to include the HTTP + * If-None-Match conditional header. If this access condition is set, the + * operation is performed only if the ETag of the resource does not match the + * specified ETag. + *

    + * For more information, + * see + * Specifying Conditional Headers for Blob Service Operations. + * + * @param string $etag string that represents the ETag value to check. + * + * @return \WindowsAzure\Blob\Models\AccessCondition + */ + public static function ifNoneMatch($etag) + { + return new AccessCondition(Resources::IF_NONE_MATCH, $etag); + } + + /** + * Returns an access condition such that an operation will be performed only if + * the resource has not been modified since the specified time. + *

    + * Setting this access condition modifies the request to include the HTTP + * If-Unmodified-Since conditional header. If this access condition is + * set, the operation is performed only if the resource has not been modified + * since the specified time. + *

    + * For more information, see + * + * Specifying Conditional Headers for Blob Service Operations. + * + * @param \DateTime $lastModified date that represents the last-modified + * time to check for the resource. + * + * @return \WindowsAzure\Blob\Models\AccessCondition + */ + public static function ifNotModifiedSince($lastModified) + { + Validate::isDate($lastModified); + return new AccessCondition( + Resources::IF_UNMODIFIED_SINCE, + $lastModified + ); + } + + /** + * Sets header type + * + * @param string $headerType can be one of Resources + * + * @return none. + */ + public function setHeader($headerType) + { + $valid = AccessCondition::isValid($headerType); + Validate::isTrue($valid, Resources::INVALID_HT_MSG); + + $this->_header = $headerType; + } + + /** + * Gets header type + * + * @return string. + */ + public function getHeader() + { + return $this->_header; + } + + /** + * Sets the header value + * + * @param string $value the value to use + * + * @return none + */ + public function setValue($value) + { + $this->_value = $value; + } + + /** + * Gets the header value + * + * @return string + */ + public function getValue() + { + return $this->_value; + } + + /** + * Check if the $headerType belongs to valid header types + * + * @param string $headerType candidate header type + * + * @return boolean + */ + public static function isValid($headerType) + { + if ( $headerType == Resources::EMPTY_STRING + || $headerType == Resources::IF_UNMODIFIED_SINCE + || $headerType == Resources::IF_MATCH + || $headerType == Resources::IF_MODIFIED_SINCE + || $headerType == Resources::IF_NONE_MATCH + ) { + return true; + } else { + return false; + } + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/AccessPolicy.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/AccessPolicy.php new file mode 100644 index 0000000..517798a --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/AccessPolicy.php @@ -0,0 +1,143 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; + +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Validate; + +/** + * Holds container access policy elements + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class AccessPolicy +{ + /** + * @var string + */ + private $_start; + + /** + * @var \DateTime + */ + private $_expiry; + + /** + * @var \DateTime + */ + private $_permission; + + /** + * Gets start. + * + * @return \DateTime. + */ + public function getStart() + { + return $this->_start; + } + + /** + * Sets start. + * + * @param \DateTime $start value. + * + * @return none. + */ + public function setStart($start) + { + Validate::isDate($start); + $this->_start = $start; + } + + /** + * Gets expiry. + * + * @return \DateTime. + */ + public function getExpiry() + { + return $this->_expiry; + } + + /** + * Sets expiry. + * + * @param \DateTime $expiry value. + * + * @return none. + */ + public function setExpiry($expiry) + { + Validate::isDate($expiry); + $this->_expiry = $expiry; + } + + /** + * Gets permission. + * + * @return string. + */ + public function getPermission() + { + return $this->_permission; + } + + /** + * Sets permission. + * + * @param string $permission value. + * + * @return none. + */ + public function setPermission($permission) + { + $this->_permission = $permission; + } + + /** + * Converts this current object to XML representation. + * + * @return array. + */ + public function toArray() + { + $array = array(); + + $array['Start'] = Utilities::convertToEdmDateTime($this->_start); + $array['Expiry'] = Utilities::convertToEdmDateTime($this->_expiry); + $array['Permission'] = $this->_permission; + + return $array; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/AcquireLeaseOptions.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/AcquireLeaseOptions.php new file mode 100644 index 0000000..ff82194 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/AcquireLeaseOptions.php @@ -0,0 +1,68 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; + +/** + * Optional parameters for acquireLease wrapper + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class AcquireLeaseOptions extends BlobServiceOptions +{ + /** + * @var AccessCondition + */ + private $_accessCondition; + + /** + * Gets access condition + * + * @return AccessCondition + */ + public function getAccessCondition() + { + return $this->_accessCondition; + } + + /** + * Sets access condition + * + * @param AccessCondition $accessCondition value to use. + * + * @return none. + */ + public function setAccessCondition($accessCondition) + { + $this->_accessCondition = $accessCondition; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/AcquireLeaseResult.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/AcquireLeaseResult.php new file mode 100644 index 0000000..e05a443 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/AcquireLeaseResult.php @@ -0,0 +1,88 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Utilities; + +/** + * The result of calling acquireLease API. + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class AcquireLeaseResult +{ + /** + * @var string + */ + private $_leaseId; + + /** + * Creates AcquireLeaseResult from response headers + * + * @param array $headers response headers + * + * @return AcquireLeaseResult + */ + public static function create($headers) + { + $result = new AcquireLeaseResult(); + + $result->setLeaseId( + Utilities::tryGetValue($headers, Resources::X_MS_LEASE_ID) + ); + + return $result; + } + + /** + * Gets lease Id for the blob + * + * @return string + */ + public function getLeaseId() + { + return $this->_leaseId; + } + + /** + * Sets lease Id for the blob + * + * @param string $leaseId the blob lease id. + * + * @return none + */ + public function setLeaseId($leaseId) + { + $this->_leaseId = $leaseId; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/Blob.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/Blob.php new file mode 100644 index 0000000..b5703f3 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/Blob.php @@ -0,0 +1,176 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; + +/** + * Represents windows azure blob object + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class Blob +{ + /** + * @var string + */ + private $_name; + + /** + * @var string + */ + private $_url; + + /** + * @var string + */ + private $_snapshot; + + /** + * @var array + */ + private $_metadata; + + /** + * @var BlobProperties + */ + private $_properties; + + /** + * Gets blob name. + * + * @return string. + */ + public function getName() + { + return $this->_name; + } + + /** + * Sets blob name. + * + * @param string $name value. + * + * @return none. + */ + public function setName($name) + { + $this->_name = $name; + } + + /** + * Gets blob snapshot. + * + * @return string. + */ + public function getSnapshot() + { + return $this->_snapshot; + } + + /** + * Sets blob snapshot. + * + * @param string $snapshot value. + * + * @return none. + */ + public function setSnapshot($snapshot) + { + $this->_snapshot = $snapshot; + } + + /** + * Gets blob url. + * + * @return string. + */ + public function getUrl() + { + return $this->_url; + } + + /** + * Sets blob url. + * + * @param string $url value. + * + * @return none. + */ + public function setUrl($url) + { + $this->_url = $url; + } + + /** + * Gets blob metadata. + * + * @return array. + */ + public function getMetadata() + { + return $this->_metadata; + } + + /** + * Sets blob metadata. + * + * @param string $metadata value. + * + * @return none. + */ + public function setMetadata($metadata) + { + $this->_metadata = $metadata; + } + + /** + * Gets blob properties. + * + * @return BlobProperties. + */ + public function getProperties() + { + return $this->_properties; + } + + /** + * Sets blob properties. + * + * @param BlobProperties $properties value. + * + * @return none. + */ + public function setProperties($properties) + { + $this->_properties = $properties; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/BlobBlockType.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/BlobBlockType.php new file mode 100644 index 0000000..0273f64 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/BlobBlockType.php @@ -0,0 +1,65 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; + +/** + * Holds available blob block types + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class BlobBlockType +{ + const COMMITTED_TYPE = 'Committed'; + const UNCOMMITTED_TYPE = 'Uncommitted'; + const LATEST_TYPE = 'Latest'; + + /** + * Validates the provided type. + * + * @param string $type The entry type. + * + * @return boolean + */ + public static function isValid($type) + { + switch ($type) { + case self::COMMITTED_TYPE: + case self::LATEST_TYPE: + case self::UNCOMMITTED_TYPE: + return true; + + default: + return false; + } + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/BlobPrefix.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/BlobPrefix.php new file mode 100644 index 0000000..a24e47b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/BlobPrefix.php @@ -0,0 +1,68 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; + +/** + * Represents BlobPrefix object + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class BlobPrefix +{ + /** + * @var string + */ + private $_name; + + /** + * Gets blob name. + * + * @return string. + */ + public function getName() + { + return $this->_name; + } + + /** + * Sets blob name. + * + * @param string $name value. + * + * @return none. + */ + public function setName($name) + { + $this->_name = $name; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/BlobProperties.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/BlobProperties.php new file mode 100644 index 0000000..64c5dfd --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/BlobProperties.php @@ -0,0 +1,452 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Validate; +use WindowsAzure\Common\Internal\Utilities; + +/** + * Represents blob properties + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class BlobProperties +{ + /** + * @var \DateTime + */ + private $_lastModified; + + /** + * @var string + */ + private $_etag; + + /** + * @var string + */ + private $_contentType; + + /** + * @var integer + */ + private $_contentLength; + + /** + * @var string + */ + private $_contentEncoding; + + /** + * @var string + */ + private $_contentLanguage; + + /** + * @var string + */ + private $_contentMD5; + + /** + * @var string + */ + private $_contentRange; + + /** + * @var string + */ + private $_cacheControl; + + /** + * @var string + */ + private $_blobType; + + /** + * @var string + */ + private $_leaseStatus; + + /** + * @var integer + */ + private $_sequenceNumber; + + /** + * Creates BlobProperties object from $parsed response in array representation + * + * @param array $parsed parsed response in array format. + * + * @return BlobProperties + */ + public static function create($parsed) + { + $result = new BlobProperties(); + $clean = array_change_key_case($parsed); + + $date = Utilities::tryGetValue($clean, Resources::LAST_MODIFIED); + $result->setBlobType(Utilities::tryGetValue($clean, 'blobtype')); + $result->setContentLength(intval($clean[Resources::CONTENT_LENGTH])); + $result->setETag(Utilities::tryGetValue($clean, Resources::ETAG)); + + if (!is_null($date)) { + $date = Utilities::rfc1123ToDateTime($date); + $result->setLastModified($date); + } + + $result->setLeaseStatus(Utilities::tryGetValue($clean, 'leasestatus')); + $result->setLeaseStatus( + Utilities::tryGetValue( + $clean, Resources::X_MS_LEASE_STATUS, $result->getLeaseStatus() + ) + ); + $result->setSequenceNumber( + intval( + Utilities::tryGetValue($clean, Resources::X_MS_BLOB_SEQUENCE_NUMBER) + ) + ); + $result->setContentRange( + Utilities::tryGetValue($clean, Resources::CONTENT_RANGE) + ); + $result->setCacheControl( + Utilities::tryGetValue($clean, Resources::CACHE_CONTROL) + ); + $result->setBlobType( + Utilities::tryGetValue( + $clean, Resources::X_MS_BLOB_TYPE, $result->getBlobType() + ) + ); + $result->setContentEncoding( + Utilities::tryGetValue($clean, Resources::CONTENT_ENCODING) + ); + $result->setContentLanguage( + Utilities::tryGetValue($clean, Resources::CONTENT_LANGUAGE) + ); + $result->setContentMD5( + Utilities::tryGetValue($clean, Resources::CONTENT_MD5) + ); + $result->setContentType( + Utilities::tryGetValue($clean, Resources::CONTENT_TYPE) + ); + + return $result; + } + + /** + * Makes deep copy from the current object. + * + * @return BlobProperties + */ + public function __clone() + { + $this->_blobType = $this->_blobType; + $this->_cacheControl = $this->_cacheControl; + $this->_contentEncoding = $this->_contentEncoding; + $this->_contentLanguage = $this->_contentLanguage; + $this->_contentLength = $this->_contentLength; + $this->_contentMD5 = $this->_contentMD5; + $this->_contentRange = $this->_contentRange; + $this->_contentType = $this->_contentType; + $this->_etag = $this->_etag; + $this->_lastModified = $this->_lastModified; + $this->_leaseStatus = $this->_leaseStatus; + $this->_sequenceNumber = $this->_sequenceNumber; + } + + /** + * Gets blob lastModified. + * + * @return \DateTime. + */ + public function getLastModified() + { + return $this->_lastModified; + } + + /** + * Sets blob lastModified. + * + * @param \DateTime $lastModified value. + * + * @return none. + */ + public function setLastModified($lastModified) + { + Validate::isDate($lastModified); + $this->_lastModified = $lastModified; + } + + /** + * Gets blob etag. + * + * @return string. + */ + public function getETag() + { + return $this->_etag; + } + + /** + * Sets blob etag. + * + * @param string $etag value. + * + * @return none. + */ + public function setETag($etag) + { + $this->_etag = $etag; + } + + /** + * Gets blob contentType. + * + * @return string. + */ + public function getContentType() + { + return $this->_contentType; + } + + /** + * Sets blob contentType. + * + * @param string $contentType value. + * + * @return none. + */ + public function setContentType($contentType) + { + $this->_contentType = $contentType; + } + + /** + * Gets blob contentRange. + * + * @return string. + */ + public function getContentRange() + { + return $this->_contentRange; + } + + /** + * Sets blob contentRange. + * + * @param string $contentRange value. + * + * @return none. + */ + public function setContentRange($contentRange) + { + $this->_contentRange = $contentRange; + } + + /** + * Gets blob contentLength. + * + * @return integer. + */ + public function getContentLength() + { + return $this->_contentLength; + } + + /** + * Sets blob contentLength. + * + * @param integer $contentLength value. + * + * @return none. + */ + public function setContentLength($contentLength) + { + Validate::isInteger($contentLength, 'contentLength'); + $this->_contentLength = $contentLength; + } + + /** + * Gets blob contentEncoding. + * + * @return string. + */ + public function getContentEncoding() + { + return $this->_contentEncoding; + } + + /** + * Sets blob contentEncoding. + * + * @param string $contentEncoding value. + * + * @return none. + */ + public function setContentEncoding($contentEncoding) + { + $this->_contentEncoding = $contentEncoding; + } + + /** + * Gets blob contentLanguage. + * + * @return string. + */ + public function getContentLanguage() + { + return $this->_contentLanguage; + } + + /** + * Sets blob contentLanguage. + * + * @param string $contentLanguage value. + * + * @return none. + */ + public function setContentLanguage($contentLanguage) + { + $this->_contentLanguage = $contentLanguage; + } + + /** + * Gets blob contentMD5. + * + * @return string. + */ + public function getContentMD5() + { + return $this->_contentMD5; + } + + /** + * Sets blob contentMD5. + * + * @param string $contentMD5 value. + * + * @return none. + */ + public function setContentMD5($contentMD5) + { + $this->_contentMD5 = $contentMD5; + } + + /** + * Gets blob cacheControl. + * + * @return string. + */ + public function getCacheControl() + { + return $this->_cacheControl; + } + + /** + * Sets blob cacheControl. + * + * @param string $cacheControl value. + * + * @return none. + */ + public function setCacheControl($cacheControl) + { + $this->_cacheControl = $cacheControl; + } + + /** + * Gets blob blobType. + * + * @return string. + */ + public function getBlobType() + { + return $this->_blobType; + } + + /** + * Sets blob blobType. + * + * @param string $blobType value. + * + * @return none. + */ + public function setBlobType($blobType) + { + $this->_blobType = $blobType; + } + + /** + * Gets blob leaseStatus. + * + * @return string. + */ + public function getLeaseStatus() + { + return $this->_leaseStatus; + } + + /** + * Sets blob leaseStatus. + * + * @param string $leaseStatus value. + * + * @return none. + */ + public function setLeaseStatus($leaseStatus) + { + $this->_leaseStatus = $leaseStatus; + } + + /** + * Gets blob sequenceNumber. + * + * @return int. + */ + public function getSequenceNumber() + { + return $this->_sequenceNumber; + } + + /** + * Sets blob sequenceNumber. + * + * @param int $sequenceNumber value. + * + * @return none. + */ + public function setSequenceNumber($sequenceNumber) + { + Validate::isInteger($sequenceNumber, 'sequenceNumber'); + $this->_sequenceNumber = $sequenceNumber; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/BlobServiceOptions.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/BlobServiceOptions.php new file mode 100644 index 0000000..119e4e4 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/BlobServiceOptions.php @@ -0,0 +1,65 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; + +/** + * Blob service options. + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class BlobServiceOptions +{ + private $_timeout; + + /** + * Gets timeout. + * + * @return string. + */ + public function getTimeout() + { + return $this->_timeout; + } + + /** + * Sets timeout. + * + * @param string $timeout value. + * + * @return none. + */ + public function setTimeout($timeout) + { + $this->_timeout = $timeout; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/BlobType.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/BlobType.php new file mode 100644 index 0000000..32b871d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/BlobType.php @@ -0,0 +1,44 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; + +/** + * Encapsulates blob types + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class BlobType +{ + const BLOCK_BLOB = 'BlockBlob'; + const PAGE_BLOB = 'PageBlob'; +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/Block.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/Block.php new file mode 100644 index 0000000..789e7e2 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/Block.php @@ -0,0 +1,95 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; + +/** + * Holds information about blob block. + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class Block +{ + /** + * @var string + */ + private $_blockId; + + /** + * @var string + */ + private $_type; + + /** + * Sets the blockId. + * + * @param string $blockId The id of the block. + * + * @return none + */ + public function setBlockId($blockId) + { + $this->_blockId = $blockId; + } + + /** + * Gets the blockId. + * + * @return string + */ + public function getBlockId() + { + return $this->_blockId; + } + + /** + * Sets the type. + * + * @param string $type The type of the block. + * + * @return none + */ + public function setType($type) + { + $this->_type = $type; + } + + /** + * Gets the type. + * + * @return string + */ + public function getType() + { + return $this->_type; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/BlockList.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/BlockList.php new file mode 100644 index 0000000..9a18baf --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/BlockList.php @@ -0,0 +1,175 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; +use WindowsAzure\Common\Internal\Validate; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Serialization\XmlSerializer; +use WindowsAzure\Blob\Models\Block; + +/** + * Holds block list used for commitBlobBlocks + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class BlockList +{ + /** + * @var array + */ + private $_entries; + public static $xmlRootName = 'BlockList'; + + /** + * Creates block list from array of blocks. + * + * @param array $array The blocks array. + * + * @return BlockList + */ + public static function create($array) + { + $blockList = new BlockList(); + + foreach ($array as $value) { + $blockList->addEntry($value->getBlockId(), $value->getType()); + } + + return $blockList; + } + + /** + * Adds new entry to the block list entries. + * + * @param string $blockId The block id. + * @param string $type The entry type, you can use BlobBlockType. + * + * @return none + */ + public function addEntry($blockId, $type) + { + Validate::isString($blockId, 'blockId'); + Validate::isTrue( + BlobBlockType::isValid($type), + sprintf(Resources::INVALID_BTE_MSG, get_class(new BlobBlockType())) + ); + $block = new Block(); + $block->setBlockId($blockId); + $block->setType($type); + + $this->_entries[] = $block; + } + + /** + * Addds committed block entry. + * + * @param string $blockId The block id. + * + * @return none + */ + public function addCommittedEntry($blockId) + { + $this->addEntry($blockId, BlobBlockType::COMMITTED_TYPE); + } + + /** + * Addds uncommitted block entry. + * + * @param string $blockId The block id. + * + * @return none + */ + public function addUncommittedEntry($blockId) + { + $this->addEntry($blockId, BlobBlockType::UNCOMMITTED_TYPE); + } + + /** + * Addds latest block entry. + * + * @param string $blockId The block id. + * + * @return none + */ + public function addLatestEntry($blockId) + { + $this->addEntry($blockId, BlobBlockType::LATEST_TYPE); + } + + /** + * Gets blob block entry. + * + * @param string $blockId The id of the block. + * + * @return Block + */ + public function getEntry($blockId) + { + foreach ($this->_entries as $value) { + if ($blockId == $value->getBlockId()) { + return $value; + } + } + + return null; + } + + /** + * Gets all blob block entries. + * + * @return string + */ + public function getEntries() + { + return $this->_entries; + } + + /** + * Converts the BlockList object to XML representation + * + * @param XmlSerializer $xmlSerializer The XML serializer. + * + * @return string + */ + public function toXml($xmlSerializer) + { + $properties = array(XmlSerializer::ROOT_NAME => self::$xmlRootName); + $array = array(); + + foreach ($this->_entries as $value) { + $array[] = array( + $value->getType() => base64_encode($value->getBlockId()) + ); + } + + return $xmlSerializer->serialize($array, $properties); + } +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/BreakLeaseResult.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/BreakLeaseResult.php new file mode 100644 index 0000000..943a519 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/BreakLeaseResult.php @@ -0,0 +1,86 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Utilities; + +/** + * The result of calling breakLease API. + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class BreakLeaseResult +{ + /** + * @var string + */ + private $_leaseTime; + + /** + * Creates BreakLeaseResult from response headers + * + * @param array $headers response headers + * + * @return BreakLeaseResult + */ + public static function create($headers) + { + $result = new BreakLeaseResult(); + + $result->setLeaseTime( + Utilities::tryGetValue($headers, Resources::X_MS_LEASE_TIME) + ); + + return $result; + } + + /** + * Gets lease time. + * + * @return string + */ + public function getLeaseTime() + { + return $this->_leaseTime; + } + + /** + * Sets lease time. + * + * @param string $leaseTime the blob lease time. + * + * @return none + */ + public function setLeaseTime($leaseTime) + { + $this->_leaseTime = $leaseTime; + } +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/CommitBlobBlocksOptions.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/CommitBlobBlocksOptions.php new file mode 100644 index 0000000..9318015 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/CommitBlobBlocksOptions.php @@ -0,0 +1,258 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; +use WindowsAzure\Common\Internal\Validate; + +/** + * Optional parameters for commitBlobBlocks + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class CommitBlobBlocksOptions extends BlobServiceOptions +{ + /** + * @var string + */ + private $_blobContentType; + + /** + * @var string + */ + private $_blobContentEncoding; + + /** + * @var string + */ + private $_blobContentLanguage; + + /** + * @var string + */ + private $_blobContentMD5; + + /** + * @var string + */ + private $_blobCacheControl; + + /** + * @var array + */ + private $_metadata; + + /** + * @var string + */ + private $_leaseId; + + /** + * @var AccessCondition + */ + private $_accessCondition; + + /** + * Gets blob ContentType. + * + * @return string. + */ + public function getBlobContentType() + { + return $this->_blobContentType; + } + + /** + * Sets blob ContentType. + * + * @param string $blobContentType value. + * + * @return none. + */ + public function setBlobContentType($blobContentType) + { + $this->_blobContentType = $blobContentType; + } + + /** + * Gets blob ContentEncoding. + * + * @return string. + */ + public function getBlobContentEncoding() + { + return $this->_blobContentEncoding; + } + + /** + * Sets blob ContentEncoding. + * + * @param string $blobContentEncoding value. + * + * @return none. + */ + public function setBlobContentEncoding($blobContentEncoding) + { + $this->_blobContentEncoding = $blobContentEncoding; + } + + /** + * Gets blob ContentLanguage. + * + * @return string. + */ + public function getBlobContentLanguage() + { + return $this->_blobContentLanguage; + } + + /** + * Sets blob ContentLanguage. + * + * @param string $blobContentLanguage value. + * + * @return none. + */ + public function setBlobContentLanguage($blobContentLanguage) + { + $this->_blobContentLanguage = $blobContentLanguage; + } + + /** + * Gets blob ContentMD5. + * + * @return string. + */ + public function getBlobContentMD5() + { + return $this->_blobContentMD5; + } + + /** + * Sets blob ContentMD5. + * + * @param string $blobContentMD5 value. + * + * @return none. + */ + public function setBlobContentMD5($blobContentMD5) + { + $this->_blobContentMD5 = $blobContentMD5; + } + + /** + * Gets blob cache control. + * + * @return string. + */ + public function getBlobCacheControl() + { + return $this->_blobCacheControl; + } + + /** + * Sets blob cacheControl. + * + * @param string $blobCacheControl value to use. + * + * @return none. + */ + public function setBlobCacheControl($blobCacheControl) + { + $this->_blobCacheControl = $blobCacheControl; + } + + /** + * Gets access condition + * + * @return AccessCondition + */ + public function getAccessCondition() + { + return $this->_accessCondition; + } + + /** + * Sets access condition + * + * @param AccessCondition $accessCondition value to use. + * + * @return none. + */ + public function setAccessCondition($accessCondition) + { + $this->_accessCondition = $accessCondition; + } + + /** + * Gets blob metadata. + * + * @return array. + */ + public function getMetadata() + { + return $this->_metadata; + } + + /** + * Sets blob metadata. + * + * @param string $metadata value. + * + * @return none. + */ + public function setMetadata($metadata) + { + $this->_metadata = $metadata; + } + + /** + * Gets lease Id for the blob + * + * @return string + */ + public function getLeaseId() + { + return $this->_leaseId; + } + + /** + * Sets lease Id for the blob + * + * @param string $leaseId the blob lease id. + * + * @return none + */ + public function setLeaseId($leaseId) + { + $this->_leaseId = $leaseId; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/Container.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/Container.php new file mode 100644 index 0000000..dd280e4 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/Container.php @@ -0,0 +1,150 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Utilities; + +/** + * WindowsAzure container object. + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class Container +{ + /** + * @var string + */ + private $_name; + + /** + * @var string + */ + private $_url; + + /** + * @var array + */ + private $_metadata; + + /** + * @var ContainerProperties + */ + private $_properties; + + /** + * Gets container name. + * + * @return string. + */ + public function getName() + { + return $this->_name; + } + + /** + * Sets container name. + * + * @param string $name value. + * + * @return none. + */ + public function setName($name) + { + $this->_name = $name; + } + + /** + * Gets container url. + * + * @return string. + */ + public function getUrl() + { + return $this->_url; + } + + /** + * Sets container url. + * + * @param string $url value. + * + * @return none. + */ + public function setUrl($url) + { + $this->_url = $url; + } + + /** + * Gets container metadata. + * + * @return array. + */ + public function getMetadata() + { + return $this->_metadata; + } + + /** + * Sets container metadata. + * + * @param array $metadata value. + * + * @return none. + */ + public function setMetadata($metadata) + { + $this->_metadata = $metadata; + } + + /** + * Gets container properties + * + * @return ContainerProperties + */ + public function getProperties() + { + return $this->_properties; + } + + /** + * Sets container properties + * + * @param ContainerProperties $properties container properties + * + * @return none. + */ + public function setProperties($properties) + { + $this->_properties = $properties; + } +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/ContainerACL.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/ContainerACL.php new file mode 100644 index 0000000..e79b0a9 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/ContainerACL.php @@ -0,0 +1,219 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Validate; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Blob\Models\AccessPolicy; +use WindowsAzure\Blob\Models\SignedIdentifier; +use WindowsAzure\Blob\Models\PublicAccessType; +use WindowsAzure\Common\Internal\Serialization\XmlSerializer; + +/** + * Holds conatiner ACL members. + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class ContainerAcl +{ + /** + * All available types can be found in PublicAccessType + * + * @var string + */ + private $_publicAccess; + + /** + * @var array + */ + private $_signedIdentifiers = array(); + + /* + * The root name of XML elemenet representation. + * + * @var string + */ + public static $xmlRootName = 'SignedIdentifiers'; + + + /** + * Parses the given array into signed identifiers. + * + * @param string $publicAccess The container public access. + * @param array $parsed The parsed response into array representation. + * + * @return none + */ + public static function create($publicAccess, $parsed) + { + $result = new ContainerAcl(); + $result->_publicAccess = $publicAccess; + $result->_signedIdentifiers = array(); + + if (!empty($parsed) && is_array($parsed['SignedIdentifier'])) { + $entries = $parsed['SignedIdentifier']; + $temp = Utilities::getArray($entries); + + foreach ($temp as $value) { + $startString = urldecode($value['AccessPolicy']['Start']); + $expiryString = urldecode($value['AccessPolicy']['Expiry']); + $start = Utilities::convertToDateTime($startString); + $expiry = Utilities::convertToDateTime($expiryString); + $permission = $value['AccessPolicy']['Permission']; + $id = $value['Id']; + $result->addSignedIdentifier($id, $start, $expiry, $permission); + } + } + + return $result; + } + + /** + * Gets container signed modifiers. + * + * @return array. + */ + public function getSignedIdentifiers() + { + return $this->_signedIdentifiers; + } + + /** + * Sets container signed modifiers. + * + * @param array $signedIdentifiers value. + * + * @return none. + */ + public function setSignedIdentifiers($signedIdentifiers) + { + $this->_signedIdentifiers = $signedIdentifiers; + } + + /** + * Gets container publicAccess. + * + * @return string. + */ + public function getPublicAccess() + { + return $this->_publicAccess; + } + + /** + * Sets container publicAccess. + * + * @param string $publicAccess value. + * + * @return none. + */ + public function setPublicAccess($publicAccess) + { + Validate::isTrue( + PublicAccessType::isValid($publicAccess), + Resources::INVALID_BLOB_PAT_MSG + ); + $this->_publicAccess = $publicAccess; + } + + /** + * Adds new signed modifier + * + * @param string $id a unique id for this modifier + * @param \DateTime $start The time at which the Shared Access Signature + * becomes valid. If omitted, start time for this call is assumed to be + * the time when the Blob service receives the request. + * @param \DateTime $expiry The time at which the Shared Access Signature + * becomes invalid. This field may be omitted if it has been specified as + * part of a container-level access policy. + * @param string $permission The permissions associated with the Shared + * Access Signature. The user is restricted to operations allowed by the + * permissions. Valid permissions values are read (r), write (w), delete (d) and + * list (l). + * + * @return none. + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/hh508996.aspx + */ + public function addSignedIdentifier($id, $start, $expiry, $permission) + { + Validate::isString($id, 'id'); + Validate::isDate($start); + Validate::isDate($expiry); + Validate::isString($permission, 'permission'); + + $accessPolicy = new AccessPolicy(); + $accessPolicy->setStart($start); + $accessPolicy->setExpiry($expiry); + $accessPolicy->setPermission($permission); + + $signedIdentifier = new SignedIdentifier(); + $signedIdentifier->setId($id); + $signedIdentifier->setAccessPolicy($accessPolicy); + + $this->_signedIdentifiers[] = $signedIdentifier; + } + + /** + * Converts this object to array representation for XML serialization + * + * @return array. + */ + public function toArray() + { + $array = array(); + + foreach ($this->_signedIdentifiers as $value) { + $array[] = $value->toArray(); + } + + return $array; + } + + /** + * Converts this current object to XML representation. + * + * @param XmlSerializer $xmlSerializer The XML serializer. + * + * @return string. + */ + public function toXml($xmlSerializer) + { + $properties = array( + XmlSerializer::DEFAULT_TAG => 'SignedIdentifier', + XmlSerializer::ROOT_NAME => self::$xmlRootName + ); + + return $xmlSerializer->serialize($this->toArray(), $properties); + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/ContainerProperties.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/ContainerProperties.php new file mode 100644 index 0000000..8a42bf1 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/ContainerProperties.php @@ -0,0 +1,95 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; + +/** + * Holds container properties fields + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class ContainerProperties +{ + /** + * @var \DateTime + */ + private $_lastModified; + + /** + * @var string + */ + private $_etag; + + /** + * Gets container lastModified. + * + * @return \DateTime. + */ + public function getLastModified() + { + return $this->_lastModified; + } + + /** + * Sets container lastModified. + * + * @param \DateTime $lastModified value. + * + * @return none. + */ + public function setLastModified($lastModified) + { + $this->_lastModified = $lastModified; + } + + /** + * Gets container etag. + * + * @return string. + */ + public function getETag() + { + return $this->_etag; + } + + /** + * Sets container etag. + * + * @param string $etag value. + * + * @return none. + */ + public function setETag($etag) + { + $this->_etag = $etag; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/CopyBlobOptions.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/CopyBlobOptions.php new file mode 100644 index 0000000..557d759 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/CopyBlobOptions.php @@ -0,0 +1,205 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; +use WindowsAzure\Common\Internal\Validate; + +/** + * optional parameters for CopyBlobOptions wrapper + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class CopyBlobOptions extends BlobServiceOptions +{ + + /** + * @var AccessCondition + */ + private $_accessCondition; + + /** + * @var AccessCondition + */ + private $_sourceAccessCondition; + + /** + * @var array + */ + private $_metadata; + + /** + * @var string + */ + private $_sourceSnapshot; + + /** + * @var string + */ + private $_leaseId; + + /** + * @var sourceLeaseId + */ + private $_sourceLeaseId; + + /** + * Gets access condition + * + * @return AccessCondition + */ + public function getAccessCondition() + { + return $this->_accessCondition; + } + + /** + * Sets access condition + * + * @param AccessCondition $accessCondition value to use. + * + * @return none. + */ + public function setAccessCondition($accessCondition) + { + $this->_accessCondition = $accessCondition; + } + + /** + * Gets source access condition + * + * @return SourceAccessCondition + */ + public function getSourceAccessCondition() + { + return $this->_sourceAccessCondition; + } + + /** + * Sets source access condition + * + * @param SourceAccessCondition $sourceAccessCondition value to use. + * + * @return none. + */ + public function setSourceAccessCondition($sourceAccessCondition) + { + $this->_sourceAccessCondition = $sourceAccessCondition; + } + + /** + * Gets metadata. + * + * @return array. + */ + public function getMetadata() + { + return $this->_metadata; + } + + /** + * Sets metadata. + * + * @param array $metadata value. + * + * @return none. + */ + public function setMetadata($metadata) + { + $this->_metadata = $metadata; + } + + /** + * Gets source snapshot. + * + * @return string + */ + public function getSourceSnapshot() + { + return $this->_sourceSnapshot; + } + + /** + * Sets source snapshot. + * + * @param string $sourceSnapshot value. + * + * @return none + */ + public function setSourceSnapshot($sourceSnapshot) + { + $this->_sourceSnapshot = $sourceSnapshot; + } + + /** + * Gets lease ID. + * + * @return string + */ + public function getLeaseId() + { + return $this->_leaseId; + } + + /** + * Sets lease ID. + * + * @param string $leaseId value. + * + * @return none + */ + public function setLeaseId($leaseId) + { + $this->_leaseId = $leaseId; + } + + /** + * Gets source lease ID. + * + * @return string + */ + public function getSourceLeaseId() + { + return $this->_sourceLeaseId; + } + + /** + * Sets source lease ID. + * + * @param string $sourceLeaseId value. + * + * @return none + */ + public function setSourceLeaseId($sourceLeaseId) + { + $this->_sourceLeaseId = $sourceLeaseId; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/CopyBlobResult.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/CopyBlobResult.php new file mode 100644 index 0000000..196528c --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/CopyBlobResult.php @@ -0,0 +1,120 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Utilities; + +/** + * The result of calling copyBlob API. + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class CopyBlobResult +{ + /** + * @var string + */ + private $_etag; + + /** + * @var \DateTime + */ + private $_lastModified; + + /** + * Creates CopyBlobResult object from the response of the copy blob request. + * + * @param array $headers The HTTP response headers in array representation. + * + * @return CopyBlobResult + */ + public static function create($headers) + { + $result = new CopyBlobResult(); + $result->setETag(Utilities::tryGetValueInsensitive( + Resources::ETAG, + $headers)); + if (Utilities::arrayKeyExistsInsensitive(Resources::LAST_MODIFIED, $headers)) { + $lastModified = Utilities::tryGetValueInsensitive( + Resources::LAST_MODIFIED, + $headers); + $result->setLastModified(Utilities::rfc1123ToDateTime($lastModified)); + } + + return $result; + } + + /** + * Gets ETag. + * + * @return string + */ + public function getETag() + { + return $this->_etag; + } + + /** + * Sets ETag. + * + * @param string $etag value. + * + * @return none + */ + public function setETag($etag) + { + $this->_etag = $etag; + } + + /** + * Gets blob lastModified. + * + * @return \DateTime + */ + public function getLastModified() + { + return $this->_lastModified; + } + + /** + * Sets blob lastModified. + * + * @param \DateTime $lastModified value. + * + * @return none + */ + public function setLastModified($lastModified) + { + $this->_lastModified = $lastModified; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/CreateBlobBlockOptions.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/CreateBlobBlockOptions.php new file mode 100644 index 0000000..4fceff8 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/CreateBlobBlockOptions.php @@ -0,0 +1,95 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; + +/** + * Optional parameters for createBlobBlock wrapper + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class CreateBlobBlockOptions extends BlobServiceOptions +{ + /** + * @var string + */ + private $_contentMD5; + + /** + * @var string + */ + private $_leaseId; + + /** + * Gets lease Id for the blob + * + * @return string + */ + public function getLeaseId() + { + return $this->_leaseId; + } + + /** + * Sets lease Id for the blob + * + * @param string $leaseId the blob lease id. + * + * @return none + */ + public function setLeaseId($leaseId) + { + $this->_leaseId = $leaseId; + } + + /** + * Gets blob contentMD5. + * + * @return string. + */ + public function getContentMD5() + { + return $this->_contentMD5; + } + + /** + * Sets blob contentMD5. + * + * @param string $contentMD5 value. + * + * @return none. + */ + public function setContentMD5($contentMD5) + { + $this->_contentMD5 = $contentMD5; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/CreateBlobOptions.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/CreateBlobOptions.php new file mode 100644 index 0000000..06eec16 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/CreateBlobOptions.php @@ -0,0 +1,421 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; +use WindowsAzure\Common\Internal\Validate; + +/** + * optional parameters for createXXXBlob wrapper + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class CreateBlobOptions extends BlobServiceOptions +{ + /** + * @var string + */ + private $_contentType; + + /** + * @var string + */ + private $_contentEncoding; + + /** + * @var string + */ + private $_contentLanguage; + + /** + * @var string + */ + private $_contentMD5; + + /** + * @var string + */ + private $_cacheControl; + + /** + * @var string + */ + private $_blobContentType; + + /** + * @var string + */ + private $_blobContentEncoding; + + /** + * @var string + */ + private $_blobContentLanguage; + + /** + * @var string + */ + private $_blobContentMD5; + + /** + * @var string + */ + private $_blobCacheControl; + + /** + * @var array + */ + private $_metadata; + + /** + * @var string + */ + private $_leaseId; + + /** + * @var integer + */ + private $_sequenceNumber; + + /** + * @var AccessCondition + */ + private $_accessCondition; + + /** + * Gets blob ContentType. + * + * @return string. + */ + public function getBlobContentType() + { + return $this->_blobContentType; + } + + /** + * Sets blob ContentType. + * + * @param string $blobContentType value. + * + * @return none. + */ + public function setBlobContentType($blobContentType) + { + $this->_blobContentType = $blobContentType; + } + + /** + * Gets blob ContentEncoding. + * + * @return string. + */ + public function getBlobContentEncoding() + { + return $this->_blobContentEncoding; + } + + /** + * Sets blob ContentEncoding. + * + * @param string $blobContentEncoding value. + * + * @return none. + */ + public function setBlobContentEncoding($blobContentEncoding) + { + $this->_blobContentEncoding = $blobContentEncoding; + } + + /** + * Gets blob ContentLanguage. + * + * @return string. + */ + public function getBlobContentLanguage() + { + return $this->_blobContentLanguage; + } + + /** + * Sets blob ContentLanguage. + * + * @param string $blobContentLanguage value. + * + * @return none. + */ + public function setBlobContentLanguage($blobContentLanguage) + { + $this->_blobContentLanguage = $blobContentLanguage; + } + + /** + * Gets blob ContentMD5. + * + * @return string. + */ + public function getBlobContentMD5() + { + return $this->_blobContentMD5; + } + + /** + * Sets blob ContentMD5. + * + * @param string $blobContentMD5 value. + * + * @return none. + */ + public function setBlobContentMD5($blobContentMD5) + { + $this->_blobContentMD5 = $blobContentMD5; + } + + /** + * Gets blob cache control. + * + * @return string. + */ + public function getBlobCacheControl() + { + return $this->_blobCacheControl; + } + + /** + * Sets blob cacheControl. + * + * @param string $blobCacheControl value to use. + * + * @return none. + */ + public function setBlobCacheControl($blobCacheControl) + { + $this->_blobCacheControl = $blobCacheControl; + } + + /** + * Gets blob contentType. + * + * @return string. + */ + public function getContentType() + { + return $this->_contentType; + } + + /** + * Sets blob contentType. + * + * @param string $contentType value. + * + * @return none. + */ + public function setContentType($contentType) + { + $this->_contentType = $contentType; + } + + /** + * Gets contentEncoding. + * + * @return string. + */ + public function getContentEncoding() + { + return $this->_contentEncoding; + } + + /** + * Sets contentEncoding. + * + * @param string $contentEncoding value. + * + * @return none. + */ + public function setContentEncoding($contentEncoding) + { + $this->_contentEncoding = $contentEncoding; + } + + /** + * Gets contentLanguage. + * + * @return string. + */ + public function getContentLanguage() + { + return $this->_contentLanguage; + } + + /** + * Sets contentLanguage. + * + * @param string $contentLanguage value. + * + * @return none. + */ + public function setContentLanguage($contentLanguage) + { + $this->_contentLanguage = $contentLanguage; + } + + /** + * Gets contentMD5. + * + * @return string. + */ + public function getContentMD5() + { + return $this->_contentMD5; + } + + /** + * Sets contentMD5. + * + * @param string $contentMD5 value. + * + * @return none. + */ + public function setContentMD5($contentMD5) + { + $this->_contentMD5 = $contentMD5; + } + + /** + * Gets cacheControl. + * + * @return string. + */ + public function getCacheControl() + { + return $this->_cacheControl; + } + + /** + * Sets cacheControl. + * + * @param string $cacheControl value to use. + * + * @return none. + */ + public function setCacheControl($cacheControl) + { + $this->_cacheControl = $cacheControl; + } + + /** + * Gets access condition + * + * @return AccessCondition + */ + public function getAccessCondition() + { + return $this->_accessCondition; + } + + /** + * Sets access condition + * + * @param AccessCondition $accessCondition value to use. + * + * @return none. + */ + public function setAccessCondition($accessCondition) + { + $this->_accessCondition = $accessCondition; + } + + /** + * Gets blob metadata. + * + * @return array. + */ + public function getMetadata() + { + return $this->_metadata; + } + + /** + * Sets blob metadata. + * + * @param string $metadata value. + * + * @return none. + */ + public function setMetadata($metadata) + { + $this->_metadata = $metadata; + } + + /** + * Gets blob sequenceNumber. + * + * @return int. + */ + public function getSequenceNumber() + { + return $this->_sequenceNumber; + } + + /** + * Sets blob sequenceNumber. + * + * @param int $sequenceNumber value. + * + * @return none. + */ + public function setSequenceNumber($sequenceNumber) + { + Validate::isInteger($sequenceNumber, 'sequenceNumber'); + $this->_sequenceNumber = $sequenceNumber; + } + + /** + * Gets lease Id for the blob + * + * @return string + */ + public function getLeaseId() + { + return $this->_leaseId; + } + + /** + * Sets lease Id for the blob + * + * @param string $leaseId the blob lease id. + * + * @return none + */ + public function setLeaseId($leaseId) + { + $this->_leaseId = $leaseId; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/CreateBlobPagesOptions.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/CreateBlobPagesOptions.php new file mode 100644 index 0000000..3eeb03e --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/CreateBlobPagesOptions.php @@ -0,0 +1,122 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; + +/** + * Optional parameters for create and clear blob pages + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class CreateBlobPagesOptions extends BlobServiceOptions +{ + /** + * @var string + */ + private $_contentMD5; + + /** + * @var string + */ + private $_leaseId; + + /** + * @var AccessCondition + */ + private $_accessCondition; + + /** + * Gets access condition + * + * @return AccessCondition + */ + public function getAccessCondition() + { + return $this->_accessCondition; + } + + /** + * Sets access condition + * + * @param AccessCondition $accessCondition value to use. + * + * @return none. + */ + public function setAccessCondition($accessCondition) + { + $this->_accessCondition = $accessCondition; + } + + /** + * Gets lease Id for the blob + * + * @return string + */ + public function getLeaseId() + { + return $this->_leaseId; + } + + /** + * Sets lease Id for the blob + * + * @param string $leaseId the blob lease id. + * + * @return none + */ + public function setLeaseId($leaseId) + { + $this->_leaseId = $leaseId; + } + + /** + * Gets blob contentMD5. + * + * @return string. + */ + public function getContentMD5() + { + return $this->_contentMD5; + } + + /** + * Sets blob contentMD5. + * + * @param string $contentMD5 value. + * + * @return none. + */ + public function setContentMD5($contentMD5) + { + $this->_contentMD5 = $contentMD5; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/CreateBlobPagesResult.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/CreateBlobPagesResult.php new file mode 100644 index 0000000..a0627e0 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/CreateBlobPagesResult.php @@ -0,0 +1,184 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Validate; +use WindowsAzure\Common\Internal\Utilities; + +/** + * Holds result of calling create or clear blob pages + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class CreateBlobPagesResult +{ + /** + * @var \DateTime + */ + private $_lastModified; + + /** + * @var string + */ + private $_etag; + + /** + * @var integer + */ + private $_sequenceNumber; + + /** + * @var string + */ + private $_contentMD5; + + /** + * Creates CreateBlobPagesResult object from $parsed response in array + * representation + * + * @param array $headers HTTP response headers + * + * @return CreateBlobPagesResult + */ + public static function create($headers) + { + $result = new CreateBlobPagesResult(); + $clean = array_change_key_case($headers); + + $date = $clean[Resources::LAST_MODIFIED]; + $date = Utilities::rfc1123ToDateTime($date); + $result->setETag($clean[Resources::ETAG]); + $result->setLastModified($date); + $result->setContentMD5( + Utilities::tryGetValue($clean, Resources::CONTENT_MD5) + ); + $result->setSequenceNumber( + intval( + Utilities::tryGetValue($clean, Resources::X_MS_BLOB_SEQUENCE_NUMBER) + ) + ); + + return $result; + } + + /** + * Gets blob lastModified. + * + * @return \DateTime. + */ + public function getLastModified() + { + return $this->_lastModified; + } + + /** + * Sets blob lastModified. + * + * @param \DateTime $lastModified value. + * + * @return none. + */ + public function setLastModified($lastModified) + { + Validate::isDate($lastModified); + $this->_lastModified = $lastModified; + } + + /** + * Gets blob etag. + * + * @return string. + */ + public function getETag() + { + return $this->_etag; + } + + /** + * Sets blob etag. + * + * @param string $etag value. + * + * @return none. + */ + public function setETag($etag) + { + Validate::isString($etag, 'etag'); + $this->_etag = $etag; + } + + /** + * Gets blob contentMD5. + * + * @return string. + */ + public function getContentMD5() + { + return $this->_contentMD5; + } + + /** + * Sets blob contentMD5. + * + * @param string $contentMD5 value. + * + * @return none. + */ + public function setContentMD5($contentMD5) + { + $this->_contentMD5 = $contentMD5; + } + + /** + * Gets blob sequenceNumber. + * + * @return int. + */ + public function getSequenceNumber() + { + return $this->_sequenceNumber; + } + + /** + * Sets blob sequenceNumber. + * + * @param int $sequenceNumber value. + * + * @return none. + */ + public function setSequenceNumber($sequenceNumber) + { + Validate::isInteger($sequenceNumber, 'sequenceNumber'); + $this->_sequenceNumber = $sequenceNumber; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/CreateBlobSnapshotOptions.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/CreateBlobSnapshotOptions.php new file mode 100644 index 0000000..fdcfa52 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/CreateBlobSnapshotOptions.php @@ -0,0 +1,123 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; + +/** + * The optional parameters for createBlobSnapshot wrapper. + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class CreateBlobSnapshotOptions extends BlobServiceOptions +{ + /** + * @var array + */ + private $_metadata; + + /** + * @var AccessCondition + */ + private $_accessCondition; + + /** + * @var string + */ + private $_leaseId; + + /** + * Gets metadata. + * + * @return array + */ + public function getMetadata() + { + return $this->_metadata; + } + + /** + * Sets metadata. + * + * @param array $metadata The metadata array. + * + * @return none + */ + public function setMetadata($metadata) + { + $this->_metadata = $metadata; + } + + /** + * Gets access condition. + * + * @return AccessCondition + */ + public function getAccessCondition() + { + return $this->_accessCondition; + } + + /** + * Sets access condition. + * + * @param AccessCondition $accessCondition The access condition object. + * + * @return none + */ + public function setAccessCondition($accessCondition) + { + $this->_accessCondition = $accessCondition; + } + + /** + * Gets lease Id. + * + * @return string + */ + public function getLeaseId() + { + return $this->_leaseId; + } + + /** + * Sets lease Id. + * + * @param string $leaseId The lease Id. + * + * @return none + */ + public function setLeaseId($leaseId) + { + $this->_leaseId = $leaseId; + } + +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/CreateBlobSnapshotResult.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/CreateBlobSnapshotResult.php new file mode 100644 index 0000000..84f8d0e --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/CreateBlobSnapshotResult.php @@ -0,0 +1,154 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Validate; +use WindowsAzure\Common\Internal\Utilities; + +/** + * The result of creating Blob snapshot. + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class CreateBlobSnapshotResult +{ + /** + * A DateTime value which uniquely identifies the snapshot. + * @var string + */ + private $_snapshot; + + /** + * The ETag for the destination blob. + * @var string + */ + private $_etag; + + /** + * The date/time that the copy operation to the destination blob completed. + * @var \DateTime + */ + private $_lastModified; + + /** + * Creates CreateBlobSnapshotResult object from the response of the + * create Blob snapshot request. + * + * @param array $headers The HTTP response headers in array representation. + * + * @return CreateBlobSnapshotResult + */ + public static function create($headers) + { + $result = new CreateBlobSnapshotResult(); + $headerWithLowerCaseKey = array_change_key_case($headers); + + $result->setETag($headerWithLowerCaseKey[Resources::ETAG]); + + $result->setLastModified( + Utilities::rfc1123ToDateTime( + $headerWithLowerCaseKey[Resources::LAST_MODIFIED] + ) + ); + + $result->setSnapshot($headerWithLowerCaseKey[Resources::X_MS_SNAPSHOT]); + + return $result; + } + + /** + * Gets snapshot. + * + * @return string + */ + public function getSnapshot() + { + return $this->_snapshot; + } + + /** + * Sets snapshot. + * + * @param string $snapshot value. + * + * @return none + */ + public function setSnapshot($snapshot) + { + $this->_snapshot = $snapshot; + } + + /** + * Gets ETag. + * + * @return string + */ + public function getETag() + { + return $this->_etag; + } + + /** + * Sets ETag. + * + * @param string $etag value. + * + * @return none + */ + public function setETag($etag) + { + $this->_etag = $etag; + } + + /** + * Gets blob lastModified. + * + * @return \DateTime + */ + public function getLastModified() + { + return $this->_lastModified; + } + + /** + * Sets blob lastModified. + * + * @param \DateTime $lastModified value. + * + * @return none + */ + public function setLastModified($lastModified) + { + $this->_lastModified = $lastModified; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/CreateContainerOptions.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/CreateContainerOptions.php new file mode 100644 index 0000000..811b50b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/CreateContainerOptions.php @@ -0,0 +1,123 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; +use WindowsAzure\Blob\Models\BlobServiceOptions; +use WindowsAzure\Common\Internal\Validate; + +/** + * Optional parameters for createContainer API + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class CreateContainerOptions extends BlobServiceOptions +{ + /** + * @var string + */ + private $_publicAccess; + + /** + * @var array + */ + private $_metadata; + + /** + * Gets container public access. + * + * @return string. + */ + public function getPublicAccess() + { + return $this->_publicAccess; + } + + /** + * Specifies whether data in the container may be accessed publicly and the level + * of access. Possible values include: + * 1) container: Specifies full public read access for container and blob data. + * Clients can enumerate blobs within the container via anonymous request, but + * cannot enumerate containers within the storage account. + * 2) blob: Specifies public read access for blobs. Blob data within this + * container can be read via anonymous request, but container data is not + * available. Clients cannot enumerate blobs within the container via + * anonymous request. + * If this value is not specified in the request, container data is private to + * the account owner. + * + * @param string $publicAccess access modifier for the container + * + * @return none. + */ + public function setPublicAccess($publicAccess) + { + Validate::isString($publicAccess, 'publicAccess'); + $this->_publicAccess = $publicAccess; + } + + /** + * Gets user defined metadata. + * + * @return array. + */ + public function getMetadata() + { + return $this->_metadata; + } + + /** + * Sets user defined metadata. This metadata should be added without the header + * prefix (x-ms-meta-*). + * + * @param array $metadata user defined metadata object in array form. + * + * @return none. + */ + public function setMetadata($metadata) + { + $this->_metadata = $metadata; + } + + /** + * Adds new metadata element. This element should be added without the header + * prefix (x-ms-meta-*). + * + * @param string $key metadata key element. + * @param string $value metadata value element. + * + * @return none. + */ + public function addMetadata($key, $value) + { + $this->_metadata[$key] = $value; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/DeleteBlobOptions.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/DeleteBlobOptions.php new file mode 100644 index 0000000..3792231 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/DeleteBlobOptions.php @@ -0,0 +1,151 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; +use WindowsAzure\Common\Internal\Validate; + +/** + * Optional parameters for deleteBlob wrapper + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class DeleteBlobOptions extends BlobServiceOptions +{ + /** + * @var string + */ + private $_leaseId; + + /** + * @var string + */ + private $_snapshot; + + /** + * @var AccessCondition + */ + private $_accessCondition; + + /** + * @var boolean + */ + private $_deleteSnaphotsOnly; + + /** + * Gets lease Id for the blob + * + * @return string + */ + public function getLeaseId() + { + return $this->_leaseId; + } + + /** + * Sets lease Id for the blob + * + * @param string $leaseId the blob lease id. + * + * @return none + */ + public function setLeaseId($leaseId) + { + $this->_leaseId = $leaseId; + } + + /** + * Gets access condition + * + * @return AccessCondition + */ + public function getAccessCondition() + { + return $this->_accessCondition; + } + + /** + * Sets access condition + * + * @param AccessCondition $accessCondition value to use. + * + * @return none. + */ + public function setAccessCondition($accessCondition) + { + $this->_accessCondition = $accessCondition; + } + + /** + * Gets blob snapshot. + * + * @return string. + */ + public function getSnapshot() + { + return $this->_snapshot; + } + + /** + * Sets blob snapshot. + * + * @param string $snapshot value. + * + * @return none. + */ + public function setSnapshot($snapshot) + { + $this->_snapshot = $snapshot; + } + + /** + * Gets blob deleteSnaphotsOnly. + * + * @return boolean. + */ + public function getDeleteSnaphotsOnly() + { + return $this->_deleteSnaphotsOnly; + } + + /** + * Sets blob deleteSnaphotsOnly. + * + * @param string $deleteSnaphotsOnly value. + * + * @return boolean. + */ + public function setDeleteSnaphotsOnly($deleteSnaphotsOnly) + { + Validate::isBoolean($deleteSnaphotsOnly); + $this->_deleteSnaphotsOnly = $deleteSnaphotsOnly; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/DeleteContainerOptions.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/DeleteContainerOptions.php new file mode 100644 index 0000000..9066804 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/DeleteContainerOptions.php @@ -0,0 +1,68 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; + +/** + * The optional for deleteContainer API. + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class DeleteContainerOptions extends BlobServiceOptions +{ + /** + * @var AccessCondition + */ + private $_accessCondition; + + /** + * Gets access condition + * + * @return AccessCondition + */ + public function getAccessCondition() + { + return $this->_accessCondition; + } + + /** + * Sets access condition + * + * @param AccessCondition $accessCondition value to use. + * + * @return none. + */ + public function setAccessCondition($accessCondition) + { + $this->_accessCondition = $accessCondition; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/GetBlobMetadataOptions.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/GetBlobMetadataOptions.php new file mode 100644 index 0000000..37d5c20 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/GetBlobMetadataOptions.php @@ -0,0 +1,122 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; + +/** + * Optional parameters for getBlobMetadata wrapper + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class GetBlobMetadataOptions extends BlobServiceOptions +{ + /** + * @var string + */ + private $_leaseId; + + /** + * @var string + */ + private $_snapshot; + + /** + * @var AccessCondition + */ + private $_accessCondition; + + /** + * Gets lease Id for the blob + * + * @return string + */ + public function getLeaseId() + { + return $this->_leaseId; + } + + /** + * Sets lease Id for the blob + * + * @param string $leaseId the blob lease id. + * + * @return none + */ + public function setLeaseId($leaseId) + { + $this->_leaseId = $leaseId; + } + + /** + * Gets access condition + * + * @return AccessCondition + */ + public function getAccessCondition() + { + return $this->_accessCondition; + } + + /** + * Sets access condition + * + * @param AccessCondition $accessCondition value to use. + * + * @return none. + */ + public function setAccessCondition($accessCondition) + { + $this->_accessCondition = $accessCondition; + } + + /** + * Gets blob snapshot. + * + * @return string. + */ + public function getSnapshot() + { + return $this->_snapshot; + } + + /** + * Sets blob snapshot. + * + * @param string $snapshot value. + * + * @return none. + */ + public function setSnapshot($snapshot) + { + $this->_snapshot = $snapshot; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/GetBlobMetadataResult.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/GetBlobMetadataResult.php new file mode 100644 index 0000000..9d3610c --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/GetBlobMetadataResult.php @@ -0,0 +1,147 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Validate; +use WindowsAzure\Common\Internal\Utilities; + +/** + * Holds results of calling getBlobMetadata wrapper + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class GetBlobMetadataResult +{ + + /** + * @var \DateTime + */ + private $_lastModified; + + /** + * @var string + */ + private $_etag; + + /** + * @var array + */ + private $_metadata; + + /** + * Creates GetBlobMetadataResult from response headers. + * + * @param array $headers The HTTP response headers. + * @param array $metadata The blob metadata array. + * + * @return GetBlobMetadataResult + */ + public static function create($headers, $metadata) + { + $result = new GetBlobMetadataResult(); + $date = $headers[Resources::LAST_MODIFIED]; + $result->setLastModified(Utilities::rfc1123ToDateTime($date)); + $result->setETag($headers[Resources::ETAG]); + $result->setMetadata(is_null($metadata) ? array() : $metadata); + + return $result; + } + + /** + * Gets blob lastModified. + * + * @return \DateTime. + */ + public function getLastModified() + { + return $this->_lastModified; + } + + /** + * Sets blob lastModified. + * + * @param \DateTime $lastModified value. + * + * @return none. + */ + public function setLastModified($lastModified) + { + Validate::isDate($lastModified); + $this->_lastModified = $lastModified; + } + + /** + * Gets blob etag. + * + * @return string. + */ + public function getETag() + { + return $this->_etag; + } + + /** + * Sets blob etag. + * + * @param string $etag value. + * + * @return none. + */ + public function setETag($etag) + { + Validate::isString($etag, 'etag'); + $this->_etag = $etag; + } + + /** + * Gets blob metadata. + * + * @return array. + */ + public function getMetadata() + { + return $this->_metadata; + } + + /** + * Sets blob metadata. + * + * @param string $metadata value. + * + * @return none. + */ + public function setMetadata($metadata) + { + $this->_metadata = $metadata; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/GetBlobOptions.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/GetBlobOptions.php new file mode 100644 index 0000000..dd41e01 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/GetBlobOptions.php @@ -0,0 +1,207 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; +use WindowsAzure\Common\Internal\Validate; + +/** + * Optional parameters for getBlob wrapper + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class GetBlobOptions extends BlobServiceOptions +{ + /** + * @var string + */ + private $_leaseId; + + /** + * @var string + */ + private $_snapshot; + + /** + * @var AccessCondition + */ + private $_accessCondition; + + /** + * @var boolean + */ + private $_computeRangeMD5; + + /** + * @var integer + */ + private $_rangeStart; + + /** + * @var integer + */ + private $_rangeEnd; + + /** + * Gets lease Id for the blob + * + * @return string + */ + public function getLeaseId() + { + return $this->_leaseId; + } + + /** + * Sets lease Id for the blob + * + * @param string $leaseId the blob lease id. + * + * @return none + */ + public function setLeaseId($leaseId) + { + $this->_leaseId = $leaseId; + } + + /** + * Gets access condition + * + * @return AccessCondition + */ + public function getAccessCondition() + { + return $this->_accessCondition; + } + + /** + * Sets access condition + * + * @param AccessCondition $accessCondition value to use. + * + * @return none. + */ + public function setAccessCondition($accessCondition) + { + $this->_accessCondition = $accessCondition; + } + + /** + * Gets blob snapshot. + * + * @return string. + */ + public function getSnapshot() + { + return $this->_snapshot; + } + + /** + * Sets blob snapshot. + * + * @param string $snapshot value. + * + * @return none. + */ + public function setSnapshot($snapshot) + { + $this->_snapshot = $snapshot; + } + + /** + * Gets rangeStart + * + * @return integer + */ + public function getRangeStart() + { + return $this->_rangeStart; + } + + /** + * Sets rangeStart + * + * @param integer $rangeStart the blob lease id. + * + * @return none + */ + public function setRangeStart($rangeStart) + { + Validate::isInteger($rangeStart, 'rangeStart'); + $this->_rangeStart = $rangeStart; + } + + /** + * Gets rangeEnd + * + * @return integer + */ + public function getRangeEnd() + { + return $this->_rangeEnd; + } + + /** + * Sets rangeEnd + * + * @param integer $rangeEnd range end value in bytes + * + * @return none + */ + public function setRangeEnd($rangeEnd) + { + Validate::isInteger($rangeEnd, 'rangeEnd'); + $this->_rangeEnd = $rangeEnd; + } + + /** + * Gets computeRangeMD5 + * + * @return boolean + */ + public function getComputeRangeMD5() + { + return $this->_computeRangeMD5; + } + + /** + * Sets computeRangeMD5 + * + * @param boolean $computeRangeMD5 value + * + * @return none + */ + public function setComputeRangeMD5($computeRangeMD5) + { + Validate::isBoolean($computeRangeMD5); + $this->_computeRangeMD5 = $computeRangeMD5; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/GetBlobPropertiesOptions.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/GetBlobPropertiesOptions.php new file mode 100644 index 0000000..155e70a --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/GetBlobPropertiesOptions.php @@ -0,0 +1,122 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; + +/** + * Optional parameters for getBlobProperties wrapper + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class GetBlobPropertiesOptions extends BlobServiceOptions +{ + /** + * @var string + */ + private $_leaseId; + + /** + * @var string + */ + private $_snapshot; + + /** + * @var AccessCondition + */ + private $_accessCondition; + + /** + * Gets lease Id for the blob + * + * @return string + */ + public function getLeaseId() + { + return $this->_leaseId; + } + + /** + * Sets lease Id for the blob + * + * @param string $leaseId the blob lease id. + * + * @return none + */ + public function setLeaseId($leaseId) + { + $this->_leaseId = $leaseId; + } + + /** + * Gets access condition + * + * @return AccessCondition + */ + public function getAccessCondition() + { + return $this->_accessCondition; + } + + /** + * Sets access condition + * + * @param AccessCondition $accessCondition value to use. + * + * @return none. + */ + public function setAccessCondition($accessCondition) + { + $this->_accessCondition = $accessCondition; + } + + /** + * Gets blob snapshot. + * + * @return string. + */ + public function getSnapshot() + { + return $this->_snapshot; + } + + /** + * Sets blob snapshot. + * + * @param string $snapshot value. + * + * @return none. + */ + public function setSnapshot($snapshot) + { + $this->_snapshot = $snapshot; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/GetBlobPropertiesResult.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/GetBlobPropertiesResult.php new file mode 100644 index 0000000..6e270e2 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/GetBlobPropertiesResult.php @@ -0,0 +1,95 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; + +/** + * Holds result of calling getBlobProperties + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class GetBlobPropertiesResult +{ + /** + * @var BlobProperties + */ + private $_properties; + + /** + * @var array + */ + private $_metadata; + + /** + * Gets blob metadata. + * + * @return array. + */ + public function getMetadata() + { + return $this->_metadata; + } + + /** + * Sets blob metadata. + * + * @param string $metadata value. + * + * @return none. + */ + public function setMetadata($metadata) + { + $this->_metadata = $metadata; + } + + /** + * Gets blob properties. + * + * @return BlobProperties. + */ + public function getProperties() + { + return $this->_properties; + } + + /** + * Sets blob properties. + * + * @param BlobProperties $properties value. + * + * @return none. + */ + public function setProperties($properties) + { + $this->_properties = $properties; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/GetBlobResult.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/GetBlobResult.php new file mode 100644 index 0000000..06a9818 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/GetBlobResult.php @@ -0,0 +1,143 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; +use WindowsAzure\Blob\Models\BlobProperties; +use WindowsAzure\Common\Internal\Utilities; + +/** + * Holds result of GetBlob API. + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class GetBlobResult +{ + /** + * @var BlobProperties + */ + private $_properties; + + /** + * @var array + */ + private $_metadata; + + /** + * @var resource + */ + private $_contentStream; + + /** + * Creates GetBlobResult from getBlob call. + * + * @param array $headers The HTTP response headers. + * @param string $body The response body. + * @param array $metadata The blob metadata. + * + * @return GetBlobResult + */ + public static function create($headers, $body, $metadata) + { + $result = new GetBlobResult(); + $result->setContentStream(Utilities::stringToStream($body)); + $result->setProperties(BlobProperties::create($headers)); + $result->setMetadata(is_null($metadata) ? array() : $metadata); + + return $result; + } + + /** + * Gets blob metadata. + * + * @return array + */ + public function getMetadata() + { + return $this->_metadata; + } + + /** + * Sets blob metadata. + * + * @param string $metadata value. + * + * @return none + */ + public function setMetadata($metadata) + { + $this->_metadata = $metadata; + } + + /** + * Gets blob properties. + * + * @return BlobProperties + */ + public function getProperties() + { + return $this->_properties; + } + + /** + * Sets blob properties. + * + * @param BlobProperties $properties value. + * + * @return none + */ + public function setProperties($properties) + { + $this->_properties = $properties; + } + + /** + * Gets blob contentStream. + * + * @return resource + */ + public function getContentStream() + { + return $this->_contentStream; + } + + /** + * Sets blob contentStream. + * + * @param resource $contentStream The stream handle. + * + * @return none + */ + public function setContentStream($contentStream) + { + $this->_contentStream = $contentStream; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/GetContainerACLResult.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/GetContainerACLResult.php new file mode 100644 index 0000000..f1df9ce --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/GetContainerACLResult.php @@ -0,0 +1,145 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; +use WindowsAzure\Blob\Models\ContainerAcl; + +/** + * Holds container ACL + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class GetContainerAclResult +{ + /** + * @var ContainerAcl + */ + private $_containerACL; + + /** + * @var \DateTime + */ + private $_lastModified; + + /** + * @var string + */ + private $_etag; + + /** + * Parses the given array into signed identifiers + * + * @param string $publicAccess container public access + * @param string $etag container etag + * @param \DateTime $lastModified last modification date + * @param array $parsed parsed response into array + * representation + * + * @return none. + */ + public static function create($publicAccess, $etag, $lastModified, $parsed) + { + $result = new GetContainerAclResult(); + $result->setETag($etag); + $result->setLastModified($lastModified); + $acl = ContainerAcl::create($publicAccess, $parsed); + $result->setContainerAcl($acl); + + return $result; + } + + /** + * Gets container ACL + * + * @return ContainerAcl + */ + public function getContainerAcl() + { + return $this->_containerACL; + } + + /** + * Sets container ACL + * + * @param ContainerAcl $containerACL value. + * + * @return none. + */ + public function setContainerAcl($containerACL) + { + $this->_containerACL = $containerACL; + } + + /** + * Gets container lastModified. + * + * @return \DateTime. + */ + public function getLastModified() + { + return $this->_lastModified; + } + + /** + * Sets container lastModified. + * + * @param \DateTime $lastModified value. + * + * @return none. + */ + public function setLastModified($lastModified) + { + $this->_lastModified = $lastModified; + } + + /** + * Gets container etag. + * + * @return string. + */ + public function getETag() + { + return $this->_etag; + } + + /** + * Sets container etag. + * + * @param string $etag value. + * + * @return none. + */ + public function setETag($etag) + { + $this->_etag = $etag; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/GetContainerPropertiesResult.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/GetContainerPropertiesResult.php new file mode 100644 index 0000000..b3e606a --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/GetContainerPropertiesResult.php @@ -0,0 +1,126 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; + +/** + * Holds result of getContainerProperties and getContainerMetadata + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class GetContainerPropertiesResult +{ + /** + * @var \DateTime + */ + private $_lastModified; + + /** + * @var string + */ + private $_etag; + + /** + * @var array + */ + private $_metadata; + + /** + * Any operation that modifies the container or its properties or metadata + * updates the last modified time. Operations on blobs do not affect the last + * modified time of the container. + * + * @return \DateTime. + */ + public function getLastModified() + { + return $this->_lastModified; + } + + /** + * Sets container lastModified. + * + * @param \DateTime $lastModified value. + * + * @return none. + */ + public function setLastModified($lastModified) + { + $this->_lastModified = $lastModified; + } + + /** + * The entity tag for the container. If the request version is 2011-08-18 or + * newer, the ETag value will be in quotes. + * + * @return string. + */ + public function getETag() + { + return $this->_etag; + } + + /** + * Sets container etag. + * + * @param string $etag value. + * + * @return none. + */ + public function setETag($etag) + { + $this->_etag = $etag; + } + + /** + * Gets user defined metadata. + * + * @return array. + */ + public function getMetadata() + { + return $this->_metadata; + } + + /** + * Sets user defined metadata. This metadata should be added without the header + * prefix (x-ms-meta-*). + * + * @param array $metadata user defined metadata object in array form. + * + * @return none. + */ + public function setMetadata($metadata) + { + $this->_metadata = $metadata; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/LeaseMode.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/LeaseMode.php new file mode 100644 index 0000000..32f1763 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/LeaseMode.php @@ -0,0 +1,46 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; + +/** + * Modes for leasing a blob + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class LeaseMode +{ + const ACQUIRE_ACTION = 'acquire'; + const RENEW_ACTION = 'renew'; + const RELEASE_ACTION = 'release'; + const BREAK_ACTION = 'break'; +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/ListBlobBlocksOptions.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/ListBlobBlocksOptions.php new file mode 100644 index 0000000..0b33617 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/ListBlobBlocksOptions.php @@ -0,0 +1,187 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; +use WindowsAzure\Common\Internal\Validate; + +/** + * Optional parameters for listBlobBlock wrapper + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class ListBlobBlocksOptions extends BlobServiceOptions +{ + /** + * @var string + */ + private $_leaseId; + + /** + * @var string + */ + private $_snapshot; + + /** + * @var boolean + */ + private $_includeUncommittedBlobs; + + /** + * @var boolean + */ + private $_includeCommittedBlobs; + + /** + * Holds result of list type. You can access it by this order: + * $_listType[$this->_includeUncommittedBlobs][$this->_includeCommittedBlobs] + * + * @var array + */ + private static $_listType; + + /** + * Constructs the static variable $listType. + */ + public function __construct() + { + self::$_listType[true][true] = 'all'; + self::$_listType[true][false] = 'uncommitted'; + self::$_listType[false][true] = 'committed'; + self::$_listType[false][false] = 'all'; + + $this->_includeUncommittedBlobs = false; + $this->_includeCommittedBlobs = false; + } + + /** + * Gets lease Id for the blob + * + * @return string + */ + public function getLeaseId() + { + return $this->_leaseId; + } + + /** + * Sets lease Id for the blob + * + * @param string $leaseId the blob lease id. + * + * @return none + */ + public function setLeaseId($leaseId) + { + $this->_leaseId = $leaseId; + } + + /** + * Gets blob snapshot. + * + * @return string. + */ + public function getSnapshot() + { + return $this->_snapshot; + } + + /** + * Sets blob snapshot. + * + * @param string $snapshot value. + * + * @return none. + */ + public function setSnapshot($snapshot) + { + $this->_snapshot = $snapshot; + } + + /** + * Sets the include uncommittedBlobs flag. + * + * @param bool $includeUncommittedBlobs value. + * + * @return none. + */ + public function setIncludeUncommittedBlobs($includeUncommittedBlobs) + { + Validate::isBoolean($includeUncommittedBlobs); + $this->_includeUncommittedBlobs = $includeUncommittedBlobs; + } + + /** + * Indicates if uncommittedBlobs is included or not. + * + * @return boolean. + */ + public function getIncludeUncommittedBlobs() + { + return $this->_includeUncommittedBlobs; + } + + /** + * Sets the include committedBlobs flag. + * + * @param bool $includeCommittedBlobs value. + * + * @return none. + */ + public function setIncludeCommittedBlobs($includeCommittedBlobs) + { + Validate::isBoolean($includeCommittedBlobs); + $this->_includeCommittedBlobs = $includeCommittedBlobs; + } + + /** + * Indicates if committedBlobs is included or not. + * + * @return boolean. + */ + public function getIncludeCommittedBlobs() + { + return $this->_includeCommittedBlobs; + } + + /** + * Gets block list type. + * + * @return string + */ + public function getBlockListType() + { + $includeUncommitted = $this->_includeUncommittedBlobs; + $includeCommitted = $this->_includeCommittedBlobs; + + return self::$_listType[$includeUncommitted][$includeCommitted]; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/ListBlobBlocksResult.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/ListBlobBlocksResult.php new file mode 100644 index 0000000..b3ab3df --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/ListBlobBlocksResult.php @@ -0,0 +1,274 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; +use WindowsAzure\Common\Internal\Validate; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Utilities; + +/** + * Holds result of listBlobBlocks + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class ListBlobBlocksResult +{ + /** + * @var \DateTime + */ + private $_lastModified; + + /** + * @var string + */ + private $_etag; + + /** + * @var string + */ + private $_contentType; + + /** + * @var integer + */ + private $_contentLength; + + /** + * @var array + */ + private $_committedBlocks; + + /** + * @var array + */ + private $_uncommittedBlocks; + + /** + * Gets block entries from parsed response + * + * @param array $parsed HTTP response + * @param string $type Block type + * + * @return array + */ + private static function _getEntries($parsed, $type) + { + $entries = array(); + + if (is_array($parsed)) { + $rawEntries = array(); + + if ( array_key_exists($type, $parsed) + && is_array($parsed[$type]) + && !empty($parsed[$type]) + ) { + $rawEntries = Utilities::getArray($parsed[$type]['Block']); + } + + foreach ($rawEntries as $value) { + $entries[base64_decode($value['Name'])] = $value['Size']; + } + } + + return $entries; + } + + /** + * Creates ListBlobBlocksResult from given response headers and parsed body + * + * @param array $headers HTTP response headers + * @param array $parsed HTTP response body in array representation + * + * @return ListBlobBlocksResult + */ + public static function create($headers, $parsed) + { + $result = new ListBlobBlocksResult(); + $clean = array_change_key_case($headers); + + $result->setETag(Utilities::tryGetValue($clean, Resources::ETAG)); + $date = Utilities::tryGetValue($clean, Resources::LAST_MODIFIED); + if (!is_null($date)) { + $date = Utilities::rfc1123ToDateTime($date); + $result->setLastModified($date); + } + $result->setContentLength( + intval( + Utilities::tryGetValue($clean, Resources::X_MS_BLOB_CONTENT_LENGTH) + ) + ); + $result->setContentType( + Utilities::tryGetValue($clean, Resources::CONTENT_TYPE) + ); + + $result->_uncommittedBlocks = self::_getEntries( + $parsed, 'UncommittedBlocks' + ); + $result->_committedBlocks = self::_getEntries($parsed, 'CommittedBlocks'); + + return $result; + } + + /** + * Gets blob lastModified. + * + * @return \DateTime. + */ + public function getLastModified() + { + return $this->_lastModified; + } + + /** + * Sets blob lastModified. + * + * @param \DateTime $lastModified value. + * + * @return none. + */ + public function setLastModified($lastModified) + { + Validate::isDate($lastModified); + $this->_lastModified = $lastModified; + } + + /** + * Gets blob etag. + * + * @return string. + */ + public function getETag() + { + return $this->_etag; + } + + /** + * Sets blob etag. + * + * @param string $etag value. + * + * @return none. + */ + public function setETag($etag) + { + $this->_etag = $etag; + } + + /** + * Gets blob contentType. + * + * @return string. + */ + public function getContentType() + { + return $this->_contentType; + } + + /** + * Sets blob contentType. + * + * @param string $contentType value. + * + * @return none. + */ + public function setContentType($contentType) + { + $this->_contentType = $contentType; + } + + /** + * Gets blob contentLength. + * + * @return integer. + */ + public function getContentLength() + { + return $this->_contentLength; + } + + /** + * Sets blob contentLength. + * + * @param integer $contentLength value. + * + * @return none. + */ + public function setContentLength($contentLength) + { + Validate::isInteger($contentLength, 'contentLength'); + $this->_contentLength = $contentLength; + } + + /** + * Gets uncommitted blocks + * + * @return array + */ + public function getUncommittedBlocks() + { + return $this->_uncommittedBlocks; + } + + /** + * Sets uncommitted blocks + * + * @param array $uncommittedBlocks The uncommitted blocks entries + * + * @return none. + */ + public function setUncommittedBlocks($uncommittedBlocks) + { + $this->_uncommittedBlocks = $uncommittedBlocks; + } + + /** + * Gets committed blocks + * + * @return array + */ + public function getCommittedBlocks() + { + return $this->_committedBlocks; + } + + /** + * Sets committed blocks + * + * @param array $committedBlocks The committed blocks entries + * + * @return none. + */ + public function setCommittedBlocks($committedBlocks) + { + $this->_committedBlocks = $committedBlocks; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/ListBlobsOptions.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/ListBlobsOptions.php new file mode 100644 index 0000000..f0db2dc --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/ListBlobsOptions.php @@ -0,0 +1,238 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; +use WindowsAzure\Common\Internal\Validate; + +/** + * Optional parameters for listBlobs API. + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class ListBlobsOptions extends BlobServiceOptions +{ + /** + * @var string + */ + private $_prefix; + + /** + * @var string + */ + private $_marker; + + /** + * @var string + */ + private $_delimiter; + + /** + * @var integer + */ + private $_maxResults; + + /** + * @var boolean + */ + private $_includeMetadata; + + /** + * @var boolean + */ + private $_includeSnapshots; + + /** + * @var boolean + */ + private $_includeUncommittedBlobs; + + /** + * Gets prefix. + * + * @return string. + */ + public function getPrefix() + { + return $this->_prefix; + } + + /** + * Sets prefix. + * + * @param string $prefix value. + * + * @return none. + */ + public function setPrefix($prefix) + { + Validate::isString($prefix, 'prefix'); + $this->_prefix = $prefix; + } + + /** + * Gets delimiter. + * + * @return string. + */ + public function getDelimiter() + { + return $this->_delimiter; + } + + /** + * Sets prefix. + * + * @param string $delimiter value. + * + * @return none. + */ + public function setDelimiter($delimiter) + { + Validate::isString($delimiter, 'delimiter'); + $this->_delimiter = $delimiter; + } + + /** + * Gets marker. + * + * @return string. + */ + public function getMarker() + { + return $this->_marker; + } + + /** + * Sets marker. + * + * @param string $marker value. + * + * @return none. + */ + public function setMarker($marker) + { + Validate::isString($marker, 'marker'); + $this->_marker = $marker; + } + + /** + * Gets max results. + * + * @return integer. + */ + public function getMaxResults() + { + return $this->_maxResults; + } + + /** + * Sets max results. + * + * @param integer $maxResults value. + * + * @return none. + */ + public function setMaxResults($maxResults) + { + Validate::isInteger($maxResults, 'maxResults'); + $this->_maxResults = $maxResults; + } + + /** + * Indicates if metadata is included or not. + * + * @return boolean. + */ + public function getIncludeMetadata() + { + return $this->_includeMetadata; + } + + /** + * Sets the include metadata flag. + * + * @param bool $includeMetadata value. + * + * @return none. + */ + public function setIncludeMetadata($includeMetadata) + { + Validate::isBoolean($includeMetadata); + $this->_includeMetadata = $includeMetadata; + } + + /** + * Indicates if snapshots is included or not. + * + * @return boolean. + */ + public function getIncludeSnapshots() + { + return $this->_includeSnapshots; + } + + /** + * Sets the include snapshots flag. + * + * @param bool $includeSnapshots value. + * + * @return none. + */ + public function setIncludeSnapshots($includeSnapshots) + { + Validate::isBoolean($includeSnapshots); + $this->_includeSnapshots = $includeSnapshots; + } + + /** + * Indicates if uncommittedBlobs is included or not. + * + * @return boolean. + */ + public function getIncludeUncommittedBlobs() + { + return $this->_includeUncommittedBlobs; + } + + /** + * Sets the include uncommittedBlobs flag. + * + * @param bool $includeUncommittedBlobs value. + * + * @return none. + */ + public function setIncludeUncommittedBlobs($includeUncommittedBlobs) + { + Validate::isBoolean($includeUncommittedBlobs); + $this->_includeUncommittedBlobs = $includeUncommittedBlobs; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/ListBlobsResult.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/ListBlobsResult.php new file mode 100644 index 0000000..d2c6897 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/ListBlobsResult.php @@ -0,0 +1,339 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Blob\Models\Blob; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\InvalidArgumentTypeException; + +/** + * Hold result of calliing listBlobs wrapper. + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class ListBlobsResult +{ + /** + * @var array + */ + private $_blobPrefixes; + + /** + * @var array + */ + private $_blobs; + + /** + * @var string + */ + private $_delimiter; + + /** + * @var string + */ + private $_prefix; + + /** + * @var string + */ + private $_marker; + + /** + * @var string + */ + private $_nextMarker; + + /** + * @var integer + */ + private $_maxResults; + + /** + * @var string + */ + private $_containerName; + + /** + * Creates ListBlobsResult object from parsed XML response. + * + * @param array $parsed XML response parsed into array. + * + * @return ListBlobsResult + */ + public static function create($parsed) + { + $result = new ListBlobsResult(); + $result->_containerName = Utilities::tryGetKeysChainValue( + $parsed, + Resources::XTAG_ATTRIBUTES, + Resources::XTAG_CONTAINER_NAME + ); + $result->_prefix = Utilities::tryGetValue( + $parsed, Resources::QP_PREFIX + ); + $result->_marker = Utilities::tryGetValue( + $parsed, Resources::QP_MARKER + ); + $result->_nextMarker = Utilities::tryGetValue( + $parsed, Resources::QP_NEXT_MARKER + ); + $result->_maxResults = intval( + Utilities::tryGetValue($parsed, Resources::QP_MAX_RESULTS, 0) + ); + $result->_delimiter = Utilities::tryGetValue( + $parsed, Resources::QP_DELIMITER + ); + $result->_blobs = array(); + $result->_blobPrefixes = array(); + $rawBlobs = array(); + $rawBlobPrefixes = array(); + + if ( is_array($parsed['Blobs']) + && array_key_exists('Blob', $parsed['Blobs']) + ) { + $rawBlobs = Utilities::getArray($parsed['Blobs']['Blob']); + } + + foreach ($rawBlobs as $value) { + $blob = new Blob(); + $blob->setName($value['Name']); + $blob->setUrl($value['Url']); + $blob->setSnapshot(Utilities::tryGetValue($value, 'Snapshot')); + $blob->setProperties( + BlobProperties::create( + Utilities::tryGetValue($value, 'Properties') + ) + ); + $blob->setMetadata( + Utilities::tryGetValue($value, Resources::QP_METADATA, array()) + ); + + $result->_blobs[] = $blob; + } + + if ( is_array($parsed['Blobs']) + && array_key_exists('BlobPrefix', $parsed['Blobs']) + ) { + $rawBlobPrefixes = Utilities::getArray($parsed['Blobs']['BlobPrefix']); + } + + foreach ($rawBlobPrefixes as $value) { + $blobPrefix = new BlobPrefix(); + $blobPrefix->setName($value['Name']); + + $result->_blobPrefixes[] = $blobPrefix; + } + + return $result; + } + + /** + * Gets blobs. + * + * @return array + */ + public function getBlobs() + { + return $this->_blobs; + } + + /** + * Sets blobs. + * + * @param array $blobs list of blobs + * + * @return none + */ + public function setBlobs($blobs) + { + $this->_blobs = array(); + foreach ($blobs as $blob) { + $this->_blobs[] = clone $blob; + } + } + + /** + * Gets blobPrefixes. + * + * @return array + */ + public function getBlobPrefixes() + { + return $this->_blobPrefixes; + } + + /** + * Sets blobPrefixes. + * + * @param array $blobPrefixes list of blobPrefixes + * + * @return none + */ + public function setBlobPrefixes($blobPrefixes) + { + $this->_blobPrefixes = array(); + foreach ($blobPrefixes as $blob) { + $this->_blobPrefixes[] = clone $blob; + } + } + + /** + * Gets prefix. + * + * @return string + */ + public function getPrefix() + { + return $this->_prefix; + } + + /** + * Sets prefix. + * + * @param string $prefix value. + * + * @return none + */ + public function setPrefix($prefix) + { + $this->_prefix = $prefix; + } + + /** + * Gets prefix. + * + * @return string + */ + public function getDelimiter() + { + return $this->_delimiter; + } + + /** + * Sets prefix. + * + * @param string $delimiter value. + * + * @return none + */ + public function setDelimiter($delimiter) + { + $this->_delimiter = $delimiter; + } + + /** + * Gets marker. + * + * @return string + */ + public function getMarker() + { + return $this->_marker; + } + + /** + * Sets marker. + * + * @param string $marker value. + * + * @return none + */ + public function setMarker($marker) + { + $this->_marker = $marker; + } + + /** + * Gets max results. + * + * @return integer + */ + public function getMaxResults() + { + return $this->_maxResults; + } + + /** + * Sets max results. + * + * @param integer $maxResults value. + * + * @return none + */ + public function setMaxResults($maxResults) + { + $this->_maxResults = $maxResults; + } + + /** + * Gets next marker. + * + * @return string + */ + public function getNextMarker() + { + return $this->_nextMarker; + } + + /** + * Sets next marker. + * + * @param string $nextMarker value. + * + * @return none + */ + public function setNextMarker($nextMarker) + { + $this->_nextMarker = $nextMarker; + } + + /** + * Gets container name. + * + * @return string + */ + public function getContainerName() + { + return $this->_containerName; + } + + /** + * Sets container name. + * + * @param string $containerName value. + * + * @return none + */ + public function setContainerName($containerName) + { + $this->_containerName = $containerName; + } +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/ListContainersOptions.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/ListContainersOptions.php new file mode 100644 index 0000000..7e27e77 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/ListContainersOptions.php @@ -0,0 +1,172 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; +use WindowsAzure\Blob\Models\BlobServiceOptions; +use \WindowsAzure\Common\Internal\Validate; + +/** + * Options for listBlobs API. + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class ListContainersOptions extends BlobServiceOptions +{ + /** + * Filters the results to return only containers whose name begins with the + * specified prefix. + * + * @var string + */ + private $_prefix; + + /** + * Identifies the portion of the list to be returned with the next list operation + * The operation returns a marker value within the + * response body if the list returned was not complete. The marker value may + * then be used in a subsequent call to request the next set of list items. + * The marker value is opaque to the client. + * + * @var string + */ + private $_marker; + + /** + * Specifies the maximum number of containers to return. If the request does not + * specify maxresults, or specifies a value greater than 5,000, the server will + * return up to 5,000 items. If the parameter is set to a value less than or + * equal to zero, the server will return status code 400 (Bad Request). + * + * @var string + */ + private $_maxResults; + + /** + * Include this parameter to specify that the container's metadata be returned + * as part of the response body. + * + * @var bool + */ + private $_includeMetadata; + + /** + * Gets prefix. + * + * @return string. + */ + public function getPrefix() + { + return $this->_prefix; + } + + /** + * Sets prefix. + * + * @param string $prefix value. + * + * @return none. + */ + public function setPrefix($prefix) + { + Validate::isString($prefix, 'prefix'); + $this->_prefix = $prefix; + } + + /** + * Gets marker. + * + * @return string. + */ + public function getMarker() + { + return $this->_marker; + } + + /** + * Sets marker. + * + * @param string $marker value. + * + * @return none. + */ + public function setMarker($marker) + { + Validate::isString($marker, 'marker'); + $this->_marker = $marker; + } + + /** + * Gets max results. + * + * @return string. + */ + public function getMaxResults() + { + return $this->_maxResults; + } + + /** + * Sets max results. + * + * @param string $maxResults value. + * + * @return none. + */ + public function setMaxResults($maxResults) + { + Validate::isString($maxResults, 'maxResults'); + $this->_maxResults = $maxResults; + } + + /** + * Indicates if metadata is included or not. + * + * @return string. + */ + public function getIncludeMetadata() + { + return $this->_includeMetadata; + } + + /** + * Sets the include metadata flag. + * + * @param bool $includeMetadata value. + * + * @return none. + */ + public function setIncludeMetadata($includeMetadata) + { + Validate::isBoolean($includeMetadata); + $this->_includeMetadata = $includeMetadata; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/ListContainersResult.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/ListContainersResult.php new file mode 100644 index 0000000..b4f04ff --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/ListContainersResult.php @@ -0,0 +1,261 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Blob\Models\Container; + +/** + * Container to hold list container response object. + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class ListContainersResult +{ + /** + * @var array + */ + private $_containers; + + /** + * @var string + */ + private $_prefix; + + /** + * @var string + */ + private $_marker; + + /** + * @var string + */ + private $_nextMarker; + + /** + * @var integer + */ + private $_maxResults; + + /** + * @var string + */ + private $_accountName; + + /** + * Creates ListBlobResult object from parsed XML response. + * + * @param array $parsedResponse XML response parsed into array. + * + * @return ListBlobResult + */ + public static function create($parsedResponse) + { + $result = new ListContainersResult(); + $result->_accountName = Utilities::tryGetKeysChainValue( + $parsedResponse, + Resources::XTAG_ATTRIBUTES, + Resources::XTAG_ACCOUNT_NAME + ); + $result->_prefix = Utilities::tryGetValue( + $parsedResponse, Resources::QP_PREFIX + ); + $result->_marker = Utilities::tryGetValue( + $parsedResponse, Resources::QP_MARKER + ); + $result->_nextMarker = Utilities::tryGetValue( + $parsedResponse, Resources::QP_NEXT_MARKER + ); + $result->_maxResults = Utilities::tryGetValue( + $parsedResponse, Resources::QP_MAX_RESULTS + ); + $result->_containers = array(); + $rawContainer = array(); + + if ( !empty($parsedResponse['Containers']) ) { + $containersArray = $parsedResponse['Containers']['Container']; + $rawContainer = Utilities::getArray($containersArray); + } + + foreach ($rawContainer as $value) { + $container = new Container(); + $container->setName($value['Name']); + $container->setUrl($value['Url']); + $container->setMetadata( + Utilities::tryGetValue($value, Resources::QP_METADATA, array()) + ); + $properties = new ContainerProperties(); + $date = $value['Properties']['Last-Modified']; + $date = Utilities::rfc1123ToDateTime($date); + $properties->setLastModified($date); + $properties->setETag($value['Properties']['Etag']); + $container->setProperties($properties); + $result->_containers[] = $container; + } + + return $result; + } + + /** + * Sets containers. + * + * @param array $containers list of containers. + * + * @return none + */ + public function setContainers($containers) + { + $this->_containers = array(); + foreach ($containers as $container) { + $this->_containers[] = clone $container; + } + } + + /** + * Gets containers. + * + * @return array + */ + public function getContainers() + { + return $this->_containers; + } + + /** + * Gets prefix. + * + * @return string + */ + public function getPrefix() + { + return $this->_prefix; + } + + /** + * Sets prefix. + * + * @param string $prefix value. + * + * @return none + */ + public function setPrefix($prefix) + { + $this->_prefix = $prefix; + } + + /** + * Gets marker. + * + * @return string + */ + public function getMarker() + { + return $this->_marker; + } + + /** + * Sets marker. + * + * @param string $marker value. + * + * @return none + */ + public function setMarker($marker) + { + $this->_marker = $marker; + } + + /** + * Gets max results. + * + * @return string + */ + public function getMaxResults() + { + return $this->_maxResults; + } + + /** + * Sets max results. + * + * @param string $maxResults value. + * + * @return none + */ + public function setMaxResults($maxResults) + { + $this->_maxResults = $maxResults; + } + + /** + * Gets next marker. + * + * @return string + */ + public function getNextMarker() + { + return $this->_nextMarker; + } + + /** + * Sets next marker. + * + * @param string $nextMarker value. + * + * @return none + */ + public function setNextMarker($nextMarker) + { + $this->_nextMarker = $nextMarker; + } + + /** + * Gets account name. + * + * @return string + */ + public function getAccountName() + { + return $this->_accountName; + } + + /** + * Sets account name. + * + * @param string $accountName value. + * + * @return none + */ + public function setAccountName($accountName) + { + $this->_accountName = $accountName; + } +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/ListPageBlobRangesOptions.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/ListPageBlobRangesOptions.php new file mode 100644 index 0000000..1da6d9d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/ListPageBlobRangesOptions.php @@ -0,0 +1,179 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; +use WindowsAzure\Common\Internal\Validate; + +/** + * Optional parameters for listPageBlobRanges wrapper + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class ListPageBlobRangesOptions extends BlobServiceOptions +{ + /** + * @var string + */ + private $_leaseId; + + /** + * @var string + */ + private $_snapshot; + + /** + * @var integer + */ + private $_rangeStart; + + /** + * @var integer + */ + private $_rangeEnd; + + /** + * @var AccessCondition + */ + private $_accessCondition; + + /** + * Gets lease Id for the blob + * + * @return string + */ + public function getLeaseId() + { + return $this->_leaseId; + } + + /** + * Sets lease Id for the blob + * + * @param string $leaseId the blob lease id. + * + * @return none + */ + public function setLeaseId($leaseId) + { + $this->_leaseId = $leaseId; + } + + /** + * Gets blob snapshot. + * + * @return string. + */ + public function getSnapshot() + { + return $this->_snapshot; + } + + /** + * Sets blob snapshot. + * + * @param string $snapshot value. + * + * @return none. + */ + public function setSnapshot($snapshot) + { + $this->_snapshot = $snapshot; + } + + /** + * Gets rangeStart + * + * @return integer + */ + public function getRangeStart() + { + return $this->_rangeStart; + } + + /** + * Sets rangeStart + * + * @param integer $rangeStart the blob lease id. + * + * @return none + */ + public function setRangeStart($rangeStart) + { + Validate::isInteger($rangeStart, 'rangeStart'); + $this->_rangeStart = $rangeStart; + } + + /** + * Gets rangeEnd + * + * @return integer + */ + public function getRangeEnd() + { + return $this->_rangeEnd; + } + + /** + * Sets rangeEnd + * + * @param integer $rangeEnd range end value in bytes + * + * @return none + */ + public function setRangeEnd($rangeEnd) + { + Validate::isInteger($rangeEnd, 'rangeEnd'); + $this->_rangeEnd = $rangeEnd; + } + + /** + * Gets access condition + * + * @return AccessCondition + */ + public function getAccessCondition() + { + return $this->_accessCondition; + } + + /** + * Sets access condition + * + * @param AccessCondition $accessCondition value to use. + * + * @return none. + */ + public function setAccessCondition($accessCondition) + { + $this->_accessCondition = $accessCondition; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/ListPageBlobRangesResult.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/ListPageBlobRangesResult.php new file mode 100644 index 0000000..e5e80b2 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/ListPageBlobRangesResult.php @@ -0,0 +1,196 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; +use WindowsAzure\Common\Internal\Validate; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Blob\Models\PageRange; + +/** + * Holds result of calling listPageBlobRanges wrapper + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class ListPageBlobRangesResult +{ + /** + * @var \DateTime + */ + private $_lastModified; + + /** + * @var string + */ + private $_etag; + + /** + * @var integer + */ + private $_contentLength; + + /** + * @var array + */ + private $_pageRanges; + + /** + * Creates BlobProperties object from $parsed response in array representation + * + * @param array $headers HTTP response headers + * @param array $parsed parsed response in array format. + * + * @return ListPageBlobRangesResult + */ + public static function create($headers, $parsed) + { + $result = new ListPageBlobRangesResult(); + $headers = array_change_key_case($headers); + + $date = $headers[Resources::LAST_MODIFIED]; + $date = Utilities::rfc1123ToDateTime($date); + $blobLength = intval($headers[Resources::X_MS_BLOB_CONTENT_LENGTH]); + $rawPageRanges = array(); + + if (!empty($parsed['PageRange'])) { + $parsed = array_change_key_case($parsed); + $rawPageRanges = Utilities::getArray($parsed['pagerange']); + } + + $result->_pageRanges = array(); + foreach ($rawPageRanges as $value) { + $result->_pageRanges[] = new PageRange( + intval($value['Start']), intval($value['End']) + ); + } + + $result->setContentLength($blobLength); + $result->setETag($headers[Resources::ETAG]); + $result->setLastModified($date); + + return $result; + } + + /** + * Gets blob lastModified. + * + * @return \DateTime. + */ + public function getLastModified() + { + return $this->_lastModified; + } + + /** + * Sets blob lastModified. + * + * @param \DateTime $lastModified value. + * + * @return none. + */ + public function setLastModified($lastModified) + { + Validate::isDate($lastModified); + $this->_lastModified = $lastModified; + } + + /** + * Gets blob etag. + * + * @return string. + */ + public function getETag() + { + return $this->_etag; + } + + /** + * Sets blob etag. + * + * @param string $etag value. + * + * @return none. + */ + public function setETag($etag) + { + Validate::isString($etag, 'etag'); + $this->_etag = $etag; + } + + /** + * Gets blob contentLength. + * + * @return integer. + */ + public function getContentLength() + { + return $this->_contentLength; + } + + /** + * Sets blob contentLength. + * + * @param integer $contentLength value. + * + * @return none. + */ + public function setContentLength($contentLength) + { + Validate::isInteger($contentLength, 'contentLength'); + $this->_contentLength = $contentLength; + } + + /** + * Gets page ranges + * + * @return array + */ + public function getPageRanges() + { + return $this->_pageRanges; + } + + /** + * Sets page ranges + * + * @param array $pageRanges page ranges to set + * + * @return none + */ + public function setPageRanges($pageRanges) + { + $this->_pageRanges = array(); + foreach ($pageRanges as $pageRange) { + $this->_pageRanges[] = clone $pageRange; + } + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/PageRange.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/PageRange.php new file mode 100644 index 0000000..444126b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/PageRange.php @@ -0,0 +1,131 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; + +/** + * Holds info about page range used in HTTP requests + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class PageRange +{ + /** + * @var integer + */ + private $_start; + + /** + * @var integer + */ + private $_end; + + /** + * Constructor + * + * @param integer $start the page start value + * @param integer $end the page end value + * + * @return PageRange + */ + public function __construct($start = null, $end = null) + { + $this->_start = $start; + $this->_end = $end; + } + + /** + * Sets page start range + * + * @param integer $start the page range start + * + * @return none. + */ + public function setStart($start) + { + $this->_start = $start; + } + + /** + * Gets page start range + * + * @return integer + */ + public function getStart() + { + return $this->_start; + } + + /** + * Sets page end range + * + * @param integer $end the page range end + * + * @return none. + */ + public function setEnd($end) + { + $this->_end = $end; + } + + /** + * Gets page end range + * + * @return integer + */ + public function getEnd() + { + return $this->_end; + } + + /** + * Gets page range length + * + * @return integer + */ + public function getLength() + { + return $this->_end - $this->_start + 1; + } + + /** + * Sets page range length + * + * @param integer $value new page range + * + * @return none + */ + public function setLength($value) + { + $this->_end = $this->_start + $value - 1; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/PageWriteOption.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/PageWriteOption.php new file mode 100644 index 0000000..3ebd5b8 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/PageWriteOption.php @@ -0,0 +1,44 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; + +/** + * Holds available blob page write options + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class PageWriteOption +{ + const CLEAR_OPTION = 'clear'; + const UPDATE_OPTION = 'update'; +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/PublicAccessType.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/PublicAccessType.php new file mode 100644 index 0000000..c3f79aa --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/PublicAccessType.php @@ -0,0 +1,66 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; +use WindowsAzure\Common\Internal\Resources; + +/** + * Holds public acces types for a container. + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class PublicAccessType +{ + const NONE = Resources::EMPTY_STRING; + const BLOBS_ONLY = 'blob'; + const CONTAINER_AND_BLOBS = 'container'; + + /** + * Validates the public access. + * + * @param string $type The public access type. + * + * @return boolean + */ + public static function isValid($type) + { + switch ($type) { + case self::NONE: + case self::BLOBS_ONLY: + case self::CONTAINER_AND_BLOBS: + return true; + + default: + return false; + } + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/SetBlobMetadataOptions.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/SetBlobMetadataOptions.php new file mode 100644 index 0000000..f46f9c3 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/SetBlobMetadataOptions.php @@ -0,0 +1,95 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; + +/** + * The optional parameters for setBlobMetadata API. + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class SetBlobMetadataOptions extends BlobServiceOptions +{ + /** + * @var string + */ + private $_leaseId; + + /** + * @var AccessCondition + */ + private $_accessCondition; + + /** + * Gets lease Id for the blob + * + * @return string + */ + public function getLeaseId() + { + return $this->_leaseId; + } + + /** + * Sets lease Id for the blob + * + * @param string $leaseId the blob lease id. + * + * @return none + */ + public function setLeaseId($leaseId) + { + $this->_leaseId = $leaseId; + } + + /** + * Gets access condition + * + * @return AccessCondition + */ + public function getAccessCondition() + { + return $this->_accessCondition; + } + + /** + * Sets access condition + * + * @param AccessCondition $accessCondition value to use. + * + * @return none. + */ + public function setAccessCondition($accessCondition) + { + $this->_accessCondition = $accessCondition; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/SetBlobMetadataResult.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/SetBlobMetadataResult.php new file mode 100644 index 0000000..1435a16 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/SetBlobMetadataResult.php @@ -0,0 +1,118 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Validate; +use WindowsAzure\Common\Internal\Utilities; + +/** + * Holds results of calling getBlobMetadata wrapper + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class SetBlobMetadataResult +{ + + /** + * @var \DateTime + */ + private $_lastModified; + + /** + * @var string + */ + private $_etag; + + /** + * Creates SetBlobMetadataResult from response headers. + * + * @param array $headers response headers + * + * @return SetBlobMetadataResult + */ + public static function create($headers) + { + $result = new SetBlobMetadataResult(); + $date = $headers[Resources::LAST_MODIFIED]; + $result->setLastModified(Utilities::rfc1123ToDateTime($date)); + $result->setETag($headers[Resources::ETAG]); + + return $result; + } + + /** + * Gets blob lastModified. + * + * @return \DateTime. + */ + public function getLastModified() + { + return $this->_lastModified; + } + + /** + * Sets blob lastModified. + * + * @param \DateTime $lastModified value. + * + * @return none. + */ + public function setLastModified($lastModified) + { + Validate::isDate($lastModified); + $this->_lastModified = $lastModified; + } + + /** + * Gets blob etag. + * + * @return string. + */ + public function getETag() + { + return $this->_etag; + } + + /** + * Sets blob etag. + * + * @param string $etag value. + * + * @return none. + */ + public function setETag($etag) + { + Validate::isString($etag, 'etag'); + $this->_etag = $etag; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/SetBlobPropertiesOptions.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/SetBlobPropertiesOptions.php new file mode 100644 index 0000000..f399faa --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/SetBlobPropertiesOptions.php @@ -0,0 +1,292 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; +use WindowsAzure\Common\Internal\Validate; + +/** + * Optional parameters for setBlobProperties wrapper + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class SetBlobPropertiesOptions extends BlobServiceOptions +{ + /** + * @var BlobProperties + */ + private $_blobProperties; + + /** + * @var string + */ + private $_leaseId; + + /** + * @var string + */ + private $_sequenceNumberAction; + + /** + * @var AccessCondition + */ + private $_accessCondition; + + /** + * Creates a new SetBlobPropertiesOptions with a specified BlobProperties + * instance. + * + * @param BlobProperties $blobProperties The blob properties instance. + */ + public function __construct($blobProperties = null) + { + $this->_blobProperties = is_null($blobProperties) + ? new BlobProperties() : clone $blobProperties; + } + + /** + * Gets access condition + * + * @return AccessCondition + */ + public function getAccessCondition() + { + return $this->_accessCondition; + } + + /** + * Sets access condition + * + * @param AccessCondition $accessCondition value to use. + * + * @return none. + */ + public function setAccessCondition($accessCondition) + { + $this->_accessCondition = $accessCondition; + } + + /** + * Gets blob sequenceNumber. + * + * @return integer. + */ + public function getSequenceNumber() + { + return $this->_blobProperties->getSequenceNumber(); + } + + /** + * Sets blob sequenceNumber. + * + * @param integer $sequenceNumber value. + * + * @return none. + */ + public function setSequenceNumber($sequenceNumber) + { + $this->_blobProperties->setSequenceNumber($sequenceNumber); + } + + /** + * Gets lease Id for the blob + * + * @return string + */ + public function getSequenceNumberAction() + { + return $this->_sequenceNumberAction; + } + + /** + * Sets lease Id for the blob + * + * @param string $sequenceNumberAction action. + * + * @return none + */ + public function setSequenceNumberAction($sequenceNumberAction) + { + $this->_sequenceNumberAction = $sequenceNumberAction; + } + + /** + * Gets lease Id for the blob + * + * @return string + */ + public function getLeaseId() + { + return $this->_leaseId; + } + + /** + * Sets lease Id for the blob + * + * @param string $leaseId the blob lease id. + * + * @return none + */ + public function setLeaseId($leaseId) + { + $this->_leaseId = $leaseId; + } + + /** + * Gets blob blobContentLength. + * + * @return integer. + */ + public function getBlobContentLength() + { + return $this->_blobProperties->getContentLength(); + } + + /** + * Sets blob blobContentLength. + * + * @param integer $blobContentLength value. + * + * @return none. + */ + public function setBlobContentLength($blobContentLength) + { + $this->_blobProperties->setContentLength($blobContentLength); + } + + /** + * Gets blob ContentType. + * + * @return string. + */ + public function getBlobContentType() + { + return $this->_blobProperties->getContentType(); + } + + /** + * Sets blob ContentType. + * + * @param string $blobContentType value. + * + * @return none. + */ + public function setBlobContentType($blobContentType) + { + $this->_blobProperties->setContentType($blobContentType); + } + + /** + * Gets blob ContentEncoding. + * + * @return string. + */ + public function getBlobContentEncoding() + { + return $this->_blobProperties->getContentEncoding(); + } + + /** + * Sets blob ContentEncoding. + * + * @param string $blobContentEncoding value. + * + * @return none. + */ + public function setBlobContentEncoding($blobContentEncoding) + { + $this->_blobProperties->setContentEncoding($blobContentEncoding); + } + + /** + * Gets blob ContentLanguage. + * + * @return string. + */ + public function getBlobContentLanguage() + { + return $this->_blobProperties->getContentLanguage(); + } + + /** + * Sets blob ContentLanguage. + * + * @param string $blobContentLanguage value. + * + * @return none. + */ + public function setBlobContentLanguage($blobContentLanguage) + { + $this->_blobProperties->setContentLanguage($blobContentLanguage); + } + + /** + * Gets blob ContentMD5. + * + * @return string. + */ + public function getBlobContentMD5() + { + return $this->_blobProperties->getContentMD5(); + } + + /** + * Sets blob ContentMD5. + * + * @param string $blobContentMD5 value. + * + * @return none. + */ + public function setBlobContentMD5($blobContentMD5) + { + $this->_blobProperties->setContentMD5($blobContentMD5); + } + + /** + * Gets blob cache control. + * + * @return string. + */ + public function getBlobCacheControl() + { + return $this->_blobProperties->getCacheControl(); + } + + /** + * Sets blob cacheControl. + * + * @param string $blobCacheControl value to use. + * + * @return none. + */ + public function setBlobCacheControl($blobCacheControl) + { + $this->_blobProperties->setCacheControl($blobCacheControl); + } +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/SetBlobPropertiesResult.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/SetBlobPropertiesResult.php new file mode 100644 index 0000000..96bb183 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/SetBlobPropertiesResult.php @@ -0,0 +1,149 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Validate; +use WindowsAzure\Common\Internal\Utilities; + +/** + * Holds result of calling setBlobProperties wrapper + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class SetBlobPropertiesResult +{ + /** + * @var \DateTime + */ + private $_lastModified; + + /** + * @var string + */ + private $_etag; + + /** + * @var integer + */ + private $_sequenceNumber; + + /** + * Creates SetBlobPropertiesResult from response headers. + * + * @param array $headers response headers + * + * @return SetBlobPropertiesResult + */ + public static function create($headers) + { + $result = new SetBlobPropertiesResult(); + $date = $headers[Resources::LAST_MODIFIED]; + $result->setLastModified(Utilities::rfc1123ToDateTime($date)); + $result->setETag($headers[Resources::ETAG]); + if (array_key_exists(Resources::X_MS_BLOB_SEQUENCE_NUMBER, $headers)) { + $sNumber = $headers[Resources::X_MS_BLOB_SEQUENCE_NUMBER]; + $result->setSequenceNumber(intval($sNumber)); + } + + return $result; + } + + /** + * Gets blob lastModified. + * + * @return \DateTime. + */ + public function getLastModified() + { + return $this->_lastModified; + } + + /** + * Sets blob lastModified. + * + * @param \DateTime $lastModified value. + * + * @return none. + */ + public function setLastModified($lastModified) + { + Validate::isDate($lastModified); + $this->_lastModified = $lastModified; + } + + /** + * Gets blob etag. + * + * @return string. + */ + public function getETag() + { + return $this->_etag; + } + + /** + * Sets blob etag. + * + * @param string $etag value. + * + * @return none. + */ + public function setETag($etag) + { + Validate::isString($etag, 'etag'); + $this->_etag = $etag; + } + + /** + * Gets blob sequenceNumber. + * + * @return int. + */ + public function getSequenceNumber() + { + return $this->_sequenceNumber; + } + + /** + * Sets blob sequenceNumber. + * + * @param int $sequenceNumber value. + * + * @return none. + */ + public function setSequenceNumber($sequenceNumber) + { + Validate::isInteger($sequenceNumber, 'sequenceNumber'); + $this->_sequenceNumber = $sequenceNumber; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/SetContainerMetadataOptions.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/SetContainerMetadataOptions.php new file mode 100644 index 0000000..5ce6dce --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/SetContainerMetadataOptions.php @@ -0,0 +1,78 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; +use WindowsAzure\Blob\Models\AccessCondition; +use WindowsAzure\Blob\Models\BlobServiceOptions; + +/** + * Optional parameters for setContainerMetadata wrapper + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class SetContainerMetadataOptions extends BlobServiceOptions +{ + /** + * @var AccessCondition + */ + private $_accessCondition; + + /** + * Constructs the access condition object with none option. + */ + public function __construct() + { + $this->_accessCondition = AccessCondition::none(); + } + + /** + * Gets access condition + * + * @return AccessCondition + */ + public function getAccessCondition() + { + return $this->_accessCondition; + } + + /** + * Sets access condition + * + * @param AccessCondition $accessCondition value to use. + * + * @return none. + */ + public function setAccessCondition($accessCondition) + { + $this->_accessCondition = $accessCondition; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/SignedIdentifier.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/SignedIdentifier.php new file mode 100644 index 0000000..7fb5fd1 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Blob/Models/SignedIdentifier.php @@ -0,0 +1,104 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Blob\Models; +use WindowsAzure\Blob\Models\AccessPolicy; + +/** + * Holds container signed identifiers. + * + * @category Microsoft + * @package WindowsAzure\Blob\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class SignedIdentifier +{ + private $_id; + private $_accessPolicy; + + /** + * Gets id. + * + * @return string. + */ + public function getId() + { + return $this->_id; + } + + /** + * Sets id. + * + * @param string $id value. + * + * @return none. + */ + public function setId($id) + { + $this->_id = $id; + } + + /** + * Gets accessPolicy. + * + * @return string. + */ + public function getAccessPolicy() + { + return $this->_accessPolicy; + } + + /** + * Sets accessPolicy. + * + * @param string $accessPolicy value. + * + * @return none. + */ + public function setAccessPolicy($accessPolicy) + { + $this->_accessPolicy = $accessPolicy; + } + + /** + * Converts this current object to XML representation. + * + * @return array. + */ + public function toArray() + { + $array = array(); + + $array['SignedIdentifier']['Id'] = $this->_id; + $array['SignedIdentifier']['AccessPolicy'] = $this->_accessPolicy->toArray(); + + return $array; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/CloudConfigurationManager.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/CloudConfigurationManager.php new file mode 100644 index 0000000..d4aff54 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/CloudConfigurationManager.php @@ -0,0 +1,167 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Validate; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\ConnectionStringSource; + +/** + * Configuration manager for accessing Windows Azure settings. + * + * @category Microsoft + * @package WindowsAzure\Common + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class CloudConfigurationManager +{ + /** + * @var boolean + */ + private static $_isInitialized = false; + + /** + * The list of connection string sources. + * + * @var array + */ + private static $_sources; + + /** + * Restrict users from creating instances from this class + */ + private function __construct() + { + + } + + /** + * Initializes the connection string source providers. + * + * @return none + */ + private static function _init() + { + if (!self::$_isInitialized) { + self::$_sources = array(); + + // Get list of default connection string sources. + $default = ConnectionStringSource::getDefaultSources(); + foreach ($default as $name => $provider) { + self::$_sources[$name] = $provider; + } + + self::$_isInitialized = true; + } + } + + /** + * Gets a connection string from all available sources. + * + * @param string $key The connection string key name. + * + * @return string If the key does not exist return null. + */ + public static function getConnectionString($key) + { + Validate::isString($key, 'key'); + + self::_init(); + $value = null; + + foreach (self::$_sources as $source) { + $value = call_user_func_array($source, array($key)); + + if (!empty($value)) { + break; + } + } + + return $value; + } + + /** + * Registers a new connection string source provider. If the source to get + * registered is a default source, only the name of the source is required. + * + * @param string $name The source name. + * @param callable $provider The source callback. + * @param boolean $prepend When true, the $provider is processed first when + * calling getConnectionString. When false (the default) the $provider is + * processed after the existing callbacks. + * + * @return none + */ + public static function registerSource($name, $provider = null, $prepend = false) + { + Validate::isString($name, 'name'); + Validate::notNullOrEmpty($name, 'name'); + + self::_init(); + $default = ConnectionStringSource::getDefaultSources(); + + // Try to get callback if the user is trying to register a default source. + $provider = Utilities::tryGetValue($default, $name, $provider); + + Validate::notNullOrEmpty($provider, 'callback'); + + if ($prepend) { + self::$_sources = array_merge( + array($name => $provider), + self::$_sources + ); + + } else { + self::$_sources[$name] = $provider; + } + } + + /** + * Unregisters a connection string source. + * + * @param string $name The source name. + * + * @return callable + */ + public static function unregisterSource($name) + { + Validate::isString($name, 'name'); + Validate::notNullOrEmpty($name, 'name'); + + self::_init(); + + $sourceCallback = Utilities::tryGetValue(self::$_sources, $name); + + if (!is_null($sourceCallback)) { + unset(self::$_sources[$name]); + } + + return $sourceCallback; + } +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Atom/AtomBase.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Atom/AtomBase.php new file mode 100644 index 0000000..fdb8cd6 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Atom/AtomBase.php @@ -0,0 +1,326 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Internal\Atom; +use WindowsAzure\Common\Internal\Validate; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Atom\AtomLink; + +/** + * The base class of ATOM library. + * + * @category Microsoft + * @package WindowsAzure\Common\Internal\Atom + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +class AtomBase +{ + /** + * The attributes of the feed. + * + * @var array + */ + protected $attributes; + + /** + * Creates an ATOM base object with default parameters. + */ + public function __construct() + { + $this->attributes = array(); + $atomlink = new AtomLink(); + } + + /** + * Gets the attributes of the ATOM class. + * + * @return array + */ + public function getAttributes() + { + return $this->attributes; + } + + /** + * Sets the attributes of the ATOM class. + * + * @param array $attributes The attributes of the array. + * + * @return array + */ + public function setAttributes($attributes) + { + Validate::isArray($attributes, 'attributes'); + $this->attributes = $attributes; + } + + /** + * Sets an attribute to the ATOM object instance. + * + * @param string $attributeKey The key of the attribute. + * @param mixed $attributeValue The value of the attribute. + * + * @return none + */ + public function setAttribute($attributeKey, $attributeValue) + { + $this->attributes[$attributeKey] = $attributeValue; + } + + /** + * Gets an attribute with a specified attribute key. + * + * @param string $attributeKey The key of the attribute. + * + * @return none + */ + public function getAttribute($attributeKey) + { + return $this->attributes[$attributeKey]; + } + + /** + * Processes author node. + * + * @param array $xmlWriter The XML writer. + * @param array $itemArray An array of item to write. + * @param array $elementName The name of the element. + * + * @return array + */ + protected function writeArrayItem($xmlWriter, $itemArray, $elementName) + { + Validate::notNull($xmlWriter, 'xmlWriter'); + Validate::isArray($itemArray, 'itemArray'); + Validate::isString($elementName, 'elementName'); + + foreach ($itemArray as $itemInstance) { + $xmlWriter->startElementNS( + 'atom', + $elementName, + Resources::ATOM_NAMESPACE + ); + $itemInstance->writeInnerXml($xmlWriter); + $xmlWriter->endElement(); + } + + } + + /** + * Processes author node. + * + * @param array $xmlArray An array of simple xml elements. + * + * @return array + */ + protected function processAuthorNode($xmlArray) + { + $author = array(); + $authorItem = $xmlArray[Resources::AUTHOR]; + + if (is_array($authorItem)) { + foreach ($xmlArray[Resources::AUTHOR] as $authorXmlInstance) { + $authorInstance = new Person(); + $authorInstance->parseXml($authorXmlInstance->asXML()); + $author[] = $authorInstance; + } + } else { + $authorInstance = new Person(); + $authorInstance->parseXml($authorItem->asXML()); + $author[] = $authorInstance; + } + return $author; + } + + /** + * Processes entry node. + * + * @param array $xmlArray An array of simple xml elements. + * + * @return array + */ + protected function processEntryNode($xmlArray) + { + $entry = array(); + $entryItem = $xmlArray[Resources::ENTRY]; + + if (is_array($entryItem)) { + foreach ($xmlArray[Resources::ENTRY] as $entryXmlInstance) { + $entryInstance = new Entry(); + $entryInstance->fromXml($entryXmlInstance); + $entry[] = $entryInstance; + } + } else { + $entryInstance = new Entry(); + $entryInstance->fromXml($entryItem); + $entry[] = $entryInstance; + } + return $entry; + } + + /** + * Processes category node. + * + * @param array $xmlArray An array of simple xml elements. + * + * @return array + */ + protected function processCategoryNode($xmlArray) + { + $category = array(); + $categoryItem = $xmlArray[Resources::CATEGORY]; + + if (is_array($categoryItem)) { + foreach ($xmlArray[Resources::CATEGORY] as $categoryXmlInstance) { + $categoryInstance = new Category(); + $categoryInstance->parseXml($categoryXmlInstance->asXML()); + $category[] = $categoryInstance; + } + } else { + $categoryInstance = new Category(); + $categoryInstance->parseXml($categoryItem->asXML()); + $category[] = $categoryInstance; + } + return $category; + } + + /** + * Processes contributor node. + * + * @param array $xmlArray An array of simple xml elements. + * + * @return array + */ + protected function processContributorNode($xmlArray) + { + $category = array(); + $contributorItem = $xmlArray[Resources::CONTRIBUTOR]; + + if (is_array($contributorItem)) { + foreach ($xmlArray[Resources::CONTRIBUTOR] as $contributorXmlInstance) { + $contributorInstance = new Person(); + $contributorInstance->parseXml($contributorXmlInstance->asXML()); + $contributor[] = $contributorInstance; + } + } elseif (is_string($contributorItem)) { + $contributorInstance = new Person(); + $contributorInstance->setName((string)$contributorItem); + $contributor[] = $contributorInstance; + } else { + $contributorInstance = new Person(); + $contributorInstance->parseXml($contributorItem->asXML()); + $contributor[] = $contributorInstance; + } + return $contributor; + } + + /** + * Processes link node. + * + * @param array $xmlArray An array of simple xml elements. + * + * @return array + */ + protected function processLinkNode($xmlArray) + { + $link = array(); + $linkValue = $xmlArray[Resources::LINK]; + + if (is_array($linkValue)) { + foreach ($xmlArray[Resources::LINK] as $linkValueInstance) { + $linkInstance = new AtomLink(); + $linkInstance->parseXml($linkValueInstance->asXML()); + $link[] = $linkInstance; + } + } else { + $linkInstance = new AtomLink(); + $linkInstance->parseXml($linkValue->asXML()); + $link[] = $linkInstance; + } + + return $link; + } + + /** + * Writes an optional attribute for ATOM. + * + * @param \XMLWriter $xmlWriter The XML writer. + * @param string $attributeName The name of the attribute. + * @param mixed $attributeValue The value of the attribute. + * + * @return none + */ + protected function writeOptionalAttribute( + $xmlWriter, + $attributeName, + $attributeValue + ) { + Validate::notNull($xmlWriter, 'xmlWriter'); + Validate::isString($attributeName, 'attributeName'); + + if (!empty($attributeValue)) { + $xmlWriter->writeAttribute( + $attributeName, + $attributeValue + ); + } + } + + /** + * Writes the optional elements namespaces. + * + * @param \XmlWriter $xmlWriter The XML writer. + * @param string $prefix The prefix. + * @param string $elementName The element name. + * @param string $namespace The namespace name. + * @param string $elementValue The element value. + * + * @return none + */ + protected function writeOptionalElementNS( + $xmlWriter, + $prefix, + $elementName, + $namespace, + $elementValue + ) { + Validate::notNull($xmlWriter, 'xmlWriter'); + Validate::isString($elementName, 'elementName'); + + if (!empty($elementValue)) { + $xmlWriter->writeElementNS( + $prefix, + $elementName, + $namespace, + $elementValue + ); + } + } +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Atom/AtomLink.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Atom/AtomLink.php new file mode 100644 index 0000000..2fcdd60 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Atom/AtomLink.php @@ -0,0 +1,343 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Internal\Atom; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Validate; + +/** + * This link defines a reference from an entry or feed to a Web resource. + * + * @category Microsoft + * @package WindowsAzure\Common\Internal\Atom + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +class AtomLink extends AtomBase +{ + /** + * The undefined content. + * + * @var string + */ + protected $undefinedContent; + + /** + * The HREF of the link. + * + * @var string + */ + protected $href; + + /** + * The rel attribute of the link. + * + * @var string + */ + protected $rel; + + /** + * The media type of the link. + * + * @var string + */ + protected $type; + + /** + * The language of HREF. + * + * @var string + */ + protected $hreflang; + + /** + * The titile of the link. + * + * @var string + */ + protected $title; + + /** + * The length of the link. + * + * @var integer + */ + protected $length; + + /** + * Creates a AtomLink instance with specified text. + */ + public function __construct() + { + } + + /** + * Parse an ATOM Link xml. + * + * @param string $xmlString an XML based string of ATOM Link. + * + * @return none + */ + public function parseXml($xmlString) + { + Validate::notNull($xmlString, 'xmlString'); + Validate::isString($xmlString, 'xmlString'); + $atomLinkXml = simplexml_load_string($xmlString); + $attributes = $atomLinkXml->attributes(); + + if (!empty($attributes['href'])) { + $this->href = (string)$attributes['href']; + } + + if (!empty($attributes['rel'])) { + $this->rel = (string)$attributes['rel']; + } + + if (!empty($attributes['type'])) { + $this->type = (string)$attributes['type']; + } + + if (!empty($attributes['hreflang'])) { + $this->hreflang = (string)$attributes['hreflang']; + } + + if (!empty($attributes['title'])) { + $this->title = (string)$attributes['title']; + } + + if (!empty($attributes['length'])) { + $this->length = (integer)$attributes['length']; + } + + $undefinedContent = (string)$atomLinkXml; + if (empty($undefinedContent)) { + $this->undefinedContent = null; + } else { + $this->undefinedContent = (string)$atomLinkXml; + } + } + + /** + * Gets the href of the link. + * + * @return string + */ + public function getHref() + { + return $this->href; + } + + /** + * Sets the href of the link. + * + * @param string $href The href of the link. + * + * @return none + */ + public function setHref($href) + { + $this->href = $href; + } + + /** + * Gets the rel of the atomLink. + * + * @return string + */ + public function getRel() + { + return $this->rel; + } + + /** + * Sets the rel of the link. + * + * @param string $rel The rel of the atomLink. + * + * @return none + */ + public function setRel($rel) + { + $this->rel = $rel; + } + + /** + * Gets the type of the link. + * + * @return string + */ + public function getType() + { + return $this->type; + } + + /** + * Sets the type of the link. + * + * @param string $type The type of the link. + * + * @return none + */ + public function setType($type) + { + $this->type = $type; + } + + /** + * Gets the language of the href. + * + * @return string + */ + public function getHrefLang() + { + return $this->hrefLang; + } + + /** + * Sets the language of the href. + * + * @param string $hrefLang The language of the href. + * + * @return none + */ + public function setHrefLang($hrefLang) + { + $this->hrefLang = $hrefLang; + } + + /** + * Gets the title of the link. + * + * @return string + */ + public function getTitle() + { + return $this->title; + } + + /** + * Sets the title of the link. + * + * @param string $title The title of the link. + * + * @return none + */ + public function setTitle($title) + { + $this->title = $title; + } + + /** + * Gets the length of the link. + * + * @return string + */ + public function getLength() + { + return $this->length; + } + + /** + * Sets the length of the link. + * + * @param string $length The length of the link. + * + * @return none + */ + public function setLength($length) + { + $this->length = $length; + } + + /** + * Gets the undefined content. + * + * @return string + */ + public function getUndefinedContent() + { + return $this->undefinedContent; + } + + /** + * Sets the undefined content. + * + * @param string $undefinedContent The undefined content. + * + * @return none + */ + public function setUndefinedContent($undefinedContent) + { + $this->undefinedContent = $undefinedContent; + } + + /** + * Writes an XML representing the ATOM link item. + * + * @param \XMLWriter $xmlWriter The xml writer. + * + * @return none + */ + public function writeXml($xmlWriter) + { + Validate::notNull($xmlWriter, 'xmlWriter'); + $xmlWriter->startElementNS( + 'atom', + Resources::LINK, + Resources::ATOM_NAMESPACE + ); + $this->writeInnerXml($xmlWriter); + $xmlWriter->endElement(); + } + + /** + * Writes the inner XML representing the ATOM link item. + * + * @param \XMLWriter $xmlWriter The xml writer. + * + * @return none + */ + public function writeInnerXml($xmlWriter) + { + Validate::notNull($xmlWriter, 'xmlWriter'); + + $this->writeOptionalAttribute($xmlWriter, 'href', $this->href); + $this->writeOptionalAttribute($xmlWriter, 'rel', $this->rel); + $this->writeOptionalAttribute($xmlWriter, 'type', $this->type); + $this->writeOptionalAttribute($xmlWriter, 'hreflang', $this->hreflang); + $this->writeOptionalAttribute($xmlWriter, 'title', $this->title); + $this->writeOptionalAttribute($xmlWriter, 'length', $this->length); + + if (!empty($this->undefinedContent)) { + $xmlWriter->writeRaw($this->undefinedContent); + } + + } +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Atom/Category.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Atom/Category.php new file mode 100644 index 0000000..a2b9a8e --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Atom/Category.php @@ -0,0 +1,253 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Internal\Atom; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Validate; + +/** + * The category class of the ATOM standard. + * + * @category Microsoft + * @package WindowsAzure\Common\Internal\Atom + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +class Category extends AtomBase +{ + /** + * The term of the category. + * + * @var string + */ + protected $term; + + /** + * The scheme of the category. + * + * @var string + */ + protected $scheme; + + /** + * The label of the category. + * + * @var string + */ + protected $label; + + /** + * The undefined content of the category. + * + * @var string + */ + protected $undefinedContent; + + /** + * Creates a Category instance with specified text. + * + * @param string $undefinedContent The undefined content of the category. + * + * @return none + */ + public function __construct($undefinedContent = Resources::EMPTY_STRING) + { + $this->undefinedContent = $undefinedContent; + } + + /** + * Creates an ATOM Category instance with specified xml string. + * + * @param string $xmlString an XML based string of ATOM CONTENT. + * + * @return none + */ + public function parseXml($xmlString) + { + Validate::notNull($xmlString, 'xmlString'); + Validate::isString($xmlString, 'xmlString'); + $categoryXml = simplexml_load_string($xmlString); + $attributes = $categoryXml->attributes(); + if (!empty($attributes['term'])) { + $this->term = (string)$attributes['term']; + } + + if (!empty($attributes['scheme'])) { + $this->scheme = (string)$attributes['scheme']; + } + + if (!empty($attributes['label'])) { + $this->label = (string)$attributes['label']; + } + + $this->undefinedContent =(string)$categoryXml; + } + + /** + * Gets the term of the category. + * + * @return string + */ + public function getTerm() + { + return $this->term; + } + + /** + * Sets the term of the category. + * + * @param string $term The term of the category. + * + * @return none + */ + public function setTerm($term) + { + $this->term = $term; + } + + /** + * Gets the scheme of the category. + * + * @return string + */ + public function getScheme() + { + return $this->scheme; + } + + /** + * Sets the scheme of the category. + * + * @param string $scheme The scheme of the category. + * + * @return none + */ + public function setScheme($scheme) + { + $this->scheme = $scheme; + } + + /** + * Gets the label of the category. + * + * @return string The label. + */ + public function getLabel() + { + return $this->label; + } + + /** + * Sets the label of the category. + * + * @param string $label The label of the category. + * + * @return none + */ + public function setLabel($label) + { + $this->label = $label; + } + + /** + * Gets the undefined content of the category. + * + * @return string + */ + public function getUndefinedContent() + { + return $this->undefinedContent; + } + + /** + * Sets the undefined content of the category. + * + * @param string $undefinedContent The undefined content of the category. + * + * @return none + */ + public function setUndefinedContent($undefinedContent) + { + $this->undefinedContent = $undefinedContent; + } + + /** + * Writes an XML representing the category. + * + * @param \XMLWriter $xmlWriter The XML writer. + * + * @return none + */ + public function writeXml($xmlWriter) + { + Validate::notNull($xmlWriter, 'xmlWriter'); + $xmlWriter->startElementNS( + 'atom', + 'category', + Resources::ATOM_NAMESPACE + ); + $this->writeInnerXml($xmlWriter); + $xmlWriter->endElement(); + } + + /** + * Writes an XML representing the category. + * + * @param \XMLWriter $xmlWriter The XML writer. + * + * @return none + */ + public function writeInnerXml($xmlWriter) + { + Validate::notNull($xmlWriter, 'xmlWriter'); + $this->writeOptionalAttribute( + $xmlWriter, + 'term', + $this->term + ); + + $this->writeOptionalAttribute( + $xmlWriter, + 'scheme', + $this->scheme + ); + + $this->writeOptionalAttribute( + $xmlWriter, + 'label', + $this->label + ); + + if (!empty($this->undefinedContent)) { + $xmlWriter->WriteRaw($this->undefinedContent); + } + + } +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Atom/Content.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Atom/Content.php new file mode 100644 index 0000000..35b4769 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Atom/Content.php @@ -0,0 +1,213 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Internal\Atom; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Validate; +use WindowsAzure\Common\Internal\Atom\AtomProperties; +/** + * The content class of ATOM standard. + * + * @category Microsoft + * @package WindowsAzure\Common\Internal\Atom + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +class Content extends AtomBase +{ + /** + * The text of the content. + * + * @var string + */ + protected $text; + + /** + * The type of the content. + * + * @var string + */ + protected $type; + + /** + * Source XML object + * + * @var \SimpleXMLElement + */ + protected $xml; + + /** + * Creates a Content instance with specified text. + * + * @param string $text The text of the content. + * + * @return none + */ + public function __construct($text = null) + { + $this->text = $text; + } + + /** + * Creates an ATOM CONTENT instance with specified xml string. + * + * @param string $xmlString an XML based string of ATOM CONTENT. + * + * @return none + */ + public function parseXml($xmlString) + { + Validate::notNull($xmlString, 'xmlString'); + Validate::isString($xmlString, 'xmlString'); + + $this->fromXml(simplexml_load_string($xmlString)); + } + + /** + * Creates an ATOM CONTENT instance with specified simpleXML object + * + * @param \SimpleXMLElement $contentXml xml element of ATOM CONTENT + * + * @return none + */ + public function fromXml($contentXml) + { + Validate::notNull($contentXml, 'contentXml'); + Validate::isA($contentXml, '\SimpleXMLElement', 'contentXml'); + + $attributes = $contentXml->attributes(); + + if (!empty($attributes['type'])) { + $this->content = (string)$attributes['type']; + } + + $text = ''; + foreach ($contentXml->children() as $child) { + $text .= $child->asXML(); + } + + $this->text = $text; + + $this->xml = $contentXml; + } + + /** + * Gets the text of the content. + * + * @return string + */ + public function getText() + { + return $this->text; + } + + /** + * Sets the text of the content. + * + * @param string $text The text of the content. + * + * @return none + */ + public function setText($text) + { + $this->text = $text; + } + + /** + * Gets the xml object of the content. + * + * @return \SimpleXMLElement + */ + public function getXml() + { + return $this->xml; + } + + /** + * Gets the type of the content. + * + * @return string + */ + public function getType() + { + return $this->type; + } + + /** + * Sets the type of the content. + * + * @param string $type The type of the content. + * + * @return none + */ + public function setType($type) + { + $this->type = $type; + } + + /** + * Writes an XML representing the content. + * + * @param \XMLWriter $xmlWriter The XML writer. + * + * @return none + */ + public function writeXml($xmlWriter) + { + Validate::notNull($xmlWriter, 'xmlWriter'); + $xmlWriter->startElementNS( + 'atom', + 'content', + Resources::ATOM_NAMESPACE + ); + + $this->writeOptionalAttribute( + $xmlWriter, + 'type', + $this->type + ); + + $this->writeInnerXml($xmlWriter); + $xmlWriter->endElement(); + } + + /** + * Writes an inner XML representing the content. + * + * @param \XMLWriter $xmlWriter The XML writer. + * + * @return none + */ + public function writeInnerXml($xmlWriter) + { + Validate::notNull($xmlWriter, 'xmlWriter'); + $xmlWriter->writeRaw($this->text); + } +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Atom/Entry.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Atom/Entry.php new file mode 100644 index 0000000..a9d00b7 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Atom/Entry.php @@ -0,0 +1,645 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Internal\Atom; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Validate; + +/** + * The Entry class of ATOM standard. + * + * @category Microsoft + * @package WindowsAzure\Common\Internal\Atom + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +class Entry extends AtomBase +{ + // @codingStandardsIgnoreStart + + /** + * The author of the entry. + * + * @var Person + */ + protected $author; + + /** + * The category of the entry. + * + * @var array + */ + protected $category; + + /** + * The content of the entry. + * + * @var string + */ + protected $content; + + /** + * The contributor of the entry. + * + * @var string + */ + protected $contributor; + + /** + * An unqiue ID representing the entry. + * + * @var string + */ + protected $id; + + /** + * The link of the entry. + * + * @var string + */ + protected $link; + + /** + * Is the entry published. + * + * @var boolean + */ + protected $published; + + /** + * The copy right of the entry. + * + * @var string + */ + protected $rights; + + /** + * The source of the entry. + * + * @var string + */ + protected $source; + + /** + * The summary of the entry. + * + * @var string + */ + protected $summary; + + /** + * The title of the entry. + * + * @var string + */ + protected $title; + + /** + * Is the entry updated. + * + * @var \DateTime + */ + protected $updated; + + /** + * The extension element of the entry. + * + * @var string + */ + protected $extensionElement; + + /** + * Creates an ATOM Entry instance with default parameters. + */ + public function __construct() + { + $this->attributes = array(); + } + + /** + * Populate the properties of an ATOM Entry instance with specified XML.. + * + * @param string $xmlString A string representing an ATOM entry instance. + * + * @return none + */ + public function parseXml($xmlString) + { + Validate::notNull($xmlString, 'xmlString'); + + $this->fromXml(simplexml_load_string($xmlString)); + } + + /** + * Creates an ATOM ENTRY instance with specified simpleXML object + * + * @param \SimpleXMLElement $entryXml xml element of ATOM ENTRY + * + * @return none + */ + public function fromXml($entryXml) { + Validate::notNull($entryXml, 'entryXml'); + Validate::isA($entryXml, '\SimpleXMLElement', 'entryXml'); + + $this->attributes = (array)$entryXml->attributes(); + $entryArray = (array)$entryXml; + + if (array_key_exists(Resources::AUTHOR, $entryArray)) { + $this->author = $this->processAuthorNode($entryArray); + } + + if (array_key_exists(Resources::CATEGORY, $entryArray)) { + $this->category = $this->processCategoryNode($entryArray); + } + + if (array_key_exists('content', $entryArray)) { + $content = new Content(); + $content->fromXml($entryArray['content']); + $this->content = $content; + } + + if (array_key_exists(Resources::CONTRIBUTOR, $entryArray)) { + $this->contributor = $this->processContributorNode($entryArray); + } + + if (array_key_exists('id', $entryArray)) { + $this->id = (string)$entryArray['id']; + } + + if (array_key_exists(Resources::LINK, $entryArray)) { + $this->link = $this->processLinkNode($entryArray); + } + + if (array_key_exists('published', $entryArray)) { + $this->published = $entryArray['published']; + } + + if (array_key_exists('rights', $entryArray)) { + $this->rights = $entryArray['rights']; + } + + if (array_key_exists('source', $entryArray)) { + $source = new Source(); + $source->parseXml($entryArray['source']->asXML()); + $this->source = $source; + } + + if (array_key_exists('title', $entryArray)) { + $this->title = $entryArray['title']; + } + + if (array_key_exists('updated', $entryArray)) { + $this->updated = \DateTime::createFromFormat( + \DateTime::ATOM, + (string)$entryArray['updated'] + ); + } + } + + /** + * Gets the author of the entry. + * + * @return Person + */ + public function getAuthor() + { + return $this->author; + } + + /** + * Sets the author of the entry. + * + * @param Person $author The author of the entry. + * + * @return none + */ + public function setAuthor($author) + { + $this->author = $author; + } + + /** + * Gets the category. + * + * @return array + */ + public function getCategory() + { + return $this->category; + } + + /** + * Sets the category. + * + * @param string $category The category of the entry. + * + * @return none + */ + public function setCategory($category) + { + $this->category = $category; + } + + /** + * Gets the content. + * + * @return Content. + */ + public function getContent() + { + return $this->content; + } + + /** + * Sets the content. + * + * @param Content $content Sets the content of the entry. + * + * @return none + */ + public function setContent($content) + { + $this->content = $content; + } + + /** + * Gets the contributor. + * + * @return string + */ + public function getContributor() + { + return $this->contributor; + } + + /** + * Sets the contributor. + * + * @param string $contributor The contributor of the entry. + * + * @return none + */ + public function setContributor($contributor) + { + $this->contributor = $contributor; + } + + /** + * Gets the ID of the entry. + * + * @return string + */ + public function getId() + { + return $this->id; + } + + /** + * Sets the ID of the entry. + * + * @param string $id The id of the entry. + * + * @return none + */ + public function setId($id) + { + $this->id = $id; + } + + /** + * Gets the link of the entry. + * + * @return string + */ + public function getLink() + { + return $this->link; + } + + /** + * Sets the link of the entry. + * + * @param string $link The link of the entry. + * + * @return none + */ + public function setLink($link) + { + $this->link = $link; + } + + /** + * Gets published of the entry. + * + * @return boolean + */ + public function getPublished() + { + return $this->published; + } + + /** + * Sets published of the entry. + * + * @param boolean $published Is the entry published. + * + * @return none + */ + public function setPublished($published) + { + $this->published = $published; + } + + /** + * Gets the rights of the entry. + * + * @return string + */ + public function getRights() + { + return $this->rights; + } + + /** + * Sets the rights of the entry. + * + * @param string $rights The rights of the entry. + * + * @return none + */ + public function setRights($rights) + { + $this->rights = $rights; + } + + /** + * Gets the source of the entry. + * + * @return string + */ + public function getSource() + { + return $this->source; + } + + /** + * Sets the source of the entry. + * + * @param string $source The source of the entry. + * + * @return none + */ + public function setSource($source) + { + $this->source = $source; + } + + /** + * Gets the summary of the entry. + * + * @return string + */ + public function getSummary() + { + return $this->summary; + } + + /** + * Sets the summary of the entry. + * + * @param string $summary The summary of the entry. + * + * @return none + */ + public function setSummary($summary) + { + $this->summary = $summary; + } + + /** + * Gets the title of the entry. + * + * @return string + */ + public function getTitle() + { + return $this->title; + } + + /** + * Sets the title of the entry. + * + * @param string $title The title of the entry. + * + * @return none + */ + public function setTitle($title) + { + $this->title = $title; + } + + /** + * Gets updated. + * + * @return \DateTime + */ + public function getUpdated() + { + return $this->updated; + } + + /** + * Sets updated + * + * @param \DateTime $updated updated. + * + * @return none + */ + public function setUpdated($updated) + { + $this->updated = $updated; + } + + /** + * Gets extension element. + * + * @return string + */ + public function getExtensionElement() + { + return $this->extensionElement; + } + + /** + * Sets extension element. + * + * @param string $extensionElement The extension element of the entry. + * + * @return none + */ + public function setExtensionElement($extensionElement) + { + $this->extensionElement = $extensionElement; + } + + /** + * Writes a inner XML string representing the entry. + * + * @param \XMLWriter $xmlWriter The XML writer. + * + * @return none + */ + public function writeXml($xmlWriter) + { + Validate::notNull($xmlWriter, 'xmlWriter'); + $xmlWriter->startElementNS( + 'atom', + Resources::ENTRY, + Resources::ATOM_NAMESPACE + ); + $this->writeInnerXml($xmlWriter); + $xmlWriter->endElement(); + } + + /** + * Writes a inner XML string representing the entry. + * + * @param \XMLWriter $xmlWriter The XML writer. + * + * @return none + */ + public function writeInnerXml($xmlWriter) + { + if (!is_null($this->attributes)) { + if (is_array($this->attributes)) { + foreach ( + $this->attributes + as $attributeName => $attributeValue + ) { + $xmlWriter->writeAttribute($attributeName, $attributeValue); + } + } + } + + if (!is_null($this->author)) { + $this->writeArrayItem( + $xmlWriter, + $this->author, + Resources::AUTHOR + ); + } + + if (!is_null($this->category)) { + $this->writeArrayItem( + $xmlWriter, + $this->category, + Resources::CATEGORY + ); + } + + if (!is_null($this->content)) { + $this->content->writeXml($xmlWriter); + } + + if (!is_null($this->contributor)) { + $this->writeArrayItem( + $xmlWriter, + $this->contributor, + Resources::CONTRIBUTOR + ); + } + + $this->writeOptionalElementNS( + $xmlWriter, + 'atom', + 'id', + Resources::ATOM_NAMESPACE, + $this->id + ); + + if (!is_null($this->link)) { + $this->writeArrayItem( + $xmlWriter, + $this->link, + Resources::LINK + ); + } + + $this->writeOptionalElementNS( + $xmlWriter, + 'atom', + 'published', + Resources::ATOM_NAMESPACE, + $this->published + ); + + $this->writeOptionalElementNS( + $xmlWriter, + 'atom', + 'rights', + Resources::ATOM_NAMESPACE, + $this->rights + ); + + $this->writeOptionalElementNS( + $xmlWriter, + 'atom', + 'source', + Resources::ATOM_NAMESPACE, + $this->source + ); + + $this->writeOptionalElementNS( + $xmlWriter, + 'atom', + 'summary', + Resources::ATOM_NAMESPACE, + $this->summary + ); + + $this->writeOptionalElementNS( + $xmlWriter, + 'atom', + 'title', + Resources::ATOM_NAMESPACE, + $this->title + ); + + if (!is_null($this->updated)) { + $xmlWriter->writeElementNS( + 'atom', + 'updated', + Resources::ATOM_NAMESPACE, + $this->updated->format(\DateTime::ATOM) + ); + } + } +} + +// @codingStandardsIgnoreEnd \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Atom/Feed.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Atom/Feed.php new file mode 100644 index 0000000..9f2fa8f --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Atom/Feed.php @@ -0,0 +1,730 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Internal\Atom; +use WindowsAzure\Common\Internal\Validate; +use WindowsAzure\Common\Internal\Resources; + +/** + * The feed class of ATOM library. + * + * @category Microsoft + * @package WindowsAzure\Common\Internal\Atom + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +class Feed extends AtomBase +{ + // @codingStandardsIgnoreStart + + /** + * The entry of the feed. + * + * @var array + */ + protected $entry; + + /** + * the author of the feed. + * + * @var array + */ + protected $author; + + /** + * The category of the feed. + * + * @var array + */ + protected $category; + + /** + * The contributor of the feed. + * + * @var array + */ + protected $contributor; + + /** + * The generator of the feed. + * + * @var Generator + */ + protected $generator; + + /** + * The icon of the feed. + * + * @var string + */ + protected $icon; + + /** + * The ID of the feed. + * + * @var string + */ + protected $id; + + /** + * The link of the feed. + * + * @var array + */ + protected $link; + + /** + * The logo of the feed. + * + * @var string + */ + protected $logo; + + /** + * The rights of the feed. + * + * @var string + */ + protected $rights; + + /** + * The subtitle of the feed. + * + * @var string + */ + protected $subtitle; + + /** + * The title of the feed. + * + * @var string + */ + protected $title; + + /** + * The update of the feed. + * + * @var \DateTime + */ + protected $updated; + + /** + * The extension element of the feed. + * + * @var string + */ + protected $extensionElement; + + /** + * Creates an ATOM FEED object with default parameters. + */ + public function __construct() + { + $this->attributes = array(); + } + + /** + * Creates a feed object with specified XML string. + * + * @param string $xmlString An XML string representing the feed object. + * + * @return none + */ + public function parseXml($xmlString) + { + $feedXml = simplexml_load_string($xmlString); + $attributes = $feedXml->attributes(); + $feedArray = (array)$feedXml; + if (!empty($attributes)) { + $this->attributes = (array)$attributes; + } + + if (array_key_exists('author', $feedArray)) { + $this->author = $this->processAuthorNode($feedArray); + } + + if (array_key_exists('entry', $feedArray)) { + $this->entry = $this->processEntryNode($feedArray); + } + + if (array_key_exists('category', $feedArray)) { + $this->category = $this->processCategoryNode($feedArray); + } + + if (array_key_exists('contributor', $feedArray)) { + $this->contributor = $this->processContributorNode($feedArray); + } + + if (array_key_exists('generator', $feedArray)) { + $generator = new Generator(); + $generatorValue = $feedArray['generator']; + if (is_string($generatorValue)) { + $generator->setText($generatorValue); + } else { + $generator->parseXml($generatorValue->asXML()); + } + + $this->generator = $generator; + } + + if (array_key_exists('icon', $feedArray)) { + $this->icon = (string)$feedArray['icon']; + } + + if (array_key_exists('id', $feedArray)) { + $this->id = (string)$feedArray['id']; + } + + if (array_key_exists('link', $feedArray)) { + $this->link = $this->processLinkNode($feedArray); + } + + if (array_key_exists('logo', $feedArray)) { + $this->logo = (string)$feedArray['logo']; + } + + if (array_key_exists('rights', $feedArray)) { + $this->rights = (string)$feedArray['rights']; + } + + if (array_key_exists('subtitle', $feedArray)) { + $this->subtitle = (string)$feedArray['subtitle']; + } + + if (array_key_exists('title', $feedArray)) { + $this->title = (string)$feedArray['title']; + } + + if (array_key_exists('updated', $feedArray)) { + $this->updated = \DateTime::createFromFormat( + \DateTime::ATOM, + (string)$feedArray['updated'] + ); + } + } + + /** + * Gets the attributes of the feed. + * + * @return array + */ + public function getAttributes() + { + return $this->attributes; + } + + /** + * Sets the attributes of the feed. + * + * @param array $attributes The attributes of the array. + * + * @return array + */ + public function setAttributes($attributes) + { + Validate::isArray($attributes, 'attributes'); + $this->attributes = $attributes; + } + + /** + * Adds an attribute to the feed object instance. + * + * @param string $attributeKey The key of the attribute. + * @param mixed $attributeValue The value of the attribute. + * + * @return none + */ + public function addAttribute($attributeKey, $attributeValue) + { + $this->attributes[$attributeKey] = $attributeValue; + } + + /** + * Gets the author of the feed. + * + * @return Person + */ + public function getAuthor() + { + return $this->author; + } + + /** + * Sets the author of the feed. + * + * @param Person $author The author of the feed. + * + * @return none + */ + public function setAuthor($author) + { + Validate::isArray($author, 'author'); + $person = new Person(); + foreach ($author as $authorInstance) { + Validate::isInstanceOf($authorInstance, $person, 'author'); + } + $this->author = $author; + } + + /** + * Gets the category of the feed. + * + * @return Category + */ + public function getCategory() + { + return $this->category; + } + + /** + * Sets the category of the feed. + * + * @param Category $category The category of the feed. + * + * @return none + */ + public function setCategory($category) + { + Validate::isArray($category, 'category'); + $categoryClassInstance = new Category(); + foreach ($category as $categoryInstance) { + Validate::isInstanceOf( + $categoryInstance, + $categoryClassInstance, + 'category' + ); + } + $this->category = $category; + } + + /** + * Gets contributor. + * + * @return array + */ + public function getContributor() + { + return $this->contributor; + } + + /** + * Sets contributor. + * + * @param string $contributor The contributor of the feed. + * + * @return none + */ + public function setContributor($contributor) + { + Validate::isArray($contributor, 'contributor'); + $person = new Person(); + foreach ($contributor as $contributorInstance) { + Validate::isInstanceOf($contributorInstance, $person, 'contributor'); + } + $this->contributor = $contributor; + } + + /** + * Gets generator. + * + * @return string + */ + public function getGenerator() + { + return $this->generator; + } + + /** + * Sets the generator. + * + * @param string $generator Sets the generator of the feed. + * + * @return none + */ + public function setGenerator($generator) + { + $this->generator = $generator; + } + + /** + * Gets the icon of the feed. + * + * @return string + */ + public function getIcon() + { + return $this->icon; + } + + /** + * Sets the icon of the feed. + * + * @param string $icon The icon of the feed. + * + * @return none + */ + public function setIcon($icon) + { + $this->icon = $icon; + } + + /** + * Gets the ID of the feed. + * + * @return string + */ + public function getId() + { + return $this->id; + } + + /** + * Sets the ID of the feed. + * + * @param string $id The ID of the feed. + * + * @return none + */ + public function setId($id) + { + $this->id = $id; + } + + /** + * Gets the link of the feed. + * + * @return array + */ + public function getLink() + { + return $this->link; + } + + /** + * Sets the link of the feed. + * + * @param array $link The link of the feed. + * + * @return none + */ + public function setLink($link) + { + Validate::isArray($link, 'link'); + $this->link = $link; + } + + /** + * Gets the logo of the feed. + * + * @return string + */ + public function getLogo() + { + return $this->logo; + } + + /** + * Sets the logo of the feed. + * + * @param string $logo The logo of the feed. + * + * @return none + */ + public function setLogo($logo) + { + $this->logo = $logo; + } + + /** + * Gets the rights of the feed. + * + * @return string + */ + public function getRights() + { + return $this->rights; + } + + /** + * Sets the rights of the feed. + * + * @param string $rights The rights of the feed. + * + * @return none + */ + public function setRights($rights) + { + $this->rights = $rights; + } + + /** + * Gets the sub title. + * + * @return string + */ + public function getSubtitle() + { + return $this->subtitle; + } + + /** + * Sets the sub title of the feed. + * + * @param string $subtitle Sets the sub title of the feed. + * + * @return none + */ + public function setSubtitle($subtitle) + { + $this->subtitle = $subtitle; + } + + /** + * Gets the title of the feed. + * + * @return string. + */ + public function getTitle() + { + return $this->title; + } + + /** + * Sets the title of the feed. + * + * @param string $title The title of the feed. + * + * @return none + */ + public function setTitle($title) + { + $this->title = $title; + } + + /** + * Gets the updated. + * + * @return \DateTime + */ + public function getUpdated() + { + return $this->updated; + } + + /** + * Sets the updated. + * + * @param \DateTime $updated updated + * + * @return none + */ + public function setUpdated($updated) + { + Validate::isInstanceOf($updated, new \DateTime(), 'updated'); + $this->updated = $updated; + } + + /** + * Gets the extension element. + * + * @return string + */ + public function getExtensionElement() + { + return $this->extensionElement; + } + + /** + * Sets the extension element. + * + * @param string $extensionElement The extension element. + * + * @return none + */ + public function setExtensionElement($extensionElement) + { + $this->extensionElement = $extensionElement; + } + + /** + * Gets the entry of the feed. + * + * @return Entry + */ + public function getEntry() + { + return $this->entry; + } + + /** + * Sets the entry of the feed. + * + * @param Entry $entry The entry of the feed. + * + * @return none + */ + public function setEntry($entry) + { + $this->entry = $entry; + } + + /** + * Writes an XML representing the feed object. + * + * @param \XMLWriter $xmlWriter The XML writer. + * + * @return none + */ + public function writeXml($xmlWriter) + { + Validate::notNull($xmlWriter, 'xmlWriter'); + + $xmlWriter->startElementNS('atom', 'feed', Resources::ATOM_NAMESPACE); + $this->writeInnerXml($xmlWriter); + $xmlWriter->endElement(); + } + + /** + * Writes an XML representing the feed object. + * + * @param \XMLWriter $xmlWriter The XML writer. + * + * @return none + */ + public function writeInnerXml($xmlWriter) + { + Validate::notNull($xmlWriter, 'xmlWriter'); + + if (!is_null($this->attributes)) { + if (is_array($this->attributes)) { + foreach ( + $this->attributes + as $attributeName => $attributeValue + ) { + $xmlWriter->writeAttribute($attributeName, $attributeValue); + } + } + } + + if (!is_null($this->author)) { + $this->writeArrayItem( + $xmlWriter, + $this->author, + Resources::AUTHOR + ); + } + + if (!is_null($this->category)) { + $this->writeArrayItem( + $xmlWriter, + $this->category, + Resources::CATEGORY + ); + } + + if (!is_null($this->contributor)) { + $this->writeArrayItem( + $xmlWriter, + $this->contributor, + Resources::CONTRIBUTOR + ); + } + + if (!is_null($this->generator)) { + $this->generator->writeXml($xmlWriter); + } + + $this->writeOptionalElementNS( + $xmlWriter, + 'atom', + 'icon', + Resources::ATOM_NAMESPACE, + $this->icon + ); + + $this->writeOptionalElementNS( + $xmlWriter, + 'atom', + 'logo', + Resources::ATOM_NAMESPACE, + $this->logo + ); + + $this->writeOptionalElementNS( + $xmlWriter, + 'atom', + 'id', + Resources::ATOM_NAMESPACE, + $this->id + ); + + if (!is_null($this->link)) { + $this->writeArrayItem( + $xmlWriter, + $this->link, + Resources::LINK + ); + } + + $this->writeOptionalElementNS( + $xmlWriter, + 'atom', + 'rights', + Resources::ATOM_NAMESPACE, + $this->rights + ); + + $this->writeOptionalElementNS( + $xmlWriter, + 'atom', + 'subtitle', + Resources::ATOM_NAMESPACE, + $this->subtitle + ); + + $this->writeOptionalElementNS( + $xmlWriter, + 'atom', + 'title', + Resources::ATOM_NAMESPACE, + $this->title + ); + + if (!is_null($this->updated)) { + $xmlWriter->writeElementNS( + 'atom', + 'updated', + Resources::ATOM_NAMESPACE, + $this->updated->format(\DateTime::ATOM) + ); + } + + } +} + +// @codingStandardsIgnoreEnd \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Atom/Generator.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Atom/Generator.php new file mode 100644 index 0000000..251cb1e --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Atom/Generator.php @@ -0,0 +1,200 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Internal\Atom; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Resources; + +/** + * The generator class of ATOM library. + * + * @category Microsoft + * @package WindowsAzure\Common\Internal\Atom + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +class Generator extends AtomBase +{ + /** + * The of the generator. + * + * @var string + */ + protected $text; + + /** + * The Uri of the generator. + * + * @var string + */ + protected $uri; + + /** + * The version of the generator. + * + * @var string + */ + protected $version; + + /** + * Creates a generator instance with specified XML string. + * + * @param string $xmlString A string representing a generator + * instance. + * + * @return none + */ + public static function parseXml($xmlString) + { + $generatorXml = new \SimpleXMLElement($xmlString); + $generatorArray = (array)$generatorXml; + $attributes = $generatorXml->attributes(); + if (!empty($attributes['uri'])) { + $this->uri = (string)$attributes['uri']; + } + + if (!empty($attributes['version'])) { + $this->version = (string)$attributes['version']; + } + + $this->text = (string)$generatorXml; + } + + /** + * Creates an ATOM generator instance with specified name. + * + * @param string $text The text content of the generator. + * + * @return none + */ + public function __construct($text = null) + { + if (!empty($text)) { + $this->text = $text; + } + } + + /** + * Gets the text of the generator. + * + * @return string + */ + public function getText() + { + return $this->text; + } + + /** + * Sets the text of the generator. + * + * @param string $text The text of the generator. + * + * @return none + */ + public function setText($text) + { + $this->text = $text; + } + + /** + * Gets the URI of the generator. + * + * @return string + */ + public function getUri() + { + return $this->uri; + } + + /** + * Sets the URI of the generator. + * + * @param string $uri The URI of the generator. + * + * @return none + */ + public function setUri($uri) + { + $this->uri = $uri; + } + + + /** + * Gets the version of the generator. + * + * @return string + */ + public function getVersion() + { + return $this->version; + } + + /** + * Sets the version of the generator. + * + * @param string $version The version of the generator. + * + * @return none + */ + public function setVersion($version) + { + $this->version = $version; + } + + /** + * Writes an XML representing the generator. + * + * @param \XMLWriter $xmlWriter The XML writer. + * + * @return none + */ + public function writeXml($xmlWriter) + { + $xmlWriter->startElementNS( + 'atom', + Resources::CATEGORY, + Resources::ATOM_NAMESPACE + ); + + $this->writeOptionalAttribute( + $xmlWriter, + 'uri', + $this->uri + ); + + $this->writeOptionalAttribute( + $xmlWriter, + 'version', + $this->version + ); + + $xmlWriter->writeRaw($this->text); + $xmlWriter->endElement(); + } +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Atom/Person.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Atom/Person.php new file mode 100644 index 0000000..513d496 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Atom/Person.php @@ -0,0 +1,222 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Internal\Atom; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Validate; + +/** + * The person class of ATOM library. + * + * @category Microsoft + * @package WindowsAzure\Common\Internal\Atom + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +class Person extends AtomBase +{ + /** + * The name of the person. + * + * @var string + */ + protected $name; + + /** + * The Uri of the person. + * + * @var string + */ + protected $uri; + + /** + * The email of the person. + * + * @var string + */ + protected $email; + + /** + * Creates an ATOM person instance with specified name. + * + * @param string $name The name of the person. + */ + public function __construct($name = Resources::EMPTY_STRING) + { + $this->name = $name; + } + + /** + * Populates the properties with a specified XML string. + * + * @param string $xmlString An XML based string representing + * the Person instance. + * + * @return none + */ + public function parseXml($xmlString) + { + $personXml = simplexml_load_string($xmlString); + $attributes = $personXml->attributes(); + $personArray = (array)$personXml; + + if (array_key_exists('name', $personArray)) { + $this->name = (string)$personArray['name']; + } + + if (array_key_exists('uri', $personArray)) { + $this->uri = (string)$personArray['uri']; + } + + if (array_key_exists('email', $personArray)) { + $this->email = (string)$personArray['email']; + } + } + + /** + * Gets the name of the person. + * + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * Sets the name of the person. + * + * @param string $name The name of the person. + * + * @return none + */ + public function setName($name) + { + $this->name = $name; + } + + /** + * Gets the URI of the person. + * + * @return string + */ + public function getUri() + { + return $this->uri; + } + + /** + * Sets the URI of the person. + * + * @param string $uri The URI of the person. + * + * @return none + */ + public function setUri($uri) + { + $this->uri = $uri; + } + + + /** + * Gets the email of the person. + * + * @return string + */ + public function getEmail() + { + return $this->email; + } + + /** + * Sets the email of the person. + * + * @param string $email The email of the person. + * + * @return none + */ + public function setEmail($email) + { + $this->email = $email; + } + + /** + * Writes an XML representing the person. + * + * @param \XMLWriter $xmlWriter The XML writer. + * + * @return none + */ + public function writeXml($xmlWriter) + { + Validate::notNull($xmlWriter, 'xmlWriter'); + $xmlWriter->startElementNS( + 'atom', + 'person', + Resources::ATOM_NAMESPACE + ); + $this->writeInnerXml($xmlWriter); + $xmlWriter->endElement(); + } + + /** + * Writes a inner XML representing the person. + * + * @param \XMLWriter $xmlWriter The XML writer. + * + * @return none + */ + public function writeInnerXml($xmlWriter) + { + Validate::notNull($xmlWriter, 'xmlWriter'); + $xmlWriter->writeElementNS( + 'atom', + 'name', + Resources::ATOM_NAMESPACE, + $this->name + ); + + $this->writeOptionalElementNS( + $xmlWriter, + 'atom', + 'uri', + Resources::ATOM_NAMESPACE, + $this->uri + ); + + $this->writeOptionalElementNS( + $xmlWriter, + 'atom', + 'email', + Resources::ATOM_NAMESPACE, + $this->email + ); + } +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Atom/Source.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Atom/Source.php new file mode 100644 index 0000000..161ccfe --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Atom/Source.php @@ -0,0 +1,632 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Internal\Atom; +use WindowsAzure\Common\Internal\Validate; +use WindowsAzure\Common\Internal\Resources; + +/** + * The source class of ATOM library. + * + * @category Microsoft + * @package WindowsAzure\Common\Internal\Atom + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +class Source extends AtomBase +{ + // @codingStandardsIgnoreStart + + /** + * The author the source. + * + * @var array + */ + protected $author; + + /** + * The category of the source. + * + * @var array + */ + protected $category; + + /** + * The contributor of the source. + * + * @var array + */ + protected $contributor; + + /** + * The generator of the source. + * + * @var Generator + */ + protected $generator; + + /** + * The icon of the source. + * + * @var string + */ + protected $icon; + + /** + * The ID of the source. + * + * @var string + */ + protected $id; + + /** + * The link of the source. + * + * @var AtomLink + */ + protected $link; + + /** + * The logo of the source. + * + * @var string + */ + protected $logo; + + /** + * The rights of the source. + * + * @var string + */ + protected $rights; + + /** + * The subtitle of the source. + * + * @var string + */ + protected $subtitle; + + /** + * The title of the source. + * + * @var string + */ + protected $title; + + /** + * The update of the source. + * + * @var \DateTime + */ + protected $updated; + + /** + * The extension element of the source. + * + * @var string + */ + protected $extensionElement; + + /** + * Creates an ATOM FEED object with default parameters. + */ + public function __construct() + { + $this->attributes = array(); + $this->category = array(); + $this->contributor = array(); + $this->author = array(); + } + + /** + * Creates a source object with specified XML string. + * + * @param string $xmlString The XML string representing a source. + * + * @return none + */ + public function parseXml($xmlString) + { + $sourceXml = new \SimpleXMLElement($xmlString); + $attributes = $sourceXml->attributes(); + $sourceArray = (array)$sourceXml; + + if (array_key_exists(Resources::AUTHOR, $sourceArray)) { + $this->content = $this->processAuthorNode($sourceArray); + } + + if (array_key_exists(Resources::CATEGORY, $sourceArray)) { + $this->category = $this->processCategoryNode($sourceArray); + } + + if (array_key_exists(Resources::CONTRIBUTOR, $sourceArray)) { + $this->contributor = $this->processContributorNode($sourceArray); + } + + if (array_key_exists('generator', $sourceArray)) { + $generator = new Generator(); + $generator->setText((string)$sourceArray['generator']->asXML()); + $this->generator = $generator; + } + + if (array_key_exists('icon', $sourceArray)) { + $this->icon = (string)$sourceArray['icon']; + } + + if (array_key_exists('id', $sourceArray)) { + $this->id = (string)$sourceArray['id']; + } + + if (array_key_exists(Resources::LINK, $sourceArray)) { + $this->link = $this->processLinkNode($sourceArray); + } + + if (array_key_exists('logo', $sourceArray)) { + $this->logo = (string)$sourceArray['logo']; + } + + if (array_key_exists('rights', $sourceArray)) { + $this->rights = (string)$sourceArray['rights']; + } + + if (array_key_exists('subtitle', $sourceArray)) { + $this->subtitle = (string)$sourceArray['subtitle']; + } + + if (array_key_exists('title', $sourceArray)) { + $this->title = (string)$sourceArray['title']; + } + + if (array_key_exists('updated', $sourceArray)) { + $this->updated = \DateTime::createFromFormat( + \DateTime::ATOM, + (string)$sourceArray['updated'] + ); + } + } + + /** + * Gets the author of the source. + * + * @return array + */ + public function getAuthor() + { + return $this->author; + } + + /** + * Sets the author of the source. + * + * @param array $author An array of authors of the sources. + * + * @return none + */ + public function setAuthor($author) + { + $this->author = $author; + } + + /** + * Gets the category of the source. + * + * @return array + */ + public function getCategory() + { + return $this->category; + } + + /** + * Sets the category of the source. + * + * @param array $category The category of the source. + * + * @return none + */ + public function setCategory($category) + { + $this->category = $category; + } + + /** + * Gets contributor. + * + * @return array + */ + public function getContributor() + { + return $this->contributor; + } + + /** + * Sets contributor. + * + * @param array $contributor The contributors of the source. + * + * @return none + */ + public function setContributor($contributor) + { + $this->contributor = $contributor; + } + + /** + * Gets generator. + * + * @return Generator + */ + public function getGenerator() + { + return $this->generator; + } + + /** + * Sets the generator. + * + * @param Generator $generator Sets the generator of the source. + * + * @return none + */ + public function setGenerator($generator) + { + $this->generator = $generator; + } + + /** + * Gets the icon of the source. + * + * @return string + */ + public function getIcon() + { + return $this->icon; + } + + /** + * Sets the icon of the source. + * + * @param string $icon The icon of the source. + * + * @return string + */ + public function setIcon($icon) + { + $this->icon = $icon; + } + + /** + * Gets the ID of the source. + * + * @return string + */ + public function getId() + { + return $this->id; + } + + /** + * Sets the ID of the source. + * + * @param string $id The ID of the source. + * + * @return string + */ + public function setId($id) + { + $this->id = $id; + } + + /** + * Gets the link of the source. + * + * @return array + */ + public function getLink() + { + return $this->link; + } + + /** + * Sets the link of the source. + * + * @param array $link The link of the source. + * + * @return none + */ + public function setLink($link) + { + $this->link = $link; + } + + /** + * Gets the logo of the source. + * + * @return string + */ + public function getLogo() + { + return $this->logo; + } + + /** + * Sets the logo of the source. + * + * @param string $logo The logo of the source. + * + * @return none + */ + public function setLogo($logo) + { + $this->logo = $logo; + } + + /** + * Gets the rights of the source. + * + * @return string + */ + public function getRights() + { + return $this->rights; + } + + /** + * Sets the rights of the source. + * + * @param string $rights The rights of the source. + * + * @return none + */ + public function setRights($rights) + { + $this->rights = $rights; + } + + /** + * Gets the sub title. + * + * @return string + */ + public function getSubtitle() + { + return $this->subtitle; + } + + /** + * Sets the sub title of the source. + * + * @param string $subtitle Sets the sub title of the source. + * + * @return none + */ + public function setSubtitle($subtitle) + { + $this->subtitle = $subtitle; + } + + /** + * Gets the title of the source. + * + * @return string. + */ + public function getTitle() + { + return $this->title; + } + + /** + * Sets the title of the source. + * + * @param string $title The title of the source. + * + * @return none + */ + public function setTitle($title) + { + $this->title = $title; + } + + /** + * Gets the updated. + * + * @return \DateTime + */ + public function getUpdated() + { + return $this->updated; + } + + /** + * Sets the updated. + * + * @param \DateTime $updated updated + * + * @return none + */ + public function setUpdated($updated) + { + $this->updated = $updated; + } + + /** + * Gets the extension element. + * + * @return string + */ + public function getExtensionElement() + { + return $this->extensionElement; + } + + /** + * Sets the extension element. + * + * @param string $extensionElement The extension element. + * + * @return none + */ + public function setExtensionElement($extensionElement) + { + $this->extensionElement = $extensionElement; + } + + /** + * Writes an XML representing the source object. + * + * @param \XMLWriter $xmlWriter The XML writer. + * + * @return none + */ + public function writeXml($xmlWriter) + { + Validate::notNull($xmlWriter, 'xmlWriter'); + $xmlWriter->startElementNS( + 'atom', + 'source', + Resources::ATOM_NAMESPACE + ); + $this->writeInnerXml($xmlWriter); + $xmlWriter->endElement(); + } + /** + * Writes a inner XML representing the source object. + * + * @param \XMLWriter $xmlWriter The XML writer. + * + * @return none + */ + public function writeInnerXml($xmlWriter) + { + Validate::notNull($xmlWriter, 'xmlWriter'); + if (!is_null($this->attributes)) { + if (is_array($this->attributes)) { + foreach ($this->attributes as $attributeName => $attributeValue) { + $xmlWriter->writeAttribute($attributeName, $attributeValue); + } + } + } + + if (!is_null($this->author)) { + Validate::isArray($this->author, Resources::AUTHOR); + $this->writeArrayItem($xmlWriter, $this->author, Resources::AUTHOR); + } + + if (!is_null($this->category)) { + Validate::isArray($this->category, Resources::CATEGORY); + $this->writeArrayItem( + $xmlWriter, + $this->category, + Resources::CATEGORY + ); + } + + if (!is_null($this->contributor)) { + Validate::isArray($this->contributor, Resources::CONTRIBUTOR); + $this->writeArrayItem( + $xmlWriter, + $this->contributor, + Resources::CONTRIBUTOR + ); + } + + if (!is_null($this->generator)) { + $this->generator->writeXml($xmlWriter); + } + + if (!is_null($this->icon)) { + $xmlWriter->writeElementNS( + 'atom', + 'icon', + Resources::ATOM_NAMESPACE, + $this->icon + ); + } + + $this->writeOptionalElementNS( + $xmlWriter, + 'atom', + 'logo', + Resources::ATOM_NAMESPACE, + $this->logo + ); + + $this->writeOptionalElementNS( + $xmlWriter, + 'atom', + 'id', + Resources::ATOM_NAMESPACE, + $this->id + ); + + if (!is_null($this->link)) { + Validate::isArray($this->link, Resources::LINK); + $this->writeArrayItem( + $xmlWriter, + $this->link, + Resources::LINK + ); + } + + $this->writeOptionalElementNS( + $xmlWriter, + 'atom', + 'rights', + Resources::ATOM_NAMESPACE, + $this->rights + ); + + $this->writeOptionalElementNS( + $xmlWriter, + 'atom', + 'subtitle', + Resources::ATOM_NAMESPACE, + $this->subtitle + ); + + $this->writeOptionalElementNS( + $xmlWriter, + 'atom', + 'title', + Resources::ATOM_NAMESPACE, + $this->title + ); + + if (!is_null($this->updated)) { + $xmlWriter->writeElementNS( + 'atom', + 'updated', + Resources::ATOM_NAMESPACE, + $this->updated->format(\DateTime::ATOM) + ); + } + } +} + +// @codingStandardsIgnoreEnd \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Authentication/IAuthScheme.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Authentication/IAuthScheme.php new file mode 100644 index 0000000..413f8f1 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Authentication/IAuthScheme.php @@ -0,0 +1,60 @@ + + * @copyright Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Internal\Authentication; + +/** + * Interface for azure authentication schemes. + * + * @category Microsoft + * @package WindowsAzure\Common\Internal\Authentication + * @author Azure PHP SDK + * @copyright Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +interface IAuthScheme +{ + /** + * Returns authorization header to be included in the request. + * + * @param array $headers request headers. + * @param string $url reuqest url. + * @param array $queryParams query variables. + * @param string $httpMethod request http method. + * + * @see Specifying the Authorization Header section at + * http://msdn.microsoft.com/en-us/library/windowsazure/dd179428.aspx + * + * @abstract + * + * @return string + */ + public function getAuthorizationHeader($headers, $url, $queryParams, + $httpMethod + ); +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Authentication/OAuthScheme.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Authentication/OAuthScheme.php new file mode 100644 index 0000000..083205c --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Authentication/OAuthScheme.php @@ -0,0 +1,141 @@ + + * @copyright Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link http://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Internal\Authentication; +use WindowsAzure\Common\Internal\Authentication\IAuthScheme; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Validate; +use WindowsAzure\Common\Internal\OAuthRestProxy; +use WindowsAzure\Common\Models\OAuthAccessToken; + +/** + * Provides shared key authentication scheme for OAuth. + * + * @category Microsoft + * @package WindowsAzure\Common\Internal\Authentication + * @author Azure PHP SDK + * @copyright Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link http://github.com/windowsazure/azure-sdk-for-php + */ +class OAuthScheme implements IAuthScheme +{ + /** + * @var string + */ + protected $accountName; + + /** + * @var string + */ + protected $accountKey; + + /** + * @var WindowsAzure\Common\Models\OAuthAccessToken + */ + protected $accessToken; + + /** + * @var WindowsAzure\Common\Internal\OAuthRestProxy + */ + protected $oauthService; + + /** + * @var string + */ + protected $grantType; + + /** + * @var string + */ + protected $scope; + + /** + * Constructor. + * + * @param string $accountName account name. + * @param string $accountKey account + * secondary key. + * + * @param string $grantType grant type + * for OAuth request. + * + * @param string $scope scope for + * OAurh request. + * + * @param WindowsAzure\Common\Internal\OAuthRestProxy $oauthService account + * primary or secondary key. + */ + public function __construct( + $accountName, + $accountKey, + $grantType, + $scope, + $oauthService) + { + Validate::isString($accountName, 'accountName'); + Validate::isString($accountKey, 'accountKey'); + Validate::isString($grantType, 'grantType'); + Validate::isString($scope, 'scope'); + Validate::notNull($oauthService, 'oauthService'); + + $this->accountName = $accountName; + $this->accountKey = $accountKey; + $this->grantType = $grantType; + $this->scope = $scope; + $this->oauthService = $oauthService; + } + + /** + * Returns authorization header to be included in the request. + * + * @param array $headers request headers. + * @param string $url reuqest url. + * @param array $queryParams query variables. + * @param string $httpMethod request http method. + * + * @see Specifying the Authorization Header section at + * http://msdn.microsoft.com/en-us/library/windowsazure/dd179428.aspx + * + * @return string + */ + public function getAuthorizationHeader($headers, $url, $queryParams, $httpMethod) + { + if (($this->accessToken == null) + || ($this->accessToken->getExpiresIn() < time())) { + $this->accessToken = $this->oauthService->getAccessToken( + $this->grantType, + $this->accountName, + $this->accountKey, + $this->scope + ); + } + + return Resources::OAUTH_ACCESS_TOKEN_PREFIX . + $this->accessToken->getAccessToken(); + } +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Authentication/SharedKeyAuthScheme.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Authentication/SharedKeyAuthScheme.php new file mode 100644 index 0000000..2ecd5b9 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Authentication/SharedKeyAuthScheme.php @@ -0,0 +1,137 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Internal\Authentication; +use WindowsAzure\Common\Internal\Authentication\StorageAuthScheme; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Utilities; + +/** + * Provides shared key authentication scheme for blob and queue. For more info + * check: http://msdn.microsoft.com/en-us/library/windowsazure/dd179428.aspx + * + * @category Microsoft + * @package WindowsAzure\Common\Internal\Authentication + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class SharedKeyAuthScheme extends StorageAuthScheme +{ + protected $includedHeaders; + + /** + * Constructor. + * + * @param string $accountName storage account name. + * @param string $accountKey storage account primary or secondary key. + * + * @return + * WindowsAzure\Common\Internal\Authentication\SharedKeyAuthScheme + */ + public function __construct($accountName, $accountKey) + { + parent::__construct($accountName, $accountKey); + + $this->includedHeaders = array(); + $this->includedHeaders[] = Resources::CONTENT_ENCODING; + $this->includedHeaders[] = Resources::CONTENT_LANGUAGE; + $this->includedHeaders[] = Resources::CONTENT_LENGTH; + $this->includedHeaders[] = Resources::CONTENT_MD5; + $this->includedHeaders[] = Resources::CONTENT_TYPE; + $this->includedHeaders[] = Resources::DATE; + $this->includedHeaders[] = Resources::IF_MODIFIED_SINCE; + $this->includedHeaders[] = Resources::IF_MATCH; + $this->includedHeaders[] = Resources::IF_NONE_MATCH; + $this->includedHeaders[] = Resources::IF_UNMODIFIED_SINCE; + $this->includedHeaders[] = Resources::RANGE; + } + + /** + * Computes the authorization signature for blob and queue shared key. + * + * @param array $headers request headers. + * @param string $url reuqest url. + * @param array $queryParams query variables. + * @param string $httpMethod request http method. + * + * @see Blob and Queue Services (Shared Key Authentication) at + * http://msdn.microsoft.com/en-us/library/windowsazure/dd179428.aspx + * + * @return string + */ + protected function computeSignature($headers, $url, $queryParams, $httpMethod) + { + $canonicalizedHeaders = parent::computeCanonicalizedHeaders($headers); + + $canonicalizedResource = parent::computeCanonicalizedResource( + $url, $queryParams + ); + + + $stringToSign = array(); + $stringToSign[] = strtoupper($httpMethod); + + foreach ($this->includedHeaders as $header) { + $stringToSign[] = Utilities::tryGetValue($headers, $header); + } + + if (count($canonicalizedHeaders) > 0) { + $stringToSign[] = implode("\n", $canonicalizedHeaders); + } + + $stringToSign[] = $canonicalizedResource; + $stringToSign = implode("\n", $stringToSign); + + return $stringToSign; + } + + /** + * Returns authorization header to be included in the request. + * + * @param array $headers request headers. + * @param string $url reuqest url. + * @param array $queryParams query variables. + * @param string $httpMethod request http method. + * + * @see Specifying the Authorization Header section at + * http://msdn.microsoft.com/en-us/library/windowsazure/dd179428.aspx + * + * @return string + */ + public function getAuthorizationHeader($headers, $url, $queryParams, $httpMethod) + { + $signature = $this->computeSignature( + $headers, $url, $queryParams, $httpMethod + ); + + return 'SharedKey ' . $this->accountName . ':' . base64_encode( + hash_hmac('sha256', $signature, base64_decode($this->accountKey), true) + ); + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Authentication/StorageAuthScheme.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Authentication/StorageAuthScheme.php new file mode 100644 index 0000000..680011f --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Authentication/StorageAuthScheme.php @@ -0,0 +1,234 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Internal\Authentication; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Authentication\IAuthScheme; + + +/** + * Base class for azure authentication schemes. + * + * @category Microsoft + * @package WindowsAzure\Common\Internal\Authentication + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +abstract class StorageAuthScheme implements IAuthScheme +{ + protected $accountName; + protected $accountKey; + + /** + * Constructor. + * + * @param string $accountName storage account name. + * @param string $accountKey storage account primary or secondary key. + * + * @return + * WindowsAzure\Common\Internal\Authentication\StorageAuthScheme + */ + public function __construct($accountName, $accountKey) + { + $this->accountKey = $accountKey; + $this->accountName = $accountName; + } + + /** + * Computes canonicalized headers for headers array. + * + * @param array $headers request headers. + * + * @see Constructing the Canonicalized Headers String section at + * http://msdn.microsoft.com/en-us/library/windowsazure/dd179428.aspx + * + * @return array + */ + protected function computeCanonicalizedHeaders($headers) + { + $canonicalizedHeaders = array(); + $normalizedHeaders = array(); + $validPrefix = Resources::X_MS_HEADER_PREFIX; + + if (is_null($normalizedHeaders)) { + return $canonicalizedHeaders; + } + + foreach ($headers as $header => $value) { + // Convert header to lower case. + $header = strtolower($header); + + // Retrieve all headers for the resource that begin with x-ms-, + // including the x-ms-date header. + if (Utilities::startsWith($header, $validPrefix)) { + // Unfold the string by replacing any breaking white space + // (meaning what splits the headers, which is \r\n) with a single + // space. + $value = str_replace("\r\n", ' ', $value); + + // Trim any white space around the colon in the header. + $value = ltrim($value); + $header = rtrim($header); + + $normalizedHeaders[$header] = $value; + } + } + + // Sort the headers lexicographically by header name, in ascending order. + // Note that each header may appear only once in the string. + ksort($normalizedHeaders); + + foreach ($normalizedHeaders as $key => $value) { + $canonicalizedHeaders[] = $key . ':' . $value; + } + + return $canonicalizedHeaders; + } + + /** + * Computes canonicalized resources from URL using Table formar + * + * @param string $url request url. + * @param array $queryParams request query variables. + * + * @see Constructing the Canonicalized Resource String section at + * http://msdn.microsoft.com/en-us/library/windowsazure/dd179428.aspx + * + * @return string + */ + protected function computeCanonicalizedResourceForTable($url, $queryParams) + { + $queryParams = array_change_key_case($queryParams); + + // 1. Beginning with an empty string (""), append a forward slash (/), + // followed by the name of the account that owns the accessed resource. + $canonicalizedResource = '/' . $this->accountName; + + // 2. Append the resource's encoded URI path, without any query parameters. + $canonicalizedResource .= parse_url($url, PHP_URL_PATH); + + // 3. The query string should include the question mark and the comp + // parameter (for example, ?comp=metadata). No other parameters should + // be included on the query string. + if (array_key_exists(Resources::QP_COMP, $queryParams)) { + $canonicalizedResource .= '?' . Resources::QP_COMP . '='; + $canonicalizedResource .= $queryParams[Resources::QP_COMP]; + } + + return $canonicalizedResource; + } + + /** + * Computes canonicalized resources from URL. + * + * @param string $url request url. + * @param array $queryParams request query variables. + * + * @see Constructing the Canonicalized Resource String section at + * http://msdn.microsoft.com/en-us/library/windowsazure/dd179428.aspx + * + * @return string + */ + protected function computeCanonicalizedResource($url, $queryParams) + { + $queryParams = array_change_key_case($queryParams); + + // 1. Beginning with an empty string (""), append a forward slash (/), + // followed by the name of the account that owns the accessed resource. + $canonicalizedResource = '/' . $this->accountName; + + // 2. Append the resource's encoded URI path, without any query parameters. + $canonicalizedResource .= parse_url($url, PHP_URL_PATH); + + // 3. Retrieve all query parameters on the resource URI, including the comp + // parameter if it exists. + // 4. Sort the query parameters lexicographically by parameter name, in + // ascending order. + if (count($queryParams) > 0) { + ksort($queryParams); + } + + // 5. Convert all parameter names to lowercase. + // 6. URL-decode each query parameter name and value. + // 7. Append each query parameter name and value to the string in the + // following format: + // parameter-name:parameter-value + // 9. Group query parameters + // 10. Append a new line character (\n) after each name-value pair. + foreach ($queryParams as $key => $value) { + // Grouping query parameters + $values = explode(Resources::SEPARATOR, $value); + sort($values); + $separated = implode(Resources::SEPARATOR, $values); + + $canonicalizedResource .= "\n" . $key . ':' . $separated; + } + + return $canonicalizedResource; + } + + /** + * Returns authorization header to be included in the request. + * + * @param array $headers request headers. + * @param string $url reuqest url. + * @param array $queryParams query variables. + * @param string $httpMethod request http method. + * + * @see Specifying the Authorization Header section at + * http://msdn.microsoft.com/en-us/library/windowsazure/dd179428.aspx + * + * @abstract + * + * @return string + */ + abstract public function getAuthorizationHeader($headers, $url, $queryParams, + $httpMethod + ); + + /** + * Computes the authorization signature. + * + * @param array $headers request headers. + * @param string $url reuqest url. + * @param array $queryParams query variables. + * @param string $httpMethod request http method. + * + * @see check all authentication schemes at + * http://msdn.microsoft.com/en-us/library/windowsazure/dd179428.aspx + * + * @abstract + * + * @return string + */ + abstract protected function computeSignature($headers, $url, $queryParams, + $httpMethod + ); +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Authentication/TableSharedKeyLiteAuthScheme.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Authentication/TableSharedKeyLiteAuthScheme.php new file mode 100644 index 0000000..6dd08f9 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Authentication/TableSharedKeyLiteAuthScheme.php @@ -0,0 +1,118 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link http://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Internal\Authentication; +use WindowsAzure\Common\Internal\Authentication\StorageAuthScheme; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Utilities; + +/** + * Provides shared key authentication scheme for blob and queue. For more info + * check: http://msdn.microsoft.com/en-us/library/windowsazure/dd179428.aspx + * + * @category Microsoft + * @package WindowsAzure\Common\Internal\Authentication + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link http://github.com/windowsazure/azure-sdk-for-php + */ +class TableSharedKeyLiteAuthScheme extends StorageAuthScheme +{ + protected $includedHeaders; + + /** + * Constructor. + * + * @param string $accountName storage account name. + * @param string $accountKey storage account primary or secondary key. + * + * @return TableSharedKeyLiteAuthScheme + */ + public function __construct($accountName, $accountKey) + { + parent::__construct($accountName, $accountKey); + + $this->includedHeaders = array(); + $this->includedHeaders[] = Resources::DATE; + } + + /** + * Computes the authorization signature for blob and queue shared key. + * + * @param array $headers request headers. + * @param string $url reuqest url. + * @param array $queryParams query variables. + * @param string $httpMethod request http method. + * + * @see Blob and Queue Services (Shared Key Authentication) at + * http://msdn.microsoft.com/en-us/library/windowsazure/dd179428.aspx + * + * @return string + */ + protected function computeSignature($headers, $url, $queryParams, $httpMethod) + { + $canonicalizedResource = parent::computeCanonicalizedResourceForTable( + $url, $queryParams + ); + + $stringToSign = array(); + + foreach ($this->includedHeaders as $header) { + $stringToSign[] = Utilities::tryGetValue($headers, $header); + } + + $stringToSign[] = $canonicalizedResource; + $stringToSign = implode("\n", $stringToSign); + + return $stringToSign; + } + + /** + * Returns authorization header to be included in the request. + * + * @param array $headers request headers. + * @param string $url reuqest url. + * @param array $queryParams query variables. + * @param string $httpMethod request http method. + * + * @see Specifying the Authorization Header section at + * http://msdn.microsoft.com/en-us/library/windowsazure/dd179428.aspx + * + * @return string + */ + public function getAuthorizationHeader($headers, $url, $queryParams, $httpMethod) + { + $signature = $this->computeSignature( + $headers, $url, $queryParams, $httpMethod + ); + + return 'SharedKeyLite ' . $this->accountName . ':' . base64_encode( + hash_hmac('sha256', $signature, base64_decode($this->accountKey), true) + ); + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/ConnectionStringParser.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/ConnectionStringParser.php new file mode 100644 index 0000000..0659d8b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/ConnectionStringParser.php @@ -0,0 +1,365 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Internal; + +/** + * Helper methods for parsing connection strings. The rules for formatting connection + * strings are defined here: + * www.connectionstrings.com/articles/show/important-rules-for-connection-strings + * + * @category Microsoft + * @package WindowsAzure\Common\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class ConnectionStringParser +{ + /** + * @var string + */ + private $_argumentName; + + /** + * @var string + */ + private $_value; + + /** + * @var integer + */ + private $_pos; + + /** + * @var string + */ + private $_state; + + /** + * Parses the connection string into a collection of key/value pairs. + * + * @param string $argumentName Name of the argument to be used in error + * messages. + * @param string $connectionString Connection string. + * + * @return array + * + * @static + */ + public static function parseConnectionString($argumentName, $connectionString) + { + Validate::isString($argumentName, 'argumentName'); + Validate::notNullOrEmpty($argumentName, 'argumentName'); + Validate::isString($connectionString, 'connectionString'); + Validate::notNullOrEmpty($connectionString, 'connectionString'); + + $parser = new ConnectionStringParser($argumentName, $connectionString); + return $parser->_parse(); + } + + /** + * Initializes the object. + * + * @param string $argumentName Name of the argument to be used in error + * messages. + * @param string $value Connection string. + */ + private function __construct($argumentName, $value) + { + $this->_argumentName = $argumentName; + $this->_value = $value; + $this->_pos = 0; + $this->_state = ParserState::EXPECT_KEY; + } + + /** + * Parses the connection string. + * + * @return array + * + * @throws \RuntimeException + */ + private function _parse() + { + $key = null; + $value = null; + $connectionStringValues = array(); + + while (true) { + $this->_skipWhiteSpaces(); + + if ( $this->_pos == strlen($this->_value) + && $this->_state != ParserState::EXPECT_VALUE + ) { + // Not stopping after the end has been reached and a value is + // expected results in creating an empty value, which we expect. + break; + } + + switch ($this->_state) { + case ParserState::EXPECT_KEY: + $key = $this->_extractKey(); + $this->_state = ParserState::EXPECT_ASSIGNMENT; + break; + + case ParserState::EXPECT_ASSIGNMENT: + $this->_skipOperator('='); + $this->_state = ParserState::EXPECT_VALUE; + break; + + case ParserState::EXPECT_VALUE: + $value = $this->_extractValue(); + $this->_state = ParserState::EXPECT_SEPARATOR; + $connectionStringValues[$key] = $value; + $key = null; + $value = null; + break; + + default: + $this->_skipOperator(';'); + $this->_state = ParserState::EXPECT_KEY; + break; + } + } + + // Must end parsing in the valid state (expected key or separator) + if ($this->_state == ParserState::EXPECT_ASSIGNMENT) { + throw $this->_createException( + $this->_pos, + Resources::MISSING_CONNECTION_STRING_CHAR, + '=' + ); + } + + return $connectionStringValues; + } + + /** + *Generates an invalid connection string exception with the detailed error + * message. + * + * @param integer $position The position of the error. + * @param string $errorString The short error formatting string. + * + * @return \RuntimeException + */ + private function _createException($position, $errorString) + { + $arguments = func_get_args(); + + // Remove first argument (position) + unset($arguments[0]); + + // Create a short error message. + $errorString = sprintf($errorString, $arguments); + + // Add position. + $errorString = sprintf( + Resources::ERROR_PARSING_STRING, + $errorString, + $position + ); + + // Create final error message. + $errorString = sprintf( + Resources::INVALID_CONNECTION_STRING, + $this->_argumentName, + $errorString + ); + + return new \RuntimeException($errorString); + } + + /** + * Skips whitespaces at the current position. + * + * @return none + */ + private function _skipWhiteSpaces() + { + while ( $this->_pos < strlen($this->_value) + && ctype_space($this->_value[$this->_pos]) + ) { + $this->_pos++; + } + } + + /** + * Extracts the key's value. + * + * @return string + */ + private function _extractValue() + { + $value = Resources::EMPTY_STRING; + + if ($this->_pos < strlen($this->_value)) { + $ch = $this->_value[$this->_pos]; + + if ($ch == '"' || $ch == '\'') { + // Value is contained between double quotes or skipped single quotes. + $this->_pos++; + $value = $this->_extractString($ch); + } else { + $firstPos = $this->_pos; + $isFound = false; + + while ($this->_pos < strlen($this->_value) && !$isFound) { + $ch = $this->_value[$this->_pos]; + + if ($ch == ';') { + $isFound = true; + } else { + $this->_pos++; + } + } + + $value = rtrim( + substr($this->_value, $firstPos, $this->_pos - $firstPos) + ); + } + } + + return $value; + } + + /** + * Extracts key at the current position. + * + * @return string + */ + private function _extractKey() + { + $key = null; + $firstPos = $this->_pos; + $ch = $this->_value[$this->_pos]; + + if ($ch == '"' || $ch == '\'') { + $this->_pos++; + $key = $this->_extractString($ch); + } else if ($ch == ';' || $ch == '=') { + // Key name was expected. + throw $this->_createException( + $firstPos, + Resources::ERROR_CONNECTION_STRING_MISSING_KEY + ); + } else { + while ($this->_pos < strlen($this->_value)) { + $ch = $this->_value[$this->_pos]; + + // At this point we've read the key, break. + if ($ch == '=') { + break; + } + + $this->_pos++; + } + $key = rtrim(substr($this->_value, $firstPos, $this->_pos - $firstPos)); + } + + if (strlen($key) == 0) { + // Empty key name. + throw $this->_createException( + $firstPos, + Resources::ERROR_CONNECTION_STRING_EMPTY_KEY + ); + } + + return $key; + } + + /** + * Extracts the string until the given quotation mark. + * + * @param string $quote The quotation mark terminating the string. + * + * @return string + */ + private function _extractString($quote) + { + $firstPos = $this->_pos; + + while ( $this->_pos < strlen($this->_value) + && $this->_value[$this->_pos] != $quote + ) { + $this->_pos++; + } + + if ($this->_pos == strlen($this->_value)) { + // Runaway string. + throw $this->_createException( + $this->_pos, + Resources::ERROR_CONNECTION_STRING_MISSING_CHARACTER, + $quote + ); + } + + return substr($this->_value, $firstPos, $this->_pos++ - $firstPos); + } + + /** + * Skips specified operator. + * + * @param string $operatorChar The operator character. + * + * @return none + * + * @throws \RuntimeException + */ + private function _skipOperator($operatorChar) + { + if ($this->_value[$this->_pos] != $operatorChar) { + // Character was expected. + throw $this->_createException( + $this->_pos, + Resources::MISSING_CONNECTION_STRING_CHAR, + $operatorChar + ); + } + + $this->_pos++; + } +} + +/** + * State of the connection string parser. + * + * @category Microsoft + * @package WindowsAzure\Common\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class ParserState +{ + const EXPECT_KEY = 'ExpectKey'; + const EXPECT_ASSIGNMENT = 'ExpectAssignment'; + const EXPECT_VALUE = 'ExpectValue'; + const EXPECT_SEPARATOR = 'ExpectSeparator'; +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/ConnectionStringSource.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/ConnectionStringSource.php new file mode 100644 index 0000000..20bf0a8 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/ConnectionStringSource.php @@ -0,0 +1,98 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Internal; + +/** + * Holder for default connection string sources used in CloudConfigurationManager. + * + * @category Microsoft + * @package WindowsAzure\Common\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class ConnectionStringSource +{ + /** + * The list of all sources which comes as default. + * + * @var type + */ + private static $_defaultSources; + + /** + * @var boolean + */ + private static $_isInitialized; + + /** + * Environment variable source name. + */ + const ENVIRONMENT_SOURCE = 'environment_source'; + + /** + * Initializes the default sources. + * + * @return none + */ + private static function _init() + { + if (!self::$_isInitialized) { + self::$_defaultSources = array( + self::ENVIRONMENT_SOURCE => array(__CLASS__, 'environmentSource') + ); + self::$_isInitialized = true; + } + } + + /** + * Gets a connection string value from the system environment. + * + * @param string $key The connection string name. + * + * @return string + */ + public static function environmentSource($key) + { + Validate::isString($key, 'key'); + + return getenv($key); + } + + /** + * Gets list of default sources. + * + * @return array + */ + public static function getDefaultSources() + { + self::_init(); + return self::$_defaultSources; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/FilterableService.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/FilterableService.php new file mode 100644 index 0000000..af86280 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/FilterableService.php @@ -0,0 +1,52 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Internal; + +/** + * Interface for service with filers. + * + * @category Microsoft + * @package WindowsAzure\Common\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +interface FilterableService +{ + /** + * Adds new filter to proxy object and returns new BlobRestProxy with + * that filter. + * + * @param WindowsAzure\Common\Internal\IServiceFilter $filter Filter to add for + * the pipeline. + * + * @return mix. + */ + public function withFilter($filter); +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Filters/AuthenticationFilter.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Filters/AuthenticationFilter.php new file mode 100644 index 0000000..0944004 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Filters/AuthenticationFilter.php @@ -0,0 +1,93 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Internal\Filters; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\IServiceFilter; +use WindowsAzure\Common\Internal\Authentication\SharedKeyAuthScheme; +use WindowsAzure\Common\Internal\Authentication\TableSharedKeyLiteAuthScheme; +use WindowsAzure\Common\Internal\InvalidArgumentTypeException; + +/** + * Adds authentication header to the http request object. + * + * @category Microsoft + * @package WindowsAzure\Common\Internal\Filters + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class AuthenticationFilter implements IServiceFilter +{ + /** + * @var WindowsAzure\Common\Internal\Authentication\StorageAuthScheme + */ + private $_authenticationScheme; + + /** + * Creates AuthenticationFilter with the passed scheme. + * + * @param StorageAuthScheme $authenticationScheme The authentication scheme. + */ + public function __construct($authenticationScheme) + { + $this->_authenticationScheme = $authenticationScheme; + } + + /** + * Adds authentication header to the request headers. + * + * @param HttpClient $request HTTP channel object. + * + * @return \HTTP_Request2 + */ + public function handleRequest($request) + { + $signedKey = $this->_authenticationScheme->getAuthorizationHeader( + $request->getHeaders(), $request->getUrl(), + $request->getUrl()->getQueryVariables(), $request->getMethod() + ); + $request->setHeader(Resources::AUTHENTICATION, $signedKey); + + return $request; + } + + /** + * Does nothing with the response. + * + * @param HttpClient $request HTTP channel object. + * @param \HTTP_Request2_Response $response HTTP response object. + * + * @return \HTTP_Request2_Response + */ + public function handleResponse($request, $response) + { + // Do nothing with the response. + return $response; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Filters/DateFilter.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Filters/DateFilter.php new file mode 100644 index 0000000..95d1fcb --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Filters/DateFilter.php @@ -0,0 +1,72 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Internal\Filters; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\IServiceFilter; + +/** + * Adds date header to the http request. + * + * @category Microsoft + * @package WindowsAzure\Common\Internal\Filters + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class DateFilter implements IServiceFilter +{ + /** + * Adds date (in GMT format) header to the request headers. + * + * @param HttpClient $request HTTP channel object. + * + * @return \HTTP_Request2 + */ + public function handleRequest($request) + { + $date = gmdate(Resources::AZURE_DATE_FORMAT, time()); + $request->setHeader(Resources::DATE, $date); + + return $request; + } + + /** + * Does nothing with the response. + * + * @param HttpClient $request HTTP channel object. + * @param \HTTP_Request2_Response $response HTTP response object. + * + * @return \HTTP_Request2_Response + */ + public function handleResponse($request, $response) + { + // Do nothing with the response. + return $response; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Filters/ExponentialRetryPolicy.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Filters/ExponentialRetryPolicy.php new file mode 100644 index 0000000..3e5ff94 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Filters/ExponentialRetryPolicy.php @@ -0,0 +1,134 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Internal\Filters; + +/** + * The exponential retry policy. + * + * @category Microsoft + * @package WindowsAzure\Common\Internal\Filters + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class ExponentialRetryPolicy extends RetryPolicy +{ + /** + * @var integer + */ + private $_deltaBackoffIntervalInMs; + + /** + * @var integer + */ + private $_maximumAttempts; + + /** + * @var integer + */ + private $_resolvedMaxBackoff; + + /** + * @var integer + */ + private $_resolvedMinBackoff; + + /** + * @var array + */ + private $_retryableStatusCodes; + + /** + * Initializes new object from ExponentialRetryPolicy. + * + * @param array $retryableStatusCodes The retryable status codes. + * @param integer $deltaBackoff The backoff time delta. + * @param integer $maximumAttempts The number of max attempts. + */ + public function __construct($retryableStatusCodes, + $deltaBackoff = parent::DEFAULT_CLIENT_BACKOFF, + $maximumAttempts = parent::DEFAULT_CLIENT_RETRY_COUNT + ) { + $this->_deltaBackoffIntervalInMs = $deltaBackoff; + $this->_maximumAttempts = $maximumAttempts; + $this->_resolvedMaxBackoff = parent::DEFAULT_MAX_BACKOFF; + $this->_resolvedMinBackoff = parent::DEFAULT_MIN_BACKOFF; + $this->_retryableStatusCodes = $retryableStatusCodes; + sort($retryableStatusCodes); + } + + /** + * Indicates if there should be a retry or not. + * + * @param integer $retryCount The retry count. + * @param \HTTP_Request2_Response $response The HTTP response object. + * + * @return boolean + */ + public function shouldRetry($retryCount, $response) + { + if ( $retryCount >= $this->_maximumAttempts + || array_search($response->getStatus(), $this->_retryableStatusCodes) + || is_null($response) + ) { + return false; + } else { + return true; + } + } + + /** + * Calculates the backoff for the retry policy. + * + * @param integer $retryCount The retry count. + * @param \HTTP_Request2_Response $response The HTTP response object. + * + * @return integer + */ + public function calculateBackoff($retryCount, $response) + { + // Calculate backoff Interval between 80% and 120% of the desired + // backoff, multiply by 2^n -1 for + // exponential + $incrementDelta = (int) (pow(2, $retryCount) - 1); + $boundedRandDelta = (int) ($this->_deltaBackoffIntervalInMs * 0.8) + + mt_rand( + 0, + (int) ($this->_deltaBackoffIntervalInMs * 1.2) + - (int) ($this->_deltaBackoffIntervalInMs * 0.8) + ); + $incrementDelta *= $boundedRandDelta; + + // Enforce max / min backoffs + return min( + $this->_resolvedMinBackoff + $incrementDelta, + $this->_resolvedMaxBackoff + ); + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Filters/HeadersFilter.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Filters/HeadersFilter.php new file mode 100644 index 0000000..fe7e641 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Filters/HeadersFilter.php @@ -0,0 +1,93 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Internal\Filters; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\IServiceFilter; + +/** + * Adds all passed headers to the HTTP request headers. + * + * @category Microsoft + * @package WindowsAzure\Common\Internal\Filters + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class HeadersFilter implements IServiceFilter +{ + /** + * @var array + */ + private $_headers; + + /** + * Constructor + * + * @param array $headers static headers to be added. + * + * @return HeadersFilter + */ + public function __construct($headers) + { + $this->_headers = $headers; + } + + /** + * Adds static header(s) to the HTTP request headers + * + * @param HttpClient $request HTTP channel object. + * + * @return \HTTP_Request2 + */ + public function handleRequest($request) + { + foreach ($this->_headers as $key => $value) { + $headers = $request->getHeaders(); + if (!array_key_exists($key, $headers)) { + $request->setHeader($key, $value); + } + } + + return $request; + } + + /** + * Does nothing with the response. + * + * @param HttpClient $request HTTP channel object. + * @param \HTTP_Request2_Response $response HTTP response object. + * + * @return \HTTP_Request2_Response + */ + public function handleResponse($request, $response) + { + // Do nothing with the response. + return $response; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Filters/RetryPolicy.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Filters/RetryPolicy.php new file mode 100644 index 0000000..f9688f9 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Filters/RetryPolicy.php @@ -0,0 +1,66 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Internal\Filters; + +/** + * The retry policy abstract class. + * + * @category Microsoft + * @package WindowsAzure\Common\Internal\Filters + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +abstract class RetryPolicy +{ + const DEFAULT_CLIENT_BACKOFF = 30000; + const DEFAULT_CLIENT_RETRY_COUNT = 3; + const DEFAULT_MAX_BACKOFF = 90000; + const DEFAULT_MIN_BACKOFF = 300; + + /** + * Indicates if there should be a retry or not. + * + * @param integer $retryCount The retry count. + * @param \HTTP_Request2_Response $response The HTTP response object. + * + * @return boolean + */ + public abstract function shouldRetry($retryCount, $response); + + /** + * Calculates the backoff for the retry policy. + * + * @param integer $retryCount The retry count. + * @param \HTTP_Request2_Response $response The HTTP response object. + * + * @return integer + */ + public abstract function calculateBackoff($retryCount, $response); +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Filters/RetryPolicyFilter.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Filters/RetryPolicyFilter.php new file mode 100644 index 0000000..dd4987c --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Filters/RetryPolicyFilter.php @@ -0,0 +1,99 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Internal\Filters; +use WindowsAzure\Common\Internal\IServiceFilter; + +/** + * Short description + * + * @category Microsoft + * @package WindowsAzure\Common\Internal\Filters + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class RetryPolicyFilter implements IServiceFilter +{ + /** + * @var RetryPolicy + */ + private $_retryPolicy; + + /** + * Initializes new object from RetryPolicyFilter. + * + * @param RetryPolicy $retryPolicy The retry policy object. + */ + public function __construct($retryPolicy) + { + $this->_retryPolicy = $retryPolicy; + } + + /** + * Handles the request before sending. + * + * @param \HTTP_Request2 $request The HTTP request. + * + * @return \HTTP_Request2 + */ + public function handleRequest($request) + { + return $request; + } + + /** + * Handles the response after sending. + * + * @param \HTTP_Request2 $request The HTTP request. + * @param \HTTP_Request2_Response $response The HTTP response. + * + * @return \HTTP_Request2_Response + */ + public function handleResponse($request, $response) + { + for ($retryCount = 0;; $retryCount++) { + $shouldRetry = $this->_retryPolicy->shouldRetry( + $retryCount, + $response + ); + + if (!$shouldRetry) { + return $response; + } + + // Backoff for some time according to retry policy + $backoffTime = $this->_retryPolicy->calculateBackoff( + $retryCount, + $response + ); + sleep($backoffTime * 0.001); + $response = $request->send(array()); + } + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Filters/WrapFilter.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Filters/WrapFilter.php new file mode 100644 index 0000000..89cf581 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Filters/WrapFilter.php @@ -0,0 +1,113 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Internal\Filters; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Validate; +use WindowsAzure\Common\Internal\IServiceFilter; +use WindowsAzure\Common\Internal\Authentication\SharedKeyAuthScheme; +use WindowsAzure\Common\Internal\Authentication\TableSharedKeyLiteAuthScheme; +use WindowsAzure\Common\Internal\InvalidArgumentTypeException; +use WindowsAzure\ServiceBus\Internal\WrapTokenManager; + + +/** + * Adds WRAP authentication header to the http request object. + * + * @category Microsoft + * @package WindowsAzure\Common\Internal\Filters + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class WrapFilter implements IServiceFilter +{ + /** + * @var WrapTokenManager + */ + private $_wrapTokenManager; + + /** + * Creates a WrapFilter with specified WRAP parameters. + * + * @param string $wrapUri The URI of the WRAP service. + * @param string $wrapUsername The user name of the WRAP account. + * @param string $wrapPassword The password of the WRAP account. + * @param IWrap $wrapRestProxy The WRAP service REST proxy. + */ + public function __construct( + $wrapUri, + $wrapUsername, + $wrapPassword, + $wrapRestProxy + ) { + $this->_wrapTokenManager = new WrapTokenManager( + $wrapUri, + $wrapUsername, + $wrapPassword, + $wrapRestProxy + ); + } + + /** + * Adds WRAP authentication header to the request headers. + * + * @param HttpClient $request HTTP channel object. + * + * @return \HTTP_Request2 + */ + public function handleRequest($request) + { + Validate::notNull($request, 'request'); + $wrapAccessToken = $this->_wrapTokenManager->getAccessToken( + $request->getUrl() + ); + + $authorization = sprintf( + Resources::WRAP_AUTHORIZATION, + $wrapAccessToken + ); + + $request->setHeader(Resources::AUTHENTICATION, $authorization); + + return $request; + } + + /** + * Returns the original response. + * + * @param HttpClient $request A HTTP channel object. + * @param \HTTP_Request2_Response $response A HTTP response object. + * + * @return \HTTP_Request2_Response + */ + public function handleResponse($request, $response) + { + return $response; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Http/BatchRequest.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Http/BatchRequest.php new file mode 100644 index 0000000..6c40caf --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Http/BatchRequest.php @@ -0,0 +1,162 @@ + + * @copyright Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Internal\Http; +require_once 'PEAR.php'; +require_once 'Mail/mimePart.php'; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Utilities; + +/** + * Batch request marshaler + * + * @category Microsoft + * @package WindowsAzure\Common\Internal + * @author Azure PHP SDK + * @copyright Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class BatchRequest +{ + /** + * Http call context list + * + * @var array + */ + private $_contexts; + + /** + * Headers + * + * @var array + */ + private $_headers; + + /** + * Request body + * + * @var string + */ + private $_body; + + /** + * Constructor + */ + public function __construct() + { + $this->_contexts = array(); + } + + /** + * Append new context to batch request + * + * @param WindowsAzure\Common\Internal\Http\HttpCallContext $context Http call + * context to add to batch request + * + * @return none + */ + public function appendContext($context) + { + $this->_contexts[] = $context; + } + + /** + * Encode contexts + * + * @return none + */ + public function encode() + { + $mimeType = Resources::MULTIPART_MIXED_TYPE; + $batchGuid = Utilities::getGuid(); + $batchId = sprintf('batch_%s', $batchGuid); + $contentType1 = array('content_type' => "$mimeType"); + $changeSetGuid = Utilities::getGuid(); + $changeSetId = sprintf('changeset_%s', $changeSetGuid); + $contentType2 = array('content_type' => "$mimeType; boundary=$changeSetId"); + $options = array( + 'encoding' => 'binary', + 'content_type' => Resources::HTTP_TYPE + ); + + // Create changeset MIME part + $changeSet = new \Mail_mimePart(); + + $i = 1; + foreach ($this->_contexts as $context) { + $context->addHeader(Resources::CONTENT_ID, $i); + $changeSet->addSubpart((string)$context, $options); + + $i++; + } + + // Encode the changeset MIME part + $changeSetEncoded = $changeSet->encode($changeSetId); + + // Create the batch MIME part + $batch = new \Mail_mimePart(Resources::EMPTY_STRING, $contentType1); + + // Add changeset encoded to batch MIME part + $batch->addSubpart($changeSetEncoded['body'], $contentType2); + + // Encode batch MIME part + $batchEncoded = $batch->encode($batchId); + + $this->_headers = $batchEncoded['headers']; + $this->_body = $batchEncoded['body']; + } + + /** + * Get "Request body" + * + * @return string + */ + public function getBody() + { + return $this->_body; + } + + /** + * Get "Headers" + * + * @return array + */ + public function getHeaders() + { + return $this->_headers; + } + + /** + * Get request contexts + * + * @return array + */ + public function getContexts() + { + return $this->_contexts; + } +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Http/BatchResponse.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Http/BatchResponse.php new file mode 100644 index 0000000..cb4360d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Http/BatchResponse.php @@ -0,0 +1,125 @@ + + * @copyright Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Internal\Http; +require_once 'PEAR.php'; +require_once 'Mail/mimeDecode.php'; +require_once 'HTTP/Request2/Response.php'; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Validate; +use WindowsAzure\Common\ServiceException; + +/** + * Batch response parser + * + * @category Microsoft + * @package WindowsAzure\Common\Internal + * @author Azure PHP SDK + * @copyright Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class BatchResponse +{ + /** + * Http responses list + * + * @var array + */ + private $_contexts; + + /** + * Constructor + * + * @param string $content Http response + * as string + * + * @param WindowsAzure\Common\Internal\Http\BatchRequest $request Source batch + * request object + */ + public function __construct($content, $request = null) + { + $params['include_bodies'] = true; + $params['input'] = $content; + $mimeDecoder = new \Mail_mimeDecode($content); + $structure = $mimeDecoder->decode($params); + $parts = $structure->parts; + $this->_contexts = array(); + $requestContexts = null; + + if ($request != null) { + Validate::isA( + $request, + 'WindowsAzure\Common\Internal\Http\BatchRequest', + 'request' + ); + $requestContexts = $request->getContexts(); + } + + $i = 0; + foreach ($parts as $part) { + if (!empty($part->body)) { + $headerEndPos = strpos($part->body, "\r\n\r\n"); + + $header = substr($part->body, 0, $headerEndPos); + $body = substr($part->body, $headerEndPos + 4); + $headerStrings = explode("\r\n", $header); + + $response = new \HTTP_Request2_Response(array_shift($headerStrings)); + foreach ($headerStrings as $headerString) { + $response->parseHeaderLine($headerString); + } + $response->appendBody($body); + + $this->_contexts[] = $response; + + if (is_array($requestContexts)) { + $expectedCodes = $requestContexts[$i]->getStatusCodes(); + $statusCode = $response->getStatus(); + + if (!in_array($statusCode, $expectedCodes)) { + $reason = $response->getReasonPhrase(); + + throw new ServiceException($statusCode, $reason, $body); + } + } + + $i++; + } + } + } + + /** + * Get parsed contexts as array + * + * @return array + */ + public function getContexts() + { + return $this->_contexts; + } + +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Http/HttpCallContext.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Http/HttpCallContext.php new file mode 100644 index 0000000..7989dc8 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Http/HttpCallContext.php @@ -0,0 +1,446 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Internal\Http; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Validate; +use WindowsAzure\Common\Internal\Http\Url; + +/** + * Holds basic elements for making HTTP call. + * + * @category Microsoft + * @package WindowsAzure\Common\Internal\Http + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class HttpCallContext +{ + /** + * The HTTP method used to make this call. + * + * @var string + */ + private $_method; + + /** + * HTTP request headers. + * + * @var array + */ + private $_headers; + + /** + * The URI query parameters. + * + * @var array + */ + private $_queryParams; + + /** + * The HTTP POST parameters. + * + * @var array. + */ + private $_postParameters; + + /** + * @var string + */ + private $_uri; + + /** + * The URI path. + * + * @var string + */ + private $_path; + + /** + * The expected status codes. + * + * @var array + */ + private $_statusCodes; + + /** + * The HTTP request body. + * + * @var string + */ + private $_body; + + /** + * Default constructor. + */ + public function __construct() + { + $this->_method = null; + $this->_body = null; + $this->_path = null; + $this->_uri = null; + $this->_queryParams = array(); + $this->_postParameters = array(); + $this->_statusCodes = array(); + $this->_headers = array(); + } + + /** + * Gets method. + * + * @return string + */ + public function getMethod() + { + return $this->_method; + } + + /** + * Sets method. + * + * @param string $method The method value. + * + * @return none + */ + public function setMethod($method) + { + Validate::isString($method, 'method'); + + $this->_method = $method; + } + + /** + * Gets headers. + * + * @return array + */ + public function getHeaders() + { + return $this->_headers; + } + + /** + * Sets headers. + * + * Ignores the header if its value is empty. + * + * @param array $headers The headers value. + * + * @return none + */ + public function setHeaders($headers) + { + $this->_headers = array(); + foreach ($headers as $key => $value) { + $this->addHeader($key, $value); + } + } + + /** + * Gets queryParams. + * + * @return array + */ + public function getQueryParameters() + { + return $this->_queryParams; + } + + /** + * Sets queryParams. + * + * Ignores the query variable if its value is empty. + * + * @param array $queryParams The queryParams value. + * + * @return none + */ + public function setQueryParameters($queryParams) + { + $this->_queryParams = array(); + foreach ($queryParams as $key => $value) { + $this->addQueryParameter($key, $value); + } + } + + /** + * Gets uri. + * + * @return string + */ + public function getUri() + { + return $this->_uri; + } + + /** + * Sets uri. + * + * @param string $uri The uri value. + * + * @return none + */ + public function setUri($uri) + { + Validate::isString($uri, 'uri'); + + $this->_uri = $uri; + } + + /** + * Gets path. + * + * @return string + */ + public function getPath() + { + return $this->_path; + } + + /** + * Sets path. + * + * @param string $path The path value. + * + * @return none + */ + public function setPath($path) + { + Validate::isString($path, 'path'); + + $this->_path = $path; + } + + /** + * Gets statusCodes. + * + * @return array + */ + public function getStatusCodes() + { + return $this->_statusCodes; + } + + /** + * Sets statusCodes. + * + * @param array $statusCodes The statusCodes value. + * + * @return none + */ + public function setStatusCodes($statusCodes) + { + $this->_statusCodes = array(); + foreach ($statusCodes as $value) { + $this->addStatusCode($value); + } + } + + /** + * Gets body. + * + * @return string + */ + public function getBody() + { + return $this->_body; + } + + /** + * Sets body. + * + * @param string $body The body value. + * + * @return none + */ + public function setBody($body) + { + Validate::isString($body, 'body'); + + $this->_body = $body; + } + + /** + * Adds or sets header pair. + * + * @param string $name The HTTP header name. + * @param string $value The HTTP header value. + * + * @return none + */ + public function addHeader($name, $value) + { + Validate::isString($name, 'name'); + Validate::isString($value, 'value'); + + $this->_headers[$name] = $value; + } + + /** + * Adds or sets header pair. + * + * Ignores header if it's value satisfies empty(). + * + * @param string $name The HTTP header name. + * @param string $value The HTTP header value. + * + * @return none + */ + public function addOptionalHeader($name, $value) + { + Validate::isString($name, 'name'); + Validate::isString($value, 'value'); + + if (!empty($value)) { + $this->_headers[$name] = $value; + } + } + + /** + * Removes header from the HTTP request headers. + * + * @param string $name The HTTP header name. + * + * @return none + */ + public function removeHeader($name) + { + Validate::isString($name, 'name'); + Validate::notNullOrEmpty($name, 'name'); + + unset($this->_headers[$name]); + } + + /** + * Adds or sets query parameter pair. + * + * @param string $name The URI query parameter name. + * @param string $value The URI query parameter value. + * + * @return none + */ + public function addQueryParameter($name, $value) + { + Validate::isString($name, 'name'); + Validate::isString($value, 'value'); + + $this->_queryParams[$name] = $value; + } + + /** + * Gets HTTP POST parameters. + * + * @return array + */ + public function getPostParameters() + { + return $this->_postParameters; + } + + /** + * Sets HTTP POST parameters. + * + * @param array $postParameters The HTTP POST parameters. + * + * @return none + */ + public function setPostParameters($postParameters) + { + Validate::isArray($postParameters, 'postParameters'); + $this->_postParameters = $postParameters; + } + + /** + * Adds or sets query parameter pair. + * + * Ignores query parameter if it's value satisfies empty(). + * + * @param string $name The URI query parameter name. + * @param string $value The URI query parameter value. + * + * @return none + */ + public function addOptionalQueryParameter($name, $value) + { + Validate::isString($name, 'name'); + Validate::isString($value, 'value'); + + if (!empty($value)) { + $this->_queryParams[$name] = $value; + } + } + + /** + * Adds status code to the expected status codes. + * + * @param integer $statusCode The expected status code. + * + * @return none + */ + public function addStatusCode($statusCode) + { + Validate::isInteger($statusCode, 'statusCode'); + + $this->_statusCodes[] = $statusCode; + } + + /** + * Gets header value. + * + * @param string $name The header name. + * + * @return mix + */ + public function getHeader($name) + { + return Utilities::tryGetValue($this->_headers, $name); + } + + /** + * Converts the context object to string. + * + * @return string + */ + public function __toString() + { + $headers = Resources::EMPTY_STRING; + $uri = new Url($this->_uri); + $uri = $uri->getUrl(); + + foreach ($this->_headers as $key => $value) { + $headers .= "$key: $value\n"; + } + + $str = "$this->_method $uri$this->_path HTTP/1.1\n$headers\n"; + $str .= "$this->_body"; + + return $str; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Http/HttpClient.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Http/HttpClient.php new file mode 100644 index 0000000..f773ae2 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Http/HttpClient.php @@ -0,0 +1,387 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Internal\Http; +use WindowsAzure\Common\Internal\Http\IHttpClient; +use WindowsAzure\Common\Internal\IServiceFilter; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\ServiceException; +use WindowsAzure\Common\Internal\Validate; +use WindowsAzure\Common\Internal\Http\IUrl; + +require_once 'HTTP/Request2.php'; + +/** + * HTTP client which sends and receives HTTP requests and responses. + * + * @category Microsoft + * @package WindowsAzure\Common\Internal\Http + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class HttpClient implements IHttpClient +{ + /** + * @var \HTTP_Request2 + */ + private $_request; + + /** + * @var WindowsAzure\Common\Internal\Http\IUrl + */ + private $_requestUrl; + + /** + * Holds the latest response object + * + * @var \HTTP_Request2_Response + */ + private $_response; + + /** + * Holds expected status code after sending the request. + * + * @var array + */ + private $_expectedStatusCodes; + + /** + * Initializes new HttpClient object. + * + * @param string $certificatePath The certificate path. + * @param string $certificateAuthorityPath The path of the certificate authority. + * + * @return WindowsAzure\Common\Internal\Http\HttpClient + */ + function __construct( + $certificatePath = Resources::EMPTY_STRING, + $certificateAuthorityPath = Resources::EMPTY_STRING + ) { + $config = array( + Resources::USE_BRACKETS => true, + Resources::SSL_VERIFY_PEER => false, + Resources::SSL_VERIFY_HOST => false + ); + + if (!empty($certificatePath)) { + $config[Resources::SSL_LOCAL_CERT] = $certificatePath; + $config[Resources::SSL_VERIFY_HOST] = true; + } + + if (!empty($certificateAuthorityPath)) { + $config[Resources::SSL_CAFILE] = $certificateAuthorityPath; + $config[Resources::SSL_VERIFY_PEER] = true; + } + + $this->_request = new \HTTP_Request2( + null, null, $config + ); + + $this->setHeader('user-agent', null); + + $this->_requestUrl = null; + $this->_response = null; + $this->_expectedStatusCodes = array(); + } + + /** + * Makes deep copy from the current object. + * + * @return WindowsAzure\Common\Internal\Http\HttpClient + */ + public function __clone() + { + $this->_request = clone $this->_request; + + if (!is_null($this->_requestUrl)) { + $this->_requestUrl = clone $this->_requestUrl; + } + } + + /** + * Sets the request url. + * + * @param WindowsAzure\Common\Internal\Http\IUrl $url request url. + * + * @return none. + */ + public function setUrl($url) + { + $this->_requestUrl = $url; + } + + /** + * Gets request url. Note that you must check if the returned object is null or + * not. + * + * @return WindowsAzure\Common\Internal\Http\IUrl + */ + public function getUrl() + { + return $this->_requestUrl; + } + + /** + * Sets request's HTTP method. You can use \HTTP_Request2 constants like + * Resources::HTTP_GET or strings like 'GET'. + * + * @param string $method request's HTTP method. + * + * @return none + */ + public function setMethod($method) + { + $this->_request->setMethod($method); + } + + /** + * Gets request's HTTP method. + * + * @return string + */ + public function getMethod() + { + return $this->_request->getMethod(); + } + + /** + * Gets request's headers. The returned array key (header names) are all in + * lower case even if they were set having some upper letters. + * + * @return array + */ + public function getHeaders() + { + return $this->_request->getHeaders(); + } + + /** + * Sets a an existing request header to value or creates a new one if the $header + * doesn't exist. + * + * @param string $header header name. + * @param string $value header value. + * @param bool $replace whether to replace previous header with the same name + * or append to its value (comma separated) + * + * @return none + */ + public function setHeader($header, $value, $replace = false) + { + Validate::isString($value, 'value'); + + $this->_request->setHeader($header, $value, $replace); + } + + /** + * Sets request headers using array + * + * @param array $headers headers key-value array + * + * @return none + */ + public function setHeaders($headers) + { + foreach ($headers as $key => $value) { + $this->setHeader($key, $value); + } + } + + /** + * Sets HTTP POST parameters. + * + * @param array $postParameters The HTTP POST parameters. + * + * @return none + */ + public function setPostParameters($postParameters) + { + $this->_request->addPostParameter($postParameters); + } + + /** + * Processes the reuqest through HTTP pipeline with passed $filters, + * sends HTTP request to the wire and process the response in the HTTP pipeline. + * + * @param array $filters HTTP filters which will be applied to the request before + * send and then applied to the response. + * @param IUrl $url Request url. + * + * @throws WindowsAzure\Common\ServiceException + * + * @return string The response body + */ + public function send($filters, $url = null) + { + if (isset($url)) { + $this->setUrl($url); + $this->_request->setUrl($this->_requestUrl->getUrl()); + } + + $contentLength = Resources::EMPTY_STRING; + if ( strtoupper($this->getMethod()) != Resources::HTTP_GET + && strtoupper($this->getMethod()) != Resources::HTTP_DELETE + && strtoupper($this->getMethod()) != Resources::HTTP_HEAD + ) { + $contentLength = 0; + + if (!is_null($this->getBody())) { + $contentLength = strlen($this->getBody()); + } + $this->_request->setHeader(Resources::CONTENT_LENGTH, $contentLength); + } + + foreach ($filters as $filter) { + $this->_request = $filter->handleRequest($this)->_request; + } + + $this->_response = $this->_request->send(); + + $start = count($filters) - 1; + for ($index = $start; $index >= 0; $index--) { + $this->_response = $filters[$index]->handleResponse( + $this, $this->_response + ); + } + + self::throwIfError( + $this->_response->getStatus(), + $this->_response->getReasonPhrase(), + $this->_response->getBody(), + $this->_expectedStatusCodes + ); + + return $this->_response->getBody(); + } + + /** + * Sets successful status code + * + * @param array|string $statusCodes successful status code. + * + * @return none + */ + public function setExpectedStatusCode($statusCodes) + { + if (!is_array($statusCodes)) { + $this->_expectedStatusCodes[] = $statusCodes; + } else { + $this->_expectedStatusCodes = $statusCodes; + } + } + + /** + * Gets successful status code + * + * @return array + */ + public function getSuccessfulStatusCode() + { + return $this->_expectedStatusCodes; + } + + /** + * Sets configuration parameter. + * + * @param string $name The configuration parameter name. + * @param mix $value The configuration parameter value. + * + * @return none + */ + public function setConfig($name, $value = null) + { + $this->_request->setConfig($name, $value); + } + + /** + * Gets value for configuration parameter. + * + * @param string $name configuration parameter name. + * + * @return string + */ + public function getConfig($name) + { + return $this->_request->getConfig($name); + } + + /** + * Sets the request body. + * + * @param string $body body to use. + * + * @return none + */ + public function setBody($body) + { + Validate::isString($body, 'body'); + $this->_request->setBody($body); + } + + /** + * Gets the request body. + * + * @return string + */ + public function getBody() + { + return $this->_request->getBody(); + } + + /** + * Gets the response object. + * + * @return \HTTP_Request2_Response + */ + public function getResponse() + { + return $this->_response; + } + + /** + * Throws ServiceException if the recieved status code is not expected. + * + * @param string $actual The received status code. + * @param string $reason The reason phrase. + * @param string $message The detailed message (if any). + * @param array $expected The expected status codes. + * + * @return none + * + * @static + * + * @throws ServiceException + */ + public static function throwIfError($actual, $reason, $message, $expected) + { + if (!in_array($actual, $expected)) { + throw new ServiceException($actual, $reason, $message); + } + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Http/IHttpClient.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Http/IHttpClient.php new file mode 100644 index 0000000..79cd6b4 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Http/IHttpClient.php @@ -0,0 +1,204 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Internal\Http; + +/** + * Defines required methods for a HTTP client proxy. + * + * @category Microsoft + * @package WindowsAzure\Common\Internal\Http + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +interface IHttpClient +{ + /** + * Sets the request url. + * + * @param WindowsAzure\Common\Internal\Http\IUrl $url request url. + * + * @return none. + */ + public function setUrl($url); + + /** + * Gets request url. + * + * @return WindowsAzure\Common\Internal\Http\IUrl + */ + public function getUrl(); + + /** + * Sets request's HTTP method. + * + * @param string $method request's HTTP method. + * + * @return none. + */ + public function setMethod($method); + + /** + * Gets request's HTTP method. + * + * @return string + */ + public function getMethod(); + + /** + * Gets request's headers + * + * @return array + */ + public function getHeaders(); + + /** + * Sets a an existing request header to value or creates a new one if the $header + * doesn't exist. + * + * @param string $header header name. + * @param string $value header value. + * @param bool $replace whether to replace previous header with the same name + * or append to its value (comma separated) + * + * @return none. + */ + public function setHeader($header, $value, $replace = false); + + /** + * Sets request headers using array + * + * @param array $headers headers key-value array + * + * @return none. + */ + public function setHeaders($headers); + + /** + * Sets HTTP POST parameters. + * + * @param array $postParameters The HTTP POST parameters. + * + * @return none + */ + public function setPostParameters($postParameters); + + /** + * Processes the reuqest through HTTP pipeline with passed $filters, + * sends HTTP request to the wire and process the response in the HTTP pipeline. + * + * @param array $filters HTTP filters which will be applied to the request before + * send and then applied to the response. + * @param IUrl $url Request url. + * + * @return string The response body. + */ + public function send($filters, $url = null); + + /** + * Sets successful status code + * + * @param array|string $statusCodes successful status code. + * + * @return none. + */ + public function setExpectedStatusCode($statusCodes); + + /** + * Gets successful status code + * + * @return array. + */ + public function getSuccessfulStatusCode(); + + /** + * Sets a configuration element for the request. + * + * @param string $name configuration parameter name. + * @param mix $value configuration parameter value. + * + * @return none. + */ + public function setConfig($name, $value = null); + + /** + * Gets value for configuration parameter. + * + * @param string $name configuration parameter name. + * + * @return string. + */ + public function getConfig($name); + + /** + * Sets the request body. + * + * @param string $body body to use. + * + * @return none. + */ + public function setBody($body); + + /** + * Gets the request body. + * + * @return string. + */ + public function getBody(); + + /** + * Makes deep copy from the current object. + * + * @return WindowsAzure\Common\Internal\Http\HttpClient + */ + public function __clone(); + + /** + * Gets the response object. + * + * @return \HTTP_Request2_Response. + */ + public function getResponse(); + + /** + * Throws ServiceException if the recieved status code is not expected. + * + * @param string $actual The received status code. + * @param string $reason The reason phrase. + * @param string $message The detailed message (if any). + * @param array $expected The expected status codes. + * + * @return none + * + * @static + * + * @throws ServiceException + */ + public static function throwIfError($actual, $reason, $message, $expected); +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Http/IUrl.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Http/IUrl.php new file mode 100644 index 0000000..8707f4c --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Http/IUrl.php @@ -0,0 +1,114 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Internal\Http; + +/** + * Defines what are main url functionalities that should be supported + * + * @category Microsoft + * @package WindowsAzure\Common\Internal\Http + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +interface IUrl +{ + /** + * Returns the query portion of the url + * + * @return string + */ + public function getQuery(); + + /** + * Returns the query portion of the url in array form + * + * @return array + */ + public function getQueryVariables(); + + /** + * Sets a an existing query parameter to value or creates a new one if the $key + * doesn't exist. + * + * @param string $key query parameter name. + * @param string $value query value. + * + * @return none. + */ + public function setQueryVariable($key, $value); + + /** + * Gets actual URL string. + * + * @return string. + */ + public function getUrl(); + + /** + * Sets url path + * + * @param string $urlPath url path to set. + * + * @return none. + */ + public function setUrlPath($urlPath); + + /** + * Appends url path + * + * @param string $urlPath url path to append. + * + * @return none. + */ + public function appendUrlPath($urlPath); + + /** + * Gets actual URL string. + * + * @return string. + */ + public function __toString(); + + /** + * Makes deep copy from the current object. + * + * @return WindowsAzure\Common\Internal\Http\Url + */ + public function __clone(); + + /** + * Sets the query string to the specified variables in $array + * + * @param array $array key/value representation of query variables. + * + * @return none. + */ + public function setQueryVariables($array); +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Http/Url.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Http/Url.php new file mode 100644 index 0000000..8967d35 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Http/Url.php @@ -0,0 +1,192 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Internal\Http; +require_once 'Net/URL2.php'; +use WindowsAzure\Common\Internal\Validate; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Http\IUrl; + +/** + * Default IUrl implementation. + * + * @category Microsoft + * @package WindowsAzure\Common\Internal\Http + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class Url implements IUrl +{ + /** + * @var \Net_URL2 + */ + private $_url; + + /** + * Sets the url path to '/' if it's empty + * + * @param string $url the url string + * + * @return none. + */ + private function _setPathIfEmpty($url) + { + $path = parse_url($url, PHP_URL_PATH); + + if (empty($path)) { + $this->setUrlPath('/'); + } + } + + /** + * Constructor + * + * @param string $url the url to set. + * + * @return WindowsAzure\Common\Internal\Http\Url + */ + public function __construct($url) + { + $errorMessage = Resources::INVALID_URL_MSG; + Validate::isTrue(filter_var($url, FILTER_VALIDATE_URL), $errorMessage); + + $this->_url = new \Net_URL2($url); + $this->_setPathIfEmpty($url); + } + + /** + * Makes deep copy from the current object. + * + * @return WindowsAzure\Common\Internal\Http\Url + */ + public function __clone() + { + $this->_url = clone $this->_url; + } + + /** + * Returns the query portion of the url + * + * @return string + */ + public function getQuery() + { + return $this->_url->getQuery(); + } + + /** + * Returns the query portion of the url in array form + * + * @return array + */ + public function getQueryVariables() + { + return $this->_url->getQueryVariables(); + } + + /** + * Sets a an existing query parameter to value or creates a new one if the $key + * doesn't exist. + * + * @param string $key query parameter name. + * @param string $value query value. + * + * @return none + */ + public function setQueryVariable($key, $value) + { + Validate::isString($key, 'key'); + Validate::isString($value, 'value'); + + $this->_url->setQueryVariable($key, $value); + } + + /** + * Gets actual URL string. + * + * @return string. + */ + public function getUrl() + { + return $this->_url->getURL(); + } + + /** + * Sets url path + * + * @param string $urlPath url path to set. + * + * @return none. + */ + public function setUrlPath($urlPath) + { + Validate::isString($urlPath, 'urlPath'); + + $this->_url->setPath($urlPath); + } + + /** + * Appends url path + * + * @param string $urlPath url path to append. + * + * @return none. + */ + public function appendUrlPath($urlPath) + { + Validate::isString($urlPath, 'urlPath'); + + $newUrlPath = parse_url($this->_url, PHP_URL_PATH) . $urlPath; + $this->_url->setPath($newUrlPath); + } + + /** + * Gets actual URL string. + * + * @return string. + */ + public function __toString() + { + return $this->_url->getURL(); + } + + /** + * Sets the query string to the specified variables in $array + * + * @param array $array key/value representation of query variables. + * + * @return none. + */ + public function setQueryVariables($array) + { + foreach ($array as $key => $value) { + $this->setQueryVariable($key, $value); + } + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/IServiceFilter.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/IServiceFilter.php new file mode 100644 index 0000000..4c8b256 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/IServiceFilter.php @@ -0,0 +1,61 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Internal; + +/** + * ServceFilter is called when the sending the request and after receiving the + * response. + * + * @category Microsoft + * @package WindowsAzure\Common\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +interface IServiceFilter +{ + /** + * Processes HTTP request before send. + * + * @param mix $request HTTP request object. + * + * @return mix processed HTTP request object. + */ + public function handleRequest($request); + + /** + * Processes HTTP response after send. + * + * @param mix $request HTTP request object. + * @param mix $response HTTP response object. + * + * @return mix processed HTTP response object. + */ + public function handleResponse($request, $response); +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/InvalidArgumentTypeException.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/InvalidArgumentTypeException.php new file mode 100644 index 0000000..bcd1cc8 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/InvalidArgumentTypeException.php @@ -0,0 +1,57 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Internal; +use WindowsAzure\Common\Internal\Resources; + +/** + * Exception thrown if an argument type does not match with the expected type. + * + * @category Microsoft + * @package WindowsAzure\Common\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class InvalidArgumentTypeException extends \InvalidArgumentException +{ + /** + * Constructor. + * + * @param string $validType The valid type that should be provided by the user. + * @param string $name The parameter name. + * + * @return WindowsAzure\Common\Internal\InvalidArgumentTypeException + */ + public function __construct($validType, $name = null) + { + parent::__construct( + sprintf(Resources::INVALID_PARAM_MSG, $name, $validType) + ); + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Logger.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Logger.php new file mode 100644 index 0000000..3858a95 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Logger.php @@ -0,0 +1,83 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Internal; + +/** + * Logger class for debugging purpose. + * + * @category Microsoft + * @package WindowsAzure\Common\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class Logger +{ + /** + * @var string + */ + private static $_filePath; + + /** + * Logs $var to file. + * + * @param mix $var The data to log. + * @param string $tip The help message. + * + * @static + * + * @return none + */ + public static function log($var, $tip = Resources::EMPTY_STRING) + { + if (!empty($tip)) { + error_log($tip . "\n", 3, self::$_filePath); + } + + if (is_array($var) || is_object($var)) { + error_log(print_r($var, true), 3, self::$_filePath); + } else { + error_log($var . "\n", 3, self::$_filePath); + } + } + + /** + * Sets file path to use. + * + * @param string $filePath The log file path. + * + * @static + * + * @return none + */ + public static function setLogFile($filePath) + { + self::$_filePath = $filePath; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/MediaServicesSettings.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/MediaServicesSettings.php new file mode 100644 index 0000000..a7bc656 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/MediaServicesSettings.php @@ -0,0 +1,268 @@ + + * @copyright Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Internal; +use WindowsAzure\Common\Internal\Resources; + +/** + * Represents the settings used to sign and access a request against the service + * management. For more information about service management connection strings check + * this page: http://msdn.microsoft.com/en-us/library/windowsazure/gg466228.aspx + * + * @category Microsoft + * @package WindowsAzure\Common\Internal + * @author Azure PHP SDK + * @copyright Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class MediaServicesSettings extends ServiceSettings +{ + /** + * @var string + */ + private $_accountName; + + /** + * @var string + */ + private $_accessKey; + + /** + * @var string + */ + private $_endpointUri; + + /** + * @var string + */ + private $_oauthEndpointUri; + + /** + * Validator for the MediaServicesAccountName setting. It has to be provided. + * + * @var array + */ + private static $_accountNameSetting; + + /** + * Validator for the MediaServicesAccessKey setting. It has to be provided. + * + * @var array + */ + private static $_accessKeySetting; + + /** + * Validator for the MediaServicesEndpoint setting. Must be a valid Uri. + * + * @var array + */ + private static $_endpointUriSetting; + + /** + * Validator for the MediaServicesOAuthEndpoint setting. Must be a valid Uri. + * + * @var array + */ + private static $_oauthEndpointUriSetting; + + /** + * @var boolean + */ + protected static $isInitialized = false; + + /** + * Holds the expected setting keys. + * + * @var array + */ + protected static $validSettingKeys = array(); + + /** + * Initializes static members of the class. + * + * @return none + */ + protected static function init() + { + self::$_endpointUriSetting = self::settingWithFunc( + Resources::MEDIA_SERVICES_ENDPOINT_URI_NAME, + Validate::getIsValidUri() + ); + + self::$_oauthEndpointUriSetting = self::settingWithFunc( + Resources::MEDIA_SERVICES_OAUTH_ENDPOINT_URI_NAME, + Validate::getIsValidUri() + ); + + self::$_accountNameSetting = self::setting( + Resources::MEDIA_SERVICES_ACCOUNT_NAME + ); + + self::$_accessKeySetting = self::setting( + Resources::MEDIA_SERVICES_ACCESS_KEY + ); + + self::$validSettingKeys[] = Resources::MEDIA_SERVICES_ENDPOINT_URI_NAME; + self::$validSettingKeys[] = Resources::MEDIA_SERVICES_OAUTH_ENDPOINT_URI_NAME; + self::$validSettingKeys[] = Resources::MEDIA_SERVICES_ACCOUNT_NAME; + self::$validSettingKeys[] = Resources::MEDIA_SERVICES_ACCESS_KEY; + } + + /** + * Creates new media services settings instance. + * + * @param string $accountName The user provided account name. + * @param string $accessKey The user provided primary access key + * @param string $endpointUri The service management endpoint uri. + * @param string $oauthEndpointUri The OAuth service endpoint uri. + */ + public function __construct( + $accountName, + $accessKey, + $endpointUri = null, + $oauthEndpointUri = null) + { + Validate::notNullOrEmpty($accountName, 'accountName'); + Validate::notNullOrEmpty($accessKey, 'accountKey'); + Validate::isString($accountName, 'accountName'); + Validate::isString($accessKey, 'accountKey'); + + if ($endpointUri != null) { + Validate::isValidUri($endpointUri); + } else { + $endpointUri = Resources::MEDIA_SERVICES_URL; + } + + if ($oauthEndpointUri != null) { + Validate::isValidUri($oauthEndpointUri); + } else { + $oauthEndpointUri = Resources::MEDIA_SERVICES_OAUTH_URL; + } + + $this->_accountName = $accountName; + $this->_accessKey = $accessKey; + $this->_endpointUri = $endpointUri; + $this->_oauthEndpointUri = $oauthEndpointUri; + } + + /** + * Creates a MediaServicesSettings object from the given connection string. + * + * @param string $connectionString The media services settings connection string. + * + * @return MediaServicesSettings + */ + public static function createFromConnectionString($connectionString) + { + $tokenizedSettings = self::parseAndValidateKeys($connectionString); + + $matchedSpecs = self::matchedSpecification( + $tokenizedSettings, + self::allRequired( + self::$_accountNameSetting, + self::$_accessKeySetting + ), + self::optional( + self::$_endpointUriSetting, + self::$_oauthEndpointUriSetting + ) + ); + if ($matchedSpecs) { + $endpointUri = Utilities::tryGetValueInsensitive( + Resources::MEDIA_SERVICES_ENDPOINT_URI_NAME, + $tokenizedSettings, + Resources::MEDIA_SERVICES_URL + ); + + $oauthEndpointUri = Utilities::tryGetValueInsensitive( + Resources::MEDIA_SERVICES_OAUTH_ENDPOINT_URI_NAME, + $tokenizedSettings, + Resources::MEDIA_SERVICES_OAUTH_URL + ); + + $accountName = Utilities::tryGetValueInsensitive( + Resources::MEDIA_SERVICES_ACCOUNT_NAME, + $tokenizedSettings + ); + + $accessKey = Utilities::tryGetValueInsensitive( + Resources::MEDIA_SERVICES_ACCESS_KEY, + $tokenizedSettings + ); + + return new MediaServicesSettings( + $accountName, + $accessKey, + $endpointUri, + $oauthEndpointUri + ); + } + + self::noMatch($connectionString); + } + + /** + * Gets media services account name. + * + * @return string + */ + public function getAccountName() + { + return $this->_accountName; + } + + /** + * Gets media services access key. + * + * @return string + */ + public function getAccessKey() + { + return $this->_accessKey; + } + + /** + * Gets media services endpoint uri. + * + * @return string + */ + public function getEndpointUri() + { + return $this->_endpointUri; + } + + /** + * Gets media services OAuth endpoint uri. + * + * @return string + */ + public function getOAuthEndpointUri() + { + return $this->_oauthEndpointUri; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/OAuthRestProxy.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/OAuthRestProxy.php new file mode 100644 index 0000000..bbd4eaf --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/OAuthRestProxy.php @@ -0,0 +1,118 @@ + + * @copyright Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Internal; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\ServiceRestProxy; +use WindowsAzure\Common\Models\OAuthAccessToken; +use WindowsAzure\Common\Internal\Serialization\JsonSerializer; + +/** + * OAuth rest proxy. + * + * @category Microsoft + * @package WindowsAzure\Common\Internal + * @author Azure PHP SDK + * @copyright Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class OAuthRestProxy extends ServiceRestProxy +{ + /** + * Initializes new OAuthRestProxy object. + * + * @param IHttpClient $channel The HTTP client used to send HTTP requests. + * @param string $uri The storage account uri. + */ + public function __construct($channel, $uri) + { + parent::__construct( + $channel, + $uri, + Resources::EMPTY_STRING, + new JsonSerializer() + ); + } + + + /** + * Get OAuth access token. + * + * @param string $grantType OAuth request grant_type field value. + * @param string $clientId OAuth request clent_id field value. + * @param string $clientSecret OAuth request clent_secret field value. + * @param string $scope OAuth request scope field value. + * + * @return WindowsAzure\Common\Internal\Models\OAuthAccessToken + */ + public function getAccessToken($grantType, $clientId, $clientSecret, $scope) + { + $method = Resources::HTTP_POST; + $headers = array(); + $queryParams = array(); + $postParameters = array(); + $statusCode = Resources::STATUS_OK; + + $postParameters = $this->addPostParameter( + $postParameters, + Resources::OAUTH_GRANT_TYPE, + $grantType + ); + + $postParameters = $this->addPostParameter( + $postParameters, + Resources::OAUTH_CLIENT_ID, + $clientId + ); + + $postParameters = $this->addPostParameter( + $postParameters, + Resources::OAUTH_CLIENT_SECRET, + $clientSecret + ); + + $postParameters = $this->addPostParameter( + $postParameters, + Resources::OAUTH_SCOPE, + $scope + ); + + $response = $this->send( + $method, + $headers, + $queryParams, + $postParameters, + Resources::EMPTY_STRING, + $statusCode + ); + + return OAuthAccessToken::create( + $this->dataSerializer->unserialize($response->getBody()) + ); + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Resources.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Resources.php new file mode 100644 index 0000000..2479da9 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Resources.php @@ -0,0 +1,454 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Internal; + +/** + * Project resources. + * + * @category Microsoft + * @package WindowsAzure\Common\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class Resources +{ + // @codingStandardsIgnoreStart + + // Connection strings + const USE_DEVELOPMENT_STORAGE_NAME = 'UseDevelopmentStorage'; + const DEVELOPMENT_STORAGE_PROXY_URI_NAME = 'DevelopmentStorageProxyUri'; + const DEFAULT_ENDPOINTS_PROTOCOL_NAME = 'DefaultEndpointsProtocol'; + const ACCOUNT_NAME_NAME = 'AccountName'; + const ACCOUNT_KEY_NAME = 'AccountKey'; + const BLOB_ENDPOINT_NAME = 'BlobEndpoint'; + const QUEUE_ENDPOINT_NAME = 'QueueEndpoint'; + const TABLE_ENDPOINT_NAME = 'TableEndpoint'; + const SHARED_ACCESS_SIGNATURE_NAME = 'SharedAccessSignature'; + const DEV_STORE_NAME = 'devstoreaccount1'; + const DEV_STORE_KEY = 'Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw=='; + const BLOB_BASE_DNS_NAME = 'blob.core.windows.net'; + const QUEUE_BASE_DNS_NAME = 'queue.core.windows.net'; + const TABLE_BASE_DNS_NAME = 'table.core.windows.net'; + const DEV_STORE_CONNECTION_STRING = 'BlobEndpoint=127.0.0.1:10000;QueueEndpoint=127.0.0.1:10001;TableEndpoint=127.0.0.1:10002;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw=='; + const SUBSCRIPTION_ID_NAME = 'SubscriptionID'; + const CERTIFICATE_PATH_NAME = 'CertificatePath'; + const SERVICE_MANAGEMENT_ENDPOINT_NAME = 'ServiceManagementEndpoint'; + const SERVICE_BUS_ENDPOINT_NAME = 'Endpoint'; + const SHARED_SECRET_ISSUER_NAME = 'SharedSecretIssuer'; + const SHARED_SECRET_VALUE_NAME = 'SharedSecretValue'; + const STS_ENDPOINT_NAME = 'StsEndpoint'; + const MEDIA_SERVICES_ENDPOINT_URI_NAME = 'MediaServicesEndpoint'; + const MEDIA_SERVICES_ACCOUNT_NAME = 'AccountName'; + const MEDIA_SERVICES_ACCESS_KEY = 'AccessKey'; + const MEDIA_SERVICES_OAUTH_ENDPOINT_URI_NAME = 'OAuthEndpoint'; + + // Messages + const INVALID_TYPE_MSG = 'The provided variable should be of type: '; + const INVALID_META_MSG = 'Metadata cannot contain newline characters.'; + const AZURE_ERROR_MSG = "Fail:\nCode: %s\nValue: %s\ndetails (if any): %s."; + const NOT_IMPLEMENTED_MSG = 'This method is not implemented.'; + const NULL_OR_EMPTY_MSG = "'%s' can't be NULL or empty."; + const NULL_MSG = "'%s' can't be NULL."; + const INVALID_URL_MSG = 'Provided URL is invalid.'; + const INVALID_HT_MSG = 'The header type provided is invalid.'; + const INVALID_EDM_MSG = 'The provided EDM type is invalid.'; + const INVALID_PROP_MSG = 'One of the provided properties is not an instance of class Property'; + const INVALID_ENTITY_MSG = 'The provided entity object is invalid.'; + const INVALID_VERSION_MSG = 'Server does not support any known protocol versions.'; + const INVALID_BO_TYPE_MSG = 'Batch operation name is not supported or invalid.'; + const INVALID_BO_PN_MSG = 'Batch operation parameter is not supported.'; + const INVALID_OC_COUNT_MSG = 'Operations and contexts must be of same size.'; + const INVALID_EXC_OBJ_MSG = 'Exception object type should be ServiceException.'; + const NULL_TABLE_KEY_MSG = 'Partition and row keys can\'t be NULL.'; + const BATCH_ENTITY_DEL_MSG = 'The entity was deleted successfully.'; + const INVALID_PROP_VAL_MSG = "'%s' property value must satisfy %s."; + const INVALID_PARAM_MSG = "The provided variable '%s' should be of type '%s'"; + const INVALID_BTE_MSG = "The blob block type must exist in %s"; + const INVALID_BLOB_PAT_MSG = 'The provided access type is invalid.'; + const INVALID_SVC_PROP_MSG = 'The provided service properties is invalid.'; + const UNKNOWN_SRILZER_MSG = 'The provided serializer type is unknown'; + const INVALID_CREATE_SERVICE_OPTIONS_MSG = 'Must provide valid location or affinity group.'; + const INVALID_UPDATE_SERVICE_OPTIONS_MSG = 'Must provide either description or label.'; + const INVALID_CONFIG_MSG = 'Config object must be of type Configuration'; + const INVALID_ACH_MSG = 'The provided access condition header is invalid'; + const INVALID_RECEIVE_MODE_MSG = 'The receive message option is in neither RECEIVE_AND_DELETE nor PEEK_LOCK mode.'; + const INVALID_CONFIG_URI = "The provided URI '%s' is invalid. It has to pass the check 'filter_var(, FILTER_VALIDATE_URL)'."; + const INVALID_CONFIG_VALUE = "The provided config value '%s' does not belong to the valid values subset:\n%s"; + const INVALID_ACCOUNT_KEY_FORMAT = "The provided account key '%s' is not a valid base64 string. It has to pass the check 'base64_decode(, true)'."; + const MISSING_CONNECTION_STRING_SETTINGS = "The provided connection string '%s' does not have complete configuration settings."; + const INVALID_CONNECTION_STRING_SETTING_KEY = "The setting key '%s' is not found in the expected configuration setting keys:\n%s"; + const INVALID_CERTIFICATE_PATH = "The provided certificate path '%s' is invalid."; + const INSTANCE_TYPE_VALIDATION_MSG = 'The type of %s is %s but is expected to be %s.'; + const MISSING_CONNECTION_STRING_CHAR = "Missing %s character"; + const ERROR_PARSING_STRING = "'%s' at position %d."; + const INVALID_CONNECTION_STRING = "Argument '%s' is not a valid connection string: '%s'"; + const ERROR_CONNECTION_STRING_MISSING_KEY = 'Missing key name'; + const ERROR_CONNECTION_STRING_EMPTY_KEY = 'Empty key name'; + const ERROR_CONNECTION_STRING_MISSING_CHARACTER = "Missing %s character"; + const ERROR_EMPTY_SETTINGS = 'No keys were found in the connection string'; + const MISSING_LOCK_LOCATION_MSG = 'The lock location of the brokered message is missing.'; + const INVALID_SLOT = "The provided deployment slot '%s' is not valid. Only 'staging' and 'production' are accepted."; + const INVALID_DEPLOYMENT_LOCATOR_MSG = 'A slot or deployment name must be provided.'; + const INVALID_CHANGE_MODE_MSG = "The change mode must be 'Auto' or 'Manual'. Use Mode class constants for that purpose."; + const INVALID_DEPLOYMENT_STATUS_MSG = "The change mode must be 'Running' or 'Suspended'. Use DeploymentStatus class constants for that purpose."; + const ERROR_OAUTH_GET_ACCESS_TOKEN = 'Unable to get oauth access token for endpoint \'%s\', account name \'%s\''; + const ERROR_OAUTH_SERVICE_MISSING = 'OAuth service missing for account name \'%s\''; + const ERROR_METHOD_NOT_FOUND = 'Method \'%s\' not found in object class \'%s\''; + const ERROR_INVALID_DATE_STRING = 'Parameter \'%s\' is not a date formatted string \'%s\''; + + // HTTP Headers + const X_MS_HEADER_PREFIX = 'x-ms-'; + const X_MS_META_HEADER_PREFIX = 'x-ms-meta-'; + const X_MS_APPROXIMATE_MESSAGES_COUNT = 'x-ms-approximate-messages-count'; + const X_MS_POPRECEIPT = 'x-ms-popreceipt'; + const X_MS_TIME_NEXT_VISIBLE = 'x-ms-time-next-visible'; + const X_MS_BLOB_PUBLIC_ACCESS = 'x-ms-blob-public-access'; + const X_MS_VERSION = 'x-ms-version'; + const X_MS_DATE = 'x-ms-date'; + const X_MS_BLOB_SEQUENCE_NUMBER = 'x-ms-blob-sequence-number'; + const X_MS_BLOB_SEQUENCE_NUMBER_ACTION = 'x-ms-sequence-number-action'; + const X_MS_BLOB_TYPE = 'x-ms-blob-type'; + const X_MS_BLOB_CONTENT_TYPE = 'x-ms-blob-content-type'; + const X_MS_BLOB_CONTENT_ENCODING = 'x-ms-blob-content-encoding'; + const X_MS_BLOB_CONTENT_LANGUAGE = 'x-ms-blob-content-language'; + const X_MS_BLOB_CONTENT_MD5 = 'x-ms-blob-content-md5'; + const X_MS_BLOB_CACHE_CONTROL = 'x-ms-blob-cache-control'; + const X_MS_BLOB_CONTENT_LENGTH = 'x-ms-blob-content-length'; + const X_MS_COPY_SOURCE = 'x-ms-copy-source'; + const X_MS_RANGE = 'x-ms-range'; + const X_MS_RANGE_GET_CONTENT_MD5 = 'x-ms-range-get-content-md5'; + const X_MS_LEASE_ID = 'x-ms-lease-id'; + const X_MS_LEASE_TIME = 'x-ms-lease-time'; + const X_MS_LEASE_STATUS = 'x-ms-lease-status'; + const X_MS_LEASE_ACTION = 'x-ms-lease-action'; + const X_MS_DELETE_SNAPSHOTS = 'x-ms-delete-snapshots'; + const X_MS_PAGE_WRITE = 'x-ms-page-write'; + const X_MS_SNAPSHOT = 'x-ms-snapshot'; + const X_MS_SOURCE_IF_MODIFIED_SINCE = 'x-ms-source-if-modified-since'; + const X_MS_SOURCE_IF_UNMODIFIED_SINCE = 'x-ms-source-if-unmodified-since'; + const X_MS_SOURCE_IF_MATCH = 'x-ms-source-if-match'; + const X_MS_SOURCE_IF_NONE_MATCH = 'x-ms-source-if-none-match'; + const X_MS_SOURCE_LEASE_ID = 'x-ms-source-lease-id'; + const X_MS_CONTINUATION_NEXTTABLENAME = 'x-ms-continuation-nexttablename'; + const X_MS_CONTINUATION_NEXTPARTITIONKEY = 'x-ms-continuation-nextpartitionkey'; + const X_MS_CONTINUATION_NEXTROWKEY = 'x-ms-continuation-nextrowkey'; + const X_MS_REQUEST_ID = 'x-ms-request-id'; + const ETAG = 'etag'; + const LAST_MODIFIED = 'last-modified'; + const DATE = 'date'; + const AUTHENTICATION = 'authorization'; + const WRAP_AUTHORIZATION = 'WRAP access_token="%s"'; + const CONTENT_ENCODING = 'content-encoding'; + const CONTENT_LANGUAGE = 'content-language'; + const CONTENT_LENGTH = 'content-length'; + const CONTENT_LENGTH_NO_SPACE = 'contentlength'; + const CONTENT_MD5 = 'content-md5'; + const CONTENT_TYPE = 'content-type'; + const CONTENT_ID = 'content-id'; + const CONTENT_RANGE = 'content-range'; + const CACHE_CONTROL = 'cache-control'; + const IF_MODIFIED_SINCE = 'if-modified-since'; + const IF_MATCH = 'if-match'; + const IF_NONE_MATCH = 'if-none-match'; + const IF_UNMODIFIED_SINCE = 'if-unmodified-since'; + const RANGE = 'range'; + const DATA_SERVICE_VERSION = 'dataserviceversion'; + const MAX_DATA_SERVICE_VERSION = 'maxdataserviceversion'; + const ACCEPT_HEADER = 'accept'; + const ACCEPT_CHARSET = 'accept-charset'; + const USER_AGENT = 'User-Agent'; + + // Type + const QUEUE_TYPE_NAME = 'IQueue'; + const BLOB_TYPE_NAME = 'IBlob'; + const TABLE_TYPE_NAME = 'ITable'; + const SERVICE_MANAGEMENT_TYPE_NAME = 'IServiceManagement'; + const SERVICE_BUS_TYPE_NAME = 'IServiceBus'; + const WRAP_TYPE_NAME = 'IWrap'; + + // WRAP + const WRAP_ACCESS_TOKEN = 'wrap_access_token'; + const WRAP_ACCESS_TOKEN_EXPIRES_IN = 'wrap_access_token_expires_in'; + const WRAP_NAME = 'wrap_name'; + const WRAP_PASSWORD = 'wrap_password'; + const WRAP_SCOPE = 'wrap_scope'; + + // OAuth + const OAUTH_GRANT_TYPE = 'grant_type'; + const OAUTH_CLIENT_ID = 'client_id'; + const OAUTH_CLIENT_SECRET = 'client_secret'; + const OAUTH_SCOPE = 'scope'; + const OAUTH_GT_CLIENT_CREDENTIALS = 'client_credentials'; + const OAUTH_ACCESS_TOKEN = 'access_token'; + const OAUTH_EXPIRES_IN = 'expires_in'; + const OAUTH_ACCESS_TOKEN_PREFIX = 'Bearer '; + + // HTTP Methods + const HTTP_GET = 'GET'; + const HTTP_PUT = 'PUT'; + const HTTP_POST = 'POST'; + const HTTP_HEAD = 'HEAD'; + const HTTP_DELETE = 'DELETE'; + const HTTP_MERGE = 'MERGE'; + + // Misc + const EMPTY_STRING = ''; + const SEPARATOR = ','; + const AZURE_DATE_FORMAT = 'D, d M Y H:i:s T'; + const TIMESTAMP_FORMAT = 'Y-m-d H:i:s'; + const EMULATED = 'EMULATED'; + const EMULATOR_BLOB_URI = '127.0.0.1:10000'; + const EMULATOR_QUEUE_URI = '127.0.0.1:10001'; + const EMULATOR_TABLE_URI = '127.0.0.1:10002'; + const ASTERISK = '*'; + const SERVICE_MANAGEMENT_URL = 'https://management.core.windows.net'; + const HTTP_SCHEME = 'http'; + const HTTPS_SCHEME = 'https'; + const SETTING_NAME = 'SettingName'; + const SETTING_CONSTRAINT = 'SettingConstraint'; + const DEV_STORE_URI = 'http://127.0.0.1'; + const SERVICE_URI_FORMAT = "%s://%s.%s"; + const WRAP_ENDPOINT_URI_FORMAT = "https://%s-sb.accesscontrol.windows.net/WRAPv0.9"; + + // Xml Namespaces + const WA_XML_NAMESPACE = 'http://schemas.microsoft.com/windowsazure'; + const ATOM_XML_NAMESPACE = 'http://www.w3.org/2005/Atom'; + const DS_XML_NAMESPACE = 'http://schemas.microsoft.com/ado/2007/08/dataservices'; + const DSM_XML_NAMESPACE = 'http://schemas.microsoft.com/ado/2007/08/dataservices/metadata'; + const XSI_XML_NAMESPACE = 'http://www.w3.org/2001/XMLSchema-instance'; + + + // Header values + const SDK_USER_AGENT = 'Azure-SDK-For-PHP/0.4.0'; + const STORAGE_API_LATEST_VERSION = '2011-08-18'; + const SM_API_LATEST_VERSION = '2011-10-01'; + const DATA_SERVICE_VERSION_VALUE = '1.0;NetFx'; + const MAX_DATA_SERVICE_VERSION_VALUE = '2.0;NetFx'; + const ACCEPT_HEADER_VALUE = 'application/atom+xml,application/xml'; + const ATOM_ENTRY_CONTENT_TYPE = 'application/atom+xml;type=entry;charset=utf-8'; + const ATOM_FEED_CONTENT_TYPE = 'application/atom+xml;type=feed;charset=utf-8'; + const ACCEPT_CHARSET_VALUE = 'utf-8'; + const INT32_MAX = 2147483647; + const MEDIA_SERVICES_API_LATEST_VERSION = '2.2'; + const MEDIA_SERVICES_DATA_SERVICE_VERSION_VALUE = '3.0;NetFx'; + const MEDIA_SERVICES_MAX_DATA_SERVICE_VERSION_VALUE = '3.0;NetFx'; + + // Query parameter names + const QP_PREFIX = 'Prefix'; + const QP_MAX_RESULTS = 'MaxResults'; + const QP_METADATA = 'Metadata'; + const QP_MARKER = 'Marker'; + const QP_NEXT_MARKER = 'NextMarker'; + const QP_COMP = 'comp'; + const QP_VISIBILITY_TIMEOUT = 'visibilitytimeout'; + const QP_POPRECEIPT = 'popreceipt'; + const QP_NUM_OF_MESSAGES = 'numofmessages'; + const QP_PEEK_ONLY = 'peekonly'; + const QP_MESSAGE_TTL = 'messagettl'; + const QP_INCLUDE = 'include'; + const QP_TIMEOUT = 'timeout'; + const QP_DELIMITER = 'Delimiter'; + const QP_REST_TYPE = 'restype'; + const QP_SNAPSHOT = 'snapshot'; + const QP_BLOCKID = 'blockid'; + const QP_BLOCK_LIST_TYPE = 'blocklisttype'; + const QP_SELECT = '$select'; + const QP_TOP = '$top'; + const QP_SKIP = '$skip'; + const QP_FILTER = '$filter'; + const QP_NEXT_TABLE_NAME = 'NextTableName'; + const QP_NEXT_PK = 'NextPartitionKey'; + const QP_NEXT_RK = 'NextRowKey'; + const QP_ACTION = 'action'; + const QP_EMBED_DETAIL = 'embed-detail'; + + // Query parameter values + const QPV_REGENERATE = 'regenerate'; + const QPV_CONFIG = 'config'; + const QPV_STATUS = 'status'; + const QPV_UPGRADE = 'upgrade'; + const QPV_WALK_UPGRADE_DOMAIN = 'walkupgradedomain'; + const QPV_REBOOT = 'reboot'; + const QPV_REIMAGE = 'reimage'; + const QPV_ROLLBACK = 'rollback'; + + // Request body content types + const URL_ENCODED_CONTENT_TYPE = 'application/x-www-form-urlencoded'; + const XML_CONTENT_TYPE = 'application/xml'; + const BINARY_FILE_TYPE = 'application/octet-stream'; + const XML_ATOM_CONTENT_TYPE = 'application/atom+xml'; + const HTTP_TYPE = 'application/http'; + const MULTIPART_MIXED_TYPE = 'multipart/mixed'; + + // Common used XML tags + const XTAG_ATTRIBUTES = '@attributes'; + const XTAG_NAMESPACE = '@namespace'; + const XTAG_LABEL = 'Label'; + const XTAG_NAME = 'Name'; + const XTAG_DESCRIPTION = 'Description'; + const XTAG_LOCATION = 'Location'; + const XTAG_AFFINITY_GROUP = 'AffinityGroup'; + const XTAG_HOSTED_SERVICES = 'HostedServices'; + const XTAG_STORAGE_SERVICES = 'StorageServices'; + const XTAG_STORAGE_SERVICE = 'StorageService'; + const XTAG_DISPLAY_NAME = 'DisplayName'; + const XTAG_SERVICE_NAME = 'ServiceName'; + const XTAG_URL = 'Url'; + const XTAG_ID = 'ID'; + const XTAG_STATUS = 'Status'; + const XTAG_HTTP_STATUS_CODE = 'HttpStatusCode'; + const XTAG_CODE = 'Code'; + const XTAG_MESSAGE = 'Message'; + const XTAG_STORAGE_SERVICE_PROPERTIES = 'StorageServiceProperties'; + const XTAG_ENDPOINT = 'Endpoint'; + const XTAG_ENDPOINTS = 'Endpoints'; + const XTAG_PRIMARY = 'Primary'; + const XTAG_SECONDARY = 'Secondary'; + const XTAG_KEY_TYPE = 'KeyType'; + const XTAG_STORAGE_SERVICE_KEYS = 'StorageServiceKeys'; + const XTAG_ERROR = 'Error'; + const XTAG_HOSTED_SERVICE = 'HostedService'; + const XTAG_HOSTED_SERVICE_PROPERTIES = 'HostedServiceProperties'; + const XTAG_CREATE_HOSTED_SERVICE = 'CreateHostedService'; + const XTAG_CREATE_STORAGE_SERVICE_INPUT = 'CreateStorageServiceInput'; + const XTAG_UPDATE_STORAGE_SERVICE_INPUT = 'UpdateStorageServiceInput'; + const XTAG_CREATE_AFFINITY_GROUP = 'CreateAffinityGroup'; + const XTAG_UPDATE_AFFINITY_GROUP = 'UpdateAffinityGroup'; + const XTAG_UPDATE_HOSTED_SERVICE = 'UpdateHostedService'; + const XTAG_PACKAGE_URL = 'PackageUrl'; + const XTAG_CONFIGURATION = 'Configuration'; + const XTAG_START_DEPLOYMENT = 'StartDeployment'; + const XTAG_TREAT_WARNINGS_AS_ERROR = 'TreatWarningsAsError'; + const XTAG_CREATE_DEPLOYMENT = 'CreateDeployment'; + const XTAG_DEPLOYMENT_SLOT = 'DeploymentSlot'; + const XTAG_PRIVATE_ID = 'PrivateID'; + const XTAG_ROLE_INSTANCE_LIST = 'RoleInstanceList'; + const XTAG_UPGRADE_DOMAIN_COUNT = 'UpgradeDomainCount'; + const XTAG_ROLE_LIST = 'RoleList'; + const XTAG_SDK_VERSION = 'SdkVersion'; + const XTAG_INPUT_ENDPOINT_LIST = 'InputEndpointList'; + const XTAG_LOCKED = 'Locked'; + const XTAG_ROLLBACK_ALLOWED = 'RollbackAllowed'; + const XTAG_UPGRADE_STATUS = 'UpgradeStatus'; + const XTAG_UPGRADE_TYPE = 'UpgradeType'; + const XTAG_CURRENT_UPGRADE_DOMAIN_STATE = 'CurrentUpgradeDomainState'; + const XTAG_CURRENT_UPGRADE_DOMAIN = 'CurrentUpgradeDomain'; + const XTAG_ROLE_NAME = 'RoleName'; + const XTAG_INSTANCE_NAME = 'InstanceName'; + const XTAG_INSTANCE_STATUS = 'InstanceStatus'; + const XTAG_INSTANCE_UPGRADE_DOMAIN = 'InstanceUpgradeDomain'; + const XTAG_INSTANCE_FAULT_DOMAIN = 'InstanceFaultDomain'; + const XTAG_INSTANCE_SIZE = 'InstanceSize'; + const XTAG_INSTANCE_STATE_DETAILS = 'InstanceStateDetails'; + const XTAG_INSTANCE_ERROR_CODE = 'InstanceErrorCode'; + const XTAG_OS_VERSION = 'OsVersion'; + const XTAG_ROLE_INSTANCE = 'RoleInstance'; + const XTAG_ROLE = 'Role'; + const XTAG_INPUT_ENDPOINT = 'InputEndpoint'; + const XTAG_VIP = 'Vip'; + const XTAG_PORT = 'Port'; + const XTAG_DEPLOYMENT = 'Deployment'; + const XTAG_DEPLOYMENTS = 'Deployments'; + const XTAG_REGENERATE_KEYS = 'RegenerateKeys'; + const XTAG_SWAP = 'Swap'; + const XTAG_PRODUCTION = 'Production'; + const XTAG_SOURCE_DEPLOYMENT = 'SourceDeployment'; + const XTAG_CHANGE_CONFIGURATION = 'ChangeConfiguration'; + const XTAG_MODE = 'Mode'; + const XTAG_UPDATE_DEPLOYMENT_STATUS = 'UpdateDeploymentStatus'; + const XTAG_ROLE_TO_UPGRADE = 'RoleToUpgrade'; + const XTAG_FORCE = 'Force'; + const XTAG_UPGRADE_DEPLOYMENT = 'UpgradeDeployment'; + const XTAG_UPGRADE_DOMAIN = 'UpgradeDomain'; + const XTAG_WALK_UPGRADE_DOMAIN = 'WalkUpgradeDomain'; + const XTAG_ROLLBACK_UPDATE_OR_UPGRADE = 'RollbackUpdateOrUpgrade'; + const XTAG_CONTAINER_NAME = 'ContainerName'; + const XTAG_ACCOUNT_NAME = 'AccountName'; + + // Service Bus + const LIST_TOPICS_PATH = '$Resources/Topics'; + const LIST_QUEUES_PATH = '$Resources/Queues'; + const LIST_RULES_PATH = '%s/subscriptions/%s/rules'; + const LIST_SUBSCRIPTIONS_PATH = '%s/subscriptions'; + const RECEIVE_MESSAGE_PATH = '%s/messages/head'; + const RECEIVE_SUBSCRIPTION_MESSAGE_PATH = '%s/subscriptions/%s/messages/head'; + const SEND_MESSAGE_PATH = '%s/messages'; + const RULE_PATH = '%s/subscriptions/%s/rules/%s'; + const SUBSCRIPTION_PATH = '%s/subscriptions/%s'; + const DEFAULT_RULE_NAME = '$Default'; + const UNIQUE_ID_PREFIX = 'urn:uuid:'; + const SERVICE_BUS_NAMESPACE = 'http://schemas.microsoft.com/netservices/2010/10/servicebus/connect'; + const BROKER_PROPERTIES = 'BrokerProperties'; + const XMLNS_ATOM = 'xmlns:atom'; + const XMLNS = 'xmlns'; + const ATOM_NAMESPACE = 'http://www.w3.org/2005/Atom'; + + // ATOM string + const AUTHOR = 'author'; + const CATEGORY = 'category'; + const CONTRIBUTOR = 'contributor'; + const ENTRY = 'entry'; + const LINK = 'link'; + const PROPERTIES = 'properties'; + const ELEMENT = 'element'; + + // PHP URL Keys + const PHP_URL_SCHEME = 'scheme'; + const PHP_URL_HOST = 'host'; + const PHP_URL_PORT = 'port'; + const PHP_URL_USER = 'user'; + const PHP_URL_PASS = 'pass'; + const PHP_URL_PATH = 'path'; + const PHP_URL_QUERY = 'query'; + const PHP_URL_FRAGMENT = 'fragment'; + + // Status Codes + const STATUS_OK = 200; + const STATUS_CREATED = 201; + const STATUS_ACCEPTED = 202; + const STATUS_NO_CONTENT = 204; + const STATUS_PARTIAL_CONTENT = 206; + const STATUS_MOVED_PERMANENTLY = 301; + + // HTTP_Request2 config parameter names + const USE_BRACKETS = 'use_brackets'; + const SSL_VERIFY_PEER = 'ssl_verify_peer'; + const SSL_VERIFY_HOST = 'ssl_verify_host'; + const SSL_LOCAL_CERT = 'ssl_local_cert'; + const SSL_CAFILE = 'ssl_cafile'; + const CONNECT_TIMEOUT = 'connect_timeout'; + + // Media services + const MEDIA_SERVICES_URL = 'https://media.windows.net/API/'; + const MEDIA_SERVICES_OAUTH_URL = 'https://wamsprodglobal001acs.accesscontrol.windows.net/v2/OAuth2-13'; + const MEDIA_SERVICES_OAUTH_SCOPE = 'urn:WindowsAzureMediaServices'; + const MEDIA_SERVICES_INPUT_ASSETS_REL = 'http://schemas.microsoft.com/ado/2007/08/dataservices/related/InputMediaAssets'; + + + // @codingStandardsIgnoreEnd +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/RestProxy.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/RestProxy.php new file mode 100644 index 0000000..8991cc4 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/RestProxy.php @@ -0,0 +1,207 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Internal; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Validate; +use WindowsAzure\Common\Internal\Http\Url; + +/** + * Base class for all REST proxies. + * + * @category Microsoft + * @package WindowsAzure\Common\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class RestProxy +{ + /** + * @var WindowsAzure\Common\Internal\Http\IHttpClient + */ + private $_channel; + + /** + * @var array + */ + private $_filters; + + /** + * @var WindowsAzure\Common\Internal\Serialization\ISerializer + */ + protected $dataSerializer; + + /** + * @var string + */ + private $_uri; + + /** + * Initializes new RestProxy object. + * + * @param IHttpClient $channel The HTTP client used to send HTTP requests. + * @param ISerializer $dataSerializer The data serializer. + * @param string $uri The uri of the service. + */ + public function __construct($channel, $dataSerializer, $uri) + { + $this->_channel = $channel; + $this->_filters = array(); + $this->dataSerializer = $dataSerializer; + $this->_uri = $uri; + } + + /** + * Gets HTTP filters that will process each request. + * + * @return array + */ + public function getFilters() + { + return $this->_filters; + } + + /** + * Gets the Uri of the service. + * + * @return string + */ + public function getUri() + { + return $this->_uri; + } + + /** + * Sets the Uri of the service. + * + * @param string $uri The URI of the request. + * + * @return none + */ + public function setUri($uri) + { + $this->_uri = $uri; + } + + /** + * Sends HTTP request with the specified HTTP call context. + * + * @param WindowsAzure\Common\Internal\Http\HttpCallContext $context The HTTP + * call context. + * + * @return \HTTP_Request2_Response + */ + protected function sendContext($context) + { + $channel = clone $this->_channel; + $contextUrl = $context->getUri(); + $url = new Url(empty($contextUrl) ? $this->_uri : $contextUrl); + $headers = $context->getHeaders(); + $statusCodes = $context->getStatusCodes(); + $body = $context->getBody(); + $queryParams = $context->getQueryParameters(); + $postParameters = $context->getPostParameters(); + $path = $context->getPath(); + + $channel->setMethod($context->getMethod()); + $channel->setExpectedStatusCode($statusCodes); + $channel->setBody($body); + $channel->setHeaders($headers); + + if (count($postParameters) > 0) { + $channel->setPostParameters($postParameters); + } + $url->setQueryVariables($queryParams); + $url->appendUrlPath($path); + + $channel->send($this->_filters, $url); + + return $channel->getResponse(); + } + + /** + * Adds new filter to new service rest proxy object and returns that object back. + * + * @param WindowsAzure\Common\Internal\IServiceFilter $filter Filter to add for + * the pipeline. + * + * @return RestProxy. + */ + public function withFilter($filter) + { + $serviceProxyWithFilter = clone $this; + $serviceProxyWithFilter->_filters[] = $filter; + + return $serviceProxyWithFilter; + } + + /** + * Adds optional query parameter. + * + * Doesn't add the value if it satisfies empty(). + * + * @param array &$queryParameters The query parameters. + * @param string $key The query variable name. + * @param string $value The query variable value. + * + * @return none + */ + protected function addOptionalQueryParam(&$queryParameters, $key, $value) + { + Validate::isArray($queryParameters, 'queryParameters'); + Validate::isString($key, 'key'); + Validate::isString($value, 'value'); + + if (!is_null($value) && Resources::EMPTY_STRING !== $value) { + $queryParameters[$key] = $value; + } + } + + /** + * Adds optional header. + * + * Doesn't add the value if it satisfies empty(). + * + * @param array &$headers The HTTP header parameters. + * @param string $key The HTTP header name. + * @param string $value The HTTP header value. + * + * @return none + */ + protected function addOptionalHeader(&$headers, $key, $value) + { + Validate::isArray($headers, 'headers'); + Validate::isString($key, 'key'); + Validate::isString($value, 'value'); + + if (!is_null($value) && Resources::EMPTY_STRING !== $value) { + $headers[$key] = $value; + } + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Serialization/ISerializer.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Serialization/ISerializer.php new file mode 100644 index 0000000..e3b79d2 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Serialization/ISerializer.php @@ -0,0 +1,73 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Internal\Serialization; + +/** + * The serialization interface. + * + * @category Microsoft + * @package WindowsAzure\Common\Internal\Serialization + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +interface ISerializer +{ + + /** + * Serialize an object into a XML. + * + * @param Object $targetObject The target object to be serialized. + * @param string $rootName The name of the root. + * + * @return string + */ + public static function objectSerialize($targetObject, $rootName); + + /** + * Serializes given array. The array indices must be string to use them as + * as element name. + * + * @param array $array The object to serialize represented in array. + * @param array $properties The used properties in the serialization process. + * + * @return string + */ + public function serialize($array, $properties = null); + + + /** + * Unserializes given serialized string. + * + * @param string $serialized The serialized object in string representation. + * + * @return array + */ + public function unserialize($serialized); +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Serialization/JsonSerializer.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Serialization/JsonSerializer.php new file mode 100644 index 0000000..60a3d85 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Serialization/JsonSerializer.php @@ -0,0 +1,96 @@ + + * @copyright Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Internal\Serialization; +use WindowsAzure\Common\Internal\Validate; +/** + * Perform JSON serialization / deserialization + * + * @category Microsoft + * @package WindowsAzure\Common\Internal\Serialization + * @author Azure PHP SDK + * @copyright Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class JsonSerializer implements ISerializer +{ + /** + * Serialize an object with specified root element name. + * + * @param object $targetObject The target object. + * @param string $rootName The name of the root element. + * + * @return string + */ + public static function objectSerialize($targetObject, $rootName) + { + Validate::notNull($targetObject, 'targetObject'); + Validate::isString($rootName, 'rootName'); + + $contianer = new \stdClass(); + + $contianer->$rootName = $targetObject; + + return json_encode($contianer); + } + + /** + * Serializes given array. The array indices must be string to use them as + * as element name. + * + * @param array $array The object to serialize represented in array. + * @param array $properties The used properties in the serialization process. + * + * @return string + */ + public function serialize($array, $properties = null) + { + Validate::isArray($array, 'array'); + + return json_encode($array); + } + + /** + * Unserializes given serialized string to array. + * + * @param string $serialized The serialized object in string representation. + * + * @return array + */ + public function unserialize($serialized) + { + Validate::isString($serialized, 'serialized'); + + $json = json_decode($serialized); + if ($json && !is_array($json)) { + return get_object_vars($json); + } else { + return $json; + } + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Serialization/XmlSerializer.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Serialization/XmlSerializer.php new file mode 100644 index 0000000..bcb338f --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Serialization/XmlSerializer.php @@ -0,0 +1,245 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Internal\Serialization; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Validate; + +/** + * Short description + * + * @category Microsoft + * @package WindowsAzure\Common\Internal\Serialization + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class XmlSerializer implements ISerializer +{ + const STANDALONE = 'standalone'; + const ROOT_NAME = 'rootName'; + const DEFAULT_TAG = 'defaultTag'; + + /** + * Converts a SimpleXML object to an Array recursively + * ensuring all sub-elements are arrays as well. + * + * @param string $sxml The SimpleXML object. + * @param array $arr The array into which to store results. + * + * @return array + */ + private function _sxml2arr($sxml, $arr = null) + { + foreach ((array) $sxml as $key => $value) { + if (is_object($value) || (is_array($value))) { + $arr[$key] = $this->_sxml2arr($value); + } else { + $arr[$key] = $value; + } + } + + return $arr; + } + + /** + * Takes an array and produces XML based on it. + * + * @param XMLWriter $xmlw XMLWriter object that was previously instanted + * and is used for creating the XML. + * @param array $data Array to be converted to XML. + * @param string $defaultTag Default XML tag to be used if none specified. + * + * @return void + */ + private function _arr2xml(\XMLWriter $xmlw, $data, $defaultTag = null) + { + foreach ($data as $key => $value) { + if ($key === Resources::XTAG_ATTRIBUTES) { + foreach ($value as $attributeName => $attributeValue) { + $xmlw->writeAttribute($attributeName, $attributeValue); + } + } else if (is_array($value)) { + if (!is_int($key)) { + if ($key != Resources::EMPTY_STRING) { + $xmlw->startElement($key); + } else { + $xmlw->startElement($defaultTag); + } + } + + $this->_arr2xml($xmlw, $value); + + if (!is_int($key)) { + $xmlw->endElement(); + } + } else { + $xmlw->writeElement($key, $value); + } + } + } + + /** + * Gets the attributes of a specified object if get attributes + * method is exposed. + * + * @param object $targetObject The target object. + * @param array $methodArray The array of method of the target object. + * + * @return mixed + */ + private static function _getInstanceAttributes($targetObject, $methodArray) + { + foreach ($methodArray as $method) { + if ($method->name == 'getAttributes') { + $classProperty = $method->invoke($targetObject); + return $classProperty; + } + } + return null; + } + + /** + * Serialize an object with specified root element name. + * + * @param object $targetObject The target object. + * @param string $rootName The name of the root element. + * + * @return string + */ + public static function objectSerialize($targetObject, $rootName) + { + Validate::notNull($targetObject, 'targetObject'); + Validate::isString($rootName, 'rootName'); + $xmlWriter = new \XmlWriter(); + $xmlWriter->openMemory(); + $xmlWriter->setIndent(true); + $reflectionClass = new \ReflectionClass($targetObject); + $methodArray = $reflectionClass->getMethods(); + $attributes = self::_getInstanceAttributes( + $targetObject, + $methodArray + ); + + $xmlWriter->startElement($rootName); + if (!is_null($attributes)) { + foreach (array_keys($attributes) as $attributeKey) { + $xmlWriter->writeAttribute( + $attributeKey, + $attributes[$attributeKey] + ); + } + } + + foreach ($methodArray as $method) { + if ((strpos($method->name, 'get') === 0) + && $method->isPublic() + && ($method->name != 'getAttributes') + ) { + $variableName = substr($method->name, 3); + $variableValue = $method->invoke($targetObject); + if (!empty($variableValue)) { + if (gettype($variableValue) === 'object') { + $xmlWriter->writeRaw( + XmlSerializer::objectSerialize( + $variableValue, $variableName + ) + ); + } else { + $xmlWriter->writeElement($variableName, $variableValue); + } + } + } + } + $xmlWriter->endElement(); + return $xmlWriter->outputMemory(true); + } + + /** + * Serializes given array. The array indices must be string to use them as + * as element name. + * + * @param array $array The object to serialize represented in array. + * @param array $properties The used properties in the serialization process. + * + * @return string + */ + public function serialize($array, $properties = null) + { + $xmlVersion = '1.0'; + $xmlEncoding = 'UTF-8'; + $standalone = Utilities::tryGetValue($properties, self::STANDALONE); + $defaultTag = Utilities::tryGetValue($properties, self::DEFAULT_TAG); + $rootName = Utilities::tryGetValue($properties, self::ROOT_NAME); + $docNamespace = Utilities::tryGetValue( + $array, + Resources::XTAG_NAMESPACE, + null + ); + + if (!is_array($array)) { + return false; + } + + $xmlw = new \XmlWriter(); + $xmlw->openMemory(); + $xmlw->setIndent(true); + $xmlw->startDocument($xmlVersion, $xmlEncoding, $standalone); + + if (is_null($docNamespace)) { + $xmlw->startElement($rootName); + } else { + foreach ($docNamespace as $uri => $prefix) { + $xmlw->startElementNS($prefix, $rootName, $uri); + break; + } + } + + unset($array[Resources::XTAG_NAMESPACE]); + self::_arr2xml($xmlw, $array, $defaultTag); + + $xmlw->endElement(); + + return $xmlw->outputMemory(true); + } + + /** + * Unserializes given serialized string. + * + * @param string $serialized The serialized object in string representation. + * + * @return array + */ + public function unserialize($serialized) + { + $sxml = new \SimpleXMLElement($serialized); + + return $this->_sxml2arr($sxml); + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/ServiceBusSettings.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/ServiceBusSettings.php new file mode 100644 index 0000000..c23deb8 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/ServiceBusSettings.php @@ -0,0 +1,267 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Internal; +use WindowsAzure\Common\Internal\Resources; + +/** + * Represents the settings used to sign and access a request against the service + * bus. + * + * @category Microsoft + * @package WindowsAzure\Common\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class ServiceBusSettings extends ServiceSettings +{ + /** + * @var string + */ + private $_serviceBusEndpointUri; + + /** + * @var string + */ + private $_wrapEndpointUri; + + /** + * @var string + */ + private $_wrapName; + + /** + * @var string + */ + private $_wrapPassword; + + /** + * @var string + */ + private $_namespace; + + /** + * Validator for the SharedSecretValue setting. It has to be provided. + * + * @var array + */ + private static $_wrapPasswordSetting; + + /** + * Validator for the SharedSecretIssuer setting. It has to be provided. + * + * @var array + */ + private static $_wrapNameSetting; + + /** + * Validator for the Endpoint setting. Must be a valid Uri. + * + * @var array + */ + private static $_serviceBusEndpointSetting; + + /** + * Validator for the StsEndpoint setting. Must be a valid Uri. + * + * @var array + */ + private static $_wrapEndpointUriSetting; + + /** + * @var boolean + */ + protected static $isInitialized = false; + + /** + * Holds the expected setting keys. + * + * @var array + */ + protected static $validSettingKeys = array(); + + /** + * Initializes static members of the class. + * + * @return none + */ + protected static function init() + { + self::$_serviceBusEndpointSetting = self::settingWithFunc( + Resources::SERVICE_BUS_ENDPOINT_NAME, + Validate::getIsValidUri() + ); + + self::$_wrapNameSetting = self::setting( + Resources::SHARED_SECRET_ISSUER_NAME + ); + + self::$_wrapPasswordSetting = self::setting( + Resources::SHARED_SECRET_VALUE_NAME + ); + + self::$_wrapEndpointUriSetting = self::settingWithFunc( + Resources::STS_ENDPOINT_NAME, + Validate::getIsValidUri() + ); + + self::$validSettingKeys[] = Resources::SERVICE_BUS_ENDPOINT_NAME; + self::$validSettingKeys[] = Resources::SHARED_SECRET_ISSUER_NAME; + self::$validSettingKeys[] = Resources::SHARED_SECRET_VALUE_NAME; + self::$validSettingKeys[] = Resources::STS_ENDPOINT_NAME; + } + + /** + * Creates new Service Bus settings instance. + * + * @param string $serviceBusEndpoint The Service Bus endpoint uri. + * @param string $namespace The service namespace. + * @param string $wrapName The wrap name. + * @param string $wrapPassword The wrap password. + */ + public function __construct( + $serviceBusEndpoint, + $namespace, + $wrapEndpointUri, + $wrapName, + $wrapPassword + ) { + $this->_namespace = $namespace; + $this->_serviceBusEndpointUri = $serviceBusEndpoint; + $this->_wrapEndpointUri = $wrapEndpointUri; + $this->_wrapName = $wrapName; + $this->_wrapPassword = $wrapPassword; + } + + /** + * Creates a ServiceBusSettings object from the given connection string. + * + * @param string $connectionString The storage settings connection string. + * + * @return ServiceBusSettings + */ + public static function createFromConnectionString($connectionString) + { + $tokenizedSettings = self::parseAndValidateKeys($connectionString); + + $matchedSpecs = self::matchedSpecification( + $tokenizedSettings, + self::allRequired( + self::$_serviceBusEndpointSetting, + self::$_wrapNameSetting, + self::$_wrapPasswordSetting + ), + self::optional(self::$_wrapEndpointUriSetting) + ); + + if ($matchedSpecs) { + $endpoint = Utilities::tryGetValueInsensitive( + Resources::SERVICE_BUS_ENDPOINT_NAME, + $tokenizedSettings + ); + + // Parse the namespace part from the URI + $namespace = explode('.', parse_url($endpoint, PHP_URL_HOST)); + $namespace = $namespace[0]; + $wrapEndpointUri = Utilities::tryGetValueInsensitive( + Resources::STS_ENDPOINT_NAME, + $tokenizedSettings, + sprintf(Resources::WRAP_ENDPOINT_URI_FORMAT, $namespace) + ); + $issuerName = Utilities::tryGetValueInsensitive( + Resources::SHARED_SECRET_ISSUER_NAME, + $tokenizedSettings + ); + $issuerValue = Utilities::tryGetValueInsensitive( + Resources::SHARED_SECRET_VALUE_NAME, + $tokenizedSettings + ); + + return new ServiceBusSettings( + $endpoint, + $namespace, + $wrapEndpointUri, + $issuerName, + $issuerValue + ); + } + + self::noMatch($connectionString); + } + + /** + * Gets the Service Bus endpoint URI. + * + * @return string + */ + public function getServiceBusEndpointUri() + { + return $this->_serviceBusEndpointUri; + } + + /** + * Gets the wrap endpoint URI. + * + * @return string + */ + public function getWrapEndpointUri() + { + return $this->_wrapEndpointUri; + } + + /** + * Gets the wrap name. + * + * @return string + */ + public function getWrapName() + { + return $this->_wrapName; + } + + /** + * Gets the wrap password. + * + * @return string + */ + public function getWrapPassword() + { + return $this->_wrapPassword; + } + + /** + * Gets the namespace name. + * + * @return string + */ + public function getNamespace() + { + return $this->_namespace; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/ServiceManagementSettings.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/ServiceManagementSettings.php new file mode 100644 index 0000000..0e6f35b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/ServiceManagementSettings.php @@ -0,0 +1,207 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Internal; +use WindowsAzure\Common\Internal\Resources; + +/** + * Represents the settings used to sign and access a request against the service + * management. For more information about service management connection strings check + * this page: http://msdn.microsoft.com/en-us/library/windowsazure/gg466228.aspx + * + * @category Microsoft + * @package WindowsAzure\Common\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class ServiceManagementSettings extends ServiceSettings +{ + /** + * @var string + */ + private $_subscriptionId; + + /** + * @var string + */ + private $_certificatePath; + + /** + * @var string + */ + private $_endpointUri; + + /** + * Validator for the ServiceManagementEndpoint setting. Must be a valid Uri. + * + * @var array + */ + private static $_endpointSetting; + + /** + * Validator for the CertificatePath setting. It has to be provided. + * + * @var array + */ + private static $_certificatePathSetting; + + /** + * Validator for the SubscriptionId setting. It has to be provided. + * + * @var array + */ + private static $_subscriptionIdSetting; + + /** + * @var boolean + */ + protected static $isInitialized = false; + + /** + * Holds the expected setting keys. + * + * @var array + */ + protected static $validSettingKeys = array(); + + /** + * Initializes static members of the class. + * + * @return none + */ + protected static function init() + { + self::$_endpointSetting = self::settingWithFunc( + Resources::SERVICE_MANAGEMENT_ENDPOINT_NAME, + Validate::getIsValidUri() + ); + + self::$_certificatePathSetting = self::setting( + Resources::CERTIFICATE_PATH_NAME + ); + + self::$_subscriptionIdSetting = self::setting( + Resources::SUBSCRIPTION_ID_NAME + ); + + self::$validSettingKeys[] = Resources::SUBSCRIPTION_ID_NAME; + self::$validSettingKeys[] = Resources::CERTIFICATE_PATH_NAME; + self::$validSettingKeys[] = Resources::SERVICE_MANAGEMENT_ENDPOINT_NAME; + } + + /** + * Creates new service management settings instance. + * + * @param string $subscriptionId The user provided subscription id. + * @param string $endpointUri The service management endpoint uri. + * @param string $certificatePath The management certificate path. + */ + public function __construct($subscriptionId, $endpointUri, $certificatePath) + { + $this->_certificatePath = $certificatePath; + $this->_endpointUri = $endpointUri; + $this->_subscriptionId = $subscriptionId; + } + + /** + * Creates a ServiceManagementSettings object from the given connection string. + * + * @param string $connectionString The storage settings connection string. + * + * @return ServiceManagementSettings + */ + public static function createFromConnectionString($connectionString) + { + $tokenizedSettings = self::parseAndValidateKeys($connectionString); + + $matchedSpecs = self::matchedSpecification( + $tokenizedSettings, + self::allRequired( + self::$_subscriptionIdSetting, + self::$_certificatePathSetting + ), + self::optional( + self::$_endpointSetting + ) + ); + if ($matchedSpecs) { + $endpointUri = Utilities::tryGetValueInsensitive( + Resources::SERVICE_MANAGEMENT_ENDPOINT_NAME, + $tokenizedSettings, + Resources::SERVICE_MANAGEMENT_URL + ); + $subscriptionId = Utilities::tryGetValueInsensitive( + Resources::SUBSCRIPTION_ID_NAME, + $tokenizedSettings + ); + $certificatePath = Utilities::tryGetValueInsensitive( + Resources::CERTIFICATE_PATH_NAME, + $tokenizedSettings + ); + + return new ServiceManagementSettings( + $subscriptionId, + $endpointUri, + $certificatePath + ); + } + + self::noMatch($connectionString); + } + + /** + * Gets service management endpoint uri. + * + * @return string + */ + public function getEndpointUri() + { + return $this->_endpointUri; + } + + /** + * Gets the subscription id. + * + * @return string + */ + public function getSubscriptionId() + { + return $this->_subscriptionId; + } + + /** + * Gets the certificate path. + * + * @return string + */ + public function getCertificatePath() + { + return $this->_certificatePath; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/ServiceRestProxy.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/ServiceRestProxy.php new file mode 100644 index 0000000..f2e73c1 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/ServiceRestProxy.php @@ -0,0 +1,347 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Internal; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Validate; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\RestProxy; +use WindowsAzure\Common\Internal\Http\Url; +use WindowsAzure\Common\Internal\Http\HttpCallContext; + +/** + * Base class for all services rest proxies. + * + * @category Microsoft + * @package WindowsAzure\Common\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class ServiceRestProxy extends RestProxy +{ + /** + * @var string + */ + private $_accountName; + + /** + * Initializes new ServiceRestProxy object. + * + * @param IHttpClient $channel The HTTP client used to send HTTP requests. + * @param string $uri The storage account uri. + * @param string $accountName The name of the account. + * @param ISerializer $dataSerializer The data serializer. + */ + public function __construct($channel, $uri, $accountName, $dataSerializer) + { + parent::__construct($channel, $dataSerializer, $uri); + $this->_accountName = $accountName; + } + + /** + * Gets the account name. + * + * @return string + */ + public function getAccountName() + { + return $this->_accountName; + } + + /** + * Sends HTTP request with the specified HTTP call context. + * + * @param WindowsAzure\Common\Internal\Http\HttpCallContext $context The HTTP + * call context. + * + * @return \HTTP_Request2_Response + */ + protected function sendContext($context) + { + $context->setUri($this->getUri()); + return parent::sendContext($context); + } + + /** + * Sends HTTP request with the specified parameters. + * + * @param string $method HTTP method used in the request + * @param array $headers HTTP headers. + * @param array $queryParams URL query parameters. + * @param array $postParameters The HTTP POST parameters. + * @param string $path URL path + * @param int $statusCode Expected status code received in the response + * @param string $body Request body + * + * @return \HTTP_Request2_Response + */ + protected function send( + $method, + $headers, + $queryParams, + $postParameters, + $path, + $statusCode, + $body = Resources::EMPTY_STRING + ) { + $context = new HttpCallContext(); + $context->setBody($body); + $context->setHeaders($headers); + $context->setMethod($method); + $context->setPath($path); + $context->setQueryParameters($queryParams); + $context->setPostParameters($postParameters); + + if (is_array($statusCode)) { + $context->setStatusCodes($statusCode); + } else { + $context->addStatusCode($statusCode); + } + + return $this->sendContext($context); + } + + + /** + * Adds optional header to headers if set + * + * @param array $headers The array of request headers. + * @param AccessCondition $accessCondition The access condition object. + * + * @return array + */ + public function addOptionalAccessConditionHeader($headers, $accessCondition) + { + if (!is_null($accessCondition)) { + $header = $accessCondition->getHeader(); + + if ($header != Resources::EMPTY_STRING) { + $value = $accessCondition->getValue(); + if ($value instanceof \DateTime) { + $value = gmdate( + Resources::AZURE_DATE_FORMAT, + $value->getTimestamp() + ); + } + $headers[$header] = $value; + } + } + + return $headers; + } + + /** + * Adds optional header to headers if set + * + * @param array $headers The array of request headers. + * @param AccessCondition $accessCondition The access condition object. + * + * @return array + */ + public function addOptionalSourceAccessConditionHeader( + $headers, + $accessCondition + ) { + if (!is_null($accessCondition)) { + $header = $accessCondition->getHeader(); + $headerName = null; + if (!empty($header)) { + switch($header) { + case Resources::IF_MATCH: + $headerName = Resources::X_MS_SOURCE_IF_MATCH; + break; + + case Resources::IF_UNMODIFIED_SINCE: + $headerName = Resources::X_MS_SOURCE_IF_UNMODIFIED_SINCE; + break; + + case Resources::IF_MODIFIED_SINCE: + $headerName = Resources::X_MS_SOURCE_IF_MODIFIED_SINCE; + break; + + case Resources::IF_NONE_MATCH: + $headerName = Resources::X_MS_SOURCE_IF_NONE_MATCH; + break; + + default: + throw new \Exception(Resources::INVALID_ACH_MSG); + break; + } + } + $value = $accessCondition->getValue(); + if ($value instanceof \DateTime) { + $value = gmdate( + Resources::AZURE_DATE_FORMAT, + $value->getTimestamp() + ); + } + + $this->addOptionalHeader($headers, $headerName, $value); + } + + return $headers; + } + + /** + * Adds HTTP POST parameter to the specified + * + * @param array $postParameters An array of HTTP POST parameters. + * @param string $key The key of a HTTP POST parameter. + * @param string $value the value of a HTTP POST parameter. + * + * @return array + */ + public function addPostParameter( + $postParameters, + $key, + $value + ) { + Validate::isArray($postParameters, 'postParameters'); + $postParameters[$key] = $value; + return $postParameters; + } + + /** + * Groups set of values into one value separated with Resources::SEPARATOR + * + * @param array $values array of values to be grouped. + * + * @return string + */ + public function groupQueryValues($values) + { + Validate::isArray($values, 'values'); + $joined = Resources::EMPTY_STRING; + + foreach ($values as $value) { + if (!is_null($value) && !empty($value)) { + $joined .= $value . Resources::SEPARATOR; + } + } + + return trim($joined, Resources::SEPARATOR); + } + + /** + * Adds metadata elements to headers array + * + * @param array $headers HTTP request headers + * @param array $metadata user specified metadata + * + * @return array + */ + protected function addMetadataHeaders($headers, $metadata) + { + $this->validateMetadata($metadata); + + $metadata = $this->generateMetadataHeaders($metadata); + $headers = array_merge($headers, $metadata); + + return $headers; + } + + /** + * Generates metadata headers by prefixing each element with 'x-ms-meta'. + * + * @param array $metadata user defined metadata. + * + * @return array. + */ + public function generateMetadataHeaders($metadata) + { + $metadataHeaders = array(); + + if (is_array($metadata) && !is_null($metadata)) { + foreach ($metadata as $key => $value) { + $headerName = Resources::X_MS_META_HEADER_PREFIX; + if ( strpos($value, "\r") !== false + || strpos($value, "\n") !== false + ) { + throw new \InvalidArgumentException(Resources::INVALID_META_MSG); + } + + $headerName .= strtolower($key); + $metadataHeaders[$headerName] = $value; + } + } + + return $metadataHeaders; + } + + /** + * Gets metadata array by parsing them from given headers. + * + * @param array $headers HTTP headers containing metadata elements. + * + * @return array. + */ + public function getMetadataArray($headers) + { + $metadata = array(); + foreach ($headers as $key => $value) { + $isMetadataHeader = Utilities::startsWith( + strtolower($key), + Resources::X_MS_META_HEADER_PREFIX + ); + + if ($isMetadataHeader) { + $MetadataName = str_replace( + Resources::X_MS_META_HEADER_PREFIX, + Resources::EMPTY_STRING, + strtolower($key) + ); + + $metadata[$MetadataName] = $value; + } + } + + return $metadata; + } + + /** + * Validates the provided metadata array. + * + * @param mix $metadata The metadata array. + * + * @return none + */ + public function validateMetadata($metadata) + { + if (!is_null($metadata)) { + Validate::isArray($metadata, 'metadata'); + } else { + $metadata = array(); + } + + foreach ($metadata as $key => $value) { + Validate::isString($key, 'metadata key'); + Validate::isString($value, 'metadata value'); + } + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/ServiceSettings.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/ServiceSettings.php new file mode 100644 index 0000000..274a0ff --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/ServiceSettings.php @@ -0,0 +1,287 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Internal; +use WindowsAzure\Common\Internal\Resources; + +/** + * Base class for all REST services settings. + * + * Derived classes must implement the following members: + * 1- $isInitialized: A static property that indicates whether the class's static + * members have been initialized. + * 2- init(): A protected static method that initializes static members. + * 3- $validSettingKeys: A static property that contains valid setting keys for this + * service. + * 4- createFromConnectionString($connectionString): A public static function that + * takes a connection string and returns the created settings object. + * + * @category Microsoft + * @package WindowsAzure\Common\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +abstract class ServiceSettings +{ + /** + * Throws an exception if the connection string format does not match any of the + * available formats. + * + * @param type $connectionString The invalid formatted connection string. + * + * @return none + * + * @throws \RuntimeException + */ + protected static function noMatch($connectionString) + { + throw new \RuntimeException( + sprintf(Resources::MISSING_CONNECTION_STRING_SETTINGS, $connectionString) + ); + } + + /** + * Parses the connection string and then validate that the parsed keys belong to + * the $validSettingKeys + * + * @param string $connectionString The user provided connection string. + * + * @return array The tokenized connection string keys. + * + * @throws \RuntimeException + */ + protected static function parseAndValidateKeys($connectionString) + { + // Initialize the static values if they are not initialized yet. + if (!static::$isInitialized) { + static::init(); + static::$isInitialized = true; + } + + $tokenizedSettings = ConnectionStringParser::parseConnectionString( + 'connectionString', + $connectionString + ); + + // Assure that all given keys are valid. + foreach ($tokenizedSettings as $key => $value) { + if (!Utilities::inArrayInsensitive($key, static::$validSettingKeys) ) { + throw new \RuntimeException( + sprintf( + Resources::INVALID_CONNECTION_STRING_SETTING_KEY, + $key, + implode("\n", static::$validSettingKeys) + ) + ); + } + } + + return $tokenizedSettings; + } + + /** + * Creates an anonymous function that acts as predicate. + * + * @param array $requirements The array of conditions to satisfy. + * @param boolean $isRequired Either these conditions are all required or all + * optional. + * @param boolean $atLeastOne Indicates that at least one requirement must + * succeed. + * + * @return callable + */ + protected static function getValidator($requirements, $isRequired, $atLeastOne) + { + // @codingStandardsIgnoreStart + + return function ($userSettings) + use ($requirements, $isRequired, $atLeastOne) { + $oneFound = false; + $result = array_change_key_case($userSettings); + foreach ($requirements as $requirement) { + $settingName = strtolower($requirement[Resources::SETTING_NAME]); + + // Check if the setting name exists in the provided user settings. + if (array_key_exists($settingName, $result)) { + // Check if the provided user setting value is valid. + $validationFunc = $requirement[Resources::SETTING_CONSTRAINT]; + $isValid = $validationFunc($result[$settingName]); + + if ($isValid) { + // Remove the setting as indicator for successful validation. + unset($result[$settingName]); + $oneFound = true; + } + } else { + // If required then fail because the setting does not exist + if ($isRequired) { + return null; + } + } + } + + if ($atLeastOne) { + // At least one requirement must succeed, otherwise fail. + return $oneFound ? $result : null; + } else { + return $result; + } + }; + + // @codingStandardsIgnoreEnd + } + + /** + * Creates at lease one succeed predicate for the provided list of requirements. + * + * @return callable + */ + protected static function atLeastOne() + { + $allSettings = func_get_args(); + return self::getValidator($allSettings, false, true); + } + + /** + * Creates an optional predicate for the provided list of requirements. + * + * @return callable + */ + protected static function optional() + { + $optionalSettings = func_get_args(); + return self::getValidator($optionalSettings, false, false); + } + + /** + * Creates an required predicate for the provided list of requirements. + * + * @return callable + */ + protected static function allRequired() + { + $requiredSettings = func_get_args(); + return self::getValidator($requiredSettings, true, false); + } + + /** + * Creates a setting value condition using the passed predicate. + * + * @param string $name The setting key name. + * @param callable $predicate The setting value predicate. + * + * @return array + */ + protected static function settingWithFunc($name, $predicate) + { + $requirement = array(); + $requirement[Resources::SETTING_NAME] = $name; + $requirement[Resources::SETTING_CONSTRAINT] = $predicate; + + return $requirement; + } + + /** + * Creates a setting value condition that validates it is one of the + * passed valid values. + * + * @param string $name The setting key name. + * + * @return array + */ + protected static function setting($name) + { + $validValues = func_get_args(); + + // Remove $name argument. + unset($validValues[0]); + + $validValuesCount = func_num_args(); + + $predicate = function ($settingValue) use ($validValuesCount, $validValues) { + if (empty($validValues)) { + // No restrictions, succeed, + return true; + } + + // Check to find if the $settingValue is valid or not. The index must + // start from 1 as unset deletes the value but does not update the array + // indecies. + for ($index = 1; $index < $validValuesCount; $index++) { + if ($settingValue == $validValues[$index]) { + // $settingValue is found in valid values set, succeed. + return true; + } + } + + throw new \RuntimeException( + sprintf( + Resources::INVALID_CONFIG_VALUE, + $settingValue, + implode("\n", $validValues) + ) + ); + + // $settingValue is missing in valid values set, fail. + return false; + }; + + return self::settingWithFunc($name, $predicate); + } + + /** + * Tests to see if a given list of settings matches a set of filters exactly. + * + * @param array $settings The settings to check. + * + * @return boolean If any filter returns null, false. If there are any settings + * left over after all filters are processed, false. Otherwise true. + */ + protected static function matchedSpecification($settings) + { + $constraints = func_get_args(); + + // Remove first element which corresponds to $settings + unset($constraints[0]); + + foreach ($constraints as $constraint) { + $remainingSettings = $constraint($settings); + + if (is_null($remainingSettings)) { + return false; + } else { + $settings = $remainingSettings; + } + } + + if (empty($settings)) { + return true; + } + + return false; + } +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/StorageServiceSettings.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/StorageServiceSettings.php new file mode 100644 index 0000000..f49c420 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/StorageServiceSettings.php @@ -0,0 +1,485 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Internal; +use WindowsAzure\Common\Internal\ConnectionStringParser; +use WindowsAzure\Common\Internal\Resources; + +/** + * Represents the settings used to sign and access a request against the storage + * service. For more information about storage service connection strings check this + * page: http://msdn.microsoft.com/en-us/library/ee758697 + * + * @category Microsoft + * @package WindowsAzure\Common\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class StorageServiceSettings extends ServiceSettings +{ + /** + * The storage service name. + * + * @var string + */ + private $_name; + + /** + * A base64 representation. + * + * @var string + */ + private $_key; + + /** + * The endpoint for the blob service. + * + * @var string + */ + private $_blobEndpointUri; + + /** + * The endpoint for the queue service. + * + * @var string + */ + private $_queueEndpointUri; + + /** + * The endpoint for the table service. + * + * @var string + */ + private $_tableEndpointUri; + + /** + * @var StorageServiceSettings + */ + private static $_devStoreAccount; + + /** + * Validator for the UseDevelopmentStorage setting. Must be "true". + * + * @var array + */ + private static $_useDevelopmentStorageSetting; + + /** + * Validator for the DevelopmentStorageProxyUri setting. Must be a valid Uri. + * + * @var array + */ + private static $_developmentStorageProxyUriSetting; + + /** + * Validator for the DefaultEndpointsProtocol setting. Must be either "http" + * or "https". + * + * @var array + */ + private static $_defaultEndpointsProtocolSetting; + + /** + * Validator for the AccountName setting. No restrictions. + * + * @var array + */ + private static $_accountNameSetting; + + /** + * Validator for the AccountKey setting. Must be a valid base64 string. + * + * @var array + */ + private static $_accountKeySetting; + + /** + * Validator for the BlobEndpoint setting. Must be a valid Uri. + * + * @var array + */ + private static $_blobEndpointSetting; + + /** + * Validator for the QueueEndpoint setting. Must be a valid Uri. + * + * @var array + */ + private static $_queueEndpointSetting; + + /** + * Validator for the TableEndpoint setting. Must be a valid Uri. + * + * @var array + */ + private static $_tableEndpointSetting; + + /** + * @var boolean + */ + protected static $isInitialized = false; + + /** + * Holds the expected setting keys. + * + * @var array + */ + protected static $validSettingKeys = array(); + + /** + * Initializes static members of the class. + * + * @return none + */ + protected static function init() + { + self::$_useDevelopmentStorageSetting = self::setting( + Resources::USE_DEVELOPMENT_STORAGE_NAME, + 'true' + ); + + self::$_developmentStorageProxyUriSetting = self::settingWithFunc( + Resources::DEVELOPMENT_STORAGE_PROXY_URI_NAME, + Validate::getIsValidUri() + ); + + self::$_defaultEndpointsProtocolSetting = self::setting( + Resources::DEFAULT_ENDPOINTS_PROTOCOL_NAME, + 'http', 'https' + ); + + self::$_accountNameSetting = self::setting(Resources::ACCOUNT_NAME_NAME); + + self::$_accountKeySetting = self::settingWithFunc( + Resources::ACCOUNT_KEY_NAME, + // base64_decode will return false if the $key is not in base64 format. + function ($key) { + $isValidBase64String = base64_decode($key, true); + if ($isValidBase64String) { + return true; + } else { + throw new \RuntimeException( + sprintf(Resources::INVALID_ACCOUNT_KEY_FORMAT, $key) + ); + } + } + ); + + self::$_blobEndpointSetting = self::settingWithFunc( + Resources::BLOB_ENDPOINT_NAME, + Validate::getIsValidUri() + ); + + self::$_queueEndpointSetting = self::settingWithFunc( + Resources::QUEUE_ENDPOINT_NAME, + Validate::getIsValidUri() + ); + + self::$_tableEndpointSetting = self::settingWithFunc( + Resources::TABLE_ENDPOINT_NAME, + Validate::getIsValidUri() + ); + + self::$validSettingKeys[] = Resources::USE_DEVELOPMENT_STORAGE_NAME; + self::$validSettingKeys[] = Resources::DEVELOPMENT_STORAGE_PROXY_URI_NAME; + self::$validSettingKeys[] = Resources::DEFAULT_ENDPOINTS_PROTOCOL_NAME; + self::$validSettingKeys[] = Resources::ACCOUNT_NAME_NAME; + self::$validSettingKeys[] = Resources::ACCOUNT_KEY_NAME; + self::$validSettingKeys[] = Resources::BLOB_ENDPOINT_NAME; + self::$validSettingKeys[] = Resources::QUEUE_ENDPOINT_NAME; + self::$validSettingKeys[] = Resources::TABLE_ENDPOINT_NAME; + } + + /** + * Creates new storage service settings instance. + * + * @param string $name The storage service name. + * @param string $key The storage service key. + * @param string $blobEndpointUri The sotrage service blob endpoint. + * @param string $queueEndpointUri The sotrage service queue endpoint. + * @param string $tableEndpointUri The sotrage service table endpoint. + */ + public function __construct( + $name, + $key, + $blobEndpointUri, + $queueEndpointUri, + $tableEndpointUri + ) { + $this->_name = $name; + $this->_key = $key; + $this->_blobEndpointUri = $blobEndpointUri; + $this->_queueEndpointUri = $queueEndpointUri; + $this->_tableEndpointUri = $tableEndpointUri; + } + + /** + * Returns a StorageServiceSettings with development storage credentials using + * the specified proxy Uri. + * + * @param string $proxyUri The proxy endpoint to use. + * + * @return StorageServiceSettings + */ + private static function _getDevelopmentStorageAccount($proxyUri) + { + if (is_null($proxyUri)) { + return self::developmentStorageAccount(); + } + + $scheme = parse_url($proxyUri, PHP_URL_SCHEME); + $host = parse_url($proxyUri, PHP_URL_HOST); + $prefix = $scheme . "://" . $host; + + return new StorageServiceSettings( + Resources::DEV_STORE_NAME, + Resources::DEV_STORE_KEY, + $prefix . ':10000/devstoreaccount1/', + $prefix . ':10001/devstoreaccount1/', + $prefix . ':10002/devstoreaccount1/' + ); + } + + /** + * Gets a StorageServiceSettings object that references the development storage + * account. + * + * @return StorageServiceSettings + */ + public static function developmentStorageAccount() + { + if (is_null(self::$_devStoreAccount)) { + self::$_devStoreAccount = self::_getDevelopmentStorageAccount( + Resources::DEV_STORE_URI + ); + } + + return self::$_devStoreAccount; + } + + /** + * Gets the default service endpoint using the specified protocol and account + * name. + * + * @param array $settings The service settings. + * @param string $dns The service DNS. + * + * @return string + */ + private static function _getDefaultServiceEndpoint($settings, $dns) + { + $scheme = Utilities::tryGetValueInsensitive( + Resources::DEFAULT_ENDPOINTS_PROTOCOL_NAME, + $settings + ); + $accountName = Utilities::tryGetValueInsensitive( + Resources::ACCOUNT_NAME_NAME, + $settings + ); + + return sprintf(Resources::SERVICE_URI_FORMAT, $scheme, $accountName, $dns); + } + + /** + * Creates StorageServiceSettings object given endpoints uri. + * + * @param array $settings The service settings. + * @param string $blobEndpointUri The blob endpoint uri. + * @param string $queueEndpointUri The queue endpoint uri. + * @param string $tableEndpointUri The table endpoint uri. + * + * @return \WindowsAzure\Common\Internal\StorageServiceSettings + */ + private static function _createStorageServiceSettings( + $settings, + $blobEndpointUri = null, + $queueEndpointUri = null, + $tableEndpointUri = null + ) { + $blobEndpointUri = Utilities::tryGetValueInsensitive( + Resources::BLOB_ENDPOINT_NAME, + $settings, + $blobEndpointUri + ); + $queueEndpointUri = Utilities::tryGetValueInsensitive( + Resources::QUEUE_ENDPOINT_NAME, + $settings, + $queueEndpointUri + ); + $tableEndpointUri = Utilities::tryGetValueInsensitive( + Resources::TABLE_ENDPOINT_NAME, + $settings, + $tableEndpointUri + ); + $accountName = Utilities::tryGetValueInsensitive( + Resources::ACCOUNT_NAME_NAME, + $settings + ); + $accountKey = Utilities::tryGetValueInsensitive( + Resources::ACCOUNT_KEY_NAME, + $settings + ); + + return new StorageServiceSettings( + $accountName, + $accountKey, + $blobEndpointUri, + $queueEndpointUri, + $tableEndpointUri + ); + } + + /** + * Creates a StorageServiceSettings object from the given connection string. + * + * @param string $connectionString The storage settings connection string. + * + * @return StorageServiceSettings + */ + public static function createFromConnectionString($connectionString) + { + $tokenizedSettings = self::parseAndValidateKeys($connectionString); + + // Devstore case + $matchedSpecs = self::matchedSpecification( + $tokenizedSettings, + self::allRequired(self::$_useDevelopmentStorageSetting), + self::optional(self::$_developmentStorageProxyUriSetting) + ); + if ($matchedSpecs) { + $proxyUri = Utilities::tryGetValueInsensitive( + Resources::DEVELOPMENT_STORAGE_PROXY_URI_NAME, + $tokenizedSettings + ); + + return self::_getDevelopmentStorageAccount($proxyUri); + } + + // Automatic case + $matchedSpecs = self::matchedSpecification( + $tokenizedSettings, + self::allRequired( + self::$_defaultEndpointsProtocolSetting, + self::$_accountNameSetting, + self::$_accountKeySetting + ), + self::optional( + self::$_blobEndpointSetting, + self::$_queueEndpointSetting, + self::$_tableEndpointSetting + ) + ); + if ($matchedSpecs) { + return self::_createStorageServiceSettings( + $tokenizedSettings, + self::_getDefaultServiceEndpoint( + $tokenizedSettings, + Resources::BLOB_BASE_DNS_NAME + ), + self::_getDefaultServiceEndpoint( + $tokenizedSettings, + Resources::QUEUE_BASE_DNS_NAME + ), + self::_getDefaultServiceEndpoint( + $tokenizedSettings, + Resources::TABLE_BASE_DNS_NAME + ) + ); + } + + // Explicit case + $matchedSpecs = self::matchedSpecification( + $tokenizedSettings, + self::atLeastOne( + self::$_blobEndpointSetting, + self::$_queueEndpointSetting, + self::$_tableEndpointSetting + ), + self::allRequired( + self::$_accountNameSetting, + self::$_accountKeySetting + ) + ); + if ($matchedSpecs) { + return self::_createStorageServiceSettings($tokenizedSettings); + } + + self::noMatch($connectionString); + } + + /** + * Gets storage service name. + * + * @return string + */ + public function getName() + { + return $this->_name; + } + + /** + * Gets storage service key. + * + * @return string + */ + public function getKey() + { + return $this->_key; + } + + /** + * Gets storage service blob endpoint uri. + * + * @return string + */ + public function getBlobEndpointUri() + { + return $this->_blobEndpointUri; + } + + /** + * Gets storage service queue endpoint uri. + * + * @return string + */ + public function getQueueEndpointUri() + { + return $this->_queueEndpointUri; + } + + /** + * Gets storage service table endpoint uri. + * + * @return string + */ + public function getTableEndpointUri() + { + return $this->_tableEndpointUri; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Utilities.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Utilities.php new file mode 100644 index 0000000..42a53f9 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Utilities.php @@ -0,0 +1,635 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Internal; + +/** + * Utilities for the project + * + * @category Microsoft + * @package WindowsAzure\Common\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class Utilities +{ + /** + * Returns the specified value of the $key passed from $array and in case that + * this $key doesn't exist, the default value is returned. + * + * @param array $array The array to be used. + * @param mix $key The array key. + * @param mix $default The value to return if $key is not found in $array. + * + * @static + * + * @return mix + */ + public static function tryGetValue($array, $key, $default = null) + { + return is_array($array) && array_key_exists($key, $array) + ? $array[$key] + : $default; + } + + /** + * Adds a url scheme if there is no scheme. + * + * @param string $url The URL. + * @param string $scheme The scheme. By default HTTP + * + * @static + * + * @return string + */ + public static function tryAddUrlScheme($url, $scheme = 'http') + { + $urlScheme = parse_url($url, PHP_URL_SCHEME); + + if (empty($urlScheme)) { + $url = "$scheme://" . $url; + } + + return $url; + } + + /** + * tries to get nested array with index name $key from $array. + * + * Returns empty array object if the value is NULL. + * + * @param string $key The index name. + * @param array $array The array object. + * + * @static + * + * @return array + */ + public static function tryGetArray($key, $array) + { + return Utilities::getArray(Utilities::tryGetValue($array, $key)); + } + + /** + * Adds the given key/value pair into array if the value doesn't satisfy empty(). + * + * This function just validates that the given $array is actually array. If it's + * NULL the function treats it as array. + * + * @param string $key The key. + * @param string $value The value. + * @param array &$array The array. If NULL will be used as array. + * + * @static + * + * @return none + */ + public static function addIfNotEmpty($key, $value, &$array) + { + if (!is_null($array)) { + Validate::isArray($array, 'array'); + } + + if (!empty($value)) { + $array[$key] = $value; + } + } + + /** + * Returns the specified value of the key chain passed from $array and in case + * that key chain doesn't exist, null is returned. + * + * @param array $array Array to be used. + * + * @static + * + * @return mix + */ + public static function tryGetKeysChainValue($array) + { + $arguments = func_get_args(); + $numArguments = func_num_args(); + + $currentArray = $array; + for ($i = 1; $i < $numArguments; $i++) { + if (is_array($currentArray)) { + if (array_key_exists($arguments[$i], $currentArray)) { + $currentArray = $currentArray[$arguments[$i]]; + } else { + return null; + } + } else { + return null; + } + } + + return $currentArray; + } + + /** + * Checks if the passed $string starts with $prefix + * + * @param string $string word to seaech in + * @param string $prefix prefix to be matched + * @param boolean $ignoreCase true to ignore case during the comparison; + * otherwise, false + * + * @static + * + * @return boolean + */ + public static function startsWith($string, $prefix, $ignoreCase = false) + { + if ($ignoreCase) { + $string = strtolower($string); + $prefix = strtolower($prefix); + } + return ($prefix == substr($string, 0, strlen($prefix))); + } + + /** + * Returns grouped items from passed $var + * + * @param array $var item to group + * + * @static + * + * @return array + */ + public static function getArray($var) + { + if (is_null($var) || empty($var)) { + return array(); + } + + foreach ($var as $value) { + if ((gettype($value) == 'object') + && (get_class($value) == 'SimpleXMLElement') + ) { + return (array) $var; + } else if (!is_array($value)) { + return array($var); + } + + } + + return $var; + } + + /** + * Unserializes the passed $xml into array. + * + * @param string $xml XML to be parsed. + * + * @static + * + * @return array + */ + public static function unserialize($xml) + { + $sxml = new \SimpleXMLElement($xml); + + return self::_sxml2arr($sxml); + } + + /** + * Converts a SimpleXML object to an Array recursively + * ensuring all sub-elements are arrays as well. + * + * @param string $sxml SimpleXML object + * @param array $arr Array into which to store results + * + * @static + * + * @return array + */ + private static function _sxml2arr($sxml, $arr = null) + { + foreach ((array) $sxml as $key => $value) { + if (is_object($value) || (is_array($value))) { + $arr[$key] = self::_sxml2arr($value); + } else { + $arr[$key] = $value; + } + } + + return $arr; + } + + /** + * Serializes given array into xml. The array indices must be string to use + * them as XML tags. + * + * @param array $array object to serialize represented in array. + * @param string $rootName name of the XML root element. + * @param string $defaultTag default tag for non-tagged elements. + * @param string $standalone adds 'standalone' header tag, values 'yes'/'no' + * + * @static + * + * @return string + */ + public static function serialize($array, $rootName, $defaultTag = null, + $standalone = null + ) { + $xmlVersion = '1.0'; + $xmlEncoding = 'UTF-8'; + + if (!is_array($array)) { + return false; + } + + $xmlw = new \XmlWriter(); + $xmlw->openMemory(); + $xmlw->startDocument($xmlVersion, $xmlEncoding, $standalone); + + $xmlw->startElement($rootName); + + self::_arr2xml($xmlw, $array, $defaultTag); + + $xmlw->endElement(); + + return $xmlw->outputMemory(true); + } + + /** + * Takes an array and produces XML based on it. + * + * @param XMLWriter $xmlw XMLWriter object that was previously instanted + * and is used for creating the XML. + * @param array $data Array to be converted to XML + * @param string $defaultTag Default XML tag to be used if none specified. + * + * @static + * + * @return void + */ + private static function _arr2xml(\XMLWriter $xmlw, $data, $defaultTag = null) + { + foreach ($data as $key => $value) { + if (strcmp($key, '@attributes') == 0) { + foreach ($value as $attributeName => $attributeValue) { + $xmlw->writeAttribute($attributeName, $attributeValue); + } + } else if (is_array($value)) { + if (!is_int($key)) { + if ($key != Resources::EMPTY_STRING) { + $xmlw->startElement($key); + } else { + $xmlw->startElement($defaultTag); + } + } + + self::_arr2xml($xmlw, $value); + + if (!is_int($key)) { + $xmlw->endElement(); + } + continue; + } else { + $xmlw->writeElement($key, $value); + } + } + } + + /** + * Converts string into boolean value. + * + * @param string $obj boolean value in string format. + * + * @static + * + * @return bool + */ + public static function toBoolean($obj) + { + return filter_var($obj, FILTER_VALIDATE_BOOLEAN); + } + + /** + * Converts string into boolean value. + * + * @param bool $obj boolean value to convert. + * + * @static + * + * @return string + */ + public static function booleanToString($obj) + { + return $obj ? 'true' : 'false'; + } + + /** + * Converts a given date string into \DateTime object + * + * @param string $date windows azure date ins string represntation. + * + * @static + * + * @return \DateTime + */ + public static function rfc1123ToDateTime($date) + { + $timeZone = new \DateTimeZone('GMT'); + $format = Resources::AZURE_DATE_FORMAT; + + return \DateTime::createFromFormat($format, $date, $timeZone); + } + + /** + * Generate ISO 8601 compliant date string in UTC time zone + * + * @param int $timestamp The unix timestamp to convert + * (for DateTime check date_timestamp_get). + * + * @static + * + * @return string + */ + public static function isoDate($timestamp = null) + { + $tz = date_default_timezone_get(); + date_default_timezone_set('UTC'); + + if (is_null($timestamp)) { + $timestamp = time(); + } + + $returnValue = str_replace( + '+00:00', '.0000000Z', date('c', $timestamp) + ); + date_default_timezone_set($tz); + return $returnValue; + } + + /** + * Converts a DateTime object into an Edm.DaeTime value in UTC timezone, + * represented as a string. + * + * @param \DateTime $value The datetime value. + * + * @static + * + * @return string + */ + public static function convertToEdmDateTime($value) + { + if (empty($value)) { + return $value; + } + + if (is_string($value)) { + $value = self::convertToDateTime($value); + } + + Validate::isDate($value); + + $cloned = clone $value; + $cloned->setTimezone(new \DateTimeZone('UTC')); + return str_replace('+0000', 'Z', $cloned->format(\DateTime::ISO8601)); + } + + /** + * Converts a string to a \DateTime object. Returns false on failure. + * + * @param string $value The string value to parse. + * + * @static + * + * @return \DateTime + */ + public static function convertToDateTime($value) + { + if ($value instanceof \DateTime) { + return $value; + } + + if (substr($value, -1) == 'Z') { + $value = substr($value, 0, strlen($value) - 1); + } + + return new \DateTime($value, new \DateTimeZone('UTC')); + } + + /** + * Converts string to stream handle. + * + * @param type $string The string contents. + * + * @static + * + * @return resource + */ + public static function stringToStream($string) + { + return fopen('data://text/plain,' . urlencode($string), 'rb'); + } + + /** + * Sorts an array based on given keys order. + * + * @param array $array The array to sort. + * @param array $order The keys order array. + * + * @return array + */ + public static function orderArray($array, $order) + { + $ordered = array(); + + foreach ($order as $key) { + if (array_key_exists($key, $array)) { + $ordered[$key] = $array[$key]; + } + } + + return $ordered; + } + + /** + * Checks if a value exists in an array. The comparison is done in a case + * insensitive manner. + * + * @param string $needle The searched value. + * @param array $haystack The array. + * + * @static + * + * @return boolean + */ + public static function inArrayInsensitive($needle, $haystack) + { + return in_array(strtolower($needle), array_map('strtolower', $haystack)); + } + + /** + * Checks if the given key exists in the array. The comparison is done in a case + * insensitive manner. + * + * @param string $key The value to check. + * @param array $search The array with keys to check. + * + * @static + * + * @return boolean + */ + public static function arrayKeyExistsInsensitive($key, $search) + { + return array_key_exists(strtolower($key), array_change_key_case($search)); + } + + /** + * Returns the specified value of the $key passed from $array and in case that + * this $key doesn't exist, the default value is returned. The key matching is + * done in a case insensitive manner. + * + * @param string $key The array key. + * @param array $haystack The array to be used. + * @param mix $default The value to return if $key is not found in $array. + * + * @static + * + * @return mix + */ + public static function tryGetValueInsensitive($key, $haystack, $default = null) + { + $array = array_change_key_case($haystack); + return Utilities::tryGetValue($array, strtolower($key), $default); + } + + /** + * Returns a string representation of a version 4 GUID, which uses random + * numbers.There are 6 reserved bits, and the GUIDs have this format: + * xxxxxxxx-xxxx-4xxx-[8|9|a|b]xxx-xxxxxxxxxxxx + * where 'x' is a hexadecimal digit, 0-9a-f. + * + * See http://tools.ietf.org/html/rfc4122 for more information. + * + * Note: This function is available on all platforms, while the + * com_create_guid() is only available for Windows. + * + * @static + * + * @return string A new GUID. + */ + public static function getGuid() + { + // @codingStandardsIgnoreStart + + return sprintf( + '%04x%04x-%04x-%04x-%02x%02x-%04x%04x%04x', + mt_rand(0, 65535), + mt_rand(0, 65535), // 32 bits for "time_low" + mt_rand(0, 65535), // 16 bits for "time_mid" + mt_rand(0, 4096) + 16384, // 16 bits for "time_hi_and_version", with + // the most significant 4 bits being 0100 + // to indicate randomly generated version + mt_rand(0, 64) + 128, // 8 bits for "clock_seq_hi", with + // the most significant 2 bits being 10, + // required by version 4 GUIDs. + mt_rand(0, 256), // 8 bits for "clock_seq_low" + mt_rand(0, 65535), // 16 bits for "node 0" and "node 1" + mt_rand(0, 65535), // 16 bits for "node 2" and "node 3" + mt_rand(0, 65535) // 16 bits for "node 4" and "node 5" + ); + + // @codingStandardsIgnoreEnd + } + + /** + * Creates a list of objects of type $class from the provided array using static + * create method. + * + * @param array $parsed The object in array representation + * @param string $class The class name. Must have static method create. + * + * @static + * + * @return array + */ + public static function createInstanceList($parsed, $class) + { + $list = array(); + + foreach ($parsed as $value) { + $list[] = $class::create($value); + } + + return $list; + } + + /** + * Takes a string and return if it ends with the specified character/string. + * + * @param string $haystack The string to search in. + * @param string $needle postfix to match. + * @param boolean $ignoreCase Set true to ignore case during the comparison; + * otherwise, false + * + * @static + * + * @return boolean + */ + public static function endsWith($haystack, $needle, $ignoreCase = false) + { + if ($ignoreCase) { + $haystack = strtolower($haystack); + $needle = strtolower($needle); + } + $length = strlen($needle); + if ($length == 0) { + return true; + } + + return (substr($haystack, -$length) === $needle); + } + + /** + * Get id from entity object or string. + * If entity is object than validate type and return $entity->$method() + * If entity is string than return this string + * + * @param object|string $entity Entity with id property + * @param string $type Entity type to validate + * @param string $method Methods that gets id (getId by default) + * + * @return string + */ + public static function getEntityId($entity, $type, $method = 'getId') + { + if (is_string($entity)) { + return $entity; + } else { + Validate::isA($entity, $type, 'entity'); + Validate::methodExists($entity, $method, $type); + + return $entity->$method(); + } + } + +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Validate.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Validate.php new file mode 100644 index 0000000..a826e70 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Internal/Validate.php @@ -0,0 +1,397 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Internal; +use WindowsAzure\Common\Internal\InvalidArgumentTypeException; +use WindowsAzure\Common\Internal\Resources; + +/** + * Validates aganist a condition and throws an exception in case of failure. + * + * @category Microsoft + * @package WindowsAzure\Common\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class Validate +{ + /** + * Throws exception if the provided variable type is not array. + * + * @param mix $var The variable to check. + * @param string $name The parameter name. + * + * @throws InvalidArgumentTypeException. + * + * @return none + */ + public static function isArray($var, $name) + { + if (!is_array($var)) { + throw new InvalidArgumentTypeException(gettype(array()), $name); + } + } + + /** + * Throws exception if the provided variable type is not string. + * + * @param mix $var The variable to check. + * @param string $name The parameter name. + * + * @throws InvalidArgumentTypeException + * + * @return none + */ + public static function isString($var, $name) + { + try { + (string)$var; + } catch (\Exception $e) { + throw new InvalidArgumentTypeException(gettype(''), $name); + } + } + + /** + * Throws exception if the provided variable type is not boolean. + * + * @param mix $var variable to check against. + * + * @throws InvalidArgumentTypeException + * + * @return none + */ + public static function isBoolean($var) + { + (bool)$var; + } + + /** + * Throws exception if the provided variable is set to null. + * + * @param mix $var The variable to check. + * @param string $name The parameter name. + * + * @throws \InvalidArgumentException + * + * @return none + */ + public static function notNullOrEmpty($var, $name) + { + if (is_null($var) || empty($var)) { + throw new \InvalidArgumentException( + sprintf(Resources::NULL_OR_EMPTY_MSG, $name) + ); + } + } + + /** + * Throws exception if the provided variable is not double. + * + * @param mix $var The variable to check. + * @param string $name The parameter name. + * + * @throws \InvalidArgumentException + * + * @return none + */ + public static function isDouble($var, $name) + { + if (!is_numeric($var)) { + throw new InvalidArgumentTypeException('double', $name); + } + } + + /** + * Throws exception if the provided variable type is not integer. + * + * @param mix $var The variable to check. + * @param string $name The parameter name. + * + * @throws InvalidArgumentTypeException + * + * @return none + */ + public static function isInteger($var, $name) + { + try { + (int)$var; + } catch (\Exception $e) { + throw new InvalidArgumentTypeException(gettype(123), $name); + } + } + + /** + * Returns whether the variable is an empty or null string. + * + * @param string $var value. + * + * @return boolean + */ + public static function isNullOrEmptyString($var) + { + try { + (string)$var; + } catch (\Exception $e) { + return false; + } + + return (!isset($var) || trim($var)===''); + } + + /** + * Throws exception if the provided condition is not satisfied. + * + * @param bool $isSatisfied condition result. + * @param string $failureMessage the exception message + * + * @throws \Exception + * + * @return none + */ + public static function isTrue($isSatisfied, $failureMessage) + { + if (!$isSatisfied) { + throw new \InvalidArgumentException($failureMessage); + } + } + + /** + * Throws exception if the provided $date is not of type \DateTime + * + * @param mix $date variable to check against. + * + * @throws WindowsAzure\Common\Internal\InvalidArgumentTypeException + * + * @return none + */ + public static function isDate($date) + { + if (gettype($date) != 'object' || get_class($date) != 'DateTime') { + throw new InvalidArgumentTypeException('DateTime'); + } + } + + /** + * Throws exception if the provided variable is set to null. + * + * @param mix $var The variable to check. + * @param string $name The parameter name. + * + * @throws \InvalidArgumentException + * + * @return none + */ + public static function notNull($var, $name) + { + if (is_null($var)) { + throw new \InvalidArgumentException(sprintf(Resources::NULL_MSG, $name)); + } + } + + /** + * Throws exception if the object is not of the specified class type. + * + * @param mixed $objectInstance An object that requires class type validation. + * @param mixed $classInstance The instance of the class the the + * object instance should be. + * @param string $name The name of the object. + * + * @throws \InvalidArgumentException + * + * @return none + */ + public static function isInstanceOf($objectInstance, $classInstance, $name) + { + Validate::notNull($classInstance, 'classInstance'); + if (is_null($objectInstance)) { + return true; + } + + $objectType = gettype($objectInstance); + $classType = gettype($classInstance); + + if ($objectType === $classType) { + return true; + } else { + throw new \InvalidArgumentException( + sprintf( + Resources::INSTANCE_TYPE_VALIDATION_MSG, + $name, + $objectType, + $classType + ) + ); + } + } + + /** + * Creates a anonymous function that check if the given uri is valid or not. + * + * @return callable + */ + public static function getIsValidUri() + { + return function ($uri) { + return Validate::isValidUri($uri); + }; + } + + /** + * Throws exception if the string is not of a valid uri. + * + * @param string $uri String to check. + * + * @throws \InvalidArgumentException + * + * @return boolean + */ + public static function isValidUri($uri) + { + $isValid = filter_var($uri, FILTER_VALIDATE_URL); + + if ($isValid) { + return true; + } else { + throw new \RuntimeException( + sprintf(Resources::INVALID_CONFIG_URI, $uri) + ); + } + } + + /** + * Throws exception if the provided variable type is not object. + * + * @param mix $var The variable to check. + * @param string $name The parameter name. + * + * @throws InvalidArgumentTypeException. + * + * @return boolean + */ + public static function isObject($var, $name) + { + if (!is_object($var)) { + throw new InvalidArgumentTypeException('object', $name); + } + + return true; + } + + /** + * Throws exception if the object is not of the specified class type. + * + * @param mixed $objectInstance An object that requires class type validation. + * @param string $class The class the object instance should be. + * @param string $name The parameter name. + * + * @throws \InvalidArgumentException + * + * @return boolean + */ + public static function isA($objectInstance, $class, $name) + { + Validate::isString($class, 'class'); + Validate::notNull($objectInstance, 'objectInstance'); + Validate::isObject($objectInstance, 'objectInstance'); + + $objectType = get_class($objectInstance); + + if (is_a($objectInstance, $class)) { + return true; + } else { + throw new \InvalidArgumentException( + sprintf( + Resources::INSTANCE_TYPE_VALIDATION_MSG, + $name, + $objectType, + $class + ) + ); + } + } + + /** + * Validate if method exists in object + * + * @param object $objectInstance An object that requires method existing + * validation + * @param string $method Method name + * @param string $name The parameter name + * + * @return boolean + */ + public static function methodExists($objectInstance, $method, $name) + { + Validate::isString($method, 'method'); + Validate::notNull($objectInstance, 'objectInstance'); + Validate::isObject($objectInstance, 'objectInstance'); + + if (method_exists($objectInstance, $method)) { + return true; + } else { + throw new \InvalidArgumentException( + sprintf( + Resources::ERROR_METHOD_NOT_FOUND, + $method, + $name + ) + ); + } + } + + /** + * Validate if string is date formatted + * + * @param string $value Value to validate + * @param string $name Name of parameter to insert in erro message + * + * @throws \InvalidArgumentException + * + * @return boolean + */ + public static function isDateString($value, $name) + { + Validate::isString($value, 'value'); + + try { + new \DateTime($value); + return true; + } + catch (\Exception $e) { + throw new \InvalidArgumentException( + sprintf( + Resources::ERROR_INVALID_DATE_STRING, + $name, + $value + ) + ); + } + } + +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Models/GetServicePropertiesResult.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Models/GetServicePropertiesResult.php new file mode 100644 index 0000000..97f69cd --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Models/GetServicePropertiesResult.php @@ -0,0 +1,81 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Models; +use WindowsAzure\Common\Models\ServiceProperties; + +/** + * Result from calling GetQueueProperties REST wrapper. + * + * @category Microsoft + * @package WindowsAzure\Common\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class GetServicePropertiesResult +{ + private $_serviceProperties; + + /** + * Creates object from $parsedResponse. + * + * @param array $parsedResponse XML response parsed into array. + * + * @return WindowsAzure\Common\Models\GetServicePropertiesResult + */ + public static function create($parsedResponse) + { + $result = new GetServicePropertiesResult(); + $result->_serviceProperties = ServiceProperties::create($parsedResponse); + + return $result; + } + + /** + * Gets service properties object. + * + * @return WindowsAzure\Common\Models\ServiceProperties + */ + public function getValue() + { + return $this->_serviceProperties; + } + + /** + * Sets service properties object. + * + * @param ServiceProperties $serviceProperties object to use. + * + * @return none + */ + public function setValue($serviceProperties) + { + $this->_serviceProperties = clone $serviceProperties; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Models/Logging.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Models/Logging.php new file mode 100644 index 0000000..07e1826 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Models/Logging.php @@ -0,0 +1,229 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Models; +use WindowsAzure\Common\Models\RetentionPolicy; +use WindowsAzure\Common\Internal\Utilities; + +/** + * Holds elements of queue properties logging field. + * + * @category Microsoft + * @package WindowsAzure\Common\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class Logging +{ + /** + * The version of Storage Analytics to configure + * + * @var string + */ + private $_version; + + /** + * Applies only to logging configuration. Indicates whether all delete requests + * should be logged. + * + * @var bool + */ + private $_delete; + + /** + * Applies only to logging configuration. Indicates whether all read requests + * should be logged. + * + * @var bool. + */ + private $_read; + + /** + * Applies only to logging configuration. Indicates whether all write requests + * should be logged. + * + * @var bool + */ + private $_write; + + /** + * @var WindowsAzure\Common\Models\RetentionPolicy + */ + private $_retentionPolicy; + + /** + * Creates object from $parsedResponse. + * + * @param array $parsedResponse XML response parsed into array. + * + * @return WindowsAzure\Common\Models\Logging + */ + public static function create($parsedResponse) + { + $result = new Logging(); + $result->setVersion($parsedResponse['Version']); + $result->setDelete(Utilities::toBoolean($parsedResponse['Delete'])); + $result->setRead(Utilities::toBoolean($parsedResponse['Read'])); + $result->setWrite(Utilities::toBoolean($parsedResponse['Write'])); + $result->setRetentionPolicy( + RetentionPolicy::create($parsedResponse['RetentionPolicy']) + ); + + return $result; + } + + /** + * Gets retention policy + * + * @return WindowsAzure\Common\Models\RetentionPolicy + * + */ + public function getRetentionPolicy() + { + return $this->_retentionPolicy; + } + + /** + * Sets retention policy + * + * @param RetentionPolicy $policy object to use + * + * @return none. + */ + public function setRetentionPolicy($policy) + { + $this->_retentionPolicy = $policy; + } + + /** + * Gets write + * + * @return bool. + */ + public function getWrite() + { + return $this->_write; + } + + /** + * Sets write + * + * @param bool $write new value. + * + * @return none. + */ + public function setWrite($write) + { + $this->_write = $write; + } + + /** + * Gets read + * + * @return bool. + */ + public function getRead() + { + return $this->_read; + } + + /** + * Sets read + * + * @param bool $read new value. + * + * @return none. + */ + public function setRead($read) + { + $this->_read = $read; + } + + /** + * Gets delete + * + * @return bool. + */ + public function getDelete() + { + return $this->_delete; + } + + /** + * Sets delete + * + * @param bool $delete new value. + * + * @return none. + */ + public function setDelete($delete) + { + $this->_delete = $delete; + } + + /** + * Gets version + * + * @return string. + */ + public function getVersion() + { + return $this->_version; + } + + /** + * Sets version + * + * @param string $version new value. + * + * @return none. + */ + public function setVersion($version) + { + $this->_version = $version; + } + + /** + * Converts this object to array with XML tags + * + * @return array. + */ + public function toArray() + { + return array( + 'Version' => $this->_version, + 'Delete' => Utilities::booleanToString($this->_delete), + 'Read' => Utilities::booleanToString($this->_read), + 'Write' => Utilities::booleanToString($this->_write), + 'RetentionPolicy' => !empty($this->_retentionPolicy) + ? $this->_retentionPolicy->toArray() + : null + ); + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Models/Metrics.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Models/Metrics.php new file mode 100644 index 0000000..cd3e665 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Models/Metrics.php @@ -0,0 +1,202 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Models; +use WindowsAzure\Common\Internal\Utilities; + +/** + * Holds elements of queue properties metrics field. + * + * @category Microsoft + * @package WindowsAzure\Common\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class Metrics +{ + /** + * The version of Storage Analytics to configure + * + * @var string + */ + private $_version; + + /** + * Indicates whether metrics is enabled for the storage service + * + * @var bool + */ + private $_enabled; + + /** + * Indicates whether a retention policy is enabled for the storage service + * + * @var bool + */ + private $_includeAPIs; + + /** + * @var WindowsAzure\Common\Models\RetentionPolicy + */ + private $_retentionPolicy; + + /** + * Creates object from $parsedResponse. + * + * @param array $parsedResponse XML response parsed into array. + * + * @return WindowsAzure\Common\Models\Metrics + */ + public static function create($parsedResponse) + { + $result = new Metrics(); + $result->setVersion($parsedResponse['Version']); + $result->setEnabled(Utilities::toBoolean($parsedResponse['Enabled'])); + if ($result->getEnabled()) { + $result->setIncludeAPIs( + Utilities::toBoolean($parsedResponse['IncludeAPIs']) + ); + } + $result->setRetentionPolicy( + RetentionPolicy::create($parsedResponse['RetentionPolicy']) + ); + + return $result; + } + + /** + * Gets retention policy + * + * @return WindowsAzure\Common\Models\RetentionPolicy + * + */ + public function getRetentionPolicy() + { + return $this->_retentionPolicy; + } + + /** + * Sets retention policy + * + * @param RetentionPolicy $policy object to use + * + * @return none. + */ + public function setRetentionPolicy($policy) + { + $this->_retentionPolicy = $policy; + } + + /** + * Gets include APIs. + * + * @return bool. + */ + public function getIncludeAPIs() + { + return $this->_includeAPIs; + } + + /** + * Sets include APIs. + * + * @param $bool $includeAPIs value to use. + * + * @return none. + */ + public function setIncludeAPIs($includeAPIs) + { + $this->_includeAPIs = $includeAPIs; + } + + /** + * Gets enabled. + * + * @return bool. + */ + public function getEnabled() + { + return $this->_enabled; + } + + /** + * Sets enabled. + * + * @param bool $enabled value to use. + * + * @return none. + */ + public function setEnabled($enabled) + { + $this->_enabled = $enabled; + } + + /** + * Gets version + * + * @return string. + */ + public function getVersion() + { + return $this->_version; + } + + /** + * Sets version + * + * @param string $version new value. + * + * @return none. + */ + public function setVersion($version) + { + $this->_version = $version; + } + + /** + * Converts this object to array with XML tags + * + * @return array. + */ + public function toArray() + { + $array = array( + 'Version' => $this->_version, + 'Enabled' => Utilities::booleanToString($this->_enabled) + ); + if ($this->_enabled) { + $array['IncludeAPIs'] = Utilities::booleanToString($this->_includeAPIs); + } + $array['RetentionPolicy'] = !empty($this->_retentionPolicy) + ? $this->_retentionPolicy->toArray() + : null; + + return $array; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Models/OAuthAccessToken.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Models/OAuthAccessToken.php new file mode 100644 index 0000000..101ca8b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Models/OAuthAccessToken.php @@ -0,0 +1,153 @@ + + * @copyright Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Models; +use WindowsAzure\Common\Internal\Resources; + +/** + * Holds OAuth access token data. + * + * @category Microsoft + * @package WindowsAzure\Common\Models + * @author Azure PHP SDK + * @copyright Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class OAuthAccessToken +{ + /** + * Access token itself + * + * @var string + */ + private $_accessToken; + + /** + * Unix time the access token valid before. + * + * @var int + */ + private $_expiresIn; + + /** + * Scope of access token + * + * @var string. + */ + private $_scope; + + /** + * Creates object from $parsedResponse. + * + * @param array $parsedResponse JSON response parsed into array. + * + * @return WindowsAzure\Common\Models\OAuthAccessToken + */ + public static function create($parsedResponse) + { + $result = new OAuthAccessToken(); + + $result->setAccessToken($parsedResponse[Resources::OAUTH_ACCESS_TOKEN]); + $result->setExpiresIn($parsedResponse[Resources::OAUTH_EXPIRES_IN] + time()); + $result->setScope($parsedResponse[Resources::OAUTH_SCOPE]); + + return $result; + } + + /** + * Gets access token + * + * @return string + */ + public function getAccessToken() + { + return $this->_accessToken; + } + + + /** + * Sets access token + * + * @param string $accessToken OAuth access token + * + * @return none + */ + public function setAccessToken($accessToken) + { + $this->_accessToken = $accessToken; + } + + + /** + * Gets expired date of access token in unixdate + * + * @return int + * + */ + public function getExpiresIn() + { + return $this->_expiresIn; + } + + + /** + * Sets access token expires date + * + * @param int $expiresIn OAuth access token expire date + * + * @return none + */ + public function setExpiresIn($expiresIn) + { + $this->_expiresIn = $expiresIn; + } + + /** + * Gets access token scope + * + * @return string + * + */ + public function getScope() + { + return $this->_scope; + } + + + /** + * Sets access token scope + * + * @param string $scope OAuth access token scope + * + * @return none + */ + public function setScope($scope) + { + $this->_scope = $scope; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Models/RetentionPolicy.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Models/RetentionPolicy.php new file mode 100644 index 0000000..c52885f --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Models/RetentionPolicy.php @@ -0,0 +1,136 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Models; +use WindowsAzure\Common\Internal\Utilities; + +/** + * Holds elements of queue properties retention policy field. + * + * @category Microsoft + * @package WindowsAzure\Common\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class RetentionPolicy +{ + /** + * Indicates whether a retention policy is enabled for the storage service + * + * @var bool. + */ + private $_enabled; + + /** + * If $_enabled is true then this field indicates the number of days that metrics + * or logging data should be retained. All data older than this value will be + * deleted. The minimum value you can specify is 1; + * the largest value is 365 (one year) + * + * @var int + */ + private $_days; + + /** + * Creates object from $parsedResponse. + * + * @param array $parsedResponse XML response parsed into array. + * + * @return WindowsAzure\Common\Models\RetentionPolicy + */ + public static function create($parsedResponse) + { + $result = new RetentionPolicy(); + $result->setEnabled(Utilities::toBoolean($parsedResponse['Enabled'])); + if ($result->getEnabled()) { + $result->setDays(intval($parsedResponse['Days'])); + } + + return $result; + } + + /** + * Gets enabled. + * + * @return bool. + */ + public function getEnabled() + { + return $this->_enabled; + } + + /** + * Sets enabled. + * + * @param bool $enabled value to use. + * + * @return none. + */ + public function setEnabled($enabled) + { + $this->_enabled = $enabled; + } + + /** + * Gets days field. + * + * @return int + */ + public function getDays() + { + return $this->_days; + } + + /** + * Sets days field. + * + * @param int $days value to use. + * + * @return none + */ + public function setDays($days) + { + $this->_days = $days; + } + + /** + * Converts this object to array with XML tags + * + * @return array. + */ + public function toArray() + { + $array = array('Enabled' => Utilities::booleanToString($this->_enabled)); + if (isset($this->_days)) { + $array['Days'] = strval($this->_days); + } + + return $array; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Models/ServiceProperties.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Models/ServiceProperties.php new file mode 100644 index 0000000..52145ae --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/Models/ServiceProperties.php @@ -0,0 +1,136 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common\Models; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Models\Logging; +use WindowsAzure\Common\Models\Metrics; +use WindowsAzure\Common\Internal\Serialization\XmlSerializer; + +/** + * Encapsulates service properties + * + * @category Microsoft + * @package WindowsAzure\Common\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class ServiceProperties +{ + private $_logging; + private $_metrics; + public static $xmlRootName = 'StorageServiceProperties'; + + /** + * Creates ServiceProperties object from parsed XML response. + * + * @param array $parsedResponse XML response parsed into array. + * + * @return WindowsAzure\Common\Models\ServiceProperties. + */ + public static function create($parsedResponse) + { + $result = new ServiceProperties(); + $result->setLogging(Logging::create($parsedResponse['Logging'])); + $result->setMetrics(Metrics::create($parsedResponse['Metrics'])); + + return $result; + } + + /** + * Gets logging element. + * + * @return WindowsAzure\Common\Models\Logging. + */ + public function getLogging() + { + return $this->_logging; + } + + /** + * Sets logging element. + * + * @param WindowsAzure\Common\Models\Logging $logging new element. + * + * @return none. + */ + public function setLogging($logging) + { + $this->_logging = clone $logging; + } + + /** + * Gets metrics element. + * + * @return WindowsAzure\Common\Models\Metrics. + */ + public function getMetrics() + { + return $this->_metrics; + } + + /** + * Sets metrics element. + * + * @param WindowsAzure\Common\Models\Metrics $metrics new element. + * + * @return none. + */ + public function setMetrics($metrics) + { + $this->_metrics = clone $metrics; + } + + /** + * Converts this object to array with XML tags + * + * @return array. + */ + public function toArray() + { + return array( + 'Logging' => !empty($this->_logging) ? $this->_logging->toArray() : null, + 'Metrics' => !empty($this->_metrics) ? $this->_metrics->toArray() : null + ); + } + + /** + * Converts this current object to XML representation. + * + * @param XmlSerializer $xmlSerializer The XML serializer. + * + * @return string + */ + public function toXml($xmlSerializer) + { + $properties = array(XmlSerializer::ROOT_NAME => self::$xmlRootName); + + return $xmlSerializer->serialize($this->toArray(), $properties); + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/ServiceException.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/ServiceException.php new file mode 100644 index 0000000..b79a129 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/ServiceException.php @@ -0,0 +1,84 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common; +use WindowsAzure\Common\Internal\Resources; + +/** + * Fires when the response code is incorrect. + * + * @category Microsoft + * @package WindowsAzure\Common + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class ServiceException extends \LogicException +{ + private $_error; + private $_reason; + + /** + * Constructor + * + * @param string $errorCode status error code. + * @param string $error string value of the error code. + * @param string $reason detailed message for the error. + * + * @return WindowsAzure\Common\ServiceException + */ + public function __construct($errorCode, $error = null, $reason = null) + { + parent::__construct( + sprintf(Resources::AZURE_ERROR_MSG, $errorCode, $error, $reason) + ); + $this->code = $errorCode; + $this->_error = $error; + $this->_reason = $reason; + } + + /** + * Gets error text. + * + * @return string + */ + public function getErrorText() + { + return $this->_error; + } + + /** + * Gets detailed error reason. + * + * @return string + */ + public function getErrorReason() + { + return $this->_reason; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/ServicesBuilder.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/ServicesBuilder.php new file mode 100644 index 0000000..09d9c67 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Common/ServicesBuilder.php @@ -0,0 +1,503 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Common; +use WindowsAzure\Blob\BlobRestProxy; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Validate; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Http\HttpClient; +use WindowsAzure\Common\Internal\Filters\DateFilter; +use WindowsAzure\Common\Internal\Filters\HeadersFilter; +use WindowsAzure\Common\Internal\Filters\AuthenticationFilter; +use WindowsAzure\Common\Internal\Filters\WrapFilter; +use WindowsAzure\Common\Internal\InvalidArgumentTypeException; +use WindowsAzure\Common\Internal\Serialization\XmlSerializer; +use WindowsAzure\Common\Internal\Authentication\SharedKeyAuthScheme; +use WindowsAzure\Common\Internal\Authentication\TableSharedKeyLiteAuthScheme; +use WindowsAzure\Common\Internal\StorageServiceSettings; +use WindowsAzure\Common\Internal\ServiceManagementSettings; +use WindowsAzure\Common\Internal\ServiceBusSettings; +use WindowsAzure\Common\Internal\MediaServicesSettings; +use WindowsAzure\Queue\QueueRestProxy; +use WindowsAzure\ServiceBus\ServiceBusRestProxy; +use WindowsAzure\ServiceBus\Internal\WrapRestProxy; +use WindowsAzure\ServiceManagement\ServiceManagementRestProxy; +use WindowsAzure\Table\TableRestProxy; +use WindowsAzure\Table\Internal\AtomReaderWriter; +use WindowsAzure\Table\Internal\MimeReaderWriter; +use WindowsAzure\MediaServices\MediaServicesRestProxy; +use WindowsAzure\Common\Internal\OAuthRestProxy; +use WindowsAzure\Common\Internal\Authentication\OAuthScheme; + + +/** + * Builds azure service objects. + * + * @category Microsoft + * @package WindowsAzure\Common + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class ServicesBuilder +{ + /** + * @var ServicesBuilder + */ + private static $_instance = null; + + /** + * Gets the HTTP client used in the REST services construction. + * + * @return WindowsAzure\Common\Internal\Http\IHttpClient + */ + protected function httpClient() + { + return new HttpClient(); + } + + /** + * Gets the serializer used in the REST services construction. + * + * @return WindowsAzure\Common\Internal\Serialization\ISerializer + */ + protected function serializer() + { + return new XmlSerializer(); + } + + /** + * Gets the MIME serializer used in the REST services construction. + * + * @return \WindowsAzure\Table\Internal\IMimeReaderWriter + */ + protected function mimeSerializer() + { + return new MimeReaderWriter(); + } + + /** + * Gets the Atom serializer used in the REST services construction. + * + * @return \WindowsAzure\Table\Internal\IAtomReaderWriter + */ + protected function atomSerializer() + { + return new AtomReaderWriter(); + } + + /** + * Gets the Queue authentication scheme. + * + * @param string $accountName The account name. + * @param string $accountKey The account key. + * + * @return \WindowsAzure\Common\Internal\Authentication\StorageAuthScheme + */ + protected function queueAuthenticationScheme($accountName, $accountKey) + { + return new SharedKeyAuthScheme($accountName, $accountKey); + } + + /** + * Gets the Blob authentication scheme. + * + * @param string $accountName The account name. + * @param string $accountKey The account key. + * + * @return \WindowsAzure\Common\Internal\Authentication\StorageAuthScheme + */ + protected function blobAuthenticationScheme($accountName, $accountKey) + { + return new SharedKeyAuthScheme($accountName, $accountKey); + } + + /** + * Gets the Table authentication scheme. + * + * @param string $accountName The account name. + * @param string $accountKey The account key. + * + * @return TableSharedKeyLiteAuthScheme + */ + protected function tableAuthenticationScheme($accountName, $accountKey) + { + return new TableSharedKeyLiteAuthScheme($accountName, $accountKey); + } + + /** + * Builds a WRAP client. + * + * @param string $wrapEndpointUri The WRAP endpoint uri. + * + * @return WindowsAzure\ServiceBus\Internal\IWrap + */ + protected function createWrapService($wrapEndpointUri) + { + $httpClient = $this->httpClient(); + $wrapWrapper = new WrapRestProxy($httpClient, $wrapEndpointUri); + + return $wrapWrapper; + } + + /** + * Builds a queue object. + * + * @param string $connectionString The configuration connection string. + * + * @return WindowsAzure\Queue\Internal\IQueue + */ + public function createQueueService($connectionString) + { + $settings = StorageServiceSettings::createFromConnectionString( + $connectionString + ); + + $httpClient = $this->httpClient(); + $serializer = $this->serializer(); + $uri = Utilities::tryAddUrlScheme( + $settings->getQueueEndpointUri() + ); + + $queueWrapper = new QueueRestProxy( + $httpClient, + $uri, + $settings->getName(), + $serializer + ); + + // Adding headers filter + $headers = array( + Resources::USER_AGENT => Resources::SDK_USER_AGENT, + ); + + $headers[Resources::X_MS_VERSION] = Resources::STORAGE_API_LATEST_VERSION; + + $headersFilter = new HeadersFilter($headers); + $queueWrapper = $queueWrapper->withFilter($headersFilter); + + // Adding date filter + $dateFilter = new DateFilter(); + $queueWrapper = $queueWrapper->withFilter($dateFilter); + + // Adding authentication filter + $authFilter = new AuthenticationFilter( + $this->queueAuthenticationScheme( + $settings->getName(), + $settings->getKey() + ) + ); + + $queueWrapper = $queueWrapper->withFilter($authFilter); + + return $queueWrapper; + } + + /** + * Builds a blob object. + * + * @param string $connectionString The configuration connection string. + * + * @return WindowsAzure\Blob\Internal\IBlob + */ + public function createBlobService($connectionString) + { + $settings = StorageServiceSettings::createFromConnectionString( + $connectionString + ); + + $httpClient = $this->httpClient(); + $serializer = $this->serializer(); + $uri = Utilities::tryAddUrlScheme( + $settings->getBlobEndpointUri() + ); + + $blobWrapper = new BlobRestProxy( + $httpClient, + $uri, + $settings->getName(), + $serializer + ); + + // Adding headers filter + $headers = array( + Resources::USER_AGENT => Resources::SDK_USER_AGENT, + ); + + $headers[Resources::X_MS_VERSION] = Resources::STORAGE_API_LATEST_VERSION; + + $headersFilter = new HeadersFilter($headers); + $blobWrapper = $blobWrapper->withFilter($headersFilter); + + // Adding date filter + $dateFilter = new DateFilter(); + $blobWrapper = $blobWrapper->withFilter($dateFilter); + + $authFilter = new AuthenticationFilter( + $this->blobAuthenticationScheme( + $settings->getName(), + $settings->getKey() + ) + ); + + $blobWrapper = $blobWrapper->withFilter($authFilter); + + return $blobWrapper; + } + + /** + * Builds a table object. + * + * @param string $connectionString The configuration connection string. + * + * @return WindowsAzure\Table\Internal\ITable + */ + public function createTableService($connectionString) + { + $settings = StorageServiceSettings::createFromConnectionString( + $connectionString + ); + + $httpClient = $this->httpClient(); + $atomSerializer = $this->atomSerializer(); + $mimeSerializer = $this->mimeSerializer(); + $serializer = $this->serializer(); + $uri = Utilities::tryAddUrlScheme( + $settings->getTableEndpointUri() + ); + + $tableWrapper = new TableRestProxy( + $httpClient, + $uri, + $atomSerializer, + $mimeSerializer, + $serializer + ); + + // Adding headers filter + $headers = array(); + $latestServicesVersion = Resources::STORAGE_API_LATEST_VERSION; + $currentVersion = Resources::DATA_SERVICE_VERSION_VALUE; + $maxVersion = Resources::MAX_DATA_SERVICE_VERSION_VALUE; + $accept = Resources::ACCEPT_HEADER_VALUE; + $acceptCharset = Resources::ACCEPT_CHARSET_VALUE; + $userAgent = Resources::SDK_USER_AGENT; + + $headers[Resources::X_MS_VERSION] = $latestServicesVersion; + $headers[Resources::DATA_SERVICE_VERSION] = $currentVersion; + $headers[Resources::MAX_DATA_SERVICE_VERSION] = $maxVersion; + $headers[Resources::MAX_DATA_SERVICE_VERSION] = $maxVersion; + $headers[Resources::ACCEPT_HEADER] = $accept; + $headers[Resources::ACCEPT_CHARSET] = $acceptCharset; + $headers[Resources::USER_AGENT] = $userAgent; + + $headersFilter = new HeadersFilter($headers); + $tableWrapper = $tableWrapper->withFilter($headersFilter); + + // Adding date filter + $dateFilter = new DateFilter(); + $tableWrapper = $tableWrapper->withFilter($dateFilter); + + // Adding authentication filter + $authFilter = new AuthenticationFilter( + $this->tableAuthenticationScheme( + $settings->getName(), + $settings->getKey() + ) + ); + + $tableWrapper = $tableWrapper->withFilter($authFilter); + + return $tableWrapper; + } + + /** + * Builds a Service Bus object. + * + * @param string $connectionString The configuration connection string. + * + * @return WindowsAzure\ServiceBus\Internal\IServiceBus + */ + public function createServiceBusService($connectionString) + { + $settings = ServiceBusSettings::createFromConnectionString( + $connectionString + ); + + $httpClient = $this->httpClient(); + $serializer = $this->serializer(); + $serviceBusWrapper = new ServiceBusRestProxy( + $httpClient, + $settings->getServiceBusEndpointUri(), + $serializer + ); + + // Adding headers filter + $headers = array( + Resources::USER_AGENT => Resources::SDK_USER_AGENT, + ); + + $headersFilter = new HeadersFilter($headers); + $serviceBusWrapper = $serviceBusWrapper->withFilter($headersFilter); + + $wrapFilter = new WrapFilter( + $settings->getWrapEndpointUri(), + $settings->getWrapName(), + $settings->getWrapPassword(), + $this->createWrapService($settings->getWrapEndpointUri()) + ); + + return $serviceBusWrapper->withFilter($wrapFilter); + } + + /** + * Builds a service management object. + * + * @param string $connectionString The configuration connection string. + * + * @return WindowsAzure\ServiceManagement\Internal\IServiceManagement + */ + public function createServiceManagementService($connectionString) + { + $settings = ServiceManagementSettings::createFromConnectionString( + $connectionString + ); + + $certificatePath = $settings->getCertificatePath(); + $httpClient = new HttpClient($certificatePath); + $serializer = $this->serializer(); + $uri = Utilities::tryAddUrlScheme( + $settings->getEndpointUri(), + Resources::HTTPS_SCHEME + ); + + $serviceManagementWrapper = new ServiceManagementRestProxy( + $httpClient, + $settings->getSubscriptionId(), + $uri, + $serializer + ); + + // Adding headers filter + $headers = array( + Resources::USER_AGENT => Resources::SDK_USER_AGENT + ); + + $headers[Resources::X_MS_VERSION] = Resources::SM_API_LATEST_VERSION; + + $headersFilter = new HeadersFilter($headers); + $serviceManagementWrapper = $serviceManagementWrapper->withFilter( + $headersFilter + ); + + return $serviceManagementWrapper; + } + + /** + * Builds a media services object. + * + * @param WindowsAzure\Common\Internal\MediaServicesSettings $settings The media + * services configuration settings. + * + * @return WindowsAzure\MediaServices\Internal\IMediaServices + */ + public function createMediaServicesService($settings) + { + Validate::isA( + $settings, + 'WindowsAzure\Common\Internal\MediaServicesSettings', + 'settings' + ); + + $httpClient = new HttpClient(); + $serializer = $this->serializer(); + $uri = Utilities::tryAddUrlScheme( + $settings->getEndpointUri(), + Resources::HTTPS_SCHEME + ); + + $mediaServicesWrapper = new MediaServicesRestProxy( + $httpClient, + $uri, + $settings->getAccountName(), + $serializer + ); + + // Adding headers filter + $xMSVersion = Resources::MEDIA_SERVICES_API_LATEST_VERSION; + $dataVersion = Resources::MEDIA_SERVICES_DATA_SERVICE_VERSION_VALUE; + $dataMaxVersion = Resources::MEDIA_SERVICES_MAX_DATA_SERVICE_VERSION_VALUE; + $accept = Resources::ACCEPT_HEADER_VALUE; + $contentType = Resources::ATOM_ENTRY_CONTENT_TYPE; + $userAgent = Resources::SDK_USER_AGENT; + + $headers = array( + Resources::X_MS_VERSION => $xMSVersion, + Resources::DATA_SERVICE_VERSION => $dataVersion, + Resources::MAX_DATA_SERVICE_VERSION => $dataMaxVersion, + Resources::ACCEPT_HEADER => $accept, + Resources::CONTENT_TYPE => $contentType, + Resources::USER_AGENT => $userAgent, + ); + + $headersFilter = new HeadersFilter($headers); + $mediaServicesWrapper = $mediaServicesWrapper->withFilter($headersFilter); + + // Adding OAuth filter + $oauthService = new OAuthRestProxy( + new HttpClient(), + $settings->getOAuthEndpointUri() + ); + $authentification = new OAuthScheme( + $settings->getAccountName(), + $settings->getAccessKey(), + Resources::OAUTH_GT_CLIENT_CREDENTIALS, + Resources::MEDIA_SERVICES_OAUTH_SCOPE, + $oauthService + ); + $authentificationFilter = new AuthenticationFilter($authentification); + $mediaServicesWrapper = $mediaServicesWrapper->withFilter( + $authentificationFilter + ); + + return $mediaServicesWrapper; + } + + /** + * Gets the static instance of this class. + * + * @return ServicesBuilder + */ + public static function getInstance() + { + if (!isset(self::$instance)) { + self::$_instance = new ServicesBuilder(); + } + + return self::$_instance; + } +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/MediaServices/Internal/IMediaServices.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/MediaServices/Internal/IMediaServices.php new file mode 100644 index 0000000..063f026 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/MediaServices/Internal/IMediaServices.php @@ -0,0 +1,446 @@ + + * @copyright Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\MediaServices\Internal; +use WindowsAzure\Common\Internal\FilterableService; + +/** + * This interface has all REST APIs provided by Windows Azure for Blob service. + * + * @category Microsoft + * @package WindowsAzure\MediaServices\Internal + * @author Azure PHP SDK + * @copyright Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd135733.aspx + */ +interface IMediaServices extends FilterableService +{ + /** + * Create new asset + * + * @param WindowsAzure\MediaServices\Models\Asset $asset Asset data + * + * @return WindowsAzure\MediaServices\Models\Asset Created asset + */ + public function createAsset($asset); + + /** + * Get asset + * + * @param WindowsAzure\MediaServices\Models\Asset|string $asset Asset data or + * asset Id + * + * @return WindowsAzure\MediaServices\Models\Asset + */ + public function getAsset($asset); + + /** + * Get asset list + * + * @return array + */ + public function getAssetList(); + + /** + * Get asset locators + * + * @param WindowsAzure\MediaServices\Models\Asset|string $asset Asset data or + * asset Id + * + * @return array + */ + public function getAssetLocators($asset); + + /** + * Get parent assets of asset + * + * @param WindowsAzure\MediaServices\Models\Asset|string $asset Asset data or + * asset Id + * + * @return array + */ + public function getAssetParentAssets($asset); + + /** + * Get assetFiles of asset + * + * @param WindowsAzure\MediaServices\Models\Asset|string $asset Asset data or + * asset Id + * + * @return array + */ + public function getAssetAssetFileList($asset); + + /** + * Get storage account of asset + * + * @param WindowsAzure\MediaServices\Models\Asset|string $asset Asset data or + * asset Id + * + * @return WindowsAzure\MediaServices\Models\StorageAccount + */ + public function getAssetStorageAccount($asset); + + /** + * Update asset + * + * @param WindowsAzure\MediaServices\Models\Asset $asset New asset data with + * valid id + * + * @return none + */ + public function updateAsset($asset); + + /** + * Delete asset + * + * @param WindowsAzure\MediaServices\Models\Asset|string $asset Asset data or + * asset Id + * + * @return none + */ + public function deleteAsset($asset); + + /** + * Create new access policy + * + * @param WindowsAzure\MediaServices\Models\AccessPolicy $accessPolicy Access + * policy data + * + * @return WindowsAzure\MediaServices\Models\AccessPolicy + */ + public function createAccessPolicy($accessPolicy); + + /** + * Get AccessPolicy. + * + * @param WindowsAzure\MediaServices\Models\AccessPolicy|string $accessPolicy A + * AccessPolicy data or AccessPolicy Id + * + * @return WindowsAzure\MediaServices\Models\AccessPolicy + */ + public function getAccessPolicy($accessPolicy); + + /** + * Get list of AccessPolicies. + * + * @return array + */ + public function getAccessPolicyList(); + + /** + * Delete access policy + * + * @param WindowsAzure\MediaServices\Models\AccessPolicy|string $accessPolicy A + * Access policy data or access policy Id + * + * @return none + */ + public function deleteAccessPolicy($accessPolicy); + + /** + * Create new locator + * + * @param WindowsAzure\MediaServices\Models\Locator $locator Locator data + * + * @return WindowsAzure\MediaServices\Models\Locator + */ + public function createLocator($locator); + + /** + * Get Locator. + * + * @param WindowsAzure\MediaServices\Models\Locator|string $locator Locator data + * or locator Id + * + * @return WindowsAzure\MediaServices\Models\Locator + */ + public function getLocator($locator); + + /** + * Get Locator access policy. + * + * @param WindowsAzure\MediaServices\Models\Locator|string $locator Locator data + * or locator Id + * + * @return WindowsAzure\MediaServices\Models\Locator + */ + public function getLocatorAccessPolicy($locator); + + /** + * Get Locator asset. + * + * @param WindowsAzure\MediaServices\Models\Locator|string $locator Locator data + * or locator Id + * + * @return WindowsAzure\MediaServices\Models\Locator + */ + public function getLocatorAsset($locator); + + /** + * Get list of Locators. + * + * @return array + */ + public function getLocatorList(); + + /** + * Update locator + * + * @param WindowsAzure\MediaServices\Models\Locator $locator New locator data + * with valid id + * + * @return none + */ + public function updateLocator($locator); + + /** + * Delete locator + * + * @param WindowsAzure\MediaServices\Models\Locator|string $locator Asset data + * or asset Id + * + * @return none + */ + public function deleteLocator($locator); + + /** + * Generate file info for all files in asset + * + * @param WindowsAzure\MediaServices\Models\Asset|string $asset Asset data or + * asset Id + * + * @return none + */ + public function createFileInfos($asset); + + /** + * Get asset file. + * + * @param WindowsAzure\MediaServices\Models\AssetFile|string $assetFile AssetFile + * data or assetFile Id + * + * @return WindowsAzure\MediaServices\Models\AssetFile + */ + public function getAssetFile($assetFile); + + + /** + * Get list of all asset files. + * + * @return array + */ + public function getAssetFileList(); + + /** + * Update asset file + * + * @param WindowsAzure\MediaServices\Models\AssetFile $assetFile New AssetFile + * data + * + * @return none + */ + public function updateAssetFile($assetFile); + + /** + * Upload asset file to storage. + * + * @param WindowsAzure\MediaServices\Models\Locator $locator Write locator for + * file upload + * + * @param string $name Uploading filename + * @param string $body Uploading content + * + * @return none + */ + public function uploadAssetFile($locator, $name, $body); + + /** + * Create a job. + * + * @param WindowsAzure\MediaServices\Models\Job $job Job data + * @param array $inputAssets Input assets list + * @param array $tasks Performed tasks + * array (optional) + * + * @return array + */ + public function createJob($job, $inputAssets, $tasks = null); + + /** + * Get Job. + * + * @param WindowsAzure\MediaServices\Models\Job|string $job Job data or job Id + * + * @return WindowsAzure\MediaServices\Models\Job + */ + public function getJob($job); + + /** + * Get list of Jobs. + * + * @return array + */ + public function getJobList(); + + /** + * Get status of a job + * + * @param WindowsAzure\MediaServices\Models\Job|string $job Job data or job Id + * + * @return string + */ + public function getJobStatus($job); + + /** + * Get job tasks. + * + * @param WindowsAzure\MediaServices\Models\Job|string $job Job data or job Id + * + * @return array + */ + public function getJobTasks($job); + + + /** + * Get job input assets. + * + * @param WindowsAzure\MediaServices\Models\Job|string $job Job data or job Id + * + * @return array + */ + public function getJobInputMediaAssets($job); + + /** + * Get job output assets. + * + * @param WindowsAzure\MediaServices\Models\Job|string $job Job data or job Id + * + * @return array + */ + public function getJobOutputMediaAssets($job); + + /** + * Cancel a job + * + * @param WindowsAzure\MediaServices\Models\Job|string $job Job data or job Id + * + * @return none + */ + public function cancelJob($job); + + /** + * Delete job + * + * @param WindowsAzure\MediaServices\Models\Job|string $job Job data or job Id + * + * @return none + */ + public function deleteJob($job); + + /** + * Get list of tasks. + * + * @return array + */ + public function getTaskList(); + + /** + * Create a job. + * + * @param WindowsAzure\MediaServices\Models\JobTemplate $jobTemplate Job + * template data + * + * @param array $taskTemplates Performed + * tasks template array + * + * @return array + */ + public function createJobTemplate($jobTemplate, $taskTemplates); + + /** + * Get job template. + * + * @param WindowsAzure\MediaServices\Models\JobTemplate|string $jobTemplate Job + * template data or jobTemplate Id + * + * @return WindowsAzure\MediaServices\Models\JobTemplate + */ + public function getJobTemplate($jobTemplate); + + /** + * Get list of Job Templates. + * + * @return array + */ + public function getJobTemplateList(); + + /** + * Get task templates for job template. + * + * @param WindowsAzure\MediaServices\Models\JobTemplate|string $jobTemplate Job + * template data or jobTemplate Id + * + * @return array + */ + public function getJobTemplateTaskTemplateList($jobTemplate); + + + /** + * Delete job template + * + * @param WindowsAzure\MediaServices\Models\JobTemplate|string $jobTemplate Job + * template data or job template Id + * + * @return none + */ + public function deleteJobTemplate($jobTemplate); + + /** + * Get list of task templates. + * + * @return array + */ + public function getTaskTemplateList(); + + /** + * Get list of all media processors asset files + * + * @return array + */ + public function getMediaProcessors(); + + /** + * Get media processor by name with latest version + * + * @param string $name Media processor name + * + * @return WindowsAzure\MediaServices\Models\JobTemplate\MediaProcessor + */ + public function getLatestMediaProcessor($name); +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/MediaServices/MediaServicesRestProxy.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/MediaServices/MediaServicesRestProxy.php new file mode 100644 index 0000000..77aab47 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/MediaServices/MediaServicesRestProxy.php @@ -0,0 +1,1484 @@ + + * @copyright Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\MediaServices; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Validate; +use WindowsAzure\Common\Internal\Http\HttpCallContext; +use WindowsAzure\Common\Models\ServiceProperties; +use WindowsAzure\Common\Internal\ServiceRestProxy; +use WindowsAzure\MediaServices\Internal\IMediaServices; +use WindowsAzure\MediaServices\Models\Asset; +use WindowsAzure\MediaServices\Models\AccessPolicy; +use WindowsAzure\MediaServices\Models\Locator; +use WindowsAzure\MediaServices\Models\AssetFile; +use WindowsAzure\MediaServices\Models\Job; +use WindowsAzure\MediaServices\Models\Task; +use WindowsAzure\MediaServices\Models\MediaProcessor; +use WindowsAzure\MediaServices\Models\JobTemplate; +use WindowsAzure\MediaServices\Models\TaskTemplate; +use WindowsAzure\MediaServices\Models\ContentProperties; +use WindowsAzure\Common\Internal\Atom\Feed; +use WindowsAzure\Common\Internal\Atom\Entry; +use WindowsAzure\Common\Internal\Atom\Content; +use WindowsAzure\Common\Internal\Atom\AtomLink; +use WindowsAzure\Blob\Models\BlobType; +use WindowsAzure\Common\Internal\Http\HttpClient; +use WindowsAzure\Common\Internal\Http\Url; +use WindowsAzure\Common\Internal\Http\BatchRequest; +use WindowsAzure\Common\Internal\Http\BatchResponse; +use WindowsAzure\MediaServices\Models\StorageAccount; + +/** + * This class constructs HTTP requests and receive HTTP responses for media services + * service layer. + * + * @category Microsoft + * @package WindowsAzure\MediaServices + * @author Azure PHP SDK + * @copyright Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class MediaServicesRestProxy extends ServiceRestProxy implements IMediaServices +{ + /** + * Headers used in batch requests + * + * @var array + */ + private $_batchHeaders = array( + Resources::DATA_SERVICE_VERSION => Resources::MEDIA_SERVICES_DATA_SERVICE_VERSION_VALUE, + Resources::MAX_DATA_SERVICE_VERSION => Resources::MEDIA_SERVICES_MAX_DATA_SERVICE_VERSION_VALUE, + Resources::ACCEPT_HEADER => Resources::ACCEPT_HEADER_VALUE, + Resources::CONTENT_TYPE => Resources::XML_ATOM_CONTENT_TYPE + ); + + /** + * Sends HTTP request with the specified parameters. + * + * @param string $method HTTP method used in the request + * @param array $headers HTTP headers. + * @param array $queryParams URL query parameters. + * @param array $postParameters The HTTP POST parameters. + * @param string $path URL path + * @param int $statusCode Expected status code received in the response + * @param string $body Request body + * + * @return \HTTP_Request2_Response + */ + protected function send( + $method, + $headers, + $queryParams, + $postParameters, + $path, + $statusCode, + $body = Resources::EMPTY_STRING + ) { + // Add redirect to expected results + if (!is_array($statusCode)) { + $statusCode = array($statusCode, ); + } + array_push($statusCode, Resources::STATUS_MOVED_PERMANENTLY); + + $response = parent::send( + $method, + $headers, + $queryParams, + $postParameters, + $path, + $statusCode, + $body + ); + + // Set new URI endpoint if we get redirect response and perform query + if ($response->getStatus() == Resources::STATUS_MOVED_PERMANENTLY) { + $this->setUri($response->getHeader('location')); + array_pop($statusCode); + + $response = parent::send( + $method, + $headers, + $queryParams, + $postParameters, + $path, + $statusCode, + $body + ); + } + + + return $response; + } + + /** + * Wraps media services entity with Atom entry + * + * @param object $entity Media services entity + * @param array $links AtomLinks to other media services entities + * + * @return XML string representing Atom Entry + */ + protected function wrapAtomEntry($entity, $links = null) + { + Validate::notNull($entity, 'entity'); + + $properties = new ContentProperties(); + $properties->setPropertiesFromObject($entity); + + $propertyWriter = new \XMLWriter(); + $propertyWriter->openMemory(); + $properties->writeXml($propertyWriter); + + $content = new Content(); + $content->setType(Resources::XML_CONTENT_TYPE); + $content->setText($propertyWriter->outputMemory()); + + $atomEntry = new Entry(); + $atomEntry->setContent($content); + + if ($links) { + Validate::isArray($links, 'links'); + + $atomEntry->setLink($links); + } + + $xmlWriter = new \XMLWriter(); + $xmlWriter->openMemory(); + $atomEntry->writeXml($xmlWriter); + + return $xmlWriter->outputMemory(); + } + + /** + * Extract media service entity from Atom Entry object + * + * @param WindowsAzure\Common\Internal\Atom\Entry $entry Atom Entry containing + * properties of media services object + * + * @return array + */ + protected function getPropertiesFromAtomEntry($entry) + { + Validate::notNull($entry, 'entry'); + Validate::isA($entry, 'WindowsAzure\Common\Internal\Atom\Entry', 'entry'); + + $result = array(); + $content = $entry->getContent(); + if (!empty($content)) { + $propertiesXml = $content->getXml()->children( + Resources::DSM_XML_NAMESPACE + ); + + $properties = new ContentProperties(); + $properties->fromXml($propertiesXml); + $result = $properties->getProperties(); + } + + return $result; + } + + /** + * Get array of properties of atom entites passed via feed or single entry + * + * @param string $xmlString Atom xml + * + * @return array + */ + protected function getEntryList($xmlString) + { + $xml = simplexml_load_string($xmlString); + + if ($xml->getName() == Resources::ENTRY) { + $entry = new Entry(); + $entry->fromXml($xml); + $entries = array($entry); + } else { + $feed = new Feed(); + $feed->parseXml($xmlString); + $entries = $feed->getEntry(); + } + + $result = array(); + if (is_array($entries)) { + foreach ($entries as $entry) { + $properties = $this->getPropertiesFromAtomEntry($entry); + if (!empty($properties)) { + $result[] = $properties; + } + } + } + + return $result; + } + + /** + * Create entity + * + * @param object $entity Entity data + * @param string $path REST path + * + * @return array Created entity data + */ + private function _createEntity($entity, $path) + { + $method = Resources::HTTP_POST; + $headers = array(); + $postParams = array(); + $queryParams = array(); + $statusCode = Resources::STATUS_CREATED; + $body = $this->wrapAtomEntry($entity); + + $response = $this->send( + $method, + $headers, + $postParams, + $queryParams, + $path, + $statusCode, + $body + ); + + $entry = new Entry(); + $entry->parseXml($response->getBody()); + return $this->getPropertiesFromAtomEntry($entry); + } + + /** + * Get entity from Azure + * + * @param string $path REST path + * + * @return array Entity data + */ + private function _getEntity($path) + { + $method = Resources::HTTP_GET; + $headers = array(); + $postParams = array(); + $queryParams = array(); + $statusCode = Resources::STATUS_OK; + + $response = $this->send( + $method, + $headers, + $postParams, + $queryParams, + $path, + $statusCode + ); + + $entry = new Entry(); + $entry->parseXml($response->getBody()); + + return $this->getPropertiesFromAtomEntry($entry); + } + + /** + * Create entity list + * + * @param string $path REST path + * + * @return array Entities list data + */ + private function _getEntityList($path) + { + $method = Resources::HTTP_GET; + $headers = array(); + $postParams = array(); + $queryParams = array(); + $statusCode = Resources::STATUS_OK; + + $response = $this->send( + $method, + $headers, + $postParams, + $queryParams, + $path, + $statusCode + ); + + return $this->getEntryList($response->getBody()); + } + + /** + * Update entity + * + * @param object $entity Entity data + * @param string $path REST path + * + * @return none + */ + private function _updateEntity($entity, $path) + { + $method = Resources::HTTP_MERGE; + $headers = array(); + $postParams = array(); + $queryParams = array(); + $statusCode = Resources::STATUS_NO_CONTENT; + $body = $this->wrapAtomEntry($entity); + + $this->send( + $method, + $headers, + $postParams, + $queryParams, + $path, + $statusCode, + $body + ); + } + + /** + * Delete entity + * + * @param string $path REST path + * + * @return none + */ + private function _deleteEntity($path) + { + $method = Resources::HTTP_DELETE; + $headers = array(); + $postParams = array(); + $queryParams = array(); + $statusCode = Resources::STATUS_NO_CONTENT; + + $this->send( + $method, + $headers, + $postParams, + $queryParams, + $path, + $statusCode + ); + } + + /** + * Create new asset + * + * @param WindowsAzure\MediaServices\Models\Asset $asset Asset data + * + * @return WindowsAzure\MediaServices\Models\Asset Created asset + */ + public function createAsset($asset) + { + Validate::isA($asset, 'WindowsAzure\Mediaservices\Models\Asset', 'asset'); + + return Asset::createFromOptions($this->_createEntity($asset, 'Assets')); + } + + /** + * Get asset + * + * @param WindowsAzure\MediaServices\Models\Asset|string $asset Asset data or + * asset Id + * + * @return WindowsAzure\MediaServices\Models\Asset + */ + public function getAsset($asset) + { + $assetId = Utilities::getEntityId( + $asset, + 'WindowsAzure\MediaServices\Models\Asset' + ); + + return Asset::createFromOptions($this->_getEntity("Assets('{$assetId}')")); + } + + /** + * Get asset list + * + * @return array + */ + public function getAssetList() + { + $propertyList = $this->_getEntityList("Assets"); + $result = array(); + + foreach ($propertyList as $properties) { + $result[] = Asset::createFromOptions($properties); + } + + return $result; + } + + /** + * Get asset locators + * + * @param WindowsAzure\MediaServices\Models\Asset|string $asset Asset data or + * asset Id + * + * @return array + */ + public function getAssetLocators($asset) + { + $assetId = Utilities::getEntityId( + $asset, + 'WindowsAzure\MediaServices\Models\Asset' + ); + + $propertyList = $this->_getEntityList("Assets('{$assetId}')/Locators"); + $result = array(); + + foreach ($propertyList as $properties) { + $result[] = Locator::createFromOptions($properties); + } + + return $result; + } + + /** + * Get parent assets of asset + * + * @param WindowsAzure\MediaServices\Models\Asset|string $asset Asset data or + * asset Id + * + * @return array + */ + public function getAssetParentAssets($asset) + { + $assetId = Utilities::getEntityId( + $asset, + 'WindowsAzure\MediaServices\Models\Asset' + ); + + $propertyList = $this->_getEntityList("Assets('{$assetId}')/ParentAssets"); + $result = array(); + + foreach ($propertyList as $properties) { + $result[] = Asset::createFromOptions($properties); + } + + return $result; + } + + /** + * Get assetFiles of asset + * + * @param WindowsAzure\MediaServices\Models\Asset|string $asset Asset data or + * asset Id + * + * @return array + */ + public function getAssetAssetFileList($asset) + { + $assetId = Utilities::getEntityId( + $asset, + 'WindowsAzure\MediaServices\Models\Asset' + ); + + $propertyList = $this->_getEntityList("Assets('{$assetId}')/Files"); + $result = array(); + + foreach ($propertyList as $properties) { + $result[] = AssetFile::createFromOptions($properties); + } + + return $result; + } + + /** + * Get storage account of asset + * + * @param WindowsAzure\MediaServices\Models\Asset|string $asset Asset data or + * asset Id + * + * @return WindowsAzure\MediaServices\Models\StorageAccount + */ + public function getAssetStorageAccount($asset) + { + $assetId = Utilities::getEntityId( + $asset, + 'WindowsAzure\MediaServices\Models\Asset' + ); + + return StorageAccount::createFromOptions( + $this->_getEntity("Assets('{$assetId}')/StorageAccount") + ); + } + + /** + * Update asset + * + * @param WindowsAzure\MediaServices\Models\Asset $asset New asset data with + * valid id + * + * @return none + */ + public function updateAsset($asset) + { + Validate::isA($asset, 'WindowsAzure\MediaServices\Models\Asset', 'asset'); + + $this->_updateEntity($asset, "Assets('{$asset->getId()}')"); + } + + /** + * Delete asset + * + * @param WindowsAzure\MediaServices\Models\Asset|string $asset Asset data or + * asset Id + * + * @return none + */ + public function deleteAsset($asset) + { + $assetId = Utilities::getEntityId( + $asset, + 'WindowsAzure\MediaServices\Models\Asset' + ); + + $this->_deleteEntity("Assets('{$assetId}')"); + } + + /** + * Create new access policy + * + * @param WindowsAzure\MediaServices\Models\AccessPolicy $accessPolicy Access + * policy data + * + * @return WindowsAzure\MediaServices\Models\AccessPolicy + */ + public function createAccessPolicy($accessPolicy) + { + Validate::isA( + $accessPolicy, + 'WindowsAzure\Mediaservices\Models\AccessPolicy', + 'accessPolicy' + ); + + return AccessPolicy::createFromOptions( + $this->_createEntity($accessPolicy, 'AccessPolicies') + ); + } + + /** + * Get AccessPolicy. + * + * @param WindowsAzure\MediaServices\Models\AccessPolicy|string $accessPolicy A + * AccessPolicy data or AccessPolicy Id + * + * @return WindowsAzure\MediaServices\Models\AccessPolicy + */ + public function getAccessPolicy($accessPolicy) + { + $accessPolicyId = Utilities::getEntityId( + $accessPolicy, + 'WindowsAzure\Mediaservices\Models\AccessPolicy' + ); + + return AccessPolicy::createFromOptions( + $this->_getEntity("AccessPolicies('{$accessPolicyId}')") + ); + } + + /** + * Get list of AccessPolicies. + * + * @return array + */ + public function getAccessPolicyList() + { + $propertyList = $this->_getEntityList('AccessPolicies'); + $result = array(); + + foreach ($propertyList as $properties) { + $result[] = AccessPolicy::createFromOptions($properties); + } + + return $result; + } + + /** + * Delete access policy + * + * @param WindowsAzure\MediaServices\Models\AccessPolicy|string $accessPolicy A + * Access policy data or access policy Id + * + * @return none + */ + public function deleteAccessPolicy($accessPolicy) + { + $accessPolicyId = Utilities::getEntityId( + $accessPolicy, + 'WindowsAzure\Mediaservices\Models\AccessPolicy' + ); + + $this->_deleteEntity("AccessPolicies('{$accessPolicyId}')"); + } + + /** + * Create new locator + * + * @param WindowsAzure\MediaServices\Models\Locator $locator Locator data + * + * @return WindowsAzure\MediaServices\Models\Locator + */ + public function createLocator($locator) + { + Validate::isA( + $locator, + 'WindowsAzure\Mediaservices\Models\Locator', + 'locator' + ); + + return Locator::createFromOptions( + $this->_createEntity($locator, 'Locators') + ); + } + + /** + * Get Locator. + * + * @param WindowsAzure\MediaServices\Models\Locator|string $locator Locator data + * or locator Id + * + * @return WindowsAzure\MediaServices\Models\Locator + */ + public function getLocator($locator) + { + $locatorId = Utilities::getEntityId( + $locator, + 'WindowsAzure\Mediaservices\Models\Locator' + ); + + return Locator::createFromOptions( + $this->_getEntity("Locators('{$locatorId}')") + ); + } + + /** + * Get Locator access policy. + * + * @param WindowsAzure\MediaServices\Models\Locator|string $locator Locator data + * or locator Id + * + * @return WindowsAzure\MediaServices\Models\Locator + */ + public function getLocatorAccessPolicy($locator) + { + $locatorId = Utilities::getEntityId( + $locator, + 'WindowsAzure\Mediaservices\Models\Locator' + ); + + return AccessPolicy::createFromOptions( + $this->_getEntity("Locators('{$locatorId}')/AccessPolicy") + ); + } + + /** + * Get Locator asset. + * + * @param WindowsAzure\MediaServices\Models\Locator|string $locator Locator data + * or locator Id + * + * @return WindowsAzure\MediaServices\Models\Locator + */ + public function getLocatorAsset($locator) + { + $locatorId = Utilities::getEntityId( + $locator, + 'WindowsAzure\Mediaservices\Models\Locator' + ); + + return Asset::createFromOptions( + $this->_getEntity("Locators('{$locatorId}')/Asset") + ); + } + + /** + * Get list of Locators. + * + * @return array + */ + public function getLocatorList() + { + $propertyList = $this->_getEntityList('Locators'); + $result = array(); + + foreach ($propertyList as $properties) { + $result[] = Locator::createFromOptions($properties); + } + + return $result; + } + + /** + * Update locator + * + * @param WindowsAzure\MediaServices\Models\Locator $locator New locator data + * with valid id + * + * @return none + */ + public function updateLocator($locator) + { + Validate::isA( + $locator, + 'WindowsAzure\MediaServices\Models\Locator', + 'locator' + ); + + $this->_updateEntity($locator, "Locators('{$locator->getId()}')"); + } + + /** + * Delete locator + * + * @param WindowsAzure\MediaServices\Models\Locator|string $locator Asset data + * or asset Id + * + * @return none + */ + public function deleteLocator($locator) + { + $locatorId = Utilities::getEntityId( + $locator, + 'WindowsAzure\Mediaservices\Models\Locator' + ); + + $this->_deleteEntity("Locators('{$locatorId}')"); + } + + /** + * Generate file info for all files in asset + * + * @param WindowsAzure\MediaServices\Models\Asset|string $asset Asset data or + * asset Id + * + * @return none + */ + public function createFileInfos($asset) + { + $assetId = Utilities::getEntityId( + $asset, + 'WindowsAzure\MediaServices\Models\Asset' + ); + $assetIdEncoded = urlencode($assetId); + + $method = Resources::HTTP_GET; + $headers = array(); + $postParams = array(); + $queryParams = array(); + $path = "CreateFileInfos?assetid='{$assetIdEncoded}'"; + $statusCode = Resources::STATUS_NO_CONTENT; + + $this->send( + $method, + $headers, + $postParams, + $queryParams, + $path, + $statusCode + ); + } + + /** + * Get asset file. + * + * @param WindowsAzure\MediaServices\Models\AssetFile|string $assetFile AssetFile + * data or assetFile Id + * + * @return WindowsAzure\MediaServices\Models\AssetFile + */ + public function getAssetFile($assetFile) + { + $assetFileId = Utilities::getEntityId( + $assetFile, + 'WindowsAzure\Mediaservices\Models\AssetFile' + ); + + return AssetFile::createFromOptions( + $this->_getEntity("Files('{$assetFileId}')") + ); + } + + + /** + * Get list of all asset files. + * + * @return array + */ + public function getAssetFileList() + { + $propertyList = $this->_getEntityList('Files'); + $result = array(); + + foreach ($propertyList as $properties) { + $result[] = AssetFile::createFromOptions($properties); + } + + return $result; + } + + /** + * Update asset file + * + * @param WindowsAzure\MediaServices\Models\AssetFile $assetFile New AssetFile + * data + * + * @return none + */ + public function updateAssetFile($assetFile) + { + Validate::isA( + $assetFile, + 'WindowsAzure\MediaServices\Models\AssetFile', + 'assetFile' + ); + + $this->_updateEntity($assetFile, "Files('{$assetFile->getId()}')"); + } + + /** + * Upload asset file to storage. + * + * @param WindowsAzure\MediaServices\Models\Locator $locator Write locator for + * file upload + * + * @param string $name Uploading filename + * @param string $body Uploading content + * + * @return none + */ + public function uploadAssetFile($locator, $name, $body) + { + Validate::isA( + $locator, + 'WindowsAzure\Mediaservices\Models\Locator', + 'locator' + ); + Validate::isString($name, 'name'); + Validate::notNull($body, 'body'); + + $method = Resources::HTTP_PUT; + $urlFile = $locator->getBaseUri() . '/' . $name; + $url = new Url($urlFile . $locator->getContentAccessComponent()); + $filters = array(); + $statusCode = Resources::STATUS_CREATED; + $headers = array( + Resources::CONTENT_TYPE => Resources::BINARY_FILE_TYPE, + Resources::X_MS_VERSION => Resources::STORAGE_API_LATEST_VERSION, + Resources::X_MS_BLOB_TYPE => BlobType::BLOCK_BLOB, + ); + + $httpClient = new HttpClient(); + $httpClient->setMethod($method); + $httpClient->setHeaders($headers); + $httpClient->setExpectedStatusCode($statusCode); + $httpClient->setBody($body); + $httpClient->send($filters, $url); + } + + /** + * Create a job HTTP call context. + * + * @param WindowsAzure\MediaServices\Models\Job $job Job data + * @param array $inputAssets Input assets list + * + * @return WindowsAzure\Common\Internal\Http\HttpCallContext + */ + private function _getCreateEmptyJobContext($job, $inputAssets) + { + Validate::isA($job, 'WindowsAzure\MediaServices\Models\Job', 'job'); + Validate::isArray($inputAssets, 'inputAssets'); + + $atomLinks = array(); + foreach ($inputAssets as $inputAsset) { + Validate::isA( + $inputAsset, + 'WindowsAzure\MediaServices\Models\Asset', + 'inputAssets' + ); + + $href = urlencode($inputAsset->getId()); + + $atomLink = new AtomLink(); + $atomLink->setHref($this->getUri() . "Assets('{$href}')"); + $atomLink->setType(Resources::ATOM_FEED_CONTENT_TYPE); + $atomLink->setTitle('InputAssets'); + $atomLink->setRel(Resources::MEDIA_SERVICES_INPUT_ASSETS_REL); + + $atomLinks[] = $atomLink; + } + + $result = new HttpCallContext(); + $result->setMethod(Resources::HTTP_POST); + $result->setHeaders($this->_batchHeaders); + $result->setUri($this->getUri()); + $result->setPath('/Jobs'); + $result->setBody($this->wrapAtomEntry($job, $atomLinks)); + $result->addStatusCode(Resources::STATUS_CREATED); + + return $result; + } + + + /** + * Create task HTTP call context + * + * @param WindowsAzure\MediaServices\Models\Task $task Task object to be created + * + * @return WindowsAzure\Common\Internal\Http\HttpCallContext + */ + private function _getCreateTaskContext($task) + { + Validate::isA($task, 'WindowsAzure\MediaServices\Models\Task', 'task'); + + $result = new HttpCallContext(); + $result->setMethod(Resources::HTTP_POST); + $result->setHeaders($this->_batchHeaders); + $result->setUri($this->getUri()); + $result->setPath('/$1/Tasks'); + $result->setBody($this->wrapAtomEntry($task)); + $result->addStatusCode(Resources::STATUS_CREATED); + + return $result; + } + + /** + * Create a job. + * + * @param WindowsAzure\MediaServices\Models\Job $job Job data + * @param array $inputAssets Input assets list + * @param array $tasks Performed tasks + * array (optional) + * + * @return array + */ + public function createJob($job, $inputAssets, $tasks = null) + { + Validate::isA($job, 'WindowsAzure\MediaServices\Models\Job', 'job'); + Validate::isArray($inputAssets, 'inputAssets'); + + $batch = new BatchRequest(); + $batch->appendContext($this->_getCreateEmptyJobContext($job, $inputAssets)); + + if ($tasks != null) { + foreach ($tasks as $task) { + $batch->appendContext($this->_getCreateTaskContext($task)); + } + } + + $batch->encode(); + + $method = Resources::HTTP_POST; + $headers = $batch->getHeaders(); + $postParams = array(); + $queryParams = array(); + $path = '$batch'; + $statusCode = Resources::STATUS_ACCEPTED; + $body = $batch->getBody(); + + $response = $this->send( + $method, + $headers, + $postParams, + $queryParams, + $path, + $statusCode, + $body + ); + + $batchResponse = new BatchResponse($response->getBody(), $batch); + $responses = $batchResponse->getContexts(); + $jobResponse = $responses[0]; + + $entry = new Entry(); + $entry->parseXml($jobResponse->getBody()); + $properties = $this->getPropertiesFromAtomEntry($entry); + + return Job::createFromOptions($properties); + } + + /** + * Get Job. + * + * @param WindowsAzure\MediaServices\Models\Job|string $job Job data or job Id + * + * @return WindowsAzure\MediaServices\Models\Job + */ + public function getJob($job) + { + $jobId = Utilities::getEntityId( + $job, + 'WindowsAzure\Mediaservices\Models\Job' + ); + + return Job::createFromOptions($this->_getEntity("Jobs('{$jobId}')")); + } + + /** + * Get list of Jobs. + * + * @return array + */ + public function getJobList() + { + $propertyList = $this->_getEntityList('Jobs'); + $result = array(); + + foreach ($propertyList as $properties) { + $result[] = Job::createFromOptions($properties); + } + + return $result; + } + + /** + * Get status of a job + * + * @param WindowsAzure\MediaServices\Models\Job|string $job Job data or job Id + * + * @return string + */ + public function getJobStatus($job) + { + $jobId = Utilities::getEntityId( + $job, + 'WindowsAzure\MediaServices\Models\Job' + ); + $jobIdEncoded = urlencode($jobId); + + $method = Resources::HTTP_GET; + $headers = array(); + $postParams = array(); + $queryParams = array(); + $path = "Jobs('{$jobIdEncoded}')/State"; + $statusCode = Resources::STATUS_OK; + + $response = $this->send( + $method, + $headers, + $postParams, + $queryParams, + $path, + $statusCode + ); + + return strip_tags($response->getBody()); + } + + /** + * Get job tasks. + * + * @param WindowsAzure\MediaServices\Models\Job|string $job Job data or job Id + * + * @return array + */ + public function getJobTasks($job) + { + $jobId = Utilities::getEntityId( + $job, + 'WindowsAzure\Mediaservices\Models\Job' + ); + + $propertyList = $this->_getEntityList("Jobs('{$jobId}')/Tasks"); + $result = array(); + + foreach ($propertyList as $properties) { + $result[] = Task::createFromOptions($properties); + } + + return $result; + } + + + /** + * Get job input assets. + * + * @param WindowsAzure\MediaServices\Models\Job|string $job Job data or job Id + * + * @return array + */ + public function getJobInputMediaAssets($job) + { + $jobId = Utilities::getEntityId( + $job, + 'WindowsAzure\Mediaservices\Models\Job' + ); + + $propertyList = $this->_getEntityList("Jobs('{$jobId}')/InputMediaAssets"); + $result = array(); + + foreach ($propertyList as $properties) { + $result[] = Asset::createFromOptions($properties); + } + + return $result; + } + + /** + * Get job output assets. + * + * @param WindowsAzure\MediaServices\Models\Job|string $job Job data or job Id + * + * @return array + */ + public function getJobOutputMediaAssets($job) + { + $jobId = Utilities::getEntityId( + $job, + 'WindowsAzure\Mediaservices\Models\Job' + ); + + $propertyList = $this->_getEntityList("Jobs('{$jobId}')/OutputMediaAssets"); + $result = array(); + + foreach ($propertyList as $properties) { + $result[] = Asset::createFromOptions($properties); + } + + return $result; + } + + /** + * Cancel a job + * + * @param WindowsAzure\MediaServices\Models\Job|string $job Job data or job Id + * + * @return none + */ + public function cancelJob($job) + { + $jobId = Utilities::getEntityId( + $job, + 'WindowsAzure\MediaServices\Models\Job' + ); + $jobIdEncoded = urlencode($jobId); + + $method = Resources::HTTP_GET; + $headers = array(); + $postParams = array(); + $queryParams = array(); + $path = "CancelJob?jobid='{$jobIdEncoded}'"; + $statusCode = Resources::STATUS_NO_CONTENT; + + $this->send( + $method, + $headers, + $postParams, + $queryParams, + $path, + $statusCode + ); + } + + /** + * Delete job + * + * @param WindowsAzure\MediaServices\Models\Job|string $job Job data or job Id + * + * @return none + */ + public function deleteJob($job) + { + $jobId = Utilities::getEntityId( + $job, + 'WindowsAzure\Mediaservices\Models\Job' + ); + + $this->_deleteEntity("Jobs('{$jobId}')"); + } + + /** + * Get list of tasks. + * + * @return array + */ + public function getTaskList() + { + $propertyList = $this->_getEntityList('Tasks'); + $result = array(); + + foreach ($propertyList as $properties) { + $result[] = Task::createFromOptions($properties); + } + + return $result; + } + + /** + * Create a job HTTP call context. + * + * @param WindowsAzure\MediaServices\Models\Job $jobTemplate JobTemplate data + * + * @return WindowsAzure\Common\Internal\Http\HttpCallContext + */ + private function _getCreateEmptyJobTemplateContext($jobTemplate) + { + Validate::isA( + $jobTemplate, + 'WindowsAzure\MediaServices\Models\JobTemplate', + 'jobTemplate' + ); + + $result = new HttpCallContext(); + $result->setMethod(Resources::HTTP_POST); + $result->setHeaders($this->_batchHeaders); + $result->setUri($this->getUri()); + $result->setPath('/JobTemplates'); + $result->setBody($this->wrapAtomEntry($jobTemplate)); + $result->addStatusCode(Resources::STATUS_CREATED); + + return $result; + } + + + /** + * Create task template HTTP call context + * + * @param WindowsAzure\MediaServices\Models\TaskTemplate $taskTemplate Task + * template object to be created + * + * @return WindowsAzure\Common\Internal\Http\HttpCallContext + */ + private function _getCreateTaskTemplateContext($taskTemplate) + { + Validate::isA( + $taskTemplate, + 'WindowsAzure\MediaServices\Models\TaskTemplate', + 'taskTemplate' + ); + + $result = new HttpCallContext(); + $result->setMethod(Resources::HTTP_POST); + $result->setHeaders($this->_batchHeaders); + $result->setUri($this->getUri()); + $result->setPath('/$1/TaskTemplates'); + $result->setBody($this->wrapAtomEntry($taskTemplate)); + $result->addStatusCode(Resources::STATUS_CREATED); + + return $result; + } + + /** + * Create a job. + * + * @param WindowsAzure\MediaServices\Models\JobTemplate $jobTemplate Job + * template data + * + * @param array $taskTemplates Performed + * tasks template array + * + * @return array + */ + public function createJobTemplate($jobTemplate, $taskTemplates) + { + Validate::isA( + $jobTemplate, + 'WindowsAzure\MediaServices\Models\JobTemplate', + 'jobTemplate' + ); + Validate::isArray($taskTemplates, 'taskTemplates'); + + $batch = new BatchRequest(); + $batch->appendContext( + $this->_getCreateEmptyJobTemplateContext($jobTemplate) + ); + + if ($taskTemplates != null) { + foreach ($taskTemplates as $taskTemplate) { + $batch->appendContext( + $this->_getCreateTaskTemplateContext($taskTemplate) + ); + } + } + + $batch->encode(); + + $method = Resources::HTTP_POST; + $headers = $batch->getHeaders(); + $postParams = array(); + $queryParams = array(); + $path = '$batch'; + $statusCode = Resources::STATUS_ACCEPTED; + $body = $batch->getBody(); + + $response = $this->send( + $method, + $headers, + $postParams, + $queryParams, + $path, + $statusCode, + $body + ); + + $batchResponse = new BatchResponse($response->getBody(), $batch); + $responses = $batchResponse->getContexts(); + $jobTemplateResponse = $responses[0]; + + $entry = new Entry(); + $entry->parseXml($jobTemplateResponse->getBody()); + $properties = $this->getPropertiesFromAtomEntry($entry); + + return JobTemplate::createFromOptions($properties); + } + + /** + * Get job template. + * + * @param WindowsAzure\MediaServices\Models\JobTemplate|string $jobTemplate Job + * template data or jobTemplate Id + * + * @return WindowsAzure\MediaServices\Models\JobTemplate + */ + public function getJobTemplate($jobTemplate) + { + $jobTemplateId = Utilities::getEntityId( + $jobTemplate, + 'WindowsAzure\Mediaservices\Models\JobTemplate' + ); + + return JobTemplate::createFromOptions( + $this->_getEntity("JobTemplates('{$jobTemplateId}')") + ); + } + + /** + * Get list of Job Templates. + * + * @return array + */ + public function getJobTemplateList() + { + $propertyList = $this->_getEntityList('JobTemplates'); + $result = array(); + + foreach ($propertyList as $properties) { + $result[] = JobTemplate::createFromOptions($properties); + } + + return $result; + } + + /** + * Get task templates for job template. + * + * @param WindowsAzure\MediaServices\Models\JobTemplate|string $jobTemplate Job + * template data or jobTemplate Id + * + * @return array + */ + public function getJobTemplateTaskTemplateList($jobTemplate) + { + $jobTemplateId = Utilities::getEntityId( + $jobTemplate, + 'WindowsAzure\Mediaservices\Models\JobTemplate' + ); + + $propertyList = $this->_getEntityList( + "JobTemplates('{$jobTemplateId}')/TaskTemplates" + ); + $result = array(); + + foreach ($propertyList as $properties) { + $result[] = TaskTemplate::createFromOptions($properties); + } + + return $result; + } + + + /** + * Delete job template + * + * @param WindowsAzure\MediaServices\Models\JobTemplate|string $jobTemplate Job + * template data or job template Id + * + * @return none + */ + public function deleteJobTemplate($jobTemplate) + { + $jobTemplateId = Utilities::getEntityId( + $jobTemplate, + 'WindowsAzure\Mediaservices\Models\JobTemplate' + ); + + $this->_deleteEntity("JobTemplates('{$jobTemplateId}')"); + } + + /** + * Get list of task templates. + * + * @return array + */ + public function getTaskTemplateList() + { + $propertyList = $this->_getEntityList('TaskTemplates'); + $result = array(); + + foreach ($propertyList as $properties) { + $result[] = TaskTemplate::createFromOptions($properties); + } + + return $result; + } + + /** + * Get list of all media processors asset files + * + * @return array + */ + public function getMediaProcessors() + { + $propertyList = $this->_getEntityList('MediaProcessors'); + $result = array(); + + foreach ($propertyList as $properties) { + $result[] = MediaProcessor::createFromOptions($properties); + } + + return $result; + } + + /** + * Get media processor by name with latest version + * + * @param string $name Media processor name + * + * @return WindowsAzure\MediaServices\Models\JobTemplate\MediaProcessor + */ + public function getLatestMediaProcessor($name) + { + $mediaProcessors = $this->getMediaProcessors(); + + $maxVersion = 0.0; + $result = null; + foreach ($mediaProcessors as $mediaProcessor) { + if (($mediaProcessor->getName() == $name) + && ($mediaProcessor->getVersion() > $maxVersion)) { + $result = $mediaProcessor; + $maxVersion = $mediaProcessor->getVersion(); + } + } + + return $result; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/MediaServices/Models/AccessPolicy.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/MediaServices/Models/AccessPolicy.php new file mode 100644 index 0000000..7e9b0df --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/MediaServices/Models/AccessPolicy.php @@ -0,0 +1,293 @@ + + * @copyright Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\MediaServices\Models; +use WindowsAzure\Common\Internal\Validate; + +/** + * Represents access policy object used in media services + * + * @category Microsoft + * @package WindowsAzure\MediaServices\Models + * @author Azure PHP SDK + * @copyright Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class AccessPolicy +{ + /** + * The access rights the client has when interacting with the Asset. (None) + * + * @var int + */ + const PERMISSIONS_NONE = 0; + + /** + * The access rights the client has when interacting with the Asset. (Read) + * + * @var int + */ + const PERMISSIONS_READ = 1; + + /** + * The access rights the client has when interacting with the Asset. + * (Write) + * + * @var int + */ + const PERMISSIONS_WRITE = 2; + + /** + * The access rights the client has when interacting with the Asset. + * (Delete) + * + * @var int + */ + const PERMISSIONS_DELETE = 4; + + /** + * The access rights the client has when interacting with the Asset. (List) + * + * @var int + */ + const PERMISSIONS_LIST = 8; + + /** + * Access policy id + * + * @var string + */ + private $_id; + + /** + * Created + * + * @var \DateTime + */ + private $_created; + + /** + * Last modified + * + * @var \DateTime + */ + private $_lastModified; + + /** + * Name + * + * @var string + */ + private $_name; + + /** + * Duration in minutes + * + * @var double + */ + private $_durationInMinutes; + + /** + * Permissions + * + * @var int + */ + private $_permissions; + + /** + * Create access policy from array + * + * @param array $options Array containing values for object properties + * + * @return WindowsAzure\MediaServices\Models\AccessPolicy + */ + public static function createFromOptions($options) + { + Validate::notNull($options['Name'], 'options[Name]'); + + $accessPolicy = new AccessPolicy($options['Name']); + $accessPolicy->fromArray($options); + + return $accessPolicy; + } + + /** + * Create access policy + * + * @param string $name Entity name + */ + public function __construct($name) + { + $this->_name = $name; + } + + /** + * Fill access policy from array + * + * @param array $options Array containing values for object properties + * + * @return none + */ + public function fromArray($options) + { + if (isset($options['Id'])) { + Validate::isString($options['Id'], 'options[Id]'); + $this->_id = $options['Id']; + } + + if (isset($options['Created'])) { + Validate::isDateString($options['Created'], 'options[Created]'); + $this->_created = new \DateTime($options['Created']); + } + + if (isset($options['LastModified'])) { + Validate::isDateString( + $options['LastModified'], + 'options[LastModified]' + ); + $this->_lastModified = new \DateTime($options['LastModified']); + } + + if (isset($options['Name'])) { + Validate::isString($options['Name'], 'options[Name]'); + $this->_name = $options['Name']; + } + + if (isset($options['DurationInMinutes'])) { + Validate::isDouble( + $options['DurationInMinutes'], + 'options[DurationInMinutes]' + ); + $this->_durationInMinutes = $options['DurationInMinutes']; + } + + if (isset($options['Permissions'])) { + Validate::isInteger( + $options['Permissions'], + 'options[Permissions]' + ); + $this->_permissions = $options['Permissions']; + } + } + + /** + * Get "Permissions" + * + * @return int + */ + public function getPermissions() + { + return $this->_permissions; + } + + /** + * Set "Permissions" + * + * @param int $value Permissions + * + * @return none + */ + public function setPermissions($value) + { + $this->_permissions = $value; + } + + /** + * Get "Duration in minutes" + * + * @return double + */ + public function getDurationInMinutes() + { + return $this->_durationInMinutes; + } + + /** + * Set "Duration in minutes" + * + * @param double $value Duration in minutes + * + * @return none + */ + public function setDurationInMinutes($value) + { + $this->_durationInMinutes = $value; + } + + /** + * Get "Name" + * + * @return string + */ + public function getName() + { + return $this->_name; + } + + /** + * Set "Name" + * + * @param string $value Name + * + * @return none + */ + public function setName($value) + { + $this->_name = $value; + } + + /** + * Get "Last modified" + * + * @return \DateTime + */ + public function getLastModified() + { + return $this->_lastModified; + } + + /** + * Get "Created" + * + * @return \DateTime + */ + public function getCreated() + { + return $this->_created; + } + + /** + * Get "Access policy id" + * + * @return string + */ + public function getId() + { + return $this->_id; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/MediaServices/Models/Asset.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/MediaServices/Models/Asset.php new file mode 100644 index 0000000..e7a722e --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/MediaServices/Models/Asset.php @@ -0,0 +1,372 @@ + + * @copyright Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\MediaServices\Models; +use WindowsAzure\Common\Internal\Validate; + + + +/** + * Represents asset object used in media services + * + * @category Microsoft + * @package WindowsAzure\MediaServices\Models + * @author Azure PHP SDK + * @copyright Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class Asset +{ + /** + * The state of the asset "initialized" + * + * @var int + */ + const STATE_INITIALIZED = 0; + + /** + * The state of the asset "published" + * + * @var int + */ + const STATE_PUBLISHED = 1; + + /** + * The state of the asset "deleted" + * + * @var int + */ + const STATE_DELETED = 2; + + /** + * The encryption options "none" + * + * @var int + */ + const OPTIONS_NONE = 0; + + /** + * The encryption options "storage encrypted" + * + * @var int + */ + const OPTIONS_STORAGE_ENCRYPTED = 1; + + /** + * The encryption options "common encryption protected" + * + * @var int + */ + const OPTIONS_COMMON_ENCRYPTION_PROTECTED = 2; + + /** + * The encryption options "envelope encryption protected" + * + * @var int + */ + const OPTIONS_ENVELOPE_ENCRYPTION_PROTECTED = 4; + + /** + * Asset id + * + * @var string + */ + private $_id; + + /** + * State + * + * @var int + */ + private $_state; + + /** + * Created + * + * @var \DateTime + */ + private $_created; + + /** + * Last modified + * + * @var \DateTime + */ + private $_lastModified; + + /** + * Alternate id + * + * @var string + */ + private $_alternateId; + + /** + * Name + * + * @var string + */ + private $_name; + + /** + * Options + * + * @var int + */ + private $_options; + + /** + * URI + * + * @var string + */ + private $_uri; + + /** + * Storage account name + * + * @var string + */ + private $_storageAccountName; + + /** + * Create asset from array + * + * @param array $options Array containing values for object properties + * + * @return WindowsAzure\MediaServices\Models\Asset + */ + public static function createFromOptions($options) + { + Validate::notNull($options['Options'], 'options[Options]'); + + $asset = new Asset($options['Options']); + $asset->fromArray($options); + + return $asset; + } + + /** + * Create asset + * + * @param int $options Asset encrytion options. + * + * @return none + */ + public function __construct($options) + { + $this->options = $options; + } + + /** + * Fill asset from array + * + * @param array $options Array containing values for object properties + * + * @return none + */ + public function fromArray($options) + { + if (isset($options['Id'])) { + Validate::isString($options['Id'], 'options[Id]'); + $this->_id = $options['Id']; + } + + if (isset($options['State'])) { + Validate::isInteger($options['State'], 'options[State]'); + $this->_state = $options['State']; + } + + if (isset($options['Created'])) { + Validate::isDateString($options['Created'], 'options[Created]'); + $this->_created = new \DateTime($options['Created']); + } + + if (isset($options['LastModified'])) { + Validate::isDateString( + $options['LastModified'], + 'options[LastModified]' + ); + $this->_lastModified = new \DateTime($options['LastModified']); + } + + if (isset($options['AlternateId'])) { + Validate::isString($options['AlternateId'], 'options[AlternateId]'); + $this->_alternateId = $options['AlternateId']; + } + + if (isset($options['Name'])) { + Validate::isString($options['Name'], 'options[Name]'); + $this->_name = $options['Name']; + } + + if (isset($options['Options'])) { + Validate::isInteger($options['Options'], 'options[Options]'); + $this->_options = $options['Options']; + } + + if (isset($options['Uri'])) { + Validate::isValidUri($options['Uri'], 'options[Uri]'); + $this->_uri = $options['Uri']; + } + + if (isset($options['StorageAccountName'])) { + Validate::isString( + $options['StorageAccountName'], + 'options[StorageAccountName]' + ); + $this->_storageAccountName = $options['StorageAccountName']; + } + } + + /** + * Get "Storage account name" + * + * @return string + */ + public function getStorageAccountName() + { + return $this->_storageAccountName; + } + + /** + * Get "URI" + * + * @return string + */ + public function getUri() + { + return $this->_uri; + } + + /** + * Get "Options" + * + * @return int + */ + public function getOptions() + { + return $this->_options; + } + + /** + * Set "Options" + * + * @param int $value Options + * + * @return none + */ + public function setOptions($value) + { + $this->_options = $value; + } + + /** + * Get "Name" + * + * @return string + */ + public function getName() + { + return $this->_name; + } + + /** + * Set "Name" + * + * @param string $value Name + * + * @return none + */ + public function setName($value) + { + $this->_name = $value; + } + + /** + * Get "Alternate id" + * + * @return string + */ + public function getAlternateId() + { + return $this->_alternateId; + } + + /** + * Set "Alternate id" + * + * @param string $value Alternate id + * + * @return none + */ + public function setAlternateId($value) + { + $this->_alternateId = $value; + } + + /** + * Get "Last modified" + * + * @return \DateTime + */ + public function getLastModified() + { + return $this->_lastModified; + } + + /** + * Get "Created" + * + * @return \DateTime + */ + public function getCreated() + { + return $this->_created; + } + + /** + * Get "State" + * + * @return int + */ + public function getState() + { + return $this->_state; + } + + /** + * Get "Asset id" + * + * @return string + */ + public function getId() + { + return $this->_id; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/MediaServices/Models/AssetFile.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/MediaServices/Models/AssetFile.php new file mode 100644 index 0000000..41df61e --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/MediaServices/Models/AssetFile.php @@ -0,0 +1,551 @@ + + * @copyright Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\MediaServices\Models; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Validate; + +/** + * Represents asset file object used in media services + * + * @category Microsoft + * @package WindowsAzure\MediaServices\Models + * @author Azure PHP SDK + * @copyright Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class AssetFile +{ + /** + * Asset file Id + * + * @var string + */ + private $_id; + + /** + * Name + * + * @var string + */ + private $_name; + + /** + * Content file size + * + * @var int + */ + private $_contentFileSize; + + /** + * Parent asset id + * + * @var string + */ + private $_parentAssetId; + + /** + * Encryption version + * + * @var string + */ + private $_encryptionVersion; + + /** + * Encryption scheme + * + * @var string + */ + private $_encryptionScheme; + + /** + * Is encrypted + * + * @var bool + */ + private $_isEncrypted; + + /** + * Encryption key id + * + * @var string + */ + private $_encryptionKeyId; + + /** + * Initialization vector + * + * @var string + */ + private $_initializationVector; + + /** + * Is primary + * + * @var bool + */ + private $_isPrimary; + + /** + * Last modified + * + * @var \DateTime + */ + private $_lastModified; + + /** + * Created + * + * @var \DateTime + */ + private $_created; + + /** + * Mime type + * + * @var string + */ + private $_mimeType; + + /** + * Content check sum + * + * @var string + */ + private $_contentCheckSum; + + /** + * Create asset file from array + * + * @param array $options Array containing values for object properties + * + * @return WindowsAzure\MediaServices\Models\AssetFile + */ + public static function createFromOptions($options) + { + Validate::notNull($options['Name'], 'options[Name]'); + Validate::notNull($options['ParentAssetId'], 'options[ParentAssetId]'); + + $assetFile = new AssetFile($options['Name'], $options['ParentAssetId']); + $assetFile->fromArray($options); + + return $assetFile; + } + + /** + * Create asset file + * + * @param string $name Friendly name for asset file. + * @param string $parentAssetId Asset Id of the Asset that this file is + * associated with. + */ + public function __construct($name, $parentAssetId) + { + $this->_name = $name; + $this->_parentAssetId = $parentAssetId; + } + + /** + * Fill asset file from array + * + * @param array $options Array containing values for object properties + * + * @return none + */ + public function fromArray($options) + { + if (isset($options['Id'])) { + Validate::isString($options['Id'], 'options[Id]'); + $this->_id = $options['Id']; + } + + if (isset($options['Name'])) { + Validate::isString($options['Name'], 'options[Name]'); + $this->_name = $options['Name']; + } + + if (isset($options['ContentFileSize'])) { + Validate::isString( + $options['ContentFileSize'], + 'options[ContentFileSize]' + ); + $this->_contentFileSize = $options['ContentFileSize']; + } + + if (isset($options['ParentAssetId'])) { + Validate::isString( + $options['ParentAssetId'], + 'options[ParentAssetId]' + ); + $this->_parentAssetId = $options['ParentAssetId']; + } + + if (isset($options['EncryptionVersion'])) { + Validate::isString( + $options['EncryptionVersion'], + 'options[EncryptionVersion]' + ); + $this->_encryptionVersion = $options['EncryptionVersion']; + } + + if (isset($options['EncryptionScheme'])) { + Validate::isString( + $options['EncryptionScheme'], + 'options[EncryptionScheme]' + ); + $this->_encryptionScheme = $options['EncryptionScheme']; + } + + if (isset($options['IsEncrypted'])) { + Validate::isBoolean( + $options['IsEncrypted'], + 'options[IsEncrypted]' + ); + $this->_isEncrypted = $options['IsEncrypted']; + } + + if (isset($options['EncryptionKeyId'])) { + Validate::isString( + $options['EncryptionKeyId'], + 'options[EncryptionKeyId]' + ); + $this->_encryptionKeyId = $options['EncryptionKeyId']; + } + + if (isset($options['InitializationVector'])) { + Validate::isString( + $options['InitializationVector'], + 'options[InitializationVector]' + ); + $this->_initializationVector = $options['InitializationVector']; + } + + if (isset($options['IsPrimary'])) { + Validate::isBoolean($options['IsPrimary'], 'options[IsPrimary]'); + $this->_isPrimary = $options['IsPrimary']; + } + + if (isset($options['LastModified'])) { + Validate::isDateString( + $options['LastModified'], + 'options[LastModified]' + ); + $this->_lastModified = new \DateTime($options['LastModified']); + } + + if (isset($options['Created'])) { + Validate::isDateString($options['Created'], 'options[Created]'); + $this->_created = new \DateTime($options['Created']); + } + + if (isset($options['MimeType'])) { + Validate::isString($options['MimeType'], 'options[MimeType]'); + $this->_mimeType = $options['MimeType']; + } + + if (isset($options['ContentChecksum'])) { + Validate::isString( + $options['ContentChecksum'], + 'options[ContentChecksum]' + ); + $this->_contentCheckSum = $options['ContentChecksum']; + } + } + + /** + * Get "Content check sum" + * + * @return string + */ + public function getContentCheckSum() + { + return $this->_contentCheckSum; + } + + /** + * Set "Content check sum" + * + * @param string $value Content check sum + * + * @return none + */ + public function setContentCheckSum($value) + { + $this->_contentCheckSum = $value; + } + + /** + * Get "Mime type" + * + * @return string + */ + public function getMimeType() + { + return $this->_mimeType; + } + + /** + * Set "Mime type" + * + * @param string $value Mime type + * + * @return none + */ + public function setMimeType($value) + { + $this->_mimeType = $value; + } + + /** + * Get "Created" + * + * @return \DateTime + */ + public function getCreated() + { + return $this->_created; + } + + /** + * Get "Last modified" + * + * @return \DateTime + */ + public function getLastModified() + { + return $this->_lastModified; + } + + /** + * Get "Is primary" + * + * @return bool + */ + public function getIsPrimary() + { + return $this->_isPrimary; + } + + /** + * Set "Is primary" + * + * @param bool $value Is primary + * + * @return none + */ + public function setIsPrimary($value) + { + $this->_isPrimary = $value; + } + + /** + * Get "Initialization vector" + * + * @return string + */ + public function getInitializationVector() + { + return $this->_initializationVector; + } + + /** + * Set "Initialization vector" + * + * @param string $value Initialization vector + * + * @return none + */ + public function setInitializationVector($value) + { + $this->_initializationVector = $value; + } + + /** + * Get "Encryption key id" + * + * @return string + */ + public function getEncryptionKeyId() + { + return $this->_encryptionKeyId; + } + + /** + * Set "Encryption key id" + * + * @param string $value Encryption key id + * + * @return none + */ + public function setEncryptionKeyId($value) + { + $this->_encryptionKeyId = $value; + } + + /** + * Get "Is encrypted" + * + * @return bool + */ + public function getIsEncrypted() + { + return $this->_isEncrypted; + } + + /** + * Set "Is encrypted" + * + * @param bool $value Is encrypted + * + * @return none + */ + public function setIsEncrypted($value) + { + $this->_isEncrypted = $value; + } + + /** + * Get "Encryption scheme" + * + * @return string + */ + public function getEncryptionScheme() + { + return $this->_encryptionScheme; + } + + /** + * Set "Encryption scheme" + * + * @param string $value Encryption scheme + * + * @return none + */ + public function setEncryptionScheme($value) + { + $this->_encryptionScheme = $value; + } + + /** + * Get "Encryption version" + * + * @return string + */ + public function getEncryptionVersion() + { + return $this->_encryptionVersion; + } + + /** + * Set "Encryption version" + * + * @param string $value Encryption version + * + * @return none + */ + public function setEncryptionVersion($value) + { + $this->_encryptionVersion = $value; + } + + /** + * Get "Parent asset id" + * + * @return string + */ + public function getParentAssetId() + { + return $this->_parentAssetId; + } + + /** + * Set "Parent asset id" + * + * @param string $value Parent asset id + * + * @return none + */ + public function setParentAssetId($value) + { + $this->_parentAssetId = $value; + } + + /** + * Get "Content file size" + * + * @return int + */ + public function getContentFileSize() + { + return $this->_contentFileSize; + } + + /** + * Set "Content file size" + * + * @param int $value Content file size + * + * @return none + */ + public function setContentFileSize($value) + { + $this->_contentFileSize = $value; + } + + /** + * Get "Name" + * + * @return string + */ + public function getName() + { + return $this->_name; + } + + /** + * Set "Name" + * + * @param string $value Name + * + * @return none + */ + public function setName($value) + { + $this->_name = $value; + } + + /** + * Get "Asset file Id" + * + * @return string + */ + public function getId() + { + return $this->_id; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/MediaServices/Models/ContentProperties.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/MediaServices/Models/ContentProperties.php new file mode 100644 index 0000000..72cd6a3 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/MediaServices/Models/ContentProperties.php @@ -0,0 +1,185 @@ + + * @copyright Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +namespace WindowsAzure\MediaServices\Models; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Validate; + + +/** + * Entity object properties. + * + * @category Microsoft + * @package WindowsAzure\Common\Internal\Atom + * @author Azure PHP SDK + * @copyright Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +class ContentProperties +{ + /** + * The undefined content. + * + * @var array + */ + protected $properties; + + /** + * Creates a AtomProperties instance. + */ + public function __construct() + { + } + + /** + * Parse an ATOM Properties xml. + * + * @param string $xmlContent An XML based string of ATOM Link. + * + * @return none + */ + public function fromXml($xmlContent) + { + Validate::notNull($xmlContent, 'xmlContent'); + + $this->properties = $this->_fromXmlToArray($xmlContent); + + } + + /** + * Parse properties recursively + * + * @param \SimpleXML $xml XML object to parse + * + * @return array + */ + private function _fromXmlToArray($xml) { + $result = array(); + $dataNamespace = Resources::DS_XML_NAMESPACE; + foreach ($xml->children($dataNamespace) as $child) { + if (count($child->children($dataNamespace)) > 0) { + $value = array(); + foreach ($child->children($dataNamespace) as $subChild) { + if ($subChild->getName() == 'element') { + $value[] = $this->_fromXmlToArray($subChild); + } + } + } else { + $value = (string)$child; + } + + $result[$child->getName()] = $value; + } + + return $result; + } + + /** + * Set properties from object. + * + * @param object $object Object to serialize + * + * @return none + */ + public function setPropertiesFromObject($object) + { + Validate::notNull($object, 'object'); + + $reflectionClass = new \ReflectionClass($object); + $methodArray = $reflectionClass->getMethods(); + + $this->properties = array(); + foreach ($methodArray as $method) { + if ((strpos($method->name, 'get') === 0) + && $method->isPublic() + ) { + $variableName = substr($method->name, 3); + $variableValue = $method->invoke($object); + if (!empty($variableValue)) { + if (is_a($variableValue, '\DateTime')) { + $variableValue = $variableValue->format(\DateTime::ATOM); + } + $this->properties[$variableName] = (string)$variableValue; + } + } + } + } + + + /** + * Get properties + * + * @return array + */ + public function getProperties() { + return $this->properties; + } + + /** + * Writes an XML representing the ATOM properties item. + * + * @param \XMLWriter $xmlWriter The xml writer. + * + * @return none + */ + public function writeXml($xmlWriter) + { + Validate::notNull($xmlWriter, 'xmlWriter'); + $xmlWriter->startElementNS( + 'meta', + Resources::PROPERTIES, + Resources::DSM_XML_NAMESPACE + ); + $this->writeInnerXml($xmlWriter); + $xmlWriter->endElement(); + } + + /** + * Writes the inner XML representing the ATOM properties item. + * + * @param \XMLWriter $xmlWriter The xml writer. + * + * @return none + */ + public function writeInnerXml($xmlWriter) + { + Validate::notNull($xmlWriter, 'xmlWriter'); + + if (is_array($this->properties)) { + foreach ($this->properties as $key => $value) { + $xmlWriter->writeElementNS( + 'data', + $key, + Resources::DS_XML_NAMESPACE, + $value + ); + } + } + } +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/MediaServices/Models/ErrorDetail.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/MediaServices/Models/ErrorDetail.php new file mode 100644 index 0000000..b593dff --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/MediaServices/Models/ErrorDetail.php @@ -0,0 +1,111 @@ + + * @copyright Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\MediaServices\Models; +use WindowsAzure\Common\Internal\Validate; + + +/** + * Represents error detail object used in media services + * + * @category Microsoft + * @package WindowsAzure\MediaServices\Models + * @author Azure PHP SDK + * @copyright Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class ErrorDetail +{ + /** + * Code + * + * @var int + */ + private $_code; + + /** + * Message + * + * @var string + */ + private $_message; + + /** + * Create error detail from array + * + * @param array $options Array containing values for object properties + * + * @return WindowsAzure\MediaServices\Models\ErrorDetail + */ + public static function createFromOptions($options) + { + $errorDetail = new ErrorDetail(); + $errorDetail->fromArray($options); + + return $errorDetail; + } + + /** + * Fill error detail from array + * + * @param array $options Array containing values for object properties + * + * @return none + */ + public function fromArray($options) + { + if (isset($options['Code'])) { + Validate::isInteger($options['Code'], 'options[Code]'); + $this->_code = $options['Code']; + } + + if (isset($options['Message'])) { + Validate::isString($options['Message'], 'options[Message]'); + $this->_message = $options['Message']; + } + } + + /** + * Get "Message" + * + * @return string + */ + public function getMessage() + { + return $this->_message; + } + + /** + * Get "Code" + * + * @return int + */ + public function getCode() + { + return $this->_code; + } +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/MediaServices/Models/Job.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/MediaServices/Models/Job.php new file mode 100644 index 0000000..18792ca --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/MediaServices/Models/Job.php @@ -0,0 +1,379 @@ + + * @copyright Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\MediaServices\Models; +use WindowsAzure\Common\Internal\Validate; + + +/** + * Represents job object used in media services + * + * @category Microsoft + * @package WindowsAzure\MediaServices\Models + * @author Azure PHP SDK + * @copyright Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class Job +{ + /** + * The state of the job "queued" + * + * @var int + */ + const STATE_QUEUED = 0; + + /** + * The state of the job "scheduled" + * + * @var int + */ + const STATE_SCHEDULED = 1; + + /** + * The state of the job "processing" + * + * @var int + */ + const STATE_PROCESSING = 2; + + /** + * The state of the job "finished" + * + * @var int + */ + const STATE_FINISHED = 3; + + /** + * The state of the job "error" + * + * @var int + */ + const STATE_ERROR = 4; + + /** + * The state of the job "canceled" + * + * @var int + */ + const STATE_CANCELED = 5; + + /** + * The state of the job "canceling" + * + * @var int + */ + const STATE_CANCELING = 6; + + /** + * Job id + * + * @var string + */ + private $_id; + + /** + * State + * + * @var int + */ + private $_state; + + /** + * Created + * + * @var \DateTime + */ + private $_created; + + /** + * Last modified + * + * @var \DateTime + */ + private $_lastModified; + + /** + * Name + * + * @var string + */ + private $_name; + + /** + * End time + * + * @var \DateTime + */ + private $_endTime; + + /** + * Priority + * + * @var int + */ + private $_priority; + + /** + * Running duration + * + * @var double + */ + private $_runningDuration; + + /** + * Start time + * + * @var \DateTime + */ + private $_startTime; + + /** + * Template id + * + * @var string + */ + private $_templateId; + + /** + * Create asset from array + * + * @param array $options Array containing values for object properties + * + * @return WindowsAzure\MediaServices\Models\Job + */ + public static function createFromOptions($options) + { + $job = new Job(); + $job->fromArray($options); + + return $job; + } + + /** + * Fill asset from array + * + * @param array $options Array containing values for object properties + * + * @return none + */ + public function fromArray($options) + { + if (isset($options['Id'])) { + Validate::isString($options['Id'], 'options[Id]'); + $this->_id = $options['Id']; + } + + if (isset($options['Name'])) { + Validate::isString($options['Name'], 'options[Name]'); + $this->_name = $options['Name']; + } + + if (isset($options['Created'])) { + Validate::isDateString($options['Created'], 'options[Created]'); + $this->_created = new \DateTime($options['Created']); + } + + if (isset($options['LastModified'])) { + Validate::isDateString( + $options['LastModified'], + 'options[LastModified]' + ); + $this->_lastModified = new \DateTime($options['LastModified']); + } + + if (isset($options['EndTime'])) { + Validate::isDateString($options['EndTime'], 'options[EndTime]'); + $this->_endTime = new \DateTime($options['EndTime']); + } + + if (isset($options['Priority'])) { + Validate::isInteger($options['Priority'], 'options[Priority]'); + $this->_priority = $options['Priority']; + } + + if (isset($options['RunningDuration'])) { + Validate::isDouble( + $options['RunningDuration'], + 'options[RunningDuration]' + ); + $this->_runningDuration = $options['RunningDuration']; + } + + if (isset($options['StartTime'])) { + Validate::isDateString($options['StartTime'], 'options[StartTime]'); + $this->_startTime = new \DateTime($options['StartTime']); + } + + if (isset($options['State'])) { + Validate::isInteger($options['State'], 'options[State]'); + $this->_state = $options['State']; + } + + if (isset($options['TemplateId'])) { + Validate::isString($options['TemplateId'], 'options[TemplateId]'); + $this->_templateId = $options['TemplateId']; + } + } + + /** + * Get "Name" + * + * @return string + */ + public function getName() + { + return $this->_name; + } + + /** + * Set "Name" + * + * @param string $value Name + * + * @return none + */ + public function setName($value) + { + $this->_name = $value; + } + + /** + * Get "Last modified" + * + * @return \DateTime + */ + public function getLastModified() + { + return $this->_lastModified; + } + + /** + * Get "Created" + * + * @return \DateTime + */ + public function getCreated() + { + return $this->_created; + } + + /** + * Get "State" + * + * @return int + */ + public function getState() + { + return $this->_state; + } + + /** + * Get "Job id" + * + * @return string + */ + public function getId() + { + return $this->_id; + } + + /** + * Get "Template id" + * + * @return string + */ + public function getTemplateId() + { + return $this->_templateId; + } + + /** + * Set "Template id" + * + * @param string $value Template id + * + * @return none + */ + public function setTemplateId($value) + { + $this->_templateId = $value; + } + + /** + * Get "Start time" + * + * @return \DateTime + */ + public function getStartTime() + { + return $this->_startTime; + } + + /** + * Get "Running duration" + * + * @return double + */ + public function getRunningDuration() + { + return $this->_runningDuration; + } + + /** + * Get "Priority" + * + * @return int + */ + public function getPriority() + { + return $this->_priority; + } + + /** + * Set "Priority" + * + * @param int $value Priority + * + * @return none + */ + public function setPriority($value) + { + $this->_priority = $value; + } + + /** + * Get "End time" + * + * @return \DateTime + */ + public function getEndTime() + { + return $this->_endTime; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/MediaServices/Models/JobTemplate.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/MediaServices/Models/JobTemplate.php new file mode 100644 index 0000000..ca48153 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/MediaServices/Models/JobTemplate.php @@ -0,0 +1,312 @@ + + * @copyright Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\MediaServices\Models; +use WindowsAzure\Common\Internal\Validate; + + +/** + * Represents job template object used in media services + * + * @category Microsoft + * @package WindowsAzure\MediaServices\Models + * @author Azure PHP SDK + * @copyright Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class JobTemplate +{ + /** + * The type of JobTemplate "system level" + * + * @var int + */ + const TYPE_SYSTEM_LEVEL = 0; + + /** + * The type of JobTemplate "account level" + * + * @var int + */ + const TYPE_ACCOUNT_LEVEL = 1; + + /** + * Job template id + * + * @var string + */ + private $_id; + + /** + * Name + * + * @var string + */ + private $_name; + + /** + * Created + * + * @var \DateTime + */ + private $_created; + + /** + * Last modified + * + * @var \DateTime + */ + private $_lastModified; + + /** + * Job template body + * + * @var string + */ + private $_jobTemplateBody; + + /** + * Number of input assets + * + * @var int + */ + private $_numberofInputAssets; + + /** + * Template type + * + * @var int + */ + private $_templateType; + + /** + * Create asset from array + * + * @param array $options Array containing values for object properties + * + * @return WindowsAzure\MediaServices\Models\JobTemplate + */ + public static function createFromOptions($options) + { + Validate::notNull($options['JobTemplateBody'], 'options[JobTemplateBody]'); + + $jobTemplate = new JobTemplate( + $options['JobTemplateBody'], + $options['TemplateType'] + ); + $jobTemplate->fromArray($options); + + return $jobTemplate; + } + + /** + * Create job template + * + * @param string $jobTemplateBody Job template XML body. + * @param string $templateType Template type default to AccountLevel. + */ + public function __construct( + $jobTemplateBody, + $templateType = JobTemplate::TYPE_ACCOUNT_LEVEL) + { + $this->_jobTemplateBody = $jobTemplateBody; + $this->_templateType = $templateType; + } + + /** + * Fill job template from array + * + * @param array $options Array containing values for object properties + * + * @return none + */ + public function fromArray($options) + { + if (isset($options['Id'])) { + Validate::isString($options['Id'], 'options[Id]'); + $this->_id = $options['Id']; + } + + if (isset($options['Name'])) { + Validate::isString($options['Name'], 'options[Name]'); + $this->_name = $options['Name']; + } + + if (isset($options['Created'])) { + Validate::isDateString($options['Created'], 'options[Created]'); + $this->_created = new \DateTime($options['Created']); + } + + if (isset($options['LastModified'])) { + Validate::isDateString( + $options['LastModified'], + 'options[LastModified]' + ); + $this->_lastModified = new \DateTime($options['LastModified']); + } + + if (isset($options['JobTemplateBody'])) { + Validate::isString( + $options['JobTemplateBody'], + 'options[JobTemplateBody]' + ); + $this->_jobTemplateBody = $options['JobTemplateBody']; + } + + if (isset($options['NumberofInputAssets'])) { + Validate::isInteger( + $options['NumberofInputAssets'], + 'options[NumberofInputAssets]' + ); + $this->_numberofInputAssets = $options['NumberofInputAssets']; + } + + if (isset($options['TemplateType'])) { + Validate::isInteger($options['TemplateType'], 'options[TemplateType]'); + $this->_templateType = $options['TemplateType']; + } + } + + /** + * Get "Name" + * + * @return string + */ + public function getName() + { + return $this->_name; + } + + /** + * Set "Name" + * + * @param string $value Name + * + * @return none + */ + public function setName($value) + { + $this->_name = $value; + } + + /** + * Get "Last modified" + * + * @return \DateTime + */ + public function getLastModified() + { + return $this->_lastModified; + } + + /** + * Get "Created" + * + * @return \DateTime + */ + public function getCreated() + { + return $this->_created; + } + + /** + * Get "job template id" + * + * @return string + */ + public function getId() + { + return $this->_id; + } + + /** + * Get "Template type" + * + * @return int + */ + public function getTemplateType() + { + return $this->_templateType; + } + + /** + * Set "Template type" + * + * @param int $value Template type + * + * @return none + */ + public function setTemplateType($value) + { + $this->_templateType = $value; + } + + /** + * Get "Number of input assets" + * + * @return int + */ + public function getNumberofInputAssets() + { + return $this->_numberofInputAssets; + } + + /** + * Set "Number of input assets" + * + * @param int $value Number of input assets + * + * @return none + */ + public function setNumberofInputAssets($value) + { + $this->_numberofInputAssets = $value; + } + + /** + * Get "Job template body" + * + * @return string + */ + public function getJobTemplateBody() + { + return $this->_jobTemplateBody; + } + + /** + * Set "Job template body" + * + * @param string $value Job template body + * + * @return none + */ + public function setJobTemplateBody($value) + { + $this->_jobTemplateBody = $value; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/MediaServices/Models/Locator.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/MediaServices/Models/Locator.php new file mode 100644 index 0000000..be5ef0f --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/MediaServices/Models/Locator.php @@ -0,0 +1,413 @@ + + * @copyright Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\MediaServices\Models; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Validate; + +/** + * Represents locator object used in media services + * + * @category Microsoft + * @package WindowsAzure\MediaServices\Models + * @author Azure PHP SDK + * @copyright Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class Locator +{ + /** + * Type of Locator - none - The default enumeration value + * + * @var int + */ + const TYPE_NONE = 0; + + /** + * Type of Locator - SAS - Specifies Shared Access Signature (Sas) + * + * @var int + */ + const TYPE_SAS = 1; + + /** + * Type of Locator - OnDemandOrigin - Specifies a locator type which refers to + * an Azure Media Service On Demand Origin streaming endpoint + * + * @var int + */ + const TYPE_ON_DEMAND_ORIGIN = 2; + + /** + * Locator id + * + * @var string + */ + private $_id; + + /** + * Name + * + * @var string + */ + private $_name; + + /** + * Expiration date time + * + * @var \DateTime + */ + private $_expirationDateTime; + + /** + * Type + * + * @var int + */ + private $_type; + + /** + * Path + * + * @var string + */ + private $_path; + + /** + * Base URI + * + * @var string + */ + private $_baseUri; + + /** + * Content access component + * + * @var string + */ + private $_contentAccessComponent; + + /** + * Access policy Id + * + * @var string + */ + private $_accessPolicyId; + + /** + * Asset id + * + * @var string + */ + private $_assetId; + + /** + * Start time + * + * @var \DateTime + */ + private $_startTime; + + /** + * Create locator from array + * + * @param array $options Array containing values for object properties + * + * @return WindowsAzure\MediaServices\Models\Locator + */ + public static function createFromOptions($options) + { + Validate::notNull($options['AssetId'], 'options[AssetId]'); + Validate::notNull($options['AccessPolicyId'], 'options[AccessPolicyId]'); + Validate::notNull($options['Type'], 'options[Type]'); + + $locator = new Locator( + $options['AssetId'], + $options['AccessPolicyId'], + $options['Type'] + ); + $locator->fromArray($options); + + return $locator; + } + + /** + * Create locator + * + * @param WindowsAzure\MediaServices\Models\Asset|string $asset A + * target asset + * + * @param WindowsAzure\MediaServices\Models\AccessPolicy|string $accessPolicy A + * target access policy + * + * @param int $type An + * enumeration value that describes the type of Locator. + */ + public function __construct($asset, $accessPolicy, $type) + { + $this->_assetId = Utilities::getEntityId( + $asset, + 'WindowsAzure\MediaServices\Models\Asset' + ); + $this->_accessPolicyId = Utilities::getEntityId( + $accessPolicy, + 'WindowsAzure\MediaServices\Models\AccessPolicy' + ); + $this->_type = $type; + } + + /** + * Fill locator from array + * + * @param array $options Array containing values for object properties + * + * @return none + */ + public function fromArray($options) + { + if (isset($options['Id'])) { + Validate::isString($options['Id'], 'options[Id]'); + $this->_id = $options['Id']; + } + + if (isset($options['Name'])) { + Validate::isString($options['Name'], 'options[Name]'); + $this->_name = $options['Name']; + } + + if (isset($options['ExpirationDateTime'])) { + Validate::isDateString( + $options['ExpirationDateTime'], + 'options[ExpirationDateTime]' + ); + $this->_expirationDateTime = new \DateTime( + $options['ExpirationDateTime'] + ); + } + + if (isset($options['Type'])) { + Validate::isInteger($options['Type'], 'options[Type]'); + $this->_type = $options['Type']; + } + + if (isset($options['Path'])) { + Validate::isValidUri($options['Path'], 'options[Path]'); + $this->_path = $options['Path']; + } + + if (isset($options['BaseUri'])) { + Validate::isValidUri($options['BaseUri'], 'options[BaseUri]'); + $this->_baseUri = $options['BaseUri']; + } + + if (isset($options['ContentAccessComponent'])) { + Validate::isString( + $options['ContentAccessComponent'], + 'options[ContentAccessComponent]' + ); + $this->_contentAccessComponent = $options['ContentAccessComponent']; + } + + if (isset($options['AccessPolicyId'])) { + Validate::isString( + $options['AccessPolicyId'], + 'options[AccessPolicyId]' + ); + $this->_accessPolicyId = $options['AccessPolicyId']; + } + + if (isset($options['AssetId'])) { + Validate::isString($options['AssetId'], 'options[AssetId]'); + $this->_assetId = $options['AssetId']; + } + + if (isset($options['StartTime'])) { + Validate::isDateString($options['StartTime'], 'options[StartTime]'); + $this->_startTime = new \DateTime($options['StartTime']); + } + } + + /** + * Get "Start time" + * + * @return \DateTime + */ + public function getStartTime() + { + return $this->_startTime; + } + + /** + * Set "Start time" + * + * @param \DateTime $value Start time + * + * @return none + */ + public function setStartTime($value) + { + $this->_startTime = $value; + } + + /** + * Get "Asset id" + * + * @return string + */ + public function getAssetId() + { + return $this->_assetId; + } + + /** + * Get "Access policy Id" + * + * @return string + */ + public function getAccessPolicyId() + { + return $this->_accessPolicyId; + } + + /** + * Get "Content access component" + * + * @return string + */ + public function getContentAccessComponent() + { + return $this->_contentAccessComponent; + } + + /** + * Get "Base URI" + * + * @return string + */ + public function getBaseUri() + { + return $this->_baseUri; + } + + /** + * Get "Path" + * + * @return string + */ + public function getPath() + { + return $this->_path; + } + + /** + * Get "Type" + * + * @return int + */ + public function getType() + { + return $this->_type; + } + + /** + * Set "Type" + * + * @param int $value Type + * + * @return none + */ + public function setType($value) + { + $this->_type = $value; + } + + /** + * Get "Expiration date time" + * + * @return \DateTime + */ + public function getExpirationDateTime() + { + return $this->_expirationDateTime; + } + + /** + * Set "Expiration date time" + * + * @param \DateTime $value Expiration date time + * + * @return none + */ + public function setExpirationDateTime($value) + { + $this->_expirationDateTime = $value; + } + + /** + * Get "Name" + * + * @return string + */ + public function getName() + { + return $this->_name; + } + + /** + * Set "Name" + * + * @param string $value Name + * + * @return none + */ + public function setName($value) + { + $this->_name = $value; + } + + /** + * Get "Locator id" + * + * @return string + */ + public function getId() + { + return $this->_id; + } + + /** + * Set "Locator id" + * + * @param string $value Locator id + * + * @return none + */ + public function setId($value) + { + $this->_id = $value; + } +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/MediaServices/Models/MediaProcessor.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/MediaServices/Models/MediaProcessor.php new file mode 100644 index 0000000..f09fb9a --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/MediaServices/Models/MediaProcessor.php @@ -0,0 +1,207 @@ + + * @copyright Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\MediaServices\Models; +use WindowsAzure\Common\Internal\Validate; + + +/** + * Represents task historical event object used in media services + * + * @category Microsoft + * @package WindowsAzure\MediaServices\Models + * @author Azure PHP SDK + * @copyright Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class MediaProcessor +{ + /** + * id + * + * @var string + */ + private $_id; + + /** + * Name + * + * @var string + */ + private $_name; + + /** + * Description + * + * @var string + */ + private $_description; + + /** + * SKU + * + * @var string + */ + private $_sku; + + /** + * Vendor + * + * @var string + */ + private $_vendor; + + /** + * Version + * + * @var string + */ + private $_version; + + /** + * Create media processor from array + * + * @param array $options Array containing values for object properties + * + * @return WindowsAzure\MediaServices\Models\MediaProcessor + */ + public static function createFromOptions($options) + { + $mediaProcessor = new MediaProcessor(); + $mediaProcessor->fromArray($options); + + return $mediaProcessor; + } + + /** + * Create media processor + */ + public function __construct() + { + } + + /** + * Fill media processor from array + * + * @param array $options Array containing values for object properties + * + * @return none + */ + public function fromArray($options) + { + if (isset($options['Id'])) { + Validate::isString($options['Id'], 'options[Id]'); + $this->_id = $options['Id']; + } + + if (isset($options['Name'])) { + Validate::isString($options['Name'], 'options[Name]'); + $this->_name = $options['Name']; + } + + if (isset($options['Description'])) { + Validate::isString($options['Description'], 'options[Description]'); + $this->_description = $options['Description']; + } + + if (isset($options['Sku'])) { + Validate::isString($options['Sku'], 'options[Sku]'); + $this->_sku = $options['Sku']; + } + + if (isset($options['Vendor'])) { + Validate::isString($options['Vendor'], 'options[Vendor]'); + $this->_vendor = $options['Vendor']; + } + + if (isset($options['Version'])) { + Validate::isString($options['Version'], 'options[Version]'); + $this->_version = $options['Version']; + } + + } + + /** + * Get "Version" + * + * @return string + */ + public function getVersion() + { + return $this->_version; + } + + /** + * Get "Vendor" + * + * @return string + */ + public function getVendor() + { + return $this->_vendor; + } + + /** + * Get "SKU" + * + * @return string + */ + public function getSku() + { + return $this->_sku; + } + + /** + * Get "Description" + * + * @return string + */ + public function getDescription() + { + return $this->_description; + } + + /** + * Get "Name" + * + * @return string + */ + public function getName() + { + return $this->_name; + } + + /** + * Get "id" + * + * @return string + */ + public function getId() + { + return $this->_id; + } +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/MediaServices/Models/StorageAccount.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/MediaServices/Models/StorageAccount.php new file mode 100644 index 0000000..c1c9a9b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/MediaServices/Models/StorageAccount.php @@ -0,0 +1,118 @@ + + * @copyright Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\MediaServices\Models; +use WindowsAzure\Common\Internal\Validate; + +/** + * Represents storage account object used in media services + * + * @category Microsoft + * @package WindowsAzure\MediaServices\Models + * @author Azure PHP SDK + * @copyright Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class StorageAccount +{ + /** + * Name + * + * @var string + */ + private $_name; + + /** + * Is default + * + * @var boolean + */ + private $_isDefault; + + /** + * Create storage account from array + * + * @param array $options Array containing values for object properties + * + * @return WindowsAzure\MediaServices\Models\StorageAccount + */ + public static function createFromOptions($options) + { + $storageAccount = new StorageAccount(); + $storageAccount->fromArray($options); + + return $storageAccount; + } + + /** + * Create storage account + * + */ + public function __construct() + { + } + + /** + * Fill storage account from array + * + * @param array $options Array containing values for object properties + * + * @return none + */ + public function fromArray($options) + { + if (isset($options['Name'])) { + Validate::isString($options['Name'], 'options[Name]'); + $this->_name = $options['Name']; + } + + if (isset($options['IsDefault'])) { + Validate::isBoolean($options['IsDefault'], 'options[IsDefault]'); + $this->_isDefault = $options['IsDefault']; + } + } + + /** + * Get "Name" + * + * @return string + */ + public function getName() + { + return $this->_name; + } + + /** + * Get "Is default" + * + * @return boolean + */ + public function getIsDefault() + { + return $this->_isDefault; + } +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/MediaServices/Models/Task.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/MediaServices/Models/Task.php new file mode 100644 index 0000000..89728f8 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/MediaServices/Models/Task.php @@ -0,0 +1,675 @@ + + * @copyright Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\MediaServices\Models; +use WindowsAzure\Common\Internal\Validate; +use WindowsAzure\MediaServices\Models\TaskHistoricalEvent; +use WindowsAzure\MediaServices\Models\ErrorDetail; + + +/** + * Represents task object used in media services + * + * @category Microsoft + * @package WindowsAzure\MediaServices\Models + * @author Azure PHP SDK + * @copyright Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class Task +{ + /** + * The state of the task "none" + * + * @var int + */ + const STATE_NONE = 0; + + /** + * The state of the task "active" + * + * @var int + */ + const STATE_ACTIVE = 1; + + /** + * The state of the task "running" + * + * @var int + */ + const STATE_RUNNING = 2; + + /** + * The state of the task "completed" + * + * @var int + */ + const STATE_COMPLETED = 3; + + /** + * Task id + * + * @var string + */ + private $_id; + + /** + * Configuration + * + * @var string + */ + private $_configuration; + + /** + * End tine + * + * @var \DateTime + */ + private $_endTime; + + /** + * Media procesot id + * + * @var string + */ + private $_mediaProcessorId; + + /** + * Perfoemance message + * + * @var string + */ + private $_perfMessage; + + /** + * Progress + * + * @var double + */ + private $_progress; + + /** + * Running duration + * + * @var double + */ + private $_runningDuration; + + /** + * Task body + * + * @var string + */ + private $_taskBody; + + /** + * Options + * + * @var int + */ + private $_options; + + /** + * Encription key id + * + * @var string + */ + private $_encryptionKeyId; + + /** + * Encryption scheme + * + * @var string + */ + private $_encryptionScheme; + + /** + * Encryption version + * + * @var string + */ + private $_encryptionVersion; + + /** + * Initialization vector + * + * @var string + */ + private $_initializationVector; + + /** + * State + * + * @var int + */ + private $_state; + + /** + * Name + * + * @var string + */ + private $_name; + + /** + * Priority + * + * @var int + */ + private $_priority; + + /** + * Start time + * + * @var \DateTime + */ + private $_startTime; + + /** + * HistoricalEvents + * + * @var array + */ + private $_historicalEvents; + + /** + * ErrorDetails + * + * @var array + */ + private $_errorDetails; + + /** + * Create task from array + * + * @param array $options Array containing values for object properties + * + * @return WindowsAzure\MediaServices\Models\Task + */ + public static function createFromOptions($options) + { + Validate::notNull($options['TaskBody'], 'options[TaskBody]'); + Validate::notNull($options['Options'], 'options[Options]'); + Validate::notNull($options['MediaProcessorId'], 'options[MediaProcessorId]'); + + $task = new Task( + $options['TaskBody'], + $options['MediaProcessorId'], + $options['Options'] + ); + $task->fromArray($options); + + return $task; + } + + /** + * Create task + * + * @param string $taskBody Task body. + * @param string $mediaProcessorId Media processor identifier. + * @param int $options Task encryption options. + */ + public function __construct($taskBody, $mediaProcessorId, $options) + { + $this->_taskBody = $taskBody; + $this->_options = $options; + $this->_mediaProcessorId = $mediaProcessorId; + } + + /** + * Fill task from array + * + * @param array $options Array containing values for object properties + * + * @return none + */ + public function fromArray($options) + { + if (isset($options['Id'])) { + Validate::isString($options['Id'], 'options[Id]'); + $this->_id = $options['Id']; + } + + if (isset($options['Configuration'])) { + Validate::isString($options['Configuration'], 'options[Configuration]'); + $this->_configuration = $options['Configuration']; + } + + if (isset($options['EndTime'])) { + Validate::isDateString($options['EndTime'], 'options[EndTime]'); + $this->_endTime = new \DateTime($options['EndTime']); + } + + if (isset($options['MediaProcessorId'])) { + Validate::isString( + $options['MediaProcessorId'], + 'options[MediaProcessorId]' + ); + $this->_mediaProcessorId = $options['MediaProcessorId']; + } + + if (isset($options['Name'])) { + Validate::isString($options['Name'], 'options[Name]'); + $this->_name = $options['Name']; + } + + if (isset($options['PerfMessage'])) { + Validate::isString($options['PerfMessage'], 'options[PerfMessage]'); + $this->_perfMessage = $options['PerfMessage']; + } + + if (isset($options['Priority'])) { + Validate::isInteger($options['Priority'], 'options[Priority]'); + $this->_priority = $options['Priority']; + } + + if (isset($options['Progress'])) { + Validate::isDouble($options['Progress'], 'options[Progress]'); + $this->_progress = $options['Progress']; + } + + if (isset($options['RunningDuration'])) { + Validate::isDouble( + $options['RunningDuration'], + 'options[RunningDuration]' + ); + $this->_runningDuration = $options['RunningDuration']; + } + + if (isset($options['StartTime'])) { + Validate::isDateString($options['StartTime'], 'options[StartTime]'); + $this->_startTime = new \DateTime($options['StartTime']); + } + + if (isset($options['State'])) { + Validate::isInteger($options['State'], 'options[State]'); + $this->_state = $options['State']; + } + + if (isset($options['TaskBody'])) { + Validate::isString($options['TaskBody'], 'options[TaskBody]'); + $this->_taskBody = $options['TaskBody']; + } + + if (isset($options['Options'])) { + Validate::isInteger($options['Options'], 'options[Options]'); + $this->_options = $options['Options']; + } + + if (isset($options['EncryptionKeyId'])) { + Validate::isString( + $options['EncryptionKeyId'], + 'options[EncryptionKeyId]' + ); + $this->_encryptionKeyId = $options['EncryptionKeyId']; + } + + if (isset($options['EncryptionScheme'])) { + Validate::isString( + $options['EncryptionScheme'], + 'options[EncryptionScheme]' + ); + $this->_encryptionScheme = $options['EncryptionScheme']; + } + + if (isset($options['EncryptionVersion'])) { + Validate::isString( + $options['EncryptionVersion'], + 'options[EncryptionVersion]' + ); + $this->_encryptionVersion = $options['EncryptionVersion']; + } + + if (isset($options['InitializationVector'])) { + Validate::isString( + $options['InitializationVector'], + 'options[InitializationVector]' + ); + $this->_initializationVector = $options['InitializationVector']; + } + + if (isset($options['ErrorDetails'])) { + $this->_errorDetails = array(); + if (is_array($options['ErrorDetails'])) { + foreach ($options['ErrorDetails'] as $errorDetail) { + $this->_errorDetails[] = ErrorDetail::createFromOptions( + $errorDetail + ); + } + } + } + + if (isset($options['HistoricalEvents'])) { + $this->_historicalEvents = array(); + if (is_array($options['HistoricalEvents'])) { + foreach ($options['HistoricalEvents'] as $historicalEvent) { + $evnt = TaskHistoricalEvent::createFromOptions($historicalEvent); + $this->_historicalEvents[] = $evnt; + } + } + } + + } + + /** + * Get "Name" + * + * @return string + */ + public function getName() + { + return $this->_name; + } + + /** + * Set "Name" + * + * @param string $value Name + * + * @return none + */ + public function setName($value) + { + $this->_name = $value; + } + + /** + * Get "State" + * + * @return int + */ + public function getState() + { + return $this->_state; + } + + /** + * Get "Task id" + * + * @return string + */ + public function getId() + { + return $this->_id; + } + + /** + * Get "Start time" + * + * @return \DateTime + */ + public function getStartTime() + { + return $this->_startTime; + } + + /** + * Get "Running duration" + * + * @return double + */ + public function getRunningDuration() + { + return $this->_runningDuration; + } + + /** + * Get "Priority" + * + * @return int + */ + public function getPriority() + { + return $this->_priority; + } + + /** + * Set "Priority" + * + * @param int $value Priority + * + * @return none + */ + public function setPriority($value) + { + $this->_priority = $value; + } + + /** + * Get "End time" + * + * @return \DateTime + */ + public function getEndTime() + { + return $this->_endTime; + } + + /** + * Get "Initialization vector" + * + * @return string + */ + public function getInitializationVector() + { + return $this->_initializationVector; + } + + /** + * Set "Initialization vector" + * + * @param string $value Initialization vector + * + * @return none + */ + public function setInitializationVector($value) + { + $this->_initializationVector = $value; + } + + /** + * Get "Encryption version" + * + * @return string + */ + public function getEncryptionVersion() + { + return $this->_encryptionVersion; + } + + /** + * Set "Encryption version" + * + * @param string $value Encryption version + * + * @return none + */ + public function setEncryptionVersion($value) + { + $this->_encryptionVersion = $value; + } + + /** + * Get "Encryption scheme" + * + * @return string + */ + public function getEncryptionScheme() + { + return $this->_encryptionScheme; + } + + /** + * Set "Encryption scheme" + * + * @param string $value Encryption scheme + * + * @return none + */ + public function setEncryptionScheme($value) + { + $this->_encryptionScheme = $value; + } + + /** + * Get "Encription key id" + * + * @return string + */ + public function getEncryptionKeyId() + { + return $this->_encryptionKeyId; + } + + /** + * Set "Encription key id" + * + * @param string $value Encription key id + * + * @return none + */ + public function setEncryptionKeyId($value) + { + $this->_encryptionKeyId = $value; + } + + /** + * Get "Options" + * + * @return int + */ + public function getOptions() + { + return $this->_options; + } + + /** + * Get "Task body" + * + * @return string + */ + public function getTaskBody() + { + return $this->_taskBody; + } + + /** + * Set "Task body" + * + * @param string $value Task body + * + * @return none + */ + public function setTaskBody($value) + { + $this->_taskBody = $value; + } + + /** + * Get "Progress" + * + * @return double + */ + public function getProgress() + { + return $this->_progress; + } + + /** + * Get "Perfoemance message" + * + * @return string + */ + public function getPerfMessage() + { + return $this->_perfMessage; + } + + /** + * Get "Media procesot id" + * + * @return string + */ + public function getMediaProcessorId() + { + return $this->_mediaProcessorId; + } + + /** + * Set "Media procesot id" + * + * @param string $value Media procesot id + * + * @return none + */ + public function setMediaProcessorId($value) + { + $this->_mediaProcessorId = $value; + } + + /** + * Get "Configuration" + * + * @return string + */ + public function getConfiguration() + { + return $this->_configuration; + } + + /** + * Set "Configuration" + * + * @param string $value Configuration + * + * @return none + */ + public function setConfiguration($value) + { + $this->_configuration = $value; + } + + /** + * Get "ErrorDetails" + * + * @return array + */ + public function getErrorDetails() + { + return $this->_errorDetails; + } + + /** + * Get "HistoricalEvents" + * + * @return array + */ + public function getHistoricalEvents() + { + return $this->_historicalEvents; + } +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/MediaServices/Models/TaskHistoricalEvent.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/MediaServices/Models/TaskHistoricalEvent.php new file mode 100644 index 0000000..f9c4d76 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/MediaServices/Models/TaskHistoricalEvent.php @@ -0,0 +1,140 @@ + + * @copyright Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\MediaServices\Models; +use WindowsAzure\Common\Internal\Validate; + + +/** + * Represents task historical event object used in media services + * + * @category Microsoft + * @package WindowsAzure\MediaServices\Models + * @author Azure PHP SDK + * @copyright Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class TaskHistoricalEvent +{ + /** + * Code + * + * @var int + */ + private $_code; + + /** + * Message + * + * @var string + */ + private $_message; + + /** + * Time stamp + * + * @var \DateTime + */ + private $_timeStamp; + + /** + * Create task historical event from array + * + * @param array $options Array containing values for object properties + * + * @return WindowsAzure\MediaServices\Models\TaskHistoricalEvent + */ + public static function createFromOptions($options) + { + $taskHistoricalEvent = new TaskHistoricalEvent(); + $taskHistoricalEvent->fromArray($options); + + return $taskHistoricalEvent; + } + + /** + * Create task historical event + */ + public function __construct() + { + } + + /** + * Fill task historical event from array + * + * @param array $options Array containing values for object properties + * + * @return none + */ + public function fromArray($options) + { + if (isset($options['Code'])) { + Validate::isInteger($options['Code'], 'options[Code]'); + $this->_code = $options['Code']; + } + + if (isset($options['Message'])) { + Validate::isString($options['Message'], 'options[Message]'); + $this->_message = $options['Message']; + } + + if (isset($options['TimeStamp'])) { + Validate::isDateString($options['TimeStamp'], 'options[TimeStamp]'); + $this->_timeStamp = new \DateTime($options['TimeStamp']); + } + } + + /** + * Get "Time stamp" + * + * @return \DateTime + */ + public function getTimeStamp() + { + return $this->_timeStamp; + } + + /** + * Get "Message" + * + * @return string + */ + public function getMessage() + { + return $this->_message; + } + + /** + * Get "Code" + * + * @return int + */ + public function getCode() + { + return $this->_code; + } +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/MediaServices/Models/TaskOptions.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/MediaServices/Models/TaskOptions.php new file mode 100644 index 0000000..b3d9862 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/MediaServices/Models/TaskOptions.php @@ -0,0 +1,56 @@ + + * @copyright Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\MediaServices\Models; +use WindowsAzure\Common\Internal\Validate; + + +/** + * Represents task options enum used in media services + * + * @category Microsoft + * @package WindowsAzure\MediaServices\Models + * @author Azure PHP SDK + * @copyright Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class TaskOptions +{ + /** + * The options of the task "none" + * + * @var int + */ + const NONE = 0; + + /** + * The options of the task "protected configuration" + * + * @var int + */ + const PROTECTED_CONFIGURATION = 1; +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/MediaServices/Models/TaskTemplate.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/MediaServices/Models/TaskTemplate.php new file mode 100644 index 0000000..d00ed9c --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/MediaServices/Models/TaskTemplate.php @@ -0,0 +1,547 @@ + + * @copyright Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\MediaServices\Models; +use WindowsAzure\Common\Internal\Validate; +use WindowsAzure\Common\Internal\Utilities; + + +/** + * Represents task template object used in media services + * + * @category Microsoft + * @package WindowsAzure\MediaServices\Models + * @author Azure PHP SDK + * @copyright Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class TaskTemplate +{ + /** + * Task template id + * + * @var string + */ + private $_id; + + /** + * Configuration + * + * @var string + */ + private $_configuration; + + /** + * Created + * + * @var \DateTime + */ + private $_created; + + /** + * Last modified date + * + * @var \DateTime + */ + private $_lastModified; + + /** + * Description + * + * @var string + */ + private $_description; + + /** + * Media processor id + * + * @var string + */ + private $_mediaProcessorId; + + /** + * Name + * + * @var string + */ + private $_name; + + /** + * Number of input assets + * + * @var int + */ + private $_numberofInputAssets; + + /** + * Number of output assets + * + * @var int + */ + private $_numberofOutputAssets; + + /** + * Options + * + * @var int + */ + private $_options; + + /** + * Encription key id + * + * @var string + */ + private $_encryptionKeyId; + + /** + * Encryption scheme + * + * @var string + */ + private $_encryptionScheme; + + /** + * Encryption version + * + * @var string + */ + private $_encryptionVersion; + + /** + * Initialization vector + * + * @var string + */ + private $_initializationVector; + + /** + * Create task template from array + * + * @param array $options Array containing values for object properties + * + * @return WindowsAzure\MediaServices\Models\TaskTemplate + */ + public static function createFromOptions($options) + { + Validate::notNull( + $options['NumberofInputAssets'], + 'options[NumberofInputAssets]' + ); + Validate::notNull( + $options['NumberofOutputAssets'], + 'options[NumberofOutputAssets]' + ); + + $taskTemplate = new TaskTemplate( + $options['NumberofInputAssets'], + $options['NumberofOutputAssets'] + ); + $taskTemplate->fromArray($options); + + return $taskTemplate; + } + + /** + * Create task + * + * @param int $numberOfInputAssets Number of input Assets the TaskTemplate + * must process. + * @param int $numberOfOutputAssets Number of output Assets the TaskTemplate + * must process. + */ + public function __construct($numberOfInputAssets, $numberOfOutputAssets) + { + $this->_id = 'nb:ttid:UUID:' . Utilities::getGuid(); + $this->_numberofInputAssets = $numberOfInputAssets; + $this->_numberofOutputAssets = $numberOfOutputAssets; + } + + /** + * Fill task template from array + * + * @param array $options Array containing values for object properties + * + * @return none + */ + public function fromArray($options) + { + if (isset($options['Id'])) { + Validate::isString($options['Id'], 'options[Id]'); + $this->_id = $options['Id']; + } + + if (isset($options['Configuration'])) { + Validate::isString($options['Configuration'], 'options[Configuration]'); + $this->_configuration = $options['Configuration']; + } + + if (isset($options['Created'])) { + Validate::isDateString($options['Created'], 'options[Created]'); + $this->_created = new \DateTime($options['Created']); + } + + if (isset($options['Description'])) { + Validate::isString($options['Description'], 'options[Description]'); + $this->_description = $options['Description']; + } + + if (isset($options['LastModified'])) { + Validate::isDateString( + $options['LastModified'], + 'options[LastModified]' + ); + $this->_lastModified = new \DateTime($options['LastModified']); + } + + if (isset($options['MediaProcessorId'])) { + Validate::isString( + $options['MediaProcessorId'], + 'options[MediaProcessorId]' + ); + $this->_mediaProcessorId = $options['MediaProcessorId']; + } + + if (isset($options['Name'])) { + Validate::isString($options['Name'], 'options[Name]'); + $this->_name = $options['Name']; + } + + if (isset($options['NumberofInputAssets'])) { + Validate::isInteger( + $options['NumberofInputAssets'], + 'options[NumberofInputAssets]' + ); + $this->_numberofInputAssets = $options['NumberofInputAssets']; + } + + if (isset($options['NumberofOutputAssets'])) { + Validate::isInteger( + $options['NumberofOutputAssets'], + 'options[NumberofOutputAssets]' + ); + $this->_numberofOutputAssets = $options['NumberofOutputAssets']; + } + + if (isset($options['Options'])) { + Validate::isInteger($options['Options'], 'options[Options]'); + $this->_options = $options['Options']; + } + + if (isset($options['EncryptionKeyId'])) { + Validate::isString( + $options['EncryptionKeyId'], + 'options[EncryptionKeyId]' + ); + $this->_encryptionKeyId = $options['EncryptionKeyId']; + } + + if (isset($options['EncryptionScheme'])) { + Validate::isString( + $options['EncryptionScheme'], + 'options[EncryptionScheme]' + ); + $this->_encryptionScheme = $options['EncryptionScheme']; + } + + if (isset($options['EncryptionVersion'])) { + Validate::isString( + $options['EncryptionVersion'], + 'options[EncryptionVersion]' + ); + $this->_encryptionVersion = $options['EncryptionVersion']; + } + + if (isset($options['InitializationVector'])) { + Validate::isString( + $options['InitializationVector'], + 'options[InitializationVector]' + ); + $this->_initializationVector = $options['InitializationVector']; + } + } + + /** + * Get "Name" + * + * @return string + */ + public function getName() + { + return $this->_name; + } + + /** + * Set "Name" + * + * @param string $value Name + * + * @return none + */ + public function setName($value) + { + $this->_name = $value; + } + + /** + * Get "Task template id" + * + * @return string + */ + public function getId() + { + return $this->_id; + } + + /** + * Get "Initialization vector" + * + * @return string + */ + public function getInitializationVector() + { + return $this->_initializationVector; + } + + /** + * Set "Initialization vector" + * + * @param string $value Initialization vector + * + * @return none + */ + public function setInitializationVector($value) + { + $this->_initializationVector = $value; + } + + /** + * Get "Encryption version" + * + * @return string + */ + public function getEncryptionVersion() + { + return $this->_encryptionVersion; + } + + /** + * Set "Encryption version" + * + * @param string $value Encryption version + * + * @return none + */ + public function setEncryptionVersion($value) + { + $this->_encryptionVersion = $value; + } + + /** + * Get "Encryption scheme" + * + * @return string + */ + public function getEncryptionScheme() + { + return $this->_encryptionScheme; + } + + /** + * Set "Encryption scheme" + * + * @param string $value Encryption scheme + * + * @return none + */ + public function setEncryptionScheme($value) + { + $this->_encryptionScheme = $value; + } + + /** + * Get "Encription key id" + * + * @return string + */ + public function getEncryptionKeyId() + { + return $this->_encryptionKeyId; + } + + /** + * Set "Encription key id" + * + * @param string $value Encription key id + * + * @return none + */ + public function setEncryptionKeyId($value) + { + $this->_encryptionKeyId = $value; + } + + /** + * Get "Options" + * + * @return int + */ + public function getOptions() + { + return $this->_options; + } + + /** + * Get "Media processor id" + * + * @return string + */ + public function getMediaProcessorId() + { + return $this->_mediaProcessorId; + } + + /** + * Set "Media processor id" + * + * @param string $value Media procesot id + * + * @return none + */ + public function setMediaProcessorId($value) + { + $this->_mediaProcessorId = $value; + } + + /** + * Get "Configuration" + * + * @return string + */ + public function getConfiguration() + { + return $this->_configuration; + } + + /** + * Set "Configuration" + * + * @param string $value Configuration + * + * @return none + */ + public function setConfiguration($value) + { + $this->_configuration = $value; + } + + /** + * Get "Created" + * + * @return \DateTime + */ + public function getCreated() + { + return $this->_created; + } + + /** + * Get "Last modified date" + * + * @return \DateTime + */ + public function getLastModified() + { + return $this->_lastModified; + } + + /** + * Get "Description" + * + * @return string + */ + public function getDescription() + { + return $this->_description; + } + + /** + * Set "Description" + * + * @param string $value Description + * + * @return none + */ + public function setDescription($value) + { + $this->_description = $value; + } + + /** + * Get "Number of output assets" + * + * @return int + */ + public function getNumberofOutputAssets() + { + return $this->_numberofOutputAssets; + } + + /** + * Set "Number of output assets" + * + * @param int $value Number of output assets + * + * @return none + */ + public function setNumberofOutputAssets($value) + { + $this->_numberofOutputAssets = $value; + } + + /** + * Get "Number of input assets" + * + * @return int + */ + public function getNumberofInputAssets() + { + return $this->_numberofInputAssets; + } + + /** + * Set "Number of input assets" + * + * @param int $value Number of input assets + * + * @return none + */ + public function setNumberofInputAssets($value) + { + $this->_numberofInputAssets = $value; + } +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Queue/Internal/IQueue.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Queue/Internal/IQueue.php new file mode 100644 index 0000000..aa8fa56 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Queue/Internal/IQueue.php @@ -0,0 +1,197 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Queue\Internal; +use WindowsAzure\Common\Internal\FilterableService; + +/** + * This interface has all REST APIs provided by Windows Azure for queue service + * + * @category Microsoft + * @package WindowsAzure\Queue\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179363.aspx + */ +interface IQueue extends FilterableService +{ + /** + * Gets the properties of the Queue service. + * + * @param QueueServiceOptions $options The optional parameters. + * + * @return WindowsAzure\Common\Models\GetServicePropertiesResult + */ + public function getServiceProperties($options = null); + + /** + * Sets the properties of the Queue service. + * + * It's recommended to use getServiceProperties, alter the returned object and + * then use setServiceProperties with this altered object. + * + * @param array $serviceProperties The new service properties. + * @param QueueServiceOptions $options The optional parameters. + * + * @return none + */ + public function setServiceProperties($serviceProperties, $options = null); + + /** + * Creates a new queue under the storage account. + * + * @param string $queueName The queue name. + * @param QueueCreateOptions $options The optional queue create options. + * + * @return none + */ + public function createQueue($queueName, $options = null); + + /** + * Deletes a queue. + * + * @param string $queueName The queue name. + * @param QueueServiceOptions $options The optional parameters. + * + * @return none + */ + public function deleteQueue($queueName, $options); + + /** + * Lists all queues in the storage account. + * + * @param ListQueuesOptions $options The optional parameters. + * + * @return WindowsAzure\Common\Models\ListQueuesResult + */ + public function listQueues($options = null); + + /** + * Returns queue properties, including user-defined metadata. + * + * @param string $queueName The queue name. + * @param QueueServiceOptions $options The optional parameters. + * + * @return WindowsAzure\Common\Models\GetQueueMetadataResult + */ + public function getQueueMetadata($queueName, $options = null); + + /** + * Sets user-defined metadata on the queue. To delete queue metadata, call + * this API without specifying any metadata in $metadata. + * + * @param string $queueName The queue name. + * @param array $metadata The metadata array. + * @param QueueServiceOptions $options The optional parameters. + * + * @return none + */ + public function setQueueMetadata($queueName, $metadata, $options = null); + + /** + * Adds a message to the queue and optionally sets a visibility timeout + * for the message. + * + * @param string $queueName The queue name. + * @param string $messageText The message contents. + * @param CreateMessageOptions $options The optional parameters. + * + * @return none + */ + public function createMessage($queueName, $messageText, $options = null); + + /** + * Updates the visibility timeout of a message and/or the message contents. + * + * @param string $queueName The queue name. + * @param string $messageId The id of the message. + * @param string $popReceipt The valid pop receipt + * value returned from an earlier call to the Get Messages or Update Message + * operation. + * @param string $messageText The message contents. + * @param int $visibilityTimeoutInSeconds Specifies the new + * visibility timeout value, in seconds, relative to server time. + * The new value must be larger than or equal to 0, and cannot be larger + * than 7 days. The visibility timeout of a message cannot be set to a value + * later than the expiry time. A message can be updated until it has been + * deleted or has expired. + * @param QueueServiceOptions $options The optional + * parameters. + * + * @return WindowsAzure\Common\Models\UpdateMessageResult + */ + public function updateMessage($queueName, $messageId, $popReceipt, $messageText, + $visibilityTimeoutInSeconds, $options = null + ); + + /** + * Deletes a specified message from the queue. + * + * @param string $queueName The queue name. + * @param string $messageId The id of the message. + * @param string $popReceipt The valid pop receipt value returned + * from an earlier call to the Get Messages or Update Message operation. + * @param QueueServiceOptions $options The optional parameters. + * + * @return none + */ + public function deleteMessage($queueName, $messageId, $popReceipt, + $options = null + ); + + /** + * Lists all messages in the queue. + * + * @param string $queueName The queue name. + * @param ListMessagesOptions $options The optional parameters. + * + * @return WindowsAzure\Common\Models\ListMessagesResult + */ + public function listMessages($queueName, $options = null); + + /** + * Retrieves a message from the front of the queue, without changing + * the message visibility. + * + * @param string $queueName The queue name. + * @param PeekMessagesOptions $options The optional parameters. + * + * @return WindowsAzure\Common\Models\PeekMessagesResult + */ + public function peekMessages($queueName, $options = null); + + /** + * Clears all messages from the queue. + * + * @param string $queueName The queue name. + * @param QueueServiceOptions $options The optional parameters. + * + * @return WindowsAzure\Common\Models\PeekMessagesResult + */ + public function clearMessages($queueName, $options = null); +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Queue/Models/CreateMessageOptions.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Queue/Models/CreateMessageOptions.php new file mode 100644 index 0000000..dcf3b5b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Queue/Models/CreateMessageOptions.php @@ -0,0 +1,107 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Queue\Models; + +/** + * Holds optional parameters for createMessage wrapper. + * + * @category Microsoft + * @package WindowsAzure\Queue\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class CreateMessageOptions extends QueueServiceOptions +{ + /** + * If specified, the request must be made using an x-ms-version + * of 2011-08-18 or newer. If not specified, the default value is 0. + * Specifies the new visibility timeout value, in seconds, relative to server + * time. The new value must be larger than or equal to 0, and cannot be + * larger than 7 days. The visibility timeout of a message cannot be set to a + * value later than the expiry time. visibilitytimeout should be set to a + * value smaller than the time-to-live value. + * + * @var integer + */ + private $_visibilityTimeoutInSeconds; + + /** + * Specifies the time-to-live interval for the message, in seconds. + * The maximum time-to-live allowed is 7 days. If this parameter is omitted, + * the default time-to-live is 7 days. + * + * @var integer + */ + private $_timeToLiveInSeconds; + + /** + * Gets visibilityTimeoutInSeconds field. + * + * @return integer + */ + public function getVisibilityTimeoutInSeconds() + { + return $this->_visibilityTimeoutInSeconds; + } + + /** + * Sets visibilityTimeoutInSeconds field. + * + * @param integer $visibilityTimeoutInSeconds value to use. + * + * @return none + */ + public function setVisibilityTimeoutInSeconds($visibilityTimeoutInSeconds) + { + $this->_visibilityTimeoutInSeconds = $visibilityTimeoutInSeconds; + } + + /** + * Gets timeToLiveInSeconds field. + * + * @return integer + */ + public function getTimeToLiveInSeconds() + { + return $this->_timeToLiveInSeconds; + } + + /** + * Sets timeToLiveInSeconds field. + * + * @param integer $timeToLiveInSeconds value to use. + * + * @return none + */ + public function setTimeToLiveInSeconds($timeToLiveInSeconds) + { + $this->_timeToLiveInSeconds = $timeToLiveInSeconds; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Queue/Models/CreateQueueOptions.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Queue/Models/CreateQueueOptions.php new file mode 100644 index 0000000..32774ff --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Queue/Models/CreateQueueOptions.php @@ -0,0 +1,80 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Queue\Models; + +/** + * Optional parameters for Create Queue REST API. + * + * @category Microsoft + * @package WindowsAzure\Queue\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class CreateQueueOptions extends QueueServiceOptions +{ + private $_metadata; + + /** + * Gets user defined metadata. + * + * @return array. + */ + public function getMetadata() + { + return $this->_metadata; + } + + /** + * Sets user defined metadata. This metadata should be added without the header + * prefix (x-ms-meta-*). + * + * @param array $metadata user defined metadata object in array form. + * + * @return none. + */ + public function setMetadata($metadata) + { + $this->_metadata = $metadata; + } + + /** + * Adds new metadata element. This element should be added without the header + * prefix (x-ms-meta-*). + * + * @param string $key metadata key element. + * @param string $value metadata value element. + * + * @return none. + */ + public function addMetadata($key, $value) + { + $this->_metadata[$key] = $value; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Queue/Models/GetQueueMetadataResult.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Queue/Models/GetQueueMetadataResult.php new file mode 100644 index 0000000..667c649 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Queue/Models/GetQueueMetadataResult.php @@ -0,0 +1,112 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Queue\Models; + +/** + * Holds result from calling GetQueueMetadata wrapper + * + * @category Microsoft + * @package WindowsAzure\Queue\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class GetQueueMetadataResult +{ + /** + * Indicates the approximate number of messages in the queue + * + * @var integer + */ + private $_approximateMessageCount; + + /** + * A user-defined name/value pair + * + * @var array + */ + private $_metadata; + + /** + * Constructor + * + * @param integer $approximateMessageCount Approximate number of queue messages. + * @param array $metadata user defined metadata. + */ + public function __construct($approximateMessageCount, $metadata) + { + $this->_approximateMessageCount = $approximateMessageCount; + $this->_metadata = is_null($metadata) ? array() : $metadata; + } + + /** + * Gets approximate message count. + * + * @return integer + */ + public function getApproximateMessageCount() + { + return $this->_approximateMessageCount; + } + + /** + * Sets approximate message count. + * + * @param integer $approximateMessageCount value to use. + * + * @return none + */ + public function setApproximateMessageCount($approximateMessageCount) + { + $this->_approximateMessageCount = $approximateMessageCount; + } + + /** + * Sets metadata. + * + * @return array + */ + public function getMetadata() + { + return $this->_metadata; + } + + /** + * Sets metadata. + * + * @param array $metadata value to use. + * + * @return none + */ + public function setMetadata($metadata) + { + $this->_metadata = $metadata; + } + +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Queue/Models/ListMessagesOptions.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Queue/Models/ListMessagesOptions.php new file mode 100644 index 0000000..08c2915 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Queue/Models/ListMessagesOptions.php @@ -0,0 +1,107 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Queue\Models; + +/** + * Optional parameters for list messages wrapper. + * + * @category Microsoft + * @package WindowsAzure\Queue\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class ListMessagesOptions extends QueueServiceOptions +{ + /** + * A nonzero integer value that specifies the number of messages to retrieve + * from the queue, up to a maximum of 32. If fewer are visible, + * the visible messages are returned. By default, a single message is retrieved + * from the queue with this operation. + * + * @var integer + */ + private $_numberOfMessages; + + /** + * Specifies the new visibility timeout value, in seconds, + * relative to server time. The new value must be larger than or equal to + * 1 second, and cannot be larger than 7 days, or larger than 2 hours on + * REST protocol versions prior to version 2011-08-18. + * The visibility timeout of a message can be set to a value later than the + * expiry time. + * + * @var integer + */ + private $_visibilityTimeoutInSeconds; + + /** + * Gets visibilityTimeoutInSeconds field. + * + * @return integer + */ + public function getVisibilityTimeoutInSeconds() + { + return $this->_visibilityTimeoutInSeconds; + } + + /** + * Sets visibilityTimeoutInSeconds field. + * + * @param integer $visibilityTimeoutInSeconds value to use. + * + * @return none + */ + public function setVisibilityTimeoutInSeconds($visibilityTimeoutInSeconds) + { + $this->_visibilityTimeoutInSeconds = $visibilityTimeoutInSeconds; + } + + /** + * Gets numberOfMessages field. + * + * @return integer + */ + public function getNumberOfMessages() + { + return $this->_numberOfMessages; + } + + /** + * Sets numberOfMessages field. + * + * @param integer $numberOfMessages value to use. + * + * @return none + */ + public function setNumberOfMessages($numberOfMessages) + { + $this->_numberOfMessages = $numberOfMessages; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Queue/Models/ListMessagesResult.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Queue/Models/ListMessagesResult.php new file mode 100644 index 0000000..1b931e6 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Queue/Models/ListMessagesResult.php @@ -0,0 +1,101 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Queue\Models; +use WindowsAzure\Queue\Models\WindowsAzureQueueMessage; +use WindowsAzure\Common\Internal\Utilities; + +/** + * Holds results of listMessages wrapper. + * + * @category Microsoft + * @package WindowsAzure\Queue\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class ListMessagesResult +{ + /** + * Holds all message entries. + * + * @var array. + */ + private $_queueMessages; + + /** + * Creates ListMessagesResult object from parsed XML response. + * + * @param array $parsedResponse XML response parsed into array. + * + * @return WindowsAzure\Queue\Models\ListMessagesResult. + */ + public static function create($parsedResponse) + { + $result = new ListMessagesResult(); + $queueMessages = array(); + + if (!empty($parsedResponse)) { + $rawMessages = Utilities::getArray($parsedResponse['QueueMessage']); + foreach ($rawMessages as $value) { + $message = WindowsAzureQueueMessage::createFromListMessages($value); + + $queueMessages[] = $message; + } + } + $result->setQueueMessages($queueMessages); + + return $result; + } + + /** + * Gets queueMessages field. + * + * @return array + */ + public function getQueueMessages() + { + return $this->_queueMessages; + } + + /** + * Sets queueMessages field. + * + * @param integer $queueMessages value to use. + * + * @return none + */ + public function setQueueMessages($queueMessages) + { + $this->_queueMessages = array(); + + foreach ($queueMessages as $value) { + $this->_queueMessages[] = clone $value; + } + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Queue/Models/ListQueuesOptions.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Queue/Models/ListQueuesOptions.php new file mode 100644 index 0000000..ac2673a --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Queue/Models/ListQueuesOptions.php @@ -0,0 +1,140 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Queue\Models; +use WindowsAzure\Queue\Models\QueueServiceOptions; +use \WindowsAzure\Common\Internal\Validate; + +/** + * Options for listQueues API. + * + * @category Microsoft + * @package WindowsAzure\Queue\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class ListQueuesOptions extends QueueServiceOptions +{ + private $_prefix; + private $_marker; + private $_maxResults; + private $_includeMetadata; + + /** + * Gets prefix. + * + * @return string. + */ + public function getPrefix() + { + return $this->_prefix; + } + + /** + * Sets prefix. + * + * @param string $prefix value. + * + * @return none. + */ + public function setPrefix($prefix) + { + Validate::isString($prefix, 'prefix'); + $this->_prefix = $prefix; + } + + /** + * Gets marker. + * + * @return string. + */ + public function getMarker() + { + return $this->_marker; + } + + /** + * Sets marker. + * + * @param string $marker value. + * + * @return none. + */ + public function setMarker($marker) + { + Validate::isString($marker, 'marker'); + $this->_marker = $marker; + } + + /** + * Gets max results. + * + * @return string. + */ + public function getMaxResults() + { + return $this->_maxResults; + } + + /** + * Sets max results. + * + * @param string $maxResults value. + * + * @return none. + */ + public function setMaxResults($maxResults) + { + Validate::isString($maxResults, 'maxResults'); + $this->_maxResults = $maxResults; + } + + /** + * Indicates if metadata is included or not. + * + * @return boolean. + */ + public function getIncludeMetadata() + { + return $this->_includeMetadata; + } + + /** + * Sets the include metadata flag. + * + * @param bool $includeMetadata value. + * + * @return none. + */ + public function setIncludeMetadata($includeMetadata) + { + Validate::isBoolean($includeMetadata); + $this->_includeMetadata = $includeMetadata; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Queue/Models/ListQueuesResult.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Queue/Models/ListQueuesResult.php new file mode 100644 index 0000000..7e5e4e9 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Queue/Models/ListQueuesResult.php @@ -0,0 +1,228 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Queue\Models; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Queue\Models\Queue; +use WindowsAzure\Common\Internal\Utilities; + +/** + * Container to hold list queue response object. + * + * @category Microsoft + * @package WindowsAzure\Queue\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class ListQueuesResult +{ + private $_queues; + private $_prefix; + private $_marker; + private $_nextMarker; + private $_maxResults; + private $_accountName; + + /** + * Creates ListQueuesResult object from parsed XML response. + * + * @param array $parsedResponse XML response parsed into array. + * + * @return WindowsAzure\Queue\Models\ListQueuesResult. + */ + public static function create($parsedResponse) + { + $result = new ListQueuesResult(); + $result->_accountName = Utilities::tryGetKeysChainValue( + $parsedResponse, + Resources::XTAG_ATTRIBUTES, + Resources::XTAG_ACCOUNT_NAME + ); + $result->_prefix = Utilities::tryGetValue( + $parsedResponse, Resources::QP_PREFIX + ); + $result->_marker = Utilities::tryGetValue( + $parsedResponse, Resources::QP_MARKER + ); + $result->_nextMarker = Utilities::tryGetValue( + $parsedResponse, Resources::QP_NEXT_MARKER + ); + $result->_maxResults = Utilities::tryGetValue( + $parsedResponse, Resources::QP_MAX_RESULTS + ); + $result->_queues = array(); + $rawQueues = array(); + + if ( !empty($parsedResponse['Queues']) ) { + $rawQueues = Utilities::getArray($parsedResponse['Queues']['Queue']); + } + + foreach ($rawQueues as $value) { + $queue = new Queue($value['Name'], $value['Url']); + $metadata = Utilities::tryGetValue($value, Resources::QP_METADATA); + $queue->setMetadata(is_null($metadata) ? array() : $metadata); + $result->_queues[] = $queue; + } + + return $result; + } + + /** + * Gets queues. + * + * @return array. + */ + public function getQueues() + { + return $this->_queues; + } + + /** + * Sets queues. + * + * @param array $queues list of queues + * + * @return none. + */ + public function setQueues($queues) + { + $this->_queues = array(); + foreach ($queues as $queue) { + $this->_queues[] = clone $queue; + } + } + + /** + * Gets prefix. + * + * @return string. + */ + public function getPrefix() + { + return $this->_prefix; + } + + /** + * Sets prefix. + * + * @param string $prefix value. + * + * @return none. + */ + public function setPrefix($prefix) + { + $this->_prefix = $prefix; + } + + /** + * Gets marker. + * + * @return string. + */ + public function getMarker() + { + return $this->_marker; + } + + /** + * Sets marker. + * + * @param string $marker value. + * + * @return none. + */ + public function setMarker($marker) + { + $this->_marker = $marker; + } + + /** + * Gets max results. + * + * @return string. + */ + public function getMaxResults() + { + return $this->_maxResults; + } + + /** + * Sets max results. + * + * @param string $maxResults value. + * + * @return none. + */ + public function setMaxResults($maxResults) + { + $this->_maxResults = $maxResults; + } + + /** + * Gets next marker. + * + * @return string. + */ + public function getNextMarker() + { + return $this->_nextMarker; + } + + /** + * Sets next marker. + * + * @param string $nextMarker value. + * + * @return none. + */ + public function setNextMarker($nextMarker) + { + $this->_nextMarker = $nextMarker; + } + + /** + * Gets account name. + * + * @return string + */ + public function getAccountName() + { + return $this->_accountName; + } + + /** + * Sets account name. + * + * @param string $accountName value. + * + * @return none + */ + public function setAccountName($accountName) + { + $this->_accountName = $accountName; + } +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Queue/Models/PeekMessagesOptions.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Queue/Models/PeekMessagesOptions.php new file mode 100644 index 0000000..040f4a4 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Queue/Models/PeekMessagesOptions.php @@ -0,0 +1,72 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Queue\Models; + +/** + * Short description + * + * @category Microsoft + * @package WindowsAzure\Queue\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class PeekMessagesOptions extends QueueServiceOptions +{ + /** + * A nonzero integer value that specifies the number of messages to peek from + * the queue, up to a maximum of 32. By default, a single message is peeked + * from the queue with this operation. + * + * @var integer + */ + private $_numberOfMessages; + + /** + * Gets numberOfMessages field. + * + * @return integer + */ + public function getNumberOfMessages() + { + return $this->_numberOfMessages; + } + + /** + * Sets numberOfMessages field. + * + * @param integer $numberOfMessages value to use. + * + * @return none + */ + public function setNumberOfMessages($numberOfMessages) + { + $this->_numberOfMessages = $numberOfMessages; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Queue/Models/PeekMessagesResult.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Queue/Models/PeekMessagesResult.php new file mode 100644 index 0000000..a70540a --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Queue/Models/PeekMessagesResult.php @@ -0,0 +1,103 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Queue\Models; +use WindowsAzure\Queue\Models\WindowsAzureQueueMessage; +use WindowsAzure\Common\Internal\Utilities; + +/** + * Holds results of listMessages wrapper. + * + * @category Microsoft + * @package WindowsAzure\Queue\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class PeekMessagesResult +{ + /** + * Holds all message entries. + * + * @var array. + */ + private $_queueMessages; + + /** + * Creates PeekMessagesResult object from parsed XML response. + * + * @param array $parsedResponse XML response parsed into array. + * + * @return WindowsAzure\Queue\Models\PeekMessagesResult. + */ + public static function create($parsedResponse) + { + $result = new PeekMessagesResult(); + $queueMessages = array(); + + if (!empty($parsedResponse)) { + $rawMessages = Utilities::getArray($parsedResponse['QueueMessage']); + foreach ($rawMessages as $value) { + $message = WindowsAzureQueueMessage::createFromPeekMessages($value); + + $queueMessages[] = $message; + } + } + $result->setQueueMessages($queueMessages); + + return $result; + } + + /** + * Gets queueMessages field. + * + * @return integer + */ + public function getQueueMessages() + { + $clonedMessages = array(); + + foreach ($this->_queueMessages as $value) { + $clonedMessages[] = clone $value; + } + + return $clonedMessages; + } + + /** + * Sets queueMessages field. + * + * @param integer $queueMessages value to use. + * + * @return none + */ + public function setQueueMessages($queueMessages) + { + $this->_queueMessages = $queueMessages; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Queue/Models/Queue.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Queue/Models/Queue.php new file mode 100644 index 0000000..2c1f4e4 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Queue/Models/Queue.php @@ -0,0 +1,126 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Queue\Models; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Utilities; + +/** + * WindowsAzure queue object. + * + * @category Microsoft + * @package WindowsAzure\Queue\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class Queue +{ + private $_name; + private $_url; + private $_metadata; + + /** + * Constructor + * + * @param string $name queue name. + * @param string $url queue url. + * + * @return WindowsAzure\Queue\Models\Queue. + */ + function __construct($name, $url) + { + $this->_name = $name; + $this->_url = $url; + } + + /** + * Gets queue name. + * + * @return string. + */ + public function getName() + { + return $this->_name; + } + + /** + * Sets queue name. + * + * @param string $name value. + * + * @return none. + */ + public function setName($name) + { + $this->_name = $name; + } + + /** + * Gets queue url. + * + * @return string. + */ + public function getUrl() + { + return $this->_url; + } + + /** + * Sets queue url. + * + * @param string $url value. + * + * @return none. + */ + public function setUrl($url) + { + $this->_url = $url; + } + + /** + * Gets queue metadata. + * + * @return array. + */ + public function getMetadata() + { + return $this->_metadata; + } + + /** + * Sets queue metadata. + * + * @param string $metadata value. + * + * @return none. + */ + public function setMetadata($metadata) + { + $this->_metadata = $metadata; + } +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Queue/Models/QueueMessage.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Queue/Models/QueueMessage.php new file mode 100644 index 0000000..8a4ba49 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Queue/Models/QueueMessage.php @@ -0,0 +1,83 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Queue\Models; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Serialization\XmlSerializer; + +/** + * Wrappers queue message text. + * + * @category Microsoft + * @package WindowsAzure\Queue\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class QueueMessage +{ + private $_messageText; + public static $xmlRootName = 'QueueMessage'; + + /** + * Gets message text field. + * + * @return string. + */ + public function getMessageText() + { + return $this->_messageText; + } + + /** + * Sets message text field. + * + * @param string $messageText message contents. + * + * @return string. + */ + public function setMessageText($messageText) + { + $this->_messageText = $messageText; + } + + /** + * Converts this current object to XML representation. + * + * @param XmlSerializer $xmlSerializer The XML serializer. + * + * @return string. + */ + public function toXml($xmlSerializer) + { + $array = array('MessageText' => $this->_messageText); + $properties = array(XmlSerializer::ROOT_NAME => self::$xmlRootName); + + return $xmlSerializer->serialize($array, $properties); + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Queue/Models/QueueServiceOptions.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Queue/Models/QueueServiceOptions.php new file mode 100644 index 0000000..57f7453 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Queue/Models/QueueServiceOptions.php @@ -0,0 +1,65 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Queue\Models; + +/** + * Queue service options. + * + * @category Microsoft + * @package WindowsAzure\Queue\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class QueueServiceOptions +{ + private $_timeout; + + /** + * Gets timeout. + * + * @return string. + */ + public function getTimeout() + { + return $this->_timeout; + } + + /** + * Sets timeout. + * + * @param string $timeout value. + * + * @return none. + */ + public function setTimeout($timeout) + { + $this->_timeout = $timeout; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Queue/Models/UpdateMessageResult.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Queue/Models/UpdateMessageResult.php new file mode 100644 index 0000000..a58bc7a --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Queue/Models/UpdateMessageResult.php @@ -0,0 +1,106 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Queue\Models; +use WindowsAzure\Common\Internal\Validate; + +/** + * Holds results of updateMessage wrapper. + * + * @category Microsoft + * @package WindowsAzure\Queue\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class UpdateMessageResult +{ + /** + * The value of PopReceipt is opaque to the client and its only purpose is to + * ensure that a message may be deleted with the delete message operation. + * + * @var string + */ + private $_popReceipt; + + /** + * A UTC date/time value that represents when the message will be visible on the + * queue. + * + * @var \DateTime + */ + private $_timeNextVisible; + + /** + * Gets timeNextVisible field. + * + * @return \DateTime. + */ + public function getTimeNextVisible() + { + return $this->_timeNextVisible; + } + + /** + * Sets timeNextVisible field. + * + * @param \DateTime $timeNextVisible A UTC date/time value that represents when + * the message will be visible on the queue. + * + * @return none. + */ + public function setTimeNextVisible($timeNextVisible) + { + Validate::isDate($timeNextVisible); + + $this->_timeNextVisible = $timeNextVisible; + } + + /** + * Gets popReceipt field. + * + * @return string. + */ + public function getPopReceipt() + { + return $this->_popReceipt; + } + + /** + * Sets popReceipt field. + * + * @param string $popReceipt The pop receipt of the queue message. + * + * @return none. + */ + public function setPopReceipt($popReceipt) + { + Validate::isString($popReceipt, 'popReceipt'); + $this->_popReceipt = $popReceipt; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Queue/Models/WindowsAzureQueueMessage.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Queue/Models/WindowsAzureQueueMessage.php new file mode 100644 index 0000000..0b8b748 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Queue/Models/WindowsAzureQueueMessage.php @@ -0,0 +1,297 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Queue\Models; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Utilities; + +/** + * Holds data for single WindowsAzure queue message. + * + * @category Microsoft + * @package WindowsAzure\Queue\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class WindowsAzureQueueMessage +{ + /** + * GUID value that identifies the message in the queue + * + * @var string + */ + private $_messageId; + + /** + * insertion date of the message. + * + * @var \DateTime + */ + private $_insertionDate; + + /** + * expiration date of the message. + * + * @var \DateTime + */ + private $_expirationDate; + + /** + * The value of PopReceipt is opaque to the client and its only purpose is to + * ensure that a message may be deleted with the delete message operation. + * + * @var string + */ + private $_popReceipt; + + /** + * next visibility time of the message. + * + * @var \DateTime + */ + private $_timeNextVisible; + + /** + * Dequeues count for this message. Note that this element is returned in the + * response body only if the queue was created with version 2009-09-19 of + * the Queue service. + * + * @var integer + */ + private $_dequeueCount; + + /** + * message contents. + * + * @var string + */ + private $_messageText; + + /** + * Creates WindowsAzureQueueMessage object from parsed XML response of + * ListMessages. + * + * @param array $parsedResponse XML response parsed into array. + * + * @return WindowsAzure\Queue\Models\WindowsAzureQueueMessage. + */ + public static function createFromListMessages($parsedResponse) + { + $timeNextVisible = $parsedResponse['TimeNextVisible']; + + $msg = self::createFromPeekMessages($parsedResponse); + $date = Utilities::rfc1123ToDateTime($timeNextVisible); + $msg->setTimeNextVisible($date); + $msg->setPopReceipt($parsedResponse['PopReceipt']); + + return $msg; + } + + /** + * Creates WindowsAzureQueueMessage object from parsed XML response of + * PeekMessages. + * + * @param array $parsedResponse XML response parsed into array. + * + * @return WindowsAzure\Queue\Models\WindowsAzureQueueMessage. + */ + public static function createFromPeekMessages($parsedResponse) + { + $msg = new WindowsAzureQueueMessage(); + $expirationDate = $parsedResponse['ExpirationTime']; + $insertionDate = $parsedResponse['InsertionTime']; + + $msg->setDequeueCount(intval($parsedResponse['DequeueCount'])); + + $date = Utilities::rfc1123ToDateTime($expirationDate); + $msg->setExpirationDate($date); + + $date = Utilities::rfc1123ToDateTime($insertionDate); + $msg->setInsertionDate($date); + + $msg->setMessageId($parsedResponse['MessageId']); + $msg->setMessageText($parsedResponse['MessageText']); + + return $msg; + } + + /** + * Gets message text field. + * + * @return string. + */ + public function getMessageText() + { + return $this->_messageText; + } + + /** + * Sets message text field. + * + * @param string $messageText message contents. + * + * @return none. + */ + public function setMessageText($messageText) + { + $this->_messageText = $messageText; + } + + /** + * Gets messageId field. + * + * @return integer. + */ + public function getMessageId() + { + return $this->_messageId; + } + + /** + * Sets messageId field. + * + * @param string $messageId message contents. + * + * @return none. + */ + public function setMessageId($messageId) + { + $this->_messageId = $messageId; + } + + /** + * Gets insertionDate field. + * + * @return \DateTime. + */ + public function getInsertionDate() + { + return $this->_insertionDate; + } + + /** + * Sets insertionDate field. + * + * @param \DateTime $insertionDate message contents. + * + * @return none. + */ + public function setInsertionDate($insertionDate) + { + $this->_insertionDate = $insertionDate; + } + + /** + * Gets expirationDate field. + * + * @return \DateTime. + */ + public function getExpirationDate() + { + return $this->_expirationDate; + } + + /** + * Sets expirationDate field. + * + * @param \DateTime $expirationDate the expiration date of the message. + * + * @return none. + */ + public function setExpirationDate($expirationDate) + { + $this->_expirationDate = $expirationDate; + } + + /** + * Gets timeNextVisible field. + * + * @return \DateTime. + */ + public function getTimeNextVisible() + { + return $this->_timeNextVisible; + } + + /** + * Sets timeNextVisible field. + * + * @param \DateTime $timeNextVisible next visibile time for the message. + * + * @return none. + */ + public function setTimeNextVisible($timeNextVisible) + { + $this->_timeNextVisible = $timeNextVisible; + } + + /** + * Gets popReceipt field. + * + * @return string. + */ + public function getPopReceipt() + { + return $this->_popReceipt; + } + + /** + * Sets popReceipt field. + * + * @param string $popReceipt used when deleting the message. + * + * @return none. + */ + public function setPopReceipt($popReceipt) + { + $this->_popReceipt = $popReceipt; + } + + /** + * Gets dequeueCount field. + * + * @return integer. + */ + public function getDequeueCount() + { + return $this->_dequeueCount; + } + + /** + * Sets dequeueCount field. + * + * @param integer $dequeueCount number of dequeues for that message. + * + * @return none. + */ + public function setDequeueCount($dequeueCount) + { + $this->_dequeueCount = $dequeueCount; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Queue/QueueRestProxy.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Queue/QueueRestProxy.php new file mode 100644 index 0000000..dcf4bf5 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Queue/QueueRestProxy.php @@ -0,0 +1,778 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Queue; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Validate; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Http\IHttpClient; +use WindowsAzure\Common\Internal\Http\Url; +use WindowsAzure\Common\Internal\ServiceRestProxy; +use WindowsAzure\Common\Models\GetServicePropertiesResult; +use WindowsAzure\Common\Models\ServiceProperties; +use WindowsAzure\Queue\Internal\IQueue; +use WindowsAzure\Queue\Models\ListQueuesOptions; +use WindowsAzure\Queue\Models\ListQueuesResult; +use WindowsAzure\Queue\Models\CreateQueueOptions; +use WindowsAzure\Queue\Models\QueueServiceOptions; +use WindowsAzure\Queue\Models\GetQueueMetadataResult; +use WindowsAzure\Queue\Models\CreateMessageOptions; +use WindowsAzure\Queue\Models\QueueMessage; +use WindowsAzure\Queue\Models\ListMessagesOptions; +use WindowsAzure\Queue\Models\ListMessagesResult; +use WindowsAzure\Queue\Models\PeekMessagesOptions; +use WindowsAzure\Queue\Models\PeekMessagesResult; +use WindowsAzure\Queue\Models\UpdateMessageResult; + +/** + * This class constructs HTTP requests and receive HTTP responses for queue + * service layer. + * + * @category Microsoft + * @package WindowsAzure\Queue + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class QueueRestProxy extends ServiceRestProxy implements IQueue +{ + /** + * Lists all queues in the storage account. + * + * @param ListQueuesOptions $options The optional list queue options. + * + * @return WindowsAzure\Queue\Models\ListQueuesResult + */ + public function listQueues($options = null) + { + $method = Resources::HTTP_GET; + $headers = array(); + $postParams = array(); + $queryParams = array(); + $path = Resources::EMPTY_STRING; + $statusCode = Resources::STATUS_OK; + + if (is_null($options)) { + $options = new ListQueuesOptions(); + } + + $timeout = $options->getTimeout(); + $maxResults = $options->getMaxResults(); + $include = $options->getIncludeMetadata(); + $include = $include ? 'metadata' : null; + $prefix = $options->getPrefix(); + $marker = $options->getMarker(); + + $this->addOptionalQueryParam($queryParams, Resources::QP_TIMEOUT, $timeout); + $this->addOptionalQueryParam($queryParams, Resources::QP_COMP, 'list'); + $this->addOptionalQueryParam($queryParams, Resources::QP_PREFIX, $prefix); + $this->addOptionalQueryParam($queryParams, Resources::QP_MARKER, $marker); + $this->addOptionalQueryParam($queryParams, Resources::QP_INCLUDE, $include); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_MAX_RESULTS, + $maxResults + ); + + $response = $this->send( + $method, + $headers, + $queryParams, + $postParams, + $path, + $statusCode + ); + $parsed = $this->dataSerializer->unserialize($response->getBody()); + + return ListQueuesResult::create($parsed); + } + + /** + * Clears all messages from the queue. + * + * If a queue contains a large number of messages, Clear Messages may time out + * before all messages have been deleted. In this case the Queue service will + * return status code 500 (Internal Server Error), with the additional error + * code OperationTimedOut. If the operation times out, the client should + * continue to retry Clear Messages until it succeeds, to ensure that all + * messages have been deleted. + * + * @param string $queueName The name of the queue. + * @param QueueServiceOptions $options The optional parameters. + * + * @return none + */ + public function clearMessages($queueName, $options = null) + { + Validate::isString($queueName, 'queueName'); + Validate::notNullOrEmpty($queueName, 'queueName'); + + $method = Resources::HTTP_DELETE; + $headers = array(); + $postParams = array(); + $queryParams = array(); + $path = $queueName . '/messages'; + $body = Resources::EMPTY_STRING; + $statusCode = Resources::STATUS_NO_CONTENT; + + if (is_null($options)) { + $options = new QueueServiceOptions(); + } + + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + + $this->send( + $method, + $headers, + $queryParams, + $postParams, + $path, + $statusCode, + $body + ); + } + + /** + * Adds a message to the queue and optionally sets a visibility timeout + * for the message. + * + * @param string $queueName The name of the queue. + * @param string $messageText The message contents. + * @param CreateMessageOptions $options The optional parameters. + * + * @return none + */ + public function createMessage($queueName, $messageText, + $options = null + ) { + Validate::isString($queueName, 'queueName'); + Validate::notNullOrEmpty($queueName, 'queueName'); + Validate::isString($messageText, 'messageText'); + + $method = Resources::HTTP_POST; + $headers = array(); + $postParams = array(); + $queryParams = array(); + $path = $queueName . '/messages'; + $body = Resources::EMPTY_STRING; + $statusCode = Resources::STATUS_CREATED; + $message = new QueueMessage(); + $message->setMessageText($messageText); + $body = $message->toXml($this->dataSerializer); + + + if (is_null($options)) { + $options = new CreateMessageOptions(); + } + + $this->addOptionalHeader( + $headers, + Resources::CONTENT_TYPE, + Resources::URL_ENCODED_CONTENT_TYPE + ); + + $visibility = $options->getVisibilityTimeoutInSeconds(); + $timeToLive = $options->getTimeToLiveInSeconds(); + $timeout = $options->getTimeout(); + + $this->addOptionalQueryParam($queryParams, Resources::QP_TIMEOUT, $timeout); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_VISIBILITY_TIMEOUT, + $visibility + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_MESSAGE_TTL, + $timeToLive + ); + + $this->send( + $method, + $headers, + $queryParams, + $postParams, + $path, + $statusCode, + $body + ); + } + + /** + * Creates a new queue under the storage account. + * + * @param string $queueName The queue name. + * @param QueueCreateOptions $options The Optional parameters. + * + * @return none + */ + public function createQueue($queueName, $options = null) + { + Validate::isString($queueName, 'queueName'); + Validate::notNullOrEmpty($queueName, 'queueName'); + + $method = Resources::HTTP_PUT; + $headers = array(); + $postParams = array(); + $queryParams = array(); + $path = $queueName; + $statusCode = array( + Resources::STATUS_CREATED, + Resources::STATUS_NO_CONTENT + ); + + if (is_null($options)) { + $options = new CreateQueueOptions(); + } + + $metadata = $options->getMetadata(); + $timeout = $options->getTimeout(); + $headers = $this->generateMetadataHeaders($metadata); + + $this->addOptionalQueryParam($queryParams, Resources::QP_TIMEOUT, $timeout); + + $this->send( + $method, + $headers, + $queryParams, + $postParams, + $path, + $statusCode + ); + } + + /** + * Deletes a specified message from the queue. + * + * @param string $queueName The name of the queue. + * @param string $messageId The id of the message. + * @param string $popReceipt The valid pop receipt value returned + * from an earlier call to the Get Messages or Update Message operation. + * @param QueueServiceOptions $options The optional parameters. + * + * @return none + */ + public function deleteMessage($queueName, $messageId, $popReceipt, + $options = null + ) { + Validate::isString($queueName, 'queueName'); + Validate::notNullOrEmpty($queueName, 'queueName'); + Validate::isString($messageId, 'messageId'); + Validate::notNullOrEmpty($messageId, 'messageId'); + Validate::isString($popReceipt, 'popReceipt'); + Validate::notNullOrEmpty($popReceipt, 'popReceipt'); + + $method = Resources::HTTP_DELETE; + $headers = array(); + $postParams = array(); + $queryParams = array(); + $path = $queueName . '/messages/' . $messageId; + $body = Resources::EMPTY_STRING; + $statusCode = Resources::STATUS_NO_CONTENT; + + if (is_null($options)) { + $options = new QueueServiceOptions(); + } + + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_POPRECEIPT, + $popReceipt + ); + + $this->send( + $method, + $headers, + $queryParams, + $postParams, + $path, + $statusCode, + $body + ); + } + + /** + * Deletes a queue. + * + * @param string $queueName The queue name. + * @param QueueServiceOptions $options The optional parameters. + * + * @return none + */ + public function deleteQueue($queueName, $options = null) + { + Validate::isString($queueName, 'queueName'); + Validate::notNullOrEmpty($queueName, 'queueName'); + + $method = Resources::HTTP_DELETE; + $headers = array(); + $postParams = array(); + $queryParams = array(); + $path = $queueName; + $statusCode = Resources::STATUS_NO_CONTENT; + + if (is_null($options)) { + $options = new QueueServiceOptions(); + } + + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + + $this->send( + $method, + $headers, + $queryParams, + $postParams, + $path, + $statusCode + ); + } + + /** + * Returns queue properties, including user-defined metadata. + * + * @param string $queueName The queue name. + * @param QueueServiceOptions $options The optional parameters. + * + * @return WindowsAzure\Common\Models\GetQueueMetadataResult + */ + public function getQueueMetadata($queueName, $options = null) + { + Validate::isString($queueName, 'queueName'); + Validate::notNullOrEmpty($queueName, 'queueName'); + + $method = Resources::HTTP_GET; + $headers = array(); + $postParams = array(); + $queryParams = array(); + $path = $queueName; + $body = Resources::EMPTY_STRING; + $statusCode = Resources::STATUS_OK; + + if (is_null($options)) { + $options = new QueueServiceOptions(); + } + + $this->addOptionalQueryParam($queryParams, Resources::QP_COMP, 'metadata'); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + + $response = $this->send( + $method, + $headers, + $queryParams, + $postParams, + $path, + $statusCode, + $body + ); + + $metadata = $this->getMetadataArray($response->getHeader()); + $maxCount = intval( + $response->getHeader(Resources::X_MS_APPROXIMATE_MESSAGES_COUNT) + ); + + return new GetQueueMetadataResult($maxCount, $metadata); + } + + /** + * Gets the properties of the Queue service. + * + * @param QueueServiceOptions $options The optional parameters. + * + * @return WindowsAzure\Common\Models\GetServicePropertiesResult + */ + public function getServiceProperties($options = null) + { + $method = Resources::HTTP_GET; + $headers = array(); + $postParams = array(); + $queryParams = array(); + $path = Resources::EMPTY_STRING; + $statusCode = Resources::STATUS_OK; + + if (is_null($options)) { + $options = new QueueServiceOptions(); + } + + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_REST_TYPE, + 'service' + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_COMP, + 'properties' + ); + + $response = $this->send( + $method, + $headers, + $queryParams, + $postParams, + $path, + $statusCode + ); + $parsed = $this->dataSerializer->unserialize($response->getBody()); + + return GetServicePropertiesResult::create($parsed); + } + + /** + * Lists all messages in the queue. + * + * @param string $queueName The queue name. + * @param ListMessagesOptions $options The optional parameters. + * + * @return WindowsAzure\Common\Models\ListMessagesResult + */ + public function listMessages($queueName, $options = null) + { + Validate::isString($queueName, 'queueName'); + Validate::notNullOrEmpty($queueName, 'queueName'); + + $method = Resources::HTTP_GET; + $headers = array(); + $queryParams = array(); + $postParams = array(); + $path = $queueName . '/messages'; + $statusCode = Resources::STATUS_OK; + + if (is_null($options)) { + $options = new ListMessagesOptions(); + } + + $messagesCount = $options->getNumberOfMessages(); + $visibility = $options->getVisibilityTimeoutInSeconds(); + $timeout = $options->getTimeout(); + + $this->addOptionalQueryParam($queryParams, Resources::QP_TIMEOUT, $timeout); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_NUM_OF_MESSAGES, + $messagesCount + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_VISIBILITY_TIMEOUT, + $visibility + ); + + $response = $this->send( + $method, + $headers, + $queryParams, + $postParams, + $path, + $statusCode + ); + + $parsed = $this->dataSerializer->unserialize($response->getBody()); + + return ListMessagesResult::create($parsed); + } + + /** + * Retrieves a message from the front of the queue, without changing + * the message visibility. + * + * @param string $queueName The queue name. + * @param PeekMessagesOptions $options The optional parameters. + * + * @return WindowsAzure\Common\Models\PeekMessagesResult + */ + public function peekMessages($queueName, $options = null) + { + Validate::isString($queueName, 'queueName'); + Validate::notNullOrEmpty($queueName, 'queueName'); + + $method = Resources::HTTP_GET; + $headers = array(); + $queryParams = array(); + $postParams = array(); + $path = $queueName . '/messages'; + $statusCode = Resources::STATUS_OK; + + if (is_null($options)) { + $options = new PeekMessagesOptions(); + } + + $messagesCount = $options->getNumberOfMessages(); + $timeout = $options->getTimeout(); + + $this->addOptionalQueryParam($queryParams, Resources::QP_PEEK_ONLY, 'true'); + $this->addOptionalQueryParam($queryParams, Resources::QP_TIMEOUT, $timeout); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_NUM_OF_MESSAGES, + $messagesCount + ); + + $response = $this->send( + $method, + $headers, + $queryParams, + $postParams, + $path, + $statusCode + ); + $parsed = $this->dataSerializer->unserialize($response->getBody()); + + return PeekMessagesResult::create($parsed); + } + + /** + * Sets user-defined metadata on the queue. To delete queue metadata, call + * this API without specifying any metadata in $metadata. + * + * @param string $queueName The queue name. + * @param array $metadata The metadata array. + * @param QueueServiceOptions $options The optional parameters. + * + * @return none + */ + public function setQueueMetadata($queueName, $metadata, $options = null) + { + Validate::isString($queueName, 'queueName'); + Validate::notNullOrEmpty($queueName, 'queueName'); + $this->validateMetadata($metadata); + + $method = Resources::HTTP_PUT; + $headers = array(); + $queryParams = array(); + $postParams = array(); + $path = $queueName; + $statusCode = Resources::STATUS_NO_CONTENT; + $body = Resources::EMPTY_STRING; + + if (is_null($options)) { + $options = new QueueServiceOptions(); + } + + $this->addOptionalQueryParam($queryParams, Resources::QP_COMP, 'metadata'); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + + $metadataHeaders = $this->generateMetadataHeaders($metadata); + $headers = $metadataHeaders; + + $this->send( + $method, + $headers, + $queryParams, + $postParams, + $path, + $statusCode, + $body + ); + } + + /** + * Sets the properties of the Queue service. + * + * It's recommended to use getServiceProperties, alter the returned object and + * then use setServiceProperties with this altered object. + * + * @param array $serviceProperties The new service properties. + * @param QueueServiceOptions $options The optional parameters. + * + * @return none + */ + public function setServiceProperties($serviceProperties, $options = null) + { + Validate::isTrue( + $serviceProperties instanceof ServiceProperties, + Resources::INVALID_SVC_PROP_MSG + ); + + $method = Resources::HTTP_PUT; + $headers = array(); + $postParams = array(); + $queryParams = array(); + $statusCode = Resources::STATUS_ACCEPTED; + $path = Resources::EMPTY_STRING; + $body = $serviceProperties->toXml($this->dataSerializer); + + if (is_null($options)) { + $options = new QueueServiceOptions(); + } + + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_REST_TYPE, + 'service' + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_COMP, + 'properties' + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + $this->addOptionalHeader( + $headers, + Resources::CONTENT_TYPE, + Resources::URL_ENCODED_CONTENT_TYPE + ); + + $this->send( + $method, + $headers, + $queryParams, + $postParams, + $path, + $statusCode, + $body + ); + } + + /** + * Updates the visibility timeout of a message and/or the message contents. + * + * @param string $queueName The queue name. + * @param string $messageId The id of the message. + * @param string $popReceipt The valid pop receipt + * value returned from an earlier call to the Get Messages or Update Message + * operation. + * @param string $messageText The message contents. + * @param int $visibilityTimeoutInSeconds Specifies the new + * visibility timeout value, in seconds, relative to server time. + * The new value must be larger than or equal to 0, and cannot be larger + * than 7 days. The visibility timeout of a message cannot be set to a value + * later than the expiry time. A message can be updated until it has been + * deleted or has expired. + * @param QueueServiceOptions $options The optional + * parameters. + * + * @return WindowsAzure\Common\Models\UpdateMessageResult + */ + public function updateMessage($queueName, $messageId, $popReceipt, $messageText, + $visibilityTimeoutInSeconds, $options = null + ) { + Validate::isString($queueName, 'queueName'); + Validate::notNullOrEmpty($queueName, 'queueName'); + Validate::isString($messageId, 'messageId'); + Validate::notNullOrEmpty($messageId, 'messageId'); + Validate::isString($popReceipt, 'popReceipt'); + Validate::notNullOrEmpty($popReceipt, 'popReceipt'); + Validate::isString($messageText, 'messageText'); + Validate::isInteger( + $visibilityTimeoutInSeconds, + 'visibilityTimeoutInSeconds' + ); + Validate::notNull( + $visibilityTimeoutInSeconds, + 'visibilityTimeoutInSeconds' + ); + + $method = Resources::HTTP_PUT; + $headers = array(); + $postParams = array(); + $queryParams = array(); + $path = $queueName . '/messages' . '/' . $messageId; + $body = Resources::EMPTY_STRING; + $statusCode = Resources::STATUS_NO_CONTENT; + + if (is_null($options)) { + $options = new QueueServiceOptions(); + } + + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_VISIBILITY_TIMEOUT, + $visibilityTimeoutInSeconds + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_POPRECEIPT, + $popReceipt + ); + + if (!empty($messageText)) { + $this->addOptionalHeader( + $headers, + Resources::CONTENT_TYPE, + Resources::URL_ENCODED_CONTENT_TYPE + ); + + $message = new QueueMessage(); + $message->setMessageText($messageText); + $body = $message->toXml($this->dataSerializer); + } + + $response = $this->send( + $method, + $headers, + $queryParams, + $postParams, + $path, + $statusCode, + $body + ); + $popReceipt = $response->getHeader(Resources::X_MS_POPRECEIPT); + $timeNextVisible = $response->getHeader(Resources::X_MS_TIME_NEXT_VISIBLE); + + $date = Utilities::rfc1123ToDateTime($timeNextVisible); + $result = new UpdateMessageResult(); + $result->setPopReceipt($popReceipt); + $result->setTimeNextVisible($date); + + return $result; + } +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Internal/Action.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Internal/Action.php new file mode 100644 index 0000000..cca4d25 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Internal/Action.php @@ -0,0 +1,79 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ +namespace WindowsAzure\ServiceBus\Internal; +use WindowsAzure\Common\Internal\Resources; + +/** + * The base class for rule action. + * + * @category Microsoft + * @package WindowsAzure\ServiceBus\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +class Action +{ + /** + * The attributes of the filter. + * + * @var array + */ + protected $attributes; + + /** + * Creates an Action instance with default parameter. + */ + public function __construct() + { + $this->attributes = array(); + $this->attributes['xmlns:xsi'] = Resources::XSI_XML_NAMESPACE; + } + + /** + * Gets the attributes. + * + * @return array + */ + public function getAttributes() + { + return $this->attributes; + } + + /** + * Sets an attribute. + * + * @param string $key The key of the attribute. + * @param string $value The value of the attribute. + * + * @return none + */ + protected function setAttribute($key, $value) + { + $this->attributes[$key] = $value; + } +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Internal/ActiveToken.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Internal/ActiveToken.php new file mode 100644 index 0000000..4afcc09 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Internal/ActiveToken.php @@ -0,0 +1,112 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceBus\Internal; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\ServiceBus\Internal\WrapAccessTokenResult; +use WindowsAzure\Common\Internal\Utilities; + +/** + * An active WRAP access Token. + * + * @category Microsoft + * @package WindowsAzure\ServiceBus\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ +class ActiveToken +{ + /** + * The WRAP access token result. + * + * @var WrapAccessTokenResult + */ + private $_wrapAccessTokenResult; + + /** + * When the WRAP access token expires. + * + * @var \DateTime + */ + private $_expirationDateTime; + + /** + * Creates an ActiveToken with specified WRAP + * access token result. + * + * @param array $wrapAccessTokenResult A WRAP access token result. + */ + public function __construct($wrapAccessTokenResult) + { + $this->_wrapAccessTokenResult = $wrapAccessTokenResult; + } + + /** + * Gets WRAP access token. + * + * @return WrapAccessTokenResult + */ + public function getWrapAccessTokenResult() + { + return $this->_wrapAccessTokenResult; + } + + /** + * Sets WRAP access token. + * + * @param string $wrapAccessTokenResult The WRAP access token result. + * + * @return none + */ + public function setWrapAccessTokenResult($wrapAccessTokenResult) + { + $this->_wrapAccessTokenResult = $wrapAccessTokenResult; + } + + /** + * Gets expiration time. + * + * @return \DateTime + */ + public function getExpirationDateTime() + { + return $this->_expirationDateTime; + } + + /** + * Sets expiration time. + * + * @param \DateTime $expirationDateTime value. + * + * @return none + */ + public function setExpirationDateTime($expirationDateTime) + { + $this->_expirationDateTime = $expirationDateTime; + } +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Internal/Filter.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Internal/Filter.php new file mode 100644 index 0000000..07acd8f --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Internal/Filter.php @@ -0,0 +1,106 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ +namespace WindowsAzure\ServiceBus\Internal; +use WindowsAzure\Common\Internal\Resources; + +/** + * The base class for rule filter. + * + * @category Microsoft + * @package WindowsAzure\ServiceBus\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +class Filter +{ + /** + * The attributes of the filter. + * + * @var array + */ + protected $attributes; + + /** + * Creates a filter with default parameters. + */ + public function __construct() + { + $this->attributes = array(); + $this->attributes['xmlns:xsi'] = Resources::XSI_XML_NAMESPACE; + } + + /** + * Creates a Filter with specifed XML based string. + * + * @param string $filterXmlString An XML based filter string. + * + * @return Filter + */ + public static function create($filterXmlString) + { + $filterXml = simplexml_load_string($filterXmlString); + $attributes = (array)$filterXml->attributes(); + + if (array_key_exists('i:type', $attributes)) { + $type = (string)$attributes['i:type']; + if ($type === 'TrueFilter') { + return new TrueFilter(); + } + + if ($type === 'FalseFilter') { + return new FalseFilter(); + } + + return new Filter(); + } + } + + /** + * Gets the attributes. + * + * @return array + */ + public function getAttributes() + { + return $this->attributes; + } + + /** + * Sets an attribute. + * + * @param string $key The key of the attribute. + * @param string $value The value of the attribute. + * + * @return none + */ + protected function setAttribute($key, $value) + { + $this->attributes[$key] = $value; + } + +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Internal/IServiceBus.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Internal/IServiceBus.php new file mode 100644 index 0000000..258eebd --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Internal/IServiceBus.php @@ -0,0 +1,318 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceBus\Internal; +use WindowsAzure\Common\Internal\FilterableService; + +/** + * This class constructs HTTP requests and receive HTTP responses for Service Bus. + * + * @category Microsoft + * @package WindowsAzure\ServiceBus\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ +interface IServiceBus extends FilterableService +{ + /** + * Sends a brokered message. + * + * @param type $path The path to send message. + * @param type $brokeredMessage The brokered message. + * + * @throws Exception + * @return none + */ + public function sendMessage($path, $brokeredMessage); + + /** + * Sends a queue message. + * + * @param string $queueName The name of the queue to send + * message. + * @param \BrokeredMessage $brokeredMessage The brokered message. + * + * @throws Exception + * @return none + */ + public function sendQueueMessage($queueName, $brokeredMessage); + + /** + * Receives a queue message. + * + * @param string $queueName The name of the + * queue. + * @param \ReceivedMessageOptions $receivedMessageOptions The options to + * receive the message. + * + * @throws Exception + * @return none + */ + public function receiveQueueMessage($queueName, $receivedMessageOptions); + + /** + * Receives a message. + * + * @param string $path The path of the + * message. + * @param \ReceivedMessageOptions $receiveMessageOptions The options to + * receive the message. + * + * @throws Exception + * @return none + */ + public function receiveMessage($path, $receiveMessageOptions); + + /** + * Sends a brokered message to a specified topic. + * + * @param string $topicName The name of the topic. + * @param \BrokeredMessage $brokeredMessage The brokered message. + * + * @throws Exception + * @return none + */ + public function sendTopicMessage($topicName, $brokeredMessage); + + /** + * Receives a subscription message. + * + * @param string $topicName The name of the + * topic. + * @param string $subscriptionName The name of the + * subscription. + * @param \ReceiveMessageOptions $receiveMessageOptions The options to + * receive the subscription message. + * + * @throws Exception + * @return none + */ + public function receiveSubscriptionMessage( + $topicName, + $subscriptionName, + $receiveMessageOptions + ); + + /** + * Unlocks a brokered message. + * + * @param \BrokeredMessage $brokeredMessage The brokered message. + * + * @throws Exception + * @return none + */ + public function unlockMessage($brokeredMessage); + + /** + * Deletes a brokered message. + * + * @param \BrokeredMessage $brokeredMessage The borkered message. + * + * @throws Exception + * @return none + */ + public function deleteMessage($brokeredMessage); + + /** + * Creates a queue with specified queue info. + * + * @param \QueueInfo $queueInfo The information of the queue. + * + * @throws Exception + * @return none + */ + public function createQueue($queueInfo); + + /** + * Deletes a queue. + * + * @param string $queuePath The path of the queue. + * + * @throws Exception + * @return none + */ + public function deleteQueue($queuePath); + + /** + * Gets a queue with specified path. + * + * @param string $queuePath The path of the queue. + * + * @throws Exception + * @return none + */ + public function getQueue($queuePath); + + /** + * Lists a queue. + * + * @param \ListQueueOptions $listQueueOptions The options to list the + * queues. + * + * @throws Exception + * @return none + */ + public function listQueues($listQueueOptions); + + /** + * Creates a topic with specified topic info. + * + * @param \TopicInfo $topicInfo The information of the topic. + * + * @throws Exception + * @return none + */ + public function createTopic($topicInfo); + + /** + * Deletes a topic with specified topic path. + * + * @param string $topicPath The path of the topic. + * + * @throws Exception + * @return none + */ + public function deleteTopic($topicPath); + + /** + * Gets a topic. + * + * @param string $topicPath The path of the topic. + * + * @throws Exception + * @return none + */ + public function getTopic($topicPath); + + /** + * Lists topics. + * + * @param \ListTopicsOptions $listTopicsOptions The options to list + * the topics. + * + * @throws Exception + * @return none + */ + public function listTopics($listTopicsOptions); + + /** + * Creates a subscription with specified topic path and + * subscription info. + * + * @param string $topicPath The path of the topic. + * @param \SubscriptionInfo $subscriptionInfo The information of the + * subscription. + * + * @throws Exception + * @return none + */ + public function createSubscription($topicPath, $subscriptionInfo); + + /** + * Deletes a subscription. + * + * @param string $topicPath The path of the topic. + * @param string $subscriptionName The name of the subscription. + * + * @throws Exception + * @return none + */ + public function deleteSubscription($topicPath, $subscriptionName); + + /** + * Gets a subscription. + * + * @param string $topicPath The path of the topic. + * @param string $subscriptionName The name of the subscription. + * + * @throws Exception + * @return none + */ + public function getSubscription($topicPath, $subscriptionName); + + /** + * Lists subscriptions. + * + * @param string $topicPath The path of + * the topic. + * @param ListSubscriptionsOptions $listSubscriptionsOptions The options + * to list the subscriptions. + * + * @throws Exception + * @return none + */ + public function listSubscriptions($topicPath, $listSubscriptionsOptions); + + /** + * Creates a rule. + * + * @param string $topicPath The path of the topic. + * @param string $subscriptionName The name of the subscription. + * @param \RuleInfo $ruleInfo The info of the rule. + * + * @throws Exception + * @return none + */ + public function createRule($topicPath, $subscriptionName, $ruleInfo); + + /** + * Deletes a rule. + * + * @param string $topicPath The path of the topic. + * @param string $subscriptionName The name of the subscription. + * @param string $ruleName The name of the rule. + * + * @throws Exception + * @return none + */ + public function deleteRule($topicPath, $subscriptionName, $ruleName); + + /** + * Gets a rule. + * + * @param string $topicPath The path of the topic. + * @param string $subscriptionName The name of the subscription. + * @param string $ruleName The name of the rule. + * + * @throws Exception + * @return none + */ + public function getRule($topicPath, $subscriptionName, $ruleName); + + /** + * Lists rules. + * + * @param string $topicPath The path of the topic. + * @param string $subscriptionName The name of the subscription. + * @param \ListRulesOptions $listRulesOptions The options to list the rules. + * + * @throws Exception + * @return none + */ + public function listRules($topicPath, $subscriptionName, $listRulesOptions); + +} diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Internal/IWrap.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Internal/IWrap.php new file mode 100644 index 0000000..10b8e72 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Internal/IWrap.php @@ -0,0 +1,56 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceBus\Internal; +use WindowsAzure\Common\Internal\FilterableService; + +/** + * This class constructs HTTP requests and receive HTTP responses for queue + * service layer. + * + * @category Microsoft + * @package WindowsAzure\ServiceBus\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ +interface IWrap extends FilterableService +{ + + /** + * Gets a WRAP access token with specified parameters. + * + * @param string $uri The URI of the WRAP service. + * @param string $name The user name of the WRAP service. + * @param string $password The password of the WRAP service. + * @param string $scope The scope of the WRAP service. + * + * @return WindowsAzure\ServiceBus\Internal\WrapAccessTokenResult + */ + public function wrapAccessToken($uri, $name, $password, $scope); + +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Internal/WrapAccessTokenResult.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Internal/WrapAccessTokenResult.php new file mode 100644 index 0000000..603f5cd --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Internal/WrapAccessTokenResult.php @@ -0,0 +1,124 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceBus\Internal; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\ServiceBus\Models; +use WindowsAzure\Common\Internal\Utilities; + +/** + * Container to hold wrap accesss token response object. + * + * @category Microsoft + * @package WindowsAzure\ServiceBus\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ +class WrapAccessTokenResult +{ + /** + * @var string + */ + private $_accessToken; + + /** + * @var integer + */ + private $_expiresIn; + + /** + * Creates WrapAccesTokenResult object from parsed XML response. + * + * @param array $response The get WRAP access token response. + * + * @return WindowsAzure\ServiceBus\Internal\WrapAccessTokenResult. + */ + public static function create($response) + { + $wrapAccessTokenResult = new WrapAccessTokenResult(); + parse_str($response, $parsedResponse); + + $wrapAccessTokenResult->setAccessToken( + Utilities::tryGetValue( + $parsedResponse, Resources::WRAP_ACCESS_TOKEN + ) + ); + + $wrapAccessTokenResult->setExpiresIn( + Utilities::tryGetValue( + $parsedResponse, Resources::WRAP_ACCESS_TOKEN_EXPIRES_IN + ) + ); + + return $wrapAccessTokenResult; + } + + /** + * Gets access token. + * + * @return string. + */ + public function getAccessToken() + { + return $this->_accessToken; + } + + /** + * Sets access token. + * + * @param string $accessToken The access token. + * + * @return none. + */ + public function setAccessToken($accessToken) + { + $this->_accessToken = $accessToken; + } + + /** + * Gets expires in. + * + * @return integer. + */ + public function getExpiresIn() + { + return $this->_expiresIn; + } + + /** + * Sets expires in. + * + * @param integer $expiresIn value. + * + * @return none. + */ + public function setExpiresIn($expiresIn) + { + $this->_expiresIn = $expiresIn; + } +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Internal/WrapRestProxy.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Internal/WrapRestProxy.php new file mode 100644 index 0000000..7c5dc6f --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Internal/WrapRestProxy.php @@ -0,0 +1,115 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceBus\Internal; +use WindowsAzure\Common\Internal\Http\IHttpClient; +use WindowsAzure\Common\Internal\Http\Url; +use WindowsAzure\Common\Internal\ServiceRestProxy; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Validate; +use WindowsAzure\Common\Models\GetServicePropertiesResult; +use WindowsAzure\Common\Models\ServiceProperties; +use WindowsAzure\ServiceBus\Internal\IWrap; +use WindowsAzure\ServiceBus\Internal\WrapAccessTokenResult; + +/** + * The WRAP service layer. + * + * @category Microsoft + * @package WindowsAzure\ServiceBus\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ +class WrapRestProxy extends ServiceRestProxy implements IWrap +{ + /** + * Creates a WrapRestProxy with specified parameters. + * + * @param IHttpClient $channel The channel to send the WRAP request. + * @param string $uri The Uri of the WRAP service. + * + * @return none + */ + public function __construct($channel, $uri) + { + parent::__construct($channel, $uri, Resources::EMPTY_STRING, null); + } + + /** + * Gets a WRAP access token with specified parameters. + * + * @param string $uri The URI of the WRAP service. + * @param string $name The user name of the WRAP service. + * @param string $password The password of the WRAP service. + * @param string $scope The scope of the WRAP service. + * + * @return WindowsAzure\ServiceBus\Internal\WrapAccessTokenResult + */ + public function wrapAccessToken($uri, $name, $password, $scope) + { + $method = Resources::HTTP_POST; + $headers = array(); + $queryParams = array(); + $postParameters = array(); + $statusCode = Resources::STATUS_OK; + + $postParameters = $this->addPostParameter( + $postParameters, + Resources::WRAP_NAME, + $name + ); + + $postParameters = $this->addPostParameter( + $postParameters, + Resources::WRAP_PASSWORD, + $password + ); + + $postParameters = $this->addPostParameter( + $postParameters, + Resources::WRAP_SCOPE, + $scope + ); + + $this->setUri($uri); + + $response = $this->send( + $method, + $headers, + $queryParams, + $postParameters, + Resources::EMPTY_STRING, + $statusCode + ); + + return WrapAccessTokenResult::create($response->getBody()); + } + +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Internal/WrapTokenManager.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Internal/WrapTokenManager.php new file mode 100644 index 0000000..8d4b4db --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Internal/WrapTokenManager.php @@ -0,0 +1,234 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceBus\Internal; +use WindowsAzure\Common\Configuration; +use WindowsAzure\Common\ServicesBuilder; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Validate; +use WindowsAzure\ServiceBus\Internal\WrapRestProxy; +use WindowsAzure\ServiceBus\Internal\ActiveToken; + +/** + * Manages WRAP tokens. + * + * @category Microsoft + * @package WindowsAzure\ServiceBus\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +class WrapTokenManager +{ + /** + * The Uri of the WRAP service. + * + * @var string + */ + private $_wrapUri; + + /** + * The user name of the WRAP service. + * + * @var string + */ + private $_wrapName; + + /** + * The password of the WRAP service. + * + * @var string + */ + private $_wrapPassword; + + /** + * The proxy of the WRAP service. + * + * @var string + */ + private $_wrapRestProxy; + + /** + * The active WRAP access tokens. + * + * @var array + */ + private $_activeTokens; + + /** + * Creates a WRAP token manager with specified parameters. + * + * @param string $wrapUri The URI of the WRAP service. + * @param string $wrapName The user name of the WRAP service. + * @param string $wrapPassword The password of the WRAP service. + * @param IWrap $wrapRestProxy The WRAP service REST proxy. + */ + public function __construct($wrapUri, $wrapName, $wrapPassword, $wrapRestProxy) + { + Validate::isString($wrapUri, 'wrapUri'); + Validate::isString($wrapName, 'wrapName'); + Validate::isString($wrapPassword, 'wrapPassword'); + Validate::notNullOrEmpty($wrapRestProxy, 'wrapRestProxy'); + + $this->_wrapUri = $wrapUri; + $this->_wrapName = $wrapName; + $this->_wrapPassword = $wrapPassword; + $this->_wrapRestProxy = $wrapRestProxy; + $this->_activeTokens = array(); + + } + + /** + * Gets WRAP access token with sepcified target Uri. + * + * @param string $targetUri The target Uri of the WRAP access Token. + * + * @return string + */ + public function getAccessToken($targetUri) + { + Validate::isString($targetUri, '$targetUri'); + + $this->_sweepExpiredTokens(); + $scopeUri = $this->_createScopeUri($targetUri); + + if (array_key_exists($scopeUri, $this->_activeTokens)) { + $activeToken = $this->_activeTokens[$scopeUri]; + return $activeToken->getWrapAccessTokenResult()->getAccessToken(); + } + + $wrapAccessTokenResult = $this->_wrapRestProxy->wrapAccessToken( + $this->_wrapUri, + $this->_wrapName, + $this->_wrapPassword, + $scopeUri + ); + + $expirationDateTime = new \DateTime("now"); + $expiresIn = intval($wrapAccessTokenResult->getExpiresIn() / 2); + $expirationDateTime = $expirationDateTime->add( + new \DateInterval('PT'.$expiresIn.'S') + ); + + $acquiredActiveToken = new ActiveToken($wrapAccessTokenResult); + $acquiredActiveToken->setExpirationDateTime($expirationDateTime); + $this->_activeTokens[$scopeUri] = $acquiredActiveToken; + + return $wrapAccessTokenResult->getAccessToken(); + } + + /** + * Removes the expired WRAP access tokens. + * + * @return none + */ + private function _sweepExpiredTokens() + { + foreach ($this->_activeTokens as $scopeUri => $activeToken) { + $currentDateTime = new \DateTime("now"); + if ($activeToken->getExpirationDateTime() < $currentDateTime ) { + unset($this->_activeTokens[$scopeUri]); + } + } + } + + /** + * Creates a SCOPE URI with specified target URI. + * + * @param array $targetUri The target URI. + * + * @return string + */ + private function _createScopeUri($targetUri) + { + $targetUriComponents = parse_url($targetUri); + + $scopeUri = Resources::EMPTY_STRING; + $authority = Resources::EMPTY_STRING; + if ($this->_containsValidAuthority($targetUriComponents)) { + $authority = $this->_createAuthority($targetUriComponents); + } + + $scopeUri = 'http://' + .$authority + .$targetUriComponents[Resources::PHP_URL_HOST]; + + if (array_key_exists(Resources::PHP_URL_PATH, $targetUriComponents)) { + $scopeUri .= $targetUriComponents[Resources::PHP_URL_PATH]; + } + + return $scopeUri; + } + + /** + * Gets whether the authority related elements are valid. + * + * @param array $uriComponents The components of an URI. + * + * @return boolean + */ + private function _containsValidAuthority($uriComponents) + { + if (! array_key_exists(Resources::PHP_URL_USER, $uriComponents)) { + return false; + } + + if (empty($uriComponents[Resources::PHP_URL_USER])) { + return false; + } + + if (! array_key_exists(Resources::PHP_URL_PASS, $uriComponents)) { + return false; + } + + if (empty($uriComponents[Resources::PHP_URL_PASS])) { + return false; + } + + return true; + } + + /** + * Creates an authority string with specified Uri components. + * + * @param array $uriComponents The URI components + * + * @return string + */ + private function _createAuthority($uriComponents) + { + $authority = sprintf( + Resources::AUTHORITY_FORMAT, + $uriComponents[Resources::PHP_URL_USER], + $uriComponents[Resources::PHP_URL_PASS] + ); + + return $authority; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/BrokerProperties.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/BrokerProperties.php new file mode 100644 index 0000000..ad5f202 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/BrokerProperties.php @@ -0,0 +1,786 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ +namespace WindowsAzure\ServiceBus\Models; +use WindowsAzure\Common\Internal\Validate; +use WindowsAzure\Common\Internal\Resources; + +/** + * The properties of the broker of a brokered message. + * + * @category Microsoft + * @package WindowsAzure\ServiceBus\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +class BrokerProperties +{ + /** + * The correlation ID. + * + * @var string + */ + private $_correlationId; + + /** + * The session ID. + * + * @var string + */ + private $_sessionId; + + /** + * The delivery count. + * + * @var integer + */ + private $_deliveryCount; + + /** + * The locked until time. + * + * @var \DateTime + */ + private $_lockedUntilUtc; + + /** + * The lock token. + * + * @var string + */ + private $_lockToken; + + /** + * The message Id. + * + * @var string + */ + private $_messageId; + + /** + * The label. + * + * @var string + */ + private $_label; + + /** + * The reply to. + * + * @var string + */ + private $_replyTo; + + /** + * The sequence number. + * + * @var string + */ + private $_sequenceNumber; + + /** + * The time to live. + * + * @var float + */ + private $_timeToLive; + + /** + * The to. + * + * @var string + */ + private $_to; + + /** + * The scheduled enqueue time. + * + * @var \DateTime + */ + private $_scheduledEnqueueTimeUtc; + + /** + * The reply to session ID. + * + * @var string + */ + private $_replyToSessionId; + + /** + * The location of the message. + * + * @var string + */ + private $_messageLocation; + + /** + * The location of the lock. + * + * @var string + */ + private $_lockLocation; + + + /** + * Creates a broker properties instance with default parameters. + */ + public function __construct() + { + } + + // @codingStandardsIgnoreStart + + /** + * Creates a broker properties instance with specified JSON message. + * + * @param string $brokerPropertiesJson A JSON message representing a + * broker properties. + * + * @return none + */ + public static function create($brokerPropertiesJson) + { + Validate::isString($brokerPropertiesJson, 'brokerPropertiesJson'); + + $brokerProperties = new BrokerProperties(); + + $brokerPropertiesArray = (array)json_decode($brokerPropertiesJson); + + if (array_key_exists('CorrelationId', $brokerPropertiesArray)) { + $brokerProperties->setCorrelationId( + $brokerPropertiesArray['CorrelationId'] + ); + } + + if (array_key_exists('SessionId', $brokerPropertiesArray)) { + $brokerProperties->setSessionId( + $brokerPropertiesArray['SessionId'] + ); + } + + if (array_key_exists('DeliveryCount', $brokerPropertiesArray)) { + $brokerProperties->setDeliveryCount( + $brokerPropertiesArray['DeliveryCount'] + ); + } + + if (array_key_exists('LockedUntilUtc', $brokerPropertiesArray)) { + $brokerProperties->setLockedUntilUtc( + \DateTime::createFromFormat( + Resources::AZURE_DATE_FORMAT, + $brokerPropertiesArray['LockedUntilUtc'] + ) + ); + } + + if (array_key_exists('LockToken', $brokerPropertiesArray)) { + $brokerProperties->setLockToken( + $brokerPropertiesArray['LockToken'] + ); + } + + if (array_key_exists('MessageId', $brokerPropertiesArray)) { + $brokerProperties->setMessageId( + $brokerPropertiesArray['MessageId'] + ); + } + + if (array_key_exists('Label', $brokerPropertiesArray)) { + $brokerProperties->setLabel($brokerPropertiesArray['Label']); + } + + if (array_key_exists('ReplyTo', $brokerPropertiesArray)) { + $brokerProperties->setReplyTo($brokerPropertiesArray['ReplyTo']); + } + + if (array_key_exists('SequenceNumber', $brokerPropertiesArray)) { + $brokerProperties->setSequenceNumber( + $brokerPropertiesArray['SequenceNumber'] + ); + } + + if (array_key_exists('TimeToLive', $brokerPropertiesArray)) { + $brokerProperties->setTimeToLive( + doubleval($brokerPropertiesArray['TimeToLive']) + ); + } + + if (array_key_exists('To', $brokerPropertiesArray)) { + $brokerProperties->setTo($brokerPropertiesArray['To']); + } + + if (array_key_exists( + 'ScheduledEnqueueTimeUtc', + $brokerPropertiesArray + ) + ) { + $brokerProperties->setScheduledEnqueueTimeUtc( + \DateTime::createFromFormat( + Resources::AZURE_DATE_FORMAT, + $brokerPropertiesArray['ScheduledEnqueueTimeUtc'] + ) + ); + } + + if (array_key_exists('ReplyToSessionId', $brokerPropertiesArray)) { + $brokerProperties->setReplyToSessionId( + $brokerPropertiesArray['ReplyToSessionId'] + ); + } + + if (array_key_exists('MessageLocation', $brokerPropertiesArray)) { + $brokerProperties->setMessageLocation( + $brokerPropertiesArray['MessageLocation'] + ); + } + + if (array_key_exists('LockLocation', $brokerPropertiesArray)) { + $brokerProperties->setLockLocation( + $brokerPropertiesArray['LockLocation'] + ); + } + + return $brokerProperties; + } + + // @codingStandardsIgnoreEnd + + /** + * Gets the correlation ID. + * + * @return string + */ + public function getCorrelationId() + { + return $this->_correlationId; + } + + /** + * Sets the correlation ID. + * + * @param string $correlationId The correlation ID. + * + * @return none + */ + public function setCorrelationId($correlationId) + { + $this->_correlationId = $correlationId; + } + + /** + * Gets the session ID. + * + * @return string + */ + public function getSessionId() + { + return $this->_sessionId; + } + + /** + * Sets the session ID. + * + * @param string $sessionId The ID of the session. + * + * @return none + */ + public function setSessionId($sessionId) + { + $this->_sessionId = $sessionId; + } + + /** + * Gets the delivery count. + * + * @return integer + */ + public function getDeliveryCount() + { + return $this->_deliveryCount; + } + + /** + * Sets the delivery count. + * + * @param integer $deliveryCount The count of the delivery. + * + * @return none + */ + public function setDeliveryCount($deliveryCount) + { + $this->_deliveryCount = $deliveryCount; + } + + /** + * Gets the locked until time. + * + * @return string + */ + public function getLockedUntilUtc() + { + return $this->_lockedUntilUtc; + } + + /** + * Sets the locked until time. + * + * @param string $lockedUntilUtc The locked until time. + * + * @return none + */ + public function setLockedUntilUtc($lockedUntilUtc) + { + $this->_lockedUntilUtc = $lockedUntilUtc; + } + + /** + * Gets lock token. + * + * @return string. + */ + public function getLockToken() + { + return $this->_lockToken; + } + + /** + * Sets the lock token. + * + * @param string $lockToken The lock token. + * + * @return none + */ + public function setLockToken($lockToken) + { + $this->_lockToken = $lockToken; + } + + /** + * Gets the message ID. + * + * @return string + */ + public function getMessageId() + { + return $this->_messageId; + } + + /** + * Sets the message ID. + * + * @param string $messageId The ID of the message. + * + * @return none + */ + public function setMessageId($messageId) + { + $this->_messageId = $messageId; + } + + /** + * Gets the label. + * + * @return string + */ + public function getLabel() + { + return $this->_label; + } + + /** + * Sets the label. + * + * @param string $label The label of the broker property. + * + * @return none + */ + public function setLabel($label) + { + $this->_label = $label; + } + + /** + * Gets the reply to. + * + * @return string + */ + public function getReplyTo() + { + return $this->_replyTo; + } + + /** + * Sets the reply to. + * + * @param string $replyTo The reply to. + * + * @return none + */ + public function setReplyTo($replyTo) + { + $this->_replyTo = $replyTo; + } + + /** + * Gets the sequence number. + * + * @return integer + */ + public function getSequenceNumber() + { + return $this->_sequenceNumber; + } + + /** + * Sets the sequence number. + * + * @param integer $sequenceNumber The sequence number. + * + * @return none + */ + public function setSequenceNumber($sequenceNumber) + { + $this->_sequenceNumber = $sequenceNumber; + } + + /** + * Gets time to live. + * + * @return string + */ + public function getTimeToLive() + { + return $this->_timeToLive; + } + + /** + * Sets time to live. + * + * @param string $timeToLive The time to live. + * + * @return none + */ + public function setTimeToLive($timeToLive) + { + $this->_timeToLive = $timeToLive; + } + + /** + * Gets to. + * + * @return string + */ + public function getTo() + { + return $this->_to; + } + + /** + * Sets to. + * + * @param string $to To. + * + * @return none + */ + public function setTo($to) + { + $this->_to = $to; + } + + /** + * Gets scheduled enqueue time UTC. + * + * @return string + */ + public function getScheduledEnqueueTimeUtc() + { + return $this->_scheduledEnqueueTimeUtc; + } + + /** + * Sets scheduled enqueue time UTC. + * + * @param string $scheduledEnqueueTimeUtc The scheduled enqueue time. + * + * @return none + */ + public function setScheduledEnqueueTimeUtc($scheduledEnqueueTimeUtc) + { + $this->_scheduledEnqueueTimeUtc = $scheduledEnqueueTimeUtc; + } + + /** + * Gets reply to session ID. + * + * @return string + */ + public function getReplyToSessionId() + { + return $this->_replyToSessionId; + } + + /** + * Sets reply to session. + * + * @param string $replyToSessionId reply to session. + * + * @return none + */ + public function setReplyToSessionId($replyToSessionId) + { + $this->_replyToSessionId = $replyToSessionId; + } + + /** + * Gets message location. + * + * @return string + */ + public function getMessageLocation() + { + return $this->_messageLocation; + } + + /** + * Sets the location of the message. + * + * @param string $messageLocation The location of the message. + * + * @return none + */ + public function setMessageLocation($messageLocation) + { + $this->_messageLocation = $messageLocation; + } + + /** + * Gets the location of the lock. + * + * @return string + */ + public function getLockLocation() + { + return $this->_lockLocation; + } + + /** + * Sets the location of the lock. + * + * @param string $lockLocation The location of the lock. + * + * @return none + */ + public function setLockLocation($lockLocation) + { + $this->_lockLocation = $lockLocation; + } + + /** + * Gets a string representing the broker property. + * + * @return string + */ + public function toString() + { + $value = array(); + + $this->setValueArrayString( + $value, + 'CorrelationId', + $this->_correlationId + ); + + $this->setValueArrayString( + $value, + 'SessionId', + $this->_sessionId + ); + + $this->setValueArrayInt( + $value, + 'DeliveryCount', + $this->_deliveryCount + ); + + $this->setValueArrayDateTime( + $value, + 'LockedUntilUtc', + $this->_lockedUntilUtc + ); + + $this->setValueArrayString( + $value, + 'LockToken', + $this->_lockToken + ); + + $this->setValueArrayString( + $value, + 'MessageId', + $this->_messageId + ); + + $this->setValueArrayString( + $value, + 'Label', + $this->_label + ); + + $this->setValueArrayString( + $value, + 'ReplyTo', + $this->_replyTo + ); + + $this->setValueArrayString( + $value, + 'SequenceNumber', + $this->_sequenceNumber + ); + + $this->setValueArrayFloat( + $value, + 'TimeToLive', + $this->_timeToLive + ); + + $this->setValueArrayString( + $value, + 'To', + $this->_to + ); + + $this->setValueArrayDateTime( + $value, + 'ScheduledEnqueueTimeUtc', + $this->_scheduledEnqueueTimeUtc + ); + + $this->setValueArrayString( + $value, + 'ReplyToSessionId', + $this->_replyToSessionId + ); + + $this->setValueArrayString( + $value, + 'MessageLocation', + $this->_messageLocation + ); + + $this->setValueArrayString( + $value, + 'LockLocation', + $this->_lockLocation + ); + + $result = json_encode($value); + return $result; + } + + /** + * Sets a string in an array. + * + * @param array &$valueArray The array of a set of values. + * @param string $key The key of the key value pair. + * @param string $value The value of the key value pair. + * + * @return none + */ + public function setValueArrayString(&$valueArray, $key, $value) + { + Validate::isArray($valueArray, 'valueArray'); + Validate::isString($key, 'key'); + + if (!empty($value)) { + Validate::isString($value, 'value'); + $valueArray[$key] = $value; + } + } + + /** + * Sets an integer value in an array. + * + * @param array &$valueArray The array of a set of values. + * @param string $key The key of the key value pair. + * @param int $value The value of the key value pair. + * + * @return none + */ + public function setValueArrayInt(&$valueArray, $key, $value) + { + Validate::isArray($valueArray, 'valueArray'); + Validate::isString($key, 'key'); + + if (!empty($value)) { + Validate::isInteger($value, 'value'); + $valueArray[$key] = $value; + } + } + + /** + * Sets a float value in an array. + * + * @param array &$valueArray The array of a set of values. + * @param string $key The key of the key value pair. + * @param float $value The value of the key value pair. + * + * @return none + */ + public function setValueArrayFloat(&$valueArray, $key, $value) + { + Validate::isArray($valueArray, 'valueArray'); + Validate::isString($key, 'key'); + + if (!empty($value)) { + Validate::isDouble($value, 'value'); + $valueArray[$key] = (double)$value; + } + } + + /** + * Sets a DateTime value in an array. + * + * @param array &$valueArray The array of a set of values. + * @param string $key The key of the key value pair. + * @param \DateTime $value The value of the key value pair. + * + * @return none + */ + public function setValueArrayDateTime(&$valueArray, $key, $value) + { + Validate::isArray($valueArray, 'valueArray'); + Validate::isString($key, 'key'); + + if (!empty($value)) { + Validate::isDate($value, 'value'); + $valueArray[$key] = gmdate( + Resources::AZURE_DATE_FORMAT, + $value->getTimestamp() + ); + } + } +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/BrokeredMessage.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/BrokeredMessage.php new file mode 100644 index 0000000..15d432b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/BrokeredMessage.php @@ -0,0 +1,552 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceBus\Models; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Validate; +use WindowsAzure\ServiceBus\Models\BrokerProperties; + +/** + * A class representing the brokered message of Windows Azure Service Bus. + * + * @category Microsoft + * @package WindowsAzure\ServiceBus\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ +class BrokeredMessage +{ + /** + * The properties of the broker. + * + * @var BrokerProperties + */ + private $_brokerProperties; + + /** + * The body of the brokered message. + * + * @var string + */ + private $_body; + + /** + * The content type of the brokered message. + * + * @var string + */ + private $_contentType; + + /** + * The date of the brokered message. + * + * @var \DateTime + */ + private $_date; + + /** + * The properties of the message that are customized. + * + * @var array + */ + private $_customProperties; + + /** + * Creates a brokered message with specified broker properties. + * + * @param string $body The body of the message. + */ + public function __construct($body = Resources::EMPTY_STRING) + { + Validate::isString($body, 'body'); + $this->_body = $body; + $this->_brokerProperties = new BrokerProperties(); + $this->_customProperties = array(); + } + + /** + * Gets the broker properties. + * + * @return BrokerProperties + */ + public function getBrokerProperties() + { + return $this->_brokerProperties; + } + + /** + * Sets the broker properties. + * + * @param BrokerProperties $brokerProperties The properties of broker. + * + * @return none + */ + public function setBrokerProperties($brokerProperties) + { + $this->_brokerProperties = $brokerProperties; + } + + /** + * Gets the body of the brokered message. + * + * @return string + */ + public function getBody() + { + return $this->_body; + } + + /** + * Sets the body of the brokered message. + * + * @param string $body The body of the brokered message. + * + * @return none + */ + public function setBody($body) + { + $this->_body = $body; + } + + /** + * Gets the content type of the brokered message. + * + * @return string + */ + public function getContentType() + { + return $this->_contentType; + } + + /** + * Sets the content type of the brokered message. + * + * @param string $contentType The content type of + * the brokered message. + * + * @return none + */ + public function setContentType($contentType) + { + $this->_contentType = $contentType; + } + + /** + * Gets the date of the brokered message. + * + * @return \DateTime + */ + public function getDate() + { + return $this->_date; + } + + /** + * Sets the date of the brokered message. + * + * @param \DateTime $date Sets the date of the brokered message. + * + * @return none + */ + public function setDate($date) + { + $this->_date = $date; + } + + /** + * Gets the value of a custom property. + * + * @param string $propertyName The name of the property. + * + * @return string + */ + public function getProperty($propertyName) + { + Validate::isString($propertyName, 'propertyName'); + return $this->_customProperties[strtolower($propertyName)]; + } + + /** + * Sets the value of a custom property. + * + * @param string $propertyName The name of the property. + * @param mixed $propertyValue The value of the property. + * + * @return none + */ + public function setProperty($propertyName, $propertyValue) + { + Validate::isString($propertyName, 'propertyName'); + Validate::notNull($propertyValue, 'propertyValue'); + + $this->_customProperties[strtolower($propertyName)] = $propertyValue; + } + + /** + * Gets the custom properties. + * + * @return array + */ + public function getProperties() + { + return $this->_customProperties; + } + + /** + * Gets the delivery count. + * + * @return integer + */ + public function getDeliveryCount() + { + return $this->_brokerProperties->getDeliveryCount(); + } + + /** + * Sets the delivery count. + * + * @param integer $deliveryCount The times that the message has been delivered. + * + * @return none + */ + public function setDeliveryCount($deliveryCount) + { + $this->_brokerProperties->setDeliveryCount($deliveryCount); + } + + /** + * Gets the ID of the message. + * + * @return string + */ + public function getMessageId() + { + return $this->_brokerProperties->getMessageId(); + } + + /** + * Sets the ID of the message. + * + * @param string $messageId The ID of the message. + * + * @return none + */ + public function setMessageId($messageId) + { + $this->_brokerProperties->setMessageId($messageId); + } + + /** + * Gets the sequence number. + * + * @return integer + */ + public function getSequenceNumber() + { + return $this->_brokerProperties->getSequenceNumber(); + } + + /** + * Sets the sequence number. + * + * @param integer $sequenceNumber The sequence number. + * + * @return none + */ + public function setSequenceNumber($sequenceNumber) + { + $this->_brokerProperties->setSequenceNumber($sequenceNumber); + } + + /** + * Gets the time to live. + * + * @return string + */ + public function getTimeToLive() + { + return $this->_brokerProperties->getTimeToLive(); + } + + /** + * Sets the time to live. + * + * @param string $timeToLive The time to live. + * + * @return none + */ + public function setTimeToLive($timeToLive) + { + $this->_brokerProperties->setTimeToLive($timeToLive); + } + + /** + * Gets the lock token. + * + * @return string + */ + public function getLockToken() + { + return $this->_brokerProperties->getLockToken(); + } + + /** + * Sets the lock token. + * + * @param string $lockToken The token of the lock. + * + * @return none + */ + public function setLockToken($lockToken) + { + $this->_brokerProperties->setLockToken($lockToken); + } + + /** + * Gets the time of locked until UTC. + * + * @return string + */ + public function getLockedUntilUtc() + { + return $this->_brokerProperties->getLockedUntilUtc(); + } + + /** + * Sets the time of locked until UTC. + * + * @param string $lockedUntilUtc The time of locked until UTC. + * + * @return none + */ + public function setLockedUntilUtc($lockedUntilUtc) + { + $this->_brokerProperties->setLockedUntilUtc($lockedUntilUtc); + } + + /** + * Gets the correlation ID. + * + * @return string + */ + public function getCorrelationId() + { + return $this->_brokerProperties->getCorrelationId(); + } + + /** + * Sets the correlation ID. + * + * @param string $correlationId The ID of the correlation. + * + * @return none + */ + public function setCorrelationId($correlationId) + { + $this->_brokerProperties->setCorrelationId($correlationId); + } + + /** + * Gets the session ID. + * + * @return string + */ + public function getSessionId() + { + return $this->_brokerProperties->getSessionId(); + } + + /** + * Sets the session ID. + * + * @param string $sessionId The ID of the session. + * + * @return none + */ + public function setSessionId($sessionId) + { + $this->_brokerProperties->setSessionId($sessionId); + } + + /** + * Gets the label. + * + * @return string + */ + public function getLabel() + { + return $this->_brokerProperties->getLabel(); + } + + /** + * Sets the label. + * + * @param string $label The label of the broker properties. + * + * @return none + */ + public function setLabel($label) + { + $this->_brokerProperties->setLabel($label); + } + + /** + * Gets reply to. + * + * @return string + */ + public function getReplyTo() + { + return $this->_brokerProperties->getReplyTo(); + } + + /** + * Sets the reply to. + * + * @param string $replyTo The reply to value. + * + * @return none + */ + public function setReplyTo($replyTo) + { + $this->_brokerProperties->setReplyTo($replyTo); + } + + /** + * Gets to. + * + * @return string + */ + public function getTo() + { + return $this->_brokerProperties->getTo(); + } + + /** + * Sets the to. + * + * @param string $to to. + * + * @return none + */ + public function setTo($to) + { + $this->_brokerProperties->setTo($to); + } + + /** + * Gets the scheduled enqueue time. + * + * @return string + */ + public function getScheduledEnqueueTimeUtc() + { + return $this->_brokerProperties->getScheduledEnqueueTimeUtc(); + } + + /** + * Sets the scheduled enqueue time. + * + * @param string $scheduledEnqueueTime The date/time of the message. + * + * @return none + */ + public function setScheduledEnqueueTimeUtc($scheduledEnqueueTime) + { + $this->_brokerProperties->setScheduledEnqueueTimeUtc($scheduledEnqueueTime); + } + + /** + * Gets the reply to session ID. + * + * @return string + */ + public function getReplyToSessionId() + { + return $this->_brokerProperties->getReplyToSessionId(); + } + + /** + * Sets the reply to session ID. + * + * @param string $replyToSessionId The session ID of the reply to recipient. + * + * @return none + */ + public function setReplyToSessionId($replyToSessionId) + { + $this->_brokerProperties->setReplyToSessionId($replyToSessionId); + } + + /** + * Gets the message location. + * + * @return string + */ + public function getMessageLocation() + { + return $this->_brokerProperties->getMessageLocation(); + } + + /** + * Sets the message location. + * + * @param string $messageLocation The location of the message. + * + * @return none + */ + public function setMessageLocation($messageLocation) + { + $this->_brokerProperties->setMessageLocation($messageLocation); + } + + + /** + * Gets the location of the lock. + * + * @return string + */ + public function getLockLocation() + { + return $this->_brokerProperties->getLockLocation(); + } + + /** + * Sets the location of the lock. + * + * @param string $lockLocation The location of the lock. + * + * @return none + */ + public function setLockLocation($lockLocation) + { + $this->_brokerProperties->setLockLocation($lockLocation); + } + +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/CorrelationFilter.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/CorrelationFilter.php new file mode 100644 index 0000000..817580a --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/CorrelationFilter.php @@ -0,0 +1,78 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ +namespace WindowsAzure\ServiceBus\Models; +use WindowsAzure\ServiceBus\Internal\Filter; + +/** + * The base class for rule filter. + * + * @category Microsoft + * @package WindowsAzure\ServiceBus\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +class CorrelationFilter extends Filter +{ + /** + * The ID of the correlation. + * + * @var string + */ + private $_correlationId; + + /** + * Creates a correlation filter with default parameter. + */ + public function __construct() + { + parent::__construct(); + $this->attributes['xsi:type'] = 'CorrelationFilter'; + } + + /** + * Gets the ID of the correlation. + * + * @return string + */ + public function getCorrelationId() + { + return $this->_correlationId; + } + + /** + * Sets the ID of the correlation. + * + * @param string $correlationId The ID of the correlation. + * + * @return none + */ + public function setCorrelationId($correlationId) + { + $this->_correlationId = $correlationId; + } +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/EmptyRuleAction.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/EmptyRuleAction.php new file mode 100644 index 0000000..6b22d3a --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/EmptyRuleAction.php @@ -0,0 +1,50 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ +namespace WindowsAzure\ServiceBus\Models; +use WindowsAzure\ServiceBus\Internal\Action; + +/** + * The empty rule action class. + * + * @category Microsoft + * @package WindowsAzure\ServiceBus\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +class EmptyRuleAction extends Action +{ + /** + * Creates an empty rule action with default parameter. + */ + public function __construct() + { + parent::__construct(); + $this->attributes['xsi:type'] = 'EmptyRuleAction'; + } + +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/FalseFilter.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/FalseFilter.php new file mode 100644 index 0000000..d89565e --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/FalseFilter.php @@ -0,0 +1,50 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ +namespace WindowsAzure\ServiceBus\Models; +use WindowsAzure\ServiceBus\Internal\Filter; + +/** + * The false filter. + * + * @category Microsoft + * @package WindowsAzure\ServiceBus\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +class FalseFilter extends Filter +{ + /** + * Creates a filter with default parameter. + */ + public function __construct() + { + parent::__construct(); + $this->attributes['xsi:type'] = 'FalseFilter'; + } + +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/ListOptions.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/ListOptions.php new file mode 100644 index 0000000..3e8337f --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/ListOptions.php @@ -0,0 +1,105 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceBus\Models; + +/** + * The base class for the options for list request. + * + * @category Microsoft + * @package WindowsAzure\ServiceBus\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +class ListOptions +{ + /** + * The skip query parameter for list API. + * + * @var integer + */ + private $_skip; + + /** + * The top query parameter for list API. + * + * @var integer + */ + private $_top; + + /** + * Creates a list option instance with default parameters. + */ + public function __construct() + { + } + + /** + * Gets the skip parameter. + * + * @return integer + */ + public function getSkip() + { + return $this->_skip; + } + + /** + * Sets the skip parameter. + * + * @param integer $skip value. + * + * @return none + */ + public function setSkip($skip) + { + $this->_skip = $skip; + } + + /** + * Gets the top parameter. + * + * @return integer + */ + public function getTop() + { + return $this->_top; + } + + /** + * Sets the top parameter. + * + * @param integer $top value. + * + * @return none + */ + public function setTop($top) + { + $this->_top = $top; + } +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/ListQueuesOptions.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/ListQueuesOptions.php new file mode 100644 index 0000000..e697a7e --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/ListQueuesOptions.php @@ -0,0 +1,42 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ +namespace WindowsAzure\ServiceBus\Models; +use WindowsAzure\ServiceBus\Models\ListOptions; + +/** + * This options to list queues. + * + * @category Microsoft + * @package WindowsAzure\ServiceBus\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +class ListQueuesOptions extends ListOptions +{ +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/ListQueuesResult.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/ListQueuesResult.php new file mode 100644 index 0000000..ef905e3 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/ListQueuesResult.php @@ -0,0 +1,99 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceBus\Models; + +use WindowsAzure\Common\Internal\Atom\Feed; +use WindowsAzure\Common\Internal\Atom\Entry; + +/** + * The results of list queues request. + * + * @category Microsoft + * @package WindowsAzure\ServiceBus\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ +class ListQueuesResult extends Feed +{ + /** + * The information of the queue. + * + * @var array + */ + private $_queueInfos; + + /** + * Populates the properties with the response from the list queues request. + * + * @param string $response The body of the response of the list queues request. + * + * @return none + */ + public function parseXml($response) + { + parent::parseXml($response); + $listQueuesResultXml = new \SimpleXMLElement($response); + $this->_queueInfos = array(); + foreach ($listQueuesResultXml->entry as $entry) { + $queueInfo = new QueueInfo(); + $queueInfo->parseXml($entry->asXml()); + $this->_queueInfos[] = $queueInfo; + } + } + + /** + * Creates a queue with default parameters. + */ + public function __construct() + { + } + + /** + * Gets the queue information. + * + * @return array + */ + public function getQueueInfos() + { + return $this->_queueInfos; + } + + /** + * Sets the information of the queue. + * + * @param array $queueInfos The information of the queue. + * + * @return none + */ + public function setQueueInfos($queueInfos) + { + $this->_queueInfos = $queueInfos; + } + +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/ListRulesOptions.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/ListRulesOptions.php new file mode 100644 index 0000000..776627c --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/ListRulesOptions.php @@ -0,0 +1,42 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ +namespace WindowsAzure\ServiceBus\Models; + +use WindowsAzure\ServiceBus\Models\ListOptions; + +/** + * The options to specify a list rules request. + * + * @category Microsoft + * @package WindowsAzure\ServiceBus\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +class ListRulesOptions extends ListOptions +{ +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/ListRulesResult.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/ListRulesResult.php new file mode 100644 index 0000000..3d69682 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/ListRulesResult.php @@ -0,0 +1,101 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceBus\Models; + +use WindowsAzure\Common\Internal\Atom\Feed; +use WindowsAzure\Common\Internal\Atom\Entry; +use WindowsAzure\ServiceBus\Models\RuleInfo; + +/** + * The result of the list rules request. + * + * @category Microsoft + * @package WindowsAzure\ServiceBus\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ +class ListRulesResult extends Feed +{ + /** + * The information of the rule. + * + * @var array + */ + private $_ruleInfos; + + /** + * Populates the properties with the response from the list rules request. + * + * @param string $response The body of the response of the list rules request. + * + * @return none + */ + public function parseXml($response) + { + parent::parseXml($response); + $listRulesResultXml = new \SimpleXMLElement($response); + $this->_ruleInfos = array(); + + foreach ($listRulesResultXml->entry as $entry) { + $ruleInfo = new RuleInfo(); + $ruleInfo->parseXml($entry->asXml()); + $this->_ruleInfos[] = $ruleInfo; + } + } + + /** + * Creates a list rules result instance with default parameters. + */ + public function __construct() + { + } + + /** + * Gets the information of the rules. + * + * @return array + */ + public function getRuleInfos() + { + return $this->_ruleInfos; + } + + /** + * Sets the information of the rule. + * + * @param array $ruleInfos The information of the rule. + * + * @return none + */ + public function setRuleInfos($ruleInfos) + { + $this->_ruleInfos = $ruleInfos; + } + +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/ListSubscriptionsOptions.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/ListSubscriptionsOptions.php new file mode 100644 index 0000000..41cd776 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/ListSubscriptionsOptions.php @@ -0,0 +1,41 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ +namespace WindowsAzure\ServiceBus\Models; +use WindowsAzure\ServiceBus\Models\ListOptions; + +/** + * The options to list the subscriptions. + * + * @category Microsoft + * @package WindowsAzure\ServiceBus\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +class ListSubscriptionsOptions extends ListOptions +{ +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/ListSubscriptionsResult.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/ListSubscriptionsResult.php new file mode 100644 index 0000000..f6c3d42 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/ListSubscriptionsResult.php @@ -0,0 +1,104 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceBus\Models; + +use WindowsAzure\Common\Internal\Atom\Feed; +use WindowsAzure\Common\Internal\Atom\Content; +use WindowsAzure\ServiceBus\Models\SubscriptionInfo; + +/** + * The result of the list subscription request. + * + * @category Microsoft + * @package WindowsAzure\ServiceBus\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +class ListSubscriptionsResult extends Feed +{ + /** + * The information of the subscription. + * + * @var array + */ + private $_subscriptionInfos; + + /** + * Populates the properties with the response from the list + * subscriptions request. + * + * @param string $response The body of the response of the list + * subscriptions request. + * + * @return none + */ + public function parseXml($response) + { + parent::parseXml($response); + $listSubscriptionsResultXml = new \SimpleXMLElement($response); + $this->_subscriptionInfos = array(); + foreach ($listSubscriptionsResultXml->entry as $entry) { + $subscriptionInfo = new SubscriptionInfo(); + $subscriptionInfo->parseXml($entry->asXml()); + $this->_subscriptionInfos[] = $subscriptionInfo; + } + } + + /** + * Creates a list subscriptions result with default parameters. + */ + public function __construct() + { + } + + /** + * Gets the information of the subscription. + * + * @return array + */ + public function getSubscriptionInfos() + { + return $this->_subscriptionInfos; + } + + /** + * Sets the information of the rule. + * + * @param array $subscriptionInfos The information of the + * subscription. + * + * @return none + */ + public function setSubscriptionInfos($subscriptionInfos) + { + $this->_subscriptionInfos = $subscriptionInfos; + } + +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/ListTopicsOptions.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/ListTopicsOptions.php new file mode 100644 index 0000000..575b963 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/ListTopicsOptions.php @@ -0,0 +1,42 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ +namespace WindowsAzure\ServiceBus\Models; + +use WindowsAzure\ServiceBus\Models\ListOptions; + +/** + * This class contains the options for list topics request. + * + * @category Microsoft + * @package WindowsAzure\ServiceBus\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +class ListTopicsOptions extends ListOptions +{ +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/ListTopicsResult.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/ListTopicsResult.php new file mode 100644 index 0000000..7fbb4e2 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/ListTopicsResult.php @@ -0,0 +1,99 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceBus\Models; + +use WindowsAzure\Common\Internal\Atom\Feed; +use WindowsAzure\Common\Internal\Atom\Entry; + +/** + * The result of a list topics request. + * + * @category Microsoft + * @package WindowsAzure\ServiceBus\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ +class ListTopicsResult extends Feed +{ + /** + * Gets the information of the topic. + * + * @var array + */ + private $_topicInfos; + + /** + * Populates the properties with a the response from the list topics request. + * + * @param string $response The body of the response of the list topics request. + * + * @return none + */ + public function parseXml($response) + { + parent::parseXml($response); + $listTopicsResultXml = new \SimpleXMLElement($response); + $this->_topicInfos = array(); + foreach ($listTopicsResultXml->entry as $entry) { + $topicInfo = new TopicInfo(); + $topicInfo->parseXml($entry->asXml()); + $this->_topicInfos[] = $topicInfo; + } + } + + /** + * Creates a list topics result with default parameters. + */ + public function __construct() + { + } + + /** + * Gets the information of the topic. + * + * @return array + */ + public function getTopicInfos() + { + return $this->_topicInfos; + } + + /** + * Sets the topic information. + * + * @param array $topicInfos The information of the topics. + * + * @return none + */ + public function setTopicInfos($topicInfos) + { + $this->_topicInfos = $topicInfos; + } + +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/QueueDescription.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/QueueDescription.php new file mode 100644 index 0000000..6ae58f7 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/QueueDescription.php @@ -0,0 +1,477 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceBus\Models; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Utilities; + +/** + * The description of a queue. + * + * @category Microsoft + * @package WindowsAzure\ServiceBus\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ +class QueueDescription +{ + /** + * The duration of the lock. + * + * @var string + */ + private $_lockDuration; + + /** + * The maximum size in mega bytes. + * + * @var integer + */ + private $_maxSizeInMegabytes; + + /** + * Requires duplicate detection for queue. + * + * @var boolean + */ + private $_requiresDuplicateDetection; + + /** + * Requires session for the queue. + * + * @var boolean + */ + private $_requiresSession; + + /** + * The default message time to live. + * + * @var string + */ + private $_defaultMessageTimeToLive; + + /** + * The dead lettering on message expiration. + * + * @var string + */ + private $_deadLetteringOnMessageExpiration; + + /** + * The duplicate detection history time window. + * + * @var integer + */ + private $_duplicateDetectionHistoryTimeWindow; + + /** + * The maximum delivery count. + * + * @var integer + */ + private $_maxDeliveryCount; + + /** + * Enables batched operations. + * + * @var boolean + */ + private $_enableBatchedOperations; + + /** + * The size in bytes. + * + * @var integer + */ + private $_sizeInBytes; + + /** + * The count of the message. + * + * @var integer + */ + private $_messageCount; + + // @codingStandardsIgnoreStart + + /** + * Creates a queue description object with specified XML string. + * + * @param string $queueDescriptionXml A XML based string describing + * the queue. + * + * @return none + */ + public static function create($queueDescriptionXml) + { + $queueDescription = new QueueDescription(); + $root = simplexml_load_string( + $queueDescriptionXml + ); + $queueDescriptionArray = (array)$root; + if (array_key_exists('LockDuration', $queueDescriptionArray)) { + $queueDescription->setLockDuration( + (string)$queueDescriptionArray['LockDuration'] + ); + } + + if (array_key_exists('MaxSizeInMegabytes', $queueDescriptionArray)) { + $queueDescription->setMaxSizeInMegabytes( + (integer)$queueDescriptionArray['MaxSizeInMegabytes'] + ); + } + + if (array_key_exists( + 'RequiresDuplicateDetection', + $queueDescriptionArray + ) + ) { + $queueDescription->setRequiresDuplicateDetection( + (boolean)$queueDescriptionArray['RequiresDuplicateDetection'] + ); + } + + if (array_key_exists('RequiresSession', $queueDescriptionArray)) { + $queueDescription->setRequiresSession( + (boolean)$queueDescriptionArray['RequiresSession'] + ); + } + + if (array_key_exists( + 'DefaultMessageTimeToLive', + $queueDescriptionArray + ) + ) { + $queueDescription->setDefaultMessageTimeToLive( + (string)$queueDescriptionArray['DefaultMessageTimeToLive'] + ); + } + + if (array_key_exists( + 'DeadLetteringOnMessageExpiration', + $queueDescriptionArray + ) + ) { + $queueDescription->setDeadLetteringOnMessageExpiration( + (string)$queueDescriptionArray['DeadLetteringOnMessageExpiration'] + ); + } + + if (array_key_exists( + 'DuplicateDetectionHistoryTimeWindow', + $queueDescriptionArray + ) + ) { + $queueDescription->setDuplicateDetectionHistoryTimeWindow( + (string)$queueDescriptionArray['DuplicateDetectionHistoryTimeWindow'] + ); + } + + if (array_key_exists('MaxDeliveryCount', $queueDescriptionArray)) { + $queueDescription->setMaxDeliveryCount( + (integer)$queueDescriptionArray['MaxDeliveryCount'] + ); + } + + if (array_key_exists('EnableBatchedOperations', $queueDescriptionArray)) { + $queueDescription->setEnableBatchedOperations( + (boolean)$queueDescriptionArray['EnableBatchedOperations'] + ); + } + + if (array_key_exists('SizeInBytes', $queueDescriptionArray)) { + $queueDescription->setSizeInBytes( + (integer)$queueDescriptionArray['SizeInBytes'] + ); + } + + if (array_key_exists('MessageCount', $queueDescriptionArray)) { + $queueDescription->setMessageCount( + (integer)$queueDescriptionArray['MessageCount'] + ); + } + + return $queueDescription; + } + + // @codingStandardsIgnoreEnd + + /** + * Creates a queue description instance with default parameters. + */ + public function __construct() + { + } + + /** + * Gets the lock duration. + * + * @return string + */ + public function getLockDuration() + { + return $this->_lockDuration; + } + + /** + * Sets the lock duration. + * + * @param string $lockDuration The lock duration. + * + * @return none + */ + public function setLockDuration($lockDuration) + { + $this->_lockDuration = $lockDuration; + } + + /** + * gets the maximum size in mega bytes. + * + * @return integer + */ + public function getMaxSizeInMegabytes() + { + return $this->_maxSizeInMegabytes; + } + + /** + * Sets the max size in mega bytes. + * + * @param integer $maxSizeInMegabytes The max size in mega bytes. + * + * @return none + */ + public function setMaxSizeInMegabytes($maxSizeInMegabytes) + { + $this->_maxSizeInMegabytes = $maxSizeInMegabytes; + } + + /** + * Gets requires duplicate detection. + * + * @return boolean + */ + public function getRequiresDuplicateDetection() + { + return $this->_requiresDuplicateDetection; + } + + /** + * Sets requires duplicate detection. + * + * @param boolean $requiresDuplicateDetection If duplicate detection is required. + * + * @return none + */ + public function setRequiresDuplicateDetection($requiresDuplicateDetection) + { + $this->_requiresDuplicateDetection = $requiresDuplicateDetection; + } + + /** + * Gets the requires session. + * + * @return boolean + */ + public function getRequiresSession() + { + return $this->_requiresSession; + } + + /** + * Sets the requires session. + * + * @param boolean $requiresSession If session is required. + * + * @return none + */ + public function setRequiresSession($requiresSession) + { + $this->_requiresSession = $requiresSession; + } + + /** + * gets the default message time to live. + * + * @return string + */ + public function getDefaultMessageTimeToLive() + { + return $this->_defaultMessageTimeToLive; + } + + /** + * Sets the default message time to live. + * + * @param string $defaultMessageTimeToLive The default message time to live. + * + * @return none + */ + public function setDefaultMessageTimeToLive($defaultMessageTimeToLive) + { + $this->_defaultMessageTimeToLive = $defaultMessageTimeToLive; + } + + /** + * Gets dead lettering on message expiration. + * + * @return string + */ + public function getDeadLetteringOnMessageExpiration() + { + return $this->_deadLetteringOnMessageExpiration; + } + + /** + * Sets dead lettering on message expiration. + * + * @param string $deadLetteringOnMessageExpiration The dead lettering on + * message expiration. + * + * @return none + */ + public function setDeadLetteringOnMessageExpiration( + $deadLetteringOnMessageExpiration + ) { + $this->_deadLetteringOnMessageExpiration = $deadLetteringOnMessageExpiration; + } + + /** + * Gets duplicate detection history time window. + * + * @return string + */ + public function getDuplicateDetectionHistoryTimeWindow() + { + return $this->_duplicateDetectionHistoryTimeWindow; + } + + /** + * Sets the duplicate detection history time window. + * + * @param string $duplicateDetectionHistoryTimeWindow The duplicate + * detection history time window. + * + * @return none + */ + public function setDuplicateDetectionHistoryTimeWindow( + $duplicateDetectionHistoryTimeWindow + ) { + $value = $duplicateDetectionHistoryTimeWindow; + + $this->_duplicateDetectionHistoryTimeWindow = $value; + } + + /** + * Gets maximum delivery count. + * + * @return string + */ + public function getMaxDeliveryCount() + { + return $this->_maxDeliveryCount; + } + + /** + * Sets the maximum delivery count. + * + * @param string $maxDeliveryCount The maximum delivery count. + * + * @return none + */ + public function setMaxDeliveryCount($maxDeliveryCount) + { + $this->_maxDeliveryCount = $maxDeliveryCount; + } + + /** + * Gets enable batched operation. + * + * @return boolean + */ + public function getEnableBatchedOperations() + { + return $this->_enableBatchedOperations; + } + + /** + * Sets enable batched operations. + * + * @param boolean $enableBatchedOperations Enable batched operations. + * + * @return none + */ + public function setEnableBatchedOperations($enableBatchedOperations) + { + $this->_enableBatchedOperations = $enableBatchedOperations; + } + + /** + * Gets the size in bytes. + * + * @return integer + */ + public function getSizeInBytes() + { + return $this->_sizeInBytes; + } + + /** + * Sets the size in bytes. + * + * @param integer $sizeInBytes The size in bytes. + * + * @return none + */ + public function setSizeInBytes($sizeInBytes) + { + $this->_sizeInBytes = $sizeInBytes; + } + + /** + * Gets the message count. + * + * @return integer + */ + public function getMessageCount() + { + return $this->_messageCount; + } + + /** + * Sets the message count. + * + * @param string $messageCount The count of the message. + * + * @return none + */ + public function setMessageCount($messageCount) + { + $this->_messageCount = $messageCount; + } +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/QueueInfo.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/QueueInfo.php new file mode 100644 index 0000000..852acc6 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/QueueInfo.php @@ -0,0 +1,452 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceBus\Models; +use WindowsAzure\Common\Internal\Atom\Content; +use WindowsAzure\Common\Internal\Atom\Entry; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Serialization\XmlSerializer; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Validate; +use WindowsAzure\ServiceBus\Models\QueueDescription; + +/** + * The information of a queue. + * + * @category Microsoft + * @package WindowsAzure\ServiceBus\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +class QueueInfo +{ + /** + * The entry of the queue info. + * + * @var Entry + */ + private $_entry; + + /** + * The description of the queue. + * + * @var QueueDescription + */ + private $_queueDescription; + + /** + * Creates a QueueInfo instance with specified parameters. + * + * @param string $title The name of the queue. + * @param QueueDescription $queueDescription The description of the queue. + */ + public function __construct( + $title = Resources::EMPTY_STRING, + $queueDescription = null + ) { + + Validate::isString($title, 'title'); + if (is_null($queueDescription)) { + $queueDescription = new QueueDescription(); + } + + $this->_queueDescription = $queueDescription; + $this->_entry = new Entry(); + $this->_entry->setTitle($title); + $this->_entry->setAttribute( + Resources::XMLNS, + Resources::SERVICE_BUS_NAMESPACE + ); + } + + /** + * Populates the properties of the queue info instance with a + * ATOM ENTRY XML string. + * + * @param string $entryXml An ATOM entry based XML string. + * + * @return none + */ + public function parseXml($entryXml) + { + $this->_entry->parseXml($entryXml); + $content = $this->_entry->getContent(); + if (is_null($content)) { + $this->_queueDescription = null; + } else { + $this->_queueDescription = QueueDescription::create($content->getText()); + } + } + + /** + * Returns a XML string based on ATOM ENTRY schema. + * + * @param \XMLWriter $xmlWriter The XML writer. + * + * @return none + */ + public function writeXml($xmlWriter) + { + $content = null; + if (!is_null($this->_queueDescription)) { + $content = new Content(); + $content->setText( + XmlSerializer::objectSerialize( + $this->_queueDescription, + 'QueueDescription' + ) + ); + $content->setType(Resources::XML_CONTENT_TYPE); + } + $this->_entry->setContent($content); + $this->_entry->writeXml($xmlWriter); + } + + /** + * Gets the description of the queue. + * + * @return none + */ + public function getQueueDescription() + { + return $this->_queueDescription; + } + + /** + * Sets the description of the queue. + * + * @param QueueDescription $queueDescription The description of the queue. + * + * @return none + */ + public function setQueueDescription($queueDescription) + { + $this->_queueDescription = $queueDescription; + } + + /** + * Gets the title. + * + * @return string + */ + public function getTitle() + { + return $this->_entry->getTitle(); + } + + /** + * Sets the title. + * + * @param string $title The title of the queue info. + * + * @return none + */ + public function setTitle($title) + { + $this->_entry->setTitle($title); + } + + /** + * Gets the entry. + * + * @return Entry + */ + public function getEntry() + { + return $this->_entry; + } + + /** + * Sets the entry. + * + * @param Entry $entry The entry of the queue info. + * + * @return none + */ + public function setEntry($entry) + { + $this->_entry = $entry; + } + + /** + * Gets the lock duration. + * + * @return string + */ + public function getLockDuration() + { + return $this->_queueDescription->getLockDuration(); + } + + /** + * Sets the lock duration. + * + * @param string $lockDuration The lock duration. + * + * @return none + */ + public function setLockDuration($lockDuration) + { + $this->_queueDescription->setLockDuration($lockDuration); + } + + /** + * gets the maximum size in mega bytes. + * + * @return integer + */ + public function getMaxSizeInMegabytes() + { + return $this->_queueDescription->getMaxSizeInMegabytes(); + } + + /** + * Sets the max size in mega bytes. + * + * @param integer $maxSizeInMegabytes The max size in mega bytes. + * + * @return none + */ + public function setMaxSizeInMegabytes($maxSizeInMegabytes) + { + $this->_queueDescription->setMaxSizeInMegabytes($maxSizeInMegabytes); + } + + /** + * Gets requires duplicate detection. + * + * @return boolean + */ + public function getRequiresDuplicateDetection() + { + return $this->_queueDescription->getRequiresDuplicateDetection(); + } + + /** + * Sets requires duplicate detection. + * + * @param boolean $requiresDuplicateDetection If duplicate detection is required. + * + * @return none + */ + public function setRequiresDuplicateDetection($requiresDuplicateDetection) + { + $this->_queueDescription->setRequiresDuplicateDetection( + $requiresDuplicateDetection + ); + } + + /** + * Gets the requires session. + * + * @return boolean + */ + public function getRequiresSession() + { + return $this->_queueDescription->getRequiresSession(); + } + + /** + * Sets the requires session. + * + * @param boolean $requiresSession If session is required. + * + * @return none + */ + public function setRequiresSession($requiresSession) + { + $this->_queueDescription->setRequiresSession($requiresSession); + } + + /** + * gets the default message time to live. + * + * @return string + */ + public function getDefaultMessageTimeToLive() + { + return $this->_queueDescription->getDefaultMessageTimeToLive(); + } + + /** + * Sets the default message time to live. + * + * @param string $defaultMessageTimeToLive The default message time to live. + * + * @return none + */ + public function setDefaultMessageTimeToLive($defaultMessageTimeToLive) + { + $this->_queueDescription->setDefaultMessageTimeToLive( + $defaultMessageTimeToLive + ); + } + + /** + * Gets dead lettering on message expiration. + * + * @return string + */ + public function getDeadLetteringOnMessageExpiration() + { + return $this->_queueDescription->getDeadLetteringOnMessageExpiration(); + } + + /** + * Sets dead lettering on message expiration. + * + * @param string $deadLetteringOnMessageExpiration The dead lettering on + * message expiration. + * + * @return none + */ + public function setDeadLetteringOnMessageExpiration( + $deadLetteringOnMessageExpiration + ) { + $this->_queueDescription->setDeadLetteringOnMessageExpiration( + $deadLetteringOnMessageExpiration + ); + } + + /** + * Gets duplicate detection history time window. + * + * @return string + */ + public function getDuplicateDetectionHistoryTimeWindow() + { + return $this->_queueDescription->getDuplicateDetectionHistoryTimeWindow(); + } + + /** + * Sets the duplicate detection history time window. + * + * @param string $duplicateDetectionHistoryTimeWindow The duplicate + * detection history time window. + * + * @return none + */ + public function setDuplicateDetectionHistoryTimeWindow( + $duplicateDetectionHistoryTimeWindow + ) { + $this->_queueDescription->setDuplicateDetectionHistoryTimeWindow( + $duplicateDetectionHistoryTimeWindow + ); + } + + /** + * Gets maximum delivery count. + * + * @return string + */ + public function getMaxDeliveryCount() + { + return $this->_queueDescription->getMaxDeliveryCount(); + } + + /** + * Sets the maximum delivery count. + * + * @param string $maxDeliveryCount The maximum delivery count. + * + * @return none + */ + public function setMaxDeliveryCount($maxDeliveryCount) + { + $this->_queueDescription->setMaxDeliveryCount($maxDeliveryCount); + } + + /** + * Gets enable batched operation. + * + * @return boolean + */ + public function getEnableBatchedOperations() + { + return $this->_queueDescription->getEnableBatchedOperations(); + } + + /** + * Sets enable batched operations. + * + * @param boolean $enableBatchedOperations Enable batched operations. + * + * @return none + */ + public function setEnableBatchedOperations($enableBatchedOperations) + { + $this->_queueDescription->setEnableBatchedOperations( + $enableBatchedOperations + ); + } + + /** + * Gets the size in bytes. + * + * @return integer + */ + public function getSizeInBytes() + { + return $this->_queueDescription->getSizeInBytes(); + } + + /** + * Sets the size in bytes. + * + * @param integer $sizeInBytes The size in bytes. + * + * @return none + */ + public function setSizeInBytes($sizeInBytes) + { + $this->_queueDescription->setSizeInBytes($sizeInBytes); + } + + /** + * Gets the message count. + * + * @return integer + */ + public function getMessageCount() + { + return $this->_queueDescription->getMessageCount(); + } + + /** + * Sets the message count. + * + * @param string $messageCount The count of the message. + * + * @return none + */ + public function setMessageCount($messageCount) + { + $this->_queueDescription->setMessageCount($messageCount); + } +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/ReceiveMessageOptions.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/ReceiveMessageOptions.php new file mode 100644 index 0000000..8afce67 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/ReceiveMessageOptions.php @@ -0,0 +1,148 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ +namespace WindowsAzure\ServiceBus\Models; + +use WindowsAzure\ServiceBus\Models\ReceiveMode; + +/** + * The options for a receive message request. + * + * @category Microsoft + * @package WindowsAzure\ServiceBus\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +class ReceiveMessageOptions +{ + /** + * The timeout value of receiving message. + * + * @var integer + */ + private $_timeout; + + /** + * The mode of receiving message. + * + * @var integer + */ + private $_receiveMode; + + /** + * Creates a receive message option instance with default parameters. + */ + public function __construct() + { + $this->_receiveMode = ReceiveMode::RECEIVE_AND_DELETE; + } + /** + * Gets the timeout of the receive message request. + * + * @return integer + */ + public function getTimeout() + { + return $this->_timeout; + } + + /** + * Sets the timeout of the receive message request. + * + * @param integer $timeout The timeout of the receive message request. + * + * @return none + */ + public function setTimeout($timeout) + { + $this->_timeout = $timeout; + } + + /** + * Gets the receive mode. + * + * @return integer + */ + public function getReceiveMode() + { + return $this->_receiveMode; + } + + /** + * Sets the receive mode. + * + * @param integer $receiveMode The mode of receiving the message. + * + * @return none + */ + public function setReceiveMode($receiveMode) + { + $this->_receiveMode = $receiveMode; + } + + /** + * Gets is receive and delete. + * + * @return boolean + */ + public function getIsReceiveAndDelete() + { + return ($this->_receiveMode === ReceiveMode::RECEIVE_AND_DELETE); + } + + /** + * Sets whether the mode of receiving is receive and delete. + * + * @return none + */ + public function setReceiveAndDelete() + { + $this->_receiveMode = ReceiveMode::RECEIVE_AND_DELETE; + } + + /** + * Gets peek lock. + * + * @return boolean + * + */ + public function getIsPeekLock() + { + return ($this->_receiveMode === ReceiveMode::PEEK_LOCK); + } + + /** + * Sets peek lock. + * + * @return none + */ + public function setPeekLock() + { + $this->_receiveMode = ReceiveMode::PEEK_LOCK; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/ReceiveMode.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/ReceiveMode.php new file mode 100644 index 0000000..a98b1b3 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/ReceiveMode.php @@ -0,0 +1,43 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ +namespace WindowsAzure\ServiceBus\Models; + +/** + * The mode of receiving message from Service Bus. + * + * @category Microsoft + * @package WindowsAzure\ServiceBus\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +class ReceiveMode +{ + const RECEIVE_AND_DELETE = 0; + const PEEK_LOCK = 1; +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/RuleDescription.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/RuleDescription.php new file mode 100644 index 0000000..b702bd7 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/RuleDescription.php @@ -0,0 +1,240 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceBus\Models; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\ServiceBus\Internal\Action; +use WindowsAzure\ServiceBus\Internal\Filter; +/** + * The description of the rule. + * + * @category Microsoft + * @package WindowsAzure\ServiceBus\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link http://msdn.microsoft.com/en-us/library/windowsazure/hh780753 + */ + +class RuleDescription +{ + /** + * The filter of the rule. + * + * @var Filter + */ + private $_filter; + + /** + * The action of the rule. + * + * @var Action + */ + private $_action; + + /** + * The name of the rule. + * + * @var string + */ + private $_name; + + + /** + * Creates a rule description instance with default parameters. + */ + public function __construct() + { + } + + // @codingStandardsIgnoreStart + + /** + * Creates a rule description instance with specified XML string. + * + * @param string $ruleDescriptionXml A XML string representing the + * rule description. + * + * @return none + */ + public static function create($ruleDescriptionXml) + { + $ruleDescription = new RuleDescription(); + $root = simplexml_load_string( + $ruleDescriptionXml + ); + $nameSpaces = $root->getNameSpaces(); + $ruleDescriptionArray = (array)$root; + if (array_key_exists('Filter', $ruleDescriptionArray)) { + $filterItem = $ruleDescriptionArray['Filter']; + $filterAttributes = $filterItem->attributes('i', true); + $filterItemArray = (array)$filterItem; + $filterType = (string)$filterAttributes['type']; + $filter = null; + switch ($filterType) { + case 'TrueFilter' : + $filter = new TrueFilter(); + break; + + case 'FalseFilter' : + $filter = new FalseFilter(); + break; + + case 'CorrelationFilter' : + $filter = new CorrelationFilter(); + + if (array_key_exists('CorrelationId', $filterItemArray)) { + $filter->setCorrelationId( + (string)$filterItemArray['CorrelationId'] + ); + } + break; + + case 'SqlFilter' : + $filter = new SqlFilter(); + + if (array_key_exists('SqlExpression', $filterItemArray)) { + $filter->setSqlExpression( + (string)$filterItemArray['SqlExpression'] + ); + } + if (array_key_exists('CompatibilityLevel', $filterItemArray)) { + $filter->setCompatibilityLevel( + (integer)$filterItemArray['CompatibilityLevel'] + ); + } + + break; + + default : + $filter = new Filter(); + } + + $ruleDescription->setFilter($filter); + } + + if (array_key_exists('Action', $ruleDescriptionArray)) { + $actionItem = $ruleDescriptionArray['Action']; + $actionAttributes = $actionItem->attributes('i', true); + $actionType = (string)$actionAttributes['type']; + $action = null; + + switch ($actionType) { + case 'EmptyRuleAction' : + $action = new EmptyRuleAction(); + break; + + case 'SqlRuleAction' : + $action = new SqlRuleAction(); + + if (array_key_exists('SqlExpression', $actionItem)) { + $action->setSqlExpression((string)$actionItem['SqlExpression']); + } + break; + + default : + $action = new Action(); + } + + $ruleDescription->setAction($action); + } + + if (array_key_exists('Name', $ruleDescriptionArray)) { + $ruleDescription->setName((string)$ruleDescriptionArray['Name']); + } + + return $ruleDescription; + } + + // @codingStandardsIgnoreEnd + + /** + * Gets the filter. + * + * @return Filter + */ + public function getFilter() + { + return $this->_filter; + } + + /** + * Sets the filter of the rule description. + * + * @param Filter $filter The filter of the rule description. + * + * @return none + */ + public function setFilter($filter) + { + $this->_filter = $filter; + } + + /** + * Gets the action. + * + * @return Action + */ + public function getAction() + { + return $this->_action; + + } + + /** + * Sets the action of the rule description. + * + * @param Action $action The action of the rule description. + * + * @return none + */ + public function setAction($action) + { + $this->_action = $action; + } + + /** + * Gets the name of the rule description. + * + * @return string + */ + public function getName() + { + return $this->_name; + } + + /** + * Sets the name of the rule description. + * + * @param string $name The name of the rule description. + * + * @return none + */ + public function setName($name) + { + $this->_name = $name; + } + +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/RuleInfo.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/RuleInfo.php new file mode 100644 index 0000000..39b9840 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/RuleInfo.php @@ -0,0 +1,337 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceBus\Models; +use WindowsAzure\Common\Internal\Atom\Content; +use WindowsAzure\Common\Internal\Atom\Entry; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Validate; +use WindowsAzure\Common\Internal\Serialization\XmlSerializer; + +/** + * The information of a rule. + * + * @category Microsoft + * @package WindowsAzure\ServiceBus\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +class RuleInfo +{ + /** + * The entry of the rule info. + * + * @var Entry + */ + private $_entry; + + /** + * The description of the rule. + * + * @var RuleDescription + */ + private $_ruleDescription; + + /** + * Creates an RuleInfo with specified parameters. + * + * @param string $title The title of the rule. + * @param RuleDescription $ruleDescription The description of the rule. + */ + public function __construct( + $title = Resources::EMPTY_STRING, + $ruleDescription = null + ) { + Validate::isString($title, 'title'); + + if (is_null($ruleDescription)) { + $ruleDescription = new RuleDescription(); + } + $this->_ruleDescription = $ruleDescription; + $this->_entry = new Entry(); + $this->_entry->setTitle($title); + $this->_entry->setAttribute( + Resources::XMLNS, + Resources::SERVICE_BUS_NAMESPACE + ); + + } + + /** + * Populates the properties with a specified XML string based on ATOM + * ENTRY schema. + * + * @param string $xmlString An XML string representing a rule info instance. + * + * @return none + */ + public function parseXml($xmlString) + { + $this->_entry->parseXml($xmlString); + $content = $this->_entry->getContent(); + if (is_null($content)) { + $this->_ruleDescription = null; + } else { + $this->_ruleDescription = RuleDescription::create($content->getText()); + } + } + + /** + * Writes an XML string representing the rule info instance. + * + * @param XMLWriter $xmlWriter The XML writer. + * + * @return none + */ + public function writeXml($xmlWriter) + { + $content = null; + if (!is_null($this->_ruleDescription)) { + $content = new Content(); + $content->setText( + XmlSerializer::objectSerialize( + $this->_ruleDescription, 'RuleDescription' + ) + ); + } + $this->_entry->setContent($content); + $this->_entry->writeXml($xmlWriter); + } + + /** + * Gets the entry. + * + * @return Entry + */ + public function getEntry() + { + return $this->_entry; + } + + /** + * Sets the entry. + * + * @param Entry $entry The entry of the queue info. + * + * @return none + */ + public function setEntry($entry) + { + $this->_entry = $entry; + } + + /** + * Gets the title. + * + * @return string + */ + public function getTitle() + { + return $this->_entry->getTitle(); + } + + /** + * Sets the title. + * + * @param string $title The title of the rule info. + * + * @return none + */ + public function setTitle($title) + { + $this->_entry->setTitle($title); + } + + /** + * Gets the filter. + * + * @return Filter + */ + public function getFilter() + { + return $this->_ruleDescription->getFilter(); + } + + /** + * Sets the filter. + * + * @param Filter $filter The filter. + * + * @return none + */ + public function setFilter($filter) + { + $this->_ruleDescription->setFilter($filter); + } + + /** + * Gets the action. + * + * @return Action + */ + public function getAction() + { + return $this->_ruleDescription->getAction(); + } + + /** + * Sets the action. + * + * @param Action $action The action. + * + * @return none + */ + public function setAction($action) + { + $this->_ruleDescription->setAction($action); + } + + /** + * Gets the description of the rule. + * + * @return RuleDescription + */ + public function getRuleDescription() + { + return $this->_ruleDescription; + } + + /** + * Sets the rule description. + * + * @param RuleDescription $ruleDescription The description of the rule. + * + * @return none + */ + public function setRuleDescription($ruleDescription) + { + $this->_ruleDescription = $ruleDescription; + } + + /** + * With correlation ID filter. + * + * @param string $correlationId The ID of the correlation. + * + * @return none + */ + public function withCorrelationFilter($correlationId) + { + $filter = new CorrelationFilter(); + $filter->setCorrelationId($correlationId); + $this->_ruleDescription->setFilter($filter); + } + + /** + * With sql expression filter. + * + * @param string $sqlExpression The SQL expression of the filter. + * + * @return none + */ + public function withSqlFilter($sqlExpression) + { + $filter = new SqlFilter(); + $filter->setSqlExpression($sqlExpression); + $filter->setCompatibilityLevel(20); + $this->_ruleDescription->setFilter($filter); + } + + /** + * With true filter. + * + * @return none + */ + public function withTrueFilter() + { + $filter = new TrueFilter(); + $this->_ruleDescription->setFilter($filter); + } + + /** + * With false filter. + * + * @return none + */ + public function withFalseFilter() + { + $filter = new FalseFilter(); + $this->_ruleDescription->setFilter($filter); + } + + /** + * With empty rule action. + * + * @return none + */ + public function withEmptyRuleAction() + { + $action = new EmptyRuleAction(); + $this->_ruleDescription->setAction($action); + } + + /** + * With SQL rule action. + * + * @param string $sqlExpression The SQL expression + * of the rule action. + * + * @return none + */ + public function withSqlRuleAction($sqlExpression) + { + $action = new SqlRuleAction(); + $action->setCompatibilityLevel(20); + $action->setSqlExpression($sqlExpression); + $this->_ruleDescription->setAction($action); + } + + /** + * Gets the name of the rule description. + * + * @return string + */ + public function getName() + { + return $this->_ruleDescription->getName(); + } + + /** + * Sets the name of the rule description. + * + * @param string $name The name of the rule description. + * + * @return none + */ + public function setName($name) + { + $this->_ruleDescription->setName($name); + } + +} diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/SqlFilter.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/SqlFilter.php new file mode 100644 index 0000000..4ced56a --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/SqlFilter.php @@ -0,0 +1,115 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceBus\Models; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Validate; +use WindowsAzure\ServiceBus\Internal\Filter; + +/** + * The SQL filter. + * + * @category Microsoft + * @package WindowsAzure\ServiceBus\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +class SqlFilter extends Filter +{ + /** + * The SQL expression of the filter. + * + * @var string + */ + private $_sqlExpression; + + /** + * The compatibility level of the filter. + * + * @var string + */ + private $_compatibilityLevel; + + + /** + * Creates a SQL filter with default parameters. + */ + public function __construct() + { + parent::__construct(); + $this->attributes['xsi:type'] = 'SqlFilter'; + } + /** + * Gets the SQL expression. + * + * @var string + * + * @return none + */ + public function getSqlExpression() + { + return $this->_sqlExpression; + } + + /** + * Sets the SQL expression. + * + * @param string $sqlExpression The SQL expression of the filter. + * + * @return none + */ + public function setSqlExpression($sqlExpression) + { + $this->_sqlExpression = $sqlExpression; + } + + /** + * Gets the compatibility level. + * + * @return string + */ + public function getCompatibilityLevel() + { + return $this->_compatibilityLevel; + } + + /** + * Sets the compatibility level. + * + * @param string $compatibilityLevel The compatibility level. + * + * @return none + */ + public function setCompatibilityLevel($compatibilityLevel) + { + $this->_compatibilityLevel = $compatibilityLevel; + } + +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/SqlRuleAction.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/SqlRuleAction.php new file mode 100644 index 0000000..5856185 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/SqlRuleAction.php @@ -0,0 +1,112 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceBus\Models; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Validate; +use WindowsAzure\ServiceBus\Internal\Action; + +/** + * The SQL rule action. + * + * @category Microsoft + * @package WindowsAzure\ServiceBus\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +class SqlRuleAction extends Action +{ + /** + * The SQL expression. + * + * @var string + */ + private $_sqlExpression; + + /** + * The compatibility level. + * + * @var string + */ + private $_compatibilityLevel; + + /** + * Creates a SQL Rule Action instance with default parameters. + */ + public function __construct() + { + parent::__construct(); + $this->attributes['xsi:type'] = 'SqlRuleAction'; + } + + /** + * Gets the SQL expression. + * + * @return string + */ + public function getSqlExpression() + { + return $this->_sqlExpression; + } + + /** + * Sets the SQL expression. + * + * @param string $sqlExpression Sets the SQL expression. + * + * @return none + */ + public function setSqlExpression($sqlExpression) + { + $this->_sqlExpression = $sqlExpression; + } + + /** + * Gets the compatibility level. + * + * @return string + */ + public function getCompatibilityLevel() + { + return $this->_compatibilityLevel; + } + + /** + * Sets the compatibility level. + * + * @param string $compatibilityLevel The level of compatibility. + * + * @return none + */ + public function setCompatibilityLevel($compatibilityLevel) + { + $this->_compatibilityLevel = $compatibilityLevel; + } + +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/SubscriptionDescription.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/SubscriptionDescription.php new file mode 100644 index 0000000..1f29b4c --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/SubscriptionDescription.php @@ -0,0 +1,414 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceBus\Models; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Utilities; + +/** + * The subscription description. + * + * @category Microsoft + * @package WindowsAzure\ServiceBus\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link http://msdn.microsoft.com/en-us/library/windowsazure/hh780763 + */ + +class SubscriptionDescription +{ + /** + * The duration of the lock. + * + * @var string + */ + private $_lockDuration; + + /** + * Requires session. + * + * @var boolean + */ + private $_requiresSession; + + /** + * The default message time to live. + * + * @var string + */ + private $_defaultMessageTimeToLive; + + /** + * The dead lettering on message expiration. + * + * @var string + */ + private $_deadLetteringOnMessageExpiration; + + /** + * The dead lettering on filter evaluation exception. + * + * @var string + */ + private $_deadLetteringOnFilterEvaluationExceptions; + + /** + * The description of the default rule. + * + * @var string + */ + private $_defaultRuleDescription; + + /** + * The count of the message. + * + * @var integer + */ + private $_messageCount; + + /** + * The count of the delivery + * + * @var integer + */ + private $_maxDeliveryCount; + + /** + * Enables Batched operations. + * + * @var boolean + */ + private $_enableBatchedOperations; + + /** + * Creates a subscription description instance with default + * parameter. + */ + public function __construct() + { + } + + /** + * Creates a subscription description with specified XML string. + * + * @param string $subscriptionDescriptionXml An XML based subscription + * description. + * + * @return none + */ + public static function create($subscriptionDescriptionXml) + { + $subscriptionDescription = new SubscriptionDescription(); + $root = simplexml_load_string( + $subscriptionDescriptionXml + ); + $subscriptionDescriptionArray = (array)$root; + if (array_key_exists('LockDuration', $subscriptionDescriptionArray)) { + $subscriptionDescription->setLockDuration( + (string)$subscriptionDescriptionArray['LockDuration'] + ); + } + + if (array_key_exists('RequiresSession', $subscriptionDescriptionArray)) { + $subscriptionDescription->setRequiresSession( + (boolean)$subscriptionDescriptionArray['RequiresSession'] + ); + } + + if (array_key_exists( + 'DefaultMessageTimeToLive', + $subscriptionDescriptionArray + ) + ) { + $subscriptionDescription->setDefaultMessageTimeToLive( + (string)$subscriptionDescriptionArray['DefaultMessageTimeToLive'] + ); + } + + if (array_key_exists( + 'DeadLetteringOnMessageExpiration', + $subscriptionDescriptionArray + ) + ) { + $subscriptionDescription->setDeadLetteringOnMessageExpiration( + (string)$subscriptionDescriptionArray[ + 'DeadLetteringOnMessageExpiration' + ] + ); + } + + if (array_key_exists( + 'DeadLetteringOnFilterEvaluationException', + $subscriptionDescriptionArray + ) + ) { + $subscriptionDescription->setDeadLetteringOnFilterEvaluationException( + (string)$subscriptionDescriptionArray[ + 'DeadLetteringOnFilterEvaluationException' + ] + ); + } + + if (array_key_exists( + 'DefaultRuleDescription', + $subscriptionDescriptionArray + ) + ) { + $subscriptionDescription->setDefaultRuleDescription( + (string)$subscriptionDescriptionArray['DefaultRuleDescription'] + ); + } + + if (array_key_exists('MessageCount', $subscriptionDescriptionArray)) { + $subscriptionDescription->setMessageCount( + (string)$subscriptionDescriptionArray['MessageCount'] + ); + } + + if (array_key_exists('MaxDeliveryCount', $subscriptionDescriptionArray)) { + $subscriptionDescription->setMaxDeliveryCount( + (string)$subscriptionDescriptionArray['MaxDeliveryCount'] + ); + } + + if (array_key_exists( + 'EnableBatchedOperations', + $subscriptionDescriptionArray + ) + ) { + $subscriptionDescription->setEnableBatchedOperations( + (boolean)$subscriptionDescriptionArray['EnableBatchedOperations'] + ); + } + + return $subscriptionDescription; + } + + /** + * Gets the lock duration. + * + * @return integer + */ + public function getLockDuration() + { + return $this->_lockDuration; + } + + /** + * Sets the lock duration. + * + * @param string $lockDuration The duration of the lock. + * + * @return none + */ + public function setLockDuration($lockDuration) + { + $this->_lockDuration = $lockDuration; + } + + /** + * Gets requires session. + * + * @return boolean + */ + public function getRequiresSession() + { + return $this->_requiresSession; + } + + /** + * Sets the requires session. + * + * @param boolean $requiresSession The requires session. + * + * @return none + */ + public function setRequiresSession($requiresSession) + { + $this->_requiresSession = $requiresSession; + } + + /** + * Gets default message time to live. + * + * @return string + */ + public function getDefaultMessageTimeToLive() + { + return $this->_defaultMessageTimeToLive; + } + + /** + * Sets default message time to live. + * + * @param string $defaultMessageTimeToLive The default message time to live. + * + * @return none + */ + public function setDefaultMessageTimeToLive($defaultMessageTimeToLive) + { + $this->_defaultMessageTimeToLive = $defaultMessageTimeToLive; + } + + /** + * Gets dead lettering on message expiration. + * + * @return string + */ + public function getDeadLetteringOnMessageExpiration() + { + return $this->_deadLetteringOnMessageExpiration; + } + + /** + * Sets dead lettering on message expiration. + * + * @param string $deadLetteringOnMessageExpiration The dead lettering + * on message expiration. + * + * @return none + */ + public function setDeadLetteringOnMessageExpiration( + $deadLetteringOnMessageExpiration + ) { + $this->_deadLetteringOnMessageExpiration = $deadLetteringOnMessageExpiration; + } + + /** + * Gets dead lettering on filter evaluation exceptions. + * + * @return string + */ + public function getDeadLetteringOnFilterEvaluationExceptions() + { + return $this->_deadLetteringOnFilterEvaluationExceptions; + } + + /** + * Sets dead lettering on filter evaluation exceptions. + * + * @param string $deadLetteringOnFilterEvaluationExceptions Sets dead lettering + * on filter evaluation exceptions. + * + * @return none + */ + public function setDeadLetteringOnFilterEvaluationExceptions( + $deadLetteringOnFilterEvaluationExceptions + ) { + $value = $deadLetteringOnFilterEvaluationExceptions; + + $this->_deadLetteringOnFilterEvaluationExceptions = $value; + } + + /** + * Gets the default rule description. + * + * @return RuleDescription + */ + public function getDefaultRuleDescription() + { + return $this->_defaultRuleDescription; + } + + /** + * Sets the default rule description. + * + * @param string $defaultRuleDescription The default rule description. + * + * @return none + */ + public function setDefaultRuleDescription($defaultRuleDescription) + { + $this->_defaultRuleDescription = $defaultRuleDescription; + } + + /** + * Gets the count of the message. + * + * @return integer + */ + public function getMessageCount() + { + return $this->_messageCount; + } + + /** + * Sets the count of the message. + * + * @param string $messageCount The count of the message. + * + * @return none + */ + public function setMessageCount($messageCount) + { + $this->_messageCount = $messageCount; + } + + /** + * Gets maximum delivery count. + * + * @return integer + */ + public function getMaxDeliveryCount() + { + return $this->_maxDeliveryCount; + } + + /** + * Sets maximum delivery count. + * + * @param integer $maxDeliveryCount The maximum delivery count. + * + * @return none + */ + public function setMaxDeliveryCount($maxDeliveryCount) + { + $this->_maxDeliveryCount = $maxDeliveryCount; + } + + /** + * Gets enable batched operations. + * + * @return boolean + */ + public function getEnableBatchedOperations() + { + return $this->_enableBatchedOperations; + } + + /** + * Sets enable batched operations. + * + * @param boolean $enableBatchedOperations Enable batched operations. + * + * @return none + */ + public function setEnableBatchedOperations($enableBatchedOperations) + { + $this->_enableBatchedOperations = $enableBatchedOperations; + } +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/SubscriptionInfo.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/SubscriptionInfo.php new file mode 100644 index 0000000..df2d5b4 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/SubscriptionInfo.php @@ -0,0 +1,412 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceBus\Models; + +use WindowsAzure\Common\Internal\Atom\Entry; +use WindowsAzure\Common\Internal\Atom\Content; +use WindowsAzure\Common\Internal\Serialization\XmlSerializer; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Validate; +use WindowsAzure\ServiceBus\Models\SubscriptionDescription; + +/** + * The information of a subscription. + * + * @category Microsoft + * @package WindowsAzure\ServiceBus\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ +class SubscriptionInfo extends Entry +{ + /** + * The entry of the subscription info. + * + * @var Entry + */ + private $_entry; + + /** + * The description of the subscription. + * + * @var SubscriptionDescription + */ + private $_subscriptionDescription; + + /** + * Creates a SubscriptionInfo instance with specified parameters. + * + * @param string $title The title of + * the subscription. + * @param SubscriptionDescription $subscriptionDescription The description + * of the subscription. + */ + public function __construct( + $title = Resources::EMPTY_STRING, + $subscriptionDescription = null + ) { + Validate::isString($title, 'title'); + if (is_null($subscriptionDescription)) { + $subscriptionDescription = new SubscriptionDescription(); + } + $this->_subscriptionDescription = $subscriptionDescription; + $this->_entry = new Entry(); + $this->_entry->setTitle($title); + $this->_entry->setAttribute( + Resources::XMLNS, + Resources::SERVICE_BUS_NAMESPACE + ); + } + + /** + * Populates the properties of the subscription info instance with a XML string. + * + * @param string $entryXml A XML string representing a subscription + * information instance. + * + * @return none + */ + public function parseXml($entryXml) + { + $this->_entry->parseXml($entryXml); + $content = $this->_entry->getContent(); + if (is_null($content)) { + $this->_subscriptionDescription = null; + } else { + $this->_subscriptionDescription = SubscriptionDescription::create( + $content->getText() + ); + } + } + + /** + * Writes XML based on the subscription information. + * + * @param XMLWriter $xmlWriter The XML writer. + * + * @return none + */ + public function writeXml($xmlWriter) + { + $content = null; + if (!is_null($this->_subscriptionDescription)) { + $content = new Content(); + $content->setText( + XmlSerializer::objectSerialize( + $this->_subscriptionDescription, + 'SubscriptionDescription' + ) + ); + } + $this->_entry->setContent($content); + $this->_entry->writeXml($xmlWriter); + } + + /** + * Gets the entry of the subscription info. + * + * @return Entry + */ + public function getEntry() + { + return $this->_entry; + } + + /** + * Sets the entry of the subscription info. + * + * @param Entry $entry The entry of the subscription info. + * + * @return none + */ + public function setEntry($entry) + { + $this->_entry = $entry; + } + + /** + * Gets the title. + * + * @return string + */ + public function getTitle() + { + return $this->_entry->getTitle(); + } + + /** + * Sets the title. + * + * @param string $title The title of the queue info. + * + * @return none + */ + public function setTitle($title) + { + $this->_entry->setTitle($title); + } + + /** + * Gets the subscription description. + * + * @return none + */ + public function getSubscriptionDescription() + { + return $this->_subscriptionDescription; + } + + /** + * Sets the subscription description. + * + * @param string $subscriptionDescription The description of + * the subscription. + * + * @return none + */ + public function setSubscriptionDescription($subscriptionDescription) + { + $this->_subscriptionDescription = $subscriptionDescription; + } + + /** + * Gets the lock duration. + * + * @return integer + */ + public function getLockDuration() + { + return $this->_subscriptionDescription->getLockDuration(); + } + + /** + * Sets the lock duration. + * + * @param string $lockDuration The duration of the lock. + * + * @return none + */ + public function setLockDuration($lockDuration) + { + $this->_subscriptionDescription->setlockDuration($lockDuration); + } + + /** + * Gets requires session. + * + * @return boolean + */ + public function getRequiresSession() + { + return $this->_subscriptionDescription->getRequiresSession(); + } + + /** + * Sets the requires session. + * + * @param boolean $requiresSession The requires session. + * + * @return none + */ + public function setRequiresSession($requiresSession) + { + $this->_subscriptionDescription->setRequiresSession($requiresSession); + } + + /** + * Gets default message time to live. + * + * @return string + */ + public function getDefaultMessageTimeToLive() + { + return $this->_subscriptionDescription->getDefaultMessageTimeToLive(); + } + + /** + * Sets default message time to live. + * + * @param string $defaultMessageTimeToLive The default message time to live. + * + * @return none + */ + public function setDefaultMessageTimeToLive($defaultMessageTimeToLive) + { + $this->_subscriptionDescription->setDefaultMessageTimeToLive( + $defaultMessageTimeToLive + ); + } + + /** + * Gets dead lettering on message expiration. + * + * @return string + */ + public function getDeadLetteringOnMessageExpiration() + { + $subscriptionDesc = $this->_subscriptionDescription; + return $subscriptionDesc->getDeadLetteringOnMessageExpiration(); + } + + /** + * Sets dead lettering on message expiration. + * + * @param string $deadLetteringOnMessageExpiration The dead lettering + * on message expiration. + * + * @return none + */ + public function setDeadLetteringOnMessageExpiration( + $deadLetteringOnMessageExpiration + ) { + $this->_subscriptionDescription->setDeadLetteringOnMessageExpiration( + $deadLetteringOnMessageExpiration + ); + } + + /** + * Gets dead lettering on filter evaluation exceptions. + * + * @return string + */ + public function getDeadLetteringOnFilterEvaluationExceptions() + { + $subscriptionDesc = $this->_subscriptionDescription; + return $subscriptionDesc->getDeadLetteringOnFilterEvaluationExceptions(); + } + + /** + * Sets dead lettering on filter evaluation exceptions. + * + * @param string $deadLetteringOnFilterEvaluationExceptions Sets dead lettering + * on filter evaluation exceptions. + * + * @return none + */ + public function setDeadLetteringOnFilterEvaluationExceptions( + $deadLetteringOnFilterEvaluationExceptions + ) { + $subscriptionDesc = $this->_subscriptionDescription; + $subscriptionDesc->setdeadLetteringOnFilterEvaluationExceptions( + $deadLetteringOnFilterEvaluationExceptions + ); + } + + /** + * Gets the default rule description. + * + * @return RuleDescription + */ + public function getDefaultRuleDescription() + { + return $this->_subscriptionDescription->getDefaultRuleDescription(); + } + + /** + * Sets the default rule description. + * + * @param string $defaultRuleDescription The default rule description. + * + * @return none + */ + public function setDefaultRuleDescription($defaultRuleDescription) + { + $this->_subscriptionDescription->setDefaultRuleDescription( + $defaultRuleDescription + ); + } + + /** + * Gets the count of the message. + * + * @return integer + */ + public function getMessageCount() + { + return $this->_subscriptionDescription->getMessageCount(); + } + + /** + * Sets the count of the message. + * + * @param string $messageCount The count of the message. + * + * @return none + */ + public function setMessageCount($messageCount) + { + $this->_subscriptionDescription->setMessageCount($messageCount); + } + + /** + * Gets maximum delivery count. + * + * @return integer + */ + public function getMaxDeliveryCount() + { + return $this->_subscriptionDescription->getMaxDeliveryCount(); + } + + /** + * Sets maximum delivery count. + * + * @param integer $maxDeliveryCount The maximum delivery count. + * + * @return none + */ + public function setMaxDeliveryCount($maxDeliveryCount) + { + $this->_subscriptionDescription->setmaxDeliveryCount($maxDeliveryCount); + } + + /** + * Gets enable batched operations. + * + * @return boolean + */ + public function getEnableBatchedOperations() + { + return $this->_subscriptionDescription->getEnableBatchedOperations(); + } + + /** + * Sets enable batched operations. + * + * @param boolean $enableBatchedOperations Enable batched operations. + * + * @return none + */ + public function setEnableBatchedOperations($enableBatchedOperations) + { + $this->_subscriptionDescription->setEnableBatchedOperations( + $enableBatchedOperations + ); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/TopicDescription.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/TopicDescription.php new file mode 100644 index 0000000..1e167e1 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/TopicDescription.php @@ -0,0 +1,286 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceBus\Models; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Utilities; + +/** + * The description of the topic. + * + * @category Microsoft + * @package WindowsAzure\ServiceBus\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link http://msdn.microsoft.com/en-us/library/windowsazure/hh780749 + */ +class TopicDescription +{ + /** + * The default message time to live. + * + * @var string + */ + private $_defaultMessageTimeToLive; + + /** + * The maxizmu size in mega bytes. + * + * @integer + */ + private $_maxSizeInMegabytes; + + /** + * Requires duplicate detection. + * + * @var boolean + */ + private $_requiresDuplicateDetection; + + /** + * Duplicate detection history time window. + * + * @var string + */ + private $_duplicateDetectionHistoryTimeWindow; + + /** + * Enables batched operations. + * + * @var boolean + */ + private $_enableBatchedOperations; + + /** + * The size in bytes. + * + * @var integer + */ + private $_sizeInBytes; + + /** + * Creates a topic description with default parameters. + */ + public function __construct() + { + } + + /** + * Creates a topic description object with specified XML string. + * + * @param string $topicDescriptionXml A XML based string describing + * the topic. + * + * @return TopicDescription + */ + public static function create($topicDescriptionXml) + { + $topicDescription = new TopicDescription(); + $root = simplexml_load_string($topicDescriptionXml); + $topicDescriptionArray = (array)$root; + + if (array_key_exists('DefaultMessageToLive', $topicDescriptionArray)) { + $topicDescription->setDefaultMessageToLive( + (string)$topicDescriptionArray['DefaultMessageToLive'] + ); + } + + if (array_key_exists('MaxSizeInMegabytes', $topicDescriptionArray)) { + $topicDescription->setMaxSizeInMegabytes( + (integer)$topicDescriptionArray['MaxSizeInMegabytes'] + ); + } + + if (array_key_exists( + 'RequiresDuplicateDetection', + $topicDescriptionArray + ) + ) { + $topicDescription->setRequiresDuplicateDetection( + (boolean)$topicDescriptionArray['RequiresDuplicateDetection'] + ); + } + + if (array_key_exists( + 'DuplicateDetectionHistoryTimeWindow', + $topicDescriptionArray + ) + ) { + $topicDescription->setDuplicateDetectionHistoryTimeWindow( + (string)$topicDescriptionArray['DuplicateDetectionHistoryTimeWindow'] + ); + } + + if (array_key_exists( + 'EnableBatchedOperations', + $topicDescriptionArray + )) { + $topicDescription->setEnableBatchedOperations( + (boolean)$topicDescriptionArray['EnableBatchedOperations'] + ); + } + + return $topicDescription; + } + + /** + * Gets default message time to live. + * + * @return string + */ + public function getDefaultMessageTimeToLive() + { + return $this->_defaultMessageTimeToLive; + } + + /** + * Sets the default message to live. + * + * @param string $defaultMessageTimeToLive The default message time to live. + * + * @return none + */ + public function setDefaultMessageTimeToLive($defaultMessageTimeToLive) + { + $this->_defaultMessageTimeToLive = $defaultMessageTimeToLive; + } + + /** + * Gets the msax size in mega bytes. + * + * @return integer + */ + public function getMaxSizeInMegabytes() + { + return $this->_maxSizeInMegabytes; + } + + /** + * Sets max size in mega bytes. + * + * @param integer $maxSizeInMegabytes The maximum size in mega bytes. + * + * @return none + */ + public function setMaxSizeInMegabytes($maxSizeInMegabytes) + { + $this->_maxSizeInMegabytes = $maxSizeInMegabytes; + } + + /** + * Gets requires duplicate detection. + * + * @return boolean + */ + public function getRequiresDuplicateDetection() + { + return $this->_requiresDuplicateDetection; + } + + /** + * Sets requires duplicate detection. + * + * @param boolean $requiresDuplicateDetection Sets requires duplicate detection. + * + * @return none + */ + public function setRequiresDuplicateDetection($requiresDuplicateDetection) + { + $this->_requiresDuplicateDetection = $requiresDuplicateDetection; + } + + /** + * Gets duplicate detection history time window. + * + * @return string + */ + public function getDuplicateDetectionHistoryTimeWindow() + { + return $this->_duplicateDetectionHistoryTimeWindow; + } + + /** + * Sets duplicate detection history time window. + * + * @param string $duplicateDetectionHistoryTimeWindow The duplicate + * detection history time window. + * + * @return none + */ + public function setDuplicateDetectionHistoryTimeWindow( + $duplicateDetectionHistoryTimeWindow + ) { + $value = $duplicateDetectionHistoryTimeWindow; + + $this->_duplicateDetectionHistoryTimeWindow = $value; + } + + /** + * Gets enable batched operations. + * + * @return boolean + */ + public function getEnableBatchedOperations() + { + return $this->_enableBatchedOperations; + } + + /** + * Sets enable batched operations. + * + * @param boolean $enableBatchedOperations Enables batched operations. + * + * @return none + */ + public function setEnableBatchedOperations($enableBatchedOperations) + { + $this->_enableBatchedOperations = $enableBatchedOperations; + } + + /** + * Gets size in bytes. + * + * @return integer + */ + public function getSizeInBytes() + { + return $this->_sizeInBytes; + } + + /** + * Sets size in bytes. + * + * @param integer $sizeInBytes The size in bytes. + * + * @return none + */ + public function setSizeInBytes($sizeInBytes) + { + $this->_sizeInBytes = $sizeInBytes; + } + +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/TopicInfo.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/TopicInfo.php new file mode 100644 index 0000000..802822f --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/TopicInfo.php @@ -0,0 +1,336 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceBus\Models; +use WindowsAzure\Common\Internal\Atom\Entry; +use WindowsAzure\Common\Internal\Atom\Content; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Serialization\XmlSerializer; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Validate; +use WindowsAzure\ServiceBus\Models\TopicDescription; + +/** + * The description of a topic. + * + * @category Microsoft + * @package WindowsAzure\ServiceBus\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ +class TopicInfo extends Entry +{ + /** + * The entry of the topic info. + * + * @var Entry + */ + private $_entry; + + /** + * The description of the topics. + * + * @var TopicDescription + */ + private $_topicDescription; + + /** + * Creates a TopicInfo with specified parameters. + * + * @param string $title The name of the topic. + * @param TopicDescription $topicDescription The description of the + * topic. + */ + public function __construct( + $title = Resources::EMPTY_STRING, + $topicDescription = null + ) { + Validate::isString($title, 'title'); + if (is_null($topicDescription)) { + $topicDescription = new TopicDescription(); + } + $this->title = $title; + $this->_topicDescription = $topicDescription; + $this->_entry = new Entry(); + $this->_entry->setTitle($title); + $this->_entry->setAttribute( + Resources::XMLNS, + Resources::SERVICE_BUS_NAMESPACE + ); + } + + /** + * Populates properties with a specified XML string. + * + * @param string $xmlString An XML string representing the topic information. + * + * @return none + */ + public function parseXml($xmlString) + { + $this->_entry->parseXml($xmlString); + $content = $this->_entry->getContent(); + if (is_null($content)) { + $this->_topicDescription = null; + } else { + $this->_topicDescription = TopicDescription::create($content->getText()); + } + } + + /** + * Writes an XML string. + * + * @param \XMLWriter $xmlWriter The XML writer. + * + * @return string + */ + public function writeXml($xmlWriter) + { + $content = null; + if (!is_null($this->_topicDescription)) { + $content = new Content(); + $content->setText( + XmlSerializer::objectSerialize( + $this->_topicDescription, + 'TopicDescription' + ) + ); + $content->setType(Resources::XML_CONTENT_TYPE); + } + $this->_entry->setContent($content); + $this->_entry->writeXml($xmlWriter); + } + + /** + * Gets the title. + * + * @return string + */ + public function getTitle() + { + return $this->_entry->getTitle(); + } + + /** + * Sets the title. + * + * @param string $title The title of the queue info. + * + * @return none + */ + public function setTitle($title) + { + $this->_entry->setTitle($title); + } + + /** + * Gets the entry. + * + * @return Entry + */ + public function getEntry() + { + return $this->_entry; + } + + /** + * Sets the entry. + * + * @param Entry $entry The entry of the queue info. + * + * @return none + */ + public function setEntry($entry) + { + $this->_entry = $entry; + } + + /** + * Gets the descriptions of the topic. + * + * @return TopicDescription + */ + public function getTopicDescription() + { + return $this->_topicDescription; + } + + /** + * Sets the descriptions of the topic. + * + * @param TopicDescription $topicDescription The description of the topic. + * + * @return none + */ + public function setTopicDescription($topicDescription) + { + $this->_topicDescription = $topicDescription; + } + + /** + * Gets default message time to live. + * + * @return string + */ + public function getDefaultMessageTimeToLive() + { + return $this->_topicDescription->getDefaultMessageTimeToLive(); + } + + /** + * Sets the default message to live. + * + * @param string $defaultMessageTimeToLive The default message time to live. + * + * @return none + */ + public function setDefaultMessageTimeToLive($defaultMessageTimeToLive) + { + $this->_topicDescription->setDefaultMessageTimeToLive( + $defaultMessageTimeToLive + ); + } + + /** + * Gets the msax size in mega bytes. + * + * @return integer + */ + public function getMaxSizeInMegabytes() + { + return $this->_topicDescription->getMaxSizeInMegabytes(); + } + + /** + * Sets max size in mega bytes. + * + * @param integer $maxSizeInMegabytes The maximum size in mega bytes. + * + * @return none + */ + public function setMaxSizeInMegabytes($maxSizeInMegabytes) + { + $this->_topicDescription->setmaxSizeInMegabytes($maxSizeInMegabytes); + } + + /** + * Gets requires duplicate detection. + * + * @return boolean + */ + public function getRequiresDuplicateDetection() + { + return $this->_topicDescription->getRequiresDuplicateDetection(); + } + + /** + * Sets requires duplicate detection. + * + * @param boolean $requiresDuplicateDetection Sets requires duplicate detection. + * + * @return none + */ + public function setRequiresDuplicateDetection($requiresDuplicateDetection) + { + $this->_topicDescription->setrequiresDuplicateDetection( + $requiresDuplicateDetection + ); + } + + /** + * Gets duplicate detection history time window. + * + * @return string + */ + public function getDuplicateDetectionHistoryTimeWindow() + { + return $this->_topicDescription->getDuplicateDetectionHistoryTimeWindow(); + } + + /** + * Sets duplicate detection history time window. + * + * @param string $duplicateDetectionHistoryTimeWindow The duplicate + * detection history time window. + * + * @return none + */ + public function setDuplicateDetectionHistoryTimeWindow( + $duplicateDetectionHistoryTimeWindow + ) { + $this->_topicDescription->setduplicateDetectionHistoryTimeWindow( + $duplicateDetectionHistoryTimeWindow + ); + } + + /** + * Gets enable batched operations. + * + * @return boolean + */ + public function getEnableBatchedOperations() + { + return $this->_topicDescription->getEnableBatchedOperations(); + } + + /** + * Sets enable batched operations. + * + * @param boolean $enableBatchedOperations Enables batched operations. + * + * @return none + */ + public function setEnableBatchedOperations($enableBatchedOperations) + { + $this->_topicDescription->setenableBatchedOperations( + $enableBatchedOperations + ); + } + + /** + * Gets size in bytes. + * + * @return integer + */ + public function getSizeInBytes() + { + return $this->_topicDescription->getSizeInBytes(); + } + + /** + * Sets size in bytes. + * + * @param integer $sizeInBytes The size in bytes. + * + * @return none + */ + public function setSizeInBytes($sizeInBytes) + { + $this->_topicDescription->setSizeInBytes($sizeInBytes); + } + +} diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/TrueFilter.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/TrueFilter.php new file mode 100644 index 0000000..3eb3b17 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/Models/TrueFilter.php @@ -0,0 +1,50 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ +namespace WindowsAzure\ServiceBus\Models; +use WindowsAzure\ServiceBus\Internal\Filter; + +/** + * The true filter. + * + * @category Microsoft + * @package WindowsAzure\ServiceBus\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +class TrueFilter extends Filter +{ + /** + * Creates a true filter with default parameter. + */ + public function __construct() + { + parent::__construct(); + $this->attributes['xsi:type'] = 'TrueFilter'; + } + +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/ServiceBusRestProxy.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/ServiceBusRestProxy.php new file mode 100644 index 0000000..fd22fb0 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceBus/ServiceBusRestProxy.php @@ -0,0 +1,916 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceBus; +use WindowsAzure\Common\Internal\ServiceRestProxy; +use WindowsAzure\Common\Internal\Http\HttpCallContext; +use WindowsAzure\Common\Internal\Serialization\XmlSerializer; +use WindowsAzure\Common\Internal\Atom\Content; +use WindowsAzure\Common\Internal\Atom\Entry; +use WindowsAzure\Common\Internal\Atom\Feed; +use WindowsAzure\Common\ServiceException; +use WindowsAzure\ServiceBus\Internal\IServiceBus; +use WindowsAzure\ServiceBus\Models\BrokeredMessage; +use WindowsAzure\ServiceBus\Models\BrokerProperties; +use WindowsAzure\ServiceBus\Models\ListQueuesOptions; +use WindowsAzure\ServiceBus\Models\ListQueuesResult; +use WindowsAzure\ServiceBus\Models\ListSubscriptionsOptions; +use WindowsAzure\ServiceBus\Models\ListSubscriptionsResult; +use WindowsAzure\ServiceBus\Models\ListTopicsOptions; +use WindowsAzure\ServiceBus\Models\ListTopicsResult; +use WindowsAzure\ServiceBus\Models\ListRulesOptions; +use WindowsAzure\ServiceBus\Models\ListRulesResult; +use WindowsAzure\ServiceBus\Models\ListOptions; +use WindowsAzure\ServiceBus\Models\QueueDescription; +use WindowsAzure\ServiceBus\Models\QueueInfo; +use WindowsAzure\ServiceBus\Models\ReceiveMessageOptions; +use WindowsAzure\ServiceBus\Models\RuleDescription; +use WindowsAzure\ServiceBus\Models\RuleInfo; +use WindowsAzure\ServiceBus\Models\SubscriptionDescription; +use WindowsAzure\ServiceBus\Models\SubscriptionInfo; +use WindowsAzure\ServiceBus\Models\TopicDescription; +use WindowsAzure\ServiceBus\Models\TopicInfo; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Validate; + +/** + * This class constructs HTTP requests and receive HTTP responses + * for Service Bus. + * + * @category Microsoft + * @package WindowsAzure\ServiceBus + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/WindowsAzure/azure-sdk-for-php + */ + +class ServiceBusRestProxy extends ServiceRestProxy implements IServiceBus +{ + /** + * Creates a ServiceBusRestProxy with specified parameter. + * + * @param IHttpClient $channel The channel to communicate. + * @param string $uri The URI of Service Bus service. + * @param ISerializer $dataSerializer The serializer of the Service Bus. + * + * @return none + */ + public function __construct($channel, $uri, $dataSerializer) + { + parent::__construct( + $channel, + $uri, + Resources::EMPTY_STRING, + $dataSerializer + ); + } + + /** + * Sends a brokered message. + * + * Queues: + * @link http://msdn.microsoft.com/en-us/library/windowsazure/hh780775 + * + * Topic Subscriptions: + * @link http://msdn.microsoft.com/en-us/library/windowsazure/hh780786 + * + * @param type $path The path to send message. + * @param type $brokeredMessage The brokered message. + * + * @return none + */ + public function sendMessage($path, $brokeredMessage) + { + $httpCallContext = new HttpCallContext(); + $httpCallContext->setMethod(Resources::HTTP_POST); + $httpCallContext->addStatusCode(Resources::STATUS_CREATED); + $httpCallContext->setPath($path); + $contentType = $brokeredMessage->getContentType(); + + if (!is_null($contentType)) { + $httpCallContext->addHeader( + Resources::CONTENT_TYPE, + $contentType + ); + } + + $brokerProperties = $brokeredMessage->getBrokerProperties(); + if (!is_null($brokerProperties)) { + $httpCallContext->addHeader( + Resources::BROKER_PROPERTIES, + $brokerProperties->toString() + ); + } + $customProperties = $brokeredMessage->getProperties(); + + if (!empty($customProperties)) { + foreach ($customProperties as $key => $value) { + $value = json_encode($value); + $httpCallContext->addHeader($key, $value); + + } + } + + $httpCallContext->setBody($brokeredMessage->getBody()); + $this->sendContext($httpCallContext); + } + + /** + * Sends a queue message. + * + * @link http://msdn.microsoft.com/en-us/library/windowsazure/hh780775 + * + * @param string $queueName The name of the queue. + * @param BrokeredMessage $brokeredMessage The brokered message. + * + * @return none + */ + public function sendQueueMessage($queueName, $brokeredMessage) + { + $path = sprintf(Resources::SEND_MESSAGE_PATH, $queueName); + $this->sendMessage($path, $brokeredMessage); + } + + /** + * Receives a queue message. + * + * @link http://msdn.microsoft.com/en-us/library/windowsazure/hh780735 + * @link http://msdn.microsoft.com/en-us/library/windowsazure/hh780756 + * + * @param string $queueName The name of the + * queue. + * @param ReceiveMessageOptions $receiveMessageOptions The options to + * receive the message. + * + * @return BrokeredMessage + */ + public function receiveQueueMessage($queueName, $receiveMessageOptions = null) + { + $queueMessagePath = sprintf(Resources::RECEIVE_MESSAGE_PATH, $queueName); + return $this->receiveMessage( + $queueMessagePath, + $receiveMessageOptions + ); + } + + // @codingStandardsIgnoreStart + + /** + * Receives a message. + * + * Queues: + * @link http://msdn.microsoft.com/en-us/library/windowsazure/hh780735 + * @link http://msdn.microsoft.com/en-us/library/windowsazure/hh780756 + * + * Topic Subscriptions: + * @link http://msdn.microsoft.com/en-us/library/windowsazure/hh780722 + * @link http://msdn.microsoft.com/en-us/library/windowsazure/hh780770 + * + * @param string $path The path of the + * message. + * @param ReceivedMessageOptions $receiveMessageOptions The options to + * receive the message. + * + * @return BrokeredMessage + */ + public function receiveMessage($path, $receiveMessageOptions = null) + { + if (is_null($receiveMessageOptions)) { + $receiveMessageOptions = new ReceiveMessageOptions(); + } + + $httpCallContext = new HttpCallContext(); + $httpCallContext->setPath($path); + $httpCallContext->addStatusCode(Resources::STATUS_CREATED); + $httpCallContext->addStatusCode(Resources::STATUS_NO_CONTENT); + $httpCallContext->addStatusCode(Resources::STATUS_OK); + $timeout = $receiveMessageOptions->getTimeout(); + if (!is_null($timeout)) { + $httpCallContext->addQueryParameter('timeout', $timeout); + } + + if ($receiveMessageOptions->getIsReceiveAndDelete()) { + $httpCallContext->setMethod(Resources::HTTP_DELETE); + } else if ($receiveMessageOptions->getIsPeekLock()) { + $httpCallContext->setMethod(Resources::HTTP_POST); + } else { + throw new \InvalidArgumentException( + Resources::INVALID_RECEIVE_MODE_MSG + ); + } + + $response = $this->sendContext($httpCallContext); + if ($response->getStatus() === Resources::STATUS_NO_CONTENT) { + $brokeredMessage = null; + } else { + $responseHeaders = $response->getHeader(); + $brokerProperties = new BrokerProperties(); + + if (array_key_exists('brokerproperties', $responseHeaders)) { + $brokerProperties = BrokerProperties::create( + $responseHeaders['brokerproperties'] + ); + } + + if (array_key_exists('location', $responseHeaders)) { + $brokerProperties->setLockLocation($responseHeaders['location']); + } + + $brokeredMessage = new BrokeredMessage(); + $brokeredMessage->setBrokerProperties($brokerProperties); + + if (array_key_exists(Resources::CONTENT_TYPE, $responseHeaders)) { + $brokeredMessage->setContentType( + $responseHeaders[Resources::CONTENT_TYPE] + ); + } + + if (array_key_exists('Date', $responseHeaders)) { + $brokeredMessage->setDate($responseHeaders['Date']); + } + + $brokeredMessage->setBody($response->getBody()); + + foreach (array_keys($responseHeaders) as $headerKey) { + $value = $responseHeaders[$headerKey]; + $decodedValue = json_decode($value); + if (is_scalar($decodedValue)) { + $brokeredMessage->setProperty( + $headerKey, + $decodedValue + ); + } + + } + } + + return $brokeredMessage; + } + + // @codingStandardsIgnoreEnd + + /** + * Sends a brokered message to a specified topic. + * + * @link http://msdn.microsoft.com/en-us/library/windowsazure/hh780786 + * + * @param string $topicName The name of the topic. + * @param BrokeredMessage $brokeredMessage The brokered message. + * + * @return none + */ + public function sendTopicMessage($topicName, $brokeredMessage) + { + $topicMessagePath = sprintf(Resources::SEND_MESSAGE_PATH, $topicName); + $this->sendMessage($topicMessagePath, $brokeredMessage); + } + + /** + * Receives a subscription message. + * + * @link http://msdn.microsoft.com/en-us/library/windowsazure/hh780722 + * @link http://msdn.microsoft.com/en-us/library/windowsazure/hh780770 + * + * @param string $topicName The name of the + * topic. + * @param string $subscriptionName The name of the + * subscription. + * @param ReceiveMessageOptions $receiveMessageOptions The options to + * receive the subscription message. + * + * @return BrokeredMessage + */ + public function receiveSubscriptionMessage( + $topicName, + $subscriptionName, + $receiveMessageOptions = null + ) { + $messagePath = sprintf( + Resources::RECEIVE_SUBSCRIPTION_MESSAGE_PATH, + $topicName, + $subscriptionName + ); + + $brokeredMessage = $this->receiveMessage( + $messagePath, + $receiveMessageOptions + ); + + return $brokeredMessage; + } + + /** + * Unlocks a brokered message. + * + * Queues: + * @link http://msdn.microsoft.com/en-us/library/windowsazure/hh780723 + * + * Topic Subscriptions: + * @link http://msdn.microsoft.com/en-us/library/windowsazure/hh780737 + * + * @param BrokeredMessage $brokeredMessage The brokered message. + * + * @return none + */ + public function unlockMessage($brokeredMessage) + { + $httpCallContext = new HttpCallContext(); + $httpCallContext->setMethod(Resources::HTTP_PUT); + $lockLocation = $brokeredMessage->getLockLocation(); + $lockLocationArray = parse_url($lockLocation); + $lockLocationPath = Resources::EMPTY_STRING; + + if (array_key_exists(Resources::PHP_URL_PATH, $lockLocationArray)) { + $lockLocationPath = $lockLocationArray[Resources::PHP_URL_PATH]; + $lockLocationPath = preg_replace( + '@^\/@', + Resources::EMPTY_STRING, + $lockLocationPath + ); + } + + $httpCallContext->setPath($lockLocationPath); + $httpCallContext->addStatusCode(Resources::STATUS_OK); + $this->sendContext($httpCallContext); + } + + /** + * Deletes a brokered message. + * + * Queues: + * @link http://msdn.microsoft.com/en-us/library/windowsazure/hh780767 + * + * Topic Subscriptions: + * @link http://msdn.microsoft.com/en-us/library/windowsazure/hh780768 + * + * @param BrokeredMessage $brokeredMessage The brokered message. + * + * @return none + */ + public function deleteMessage($brokeredMessage) + { + $httpCallContext = new HttpCallContext(); + $httpCallContext->setMethod(Resources::HTTP_DELETE); + $lockLocation = $brokeredMessage->getLockLocation(); + $lockLocationArray = parse_url($lockLocation); + $lockLocationPath = Resources::EMPTY_STRING; + + if (array_key_exists(Resources::PHP_URL_PATH, $lockLocationArray)) { + $lockLocationPath = $lockLocationArray[Resources::PHP_URL_PATH]; + $lockLocationPath = preg_replace( + '@^\/@', + Resources::EMPTY_STRING, + $lockLocationPath + ); + } + + if (empty($lockLocationPath)) { + throw new \InvalidArgumentException( + Resources::MISSING_LOCK_LOCATION_MSG + ); + } + $httpCallContext->setPath($lockLocationPath); + $httpCallContext->addStatusCode(Resources::STATUS_OK); + $this->sendContext($httpCallContext); + } + + /** + * Creates a queue with a specified queue information. + * + * @link http://msdn.microsoft.com/en-us/library/windowsazure/hh780716 + * + * @param QueueInfo $queueInfo The information of the queue. + * + * @return QueueInfo + */ + public function createQueue($queueInfo) + { + $httpCallContext = new HttpCallContext(); + $httpCallContext->setMethod(Resources::HTTP_PUT); + $httpCallContext->setPath($queueInfo->getTitle()); + $httpCallContext->addHeader( + Resources::CONTENT_TYPE, + Resources::ATOM_ENTRY_CONTENT_TYPE + ); + $httpCallContext->addStatusCode(Resources::STATUS_CREATED); + + $xmlWriter = new \XMLWriter(); + $xmlWriter->openMemory(); + $queueInfo->writeXml($xmlWriter); + $body = $xmlWriter->outputMemory(); + $httpCallContext->setBody($body); + + $response = $this->sendContext($httpCallContext); + $queueInfo = new QueueInfo(); + $queueInfo->parseXml($response->getBody()); + return $queueInfo; + } + + /** + * Deletes a queue. + * + * @link http://msdn.microsoft.com/en-us/library/windowsazure/hh780747 + * + * @param string $queuePath The path of the queue. + * + * @return none + */ + public function deleteQueue($queuePath) + { + Validate::isString($queuePath, 'queuePath'); + Validate::notNullOrEmpty($queuePath, 'queuePath'); + + $httpCallContext = new HttpCallContext(); + $httpCallContext->setMethod(Resources::HTTP_DELETE); + $httpCallContext->addStatusCode(Resources::STATUS_OK); + $httpCallContext->setPath($queuePath); + + $this->sendContext($httpCallContext); + } + + /** + * Gets a queue with specified path. + * + * @link http://msdn.microsoft.com/en-us/library/windowsazure/hh780764 + * + * @param string $queuePath The path of the queue. + * + * @return QueueInfo + */ + public function getQueue($queuePath) + { + $httpCallContext = new HttpCallContext(); + $httpCallContext->setPath($queuePath); + $httpCallContext->setMethod(Resources::HTTP_GET); + $httpCallContext->addStatusCode(Resources::STATUS_OK); + $response = $this->sendContext($httpCallContext); + $queueInfo = new QueueInfo(); + $queueInfo->parseXml($response->getBody()); + return $queueInfo; + } + + /** + * Lists a queue. + * + * @link http://msdn.microsoft.com/en-us/library/windowsazure/hh780759 + * + * @param ListQueuesOptions $listQueuesOptions The options to list the + * queues. + * + * @return ListQueuesResult; + */ + public function listQueues($listQueuesOptions = null) + { + $response = $this->_listOptions( + $listQueuesOptions, + Resources::LIST_QUEUES_PATH + ); + + $listQueuesResult = new ListQueuesResult(); + $listQueuesResult->parseXml($response->getBody()); + return $listQueuesResult; + } + + /** + * The base method of all the list operations. + * + * @param ListOptions $listOptions The options for list operation. + * @param string $path The path of the list operation. + * + * @return none + */ + private function _listOptions($listOptions, $path) + { + if (is_null($listOptions)) { + $listOptions = new ListOptions(); + } + + $httpCallContext = new HttpCallContext(); + $httpCallContext->setMethod(Resources::HTTP_GET); + $httpCallContext->setPath($path); + $httpCallContext->addStatusCode(Resources::STATUS_OK); + $top = $listOptions->getTop(); + $skip = $listOptions->getSkip(); + + if (!empty($top)) { + $httpCallContext->addQueryParameter(Resources::QP_TOP, $top); + } + + if (!empty($skip)) { + $httpCallContext->addQueryParameter(Resources::QP_SKIP, $skip); + } + + return $this->sendContext($httpCallContext); + } + + /** + * Creates a topic with specified topic info. + * + * @link http://msdn.microsoft.com/en-us/library/windowsazure/hh780728 + * + * @param TopicInfo $topicInfo The information of the topic. + * + * @return TopicInfo + */ + public function createTopic($topicInfo) + { + Validate::notNullOrEmpty($topicInfo, 'topicInfo'); + $httpCallContext = new HttpCallContext(); + $httpCallContext->setMethod(Resources::HTTP_PUT); + $httpCallContext->setPath($topicInfo->getTitle()); + $httpCallContext->addHeader( + Resources::CONTENT_TYPE, + Resources::ATOM_ENTRY_CONTENT_TYPE + ); + $httpCallContext->addStatusCode(Resources::STATUS_CREATED); + + $topicDescriptionXml = XmlSerializer::objectSerialize( + $topicInfo->getTopicDescription(), + 'TopicDescription' + ); + + $entry = new Entry(); + $content = new Content($topicDescriptionXml); + $content->setType(Resources::XML_CONTENT_TYPE); + $entry->setContent($content); + + $entry->setAttribute( + Resources::XMLNS, + Resources::SERVICE_BUS_NAMESPACE + ); + + $xmlWriter = new \XMLWriter(); + $xmlWriter->openMemory(); + $entry->writeXml($xmlWriter); + $httpCallContext->setBody($xmlWriter->outputMemory()); + + $response = $this->sendContext($httpCallContext); + $topicInfo = new TopicInfo(); + $topicInfo->parseXml($response->getBody()); + return $topicInfo; + } + + /** + * Deletes a topic with specified topic path. + * + * @link http://msdn.microsoft.com/en-us/library/windowsazure/hh780721 + * + * @param string $topicPath The path of the topic. + * + * @return none + */ + public function deleteTopic($topicPath) + { + $httpCallContext = new HttpCallContext(); + $httpCallContext->setMethod(Resources::HTTP_DELETE); + $httpCallContext->setPath($topicPath); + $httpCallContext->addStatusCode(Resources::STATUS_OK); + + $this->sendContext($httpCallContext); + } + + /** + * Gets a topic. + * + * @link http://msdn.microsoft.com/en-us/library/windowsazure/hh780769 + * + * @param string $topicPath The path of the topic. + * + * @return TopicInfo + */ + public function getTopic($topicPath) + { + $httpCallContext = new HttpCallContext(); + $httpCallContext->setMethod(Resources::HTTP_GET); + $httpCallContext->setPath($topicPath); + $httpCallContext->addStatusCode(Resources::STATUS_OK); + $response = $this->sendContext($httpCallContext); + $topicInfo = new TopicInfo(); + $topicInfo->parseXml($response->getBody()); + return $topicInfo; + } + + /** + * Lists topics. + * + * @link http://msdn.microsoft.com/en-us/library/windowsazure/hh780744 + * + * @param ListTopicsOptions $listTopicsOptions The options to list + * the topics. + * + * @return ListTopicsResults + */ + public function listTopics($listTopicsOptions = null) + { + $response = $this->_listOptions( + $listTopicsOptions, + Resources::LIST_TOPICS_PATH + ); + + $listTopicsResult = new ListTopicsResult(); + $listTopicsResult->parseXml($response->getBody()); + return $listTopicsResult; + } + + /** + * Creates a subscription with specified topic path and + * subscription info. + * + * @link http://msdn.microsoft.com/en-us/library/windowsazure/hh780748 + * + * @param string $topicPath The path of + * the topic. + * @param SubscriptionInfo $subscriptionInfo The information + * of the subscription. + * + * @return SubscriptionInfo + */ + public function createSubscription($topicPath, $subscriptionInfo) + { + $httpCallContext = new HttpCallContext(); + $httpCallContext->setMethod(Resources::HTTP_PUT); + $subscriptionPath = sprintf( + Resources::SUBSCRIPTION_PATH, + $topicPath, + $subscriptionInfo->getTitle() + ); + $httpCallContext->setPath($subscriptionPath); + $httpCallContext->addHeader( + Resources::CONTENT_TYPE, + Resources::ATOM_ENTRY_CONTENT_TYPE + ); + $httpCallContext->addStatusCode(Resources::STATUS_CREATED); + + $subscriptionDescriptionXml = XmlSerializer::objectSerialize( + $subscriptionInfo->getSubscriptionDescription(), + 'SubscriptionDescription' + ); + + $entry = new Entry(); + $content = new Content($subscriptionDescriptionXml); + $content->setType(Resources::XML_CONTENT_TYPE); + $entry->setContent($content); + + $entry->setAttribute( + Resources::XMLNS, + Resources::SERVICE_BUS_NAMESPACE + ); + + $xmlWriter = new \XMLWriter(); + $xmlWriter->openMemory(); + $entry->writeXml($xmlWriter); + $httpCallContext->setBody($xmlWriter->outputMemory()); + + $response = $this->sendContext($httpCallContext); + $subscriptionInfo = new SubscriptionInfo(); + $subscriptionInfo->parseXml($response->getBody()); + return $subscriptionInfo; + } + + /** + * Deletes a subscription. + * + * @link http://msdn.microsoft.com/en-us/library/windowsazure/hh780740 + * + * @param string $topicPath The path of the topic. + * @param string $subscriptionName The name of the subscription. + * + * @return none + */ + public function deleteSubscription($topicPath, $subscriptionName) + { + $httpCallContext = new HttpCallContext(); + $httpCallContext->setMethod(Resources::HTTP_DELETE); + $httpCallContext->addStatusCode(Resources::STATUS_OK); + $subscriptionPath = sprintf( + Resources::SUBSCRIPTION_PATH, + $topicPath, + $subscriptionName + ); + $httpCallContext->setPath($subscriptionPath); + $this->sendContext($httpCallContext); + } + + /** + * Gets a subscription. + * + * @link http://msdn.microsoft.com/en-us/library/windowsazure/hh780741 + * + * @param string $topicPath The path of the topic. + * @param string $subscriptionName The name of the subscription. + * + * @return SubscriptionInfo + */ + public function getSubscription($topicPath, $subscriptionName) + { + $httpCallContext = new HttpCallContext(); + $httpCallContext->setMethod(Resources::HTTP_GET); + $httpCallContext->addStatusCode(Resources::STATUS_OK); + $subscriptionPath = sprintf( + Resources::SUBSCRIPTION_PATH, + $topicPath, + $subscriptionName + ); + $httpCallContext->setPath($subscriptionPath); + $response = $this->sendContext($httpCallContext); + $subscriptionInfo = new SubscriptionInfo(); + $subscriptionInfo->parseXml($response->getBody()); + return $subscriptionInfo; + } + + /** + * Lists subscription. + * + * @link http://msdn.microsoft.com/en-us/library/windowsazure/hh780766 + * + * @param string $topicPath The path of + * the topic. + * @param ListSubscriptionsOptions $listSubscriptionsOptions The options + * to list the subscription. + * + * @return ListSubscriptionsResult + */ + public function listSubscriptions( + $topicPath, + $listSubscriptionsOptions = null + ) { + + $listSubscriptionsPath = sprintf( + Resources::LIST_SUBSCRIPTIONS_PATH, + $topicPath + ); + $response = $this->_listOptions( + $listSubscriptionsOptions, + $listSubscriptionsPath + ); + $listSubscriptionsResult = new ListSubscriptionsResult(); + $listSubscriptionsResult->parseXml($response->getBody()); + return $listSubscriptionsResult; + } + + /** + * Creates a rule. + * + * @link http://msdn.microsoft.com/en-us/library/windowsazure/hh780774 + * + * @param string $topicPath The path of the topic. + * @param string $subscriptionName The name of the subscription. + * @param RuleInfo $ruleInfo The information of the rule. + * + * @return RuleInfo + */ + public function createRule($topicPath, $subscriptionName, $ruleInfo) + { + $httpCallContext = new HttpCallContext(); + $httpCallContext->setMethod(Resources::HTTP_PUT); + $httpCallContext->addStatusCode(Resources::STATUS_CREATED); + $httpCallContext->addHeader( + Resources::CONTENT_TYPE, + Resources::ATOM_ENTRY_CONTENT_TYPE + ); + $rulePath = sprintf( + Resources::RULE_PATH, + $topicPath, + $subscriptionName, + $ruleInfo->getTitle() + ); + + $ruleDescriptionXml = XmlSerializer::objectSerialize( + $ruleInfo->getRuleDescription(), + 'RuleDescription' + ); + + $entry = new Entry(); + $content = new Content($ruleDescriptionXml); + $content->setType(Resources::XML_CONTENT_TYPE); + $entry->setContent($content); + + $entry->setAttribute( + Resources::XMLNS, + Resources::SERVICE_BUS_NAMESPACE + ); + + $xmlWriter = new \XMLWriter(); + $xmlWriter->openMemory(); + $entry->writeXml($xmlWriter); + $httpCallContext->setBody($xmlWriter->outputMemory()); + + $httpCallContext->setPath($rulePath); + $response = $this->sendContext($httpCallContext); + $ruleInfo = new ruleInfo(); + $ruleInfo->parseXml($response->getBody()); + return $ruleInfo; + } + + /** + * Deletes a rule. + * + * @link http://msdn.microsoft.com/en-us/library/windowsazure/hh780751 + * + * @param string $topicPath The path of the topic. + * @param string $subscriptionName The name of the subscription. + * @param string $ruleName The name of the rule. + * + * @return none + */ + public function deleteRule($topicPath, $subscriptionName, $ruleName) + { + $httpCallContext = new HttpCallContext(); + $httpCallContext->addStatusCode(Resources::STATUS_OK); + $httpCallContext->setMethod(Resources::HTTP_DELETE); + $rulePath = sprintf( + Resources::RULE_PATH, + $topicPath, + $subscriptionName, + $ruleName + ); + $httpCallContext->setPath($rulePath); + $this->sendContext($httpCallContext); + } + + /** + * Gets a rule. + * + * @link http://msdn.microsoft.com/en-us/library/windowsazure/hh780772 + * + * @param string $topicPath The path of the topic. + * @param string $subscriptionName The name of the subscription. + * @param string $ruleName The name of the rule. + * + * @return RuleInfo + */ + public function getRule($topicPath, $subscriptionName, $ruleName) + { + $httpCallContext = new HttpCallContext(); + $httpCallContext->setMethod(Resources::HTTP_GET); + $httpCallContext->addStatusCode(Resources::STATUS_OK); + $rulePath = sprintf( + Resources::RULE_PATH, + $topicPath, + $subscriptionName, + $ruleName + ); + $httpCallContext->setPath($rulePath); + $response = $this->sendContext($httpCallContext); + $ruleInfo = new RuleInfo(); + $ruleInfo->parseXml($response->getBody()); + return $ruleInfo; + } + + /** + * Lists rules. + * + * @link http://msdn.microsoft.com/en-us/library/windowsazure/hh780732 + * + * @param string $topicPath The path of the topic. + * @param string $subscriptionName The name of the subscription. + * @param ListRulesOptions $listRulesOptions The options to list the rules. + * + * @return ListRuleResult + */ + public function listRules( + $topicPath, + $subscriptionName, + $listRulesOptions = null + ) { + $listRulesPath = sprintf( + Resources::LIST_RULES_PATH, + $topicPath, + $subscriptionName + ); + + $response = $this->_listOptions( + $listRulesOptions, + $listRulesPath + ); + + $listRulesResult = new ListRulesResult(); + $listRulesResult->parseXml($response->getBody()); + return $listRulesResult; + } + +} diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Internal/IServiceManagement.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Internal/IServiceManagement.php new file mode 100644 index 0000000..9a814ad --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Internal/IServiceManagement.php @@ -0,0 +1,552 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceManagement\Internal; +use WindowsAzure\Common\Internal\FilterableService; + +/** + * The Windows Azure service management REST API wrappers. + * + * @category Microsoft + * @package WindowsAzure\ServiceManagement\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +interface IServiceManagement extends FilterableService +{ + /** + * Lists the storage accounts available under the current subscription. + * + * @return ListStorageServicesResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee460787.aspx + */ + public function listStorageServices(); + + /** + * Returns the system properties for the specified storage account. + * + * These properties include: the address, description, and label of the storage + * account; and the name of the affinity group to which the service belongs, + * or its geo-location if it is not part of an affinity group. + * + * @param string $name The storage account name. + * + * @return GetStorageServicePropertiesResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee460802.aspx + */ + public function getStorageServiceProperties($name); + + /** + * Returns the primary and secondary access keys for the specified storage + * account. + * + * @param string $name The storage account name. + * + * @return GetStorageServiceKeysResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee460785.aspx + */ + public function getStorageServiceKeys($name); + + + /** + * Regenerates the primary or secondary access key for the specified storage + * account. + * + * @param string $name The storage account name. + * @param string $keyType Specifies which key to regenerate. + * + * @return GetStorageServiceKeysResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee460795.aspx + */ + public function regenerateStorageServiceKeys($name, $keyType); + + /** + * Creates a new storage account in Windows Azure. + * + * In the optional parameters either location or affinity group must be provided. + * Because Create Storage Account is an asynchronous operation, it always returns + * status code 202 (Accepted). To determine the status code for the operation + * once it is complete, call Get Operation Status. The status code is embedded + * in the response for this operation; if successful, it will be + * status code 200 (OK). + * + * @param string $name The storage account name. + * @param string $label Name for the storage + * account specified as a base64-encoded string. The name may be up to 100 + * characters in length. The name can be used identify the storage account for + * your tracking purposes. + * @param CreateServiceOptions $options The optional parameters. + * + * @return AsynchronousOperationResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/hh264518.aspx + */ + public function createStorageService($name, $label, $options); + + /** + * Deletes the specified storage account from Windows Azure. + * + * @param string $name The storage account name. + * + * @return none + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/hh264517.aspx + */ + public function deleteStorageService($name); + + /** + * Updates the label and/or the description for a storage account in Windows + * Azure. + * + * @param string $name The storage account name. + * @param UpdateServiceOptions $options The optional parameters. + * + * @return none + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/hh264516.aspx + */ + public function updateStorageService($name, $options); + + /** + * Lists the affinity groups associated with the specified subscription. + * + * @return ListAffinityGroupsResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee460797.aspx + */ + public function listAffinityGroups(); + + /** + * Creates a new affinity group for the specified subscription. + * + * @param string $name The affinity group name. + * @param string $label A base-64 encoded name for + * the affinity group. The name can be up to 100 characters in length. + * @param string $location The data center location + * where the affinity group will be created. To list available locations, use + * the listLocations API. + * @param CreateAffinityGroupOptions $options The optional parameters. + * + * @return none + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/gg715317.aspx + */ + public function createAffinityGroup($name, $label, $location, $options = null); + + /** + * Deletes an affinity group in the specified subscription. + * + * @param string $name The affinity group name. + * + * @return none + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/gg715314.aspx + */ + public function deleteAffinityGroup($name); + + /** + * Updates the label and/or the description for an affinity group for the + * specified subscription. + * + * @param string $name The affinity group name. + * @param string $label The affinity group label. + * @param CreateAffinityGroupOptions $options The optional parameters. + * + * @return none + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/gg715316.aspx + */ + public function updateAffinityGroup($name, $label, $options = null); + + /** + * Returns the system properties associated with the specified affinity group. + * + * @param string $name The affinity group name. + * + * @return GetAffinityGroupPropertiesResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee460789.aspx + */ + public function getAffinityGroupProperties($name); + + /** + * Lists all of the data center locations that are valid for your subscription. + * + * @return ListLocationsResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/gg441293.aspx + */ + public function listLocations(); + + /** + * Returns the status of the specified operation. After calling an asynchronous + * operation, you can call Get Operation Status to determine whether the + * operation has succeeded, failed, or is still in progress. + * + * @param AsynchronousOperationResult $requestInfo The request information for + * the REST call you want to track. + * + * @return GetOperationStatusResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee460783.aspx + */ + public function getOperationStatus($requestInfo); + + /** + * Lists the hosted services available under the current subscription. + * + * @return ListHostedServicesResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee460781.aspx + */ + public function listHostedServices(); + + /** + * Creates a new hosted service in Windows Azure. + * + * @param string $name The name for the hosted service + * that is unique within Windows Azure. This name is the DNS prefix name and can + * be used to access the hosted service. + * @param string $label The name for the hosted service + * that is base-64 encoded. The name can be used identify the storage account for + * your tracking purposes. + * @param CreateServiceOptions $options The optional parameters. + * + * @return none + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/gg441304.aspx + */ + public function createHostedService($name, $label, $options); + + /** + * updates the label and/or the description for a hosted service in Windows + * Azure. + * + * @param string $name The name for the hosted service that is + * unique within Windows Azure. + * @param UpdateServiceOptions $options The optional parameters. + * + * @return none + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/gg441303.aspx + */ + public function updateHostedService($name, $options); + + /** + * Deletes the specified hosted service from Windows Azure. + * + * Before you can delete a hosted service, you must delete any deployments it + * has. Attempting to delete a hosted service that has deployments results in + * an error. You can call the deleteDeployment API to delete a hosted service's + * deployments. + * + * @param string $name The name for the hosted service. + * + * @return none + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/gg441305.aspx + */ + public function deleteHostedService($name); + + /** + * Retrieves system properties for the specified hosted service. These properties + * include the service name and service type; the name of the affinity group to + * which the service belongs, or its location if it is not part of an affinity + * group; and optionally, information on the service's deployments. + * + * @param string $name The name for the hosted + * service. + * @param GetHostedServicePropertiesOptions $options The optional parameters. + * + * @return GetHostedServicePropertiesResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee460806.aspx + */ + public function getHostedServiceProperties($name, $options = null); + + /** + * Uploads a new service package and creates a new deployment on staging or + * production. + * + * The createDeployment API is an asynchronous operation. To determine whether + * the management service has finished processing the request, call + * getOperationStatus API. + * + * @param string $name The name for the hosted service + * that is unique within Windows Azure. + * @param string $deploymentName The name for the deployment. + * The deployment name must be unique among other deployments for the hosted + * service. + * @param string $slot The name of the deployment slot + * This can be "production" or "staging". + * @param string $packageUrl The URL that refers to the + * location of the service package in the Blob service. The service package can + * be located in a storage account beneath the same subscription. + * @param string $configuration The base-64 encoded service + * configuration file for the deployment. + * @param string $label The name for the hosted service + * that is base-64 encoded. The name can be up to 100 characters in length. It is + * recommended that the label be unique within the subscription. The name can be + * used identify the hosted service for your tracking purposes. + * @param CreateDeploymentOptions $options The optional parameters. + * + * @return AsynchronousOperationResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee460813.aspx + */ + public function createDeployment( + $name, + $deploymentName, + $slot, + $packageUrl, + $configuration, + $label, + $options = null + ); + + /** + * Returns configuration information, status, and system properties for a + * deployment. + * + * The getDeployment API can be used to retrieve information for a specific + * deployment or for all deployments in the staging or production environment. + * If you want to retrieve information about a specific deployment, you must + * first get the unique name for the deployment. This unique name is part of the + * response when you make a request to get all deployments in an environment. + * + * @param string $name The hosted service name. + * @param GetDeploymentOptions $options The optional parameters. + * + * @return GetDeploymentResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee460804.aspx + */ + public function getDeployment($name, $options); + + /** + * Initiates a virtual IP swap between the staging and production deployment + * environments for a service. If the service is currently running in the staging + * environment, it will be swapped to the production environment. If it is + * running in the production environment, it will be swapped to staging. + * + * You can swap VIPs only if the number of endpoints specified by the service + * definition is identical for both deployments. For example, if you add an HTTPS + * endpoint to a web role that previously exposed only an HTTP endpoint, you + * cannot upgrade your service using a VIP swap; you must delete your production + * deployment and redeploy instead. You can obtain information about endpoints + * that are used by using the Get Deployment operation. + * + * @param string $name The hosted service name. + * @param string $source The name of the source deployment. + * @param string $destination The name of the destination deployment. + * + * @return AsynchronousOperationResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee460814.aspx + */ + public function swapDeployment($name, $source, $destination); + + /** + * Deletes the specified deployment. + * + * Note that you can delete a deployment either by specifying the deployment + * environment (staging or production), or by specifying the deployment's unique + * name. + * + * @param string $name The hosted service name. + * @param GetDeploymentOptions $options The optional parameters. + * + * @return AsynchronousOperationResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee460815.aspx + */ + public function deleteDeployment($name, $options); + + /** + * Initiates a change to the deployment configuration. + * + * Note that you can change a deployment's configuration either by specifying the + * deployment environment (staging or production), or by specifying the + * deployment's unique name. + * + * @param string $name The hosted service + * name. + * @param string|resource $configuration The configuration + * file contents or file stream, + * @param ChangeDeploymentConfigurationOptions $options The optional + * parameters. + * + * @return AsynchronousOperationResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee460809.aspx + */ + public function changeDeploymentConfiguration($name, $configuration, $options); + + /** + * Initiates a change in deployment status. + * + * Note that you can change deployment status either by specifying the deployment + * environment (staging or production), or by specifying the deployment's unique + * name. + * + * @param string $name The hosted service name. + * @param string $status The change to initiate to the + * deployment status. + * Possible values include Running or Suspended. + * @param GetDeploymentOptions $options The optional parameters. + * + * @return AsynchronousOperationResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee460808.aspx + */ + public function updateDeploymentStatus($name, $status, $options); + + /** + * Initiates an upgrade to a deployment. + * + * Note that you can upgrade a deployment either by specifying the deployment + * environment (staging or production), or by specifying the deployment's unique + * name. + * + * @param string $name The hosted service name. + * @param string $mode The type of upgrade to initiate + * If not specified the default value is Auto. If set to Manual, + * walkUpgradeDomain API must be called to apply the update. If set to Auto, the + * Windows Azure platform will automatically apply the update to each Upgrade + * Domain in sequence. + * @param string $packageUrl The URL that refers to the + * location of the service package in the Blob service. The service package can + * be located in a storage account beneath the same subscription. + * @param string $configuration The base-64 encoded service + * configuration file for the deployment. + * @param string $label The name for the hosted service + * that is base-64 encoded. The name may be up to 100 characters in length. + * @param boolean $force Specifies whether the rollback + * should proceed even when it will cause local data to be lost from some role + * instances. True if the rollback should proceed; otherwise false if the + * rollback should fail. + * @param UpgradeDeploymentOptions $options The optional parameters. + * + * @return AsynchronousOperationResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee460793.aspx + */ + public function upgradeDeployment( + $name, + $mode, + $packageUrl, + $configuration, + $label, + $force, + $options + ); + + /** + * Specifies the next upgrade domain to be walked during manual in-place upgrade + * or configuration change. + * + * Note that you can walk an upgrade domain either by specifying the deployment + * environment (staging or production), or by specifying the deployment's unique + * name. + * + * @param string $name The hosted service name. + * @param integer $upgradeDomain The integer value that + * identifies the upgrade domain to walk. Upgrade domains are identified with a + * zero-based index: the first upgrade domain has an ID of 0, the second has an + * ID of 1, and so on. + * @param GetDeploymentOptions $options The optional parameters. + * + * @return AsynchronousOperationResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee460800.aspx + */ + public function walkUpgradeDomain($name, $upgradeDomain, $options); + + /** + * Requests a reboot of a role instance that is running in a deployment. + * + * Note that you can reboot role instance either by specifying the deployment + * environment (staging or production), or by specifying the deployment's unique + * name. + * + * @param string $name The hosted service name. + * @param string $roleName The role instance name. + * @param GetDeploymentOptions $options The optional parameters. + * + * @return AsynchronousOperationResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/gg441298.aspx + */ + public function rebootRoleInstance($name, $roleName, $options); + + /** + * Requests a reimage of a role instance that is running in a deployment. + * + * Note that you can reimage role instance either by specifying the deployment + * environment (staging or production), or by specifying the deployment's unique + * name. + * + * @param string $name The hosted service name. + * @param string $roleName The role instance name. + * @param GetDeploymentOptions $options The optional parameters. + * + * @return AsynchronousOperationResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/gg441292.aspx + */ + public function reimageRoleInstance($name, $roleName, $options); + + /** + * Cancels an in progress configuration change (update) or upgrade and returns + * the deployment to its state before the upgrade or configuration change was + * started. + * + * Note that you can rollback update or upgrade either by specifying the + * deployment environment (staging or production), or by specifying the + * deployment's unique name. + * + * @param string $name The hosted service name. + * @param string $mode Specifies whether the rollback + * should proceed automatically or not. Auto, The rollback proceeds without + * further user input. Manual, You must call the walkUpgradeDomain API to apply + * the rollback to each upgrade domain. + * @param boolean $force Specifies whether the rollback + * should proceed even when it will cause local data to be lost from some role + * instances. True if the rollback should proceed; otherwise false if the + * rollback should fail. + * @param GetDeploymentOptions $options The optional parameters. + * + * @return none + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/hh403977.aspx + */ + public function rollbackUpdateOrUpgrade($name, $mode, $force, $options); +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Internal/Service.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Internal/Service.php new file mode 100644 index 0000000..8948b82 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Internal/Service.php @@ -0,0 +1,267 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceManagement\Internal; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Serialization\XmlSerializer; + +/** + * Windows Azure service basic elements. + * + * @category Microsoft + * @package WindowsAzure\ServiceManagement\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class Service +{ + /** + * @var string + */ + private $_name; + + /** + * @var string + */ + private $_label; + + /** + * @var string + */ + private $_description; + + /** + * @var string + */ + private $_location; + + /** + * @var array + */ + private $_serializationProperties; + + /** + * Creates Service object from the given raw array. + * + * @param array $sources The list of sources that has the row XML. + */ + public function __construct($sources = array()) + { + foreach ($sources as $source) { + $this->setLabel( + Utilities::tryGetValue( + $source, + Resources::XTAG_LABEL, + $this->getLabel() + ) + ); + + $this->setLocation( + Utilities::tryGetValue( + $source, + Resources::XTAG_LOCATION, + $this->getLocation() + ) + ); + + $this->setDescription( + Utilities::tryGetValue( + $source, + Resources::XTAG_DESCRIPTION, + $this->getDescription() + ) + ); + } + } + + /** + * Gets the name. + * + * @return string + */ + public function getName() + { + return $this->_name; + } + + /** + * Sets the name. + * + * @param string $name The name. + * + * @return none + */ + public function setName($name) + { + $this->_name = $name; + } + + /** + * Gets the label. + * + * @return string + */ + public function getLabel() + { + return $this->_label; + } + + /** + * Sets the label. + * + * @param string $label The label. + * + * @return none + */ + public function setLabel($label) + { + $this->_label = $label; + } + + /** + * Gets the description. + * + * @return string + */ + public function getDescription() + { + return $this->_description; + } + + /** + * Sets the description. + * + * @param string $description The description. + * + * @return none + */ + public function setDescription($description) + { + $this->_description = $description; + } + + /** + * Gets the location. + * + * @return string + */ + public function getLocation() + { + return $this->_location; + } + + /** + * Sets the location. + * + * @param string $location The location. + * + * @return none + */ + public function setLocation($location) + { + $this->_location = $location; + } + + /** + * Adds serialization property. + * + * @param string $key The property name. + * @param string $value The property value. + * + * @return none + */ + public function addSerializationProperty($key, $value) + { + $this->_serializationProperties[$key] = $value; + } + + /** + * Gets serialization property value. + * + * @param string $key The property key. + * + * @return string + */ + public function getSerializationPropertyValue($key) + { + return Utilities::tryGetValue($this->_serializationProperties, $key); + } + + /** + * Converts the current object into array representation. + * + * @return array + */ + protected function toArray() + { + $arr = array(); + $arr[Resources::XTAG_NAMESPACE] = array( + Resources::WA_XML_NAMESPACE => null + ); + + Utilities::addIfNotEmpty(Resources::XTAG_LABEL, $this->_label, $arr); + Utilities::addIfNotEmpty( + Resources::XTAG_DESCRIPTION, + $this->_description, + $arr + ); + Utilities::addIfNotEmpty( + Resources::XTAG_LOCATION, + $this->_location, + $arr + ); + + return $arr; + } + + /** + * Serializes the current object. + * + * @param ISerializer $serializer The serializer. + * + * @return string + * + * @throws \InvalidArgumentException + */ + public function serialize($serializer) + { + $serialized = Resources::EMPTY_STRING; + + if ($serializer instanceof XmlSerializer) { + $arr = $this->toArray(); + $serialized = $serializer->serialize( + $arr, + $this->_serializationProperties + ); + } else { + throw new \InvalidArgumentException(Resources::UNKNOWN_SRILZER_MSG); + } + + return $serialized; + } +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Internal/WindowsAzureService.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Internal/WindowsAzureService.php new file mode 100644 index 0000000..cd2fe12 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Internal/WindowsAzureService.php @@ -0,0 +1,151 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceManagement\Internal; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Utilities; + +/** + * Base class for all windows azure provided services. + * + * @category Microsoft + * @package WindowsAzure\ServiceManagement\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class WindowsAzureService extends Service +{ + /** + * @var string + */ + private $_affinityGroup; + + /** + * @var string + */ + private $_url; + + /** + * Constructs new storage service object. + * + * @param array $sources The list of sources that has the row XML. + */ + public function __construct($sources = array()) + { + parent::__construct($sources); + + foreach ($sources as $source) { + $this->setName( + Utilities::tryGetValue( + $source, + Resources::XTAG_SERVICE_NAME, + $this->getName() + ) + ); + + $this->setAffinityGroup( + Utilities::tryGetValue( + $source, + Resources::XTAG_AFFINITY_GROUP, + $this->getAffinityGroup() + ) + ); + + $this->setUrl( + Utilities::tryGetValue( + $source, + Resources::XTAG_URL, + $this->getUrl() + ) + ); + } + } + + /** + * Gets the affinityGroup name. + * + * @return string + */ + public function getAffinityGroup() + { + return $this->_affinityGroup; + } + + /** + * Sets the affinityGroup name. + * + * @param string $affinityGroup The affinityGroup name. + * + * @return none + */ + public function setAffinityGroup($affinityGroup) + { + $this->_affinityGroup = $affinityGroup; + } + + /** + * Gets the url name. + * + * @return string + */ + public function getUrl() + { + return $this->_url; + } + + /** + * Sets the url name. + * + * @param string $url The url name. + * + * @return none + */ + public function setUrl($url) + { + $this->_url = $url; + } + + /** + * Converts the current object into ordered array representation. + * + * @return array + */ + protected function toArray() + { + $arr = parent::toArray(); + Utilities::addIfNotEmpty( + Resources::XTAG_SERVICE_NAME, $this->getName(), + $arr + ); + Utilities::addIfNotEmpty( + Resources::XTAG_AFFINITY_GROUP, $this->getAffinityGroup(), + $arr + ); + + return $arr; + } +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/AffinityGroup.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/AffinityGroup.php new file mode 100644 index 0000000..f3b19a3 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/AffinityGroup.php @@ -0,0 +1,84 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceManagement\Models; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\ServiceManagement\Internal\Service; + +/** + * The affinity group class. + * + * @category Microsoft + * @package WindowsAzure\ServiceManagement\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class AffinityGroup extends Service +{ + /** + * Constructs new affinity group object. + */ + public function __construct() + { + $sources = func_get_args(); + parent::__construct($sources); + + foreach ($sources as $source) { + $this->setName( + Utilities::tryGetValue( + $source, + Resources::XTAG_NAME, + $this->getName() + ) + ); + } + } + + /** + * Converts the current object into ordered array representation. + * + * @return array + */ + protected function toArray() + { + $arr = parent::toArray(); + $order = array( + Resources::XTAG_NAMESPACE, + Resources::XTAG_NAME, + Resources::XTAG_LABEL, + Resources::XTAG_DESCRIPTION, + Resources::XTAG_LOCATION + ); + Utilities::addIfNotEmpty(Resources::XTAG_NAME, $this->getName(), $arr); + $ordered = Utilities::orderArray($arr, $order); + + return $ordered; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/AsynchronousOperationResult.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/AsynchronousOperationResult.php new file mode 100644 index 0000000..31d056f --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/AsynchronousOperationResult.php @@ -0,0 +1,88 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceManagement\Models; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Utilities; + +/** + * The result of an asynchronous operation. + * + * @category Microsoft + * @package WindowsAzure\ServiceManagement\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class AsynchronousOperationResult +{ + /** + * @var string + */ + private $_requestId; + + /** + * Creates new AsynchronousOperationResult from response HTTP headers. + * + * @param array $headers The HTTP response headers array. + * + * @return AsynchronousOperationResult + */ + public static function create($headers) + { + $result = new AsynchronousOperationResult(); + $result->_requestId = Utilities::tryGetValue( + $headers, + Resources::X_MS_REQUEST_ID + ); + + return $result; + } + + /** + * Gets the requestId. + * + * @return string + */ + public function getrequestId() + { + return $this->_requestId; + } + + /** + * Sets the requestId. + * + * @param string $requestId The request Id of the asynchronous operation. + * + * @return none + */ + public function setrequestId($requestId) + { + $this->_requestId = $requestId; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/ChangeDeploymentConfigurationOptions.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/ChangeDeploymentConfigurationOptions.php new file mode 100644 index 0000000..0004707 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/ChangeDeploymentConfigurationOptions.php @@ -0,0 +1,124 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceManagement\Models; +use WindowsAzure\Common\Internal\Validate; +use WindowsAzure\Common\Internal\Resources; + +/** + * The optional parameters for changeDeploymentConfiguration API. + * + * @category Microsoft + * @package WindowsAzure\ServiceManagement\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class ChangeDeploymentConfigurationOptions extends GetDeploymentOptions +{ + /** + * Indicates whether to treat package validation warnings as errors. + * + * @var boolean + */ + private $_treatWarningsAsErrors; + + /** + * If not specified the default value is Auto. If set to Manual, + * WalkUpgradeDomain must be called to apply the update. If set to Auto, the + * Windows Azure platform will automatically apply the update To each upgrade + * domain for the service. + * + * @var string + */ + private $_mode; + + /** + * Constructs new ChangeDeploymentConfigurationOptions instance. + */ + public function __construct() + { + $this->_treatWarningsAsErrors = false; + } + + /** + * Gets treat warnings as errors flag. + * + * If not specified the default value is false. If set to true, the update will + * be blocked when warnings are encountered. + * + * @return boolean + */ + public function getTreatWarningsAsErrors() + { + return $this->_treatWarningsAsErrors; + } + + /** + * Sets treat warnings as errors flag. + * + * @param boolean $treatWarningsAsErrors Indicates whether to treat package + * validation warnings as errors. + * + * @return none + */ + public function setTreatWarningsAsErrors($treatWarningsAsErrors) + { + Validate::isBoolean($treatWarningsAsErrors, 'treatWarningsAsErrors'); + + $this->_treatWarningsAsErrors = $treatWarningsAsErrors; + } + + /** + * Gets change mode. + * + * If not specified the default value is Auto. If set to Manual, + * WalkUpgradeDomain must be called to apply the update. If set to Auto, the + * Windows Azure platform will automatically apply the update To each upgrade + * domain for the service. + * + * @return string + */ + public function getMode() + { + return $this->_mode; + } + + /** + * Sets mode. + * + * @param string $mode The change mode. + * + * @return none + */ + public function setMode($mode) + { + Validate::isString($mode, 'mode'); + Validate::isTrue(Mode::isValid($mode), Resources::INVALID_CHANGE_MODE_MSG); + + $this->_mode = $mode; + } +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/CreateAffinityGroupOptions.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/CreateAffinityGroupOptions.php new file mode 100644 index 0000000..93d186f --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/CreateAffinityGroupOptions.php @@ -0,0 +1,71 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceManagement\Models; +use WindowsAzure\Common\Internal\Validate; + +/** + * The optional parameters for createAffinityGroup API. + * + * @category Microsoft + * @package WindowsAzure\ServiceManagement\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class CreateAffinityGroupOptions +{ + /** + * @var string + */ + private $_description; + + /** + * Gets the description. + * + * @return string + */ + public function getDescription() + { + return $this->_description; + } + + /** + * Sets the description. + * + * @param string $description The description. + * + * @return none + */ + public function setDescription($description) + { + Validate::isString($description, 'description'); + + $this->_description = $description; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/CreateDeploymentOptions.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/CreateDeploymentOptions.php new file mode 100644 index 0000000..9e01714 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/CreateDeploymentOptions.php @@ -0,0 +1,113 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceManagement\Models; +use WindowsAzure\Common\Internal\Validate; + +/** + * The optional parameters for createDeployment API. + * + * @category Microsoft + * @package WindowsAzure\ServiceManagement\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class CreateDeploymentOptions +{ + /** + * Indicates whether to start the deployment immediately after it is created. + * + * @var boolean + */ + private $_startDeployment; + + /** + * Indicates whether to treat package validation warnings as errors. + * + * @var boolean + */ + private $_treatWarningsAsErrors; + + /** + * Constructs new CreateDeploymentOptions instance. + */ + public function __construct() + { + $this->_startDeployment = false; + $this->_treatWarningsAsErrors = false; + } + + /** + * Gets start deployment flag. + * + * @return boolean + */ + public function getStartDeployment() + { + return $this->_startDeployment; + } + + /** + * Sets start deployment flag. + * + * @param boolean $startDeployment Indicates whether to start the deployment + * immediately after it is created. + * + * @return none + */ + public function setStartDeployment($startDeployment) + { + Validate::isBoolean($startDeployment, 'startDeployment'); + + $this->_startDeployment = $startDeployment; + } + + /** + * Gets treat warnings as errors flag. + * + * @return boolean + */ + public function getTreatWarningsAsErrors() + { + return $this->_treatWarningsAsErrors; + } + + /** + * Sets treat warnings as errors flag. + * + * @param boolean $treatWarningsAsErrors Indicates whether to treat package + * validation warnings as errors. + * + * @return none + */ + public function setTreatWarningsAsErrors($treatWarningsAsErrors) + { + Validate::isBoolean($treatWarningsAsErrors, 'treatWarningsAsErrors'); + + $this->_treatWarningsAsErrors = $treatWarningsAsErrors; + } +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/CreateServiceOptions.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/CreateServiceOptions.php new file mode 100644 index 0000000..0ba11f9 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/CreateServiceOptions.php @@ -0,0 +1,131 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceManagement\Models; +use WindowsAzure\Common\Internal\Validate; + +/** + * Optional parameters for createStorageService API. + * + * @category Microsoft + * @package WindowsAzure\ServiceManagement\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class CreateServiceOptions +{ + /** + * @var string + */ + private $_location; + + /** + * @var string + */ + private $_affinityGroup; + + /** + * @var string + */ + private $_description; + + /** + * Gets the location. + * + * @return string + */ + public function getLocation() + { + return $this->_location; + } + + /** + * Sets the location. + * + * @param string $location The location. + * + * @return none + */ + public function setLocation($location) + { + Validate::isString($location, 'location'); + Validate::notNullOrEmpty($location, 'location'); + + $this->_location = $location; + } + + /** + * Gets the affinityGroup. + * + * @return string + */ + public function getAffinityGroup() + { + return $this->_affinityGroup; + } + + /** + * Sets the affinityGroup. + * + * @param string $affinityGroup The affinityGroup. + * + * @return none + */ + public function setAffinityGroup($affinityGroup) + { + Validate::isString($affinityGroup, 'affinityGroup'); + Validate::notNullOrEmpty($affinityGroup, 'affinityGroup'); + + $this->_affinityGroup = $affinityGroup; + } + + /** + * Gets the description. + * + * @return string + */ + public function getDescription() + { + return $this->_description; + } + + /** + * Sets the description. + * + * @param string $description The description. + * + * @return none + */ + public function setDescription($description) + { + Validate::isString($description, 'description'); + + $this->_description = $description; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/Deployment.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/Deployment.php new file mode 100644 index 0000000..dd307e8 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/Deployment.php @@ -0,0 +1,560 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceManagement\Models; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Utilities; + +/** + * Represents a Windows Azure deployment. + * + * @category Microsoft + * @package WindowsAzure\ServiceManagement\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class Deployment +{ + /** + * @var string + */ + private $_name; + + /** + * @var string + */ + private $_slot; + + /** + * @var string + */ + private $_privateId; + + /** + * @var string + */ + private $_status; + + /** + * @var string + */ + private $_label; + + /** + * @var string + */ + private $_configuration; + + /** + * @var array + */ + private $_roleInstanceList; + + /** + * @var integer + */ + private $_upgradeDomainCount; + + /** + * @var array + */ + private $_roleList; + + /** + * @var string + */ + private $_sdkVersion; + + /** + * @var array + */ + private $_inputEndpointList; + + /** + * @var boolean + */ + private $_locked; + + /** + * @var boolean + */ + private $_rollbackAllowed; + + /** + * @var UpgradeStatus + */ + private $_upgradeStatus; + + /** + * Creates a new Deployment from parsed response body. + * + * @param array $parsed The parsed response body in array representation. + * + * @return Deployment + */ + public static function create($parsed) + { + $result = new Deployment(); + $name = Utilities::tryGetValue($parsed, Resources::XTAG_NAME); + $label = Utilities::tryGetValue($parsed, Resources::XTAG_LABEL); + $url = Utilities::tryGetValue($parsed, Resources::XTAG_URL); + $locked = Utilities::tryGetValue( + $parsed, + Resources::XTAG_LOCKED + ); + $rollbackAllowed = Utilities::tryGetValue( + $parsed, + Resources::XTAG_ROLLBACK_ALLOWED + ); + $sdkVersion = Utilities::tryGetValue( + $parsed, + Resources::XTAG_SDK_VERSION + ); + $inputEndpointList = Utilities::tryGetKeysChainValue( + $parsed, + Resources::XTAG_INPUT_ENDPOINT_LIST, + Resources::XTAG_INPUT_ENDPOINT + ); + $roleList = Utilities::tryGetKeysChainValue( + $parsed, + Resources::XTAG_ROLE_LIST, + Resources::XTAG_ROLE + ); + $roleInstanceList = Utilities::tryGetKeysChainValue( + $parsed, + Resources::XTAG_ROLE_INSTANCE_LIST, + Resources::XTAG_ROLE_INSTANCE + ); + $status = Utilities::tryGetValue( + $parsed, + Resources::XTAG_STATUS + ); + $slot = Utilities::tryGetValue( + $parsed, + Resources::XTAG_DEPLOYMENT_SLOT + ); + $privateId = Utilities::tryGetValue( + $parsed, + Resources::XTAG_PRIVATE_ID + ); + $configuration = Utilities::tryGetValue( + $parsed, + Resources::XTAG_CONFIGURATION + ); + $upgradeDomainCount = Utilities::tryGetValue( + $parsed, + Resources::XTAG_UPGRADE_DOMAIN_COUNT + ); + $upgradeStatus = Utilities::tryGetValue( + $parsed, + Resources::XTAG_UPGRADE_STATUS + ); + + $result->setConfiguration($configuration); + $result->setLabel($label); + $result->setLocked(Utilities::toBoolean($locked)); + $result->setName($name); + $result->setPrivateId($privateId); + $result->setRollbackAllowed(Utilities::toBoolean($rollbackAllowed)); + $result->setSdkVersion($sdkVersion); + $result->setSlot($slot); + $result->setStatus($status); + $result->setUpgradeDomainCount(intval($upgradeDomainCount)); + $result->setUpgradeStatus(UpgradeStatus::create($upgradeStatus)); + $result->setUrl($url); + $result->setRoleInstanceList( + Utilities::createInstanceList( + Utilities::getArray($roleInstanceList), + 'WindowsAzure\ServiceManagement\Models\RoleInstance' + ) + ); + $result->setRoleList( + Utilities::createInstanceList( + Utilities::getArray($roleList), + 'WindowsAzure\ServiceManagement\Models\Role' + ) + ); + $result->setInputEndpointList( + Utilities::createInstanceList( + Utilities::getArray($inputEndpointList), + 'WindowsAzure\ServiceManagement\Models\InputEndpoint' + ) + ); + + return $result; + } + + /** + * Gets the deployment name. + * + * The user-supplied name for this deployment. + * + * @return string + */ + public function getName() + { + return $this->_name; + } + + /** + * Sets the deployment name. + * + * @param string $name The deployment name. + * + * @return none + */ + public function setName($name) + { + $this->_name = $name; + } + + /** + * Gets the deployment slot. + * + * The environment to which the hosted service is deployed, either staging or + * production. + * + * @return string + */ + public function getSlot() + { + return $this->_slot; + } + + /** + * Sets the deployment slot. + * + * @param string $slot The deployment slot. + * + * @return none + */ + public function setSlot($slot) + { + $this->_slot = $slot; + } + + /** + * Gets the deployment label. + * + * The user-supplied name of the deployment returned as a base-64 encoded string. + * This name can be used identify the deployment for your tracking purposes. + * + * @return string + */ + public function getLabel() + { + return $this->_label; + } + + /** + * Sets the deployment label. + * + * @param string $label The deployment label. + * + * @return none + */ + public function setLabel($label) + { + $this->_label = $label; + } + + /** + * Gets the deployment private Id. + * + * A unique identifier generated internally by Windows Azure for this deployment. + * + * @return string + */ + public function getPrivateId() + { + return $this->_privateId; + } + + /** + * Sets the deployment private Id. + * + * @param string $privateId The deployment privateId. + * + * @return none + */ + public function setPrivateId($privateId) + { + $this->_privateId = $privateId; + } + + /** + * Gets the deployment status. + * + * The status of the deployment. Possible values are: Running, Suspended, + * RunningTransitioning, SuspendedTransitioning, Starting, Suspending, Deploying, + * Deploying. + * + * @return string + */ + public function getStatus() + { + return $this->_status; + } + + /** + * Sets the deployment status. + * + * @param string $status The deployment status. + * + * @return none + */ + public function setStatus($status) + { + $this->_status = $status; + } + + /** + * Gets the deployment url. + * + * The URL used to access the hosted service. + * + * @return string + */ + public function getUrl() + { + return $this->_url; + } + + /** + * Sets the deployment url. + * + * @param string $url The deployment url. + * + * @return none + */ + public function setUrl($url) + { + $this->_url = $url; + } + + /** + * Gets the deployment configuration. + * + * The base-64 encoded configuration file of the deployment. + * + * @return string + */ + public function getConfiguration() + { + return $this->_configuration; + } + + /** + * Sets the configuration. + * + * @param string $configuration The deployment configuration. + * + * @return none + */ + public function setConfiguration($configuration) + { + $this->_configuration = $configuration; + } + + /** + * Gets the deployment role instance list. + * + * @return array + */ + public function getRoleInstanceList() + { + return $this->_roleInstanceList; + } + + /** + * Sets the deployment role instance list. + * + * @param array $roleInstanceList The deployment role instance list. + * + * @return none + */ + public function setRoleInstanceList($roleInstanceList) + { + $this->_roleInstanceList = $roleInstanceList; + } + + /** + * Gets the deployment upgrade domain count. + * + * @return integer + */ + public function getUpgradeDomainCount() + { + return $this->_upgradeDomainCount; + } + + /** + * Sets the deployment upgradeDomainCount. + * + * @param integer $upgradeDomainCount The deployment upgrade domain count. + * + * @return none + */ + public function setUpgradeDomainCount($upgradeDomainCount) + { + $this->_upgradeDomainCount = $upgradeDomainCount; + } + + /** + * Gets the deployment role list. + * + * Contains the provisioning details for the new virtual machine deployment. + * + * @return array + */ + public function getRoleList() + { + return $this->_roleList; + } + + /** + * Sets the deployment role list. + * + * @param array $roleList The deployment role list. + * + * @return none + */ + public function setRoleList($roleList) + { + $this->_roleList = $roleList; + } + + /** + * Gets the deployment SDK version. + * + * @return string + */ + public function getSdkVersion() + { + return $this->_sdkVersion; + } + + /** + * Sets the deployment SDK version. + * + * @param string $sdkVersion The deployment SDK version. + * + * @return none + */ + public function setSdkVersion($sdkVersion) + { + $this->_sdkVersion = $sdkVersion; + } + + /** + * Gets the deployment input endpoint list. + * + * @return array + */ + public function getInputEndpointList() + { + return $this->_inputEndpointList; + } + + /** + * Sets the deployment input endpoint list. + * + * @param array $inputEndpointList The deployment input endpoint list. + * + * @return none + */ + public function setInputEndpointList($inputEndpointList) + { + $this->_inputEndpointList = $inputEndpointList; + } + + /** + * Gets the deployment locked flag. + * + * @return boolean + */ + public function getLocked() + { + return $this->_locked; + } + + /** + * Sets the deployment locked flag. + * + * @param boolean $locked The deployment locked flag. + * + * @return none + */ + public function setLocked($locked) + { + $this->_locked = $locked; + } + + /** + * Gets the deployment rollback allowed flag. + * + * @return boolean + */ + public function getRollbackAllowed() + { + return $this->_rollbackAllowed; + } + + /** + * Sets the deployment rollbackAllowed. + * + * @param boolean $rollbackAllowed The deployment rollback allowed flag. + * + * @return none + */ + public function setRollbackAllowed($rollbackAllowed) + { + $this->_rollbackAllowed = $rollbackAllowed; + } + + /** + * Gets the deployment upgrade status. + * + * @return UpgradeStatus + */ + public function getUpgradeStatus() + { + return $this->_upgradeStatus; + } + + /** + * Sets the deployment upgrade status. + * + * @param UpgradeStatus $upgradeStatus The deployment upgrade status. + * + * @return none + */ + public function setUpgradeStatus($upgradeStatus) + { + $this->_upgradeStatus = $upgradeStatus; + } +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/DeploymentSlot.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/DeploymentSlot.php new file mode 100644 index 0000000..345f6cc --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/DeploymentSlot.php @@ -0,0 +1,61 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceManagement\Models; + +/** + * Valid deployment slots that can be used on Windows Azure. + * + * @category Microsoft + * @package WindowsAzure\ServiceManagement\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class DeploymentSlot +{ + const STAGING = 'staging'; + const PRODUCTION = 'production'; + + /** + * Validates the provided slot name. + * + * @param string $slot The deployment slot name. + * + * @return boolean + */ + public static function isValid($slot) + { + switch (strtolower($slot)) { + case self::STAGING: + case self::PRODUCTION: + return true; + + default: + return false; + } + } +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/DeploymentStatus.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/DeploymentStatus.php new file mode 100644 index 0000000..cc1361f --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/DeploymentStatus.php @@ -0,0 +1,61 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceManagement\Models; + +/** + * The possible values for deployment status. + * + * @category Microsoft + * @package WindowsAzure\ServiceManagement\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class DeploymentStatus +{ + const SUSPENDED = 'Suspended'; + const RUNNING = 'Running'; + + /** + * Validates the provided status. + * + * @param string $status The deployment status. + * + * @return boolean + */ + public static function isValid($status) + { + switch (strtolower($status)) { + case strtolower(self::SUSPENDED): + case strtolower(self::RUNNING): + return true; + + default: + return false; + } + } +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/GetAffinityGroupPropertiesResult.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/GetAffinityGroupPropertiesResult.php new file mode 100644 index 0000000..95287b1 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/GetAffinityGroupPropertiesResult.php @@ -0,0 +1,158 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceManagement\Models; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Utilities; + +/** + * The result of calling getAffinityGroupProperties API. + * + * @category Microsoft + * @package WindowsAzure\ServiceManagement\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class GetAffinityGroupPropertiesResult +{ + /** + * @var AffinityGroup + */ + private $_affinityGroup; + + /** + * @var array + */ + private $_hostedServices; + + /** + * @var array + */ + private $_storageServices; + + /** + * Creates GetAffinityGroupPropertiesResult from parsed response into array. + * + * @param array $parsed The parsed HTTP response body. + * + * @return GetAffinityGroupPropertiesResult + */ + public static function create($parsed) + { + $result = new GetAffinityGroupPropertiesResult(); + $hostedServices = Utilities::tryGetArray( + Resources::XTAG_HOSTED_SERVICES, + $parsed + ); + $storageServices = Utilities::tryGetArray( + Resources::XTAG_STORAGE_SERVICES, + $parsed + ); + + $result->_affinityGroup = new AffinityGroup($parsed); + + foreach ($hostedServices as $value) { + $service = new HostedService($value); + $result->_hostedServices[] = $service; + } + + foreach ($storageServices as $value) { + $service = new StorageService($value); + $result->_storageServices[] = $service; + } + + return $result; + } + + /** + * Gets the affinityGroup. + * + * @return AffinityGroup + */ + public function getAffinityGroup() + { + return $this->_affinityGroup; + } + + /** + * Sets the affinityGroup. + * + * @param AffinityGroup $affinityGroup The affinityGroup. + * + * @return none + */ + public function setAffinityGroup($affinityGroup) + { + $this->_affinityGroup = $affinityGroup; + } + + /** + * Gets the hostedServices. + * + * @return array + */ + public function getHostedServices() + { + return $this->_hostedServices; + } + + /** + * Sets the hostedServices. + * + * @param array $hostedServices The hostedServices. + * + * @return none + */ + public function setHostedServices($hostedServices) + { + $this->_hostedServices = $hostedServices; + } + + /** + * Gets the storageServices. + * + * @return array + */ + public function getStorageServices() + { + return $this->_storageServices; + } + + /** + * Sets the storageServices. + * + * @param array $storageServices The storageServices. + * + * @return none + */ + public function setStorageServices($storageServices) + { + $this->_storageServices = $storageServices; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/GetDeploymentOptions.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/GetDeploymentOptions.php new file mode 100644 index 0000000..77247a4 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/GetDeploymentOptions.php @@ -0,0 +1,106 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceManagement\Models; +use WindowsAzure\Common\Internal\Validate; +use WindowsAzure\Common\Internal\Resources; + +/** + * The parameters to get a deployment. + * + * @category Microsoft + * @package WindowsAzure\ServiceManagement\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class GetDeploymentOptions +{ + /** + * @var string + */ + private $_slot; + + /** + * @var string + */ + private $_deploymentName; + + + /** + * Gets the deployment slot. + * + * @return string + */ + public function getSlot() + { + return $this->_slot; + } + + /** + * Sets the deployment slot. + * + * @param string $slot The deployment slot name. + * + * @return none + */ + public function setSlot($slot) + { + Validate::isString($slot, 'slot'); + Validate::notNullOrEmpty($slot, 'slot'); + Validate::isTrue( + DeploymentSlot::isValid($slot), + sprintf(Resources::INVALID_SLOT, $slot) + ); + + $this->_slot = $slot; + } + + /** + * Gets the deployment name. + * + * @return string + */ + public function getDeploymentName() + { + return $this->_deploymentName; + } + + /** + * Sets the deployment name. + * + * @param string $deploymentName The deployment name. + * + * @return none + */ + public function setDeploymentName($deploymentName) + { + Validate::isString($deploymentName, 'deploymentName'); + Validate::notNullOrEmpty($deploymentName, 'deploymentName'); + + $this->_deploymentName = $deploymentName; + } +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/GetDeploymentResult.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/GetDeploymentResult.php new file mode 100644 index 0000000..8766de4 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/GetDeploymentResult.php @@ -0,0 +1,84 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceManagement\Models; + +/** + * The result of calling getDeployment API. + * + * @category Microsoft + * @package WindowsAzure\ServiceManagement\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class GetDeploymentResult +{ + /** + * @var Deployment + */ + private $_deployment; + + /** + * Creates a new GetDeploymentResult from parsed response body. + * + * @param array $parsed The parsed response body in array representation. + * + * @return GetDeploymentResult + * + * @static + */ + public static function create($parsed) + { + $result = new GetDeploymentResult(); + + $result->setDeployment(Deployment::create($parsed)); + + return $result; + } + + /** + * Gets the deployment instance. + * + * @return Deployment + */ + public function getDeployment() + { + return $this->_deployment; + } + + /** + * Sets the deployment. + * + * @param Deployment $deployment The deployment instance. + * + * @return none + */ + public function setDeployment($deployment) + { + $this->_deployment = $deployment; + } +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/GetHostedServicePropertiesOptions.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/GetHostedServicePropertiesOptions.php new file mode 100644 index 0000000..d2b2ed6 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/GetHostedServicePropertiesOptions.php @@ -0,0 +1,77 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceManagement\Models; +use WindowsAzure\Common\Internal\Validate; + +/** + * The optional parameter for getHostedServiceProperties API. + * + * @category Microsoft + * @package WindowsAzure\ServiceManagement\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class GetHostedServicePropertiesOptions +{ + /** + * @var boolean + */ + private $_embedDetail; + + /** + * Constructs new GetHostedServicePropertiesOptions instance. + */ + public function __construct() + { + $this->_embedDetail = false; + } + + /** + * Sets the embed detail flag. + * + * @param boolean $embedDetail The embed detail flag. + * + * @return none + */ + public function setEmbedDetail($embedDetail) + { + Validate::isBoolean($embedDetail); + + $this->_embedDetail = $embedDetail; + } + + /** + * Gets the embed detail flag. + * + * @return boolean + */ + public function getEmbedDetail() + { + return $this->_embedDetail; + } +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/GetHostedServicePropertiesResult.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/GetHostedServicePropertiesResult.php new file mode 100644 index 0000000..bc8d7e4 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/GetHostedServicePropertiesResult.php @@ -0,0 +1,87 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceManagement\Models; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Resources; + +/** + * The result of calling getHostedServiceProperties API. + * + * @category Microsoft + * @package WindowsAzure\ServiceManagement\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class GetHostedServicePropertiesResult +{ + /** + * @var HostedService + */ + private $_hostedService; + + /** + * Creates GetHostedServicePropertiesResult from parsed response. + * + * @param array $parsed The parsed response in array representation. + * + * @return GetHostedServicePropertiesResult + */ + public static function create($parsed) + { + $result = new GetHostedServicePropertiesResult(); + $properties = Utilities::tryGetValue( + $parsed, + Resources::XTAG_HOSTED_SERVICE_PROPERTIES + ); + $result->_hostedService = new HostedService($parsed, $properties); + + return $result; + } + + /** + * Gets the hostedService. + * + * @return HostedService + */ + public function getHostedService() + { + return $this->_hostedService; + } + + /** + * Sets the hostedService. + * + * @param HostedService $hostedService The hostedService. + * + * @return none + */ + public function setHostedService($hostedService) + { + $this->_hostedService = $hostedService; + } +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/GetOperationStatusResult.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/GetOperationStatusResult.php new file mode 100644 index 0000000..6c70b79 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/GetOperationStatusResult.php @@ -0,0 +1,190 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceManagement\Models; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\ServiceException; + +/** + * The result of calling getOperationStatus API. + * + * @category Microsoft + * @package WindowsAzure\ServiceManagement\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class GetOperationStatusResult +{ + /** + * @var string + */ + private $_id; + + /** + * @var string + */ + private $_status; + + /** + * @var string + */ + private $_httpStatusCode; + + /** + * @var ServiceException + */ + private $_error; + + /** + * Creates GetOperationStatusResult object from parsed response. + * + * @param array $parsed The parsed response. + * + * @return GetOperationStatusResult + */ + public static function create($parsed) + { + $result = new GetOperationStatusResult(); + + $result->_id = Utilities::tryGetValue( + $parsed, + Resources::XTAG_ID + ); + $result->_status = Utilities::tryGetValue( + $parsed, + Resources::XTAG_STATUS + ); + $result->_httpStatusCode = Utilities::tryGetValue( + $parsed, + Resources::XTAG_HTTP_STATUS_CODE + ); + $error = Utilities::tryGetValue( + $parsed, + Resources::XTAG_ERROR + ); + + if (!empty($error)) { + $code = Utilities::tryGetValue($error, Resources::XTAG_CODE); + $message = Utilities::tryGetValue($error, Resources::XTAG_MESSAGE); + + $result->_error = new ServiceException($code, $message); + } + + return $result; + } + + /** + * Gets the id. + * + * @return string + */ + public function getId() + { + return $this->_id; + } + + /** + * Sets the id. + * + * @param string $id The id. + * + * @return none + */ + public function setId($id) + { + $this->_id = $id; + } + + /** + * Gets the status. + * + * @return string + */ + public function getStatus() + { + return $this->_status; + } + + /** + * Sets the status. + * + * @param string $status The status. + * + * @return none + */ + public function setStatus($status) + { + $this->_status = $status; + } + + /** + * Gets the httpStatusCode. + * + * @return string + */ + public function getHttpStatusCode() + { + return $this->_httpStatusCode; + } + + /** + * Sets the httpStatusCode. + * + * @param string $httpStatusCode The httpStatusCode. + * + * @return none + */ + public function setHttpStatusCode($httpStatusCode) + { + $this->_httpStatusCode = $httpStatusCode; + } + + /** + * Gets the error. + * + * @return ServiceException + */ + public function getError() + { + return $this->_error; + } + + /** + * Sets the error. + * + * @param ServiceException $error The error. + * + * @return none + */ + public function setError($error) + { + $this->_error = $error; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/GetStorageServiceKeysResult.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/GetStorageServiceKeysResult.php new file mode 100644 index 0000000..50d664f --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/GetStorageServiceKeysResult.php @@ -0,0 +1,151 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceManagement\Models; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Utilities; + +/** + * The result of calling getStorageServiceKeys and regenerateStorageServiceKeys API. + * + * @category Microsoft + * @package WindowsAzure\ServiceManagement\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class GetStorageServiceKeysResult +{ + /** + * @var string + */ + private $_url; + + /** + * @var string + */ + private $_primary; + + /** + * @var string + */ + private $_secondary; + + /** + * Creates new GetStorageServiceKeysResult object from parsed response. + * + * @param array $parsed The HTTP parsed response into array representation. + * + * @return GetStorageServiceKeysResult + */ + public static function create($parsed) + { + $result = new GetStorageServiceKeysResult(); + $keys = Utilities::tryGetValue( + $parsed, + Resources::XTAG_STORAGE_SERVICE_KEYS + ); + $result->_url = Utilities::tryGetValue($parsed, Resources::XTAG_URL); + $result->_primary = Utilities::tryGetValue( + $keys, + Resources::XTAG_PRIMARY + ); + $result->_secondary = Utilities::tryGetValue( + $keys, + Resources::XTAG_SECONDARY + ); + + return $result; + } + + /** + * Gets the url. + * + * @return string + */ + public function getUrl() + { + return $this->_url; + } + + /** + * Sets the url. + * + * @param string $url The url. + * + * @return none + */ + public function setUrl($url) + { + $this->_url = $url; + } + + /** + * Gets the primary. + * + * @return string + */ + public function getPrimary() + { + return $this->_primary; + } + + /** + * Sets the primary. + * + * @param string $primary The primary. + * + * @return none + */ + public function setPrimary($primary) + { + $this->_primary = $primary; + } + + /** + * Gets the secondary. + * + * @return string + */ + public function getSecondary() + { + return $this->_secondary; + } + + /** + * Sets the secondary. + * + * @param string $secondary The secondary. + * + * @return none + */ + public function setSecondary($secondary) + { + $this->_secondary = $secondary; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/GetStorageServicePropertiesResult.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/GetStorageServicePropertiesResult.php new file mode 100644 index 0000000..769cbd3 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/GetStorageServicePropertiesResult.php @@ -0,0 +1,87 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceManagement\Models; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Resources; + +/** + * The result of calling getStorageServiceProperties API. + * + * @category Microsoft + * @package WindowsAzure\ServiceManagement\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class GetStorageServicePropertiesResult +{ + /** + * @var StorageService + */ + private $_storageService; + + /** + * Creates GetStorageServicePropertiesResult from parsed response. + * + * @param array $parsed The parsed response in array representation. + * + * @return GetStorageServicePropertiesResult + */ + public static function create($parsed) + { + $result = new GetStorageServicePropertiesResult(); + $properties = Utilities::tryGetValue( + $parsed, + Resources::XTAG_STORAGE_SERVICE_PROPERTIES + ); + $result->_storageService = new StorageService($parsed, $properties); + + return $result; + } + + /** + * Gets the storageService. + * + * @return StorageService + */ + public function getStorageService() + { + return $this->_storageService; + } + + /** + * Sets the storageService. + * + * @param StorageService $storageService The storageService. + * + * @return none + */ + public function setStorageService($storageService) + { + $this->_storageService = $storageService; + } +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/HostedService.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/HostedService.php new file mode 100644 index 0000000..f79d9de --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/HostedService.php @@ -0,0 +1,115 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceManagement\Models; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\ServiceManagement\Internal\WindowsAzureService; + +/** + * The hosted service class. + * + * @category Microsoft + * @package WindowsAzure\ServiceManagement\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class HostedService extends WindowsAzureService +{ + /** + * @var array + */ + private $_deployments; + + /** + * Constructs new hosted service object. + */ + public function __construct() + { + $sources = func_get_args(); + parent::__construct($sources); + + $this->_deployments = array(); + foreach ($sources as $source) { + $deployments = Utilities::tryGetKeysChainValue( + $source, + Resources::XTAG_DEPLOYMENTS, + Resources::XTAG_DEPLOYMENT + ); + + if (!empty($deployments)) { + $this->_deployments = Utilities::createInstanceList( + Utilities::getArray($deployments), + 'WindowsAzure\ServiceManagement\Models\Deployment' + ); + } + } + } + + /** + * Converts the current object into ordered array representation. + * + * @return array + */ + protected function toArray() + { + $arr = parent::toArray(); + $order = array( + Resources::XTAG_NAMESPACE, + Resources::XTAG_SERVICE_NAME, + Resources::XTAG_LABEL, + Resources::XTAG_DESCRIPTION, + Resources::XTAG_LOCATION, + Resources::XTAG_AFFINITY_GROUP + ); + $ordered = Utilities::orderArray($arr, $order); + + return $ordered; + } + + /** + * Gets the deployments array. + * + * @return array + */ + public function getDeployments() + { + return $this->_deployments; + } + + /** + * Sets the deployments array. + * + * @param array $deployments The deployments array. + * + * @return none + */ + public function setDeployments($deployments) + { + $this->_deployments = $deployments; + } +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/InputEndpoint.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/InputEndpoint.php new file mode 100644 index 0000000..0240e4e --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/InputEndpoint.php @@ -0,0 +1,152 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceManagement\Models; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Utilities; + +/** + * Represents a Windows Azure deployment input endpoint. + * + * @category Microsoft + * @package WindowsAzure\ServiceManagement\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class InputEndpoint +{ + /** + * @var string + */ + private $_roleName; + + /** + * @var string + */ + private $_vip; + + /** + * @var string + */ + private $_port; + + /** + * Creates a new InputEndpoint from parsed response body. + * + * @param array $parsed The parsed response body in array representation. + * + * @return InputEndpoint + */ + public static function create($parsed) + { + $inputEndpoint = new InputEndpoint(); + $vip = Utilities::tryGetValue($parsed, Resources::XTAG_VIP); + $port = Utilities::tryGetValue($parsed, Resources::XTAG_PORT); + $roleName = Utilities::tryGetValue( + $parsed, + Resources::XTAG_ROLE_NAME + ); + + $inputEndpoint->setPort($port); + $inputEndpoint->setRoleName($roleName); + $inputEndpoint->setVip($vip); + + return $inputEndpoint; + } + + /** + * Gets the input endpoint role name. + * + * The name of the role. + * + * @return string + */ + public function getRoleName() + { + return $this->_roleName; + } + + /** + * Sets the input endpoint role name. + * + * @param string $roleName The input endpoint role name. + * + * @return none + */ + public function setRoleName($roleName) + { + $this->_roleName = $roleName; + } + + /** + * Gets the input endpoint VIP. + * + * The virtual IP address that this input endpoint is exposed on. + * + * @return string + */ + public function getVip() + { + return $this->_vip; + } + + /** + * Sets the input endpoint VIP. + * + * @param string $vip The input endpoint VIP. + * + * @return none + */ + public function setVip($vip) + { + $this->_vip = $vip; + } + + /** + * Gets the input endpoint port. + * + * The port this input endpoint is exposed on. + * + * @return string + */ + public function getPort() + { + return $this->_port; + } + + /** + * Sets the input endpoint port. + * + * @param string $port The input endpoint port. + * + * @return none + */ + public function setPort($port) + { + $this->_port = $port; + } +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/KeyType.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/KeyType.php new file mode 100644 index 0000000..9f7f248 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/KeyType.php @@ -0,0 +1,44 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceManagement\Models; + +/** + * The storage account key type. + * + * @category Microsoft + * @package WindowsAzure\ServiceManagement\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class KeyType +{ + const PRIMARY_KEY = 'Primary'; + const SECONDARY_KEY = 'Secondary'; +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/ListAffinityGroupsResult.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/ListAffinityGroupsResult.php new file mode 100644 index 0000000..5867f28 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/ListAffinityGroupsResult.php @@ -0,0 +1,94 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceManagement\Models; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Resources; + +/** + * The result of calling listAfinityGroups API. + * + * @category Microsoft + * @package WindowsAzure\ServiceManagement\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class ListAffinityGroupsResult +{ + /** + * @var array + */ + private $_affinityGroups; + + /** + * Creates new ListAffinityGroupsResult from parsed response body. + * + * @param array $parsed The parsed response body. + * + * @return ListAffinityGroupsResult + */ + public static function create($parsed) + { + $result = new ListAffinityGroupsResult(); + + $result->_affinityGroups = array(); + $entries = Utilities::tryGetArray( + Resources::XTAG_AFFINITY_GROUP, + $parsed + ); + + foreach ($entries as $value) { + $result->_affinityGroups[] = new AffinityGroup($value); + } + + return $result; + } + + /** + * Gets affinity groups. + * + * @return array + */ + public function getAffinityGroups() + { + return $this->_affinityGroups; + } + + /** + * Sets affinity groups. + * + * @param array $affinityGroups The affinity groups. + * + * @return none + */ + public function setAffinityGroups($affinityGroups) + { + $this->_affinityGroups = $affinityGroups; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/ListHostedServicesResult.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/ListHostedServicesResult.php new file mode 100644 index 0000000..ad60772 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/ListHostedServicesResult.php @@ -0,0 +1,99 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceManagement\Models; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Resources; + +/** + * The result of calling listHostedServices API. + * + * @category Microsoft + * @package WindowsAzure\ServiceManagement\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class ListHostedServicesResult +{ + /** + * @var array + */ + private $_hostedServices; + + /** + * Creates new ListHostedServicesResult from parsed response body. + * + * @param array $parsed The parsed response body. + * + * @return ListHostedServicesResult + */ + public static function create($parsed) + { + $result = new ListHostedServicesResult(); + $result->_hostedServices = array(); + $rowHostedServices = Utilities::tryGetArray( + Resources::XTAG_HOSTED_SERVICE, + $parsed + ); + + foreach ($rowHostedServices as $rowHostedService) { + $properties = Utilities::tryGetArray( + Resources::XTAG_HOSTED_SERVICE_PROPERTIES, + $rowHostedService + ); + $hostedService = new HostedService( + $rowHostedService, + $properties + ); + $result->_hostedServices[] = $hostedService; + } + + return $result; + } + + /** + * Gets hosted services. + * + * @return array + */ + public function getHostedServices() + { + return $this->_hostedServices; + } + + /** + * Sets hosted services. + * + * @param array $hostedServices The hosted services. + * + * @return none + */ + public function setHostedServices($hostedServices) + { + $this->_hostedServices = $hostedServices; + } +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/ListLocationsResult.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/ListLocationsResult.php new file mode 100644 index 0000000..35ce099 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/ListLocationsResult.php @@ -0,0 +1,100 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceManagement\Models; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Resources; + +/** + * The result of calling listLocations API. + * + * @category Microsoft + * @package WindowsAzure\ServiceManagement\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class ListLocationsResult +{ + /** + * @var array + */ + private $_locations; + + /** + * Creates new ListLocationsResult from parsed response body. + * + * @param array $parsed The parsed response body. + * + * @return ListLocationsResult + */ + public static function create($parsed) + { + $result = new ListLocationsResult(); + + $result->_locations = array(); + $entries = array(); + + if (!empty($parsed)) { + $entries = Utilities::getArray($parsed[Resources::XTAG_LOCATION]); + } + + foreach ($entries as $value) { + $location = new Location(); + $location->setName(Utilities::tryGetValue($value, Resources::XTAG_NAME)); + $location->setDisplayName( + Utilities::tryGetValue($value, Resources::XTAG_DISPLAY_NAME) + ); + $result->_locations[] = $location; + } + + return $result; + } + + /** + * Gets locations. + * + * @return array + */ + public function getLocations() + { + return $this->_locations; + } + + /** + * Sets locations. + * + * @param array $locations The locations. + * + * @return none + */ + public function setLocations($locations) + { + $this->_locations = $locations; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/ListStorageServicesResult.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/ListStorageServicesResult.php new file mode 100644 index 0000000..bc1504d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/ListStorageServicesResult.php @@ -0,0 +1,90 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceManagement\Models; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Resources; + +/** + * The result of calling listStorageServices API. + * + * @category Microsoft + * @package WindowsAzure\ServiceManagement\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class ListStorageServicesResult +{ + /** + * @var array + */ + private $_storageServices; + + /** + * Creates new ListStorageServicesResult from parsed response body. + * + * @param array $parsed The parsed response body. + * + * @return ListStorageServicesResult + */ + public static function create($parsed) + { + $result = new ListStorageServicesResult(); + $rowStorageServices = Utilities::tryGetArray( + Resources::XTAG_STORAGE_SERVICE, + $parsed + ); + + foreach ($rowStorageServices as $rowStorageService) { + $result->_storageServices[] = new StorageService($rowStorageService); + } + + return $result; + } + + /** + * Gets storage accounts. + * + * @return array + */ + public function getStorageServices() + { + return $this->_storageServices; + } + + /** + * Sets storage accounts. + * + * @param array $storageServices The storage accounts. + * + * @return none + */ + public function setStorageServices($storageServices) + { + $this->_storageServices = $storageServices; + } +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/Location.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/Location.php new file mode 100644 index 0000000..45e63aa --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/Location.php @@ -0,0 +1,95 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceManagement\Models; + +/** + * The location class. + * + * @category Microsoft + * @package WindowsAzure\ServiceManagement\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class Location +{ + /** + * @var string + */ + private $_name; + + /** + * @var string + */ + private $_displayName; + + /** + * Gets the name. + * + * @return string + */ + public function getName() + { + return $this->_name; + } + + /** + * Sets the name. + * + * @param string $name The name. + * + * @return none + */ + public function setName($name) + { + $this->_name = $name; + } + + /** + * Gets the displayName. + * + * @return string + */ + public function getDisplayName() + { + return $this->_displayName; + } + + /** + * Sets the displayName. + * + * @param string $displayName The displayName. + * + * @return none + */ + public function setDisplayName($displayName) + { + $this->_displayName = $displayName; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/Mode.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/Mode.php new file mode 100644 index 0000000..9b0b317 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/Mode.php @@ -0,0 +1,61 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceManagement\Models; + +/** + * The possible values for deployment change mode. + * + * @category Microsoft + * @package WindowsAzure\ServiceManagement\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class Mode +{ + const AUTO = 'auto'; + const MANUAL = 'manual'; + + /** + * Validates the provided mode. + * + * @param string $mode The deployment change mode. + * + * @return boolean + */ + public static function isValid($mode) + { + switch (strtolower($mode)) { + case self::AUTO: + case self::MANUAL: + return true; + + default: + return false; + } + } +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/OperationStatus.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/OperationStatus.php new file mode 100644 index 0000000..81b0aef --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/OperationStatus.php @@ -0,0 +1,45 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceManagement\Models; + +/** + * The possible staus values of asynchronous request. + * + * @category Microsoft + * @package WindowsAzure\ServiceManagement\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class OperationStatus +{ + const IN_PROGRESS = 'InProgress'; + const SUCCEEDED = 'Succeeded'; + const FAILED = 'Failed'; +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/Role.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/Role.php new file mode 100644 index 0000000..c900833 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/Role.php @@ -0,0 +1,125 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceManagement\Models; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Utilities; + +/** + * Represents a Windows Azure deployment role. + * + * @category Microsoft + * @package WindowsAzure\ServiceManagement\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class Role +{ + /** + * @var string + */ + private $_roleName; + + /** + * @var string + */ + private $_osVersion; + + /** + * Creates a new Role from parsed response body. + * + * @param array $parsed The parsed response body in array representation. + * + * @return Role + */ + public static function create($parsed) + { + $role = new Role(); + $roleName = Utilities::tryGetValue( + $parsed, + Resources::XTAG_ROLE_NAME + ); + $osVersion = Utilities::tryGetValue( + $parsed, + Resources::XTAG_OS_VERSION + ); + + $role->setOsVersion($osVersion); + $role->setRoleName($roleName); + + return $role; + } + + /** + * Gets the role name. + * + * The name of the role. + * + * @return string + */ + public function getRoleName() + { + return $this->_roleName; + } + + /** + * Sets the role name. + * + * @param string $roleName The role name. + * + * @return none + */ + public function setRoleName($roleName) + { + $this->_roleName = $roleName; + } + + /** + * Gets the role OS version. + * + * The version of the Windows Azure Guest Operating System on which this role's + * instances are running. + * + * @return string + */ + public function getOsVersion() + { + return $this->_osVersion; + } + + /** + * Sets the role OS version. + * + * @param string $osVersion The role OS version. + * + * @return none + */ + public function setOsVersion($osVersion) + { + $this->_osVersion = $osVersion; + } +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/RoleInstance.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/RoleInstance.php new file mode 100644 index 0000000..016cd41 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/RoleInstance.php @@ -0,0 +1,341 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceManagement\Models; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Utilities; + +/** + * Represents a Windows Azure deployment role instance. + * + * @category Microsoft + * @package WindowsAzure\ServiceManagement\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class RoleInstance +{ + /** + * @var string + */ + private $_roleName; + + /** + * @var string + */ + private $_instanceName; + + /** + * @var string + */ + private $_instanceStatus; + + /** + * @var integer + */ + private $_instanceUpgradeDomain; + + /** + * @var integer + */ + private $_instanceFaultDomain; + + /** + * @var string + */ + private $_instanceSize; + + /** + * @var string + */ + private $_instanceStateDetails; + + /** + * @var string + */ + private $_instanceErrorCode; + + /** + * Creates a new RoleInstance from parsed response body. + * + * @param array $parsed The parsed response body in array representation. + * + * @return RoleInstance + */ + public static function create($parsed) + { + $roleInstance = new RoleInstance(); + $roleName = Utilities::tryGetValue( + $parsed, + Resources::XTAG_ROLE_NAME + ); + $instanceName = Utilities::tryGetValue( + $parsed, + Resources::XTAG_INSTANCE_NAME + ); + $instanceStatus = Utilities::tryGetValue( + $parsed, + Resources::XTAG_INSTANCE_STATUS + ); + $instanceUpgradeDomain = Utilities::tryGetValue( + $parsed, + Resources::XTAG_INSTANCE_UPGRADE_DOMAIN + ); + $instanceFaultDomain = Utilities::tryGetValue( + $parsed, + Resources::XTAG_INSTANCE_FAULT_DOMAIN + ); + $instanceSize = Utilities::tryGetValue( + $parsed, + Resources::XTAG_INSTANCE_SIZE + ); + $instanceStateDetails = Utilities::tryGetValue( + $parsed, + Resources::XTAG_INSTANCE_STATE_DETAILS + ); + $instanceErrorCode = Utilities::tryGetValue( + $parsed, + Resources::XTAG_INSTANCE_ERROR_CODE + ); + + $roleInstance->setInstanceErrorCode($instanceErrorCode); + $roleInstance->setInstanceFaultDomain(intval($instanceFaultDomain)); + $roleInstance->setInstanceName($instanceName); + $roleInstance->setInstanceSize($instanceSize); + $roleInstance->setInstanceStateDetails($instanceStateDetails); + $roleInstance->setInstanceStatus($instanceStatus); + $roleInstance->setInstanceUpgradeDomain(intval($instanceUpgradeDomain)); + $roleInstance->setRoleName($roleName); + + return $roleInstance; + } + + /** + * Gets the role name. + * + * The name of the role. + * + * @return string + */ + public function getRoleName() + { + return $this->_roleName; + } + + /** + * Sets the role name. + * + * @param string $roleName The role name. + * + * @return none + */ + public function setRoleName($roleName) + { + $this->_roleName = $roleName; + } + + /** + * Gets the instance name. + * + * The name of the specific role instance (if any). + * + * @return string + */ + public function getInstanceName() + { + return $this->_instanceName; + } + + /** + * Sets the instance name. + * + * @param string $instanceName The instance name. + * + * @return none + */ + public function setInstanceName($instanceName) + { + $this->_instanceName = $instanceName; + } + + /** + * Gets the instance status. + * + * The current status of this instance. + * + * @return string + */ + public function getInstanceStatus() + { + return $this->_instanceStatus; + } + + /** + * Sets the instance status. + * + * @param string $instanceStatus The instance status. + * + * @return none + */ + public function setInstanceStatus($instanceStatus) + { + $this->_instanceStatus = $instanceStatus; + } + + /** + * Gets the instance upgrade domain. + * + * The upgrade domain that this role instance belongs to. During an upgrade + * deployment, all roles in the same upgrade domain are upgraded at the same + * time. + * + * @return integer + */ + public function getInstanceUpgradeDomain() + { + return $this->_instanceUpgradeDomain; + } + + /** + * Sets the instance upgrade domain. + * + * @param integer $instanceUpgradeDomain The instance upgrade domain. + * + * @return none + */ + public function setInstanceUpgradeDomain($instanceUpgradeDomain) + { + $this->_instanceUpgradeDomain = $instanceUpgradeDomain; + } + + /** + * Gets the instance fault domain. + * + * The fault domain that this role instance belongs to. Role instances in the + * same fault domain may be vulnerable to the failure of a single piece of + * hardware. + * + * @return integer + */ + public function getInstanceFaultDomain() + { + return $this->_instanceFaultDomain; + } + + /** + * Sets the instance fault domain. + * + * @param integer $instanceFaultDomain The instance fault domain. + * + * @return none + */ + public function setInstanceFaultDomain($instanceFaultDomain) + { + $this->_instanceFaultDomain = $instanceFaultDomain; + } + + /** + * Gets the instance size. + * + * The size of the role instance. Possible values are: ExtraSmall, Small, Medium, + * Large, ExtraLarge. + * + * @return string + */ + public function getInstanceSize() + { + return $this->_instanceSize; + } + + /** + * Sets the instance size. + * + * @param string $instanceSize The instance size. + * + * @return none + */ + public function setInstanceSize($instanceSize) + { + $this->_instanceSize = $instanceSize; + } + + /** + * Gets the instance state details. + * + * The instance state is returned as an English human-readable string that, when + * present, provides a snapshot of the state of the virtual machine at the time + * the operation was called. For example, when the instance is first being + * initialized a "Preparing Windows for first use." could be returned. + * + * @return string + */ + public function getInstanceStateDetails() + { + return $this->_instanceStateDetails; + } + + /** + * Sets the instance state details. + * + * @param string $instanceStateDetails The instance state details. + * + * @return none + */ + public function setInstanceStateDetails($instanceStateDetails) + { + $this->_instanceStateDetails = $instanceStateDetails; + } + + /** + * Gets the instance error code. + * + * Error code of the latest role or VM start. For VMRoles the error codes are: + * WaitTimeout, VhdTooLarge, AzureInternalError. + * + * For web and worker roles this field returns an error code that can be provided + * to Windows Azure support to assist in resolution of errors. Typically this + * field will be empty. + * + * @return string + */ + public function getInstanceErrorCode() + { + return $this->_instanceErrorCode; + } + + /** + * Sets the instance error code. + * + * @param string $instanceErrorCode The instance error code. + * + * @return none + */ + public function setInstanceErrorCode($instanceErrorCode) + { + $this->_instanceErrorCode = $instanceErrorCode; + } +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/StorageService.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/StorageService.php new file mode 100644 index 0000000..42c4322 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/StorageService.php @@ -0,0 +1,199 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceManagement\Models; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\ServiceManagement\Internal\WindowsAzureService; + +/** + * The storage service class. + * + * @category Microsoft + * @package WindowsAzure\ServiceManagement\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class StorageService extends WindowsAzureService +{ + /** + * @var string + */ + private $_blobEndpointUri; + + /** + * @var string + */ + private $_queueEndpointUri; + + /** + * @var string + */ + private $_tableEndpointUri; + + /** + * @var string + */ + private $_status; + + /** + * Constructs new storage service object. + */ + public function __construct() + { + $sources = func_get_args(); + parent::__construct($sources); + + foreach ($sources as $source) { + $this->setStatus( + Utilities::tryGetValue( + $source, + Resources::XTAG_STATUS, + $this->getStatus() + ) + ); + + $endpoints = Utilities::tryGetKeysChainValue( + $source, + Resources::XTAG_ENDPOINTS, + Resources::XTAG_ENDPOINT + ); + $this->setBlobEndpointUri(Utilities::tryGetValue($endpoints, 0)); + $this->setQueueEndpointUri(Utilities::tryGetValue($endpoints, 1)); + $this->setTableEndpointUri(Utilities::tryGetValue($endpoints, 2)); + } + } + + /** + * Converts the current object into ordered array representation. + * + * @return array + */ + protected function toArray() + { + $arr = parent::toArray(); + $order = array( + Resources::XTAG_NAMESPACE, + Resources::XTAG_SERVICE_NAME, + Resources::XTAG_DESCRIPTION, + Resources::XTAG_LABEL, + Resources::XTAG_AFFINITY_GROUP, + Resources::XTAG_LOCATION + ); + $ordered = Utilities::orderArray($arr, $order); + + return $ordered; + } + + /** + * Gets the status. + * + * @return string + */ + public function getStatus() + { + return $this->_status; + } + + /** + * Sets the status. + * + * @param string $status The status. + * + * @return none + */ + public function setStatus($status) + { + $this->_status = $status; + } + + /** + * Gets storage service blob endpoint uri. + * + * @return string + */ + public function getBlobEndpointUri() + { + return $this->_blobEndpointUri; + } + + /** + * Gets storage service queue endpoint uri. + * + * @return string + */ + public function getQueueEndpointUri() + { + return $this->_queueEndpointUri; + } + + /** + * Gets storage service table endpoint uri. + * + * @return string + */ + public function getTableEndpointUri() + { + return $this->_tableEndpointUri; + } + + /** + * Gets storage service blob endpoint uri. + * + * @param string $blobEndpointUri The endpoint URI. + * + * @return string + */ + public function setBlobEndpointUri($blobEndpointUri) + { + $this->_blobEndpointUri = $blobEndpointUri; + } + + /** + * Gets storage service queue endpoint uri. + * + * @param string $queueEndpointUri The endpoint URI. + * + * @return string + */ + public function setQueueEndpointUri($queueEndpointUri) + { + $this->_queueEndpointUri = $queueEndpointUri; + } + + /** + * Gets storage service table endpoint uri. + * + * @param string $tableEndpointUri The endpoint URI. + * + * @return string + */ + public function setTableEndpointUri($tableEndpointUri) + { + $this->_tableEndpointUri = $tableEndpointUri; + } +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/UpdateServiceOptions.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/UpdateServiceOptions.php new file mode 100644 index 0000000..1ecd7f5 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/UpdateServiceOptions.php @@ -0,0 +1,100 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceManagement\Models; +use WindowsAzure\Common\Internal\Validate; + +/** + * The optional parameters for updateStorageService API. + * + * @category Microsoft + * @package WindowsAzure\ServiceManagement\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class UpdateServiceOptions +{ + /** + * @var string + */ + private $_label; + + /** + * @var string + */ + private $_description; + + /** + * Gets the label. + * + * @return string + */ + public function getLabel() + { + return $this->_label; + } + + /** + * Sets the label. + * + * @param string $label The label. + * + * @return none + */ + public function setLabel($label) + { + Validate::isString($label, 'label'); + + $this->_label = $label; + } + + /** + * Gets the description. + * + * @return string + */ + public function getDescription() + { + return $this->_description; + } + + /** + * Sets the description. + * + * @param string $description The description. + * + * @return none + */ + public function setDescription($description) + { + Validate::isString($description, 'description'); + + $this->_description = $description; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/UpgradeDeploymentOptions.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/UpgradeDeploymentOptions.php new file mode 100644 index 0000000..ac57444 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/UpgradeDeploymentOptions.php @@ -0,0 +1,72 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceManagement\Models; +use WindowsAzure\Common\Internal\Validate; + +/** + * The optional parameters for upgradeDeployment API. + * + * @category Microsoft + * @package WindowsAzure\ServiceManagement\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class UpgradeDeploymentOptions extends GetDeploymentOptions +{ + /** + * @var string + */ + private $_roleToUpgrade; + + /** + * Gets the role to upgrade name. + * + * The name of the specific role to upgrade. + * + * @return string + */ + public function getRoleToUpgrade() + { + return $this->_roleToUpgrade; + } + + /** + * Sets the role to upgrade name. + * + * @param string $roleToUpgrade The role to upgrade name. + * + * @return none + */ + public function setRoleToUpgrade($roleToUpgrade) + { + Validate::isString($roleToUpgrade, 'roleToUpgrade'); + Validate::notNullOrEmpty($roleToUpgrade, 'roleToUpgrade'); + + $this->_roleToUpgrade = $roleToUpgrade; + } +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/UpgradeStatus.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/UpgradeStatus.php new file mode 100644 index 0000000..e862f58 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/Models/UpgradeStatus.php @@ -0,0 +1,163 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceManagement\Models; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Utilities; + +/** + * Holds a deployment upgrade status. + * + * @category Microsoft + * @package WindowsAzure\ServiceManagement\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class UpgradeStatus +{ + /** + * @var string + */ + private $_upgradeType; + + /** + * @var string + */ + private $_currentUpgradeDomainState; + + /** + * @var integer + */ + private $_currentUpgradeDomain; + + /** + * Creates a new UpgradeStatus object from the parsed response. + * + * @param array $parsed The parsed response body in array representation + * + * @return \WindowsAzure\ServiceManagement\Models\UpgradeStatus + */ + public static function create($parsed) + { + $result = new UpgradeStatus(); + $upgradeType = Utilities::tryGetValue( + $parsed, + Resources::XTAG_UPGRADE_TYPE + ); + $currentUpgradeDomainState = Utilities::tryGetValue( + $parsed, + Resources::XTAG_CURRENT_UPGRADE_DOMAIN_STATE + ); + $currentUpgradeDomain = Utilities::tryGetValue( + $parsed, + Resources::XTAG_CURRENT_UPGRADE_DOMAIN + ); + + $result->setCurrentUpgradeDomain(intval($currentUpgradeDomain)); + $result->setCurrentUpgradeDomainState($currentUpgradeDomainState); + $result->setUpgradeType($upgradeType); + + return $result; + } + + /** + * Gets the deployment upgrade type. + * + * The upgrade type designated for this deployment. Possible values are Auto and + * Manual. + * + * @return string + */ + public function getUpgradeType() + { + return $this->_upgradeType; + } + + /** + * Sets the deployment upgrade type. + * + * @param string $upgradeType The deployment upgrade type. + * + * @return none + */ + public function setUpgradeType($upgradeType) + { + $this->_upgradeType = $upgradeType; + } + + /** + * Gets the deployment current upgrade domain state. + * + * The state of the current upgrade domain. Possible values are Before and + * During. + * + * @return string + */ + public function getCurrentUpgradeDomainState() + { + return $this->_currentUpgradeDomainState; + } + + /** + * Sets the deployment current upgrade domain state. + * + * @param string $currentUpgradeDomainState The deployment current upgrade domain + * state. + * + * @return none + */ + public function setCurrentUpgradeDomainState($currentUpgradeDomainState) + { + $this->_currentUpgradeDomainState = $currentUpgradeDomainState; + } + + /** + * Gets the deployment current upgrade domain. + * + * An integer value that identifies the current upgrade domain. Upgrade domains + * are identified with a zero-based index: the first upgrade domain has an ID of + * 0, the second has an ID of 1, and so on. + * + * @return integer + */ + public function getCurrentUpgradeDomain() + { + return $this->_currentUpgradeDomain; + } + + /** + * Sets the deployment current upgrade domain. + * + * @param integer $currentUpgradeDomain The deployment current upgrade domain. + * + * @return none + */ + public function setCurrentUpgradeDomain($currentUpgradeDomain) + { + $this->_currentUpgradeDomain = $currentUpgradeDomain; + } +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/ServiceManagementRestProxy.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/ServiceManagementRestProxy.php new file mode 100644 index 0000000..b599a64 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceManagement/ServiceManagementRestProxy.php @@ -0,0 +1,1534 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceManagement; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Validate; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\RestProxy; +use WindowsAzure\Common\Internal\Http\HttpCallContext; +use WindowsAzure\Common\Internal\Serialization\XmlSerializer; +use WindowsAzure\ServiceManagement\Internal\IServiceManagement; +use WindowsAzure\ServiceManagement\Models\CreateAffinityGroupOptions; +use WindowsAzure\ServiceManagement\Models\AffinityGroup; +use WindowsAzure\ServiceManagement\Models\ListAffinityGroupsResult; +use WindowsAzure\ServiceManagement\Models\GetAffinityGroupPropertiesResult; +use WindowsAzure\ServiceManagement\Models\ListLocationsResult; +use WindowsAzure\ServiceManagement\Models\StorageService; +use WindowsAzure\ServiceManagement\Models\ListStorageServicesResult; +use WindowsAzure\ServiceManagement\Models\GetOperationStatusResult; +use WindowsAzure\ServiceManagement\Models\AsynchronousOperationResult; +use WindowsAzure\ServiceManagement\Models\UpdateServiceOptions; +use WindowsAzure\ServiceManagement\Models\GetStorageServicePropertiesResult; +use WindowsAzure\ServiceManagement\Models\GetStorageServiceKeysResult; +use WindowsAzure\ServiceManagement\Models\ListHostedServicesResult; +use WindowsAzure\ServiceManagement\Models\HostedService; +use WindowsAzure\ServiceManagement\Models\GetHostedServicePropertiesOptions; +use WindowsAzure\ServiceManagement\Models\GetHostedServicePropertiesResult; +use WindowsAzure\ServiceManagement\Models\DeploymentSlot; +use WindowsAzure\ServiceManagement\Models\CreateDeploymentOptions; +use WindowsAzure\ServiceManagement\Models\GetDeploymentResult; +use WindowsAzure\ServiceManagement\Models\DeploymentStatus; +use WindowsAzure\ServiceManagement\Models\Mode; + +/** + * This class constructs HTTP requests and receive HTTP responses for service + * management service layer. + * + * @category Microsoft + * @package WindowsAzure\ServiceManagement + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class ServiceManagementRestProxy extends RestProxy + implements IServiceManagement +{ + /** + * @var string + */ + private $_subscriptionId; + + /** + * Sends an order request for the specified role instance. + * + * @param string $name The hosted service name. + * @param string $roleName The role instance name. + * @param GetDeploymentOptions $options The optional parameters. + * @param string $order The order name which is used as value + * for query parameter 'comp'. + * + * @return AsynchronousOperationResult + */ + private function _sendRoleInstanceOrder($name, $roleName, $options, $order) + { + Validate::isString($name, 'name'); + Validate::notNullOrEmpty($name, 'name'); + Validate::isString($roleName, 'roleName'); + Validate::notNullOrEmpty($roleName, 'roleName'); + Validate::notNullOrEmpty($options, 'options'); + + $context = new HttpCallContext(); + $context->setMethod(Resources::HTTP_POST); + $context->setPath($this->_getRoleInstancePath($name, $options, $roleName)); + $context->addStatusCode(Resources::STATUS_ACCEPTED); + $context->addQueryParameter(Resources::QP_COMP, $order); + $context->addHeader(Resources::CONTENT_TYPE, Resources::XML_CONTENT_TYPE); + $context->addHeader(Resources::CONTENT_LENGTH_NO_SPACE, 0); + + $response = $this->sendContext($context); + + return AsynchronousOperationResult::create($response->getHeader()); + } + + /** + * Constructs URI path for given service management resource. + * + * @param string $serviceManagementResource The resource name. + * @param string $name The service name. + * + * @return string + */ + private function _getPath($serviceManagementResource, $name) + { + $path = $this->_subscriptionId . '/' . $serviceManagementResource; + + if (!is_null($name)) { + $path .= '/' . $name; + } + + return $path; + } + + /** + * Constructs URI path for locations. + * + * @return string + */ + private function _getLocationPath() + { + return $this->_getPath('locations', null); + } + + /** + * Constructs URI path for affinity group. + * + * @param string $name The affinity group name. + * + * @return string + */ + private function _getAffinityGroupPath($name = null) + { + return $this->_getPath('affinitygroups', $name); + } + + /** + * Constructs URI path for storage service. + * + * @param string $name The storage service name. + * + * @return string + */ + private function _getStorageServicePath($name = null) + { + return $this->_getPath('services/storageservices', $name); + } + + /** + * Constructs URI path for hosted service. + * + * @param string $name The hosted service name. + * + * @return string + */ + private function _getHostedServicePath($name = null) + { + return $this->_getPath('services/hostedservices', $name); + } + + /** + * Constructs URI path for deployment slot. + * + * @param string $name The hosted service name. + * @param string $slot The deployment slot name. + * + * @return string + */ + private function _getDeploymentPathUsingSlot($name, $slot) + { + $path = "services/hostedservices/$name/deploymentslots"; + return $this->_getPath($path, $slot); + } + + /** + * Constructs URI path for deployment slot. + * + * @param string $name The hosted service name. + * @param string $deploymentName The deployment slot name. + * + * @return string + */ + private function _getDeploymentPathUsingName($name, $deploymentName) + { + $path = "services/hostedservices/$name/deployments"; + return $this->_getPath($path, $deploymentName); + } + + /** + * Gets role instance path. + * + * @param string $name The hosted service name. + * @param GetDeploymentOptions $options The get deployment options. + * @param string $roleName The role instance name. + * + * @return string + */ + private function _getRoleInstancePath($name, $options, $roleName) + { + $path = $this->_getDeploymentPath($name, $options) . '/roleinstances'; + return "$path/$roleName"; + } + + /** + * Gets the deployment URI path using the slot or name. + * + * @param string $name The hosted service name. + * @param GetDeploymentOptions $options The optional parameters. + * + * @return string + */ + private function _getDeploymentPath($name, $options) + { + $slot = $options->getSlot(); + $deploymentName = $options->getDeploymentName(); + $path = null; + + Validate::isTrue( + !empty($slot) || !empty($deploymentName), + Resources::INVALID_DEPLOYMENT_LOCATOR_MSG + ); + + if (!empty($slot)) { + $path = $this->_getDeploymentPathUsingSlot($name, $slot); + } else { + $path = $this->_getDeploymentPathUsingName($name, $deploymentName); + } + + return $path; + } + + /** + * Constructs URI path for storage service key. + * + * @param string $name The storage service name. + * + * @return string + */ + private function _getStorageServiceKeysPath($name = null) + { + return $this->_getPath('services/storageservices', $name) . '/keys'; + } + + /** + * Constructs URI path for operations. + * + * @param string $name The operation resource name. + * + * @return string + */ + private function _getOperationPath($name = null) + { + return $this->_getPath('operations', $name); + } + + /** + * Constructs request XML including windows azure XML namesoace. + * + * @param array $xmlElements The XML elements associated with their values. + * @param string $root The XML root name. + * + * @return string + */ + private function _createRequestXml($xmlElements, $root) + { + $requestArray = array( + Resources::XTAG_NAMESPACE => array(Resources::WA_XML_NAMESPACE => null) + ); + + foreach ($xmlElements as $tagName => $value) { + if (!empty($value)) { + $requestArray[$tagName] = $value; + } + } + + $properties = array(XmlSerializer::ROOT_NAME => $root); + + return $this->dataSerializer->serialize($requestArray, $properties); + } + + /** + * Prepare configuration XML for sending via REST API + * + * @param string|resource $configuration The configuration file contents + * or file stream. + * @return string + */ + private function _encodeConfiguration($value) { + $value = is_resource($value) ? stream_get_contents($value) : $value; + $value = base64_encode($value); + + // Cut the BOM if any. If the xml configuration would start with BOM Azure treats it as invalid XML file. + if (strpos($value, '77u/') === 0) { + $value = substr($value, 4); + } + + return $value; + } + + /** + * Initializes new ServiceManagementRestProxy object. + * + * @param IHttpClient $channel The HTTP channel. + * @param string $subscriptionId The user subscription id. + * @param string $uri The service URI. + * @param ISerializer $dataSerializer The data serializer. + */ + public function __construct($channel, $subscriptionId, $uri, $dataSerializer) + { + parent::__construct( + $channel, + $dataSerializer, + $uri + ); + $this->_subscriptionId = $subscriptionId; + } + + /** + * Lists the storage accounts available under the current subscription. + * + * @return ListStorageServicesResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee460787.aspx + */ + public function listStorageServices() + { + $context = new HttpCallContext(); + $context->setMethod(Resources::HTTP_GET); + $context->setPath($this->_getStorageServicePath()); + $context->addStatusCode(Resources::STATUS_OK); + + $response = $this->sendContext($context); + $serialized = $this->dataSerializer->unserialize($response->getBody()); + + return ListStorageServicesResult::create($serialized); + } + + /** + * Returns the system properties for the specified storage account. + * + * These properties include: the address, description, and label of the storage + * account; and the name of the affinity group to which the service belongs, + * or its geo-location if it is not part of an affinity group. + * + * @param string $name The storage account name. + * + * @return GetStorageServicePropertiesResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee460802.aspx + */ + public function getStorageServiceProperties($name) + { + Validate::isString($name, 'name'); + Validate::notNullOrEmpty($name, 'name'); + + $context = new HttpCallContext(); + $context->setMethod(Resources::HTTP_GET); + $context->setPath($this->_getStorageServicePath($name)); + $context->addStatusCode(Resources::STATUS_OK); + + $response = $this->sendContext($context); + $parsed = $this->dataSerializer->unserialize($response->getBody()); + + return GetStorageServicePropertiesResult::create($parsed); + } + + /** + * Returns the primary and secondary access keys for the specified storage + * account. + * + * @param string $name The storage account name. + * + * @return GetStorageServiceKeysResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee460785.aspx + */ + public function getStorageServiceKeys($name) + { + Validate::isString($name, 'name'); + Validate::notNullOrEmpty($name, 'name'); + + $context = new HttpCallContext(); + $context->setMethod(Resources::HTTP_GET); + $context->setPath($this->_getStorageServiceKeysPath($name)); + $context->addStatusCode(Resources::STATUS_OK); + + $response = $this->sendContext($context); + $parsed = $this->dataSerializer->unserialize($response->getBody()); + + return GetStorageServiceKeysResult::create($parsed); + } + + /** + * Regenerates the primary or secondary access key for the specified storage + * account. + * + * @param string $name The storage account name. + * @param string $keyType Specifies which key to regenerate. + * + * @return GetStorageServiceKeysResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee460795.aspx + */ + public function regenerateStorageServiceKeys($name, $keyType) + { + Validate::isString($name, 'name'); + Validate::notNullOrEmpty($name, 'name'); + Validate::isString($keyType, 'keyType'); + Validate::notNullOrEmpty($keyType, 'keyType'); + + $body = $this->_createRequestXml( + array(Resources::XTAG_KEY_TYPE => $keyType), + Resources::XTAG_REGENERATE_KEYS + ); + + $context = new HttpCallContext(); + $context->setMethod(Resources::HTTP_POST); + $context->setPath($this->_getStorageServiceKeysPath($name)); + $context->addStatusCode(Resources::STATUS_OK); + $context->addQueryParameter(Resources::QP_ACTION, Resources::QPV_REGENERATE); + $context->setBody($body); + $context->addHeader( + Resources::CONTENT_TYPE, + Resources::XML_CONTENT_TYPE + ); + + $response = $this->sendContext($context); + $parsed = $this->dataSerializer->unserialize($response->getBody()); + + return GetStorageServiceKeysResult::create($parsed); + } + + /** + * Creates a new storage account in Windows Azure. + * + * In the optional parameters either location or affinity group must be provided. + * Because Create Storage Account is an asynchronous operation, it always returns + * status code 202 (Accepted). To determine the status code for the operation + * once it is complete, call getOperationStatus API. The status code is embedded + * in the response for this operation; if successful, it will be + * status code 200 (OK). + * + * @param string $name The storage account name. + * @param string $label The name for the storage account + * specified as a base64-encoded string. The name may be up to 100 characters + * in length. The name can be used identify the storage account for your tracking + * purposes. + * @param CreateServiceOptions $options The optional parameters. + * + * @return AsynchronousOperationResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/hh264518.aspx + */ + public function createStorageService($name, $label, $options) + { + Validate::isString($name, 'name'); + Validate::notNullOrEmpty($name, 'name'); + Validate::isString($label, 'label'); + Validate::notNullOrEmpty($label, 'label'); + Validate::notNullOrEmpty($options, 'options'); + $affinityGroup = $options->getAffinityGroup(); + $location = $options->getLocation(); + Validate::isTrue( + !empty($location) || !empty($affinityGroup), + Resources::INVALID_CREATE_SERVICE_OPTIONS_MSG + ); + + $storageService = new StorageService(); + $storageService->setName($name); + $storageService->setLabel($label); + $storageService->setLocation($options->getLocation()); + $storageService->setAffinityGroup($options->getAffinityGroup()); + $storageService->setDescription($options->getDescription()); + $storageService->addSerializationProperty( + XmlSerializer::ROOT_NAME, + Resources::XTAG_CREATE_STORAGE_SERVICE_INPUT + ); + + $context = new HttpCallContext(); + $context->setMethod(Resources::HTTP_POST); + $context->setPath($this->_getStorageServicePath()); + $context->addStatusCode(Resources::STATUS_ACCEPTED); + $context->setBody($storageService->serialize($this->dataSerializer)); + $context->addHeader( + Resources::CONTENT_TYPE, + Resources::XML_CONTENT_TYPE + ); + + $response = $this->sendContext($context); + + return AsynchronousOperationResult::create($response->getHeader()); + } + + /** + * Deletes the specified storage account from Windows Azure. + * + * @param string $name The storage account name. + * + * @return none + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/hh264517.aspx + */ + public function deleteStorageService($name) + { + Validate::isString($name, 'name'); + Validate::notNullOrEmpty($name, 'name'); + + $context = new HttpCallContext(); + $context->setMethod(Resources::HTTP_DELETE); + $context->setPath($this->_getStorageServicePath($name)); + $context->addStatusCode(Resources::STATUS_OK); + + $this->sendContext($context); + } + + /** + * Updates the label and/or the description for a storage account in Windows + * Azure. + * + * @param string $name The storage account name. + * @param UpdateServiceOptions $options The optional parameters. + * + * @return none + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/hh264516.aspx + */ + public function updateStorageService($name, $options) + { + Validate::isString($name, 'name'); + Validate::notNullOrEmpty($name, 'name'); + $label = $options->getLabel(); + $description = $options->getDescription(); + Validate::isTrue( + !empty($label) || !empty($description), + Resources::INVALID_UPDATE_SERVICE_OPTIONS_MSG + ); + + $storageService = new StorageService(); + $storageService->setLabel($options->getLabel()); + $storageService->setDescription($options->getDescription()); + $storageService->addSerializationProperty( + XmlSerializer::ROOT_NAME, + Resources::XTAG_UPDATE_STORAGE_SERVICE_INPUT + ); + + $context = new HttpCallContext(); + $context->setMethod(Resources::HTTP_PUT); + $context->setPath($this->_getStorageServicePath($name)); + $context->addStatusCode(Resources::STATUS_OK); + $context->setBody($storageService->serialize($this->dataSerializer)); + $context->addHeader( + Resources::CONTENT_TYPE, + Resources::XML_CONTENT_TYPE + ); + $this->sendContext($context); + } + + /** + * Lists the affinity groups associated with the specified subscription. + * + * @return ListAffinityGroupsResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee460797.aspx + */ + public function listAffinityGroups() + { + $context = new HttpCallContext(); + $context->setMethod(Resources::HTTP_GET); + $context->setPath($this->_getAffinityGroupPath()); + $context->addStatusCode(Resources::STATUS_OK); + + $response = $this->sendContext($context); + $serialized = $this->dataSerializer->unserialize($response->getBody()); + + return ListAffinityGroupsResult::create($serialized); + } + + /** + * Creates a new affinity group for the specified subscription. + * + * @param string $name The affinity group name. + * @param string $label The base-64 encoded name for the + * affinity group. The name can be up to 100 characters in length. + * @param string $location The data center location where the + * affinity group will be created. To list available locations, use the + * listLocations API. + * @param CreateAffinityGroupOptions $options The optional parameters. + * + * @return none + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/gg715317.aspx + */ + public function createAffinityGroup($name, $label, $location, $options = null) + { + Validate::isString($name, 'name'); + Validate::notNullOrEmpty($name, 'name'); + Validate::isString($label, 'label'); + Validate::notNullOrEmpty($label, 'label'); + Validate::isString($location, 'location'); + Validate::notNullOrEmpty($location, 'location'); + + if (is_null($options)) { + $options = new CreateAffinityGroupOptions(); + } + + $affinityGroup = new AffinityGroup(); + $affinityGroup->setName($name); + $affinityGroup->setLabel($label); + $affinityGroup->setLocation($location); + $affinityGroup->setDescription($options->getDescription()); + $affinityGroup->addSerializationProperty( + XmlSerializer::ROOT_NAME, + Resources::XTAG_CREATE_AFFINITY_GROUP + ); + + $context = new HttpCallContext(); + $context->setMethod(Resources::HTTP_POST); + $context->setPath($this->_getAffinityGroupPath()); + $context->addStatusCode(Resources::STATUS_CREATED); + $context->setBody($affinityGroup->serialize($this->dataSerializer)); + $context->addHeader( + Resources::CONTENT_TYPE, + Resources::XML_CONTENT_TYPE + ); + + $this->sendContext($context); + } + + /** + * Deletes an affinity group in the specified subscription. + * + * @param string $name The affinity group name. + * + * @return none + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/gg715314.aspx + */ + public function deleteAffinityGroup($name) + { + Validate::isString($name, 'name'); + Validate::notNullOrEmpty($name, 'name'); + + $context = new HttpCallContext(); + $context->setMethod(Resources::HTTP_DELETE); + $context->setPath($this->_getAffinityGroupPath($name)); + $context->addStatusCode(Resources::STATUS_OK); + + $this->sendContext($context); + } + + /** + * Updates the label and/or the description for an affinity group for the + * specified subscription. + * + * @param string $name The affinity group name. + * @param string $label The affinity group label. + * @param CreateAffinityGroupOptions $options The optional parameters. + * + * @return none + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/gg715316.aspx + */ + public function updateAffinityGroup($name, $label, $options = null) + { + Validate::isString($name, 'name'); + Validate::notNullOrEmpty($name, 'name'); + Validate::isString($label, 'label'); + Validate::notNullOrEmpty($label, 'label'); + + if (is_null($options)) { + $options = new CreateAffinityGroupOptions(); + } + + $affinityGroup = new AffinityGroup(); + $affinityGroup->setLabel($label); + $affinityGroup->setDescription($options->getDescription()); + $affinityGroup->addSerializationProperty( + XmlSerializer::ROOT_NAME, + Resources::XTAG_UPDATE_AFFINITY_GROUP + ); + + $context = new HttpCallContext(); + $context->setMethod(Resources::HTTP_PUT); + $context->setPath($this->_getAffinityGroupPath($name)); + $context->addStatusCode(Resources::STATUS_OK); + $context->setBody($affinityGroup->serialize($this->dataSerializer)); + $context->addHeader( + Resources::CONTENT_TYPE, + Resources::XML_CONTENT_TYPE + ); + + $this->sendContext($context); + } + + /** + * Returns the system properties associated with the specified affinity group. + * + * @param string $name The affinity group name. + * + * @return GetAffinityGroupPropertiesResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee460789.aspx + */ + public function getAffinityGroupProperties($name) + { + Validate::isString($name, 'name'); + Validate::notNullOrEmpty($name, 'name'); + + $context = new HttpCallContext(); + $context->setMethod(Resources::HTTP_GET); + $context->setPath($this->_getAffinityGroupPath($name)); + $context->addStatusCode(Resources::STATUS_OK); + + $response = $this->sendContext($context); + $parsed = $this->dataSerializer->unserialize($response->getBody()); + + return GetAffinityGroupPropertiesResult::create($parsed); + } + + /** + * Lists all of the data center locations that are valid for your subscription. + * + * @return ListLocationsResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/gg441293.aspx + */ + public function listLocations() + { + $context = new HttpCallContext(); + $context->setMethod(Resources::HTTP_GET); + $context->setPath($this->_getLocationPath()); + $context->addStatusCode(Resources::STATUS_OK); + + $response = $this->sendContext($context); + $serialized = $this->dataSerializer->unserialize($response->getBody()); + + return ListLocationsResult::create($serialized); + } + + /** + * Returns the status of the specified operation. After calling an asynchronous + * operation, you can call Get Operation Status to determine whether the + * operation has succeeded, failed, or is still in progress. + * + * @param AsynchronousOperationResult $requestInfo The request information for + * the REST call you want to track. + * + * @return GetOperationStatusResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee460783.aspx + */ + public function getOperationStatus($requestInfo) + { + Validate::notNullOrEmpty($requestInfo, 'requestInfo'); + Validate::notNullOrEmpty($requestInfo->getrequestId(), 'requestId'); + + + $context = new HttpCallContext(); + $context->setMethod(Resources::HTTP_GET); + $context->setPath($this->_getOperationPath($requestInfo->getrequestId())); + $context->addStatusCode(Resources::STATUS_OK); + + $response = $this->sendContext($context); + $serialized = $this->dataSerializer->unserialize($response->getBody()); + + return GetOperationStatusResult::create($serialized); + } + + /** + * Lists the hosted services available under the current subscription. + * + * @return ListHostedServicesResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee460781.aspx + */ + public function listHostedServices() + { + $context = new HttpCallContext(); + $context->setMethod(Resources::HTTP_GET); + $context->setPath($this->_getHostedServicePath()); + $context->addStatusCode(Resources::STATUS_OK); + + $response = $this->sendContext($context); + $serialized = $this->dataSerializer->unserialize($response->getBody()); + + return ListHostedServicesResult::create($serialized); + } + + /** + * Creates a new hosted service in Windows Azure. + * + * @param string $name The name for the hosted service + * that is unique within Windows Azure. This name is the DNS prefix name and can + * be used to access the hosted service. + * @param string $label The name for the hosted service + * that is base-64 encoded. The name can be used identify the storage account for + * your tracking purposes. + * @param CreateServiceOptions $options The optional parameters. + * + * @return none + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/gg441304.aspx + */ + public function createHostedService($name, $label, $options) + { + Validate::isString($name, 'name'); + Validate::notNullOrEmpty($name, 'name'); + Validate::isString($label, 'label'); + Validate::notNullOrEmpty($label, 'label'); + Validate::notNullOrEmpty($options, 'options'); + + // User have to set affinity group or location. + $affinityGroup = $options->getAffinityGroup(); + $location = $options->getLocation(); + Validate::isTrue( + !empty($location) || !empty($affinityGroup), + Resources::INVALID_CREATE_SERVICE_OPTIONS_MSG + ); + + $hostedService = new HostedService(); + $hostedService->setName($name); + $hostedService->setLabel($label); + $hostedService->setLocation($options->getLocation()); + $hostedService->setAffinityGroup($options->getAffinityGroup()); + $hostedService->setDescription($options->getDescription()); + $hostedService->addSerializationProperty( + XmlSerializer::ROOT_NAME, + Resources::XTAG_CREATE_HOSTED_SERVICE + ); + + $context = new HttpCallContext(); + $context->setMethod(Resources::HTTP_POST); + $context->setPath($this->_getHostedServicePath()); + $context->addStatusCode(Resources::STATUS_CREATED); + $context->setBody($hostedService->serialize($this->dataSerializer)); + $context->addHeader( + Resources::CONTENT_TYPE, + Resources::XML_CONTENT_TYPE + ); + + $this->sendContext($context); + } + + /** + * updates the label and/or the description for a hosted service in Windows + * Azure. + * + * @param string $name The name for the hosted service that is + * unique within Windows Azure. + * @param UpdateServiceOptions $options The optional parameters. + * + * @return none + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/gg441303.aspx + */ + public function updateHostedService($name, $options) + { + Validate::isString($name, 'name'); + Validate::notNullOrEmpty($name, 'name'); + Validate::notNullOrEmpty($options, 'options'); + $label = $options->getLabel(); + $description = $options->getDescription(); + Validate::isTrue( + !empty($label) || !empty($description), + Resources::INVALID_UPDATE_SERVICE_OPTIONS_MSG + ); + + $hostedService = new HostedService(); + $hostedService->setLabel($options->getLabel()); + $hostedService->setDescription($options->getDescription()); + $hostedService->addSerializationProperty( + XmlSerializer::ROOT_NAME, + Resources::XTAG_UPDATE_HOSTED_SERVICE + ); + + $context = new HttpCallContext(); + $context->setMethod(Resources::HTTP_PUT); + $context->setPath($this->_getHostedServicePath($name)); + $context->addStatusCode(Resources::STATUS_OK); + $context->setBody($hostedService->serialize($this->dataSerializer)); + $context->addHeader( + Resources::CONTENT_TYPE, + Resources::XML_CONTENT_TYPE + ); + $this->sendContext($context); + } + + /** + * Deletes the specified hosted service from Windows Azure. + * + * Before you can delete a hosted service, you must delete any deployments it + * has. Attempting to delete a hosted service that has deployments results in + * an error. You can call the deleteDeployment API to delete a hosted service's + * deployments. + * + * @param string $name The name for the hosted service. + * + * @return none + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/gg441305.aspx + */ + public function deleteHostedService($name) + { + Validate::isString($name, 'name'); + Validate::notNullOrEmpty($name, 'name'); + + $context = new HttpCallContext(); + $context->setMethod(Resources::HTTP_DELETE); + $context->setPath($this->_getHostedServicePath($name)); + $context->addStatusCode(Resources::STATUS_OK); + + $this->sendContext($context); + } + + /** + * Retrieves system properties for the specified hosted service. These properties + * include the service name and service type; the name of the affinity group to + * which the service belongs, or its location if it is not part of an affinity + * group; and optionally, information on the service's deployments. + * + * @param string $name The name for the hosted + * service. + * @param GetHostedServicePropertiesOptions $options The optional parameters. + * + * @return GetHostedServicePropertiesResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee460806.aspx + */ + public function getHostedServiceProperties($name, $options = null) + { + Validate::isString($name, 'name'); + Validate::notNullOrEmpty($name, 'name'); + + if (is_null($options)) { + $options = new GetHostedServicePropertiesOptions(); + } + + $context = new HttpCallContext(); + $context->setMethod(Resources::HTTP_GET); + $context->setPath($this->_getHostedServicePath($name)); + $context->addStatusCode(Resources::STATUS_OK); + $context->addQueryParameter( + Resources::QP_EMBED_DETAIL, + Utilities::booleanToString($options->getEmbedDetail()) + ); + + $response = $this->sendContext($context); + $parsed = $this->dataSerializer->unserialize($response->getBody()); + + return GetHostedServicePropertiesResult::create($parsed); + } + + /** + * Uploads a new service package and creates a new deployment on staging or + * production. + * + * The createDeployment API is an asynchronous operation. To determine whether + * the management service has finished processing the request, call + * getOperationStatus API. + * + * @param string $name The name for the hosted service + * that is unique within Windows Azure. + * @param string $deploymentName The name for the deployment. + * The deployment name must be unique among other deployments for the hosted + * service. + * @param string $slot The name of the deployment slot + * This can be "production" or "staging". + * @param string $packageUrl The URL that refers to the + * location of the service package in the Blob service. The service package can + * be located in a storage account beneath the same subscription. + * @param string|resource $configuration The configuration file contents + * or file stream. + * @param string $label The name for the hosted service + * that is base-64 encoded. The name can be up to 100 characters in length. It is + * recommended that the label be unique within the subscription. The name can be + * used identify the hosted service for your tracking purposes. + * @param CreateDeploymentOptions $options The optional parameters. + * + * @return AsynchronousOperationResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee460813.aspx + */ + public function createDeployment( + $name, + $deploymentName, + $slot, + $packageUrl, + $configuration, + $label, + $options = null + ) { + Validate::isString($name, 'name'); + Validate::notNullOrEmpty($name, 'name'); + Validate::isString($deploymentName, 'deploymentName'); + Validate::notNullOrEmpty($deploymentName, 'deploymentName'); + Validate::isString($slot, 'slot'); + Validate::notNullOrEmpty($slot, 'slot'); + Validate::isTrue( + DeploymentSlot::isValid($slot), + sprintf(Resources::INVALID_SLOT, $slot) + ); + Validate::isString($packageUrl, 'packageUrl'); + Validate::notNullOrEmpty($packageUrl, 'packageUrl'); + Validate::isString($configuration, 'configuration'); + Validate::notNullOrEmpty($configuration, 'configuration'); + Validate::isString($label, 'label'); + Validate::notNullOrEmpty($label, 'label'); + + if (is_null($options)) { + $options = new CreateDeploymentOptions(); + } + + $configuration = $this->_encodeConfiguration($configuration); + + $startDeployment = Utilities::booleanToString( + $options->getStartDeployment() + ); + $treatWarningsAsErrors = Utilities::booleanToString( + $options->getTreatWarningsAsErrors() + ); + $xmlElements = array( + Resources::XTAG_NAME => $deploymentName, + Resources::XTAG_PACKAGE_URL => $packageUrl, + Resources::XTAG_LABEL => $label, + Resources::XTAG_CONFIGURATION => $configuration, + Resources::XTAG_START_DEPLOYMENT => $startDeployment, + Resources::XTAG_TREAT_WARNINGS_AS_ERROR => $treatWarningsAsErrors + ); + $requestXml = $this->_createRequestXml( + $xmlElements, + Resources::XTAG_CREATE_DEPLOYMENT + ); + + $context = new HttpCallContext(); + $context->setMethod(Resources::HTTP_POST); + $context->setPath($this->_getDeploymentPathUsingSlot($name, $slot)); + $context->addStatusCode(Resources::STATUS_ACCEPTED); + $context->setBody($requestXml); + $context->addHeader( + Resources::CONTENT_TYPE, + Resources::XML_CONTENT_TYPE + ); + + $response = $this->sendContext($context); + + return AsynchronousOperationResult::create($response->getHeader()); + } + + /** + * Returns configuration information, status, and system properties for a + * deployment. + * + * The getDeployment API can be used to retrieve information for a specific + * deployment or for all deployments in the staging or production environment. + * If you want to retrieve information about a specific deployment, you must + * first get the unique name for the deployment. This unique name is part of the + * response when you make a request to get all deployments in an environment. + * + * @param string $name The hosted service name. + * @param GetDeploymentOptions $options The optional parameters. + * + * @return GetDeploymentResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee460804.aspx + */ + public function getDeployment($name, $options) + { + Validate::isString($name, 'name'); + Validate::notNullOrEmpty($name, 'name'); + Validate::notNullOrEmpty($options, 'options'); + + $context = new HttpCallContext(); + $path = $this->_getDeploymentPath($name, $options); + $context->setMethod(Resources::HTTP_GET); + $context->setPath($path); + $context->addStatusCode(Resources::STATUS_OK); + + $response = $this->sendContext($context); + $parsed = $this->dataSerializer->unserialize($response->getBody()); + + return GetDeploymentResult::create($parsed); + } + + /** + * Initiates a virtual IP swap between the staging and production deployment + * environments for a service. If the service is currently running in the staging + * environment, it will be swapped to the production environment. If it is + * running in the production environment, it will be swapped to staging. + * + * You can swap VIPs only if the number of endpoints specified by the service + * definition is identical for both deployments. For example, if you add an HTTPS + * endpoint to a web role that previously exposed only an HTTP endpoint, you + * cannot upgrade your service using a VIP swap; you must delete your production + * deployment and redeploy instead. You can obtain information about endpoints + * that are used by using the Get Deployment operation. + * + * @param string $name The hosted service name. + * @param string $source The name of the source deployment. + * @param string $destination The name of the destination deployment. + * + * @return AsynchronousOperationResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee460814.aspx + */ + public function swapDeployment($name, $source, $destination) + { + Validate::isString($name, 'name'); + Validate::notNullOrEmpty($name, 'name'); + Validate::isString($destination, 'destination'); + Validate::notNullOrEmpty($destination, 'destination'); + Validate::isString($source, 'source'); + Validate::notNullOrEmpty($source, 'source'); + + $xmlElements = array( + Resources::XTAG_PRODUCTION => $destination, + Resources::XTAG_SOURCE_DEPLOYMENT => $source + ); + $body = $this->_createRequestXml($xmlElements, Resources::XTAG_SWAP); + $context = new HttpCallContext(); + $context->setMethod(Resources::HTTP_POST); + $context->setPath($this->_getHostedServicePath($name)); + $context->addStatusCode(Resources::STATUS_ACCEPTED); + $context->setBody($body); + $context->addHeader( + Resources::CONTENT_TYPE, + Resources::XML_CONTENT_TYPE + ); + + $response = $this->sendContext($context); + + return AsynchronousOperationResult::create($response->getHeader()); + } + + /** + * Deletes the specified deployment. + * + * Note that you can delete a deployment either by specifying the deployment + * environment (staging or production), or by specifying the deployment's unique + * name. + * + * @param string $name The hosted service name. + * @param GetDeploymentOptions $options The optional parameters. + * + * @return AsynchronousOperationResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee460815.aspx + */ + public function deleteDeployment($name, $options) + { + Validate::isString($name, 'name'); + Validate::notNullOrEmpty($name, 'name'); + Validate::notNullOrEmpty($options, 'options'); + + $context = new HttpCallContext(); + $path = $this->_getDeploymentPath($name, $options); + $context->setMethod(Resources::HTTP_DELETE); + $context->setPath($path); + $context->addStatusCode(Resources::STATUS_ACCEPTED); + + $response = $this->sendContext($context); + + return AsynchronousOperationResult::create($response->getHeader()); + } + + /** + * Initiates a change to the deployment configuration. + * + * Note that you can change a deployment's configuration either by specifying the + * deployment environment (staging or production), or by specifying the + * deployment's unique name. + * + * @param string $name The hosted service + * name. + * @param string|resource $configuration The configuration + * file contents or file stream. + * @param ChangeDeploymentConfigurationOptions $options The optional + * parameters. + * + * @return AsynchronousOperationResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee460809.aspx + */ + public function changeDeploymentConfiguration($name, $configuration, $options) + { + Validate::isString($name, 'name'); + Validate::notNullOrEmpty($name, 'name'); + Validate::isString($configuration, 'configuration'); + Validate::notNullOrEmpty($configuration, 'configuration'); + Validate::notNullOrEmpty($options, 'options'); + + $configuration = $this->_encodeConfiguration($configuration); + $warningsTreatment = Utilities::booleanToString( + $options->getTreatWarningsAsErrors() + ); + $xmlElements = array( + Resources::XTAG_CONFIGURATION => $configuration, + Resources::XTAG_TREAT_WARNINGS_AS_ERROR => $warningsTreatment, + Resources::XTAG_MODE => $options->getMode() + ); + $body = $this->_createRequestXml( + $xmlElements, + Resources::XTAG_CHANGE_CONFIGURATION + ); + $context = new HttpCallContext(); + $context->setMethod(Resources::HTTP_POST); + $context->setPath($this->_getDeploymentPath($name, $options) . '/'); + $context->addStatusCode(Resources::STATUS_ACCEPTED); + $context->addQueryParameter( + Resources::QP_COMP, + Resources::QPV_CONFIG + ); + $context->setBody($body); + $context->addHeader( + Resources::CONTENT_TYPE, + Resources::XML_CONTENT_TYPE + ); + + assert(Utilities::endsWith($context->getPath(), '/')); + $response = $this->sendContext($context); + + return AsynchronousOperationResult::create($response->getHeader()); + } + + /** + * Initiates a change in deployment status. + * + * Note that you can change deployment status either by specifying the deployment + * environment (staging or production), or by specifying the deployment's unique + * name. + * + * @param string $name The hosted service name. + * @param string $status The change to initiate to the + * deployment status. + * Possible values include Running or Suspended. + * @param GetDeploymentOptions $options The optional parameters. + * + * @return AsynchronousOperationResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee460808.aspx + */ + public function updateDeploymentStatus($name, $status, $options) + { + Validate::isString($name, 'name'); + Validate::notNullOrEmpty($name, 'name'); + Validate::isTrue( + DeploymentStatus::isValid($status), + Resources::INVALID_DEPLOYMENT_STATUS_MSG + ); + Validate::notNullOrEmpty($options, 'options'); + + $body = $this->_createRequestXml( + array(Resources::XTAG_STATUS => $status), + Resources::XTAG_UPDATE_DEPLOYMENT_STATUS + ); + $context = new HttpCallContext(); + $context->setMethod(Resources::HTTP_POST); + $context->setPath($this->_getDeploymentPath($name, $options) . '/'); + $context->addStatusCode(Resources::STATUS_ACCEPTED); + $context->addQueryParameter( + Resources::QP_COMP, + Resources::QPV_STATUS + ); + $context->setBody($body); + $context->addHeader( + Resources::CONTENT_TYPE, + Resources::XML_CONTENT_TYPE + ); + + assert(Utilities::endsWith($context->getPath(), '/')); + $response = $this->sendContext($context); + + return AsynchronousOperationResult::create($response->getHeader()); + } + + /** + * Initiates an upgrade to a deployment. + * + * Note that you can upgrade a deployment either by specifying the deployment + * environment (staging or production), or by specifying the deployment's unique + * name. + * + * @param string $name The hosted service name. + * @param string $mode The type of upgrade to initiate + * If not specified the default value is Auto. If set to Manual, + * walkUpgradeDomain API must be called to apply the update. If set to Auto, the + * Windows Azure platform will automatically apply the update to each Upgrade + * Domain in sequence. + * @param string $packageUrl The URL that refers to the + * location of the service package in the Blob service. The service package can + * be located in a storage account beneath the same subscription. + * @param string|resource $configuration The configuration file contents + * or file stream. + * @param string $label The name for the hosted service + * that is base-64 encoded. The name may be up to 100 characters in length. + * @param boolean $force Specifies whether the rollback + * should proceed even when it will cause local data to be lost from some role + * instances. True if the rollback should proceed; otherwise false if the + * rollback should fail. + * @param UpgradeDeploymentOptions $options The optional parameters. + * + * @return AsynchronousOperationResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee460793.aspx + */ + public function upgradeDeployment( + $name, + $mode, + $packageUrl, + $configuration, + $label, + $force, + $options + ) { + Validate::isString($name, 'name'); + Validate::notNullOrEmpty($name, 'name'); + Validate::isString($mode, 'mode'); + Validate::isTrue(Mode::isValid($mode), Resources::INVALID_CHANGE_MODE_MSG); + Validate::isString($packageUrl, 'packageUrl'); + Validate::notNullOrEmpty($packageUrl, 'packageUrl'); + Validate::isString($configuration, 'configuration'); + Validate::notNullOrEmpty($configuration, 'configuration'); + Validate::isString($label, 'label'); + Validate::notNullOrEmpty($label, 'label'); + Validate::isBoolean($force, 'force'); + Validate::notNullOrEmpty($force, 'force'); + Validate::notNullOrEmpty($options, 'options'); + + $configuration = $this->_encodeConfiguration($configuration); + + $xmlElements = array( + Resources::XTAG_MODE => $mode, + Resources::XTAG_PACKAGE_URL => $packageUrl, + Resources::XTAG_CONFIGURATION => $configuration, + Resources::XTAG_LABEL => $label, + Resources::XTAG_ROLE_TO_UPGRADE => $options->getRoleToUpgrade(), + Resources::XTAG_FORCE => Utilities::booleanToString($force), + ); + $body = $this->_createRequestXml( + $xmlElements, + Resources::XTAG_UPGRADE_DEPLOYMENT + ); + $context = new HttpCallContext(); + $context->setMethod(Resources::HTTP_POST); + $context->setPath($this->_getDeploymentPath($name, $options) . '/'); + $context->addStatusCode(Resources::STATUS_ACCEPTED); + $context->addQueryParameter( + Resources::QP_COMP, + Resources::QPV_UPGRADE + ); + $context->setBody($body); + $context->addHeader( + Resources::CONTENT_TYPE, + Resources::XML_CONTENT_TYPE + ); + + assert(Utilities::endsWith($context->getPath(), '/')); + $response = $this->sendContext($context); + + return AsynchronousOperationResult::create($response->getHeader()); + } + + /** + * Specifies the next upgrade domain to be walked during manual in-place upgrade + * or configuration change. + * + * Note that you can walk an upgrade domain either by specifying the deployment + * environment (staging or production), or by specifying the deployment's unique + * name. + * + * @param string $name The hosted service name. + * @param integer $upgradeDomain The integer value that + * identifies the upgrade domain to walk. Upgrade domains are identified with a + * zero-based index: the first upgrade domain has an ID of 0, the second has an + * ID of 1, and so on. + * @param GetDeploymentOptions $options The optional parameters. + * + * @return AsynchronousOperationResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee460800.aspx + */ + public function walkUpgradeDomain($name, $upgradeDomain, $options) + { + Validate::isString($name, 'name'); + Validate::notNullOrEmpty($name, 'name'); + Validate::isInteger($upgradeDomain, 'upgradeDomain'); + Validate::notNullOrEmpty($options, 'options'); + + $body = $this->_createRequestXml( + array(Resources::XTAG_UPGRADE_DOMAIN => $upgradeDomain), + Resources::XTAG_WALK_UPGRADE_DOMAIN + ); + $context = new HttpCallContext(); + $context->setMethod(Resources::HTTP_POST); + $context->setPath($this->_getDeploymentPath($name, $options) . '/'); + $context->addStatusCode(Resources::STATUS_ACCEPTED); + $context->addQueryParameter( + Resources::QP_COMP, + Resources::QPV_WALK_UPGRADE_DOMAIN + ); + $context->setBody($body); + $context->addHeader( + Resources::CONTENT_TYPE, + Resources::XML_CONTENT_TYPE + ); + + assert(Utilities::endsWith($context->getPath(), '/')); + $response = $this->sendContext($context); + + return AsynchronousOperationResult::create($response->getHeader()); + } + + /** + * Requests a reboot of a role instance that is running in a deployment. + * + * Note that you can reboot role instance either by specifying the deployment + * environment (staging or production), or by specifying the deployment's unique + * name. + * + * @param string $name The hosted service name. + * @param string $roleName The role instance name. + * @param GetDeploymentOptions $options The optional parameters. + * + * @return AsynchronousOperationResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/gg441298.aspx + */ + public function rebootRoleInstance($name, $roleName, $options) + { + return $this->_sendRoleInstanceOrder( + $name, + $roleName, + $options, + Resources::QPV_REBOOT + ); + } + + /** + * Requests a reimage of a role instance that is running in a deployment. + * + * Note that you can reimage role instance either by specifying the deployment + * environment (staging or production), or by specifying the deployment's unique + * name. + * + * @param string $name The hosted service name. + * @param string $roleName The role instance name. + * @param GetDeploymentOptions $options The optional parameters. + * + * @return AsynchronousOperationResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/gg441292.aspx + */ + public function reimageRoleInstance($name, $roleName, $options) + { + return $this->_sendRoleInstanceOrder( + $name, + $roleName, + $options, + Resources::QPV_REIMAGE + ); + } + + /** + * Cancels an in progress configuration change (update) or upgrade and returns + * the deployment to its state before the upgrade or configuration change was + * started. + * + * Note that you can rollback update or upgrade either by specifying the + * deployment environment (staging or production), or by specifying the + * deployment's unique name. + * + * @param string $name The hosted service name. + * @param string $mode Specifies whether the rollback + * should proceed automatically or not. Auto, The rollback proceeds without + * further user input. Manual, You must call the walkUpgradeDomain API to apply + * the rollback to each upgrade domain. + * @param boolean $force Specifies whether the rollback + * should proceed even when it will cause local data to be lost from some role + * instances. True if the rollback should proceed; otherwise false if the + * rollback should fail. + * @param GetDeploymentOptions $options The optional parameters. + * + * @return none + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/hh403977.aspx + */ + public function rollbackUpdateOrUpgrade($name, $mode, $force, $options) + { + Validate::isString($name, 'name'); + Validate::notNullOrEmpty($name, 'name'); + Validate::isString($mode, 'mode'); + Validate::isTrue(Mode::isValid($mode), Resources::INVALID_CHANGE_MODE_MSG); + Validate::isBoolean($force, 'force'); + Validate::notNullOrEmpty($force, 'force'); + Validate::notNullOrEmpty($options, 'options'); + + $xmlElements = array( + Resources::XTAG_MODE => $mode, + Resources::XTAG_FORCE => Utilities::booleanToString($force), + ); + $body = $this->_createRequestXml( + $xmlElements, + Resources::XTAG_ROLLBACK_UPDATE_OR_UPGRADE + ); + $context = new HttpCallContext(); + $context->setMethod(Resources::HTTP_POST); + $context->setPath($this->_getDeploymentPath($name, $options) . '/'); + $context->addStatusCode(Resources::STATUS_ACCEPTED); + $context->addQueryParameter( + Resources::QP_COMP, + Resources::QPV_ROLLBACK + ); + $context->setBody($body); + $context->addHeader( + Resources::CONTENT_TYPE, + Resources::XML_CONTENT_TYPE + ); + + assert(Utilities::endsWith($context->getPath(), '/')); + $response = $this->sendContext($context); + + return AsynchronousOperationResult::create($response->getHeader()); + } +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/AcquireCurrentState.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/AcquireCurrentState.php new file mode 100644 index 0000000..fd4d594 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/AcquireCurrentState.php @@ -0,0 +1,101 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceRuntime\Internal; + +/** + * The acquire current state request. + * + * @category Microsoft + * @package WindowsAzure\ServiceRuntime\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class AcquireCurrentState extends CurrentState +{ + /** + * @var string + */ + private $_incarnation; + + /** + * @var CurrentStatus + */ + private $_status; + + /** + * @var \DateTime + */ + private $_expiration; + + /** + * Constructor + * + * @param string $clientId The client identifier. + * @param string $incarnation The incarnation. + * @param string $status The status. + * @param \DateTime $expiration The expiration date. + */ + public function __construct($clientId, $incarnation, $status, $expiration) + { + parent::__construct($clientId); + $this->_incarnation = $incarnation; + $this->_status = $status; + $this->_expiration = $expiration; + } + + /** + * Gets the incarnation. + * + * @return string + */ + public function getIncarnation() + { + return $this->_incarnation; + } + + /** + * Gets the status. + * + * @return string + */ + public function getStatus() + { + return $this->_status; + } + + /** + * Gets the expiration. + * + * @return \DateTime + */ + public function getExpiration() + { + return $this->_expiration; + } +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/ChannelNotAvailableException.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/ChannelNotAvailableException.php new file mode 100644 index 0000000..8e87a99 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/ChannelNotAvailableException.php @@ -0,0 +1,41 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceRuntime\Internal; + +/** + * Custom exception when a role environment channel is not available. + * + * @category Microsoft + * @package WindowsAzure\ServiceRuntime\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class ChannelNotAvailableException extends \Exception +{ +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/ChunkedGoalStateDeserializer.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/ChunkedGoalStateDeserializer.php new file mode 100644 index 0000000..4e9c10c --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/ChunkedGoalStateDeserializer.php @@ -0,0 +1,91 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceRuntime\Internal; + +/** + * The goal state representation. + * + * @category Microsoft + * @package WindowsAzure\ServiceRuntime\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class ChunkedGoalStateDeserializer implements IGoalStateDeserializer +{ + /** + * @var XmlGoalStateDeserializer + */ + private $_deserializer; + + /** + * @var resource + */ + private $_inputStream; + + /** + * Constructor + */ + public function __construct() + { + $this->_deserializer = new XmlGoalStateDeserializer(); + } + + /** + * Initializes the goal state deserializer with the input stream. + * + * @param Stream $inputStream The input stream. + * + * @return none + */ + public function initialize($inputStream) + { + $this->_inputStream = $inputStream; + } + + /** + * Deserializes a goal state document. + * + * @return none + */ + public function deserialize() + { + do { + $lengthString = stream_get_line($this->_inputStream, 100, "\n"); + } while ( + empty($lengthString) || $lengthString == "\n" || $lengthString == "\r" + ); + + $intLengthString = hexdec(trim($lengthString)); + + $chunkData = stream_get_contents($this->_inputStream, $intLengthString); + $goalState = $this->_deserializer->deserialize($chunkData); + + return $goalState; + } +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/CurrentState.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/CurrentState.php new file mode 100644 index 0000000..a09e19d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/CurrentState.php @@ -0,0 +1,65 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceRuntime\Internal; + +/** + * The current state representation. + * + * @category Microsoft + * @package WindowsAzure\ServiceRuntime\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class CurrentState +{ + /** + * @var string + */ + private $_clientId; + + /** + * Constructor + * + * @param string $clientId The client identifier. + */ + public function __construct($clientId) + { + $this->_clientId = $clientId; + } + + /** + * Gets the client identifier. + * + * @return string + */ + public function getClientId() + { + return $this->_clientId; + } +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/CurrentStatus.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/CurrentStatus.php new file mode 100644 index 0000000..9e32418 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/CurrentStatus.php @@ -0,0 +1,60 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceRuntime\Internal; + +/** + * The current status. + * + * @category Microsoft + * @package WindowsAzure\ServiceRuntime\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class CurrentStatus +{ + /** + * @var string + */ + const STARTED = 'Started'; + + /** + * @var string + */ + const BUSY = 'Busy'; + + /** + * @var string + */ + const RECYCLE = 'Recycle'; + + /** + * @var string + */ + const STOPPED = 'Stopped'; +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/FileInputChannel.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/FileInputChannel.php new file mode 100644 index 0000000..9ea4c74 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/FileInputChannel.php @@ -0,0 +1,79 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceRuntime\Internal; + +/** + * The file input channel. + * + * @category Microsoft + * @package WindowsAzure\ServiceRuntime\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class FileInputChannel implements IInputChannel +{ + // @codingStandardsIgnoreStart + + /** + * @var Resource + */ + private $_inputStream; + + /** + * Gets the input stream. + * + * @param string $name The input stream path. + * + * @return none + */ + public function getInputStream($name) + { + $this->_inputStream = @fopen($name, 'r'); + if ($this->_inputStream) { + return $this->_inputStream; + } else { + throw new ChannelNotAvailableException(); + } + } + + /** + * Closes the input stream. + * + * @return none + */ + public function closeInputStream() + { + if (!is_null($this->_inputStream)) { + fclose($this->_inputStream); + $this->_inputStream = null; + } + } + + // @codingStandardsIgnoreEnd +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/FileOutputChannel.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/FileOutputChannel.php new file mode 100644 index 0000000..068fac4 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/FileOutputChannel.php @@ -0,0 +1,61 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceRuntime\Internal; + +/** + * The file output channel. + * + * @category Microsoft + * @package WindowsAzure\ServiceRuntime\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class FileOutputChannel implements IOutputChannel +{ + // @codingStandardsIgnoreStart + + /** + * Gets the output stream. + * + * @param string $name The output channel path. + * + * @return none + */ + public function getOutputStream($name) + { + $fp = @fopen($name, 'w'); + if ($fp) { + return $fp; + } else { + throw new ChannelNotAvailableException(); + } + } + + // @codingStandardsIgnoreEnd +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/GoalState.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/GoalState.php new file mode 100644 index 0000000..1a7c3e2 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/GoalState.php @@ -0,0 +1,137 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceRuntime\Internal; +use WindowsAzure\Common\Internal\Validate; + +/** + * The goal state representation. + * + * @category Microsoft + * @package WindowsAzure\ServiceRuntime\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class GoalState +{ + /** + * @var string + */ + private $_incarnation; + + /** + * @var string + */ + private $_expectedState; + + /** + * @var string + */ + private $_environmentPath; + + /** + * @var string + */ + private $_deadline; + + /** + * @var string + */ + private $_currentStateEndpoint; + + /** + * Constructor + * + * @param string $incarnation The incarnation. + * @param string $expectedState The expected state. + * @param string $environmentPath The environment path. + * @param \DateTime $deadline The deadline. + * @param string $currentStateEndpoint The current state endpoint. + */ + public function __construct ($incarnation, $expectedState, $environmentPath, + $deadline, $currentStateEndpoint + ) { + Validate::isDate($deadline); + + $this->_incarnation = $incarnation; + $this->_expectedState = $expectedState; + $this->_environmentPath = $environmentPath; + $this->_deadline = $deadline; + $this->_currentStateEndpoint = $currentStateEndpoint; + } + + /** + * Gets the incarnation. + * + * @return string + */ + public function getIncarnation() + { + return $this->_incarnation; + } + + /** + * Gets the expected state. + * + * @return string + */ + public function getExpectedState() + { + return $this->_expectedState; + } + + /** + * Gets the environment path. + * + * @return string + */ + public function getEnvironmentPath() + { + return $this->_environmentPath; + } + + /** + * Gets the deadline. + * + * @return string + */ + public function getDeadline() + { + return $this->_deadline; + } + + /** + * Gets the current state endpoint. + * + * @return string + */ + public function getCurrentStateEndpoint() + { + return $this->_currentStateEndpoint; + } +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/ICurrentStateSerializer.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/ICurrentStateSerializer.php new file mode 100644 index 0000000..71e811b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/ICurrentStateSerializer.php @@ -0,0 +1,50 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceRuntime\Internal; + +/** + * The current state serializer. + * + * @category Microsoft + * @package WindowsAzure\ServiceRuntime\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +interface ICurrentStateSerializer +{ + /** + * Serializes the current state. + * + * @param CurrentState $state The current state. + * @param string $stream The output stream. + * + * @return none + */ + public function serialize($state, $stream); +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/IGoalStateDeserializer.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/IGoalStateDeserializer.php new file mode 100644 index 0000000..a10626b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/IGoalStateDeserializer.php @@ -0,0 +1,56 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceRuntime\Internal; + +/** + * The goal state deserializer. + * + * @category Microsoft + * @package WindowsAzure\ServiceRuntime\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +interface IGoalStateDeserializer +{ + /** + * Initializes the goal state deserializer with the input stream. + * + * @param Stream $inputStream The input stream. + * + * @return none + */ + public function initialize($inputStream); + + /** + * Deserializes a goal state. + * + * @return none + */ + public function deserialize(); +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/IInputChannel.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/IInputChannel.php new file mode 100644 index 0000000..4c108cc --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/IInputChannel.php @@ -0,0 +1,49 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceRuntime\Internal; + +/** + * The input channel. + * + * @category Microsoft + * @package WindowsAzure\ServiceRuntime\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +interface IInputChannel +{ + /** + * Gets the input stream. + * + * @param string $name The input stream path. + * + * @return none + */ + public function getInputStream($name); +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/IOutputChannel.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/IOutputChannel.php new file mode 100644 index 0000000..9b365c0 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/IOutputChannel.php @@ -0,0 +1,49 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceRuntime\Internal; + +/** + * The output channel. + * + * @category Microsoft + * @package WindowsAzure\ServiceRuntime\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +interface IOutputChannel +{ + /** + * Gets the output stream. + * + * @param string $name The output channel path. + * + * @return none + */ + public function getOutputStream($name); +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/IRoleEnvironmentChange.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/IRoleEnvironmentChange.php new file mode 100644 index 0000000..8d31955 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/IRoleEnvironmentChange.php @@ -0,0 +1,41 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceRuntime\Internal; + +/** + * The role environment change. + * + * @category Microsoft + * @package WindowsAzure\ServiceRuntime\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +interface IRoleEnvironmentChange +{ +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/IRoleEnvironmentDataDeserializer.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/IRoleEnvironmentDataDeserializer.php new file mode 100644 index 0000000..da64469 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/IRoleEnvironmentDataDeserializer.php @@ -0,0 +1,49 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceRuntime\Internal; + +/** + * The role environment data deserializer. + * + * @category Microsoft + * @package WindowsAzure\ServiceRuntime\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +interface IRoleEnvironmentDataDeserializer +{ + /** + * Deserializes the role environment data. + * + * @param string $document The document to deserialize. + * + * @return none + */ + public function deserialize($document); +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/IRuntimeClient.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/IRuntimeClient.php new file mode 100644 index 0000000..4098dce --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/IRuntimeClient.php @@ -0,0 +1,41 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceRuntime\Internal; + +/** + * The runtime client. + * + * @category Microsoft + * @package WindowsAzure\ServiceRuntime\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +interface IRuntimeClient extends IRuntimeCurrentStateClient, IRuntimeGoalStateClient +{ +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/IRuntimeClientFactory.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/IRuntimeClientFactory.php new file mode 100644 index 0000000..ff3027e --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/IRuntimeClientFactory.php @@ -0,0 +1,56 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceRuntime\Internal; + +/** + * The runtime client factory. + * + * @category Microsoft + * @package WindowsAzure\ServiceRuntime\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +interface IRuntimeClientFactory +{ + /** + * Gets the runtime version. + * + * @return string + */ + public function getVersion(); + + /** + * Creates a new runtime client instance. + * + * @param string $path The goal state path. + * + * @return IRuntimeClient + */ + public function createRuntimeClient($path); +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/IRuntimeCurrentStateClient.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/IRuntimeCurrentStateClient.php new file mode 100644 index 0000000..6ffb0e0 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/IRuntimeCurrentStateClient.php @@ -0,0 +1,49 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceRuntime\Internal; + +/** + * The runtime current state client. + * + * @category Microsoft + * @package WindowsAzure\ServiceRuntime\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +interface IRuntimeCurrentStateClient +{ + /** + * Sets the current state. + * + * @param CurrentState $state The current state. + * + * @return none + */ + public function setCurrentState($state); +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/IRuntimeGoalStateClient.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/IRuntimeGoalStateClient.php new file mode 100644 index 0000000..4bab4e4 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/IRuntimeGoalStateClient.php @@ -0,0 +1,54 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceRuntime\Internal; + +/** + * The runtime goal state client. + * + * @category Microsoft + * @package WindowsAzure\ServiceRuntime\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +interface IRuntimeGoalStateClient +{ + /** + * Gets the current goal state. + * + * @return GoalState + */ + public function getCurrentGoalState(); + + /** + * Gets the role environment data. + * + * @return RoleEnvironmentData + */ + public function getRoleEnvironmentData(); +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/LocalResource.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/LocalResource.php new file mode 100644 index 0000000..1e921df --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/LocalResource.php @@ -0,0 +1,101 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceRuntime\Internal; + +/** + * The local resource. + * + * @category Microsoft + * @package WindowsAzure\ServiceRuntime\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class LocalResource +{ + /** + * @var int + */ + private $_maximumSizeInMegabytes; + + /** + * @var string + */ + private $_name; + + /** + * @var string + */ + private $_rootPath; + + /** + * Package accessible constructor. + * + * @param string $maximumSizeInMegabytes Maximum size in megabytes. + * @param string $name The name. + * @param string $rootPath The root path. + */ + public function __construct ($maximumSizeInMegabytes, $name, $rootPath) + { + $this->_maximumSizeInMegabytes = $maximumSizeInMegabytes; + $this->_name = $name; + $this->_rootPath = $rootPath; + } + + /** + * Returns the maximum size, in megabytes, allocated for the local storage + * resource, as defined in the service. + * + * @return int + */ + public function getMaximumSizeInMegabytes() + { + return $this->_maximumSizeInMegabytes; + } + + /** + * Returns the name of the local store as declared in the service definition + * file. + * + * @return string + */ + public function getName() + { + return $this->_name; + } + + /** + * Returns the full directory path to the local storage resource. + * + * @return string + */ + public function getRootPath() + { + return $this->_rootPath; + } +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/Protocol1RuntimeClient.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/Protocol1RuntimeClient.php new file mode 100644 index 0000000..d6fe14f --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/Protocol1RuntimeClient.php @@ -0,0 +1,97 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceRuntime\Internal; + +/** + * An implementation for the protocol runtime client. + * + * @category Microsoft + * @package WindowsAzure\ServiceRuntime\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class Protocol1RuntimeClient +{ + /** + * @var Protocol1RuntimeGoalStateClient + */ + private $_goalStateClient; + + /** + * @var Protocol1RuntimeCurrentStateClient + */ + private $_currentStateClient; + + /** + * Constructor + * + * @param string $goalStateClient The goal state client. + * @param string $currentStateClient The current state client. + * @param string $endpoint The endpoint. + */ + public function __construct($goalStateClient, $currentStateClient, $endpoint) + { + $this->_goalStateClient = $goalStateClient; + $this->_currentStateClient = $currentStateClient; + + $this->_goalStateClient->setEndpoint($endpoint); + } + + /** + * Gets the current goal state. + * + * @return GoalState. + */ + public function getCurrentGoalState() + { + return $this->_goalStateClient->getCurrentGoalState(); + } + + /** + * Gets the role environment data. + * + * @return RoleEnvironmentData. + */ + public function getRoleEnvironmentData() + { + return $this->_goalStateClient->getRoleEnvironmentData(); + } + + /** + * Sets the current state. + * + * @param CurrentState $state The current state. + * + * @return none + */ + public function setCurrentState($state) + { + $this->_currentStateClient->setCurrentState($state); + } +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/Protocol1RuntimeClientFactory.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/Protocol1RuntimeClientFactory.php new file mode 100644 index 0000000..28efc18 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/Protocol1RuntimeClientFactory.php @@ -0,0 +1,68 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceRuntime\Internal; + +/** + * The runtime client factory. + * + * @category Microsoft + * @package WindowsAzure\ServiceRuntime\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class Protocol1RuntimeClientFactory +{ + /** + * Gets the runtime version. + * + * @return string + */ + public function getVersion() + { + return '2011-03-08'; + } + + /** + * Creates a new runtime client instance. + * + * @param string $path The goal state path. + * + * @return IRuntimeClient + */ + public function createRuntimeClient($path) + { + $kernel = RuntimeKernel::getKernel(); + + return new Protocol1RuntimeClient( + $kernel->getProtocol1RuntimeGoalStateClient(), + $kernel->getProtocol1RuntimeCurrentStateClient(), + $path + ); + } +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/Protocol1RuntimeCurrentStateClient.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/Protocol1RuntimeCurrentStateClient.php new file mode 100644 index 0000000..38e3774 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/Protocol1RuntimeCurrentStateClient.php @@ -0,0 +1,95 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceRuntime\Internal; + +/** + * An implementation for the protocol runtime current state client. + * + * @category Microsoft + * @package WindowsAzure\ServiceRuntime\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class Protocol1RuntimeCurrentStateClient implements IRuntimeCurrentStateClient +{ + /** + * @var ICurrentStateSerializer + */ + private $_serializer; + + /** + * @var IOutputChannel + */ + private $_outputChannel; + + /** + * @var string + */ + private $_endpoint; + + /** + * Constructor + * + * @param ICurrentStateSerializer $serializer The current state + * serializer. + * @param IOutputChannel $outputChannel The output channel. + */ + public function __construct($serializer, $outputChannel) + { + $this->_serializer = $serializer; + $this->_outputChannel = $outputChannel; + $this->_endpoint = null; + } + + /** + * Sets the endpoint to be used. + * + * @param string $endpoint The endpoint. + * + * @return none + */ + public function setEndpoint($endpoint) + { + $this->_endpoint = $endpoint; + } + + /** + * Sets the current state. + * + * @param CurrentState $state The current state. + * + * @return none + */ + public function setCurrentState($state) + { + $outputStream = $this->_outputChannel->getOutputStream($this->_endpoint); + $this->_serializer->serialize($state, $outputStream); + fclose($outputStream); + } +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/Protocol1RuntimeGoalStateClient.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/Protocol1RuntimeGoalStateClient.php new file mode 100644 index 0000000..d181b1a --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/Protocol1RuntimeGoalStateClient.php @@ -0,0 +1,225 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceRuntime\Internal; + +/** + * An implementation for the protocol runtime goal state client. + * + * @category Microsoft + * @package WindowsAzure\ServiceRuntime\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class Protocol1RuntimeGoalStateClient implements IRuntimeGoalStateClient +{ + /** + * @var Protocol1RuntimeCurrentStateClient + */ + private $_currentStateClient; + + /** + * @var IGoalStateDeserializer + */ + private $_goalStateDeserializer; + + /** + * @var IGoalStateDeserializer + */ + private $_roleEnvironmentDeserializer; + + /** + * @var IInputChannel + */ + private $_inputChannel; + + /** + * @var string + */ + private $_endpoint; + + /** + * @var CurrentGoalState + */ + private $_currentGoalState; + + /** + * @var RoleEnvironmentData + */ + private $_currentEnvironmentData; + + /** + * @var bool + */ + private $_keepOpen; + + /** + * Constructor + * + * @param Protocol1RuntimeCurrentStateClient $currentStateClient The + * current state client. + * @param IGoalStateDeserializer $goalStateDeserializer The + * goal state deserializer. + * @param IRoleEnvironmentDeserializer $roleEnvironmentDeserializer The + * role environment deserializer. + * @param IInputChannel $inputChannel The + * input channel. + */ + public function __construct($currentStateClient, $goalStateDeserializer, + $roleEnvironmentDeserializer, $inputChannel + ) { + $this->_currentStateClient = $currentStateClient; + $this->_goalStateDeserializer = $goalStateDeserializer; + $this->_roleEnvironmentDeserializer = $roleEnvironmentDeserializer; + $this->_inputChannel = $inputChannel; + + $this->_listeners = array(); + + $this->_currentGoalState = null; + $this->_currentEnvironmentData = null; + $this->_keepOpen = false; + } + + /** + * Gets the current goal state. + * + * @return GoalState + */ + public function getCurrentGoalState() + { + $this->_ensureGoalStateRetrieved(); + + return $this->_currentGoalState; + } + + /** + * Gets the role environment data. + * + * @return RoleEnvironmentData + */ + public function getRoleEnvironmentData() + { + $this->_ensureGoalStateRetrieved(); + + if (is_null($this->_currentEnvironmentData)) { + $current = $this->_currentGoalState; + + if (is_null($current->getEnvironmentPath())) { + throw new RoleEnvironmentNotAvailableException( + 'No role environment data for the current goal state' + ); + } + + $environmentStream = $this->_inputChannel->getInputStream( + $current->getEnvironmentPath() + ); + + $this->_currentEnvironmentData = $this->_roleEnvironmentDeserializer + ->deserialize($environmentStream); + } + + return $this->_currentEnvironmentData; + } + + /** + * Sets the endpoint. + * + * @param string $endpoint Sets the endpoint. + * + * @return none + */ + public function setEndpoint($endpoint) + { + $this->_endpoint = $endpoint; + } + + /** + * Gets the endpoint. + * + * @return string + */ + public function getEndpoint() + { + return $this->_endpoint; + } + + /** + * Sets the keep open state. + * + * @param string $keepOpen Sets the keep open state. + * + * @return none + */ + public function setKeepOpen($keepOpen) + { + $this->_keepOpen = $keepOpen; + } + + /** + * Gets the keep open state. + * + * @return bool + */ + public function getKeepOpen() + { + return $this->_keepOpen; + } + + /** + * Ensures that the goal state is retrieved. + * + * @return none + */ + private function _ensureGoalStateRetrieved() + { + if (is_null($this->_currentGoalState) || !$this->_keepOpen) { + $inputStream = $this->_inputChannel->getInputStream($this->_endpoint); + $this->_goalStateDeserializer->initialize($inputStream); + } + + $goalState = $this->_goalStateDeserializer->deserialize(); + if (is_null($goalState)) { + return; + } + + $this->_currentGoalState = $goalState; + + if (!is_null($goalState->getEnvironmentPath())) { + $this->_currentEnvironmentData = null; + } + + $this->_currentStateClient->setEndpoint( + $this->_currentGoalState->getCurrentStateEndpoint() + ); + + if (!$this->_keepOpen) { + $this->_inputChannel->closeInputStream(); + } + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/ReleaseCurrentState.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/ReleaseCurrentState.php new file mode 100644 index 0000000..b111ea2 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/ReleaseCurrentState.php @@ -0,0 +1,50 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceRuntime\Internal; + +/** + * The release current state request. + * + * @category Microsoft + * @package WindowsAzure\ServiceRuntime\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class ReleaseCurrentState extends CurrentState +{ + /** + * Constructor + * + * @param string $clientId The client identifier. + */ + public function __construct($clientId) + { + parent::__construct($clientId); + } +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/Role.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/Role.php new file mode 100644 index 0000000..f3e1160 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/Role.php @@ -0,0 +1,92 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceRuntime\Internal; +use WindowsAzure\Common\Internal\Validate; + +/** + * The role data. + * + * @category Microsoft + * @package WindowsAzure\ServiceRuntime\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class Role +{ + /** + * @var string + */ + private $_name; + + /** + * @var array + */ + private $_instances; + + /** + * Constructor + * + * @param string $name The role name. + * @param array $instances The role instances. + */ + public function __construct($name, $instances) + { + Validate::isArray($instances, 'instances'); + + $this->_name = $name; + $this->_instances = $instances; + } + + /** + * Returns the collection of instances for the role. + * + * The number of instances of a role to be deployed to Windows Azure is + * specified in the service's configuration file. + * + * A role must define at least one internal endpoint in order for its set + * of instances to be known at runtime. + * + * @return array + */ + public function getInstances() + { + return $this->_instances; + } + + /** + * Returns the name of the role as it is declared in the service definition + * file. + * + * @return string + */ + public function getName() + { + return $this->_name; + } +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/RoleEnvironmentConfigurationSettingChange.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/RoleEnvironmentConfigurationSettingChange.php new file mode 100644 index 0000000..d070601 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/RoleEnvironmentConfigurationSettingChange.php @@ -0,0 +1,65 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceRuntime\Internal; + +/** + * The role environment configuration setting change. + * + * @category Microsoft + * @package WindowsAzure\ServiceRuntime\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class RoleEnvironmentConfigurationSettingChange implements IRoleEnvironmentChange +{ + /** + * @var string + */ + private $_settingName; + + /** + * Constructor + * + * @param string $settingName The setting name. + */ + public function __construct($settingName) + { + $this->_settingName = $settingName; + } + + /** + * Returns the name of the configuration setting that has been changed. + * + * @return string + */ + public function getConfigurationSettingName() + { + return $this->_settingName; + } +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/RoleEnvironmentData.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/RoleEnvironmentData.php new file mode 100644 index 0000000..83df91e --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/RoleEnvironmentData.php @@ -0,0 +1,152 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceRuntime\Internal; + +/** + * The role environment data. + * + * @category Microsoft + * @package WindowsAzure\ServiceRuntime\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class RoleEnvironmentData +{ + /** + * @var string + */ + private $_deploymentId; + + /** + * @var array + */ + private $_configurationSettings; + + /** + * @var array + */ + private $_localResources; + + /** + * @var RoleInstance + */ + private $_currentInstance; + + /** + * @var array + */ + private $_roles; + + /** + * @var boolean + */ + private $_isEmulated; + + /** + * Constructor + * + * @param string $deploymentId The deployment identifier. + * @param array $configurationSettings The configuration settings. + * @param array $localResources The local resources. + * @param RoleInstance $currentInstance The current instance information. + * @param array $roles The instance roles. + * @param boolean $isEmulated Boolean value indicating if + * the instance is running in the emulator. + */ + public function __construct($deploymentId, $configurationSettings, + $localResources, $currentInstance, $roles, $isEmulated + ) { + $this->_deploymentId = $deploymentId; + $this->_configurationSettings = $configurationSettings; + $this->_localResources = $localResources; + $this->_currentInstance = $currentInstance; + $this->_roles = $roles; + $this->_isEmulated = $isEmulated; + } + + /** + * Gets the configuration settings. + * + * @return array + */ + function getConfigurationSettings() + { + return $this->_configurationSettings; + } + + /** + * Gets the local resources. + * + * @return array + */ + function getLocalResources() + { + return $this->_localResources; + } + + /** + * Gets the current instance. + * + * @return RoleInstance + */ + function getCurrentInstance() + { + return $this->_currentInstance; + } + + /** + * Gets the roles. + * + * @return array + */ + function getRoles() + { + return $this->_roles; + } + + /** + * Gets the deployment identifier. + * + * @return string + */ + function getDeploymentId() + { + return $this->_deploymentId; + } + + /** + * Indicates if it is emulated. + * + * @return boolean + */ + function isEmulated() + { + return $this->_isEmulated; + } +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/RoleEnvironmentNotAvailableException.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/RoleEnvironmentNotAvailableException.php new file mode 100644 index 0000000..8c5aaa5 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/RoleEnvironmentNotAvailableException.php @@ -0,0 +1,41 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceRuntime\Internal; + +/** + * Custom exception when the role environment is not available. + * + * @category Microsoft + * @package WindowsAzure\ServiceRuntime\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class RoleEnvironmentNotAvailableException extends \Exception +{ +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/RoleEnvironmentTopologyChange.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/RoleEnvironmentTopologyChange.php new file mode 100644 index 0000000..aa684cd --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/RoleEnvironmentTopologyChange.php @@ -0,0 +1,65 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceRuntime\Internal; + +/** + * The role environment topology change. + * + * @category Microsoft + * @package WindowsAzure\ServiceRuntime\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class RoleEnvironmentTopologyChange implements IRoleEnvironmentChange +{ + /** + * @var string + */ + private $_roleName; + + /** + * Constructor + * + * @param string $roleName The role name. + */ + public function __construct($roleName) + { + $this->_roleName = $roleName; + } + + /** + * Returns the name of the role. + * + * @return string + */ + public function getRoleName() + { + return $this->_roleName; + } +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/RoleInstance.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/RoleInstance.php new file mode 100644 index 0000000..bdce6bd --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/RoleInstance.php @@ -0,0 +1,150 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceRuntime\Internal; + +/** + * The role instance data. + * + * @category Microsoft + * @package WindowsAzure\ServiceRuntime\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class RoleInstance +{ + /** + * @var string + */ + private $_id; + + /** + * @var integer + */ + private $_faultDomain; + + /** + * @var integer + */ + private $_updateDomain; + + /** + * @var array + */ + private $_endpoints; + + /** + * @var Role + */ + private $_role; + + /** + * Constructor + * + * @param string $id The identifier. + * @param integer $faultDomain The fault domain. + * @param integer $updateDomain The update domain. + * @param array $endpoints The endpoints. + */ + public function __construct($id, $faultDomain, $updateDomain, $endpoints) + { + $this->_id = $id; + $this->_faultDomain = $faultDomain; + $this->_updateDomain = $updateDomain; + $this->_endpoints = $endpoints; + } + + /** + * Returns the ID of this instance. + * + * The returned ID is unique to the application domain of the role's + * instance. If an instance is terminated and has been configured to + * restart automatically, the restarted instance will have the same ID + * as the terminated instance. + * + * @return string + */ + public function getId() + { + return $this->_id; + } + + /** + * Returns an integer value that indicates the fault domain in which this + * instance resides. + * + * @return integer + */ + public function getFaultDomain() + { + return $this->_faultDomain; + } + + /** + * Returns an integer value that indicates the update domain in which this + * instance resides. + * + * @return integer + */ + public function getUpdateDomain() + { + return $this->_updateDomain; + } + + /** + * Returns the Role object associated with this instance. + * + * @return Role + */ + public function getRole() + { + return $this->_role; + } + + /** + * Sets the Role object associated with this instance. + * + * @param Role $role The role object. + * + * @return Role + */ + public function setRole($role) + { + $this->_role = $role; + } + + /** + * Returns the set of endpoints associated with this role instance. + * + * @return array + */ + public function getInstanceEndpoints() + { + return $this->_endpoints; + } +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/RoleInstanceEndpoint.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/RoleInstanceEndpoint.php new file mode 100644 index 0000000..5b6ca1f --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/RoleInstanceEndpoint.php @@ -0,0 +1,126 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceRuntime\Internal; + +/** + * The role instance endpoint data. + * + * @category Microsoft + * @package WindowsAzure\ServiceRuntime\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class RoleInstanceEndpoint +{ + /** + * @var RoleInstance + */ + private $_roleInstance; + + /** + * @var string + */ + private $_protocol; + + /** + * @var string + */ + private $_address; + + /** + * @var string + */ + private $_port; + + /** + * Constructor + * + * @param string $protocol The protocol. + * @param string $address The Address. + * @param string $port The Port. + */ + public function __construct($protocol, $address, $port) + { + $this->_protocol = $protocol; + $this->_address = $address; + $this->_port = $port; + } + + /** + * Sets the role instance. + * + * @param RoleInstance $roleInstance The role instance. + * + * @return none + */ + public function setRoleInstance($roleInstance) + { + $this->_roleInstance = $roleInstance; + } + + /** + * Returns the RoleInstance object associated with this endpoint. + * + * @return RoleInstance + */ + public function getRoleInstance() + { + return $this->_roleInstance; + } + + /** + * Returns the protocol associated with the endpoint. + * + * @return string + */ + public function getProtocol() + { + return $this->_protocol; + } + + /** + * Return the address. + * + * @return string + */ + public function getAddress() + { + return $this->_address; + } + + /** + * Return the port. + * + * @return string + */ + public function getPort() + { + return $this->_port; + } +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/RoleInstanceStatus.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/RoleInstanceStatus.php new file mode 100644 index 0000000..65dc411 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/RoleInstanceStatus.php @@ -0,0 +1,54 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceRuntime\Internal; + +/** + * The role instance status. + * + * @category Microsoft + * @package WindowsAzure\ServiceRuntime\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class RoleInstanceStatus +{ + /** + * The role instance is unavailable for requests. + * + * @var int + */ + const BUSY = 0; + + /** + * The role instance is ready to accept requests. + * + * @var int + */ + const READY = 1; +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/RuntimeKernel.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/RuntimeKernel.php new file mode 100644 index 0000000..3442613 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/RuntimeKernel.php @@ -0,0 +1,253 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceRuntime\Internal; + +/** + * The runtime kernel. + * + * @category Microsoft + * @package WindowsAzure\ServiceRuntime\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class RuntimeKernel +{ + /** + * The singleton instance of the runtime kernel. + * + * @var type + */ + private static $_theKernel; + + /** + * The current state serializer. + * + * @var type + */ + private $_currentStateSerializer; + + /** + * The goal state deserializer. + * + * @var type + */ + private $_goalStateDeserializer; + + /** + * The input channel. + * + * @var IInputChannel + */ + private $_inputChannel; + + /** + * The output channel. + * + * @var IOutputChannel + */ + private $_outputChannel; + + /** + * The runtime current state client. + * + * @var Protocol1RuntimeCurrentStateClient + */ + private $_protocol1RuntimeCurrentStateClient; + + /** + * The role environment data deserializer. + * + * @var IRoleEnvironmentDataDeserializer + */ + private $_roleEnvironmentDataDeserializer; + + /** + * The runtime goal state client. + * + * @var Protocol1RuntimeGoalStateClient + */ + private $_protocol1RuntimeGoalStateClient; + + /** + * The runtime version protocol client. + * + * @var RuntimeVersionProtocolClient + */ + private $_runtimeVersionProtocolClient; + + /** + * The runtime version manager. + * + * @var RuntimeVersionManager + */ + private $_runtimeVersionManager; + + /** + * Constructor + */ + private function __construct() + { + $this->_currentStateSerializer = new XmlCurrentStateSerializer(); + $this->_goalStateDeserializer = new ChunkedGoalStateDeserializer(); + $this->_inputChannel = new FileInputChannel(); + $this->_outputChannel = new FileOutputChannel(); + + $this->_protocol1RuntimeCurrentStateClient = new + Protocol1RuntimeCurrentStateClient( + $this->_currentStateSerializer, + $this->_outputChannel + ); + + $this->_roleEnvironmentDataDeserializer = new + XmlRoleEnvironmentDataDeserializer(); + + $this->_protocol1RuntimeGoalStateClient = new + Protocol1RuntimeGoalStateClient( + $this->_protocol1RuntimeCurrentStateClient, + $this->_goalStateDeserializer, + $this->_roleEnvironmentDataDeserializer, + $this->_inputChannel + ); + + $this->_runtimeVersionProtocolClient = new RuntimeVersionProtocolClient( + $this->_inputChannel + ); + + $this->_runtimeVersionManager = new RuntimeVersionManager( + $this->_runtimeVersionProtocolClient + ); + } + + /** + * Gets the current kernel instance. + * + * @param boolean $forceNewInstance Boolean value indicating if a new instance + * should be obtained even if a previous one exists. + * + * @return RuntimeKernel + */ + public static function getKernel($forceNewInstance = false) + { + if (is_null(self::$_theKernel) || $forceNewInstance) { + self::$_theKernel = new RuntimeKernel(); + } + + return self::$_theKernel; + } + + /** + * Gets the current state serializer. + * + * @return ICurrentStateSerializer + */ + public function getCurrentStateSerializer() + { + return $this->_currentStateSerializer; + } + + /** + * Gets the goal state deserializer. + * + * @return IGoalStateDeserializer + */ + public function getGoalStateDeserializer() + { + return $this->_goalStateDeserializer; + } + + /** + * Gets the input channel. + * + * @return IInputChannel + */ + public function getInputChannel() + { + return $this->_inputChannel; + } + + /** + * Gets the output channel. + * + * @return IOutputChannel + */ + public function getOutputChannel() + { + return $this->_outputChannel; + } + + /** + * Gets the runtime current state client. + * + * @return Protocol1RuntimeCurrentStateClient + */ + public function getProtocol1RuntimeCurrentStateClient() + { + return $this->_protocol1RuntimeCurrentStateClient; + } + + /** + * Gets the role environment data deserializer. + * + * @return IRoleEnvironmentDataDeserializer + */ + public function getRoleEnvironmentDataDeserializer() + { + return $this->_roleEnvironmentDataDeserializer; + } + + /** + * Gets the runtime goal state client. + * + * @return Protocol1RuntimeGoalStateClient + */ + public function getProtocol1RuntimeGoalStateClient() + { + return $this->_protocol1RuntimeGoalStateClient; + } + + /** + * Gets the runtime version protocol client. + * + * @return RuntimeVersionProtocolClient + */ + public function getRuntimeVersionProtocolClient() + { + return $this->_runtimeVersionProtocolClient; + } + + /** + * Gets the runtime version manager. + * + * @return RuntimeVersionManager + */ + public function getRuntimeVersionManager() + { + return $this->_runtimeVersionManager; + } +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/RuntimeVersionManager.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/RuntimeVersionManager.php new file mode 100644 index 0000000..8eb2edc --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/RuntimeVersionManager.php @@ -0,0 +1,94 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceRuntime\Internal; +use WindowsAzure\Common\Internal\Resources; + +/** + * The runtime version manager. + * + * @category Microsoft + * @package WindowsAzure\ServiceRuntime\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class RuntimeVersionManager +{ + /** + * The protocol client. + * + * @var RuntimeVersionProtocolClient + */ + private $_protocolClient; + + /** + * The supported versions list. + * + * @var array + */ + private $_supportedVersionList; + + /** + * Constructor + * + * @param RuntimeVersionProtocolClient $protocolClient The runtime version + * protocol client. + */ + public function __construct($protocolClient) + { + $this->_protocolClient = $protocolClient; + + $this->_supportedVersionList = array(); + array_push( + $this->_supportedVersionList, + new Protocol1RuntimeClientFactory() + ); + } + + /** + * Gets the runtime client. + * + * @param string $versionEndpoint The endpoint's version. + * + * @return Protocol1RuntimeClient + */ + public function getRuntimeClient($versionEndpoint) + { + $versionMap = $this->_protocolClient->getVersionMap($versionEndpoint); + + foreach ($this->_supportedVersionList as $factory) { + if (array_key_exists($factory->getVersion(), $versionMap)) { + return $factory->createRuntimeClient( + $versionMap[$factory->getVersion()] + ); + } + } + + throw new \RuntimeException(Resources::INVALID_VERSION_MSG); + } +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/RuntimeVersionProtocolClient.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/RuntimeVersionProtocolClient.php new file mode 100644 index 0000000..1663a53 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/RuntimeVersionProtocolClient.php @@ -0,0 +1,91 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceRuntime\Internal; +use WindowsAzure\Common\Internal\Utilities; + +/** + * The runtime version protocol client. + * + * @category Microsoft + * @package WindowsAzure\ServiceRuntime\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class RuntimeVersionProtocolClient +{ + /** + * The input channel. + * + * @var IInputChannel + */ + private $_inputChannel; + + /** + * Constructor + * + * @param IInputChannel $inputChannel The input channel. + */ + public function __construct($inputChannel) + { + $this->_inputChannel = $inputChannel; + } + + /** + * Gets the version map. + * + * @param string $connectionPath The connection path. + * + * @return array + */ + public function getVersionMap($connectionPath) + { + $versions = array(); + + $input = $this->_inputChannel->getInputStream($connectionPath); + $contents = stream_get_contents($input); + + $discoveryInfo = Utilities::unserialize($contents); + + $endpoints = $discoveryInfo['RuntimeServerEndpoints'] + ['RuntimeServerEndpoint']; + + if (array_key_exists('@attributes', $endpoints)) { + $endpoints = array(); + $endpoints[] = $discoveryInfo + ['RuntimeServerEndpoints']['RuntimeServerEndpoint']; + } + + foreach ($endpoints as $endpoint) { + $versions[$endpoint['@attributes']['version']] = $endpoint + ['@attributes']['path']; + } + + return $versions; + } +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/XmlCurrentStateSerializer.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/XmlCurrentStateSerializer.php new file mode 100644 index 0000000..ce34749 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/XmlCurrentStateSerializer.php @@ -0,0 +1,75 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceRuntime\Internal; +use WindowsAzure\Common\Internal\Utilities; + +/** + * The XML current state serializer. + * + * @category Microsoft + * @package WindowsAzure\ServiceRuntime\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class XmlCurrentStateSerializer +{ + /** + * Serializes the current state. + * + * @param CurrentState $state The current state. + * @param IOutputStream $outputStream The output stream. + * + * @return none + */ + public function serialize($state, $outputStream) + { + $statusLeaseInfo = array( + 'StatusLease' => array( + '@attributes' => array( + 'ClientId' => $state->getClientId() + ) + ) + ); + + if ($state instanceof AcquireCurrentState) { + $statusLeaseInfo['StatusLease']['Acquire'] = array( + 'Incarnation' => $state->getIncarnation(), + 'Status' => $state->getStatus(), + 'Expiration' => Utilities::isoDate( + date_timestamp_get($state->getExpiration()) + ) + ); + } else if ($state instanceof ReleaseCurrentState) { + $statusLeaseInfo['StatusLease']['Release'] = array(); + } + + $currentState = Utilities::serialize($statusLeaseInfo, 'CurrentState'); + fwrite($outputStream, $currentState); + } +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/XmlGoalStateDeserializer.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/XmlGoalStateDeserializer.php new file mode 100644 index 0000000..d981cb0 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/XmlGoalStateDeserializer.php @@ -0,0 +1,61 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceRuntime\Internal; +use WindowsAzure\Common\Internal\Utilities; + +/** + * The XML goal state deserializer. + * + * @category Microsoft + * @package WindowsAzure\ServiceRuntime\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class XmlGoalStateDeserializer +{ + /** + * Deserializes a goal state. + * + * @param string $document The goal state document. + * + * @return GoalState + */ + public function deserialize($document) + { + $goalStateInfo = Utilities::unserialize($document); + + return new GoalState( + $goalStateInfo['Incarnation'], + $goalStateInfo['ExpectedState'], + $goalStateInfo['RoleEnvironmentPath'], + new \DateTime($goalStateInfo['Deadline']), + $goalStateInfo['CurrentStateEndpoint'] + ); + } +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/XmlRoleEnvironmentDataDeserializer.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/XmlRoleEnvironmentDataDeserializer.php new file mode 100644 index 0000000..d2527ca --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/Internal/XmlRoleEnvironmentDataDeserializer.php @@ -0,0 +1,309 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceRuntime\Internal; +use WindowsAzure\Common\Internal\Utilities; + +/** + * The XML role environment data deserializer. + * + * @category Microsoft + * @package WindowsAzure\ServiceRuntime\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class XmlRoleEnvironmentDataDeserializer +{ + /** + * Deserializes the role environment data. + * + * @param IInputChannel $inputChannel The input Channel. + * + * @return RoleEnvironmentData + */ + public function deserialize($inputChannel) + { + $document = stream_get_contents($inputChannel); + + $environmentInfo = Utilities::unserialize($document); + + $configurationSettings = $this->_translateConfigurationSettings( + $environmentInfo + ); + + $localResources = $this->_translateLocalResources($environmentInfo); + $currentInstance = $this + ->_translateCurrentInstance($environmentInfo); + $roles = $this->_translateRoles( + $environmentInfo, + $currentInstance, + $environmentInfo['CurrentInstance']['@attributes']['roleName'] + ); + + return new RoleEnvironmentData( + $environmentInfo['Deployment']['@attributes']['id'], + $configurationSettings, + $localResources, + $currentInstance, + $roles, + ($environmentInfo['Deployment']['@attributes']['emulated'] == 'true') + ); + } + + /** + * Translates the configuration settings. + * + * @param string $environmentInfo The role environment info. + * + * @return array + */ + private function _translateConfigurationSettings($environmentInfo) + { + $configurationSettings = array(); + + $settingsInfo = Utilities::tryGetKeysChainValue( + $environmentInfo, + 'CurrentInstance', + 'ConfigurationSettings', + 'ConfigurationSetting' + ); + + if (!is_null($settingsInfo)) { + if (array_key_exists('@attributes', $settingsInfo)) { + $settingsInfo = array(0 => $settingsInfo); + } + + foreach ($settingsInfo as $settingInfo) { + $configurationSettings + [$settingInfo['@attributes']['name']] = $settingInfo + ['@attributes']['value']; + } + } + + return $configurationSettings; + } + + /** + * Translates the local resources. + * + * @param string $environmentInfo The role environment info. + * + * @return array + */ + private function _translateLocalResources($environmentInfo) + { + $localResourcesMap = array(); + + $localResourcesInfo = Utilities::tryGetKeysChainValue( + $environmentInfo, + 'CurrentInstance', + 'LocalResources', + 'LocalResource' + ); + + if (!is_null($localResourcesInfo)) { + if (array_key_exists('@attributes', $localResourcesInfo)) { + $localResourcesInfo = array(0 => $localResourcesInfo); + } + + foreach ($localResourcesInfo as $localResourceInfo) { + $localResource = new LocalResource( + $localResourceInfo['@attributes']['sizeInMB'], + $localResourceInfo['@attributes']['name'], + $localResourceInfo['@attributes']['path'] + ); + + $localResourcesMap[$localResource->getName()] = $localResource; + } + } + + return $localResourcesMap; + } + + /** + * Translates the roles. + * + * @param string $environmentInfo The role environment info. + * @param RoleInstance $currentInstance The current instance info. + * @param string $currentRole The current role. + * + * @return array + */ + private function _translateRoles($environmentInfo, $currentInstance, + $currentRole + ) { + $rolesMap = array(); + + $rolesInfo = Utilities::tryGetKeysChainValue( + $environmentInfo, + 'Roles', + 'Role' + ); + + if (!is_null($rolesInfo)) { + if (array_key_exists('@attributes', $rolesInfo)) { + $rolesInfo = array(0 => $rolesInfo); + } + + foreach ($rolesInfo as $roleInfo) { + $roleInstances = $this->_translateRoleInstances($roleInfo); + + if ($roleInfo['@attributes']['name'] == $currentRole) { + $roleInstances[$currentInstance->getId()] = $currentInstance; + } + + $role = new Role($roleInfo['@attributes']['name'], $roleInstances); + + foreach ($roleInstances as $instance) { + $instance->setRole($role); + } + + $rolesMap[$roleInfo['@attributes']['name']] = $role; + } + } + + if (!array_key_exists($currentRole, $rolesMap)) { + $roleInstances = array(); + $roleInstances[$currentInstance->getId()] = $currentInstance; + + $singleRole = new Role($currentRole, $roleInstances); + $currentInstance->setRole($singleRole); + + $rolesMap[$currentRole] = $singleRole; + } + + return $rolesMap; + } + + /** + * Translates the role instances. + * + * @param string $instancesInfo The instance info. + * + * @return array + */ + private function _translateRoleInstances($instancesInfo) + { + $roleInstanceMap = array(); + + $instances = Utilities::tryGetKeysChainValue( + $instancesInfo, + 'Instances', + 'Instance' + ); + + if (!is_null($instances)) { + if (array_key_exists('@attributes', $instances)) { + $instances = array(0 => $instances); + } + + foreach ($instances as $instanceInfo) { + $endpoints = $this->_translateRoleInstanceEndpoints( + $instanceInfo['Endpoints']['Endpoint'] + ); + + $roleInstance = new RoleInstance( + $instanceInfo['@attributes']['id'], + $instanceInfo['@attributes']['faultDomain'], + $instanceInfo['@attributes']['updateDomain'], + $endpoints + ); + + $roleInstanceMap + [$instanceInfo['@attributes']['id']] = $roleInstance; + } + } + + return $roleInstanceMap; + } + + /** + * Translates the role instance endpoints. + * + * @param string $endpointsInfo The endpoints info. + * + * @return array + */ + private function _translateRoleInstanceEndpoints($endpointsInfo) + { + $endpointsMap = array(); + + $endpoints = $endpointsInfo; + if (array_key_exists('@attributes', $endpoints)) { + $endpoints = array(0 => $endpointsInfo); + } + + foreach ($endpoints as $endpoint) { + $roleInstanceEndpoint = new RoleInstanceEndpoint( + $endpoint['@attributes']['protocol'], + $endpoint['@attributes']['address'], + intval($endpoint['@attributes']['port'], 10) + ); + + $endpointsMap[$endpoint['@attributes']['name']] = $roleInstanceEndpoint; + } + + return $endpointsMap; + } + + /** + * Translates the current instance info. + * + * @param string $environmentInfo The environment info. + * + * @return RoleInstance + */ + private function _translateCurrentInstance($environmentInfo) + { + $endpoints = array(); + + $endpointsInfo = Utilities::tryGetKeysChainValue( + $environmentInfo, + 'CurrentInstance', + 'Endpoints', + 'Endpoint' + ); + + if (!is_null($endpointsInfo)) { + $endpoints = $this->_translateRoleInstanceEndpoints($endpointsInfo); + } + + $currentInstance = new RoleInstance( + $environmentInfo['CurrentInstance']['@attributes']['id'], + $environmentInfo['CurrentInstance']['@attributes']['faultDomain'], + $environmentInfo['CurrentInstance']['@attributes']['updateDomain'], + $endpoints + ); + + foreach ($currentInstance->getInstanceEndpoints() as $endpoint) { + $endpoint->setRoleInstance($currentInstance); + } + + return $currentInstance; + } +} + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/RoleEnvironment.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/RoleEnvironment.php new file mode 100644 index 0000000..044f7ee --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/ServiceRuntime/RoleEnvironment.php @@ -0,0 +1,964 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\ServiceRuntime; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\ServiceRuntime\Internal\RuntimeKernel; +use WindowsAzure\ServiceRuntime\Internal\RoleEnvironmentNotAvailableException; +use WindowsAzure\ServiceRuntime\Internal\ChannelNotAvailableException; +use WindowsAzure\ServiceRuntime\Internal\CurrentStatus; +use WindowsAzure\ServiceRuntime\Internal\AcquireCurrentState; +use WindowsAzure\ServiceRuntime\Internal\ReleaseCurrentState; +use WindowsAzure\ServiceRuntime\Internal\RoleInstanceStatus; +use WindowsAzure\ServiceRuntime\Internal\RoleEnvironmentConfigurationSettingChange; +use WindowsAzure\ServiceRuntime\Internal\RoleEnvironmentTopologyChange; + +/** + * Represents the Windows Azure environment in which an instance of a role is + * running. + * + * @category Microsoft + * @package WindowsAzure\ServiceRuntime + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class RoleEnvironment +{ + /** + * Specifies the environment variable that contains the path to the endpoint. + * + * @var string + */ + const VERSION_ENDPOINT_ENVIRONMENT_NAME = 'WaRuntimeEndpoint'; + + /** + * Specifies the endpoint fixed path. + * + * @var string + */ + const VERSION_ENDPOINT_FIXED_PATH = '\\\\.\\pipe\\WindowsAzureRuntime'; + + /** + * @var string + */ + private static $_clientId; + + /** + * @var \DateTime + */ + private static $_maxDateTime; + + /** + * @var IRuntimeClient + */ + private static $_runtimeClient; + + /** + * @var GoalState + */ + private static $_currentGoalState; + + /** + * @var RoleEnvironmentData + */ + private static $_currentEnvironmentData; + + /** + * @var array + */ + private static $_changingListeners; + + /** + * @var array + */ + private static $_changedListeners; + + /** + * @var array + */ + private static $_stoppingListeners; + + /** + * @var CurrentState + */ + private static $_lastState; + + /** + * @var string + */ + private static $_versionEndpoint; + + /** + * @var mix + */ + private static $_tracking; + + /** + * Initializes the role environment. + * + * @static + * + * @return none + */ + public static function init() + { + self::$_clientId = uniqid(); + + // 2038-01-19 04:14:07 + self::$_maxDateTime = new \DateTime( + date(Resources::TIMESTAMP_FORMAT, Resources::INT32_MAX) + ); + + self::$_tracking = true; + } + + /** + * Returns the client identifier. + * + * @static + * + * @return string + */ + public static function getClientId() + { + return self::$_clientId; + } + + /** + * Initializes the runtime client. + * + * @param bool $keepOpen Boolean value indicating if the connection + * should remain open. + * + * @static + * + * @return none + */ + private static function _initialize($keepOpen = false) + { + try { + if (is_null(self::$_runtimeClient)) { + self::$_versionEndpoint = getenv( + self::VERSION_ENDPOINT_ENVIRONMENT_NAME + ); + + if (self::$_versionEndpoint == false) { + self::$_versionEndpoint = self::VERSION_ENDPOINT_FIXED_PATH; + } + + $kernel = RuntimeKernel::getKernel(); + $kernel->getProtocol1RuntimeGoalStateClient()->setKeepOpen( + $keepOpen + ); + + self::$_runtimeClient = $kernel->getRuntimeVersionManager() + ->getRuntimeClient(self::$_versionEndpoint); + + self::$_currentGoalState = self::$_runtimeClient + ->getCurrentGoalState(); + + self::$_currentEnvironmentData = self::$_runtimeClient + ->getRoleEnvironmentData(); + } else { + self::$_currentGoalState = self::$_runtimeClient + ->getCurrentGoalState(); + + self::$_currentEnvironmentData = self::$_runtimeClient + ->getRoleEnvironmentData(); + } + } catch (ChannelNotAvailableException $ex) { + throw new RoleEnvironmentNotAvailableException(); + } + } + + /** + * Tracks role environment changes raising events as necessary. + * + * This method is blocking and can/should be called in a separate fork. + * + * @static + * + * @return none + */ + public static function trackChanges() + { + self::_initialize(true); + + while (self::$_tracking) { + $newGoalState = self::$_runtimeClient->getCurrentGoalState(); + + switch ($newGoalState->getExpectedState()) { + case CurrentStatus::STARTED: + $newIncarnation = $newGoalState->getIncarnation(); + $currentIncarnation = self::$_currentGoalState->getIncarnation(); + + if ($newIncarnation > $currentIncarnation) { + self::_processGoalStateChange($newGoalState); + } + + break; + case CurrentStatus::STOPPED: + self::_raiseStoppingEvent(); + + $stoppedState = new AcquireCurrentState( + self::$_clientId, + $newGoalState->getIncarnation(), + CurrentStatus::STOPPED, + self::$_maxDateTime + ); + + self::$_runtimeClient->setCurrentState($stoppedState); + break; + } + + if (is_int(self::$_tracking)) { + self::$_tracking--; + } + } + } + + /** + * Processes a goal state change. + * + * @param GoalState $newGoalState The new goal state. + * + * @static + * + * @return none + */ + private static function _processGoalStateChange($newGoalState) + { + $last = self::$_lastState; + $changes = self::_calculateChanges(); + + if (count($changes) == 0) { + self::_acceptLatestIncarnation($newGoalState, $last); + } else { + self::_raiseChangingEvent($changes); + + self::_acceptLatestIncarnation($newGoalState, $last); + + self::$_currentEnvironmentData = self::$_runtimeClient + ->getRoleEnvironmentData(); + + self::_raiseChangedEvent($changes); + } + } + + /** + * Accepts the latest incarnation. + * + * @param GoalState $newGoalState The new goal state. + * @param CurrentState $last The last state. + * + * @static + * + * @return none + */ + private static function _acceptLatestIncarnation($newGoalState, $last) + { + if (!is_null($last) && $last instanceof AcquireCurrentState) { + $acquireState = $last; + + $acceptState = new AcquireCurrentState( + self::$_clientId, + $newGoalState->getIncarnation(), + $acquireState->getStatus(), + $acquireState->getExpiration() + ); + + self::$_runtimeClient->setCurrentState($acceptState); + } + + self::$_currentGoalState = $newGoalState; + } + + /** + * Raises a stopping event. + * + * @static + * + * @return none + */ + private static function _raiseStoppingEvent() + { + foreach (self::$_stoppingListeners as $callback) { + call_user_func($callback); + } + } + + /** + * Raises a changing event. + * + * @param array $changes The changes. + * + * @static + * + * @return none + */ + private static function _raiseChangingEvent($changes) + { + foreach (self::$_changingListeners as $callback) { + call_user_func($callback, $changes); + } + } + + /** + * Raises a changed event. + * + * @param array $changes The changes. + * + * @static + * + * @return none + */ + private static function _raiseChangedEvent($changes) + { + foreach (self::$_changedListeners as $callback) { + call_user_func($callback, $changes); + } + } + + /** + * Calculates changes. + * + * @static + * + * @return array + */ + private static function _calculateChanges() + { + $current = self::$_currentEnvironmentData; + $newData = self::$_runtimeClient->getRoleEnvironmentData(); + + $changes = self::_calculateConfigurationChanges($current, $newData); + + $currentRoles = $current->getRoles(); + $newRoles = $newData->getRoles(); + $changedRoleSet = array(); + + foreach ($currentRoles as $roleName => $role) { + if (array_key_exists($roleName, $newRoles)) { + $currentRole = $currentRoles[$roleName]; + $newRole = $newRoles[$roleName]; + + $currentRoleInstances = $currentRole->getInstances(); + $newRoleInstances = $newRole->getInstances(); + + $changedRoleSet = array_merge( + $changedRoleSet, + self::_calculateNewRoleInstanceChanges( + $role, + $currentRoleInstances, + $newRoleInstances + ) + ); + } else { + $changedRoleSet[] = $role; + } + } + + foreach ($newRoles as $roleName => $role) { + if (array_key_exists($roleName, $currentRoles)) { + $currentRole = $currentRoles[$roleName]; + $newRole = $newRoles[$roleName]; + + $currentRoleInstances = $currentRole->getInstances(); + $newRoleInstances = $newRole->getInstances(); + + $changedRoleSet = array_merge( + $changedRoleSet, + self::_calculateCurrentRoleInstanceChanges( + $role, + $currentRoleInstances, + $newRoleInstances + ) + ); + } else { + $changedRoleSet[] = $role; + } + } + + foreach ($changedRoleSet as $role) { + $changes[] = new RoleEnvironmentTopologyChange($role); + } + + return $changes; + } + + /** + * Calculates the configuration changes. + * + * @param RoleEnvironmentData $currentRoleEnvironment The current role + * environment data. + * @param RoleEnvionrmentData $newRoleEnvironment The new role + * environment data. + * + * @static + * + * @return array + */ + private static function _calculateConfigurationChanges( + $currentRoleEnvironment, $newRoleEnvironment + ) { + $changes = array(); + $currentConfig = $currentRoleEnvironment->getConfigurationSettings(); + $newConfig = $newRoleEnvironment->getConfigurationSettings(); + + foreach ($currentConfig as $settingKey => $setting) { + if (array_key_exists($settingKey, $newConfig)) { + if ($newConfig[$settingKey] != $currentConfig[$settingKey]) { + $changes[] = new RoleEnvironmentConfigurationSettingChange( + $settingKey + ); + } + } else { + $changes[] = new RoleEnvironmentConfigurationSettingChange( + $settingKey + ); + } + } + + foreach ($newConfig as $settingKey => $setting) { + if (!array_key_exists($settingKey, $currentConfig)) { + $changes[] = new RoleEnvironmentConfigurationSettingChange( + $settingKey + ); + } + } + + return $changes; + } + + /** + * Calculates which instances / instance endpoints were added from the current + * role to the new role. + * + * @param RoleInstance $role The current role. + * @param array $currentRoleInstances The current role instances. + * @param array $newRoleInstances The new role instances. + * + * @static + * + * @return array + */ + private static function _calculateNewRoleInstanceChanges( + $role, $currentRoleInstances, $newRoleInstances + ) { + $changedRoleSet = array(); + + foreach ($currentRoleInstances as $instanceKey => $currentInstance) { + if (array_key_exists($instanceKey, $newRoleInstances)) { + $newInstance = $newRoleInstances[$instanceKey]; + + $currentUpdateDomain = $currentInstance->getUpdateDomain(); + $newUpdateDomain = $newInstance->getUpdateDomain(); + $currentFaultDomain = $currentInstance->getFaultDomain(); + $newFaultDomain = $newInstance->getFaultDomain(); + + if ($currentUpdateDomain == $newUpdateDomain + && $currentFaultDomain == $newFaultDomain + ) { + $currentInstanceEndpoints = $currentInstance + ->getInstanceEndpoints(); + $newInstanceEndpoints = $newInstance->getInstanceEndpoints(); + + $changedRoleSet = array_merge( + $changedRoleSet, + self::_calculateNewRoleInstanceEndpointsChanges( + $role, + $currentInstanceEndpoints, + $newInstanceEndpoints + ) + ); + } else { + $changedRoleSet[] = $role; + } + } else { + $changedRoleSet[] = $role; + } + } + + return $changedRoleSet; + } + + /** + * Calculates which endpoints / endpoint were added from the current + * role to the new role. + * + * @param RoleInstance $role The current role. + * @param array $currentInstanceEndpoints The current instance endpoints. + * @param array $newInstanceEndpoints The new instance endpoints. + * + * @static + * + * @return array + */ + private static function _calculateNewRoleInstanceEndpointsChanges( + $role, $currentInstanceEndpoints, $newInstanceEndpoints + ) { + $changedRoleSet = array(); + + foreach ($currentInstanceEndpoints as $endpointKey => $currentEndpoint) { + if (array_key_exists($endpointKey, $newInstanceEndpoints)) { + $newEndpoint = $newInstanceEndpoints[$endpointKey]; + + $currentProtocol = $currentEndpoint->getProtocol(); + $newProtocol = $newEndpoint->getProtocol(); + $currentAddress = $currentEndpoint->getAddress(); + $newAddress = $newEndpoint->getAddress(); + $currentPort = $currentEndpoint->getPort(); + $newPort = $newEndpoint->getPort(); + if ($currentProtocol != $newProtocol + || $currentAddress != $newAddress + || $currentPort != $newPort + ) { + $changedRoleSet[] = $role; + } + } else { + $changedRoleSet[] = $role; + } + } + + return $changedRoleSet; + } + + /** + * Calculates which instances / instance endpoints were removed from the current + * role to the new role. + * + * @param RoleInstance $role The current role. + * @param array $currentRoleInstances The current role instances. + * @param array $newRoleInstances The new role instances. + * + * @static + * + * @return array + */ + private static function _calculateCurrentRoleInstanceChanges( + $role, $currentRoleInstances, $newRoleInstances + ) { + $changedRoleSet = array(); + + foreach ($newRoleInstances as $instanceKey => $newInstance) { + if (array_key_exists($instanceKey, $currentRoleInstances)) { + $currentInstance = $currentRoleInstances[$instanceKey]; + + $currentUpdateDomain = $currentInstance->getUpdateDomain(); + $newUpdateDomain = $newInstance->getUpdateDomain(); + $currentFaultDomain = $currentInstance->getFaultDomain(); + $newFaultDomain = $newInstance->getFaultDomain(); + + if ($currentUpdateDomain == $newUpdateDomain + && $currentFaultDomain == $newFaultDomain + ) { + $newInstanceEndpoints = $newInstance + ->getInstanceEndpoints(); + $currentInstanceEndpoints = $currentInstance + ->getInstanceEndpoints(); + + $changedRoleSet = array_merge( + $changedRoleSet, + self::_calculateCurrentRoleInstanceEndpointsChanges( + $role, + $currentInstanceEndpoints, + $newInstanceEndpoints + ) + ); + } + // Intentionally not adding since if the values are different, + // it should have already been added + } else { + $changedRoleSet[] = $role; + } + } + + return $changedRoleSet; + } + + /** + * Calculates which endpoints / endpoint were removed from the current + * role to the new role. + * + * @param RoleInstance $role The current changed role set. + * @param array $currentInstanceEndpoints The current instance endpoints. + * @param array $newInstanceEndpoints The new instance endpoints. + * + * @static + * + * @return array + */ + private static function _calculateCurrentRoleInstanceEndpointsChanges( + $role, $currentInstanceEndpoints, $newInstanceEndpoints + ) { + $changedRoleSet = array(); + + foreach ($newInstanceEndpoints as $endpointKey => $newEndpoint) { + if (!array_key_exists( + $endpointKey, + $currentInstanceEndpoints + ) + ) { + $changedRoleSet[] = $role; + } + } + + return $changedRoleSet; + } + + /** + * Returns a RoleInstance object that represents the role instance + * in which this code is currently executing. + * + * @static + * + * @return RoleInstance + */ + public static function getCurrentRoleInstance() + { + self::_initialize(); + + return self::$_currentEnvironmentData->getCurrentInstance(); + } + + /** + * Returns the deployment ID that uniquely identifies the deployment in + * which this role instance is running. + * + * @static + * + * @return string + */ + public static function getDeploymentId() + { + self::_initialize(); + + return self::$_currentEnvironmentData->getDeploymentId(); + } + + /** + * Indicates whether the role instance is running in the Windows Azure + * environment. + * + * @static + * + * @return boolean + */ + public static function isAvailable() + { + try { + self::_initialize(); + } catch (RoleEnvironmentNotAvailableException $ex) { + return false; + } catch (ChannelNotAvailableException $ex) { + return false; + } + + return self::$_runtimeClient != null; + } + + /** + * Indicates whether the role instance is running in the development fabric. + * + * @static + * + * @return boolean + */ + public static function isEmulated() + { + self::_initialize(); + + return self::$_currentEnvironmentData->isEmulated(); + } + + /** + * Returns the set of Role objects defined for your service. + * + * Roles are defined in the service definition file. + * + * @static + * + * @return array + */ + public static function getRoles() + { + self::_initialize(); + + return self::$_currentEnvironmentData->getRoles(); + } + + /** + * Retrieves the settings in the service configuration file. + * + * A role's configuration settings are defined in the service definition + * file. Values for configuration settings are set in the service + * configuration file. + * + * @static + * + * @return array + */ + public static function getConfigurationSettings() + { + self::_initialize(); + + return self::$_currentEnvironmentData->getConfigurationSettings(); + } + + /** + * Retrieves the set of named local storage resources. + * + * @static + * + * @return array + */ + public static function getLocalResources() + { + self::_initialize(); + + return self::$_currentEnvironmentData->getLocalResources(); + } + + /** + * Requests that the current role instance be stopped and restarted. + * Before the role instance is recycled, the Windows Azure load balancer + * takes the role instance out of rotation. + * + * This ensures that no new requests are routed to the instance while it + * is restarting. + * + * @static + * + * @return none + */ + public static function requestRecycle() + { + self::_initialize(); + + $recycleState = new AcquireCurrentState( + self::$_clientId, + self::$_currentGoalState->getIncarnation(), + CurrentStatus::RECYCLE, + self::$_maxDateTime + ); + + self::$_runtimeClient->setCurrentState($recycleState); + } + + /** + * Sets the status of the role instance. + * + * An instance may indicate that it is in one of two states: Ready or Busy. + * If an instance's state is Ready, it is prepared to receive requests from + * the load balancer. If the instance's state is Busy, it will not receive + * requests from the load balancer. + * + * @param RoleInstanceStatus $status The new role status. + * @param \DateTime $expirationUtc The expiration UTC time. + * + * @static + * + * @return none + */ + public static function setStatus($status, $expirationUtc) + { + self::_initialize(); + + $currentStatus = CurrentStatus::STARTED; + + switch ($status) { + case RoleInstanceStatus::BUSY: + $currentStatus = CurrentStatus::BUSY; + break; + case RoleInstanceStatus::READY: + $currentStatus = CurrentStatus::STARTED; + break; + } + + $newState = new AcquireCurrentState( + self::$_clientId, + self::$_currentGoalState->getIncarnation(), + $currentStatus, + $expirationUtc + ); + + self::$_lastState = $newState; + + self::$_runtimeClient->setCurrentState($newState); + } + + /** + * Clears the status of the role instance. + * + * An instance may indicate that it has completed communicating status by + * calling this method. + * + * @static + * + * @return none + */ + public static function clearStatus() + { + self::_initialize(); + + $newState = new ReleaseCurrentState(self::$_clientId); + + self::$_lastState = $newState; + + self::$_runtimeClient->setCurrentState($newState); + } + + /** + * Adds an event listener for the changed event, which occurs + * after a configuration change has been applied to a role instance. + * + * To listen for events, one should call trackChanges. + * + * @param function $listener The changed listener. + * + * @return none + */ + public static function addRoleEnvironmentChangedListener($listener) + { + self::$_changedListeners[] = $listener; + } + + /** + * Removes an event listener for the Changed event. + * + * @param function $listener The changed listener. + * + * @static + * + * @return bool + */ + public static function removeRoleEnvironmentChangedListener($listener) + { + foreach (self::$_changedListeners as $key => $changedListener) { + if ($changedListener == $listener) { + unset(self::$_changedListeners[$key]); + return true; + } + } + + return false; + } + + /** + * Adds an event listener for the Changing event, which occurs + * before a change to the service configuration is applied to the running + * instances of the role. + * + * Service configuration changes are applied on-the-fly to running role + * instances. Configuration changes include changes to the service + * configuration changes and changes to the number of instances in the + * service. + * + * This event occurs after the new configuration file has been submitted to + * Windows Azure but before the changes have been applied to each running + * role instance. This event can be cancelled for a given instance to + * prevent the configuration change. + * + * Note that cancelling this event causes the instance to be automatically + * recycled. When the instance is recycled, the configuration change is + * applied when it restarts. + * + * To listen for events, one should call trackChanges. + * + * @param function $listener The changing listener. + * + * @static + * + * @return none + */ + public static function addRoleEnvironmentChangingListener($listener) + { + self::$_changingListeners[] = $listener; + } + + /** + * Removes an event listener for the Changing event. + * + * @param function $listener The changing listener. + * + * @static + * + * @return bool + */ + public static function removeRoleEnvironmentChangingListener($listener) + { + foreach (self::$_changingListeners as $key => $changingListener) { + if ($changingListener == $listener) { + unset(self::$_changingListeners[$key]); + return true; + } + } + + return false; + } + + /** + * Adds an event listener for the Stopping event, which occurs + * when the role is stopping. + * To listen for events, one should call trackChanges. + * + * @param function $listener The stopping listener. + * + * @static + * + * @return none + */ + public static function addRoleEnvironmentStoppingListener($listener) + { + self::$_stoppingListeners[] = $listener; + } + + /** + * Removes an event listener for the Stopping event. + * + * @param function $listener The stopping listener. + * + * @static + * + * @return bool + */ + public static function removeRoleEnvironmentStoppingListener($listener) + { + foreach (self::$_stoppingListeners as $key => $stoppingListener) { + if ($stoppingListener == $listener) { + unset(self::$_stoppingListeners[$key]); + return true; + } + } + + return false; + } +} + +// Initialize static fields +RoleEnvironment::init(); + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Internal/AtomReaderWriter.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Internal/AtomReaderWriter.php new file mode 100644 index 0000000..84e813a --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Internal/AtomReaderWriter.php @@ -0,0 +1,375 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Table\Internal; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Table\Models\EdmType; +use WindowsAzure\Table\Models\Entity; + +/** + * Serializes and unserializes results from table wrapper calls + * + * @category Microsoft + * @package WindowsAzure\Table\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class AtomReaderWriter implements IAtomReaderWriter +{ + /** + * @var string + */ + private $_atomNamespaceName; + + /** + * @var string + */ + private $_dataServicesNamespaceName; + + /** + * @var string + */ + private $_dataServicesMetadataNamespaceName; + + /** + * @var string + */ + private $_xmlVersion; + + /** + * @var string + */ + private $_xmlEncoding; + + /** + * @var string + */ + private $_dataServicesPrefix; + + /** + * @var string + */ + private $_dataServicesMetadataPrefix; + + /** + * Generates the atom XML properties. + * + * @param \XmlWriter $xmlw The XML writer. + * @param array $properties The atom properties. + * + * @return none + */ + private function _generateProperties($xmlw, $properties) + { + foreach ($properties as $key => $value) { + $content = key($value); + $attributes = $value[$content]; + $xmlw->startElementNS($this->_dataServicesPrefix, $key, null); + if (!is_null($attributes)) { + foreach ($attributes as $attribute => $attributeValue) { + $xmlw->writeAttributeNS( + $this->_dataServicesMetadataPrefix, + $attribute, + null, + $attributeValue + ); + } + } + $xmlw->text($content); + $xmlw->endElement(); + } + } + + /** + * Serializes the atom into XML representation. + * + * @param array $properties The atom properties. + * + * @return string + */ + private function _serializeAtom($properties) + { + $xmlw = new \XmlWriter(); + $xmlw->openMemory(); + $xmlw->setIndent(true); + $xmlw->startDocument( + strtoupper($this->_xmlVersion), + $this->_xmlEncoding, + 'yes' + ); + $xmlw->startElementNS(null, 'entry', $this->_atomNamespaceName); + $xmlw->writeAttribute( + "xmlns:$this->_dataServicesPrefix", + $this->_dataServicesNamespaceName + ); + $xmlw->writeAttribute( + "xmlns:$this->_dataServicesMetadataPrefix", + $this->_dataServicesMetadataNamespaceName + ); + $xmlw->writeElement('title'); + $xmlw->writeElement('updated', Utilities::isoDate()); + $xmlw->startElement('author'); + $xmlw->writeElement('name'); + $xmlw->endElement(); + $xmlw->writeElement('id'); + $xmlw->startElement('content'); + $xmlw->writeAttribute('type', Resources::XML_CONTENT_TYPE); + $xmlw->startElementNS( + $this->_dataServicesMetadataPrefix, + 'properties', + null + ); + $this->_generateProperties($xmlw, $properties); + $xmlw->endElement(); + $xmlw->endElement(); + $xmlw->endElement(); + + return $xmlw->outputMemory(true); + } + + /** + * Creates new SimpleXml from Atom XML and registers the namespaces prefixes. + * + * @param string $body Response from HTTP call. + * + * @return \SimpleXml + */ + private function _parseBody($body) + { + $xml = simplexml_load_string($body); + + if ($xml !== false) { + $xml->registerXPathNamespace( + $this->_dataServicesPrefix, + $this->_dataServicesNamespaceName + ); + $xml->registerXPathNamespace( + $this->_dataServicesMetadataPrefix, + $this->_dataServicesMetadataNamespaceName + ); + } + + return $xml; + } + + /** + * Parses one table entry and returns the table name. + * + * @param \SimpleXml $result The original XML body loaded in XML. + * + * @return string + */ + private function _parseOneTable($result) + { + $query = ".//$this->_dataServicesMetadataPrefix:properties/"; + $query .= "$this->_dataServicesPrefix:TableName"; + $tableName = $result->xpath($query); + $table = (string)$tableName[0]; + + return $table; + } + + /** + * Gets entry nodes from the XML body. + * + * @param \SimpleXml $body The original XML body loaded in XML. + * + * @return array + */ + private function _getRawEntries($body) + { + $rawEntries = array(); + + if (!is_null($body) && $body->entry) { + $rawEntries = $body->entry; + } + + return $rawEntries; + } + + /** + * Parses an entity entry from given SimpleXML object. + * + * @param \SimpleXML $result The SimpleXML object representing the entity. + * + * @return \WindowsAzure\Table\Models\Entity + */ + private function _parseOneEntity($result) + { + $prefix = $this->_dataServicesMetadataPrefix; + $prop = $result->content->xpath(".//$prefix:properties"); + $prop = $prop[0]->children($this->_dataServicesNamespaceName); + $entity = new Entity(); + + // Set ETag + $etag = $result->attributes($this->_dataServicesMetadataNamespaceName); + $etag = $etag[Resources::ETAG]; + $entity->setETag((string)$etag); + + foreach ($prop as $key => $value) { + $attributes = $value->attributes( + $this->_dataServicesMetadataNamespaceName + ); + $type = $attributes['type']; + $isnull = $attributes['null']; + $value = EdmType::unserializeQueryValue((string)$type, $value); + + $entity->addProperty( + (string)$key, + is_null($type) ? null : (string)$type, + $isnull ? null : $value + ); + } + + return $entity; + } + + /** + * Constructs new AtomReaderWriter object. + */ + public function __construct() + { + $this->_atomNamespaceName = Resources::ATOM_XML_NAMESPACE; + $this->_dataServicesNamespaceName = Resources::DS_XML_NAMESPACE; + $this->_dataServicesMetadataNamespaceName = Resources::DSM_XML_NAMESPACE; + $this->_dataServicesPrefix = 'd'; + $this->_dataServicesMetadataPrefix = 'm'; + $this->_xmlVersion = '1.0'; + $this->_xmlEncoding = 'UTF-8'; + } + + /** + * Constructs XML representation for table entry. + * + * @param string $name The name of the table. + * + * @return string + */ + public function getTable($name) + { + return $this->_serializeAtom(array('TableName' => array($name => null))); + } + + /** + * Parses one table entry. + * + * @param string $body The HTTP response body. + * + * @return string + */ + public function parseTable($body) + { + $result = $this->_parseBody($body); + return $this->_parseOneTable($result); + } + + /** + * Constructs array of tables from HTTP response body. + * + * @param string $body The HTTP response body. + * + * @return array + */ + public function parseTableEntries($body) + { + $tables = array(); + $result = $this->_parseBody($body); + $rawEntries = $this->_getRawEntries($result); + + foreach ($rawEntries as $entry) { + $tables[] = $this->_parseOneTable($entry); + } + + return $tables; + } + + /** + * Constructs XML representation for entity. + * + * @param Models\Entity $entity The entity instance. + * + * @return string + */ + public function getEntity($entity) + { + $entityProperties = $entity->getProperties(); + $properties = array(); + + foreach ($entityProperties as $name => $property) { + $attributes = array(); + $edmType = $property->getEdmType(); + $edmValue = $property->getValue(); + if (!is_null($edmType)) { + $attributes['type'] = $edmType; + } + if (is_null($edmValue)) { + $attributes['null'] = 'true'; + } + $value = EdmType::serializeValue($edmType, $edmValue); + $properties[$name] = array($value => $attributes); + } + + return $this->_serializeAtom($properties); + } + + /** + * Constructs entity from HTTP response body. + * + * @param string $body The HTTP response body. + * + * @return Entity + */ + public function parseEntity($body) + { + $result = $this->_parseBody($body); + $entity = $this->_parseOneEntity($result); + return $entity; + } + + /** + * Constructs array of entities from HTTP response body. + * + * @param string $body The HTTP response body. + * + * @return array + */ + public function parseEntities($body) + { + $result = $this->_parseBody($body); + $entities = array(); + $rawEntries = $this->_getRawEntries($result); + + foreach ($rawEntries as $entity) { + $entities[] = $this->_parseOneEntity($entity); + } + + return $entities; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Internal/IAtomReaderWriter.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Internal/IAtomReaderWriter.php new file mode 100644 index 0000000..e53b61f --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Internal/IAtomReaderWriter.php @@ -0,0 +1,95 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Table\Internal; + +/** + * Defines how to serialize and unserialize table wrapper xml + * + * @category Microsoft + * @package WindowsAzure\Table\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +interface IAtomReaderWriter +{ + /** + * Constructs XML representation for table entry. + * + * @param string $name The name of the table. + * + * @return string + */ + public function getTable($name); + + /** + * Parses one table entry. + * + * @param string $body The HTTP response body. + * + * @return string + */ + public function parseTable($body); + + /** + * Constructs array of tables from HTTP response body. + * + * @param string $body The HTTP response body. + * + * @return array + */ + public function parseTableEntries($body); + + /** + * Constructs XML representation for entity. + * + * @param Models\Entity $entity The entity instance. + * + * @return string + */ + public function getEntity($entity); + + /** + * Constructs entity from HTTP response body. + * + * @param string $body The HTTP response body. + * + * @return Models\Entity + */ + public function parseEntity($body); + + /** + * Constructs array of entities from HTTP response body. + * + * @param string $body The HTTP response body. + * + * @return array + */ + public function parseEntities($body); +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Internal/IMimeReaderWriter.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Internal/IMimeReaderWriter.php new file mode 100644 index 0000000..1228596 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Internal/IMimeReaderWriter.php @@ -0,0 +1,62 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Table\Internal; + +/** + * Interface for MIME reading and writing. + * + * @category Microsoft + * @package WindowsAzure\Table\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +interface IMimeReaderWriter +{ + /** + * Given array of MIME parts in raw string, this function converts them into MIME + * representation. + * + * @param array $bodyPartContents The MIME body parts. + * + * @return array Returns array with two elements 'headers' and 'body' which + * represents the MIME message. + */ + public function encodeMimeMultipart($bodyPartContents); + + /** + * Parses given mime HTTP response body into array. Each array element + * represents a change set result. + * + * @param string $mimeBody The raw MIME body result. + * + * @return array + */ + public function decodeMimeMultipart($mimeBody); +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Internal/ITable.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Internal/ITable.php new file mode 100644 index 0000000..f18776d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Internal/ITable.php @@ -0,0 +1,233 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Table\Internal; +use WindowsAzure\Common\Internal\FilterableService; + +/** + * This interface has all REST APIs provided by Windows Azure for Table service. + * + * @category Microsoft + * @package WindowsAzure\Table\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179423.aspx + */ +interface ITable extends FilterableService +{ + /** + * Gets the properties of the Table service. + * + * @param Models\TableServiceOptions $options optional table service options. + * + * @return WindowsAzure\Common\Models\GetServicePropertiesResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/hh452238.aspx + */ + public function getServiceProperties($options = null); + + /** + * Sets the properties of the Table service. + * + * @param ServiceProperties $serviceProperties new service properties + * @param Models\TableServiceOptions $options optional parameters + * + * @return none. + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/hh452240.aspx + */ + public function setServiceProperties($serviceProperties, $options = null); + + /** + * Quries tables in the given storage account. + * + * @param Models\QueryTablesOptions|string|Models\Filter $options Could be + * optional parameters, table prefix or filter to apply. + * + * @return Models\QueryTablesResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179405.aspx + */ + public function queryTables($options = null); + + /** + * Creates new table in the storage account + * + * @param string $table The name of the table. + * @param Models\TableServiceOptions $options optional parameters + * + * @return none + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd135729.aspx + */ + public function createTable($table, $options = null); + + /** + * Gets the table. + * + * @param string $table The The name of the table.. + * @param Models\TableServiceOptions $options The optional parameters. + * + * @return Models\GetTableResult + */ + public function getTable($table, $options = null); + + /** + * Deletes the specified table and any data it contains. + * + * @param string $table The name of the table. + * @param Models\TableServiceOptions $options optional parameters + * + * @return none + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179387.aspx + */ + public function deleteTable($table, $options = null); + + /** + * Quries entities for the given table name + * + * @param string $table The name of + * the table. + * @param Models\QueryEntitiesOptions|string|Models\Filter $options Coule be + * optional parameters, query string or filter to apply. + * + * @return Models\QueryEntitiesResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179421.aspx + */ + public function queryEntities($table, $options = null); + + /** + * Inserts new entity to the table + * + * @param string $table name of the table + * @param Models\Entity $entity table entity + * @param Models\TableServiceOptions $options optional parameters + * + * @return Models\InsertEntityResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179433.aspx + */ + public function insertEntity($table, $entity, $options = null); + + /** + * Updates an existing entity or inserts a new entity if it does not exist in the + * table. + * + * @param string $table name of the table + * @param Models\Entity $entity table entity + * @param Models\TableServiceOptions $options optional parameters + * + * @return Models\UpdateEntityResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/hh452241.aspx + */ + public function insertOrMergeEntity($table, $entity, $options = null); + + /** + * Replaces an existing entity or inserts a new entity if it does not exist in + * the table. + * + * @param string $table name of the table + * @param Models\Entity $entity table entity + * @param Models\TableServiceOptions $options optional parameters + * + * @return Models\UpdateEntityResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/hh452242.aspx + */ + public function insertOrReplaceEntity($table, $entity, $options = null); + + /** + * Updates an existing entity in a table. The Update Entity operation replaces + * the entire entity and can be used to remove properties. + * + * @param string $table The table name. + * @param Models\Entity $entity The table entity. + * @param Models\TableServiceOptions $options The optional parameters. + * + * @return Models\UpdateEntityResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179427.aspx + */ + public function updateEntity($table, $entity, $options = null); + + /** + * Updates an existing entity by updating the entity's properties. This operation + * does not replace the existing entity, as the updateEntity operation does. + * + * @param string $table The table name. + * @param Models\Entity $entity The table entity. + * @param Models\TableServiceOptions $options The optional parameters. + * + * @return Models\UpdateEntityResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179392.aspx + */ + public function mergeEntity($table, $entity, $options = null); + + /** + * Deletes an existing entity in a table. + * + * @param string $table The name of the table. + * @param string $partitionKey The entity partition key. + * @param string $rowKey The entity row key. + * @param Models\DeleteEntityOptions $options The optional parameters. + * + * @return none + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd135727.aspx + */ + public function deleteEntity($table, $partitionKey, $rowKey, $options = null); + + /** + * Gets table entity. + * + * @param string $table The name of the table. + * @param string $partitionKey The entity partition key. + * @param string $rowKey The entity row key. + * @param Models\TableServiceOptions $options The optional parameters. + * + * @return Models\GetEntityResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179421.aspx + */ + public function getEntity($table, $partitionKey, $rowKey, $options = null); + + /** + * Does batch of operations on given table service. + * + * @param BatchOperations $operations the operations to apply + * @param Models\TableServiceOptions $options optional parameters + * + * @return Models\BatchResult + */ + public function batch($operations, $options = null); +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Internal/MimeReaderWriter.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Internal/MimeReaderWriter.php new file mode 100644 index 0000000..cf3d24a --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Internal/MimeReaderWriter.php @@ -0,0 +1,116 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Table\Internal; +require_once 'PEAR.php'; +require_once 'Mail/mimePart.php'; +require_once 'Mail/mimeDecode.php'; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Utilities; + +/** + * Reads and writes MIME for batch API. + * + * @category Microsoft + * @package WindowsAzure\Table\Internal + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class MimeReaderWriter implements IMimeReaderWriter +{ + /** + * Given array of MIME parts in raw string, this function converts them into MIME + * representation. + * + * @param array $bodyPartContents The MIME body parts. + * + * @return array Returns array with two elements 'headers' and 'body' which + * represents the MIME message. + */ + public function encodeMimeMultipart($bodyPartContents) + { + $count = count($bodyPartContents); + $mimeType = Resources::MULTIPART_MIXED_TYPE; + $batchGuid = Utilities::getGuid(); + $batchId = sprintf('batch_%s', $batchGuid); + $contentType1 = array('content_type' => "$mimeType"); + $changeSetGuid = Utilities::getGuid(); + $changeSetId = sprintf('changeset_%s', $changeSetGuid); + $contentType2 = array('content_type' => "$mimeType; boundary=$changeSetId"); + $options = array( + 'encoding' => 'binary', + 'content_type' => Resources::HTTP_TYPE + ); + + // Create changeset MIME part + $changeSet = new \Mail_mimePart(); + + for ($i = 0; $i < $count; $i++) { + $changeSet->addSubpart($bodyPartContents[$i], $options); + } + + // Encode the changeset MIME part + $changeSetEncoded = $changeSet->encode($changeSetId); + + // Create the batch MIME part + $batch = new \Mail_mimePart(Resources::EMPTY_STRING, $contentType1); + + // Add changeset encoded to batch MIME part + $batch->addSubpart($changeSetEncoded['body'], $contentType2); + + // Encode batch MIME part + $batchEncoded = $batch->encode($batchId); + + return $batchEncoded; + } + + /** + * Parses given mime HTTP response body into array. Each array element + * represents a change set result. + * + * @param string $mimeBody The raw MIME body result. + * + * @return array + */ + public function decodeMimeMultipart($mimeBody) + { + $params['include_bodies'] = true; + $params['input'] = $mimeBody; + $mimeDecoder = new \Mail_mimeDecode($mimeBody); + $structure = $mimeDecoder->decode($params); + $parts = $structure->parts; + $bodies = array(); + + foreach ($parts as $part) { + $bodies[] = $part->body; + } + + return $bodies; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/BatchError.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/BatchError.php new file mode 100644 index 0000000..0a3ccab --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/BatchError.php @@ -0,0 +1,125 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Table\Models; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Validate; +use WindowsAzure\Common\ServiceException; + +/** + * Represents an error returned from call to batch API. + * + * @category Microsoft + * @package WindowsAzure\Table\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class BatchError +{ + /** + * @var WindowsAzure\Common\ServiceException + */ + private $_error; + + /** + * @var integer + */ + private $_contentId; + + /** + * Creates BatchError object. + * + * @param WindowsAzure\Common\ServiceException $error The error object. + * @param array $headers The response headers. + * + * @return \WindowsAzure\Table\Models\BatchError + */ + public static function create($error, $headers) + { + Validate::isTrue( + $error instanceof ServiceException, + Resources::INVALID_EXC_OBJ_MSG + ); + Validate::isArray($headers, 'headers'); + + $result = new BatchError(); + $clean = array_change_key_case($headers); + + $result->setError($error); + $contentId = Utilities::tryGetValue($clean, Resources::CONTENT_ID); + $result->setContentId(is_null($contentId) ? null : intval($contentId)); + + return $result; + } + + /** + * Gets the error. + * + * @return WindowsAzure\Common\ServiceException + */ + public function getError() + { + return $this->_error; + } + + /** + * Sets the error. + * + * @param WindowsAzure\Common\ServiceException $error The error object. + * + * @return none + */ + public function setError($error) + { + $this->_error = $error; + } + + /** + * Gets the contentId. + * + * @return integer + */ + public function getContentId() + { + return $this->_contentId; + } + + /** + * Sets the contentId. + * + * @param integer $contentId The contentId object. + * + * @return none + */ + public function setContentId($contentId) + { + $this->_contentId = $contentId; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/BatchOperation.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/BatchOperation.php new file mode 100644 index 0000000..12e5897 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/BatchOperation.php @@ -0,0 +1,110 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Table\Models; +use WindowsAzure\Common\Internal\Validate; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Utilities; + +/** + * Represents one batch operation + * + * @category Microsoft + * @package WindowsAzure\Table\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class BatchOperation +{ + /** + * @var string + */ + private $_type; + + /** + * @var array + */ + private $_params; + + /** + * Sets operation type. + * + * @param string $type The operation type. Must be valid type. + * + * @return none + */ + public function setType($type) + { + Validate::isTrue( + BatchOperationType::isValid($type), + Resources::INVALID_BO_TYPE_MSG + ); + + $this->_type = $type; + } + + /** + * Gets operation type. + * + * @return string + */ + public function getType() + { + return $this->_type; + } + + /** + * Adds or sets parameter for the operation. + * + * @param string $name The param name. Must be valid name. + * @param mix $value The param value. + * + * @return none + */ + public function addParameter($name, $value) + { + Validate::isTrue( + BatchOperationParameterName::isValid($name), + Resources::INVALID_BO_PN_MSG + ); + $this->_params[$name] = $value; + } + + /** + * Gets parameter value and if the name doesn't exist, return null. + * + * @param string $name The parameter name. + * + * @return mix + */ + public function getParameter($name) + { + return Utilities::tryGetValue($this->_params, $name); + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/BatchOperationParameterName.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/BatchOperationParameterName.php new file mode 100644 index 0000000..9e2d6e1 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/BatchOperationParameterName.php @@ -0,0 +1,69 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Table\Models; + +/** + * Batch parameter names. + * + * @category Microsoft + * @package WindowsAzure\Table\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class BatchOperationParameterName +{ + const BP_TABLE = 'table'; + const BP_ENTITY = 'entity'; + const BP_PARTITION_KEY = 'PartitionKey'; + const BP_ROW_KEY = 'RowKey'; + const BP_ETAG = 'etag'; + + /** + * Validates if $paramName is already defined. + * + * @param string $paramName The batch operation parameter name. + * + * @return boolean + */ + public static function isValid($paramName) + { + switch ($paramName) { + case self::BP_TABLE: + case self::BP_ENTITY: + case self::BP_PARTITION_KEY: + case self::BP_ROW_KEY: + case self::BP_ETAG: + return true; + + default: + return false; + } + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/BatchOperationType.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/BatchOperationType.php new file mode 100644 index 0000000..a0f1e7b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/BatchOperationType.php @@ -0,0 +1,71 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Table\Models; + +/** + * Supported batch operations. + * + * @category Microsoft + * @package WindowsAzure\Table\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class BatchOperationType +{ + const INSERT_ENTITY_OPERATION = 'InsertEntityOperation'; + const UPDATE_ENTITY_OPERATION = 'UpdateEntityOperation'; + const DELETE_ENTITY_OPERATION = 'DeleteEntityOperation'; + const MERGE_ENTITY_OPERATION = 'MergeEntityOperation'; + const INSERT_REPLACE_ENTITY_OPERATION = 'InsertOrReplaceEntityOperation'; + const INSERT_MERGE_ENTITY_OPERATION = 'InsertOrMergeEntityOperation'; + + /** + * Validates if $type is already defined. + * + * @param string $type The operation type. + * + * @return boolean + */ + public static function isValid($type) + { + switch ($type) { + case self::INSERT_ENTITY_OPERATION: + case self::UPDATE_ENTITY_OPERATION: + case self::DELETE_ENTITY_OPERATION: + case self::MERGE_ENTITY_OPERATION: + case self::INSERT_REPLACE_ENTITY_OPERATION: + case self::INSERT_MERGE_ENTITY_OPERATION: + return true; + + default: + return false; + } + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/BatchOperations.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/BatchOperations.php new file mode 100644 index 0000000..17a39d3 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/BatchOperations.php @@ -0,0 +1,232 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Table\Models; +use WindowsAzure\Common\Internal\Validate; +use WindowsAzure\Common\Internal\Resources; + +/** + * Holds batch operation change set. + * + * @category Microsoft + * @package WindowsAzure\Table\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class BatchOperations +{ + /** + * @var array + */ + private $_operations; + + /** + * Default constructor. + */ + public function __construct() + { + $this->_operations = array(); + } + + /** + * Gets the batch operations. + * + * @return array + */ + public function getOperations() + { + return $this->_operations; + } + + /** + * Sets the batch operations. + * + * @param array $operations The batch operations. + * + * @return none + */ + public function setOperations($operations) + { + $this->_operations = array(); + foreach ($operations as $operation) { + $this->addOperation($operation); + } + } + + /** + * Adds operation to the batch operations. + * + * @param mix $operation The operation to add. + * + * @return none + */ + public function addOperation($operation) + { + Validate::isTrue( + $operation instanceof BatchOperation, + Resources::INVALID_BO_TYPE_MSG + ); + + $this->_operations[] = $operation; + } + + /** + * Adds insertEntity operation. + * + * @param string $table The table name. + * @param Entity $entity The entity instance. + * + * @return none + */ + public function addInsertEntity($table, $entity) + { + Validate::isString($table, 'table'); + Validate::notNullOrEmpty($entity, 'entity'); + + $operation = new BatchOperation(); + $type = BatchOperationType::INSERT_ENTITY_OPERATION; + $operation->setType($type); + $operation->addParameter(BatchOperationParameterName::BP_TABLE, $table); + $operation->addParameter(BatchOperationParameterName::BP_ENTITY, $entity); + $this->addOperation($operation); + } + + /** + * Adds updateEntity operation. + * + * @param string $table The table name. + * @param Entity $entity The entity instance. + * + * @return none + */ + public function addUpdateEntity($table, $entity) + { + Validate::isString($table, 'table'); + Validate::notNullOrEmpty($entity, 'entity'); + + $operation = new BatchOperation(); + $type = BatchOperationType::UPDATE_ENTITY_OPERATION; + $operation->setType($type); + $operation->addParameter(BatchOperationParameterName::BP_TABLE, $table); + $operation->addParameter(BatchOperationParameterName::BP_ENTITY, $entity); + $this->addOperation($operation); + } + + /** + * Adds mergeEntity operation. + * + * @param string $table The table name. + * @param Entity $entity The entity instance. + * + * @return none + */ + public function addMergeEntity($table, $entity) + { + Validate::isString($table, 'table'); + Validate::notNullOrEmpty($entity, 'entity'); + + $operation = new BatchOperation(); + $type = BatchOperationType::MERGE_ENTITY_OPERATION; + $operation->setType($type); + $operation->addParameter(BatchOperationParameterName::BP_TABLE, $table); + $operation->addParameter(BatchOperationParameterName::BP_ENTITY, $entity); + $this->addOperation($operation); + } + + /** + * Adds insertOrReplaceEntity operation. + * + * @param string $table The table name. + * @param Entity $entity The entity instance. + * + * @return none + */ + public function addInsertOrReplaceEntity($table, $entity) + { + Validate::isString($table, 'table'); + Validate::notNullOrEmpty($entity, 'entity'); + + $operation = new BatchOperation(); + $type = BatchOperationType::INSERT_REPLACE_ENTITY_OPERATION; + $operation->setType($type); + $operation->addParameter(BatchOperationParameterName::BP_TABLE, $table); + $operation->addParameter(BatchOperationParameterName::BP_ENTITY, $entity); + $this->addOperation($operation); + } + + /** + * Adds insertOrMergeEntity operation. + * + * @param string $table The table name. + * @param Entity $entity The entity instance. + * + * @return none + */ + public function addInsertOrMergeEntity($table, $entity) + { + Validate::isString($table, 'table'); + Validate::notNullOrEmpty($entity, 'entity'); + + $operation = new BatchOperation(); + $type = BatchOperationType::INSERT_MERGE_ENTITY_OPERATION; + $operation->setType($type); + $operation->addParameter(BatchOperationParameterName::BP_TABLE, $table); + $operation->addParameter(BatchOperationParameterName::BP_ENTITY, $entity); + $this->addOperation($operation); + } + + /** + * Adds deleteEntity operation. + * + * @param string $table The table name. + * @param string $partitionKey The entity partition key. + * @param string $rowKey The entity row key. + * @param string $etag The entity etag. + * + * @return none + */ + public function addDeleteEntity($table, $partitionKey, $rowKey, $etag = null) + { + Validate::isString($table, 'table'); + Validate::isTrue(!is_null($partitionKey), Resources::NULL_TABLE_KEY_MSG); + Validate::isTrue(!is_null($rowKey), Resources::NULL_TABLE_KEY_MSG); + + $operation = new BatchOperation(); + $type = BatchOperationType::DELETE_ENTITY_OPERATION; + $operation->setType($type); + $operation->addParameter(BatchOperationParameterName::BP_TABLE, $table); + $operation->addParameter(BatchOperationParameterName::BP_ROW_KEY, $rowKey); + $operation->addParameter(BatchOperationParameterName::BP_ETAG, $etag); + $operation->addParameter( + BatchOperationParameterName::BP_PARTITION_KEY, + $partitionKey + ); + $this->addOperation($operation); + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/BatchResult.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/BatchResult.php new file mode 100644 index 0000000..bb6b156 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/BatchResult.php @@ -0,0 +1,202 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Table\Models; +require_once 'HTTP/Request2/Response.php'; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Http\HttpClient; +use WindowsAzure\Common\ServiceException; +use WindowsAzure\Table\Models\BatchError; +use WindowsAzure\Table\Models\InsertEntityResult; +use WindowsAzure\Table\Models\UpdateEntityResult; + +/** + * Holds results from batch API. + * + * @category Microsoft + * @package WindowsAzure\Table\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class BatchResult +{ + /** + * Each entry represents change set result. + * + * @var array + */ + private $_entries; + + /** + * Creates a array of responses from the batch response body. + * + * @param string $body The HTTP response body. + * @param IMimeReaderWriter $mimeSerializer The MIME reader and writer. + * + * @return array + */ + private static function _constructResponses($body, $mimeSerializer) + { + $responses = array(); + $parts = $mimeSerializer->decodeMimeMultipart($body); + // Decrease the count of parts to remove the batch response body and just + // include change sets response body. We may need to undo this action in + // case that batch response body has useful info. + $count = count($parts) - 1; + + for ($i = 0; $i < $count; $i++) { + $lines = explode("\r\n", $parts[$i]); + $response = new \HTTP_Request2_Response($lines[0]); + $j = 1; + do { + $headerLine = $lines[$j++]; + $response->parseHeaderLine($headerLine); + } while (Resources::EMPTY_STRING != $headerLine); + $body = implode("\r\n", array_slice($lines, $j)); + $response->appendBody($body); + $responses[] = $response; + } + + return $responses; + } + + /** + * Compares between two responses by Content-ID header. + * + * @param \HTTP_Request2_Response $r1 The first response object. + * @param \HTTP_Request2_Response $r2 The second response object. + * + * @return boolean + */ + private static function _compareUsingContentId($r1, $r2) + { + $h1 = array_change_key_case($r1->getHeader()); + $h2 = array_change_key_case($r2->getHeader()); + $c1 = Utilities::tryGetValue($h1, Resources::CONTENT_ID, 0); + $c2 = Utilities::tryGetValue($h2, Resources::CONTENT_ID, 0); + + return intval($c1) >= intval($c2); + } + + + /** + * Creates BatchResult object. + * + * @param string $body The HTTP response body. + * @param array $operations The batch operations. + * @param array $contexts The batch operations context. + * @param IAtomReaderWriter $atomSerializer The Atom reader and writer. + * @param IMimeReaderWriter $mimeSerializer The MIME reader and writer. + * + * @return \WindowsAzure\Table\Models\BatchResult + * + * @throws \InvalidArgumentException + */ + public static function create($body, $operations, $contexts, $atomSerializer, + $mimeSerializer + ) { + $result = new BatchResult(); + $responses = self::_constructResponses($body, $mimeSerializer); + $callbackName = __CLASS__ . '::_compareUsingContentId'; + $count = count($responses); + $entries = array(); + + // Sort $responses based on Content-ID so they match order of $operations. + uasort($responses, $callbackName); + + for ($i = 0; $i < $count; $i++) { + $context = $contexts[$i]; + $response = $responses[$i]; + $operation = $operations[$i]; + $type = $operation->getType(); + $body = $response->getBody(); + $headers = $response->getHeader(); + + try { + HttpClient::throwIfError( + $response->getStatus(), + $response->getReasonPhrase(), + $response->getBody(), + $context->getStatusCodes() + ); + + switch ($type) { + case BatchOperationType::INSERT_ENTITY_OPERATION: + $entries[] = InsertEntityResult::create( + $body, + $headers, + $atomSerializer + ); + break; + case BatchOperationType::UPDATE_ENTITY_OPERATION: + case BatchOperationType::MERGE_ENTITY_OPERATION: + case BatchOperationType::INSERT_REPLACE_ENTITY_OPERATION: + case BatchOperationType::INSERT_MERGE_ENTITY_OPERATION: + $entries[] = UpdateEntityResult::create($headers); + break; + + case BatchOperationType::DELETE_ENTITY_OPERATION: + $entries[] = Resources::BATCH_ENTITY_DEL_MSG; + break; + + default: + throw new \InvalidArgumentException(); + } + } catch (ServiceException $e) { + $entries[] = BatchError::create($e, $response->getHeader()); + } + } + $result->setEntries($entries); + + return $result; + } + + /** + * Gets batch call result entries. + * + * @return array + */ + public function getEntries() + { + return $this->_entries; + } + + /** + * Sets batch call result entries. + * + * @param array $entries The batch call result entries. + * + * @return none + */ + public function setEntries($entries) + { + $this->_entries = $entries; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/DeleteEntityOptions.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/DeleteEntityOptions.php new file mode 100644 index 0000000..bf182e7 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/DeleteEntityOptions.php @@ -0,0 +1,70 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Table\Models; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Resources; + +/** + * Holds optional parameters for deleteEntity API. + * + * @category Microsoft + * @package WindowsAzure\Table\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class DeleteEntityOptions extends TableServiceOptions +{ + /** + * @var string + */ + private $_etag; + + /** + * Gets entity etag. + * + * @return string + */ + public function getETag() + { + return $this->_etag; + } + + /** + * Sets entity etag. + * + * @param string $etag The entity ETag. + * + * @return none + */ + public function setETag($etag) + { + $this->_etag = $etag; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/EdmType.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/EdmType.php new file mode 100644 index 0000000..3ef9dbe --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/EdmType.php @@ -0,0 +1,273 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Table\Models; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Validate; +use WindowsAzure\Common\Internal\Resources; + +/** + * Basic Windows Azure EDM Types used for table entity properties. + * + * @category Microsoft + * @package WindowsAzure\Table\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class EdmType +{ + // @codingStandardsIgnoreStart + + const DATETIME = 'Edm.DateTime'; + const BINARY = 'Edm.Binary'; + const BOOLEAN = 'Edm.Boolean'; + const DOUBLE = 'Edm.Double'; + const GUID = 'Edm.Guid'; + const INT32 = 'Edm.Int32'; + const INT64 = 'Edm.Int64'; + const STRING = 'Edm.String'; + + /** + * Converts the type to string if it's empty and validates the type. + * + * @param string $type The Edm type + * + * @return string + */ + public static function processType($type) + { + $type = empty($type) ? self::STRING : $type; + Validate::isTrue(self::isValid($type), Resources::INVALID_EDM_MSG); + + return $type; + } + + /** + * Validates that the value associated with the EDM type is valid. + * + * @param string $type The EDM type. + * @param mix $value The EDM value. + * @param string &$condition The error message. + * + * @return boolean + * + * @throws \InvalidArgumentException + */ + public static function validateEdmValue($type, $value, &$condition = null) + { + // Having null value means that the user wants to remove the property name + // associated with this value. Leave the value as null so this hold. + if (is_null($value)) { + return true; + } else { + switch ($type) { + case EdmType::GUID: + case EdmType::BINARY: + case EdmType::STRING: + case EdmType::INT64: + case null: + // NULL also is treated as EdmType::STRING + $condition = 'is_string'; + return is_string($value); + + case EdmType::DOUBLE: + $condition = 'is_double'; + return is_double($value); + + case EdmType::INT32: + $condition = 'is_int'; + return is_int($value); + + case EdmType::DATETIME: + $condition = 'instanceof \DateTime'; + return $value instanceof \DateTime; + + case EdmType::BOOLEAN: + $condition = 'is_bool'; + return is_bool($value); + + default: + throw new \InvalidArgumentException(); + } + } + } + + /** + * Serializes EDM value into proper value for sending it to Windows Azure. + * + * @param string $type The EDM type. + * @param mix $value The EDM value. + * + * @return string + * + * @throws \InvalidArgumentException + */ + public static function serializeValue($type, $value) + { + switch ($type) { + case EdmType::DOUBLE: + case EdmType::INT32: + case EdmType::INT64: + case EdmType::GUID: + case EdmType::STRING: + case null: + // NULL also is treated as EdmType::STRING + return strval($value); + + case EdmType::BINARY: + return base64_encode($value); + + case EdmType::DATETIME: + return Utilities::convertToEdmDateTime($value); + + case EdmType::BOOLEAN: + return (is_null($value) ? '' : ($value == true ? '1' : '0')); + + default: + throw new \InvalidArgumentException(); + } + } + + /** + * Serializes EDM value into proper value to be used in query. + * + * @param string $type The EDM type. + * @param mix $value The EDM value. + * + * @return string + * + * @throws \InvalidArgumentException + */ + public static function serializeQueryValue($type, $value) + { + switch ($type) { + case EdmType::DATETIME: + $edmDate = Utilities::convertToEdmDateTime($value); + return 'datetime\'' . $edmDate . '\''; + + case EdmType::BINARY: + return 'X\'' . implode('', unpack("H*", $value)) . '\''; + + case EdmType::BOOLEAN: + return ($value ? 'true' : 'false'); + + case EdmType::DOUBLE: + case EdmType::INT32: + return $value; + + case EdmType::INT64: + return $value . 'L'; + + case EdmType::GUID: + return 'guid\'' . $value . '\''; + + case null: + case EdmType::STRING: + // NULL also is treated as EdmType::STRING + return '\'' . str_replace('\'', '\'\'', $value) . '\''; + + default: + throw new \InvalidArgumentException(); + } + } + + /** + * Converts the value into its proper type. + * + * @param string $type The edm type. + * @param string $value The edm value. + * + * @return mix + * + * @throws \InvalidArgumentException + */ + public static function unserializeQueryValue($type, $value) + { + // Having null value means that the user wants to remove the property name + // associated with this value. Leave the value as null so this hold. + if (is_null($value)) { + return null; + } else { + switch ($type) { + case self::GUID: + case self::STRING: + case self::INT64: + case null: + // NULL also is treated as EdmType::STRING + return strval($value); + + case self::BINARY: + return base64_decode($value); + + case self::DATETIME: + return Utilities::convertToDateTime($value); + + case self::BOOLEAN: + return Utilities::toBoolean($value); + + case self::DOUBLE: + return doubleval($value); + + case self::INT32: + return intval($value); + + default: + throw new \InvalidArgumentException(); + } + } + } + + /** + * Check if the $type belongs to valid header types. + * + * @param string $type The type string to check. + * + * @return boolean + */ + public static function isValid($type) + { + switch($type) { + case $type == self::DATETIME: + case $type == self::BINARY: + case $type == self::BOOLEAN: + case $type == self::DOUBLE: + case $type == self::GUID: + case $type == self::INT32: + case $type == self::INT64: + case $type == self::STRING: + case $type == null: + // NULL also is treated as EdmType::STRING + return true; + + default: + return false; + + } + } + + // @codingStandardsIgnoreEnd +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/Entity.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/Entity.php new file mode 100644 index 0000000..f847e4f --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/Entity.php @@ -0,0 +1,296 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Table\Models; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Validate; + +/** + * Represents entity object used in tables + * + * @category Microsoft + * @package WindowsAzure\Table\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class Entity +{ + /** + * @var string + */ + private $_etag; + + /** + * @var array + */ + private $_properties; + + /** + * Validates if properties is valid or not. + * + * @param mix $properties The properties array. + * + * @return none + */ + private function _validateProperties($properties) + { + Validate::isArray($properties, 'entity properties'); + + foreach ($properties as $key => $value) { + Validate::isString($key, 'key'); + Validate::isTrue( + $value instanceof Property, + Resources::INVALID_PROP_MSG + ); + Validate::isTrue( + EdmType::validateEdmValue( + $value->getEdmType(), + $value->getValue(), + $condition + ), + sprintf(Resources::INVALID_PROP_VAL_MSG, $key, $condition) + ); + } + } + + /** + * Gets property value and if the property name is not found return null. + * + * @param string $name The property name. + * + * @return mix + */ + public function getPropertyValue($name) + { + $p = Utilities::tryGetValue($this->_properties, $name); + return is_null($p) ? null : $p->getValue(); + } + + /** + * Sets property value. + * + * Note that if the property doesn't exist, it doesn't add it. Use addProperty + * to add new properties. + * + * @param string $name The property name. + * @param mix $value The property value. + * + * @return mix + */ + public function setPropertyValue($name, $value) + { + $p = Utilities::tryGetValue($this->_properties, $name); + if (!is_null($p)) { + $p->setValue($value); + } + } + + /** + * Gets entity etag. + * + * @return string + */ + public function getETag() + { + return $this->_etag; + } + + /** + * Sets entity etag. + * + * @param string $etag The entity ETag value. + * + * @return none + */ + public function setETag($etag) + { + $this->_etag = $etag; + } + + /** + * Gets entity PartitionKey. + * + * @return string + */ + public function getPartitionKey() + { + return $this->getPropertyValue('PartitionKey'); + } + + /** + * Sets entity PartitionKey. + * + * @param string $partitionKey The entity PartitionKey value. + * + * @return none + */ + public function setPartitionKey($partitionKey) + { + $this->addProperty('PartitionKey', null, $partitionKey); + } + + /** + * Gets entity RowKey. + * + * @return string + */ + public function getRowKey() + { + return $this->getPropertyValue('RowKey'); + } + + /** + * Sets entity RowKey. + * + * @param string $rowKey The entity RowKey value. + * + * @return none + */ + public function setRowKey($rowKey) + { + $this->addProperty('RowKey', null, $rowKey); + } + + /** + * Gets entity Timestamp. + * + * @return \DateTime + */ + public function getTimestamp() + { + return $this->getPropertyValue('Timestamp'); + } + + /** + * Sets entity Timestamp. + * + * @param \DateTime $timestamp The entity Timestamp value. + * + * @return none + */ + public function setTimestamp($timestamp) + { + $this->addProperty('Timestamp', EdmType::DATETIME, $timestamp); + } + + /** + * Gets the entity properties array. + * + * @return array + */ + public function getProperties() + { + return $this->_properties; + } + + /** + * Sets the entity properties array. + * + * @param array $properties The entity properties. + * + * @return none + */ + public function setProperties($properties) + { + $this->_validateProperties($properties); + $this->_properties = $properties; + } + + /** + * Gets property object from the entity properties. + * + * @param string $name The property name. + * + * @return Property + */ + public function getProperty($name) + { + return Utilities::tryGetValue($this->_properties, $name); + } + + /** + * Sets entity property. + * + * @param string $name The property name. + * @param Property $property The property object. + * + * @return none + */ + public function setProperty($name, $property) + { + Validate::isTrue($property instanceof Property, Resources::INVALID_PROP_MSG); + $this->_properties[$name] = $property; + } + + /** + * Creates new entity property. + * + * @param string $name The property name. + * @param string $edmType The property edm type. + * @param mix $value The property value. + * + * @return none + */ + public function addProperty($name, $edmType, $value) + { + $p = new Property(); + $p->setEdmType($edmType); + $p->setValue($value); + $this->setProperty($name, $p); + } + + /** + * Checks if the entity object is valid or not. + * Valid means the partition and row key exists for this entity along with the + * timestamp. + * + * @param string &$msg The error message. + * + * @return boolean + */ + public function isValid(&$msg = null) + { + try { + $this->_validateProperties($this->_properties); + } catch (\Exception $exc) { + $msg = $exc->getMessage(); + return false; + } + + if ( is_null($this->getPartitionKey()) + || is_null($this->getRowKey()) + ) { + $msg = Resources::NULL_TABLE_KEY_MSG; + return false; + } else { + return true; + } + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/Filters/BinaryFilter.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/Filters/BinaryFilter.php new file mode 100644 index 0000000..f74222c --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/Filters/BinaryFilter.php @@ -0,0 +1,100 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Table\Models\Filters; + +/** + * Binary filter + * + * @category Microsoft + * @package WindowsAzure\Table\Models\Filters + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class BinaryFilter extends Filter +{ + /** + * @var string + */ + private $_operator; + + /** + * @var Filter + */ + private $_left; + + /** + * @var Filter + */ + private $_right; + + /** + * Constructor. + * + * @param Filter $left The left operand. + * @param string $operator The operator. + * @param Filter $right The right operand. + */ + public function __construct($left, $operator, $right) + { + $this->_left = $left; + $this->_operator = $operator; + $this->_right = $right; + } + + /** + * Gets operator + * + * @return string + */ + public function getOperator() + { + return $this->_operator; + } + + /** + * Gets left + * + * @return Filter + */ + public function getLeft() + { + return $this->_left; + } + + /** + * Gets right + * + * @return Filter + */ + public function getRight() + { + return $this->_right; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/Filters/ConstantFilter.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/Filters/ConstantFilter.php new file mode 100644 index 0000000..9b5ae50 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/Filters/ConstantFilter.php @@ -0,0 +1,84 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Table\Models\Filters; +use WindowsAzure\Table\Models\EdmType; + +/** + * Constant filter + * + * @category Microsoft + * @package WindowsAzure\Table\Models\Filters + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class ConstantFilter extends Filter +{ + /** + * @var mix + */ + private $_value; + + /** + * @var string + */ + private $_edmType; + + /** + * Constructor. + * + * @param string $edmType The EDM type. + * @param string $value The EDM value. + */ + public function __construct($edmType, $value) + { + $this->_edmType = EdmType::processType($edmType); + $this->_value = $value; + } + + /** + * Gets value + * + * @return mix + */ + public function getValue() + { + return $this->_value; + } + + /** + * Gets the type of the constant. + * + * @return string + */ + public function getEdmType() + { + return $this->_edmType; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/Filters/Filter.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/Filters/Filter.php new file mode 100644 index 0000000..db29ec2 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/Filters/Filter.php @@ -0,0 +1,206 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Table\Models\Filters; + +/** + * Filter operations + * + * @category Microsoft + * @package WindowsAzure\Table\Models\Filters + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class Filter +{ + /** + * Apply and operation between two filters + * + * @param Filter $left The left filter + * @param Filter $right The right filter + * + * @return \WindowsAzure\Table\Models\Filters\BinaryFilter + */ + public static function applyAnd($left, $right) + { + $filter = new BinaryFilter($left, 'and', $right); + return $filter; + } + + /** + * Applies not operation on $operand + * + * @param Filter $operand The operand + * + * @return \WindowsAzure\Table\Models\Filters\UnaryFilter + */ + public static function applyNot($operand) + { + $filter = new UnaryFilter('not', $operand); + return $filter; + } + + /** + * Apply or operation on the passed filers + * + * @param Filter $left The left operand + * @param Filter $right The right operand + * + * @return BinaryFilter + */ + public static function applyOr($left, $right) + { + $filter = new BinaryFilter($left, 'or', $right); + return $filter; + } + + /** + * Apply eq operation on the passed filers + * + * @param Filter $left The left operand + * @param Filter $right The right operand + * + * @return BinaryFilter + */ + public static function applyEq($left, $right) + { + $filter = new BinaryFilter($left, 'eq', $right); + return $filter; + } + + /** + * Apply ne operation on the passed filers + * + * @param Filter $left The left operand + * @param Filter $right The right operand + * + * @return BinaryFilter + */ + public static function applyNe($left, $right) + { + $filter = new BinaryFilter($left, 'ne', $right); + return $filter; + } + + /** + * Apply ge operation on the passed filers + * + * @param Filter $left The left operand + * @param Filter $right The right operand + * + * @return BinaryFilter + */ + public static function applyGe($left, $right) + { + $filter = new BinaryFilter($left, 'ge', $right); + return $filter; + } + + /** + * Apply gt operation on the passed filers + * + * @param Filter $left The left operand + * @param Filter $right The right operand + * + * @return BinaryFilter + */ + public static function applyGt($left, $right) + { + $filter = new BinaryFilter($left, 'gt', $right); + return $filter; + } + + /** + * Apply lt operation on the passed filers + * + * @param Filter $left The left operand + * @param Filter $right The right operand + * + * @return BinaryFilter + */ + public static function applyLt($left, $right) + { + $filter = new BinaryFilter($left, 'lt', $right); + return $filter; + } + + /** + * Apply le operation on the passed filers + * + * @param Filter $left The left operand + * @param Filter $right The right operand + * + * @return BinaryFilter + */ + public static function applyLe($left, $right) + { + $filter = new BinaryFilter($left, 'le', $right); + return $filter; + } + + /** + * Apply constant filter on value. + * + * @param mix $value The filter value + * @param string $edmType The value EDM type. + * + * @return \WindowsAzure\Table\Models\Filters\ConstantFilter + */ + public static function applyConstant($value, $edmType = null) + { + $filter = new ConstantFilter($edmType, $value); + return $filter; + } + + /** + * Apply propertyName filter on $value + * + * @param string $value The filter value + * + * @return \WindowsAzure\Table\Models\Filters\PropertyNameFilter + */ + public static function applyPropertyName($value) + { + $filter = new PropertyNameFilter($value); + return $filter; + } + + /** + * Takes raw string filter + * + * @param string $value The raw string filter expression + * + * @return \WindowsAzure\Table\Models\Filters\QueryStringFilter + */ + public static function applyQueryString($value) + { + $filter = new QueryStringFilter($value); + return $filter; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/Filters/PropertyNameFilter.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/Filters/PropertyNameFilter.php new file mode 100644 index 0000000..341bf87 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/Filters/PropertyNameFilter.php @@ -0,0 +1,66 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Table\Models\Filters; + +/** + * Constant filter + * + * @category Microsoft + * @package WindowsAzure\Table\Models\Filters + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class PropertyNameFilter extends Filter +{ + /** + * @var string + */ + private $_propertyName; + + /** + * Constructor. + * + * @param string $propertyName The propertyName. + */ + public function __construct($propertyName) + { + $this->_propertyName = $propertyName; + } + + /** + * Gets propertyName + * + * @return string + */ + public function getPropertyName() + { + return $this->_propertyName; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/Filters/QueryStringFilter.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/Filters/QueryStringFilter.php new file mode 100644 index 0000000..2f4192a --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/Filters/QueryStringFilter.php @@ -0,0 +1,67 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Table\Models\Filters; + +/** + * Constant filter + * + * @category Microsoft + * @package WindowsAzure\Table\Models\Filters + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class QueryStringFilter extends Filter +{ + /** + * @var string + */ + private $_queryString; + + /** + * Constructor. + * + * @param string $queryString The OData query string. + */ + public function __construct($queryString) + { + $this->_queryString = $queryString; + } + + + /** + * Gets raw string filter + * + * @return string + */ + public function getQueryString() + { + return $this->_queryString; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/Filters/UnaryFilter.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/Filters/UnaryFilter.php new file mode 100644 index 0000000..9d8c9ef --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/Filters/UnaryFilter.php @@ -0,0 +1,83 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Table\Models\Filters; + +/** + * Unary filter + * + * @category Microsoft + * @package WindowsAzure\Table\Models\Filters + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class UnaryFilter extends Filter +{ + /** + * @var string + */ + private $_operator; + + /** + * @var Filter + */ + private $_operand; + + /** + * Constructor. + * + * @param string $operator The operator. + * @param Filter $operand The operand filter. + */ + public function __construct($operator, $operand) + { + $this->_operand = $operand; + $this->_operator = $operator; + } + + /** + * Gets operator + * + * @return string + */ + public function getOperator() + { + return $this->_operator; + } + + /** + * Gets operand + * + * @return Filter + */ + public function getOperand() + { + return $this->_operand; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/GetEntityResult.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/GetEntityResult.php new file mode 100644 index 0000000..c8ad9f7 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/GetEntityResult.php @@ -0,0 +1,68 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Table\Models; + +/** + * Holds result of calling getEntity wrapper. + * + * @category Microsoft + * @package WindowsAzure\Table\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class GetEntityResult +{ + /** + * @var Entity + */ + private $_entity; + + /** + * Gets table entity. + * + * @return Entity + */ + public function getEntity() + { + return $this->_entity; + } + + /** + * Sets table entity. + * + * @param Entity $entity The table entity instance. + * + * @return none + */ + public function setEntity($entity) + { + $this->_entity = $entity; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/GetTableResult.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/GetTableResult.php new file mode 100644 index 0000000..bbcd52e --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/GetTableResult.php @@ -0,0 +1,87 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Table\Models; +use WindowsAzure\Common\Internal\Utilities; + +/** + * Holds result of getTable API. + * + * @category Microsoft + * @package WindowsAzure\Table\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class GetTableResult +{ + /** + * @var string + */ + private $_name; + + /** + * Creates GetTableResult from HTTP response body. + * + * @param string $body The HTTP response body. + * @param AtomReaderWriter $atomSerializer The Atom reader and writer. + * + * @return \WindowsAzure\Table\Models\GetTableResult + */ + public static function create($body, $atomSerializer) + { + $result = new GetTableResult(); + + $name = $atomSerializer->parseTable($body); + $result->setName($name); + + return $result; + } + + /** + * Gets the name. + * + * @return string + */ + public function getName() + { + return $this->_name; + } + + /** + * Sets the name. + * + * @param string $name The table name. + * + * @return none + */ + public function setName($name) + { + $this->_name = $name; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/InsertEntityResult.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/InsertEntityResult.php new file mode 100644 index 0000000..a541cba --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/InsertEntityResult.php @@ -0,0 +1,91 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Table\Models; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Resources; + +/** + * Holds result of calling insertEntity wrapper + * + * @category Microsoft + * @package WindowsAzure\Table\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class InsertEntityResult +{ + /** + * @var Entity + */ + private $_entity; + + /** + * Create InsertEntityResult object from HTTP response parts. + * + * @param string $body The HTTP response body. + * @param array $headers The HTTP response headers. + * @param IAtomReaderWriter $atomSerializer The atom reader and writer. + * + * @return \WindowsAzure\Table\Models\InsertEntityResult + * + * @static + */ + public static function create($body, $headers, $atomSerializer) + { + $result = new InsertEntityResult(); + $entity = $atomSerializer->parseEntity($body); + $entity->setETag(Utilities::tryGetValue($headers, Resources::ETAG)); + $result->setEntity($entity); + + return $result; + } + + /** + * Gets table entity. + * + * @return Entity + */ + public function getEntity() + { + return $this->_entity; + } + + /** + * Sets table entity. + * + * @param Entity $entity The table entity instance. + * + * @return none + */ + public function setEntity($entity) + { + $this->_entity = $entity; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/Property.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/Property.php new file mode 100644 index 0000000..ca7a304 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/Property.php @@ -0,0 +1,98 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Table\Models; +use WindowsAzure\Table\Models\EdmType; +use WindowsAzure\Common\Internal\Validate; + +/** + * Represents entity property. + * + * @category Microsoft + * @package WindowsAzure\Table\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class Property +{ + /** + * @var string + */ + private $_edmType; + + /** + * @var mix + */ + private $_value; + + /** + * Gets the type of the property. + * + * @return string + */ + public function getEdmType() + { + return $this->_edmType; + } + + /** + * Sets the value of the property. + * + * @param string $edmType The property type. + * + * @return none + */ + public function setEdmType($edmType) + { + EdmType::isValid($edmType); + $this->_edmType = $edmType; + } + + /** + * Gets the value of the property. + * + * @return string + */ + public function getValue() + { + return $this->_value; + } + + /** + * Sets the property value. + * + * @param mix $value The value of property. + * + * @return none + */ + public function setValue($value) + { + $this->_value = $value; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/Query.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/Query.php new file mode 100644 index 0000000..8987178 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/Query.php @@ -0,0 +1,134 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Table\Models; + +/** + * Query to be performed on a table + * + * @category Microsoft + * @package WindowsAzure\Table\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class Query +{ + /** + * @var array + */ + private $_selectFields; + + /** + * @var Filters\Filter + */ + private $_filter; + + /** + * @var integer + */ + private $_top; + + /** + * Gets filter. + * + * @return Filters\Filter + */ + public function getFilter() + { + return $this->_filter; + } + + /** + * Sets filter. + * + * @param Filters\Filter $filter value. + * + * @return none. + */ + public function setFilter($filter) + { + $this->_filter = $filter; + } + + /** + * Gets top. + * + * @return integer. + */ + public function getTop() + { + return $this->_top; + } + + /** + * Sets top. + * + * @param integer $top value. + * + * @return none. + */ + public function setTop($top) + { + $this->_top = $top; + } + + /** + * Adds a field to select fields. + * + * @param string $field The value of the field. + * + * @return none. + */ + public function addSelectField($field) + { + $this->_selectFields[] = $field; + } + + /** + * Gets selectFields. + * + * @return array. + */ + public function getSelectFields() + { + return $this->_selectFields; + } + + /** + * Sets selectFields. + * + * @param array $selectFields value. + * + * @return none. + */ + public function setSelectFields($selectFields) + { + $this->_selectFields = $selectFields; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/QueryEntitiesOptions.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/QueryEntitiesOptions.php new file mode 100644 index 0000000..7f9b436 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/QueryEntitiesOptions.php @@ -0,0 +1,223 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Table\Models; + +/** + * Holds optional parameters for queryEntities API + * + * @category Microsoft + * @package WindowsAzure\Table\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class QueryEntitiesOptions extends TableServiceOptions +{ + /** + * @var Query + */ + private $_query; + + /** + * @var string + */ + private $_nextPartitionKey; + + /** + * @var string + */ + private $_nextRowKey; + + /** + * Constructs new QueryEntitiesOptions object. + */ + public function __construct() + { + $this->_query = new Query(); + } + + /** + * Gets query. + * + * @return Query + */ + public function getQuery() + { + return $this->_query; + } + + /** + * Sets query. + * + * You can either sets the whole query *or* use the individual query functions + * like (setTop). + * + * @param string $query The query instance. + * + * @return none + */ + public function setQuery($query) + { + $this->_query = $query; + } + + /** + * Gets entity next partition key. + * + * @return string + */ + public function getNextPartitionKey() + { + return $this->_nextPartitionKey; + } + + /** + * Sets entity next partition key. + * + * @param string $nextPartitionKey The entity next partition key value. + * + * @return none + */ + public function setNextPartitionKey($nextPartitionKey) + { + $this->_nextPartitionKey = $nextPartitionKey; + } + + /** + * Gets entity next row key. + * + * @return string + */ + public function getNextRowKey() + { + return $this->_nextRowKey; + } + + /** + * Sets entity next row key. + * + * @param string $nextRowKey The entity next row key value. + * + * @return none + */ + public function setNextRowKey($nextRowKey) + { + $this->_nextRowKey = $nextRowKey; + } + + /** + * Gets filter. + * + * @return Filters\Filter + */ + public function getFilter() + { + return $this->_query->getFilter(); + } + + /** + * Sets filter. + * + * You can either use this individual function or use setQuery to set the whole + * query object. + * + * @param Filters\Filter $filter value. + * + * @return none. + */ + public function setFilter($filter) + { + $this->_query->setFilter($filter); + } + + /** + * Gets top. + * + * @return integer. + */ + public function getTop() + { + return $this->_query->getTop(); + } + + /** + * Sets top. + * + * You can either use this individual function or use setQuery to set the whole + * query object. + * + * @param integer $top value. + * + * @return none. + */ + public function setTop($top) + { + $this->_query->setTop($top); + } + + /** + * Adds a field to select fields. + * + * You can either use this individual function or use setQuery to set the whole + * query object. + * + * @param string $field The value of the field. + * + * @return none. + */ + public function addSelectField($field) + { + $this->_query->addSelectField($field); + } + + /** + * Gets selectFields. + * + * @return array. + */ + public function getSelectFields() + { + return $this->_query->getSelectFields(); + } + + /** + * Sets selectFields. + * + * You can either use this individual function or use setQuery to set the whole + * query object. + * + * @param array $selectFields value. + * + * @return none. + */ + public function setSelectFields($selectFields) + { + $this->_query->setSelectFields($selectFields); + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/QueryEntitiesResult.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/QueryEntitiesResult.php new file mode 100644 index 0000000..a20e347 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/QueryEntitiesResult.php @@ -0,0 +1,150 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Table\Models; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Resources; + +/** + * Holds results of calling queryEntities API + * + * @category Microsoft + * @package WindowsAzure\Table\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class QueryEntitiesResult +{ + /** + * @var Query + */ + private $_nextRowKey; + + /** + * @var string + */ + private $_nextPartitionKey; + + /** + * @var array + */ + private $_entities; + + /** + * Creates new QueryEntitiesResult instance. + * + * @param array $headers The HTTP response headers. + * @param array $entities The entities. + * + * @return QueryEntitiesResult + */ + public static function create($headers, $entities) + { + $result = new QueryEntitiesResult(); + $headers = array_change_key_case($headers); + $nextPK = Utilities::tryGetValue( + $headers, Resources::X_MS_CONTINUATION_NEXTPARTITIONKEY + ); + $nextRK = Utilities::tryGetValue( + $headers, Resources::X_MS_CONTINUATION_NEXTROWKEY + ); + + $result->setEntities($entities); + $result->setNextPartitionKey($nextPK); + $result->setNextRowKey($nextRK); + + return $result; + } + + /** + * Gets entities. + * + * @return array + */ + public function getEntities() + { + return $this->_entities; + } + + /** + * Sets entities. + * + * @param array $entities The entities array. + * + * @return none + */ + public function setEntities($entities) + { + $this->_entities = $entities; + } + + /** + * Gets entity next partition key. + * + * @return string + */ + public function getNextPartitionKey() + { + return $this->_nextPartitionKey; + } + + /** + * Sets entity next partition key. + * + * @param string $nextPartitionKey The entity next partition key value. + * + * @return none + */ + public function setNextPartitionKey($nextPartitionKey) + { + $this->_nextPartitionKey = $nextPartitionKey; + } + + /** + * Gets entity next row key. + * + * @return string + */ + public function getNextRowKey() + { + return $this->_nextRowKey; + } + + /** + * Sets entity next row key. + * + * @param string $nextRowKey The entity next row key value. + * + * @return none + */ + public function setNextRowKey($nextRowKey) + { + $this->_nextRowKey = $nextRowKey; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/QueryTablesOptions.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/QueryTablesOptions.php new file mode 100644 index 0000000..15943b6 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/QueryTablesOptions.php @@ -0,0 +1,162 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Table\Models; + +/** + * Optional parameters for queryTables wrapper. + * + * @category Microsoft + * @package WindowsAzure\Table\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class QueryTablesOptions extends TableServiceOptions +{ + /** + * @var string + */ + private $_nextTableName; + + /** + * @var Query + */ + private $_query; + + /** + * @var string + */ + private $_prefix; + + /** + * Constructs new QueryTablesOptions object. + */ + public function __construct() + { + $this->_query = new Query(); + } + + /** + * Gets nextTableName + * + * @return string + */ + public function getNextTableName() + { + return $this->_nextTableName; + } + + /** + * Sets nextTableName + * + * @param string $nextTableName value + * + * @return none + */ + public function setNextTableName($nextTableName) + { + $this->_nextTableName = $nextTableName; + } + + /** + * Gets prefix + * + * @return string + */ + public function getPrefix() + { + return $this->_prefix; + } + + /** + * Sets prefix + * + * @param string $prefix value + * + * @return none + */ + public function setPrefix($prefix) + { + $this->_prefix = $prefix; + } + + /** + * Gets top. + * + * @return integer. + */ + public function getTop() + { + return $this->_query->getTop(); + } + + /** + * Sets top. + * + * @param integer $top value. + * + * @return none. + */ + public function setTop($top) + { + $this->_query->setTop($top); + } + + /** + * Gets query. + * + * @return Query + */ + public function getQuery() + { + return $this->_query; + } + + /** + * Gets filter. + * + * @return Filters\Filter + */ + public function getFilter() + { + return $this->_query->getFilter(); + } + + /** + * Sets filter. + * + * @param Filters\Filter $filter value. + * + * @return none. + */ + public function setFilter($filter) + { + $this->_query->setFilter($filter); + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/QueryTablesResult.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/QueryTablesResult.php new file mode 100644 index 0000000..d229845 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/QueryTablesResult.php @@ -0,0 +1,120 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Table\Models; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Resources; + +/** + * QueryTablesResult + * + * @category Microsoft + * @package WindowsAzure\Table\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class QueryTablesResult +{ + /** + * @var string + */ + private $_nextTableName; + + /** + * @var array + */ + private $_tables; + + /** + * Creates new QueryTablesResult object + * + * @param array $headers The HTTP response headers + * @param array $entries The table entriess + * + * @return \WindowsAzure\Table\Models\QueryTablesResult + */ + public static function create($headers, $entries) + { + $result = new QueryTablesResult(); + $headers = array_change_key_case($headers); + + $result->setNextTableName( + Utilities::tryGetValue( + $headers, Resources::X_MS_CONTINUATION_NEXTTABLENAME + ) + ); + $result->setTables($entries); + + return $result; + } + + /** + * Gets nextTableName + * + * @return string + */ + public function getNextTableName() + { + return $this->_nextTableName; + } + + /** + * Sets nextTableName + * + * @param string $nextTableName value + * + * @return none + */ + public function setNextTableName($nextTableName) + { + $this->_nextTableName = $nextTableName; + } + + /** + * Gets tables + * + * @return array + */ + public function getTables() + { + return $this->_tables; + } + + /** + * Sets tables + * + * @param array $tables value + * + * @return none + */ + public function setTables($tables) + { + $this->_tables = $tables; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/TableServiceOptions.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/TableServiceOptions.php new file mode 100644 index 0000000..3ff0ea8 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/TableServiceOptions.php @@ -0,0 +1,65 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Table\Models; + +/** + * Table service options. + * + * @category Microsoft + * @package WindowsAzure\Table\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class TableServiceOptions +{ + private $_timeout; + + /** + * Gets timeout. + * + * @return string. + */ + public function getTimeout() + { + return $this->_timeout; + } + + /** + * Sets timeout. + * + * @param string $timeout value. + * + * @return none. + */ + public function setTimeout($timeout) + { + $this->_timeout = $timeout; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/UpdateEntityResult.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/UpdateEntityResult.php new file mode 100644 index 0000000..c3e820a --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/Models/UpdateEntityResult.php @@ -0,0 +1,86 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Table\Models; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Resources; + +/** + * Holds result of updateEntity and mergeEntity APIs + * + * @category Microsoft + * @package WindowsAzure\Table\Models + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class UpdateEntityResult +{ + /** + * @var string + */ + private $_etag; + + /** + * Creates UpdateEntityResult from HTTP response headers. + * + * @param array $headers The HTTP response headers. + * + * @return \WindowsAzure\Table\Models\UpdateEntityResult + */ + public static function create($headers) + { + $result = new UpdateEntityResult(); + $clean = array_change_key_case($headers); + $result->setETag($clean[Resources::ETAG]); + + return $result; + } + + /** + * Gets entity etag. + * + * @return string + */ + public function getETag() + { + return $this->_etag; + } + + /** + * Sets entity etag. + * + * @param string $etag The entity ETag. + * + * @return none + */ + public function setETag($etag) + { + $this->_etag = $etag; + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/TableRestProxy.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/TableRestProxy.php new file mode 100644 index 0000000..1eb8af5 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/Table/TableRestProxy.php @@ -0,0 +1,1302 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +namespace WindowsAzure\Table; +use WindowsAzure\Common\Internal\Resources; +use WindowsAzure\Common\Internal\Utilities; +use WindowsAzure\Common\Internal\Validate; +use WindowsAzure\Common\Internal\Http\HttpCallContext; +use WindowsAzure\Common\Models\ServiceProperties; +use WindowsAzure\Common\Internal\ServiceRestProxy; +use WindowsAzure\Common\Models\GetServicePropertiesResult; +use WindowsAzure\Table\Internal\ITable; +use WindowsAzure\Table\Models\TableServiceOptions; +use WindowsAzure\Table\Models\EdmType; +use WindowsAzure\Table\Models\Filters; +use WindowsAzure\Table\Models\Filters\Filter; +use WindowsAzure\Table\Models\Filters\PropertyNameFilter; +use WindowsAzure\Table\Models\Filters\ConstantFilter; +use WindowsAzure\Table\Models\Filters\UnaryFilter; +use WindowsAzure\Table\Models\Filters\BinaryFilter; +use WindowsAzure\Table\Models\Filters\QueryStringFilter; +use WindowsAzure\Table\Models\GetTableResult; +use WindowsAzure\Table\Models\QueryTablesOptions; +use WindowsAzure\Table\Models\QueryTablesResult; +use WindowsAzure\Table\Models\InsertEntityResult; +use WindowsAzure\Table\Models\UpdateEntityResult; +use WindowsAzure\Table\Models\QueryEntitiesOptions; +use WindowsAzure\Table\Models\QueryEntitiesResult; +use WindowsAzure\Table\Models\DeleteEntityOptions; +use WindowsAzure\Table\Models\GetEntityResult; +use WindowsAzure\Table\Models\BatchOperationType; +use WindowsAzure\Table\Models\BatchOperationParameterName; +use WindowsAzure\Table\Models\BatchResult; + +/** + * This class constructs HTTP requests and receive HTTP responses for table + * service layer. + * + * @category Microsoft + * @package WindowsAzure\Table + * @author Azure PHP SDK + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @version Release: 0.4.0_2014-01 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ +class TableRestProxy extends ServiceRestProxy implements ITable +{ + /** + * @var Utilities\IAtomReaderWriter + */ + private $_atomSerializer; + + /** + * + * @var Utilities\IMimeReaderWriter + */ + private $_mimeSerializer; + + /** + * Creates contexts for batch operations. + * + * @param array $operations The batch operations array. + * + * @return array + * + * @throws \InvalidArgumentException + */ + private function _createOperationsContexts($operations) + { + $contexts = array(); + + foreach ($operations as $operation) { + $context = null; + $type = $operation->getType(); + + switch ($type) { + case BatchOperationType::INSERT_ENTITY_OPERATION: + case BatchOperationType::UPDATE_ENTITY_OPERATION: + case BatchOperationType::MERGE_ENTITY_OPERATION: + case BatchOperationType::INSERT_REPLACE_ENTITY_OPERATION: + case BatchOperationType::INSERT_MERGE_ENTITY_OPERATION: + $table = $operation->getParameter( + BatchOperationParameterName::BP_TABLE + ); + $entity = $operation->getParameter( + BatchOperationParameterName::BP_ENTITY + ); + $context = $this->_getOperationContext($table, $entity, $type); + break; + + case BatchOperationType::DELETE_ENTITY_OPERATION: + $table = $operation->getParameter( + BatchOperationParameterName::BP_TABLE + ); + $partitionKey = $operation->getParameter( + BatchOperationParameterName::BP_PARTITION_KEY + ); + $rowKey = $operation->getParameter( + BatchOperationParameterName::BP_ROW_KEY + ); + $etag = $operation->getParameter( + BatchOperationParameterName::BP_ETAG + ); + $options = new DeleteEntityOptions(); + $options->setETag($etag); + $context = $this->_constructDeleteEntityContext( + $table, $partitionKey, $rowKey, $options + ); + break; + + default: + throw new \InvalidArgumentException(); + } + + $contexts[] = $context; + } + + return $contexts; + } + + /** + * Creates operation context for the API. + * + * @param string $table The table name. + * @param Models\Entity $entity The entity object. + * @param string $type The API type. + * + * @return WindowsAzure\Common\Internal\Http\HttpCallContext + * + * @throws \InvalidArgumentException + */ + private function _getOperationContext($table, $entity, $type) + { + switch ($type) { + case BatchOperationType::INSERT_ENTITY_OPERATION: + return $this->_constructInsertEntityContext($table, $entity, null); + + case BatchOperationType::UPDATE_ENTITY_OPERATION: + return $this->_constructPutOrMergeEntityContext( + $table, + $entity, + Resources::HTTP_PUT, + true, + null + ); + + case BatchOperationType::MERGE_ENTITY_OPERATION: + return $this->_constructPutOrMergeEntityContext( + $table, + $entity, + Resources::HTTP_MERGE, + true, + null + ); + + case BatchOperationType::INSERT_REPLACE_ENTITY_OPERATION: + return $this->_constructPutOrMergeEntityContext( + $table, + $entity, + Resources::HTTP_PUT, + false, + null + ); + + case BatchOperationType::INSERT_MERGE_ENTITY_OPERATION: + return $this->_constructPutOrMergeEntityContext( + $table, + $entity, + Resources::HTTP_MERGE, + false, + null + ); + + default: + throw new \InvalidArgumentException(); + } + } + + /** + * Creates MIME part body for batch API. + * + * @param array $operations The batch operations. + * @param array $contexts The contexts objects. + * + * @return array + * + * @throws \InvalidArgumentException + */ + private function _createBatchRequestBody($operations, $contexts) + { + $mimeBodyParts = array(); + $contentId = 1; + $count = count($operations); + + Validate::isTrue( + count($operations) == count($contexts), + Resources::INVALID_OC_COUNT_MSG + ); + + for ($i = 0; $i < $count; $i++) { + $operation = $operations[$i]; + $context = $contexts[$i]; + $type = $operation->getType(); + + switch ($type) { + case BatchOperationType::INSERT_ENTITY_OPERATION: + case BatchOperationType::UPDATE_ENTITY_OPERATION: + case BatchOperationType::MERGE_ENTITY_OPERATION: + case BatchOperationType::INSERT_REPLACE_ENTITY_OPERATION: + case BatchOperationType::INSERT_MERGE_ENTITY_OPERATION: + $contentType = $context->getHeader(Resources::CONTENT_TYPE); + $body = $context->getBody(); + $contentType .= ';type=entry'; + $context->addOptionalHeader(Resources::CONTENT_TYPE, $contentType); + // Use mb_strlen instead of strlen to get the length of the string + // in bytes instead of the length in chars. + $context->addOptionalHeader( + Resources::CONTENT_LENGTH, + strlen($body) + ); + break; + + case BatchOperationType::DELETE_ENTITY_OPERATION: + break; + + default: + throw new \InvalidArgumentException(); + } + + $context->addOptionalHeader(Resources::CONTENT_ID, $contentId); + $mimeBodyPart = $context->__toString(); + $mimeBodyParts[] = $mimeBodyPart; + $contentId++; + } + + return $this->_mimeSerializer->encodeMimeMultipart($mimeBodyParts); + } + + /** + * Constructs HTTP call context for deleteEntity API. + * + * @param string $table The name of the table. + * @param string $partitionKey The entity partition key. + * @param string $rowKey The entity row key. + * @param Models\DeleteEntityOptions $options The optional parameters. + * + * @return HttpCallContext + */ + private function _constructDeleteEntityContext($table, $partitionKey, $rowKey, + $options + ) { + Validate::isString($table, 'table'); + Validate::notNullOrEmpty($table, 'table'); + Validate::isTrue(!is_null($partitionKey), Resources::NULL_TABLE_KEY_MSG); + Validate::isTrue(!is_null($rowKey), Resources::NULL_TABLE_KEY_MSG); + + $method = Resources::HTTP_DELETE; + $headers = array(); + $queryParams = array(); + $statusCode = Resources::STATUS_NO_CONTENT; + $path = $this->_getEntityPath($table, $partitionKey, $rowKey); + + if (is_null($options)) { + $options = new DeleteEntityOptions(); + } + + $etagObj = $options->getETag(); + $ETag = !is_null($etagObj); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + $this->addOptionalHeader( + $headers, + Resources::IF_MATCH, + $ETag ? $etagObj : Resources::ASTERISK + ); + + $context = new HttpCallContext(); + $context->setHeaders($headers); + $context->setMethod($method); + $context->setPath($path); + $context->setQueryParameters($queryParams); + $context->addStatusCode($statusCode); + $context->setUri($this->getUri()); + $context->setBody(''); + + return $context; + } + + /** + * Constructs HTTP call context for updateEntity, mergeEntity, + * insertOrReplaceEntity and insertOrMergeEntity. + * + * @param string $table The table name. + * @param Models\Entity $entity The entity instance to use. + * @param string $verb The HTTP method. + * @param boolean $useETag The flag to include etag or not. + * @param Models\TableServiceOptions $options The optional parameters. + * + * @return HttpCallContext + */ + private function _constructPutOrMergeEntityContext($table, $entity, $verb, + $useETag, $options + ) { + Validate::isString($table, 'table'); + Validate::notNullOrEmpty($table, 'table'); + Validate::notNullOrEmpty($entity, 'entity'); + Validate::isTrue($entity->isValid($msg), $msg); + + $method = $verb; + $headers = array(); + $queryParams = array(); + $statusCode = Resources::STATUS_NO_CONTENT; + $partitionKey = $entity->getPartitionKey(); + $rowKey = $entity->getRowKey(); + $path = $this->_getEntityPath($table, $partitionKey, $rowKey); + $body = $this->_atomSerializer->getEntity($entity); + + if (is_null($options)) { + $options = new TableServiceOptions(); + } + + if ($useETag) { + $etag = $entity->getETag(); + $ifMatchValue = is_null($etag) ? Resources::ASTERISK : $etag; + + $this->addOptionalHeader($headers, Resources::IF_MATCH, $ifMatchValue); + } + + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + $this->addOptionalHeader( + $headers, + Resources::CONTENT_TYPE, + Resources::XML_ATOM_CONTENT_TYPE + ); + + $context = new HttpCallContext(); + $context->setBody($body); + $context->setHeaders($headers); + $context->setMethod($method); + $context->setPath($path); + $context->setQueryParameters($queryParams); + $context->addStatusCode($statusCode); + $context->setUri($this->getUri()); + + return $context; + } + + /** + * Constructs HTTP call context for insertEntity API. + * + * @param string $table The name of the table. + * @param Models\Entity $entity The table entity. + * @param Models\TableServiceOptions $options The optional parameters. + * + * @return HttpCallContext + */ + private function _constructInsertEntityContext($table, $entity, $options) + { + Validate::isString($table, 'table'); + Validate::notNullOrEmpty($table, 'table'); + Validate::notNullOrEmpty($entity, 'entity'); + Validate::isTrue($entity->isValid($msg), $msg); + + $method = Resources::HTTP_POST; + $context = new HttpCallContext(); + $headers = array(); + $queryParams = array(); + $statusCode = Resources::STATUS_CREATED; + $path = $table; + $body = $this->_atomSerializer->getEntity($entity); + + if (is_null($options)) { + $options = new TableServiceOptions(); + } + + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + $this->addOptionalHeader( + $headers, + Resources::CONTENT_TYPE, + Resources::XML_ATOM_CONTENT_TYPE + ); + + $context->setBody($body); + $context->setHeaders($headers); + $context->setMethod($method); + $context->setPath($path); + $context->setQueryParameters($queryParams); + $context->addStatusCode($statusCode); + $context->setUri($this->getUri()); + + return $context; + } + + /** + * Constructs URI path for entity. + * + * @param string $table The table name. + * @param string $partitionKey The entity's partition key. + * @param string $rowKey The entity's row key. + * + * @return string + */ + private function _getEntityPath($table, $partitionKey, $rowKey) + { + $encodedPK = $this->_encodeODataUriValue($partitionKey); + $encodedRK = $this->_encodeODataUriValue($rowKey); + + return "$table(PartitionKey='$encodedPK',RowKey='$encodedRK')"; + } + + /** + * Does actual work for update and merge entity APIs. + * + * @param string $table The table name. + * @param Models\Entity $entity The entity instance to use. + * @param string $verb The HTTP method. + * @param boolean $useETag The flag to include etag or not. + * @param Models\TableServiceOptions $options The optional parameters. + * + * @return Models\UpdateEntityResult + */ + private function _putOrMergeEntityImpl($table, $entity, $verb, $useETag, + $options + ) { + $context = $this->_constructPutOrMergeEntityContext( + $table, + $entity, + $verb, + $useETag, + $options + ); + + $response = $this->sendContext($context); + + return UpdateEntityResult::create($response->getHeader()); + } + + /** + * Builds filter expression + * + * @param Filter $filter The filter object + * + * @return string + */ + private function _buildFilterExpression($filter) + { + $e = Resources::EMPTY_STRING; + $this->_buildFilterExpressionRec($filter, $e); + + return $e; + } + + /** + * Builds filter expression + * + * @param Filter $filter The filter object + * @param string &$e The filter expression + * + * @return string + */ + private function _buildFilterExpressionRec($filter, &$e) + { + if (is_null($filter)) { + return; + } + + if ($filter instanceof PropertyNameFilter) { + $e .= $filter->getPropertyName(); + } else if ($filter instanceof ConstantFilter) { + $value = $filter->getValue(); + // If the value is null we just append null regardless of the edmType. + if (is_null($value)) { + $e .= 'null'; + } else { + $type = $filter->getEdmType(); + $e .= EdmType::serializeQueryValue($type, $value); + } + } else if ($filter instanceof UnaryFilter) { + $e .= $filter->getOperator(); + $e .= '('; + $this->_buildFilterExpressionRec($filter->getOperand(), $e); + $e .= ')'; + } else if ($filter instanceof Filters\BinaryFilter) { + $e .= '('; + $this->_buildFilterExpressionRec($filter->getLeft(), $e); + $e .= ' '; + $e .= $filter->getOperator(); + $e .= ' '; + $this->_buildFilterExpressionRec($filter->getRight(), $e); + $e .= ')'; + } else if ($filter instanceof QueryStringFilter) { + $e .= $filter->getQueryString(); + } + + return $e; + } + + /** + * Adds query object to the query parameter array + * + * @param array $queryParam The URI query parameters + * @param Models\Query $query The query object + * + * @return array + */ + private function _addOptionalQuery($queryParam, $query) + { + if (!is_null($query)) { + $selectedFields = $query->getSelectFields(); + if (!empty($selectedFields)) { + $final = $this->_encodeODataUriValues($selectedFields); + + $this->addOptionalQueryParam( + $queryParam, + Resources::QP_SELECT, + implode(',', $final) + ); + } + + if (!is_null($query->getTop())) { + $final = strval($this->_encodeODataUriValue($query->getTop())); + + $this->addOptionalQueryParam( + $queryParam, + Resources::QP_TOP, + $final + ); + } + + if (!is_null($query->getFilter())) { + $final = $this->_buildFilterExpression($query->getFilter()); + + $this->addOptionalQueryParam( + $queryParam, + Resources::QP_FILTER, + $final + ); + } + } + + return $queryParam; + } + + /** + * Encodes OData URI values + * + * @param array $values The OData URL values + * + * @return array + */ + private function _encodeODataUriValues($values) + { + $list = array(); + + foreach ($values as $value) { + $list[] = $this->_encodeODataUriValue($value); + } + + return $list; + } + + /** + * Encodes OData URI value + * + * @param string $value The OData URL value + * + * @return string + */ + private function _encodeODataUriValue($value) + { + // Replace each single quote (') with double single quotes ('') not doudle + // quotes (") + $value = str_replace('\'', '\'\'', $value); + + // Encode the special URL characters + $value = rawurlencode($value); + + return $value; + } + + /** + * Initializes new TableRestProxy object. + * + * @param IHttpClient $channel The HTTP client channel. + * @param string $uri The storage account uri. + * @param IAtomReaderWriter $atomSerializer The atom serializer. + * @param IMimeReaderWriter $mimeSerializer The MIME serializer. + * @param ISerializable $dataSerializer The data serializer. + */ + public function __construct($channel, $uri, $atomSerializer, $mimeSerializer, + $dataSerializer + ) { + parent::__construct( + $channel, + $uri, + Resources::EMPTY_STRING, + $dataSerializer + ); + $this->_atomSerializer = $atomSerializer; + $this->_mimeSerializer = $mimeSerializer; + } + + /** + * Gets the properties of the Table service. + * + * @param Models\TableServiceOptions $options optional table service options. + * + * @return WindowsAzure\Common\Models\GetServicePropertiesResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/hh452238.aspx + */ + public function getServiceProperties($options = null) + { + if (is_null($options)) { + $options = new TableServiceOptions(); + } + + $context = new HttpCallContext(); + $timeout = $options->getTimeout(); + $context->setMethod(Resources::HTTP_GET); + $context->addOptionalQueryParameter(Resources::QP_REST_TYPE, 'service'); + $context->addOptionalQueryParameter(Resources::QP_COMP, 'properties'); + $context->addOptionalQueryParameter(Resources::QP_TIMEOUT, $timeout); + $context->addStatusCode(Resources::STATUS_OK); + + $response = $this->sendContext($context); + $parsed = $this->dataSerializer->unserialize($response->getBody()); + + return GetServicePropertiesResult::create($parsed); + } + + /** + * Sets the properties of the Table service. + * + * It's recommended to use getServiceProperties, alter the returned object and + * then use setServiceProperties with this altered object. + * + * @param ServiceProperties $serviceProperties new service properties + * @param Models\TableServiceOptions $options optional parameters + * + * @return none. + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/hh452240.aspx + */ + public function setServiceProperties($serviceProperties, $options = null) + { + Validate::isTrue( + $serviceProperties instanceof ServiceProperties, + Resources::INVALID_SVC_PROP_MSG + ); + + $method = Resources::HTTP_PUT; + $headers = array(); + $postParams = array(); + $queryParams = array(); + $statusCode = Resources::STATUS_ACCEPTED; + $path = Resources::EMPTY_STRING; + $body = Resources::EMPTY_STRING; + + if (is_null($options)) { + $options = new TableServiceOptions(); + } + + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_REST_TYPE, + 'service' + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_COMP, + 'properties' + ); + + $this->addOptionalHeader( + $headers, + Resources::CONTENT_TYPE, + Resources::XML_ATOM_CONTENT_TYPE + ); + $body = $serviceProperties->toXml($this->dataSerializer); + + $this->send( + $method, + $headers, + $queryParams, + $postParams, + $path, + $statusCode, + $body + ); + } + + /** + * Quries tables in the given storage account. + * + * @param Models\QueryTablesOptions|string|Models\Filter $options Could be + * optional parameters, table prefix or filter to apply. + * + * @return Models\QueryTablesResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179405.aspx + */ + public function queryTables($options = null) + { + $method = Resources::HTTP_GET; + $headers = array(); + $postParams = array(); + $queryParams = array(); + $statusCode = Resources::STATUS_OK; + $path = 'Tables'; + + if (is_null($options)) { + $options = new QueryTablesOptions(); + } else if (is_string($options)) { + $prefix = $options; + $options = new QueryTablesOptions(); + $options->setPrefix($prefix); + } else if ($options instanceof Filter) { + $filter = $options; + $options = new QueryTablesOptions(); + $options->setFilter($filter); + } + + $query = $options->getQuery(); + $next = $options->getNextTableName(); + $prefix = $options->getPrefix(); + $timeout = $options->getTimeout(); + + if (!empty($prefix)) { + // Append Max char to end '{' is 1 + 'z' in AsciiTable ==> upperBound + // is prefix + '{' + $prefixFilter = Filter::applyAnd( + Filter::applyGe( + Filter::applyPropertyName('TableName'), + Filter::applyConstant($prefix, EdmType::STRING) + ), + Filter::applyLe( + Filter::applyPropertyName('TableName'), + Filter::applyConstant($prefix . '{', EdmType::STRING) + ) + ); + + if (is_null($query)) { + $query = new Models\Query(); + } + + if (is_null($query->getFilter())) { + // use the prefix filter if the query filter is null + $query->setFilter($prefixFilter); + } else { + // combine and use the prefix filter if the query filter exists + $combinedFilter = Filter::applyAnd( + $query->getFilter(), $prefixFilter + ); + $query->setFilter($combinedFilter); + } + } + + $queryParams = $this->_addOptionalQuery($queryParams, $query); + + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_NEXT_TABLE_NAME, + $next + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $timeout + ); + + // One can specify the NextTableName option to get table entities starting + // from the specified name. However, there appears to be an issue in the + // Azure Table service where this does not engage on the server unless + // $filter appears in the URL. The current behavior is to just ignore the + // NextTableName options, which is not expected or easily detectable. + if ( array_key_exists(Resources::QP_NEXT_TABLE_NAME, $queryParams) + && !array_key_exists(Resources::QP_FILTER, $queryParams) + ) { + $queryParams[Resources::QP_FILTER] = Resources::EMPTY_STRING; + } + + $response = $this->send( + $method, + $headers, + $queryParams, + $postParams, + $path, + $statusCode + ); + $tables = $this->_atomSerializer->parseTableEntries($response->getBody()); + + return QueryTablesResult::create($response->getHeader(), $tables); + } + + /** + * Creates new table in the storage account + * + * @param string $table The name of the table. + * @param Models\TableServiceOptions $options The optional parameters. + * + * @return none + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd135729.aspx + */ + public function createTable($table, $options = null) + { + Validate::isString($table, 'table'); + Validate::notNullOrEmpty($table, 'table'); + + $method = Resources::HTTP_POST; + $headers = array(); + $postParams = array(); + $queryParams = array(); + $statusCode = Resources::STATUS_CREATED; + $path = 'Tables'; + $body = $this->_atomSerializer->getTable($table); + + if (is_null($options)) { + $options = new TableServiceOptions(); + } + + $this->addOptionalHeader( + $headers, + Resources::CONTENT_TYPE, + Resources::XML_ATOM_CONTENT_TYPE + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + + $this->send( + $method, + $headers, + $queryParams, + $postParams, + $path, + $statusCode, + $body + ); + } + + /** + * Gets the table. + * + * @param string $table The name of the table. + * @param Models\TableServiceOptions $options The optional parameters. + * + * @return Models\GetTableResult + */ + public function getTable($table, $options = null) + { + Validate::isString($table, 'table'); + Validate::notNullOrEmpty($table, 'table'); + + $method = Resources::HTTP_GET; + $headers = array(); + $postParams = array(); + $queryParams = array(); + $statusCode = Resources::STATUS_OK; + $path = "Tables('$table')"; + + if (is_null($options)) { + $options = new TableServiceOptions(); + } + + $this->addOptionalHeader( + $headers, + Resources::CONTENT_TYPE, + Resources::XML_ATOM_CONTENT_TYPE + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + + $response = $this->send( + $method, + $headers, + $queryParams, + $postParams, + $path, + $statusCode + ); + + return GetTableResult::create($response->getBody(), $this->_atomSerializer); + } + + /** + * Deletes the specified table and any data it contains. + * + * @param string $table The name of the table. + * @param Models\TableServiceOptions $options optional parameters + * + * @return none + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179387.aspx + */ + public function deleteTable($table, $options = null) + { + Validate::isString($table, 'table'); + Validate::notNullOrEmpty($table, 'table'); + + $method = Resources::HTTP_DELETE; + $headers = array(); + $postParams = array(); + $queryParams = array(); + $statusCode = Resources::STATUS_NO_CONTENT; + $path = "Tables('$table')"; + + if (is_null($options)) { + $options = new TableServiceOptions(); + } + + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + + $this->send( + $method, + $headers, + $queryParams, + $postParams, + $path, + $statusCode + ); + } + + /** + * Quries entities for the given table name + * + * @param string $table The name of + * the table. + * @param Models\QueryEntitiesOptions|string|Models\Filter $options Coule be + * optional parameters, query string or filter to apply. + * + * @return Models\QueryEntitiesResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179421.aspx + */ + public function queryEntities($table, $options = null) + { + Validate::isString($table, 'table'); + Validate::notNullOrEmpty($table, 'table'); + + $method = Resources::HTTP_GET; + $headers = array(); + $postParams = array(); + $queryParams = array(); + $statusCode = Resources::STATUS_OK; + $path = $table; + + if (is_null($options)) { + $options = new QueryEntitiesOptions(); + } else if (is_string($options)) { + $queryString = $options; + $options = new QueryEntitiesOptions(); + $options->setFilter(Filter::applyQueryString($queryString)); + } else if ($options instanceof Filter) { + $filter = $options; + $options = new QueryEntitiesOptions(); + $options->setFilter($filter); + } + + $queryParams = $this->_addOptionalQuery($queryParams, $options->getQuery()); + + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_NEXT_PK, + $options->getNextPartitionKey() + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_NEXT_RK, + $options->getNextRowKey() + ); + + $this->addOptionalHeader( + $headers, + Resources::CONTENT_TYPE, + Resources::XML_ATOM_CONTENT_TYPE + ); + + if (!is_null($options->getQuery())) { + $dsHeader = Resources::DATA_SERVICE_VERSION; + $maxdsValue = Resources::MAX_DATA_SERVICE_VERSION_VALUE; + $fields = $options->getQuery()->getSelectFields(); + $hasSelect = !empty($fields); + if ($hasSelect) { + $this->addOptionalHeader($headers, $dsHeader, $maxdsValue); + } + } + + $response = $this->send( + $method, + $headers, + $queryParams, + $postParams, + $path, + $statusCode + ); + + $entities = $this->_atomSerializer->parseEntities($response->getBody()); + + return QueryEntitiesResult::create($response->getHeader(), $entities); + } + + /** + * Inserts new entity to the table. + * + * @param string $table name of the table. + * @param Models\Entity $entity table entity. + * @param Models\TableServiceOptions $options optional parameters. + * + * @return Models\InsertEntityResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179433.aspx + */ + public function insertEntity($table, $entity, $options = null) + { + $context = $this->_constructInsertEntityContext($table, $entity, $options); + + $response = $this->sendContext($context); + $body = $response->getBody(); + $headers = $response->getHeader(); + + return InsertEntityResult::create($body, $headers, $this->_atomSerializer); + } + + /** + * Updates an existing entity or inserts a new entity if it does not exist in the + * table. + * + * @param string $table name of the table + * @param Models\Entity $entity table entity + * @param Models\TableServiceOptions $options optional parameters + * + * @return Models\UpdateEntityResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/hh452241.aspx + */ + public function insertOrMergeEntity($table, $entity, $options = null) + { + return $this->_putOrMergeEntityImpl( + $table, + $entity, + Resources::HTTP_MERGE, + false, + $options + ); + } + + /** + * Replaces an existing entity or inserts a new entity if it does not exist in + * the table. + * + * @param string $table name of the table + * @param Models\Entity $entity table entity + * @param Models\TableServiceOptions $options optional parameters + * + * @return Models\UpdateEntityResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/hh452242.aspx + */ + public function insertOrReplaceEntity($table, $entity, $options = null) + { + return $this->_putOrMergeEntityImpl( + $table, + $entity, + Resources::HTTP_PUT, + false, + $options + ); + } + + /** + * Updates an existing entity in a table. The Update Entity operation replaces + * the entire entity and can be used to remove properties. + * + * @param string $table The table name. + * @param Models\Entity $entity The table entity. + * @param Models\TableServiceOptions $options The optional parameters. + * + * @return Models\UpdateEntityResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179427.aspx + */ + public function updateEntity($table, $entity, $options = null) + { + return $this->_putOrMergeEntityImpl( + $table, + $entity, + Resources::HTTP_PUT, + true, + $options + ); + } + + /** + * Updates an existing entity by updating the entity's properties. This operation + * does not replace the existing entity, as the updateEntity operation does. + * + * @param string $table The table name. + * @param Models\Entity $entity The table entity. + * @param Models\TableServiceOptions $options The optional parameters. + * + * @return Models\UpdateEntityResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179392.aspx + */ + public function mergeEntity($table, $entity, $options = null) + { + return $this->_putOrMergeEntityImpl( + $table, + $entity, + Resources::HTTP_MERGE, + true, + $options + ); + } + + /** + * Deletes an existing entity in a table. + * + * @param string $table The name of the table. + * @param string $partitionKey The entity partition key. + * @param string $rowKey The entity row key. + * @param Models\DeleteEntityOptions $options The optional parameters. + * + * @return none + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd135727.aspx + */ + public function deleteEntity($table, $partitionKey, $rowKey, $options = null) + { + $context = $this->_constructDeleteEntityContext( + $table, + $partitionKey, + $rowKey, + $options + ); + + $this->sendContext($context); + } + + /** + * Gets table entity. + * + * @param string $table The name of the table. + * @param string $partitionKey The entity partition key. + * @param string $rowKey The entity row key. + * @param Models\TableServiceOptions $options The optional parameters. + * + * @return Models\GetEntityResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179421.aspx + */ + public function getEntity($table, $partitionKey, $rowKey, $options = null) + { + Validate::isString($table, 'table'); + Validate::notNullOrEmpty($table, 'table'); + Validate::isTrue(!is_null($partitionKey), Resources::NULL_TABLE_KEY_MSG); + Validate::isTrue(!is_null($rowKey), Resources::NULL_TABLE_KEY_MSG); + + $method = Resources::HTTP_GET; + $headers = array(); + $queryParams = array(); + $statusCode = Resources::STATUS_OK; + $path = $this->_getEntityPath($table, $partitionKey, $rowKey); + + if (is_null($options)) { + $options = new TableServiceOptions(); + } + + $this->addOptionalHeader( + $headers, + Resources::CONTENT_TYPE, + Resources::XML_ATOM_CONTENT_TYPE + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + + $context = new HttpCallContext(); + $context->setHeaders($headers); + $context->setMethod($method); + $context->setPath($path); + $context->setQueryParameters($queryParams); + $context->addStatusCode($statusCode); + + $response = $this->sendContext($context); + $entity = $this->_atomSerializer->parseEntity($response->getBody()); + $result = new GetEntityResult(); + $result->setEntity($entity); + + return $result; + } + + /** + * Does batch of operations on the table service. + * + * @param Models\BatchOperations $batchOperations The operations to apply. + * @param Models\TableServiceOptions $options The optional parameters. + * + * @return Models\BatchResult + */ + public function batch($batchOperations, $options = null) + { + Validate::notNullOrEmpty($batchOperations, 'batchOperations'); + + $method = Resources::HTTP_POST; + $operations = $batchOperations->getOperations(); + $contexts = $this->_createOperationsContexts($operations); + $mime = $this->_createBatchRequestBody($operations, $contexts); + $body = $mime['body']; + $headers = $mime['headers']; + $postParams = array(); + $queryParams = array(); + $statusCode = Resources::STATUS_ACCEPTED; + $path = '$batch'; + + if (is_null($options)) { + $options = new TableServiceOptions(); + } + + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + + $response = $this->send( + $method, + $headers, + $queryParams, + $postParams, + $path, + $statusCode, + $body + ); + + return BatchResult::create( + $response->getBody(), + $operations, + $contexts, + $this->_atomSerializer, + $this->_mimeSerializer + ); + } +} + + diff --git a/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/WindowsAzure.php b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/WindowsAzure.php new file mode 100644 index 0000000..2934359 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/microsoft/windowsazure/WindowsAzure/WindowsAzure.php @@ -0,0 +1,327 @@ + + * @copyright 2012 Microsoft Corporation + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://github.com/windowsazure/azure-sdk-for-php + */ + +spl_autoload_register( + function($class) { + static $classes = null; + if ($classes === null) { + $classes = array( + 'windowsazure\\blob\\blobrestproxy' => '/Blob/BlobRestProxy.php', + 'windowsazure\\blob\\internal\\iblob' => '/Blob/Internal/IBlob.php', + 'windowsazure\\blob\\models\\accesscondition' => '/Blob/Models/AccessCondition.php', + 'windowsazure\\blob\\models\\accesspolicy' => '/Blob/Models/AccessPolicy.php', + 'windowsazure\\blob\\models\\acquireleaseoptions' => '/Blob/Models/AcquireLeaseOptions.php', + 'windowsazure\\blob\\models\\acquireleaseresult' => '/Blob/Models/AcquireLeaseResult.php', + 'windowsazure\\blob\\models\\blob' => '/Blob/Models/Blob.php', + 'windowsazure\\blob\\models\\blobblocktype' => '/Blob/Models/BlobBlockType.php', + 'windowsazure\\blob\\models\\blobprefix' => '/Blob/Models/BlobPrefix.php', + 'windowsazure\\blob\\models\\blobproperties' => '/Blob/Models/BlobProperties.php', + 'windowsazure\\blob\\models\\blobserviceoptions' => '/Blob/Models/BlobServiceOptions.php', + 'windowsazure\\blob\\models\\blobtype' => '/Blob/Models/BlobType.php', + 'windowsazure\\blob\\models\\block' => '/Blob/Models/Block.php', + 'windowsazure\\blob\\models\\blocklist' => '/Blob/Models/BlockList.php', + 'windowsazure\\blob\\models\\breakleaseresult' => '/Blob/Models/BreakLeaseResult.php', + 'windowsazure\\blob\\models\\commitblobblocksoptions' => '/Blob/Models/CommitBlobBlocksOptions.php', + 'windowsazure\\blob\\models\\container' => '/Blob/Models/Container.php', + 'windowsazure\\blob\\models\\containeracl' => '/Blob/Models/ContainerACL.php', + 'windowsazure\\blob\\models\\containerproperties' => '/Blob/Models/ContainerProperties.php', + 'windowsazure\\blob\\models\\copybloboptions' => '/Blob/Models/CopyBlobOptions.php', + 'windowsazure\\blob\\models\\copyblobresult' => '/Blob/Models/CopyBlobResult.php', + 'windowsazure\\blob\\models\\createblobblockoptions' => '/Blob/Models/CreateBlobBlockOptions.php', + 'windowsazure\\blob\\models\\createbloboptions' => '/Blob/Models/CreateBlobOptions.php', + 'windowsazure\\blob\\models\\createblobpagesoptions' => '/Blob/Models/CreateBlobPagesOptions.php', + 'windowsazure\\blob\\models\\createblobpagesresult' => '/Blob/Models/CreateBlobPagesResult.php', + 'windowsazure\\blob\\models\\createblobsnapshotoptions' => '/Blob/Models/CreateBlobSnapshotOptions.php', + 'windowsazure\\blob\\models\\createblobsnapshotresult' => '/Blob/Models/CreateBlobSnapshotResult.php', + 'windowsazure\\blob\\models\\createcontaineroptions' => '/Blob/Models/CreateContainerOptions.php', + 'windowsazure\\blob\\models\\deletebloboptions' => '/Blob/Models/DeleteBlobOptions.php', + 'windowsazure\\blob\\models\\deletecontaineroptions' => '/Blob/Models/DeleteContainerOptions.php', + 'windowsazure\\blob\\models\\getblobmetadataoptions' => '/Blob/Models/GetBlobMetadataOptions.php', + 'windowsazure\\blob\\models\\getblobmetadataresult' => '/Blob/Models/GetBlobMetadataResult.php', + 'windowsazure\\blob\\models\\getbloboptions' => '/Blob/Models/GetBlobOptions.php', + 'windowsazure\\blob\\models\\getblobpropertiesoptions' => '/Blob/Models/GetBlobPropertiesOptions.php', + 'windowsazure\\blob\\models\\getblobpropertiesresult' => '/Blob/Models/GetBlobPropertiesResult.php', + 'windowsazure\\blob\\models\\getblobresult' => '/Blob/Models/GetBlobResult.php', + 'windowsazure\\blob\\models\\getcontaineraclresult' => '/Blob/Models/GetContainerACLResult.php', + 'windowsazure\\blob\\models\\getcontainerpropertiesresult' => '/Blob/Models/GetContainerPropertiesResult.php', + 'windowsazure\\blob\\models\\leasemode' => '/Blob/Models/LeaseMode.php', + 'windowsazure\\blob\\models\\listblobblocksoptions' => '/Blob/Models/ListBlobBlocksOptions.php', + 'windowsazure\\blob\\models\\listblobblocksresult' => '/Blob/Models/ListBlobBlocksResult.php', + 'windowsazure\\blob\\models\\listblobsoptions' => '/Blob/Models/ListBlobsOptions.php', + 'windowsazure\\blob\\models\\listblobsresult' => '/Blob/Models/ListBlobsResult.php', + 'windowsazure\\blob\\models\\listcontainersoptions' => '/Blob/Models/ListContainersOptions.php', + 'windowsazure\\blob\\models\\listcontainersresult' => '/Blob/Models/ListContainersResult.php', + 'windowsazure\\blob\\models\\listpageblobrangesoptions' => '/Blob/Models/ListPageBlobRangesOptions.php', + 'windowsazure\\blob\\models\\listpageblobrangesresult' => '/Blob/Models/ListPageBlobRangesResult.php', + 'windowsazure\\blob\\models\\pagerange' => '/Blob/Models/PageRange.php', + 'windowsazure\\blob\\models\\pagewriteoption' => '/Blob/Models/PageWriteOption.php', + 'windowsazure\\blob\\models\\publicaccesstype' => '/Blob/Models/PublicAccessType.php', + 'windowsazure\\blob\\models\\setblobmetadataoptions' => '/Blob/Models/SetBlobMetadataOptions.php', + 'windowsazure\\blob\\models\\setblobmetadataresult' => '/Blob/Models/SetBlobMetadataResult.php', + 'windowsazure\\blob\\models\\setblobpropertiesoptions' => '/Blob/Models/SetBlobPropertiesOptions.php', + 'windowsazure\\blob\\models\\setblobpropertiesresult' => '/Blob/Models/SetBlobPropertiesResult.php', + 'windowsazure\\blob\\models\\setcontainermetadataoptions' => '/Blob/Models/SetContainerMetadataOptions.php', + 'windowsazure\\blob\\models\\signedidentifier' => '/Blob/Models/SignedIdentifier.php', + 'windowsazure\\common\\cloudconfigurationmanager' => '/Common/CloudConfigurationManager.php', + 'windowsazure\\common\\internal\\atom\\atombase' => '/Common/Internal/Atom/AtomBase.php', + 'windowsazure\\common\\internal\\atom\\atomlink' => '/Common/Internal/Atom/AtomLink.php', + 'windowsazure\\common\\internal\\atom\\category' => '/Common/Internal/Atom/Category.php', + 'windowsazure\\common\\internal\\atom\\content' => '/Common/Internal/Atom/Content.php', + 'windowsazure\\common\\internal\\atom\\entry' => '/Common/Internal/Atom/Entry.php', + 'windowsazure\\common\\internal\\atom\\feed' => '/Common/Internal/Atom/Feed.php', + 'windowsazure\\common\\internal\\atom\\generator' => '/Common/Internal/Atom/Generator.php', + 'windowsazure\\common\\internal\\atom\\person' => '/Common/Internal/Atom/Person.php', + 'windowsazure\\common\\internal\\atom\\source' => '/Common/Internal/Atom/Source.php', + 'windowsazure\\common\\internal\\authentication\\iauthscheme' => '/Common/Internal/Authentication/IAuthScheme.php', + 'windowsazure\\common\\internal\\authentication\\oauthscheme' => '/Common/Internal/Authentication/OAuthScheme.php', + 'windowsazure\\common\\internal\\authentication\\sharedkeyauthscheme' => '/Common/Internal/Authentication/SharedKeyAuthScheme.php', + 'windowsazure\\common\\internal\\authentication\\storageauthscheme' => '/Common/Internal/Authentication/StorageAuthScheme.php', + 'windowsazure\\common\\internal\\authentication\\tablesharedkeyliteauthscheme' => '/Common/Internal/Authentication/TableSharedKeyLiteAuthScheme.php', + 'windowsazure\\common\\internal\\connectionstringparser' => '/Common/Internal/ConnectionStringParser.php', + 'windowsazure\\common\\internal\\connectionstringsource' => '/Common/Internal/ConnectionStringSource.php', + 'windowsazure\\common\\internal\\filterableservice' => '/Common/Internal/FilterableService.php', + 'windowsazure\\common\\internal\\filters\\authenticationfilter' => '/Common/Internal/Filters/AuthenticationFilter.php', + 'windowsazure\\common\\internal\\filters\\datefilter' => '/Common/Internal/Filters/DateFilter.php', + 'windowsazure\\common\\internal\\filters\\exponentialretrypolicy' => '/Common/Internal/Filters/ExponentialRetryPolicy.php', + 'windowsazure\\common\\internal\\filters\\headersfilter' => '/Common/Internal/Filters/HeadersFilter.php', + 'windowsazure\\common\\internal\\filters\\retrypolicy' => '/Common/Internal/Filters/RetryPolicy.php', + 'windowsazure\\common\\internal\\filters\\retrypolicyfilter' => '/Common/Internal/Filters/RetryPolicyFilter.php', + 'windowsazure\\common\\internal\\filters\\wrapfilter' => '/Common/Internal/Filters/WrapFilter.php', + 'windowsazure\\common\\internal\\http\\batchrequest' => '/Common/Internal/Http/BatchRequest.php', + 'windowsazure\\common\\internal\\http\\batchresponse' => '/Common/Internal/Http/BatchResponse.php', + 'windowsazure\\common\\internal\\http\\httpcallcontext' => '/Common/Internal/Http/HttpCallContext.php', + 'windowsazure\\common\\internal\\http\\httpclient' => '/Common/Internal/Http/HttpClient.php', + 'windowsazure\\common\\internal\\http\\ihttpclient' => '/Common/Internal/Http/IHttpClient.php', + 'windowsazure\\common\\internal\\http\\iurl' => '/Common/Internal/Http/IUrl.php', + 'windowsazure\\common\\internal\\http\\url' => '/Common/Internal/Http/Url.php', + 'windowsazure\\common\\internal\\invalidargumenttypeexception' => '/Common/Internal/InvalidArgumentTypeException.php', + 'windowsazure\\common\\internal\\iservicefilter' => '/Common/Internal/IServiceFilter.php', + 'windowsazure\\common\\internal\\logger' => '/Common/Internal/Logger.php', + 'windowsazure\\common\\internal\\mediaservicessettings' => '/Common/Internal/MediaServicesSettings.php', + 'windowsazure\\common\\internal\\oauthrestproxy' => '/Common/Internal/OAuthRestProxy.php', + 'windowsazure\\common\\internal\\parserstate' => '/Common/Internal/ConnectionStringParser.php', + 'windowsazure\\common\\internal\\resources' => '/Common/Internal/Resources.php', + 'windowsazure\\common\\internal\\restproxy' => '/Common/Internal/RestProxy.php', + 'windowsazure\\common\\internal\\serialization\\iserializer' => '/Common/Internal/Serialization/ISerializer.php', + 'windowsazure\\common\\internal\\serialization\\jsonserializer' => '/Common/Internal/Serialization/JsonSerializer.php', + 'windowsazure\\common\\internal\\serialization\\xmlserializer' => '/Common/Internal/Serialization/XmlSerializer.php', + 'windowsazure\\common\\internal\\servicebussettings' => '/Common/Internal/ServiceBusSettings.php', + 'windowsazure\\common\\internal\\servicemanagementsettings' => '/Common/Internal/ServiceManagementSettings.php', + 'windowsazure\\common\\internal\\servicerestproxy' => '/Common/Internal/ServiceRestProxy.php', + 'windowsazure\\common\\internal\\servicesettings' => '/Common/Internal/ServiceSettings.php', + 'windowsazure\\common\\internal\\storageservicesettings' => '/Common/Internal/StorageServiceSettings.php', + 'windowsazure\\common\\internal\\utilities' => '/Common/Internal/Utilities.php', + 'windowsazure\\common\\internal\\validate' => '/Common/Internal/Validate.php', + 'windowsazure\\common\\models\\getservicepropertiesresult' => '/Common/Models/GetServicePropertiesResult.php', + 'windowsazure\\common\\models\\logging' => '/Common/Models/Logging.php', + 'windowsazure\\common\\models\\metrics' => '/Common/Models/Metrics.php', + 'windowsazure\\common\\models\\oauthaccesstoken' => '/Common/Models/OAuthAccessToken.php', + 'windowsazure\\common\\models\\retentionpolicy' => '/Common/Models/RetentionPolicy.php', + 'windowsazure\\common\\models\\serviceproperties' => '/Common/Models/ServiceProperties.php', + 'windowsazure\\common\\serviceexception' => '/Common/ServiceException.php', + 'windowsazure\\common\\servicesbuilder' => '/Common/ServicesBuilder.php', + 'windowsazure\\mediaservices\\internal\\imediaservices' => '/MediaServices/Internal/IMediaServices.php', + 'windowsazure\\mediaservices\\mediaservicesrestproxy' => '/MediaServices/MediaServicesRestProxy.php', + 'windowsazure\\mediaservices\\models\\accesspolicy' => '/MediaServices/Models/AccessPolicy.php', + 'windowsazure\\mediaservices\\models\\asset' => '/MediaServices/Models/Asset.php', + 'windowsazure\\mediaservices\\models\\assetfile' => '/MediaServices/Models/AssetFile.php', + 'windowsazure\\mediaservices\\models\\contentproperties' => '/MediaServices/Models/ContentProperties.php', + 'windowsazure\\mediaservices\\models\\errordetail' => '/MediaServices/Models/ErrorDetail.php', + 'windowsazure\\mediaservices\\models\\job' => '/MediaServices/Models/Job.php', + 'windowsazure\\mediaservices\\models\\jobtemplate' => '/MediaServices/Models/JobTemplate.php', + 'windowsazure\\mediaservices\\models\\locator' => '/MediaServices/Models/Locator.php', + 'windowsazure\\mediaservices\\models\\mediaprocessor' => '/MediaServices/Models/MediaProcessor.php', + 'windowsazure\\mediaservices\\models\\storageaccount' => '/MediaServices/Models/StorageAccount.php', + 'windowsazure\\mediaservices\\models\\task' => '/MediaServices/Models/Task.php', + 'windowsazure\\mediaservices\\models\\taskhistoricalevent' => '/MediaServices/Models/TaskHistoricalEvent.php', + 'windowsazure\\mediaservices\\models\\taskoptions' => '/MediaServices/Models/TaskOptions.php', + 'windowsazure\\mediaservices\\models\\tasktemplate' => '/MediaServices/Models/TaskTemplate.php', + 'windowsazure\\queue\\internal\\iqueue' => '/Queue/Internal/IQueue.php', + 'windowsazure\\queue\\models\\createmessageoptions' => '/Queue/Models/CreateMessageOptions.php', + 'windowsazure\\queue\\models\\createqueueoptions' => '/Queue/Models/CreateQueueOptions.php', + 'windowsazure\\queue\\models\\getqueuemetadataresult' => '/Queue/Models/GetQueueMetadataResult.php', + 'windowsazure\\queue\\models\\listmessagesoptions' => '/Queue/Models/ListMessagesOptions.php', + 'windowsazure\\queue\\models\\listmessagesresult' => '/Queue/Models/ListMessagesResult.php', + 'windowsazure\\queue\\models\\listqueuesoptions' => '/Queue/Models/ListQueuesOptions.php', + 'windowsazure\\queue\\models\\listqueuesresult' => '/Queue/Models/ListQueuesResult.php', + 'windowsazure\\queue\\models\\peekmessagesoptions' => '/Queue/Models/PeekMessagesOptions.php', + 'windowsazure\\queue\\models\\peekmessagesresult' => '/Queue/Models/PeekMessagesResult.php', + 'windowsazure\\queue\\models\\queue' => '/Queue/Models/Queue.php', + 'windowsazure\\queue\\models\\queuemessage' => '/Queue/Models/QueueMessage.php', + 'windowsazure\\queue\\models\\queueserviceoptions' => '/Queue/Models/QueueServiceOptions.php', + 'windowsazure\\queue\\models\\updatemessageresult' => '/Queue/Models/UpdateMessageResult.php', + 'windowsazure\\queue\\models\\windowsazurequeuemessage' => '/Queue/Models/WindowsAzureQueueMessage.php', + 'windowsazure\\queue\\queuerestproxy' => '/Queue/QueueRestProxy.php', + 'windowsazure\\servicebus\\internal\\action' => '/ServiceBus/Internal/Action.php', + 'windowsazure\\servicebus\\internal\\activetoken' => '/ServiceBus/Internal/ActiveToken.php', + 'windowsazure\\servicebus\\internal\\filter' => '/ServiceBus/Internal/Filter.php', + 'windowsazure\\servicebus\\internal\\iservicebus' => '/ServiceBus/Internal/IServiceBus.php', + 'windowsazure\\servicebus\\internal\\iwrap' => '/ServiceBus/Internal/IWrap.php', + 'windowsazure\\servicebus\\internal\\wrapaccesstokenresult' => '/ServiceBus/Internal/WrapAccessTokenResult.php', + 'windowsazure\\servicebus\\internal\\wraprestproxy' => '/ServiceBus/Internal/WrapRestProxy.php', + 'windowsazure\\servicebus\\internal\\wraptokenmanager' => '/ServiceBus/Internal/WrapTokenManager.php', + 'windowsazure\\servicebus\\models\\brokeredmessage' => '/ServiceBus/Models/BrokeredMessage.php', + 'windowsazure\\servicebus\\models\\brokerproperties' => '/ServiceBus/Models/BrokerProperties.php', + 'windowsazure\\servicebus\\models\\correlationfilter' => '/ServiceBus/Models/CorrelationFilter.php', + 'windowsazure\\servicebus\\models\\emptyruleaction' => '/ServiceBus/Models/EmptyRuleAction.php', + 'windowsazure\\servicebus\\models\\falsefilter' => '/ServiceBus/Models/FalseFilter.php', + 'windowsazure\\servicebus\\models\\listoptions' => '/ServiceBus/Models/ListOptions.php', + 'windowsazure\\servicebus\\models\\listqueuesoptions' => '/ServiceBus/Models/ListQueuesOptions.php', + 'windowsazure\\servicebus\\models\\listqueuesresult' => '/ServiceBus/Models/ListQueuesResult.php', + 'windowsazure\\servicebus\\models\\listrulesoptions' => '/ServiceBus/Models/ListRulesOptions.php', + 'windowsazure\\servicebus\\models\\listrulesresult' => '/ServiceBus/Models/ListRulesResult.php', + 'windowsazure\\servicebus\\models\\listsubscriptionsoptions' => '/ServiceBus/Models/ListSubscriptionsOptions.php', + 'windowsazure\\servicebus\\models\\listsubscriptionsresult' => '/ServiceBus/Models/ListSubscriptionsResult.php', + 'windowsazure\\servicebus\\models\\listtopicsoptions' => '/ServiceBus/Models/ListTopicsOptions.php', + 'windowsazure\\servicebus\\models\\listtopicsresult' => '/ServiceBus/Models/ListTopicsResult.php', + 'windowsazure\\servicebus\\models\\queuedescription' => '/ServiceBus/Models/QueueDescription.php', + 'windowsazure\\servicebus\\models\\queueinfo' => '/ServiceBus/Models/QueueInfo.php', + 'windowsazure\\servicebus\\models\\receivemessageoptions' => '/ServiceBus/Models/ReceiveMessageOptions.php', + 'windowsazure\\servicebus\\models\\receivemode' => '/ServiceBus/Models/ReceiveMode.php', + 'windowsazure\\servicebus\\models\\ruledescription' => '/ServiceBus/Models/RuleDescription.php', + 'windowsazure\\servicebus\\models\\ruleinfo' => '/ServiceBus/Models/RuleInfo.php', + 'windowsazure\\servicebus\\models\\sqlfilter' => '/ServiceBus/Models/SqlFilter.php', + 'windowsazure\\servicebus\\models\\sqlruleaction' => '/ServiceBus/Models/SqlRuleAction.php', + 'windowsazure\\servicebus\\models\\subscriptiondescription' => '/ServiceBus/Models/SubscriptionDescription.php', + 'windowsazure\\servicebus\\models\\subscriptioninfo' => '/ServiceBus/Models/SubscriptionInfo.php', + 'windowsazure\\servicebus\\models\\topicdescription' => '/ServiceBus/Models/TopicDescription.php', + 'windowsazure\\servicebus\\models\\topicinfo' => '/ServiceBus/Models/TopicInfo.php', + 'windowsazure\\servicebus\\models\\truefilter' => '/ServiceBus/Models/TrueFilter.php', + 'windowsazure\\servicebus\\servicebusrestproxy' => '/ServiceBus/ServiceBusRestProxy.php', + 'windowsazure\\servicemanagement\\internal\\iservicemanagement' => '/ServiceManagement/Internal/IServiceManagement.php', + 'windowsazure\\servicemanagement\\internal\\service' => '/ServiceManagement/Internal/Service.php', + 'windowsazure\\servicemanagement\\internal\\windowsazureservice' => '/ServiceManagement/Internal/WindowsAzureService.php', + 'windowsazure\\servicemanagement\\models\\affinitygroup' => '/ServiceManagement/Models/AffinityGroup.php', + 'windowsazure\\servicemanagement\\models\\asynchronousoperationresult' => '/ServiceManagement/Models/AsynchronousOperationResult.php', + 'windowsazure\\servicemanagement\\models\\changedeploymentconfigurationoptions' => '/ServiceManagement/Models/ChangeDeploymentConfigurationOptions.php', + 'windowsazure\\servicemanagement\\models\\createaffinitygroupoptions' => '/ServiceManagement/Models/CreateAffinityGroupOptions.php', + 'windowsazure\\servicemanagement\\models\\createdeploymentoptions' => '/ServiceManagement/Models/CreateDeploymentOptions.php', + 'windowsazure\\servicemanagement\\models\\createserviceoptions' => '/ServiceManagement/Models/CreateServiceOptions.php', + 'windowsazure\\servicemanagement\\models\\deployment' => '/ServiceManagement/Models/Deployment.php', + 'windowsazure\\servicemanagement\\models\\deploymentslot' => '/ServiceManagement/Models/DeploymentSlot.php', + 'windowsazure\\servicemanagement\\models\\deploymentstatus' => '/ServiceManagement/Models/DeploymentStatus.php', + 'windowsazure\\servicemanagement\\models\\getaffinitygrouppropertiesresult' => '/ServiceManagement/Models/GetAffinityGroupPropertiesResult.php', + 'windowsazure\\servicemanagement\\models\\getdeploymentoptions' => '/ServiceManagement/Models/GetDeploymentOptions.php', + 'windowsazure\\servicemanagement\\models\\getdeploymentresult' => '/ServiceManagement/Models/GetDeploymentResult.php', + 'windowsazure\\servicemanagement\\models\\gethostedservicepropertiesoptions' => '/ServiceManagement/Models/GetHostedServicePropertiesOptions.php', + 'windowsazure\\servicemanagement\\models\\gethostedservicepropertiesresult' => '/ServiceManagement/Models/GetHostedServicePropertiesResult.php', + 'windowsazure\\servicemanagement\\models\\getoperationstatusresult' => '/ServiceManagement/Models/GetOperationStatusResult.php', + 'windowsazure\\servicemanagement\\models\\getstorageservicekeysresult' => '/ServiceManagement/Models/GetStorageServiceKeysResult.php', + 'windowsazure\\servicemanagement\\models\\getstorageservicepropertiesresult' => '/ServiceManagement/Models/GetStorageServicePropertiesResult.php', + 'windowsazure\\servicemanagement\\models\\hostedservice' => '/ServiceManagement/Models/HostedService.php', + 'windowsazure\\servicemanagement\\models\\inputendpoint' => '/ServiceManagement/Models/InputEndpoint.php', + 'windowsazure\\servicemanagement\\models\\keytype' => '/ServiceManagement/Models/KeyType.php', + 'windowsazure\\servicemanagement\\models\\listaffinitygroupsresult' => '/ServiceManagement/Models/ListAffinityGroupsResult.php', + 'windowsazure\\servicemanagement\\models\\listhostedservicesresult' => '/ServiceManagement/Models/ListHostedServicesResult.php', + 'windowsazure\\servicemanagement\\models\\listlocationsresult' => '/ServiceManagement/Models/ListLocationsResult.php', + 'windowsazure\\servicemanagement\\models\\liststorageservicesresult' => '/ServiceManagement/Models/ListStorageServicesResult.php', + 'windowsazure\\servicemanagement\\models\\location' => '/ServiceManagement/Models/Location.php', + 'windowsazure\\servicemanagement\\models\\mode' => '/ServiceManagement/Models/Mode.php', + 'windowsazure\\servicemanagement\\models\\operationstatus' => '/ServiceManagement/Models/OperationStatus.php', + 'windowsazure\\servicemanagement\\models\\role' => '/ServiceManagement/Models/Role.php', + 'windowsazure\\servicemanagement\\models\\roleinstance' => '/ServiceManagement/Models/RoleInstance.php', + 'windowsazure\\servicemanagement\\models\\storageservice' => '/ServiceManagement/Models/StorageService.php', + 'windowsazure\\servicemanagement\\models\\updateserviceoptions' => '/ServiceManagement/Models/UpdateServiceOptions.php', + 'windowsazure\\servicemanagement\\models\\upgradedeploymentoptions' => '/ServiceManagement/Models/UpgradeDeploymentOptions.php', + 'windowsazure\\servicemanagement\\models\\upgradestatus' => '/ServiceManagement/Models/UpgradeStatus.php', + 'windowsazure\\servicemanagement\\servicemanagementrestproxy' => '/ServiceManagement/ServiceManagementRestProxy.php', + 'windowsazure\\serviceruntime\\internal\\acquirecurrentstate' => '/ServiceRuntime/Internal/AcquireCurrentState.php', + 'windowsazure\\serviceruntime\\internal\\channelnotavailableexception' => '/ServiceRuntime/Internal/ChannelNotAvailableException.php', + 'windowsazure\\serviceruntime\\internal\\chunkedgoalstatedeserializer' => '/ServiceRuntime/Internal/ChunkedGoalStateDeserializer.php', + 'windowsazure\\serviceruntime\\internal\\currentstate' => '/ServiceRuntime/Internal/CurrentState.php', + 'windowsazure\\serviceruntime\\internal\\currentstatus' => '/ServiceRuntime/Internal/CurrentStatus.php', + 'windowsazure\\serviceruntime\\internal\\fileinputchannel' => '/ServiceRuntime/Internal/FileInputChannel.php', + 'windowsazure\\serviceruntime\\internal\\fileoutputchannel' => '/ServiceRuntime/Internal/FileOutputChannel.php', + 'windowsazure\\serviceruntime\\internal\\goalstate' => '/ServiceRuntime/Internal/GoalState.php', + 'windowsazure\\serviceruntime\\internal\\icurrentstateserializer' => '/ServiceRuntime/Internal/ICurrentStateSerializer.php', + 'windowsazure\\serviceruntime\\internal\\igoalstatedeserializer' => '/ServiceRuntime/Internal/IGoalStateDeserializer.php', + 'windowsazure\\serviceruntime\\internal\\iinputchannel' => '/ServiceRuntime/Internal/IInputChannel.php', + 'windowsazure\\serviceruntime\\internal\\ioutputchannel' => '/ServiceRuntime/Internal/IOutputChannel.php', + 'windowsazure\\serviceruntime\\internal\\iroleenvironmentchange' => '/ServiceRuntime/Internal/IRoleEnvironmentChange.php', + 'windowsazure\\serviceruntime\\internal\\iroleenvironmentdatadeserializer' => '/ServiceRuntime/Internal/IRoleEnvironmentDataDeserializer.php', + 'windowsazure\\serviceruntime\\internal\\iruntimeclient' => '/ServiceRuntime/Internal/IRuntimeClient.php', + 'windowsazure\\serviceruntime\\internal\\iruntimeclientfactory' => '/ServiceRuntime/Internal/IRuntimeClientFactory.php', + 'windowsazure\\serviceruntime\\internal\\iruntimecurrentstateclient' => '/ServiceRuntime/Internal/IRuntimeCurrentStateClient.php', + 'windowsazure\\serviceruntime\\internal\\iruntimegoalstateclient' => '/ServiceRuntime/Internal/IRuntimeGoalStateClient.php', + 'windowsazure\\serviceruntime\\internal\\localresource' => '/ServiceRuntime/Internal/LocalResource.php', + 'windowsazure\\serviceruntime\\internal\\protocol1runtimeclient' => '/ServiceRuntime/Internal/Protocol1RuntimeClient.php', + 'windowsazure\\serviceruntime\\internal\\protocol1runtimeclientfactory' => '/ServiceRuntime/Internal/Protocol1RuntimeClientFactory.php', + 'windowsazure\\serviceruntime\\internal\\protocol1runtimecurrentstateclient' => '/ServiceRuntime/Internal/Protocol1RuntimeCurrentStateClient.php', + 'windowsazure\\serviceruntime\\internal\\protocol1runtimegoalstateclient' => '/ServiceRuntime/Internal/Protocol1RuntimeGoalStateClient.php', + 'windowsazure\\serviceruntime\\internal\\releasecurrentstate' => '/ServiceRuntime/Internal/ReleaseCurrentState.php', + 'windowsazure\\serviceruntime\\internal\\role' => '/ServiceRuntime/Internal/Role.php', + 'windowsazure\\serviceruntime\\internal\\roleenvironmentconfigurationsettingchange' => '/ServiceRuntime/Internal/RoleEnvironmentConfigurationSettingChange.php', + 'windowsazure\\serviceruntime\\internal\\roleenvironmentdata' => '/ServiceRuntime/Internal/RoleEnvironmentData.php', + 'windowsazure\\serviceruntime\\internal\\roleenvironmentnotavailableexception' => '/ServiceRuntime/Internal/RoleEnvironmentNotAvailableException.php', + 'windowsazure\\serviceruntime\\internal\\roleenvironmenttopologychange' => '/ServiceRuntime/Internal/RoleEnvironmentTopologyChange.php', + 'windowsazure\\serviceruntime\\internal\\roleinstance' => '/ServiceRuntime/Internal/RoleInstance.php', + 'windowsazure\\serviceruntime\\internal\\roleinstanceendpoint' => '/ServiceRuntime/Internal/RoleInstanceEndpoint.php', + 'windowsazure\\serviceruntime\\internal\\roleinstancestatus' => '/ServiceRuntime/Internal/RoleInstanceStatus.php', + 'windowsazure\\serviceruntime\\internal\\runtimekernel' => '/ServiceRuntime/Internal/RuntimeKernel.php', + 'windowsazure\\serviceruntime\\internal\\runtimeversionmanager' => '/ServiceRuntime/Internal/RuntimeVersionManager.php', + 'windowsazure\\serviceruntime\\internal\\runtimeversionprotocolclient' => '/ServiceRuntime/Internal/RuntimeVersionProtocolClient.php', + 'windowsazure\\serviceruntime\\internal\\xmlcurrentstateserializer' => '/ServiceRuntime/Internal/XmlCurrentStateSerializer.php', + 'windowsazure\\serviceruntime\\internal\\xmlgoalstatedeserializer' => '/ServiceRuntime/Internal/XmlGoalStateDeserializer.php', + 'windowsazure\\serviceruntime\\internal\\xmlroleenvironmentdatadeserializer' => '/ServiceRuntime/Internal/XmlRoleEnvironmentDataDeserializer.php', + 'windowsazure\\serviceruntime\\roleenvironment' => '/ServiceRuntime/RoleEnvironment.php', + 'windowsazure\\table\\internal\\atomreaderwriter' => '/Table/Internal/AtomReaderWriter.php', + 'windowsazure\\table\\internal\\iatomreaderwriter' => '/Table/Internal/IAtomReaderWriter.php', + 'windowsazure\\table\\internal\\imimereaderwriter' => '/Table/Internal/IMimeReaderWriter.php', + 'windowsazure\\table\\internal\\itable' => '/Table/Internal/ITable.php', + 'windowsazure\\table\\internal\\mimereaderwriter' => '/Table/Internal/MimeReaderWriter.php', + 'windowsazure\\table\\models\\batcherror' => '/Table/Models/BatchError.php', + 'windowsazure\\table\\models\\batchoperation' => '/Table/Models/BatchOperation.php', + 'windowsazure\\table\\models\\batchoperationparametername' => '/Table/Models/BatchOperationParameterName.php', + 'windowsazure\\table\\models\\batchoperations' => '/Table/Models/BatchOperations.php', + 'windowsazure\\table\\models\\batchoperationtype' => '/Table/Models/BatchOperationType.php', + 'windowsazure\\table\\models\\batchresult' => '/Table/Models/BatchResult.php', + 'windowsazure\\table\\models\\deleteentityoptions' => '/Table/Models/DeleteEntityOptions.php', + 'windowsazure\\table\\models\\edmtype' => '/Table/Models/EdmType.php', + 'windowsazure\\table\\models\\entity' => '/Table/Models/Entity.php', + 'windowsazure\\table\\models\\filters\\binaryfilter' => '/Table/Models/Filters/BinaryFilter.php', + 'windowsazure\\table\\models\\filters\\constantfilter' => '/Table/Models/Filters/ConstantFilter.php', + 'windowsazure\\table\\models\\filters\\filter' => '/Table/Models/Filters/Filter.php', + 'windowsazure\\table\\models\\filters\\propertynamefilter' => '/Table/Models/Filters/PropertyNameFilter.php', + 'windowsazure\\table\\models\\filters\\querystringfilter' => '/Table/Models/Filters/QueryStringFilter.php', + 'windowsazure\\table\\models\\filters\\unaryfilter' => '/Table/Models/Filters/UnaryFilter.php', + 'windowsazure\\table\\models\\getentityresult' => '/Table/Models/GetEntityResult.php', + 'windowsazure\\table\\models\\gettableresult' => '/Table/Models/GetTableResult.php', + 'windowsazure\\table\\models\\insertentityresult' => '/Table/Models/InsertEntityResult.php', + 'windowsazure\\table\\models\\property' => '/Table/Models/Property.php', + 'windowsazure\\table\\models\\query' => '/Table/Models/Query.php', + 'windowsazure\\table\\models\\queryentitiesoptions' => '/Table/Models/QueryEntitiesOptions.php', + 'windowsazure\\table\\models\\queryentitiesresult' => '/Table/Models/QueryEntitiesResult.php', + 'windowsazure\\table\\models\\querytablesoptions' => '/Table/Models/QueryTablesOptions.php', + 'windowsazure\\table\\models\\querytablesresult' => '/Table/Models/QueryTablesResult.php', + 'windowsazure\\table\\models\\tableserviceoptions' => '/Table/Models/TableServiceOptions.php', + 'windowsazure\\table\\models\\updateentityresult' => '/Table/Models/UpdateEntityResult.php', + 'windowsazure\\table\\tablerestproxy' => '/Table/TableRestProxy.php' + ); + } + $cn = strtolower($class); + if (isset($classes[$cn])) { + require __DIR__ . $classes[$cn]; + } + } +); diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/ErrorHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/ErrorHandler.php new file mode 100644 index 0000000..0152298 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/ErrorHandler.php @@ -0,0 +1,227 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog; + +use Psr\Log\LoggerInterface; +use Psr\Log\LogLevel; +use Monolog\Handler\AbstractHandler; + +/** + * Monolog error handler + * + * A facility to enable logging of runtime errors, exceptions and fatal errors. + * + * Quick setup: ErrorHandler::register($logger); + * + * @author Jordi Boggiano + */ +class ErrorHandler +{ + private $logger; + + private $previousExceptionHandler; + private $uncaughtExceptionLevel; + + private $previousErrorHandler; + private $errorLevelMap; + private $handleOnlyReportedErrors; + + private $hasFatalErrorHandler; + private $fatalLevel; + private $reservedMemory; + private static $fatalErrors = array(E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR); + + public function __construct(LoggerInterface $logger) + { + $this->logger = $logger; + } + + /** + * Registers a new ErrorHandler for a given Logger + * + * By default it will handle errors, exceptions and fatal errors + * + * @param LoggerInterface $logger + * @param array|false $errorLevelMap an array of E_* constant to LogLevel::* constant mapping, or false to disable error handling + * @param int|false $exceptionLevel a LogLevel::* constant, or false to disable exception handling + * @param int|false $fatalLevel a LogLevel::* constant, or false to disable fatal error handling + * @return ErrorHandler + */ + public static function register(LoggerInterface $logger, $errorLevelMap = array(), $exceptionLevel = null, $fatalLevel = null) + { + $handler = new static($logger); + if ($errorLevelMap !== false) { + $handler->registerErrorHandler($errorLevelMap); + } + if ($exceptionLevel !== false) { + $handler->registerExceptionHandler($exceptionLevel); + } + if ($fatalLevel !== false) { + $handler->registerFatalHandler($fatalLevel); + } + + return $handler; + } + + public function registerExceptionHandler($level = null, $callPrevious = true) + { + $prev = set_exception_handler(array($this, 'handleException')); + $this->uncaughtExceptionLevel = $level; + if ($callPrevious && $prev) { + $this->previousExceptionHandler = $prev; + } + } + + public function registerErrorHandler(array $levelMap = array(), $callPrevious = true, $errorTypes = -1, $handleOnlyReportedErrors = true) + { + $prev = set_error_handler(array($this, 'handleError'), $errorTypes); + $this->errorLevelMap = array_replace($this->defaultErrorLevelMap(), $levelMap); + if ($callPrevious) { + $this->previousErrorHandler = $prev ?: true; + } + + $this->handleOnlyReportedErrors = $handleOnlyReportedErrors; + } + + public function registerFatalHandler($level = null, $reservedMemorySize = 20) + { + register_shutdown_function(array($this, 'handleFatalError')); + + $this->reservedMemory = str_repeat(' ', 1024 * $reservedMemorySize); + $this->fatalLevel = $level; + $this->hasFatalErrorHandler = true; + } + + protected function defaultErrorLevelMap() + { + return array( + E_ERROR => LogLevel::CRITICAL, + E_WARNING => LogLevel::WARNING, + E_PARSE => LogLevel::ALERT, + E_NOTICE => LogLevel::NOTICE, + E_CORE_ERROR => LogLevel::CRITICAL, + E_CORE_WARNING => LogLevel::WARNING, + E_COMPILE_ERROR => LogLevel::ALERT, + E_COMPILE_WARNING => LogLevel::WARNING, + E_USER_ERROR => LogLevel::ERROR, + E_USER_WARNING => LogLevel::WARNING, + E_USER_NOTICE => LogLevel::NOTICE, + E_STRICT => LogLevel::NOTICE, + E_RECOVERABLE_ERROR => LogLevel::ERROR, + E_DEPRECATED => LogLevel::NOTICE, + E_USER_DEPRECATED => LogLevel::NOTICE, + ); + } + + /** + * @private + */ + public function handleException($e) + { + $this->logger->log( + $this->uncaughtExceptionLevel === null ? LogLevel::ERROR : $this->uncaughtExceptionLevel, + sprintf('Uncaught Exception %s: "%s" at %s line %s', get_class($e), $e->getMessage(), $e->getFile(), $e->getLine()), + array('exception' => $e) + ); + + if ($this->previousExceptionHandler) { + call_user_func($this->previousExceptionHandler, $e); + } + + exit(255); + } + + /** + * @private + */ + public function handleError($code, $message, $file = '', $line = 0, $context = array()) + { + if ($this->handleOnlyReportedErrors && !(error_reporting() & $code)) { + return; + } + + // fatal error codes are ignored if a fatal error handler is present as well to avoid duplicate log entries + if (!$this->hasFatalErrorHandler || !in_array($code, self::$fatalErrors, true)) { + $level = isset($this->errorLevelMap[$code]) ? $this->errorLevelMap[$code] : LogLevel::CRITICAL; + $this->logger->log($level, self::codeToString($code).': '.$message, array('code' => $code, 'message' => $message, 'file' => $file, 'line' => $line)); + } + + if ($this->previousErrorHandler === true) { + return false; + } elseif ($this->previousErrorHandler) { + return call_user_func($this->previousErrorHandler, $code, $message, $file, $line, $context); + } + } + + /** + * @private + */ + public function handleFatalError() + { + $this->reservedMemory = null; + + $lastError = error_get_last(); + if ($lastError && in_array($lastError['type'], self::$fatalErrors, true)) { + $this->logger->log( + $this->fatalLevel === null ? LogLevel::ALERT : $this->fatalLevel, + 'Fatal Error ('.self::codeToString($lastError['type']).'): '.$lastError['message'], + array('code' => $lastError['type'], 'message' => $lastError['message'], 'file' => $lastError['file'], 'line' => $lastError['line']) + ); + + if ($this->logger instanceof Logger) { + foreach ($this->logger->getHandlers() as $handler) { + if ($handler instanceof AbstractHandler) { + $handler->close(); + } + } + } + } + } + + private static function codeToString($code) + { + switch ($code) { + case E_ERROR: + return 'E_ERROR'; + case E_WARNING: + return 'E_WARNING'; + case E_PARSE: + return 'E_PARSE'; + case E_NOTICE: + return 'E_NOTICE'; + case E_CORE_ERROR: + return 'E_CORE_ERROR'; + case E_CORE_WARNING: + return 'E_CORE_WARNING'; + case E_COMPILE_ERROR: + return 'E_COMPILE_ERROR'; + case E_COMPILE_WARNING: + return 'E_COMPILE_WARNING'; + case E_USER_ERROR: + return 'E_USER_ERROR'; + case E_USER_WARNING: + return 'E_USER_WARNING'; + case E_USER_NOTICE: + return 'E_USER_NOTICE'; + case E_STRICT: + return 'E_STRICT'; + case E_RECOVERABLE_ERROR: + return 'E_RECOVERABLE_ERROR'; + case E_DEPRECATED: + return 'E_DEPRECATED'; + case E_USER_DEPRECATED: + return 'E_USER_DEPRECATED'; + } + + return 'Unknown PHP error'; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Formatter/ChromePHPFormatter.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Formatter/ChromePHPFormatter.php new file mode 100644 index 0000000..9beda1e --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Formatter/ChromePHPFormatter.php @@ -0,0 +1,78 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Formatter; + +use Monolog\Logger; + +/** + * Formats a log message according to the ChromePHP array format + * + * @author Christophe Coevoet + */ +class ChromePHPFormatter implements FormatterInterface +{ + /** + * Translates Monolog log levels to Wildfire levels. + */ + private $logLevels = array( + Logger::DEBUG => 'log', + Logger::INFO => 'info', + Logger::NOTICE => 'info', + Logger::WARNING => 'warn', + Logger::ERROR => 'error', + Logger::CRITICAL => 'error', + Logger::ALERT => 'error', + Logger::EMERGENCY => 'error', + ); + + /** + * {@inheritdoc} + */ + public function format(array $record) + { + // Retrieve the line and file if set and remove them from the formatted extra + $backtrace = 'unknown'; + if (isset($record['extra']['file'], $record['extra']['line'])) { + $backtrace = $record['extra']['file'].' : '.$record['extra']['line']; + unset($record['extra']['file'], $record['extra']['line']); + } + + $message = array('message' => $record['message']); + if ($record['context']) { + $message['context'] = $record['context']; + } + if ($record['extra']) { + $message['extra'] = $record['extra']; + } + if (count($message) === 1) { + $message = reset($message); + } + + return array( + $record['channel'], + $message, + $backtrace, + $this->logLevels[$record['level']], + ); + } + + public function formatBatch(array $records) + { + $formatted = array(); + + foreach ($records as $record) { + $formatted[] = $this->format($record); + } + + return $formatted; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Formatter/ElasticaFormatter.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Formatter/ElasticaFormatter.php new file mode 100644 index 0000000..4c556cf --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Formatter/ElasticaFormatter.php @@ -0,0 +1,89 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Formatter; + +use Elastica\Document; + +/** + * Format a log message into an Elastica Document + * + * @author Jelle Vink + */ +class ElasticaFormatter extends NormalizerFormatter +{ + /** + * @var string Elastic search index name + */ + protected $index; + + /** + * @var string Elastic search document type + */ + protected $type; + + /** + * @param string $index Elastic Search index name + * @param string $type Elastic Search document type + */ + public function __construct($index, $type) + { + // elasticsearch requires a ISO 8601 format date with optional millisecond precision. + parent::__construct('Y-m-d\TH:i:s.uP'); + + $this->index = $index; + $this->type = $type; + } + + /** + * {@inheritdoc} + */ + public function format(array $record) + { + $record = parent::format($record); + + return $this->getDocument($record); + } + + /** + * Getter index + * @return string + */ + public function getIndex() + { + return $this->index; + } + + /** + * Getter type + * @return string + */ + public function getType() + { + return $this->type; + } + + /** + * Convert a log message into an Elastica Document + * + * @param array $record Log message + * @return Document + */ + protected function getDocument($record) + { + $document = new Document(); + $document->setData($record); + $document->setType($this->type); + $document->setIndex($this->index); + + return $document; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Formatter/FlowdockFormatter.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Formatter/FlowdockFormatter.php new file mode 100644 index 0000000..5094af3 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Formatter/FlowdockFormatter.php @@ -0,0 +1,116 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Formatter; + +/** + * formats the record to be used in the FlowdockHandler + * + * @author Dominik Liebler + */ +class FlowdockFormatter implements FormatterInterface +{ + /** + * @var string + */ + private $source; + + /** + * @var string + */ + private $sourceEmail; + + /** + * @param string $source + * @param string $sourceEmail + */ + public function __construct($source, $sourceEmail) + { + $this->source = $source; + $this->sourceEmail = $sourceEmail; + } + + /** + * {@inheritdoc} + */ + public function format(array $record) + { + $tags = array( + '#logs', + '#' . strtolower($record['level_name']), + '#' . $record['channel'], + ); + + foreach ($record['extra'] as $value) { + $tags[] = '#' . $value; + } + + $subject = sprintf( + 'in %s: %s - %s', + $this->source, + $record['level_name'], + $this->getShortMessage($record['message']) + ); + + $record['flowdock'] = array( + 'source' => $this->source, + 'from_address' => $this->sourceEmail, + 'subject' => $subject, + 'content' => $record['message'], + 'tags' => $tags, + 'project' => $this->source, + ); + + return $record; + } + + /** + * {@inheritdoc} + */ + public function formatBatch(array $records) + { + $formatted = array(); + + foreach ($records as $record) { + $formatted[] = $this->format($record); + } + + return $formatted; + } + + /** + * @param string $message + * + * @return string + */ + public function getShortMessage($message) + { + static $hasMbString; + + if (null === $hasMbString) { + $hasMbString = function_exists('mb_strlen'); + } + + $maxLength = 45; + + if ($hasMbString) { + if (mb_strlen($message, 'UTF-8') > $maxLength) { + $message = mb_substr($message, 0, $maxLength - 4, 'UTF-8') . ' ...'; + } + } else { + if (strlen($message) > $maxLength) { + $message = substr($message, 0, $maxLength - 4) . ' ...'; + } + } + + return $message; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Formatter/FluentdFormatter.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Formatter/FluentdFormatter.php new file mode 100644 index 0000000..02632bb --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Formatter/FluentdFormatter.php @@ -0,0 +1,85 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Formatter; + +/** + * Class FluentdFormatter + * + * Serializes a log message to Fluentd unix socket protocol + * + * Fluentd config: + * + * + * type unix + * path /var/run/td-agent/td-agent.sock + * + * + * Monolog setup: + * + * $logger = new Monolog\Logger('fluent.tag'); + * $fluentHandler = new Monolog\Handler\SocketHandler('unix:///var/run/td-agent/td-agent.sock'); + * $fluentHandler->setFormatter(new Monolog\Formatter\FluentdFormatter()); + * $logger->pushHandler($fluentHandler); + * + * @author Andrius Putna + */ +class FluentdFormatter implements FormatterInterface +{ + /** + * @var bool $levelTag should message level be a part of the fluentd tag + */ + protected $levelTag = false; + + public function __construct($levelTag = false) + { + if (!function_exists('json_encode')) { + throw new \RuntimeException('PHP\'s json extension is required to use Monolog\'s FluentdUnixFormatter'); + } + + $this->levelTag = (bool) $levelTag; + } + + public function isUsingLevelsInTag() + { + return $this->levelTag; + } + + public function format(array $record) + { + $tag = $record['channel']; + if ($this->levelTag) { + $tag .= '.' . strtolower($record['level_name']); + } + + $message = array( + 'message' => $record['message'], + 'extra' => $record['extra'], + ); + + if (!$this->levelTag) { + $message['level'] = $record['level']; + $message['level_name'] = $record['level_name']; + } + + return json_encode(array($tag, $record['datetime']->getTimestamp(), $message)); + } + + public function formatBatch(array $records) + { + $message = ''; + foreach ($records as $record) { + $message .= $this->format($record); + } + + return $message; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Formatter/FormatterInterface.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Formatter/FormatterInterface.php new file mode 100644 index 0000000..b5de751 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Formatter/FormatterInterface.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Formatter; + +/** + * Interface for formatters + * + * @author Jordi Boggiano + */ +interface FormatterInterface +{ + /** + * Formats a log record. + * + * @param array $record A record to format + * @return mixed The formatted record + */ + public function format(array $record); + + /** + * Formats a set of log records. + * + * @param array $records A set of records to format + * @return mixed The formatted set of records + */ + public function formatBatch(array $records); +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Formatter/GelfMessageFormatter.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Formatter/GelfMessageFormatter.php new file mode 100644 index 0000000..64e7665 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Formatter/GelfMessageFormatter.php @@ -0,0 +1,137 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Formatter; + +use Monolog\Logger; +use Gelf\Message; + +/** + * Serializes a log message to GELF + * @see http://www.graylog2.org/about/gelf + * + * @author Matt Lehner + */ +class GelfMessageFormatter extends NormalizerFormatter +{ + const MAX_LENGTH = 32766; + + /** + * @var string the name of the system for the Gelf log message + */ + protected $systemName; + + /** + * @var string a prefix for 'extra' fields from the Monolog record (optional) + */ + protected $extraPrefix; + + /** + * @var string a prefix for 'context' fields from the Monolog record (optional) + */ + protected $contextPrefix; + + /** + * Translates Monolog log levels to Graylog2 log priorities. + */ + private $logLevels = array( + Logger::DEBUG => 7, + Logger::INFO => 6, + Logger::NOTICE => 5, + Logger::WARNING => 4, + Logger::ERROR => 3, + Logger::CRITICAL => 2, + Logger::ALERT => 1, + Logger::EMERGENCY => 0, + ); + + public function __construct($systemName = null, $extraPrefix = null, $contextPrefix = 'ctxt_') + { + parent::__construct('U.u'); + + $this->systemName = $systemName ?: gethostname(); + + $this->extraPrefix = $extraPrefix; + $this->contextPrefix = $contextPrefix; + } + + /** + * {@inheritdoc} + */ + public function format(array $record) + { + $record = parent::format($record); + + if (!isset($record['datetime'], $record['message'], $record['level'])) { + throw new \InvalidArgumentException('The record should at least contain datetime, message and level keys, '.var_export($record, true).' given'); + } + + $message = new Message(); + $message + ->setTimestamp($record['datetime']) + ->setShortMessage((string) $record['message']) + ->setHost($this->systemName) + ->setLevel($this->logLevels[$record['level']]); + + // start count with message length + system name length + 200 for padding / metadata + $len = 200 + strlen((string) $record['message']) + strlen($this->systemName); + + if ($len > self::MAX_LENGTH) { + $message->setShortMessage(substr($record['message'], 0, self::MAX_LENGTH - 200)); + + return $message; + } + + if (isset($record['channel'])) { + $message->setFacility($record['channel']); + $len += strlen($record['channel']); + } + if (isset($record['extra']['line'])) { + $message->setLine($record['extra']['line']); + $len += 10; + unset($record['extra']['line']); + } + if (isset($record['extra']['file'])) { + $message->setFile($record['extra']['file']); + $len += strlen($record['extra']['file']); + unset($record['extra']['file']); + } + + foreach ($record['extra'] as $key => $val) { + $val = is_scalar($val) || null === $val ? $val : $this->toJson($val); + $len += strlen($this->extraPrefix . $key . $val); + if ($len > self::MAX_LENGTH) { + $message->setAdditional($this->extraPrefix . $key, substr($val, 0, self::MAX_LENGTH - $len)); + break; + } + $message->setAdditional($this->extraPrefix . $key, $val); + } + + foreach ($record['context'] as $key => $val) { + $val = is_scalar($val) || null === $val ? $val : $this->toJson($val); + $len += strlen($this->contextPrefix . $key . $val); + if ($len > self::MAX_LENGTH) { + $message->setAdditional($this->contextPrefix . $key, substr($val, 0, self::MAX_LENGTH - $len)); + break; + } + $message->setAdditional($this->contextPrefix . $key, $val); + } + + if (null === $message->getFile() && isset($record['context']['exception']['file'])) { + if (preg_match("/^(.+):([0-9]+)$/", $record['context']['exception']['file'], $matches)) { + $message->setFile($matches[1]); + $message->setLine($matches[2]); + } + } + + return $message; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Formatter/HtmlFormatter.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Formatter/HtmlFormatter.php new file mode 100644 index 0000000..3eec95f --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Formatter/HtmlFormatter.php @@ -0,0 +1,141 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Formatter; + +use Monolog\Logger; + +/** + * Formats incoming records into an HTML table + * + * This is especially useful for html email logging + * + * @author Tiago Brito + */ +class HtmlFormatter extends NormalizerFormatter +{ + /** + * Translates Monolog log levels to html color priorities. + */ + protected $logLevels = array( + Logger::DEBUG => '#cccccc', + Logger::INFO => '#468847', + Logger::NOTICE => '#3a87ad', + Logger::WARNING => '#c09853', + Logger::ERROR => '#f0ad4e', + Logger::CRITICAL => '#FF7708', + Logger::ALERT => '#C12A19', + Logger::EMERGENCY => '#000000', + ); + + /** + * @param string $dateFormat The format of the timestamp: one supported by DateTime::format + */ + public function __construct($dateFormat = null) + { + parent::__construct($dateFormat); + } + + /** + * Creates an HTML table row + * + * @param string $th Row header content + * @param string $td Row standard cell content + * @param bool $escapeTd false if td content must not be html escaped + * @return string + */ + protected function addRow($th, $td = ' ', $escapeTd = true) + { + $th = htmlspecialchars($th, ENT_NOQUOTES, 'UTF-8'); + if ($escapeTd) { + $td = '

    '.htmlspecialchars($td, ENT_NOQUOTES, 'UTF-8').'
    '; + } + + return "\n$th:\n".$td."\n"; + } + + /** + * Create a HTML h1 tag + * + * @param string $title Text to be in the h1 + * @param int $level Error level + * @return string + */ + protected function addTitle($title, $level) + { + $title = htmlspecialchars($title, ENT_NOQUOTES, 'UTF-8'); + + return '

    '.$title.'

    '; + } + + /** + * Formats a log record. + * + * @param array $record A record to format + * @return mixed The formatted record + */ + public function format(array $record) + { + $output = $this->addTitle($record['level_name'], $record['level']); + $output .= ''; + + $output .= $this->addRow('Message', (string) $record['message']); + $output .= $this->addRow('Time', $record['datetime']->format($this->dateFormat)); + $output .= $this->addRow('Channel', $record['channel']); + if ($record['context']) { + $embeddedTable = '
    '; + foreach ($record['context'] as $key => $value) { + $embeddedTable .= $this->addRow($key, $this->convertToString($value)); + } + $embeddedTable .= '
    '; + $output .= $this->addRow('Context', $embeddedTable, false); + } + if ($record['extra']) { + $embeddedTable = ''; + foreach ($record['extra'] as $key => $value) { + $embeddedTable .= $this->addRow($key, $this->convertToString($value)); + } + $embeddedTable .= '
    '; + $output .= $this->addRow('Extra', $embeddedTable, false); + } + + return $output.''; + } + + /** + * Formats a set of log records. + * + * @param array $records A set of records to format + * @return mixed The formatted set of records + */ + public function formatBatch(array $records) + { + $message = ''; + foreach ($records as $record) { + $message .= $this->format($record); + } + + return $message; + } + + protected function convertToString($data) + { + if (null === $data || is_scalar($data)) { + return (string) $data; + } + + $data = $this->normalize($data); + if (version_compare(PHP_VERSION, '5.4.0', '>=')) { + return json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); + } + + return str_replace('\\/', '/', json_encode($data)); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Formatter/JsonFormatter.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Formatter/JsonFormatter.php new file mode 100644 index 0000000..4b2be77 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Formatter/JsonFormatter.php @@ -0,0 +1,206 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Formatter; + +use Exception; +use Throwable; + +/** + * Encodes whatever record data is passed to it as json + * + * This can be useful to log to databases or remote APIs + * + * @author Jordi Boggiano + */ +class JsonFormatter extends NormalizerFormatter +{ + const BATCH_MODE_JSON = 1; + const BATCH_MODE_NEWLINES = 2; + + protected $batchMode; + protected $appendNewline; + /** + * @var bool + */ + protected $includeStacktraces = false; + + /** + * @param int $batchMode + */ + public function __construct($batchMode = self::BATCH_MODE_JSON, $appendNewline = true) + { + $this->batchMode = $batchMode; + $this->appendNewline = $appendNewline; + } + + /** + * The batch mode option configures the formatting style for + * multiple records. By default, multiple records will be + * formatted as a JSON-encoded array. However, for + * compatibility with some API endpoints, alternative styles + * are available. + * + * @return int + */ + public function getBatchMode() + { + return $this->batchMode; + } + + /** + * True if newlines are appended to every formatted record + * + * @return bool + */ + public function isAppendingNewlines() + { + return $this->appendNewline; + } + + /** + * {@inheritdoc} + */ + public function format(array $record) + { + return $this->toJson($this->normalize($record), true) . ($this->appendNewline ? "\n" : ''); + } + + /** + * {@inheritdoc} + */ + public function formatBatch(array $records) + { + switch ($this->batchMode) { + case static::BATCH_MODE_NEWLINES: + return $this->formatBatchNewlines($records); + + case static::BATCH_MODE_JSON: + default: + return $this->formatBatchJson($records); + } + } + + /** + * @param bool $include + */ + public function includeStacktraces($include = true) + { + $this->includeStacktraces = $include; + } + + /** + * Return a JSON-encoded array of records. + * + * @param array $records + * @return string + */ + protected function formatBatchJson(array $records) + { + return $this->toJson($this->normalize($records), true); + } + + /** + * Use new lines to separate records instead of a + * JSON-encoded array. + * + * @param array $records + * @return string + */ + protected function formatBatchNewlines(array $records) + { + $instance = $this; + + $oldNewline = $this->appendNewline; + $this->appendNewline = false; + array_walk($records, function (&$value, $key) use ($instance) { + $value = $instance->format($value); + }); + $this->appendNewline = $oldNewline; + + return implode("\n", $records); + } + + /** + * Normalizes given $data. + * + * @param mixed $data + * + * @return mixed + */ + protected function normalize($data) + { + if (is_array($data) || $data instanceof \Traversable) { + $normalized = array(); + + $count = 1; + foreach ($data as $key => $value) { + if ($count++ >= 1000) { + $normalized['...'] = 'Over 1000 items, aborting normalization'; + break; + } + $normalized[$key] = $this->normalize($value); + } + + return $normalized; + } + + if ($data instanceof Exception || $data instanceof Throwable) { + return $this->normalizeException($data); + } + + return $data; + } + + /** + * Normalizes given exception with or without its own stack trace based on + * `includeStacktraces` property. + * + * @param Exception|Throwable $e + * + * @return array + */ + protected function normalizeException($e) + { + // TODO 2.0 only check for Throwable + if (!$e instanceof Exception && !$e instanceof Throwable) { + throw new \InvalidArgumentException('Exception/Throwable expected, got '.gettype($e).' / '.get_class($e)); + } + + $data = array( + 'class' => get_class($e), + 'message' => $e->getMessage(), + 'code' => $e->getCode(), + 'file' => $e->getFile().':'.$e->getLine(), + ); + + if ($this->includeStacktraces) { + $trace = $e->getTrace(); + foreach ($trace as $frame) { + if (isset($frame['file'])) { + $data['trace'][] = $frame['file'].':'.$frame['line']; + } elseif (isset($frame['function']) && $frame['function'] === '{closure}') { + // We should again normalize the frames, because it might contain invalid items + $data['trace'][] = $frame['function']; + } else { + // We should again normalize the frames, because it might contain invalid items + $data['trace'][] = $this->normalize($frame); + } + } + } + + if ($previous = $e->getPrevious()) { + $data['previous'] = $this->normalizeException($previous); + } + + return $data; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Formatter/LineFormatter.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Formatter/LineFormatter.php new file mode 100644 index 0000000..0e62aa3 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Formatter/LineFormatter.php @@ -0,0 +1,169 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Formatter; + +/** + * Formats incoming records into a one-line string + * + * This is especially useful for logging to files + * + * @author Jordi Boggiano + * @author Christophe Coevoet + */ +class LineFormatter extends NormalizerFormatter +{ + const SIMPLE_FORMAT = "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n"; + + protected $format; + protected $allowInlineLineBreaks; + protected $ignoreEmptyContextAndExtra; + protected $includeStacktraces; + + /** + * @param string $format The format of the message + * @param string $dateFormat The format of the timestamp: one supported by DateTime::format + * @param bool $allowInlineLineBreaks Whether to allow inline line breaks in log entries + * @param bool $ignoreEmptyContextAndExtra + */ + public function __construct($format = null, $dateFormat = null, $allowInlineLineBreaks = false, $ignoreEmptyContextAndExtra = false) + { + $this->format = $format ?: static::SIMPLE_FORMAT; + $this->allowInlineLineBreaks = $allowInlineLineBreaks; + $this->ignoreEmptyContextAndExtra = $ignoreEmptyContextAndExtra; + parent::__construct($dateFormat); + } + + public function includeStacktraces($include = true) + { + $this->includeStacktraces = $include; + if ($this->includeStacktraces) { + $this->allowInlineLineBreaks = true; + } + } + + public function allowInlineLineBreaks($allow = true) + { + $this->allowInlineLineBreaks = $allow; + } + + public function ignoreEmptyContextAndExtra($ignore = true) + { + $this->ignoreEmptyContextAndExtra = $ignore; + } + + /** + * {@inheritdoc} + */ + public function format(array $record) + { + $vars = parent::format($record); + + $output = $this->format; + + foreach ($vars['extra'] as $var => $val) { + if (false !== strpos($output, '%extra.'.$var.'%')) { + $output = str_replace('%extra.'.$var.'%', $this->stringify($val), $output); + unset($vars['extra'][$var]); + } + } + + foreach ($vars['context'] as $var => $val) { + if (false !== strpos($output, '%context.'.$var.'%')) { + $output = str_replace('%context.'.$var.'%', $this->stringify($val), $output); + unset($vars['context'][$var]); + } + } + + if ($this->ignoreEmptyContextAndExtra) { + if (empty($vars['context'])) { + unset($vars['context']); + $output = str_replace('%context%', '', $output); + } + + if (empty($vars['extra'])) { + unset($vars['extra']); + $output = str_replace('%extra%', '', $output); + } + } + + foreach ($vars as $var => $val) { + if (false !== strpos($output, '%'.$var.'%')) { + $output = str_replace('%'.$var.'%', $this->stringify($val), $output); + } + } + + return $output; + } + + public function formatBatch(array $records) + { + $message = ''; + foreach ($records as $record) { + $message .= $this->format($record); + } + + return $message; + } + + public function stringify($value) + { + return $this->replaceNewlines($this->convertToString($value)); + } + + protected function normalizeException($e) + { + // TODO 2.0 only check for Throwable + if (!$e instanceof \Exception && !$e instanceof \Throwable) { + throw new \InvalidArgumentException('Exception/Throwable expected, got '.gettype($e).' / '.get_class($e)); + } + + $previousText = ''; + if ($previous = $e->getPrevious()) { + do { + $previousText .= ', '.get_class($previous).'(code: '.$previous->getCode().'): '.$previous->getMessage().' at '.$previous->getFile().':'.$previous->getLine(); + } while ($previous = $previous->getPrevious()); + } + + $str = '[object] ('.get_class($e).'(code: '.$e->getCode().'): '.$e->getMessage().' at '.$e->getFile().':'.$e->getLine().$previousText.')'; + if ($this->includeStacktraces) { + $str .= "\n[stacktrace]\n".$e->getTraceAsString(); + } + + return $str; + } + + protected function convertToString($data) + { + if (null === $data || is_bool($data)) { + return var_export($data, true); + } + + if (is_scalar($data)) { + return (string) $data; + } + + if (version_compare(PHP_VERSION, '5.4.0', '>=')) { + return $this->toJson($data, true); + } + + return str_replace('\\/', '/', @json_encode($data)); + } + + protected function replaceNewlines($str) + { + if ($this->allowInlineLineBreaks) { + return $str; + } + + return str_replace(array("\r\n", "\r", "\n"), ' ', $str); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Formatter/LogglyFormatter.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Formatter/LogglyFormatter.php new file mode 100644 index 0000000..401859b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Formatter/LogglyFormatter.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Formatter; + +/** + * Encodes message information into JSON in a format compatible with Loggly. + * + * @author Adam Pancutt + */ +class LogglyFormatter extends JsonFormatter +{ + /** + * Overrides the default batch mode to new lines for compatibility with the + * Loggly bulk API. + * + * @param int $batchMode + */ + public function __construct($batchMode = self::BATCH_MODE_NEWLINES, $appendNewline = false) + { + parent::__construct($batchMode, $appendNewline); + } + + /** + * Appends the 'timestamp' parameter for indexing by Loggly. + * + * @see https://www.loggly.com/docs/automated-parsing/#json + * @see \Monolog\Formatter\JsonFormatter::format() + */ + public function format(array $record) + { + if (isset($record["datetime"]) && ($record["datetime"] instanceof \DateTime)) { + $record["timestamp"] = $record["datetime"]->format("Y-m-d\TH:i:s.uO"); + // TODO 2.0 unset the 'datetime' parameter, retained for BC + } + + return parent::format($record); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Formatter/LogstashFormatter.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Formatter/LogstashFormatter.php new file mode 100644 index 0000000..8f83bec --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Formatter/LogstashFormatter.php @@ -0,0 +1,166 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Formatter; + +/** + * Serializes a log message to Logstash Event Format + * + * @see http://logstash.net/ + * @see https://github.com/logstash/logstash/blob/master/lib/logstash/event.rb + * + * @author Tim Mower + */ +class LogstashFormatter extends NormalizerFormatter +{ + const V0 = 0; + const V1 = 1; + + /** + * @var string the name of the system for the Logstash log message, used to fill the @source field + */ + protected $systemName; + + /** + * @var string an application name for the Logstash log message, used to fill the @type field + */ + protected $applicationName; + + /** + * @var string a prefix for 'extra' fields from the Monolog record (optional) + */ + protected $extraPrefix; + + /** + * @var string a prefix for 'context' fields from the Monolog record (optional) + */ + protected $contextPrefix; + + /** + * @var int logstash format version to use + */ + protected $version; + + /** + * @param string $applicationName the application that sends the data, used as the "type" field of logstash + * @param string $systemName the system/machine name, used as the "source" field of logstash, defaults to the hostname of the machine + * @param string $extraPrefix prefix for extra keys inside logstash "fields" + * @param string $contextPrefix prefix for context keys inside logstash "fields", defaults to ctxt_ + * @param int $version the logstash format version to use, defaults to 0 + */ + public function __construct($applicationName, $systemName = null, $extraPrefix = null, $contextPrefix = 'ctxt_', $version = self::V0) + { + // logstash requires a ISO 8601 format date with optional millisecond precision. + parent::__construct('Y-m-d\TH:i:s.uP'); + + $this->systemName = $systemName ?: gethostname(); + $this->applicationName = $applicationName; + $this->extraPrefix = $extraPrefix; + $this->contextPrefix = $contextPrefix; + $this->version = $version; + } + + /** + * {@inheritdoc} + */ + public function format(array $record) + { + $record = parent::format($record); + + if ($this->version === self::V1) { + $message = $this->formatV1($record); + } else { + $message = $this->formatV0($record); + } + + return $this->toJson($message) . "\n"; + } + + protected function formatV0(array $record) + { + if (empty($record['datetime'])) { + $record['datetime'] = gmdate('c'); + } + $message = array( + '@timestamp' => $record['datetime'], + '@source' => $this->systemName, + '@fields' => array(), + ); + if (isset($record['message'])) { + $message['@message'] = $record['message']; + } + if (isset($record['channel'])) { + $message['@tags'] = array($record['channel']); + $message['@fields']['channel'] = $record['channel']; + } + if (isset($record['level'])) { + $message['@fields']['level'] = $record['level']; + } + if ($this->applicationName) { + $message['@type'] = $this->applicationName; + } + if (isset($record['extra']['server'])) { + $message['@source_host'] = $record['extra']['server']; + } + if (isset($record['extra']['url'])) { + $message['@source_path'] = $record['extra']['url']; + } + if (!empty($record['extra'])) { + foreach ($record['extra'] as $key => $val) { + $message['@fields'][$this->extraPrefix . $key] = $val; + } + } + if (!empty($record['context'])) { + foreach ($record['context'] as $key => $val) { + $message['@fields'][$this->contextPrefix . $key] = $val; + } + } + + return $message; + } + + protected function formatV1(array $record) + { + if (empty($record['datetime'])) { + $record['datetime'] = gmdate('c'); + } + $message = array( + '@timestamp' => $record['datetime'], + '@version' => 1, + 'host' => $this->systemName, + ); + if (isset($record['message'])) { + $message['message'] = $record['message']; + } + if (isset($record['channel'])) { + $message['type'] = $record['channel']; + $message['channel'] = $record['channel']; + } + if (isset($record['level_name'])) { + $message['level'] = $record['level_name']; + } + if ($this->applicationName) { + $message['type'] = $this->applicationName; + } + if (!empty($record['extra'])) { + foreach ($record['extra'] as $key => $val) { + $message[$this->extraPrefix . $key] = $val; + } + } + if (!empty($record['context'])) { + foreach ($record['context'] as $key => $val) { + $message[$this->contextPrefix . $key] = $val; + } + } + + return $message; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Formatter/MongoDBFormatter.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Formatter/MongoDBFormatter.php new file mode 100644 index 0000000..eb067bb --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Formatter/MongoDBFormatter.php @@ -0,0 +1,105 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Formatter; + +/** + * Formats a record for use with the MongoDBHandler. + * + * @author Florian Plattner + */ +class MongoDBFormatter implements FormatterInterface +{ + private $exceptionTraceAsString; + private $maxNestingLevel; + + /** + * @param int $maxNestingLevel 0 means infinite nesting, the $record itself is level 1, $record['context'] is 2 + * @param bool $exceptionTraceAsString set to false to log exception traces as a sub documents instead of strings + */ + public function __construct($maxNestingLevel = 3, $exceptionTraceAsString = true) + { + $this->maxNestingLevel = max($maxNestingLevel, 0); + $this->exceptionTraceAsString = (bool) $exceptionTraceAsString; + } + + /** + * {@inheritDoc} + */ + public function format(array $record) + { + return $this->formatArray($record); + } + + /** + * {@inheritDoc} + */ + public function formatBatch(array $records) + { + foreach ($records as $key => $record) { + $records[$key] = $this->format($record); + } + + return $records; + } + + protected function formatArray(array $record, $nestingLevel = 0) + { + if ($this->maxNestingLevel == 0 || $nestingLevel <= $this->maxNestingLevel) { + foreach ($record as $name => $value) { + if ($value instanceof \DateTime) { + $record[$name] = $this->formatDate($value, $nestingLevel + 1); + } elseif ($value instanceof \Exception) { + $record[$name] = $this->formatException($value, $nestingLevel + 1); + } elseif (is_array($value)) { + $record[$name] = $this->formatArray($value, $nestingLevel + 1); + } elseif (is_object($value)) { + $record[$name] = $this->formatObject($value, $nestingLevel + 1); + } + } + } else { + $record = '[...]'; + } + + return $record; + } + + protected function formatObject($value, $nestingLevel) + { + $objectVars = get_object_vars($value); + $objectVars['class'] = get_class($value); + + return $this->formatArray($objectVars, $nestingLevel); + } + + protected function formatException(\Exception $exception, $nestingLevel) + { + $formattedException = array( + 'class' => get_class($exception), + 'message' => $exception->getMessage(), + 'code' => $exception->getCode(), + 'file' => $exception->getFile() . ':' . $exception->getLine(), + ); + + if ($this->exceptionTraceAsString === true) { + $formattedException['trace'] = $exception->getTraceAsString(); + } else { + $formattedException['trace'] = $exception->getTrace(); + } + + return $this->formatArray($formattedException, $nestingLevel); + } + + protected function formatDate(\DateTime $value, $nestingLevel) + { + return new \MongoDate($value->getTimestamp()); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Formatter/NormalizerFormatter.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Formatter/NormalizerFormatter.php new file mode 100644 index 0000000..ab79dbc --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Formatter/NormalizerFormatter.php @@ -0,0 +1,297 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Formatter; + +use Exception; + +/** + * Normalizes incoming records to remove objects/resources so it's easier to dump to various targets + * + * @author Jordi Boggiano + */ +class NormalizerFormatter implements FormatterInterface +{ + const SIMPLE_DATE = "Y-m-d H:i:s"; + + protected $dateFormat; + + /** + * @param string $dateFormat The format of the timestamp: one supported by DateTime::format + */ + public function __construct($dateFormat = null) + { + $this->dateFormat = $dateFormat ?: static::SIMPLE_DATE; + if (!function_exists('json_encode')) { + throw new \RuntimeException('PHP\'s json extension is required to use Monolog\'s NormalizerFormatter'); + } + } + + /** + * {@inheritdoc} + */ + public function format(array $record) + { + return $this->normalize($record); + } + + /** + * {@inheritdoc} + */ + public function formatBatch(array $records) + { + foreach ($records as $key => $record) { + $records[$key] = $this->format($record); + } + + return $records; + } + + protected function normalize($data) + { + if (null === $data || is_scalar($data)) { + if (is_float($data)) { + if (is_infinite($data)) { + return ($data > 0 ? '' : '-') . 'INF'; + } + if (is_nan($data)) { + return 'NaN'; + } + } + + return $data; + } + + if (is_array($data) || $data instanceof \Traversable) { + $normalized = array(); + + $count = 1; + foreach ($data as $key => $value) { + if ($count++ >= 1000) { + $normalized['...'] = 'Over 1000 items, aborting normalization'; + break; + } + $normalized[$key] = $this->normalize($value); + } + + return $normalized; + } + + if ($data instanceof \DateTime) { + return $data->format($this->dateFormat); + } + + if (is_object($data)) { + // TODO 2.0 only check for Throwable + if ($data instanceof Exception || (PHP_VERSION_ID > 70000 && $data instanceof \Throwable)) { + return $this->normalizeException($data); + } + + // non-serializable objects that implement __toString stringified + if (method_exists($data, '__toString') && !$data instanceof \JsonSerializable) { + $value = $data->__toString(); + } else { + // the rest is json-serialized in some way + $value = $this->toJson($data, true); + } + + return sprintf("[object] (%s: %s)", get_class($data), $value); + } + + if (is_resource($data)) { + return sprintf('[resource] (%s)', get_resource_type($data)); + } + + return '[unknown('.gettype($data).')]'; + } + + protected function normalizeException($e) + { + // TODO 2.0 only check for Throwable + if (!$e instanceof Exception && !$e instanceof \Throwable) { + throw new \InvalidArgumentException('Exception/Throwable expected, got '.gettype($e).' / '.get_class($e)); + } + + $data = array( + 'class' => get_class($e), + 'message' => $e->getMessage(), + 'code' => $e->getCode(), + 'file' => $e->getFile().':'.$e->getLine(), + ); + + if ($e instanceof \SoapFault) { + if (isset($e->faultcode)) { + $data['faultcode'] = $e->faultcode; + } + + if (isset($e->faultactor)) { + $data['faultactor'] = $e->faultactor; + } + + if (isset($e->detail)) { + $data['detail'] = $e->detail; + } + } + + $trace = $e->getTrace(); + foreach ($trace as $frame) { + if (isset($frame['file'])) { + $data['trace'][] = $frame['file'].':'.$frame['line']; + } elseif (isset($frame['function']) && $frame['function'] === '{closure}') { + // We should again normalize the frames, because it might contain invalid items + $data['trace'][] = $frame['function']; + } else { + // We should again normalize the frames, because it might contain invalid items + $data['trace'][] = $this->toJson($this->normalize($frame), true); + } + } + + if ($previous = $e->getPrevious()) { + $data['previous'] = $this->normalizeException($previous); + } + + return $data; + } + + /** + * Return the JSON representation of a value + * + * @param mixed $data + * @param bool $ignoreErrors + * @throws \RuntimeException if encoding fails and errors are not ignored + * @return string + */ + protected function toJson($data, $ignoreErrors = false) + { + // suppress json_encode errors since it's twitchy with some inputs + if ($ignoreErrors) { + return @$this->jsonEncode($data); + } + + $json = $this->jsonEncode($data); + + if ($json === false) { + $json = $this->handleJsonError(json_last_error(), $data); + } + + return $json; + } + + /** + * @param mixed $data + * @return string JSON encoded data or null on failure + */ + private function jsonEncode($data) + { + if (version_compare(PHP_VERSION, '5.4.0', '>=')) { + return json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); + } + + return json_encode($data); + } + + /** + * Handle a json_encode failure. + * + * If the failure is due to invalid string encoding, try to clean the + * input and encode again. If the second encoding attempt fails, the + * inital error is not encoding related or the input can't be cleaned then + * raise a descriptive exception. + * + * @param int $code return code of json_last_error function + * @param mixed $data data that was meant to be encoded + * @throws \RuntimeException if failure can't be corrected + * @return string JSON encoded data after error correction + */ + private function handleJsonError($code, $data) + { + if ($code !== JSON_ERROR_UTF8) { + $this->throwEncodeError($code, $data); + } + + if (is_string($data)) { + $this->detectAndCleanUtf8($data); + } elseif (is_array($data)) { + array_walk_recursive($data, array($this, 'detectAndCleanUtf8')); + } else { + $this->throwEncodeError($code, $data); + } + + $json = $this->jsonEncode($data); + + if ($json === false) { + $this->throwEncodeError(json_last_error(), $data); + } + + return $json; + } + + /** + * Throws an exception according to a given code with a customized message + * + * @param int $code return code of json_last_error function + * @param mixed $data data that was meant to be encoded + * @throws \RuntimeException + */ + private function throwEncodeError($code, $data) + { + switch ($code) { + case JSON_ERROR_DEPTH: + $msg = 'Maximum stack depth exceeded'; + break; + case JSON_ERROR_STATE_MISMATCH: + $msg = 'Underflow or the modes mismatch'; + break; + case JSON_ERROR_CTRL_CHAR: + $msg = 'Unexpected control character found'; + break; + case JSON_ERROR_UTF8: + $msg = 'Malformed UTF-8 characters, possibly incorrectly encoded'; + break; + default: + $msg = 'Unknown error'; + } + + throw new \RuntimeException('JSON encoding failed: '.$msg.'. Encoding: '.var_export($data, true)); + } + + /** + * Detect invalid UTF-8 string characters and convert to valid UTF-8. + * + * Valid UTF-8 input will be left unmodified, but strings containing + * invalid UTF-8 codepoints will be reencoded as UTF-8 with an assumed + * original encoding of ISO-8859-15. This conversion may result in + * incorrect output if the actual encoding was not ISO-8859-15, but it + * will be clean UTF-8 output and will not rely on expensive and fragile + * detection algorithms. + * + * Function converts the input in place in the passed variable so that it + * can be used as a callback for array_walk_recursive. + * + * @param mixed &$data Input to check and convert if needed + * @private + */ + public function detectAndCleanUtf8(&$data) + { + if (is_string($data) && !preg_match('//u', $data)) { + $data = preg_replace_callback( + '/[\x80-\xFF]+/', + function ($m) { return utf8_encode($m[0]); }, + $data + ); + $data = str_replace( + array('¤', '¦', '¨', '´', '¸', '¼', '½', '¾'), + array('€', 'Š', 'š', 'Ž', 'ž', 'Œ', 'œ', 'Ÿ'), + $data + ); + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Formatter/ScalarFormatter.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Formatter/ScalarFormatter.php new file mode 100644 index 0000000..5d345d5 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Formatter/ScalarFormatter.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Formatter; + +/** + * Formats data into an associative array of scalar values. + * Objects and arrays will be JSON encoded. + * + * @author Andrew Lawson + */ +class ScalarFormatter extends NormalizerFormatter +{ + /** + * {@inheritdoc} + */ + public function format(array $record) + { + foreach ($record as $key => $value) { + $record[$key] = $this->normalizeValue($value); + } + + return $record; + } + + /** + * @param mixed $value + * @return mixed + */ + protected function normalizeValue($value) + { + $normalized = $this->normalize($value); + + if (is_array($normalized) || is_object($normalized)) { + return $this->toJson($normalized, true); + } + + return $normalized; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Formatter/WildfireFormatter.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Formatter/WildfireFormatter.php new file mode 100644 index 0000000..654710a --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Formatter/WildfireFormatter.php @@ -0,0 +1,113 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Formatter; + +use Monolog\Logger; + +/** + * Serializes a log message according to Wildfire's header requirements + * + * @author Eric Clemmons (@ericclemmons) + * @author Christophe Coevoet + * @author Kirill chEbba Chebunin + */ +class WildfireFormatter extends NormalizerFormatter +{ + const TABLE = 'table'; + + /** + * Translates Monolog log levels to Wildfire levels. + */ + private $logLevels = array( + Logger::DEBUG => 'LOG', + Logger::INFO => 'INFO', + Logger::NOTICE => 'INFO', + Logger::WARNING => 'WARN', + Logger::ERROR => 'ERROR', + Logger::CRITICAL => 'ERROR', + Logger::ALERT => 'ERROR', + Logger::EMERGENCY => 'ERROR', + ); + + /** + * {@inheritdoc} + */ + public function format(array $record) + { + // Retrieve the line and file if set and remove them from the formatted extra + $file = $line = ''; + if (isset($record['extra']['file'])) { + $file = $record['extra']['file']; + unset($record['extra']['file']); + } + if (isset($record['extra']['line'])) { + $line = $record['extra']['line']; + unset($record['extra']['line']); + } + + $record = $this->normalize($record); + $message = array('message' => $record['message']); + $handleError = false; + if ($record['context']) { + $message['context'] = $record['context']; + $handleError = true; + } + if ($record['extra']) { + $message['extra'] = $record['extra']; + $handleError = true; + } + if (count($message) === 1) { + $message = reset($message); + } + + if (isset($record['context'][self::TABLE])) { + $type = 'TABLE'; + $label = $record['channel'] .': '. $record['message']; + $message = $record['context'][self::TABLE]; + } else { + $type = $this->logLevels[$record['level']]; + $label = $record['channel']; + } + + // Create JSON object describing the appearance of the message in the console + $json = $this->toJson(array( + array( + 'Type' => $type, + 'File' => $file, + 'Line' => $line, + 'Label' => $label, + ), + $message, + ), $handleError); + + // The message itself is a serialization of the above JSON object + it's length + return sprintf( + '%s|%s|', + strlen($json), + $json + ); + } + + public function formatBatch(array $records) + { + throw new \BadMethodCallException('Batch formatting does not make sense for the WildfireFormatter'); + } + + protected function normalize($data) + { + if (is_object($data) && !$data instanceof \DateTime) { + return $data; + } + + return parent::normalize($data); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/AbstractHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/AbstractHandler.php new file mode 100644 index 0000000..758a425 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/AbstractHandler.php @@ -0,0 +1,186 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; +use Monolog\Formatter\FormatterInterface; +use Monolog\Formatter\LineFormatter; + +/** + * Base Handler class providing the Handler structure + * + * @author Jordi Boggiano + */ +abstract class AbstractHandler implements HandlerInterface +{ + protected $level = Logger::DEBUG; + protected $bubble = true; + + /** + * @var FormatterInterface + */ + protected $formatter; + protected $processors = array(); + + /** + * @param int $level The minimum logging level at which this handler will be triggered + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct($level = Logger::DEBUG, $bubble = true) + { + $this->setLevel($level); + $this->bubble = $bubble; + } + + /** + * {@inheritdoc} + */ + public function isHandling(array $record) + { + return $record['level'] >= $this->level; + } + + /** + * {@inheritdoc} + */ + public function handleBatch(array $records) + { + foreach ($records as $record) { + $this->handle($record); + } + } + + /** + * Closes the handler. + * + * This will be called automatically when the object is destroyed + */ + public function close() + { + } + + /** + * {@inheritdoc} + */ + public function pushProcessor($callback) + { + if (!is_callable($callback)) { + throw new \InvalidArgumentException('Processors must be valid callables (callback or object with an __invoke method), '.var_export($callback, true).' given'); + } + array_unshift($this->processors, $callback); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function popProcessor() + { + if (!$this->processors) { + throw new \LogicException('You tried to pop from an empty processor stack.'); + } + + return array_shift($this->processors); + } + + /** + * {@inheritdoc} + */ + public function setFormatter(FormatterInterface $formatter) + { + $this->formatter = $formatter; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function getFormatter() + { + if (!$this->formatter) { + $this->formatter = $this->getDefaultFormatter(); + } + + return $this->formatter; + } + + /** + * Sets minimum logging level at which this handler will be triggered. + * + * @param int|string $level Level or level name + * @return self + */ + public function setLevel($level) + { + $this->level = Logger::toMonologLevel($level); + + return $this; + } + + /** + * Gets minimum logging level at which this handler will be triggered. + * + * @return int + */ + public function getLevel() + { + return $this->level; + } + + /** + * Sets the bubbling behavior. + * + * @param Boolean $bubble true means that this handler allows bubbling. + * false means that bubbling is not permitted. + * @return self + */ + public function setBubble($bubble) + { + $this->bubble = $bubble; + + return $this; + } + + /** + * Gets the bubbling behavior. + * + * @return Boolean true means that this handler allows bubbling. + * false means that bubbling is not permitted. + */ + public function getBubble() + { + return $this->bubble; + } + + public function __destruct() + { + try { + $this->close(); + } catch (\Exception $e) { + // do nothing + } catch (\Throwable $e) { + // do nothing + } + } + + /** + * Gets the default formatter. + * + * @return FormatterInterface + */ + protected function getDefaultFormatter() + { + return new LineFormatter(); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/AbstractProcessingHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/AbstractProcessingHandler.php new file mode 100644 index 0000000..6f18f72 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/AbstractProcessingHandler.php @@ -0,0 +1,66 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +/** + * Base Handler class providing the Handler structure + * + * Classes extending it should (in most cases) only implement write($record) + * + * @author Jordi Boggiano + * @author Christophe Coevoet + */ +abstract class AbstractProcessingHandler extends AbstractHandler +{ + /** + * {@inheritdoc} + */ + public function handle(array $record) + { + if (!$this->isHandling($record)) { + return false; + } + + $record = $this->processRecord($record); + + $record['formatted'] = $this->getFormatter()->format($record); + + $this->write($record); + + return false === $this->bubble; + } + + /** + * Writes the record down to the log of the implementing handler + * + * @param array $record + * @return void + */ + abstract protected function write(array $record); + + /** + * Processes a record. + * + * @param array $record + * @return array + */ + protected function processRecord(array $record) + { + if ($this->processors) { + foreach ($this->processors as $processor) { + $record = call_user_func($processor, $record); + } + } + + return $record; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/AbstractSyslogHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/AbstractSyslogHandler.php new file mode 100644 index 0000000..e2b2832 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/AbstractSyslogHandler.php @@ -0,0 +1,101 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; +use Monolog\Formatter\LineFormatter; + +/** + * Common syslog functionality + */ +abstract class AbstractSyslogHandler extends AbstractProcessingHandler +{ + protected $facility; + + /** + * Translates Monolog log levels to syslog log priorities. + */ + protected $logLevels = array( + Logger::DEBUG => LOG_DEBUG, + Logger::INFO => LOG_INFO, + Logger::NOTICE => LOG_NOTICE, + Logger::WARNING => LOG_WARNING, + Logger::ERROR => LOG_ERR, + Logger::CRITICAL => LOG_CRIT, + Logger::ALERT => LOG_ALERT, + Logger::EMERGENCY => LOG_EMERG, + ); + + /** + * List of valid log facility names. + */ + protected $facilities = array( + 'auth' => LOG_AUTH, + 'authpriv' => LOG_AUTHPRIV, + 'cron' => LOG_CRON, + 'daemon' => LOG_DAEMON, + 'kern' => LOG_KERN, + 'lpr' => LOG_LPR, + 'mail' => LOG_MAIL, + 'news' => LOG_NEWS, + 'syslog' => LOG_SYSLOG, + 'user' => LOG_USER, + 'uucp' => LOG_UUCP, + ); + + /** + * @param mixed $facility + * @param int $level The minimum logging level at which this handler will be triggered + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct($facility = LOG_USER, $level = Logger::DEBUG, $bubble = true) + { + parent::__construct($level, $bubble); + + if (!defined('PHP_WINDOWS_VERSION_BUILD')) { + $this->facilities['local0'] = LOG_LOCAL0; + $this->facilities['local1'] = LOG_LOCAL1; + $this->facilities['local2'] = LOG_LOCAL2; + $this->facilities['local3'] = LOG_LOCAL3; + $this->facilities['local4'] = LOG_LOCAL4; + $this->facilities['local5'] = LOG_LOCAL5; + $this->facilities['local6'] = LOG_LOCAL6; + $this->facilities['local7'] = LOG_LOCAL7; + } else { + $this->facilities['local0'] = 128; // LOG_LOCAL0 + $this->facilities['local1'] = 136; // LOG_LOCAL1 + $this->facilities['local2'] = 144; // LOG_LOCAL2 + $this->facilities['local3'] = 152; // LOG_LOCAL3 + $this->facilities['local4'] = 160; // LOG_LOCAL4 + $this->facilities['local5'] = 168; // LOG_LOCAL5 + $this->facilities['local6'] = 176; // LOG_LOCAL6 + $this->facilities['local7'] = 184; // LOG_LOCAL7 + } + + // convert textual description of facility to syslog constant + if (array_key_exists(strtolower($facility), $this->facilities)) { + $facility = $this->facilities[strtolower($facility)]; + } elseif (!in_array($facility, array_values($this->facilities), true)) { + throw new \UnexpectedValueException('Unknown facility value "'.$facility.'" given'); + } + + $this->facility = $facility; + } + + /** + * {@inheritdoc} + */ + protected function getDefaultFormatter() + { + return new LineFormatter('%channel%.%level_name%: %message% %context% %extra%'); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/AmqpHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/AmqpHandler.php new file mode 100644 index 0000000..95a91fc --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/AmqpHandler.php @@ -0,0 +1,148 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; +use Monolog\Formatter\JsonFormatter; +use PhpAmqpLib\Message\AMQPMessage; +use PhpAmqpLib\Channel\AMQPChannel; +use AMQPExchange; + +class AmqpHandler extends AbstractProcessingHandler +{ + /** + * @var AMQPExchange|AMQPChannel $exchange + */ + protected $exchange; + + /** + * @var string + */ + protected $exchangeName; + + /** + * @param AMQPExchange|AMQPChannel $exchange AMQPExchange (php AMQP ext) or PHP AMQP lib channel, ready for use + * @param string $exchangeName + * @param int $level + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct($exchange, $exchangeName = 'log', $level = Logger::DEBUG, $bubble = true) + { + if ($exchange instanceof AMQPExchange) { + $exchange->setName($exchangeName); + } elseif ($exchange instanceof AMQPChannel) { + $this->exchangeName = $exchangeName; + } else { + throw new \InvalidArgumentException('PhpAmqpLib\Channel\AMQPChannel or AMQPExchange instance required'); + } + $this->exchange = $exchange; + + parent::__construct($level, $bubble); + } + + /** + * {@inheritDoc} + */ + protected function write(array $record) + { + $data = $record["formatted"]; + $routingKey = $this->getRoutingKey($record); + + if ($this->exchange instanceof AMQPExchange) { + $this->exchange->publish( + $data, + $routingKey, + 0, + array( + 'delivery_mode' => 2, + 'content_type' => 'application/json', + ) + ); + } else { + $this->exchange->basic_publish( + $this->createAmqpMessage($data), + $this->exchangeName, + $routingKey + ); + } + } + + /** + * {@inheritDoc} + */ + public function handleBatch(array $records) + { + if ($this->exchange instanceof AMQPExchange) { + parent::handleBatch($records); + + return; + } + + foreach ($records as $record) { + if (!$this->isHandling($record)) { + continue; + } + + $record = $this->processRecord($record); + $data = $this->getFormatter()->format($record); + + $this->exchange->batch_basic_publish( + $this->createAmqpMessage($data), + $this->exchangeName, + $this->getRoutingKey($record) + ); + } + + $this->exchange->publish_batch(); + } + + /** + * Gets the routing key for the AMQP exchange + * + * @param array $record + * @return string + */ + private function getRoutingKey(array $record) + { + $routingKey = sprintf( + '%s.%s', + // TODO 2.0 remove substr call + substr($record['level_name'], 0, 4), + $record['channel'] + ); + + return strtolower($routingKey); + } + + /** + * @param string $data + * @return AMQPMessage + */ + private function createAmqpMessage($data) + { + return new AMQPMessage( + (string) $data, + array( + 'delivery_mode' => 2, + 'content_type' => 'application/json', + ) + ); + } + + /** + * {@inheritDoc} + */ + protected function getDefaultFormatter() + { + return new JsonFormatter(JsonFormatter::BATCH_MODE_JSON, false); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/BrowserConsoleHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/BrowserConsoleHandler.php new file mode 100644 index 0000000..b3a21bd --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/BrowserConsoleHandler.php @@ -0,0 +1,230 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Formatter\LineFormatter; + +/** + * Handler sending logs to browser's javascript console with no browser extension required + * + * @author Olivier Poitrey + */ +class BrowserConsoleHandler extends AbstractProcessingHandler +{ + protected static $initialized = false; + protected static $records = array(); + + /** + * {@inheritDoc} + * + * Formatted output may contain some formatting markers to be transferred to `console.log` using the %c format. + * + * Example of formatted string: + * + * You can do [[blue text]]{color: blue} or [[green background]]{background-color: green; color: white} + */ + protected function getDefaultFormatter() + { + return new LineFormatter('[[%channel%]]{macro: autolabel} [[%level_name%]]{font-weight: bold} %message%'); + } + + /** + * {@inheritDoc} + */ + protected function write(array $record) + { + // Accumulate records + self::$records[] = $record; + + // Register shutdown handler if not already done + if (!self::$initialized) { + self::$initialized = true; + $this->registerShutdownFunction(); + } + } + + /** + * Convert records to javascript console commands and send it to the browser. + * This method is automatically called on PHP shutdown if output is HTML or Javascript. + */ + public static function send() + { + $format = self::getResponseFormat(); + if ($format === 'unknown') { + return; + } + + if (count(self::$records)) { + if ($format === 'html') { + self::writeOutput(''); + } elseif ($format === 'js') { + self::writeOutput(self::generateScript()); + } + self::reset(); + } + } + + /** + * Forget all logged records + */ + public static function reset() + { + self::$records = array(); + } + + /** + * Wrapper for register_shutdown_function to allow overriding + */ + protected function registerShutdownFunction() + { + if (PHP_SAPI !== 'cli') { + register_shutdown_function(array('Monolog\Handler\BrowserConsoleHandler', 'send')); + } + } + + /** + * Wrapper for echo to allow overriding + * + * @param string $str + */ + protected static function writeOutput($str) + { + echo $str; + } + + /** + * Checks the format of the response + * + * If Content-Type is set to application/javascript or text/javascript -> js + * If Content-Type is set to text/html, or is unset -> html + * If Content-Type is anything else -> unknown + * + * @return string One of 'js', 'html' or 'unknown' + */ + protected static function getResponseFormat() + { + // Check content type + foreach (headers_list() as $header) { + if (stripos($header, 'content-type:') === 0) { + // This handler only works with HTML and javascript outputs + // text/javascript is obsolete in favour of application/javascript, but still used + if (stripos($header, 'application/javascript') !== false || stripos($header, 'text/javascript') !== false) { + return 'js'; + } + if (stripos($header, 'text/html') === false) { + return 'unknown'; + } + break; + } + } + + return 'html'; + } + + private static function generateScript() + { + $script = array(); + foreach (self::$records as $record) { + $context = self::dump('Context', $record['context']); + $extra = self::dump('Extra', $record['extra']); + + if (empty($context) && empty($extra)) { + $script[] = self::call_array('log', self::handleStyles($record['formatted'])); + } else { + $script = array_merge($script, + array(self::call_array('groupCollapsed', self::handleStyles($record['formatted']))), + $context, + $extra, + array(self::call('groupEnd')) + ); + } + } + + return "(function (c) {if (c && c.groupCollapsed) {\n" . implode("\n", $script) . "\n}})(console);"; + } + + private static function handleStyles($formatted) + { + $args = array(self::quote('font-weight: normal')); + $format = '%c' . $formatted; + preg_match_all('/\[\[(.*?)\]\]\{([^}]*)\}/s', $format, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER); + + foreach (array_reverse($matches) as $match) { + $args[] = self::quote(self::handleCustomStyles($match[2][0], $match[1][0])); + $args[] = '"font-weight: normal"'; + + $pos = $match[0][1]; + $format = substr($format, 0, $pos) . '%c' . $match[1][0] . '%c' . substr($format, $pos + strlen($match[0][0])); + } + + array_unshift($args, self::quote($format)); + + return $args; + } + + private static function handleCustomStyles($style, $string) + { + static $colors = array('blue', 'green', 'red', 'magenta', 'orange', 'black', 'grey'); + static $labels = array(); + + return preg_replace_callback('/macro\s*:(.*?)(?:;|$)/', function ($m) use ($string, &$colors, &$labels) { + if (trim($m[1]) === 'autolabel') { + // Format the string as a label with consistent auto assigned background color + if (!isset($labels[$string])) { + $labels[$string] = $colors[count($labels) % count($colors)]; + } + $color = $labels[$string]; + + return "background-color: $color; color: white; border-radius: 3px; padding: 0 2px 0 2px"; + } + + return $m[1]; + }, $style); + } + + private static function dump($title, array $dict) + { + $script = array(); + $dict = array_filter($dict); + if (empty($dict)) { + return $script; + } + $script[] = self::call('log', self::quote('%c%s'), self::quote('font-weight: bold'), self::quote($title)); + foreach ($dict as $key => $value) { + $value = json_encode($value); + if (empty($value)) { + $value = self::quote(''); + } + $script[] = self::call('log', self::quote('%s: %o'), self::quote($key), $value); + } + + return $script; + } + + private static function quote($arg) + { + return '"' . addcslashes($arg, "\"\n\\") . '"'; + } + + private static function call() + { + $args = func_get_args(); + $method = array_shift($args); + + return self::call_array($method, $args); + } + + private static function call_array($method, array $args) + { + return 'c.' . $method . '(' . implode(', ', $args) . ');'; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/BufferHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/BufferHandler.php new file mode 100644 index 0000000..72f8953 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/BufferHandler.php @@ -0,0 +1,117 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; + +/** + * Buffers all records until closing the handler and then pass them as batch. + * + * This is useful for a MailHandler to send only one mail per request instead of + * sending one per log message. + * + * @author Christophe Coevoet + */ +class BufferHandler extends AbstractHandler +{ + protected $handler; + protected $bufferSize = 0; + protected $bufferLimit; + protected $flushOnOverflow; + protected $buffer = array(); + protected $initialized = false; + + /** + * @param HandlerInterface $handler Handler. + * @param int $bufferLimit How many entries should be buffered at most, beyond that the oldest items are removed from the buffer. + * @param int $level The minimum logging level at which this handler will be triggered + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + * @param Boolean $flushOnOverflow If true, the buffer is flushed when the max size has been reached, by default oldest entries are discarded + */ + public function __construct(HandlerInterface $handler, $bufferLimit = 0, $level = Logger::DEBUG, $bubble = true, $flushOnOverflow = false) + { + parent::__construct($level, $bubble); + $this->handler = $handler; + $this->bufferLimit = (int) $bufferLimit; + $this->flushOnOverflow = $flushOnOverflow; + } + + /** + * {@inheritdoc} + */ + public function handle(array $record) + { + if ($record['level'] < $this->level) { + return false; + } + + if (!$this->initialized) { + // __destructor() doesn't get called on Fatal errors + register_shutdown_function(array($this, 'close')); + $this->initialized = true; + } + + if ($this->bufferLimit > 0 && $this->bufferSize === $this->bufferLimit) { + if ($this->flushOnOverflow) { + $this->flush(); + } else { + array_shift($this->buffer); + $this->bufferSize--; + } + } + + if ($this->processors) { + foreach ($this->processors as $processor) { + $record = call_user_func($processor, $record); + } + } + + $this->buffer[] = $record; + $this->bufferSize++; + + return false === $this->bubble; + } + + public function flush() + { + if ($this->bufferSize === 0) { + return; + } + + $this->handler->handleBatch($this->buffer); + $this->clear(); + } + + public function __destruct() + { + // suppress the parent behavior since we already have register_shutdown_function() + // to call close(), and the reference contained there will prevent this from being + // GC'd until the end of the request + } + + /** + * {@inheritdoc} + */ + public function close() + { + $this->flush(); + } + + /** + * Clears the buffer without flushing any messages down to the wrapped handler. + */ + public function clear() + { + $this->bufferSize = 0; + $this->buffer = array(); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/ChromePHPHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/ChromePHPHandler.php new file mode 100644 index 0000000..b00fa84 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/ChromePHPHandler.php @@ -0,0 +1,211 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Formatter\ChromePHPFormatter; +use Monolog\Logger; + +/** + * Handler sending logs to the ChromePHP extension (http://www.chromephp.com/) + * + * This also works out of the box with Firefox 43+ + * + * @author Christophe Coevoet + */ +class ChromePHPHandler extends AbstractProcessingHandler +{ + /** + * Version of the extension + */ + const VERSION = '4.0'; + + /** + * Header name + */ + const HEADER_NAME = 'X-ChromeLogger-Data'; + + /** + * Regular expression to detect supported browsers (matches any Chrome, or Firefox 43+) + */ + const USER_AGENT_REGEX = '{\b(?:Chrome/\d+(?:\.\d+)*|Firefox/(?:4[3-9]|[5-9]\d|\d{3,})(?:\.\d)*)\b}'; + + protected static $initialized = false; + + /** + * Tracks whether we sent too much data + * + * Chrome limits the headers to 256KB, so when we sent 240KB we stop sending + * + * @var Boolean + */ + protected static $overflowed = false; + + protected static $json = array( + 'version' => self::VERSION, + 'columns' => array('label', 'log', 'backtrace', 'type'), + 'rows' => array(), + ); + + protected static $sendHeaders = true; + + /** + * @param int $level The minimum logging level at which this handler will be triggered + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct($level = Logger::DEBUG, $bubble = true) + { + parent::__construct($level, $bubble); + if (!function_exists('json_encode')) { + throw new \RuntimeException('PHP\'s json extension is required to use Monolog\'s ChromePHPHandler'); + } + } + + /** + * {@inheritdoc} + */ + public function handleBatch(array $records) + { + $messages = array(); + + foreach ($records as $record) { + if ($record['level'] < $this->level) { + continue; + } + $messages[] = $this->processRecord($record); + } + + if (!empty($messages)) { + $messages = $this->getFormatter()->formatBatch($messages); + self::$json['rows'] = array_merge(self::$json['rows'], $messages); + $this->send(); + } + } + + /** + * {@inheritDoc} + */ + protected function getDefaultFormatter() + { + return new ChromePHPFormatter(); + } + + /** + * Creates & sends header for a record + * + * @see sendHeader() + * @see send() + * @param array $record + */ + protected function write(array $record) + { + self::$json['rows'][] = $record['formatted']; + + $this->send(); + } + + /** + * Sends the log header + * + * @see sendHeader() + */ + protected function send() + { + if (self::$overflowed || !self::$sendHeaders) { + return; + } + + if (!self::$initialized) { + self::$initialized = true; + + self::$sendHeaders = $this->headersAccepted(); + if (!self::$sendHeaders) { + return; + } + + self::$json['request_uri'] = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : ''; + } + + $json = @json_encode(self::$json); + $data = base64_encode(utf8_encode($json)); + if (strlen($data) > 240 * 1024) { + self::$overflowed = true; + + $record = array( + 'message' => 'Incomplete logs, chrome header size limit reached', + 'context' => array(), + 'level' => Logger::WARNING, + 'level_name' => Logger::getLevelName(Logger::WARNING), + 'channel' => 'monolog', + 'datetime' => new \DateTime(), + 'extra' => array(), + ); + self::$json['rows'][count(self::$json['rows']) - 1] = $this->getFormatter()->format($record); + $json = @json_encode(self::$json); + $data = base64_encode(utf8_encode($json)); + } + + if (trim($data) !== '') { + $this->sendHeader(self::HEADER_NAME, $data); + } + } + + /** + * Send header string to the client + * + * @param string $header + * @param string $content + */ + protected function sendHeader($header, $content) + { + if (!headers_sent() && self::$sendHeaders) { + header(sprintf('%s: %s', $header, $content)); + } + } + + /** + * Verifies if the headers are accepted by the current user agent + * + * @return Boolean + */ + protected function headersAccepted() + { + if (empty($_SERVER['HTTP_USER_AGENT'])) { + return false; + } + + return preg_match(self::USER_AGENT_REGEX, $_SERVER['HTTP_USER_AGENT']); + } + + /** + * BC getter for the sendHeaders property that has been made static + */ + public function __get($property) + { + if ('sendHeaders' !== $property) { + throw new \InvalidArgumentException('Undefined property '.$property); + } + + return static::$sendHeaders; + } + + /** + * BC setter for the sendHeaders property that has been made static + */ + public function __set($property, $value) + { + if ('sendHeaders' !== $property) { + throw new \InvalidArgumentException('Undefined property '.$property); + } + + static::$sendHeaders = $value; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/CouchDBHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/CouchDBHandler.php new file mode 100644 index 0000000..cc98697 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/CouchDBHandler.php @@ -0,0 +1,72 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Formatter\JsonFormatter; +use Monolog\Logger; + +/** + * CouchDB handler + * + * @author Markus Bachmann + */ +class CouchDBHandler extends AbstractProcessingHandler +{ + private $options; + + public function __construct(array $options = array(), $level = Logger::DEBUG, $bubble = true) + { + $this->options = array_merge(array( + 'host' => 'localhost', + 'port' => 5984, + 'dbname' => 'logger', + 'username' => null, + 'password' => null, + ), $options); + + parent::__construct($level, $bubble); + } + + /** + * {@inheritDoc} + */ + protected function write(array $record) + { + $basicAuth = null; + if ($this->options['username']) { + $basicAuth = sprintf('%s:%s@', $this->options['username'], $this->options['password']); + } + + $url = 'http://'.$basicAuth.$this->options['host'].':'.$this->options['port'].'/'.$this->options['dbname']; + $context = stream_context_create(array( + 'http' => array( + 'method' => 'POST', + 'content' => $record['formatted'], + 'ignore_errors' => true, + 'max_redirects' => 0, + 'header' => 'Content-type: application/json', + ), + )); + + if (false === @file_get_contents($url, null, $context)) { + throw new \RuntimeException(sprintf('Could not connect to %s', $url)); + } + } + + /** + * {@inheritDoc} + */ + protected function getDefaultFormatter() + { + return new JsonFormatter(JsonFormatter::BATCH_MODE_JSON, false); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/CubeHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/CubeHandler.php new file mode 100644 index 0000000..96b3ca0 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/CubeHandler.php @@ -0,0 +1,151 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; + +/** + * Logs to Cube. + * + * @link http://square.github.com/cube/ + * @author Wan Chen + */ +class CubeHandler extends AbstractProcessingHandler +{ + private $udpConnection; + private $httpConnection; + private $scheme; + private $host; + private $port; + private $acceptedSchemes = array('http', 'udp'); + + /** + * Create a Cube handler + * + * @throws \UnexpectedValueException when given url is not a valid url. + * A valid url must consist of three parts : protocol://host:port + * Only valid protocols used by Cube are http and udp + */ + public function __construct($url, $level = Logger::DEBUG, $bubble = true) + { + $urlInfo = parse_url($url); + + if (!isset($urlInfo['scheme'], $urlInfo['host'], $urlInfo['port'])) { + throw new \UnexpectedValueException('URL "'.$url.'" is not valid'); + } + + if (!in_array($urlInfo['scheme'], $this->acceptedSchemes)) { + throw new \UnexpectedValueException( + 'Invalid protocol (' . $urlInfo['scheme'] . ').' + . ' Valid options are ' . implode(', ', $this->acceptedSchemes)); + } + + $this->scheme = $urlInfo['scheme']; + $this->host = $urlInfo['host']; + $this->port = $urlInfo['port']; + + parent::__construct($level, $bubble); + } + + /** + * Establish a connection to an UDP socket + * + * @throws \LogicException when unable to connect to the socket + * @throws MissingExtensionException when there is no socket extension + */ + protected function connectUdp() + { + if (!extension_loaded('sockets')) { + throw new MissingExtensionException('The sockets extension is required to use udp URLs with the CubeHandler'); + } + + $this->udpConnection = socket_create(AF_INET, SOCK_DGRAM, 0); + if (!$this->udpConnection) { + throw new \LogicException('Unable to create a socket'); + } + + if (!socket_connect($this->udpConnection, $this->host, $this->port)) { + throw new \LogicException('Unable to connect to the socket at ' . $this->host . ':' . $this->port); + } + } + + /** + * Establish a connection to a http server + * @throws \LogicException when no curl extension + */ + protected function connectHttp() + { + if (!extension_loaded('curl')) { + throw new \LogicException('The curl extension is needed to use http URLs with the CubeHandler'); + } + + $this->httpConnection = curl_init('http://'.$this->host.':'.$this->port.'/1.0/event/put'); + + if (!$this->httpConnection) { + throw new \LogicException('Unable to connect to ' . $this->host . ':' . $this->port); + } + + curl_setopt($this->httpConnection, CURLOPT_CUSTOMREQUEST, "POST"); + curl_setopt($this->httpConnection, CURLOPT_RETURNTRANSFER, true); + } + + /** + * {@inheritdoc} + */ + protected function write(array $record) + { + $date = $record['datetime']; + + $data = array('time' => $date->format('Y-m-d\TH:i:s.uO')); + unset($record['datetime']); + + if (isset($record['context']['type'])) { + $data['type'] = $record['context']['type']; + unset($record['context']['type']); + } else { + $data['type'] = $record['channel']; + } + + $data['data'] = $record['context']; + $data['data']['level'] = $record['level']; + + if ($this->scheme === 'http') { + $this->writeHttp(json_encode($data)); + } else { + $this->writeUdp(json_encode($data)); + } + } + + private function writeUdp($data) + { + if (!$this->udpConnection) { + $this->connectUdp(); + } + + socket_send($this->udpConnection, $data, strlen($data), 0); + } + + private function writeHttp($data) + { + if (!$this->httpConnection) { + $this->connectHttp(); + } + + curl_setopt($this->httpConnection, CURLOPT_POSTFIELDS, '['.$data.']'); + curl_setopt($this->httpConnection, CURLOPT_HTTPHEADER, array( + 'Content-Type: application/json', + 'Content-Length: ' . strlen('['.$data.']'), + )); + + Curl\Util::execute($this->httpConnection, 5, false); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/Curl/Util.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/Curl/Util.php new file mode 100644 index 0000000..48d30b3 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/Curl/Util.php @@ -0,0 +1,57 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler\Curl; + +class Util +{ + private static $retriableErrorCodes = array( + CURLE_COULDNT_RESOLVE_HOST, + CURLE_COULDNT_CONNECT, + CURLE_HTTP_NOT_FOUND, + CURLE_READ_ERROR, + CURLE_OPERATION_TIMEOUTED, + CURLE_HTTP_POST_ERROR, + CURLE_SSL_CONNECT_ERROR, + ); + + /** + * Executes a CURL request with optional retries and exception on failure + * + * @param resource $ch curl handler + * @throws \RuntimeException + */ + public static function execute($ch, $retries = 5, $closeAfterDone = true) + { + while ($retries--) { + if (curl_exec($ch) === false) { + $curlErrno = curl_errno($ch); + + if (false === in_array($curlErrno, self::$retriableErrorCodes, true) || !$retries) { + $curlError = curl_error($ch); + + if ($closeAfterDone) { + curl_close($ch); + } + + throw new \RuntimeException(sprintf('Curl error (code %s): %s', $curlErrno, $curlError)); + } + + continue; + } + + if ($closeAfterDone) { + curl_close($ch); + } + break; + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/DeduplicationHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/DeduplicationHandler.php new file mode 100644 index 0000000..7778c22 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/DeduplicationHandler.php @@ -0,0 +1,169 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; + +/** + * Simple handler wrapper that deduplicates log records across multiple requests + * + * It also includes the BufferHandler functionality and will buffer + * all messages until the end of the request or flush() is called. + * + * This works by storing all log records' messages above $deduplicationLevel + * to the file specified by $deduplicationStore. When further logs come in at the end of the + * request (or when flush() is called), all those above $deduplicationLevel are checked + * against the existing stored logs. If they match and the timestamps in the stored log is + * not older than $time seconds, the new log record is discarded. If no log record is new, the + * whole data set is discarded. + * + * This is mainly useful in combination with Mail handlers or things like Slack or HipChat handlers + * that send messages to people, to avoid spamming with the same message over and over in case of + * a major component failure like a database server being down which makes all requests fail in the + * same way. + * + * @author Jordi Boggiano + */ +class DeduplicationHandler extends BufferHandler +{ + /** + * @var string + */ + protected $deduplicationStore; + + /** + * @var int + */ + protected $deduplicationLevel; + + /** + * @var int + */ + protected $time; + + /** + * @var bool + */ + private $gc = false; + + /** + * @param HandlerInterface $handler Handler. + * @param string $deduplicationStore The file/path where the deduplication log should be kept + * @param int $deduplicationLevel The minimum logging level for log records to be looked at for deduplication purposes + * @param int $time The period (in seconds) during which duplicate entries should be suppressed after a given log is sent through + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct(HandlerInterface $handler, $deduplicationStore = null, $deduplicationLevel = Logger::ERROR, $time = 60, $bubble = true) + { + parent::__construct($handler, 0, Logger::DEBUG, $bubble, false); + + $this->deduplicationStore = $deduplicationStore === null ? sys_get_temp_dir() . '/monolog-dedup-' . substr(md5(__FILE__), 0, 20) .'.log' : $deduplicationStore; + $this->deduplicationLevel = Logger::toMonologLevel($deduplicationLevel); + $this->time = $time; + } + + public function flush() + { + if ($this->bufferSize === 0) { + return; + } + + $passthru = null; + + foreach ($this->buffer as $record) { + if ($record['level'] >= $this->deduplicationLevel) { + + $passthru = $passthru || !$this->isDuplicate($record); + if ($passthru) { + $this->appendRecord($record); + } + } + } + + // default of null is valid as well as if no record matches duplicationLevel we just pass through + if ($passthru === true || $passthru === null) { + $this->handler->handleBatch($this->buffer); + } + + $this->clear(); + + if ($this->gc) { + $this->collectLogs(); + } + } + + private function isDuplicate(array $record) + { + if (!file_exists($this->deduplicationStore)) { + return false; + } + + $store = file($this->deduplicationStore, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); + if (!is_array($store)) { + return false; + } + + $yesterday = time() - 86400; + $timestampValidity = $record['datetime']->getTimestamp() - $this->time; + $expectedMessage = preg_replace('{[\r\n].*}', '', $record['message']); + + for ($i = count($store) - 1; $i >= 0; $i--) { + list($timestamp, $level, $message) = explode(':', $store[$i], 3); + + if ($level === $record['level_name'] && $message === $expectedMessage && $timestamp > $timestampValidity) { + return true; + } + + if ($timestamp < $yesterday) { + $this->gc = true; + } + } + + return false; + } + + private function collectLogs() + { + if (!file_exists($this->deduplicationStore)) { + return false; + } + + $handle = fopen($this->deduplicationStore, 'rw+'); + flock($handle, LOCK_EX); + $validLogs = array(); + + $timestampValidity = time() - $this->time; + + while (!feof($handle)) { + $log = fgets($handle); + if (substr($log, 0, 10) >= $timestampValidity) { + $validLogs[] = $log; + } + } + + ftruncate($handle, 0); + rewind($handle); + foreach ($validLogs as $log) { + fwrite($handle, $log); + } + + flock($handle, LOCK_UN); + fclose($handle); + + $this->gc = false; + } + + private function appendRecord(array $record) + { + file_put_contents($this->deduplicationStore, $record['datetime']->getTimestamp() . ':' . $record['level_name'] . ':' . preg_replace('{[\r\n].*}', '', $record['message']) . "\n", FILE_APPEND); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/DoctrineCouchDBHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/DoctrineCouchDBHandler.php new file mode 100644 index 0000000..b91ffec --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/DoctrineCouchDBHandler.php @@ -0,0 +1,45 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; +use Monolog\Formatter\NormalizerFormatter; +use Doctrine\CouchDB\CouchDBClient; + +/** + * CouchDB handler for Doctrine CouchDB ODM + * + * @author Markus Bachmann + */ +class DoctrineCouchDBHandler extends AbstractProcessingHandler +{ + private $client; + + public function __construct(CouchDBClient $client, $level = Logger::DEBUG, $bubble = true) + { + $this->client = $client; + parent::__construct($level, $bubble); + } + + /** + * {@inheritDoc} + */ + protected function write(array $record) + { + $this->client->postDocument($record['formatted']); + } + + protected function getDefaultFormatter() + { + return new NormalizerFormatter; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/DynamoDbHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/DynamoDbHandler.php new file mode 100644 index 0000000..7b20830 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/DynamoDbHandler.php @@ -0,0 +1,89 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Aws\Common\Aws; +use Aws\DynamoDb\DynamoDbClient; +use Monolog\Formatter\ScalarFormatter; +use Monolog\Logger; + +/** + * Amazon DynamoDB handler (http://aws.amazon.com/dynamodb/) + * + * @link https://github.com/aws/aws-sdk-php/ + * @author Andrew Lawson + */ +class DynamoDbHandler extends AbstractProcessingHandler +{ + const DATE_FORMAT = 'Y-m-d\TH:i:s.uO'; + + /** + * @var DynamoDbClient + */ + protected $client; + + /** + * @var string + */ + protected $table; + + /** + * @param DynamoDbClient $client + * @param string $table + * @param int $level + * @param bool $bubble + */ + public function __construct(DynamoDbClient $client, $table, $level = Logger::DEBUG, $bubble = true) + { + if (!defined('Aws\Common\Aws::VERSION') || version_compare('3.0', Aws::VERSION, '<=')) { + throw new \RuntimeException('The DynamoDbHandler is only known to work with the AWS SDK 2.x releases'); + } + + $this->client = $client; + $this->table = $table; + + parent::__construct($level, $bubble); + } + + /** + * {@inheritdoc} + */ + protected function write(array $record) + { + $filtered = $this->filterEmptyFields($record['formatted']); + $formatted = $this->client->formatAttributes($filtered); + + $this->client->putItem(array( + 'TableName' => $this->table, + 'Item' => $formatted, + )); + } + + /** + * @param array $record + * @return array + */ + protected function filterEmptyFields(array $record) + { + return array_filter($record, function ($value) { + return !empty($value) || false === $value || 0 === $value; + }); + } + + /** + * {@inheritdoc} + */ + protected function getDefaultFormatter() + { + return new ScalarFormatter(self::DATE_FORMAT); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/ElasticSearchHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/ElasticSearchHandler.php new file mode 100644 index 0000000..8196740 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/ElasticSearchHandler.php @@ -0,0 +1,128 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Formatter\FormatterInterface; +use Monolog\Formatter\ElasticaFormatter; +use Monolog\Logger; +use Elastica\Client; +use Elastica\Exception\ExceptionInterface; + +/** + * Elastic Search handler + * + * Usage example: + * + * $client = new \Elastica\Client(); + * $options = array( + * 'index' => 'elastic_index_name', + * 'type' => 'elastic_doc_type', + * ); + * $handler = new ElasticSearchHandler($client, $options); + * $log = new Logger('application'); + * $log->pushHandler($handler); + * + * @author Jelle Vink + */ +class ElasticSearchHandler extends AbstractProcessingHandler +{ + /** + * @var Client + */ + protected $client; + + /** + * @var array Handler config options + */ + protected $options = array(); + + /** + * @param Client $client Elastica Client object + * @param array $options Handler configuration + * @param int $level The minimum logging level at which this handler will be triggered + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct(Client $client, array $options = array(), $level = Logger::DEBUG, $bubble = true) + { + parent::__construct($level, $bubble); + $this->client = $client; + $this->options = array_merge( + array( + 'index' => 'monolog', // Elastic index name + 'type' => 'record', // Elastic document type + 'ignore_error' => false, // Suppress Elastica exceptions + ), + $options + ); + } + + /** + * {@inheritDoc} + */ + protected function write(array $record) + { + $this->bulkSend(array($record['formatted'])); + } + + /** + * {@inheritdoc} + */ + public function setFormatter(FormatterInterface $formatter) + { + if ($formatter instanceof ElasticaFormatter) { + return parent::setFormatter($formatter); + } + throw new \InvalidArgumentException('ElasticSearchHandler is only compatible with ElasticaFormatter'); + } + + /** + * Getter options + * @return array + */ + public function getOptions() + { + return $this->options; + } + + /** + * {@inheritDoc} + */ + protected function getDefaultFormatter() + { + return new ElasticaFormatter($this->options['index'], $this->options['type']); + } + + /** + * {@inheritdoc} + */ + public function handleBatch(array $records) + { + $documents = $this->getFormatter()->formatBatch($records); + $this->bulkSend($documents); + } + + /** + * Use Elasticsearch bulk API to send list of documents + * @param array $documents + * @throws \RuntimeException + */ + protected function bulkSend(array $documents) + { + try { + $this->client->addDocuments($documents); + } catch (ExceptionInterface $e) { + if (!$this->options['ignore_error']) { + throw new \RuntimeException("Error sending messages to Elasticsearch", 0, $e); + } + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/ErrorLogHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/ErrorLogHandler.php new file mode 100644 index 0000000..1447a58 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/ErrorLogHandler.php @@ -0,0 +1,82 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Formatter\LineFormatter; +use Monolog\Logger; + +/** + * Stores to PHP error_log() handler. + * + * @author Elan Ruusamäe + */ +class ErrorLogHandler extends AbstractProcessingHandler +{ + const OPERATING_SYSTEM = 0; + const SAPI = 4; + + protected $messageType; + protected $expandNewlines; + + /** + * @param int $messageType Says where the error should go. + * @param int $level The minimum logging level at which this handler will be triggered + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + * @param Boolean $expandNewlines If set to true, newlines in the message will be expanded to be take multiple log entries + */ + public function __construct($messageType = self::OPERATING_SYSTEM, $level = Logger::DEBUG, $bubble = true, $expandNewlines = false) + { + parent::__construct($level, $bubble); + + if (false === in_array($messageType, self::getAvailableTypes())) { + $message = sprintf('The given message type "%s" is not supported', print_r($messageType, true)); + throw new \InvalidArgumentException($message); + } + + $this->messageType = $messageType; + $this->expandNewlines = $expandNewlines; + } + + /** + * @return array With all available types + */ + public static function getAvailableTypes() + { + return array( + self::OPERATING_SYSTEM, + self::SAPI, + ); + } + + /** + * {@inheritDoc} + */ + protected function getDefaultFormatter() + { + return new LineFormatter('[%datetime%] %channel%.%level_name%: %message% %context% %extra%'); + } + + /** + * {@inheritdoc} + */ + protected function write(array $record) + { + if ($this->expandNewlines) { + $lines = preg_split('{[\r\n]+}', (string) $record['formatted']); + foreach ($lines as $line) { + error_log($line, $this->messageType); + } + } else { + error_log((string) $record['formatted'], $this->messageType); + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/FilterHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/FilterHandler.php new file mode 100644 index 0000000..2a0f7fd --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/FilterHandler.php @@ -0,0 +1,140 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; + +/** + * Simple handler wrapper that filters records based on a list of levels + * + * It can be configured with an exact list of levels to allow, or a min/max level. + * + * @author Hennadiy Verkh + * @author Jordi Boggiano + */ +class FilterHandler extends AbstractHandler +{ + /** + * Handler or factory callable($record, $this) + * + * @var callable|\Monolog\Handler\HandlerInterface + */ + protected $handler; + + /** + * Minimum level for logs that are passed to handler + * + * @var int[] + */ + protected $acceptedLevels; + + /** + * Whether the messages that are handled can bubble up the stack or not + * + * @var Boolean + */ + protected $bubble; + + /** + * @param callable|HandlerInterface $handler Handler or factory callable($record, $this). + * @param int|array $minLevelOrList A list of levels to accept or a minimum level if maxLevel is provided + * @param int $maxLevel Maximum level to accept, only used if $minLevelOrList is not an array + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct($handler, $minLevelOrList = Logger::DEBUG, $maxLevel = Logger::EMERGENCY, $bubble = true) + { + $this->handler = $handler; + $this->bubble = $bubble; + $this->setAcceptedLevels($minLevelOrList, $maxLevel); + + if (!$this->handler instanceof HandlerInterface && !is_callable($this->handler)) { + throw new \RuntimeException("The given handler (".json_encode($this->handler).") is not a callable nor a Monolog\Handler\HandlerInterface object"); + } + } + + /** + * @return array + */ + public function getAcceptedLevels() + { + return array_flip($this->acceptedLevels); + } + + /** + * @param int|string|array $minLevelOrList A list of levels to accept or a minimum level or level name if maxLevel is provided + * @param int|string $maxLevel Maximum level or level name to accept, only used if $minLevelOrList is not an array + */ + public function setAcceptedLevels($minLevelOrList = Logger::DEBUG, $maxLevel = Logger::EMERGENCY) + { + if (is_array($minLevelOrList)) { + $acceptedLevels = array_map('Monolog\Logger::toMonologLevel', $minLevelOrList); + } else { + $minLevelOrList = Logger::toMonologLevel($minLevelOrList); + $maxLevel = Logger::toMonologLevel($maxLevel); + $acceptedLevels = array_values(array_filter(Logger::getLevels(), function ($level) use ($minLevelOrList, $maxLevel) { + return $level >= $minLevelOrList && $level <= $maxLevel; + })); + } + $this->acceptedLevels = array_flip($acceptedLevels); + } + + /** + * {@inheritdoc} + */ + public function isHandling(array $record) + { + return isset($this->acceptedLevels[$record['level']]); + } + + /** + * {@inheritdoc} + */ + public function handle(array $record) + { + if (!$this->isHandling($record)) { + return false; + } + + // The same logic as in FingersCrossedHandler + if (!$this->handler instanceof HandlerInterface) { + $this->handler = call_user_func($this->handler, $record, $this); + if (!$this->handler instanceof HandlerInterface) { + throw new \RuntimeException("The factory callable should return a HandlerInterface"); + } + } + + if ($this->processors) { + foreach ($this->processors as $processor) { + $record = call_user_func($processor, $record); + } + } + + $this->handler->handle($record); + + return false === $this->bubble; + } + + /** + * {@inheritdoc} + */ + public function handleBatch(array $records) + { + $filtered = array(); + foreach ($records as $record) { + if ($this->isHandling($record)) { + $filtered[] = $record; + } + } + + $this->handler->handleBatch($filtered); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossed/ActivationStrategyInterface.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossed/ActivationStrategyInterface.php new file mode 100644 index 0000000..c3e42ef --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossed/ActivationStrategyInterface.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler\FingersCrossed; + +/** + * Interface for activation strategies for the FingersCrossedHandler. + * + * @author Johannes M. Schmitt + */ +interface ActivationStrategyInterface +{ + /** + * Returns whether the given record activates the handler. + * + * @param array $record + * @return Boolean + */ + public function isHandlerActivated(array $record); +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossed/ChannelLevelActivationStrategy.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossed/ChannelLevelActivationStrategy.php new file mode 100644 index 0000000..2a2a64d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossed/ChannelLevelActivationStrategy.php @@ -0,0 +1,59 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler\FingersCrossed; + +use Monolog\Logger; + +/** + * Channel and Error level based monolog activation strategy. Allows to trigger activation + * based on level per channel. e.g. trigger activation on level 'ERROR' by default, except + * for records of the 'sql' channel; those should trigger activation on level 'WARN'. + * + * Example: + * + * + * $activationStrategy = new ChannelLevelActivationStrategy( + * Logger::CRITICAL, + * array( + * 'request' => Logger::ALERT, + * 'sensitive' => Logger::ERROR, + * ) + * ); + * $handler = new FingersCrossedHandler(new StreamHandler('php://stderr'), $activationStrategy); + * + * + * @author Mike Meessen + */ +class ChannelLevelActivationStrategy implements ActivationStrategyInterface +{ + private $defaultActionLevel; + private $channelToActionLevel; + + /** + * @param int $defaultActionLevel The default action level to be used if the record's category doesn't match any + * @param array $channelToActionLevel An array that maps channel names to action levels. + */ + public function __construct($defaultActionLevel, $channelToActionLevel = array()) + { + $this->defaultActionLevel = Logger::toMonologLevel($defaultActionLevel); + $this->channelToActionLevel = array_map('Monolog\Logger::toMonologLevel', $channelToActionLevel); + } + + public function isHandlerActivated(array $record) + { + if (isset($this->channelToActionLevel[$record['channel']])) { + return $record['level'] >= $this->channelToActionLevel[$record['channel']]; + } + + return $record['level'] >= $this->defaultActionLevel; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossed/ErrorLevelActivationStrategy.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossed/ErrorLevelActivationStrategy.php new file mode 100644 index 0000000..6e63085 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossed/ErrorLevelActivationStrategy.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler\FingersCrossed; + +use Monolog\Logger; + +/** + * Error level based activation strategy. + * + * @author Johannes M. Schmitt + */ +class ErrorLevelActivationStrategy implements ActivationStrategyInterface +{ + private $actionLevel; + + public function __construct($actionLevel) + { + $this->actionLevel = Logger::toMonologLevel($actionLevel); + } + + public function isHandlerActivated(array $record) + { + return $record['level'] >= $this->actionLevel; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossedHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossedHandler.php new file mode 100644 index 0000000..d1dcaac --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossedHandler.php @@ -0,0 +1,163 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy; +use Monolog\Handler\FingersCrossed\ActivationStrategyInterface; +use Monolog\Logger; + +/** + * Buffers all records until a certain level is reached + * + * The advantage of this approach is that you don't get any clutter in your log files. + * Only requests which actually trigger an error (or whatever your actionLevel is) will be + * in the logs, but they will contain all records, not only those above the level threshold. + * + * You can find the various activation strategies in the + * Monolog\Handler\FingersCrossed\ namespace. + * + * @author Jordi Boggiano + */ +class FingersCrossedHandler extends AbstractHandler +{ + protected $handler; + protected $activationStrategy; + protected $buffering = true; + protected $bufferSize; + protected $buffer = array(); + protected $stopBuffering; + protected $passthruLevel; + + /** + * @param callable|HandlerInterface $handler Handler or factory callable($record, $fingersCrossedHandler). + * @param int|ActivationStrategyInterface $activationStrategy Strategy which determines when this handler takes action + * @param int $bufferSize How many entries should be buffered at most, beyond that the oldest items are removed from the buffer. + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + * @param Boolean $stopBuffering Whether the handler should stop buffering after being triggered (default true) + * @param int $passthruLevel Minimum level to always flush to handler on close, even if strategy not triggered + */ + public function __construct($handler, $activationStrategy = null, $bufferSize = 0, $bubble = true, $stopBuffering = true, $passthruLevel = null) + { + if (null === $activationStrategy) { + $activationStrategy = new ErrorLevelActivationStrategy(Logger::WARNING); + } + + // convert simple int activationStrategy to an object + if (!$activationStrategy instanceof ActivationStrategyInterface) { + $activationStrategy = new ErrorLevelActivationStrategy($activationStrategy); + } + + $this->handler = $handler; + $this->activationStrategy = $activationStrategy; + $this->bufferSize = $bufferSize; + $this->bubble = $bubble; + $this->stopBuffering = $stopBuffering; + + if ($passthruLevel !== null) { + $this->passthruLevel = Logger::toMonologLevel($passthruLevel); + } + + if (!$this->handler instanceof HandlerInterface && !is_callable($this->handler)) { + throw new \RuntimeException("The given handler (".json_encode($this->handler).") is not a callable nor a Monolog\Handler\HandlerInterface object"); + } + } + + /** + * {@inheritdoc} + */ + public function isHandling(array $record) + { + return true; + } + + /** + * Manually activate this logger regardless of the activation strategy + */ + public function activate() + { + if ($this->stopBuffering) { + $this->buffering = false; + } + if (!$this->handler instanceof HandlerInterface) { + $record = end($this->buffer) ?: null; + + $this->handler = call_user_func($this->handler, $record, $this); + if (!$this->handler instanceof HandlerInterface) { + throw new \RuntimeException("The factory callable should return a HandlerInterface"); + } + } + $this->handler->handleBatch($this->buffer); + $this->buffer = array(); + } + + /** + * {@inheritdoc} + */ + public function handle(array $record) + { + if ($this->processors) { + foreach ($this->processors as $processor) { + $record = call_user_func($processor, $record); + } + } + + if ($this->buffering) { + $this->buffer[] = $record; + if ($this->bufferSize > 0 && count($this->buffer) > $this->bufferSize) { + array_shift($this->buffer); + } + if ($this->activationStrategy->isHandlerActivated($record)) { + $this->activate(); + } + } else { + $this->handler->handle($record); + } + + return false === $this->bubble; + } + + /** + * {@inheritdoc} + */ + public function close() + { + if (null !== $this->passthruLevel) { + $level = $this->passthruLevel; + $this->buffer = array_filter($this->buffer, function ($record) use ($level) { + return $record['level'] >= $level; + }); + if (count($this->buffer) > 0) { + $this->handler->handleBatch($this->buffer); + $this->buffer = array(); + } + } + } + + /** + * Resets the state of the handler. Stops forwarding records to the wrapped handler. + */ + public function reset() + { + $this->buffering = true; + } + + /** + * Clears the buffer without flushing any messages down to the wrapped handler. + * + * It also resets the handler to its initial buffering state. + */ + public function clear() + { + $this->buffer = array(); + $this->reset(); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/FirePHPHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/FirePHPHandler.php new file mode 100644 index 0000000..fee4795 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/FirePHPHandler.php @@ -0,0 +1,195 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Formatter\WildfireFormatter; + +/** + * Simple FirePHP Handler (http://www.firephp.org/), which uses the Wildfire protocol. + * + * @author Eric Clemmons (@ericclemmons) + */ +class FirePHPHandler extends AbstractProcessingHandler +{ + /** + * WildFire JSON header message format + */ + const PROTOCOL_URI = 'http://meta.wildfirehq.org/Protocol/JsonStream/0.2'; + + /** + * FirePHP structure for parsing messages & their presentation + */ + const STRUCTURE_URI = 'http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1'; + + /** + * Must reference a "known" plugin, otherwise headers won't display in FirePHP + */ + const PLUGIN_URI = 'http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/0.3'; + + /** + * Header prefix for Wildfire to recognize & parse headers + */ + const HEADER_PREFIX = 'X-Wf'; + + /** + * Whether or not Wildfire vendor-specific headers have been generated & sent yet + */ + protected static $initialized = false; + + /** + * Shared static message index between potentially multiple handlers + * @var int + */ + protected static $messageIndex = 1; + + protected static $sendHeaders = true; + + /** + * Base header creation function used by init headers & record headers + * + * @param array $meta Wildfire Plugin, Protocol & Structure Indexes + * @param string $message Log message + * @return array Complete header string ready for the client as key and message as value + */ + protected function createHeader(array $meta, $message) + { + $header = sprintf('%s-%s', self::HEADER_PREFIX, join('-', $meta)); + + return array($header => $message); + } + + /** + * Creates message header from record + * + * @see createHeader() + * @param array $record + * @return string + */ + protected function createRecordHeader(array $record) + { + // Wildfire is extensible to support multiple protocols & plugins in a single request, + // but we're not taking advantage of that (yet), so we're using "1" for simplicity's sake. + return $this->createHeader( + array(1, 1, 1, self::$messageIndex++), + $record['formatted'] + ); + } + + /** + * {@inheritDoc} + */ + protected function getDefaultFormatter() + { + return new WildfireFormatter(); + } + + /** + * Wildfire initialization headers to enable message parsing + * + * @see createHeader() + * @see sendHeader() + * @return array + */ + protected function getInitHeaders() + { + // Initial payload consists of required headers for Wildfire + return array_merge( + $this->createHeader(array('Protocol', 1), self::PROTOCOL_URI), + $this->createHeader(array(1, 'Structure', 1), self::STRUCTURE_URI), + $this->createHeader(array(1, 'Plugin', 1), self::PLUGIN_URI) + ); + } + + /** + * Send header string to the client + * + * @param string $header + * @param string $content + */ + protected function sendHeader($header, $content) + { + if (!headers_sent() && self::$sendHeaders) { + header(sprintf('%s: %s', $header, $content)); + } + } + + /** + * Creates & sends header for a record, ensuring init headers have been sent prior + * + * @see sendHeader() + * @see sendInitHeaders() + * @param array $record + */ + protected function write(array $record) + { + if (!self::$sendHeaders) { + return; + } + + // WildFire-specific headers must be sent prior to any messages + if (!self::$initialized) { + self::$initialized = true; + + self::$sendHeaders = $this->headersAccepted(); + if (!self::$sendHeaders) { + return; + } + + foreach ($this->getInitHeaders() as $header => $content) { + $this->sendHeader($header, $content); + } + } + + $header = $this->createRecordHeader($record); + if (trim(current($header)) !== '') { + $this->sendHeader(key($header), current($header)); + } + } + + /** + * Verifies if the headers are accepted by the current user agent + * + * @return Boolean + */ + protected function headersAccepted() + { + if (!empty($_SERVER['HTTP_USER_AGENT']) && preg_match('{\bFirePHP/\d+\.\d+\b}', $_SERVER['HTTP_USER_AGENT'])) { + return true; + } + + return isset($_SERVER['HTTP_X_FIREPHP_VERSION']); + } + + /** + * BC getter for the sendHeaders property that has been made static + */ + public function __get($property) + { + if ('sendHeaders' !== $property) { + throw new \InvalidArgumentException('Undefined property '.$property); + } + + return static::$sendHeaders; + } + + /** + * BC setter for the sendHeaders property that has been made static + */ + public function __set($property, $value) + { + if ('sendHeaders' !== $property) { + throw new \InvalidArgumentException('Undefined property '.$property); + } + + static::$sendHeaders = $value; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/FleepHookHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/FleepHookHandler.php new file mode 100644 index 0000000..c43c013 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/FleepHookHandler.php @@ -0,0 +1,126 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Formatter\LineFormatter; +use Monolog\Logger; + +/** + * Sends logs to Fleep.io using Webhook integrations + * + * You'll need a Fleep.io account to use this handler. + * + * @see https://fleep.io/integrations/webhooks/ Fleep Webhooks Documentation + * @author Ando Roots + */ +class FleepHookHandler extends SocketHandler +{ + const FLEEP_HOST = 'fleep.io'; + + const FLEEP_HOOK_URI = '/hook/'; + + /** + * @var string Webhook token (specifies the conversation where logs are sent) + */ + protected $token; + + /** + * Construct a new Fleep.io Handler. + * + * For instructions on how to create a new web hook in your conversations + * see https://fleep.io/integrations/webhooks/ + * + * @param string $token Webhook token + * @param bool|int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + * @throws MissingExtensionException + */ + public function __construct($token, $level = Logger::DEBUG, $bubble = true) + { + if (!extension_loaded('openssl')) { + throw new MissingExtensionException('The OpenSSL PHP extension is required to use the FleepHookHandler'); + } + + $this->token = $token; + + $connectionString = 'ssl://' . self::FLEEP_HOST . ':443'; + parent::__construct($connectionString, $level, $bubble); + } + + /** + * Returns the default formatter to use with this handler + * + * Overloaded to remove empty context and extra arrays from the end of the log message. + * + * @return LineFormatter + */ + protected function getDefaultFormatter() + { + return new LineFormatter(null, null, true, true); + } + + /** + * Handles a log record + * + * @param array $record + */ + public function write(array $record) + { + parent::write($record); + $this->closeSocket(); + } + + /** + * {@inheritdoc} + * + * @param array $record + * @return string + */ + protected function generateDataStream($record) + { + $content = $this->buildContent($record); + + return $this->buildHeader($content) . $content; + } + + /** + * Builds the header of the API Call + * + * @param string $content + * @return string + */ + private function buildHeader($content) + { + $header = "POST " . self::FLEEP_HOOK_URI . $this->token . " HTTP/1.1\r\n"; + $header .= "Host: " . self::FLEEP_HOST . "\r\n"; + $header .= "Content-Type: application/x-www-form-urlencoded\r\n"; + $header .= "Content-Length: " . strlen($content) . "\r\n"; + $header .= "\r\n"; + + return $header; + } + + /** + * Builds the body of API call + * + * @param array $record + * @return string + */ + private function buildContent($record) + { + $dataArray = array( + 'message' => $record['formatted'], + ); + + return http_build_query($dataArray); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/FlowdockHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/FlowdockHandler.php new file mode 100644 index 0000000..dd9a361 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/FlowdockHandler.php @@ -0,0 +1,127 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; +use Monolog\Formatter\FlowdockFormatter; +use Monolog\Formatter\FormatterInterface; + +/** + * Sends notifications through the Flowdock push API + * + * This must be configured with a FlowdockFormatter instance via setFormatter() + * + * Notes: + * API token - Flowdock API token + * + * @author Dominik Liebler + * @see https://www.flowdock.com/api/push + */ +class FlowdockHandler extends SocketHandler +{ + /** + * @var string + */ + protected $apiToken; + + /** + * @param string $apiToken + * @param bool|int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + * + * @throws MissingExtensionException if OpenSSL is missing + */ + public function __construct($apiToken, $level = Logger::DEBUG, $bubble = true) + { + if (!extension_loaded('openssl')) { + throw new MissingExtensionException('The OpenSSL PHP extension is required to use the FlowdockHandler'); + } + + parent::__construct('ssl://api.flowdock.com:443', $level, $bubble); + $this->apiToken = $apiToken; + } + + /** + * {@inheritdoc} + */ + public function setFormatter(FormatterInterface $formatter) + { + if (!$formatter instanceof FlowdockFormatter) { + throw new \InvalidArgumentException('The FlowdockHandler requires an instance of Monolog\Formatter\FlowdockFormatter to function correctly'); + } + + return parent::setFormatter($formatter); + } + + /** + * Gets the default formatter. + * + * @return FormatterInterface + */ + protected function getDefaultFormatter() + { + throw new \InvalidArgumentException('The FlowdockHandler must be configured (via setFormatter) with an instance of Monolog\Formatter\FlowdockFormatter to function correctly'); + } + + /** + * {@inheritdoc} + * + * @param array $record + */ + protected function write(array $record) + { + parent::write($record); + + $this->closeSocket(); + } + + /** + * {@inheritdoc} + * + * @param array $record + * @return string + */ + protected function generateDataStream($record) + { + $content = $this->buildContent($record); + + return $this->buildHeader($content) . $content; + } + + /** + * Builds the body of API call + * + * @param array $record + * @return string + */ + private function buildContent($record) + { + return json_encode($record['formatted']['flowdock']); + } + + /** + * Builds the header of the API Call + * + * @param string $content + * @return string + */ + private function buildHeader($content) + { + $header = "POST /v1/messages/team_inbox/" . $this->apiToken . " HTTP/1.1\r\n"; + $header .= "Host: api.flowdock.com\r\n"; + $header .= "Content-Type: application/json\r\n"; + $header .= "Content-Length: " . strlen($content) . "\r\n"; + $header .= "\r\n"; + + return $header; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/GelfHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/GelfHandler.php new file mode 100644 index 0000000..d3847d8 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/GelfHandler.php @@ -0,0 +1,73 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Gelf\IMessagePublisher; +use Gelf\PublisherInterface; +use Gelf\Publisher; +use InvalidArgumentException; +use Monolog\Logger; +use Monolog\Formatter\GelfMessageFormatter; + +/** + * Handler to send messages to a Graylog2 (http://www.graylog2.org) server + * + * @author Matt Lehner + * @author Benjamin Zikarsky + */ +class GelfHandler extends AbstractProcessingHandler +{ + /** + * @var Publisher the publisher object that sends the message to the server + */ + protected $publisher; + + /** + * @param PublisherInterface|IMessagePublisher|Publisher $publisher a publisher object + * @param int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct($publisher, $level = Logger::DEBUG, $bubble = true) + { + parent::__construct($level, $bubble); + + if (!$publisher instanceof Publisher && !$publisher instanceof IMessagePublisher && !$publisher instanceof PublisherInterface) { + throw new InvalidArgumentException('Invalid publisher, expected a Gelf\Publisher, Gelf\IMessagePublisher or Gelf\PublisherInterface instance'); + } + + $this->publisher = $publisher; + } + + /** + * {@inheritdoc} + */ + public function close() + { + $this->publisher = null; + } + + /** + * {@inheritdoc} + */ + protected function write(array $record) + { + $this->publisher->publish($record['formatted']); + } + + /** + * {@inheritDoc} + */ + protected function getDefaultFormatter() + { + return new GelfMessageFormatter(); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/GroupHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/GroupHandler.php new file mode 100644 index 0000000..663f5a9 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/GroupHandler.php @@ -0,0 +1,104 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Formatter\FormatterInterface; + +/** + * Forwards records to multiple handlers + * + * @author Lenar Lõhmus + */ +class GroupHandler extends AbstractHandler +{ + protected $handlers; + + /** + * @param array $handlers Array of Handlers. + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct(array $handlers, $bubble = true) + { + foreach ($handlers as $handler) { + if (!$handler instanceof HandlerInterface) { + throw new \InvalidArgumentException('The first argument of the GroupHandler must be an array of HandlerInterface instances.'); + } + } + + $this->handlers = $handlers; + $this->bubble = $bubble; + } + + /** + * {@inheritdoc} + */ + public function isHandling(array $record) + { + foreach ($this->handlers as $handler) { + if ($handler->isHandling($record)) { + return true; + } + } + + return false; + } + + /** + * {@inheritdoc} + */ + public function handle(array $record) + { + if ($this->processors) { + foreach ($this->processors as $processor) { + $record = call_user_func($processor, $record); + } + } + + foreach ($this->handlers as $handler) { + $handler->handle($record); + } + + return false === $this->bubble; + } + + /** + * {@inheritdoc} + */ + public function handleBatch(array $records) + { + if ($this->processors) { + $processed = array(); + foreach ($records as $record) { + foreach ($this->processors as $processor) { + $processed[] = call_user_func($processor, $record); + } + } + $records = $processed; + } + + foreach ($this->handlers as $handler) { + $handler->handleBatch($records); + } + } + + /** + * {@inheritdoc} + */ + public function setFormatter(FormatterInterface $formatter) + { + foreach ($this->handlers as $handler) { + $handler->setFormatter($formatter); + } + + return $this; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/HandlerInterface.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/HandlerInterface.php new file mode 100644 index 0000000..d920c4b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/HandlerInterface.php @@ -0,0 +1,90 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Formatter\FormatterInterface; + +/** + * Interface that all Monolog Handlers must implement + * + * @author Jordi Boggiano + */ +interface HandlerInterface +{ + /** + * Checks whether the given record will be handled by this handler. + * + * This is mostly done for performance reasons, to avoid calling processors for nothing. + * + * Handlers should still check the record levels within handle(), returning false in isHandling() + * is no guarantee that handle() will not be called, and isHandling() might not be called + * for a given record. + * + * @param array $record Partial log record containing only a level key + * + * @return Boolean + */ + public function isHandling(array $record); + + /** + * Handles a record. + * + * All records may be passed to this method, and the handler should discard + * those that it does not want to handle. + * + * The return value of this function controls the bubbling process of the handler stack. + * Unless the bubbling is interrupted (by returning true), the Logger class will keep on + * calling further handlers in the stack with a given log record. + * + * @param array $record The record to handle + * @return Boolean true means that this handler handled the record, and that bubbling is not permitted. + * false means the record was either not processed or that this handler allows bubbling. + */ + public function handle(array $record); + + /** + * Handles a set of records at once. + * + * @param array $records The records to handle (an array of record arrays) + */ + public function handleBatch(array $records); + + /** + * Adds a processor in the stack. + * + * @param callable $callback + * @return self + */ + public function pushProcessor($callback); + + /** + * Removes the processor on top of the stack and returns it. + * + * @return callable + */ + public function popProcessor(); + + /** + * Sets the formatter. + * + * @param FormatterInterface $formatter + * @return self + */ + public function setFormatter(FormatterInterface $formatter); + + /** + * Gets the formatter. + * + * @return FormatterInterface + */ + public function getFormatter(); +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/HandlerWrapper.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/HandlerWrapper.php new file mode 100644 index 0000000..56bc270 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/HandlerWrapper.php @@ -0,0 +1,106 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Formatter\FormatterInterface; + +/** + * This simple wrapper class can be used to extend handlers functionality. + * + * Example: A filtering handle. Inherit from this class, override isHandling() like this + * + * public function isHandling(array $record) + * { + * if ($record meets certain conditions) { + * return false; + * } + * return $this->handler->isHandling($record); + * } + * + * @author Alexey Karapetov + */ +class HandlerWrapper implements HandlerInterface +{ + /** + * @var HandlerInterface + */ + protected $handler; + + /** + * HandlerWrapper constructor. + * @param HandlerInterface $handler + */ + public function __construct(HandlerInterface $handler) + { + $this->handler = $handler; + } + + /** + * {@inheritdoc} + */ + public function isHandling(array $record) + { + return $this->handler->isHandling($record); + } + + /** + * {@inheritdoc} + */ + public function handle(array $record) + { + return $this->handler->handle($record); + } + + /** + * {@inheritdoc} + */ + public function handleBatch(array $records) + { + return $this->handler->handleBatch($records); + } + + /** + * {@inheritdoc} + */ + public function pushProcessor($callback) + { + $this->handler->pushProcessor($callback); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function popProcessor() + { + return $this->handler->popProcessor(); + } + + /** + * {@inheritdoc} + */ + public function setFormatter(FormatterInterface $formatter) + { + $this->handler->setFormatter($formatter); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function getFormatter() + { + return $this->handler->getFormatter(); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/HipChatHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/HipChatHandler.php new file mode 100644 index 0000000..73049f3 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/HipChatHandler.php @@ -0,0 +1,350 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; + +/** + * Sends notifications through the hipchat api to a hipchat room + * + * Notes: + * API token - HipChat API token + * Room - HipChat Room Id or name, where messages are sent + * Name - Name used to send the message (from) + * notify - Should the message trigger a notification in the clients + * version - The API version to use (HipChatHandler::API_V1 | HipChatHandler::API_V2) + * + * @author Rafael Dohms + * @see https://www.hipchat.com/docs/api + */ +class HipChatHandler extends SocketHandler +{ + /** + * Use API version 1 + */ + const API_V1 = 'v1'; + + /** + * Use API version v2 + */ + const API_V2 = 'v2'; + + /** + * The maximum allowed length for the name used in the "from" field. + */ + const MAXIMUM_NAME_LENGTH = 15; + + /** + * The maximum allowed length for the message. + */ + const MAXIMUM_MESSAGE_LENGTH = 9500; + + /** + * @var string + */ + private $token; + + /** + * @var string + */ + private $room; + + /** + * @var string + */ + private $name; + + /** + * @var bool + */ + private $notify; + + /** + * @var string + */ + private $format; + + /** + * @var string + */ + private $host; + + /** + * @var string + */ + private $version; + + /** + * @param string $token HipChat API Token + * @param string $room The room that should be alerted of the message (Id or Name) + * @param string $name Name used in the "from" field. + * @param bool $notify Trigger a notification in clients or not + * @param int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + * @param bool $useSSL Whether to connect via SSL. + * @param string $format The format of the messages (default to text, can be set to html if you have html in the messages) + * @param string $host The HipChat server hostname. + * @param string $version The HipChat API version (default HipChatHandler::API_V1) + */ + public function __construct($token, $room, $name = 'Monolog', $notify = false, $level = Logger::CRITICAL, $bubble = true, $useSSL = true, $format = 'text', $host = 'api.hipchat.com', $version = self::API_V1) + { + if ($version == self::API_V1 && !$this->validateStringLength($name, static::MAXIMUM_NAME_LENGTH)) { + throw new \InvalidArgumentException('The supplied name is too long. HipChat\'s v1 API supports names up to 15 UTF-8 characters.'); + } + + $connectionString = $useSSL ? 'ssl://'.$host.':443' : $host.':80'; + parent::__construct($connectionString, $level, $bubble); + + $this->token = $token; + $this->name = $name; + $this->notify = $notify; + $this->room = $room; + $this->format = $format; + $this->host = $host; + $this->version = $version; + } + + /** + * {@inheritdoc} + * + * @param array $record + * @return string + */ + protected function generateDataStream($record) + { + $content = $this->buildContent($record); + + return $this->buildHeader($content) . $content; + } + + /** + * Builds the body of API call + * + * @param array $record + * @return string + */ + private function buildContent($record) + { + $dataArray = array( + 'notify' => $this->version == self::API_V1 ? + ($this->notify ? 1 : 0) : + ($this->notify ? 'true' : 'false'), + 'message' => $record['formatted'], + 'message_format' => $this->format, + 'color' => $this->getAlertColor($record['level']), + ); + + if (!$this->validateStringLength($dataArray['message'], static::MAXIMUM_MESSAGE_LENGTH)) { + if (function_exists('mb_substr')) { + $dataArray['message'] = mb_substr($dataArray['message'], 0, static::MAXIMUM_MESSAGE_LENGTH).' [truncated]'; + } else { + $dataArray['message'] = substr($dataArray['message'], 0, static::MAXIMUM_MESSAGE_LENGTH).' [truncated]'; + } + } + + // if we are using the legacy API then we need to send some additional information + if ($this->version == self::API_V1) { + $dataArray['room_id'] = $this->room; + } + + // append the sender name if it is set + // always append it if we use the v1 api (it is required in v1) + if ($this->version == self::API_V1 || $this->name !== null) { + $dataArray['from'] = (string) $this->name; + } + + return http_build_query($dataArray); + } + + /** + * Builds the header of the API Call + * + * @param string $content + * @return string + */ + private function buildHeader($content) + { + if ($this->version == self::API_V1) { + $header = "POST /v1/rooms/message?format=json&auth_token={$this->token} HTTP/1.1\r\n"; + } else { + // needed for rooms with special (spaces, etc) characters in the name + $room = rawurlencode($this->room); + $header = "POST /v2/room/{$room}/notification?auth_token={$this->token} HTTP/1.1\r\n"; + } + + $header .= "Host: {$this->host}\r\n"; + $header .= "Content-Type: application/x-www-form-urlencoded\r\n"; + $header .= "Content-Length: " . strlen($content) . "\r\n"; + $header .= "\r\n"; + + return $header; + } + + /** + * Assigns a color to each level of log records. + * + * @param int $level + * @return string + */ + protected function getAlertColor($level) + { + switch (true) { + case $level >= Logger::ERROR: + return 'red'; + case $level >= Logger::WARNING: + return 'yellow'; + case $level >= Logger::INFO: + return 'green'; + case $level == Logger::DEBUG: + return 'gray'; + default: + return 'yellow'; + } + } + + /** + * {@inheritdoc} + * + * @param array $record + */ + protected function write(array $record) + { + parent::write($record); + $this->closeSocket(); + } + + /** + * {@inheritdoc} + */ + public function handleBatch(array $records) + { + if (count($records) == 0) { + return true; + } + + $batchRecords = $this->combineRecords($records); + + $handled = false; + foreach ($batchRecords as $batchRecord) { + if ($this->isHandling($batchRecord)) { + $this->write($batchRecord); + $handled = true; + } + } + + if (!$handled) { + return false; + } + + return false === $this->bubble; + } + + /** + * Combines multiple records into one. Error level of the combined record + * will be the highest level from the given records. Datetime will be taken + * from the first record. + * + * @param $records + * @return array + */ + private function combineRecords($records) + { + $batchRecord = null; + $batchRecords = array(); + $messages = array(); + $formattedMessages = array(); + $level = 0; + $levelName = null; + $datetime = null; + + foreach ($records as $record) { + $record = $this->processRecord($record); + + if ($record['level'] > $level) { + $level = $record['level']; + $levelName = $record['level_name']; + } + + if (null === $datetime) { + $datetime = $record['datetime']; + } + + $messages[] = $record['message']; + $messageStr = implode(PHP_EOL, $messages); + $formattedMessages[] = $this->getFormatter()->format($record); + $formattedMessageStr = implode('', $formattedMessages); + + $batchRecord = array( + 'message' => $messageStr, + 'formatted' => $formattedMessageStr, + 'context' => array(), + 'extra' => array(), + ); + + if (!$this->validateStringLength($batchRecord['formatted'], static::MAXIMUM_MESSAGE_LENGTH)) { + // Pop the last message and implode the remaining messages + $lastMessage = array_pop($messages); + $lastFormattedMessage = array_pop($formattedMessages); + $batchRecord['message'] = implode(PHP_EOL, $messages); + $batchRecord['formatted'] = implode('', $formattedMessages); + + $batchRecords[] = $batchRecord; + $messages = array($lastMessage); + $formattedMessages = array($lastFormattedMessage); + + $batchRecord = null; + } + } + + if (null !== $batchRecord) { + $batchRecords[] = $batchRecord; + } + + // Set the max level and datetime for all records + foreach ($batchRecords as &$batchRecord) { + $batchRecord = array_merge( + $batchRecord, + array( + 'level' => $level, + 'level_name' => $levelName, + 'datetime' => $datetime, + ) + ); + } + + return $batchRecords; + } + + /** + * Validates the length of a string. + * + * If the `mb_strlen()` function is available, it will use that, as HipChat + * allows UTF-8 characters. Otherwise, it will fall back to `strlen()`. + * + * Note that this might cause false failures in the specific case of using + * a valid name with less than 16 characters, but 16 or more bytes, on a + * system where `mb_strlen()` is unavailable. + * + * @param string $str + * @param int $length + * + * @return bool + */ + private function validateStringLength($str, $length) + { + if (function_exists('mb_strlen')) { + return (mb_strlen($str) <= $length); + } + + return (strlen($str) <= $length); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/IFTTTHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/IFTTTHandler.php new file mode 100644 index 0000000..d60a3c8 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/IFTTTHandler.php @@ -0,0 +1,69 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; + +/** + * IFTTTHandler uses cURL to trigger IFTTT Maker actions + * + * Register a secret key and trigger/event name at https://ifttt.com/maker + * + * value1 will be the channel from monolog's Logger constructor, + * value2 will be the level name (ERROR, WARNING, ..) + * value3 will be the log record's message + * + * @author Nehal Patel + */ +class IFTTTHandler extends AbstractProcessingHandler +{ + private $eventName; + private $secretKey; + + /** + * @param string $eventName The name of the IFTTT Maker event that should be triggered + * @param string $secretKey A valid IFTTT secret key + * @param int $level The minimum logging level at which this handler will be triggered + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct($eventName, $secretKey, $level = Logger::ERROR, $bubble = true) + { + $this->eventName = $eventName; + $this->secretKey = $secretKey; + + parent::__construct($level, $bubble); + } + + /** + * {@inheritdoc} + */ + public function write(array $record) + { + $postData = array( + "value1" => $record["channel"], + "value2" => $record["level_name"], + "value3" => $record["message"], + ); + $postString = json_encode($postData); + + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, "https://maker.ifttt.com/trigger/" . $this->eventName . "/with/key/" . $this->secretKey); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $postString); + curl_setopt($ch, CURLOPT_HTTPHEADER, array( + "Content-Type: application/json", + )); + + Curl\Util::execute($ch); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/LogEntriesHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/LogEntriesHandler.php new file mode 100644 index 0000000..494c605 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/LogEntriesHandler.php @@ -0,0 +1,55 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; + +/** + * @author Robert Kaufmann III + */ +class LogEntriesHandler extends SocketHandler +{ + /** + * @var string + */ + protected $logToken; + + /** + * @param string $token Log token supplied by LogEntries + * @param bool $useSSL Whether or not SSL encryption should be used. + * @param int $level The minimum logging level to trigger this handler + * @param bool $bubble Whether or not messages that are handled should bubble up the stack. + * + * @throws MissingExtensionException If SSL encryption is set to true and OpenSSL is missing + */ + public function __construct($token, $useSSL = true, $level = Logger::DEBUG, $bubble = true) + { + if ($useSSL && !extension_loaded('openssl')) { + throw new MissingExtensionException('The OpenSSL PHP plugin is required to use SSL encrypted connection for LogEntriesHandler'); + } + + $endpoint = $useSSL ? 'ssl://data.logentries.com:443' : 'data.logentries.com:80'; + parent::__construct($endpoint, $level, $bubble); + $this->logToken = $token; + } + + /** + * {@inheritdoc} + * + * @param array $record + * @return string + */ + protected function generateDataStream($record) + { + return $this->logToken . ' ' . $record['formatted']; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/LogglyHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/LogglyHandler.php new file mode 100644 index 0000000..bcd62e1 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/LogglyHandler.php @@ -0,0 +1,102 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; +use Monolog\Formatter\LogglyFormatter; + +/** + * Sends errors to Loggly. + * + * @author Przemek Sobstel + * @author Adam Pancutt + * @author Gregory Barchard + */ +class LogglyHandler extends AbstractProcessingHandler +{ + const HOST = 'logs-01.loggly.com'; + const ENDPOINT_SINGLE = 'inputs'; + const ENDPOINT_BATCH = 'bulk'; + + protected $token; + + protected $tag = array(); + + public function __construct($token, $level = Logger::DEBUG, $bubble = true) + { + if (!extension_loaded('curl')) { + throw new \LogicException('The curl extension is needed to use the LogglyHandler'); + } + + $this->token = $token; + + parent::__construct($level, $bubble); + } + + public function setTag($tag) + { + $tag = !empty($tag) ? $tag : array(); + $this->tag = is_array($tag) ? $tag : array($tag); + } + + public function addTag($tag) + { + if (!empty($tag)) { + $tag = is_array($tag) ? $tag : array($tag); + $this->tag = array_unique(array_merge($this->tag, $tag)); + } + } + + protected function write(array $record) + { + $this->send($record["formatted"], self::ENDPOINT_SINGLE); + } + + public function handleBatch(array $records) + { + $level = $this->level; + + $records = array_filter($records, function ($record) use ($level) { + return ($record['level'] >= $level); + }); + + if ($records) { + $this->send($this->getFormatter()->formatBatch($records), self::ENDPOINT_BATCH); + } + } + + protected function send($data, $endpoint) + { + $url = sprintf("https://%s/%s/%s/", self::HOST, $endpoint, $this->token); + + $headers = array('Content-Type: application/json'); + + if (!empty($this->tag)) { + $headers[] = 'X-LOGGLY-TAG: '.implode(',', $this->tag); + } + + $ch = curl_init(); + + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $data); + curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + Curl\Util::execute($ch); + } + + protected function getDefaultFormatter() + { + return new LogglyFormatter(); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/MailHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/MailHandler.php new file mode 100644 index 0000000..9e23283 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/MailHandler.php @@ -0,0 +1,67 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +/** + * Base class for all mail handlers + * + * @author Gyula Sallai + */ +abstract class MailHandler extends AbstractProcessingHandler +{ + /** + * {@inheritdoc} + */ + public function handleBatch(array $records) + { + $messages = array(); + + foreach ($records as $record) { + if ($record['level'] < $this->level) { + continue; + } + $messages[] = $this->processRecord($record); + } + + if (!empty($messages)) { + $this->send((string) $this->getFormatter()->formatBatch($messages), $messages); + } + } + + /** + * Send a mail with the given content + * + * @param string $content formatted email body to be sent + * @param array $records the array of log records that formed this content + */ + abstract protected function send($content, array $records); + + /** + * {@inheritdoc} + */ + protected function write(array $record) + { + $this->send((string) $record['formatted'], array($record)); + } + + protected function getHighestRecord(array $records) + { + $highestRecord = null; + foreach ($records as $record) { + if ($highestRecord === null || $highestRecord['level'] < $record['level']) { + $highestRecord = $record; + } + } + + return $highestRecord; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/MandrillHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/MandrillHandler.php new file mode 100644 index 0000000..ab95924 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/MandrillHandler.php @@ -0,0 +1,68 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; + +/** + * MandrillHandler uses cURL to send the emails to the Mandrill API + * + * @author Adam Nicholson + */ +class MandrillHandler extends MailHandler +{ + protected $message; + protected $apiKey; + + /** + * @param string $apiKey A valid Mandrill API key + * @param callable|\Swift_Message $message An example message for real messages, only the body will be replaced + * @param int $level The minimum logging level at which this handler will be triggered + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct($apiKey, $message, $level = Logger::ERROR, $bubble = true) + { + parent::__construct($level, $bubble); + + if (!$message instanceof \Swift_Message && is_callable($message)) { + $message = call_user_func($message); + } + if (!$message instanceof \Swift_Message) { + throw new \InvalidArgumentException('You must provide either a Swift_Message instance or a callable returning it'); + } + $this->message = $message; + $this->apiKey = $apiKey; + } + + /** + * {@inheritdoc} + */ + protected function send($content, array $records) + { + $message = clone $this->message; + $message->setBody($content); + $message->setDate(time()); + + $ch = curl_init(); + + curl_setopt($ch, CURLOPT_URL, 'https://mandrillapp.com/api/1.0/messages/send-raw.json'); + curl_setopt($ch, CURLOPT_POST, 1); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(array( + 'key' => $this->apiKey, + 'raw_message' => (string) $message, + 'async' => false, + ))); + + Curl\Util::execute($ch); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/MissingExtensionException.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/MissingExtensionException.php new file mode 100644 index 0000000..4724a7e --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/MissingExtensionException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +/** + * Exception can be thrown if an extension for an handler is missing + * + * @author Christian Bergau + */ +class MissingExtensionException extends \Exception +{ +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/MongoDBHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/MongoDBHandler.php new file mode 100644 index 0000000..56fe755 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/MongoDBHandler.php @@ -0,0 +1,59 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; +use Monolog\Formatter\NormalizerFormatter; + +/** + * Logs to a MongoDB database. + * + * usage example: + * + * $log = new Logger('application'); + * $mongodb = new MongoDBHandler(new \Mongo("mongodb://localhost:27017"), "logs", "prod"); + * $log->pushHandler($mongodb); + * + * @author Thomas Tourlourat + */ +class MongoDBHandler extends AbstractProcessingHandler +{ + protected $mongoCollection; + + public function __construct($mongo, $database, $collection, $level = Logger::DEBUG, $bubble = true) + { + if (!($mongo instanceof \MongoClient || $mongo instanceof \Mongo || $mongo instanceof \MongoDB\Client)) { + throw new \InvalidArgumentException('MongoClient, Mongo or MongoDB\Client instance required'); + } + + $this->mongoCollection = $mongo->selectCollection($database, $collection); + + parent::__construct($level, $bubble); + } + + protected function write(array $record) + { + if ($this->mongoCollection instanceof \MongoDB\Collection) { + $this->mongoCollection->insertOne($record["formatted"]); + } else { + $this->mongoCollection->save($record["formatted"]); + } + } + + /** + * {@inheritDoc} + */ + protected function getDefaultFormatter() + { + return new NormalizerFormatter(); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/NativeMailerHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/NativeMailerHandler.php new file mode 100644 index 0000000..d7807fd --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/NativeMailerHandler.php @@ -0,0 +1,185 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; +use Monolog\Formatter\LineFormatter; + +/** + * NativeMailerHandler uses the mail() function to send the emails + * + * @author Christophe Coevoet + * @author Mark Garrett + */ +class NativeMailerHandler extends MailHandler +{ + /** + * The email addresses to which the message will be sent + * @var array + */ + protected $to; + + /** + * The subject of the email + * @var string + */ + protected $subject; + + /** + * Optional headers for the message + * @var array + */ + protected $headers = array(); + + /** + * Optional parameters for the message + * @var array + */ + protected $parameters = array(); + + /** + * The wordwrap length for the message + * @var int + */ + protected $maxColumnWidth; + + /** + * The Content-type for the message + * @var string + */ + protected $contentType = 'text/plain'; + + /** + * The encoding for the message + * @var string + */ + protected $encoding = 'utf-8'; + + /** + * @param string|array $to The receiver of the mail + * @param string $subject The subject of the mail + * @param string $from The sender of the mail + * @param int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + * @param int $maxColumnWidth The maximum column width that the message lines will have + */ + public function __construct($to, $subject, $from, $level = Logger::ERROR, $bubble = true, $maxColumnWidth = 70) + { + parent::__construct($level, $bubble); + $this->to = is_array($to) ? $to : array($to); + $this->subject = $subject; + $this->addHeader(sprintf('From: %s', $from)); + $this->maxColumnWidth = $maxColumnWidth; + } + + /** + * Add headers to the message + * + * @param string|array $headers Custom added headers + * @return self + */ + public function addHeader($headers) + { + foreach ((array) $headers as $header) { + if (strpos($header, "\n") !== false || strpos($header, "\r") !== false) { + throw new \InvalidArgumentException('Headers can not contain newline characters for security reasons'); + } + $this->headers[] = $header; + } + + return $this; + } + + /** + * Add parameters to the message + * + * @param string|array $parameters Custom added parameters + * @return self + */ + public function addParameter($parameters) + { + $this->parameters = array_merge($this->parameters, (array) $parameters); + + return $this; + } + + /** + * {@inheritdoc} + */ + protected function send($content, array $records) + { + $content = wordwrap($content, $this->maxColumnWidth); + $headers = ltrim(implode("\r\n", $this->headers) . "\r\n", "\r\n"); + $headers .= 'Content-type: ' . $this->getContentType() . '; charset=' . $this->getEncoding() . "\r\n"; + if ($this->getContentType() == 'text/html' && false === strpos($headers, 'MIME-Version:')) { + $headers .= 'MIME-Version: 1.0' . "\r\n"; + } + + $subject = $this->subject; + if ($records) { + $subjectFormatter = new LineFormatter($this->subject); + $subject = $subjectFormatter->format($this->getHighestRecord($records)); + } + + $parameters = implode(' ', $this->parameters); + foreach ($this->to as $to) { + mail($to, $subject, $content, $headers, $parameters); + } + } + + /** + * @return string $contentType + */ + public function getContentType() + { + return $this->contentType; + } + + /** + * @return string $encoding + */ + public function getEncoding() + { + return $this->encoding; + } + + /** + * @param string $contentType The content type of the email - Defaults to text/plain. Use text/html for HTML + * messages. + * @return self + */ + public function setContentType($contentType) + { + if (strpos($contentType, "\n") !== false || strpos($contentType, "\r") !== false) { + throw new \InvalidArgumentException('The content type can not contain newline characters to prevent email header injection'); + } + + $this->contentType = $contentType; + + return $this; + } + + /** + * @param string $encoding + * @return self + */ + public function setEncoding($encoding) + { + if (strpos($encoding, "\n") !== false || strpos($encoding, "\r") !== false) { + throw new \InvalidArgumentException('The encoding can not contain newline characters to prevent email header injection'); + } + + $this->encoding = $encoding; + + return $this; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/NewRelicHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/NewRelicHandler.php new file mode 100644 index 0000000..6718e9e --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/NewRelicHandler.php @@ -0,0 +1,202 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; +use Monolog\Formatter\NormalizerFormatter; + +/** + * Class to record a log on a NewRelic application. + * Enabling New Relic High Security mode may prevent capture of useful information. + * + * @see https://docs.newrelic.com/docs/agents/php-agent + * @see https://docs.newrelic.com/docs/accounts-partnerships/accounts/security/high-security + */ +class NewRelicHandler extends AbstractProcessingHandler +{ + /** + * Name of the New Relic application that will receive logs from this handler. + * + * @var string + */ + protected $appName; + + /** + * Name of the current transaction + * + * @var string + */ + protected $transactionName; + + /** + * Some context and extra data is passed into the handler as arrays of values. Do we send them as is + * (useful if we are using the API), or explode them for display on the NewRelic RPM website? + * + * @var bool + */ + protected $explodeArrays; + + /** + * {@inheritDoc} + * + * @param string $appName + * @param bool $explodeArrays + * @param string $transactionName + */ + public function __construct( + $level = Logger::ERROR, + $bubble = true, + $appName = null, + $explodeArrays = false, + $transactionName = null + ) { + parent::__construct($level, $bubble); + + $this->appName = $appName; + $this->explodeArrays = $explodeArrays; + $this->transactionName = $transactionName; + } + + /** + * {@inheritDoc} + */ + protected function write(array $record) + { + if (!$this->isNewRelicEnabled()) { + throw new MissingExtensionException('The newrelic PHP extension is required to use the NewRelicHandler'); + } + + if ($appName = $this->getAppName($record['context'])) { + $this->setNewRelicAppName($appName); + } + + if ($transactionName = $this->getTransactionName($record['context'])) { + $this->setNewRelicTransactionName($transactionName); + unset($record['formatted']['context']['transaction_name']); + } + + if (isset($record['context']['exception']) && $record['context']['exception'] instanceof \Exception) { + newrelic_notice_error($record['message'], $record['context']['exception']); + unset($record['formatted']['context']['exception']); + } else { + newrelic_notice_error($record['message']); + } + + if (isset($record['formatted']['context']) && is_array($record['formatted']['context'])) { + foreach ($record['formatted']['context'] as $key => $parameter) { + if (is_array($parameter) && $this->explodeArrays) { + foreach ($parameter as $paramKey => $paramValue) { + $this->setNewRelicParameter('context_' . $key . '_' . $paramKey, $paramValue); + } + } else { + $this->setNewRelicParameter('context_' . $key, $parameter); + } + } + } + + if (isset($record['formatted']['extra']) && is_array($record['formatted']['extra'])) { + foreach ($record['formatted']['extra'] as $key => $parameter) { + if (is_array($parameter) && $this->explodeArrays) { + foreach ($parameter as $paramKey => $paramValue) { + $this->setNewRelicParameter('extra_' . $key . '_' . $paramKey, $paramValue); + } + } else { + $this->setNewRelicParameter('extra_' . $key, $parameter); + } + } + } + } + + /** + * Checks whether the NewRelic extension is enabled in the system. + * + * @return bool + */ + protected function isNewRelicEnabled() + { + return extension_loaded('newrelic'); + } + + /** + * Returns the appname where this log should be sent. Each log can override the default appname, set in this + * handler's constructor, by providing the appname in it's context. + * + * @param array $context + * @return null|string + */ + protected function getAppName(array $context) + { + if (isset($context['appname'])) { + return $context['appname']; + } + + return $this->appName; + } + + /** + * Returns the name of the current transaction. Each log can override the default transaction name, set in this + * handler's constructor, by providing the transaction_name in it's context + * + * @param array $context + * + * @return null|string + */ + protected function getTransactionName(array $context) + { + if (isset($context['transaction_name'])) { + return $context['transaction_name']; + } + + return $this->transactionName; + } + + /** + * Sets the NewRelic application that should receive this log. + * + * @param string $appName + */ + protected function setNewRelicAppName($appName) + { + newrelic_set_appname($appName); + } + + /** + * Overwrites the name of the current transaction + * + * @param string $transactionName + */ + protected function setNewRelicTransactionName($transactionName) + { + newrelic_name_transaction($transactionName); + } + + /** + * @param string $key + * @param mixed $value + */ + protected function setNewRelicParameter($key, $value) + { + if (null === $value || is_scalar($value)) { + newrelic_add_custom_parameter($key, $value); + } else { + newrelic_add_custom_parameter($key, @json_encode($value)); + } + } + + /** + * {@inheritDoc} + */ + protected function getDefaultFormatter() + { + return new NormalizerFormatter(); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/NullHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/NullHandler.php new file mode 100644 index 0000000..4b84588 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/NullHandler.php @@ -0,0 +1,45 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; + +/** + * Blackhole + * + * Any record it can handle will be thrown away. This can be used + * to put on top of an existing stack to override it temporarily. + * + * @author Jordi Boggiano + */ +class NullHandler extends AbstractHandler +{ + /** + * @param int $level The minimum logging level at which this handler will be triggered + */ + public function __construct($level = Logger::DEBUG) + { + parent::__construct($level, false); + } + + /** + * {@inheritdoc} + */ + public function handle(array $record) + { + if ($record['level'] < $this->level) { + return false; + } + + return true; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/PHPConsoleHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/PHPConsoleHandler.php new file mode 100644 index 0000000..1f2076a --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/PHPConsoleHandler.php @@ -0,0 +1,242 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Exception; +use Monolog\Formatter\LineFormatter; +use Monolog\Logger; +use PhpConsole\Connector; +use PhpConsole\Handler; +use PhpConsole\Helper; + +/** + * Monolog handler for Google Chrome extension "PHP Console" + * + * Display PHP error/debug log messages in Google Chrome console and notification popups, executes PHP code remotely + * + * Usage: + * 1. Install Google Chrome extension https://chrome.google.com/webstore/detail/php-console/nfhmhhlpfleoednkpnnnkolmclajemef + * 2. See overview https://github.com/barbushin/php-console#overview + * 3. Install PHP Console library https://github.com/barbushin/php-console#installation + * 4. Example (result will looks like http://i.hizliresim.com/vg3Pz4.png) + * + * $logger = new \Monolog\Logger('all', array(new \Monolog\Handler\PHPConsoleHandler())); + * \Monolog\ErrorHandler::register($logger); + * echo $undefinedVar; + * $logger->addDebug('SELECT * FROM users', array('db', 'time' => 0.012)); + * PC::debug($_SERVER); // PHP Console debugger for any type of vars + * + * @author Sergey Barbushin https://www.linkedin.com/in/barbushin + */ +class PHPConsoleHandler extends AbstractProcessingHandler +{ + private $options = array( + 'enabled' => true, // bool Is PHP Console server enabled + 'classesPartialsTraceIgnore' => array('Monolog\\'), // array Hide calls of classes started with... + 'debugTagsKeysInContext' => array(0, 'tag'), // bool Is PHP Console server enabled + 'useOwnErrorsHandler' => false, // bool Enable errors handling + 'useOwnExceptionsHandler' => false, // bool Enable exceptions handling + 'sourcesBasePath' => null, // string Base path of all project sources to strip in errors source paths + 'registerHelper' => true, // bool Register PhpConsole\Helper that allows short debug calls like PC::debug($var, 'ta.g.s') + 'serverEncoding' => null, // string|null Server internal encoding + 'headersLimit' => null, // int|null Set headers size limit for your web-server + 'password' => null, // string|null Protect PHP Console connection by password + 'enableSslOnlyMode' => false, // bool Force connection by SSL for clients with PHP Console installed + 'ipMasks' => array(), // array Set IP masks of clients that will be allowed to connect to PHP Console: array('192.168.*.*', '127.0.0.1') + 'enableEvalListener' => false, // bool Enable eval request to be handled by eval dispatcher(if enabled, 'password' option is also required) + 'dumperDetectCallbacks' => false, // bool Convert callback items in dumper vars to (callback SomeClass::someMethod) strings + 'dumperLevelLimit' => 5, // int Maximum dumped vars array or object nested dump level + 'dumperItemsCountLimit' => 100, // int Maximum dumped var same level array items or object properties number + 'dumperItemSizeLimit' => 5000, // int Maximum length of any string or dumped array item + 'dumperDumpSizeLimit' => 500000, // int Maximum approximate size of dumped vars result formatted in JSON + 'detectDumpTraceAndSource' => false, // bool Autodetect and append trace data to debug + 'dataStorage' => null, // PhpConsole\Storage|null Fixes problem with custom $_SESSION handler(see http://goo.gl/Ne8juJ) + ); + + /** @var Connector */ + private $connector; + + /** + * @param array $options See \Monolog\Handler\PHPConsoleHandler::$options for more details + * @param Connector|null $connector Instance of \PhpConsole\Connector class (optional) + * @param int $level + * @param bool $bubble + * @throws Exception + */ + public function __construct(array $options = array(), Connector $connector = null, $level = Logger::DEBUG, $bubble = true) + { + if (!class_exists('PhpConsole\Connector')) { + throw new Exception('PHP Console library not found. See https://github.com/barbushin/php-console#installation'); + } + parent::__construct($level, $bubble); + $this->options = $this->initOptions($options); + $this->connector = $this->initConnector($connector); + } + + private function initOptions(array $options) + { + $wrongOptions = array_diff(array_keys($options), array_keys($this->options)); + if ($wrongOptions) { + throw new Exception('Unknown options: ' . implode(', ', $wrongOptions)); + } + + return array_replace($this->options, $options); + } + + private function initConnector(Connector $connector = null) + { + if (!$connector) { + if ($this->options['dataStorage']) { + Connector::setPostponeStorage($this->options['dataStorage']); + } + $connector = Connector::getInstance(); + } + + if ($this->options['registerHelper'] && !Helper::isRegistered()) { + Helper::register(); + } + + if ($this->options['enabled'] && $connector->isActiveClient()) { + if ($this->options['useOwnErrorsHandler'] || $this->options['useOwnExceptionsHandler']) { + $handler = Handler::getInstance(); + $handler->setHandleErrors($this->options['useOwnErrorsHandler']); + $handler->setHandleExceptions($this->options['useOwnExceptionsHandler']); + $handler->start(); + } + if ($this->options['sourcesBasePath']) { + $connector->setSourcesBasePath($this->options['sourcesBasePath']); + } + if ($this->options['serverEncoding']) { + $connector->setServerEncoding($this->options['serverEncoding']); + } + if ($this->options['password']) { + $connector->setPassword($this->options['password']); + } + if ($this->options['enableSslOnlyMode']) { + $connector->enableSslOnlyMode(); + } + if ($this->options['ipMasks']) { + $connector->setAllowedIpMasks($this->options['ipMasks']); + } + if ($this->options['headersLimit']) { + $connector->setHeadersLimit($this->options['headersLimit']); + } + if ($this->options['detectDumpTraceAndSource']) { + $connector->getDebugDispatcher()->detectTraceAndSource = true; + } + $dumper = $connector->getDumper(); + $dumper->levelLimit = $this->options['dumperLevelLimit']; + $dumper->itemsCountLimit = $this->options['dumperItemsCountLimit']; + $dumper->itemSizeLimit = $this->options['dumperItemSizeLimit']; + $dumper->dumpSizeLimit = $this->options['dumperDumpSizeLimit']; + $dumper->detectCallbacks = $this->options['dumperDetectCallbacks']; + if ($this->options['enableEvalListener']) { + $connector->startEvalRequestsListener(); + } + } + + return $connector; + } + + public function getConnector() + { + return $this->connector; + } + + public function getOptions() + { + return $this->options; + } + + public function handle(array $record) + { + if ($this->options['enabled'] && $this->connector->isActiveClient()) { + return parent::handle($record); + } + + return !$this->bubble; + } + + /** + * Writes the record down to the log of the implementing handler + * + * @param array $record + * @return void + */ + protected function write(array $record) + { + if ($record['level'] < Logger::NOTICE) { + $this->handleDebugRecord($record); + } elseif (isset($record['context']['exception']) && $record['context']['exception'] instanceof Exception) { + $this->handleExceptionRecord($record); + } else { + $this->handleErrorRecord($record); + } + } + + private function handleDebugRecord(array $record) + { + $tags = $this->getRecordTags($record); + $message = $record['message']; + if ($record['context']) { + $message .= ' ' . json_encode($this->connector->getDumper()->dump(array_filter($record['context']))); + } + $this->connector->getDebugDispatcher()->dispatchDebug($message, $tags, $this->options['classesPartialsTraceIgnore']); + } + + private function handleExceptionRecord(array $record) + { + $this->connector->getErrorsDispatcher()->dispatchException($record['context']['exception']); + } + + private function handleErrorRecord(array $record) + { + $context = $record['context']; + + $this->connector->getErrorsDispatcher()->dispatchError( + isset($context['code']) ? $context['code'] : null, + isset($context['message']) ? $context['message'] : $record['message'], + isset($context['file']) ? $context['file'] : null, + isset($context['line']) ? $context['line'] : null, + $this->options['classesPartialsTraceIgnore'] + ); + } + + private function getRecordTags(array &$record) + { + $tags = null; + if (!empty($record['context'])) { + $context = & $record['context']; + foreach ($this->options['debugTagsKeysInContext'] as $key) { + if (!empty($context[$key])) { + $tags = $context[$key]; + if ($key === 0) { + array_shift($context); + } else { + unset($context[$key]); + } + break; + } + } + } + + return $tags ?: strtolower($record['level_name']); + } + + /** + * {@inheritDoc} + */ + protected function getDefaultFormatter() + { + return new LineFormatter('%message%'); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/PsrHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/PsrHandler.php new file mode 100644 index 0000000..1ae8584 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/PsrHandler.php @@ -0,0 +1,56 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; +use Psr\Log\LoggerInterface; + +/** + * Proxies log messages to an existing PSR-3 compliant logger. + * + * @author Michael Moussa + */ +class PsrHandler extends AbstractHandler +{ + /** + * PSR-3 compliant logger + * + * @var LoggerInterface + */ + protected $logger; + + /** + * @param LoggerInterface $logger The underlying PSR-3 compliant logger to which messages will be proxied + * @param int $level The minimum logging level at which this handler will be triggered + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct(LoggerInterface $logger, $level = Logger::DEBUG, $bubble = true) + { + parent::__construct($level, $bubble); + + $this->logger = $logger; + } + + /** + * {@inheritDoc} + */ + public function handle(array $record) + { + if (!$this->isHandling($record)) { + return false; + } + + $this->logger->log(strtolower($record['level_name']), $record['message'], $record['context']); + + return false === $this->bubble; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/PushoverHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/PushoverHandler.php new file mode 100644 index 0000000..bba7200 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/PushoverHandler.php @@ -0,0 +1,185 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; + +/** + * Sends notifications through the pushover api to mobile phones + * + * @author Sebastian Göttschkes + * @see https://www.pushover.net/api + */ +class PushoverHandler extends SocketHandler +{ + private $token; + private $users; + private $title; + private $user; + private $retry; + private $expire; + + private $highPriorityLevel; + private $emergencyLevel; + private $useFormattedMessage = false; + + /** + * All parameters that can be sent to Pushover + * @see https://pushover.net/api + * @var array + */ + private $parameterNames = array( + 'token' => true, + 'user' => true, + 'message' => true, + 'device' => true, + 'title' => true, + 'url' => true, + 'url_title' => true, + 'priority' => true, + 'timestamp' => true, + 'sound' => true, + 'retry' => true, + 'expire' => true, + 'callback' => true, + ); + + /** + * Sounds the api supports by default + * @see https://pushover.net/api#sounds + * @var array + */ + private $sounds = array( + 'pushover', 'bike', 'bugle', 'cashregister', 'classical', 'cosmic', 'falling', 'gamelan', 'incoming', + 'intermission', 'magic', 'mechanical', 'pianobar', 'siren', 'spacealarm', 'tugboat', 'alien', 'climb', + 'persistent', 'echo', 'updown', 'none', + ); + + /** + * @param string $token Pushover api token + * @param string|array $users Pushover user id or array of ids the message will be sent to + * @param string $title Title sent to the Pushover API + * @param int $level The minimum logging level at which this handler will be triggered + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + * @param Boolean $useSSL Whether to connect via SSL. Required when pushing messages to users that are not + * the pushover.net app owner. OpenSSL is required for this option. + * @param int $highPriorityLevel The minimum logging level at which this handler will start + * sending "high priority" requests to the Pushover API + * @param int $emergencyLevel The minimum logging level at which this handler will start + * sending "emergency" requests to the Pushover API + * @param int $retry The retry parameter specifies how often (in seconds) the Pushover servers will send the same notification to the user. + * @param int $expire The expire parameter specifies how many seconds your notification will continue to be retried for (every retry seconds). + */ + public function __construct($token, $users, $title = null, $level = Logger::CRITICAL, $bubble = true, $useSSL = true, $highPriorityLevel = Logger::CRITICAL, $emergencyLevel = Logger::EMERGENCY, $retry = 30, $expire = 25200) + { + $connectionString = $useSSL ? 'ssl://api.pushover.net:443' : 'api.pushover.net:80'; + parent::__construct($connectionString, $level, $bubble); + + $this->token = $token; + $this->users = (array) $users; + $this->title = $title ?: gethostname(); + $this->highPriorityLevel = Logger::toMonologLevel($highPriorityLevel); + $this->emergencyLevel = Logger::toMonologLevel($emergencyLevel); + $this->retry = $retry; + $this->expire = $expire; + } + + protected function generateDataStream($record) + { + $content = $this->buildContent($record); + + return $this->buildHeader($content) . $content; + } + + private function buildContent($record) + { + // Pushover has a limit of 512 characters on title and message combined. + $maxMessageLength = 512 - strlen($this->title); + + $message = ($this->useFormattedMessage) ? $record['formatted'] : $record['message']; + $message = substr($message, 0, $maxMessageLength); + + $timestamp = $record['datetime']->getTimestamp(); + + $dataArray = array( + 'token' => $this->token, + 'user' => $this->user, + 'message' => $message, + 'title' => $this->title, + 'timestamp' => $timestamp, + ); + + if (isset($record['level']) && $record['level'] >= $this->emergencyLevel) { + $dataArray['priority'] = 2; + $dataArray['retry'] = $this->retry; + $dataArray['expire'] = $this->expire; + } elseif (isset($record['level']) && $record['level'] >= $this->highPriorityLevel) { + $dataArray['priority'] = 1; + } + + // First determine the available parameters + $context = array_intersect_key($record['context'], $this->parameterNames); + $extra = array_intersect_key($record['extra'], $this->parameterNames); + + // Least important info should be merged with subsequent info + $dataArray = array_merge($extra, $context, $dataArray); + + // Only pass sounds that are supported by the API + if (isset($dataArray['sound']) && !in_array($dataArray['sound'], $this->sounds)) { + unset($dataArray['sound']); + } + + return http_build_query($dataArray); + } + + private function buildHeader($content) + { + $header = "POST /1/messages.json HTTP/1.1\r\n"; + $header .= "Host: api.pushover.net\r\n"; + $header .= "Content-Type: application/x-www-form-urlencoded\r\n"; + $header .= "Content-Length: " . strlen($content) . "\r\n"; + $header .= "\r\n"; + + return $header; + } + + protected function write(array $record) + { + foreach ($this->users as $user) { + $this->user = $user; + + parent::write($record); + $this->closeSocket(); + } + + $this->user = null; + } + + public function setHighPriorityLevel($value) + { + $this->highPriorityLevel = $value; + } + + public function setEmergencyLevel($value) + { + $this->emergencyLevel = $value; + } + + /** + * Use the formatted message? + * @param bool $value + */ + public function useFormattedMessage($value) + { + $this->useFormattedMessage = (boolean) $value; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/RavenHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/RavenHandler.php new file mode 100644 index 0000000..0b9f367 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/RavenHandler.php @@ -0,0 +1,231 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Formatter\LineFormatter; +use Monolog\Formatter\FormatterInterface; +use Monolog\Logger; +use Raven_Client; + +/** + * Handler to send messages to a Sentry (https://github.com/getsentry/sentry) server + * using raven-php (https://github.com/getsentry/raven-php) + * + * @author Marc Abramowitz + */ +class RavenHandler extends AbstractProcessingHandler +{ + /** + * Translates Monolog log levels to Raven log levels. + */ + private $logLevels = array( + Logger::DEBUG => Raven_Client::DEBUG, + Logger::INFO => Raven_Client::INFO, + Logger::NOTICE => Raven_Client::INFO, + Logger::WARNING => Raven_Client::WARNING, + Logger::ERROR => Raven_Client::ERROR, + Logger::CRITICAL => Raven_Client::FATAL, + Logger::ALERT => Raven_Client::FATAL, + Logger::EMERGENCY => Raven_Client::FATAL, + ); + + /** + * @var string should represent the current version of the calling + * software. Can be any string (git commit, version number) + */ + private $release; + + /** + * @var Raven_Client the client object that sends the message to the server + */ + protected $ravenClient; + + /** + * @var LineFormatter The formatter to use for the logs generated via handleBatch() + */ + protected $batchFormatter; + + /** + * @param Raven_Client $ravenClient + * @param int $level The minimum logging level at which this handler will be triggered + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct(Raven_Client $ravenClient, $level = Logger::DEBUG, $bubble = true) + { + parent::__construct($level, $bubble); + + $this->ravenClient = $ravenClient; + } + + /** + * {@inheritdoc} + */ + public function handleBatch(array $records) + { + $level = $this->level; + + // filter records based on their level + $records = array_filter($records, function ($record) use ($level) { + return $record['level'] >= $level; + }); + + if (!$records) { + return; + } + + // the record with the highest severity is the "main" one + $record = array_reduce($records, function ($highest, $record) { + if ($record['level'] >= $highest['level']) { + return $record; + } + + return $highest; + }); + + // the other ones are added as a context item + $logs = array(); + foreach ($records as $r) { + $logs[] = $this->processRecord($r); + } + + if ($logs) { + $record['context']['logs'] = (string) $this->getBatchFormatter()->formatBatch($logs); + } + + $this->handle($record); + } + + /** + * Sets the formatter for the logs generated by handleBatch(). + * + * @param FormatterInterface $formatter + */ + public function setBatchFormatter(FormatterInterface $formatter) + { + $this->batchFormatter = $formatter; + } + + /** + * Gets the formatter for the logs generated by handleBatch(). + * + * @return FormatterInterface + */ + public function getBatchFormatter() + { + if (!$this->batchFormatter) { + $this->batchFormatter = $this->getDefaultBatchFormatter(); + } + + return $this->batchFormatter; + } + + /** + * {@inheritdoc} + */ + protected function write(array $record) + { + $previousUserContext = false; + $options = array(); + $options['level'] = $this->logLevels[$record['level']]; + $options['tags'] = array(); + if (!empty($record['extra']['tags'])) { + $options['tags'] = array_merge($options['tags'], $record['extra']['tags']); + unset($record['extra']['tags']); + } + if (!empty($record['context']['tags'])) { + $options['tags'] = array_merge($options['tags'], $record['context']['tags']); + unset($record['context']['tags']); + } + if (!empty($record['context']['fingerprint'])) { + $options['fingerprint'] = $record['context']['fingerprint']; + unset($record['context']['fingerprint']); + } + if (!empty($record['context']['logger'])) { + $options['logger'] = $record['context']['logger']; + unset($record['context']['logger']); + } else { + $options['logger'] = $record['channel']; + } + foreach ($this->getExtraParameters() as $key) { + foreach (array('extra', 'context') as $source) { + if (!empty($record[$source][$key])) { + $options[$key] = $record[$source][$key]; + unset($record[$source][$key]); + } + } + } + if (!empty($record['context'])) { + $options['extra']['context'] = $record['context']; + if (!empty($record['context']['user'])) { + $previousUserContext = $this->ravenClient->context->user; + $this->ravenClient->user_context($record['context']['user']); + unset($options['extra']['context']['user']); + } + } + if (!empty($record['extra'])) { + $options['extra']['extra'] = $record['extra']; + } + + if (!empty($this->release) && !isset($options['release'])) { + $options['release'] = $this->release; + } + + if (isset($record['context']['exception']) && ($record['context']['exception'] instanceof \Exception || (PHP_VERSION_ID >= 70000 && $record['context']['exception'] instanceof \Throwable))) { + $options['extra']['message'] = $record['formatted']; + $this->ravenClient->captureException($record['context']['exception'], $options); + } else { + $this->ravenClient->captureMessage($record['formatted'], array(), $options); + } + + if ($previousUserContext !== false) { + $this->ravenClient->user_context($previousUserContext); + } + } + + /** + * {@inheritDoc} + */ + protected function getDefaultFormatter() + { + return new LineFormatter('[%channel%] %message%'); + } + + /** + * Gets the default formatter for the logs generated by handleBatch(). + * + * @return FormatterInterface + */ + protected function getDefaultBatchFormatter() + { + return new LineFormatter(); + } + + /** + * Gets extra parameters supported by Raven that can be found in "extra" and "context" + * + * @return array + */ + protected function getExtraParameters() + { + return array('checksum', 'release'); + } + + /** + * @param string $value + */ + public function setRelease($value) + { + $this->release = $value; + + return $this; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/RedisHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/RedisHandler.php new file mode 100644 index 0000000..590f996 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/RedisHandler.php @@ -0,0 +1,97 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Formatter\LineFormatter; +use Monolog\Logger; + +/** + * Logs to a Redis key using rpush + * + * usage example: + * + * $log = new Logger('application'); + * $redis = new RedisHandler(new Predis\Client("tcp://localhost:6379"), "logs", "prod"); + * $log->pushHandler($redis); + * + * @author Thomas Tourlourat + */ +class RedisHandler extends AbstractProcessingHandler +{ + private $redisClient; + private $redisKey; + protected $capSize; + + /** + * @param \Predis\Client|\Redis $redis The redis instance + * @param string $key The key name to push records to + * @param int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + * @param int $capSize Number of entries to limit list size to + */ + public function __construct($redis, $key, $level = Logger::DEBUG, $bubble = true, $capSize = false) + { + if (!(($redis instanceof \Predis\Client) || ($redis instanceof \Redis))) { + throw new \InvalidArgumentException('Predis\Client or Redis instance required'); + } + + $this->redisClient = $redis; + $this->redisKey = $key; + $this->capSize = $capSize; + + parent::__construct($level, $bubble); + } + + /** + * {@inheritDoc} + */ + protected function write(array $record) + { + if ($this->capSize) { + $this->writeCapped($record); + } else { + $this->redisClient->rpush($this->redisKey, $record["formatted"]); + } + } + + /** + * Write and cap the collection + * Writes the record to the redis list and caps its + * + * @param array $record associative record array + * @return void + */ + protected function writeCapped(array $record) + { + if ($this->redisClient instanceof \Redis) { + $this->redisClient->multi() + ->rpush($this->redisKey, $record["formatted"]) + ->ltrim($this->redisKey, -$this->capSize, -1) + ->exec(); + } else { + $redisKey = $this->redisKey; + $capSize = $this->capSize; + $this->redisClient->transaction(function ($tx) use ($record, $redisKey, $capSize) { + $tx->rpush($redisKey, $record["formatted"]); + $tx->ltrim($redisKey, -$capSize, -1); + }); + } + } + + /** + * {@inheritDoc} + */ + protected function getDefaultFormatter() + { + return new LineFormatter(); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/RollbarHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/RollbarHandler.php new file mode 100644 index 0000000..e11d464 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/RollbarHandler.php @@ -0,0 +1,106 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use RollbarNotifier; +use Exception; +use Monolog\Logger; + +/** + * Sends errors to Rollbar + * + * If the context data contains a `payload` key, that is used as an array + * of payload options to RollbarNotifier's report_message/report_exception methods. + * + * @author Paul Statezny + */ +class RollbarHandler extends AbstractProcessingHandler +{ + /** + * Rollbar notifier + * + * @var RollbarNotifier + */ + protected $rollbarNotifier; + + /** + * Records whether any log records have been added since the last flush of the rollbar notifier + * + * @var bool + */ + private $hasRecords = false; + + /** + * @param RollbarNotifier $rollbarNotifier RollbarNotifier object constructed with valid token + * @param int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct(RollbarNotifier $rollbarNotifier, $level = Logger::ERROR, $bubble = true) + { + $this->rollbarNotifier = $rollbarNotifier; + + parent::__construct($level, $bubble); + } + + /** + * {@inheritdoc} + */ + protected function write(array $record) + { + if (isset($record['context']['exception']) && $record['context']['exception'] instanceof Exception) { + $context = $record['context']; + $exception = $context['exception']; + unset($context['exception']); + + $payload = array(); + if (isset($context['payload'])) { + $payload = $context['payload']; + unset($context['payload']); + } + + $this->rollbarNotifier->report_exception($exception, $context, $payload); + } else { + $extraData = array( + 'level' => $record['level'], + 'channel' => $record['channel'], + 'datetime' => $record['datetime']->format('U'), + ); + + $context = $record['context']; + $payload = array(); + if (isset($context['payload'])) { + $payload = $context['payload']; + unset($context['payload']); + } + + $this->rollbarNotifier->report_message( + $record['message'], + $record['level_name'], + array_merge($record['context'], $record['extra'], $extraData), + $payload + ); + } + + $this->hasRecords = true; + } + + /** + * {@inheritdoc} + */ + public function close() + { + if ($this->hasRecords) { + $this->rollbarNotifier->flush(); + $this->hasRecords = false; + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/RotatingFileHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/RotatingFileHandler.php new file mode 100644 index 0000000..3b60b3d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/RotatingFileHandler.php @@ -0,0 +1,178 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; + +/** + * Stores logs to files that are rotated every day and a limited number of files are kept. + * + * This rotation is only intended to be used as a workaround. Using logrotate to + * handle the rotation is strongly encouraged when you can use it. + * + * @author Christophe Coevoet + * @author Jordi Boggiano + */ +class RotatingFileHandler extends StreamHandler +{ + const FILE_PER_DAY = 'Y-m-d'; + const FILE_PER_MONTH = 'Y-m'; + const FILE_PER_YEAR = 'Y'; + + protected $filename; + protected $maxFiles; + protected $mustRotate; + protected $nextRotation; + protected $filenameFormat; + protected $dateFormat; + + /** + * @param string $filename + * @param int $maxFiles The maximal amount of files to keep (0 means unlimited) + * @param int $level The minimum logging level at which this handler will be triggered + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + * @param int|null $filePermission Optional file permissions (default (0644) are only for owner read/write) + * @param Boolean $useLocking Try to lock log file before doing any writes + */ + public function __construct($filename, $maxFiles = 0, $level = Logger::DEBUG, $bubble = true, $filePermission = null, $useLocking = false) + { + $this->filename = $filename; + $this->maxFiles = (int) $maxFiles; + $this->nextRotation = new \DateTime('tomorrow'); + $this->filenameFormat = '{filename}-{date}'; + $this->dateFormat = 'Y-m-d'; + + parent::__construct($this->getTimedFilename(), $level, $bubble, $filePermission, $useLocking); + } + + /** + * {@inheritdoc} + */ + public function close() + { + parent::close(); + + if (true === $this->mustRotate) { + $this->rotate(); + } + } + + public function setFilenameFormat($filenameFormat, $dateFormat) + { + if (!preg_match('{^Y(([/_.-]?m)([/_.-]?d)?)?$}', $dateFormat)) { + trigger_error( + 'Invalid date format - format must be one of '. + 'RotatingFileHandler::FILE_PER_DAY ("Y-m-d"), RotatingFileHandler::FILE_PER_MONTH ("Y-m") '. + 'or RotatingFileHandler::FILE_PER_YEAR ("Y"), or you can set one of the '. + 'date formats using slashes, underscores and/or dots instead of dashes.', + E_USER_DEPRECATED + ); + } + if (substr_count($filenameFormat, '{date}') === 0) { + trigger_error( + 'Invalid filename format - format should contain at least `{date}`, because otherwise rotating is impossible.', + E_USER_DEPRECATED + ); + } + $this->filenameFormat = $filenameFormat; + $this->dateFormat = $dateFormat; + $this->url = $this->getTimedFilename(); + $this->close(); + } + + /** + * {@inheritdoc} + */ + protected function write(array $record) + { + // on the first record written, if the log is new, we should rotate (once per day) + if (null === $this->mustRotate) { + $this->mustRotate = !file_exists($this->url); + } + + if ($this->nextRotation < $record['datetime']) { + $this->mustRotate = true; + $this->close(); + } + + parent::write($record); + } + + /** + * Rotates the files. + */ + protected function rotate() + { + // update filename + $this->url = $this->getTimedFilename(); + $this->nextRotation = new \DateTime('tomorrow'); + + // skip GC of old logs if files are unlimited + if (0 === $this->maxFiles) { + return; + } + + $logFiles = glob($this->getGlobPattern()); + if ($this->maxFiles >= count($logFiles)) { + // no files to remove + return; + } + + // Sorting the files by name to remove the older ones + usort($logFiles, function ($a, $b) { + return strcmp($b, $a); + }); + + foreach (array_slice($logFiles, $this->maxFiles) as $file) { + if (is_writable($file)) { + // suppress errors here as unlink() might fail if two processes + // are cleaning up/rotating at the same time + set_error_handler(function ($errno, $errstr, $errfile, $errline) {}); + unlink($file); + restore_error_handler(); + } + } + + $this->mustRotate = false; + } + + protected function getTimedFilename() + { + $fileInfo = pathinfo($this->filename); + $timedFilename = str_replace( + array('{filename}', '{date}'), + array($fileInfo['filename'], date($this->dateFormat)), + $fileInfo['dirname'] . '/' . $this->filenameFormat + ); + + if (!empty($fileInfo['extension'])) { + $timedFilename .= '.'.$fileInfo['extension']; + } + + return $timedFilename; + } + + protected function getGlobPattern() + { + $fileInfo = pathinfo($this->filename); + $glob = str_replace( + array('{filename}', '{date}'), + array($fileInfo['filename'], '*'), + $fileInfo['dirname'] . '/' . $this->filenameFormat + ); + if (!empty($fileInfo['extension'])) { + $glob .= '.'.$fileInfo['extension']; + } + + return $glob; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/SamplingHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/SamplingHandler.php new file mode 100644 index 0000000..9509ae3 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/SamplingHandler.php @@ -0,0 +1,82 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +/** + * Sampling handler + * + * A sampled event stream can be useful for logging high frequency events in + * a production environment where you only need an idea of what is happening + * and are not concerned with capturing every occurrence. Since the decision to + * handle or not handle a particular event is determined randomly, the + * resulting sampled log is not guaranteed to contain 1/N of the events that + * occurred in the application, but based on the Law of large numbers, it will + * tend to be close to this ratio with a large number of attempts. + * + * @author Bryan Davis + * @author Kunal Mehta + */ +class SamplingHandler extends AbstractHandler +{ + /** + * @var callable|HandlerInterface $handler + */ + protected $handler; + + /** + * @var int $factor + */ + protected $factor; + + /** + * @param callable|HandlerInterface $handler Handler or factory callable($record, $fingersCrossedHandler). + * @param int $factor Sample factor + */ + public function __construct($handler, $factor) + { + parent::__construct(); + $this->handler = $handler; + $this->factor = $factor; + + if (!$this->handler instanceof HandlerInterface && !is_callable($this->handler)) { + throw new \RuntimeException("The given handler (".json_encode($this->handler).") is not a callable nor a Monolog\Handler\HandlerInterface object"); + } + } + + public function isHandling(array $record) + { + return $this->handler->isHandling($record); + } + + public function handle(array $record) + { + if ($this->isHandling($record) && mt_rand(1, $this->factor) === 1) { + // The same logic as in FingersCrossedHandler + if (!$this->handler instanceof HandlerInterface) { + $this->handler = call_user_func($this->handler, $record, $this); + if (!$this->handler instanceof HandlerInterface) { + throw new \RuntimeException("The factory callable should return a HandlerInterface"); + } + } + + if ($this->processors) { + foreach ($this->processors as $processor) { + $record = call_user_func($processor, $record); + } + } + + $this->handler->handle($record); + } + + return false === $this->bubble; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/SlackHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/SlackHandler.php new file mode 100644 index 0000000..3de2576 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/SlackHandler.php @@ -0,0 +1,295 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; +use Monolog\Formatter\LineFormatter; + +/** + * Sends notifications through Slack API + * + * @author Greg Kedzierski + * @see https://api.slack.com/ + */ +class SlackHandler extends SocketHandler +{ + /** + * Slack API token + * @var string + */ + private $token; + + /** + * Slack channel (encoded ID or name) + * @var string + */ + private $channel; + + /** + * Name of a bot + * @var string + */ + private $username; + + /** + * Emoji icon name + * @var string + */ + private $iconEmoji; + + /** + * Whether the message should be added to Slack as attachment (plain text otherwise) + * @var bool + */ + private $useAttachment; + + /** + * Whether the the context/extra messages added to Slack as attachments are in a short style + * @var bool + */ + private $useShortAttachment; + + /** + * Whether the attachment should include context and extra data + * @var bool + */ + private $includeContextAndExtra; + + /** + * @var LineFormatter + */ + private $lineFormatter; + + /** + * @param string $token Slack API token + * @param string $channel Slack channel (encoded ID or name) + * @param string $username Name of a bot + * @param bool $useAttachment Whether the message should be added to Slack as attachment (plain text otherwise) + * @param string|null $iconEmoji The emoji name to use (or null) + * @param int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + * @param bool $useShortAttachment Whether the the context/extra messages added to Slack as attachments are in a short style + * @param bool $includeContextAndExtra Whether the attachment should include context and extra data + * @throws MissingExtensionException If no OpenSSL PHP extension configured + */ + public function __construct($token, $channel, $username = 'Monolog', $useAttachment = true, $iconEmoji = null, $level = Logger::CRITICAL, $bubble = true, $useShortAttachment = false, $includeContextAndExtra = false) + { + if (!extension_loaded('openssl')) { + throw new MissingExtensionException('The OpenSSL PHP extension is required to use the SlackHandler'); + } + + parent::__construct('ssl://slack.com:443', $level, $bubble); + + $this->token = $token; + $this->channel = $channel; + $this->username = $username; + $this->iconEmoji = trim($iconEmoji, ':'); + $this->useAttachment = $useAttachment; + $this->useShortAttachment = $useShortAttachment; + $this->includeContextAndExtra = $includeContextAndExtra; + + if ($this->includeContextAndExtra && $this->useShortAttachment) { + $this->lineFormatter = new LineFormatter; + } + } + + /** + * {@inheritdoc} + * + * @param array $record + * @return string + */ + protected function generateDataStream($record) + { + $content = $this->buildContent($record); + + return $this->buildHeader($content) . $content; + } + + /** + * Builds the body of API call + * + * @param array $record + * @return string + */ + private function buildContent($record) + { + $dataArray = $this->prepareContentData($record); + + return http_build_query($dataArray); + } + + /** + * Prepares content data + * + * @param array $record + * @return array + */ + protected function prepareContentData($record) + { + $dataArray = array( + 'token' => $this->token, + 'channel' => $this->channel, + 'username' => $this->username, + 'text' => '', + 'attachments' => array(), + ); + + if ($this->formatter) { + $message = $this->formatter->format($record); + } else { + $message = $record['message']; + } + + if ($this->useAttachment) { + $attachment = array( + 'fallback' => $message, + 'color' => $this->getAttachmentColor($record['level']), + 'fields' => array(), + ); + + if ($this->useShortAttachment) { + $attachment['title'] = $record['level_name']; + $attachment['text'] = $message; + } else { + $attachment['title'] = 'Message'; + $attachment['text'] = $message; + $attachment['fields'][] = array( + 'title' => 'Level', + 'value' => $record['level_name'], + 'short' => true, + ); + } + + if ($this->includeContextAndExtra) { + if (!empty($record['extra'])) { + if ($this->useShortAttachment) { + $attachment['fields'][] = array( + 'title' => "Extra", + 'value' => $this->stringify($record['extra']), + 'short' => $this->useShortAttachment, + ); + } else { + // Add all extra fields as individual fields in attachment + foreach ($record['extra'] as $var => $val) { + $attachment['fields'][] = array( + 'title' => $var, + 'value' => $val, + 'short' => $this->useShortAttachment, + ); + } + } + } + + if (!empty($record['context'])) { + if ($this->useShortAttachment) { + $attachment['fields'][] = array( + 'title' => "Context", + 'value' => $this->stringify($record['context']), + 'short' => $this->useShortAttachment, + ); + } else { + // Add all context fields as individual fields in attachment + foreach ($record['context'] as $var => $val) { + $attachment['fields'][] = array( + 'title' => $var, + 'value' => $val, + 'short' => $this->useShortAttachment, + ); + } + } + } + } + + $dataArray['attachments'] = json_encode(array($attachment)); + } else { + $dataArray['text'] = $message; + } + + if ($this->iconEmoji) { + $dataArray['icon_emoji'] = ":{$this->iconEmoji}:"; + } + + return $dataArray; + } + + /** + * Builds the header of the API Call + * + * @param string $content + * @return string + */ + private function buildHeader($content) + { + $header = "POST /api/chat.postMessage HTTP/1.1\r\n"; + $header .= "Host: slack.com\r\n"; + $header .= "Content-Type: application/x-www-form-urlencoded\r\n"; + $header .= "Content-Length: " . strlen($content) . "\r\n"; + $header .= "\r\n"; + + return $header; + } + + /** + * {@inheritdoc} + * + * @param array $record + */ + protected function write(array $record) + { + parent::write($record); + $res = $this->getResource(); + if (is_resource($res)) { + @fread($res, 2048); + } + $this->closeSocket(); + } + + /** + * Returned a Slack message attachment color associated with + * provided level. + * + * @param int $level + * @return string + */ + protected function getAttachmentColor($level) + { + switch (true) { + case $level >= Logger::ERROR: + return 'danger'; + case $level >= Logger::WARNING: + return 'warning'; + case $level >= Logger::INFO: + return 'good'; + default: + return '#e3e4e6'; + } + } + + /** + * Stringifies an array of key/value pairs to be used in attachment fields + * + * @param array $fields + * @return string + */ + protected function stringify($fields) + { + $string = ''; + foreach ($fields as $var => $val) { + $string .= $var.': '.$this->lineFormatter->stringify($val)." | "; + } + + $string = rtrim($string, " |"); + + return $string; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/SocketHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/SocketHandler.php new file mode 100644 index 0000000..7a61bf4 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/SocketHandler.php @@ -0,0 +1,346 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; + +/** + * Stores to any socket - uses fsockopen() or pfsockopen(). + * + * @author Pablo de Leon Belloc + * @see http://php.net/manual/en/function.fsockopen.php + */ +class SocketHandler extends AbstractProcessingHandler +{ + private $connectionString; + private $connectionTimeout; + private $resource; + private $timeout = 0; + private $writingTimeout = 10; + private $lastSentBytes = null; + private $persistent = false; + private $errno; + private $errstr; + private $lastWritingAt; + + /** + * @param string $connectionString Socket connection string + * @param int $level The minimum logging level at which this handler will be triggered + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct($connectionString, $level = Logger::DEBUG, $bubble = true) + { + parent::__construct($level, $bubble); + $this->connectionString = $connectionString; + $this->connectionTimeout = (float) ini_get('default_socket_timeout'); + } + + /** + * Connect (if necessary) and write to the socket + * + * @param array $record + * + * @throws \UnexpectedValueException + * @throws \RuntimeException + */ + protected function write(array $record) + { + $this->connectIfNotConnected(); + $data = $this->generateDataStream($record); + $this->writeToSocket($data); + } + + /** + * We will not close a PersistentSocket instance so it can be reused in other requests. + */ + public function close() + { + if (!$this->isPersistent()) { + $this->closeSocket(); + } + } + + /** + * Close socket, if open + */ + public function closeSocket() + { + if (is_resource($this->resource)) { + fclose($this->resource); + $this->resource = null; + } + } + + /** + * Set socket connection to nbe persistent. It only has effect before the connection is initiated. + * + * @param bool $persistent + */ + public function setPersistent($persistent) + { + $this->persistent = (boolean) $persistent; + } + + /** + * Set connection timeout. Only has effect before we connect. + * + * @param float $seconds + * + * @see http://php.net/manual/en/function.fsockopen.php + */ + public function setConnectionTimeout($seconds) + { + $this->validateTimeout($seconds); + $this->connectionTimeout = (float) $seconds; + } + + /** + * Set write timeout. Only has effect before we connect. + * + * @param float $seconds + * + * @see http://php.net/manual/en/function.stream-set-timeout.php + */ + public function setTimeout($seconds) + { + $this->validateTimeout($seconds); + $this->timeout = (float) $seconds; + } + + /** + * Set writing timeout. Only has effect during connection in the writing cycle. + * + * @param float $seconds 0 for no timeout + */ + public function setWritingTimeout($seconds) + { + $this->validateTimeout($seconds); + $this->writingTimeout = (float) $seconds; + } + + /** + * Get current connection string + * + * @return string + */ + public function getConnectionString() + { + return $this->connectionString; + } + + /** + * Get persistent setting + * + * @return bool + */ + public function isPersistent() + { + return $this->persistent; + } + + /** + * Get current connection timeout setting + * + * @return float + */ + public function getConnectionTimeout() + { + return $this->connectionTimeout; + } + + /** + * Get current in-transfer timeout + * + * @return float + */ + public function getTimeout() + { + return $this->timeout; + } + + /** + * Get current local writing timeout + * + * @return float + */ + public function getWritingTimeout() + { + return $this->writingTimeout; + } + + /** + * Check to see if the socket is currently available. + * + * UDP might appear to be connected but might fail when writing. See http://php.net/fsockopen for details. + * + * @return bool + */ + public function isConnected() + { + return is_resource($this->resource) + && !feof($this->resource); // on TCP - other party can close connection. + } + + /** + * Wrapper to allow mocking + */ + protected function pfsockopen() + { + return @pfsockopen($this->connectionString, -1, $this->errno, $this->errstr, $this->connectionTimeout); + } + + /** + * Wrapper to allow mocking + */ + protected function fsockopen() + { + return @fsockopen($this->connectionString, -1, $this->errno, $this->errstr, $this->connectionTimeout); + } + + /** + * Wrapper to allow mocking + * + * @see http://php.net/manual/en/function.stream-set-timeout.php + */ + protected function streamSetTimeout() + { + $seconds = floor($this->timeout); + $microseconds = round(($this->timeout - $seconds) * 1e6); + + return stream_set_timeout($this->resource, $seconds, $microseconds); + } + + /** + * Wrapper to allow mocking + */ + protected function fwrite($data) + { + return @fwrite($this->resource, $data); + } + + /** + * Wrapper to allow mocking + */ + protected function streamGetMetadata() + { + return stream_get_meta_data($this->resource); + } + + private function validateTimeout($value) + { + $ok = filter_var($value, FILTER_VALIDATE_FLOAT); + if ($ok === false || $value < 0) { + throw new \InvalidArgumentException("Timeout must be 0 or a positive float (got $value)"); + } + } + + private function connectIfNotConnected() + { + if ($this->isConnected()) { + return; + } + $this->connect(); + } + + protected function generateDataStream($record) + { + return (string) $record['formatted']; + } + + /** + * @return resource|null + */ + protected function getResource() + { + return $this->resource; + } + + private function connect() + { + $this->createSocketResource(); + $this->setSocketTimeout(); + } + + private function createSocketResource() + { + if ($this->isPersistent()) { + $resource = $this->pfsockopen(); + } else { + $resource = $this->fsockopen(); + } + if (!$resource) { + throw new \UnexpectedValueException("Failed connecting to $this->connectionString ($this->errno: $this->errstr)"); + } + $this->resource = $resource; + } + + private function setSocketTimeout() + { + if (!$this->streamSetTimeout()) { + throw new \UnexpectedValueException("Failed setting timeout with stream_set_timeout()"); + } + } + + private function writeToSocket($data) + { + $length = strlen($data); + $sent = 0; + $this->lastSentBytes = $sent; + while ($this->isConnected() && $sent < $length) { + if (0 == $sent) { + $chunk = $this->fwrite($data); + } else { + $chunk = $this->fwrite(substr($data, $sent)); + } + if ($chunk === false) { + throw new \RuntimeException("Could not write to socket"); + } + $sent += $chunk; + $socketInfo = $this->streamGetMetadata(); + if ($socketInfo['timed_out']) { + throw new \RuntimeException("Write timed-out"); + } + + if ($this->writingIsTimedOut($sent)) { + throw new \RuntimeException("Write timed-out, no data sent for `{$this->writingTimeout}` seconds, probably we got disconnected (sent $sent of $length)"); + } + } + if (!$this->isConnected() && $sent < $length) { + throw new \RuntimeException("End-of-file reached, probably we got disconnected (sent $sent of $length)"); + } + } + + private function writingIsTimedOut($sent) + { + $writingTimeout = (int) floor($this->writingTimeout); + if (0 === $writingTimeout) { + return false; + } + + if ($sent !== $this->lastSentBytes) { + $this->lastWritingAt = time(); + $this->lastSentBytes = $sent; + + return false; + } else { + usleep(100); + } + + if ((time() - $this->lastWritingAt) >= $writingTimeout) { + $this->closeSocket(); + + return true; + } + + return false; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php new file mode 100644 index 0000000..b084f1a --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php @@ -0,0 +1,166 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; + +/** + * Stores to any stream resource + * + * Can be used to store into php://stderr, remote and local files, etc. + * + * @author Jordi Boggiano + */ +class StreamHandler extends AbstractProcessingHandler +{ + protected $stream; + protected $url; + private $errorMessage; + protected $filePermission; + protected $useLocking; + private $dirCreated; + + /** + * @param resource|string $stream + * @param int $level The minimum logging level at which this handler will be triggered + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + * @param int|null $filePermission Optional file permissions (default (0644) are only for owner read/write) + * @param Boolean $useLocking Try to lock log file before doing any writes + * + * @throws \Exception If a missing directory is not buildable + * @throws \InvalidArgumentException If stream is not a resource or string + */ + public function __construct($stream, $level = Logger::DEBUG, $bubble = true, $filePermission = null, $useLocking = false) + { + parent::__construct($level, $bubble); + if (is_resource($stream)) { + $this->stream = $stream; + } elseif (is_string($stream)) { + $this->url = $stream; + } else { + throw new \InvalidArgumentException('A stream must either be a resource or a string.'); + } + + $this->filePermission = $filePermission; + $this->useLocking = $useLocking; + } + + /** + * {@inheritdoc} + */ + public function close() + { + if ($this->url && is_resource($this->stream)) { + fclose($this->stream); + } + $this->stream = null; + } + + /** + * Return the currently active stream if it is open + * + * @return resource|null + */ + public function getStream() + { + return $this->stream; + } + + /** + * Return the stream URL if it was configured with a URL and not an active resource + * + * @return string|null + */ + public function getUrl() + { + return $this->url; + } + + /** + * {@inheritdoc} + */ + protected function write(array $record) + { + if (!is_resource($this->stream)) { + if (null === $this->url || '' === $this->url) { + throw new \LogicException('Missing stream url, the stream can not be opened. This may be caused by a premature call to close().'); + } + $this->createDir(); + $this->errorMessage = null; + set_error_handler(array($this, 'customErrorHandler')); + $this->stream = fopen($this->url, 'a'); + if ($this->filePermission !== null) { + @chmod($this->url, $this->filePermission); + } + restore_error_handler(); + if (!is_resource($this->stream)) { + $this->stream = null; + throw new \UnexpectedValueException(sprintf('The stream or file "%s" could not be opened: '.$this->errorMessage, $this->url)); + } + } + + if ($this->useLocking) { + // ignoring errors here, there's not much we can do about them + flock($this->stream, LOCK_EX); + } + + fwrite($this->stream, (string) $record['formatted']); + + if ($this->useLocking) { + flock($this->stream, LOCK_UN); + } + } + + private function customErrorHandler($code, $msg) + { + $this->errorMessage = preg_replace('{^(fopen|mkdir)\(.*?\): }', '', $msg); + } + + /** + * @param string $stream + * + * @return null|string + */ + private function getDirFromStream($stream) + { + $pos = strpos($stream, '://'); + if ($pos === false) { + return dirname($stream); + } + + if ('file://' === substr($stream, 0, 7)) { + return dirname(substr($stream, 7)); + } + + return; + } + + private function createDir() + { + // Do not try to create dir if it has already been tried. + if ($this->dirCreated) { + return; + } + + $dir = $this->getDirFromStream($this->url); + if (null !== $dir && !is_dir($dir)) { + $this->errorMessage = null; + set_error_handler(array($this, 'customErrorHandler')); + $status = mkdir($dir, 0777, true); + restore_error_handler(); + if (false === $status) { + throw new \UnexpectedValueException(sprintf('There is no existing directory at "%s" and its not buildable: '.$this->errorMessage, $dir)); + } + } + $this->dirCreated = true; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/SwiftMailerHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/SwiftMailerHandler.php new file mode 100644 index 0000000..aba1396 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/SwiftMailerHandler.php @@ -0,0 +1,94 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; +use Monolog\Formatter\LineFormatter; + +/** + * SwiftMailerHandler uses Swift_Mailer to send the emails + * + * @author Gyula Sallai + */ +class SwiftMailerHandler extends MailHandler +{ + protected $mailer; + private $messageTemplate; + + /** + * @param \Swift_Mailer $mailer The mailer to use + * @param callable|\Swift_Message $message An example message for real messages, only the body will be replaced + * @param int $level The minimum logging level at which this handler will be triggered + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct(\Swift_Mailer $mailer, $message, $level = Logger::ERROR, $bubble = true) + { + parent::__construct($level, $bubble); + + $this->mailer = $mailer; + $this->messageTemplate = $message; + } + + /** + * {@inheritdoc} + */ + protected function send($content, array $records) + { + $this->mailer->send($this->buildMessage($content, $records)); + } + + /** + * Creates instance of Swift_Message to be sent + * + * @param string $content formatted email body to be sent + * @param array $records Log records that formed the content + * @return \Swift_Message + */ + protected function buildMessage($content, array $records) + { + $message = null; + if ($this->messageTemplate instanceof \Swift_Message) { + $message = clone $this->messageTemplate; + $message->generateId(); + } elseif (is_callable($this->messageTemplate)) { + $message = call_user_func($this->messageTemplate, $content, $records); + } + + if (!$message instanceof \Swift_Message) { + throw new \InvalidArgumentException('Could not resolve message as instance of Swift_Message or a callable returning it'); + } + + if ($records) { + $subjectFormatter = new LineFormatter($message->getSubject()); + $message->setSubject($subjectFormatter->format($this->getHighestRecord($records))); + } + + $message->setBody($content); + $message->setDate(time()); + + return $message; + } + + /** + * BC getter, to be removed in 2.0 + */ + public function __get($name) + { + if ($name === 'message') { + trigger_error('SwiftMailerHandler->message is deprecated, use ->buildMessage() instead to retrieve the message', E_USER_DEPRECATED); + + return $this->buildMessage(null, array()); + } + + throw new \InvalidArgumentException('Invalid property '.$name); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/SyslogHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/SyslogHandler.php new file mode 100644 index 0000000..376bc3b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/SyslogHandler.php @@ -0,0 +1,67 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; + +/** + * Logs to syslog service. + * + * usage example: + * + * $log = new Logger('application'); + * $syslog = new SyslogHandler('myfacility', 'local6'); + * $formatter = new LineFormatter("%channel%.%level_name%: %message% %extra%"); + * $syslog->setFormatter($formatter); + * $log->pushHandler($syslog); + * + * @author Sven Paulus + */ +class SyslogHandler extends AbstractSyslogHandler +{ + protected $ident; + protected $logopts; + + /** + * @param string $ident + * @param mixed $facility + * @param int $level The minimum logging level at which this handler will be triggered + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + * @param int $logopts Option flags for the openlog() call, defaults to LOG_PID + */ + public function __construct($ident, $facility = LOG_USER, $level = Logger::DEBUG, $bubble = true, $logopts = LOG_PID) + { + parent::__construct($facility, $level, $bubble); + + $this->ident = $ident; + $this->logopts = $logopts; + } + + /** + * {@inheritdoc} + */ + public function close() + { + closelog(); + } + + /** + * {@inheritdoc} + */ + protected function write(array $record) + { + if (!openlog($this->ident, $this->logopts, $this->facility)) { + throw new \LogicException('Can\'t open syslog for ident "'.$this->ident.'" and facility "'.$this->facility.'"'); + } + syslog($this->logLevels[$record['level']], (string) $record['formatted']); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/SyslogUdp/UdpSocket.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/SyslogUdp/UdpSocket.php new file mode 100644 index 0000000..3bff085 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/SyslogUdp/UdpSocket.php @@ -0,0 +1,56 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler\SyslogUdp; + +class UdpSocket +{ + const DATAGRAM_MAX_LENGTH = 65023; + + protected $ip; + protected $port; + protected $socket; + + public function __construct($ip, $port = 514) + { + $this->ip = $ip; + $this->port = $port; + $this->socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); + } + + public function write($line, $header = "") + { + $this->send($this->assembleMessage($line, $header)); + } + + public function close() + { + if (is_resource($this->socket)) { + socket_close($this->socket); + $this->socket = null; + } + } + + protected function send($chunk) + { + if (!is_resource($this->socket)) { + throw new \LogicException('The UdpSocket to '.$this->ip.':'.$this->port.' has been closed and can not be written to anymore'); + } + socket_sendto($this->socket, $chunk, strlen($chunk), $flags = 0, $this->ip, $this->port); + } + + protected function assembleMessage($line, $header) + { + $chunkSize = self::DATAGRAM_MAX_LENGTH - strlen($header); + + return $header . substr($line, 0, $chunkSize); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/SyslogUdpHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/SyslogUdpHandler.php new file mode 100644 index 0000000..b175cc3 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/SyslogUdpHandler.php @@ -0,0 +1,82 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; +use Monolog\Handler\SyslogUdp\UdpSocket; + +/** + * A Handler for logging to a remote syslogd server. + * + * @author Jesper Skovgaard Nielsen + */ +class SyslogUdpHandler extends AbstractSyslogHandler +{ + protected $socket; + + /** + * @param string $host + * @param int $port + * @param mixed $facility + * @param int $level The minimum logging level at which this handler will be triggered + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct($host, $port = 514, $facility = LOG_USER, $level = Logger::DEBUG, $bubble = true) + { + parent::__construct($facility, $level, $bubble); + + $this->socket = new UdpSocket($host, $port ?: 514); + } + + protected function write(array $record) + { + $lines = $this->splitMessageIntoLines($record['formatted']); + + $header = $this->makeCommonSyslogHeader($this->logLevels[$record['level']]); + + foreach ($lines as $line) { + $this->socket->write($line, $header); + } + } + + public function close() + { + $this->socket->close(); + } + + private function splitMessageIntoLines($message) + { + if (is_array($message)) { + $message = implode("\n", $message); + } + + return preg_split('/$\R?^/m', $message); + } + + /** + * Make common syslog header (see rfc5424) + */ + protected function makeCommonSyslogHeader($severity) + { + $priority = $severity + $this->facility; + + return "<$priority>1 "; + } + + /** + * Inject your own socket, mainly used for testing + */ + public function setSocket($socket) + { + $this->socket = $socket; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/TestHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/TestHandler.php new file mode 100644 index 0000000..458020b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/TestHandler.php @@ -0,0 +1,154 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +/** + * Used for testing purposes. + * + * It records all records and gives you access to them for verification. + * + * @author Jordi Boggiano + * + * @method bool hasEmergency($record) + * @method bool hasAlert($record) + * @method bool hasCritical($record) + * @method bool hasError($record) + * @method bool hasWarning($record) + * @method bool hasNotice($record) + * @method bool hasInfo($record) + * @method bool hasDebug($record) + * + * @method bool hasEmergencyRecords() + * @method bool hasAlertRecords() + * @method bool hasCriticalRecords() + * @method bool hasErrorRecords() + * @method bool hasWarningRecords() + * @method bool hasNoticeRecords() + * @method bool hasInfoRecords() + * @method bool hasDebugRecords() + * + * @method bool hasEmergencyThatContains($message) + * @method bool hasAlertThatContains($message) + * @method bool hasCriticalThatContains($message) + * @method bool hasErrorThatContains($message) + * @method bool hasWarningThatContains($message) + * @method bool hasNoticeThatContains($message) + * @method bool hasInfoThatContains($message) + * @method bool hasDebugThatContains($message) + * + * @method bool hasEmergencyThatMatches($message) + * @method bool hasAlertThatMatches($message) + * @method bool hasCriticalThatMatches($message) + * @method bool hasErrorThatMatches($message) + * @method bool hasWarningThatMatches($message) + * @method bool hasNoticeThatMatches($message) + * @method bool hasInfoThatMatches($message) + * @method bool hasDebugThatMatches($message) + * + * @method bool hasEmergencyThatPasses($message) + * @method bool hasAlertThatPasses($message) + * @method bool hasCriticalThatPasses($message) + * @method bool hasErrorThatPasses($message) + * @method bool hasWarningThatPasses($message) + * @method bool hasNoticeThatPasses($message) + * @method bool hasInfoThatPasses($message) + * @method bool hasDebugThatPasses($message) + */ +class TestHandler extends AbstractProcessingHandler +{ + protected $records = array(); + protected $recordsByLevel = array(); + + public function getRecords() + { + return $this->records; + } + + public function clear() + { + $this->records = array(); + $this->recordsByLevel = array(); + } + + protected function hasRecordRecords($level) + { + return isset($this->recordsByLevel[$level]); + } + + protected function hasRecord($record, $level) + { + if (is_array($record)) { + $record = $record['message']; + } + + return $this->hasRecordThatPasses(function ($rec) use ($record) { + return $rec['message'] === $record; + }, $level); + } + + public function hasRecordThatContains($message, $level) + { + return $this->hasRecordThatPasses(function ($rec) use ($message) { + return strpos($rec['message'], $message) !== false; + }, $level); + } + + public function hasRecordThatMatches($regex, $level) + { + return $this->hasRecordThatPasses(function ($rec) use ($regex) { + return preg_match($regex, $rec['message']) > 0; + }, $level); + } + + public function hasRecordThatPasses($predicate, $level) + { + if (!is_callable($predicate)) { + throw new \InvalidArgumentException("Expected a callable for hasRecordThatSucceeds"); + } + + if (!isset($this->recordsByLevel[$level])) { + return false; + } + + foreach ($this->recordsByLevel[$level] as $i => $rec) { + if (call_user_func($predicate, $rec, $i)) { + return true; + } + } + + return false; + } + + /** + * {@inheritdoc} + */ + protected function write(array $record) + { + $this->recordsByLevel[$record['level']][] = $record; + $this->records[] = $record; + } + + public function __call($method, $args) + { + if (preg_match('/(.*)(Debug|Info|Notice|Warning|Error|Critical|Alert|Emergency)(.*)/', $method, $matches) > 0) { + $genericMethod = $matches[1] . 'Record' . $matches[3]; + $level = constant('Monolog\Logger::' . strtoupper($matches[2])); + if (method_exists($this, $genericMethod)) { + $args[] = $level; + + return call_user_func_array(array($this, $genericMethod), $args); + } + } + + throw new \BadMethodCallException('Call to undefined method ' . get_class($this) . '::' . $method . '()'); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/WhatFailureGroupHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/WhatFailureGroupHandler.php new file mode 100644 index 0000000..2732ba3 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/WhatFailureGroupHandler.php @@ -0,0 +1,61 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +/** + * Forwards records to multiple handlers suppressing failures of each handler + * and continuing through to give every handler a chance to succeed. + * + * @author Craig D'Amelio + */ +class WhatFailureGroupHandler extends GroupHandler +{ + /** + * {@inheritdoc} + */ + public function handle(array $record) + { + if ($this->processors) { + foreach ($this->processors as $processor) { + $record = call_user_func($processor, $record); + } + } + + foreach ($this->handlers as $handler) { + try { + $handler->handle($record); + } catch (\Exception $e) { + // What failure? + } catch (\Throwable $e) { + // What failure? + } + } + + return false === $this->bubble; + } + + /** + * {@inheritdoc} + */ + public function handleBatch(array $records) + { + foreach ($this->handlers as $handler) { + try { + $handler->handleBatch($records); + } catch (\Exception $e) { + // What failure? + } catch (\Throwable $e) { + // What failure? + } + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/ZendMonitorHandler.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/ZendMonitorHandler.php new file mode 100644 index 0000000..f22cf21 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Handler/ZendMonitorHandler.php @@ -0,0 +1,95 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Formatter\NormalizerFormatter; +use Monolog\Logger; + +/** + * Handler sending logs to Zend Monitor + * + * @author Christian Bergau + */ +class ZendMonitorHandler extends AbstractProcessingHandler +{ + /** + * Monolog level / ZendMonitor Custom Event priority map + * + * @var array + */ + protected $levelMap = array( + Logger::DEBUG => 1, + Logger::INFO => 2, + Logger::NOTICE => 3, + Logger::WARNING => 4, + Logger::ERROR => 5, + Logger::CRITICAL => 6, + Logger::ALERT => 7, + Logger::EMERGENCY => 0, + ); + + /** + * Construct + * + * @param int $level + * @param bool $bubble + * @throws MissingExtensionException + */ + public function __construct($level = Logger::DEBUG, $bubble = true) + { + if (!function_exists('zend_monitor_custom_event')) { + throw new MissingExtensionException('You must have Zend Server installed in order to use this handler'); + } + parent::__construct($level, $bubble); + } + + /** + * {@inheritdoc} + */ + protected function write(array $record) + { + $this->writeZendMonitorCustomEvent( + $this->levelMap[$record['level']], + $record['message'], + $record['formatted'] + ); + } + + /** + * Write a record to Zend Monitor + * + * @param int $level + * @param string $message + * @param array $formatted + */ + protected function writeZendMonitorCustomEvent($level, $message, $formatted) + { + zend_monitor_custom_event($level, $message, $formatted); + } + + /** + * {@inheritdoc} + */ + public function getDefaultFormatter() + { + return new NormalizerFormatter(); + } + + /** + * Get the level map + * + * @return array + */ + public function getLevelMap() + { + return $this->levelMap; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Logger.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Logger.php new file mode 100644 index 0000000..2fbc02c --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Logger.php @@ -0,0 +1,699 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog; + +use Monolog\Handler\HandlerInterface; +use Monolog\Handler\StreamHandler; +use Psr\Log\LoggerInterface; +use Psr\Log\InvalidArgumentException; + +/** + * Monolog log channel + * + * It contains a stack of Handlers and a stack of Processors, + * and uses them to store records that are added to it. + * + * @author Jordi Boggiano + */ +class Logger implements LoggerInterface +{ + /** + * Detailed debug information + */ + const DEBUG = 100; + + /** + * Interesting events + * + * Examples: User logs in, SQL logs. + */ + const INFO = 200; + + /** + * Uncommon events + */ + const NOTICE = 250; + + /** + * Exceptional occurrences that are not errors + * + * Examples: Use of deprecated APIs, poor use of an API, + * undesirable things that are not necessarily wrong. + */ + const WARNING = 300; + + /** + * Runtime errors + */ + const ERROR = 400; + + /** + * Critical conditions + * + * Example: Application component unavailable, unexpected exception. + */ + const CRITICAL = 500; + + /** + * Action must be taken immediately + * + * Example: Entire website down, database unavailable, etc. + * This should trigger the SMS alerts and wake you up. + */ + const ALERT = 550; + + /** + * Urgent alert. + */ + const EMERGENCY = 600; + + /** + * Monolog API version + * + * This is only bumped when API breaks are done and should + * follow the major version of the library + * + * @var int + */ + const API = 1; + + /** + * Logging levels from syslog protocol defined in RFC 5424 + * + * @var array $levels Logging levels + */ + protected static $levels = array( + self::DEBUG => 'DEBUG', + self::INFO => 'INFO', + self::NOTICE => 'NOTICE', + self::WARNING => 'WARNING', + self::ERROR => 'ERROR', + self::CRITICAL => 'CRITICAL', + self::ALERT => 'ALERT', + self::EMERGENCY => 'EMERGENCY', + ); + + /** + * @var \DateTimeZone + */ + protected static $timezone; + + /** + * @var string + */ + protected $name; + + /** + * The handler stack + * + * @var HandlerInterface[] + */ + protected $handlers; + + /** + * Processors that will process all log records + * + * To process records of a single handler instead, add the processor on that specific handler + * + * @var callable[] + */ + protected $processors; + + /** + * @var bool + */ + protected $microsecondTimestamps = true; + + /** + * @param string $name The logging channel + * @param HandlerInterface[] $handlers Optional stack of handlers, the first one in the array is called first, etc. + * @param callable[] $processors Optional array of processors + */ + public function __construct($name, array $handlers = array(), array $processors = array()) + { + $this->name = $name; + $this->handlers = $handlers; + $this->processors = $processors; + } + + /** + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * Return a new cloned instance with the name changed + * + * @return static + */ + public function withName($name) + { + $new = clone $this; + $new->name = $name; + + return $new; + } + + /** + * Pushes a handler on to the stack. + * + * @param HandlerInterface $handler + * @return $this + */ + public function pushHandler(HandlerInterface $handler) + { + array_unshift($this->handlers, $handler); + + return $this; + } + + /** + * Pops a handler from the stack + * + * @return HandlerInterface + */ + public function popHandler() + { + if (!$this->handlers) { + throw new \LogicException('You tried to pop from an empty handler stack.'); + } + + return array_shift($this->handlers); + } + + /** + * Set handlers, replacing all existing ones. + * + * If a map is passed, keys will be ignored. + * + * @param HandlerInterface[] $handlers + * @return $this + */ + public function setHandlers(array $handlers) + { + $this->handlers = array(); + foreach (array_reverse($handlers) as $handler) { + $this->pushHandler($handler); + } + + return $this; + } + + /** + * @return HandlerInterface[] + */ + public function getHandlers() + { + return $this->handlers; + } + + /** + * Adds a processor on to the stack. + * + * @param callable $callback + * @return $this + */ + public function pushProcessor($callback) + { + if (!is_callable($callback)) { + throw new \InvalidArgumentException('Processors must be valid callables (callback or object with an __invoke method), '.var_export($callback, true).' given'); + } + array_unshift($this->processors, $callback); + + return $this; + } + + /** + * Removes the processor on top of the stack and returns it. + * + * @return callable + */ + public function popProcessor() + { + if (!$this->processors) { + throw new \LogicException('You tried to pop from an empty processor stack.'); + } + + return array_shift($this->processors); + } + + /** + * @return callable[] + */ + public function getProcessors() + { + return $this->processors; + } + + /** + * Control the use of microsecond resolution timestamps in the 'datetime' + * member of new records. + * + * Generating microsecond resolution timestamps by calling + * microtime(true), formatting the result via sprintf() and then parsing + * the resulting string via \DateTime::createFromFormat() can incur + * a measurable runtime overhead vs simple usage of DateTime to capture + * a second resolution timestamp in systems which generate a large number + * of log events. + * + * @param bool $micro True to use microtime() to create timestamps + */ + public function useMicrosecondTimestamps($micro) + { + $this->microsecondTimestamps = (bool) $micro; + } + + /** + * Adds a log record. + * + * @param int $level The logging level + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function addRecord($level, $message, array $context = array()) + { + if (!$this->handlers) { + $this->pushHandler(new StreamHandler('php://stderr', static::DEBUG)); + } + + $levelName = static::getLevelName($level); + + // check if any handler will handle this message so we can return early and save cycles + $handlerKey = null; + reset($this->handlers); + while ($handler = current($this->handlers)) { + if ($handler->isHandling(array('level' => $level))) { + $handlerKey = key($this->handlers); + break; + } + + next($this->handlers); + } + + if (null === $handlerKey) { + return false; + } + + if (!static::$timezone) { + static::$timezone = new \DateTimeZone(date_default_timezone_get() ?: 'UTC'); + } + + if ($this->microsecondTimestamps) { + $ts = \DateTime::createFromFormat('U.u', sprintf('%.6F', microtime(true)), static::$timezone); + } else { + $ts = new \DateTime(null, static::$timezone); + } + $ts->setTimezone(static::$timezone); + + $record = array( + 'message' => (string) $message, + 'context' => $context, + 'level' => $level, + 'level_name' => $levelName, + 'channel' => $this->name, + 'datetime' => $ts, + 'extra' => array(), + ); + + foreach ($this->processors as $processor) { + $record = call_user_func($processor, $record); + } + + while ($handler = current($this->handlers)) { + if (true === $handler->handle($record)) { + break; + } + + next($this->handlers); + } + + return true; + } + + /** + * Adds a log record at the DEBUG level. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function addDebug($message, array $context = array()) + { + return $this->addRecord(static::DEBUG, $message, $context); + } + + /** + * Adds a log record at the INFO level. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function addInfo($message, array $context = array()) + { + return $this->addRecord(static::INFO, $message, $context); + } + + /** + * Adds a log record at the NOTICE level. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function addNotice($message, array $context = array()) + { + return $this->addRecord(static::NOTICE, $message, $context); + } + + /** + * Adds a log record at the WARNING level. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function addWarning($message, array $context = array()) + { + return $this->addRecord(static::WARNING, $message, $context); + } + + /** + * Adds a log record at the ERROR level. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function addError($message, array $context = array()) + { + return $this->addRecord(static::ERROR, $message, $context); + } + + /** + * Adds a log record at the CRITICAL level. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function addCritical($message, array $context = array()) + { + return $this->addRecord(static::CRITICAL, $message, $context); + } + + /** + * Adds a log record at the ALERT level. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function addAlert($message, array $context = array()) + { + return $this->addRecord(static::ALERT, $message, $context); + } + + /** + * Adds a log record at the EMERGENCY level. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function addEmergency($message, array $context = array()) + { + return $this->addRecord(static::EMERGENCY, $message, $context); + } + + /** + * Gets all supported logging levels. + * + * @return array Assoc array with human-readable level names => level codes. + */ + public static function getLevels() + { + return array_flip(static::$levels); + } + + /** + * Gets the name of the logging level. + * + * @param int $level + * @return string + */ + public static function getLevelName($level) + { + if (!isset(static::$levels[$level])) { + throw new InvalidArgumentException('Level "'.$level.'" is not defined, use one of: '.implode(', ', array_keys(static::$levels))); + } + + return static::$levels[$level]; + } + + /** + * Converts PSR-3 levels to Monolog ones if necessary + * + * @param string|int Level number (monolog) or name (PSR-3) + * @return int + */ + public static function toMonologLevel($level) + { + if (is_string($level) && defined(__CLASS__.'::'.strtoupper($level))) { + return constant(__CLASS__.'::'.strtoupper($level)); + } + + return $level; + } + + /** + * Checks whether the Logger has a handler that listens on the given level + * + * @param int $level + * @return Boolean + */ + public function isHandling($level) + { + $record = array( + 'level' => $level, + ); + + foreach ($this->handlers as $handler) { + if ($handler->isHandling($record)) { + return true; + } + } + + return false; + } + + /** + * Adds a log record at an arbitrary level. + * + * This method allows for compatibility with common interfaces. + * + * @param mixed $level The log level + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function log($level, $message, array $context = array()) + { + $level = static::toMonologLevel($level); + + return $this->addRecord($level, $message, $context); + } + + /** + * Adds a log record at the DEBUG level. + * + * This method allows for compatibility with common interfaces. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function debug($message, array $context = array()) + { + return $this->addRecord(static::DEBUG, $message, $context); + } + + /** + * Adds a log record at the INFO level. + * + * This method allows for compatibility with common interfaces. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function info($message, array $context = array()) + { + return $this->addRecord(static::INFO, $message, $context); + } + + /** + * Adds a log record at the NOTICE level. + * + * This method allows for compatibility with common interfaces. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function notice($message, array $context = array()) + { + return $this->addRecord(static::NOTICE, $message, $context); + } + + /** + * Adds a log record at the WARNING level. + * + * This method allows for compatibility with common interfaces. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function warn($message, array $context = array()) + { + return $this->addRecord(static::WARNING, $message, $context); + } + + /** + * Adds a log record at the WARNING level. + * + * This method allows for compatibility with common interfaces. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function warning($message, array $context = array()) + { + return $this->addRecord(static::WARNING, $message, $context); + } + + /** + * Adds a log record at the ERROR level. + * + * This method allows for compatibility with common interfaces. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function err($message, array $context = array()) + { + return $this->addRecord(static::ERROR, $message, $context); + } + + /** + * Adds a log record at the ERROR level. + * + * This method allows for compatibility with common interfaces. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function error($message, array $context = array()) + { + return $this->addRecord(static::ERROR, $message, $context); + } + + /** + * Adds a log record at the CRITICAL level. + * + * This method allows for compatibility with common interfaces. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function crit($message, array $context = array()) + { + return $this->addRecord(static::CRITICAL, $message, $context); + } + + /** + * Adds a log record at the CRITICAL level. + * + * This method allows for compatibility with common interfaces. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function critical($message, array $context = array()) + { + return $this->addRecord(static::CRITICAL, $message, $context); + } + + /** + * Adds a log record at the ALERT level. + * + * This method allows for compatibility with common interfaces. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function alert($message, array $context = array()) + { + return $this->addRecord(static::ALERT, $message, $context); + } + + /** + * Adds a log record at the EMERGENCY level. + * + * This method allows for compatibility with common interfaces. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function emerg($message, array $context = array()) + { + return $this->addRecord(static::EMERGENCY, $message, $context); + } + + /** + * Adds a log record at the EMERGENCY level. + * + * This method allows for compatibility with common interfaces. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function emergency($message, array $context = array()) + { + return $this->addRecord(static::EMERGENCY, $message, $context); + } + + /** + * Set the timezone to be used for the timestamp of log records. + * + * This is stored globally for all Logger instances + * + * @param \DateTimeZone $tz Timezone object + */ + public static function setTimezone(\DateTimeZone $tz) + { + self::$timezone = $tz; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Processor/GitProcessor.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Processor/GitProcessor.php new file mode 100644 index 0000000..1899400 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Processor/GitProcessor.php @@ -0,0 +1,64 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Processor; + +use Monolog\Logger; + +/** + * Injects Git branch and Git commit SHA in all records + * + * @author Nick Otter + * @author Jordi Boggiano + */ +class GitProcessor +{ + private $level; + private static $cache; + + public function __construct($level = Logger::DEBUG) + { + $this->level = Logger::toMonologLevel($level); + } + + /** + * @param array $record + * @return array + */ + public function __invoke(array $record) + { + // return if the level is not high enough + if ($record['level'] < $this->level) { + return $record; + } + + $record['extra']['git'] = self::getGitInfo(); + + return $record; + } + + private static function getGitInfo() + { + if (self::$cache) { + return self::$cache; + } + + $branches = `git branch -v --no-abbrev`; + if (preg_match('{^\* (.+?)\s+([a-f0-9]{40})(?:\s|$)}m', $branches, $matches)) { + return self::$cache = array( + 'branch' => $matches[1], + 'commit' => $matches[2], + ); + } + + return self::$cache = array(); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Processor/IntrospectionProcessor.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Processor/IntrospectionProcessor.php new file mode 100644 index 0000000..2691630 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Processor/IntrospectionProcessor.php @@ -0,0 +1,107 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Processor; + +use Monolog\Logger; + +/** + * Injects line/file:class/function where the log message came from + * + * Warning: This only works if the handler processes the logs directly. + * If you put the processor on a handler that is behind a FingersCrossedHandler + * for example, the processor will only be called once the trigger level is reached, + * and all the log records will have the same file/line/.. data from the call that + * triggered the FingersCrossedHandler. + * + * @author Jordi Boggiano + */ +class IntrospectionProcessor +{ + private $level; + + private $skipClassesPartials; + + private $skipStackFramesCount; + + private $skipFunctions = array( + 'call_user_func', + 'call_user_func_array', + ); + + public function __construct($level = Logger::DEBUG, array $skipClassesPartials = array(), $skipStackFramesCount = 0) + { + $this->level = Logger::toMonologLevel($level); + $this->skipClassesPartials = array_merge(array('Monolog\\'), $skipClassesPartials); + $this->skipStackFramesCount = $skipStackFramesCount; + } + + /** + * @param array $record + * @return array + */ + public function __invoke(array $record) + { + // return if the level is not high enough + if ($record['level'] < $this->level) { + return $record; + } + + $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); + + // skip first since it's always the current method + array_shift($trace); + // the call_user_func call is also skipped + array_shift($trace); + + $i = 0; + + while ($this->isTraceClassOrSkippedFunction($trace, $i)) { + if (isset($trace[$i]['class'])) { + foreach ($this->skipClassesPartials as $part) { + if (strpos($trace[$i]['class'], $part) !== false) { + $i++; + continue 2; + } + } + } elseif (in_array($trace[$i]['function'], $this->skipFunctions)) { + $i++; + continue; + } + + break; + } + + $i += $this->skipStackFramesCount; + + // we should have the call source now + $record['extra'] = array_merge( + $record['extra'], + array( + 'file' => isset($trace[$i - 1]['file']) ? $trace[$i - 1]['file'] : null, + 'line' => isset($trace[$i - 1]['line']) ? $trace[$i - 1]['line'] : null, + 'class' => isset($trace[$i]['class']) ? $trace[$i]['class'] : null, + 'function' => isset($trace[$i]['function']) ? $trace[$i]['function'] : null, + ) + ); + + return $record; + } + + private function isTraceClassOrSkippedFunction(array $trace, $index) + { + if (!isset($trace[$index])) { + return false; + } + + return isset($trace[$index]['class']) || in_array($trace[$index]['function'], $this->skipFunctions); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Processor/MemoryPeakUsageProcessor.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Processor/MemoryPeakUsageProcessor.php new file mode 100644 index 0000000..0543e92 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Processor/MemoryPeakUsageProcessor.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Processor; + +/** + * Injects memory_get_peak_usage in all records + * + * @see Monolog\Processor\MemoryProcessor::__construct() for options + * @author Rob Jensen + */ +class MemoryPeakUsageProcessor extends MemoryProcessor +{ + /** + * @param array $record + * @return array + */ + public function __invoke(array $record) + { + $bytes = memory_get_peak_usage($this->realUsage); + $formatted = $this->formatBytes($bytes); + + $record['extra']['memory_peak_usage'] = $formatted; + + return $record; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Processor/MemoryProcessor.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Processor/MemoryProcessor.php new file mode 100644 index 0000000..85f9dc5 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Processor/MemoryProcessor.php @@ -0,0 +1,63 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Processor; + +/** + * Some methods that are common for all memory processors + * + * @author Rob Jensen + */ +abstract class MemoryProcessor +{ + /** + * @var bool If true, get the real size of memory allocated from system. Else, only the memory used by emalloc() is reported. + */ + protected $realUsage; + + /** + * @var bool If true, then format memory size to human readable string (MB, KB, B depending on size) + */ + protected $useFormatting; + + /** + * @param bool $realUsage Set this to true to get the real size of memory allocated from system. + * @param bool $useFormatting If true, then format memory size to human readable string (MB, KB, B depending on size) + */ + public function __construct($realUsage = true, $useFormatting = true) + { + $this->realUsage = (boolean) $realUsage; + $this->useFormatting = (boolean) $useFormatting; + } + + /** + * Formats bytes into a human readable string if $this->useFormatting is true, otherwise return $bytes as is + * + * @param int $bytes + * @return string|int Formatted string if $this->useFormatting is true, otherwise return $bytes as is + */ + protected function formatBytes($bytes) + { + $bytes = (int) $bytes; + + if (!$this->useFormatting) { + return $bytes; + } + + if ($bytes > 1024 * 1024) { + return round($bytes / 1024 / 1024, 2).' MB'; + } elseif ($bytes > 1024) { + return round($bytes / 1024, 2).' KB'; + } + + return $bytes . ' B'; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Processor/MemoryUsageProcessor.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Processor/MemoryUsageProcessor.php new file mode 100644 index 0000000..2783d65 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Processor/MemoryUsageProcessor.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Processor; + +/** + * Injects memory_get_usage in all records + * + * @see Monolog\Processor\MemoryProcessor::__construct() for options + * @author Rob Jensen + */ +class MemoryUsageProcessor extends MemoryProcessor +{ + /** + * @param array $record + * @return array + */ + public function __invoke(array $record) + { + $bytes = memory_get_usage($this->realUsage); + $formatted = $this->formatBytes($bytes); + + $record['extra']['memory_usage'] = $formatted; + + return $record; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Processor/ProcessIdProcessor.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Processor/ProcessIdProcessor.php new file mode 100644 index 0000000..9d3f559 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Processor/ProcessIdProcessor.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Processor; + +/** + * Adds value of getmypid into records + * + * @author Andreas Hörnicke + */ +class ProcessIdProcessor +{ + /** + * @param array $record + * @return array + */ + public function __invoke(array $record) + { + $record['extra']['process_id'] = getmypid(); + + return $record; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Processor/PsrLogMessageProcessor.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Processor/PsrLogMessageProcessor.php new file mode 100644 index 0000000..c2686ce --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Processor/PsrLogMessageProcessor.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Processor; + +/** + * Processes a record's message according to PSR-3 rules + * + * It replaces {foo} with the value from $context['foo'] + * + * @author Jordi Boggiano + */ +class PsrLogMessageProcessor +{ + /** + * @param array $record + * @return array + */ + public function __invoke(array $record) + { + if (false === strpos($record['message'], '{')) { + return $record; + } + + $replacements = array(); + foreach ($record['context'] as $key => $val) { + if (is_null($val) || is_scalar($val) || (is_object($val) && method_exists($val, "__toString"))) { + $replacements['{'.$key.'}'] = $val; + } elseif (is_object($val)) { + $replacements['{'.$key.'}'] = '[object '.get_class($val).']'; + } else { + $replacements['{'.$key.'}'] = '['.gettype($val).']'; + } + } + + $record['message'] = strtr($record['message'], $replacements); + + return $record; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Processor/TagProcessor.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Processor/TagProcessor.php new file mode 100644 index 0000000..7e2df2a --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Processor/TagProcessor.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Processor; + +/** + * Adds a tags array into record + * + * @author Martijn Riemers + */ +class TagProcessor +{ + private $tags; + + public function __construct(array $tags = array()) + { + $this->setTags($tags); + } + + public function addTags(array $tags = array()) + { + $this->tags = array_merge($this->tags, $tags); + } + + public function setTags(array $tags = array()) + { + $this->tags = $tags; + } + + public function __invoke(array $record) + { + $record['extra']['tags'] = $this->tags; + + return $record; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Processor/UidProcessor.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Processor/UidProcessor.php new file mode 100644 index 0000000..812707c --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Processor/UidProcessor.php @@ -0,0 +1,46 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Processor; + +/** + * Adds a unique identifier into records + * + * @author Simon Mönch + */ +class UidProcessor +{ + private $uid; + + public function __construct($length = 7) + { + if (!is_int($length) || $length > 32 || $length < 1) { + throw new \InvalidArgumentException('The uid length must be an integer between 1 and 32'); + } + + $this->uid = substr(hash('md5', uniqid('', true)), 0, $length); + } + + public function __invoke(array $record) + { + $record['extra']['uid'] = $this->uid; + + return $record; + } + + /** + * @return string + */ + public function getUid() + { + return $this->uid; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Processor/WebProcessor.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Processor/WebProcessor.php new file mode 100644 index 0000000..ea1d897 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Processor/WebProcessor.php @@ -0,0 +1,113 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Processor; + +/** + * Injects url/method and remote IP of the current web request in all records + * + * @author Jordi Boggiano + */ +class WebProcessor +{ + /** + * @var array|\ArrayAccess + */ + protected $serverData; + + /** + * Default fields + * + * Array is structured as [key in record.extra => key in $serverData] + * + * @var array + */ + protected $extraFields = array( + 'url' => 'REQUEST_URI', + 'ip' => 'REMOTE_ADDR', + 'http_method' => 'REQUEST_METHOD', + 'server' => 'SERVER_NAME', + 'referrer' => 'HTTP_REFERER', + ); + + /** + * @param array|\ArrayAccess $serverData Array or object w/ ArrayAccess that provides access to the $_SERVER data + * @param array|null $extraFields Field names and the related key inside $serverData to be added. If not provided it defaults to: url, ip, http_method, server, referrer + */ + public function __construct($serverData = null, array $extraFields = null) + { + if (null === $serverData) { + $this->serverData = &$_SERVER; + } elseif (is_array($serverData) || $serverData instanceof \ArrayAccess) { + $this->serverData = $serverData; + } else { + throw new \UnexpectedValueException('$serverData must be an array or object implementing ArrayAccess.'); + } + + if (null !== $extraFields) { + if (isset($extraFields[0])) { + foreach (array_keys($this->extraFields) as $fieldName) { + if (!in_array($fieldName, $extraFields)) { + unset($this->extraFields[$fieldName]); + } + } + } else { + $this->extraFields = $extraFields; + } + } + } + + /** + * @param array $record + * @return array + */ + public function __invoke(array $record) + { + // skip processing if for some reason request data + // is not present (CLI or wonky SAPIs) + if (!isset($this->serverData['REQUEST_URI'])) { + return $record; + } + + $record['extra'] = $this->appendExtraFields($record['extra']); + + return $record; + } + + /** + * @param string $extraName + * @param string $serverName + * @return $this + */ + public function addExtraField($extraName, $serverName) + { + $this->extraFields[$extraName] = $serverName; + + return $this; + } + + /** + * @param array $extra + * @return array + */ + private function appendExtraFields(array $extra) + { + foreach ($this->extraFields as $extraName => $serverName) { + $extra[$extraName] = isset($this->serverData[$serverName]) ? $this->serverData[$serverName] : null; + } + + if (isset($this->serverData['UNIQUE_ID'])) { + $extra['unique_id'] = $this->serverData['UNIQUE_ID']; + } + + return $extra; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Registry.php b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Registry.php new file mode 100644 index 0000000..159b751 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/monolog/monolog/src/Monolog/Registry.php @@ -0,0 +1,134 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog; + +use InvalidArgumentException; + +/** + * Monolog log registry + * + * Allows to get `Logger` instances in the global scope + * via static method calls on this class. + * + * + * $application = new Monolog\Logger('application'); + * $api = new Monolog\Logger('api'); + * + * Monolog\Registry::addLogger($application); + * Monolog\Registry::addLogger($api); + * + * function testLogger() + * { + * Monolog\Registry::api()->addError('Sent to $api Logger instance'); + * Monolog\Registry::application()->addError('Sent to $application Logger instance'); + * } + * + * + * @author Tomas Tatarko + */ +class Registry +{ + /** + * List of all loggers in the registry (by named indexes) + * + * @var Logger[] + */ + private static $loggers = array(); + + /** + * Adds new logging channel to the registry + * + * @param Logger $logger Instance of the logging channel + * @param string|null $name Name of the logging channel ($logger->getName() by default) + * @param bool $overwrite Overwrite instance in the registry if the given name already exists? + * @throws \InvalidArgumentException If $overwrite set to false and named Logger instance already exists + */ + public static function addLogger(Logger $logger, $name = null, $overwrite = false) + { + $name = $name ?: $logger->getName(); + + if (isset(self::$loggers[$name]) && !$overwrite) { + throw new InvalidArgumentException('Logger with the given name already exists'); + } + + self::$loggers[$name] = $logger; + } + + /** + * Checks if such logging channel exists by name or instance + * + * @param string|Logger $logger Name or logger instance + */ + public static function hasLogger($logger) + { + if ($logger instanceof Logger) { + $index = array_search($logger, self::$loggers, true); + + return false !== $index; + } else { + return isset(self::$loggers[$logger]); + } + } + + /** + * Removes instance from registry by name or instance + * + * @param string|Logger $logger Name or logger instance + */ + public static function removeLogger($logger) + { + if ($logger instanceof Logger) { + if (false !== ($idx = array_search($logger, self::$loggers, true))) { + unset(self::$loggers[$idx]); + } + } else { + unset(self::$loggers[$logger]); + } + } + + /** + * Clears the registry + */ + public static function clear() + { + self::$loggers = array(); + } + + /** + * Gets Logger instance from the registry + * + * @param string $name Name of the requested Logger instance + * @throws \InvalidArgumentException If named Logger instance is not in the registry + * @return Logger Requested instance of Logger + */ + public static function getInstance($name) + { + if (!isset(self::$loggers[$name])) { + throw new InvalidArgumentException(sprintf('Requested "%s" logger instance is not in the registry', $name)); + } + + return self::$loggers[$name]; + } + + /** + * Gets Logger instance from the registry via static method call + * + * @param string $name Name of the requested Logger instance + * @param array $arguments Arguments passed to static method call + * @throws \InvalidArgumentException If named Logger instance is not in the registry + * @return Logger Requested instance of Logger + */ + public static function __callStatic($name, $arguments) + { + return self::getInstance($name); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/Archive_Tar/Archive/Tar.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/Archive_Tar/Archive/Tar.php new file mode 100644 index 0000000..202fffb --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/Archive_Tar/Archive/Tar.php @@ -0,0 +1,2421 @@ + + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * @category File_Formats + * @package Archive_Tar + * @author Vincent Blavet + * @copyright 1997-2010 The Authors + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id$ + * @link http://pear.php.net/package/Archive_Tar + */ + +// If the PEAR class cannot be loaded via the autoloader, +// then try to require_once it from the PHP include path. +if (!class_exists('PEAR')) { + require_once 'PEAR.php'; +} + +define('ARCHIVE_TAR_ATT_SEPARATOR', 90001); +define('ARCHIVE_TAR_END_BLOCK', pack("a512", '')); + +if (!function_exists('gzopen') && function_exists('gzopen64')) { + function gzopen($filename, $mode, $use_include_path = 0) + { + return gzopen64($filename, $mode, $use_include_path); + } +} + +if (!function_exists('gztell') && function_exists('gztell64')) { + function gztell($zp) + { + return gztell64($zp); + } +} + +if (!function_exists('gzseek') && function_exists('gzseek64')) { + function gzseek($zp, $offset, $whence = SEEK_SET) + { + return gzseek64($zp, $offset, $whence); + } +} + +/** + * Creates a (compressed) Tar archive + * + * @package Archive_Tar + * @author Vincent Blavet + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Revision$ + */ +class Archive_Tar extends PEAR +{ + /** + * @var string Name of the Tar + */ + public $_tarname = ''; + + /** + * @var boolean if true, the Tar file will be gzipped + */ + public $_compress = false; + + /** + * @var string Type of compression : 'none', 'gz', 'bz2' or 'lzma2' + */ + public $_compress_type = 'none'; + + /** + * @var string Explode separator + */ + public $_separator = ' '; + + /** + * @var file descriptor + */ + public $_file = 0; + + /** + * @var string Local Tar name of a remote Tar (http:// or ftp://) + */ + public $_temp_tarname = ''; + + /** + * @var string regular expression for ignoring files or directories + */ + public $_ignore_regexp = ''; + + /** + * @var object PEAR_Error object + */ + public $error_object = null; + + /** + * Format for data extraction + * + * @var string + */ + public $_fmt =''; + /** + * Archive_Tar Class constructor. This flavour of the constructor only + * declare a new Archive_Tar object, identifying it by the name of the + * tar file. + * If the compress argument is set the tar will be read or created as a + * gzip or bz2 compressed TAR file. + * + * @param string $p_tarname The name of the tar archive to create + * @param string $p_compress can be null, 'gz', 'bz2' or 'lzma2'. This + * parameter indicates if gzip, bz2 or lzma2 compression + * is required. For compatibility reason the + * boolean value 'true' means 'gz'. + * + * @return bool + */ + public function __construct($p_tarname, $p_compress = null) + { + parent::__construct(); + + $this->_compress = false; + $this->_compress_type = 'none'; + if (($p_compress === null) || ($p_compress == '')) { + if (@file_exists($p_tarname)) { + if ($fp = @fopen($p_tarname, "rb")) { + // look for gzip magic cookie + $data = fread($fp, 2); + fclose($fp); + if ($data == "\37\213") { + $this->_compress = true; + $this->_compress_type = 'gz'; + // No sure it's enought for a magic code .... + } elseif ($data == "BZ") { + $this->_compress = true; + $this->_compress_type = 'bz2'; + } elseif (file_get_contents($p_tarname, false, null, 1, 4) == '7zXZ') { + $this->_compress = true; + $this->_compress_type = 'lzma2'; + } + } + } else { + // probably a remote file or some file accessible + // through a stream interface + if (substr($p_tarname, -2) == 'gz') { + $this->_compress = true; + $this->_compress_type = 'gz'; + } elseif ((substr($p_tarname, -3) == 'bz2') || + (substr($p_tarname, -2) == 'bz') + ) { + $this->_compress = true; + $this->_compress_type = 'bz2'; + } else { + if (substr($p_tarname, -2) == 'xz') { + $this->_compress = true; + $this->_compress_type = 'lzma2'; + } + } + } + } else { + if (($p_compress === true) || ($p_compress == 'gz')) { + $this->_compress = true; + $this->_compress_type = 'gz'; + } else { + if ($p_compress == 'bz2') { + $this->_compress = true; + $this->_compress_type = 'bz2'; + } else { + if ($p_compress == 'lzma2') { + $this->_compress = true; + $this->_compress_type = 'lzma2'; + } else { + $this->_error( + "Unsupported compression type '$p_compress'\n" . + "Supported types are 'gz', 'bz2' and 'lzma2'.\n" + ); + return false; + } + } + } + } + $this->_tarname = $p_tarname; + if ($this->_compress) { // assert zlib or bz2 or xz extension support + if ($this->_compress_type == 'gz') { + $extname = 'zlib'; + } else { + if ($this->_compress_type == 'bz2') { + $extname = 'bz2'; + } else { + if ($this->_compress_type == 'lzma2') { + $extname = 'xz'; + } + } + } + + if (!extension_loaded($extname)) { + PEAR::loadExtension($extname); + } + if (!extension_loaded($extname)) { + $this->_error( + "The extension '$extname' couldn't be found.\n" . + "Please make sure your version of PHP was built " . + "with '$extname' support.\n" + ); + return false; + } + } + + + if (version_compare(PHP_VERSION, "5.5.0-dev") < 0) { + $this->_fmt = "a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/" . + "a8checksum/a1typeflag/a100link/a6magic/a2version/" . + "a32uname/a32gname/a8devmajor/a8devminor/a131prefix"; + } else { + $this->_fmt = "Z100filename/Z8mode/Z8uid/Z8gid/Z12size/Z12mtime/" . + "Z8checksum/Z1typeflag/Z100link/Z6magic/Z2version/" . + "Z32uname/Z32gname/Z8devmajor/Z8devminor/Z131prefix"; + } + + + } + + public function __destruct() + { + $this->_close(); + // ----- Look for a local copy to delete + if ($this->_temp_tarname != '') { + @unlink($this->_temp_tarname); + } + } + + /** + * This method creates the archive file and add the files / directories + * that are listed in $p_filelist. + * If a file with the same name exist and is writable, it is replaced + * by the new tar. + * The method return false and a PEAR error text. + * The $p_filelist parameter can be an array of string, each string + * representing a filename or a directory name with their path if + * needed. It can also be a single string with names separated by a + * single blank. + * For each directory added in the archive, the files and + * sub-directories are also added. + * See also createModify() method for more details. + * + * @param array $p_filelist An array of filenames and directory names, or a + * single string with names separated by a single + * blank space. + * + * @return true on success, false on error. + * @see createModify() + */ + public function create($p_filelist) + { + return $this->createModify($p_filelist, '', ''); + } + + /** + * This method add the files / directories that are listed in $p_filelist in + * the archive. If the archive does not exist it is created. + * The method return false and a PEAR error text. + * The files and directories listed are only added at the end of the archive, + * even if a file with the same name is already archived. + * See also createModify() method for more details. + * + * @param array $p_filelist An array of filenames and directory names, or a + * single string with names separated by a single + * blank space. + * + * @return true on success, false on error. + * @see createModify() + * @access public + */ + public function add($p_filelist) + { + return $this->addModify($p_filelist, '', ''); + } + + /** + * @param string $p_path + * @param bool $p_preserve + * @return bool + */ + public function extract($p_path = '', $p_preserve = false) + { + return $this->extractModify($p_path, '', $p_preserve); + } + + /** + * @return array|int + */ + public function listContent() + { + $v_list_detail = array(); + + if ($this->_openRead()) { + if (!$this->_extractList('', $v_list_detail, "list", '', '')) { + unset($v_list_detail); + $v_list_detail = 0; + } + $this->_close(); + } + + return $v_list_detail; + } + + /** + * This method creates the archive file and add the files / directories + * that are listed in $p_filelist. + * If the file already exists and is writable, it is replaced by the + * new tar. It is a create and not an add. If the file exists and is + * read-only or is a directory it is not replaced. The method return + * false and a PEAR error text. + * The $p_filelist parameter can be an array of string, each string + * representing a filename or a directory name with their path if + * needed. It can also be a single string with names separated by a + * single blank. + * The path indicated in $p_remove_dir will be removed from the + * memorized path of each file / directory listed when this path + * exists. By default nothing is removed (empty path '') + * The path indicated in $p_add_dir will be added at the beginning of + * the memorized path of each file / directory listed. However it can + * be set to empty ''. The adding of a path is done after the removing + * of path. + * The path add/remove ability enables the user to prepare an archive + * for extraction in a different path than the origin files are. + * See also addModify() method for file adding properties. + * + * @param array $p_filelist An array of filenames and directory names, + * or a single string with names separated by + * a single blank space. + * @param string $p_add_dir A string which contains a path to be added + * to the memorized path of each element in + * the list. + * @param string $p_remove_dir A string which contains a path to be + * removed from the memorized path of each + * element in the list, when relevant. + * + * @return boolean true on success, false on error. + * @see addModify() + */ + public function createModify($p_filelist, $p_add_dir, $p_remove_dir = '') + { + $v_result = true; + + if (!$this->_openWrite()) { + return false; + } + + if ($p_filelist != '') { + if (is_array($p_filelist)) { + $v_list = $p_filelist; + } elseif (is_string($p_filelist)) { + $v_list = explode($this->_separator, $p_filelist); + } else { + $this->_cleanFile(); + $this->_error('Invalid file list'); + return false; + } + + $v_result = $this->_addList($v_list, $p_add_dir, $p_remove_dir); + } + + if ($v_result) { + $this->_writeFooter(); + $this->_close(); + } else { + $this->_cleanFile(); + } + + return $v_result; + } + + /** + * This method add the files / directories listed in $p_filelist at the + * end of the existing archive. If the archive does not yet exists it + * is created. + * The $p_filelist parameter can be an array of string, each string + * representing a filename or a directory name with their path if + * needed. It can also be a single string with names separated by a + * single blank. + * The path indicated in $p_remove_dir will be removed from the + * memorized path of each file / directory listed when this path + * exists. By default nothing is removed (empty path '') + * The path indicated in $p_add_dir will be added at the beginning of + * the memorized path of each file / directory listed. However it can + * be set to empty ''. The adding of a path is done after the removing + * of path. + * The path add/remove ability enables the user to prepare an archive + * for extraction in a different path than the origin files are. + * If a file/dir is already in the archive it will only be added at the + * end of the archive. There is no update of the existing archived + * file/dir. However while extracting the archive, the last file will + * replace the first one. This results in a none optimization of the + * archive size. + * If a file/dir does not exist the file/dir is ignored. However an + * error text is send to PEAR error. + * If a file/dir is not readable the file/dir is ignored. However an + * error text is send to PEAR error. + * + * @param array $p_filelist An array of filenames and directory + * names, or a single string with names + * separated by a single blank space. + * @param string $p_add_dir A string which contains a path to be + * added to the memorized path of each + * element in the list. + * @param string $p_remove_dir A string which contains a path to be + * removed from the memorized path of + * each element in the list, when + * relevant. + * + * @return true on success, false on error. + */ + public function addModify($p_filelist, $p_add_dir, $p_remove_dir = '') + { + $v_result = true; + + if (!$this->_isArchive()) { + $v_result = $this->createModify( + $p_filelist, + $p_add_dir, + $p_remove_dir + ); + } else { + if (is_array($p_filelist)) { + $v_list = $p_filelist; + } elseif (is_string($p_filelist)) { + $v_list = explode($this->_separator, $p_filelist); + } else { + $this->_error('Invalid file list'); + return false; + } + + $v_result = $this->_append($v_list, $p_add_dir, $p_remove_dir); + } + + return $v_result; + } + + /** + * This method add a single string as a file at the + * end of the existing archive. If the archive does not yet exists it + * is created. + * + * @param string $p_filename A string which contains the full + * filename path that will be associated + * with the string. + * @param string $p_string The content of the file added in + * the archive. + * @param bool|int $p_datetime A custom date/time (unix timestamp) + * for the file (optional). + * @param array $p_params An array of optional params: + * stamp => the datetime (replaces + * datetime above if it exists) + * mode => the permissions on the + * file (600 by default) + * type => is this a link? See the + * tar specification for details. + * (default = regular file) + * uid => the user ID of the file + * (default = 0 = root) + * gid => the group ID of the file + * (default = 0 = root) + * + * @return true on success, false on error. + */ + public function addString($p_filename, $p_string, $p_datetime = false, $p_params = array()) + { + $p_stamp = @$p_params["stamp"] ? $p_params["stamp"] : ($p_datetime ? $p_datetime : time()); + $p_mode = @$p_params["mode"] ? $p_params["mode"] : 0600; + $p_type = @$p_params["type"] ? $p_params["type"] : ""; + $p_uid = @$p_params["uid"] ? $p_params["uid"] : ""; + $p_gid = @$p_params["gid"] ? $p_params["gid"] : ""; + $v_result = true; + + if (!$this->_isArchive()) { + if (!$this->_openWrite()) { + return false; + } + $this->_close(); + } + + if (!$this->_openAppend()) { + return false; + } + + // Need to check the get back to the temporary file ? .... + $v_result = $this->_addString($p_filename, $p_string, $p_datetime, $p_params); + + $this->_writeFooter(); + + $this->_close(); + + return $v_result; + } + + /** + * This method extract all the content of the archive in the directory + * indicated by $p_path. When relevant the memorized path of the + * files/dir can be modified by removing the $p_remove_path path at the + * beginning of the file/dir path. + * While extracting a file, if the directory path does not exists it is + * created. + * While extracting a file, if the file already exists it is replaced + * without looking for last modification date. + * While extracting a file, if the file already exists and is write + * protected, the extraction is aborted. + * While extracting a file, if a directory with the same name already + * exists, the extraction is aborted. + * While extracting a directory, if a file with the same name already + * exists, the extraction is aborted. + * While extracting a file/directory if the destination directory exist + * and is write protected, or does not exist but can not be created, + * the extraction is aborted. + * If after extraction an extracted file does not show the correct + * stored file size, the extraction is aborted. + * When the extraction is aborted, a PEAR error text is set and false + * is returned. However the result can be a partial extraction that may + * need to be manually cleaned. + * + * @param string $p_path The path of the directory where the + * files/dir need to by extracted. + * @param string $p_remove_path Part of the memorized path that can be + * removed if present at the beginning of + * the file/dir path. + * @param boolean $p_preserve Preserve user/group ownership of files + * + * @return boolean true on success, false on error. + * @see extractList() + */ + public function extractModify($p_path, $p_remove_path, $p_preserve = false) + { + $v_result = true; + $v_list_detail = array(); + + if ($v_result = $this->_openRead()) { + $v_result = $this->_extractList( + $p_path, + $v_list_detail, + "complete", + 0, + $p_remove_path, + $p_preserve + ); + $this->_close(); + } + + return $v_result; + } + + /** + * This method extract from the archive one file identified by $p_filename. + * The return value is a string with the file content, or NULL on error. + * + * @param string $p_filename The path of the file to extract in a string. + * + * @return a string with the file content or NULL. + */ + public function extractInString($p_filename) + { + if ($this->_openRead()) { + $v_result = $this->_extractInString($p_filename); + $this->_close(); + } else { + $v_result = null; + } + + return $v_result; + } + + /** + * This method extract from the archive only the files indicated in the + * $p_filelist. These files are extracted in the current directory or + * in the directory indicated by the optional $p_path parameter. + * If indicated the $p_remove_path can be used in the same way as it is + * used in extractModify() method. + * + * @param array $p_filelist An array of filenames and directory names, + * or a single string with names separated + * by a single blank space. + * @param string $p_path The path of the directory where the + * files/dir need to by extracted. + * @param string $p_remove_path Part of the memorized path that can be + * removed if present at the beginning of + * the file/dir path. + * @param boolean $p_preserve Preserve user/group ownership of files + * + * @return true on success, false on error. + * @see extractModify() + */ + public function extractList($p_filelist, $p_path = '', $p_remove_path = '', $p_preserve = false) + { + $v_result = true; + $v_list_detail = array(); + + if (is_array($p_filelist)) { + $v_list = $p_filelist; + } elseif (is_string($p_filelist)) { + $v_list = explode($this->_separator, $p_filelist); + } else { + $this->_error('Invalid string list'); + return false; + } + + if ($v_result = $this->_openRead()) { + $v_result = $this->_extractList( + $p_path, + $v_list_detail, + "partial", + $v_list, + $p_remove_path, + $p_preserve + ); + $this->_close(); + } + + return $v_result; + } + + /** + * This method set specific attributes of the archive. It uses a variable + * list of parameters, in the format attribute code + attribute values : + * $arch->setAttribute(ARCHIVE_TAR_ATT_SEPARATOR, ','); + * + * @return true on success, false on error. + */ + public function setAttribute() + { + $v_result = true; + + // ----- Get the number of variable list of arguments + if (($v_size = func_num_args()) == 0) { + return true; + } + + // ----- Get the arguments + $v_att_list = & func_get_args(); + + // ----- Read the attributes + $i = 0; + while ($i < $v_size) { + + // ----- Look for next option + switch ($v_att_list[$i]) { + // ----- Look for options that request a string value + case ARCHIVE_TAR_ATT_SEPARATOR : + // ----- Check the number of parameters + if (($i + 1) >= $v_size) { + $this->_error( + 'Invalid number of parameters for ' + . 'attribute ARCHIVE_TAR_ATT_SEPARATOR' + ); + return false; + } + + // ----- Get the value + $this->_separator = $v_att_list[$i + 1]; + $i++; + break; + + default : + $this->_error('Unknown attribute code ' . $v_att_list[$i] . ''); + return false; + } + + // ----- Next attribute + $i++; + } + + return $v_result; + } + + /** + * This method sets the regular expression for ignoring files and directories + * at import, for example: + * $arch->setIgnoreRegexp("#CVS|\.svn#"); + * + * @param string $regexp regular expression defining which files or directories to ignore + */ + public function setIgnoreRegexp($regexp) + { + $this->_ignore_regexp = $regexp; + } + + /** + * This method sets the regular expression for ignoring all files and directories + * matching the filenames in the array list at import, for example: + * $arch->setIgnoreList(array('CVS', '.svn', 'bin/tool')); + * + * @param array $list a list of file or directory names to ignore + * + * @access public + */ + public function setIgnoreList($list) + { + $regexp = str_replace(array('#', '.', '^', '$'), array('\#', '\.', '\^', '\$'), $list); + $regexp = '#/' . join('$|/', $list) . '#'; + $this->setIgnoreRegexp($regexp); + } + + /** + * @param string $p_message + */ + public function _error($p_message) + { + $this->error_object = $this->raiseError($p_message); + } + + /** + * @param string $p_message + */ + public function _warning($p_message) + { + $this->error_object = $this->raiseError($p_message); + } + + /** + * @param string $p_filename + * @return bool + */ + public function _isArchive($p_filename = null) + { + if ($p_filename == null) { + $p_filename = $this->_tarname; + } + clearstatcache(); + return @is_file($p_filename) && !@is_link($p_filename); + } + + /** + * @return bool + */ + public function _openWrite() + { + if ($this->_compress_type == 'gz' && function_exists('gzopen')) { + $this->_file = @gzopen($this->_tarname, "wb9"); + } else { + if ($this->_compress_type == 'bz2' && function_exists('bzopen')) { + $this->_file = @bzopen($this->_tarname, "w"); + } else { + if ($this->_compress_type == 'lzma2' && function_exists('xzopen')) { + $this->_file = @xzopen($this->_tarname, 'w'); + } else { + if ($this->_compress_type == 'none') { + $this->_file = @fopen($this->_tarname, "wb"); + } else { + $this->_error( + 'Unknown or missing compression type (' + . $this->_compress_type . ')' + ); + return false; + } + } + } + } + + if ($this->_file == 0) { + $this->_error( + 'Unable to open in write mode \'' + . $this->_tarname . '\'' + ); + return false; + } + + return true; + } + + /** + * @return bool + */ + public function _openRead() + { + if (strtolower(substr($this->_tarname, 0, 7)) == 'http://') { + + // ----- Look if a local copy need to be done + if ($this->_temp_tarname == '') { + $this->_temp_tarname = uniqid('tar') . '.tmp'; + if (!$v_file_from = @fopen($this->_tarname, 'rb')) { + $this->_error( + 'Unable to open in read mode \'' + . $this->_tarname . '\'' + ); + $this->_temp_tarname = ''; + return false; + } + if (!$v_file_to = @fopen($this->_temp_tarname, 'wb')) { + $this->_error( + 'Unable to open in write mode \'' + . $this->_temp_tarname . '\'' + ); + $this->_temp_tarname = ''; + return false; + } + while ($v_data = @fread($v_file_from, 1024)) { + @fwrite($v_file_to, $v_data); + } + @fclose($v_file_from); + @fclose($v_file_to); + } + + // ----- File to open if the local copy + $v_filename = $this->_temp_tarname; + } else { + // ----- File to open if the normal Tar file + + $v_filename = $this->_tarname; + } + + if ($this->_compress_type == 'gz' && function_exists('gzopen')) { + $this->_file = @gzopen($v_filename, "rb"); + } else { + if ($this->_compress_type == 'bz2' && function_exists('bzopen')) { + $this->_file = @bzopen($v_filename, "r"); + } else { + if ($this->_compress_type == 'lzma2' && function_exists('xzopen')) { + $this->_file = @xzopen($v_filename, "r"); + } else { + if ($this->_compress_type == 'none') { + $this->_file = @fopen($v_filename, "rb"); + } else { + $this->_error( + 'Unknown or missing compression type (' + . $this->_compress_type . ')' + ); + return false; + } + } + } + } + + if ($this->_file == 0) { + $this->_error('Unable to open in read mode \'' . $v_filename . '\''); + return false; + } + + return true; + } + + /** + * @return bool + */ + public function _openReadWrite() + { + if ($this->_compress_type == 'gz') { + $this->_file = @gzopen($this->_tarname, "r+b"); + } else { + if ($this->_compress_type == 'bz2') { + $this->_error( + 'Unable to open bz2 in read/write mode \'' + . $this->_tarname . '\' (limitation of bz2 extension)' + ); + return false; + } else { + if ($this->_compress_type == 'lzma2') { + $this->_error( + 'Unable to open lzma2 in read/write mode \'' + . $this->_tarname . '\' (limitation of lzma2 extension)' + ); + return false; + } else { + if ($this->_compress_type == 'none') { + $this->_file = @fopen($this->_tarname, "r+b"); + } else { + $this->_error( + 'Unknown or missing compression type (' + . $this->_compress_type . ')' + ); + return false; + } + } + } + } + + if ($this->_file == 0) { + $this->_error( + 'Unable to open in read/write mode \'' + . $this->_tarname . '\'' + ); + return false; + } + + return true; + } + + /** + * @return bool + */ + public function _close() + { + //if (isset($this->_file)) { + if (is_resource($this->_file)) { + if ($this->_compress_type == 'gz') { + @gzclose($this->_file); + } else { + if ($this->_compress_type == 'bz2') { + @bzclose($this->_file); + } else { + if ($this->_compress_type == 'lzma2') { + @xzclose($this->_file); + } else { + if ($this->_compress_type == 'none') { + @fclose($this->_file); + } else { + $this->_error( + 'Unknown or missing compression type (' + . $this->_compress_type . ')' + ); + } + } + } + } + + $this->_file = 0; + } + + // ----- Look if a local copy need to be erase + // Note that it might be interesting to keep the url for a time : ToDo + if ($this->_temp_tarname != '') { + @unlink($this->_temp_tarname); + $this->_temp_tarname = ''; + } + + return true; + } + + /** + * @return bool + */ + public function _cleanFile() + { + $this->_close(); + + // ----- Look for a local copy + if ($this->_temp_tarname != '') { + // ----- Remove the local copy but not the remote tarname + @unlink($this->_temp_tarname); + $this->_temp_tarname = ''; + } else { + // ----- Remove the local tarname file + @unlink($this->_tarname); + } + $this->_tarname = ''; + + return true; + } + + /** + * @param mixed $p_binary_data + * @param integer $p_len + * @return bool + */ + public function _writeBlock($p_binary_data, $p_len = null) + { + if (is_resource($this->_file)) { + if ($p_len === null) { + if ($this->_compress_type == 'gz') { + @gzputs($this->_file, $p_binary_data); + } else { + if ($this->_compress_type == 'bz2') { + @bzwrite($this->_file, $p_binary_data); + } else { + if ($this->_compress_type == 'lzma2') { + @xzwrite($this->_file, $p_binary_data); + } else { + if ($this->_compress_type == 'none') { + @fputs($this->_file, $p_binary_data); + } else { + $this->_error( + 'Unknown or missing compression type (' + . $this->_compress_type . ')' + ); + } + } + } + } + } else { + if ($this->_compress_type == 'gz') { + @gzputs($this->_file, $p_binary_data, $p_len); + } else { + if ($this->_compress_type == 'bz2') { + @bzwrite($this->_file, $p_binary_data, $p_len); + } else { + if ($this->_compress_type == 'lzma2') { + @xzwrite($this->_file, $p_binary_data, $p_len); + } else { + if ($this->_compress_type == 'none') { + @fputs($this->_file, $p_binary_data, $p_len); + } else { + $this->_error( + 'Unknown or missing compression type (' + . $this->_compress_type . ')' + ); + } + } + } + } + } + } + return true; + } + + /** + * @return null|string + */ + public function _readBlock() + { + $v_block = null; + if (is_resource($this->_file)) { + if ($this->_compress_type == 'gz') { + $v_block = @gzread($this->_file, 512); + } else { + if ($this->_compress_type == 'bz2') { + $v_block = @bzread($this->_file, 512); + } else { + if ($this->_compress_type == 'lzma2') { + $v_block = @xzread($this->_file, 512); + } else { + if ($this->_compress_type == 'none') { + $v_block = @fread($this->_file, 512); + } else { + $this->_error( + 'Unknown or missing compression type (' + . $this->_compress_type . ')' + ); + } + } + } + } + } + return $v_block; + } + + /** + * @param null $p_len + * @return bool + */ + public function _jumpBlock($p_len = null) + { + if (is_resource($this->_file)) { + if ($p_len === null) { + $p_len = 1; + } + + if ($this->_compress_type == 'gz') { + @gzseek($this->_file, gztell($this->_file) + ($p_len * 512)); + } else { + if ($this->_compress_type == 'bz2') { + // ----- Replace missing bztell() and bzseek() + for ($i = 0; $i < $p_len; $i++) { + $this->_readBlock(); + } + } else { + if ($this->_compress_type == 'lzma2') { + // ----- Replace missing xztell() and xzseek() + for ($i = 0; $i < $p_len; $i++) { + $this->_readBlock(); + } + } else { + if ($this->_compress_type == 'none') { + @fseek($this->_file, $p_len * 512, SEEK_CUR); + } else { + $this->_error( + 'Unknown or missing compression type (' + . $this->_compress_type . ')' + ); + } + } + } + } + } + return true; + } + + /** + * @return bool + */ + public function _writeFooter() + { + if (is_resource($this->_file)) { + // ----- Write the last 0 filled block for end of archive + $v_binary_data = pack('a1024', ''); + $this->_writeBlock($v_binary_data); + } + return true; + } + + /** + * @param array $p_list + * @param string $p_add_dir + * @param string $p_remove_dir + * @return bool + */ + public function _addList($p_list, $p_add_dir, $p_remove_dir) + { + $v_result = true; + $v_header = array(); + + // ----- Remove potential windows directory separator + $p_add_dir = $this->_translateWinPath($p_add_dir); + $p_remove_dir = $this->_translateWinPath($p_remove_dir, false); + + if (!$this->_file) { + $this->_error('Invalid file descriptor'); + return false; + } + + if (sizeof($p_list) == 0) { + return true; + } + + foreach ($p_list as $v_filename) { + if (!$v_result) { + break; + } + + // ----- Skip the current tar name + if ($v_filename == $this->_tarname) { + continue; + } + + if ($v_filename == '') { + continue; + } + + // ----- ignore files and directories matching the ignore regular expression + if ($this->_ignore_regexp && preg_match($this->_ignore_regexp, '/' . $v_filename)) { + $this->_warning("File '$v_filename' ignored"); + continue; + } + + if (!file_exists($v_filename) && !is_link($v_filename)) { + $this->_warning("File '$v_filename' does not exist"); + continue; + } + + // ----- Add the file or directory header + if (!$this->_addFile($v_filename, $v_header, $p_add_dir, $p_remove_dir)) { + return false; + } + + if (@is_dir($v_filename) && !@is_link($v_filename)) { + if (!($p_hdir = opendir($v_filename))) { + $this->_warning("Directory '$v_filename' can not be read"); + continue; + } + while (false !== ($p_hitem = readdir($p_hdir))) { + if (($p_hitem != '.') && ($p_hitem != '..')) { + if ($v_filename != ".") { + $p_temp_list[0] = $v_filename . '/' . $p_hitem; + } else { + $p_temp_list[0] = $p_hitem; + } + + $v_result = $this->_addList( + $p_temp_list, + $p_add_dir, + $p_remove_dir + ); + } + } + + unset($p_temp_list); + unset($p_hdir); + unset($p_hitem); + } + } + + return $v_result; + } + + /** + * @param string $p_filename + * @param mixed $p_header + * @param string $p_add_dir + * @param string $p_remove_dir + * @param null $v_stored_filename + * @return bool + */ + public function _addFile($p_filename, &$p_header, $p_add_dir, $p_remove_dir, $v_stored_filename = null) + { + if (!$this->_file) { + $this->_error('Invalid file descriptor'); + return false; + } + + if ($p_filename == '') { + $this->_error('Invalid file name'); + return false; + } + + if (is_null($v_stored_filename)) { + // ----- Calculate the stored filename + $p_filename = $this->_translateWinPath($p_filename, false); + $v_stored_filename = $p_filename; + + if (strcmp($p_filename, $p_remove_dir) == 0) { + return true; + } + + if ($p_remove_dir != '') { + if (substr($p_remove_dir, -1) != '/') { + $p_remove_dir .= '/'; + } + + if (substr($p_filename, 0, strlen($p_remove_dir)) == $p_remove_dir) { + $v_stored_filename = substr($p_filename, strlen($p_remove_dir)); + } + } + + $v_stored_filename = $this->_translateWinPath($v_stored_filename); + if ($p_add_dir != '') { + if (substr($p_add_dir, -1) == '/') { + $v_stored_filename = $p_add_dir . $v_stored_filename; + } else { + $v_stored_filename = $p_add_dir . '/' . $v_stored_filename; + } + } + + $v_stored_filename = $this->_pathReduction($v_stored_filename); + } + + if ($this->_isArchive($p_filename)) { + if (($v_file = @fopen($p_filename, "rb")) == 0) { + $this->_warning( + "Unable to open file '" . $p_filename + . "' in binary read mode" + ); + return true; + } + + if (!$this->_writeHeader($p_filename, $v_stored_filename)) { + return false; + } + + while (($v_buffer = fread($v_file, 512)) != '') { + $v_binary_data = pack("a512", "$v_buffer"); + $this->_writeBlock($v_binary_data); + } + + fclose($v_file); + } else { + // ----- Only header for dir + if (!$this->_writeHeader($p_filename, $v_stored_filename)) { + return false; + } + } + + return true; + } + + /** + * @param string $p_filename + * @param string $p_string + * @param bool $p_datetime + * @param array $p_params + * @return bool + */ + public function _addString($p_filename, $p_string, $p_datetime = false, $p_params = array()) + { + $p_stamp = @$p_params["stamp"] ? $p_params["stamp"] : ($p_datetime ? $p_datetime : time()); + $p_mode = @$p_params["mode"] ? $p_params["mode"] : 0600; + $p_type = @$p_params["type"] ? $p_params["type"] : ""; + $p_uid = @$p_params["uid"] ? $p_params["uid"] : 0; + $p_gid = @$p_params["gid"] ? $p_params["gid"] : 0; + if (!$this->_file) { + $this->_error('Invalid file descriptor'); + return false; + } + + if ($p_filename == '') { + $this->_error('Invalid file name'); + return false; + } + + // ----- Calculate the stored filename + $p_filename = $this->_translateWinPath($p_filename, false); + + // ----- If datetime is not specified, set current time + if ($p_datetime === false) { + $p_datetime = time(); + } + + if (!$this->_writeHeaderBlock( + $p_filename, + strlen($p_string), + $p_stamp, + $p_mode, + $p_type, + $p_uid, + $p_gid + ) + ) { + return false; + } + + $i = 0; + while (($v_buffer = substr($p_string, (($i++) * 512), 512)) != '') { + $v_binary_data = pack("a512", $v_buffer); + $this->_writeBlock($v_binary_data); + } + + return true; + } + + /** + * @param string $p_filename + * @param string $p_stored_filename + * @return bool + */ + public function _writeHeader($p_filename, $p_stored_filename) + { + if ($p_stored_filename == '') { + $p_stored_filename = $p_filename; + } + $v_reduce_filename = $this->_pathReduction($p_stored_filename); + + if (strlen($v_reduce_filename) > 99) { + if (!$this->_writeLongHeader($v_reduce_filename)) { + return false; + } + } + + $v_info = lstat($p_filename); + $v_uid = sprintf("%07s", DecOct($v_info[4])); + $v_gid = sprintf("%07s", DecOct($v_info[5])); + $v_perms = sprintf("%07s", DecOct($v_info['mode'] & 000777)); + + $v_mtime = sprintf("%011s", DecOct($v_info['mtime'])); + + $v_linkname = ''; + + if (@is_link($p_filename)) { + $v_typeflag = '2'; + $v_linkname = readlink($p_filename); + $v_size = sprintf("%011s", DecOct(0)); + } elseif (@is_dir($p_filename)) { + $v_typeflag = "5"; + $v_size = sprintf("%011s", DecOct(0)); + } else { + $v_typeflag = '0'; + clearstatcache(); + $v_size = sprintf("%011s", DecOct($v_info['size'])); + } + + $v_magic = 'ustar '; + + $v_version = ' '; + + if (function_exists('posix_getpwuid')) { + $userinfo = posix_getpwuid($v_info[4]); + $groupinfo = posix_getgrgid($v_info[5]); + + $v_uname = $userinfo['name']; + $v_gname = $groupinfo['name']; + } else { + $v_uname = ''; + $v_gname = ''; + } + + $v_devmajor = ''; + + $v_devminor = ''; + + $v_prefix = ''; + + $v_binary_data_first = pack( + "a100a8a8a8a12a12", + $v_reduce_filename, + $v_perms, + $v_uid, + $v_gid, + $v_size, + $v_mtime + ); + $v_binary_data_last = pack( + "a1a100a6a2a32a32a8a8a155a12", + $v_typeflag, + $v_linkname, + $v_magic, + $v_version, + $v_uname, + $v_gname, + $v_devmajor, + $v_devminor, + $v_prefix, + '' + ); + + // ----- Calculate the checksum + $v_checksum = 0; + // ..... First part of the header + for ($i = 0; $i < 148; $i++) { + $v_checksum += ord(substr($v_binary_data_first, $i, 1)); + } + // ..... Ignore the checksum value and replace it by ' ' (space) + for ($i = 148; $i < 156; $i++) { + $v_checksum += ord(' '); + } + // ..... Last part of the header + for ($i = 156, $j = 0; $i < 512; $i++, $j++) { + $v_checksum += ord(substr($v_binary_data_last, $j, 1)); + } + + // ----- Write the first 148 bytes of the header in the archive + $this->_writeBlock($v_binary_data_first, 148); + + // ----- Write the calculated checksum + $v_checksum = sprintf("%06s ", DecOct($v_checksum)); + $v_binary_data = pack("a8", $v_checksum); + $this->_writeBlock($v_binary_data, 8); + + // ----- Write the last 356 bytes of the header in the archive + $this->_writeBlock($v_binary_data_last, 356); + + return true; + } + + /** + * @param string $p_filename + * @param int $p_size + * @param int $p_mtime + * @param int $p_perms + * @param string $p_type + * @param int $p_uid + * @param int $p_gid + * @return bool + */ + public function _writeHeaderBlock( + $p_filename, + $p_size, + $p_mtime = 0, + $p_perms = 0, + $p_type = '', + $p_uid = 0, + $p_gid = 0 + ) { + $p_filename = $this->_pathReduction($p_filename); + + if (strlen($p_filename) > 99) { + if (!$this->_writeLongHeader($p_filename)) { + return false; + } + } + + if ($p_type == "5") { + $v_size = sprintf("%011s", DecOct(0)); + } else { + $v_size = sprintf("%011s", DecOct($p_size)); + } + + $v_uid = sprintf("%07s", DecOct($p_uid)); + $v_gid = sprintf("%07s", DecOct($p_gid)); + $v_perms = sprintf("%07s", DecOct($p_perms & 000777)); + + $v_mtime = sprintf("%11s", DecOct($p_mtime)); + + $v_linkname = ''; + + $v_magic = 'ustar '; + + $v_version = ' '; + + if (function_exists('posix_getpwuid')) { + $userinfo = posix_getpwuid($p_uid); + $groupinfo = posix_getgrgid($p_gid); + + $v_uname = $userinfo['name']; + $v_gname = $groupinfo['name']; + } else { + $v_uname = ''; + $v_gname = ''; + } + + $v_devmajor = ''; + + $v_devminor = ''; + + $v_prefix = ''; + + $v_binary_data_first = pack( + "a100a8a8a8a12A12", + $p_filename, + $v_perms, + $v_uid, + $v_gid, + $v_size, + $v_mtime + ); + $v_binary_data_last = pack( + "a1a100a6a2a32a32a8a8a155a12", + $p_type, + $v_linkname, + $v_magic, + $v_version, + $v_uname, + $v_gname, + $v_devmajor, + $v_devminor, + $v_prefix, + '' + ); + + // ----- Calculate the checksum + $v_checksum = 0; + // ..... First part of the header + for ($i = 0; $i < 148; $i++) { + $v_checksum += ord(substr($v_binary_data_first, $i, 1)); + } + // ..... Ignore the checksum value and replace it by ' ' (space) + for ($i = 148; $i < 156; $i++) { + $v_checksum += ord(' '); + } + // ..... Last part of the header + for ($i = 156, $j = 0; $i < 512; $i++, $j++) { + $v_checksum += ord(substr($v_binary_data_last, $j, 1)); + } + + // ----- Write the first 148 bytes of the header in the archive + $this->_writeBlock($v_binary_data_first, 148); + + // ----- Write the calculated checksum + $v_checksum = sprintf("%06s ", DecOct($v_checksum)); + $v_binary_data = pack("a8", $v_checksum); + $this->_writeBlock($v_binary_data, 8); + + // ----- Write the last 356 bytes of the header in the archive + $this->_writeBlock($v_binary_data_last, 356); + + return true; + } + + /** + * @param string $p_filename + * @return bool + */ + public function _writeLongHeader($p_filename) + { + $v_size = sprintf("%11s ", DecOct(strlen($p_filename))); + + $v_typeflag = 'L'; + + $v_linkname = ''; + + $v_magic = ''; + + $v_version = ''; + + $v_uname = ''; + + $v_gname = ''; + + $v_devmajor = ''; + + $v_devminor = ''; + + $v_prefix = ''; + + $v_binary_data_first = pack( + "a100a8a8a8a12a12", + '././@LongLink', + 0, + 0, + 0, + $v_size, + 0 + ); + $v_binary_data_last = pack( + "a1a100a6a2a32a32a8a8a155a12", + $v_typeflag, + $v_linkname, + $v_magic, + $v_version, + $v_uname, + $v_gname, + $v_devmajor, + $v_devminor, + $v_prefix, + '' + ); + + // ----- Calculate the checksum + $v_checksum = 0; + // ..... First part of the header + for ($i = 0; $i < 148; $i++) { + $v_checksum += ord(substr($v_binary_data_first, $i, 1)); + } + // ..... Ignore the checksum value and replace it by ' ' (space) + for ($i = 148; $i < 156; $i++) { + $v_checksum += ord(' '); + } + // ..... Last part of the header + for ($i = 156, $j = 0; $i < 512; $i++, $j++) { + $v_checksum += ord(substr($v_binary_data_last, $j, 1)); + } + + // ----- Write the first 148 bytes of the header in the archive + $this->_writeBlock($v_binary_data_first, 148); + + // ----- Write the calculated checksum + $v_checksum = sprintf("%06s ", DecOct($v_checksum)); + $v_binary_data = pack("a8", $v_checksum); + $this->_writeBlock($v_binary_data, 8); + + // ----- Write the last 356 bytes of the header in the archive + $this->_writeBlock($v_binary_data_last, 356); + + // ----- Write the filename as content of the block + $i = 0; + while (($v_buffer = substr($p_filename, (($i++) * 512), 512)) != '') { + $v_binary_data = pack("a512", "$v_buffer"); + $this->_writeBlock($v_binary_data); + } + + return true; + } + + /** + * @param mixed $v_binary_data + * @param mixed $v_header + * @return bool + */ + public function _readHeader($v_binary_data, &$v_header) + { + if (strlen($v_binary_data) == 0) { + $v_header['filename'] = ''; + return true; + } + + if (strlen($v_binary_data) != 512) { + $v_header['filename'] = ''; + $this->_error('Invalid block size : ' . strlen($v_binary_data)); + return false; + } + + if (!is_array($v_header)) { + $v_header = array(); + } + // ----- Calculate the checksum + $v_checksum = 0; + // ..... First part of the header + $v_binary_split = str_split($v_binary_data); + $v_checksum += array_sum(array_map('ord', array_slice($v_binary_split, 0, 148))); + $v_checksum += array_sum(array_map('ord', array(' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',))); + $v_checksum += array_sum(array_map('ord', array_slice($v_binary_split, 156, 512))); + + + $v_data = unpack($this->_fmt, $v_binary_data); + + if (strlen($v_data["prefix"]) > 0) { + $v_data["filename"] = "$v_data[prefix]/$v_data[filename]"; + } + + // ----- Extract the checksum + $v_header['checksum'] = OctDec(trim($v_data['checksum'])); + if ($v_header['checksum'] != $v_checksum) { + $v_header['filename'] = ''; + + // ----- Look for last block (empty block) + if (($v_checksum == 256) && ($v_header['checksum'] == 0)) { + return true; + } + + $this->_error( + 'Invalid checksum for file "' . $v_data['filename'] + . '" : ' . $v_checksum . ' calculated, ' + . $v_header['checksum'] . ' expected' + ); + return false; + } + + // ----- Extract the properties + $v_header['filename'] = rtrim($v_data['filename'], "\0"); + if ($this->_maliciousFilename($v_header['filename'])) { + $this->_error( + 'Malicious .tar detected, file "' . $v_header['filename'] . + '" will not install in desired directory tree' + ); + return false; + } + $v_header['mode'] = OctDec(trim($v_data['mode'])); + $v_header['uid'] = OctDec(trim($v_data['uid'])); + $v_header['gid'] = OctDec(trim($v_data['gid'])); + $v_header['size'] = $this->_tarRecToSize($v_data['size']); + $v_header['mtime'] = OctDec(trim($v_data['mtime'])); + if (($v_header['typeflag'] = $v_data['typeflag']) == "5") { + $v_header['size'] = 0; + } + $v_header['link'] = trim($v_data['link']); + /* ----- All these fields are removed form the header because + they do not carry interesting info + $v_header[magic] = trim($v_data[magic]); + $v_header[version] = trim($v_data[version]); + $v_header[uname] = trim($v_data[uname]); + $v_header[gname] = trim($v_data[gname]); + $v_header[devmajor] = trim($v_data[devmajor]); + $v_header[devminor] = trim($v_data[devminor]); + */ + + return true; + } + + /** + * Convert Tar record size to actual size + * + * @param string $tar_size + * @return size of tar record in bytes + */ + private function _tarRecToSize($tar_size) + { + /* + * First byte of size has a special meaning if bit 7 is set. + * + * Bit 7 indicates base-256 encoding if set. + * Bit 6 is the sign bit. + * Bits 5:0 are most significant value bits. + */ + $ch = ord($tar_size[0]); + if ($ch & 0x80) { + // Full 12-bytes record is required. + $rec_str = $tar_size . "\x00"; + + $size = ($ch & 0x40) ? -1 : 0; + $size = ($size << 6) | ($ch & 0x3f); + + for ($num_ch = 1; $num_ch < 12; ++$num_ch) { + $size = ($size * 256) + ord($rec_str[$num_ch]); + } + + return $size; + + } else { + return OctDec(trim($tar_size)); + } + } + + /** + * Detect and report a malicious file name + * + * @param string $file + * + * @return bool + */ + private function _maliciousFilename($file) + { + if (strpos($file, '/../') !== false) { + return true; + } + if (strpos($file, '../') === 0) { + return true; + } + return false; + } + + /** + * @param $v_header + * @return bool + */ + public function _readLongHeader(&$v_header) + { + $v_filename = ''; + $v_filesize = $v_header['size']; + $n = floor($v_header['size'] / 512); + for ($i = 0; $i < $n; $i++) { + $v_content = $this->_readBlock(); + $v_filename .= $v_content; + } + if (($v_header['size'] % 512) != 0) { + $v_content = $this->_readBlock(); + $v_filename .= $v_content; + } + + // ----- Read the next header + $v_binary_data = $this->_readBlock(); + + if (!$this->_readHeader($v_binary_data, $v_header)) { + return false; + } + + $v_filename = rtrim(substr($v_filename, 0, $v_filesize), "\0"); + $v_header['filename'] = $v_filename; + if ($this->_maliciousFilename($v_filename)) { + $this->_error( + 'Malicious .tar detected, file "' . $v_filename . + '" will not install in desired directory tree' + ); + return false; + } + + return true; + } + + /** + * This method extract from the archive one file identified by $p_filename. + * The return value is a string with the file content, or null on error. + * + * @param string $p_filename The path of the file to extract in a string. + * + * @return a string with the file content or null. + */ + private function _extractInString($p_filename) + { + $v_result_str = ""; + + while (strlen($v_binary_data = $this->_readBlock()) != 0) { + if (!$this->_readHeader($v_binary_data, $v_header)) { + return null; + } + + if ($v_header['filename'] == '') { + continue; + } + + // ----- Look for long filename + if ($v_header['typeflag'] == 'L') { + if (!$this->_readLongHeader($v_header)) { + return null; + } + } + + if ($v_header['filename'] == $p_filename) { + if ($v_header['typeflag'] == "5") { + $this->_error( + 'Unable to extract in string a directory ' + . 'entry {' . $v_header['filename'] . '}' + ); + return null; + } else { + $n = floor($v_header['size'] / 512); + for ($i = 0; $i < $n; $i++) { + $v_result_str .= $this->_readBlock(); + } + if (($v_header['size'] % 512) != 0) { + $v_content = $this->_readBlock(); + $v_result_str .= substr( + $v_content, + 0, + ($v_header['size'] % 512) + ); + } + return $v_result_str; + } + } else { + $this->_jumpBlock(ceil(($v_header['size'] / 512))); + } + } + + return null; + } + + /** + * @param string $p_path + * @param string $p_list_detail + * @param string $p_mode + * @param string $p_file_list + * @param string $p_remove_path + * @param bool $p_preserve + * @return bool + */ + public function _extractList( + $p_path, + &$p_list_detail, + $p_mode, + $p_file_list, + $p_remove_path, + $p_preserve = false + ) { + $v_result = true; + $v_nb = 0; + $v_extract_all = true; + $v_listing = false; + + $p_path = $this->_translateWinPath($p_path, false); + if ($p_path == '' || (substr($p_path, 0, 1) != '/' + && substr($p_path, 0, 3) != "../" && !strpos($p_path, ':')) + ) { + $p_path = "./" . $p_path; + } + $p_remove_path = $this->_translateWinPath($p_remove_path); + + // ----- Look for path to remove format (should end by /) + if (($p_remove_path != '') && (substr($p_remove_path, -1) != '/')) { + $p_remove_path .= '/'; + } + $p_remove_path_size = strlen($p_remove_path); + + switch ($p_mode) { + case "complete" : + $v_extract_all = true; + $v_listing = false; + break; + case "partial" : + $v_extract_all = false; + $v_listing = false; + break; + case "list" : + $v_extract_all = false; + $v_listing = true; + break; + default : + $this->_error('Invalid extract mode (' . $p_mode . ')'); + return false; + } + + clearstatcache(); + + while (strlen($v_binary_data = $this->_readBlock()) != 0) { + $v_extract_file = false; + $v_extraction_stopped = 0; + + if (!$this->_readHeader($v_binary_data, $v_header)) { + return false; + } + + if ($v_header['filename'] == '') { + continue; + } + + // ----- Look for long filename + if ($v_header['typeflag'] == 'L') { + if (!$this->_readLongHeader($v_header)) { + return false; + } + } + + // ignore extended / pax headers + if ($v_header['typeflag'] == 'x' || $v_header['typeflag'] == 'g') { + $this->_jumpBlock(ceil(($v_header['size'] / 512))); + continue; + } + + if ((!$v_extract_all) && (is_array($p_file_list))) { + // ----- By default no unzip if the file is not found + $v_extract_file = false; + + for ($i = 0; $i < sizeof($p_file_list); $i++) { + // ----- Look if it is a directory + if (substr($p_file_list[$i], -1) == '/') { + // ----- Look if the directory is in the filename path + if ((strlen($v_header['filename']) > strlen($p_file_list[$i])) + && (substr($v_header['filename'], 0, strlen($p_file_list[$i])) + == $p_file_list[$i]) + ) { + $v_extract_file = true; + break; + } + } // ----- It is a file, so compare the file names + elseif ($p_file_list[$i] == $v_header['filename']) { + $v_extract_file = true; + break; + } + } + } else { + $v_extract_file = true; + } + + // ----- Look if this file need to be extracted + if (($v_extract_file) && (!$v_listing)) { + if (($p_remove_path != '') + && (substr($v_header['filename'] . '/', 0, $p_remove_path_size) + == $p_remove_path) + ) { + $v_header['filename'] = substr( + $v_header['filename'], + $p_remove_path_size + ); + if ($v_header['filename'] == '') { + continue; + } + } + if (($p_path != './') && ($p_path != '/')) { + while (substr($p_path, -1) == '/') { + $p_path = substr($p_path, 0, strlen($p_path) - 1); + } + + if (substr($v_header['filename'], 0, 1) == '/') { + $v_header['filename'] = $p_path . $v_header['filename']; + } else { + $v_header['filename'] = $p_path . '/' . $v_header['filename']; + } + } + if (file_exists($v_header['filename'])) { + if ((@is_dir($v_header['filename'])) + && ($v_header['typeflag'] == '') + ) { + $this->_error( + 'File ' . $v_header['filename'] + . ' already exists as a directory' + ); + return false; + } + if (($this->_isArchive($v_header['filename'])) + && ($v_header['typeflag'] == "5") + ) { + $this->_error( + 'Directory ' . $v_header['filename'] + . ' already exists as a file' + ); + return false; + } + if (!is_writeable($v_header['filename'])) { + $this->_error( + 'File ' . $v_header['filename'] + . ' already exists and is write protected' + ); + return false; + } + if (filemtime($v_header['filename']) > $v_header['mtime']) { + // To be completed : An error or silent no replace ? + } + } // ----- Check the directory availability and create it if necessary + elseif (($v_result + = $this->_dirCheck( + ($v_header['typeflag'] == "5" + ? $v_header['filename'] + : dirname($v_header['filename'])) + )) != 1 + ) { + $this->_error('Unable to create path for ' . $v_header['filename']); + return false; + } + + if ($v_extract_file) { + if ($v_header['typeflag'] == "5") { + if (!@file_exists($v_header['filename'])) { + if (!@mkdir($v_header['filename'], 0777)) { + $this->_error( + 'Unable to create directory {' + . $v_header['filename'] . '}' + ); + return false; + } + } + } elseif ($v_header['typeflag'] == "2") { + if (@file_exists($v_header['filename'])) { + @unlink($v_header['filename']); + } + if (!@symlink($v_header['link'], $v_header['filename'])) { + $this->_error( + 'Unable to extract symbolic link {' + . $v_header['filename'] . '}' + ); + return false; + } + } else { + if (($v_dest_file = @fopen($v_header['filename'], "wb")) == 0) { + $this->_error( + 'Error while opening {' . $v_header['filename'] + . '} in write binary mode' + ); + return false; + } else { + $n = floor($v_header['size'] / 512); + for ($i = 0; $i < $n; $i++) { + $v_content = $this->_readBlock(); + fwrite($v_dest_file, $v_content, 512); + } + if (($v_header['size'] % 512) != 0) { + $v_content = $this->_readBlock(); + fwrite($v_dest_file, $v_content, ($v_header['size'] % 512)); + } + + @fclose($v_dest_file); + + if ($p_preserve) { + @chown($v_header['filename'], $v_header['uid']); + @chgrp($v_header['filename'], $v_header['gid']); + } + + // ----- Change the file mode, mtime + @touch($v_header['filename'], $v_header['mtime']); + if ($v_header['mode'] & 0111) { + // make file executable, obey umask + $mode = fileperms($v_header['filename']) | (~umask() & 0111); + @chmod($v_header['filename'], $mode); + } + } + + // ----- Check the file size + clearstatcache(); + if (!is_file($v_header['filename'])) { + $this->_error( + 'Extracted file ' . $v_header['filename'] + . 'does not exist. Archive may be corrupted.' + ); + return false; + } + + $filesize = filesize($v_header['filename']); + if ($filesize != $v_header['size']) { + $this->_error( + 'Extracted file ' . $v_header['filename'] + . ' does not have the correct file size \'' + . $filesize + . '\' (' . $v_header['size'] + . ' expected). Archive may be corrupted.' + ); + return false; + } + } + } else { + $this->_jumpBlock(ceil(($v_header['size'] / 512))); + } + } else { + $this->_jumpBlock(ceil(($v_header['size'] / 512))); + } + + /* TBC : Seems to be unused ... + if ($this->_compress) + $v_end_of_file = @gzeof($this->_file); + else + $v_end_of_file = @feof($this->_file); + */ + + if ($v_listing || $v_extract_file || $v_extraction_stopped) { + // ----- Log extracted files + if (($v_file_dir = dirname($v_header['filename'])) + == $v_header['filename'] + ) { + $v_file_dir = ''; + } + if ((substr($v_header['filename'], 0, 1) == '/') && ($v_file_dir == '')) { + $v_file_dir = '/'; + } + + $p_list_detail[$v_nb++] = $v_header; + if (is_array($p_file_list) && (count($p_list_detail) == count($p_file_list))) { + return true; + } + } + } + + return true; + } + + /** + * @return bool + */ + public function _openAppend() + { + if (filesize($this->_tarname) == 0) { + return $this->_openWrite(); + } + + if ($this->_compress) { + $this->_close(); + + if (!@rename($this->_tarname, $this->_tarname . ".tmp")) { + $this->_error( + 'Error while renaming \'' . $this->_tarname + . '\' to temporary file \'' . $this->_tarname + . '.tmp\'' + ); + return false; + } + + if ($this->_compress_type == 'gz') { + $v_temp_tar = @gzopen($this->_tarname . ".tmp", "rb"); + } elseif ($this->_compress_type == 'bz2') { + $v_temp_tar = @bzopen($this->_tarname . ".tmp", "r"); + } elseif ($this->_compress_type == 'lzma2') { + $v_temp_tar = @xzopen($this->_tarname . ".tmp", "r"); + } + + + if ($v_temp_tar == 0) { + $this->_error( + 'Unable to open file \'' . $this->_tarname + . '.tmp\' in binary read mode' + ); + @rename($this->_tarname . ".tmp", $this->_tarname); + return false; + } + + if (!$this->_openWrite()) { + @rename($this->_tarname . ".tmp", $this->_tarname); + return false; + } + + if ($this->_compress_type == 'gz') { + $end_blocks = 0; + + while (!@gzeof($v_temp_tar)) { + $v_buffer = @gzread($v_temp_tar, 512); + if ($v_buffer == ARCHIVE_TAR_END_BLOCK || strlen($v_buffer) == 0) { + $end_blocks++; + // do not copy end blocks, we will re-make them + // after appending + continue; + } elseif ($end_blocks > 0) { + for ($i = 0; $i < $end_blocks; $i++) { + $this->_writeBlock(ARCHIVE_TAR_END_BLOCK); + } + $end_blocks = 0; + } + $v_binary_data = pack("a512", $v_buffer); + $this->_writeBlock($v_binary_data); + } + + @gzclose($v_temp_tar); + } elseif ($this->_compress_type == 'bz2') { + $end_blocks = 0; + + while (strlen($v_buffer = @bzread($v_temp_tar, 512)) > 0) { + if ($v_buffer == ARCHIVE_TAR_END_BLOCK || strlen($v_buffer) == 0) { + $end_blocks++; + // do not copy end blocks, we will re-make them + // after appending + continue; + } elseif ($end_blocks > 0) { + for ($i = 0; $i < $end_blocks; $i++) { + $this->_writeBlock(ARCHIVE_TAR_END_BLOCK); + } + $end_blocks = 0; + } + $v_binary_data = pack("a512", $v_buffer); + $this->_writeBlock($v_binary_data); + } + + @bzclose($v_temp_tar); + } elseif ($this->_compress_type == 'lzma2') { + $end_blocks = 0; + + while (strlen($v_buffer = @xzread($v_temp_tar, 512)) > 0) { + if ($v_buffer == ARCHIVE_TAR_END_BLOCK || strlen($v_buffer) == 0) { + $end_blocks++; + // do not copy end blocks, we will re-make them + // after appending + continue; + } elseif ($end_blocks > 0) { + for ($i = 0; $i < $end_blocks; $i++) { + $this->_writeBlock(ARCHIVE_TAR_END_BLOCK); + } + $end_blocks = 0; + } + $v_binary_data = pack("a512", $v_buffer); + $this->_writeBlock($v_binary_data); + } + + @xzclose($v_temp_tar); + } + + if (!@unlink($this->_tarname . ".tmp")) { + $this->_error( + 'Error while deleting temporary file \'' + . $this->_tarname . '.tmp\'' + ); + } + } else { + // ----- For not compressed tar, just add files before the last + // one or two 512 bytes block + if (!$this->_openReadWrite()) { + return false; + } + + clearstatcache(); + $v_size = filesize($this->_tarname); + + // We might have zero, one or two end blocks. + // The standard is two, but we should try to handle + // other cases. + fseek($this->_file, $v_size - 1024); + if (fread($this->_file, 512) == ARCHIVE_TAR_END_BLOCK) { + fseek($this->_file, $v_size - 1024); + } elseif (fread($this->_file, 512) == ARCHIVE_TAR_END_BLOCK) { + fseek($this->_file, $v_size - 512); + } + } + + return true; + } + + /** + * @param $p_filelist + * @param string $p_add_dir + * @param string $p_remove_dir + * @return bool + */ + public function _append($p_filelist, $p_add_dir = '', $p_remove_dir = '') + { + if (!$this->_openAppend()) { + return false; + } + + if ($this->_addList($p_filelist, $p_add_dir, $p_remove_dir)) { + $this->_writeFooter(); + } + + $this->_close(); + + return true; + } + + /** + * Check if a directory exists and create it (including parent + * dirs) if not. + * + * @param string $p_dir directory to check + * + * @return bool true if the directory exists or was created + */ + public function _dirCheck($p_dir) + { + clearstatcache(); + if ((@is_dir($p_dir)) || ($p_dir == '')) { + return true; + } + + $p_parent_dir = dirname($p_dir); + + if (($p_parent_dir != $p_dir) && + ($p_parent_dir != '') && + (!$this->_dirCheck($p_parent_dir)) + ) { + return false; + } + + if (!@mkdir($p_dir, 0777)) { + $this->_error("Unable to create directory '$p_dir'"); + return false; + } + + return true; + } + + /** + * Compress path by changing for example "/dir/foo/../bar" to "/dir/bar", + * rand emove double slashes. + * + * @param string $p_dir path to reduce + * + * @return string reduced path + */ + private function _pathReduction($p_dir) + { + $v_result = ''; + + // ----- Look for not empty path + if ($p_dir != '') { + // ----- Explode path by directory names + $v_list = explode('/', $p_dir); + + // ----- Study directories from last to first + for ($i = sizeof($v_list) - 1; $i >= 0; $i--) { + // ----- Look for current path + if ($v_list[$i] == ".") { + // ----- Ignore this directory + // Should be the first $i=0, but no check is done + } else { + if ($v_list[$i] == "..") { + // ----- Ignore it and ignore the $i-1 + $i--; + } else { + if (($v_list[$i] == '') + && ($i != (sizeof($v_list) - 1)) + && ($i != 0) + ) { + // ----- Ignore only the double '//' in path, + // but not the first and last / + } else { + $v_result = $v_list[$i] . ($i != (sizeof($v_list) - 1) ? '/' + . $v_result : ''); + } + } + } + } + } + + if (defined('OS_WINDOWS') && OS_WINDOWS) { + $v_result = strtr($v_result, '\\', '/'); + } + + return $v_result; + } + + /** + * @param $p_path + * @param bool $p_remove_disk_letter + * @return string + */ + public function _translateWinPath($p_path, $p_remove_disk_letter = true) + { + if (defined('OS_WINDOWS') && OS_WINDOWS) { + // ----- Look for potential disk letter + if (($p_remove_disk_letter) + && (($v_position = strpos($p_path, ':')) != false) + ) { + $p_path = substr($p_path, $v_position + 1); + } + // ----- Change potential windows directory separator + if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0, 1) == '\\')) { + $p_path = strtr($p_path, '\\', '/'); + } + } + return $p_path; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/Console_Getopt/Console/Getopt.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/Console_Getopt/Console/Getopt.php new file mode 100644 index 0000000..0da8858 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/Console_Getopt/Console/Getopt.php @@ -0,0 +1,360 @@ + + * @license http://www.php.net/license/3_0.txt PHP 3.0 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Console_Getopt + */ + +require_once 'PEAR.php'; + +/** + * Command-line options parsing class. + * + * @category Console + * @package Console_Getopt + * @author Andrei Zmievski + * @license http://www.php.net/license/3_0.txt PHP 3.0 + * @link http://pear.php.net/package/Console_Getopt + */ +class Console_Getopt +{ + + /** + * Parses the command-line options. + * + * The first parameter to this function should be the list of command-line + * arguments without the leading reference to the running program. + * + * The second parameter is a string of allowed short options. Each of the + * option letters can be followed by a colon ':' to specify that the option + * requires an argument, or a double colon '::' to specify that the option + * takes an optional argument. + * + * The third argument is an optional array of allowed long options. The + * leading '--' should not be included in the option name. Options that + * require an argument should be followed by '=', and options that take an + * option argument should be followed by '=='. + * + * The return value is an array of two elements: the list of parsed + * options and the list of non-option command-line arguments. Each entry in + * the list of parsed options is a pair of elements - the first one + * specifies the option, and the second one specifies the option argument, + * if there was one. + * + * Long and short options can be mixed. + * + * Most of the semantics of this function are based on GNU getopt_long(). + * + * @param array $args an array of command-line arguments + * @param string $short_options specifies the list of allowed short options + * @param array $long_options specifies the list of allowed long options + * @param boolean $skip_unknown suppresses Console_Getopt: unrecognized option + * + * @return array two-element array containing the list of parsed options and + * the non-option arguments + */ + public static function getopt2($args, $short_options, $long_options = null, $skip_unknown = false) + { + return Console_Getopt::doGetopt(2, $args, $short_options, $long_options, $skip_unknown); + } + + /** + * This function expects $args to start with the script name (POSIX-style). + * Preserved for backwards compatibility. + * + * @param array $args an array of command-line arguments + * @param string $short_options specifies the list of allowed short options + * @param array $long_options specifies the list of allowed long options + * + * @see getopt2() + * @return array two-element array containing the list of parsed options and + * the non-option arguments + */ + public static function getopt($args, $short_options, $long_options = null, $skip_unknown = false) + { + return Console_Getopt::doGetopt(1, $args, $short_options, $long_options, $skip_unknown); + } + + /** + * The actual implementation of the argument parsing code. + * + * @param int $version Version to use + * @param array $args an array of command-line arguments + * @param string $short_options specifies the list of allowed short options + * @param array $long_options specifies the list of allowed long options + * @param boolean $skip_unknown suppresses Console_Getopt: unrecognized option + * + * @return array + */ + public static function doGetopt($version, $args, $short_options, $long_options = null, $skip_unknown = false) + { + // in case you pass directly readPHPArgv() as the first arg + if (PEAR::isError($args)) { + return $args; + } + + if (empty($args)) { + return array(array(), array()); + } + + $non_opts = $opts = array(); + + settype($args, 'array'); + + if ($long_options) { + sort($long_options); + } + + /* + * Preserve backwards compatibility with callers that relied on + * erroneous POSIX fix. + */ + if ($version < 2) { + if (isset($args[0]{0}) && $args[0]{0} != '-') { + array_shift($args); + } + } + + reset($args); + while (list($i, $arg) = each($args)) { + /* The special element '--' means explicit end of + options. Treat the rest of the arguments as non-options + and end the loop. */ + if ($arg == '--') { + $non_opts = array_merge($non_opts, array_slice($args, $i + 1)); + break; + } + + if ($arg{0} != '-' || (strlen($arg) > 1 && $arg{1} == '-' && !$long_options)) { + $non_opts = array_merge($non_opts, array_slice($args, $i)); + break; + } elseif (strlen($arg) > 1 && $arg{1} == '-') { + $error = Console_Getopt::_parseLongOption(substr($arg, 2), + $long_options, + $opts, + $args, + $skip_unknown); + if (PEAR::isError($error)) { + return $error; + } + } elseif ($arg == '-') { + // - is stdin + $non_opts = array_merge($non_opts, array_slice($args, $i)); + break; + } else { + $error = Console_Getopt::_parseShortOption(substr($arg, 1), + $short_options, + $opts, + $args, + $skip_unknown); + if (PEAR::isError($error)) { + return $error; + } + } + } + + return array($opts, $non_opts); + } + + /** + * Parse short option + * + * @param string $arg Argument + * @param string[] $short_options Available short options + * @param string[][] &$opts + * @param string[] &$args + * @param boolean $skip_unknown suppresses Console_Getopt: unrecognized option + * + * @return void + */ + protected static function _parseShortOption($arg, $short_options, &$opts, &$args, $skip_unknown) + { + for ($i = 0; $i < strlen($arg); $i++) { + $opt = $arg{$i}; + $opt_arg = null; + + /* Try to find the short option in the specifier string. */ + if (($spec = strstr($short_options, $opt)) === false || $arg{$i} == ':') { + if ($skip_unknown === true) { + break; + } + + $msg = "Console_Getopt: unrecognized option -- $opt"; + return PEAR::raiseError($msg); + } + + if (strlen($spec) > 1 && $spec{1} == ':') { + if (strlen($spec) > 2 && $spec{2} == ':') { + if ($i + 1 < strlen($arg)) { + /* Option takes an optional argument. Use the remainder of + the arg string if there is anything left. */ + $opts[] = array($opt, substr($arg, $i + 1)); + break; + } + } else { + /* Option requires an argument. Use the remainder of the arg + string if there is anything left. */ + if ($i + 1 < strlen($arg)) { + $opts[] = array($opt, substr($arg, $i + 1)); + break; + } else if (list(, $opt_arg) = each($args)) { + /* Else use the next argument. */; + if (Console_Getopt::_isShortOpt($opt_arg) + || Console_Getopt::_isLongOpt($opt_arg)) { + $msg = "option requires an argument --$opt"; + return PEAR::raiseError("Console_Getopt: " . $msg); + } + } else { + $msg = "option requires an argument --$opt"; + return PEAR::raiseError("Console_Getopt: " . $msg); + } + } + } + + $opts[] = array($opt, $opt_arg); + } + } + + /** + * Checks if an argument is a short option + * + * @param string $arg Argument to check + * + * @return bool + */ + protected static function _isShortOpt($arg) + { + return strlen($arg) == 2 && $arg[0] == '-' + && preg_match('/[a-zA-Z]/', $arg[1]); + } + + /** + * Checks if an argument is a long option + * + * @param string $arg Argument to check + * + * @return bool + */ + protected static function _isLongOpt($arg) + { + return strlen($arg) > 2 && $arg[0] == '-' && $arg[1] == '-' && + preg_match('/[a-zA-Z]+$/', substr($arg, 2)); + } + + /** + * Parse long option + * + * @param string $arg Argument + * @param string[] $long_options Available long options + * @param string[][] &$opts + * @param string[] &$args + * + * @return void|PEAR_Error + */ + protected static function _parseLongOption($arg, $long_options, &$opts, &$args, $skip_unknown) + { + @list($opt, $opt_arg) = explode('=', $arg, 2); + + $opt_len = strlen($opt); + + for ($i = 0; $i < count($long_options); $i++) { + $long_opt = $long_options[$i]; + $opt_start = substr($long_opt, 0, $opt_len); + + $long_opt_name = str_replace('=', '', $long_opt); + + /* Option doesn't match. Go on to the next one. */ + if ($long_opt_name != $opt) { + continue; + } + + $opt_rest = substr($long_opt, $opt_len); + + /* Check that the options uniquely matches one of the allowed + options. */ + if ($i + 1 < count($long_options)) { + $next_option_rest = substr($long_options[$i + 1], $opt_len); + } else { + $next_option_rest = ''; + } + + if ($opt_rest != '' && $opt{0} != '=' && + $i + 1 < count($long_options) && + $opt == substr($long_options[$i+1], 0, $opt_len) && + $next_option_rest != '' && + $next_option_rest{0} != '=') { + + $msg = "Console_Getopt: option --$opt is ambiguous"; + return PEAR::raiseError($msg); + } + + if (substr($long_opt, -1) == '=') { + if (substr($long_opt, -2) != '==') { + /* Long option requires an argument. + Take the next argument if one wasn't specified. */; + if (!strlen($opt_arg) && !(list(, $opt_arg) = each($args))) { + $msg = "Console_Getopt: option requires an argument --$opt"; + return PEAR::raiseError($msg); + } + + if (Console_Getopt::_isShortOpt($opt_arg) + || Console_Getopt::_isLongOpt($opt_arg)) { + $msg = "Console_Getopt: option requires an argument --$opt"; + return PEAR::raiseError($msg); + } + } + } else if ($opt_arg) { + $msg = "Console_Getopt: option --$opt doesn't allow an argument"; + return PEAR::raiseError($msg); + } + + $opts[] = array('--' . $opt, $opt_arg); + return; + } + + if ($skip_unknown === true) { + return; + } + + return PEAR::raiseError("Console_Getopt: unrecognized option --$opt"); + } + + /** + * Safely read the $argv PHP array across different PHP configurations. + * Will take care on register_globals and register_argc_argv ini directives + * + * @return mixed the $argv PHP array or PEAR error if not registered + */ + public static function readPHPArgv() + { + global $argv; + if (!is_array($argv)) { + if (!@is_array($_SERVER['argv'])) { + if (!@is_array($GLOBALS['HTTP_SERVER_VARS']['argv'])) { + $msg = "Could not read cmd args (register_argc_argv=Off?)"; + return PEAR::raiseError("Console_Getopt: " . $msg); + } + return $GLOBALS['HTTP_SERVER_VARS']['argv']; + } + return $_SERVER['argv']; + } + return $argv; + } + +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/HTTP_Request2/HTTP/Request2.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/HTTP_Request2/HTTP/Request2.php new file mode 100644 index 0000000..b835822 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/HTTP_Request2/HTTP/Request2.php @@ -0,0 +1,1037 @@ + + * @copyright 2008-2016 Alexey Borzov + * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License + * @link http://pear.php.net/package/HTTP_Request2 + */ + +/** + * A class representing an URL as per RFC 3986. + */ +if (!class_exists('Net_URL2', true)) { + require_once 'Net/URL2.php'; +} + +/** + * Exception class for HTTP_Request2 package + */ +require_once 'HTTP/Request2/Exception.php'; + +/** + * Class representing a HTTP request message + * + * @category HTTP + * @package HTTP_Request2 + * @author Alexey Borzov + * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License + * @version Release: 2.3.0 + * @link http://pear.php.net/package/HTTP_Request2 + * @link http://tools.ietf.org/html/rfc2616#section-5 + */ +class HTTP_Request2 implements SplSubject +{ + /**#@+ + * Constants for HTTP request methods + * + * @link http://tools.ietf.org/html/rfc2616#section-5.1.1 + */ + const METHOD_OPTIONS = 'OPTIONS'; + const METHOD_GET = 'GET'; + const METHOD_HEAD = 'HEAD'; + const METHOD_POST = 'POST'; + const METHOD_PUT = 'PUT'; + const METHOD_DELETE = 'DELETE'; + const METHOD_TRACE = 'TRACE'; + const METHOD_CONNECT = 'CONNECT'; + /**#@-*/ + + /**#@+ + * Constants for HTTP authentication schemes + * + * @link http://tools.ietf.org/html/rfc2617 + */ + const AUTH_BASIC = 'basic'; + const AUTH_DIGEST = 'digest'; + /**#@-*/ + + /** + * Regular expression used to check for invalid symbols in RFC 2616 tokens + * @link http://pear.php.net/bugs/bug.php?id=15630 + */ + const REGEXP_INVALID_TOKEN = '![\x00-\x1f\x7f-\xff()<>@,;:\\\\"/\[\]?={}\s]!'; + + /** + * Regular expression used to check for invalid symbols in cookie strings + * @link http://pear.php.net/bugs/bug.php?id=15630 + * @link http://web.archive.org/web/20080331104521/http://cgi.netscape.com/newsref/std/cookie_spec.html + */ + const REGEXP_INVALID_COOKIE = '/[\s,;]/'; + + /** + * Fileinfo magic database resource + * @var resource + * @see detectMimeType() + */ + private static $_fileinfoDb; + + /** + * Observers attached to the request (instances of SplObserver) + * @var array + */ + protected $observers = array(); + + /** + * Request URL + * @var Net_URL2 + */ + protected $url; + + /** + * Request method + * @var string + */ + protected $method = self::METHOD_GET; + + /** + * Authentication data + * @var array + * @see getAuth() + */ + protected $auth; + + /** + * Request headers + * @var array + */ + protected $headers = array(); + + /** + * Configuration parameters + * @var array + * @see setConfig() + */ + protected $config = array( + 'adapter' => 'HTTP_Request2_Adapter_Socket', + 'connect_timeout' => 10, + 'timeout' => 0, + 'use_brackets' => true, + 'protocol_version' => '1.1', + 'buffer_size' => 16384, + 'store_body' => true, + 'local_ip' => null, + + 'proxy_host' => '', + 'proxy_port' => '', + 'proxy_user' => '', + 'proxy_password' => '', + 'proxy_auth_scheme' => self::AUTH_BASIC, + 'proxy_type' => 'http', + + 'ssl_verify_peer' => true, + 'ssl_verify_host' => true, + 'ssl_cafile' => null, + 'ssl_capath' => null, + 'ssl_local_cert' => null, + 'ssl_passphrase' => null, + + 'digest_compat_ie' => false, + + 'follow_redirects' => false, + 'max_redirects' => 5, + 'strict_redirects' => false + ); + + /** + * Last event in request / response handling, intended for observers + * @var array + * @see getLastEvent() + */ + protected $lastEvent = array( + 'name' => 'start', + 'data' => null + ); + + /** + * Request body + * @var string|resource + * @see setBody() + */ + protected $body = ''; + + /** + * Array of POST parameters + * @var array + */ + protected $postParams = array(); + + /** + * Array of file uploads (for multipart/form-data POST requests) + * @var array + */ + protected $uploads = array(); + + /** + * Adapter used to perform actual HTTP request + * @var HTTP_Request2_Adapter + */ + protected $adapter; + + /** + * Cookie jar to persist cookies between requests + * @var HTTP_Request2_CookieJar + */ + protected $cookieJar = null; + + /** + * Constructor. Can set request URL, method and configuration array. + * + * Also sets a default value for User-Agent header. + * + * @param string|Net_Url2 $url Request URL + * @param string $method Request method + * @param array $config Configuration for this Request instance + */ + public function __construct( + $url = null, $method = self::METHOD_GET, array $config = array() + ) { + $this->setConfig($config); + if (!empty($url)) { + $this->setUrl($url); + } + if (!empty($method)) { + $this->setMethod($method); + } + $this->setHeader( + 'user-agent', 'HTTP_Request2/2.3.0 ' . + '(http://pear.php.net/package/http_request2) PHP/' . phpversion() + ); + } + + /** + * Sets the URL for this request + * + * If the URL has userinfo part (username & password) these will be removed + * and converted to auth data. If the URL does not have a path component, + * that will be set to '/'. + * + * @param string|Net_URL2 $url Request URL + * + * @return HTTP_Request2 + * @throws HTTP_Request2_LogicException + */ + public function setUrl($url) + { + if (is_string($url)) { + $url = new Net_URL2( + $url, array(Net_URL2::OPTION_USE_BRACKETS => $this->config['use_brackets']) + ); + } + if (!$url instanceof Net_URL2) { + throw new HTTP_Request2_LogicException( + 'Parameter is not a valid HTTP URL', + HTTP_Request2_Exception::INVALID_ARGUMENT + ); + } + // URL contains username / password? + if ($url->getUserinfo()) { + $username = $url->getUser(); + $password = $url->getPassword(); + $this->setAuth(rawurldecode($username), $password? rawurldecode($password): ''); + $url->setUserinfo(''); + } + if ('' == $url->getPath()) { + $url->setPath('/'); + } + $this->url = $url; + + return $this; + } + + /** + * Returns the request URL + * + * @return Net_URL2 + */ + public function getUrl() + { + return $this->url; + } + + /** + * Sets the request method + * + * @param string $method one of the methods defined in RFC 2616 + * + * @return HTTP_Request2 + * @throws HTTP_Request2_LogicException if the method name is invalid + */ + public function setMethod($method) + { + // Method name should be a token: http://tools.ietf.org/html/rfc2616#section-5.1.1 + if (preg_match(self::REGEXP_INVALID_TOKEN, $method)) { + throw new HTTP_Request2_LogicException( + "Invalid request method '{$method}'", + HTTP_Request2_Exception::INVALID_ARGUMENT + ); + } + $this->method = $method; + + return $this; + } + + /** + * Returns the request method + * + * @return string + */ + public function getMethod() + { + return $this->method; + } + + /** + * Sets the configuration parameter(s) + * + * The following parameters are available: + *
      + *
    • 'adapter' - adapter to use (string)
    • + *
    • 'connect_timeout' - Connection timeout in seconds (integer)
    • + *
    • 'timeout' - Total number of seconds a request can take. + * Use 0 for no limit, should be greater than + * 'connect_timeout' if set (integer)
    • + *
    • 'use_brackets' - Whether to append [] to array variable names (bool)
    • + *
    • 'protocol_version' - HTTP Version to use, '1.0' or '1.1' (string)
    • + *
    • 'buffer_size' - Buffer size to use for reading and writing (int)
    • + *
    • 'store_body' - Whether to store response body in response object. + * Set to false if receiving a huge response and + * using an Observer to save it (boolean)
    • + *
    • 'local_ip' - Specifies the IP address that will be used for accessing + * the network (string)
    • + *
    • 'proxy_type' - Proxy type, 'http' or 'socks5' (string)
    • + *
    • 'proxy_host' - Proxy server host (string)
    • + *
    • 'proxy_port' - Proxy server port (integer)
    • + *
    • 'proxy_user' - Proxy auth username (string)
    • + *
    • 'proxy_password' - Proxy auth password (string)
    • + *
    • 'proxy_auth_scheme' - Proxy auth scheme, one of HTTP_Request2::AUTH_* constants (string)
    • + *
    • 'proxy' - Shorthand for proxy_* parameters, proxy given as URL, + * e.g. 'socks5://localhost:1080/' (string)
    • + *
    • 'ssl_verify_peer' - Whether to verify peer's SSL certificate (bool)
    • + *
    • 'ssl_verify_host' - Whether to check that Common Name in SSL + * certificate matches host name (bool)
    • + *
    • 'ssl_cafile' - Cerificate Authority file to verify the peer + * with (use with 'ssl_verify_peer') (string)
    • + *
    • 'ssl_capath' - Directory holding multiple Certificate + * Authority files (string)
    • + *
    • 'ssl_local_cert' - Name of a file containing local cerificate (string)
    • + *
    • 'ssl_passphrase' - Passphrase with which local certificate + * was encoded (string)
    • + *
    • 'digest_compat_ie' - Whether to imitate behaviour of MSIE 5 and 6 + * in using URL without query string in digest + * authentication (boolean)
    • + *
    • 'follow_redirects' - Whether to automatically follow HTTP Redirects (boolean)
    • + *
    • 'max_redirects' - Maximum number of redirects to follow (integer)
    • + *
    • 'strict_redirects' - Whether to keep request method on redirects via status 301 and + * 302 (true, needed for compatibility with RFC 2616) + * or switch to GET (false, needed for compatibility with most + * browsers) (boolean)
    • + *
    + * + * @param string|array $nameOrConfig configuration parameter name or array + * ('parameter name' => 'parameter value') + * @param mixed $value parameter value if $nameOrConfig is not an array + * + * @return HTTP_Request2 + * @throws HTTP_Request2_LogicException If the parameter is unknown + */ + public function setConfig($nameOrConfig, $value = null) + { + if (is_array($nameOrConfig)) { + foreach ($nameOrConfig as $name => $value) { + $this->setConfig($name, $value); + } + + } elseif ('proxy' == $nameOrConfig) { + $url = new Net_URL2($value); + $this->setConfig(array( + 'proxy_type' => $url->getScheme(), + 'proxy_host' => $url->getHost(), + 'proxy_port' => $url->getPort(), + 'proxy_user' => rawurldecode($url->getUser()), + 'proxy_password' => rawurldecode($url->getPassword()) + )); + + } else { + if (!array_key_exists($nameOrConfig, $this->config)) { + throw new HTTP_Request2_LogicException( + "Unknown configuration parameter '{$nameOrConfig}'", + HTTP_Request2_Exception::INVALID_ARGUMENT + ); + } + $this->config[$nameOrConfig] = $value; + } + + return $this; + } + + /** + * Returns the value(s) of the configuration parameter(s) + * + * @param string $name parameter name + * + * @return mixed value of $name parameter, array of all configuration + * parameters if $name is not given + * @throws HTTP_Request2_LogicException If the parameter is unknown + */ + public function getConfig($name = null) + { + if (null === $name) { + return $this->config; + } elseif (!array_key_exists($name, $this->config)) { + throw new HTTP_Request2_LogicException( + "Unknown configuration parameter '{$name}'", + HTTP_Request2_Exception::INVALID_ARGUMENT + ); + } + return $this->config[$name]; + } + + /** + * Sets the autentification data + * + * @param string $user user name + * @param string $password password + * @param string $scheme authentication scheme + * + * @return HTTP_Request2 + */ + public function setAuth($user, $password = '', $scheme = self::AUTH_BASIC) + { + if (empty($user)) { + $this->auth = null; + } else { + $this->auth = array( + 'user' => (string)$user, + 'password' => (string)$password, + 'scheme' => $scheme + ); + } + + return $this; + } + + /** + * Returns the authentication data + * + * The array has the keys 'user', 'password' and 'scheme', where 'scheme' + * is one of the HTTP_Request2::AUTH_* constants. + * + * @return array + */ + public function getAuth() + { + return $this->auth; + } + + /** + * Sets request header(s) + * + * The first parameter may be either a full header string 'header: value' or + * header name. In the former case $value parameter is ignored, in the latter + * the header's value will either be set to $value or the header will be + * removed if $value is null. The first parameter can also be an array of + * headers, in that case method will be called recursively. + * + * Note that headers are treated case insensitively as per RFC 2616. + * + * + * $req->setHeader('Foo: Bar'); // sets the value of 'Foo' header to 'Bar' + * $req->setHeader('FoO', 'Baz'); // sets the value of 'Foo' header to 'Baz' + * $req->setHeader(array('foo' => 'Quux')); // sets the value of 'Foo' header to 'Quux' + * $req->setHeader('FOO'); // removes 'Foo' header from request + * + * + * @param string|array $name header name, header string ('Header: value') + * or an array of headers + * @param string|array|null $value header value if $name is not an array, + * header will be removed if value is null + * @param bool $replace whether to replace previous header with the + * same name or append to its value + * + * @return HTTP_Request2 + * @throws HTTP_Request2_LogicException + */ + public function setHeader($name, $value = null, $replace = true) + { + if (is_array($name)) { + foreach ($name as $k => $v) { + if (is_string($k)) { + $this->setHeader($k, $v, $replace); + } else { + $this->setHeader($v, null, $replace); + } + } + } else { + if (null === $value && strpos($name, ':')) { + list($name, $value) = array_map('trim', explode(':', $name, 2)); + } + // Header name should be a token: http://tools.ietf.org/html/rfc2616#section-4.2 + if (preg_match(self::REGEXP_INVALID_TOKEN, $name)) { + throw new HTTP_Request2_LogicException( + "Invalid header name '{$name}'", + HTTP_Request2_Exception::INVALID_ARGUMENT + ); + } + // Header names are case insensitive anyway + $name = strtolower($name); + if (null === $value) { + unset($this->headers[$name]); + + } else { + if (is_array($value)) { + $value = implode(', ', array_map('trim', $value)); + } elseif (is_string($value)) { + $value = trim($value); + } + if (!isset($this->headers[$name]) || $replace) { + $this->headers[$name] = $value; + } else { + $this->headers[$name] .= ', ' . $value; + } + } + } + + return $this; + } + + /** + * Returns the request headers + * + * The array is of the form ('header name' => 'header value'), header names + * are lowercased + * + * @return array + */ + public function getHeaders() + { + return $this->headers; + } + + /** + * Adds a cookie to the request + * + * If the request does not have a CookieJar object set, this method simply + * appends a cookie to "Cookie:" header. + * + * If a CookieJar object is available, the cookie is stored in that object. + * Data from request URL will be used for setting its 'domain' and 'path' + * parameters, 'expires' and 'secure' will be set to null and false, + * respectively. If you need further control, use CookieJar's methods. + * + * @param string $name cookie name + * @param string $value cookie value + * + * @return HTTP_Request2 + * @throws HTTP_Request2_LogicException + * @see setCookieJar() + */ + public function addCookie($name, $value) + { + if (!empty($this->cookieJar)) { + $this->cookieJar->store( + array('name' => $name, 'value' => $value), $this->url + ); + + } else { + $cookie = $name . '=' . $value; + if (preg_match(self::REGEXP_INVALID_COOKIE, $cookie)) { + throw new HTTP_Request2_LogicException( + "Invalid cookie: '{$cookie}'", + HTTP_Request2_Exception::INVALID_ARGUMENT + ); + } + $cookies = empty($this->headers['cookie'])? '': $this->headers['cookie'] . '; '; + $this->setHeader('cookie', $cookies . $cookie); + } + + return $this; + } + + /** + * Sets the request body + * + * If you provide file pointer rather than file name, it should support + * fstat() and rewind() operations. + * + * @param string|resource|HTTP_Request2_MultipartBody $body Either a + * string with the body or filename containing body or + * pointer to an open file or object with multipart body data + * @param bool $isFilename Whether + * first parameter is a filename + * + * @return HTTP_Request2 + * @throws HTTP_Request2_LogicException + */ + public function setBody($body, $isFilename = false) + { + if (!$isFilename && !is_resource($body)) { + if (!$body instanceof HTTP_Request2_MultipartBody) { + $this->body = (string)$body; + } else { + $this->body = $body; + } + } else { + $fileData = $this->fopenWrapper($body, empty($this->headers['content-type'])); + $this->body = $fileData['fp']; + if (empty($this->headers['content-type'])) { + $this->setHeader('content-type', $fileData['type']); + } + } + $this->postParams = $this->uploads = array(); + + return $this; + } + + /** + * Returns the request body + * + * @return string|resource|HTTP_Request2_MultipartBody + */ + public function getBody() + { + if (self::METHOD_POST == $this->method + && (!empty($this->postParams) || !empty($this->uploads)) + ) { + if (0 === strpos($this->headers['content-type'], 'application/x-www-form-urlencoded')) { + $body = http_build_query($this->postParams, '', '&'); + if (!$this->getConfig('use_brackets')) { + $body = preg_replace('/%5B\d+%5D=/', '=', $body); + } + // support RFC 3986 by not encoding '~' symbol (request #15368) + return str_replace('%7E', '~', $body); + + } elseif (0 === strpos($this->headers['content-type'], 'multipart/form-data')) { + require_once 'HTTP/Request2/MultipartBody.php'; + return new HTTP_Request2_MultipartBody( + $this->postParams, $this->uploads, $this->getConfig('use_brackets') + ); + } + } + return $this->body; + } + + /** + * Adds a file to form-based file upload + * + * Used to emulate file upload via a HTML form. The method also sets + * Content-Type of HTTP request to 'multipart/form-data'. + * + * If you just want to send the contents of a file as the body of HTTP + * request you should use setBody() method. + * + * If you provide file pointers rather than file names, they should support + * fstat() and rewind() operations. + * + * @param string $fieldName name of file-upload field + * @param string|resource|array $filename full name of local file, + * pointer to open file or an array of files + * @param string $sendFilename filename to send in the request + * @param string $contentType content-type of file being uploaded + * + * @return HTTP_Request2 + * @throws HTTP_Request2_LogicException + */ + public function addUpload( + $fieldName, $filename, $sendFilename = null, $contentType = null + ) { + if (!is_array($filename)) { + $fileData = $this->fopenWrapper($filename, empty($contentType)); + $this->uploads[$fieldName] = array( + 'fp' => $fileData['fp'], + 'filename' => !empty($sendFilename)? $sendFilename + :(is_string($filename)? basename($filename): 'anonymous.blob') , + 'size' => $fileData['size'], + 'type' => empty($contentType)? $fileData['type']: $contentType + ); + } else { + $fps = $names = $sizes = $types = array(); + foreach ($filename as $f) { + if (!is_array($f)) { + $f = array($f); + } + $fileData = $this->fopenWrapper($f[0], empty($f[2])); + $fps[] = $fileData['fp']; + $names[] = !empty($f[1])? $f[1] + :(is_string($f[0])? basename($f[0]): 'anonymous.blob'); + $sizes[] = $fileData['size']; + $types[] = empty($f[2])? $fileData['type']: $f[2]; + } + $this->uploads[$fieldName] = array( + 'fp' => $fps, 'filename' => $names, 'size' => $sizes, 'type' => $types + ); + } + if (empty($this->headers['content-type']) + || 'application/x-www-form-urlencoded' == $this->headers['content-type'] + ) { + $this->setHeader('content-type', 'multipart/form-data'); + } + + return $this; + } + + /** + * Adds POST parameter(s) to the request. + * + * @param string|array $name parameter name or array ('name' => 'value') + * @param mixed $value parameter value (can be an array) + * + * @return HTTP_Request2 + */ + public function addPostParameter($name, $value = null) + { + if (!is_array($name)) { + $this->postParams[$name] = $value; + } else { + foreach ($name as $k => $v) { + $this->addPostParameter($k, $v); + } + } + if (empty($this->headers['content-type'])) { + $this->setHeader('content-type', 'application/x-www-form-urlencoded'); + } + + return $this; + } + + /** + * Attaches a new observer + * + * @param SplObserver $observer any object implementing SplObserver + */ + public function attach(SplObserver $observer) + { + foreach ($this->observers as $attached) { + if ($attached === $observer) { + return; + } + } + $this->observers[] = $observer; + } + + /** + * Detaches an existing observer + * + * @param SplObserver $observer any object implementing SplObserver + */ + public function detach(SplObserver $observer) + { + foreach ($this->observers as $key => $attached) { + if ($attached === $observer) { + unset($this->observers[$key]); + return; + } + } + } + + /** + * Notifies all observers + */ + public function notify() + { + foreach ($this->observers as $observer) { + $observer->update($this); + } + } + + /** + * Sets the last event + * + * Adapters should use this method to set the current state of the request + * and notify the observers. + * + * @param string $name event name + * @param mixed $data event data + */ + public function setLastEvent($name, $data = null) + { + $this->lastEvent = array( + 'name' => $name, + 'data' => $data + ); + $this->notify(); + } + + /** + * Returns the last event + * + * Observers should use this method to access the last change in request. + * The following event names are possible: + *
      + *
    • 'connect' - after connection to remote server, + * data is the destination (string)
    • + *
    • 'disconnect' - after disconnection from server
    • + *
    • 'sentHeaders' - after sending the request headers, + * data is the headers sent (string)
    • + *
    • 'sentBodyPart' - after sending a part of the request body, + * data is the length of that part (int)
    • + *
    • 'sentBody' - after sending the whole request body, + * data is request body length (int)
    • + *
    • 'receivedHeaders' - after receiving the response headers, + * data is HTTP_Request2_Response object
    • + *
    • 'receivedBodyPart' - after receiving a part of the response + * body, data is that part (string)
    • + *
    • 'receivedEncodedBodyPart' - as 'receivedBodyPart', but data is still + * encoded by Content-Encoding
    • + *
    • 'receivedBody' - after receiving the complete response + * body, data is HTTP_Request2_Response object
    • + *
    • 'warning' - a problem arose during the request + * that is not severe enough to throw + * an Exception, data is the warning + * message (string). Currently dispatched if + * response body was received incompletely.
    • + *
    + * Different adapters may not send all the event types. Mock adapter does + * not send any events to the observers. + * + * @return array The array has two keys: 'name' and 'data' + */ + public function getLastEvent() + { + return $this->lastEvent; + } + + /** + * Sets the adapter used to actually perform the request + * + * You can pass either an instance of a class implementing HTTP_Request2_Adapter + * or a class name. The method will only try to include a file if the class + * name starts with HTTP_Request2_Adapter_, it will also try to prepend this + * prefix to the class name if it doesn't contain any underscores, so that + * + * $request->setAdapter('curl'); + * + * will work. + * + * @param string|HTTP_Request2_Adapter $adapter Adapter to use + * + * @return HTTP_Request2 + * @throws HTTP_Request2_LogicException + */ + public function setAdapter($adapter) + { + if (is_string($adapter)) { + if (!class_exists($adapter, false)) { + if (false === strpos($adapter, '_')) { + $adapter = 'HTTP_Request2_Adapter_' . ucfirst($adapter); + } + if (!class_exists($adapter, false) + && preg_match('/^HTTP_Request2_Adapter_([a-zA-Z0-9]+)$/', $adapter) + ) { + include_once str_replace('_', DIRECTORY_SEPARATOR, $adapter) . '.php'; + } + if (!class_exists($adapter, false)) { + throw new HTTP_Request2_LogicException( + "Class {$adapter} not found", + HTTP_Request2_Exception::MISSING_VALUE + ); + } + } + $adapter = new $adapter; + } + if (!$adapter instanceof HTTP_Request2_Adapter) { + throw new HTTP_Request2_LogicException( + 'Parameter is not a HTTP request adapter', + HTTP_Request2_Exception::INVALID_ARGUMENT + ); + } + $this->adapter = $adapter; + + return $this; + } + + /** + * Sets the cookie jar + * + * A cookie jar is used to maintain cookies across HTTP requests and + * responses. Cookies from jar will be automatically added to the request + * headers based on request URL. + * + * @param HTTP_Request2_CookieJar|bool $jar Existing CookieJar object, true to + * create a new one, false to remove + * + * @return HTTP_Request2 + * @throws HTTP_Request2_LogicException + */ + public function setCookieJar($jar = true) + { + if (!class_exists('HTTP_Request2_CookieJar', false)) { + require_once 'HTTP/Request2/CookieJar.php'; + } + + if ($jar instanceof HTTP_Request2_CookieJar) { + $this->cookieJar = $jar; + } elseif (true === $jar) { + $this->cookieJar = new HTTP_Request2_CookieJar(); + } elseif (!$jar) { + $this->cookieJar = null; + } else { + throw new HTTP_Request2_LogicException( + 'Invalid parameter passed to setCookieJar()', + HTTP_Request2_Exception::INVALID_ARGUMENT + ); + } + + return $this; + } + + /** + * Returns current CookieJar object or null if none + * + * @return HTTP_Request2_CookieJar|null + */ + public function getCookieJar() + { + return $this->cookieJar; + } + + /** + * Sends the request and returns the response + * + * @throws HTTP_Request2_Exception + * @return HTTP_Request2_Response + */ + public function send() + { + // Sanity check for URL + if (!$this->url instanceof Net_URL2 + || !$this->url->isAbsolute() + || !in_array(strtolower($this->url->getScheme()), array('https', 'http')) + ) { + throw new HTTP_Request2_LogicException( + 'HTTP_Request2 needs an absolute HTTP(S) request URL, ' + . ($this->url instanceof Net_URL2 + ? "'" . $this->url->__toString() . "'" : 'none') + . ' given', + HTTP_Request2_Exception::INVALID_ARGUMENT + ); + } + if (empty($this->adapter)) { + $this->setAdapter($this->getConfig('adapter')); + } + // magic_quotes_runtime may break file uploads and chunked response + // processing; see bug #4543. Don't use ini_get() here; see bug #16440. + if ($magicQuotes = get_magic_quotes_runtime()) { + set_magic_quotes_runtime(false); + } + // force using single byte encoding if mbstring extension overloads + // strlen() and substr(); see bug #1781, bug #10605 + if (extension_loaded('mbstring') && (2 & ini_get('mbstring.func_overload'))) { + $oldEncoding = mb_internal_encoding(); + mb_internal_encoding('8bit'); + } + + try { + $response = $this->adapter->sendRequest($this); + } catch (Exception $e) { + } + // cleanup in either case (poor man's "finally" clause) + if ($magicQuotes) { + set_magic_quotes_runtime(true); + } + if (!empty($oldEncoding)) { + mb_internal_encoding($oldEncoding); + } + // rethrow the exception + if (!empty($e)) { + throw $e; + } + return $response; + } + + /** + * Wrapper around fopen()/fstat() used by setBody() and addUpload() + * + * @param string|resource $file file name or pointer to open file + * @param bool $detectType whether to try autodetecting MIME + * type of file, will only work if $file is a + * filename, not pointer + * + * @return array array('fp' => file pointer, 'size' => file size, 'type' => MIME type) + * @throws HTTP_Request2_LogicException + */ + protected function fopenWrapper($file, $detectType = false) + { + if (!is_string($file) && !is_resource($file)) { + throw new HTTP_Request2_LogicException( + "Filename or file pointer resource expected", + HTTP_Request2_Exception::INVALID_ARGUMENT + ); + } + $fileData = array( + 'fp' => is_string($file)? null: $file, + 'type' => 'application/octet-stream', + 'size' => 0 + ); + if (is_string($file)) { + if (!($fileData['fp'] = @fopen($file, 'rb'))) { + $error = error_get_last(); + throw new HTTP_Request2_LogicException( + $error['message'], HTTP_Request2_Exception::READ_ERROR + ); + } + if ($detectType) { + $fileData['type'] = self::detectMimeType($file); + } + } + if (!($stat = fstat($fileData['fp']))) { + throw new HTTP_Request2_LogicException( + "fstat() call failed", HTTP_Request2_Exception::READ_ERROR + ); + } + $fileData['size'] = $stat['size']; + + return $fileData; + } + + /** + * Tries to detect MIME type of a file + * + * The method will try to use fileinfo extension if it is available, + * deprecated mime_content_type() function in the other case. If neither + * works, default 'application/octet-stream' MIME type is returned + * + * @param string $filename file name + * + * @return string file MIME type + */ + protected static function detectMimeType($filename) + { + // finfo extension from PECL available + if (function_exists('finfo_open')) { + if (!isset(self::$_fileinfoDb)) { + self::$_fileinfoDb = @finfo_open(FILEINFO_MIME); + } + if (self::$_fileinfoDb) { + $info = finfo_file(self::$_fileinfoDb, $filename); + } + } + // (deprecated) mime_content_type function available + if (empty($info) && function_exists('mime_content_type')) { + $info = mime_content_type($filename); + } + return empty($info)? 'application/octet-stream': $info; + } +} +?> diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/HTTP_Request2/HTTP/Request2/Adapter.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/HTTP_Request2/HTTP/Request2/Adapter.php new file mode 100644 index 0000000..0356327 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/HTTP_Request2/HTTP/Request2/Adapter.php @@ -0,0 +1,137 @@ + + * @copyright 2008-2016 Alexey Borzov + * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License + * @link http://pear.php.net/package/HTTP_Request2 + */ + +/** + * Class representing a HTTP response + */ +require_once 'HTTP/Request2/Response.php'; + +/** + * Base class for HTTP_Request2 adapters + * + * HTTP_Request2 class itself only defines methods for aggregating the request + * data, all actual work of sending the request to the remote server and + * receiving its response is performed by adapters. + * + * @category HTTP + * @package HTTP_Request2 + * @author Alexey Borzov + * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License + * @version Release: 2.3.0 + * @link http://pear.php.net/package/HTTP_Request2 + */ +abstract class HTTP_Request2_Adapter +{ + /** + * A list of methods that MUST NOT have a request body, per RFC 2616 + * @var array + */ + protected static $bodyDisallowed = array('TRACE'); + + /** + * Methods having defined semantics for request body + * + * Content-Length header (indicating that the body follows, section 4.3 of + * RFC 2616) will be sent for these methods even if no body was added + * + * @var array + * @link http://pear.php.net/bugs/bug.php?id=12900 + * @link http://pear.php.net/bugs/bug.php?id=14740 + */ + protected static $bodyRequired = array('POST', 'PUT'); + + /** + * Request being sent + * @var HTTP_Request2 + */ + protected $request; + + /** + * Request body + * @var string|resource|HTTP_Request2_MultipartBody + * @see HTTP_Request2::getBody() + */ + protected $requestBody; + + /** + * Length of the request body + * @var integer + */ + protected $contentLength; + + /** + * Sends request to the remote server and returns its response + * + * @param HTTP_Request2 $request HTTP request message + * + * @return HTTP_Request2_Response + * @throws HTTP_Request2_Exception + */ + abstract public function sendRequest(HTTP_Request2 $request); + + /** + * Calculates length of the request body, adds proper headers + * + * @param array &$headers associative array of request headers, this method + * will add proper 'Content-Length' and 'Content-Type' + * headers to this array (or remove them if not needed) + */ + protected function calculateRequestLength(&$headers) + { + $this->requestBody = $this->request->getBody(); + + if (is_string($this->requestBody)) { + $this->contentLength = strlen($this->requestBody); + } elseif (is_resource($this->requestBody)) { + $stat = fstat($this->requestBody); + $this->contentLength = $stat['size']; + rewind($this->requestBody); + } else { + $this->contentLength = $this->requestBody->getLength(); + $headers['content-type'] = 'multipart/form-data; boundary=' . + $this->requestBody->getBoundary(); + $this->requestBody->rewind(); + } + + if (in_array($this->request->getMethod(), self::$bodyDisallowed) + || 0 == $this->contentLength + ) { + // No body: send a Content-Length header nonetheless (request #12900), + // but do that only for methods that require a body (bug #14740) + if (in_array($this->request->getMethod(), self::$bodyRequired)) { + $headers['content-length'] = 0; + } else { + unset($headers['content-length']); + // if the method doesn't require a body and doesn't have a + // body, don't send a Content-Type header. (request #16799) + unset($headers['content-type']); + } + } else { + if (empty($headers['content-type'])) { + $headers['content-type'] = 'application/x-www-form-urlencoded'; + } + // Content-Length should not be sent for chunked Transfer-Encoding (bug #20125) + if (!isset($headers['transfer-encoding'])) { + $headers['content-length'] = $this->contentLength; + } + } + } +} +?> diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/HTTP_Request2/HTTP/Request2/Adapter/Curl.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/HTTP_Request2/HTTP/Request2/Adapter/Curl.php new file mode 100644 index 0000000..13d4a29 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/HTTP_Request2/HTTP/Request2/Adapter/Curl.php @@ -0,0 +1,577 @@ + + * @copyright 2008-2016 Alexey Borzov + * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License + * @link http://pear.php.net/package/HTTP_Request2 + */ + +/** + * Base class for HTTP_Request2 adapters + */ +require_once 'HTTP/Request2/Adapter.php'; + +/** + * Adapter for HTTP_Request2 wrapping around cURL extension + * + * @category HTTP + * @package HTTP_Request2 + * @author Alexey Borzov + * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License + * @version Release: 2.3.0 + * @link http://pear.php.net/package/HTTP_Request2 + */ +class HTTP_Request2_Adapter_Curl extends HTTP_Request2_Adapter +{ + /** + * Mapping of header names to cURL options + * @var array + */ + protected static $headerMap = array( + 'accept-encoding' => CURLOPT_ENCODING, + 'cookie' => CURLOPT_COOKIE, + 'referer' => CURLOPT_REFERER, + 'user-agent' => CURLOPT_USERAGENT + ); + + /** + * Mapping of SSL context options to cURL options + * @var array + */ + protected static $sslContextMap = array( + 'ssl_verify_peer' => CURLOPT_SSL_VERIFYPEER, + 'ssl_cafile' => CURLOPT_CAINFO, + 'ssl_capath' => CURLOPT_CAPATH, + 'ssl_local_cert' => CURLOPT_SSLCERT, + 'ssl_passphrase' => CURLOPT_SSLCERTPASSWD + ); + + /** + * Mapping of CURLE_* constants to Exception subclasses and error codes + * @var array + */ + protected static $errorMap = array( + CURLE_UNSUPPORTED_PROTOCOL => array('HTTP_Request2_MessageException', + HTTP_Request2_Exception::NON_HTTP_REDIRECT), + CURLE_COULDNT_RESOLVE_PROXY => array('HTTP_Request2_ConnectionException'), + CURLE_COULDNT_RESOLVE_HOST => array('HTTP_Request2_ConnectionException'), + CURLE_COULDNT_CONNECT => array('HTTP_Request2_ConnectionException'), + // error returned from write callback + CURLE_WRITE_ERROR => array('HTTP_Request2_MessageException', + HTTP_Request2_Exception::NON_HTTP_REDIRECT), + CURLE_OPERATION_TIMEOUTED => array('HTTP_Request2_MessageException', + HTTP_Request2_Exception::TIMEOUT), + CURLE_HTTP_RANGE_ERROR => array('HTTP_Request2_MessageException'), + CURLE_SSL_CONNECT_ERROR => array('HTTP_Request2_ConnectionException'), + CURLE_LIBRARY_NOT_FOUND => array('HTTP_Request2_LogicException', + HTTP_Request2_Exception::MISCONFIGURATION), + CURLE_FUNCTION_NOT_FOUND => array('HTTP_Request2_LogicException', + HTTP_Request2_Exception::MISCONFIGURATION), + CURLE_ABORTED_BY_CALLBACK => array('HTTP_Request2_MessageException', + HTTP_Request2_Exception::NON_HTTP_REDIRECT), + CURLE_TOO_MANY_REDIRECTS => array('HTTP_Request2_MessageException', + HTTP_Request2_Exception::TOO_MANY_REDIRECTS), + CURLE_SSL_PEER_CERTIFICATE => array('HTTP_Request2_ConnectionException'), + CURLE_GOT_NOTHING => array('HTTP_Request2_MessageException'), + CURLE_SSL_ENGINE_NOTFOUND => array('HTTP_Request2_LogicException', + HTTP_Request2_Exception::MISCONFIGURATION), + CURLE_SSL_ENGINE_SETFAILED => array('HTTP_Request2_LogicException', + HTTP_Request2_Exception::MISCONFIGURATION), + CURLE_SEND_ERROR => array('HTTP_Request2_MessageException'), + CURLE_RECV_ERROR => array('HTTP_Request2_MessageException'), + CURLE_SSL_CERTPROBLEM => array('HTTP_Request2_LogicException', + HTTP_Request2_Exception::INVALID_ARGUMENT), + CURLE_SSL_CIPHER => array('HTTP_Request2_ConnectionException'), + CURLE_SSL_CACERT => array('HTTP_Request2_ConnectionException'), + CURLE_BAD_CONTENT_ENCODING => array('HTTP_Request2_MessageException'), + ); + + /** + * Response being received + * @var HTTP_Request2_Response + */ + protected $response; + + /** + * Whether 'sentHeaders' event was sent to observers + * @var boolean + */ + protected $eventSentHeaders = false; + + /** + * Whether 'receivedHeaders' event was sent to observers + * @var boolean + */ + protected $eventReceivedHeaders = false; + + /** + * Whether 'sentBoody' event was sent to observers + * @var boolean + */ + protected $eventSentBody = false; + + /** + * Position within request body + * @var integer + * @see callbackReadBody() + */ + protected $position = 0; + + /** + * Information about last transfer, as returned by curl_getinfo() + * @var array + */ + protected $lastInfo; + + /** + * Creates a subclass of HTTP_Request2_Exception from curl error data + * + * @param resource $ch curl handle + * + * @return HTTP_Request2_Exception + */ + protected static function wrapCurlError($ch) + { + $nativeCode = curl_errno($ch); + $message = 'Curl error: ' . curl_error($ch); + if (!isset(self::$errorMap[$nativeCode])) { + return new HTTP_Request2_Exception($message, 0, $nativeCode); + } else { + $class = self::$errorMap[$nativeCode][0]; + $code = empty(self::$errorMap[$nativeCode][1]) + ? 0 : self::$errorMap[$nativeCode][1]; + return new $class($message, $code, $nativeCode); + } + } + + /** + * Sends request to the remote server and returns its response + * + * @param HTTP_Request2 $request HTTP request message + * + * @return HTTP_Request2_Response + * @throws HTTP_Request2_Exception + */ + public function sendRequest(HTTP_Request2 $request) + { + if (!extension_loaded('curl')) { + throw new HTTP_Request2_LogicException( + 'cURL extension not available', HTTP_Request2_Exception::MISCONFIGURATION + ); + } + + $this->request = $request; + $this->response = null; + $this->position = 0; + $this->eventSentHeaders = false; + $this->eventReceivedHeaders = false; + $this->eventSentBody = false; + + try { + if (false === curl_exec($ch = $this->createCurlHandle())) { + $e = self::wrapCurlError($ch); + } + } catch (Exception $e) { + } + if (isset($ch)) { + $this->lastInfo = curl_getinfo($ch); + if (CURLE_OK !== curl_errno($ch)) { + $this->request->setLastEvent('warning', curl_error($ch)); + } + curl_close($ch); + } + + $response = $this->response; + unset($this->request, $this->requestBody, $this->response); + + if (!empty($e)) { + throw $e; + } + + if ($jar = $request->getCookieJar()) { + $jar->addCookiesFromResponse($response); + } + + if (0 < $this->lastInfo['size_download']) { + $request->setLastEvent('receivedBody', $response); + } + return $response; + } + + /** + * Returns information about last transfer + * + * @return array associative array as returned by curl_getinfo() + */ + public function getInfo() + { + return $this->lastInfo; + } + + /** + * Creates a new cURL handle and populates it with data from the request + * + * @return resource a cURL handle, as created by curl_init() + * @throws HTTP_Request2_LogicException + * @throws HTTP_Request2_NotImplementedException + */ + protected function createCurlHandle() + { + $ch = curl_init(); + + curl_setopt_array($ch, array( + // setup write callbacks + CURLOPT_HEADERFUNCTION => array($this, 'callbackWriteHeader'), + CURLOPT_WRITEFUNCTION => array($this, 'callbackWriteBody'), + // buffer size + CURLOPT_BUFFERSIZE => $this->request->getConfig('buffer_size'), + // connection timeout + CURLOPT_CONNECTTIMEOUT => $this->request->getConfig('connect_timeout'), + // save full outgoing headers, in case someone is interested + CURLINFO_HEADER_OUT => true, + // request url + CURLOPT_URL => $this->request->getUrl()->getUrl() + )); + + // set up redirects + if (!$this->request->getConfig('follow_redirects')) { + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false); + } else { + if (!@curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true)) { + throw new HTTP_Request2_LogicException( + 'Redirect support in curl is unavailable due to open_basedir or safe_mode setting', + HTTP_Request2_Exception::MISCONFIGURATION + ); + } + curl_setopt($ch, CURLOPT_MAXREDIRS, $this->request->getConfig('max_redirects')); + // limit redirects to http(s), works in 5.2.10+ + if (defined('CURLOPT_REDIR_PROTOCOLS')) { + curl_setopt($ch, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS); + } + // works in 5.3.2+, http://bugs.php.net/bug.php?id=49571 + if ($this->request->getConfig('strict_redirects') && defined('CURLOPT_POSTREDIR')) { + curl_setopt($ch, CURLOPT_POSTREDIR, 3); + } + } + + // set local IP via CURLOPT_INTERFACE (request #19515) + if ($ip = $this->request->getConfig('local_ip')) { + curl_setopt($ch, CURLOPT_INTERFACE, $ip); + } + + // request timeout + if ($timeout = $this->request->getConfig('timeout')) { + curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); + } + + // set HTTP version + switch ($this->request->getConfig('protocol_version')) { + case '1.0': + curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); + break; + case '1.1': + curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); + } + + // set request method + switch ($this->request->getMethod()) { + case HTTP_Request2::METHOD_GET: + curl_setopt($ch, CURLOPT_HTTPGET, true); + break; + case HTTP_Request2::METHOD_POST: + curl_setopt($ch, CURLOPT_POST, true); + break; + case HTTP_Request2::METHOD_HEAD: + curl_setopt($ch, CURLOPT_NOBODY, true); + break; + case HTTP_Request2::METHOD_PUT: + curl_setopt($ch, CURLOPT_UPLOAD, true); + break; + default: + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $this->request->getMethod()); + } + + // set proxy, if needed + if ($host = $this->request->getConfig('proxy_host')) { + if (!($port = $this->request->getConfig('proxy_port'))) { + throw new HTTP_Request2_LogicException( + 'Proxy port not provided', HTTP_Request2_Exception::MISSING_VALUE + ); + } + curl_setopt($ch, CURLOPT_PROXY, $host . ':' . $port); + if ($user = $this->request->getConfig('proxy_user')) { + curl_setopt( + $ch, CURLOPT_PROXYUSERPWD, + $user . ':' . $this->request->getConfig('proxy_password') + ); + switch ($this->request->getConfig('proxy_auth_scheme')) { + case HTTP_Request2::AUTH_BASIC: + curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_BASIC); + break; + case HTTP_Request2::AUTH_DIGEST: + curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_DIGEST); + } + } + if ($type = $this->request->getConfig('proxy_type')) { + switch ($type) { + case 'http': + curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP); + break; + case 'socks5': + curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5); + break; + default: + throw new HTTP_Request2_NotImplementedException( + "Proxy type '{$type}' is not supported" + ); + } + } + } + + // set authentication data + if ($auth = $this->request->getAuth()) { + curl_setopt($ch, CURLOPT_USERPWD, $auth['user'] . ':' . $auth['password']); + switch ($auth['scheme']) { + case HTTP_Request2::AUTH_BASIC: + curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); + break; + case HTTP_Request2::AUTH_DIGEST: + curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST); + } + } + + // set SSL options + foreach ($this->request->getConfig() as $name => $value) { + if ('ssl_verify_host' == $name && null !== $value) { + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, $value? 2: 0); + } elseif (isset(self::$sslContextMap[$name]) && null !== $value) { + curl_setopt($ch, self::$sslContextMap[$name], $value); + } + } + + $headers = $this->request->getHeaders(); + // make cURL automagically send proper header + if (!isset($headers['accept-encoding'])) { + $headers['accept-encoding'] = ''; + } + + if (($jar = $this->request->getCookieJar()) + && ($cookies = $jar->getMatching($this->request->getUrl(), true)) + ) { + $headers['cookie'] = (empty($headers['cookie'])? '': $headers['cookie'] . '; ') . $cookies; + } + + // set headers having special cURL keys + foreach (self::$headerMap as $name => $option) { + if (isset($headers[$name])) { + curl_setopt($ch, $option, $headers[$name]); + unset($headers[$name]); + } + } + + $this->calculateRequestLength($headers); + if (isset($headers['content-length']) || isset($headers['transfer-encoding'])) { + $this->workaroundPhpBug47204($ch, $headers); + } + + // set headers not having special keys + $headersFmt = array(); + foreach ($headers as $name => $value) { + $canonicalName = implode('-', array_map('ucfirst', explode('-', $name))); + $headersFmt[] = $canonicalName . ': ' . $value; + } + curl_setopt($ch, CURLOPT_HTTPHEADER, $headersFmt); + + return $ch; + } + + /** + * Workaround for PHP bug #47204 that prevents rewinding request body + * + * The workaround consists of reading the entire request body into memory + * and setting it as CURLOPT_POSTFIELDS, so it isn't recommended for large + * file uploads, use Socket adapter instead. + * + * @param resource $ch cURL handle + * @param array &$headers Request headers + */ + protected function workaroundPhpBug47204($ch, &$headers) + { + // no redirects, no digest auth -> probably no rewind needed + // also apply workaround only for POSTs, othrerwise we get + // https://pear.php.net/bugs/bug.php?id=20440 for PUTs + if (!$this->request->getConfig('follow_redirects') + && (!($auth = $this->request->getAuth()) + || HTTP_Request2::AUTH_DIGEST != $auth['scheme']) + || HTTP_Request2::METHOD_POST !== $this->request->getMethod() + ) { + curl_setopt($ch, CURLOPT_READFUNCTION, array($this, 'callbackReadBody')); + + } else { + // rewind may be needed, read the whole body into memory + if ($this->requestBody instanceof HTTP_Request2_MultipartBody) { + $this->requestBody = $this->requestBody->__toString(); + + } elseif (is_resource($this->requestBody)) { + $fp = $this->requestBody; + $this->requestBody = ''; + while (!feof($fp)) { + $this->requestBody .= fread($fp, 16384); + } + } + // curl hangs up if content-length is present + unset($headers['content-length']); + curl_setopt($ch, CURLOPT_POSTFIELDS, $this->requestBody); + } + } + + /** + * Callback function called by cURL for reading the request body + * + * @param resource $ch cURL handle + * @param resource $fd file descriptor (not used) + * @param integer $length maximum length of data to return + * + * @return string part of the request body, up to $length bytes + */ + protected function callbackReadBody($ch, $fd, $length) + { + if (!$this->eventSentHeaders) { + $this->request->setLastEvent( + 'sentHeaders', curl_getinfo($ch, CURLINFO_HEADER_OUT) + ); + $this->eventSentHeaders = true; + } + if (in_array($this->request->getMethod(), self::$bodyDisallowed) + || 0 == $this->contentLength || $this->position >= $this->contentLength + ) { + return ''; + } + if (is_string($this->requestBody)) { + $string = substr($this->requestBody, $this->position, $length); + } elseif (is_resource($this->requestBody)) { + $string = fread($this->requestBody, $length); + } else { + $string = $this->requestBody->read($length); + } + $this->request->setLastEvent('sentBodyPart', strlen($string)); + $this->position += strlen($string); + return $string; + } + + /** + * Callback function called by cURL for saving the response headers + * + * @param resource $ch cURL handle + * @param string $string response header (with trailing CRLF) + * + * @return integer number of bytes saved + * @see HTTP_Request2_Response::parseHeaderLine() + */ + protected function callbackWriteHeader($ch, $string) + { + if (!$this->eventSentHeaders + // we may receive a second set of headers if doing e.g. digest auth + // but don't bother with 100-Continue responses (bug #15785) + || $this->eventReceivedHeaders && $this->response->getStatus() >= 200 + ) { + $this->request->setLastEvent( + 'sentHeaders', curl_getinfo($ch, CURLINFO_HEADER_OUT) + ); + } + if (!$this->eventSentBody) { + $upload = curl_getinfo($ch, CURLINFO_SIZE_UPLOAD); + // if body wasn't read by the callback, send event with total body size + if ($upload > $this->position) { + $this->request->setLastEvent( + 'sentBodyPart', $upload - $this->position + ); + } + if ($upload > 0) { + $this->request->setLastEvent('sentBody', $upload); + } + } + $this->eventSentHeaders = true; + $this->eventSentBody = true; + + if ($this->eventReceivedHeaders || empty($this->response)) { + $this->eventReceivedHeaders = false; + $this->response = new HTTP_Request2_Response( + $string, false, curl_getinfo($ch, CURLINFO_EFFECTIVE_URL) + ); + + } else { + $this->response->parseHeaderLine($string); + if ('' == trim($string)) { + // don't bother with 100-Continue responses (bug #15785) + if (200 <= $this->response->getStatus()) { + $this->request->setLastEvent('receivedHeaders', $this->response); + } + + if ($this->request->getConfig('follow_redirects') && $this->response->isRedirect()) { + $redirectUrl = new Net_URL2($this->response->getHeader('location')); + + // for versions lower than 5.2.10, check the redirection URL protocol + if (!defined('CURLOPT_REDIR_PROTOCOLS') && $redirectUrl->isAbsolute() + && !in_array($redirectUrl->getScheme(), array('http', 'https')) + ) { + return -1; + } + + if ($jar = $this->request->getCookieJar()) { + $jar->addCookiesFromResponse($this->response); + if (!$redirectUrl->isAbsolute()) { + $redirectUrl = $this->request->getUrl()->resolve($redirectUrl); + } + if ($cookies = $jar->getMatching($redirectUrl, true)) { + curl_setopt($ch, CURLOPT_COOKIE, $cookies); + } + } + } + $this->eventReceivedHeaders = true; + $this->eventSentBody = false; + } + } + return strlen($string); + } + + /** + * Callback function called by cURL for saving the response body + * + * @param resource $ch cURL handle (not used) + * @param string $string part of the response body + * + * @return integer number of bytes saved + * @throws HTTP_Request2_MessageException + * @see HTTP_Request2_Response::appendBody() + */ + protected function callbackWriteBody($ch, $string) + { + // cURL calls WRITEFUNCTION callback without calling HEADERFUNCTION if + // response doesn't start with proper HTTP status line (see bug #15716) + if (empty($this->response)) { + throw new HTTP_Request2_MessageException( + "Malformed response: {$string}", + HTTP_Request2_Exception::MALFORMED_RESPONSE + ); + } + if ($this->request->getConfig('store_body')) { + $this->response->appendBody($string); + } + $this->request->setLastEvent('receivedBodyPart', $string); + return strlen($string); + } +} +?> diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/HTTP_Request2/HTTP/Request2/Adapter/Mock.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/HTTP_Request2/HTTP/Request2/Adapter/Mock.php new file mode 100644 index 0000000..22b4282 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/HTTP_Request2/HTTP/Request2/Adapter/Mock.php @@ -0,0 +1,166 @@ + + * @copyright 2008-2016 Alexey Borzov + * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License + * @link http://pear.php.net/package/HTTP_Request2 + */ + +/** + * Base class for HTTP_Request2 adapters + */ +require_once 'HTTP/Request2/Adapter.php'; + +/** + * Mock adapter intended for testing + * + * Can be used to test applications depending on HTTP_Request2 package without + * actually performing any HTTP requests. This adapter will return responses + * previously added via addResponse() + * + * $mock = new HTTP_Request2_Adapter_Mock(); + * $mock->addResponse("HTTP/1.1 ... "); + * + * $request = new HTTP_Request2(); + * $request->setAdapter($mock); + * + * // This will return the response set above + * $response = $req->send(); + * + * + * @category HTTP + * @package HTTP_Request2 + * @author Alexey Borzov + * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License + * @version Release: 2.3.0 + * @link http://pear.php.net/package/HTTP_Request2 + */ +class HTTP_Request2_Adapter_Mock extends HTTP_Request2_Adapter +{ + /** + * A queue of responses to be returned by sendRequest() + * @var array + */ + protected $responses = array(); + + /** + * Returns the next response from the queue built by addResponse() + * + * Only responses without explicit URLs or with URLs equal to request URL + * will be considered. If matching response is not found or the queue is + * empty then default empty response with status 400 will be returned, + * if an Exception object was added to the queue it will be thrown. + * + * @param HTTP_Request2 $request HTTP request message + * + * @return HTTP_Request2_Response + * @throws Exception + */ + public function sendRequest(HTTP_Request2 $request) + { + $requestUrl = (string)$request->getUrl(); + $response = null; + foreach ($this->responses as $k => $v) { + if (!$v[1] || $requestUrl == $v[1]) { + $response = $v[0]; + array_splice($this->responses, $k, 1); + break; + } + } + if (!$response) { + return self::createResponseFromString("HTTP/1.1 400 Bad Request\r\n\r\n"); + + } elseif ($response instanceof HTTP_Request2_Response) { + return $response; + + } else { + // rethrow the exception + $class = get_class($response); + $message = $response->getMessage(); + $code = $response->getCode(); + throw new $class($message, $code); + } + } + + /** + * Adds response to the queue + * + * @param mixed $response either a string, a pointer to an open file, + * an instance of HTTP_Request2_Response or Exception + * @param string $url A request URL this response should be valid for + * (see {@link http://pear.php.net/bugs/bug.php?id=19276}) + * + * @throws HTTP_Request2_Exception + */ + public function addResponse($response, $url = null) + { + if (is_string($response)) { + $response = self::createResponseFromString($response); + } elseif (is_resource($response)) { + $response = self::createResponseFromFile($response); + } elseif (!$response instanceof HTTP_Request2_Response && + !$response instanceof Exception + ) { + throw new HTTP_Request2_Exception('Parameter is not a valid response'); + } + $this->responses[] = array($response, $url); + } + + /** + * Creates a new HTTP_Request2_Response object from a string + * + * @param string $str string containing HTTP response message + * + * @return HTTP_Request2_Response + * @throws HTTP_Request2_Exception + */ + public static function createResponseFromString($str) + { + $parts = preg_split('!(\r?\n){2}!m', $str, 2); + $headerLines = explode("\n", $parts[0]); + $response = new HTTP_Request2_Response(array_shift($headerLines)); + foreach ($headerLines as $headerLine) { + $response->parseHeaderLine($headerLine); + } + $response->parseHeaderLine(''); + if (isset($parts[1])) { + $response->appendBody($parts[1]); + } + return $response; + } + + /** + * Creates a new HTTP_Request2_Response object from a file + * + * @param resource $fp file pointer returned by fopen() + * + * @return HTTP_Request2_Response + * @throws HTTP_Request2_Exception + */ + public static function createResponseFromFile($fp) + { + $response = new HTTP_Request2_Response(fgets($fp)); + do { + $headerLine = fgets($fp); + $response->parseHeaderLine($headerLine); + } while ('' != trim($headerLine)); + + while (!feof($fp)) { + $response->appendBody(fread($fp, 8192)); + } + return $response; + } +} +?> \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/HTTP_Request2/HTTP/Request2/Adapter/Socket.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/HTTP_Request2/HTTP/Request2/Adapter/Socket.php new file mode 100644 index 0000000..3a1d186 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/HTTP_Request2/HTTP/Request2/Adapter/Socket.php @@ -0,0 +1,1138 @@ + + * @copyright 2008-2016 Alexey Borzov + * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License + * @link http://pear.php.net/package/HTTP_Request2 + */ + +/** Base class for HTTP_Request2 adapters */ +require_once 'HTTP/Request2/Adapter.php'; + +/** Socket wrapper class */ +require_once 'HTTP/Request2/SocketWrapper.php'; + +/** + * Socket-based adapter for HTTP_Request2 + * + * This adapter uses only PHP sockets and will work on almost any PHP + * environment. Code is based on original HTTP_Request PEAR package. + * + * @category HTTP + * @package HTTP_Request2 + * @author Alexey Borzov + * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License + * @version Release: 2.3.0 + * @link http://pear.php.net/package/HTTP_Request2 + */ +class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter +{ + /** + * Regular expression for 'token' rule from RFC 2616 + */ + const REGEXP_TOKEN = '[^\x00-\x1f\x7f-\xff()<>@,;:\\\\"/\[\]?={}\s]+'; + + /** + * Regular expression for 'quoted-string' rule from RFC 2616 + */ + const REGEXP_QUOTED_STRING = '"(?>[^"\\\\]+|\\\\.)*"'; + + /** + * Connected sockets, needed for Keep-Alive support + * @var array + * @see connect() + */ + protected static $sockets = array(); + + /** + * Data for digest authentication scheme + * + * The keys for the array are URL prefixes. + * + * The values are associative arrays with data (realm, nonce, nonce-count, + * opaque...) needed for digest authentication. Stored here to prevent making + * duplicate requests to digest-protected resources after we have already + * received the challenge. + * + * @var array + */ + protected static $challenges = array(); + + /** + * Connected socket + * @var HTTP_Request2_SocketWrapper + * @see connect() + */ + protected $socket; + + /** + * Challenge used for server digest authentication + * @var array + */ + protected $serverChallenge; + + /** + * Challenge used for proxy digest authentication + * @var array + */ + protected $proxyChallenge; + + /** + * Remaining length of the current chunk, when reading chunked response + * @var integer + * @see readChunked() + */ + protected $chunkLength = 0; + + /** + * Remaining amount of redirections to follow + * + * Starts at 'max_redirects' configuration parameter and is reduced on each + * subsequent redirect. An Exception will be thrown once it reaches zero. + * + * @var integer + */ + protected $redirectCountdown = null; + + /** + * Whether to wait for "100 Continue" response before sending request body + * @var bool + */ + protected $expect100Continue = false; + + /** + * Sends request to the remote server and returns its response + * + * @param HTTP_Request2 $request HTTP request message + * + * @return HTTP_Request2_Response + * @throws HTTP_Request2_Exception + */ + public function sendRequest(HTTP_Request2 $request) + { + $this->request = $request; + + try { + $keepAlive = $this->connect(); + $headers = $this->prepareHeaders(); + $this->socket->write($headers); + // provide request headers to the observer, see request #7633 + $this->request->setLastEvent('sentHeaders', $headers); + + if (!$this->expect100Continue) { + $this->writeBody(); + $response = $this->readResponse(); + + } else { + $response = $this->readResponse(); + if (!$response || 100 == $response->getStatus()) { + $this->expect100Continue = false; + // either got "100 Continue" or timed out -> send body + $this->writeBody(); + $response = $this->readResponse(); + } + } + + + if ($jar = $request->getCookieJar()) { + $jar->addCookiesFromResponse($response); + } + + if (!$this->canKeepAlive($keepAlive, $response)) { + $this->disconnect(); + } + + if ($this->shouldUseProxyDigestAuth($response)) { + return $this->sendRequest($request); + } + if ($this->shouldUseServerDigestAuth($response)) { + return $this->sendRequest($request); + } + if ($authInfo = $response->getHeader('authentication-info')) { + $this->updateChallenge($this->serverChallenge, $authInfo); + } + if ($proxyInfo = $response->getHeader('proxy-authentication-info')) { + $this->updateChallenge($this->proxyChallenge, $proxyInfo); + } + + } catch (Exception $e) { + $this->disconnect(); + } + + unset($this->request, $this->requestBody); + + if (!empty($e)) { + $this->redirectCountdown = null; + throw $e; + } + + if (!$request->getConfig('follow_redirects') || !$response->isRedirect()) { + $this->redirectCountdown = null; + return $response; + } else { + return $this->handleRedirect($request, $response); + } + } + + /** + * Connects to the remote server + * + * @return bool whether the connection can be persistent + * @throws HTTP_Request2_Exception + */ + protected function connect() + { + $secure = 0 == strcasecmp($this->request->getUrl()->getScheme(), 'https'); + $tunnel = HTTP_Request2::METHOD_CONNECT == $this->request->getMethod(); + $headers = $this->request->getHeaders(); + $reqHost = $this->request->getUrl()->getHost(); + if (!($reqPort = $this->request->getUrl()->getPort())) { + $reqPort = $secure? 443: 80; + } + + $httpProxy = $socksProxy = false; + if (!($host = $this->request->getConfig('proxy_host'))) { + $host = $reqHost; + $port = $reqPort; + } else { + if (!($port = $this->request->getConfig('proxy_port'))) { + throw new HTTP_Request2_LogicException( + 'Proxy port not provided', + HTTP_Request2_Exception::MISSING_VALUE + ); + } + if ('http' == ($type = $this->request->getConfig('proxy_type'))) { + $httpProxy = true; + } elseif ('socks5' == $type) { + $socksProxy = true; + } else { + throw new HTTP_Request2_NotImplementedException( + "Proxy type '{$type}' is not supported" + ); + } + } + + if ($tunnel && !$httpProxy) { + throw new HTTP_Request2_LogicException( + "Trying to perform CONNECT request without proxy", + HTTP_Request2_Exception::MISSING_VALUE + ); + } + if ($secure && !in_array('ssl', stream_get_transports())) { + throw new HTTP_Request2_LogicException( + 'Need OpenSSL support for https:// requests', + HTTP_Request2_Exception::MISCONFIGURATION + ); + } + + // RFC 2068, section 19.7.1: A client MUST NOT send the Keep-Alive + // connection token to a proxy server... + if ($httpProxy && !$secure && !empty($headers['connection']) + && 'Keep-Alive' == $headers['connection'] + ) { + $this->request->setHeader('connection'); + } + + $keepAlive = ('1.1' == $this->request->getConfig('protocol_version') && + empty($headers['connection'])) || + (!empty($headers['connection']) && + 'Keep-Alive' == $headers['connection']); + + $options = array(); + if ($ip = $this->request->getConfig('local_ip')) { + $options['socket'] = array( + 'bindto' => (false === strpos($ip, ':') ? $ip : '[' . $ip . ']') . ':0' + ); + } + if ($secure || $tunnel) { + $options['ssl'] = array(); + foreach ($this->request->getConfig() as $name => $value) { + if ('ssl_' == substr($name, 0, 4) && null !== $value) { + if ('ssl_verify_host' == $name) { + if (version_compare(phpversion(), '5.6', '<')) { + if ($value) { + $options['ssl']['CN_match'] = $reqHost; + } + + } else { + $options['ssl']['verify_peer_name'] = $value; + $options['ssl']['peer_name'] = $reqHost; + } + + } else { + $options['ssl'][substr($name, 4)] = $value; + } + } + } + ksort($options['ssl']); + } + + // Use global request timeout if given, see feature requests #5735, #8964 + if ($timeout = $this->request->getConfig('timeout')) { + $deadline = time() + $timeout; + } else { + $deadline = null; + } + + // Changing SSL context options after connection is established does *not* + // work, we need a new connection if options change + $remote = ((!$secure || $httpProxy || $socksProxy)? 'tcp://': 'tls://') + . $host . ':' . $port; + $socketKey = $remote . ( + ($secure && $httpProxy || $socksProxy) + ? "->{$reqHost}:{$reqPort}" : '' + ) . (empty($options)? '': ':' . serialize($options)); + unset($this->socket); + + // We use persistent connections and have a connected socket? + // Ensure that the socket is still connected, see bug #16149 + if ($keepAlive && !empty(self::$sockets[$socketKey]) + && !self::$sockets[$socketKey]->eof() + ) { + $this->socket =& self::$sockets[$socketKey]; + + } else { + if ($socksProxy) { + require_once 'HTTP/Request2/SOCKS5.php'; + + $this->socket = new HTTP_Request2_SOCKS5( + $remote, $this->request->getConfig('connect_timeout'), + $options, $this->request->getConfig('proxy_user'), + $this->request->getConfig('proxy_password') + ); + // handle request timeouts ASAP + $this->socket->setDeadline($deadline, $this->request->getConfig('timeout')); + $this->socket->connect($reqHost, $reqPort); + if (!$secure) { + $conninfo = "tcp://{$reqHost}:{$reqPort} via {$remote}"; + } else { + $this->socket->enableCrypto(); + $conninfo = "tls://{$reqHost}:{$reqPort} via {$remote}"; + } + + } elseif ($secure && $httpProxy && !$tunnel) { + $this->establishTunnel(); + $conninfo = "tls://{$reqHost}:{$reqPort} via {$remote}"; + + } else { + $this->socket = new HTTP_Request2_SocketWrapper( + $remote, $this->request->getConfig('connect_timeout'), $options + ); + } + $this->request->setLastEvent('connect', empty($conninfo)? $remote: $conninfo); + self::$sockets[$socketKey] =& $this->socket; + } + $this->socket->setDeadline($deadline, $this->request->getConfig('timeout')); + return $keepAlive; + } + + /** + * Establishes a tunnel to a secure remote server via HTTP CONNECT request + * + * This method will fail if 'ssl_verify_peer' is enabled. Probably because PHP + * sees that we are connected to a proxy server (duh!) rather than the server + * that presents its certificate. + * + * @link http://tools.ietf.org/html/rfc2817#section-5.2 + * @throws HTTP_Request2_Exception + */ + protected function establishTunnel() + { + $donor = new self; + $connect = new HTTP_Request2( + $this->request->getUrl(), HTTP_Request2::METHOD_CONNECT, + array_merge($this->request->getConfig(), array('adapter' => $donor)) + ); + $response = $connect->send(); + // Need any successful (2XX) response + if (200 > $response->getStatus() || 300 <= $response->getStatus()) { + throw new HTTP_Request2_ConnectionException( + 'Failed to connect via HTTPS proxy. Proxy response: ' . + $response->getStatus() . ' ' . $response->getReasonPhrase() + ); + } + $this->socket = $donor->socket; + $this->socket->enableCrypto(); + } + + /** + * Checks whether current connection may be reused or should be closed + * + * @param boolean $requestKeepAlive whether connection could + * be persistent in the first place + * @param HTTP_Request2_Response $response response object to check + * + * @return boolean + */ + protected function canKeepAlive($requestKeepAlive, HTTP_Request2_Response $response) + { + // Do not close socket on successful CONNECT request + if (HTTP_Request2::METHOD_CONNECT == $this->request->getMethod() + && 200 <= $response->getStatus() && 300 > $response->getStatus() + ) { + return true; + } + + $lengthKnown = 'chunked' == strtolower($response->getHeader('transfer-encoding')) + || null !== $response->getHeader('content-length') + // no body possible for such responses, see also request #17031 + || HTTP_Request2::METHOD_HEAD == $this->request->getMethod() + || in_array($response->getStatus(), array(204, 304)); + $persistent = 'keep-alive' == strtolower($response->getHeader('connection')) || + (null === $response->getHeader('connection') && + '1.1' == $response->getVersion()); + return $requestKeepAlive && $lengthKnown && $persistent; + } + + /** + * Disconnects from the remote server + */ + protected function disconnect() + { + if (!empty($this->socket)) { + $this->socket = null; + $this->request->setLastEvent('disconnect'); + } + } + + /** + * Handles HTTP redirection + * + * This method will throw an Exception if redirect to a non-HTTP(S) location + * is attempted, also if number of redirects performed already is equal to + * 'max_redirects' configuration parameter. + * + * @param HTTP_Request2 $request Original request + * @param HTTP_Request2_Response $response Response containing redirect + * + * @return HTTP_Request2_Response Response from a new location + * @throws HTTP_Request2_Exception + */ + protected function handleRedirect( + HTTP_Request2 $request, HTTP_Request2_Response $response + ) { + if (is_null($this->redirectCountdown)) { + $this->redirectCountdown = $request->getConfig('max_redirects'); + } + if (0 == $this->redirectCountdown) { + $this->redirectCountdown = null; + // Copying cURL behaviour + throw new HTTP_Request2_MessageException( + 'Maximum (' . $request->getConfig('max_redirects') . ') redirects followed', + HTTP_Request2_Exception::TOO_MANY_REDIRECTS + ); + } + $redirectUrl = new Net_URL2( + $response->getHeader('location'), + array(Net_URL2::OPTION_USE_BRACKETS => $request->getConfig('use_brackets')) + ); + // refuse non-HTTP redirect + if ($redirectUrl->isAbsolute() + && !in_array($redirectUrl->getScheme(), array('http', 'https')) + ) { + $this->redirectCountdown = null; + throw new HTTP_Request2_MessageException( + 'Refusing to redirect to a non-HTTP URL ' . $redirectUrl->__toString(), + HTTP_Request2_Exception::NON_HTTP_REDIRECT + ); + } + // Theoretically URL should be absolute (see http://tools.ietf.org/html/rfc2616#section-14.30), + // but in practice it is often not + if (!$redirectUrl->isAbsolute()) { + $redirectUrl = $request->getUrl()->resolve($redirectUrl); + } + $redirect = clone $request; + $redirect->setUrl($redirectUrl); + if (303 == $response->getStatus() + || (!$request->getConfig('strict_redirects') + && in_array($response->getStatus(), array(301, 302))) + ) { + $redirect->setMethod(HTTP_Request2::METHOD_GET); + $redirect->setBody(''); + } + + if (0 < $this->redirectCountdown) { + $this->redirectCountdown--; + } + return $this->sendRequest($redirect); + } + + /** + * Checks whether another request should be performed with server digest auth + * + * Several conditions should be satisfied for it to return true: + * - response status should be 401 + * - auth credentials should be set in the request object + * - response should contain WWW-Authenticate header with digest challenge + * - there is either no challenge stored for this URL or new challenge + * contains stale=true parameter (in other case we probably just failed + * due to invalid username / password) + * + * The method stores challenge values in $challenges static property + * + * @param HTTP_Request2_Response $response response to check + * + * @return boolean whether another request should be performed + * @throws HTTP_Request2_Exception in case of unsupported challenge parameters + */ + protected function shouldUseServerDigestAuth(HTTP_Request2_Response $response) + { + // no sense repeating a request if we don't have credentials + if (401 != $response->getStatus() || !$this->request->getAuth()) { + return false; + } + if (!$challenge = $this->parseDigestChallenge($response->getHeader('www-authenticate'))) { + return false; + } + + $url = $this->request->getUrl(); + $scheme = $url->getScheme(); + $host = $scheme . '://' . $url->getHost(); + if ($port = $url->getPort()) { + if ((0 == strcasecmp($scheme, 'http') && 80 != $port) + || (0 == strcasecmp($scheme, 'https') && 443 != $port) + ) { + $host .= ':' . $port; + } + } + + if (!empty($challenge['domain'])) { + $prefixes = array(); + foreach (preg_split('/\\s+/', $challenge['domain']) as $prefix) { + // don't bother with different servers + if ('/' == substr($prefix, 0, 1)) { + $prefixes[] = $host . $prefix; + } + } + } + if (empty($prefixes)) { + $prefixes = array($host . '/'); + } + + $ret = true; + foreach ($prefixes as $prefix) { + if (!empty(self::$challenges[$prefix]) + && (empty($challenge['stale']) || strcasecmp('true', $challenge['stale'])) + ) { + // probably credentials are invalid + $ret = false; + } + self::$challenges[$prefix] =& $challenge; + } + return $ret; + } + + /** + * Checks whether another request should be performed with proxy digest auth + * + * Several conditions should be satisfied for it to return true: + * - response status should be 407 + * - proxy auth credentials should be set in the request object + * - response should contain Proxy-Authenticate header with digest challenge + * - there is either no challenge stored for this proxy or new challenge + * contains stale=true parameter (in other case we probably just failed + * due to invalid username / password) + * + * The method stores challenge values in $challenges static property + * + * @param HTTP_Request2_Response $response response to check + * + * @return boolean whether another request should be performed + * @throws HTTP_Request2_Exception in case of unsupported challenge parameters + */ + protected function shouldUseProxyDigestAuth(HTTP_Request2_Response $response) + { + if (407 != $response->getStatus() || !$this->request->getConfig('proxy_user')) { + return false; + } + if (!($challenge = $this->parseDigestChallenge($response->getHeader('proxy-authenticate')))) { + return false; + } + + $key = 'proxy://' . $this->request->getConfig('proxy_host') . + ':' . $this->request->getConfig('proxy_port'); + + if (!empty(self::$challenges[$key]) + && (empty($challenge['stale']) || strcasecmp('true', $challenge['stale'])) + ) { + $ret = false; + } else { + $ret = true; + } + self::$challenges[$key] = $challenge; + return $ret; + } + + /** + * Extracts digest method challenge from (WWW|Proxy)-Authenticate header value + * + * There is a problem with implementation of RFC 2617: several of the parameters + * are defined as quoted-string there and thus may contain backslash escaped + * double quotes (RFC 2616, section 2.2). However, RFC 2617 defines unq(X) as + * just value of quoted-string X without surrounding quotes, it doesn't speak + * about removing backslash escaping. + * + * Now realm parameter is user-defined and human-readable, strange things + * happen when it contains quotes: + * - Apache allows quotes in realm, but apparently uses realm value without + * backslashes for digest computation + * - Squid allows (manually escaped) quotes there, but it is impossible to + * authorize with either escaped or unescaped quotes used in digest, + * probably it can't parse the response (?) + * - Both IE and Firefox display realm value with backslashes in + * the password popup and apparently use the same value for digest + * + * HTTP_Request2 follows IE and Firefox (and hopefully RFC 2617) in + * quoted-string handling, unfortunately that means failure to authorize + * sometimes + * + * @param string $headerValue value of WWW-Authenticate or Proxy-Authenticate header + * + * @return mixed associative array with challenge parameters, false if + * no challenge is present in header value + * @throws HTTP_Request2_NotImplementedException in case of unsupported challenge parameters + */ + protected function parseDigestChallenge($headerValue) + { + $authParam = '(' . self::REGEXP_TOKEN . ')\\s*=\\s*(' . + self::REGEXP_TOKEN . '|' . self::REGEXP_QUOTED_STRING . ')'; + $challenge = "!(?<=^|\\s|,)Digest ({$authParam}\\s*(,\\s*|$))+!"; + if (!preg_match($challenge, $headerValue, $matches)) { + return false; + } + + preg_match_all('!' . $authParam . '!', $matches[0], $params); + $paramsAry = array(); + $knownParams = array('realm', 'domain', 'nonce', 'opaque', 'stale', + 'algorithm', 'qop'); + for ($i = 0; $i < count($params[0]); $i++) { + // section 3.2.1: Any unrecognized directive MUST be ignored. + if (in_array($params[1][$i], $knownParams)) { + if ('"' == substr($params[2][$i], 0, 1)) { + $paramsAry[$params[1][$i]] = substr($params[2][$i], 1, -1); + } else { + $paramsAry[$params[1][$i]] = $params[2][$i]; + } + } + } + // we only support qop=auth + if (!empty($paramsAry['qop']) + && !in_array('auth', array_map('trim', explode(',', $paramsAry['qop']))) + ) { + throw new HTTP_Request2_NotImplementedException( + "Only 'auth' qop is currently supported in digest authentication, " . + "server requested '{$paramsAry['qop']}'" + ); + } + // we only support algorithm=MD5 + if (!empty($paramsAry['algorithm']) && 'MD5' != $paramsAry['algorithm']) { + throw new HTTP_Request2_NotImplementedException( + "Only 'MD5' algorithm is currently supported in digest authentication, " . + "server requested '{$paramsAry['algorithm']}'" + ); + } + + return $paramsAry; + } + + /** + * Parses [Proxy-]Authentication-Info header value and updates challenge + * + * @param array &$challenge challenge to update + * @param string $headerValue value of [Proxy-]Authentication-Info header + * + * @todo validate server rspauth response + */ + protected function updateChallenge(&$challenge, $headerValue) + { + $authParam = '!(' . self::REGEXP_TOKEN . ')\\s*=\\s*(' . + self::REGEXP_TOKEN . '|' . self::REGEXP_QUOTED_STRING . ')!'; + $paramsAry = array(); + + preg_match_all($authParam, $headerValue, $params); + for ($i = 0; $i < count($params[0]); $i++) { + if ('"' == substr($params[2][$i], 0, 1)) { + $paramsAry[$params[1][$i]] = substr($params[2][$i], 1, -1); + } else { + $paramsAry[$params[1][$i]] = $params[2][$i]; + } + } + // for now, just update the nonce value + if (!empty($paramsAry['nextnonce'])) { + $challenge['nonce'] = $paramsAry['nextnonce']; + $challenge['nc'] = 1; + } + } + + /** + * Creates a value for [Proxy-]Authorization header when using digest authentication + * + * @param string $user user name + * @param string $password password + * @param string $url request URL + * @param array &$challenge digest challenge parameters + * + * @return string value of [Proxy-]Authorization request header + * @link http://tools.ietf.org/html/rfc2617#section-3.2.2 + */ + protected function createDigestResponse($user, $password, $url, &$challenge) + { + if (false !== ($q = strpos($url, '?')) + && $this->request->getConfig('digest_compat_ie') + ) { + $url = substr($url, 0, $q); + } + + $a1 = md5($user . ':' . $challenge['realm'] . ':' . $password); + $a2 = md5($this->request->getMethod() . ':' . $url); + + if (empty($challenge['qop'])) { + $digest = md5($a1 . ':' . $challenge['nonce'] . ':' . $a2); + } else { + $challenge['cnonce'] = 'Req2.' . rand(); + if (empty($challenge['nc'])) { + $challenge['nc'] = 1; + } + $nc = sprintf('%08x', $challenge['nc']++); + $digest = md5( + $a1 . ':' . $challenge['nonce'] . ':' . $nc . ':' . + $challenge['cnonce'] . ':auth:' . $a2 + ); + } + return 'Digest username="' . str_replace(array('\\', '"'), array('\\\\', '\\"'), $user) . '", ' . + 'realm="' . $challenge['realm'] . '", ' . + 'nonce="' . $challenge['nonce'] . '", ' . + 'uri="' . $url . '", ' . + 'response="' . $digest . '"' . + (!empty($challenge['opaque'])? + ', opaque="' . $challenge['opaque'] . '"': + '') . + (!empty($challenge['qop'])? + ', qop="auth", nc=' . $nc . ', cnonce="' . $challenge['cnonce'] . '"': + ''); + } + + /** + * Adds 'Authorization' header (if needed) to request headers array + * + * @param array &$headers request headers + * @param string $requestHost request host (needed for digest authentication) + * @param string $requestUrl request URL (needed for digest authentication) + * + * @throws HTTP_Request2_NotImplementedException + */ + protected function addAuthorizationHeader(&$headers, $requestHost, $requestUrl) + { + if (!($auth = $this->request->getAuth())) { + return; + } + switch ($auth['scheme']) { + case HTTP_Request2::AUTH_BASIC: + $headers['authorization'] = 'Basic ' . base64_encode( + $auth['user'] . ':' . $auth['password'] + ); + break; + + case HTTP_Request2::AUTH_DIGEST: + unset($this->serverChallenge); + $fullUrl = ('/' == $requestUrl[0])? + $this->request->getUrl()->getScheme() . '://' . + $requestHost . $requestUrl: + $requestUrl; + foreach (array_keys(self::$challenges) as $key) { + if ($key == substr($fullUrl, 0, strlen($key))) { + $headers['authorization'] = $this->createDigestResponse( + $auth['user'], $auth['password'], + $requestUrl, self::$challenges[$key] + ); + $this->serverChallenge =& self::$challenges[$key]; + break; + } + } + break; + + default: + throw new HTTP_Request2_NotImplementedException( + "Unknown HTTP authentication scheme '{$auth['scheme']}'" + ); + } + } + + /** + * Adds 'Proxy-Authorization' header (if needed) to request headers array + * + * @param array &$headers request headers + * @param string $requestUrl request URL (needed for digest authentication) + * + * @throws HTTP_Request2_NotImplementedException + */ + protected function addProxyAuthorizationHeader(&$headers, $requestUrl) + { + if (!$this->request->getConfig('proxy_host') + || !($user = $this->request->getConfig('proxy_user')) + || (0 == strcasecmp('https', $this->request->getUrl()->getScheme()) + && HTTP_Request2::METHOD_CONNECT != $this->request->getMethod()) + ) { + return; + } + + $password = $this->request->getConfig('proxy_password'); + switch ($this->request->getConfig('proxy_auth_scheme')) { + case HTTP_Request2::AUTH_BASIC: + $headers['proxy-authorization'] = 'Basic ' . base64_encode( + $user . ':' . $password + ); + break; + + case HTTP_Request2::AUTH_DIGEST: + unset($this->proxyChallenge); + $proxyUrl = 'proxy://' . $this->request->getConfig('proxy_host') . + ':' . $this->request->getConfig('proxy_port'); + if (!empty(self::$challenges[$proxyUrl])) { + $headers['proxy-authorization'] = $this->createDigestResponse( + $user, $password, + $requestUrl, self::$challenges[$proxyUrl] + ); + $this->proxyChallenge =& self::$challenges[$proxyUrl]; + } + break; + + default: + throw new HTTP_Request2_NotImplementedException( + "Unknown HTTP authentication scheme '" . + $this->request->getConfig('proxy_auth_scheme') . "'" + ); + } + } + + + /** + * Creates the string with the Request-Line and request headers + * + * @return string + * @throws HTTP_Request2_Exception + */ + protected function prepareHeaders() + { + $headers = $this->request->getHeaders(); + $url = $this->request->getUrl(); + $connect = HTTP_Request2::METHOD_CONNECT == $this->request->getMethod(); + $host = $url->getHost(); + + $defaultPort = 0 == strcasecmp($url->getScheme(), 'https')? 443: 80; + if (($port = $url->getPort()) && $port != $defaultPort || $connect) { + $host .= ':' . (empty($port)? $defaultPort: $port); + } + // Do not overwrite explicitly set 'Host' header, see bug #16146 + if (!isset($headers['host'])) { + $headers['host'] = $host; + } + + if ($connect) { + $requestUrl = $host; + + } else { + if (!$this->request->getConfig('proxy_host') + || 'http' != $this->request->getConfig('proxy_type') + || 0 == strcasecmp($url->getScheme(), 'https') + ) { + $requestUrl = ''; + } else { + $requestUrl = $url->getScheme() . '://' . $host; + } + $path = $url->getPath(); + $query = $url->getQuery(); + $requestUrl .= (empty($path)? '/': $path) . (empty($query)? '': '?' . $query); + } + + if ('1.1' == $this->request->getConfig('protocol_version') + && extension_loaded('zlib') && !isset($headers['accept-encoding']) + ) { + $headers['accept-encoding'] = 'gzip, deflate'; + } + if (($jar = $this->request->getCookieJar()) + && ($cookies = $jar->getMatching($this->request->getUrl(), true)) + ) { + $headers['cookie'] = (empty($headers['cookie'])? '': $headers['cookie'] . '; ') . $cookies; + } + + $this->addAuthorizationHeader($headers, $host, $requestUrl); + $this->addProxyAuthorizationHeader($headers, $requestUrl); + $this->calculateRequestLength($headers); + if ('1.1' == $this->request->getConfig('protocol_version')) { + $this->updateExpectHeader($headers); + } else { + $this->expect100Continue = false; + } + + $headersStr = $this->request->getMethod() . ' ' . $requestUrl . ' HTTP/' . + $this->request->getConfig('protocol_version') . "\r\n"; + foreach ($headers as $name => $value) { + $canonicalName = implode('-', array_map('ucfirst', explode('-', $name))); + $headersStr .= $canonicalName . ': ' . $value . "\r\n"; + } + return $headersStr . "\r\n"; + } + + /** + * Adds or removes 'Expect: 100-continue' header from request headers + * + * Also sets the $expect100Continue property. Parsing of existing header + * is somewhat needed due to its complex structure and due to the + * requirement in section 8.2.3 of RFC 2616: + * > A client MUST NOT send an Expect request-header field (section + * > 14.20) with the "100-continue" expectation if it does not intend + * > to send a request body. + * + * @param array &$headers Array of headers prepared for the request + * + * @throws HTTP_Request2_LogicException + * @link http://pear.php.net/bugs/bug.php?id=19233 + * @link http://tools.ietf.org/html/rfc2616#section-8.2.3 + */ + protected function updateExpectHeader(&$headers) + { + $this->expect100Continue = false; + $expectations = array(); + if (isset($headers['expect'])) { + if ('' === $headers['expect']) { + // empty 'Expect' header is technically invalid, so just get rid of it + unset($headers['expect']); + return; + } + // build regexp to parse the value of existing Expect header + $expectParam = ';\s*' . self::REGEXP_TOKEN . '(?:\s*=\s*(?:' + . self::REGEXP_TOKEN . '|' + . self::REGEXP_QUOTED_STRING . '))?\s*'; + $expectExtension = self::REGEXP_TOKEN . '(?:\s*=\s*(?:' + . self::REGEXP_TOKEN . '|' + . self::REGEXP_QUOTED_STRING . ')\s*(?:' + . $expectParam . ')*)?'; + $expectItem = '!(100-continue|' . $expectExtension . ')!A'; + + $pos = 0; + $length = strlen($headers['expect']); + + while ($pos < $length) { + $pos += strspn($headers['expect'], " \t", $pos); + if (',' === substr($headers['expect'], $pos, 1)) { + $pos++; + continue; + + } elseif (!preg_match($expectItem, $headers['expect'], $m, 0, $pos)) { + throw new HTTP_Request2_LogicException( + "Cannot parse value '{$headers['expect']}' of Expect header", + HTTP_Request2_Exception::INVALID_ARGUMENT + ); + + } else { + $pos += strlen($m[0]); + if (strcasecmp('100-continue', $m[0])) { + $expectations[] = $m[0]; + } + } + } + } + + if (1024 < $this->contentLength) { + $expectations[] = '100-continue'; + $this->expect100Continue = true; + } + + if (empty($expectations)) { + unset($headers['expect']); + } else { + $headers['expect'] = implode(',', $expectations); + } + } + + /** + * Sends the request body + * + * @throws HTTP_Request2_MessageException + */ + protected function writeBody() + { + if (in_array($this->request->getMethod(), self::$bodyDisallowed) + || 0 == $this->contentLength + ) { + return; + } + + $position = 0; + $bufferSize = $this->request->getConfig('buffer_size'); + $headers = $this->request->getHeaders(); + $chunked = isset($headers['transfer-encoding']); + while ($position < $this->contentLength) { + if (is_string($this->requestBody)) { + $str = substr($this->requestBody, $position, $bufferSize); + } elseif (is_resource($this->requestBody)) { + $str = fread($this->requestBody, $bufferSize); + } else { + $str = $this->requestBody->read($bufferSize); + } + if (!$chunked) { + $this->socket->write($str); + } else { + $this->socket->write(dechex(strlen($str)) . "\r\n{$str}\r\n"); + } + // Provide the length of written string to the observer, request #7630 + $this->request->setLastEvent('sentBodyPart', strlen($str)); + $position += strlen($str); + } + + // write zero-length chunk + if ($chunked) { + $this->socket->write("0\r\n\r\n"); + } + $this->request->setLastEvent('sentBody', $this->contentLength); + } + + /** + * Reads the remote server's response + * + * @return HTTP_Request2_Response + * @throws HTTP_Request2_Exception + */ + protected function readResponse() + { + $bufferSize = $this->request->getConfig('buffer_size'); + // http://tools.ietf.org/html/rfc2616#section-8.2.3 + // ...the client SHOULD NOT wait for an indefinite period before sending the request body + $timeout = $this->expect100Continue ? 1 : null; + + do { + try { + $response = new HTTP_Request2_Response( + $this->socket->readLine($bufferSize, $timeout), true, $this->request->getUrl() + ); + do { + $headerLine = $this->socket->readLine($bufferSize); + $response->parseHeaderLine($headerLine); + } while ('' != $headerLine); + + } catch (HTTP_Request2_MessageException $e) { + if (HTTP_Request2_Exception::TIMEOUT === $e->getCode() + && $this->expect100Continue + ) { + return null; + } + throw $e; + } + if ($this->expect100Continue && 100 == $response->getStatus()) { + return $response; + } + } while (in_array($response->getStatus(), array(100, 101))); + + $this->request->setLastEvent('receivedHeaders', $response); + + // No body possible in such responses + if (HTTP_Request2::METHOD_HEAD == $this->request->getMethod() + || (HTTP_Request2::METHOD_CONNECT == $this->request->getMethod() + && 200 <= $response->getStatus() && 300 > $response->getStatus()) + || in_array($response->getStatus(), array(204, 304)) + ) { + return $response; + } + + $chunked = 'chunked' == $response->getHeader('transfer-encoding'); + $length = $response->getHeader('content-length'); + $hasBody = false; + // RFC 2616, section 4.4: + // 3. ... If a message is received with both a + // Transfer-Encoding header field and a Content-Length header field, + // the latter MUST be ignored. + $toRead = ($chunked || null === $length)? null: $length; + $this->chunkLength = 0; + + if ($chunked || null === $length || 0 < intval($length)) { + while (!$this->socket->eof() && (is_null($toRead) || 0 < $toRead)) { + if ($chunked) { + $data = $this->readChunked($bufferSize); + } elseif (is_null($toRead)) { + $data = $this->socket->read($bufferSize); + } else { + $data = $this->socket->read(min($toRead, $bufferSize)); + $toRead -= strlen($data); + } + if ('' == $data && (!$this->chunkLength || $this->socket->eof())) { + break; + } + + $hasBody = true; + if ($this->request->getConfig('store_body')) { + $response->appendBody($data); + } + if (!in_array($response->getHeader('content-encoding'), array('identity', null))) { + $this->request->setLastEvent('receivedEncodedBodyPart', $data); + } else { + $this->request->setLastEvent('receivedBodyPart', $data); + } + } + } + if (0 !== $this->chunkLength || null !== $toRead && $toRead > 0) { + $this->request->setLastEvent( + 'warning', 'transfer closed with outstanding read data remaining' + ); + } + + if ($hasBody) { + $this->request->setLastEvent('receivedBody', $response); + } + return $response; + } + + /** + * Reads a part of response body encoded with chunked Transfer-Encoding + * + * @param int $bufferSize buffer size to use for reading + * + * @return string + * @throws HTTP_Request2_MessageException + */ + protected function readChunked($bufferSize) + { + // at start of the next chunk? + if (0 == $this->chunkLength) { + $line = $this->socket->readLine($bufferSize); + if ('' === $line && $this->socket->eof()) { + $this->chunkLength = -1; // indicate missing chunk + return ''; + + } elseif (!preg_match('/^([0-9a-f]+)/i', $line, $matches)) { + throw new HTTP_Request2_MessageException( + "Cannot decode chunked response, invalid chunk length '{$line}'", + HTTP_Request2_Exception::DECODE_ERROR + ); + + } else { + $this->chunkLength = hexdec($matches[1]); + // Chunk with zero length indicates the end + if (0 == $this->chunkLength) { + $this->socket->readLine($bufferSize); + return ''; + } + } + } + $data = $this->socket->read(min($this->chunkLength, $bufferSize)); + $this->chunkLength -= strlen($data); + if (0 == $this->chunkLength) { + $this->socket->readLine($bufferSize); // Trailing CRLF + } + return $data; + } +} + +?> \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/HTTP_Request2/HTTP/Request2/CookieJar.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/HTTP_Request2/HTTP/Request2/CookieJar.php new file mode 100644 index 0000000..a703fac --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/HTTP_Request2/HTTP/Request2/CookieJar.php @@ -0,0 +1,547 @@ + + * @copyright 2008-2016 Alexey Borzov + * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License + * @link http://pear.php.net/package/HTTP_Request2 + */ + +/** Class representing a HTTP request message */ +require_once 'HTTP/Request2.php'; + +/** + * Stores cookies and passes them between HTTP requests + * + * @category HTTP + * @package HTTP_Request2 + * @author Alexey Borzov + * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License + * @version Release: 2.3.0 + * @link http://pear.php.net/package/HTTP_Request2 + */ +class HTTP_Request2_CookieJar implements Serializable +{ + /** + * Array of stored cookies + * + * The array is indexed by domain, path and cookie name + * .example.com + * / + * some_cookie => cookie data + * /subdir + * other_cookie => cookie data + * .example.org + * ... + * + * @var array + */ + protected $cookies = array(); + + /** + * Whether session cookies should be serialized when serializing the jar + * @var bool + */ + protected $serializeSession = false; + + /** + * Whether Public Suffix List should be used for domain matching + * @var bool + */ + protected $useList = true; + + /** + * Whether an attempt to store an invalid cookie should be ignored, rather than cause an Exception + * @var bool + */ + protected $ignoreInvalid = false; + + /** + * Array with Public Suffix List data + * @var array + * @link http://publicsuffix.org/ + */ + protected static $psl = array(); + + /** + * Class constructor, sets various options + * + * @param bool $serializeSessionCookies Controls serializing session cookies, + * see {@link serializeSessionCookies()} + * @param bool $usePublicSuffixList Controls using Public Suffix List, + * see {@link usePublicSuffixList()} + * @param bool $ignoreInvalidCookies Whether invalid cookies should be ignored, + * see {@link ignoreInvalidCookies()} + */ + public function __construct( + $serializeSessionCookies = false, $usePublicSuffixList = true, + $ignoreInvalidCookies = false + ) { + $this->serializeSessionCookies($serializeSessionCookies); + $this->usePublicSuffixList($usePublicSuffixList); + $this->ignoreInvalidCookies($ignoreInvalidCookies); + } + + /** + * Returns current time formatted in ISO-8601 at UTC timezone + * + * @return string + */ + protected function now() + { + $dt = new DateTime(); + $dt->setTimezone(new DateTimeZone('UTC')); + return $dt->format(DateTime::ISO8601); + } + + /** + * Checks cookie array for correctness, possibly updating its 'domain', 'path' and 'expires' fields + * + * The checks are as follows: + * - cookie array should contain 'name' and 'value' fields; + * - name and value should not contain disallowed symbols; + * - 'expires' should be either empty parseable by DateTime; + * - 'domain' and 'path' should be either not empty or an URL where + * cookie was set should be provided. + * - if $setter is provided, then document at that URL should be allowed + * to set a cookie for that 'domain'. If $setter is not provided, + * then no domain checks will be made. + * + * 'expires' field will be converted to ISO8601 format from COOKIE format, + * 'domain' and 'path' will be set from setter URL if empty. + * + * @param array $cookie cookie data, as returned by + * {@link HTTP_Request2_Response::getCookies()} + * @param Net_URL2 $setter URL of the document that sent Set-Cookie header + * + * @return array Updated cookie array + * @throws HTTP_Request2_LogicException + * @throws HTTP_Request2_MessageException + */ + protected function checkAndUpdateFields(array $cookie, Net_URL2 $setter = null) + { + if ($missing = array_diff(array('name', 'value'), array_keys($cookie))) { + throw new HTTP_Request2_LogicException( + "Cookie array should contain 'name' and 'value' fields", + HTTP_Request2_Exception::MISSING_VALUE + ); + } + if (preg_match(HTTP_Request2::REGEXP_INVALID_COOKIE, $cookie['name'])) { + throw new HTTP_Request2_LogicException( + "Invalid cookie name: '{$cookie['name']}'", + HTTP_Request2_Exception::INVALID_ARGUMENT + ); + } + if (preg_match(HTTP_Request2::REGEXP_INVALID_COOKIE, $cookie['value'])) { + throw new HTTP_Request2_LogicException( + "Invalid cookie value: '{$cookie['value']}'", + HTTP_Request2_Exception::INVALID_ARGUMENT + ); + } + $cookie += array('domain' => '', 'path' => '', 'expires' => null, 'secure' => false); + + // Need ISO-8601 date @ UTC timezone + if (!empty($cookie['expires']) + && !preg_match('/^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\+0000$/', $cookie['expires']) + ) { + try { + $dt = new DateTime($cookie['expires']); + $dt->setTimezone(new DateTimeZone('UTC')); + $cookie['expires'] = $dt->format(DateTime::ISO8601); + } catch (Exception $e) { + throw new HTTP_Request2_LogicException($e->getMessage()); + } + } + + if (empty($cookie['domain']) || empty($cookie['path'])) { + if (!$setter) { + throw new HTTP_Request2_LogicException( + 'Cookie misses domain and/or path component, cookie setter URL needed', + HTTP_Request2_Exception::MISSING_VALUE + ); + } + if (empty($cookie['domain'])) { + if ($host = $setter->getHost()) { + $cookie['domain'] = $host; + } else { + throw new HTTP_Request2_LogicException( + 'Setter URL does not contain host part, can\'t set cookie domain', + HTTP_Request2_Exception::MISSING_VALUE + ); + } + } + if (empty($cookie['path'])) { + $path = $setter->getPath(); + $cookie['path'] = empty($path)? '/': substr($path, 0, strrpos($path, '/') + 1); + } + } + + if ($setter && !$this->domainMatch($setter->getHost(), $cookie['domain'])) { + throw new HTTP_Request2_MessageException( + "Domain " . $setter->getHost() . " cannot set cookies for " + . $cookie['domain'] + ); + } + + return $cookie; + } + + /** + * Stores a cookie in the jar + * + * @param array $cookie cookie data, as returned by + * {@link HTTP_Request2_Response::getCookies()} + * @param Net_URL2 $setter URL of the document that sent Set-Cookie header + * + * @return bool whether the cookie was successfully stored + * @throws HTTP_Request2_Exception + */ + public function store(array $cookie, Net_URL2 $setter = null) + { + try { + $cookie = $this->checkAndUpdateFields($cookie, $setter); + } catch (HTTP_Request2_Exception $e) { + if ($this->ignoreInvalid) { + return false; + } else { + throw $e; + } + } + + if (strlen($cookie['value']) + && (is_null($cookie['expires']) || $cookie['expires'] > $this->now()) + ) { + if (!isset($this->cookies[$cookie['domain']])) { + $this->cookies[$cookie['domain']] = array(); + } + if (!isset($this->cookies[$cookie['domain']][$cookie['path']])) { + $this->cookies[$cookie['domain']][$cookie['path']] = array(); + } + $this->cookies[$cookie['domain']][$cookie['path']][$cookie['name']] = $cookie; + + } elseif (isset($this->cookies[$cookie['domain']][$cookie['path']][$cookie['name']])) { + unset($this->cookies[$cookie['domain']][$cookie['path']][$cookie['name']]); + } + + return true; + } + + /** + * Adds cookies set in HTTP response to the jar + * + * @param HTTP_Request2_Response $response HTTP response message + * @param Net_URL2 $setter original request URL, needed for + * setting default domain/path. If not given, + * effective URL from response will be used. + * + * @return bool whether all cookies were successfully stored + * @throws HTTP_Request2_LogicException + */ + public function addCookiesFromResponse(HTTP_Request2_Response $response, Net_URL2 $setter = null) + { + if (null === $setter) { + if (!($effectiveUrl = $response->getEffectiveUrl())) { + throw new HTTP_Request2_LogicException( + 'Response URL required for adding cookies from response', + HTTP_Request2_Exception::MISSING_VALUE + ); + } + $setter = new Net_URL2($effectiveUrl); + } + + $success = true; + foreach ($response->getCookies() as $cookie) { + $success = $this->store($cookie, $setter) && $success; + } + return $success; + } + + /** + * Returns all cookies matching a given request URL + * + * The following checks are made: + * - cookie domain should match request host + * - cookie path should be a prefix for request path + * - 'secure' cookies will only be sent for HTTPS requests + * + * @param Net_URL2 $url Request url + * @param bool $asString Whether to return cookies as string for "Cookie: " header + * + * @return array|string Matching cookies + */ + public function getMatching(Net_URL2 $url, $asString = false) + { + $host = $url->getHost(); + $path = $url->getPath(); + $secure = 0 == strcasecmp($url->getScheme(), 'https'); + + $matched = $ret = array(); + foreach (array_keys($this->cookies) as $domain) { + if ($this->domainMatch($host, $domain)) { + foreach (array_keys($this->cookies[$domain]) as $cPath) { + if (0 === strpos($path, $cPath)) { + foreach ($this->cookies[$domain][$cPath] as $name => $cookie) { + if (!$cookie['secure'] || $secure) { + $matched[$name][strlen($cookie['path'])] = $cookie; + } + } + } + } + } + } + foreach ($matched as $cookies) { + krsort($cookies); + $ret = array_merge($ret, $cookies); + } + if (!$asString) { + return $ret; + } else { + $str = ''; + foreach ($ret as $c) { + $str .= (empty($str)? '': '; ') . $c['name'] . '=' . $c['value']; + } + return $str; + } + } + + /** + * Returns all cookies stored in a jar + * + * @return array + */ + public function getAll() + { + $cookies = array(); + foreach (array_keys($this->cookies) as $domain) { + foreach (array_keys($this->cookies[$domain]) as $path) { + foreach ($this->cookies[$domain][$path] as $name => $cookie) { + $cookies[] = $cookie; + } + } + } + return $cookies; + } + + /** + * Sets whether session cookies should be serialized when serializing the jar + * + * @param boolean $serialize serialize? + */ + public function serializeSessionCookies($serialize) + { + $this->serializeSession = (bool)$serialize; + } + + /** + * Sets whether invalid cookies should be silently ignored or cause an Exception + * + * @param boolean $ignore ignore? + * @link http://pear.php.net/bugs/bug.php?id=19937 + * @link http://pear.php.net/bugs/bug.php?id=20401 + */ + public function ignoreInvalidCookies($ignore) + { + $this->ignoreInvalid = (bool)$ignore; + } + + /** + * Sets whether Public Suffix List should be used for restricting cookie-setting + * + * Without PSL {@link domainMatch()} will only prevent setting cookies for + * top-level domains like '.com' or '.org'. However, it will not prevent + * setting a cookie for '.co.uk' even though only third-level registrations + * are possible in .uk domain. + * + * With the List it is possible to find the highest level at which a domain + * may be registered for a particular top-level domain and consequently + * prevent cookies set for '.co.uk' or '.msk.ru'. The same list is used by + * Firefox, Chrome and Opera browsers to restrict cookie setting. + * + * Note that PSL is licensed differently to HTTP_Request2 package (refer to + * the license information in public-suffix-list.php), so you can disable + * its use if this is an issue for you. + * + * @param boolean $useList use the list? + * + * @link http://publicsuffix.org/learn/ + */ + public function usePublicSuffixList($useList) + { + $this->useList = (bool)$useList; + } + + /** + * Returns string representation of object + * + * @return string + * + * @see Serializable::serialize() + */ + public function serialize() + { + $cookies = $this->getAll(); + if (!$this->serializeSession) { + for ($i = count($cookies) - 1; $i >= 0; $i--) { + if (empty($cookies[$i]['expires'])) { + unset($cookies[$i]); + } + } + } + return serialize(array( + 'cookies' => $cookies, + 'serializeSession' => $this->serializeSession, + 'useList' => $this->useList, + 'ignoreInvalid' => $this->ignoreInvalid + )); + } + + /** + * Constructs the object from serialized string + * + * @param string $serialized string representation + * + * @see Serializable::unserialize() + */ + public function unserialize($serialized) + { + $data = unserialize($serialized); + $now = $this->now(); + $this->serializeSessionCookies($data['serializeSession']); + $this->usePublicSuffixList($data['useList']); + if (array_key_exists('ignoreInvalid', $data)) { + $this->ignoreInvalidCookies($data['ignoreInvalid']); + } + foreach ($data['cookies'] as $cookie) { + if (!empty($cookie['expires']) && $cookie['expires'] <= $now) { + continue; + } + if (!isset($this->cookies[$cookie['domain']])) { + $this->cookies[$cookie['domain']] = array(); + } + if (!isset($this->cookies[$cookie['domain']][$cookie['path']])) { + $this->cookies[$cookie['domain']][$cookie['path']] = array(); + } + $this->cookies[$cookie['domain']][$cookie['path']][$cookie['name']] = $cookie; + } + } + + /** + * Checks whether a cookie domain matches a request host. + * + * The method is used by {@link store()} to check for whether a document + * at given URL can set a cookie with a given domain attribute and by + * {@link getMatching()} to find cookies matching the request URL. + * + * @param string $requestHost request host + * @param string $cookieDomain cookie domain + * + * @return bool match success + */ + public function domainMatch($requestHost, $cookieDomain) + { + if ($requestHost == $cookieDomain) { + return true; + } + // IP address, we require exact match + if (preg_match('/^(?:\d{1,3}\.){3}\d{1,3}$/', $requestHost)) { + return false; + } + if ('.' != $cookieDomain[0]) { + $cookieDomain = '.' . $cookieDomain; + } + // prevents setting cookies for '.com' and similar domains + if (!$this->useList && substr_count($cookieDomain, '.') < 2 + || $this->useList && !self::getRegisteredDomain($cookieDomain) + ) { + return false; + } + return substr('.' . $requestHost, -strlen($cookieDomain)) == $cookieDomain; + } + + /** + * Removes subdomains to get the registered domain (the first after top-level) + * + * The method will check Public Suffix List to find out where top-level + * domain ends and registered domain starts. It will remove domain parts + * to the left of registered one. + * + * @param string $domain domain name + * + * @return string|bool registered domain, will return false if $domain is + * either invalid or a TLD itself + */ + public static function getRegisteredDomain($domain) + { + $domainParts = explode('.', ltrim($domain, '.')); + + // load the list if needed + if (empty(self::$psl)) { + $path = '/home/zaak/workspace/js/ckfinder/vendor/pear-pear.php.net/HTTP_Request2/data' . DIRECTORY_SEPARATOR . 'HTTP_Request2'; + if (0 === strpos($path, '@' . 'data_dir@')) { + $path = realpath( + dirname(__FILE__) . DIRECTORY_SEPARATOR . '..' + . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'data' + ); + } + self::$psl = include_once $path . DIRECTORY_SEPARATOR . 'public-suffix-list.php'; + } + + if (!($result = self::checkDomainsList($domainParts, self::$psl))) { + // known TLD, invalid domain name + return false; + } + + // unknown TLD + if (!strpos($result, '.')) { + // fallback to checking that domain "has at least two dots" + if (2 > ($count = count($domainParts))) { + return false; + } + return $domainParts[$count - 2] . '.' . $domainParts[$count - 1]; + } + return $result; + } + + /** + * Recursive helper method for {@link getRegisteredDomain()} + * + * @param array $domainParts remaining domain parts + * @param mixed $listNode node in {@link HTTP_Request2_CookieJar::$psl} to check + * + * @return string|null concatenated domain parts, null in case of error + */ + protected static function checkDomainsList(array $domainParts, $listNode) + { + $sub = array_pop($domainParts); + $result = null; + + if (!is_array($listNode) || is_null($sub) + || array_key_exists('!' . $sub, $listNode) + ) { + return $sub; + + } elseif (array_key_exists($sub, $listNode)) { + $result = self::checkDomainsList($domainParts, $listNode[$sub]); + + } elseif (array_key_exists('*', $listNode)) { + $result = self::checkDomainsList($domainParts, $listNode['*']); + + } else { + return $sub; + } + + return (strlen($result) > 0) ? ($result . '.' . $sub) : null; + } +} +?> \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/HTTP_Request2/HTTP/Request2/Exception.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/HTTP_Request2/HTTP/Request2/Exception.php new file mode 100644 index 0000000..de9432d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/HTTP_Request2/HTTP/Request2/Exception.php @@ -0,0 +1,160 @@ + + * @copyright 2008-2016 Alexey Borzov + * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License + * @link http://pear.php.net/package/HTTP_Request2 + */ + +/** + * Base class for exceptions in PEAR + */ +require_once 'PEAR/Exception.php'; + +/** + * Base exception class for HTTP_Request2 package + * + * @category HTTP + * @package HTTP_Request2 + * @author Alexey Borzov + * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License + * @version Release: 2.3.0 + * @link http://pear.php.net/package/HTTP_Request2 + * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=132 + */ +class HTTP_Request2_Exception extends PEAR_Exception +{ + /** An invalid argument was passed to a method */ + const INVALID_ARGUMENT = 1; + /** Some required value was not available */ + const MISSING_VALUE = 2; + /** Request cannot be processed due to errors in PHP configuration */ + const MISCONFIGURATION = 3; + /** Error reading the local file */ + const READ_ERROR = 4; + + /** Server returned a response that does not conform to HTTP protocol */ + const MALFORMED_RESPONSE = 10; + /** Failure decoding Content-Encoding or Transfer-Encoding of response */ + const DECODE_ERROR = 20; + /** Operation timed out */ + const TIMEOUT = 30; + /** Number of redirects exceeded 'max_redirects' configuration parameter */ + const TOO_MANY_REDIRECTS = 40; + /** Redirect to a protocol other than http(s):// */ + const NON_HTTP_REDIRECT = 50; + + /** + * Native error code + * @var int + */ + private $_nativeCode; + + /** + * Constructor, can set package error code and native error code + * + * @param string $message exception message + * @param int $code package error code, one of class constants + * @param int $nativeCode error code from underlying PHP extension + */ + public function __construct($message = null, $code = null, $nativeCode = null) + { + parent::__construct($message, $code); + $this->_nativeCode = $nativeCode; + } + + /** + * Returns error code produced by underlying PHP extension + * + * For Socket Adapter this may contain error number returned by + * stream_socket_client(), for Curl Adapter this will contain error number + * returned by curl_errno() + * + * @return integer + */ + public function getNativeCode() + { + return $this->_nativeCode; + } +} + +/** + * Exception thrown in case of missing features + * + * @category HTTP + * @package HTTP_Request2 + * @author Alexey Borzov + * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License + * @version Release: 2.3.0 + * @link http://pear.php.net/package/HTTP_Request2 + */ +class HTTP_Request2_NotImplementedException extends HTTP_Request2_Exception +{ +} + +/** + * Exception that represents error in the program logic + * + * This exception usually implies a programmer's error, like passing invalid + * data to methods or trying to use PHP extensions that weren't installed or + * enabled. Usually exceptions of this kind will be thrown before request even + * starts. + * + * The exception will usually contain a package error code. + * + * @category HTTP + * @package HTTP_Request2 + * @author Alexey Borzov + * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License + * @version Release: 2.3.0 + * @link http://pear.php.net/package/HTTP_Request2 + */ +class HTTP_Request2_LogicException extends HTTP_Request2_Exception +{ +} + +/** + * Exception thrown when connection to a web or proxy server fails + * + * The exception will not contain a package error code, but will contain + * native error code, as returned by stream_socket_client() or curl_errno(). + * + * @category HTTP + * @package HTTP_Request2 + * @author Alexey Borzov + * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License + * @version Release: 2.3.0 + * @link http://pear.php.net/package/HTTP_Request2 + */ +class HTTP_Request2_ConnectionException extends HTTP_Request2_Exception +{ +} + +/** + * Exception thrown when sending or receiving HTTP message fails + * + * The exception may contain both package error code and native error code. + * + * @category HTTP + * @package HTTP_Request2 + * @author Alexey Borzov + * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License + * @version Release: 2.3.0 + * @link http://pear.php.net/package/HTTP_Request2 + */ +class HTTP_Request2_MessageException extends HTTP_Request2_Exception +{ +} +?> \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/HTTP_Request2/HTTP/Request2/MultipartBody.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/HTTP_Request2/HTTP/Request2/MultipartBody.php new file mode 100644 index 0000000..e5a3845 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/HTTP_Request2/HTTP/Request2/MultipartBody.php @@ -0,0 +1,268 @@ + + * @copyright 2008-2016 Alexey Borzov + * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License + * @link http://pear.php.net/package/HTTP_Request2 + */ + +/** Exception class for HTTP_Request2 package */ +require_once 'HTTP/Request2/Exception.php'; + +/** + * Class for building multipart/form-data request body + * + * The class helps to reduce memory consumption by streaming large file uploads + * from disk, it also allows monitoring of upload progress (see request #7630) + * + * @category HTTP + * @package HTTP_Request2 + * @author Alexey Borzov + * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License + * @version Release: 2.3.0 + * @link http://pear.php.net/package/HTTP_Request2 + * @link http://tools.ietf.org/html/rfc1867 + */ +class HTTP_Request2_MultipartBody +{ + /** + * MIME boundary + * @var string + */ + private $_boundary; + + /** + * Form parameters added via {@link HTTP_Request2::addPostParameter()} + * @var array + */ + private $_params = array(); + + /** + * File uploads added via {@link HTTP_Request2::addUpload()} + * @var array + */ + private $_uploads = array(); + + /** + * Header for parts with parameters + * @var string + */ + private $_headerParam = "--%s\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n"; + + /** + * Header for parts with uploads + * @var string + */ + private $_headerUpload = "--%s\r\nContent-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\nContent-Type: %s\r\n\r\n"; + + /** + * Current position in parameter and upload arrays + * + * First number is index of "current" part, second number is position within + * "current" part + * + * @var array + */ + private $_pos = array(0, 0); + + + /** + * Constructor. Sets the arrays with POST data. + * + * @param array $params values of form fields set via + * {@link HTTP_Request2::addPostParameter()} + * @param array $uploads file uploads set via + * {@link HTTP_Request2::addUpload()} + * @param bool $useBrackets whether to append brackets to array variable names + */ + public function __construct(array $params, array $uploads, $useBrackets = true) + { + $this->_params = self::_flattenArray('', $params, $useBrackets); + foreach ($uploads as $fieldName => $f) { + if (!is_array($f['fp'])) { + $this->_uploads[] = $f + array('name' => $fieldName); + } else { + for ($i = 0; $i < count($f['fp']); $i++) { + $upload = array( + 'name' => ($useBrackets? $fieldName . '[' . $i . ']': $fieldName) + ); + foreach (array('fp', 'filename', 'size', 'type') as $key) { + $upload[$key] = $f[$key][$i]; + } + $this->_uploads[] = $upload; + } + } + } + } + + /** + * Returns the length of the body to use in Content-Length header + * + * @return integer + */ + public function getLength() + { + $boundaryLength = strlen($this->getBoundary()); + $headerParamLength = strlen($this->_headerParam) - 4 + $boundaryLength; + $headerUploadLength = strlen($this->_headerUpload) - 8 + $boundaryLength; + $length = $boundaryLength + 6; + foreach ($this->_params as $p) { + $length += $headerParamLength + strlen($p[0]) + strlen($p[1]) + 2; + } + foreach ($this->_uploads as $u) { + $length += $headerUploadLength + strlen($u['name']) + strlen($u['type']) + + strlen($u['filename']) + $u['size'] + 2; + } + return $length; + } + + /** + * Returns the boundary to use in Content-Type header + * + * @return string + */ + public function getBoundary() + { + if (empty($this->_boundary)) { + $this->_boundary = '--' . md5('PEAR-HTTP_Request2-' . microtime()); + } + return $this->_boundary; + } + + /** + * Returns next chunk of request body + * + * @param integer $length Number of bytes to read + * + * @return string Up to $length bytes of data, empty string if at end + * @throws HTTP_Request2_LogicException + */ + public function read($length) + { + $ret = ''; + $boundary = $this->getBoundary(); + $paramCount = count($this->_params); + $uploadCount = count($this->_uploads); + while ($length > 0 && $this->_pos[0] <= $paramCount + $uploadCount) { + $oldLength = $length; + if ($this->_pos[0] < $paramCount) { + $param = sprintf( + $this->_headerParam, $boundary, $this->_params[$this->_pos[0]][0] + ) . $this->_params[$this->_pos[0]][1] . "\r\n"; + $ret .= substr($param, $this->_pos[1], $length); + $length -= min(strlen($param) - $this->_pos[1], $length); + + } elseif ($this->_pos[0] < $paramCount + $uploadCount) { + $pos = $this->_pos[0] - $paramCount; + $header = sprintf( + $this->_headerUpload, $boundary, $this->_uploads[$pos]['name'], + $this->_uploads[$pos]['filename'], $this->_uploads[$pos]['type'] + ); + if ($this->_pos[1] < strlen($header)) { + $ret .= substr($header, $this->_pos[1], $length); + $length -= min(strlen($header) - $this->_pos[1], $length); + } + $filePos = max(0, $this->_pos[1] - strlen($header)); + if ($filePos < $this->_uploads[$pos]['size']) { + while ($length > 0 && !feof($this->_uploads[$pos]['fp'])) { + if (false === ($chunk = fread($this->_uploads[$pos]['fp'], $length))) { + throw new HTTP_Request2_LogicException( + 'Failed reading file upload', HTTP_Request2_Exception::READ_ERROR + ); + } + $ret .= $chunk; + $length -= strlen($chunk); + } + } + if ($length > 0) { + $start = $this->_pos[1] + ($oldLength - $length) - + strlen($header) - $this->_uploads[$pos]['size']; + $ret .= substr("\r\n", $start, $length); + $length -= min(2 - $start, $length); + } + + } else { + $closing = '--' . $boundary . "--\r\n"; + $ret .= substr($closing, $this->_pos[1], $length); + $length -= min(strlen($closing) - $this->_pos[1], $length); + } + if ($length > 0) { + $this->_pos = array($this->_pos[0] + 1, 0); + } else { + $this->_pos[1] += $oldLength; + } + } + return $ret; + } + + /** + * Sets the current position to the start of the body + * + * This allows reusing the same body in another request + */ + public function rewind() + { + $this->_pos = array(0, 0); + foreach ($this->_uploads as $u) { + rewind($u['fp']); + } + } + + /** + * Returns the body as string + * + * Note that it reads all file uploads into memory so it is a good idea not + * to use this method with large file uploads and rely on read() instead. + * + * @return string + */ + public function __toString() + { + $this->rewind(); + return $this->read($this->getLength()); + } + + + /** + * Helper function to change the (probably multidimensional) associative array + * into the simple one. + * + * @param string $name name for item + * @param mixed $values item's values + * @param bool $useBrackets whether to append [] to array variables' names + * + * @return array array with the following items: array('item name', 'item value'); + */ + private static function _flattenArray($name, $values, $useBrackets) + { + if (!is_array($values)) { + return array(array($name, $values)); + } else { + $ret = array(); + foreach ($values as $k => $v) { + if (empty($name)) { + $newName = $k; + } elseif ($useBrackets) { + $newName = $name . '[' . $k . ']'; + } else { + $newName = $name; + } + $ret = array_merge($ret, self::_flattenArray($newName, $v, $useBrackets)); + } + return $ret; + } + } +} +?> diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/HTTP_Request2/HTTP/Request2/Observer/Log.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/HTTP_Request2/HTTP/Request2/Observer/Log.php new file mode 100644 index 0000000..069baf8 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/HTTP_Request2/HTTP/Request2/Observer/Log.php @@ -0,0 +1,192 @@ + + * @author Alexey Borzov + * @copyright 2008-2016 Alexey Borzov + * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License + * @link http://pear.php.net/package/HTTP_Request2 + */ + +/** + * Exception class for HTTP_Request2 package + */ +require_once 'HTTP/Request2/Exception.php'; + +/** + * A debug observer useful for debugging / testing. + * + * This observer logs to a log target data corresponding to the various request + * and response events, it logs by default to php://output but can be configured + * to log to a file or via the PEAR Log package. + * + * A simple example: + * + * require_once 'HTTP/Request2.php'; + * require_once 'HTTP/Request2/Observer/Log.php'; + * + * $request = new HTTP_Request2('http://www.example.com'); + * $observer = new HTTP_Request2_Observer_Log(); + * $request->attach($observer); + * $request->send(); + * + * + * A more complex example with PEAR Log: + * + * require_once 'HTTP/Request2.php'; + * require_once 'HTTP/Request2/Observer/Log.php'; + * require_once 'Log.php'; + * + * $request = new HTTP_Request2('http://www.example.com'); + * // we want to log with PEAR log + * $observer = new HTTP_Request2_Observer_Log(Log::factory('console')); + * + * // we only want to log received headers + * $observer->events = array('receivedHeaders'); + * + * $request->attach($observer); + * $request->send(); + * + * + * @category HTTP + * @package HTTP_Request2 + * @author David Jean Louis + * @author Alexey Borzov + * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License + * @version Release: 2.3.0 + * @link http://pear.php.net/package/HTTP_Request2 + */ +class HTTP_Request2_Observer_Log implements SplObserver +{ + // properties {{{ + + /** + * The log target, it can be a a resource or a PEAR Log instance. + * + * @var resource|Log $target + */ + protected $target = null; + + /** + * The events to log. + * + * @var array $events + */ + public $events = array( + 'connect', + 'sentHeaders', + 'sentBody', + 'receivedHeaders', + 'receivedBody', + 'disconnect', + ); + + // }}} + // __construct() {{{ + + /** + * Constructor. + * + * @param mixed $target Can be a file path (default: php://output), a resource, + * or an instance of the PEAR Log class. + * @param array $events Array of events to listen to (default: all events) + * + * @return void + */ + public function __construct($target = 'php://output', array $events = array()) + { + if (!empty($events)) { + $this->events = $events; + } + if (is_resource($target) || $target instanceof Log) { + $this->target = $target; + } elseif (false === ($this->target = @fopen($target, 'ab'))) { + throw new HTTP_Request2_Exception("Unable to open '{$target}'"); + } + } + + // }}} + // update() {{{ + + /** + * Called when the request notifies us of an event. + * + * @param HTTP_Request2 $subject The HTTP_Request2 instance + * + * @return void + */ + public function update(SplSubject $subject) + { + $event = $subject->getLastEvent(); + if (!in_array($event['name'], $this->events)) { + return; + } + + switch ($event['name']) { + case 'connect': + $this->log('* Connected to ' . $event['data']); + break; + case 'sentHeaders': + $headers = explode("\r\n", $event['data']); + array_pop($headers); + foreach ($headers as $header) { + $this->log('> ' . $header); + } + break; + case 'sentBody': + $this->log('> ' . $event['data'] . ' byte(s) sent'); + break; + case 'receivedHeaders': + $this->log(sprintf( + '< HTTP/%s %s %s', $event['data']->getVersion(), + $event['data']->getStatus(), $event['data']->getReasonPhrase() + )); + $headers = $event['data']->getHeader(); + foreach ($headers as $key => $val) { + $this->log('< ' . $key . ': ' . $val); + } + $this->log('< '); + break; + case 'receivedBody': + $this->log($event['data']->getBody()); + break; + case 'disconnect': + $this->log('* Disconnected'); + break; + } + } + + // }}} + // log() {{{ + + /** + * Logs the given message to the configured target. + * + * @param string $message Message to display + * + * @return void + */ + protected function log($message) + { + if ($this->target instanceof Log) { + $this->target->debug($message); + } elseif (is_resource($this->target)) { + fwrite($this->target, $message . "\r\n"); + } + } + + // }}} +} + +?> \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/HTTP_Request2/HTTP/Request2/Observer/UncompressingDownload.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/HTTP_Request2/HTTP/Request2/Observer/UncompressingDownload.php new file mode 100644 index 0000000..8a3430a --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/HTTP_Request2/HTTP/Request2/Observer/UncompressingDownload.php @@ -0,0 +1,265 @@ + + * @author Alexey Borzov + * @copyright 2008-2016 Alexey Borzov + * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License + * @link http://pear.php.net/package/HTTP_Request2 + */ + +require_once 'HTTP/Request2/Response.php'; + +/** + * An observer that saves response body to stream, possibly uncompressing it + * + * This Observer is written in compliment to pear's HTTP_Request2 in order to + * avoid reading the whole response body in memory. Instead it writes the body + * to a stream. If the body is transferred with content-encoding set to + * "deflate" or "gzip" it is decoded on the fly. + * + * The constructor accepts an already opened (for write) stream (file_descriptor). + * If the response is deflate/gzip encoded a "zlib.inflate" filter is applied + * to the stream. When the body has been read from the request and written to + * the stream ("receivedBody" event) the filter is removed from the stream. + * + * The "zlib.inflate" filter works fine with pure "deflate" encoding. It does + * not understand the "deflate+zlib" and "gzip" headers though, so they have to + * be removed prior to being passed to the stream. This is done in the "update" + * method. + * + * It is also possible to limit the size of written extracted bytes by passing + * "max_bytes" to the constructor. This is important because e.g. 1GB of + * zeroes take about a MB when compressed. + * + * Exceptions are being thrown if data could not be written to the stream or + * the written bytes have already exceeded the requested maximum. If the "gzip" + * header is malformed or could not be parsed an exception will be thrown too. + * + * Example usage follows: + * + * + * require_once 'HTTP/Request2.php'; + * require_once 'HTTP/Request2/Observer/UncompressingDownload.php'; + * + * #$inPath = 'http://carsten.codimi.de/gzip.yaws/daniels.html'; + * #$inPath = 'http://carsten.codimi.de/gzip.yaws/daniels.html?deflate=on'; + * $inPath = 'http://carsten.codimi.de/gzip.yaws/daniels.html?deflate=on&zlib=on'; + * #$outPath = "/dev/null"; + * $outPath = "delme"; + * + * $stream = fopen($outPath, 'wb'); + * if (!$stream) { + * throw new Exception('fopen failed'); + * } + * + * $request = new HTTP_Request2( + * $inPath, + * HTTP_Request2::METHOD_GET, + * array( + * 'store_body' => false, + * 'connect_timeout' => 5, + * 'timeout' => 10, + * 'ssl_verify_peer' => true, + * 'ssl_verify_host' => true, + * 'ssl_cafile' => null, + * 'ssl_capath' => '/etc/ssl/certs', + * 'max_redirects' => 10, + * 'follow_redirects' => true, + * 'strict_redirects' => false + * ) + * ); + * + * $observer = new HTTP_Request2_Observer_UncompressingDownload($stream, 9999999); + * $request->attach($observer); + * + * $response = $request->send(); + * + * fclose($stream); + * echo "OK\n"; + * + * + * @category HTTP + * @package HTTP_Request2 + * @author Delian Krustev + * @author Alexey Borzov + * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License + * @version Release: 2.3.0 + * @link http://pear.php.net/package/HTTP_Request2 + */ +class HTTP_Request2_Observer_UncompressingDownload implements SplObserver +{ + /** + * The stream to write response body to + * @var resource + */ + private $_stream; + + /** + * zlib.inflate filter possibly added to stream + * @var resource + */ + private $_streamFilter; + + /** + * The value of response's Content-Encoding header + * @var string + */ + private $_encoding; + + /** + * Whether the observer is still waiting for gzip/deflate header + * @var bool + */ + private $_processingHeader = true; + + /** + * Starting position in the stream observer writes to + * @var int + */ + private $_startPosition = 0; + + /** + * Maximum bytes to write + * @var int|null + */ + private $_maxDownloadSize; + + /** + * Whether response being received is a redirect + * @var bool + */ + private $_redirect = false; + + /** + * Accumulated body chunks that may contain (gzip) header + * @var string + */ + private $_possibleHeader = ''; + + /** + * Class constructor + * + * Note that there might be problems with max_bytes and files bigger + * than 2 GB on 32bit platforms + * + * @param resource $stream a stream (or file descriptor) opened for writing. + * @param int $maxDownloadSize maximum bytes to write + */ + public function __construct($stream, $maxDownloadSize = null) + { + $this->_stream = $stream; + if ($maxDownloadSize) { + $this->_maxDownloadSize = $maxDownloadSize; + $this->_startPosition = ftell($this->_stream); + } + } + + /** + * Called when the request notifies us of an event. + * + * @param SplSubject $request The HTTP_Request2 instance + * + * @return void + * @throws HTTP_Request2_MessageException + */ + public function update(SplSubject $request) + { + /* @var $request HTTP_Request2 */ + $event = $request->getLastEvent(); + $encoded = false; + + /* @var $event['data'] HTTP_Request2_Response */ + switch ($event['name']) { + case 'receivedHeaders': + $this->_processingHeader = true; + $this->_redirect = $event['data']->isRedirect(); + $this->_encoding = strtolower($event['data']->getHeader('content-encoding')); + $this->_possibleHeader = ''; + break; + + case 'receivedEncodedBodyPart': + if (!$this->_streamFilter + && ($this->_encoding === 'deflate' || $this->_encoding === 'gzip') + ) { + $this->_streamFilter = stream_filter_append( + $this->_stream, 'zlib.inflate', STREAM_FILTER_WRITE + ); + } + $encoded = true; + // fall-through is intentional + + case 'receivedBodyPart': + if ($this->_redirect) { + break; + } + + if (!$encoded || !$this->_processingHeader) { + $bytes = fwrite($this->_stream, $event['data']); + + } else { + $offset = 0; + $this->_possibleHeader .= $event['data']; + if ('deflate' === $this->_encoding) { + if (2 > strlen($this->_possibleHeader)) { + break; + } + $header = unpack('n', substr($this->_possibleHeader, 0, 2)); + if (0 == $header[1] % 31) { + $offset = 2; + } + + } elseif ('gzip' === $this->_encoding) { + if (10 > strlen($this->_possibleHeader)) { + break; + } + try { + $offset = HTTP_Request2_Response::parseGzipHeader($this->_possibleHeader, false); + + } catch (HTTP_Request2_MessageException $e) { + // need more data? + if (false !== strpos($e->getMessage(), 'data too short')) { + break; + } + throw $e; + } + } + + $this->_processingHeader = false; + $bytes = fwrite($this->_stream, substr($this->_possibleHeader, $offset)); + } + + if (false === $bytes) { + throw new HTTP_Request2_MessageException('fwrite failed.'); + } + + if ($this->_maxDownloadSize + && ftell($this->_stream) - $this->_startPosition > $this->_maxDownloadSize + ) { + throw new HTTP_Request2_MessageException(sprintf( + 'Body length limit (%d bytes) reached', + $this->_maxDownloadSize + )); + } + break; + + case 'receivedBody': + if ($this->_streamFilter) { + stream_filter_remove($this->_streamFilter); + $this->_streamFilter = null; + } + break; + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/HTTP_Request2/HTTP/Request2/Response.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/HTTP_Request2/HTTP/Request2/Response.php new file mode 100644 index 0000000..b144fda --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/HTTP_Request2/HTTP/Request2/Response.php @@ -0,0 +1,680 @@ + + * @copyright 2008-2016 Alexey Borzov + * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License + * @link http://pear.php.net/package/HTTP_Request2 + */ + +/** + * Exception class for HTTP_Request2 package + */ +require_once 'HTTP/Request2/Exception.php'; + +/** + * Class representing a HTTP response + * + * The class is designed to be used in "streaming" scenario, building the + * response as it is being received: + * + * $statusLine = read_status_line(); + * $response = new HTTP_Request2_Response($statusLine); + * do { + * $headerLine = read_header_line(); + * $response->parseHeaderLine($headerLine); + * } while ($headerLine != ''); + * + * while ($chunk = read_body()) { + * $response->appendBody($chunk); + * } + * + * var_dump($response->getHeader(), $response->getCookies(), $response->getBody()); + * + * + * @category HTTP + * @package HTTP_Request2 + * @author Alexey Borzov + * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License + * @version Release: 2.3.0 + * @link http://pear.php.net/package/HTTP_Request2 + * @link http://tools.ietf.org/html/rfc2616#section-6 + */ +class HTTP_Request2_Response +{ + /** + * HTTP protocol version (e.g. 1.0, 1.1) + * @var string + */ + protected $version; + + /** + * Status code + * @var integer + * @link http://tools.ietf.org/html/rfc2616#section-6.1.1 + */ + protected $code; + + /** + * Reason phrase + * @var string + * @link http://tools.ietf.org/html/rfc2616#section-6.1.1 + */ + protected $reasonPhrase; + + /** + * Effective URL (may be different from original request URL in case of redirects) + * @var string + */ + protected $effectiveUrl; + + /** + * Associative array of response headers + * @var array + */ + protected $headers = array(); + + /** + * Cookies set in the response + * @var array + */ + protected $cookies = array(); + + /** + * Name of last header processed by parseHederLine() + * + * Used to handle the headers that span multiple lines + * + * @var string + */ + protected $lastHeader = null; + + /** + * Response body + * @var string + */ + protected $body = ''; + + /** + * Whether the body is still encoded by Content-Encoding + * + * cURL provides the decoded body to the callback; if we are reading from + * socket the body is still gzipped / deflated + * + * @var bool + */ + protected $bodyEncoded; + + /** + * Associative array of HTTP status code / reason phrase. + * + * @var array + * @link http://tools.ietf.org/html/rfc2616#section-10 + */ + protected static $phrases = array( + + // 1xx: Informational - Request received, continuing process + 100 => 'Continue', + 101 => 'Switching Protocols', + + // 2xx: Success - The action was successfully received, understood and + // accepted + 200 => 'OK', + 201 => 'Created', + 202 => 'Accepted', + 203 => 'Non-Authoritative Information', + 204 => 'No Content', + 205 => 'Reset Content', + 206 => 'Partial Content', + + // 3xx: Redirection - Further action must be taken in order to complete + // the request + 300 => 'Multiple Choices', + 301 => 'Moved Permanently', + 302 => 'Found', // 1.1 + 303 => 'See Other', + 304 => 'Not Modified', + 305 => 'Use Proxy', + 307 => 'Temporary Redirect', + + // 4xx: Client Error - The request contains bad syntax or cannot be + // fulfilled + 400 => 'Bad Request', + 401 => 'Unauthorized', + 402 => 'Payment Required', + 403 => 'Forbidden', + 404 => 'Not Found', + 405 => 'Method Not Allowed', + 406 => 'Not Acceptable', + 407 => 'Proxy Authentication Required', + 408 => 'Request Timeout', + 409 => 'Conflict', + 410 => 'Gone', + 411 => 'Length Required', + 412 => 'Precondition Failed', + 413 => 'Request Entity Too Large', + 414 => 'Request-URI Too Long', + 415 => 'Unsupported Media Type', + 416 => 'Requested Range Not Satisfiable', + 417 => 'Expectation Failed', + + // 5xx: Server Error - The server failed to fulfill an apparently + // valid request + 500 => 'Internal Server Error', + 501 => 'Not Implemented', + 502 => 'Bad Gateway', + 503 => 'Service Unavailable', + 504 => 'Gateway Timeout', + 505 => 'HTTP Version Not Supported', + 509 => 'Bandwidth Limit Exceeded', + + ); + + /** + * Returns the default reason phrase for the given code or all reason phrases + * + * @param int $code Response code + * + * @return string|array|null Default reason phrase for $code if $code is given + * (null if no phrase is available), array of all + * reason phrases if $code is null + * @link http://pear.php.net/bugs/18716 + */ + public static function getDefaultReasonPhrase($code = null) + { + if (null === $code) { + return self::$phrases; + } else { + return isset(self::$phrases[$code]) ? self::$phrases[$code] : null; + } + } + + /** + * Constructor, parses the response status line + * + * @param string $statusLine Response status line (e.g. "HTTP/1.1 200 OK") + * @param bool $bodyEncoded Whether body is still encoded by Content-Encoding + * @param string $effectiveUrl Effective URL of the response + * + * @throws HTTP_Request2_MessageException if status line is invalid according to spec + */ + public function __construct($statusLine, $bodyEncoded = true, $effectiveUrl = null) + { + if (!preg_match('!^HTTP/(\d\.\d) (\d{3})(?: (.+))?!', $statusLine, $m)) { + throw new HTTP_Request2_MessageException( + "Malformed response: {$statusLine}", + HTTP_Request2_Exception::MALFORMED_RESPONSE + ); + } + $this->version = $m[1]; + $this->code = intval($m[2]); + $this->reasonPhrase = !empty($m[3]) ? trim($m[3]) : self::getDefaultReasonPhrase($this->code); + $this->bodyEncoded = (bool)$bodyEncoded; + $this->effectiveUrl = (string)$effectiveUrl; + } + + /** + * Parses the line from HTTP response filling $headers array + * + * The method should be called after reading the line from socket or receiving + * it into cURL callback. Passing an empty string here indicates the end of + * response headers and triggers additional processing, so be sure to pass an + * empty string in the end. + * + * @param string $headerLine Line from HTTP response + */ + public function parseHeaderLine($headerLine) + { + $headerLine = trim($headerLine, "\r\n"); + + if ('' == $headerLine) { + // empty string signals the end of headers, process the received ones + if (!empty($this->headers['set-cookie'])) { + $cookies = is_array($this->headers['set-cookie'])? + $this->headers['set-cookie']: + array($this->headers['set-cookie']); + foreach ($cookies as $cookieString) { + $this->parseCookie($cookieString); + } + unset($this->headers['set-cookie']); + } + foreach (array_keys($this->headers) as $k) { + if (is_array($this->headers[$k])) { + $this->headers[$k] = implode(', ', $this->headers[$k]); + } + } + + } elseif (preg_match('!^([^\x00-\x1f\x7f-\xff()<>@,;:\\\\"/\[\]?={}\s]+):(.+)$!', $headerLine, $m)) { + // string of the form header-name: header value + $name = strtolower($m[1]); + $value = trim($m[2]); + if (empty($this->headers[$name])) { + $this->headers[$name] = $value; + } else { + if (!is_array($this->headers[$name])) { + $this->headers[$name] = array($this->headers[$name]); + } + $this->headers[$name][] = $value; + } + $this->lastHeader = $name; + + } elseif (preg_match('!^\s+(.+)$!', $headerLine, $m) && $this->lastHeader) { + // continuation of a previous header + if (!is_array($this->headers[$this->lastHeader])) { + $this->headers[$this->lastHeader] .= ' ' . trim($m[1]); + } else { + $key = count($this->headers[$this->lastHeader]) - 1; + $this->headers[$this->lastHeader][$key] .= ' ' . trim($m[1]); + } + } + } + + /** + * Parses a Set-Cookie header to fill $cookies array + * + * @param string $cookieString value of Set-Cookie header + * + * @link http://web.archive.org/web/20080331104521/http://cgi.netscape.com/newsref/std/cookie_spec.html + */ + protected function parseCookie($cookieString) + { + $cookie = array( + 'expires' => null, + 'domain' => null, + 'path' => null, + 'secure' => false + ); + + if (!strpos($cookieString, ';')) { + // Only a name=value pair + $pos = strpos($cookieString, '='); + $cookie['name'] = trim(substr($cookieString, 0, $pos)); + $cookie['value'] = trim(substr($cookieString, $pos + 1)); + + } else { + // Some optional parameters are supplied + $elements = explode(';', $cookieString); + $pos = strpos($elements[0], '='); + $cookie['name'] = trim(substr($elements[0], 0, $pos)); + $cookie['value'] = trim(substr($elements[0], $pos + 1)); + + for ($i = 1; $i < count($elements); $i++) { + if (false === strpos($elements[$i], '=')) { + $elName = trim($elements[$i]); + $elValue = null; + } else { + list ($elName, $elValue) = array_map('trim', explode('=', $elements[$i])); + } + $elName = strtolower($elName); + if ('secure' == $elName) { + $cookie['secure'] = true; + } elseif ('expires' == $elName) { + $cookie['expires'] = str_replace('"', '', $elValue); + } elseif ('path' == $elName || 'domain' == $elName) { + $cookie[$elName] = urldecode($elValue); + } else { + $cookie[$elName] = $elValue; + } + } + } + $this->cookies[] = $cookie; + } + + /** + * Appends a string to the response body + * + * @param string $bodyChunk part of response body + */ + public function appendBody($bodyChunk) + { + $this->body .= $bodyChunk; + } + + /** + * Returns the effective URL of the response + * + * This may be different from the request URL if redirects were followed. + * + * @return string + * @link http://pear.php.net/bugs/bug.php?id=18412 + */ + public function getEffectiveUrl() + { + return $this->effectiveUrl; + } + + /** + * Returns the status code + * + * @return integer + */ + public function getStatus() + { + return $this->code; + } + + /** + * Returns the reason phrase + * + * @return string + */ + public function getReasonPhrase() + { + return $this->reasonPhrase; + } + + /** + * Whether response is a redirect that can be automatically handled by HTTP_Request2 + * + * @return bool + */ + public function isRedirect() + { + return in_array($this->code, array(300, 301, 302, 303, 307)) + && isset($this->headers['location']); + } + + /** + * Returns either the named header or all response headers + * + * @param string $headerName Name of header to return + * + * @return string|array Value of $headerName header (null if header is + * not present), array of all response headers if + * $headerName is null + */ + public function getHeader($headerName = null) + { + if (null === $headerName) { + return $this->headers; + } else { + $headerName = strtolower($headerName); + return isset($this->headers[$headerName])? $this->headers[$headerName]: null; + } + } + + /** + * Returns cookies set in response + * + * @return array + */ + public function getCookies() + { + return $this->cookies; + } + + /** + * Returns the body of the response + * + * @return string + * @throws HTTP_Request2_Exception if body cannot be decoded + */ + public function getBody() + { + if (0 == strlen($this->body) || !$this->bodyEncoded + || !in_array(strtolower($this->getHeader('content-encoding')), array('gzip', 'deflate')) + ) { + return $this->body; + + } else { + if (extension_loaded('mbstring') && (2 & ini_get('mbstring.func_overload'))) { + $oldEncoding = mb_internal_encoding(); + mb_internal_encoding('8bit'); + } + + try { + switch (strtolower($this->getHeader('content-encoding'))) { + case 'gzip': + $decoded = self::decodeGzip($this->body); + break; + case 'deflate': + $decoded = self::decodeDeflate($this->body); + } + } catch (Exception $e) { + } + + if (!empty($oldEncoding)) { + mb_internal_encoding($oldEncoding); + } + if (!empty($e)) { + throw $e; + } + return $decoded; + } + } + + /** + * Get the HTTP version of the response + * + * @return string + */ + public function getVersion() + { + return $this->version; + } + + /** + * Checks whether data starts with GZIP format identification bytes from RFC 1952 + * + * @param string $data gzip-encoded (presumably) data + * + * @return bool + */ + public static function hasGzipIdentification($data) + { + return 0 === strcmp(substr($data, 0, 2), "\x1f\x8b"); + } + + /** + * Tries to parse GZIP format header in the given string + * + * If the header conforms to RFC 1952, its length is returned. If any + * sanity check fails, HTTP_Request2_MessageException is thrown. + * + * Note: This function might be usable outside of HTTP_Request2 so it might + * be good idea to be moved to some common package. (Delian Krustev) + * + * @param string $data Either the complete response body or + * the leading part of it + * @param boolean $dataComplete Whether $data contains complete response body + * + * @return int gzip header length in bytes + * @throws HTTP_Request2_MessageException + * @link http://tools.ietf.org/html/rfc1952 + */ + public static function parseGzipHeader($data, $dataComplete = false) + { + // if data is complete, trailing 8 bytes should be present for size and crc32 + $length = strlen($data) - ($dataComplete ? 8 : 0); + + if ($length < 10 || !self::hasGzipIdentification($data)) { + throw new HTTP_Request2_MessageException( + 'The data does not seem to contain a valid gzip header', + HTTP_Request2_Exception::DECODE_ERROR + ); + } + + $method = ord(substr($data, 2, 1)); + if (8 != $method) { + throw new HTTP_Request2_MessageException( + 'Error parsing gzip header: unknown compression method', + HTTP_Request2_Exception::DECODE_ERROR + ); + } + $flags = ord(substr($data, 3, 1)); + if ($flags & 224) { + throw new HTTP_Request2_MessageException( + 'Error parsing gzip header: reserved bits are set', + HTTP_Request2_Exception::DECODE_ERROR + ); + } + + // header is 10 bytes minimum. may be longer, though. + $headerLength = 10; + // extra fields, need to skip 'em + if ($flags & 4) { + if ($length - $headerLength - 2 < 0) { + throw new HTTP_Request2_MessageException( + 'Error parsing gzip header: data too short', + HTTP_Request2_Exception::DECODE_ERROR + ); + } + $extraLength = unpack('v', substr($data, 10, 2)); + if ($length - $headerLength - 2 - $extraLength[1] < 0) { + throw new HTTP_Request2_MessageException( + 'Error parsing gzip header: data too short', + HTTP_Request2_Exception::DECODE_ERROR + ); + } + $headerLength += $extraLength[1] + 2; + } + // file name, need to skip that + if ($flags & 8) { + if ($length - $headerLength - 1 < 0) { + throw new HTTP_Request2_MessageException( + 'Error parsing gzip header: data too short', + HTTP_Request2_Exception::DECODE_ERROR + ); + } + $filenameLength = strpos(substr($data, $headerLength), chr(0)); + if (false === $filenameLength + || $length - $headerLength - $filenameLength - 1 < 0 + ) { + throw new HTTP_Request2_MessageException( + 'Error parsing gzip header: data too short', + HTTP_Request2_Exception::DECODE_ERROR + ); + } + $headerLength += $filenameLength + 1; + } + // comment, need to skip that also + if ($flags & 16) { + if ($length - $headerLength - 1 < 0) { + throw new HTTP_Request2_MessageException( + 'Error parsing gzip header: data too short', + HTTP_Request2_Exception::DECODE_ERROR + ); + } + $commentLength = strpos(substr($data, $headerLength), chr(0)); + if (false === $commentLength + || $length - $headerLength - $commentLength - 1 < 0 + ) { + throw new HTTP_Request2_MessageException( + 'Error parsing gzip header: data too short', + HTTP_Request2_Exception::DECODE_ERROR + ); + } + $headerLength += $commentLength + 1; + } + // have a CRC for header. let's check + if ($flags & 2) { + if ($length - $headerLength - 2 < 0) { + throw new HTTP_Request2_MessageException( + 'Error parsing gzip header: data too short', + HTTP_Request2_Exception::DECODE_ERROR + ); + } + $crcReal = 0xffff & crc32(substr($data, 0, $headerLength)); + $crcStored = unpack('v', substr($data, $headerLength, 2)); + if ($crcReal != $crcStored[1]) { + throw new HTTP_Request2_MessageException( + 'Header CRC check failed', + HTTP_Request2_Exception::DECODE_ERROR + ); + } + $headerLength += 2; + } + return $headerLength; + } + + /** + * Decodes the message-body encoded by gzip + * + * The real decoding work is done by gzinflate() built-in function, this + * method only parses the header and checks data for compliance with + * RFC 1952 + * + * @param string $data gzip-encoded data + * + * @return string decoded data + * @throws HTTP_Request2_LogicException + * @throws HTTP_Request2_MessageException + * @link http://tools.ietf.org/html/rfc1952 + */ + public static function decodeGzip($data) + { + // If it doesn't look like gzip-encoded data, don't bother + if (!self::hasGzipIdentification($data)) { + return $data; + } + if (!function_exists('gzinflate')) { + throw new HTTP_Request2_LogicException( + 'Unable to decode body: gzip extension not available', + HTTP_Request2_Exception::MISCONFIGURATION + ); + } + + // unpacked data CRC and size at the end of encoded data + $tmp = unpack('V2', substr($data, -8)); + $dataCrc = $tmp[1]; + $dataSize = $tmp[2]; + + $headerLength = self::parseGzipHeader($data, true); + + // don't pass $dataSize to gzinflate, see bugs #13135, #14370 + $unpacked = gzinflate(substr($data, $headerLength, -8)); + if (false === $unpacked) { + throw new HTTP_Request2_MessageException( + 'gzinflate() call failed', + HTTP_Request2_Exception::DECODE_ERROR + ); + } elseif ($dataSize != strlen($unpacked)) { + throw new HTTP_Request2_MessageException( + 'Data size check failed', + HTTP_Request2_Exception::DECODE_ERROR + ); + } elseif ((0xffffffff & $dataCrc) != (0xffffffff & crc32($unpacked))) { + throw new HTTP_Request2_MessageException( + 'Data CRC check failed', + HTTP_Request2_Exception::DECODE_ERROR + ); + } + return $unpacked; + } + + /** + * Decodes the message-body encoded by deflate + * + * @param string $data deflate-encoded data + * + * @return string decoded data + * @throws HTTP_Request2_LogicException + */ + public static function decodeDeflate($data) + { + if (!function_exists('gzuncompress')) { + throw new HTTP_Request2_LogicException( + 'Unable to decode body: gzip extension not available', + HTTP_Request2_Exception::MISCONFIGURATION + ); + } + // RFC 2616 defines 'deflate' encoding as zlib format from RFC 1950, + // while many applications send raw deflate stream from RFC 1951. + // We should check for presence of zlib header and use gzuncompress() or + // gzinflate() as needed. See bug #15305 + $header = unpack('n', substr($data, 0, 2)); + return (0 == $header[1] % 31)? gzuncompress($data): gzinflate($data); + } +} +?> \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/HTTP_Request2/HTTP/Request2/SOCKS5.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/HTTP_Request2/HTTP/Request2/SOCKS5.php new file mode 100644 index 0000000..2a782ce --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/HTTP_Request2/HTTP/Request2/SOCKS5.php @@ -0,0 +1,135 @@ + + * @copyright 2008-2016 Alexey Borzov + * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License + * @link http://pear.php.net/package/HTTP_Request2 + */ + +/** Socket wrapper class used by Socket Adapter */ +require_once 'HTTP/Request2/SocketWrapper.php'; + +/** + * SOCKS5 proxy connection class (used by Socket Adapter) + * + * @category HTTP + * @package HTTP_Request2 + * @author Alexey Borzov + * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License + * @version Release: 2.3.0 + * @link http://pear.php.net/package/HTTP_Request2 + * @link http://pear.php.net/bugs/bug.php?id=19332 + * @link http://tools.ietf.org/html/rfc1928 + */ +class HTTP_Request2_SOCKS5 extends HTTP_Request2_SocketWrapper +{ + /** + * Constructor, tries to connect and authenticate to a SOCKS5 proxy + * + * @param string $address Proxy address, e.g. 'tcp://localhost:1080' + * @param int $timeout Connection timeout (seconds) + * @param array $contextOptions Stream context options + * @param string $username Proxy user name + * @param string $password Proxy password + * + * @throws HTTP_Request2_LogicException + * @throws HTTP_Request2_ConnectionException + * @throws HTTP_Request2_MessageException + */ + public function __construct( + $address, $timeout = 10, array $contextOptions = array(), + $username = null, $password = null + ) { + parent::__construct($address, $timeout, $contextOptions); + + if (strlen($username)) { + $request = pack('C4', 5, 2, 0, 2); + } else { + $request = pack('C3', 5, 1, 0); + } + $this->write($request); + $response = unpack('Cversion/Cmethod', $this->read(3)); + if (5 != $response['version']) { + throw new HTTP_Request2_MessageException( + 'Invalid version received from SOCKS5 proxy: ' . $response['version'], + HTTP_Request2_Exception::MALFORMED_RESPONSE + ); + } + switch ($response['method']) { + case 2: + $this->performAuthentication($username, $password); + case 0: + break; + default: + throw new HTTP_Request2_ConnectionException( + "Connection rejected by proxy due to unsupported auth method" + ); + } + } + + /** + * Performs username/password authentication for SOCKS5 + * + * @param string $username Proxy user name + * @param string $password Proxy password + * + * @throws HTTP_Request2_ConnectionException + * @throws HTTP_Request2_MessageException + * @link http://tools.ietf.org/html/rfc1929 + */ + protected function performAuthentication($username, $password) + { + $request = pack('C2', 1, strlen($username)) . $username + . pack('C', strlen($password)) . $password; + + $this->write($request); + $response = unpack('Cvn/Cstatus', $this->read(3)); + if (1 != $response['vn'] || 0 != $response['status']) { + throw new HTTP_Request2_ConnectionException( + 'Connection rejected by proxy due to invalid username and/or password' + ); + } + } + + /** + * Connects to a remote host via proxy + * + * @param string $remoteHost Remote host + * @param int $remotePort Remote port + * + * @throws HTTP_Request2_ConnectionException + * @throws HTTP_Request2_MessageException + */ + public function connect($remoteHost, $remotePort) + { + $request = pack('C5', 0x05, 0x01, 0x00, 0x03, strlen($remoteHost)) + . $remoteHost . pack('n', $remotePort); + + $this->write($request); + $response = unpack('Cversion/Creply/Creserved', $this->read(1024)); + if (5 != $response['version'] || 0 != $response['reserved']) { + throw new HTTP_Request2_MessageException( + 'Invalid response received from SOCKS5 proxy', + HTTP_Request2_Exception::MALFORMED_RESPONSE + ); + } elseif (0 != $response['reply']) { + throw new HTTP_Request2_ConnectionException( + "Unable to connect to {$remoteHost}:{$remotePort} through SOCKS5 proxy", + 0, $response['reply'] + ); + } + } +} +?> \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/HTTP_Request2/HTTP/Request2/SocketWrapper.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/HTTP_Request2/HTTP/Request2/SocketWrapper.php new file mode 100644 index 0000000..2cf4257 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/HTTP_Request2/HTTP/Request2/SocketWrapper.php @@ -0,0 +1,320 @@ + + * @copyright 2008-2016 Alexey Borzov + * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License + * @link http://pear.php.net/package/HTTP_Request2 + */ + +/** Exception classes for HTTP_Request2 package */ +require_once 'HTTP/Request2/Exception.php'; + +/** + * Socket wrapper class used by Socket Adapter + * + * Needed to properly handle connection errors, global timeout support and + * similar things. Loosely based on Net_Socket used by older HTTP_Request. + * + * @category HTTP + * @package HTTP_Request2 + * @author Alexey Borzov + * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License + * @version Release: 2.3.0 + * @link http://pear.php.net/package/HTTP_Request2 + * @link http://pear.php.net/bugs/bug.php?id=19332 + * @link http://tools.ietf.org/html/rfc1928 + */ +class HTTP_Request2_SocketWrapper +{ + /** + * PHP warning messages raised during stream_socket_client() call + * @var array + */ + protected $connectionWarnings = array(); + + /** + * Connected socket + * @var resource + */ + protected $socket; + + /** + * Sum of start time and global timeout, exception will be thrown if request continues past this time + * @var integer + */ + protected $deadline; + + /** + * Global timeout value, mostly for exception messages + * @var integer + */ + protected $timeout; + + /** + * Class constructor, tries to establish connection + * + * @param string $address Address for stream_socket_client() call, + * e.g. 'tcp://localhost:80' + * @param int $timeout Connection timeout (seconds) + * @param array $contextOptions Context options + * + * @throws HTTP_Request2_LogicException + * @throws HTTP_Request2_ConnectionException + */ + public function __construct($address, $timeout, array $contextOptions = array()) + { + if (!empty($contextOptions) + && !isset($contextOptions['socket']) && !isset($contextOptions['ssl']) + ) { + // Backwards compatibility with 2.1.0 and 2.1.1 releases + $contextOptions = array('ssl' => $contextOptions); + } + if (isset($contextOptions['ssl'])) { + $contextOptions['ssl'] += array( + // Using "Intermediate compatibility" cipher bundle from + // https://wiki.mozilla.org/Security/Server_Side_TLS + 'ciphers' => 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:' + . 'ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:' + . 'DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:' + . 'ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:' + . 'ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:' + . 'ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:' + . 'ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:' + . 'DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:' + . 'DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:' + . 'ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:' + . 'AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:' + . 'AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:' + . '!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA' + ); + if (version_compare(phpversion(), '5.4.13', '>=')) { + $contextOptions['ssl']['disable_compression'] = true; + if (version_compare(phpversion(), '5.6', '>=')) { + $contextOptions['ssl']['crypto_method'] = STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT + | STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT; + } + } + } + $context = stream_context_create(); + foreach ($contextOptions as $wrapper => $options) { + foreach ($options as $name => $value) { + if (!stream_context_set_option($context, $wrapper, $name, $value)) { + throw new HTTP_Request2_LogicException( + "Error setting '{$wrapper}' wrapper context option '{$name}'" + ); + } + } + } + set_error_handler(array($this, 'connectionWarningsHandler')); + $this->socket = stream_socket_client( + $address, $errno, $errstr, $timeout, STREAM_CLIENT_CONNECT, $context + ); + restore_error_handler(); + // if we fail to bind to a specified local address (see request #19515), + // connection still succeeds, albeit with a warning. Throw an Exception + // with the warning text in this case as that connection is unlikely + // to be what user wants and as Curl throws an error in similar case. + if ($this->connectionWarnings) { + if ($this->socket) { + fclose($this->socket); + } + $error = $errstr ? $errstr : implode("\n", $this->connectionWarnings); + throw new HTTP_Request2_ConnectionException( + "Unable to connect to {$address}. Error: {$error}", 0, $errno + ); + } + } + + /** + * Destructor, disconnects socket + */ + public function __destruct() + { + fclose($this->socket); + } + + /** + * Wrapper around fread(), handles global request timeout + * + * @param int $length Reads up to this number of bytes + * + * @return string Data read from socket + * @throws HTTP_Request2_MessageException In case of timeout + */ + public function read($length) + { + if ($this->deadline) { + stream_set_timeout($this->socket, max($this->deadline - time(), 1)); + } + $data = fread($this->socket, $length); + $this->checkTimeout(); + return $data; + } + + /** + * Reads until either the end of the socket or a newline, whichever comes first + * + * Strips the trailing newline from the returned data, handles global + * request timeout. Method idea borrowed from Net_Socket PEAR package. + * + * @param int $bufferSize buffer size to use for reading + * @param int $localTimeout timeout value to use just for this call + * (used when waiting for "100 Continue" response) + * + * @return string Available data up to the newline (not including newline) + * @throws HTTP_Request2_MessageException In case of timeout + */ + public function readLine($bufferSize, $localTimeout = null) + { + $line = ''; + while (!feof($this->socket)) { + if (null !== $localTimeout) { + stream_set_timeout($this->socket, $localTimeout); + } elseif ($this->deadline) { + stream_set_timeout($this->socket, max($this->deadline - time(), 1)); + } + + $line .= @fgets($this->socket, $bufferSize); + + if (null === $localTimeout) { + $this->checkTimeout(); + + } else { + $info = stream_get_meta_data($this->socket); + // reset socket timeout if we don't have request timeout specified, + // prevents further calls failing with a bogus Exception + if (!$this->deadline) { + $default = (int)@ini_get('default_socket_timeout'); + stream_set_timeout($this->socket, $default > 0 ? $default : PHP_INT_MAX); + } + if ($info['timed_out']) { + throw new HTTP_Request2_MessageException( + "readLine() call timed out", HTTP_Request2_Exception::TIMEOUT + ); + } + } + if (substr($line, -1) == "\n") { + return rtrim($line, "\r\n"); + } + } + return $line; + } + + /** + * Wrapper around fwrite(), handles global request timeout + * + * @param string $data String to be written + * + * @return int + * @throws HTTP_Request2_MessageException + */ + public function write($data) + { + if ($this->deadline) { + stream_set_timeout($this->socket, max($this->deadline - time(), 1)); + } + $written = fwrite($this->socket, $data); + $this->checkTimeout(); + // http://www.php.net/manual/en/function.fwrite.php#96951 + if ($written < strlen($data)) { + throw new HTTP_Request2_MessageException('Error writing request'); + } + return $written; + } + + /** + * Tests for end-of-file on a socket + * + * @return bool + */ + public function eof() + { + return feof($this->socket); + } + + /** + * Sets request deadline + * + * @param int $deadline Exception will be thrown if request continues + * past this time + * @param int $timeout Original request timeout value, to use in + * Exception message + */ + public function setDeadline($deadline, $timeout) + { + $this->deadline = $deadline; + $this->timeout = $timeout; + } + + /** + * Turns on encryption on a socket + * + * @throws HTTP_Request2_ConnectionException + */ + public function enableCrypto() + { + if (version_compare(phpversion(), '5.6', '<')) { + $cryptoMethod = STREAM_CRYPTO_METHOD_TLS_CLIENT; + } else { + $cryptoMethod = STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT + | STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT; + } + + if (!stream_socket_enable_crypto($this->socket, true, $cryptoMethod)) { + throw new HTTP_Request2_ConnectionException( + 'Failed to enable secure connection when connecting through proxy' + ); + } + } + + /** + * Throws an Exception if stream timed out + * + * @throws HTTP_Request2_MessageException + */ + protected function checkTimeout() + { + $info = stream_get_meta_data($this->socket); + if ($info['timed_out'] || $this->deadline && time() > $this->deadline) { + $reason = $this->deadline + ? "after {$this->timeout} second(s)" + : 'due to default_socket_timeout php.ini setting'; + throw new HTTP_Request2_MessageException( + "Request timed out {$reason}", HTTP_Request2_Exception::TIMEOUT + ); + } + } + + /** + * Error handler to use during stream_socket_client() call + * + * One stream_socket_client() call may produce *multiple* PHP warnings + * (especially OpenSSL-related), we keep them in an array to later use for + * the message of HTTP_Request2_ConnectionException + * + * @param int $errno error level + * @param string $errstr error message + * + * @return bool + */ + protected function connectionWarningsHandler($errno, $errstr) + { + if ($errno & E_WARNING) { + array_unshift($this->connectionWarnings, $errstr); + } + return true; + } +} +?> diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/HTTP_Request2/data/generate-list.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/HTTP_Request2/data/generate-list.php new file mode 100644 index 0000000..b27c5f9 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/HTTP_Request2/data/generate-list.php @@ -0,0 +1,103 @@ + "); + } + + if (0 == ($count = count($valueTree))) { + fwrite($fp, 'true'); + } else { + fwrite($fp, "array(\n"); + for ($keys = array_keys($valueTree), $i = 0; $i < $count; $i++) { + writeNode($fp, $valueTree[$keys[$i]], $keys[$i], $indent + 1); + if ($i + 1 != $count) { + fwrite($fp, ",\n"); + } else { + fwrite($fp, "\n"); + } + } + fwrite($fp, str_repeat(' ', $indent) . ")"); + } +} + + +try { + $request = new HTTP_Request2(LIST_URL, HTTP_Request2::METHOD_GET, array( + // Provide path to your CA file and change 'ssl_verify_peer' to true to enable peer validation + // 'ssl_cafile' => '... path to your Certificate Authority file ...', + 'ssl_verify_peer' => false + )); + $response = $request->send(); + if (200 != $response->getStatus()) { + throw new Exception("List download URL returned status: " . + $response->getStatus() . ' ' . $response->getReasonPhrase()); + } + $list = $response->getBody(); + if (false === strpos($list, '// ===BEGIN ICANN DOMAINS===')) { + throw new Exception("List download URL does not contain expected phrase"); + } + if (!($fp = @fopen(OUTPUT_FILE, 'wt'))) { + throw new Exception("Unable to open " . OUTPUT_FILE); + } + +} catch (Exception $e) { + die($e->getMessage()); +} + +$tldTree = array(); +$license = true; + +fwrite($fp, ""); +fclose($fp); +?> \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/HTTP_Request2/data/public-suffix-list.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/HTTP_Request2/data/public-suffix-list.php new file mode 100644 index 0000000..fedfd31 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/HTTP_Request2/data/public-suffix-list.php @@ -0,0 +1,8333 @@ + array( + 'com' => true, + 'edu' => true, + 'gov' => true, + 'net' => true, + 'mil' => true, + 'org' => true + ), + 'ad' => array( + 'nom' => true + ), + 'ae' => array( + 'co' => true, + 'net' => true, + 'org' => true, + 'sch' => true, + 'ac' => true, + 'gov' => true, + 'mil' => true, + 'blogspot' => true + ), + 'aero' => array( + 'accident-investigation' => true, + 'accident-prevention' => true, + 'aerobatic' => true, + 'aeroclub' => true, + 'aerodrome' => true, + 'agents' => true, + 'aircraft' => true, + 'airline' => true, + 'airport' => true, + 'air-surveillance' => true, + 'airtraffic' => true, + 'air-traffic-control' => true, + 'ambulance' => true, + 'amusement' => true, + 'association' => true, + 'author' => true, + 'ballooning' => true, + 'broker' => true, + 'caa' => true, + 'cargo' => true, + 'catering' => true, + 'certification' => true, + 'championship' => true, + 'charter' => true, + 'civilaviation' => true, + 'club' => true, + 'conference' => true, + 'consultant' => true, + 'consulting' => true, + 'control' => true, + 'council' => true, + 'crew' => true, + 'design' => true, + 'dgca' => true, + 'educator' => true, + 'emergency' => true, + 'engine' => true, + 'engineer' => true, + 'entertainment' => true, + 'equipment' => true, + 'exchange' => true, + 'express' => true, + 'federation' => true, + 'flight' => true, + 'freight' => true, + 'fuel' => true, + 'gliding' => true, + 'government' => true, + 'groundhandling' => true, + 'group' => true, + 'hanggliding' => true, + 'homebuilt' => true, + 'insurance' => true, + 'journal' => true, + 'journalist' => true, + 'leasing' => true, + 'logistics' => true, + 'magazine' => true, + 'maintenance' => true, + 'media' => true, + 'microlight' => true, + 'modelling' => true, + 'navigation' => true, + 'parachuting' => true, + 'paragliding' => true, + 'passenger-association' => true, + 'pilot' => true, + 'press' => true, + 'production' => true, + 'recreation' => true, + 'repbody' => true, + 'res' => true, + 'research' => true, + 'rotorcraft' => true, + 'safety' => true, + 'scientist' => true, + 'services' => true, + 'show' => true, + 'skydiving' => true, + 'software' => true, + 'student' => true, + 'trader' => true, + 'trading' => true, + 'trainer' => true, + 'union' => true, + 'workinggroup' => true, + 'works' => true + ), + 'af' => array( + 'gov' => true, + 'com' => true, + 'org' => true, + 'net' => true, + 'edu' => true + ), + 'ag' => array( + 'com' => true, + 'org' => true, + 'net' => true, + 'co' => true, + 'nom' => true + ), + 'ai' => array( + 'off' => true, + 'com' => true, + 'net' => true, + 'org' => true + ), + 'al' => array( + 'com' => true, + 'edu' => true, + 'gov' => true, + 'mil' => true, + 'net' => true, + 'org' => true, + 'blogspot' => true + ), + 'am' => array( + 'blogspot' => true + ), + 'ao' => array( + 'ed' => true, + 'gv' => true, + 'og' => true, + 'co' => true, + 'pb' => true, + 'it' => true + ), + 'aq' => true, + 'ar' => array( + 'com' => array( + 'blogspot' => true + ), + 'edu' => true, + 'gob' => true, + 'gov' => true, + 'int' => true, + 'mil' => true, + 'net' => true, + 'org' => true, + 'tur' => true + ), + 'arpa' => array( + 'e164' => true, + 'in-addr' => true, + 'ip6' => true, + 'iris' => true, + 'uri' => true, + 'urn' => true + ), + 'as' => array( + 'gov' => true + ), + 'asia' => true, + 'at' => array( + 'ac' => true, + 'co' => array( + 'blogspot' => true + ), + 'gv' => true, + 'or' => true, + 'biz' => true, + 'info' => true, + 'priv' => true + ), + 'au' => array( + 'com' => array( + 'blogspot' => true + ), + 'net' => true, + 'org' => true, + 'edu' => array( + 'act' => true, + 'nsw' => true, + 'nt' => true, + 'qld' => true, + 'sa' => true, + 'tas' => true, + 'vic' => true, + 'wa' => true + ), + 'gov' => array( + 'qld' => true, + 'sa' => true, + 'tas' => true, + 'vic' => true, + 'wa' => true + ), + 'asn' => true, + 'id' => true, + 'info' => true, + 'conf' => true, + 'oz' => true, + 'act' => true, + 'nsw' => true, + 'nt' => true, + 'qld' => true, + 'sa' => true, + 'tas' => true, + 'vic' => true, + 'wa' => true + ), + 'aw' => array( + 'com' => true + ), + 'ax' => true, + 'az' => array( + 'com' => true, + 'net' => true, + 'int' => true, + 'gov' => true, + 'org' => true, + 'edu' => true, + 'info' => true, + 'pp' => true, + 'mil' => true, + 'name' => true, + 'pro' => true, + 'biz' => true + ), + 'ba' => array( + 'org' => true, + 'net' => true, + 'edu' => true, + 'gov' => true, + 'mil' => true, + 'unsa' => true, + 'unbi' => true, + 'co' => true, + 'com' => true, + 'rs' => true, + 'blogspot' => true + ), + 'bb' => array( + 'biz' => true, + 'co' => true, + 'com' => true, + 'edu' => true, + 'gov' => true, + 'info' => true, + 'net' => true, + 'org' => true, + 'store' => true, + 'tv' => true + ), + 'bd' => array( + '*' => true + ), + 'be' => array( + 'ac' => true, + 'blogspot' => true + ), + 'bf' => array( + 'gov' => true + ), + 'bg' => array( + 'a' => true, + 'b' => true, + 'c' => true, + 'd' => true, + 'e' => true, + 'f' => true, + 'g' => true, + 'h' => true, + 'i' => true, + 'j' => true, + 'k' => true, + 'l' => true, + 'm' => true, + 'n' => true, + 'o' => true, + 'p' => true, + 'q' => true, + 'r' => true, + 's' => true, + 't' => true, + 'u' => true, + 'v' => true, + 'w' => true, + 'x' => true, + 'y' => true, + 'z' => true, + '0' => true, + '1' => true, + '2' => true, + '3' => true, + '4' => true, + '5' => true, + '6' => true, + '7' => true, + '8' => true, + '9' => true, + 'blogspot' => true + ), + 'bh' => array( + 'com' => true, + 'edu' => true, + 'net' => true, + 'org' => true, + 'gov' => true + ), + 'bi' => array( + 'co' => true, + 'com' => true, + 'edu' => true, + 'or' => true, + 'org' => true + ), + 'biz' => array( + 'dyndns' => true, + 'for-better' => true, + 'for-more' => true, + 'for-some' => true, + 'for-the' => true, + 'selfip' => true, + 'webhop' => true, + 'dscloud' => true + ), + 'bj' => array( + 'asso' => true, + 'barreau' => true, + 'gouv' => true, + 'blogspot' => true + ), + 'bm' => array( + 'com' => true, + 'edu' => true, + 'gov' => true, + 'net' => true, + 'org' => true + ), + 'bn' => array( + '*' => true + ), + 'bo' => array( + 'com' => true, + 'edu' => true, + 'gov' => true, + 'gob' => true, + 'int' => true, + 'org' => true, + 'net' => true, + 'mil' => true, + 'tv' => true + ), + 'br' => array( + 'adm' => true, + 'adv' => true, + 'agr' => true, + 'am' => true, + 'arq' => true, + 'art' => true, + 'ato' => true, + 'b' => true, + 'bio' => true, + 'blog' => true, + 'bmd' => true, + 'cim' => true, + 'cng' => true, + 'cnt' => true, + 'com' => array( + 'blogspot' => true + ), + 'coop' => true, + 'ecn' => true, + 'eco' => true, + 'edu' => true, + 'emp' => true, + 'eng' => true, + 'esp' => true, + 'etc' => true, + 'eti' => true, + 'far' => true, + 'flog' => true, + 'fm' => true, + 'fnd' => true, + 'fot' => true, + 'fst' => true, + 'g12' => true, + 'ggf' => true, + 'gov' => true, + 'imb' => true, + 'ind' => true, + 'inf' => true, + 'jor' => true, + 'jus' => true, + 'leg' => true, + 'lel' => true, + 'mat' => true, + 'med' => true, + 'mil' => true, + 'mp' => true, + 'mus' => true, + 'net' => true, + 'nom' => array( + '*' => true + ), + 'not' => true, + 'ntr' => true, + 'odo' => true, + 'org' => true, + 'ppg' => true, + 'pro' => true, + 'psc' => true, + 'psi' => true, + 'qsl' => true, + 'radio' => true, + 'rec' => true, + 'slg' => true, + 'srv' => true, + 'taxi' => true, + 'teo' => true, + 'tmp' => true, + 'trd' => true, + 'tur' => true, + 'tv' => true, + 'vet' => true, + 'vlog' => true, + 'wiki' => true, + 'zlg' => true + ), + 'bs' => array( + 'com' => true, + 'net' => true, + 'org' => true, + 'edu' => true, + 'gov' => true + ), + 'bt' => array( + 'com' => true, + 'edu' => true, + 'gov' => true, + 'net' => true, + 'org' => true + ), + 'bv' => true, + 'bw' => array( + 'co' => true, + 'org' => true + ), + 'by' => array( + 'gov' => true, + 'mil' => true, + 'com' => array( + 'blogspot' => true + ), + 'of' => true + ), + 'bz' => array( + 'com' => true, + 'net' => true, + 'org' => true, + 'edu' => true, + 'gov' => true, + 'za' => true + ), + 'ca' => array( + 'ab' => true, + 'bc' => true, + 'mb' => true, + 'nb' => true, + 'nf' => true, + 'nl' => true, + 'ns' => true, + 'nt' => true, + 'nu' => true, + 'on' => true, + 'pe' => true, + 'qc' => true, + 'sk' => true, + 'yk' => true, + 'gc' => true, + 'co' => true, + 'blogspot' => true + ), + 'cat' => true, + 'cc' => array( + 'ftpaccess' => true, + 'game-server' => true, + 'myphotos' => true, + 'scrapping' => true + ), + 'cd' => array( + 'gov' => true + ), + 'cf' => array( + 'blogspot' => true + ), + 'cg' => true, + 'ch' => array( + 'blogspot' => true + ), + 'ci' => array( + 'org' => true, + 'or' => true, + 'com' => true, + 'co' => true, + 'edu' => true, + 'ed' => true, + 'ac' => true, + 'net' => true, + 'go' => true, + 'asso' => true, + 'aéroport' => true, + 'int' => true, + 'presse' => true, + 'md' => true, + 'gouv' => true + ), + 'ck' => array( + '*' => true, + '!www' => true + ), + 'cl' => array( + 'gov' => true, + 'gob' => true, + 'co' => true, + 'mil' => true, + 'blogspot' => true + ), + 'cm' => array( + 'co' => true, + 'com' => true, + 'gov' => true, + 'net' => true + ), + 'cn' => array( + 'ac' => true, + 'com' => array( + 'amazonaws' => array( + 'cn-north-1' => array( + 's3' => true + ) + ) + ), + 'edu' => true, + 'gov' => true, + 'net' => true, + 'org' => true, + 'mil' => true, + '公司' => true, + '网络' => true, + '網絡' => true, + 'ah' => true, + 'bj' => true, + 'cq' => true, + 'fj' => true, + 'gd' => true, + 'gs' => true, + 'gz' => true, + 'gx' => true, + 'ha' => true, + 'hb' => true, + 'he' => true, + 'hi' => true, + 'hl' => true, + 'hn' => true, + 'jl' => true, + 'js' => true, + 'jx' => true, + 'ln' => true, + 'nm' => true, + 'nx' => true, + 'qh' => true, + 'sc' => true, + 'sd' => true, + 'sh' => true, + 'sn' => true, + 'sx' => true, + 'tj' => true, + 'xj' => true, + 'xz' => true, + 'yn' => true, + 'zj' => true, + 'hk' => true, + 'mo' => true, + 'tw' => true, + 'amazonaws' => array( + 'compute' => array( + 'cn-north-1' => true + ) + ) + ), + 'co' => array( + 'arts' => true, + 'com' => array( + 'blogspot' => true + ), + 'edu' => true, + 'firm' => true, + 'gov' => true, + 'info' => true, + 'int' => true, + 'mil' => true, + 'net' => true, + 'nom' => true, + 'org' => true, + 'rec' => true, + 'web' => true + ), + 'com' => array( + 'amazonaws' => array( + 'compute' => array( + 'ap-northeast-1' => true, + 'ap-northeast-2' => true, + 'ap-southeast-1' => true, + 'ap-southeast-2' => true, + 'eu-central-1' => true, + 'eu-west-1' => true, + 'sa-east-1' => true, + 'us-gov-west-1' => true, + 'us-west-1' => true, + 'us-west-2' => true + ), + 'compute-1' => array( + 'z-1' => true, + 'z-2' => true + ), + 'us-east-1' => true, + 'elb' => true, + 's3' => true, + 's3-ap-northeast-1' => true, + 's3-ap-northeast-2' => true, + 's3-ap-southeast-1' => true, + 's3-ap-southeast-2' => true, + 's3-eu-central-1' => true, + 's3-eu-west-1' => true, + 's3-external-1' => true, + 's3-external-2' => true, + 's3-fips-us-gov-west-1' => true, + 's3-sa-east-1' => true, + 's3-us-gov-west-1' => true, + 's3-us-west-1' => true, + 's3-us-west-2' => true, + 'ap-northeast-2' => array( + 's3' => true + ), + 'eu-central-1' => array( + 's3' => true + ) + ), + 'elasticbeanstalk' => true, + 'betainabox' => true, + 'ar' => true, + 'br' => true, + 'cn' => true, + 'de' => true, + 'eu' => true, + 'gb' => true, + 'hu' => true, + 'jpn' => true, + 'kr' => true, + 'mex' => true, + 'no' => true, + 'qc' => true, + 'ru' => true, + 'sa' => true, + 'se' => true, + 'uk' => true, + 'us' => true, + 'uy' => true, + 'za' => true, + 'africa' => true, + 'xenapponazure' => true, + 'gr' => true, + 'co' => true, + 'cloudcontrolled' => true, + 'cloudcontrolapp' => true, + 'dreamhosters' => true, + 'mydrobo' => true, + 'dyndns-at-home' => true, + 'dyndns-at-work' => true, + 'dyndns-blog' => true, + 'dyndns-free' => true, + 'dyndns-home' => true, + 'dyndns-ip' => true, + 'dyndns-mail' => true, + 'dyndns-office' => true, + 'dyndns-pics' => true, + 'dyndns-remote' => true, + 'dyndns-server' => true, + 'dyndns-web' => true, + 'dyndns-wiki' => true, + 'dyndns-work' => true, + 'blogdns' => true, + 'cechire' => true, + 'dnsalias' => true, + 'dnsdojo' => true, + 'doesntexist' => true, + 'dontexist' => true, + 'doomdns' => true, + 'dyn-o-saur' => true, + 'dynalias' => true, + 'est-a-la-maison' => true, + 'est-a-la-masion' => true, + 'est-le-patron' => true, + 'est-mon-blogueur' => true, + 'from-ak' => true, + 'from-al' => true, + 'from-ar' => true, + 'from-ca' => true, + 'from-ct' => true, + 'from-dc' => true, + 'from-de' => true, + 'from-fl' => true, + 'from-ga' => true, + 'from-hi' => true, + 'from-ia' => true, + 'from-id' => true, + 'from-il' => true, + 'from-in' => true, + 'from-ks' => true, + 'from-ky' => true, + 'from-ma' => true, + 'from-md' => true, + 'from-mi' => true, + 'from-mn' => true, + 'from-mo' => true, + 'from-ms' => true, + 'from-mt' => true, + 'from-nc' => true, + 'from-nd' => true, + 'from-ne' => true, + 'from-nh' => true, + 'from-nj' => true, + 'from-nm' => true, + 'from-nv' => true, + 'from-oh' => true, + 'from-ok' => true, + 'from-or' => true, + 'from-pa' => true, + 'from-pr' => true, + 'from-ri' => true, + 'from-sc' => true, + 'from-sd' => true, + 'from-tn' => true, + 'from-tx' => true, + 'from-ut' => true, + 'from-va' => true, + 'from-vt' => true, + 'from-wa' => true, + 'from-wi' => true, + 'from-wv' => true, + 'from-wy' => true, + 'getmyip' => true, + 'gotdns' => true, + 'hobby-site' => true, + 'homelinux' => true, + 'homeunix' => true, + 'iamallama' => true, + 'is-a-anarchist' => true, + 'is-a-blogger' => true, + 'is-a-bookkeeper' => true, + 'is-a-bulls-fan' => true, + 'is-a-caterer' => true, + 'is-a-chef' => true, + 'is-a-conservative' => true, + 'is-a-cpa' => true, + 'is-a-cubicle-slave' => true, + 'is-a-democrat' => true, + 'is-a-designer' => true, + 'is-a-doctor' => true, + 'is-a-financialadvisor' => true, + 'is-a-geek' => true, + 'is-a-green' => true, + 'is-a-guru' => true, + 'is-a-hard-worker' => true, + 'is-a-hunter' => true, + 'is-a-landscaper' => true, + 'is-a-lawyer' => true, + 'is-a-liberal' => true, + 'is-a-libertarian' => true, + 'is-a-llama' => true, + 'is-a-musician' => true, + 'is-a-nascarfan' => true, + 'is-a-nurse' => true, + 'is-a-painter' => true, + 'is-a-personaltrainer' => true, + 'is-a-photographer' => true, + 'is-a-player' => true, + 'is-a-republican' => true, + 'is-a-rockstar' => true, + 'is-a-socialist' => true, + 'is-a-student' => true, + 'is-a-teacher' => true, + 'is-a-techie' => true, + 'is-a-therapist' => true, + 'is-an-accountant' => true, + 'is-an-actor' => true, + 'is-an-actress' => true, + 'is-an-anarchist' => true, + 'is-an-artist' => true, + 'is-an-engineer' => true, + 'is-an-entertainer' => true, + 'is-certified' => true, + 'is-gone' => true, + 'is-into-anime' => true, + 'is-into-cars' => true, + 'is-into-cartoons' => true, + 'is-into-games' => true, + 'is-leet' => true, + 'is-not-certified' => true, + 'is-slick' => true, + 'is-uberleet' => true, + 'is-with-theband' => true, + 'isa-geek' => true, + 'isa-hockeynut' => true, + 'issmarterthanyou' => true, + 'likes-pie' => true, + 'likescandy' => true, + 'neat-url' => true, + 'saves-the-whales' => true, + 'selfip' => true, + 'sells-for-less' => true, + 'sells-for-u' => true, + 'servebbs' => true, + 'simple-url' => true, + 'space-to-rent' => true, + 'teaches-yoga' => true, + 'writesthisblog' => true, + 'firebaseapp' => true, + 'flynnhub' => true, + 'githubusercontent' => true, + 'ro' => true, + 'appspot' => true, + 'blogspot' => true, + 'codespot' => true, + 'googleapis' => true, + 'googlecode' => true, + 'pagespeedmobilizer' => true, + 'withgoogle' => true, + 'withyoutube' => true, + 'herokuapp' => true, + 'herokussl' => true, + '4u' => true, + 'nfshost' => true, + 'operaunite' => true, + 'outsystemscloud' => true, + 'pagefrontapp' => true, + 'gotpantheon' => true, + 'prgmr' => array( + 'xen' => true + ), + 'qa2' => true, + 'rackmaze' => true, + 'rhcloud' => true, + 'sinaapp' => true, + 'vipsinaapp' => true, + '1kapp' => true, + 'dsmynas' => true, + 'familyds' => true, + 'hk' => true, + 'yolasite' => true + ), + 'coop' => true, + 'cr' => array( + 'ac' => true, + 'co' => true, + 'ed' => true, + 'fi' => true, + 'go' => true, + 'or' => true, + 'sa' => true + ), + 'cu' => array( + 'com' => true, + 'edu' => true, + 'org' => true, + 'net' => true, + 'gov' => true, + 'inf' => true + ), + 'cv' => array( + 'blogspot' => true + ), + 'cw' => array( + 'com' => true, + 'edu' => true, + 'net' => true, + 'org' => true + ), + 'cx' => array( + 'gov' => true, + 'ath' => true + ), + 'cy' => array( + 'ac' => true, + 'biz' => true, + 'com' => array( + 'blogspot' => true + ), + 'ekloges' => true, + 'gov' => true, + 'ltd' => true, + 'name' => true, + 'net' => true, + 'org' => true, + 'parliament' => true, + 'press' => true, + 'pro' => true, + 'tm' => true + ), + 'cz' => array( + 'co' => true, + 'blogspot' => true + ), + 'de' => array( + 'com' => true, + 'fuettertdasnetz' => true, + 'isteingeek' => true, + 'istmein' => true, + 'lebtimnetz' => true, + 'leitungsen' => true, + 'traeumtgerade' => true, + 'blogspot' => true + ), + 'dj' => true, + 'dk' => array( + 'blogspot' => true + ), + 'dm' => array( + 'com' => true, + 'net' => true, + 'org' => true, + 'edu' => true, + 'gov' => true + ), + 'do' => array( + 'art' => true, + 'com' => true, + 'edu' => true, + 'gob' => true, + 'gov' => true, + 'mil' => true, + 'net' => true, + 'org' => true, + 'sld' => true, + 'web' => true + ), + 'dz' => array( + 'com' => true, + 'org' => true, + 'net' => true, + 'gov' => true, + 'edu' => true, + 'asso' => true, + 'pol' => true, + 'art' => true + ), + 'ec' => array( + 'com' => true, + 'info' => true, + 'net' => true, + 'fin' => true, + 'k12' => true, + 'med' => true, + 'pro' => true, + 'org' => true, + 'edu' => true, + 'gov' => true, + 'gob' => true, + 'mil' => true + ), + 'edu' => true, + 'ee' => array( + 'edu' => true, + 'gov' => true, + 'riik' => true, + 'lib' => true, + 'med' => true, + 'com' => array( + 'blogspot' => true + ), + 'pri' => true, + 'aip' => true, + 'org' => true, + 'fie' => true + ), + 'eg' => array( + 'com' => array( + 'blogspot' => true + ), + 'edu' => true, + 'eun' => true, + 'gov' => true, + 'mil' => true, + 'name' => true, + 'net' => true, + 'org' => true, + 'sci' => true + ), + 'er' => array( + '*' => true + ), + 'es' => array( + 'com' => array( + 'blogspot' => true + ), + 'nom' => true, + 'org' => true, + 'gob' => true, + 'edu' => true + ), + 'et' => array( + 'com' => true, + 'gov' => true, + 'org' => true, + 'edu' => true, + 'biz' => true, + 'name' => true, + 'info' => true, + 'net' => true + ), + 'eu' => true, + 'fi' => array( + 'aland' => true, + 'blogspot' => true, + 'iki' => true + ), + 'fj' => array( + '*' => true + ), + 'fk' => array( + '*' => true + ), + 'fm' => true, + 'fo' => true, + 'fr' => array( + 'com' => true, + 'asso' => true, + 'nom' => true, + 'prd' => true, + 'presse' => true, + 'tm' => true, + 'aeroport' => true, + 'assedic' => true, + 'avocat' => true, + 'avoues' => true, + 'cci' => true, + 'chambagri' => true, + 'chirurgiens-dentistes' => true, + 'experts-comptables' => true, + 'geometre-expert' => true, + 'gouv' => true, + 'greta' => true, + 'huissier-justice' => true, + 'medecin' => true, + 'notaires' => true, + 'pharmacien' => true, + 'port' => true, + 'veterinaire' => true, + 'blogspot' => true + ), + 'ga' => true, + 'gb' => true, + 'gd' => true, + 'ge' => array( + 'com' => true, + 'edu' => true, + 'gov' => true, + 'org' => true, + 'mil' => true, + 'net' => true, + 'pvt' => true + ), + 'gf' => true, + 'gg' => array( + 'co' => true, + 'net' => true, + 'org' => true + ), + 'gh' => array( + 'com' => true, + 'edu' => true, + 'gov' => true, + 'org' => true, + 'mil' => true + ), + 'gi' => array( + 'com' => true, + 'ltd' => true, + 'gov' => true, + 'mod' => true, + 'edu' => true, + 'org' => true + ), + 'gl' => array( + 'co' => true, + 'com' => true, + 'edu' => true, + 'net' => true, + 'org' => true + ), + 'gm' => true, + 'gn' => array( + 'ac' => true, + 'com' => true, + 'edu' => true, + 'gov' => true, + 'org' => true, + 'net' => true + ), + 'gov' => true, + 'gp' => array( + 'com' => true, + 'net' => true, + 'mobi' => true, + 'edu' => true, + 'org' => true, + 'asso' => true + ), + 'gq' => true, + 'gr' => array( + 'com' => true, + 'edu' => true, + 'net' => true, + 'org' => true, + 'gov' => true, + 'blogspot' => true + ), + 'gs' => true, + 'gt' => array( + 'com' => true, + 'edu' => true, + 'gob' => true, + 'ind' => true, + 'mil' => true, + 'net' => true, + 'org' => true + ), + 'gu' => array( + '*' => true + ), + 'gw' => true, + 'gy' => array( + 'co' => true, + 'com' => true, + 'edu' => true, + 'gov' => true, + 'net' => true, + 'org' => true + ), + 'hk' => array( + 'com' => true, + 'edu' => true, + 'gov' => true, + 'idv' => true, + 'net' => true, + 'org' => true, + '公司' => true, + '教育' => true, + '敎育' => true, + '政府' => true, + '個人' => true, + '个人' => true, + '箇人' => true, + '網络' => true, + '网络' => true, + '组織' => true, + '網絡' => true, + '网絡' => true, + '组织' => true, + '組織' => true, + '組织' => true, + 'blogspot' => true, + 'ltd' => true, + 'inc' => true + ), + 'hm' => true, + 'hn' => array( + 'com' => true, + 'edu' => true, + 'org' => true, + 'net' => true, + 'mil' => true, + 'gob' => true + ), + 'hr' => array( + 'iz' => true, + 'from' => true, + 'name' => true, + 'com' => true, + 'blogspot' => true + ), + 'ht' => array( + 'com' => true, + 'shop' => true, + 'firm' => true, + 'info' => true, + 'adult' => true, + 'net' => true, + 'pro' => true, + 'org' => true, + 'med' => true, + 'art' => true, + 'coop' => true, + 'pol' => true, + 'asso' => true, + 'edu' => true, + 'rel' => true, + 'gouv' => true, + 'perso' => true + ), + 'hu' => array( + 'co' => true, + 'info' => true, + 'org' => true, + 'priv' => true, + 'sport' => true, + 'tm' => true, + '2000' => true, + 'agrar' => true, + 'bolt' => true, + 'casino' => true, + 'city' => true, + 'erotica' => true, + 'erotika' => true, + 'film' => true, + 'forum' => true, + 'games' => true, + 'hotel' => true, + 'ingatlan' => true, + 'jogasz' => true, + 'konyvelo' => true, + 'lakas' => true, + 'media' => true, + 'news' => true, + 'reklam' => true, + 'sex' => true, + 'shop' => true, + 'suli' => true, + 'szex' => true, + 'tozsde' => true, + 'utazas' => true, + 'video' => true, + 'blogspot' => true + ), + 'id' => array( + 'ac' => true, + 'biz' => true, + 'co' => array( + 'blogspot' => true + ), + 'desa' => true, + 'go' => true, + 'mil' => true, + 'my' => true, + 'net' => true, + 'or' => true, + 'sch' => true, + 'web' => true + ), + 'ie' => array( + 'gov' => true, + 'blogspot' => true + ), + 'il' => array( + 'ac' => true, + 'co' => array( + 'blogspot' => true + ), + 'gov' => true, + 'idf' => true, + 'k12' => true, + 'muni' => true, + 'net' => true, + 'org' => true + ), + 'im' => array( + 'ac' => true, + 'co' => array( + 'ltd' => true, + 'plc' => true + ), + 'com' => true, + 'net' => true, + 'org' => true, + 'tt' => true, + 'tv' => true + ), + 'in' => array( + 'co' => true, + 'firm' => true, + 'net' => true, + 'org' => true, + 'gen' => true, + 'ind' => true, + 'nic' => true, + 'ac' => true, + 'edu' => true, + 'res' => true, + 'gov' => true, + 'mil' => true, + 'blogspot' => true + ), + 'info' => array( + 'dyndns' => true, + 'barrel-of-knowledge' => true, + 'barrell-of-knowledge' => true, + 'for-our' => true, + 'groks-the' => true, + 'groks-this' => true, + 'here-for-more' => true, + 'knowsitall' => true, + 'selfip' => true, + 'webhop' => true + ), + 'int' => array( + 'eu' => true + ), + 'io' => array( + 'com' => true, + 'github' => true, + 'ngrok' => true, + 'nid' => true, + 'pantheon' => true, + 'sandcats' => true + ), + 'iq' => array( + 'gov' => true, + 'edu' => true, + 'mil' => true, + 'com' => true, + 'org' => true, + 'net' => true + ), + 'ir' => array( + 'ac' => true, + 'co' => true, + 'gov' => true, + 'id' => true, + 'net' => true, + 'org' => true, + 'sch' => true, + 'ایران' => true, + 'ايران' => true + ), + 'is' => array( + 'net' => true, + 'com' => true, + 'edu' => true, + 'gov' => true, + 'org' => true, + 'int' => true, + 'cupcake' => true, + 'blogspot' => true + ), + 'it' => array( + 'gov' => true, + 'edu' => true, + 'abr' => true, + 'abruzzo' => true, + 'aosta-valley' => true, + 'aostavalley' => true, + 'bas' => true, + 'basilicata' => true, + 'cal' => true, + 'calabria' => true, + 'cam' => true, + 'campania' => true, + 'emilia-romagna' => true, + 'emiliaromagna' => true, + 'emr' => true, + 'friuli-v-giulia' => true, + 'friuli-ve-giulia' => true, + 'friuli-vegiulia' => true, + 'friuli-venezia-giulia' => true, + 'friuli-veneziagiulia' => true, + 'friuli-vgiulia' => true, + 'friuliv-giulia' => true, + 'friulive-giulia' => true, + 'friulivegiulia' => true, + 'friulivenezia-giulia' => true, + 'friuliveneziagiulia' => true, + 'friulivgiulia' => true, + 'fvg' => true, + 'laz' => true, + 'lazio' => true, + 'lig' => true, + 'liguria' => true, + 'lom' => true, + 'lombardia' => true, + 'lombardy' => true, + 'lucania' => true, + 'mar' => true, + 'marche' => true, + 'mol' => true, + 'molise' => true, + 'piedmont' => true, + 'piemonte' => true, + 'pmn' => true, + 'pug' => true, + 'puglia' => true, + 'sar' => true, + 'sardegna' => true, + 'sardinia' => true, + 'sic' => true, + 'sicilia' => true, + 'sicily' => true, + 'taa' => true, + 'tos' => true, + 'toscana' => true, + 'trentino-a-adige' => true, + 'trentino-aadige' => true, + 'trentino-alto-adige' => true, + 'trentino-altoadige' => true, + 'trentino-s-tirol' => true, + 'trentino-stirol' => true, + 'trentino-sud-tirol' => true, + 'trentino-sudtirol' => true, + 'trentino-sued-tirol' => true, + 'trentino-suedtirol' => true, + 'trentinoa-adige' => true, + 'trentinoaadige' => true, + 'trentinoalto-adige' => true, + 'trentinoaltoadige' => true, + 'trentinos-tirol' => true, + 'trentinostirol' => true, + 'trentinosud-tirol' => true, + 'trentinosudtirol' => true, + 'trentinosued-tirol' => true, + 'trentinosuedtirol' => true, + 'tuscany' => true, + 'umb' => true, + 'umbria' => true, + 'val-d-aosta' => true, + 'val-daosta' => true, + 'vald-aosta' => true, + 'valdaosta' => true, + 'valle-aosta' => true, + 'valle-d-aosta' => true, + 'valle-daosta' => true, + 'valleaosta' => true, + 'valled-aosta' => true, + 'valledaosta' => true, + 'vallee-aoste' => true, + 'valleeaoste' => true, + 'vao' => true, + 'vda' => true, + 'ven' => true, + 'veneto' => true, + 'ag' => true, + 'agrigento' => true, + 'al' => true, + 'alessandria' => true, + 'alto-adige' => true, + 'altoadige' => true, + 'an' => true, + 'ancona' => true, + 'andria-barletta-trani' => true, + 'andria-trani-barletta' => true, + 'andriabarlettatrani' => true, + 'andriatranibarletta' => true, + 'ao' => true, + 'aosta' => true, + 'aoste' => true, + 'ap' => true, + 'aq' => true, + 'aquila' => true, + 'ar' => true, + 'arezzo' => true, + 'ascoli-piceno' => true, + 'ascolipiceno' => true, + 'asti' => true, + 'at' => true, + 'av' => true, + 'avellino' => true, + 'ba' => true, + 'balsan' => true, + 'bari' => true, + 'barletta-trani-andria' => true, + 'barlettatraniandria' => true, + 'belluno' => true, + 'benevento' => true, + 'bergamo' => true, + 'bg' => true, + 'bi' => true, + 'biella' => true, + 'bl' => true, + 'bn' => true, + 'bo' => true, + 'bologna' => true, + 'bolzano' => true, + 'bozen' => true, + 'br' => true, + 'brescia' => true, + 'brindisi' => true, + 'bs' => true, + 'bt' => true, + 'bz' => true, + 'ca' => true, + 'cagliari' => true, + 'caltanissetta' => true, + 'campidano-medio' => true, + 'campidanomedio' => true, + 'campobasso' => true, + 'carbonia-iglesias' => true, + 'carboniaiglesias' => true, + 'carrara-massa' => true, + 'carraramassa' => true, + 'caserta' => true, + 'catania' => true, + 'catanzaro' => true, + 'cb' => true, + 'ce' => true, + 'cesena-forli' => true, + 'cesenaforli' => true, + 'ch' => true, + 'chieti' => true, + 'ci' => true, + 'cl' => true, + 'cn' => true, + 'co' => true, + 'como' => true, + 'cosenza' => true, + 'cr' => true, + 'cremona' => true, + 'crotone' => true, + 'cs' => true, + 'ct' => true, + 'cuneo' => true, + 'cz' => true, + 'dell-ogliastra' => true, + 'dellogliastra' => true, + 'en' => true, + 'enna' => true, + 'fc' => true, + 'fe' => true, + 'fermo' => true, + 'ferrara' => true, + 'fg' => true, + 'fi' => true, + 'firenze' => true, + 'florence' => true, + 'fm' => true, + 'foggia' => true, + 'forli-cesena' => true, + 'forlicesena' => true, + 'fr' => true, + 'frosinone' => true, + 'ge' => true, + 'genoa' => true, + 'genova' => true, + 'go' => true, + 'gorizia' => true, + 'gr' => true, + 'grosseto' => true, + 'iglesias-carbonia' => true, + 'iglesiascarbonia' => true, + 'im' => true, + 'imperia' => true, + 'is' => true, + 'isernia' => true, + 'kr' => true, + 'la-spezia' => true, + 'laquila' => true, + 'laspezia' => true, + 'latina' => true, + 'lc' => true, + 'le' => true, + 'lecce' => true, + 'lecco' => true, + 'li' => true, + 'livorno' => true, + 'lo' => true, + 'lodi' => true, + 'lt' => true, + 'lu' => true, + 'lucca' => true, + 'macerata' => true, + 'mantova' => true, + 'massa-carrara' => true, + 'massacarrara' => true, + 'matera' => true, + 'mb' => true, + 'mc' => true, + 'me' => true, + 'medio-campidano' => true, + 'mediocampidano' => true, + 'messina' => true, + 'mi' => true, + 'milan' => true, + 'milano' => true, + 'mn' => true, + 'mo' => true, + 'modena' => true, + 'monza-brianza' => true, + 'monza-e-della-brianza' => true, + 'monza' => true, + 'monzabrianza' => true, + 'monzaebrianza' => true, + 'monzaedellabrianza' => true, + 'ms' => true, + 'mt' => true, + 'na' => true, + 'naples' => true, + 'napoli' => true, + 'no' => true, + 'novara' => true, + 'nu' => true, + 'nuoro' => true, + 'og' => true, + 'ogliastra' => true, + 'olbia-tempio' => true, + 'olbiatempio' => true, + 'or' => true, + 'oristano' => true, + 'ot' => true, + 'pa' => true, + 'padova' => true, + 'padua' => true, + 'palermo' => true, + 'parma' => true, + 'pavia' => true, + 'pc' => true, + 'pd' => true, + 'pe' => true, + 'perugia' => true, + 'pesaro-urbino' => true, + 'pesarourbino' => true, + 'pescara' => true, + 'pg' => true, + 'pi' => true, + 'piacenza' => true, + 'pisa' => true, + 'pistoia' => true, + 'pn' => true, + 'po' => true, + 'pordenone' => true, + 'potenza' => true, + 'pr' => true, + 'prato' => true, + 'pt' => true, + 'pu' => true, + 'pv' => true, + 'pz' => true, + 'ra' => true, + 'ragusa' => true, + 'ravenna' => true, + 'rc' => true, + 're' => true, + 'reggio-calabria' => true, + 'reggio-emilia' => true, + 'reggiocalabria' => true, + 'reggioemilia' => true, + 'rg' => true, + 'ri' => true, + 'rieti' => true, + 'rimini' => true, + 'rm' => true, + 'rn' => true, + 'ro' => true, + 'roma' => true, + 'rome' => true, + 'rovigo' => true, + 'sa' => true, + 'salerno' => true, + 'sassari' => true, + 'savona' => true, + 'si' => true, + 'siena' => true, + 'siracusa' => true, + 'so' => true, + 'sondrio' => true, + 'sp' => true, + 'sr' => true, + 'ss' => true, + 'suedtirol' => true, + 'sv' => true, + 'ta' => true, + 'taranto' => true, + 'te' => true, + 'tempio-olbia' => true, + 'tempioolbia' => true, + 'teramo' => true, + 'terni' => true, + 'tn' => true, + 'to' => true, + 'torino' => true, + 'tp' => true, + 'tr' => true, + 'trani-andria-barletta' => true, + 'trani-barletta-andria' => true, + 'traniandriabarletta' => true, + 'tranibarlettaandria' => true, + 'trapani' => true, + 'trentino' => true, + 'trento' => true, + 'treviso' => true, + 'trieste' => true, + 'ts' => true, + 'turin' => true, + 'tv' => true, + 'ud' => true, + 'udine' => true, + 'urbino-pesaro' => true, + 'urbinopesaro' => true, + 'va' => true, + 'varese' => true, + 'vb' => true, + 'vc' => true, + 've' => true, + 'venezia' => true, + 'venice' => true, + 'verbania' => true, + 'vercelli' => true, + 'verona' => true, + 'vi' => true, + 'vibo-valentia' => true, + 'vibovalentia' => true, + 'vicenza' => true, + 'viterbo' => true, + 'vr' => true, + 'vs' => true, + 'vt' => true, + 'vv' => true, + 'blogspot' => true + ), + 'je' => array( + 'co' => true, + 'net' => true, + 'org' => true + ), + 'jm' => array( + '*' => true + ), + 'jo' => array( + 'com' => true, + 'org' => true, + 'net' => true, + 'edu' => true, + 'sch' => true, + 'gov' => true, + 'mil' => true, + 'name' => true + ), + 'jobs' => true, + 'jp' => array( + 'ac' => true, + 'ad' => true, + 'co' => true, + 'ed' => true, + 'go' => true, + 'gr' => true, + 'lg' => true, + 'ne' => true, + 'or' => true, + 'aichi' => array( + 'aisai' => true, + 'ama' => true, + 'anjo' => true, + 'asuke' => true, + 'chiryu' => true, + 'chita' => true, + 'fuso' => true, + 'gamagori' => true, + 'handa' => true, + 'hazu' => true, + 'hekinan' => true, + 'higashiura' => true, + 'ichinomiya' => true, + 'inazawa' => true, + 'inuyama' => true, + 'isshiki' => true, + 'iwakura' => true, + 'kanie' => true, + 'kariya' => true, + 'kasugai' => true, + 'kira' => true, + 'kiyosu' => true, + 'komaki' => true, + 'konan' => true, + 'kota' => true, + 'mihama' => true, + 'miyoshi' => true, + 'nishio' => true, + 'nisshin' => true, + 'obu' => true, + 'oguchi' => true, + 'oharu' => true, + 'okazaki' => true, + 'owariasahi' => true, + 'seto' => true, + 'shikatsu' => true, + 'shinshiro' => true, + 'shitara' => true, + 'tahara' => true, + 'takahama' => true, + 'tobishima' => true, + 'toei' => true, + 'togo' => true, + 'tokai' => true, + 'tokoname' => true, + 'toyoake' => true, + 'toyohashi' => true, + 'toyokawa' => true, + 'toyone' => true, + 'toyota' => true, + 'tsushima' => true, + 'yatomi' => true + ), + 'akita' => array( + 'akita' => true, + 'daisen' => true, + 'fujisato' => true, + 'gojome' => true, + 'hachirogata' => true, + 'happou' => true, + 'higashinaruse' => true, + 'honjo' => true, + 'honjyo' => true, + 'ikawa' => true, + 'kamikoani' => true, + 'kamioka' => true, + 'katagami' => true, + 'kazuno' => true, + 'kitaakita' => true, + 'kosaka' => true, + 'kyowa' => true, + 'misato' => true, + 'mitane' => true, + 'moriyoshi' => true, + 'nikaho' => true, + 'noshiro' => true, + 'odate' => true, + 'oga' => true, + 'ogata' => true, + 'semboku' => true, + 'yokote' => true, + 'yurihonjo' => true + ), + 'aomori' => array( + 'aomori' => true, + 'gonohe' => true, + 'hachinohe' => true, + 'hashikami' => true, + 'hiranai' => true, + 'hirosaki' => true, + 'itayanagi' => true, + 'kuroishi' => true, + 'misawa' => true, + 'mutsu' => true, + 'nakadomari' => true, + 'noheji' => true, + 'oirase' => true, + 'owani' => true, + 'rokunohe' => true, + 'sannohe' => true, + 'shichinohe' => true, + 'shingo' => true, + 'takko' => true, + 'towada' => true, + 'tsugaru' => true, + 'tsuruta' => true + ), + 'chiba' => array( + 'abiko' => true, + 'asahi' => true, + 'chonan' => true, + 'chosei' => true, + 'choshi' => true, + 'chuo' => true, + 'funabashi' => true, + 'futtsu' => true, + 'hanamigawa' => true, + 'ichihara' => true, + 'ichikawa' => true, + 'ichinomiya' => true, + 'inzai' => true, + 'isumi' => true, + 'kamagaya' => true, + 'kamogawa' => true, + 'kashiwa' => true, + 'katori' => true, + 'katsuura' => true, + 'kimitsu' => true, + 'kisarazu' => true, + 'kozaki' => true, + 'kujukuri' => true, + 'kyonan' => true, + 'matsudo' => true, + 'midori' => true, + 'mihama' => true, + 'minamiboso' => true, + 'mobara' => true, + 'mutsuzawa' => true, + 'nagara' => true, + 'nagareyama' => true, + 'narashino' => true, + 'narita' => true, + 'noda' => true, + 'oamishirasato' => true, + 'omigawa' => true, + 'onjuku' => true, + 'otaki' => true, + 'sakae' => true, + 'sakura' => true, + 'shimofusa' => true, + 'shirako' => true, + 'shiroi' => true, + 'shisui' => true, + 'sodegaura' => true, + 'sosa' => true, + 'tako' => true, + 'tateyama' => true, + 'togane' => true, + 'tohnosho' => true, + 'tomisato' => true, + 'urayasu' => true, + 'yachimata' => true, + 'yachiyo' => true, + 'yokaichiba' => true, + 'yokoshibahikari' => true, + 'yotsukaido' => true + ), + 'ehime' => array( + 'ainan' => true, + 'honai' => true, + 'ikata' => true, + 'imabari' => true, + 'iyo' => true, + 'kamijima' => true, + 'kihoku' => true, + 'kumakogen' => true, + 'masaki' => true, + 'matsuno' => true, + 'matsuyama' => true, + 'namikata' => true, + 'niihama' => true, + 'ozu' => true, + 'saijo' => true, + 'seiyo' => true, + 'shikokuchuo' => true, + 'tobe' => true, + 'toon' => true, + 'uchiko' => true, + 'uwajima' => true, + 'yawatahama' => true + ), + 'fukui' => array( + 'echizen' => true, + 'eiheiji' => true, + 'fukui' => true, + 'ikeda' => true, + 'katsuyama' => true, + 'mihama' => true, + 'minamiechizen' => true, + 'obama' => true, + 'ohi' => true, + 'ono' => true, + 'sabae' => true, + 'sakai' => true, + 'takahama' => true, + 'tsuruga' => true, + 'wakasa' => true + ), + 'fukuoka' => array( + 'ashiya' => true, + 'buzen' => true, + 'chikugo' => true, + 'chikuho' => true, + 'chikujo' => true, + 'chikushino' => true, + 'chikuzen' => true, + 'chuo' => true, + 'dazaifu' => true, + 'fukuchi' => true, + 'hakata' => true, + 'higashi' => true, + 'hirokawa' => true, + 'hisayama' => true, + 'iizuka' => true, + 'inatsuki' => true, + 'kaho' => true, + 'kasuga' => true, + 'kasuya' => true, + 'kawara' => true, + 'keisen' => true, + 'koga' => true, + 'kurate' => true, + 'kurogi' => true, + 'kurume' => true, + 'minami' => true, + 'miyako' => true, + 'miyama' => true, + 'miyawaka' => true, + 'mizumaki' => true, + 'munakata' => true, + 'nakagawa' => true, + 'nakama' => true, + 'nishi' => true, + 'nogata' => true, + 'ogori' => true, + 'okagaki' => true, + 'okawa' => true, + 'oki' => true, + 'omuta' => true, + 'onga' => true, + 'onojo' => true, + 'oto' => true, + 'saigawa' => true, + 'sasaguri' => true, + 'shingu' => true, + 'shinyoshitomi' => true, + 'shonai' => true, + 'soeda' => true, + 'sue' => true, + 'tachiarai' => true, + 'tagawa' => true, + 'takata' => true, + 'toho' => true, + 'toyotsu' => true, + 'tsuiki' => true, + 'ukiha' => true, + 'umi' => true, + 'usui' => true, + 'yamada' => true, + 'yame' => true, + 'yanagawa' => true, + 'yukuhashi' => true + ), + 'fukushima' => array( + 'aizubange' => true, + 'aizumisato' => true, + 'aizuwakamatsu' => true, + 'asakawa' => true, + 'bandai' => true, + 'date' => true, + 'fukushima' => true, + 'furudono' => true, + 'futaba' => true, + 'hanawa' => true, + 'higashi' => true, + 'hirata' => true, + 'hirono' => true, + 'iitate' => true, + 'inawashiro' => true, + 'ishikawa' => true, + 'iwaki' => true, + 'izumizaki' => true, + 'kagamiishi' => true, + 'kaneyama' => true, + 'kawamata' => true, + 'kitakata' => true, + 'kitashiobara' => true, + 'koori' => true, + 'koriyama' => true, + 'kunimi' => true, + 'miharu' => true, + 'mishima' => true, + 'namie' => true, + 'nango' => true, + 'nishiaizu' => true, + 'nishigo' => true, + 'okuma' => true, + 'omotego' => true, + 'ono' => true, + 'otama' => true, + 'samegawa' => true, + 'shimogo' => true, + 'shirakawa' => true, + 'showa' => true, + 'soma' => true, + 'sukagawa' => true, + 'taishin' => true, + 'tamakawa' => true, + 'tanagura' => true, + 'tenei' => true, + 'yabuki' => true, + 'yamato' => true, + 'yamatsuri' => true, + 'yanaizu' => true, + 'yugawa' => true + ), + 'gifu' => array( + 'anpachi' => true, + 'ena' => true, + 'gifu' => true, + 'ginan' => true, + 'godo' => true, + 'gujo' => true, + 'hashima' => true, + 'hichiso' => true, + 'hida' => true, + 'higashishirakawa' => true, + 'ibigawa' => true, + 'ikeda' => true, + 'kakamigahara' => true, + 'kani' => true, + 'kasahara' => true, + 'kasamatsu' => true, + 'kawaue' => true, + 'kitagata' => true, + 'mino' => true, + 'minokamo' => true, + 'mitake' => true, + 'mizunami' => true, + 'motosu' => true, + 'nakatsugawa' => true, + 'ogaki' => true, + 'sakahogi' => true, + 'seki' => true, + 'sekigahara' => true, + 'shirakawa' => true, + 'tajimi' => true, + 'takayama' => true, + 'tarui' => true, + 'toki' => true, + 'tomika' => true, + 'wanouchi' => true, + 'yamagata' => true, + 'yaotsu' => true, + 'yoro' => true + ), + 'gunma' => array( + 'annaka' => true, + 'chiyoda' => true, + 'fujioka' => true, + 'higashiagatsuma' => true, + 'isesaki' => true, + 'itakura' => true, + 'kanna' => true, + 'kanra' => true, + 'katashina' => true, + 'kawaba' => true, + 'kiryu' => true, + 'kusatsu' => true, + 'maebashi' => true, + 'meiwa' => true, + 'midori' => true, + 'minakami' => true, + 'naganohara' => true, + 'nakanojo' => true, + 'nanmoku' => true, + 'numata' => true, + 'oizumi' => true, + 'ora' => true, + 'ota' => true, + 'shibukawa' => true, + 'shimonita' => true, + 'shinto' => true, + 'showa' => true, + 'takasaki' => true, + 'takayama' => true, + 'tamamura' => true, + 'tatebayashi' => true, + 'tomioka' => true, + 'tsukiyono' => true, + 'tsumagoi' => true, + 'ueno' => true, + 'yoshioka' => true + ), + 'hiroshima' => array( + 'asaminami' => true, + 'daiwa' => true, + 'etajima' => true, + 'fuchu' => true, + 'fukuyama' => true, + 'hatsukaichi' => true, + 'higashihiroshima' => true, + 'hongo' => true, + 'jinsekikogen' => true, + 'kaita' => true, + 'kui' => true, + 'kumano' => true, + 'kure' => true, + 'mihara' => true, + 'miyoshi' => true, + 'naka' => true, + 'onomichi' => true, + 'osakikamijima' => true, + 'otake' => true, + 'saka' => true, + 'sera' => true, + 'seranishi' => true, + 'shinichi' => true, + 'shobara' => true, + 'takehara' => true + ), + 'hokkaido' => array( + 'abashiri' => true, + 'abira' => true, + 'aibetsu' => true, + 'akabira' => true, + 'akkeshi' => true, + 'asahikawa' => true, + 'ashibetsu' => true, + 'ashoro' => true, + 'assabu' => true, + 'atsuma' => true, + 'bibai' => true, + 'biei' => true, + 'bifuka' => true, + 'bihoro' => true, + 'biratori' => true, + 'chippubetsu' => true, + 'chitose' => true, + 'date' => true, + 'ebetsu' => true, + 'embetsu' => true, + 'eniwa' => true, + 'erimo' => true, + 'esan' => true, + 'esashi' => true, + 'fukagawa' => true, + 'fukushima' => true, + 'furano' => true, + 'furubira' => true, + 'haboro' => true, + 'hakodate' => true, + 'hamatonbetsu' => true, + 'hidaka' => true, + 'higashikagura' => true, + 'higashikawa' => true, + 'hiroo' => true, + 'hokuryu' => true, + 'hokuto' => true, + 'honbetsu' => true, + 'horokanai' => true, + 'horonobe' => true, + 'ikeda' => true, + 'imakane' => true, + 'ishikari' => true, + 'iwamizawa' => true, + 'iwanai' => true, + 'kamifurano' => true, + 'kamikawa' => true, + 'kamishihoro' => true, + 'kamisunagawa' => true, + 'kamoenai' => true, + 'kayabe' => true, + 'kembuchi' => true, + 'kikonai' => true, + 'kimobetsu' => true, + 'kitahiroshima' => true, + 'kitami' => true, + 'kiyosato' => true, + 'koshimizu' => true, + 'kunneppu' => true, + 'kuriyama' => true, + 'kuromatsunai' => true, + 'kushiro' => true, + 'kutchan' => true, + 'kyowa' => true, + 'mashike' => true, + 'matsumae' => true, + 'mikasa' => true, + 'minamifurano' => true, + 'mombetsu' => true, + 'moseushi' => true, + 'mukawa' => true, + 'muroran' => true, + 'naie' => true, + 'nakagawa' => true, + 'nakasatsunai' => true, + 'nakatombetsu' => true, + 'nanae' => true, + 'nanporo' => true, + 'nayoro' => true, + 'nemuro' => true, + 'niikappu' => true, + 'niki' => true, + 'nishiokoppe' => true, + 'noboribetsu' => true, + 'numata' => true, + 'obihiro' => true, + 'obira' => true, + 'oketo' => true, + 'okoppe' => true, + 'otaru' => true, + 'otobe' => true, + 'otofuke' => true, + 'otoineppu' => true, + 'oumu' => true, + 'ozora' => true, + 'pippu' => true, + 'rankoshi' => true, + 'rebun' => true, + 'rikubetsu' => true, + 'rishiri' => true, + 'rishirifuji' => true, + 'saroma' => true, + 'sarufutsu' => true, + 'shakotan' => true, + 'shari' => true, + 'shibecha' => true, + 'shibetsu' => true, + 'shikabe' => true, + 'shikaoi' => true, + 'shimamaki' => true, + 'shimizu' => true, + 'shimokawa' => true, + 'shinshinotsu' => true, + 'shintoku' => true, + 'shiranuka' => true, + 'shiraoi' => true, + 'shiriuchi' => true, + 'sobetsu' => true, + 'sunagawa' => true, + 'taiki' => true, + 'takasu' => true, + 'takikawa' => true, + 'takinoue' => true, + 'teshikaga' => true, + 'tobetsu' => true, + 'tohma' => true, + 'tomakomai' => true, + 'tomari' => true, + 'toya' => true, + 'toyako' => true, + 'toyotomi' => true, + 'toyoura' => true, + 'tsubetsu' => true, + 'tsukigata' => true, + 'urakawa' => true, + 'urausu' => true, + 'uryu' => true, + 'utashinai' => true, + 'wakkanai' => true, + 'wassamu' => true, + 'yakumo' => true, + 'yoichi' => true + ), + 'hyogo' => array( + 'aioi' => true, + 'akashi' => true, + 'ako' => true, + 'amagasaki' => true, + 'aogaki' => true, + 'asago' => true, + 'ashiya' => true, + 'awaji' => true, + 'fukusaki' => true, + 'goshiki' => true, + 'harima' => true, + 'himeji' => true, + 'ichikawa' => true, + 'inagawa' => true, + 'itami' => true, + 'kakogawa' => true, + 'kamigori' => true, + 'kamikawa' => true, + 'kasai' => true, + 'kasuga' => true, + 'kawanishi' => true, + 'miki' => true, + 'minamiawaji' => true, + 'nishinomiya' => true, + 'nishiwaki' => true, + 'ono' => true, + 'sanda' => true, + 'sannan' => true, + 'sasayama' => true, + 'sayo' => true, + 'shingu' => true, + 'shinonsen' => true, + 'shiso' => true, + 'sumoto' => true, + 'taishi' => true, + 'taka' => true, + 'takarazuka' => true, + 'takasago' => true, + 'takino' => true, + 'tamba' => true, + 'tatsuno' => true, + 'toyooka' => true, + 'yabu' => true, + 'yashiro' => true, + 'yoka' => true, + 'yokawa' => true + ), + 'ibaraki' => array( + 'ami' => true, + 'asahi' => true, + 'bando' => true, + 'chikusei' => true, + 'daigo' => true, + 'fujishiro' => true, + 'hitachi' => true, + 'hitachinaka' => true, + 'hitachiomiya' => true, + 'hitachiota' => true, + 'ibaraki' => true, + 'ina' => true, + 'inashiki' => true, + 'itako' => true, + 'iwama' => true, + 'joso' => true, + 'kamisu' => true, + 'kasama' => true, + 'kashima' => true, + 'kasumigaura' => true, + 'koga' => true, + 'miho' => true, + 'mito' => true, + 'moriya' => true, + 'naka' => true, + 'namegata' => true, + 'oarai' => true, + 'ogawa' => true, + 'omitama' => true, + 'ryugasaki' => true, + 'sakai' => true, + 'sakuragawa' => true, + 'shimodate' => true, + 'shimotsuma' => true, + 'shirosato' => true, + 'sowa' => true, + 'suifu' => true, + 'takahagi' => true, + 'tamatsukuri' => true, + 'tokai' => true, + 'tomobe' => true, + 'tone' => true, + 'toride' => true, + 'tsuchiura' => true, + 'tsukuba' => true, + 'uchihara' => true, + 'ushiku' => true, + 'yachiyo' => true, + 'yamagata' => true, + 'yawara' => true, + 'yuki' => true + ), + 'ishikawa' => array( + 'anamizu' => true, + 'hakui' => true, + 'hakusan' => true, + 'kaga' => true, + 'kahoku' => true, + 'kanazawa' => true, + 'kawakita' => true, + 'komatsu' => true, + 'nakanoto' => true, + 'nanao' => true, + 'nomi' => true, + 'nonoichi' => true, + 'noto' => true, + 'shika' => true, + 'suzu' => true, + 'tsubata' => true, + 'tsurugi' => true, + 'uchinada' => true, + 'wajima' => true + ), + 'iwate' => array( + 'fudai' => true, + 'fujisawa' => true, + 'hanamaki' => true, + 'hiraizumi' => true, + 'hirono' => true, + 'ichinohe' => true, + 'ichinoseki' => true, + 'iwaizumi' => true, + 'iwate' => true, + 'joboji' => true, + 'kamaishi' => true, + 'kanegasaki' => true, + 'karumai' => true, + 'kawai' => true, + 'kitakami' => true, + 'kuji' => true, + 'kunohe' => true, + 'kuzumaki' => true, + 'miyako' => true, + 'mizusawa' => true, + 'morioka' => true, + 'ninohe' => true, + 'noda' => true, + 'ofunato' => true, + 'oshu' => true, + 'otsuchi' => true, + 'rikuzentakata' => true, + 'shiwa' => true, + 'shizukuishi' => true, + 'sumita' => true, + 'tanohata' => true, + 'tono' => true, + 'yahaba' => true, + 'yamada' => true + ), + 'kagawa' => array( + 'ayagawa' => true, + 'higashikagawa' => true, + 'kanonji' => true, + 'kotohira' => true, + 'manno' => true, + 'marugame' => true, + 'mitoyo' => true, + 'naoshima' => true, + 'sanuki' => true, + 'tadotsu' => true, + 'takamatsu' => true, + 'tonosho' => true, + 'uchinomi' => true, + 'utazu' => true, + 'zentsuji' => true + ), + 'kagoshima' => array( + 'akune' => true, + 'amami' => true, + 'hioki' => true, + 'isa' => true, + 'isen' => true, + 'izumi' => true, + 'kagoshima' => true, + 'kanoya' => true, + 'kawanabe' => true, + 'kinko' => true, + 'kouyama' => true, + 'makurazaki' => true, + 'matsumoto' => true, + 'minamitane' => true, + 'nakatane' => true, + 'nishinoomote' => true, + 'satsumasendai' => true, + 'soo' => true, + 'tarumizu' => true, + 'yusui' => true + ), + 'kanagawa' => array( + 'aikawa' => true, + 'atsugi' => true, + 'ayase' => true, + 'chigasaki' => true, + 'ebina' => true, + 'fujisawa' => true, + 'hadano' => true, + 'hakone' => true, + 'hiratsuka' => true, + 'isehara' => true, + 'kaisei' => true, + 'kamakura' => true, + 'kiyokawa' => true, + 'matsuda' => true, + 'minamiashigara' => true, + 'miura' => true, + 'nakai' => true, + 'ninomiya' => true, + 'odawara' => true, + 'oi' => true, + 'oiso' => true, + 'sagamihara' => true, + 'samukawa' => true, + 'tsukui' => true, + 'yamakita' => true, + 'yamato' => true, + 'yokosuka' => true, + 'yugawara' => true, + 'zama' => true, + 'zushi' => true + ), + 'kochi' => array( + 'aki' => true, + 'geisei' => true, + 'hidaka' => true, + 'higashitsuno' => true, + 'ino' => true, + 'kagami' => true, + 'kami' => true, + 'kitagawa' => true, + 'kochi' => true, + 'mihara' => true, + 'motoyama' => true, + 'muroto' => true, + 'nahari' => true, + 'nakamura' => true, + 'nankoku' => true, + 'nishitosa' => true, + 'niyodogawa' => true, + 'ochi' => true, + 'okawa' => true, + 'otoyo' => true, + 'otsuki' => true, + 'sakawa' => true, + 'sukumo' => true, + 'susaki' => true, + 'tosa' => true, + 'tosashimizu' => true, + 'toyo' => true, + 'tsuno' => true, + 'umaji' => true, + 'yasuda' => true, + 'yusuhara' => true + ), + 'kumamoto' => array( + 'amakusa' => true, + 'arao' => true, + 'aso' => true, + 'choyo' => true, + 'gyokuto' => true, + 'hitoyoshi' => true, + 'kamiamakusa' => true, + 'kashima' => true, + 'kikuchi' => true, + 'kosa' => true, + 'kumamoto' => true, + 'mashiki' => true, + 'mifune' => true, + 'minamata' => true, + 'minamioguni' => true, + 'nagasu' => true, + 'nishihara' => true, + 'oguni' => true, + 'ozu' => true, + 'sumoto' => true, + 'takamori' => true, + 'uki' => true, + 'uto' => true, + 'yamaga' => true, + 'yamato' => true, + 'yatsushiro' => true + ), + 'kyoto' => array( + 'ayabe' => true, + 'fukuchiyama' => true, + 'higashiyama' => true, + 'ide' => true, + 'ine' => true, + 'joyo' => true, + 'kameoka' => true, + 'kamo' => true, + 'kita' => true, + 'kizu' => true, + 'kumiyama' => true, + 'kyotamba' => true, + 'kyotanabe' => true, + 'kyotango' => true, + 'maizuru' => true, + 'minami' => true, + 'minamiyamashiro' => true, + 'miyazu' => true, + 'muko' => true, + 'nagaokakyo' => true, + 'nakagyo' => true, + 'nantan' => true, + 'oyamazaki' => true, + 'sakyo' => true, + 'seika' => true, + 'tanabe' => true, + 'uji' => true, + 'ujitawara' => true, + 'wazuka' => true, + 'yamashina' => true, + 'yawata' => true + ), + 'mie' => array( + 'asahi' => true, + 'inabe' => true, + 'ise' => true, + 'kameyama' => true, + 'kawagoe' => true, + 'kiho' => true, + 'kisosaki' => true, + 'kiwa' => true, + 'komono' => true, + 'kumano' => true, + 'kuwana' => true, + 'matsusaka' => true, + 'meiwa' => true, + 'mihama' => true, + 'minamiise' => true, + 'misugi' => true, + 'miyama' => true, + 'nabari' => true, + 'shima' => true, + 'suzuka' => true, + 'tado' => true, + 'taiki' => true, + 'taki' => true, + 'tamaki' => true, + 'toba' => true, + 'tsu' => true, + 'udono' => true, + 'ureshino' => true, + 'watarai' => true, + 'yokkaichi' => true + ), + 'miyagi' => array( + 'furukawa' => true, + 'higashimatsushima' => true, + 'ishinomaki' => true, + 'iwanuma' => true, + 'kakuda' => true, + 'kami' => true, + 'kawasaki' => true, + 'kesennuma' => true, + 'marumori' => true, + 'matsushima' => true, + 'minamisanriku' => true, + 'misato' => true, + 'murata' => true, + 'natori' => true, + 'ogawara' => true, + 'ohira' => true, + 'onagawa' => true, + 'osaki' => true, + 'rifu' => true, + 'semine' => true, + 'shibata' => true, + 'shichikashuku' => true, + 'shikama' => true, + 'shiogama' => true, + 'shiroishi' => true, + 'tagajo' => true, + 'taiwa' => true, + 'tome' => true, + 'tomiya' => true, + 'wakuya' => true, + 'watari' => true, + 'yamamoto' => true, + 'zao' => true + ), + 'miyazaki' => array( + 'aya' => true, + 'ebino' => true, + 'gokase' => true, + 'hyuga' => true, + 'kadogawa' => true, + 'kawaminami' => true, + 'kijo' => true, + 'kitagawa' => true, + 'kitakata' => true, + 'kitaura' => true, + 'kobayashi' => true, + 'kunitomi' => true, + 'kushima' => true, + 'mimata' => true, + 'miyakonojo' => true, + 'miyazaki' => true, + 'morotsuka' => true, + 'nichinan' => true, + 'nishimera' => true, + 'nobeoka' => true, + 'saito' => true, + 'shiiba' => true, + 'shintomi' => true, + 'takaharu' => true, + 'takanabe' => true, + 'takazaki' => true, + 'tsuno' => true + ), + 'nagano' => array( + 'achi' => true, + 'agematsu' => true, + 'anan' => true, + 'aoki' => true, + 'asahi' => true, + 'azumino' => true, + 'chikuhoku' => true, + 'chikuma' => true, + 'chino' => true, + 'fujimi' => true, + 'hakuba' => true, + 'hara' => true, + 'hiraya' => true, + 'iida' => true, + 'iijima' => true, + 'iiyama' => true, + 'iizuna' => true, + 'ikeda' => true, + 'ikusaka' => true, + 'ina' => true, + 'karuizawa' => true, + 'kawakami' => true, + 'kiso' => true, + 'kisofukushima' => true, + 'kitaaiki' => true, + 'komagane' => true, + 'komoro' => true, + 'matsukawa' => true, + 'matsumoto' => true, + 'miasa' => true, + 'minamiaiki' => true, + 'minamimaki' => true, + 'minamiminowa' => true, + 'minowa' => true, + 'miyada' => true, + 'miyota' => true, + 'mochizuki' => true, + 'nagano' => true, + 'nagawa' => true, + 'nagiso' => true, + 'nakagawa' => true, + 'nakano' => true, + 'nozawaonsen' => true, + 'obuse' => true, + 'ogawa' => true, + 'okaya' => true, + 'omachi' => true, + 'omi' => true, + 'ookuwa' => true, + 'ooshika' => true, + 'otaki' => true, + 'otari' => true, + 'sakae' => true, + 'sakaki' => true, + 'saku' => true, + 'sakuho' => true, + 'shimosuwa' => true, + 'shinanomachi' => true, + 'shiojiri' => true, + 'suwa' => true, + 'suzaka' => true, + 'takagi' => true, + 'takamori' => true, + 'takayama' => true, + 'tateshina' => true, + 'tatsuno' => true, + 'togakushi' => true, + 'togura' => true, + 'tomi' => true, + 'ueda' => true, + 'wada' => true, + 'yamagata' => true, + 'yamanouchi' => true, + 'yasaka' => true, + 'yasuoka' => true + ), + 'nagasaki' => array( + 'chijiwa' => true, + 'futsu' => true, + 'goto' => true, + 'hasami' => true, + 'hirado' => true, + 'iki' => true, + 'isahaya' => true, + 'kawatana' => true, + 'kuchinotsu' => true, + 'matsuura' => true, + 'nagasaki' => true, + 'obama' => true, + 'omura' => true, + 'oseto' => true, + 'saikai' => true, + 'sasebo' => true, + 'seihi' => true, + 'shimabara' => true, + 'shinkamigoto' => true, + 'togitsu' => true, + 'tsushima' => true, + 'unzen' => true + ), + 'nara' => array( + 'ando' => true, + 'gose' => true, + 'heguri' => true, + 'higashiyoshino' => true, + 'ikaruga' => true, + 'ikoma' => true, + 'kamikitayama' => true, + 'kanmaki' => true, + 'kashiba' => true, + 'kashihara' => true, + 'katsuragi' => true, + 'kawai' => true, + 'kawakami' => true, + 'kawanishi' => true, + 'koryo' => true, + 'kurotaki' => true, + 'mitsue' => true, + 'miyake' => true, + 'nara' => true, + 'nosegawa' => true, + 'oji' => true, + 'ouda' => true, + 'oyodo' => true, + 'sakurai' => true, + 'sango' => true, + 'shimoichi' => true, + 'shimokitayama' => true, + 'shinjo' => true, + 'soni' => true, + 'takatori' => true, + 'tawaramoto' => true, + 'tenkawa' => true, + 'tenri' => true, + 'uda' => true, + 'yamatokoriyama' => true, + 'yamatotakada' => true, + 'yamazoe' => true, + 'yoshino' => true + ), + 'niigata' => array( + 'aga' => true, + 'agano' => true, + 'gosen' => true, + 'itoigawa' => true, + 'izumozaki' => true, + 'joetsu' => true, + 'kamo' => true, + 'kariwa' => true, + 'kashiwazaki' => true, + 'minamiuonuma' => true, + 'mitsuke' => true, + 'muika' => true, + 'murakami' => true, + 'myoko' => true, + 'nagaoka' => true, + 'niigata' => true, + 'ojiya' => true, + 'omi' => true, + 'sado' => true, + 'sanjo' => true, + 'seiro' => true, + 'seirou' => true, + 'sekikawa' => true, + 'shibata' => true, + 'tagami' => true, + 'tainai' => true, + 'tochio' => true, + 'tokamachi' => true, + 'tsubame' => true, + 'tsunan' => true, + 'uonuma' => true, + 'yahiko' => true, + 'yoita' => true, + 'yuzawa' => true + ), + 'oita' => array( + 'beppu' => true, + 'bungoono' => true, + 'bungotakada' => true, + 'hasama' => true, + 'hiji' => true, + 'himeshima' => true, + 'hita' => true, + 'kamitsue' => true, + 'kokonoe' => true, + 'kuju' => true, + 'kunisaki' => true, + 'kusu' => true, + 'oita' => true, + 'saiki' => true, + 'taketa' => true, + 'tsukumi' => true, + 'usa' => true, + 'usuki' => true, + 'yufu' => true + ), + 'okayama' => array( + 'akaiwa' => true, + 'asakuchi' => true, + 'bizen' => true, + 'hayashima' => true, + 'ibara' => true, + 'kagamino' => true, + 'kasaoka' => true, + 'kibichuo' => true, + 'kumenan' => true, + 'kurashiki' => true, + 'maniwa' => true, + 'misaki' => true, + 'nagi' => true, + 'niimi' => true, + 'nishiawakura' => true, + 'okayama' => true, + 'satosho' => true, + 'setouchi' => true, + 'shinjo' => true, + 'shoo' => true, + 'soja' => true, + 'takahashi' => true, + 'tamano' => true, + 'tsuyama' => true, + 'wake' => true, + 'yakage' => true + ), + 'okinawa' => array( + 'aguni' => true, + 'ginowan' => true, + 'ginoza' => true, + 'gushikami' => true, + 'haebaru' => true, + 'higashi' => true, + 'hirara' => true, + 'iheya' => true, + 'ishigaki' => true, + 'ishikawa' => true, + 'itoman' => true, + 'izena' => true, + 'kadena' => true, + 'kin' => true, + 'kitadaito' => true, + 'kitanakagusuku' => true, + 'kumejima' => true, + 'kunigami' => true, + 'minamidaito' => true, + 'motobu' => true, + 'nago' => true, + 'naha' => true, + 'nakagusuku' => true, + 'nakijin' => true, + 'nanjo' => true, + 'nishihara' => true, + 'ogimi' => true, + 'okinawa' => true, + 'onna' => true, + 'shimoji' => true, + 'taketomi' => true, + 'tarama' => true, + 'tokashiki' => true, + 'tomigusuku' => true, + 'tonaki' => true, + 'urasoe' => true, + 'uruma' => true, + 'yaese' => true, + 'yomitan' => true, + 'yonabaru' => true, + 'yonaguni' => true, + 'zamami' => true + ), + 'osaka' => array( + 'abeno' => true, + 'chihayaakasaka' => true, + 'chuo' => true, + 'daito' => true, + 'fujiidera' => true, + 'habikino' => true, + 'hannan' => true, + 'higashiosaka' => true, + 'higashisumiyoshi' => true, + 'higashiyodogawa' => true, + 'hirakata' => true, + 'ibaraki' => true, + 'ikeda' => true, + 'izumi' => true, + 'izumiotsu' => true, + 'izumisano' => true, + 'kadoma' => true, + 'kaizuka' => true, + 'kanan' => true, + 'kashiwara' => true, + 'katano' => true, + 'kawachinagano' => true, + 'kishiwada' => true, + 'kita' => true, + 'kumatori' => true, + 'matsubara' => true, + 'minato' => true, + 'minoh' => true, + 'misaki' => true, + 'moriguchi' => true, + 'neyagawa' => true, + 'nishi' => true, + 'nose' => true, + 'osakasayama' => true, + 'sakai' => true, + 'sayama' => true, + 'sennan' => true, + 'settsu' => true, + 'shijonawate' => true, + 'shimamoto' => true, + 'suita' => true, + 'tadaoka' => true, + 'taishi' => true, + 'tajiri' => true, + 'takaishi' => true, + 'takatsuki' => true, + 'tondabayashi' => true, + 'toyonaka' => true, + 'toyono' => true, + 'yao' => true + ), + 'saga' => array( + 'ariake' => true, + 'arita' => true, + 'fukudomi' => true, + 'genkai' => true, + 'hamatama' => true, + 'hizen' => true, + 'imari' => true, + 'kamimine' => true, + 'kanzaki' => true, + 'karatsu' => true, + 'kashima' => true, + 'kitagata' => true, + 'kitahata' => true, + 'kiyama' => true, + 'kouhoku' => true, + 'kyuragi' => true, + 'nishiarita' => true, + 'ogi' => true, + 'omachi' => true, + 'ouchi' => true, + 'saga' => true, + 'shiroishi' => true, + 'taku' => true, + 'tara' => true, + 'tosu' => true, + 'yoshinogari' => true + ), + 'saitama' => array( + 'arakawa' => true, + 'asaka' => true, + 'chichibu' => true, + 'fujimi' => true, + 'fujimino' => true, + 'fukaya' => true, + 'hanno' => true, + 'hanyu' => true, + 'hasuda' => true, + 'hatogaya' => true, + 'hatoyama' => true, + 'hidaka' => true, + 'higashichichibu' => true, + 'higashimatsuyama' => true, + 'honjo' => true, + 'ina' => true, + 'iruma' => true, + 'iwatsuki' => true, + 'kamiizumi' => true, + 'kamikawa' => true, + 'kamisato' => true, + 'kasukabe' => true, + 'kawagoe' => true, + 'kawaguchi' => true, + 'kawajima' => true, + 'kazo' => true, + 'kitamoto' => true, + 'koshigaya' => true, + 'kounosu' => true, + 'kuki' => true, + 'kumagaya' => true, + 'matsubushi' => true, + 'minano' => true, + 'misato' => true, + 'miyashiro' => true, + 'miyoshi' => true, + 'moroyama' => true, + 'nagatoro' => true, + 'namegawa' => true, + 'niiza' => true, + 'ogano' => true, + 'ogawa' => true, + 'ogose' => true, + 'okegawa' => true, + 'omiya' => true, + 'otaki' => true, + 'ranzan' => true, + 'ryokami' => true, + 'saitama' => true, + 'sakado' => true, + 'satte' => true, + 'sayama' => true, + 'shiki' => true, + 'shiraoka' => true, + 'soka' => true, + 'sugito' => true, + 'toda' => true, + 'tokigawa' => true, + 'tokorozawa' => true, + 'tsurugashima' => true, + 'urawa' => true, + 'warabi' => true, + 'yashio' => true, + 'yokoze' => true, + 'yono' => true, + 'yorii' => true, + 'yoshida' => true, + 'yoshikawa' => true, + 'yoshimi' => true + ), + 'shiga' => array( + 'aisho' => true, + 'gamo' => true, + 'higashiomi' => true, + 'hikone' => true, + 'koka' => true, + 'konan' => true, + 'kosei' => true, + 'koto' => true, + 'kusatsu' => true, + 'maibara' => true, + 'moriyama' => true, + 'nagahama' => true, + 'nishiazai' => true, + 'notogawa' => true, + 'omihachiman' => true, + 'otsu' => true, + 'ritto' => true, + 'ryuoh' => true, + 'takashima' => true, + 'takatsuki' => true, + 'torahime' => true, + 'toyosato' => true, + 'yasu' => true + ), + 'shimane' => array( + 'akagi' => true, + 'ama' => true, + 'gotsu' => true, + 'hamada' => true, + 'higashiizumo' => true, + 'hikawa' => true, + 'hikimi' => true, + 'izumo' => true, + 'kakinoki' => true, + 'masuda' => true, + 'matsue' => true, + 'misato' => true, + 'nishinoshima' => true, + 'ohda' => true, + 'okinoshima' => true, + 'okuizumo' => true, + 'shimane' => true, + 'tamayu' => true, + 'tsuwano' => true, + 'unnan' => true, + 'yakumo' => true, + 'yasugi' => true, + 'yatsuka' => true + ), + 'shizuoka' => array( + 'arai' => true, + 'atami' => true, + 'fuji' => true, + 'fujieda' => true, + 'fujikawa' => true, + 'fujinomiya' => true, + 'fukuroi' => true, + 'gotemba' => true, + 'haibara' => true, + 'hamamatsu' => true, + 'higashiizu' => true, + 'ito' => true, + 'iwata' => true, + 'izu' => true, + 'izunokuni' => true, + 'kakegawa' => true, + 'kannami' => true, + 'kawanehon' => true, + 'kawazu' => true, + 'kikugawa' => true, + 'kosai' => true, + 'makinohara' => true, + 'matsuzaki' => true, + 'minamiizu' => true, + 'mishima' => true, + 'morimachi' => true, + 'nishiizu' => true, + 'numazu' => true, + 'omaezaki' => true, + 'shimada' => true, + 'shimizu' => true, + 'shimoda' => true, + 'shizuoka' => true, + 'susono' => true, + 'yaizu' => true, + 'yoshida' => true + ), + 'tochigi' => array( + 'ashikaga' => true, + 'bato' => true, + 'haga' => true, + 'ichikai' => true, + 'iwafune' => true, + 'kaminokawa' => true, + 'kanuma' => true, + 'karasuyama' => true, + 'kuroiso' => true, + 'mashiko' => true, + 'mibu' => true, + 'moka' => true, + 'motegi' => true, + 'nasu' => true, + 'nasushiobara' => true, + 'nikko' => true, + 'nishikata' => true, + 'nogi' => true, + 'ohira' => true, + 'ohtawara' => true, + 'oyama' => true, + 'sakura' => true, + 'sano' => true, + 'shimotsuke' => true, + 'shioya' => true, + 'takanezawa' => true, + 'tochigi' => true, + 'tsuga' => true, + 'ujiie' => true, + 'utsunomiya' => true, + 'yaita' => true + ), + 'tokushima' => array( + 'aizumi' => true, + 'anan' => true, + 'ichiba' => true, + 'itano' => true, + 'kainan' => true, + 'komatsushima' => true, + 'matsushige' => true, + 'mima' => true, + 'minami' => true, + 'miyoshi' => true, + 'mugi' => true, + 'nakagawa' => true, + 'naruto' => true, + 'sanagochi' => true, + 'shishikui' => true, + 'tokushima' => true, + 'wajiki' => true + ), + 'tokyo' => array( + 'adachi' => true, + 'akiruno' => true, + 'akishima' => true, + 'aogashima' => true, + 'arakawa' => true, + 'bunkyo' => true, + 'chiyoda' => true, + 'chofu' => true, + 'chuo' => true, + 'edogawa' => true, + 'fuchu' => true, + 'fussa' => true, + 'hachijo' => true, + 'hachioji' => true, + 'hamura' => true, + 'higashikurume' => true, + 'higashimurayama' => true, + 'higashiyamato' => true, + 'hino' => true, + 'hinode' => true, + 'hinohara' => true, + 'inagi' => true, + 'itabashi' => true, + 'katsushika' => true, + 'kita' => true, + 'kiyose' => true, + 'kodaira' => true, + 'koganei' => true, + 'kokubunji' => true, + 'komae' => true, + 'koto' => true, + 'kouzushima' => true, + 'kunitachi' => true, + 'machida' => true, + 'meguro' => true, + 'minato' => true, + 'mitaka' => true, + 'mizuho' => true, + 'musashimurayama' => true, + 'musashino' => true, + 'nakano' => true, + 'nerima' => true, + 'ogasawara' => true, + 'okutama' => true, + 'ome' => true, + 'oshima' => true, + 'ota' => true, + 'setagaya' => true, + 'shibuya' => true, + 'shinagawa' => true, + 'shinjuku' => true, + 'suginami' => true, + 'sumida' => true, + 'tachikawa' => true, + 'taito' => true, + 'tama' => true, + 'toshima' => true + ), + 'tottori' => array( + 'chizu' => true, + 'hino' => true, + 'kawahara' => true, + 'koge' => true, + 'kotoura' => true, + 'misasa' => true, + 'nanbu' => true, + 'nichinan' => true, + 'sakaiminato' => true, + 'tottori' => true, + 'wakasa' => true, + 'yazu' => true, + 'yonago' => true + ), + 'toyama' => array( + 'asahi' => true, + 'fuchu' => true, + 'fukumitsu' => true, + 'funahashi' => true, + 'himi' => true, + 'imizu' => true, + 'inami' => true, + 'johana' => true, + 'kamiichi' => true, + 'kurobe' => true, + 'nakaniikawa' => true, + 'namerikawa' => true, + 'nanto' => true, + 'nyuzen' => true, + 'oyabe' => true, + 'taira' => true, + 'takaoka' => true, + 'tateyama' => true, + 'toga' => true, + 'tonami' => true, + 'toyama' => true, + 'unazuki' => true, + 'uozu' => true, + 'yamada' => true + ), + 'wakayama' => array( + 'arida' => true, + 'aridagawa' => true, + 'gobo' => true, + 'hashimoto' => true, + 'hidaka' => true, + 'hirogawa' => true, + 'inami' => true, + 'iwade' => true, + 'kainan' => true, + 'kamitonda' => true, + 'katsuragi' => true, + 'kimino' => true, + 'kinokawa' => true, + 'kitayama' => true, + 'koya' => true, + 'koza' => true, + 'kozagawa' => true, + 'kudoyama' => true, + 'kushimoto' => true, + 'mihama' => true, + 'misato' => true, + 'nachikatsuura' => true, + 'shingu' => true, + 'shirahama' => true, + 'taiji' => true, + 'tanabe' => true, + 'wakayama' => true, + 'yuasa' => true, + 'yura' => true + ), + 'yamagata' => array( + 'asahi' => true, + 'funagata' => true, + 'higashine' => true, + 'iide' => true, + 'kahoku' => true, + 'kaminoyama' => true, + 'kaneyama' => true, + 'kawanishi' => true, + 'mamurogawa' => true, + 'mikawa' => true, + 'murayama' => true, + 'nagai' => true, + 'nakayama' => true, + 'nanyo' => true, + 'nishikawa' => true, + 'obanazawa' => true, + 'oe' => true, + 'oguni' => true, + 'ohkura' => true, + 'oishida' => true, + 'sagae' => true, + 'sakata' => true, + 'sakegawa' => true, + 'shinjo' => true, + 'shirataka' => true, + 'shonai' => true, + 'takahata' => true, + 'tendo' => true, + 'tozawa' => true, + 'tsuruoka' => true, + 'yamagata' => true, + 'yamanobe' => true, + 'yonezawa' => true, + 'yuza' => true + ), + 'yamaguchi' => array( + 'abu' => true, + 'hagi' => true, + 'hikari' => true, + 'hofu' => true, + 'iwakuni' => true, + 'kudamatsu' => true, + 'mitou' => true, + 'nagato' => true, + 'oshima' => true, + 'shimonoseki' => true, + 'shunan' => true, + 'tabuse' => true, + 'tokuyama' => true, + 'toyota' => true, + 'ube' => true, + 'yuu' => true + ), + 'yamanashi' => array( + 'chuo' => true, + 'doshi' => true, + 'fuefuki' => true, + 'fujikawa' => true, + 'fujikawaguchiko' => true, + 'fujiyoshida' => true, + 'hayakawa' => true, + 'hokuto' => true, + 'ichikawamisato' => true, + 'kai' => true, + 'kofu' => true, + 'koshu' => true, + 'kosuge' => true, + 'minami-alps' => true, + 'minobu' => true, + 'nakamichi' => true, + 'nanbu' => true, + 'narusawa' => true, + 'nirasaki' => true, + 'nishikatsura' => true, + 'oshino' => true, + 'otsuki' => true, + 'showa' => true, + 'tabayama' => true, + 'tsuru' => true, + 'uenohara' => true, + 'yamanakako' => true, + 'yamanashi' => true + ), + '栃木' => true, + '愛知' => true, + '愛媛' => true, + '兵庫' => true, + '熊本' => true, + '茨城' => true, + '北海道' => true, + '千葉' => true, + '和歌山' => true, + '長崎' => true, + '長野' => true, + '新潟' => true, + '青森' => true, + '静岡' => true, + '東京' => true, + '石川' => true, + '埼玉' => true, + '三重' => true, + '京都' => true, + '佐賀' => true, + '大分' => true, + '大阪' => true, + '奈良' => true, + '宮城' => true, + '宮崎' => true, + '富山' => true, + '山口' => true, + '山形' => true, + '山梨' => true, + '岩手' => true, + '岐阜' => true, + '岡山' => true, + '島根' => true, + '広島' => true, + '徳島' => true, + '沖縄' => true, + '滋賀' => true, + '神奈川' => true, + '福井' => true, + '福岡' => true, + '福島' => true, + '秋田' => true, + '群馬' => true, + '香川' => true, + '高知' => true, + '鳥取' => true, + '鹿児島' => true, + 'kawasaki' => array( + '*' => true, + '!city' => true + ), + 'kitakyushu' => array( + '*' => true, + '!city' => true + ), + 'kobe' => array( + '*' => true, + '!city' => true + ), + 'nagoya' => array( + '*' => true, + '!city' => true + ), + 'sapporo' => array( + '*' => true, + '!city' => true + ), + 'sendai' => array( + '*' => true, + '!city' => true + ), + 'yokohama' => array( + '*' => true, + '!city' => true + ), + 'blogspot' => true + ), + 'ke' => array( + '*' => true, + 'co' => array( + 'blogspot' => true + ) + ), + 'kg' => array( + 'org' => true, + 'net' => true, + 'com' => true, + 'edu' => true, + 'gov' => true, + 'mil' => true + ), + 'kh' => array( + '*' => true + ), + 'ki' => array( + 'edu' => true, + 'biz' => true, + 'net' => true, + 'org' => true, + 'gov' => true, + 'info' => true, + 'com' => true + ), + 'km' => array( + 'org' => true, + 'nom' => true, + 'gov' => true, + 'prd' => true, + 'tm' => true, + 'edu' => true, + 'mil' => true, + 'ass' => true, + 'com' => true, + 'coop' => true, + 'asso' => true, + 'presse' => true, + 'medecin' => true, + 'notaires' => true, + 'pharmaciens' => true, + 'veterinaire' => true, + 'gouv' => true + ), + 'kn' => array( + 'net' => true, + 'org' => true, + 'edu' => true, + 'gov' => true + ), + 'kp' => array( + 'com' => true, + 'edu' => true, + 'gov' => true, + 'org' => true, + 'rep' => true, + 'tra' => true + ), + 'kr' => array( + 'ac' => true, + 'co' => true, + 'es' => true, + 'go' => true, + 'hs' => true, + 'kg' => true, + 'mil' => true, + 'ms' => true, + 'ne' => true, + 'or' => true, + 'pe' => true, + 're' => true, + 'sc' => true, + 'busan' => true, + 'chungbuk' => true, + 'chungnam' => true, + 'daegu' => true, + 'daejeon' => true, + 'gangwon' => true, + 'gwangju' => true, + 'gyeongbuk' => true, + 'gyeonggi' => true, + 'gyeongnam' => true, + 'incheon' => true, + 'jeju' => true, + 'jeonbuk' => true, + 'jeonnam' => true, + 'seoul' => true, + 'ulsan' => true, + 'blogspot' => true + ), + 'kw' => array( + '*' => true + ), + 'ky' => array( + 'edu' => true, + 'gov' => true, + 'com' => true, + 'org' => true, + 'net' => true + ), + 'kz' => array( + 'org' => true, + 'edu' => true, + 'net' => true, + 'gov' => true, + 'mil' => true, + 'com' => true + ), + 'la' => array( + 'int' => true, + 'net' => true, + 'info' => true, + 'edu' => true, + 'gov' => true, + 'per' => true, + 'com' => true, + 'org' => true, + 'c' => true + ), + 'lb' => array( + 'com' => true, + 'edu' => true, + 'gov' => true, + 'net' => true, + 'org' => true + ), + 'lc' => array( + 'com' => true, + 'net' => true, + 'co' => true, + 'org' => true, + 'edu' => true, + 'gov' => true + ), + 'li' => array( + 'blogspot' => true + ), + 'lk' => array( + 'gov' => true, + 'sch' => true, + 'net' => true, + 'int' => true, + 'com' => true, + 'org' => true, + 'edu' => true, + 'ngo' => true, + 'soc' => true, + 'web' => true, + 'ltd' => true, + 'assn' => true, + 'grp' => true, + 'hotel' => true, + 'ac' => true + ), + 'lr' => array( + 'com' => true, + 'edu' => true, + 'gov' => true, + 'org' => true, + 'net' => true + ), + 'ls' => array( + 'co' => true, + 'org' => true + ), + 'lt' => array( + 'gov' => true, + 'blogspot' => true + ), + 'lu' => array( + 'blogspot' => true + ), + 'lv' => array( + 'com' => true, + 'edu' => true, + 'gov' => true, + 'org' => true, + 'mil' => true, + 'id' => true, + 'net' => true, + 'asn' => true, + 'conf' => true + ), + 'ly' => array( + 'com' => true, + 'net' => true, + 'gov' => true, + 'plc' => true, + 'edu' => true, + 'sch' => true, + 'med' => true, + 'org' => true, + 'id' => true + ), + 'ma' => array( + 'co' => true, + 'net' => true, + 'gov' => true, + 'org' => true, + 'ac' => true, + 'press' => true + ), + 'mc' => array( + 'tm' => true, + 'asso' => true + ), + 'md' => array( + 'blogspot' => true + ), + 'me' => array( + 'co' => true, + 'net' => true, + 'org' => true, + 'edu' => true, + 'ac' => true, + 'gov' => true, + 'its' => true, + 'priv' => true, + 'diskstation' => true, + 'dscloud' => true, + 'i234' => true, + 'myds' => true, + 'synology' => true + ), + 'mg' => array( + 'org' => true, + 'nom' => true, + 'gov' => true, + 'prd' => true, + 'tm' => true, + 'edu' => true, + 'mil' => true, + 'com' => true, + 'co' => true + ), + 'mh' => true, + 'mil' => true, + 'mk' => array( + 'com' => true, + 'org' => true, + 'net' => true, + 'edu' => true, + 'gov' => true, + 'inf' => true, + 'name' => true, + 'blogspot' => true + ), + 'ml' => array( + 'com' => true, + 'edu' => true, + 'gouv' => true, + 'gov' => true, + 'net' => true, + 'org' => true, + 'presse' => true + ), + 'mm' => array( + '*' => true + ), + 'mn' => array( + 'gov' => true, + 'edu' => true, + 'org' => true, + 'nyc' => true + ), + 'mo' => array( + 'com' => true, + 'net' => true, + 'org' => true, + 'edu' => true, + 'gov' => true + ), + 'mobi' => array( + 'dscloud' => true + ), + 'mp' => true, + 'mq' => true, + 'mr' => array( + 'gov' => true, + 'blogspot' => true + ), + 'ms' => array( + 'com' => true, + 'edu' => true, + 'gov' => true, + 'net' => true, + 'org' => true + ), + 'mt' => array( + 'com' => array( + 'blogspot' => true + ), + 'edu' => true, + 'net' => true, + 'org' => true + ), + 'mu' => array( + 'com' => true, + 'net' => true, + 'org' => true, + 'gov' => true, + 'ac' => true, + 'co' => true, + 'or' => true + ), + 'museum' => array( + 'academy' => true, + 'agriculture' => true, + 'air' => true, + 'airguard' => true, + 'alabama' => true, + 'alaska' => true, + 'amber' => true, + 'ambulance' => true, + 'american' => true, + 'americana' => true, + 'americanantiques' => true, + 'americanart' => true, + 'amsterdam' => true, + 'and' => true, + 'annefrank' => true, + 'anthro' => true, + 'anthropology' => true, + 'antiques' => true, + 'aquarium' => true, + 'arboretum' => true, + 'archaeological' => true, + 'archaeology' => true, + 'architecture' => true, + 'art' => true, + 'artanddesign' => true, + 'artcenter' => true, + 'artdeco' => true, + 'arteducation' => true, + 'artgallery' => true, + 'arts' => true, + 'artsandcrafts' => true, + 'asmatart' => true, + 'assassination' => true, + 'assisi' => true, + 'association' => true, + 'astronomy' => true, + 'atlanta' => true, + 'austin' => true, + 'australia' => true, + 'automotive' => true, + 'aviation' => true, + 'axis' => true, + 'badajoz' => true, + 'baghdad' => true, + 'bahn' => true, + 'bale' => true, + 'baltimore' => true, + 'barcelona' => true, + 'baseball' => true, + 'basel' => true, + 'baths' => true, + 'bauern' => true, + 'beauxarts' => true, + 'beeldengeluid' => true, + 'bellevue' => true, + 'bergbau' => true, + 'berkeley' => true, + 'berlin' => true, + 'bern' => true, + 'bible' => true, + 'bilbao' => true, + 'bill' => true, + 'birdart' => true, + 'birthplace' => true, + 'bonn' => true, + 'boston' => true, + 'botanical' => true, + 'botanicalgarden' => true, + 'botanicgarden' => true, + 'botany' => true, + 'brandywinevalley' => true, + 'brasil' => true, + 'bristol' => true, + 'british' => true, + 'britishcolumbia' => true, + 'broadcast' => true, + 'brunel' => true, + 'brussel' => true, + 'brussels' => true, + 'bruxelles' => true, + 'building' => true, + 'burghof' => true, + 'bus' => true, + 'bushey' => true, + 'cadaques' => true, + 'california' => true, + 'cambridge' => true, + 'can' => true, + 'canada' => true, + 'capebreton' => true, + 'carrier' => true, + 'cartoonart' => true, + 'casadelamoneda' => true, + 'castle' => true, + 'castres' => true, + 'celtic' => true, + 'center' => true, + 'chattanooga' => true, + 'cheltenham' => true, + 'chesapeakebay' => true, + 'chicago' => true, + 'children' => true, + 'childrens' => true, + 'childrensgarden' => true, + 'chiropractic' => true, + 'chocolate' => true, + 'christiansburg' => true, + 'cincinnati' => true, + 'cinema' => true, + 'circus' => true, + 'civilisation' => true, + 'civilization' => true, + 'civilwar' => true, + 'clinton' => true, + 'clock' => true, + 'coal' => true, + 'coastaldefence' => true, + 'cody' => true, + 'coldwar' => true, + 'collection' => true, + 'colonialwilliamsburg' => true, + 'coloradoplateau' => true, + 'columbia' => true, + 'columbus' => true, + 'communication' => true, + 'communications' => true, + 'community' => true, + 'computer' => true, + 'computerhistory' => true, + 'comunicações' => true, + 'contemporary' => true, + 'contemporaryart' => true, + 'convent' => true, + 'copenhagen' => true, + 'corporation' => true, + 'correios-e-telecomunicações' => true, + 'corvette' => true, + 'costume' => true, + 'countryestate' => true, + 'county' => true, + 'crafts' => true, + 'cranbrook' => true, + 'creation' => true, + 'cultural' => true, + 'culturalcenter' => true, + 'culture' => true, + 'cyber' => true, + 'cymru' => true, + 'dali' => true, + 'dallas' => true, + 'database' => true, + 'ddr' => true, + 'decorativearts' => true, + 'delaware' => true, + 'delmenhorst' => true, + 'denmark' => true, + 'depot' => true, + 'design' => true, + 'detroit' => true, + 'dinosaur' => true, + 'discovery' => true, + 'dolls' => true, + 'donostia' => true, + 'durham' => true, + 'eastafrica' => true, + 'eastcoast' => true, + 'education' => true, + 'educational' => true, + 'egyptian' => true, + 'eisenbahn' => true, + 'elburg' => true, + 'elvendrell' => true, + 'embroidery' => true, + 'encyclopedic' => true, + 'england' => true, + 'entomology' => true, + 'environment' => true, + 'environmentalconservation' => true, + 'epilepsy' => true, + 'essex' => true, + 'estate' => true, + 'ethnology' => true, + 'exeter' => true, + 'exhibition' => true, + 'family' => true, + 'farm' => true, + 'farmequipment' => true, + 'farmers' => true, + 'farmstead' => true, + 'field' => true, + 'figueres' => true, + 'filatelia' => true, + 'film' => true, + 'fineart' => true, + 'finearts' => true, + 'finland' => true, + 'flanders' => true, + 'florida' => true, + 'force' => true, + 'fortmissoula' => true, + 'fortworth' => true, + 'foundation' => true, + 'francaise' => true, + 'frankfurt' => true, + 'franziskaner' => true, + 'freemasonry' => true, + 'freiburg' => true, + 'fribourg' => true, + 'frog' => true, + 'fundacio' => true, + 'furniture' => true, + 'gallery' => true, + 'garden' => true, + 'gateway' => true, + 'geelvinck' => true, + 'gemological' => true, + 'geology' => true, + 'georgia' => true, + 'giessen' => true, + 'glas' => true, + 'glass' => true, + 'gorge' => true, + 'grandrapids' => true, + 'graz' => true, + 'guernsey' => true, + 'halloffame' => true, + 'hamburg' => true, + 'handson' => true, + 'harvestcelebration' => true, + 'hawaii' => true, + 'health' => true, + 'heimatunduhren' => true, + 'hellas' => true, + 'helsinki' => true, + 'hembygdsforbund' => true, + 'heritage' => true, + 'histoire' => true, + 'historical' => true, + 'historicalsociety' => true, + 'historichouses' => true, + 'historisch' => true, + 'historisches' => true, + 'history' => true, + 'historyofscience' => true, + 'horology' => true, + 'house' => true, + 'humanities' => true, + 'illustration' => true, + 'imageandsound' => true, + 'indian' => true, + 'indiana' => true, + 'indianapolis' => true, + 'indianmarket' => true, + 'intelligence' => true, + 'interactive' => true, + 'iraq' => true, + 'iron' => true, + 'isleofman' => true, + 'jamison' => true, + 'jefferson' => true, + 'jerusalem' => true, + 'jewelry' => true, + 'jewish' => true, + 'jewishart' => true, + 'jfk' => true, + 'journalism' => true, + 'judaica' => true, + 'judygarland' => true, + 'juedisches' => true, + 'juif' => true, + 'karate' => true, + 'karikatur' => true, + 'kids' => true, + 'koebenhavn' => true, + 'koeln' => true, + 'kunst' => true, + 'kunstsammlung' => true, + 'kunstunddesign' => true, + 'labor' => true, + 'labour' => true, + 'lajolla' => true, + 'lancashire' => true, + 'landes' => true, + 'lans' => true, + 'läns' => true, + 'larsson' => true, + 'lewismiller' => true, + 'lincoln' => true, + 'linz' => true, + 'living' => true, + 'livinghistory' => true, + 'localhistory' => true, + 'london' => true, + 'losangeles' => true, + 'louvre' => true, + 'loyalist' => true, + 'lucerne' => true, + 'luxembourg' => true, + 'luzern' => true, + 'mad' => true, + 'madrid' => true, + 'mallorca' => true, + 'manchester' => true, + 'mansion' => true, + 'mansions' => true, + 'manx' => true, + 'marburg' => true, + 'maritime' => true, + 'maritimo' => true, + 'maryland' => true, + 'marylhurst' => true, + 'media' => true, + 'medical' => true, + 'medizinhistorisches' => true, + 'meeres' => true, + 'memorial' => true, + 'mesaverde' => true, + 'michigan' => true, + 'midatlantic' => true, + 'military' => true, + 'mill' => true, + 'miners' => true, + 'mining' => true, + 'minnesota' => true, + 'missile' => true, + 'missoula' => true, + 'modern' => true, + 'moma' => true, + 'money' => true, + 'monmouth' => true, + 'monticello' => true, + 'montreal' => true, + 'moscow' => true, + 'motorcycle' => true, + 'muenchen' => true, + 'muenster' => true, + 'mulhouse' => true, + 'muncie' => true, + 'museet' => true, + 'museumcenter' => true, + 'museumvereniging' => true, + 'music' => true, + 'national' => true, + 'nationalfirearms' => true, + 'nationalheritage' => true, + 'nativeamerican' => true, + 'naturalhistory' => true, + 'naturalhistorymuseum' => true, + 'naturalsciences' => true, + 'nature' => true, + 'naturhistorisches' => true, + 'natuurwetenschappen' => true, + 'naumburg' => true, + 'naval' => true, + 'nebraska' => true, + 'neues' => true, + 'newhampshire' => true, + 'newjersey' => true, + 'newmexico' => true, + 'newport' => true, + 'newspaper' => true, + 'newyork' => true, + 'niepce' => true, + 'norfolk' => true, + 'north' => true, + 'nrw' => true, + 'nuernberg' => true, + 'nuremberg' => true, + 'nyc' => true, + 'nyny' => true, + 'oceanographic' => true, + 'oceanographique' => true, + 'omaha' => true, + 'online' => true, + 'ontario' => true, + 'openair' => true, + 'oregon' => true, + 'oregontrail' => true, + 'otago' => true, + 'oxford' => true, + 'pacific' => true, + 'paderborn' => true, + 'palace' => true, + 'paleo' => true, + 'palmsprings' => true, + 'panama' => true, + 'paris' => true, + 'pasadena' => true, + 'pharmacy' => true, + 'philadelphia' => true, + 'philadelphiaarea' => true, + 'philately' => true, + 'phoenix' => true, + 'photography' => true, + 'pilots' => true, + 'pittsburgh' => true, + 'planetarium' => true, + 'plantation' => true, + 'plants' => true, + 'plaza' => true, + 'portal' => true, + 'portland' => true, + 'portlligat' => true, + 'posts-and-telecommunications' => true, + 'preservation' => true, + 'presidio' => true, + 'press' => true, + 'project' => true, + 'public' => true, + 'pubol' => true, + 'quebec' => true, + 'railroad' => true, + 'railway' => true, + 'research' => true, + 'resistance' => true, + 'riodejaneiro' => true, + 'rochester' => true, + 'rockart' => true, + 'roma' => true, + 'russia' => true, + 'saintlouis' => true, + 'salem' => true, + 'salvadordali' => true, + 'salzburg' => true, + 'sandiego' => true, + 'sanfrancisco' => true, + 'santabarbara' => true, + 'santacruz' => true, + 'santafe' => true, + 'saskatchewan' => true, + 'satx' => true, + 'savannahga' => true, + 'schlesisches' => true, + 'schoenbrunn' => true, + 'schokoladen' => true, + 'school' => true, + 'schweiz' => true, + 'science' => true, + 'scienceandhistory' => true, + 'scienceandindustry' => true, + 'sciencecenter' => true, + 'sciencecenters' => true, + 'science-fiction' => true, + 'sciencehistory' => true, + 'sciences' => true, + 'sciencesnaturelles' => true, + 'scotland' => true, + 'seaport' => true, + 'settlement' => true, + 'settlers' => true, + 'shell' => true, + 'sherbrooke' => true, + 'sibenik' => true, + 'silk' => true, + 'ski' => true, + 'skole' => true, + 'society' => true, + 'sologne' => true, + 'soundandvision' => true, + 'southcarolina' => true, + 'southwest' => true, + 'space' => true, + 'spy' => true, + 'square' => true, + 'stadt' => true, + 'stalbans' => true, + 'starnberg' => true, + 'state' => true, + 'stateofdelaware' => true, + 'station' => true, + 'steam' => true, + 'steiermark' => true, + 'stjohn' => true, + 'stockholm' => true, + 'stpetersburg' => true, + 'stuttgart' => true, + 'suisse' => true, + 'surgeonshall' => true, + 'surrey' => true, + 'svizzera' => true, + 'sweden' => true, + 'sydney' => true, + 'tank' => true, + 'tcm' => true, + 'technology' => true, + 'telekommunikation' => true, + 'television' => true, + 'texas' => true, + 'textile' => true, + 'theater' => true, + 'time' => true, + 'timekeeping' => true, + 'topology' => true, + 'torino' => true, + 'touch' => true, + 'town' => true, + 'transport' => true, + 'tree' => true, + 'trolley' => true, + 'trust' => true, + 'trustee' => true, + 'uhren' => true, + 'ulm' => true, + 'undersea' => true, + 'university' => true, + 'usa' => true, + 'usantiques' => true, + 'usarts' => true, + 'uscountryestate' => true, + 'usculture' => true, + 'usdecorativearts' => true, + 'usgarden' => true, + 'ushistory' => true, + 'ushuaia' => true, + 'uslivinghistory' => true, + 'utah' => true, + 'uvic' => true, + 'valley' => true, + 'vantaa' => true, + 'versailles' => true, + 'viking' => true, + 'village' => true, + 'virginia' => true, + 'virtual' => true, + 'virtuel' => true, + 'vlaanderen' => true, + 'volkenkunde' => true, + 'wales' => true, + 'wallonie' => true, + 'war' => true, + 'washingtondc' => true, + 'watchandclock' => true, + 'watch-and-clock' => true, + 'western' => true, + 'westfalen' => true, + 'whaling' => true, + 'wildlife' => true, + 'williamsburg' => true, + 'windmill' => true, + 'workshop' => true, + 'york' => true, + 'yorkshire' => true, + 'yosemite' => true, + 'youth' => true, + 'zoological' => true, + 'zoology' => true, + 'ירושלים' => true, + 'иком' => true + ), + 'mv' => array( + 'aero' => true, + 'biz' => true, + 'com' => true, + 'coop' => true, + 'edu' => true, + 'gov' => true, + 'info' => true, + 'int' => true, + 'mil' => true, + 'museum' => true, + 'name' => true, + 'net' => true, + 'org' => true, + 'pro' => true + ), + 'mw' => array( + 'ac' => true, + 'biz' => true, + 'co' => true, + 'com' => true, + 'coop' => true, + 'edu' => true, + 'gov' => true, + 'int' => true, + 'museum' => true, + 'net' => true, + 'org' => true + ), + 'mx' => array( + 'com' => true, + 'org' => true, + 'gob' => true, + 'edu' => true, + 'net' => true, + 'blogspot' => true + ), + 'my' => array( + 'com' => true, + 'net' => true, + 'org' => true, + 'gov' => true, + 'edu' => true, + 'mil' => true, + 'name' => true, + 'blogspot' => true + ), + 'mz' => array( + '*' => true, + '!teledata' => true + ), + 'na' => array( + 'info' => true, + 'pro' => true, + 'name' => true, + 'school' => true, + 'or' => true, + 'dr' => true, + 'us' => true, + 'mx' => true, + 'ca' => true, + 'in' => true, + 'cc' => true, + 'tv' => true, + 'ws' => true, + 'mobi' => true, + 'co' => true, + 'com' => true, + 'org' => true + ), + 'name' => array( + 'her' => array( + 'forgot' => true + ), + 'his' => array( + 'forgot' => true + ) + ), + 'nc' => array( + 'asso' => true + ), + 'ne' => true, + 'net' => array( + 'cloudfront' => true, + 'gb' => true, + 'hu' => true, + 'jp' => true, + 'se' => true, + 'uk' => true, + 'in' => true, + 'cdn77-ssl' => true, + 'cdn77' => array( + 'r' => true + ), + 'at-band-camp' => true, + 'blogdns' => true, + 'broke-it' => true, + 'buyshouses' => true, + 'dnsalias' => true, + 'dnsdojo' => true, + 'does-it' => true, + 'dontexist' => true, + 'dynalias' => true, + 'dynathome' => true, + 'endofinternet' => true, + 'from-az' => true, + 'from-co' => true, + 'from-la' => true, + 'from-ny' => true, + 'gets-it' => true, + 'ham-radio-op' => true, + 'homeftp' => true, + 'homeip' => true, + 'homelinux' => true, + 'homeunix' => true, + 'in-the-band' => true, + 'is-a-chef' => true, + 'is-a-geek' => true, + 'isa-geek' => true, + 'kicks-ass' => true, + 'office-on-the' => true, + 'podzone' => true, + 'scrapper-site' => true, + 'selfip' => true, + 'sells-it' => true, + 'servebbs' => true, + 'serveftp' => true, + 'thruhere' => true, + 'webhop' => true, + 'fastly' => array( + 'ssl' => array( + 'a' => true, + 'b' => true, + 'global' => true + ), + 'prod' => array( + 'a' => true, + 'global' => true + ) + ), + 'cloudfunctions' => true, + 'azurewebsites' => true, + 'azure-mobile' => true, + 'cloudapp' => true, + 'rackmaze' => true, + 'dsmynas' => true, + 'familyds' => true, + 'za' => true + ), + 'nf' => array( + 'com' => true, + 'net' => true, + 'per' => true, + 'rec' => true, + 'web' => true, + 'arts' => true, + 'firm' => true, + 'info' => true, + 'other' => true, + 'store' => true + ), + 'ng' => array( + 'com' => array( + 'blogspot' => true + ), + 'edu' => true, + 'gov' => true, + 'i' => true, + 'mil' => true, + 'mobi' => true, + 'name' => true, + 'net' => true, + 'org' => true, + 'sch' => true + ), + 'ni' => array( + 'com' => true, + 'gob' => true, + 'edu' => true, + 'org' => true, + 'nom' => true, + 'net' => true, + 'mil' => true, + 'co' => true, + 'biz' => true, + 'web' => true, + 'int' => true, + 'ac' => true, + 'in' => true, + 'info' => true + ), + 'nl' => array( + 'bv' => true, + 'co' => true, + 'blogspot' => true + ), + 'no' => array( + 'fhs' => true, + 'vgs' => true, + 'fylkesbibl' => true, + 'folkebibl' => true, + 'museum' => true, + 'idrett' => true, + 'priv' => true, + 'mil' => true, + 'stat' => true, + 'dep' => true, + 'kommune' => true, + 'herad' => true, + 'aa' => array( + 'gs' => true + ), + 'ah' => array( + 'gs' => true + ), + 'bu' => array( + 'gs' => true + ), + 'fm' => array( + 'gs' => true + ), + 'hl' => array( + 'gs' => true + ), + 'hm' => array( + 'gs' => true + ), + 'jan-mayen' => array( + 'gs' => true + ), + 'mr' => array( + 'gs' => true + ), + 'nl' => array( + 'gs' => true + ), + 'nt' => array( + 'gs' => true + ), + 'of' => array( + 'gs' => true + ), + 'ol' => array( + 'gs' => true + ), + 'oslo' => array( + 'gs' => true + ), + 'rl' => array( + 'gs' => true + ), + 'sf' => array( + 'gs' => true + ), + 'st' => array( + 'gs' => true + ), + 'svalbard' => array( + 'gs' => true + ), + 'tm' => array( + 'gs' => true + ), + 'tr' => array( + 'gs' => true + ), + 'va' => array( + 'gs' => true + ), + 'vf' => array( + 'gs' => true + ), + 'akrehamn' => true, + 'åkrehamn' => true, + 'algard' => true, + 'ålgård' => true, + 'arna' => true, + 'brumunddal' => true, + 'bryne' => true, + 'bronnoysund' => true, + 'brønnøysund' => true, + 'drobak' => true, + 'drøbak' => true, + 'egersund' => true, + 'fetsund' => true, + 'floro' => true, + 'florø' => true, + 'fredrikstad' => true, + 'hokksund' => true, + 'honefoss' => true, + 'hønefoss' => true, + 'jessheim' => true, + 'jorpeland' => true, + 'jørpeland' => true, + 'kirkenes' => true, + 'kopervik' => true, + 'krokstadelva' => true, + 'langevag' => true, + 'langevåg' => true, + 'leirvik' => true, + 'mjondalen' => true, + 'mjøndalen' => true, + 'mo-i-rana' => true, + 'mosjoen' => true, + 'mosjøen' => true, + 'nesoddtangen' => true, + 'orkanger' => true, + 'osoyro' => true, + 'osøyro' => true, + 'raholt' => true, + 'råholt' => true, + 'sandnessjoen' => true, + 'sandnessjøen' => true, + 'skedsmokorset' => true, + 'slattum' => true, + 'spjelkavik' => true, + 'stathelle' => true, + 'stavern' => true, + 'stjordalshalsen' => true, + 'stjørdalshalsen' => true, + 'tananger' => true, + 'tranby' => true, + 'vossevangen' => true, + 'afjord' => true, + 'åfjord' => true, + 'agdenes' => true, + 'al' => true, + 'ål' => true, + 'alesund' => true, + 'ålesund' => true, + 'alstahaug' => true, + 'alta' => true, + 'áltá' => true, + 'alaheadju' => true, + 'álaheadju' => true, + 'alvdal' => true, + 'amli' => true, + 'åmli' => true, + 'amot' => true, + 'åmot' => true, + 'andebu' => true, + 'andoy' => true, + 'andøy' => true, + 'andasuolo' => true, + 'ardal' => true, + 'årdal' => true, + 'aremark' => true, + 'arendal' => true, + 'ås' => true, + 'aseral' => true, + 'åseral' => true, + 'asker' => true, + 'askim' => true, + 'askvoll' => true, + 'askoy' => true, + 'askøy' => true, + 'asnes' => true, + 'åsnes' => true, + 'audnedaln' => true, + 'aukra' => true, + 'aure' => true, + 'aurland' => true, + 'aurskog-holand' => true, + 'aurskog-høland' => true, + 'austevoll' => true, + 'austrheim' => true, + 'averoy' => true, + 'averøy' => true, + 'balestrand' => true, + 'ballangen' => true, + 'balat' => true, + 'bálát' => true, + 'balsfjord' => true, + 'bahccavuotna' => true, + 'báhccavuotna' => true, + 'bamble' => true, + 'bardu' => true, + 'beardu' => true, + 'beiarn' => true, + 'bajddar' => true, + 'bájddar' => true, + 'baidar' => true, + 'báidár' => true, + 'berg' => true, + 'bergen' => true, + 'berlevag' => true, + 'berlevåg' => true, + 'bearalvahki' => true, + 'bearalváhki' => true, + 'bindal' => true, + 'birkenes' => true, + 'bjarkoy' => true, + 'bjarkøy' => true, + 'bjerkreim' => true, + 'bjugn' => true, + 'bodo' => true, + 'bodø' => true, + 'badaddja' => true, + 'bådåddjå' => true, + 'budejju' => true, + 'bokn' => true, + 'bremanger' => true, + 'bronnoy' => true, + 'brønnøy' => true, + 'bygland' => true, + 'bykle' => true, + 'barum' => true, + 'bærum' => true, + 'telemark' => array( + 'bo' => true, + 'bø' => true + ), + 'nordland' => array( + 'bo' => true, + 'bø' => true, + 'heroy' => true, + 'herøy' => true + ), + 'bievat' => true, + 'bievát' => true, + 'bomlo' => true, + 'bømlo' => true, + 'batsfjord' => true, + 'båtsfjord' => true, + 'bahcavuotna' => true, + 'báhcavuotna' => true, + 'dovre' => true, + 'drammen' => true, + 'drangedal' => true, + 'dyroy' => true, + 'dyrøy' => true, + 'donna' => true, + 'dønna' => true, + 'eid' => true, + 'eidfjord' => true, + 'eidsberg' => true, + 'eidskog' => true, + 'eidsvoll' => true, + 'eigersund' => true, + 'elverum' => true, + 'enebakk' => true, + 'engerdal' => true, + 'etne' => true, + 'etnedal' => true, + 'evenes' => true, + 'evenassi' => true, + 'evenášši' => true, + 'evje-og-hornnes' => true, + 'farsund' => true, + 'fauske' => true, + 'fuossko' => true, + 'fuoisku' => true, + 'fedje' => true, + 'fet' => true, + 'finnoy' => true, + 'finnøy' => true, + 'fitjar' => true, + 'fjaler' => true, + 'fjell' => true, + 'flakstad' => true, + 'flatanger' => true, + 'flekkefjord' => true, + 'flesberg' => true, + 'flora' => true, + 'fla' => true, + 'flå' => true, + 'folldal' => true, + 'forsand' => true, + 'fosnes' => true, + 'frei' => true, + 'frogn' => true, + 'froland' => true, + 'frosta' => true, + 'frana' => true, + 'fræna' => true, + 'froya' => true, + 'frøya' => true, + 'fusa' => true, + 'fyresdal' => true, + 'forde' => true, + 'førde' => true, + 'gamvik' => true, + 'gangaviika' => true, + 'gáŋgaviika' => true, + 'gaular' => true, + 'gausdal' => true, + 'gildeskal' => true, + 'gildeskål' => true, + 'giske' => true, + 'gjemnes' => true, + 'gjerdrum' => true, + 'gjerstad' => true, + 'gjesdal' => true, + 'gjovik' => true, + 'gjøvik' => true, + 'gloppen' => true, + 'gol' => true, + 'gran' => true, + 'grane' => true, + 'granvin' => true, + 'gratangen' => true, + 'grimstad' => true, + 'grong' => true, + 'kraanghke' => true, + 'kråanghke' => true, + 'grue' => true, + 'gulen' => true, + 'hadsel' => true, + 'halden' => true, + 'halsa' => true, + 'hamar' => true, + 'hamaroy' => true, + 'habmer' => true, + 'hábmer' => true, + 'hapmir' => true, + 'hápmir' => true, + 'hammerfest' => true, + 'hammarfeasta' => true, + 'hámmárfeasta' => true, + 'haram' => true, + 'hareid' => true, + 'harstad' => true, + 'hasvik' => true, + 'aknoluokta' => true, + 'ákŋoluokta' => true, + 'hattfjelldal' => true, + 'aarborte' => true, + 'haugesund' => true, + 'hemne' => true, + 'hemnes' => true, + 'hemsedal' => true, + 'more-og-romsdal' => array( + 'heroy' => true, + 'sande' => true + ), + 'møre-og-romsdal' => array( + 'herøy' => true, + 'sande' => true + ), + 'hitra' => true, + 'hjartdal' => true, + 'hjelmeland' => true, + 'hobol' => true, + 'hobøl' => true, + 'hof' => true, + 'hol' => true, + 'hole' => true, + 'holmestrand' => true, + 'holtalen' => true, + 'holtålen' => true, + 'hornindal' => true, + 'horten' => true, + 'hurdal' => true, + 'hurum' => true, + 'hvaler' => true, + 'hyllestad' => true, + 'hagebostad' => true, + 'hægebostad' => true, + 'hoyanger' => true, + 'høyanger' => true, + 'hoylandet' => true, + 'høylandet' => true, + 'ha' => true, + 'hå' => true, + 'ibestad' => true, + 'inderoy' => true, + 'inderøy' => true, + 'iveland' => true, + 'jevnaker' => true, + 'jondal' => true, + 'jolster' => true, + 'jølster' => true, + 'karasjok' => true, + 'karasjohka' => true, + 'kárášjohka' => true, + 'karlsoy' => true, + 'galsa' => true, + 'gálsá' => true, + 'karmoy' => true, + 'karmøy' => true, + 'kautokeino' => true, + 'guovdageaidnu' => true, + 'klepp' => true, + 'klabu' => true, + 'klæbu' => true, + 'kongsberg' => true, + 'kongsvinger' => true, + 'kragero' => true, + 'kragerø' => true, + 'kristiansand' => true, + 'kristiansund' => true, + 'krodsherad' => true, + 'krødsherad' => true, + 'kvalsund' => true, + 'rahkkeravju' => true, + 'ráhkkerávju' => true, + 'kvam' => true, + 'kvinesdal' => true, + 'kvinnherad' => true, + 'kviteseid' => true, + 'kvitsoy' => true, + 'kvitsøy' => true, + 'kvafjord' => true, + 'kvæfjord' => true, + 'giehtavuoatna' => true, + 'kvanangen' => true, + 'kvænangen' => true, + 'navuotna' => true, + 'návuotna' => true, + 'kafjord' => true, + 'kåfjord' => true, + 'gaivuotna' => true, + 'gáivuotna' => true, + 'larvik' => true, + 'lavangen' => true, + 'lavagis' => true, + 'loabat' => true, + 'loabát' => true, + 'lebesby' => true, + 'davvesiida' => true, + 'leikanger' => true, + 'leirfjord' => true, + 'leka' => true, + 'leksvik' => true, + 'lenvik' => true, + 'leangaviika' => true, + 'leaŋgaviika' => true, + 'lesja' => true, + 'levanger' => true, + 'lier' => true, + 'lierne' => true, + 'lillehammer' => true, + 'lillesand' => true, + 'lindesnes' => true, + 'lindas' => true, + 'lindås' => true, + 'lom' => true, + 'loppa' => true, + 'lahppi' => true, + 'láhppi' => true, + 'lund' => true, + 'lunner' => true, + 'luroy' => true, + 'lurøy' => true, + 'luster' => true, + 'lyngdal' => true, + 'lyngen' => true, + 'ivgu' => true, + 'lardal' => true, + 'lerdal' => true, + 'lærdal' => true, + 'lodingen' => true, + 'lødingen' => true, + 'lorenskog' => true, + 'lørenskog' => true, + 'loten' => true, + 'løten' => true, + 'malvik' => true, + 'masoy' => true, + 'måsøy' => true, + 'muosat' => true, + 'muosát' => true, + 'mandal' => true, + 'marker' => true, + 'marnardal' => true, + 'masfjorden' => true, + 'meland' => true, + 'meldal' => true, + 'melhus' => true, + 'meloy' => true, + 'meløy' => true, + 'meraker' => true, + 'meråker' => true, + 'moareke' => true, + 'moåreke' => true, + 'midsund' => true, + 'midtre-gauldal' => true, + 'modalen' => true, + 'modum' => true, + 'molde' => true, + 'moskenes' => true, + 'moss' => true, + 'mosvik' => true, + 'malselv' => true, + 'målselv' => true, + 'malatvuopmi' => true, + 'málatvuopmi' => true, + 'namdalseid' => true, + 'aejrie' => true, + 'namsos' => true, + 'namsskogan' => true, + 'naamesjevuemie' => true, + 'nååmesjevuemie' => true, + 'laakesvuemie' => true, + 'nannestad' => true, + 'narvik' => true, + 'narviika' => true, + 'naustdal' => true, + 'nedre-eiker' => true, + 'akershus' => array( + 'nes' => true + ), + 'buskerud' => array( + 'nes' => true + ), + 'nesna' => true, + 'nesodden' => true, + 'nesseby' => true, + 'unjarga' => true, + 'unjárga' => true, + 'nesset' => true, + 'nissedal' => true, + 'nittedal' => true, + 'nord-aurdal' => true, + 'nord-fron' => true, + 'nord-odal' => true, + 'norddal' => true, + 'nordkapp' => true, + 'davvenjarga' => true, + 'davvenjárga' => true, + 'nordre-land' => true, + 'nordreisa' => true, + 'raisa' => true, + 'ráisa' => true, + 'nore-og-uvdal' => true, + 'notodden' => true, + 'naroy' => true, + 'nærøy' => true, + 'notteroy' => true, + 'nøtterøy' => true, + 'odda' => true, + 'oksnes' => true, + 'øksnes' => true, + 'oppdal' => true, + 'oppegard' => true, + 'oppegård' => true, + 'orkdal' => true, + 'orland' => true, + 'ørland' => true, + 'orskog' => true, + 'ørskog' => true, + 'orsta' => true, + 'ørsta' => true, + 'hedmark' => array( + 'os' => true, + 'valer' => true, + 'våler' => true + ), + 'hordaland' => array( + 'os' => true + ), + 'osen' => true, + 'osteroy' => true, + 'osterøy' => true, + 'ostre-toten' => true, + 'østre-toten' => true, + 'overhalla' => true, + 'ovre-eiker' => true, + 'øvre-eiker' => true, + 'oyer' => true, + 'øyer' => true, + 'oygarden' => true, + 'øygarden' => true, + 'oystre-slidre' => true, + 'øystre-slidre' => true, + 'porsanger' => true, + 'porsangu' => true, + 'porsáŋgu' => true, + 'porsgrunn' => true, + 'radoy' => true, + 'radøy' => true, + 'rakkestad' => true, + 'rana' => true, + 'ruovat' => true, + 'randaberg' => true, + 'rauma' => true, + 'rendalen' => true, + 'rennebu' => true, + 'rennesoy' => true, + 'rennesøy' => true, + 'rindal' => true, + 'ringebu' => true, + 'ringerike' => true, + 'ringsaker' => true, + 'rissa' => true, + 'risor' => true, + 'risør' => true, + 'roan' => true, + 'rollag' => true, + 'rygge' => true, + 'ralingen' => true, + 'rælingen' => true, + 'rodoy' => true, + 'rødøy' => true, + 'romskog' => true, + 'rømskog' => true, + 'roros' => true, + 'røros' => true, + 'rost' => true, + 'røst' => true, + 'royken' => true, + 'røyken' => true, + 'royrvik' => true, + 'røyrvik' => true, + 'rade' => true, + 'råde' => true, + 'salangen' => true, + 'siellak' => true, + 'saltdal' => true, + 'salat' => true, + 'sálát' => true, + 'sálat' => true, + 'samnanger' => true, + 'vestfold' => array( + 'sande' => true + ), + 'sandefjord' => true, + 'sandnes' => true, + 'sandoy' => true, + 'sandøy' => true, + 'sarpsborg' => true, + 'sauda' => true, + 'sauherad' => true, + 'sel' => true, + 'selbu' => true, + 'selje' => true, + 'seljord' => true, + 'sigdal' => true, + 'siljan' => true, + 'sirdal' => true, + 'skaun' => true, + 'skedsmo' => true, + 'ski' => true, + 'skien' => true, + 'skiptvet' => true, + 'skjervoy' => true, + 'skjervøy' => true, + 'skierva' => true, + 'skiervá' => true, + 'skjak' => true, + 'skjåk' => true, + 'skodje' => true, + 'skanland' => true, + 'skånland' => true, + 'skanit' => true, + 'skánit' => true, + 'smola' => true, + 'smøla' => true, + 'snillfjord' => true, + 'snasa' => true, + 'snåsa' => true, + 'snoasa' => true, + 'snaase' => true, + 'snåase' => true, + 'sogndal' => true, + 'sokndal' => true, + 'sola' => true, + 'solund' => true, + 'songdalen' => true, + 'sortland' => true, + 'spydeberg' => true, + 'stange' => true, + 'stavanger' => true, + 'steigen' => true, + 'steinkjer' => true, + 'stjordal' => true, + 'stjørdal' => true, + 'stokke' => true, + 'stor-elvdal' => true, + 'stord' => true, + 'stordal' => true, + 'storfjord' => true, + 'omasvuotna' => true, + 'strand' => true, + 'stranda' => true, + 'stryn' => true, + 'sula' => true, + 'suldal' => true, + 'sund' => true, + 'sunndal' => true, + 'surnadal' => true, + 'sveio' => true, + 'svelvik' => true, + 'sykkylven' => true, + 'sogne' => true, + 'søgne' => true, + 'somna' => true, + 'sømna' => true, + 'sondre-land' => true, + 'søndre-land' => true, + 'sor-aurdal' => true, + 'sør-aurdal' => true, + 'sor-fron' => true, + 'sør-fron' => true, + 'sor-odal' => true, + 'sør-odal' => true, + 'sor-varanger' => true, + 'sør-varanger' => true, + 'matta-varjjat' => true, + 'mátta-várjjat' => true, + 'sorfold' => true, + 'sørfold' => true, + 'sorreisa' => true, + 'sørreisa' => true, + 'sorum' => true, + 'sørum' => true, + 'tana' => true, + 'deatnu' => true, + 'time' => true, + 'tingvoll' => true, + 'tinn' => true, + 'tjeldsund' => true, + 'dielddanuorri' => true, + 'tjome' => true, + 'tjøme' => true, + 'tokke' => true, + 'tolga' => true, + 'torsken' => true, + 'tranoy' => true, + 'tranøy' => true, + 'tromso' => true, + 'tromsø' => true, + 'tromsa' => true, + 'romsa' => true, + 'trondheim' => true, + 'troandin' => true, + 'trysil' => true, + 'trana' => true, + 'træna' => true, + 'trogstad' => true, + 'trøgstad' => true, + 'tvedestrand' => true, + 'tydal' => true, + 'tynset' => true, + 'tysfjord' => true, + 'divtasvuodna' => true, + 'divttasvuotna' => true, + 'tysnes' => true, + 'tysvar' => true, + 'tysvær' => true, + 'tonsberg' => true, + 'tønsberg' => true, + 'ullensaker' => true, + 'ullensvang' => true, + 'ulvik' => true, + 'utsira' => true, + 'vadso' => true, + 'vadsø' => true, + 'cahcesuolo' => true, + 'čáhcesuolo' => true, + 'vaksdal' => true, + 'valle' => true, + 'vang' => true, + 'vanylven' => true, + 'vardo' => true, + 'vardø' => true, + 'varggat' => true, + 'várggát' => true, + 'vefsn' => true, + 'vaapste' => true, + 'vega' => true, + 'vegarshei' => true, + 'vegårshei' => true, + 'vennesla' => true, + 'verdal' => true, + 'verran' => true, + 'vestby' => true, + 'vestnes' => true, + 'vestre-slidre' => true, + 'vestre-toten' => true, + 'vestvagoy' => true, + 'vestvågøy' => true, + 'vevelstad' => true, + 'vik' => true, + 'vikna' => true, + 'vindafjord' => true, + 'volda' => true, + 'voss' => true, + 'varoy' => true, + 'værøy' => true, + 'vagan' => true, + 'vågan' => true, + 'voagat' => true, + 'vagsoy' => true, + 'vågsøy' => true, + 'vaga' => true, + 'vågå' => true, + 'ostfold' => array( + 'valer' => true + ), + 'østfold' => array( + 'våler' => true + ), + 'co' => true, + 'blogspot' => true + ), + 'np' => array( + '*' => true + ), + 'nr' => array( + 'biz' => true, + 'info' => true, + 'gov' => true, + 'edu' => true, + 'org' => true, + 'net' => true, + 'com' => true + ), + 'nu' => array( + 'merseine' => true, + 'mine' => true, + 'shacknet' => true + ), + 'nz' => array( + 'ac' => true, + 'co' => array( + 'blogspot' => true + ), + 'cri' => true, + 'geek' => true, + 'gen' => true, + 'govt' => true, + 'health' => true, + 'iwi' => true, + 'kiwi' => true, + 'maori' => true, + 'mil' => true, + 'māori' => true, + 'net' => true, + 'org' => true, + 'parliament' => true, + 'school' => true + ), + 'om' => array( + 'co' => true, + 'com' => true, + 'edu' => true, + 'gov' => true, + 'med' => true, + 'museum' => true, + 'net' => true, + 'org' => true, + 'pro' => true + ), + 'org' => array( + 'ae' => true, + 'us' => true, + 'cdn77' => array( + 'c' => true, + 'rsc' => true + ), + 'cdn77-secure' => array( + 'origin' => array( + 'ssl' => true + ) + ), + 'duckdns' => true, + 'dyndns' => array( + 'go' => true, + 'home' => true + ), + 'blogdns' => true, + 'blogsite' => true, + 'boldlygoingnowhere' => true, + 'dnsalias' => true, + 'dnsdojo' => true, + 'doesntexist' => true, + 'dontexist' => true, + 'doomdns' => true, + 'dvrdns' => true, + 'dynalias' => true, + 'endofinternet' => true, + 'endoftheinternet' => true, + 'from-me' => true, + 'game-host' => true, + 'gotdns' => true, + 'hobby-site' => true, + 'homedns' => true, + 'homeftp' => true, + 'homelinux' => true, + 'homeunix' => true, + 'is-a-bruinsfan' => true, + 'is-a-candidate' => true, + 'is-a-celticsfan' => true, + 'is-a-chef' => true, + 'is-a-geek' => true, + 'is-a-knight' => true, + 'is-a-linux-user' => true, + 'is-a-patsfan' => true, + 'is-a-soxfan' => true, + 'is-found' => true, + 'is-lost' => true, + 'is-saved' => true, + 'is-very-bad' => true, + 'is-very-evil' => true, + 'is-very-good' => true, + 'is-very-nice' => true, + 'is-very-sweet' => true, + 'isa-geek' => true, + 'kicks-ass' => true, + 'misconfused' => true, + 'podzone' => true, + 'readmyblog' => true, + 'selfip' => true, + 'sellsyourhome' => true, + 'servebbs' => true, + 'serveftp' => true, + 'servegame' => true, + 'stuff-4-sale' => true, + 'webhop' => true, + 'eu' => array( + 'al' => true, + 'asso' => true, + 'at' => true, + 'au' => true, + 'be' => true, + 'bg' => true, + 'ca' => true, + 'cd' => true, + 'ch' => true, + 'cn' => true, + 'cy' => true, + 'cz' => true, + 'de' => true, + 'dk' => true, + 'edu' => true, + 'ee' => true, + 'es' => true, + 'fi' => true, + 'fr' => true, + 'gr' => true, + 'hr' => true, + 'hu' => true, + 'ie' => true, + 'il' => true, + 'in' => true, + 'int' => true, + 'is' => true, + 'it' => true, + 'jp' => true, + 'kr' => true, + 'lt' => true, + 'lu' => true, + 'lv' => true, + 'mc' => true, + 'me' => true, + 'mk' => true, + 'mt' => true, + 'my' => true, + 'net' => true, + 'ng' => true, + 'nl' => true, + 'no' => true, + 'nz' => true, + 'paris' => true, + 'pl' => true, + 'pt' => true, + 'q-a' => true, + 'ro' => true, + 'ru' => true, + 'se' => true, + 'si' => true, + 'sk' => true, + 'tr' => true, + 'uk' => true, + 'us' => true + ), + 'bmoattachments' => true, + 'dsmynas' => true, + 'familyds' => true, + 'hk' => true, + 'za' => true + ), + 'pa' => array( + 'ac' => true, + 'gob' => true, + 'com' => true, + 'org' => true, + 'sld' => true, + 'edu' => true, + 'net' => true, + 'ing' => true, + 'abo' => true, + 'med' => true, + 'nom' => true + ), + 'pe' => array( + 'edu' => true, + 'gob' => true, + 'nom' => true, + 'mil' => true, + 'org' => true, + 'com' => true, + 'net' => true, + 'blogspot' => true + ), + 'pf' => array( + 'com' => true, + 'org' => true, + 'edu' => true + ), + 'pg' => array( + '*' => true + ), + 'ph' => array( + 'com' => true, + 'net' => true, + 'org' => true, + 'gov' => true, + 'edu' => true, + 'ngo' => true, + 'mil' => true, + 'i' => true + ), + 'pk' => array( + 'com' => true, + 'net' => true, + 'edu' => true, + 'org' => true, + 'fam' => true, + 'biz' => true, + 'web' => true, + 'gov' => true, + 'gob' => true, + 'gok' => true, + 'gon' => true, + 'gop' => true, + 'gos' => true, + 'info' => true + ), + 'pl' => array( + 'com' => true, + 'net' => true, + 'org' => true, + 'aid' => true, + 'agro' => true, + 'atm' => true, + 'auto' => true, + 'biz' => true, + 'edu' => true, + 'gmina' => true, + 'gsm' => true, + 'info' => true, + 'mail' => true, + 'miasta' => true, + 'media' => true, + 'mil' => true, + 'nieruchomosci' => true, + 'nom' => true, + 'pc' => true, + 'powiat' => true, + 'priv' => true, + 'realestate' => true, + 'rel' => true, + 'sex' => true, + 'shop' => true, + 'sklep' => true, + 'sos' => true, + 'szkola' => true, + 'targi' => true, + 'tm' => true, + 'tourism' => true, + 'travel' => true, + 'turystyka' => true, + 'gov' => array( + 'ap' => true, + 'ic' => true, + 'is' => true, + 'us' => true, + 'kmpsp' => true, + 'kppsp' => true, + 'kwpsp' => true, + 'psp' => true, + 'wskr' => true, + 'kwp' => true, + 'mw' => true, + 'ug' => true, + 'um' => true, + 'umig' => true, + 'ugim' => true, + 'upow' => true, + 'uw' => true, + 'starostwo' => true, + 'pa' => true, + 'po' => true, + 'psse' => true, + 'pup' => true, + 'rzgw' => true, + 'sa' => true, + 'so' => true, + 'sr' => true, + 'wsa' => true, + 'sko' => true, + 'uzs' => true, + 'wiih' => true, + 'winb' => true, + 'pinb' => true, + 'wios' => true, + 'witd' => true, + 'wzmiuw' => true, + 'piw' => true, + 'wiw' => true, + 'griw' => true, + 'wif' => true, + 'oum' => true, + 'sdn' => true, + 'zp' => true, + 'uppo' => true, + 'mup' => true, + 'wuoz' => true, + 'konsulat' => true, + 'oirm' => true + ), + 'augustow' => true, + 'babia-gora' => true, + 'bedzin' => true, + 'beskidy' => true, + 'bialowieza' => true, + 'bialystok' => true, + 'bielawa' => true, + 'bieszczady' => true, + 'boleslawiec' => true, + 'bydgoszcz' => true, + 'bytom' => true, + 'cieszyn' => true, + 'czeladz' => true, + 'czest' => true, + 'dlugoleka' => true, + 'elblag' => true, + 'elk' => true, + 'glogow' => true, + 'gniezno' => true, + 'gorlice' => true, + 'grajewo' => true, + 'ilawa' => true, + 'jaworzno' => true, + 'jelenia-gora' => true, + 'jgora' => true, + 'kalisz' => true, + 'kazimierz-dolny' => true, + 'karpacz' => true, + 'kartuzy' => true, + 'kaszuby' => true, + 'katowice' => true, + 'kepno' => true, + 'ketrzyn' => true, + 'klodzko' => true, + 'kobierzyce' => true, + 'kolobrzeg' => true, + 'konin' => true, + 'konskowola' => true, + 'kutno' => true, + 'lapy' => true, + 'lebork' => true, + 'legnica' => true, + 'lezajsk' => true, + 'limanowa' => true, + 'lomza' => true, + 'lowicz' => true, + 'lubin' => true, + 'lukow' => true, + 'malbork' => true, + 'malopolska' => true, + 'mazowsze' => true, + 'mazury' => true, + 'mielec' => true, + 'mielno' => true, + 'mragowo' => true, + 'naklo' => true, + 'nowaruda' => true, + 'nysa' => true, + 'olawa' => true, + 'olecko' => true, + 'olkusz' => true, + 'olsztyn' => true, + 'opoczno' => true, + 'opole' => true, + 'ostroda' => true, + 'ostroleka' => true, + 'ostrowiec' => true, + 'ostrowwlkp' => true, + 'pila' => true, + 'pisz' => true, + 'podhale' => true, + 'podlasie' => true, + 'polkowice' => true, + 'pomorze' => true, + 'pomorskie' => true, + 'prochowice' => true, + 'pruszkow' => true, + 'przeworsk' => true, + 'pulawy' => true, + 'radom' => true, + 'rawa-maz' => true, + 'rybnik' => true, + 'rzeszow' => true, + 'sanok' => true, + 'sejny' => true, + 'slask' => true, + 'slupsk' => true, + 'sosnowiec' => true, + 'stalowa-wola' => true, + 'skoczow' => true, + 'starachowice' => true, + 'stargard' => true, + 'suwalki' => true, + 'swidnica' => true, + 'swiebodzin' => true, + 'swinoujscie' => true, + 'szczecin' => true, + 'szczytno' => true, + 'tarnobrzeg' => true, + 'tgory' => true, + 'turek' => true, + 'tychy' => true, + 'ustka' => true, + 'walbrzych' => true, + 'warmia' => true, + 'warszawa' => true, + 'waw' => true, + 'wegrow' => true, + 'wielun' => true, + 'wlocl' => true, + 'wloclawek' => true, + 'wodzislaw' => true, + 'wolomin' => true, + 'wroclaw' => true, + 'zachpomor' => true, + 'zagan' => true, + 'zarow' => true, + 'zgora' => true, + 'zgorzelec' => true, + 'co' => true, + 'art' => true, + 'gliwice' => true, + 'krakow' => true, + 'poznan' => true, + 'wroc' => true, + 'zakopane' => true, + 'gda' => true, + 'gdansk' => true, + 'gdynia' => true, + 'med' => true, + 'sopot' => true + ), + 'pm' => true, + 'pn' => array( + 'gov' => true, + 'co' => true, + 'org' => true, + 'edu' => true, + 'net' => true + ), + 'post' => true, + 'pr' => array( + 'com' => true, + 'net' => true, + 'org' => true, + 'gov' => true, + 'edu' => true, + 'isla' => true, + 'pro' => true, + 'biz' => true, + 'info' => true, + 'name' => true, + 'est' => true, + 'prof' => true, + 'ac' => true + ), + 'pro' => array( + 'aaa' => true, + 'aca' => true, + 'acct' => true, + 'avocat' => true, + 'bar' => true, + 'cpa' => true, + 'eng' => true, + 'jur' => true, + 'law' => true, + 'med' => true, + 'recht' => true + ), + 'ps' => array( + 'edu' => true, + 'gov' => true, + 'sec' => true, + 'plo' => true, + 'com' => true, + 'org' => true, + 'net' => true + ), + 'pt' => array( + 'net' => true, + 'gov' => true, + 'org' => true, + 'edu' => true, + 'int' => true, + 'publ' => true, + 'com' => true, + 'nome' => true, + 'blogspot' => true + ), + 'pw' => array( + 'co' => true, + 'ne' => true, + 'or' => true, + 'ed' => true, + 'go' => true, + 'belau' => true + ), + 'py' => array( + 'com' => true, + 'coop' => true, + 'edu' => true, + 'gov' => true, + 'mil' => true, + 'net' => true, + 'org' => true + ), + 'qa' => array( + 'com' => true, + 'edu' => true, + 'gov' => true, + 'mil' => true, + 'name' => true, + 'net' => true, + 'org' => true, + 'sch' => true, + 'blogspot' => true + ), + 're' => array( + 'asso' => true, + 'com' => true, + 'nom' => true, + 'blogspot' => true + ), + 'ro' => array( + 'arts' => true, + 'com' => true, + 'firm' => true, + 'info' => true, + 'nom' => true, + 'nt' => true, + 'org' => true, + 'rec' => true, + 'store' => true, + 'tm' => true, + 'www' => true, + 'blogspot' => true + ), + 'rs' => array( + 'ac' => true, + 'co' => true, + 'edu' => true, + 'gov' => true, + 'in' => true, + 'org' => true, + 'blogspot' => true + ), + 'ru' => array( + 'ac' => true, + 'com' => true, + 'edu' => true, + 'int' => true, + 'net' => true, + 'org' => true, + 'pp' => true, + 'adygeya' => true, + 'altai' => true, + 'amur' => true, + 'arkhangelsk' => true, + 'astrakhan' => true, + 'bashkiria' => true, + 'belgorod' => true, + 'bir' => true, + 'bryansk' => true, + 'buryatia' => true, + 'cbg' => true, + 'chel' => true, + 'chelyabinsk' => true, + 'chita' => true, + 'chukotka' => true, + 'chuvashia' => true, + 'dagestan' => true, + 'dudinka' => true, + 'e-burg' => true, + 'grozny' => true, + 'irkutsk' => true, + 'ivanovo' => true, + 'izhevsk' => true, + 'jar' => true, + 'joshkar-ola' => true, + 'kalmykia' => true, + 'kaluga' => true, + 'kamchatka' => true, + 'karelia' => true, + 'kazan' => true, + 'kchr' => true, + 'kemerovo' => true, + 'khabarovsk' => true, + 'khakassia' => true, + 'khv' => true, + 'kirov' => true, + 'koenig' => true, + 'komi' => true, + 'kostroma' => true, + 'krasnoyarsk' => true, + 'kuban' => true, + 'kurgan' => true, + 'kursk' => true, + 'lipetsk' => true, + 'magadan' => true, + 'mari' => true, + 'mari-el' => true, + 'marine' => true, + 'mordovia' => true, + 'msk' => true, + 'murmansk' => true, + 'nalchik' => true, + 'nnov' => true, + 'nov' => true, + 'novosibirsk' => true, + 'nsk' => true, + 'omsk' => true, + 'orenburg' => true, + 'oryol' => true, + 'palana' => true, + 'penza' => true, + 'perm' => true, + 'ptz' => true, + 'rnd' => true, + 'ryazan' => true, + 'sakhalin' => true, + 'samara' => true, + 'saratov' => true, + 'simbirsk' => true, + 'smolensk' => true, + 'spb' => true, + 'stavropol' => true, + 'stv' => true, + 'surgut' => true, + 'tambov' => true, + 'tatarstan' => true, + 'tom' => true, + 'tomsk' => true, + 'tsaritsyn' => true, + 'tsk' => true, + 'tula' => true, + 'tuva' => true, + 'tver' => true, + 'tyumen' => true, + 'udm' => true, + 'udmurtia' => true, + 'ulan-ude' => true, + 'vladikavkaz' => true, + 'vladimir' => true, + 'vladivostok' => true, + 'volgograd' => true, + 'vologda' => true, + 'voronezh' => true, + 'vrn' => true, + 'vyatka' => true, + 'yakutia' => true, + 'yamal' => true, + 'yaroslavl' => true, + 'yekaterinburg' => true, + 'yuzhno-sakhalinsk' => true, + 'amursk' => true, + 'baikal' => true, + 'cmw' => true, + 'fareast' => true, + 'jamal' => true, + 'kms' => true, + 'k-uralsk' => true, + 'kustanai' => true, + 'kuzbass' => true, + 'mytis' => true, + 'nakhodka' => true, + 'nkz' => true, + 'norilsk' => true, + 'oskol' => true, + 'pyatigorsk' => true, + 'rubtsovsk' => true, + 'snz' => true, + 'syzran' => true, + 'vdonsk' => true, + 'zgrad' => true, + 'gov' => true, + 'mil' => true, + 'test' => true, + 'blogspot' => true + ), + 'rw' => array( + 'gov' => true, + 'net' => true, + 'edu' => true, + 'ac' => true, + 'com' => true, + 'co' => true, + 'int' => true, + 'mil' => true, + 'gouv' => true + ), + 'sa' => array( + 'com' => true, + 'net' => true, + 'org' => true, + 'gov' => true, + 'med' => true, + 'pub' => true, + 'edu' => true, + 'sch' => true + ), + 'sb' => array( + 'com' => true, + 'edu' => true, + 'gov' => true, + 'net' => true, + 'org' => true + ), + 'sc' => array( + 'com' => true, + 'gov' => true, + 'net' => true, + 'org' => true, + 'edu' => true + ), + 'sd' => array( + 'com' => true, + 'net' => true, + 'org' => true, + 'edu' => true, + 'med' => true, + 'tv' => true, + 'gov' => true, + 'info' => true + ), + 'se' => array( + 'a' => true, + 'ac' => true, + 'b' => true, + 'bd' => true, + 'brand' => true, + 'c' => true, + 'd' => true, + 'e' => true, + 'f' => true, + 'fh' => true, + 'fhsk' => true, + 'fhv' => true, + 'g' => true, + 'h' => true, + 'i' => true, + 'k' => true, + 'komforb' => true, + 'kommunalforbund' => true, + 'komvux' => true, + 'l' => true, + 'lanbib' => true, + 'm' => true, + 'n' => true, + 'naturbruksgymn' => true, + 'o' => true, + 'org' => true, + 'p' => true, + 'parti' => true, + 'pp' => true, + 'press' => true, + 'r' => true, + 's' => true, + 't' => true, + 'tm' => true, + 'u' => true, + 'w' => true, + 'x' => true, + 'y' => true, + 'z' => true, + 'com' => true, + 'blogspot' => true + ), + 'sg' => array( + 'com' => true, + 'net' => true, + 'org' => true, + 'gov' => true, + 'edu' => true, + 'per' => true, + 'blogspot' => true + ), + 'sh' => array( + 'com' => true, + 'net' => true, + 'gov' => true, + 'org' => true, + 'mil' => true, + 'platform' => array( + '*' => true + ), + 'hashbang' => true + ), + 'si' => array( + 'blogspot' => true + ), + 'sj' => true, + 'sk' => array( + 'blogspot' => true + ), + 'sl' => array( + 'com' => true, + 'net' => true, + 'edu' => true, + 'gov' => true, + 'org' => true + ), + 'sm' => true, + 'sn' => array( + 'art' => true, + 'com' => true, + 'edu' => true, + 'gouv' => true, + 'org' => true, + 'perso' => true, + 'univ' => true, + 'blogspot' => true + ), + 'so' => array( + 'com' => true, + 'net' => true, + 'org' => true + ), + 'sr' => true, + 'st' => array( + 'co' => true, + 'com' => true, + 'consulado' => true, + 'edu' => true, + 'embaixada' => true, + 'gov' => true, + 'mil' => true, + 'net' => true, + 'org' => true, + 'principe' => true, + 'saotome' => true, + 'store' => true + ), + 'su' => array( + 'adygeya' => true, + 'arkhangelsk' => true, + 'balashov' => true, + 'bashkiria' => true, + 'bryansk' => true, + 'dagestan' => true, + 'grozny' => true, + 'ivanovo' => true, + 'kalmykia' => true, + 'kaluga' => true, + 'karelia' => true, + 'khakassia' => true, + 'krasnodar' => true, + 'kurgan' => true, + 'lenug' => true, + 'mordovia' => true, + 'msk' => true, + 'murmansk' => true, + 'nalchik' => true, + 'nov' => true, + 'obninsk' => true, + 'penza' => true, + 'pokrovsk' => true, + 'sochi' => true, + 'spb' => true, + 'togliatti' => true, + 'troitsk' => true, + 'tula' => true, + 'tuva' => true, + 'vladikavkaz' => true, + 'vladimir' => true, + 'vologda' => true + ), + 'sv' => array( + 'com' => true, + 'edu' => true, + 'gob' => true, + 'org' => true, + 'red' => true + ), + 'sx' => array( + 'gov' => true + ), + 'sy' => array( + 'edu' => true, + 'gov' => true, + 'net' => true, + 'mil' => true, + 'com' => true, + 'org' => true + ), + 'sz' => array( + 'co' => true, + 'ac' => true, + 'org' => true + ), + 'tc' => true, + 'td' => array( + 'blogspot' => true + ), + 'tel' => true, + 'tf' => true, + 'tg' => true, + 'th' => array( + 'ac' => true, + 'co' => true, + 'go' => true, + 'in' => true, + 'mi' => true, + 'net' => true, + 'or' => true + ), + 'tj' => array( + 'ac' => true, + 'biz' => true, + 'co' => true, + 'com' => true, + 'edu' => true, + 'go' => true, + 'gov' => true, + 'int' => true, + 'mil' => true, + 'name' => true, + 'net' => true, + 'nic' => true, + 'org' => true, + 'test' => true, + 'web' => true + ), + 'tk' => true, + 'tl' => array( + 'gov' => true + ), + 'tm' => array( + 'com' => true, + 'co' => true, + 'org' => true, + 'net' => true, + 'nom' => true, + 'gov' => true, + 'mil' => true, + 'edu' => true + ), + 'tn' => array( + 'com' => true, + 'ens' => true, + 'fin' => true, + 'gov' => true, + 'ind' => true, + 'intl' => true, + 'nat' => true, + 'net' => true, + 'org' => true, + 'info' => true, + 'perso' => true, + 'tourism' => true, + 'edunet' => true, + 'rnrt' => true, + 'rns' => true, + 'rnu' => true, + 'mincom' => true, + 'agrinet' => true, + 'defense' => true, + 'turen' => true + ), + 'to' => array( + 'com' => true, + 'gov' => true, + 'net' => true, + 'org' => true, + 'edu' => true, + 'mil' => true + ), + 'tr' => array( + 'com' => array( + 'blogspot' => true + ), + 'info' => true, + 'biz' => true, + 'net' => true, + 'org' => true, + 'web' => true, + 'gen' => true, + 'tv' => true, + 'av' => true, + 'dr' => true, + 'bbs' => true, + 'name' => true, + 'tel' => true, + 'gov' => true, + 'bel' => true, + 'pol' => true, + 'mil' => true, + 'k12' => true, + 'edu' => true, + 'kep' => true, + 'nc' => array( + 'gov' => true + ) + ), + 'travel' => true, + 'tt' => array( + 'co' => true, + 'com' => true, + 'org' => true, + 'net' => true, + 'biz' => true, + 'info' => true, + 'pro' => true, + 'int' => true, + 'coop' => true, + 'jobs' => true, + 'mobi' => true, + 'travel' => true, + 'museum' => true, + 'aero' => true, + 'name' => true, + 'gov' => true, + 'edu' => true + ), + 'tv' => array( + 'dyndns' => true, + 'better-than' => true, + 'on-the-web' => true, + 'worse-than' => true + ), + 'tw' => array( + 'edu' => true, + 'gov' => true, + 'mil' => true, + 'com' => true, + 'net' => true, + 'org' => true, + 'idv' => true, + 'game' => true, + 'ebiz' => true, + 'club' => true, + '網路' => true, + '組織' => true, + '商業' => true, + 'blogspot' => true + ), + 'tz' => array( + 'ac' => true, + 'co' => true, + 'go' => true, + 'hotel' => true, + 'info' => true, + 'me' => true, + 'mil' => true, + 'mobi' => true, + 'ne' => true, + 'or' => true, + 'sc' => true, + 'tv' => true + ), + 'ua' => array( + 'com' => true, + 'edu' => true, + 'gov' => true, + 'in' => true, + 'net' => true, + 'org' => true, + 'cherkassy' => true, + 'cherkasy' => true, + 'chernigov' => true, + 'chernihiv' => true, + 'chernivtsi' => true, + 'chernovtsy' => true, + 'ck' => true, + 'cn' => true, + 'cr' => true, + 'crimea' => true, + 'cv' => true, + 'dn' => true, + 'dnepropetrovsk' => true, + 'dnipropetrovsk' => true, + 'dominic' => true, + 'donetsk' => true, + 'dp' => true, + 'if' => true, + 'ivano-frankivsk' => true, + 'kh' => true, + 'kharkiv' => true, + 'kharkov' => true, + 'kherson' => true, + 'khmelnitskiy' => true, + 'khmelnytskyi' => true, + 'kiev' => true, + 'kirovograd' => true, + 'km' => true, + 'kr' => true, + 'krym' => true, + 'ks' => true, + 'kv' => true, + 'kyiv' => true, + 'lg' => true, + 'lt' => true, + 'lugansk' => true, + 'lutsk' => true, + 'lv' => true, + 'lviv' => true, + 'mk' => true, + 'mykolaiv' => true, + 'nikolaev' => true, + 'od' => true, + 'odesa' => true, + 'odessa' => true, + 'pl' => true, + 'poltava' => true, + 'rivne' => true, + 'rovno' => true, + 'rv' => true, + 'sb' => true, + 'sebastopol' => true, + 'sevastopol' => true, + 'sm' => true, + 'sumy' => true, + 'te' => true, + 'ternopil' => true, + 'uz' => true, + 'uzhgorod' => true, + 'vinnica' => true, + 'vinnytsia' => true, + 'vn' => true, + 'volyn' => true, + 'yalta' => true, + 'zaporizhzhe' => true, + 'zaporizhzhia' => true, + 'zhitomir' => true, + 'zhytomyr' => true, + 'zp' => true, + 'zt' => true, + 'biz' => true, + 'co' => true, + 'pp' => true + ), + 'ug' => array( + 'co' => true, + 'or' => true, + 'ac' => true, + 'sc' => true, + 'go' => true, + 'ne' => true, + 'com' => true, + 'org' => true, + 'blogspot' => true + ), + 'uk' => array( + 'ac' => true, + 'co' => array( + 'blogspot' => true + ), + 'gov' => array( + 'service' => true + ), + 'ltd' => true, + 'me' => true, + 'net' => true, + 'nhs' => true, + 'org' => true, + 'plc' => true, + 'police' => true, + 'sch' => array( + '*' => true + ) + ), + 'us' => array( + 'dni' => true, + 'fed' => true, + 'isa' => true, + 'kids' => true, + 'nsn' => true, + 'ak' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'al' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'ar' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'as' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'az' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'ca' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'co' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'ct' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'dc' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'de' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'fl' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'ga' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'gu' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'hi' => array( + 'cc' => true, + 'lib' => true + ), + 'ia' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'id' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'il' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'in' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'ks' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'ky' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'la' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'ma' => array( + 'k12' => array( + 'pvt' => true, + 'chtr' => true, + 'paroch' => true + ), + 'cc' => true, + 'lib' => true + ), + 'md' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'me' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'mi' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'mn' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'mo' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'ms' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'mt' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'nc' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'nd' => array( + 'cc' => true, + 'lib' => true + ), + 'ne' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'nh' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'nj' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'nm' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'nv' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'ny' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'oh' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'ok' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'or' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'pa' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'pr' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'ri' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'sc' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'sd' => array( + 'cc' => true, + 'lib' => true + ), + 'tn' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'tx' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'ut' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'vi' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'vt' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'va' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'wa' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'wi' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'wv' => array( + 'cc' => true + ), + 'wy' => array( + 'k12' => true, + 'cc' => true, + 'lib' => true + ), + 'is-by' => true, + 'land-4-sale' => true, + 'stuff-4-sale' => true + ), + 'uy' => array( + 'com' => array( + 'blogspot' => true + ), + 'edu' => true, + 'gub' => true, + 'mil' => true, + 'net' => true, + 'org' => true + ), + 'uz' => array( + 'co' => true, + 'com' => true, + 'net' => true, + 'org' => true + ), + 'va' => true, + 'vc' => array( + 'com' => true, + 'net' => true, + 'org' => true, + 'gov' => true, + 'mil' => true, + 'edu' => true + ), + 've' => array( + 'arts' => true, + 'co' => true, + 'com' => true, + 'e12' => true, + 'edu' => true, + 'firm' => true, + 'gob' => true, + 'gov' => true, + 'info' => true, + 'int' => true, + 'mil' => true, + 'net' => true, + 'org' => true, + 'rec' => true, + 'store' => true, + 'tec' => true, + 'web' => true + ), + 'vg' => true, + 'vi' => array( + 'co' => true, + 'com' => true, + 'k12' => true, + 'net' => true, + 'org' => true + ), + 'vn' => array( + 'com' => true, + 'net' => true, + 'org' => true, + 'edu' => true, + 'gov' => true, + 'int' => true, + 'ac' => true, + 'biz' => true, + 'info' => true, + 'name' => true, + 'pro' => true, + 'health' => true, + 'blogspot' => true + ), + 'vu' => array( + 'com' => true, + 'edu' => true, + 'net' => true, + 'org' => true + ), + 'wf' => true, + 'ws' => array( + 'com' => true, + 'net' => true, + 'org' => true, + 'gov' => true, + 'edu' => true, + 'dyndns' => true, + 'mypets' => true + ), + 'yt' => true, + 'امارات' => true, + 'հայ' => true, + 'বাংলা' => true, + 'бел' => true, + '中国' => true, + '中國' => true, + 'الجزائر' => true, + 'مصر' => true, + 'გე' => true, + 'ελ' => true, + '香港' => true, + 'भारत' => true, + 'بھارت' => true, + 'భారత్' => true, + 'ભારત' => true, + 'ਭਾਰਤ' => true, + 'ভারত' => true, + 'இந்தியா' => true, + 'ایران' => true, + 'ايران' => true, + 'عراق' => true, + 'الاردن' => true, + '한국' => true, + 'қаз' => true, + 'ලංකා' => true, + 'இலங்கை' => true, + 'المغرب' => true, + 'мкд' => true, + 'мон' => true, + '澳門' => true, + '澳门' => true, + 'مليسيا' => true, + 'عمان' => true, + 'پاکستان' => true, + 'پاكستان' => true, + 'فلسطين' => true, + 'срб' => array( + 'пр' => true, + 'орг' => true, + 'обр' => true, + 'од' => true, + 'упр' => true, + 'ак' => true + ), + 'рф' => true, + 'قطر' => true, + 'السعودية' => true, + 'السعودیة' => true, + 'السعودیۃ' => true, + 'السعوديه' => true, + 'سودان' => true, + '新加坡' => true, + 'சிங்கப்பூர்' => true, + 'سورية' => true, + 'سوريا' => true, + 'ไทย' => true, + 'تونس' => true, + '台灣' => true, + '台湾' => true, + '臺灣' => true, + 'укр' => true, + 'اليمن' => true, + 'xxx' => true, + 'ye' => array( + '*' => true + ), + 'za' => array( + 'ac' => true, + 'agric' => true, + 'alt' => true, + 'co' => array( + 'blogspot' => true + ), + 'edu' => true, + 'gov' => true, + 'grondar' => true, + 'law' => true, + 'mil' => true, + 'net' => true, + 'ngo' => true, + 'nis' => true, + 'nom' => true, + 'org' => true, + 'school' => true, + 'tm' => true, + 'web' => true + ), + 'zm' => array( + '*' => true + ), + 'zw' => array( + '*' => true + ), + 'aaa' => true, + 'aarp' => true, + 'abarth' => true, + 'abb' => true, + 'abbott' => true, + 'abbvie' => true, + 'abc' => true, + 'able' => true, + 'abogado' => true, + 'abudhabi' => true, + 'academy' => true, + 'accenture' => true, + 'accountant' => true, + 'accountants' => true, + 'aco' => true, + 'active' => true, + 'actor' => true, + 'adac' => true, + 'ads' => true, + 'adult' => true, + 'aeg' => true, + 'aetna' => true, + 'afamilycompany' => true, + 'afl' => true, + 'africa' => true, + 'africamagic' => true, + 'agakhan' => true, + 'agency' => true, + 'aig' => true, + 'aigo' => true, + 'airbus' => true, + 'airforce' => true, + 'airtel' => true, + 'akdn' => true, + 'alfaromeo' => true, + 'alibaba' => true, + 'alipay' => true, + 'allfinanz' => true, + 'allstate' => true, + 'ally' => true, + 'alsace' => true, + 'alstom' => true, + 'americanexpress' => true, + 'americanfamily' => true, + 'amex' => true, + 'amfam' => true, + 'amica' => true, + 'amsterdam' => true, + 'analytics' => true, + 'android' => true, + 'anquan' => true, + 'anz' => true, + 'aol' => true, + 'apartments' => true, + 'app' => true, + 'apple' => true, + 'aquarelle' => true, + 'arab' => true, + 'aramco' => true, + 'archi' => true, + 'army' => true, + 'arte' => true, + 'asda' => true, + 'associates' => true, + 'athleta' => true, + 'attorney' => true, + 'auction' => true, + 'audi' => true, + 'audible' => true, + 'audio' => true, + 'auspost' => true, + 'author' => true, + 'auto' => true, + 'autos' => true, + 'avianca' => true, + 'aws' => true, + 'axa' => true, + 'azure' => true, + 'baby' => true, + 'baidu' => true, + 'banamex' => true, + 'bananarepublic' => true, + 'band' => true, + 'bank' => true, + 'bar' => true, + 'barcelona' => true, + 'barclaycard' => true, + 'barclays' => true, + 'barefoot' => true, + 'bargains' => true, + 'baseball' => true, + 'basketball' => true, + 'bauhaus' => true, + 'bayern' => true, + 'bbc' => true, + 'bbt' => true, + 'bbva' => true, + 'bcg' => true, + 'bcn' => true, + 'beats' => true, + 'beauty' => true, + 'beer' => true, + 'bentley' => true, + 'berlin' => true, + 'best' => true, + 'bestbuy' => true, + 'bet' => true, + 'bharti' => true, + 'bible' => true, + 'bid' => true, + 'bike' => true, + 'bing' => true, + 'bingo' => true, + 'bio' => true, + 'black' => true, + 'blackfriday' => true, + 'blanco' => true, + 'blockbuster' => true, + 'blog' => true, + 'bloomberg' => true, + 'blue' => true, + 'bms' => true, + 'bmw' => true, + 'bnl' => true, + 'bnpparibas' => true, + 'boats' => true, + 'boehringer' => true, + 'bofa' => true, + 'bom' => true, + 'bond' => true, + 'boo' => true, + 'book' => true, + 'booking' => true, + 'boots' => true, + 'bosch' => true, + 'bostik' => true, + 'boston' => true, + 'bot' => true, + 'boutique' => true, + 'box' => true, + 'bradesco' => true, + 'bridgestone' => true, + 'broadway' => true, + 'broker' => true, + 'brother' => true, + 'brussels' => true, + 'budapest' => true, + 'bugatti' => true, + 'build' => true, + 'builders' => true, + 'business' => true, + 'buy' => true, + 'buzz' => true, + 'bzh' => true, + 'cab' => true, + 'cafe' => true, + 'cal' => true, + 'call' => true, + 'calvinklein' => true, + 'camera' => true, + 'camp' => true, + 'cancerresearch' => true, + 'canon' => true, + 'capetown' => true, + 'capital' => true, + 'capitalone' => true, + 'car' => true, + 'caravan' => true, + 'cards' => true, + 'care' => true, + 'career' => true, + 'careers' => true, + 'cars' => true, + 'cartier' => true, + 'casa' => true, + 'case' => true, + 'caseih' => true, + 'cash' => true, + 'casino' => true, + 'catering' => true, + 'catholic' => true, + 'cba' => true, + 'cbn' => true, + 'cbre' => true, + 'cbs' => true, + 'ceb' => true, + 'center' => true, + 'ceo' => true, + 'cern' => true, + 'cfa' => true, + 'cfd' => true, + 'chanel' => true, + 'channel' => true, + 'chase' => true, + 'chat' => true, + 'cheap' => true, + 'chintai' => true, + 'chloe' => true, + 'christmas' => true, + 'chrome' => true, + 'chrysler' => true, + 'church' => true, + 'cipriani' => true, + 'circle' => true, + 'cisco' => true, + 'citadel' => true, + 'citi' => true, + 'citic' => true, + 'city' => true, + 'cityeats' => true, + 'claims' => true, + 'cleaning' => true, + 'click' => true, + 'clinic' => true, + 'clinique' => true, + 'clothing' => true, + 'cloud' => true, + 'club' => true, + 'clubmed' => true, + 'coach' => true, + 'codes' => true, + 'coffee' => true, + 'college' => true, + 'cologne' => true, + 'comcast' => true, + 'commbank' => true, + 'community' => true, + 'company' => true, + 'compare' => true, + 'computer' => true, + 'comsec' => true, + 'condos' => true, + 'construction' => true, + 'consulting' => true, + 'contact' => true, + 'contractors' => true, + 'cooking' => true, + 'cookingchannel' => true, + 'cool' => true, + 'corsica' => true, + 'country' => true, + 'coupon' => true, + 'coupons' => true, + 'courses' => true, + 'credit' => true, + 'creditcard' => true, + 'creditunion' => true, + 'cricket' => true, + 'crown' => true, + 'crs' => true, + 'cruise' => true, + 'cruises' => true, + 'csc' => true, + 'cuisinella' => true, + 'cymru' => true, + 'cyou' => true, + 'dabur' => true, + 'dad' => true, + 'dance' => true, + 'date' => true, + 'dating' => true, + 'datsun' => true, + 'day' => true, + 'dclk' => true, + 'dds' => true, + 'deal' => true, + 'dealer' => true, + 'deals' => true, + 'degree' => true, + 'delivery' => true, + 'dell' => true, + 'deloitte' => true, + 'delta' => true, + 'democrat' => true, + 'dental' => true, + 'dentist' => true, + 'desi' => true, + 'design' => true, + 'dev' => true, + 'dhl' => true, + 'diamonds' => true, + 'diet' => true, + 'digital' => true, + 'direct' => true, + 'directory' => true, + 'discount' => true, + 'discover' => true, + 'dish' => true, + 'diy' => true, + 'dnp' => true, + 'docs' => true, + 'dodge' => true, + 'dog' => true, + 'doha' => true, + 'domains' => true, + 'doosan' => true, + 'dot' => true, + 'download' => true, + 'drive' => true, + 'dstv' => true, + 'dtv' => true, + 'dubai' => true, + 'duck' => true, + 'dunlop' => true, + 'duns' => true, + 'dupont' => true, + 'durban' => true, + 'dvag' => true, + 'dwg' => true, + 'earth' => true, + 'eat' => true, + 'edeka' => true, + 'education' => true, + 'email' => true, + 'emerck' => true, + 'emerson' => true, + 'energy' => true, + 'engineer' => true, + 'engineering' => true, + 'enterprises' => true, + 'epost' => true, + 'epson' => true, + 'equipment' => true, + 'ericsson' => true, + 'erni' => true, + 'esq' => true, + 'estate' => true, + 'esurance' => true, + 'etisalat' => true, + 'eurovision' => true, + 'eus' => true, + 'events' => true, + 'everbank' => true, + 'exchange' => true, + 'expert' => true, + 'exposed' => true, + 'express' => true, + 'extraspace' => true, + 'fage' => true, + 'fail' => true, + 'fairwinds' => true, + 'faith' => true, + 'family' => true, + 'fan' => true, + 'fans' => true, + 'farm' => true, + 'farmers' => true, + 'fashion' => true, + 'fast' => true, + 'fedex' => true, + 'feedback' => true, + 'ferrari' => true, + 'ferrero' => true, + 'fiat' => true, + 'fidelity' => true, + 'fido' => true, + 'film' => true, + 'final' => true, + 'finance' => true, + 'financial' => true, + 'fire' => true, + 'firestone' => true, + 'firmdale' => true, + 'fish' => true, + 'fishing' => true, + 'fit' => true, + 'fitness' => true, + 'flickr' => true, + 'flights' => true, + 'flir' => true, + 'florist' => true, + 'flowers' => true, + 'flsmidth' => true, + 'fly' => true, + 'foo' => true, + 'foodnetwork' => true, + 'football' => true, + 'ford' => true, + 'forex' => true, + 'forsale' => true, + 'forum' => true, + 'foundation' => true, + 'fox' => true, + 'free' => true, + 'fresenius' => true, + 'frl' => true, + 'frogans' => true, + 'frontdoor' => true, + 'frontier' => true, + 'ftr' => true, + 'fujitsu' => true, + 'fujixerox' => true, + 'fund' => true, + 'furniture' => true, + 'futbol' => true, + 'fyi' => true, + 'gal' => true, + 'gallery' => true, + 'gallo' => true, + 'gallup' => true, + 'game' => true, + 'games' => true, + 'gap' => true, + 'garden' => true, + 'gbiz' => true, + 'gdn' => true, + 'gea' => true, + 'gent' => true, + 'genting' => true, + 'george' => true, + 'ggee' => true, + 'gift' => true, + 'gifts' => true, + 'gives' => true, + 'giving' => true, + 'glade' => true, + 'glass' => true, + 'gle' => true, + 'global' => true, + 'globo' => true, + 'gmail' => true, + 'gmo' => true, + 'gmx' => true, + 'godaddy' => true, + 'gold' => true, + 'goldpoint' => true, + 'golf' => true, + 'goo' => true, + 'goodhands' => true, + 'goodyear' => true, + 'goog' => true, + 'google' => true, + 'gop' => true, + 'got' => true, + 'gotv' => true, + 'grainger' => true, + 'graphics' => true, + 'gratis' => true, + 'green' => true, + 'gripe' => true, + 'group' => true, + 'guardian' => true, + 'gucci' => true, + 'guge' => true, + 'guide' => true, + 'guitars' => true, + 'guru' => true, + 'hair' => true, + 'hamburg' => true, + 'hangout' => true, + 'haus' => true, + 'hbo' => true, + 'hdfc' => true, + 'hdfcbank' => true, + 'health' => true, + 'healthcare' => true, + 'help' => true, + 'helsinki' => true, + 'here' => true, + 'hermes' => true, + 'hgtv' => true, + 'hiphop' => true, + 'hisamitsu' => true, + 'hitachi' => true, + 'hiv' => true, + 'hkt' => true, + 'hockey' => true, + 'holdings' => true, + 'holiday' => true, + 'homedepot' => true, + 'homegoods' => true, + 'homes' => true, + 'homesense' => true, + 'honda' => true, + 'honeywell' => true, + 'horse' => true, + 'host' => true, + 'hosting' => true, + 'hot' => true, + 'hoteles' => true, + 'hotmail' => true, + 'house' => true, + 'how' => true, + 'hsbc' => true, + 'htc' => true, + 'hughes' => true, + 'hyatt' => true, + 'hyundai' => true, + 'ibm' => true, + 'icbc' => true, + 'ice' => true, + 'icu' => true, + 'ieee' => true, + 'ifm' => true, + 'iinet' => true, + 'ikano' => true, + 'imamat' => true, + 'imdb' => true, + 'immo' => true, + 'immobilien' => true, + 'industries' => true, + 'infiniti' => true, + 'ing' => true, + 'ink' => true, + 'institute' => true, + 'insurance' => true, + 'insure' => true, + 'intel' => true, + 'international' => true, + 'intuit' => true, + 'investments' => true, + 'ipiranga' => true, + 'irish' => true, + 'iselect' => true, + 'ismaili' => true, + 'ist' => true, + 'istanbul' => true, + 'itau' => true, + 'itv' => true, + 'iveco' => true, + 'iwc' => true, + 'jaguar' => true, + 'java' => true, + 'jcb' => true, + 'jcp' => true, + 'jeep' => true, + 'jetzt' => true, + 'jewelry' => true, + 'jio' => true, + 'jlc' => true, + 'jll' => true, + 'jmp' => true, + 'jnj' => true, + 'joburg' => true, + 'jot' => true, + 'joy' => true, + 'jpmorgan' => true, + 'jprs' => true, + 'juegos' => true, + 'juniper' => true, + 'kaufen' => true, + 'kddi' => true, + 'kerryhotels' => true, + 'kerrylogistics' => true, + 'kerryproperties' => true, + 'kfh' => true, + 'kia' => true, + 'kim' => true, + 'kinder' => true, + 'kindle' => true, + 'kitchen' => true, + 'kiwi' => true, + 'koeln' => true, + 'komatsu' => true, + 'kosher' => true, + 'kpmg' => true, + 'kpn' => true, + 'krd' => true, + 'kred' => true, + 'kuokgroup' => true, + 'kyknet' => true, + 'kyoto' => true, + 'lacaixa' => true, + 'ladbrokes' => true, + 'lamborghini' => true, + 'lamer' => true, + 'lancaster' => true, + 'lancia' => true, + 'lancome' => true, + 'land' => true, + 'landrover' => true, + 'lanxess' => true, + 'lasalle' => true, + 'lat' => true, + 'latino' => true, + 'latrobe' => true, + 'law' => true, + 'lawyer' => true, + 'lds' => true, + 'lease' => true, + 'leclerc' => true, + 'lefrak' => true, + 'legal' => true, + 'lego' => true, + 'lexus' => true, + 'lgbt' => true, + 'liaison' => true, + 'lidl' => true, + 'life' => true, + 'lifeinsurance' => true, + 'lifestyle' => true, + 'lighting' => true, + 'like' => true, + 'lilly' => true, + 'limited' => true, + 'limo' => true, + 'lincoln' => true, + 'linde' => true, + 'link' => true, + 'lipsy' => true, + 'live' => true, + 'living' => true, + 'lixil' => true, + 'loan' => true, + 'loans' => true, + 'locker' => true, + 'locus' => true, + 'loft' => true, + 'lol' => true, + 'london' => true, + 'lotte' => true, + 'lotto' => true, + 'love' => true, + 'lpl' => true, + 'lplfinancial' => true, + 'ltd' => true, + 'ltda' => true, + 'lundbeck' => true, + 'lupin' => true, + 'luxe' => true, + 'luxury' => true, + 'macys' => true, + 'madrid' => true, + 'maif' => true, + 'maison' => true, + 'makeup' => true, + 'man' => true, + 'management' => true, + 'mango' => true, + 'market' => true, + 'marketing' => true, + 'markets' => true, + 'marriott' => true, + 'marshalls' => true, + 'maserati' => true, + 'mattel' => true, + 'mba' => true, + 'mcd' => true, + 'mcdonalds' => true, + 'mckinsey' => true, + 'med' => true, + 'media' => true, + 'meet' => true, + 'melbourne' => true, + 'meme' => true, + 'memorial' => true, + 'men' => true, + 'menu' => true, + 'meo' => true, + 'metlife' => true, + 'miami' => true, + 'microsoft' => true, + 'mini' => true, + 'mint' => true, + 'mit' => true, + 'mitsubishi' => true, + 'mlb' => true, + 'mls' => true, + 'mma' => true, + 'mnet' => true, + 'mobily' => true, + 'moda' => true, + 'moe' => true, + 'moi' => true, + 'mom' => true, + 'monash' => true, + 'money' => true, + 'monster' => true, + 'montblanc' => true, + 'mopar' => true, + 'mormon' => true, + 'mortgage' => true, + 'moscow' => true, + 'moto' => true, + 'motorcycles' => true, + 'mov' => true, + 'movie' => true, + 'movistar' => true, + 'msd' => true, + 'mtn' => true, + 'mtpc' => true, + 'mtr' => true, + 'multichoice' => true, + 'mutual' => true, + 'mutuelle' => true, + 'mzansimagic' => true, + 'nab' => true, + 'nadex' => true, + 'nagoya' => true, + 'naspers' => true, + 'nationwide' => true, + 'natura' => true, + 'navy' => true, + 'nba' => true, + 'nec' => true, + 'netbank' => true, + 'netflix' => true, + 'network' => true, + 'neustar' => true, + 'new' => true, + 'newholland' => true, + 'news' => true, + 'next' => true, + 'nextdirect' => true, + 'nexus' => true, + 'nfl' => true, + 'ngo' => true, + 'nhk' => true, + 'nico' => true, + 'nike' => true, + 'nikon' => true, + 'ninja' => true, + 'nissan' => true, + 'nissay' => true, + 'nokia' => true, + 'northwesternmutual' => true, + 'norton' => true, + 'now' => true, + 'nowruz' => true, + 'nowtv' => true, + 'nra' => true, + 'nrw' => true, + 'ntt' => true, + 'nyc' => true, + 'obi' => true, + 'observer' => true, + 'off' => true, + 'office' => true, + 'okinawa' => true, + 'olayan' => true, + 'olayangroup' => true, + 'oldnavy' => true, + 'ollo' => true, + 'omega' => true, + 'one' => true, + 'ong' => true, + 'onl' => true, + 'online' => true, + 'onyourside' => true, + 'ooo' => true, + 'open' => true, + 'oracle' => true, + 'orange' => true, + 'organic' => true, + 'orientexpress' => true, + 'origins' => true, + 'osaka' => true, + 'otsuka' => true, + 'ott' => true, + 'ovh' => true, + 'page' => true, + 'pamperedchef' => true, + 'panasonic' => true, + 'panerai' => true, + 'paris' => true, + 'pars' => true, + 'partners' => true, + 'parts' => true, + 'party' => true, + 'passagens' => true, + 'pay' => true, + 'payu' => true, + 'pccw' => true, + 'pet' => true, + 'pfizer' => true, + 'pharmacy' => true, + 'philips' => true, + 'photo' => true, + 'photography' => true, + 'photos' => true, + 'physio' => true, + 'piaget' => true, + 'pics' => true, + 'pictet' => true, + 'pictures' => true, + 'pid' => true, + 'pin' => true, + 'ping' => true, + 'pink' => true, + 'pioneer' => true, + 'pizza' => true, + 'place' => true, + 'play' => true, + 'playstation' => true, + 'plumbing' => true, + 'plus' => true, + 'pnc' => true, + 'pohl' => true, + 'poker' => true, + 'politie' => true, + 'porn' => true, + 'pramerica' => true, + 'praxi' => true, + 'press' => true, + 'prime' => true, + 'prod' => true, + 'productions' => true, + 'prof' => true, + 'progressive' => true, + 'promo' => true, + 'properties' => true, + 'property' => true, + 'protection' => true, + 'pru' => true, + 'prudential' => true, + 'pub' => true, + 'pwc' => true, + 'qpon' => true, + 'quebec' => true, + 'quest' => true, + 'qvc' => true, + 'racing' => true, + 'raid' => true, + 'read' => true, + 'realestate' => true, + 'realtor' => true, + 'realty' => true, + 'recipes' => true, + 'red' => true, + 'redstone' => true, + 'redumbrella' => true, + 'rehab' => true, + 'reise' => true, + 'reisen' => true, + 'reit' => true, + 'reliance' => true, + 'ren' => true, + 'rent' => true, + 'rentals' => true, + 'repair' => true, + 'report' => true, + 'republican' => true, + 'rest' => true, + 'restaurant' => true, + 'review' => true, + 'reviews' => true, + 'rexroth' => true, + 'rich' => true, + 'richardli' => true, + 'ricoh' => true, + 'rightathome' => true, + 'ril' => true, + 'rio' => true, + 'rip' => true, + 'rmit' => true, + 'rocher' => true, + 'rocks' => true, + 'rodeo' => true, + 'rogers' => true, + 'room' => true, + 'rsvp' => true, + 'ruhr' => true, + 'run' => true, + 'rwe' => true, + 'ryukyu' => true, + 'saarland' => true, + 'safe' => true, + 'safety' => true, + 'sakura' => true, + 'sale' => true, + 'salon' => true, + 'samsclub' => true, + 'samsung' => true, + 'sandvik' => true, + 'sandvikcoromant' => true, + 'sanofi' => true, + 'sap' => true, + 'sapo' => true, + 'sarl' => true, + 'sas' => true, + 'save' => true, + 'saxo' => true, + 'sbi' => true, + 'sbs' => true, + 'sca' => true, + 'scb' => true, + 'schaeffler' => true, + 'schmidt' => true, + 'scholarships' => true, + 'school' => true, + 'schule' => true, + 'schwarz' => true, + 'science' => true, + 'scjohnson' => true, + 'scor' => true, + 'scot' => true, + 'seat' => true, + 'secure' => true, + 'security' => true, + 'seek' => true, + 'select' => true, + 'sener' => true, + 'services' => true, + 'ses' => true, + 'seven' => true, + 'sew' => true, + 'sex' => true, + 'sexy' => true, + 'sfr' => true, + 'shangrila' => true, + 'sharp' => true, + 'shaw' => true, + 'shell' => true, + 'shia' => true, + 'shiksha' => true, + 'shoes' => true, + 'shouji' => true, + 'show' => true, + 'showtime' => true, + 'shriram' => true, + 'silk' => true, + 'sina' => true, + 'singles' => true, + 'site' => true, + 'ski' => true, + 'skin' => true, + 'sky' => true, + 'skype' => true, + 'sling' => true, + 'smart' => true, + 'smile' => true, + 'sncf' => true, + 'soccer' => true, + 'social' => true, + 'softbank' => true, + 'software' => true, + 'sohu' => true, + 'solar' => true, + 'solutions' => true, + 'song' => true, + 'sony' => true, + 'soy' => true, + 'space' => true, + 'spiegel' => true, + 'spot' => true, + 'spreadbetting' => true, + 'srl' => true, + 'srt' => true, + 'stada' => true, + 'staples' => true, + 'star' => true, + 'starhub' => true, + 'statebank' => true, + 'statefarm' => true, + 'statoil' => true, + 'stc' => true, + 'stcgroup' => true, + 'stockholm' => true, + 'storage' => true, + 'store' => true, + 'studio' => true, + 'study' => true, + 'style' => true, + 'sucks' => true, + 'supersport' => true, + 'supplies' => true, + 'supply' => true, + 'support' => true, + 'surf' => true, + 'surgery' => true, + 'suzuki' => true, + 'swatch' => true, + 'swiftcover' => true, + 'swiss' => true, + 'sydney' => true, + 'symantec' => true, + 'systems' => true, + 'tab' => true, + 'taipei' => true, + 'talk' => true, + 'taobao' => true, + 'target' => true, + 'tatamotors' => true, + 'tatar' => true, + 'tattoo' => true, + 'tax' => true, + 'taxi' => true, + 'tci' => true, + 'tdk' => true, + 'team' => true, + 'tech' => true, + 'technology' => true, + 'telecity' => true, + 'telefonica' => true, + 'temasek' => true, + 'tennis' => true, + 'teva' => true, + 'thd' => true, + 'theater' => true, + 'theatre' => true, + 'theguardian' => true, + 'tiaa' => true, + 'tickets' => true, + 'tienda' => true, + 'tiffany' => true, + 'tips' => true, + 'tires' => true, + 'tirol' => true, + 'tjmaxx' => true, + 'tjx' => true, + 'tkmaxx' => true, + 'tmall' => true, + 'today' => true, + 'tokyo' => true, + 'tools' => true, + 'top' => true, + 'toray' => true, + 'toshiba' => true, + 'total' => true, + 'tours' => true, + 'town' => true, + 'toyota' => true, + 'toys' => true, + 'trade' => true, + 'trading' => true, + 'training' => true, + 'travelchannel' => true, + 'travelers' => true, + 'travelersinsurance' => true, + 'trust' => true, + 'trv' => true, + 'tube' => true, + 'tui' => true, + 'tunes' => true, + 'tushu' => true, + 'tvs' => true, + 'ubank' => true, + 'ubs' => true, + 'uconnect' => true, + 'unicom' => true, + 'university' => true, + 'uno' => true, + 'uol' => true, + 'ups' => true, + 'vacations' => true, + 'vana' => true, + 'vanguard' => true, + 'vegas' => true, + 'ventures' => true, + 'verisign' => true, + 'versicherung' => true, + 'vet' => true, + 'viajes' => true, + 'video' => true, + 'vig' => true, + 'viking' => true, + 'villas' => true, + 'vin' => true, + 'vip' => true, + 'virgin' => true, + 'visa' => true, + 'vision' => true, + 'vista' => true, + 'vistaprint' => true, + 'viva' => true, + 'vivo' => true, + 'vlaanderen' => true, + 'vodka' => true, + 'volkswagen' => true, + 'volvo' => true, + 'vote' => true, + 'voting' => true, + 'voto' => true, + 'voyage' => true, + 'vuelos' => true, + 'wales' => true, + 'walmart' => true, + 'walter' => true, + 'wang' => true, + 'wanggou' => true, + 'warman' => true, + 'watch' => true, + 'watches' => true, + 'weather' => true, + 'weatherchannel' => true, + 'webcam' => true, + 'weber' => true, + 'website' => true, + 'wed' => true, + 'wedding' => true, + 'weibo' => true, + 'weir' => true, + 'whoswho' => true, + 'wien' => true, + 'wiki' => true, + 'williamhill' => true, + 'win' => true, + 'windows' => true, + 'wine' => true, + 'winners' => true, + 'wme' => true, + 'wolterskluwer' => true, + 'woodside' => true, + 'work' => true, + 'works' => true, + 'world' => true, + 'wow' => true, + 'wtc' => true, + 'wtf' => true, + 'xbox' => true, + 'xerox' => true, + 'xfinity' => true, + 'xihuan' => true, + 'xin' => true, + 'कॉम' => true, + 'セール' => true, + '佛山' => true, + '慈善' => true, + '集团' => true, + '在线' => true, + '大众汽车' => true, + '点看' => true, + 'คอม' => true, + '八卦' => true, + 'موقع' => true, + '一号店' => true, + '公益' => true, + '公司' => true, + '香格里拉' => true, + '网站' => true, + '移动' => true, + '我爱你' => true, + 'москва' => true, + 'католик' => true, + 'онлайн' => true, + 'сайт' => true, + '联通' => true, + 'קום' => true, + '时尚' => true, + '微博' => true, + '淡马锡' => true, + 'ファッション' => true, + 'орг' => true, + 'नेट' => true, + 'ストア' => true, + '삼성' => true, + '商标' => true, + '商店' => true, + '商城' => true, + 'дети' => true, + 'ポイント' => true, + '新闻' => true, + '工行' => true, + '家電' => true, + 'كوم' => true, + '中文网' => true, + '中信' => true, + '娱乐' => true, + '谷歌' => true, + '電訊盈科' => true, + '购物' => true, + 'クラウド' => true, + '通販' => true, + '网店' => true, + 'संगठन' => true, + '餐厅' => true, + '网络' => true, + 'ком' => true, + '诺基亚' => true, + '食品' => true, + '飞利浦' => true, + '手表' => true, + '手机' => true, + 'ارامكو' => true, + 'العليان' => true, + 'اتصالات' => true, + 'بازار' => true, + 'موبايلي' => true, + 'ابوظبي' => true, + 'كاثوليك' => true, + 'همراه' => true, + '닷컴' => true, + '政府' => true, + 'شبكة' => true, + 'بيتك' => true, + 'عرب' => true, + '机构' => true, + '组织机构' => true, + '健康' => true, + 'рус' => true, + '珠宝' => true, + '大拿' => true, + 'みんな' => true, + 'グーグル' => true, + '世界' => true, + '書籍' => true, + '网址' => true, + '닷넷' => true, + 'コム' => true, + '天主教' => true, + '游戏' => true, + 'vermögensberater' => true, + 'vermögensberatung' => true, + '企业' => true, + '信息' => true, + '嘉里大酒店' => true, + '嘉里' => true, + '广东' => true, + '政务' => true, + 'xperia' => true, + 'xyz' => true, + 'yachts' => true, + 'yahoo' => true, + 'yamaxun' => true, + 'yandex' => true, + 'yodobashi' => true, + 'yoga' => true, + 'yokohama' => true, + 'you' => true, + 'youtube' => true, + 'yun' => true, + 'zappos' => true, + 'zara' => true, + 'zero' => true, + 'zip' => true, + 'zippo' => true, + 'zone' => true, + 'zuerich' => true +); +?> \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/Mail_Mime/Mail/mime.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/Mail_Mime/Mail/mime.php new file mode 100644 index 0000000..98f7206 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/Mail_Mime/Mail/mime.php @@ -0,0 +1,1626 @@ += 5 + * + * LICENSE: This LICENSE is in the BSD license style. + * Copyright (c) 2002-2003, Richard Heyes + * Copyright (c) 2003-2006, PEAR + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of the authors, nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * @category Mail + * @package Mail_Mime + * @author Richard Heyes + * @author Tomas V.V. Cox + * @author Cipriano Groenendal + * @author Sean Coates + * @author Aleksander Machniak + * @copyright 2003-2006 PEAR + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: @package_version@ + * @link http://pear.php.net/package/Mail_mime + * + * This class is based on HTML Mime Mail class from + * Richard Heyes which was based also + * in the mime_mail.class by Tobias Ratschiller + * and Sascha Schumann + */ + + +require_once 'PEAR.php'; +require_once 'Mail/mimePart.php'; + + +/** + * The Mail_Mime class provides an OO interface to create MIME + * enabled email messages. This way you can create emails that + * contain plain-text bodies, HTML bodies, attachments, inline + * images and specific headers. + * + * @category Mail + * @package Mail_Mime + * @author Richard Heyes + * @author Tomas V.V. Cox + * @author Cipriano Groenendal + * @author Sean Coates + * @copyright 2003-2006 PEAR + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: @package_version@ + * @link http://pear.php.net/package/Mail_mime + */ +class Mail_mime +{ + /** + * Contains the plain text part of the email + * + * @var string + */ + protected $txtbody; + + /** + * Contains the html part of the email + * + * @var string + */ + protected $htmlbody; + + /** + * Contains the text/calendar part of the email + * + * @var string + */ + protected $calbody; + + /** + * list of the attached images + * + * @var array + */ + protected $html_images = array(); + + /** + * list of the attachements + * + * @var array + */ + protected $parts = array(); + + /** + * Headers for the mail + * + * @var array + */ + protected $headers = array(); + + /** + * Build parameters + * + * @var array + */ + protected $build_params = array( + // What encoding to use for the headers + // Options: quoted-printable or base64 + 'head_encoding' => 'quoted-printable', + // What encoding to use for plain text + // Options: 7bit, 8bit, base64, or quoted-printable + 'text_encoding' => 'quoted-printable', + // What encoding to use for html + // Options: 7bit, 8bit, base64, or quoted-printable + 'html_encoding' => 'quoted-printable', + // What encoding to use for calendar part + // Options: 7bit, 8bit, base64, or quoted-printable + 'calendar_encoding' => 'quoted-printable', + // The character set to use for html + 'html_charset' => 'ISO-8859-1', + // The character set to use for text + 'text_charset' => 'ISO-8859-1', + // The character set to use for calendar part + 'calendar_charset' => 'UTF-8', + // The character set to use for headers + 'head_charset' => 'ISO-8859-1', + // End-of-line sequence + 'eol' => "\r\n", + // Delay attachment files IO until building the message + 'delay_file_io' => false, + // Default calendar method + 'calendar_method' => 'request', + // multipart part preamble (RFC2046 5.1.1) + 'preamble' => '', + ); + + + /** + * Constructor function + * + * @param mixed $params Build parameters that change the way the email + * is built. Should be an associative array. + * See $_build_params. + * + * @return void + */ + public function __construct($params = array()) + { + // Backward-compatible EOL setting + if (is_string($params)) { + $this->build_params['eol'] = $params; + } else if (defined('MAIL_MIME_CRLF') && !isset($params['eol'])) { + $this->build_params['eol'] = MAIL_MIME_CRLF; + } + + // Update build parameters + if (!empty($params) && is_array($params)) { + while (list($key, $value) = each($params)) { + $this->build_params[$key] = $value; + } + } + } + + /** + * Set build parameter value + * + * @param string $name Parameter name + * @param string $value Parameter value + * + * @return void + * @since 1.6.0 + */ + public function setParam($name, $value) + { + $this->build_params[$name] = $value; + } + + /** + * Get build parameter value + * + * @param string $name Parameter name + * + * @return mixed Parameter value + * @since 1.6.0 + */ + public function getParam($name) + { + return isset($this->build_params[$name]) ? $this->build_params[$name] : null; + } + + /** + * Accessor function to set the body text. Body text is used if + * it's not an html mail being sent or else is used to fill the + * text/plain part that emails clients who don't support + * html should show. + * + * @param string $data Either a string or the file name with the contents + * @param bool $isfile If true the first param should be treated + * as a file name, else as a string (default) + * @param bool $append If true the text or file is appended to + * the existing body, else the old body is + * overwritten + * + * @return mixed True on success or PEAR_Error object + */ + public function setTXTBody($data, $isfile = false, $append = false) + { + return $this->setBody('txtbody', $data, $isfile, $append); + } + + /** + * Get message text body + * + * @return string Text body + * @since 1.6.0 + */ + public function getTXTBody() + { + return $this->txtbody; + } + + /** + * Adds a html part to the mail. + * + * @param string $data Either a string or the file name with the contents + * @param bool $isfile A flag that determines whether $data is a + * filename, or a string(false, default) + * + * @return bool True on success or PEAR_Error object + */ + public function setHTMLBody($data, $isfile = false) + { + return $this->setBody('htmlbody', $data, $isfile); + } + + /** + * Get message HTML body + * + * @return string HTML body + * @since 1.6.0 + */ + public function getHTMLBody() + { + return $this->htmlbody; + } + + /** + * Function to set a body of text/calendar part (not attachment) + * + * @param string $data Either a string or the file name with the contents + * @param bool $isfile If true the first param should be treated + * as a file name, else as a string (default) + * @param bool $append If true the text or file is appended to + * the existing body, else the old body is + * overwritten + * @param string $method iCalendar object method + * @param string $charset iCalendar character set + * @param string $encoding Transfer encoding + * + * @return mixed True on success or PEAR_Error object + * @since 1.9.0 + */ + public function setCalendarBody($data, $isfile = false, $append = false, + $method = 'request', $charset = 'UTF-8', $encoding = 'quoted-printable' + ) { + $result = $this->setBody('calbody', $data, $isfile, $append); + + if ($result === true) { + $this->build_params['calendar_method'] = $method; + $this->build_params['calendar_charset'] = $charset; + $this->build_params['calendar_encoding'] = $encoding; + } + } + + /** + * Get body of calendar part + * + * @return string Calendar part body + * @since 1.9.0 + */ + public function getCalendarBody() + { + return $this->calbody; + } + + /** + * Adds an image to the list of embedded images. + * Images added this way will be added as related parts of the HTML message. + * + * To correctly match the HTML image with the related attachment + * HTML should refer to it by a filename (specified in $file or $name + * arguments) or by cid: (specified in $content_id arg). + * + * @param string $file The image file name OR image data itself + * @param string $c_type The content type + * @param string $name The filename of the image. Used to find + * the image in HTML content. + * @param bool $isfile Whether $file is a filename or not. + * Defaults to true + * @param string $content_id Desired Content-ID of MIME part + * Defaults to generated unique ID + * + * @return bool True on success + */ + public function addHTMLImage($file, + $c_type = 'application/octet-stream', + $name = '', + $isfile = true, + $content_id = null + ) { + $bodyfile = null; + + if ($isfile) { + // Don't load file into memory + if ($this->build_params['delay_file_io']) { + $filedata = null; + $bodyfile = $file; + } else { + if (self::isError($filedata = $this->file2str($file))) { + return $filedata; + } + } + + $filename = $name ? $name : $file; + } else { + $filedata = $file; + $filename = $name; + } + + if (!$content_id) { + $content_id = preg_replace('/[^0-9a-zA-Z]/', '', uniqid(time(), true)); + } + + $this->html_images[] = array( + 'body' => $filedata, + 'body_file' => $bodyfile, + 'name' => $filename, + 'c_type' => $c_type, + 'cid' => $content_id + ); + + return true; + } + + /** + * Adds a file to the list of attachments. + * + * @param mixed $file The file name or the file contents itself, + * it can be also Mail_mimePart object + * @param string $c_type The content type + * @param string $name The filename of the attachment + * Only use if $file is the contents + * @param bool $isfile Whether $file is a filename or not. Defaults to true + * @param string $encoding The type of encoding to use. Defaults to base64. + * Possible values: 7bit, 8bit, base64 or quoted-printable. + * @param string $disposition The content-disposition of this file + * Defaults to attachment. + * Possible values: attachment, inline. + * @param string $charset The character set of attachment's content. + * @param string $language The language of the attachment + * @param string $location The RFC 2557.4 location of the attachment + * @param string $n_encoding Encoding of the attachment's name in Content-Type + * By default filenames are encoded using RFC2231 method + * Here you can set RFC2047 encoding (quoted-printable + * or base64) instead + * @param string $f_encoding Encoding of the attachment's filename + * in Content-Disposition header. + * @param string $description Content-Description header + * @param string $h_charset The character set of the headers e.g. filename + * If not specified, $charset will be used + * @param array $add_headers Additional part headers. Array keys can be in form + * of : + * + * @return mixed True on success or PEAR_Error object + */ + public function addAttachment($file, + $c_type = 'application/octet-stream', + $name = '', + $isfile = true, + $encoding = 'base64', + $disposition = 'attachment', + $charset = '', + $language = '', + $location = '', + $n_encoding = null, + $f_encoding = null, + $description = '', + $h_charset = null, + $add_headers = array() + ) { + if ($file instanceof Mail_mimePart) { + $this->parts[] = $file; + return true; + } + + $bodyfile = null; + + if ($isfile) { + // Don't load file into memory + if ($this->build_params['delay_file_io']) { + $filedata = null; + $bodyfile = $file; + } else { + if (self::isError($filedata = $this->file2str($file))) { + return $filedata; + } + } + // Force the name the user supplied, otherwise use $file + $filename = ($name ? $name : $this->basename($file)); + } else { + $filedata = $file; + $filename = $name; + } + + if (!strlen($filename)) { + $msg = "The supplied filename for the attachment can't be empty"; + return self::raiseError($msg); + } + + $this->parts[] = array( + 'body' => $filedata, + 'body_file' => $bodyfile, + 'name' => $filename, + 'c_type' => $c_type, + 'charset' => $charset, + 'encoding' => $encoding, + 'language' => $language, + 'location' => $location, + 'disposition' => $disposition, + 'description' => $description, + 'add_headers' => $add_headers, + 'name_encoding' => $n_encoding, + 'filename_encoding' => $f_encoding, + 'headers_charset' => $h_charset, + ); + + return true; + } + + /** + * Checks if the current message has many parts + * + * @return bool True if the message has many parts, False otherwise. + * @since 1.9.0 + */ + public function isMultipart() + { + return count($this->parts) > 0 || count($this->html_images) > 0 + || (strlen($this->htmlbody) > 0 && strlen($this->txtbody) > 0); + } + + /** + * Get the contents of the given file name as string + * + * @param string $file_name Path of file to process + * + * @return string Contents of $file_name + */ + protected function file2str($file_name) + { + // Check state of file and raise an error properly + if (!file_exists($file_name)) { + return self::raiseError('File not found: ' . $file_name); + } + if (!is_file($file_name)) { + return self::raiseError('Not a regular file: ' . $file_name); + } + if (!is_readable($file_name)) { + return self::raiseError('File is not readable: ' . $file_name); + } + + // Temporarily reset magic_quotes_runtime and read file contents + if ($magic_quote_setting = get_magic_quotes_runtime()) { + @ini_set('magic_quotes_runtime', 0); + } + + $cont = file_get_contents($file_name); + + if ($magic_quote_setting) { + @ini_set('magic_quotes_runtime', $magic_quote_setting); + } + + return $cont; + } + + /** + * Adds a text subpart to the mimePart object and + * returns it during the build process. + * + * @param mixed $obj The object to add the part to, or + * anything else if a new object is to be created. + * + * @return object The text mimePart object + */ + protected function addTextPart($obj = null) + { + return $this->addBodyPart($obj, $this->txtbody, 'text/plain', 'text'); + } + + /** + * Adds a html subpart to the mimePart object and + * returns it during the build process. + * + * @param mixed $obj The object to add the part to, or + * anything else if a new object is to be created. + * + * @return object The html mimePart object + */ + protected function addHtmlPart($obj = null) + { + return $this->addBodyPart($obj, $this->htmlbody, 'text/html', 'html'); + } + + /** + * Adds a calendar subpart to the mimePart object and + * returns it during the build process. + * + * @param mixed $obj The object to add the part to, or + * anything else if a new object is to be created. + * + * @return object The text mimePart object + */ + protected function addCalendarPart($obj = null) + { + $ctype = 'text/calendar; method='. $this->build_params['calendar_method']; + + return $this->addBodyPart($obj, $this->calbody, $ctype, 'calendar'); + } + + /** + * Creates a new mimePart object, using multipart/mixed as + * the initial content-type and returns it during the + * build process. + * + * @param array $params Additional part parameters + * + * @return object The multipart/mixed mimePart object + */ + protected function addMixedPart($params = array()) + { + $params['content_type'] = 'multipart/mixed'; + $params['eol'] = $this->build_params['eol']; + + // Create empty multipart/mixed Mail_mimePart object to return + return new Mail_mimePart('', $params); + } + + /** + * Adds a multipart/alternative part to a mimePart + * object (or creates one), and returns it during + * the build process. + * + * @param mixed $obj The object to add the part to, or + * anything else if a new object is to be created. + * + * @return object The multipart/mixed mimePart object + */ + protected function addAlternativePart($obj = null) + { + $params['content_type'] = 'multipart/alternative'; + $params['eol'] = $this->build_params['eol']; + + if (is_object($obj)) { + $ret = $obj->addSubpart('', $params); + } else { + $ret = new Mail_mimePart('', $params); + } + + return $ret; + } + + /** + * Adds a multipart/related part to a mimePart + * object (or creates one), and returns it during + * the build process. + * + * @param mixed $obj The object to add the part to, or + * anything else if a new object is to be created + * + * @return object The multipart/mixed mimePart object + */ + protected function addRelatedPart($obj = null) + { + $params['content_type'] = 'multipart/related'; + $params['eol'] = $this->build_params['eol']; + + if (is_object($obj)) { + $ret = $obj->addSubpart('', $params); + } else { + $ret = new Mail_mimePart('', $params); + } + + return $ret; + } + + /** + * Adds an html image subpart to a mimePart object + * and returns it during the build process. + * + * @param object $obj The mimePart to add the image to + * @param array $value The image information + * + * @return object The image mimePart object + */ + protected function addHtmlImagePart($obj, $value) + { + $params['content_type'] = $value['c_type']; + $params['encoding'] = 'base64'; + $params['disposition'] = 'inline'; + $params['filename'] = $value['name']; + $params['cid'] = $value['cid']; + $params['body_file'] = $value['body_file']; + $params['eol'] = $this->build_params['eol']; + + if (!empty($value['name_encoding'])) { + $params['name_encoding'] = $value['name_encoding']; + } + if (!empty($value['filename_encoding'])) { + $params['filename_encoding'] = $value['filename_encoding']; + } + + return $obj->addSubpart($value['body'], $params); + } + + /** + * Adds an attachment subpart to a mimePart object + * and returns it during the build process. + * + * @param object $obj The mimePart to add the image to + * @param mixed $value The attachment information array or Mail_mimePart object + * + * @return object The image mimePart object + */ + protected function addAttachmentPart($obj, $value) + { + if ($value instanceof Mail_mimePart) { + return $obj->addSubpart($value); + } + + $params['eol'] = $this->build_params['eol']; + $params['filename'] = $value['name']; + $params['encoding'] = $value['encoding']; + $params['content_type'] = $value['c_type']; + $params['body_file'] = $value['body_file']; + $params['disposition'] = isset($value['disposition']) ? + $value['disposition'] : 'attachment'; + + // content charset + if (!empty($value['charset'])) { + $params['charset'] = $value['charset']; + } + // headers charset (filename, description) + if (!empty($value['headers_charset'])) { + $params['headers_charset'] = $value['headers_charset']; + } + if (!empty($value['language'])) { + $params['language'] = $value['language']; + } + if (!empty($value['location'])) { + $params['location'] = $value['location']; + } + if (!empty($value['name_encoding'])) { + $params['name_encoding'] = $value['name_encoding']; + } + if (!empty($value['filename_encoding'])) { + $params['filename_encoding'] = $value['filename_encoding']; + } + if (!empty($value['description'])) { + $params['description'] = $value['description']; + } + if (is_array($value['add_headers'])) { + $params['headers'] = $value['add_headers']; + } + + return $obj->addSubpart($value['body'], $params); + } + + /** + * Returns the complete e-mail, ready to send using an alternative + * mail delivery method. Note that only the mailpart that is made + * with Mail_Mime is created. This means that, + * YOU WILL HAVE NO TO: HEADERS UNLESS YOU SET IT YOURSELF + * using the $headers parameter! + * + * @param string $separation The separation between these two parts. + * @param array $params The Build parameters passed to the + * get() function. See get() for more info. + * @param array $headers The extra headers that should be passed + * to the headers() method. + * See that function for more info. + * @param bool $overwrite Overwrite the existing headers with new. + * + * @return mixed The complete e-mail or PEAR error object + */ + public function getMessage($separation = null, $params = null, $headers = null, + $overwrite = false + ) { + if ($separation === null) { + $separation = $this->build_params['eol']; + } + + $body = $this->get($params); + + if (self::isError($body)) { + return $body; + } + + return $this->txtHeaders($headers, $overwrite) . $separation . $body; + } + + /** + * Returns the complete e-mail body, ready to send using an alternative + * mail delivery method. + * + * @param array $params The Build parameters passed to the + * get() method. See get() for more info. + * + * @return mixed The e-mail body or PEAR error object + * @since 1.6.0 + */ + public function getMessageBody($params = null) + { + return $this->get($params, null, true); + } + + /** + * Writes (appends) the complete e-mail into file. + * + * @param string $filename Output file location + * @param array $params The Build parameters passed to the + * get() method. See get() for more info. + * @param array $headers The extra headers that should be passed + * to the headers() function. + * See that function for more info. + * @param bool $overwrite Overwrite the existing headers with new. + * + * @return mixed True or PEAR error object + * @since 1.6.0 + */ + public function saveMessage($filename, $params = null, $headers = null, $overwrite = false) + { + // Check state of file and raise an error properly + if (file_exists($filename) && !is_writable($filename)) { + return self::raiseError('File is not writable: ' . $filename); + } + + // Temporarily reset magic_quotes_runtime and read file contents + if ($magic_quote_setting = get_magic_quotes_runtime()) { + @ini_set('magic_quotes_runtime', 0); + } + + if (!($fh = fopen($filename, 'ab'))) { + return self::raiseError('Unable to open file: ' . $filename); + } + + // Write message headers into file (skipping Content-* headers) + $head = $this->txtHeaders($headers, $overwrite, true); + if (fwrite($fh, $head) === false) { + return self::raiseError('Error writing to file: ' . $filename); + } + + fclose($fh); + + if ($magic_quote_setting) { + @ini_set('magic_quotes_runtime', $magic_quote_setting); + } + + // Write the rest of the message into file + $res = $this->get($params, $filename); + + return $res ? $res : true; + } + + /** + * Writes (appends) the complete e-mail body into file or stream. + * + * @param mixed $filename Output filename or file pointer where to save + * the message instead of returning it + * @param array $params The Build parameters passed to the + * get() method. See get() for more info. + * + * @return mixed True or PEAR error object + * @since 1.6.0 + */ + public function saveMessageBody($filename, $params = null) + { + if (!is_resource($filename)) { + // Check state of file and raise an error properly + if (!file_exists($filename) || !is_writable($filename)) { + return self::raiseError('File is not writable: ' . $filename); + } + + if (!($fh = fopen($filename, 'ab'))) { + return self::raiseError('Unable to open file: ' . $filename); + } + } else { + $fh = $filename; + } + + // Temporarily reset magic_quotes_runtime and read file contents + if ($magic_quote_setting = get_magic_quotes_runtime()) { + @ini_set('magic_quotes_runtime', 0); + } + + // Write the rest of the message into file + $res = $this->get($params, $fh, true); + + if (!is_resource($filename)) { + fclose($fh); + } + + if ($magic_quote_setting) { + @ini_set('magic_quotes_runtime', $magic_quote_setting); + } + + return $res ? $res : true; + } + + /** + * Builds the multipart message from the list ($this->parts) and + * returns the mime content. + * + * @param array $params Build parameters that change the way the email + * is built. Should be associative. See $_build_params. + * @param mixed $filename Output filename or file pointer where to save + * the message instead of returning it + * @param boolean $skip_head True if you want to return/save only the message + * without headers + * + * @return mixed The MIME message content string, null or PEAR error object + */ + public function get($params = null, $filename = null, $skip_head = false) + { + if (isset($params)) { + while (list($key, $value) = each($params)) { + $this->build_params[$key] = $value; + } + } + + if (isset($this->headers['From'])) { + // Bug #11381: Illegal characters in domain ID + if (preg_match('#(@[0-9a-zA-Z\-\.]+)#', $this->headers['From'], $matches)) { + $domainID = $matches[1]; + } else { + $domainID = '@localhost'; + } + + foreach ($this->html_images as $i => $img) { + $cid = $this->html_images[$i]['cid']; + if (!preg_match('#'.preg_quote($domainID).'$#', $cid)) { + $this->html_images[$i]['cid'] = $cid . $domainID; + } + } + } + + if (count($this->html_images) && isset($this->htmlbody)) { + foreach ($this->html_images as $key => $value) { + $rval = preg_quote($value['name'], '#'); + $regex = array( + '#(\s)((?i)src|background|href(?-i))\s*=\s*(["\']?)' . $rval . '\3#', + '#(?i)url(?-i)\(\s*(["\']?)' . $rval . '\1\s*\)#', + ); + + $rep = array( + '\1\2=\3cid:' . $value['cid'] .'\3', + 'url(\1cid:' . $value['cid'] . '\1)', + ); + + $this->htmlbody = preg_replace($regex, $rep, $this->htmlbody); + $this->html_images[$key]['name'] + = $this->basename($this->html_images[$key]['name']); + } + } + + $this->checkParams(); + + $attachments = count($this->parts) > 0; + $html_images = count($this->html_images) > 0; + $html = strlen($this->htmlbody) > 0; + $calendar = strlen($this->calbody) > 0; + $has_text = strlen($this->txtbody) > 0; + $text = !$html && $has_text; + $mixed_params = array('preamble' => $this->build_params['preamble']); + + switch (true) { + case $calendar && !$attachments && !$text && !$html: + $message = $this->addCalendarPart(); + break; + + case $calendar && !$attachments: + $message = $this->addAlternativePart($mixed_params); + if ($has_text) { + $this->addTextPart($message); + } + if ($html) { + $this->addHtmlPart($message); + } + $this->addCalendarPart($message); + break; + + case $text && !$attachments: + $message = $this->addTextPart(); + break; + + case !$text && !$html && $attachments: + $message = $this->addMixedPart($mixed_params); + for ($i = 0; $i < count($this->parts); $i++) { + $this->addAttachmentPart($message, $this->parts[$i]); + } + break; + + case $text && $attachments: + $message = $this->addMixedPart($mixed_params); + $this->addTextPart($message); + for ($i = 0; $i < count($this->parts); $i++) { + $this->addAttachmentPart($message, $this->parts[$i]); + } + break; + + case $html && !$attachments && !$html_images: + if (isset($this->txtbody)) { + $message = $this->addAlternativePart(); + $this->addTextPart($message); + $this->addHtmlPart($message); + } else { + $message = $this->addHtmlPart(); + } + break; + + case $html && !$attachments && $html_images: + // * Content-Type: multipart/alternative; + // * text + // * Content-Type: multipart/related; + // * html + // * image... + if (isset($this->txtbody)) { + $message = $this->addAlternativePart(); + $this->addTextPart($message); + + $ht = $this->addRelatedPart($message); + $this->addHtmlPart($ht); + for ($i = 0; $i < count($this->html_images); $i++) { + $this->addHtmlImagePart($ht, $this->html_images[$i]); + } + } else { + // * Content-Type: multipart/related; + // * html + // * image... + $message = $this->addRelatedPart(); + $this->addHtmlPart($message); + for ($i = 0; $i < count($this->html_images); $i++) { + $this->addHtmlImagePart($message, $this->html_images[$i]); + } + } + /* + // #13444, #9725: the code below was a non-RFC compliant hack + // * Content-Type: multipart/related; + // * Content-Type: multipart/alternative; + // * text + // * html + // * image... + $message = $this->addRelatedPart(); + if (isset($this->txtbody)) { + $alt = $this->addAlternativePart($message); + $this->addTextPart($alt); + $this->addHtmlPart($alt); + } else { + $this->addHtmlPart($message); + } + for ($i = 0; $i < count($this->html_images); $i++) { + $this->addHtmlImagePart($message, $this->html_images[$i]); + } + */ + break; + + case $html && $attachments && !$html_images: + $message = $this->addMixedPart($mixed_params); + if (isset($this->txtbody)) { + $alt = $this->addAlternativePart($message); + $this->addTextPart($alt); + $this->addHtmlPart($alt); + } else { + $this->addHtmlPart($message); + } + for ($i = 0; $i < count($this->parts); $i++) { + $this->addAttachmentPart($message, $this->parts[$i]); + } + break; + + case $html && $attachments && $html_images: + $message = $this->addMixedPart($mixed_params); + if (isset($this->txtbody)) { + $alt = $this->addAlternativePart($message); + $this->addTextPart($alt); + $rel = $this->addRelatedPart($alt); + } else { + $rel = $this->addRelatedPart($message); + } + $this->addHtmlPart($rel); + for ($i = 0; $i < count($this->html_images); $i++) { + $this->addHtmlImagePart($rel, $this->html_images[$i]); + } + for ($i = 0; $i < count($this->parts); $i++) { + $this->addAttachmentPart($message, $this->parts[$i]); + } + break; + } + + if (!isset($message)) { + return null; + } + + // Use saved boundary + if (!empty($this->build_params['boundary'])) { + $boundary = $this->build_params['boundary']; + } else { + $boundary = null; + } + + // Write output to file + if ($filename) { + // Append mimePart message headers and body into file + $headers = $message->encodeToFile($filename, $boundary, $skip_head); + if (self::isError($headers)) { + return $headers; + } + $this->headers = array_merge($this->headers, $headers); + return null; + } else { + $output = $message->encode($boundary, $skip_head); + if (self::isError($output)) { + return $output; + } + $this->headers = array_merge($this->headers, $output['headers']); + return $output['body']; + } + } + + /** + * Returns an array with the headers needed to prepend to the email + * (MIME-Version and Content-Type). Format of argument is: + * $array['header-name'] = 'header-value'; + * + * @param array $xtra_headers Assoc array with any extra headers (optional) + * (Don't set Content-Type for multipart messages here!) + * @param bool $overwrite Overwrite already existing headers. + * @param bool $skip_content Don't return content headers: Content-Type, + * Content-Disposition and Content-Transfer-Encoding + * + * @return array Assoc array with the mime headers + */ + public function headers($xtra_headers = null, $overwrite = false, $skip_content = false) + { + // Add mime version header + $headers['MIME-Version'] = '1.0'; + + // Content-Type and Content-Transfer-Encoding headers should already + // be present if get() was called, but we'll re-set them to make sure + // we got them when called before get() or something in the message + // has been changed after get() [#14780] + if (!$skip_content) { + $headers += $this->contentHeaders(); + } + + if (!empty($xtra_headers)) { + $headers = array_merge($headers, $xtra_headers); + } + + if ($overwrite) { + $this->headers = array_merge($this->headers, $headers); + } else { + $this->headers = array_merge($headers, $this->headers); + } + + $headers = $this->headers; + + if ($skip_content) { + unset($headers['Content-Type']); + unset($headers['Content-Transfer-Encoding']); + unset($headers['Content-Disposition']); + } else if (!empty($this->build_params['ctype'])) { + $headers['Content-Type'] = $this->build_params['ctype']; + } + + $encodedHeaders = $this->encodeHeaders($headers); + return $encodedHeaders; + } + + /** + * Get the text version of the headers + * (usefull if you want to use the PHP mail() function) + * + * @param array $xtra_headers Assoc array with any extra headers (optional) + * (Don't set Content-Type for multipart messages here!) + * @param bool $overwrite Overwrite the existing headers with new. + * @param bool $skip_content Don't return content headers: Content-Type, + * Content-Disposition and Content-Transfer-Encoding + * + * @return string Plain text headers + */ + public function txtHeaders($xtra_headers = null, $overwrite = false, $skip_content = false) + { + $headers = $this->headers($xtra_headers, $overwrite, $skip_content); + + // Place Received: headers at the beginning of the message + // Spam detectors often flag messages with it after the Subject: as spam + if (isset($headers['Received'])) { + $received = $headers['Received']; + unset($headers['Received']); + $headers = array('Received' => $received) + $headers; + } + + $ret = ''; + $eol = $this->build_params['eol']; + + foreach ($headers as $key => $val) { + if (is_array($val)) { + foreach ($val as $value) { + $ret .= "$key: $value" . $eol; + } + } else { + $ret .= "$key: $val" . $eol; + } + } + + return $ret; + } + + /** + * Sets message Content-Type header. + * Use it to build messages with various content-types e.g. miltipart/raport + * not supported by contentHeaders() function. + * + * @param string $type Type name + * @param array $params Hash array of header parameters + * + * @return void + * @since 1.7.0 + */ + public function setContentType($type, $params = array()) + { + $header = $type; + + $eol = !empty($this->build_params['eol']) + ? $this->build_params['eol'] : "\r\n"; + + // add parameters + $token_regexp = '#([^\x21\x23-\x27\x2A\x2B\x2D' + . '\x2E\x30-\x39\x41-\x5A\x5E-\x7E])#'; + + if (is_array($params)) { + foreach ($params as $name => $value) { + if ($name == 'boundary') { + $this->build_params['boundary'] = $value; + } + if (!preg_match($token_regexp, $value)) { + $header .= ";$eol $name=$value"; + } else { + $value = addcslashes($value, '\\"'); + $header .= ";$eol $name=\"$value\""; + } + } + } + + // add required boundary parameter if not defined + if (stripos($type, 'multipart/') === 0) { + if (empty($this->build_params['boundary'])) { + $this->build_params['boundary'] = '=_' . md5(rand() . microtime()); + } + + $header .= ";$eol boundary=\"".$this->build_params['boundary']."\""; + } + + $this->build_params['ctype'] = $header; + } + + /** + * Sets the Subject header + * + * @param string $subject String to set the subject to. + * + * @return void + */ + public function setSubject($subject) + { + $this->headers['Subject'] = $subject; + } + + /** + * Set an email to the From (the sender) header + * + * @param string $email The email address to use + * + * @return void + */ + public function setFrom($email) + { + $this->headers['From'] = $email; + } + + /** + * Add an email to the To header + * (multiple calls to this method are allowed) + * + * @param string $email The email direction to add + * + * @return void + */ + public function addTo($email) + { + if (isset($this->headers['To'])) { + $this->headers['To'] .= ", $email"; + } else { + $this->headers['To'] = $email; + } + } + + /** + * Add an email to the Cc (carbon copy) header + * (multiple calls to this method are allowed) + * + * @param string $email The email direction to add + * + * @return void + */ + public function addCc($email) + { + if (isset($this->headers['Cc'])) { + $this->headers['Cc'] .= ", $email"; + } else { + $this->headers['Cc'] = $email; + } + } + + /** + * Add an email to the Bcc (blank carbon copy) header + * (multiple calls to this method are allowed) + * + * @param string $email The email direction to add + * + * @return void + */ + public function addBcc($email) + { + if (isset($this->headers['Bcc'])) { + $this->headers['Bcc'] .= ", $email"; + } else { + $this->headers['Bcc'] = $email; + } + } + + /** + * Since the PHP send function requires you to specify + * recipients (To: header) separately from the other + * headers, the To: header is not properly encoded. + * To fix this, you can use this public method to encode + * your recipients before sending to the send function. + * + * @param string $recipients A comma-delimited list of recipients + * + * @return string Encoded data + */ + public function encodeRecipients($recipients) + { + $input = array('To' => $recipients); + $retval = $this->encodeHeaders($input); + + return $retval['To'] ; + } + + /** + * Encodes headers as per RFC2047 + * + * @param array $input The header data to encode + * @param array $params Extra build parameters + * + * @return array Encoded data + */ + protected function encodeHeaders($input, $params = array()) + { + $build_params = $this->build_params; + + if (!empty($params)) { + $build_params = array_merge($build_params, $params); + } + + foreach ($input as $hdr_name => $hdr_value) { + if (is_array($hdr_value)) { + foreach ($hdr_value as $idx => $value) { + $input[$hdr_name][$idx] = $this->encodeHeader( + $hdr_name, $value, + $build_params['head_charset'], $build_params['head_encoding'] + ); + } + } else if ($hdr_value !== null) { + $input[$hdr_name] = $this->encodeHeader( + $hdr_name, $hdr_value, + $build_params['head_charset'], $build_params['head_encoding'] + ); + } else { + unset($input[$hdr_name]); + } + } + + return $input; + } + + /** + * Encodes a header as per RFC2047 + * + * @param string $name The header name + * @param string $value The header data to encode + * @param string $charset Character set name + * @param string $encoding Encoding name (base64 or quoted-printable) + * + * @return string Encoded header data (without a name) + * @since 1.5.3 + */ + public function encodeHeader($name, $value, $charset, $encoding) + { + return Mail_mimePart::encodeHeader( + $name, $value, $charset, $encoding, $this->build_params['eol'] + ); + } + + /** + * Get file's basename (locale independent) + * + * @param string $filename Filename + * + * @return string Basename + */ + protected function basename($filename) + { + // basename() is not unicode safe and locale dependent + if (stristr(PHP_OS, 'win') || stristr(PHP_OS, 'netware')) { + return preg_replace('/^.*[\\\\\\/]/', '', $filename); + } else { + return preg_replace('/^.*[\/]/', '', $filename); + } + } + + /** + * Get Content-Type and Content-Transfer-Encoding headers of the message + * + * @return array Headers array + */ + protected function contentHeaders() + { + $attachments = count($this->parts) > 0; + $html_images = count($this->html_images) > 0; + $html = strlen($this->htmlbody) > 0; + $calendar = strlen($this->calbody) > 0; + $has_text = strlen($this->txtbody) > 0; + $text = !$html && $has_text; + $headers = array(); + + // See get() + switch (true) { + case $calendar && !$attachments && !$html && !$has_text: + $headers['Content-Type'] = 'text/calendar'; + break; + + case $calendar && !$attachments: + $headers['Content-Type'] = 'multipart/alternative'; + break; + + case $text && !$attachments: + $headers['Content-Type'] = 'text/plain'; + break; + + case !$text && !$html && $attachments: + case $text && $attachments: + case $html && $attachments && !$html_images: + case $html && $attachments && $html_images: + $headers['Content-Type'] = 'multipart/mixed'; + break; + + case $html && !$attachments && !$html_images && $has_text: + case $html && !$attachments && $html_images && $has_text: + $headers['Content-Type'] = 'multipart/alternative'; + break; + + case $html && !$attachments && !$html_images && !$has_text: + $headers['Content-Type'] = 'text/html'; + break; + + case $html && !$attachments && $html_images && !$has_text: + $headers['Content-Type'] = 'multipart/related'; + break; + + default: + return $headers; + } + + $this->checkParams(); + + $eol = !empty($this->build_params['eol']) + ? $this->build_params['eol'] : "\r\n"; + + if ($headers['Content-Type'] == 'text/plain') { + // single-part message: add charset and encoding + if ($this->build_params['text_charset']) { + $charset = 'charset=' . $this->build_params['text_charset']; + // place charset parameter in the same line, if possible + // 26 = strlen("Content-Type: text/plain; ") + $headers['Content-Type'] + .= (strlen($charset) + 26 <= 76) ? "; $charset" : ";$eol $charset"; + } + + $headers['Content-Transfer-Encoding'] + = $this->build_params['text_encoding']; + } else if ($headers['Content-Type'] == 'text/html') { + // single-part message: add charset and encoding + if ($this->build_params['html_charset']) { + $charset = 'charset=' . $this->build_params['html_charset']; + // place charset parameter in the same line, if possible + $headers['Content-Type'] + .= (strlen($charset) + 25 <= 76) ? "; $charset" : ";$eol $charset"; + } + $headers['Content-Transfer-Encoding'] + = $this->build_params['html_encoding']; + } + else if ($headers['Content-Type'] == 'text/calendar') { + // single-part message: add charset and encoding + if ($this->build_params['calendar_charset']) { + $charset = 'charset=' . $this->build_params['calendar_charset']; + $headers['Content-Type'] .= "; $charset"; + } + + if ($this->build_params['calendar_method']) { + $method = 'method=' . $this->build_params['calendar_method']; + $headers['Content-Type'] .= "; $method"; + } + + $headers['Content-Transfer-Encoding'] + = $this->build_params['calendar_encoding']; + } else { + // multipart message: and boundary + if (!empty($this->build_params['boundary'])) { + $boundary = $this->build_params['boundary']; + } else if (!empty($this->headers['Content-Type']) + && preg_match('/boundary="([^"]+)"/', $this->headers['Content-Type'], $m) + ) { + $boundary = $m[1]; + } else { + $boundary = '=_' . md5(rand() . microtime()); + } + + $this->build_params['boundary'] = $boundary; + $headers['Content-Type'] .= ";$eol boundary=\"$boundary\""; + } + + return $headers; + } + + /** + * Validate and set build parameters + * + * @return void + */ + protected function checkParams() + { + $encodings = array('7bit', '8bit', 'base64', 'quoted-printable'); + + $this->build_params['text_encoding'] + = strtolower($this->build_params['text_encoding']); + $this->build_params['html_encoding'] + = strtolower($this->build_params['html_encoding']); + $this->build_params['calendar_encoding'] + = strtolower($this->build_params['calendar_encoding']); + + if (!in_array($this->build_params['text_encoding'], $encodings)) { + $this->build_params['text_encoding'] = '7bit'; + } + if (!in_array($this->build_params['html_encoding'], $encodings)) { + $this->build_params['html_encoding'] = '7bit'; + } + if (!in_array($this->build_params['calendar_encoding'], $encodings)) { + $this->build_params['calendar_encoding'] = '7bit'; + } + + // text body + if ($this->build_params['text_encoding'] == '7bit' + && !preg_match('/ascii/i', $this->build_params['text_charset']) + && preg_match('/[^\x00-\x7F]/', $this->txtbody) + ) { + $this->build_params['text_encoding'] = 'quoted-printable'; + } + // html body + if ($this->build_params['html_encoding'] == '7bit' + && !preg_match('/ascii/i', $this->build_params['html_charset']) + && preg_match('/[^\x00-\x7F]/', $this->htmlbody) + ) { + $this->build_params['html_encoding'] = 'quoted-printable'; + } + // calendar body + if ($this->build_params['calendar_encoding'] == '7bit' + && !preg_match('/ascii/i', $this->build_params['calendar_charset']) + && preg_match('/[^\x00-\x7F]/', $this->calbody) + ) { + $this->build_params['calendar_encoding'] = 'quoted-printable'; + } + } + + /** + * Set body of specified message part + * + * @param string $type One of: txtbody, calbody, htmlbody + * @param string $data Either a string or the file name with the contents + * @param bool $isfile If true the first param should be treated + * as a file name, else as a string (default) + * @param bool $append If true the text or file is appended to + * the existing body, else the old body is + * overwritten + * + * @return mixed True on success or PEAR_Error object + */ + protected function setBody($type, $data, $isfile = false, $append = false) + { + if (!$isfile) { + if (!$append) { + $this->{$type} = $data; + } else { + $this->{$type} .= $data; + } + } else { + $cont = $this->file2str($data); + if (self::isError($cont)) { + return $cont; + } + + if (!$append) { + $this->{$type} = $cont; + } else { + $this->{$type} .= $cont; + } + } + + return true; + } + + /** + * Adds a subpart to the mimePart object and + * returns it during the build process. + * + * @param mixed $obj The object to add the part to, or + * anything else if a new object is to be created. + * @param string $body Part body + * @param string $ctype Part content type + * @param string $type Internal part type + * + * @return object The mimePart object + */ + protected function addBodyPart($obj, $body, $ctype, $type) + { + $params['content_type'] = $ctype; + $params['encoding'] = $this->build_params[$type . '_encoding']; + $params['charset'] = $this->build_params[$type . '_charset']; + $params['eol'] = $this->build_params['eol']; + + if (is_object($obj)) { + $ret = $obj->addSubpart($body, $params); + } else { + $ret = new Mail_mimePart($body, $params); + } + + return $ret; + } + + /** + * PEAR::isError implementation + * + * @param mixed $data Object + * + * @return bool True if object is an instance of PEAR_Error + */ + public static function isError($data) + { + // PEAR::isError() is not PHP 5.4 compatible (see Bug #19473) + if (is_a($data, 'PEAR_Error')) { + return true; + } + + return false; + } + + /** + * PEAR::raiseError implementation + * + * @param string $message A text error message + * + * @return PEAR_Error Instance of PEAR_Error + */ + public static function raiseError($message) + { + // PEAR::raiseError() is not PHP 5.4 compatible + return new PEAR_Error($message); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/Mail_Mime/Mail/mimePart.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/Mail_Mime/Mail/mimePart.php new file mode 100644 index 0000000..6ac85a2 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/Mail_Mime/Mail/mimePart.php @@ -0,0 +1,1249 @@ + + * Copyright (c) 2003-2006, PEAR + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of the authors, nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * @category Mail + * @package Mail_Mime + * @author Richard Heyes + * @author Cipriano Groenendal + * @author Sean Coates + * @author Aleksander Machniak + * @copyright 2003-2006 PEAR + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: @package_version@ + * @link http://pear.php.net/package/Mail_mime + */ + +/** + * require PEAR + * + * This package depends on PEAR to raise errors. + */ +require_once 'PEAR.php'; + +/** + * The Mail_mimePart class is used to create MIME E-mail messages + * + * This class enables you to manipulate and build a mime email + * from the ground up. The Mail_Mime class is a userfriendly api + * to this class for people who aren't interested in the internals + * of mime mail. + * This class however allows full control over the email. + * + * @category Mail + * @package Mail_Mime + * @author Richard Heyes + * @author Cipriano Groenendal + * @author Sean Coates + * @author Aleksander Machniak + * @copyright 2003-2006 PEAR + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: @package_version@ + * @link http://pear.php.net/package/Mail_mime + */ +class Mail_mimePart +{ + /** + * The encoding type of this part + * + * @var string + */ + protected $encoding; + + /** + * An array of subparts + * + * @var array + */ + protected $subparts; + + /** + * The output of this part after being built + * + * @var string + */ + protected $encoded; + + /** + * Headers for this part + * + * @var array + */ + protected $headers; + + /** + * The body of this part (not encoded) + * + * @var string + */ + protected $body; + + /** + * The location of file with body of this part (not encoded) + * + * @var string + */ + protected $body_file; + + /** + * The short text of multipart part preamble (RFC2046 5.1.1) + * + * @var string + */ + protected $preamble; + + /** + * The end-of-line sequence + * + * @var string + */ + protected $eol = "\r\n"; + + + /** + * Constructor. + * + * Sets up the object. + * + * @param string $body The body of the mime part if any. + * @param array $params An associative array of optional parameters: + * content_type - The content type for this part eg multipart/mixed + * encoding - The encoding to use, 7bit, 8bit, + * base64, or quoted-printable + * charset - Content character set + * cid - Content ID to apply + * disposition - Content disposition, inline or attachment + * filename - Filename parameter for content disposition + * description - Content description + * name_encoding - Encoding of the attachment name (Content-Type) + * By default filenames are encoded using RFC2231 + * Here you can set RFC2047 encoding (quoted-printable + * or base64) instead + * filename_encoding - Encoding of the attachment filename (Content-Disposition) + * See 'name_encoding' + * headers_charset - Charset of the headers e.g. filename, description. + * If not set, 'charset' will be used + * eol - End of line sequence. Default: "\r\n" + * headers - Hash array with additional part headers. Array keys can be + * in form of : + * body_file - Location of file with part's body (instead of $body) + * preamble - short text of multipart part preamble (RFC2046 5.1.1) + */ + public function __construct($body = '', $params = array()) + { + if (!empty($params['eol'])) { + $this->eol = $params['eol']; + } else if (defined('MAIL_MIMEPART_CRLF')) { // backward-copat. + $this->eol = MAIL_MIMEPART_CRLF; + } + + // Additional part headers + if (!empty($params['headers']) && is_array($params['headers'])) { + $headers = $params['headers']; + } + + foreach ($params as $key => $value) { + switch ($key) { + case 'encoding': + $this->encoding = $value; + $headers['Content-Transfer-Encoding'] = $value; + break; + + case 'cid': + $headers['Content-ID'] = '<' . $value . '>'; + break; + + case 'location': + $headers['Content-Location'] = $value; + break; + + case 'body_file': + $this->body_file = $value; + break; + + case 'preamble': + $this->preamble = $value; + break; + + // for backward compatibility + case 'dfilename': + $params['filename'] = $value; + break; + } + } + + // Default content-type + if (empty($params['content_type'])) { + $params['content_type'] = 'text/plain'; + } + + // Content-Type + $headers['Content-Type'] = $params['content_type']; + if (!empty($params['charset'])) { + $charset = "charset={$params['charset']}"; + // place charset parameter in the same line, if possible + if ((strlen($headers['Content-Type']) + strlen($charset) + 16) <= 76) { + $headers['Content-Type'] .= '; '; + } else { + $headers['Content-Type'] .= ';' . $this->eol . ' '; + } + $headers['Content-Type'] .= $charset; + + // Default headers charset + if (!isset($params['headers_charset'])) { + $params['headers_charset'] = $params['charset']; + } + } + + // header values encoding parameters + $h_charset = !empty($params['headers_charset']) ? $params['headers_charset'] : 'US-ASCII'; + $h_language = !empty($params['language']) ? $params['language'] : null; + $h_encoding = !empty($params['name_encoding']) ? $params['name_encoding'] : null; + + if (!empty($params['filename'])) { + $headers['Content-Type'] .= ';' . $this->eol; + $headers['Content-Type'] .= $this->buildHeaderParam( + 'name', $params['filename'], $h_charset, $h_language, $h_encoding + ); + } + + // Content-Disposition + if (!empty($params['disposition'])) { + $headers['Content-Disposition'] = $params['disposition']; + if (!empty($params['filename'])) { + $headers['Content-Disposition'] .= ';' . $this->eol; + $headers['Content-Disposition'] .= $this->buildHeaderParam( + 'filename', $params['filename'], $h_charset, $h_language, + !empty($params['filename_encoding']) ? $params['filename_encoding'] : null + ); + } + + // add attachment size + $size = $this->body_file ? filesize($this->body_file) : strlen($body); + if ($size) { + $headers['Content-Disposition'] .= ';' . $this->eol . ' size=' . $size; + } + } + + if (!empty($params['description'])) { + $headers['Content-Description'] = $this->encodeHeader( + 'Content-Description', $params['description'], $h_charset, $h_encoding, + $this->eol + ); + } + + // Search and add existing headers' parameters + foreach ($headers as $key => $value) { + $items = explode(':', $key); + if (count($items) == 2) { + $header = $items[0]; + $param = $items[1]; + if (isset($headers[$header])) { + $headers[$header] .= ';' . $this->eol; + } + $headers[$header] .= $this->buildHeaderParam( + $param, $value, $h_charset, $h_language, $h_encoding + ); + unset($headers[$key]); + } + } + + // Default encoding + if (!isset($this->encoding)) { + $this->encoding = '7bit'; + } + + // Assign stuff to member variables + $this->encoded = array(); + $this->headers = $headers; + $this->body = $body; + } + + /** + * Encodes and returns the email. Also stores + * it in the encoded member variable + * + * @param string $boundary Pre-defined boundary string + * + * @return An associative array containing two elements, + * body and headers. The headers element is itself + * an indexed array. On error returns PEAR error object. + */ + public function encode($boundary=null) + { + $encoded =& $this->encoded; + + if (count($this->subparts)) { + $boundary = $boundary ? $boundary : '=_' . md5(rand() . microtime()); + $eol = $this->eol; + + $this->headers['Content-Type'] .= ";$eol boundary=\"$boundary\""; + + $encoded['body'] = ''; + + if ($this->preamble) { + $encoded['body'] .= $this->preamble . $eol . $eol; + } + + for ($i = 0; $i < count($this->subparts); $i++) { + $encoded['body'] .= '--' . $boundary . $eol; + $tmp = $this->subparts[$i]->encode(); + if (is_a($tmp, 'PEAR_Error')) { + return $tmp; + } + foreach ($tmp['headers'] as $key => $value) { + $encoded['body'] .= $key . ': ' . $value . $eol; + } + $encoded['body'] .= $eol . $tmp['body'] . $eol; + } + + $encoded['body'] .= '--' . $boundary . '--' . $eol; + } else if ($this->body) { + $encoded['body'] = $this->getEncodedData($this->body, $this->encoding); + } else if ($this->body_file) { + // Temporarily reset magic_quotes_runtime for file reads and writes + if ($magic_quote_setting = get_magic_quotes_runtime()) { + @ini_set('magic_quotes_runtime', 0); + } + $body = $this->getEncodedDataFromFile($this->body_file, $this->encoding); + if ($magic_quote_setting) { + @ini_set('magic_quotes_runtime', $magic_quote_setting); + } + + if (is_a($body, 'PEAR_Error')) { + return $body; + } + $encoded['body'] = $body; + } else { + $encoded['body'] = ''; + } + + // Add headers to $encoded + $encoded['headers'] =& $this->headers; + + return $encoded; + } + + /** + * Encodes and saves the email into file or stream. + * Data will be appended to the file/stream. + * + * @param mixed $filename Existing file location + * or file pointer resource + * @param string $boundary Pre-defined boundary string + * @param boolean $skip_head True if you don't want to save headers + * + * @return array An associative array containing message headers + * or PEAR error object + * @since 1.6.0 + */ + public function encodeToFile($filename, $boundary = null, $skip_head = false) + { + if (!is_resource($filename)) { + if (file_exists($filename) && !is_writable($filename)) { + $err = self::raiseError('File is not writeable: ' . $filename); + return $err; + } + + if (!($fh = fopen($filename, 'ab'))) { + $err = self::raiseError('Unable to open file: ' . $filename); + return $err; + } + } else { + $fh = $filename; + } + + // Temporarily reset magic_quotes_runtime for file reads and writes + if ($magic_quote_setting = get_magic_quotes_runtime()) { + @ini_set('magic_quotes_runtime', 0); + } + + $res = $this->encodePartToFile($fh, $boundary, $skip_head); + + if (!is_resource($filename)) { + fclose($fh); + } + + if ($magic_quote_setting) { + @ini_set('magic_quotes_runtime', $magic_quote_setting); + } + + return is_a($res, 'PEAR_Error') ? $res : $this->headers; + } + + /** + * Encodes given email part into file + * + * @param string $fh Output file handle + * @param string $boundary Pre-defined boundary string + * @param boolean $skip_head True if you don't want to save headers + * + * @return array True on sucess or PEAR error object + */ + protected function encodePartToFile($fh, $boundary = null, $skip_head = false) + { + $eol = $this->eol; + + if (count($this->subparts)) { + $boundary = $boundary ? $boundary : '=_' . md5(rand() . microtime()); + $this->headers['Content-Type'] .= ";$eol boundary=\"$boundary\""; + } + + if (!$skip_head) { + foreach ($this->headers as $key => $value) { + fwrite($fh, $key . ': ' . $value . $eol); + } + $f_eol = $eol; + } else { + $f_eol = ''; + } + + if (count($this->subparts)) { + if ($this->preamble) { + fwrite($fh, $f_eol . $this->preamble . $eol); + $f_eol = $eol; + } + + for ($i = 0; $i < count($this->subparts); $i++) { + fwrite($fh, $f_eol . '--' . $boundary . $eol); + $res = $this->subparts[$i]->encodePartToFile($fh); + if (is_a($res, 'PEAR_Error')) { + return $res; + } + $f_eol = $eol; + } + + fwrite($fh, $eol . '--' . $boundary . '--' . $eol); + } else if ($this->body) { + fwrite($fh, $f_eol); + fwrite($fh, $this->getEncodedData($this->body, $this->encoding)); + } else if ($this->body_file) { + fwrite($fh, $f_eol); + $res = $this->getEncodedDataFromFile( + $this->body_file, $this->encoding, $fh + ); + if (is_a($res, 'PEAR_Error')) { + return $res; + } + } + + return true; + } + + /** + * Adds a subpart to current mime part and returns + * a reference to it + * + * @param mixed $body The body of the subpart or Mail_mimePart object + * @param array $params The parameters for the subpart, same + * as the $params argument for constructor + * + * @return Mail_mimePart A reference to the part you just added. + */ + public function addSubpart($body, $params = null) + { + if ($body instanceof Mail_mimePart) { + $part = $body; + } else { + $part = new Mail_mimePart($body, $params); + } + + $this->subparts[] = $part; + + return $part; + } + + /** + * Returns encoded data based upon encoding passed to it + * + * @param string $data The data to encode. + * @param string $encoding The encoding type to use, 7bit, base64, + * or quoted-printable. + * + * @return string Encoded data string + */ + protected function getEncodedData($data, $encoding) + { + switch ($encoding) { + case 'quoted-printable': + return self::quotedPrintableEncode($data, 76, $this->eol); + break; + + case 'base64': + return rtrim(chunk_split(base64_encode($data), 76, $this->eol)); + break; + + case '8bit': + case '7bit': + default: + return $data; + } + } + + /** + * Returns encoded data based upon encoding passed to it + * + * @param string $filename Data file location + * @param string $encoding The encoding type to use, 7bit, base64, + * or quoted-printable. + * @param resource $fh Output file handle. If set, data will be + * stored into it instead of returning it + * + * @return string Encoded data or PEAR error object + */ + protected function getEncodedDataFromFile($filename, $encoding, $fh = null) + { + if (!is_readable($filename)) { + $err = self::raiseError('Unable to read file: ' . $filename); + return $err; + } + + if (!($fd = fopen($filename, 'rb'))) { + $err = self::raiseError('Could not open file: ' . $filename); + return $err; + } + + $data = ''; + + switch ($encoding) { + case 'quoted-printable': + while (!feof($fd)) { + $buffer = self::quotedPrintableEncode(fgets($fd), 76, $this->eol); + if ($fh) { + fwrite($fh, $buffer); + } else { + $data .= $buffer; + } + } + break; + + case 'base64': + while (!feof($fd)) { + // Should read in a multiple of 57 bytes so that + // the output is 76 bytes per line. Don't use big chunks + // because base64 encoding is memory expensive + $buffer = fread($fd, 57 * 9198); // ca. 0.5 MB + $buffer = base64_encode($buffer); + $buffer = chunk_split($buffer, 76, $this->eol); + if (feof($fd)) { + $buffer = rtrim($buffer); + } + + if ($fh) { + fwrite($fh, $buffer); + } else { + $data .= $buffer; + } + } + break; + + case '8bit': + case '7bit': + default: + while (!feof($fd)) { + $buffer = fread($fd, 1048576); // 1 MB + if ($fh) { + fwrite($fh, $buffer); + } else { + $data .= $buffer; + } + } + } + + fclose($fd); + + if (!$fh) { + return $data; + } + } + + /** + * Encodes data to quoted-printable standard. + * + * @param string $input The data to encode + * @param int $line_max Optional max line length. Should + * not be more than 76 chars + * @param string $eol End-of-line sequence. Default: "\r\n" + * + * @return string Encoded data + */ + public static function quotedPrintableEncode($input , $line_max = 76, $eol = "\r\n") + { + /* + // imap_8bit() is extremely fast, but doesn't handle properly some characters + if (function_exists('imap_8bit') && $line_max == 76) { + $input = preg_replace('/\r?\n/', "\r\n", $input); + $input = imap_8bit($input); + if ($eol != "\r\n") { + $input = str_replace("\r\n", $eol, $input); + } + return $input; + } + */ + $lines = preg_split("/\r?\n/", $input); + $escape = '='; + $output = ''; + + while (list($idx, $line) = each($lines)) { + $newline = ''; + $i = 0; + + while (isset($line[$i])) { + $char = $line[$i]; + $dec = ord($char); + $i++; + + if (($dec == 32) && (!isset($line[$i]))) { + // convert space at eol only + $char = '=20'; + } elseif ($dec == 9 && isset($line[$i])) { + ; // Do nothing if a TAB is not on eol + } elseif (($dec == 61) || ($dec < 32) || ($dec > 126)) { + $char = $escape . sprintf('%02X', $dec); + } elseif (($dec == 46) && (($newline == '') + || ((strlen($newline) + strlen("=2E")) >= $line_max)) + ) { + // Bug #9722: convert full-stop at bol, + // some Windows servers need this, won't break anything (cipri) + // Bug #11731: full-stop at bol also needs to be encoded + // if this line would push us over the line_max limit. + $char = '=2E'; + } + + // Note, when changing this line, also change the ($dec == 46) + // check line, as it mimics this line due to Bug #11731 + // EOL is not counted + if ((strlen($newline) + strlen($char)) >= $line_max) { + // soft line break; " =\r\n" is okay + $output .= $newline . $escape . $eol; + $newline = ''; + } + $newline .= $char; + } // end of for + $output .= $newline . $eol; + unset($lines[$idx]); + } + // Don't want last crlf + $output = substr($output, 0, -1 * strlen($eol)); + return $output; + } + + /** + * Encodes the parameter of a header. + * + * @param string $name The name of the header-parameter + * @param string $value The value of the paramter + * @param string $charset The characterset of $value + * @param string $language The language used in $value + * @param string $encoding Parameter encoding. If not set, parameter value + * is encoded according to RFC2231 + * @param int $maxLength The maximum length of a line. Defauls to 75 + * + * @return string + */ + protected function buildHeaderParam($name, $value, $charset = null, + $language = null, $encoding = null, $maxLength = 75 + ) { + // RFC 2045: + // value needs encoding if contains non-ASCII chars or is longer than 78 chars + if (!preg_match('#[^\x20-\x7E]#', $value)) { + $token_regexp = '#([^\x21\x23-\x27\x2A\x2B\x2D' + . '\x2E\x30-\x39\x41-\x5A\x5E-\x7E])#'; + if (!preg_match($token_regexp, $value)) { + // token + if (strlen($name) + strlen($value) + 3 <= $maxLength) { + return " {$name}={$value}"; + } + } else { + // quoted-string + $quoted = addcslashes($value, '\\"'); + if (strlen($name) + strlen($quoted) + 5 <= $maxLength) { + return " {$name}=\"{$quoted}\""; + } + } + } + + // RFC2047: use quoted-printable/base64 encoding + if ($encoding == 'quoted-printable' || $encoding == 'base64') { + return $this->buildRFC2047Param($name, $value, $charset, $encoding); + } + + // RFC2231: + $encValue = preg_replace_callback( + '/([^\x21\x23\x24\x26\x2B\x2D\x2E\x30-\x39\x41-\x5A\x5E-\x7E])/', + array($this, 'encodeReplaceCallback'), $value + ); + $value = "$charset'$language'$encValue"; + + $header = " {$name}*={$value}"; + if (strlen($header) <= $maxLength) { + return $header; + } + + $preLength = strlen(" {$name}*0*="); + $maxLength = max(16, $maxLength - $preLength - 3); + $maxLengthReg = "|(.{0,$maxLength}[^\%][^\%])|"; + + $headers = array(); + $headCount = 0; + while ($value) { + $matches = array(); + $found = preg_match($maxLengthReg, $value, $matches); + if ($found) { + $headers[] = " {$name}*{$headCount}*={$matches[0]}"; + $value = substr($value, strlen($matches[0])); + } else { + $headers[] = " {$name}*{$headCount}*={$value}"; + $value = ''; + } + $headCount++; + } + + $headers = implode(';' . $this->eol, $headers); + return $headers; + } + + /** + * Encodes header parameter as per RFC2047 if needed + * + * @param string $name The parameter name + * @param string $value The parameter value + * @param string $charset The parameter charset + * @param string $encoding Encoding type (quoted-printable or base64) + * @param int $maxLength Encoded parameter max length. Default: 76 + * + * @return string Parameter line + */ + protected function buildRFC2047Param($name, $value, $charset, + $encoding = 'quoted-printable', $maxLength = 76 + ) { + // WARNING: RFC 2047 says: "An 'encoded-word' MUST NOT be used in + // parameter of a MIME Content-Type or Content-Disposition field", + // but... it's supported by many clients/servers + $quoted = ''; + + if ($encoding == 'base64') { + $value = base64_encode($value); + $prefix = '=?' . $charset . '?B?'; + $suffix = '?='; + + // 2 x SPACE, 2 x '"', '=', ';' + $add_len = strlen($prefix . $suffix) + strlen($name) + 6; + $len = $add_len + strlen($value); + + while ($len > $maxLength) { + // We can cut base64-encoded string every 4 characters + $real_len = floor(($maxLength - $add_len) / 4) * 4; + $_quote = substr($value, 0, $real_len); + $value = substr($value, $real_len); + + $quoted .= $prefix . $_quote . $suffix . $this->eol . ' '; + $add_len = strlen($prefix . $suffix) + 4; // 2 x SPACE, '"', ';' + $len = strlen($value) + $add_len; + } + $quoted .= $prefix . $value . $suffix; + + } else { + // quoted-printable + $value = $this->encodeQP($value); + $prefix = '=?' . $charset . '?Q?'; + $suffix = '?='; + + // 2 x SPACE, 2 x '"', '=', ';' + $add_len = strlen($prefix . $suffix) + strlen($name) + 6; + $len = $add_len + strlen($value); + + while ($len > $maxLength) { + $length = $maxLength - $add_len; + // don't break any encoded letters + if (preg_match("/^(.{0,$length}[^\=][^\=])/", $value, $matches)) { + $_quote = $matches[1]; + } + + $quoted .= $prefix . $_quote . $suffix . $this->eol . ' '; + $value = substr($value, strlen($_quote)); + $add_len = strlen($prefix . $suffix) + 4; // 2 x SPACE, '"', ';' + $len = strlen($value) + $add_len; + } + + $quoted .= $prefix . $value . $suffix; + } + + return " {$name}=\"{$quoted}\""; + } + + /** + * Encodes a header as per RFC2047 + * + * @param string $name The header name + * @param string $value The header data to encode + * @param string $charset Character set name + * @param string $encoding Encoding name (base64 or quoted-printable) + * @param string $eol End-of-line sequence. Default: "\r\n" + * + * @return string Encoded header data (without a name) + * @since 1.6.1 + */ + public static function encodeHeader($name, $value, $charset = 'ISO-8859-1', + $encoding = 'quoted-printable', $eol = "\r\n" + ) { + // Structured headers + $comma_headers = array( + 'from', 'to', 'cc', 'bcc', 'sender', 'reply-to', + 'resent-from', 'resent-to', 'resent-cc', 'resent-bcc', + 'resent-sender', 'resent-reply-to', + 'mail-reply-to', 'mail-followup-to', + 'return-receipt-to', 'disposition-notification-to', + ); + $other_headers = array( + 'references', 'in-reply-to', 'message-id', 'resent-message-id', + ); + + $name = strtolower($name); + + if (in_array($name, $comma_headers)) { + $separator = ','; + } else if (in_array($name, $other_headers)) { + $separator = ' '; + } + + if (!$charset) { + $charset = 'ISO-8859-1'; + } + + // Structured header (make sure addr-spec inside is not encoded) + if (!empty($separator)) { + // Simple e-mail address regexp + $email_regexp = '([^\s<]+|("[^\r\n"]+"))@\S+'; + + $parts = Mail_mimePart::explodeQuotedString("[\t$separator]", $value); + $value = ''; + + foreach ($parts as $part) { + $part = preg_replace('/\r?\n[\s\t]*/', $eol . ' ', $part); + $part = trim($part); + + if (!$part) { + continue; + } + if ($value) { + $value .= $separator == ',' ? $separator . ' ' : ' '; + } else { + $value = $name . ': '; + } + + // let's find phrase (name) and/or addr-spec + if (preg_match('/^<' . $email_regexp . '>$/', $part)) { + $value .= $part; + } else if (preg_match('/^' . $email_regexp . '$/', $part)) { + // address without brackets and without name + $value .= $part; + } else if (preg_match('/<*' . $email_regexp . '>*$/', $part, $matches)) { + // address with name (handle name) + $address = $matches[0]; + $word = str_replace($address, '', $part); + $word = trim($word); + // check if phrase requires quoting + if ($word) { + // non-ASCII: require encoding + if (preg_match('#([^\s\x21-\x7E]){1}#', $word)) { + if ($word[0] == '"' && $word[strlen($word)-1] == '"') { + // de-quote quoted-string, encoding changes + // string to atom + $search = array("\\\"", "\\\\"); + $replace = array("\"", "\\"); + $word = str_replace($search, $replace, $word); + $word = substr($word, 1, -1); + } + // find length of last line + if (($pos = strrpos($value, $eol)) !== false) { + $last_len = strlen($value) - $pos; + } else { + $last_len = strlen($value); + } + $word = Mail_mimePart::encodeHeaderValue( + $word, $charset, $encoding, $last_len, $eol + ); + } else if (($word[0] != '"' || $word[strlen($word)-1] != '"') + && preg_match('/[\(\)\<\>\\\.\[\]@,;:"]/', $word) + ) { + // ASCII: quote string if needed + $word = '"'.addcslashes($word, '\\"').'"'; + } + } + $value .= $word.' '.$address; + } else { + // addr-spec not found, don't encode (?) + $value .= $part; + } + + // RFC2822 recommends 78 characters limit, use 76 from RFC2047 + $value = wordwrap($value, 76, $eol . ' '); + } + + // remove header name prefix (there could be EOL too) + $value = preg_replace( + '/^'.$name.':('.preg_quote($eol, '/').')* /', '', $value + ); + } else { + // Unstructured header + // non-ASCII: require encoding + if (preg_match('#([^\s\x21-\x7E]){1}#', $value)) { + if ($value[0] == '"' && $value[strlen($value)-1] == '"') { + // de-quote quoted-string, encoding changes + // string to atom + $search = array("\\\"", "\\\\"); + $replace = array("\"", "\\"); + $value = str_replace($search, $replace, $value); + $value = substr($value, 1, -1); + } + $value = Mail_mimePart::encodeHeaderValue( + $value, $charset, $encoding, strlen($name) + 2, $eol + ); + } else if (strlen($name.': '.$value) > 78) { + // ASCII: check if header line isn't too long and use folding + $value = preg_replace('/\r?\n[\s\t]*/', $eol . ' ', $value); + $tmp = wordwrap($name.': '.$value, 78, $eol . ' '); + $value = preg_replace('/^'.$name.':\s*/', '', $tmp); + // hard limit 998 (RFC2822) + $value = wordwrap($value, 998, $eol . ' ', true); + } + } + + return $value; + } + + /** + * Explode quoted string + * + * @param string $delimiter Delimiter expression string for preg_match() + * @param string $string Input string + * + * @return array String tokens array + */ + protected static function explodeQuotedString($delimiter, $string) + { + $result = array(); + $strlen = strlen($string); + + for ($q=$p=$i=0; $i < $strlen; $i++) { + if ($string[$i] == "\"" + && (empty($string[$i-1]) || $string[$i-1] != "\\") + ) { + $q = $q ? false : true; + } else if (!$q && preg_match("/$delimiter/", $string[$i])) { + $result[] = substr($string, $p, $i - $p); + $p = $i + 1; + } + } + + $result[] = substr($string, $p); + return $result; + } + + /** + * Encodes a header value as per RFC2047 + * + * @param string $value The header data to encode + * @param string $charset Character set name + * @param string $encoding Encoding name (base64 or quoted-printable) + * @param int $prefix_len Prefix length. Default: 0 + * @param string $eol End-of-line sequence. Default: "\r\n" + * + * @return string Encoded header data + * @since 1.6.1 + */ + public static function encodeHeaderValue($value, $charset, $encoding, $prefix_len = 0, $eol = "\r\n") + { + // #17311: Use multibyte aware method (requires mbstring extension) + if ($result = Mail_mimePart::encodeMB($value, $charset, $encoding, $prefix_len, $eol)) { + return $result; + } + + // Generate the header using the specified params and dynamicly + // determine the maximum length of such strings. + // 75 is the value specified in the RFC. + $encoding = $encoding == 'base64' ? 'B' : 'Q'; + $prefix = '=?' . $charset . '?' . $encoding .'?'; + $suffix = '?='; + $maxLength = 75 - strlen($prefix . $suffix); + $maxLength1stLine = $maxLength - $prefix_len; + + if ($encoding == 'B') { + // Base64 encode the entire string + $value = base64_encode($value); + + // We can cut base64 every 4 characters, so the real max + // we can get must be rounded down. + $maxLength = $maxLength - ($maxLength % 4); + $maxLength1stLine = $maxLength1stLine - ($maxLength1stLine % 4); + + $cutpoint = $maxLength1stLine; + $output = ''; + + while ($value) { + // Split translated string at every $maxLength + $part = substr($value, 0, $cutpoint); + $value = substr($value, $cutpoint); + $cutpoint = $maxLength; + // RFC 2047 specifies that any split header should + // be separated by a CRLF SPACE. + if ($output) { + $output .= $eol . ' '; + } + $output .= $prefix . $part . $suffix; + } + $value = $output; + } else { + // quoted-printable encoding has been selected + $value = Mail_mimePart::encodeQP($value); + + // This regexp will break QP-encoded text at every $maxLength + // but will not break any encoded letters. + $reg1st = "|(.{0,$maxLength1stLine}[^\=][^\=])|"; + $reg2nd = "|(.{0,$maxLength}[^\=][^\=])|"; + + if (strlen($value) > $maxLength1stLine) { + // Begin with the regexp for the first line. + $reg = $reg1st; + $output = ''; + while ($value) { + // Split translated string at every $maxLength + // But make sure not to break any translated chars. + $found = preg_match($reg, $value, $matches); + + // After this first line, we need to use a different + // regexp for the first line. + $reg = $reg2nd; + + // Save the found part and encapsulate it in the + // prefix & suffix. Then remove the part from the + // $value_out variable. + if ($found) { + $part = $matches[0]; + $len = strlen($matches[0]); + $value = substr($value, $len); + } else { + $part = $value; + $value = ''; + } + + // RFC 2047 specifies that any split header should + // be separated by a CRLF SPACE + if ($output) { + $output .= $eol . ' '; + } + $output .= $prefix . $part . $suffix; + } + $value = $output; + } else { + $value = $prefix . $value . $suffix; + } + } + + return $value; + } + + /** + * Encodes the given string using quoted-printable + * + * @param string $str String to encode + * + * @return string Encoded string + * @since 1.6.0 + */ + public static function encodeQP($str) + { + // Bug #17226 RFC 2047 restricts some characters + // if the word is inside a phrase, permitted chars are only: + // ASCII letters, decimal digits, "!", "*", "+", "-", "/", "=", and "_" + + // "=", "_", "?" must be encoded + $regexp = '/([\x22-\x29\x2C\x2E\x3A-\x40\x5B-\x60\x7B-\x7E\x80-\xFF])/'; + $str = preg_replace_callback( + $regexp, array('Mail_mimePart', 'qpReplaceCallback'), $str + ); + + return str_replace(' ', '_', $str); + } + + /** + * Encodes the given string using base64 or quoted-printable. + * This method makes sure that encoded-word represents an integral + * number of characters as per RFC2047. + * + * @param string $str String to encode + * @param string $charset Character set name + * @param string $encoding Encoding name (base64 or quoted-printable) + * @param int $prefix_len Prefix length. Default: 0 + * @param string $eol End-of-line sequence. Default: "\r\n" + * + * @return string Encoded string + * @since 1.8.0 + */ + public static function encodeMB($str, $charset, $encoding, $prefix_len=0, $eol="\r\n") + { + if (!function_exists('mb_substr') || !function_exists('mb_strlen')) { + return; + } + + $encoding = $encoding == 'base64' ? 'B' : 'Q'; + // 75 is the value specified in the RFC + $prefix = '=?' . $charset . '?'.$encoding.'?'; + $suffix = '?='; + $maxLength = 75 - strlen($prefix . $suffix); + + // A multi-octet character may not be split across adjacent encoded-words + // So, we'll loop over each character + // mb_stlen() with wrong charset will generate a warning here and return null + $length = mb_strlen($str, $charset); + $result = ''; + $line_length = $prefix_len; + + if ($encoding == 'B') { + // base64 + $start = 0; + $prev = ''; + + for ($i=1; $i<=$length; $i++) { + // See #17311 + $chunk = mb_substr($str, $start, $i-$start, $charset); + $chunk = base64_encode($chunk); + $chunk_len = strlen($chunk); + + if ($line_length + $chunk_len == $maxLength || $i == $length) { + if ($result) { + $result .= "\n"; + } + $result .= $chunk; + $line_length = 0; + $start = $i; + } else if ($line_length + $chunk_len > $maxLength) { + if ($result) { + $result .= "\n"; + } + if ($prev) { + $result .= $prev; + } + $line_length = 0; + $start = $i - 1; + } else { + $prev = $chunk; + } + } + } else { + // quoted-printable + // see encodeQP() + $regexp = '/([\x22-\x29\x2C\x2E\x3A-\x40\x5B-\x60\x7B-\x7E\x80-\xFF])/'; + + for ($i=0; $i<=$length; $i++) { + $char = mb_substr($str, $i, 1, $charset); + // RFC recommends underline (instead of =20) in place of the space + // that's one of the reasons why we're not using iconv_mime_encode() + if ($char == ' ') { + $char = '_'; + $char_len = 1; + } else { + $char = preg_replace_callback( + $regexp, array('Mail_mimePart', 'qpReplaceCallback'), $char + ); + $char_len = strlen($char); + } + + if ($line_length + $char_len > $maxLength) { + if ($result) { + $result .= "\n"; + } + $line_length = 0; + } + + $result .= $char; + $line_length += $char_len; + } + } + + if ($result) { + $result = $prefix + .str_replace("\n", $suffix.$eol.' '.$prefix, $result).$suffix; + } + + return $result; + } + + /** + * Callback function to replace extended characters (\x80-xFF) with their + * ASCII values (RFC2047: quoted-printable) + * + * @param array $matches Preg_replace's matches array + * + * @return string Encoded character string + */ + protected static function qpReplaceCallback($matches) + { + return sprintf('=%02X', ord($matches[1])); + } + + /** + * Callback function to replace extended characters (\x80-xFF) with their + * ASCII values (RFC2231) + * + * @param array $matches Preg_replace's matches array + * + * @return string Encoded character string + */ + protected static function encodeReplaceCallback($matches) + { + return sprintf('%%%02X', ord($matches[1])); + } + + /** + * PEAR::raiseError implementation + * + * @param string $message A text error message + * + * @return PEAR_Error Instance of PEAR_Error + */ + public static function raiseError($message) + { + // PEAR::raiseError() is not PHP 5.4 compatible + return new PEAR_Error($message); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/Mail_mimeDecode/Mail/mimeDecode.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/Mail_mimeDecode/Mail/mimeDecode.php new file mode 100644 index 0000000..60534c8 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/Mail_mimeDecode/Mail/mimeDecode.php @@ -0,0 +1,1080 @@ + + * Copyright (c) 2003-2006, PEAR + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of the authors, nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * @category Mail + * @package Mail_Mime + * @author Richard Heyes + * @author George Schlossnagle + * @author Cipriano Groenendal + * @author Sean Coates + * @copyright 2003-2006 PEAR + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version CVS: $Id: mimeDecode.php 337165 2015-07-15 09:42:08Z alan_k $ + * @link http://pear.php.net/package/Mail_mime + */ + + +/** + * require PEAR + * + * This package depends on PEAR to raise errors. + */ +require_once 'PEAR.php'; + + +/** + * The Mail_mimeDecode class is used to decode mail/mime messages + * + * This class will parse a raw mime email and return the structure. + * Returned structure is similar to that returned by imap_fetchstructure(). + * + * +----------------------------- IMPORTANT ------------------------------+ + * | Usage of this class compared to native php extensions such as | + * | mailparse or imap, is slow and may be feature deficient. If available| + * | you are STRONGLY recommended to use the php extensions. | + * +----------------------------------------------------------------------+ + * + * @category Mail + * @package Mail_Mime + * @author Richard Heyes + * @author George Schlossnagle + * @author Cipriano Groenendal + * @author Sean Coates + * @copyright 2003-2006 PEAR + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: @package_version@ + * @link http://pear.php.net/package/Mail_mime + */ +class Mail_mimeDecode extends PEAR +{ + /** + * The raw email to decode + * + * @var string + * @access private + */ + var $_input; + + /** + * The header part of the input + * + * @var string + * @access private + */ + var $_header; + + /** + * The body part of the input + * + * @var string + * @access private + */ + var $_body; + + /** + * If an error occurs, this is used to store the message + * + * @var string + * @access private + */ + var $_error; + + /** + * Flag to determine whether to include bodies in the + * returned object. + * + * @var boolean + * @access private + */ + var $_include_bodies; + + /** + * Flag to determine whether to decode bodies + * + * @var boolean + * @access private + */ + var $_decode_bodies; + + /** + * Flag to determine whether to decode headers + * (set to UTF8 to iconv convert headers) + * @var mixed + * @access private + */ + var $_decode_headers; + + + /** + * Flag to determine whether to include attached messages + * as body in the returned object. Depends on $_include_bodies + * + * @var boolean + * @access private + */ + var $_rfc822_bodies; + + /** + * Constructor. + * + * Sets up the object, initialise the variables, and splits and + * stores the header and body of the input. + * + * @param string The input to decode + * @access public + */ + function __construct($input) + { + list($header, $body) = $this->_splitBodyHeader($input); + + $this->_input = $input; + $this->_header = $header; + $this->_body = $body; + $this->_decode_bodies = false; + $this->_include_bodies = true; + $this->_rfc822_bodies = false; + } + // BC + function Mail_mimeDecode($input) + { + $this->__construct($input); + } + + + /** + * Begins the decoding process. If called statically + * it will create an object and call the decode() method + * of it. + * + * @param array An array of various parameters that determine + * various things: + * include_bodies - Whether to include the body in the returned + * object. + * decode_bodies - Whether to decode the bodies + * of the parts. (Transfer encoding) + * decode_headers - Whether to decode headers, + * - use "UTF8//IGNORE" to convert charset. + * + * input - If called statically, this will be treated + * as the input + * @return object Decoded results + * @access public + */ + function decode($params = null) + { + // determine if this method has been called statically + $isStatic = empty($this) || !is_a($this, __CLASS__); + + // Have we been called statically? + // If so, create an object and pass details to that. + if ($isStatic AND isset($params['input'])) { + + $obj = new Mail_mimeDecode($params['input']); + $structure = $obj->decode($params); + + // Called statically but no input + } elseif ($isStatic) { + return PEAR::raiseError('Called statically and no input given'); + + // Called via an object + } else { + $this->_include_bodies = isset($params['include_bodies']) ? + $params['include_bodies'] : false; + $this->_decode_bodies = isset($params['decode_bodies']) ? + $params['decode_bodies'] : false; + $this->_decode_headers = isset($params['decode_headers']) ? + $params['decode_headers'] : false; + $this->_rfc822_bodies = isset($params['rfc_822bodies']) ? + $params['rfc_822bodies'] : false; + + if (is_string($this->_decode_headers) && !function_exists('iconv')) { + PEAR::raiseError('header decode conversion requested, however iconv is missing'); + } + + $structure = $this->_decode($this->_header, $this->_body); + if ($structure === false) { + $structure = $this->raiseError($this->_error); + } + } + + return $structure; + } + + /** + * Performs the decoding. Decodes the body string passed to it + * If it finds certain content-types it will call itself in a + * recursive fashion + * + * @param string Header section + * @param string Body section + * @return object Results of decoding process + * @access private + */ + function _decode($headers, $body, $default_ctype = 'text/plain') + { + $return = new stdClass; + $return->headers = array(); + $headers = $this->_parseHeaders($headers); + + foreach ($headers as $value) { + $value['value'] = $this->_decodeHeader($value['value']); + if (isset($return->headers[strtolower($value['name'])]) AND !is_array($return->headers[strtolower($value['name'])])) { + $return->headers[strtolower($value['name'])] = array($return->headers[strtolower($value['name'])]); + $return->headers[strtolower($value['name'])][] = $value['value']; + + } elseif (isset($return->headers[strtolower($value['name'])])) { + $return->headers[strtolower($value['name'])][] = $value['value']; + + } else { + $return->headers[strtolower($value['name'])] = $value['value']; + } + } + + + foreach ($headers as $key => $value) { + $headers[$key]['name'] = strtolower($headers[$key]['name']); + switch ($headers[$key]['name']) { + + case 'content-type': + $content_type = $this->_parseHeaderValue($headers[$key]['value']); + + if (preg_match('/([0-9a-z+.-]+)\/([0-9a-z+.-]+)/i', $content_type['value'], $regs)) { + $return->ctype_primary = $regs[1]; + $return->ctype_secondary = $regs[2]; + } + + if (isset($content_type['other'])) { + foreach($content_type['other'] as $p_name => $p_value) { + $return->ctype_parameters[$p_name] = $p_value; + } + } + break; + + case 'content-disposition': + $content_disposition = $this->_parseHeaderValue($headers[$key]['value']); + $return->disposition = $content_disposition['value']; + if (isset($content_disposition['other'])) { + foreach($content_disposition['other'] as $p_name => $p_value) { + $return->d_parameters[$p_name] = $p_value; + } + } + break; + + case 'content-transfer-encoding': + $content_transfer_encoding = $this->_parseHeaderValue($headers[$key]['value']); + break; + } + } + + if (isset($content_type)) { + switch (strtolower($content_type['value'])) { + case 'text/plain': + $encoding = isset($content_transfer_encoding) ? $content_transfer_encoding['value'] : '7bit'; + $this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $encoding) : $body) : null; + break; + + case 'text/html': + $encoding = isset($content_transfer_encoding) ? $content_transfer_encoding['value'] : '7bit'; + $this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $encoding) : $body) : null; + break; + + case 'multipart/signed': // PGP + $parts = $this->_boundarySplit($body, $content_type['other']['boundary'], true); + $return->parts['msg_body'] = $parts[0]; + list($part_header, $part_body) = $this->_splitBodyHeader($parts[1]); + $return->parts['sig_hdr'] = $part_header; + $return->parts['sig_body'] = $part_body; + break; + + case 'multipart/parallel': + case 'multipart/appledouble': // Appledouble mail + case 'multipart/report': // RFC1892 + case 'multipart/signed': // PGP + case 'multipart/digest': + case 'multipart/alternative': + case 'multipart/related': + case 'multipart/relative': //#20431 - android + case 'multipart/mixed': + case 'application/vnd.wap.multipart.related': + if(!isset($content_type['other']['boundary'])){ + $this->_error = 'No boundary found for ' . $content_type['value'] . ' part'; + return false; + } + + $default_ctype = (strtolower($content_type['value']) === 'multipart/digest') ? 'message/rfc822' : 'text/plain'; + + $parts = $this->_boundarySplit($body, $content_type['other']['boundary']); + for ($i = 0; $i < count($parts); $i++) { + list($part_header, $part_body) = $this->_splitBodyHeader($parts[$i]); + $part = $this->_decode($part_header, $part_body, $default_ctype); + if($part === false) + $part = $this->raiseError($this->_error); + $return->parts[] = $part; + } + break; + + case 'message/rfc822': + case 'message/delivery-status': // #bug #18693 + if ($this->_rfc822_bodies) { + $encoding = isset($content_transfer_encoding) ? $content_transfer_encoding['value'] : '7bit'; + $return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $encoding) : $body); + } + $obj = new Mail_mimeDecode($body); + $return->parts[] = $obj->decode(array('include_bodies' => $this->_include_bodies, + 'decode_bodies' => $this->_decode_bodies, + 'decode_headers' => $this->_decode_headers)); + unset($obj); + break; + + default: + if(!isset($content_transfer_encoding['value'])) + $content_transfer_encoding['value'] = '7bit'; + $this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $content_transfer_encoding['value']) : $body) : null; + break; + } + + } else { + $ctype = explode('/', $default_ctype); + $return->ctype_primary = $ctype[0]; + $return->ctype_secondary = $ctype[1]; + $this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body) : $body) : null; + } + + return $return; + } + + /** + * Given the output of the above function, this will return an + * array of references to the parts, indexed by mime number. + * + * @param object $structure The structure to go through + * @param string $mime_number Internal use only. + * @return array Mime numbers + */ + function &getMimeNumbers(&$structure, $no_refs = false, $mime_number = '', $prepend = '') + { + $return = array(); + if (!empty($structure->parts)) { + if ($mime_number != '') { + $structure->mime_id = $prepend . $mime_number; + $return[$prepend . $mime_number] = &$structure; + } + for ($i = 0; $i < count($structure->parts); $i++) { + + + if (!empty($structure->headers['content-type']) AND substr(strtolower($structure->headers['content-type']), 0, 8) == 'message/') { + $prepend = $prepend . $mime_number . '.'; + $_mime_number = ''; + } else { + $_mime_number = ($mime_number == '' ? $i + 1 : sprintf('%s.%s', $mime_number, $i + 1)); + } + + $arr = &Mail_mimeDecode::getMimeNumbers($structure->parts[$i], $no_refs, $_mime_number, $prepend); + foreach ($arr as $key => $val) { + $no_refs ? $return[$key] = '' : $return[$key] = &$arr[$key]; + } + } + } else { + if ($mime_number == '') { + $mime_number = '1'; + } + $structure->mime_id = $prepend . $mime_number; + $no_refs ? $return[$prepend . $mime_number] = '' : $return[$prepend . $mime_number] = &$structure; + } + + return $return; + } + + /** + * Given a string containing a header and body + * section, this function will split them (at the first + * blank line) and return them. + * + * @param string Input to split apart + * @return array Contains header and body section + * @access private + */ + function _splitBodyHeader($input) + { + if (preg_match("/^(.*?)\r?\n\r?\n(.*)/s", $input, $match)) { + return array($match[1], $match[2]); + } + // bug #17325 - empty bodies are allowed. - we just check that at least one line + // of headers exist.. + if (count(explode("\n",$input))) { + return array($input, ''); + } + $this->_error = 'Could not split header and body'; + return false; + } + + /** + * Parse headers given in $input and return + * as assoc array. + * + * @param string Headers to parse + * @return array Contains parsed headers + * @access private + */ + function _parseHeaders($input) + { + + if ($input !== '') { + // Unfold the input + $input = preg_replace("/\r?\n/", "\r\n", $input); + //#7065 - wrapping.. with encoded stuff.. - probably not needed, + // wrapping space should only get removed if the trailing item on previous line is a + // encoded character + $input = preg_replace("/=\r\n(\t| )+/", '=', $input); + $input = preg_replace("/\r\n(\t| )+/", ' ', $input); + + $headers = explode("\r\n", trim($input)); + $got_start = false; + foreach ($headers as $value) { + if (!$got_start) { + // munge headers for mbox style from + if ($value[0] == '>') { + $value = substring($value, 1); // remove mbox > + } + if (substr($value,0,5) == 'From ') { + $value = 'Return-Path: ' . substr($value, 5); + } else { + $got_start = true; + } + } + + $hdr_name = substr($value, 0, $pos = strpos($value, ':')); + $hdr_value = substr($value, $pos+1); + if($hdr_value[0] == ' ') { + $hdr_value = substr($hdr_value, 1); + } + + $return[] = array( + 'name' => $hdr_name, + 'value' => $hdr_value + ); + } + } else { + $return = array(); + } + + return $return; + } + + /** + * Function to parse a header value, + * extract first part, and any secondary + * parts (after ;) This function is not as + * robust as it could be. Eg. header comments + * in the wrong place will probably break it. + * + * Extra things this can handle + * filename*0=...... + * filename*1=...... + * + * This is where lines are broken in, and need merging. + * + * filename*0*=ENC'lang'urlencoded data. + * filename*1*=ENC'lang'urlencoded data. + * + * + * + * @param string Header value to parse + * @return array Contains parsed result + * @access private + */ + function _parseHeaderValue($input) + { + if (($pos = strpos($input, ';')) === false) { + $input = $this->_decodeHeader($input); + $return['value'] = trim($input); + return $return; + } + + + + $value = substr($input, 0, $pos); + $value = $this->_decodeHeader($value); + $return['value'] = trim($value); + $input = trim(substr($input, $pos+1)); + + if (!strlen($input) > 0) { + return $return; + } + // at this point input contains xxxx=".....";zzzz="...." + // since we are dealing with quoted strings, we need to handle this properly.. + $i = 0; + $l = strlen($input); + $key = ''; + $val = false; // our string - including quotes.. + $q = false; // in quote.. + $lq = ''; // last quote.. + + while ($i < $l) { + + $c = $input[$i]; + //var_dump(array('i'=>$i,'c'=>$c,'q'=>$q, 'lq'=>$lq, 'key'=>$key, 'val' =>$val)); + + $escaped = false; + if ($c == '\\') { + $i++; + if ($i == $l-1) { // end of string. + break; + } + $escaped = true; + $c = $input[$i]; + } + + + // state - in key.. + if ($val === false) { + if (!$escaped && $c == '=') { + $val = ''; + $key = trim($key); + $i++; + continue; + } + if (!$escaped && $c == ';') { + if ($key) { // a key without a value.. + $key= trim($key); + $return['other'][$key] = ''; + } + $key = ''; + } + $key .= $c; + $i++; + continue; + } + + // state - in value.. (as $val is set..) + + if ($q === false) { + // not in quote yet. + if ((!strlen($val) || $lq !== false) && $c == ' ' || $c == "\t") { + $i++; + continue; // skip leading spaces after '=' or after '"' + } + + // do not de-quote 'xxx*= itesm.. + $key_is_trans = $key[strlen($key)-1] == '*'; + + if (!$key_is_trans && !$escaped && ($c == '"' || $c == "'")) { + // start quoted area.. + $q = $c; + // in theory should not happen raw text in value part.. + // but we will handle it as a merged part of the string.. + $val = !strlen(trim($val)) ? '' : trim($val); + $i++; + continue; + } + // got end.... + if (!$escaped && $c == ';') { + + $return['other'][$key] = trim($val); + $val = false; + $key = ''; + $lq = false; + $i++; + continue; + } + + $val .= $c; + $i++; + continue; + } + + // state - in quote.. + if (!$escaped && $c == $q) { // potential exit state.. + + // end of quoted string.. + $lq = $q; + $q = false; + $i++; + continue; + } + + // normal char inside of quoted string.. + $val.= $c; + $i++; + } + + // do we have anything left.. + if (strlen(trim($key)) || $val !== false) { + + $val = trim($val); + + $return['other'][$key] = $val; + } + + + $clean_others = array(); + // merge added values. eg. *1[*] + foreach($return['other'] as $key =>$val) { + if (preg_match('/\*[0-9]+\**$/', $key)) { + $key = preg_replace('/(.*)\*[0-9]+(\**)$/', '\1\2', $key); + if (isset($clean_others[$key])) { + $clean_others[$key] .= $val; + continue; + } + + } + $clean_others[$key] = $val; + + } + + // handle language translation of '*' ending others. + foreach( $clean_others as $key =>$val) { + if ( $key[strlen($key)-1] != '*') { + $clean_others[strtolower($key)] = $val; + continue; + } + unset($clean_others[$key]); + $key = substr($key,0,-1); + //extended-initial-value := [charset] "'" [language] "'" + // extended-other-values + $match = array(); + $info = preg_match("/^([^']+)'([^']*)'(.*)$/", $val, $match); + + $clean_others[$key] = urldecode($match[3]); + $clean_others[strtolower($key)] = $clean_others[$key]; + $clean_others[strtolower($key).'-charset'] = $match[1]; + $clean_others[strtolower($key).'-language'] = $match[2]; + + + } + + + $return['other'] = $clean_others; + + // decode values. + foreach($return['other'] as $key =>$val) { + $charset = isset($return['other'][$key . '-charset']) ? + $return['other'][$key . '-charset'] : false; + + $return['other'][$key] = $this->_decodeHeader($val, $charset); + } + + return $return; + } + + /** + * This function splits the input based + * on the given boundary + * + * @param string Input to parse + * @return array Contains array of resulting mime parts + * @access private + */ + function _boundarySplit($input, $boundary, $eatline = false) + { + $parts = array(); + + $bs_possible = substr($boundary, 2, -2); + $bs_check = '\"' . $bs_possible . '\"'; + + if ($boundary == $bs_check) { + $boundary = $bs_possible; + } + // eatline is used by multipart/signed. + $tmp = $eatline ? + preg_split("/\r?\n--".preg_quote($boundary, '/')."(|--)\n/", $input) : + preg_split("/--".preg_quote($boundary, '/')."((?=\s)|--)/", $input); + + $len = count($tmp) -1; + for ($i = 1; $i < $len; $i++) { + if (strlen(trim($tmp[$i]))) { + $parts[] = $tmp[$i]; + } + } + + // add the last part on if it does not end with the 'closing indicator' + if (!empty($tmp[$len]) && strlen(trim($tmp[$len])) && $tmp[$len][0] != '-') { + $parts[] = $tmp[$len]; + } + return $parts; + } + + /** + * Given a header, this function will decode it + * according to RFC2047. Probably not *exactly* + * conformant, but it does pass all the given + * examples (in RFC2047). + * + * @param string Input header value to decode + * @return string Decoded header value + * @access private + */ + function _decodeHeader($input, $default_charset=false) + { + if (!$this->_decode_headers) { + return $input; + } + // Remove white space between encoded-words + $input = preg_replace('/(=\?[^?]+\?(q|b)\?[^?]*\?=)(\s)+=\?/i', '\1=?', $input); + + // For each encoded-word... + while (preg_match('/(=\?([^?]+)\?(q|b)\?([^?]*)\?=)/i', $input, $matches)) { + + $encoded = $matches[1]; + $charset = $matches[2]; + $encoding = $matches[3]; + $text = $matches[4]; + + switch (strtolower($encoding)) { + case 'b': + $text = base64_decode($text); + break; + + case 'q': + $text = str_replace('_', ' ', $text); + preg_match_all('/=([a-f0-9]{2})/i', $text, $matches); + foreach($matches[1] as $value) + $text = str_replace('='.$value, chr(hexdec($value)), $text); + break; + } + if (is_string($this->_decode_headers)) { + $conv = @iconv($charset, $this->_decode_headers, $text); + $text = ($conv === false) ? $text : $conv; + } + $input = str_replace($encoded, $text, $input); + } + + if ($default_charset && is_string($this->_decode_headers)) { + $conv = @iconv($charset, $this->_decode_headers, $input); + $input = ($conv === false) ? $input : $conv; + } + + return $input; + } + + /** + * Given a body string and an encoding type, + * this function will decode and return it. + * + * @param string Input body to decode + * @param string Encoding type to use. + * @return string Decoded body + * @access private + */ + function _decodeBody($input, $encoding = '7bit') + { + switch (strtolower($encoding)) { + case '7bit': + return $input; + break; + + case 'quoted-printable': + return $this->_quotedPrintableDecode($input); + break; + + case 'base64': + return base64_decode($input); + break; + + default: + return $input; + } + } + + /** + * Given a quoted-printable string, this + * function will decode and return it. + * + * @param string Input body to decode + * @return string Decoded body + * @access private + */ + function _quotedPrintableDecode($input) + { + // Remove soft line breaks + $input = preg_replace("/=\r?\n/", '', $input); + + // Replace encoded characters + + $cb = create_function('$matches', ' return chr(hexdec($matches[0]));'); + + $input = preg_replace_callback( '/=([a-f0-9]{2})/i', $cb, $input); + + return $input; + } + + /** + * Checks the input for uuencoded files and returns + * an array of them. Can be called statically, eg: + * + * $files =& Mail_mimeDecode::uudecode($some_text); + * + * It will check for the begin 666 ... end syntax + * however and won't just blindly decode whatever you + * pass it. + * + * @param string Input body to look for attahcments in + * @return array Decoded bodies, filenames and permissions + * @access public + * @author Unknown + */ + function &uudecode($input) + { + // Find all uuencoded sections + preg_match_all("/begin ([0-7]{3}) (.+)\r?\n(.+)\r?\nend/Us", $input, $matches); + + for ($j = 0; $j < count($matches[3]); $j++) { + + $str = $matches[3][$j]; + $filename = $matches[2][$j]; + $fileperm = $matches[1][$j]; + + $file = ''; + $str = preg_split("/\r?\n/", trim($str)); + $strlen = count($str); + + for ($i = 0; $i < $strlen; $i++) { + $pos = 1; + $d = 0; + $len=(int)(((ord(substr($str[$i],0,1)) -32) - ' ') & 077); + + while (($d + 3 <= $len) AND ($pos + 4 <= strlen($str[$i]))) { + $c0 = (ord(substr($str[$i],$pos,1)) ^ 0x20); + $c1 = (ord(substr($str[$i],$pos+1,1)) ^ 0x20); + $c2 = (ord(substr($str[$i],$pos+2,1)) ^ 0x20); + $c3 = (ord(substr($str[$i],$pos+3,1)) ^ 0x20); + $file .= chr(((($c0 - ' ') & 077) << 2) | ((($c1 - ' ') & 077) >> 4)); + + $file .= chr(((($c1 - ' ') & 077) << 4) | ((($c2 - ' ') & 077) >> 2)); + + $file .= chr(((($c2 - ' ') & 077) << 6) | (($c3 - ' ') & 077)); + + $pos += 4; + $d += 3; + } + + if (($d + 2 <= $len) && ($pos + 3 <= strlen($str[$i]))) { + $c0 = (ord(substr($str[$i],$pos,1)) ^ 0x20); + $c1 = (ord(substr($str[$i],$pos+1,1)) ^ 0x20); + $c2 = (ord(substr($str[$i],$pos+2,1)) ^ 0x20); + $file .= chr(((($c0 - ' ') & 077) << 2) | ((($c1 - ' ') & 077) >> 4)); + + $file .= chr(((($c1 - ' ') & 077) << 4) | ((($c2 - ' ') & 077) >> 2)); + + $pos += 3; + $d += 2; + } + + if (($d + 1 <= $len) && ($pos + 2 <= strlen($str[$i]))) { + $c0 = (ord(substr($str[$i],$pos,1)) ^ 0x20); + $c1 = (ord(substr($str[$i],$pos+1,1)) ^ 0x20); + $file .= chr(((($c0 - ' ') & 077) << 2) | ((($c1 - ' ') & 077) >> 4)); + + } + } + $files[] = array('filename' => $filename, 'fileperm' => $fileperm, 'filedata' => $file); + } + + return $files; + } + + /** + * getSendArray() returns the arguments required for Mail::send() + * used to build the arguments for a mail::send() call + * + * Usage: + * $mailtext = Full email (for example generated by a template) + * $decoder = new Mail_mimeDecode($mailtext); + * $parts = $decoder->getSendArray(); + * if (!PEAR::isError($parts) { + * list($recipents,$headers,$body) = $parts; + * $mail = Mail::factory('smtp'); + * $mail->send($recipents,$headers,$body); + * } else { + * echo $parts->message; + * } + * @return mixed array of recipeint, headers,body or Pear_Error + * @access public + * @author Alan Knowles + */ + function getSendArray() + { + // prevent warning if this is not set + $this->_decode_headers = FALSE; + $headerlist =$this->_parseHeaders($this->_header); + $to = ""; + if (!$headerlist) { + return $this->raiseError("Message did not contain headers"); + } + foreach($headerlist as $item) { + $header[$item['name']] = $item['value']; + switch (strtolower($item['name'])) { + case "to": + case "cc": + case "bcc": + $to .= ",".$item['value']; + default: + break; + } + } + if ($to == "") { + return $this->raiseError("Message did not contain any recipents"); + } + $to = substr($to,1); + return array($to,$header,$this->_body); + } + + /** + * Returns a xml copy of the output of + * Mail_mimeDecode::decode. Pass the output in as the + * argument. This function can be called statically. Eg: + * + * $output = $obj->decode(); + * $xml = Mail_mimeDecode::getXML($output); + * + * The DTD used for this should have been in the package. Or + * alternatively you can get it from cvs, or here: + * http://www.phpguru.org/xmail/xmail.dtd. + * + * @param object Input to convert to xml. This should be the + * output of the Mail_mimeDecode::decode function + * @return string XML version of input + * @access public + */ + function getXML($input) + { + $crlf = "\r\n"; + $output = '' . $crlf . + '' . $crlf . + '' . $crlf . + Mail_mimeDecode::_getXML($input) . + ''; + + return $output; + } + + /** + * Function that does the actual conversion to xml. Does a single + * mimepart at a time. + * + * @param object Input to convert to xml. This is a mimepart object. + * It may or may not contain subparts. + * @param integer Number of tabs to indent + * @return string XML version of input + * @access private + */ + function _getXML($input, $indent = 1) + { + $htab = "\t"; + $crlf = "\r\n"; + $output = ''; + $headers = @(array)$input->headers; + + foreach ($headers as $hdr_name => $hdr_value) { + + // Multiple headers with this name + if (is_array($headers[$hdr_name])) { + for ($i = 0; $i < count($hdr_value); $i++) { + $output .= Mail_mimeDecode::_getXML_helper($hdr_name, $hdr_value[$i], $indent); + } + + // Only one header of this sort + } else { + $output .= Mail_mimeDecode::_getXML_helper($hdr_name, $hdr_value, $indent); + } + } + + if (!empty($input->parts)) { + for ($i = 0; $i < count($input->parts); $i++) { + $output .= $crlf . str_repeat($htab, $indent) . '' . $crlf . + Mail_mimeDecode::_getXML($input->parts[$i], $indent+1) . + str_repeat($htab, $indent) . '' . $crlf; + } + } elseif (isset($input->body)) { + $output .= $crlf . str_repeat($htab, $indent) . 'body . ']]>' . $crlf; + } + + return $output; + } + + /** + * Helper function to _getXML(). Returns xml of a header. + * + * @param string Name of header + * @param string Value of header + * @param integer Number of tabs to indent + * @return string XML version of input + * @access private + */ + function _getXML_helper($hdr_name, $hdr_value, $indent) + { + $htab = "\t"; + $crlf = "\r\n"; + $return = ''; + + $new_hdr_value = ($hdr_name != 'received') ? Mail_mimeDecode::_parseHeaderValue($hdr_value) : array('value' => $hdr_value); + $new_hdr_name = str_replace(' ', '-', ucwords(str_replace('-', ' ', $hdr_name))); + + // Sort out any parameters + if (!empty($new_hdr_value['other'])) { + foreach ($new_hdr_value['other'] as $paramname => $paramvalue) { + $params[] = str_repeat($htab, $indent) . $htab . '' . $crlf . + str_repeat($htab, $indent) . $htab . $htab . '' . htmlspecialchars($paramname) . '' . $crlf . + str_repeat($htab, $indent) . $htab . $htab . '' . htmlspecialchars($paramvalue) . '' . $crlf . + str_repeat($htab, $indent) . $htab . '' . $crlf; + } + + $params = implode('', $params); + } else { + $params = ''; + } + + $return = str_repeat($htab, $indent) . '
    ' . $crlf . + str_repeat($htab, $indent) . $htab . '' . htmlspecialchars($new_hdr_name) . '' . $crlf . + str_repeat($htab, $indent) . $htab . '' . htmlspecialchars($new_hdr_value['value']) . '' . $crlf . + $params . + str_repeat($htab, $indent) . '
    ' . $crlf; + + return $return; + } + +} // End of class diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/Net_URL2/Net/URL2.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/Net_URL2/Net/URL2.php new file mode 100644 index 0000000..b4ae3ec --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/Net_URL2/Net/URL2.php @@ -0,0 +1,1219 @@ + + * @copyright 2007-2009 Peytz & Co. A/S + * @license https://spdx.org/licenses/BSD-3-Clause BSD-3-Clause + * @version CVS: $Id$ + * @link https://tools.ietf.org/html/rfc3986 + */ + +/** + * Represents a URL as per RFC 3986. + * + * @category Networking + * @package Net_URL2 + * @author Christian Schmidt + * @copyright 2007-2009 Peytz & Co. A/S + * @license https://spdx.org/licenses/BSD-3-Clause BSD-3-Clause + * @version Release: 2.2.1 + * @link https://pear.php.net/package/Net_URL2 + */ +class Net_URL2 +{ + /** + * Do strict parsing in resolve() (see RFC 3986, section 5.2.2). Default + * is true. + */ + const OPTION_STRICT = 'strict'; + + /** + * Represent arrays in query using PHP's [] notation. Default is true. + */ + const OPTION_USE_BRACKETS = 'use_brackets'; + + /** + * Drop zero-based integer sequences in query using PHP's [] notation. Default + * is true. + */ + const OPTION_DROP_SEQUENCE = 'drop_sequence'; + + /** + * URL-encode query variable keys. Default is true. + */ + const OPTION_ENCODE_KEYS = 'encode_keys'; + + /** + * Query variable separators when parsing the query string. Every character + * is considered a separator. Default is "&". + */ + const OPTION_SEPARATOR_INPUT = 'input_separator'; + + /** + * Query variable separator used when generating the query string. Default + * is "&". + */ + const OPTION_SEPARATOR_OUTPUT = 'output_separator'; + + /** + * Default options corresponds to how PHP handles $_GET. + */ + private $_options = array( + self::OPTION_STRICT => true, + self::OPTION_USE_BRACKETS => true, + self::OPTION_DROP_SEQUENCE => true, + self::OPTION_ENCODE_KEYS => true, + self::OPTION_SEPARATOR_INPUT => '&', + self::OPTION_SEPARATOR_OUTPUT => '&', + ); + + /** + * @var string|bool + */ + private $_scheme = false; + + /** + * @var string|bool + */ + private $_userinfo = false; + + /** + * @var string|bool + */ + private $_host = false; + + /** + * @var string|bool + */ + private $_port = false; + + /** + * @var string + */ + private $_path = ''; + + /** + * @var string|bool + */ + private $_query = false; + + /** + * @var string|bool + */ + private $_fragment = false; + + /** + * Constructor. + * + * @param string $url an absolute or relative URL + * @param array $options an array of OPTION_xxx constants + * + * @uses self::parseUrl() + */ + public function __construct($url, array $options = array()) + { + foreach ($options as $optionName => $value) { + if (array_key_exists($optionName, $this->_options)) { + $this->_options[$optionName] = $value; + } + } + + $this->parseUrl($url); + } + + /** + * Magic Setter. + * + * This method will magically set the value of a private variable ($var) + * with the value passed as the args + * + * @param string $var The private variable to set. + * @param mixed $arg An argument of any type. + * + * @return void + */ + public function __set($var, $arg) + { + $method = 'set' . $var; + if (method_exists($this, $method)) { + $this->$method($arg); + } + } + + /** + * Magic Getter. + * + * This is the magic get method to retrieve the private variable + * that was set by either __set() or it's setter... + * + * @param string $var The property name to retrieve. + * + * @return mixed $this->$var Either a boolean false if the + * property is not set or the value + * of the private property. + */ + public function __get($var) + { + $method = 'get' . $var; + if (method_exists($this, $method)) { + return $this->$method(); + } + + return false; + } + + /** + * Returns the scheme, e.g. "http" or "urn", or false if there is no + * scheme specified, i.e. if this is a relative URL. + * + * @return string|bool + */ + public function getScheme() + { + return $this->_scheme; + } + + /** + * Sets the scheme, e.g. "http" or "urn". Specify false if there is no + * scheme specified, i.e. if this is a relative URL. + * + * @param string|bool $scheme e.g. "http" or "urn", or false if there is no + * scheme specified, i.e. if this is a relative + * URL + * + * @return $this + * @see getScheme + */ + public function setScheme($scheme) + { + $this->_scheme = $scheme; + return $this; + } + + /** + * Returns the user part of the userinfo part (the part preceding the first + * ":"), or false if there is no userinfo part. + * + * @return string|bool + */ + public function getUser() + { + return $this->_userinfo !== false + ? preg_replace('(:.*$)', '', $this->_userinfo) + : false; + } + + /** + * Returns the password part of the userinfo part (the part after the first + * ":"), or false if there is no userinfo part (i.e. the URL does not + * contain "@" in front of the hostname) or the userinfo part does not + * contain ":". + * + * @return string|bool + */ + public function getPassword() + { + return $this->_userinfo !== false + ? substr(strstr($this->_userinfo, ':'), 1) + : false; + } + + /** + * Returns the userinfo part, or false if there is none, i.e. if the + * authority part does not contain "@". + * + * @return string|bool + */ + public function getUserinfo() + { + return $this->_userinfo; + } + + /** + * Sets the userinfo part. If two arguments are passed, they are combined + * in the userinfo part as username ":" password. + * + * @param string|bool $userinfo userinfo or username + * @param string|bool $password optional password, or false + * + * @return $this + */ + public function setUserinfo($userinfo, $password = false) + { + if ($password !== false) { + $userinfo .= ':' . $password; + } + + if ($userinfo !== false) { + $userinfo = $this->_encodeData($userinfo); + } + + $this->_userinfo = $userinfo; + return $this; + } + + /** + * Returns the host part, or false if there is no authority part, e.g. + * relative URLs. + * + * @return string|bool a hostname, an IP address, or false + */ + public function getHost() + { + return $this->_host; + } + + /** + * Sets the host part. Specify false if there is no authority part, e.g. + * relative URLs. + * + * @param string|bool $host a hostname, an IP address, or false + * + * @return $this + */ + public function setHost($host) + { + $this->_host = $host; + return $this; + } + + /** + * Returns the port number, or false if there is no port number specified, + * i.e. if the default port is to be used. + * + * @return string|bool + */ + public function getPort() + { + return $this->_port; + } + + /** + * Sets the port number. Specify false if there is no port number specified, + * i.e. if the default port is to be used. + * + * @param string|bool $port a port number, or false + * + * @return $this + */ + public function setPort($port) + { + $this->_port = $port; + return $this; + } + + /** + * Returns the authority part, i.e. [ userinfo "@" ] host [ ":" port ], or + * false if there is no authority. + * + * @return string|bool + */ + public function getAuthority() + { + if (false === $this->_host) { + return false; + } + + $authority = ''; + + if (strlen($this->_userinfo)) { + $authority .= $this->_userinfo . '@'; + } + + $authority .= $this->_host; + + if ($this->_port !== false) { + $authority .= ':' . $this->_port; + } + + return $authority; + } + + /** + * Sets the authority part, i.e. [ userinfo "@" ] host [ ":" port ]. Specify + * false if there is no authority. + * + * @param string|bool $authority a hostname or an IP address, possibly + * with userinfo prefixed and port number + * appended, e.g. "foo:bar@example.org:81". + * + * @return $this + */ + public function setAuthority($authority) + { + $this->_userinfo = false; + $this->_host = false; + $this->_port = false; + + if ('' === $authority) { + $this->_host = $authority; + return $this; + } + + if (!preg_match('(^(([^@]*)@)?(.+?)(:(\d*))?$)', $authority, $matches)) { + return $this; + } + + if ($matches[1]) { + $this->_userinfo = $this->_encodeData($matches[2]); + } + + $this->_host = $matches[3]; + + if (isset($matches[5]) && strlen($matches[5])) { + $this->_port = $matches[5]; + } + return $this; + } + + /** + * Returns the path part (possibly an empty string). + * + * @return string + */ + public function getPath() + { + return $this->_path; + } + + /** + * Sets the path part (possibly an empty string). + * + * @param string $path a path + * + * @return $this + */ + public function setPath($path) + { + $this->_path = $path; + return $this; + } + + /** + * Returns the query string (excluding the leading "?"), or false if "?" + * is not present in the URL. + * + * @return string|bool + * @see getQueryVariables + */ + public function getQuery() + { + return $this->_query; + } + + /** + * Sets the query string (excluding the leading "?"). Specify false if "?" + * is not present in the URL. + * + * @param string|bool $query a query string, e.g. "foo=1&bar=2" + * + * @return $this + * @see setQueryVariables + */ + public function setQuery($query) + { + $this->_query = $query; + return $this; + } + + /** + * Returns the fragment name, or false if "#" is not present in the URL. + * + * @return string|bool + */ + public function getFragment() + { + return $this->_fragment; + } + + /** + * Sets the fragment name. Specify false if "#" is not present in the URL. + * + * @param string|bool $fragment a fragment excluding the leading "#", or + * false + * + * @return $this + */ + public function setFragment($fragment) + { + $this->_fragment = $fragment; + return $this; + } + + /** + * Returns the query string like an array as the variables would appear in + * $_GET in a PHP script. If the URL does not contain a "?", an empty array + * is returned. + * + * @return array + */ + public function getQueryVariables() + { + $separator = $this->getOption(self::OPTION_SEPARATOR_INPUT); + $encodeKeys = $this->getOption(self::OPTION_ENCODE_KEYS); + $useBrackets = $this->getOption(self::OPTION_USE_BRACKETS); + + $return = array(); + + for ($part = strtok($this->_query, $separator); + strlen($part); + $part = strtok($separator) + ) { + list($key, $value) = explode('=', $part, 2) + array(1 => ''); + + if ($encodeKeys) { + $key = rawurldecode($key); + } + $value = rawurldecode($value); + + if ($useBrackets) { + $return = $this->_queryArrayByKey($key, $value, $return); + } else { + if (isset($return[$key])) { + $return[$key] = (array) $return[$key]; + $return[$key][] = $value; + } else { + $return[$key] = $value; + } + } + } + + return $return; + } + + /** + * Parse a single query key=value pair into an existing php array + * + * @param string $key query-key + * @param string $value query-value + * @param array $array of existing query variables (if any) + * + * @return mixed + */ + private function _queryArrayByKey($key, $value, array $array = array()) + { + if (!strlen($key)) { + return $array; + } + + $offset = $this->_queryKeyBracketOffset($key); + if ($offset === false) { + $name = $key; + } else { + $name = substr($key, 0, $offset); + } + + if (!strlen($name)) { + return $array; + } + + if (!$offset) { + // named value + $array[$name] = $value; + } else { + // array + $brackets = substr($key, $offset); + if (!isset($array[$name])) { + $array[$name] = null; + } + $array[$name] = $this->_queryArrayByBrackets( + $brackets, $value, $array[$name] + ); + } + + return $array; + } + + /** + * Parse a key-buffer to place value in array + * + * @param string $buffer to consume all keys from + * @param string $value to be set/add + * @param array $array to traverse and set/add value in + * + * @throws Exception + * @return array + */ + private function _queryArrayByBrackets($buffer, $value, array $array = null) + { + $entry = &$array; + + for ($iteration = 0; strlen($buffer); $iteration++) { + $open = $this->_queryKeyBracketOffset($buffer); + if ($open !== 0) { + // Opening bracket [ must exist at offset 0, if not, there is + // no bracket to parse and the value dropped. + // if this happens in the first iteration, this is flawed, see + // as well the second exception below. + if ($iteration) { + break; + } + // @codeCoverageIgnoreStart + throw new Exception( + 'Net_URL2 Internal Error: '. __METHOD__ .'(): ' . + 'Opening bracket [ must exist at offset 0' + ); + // @codeCoverageIgnoreEnd + } + + $close = strpos($buffer, ']', 1); + if (!$close) { + // this error condition should never be reached as this is a + // private method and bracket pairs are checked beforehand. + // See as well the first exception for the opening bracket. + // @codeCoverageIgnoreStart + throw new Exception( + 'Net_URL2 Internal Error: '. __METHOD__ .'(): ' . + 'Closing bracket ] must exist, not found' + ); + // @codeCoverageIgnoreEnd + } + + $index = substr($buffer, 1, $close - 1); + if (strlen($index)) { + $entry = &$entry[$index]; + } else { + if (!is_array($entry)) { + $entry = array(); + } + $entry[] = &$new; + $entry = &$new; + unset($new); + } + $buffer = substr($buffer, $close + 1); + } + + $entry = $value; + + return $array; + } + + /** + * Query-key has brackets ("...[]") + * + * @param string $key query-key + * + * @return bool|int offset of opening bracket, false if no brackets + */ + private function _queryKeyBracketOffset($key) + { + if (false !== $open = strpos($key, '[') + and false === strpos($key, ']', $open + 1) + ) { + $open = false; + } + + return $open; + } + + /** + * Sets the query string to the specified variable in the query string. + * + * @param array $array (name => value) array + * + * @return $this + */ + public function setQueryVariables(array $array) + { + if (!$array) { + $this->_query = false; + } else { + $this->_query = $this->buildQuery( + $array, + $this->getOption(self::OPTION_SEPARATOR_OUTPUT) + ); + } + return $this; + } + + /** + * Sets the specified variable in the query string. + * + * @param string $name variable name + * @param mixed $value variable value + * + * @return $this + */ + public function setQueryVariable($name, $value) + { + $array = $this->getQueryVariables(); + $array[$name] = $value; + $this->setQueryVariables($array); + return $this; + } + + /** + * Removes the specified variable from the query string. + * + * @param string $name a query string variable, e.g. "foo" in "?foo=1" + * + * @return void + */ + public function unsetQueryVariable($name) + { + $array = $this->getQueryVariables(); + unset($array[$name]); + $this->setQueryVariables($array); + } + + /** + * Returns a string representation of this URL. + * + * @return string + */ + public function getURL() + { + // See RFC 3986, section 5.3 + $url = ''; + + if ($this->_scheme !== false) { + $url .= $this->_scheme . ':'; + } + + $authority = $this->getAuthority(); + if ($authority === false && strtolower($this->_scheme) === 'file') { + $authority = ''; + } + + $url .= $this->_buildAuthorityAndPath($authority, $this->_path); + + if ($this->_query !== false) { + $url .= '?' . $this->_query; + } + + if ($this->_fragment !== false) { + $url .= '#' . $this->_fragment; + } + + return $url; + } + + /** + * Put authority and path together, wrapping authority + * into proper separators/terminators. + * + * @param string|bool $authority authority + * @param string $path path + * + * @return string + */ + private function _buildAuthorityAndPath($authority, $path) + { + if ($authority === false) { + return $path; + } + + $terminator = ($path !== '' && $path[0] !== '/') ? '/' : ''; + + return '//' . $authority . $terminator . $path; + } + + /** + * Returns a string representation of this URL. + * + * @return string + * @link https://php.net/language.oop5.magic#object.tostring + */ + public function __toString() + { + return $this->getURL(); + } + + /** + * Returns a normalized string representation of this URL. This is useful + * for comparison of URLs. + * + * @return string + */ + public function getNormalizedURL() + { + $url = clone $this; + $url->normalize(); + return $url->getURL(); + } + + /** + * Normalizes the URL + * + * See RFC 3986, Section 6. Normalization and Comparison + * + * @link https://tools.ietf.org/html/rfc3986#section-6 + * + * @return void + */ + public function normalize() + { + // See RFC 3986, section 6 + + // Scheme is case-insensitive + if ($this->_scheme) { + $this->_scheme = strtolower($this->_scheme); + } + + // Hostname is case-insensitive + if ($this->_host) { + $this->_host = strtolower($this->_host); + } + + // Remove default port number for known schemes (RFC 3986, section 6.2.3) + if ('' === $this->_port + || $this->_port + && $this->_scheme + && $this->_port == getservbyname($this->_scheme, 'tcp') + ) { + $this->_port = false; + } + + // Normalize case of %XX percentage-encodings (RFC 3986, section 6.2.2.1) + // Normalize percentage-encoded unreserved characters (section 6.2.2.2) + $fields = array(&$this->_userinfo, &$this->_host, &$this->_path, + &$this->_query, &$this->_fragment); + foreach ($fields as &$field) { + if ($field !== false) { + $field = $this->_normalize("$field"); + } + } + unset($field); + + // Path segment normalization (RFC 3986, section 6.2.2.3) + $this->_path = self::removeDotSegments($this->_path); + + // Scheme based normalization (RFC 3986, section 6.2.3) + if (false !== $this->_host && '' === $this->_path) { + $this->_path = '/'; + } + + // path should start with '/' if there is authority (section 3.3.) + if (strlen($this->getAuthority()) + && strlen($this->_path) + && $this->_path[0] !== '/' + ) { + $this->_path = '/' . $this->_path; + } + } + + /** + * Normalize case of %XX percentage-encodings (RFC 3986, section 6.2.2.1) + * Normalize percentage-encoded unreserved characters (section 6.2.2.2) + * + * @param string|array $mixed string or array of strings to normalize + * + * @return string|array + * @see normalize + * @see _normalizeCallback() + */ + private function _normalize($mixed) + { + return preg_replace_callback( + '((?:%[0-9a-fA-Z]{2})+)', array($this, '_normalizeCallback'), + $mixed + ); + } + + /** + * Callback for _normalize() of %XX percentage-encodings + * + * @param array $matches as by preg_replace_callback + * + * @return string + * @see normalize + * @see _normalize + * @SuppressWarnings(PHPMD.UnusedPrivateMethod) + */ + private function _normalizeCallback($matches) + { + return self::urlencode(urldecode($matches[0])); + } + + /** + * Returns whether this instance represents an absolute URL. + * + * @return bool + */ + public function isAbsolute() + { + return (bool) $this->_scheme; + } + + /** + * Returns an Net_URL2 instance representing an absolute URL relative to + * this URL. + * + * @param Net_URL2|string $reference relative URL + * + * @throws Exception + * @return $this + */ + public function resolve($reference) + { + if (!$reference instanceof Net_URL2) { + $reference = new self($reference); + } + if (!$reference->_isFragmentOnly() && !$this->isAbsolute()) { + throw new Exception( + 'Base-URL must be absolute if reference is not fragment-only' + ); + } + + // A non-strict parser may ignore a scheme in the reference if it is + // identical to the base URI's scheme. + if (!$this->getOption(self::OPTION_STRICT) + && $reference->_scheme == $this->_scheme + ) { + $reference->_scheme = false; + } + + $target = new self(''); + if ($reference->_scheme !== false) { + $target->_scheme = $reference->_scheme; + $target->setAuthority($reference->getAuthority()); + $target->_path = self::removeDotSegments($reference->_path); + $target->_query = $reference->_query; + } else { + $authority = $reference->getAuthority(); + if ($authority !== false) { + $target->setAuthority($authority); + $target->_path = self::removeDotSegments($reference->_path); + $target->_query = $reference->_query; + } else { + if ($reference->_path == '') { + $target->_path = $this->_path; + if ($reference->_query !== false) { + $target->_query = $reference->_query; + } else { + $target->_query = $this->_query; + } + } else { + if (substr($reference->_path, 0, 1) == '/') { + $target->_path = self::removeDotSegments($reference->_path); + } else { + // Merge paths (RFC 3986, section 5.2.3) + if ($this->_host !== false && $this->_path == '') { + $target->_path = '/' . $reference->_path; + } else { + $i = strrpos($this->_path, '/'); + if ($i !== false) { + $target->_path = substr($this->_path, 0, $i + 1); + } + $target->_path .= $reference->_path; + } + $target->_path = self::removeDotSegments($target->_path); + } + $target->_query = $reference->_query; + } + $target->setAuthority($this->getAuthority()); + } + $target->_scheme = $this->_scheme; + } + + $target->_fragment = $reference->_fragment; + + return $target; + } + + /** + * URL is fragment-only + * + * @SuppressWarnings(PHPMD.UnusedPrivateMethod) + * @return bool + */ + private function _isFragmentOnly() + { + return ( + $this->_fragment !== false + && $this->_query === false + && $this->_path === '' + && $this->_port === false + && $this->_host === false + && $this->_userinfo === false + && $this->_scheme === false + ); + } + + /** + * Removes dots as described in RFC 3986, section 5.2.4, e.g. + * "/foo/../bar/baz" => "/bar/baz" + * + * @param string $path a path + * + * @return string a path + */ + public static function removeDotSegments($path) + { + $path = (string) $path; + $output = ''; + + // Make sure not to be trapped in an infinite loop due to a bug in this + // method + $loopLimit = 256; + $j = 0; + while ('' !== $path && $j++ < $loopLimit) { + if (substr($path, 0, 2) === './') { + // Step 2.A + $path = substr($path, 2); + } elseif (substr($path, 0, 3) === '../') { + // Step 2.A + $path = substr($path, 3); + } elseif (substr($path, 0, 3) === '/./' || $path === '/.') { + // Step 2.B + $path = '/' . substr($path, 3); + } elseif (substr($path, 0, 4) === '/../' || $path === '/..') { + // Step 2.C + $path = '/' . substr($path, 4); + $i = strrpos($output, '/'); + $output = $i === false ? '' : substr($output, 0, $i); + } elseif ($path === '.' || $path === '..') { + // Step 2.D + $path = ''; + } else { + // Step 2.E + $i = strpos($path, '/', $path[0] === '/'); + if ($i === false) { + $output .= $path; + $path = ''; + break; + } + $output .= substr($path, 0, $i); + $path = substr($path, $i); + } + } + + if ($path !== '') { + $message = sprintf( + 'Unable to remove dot segments; hit loop limit %d (left: %s)', + $j, var_export($path, true) + ); + trigger_error($message, E_USER_WARNING); + } + + return $output; + } + + /** + * Percent-encodes all non-alphanumeric characters except these: _ . - ~ + * Similar to PHP's rawurlencode(), except that it also encodes ~ in PHP + * 5.2.x and earlier. + * + * @param string $string string to encode + * + * @return string + */ + public static function urlencode($string) + { + $encoded = rawurlencode($string); + + // This is only necessary in PHP < 5.3. + $encoded = str_replace('%7E', '~', $encoded); + return $encoded; + } + + /** + * Returns a Net_URL2 instance representing the canonical URL of the + * currently executing PHP script. + * + * @throws Exception + * @return string + */ + public static function getCanonical() + { + if (!isset($_SERVER['REQUEST_METHOD'])) { + // ALERT - no current URL + throw new Exception('Script was not called through a webserver'); + } + + // Begin with a relative URL + $url = new self($_SERVER['PHP_SELF']); + $url->_scheme = isset($_SERVER['HTTPS']) ? 'https' : 'http'; + $url->_host = $_SERVER['SERVER_NAME']; + $port = $_SERVER['SERVER_PORT']; + if ($url->_scheme == 'http' && $port != 80 + || $url->_scheme == 'https' && $port != 443 + ) { + $url->_port = $port; + } + return $url; + } + + /** + * Returns the URL used to retrieve the current request. + * + * @return string + */ + public static function getRequestedURL() + { + return self::getRequested()->getUrl(); + } + + /** + * Returns a Net_URL2 instance representing the URL used to retrieve the + * current request. + * + * @throws Exception + * @return $this + */ + public static function getRequested() + { + if (!isset($_SERVER['REQUEST_METHOD'])) { + // ALERT - no current URL + throw new Exception('Script was not called through a webserver'); + } + + // Begin with a relative URL + $url = new self($_SERVER['REQUEST_URI']); + $url->_scheme = isset($_SERVER['HTTPS']) ? 'https' : 'http'; + // Set host and possibly port + $url->setAuthority($_SERVER['HTTP_HOST']); + return $url; + } + + /** + * Returns the value of the specified option. + * + * @param string $optionName The name of the option to retrieve + * + * @return mixed + */ + public function getOption($optionName) + { + return isset($this->_options[$optionName]) + ? $this->_options[$optionName] : false; + } + + /** + * A simple version of http_build_query in userland. The encoded string is + * percentage encoded according to RFC 3986. + * + * @param array $data An array, which has to be converted into + * QUERY_STRING. Anything is possible. + * @param string $separator Separator {@link self::OPTION_SEPARATOR_OUTPUT} + * @param string $key For stacked values (arrays in an array). + * + * @return string + */ + protected function buildQuery(array $data, $separator, $key = null) + { + $query = array(); + $drop_names = ( + $this->_options[self::OPTION_DROP_SEQUENCE] === true + && array_keys($data) === array_keys(array_values($data)) + ); + foreach ($data as $name => $value) { + if ($this->getOption(self::OPTION_ENCODE_KEYS) === true) { + $name = rawurlencode($name); + } + if ($key !== null) { + if ($this->getOption(self::OPTION_USE_BRACKETS) === true) { + $drop_names && $name = ''; + $name = $key . '[' . $name . ']'; + } else { + $name = $key; + } + } + if (is_array($value)) { + $query[] = $this->buildQuery($value, $separator, $name); + } else { + $query[] = $name . '=' . rawurlencode($value); + } + } + return implode($separator, $query); + } + + /** + * This method uses a regex to parse the url into the designated parts. + * + * @param string $url URL + * + * @return void + * @uses self::$_scheme, self::setAuthority(), self::$_path, self::$_query, + * self::$_fragment + * @see __construct + */ + protected function parseUrl($url) + { + // The regular expression is copied verbatim from RFC 3986, appendix B. + // The expression does not validate the URL but matches any string. + preg_match( + '(^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?)', + $url, $matches + ); + + // "path" is always present (possibly as an empty string); the rest + // are optional. + $this->_scheme = !empty($matches[1]) ? $matches[2] : false; + $this->setAuthority(!empty($matches[3]) ? $matches[4] : false); + $this->_path = $this->_encodeData($matches[5]); + $this->_query = !empty($matches[6]) + ? $this->_encodeData($matches[7]) + : false + ; + $this->_fragment = !empty($matches[8]) ? $matches[9] : false; + } + + /** + * Encode characters that might have been forgotten to encode when passing + * in an URL. Applied onto Userinfo, Path and Query. + * + * @param string $url URL + * + * @return string + * @see parseUrl + * @see setAuthority + * @link https://pear.php.net/bugs/bug.php?id=20425 + */ + private function _encodeData($url) + { + return preg_replace_callback( + '([\x-\x20\x22\x3C\x3E\x7F-\xFF]+)', + array($this, '_encodeCallback'), $url + ); + } + + /** + * callback for encoding character data + * + * @param array $matches Matches + * + * @return string + * @see _encodeData + * @SuppressWarnings(PHPMD.UnusedPrivateMethod) + */ + private function _encodeCallback(array $matches) + { + return rawurlencode($matches[0]); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/OS/Guess.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/OS/Guess.php new file mode 100644 index 0000000..4c9254a --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/OS/Guess.php @@ -0,0 +1,337 @@ + + * @author Gregory Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since PEAR 0.1 + */ + +// {{{ uname examples + +// php_uname() without args returns the same as 'uname -a', or a PHP-custom +// string for Windows. +// PHP versions prior to 4.3 return the uname of the host where PHP was built, +// as of 4.3 it returns the uname of the host running the PHP code. +// +// PC RedHat Linux 7.1: +// Linux host.example.com 2.4.2-2 #1 Sun Apr 8 20:41:30 EDT 2001 i686 unknown +// +// PC Debian Potato: +// Linux host 2.4.17 #2 SMP Tue Feb 12 15:10:04 CET 2002 i686 unknown +// +// PC FreeBSD 3.3: +// FreeBSD host.example.com 3.3-STABLE FreeBSD 3.3-STABLE #0: Mon Feb 21 00:42:31 CET 2000 root@example.com:/usr/src/sys/compile/CONFIG i386 +// +// PC FreeBSD 4.3: +// FreeBSD host.example.com 4.3-RELEASE FreeBSD 4.3-RELEASE #1: Mon Jun 25 11:19:43 EDT 2001 root@example.com:/usr/src/sys/compile/CONFIG i386 +// +// PC FreeBSD 4.5: +// FreeBSD host.example.com 4.5-STABLE FreeBSD 4.5-STABLE #0: Wed Feb 6 23:59:23 CET 2002 root@example.com:/usr/src/sys/compile/CONFIG i386 +// +// PC FreeBSD 4.5 w/uname from GNU shellutils: +// FreeBSD host.example.com 4.5-STABLE FreeBSD 4.5-STABLE #0: Wed Feb i386 unknown +// +// HP 9000/712 HP-UX 10: +// HP-UX iq B.10.10 A 9000/712 2008429113 two-user license +// +// HP 9000/712 HP-UX 10 w/uname from GNU shellutils: +// HP-UX host B.10.10 A 9000/712 unknown +// +// IBM RS6000/550 AIX 4.3: +// AIX host 3 4 000003531C00 +// +// AIX 4.3 w/uname from GNU shellutils: +// AIX host 3 4 000003531C00 unknown +// +// SGI Onyx IRIX 6.5 w/uname from GNU shellutils: +// IRIX64 host 6.5 01091820 IP19 mips +// +// SGI Onyx IRIX 6.5: +// IRIX64 host 6.5 01091820 IP19 +// +// SparcStation 20 Solaris 8 w/uname from GNU shellutils: +// SunOS host.example.com 5.8 Generic_108528-12 sun4m sparc +// +// SparcStation 20 Solaris 8: +// SunOS host.example.com 5.8 Generic_108528-12 sun4m sparc SUNW,SPARCstation-20 +// +// Mac OS X (Darwin) +// Darwin home-eden.local 7.5.0 Darwin Kernel Version 7.5.0: Thu Aug 5 19:26:16 PDT 2004; root:xnu/xnu-517.7.21.obj~3/RELEASE_PPC Power Macintosh +// +// Mac OS X early versions +// + +// }}} + +/* TODO: + * - define endianness, to allow matchSignature("bigend") etc. + */ + +/** + * Retrieves information about the current operating system + * + * This class uses php_uname() to grok information about the current OS + * + * @category pear + * @package PEAR + * @author Stig Bakken + * @author Gregory Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 0.1 + */ +class OS_Guess +{ + var $sysname; + var $nodename; + var $cpu; + var $release; + var $extra; + + function __construct($uname = null) + { + list($this->sysname, + $this->release, + $this->cpu, + $this->extra, + $this->nodename) = $this->parseSignature($uname); + } + + function parseSignature($uname = null) + { + static $sysmap = array( + 'HP-UX' => 'hpux', + 'IRIX64' => 'irix', + ); + static $cpumap = array( + 'i586' => 'i386', + 'i686' => 'i386', + 'ppc' => 'powerpc', + ); + if ($uname === null) { + $uname = php_uname(); + } + $parts = preg_split('/\s+/', trim($uname)); + $n = count($parts); + + $release = $machine = $cpu = ''; + $sysname = $parts[0]; + $nodename = $parts[1]; + $cpu = $parts[$n-1]; + $extra = ''; + if ($cpu == 'unknown') { + $cpu = $parts[$n - 2]; + } + + switch ($sysname) { + case 'AIX' : + $release = "$parts[3].$parts[2]"; + break; + case 'Windows' : + switch ($parts[1]) { + case '95/98': + $release = '9x'; + break; + default: + $release = $parts[1]; + break; + } + $cpu = 'i386'; + break; + case 'Linux' : + $extra = $this->_detectGlibcVersion(); + // use only the first two digits from the kernel version + $release = preg_replace('/^([0-9]+\.[0-9]+).*/', '\1', $parts[2]); + break; + case 'Mac' : + $sysname = 'darwin'; + $nodename = $parts[2]; + $release = $parts[3]; + if ($cpu == 'Macintosh') { + if ($parts[$n - 2] == 'Power') { + $cpu = 'powerpc'; + } + } + break; + case 'Darwin' : + if ($cpu == 'Macintosh') { + if ($parts[$n - 2] == 'Power') { + $cpu = 'powerpc'; + } + } + $release = preg_replace('/^([0-9]+\.[0-9]+).*/', '\1', $parts[2]); + break; + default: + $release = preg_replace('/-.*/', '', $parts[2]); + break; + } + + if (isset($sysmap[$sysname])) { + $sysname = $sysmap[$sysname]; + } else { + $sysname = strtolower($sysname); + } + if (isset($cpumap[$cpu])) { + $cpu = $cpumap[$cpu]; + } + return array($sysname, $release, $cpu, $extra, $nodename); + } + + function _detectGlibcVersion() + { + static $glibc = false; + if ($glibc !== false) { + return $glibc; // no need to run this multiple times + } + $major = $minor = 0; + include_once "System.php"; + // Use glibc's header file to + // get major and minor version number: + if (@file_exists('/usr/include/features.h') && + @is_readable('/usr/include/features.h')) { + if (!@file_exists('/usr/bin/cpp') || !@is_executable('/usr/bin/cpp')) { + $features_file = fopen('/usr/include/features.h', 'rb'); + while (!feof($features_file)) { + $line = fgets($features_file, 8192); + if (!$line || (strpos($line, '#define') === false)) { + continue; + } + if (strpos($line, '__GLIBC__')) { + // major version number #define __GLIBC__ version + $line = preg_split('/\s+/', $line); + $glibc_major = trim($line[2]); + if (isset($glibc_minor)) { + break; + } + continue; + } + + if (strpos($line, '__GLIBC_MINOR__')) { + // got the minor version number + // #define __GLIBC_MINOR__ version + $line = preg_split('/\s+/', $line); + $glibc_minor = trim($line[2]); + if (isset($glibc_major)) { + break; + } + continue; + } + } + fclose($features_file); + if (!isset($glibc_major) || !isset($glibc_minor)) { + return $glibc = ''; + } + return $glibc = 'glibc' . trim($glibc_major) . "." . trim($glibc_minor) ; + } // no cpp + + $tmpfile = System::mktemp("glibctest"); + $fp = fopen($tmpfile, "w"); + fwrite($fp, "#include \n__GLIBC__ __GLIBC_MINOR__\n"); + fclose($fp); + $cpp = popen("/usr/bin/cpp $tmpfile", "r"); + while ($line = fgets($cpp, 1024)) { + if ($line{0} == '#' || trim($line) == '') { + continue; + } + + if (list($major, $minor) = explode(' ', trim($line))) { + break; + } + } + pclose($cpp); + unlink($tmpfile); + } // features.h + + if (!($major && $minor) && @is_link('/lib/libc.so.6')) { + // Let's try reading the libc.so.6 symlink + if (preg_match('/^libc-(.*)\.so$/', basename(readlink('/lib/libc.so.6')), $matches)) { + list($major, $minor) = explode('.', $matches[1]); + } + } + + if (!($major && $minor)) { + return $glibc = ''; + } + + return $glibc = "glibc{$major}.{$minor}"; + } + + function getSignature() + { + if (empty($this->extra)) { + return "{$this->sysname}-{$this->release}-{$this->cpu}"; + } + return "{$this->sysname}-{$this->release}-{$this->cpu}-{$this->extra}"; + } + + function getSysname() + { + return $this->sysname; + } + + function getNodename() + { + return $this->nodename; + } + + function getCpu() + { + return $this->cpu; + } + + function getRelease() + { + return $this->release; + } + + function getExtra() + { + return $this->extra; + } + + function matchSignature($match) + { + $fragments = is_array($match) ? $match : explode('-', $match); + $n = count($fragments); + $matches = 0; + if ($n > 0) { + $matches += $this->_matchFragment($fragments[0], $this->sysname); + } + if ($n > 1) { + $matches += $this->_matchFragment($fragments[1], $this->release); + } + if ($n > 2) { + $matches += $this->_matchFragment($fragments[2], $this->cpu); + } + if ($n > 3) { + $matches += $this->_matchFragment($fragments[3], $this->extra); + } + return ($matches == $n); + } + + function _matchFragment($fragment, $value) + { + if (strcspn($fragment, '*?') < strlen($fragment)) { + $reg = '/^' . str_replace(array('*', '?', '/'), array('.*', '.', '\\/'), $fragment) . '\\z/'; + return preg_match($reg, $value); + } + return ($fragment == '*' || !strcasecmp($fragment, $value)); + } + +} +/* + * Local Variables: + * indent-tabs-mode: nil + * c-basic-offset: 4 + * End: + */ diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR.php new file mode 100644 index 0000000..d661cc2 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR.php @@ -0,0 +1,1112 @@ + + * @author Stig Bakken + * @author Tomas V.V.Cox + * @author Greg Beaver + * @copyright 1997-2010 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 0.1 + */ + +/**#@+ + * ERROR constants + */ +define('PEAR_ERROR_RETURN', 1); +define('PEAR_ERROR_PRINT', 2); +define('PEAR_ERROR_TRIGGER', 4); +define('PEAR_ERROR_DIE', 8); +define('PEAR_ERROR_CALLBACK', 16); +/** + * WARNING: obsolete + * @deprecated + */ +define('PEAR_ERROR_EXCEPTION', 32); +/**#@-*/ + +if (substr(PHP_OS, 0, 3) == 'WIN') { + define('OS_WINDOWS', true); + define('OS_UNIX', false); + define('PEAR_OS', 'Windows'); +} else { + define('OS_WINDOWS', false); + define('OS_UNIX', true); + define('PEAR_OS', 'Unix'); // blatant assumption +} + +$GLOBALS['_PEAR_default_error_mode'] = PEAR_ERROR_RETURN; +$GLOBALS['_PEAR_default_error_options'] = E_USER_NOTICE; +$GLOBALS['_PEAR_destructor_object_list'] = array(); +$GLOBALS['_PEAR_shutdown_funcs'] = array(); +$GLOBALS['_PEAR_error_handler_stack'] = array(); + +@ini_set('track_errors', true); + +/** + * Base class for other PEAR classes. Provides rudimentary + * emulation of destructors. + * + * If you want a destructor in your class, inherit PEAR and make a + * destructor method called _yourclassname (same name as the + * constructor, but with a "_" prefix). Also, in your constructor you + * have to call the PEAR constructor: $this->PEAR();. + * The destructor method will be called without parameters. Note that + * at in some SAPI implementations (such as Apache), any output during + * the request shutdown (in which destructors are called) seems to be + * discarded. If you need to get any debug information from your + * destructor, use error_log(), syslog() or something similar. + * + * IMPORTANT! To use the emulated destructors you need to create the + * objects by reference: $obj =& new PEAR_child; + * + * @category pear + * @package PEAR + * @author Stig Bakken + * @author Tomas V.V. Cox + * @author Greg Beaver + * @copyright 1997-2006 The PHP Group + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @see PEAR_Error + * @since Class available since PHP 4.0.2 + * @link http://pear.php.net/manual/en/core.pear.php#core.pear.pear + */ +class PEAR +{ + /** + * Whether to enable internal debug messages. + * + * @var bool + * @access private + */ + var $_debug = false; + + /** + * Default error mode for this object. + * + * @var int + * @access private + */ + var $_default_error_mode = null; + + /** + * Default error options used for this object when error mode + * is PEAR_ERROR_TRIGGER. + * + * @var int + * @access private + */ + var $_default_error_options = null; + + /** + * Default error handler (callback) for this object, if error mode is + * PEAR_ERROR_CALLBACK. + * + * @var string + * @access private + */ + var $_default_error_handler = ''; + + /** + * Which class to use for error objects. + * + * @var string + * @access private + */ + var $_error_class = 'PEAR_Error'; + + /** + * An array of expected errors. + * + * @var array + * @access private + */ + var $_expected_errors = array(); + + /** + * List of methods that can be called both statically and non-statically. + * @var array + */ + protected static $bivalentMethods = array( + 'setErrorHandling' => true, + 'raiseError' => true, + 'throwError' => true, + 'pushErrorHandling' => true, + 'popErrorHandling' => true, + ); + + /** + * Constructor. Registers this object in + * $_PEAR_destructor_object_list for destructor emulation if a + * destructor object exists. + * + * @param string $error_class (optional) which class to use for + * error objects, defaults to PEAR_Error. + * @access public + * @return void + */ + function __construct($error_class = null) + { + $classname = strtolower(get_class($this)); + if ($this->_debug) { + print "PEAR constructor called, class=$classname\n"; + } + + if ($error_class !== null) { + $this->_error_class = $error_class; + } + + while ($classname && strcasecmp($classname, "pear")) { + $destructor = "_$classname"; + if (method_exists($this, $destructor)) { + global $_PEAR_destructor_object_list; + $_PEAR_destructor_object_list[] = &$this; + if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) { + register_shutdown_function("_PEAR_call_destructors"); + $GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true; + } + break; + } else { + $classname = get_parent_class($classname); + } + } + } + + /** + * Only here for backwards compatibility. + * E.g. Archive_Tar calls $this->PEAR() in its constructor. + * + * @param string $error_class Which class to use for error objects, + * defaults to PEAR_Error. + */ + public function PEAR($error_class = null) + { + self::__construct($error_class); + } + + /** + * Destructor (the emulated type of...). Does nothing right now, + * but is included for forward compatibility, so subclass + * destructors should always call it. + * + * See the note in the class desciption about output from + * destructors. + * + * @access public + * @return void + */ + function _PEAR() { + if ($this->_debug) { + printf("PEAR destructor called, class=%s\n", strtolower(get_class($this))); + } + } + + public function __call($method, $arguments) + { + if (!isset(self::$bivalentMethods[$method])) { + trigger_error( + 'Call to undefined method PEAR::' . $method . '()', E_USER_ERROR + ); + } + return call_user_func_array( + array(get_class(), '_' . $method), + array_merge(array($this), $arguments) + ); + } + + public static function __callStatic($method, $arguments) + { + if (!isset(self::$bivalentMethods[$method])) { + trigger_error( + 'Call to undefined method PEAR::' . $method . '()', E_USER_ERROR + ); + } + return call_user_func_array( + array(get_class(), '_' . $method), + array_merge(array(null), $arguments) + ); + } + + /** + * If you have a class that's mostly/entirely static, and you need static + * properties, you can use this method to simulate them. Eg. in your method(s) + * do this: $myVar = &PEAR::getStaticProperty('myclass', 'myVar'); + * You MUST use a reference, or they will not persist! + * + * @param string $class The calling classname, to prevent clashes + * @param string $var The variable to retrieve. + * @return mixed A reference to the variable. If not set it will be + * auto initialised to NULL. + */ + public static function &getStaticProperty($class, $var) + { + static $properties; + if (!isset($properties[$class])) { + $properties[$class] = array(); + } + + if (!array_key_exists($var, $properties[$class])) { + $properties[$class][$var] = null; + } + + return $properties[$class][$var]; + } + + /** + * Use this function to register a shutdown method for static + * classes. + * + * @param mixed $func The function name (or array of class/method) to call + * @param mixed $args The arguments to pass to the function + * + * @return void + */ + public static function registerShutdownFunc($func, $args = array()) + { + // if we are called statically, there is a potential + // that no shutdown func is registered. Bug #6445 + if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) { + register_shutdown_function("_PEAR_call_destructors"); + $GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true; + } + $GLOBALS['_PEAR_shutdown_funcs'][] = array($func, $args); + } + + /** + * Tell whether a value is a PEAR error. + * + * @param mixed $data the value to test + * @param int $code if $data is an error object, return true + * only if $code is a string and + * $obj->getMessage() == $code or + * $code is an integer and $obj->getCode() == $code + * + * @return bool true if parameter is an error + */ + public static function isError($data, $code = null) + { + if (!is_a($data, 'PEAR_Error')) { + return false; + } + + if (is_null($code)) { + return true; + } elseif (is_string($code)) { + return $data->getMessage() == $code; + } + + return $data->getCode() == $code; + } + + /** + * Sets how errors generated by this object should be handled. + * Can be invoked both in objects and statically. If called + * statically, setErrorHandling sets the default behaviour for all + * PEAR objects. If called in an object, setErrorHandling sets + * the default behaviour for that object. + * + * @param object $object + * Object the method was called on (non-static mode) + * + * @param int $mode + * One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT, + * PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE, + * PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION. + * + * @param mixed $options + * When $mode is PEAR_ERROR_TRIGGER, this is the error level (one + * of E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR). + * + * When $mode is PEAR_ERROR_CALLBACK, this parameter is expected + * to be the callback function or method. A callback + * function is a string with the name of the function, a + * callback method is an array of two elements: the element + * at index 0 is the object, and the element at index 1 is + * the name of the method to call in the object. + * + * When $mode is PEAR_ERROR_PRINT or PEAR_ERROR_DIE, this is + * a printf format string used when printing the error + * message. + * + * @access public + * @return void + * @see PEAR_ERROR_RETURN + * @see PEAR_ERROR_PRINT + * @see PEAR_ERROR_TRIGGER + * @see PEAR_ERROR_DIE + * @see PEAR_ERROR_CALLBACK + * @see PEAR_ERROR_EXCEPTION + * + * @since PHP 4.0.5 + */ + protected static function _setErrorHandling( + $object, $mode = null, $options = null + ) { + if ($object !== null) { + $setmode = &$object->_default_error_mode; + $setoptions = &$object->_default_error_options; + } else { + $setmode = &$GLOBALS['_PEAR_default_error_mode']; + $setoptions = &$GLOBALS['_PEAR_default_error_options']; + } + + switch ($mode) { + case PEAR_ERROR_EXCEPTION: + case PEAR_ERROR_RETURN: + case PEAR_ERROR_PRINT: + case PEAR_ERROR_TRIGGER: + case PEAR_ERROR_DIE: + case null: + $setmode = $mode; + $setoptions = $options; + break; + + case PEAR_ERROR_CALLBACK: + $setmode = $mode; + // class/object method callback + if (is_callable($options)) { + $setoptions = $options; + } else { + trigger_error("invalid error callback", E_USER_WARNING); + } + break; + + default: + trigger_error("invalid error mode", E_USER_WARNING); + break; + } + } + + /** + * This method is used to tell which errors you expect to get. + * Expected errors are always returned with error mode + * PEAR_ERROR_RETURN. Expected error codes are stored in a stack, + * and this method pushes a new element onto it. The list of + * expected errors are in effect until they are popped off the + * stack with the popExpect() method. + * + * Note that this method can not be called statically + * + * @param mixed $code a single error code or an array of error codes to expect + * + * @return int the new depth of the "expected errors" stack + * @access public + */ + function expectError($code = '*') + { + if (is_array($code)) { + array_push($this->_expected_errors, $code); + } else { + array_push($this->_expected_errors, array($code)); + } + return count($this->_expected_errors); + } + + /** + * This method pops one element off the expected error codes + * stack. + * + * @return array the list of error codes that were popped + */ + function popExpect() + { + return array_pop($this->_expected_errors); + } + + /** + * This method checks unsets an error code if available + * + * @param mixed error code + * @return bool true if the error code was unset, false otherwise + * @access private + * @since PHP 4.3.0 + */ + function _checkDelExpect($error_code) + { + $deleted = false; + foreach ($this->_expected_errors as $key => $error_array) { + if (in_array($error_code, $error_array)) { + unset($this->_expected_errors[$key][array_search($error_code, $error_array)]); + $deleted = true; + } + + // clean up empty arrays + if (0 == count($this->_expected_errors[$key])) { + unset($this->_expected_errors[$key]); + } + } + + return $deleted; + } + + /** + * This method deletes all occurences of the specified element from + * the expected error codes stack. + * + * @param mixed $error_code error code that should be deleted + * @return mixed list of error codes that were deleted or error + * @access public + * @since PHP 4.3.0 + */ + function delExpect($error_code) + { + $deleted = false; + if ((is_array($error_code) && (0 != count($error_code)))) { + // $error_code is a non-empty array here; we walk through it trying + // to unset all values + foreach ($error_code as $key => $error) { + $deleted = $this->_checkDelExpect($error) ? true : false; + } + + return $deleted ? true : PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME + } elseif (!empty($error_code)) { + // $error_code comes alone, trying to unset it + if ($this->_checkDelExpect($error_code)) { + return true; + } + + return PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME + } + + // $error_code is empty + return PEAR::raiseError("The expected error you submitted is empty"); // IMPROVE ME + } + + /** + * This method is a wrapper that returns an instance of the + * configured error class with this object's default error + * handling applied. If the $mode and $options parameters are not + * specified, the object's defaults are used. + * + * @param mixed $message a text error message or a PEAR error object + * + * @param int $code a numeric error code (it is up to your class + * to define these if you want to use codes) + * + * @param int $mode One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT, + * PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE, + * PEAR_ERROR_CALLBACK, PEAR_ERROR_EXCEPTION. + * + * @param mixed $options If $mode is PEAR_ERROR_TRIGGER, this parameter + * specifies the PHP-internal error level (one of + * E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR). + * If $mode is PEAR_ERROR_CALLBACK, this + * parameter specifies the callback function or + * method. In other error modes this parameter + * is ignored. + * + * @param string $userinfo If you need to pass along for example debug + * information, this parameter is meant for that. + * + * @param string $error_class The returned error object will be + * instantiated from this class, if specified. + * + * @param bool $skipmsg If true, raiseError will only pass error codes, + * the error message parameter will be dropped. + * + * @return object a PEAR error object + * @see PEAR::setErrorHandling + * @since PHP 4.0.5 + */ + protected static function _raiseError($object, + $message = null, + $code = null, + $mode = null, + $options = null, + $userinfo = null, + $error_class = null, + $skipmsg = false) + { + // The error is yet a PEAR error object + if (is_object($message)) { + $code = $message->getCode(); + $userinfo = $message->getUserInfo(); + $error_class = $message->getType(); + $message->error_message_prefix = ''; + $message = $message->getMessage(); + } + + if ( + $object !== null && + isset($object->_expected_errors) && + count($object->_expected_errors) > 0 && + count($exp = end($object->_expected_errors)) + ) { + if ($exp[0] == "*" || + (is_int(reset($exp)) && in_array($code, $exp)) || + (is_string(reset($exp)) && in_array($message, $exp)) + ) { + $mode = PEAR_ERROR_RETURN; + } + } + + // No mode given, try global ones + if ($mode === null) { + // Class error handler + if ($object !== null && isset($object->_default_error_mode)) { + $mode = $object->_default_error_mode; + $options = $object->_default_error_options; + // Global error handler + } elseif (isset($GLOBALS['_PEAR_default_error_mode'])) { + $mode = $GLOBALS['_PEAR_default_error_mode']; + $options = $GLOBALS['_PEAR_default_error_options']; + } + } + + if ($error_class !== null) { + $ec = $error_class; + } elseif ($object !== null && isset($object->_error_class)) { + $ec = $object->_error_class; + } else { + $ec = 'PEAR_Error'; + } + + if ($skipmsg) { + $a = new $ec($code, $mode, $options, $userinfo); + } else { + $a = new $ec($message, $code, $mode, $options, $userinfo); + } + + return $a; + } + + /** + * Simpler form of raiseError with fewer options. In most cases + * message, code and userinfo are enough. + * + * @param mixed $message a text error message or a PEAR error object + * + * @param int $code a numeric error code (it is up to your class + * to define these if you want to use codes) + * + * @param string $userinfo If you need to pass along for example debug + * information, this parameter is meant for that. + * + * @return object a PEAR error object + * @see PEAR::raiseError + */ + protected static function _throwError($object, $message = null, $code = null, $userinfo = null) + { + if ($object !== null) { + $a = &$object->raiseError($message, $code, null, null, $userinfo); + return $a; + } + + $a = &PEAR::raiseError($message, $code, null, null, $userinfo); + return $a; + } + + public static function staticPushErrorHandling($mode, $options = null) + { + $stack = &$GLOBALS['_PEAR_error_handler_stack']; + $def_mode = &$GLOBALS['_PEAR_default_error_mode']; + $def_options = &$GLOBALS['_PEAR_default_error_options']; + $stack[] = array($def_mode, $def_options); + switch ($mode) { + case PEAR_ERROR_EXCEPTION: + case PEAR_ERROR_RETURN: + case PEAR_ERROR_PRINT: + case PEAR_ERROR_TRIGGER: + case PEAR_ERROR_DIE: + case null: + $def_mode = $mode; + $def_options = $options; + break; + + case PEAR_ERROR_CALLBACK: + $def_mode = $mode; + // class/object method callback + if (is_callable($options)) { + $def_options = $options; + } else { + trigger_error("invalid error callback", E_USER_WARNING); + } + break; + + default: + trigger_error("invalid error mode", E_USER_WARNING); + break; + } + $stack[] = array($mode, $options); + return true; + } + + public static function staticPopErrorHandling() + { + $stack = &$GLOBALS['_PEAR_error_handler_stack']; + $setmode = &$GLOBALS['_PEAR_default_error_mode']; + $setoptions = &$GLOBALS['_PEAR_default_error_options']; + array_pop($stack); + list($mode, $options) = $stack[sizeof($stack) - 1]; + array_pop($stack); + switch ($mode) { + case PEAR_ERROR_EXCEPTION: + case PEAR_ERROR_RETURN: + case PEAR_ERROR_PRINT: + case PEAR_ERROR_TRIGGER: + case PEAR_ERROR_DIE: + case null: + $setmode = $mode; + $setoptions = $options; + break; + + case PEAR_ERROR_CALLBACK: + $setmode = $mode; + // class/object method callback + if (is_callable($options)) { + $setoptions = $options; + } else { + trigger_error("invalid error callback", E_USER_WARNING); + } + break; + + default: + trigger_error("invalid error mode", E_USER_WARNING); + break; + } + return true; + } + + /** + * Push a new error handler on top of the error handler options stack. With this + * you can easily override the actual error handler for some code and restore + * it later with popErrorHandling. + * + * @param mixed $mode (same as setErrorHandling) + * @param mixed $options (same as setErrorHandling) + * + * @return bool Always true + * + * @see PEAR::setErrorHandling + */ + protected static function _pushErrorHandling($object, $mode, $options = null) + { + $stack = &$GLOBALS['_PEAR_error_handler_stack']; + if ($object !== null) { + $def_mode = &$object->_default_error_mode; + $def_options = &$object->_default_error_options; + } else { + $def_mode = &$GLOBALS['_PEAR_default_error_mode']; + $def_options = &$GLOBALS['_PEAR_default_error_options']; + } + $stack[] = array($def_mode, $def_options); + + if ($object !== null) { + $object->setErrorHandling($mode, $options); + } else { + PEAR::setErrorHandling($mode, $options); + } + $stack[] = array($mode, $options); + return true; + } + + /** + * Pop the last error handler used + * + * @return bool Always true + * + * @see PEAR::pushErrorHandling + */ + protected static function _popErrorHandling($object) + { + $stack = &$GLOBALS['_PEAR_error_handler_stack']; + array_pop($stack); + list($mode, $options) = $stack[sizeof($stack) - 1]; + array_pop($stack); + if ($object !== null) { + $object->setErrorHandling($mode, $options); + } else { + PEAR::setErrorHandling($mode, $options); + } + return true; + } + + /** + * OS independent PHP extension load. Remember to take care + * on the correct extension name for case sensitive OSes. + * + * @param string $ext The extension name + * @return bool Success or not on the dl() call + */ + public static function loadExtension($ext) + { + if (extension_loaded($ext)) { + return true; + } + + // if either returns true dl() will produce a FATAL error, stop that + if ( + function_exists('dl') === false || + ini_get('enable_dl') != 1 + ) { + return false; + } + + if (OS_WINDOWS) { + $suffix = '.dll'; + } elseif (PHP_OS == 'HP-UX') { + $suffix = '.sl'; + } elseif (PHP_OS == 'AIX') { + $suffix = '.a'; + } elseif (PHP_OS == 'OSX') { + $suffix = '.bundle'; + } else { + $suffix = '.so'; + } + + return @dl('php_'.$ext.$suffix) || @dl($ext.$suffix); + } +} + +function _PEAR_call_destructors() +{ + global $_PEAR_destructor_object_list; + if (is_array($_PEAR_destructor_object_list) && + sizeof($_PEAR_destructor_object_list)) + { + reset($_PEAR_destructor_object_list); + + $destructLifoExists = PEAR::getStaticProperty('PEAR', 'destructlifo'); + + if ($destructLifoExists) { + $_PEAR_destructor_object_list = array_reverse($_PEAR_destructor_object_list); + } + + while (list($k, $objref) = each($_PEAR_destructor_object_list)) { + $classname = get_class($objref); + while ($classname) { + $destructor = "_$classname"; + if (method_exists($objref, $destructor)) { + $objref->$destructor(); + break; + } else { + $classname = get_parent_class($classname); + } + } + } + // Empty the object list to ensure that destructors are + // not called more than once. + $_PEAR_destructor_object_list = array(); + } + + // Now call the shutdown functions + if ( + isset($GLOBALS['_PEAR_shutdown_funcs']) && + is_array($GLOBALS['_PEAR_shutdown_funcs']) && + !empty($GLOBALS['_PEAR_shutdown_funcs']) + ) { + foreach ($GLOBALS['_PEAR_shutdown_funcs'] as $value) { + call_user_func_array($value[0], $value[1]); + } + } +} + +/** + * Standard PEAR error class for PHP 4 + * + * This class is supserseded by {@link PEAR_Exception} in PHP 5 + * + * @category pear + * @package PEAR + * @author Stig Bakken + * @author Tomas V.V. Cox + * @author Gregory Beaver + * @copyright 1997-2006 The PHP Group + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/manual/en/core.pear.pear-error.php + * @see PEAR::raiseError(), PEAR::throwError() + * @since Class available since PHP 4.0.2 + */ +class PEAR_Error +{ + var $error_message_prefix = ''; + var $mode = PEAR_ERROR_RETURN; + var $level = E_USER_NOTICE; + var $code = -1; + var $message = ''; + var $userinfo = ''; + var $backtrace = null; + + /** + * PEAR_Error constructor + * + * @param string $message message + * + * @param int $code (optional) error code + * + * @param int $mode (optional) error mode, one of: PEAR_ERROR_RETURN, + * PEAR_ERROR_PRINT, PEAR_ERROR_DIE, PEAR_ERROR_TRIGGER, + * PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION + * + * @param mixed $options (optional) error level, _OR_ in the case of + * PEAR_ERROR_CALLBACK, the callback function or object/method + * tuple. + * + * @param string $userinfo (optional) additional user/debug info + * + * @access public + * + */ + function __construct($message = 'unknown error', $code = null, + $mode = null, $options = null, $userinfo = null) + { + if ($mode === null) { + $mode = PEAR_ERROR_RETURN; + } + $this->message = $message; + $this->code = $code; + $this->mode = $mode; + $this->userinfo = $userinfo; + + $skiptrace = PEAR::getStaticProperty('PEAR_Error', 'skiptrace'); + + if (!$skiptrace) { + $this->backtrace = debug_backtrace(); + if (isset($this->backtrace[0]) && isset($this->backtrace[0]['object'])) { + unset($this->backtrace[0]['object']); + } + } + + if ($mode & PEAR_ERROR_CALLBACK) { + $this->level = E_USER_NOTICE; + $this->callback = $options; + } else { + if ($options === null) { + $options = E_USER_NOTICE; + } + + $this->level = $options; + $this->callback = null; + } + + if ($this->mode & PEAR_ERROR_PRINT) { + if (is_null($options) || is_int($options)) { + $format = "%s"; + } else { + $format = $options; + } + + printf($format, $this->getMessage()); + } + + if ($this->mode & PEAR_ERROR_TRIGGER) { + trigger_error($this->getMessage(), $this->level); + } + + if ($this->mode & PEAR_ERROR_DIE) { + $msg = $this->getMessage(); + if (is_null($options) || is_int($options)) { + $format = "%s"; + if (substr($msg, -1) != "\n") { + $msg .= "\n"; + } + } else { + $format = $options; + } + die(sprintf($format, $msg)); + } + + if ($this->mode & PEAR_ERROR_CALLBACK && is_callable($this->callback)) { + call_user_func($this->callback, $this); + } + + if ($this->mode & PEAR_ERROR_EXCEPTION) { + trigger_error("PEAR_ERROR_EXCEPTION is obsolete, use class PEAR_Exception for exceptions", E_USER_WARNING); + eval('$e = new Exception($this->message, $this->code);throw($e);'); + } + } + + /** + * Only here for backwards compatibility. + * + * Class "Cache_Error" still uses it, among others. + * + * @param string $message Message + * @param int $code Error code + * @param int $mode Error mode + * @param mixed $options See __construct() + * @param string $userinfo Additional user/debug info + */ + public function PEAR_Error( + $message = 'unknown error', $code = null, $mode = null, + $options = null, $userinfo = null + ) { + self::__construct($message, $code, $mode, $options, $userinfo); + } + + /** + * Get the error mode from an error object. + * + * @return int error mode + * @access public + */ + function getMode() + { + return $this->mode; + } + + /** + * Get the callback function/method from an error object. + * + * @return mixed callback function or object/method array + * @access public + */ + function getCallback() + { + return $this->callback; + } + + /** + * Get the error message from an error object. + * + * @return string full error message + * @access public + */ + function getMessage() + { + return ($this->error_message_prefix . $this->message); + } + + /** + * Get error code from an error object + * + * @return int error code + * @access public + */ + function getCode() + { + return $this->code; + } + + /** + * Get the name of this error/exception. + * + * @return string error/exception name (type) + * @access public + */ + function getType() + { + return get_class($this); + } + + /** + * Get additional user-supplied information. + * + * @return string user-supplied information + * @access public + */ + function getUserInfo() + { + return $this->userinfo; + } + + /** + * Get additional debug information supplied by the application. + * + * @return string debug information + * @access public + */ + function getDebugInfo() + { + return $this->getUserInfo(); + } + + /** + * Get the call backtrace from where the error was generated. + * Supported with PHP 4.3.0 or newer. + * + * @param int $frame (optional) what frame to fetch + * @return array Backtrace, or NULL if not available. + * @access public + */ + function getBacktrace($frame = null) + { + if (defined('PEAR_IGNORE_BACKTRACE')) { + return null; + } + if ($frame === null) { + return $this->backtrace; + } + return $this->backtrace[$frame]; + } + + function addUserInfo($info) + { + if (empty($this->userinfo)) { + $this->userinfo = $info; + } else { + $this->userinfo .= " ** $info"; + } + } + + function __toString() + { + return $this->getMessage(); + } + + /** + * Make a string representation of this object. + * + * @return string a string with an object summary + * @access public + */ + function toString() + { + $modes = array(); + $levels = array(E_USER_NOTICE => 'notice', + E_USER_WARNING => 'warning', + E_USER_ERROR => 'error'); + if ($this->mode & PEAR_ERROR_CALLBACK) { + if (is_array($this->callback)) { + $callback = (is_object($this->callback[0]) ? + strtolower(get_class($this->callback[0])) : + $this->callback[0]) . '::' . + $this->callback[1]; + } else { + $callback = $this->callback; + } + return sprintf('[%s: message="%s" code=%d mode=callback '. + 'callback=%s prefix="%s" info="%s"]', + strtolower(get_class($this)), $this->message, $this->code, + $callback, $this->error_message_prefix, + $this->userinfo); + } + if ($this->mode & PEAR_ERROR_PRINT) { + $modes[] = 'print'; + } + if ($this->mode & PEAR_ERROR_TRIGGER) { + $modes[] = 'trigger'; + } + if ($this->mode & PEAR_ERROR_DIE) { + $modes[] = 'die'; + } + if ($this->mode & PEAR_ERROR_RETURN) { + $modes[] = 'return'; + } + return sprintf('[%s: message="%s" code=%d mode=%s level=%s '. + 'prefix="%s" info="%s"]', + strtolower(get_class($this)), $this->message, $this->code, + implode("|", $modes), $levels[$this->level], + $this->error_message_prefix, + $this->userinfo); + } +} + +/* + * Local Variables: + * mode: php + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Autoloader.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Autoloader.php new file mode 100644 index 0000000..bcb57f6 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Autoloader.php @@ -0,0 +1,217 @@ + + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/manual/en/core.ppm.php#core.ppm.pear-autoloader + * @since File available since Release 0.1 + * @deprecated File deprecated in Release 1.4.0a1 + */ + +// /* vim: set expandtab tabstop=4 shiftwidth=4: */ + +if (!extension_loaded("overload")) { + // die hard without ext/overload + die("Rebuild PHP with the `overload' extension to use PEAR_Autoloader"); +} + +/** + * Include for PEAR_Error and PEAR classes + */ +require_once "PEAR.php"; + +/** + * This class is for objects where you want to separate the code for + * some methods into separate classes. This is useful if you have a + * class with not-frequently-used methods that contain lots of code + * that you would like to avoid always parsing. + * + * The PEAR_Autoloader class provides autoloading and aggregation. + * The autoloading lets you set up in which classes the separated + * methods are found. Aggregation is the technique used to import new + * methods, an instance of each class providing separated methods is + * stored and called every time the aggregated method is called. + * + * @category pear + * @package PEAR + * @author Stig Bakken + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/manual/en/core.ppm.php#core.ppm.pear-autoloader + * @since File available since Release 0.1 + * @deprecated File deprecated in Release 1.4.0a1 + */ +class PEAR_Autoloader extends PEAR +{ + // {{{ properties + + /** + * Map of methods and classes where they are defined + * + * @var array + * + * @access private + */ + var $_autoload_map = array(); + + /** + * Map of methods and aggregate objects + * + * @var array + * + * @access private + */ + var $_method_map = array(); + + // }}} + // {{{ addAutoload() + + /** + * Add one or more autoload entries. + * + * @param string $method which method to autoload + * + * @param string $classname (optional) which class to find the method in. + * If the $method parameter is an array, this + * parameter may be omitted (and will be ignored + * if not), and the $method parameter will be + * treated as an associative array with method + * names as keys and class names as values. + * + * @return void + * + * @access public + */ + function addAutoload($method, $classname = null) + { + if (is_array($method)) { + array_walk($method, create_function('$a,&$b', '$b = strtolower($b);')); + $this->_autoload_map = array_merge($this->_autoload_map, $method); + } else { + $this->_autoload_map[strtolower($method)] = $classname; + } + } + + // }}} + // {{{ removeAutoload() + + /** + * Remove an autoload entry. + * + * @param string $method which method to remove the autoload entry for + * + * @return bool TRUE if an entry was removed, FALSE if not + * + * @access public + */ + function removeAutoload($method) + { + $method = strtolower($method); + $ok = isset($this->_autoload_map[$method]); + unset($this->_autoload_map[$method]); + return $ok; + } + + // }}} + // {{{ addAggregateObject() + + /** + * Add an aggregate object to this object. If the specified class + * is not defined, loading it will be attempted following PEAR's + * file naming scheme. All the methods in the class will be + * aggregated, except private ones (name starting with an + * underscore) and constructors. + * + * @param string $classname what class to instantiate for the object. + * + * @return void + * + * @access public + */ + function addAggregateObject($classname) + { + $classname = strtolower($classname); + if (!class_exists($classname)) { + $include_file = preg_replace('/[^a-z0-9]/i', '_', $classname); + include_once $include_file; + } + $obj = new $classname; + $methods = get_class_methods($classname); + foreach ($methods as $method) { + // don't import priviate methods and constructors + if ($method{0} != '_' && $method != $classname) { + $this->_method_map[$method] = $obj; + } + } + } + + // }}} + // {{{ removeAggregateObject() + + /** + * Remove an aggregate object. + * + * @param string $classname the class of the object to remove + * + * @return bool TRUE if an object was removed, FALSE if not + * + * @access public + */ + function removeAggregateObject($classname) + { + $ok = false; + $classname = strtolower($classname); + reset($this->_method_map); + while (list($method, $obj) = each($this->_method_map)) { + if (is_a($obj, $classname)) { + unset($this->_method_map[$method]); + $ok = true; + } + } + return $ok; + } + + // }}} + // {{{ __call() + + /** + * Overloaded object call handler, called each time an + * undefined/aggregated method is invoked. This method repeats + * the call in the right aggregate object and passes on the return + * value. + * + * @param string $method which method that was called + * + * @param string $args An array of the parameters passed in the + * original call + * + * @return mixed The return value from the aggregated method, or a PEAR + * error if the called method was unknown. + */ + function __call($method, $args, &$retval) + { + $method = strtolower($method); + if (empty($this->_method_map[$method]) && isset($this->_autoload_map[$method])) { + $this->addAggregateObject($this->_autoload_map[$method]); + } + if (isset($this->_method_map[$method])) { + $retval = call_user_func_array(array($this->_method_map[$method], $method), $args); + return true; + } + return false; + } + + // }}} +} + +overload("PEAR_Autoloader"); + +?> diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Builder.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Builder.php new file mode 100644 index 0000000..94b09f0 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Builder.php @@ -0,0 +1,499 @@ + + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 0.1 + * + * TODO: log output parameters in PECL command line + * TODO: msdev path in configuration + */ + +/** + * Needed for extending PEAR_Builder + */ +require_once 'PEAR/Common.php'; +require_once 'PEAR/PackageFile.php'; +require_once 'System.php'; + +/** + * Class to handle building (compiling) extensions. + * + * @category pear + * @package PEAR + * @author Stig Bakken + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since PHP 4.0.2 + * @see http://pear.php.net/manual/en/core.ppm.pear-builder.php + */ +class PEAR_Builder extends PEAR_Common +{ + var $php_api_version = 0; + var $zend_module_api_no = 0; + var $zend_extension_api_no = 0; + + var $extensions_built = array(); + + /** + * @var string Used for reporting when it is not possible to pass function + * via extra parameter, e.g. log, msdevCallback + */ + var $current_callback = null; + + // used for msdev builds + var $_lastline = null; + var $_firstline = null; + + /** + * PEAR_Builder constructor. + * + * @param object $ui user interface object (instance of PEAR_Frontend_*) + * + * @access public + */ + function __construct(&$ui) + { + parent::__construct(); + $this->setFrontendObject($ui); + } + + /** + * Build an extension from source on windows. + * requires msdev + */ + function _build_win32($descfile, $callback = null) + { + if (is_object($descfile)) { + $pkg = $descfile; + $descfile = $pkg->getPackageFile(); + } else { + $pf = new PEAR_PackageFile($this->config, $this->debug); + $pkg = &$pf->fromPackageFile($descfile, PEAR_VALIDATE_NORMAL); + if (PEAR::isError($pkg)) { + return $pkg; + } + } + $dir = dirname($descfile); + $old_cwd = getcwd(); + + if (!file_exists($dir) || !is_dir($dir) || !chdir($dir)) { + return $this->raiseError("could not chdir to $dir"); + } + + // packages that were in a .tar have the packagefile in this directory + $vdir = $pkg->getPackage() . '-' . $pkg->getVersion(); + if (file_exists($dir) && is_dir($vdir)) { + if (!chdir($vdir)) { + return $this->raiseError("could not chdir to " . realpath($vdir)); + } + + $dir = getcwd(); + } + + $this->log(2, "building in $dir"); + + $dsp = $pkg->getPackage().'.dsp'; + if (!file_exists("$dir/$dsp")) { + return $this->raiseError("The DSP $dsp does not exist."); + } + // XXX TODO: make release build type configurable + $command = 'msdev '.$dsp.' /MAKE "'.$pkg->getPackage(). ' - Release"'; + + $err = $this->_runCommand($command, array(&$this, 'msdevCallback')); + if (PEAR::isError($err)) { + return $err; + } + + // figure out the build platform and type + $platform = 'Win32'; + $buildtype = 'Release'; + if (preg_match('/.*?'.$pkg->getPackage().'\s-\s(\w+)\s(.*?)-+/i',$this->_firstline,$matches)) { + $platform = $matches[1]; + $buildtype = $matches[2]; + } + + if (preg_match('/(.*)?\s-\s(\d+).*?(\d+)/', $this->_lastline, $matches)) { + if ($matches[2]) { + // there were errors in the build + return $this->raiseError("There were errors during compilation."); + } + $out = $matches[1]; + } else { + return $this->raiseError("Did not understand the completion status returned from msdev.exe."); + } + + // msdev doesn't tell us the output directory :/ + // open the dsp, find /out and use that directory + $dsptext = join(file($dsp),''); + + // this regex depends on the build platform and type having been + // correctly identified above. + $regex ='/.*?!IF\s+"\$\(CFG\)"\s+==\s+("'. + $pkg->getPackage().'\s-\s'. + $platform.'\s'. + $buildtype.'").*?'. + '\/out:"(.*?)"/is'; + + if ($dsptext && preg_match($regex, $dsptext, $matches)) { + // what we get back is a relative path to the output file itself. + $outfile = realpath($matches[2]); + } else { + return $this->raiseError("Could not retrieve output information from $dsp."); + } + // realpath returns false if the file doesn't exist + if ($outfile && copy($outfile, "$dir/$out")) { + $outfile = "$dir/$out"; + } + + $built_files[] = array( + 'file' => "$outfile", + 'php_api' => $this->php_api_version, + 'zend_mod_api' => $this->zend_module_api_no, + 'zend_ext_api' => $this->zend_extension_api_no, + ); + + return $built_files; + } + // }}} + + // {{{ msdevCallback() + function msdevCallback($what, $data) + { + if (!$this->_firstline) + $this->_firstline = $data; + $this->_lastline = $data; + call_user_func($this->current_callback, $what, $data); + } + + /** + * @param string + * @param string + * @param array + * @access private + */ + function _harvestInstDir($dest_prefix, $dirname, &$built_files) + { + $d = opendir($dirname); + if (!$d) + return false; + + $ret = true; + while (($ent = readdir($d)) !== false) { + if ($ent{0} == '.') + continue; + + $full = $dirname . DIRECTORY_SEPARATOR . $ent; + if (is_dir($full)) { + if (!$this->_harvestInstDir( + $dest_prefix . DIRECTORY_SEPARATOR . $ent, + $full, $built_files)) { + $ret = false; + break; + } + } else { + $dest = $dest_prefix . DIRECTORY_SEPARATOR . $ent; + $built_files[] = array( + 'file' => $full, + 'dest' => $dest, + 'php_api' => $this->php_api_version, + 'zend_mod_api' => $this->zend_module_api_no, + 'zend_ext_api' => $this->zend_extension_api_no, + ); + } + } + closedir($d); + return $ret; + } + + /** + * Build an extension from source. Runs "phpize" in the source + * directory, but compiles in a temporary directory + * (TMPDIR/pear-build-USER/PACKAGE-VERSION). + * + * @param string|PEAR_PackageFile_v* $descfile path to XML package description file, or + * a PEAR_PackageFile object + * + * @param mixed $callback callback function used to report output, + * see PEAR_Builder::_runCommand for details + * + * @return array an array of associative arrays with built files, + * format: + * array( array( 'file' => '/path/to/ext.so', + * 'php_api' => YYYYMMDD, + * 'zend_mod_api' => YYYYMMDD, + * 'zend_ext_api' => YYYYMMDD ), + * ... ) + * + * @access public + * + * @see PEAR_Builder::_runCommand + */ + function build($descfile, $callback = null) + { + if (preg_match('/(\\/|\\\\|^)([^\\/\\\\]+)?php([^\\/\\\\]+)?$/', + $this->config->get('php_bin'), $matches)) { + if (isset($matches[2]) && strlen($matches[2]) && + trim($matches[2]) != trim($this->config->get('php_prefix'))) { + $this->log(0, 'WARNING: php_bin ' . $this->config->get('php_bin') . + ' appears to have a prefix ' . $matches[2] . ', but' . + ' config variable php_prefix does not match'); + } + + if (isset($matches[3]) && strlen($matches[3]) && + trim($matches[3]) != trim($this->config->get('php_suffix'))) { + $this->log(0, 'WARNING: php_bin ' . $this->config->get('php_bin') . + ' appears to have a suffix ' . $matches[3] . ', but' . + ' config variable php_suffix does not match'); + } + } + + $this->current_callback = $callback; + if (PEAR_OS == "Windows") { + return $this->_build_win32($descfile, $callback); + } + + if (PEAR_OS != 'Unix') { + return $this->raiseError("building extensions not supported on this platform"); + } + + if (is_object($descfile)) { + $pkg = $descfile; + $descfile = $pkg->getPackageFile(); + if (is_a($pkg, 'PEAR_PackageFile_v1')) { + $dir = dirname($descfile); + } else { + $dir = $pkg->_config->get('temp_dir') . '/' . $pkg->getName(); + // automatically delete at session end + $this->addTempFile($dir); + } + } else { + $pf = new PEAR_PackageFile($this->config); + $pkg = &$pf->fromPackageFile($descfile, PEAR_VALIDATE_NORMAL); + if (PEAR::isError($pkg)) { + return $pkg; + } + $dir = dirname($descfile); + } + + // Find config. outside of normal path - e.g. config.m4 + foreach (array_keys($pkg->getInstallationFileList()) as $item) { + if (stristr(basename($item), 'config.m4') && dirname($item) != '.') { + $dir .= DIRECTORY_SEPARATOR . dirname($item); + break; + } + } + + $old_cwd = getcwd(); + if (!file_exists($dir) || !is_dir($dir) || !chdir($dir)) { + return $this->raiseError("could not chdir to $dir"); + } + + $vdir = $pkg->getPackage() . '-' . $pkg->getVersion(); + if (is_dir($vdir)) { + chdir($vdir); + } + + $dir = getcwd(); + $this->log(2, "building in $dir"); + putenv('PATH=' . $this->config->get('bin_dir') . ':' . getenv('PATH')); + $err = $this->_runCommand($this->config->get('php_prefix') + . "phpize" . + $this->config->get('php_suffix'), + array(&$this, 'phpizeCallback')); + if (PEAR::isError($err)) { + return $err; + } + + if (!$err) { + return $this->raiseError("`phpize' failed"); + } + + // {{{ start of interactive part + $configure_command = "$dir/configure"; + + $phpConfigName = $this->config->get('php_prefix') + . 'php-config' + . $this->config->get('php_suffix'); + $phpConfigPath = System::which($phpConfigName); + if ($phpConfigPath !== false) { + $configure_command .= ' --with-php-config=' + . $phpConfigPath; + } + + $configure_options = $pkg->getConfigureOptions(); + if ($configure_options) { + foreach ($configure_options as $o) { + $default = array_key_exists('default', $o) ? $o['default'] : null; + list($r) = $this->ui->userDialog('build', + array($o['prompt']), + array('text'), + array($default)); + if (substr($o['name'], 0, 5) == 'with-' && + ($r == 'yes' || $r == 'autodetect')) { + $configure_command .= " --$o[name]"; + } else { + $configure_command .= " --$o[name]=".trim($r); + } + } + } + // }}} end of interactive part + + // FIXME make configurable + if (!$user=getenv('USER')) { + $user='defaultuser'; + } + + $tmpdir = $this->config->get('temp_dir'); + $build_basedir = System::mktemp(' -t "' . $tmpdir . '" -d "pear-build-' . $user . '"'); + $build_dir = "$build_basedir/$vdir"; + $inst_dir = "$build_basedir/install-$vdir"; + $this->log(1, "building in $build_dir"); + if (is_dir($build_dir)) { + System::rm(array('-rf', $build_dir)); + } + + if (!System::mkDir(array('-p', $build_dir))) { + return $this->raiseError("could not create build dir: $build_dir"); + } + + $this->addTempFile($build_dir); + if (!System::mkDir(array('-p', $inst_dir))) { + return $this->raiseError("could not create temporary install dir: $inst_dir"); + } + $this->addTempFile($inst_dir); + + $make_command = getenv('MAKE') ? getenv('MAKE') : 'make'; + + $to_run = array( + $configure_command, + $make_command, + "$make_command INSTALL_ROOT=\"$inst_dir\" install", + "find \"$inst_dir\" | xargs ls -dils" + ); + if (!file_exists($build_dir) || !is_dir($build_dir) || !chdir($build_dir)) { + return $this->raiseError("could not chdir to $build_dir"); + } + putenv('PHP_PEAR_VERSION=1.10.1'); + foreach ($to_run as $cmd) { + $err = $this->_runCommand($cmd, $callback); + if (PEAR::isError($err)) { + chdir($old_cwd); + return $err; + } + if (!$err) { + chdir($old_cwd); + return $this->raiseError("`$cmd' failed"); + } + } + if (!($dp = opendir("modules"))) { + chdir($old_cwd); + return $this->raiseError("no `modules' directory found"); + } + $built_files = array(); + $prefix = exec($this->config->get('php_prefix') + . "php-config" . + $this->config->get('php_suffix') . " --prefix"); + $this->_harvestInstDir($prefix, $inst_dir . DIRECTORY_SEPARATOR . $prefix, $built_files); + chdir($old_cwd); + return $built_files; + } + + /** + * Message callback function used when running the "phpize" + * program. Extracts the API numbers used. Ignores other message + * types than "cmdoutput". + * + * @param string $what the type of message + * @param mixed $data the message + * + * @return void + * + * @access public + */ + function phpizeCallback($what, $data) + { + if ($what != 'cmdoutput') { + return; + } + $this->log(1, rtrim($data)); + if (preg_match('/You should update your .aclocal.m4/', $data)) { + return; + } + $matches = array(); + if (preg_match('/^\s+(\S[^:]+):\s+(\d{8})/', $data, $matches)) { + $member = preg_replace('/[^a-z]/', '_', strtolower($matches[1])); + $apino = (int)$matches[2]; + if (isset($this->$member)) { + $this->$member = $apino; + //$msg = sprintf("%-22s : %d", $matches[1], $apino); + //$this->log(1, $msg); + } + } + } + + /** + * Run an external command, using a message callback to report + * output. The command will be run through popen and output is + * reported for every line with a "cmdoutput" message with the + * line string, including newlines, as payload. + * + * @param string $command the command to run + * + * @param mixed $callback (optional) function to use as message + * callback + * + * @return bool whether the command was successful (exit code 0 + * means success, any other means failure) + * + * @access private + */ + function _runCommand($command, $callback = null) + { + $this->log(1, "running: $command"); + $pp = popen("$command 2>&1", "r"); + if (!$pp) { + return $this->raiseError("failed to run `$command'"); + } + if ($callback && $callback[0]->debug == 1) { + $olddbg = $callback[0]->debug; + $callback[0]->debug = 2; + } + + while ($line = fgets($pp, 1024)) { + if ($callback) { + call_user_func($callback, 'cmdoutput', $line); + } else { + $this->log(2, rtrim($line)); + } + } + if ($callback && isset($olddbg)) { + $callback[0]->debug = $olddbg; + } + + $exitcode = is_resource($pp) ? pclose($pp) : -1; + return ($exitcode == 0); + } + + function log($level, $msg, $append_crlf = true) + { + if ($this->current_callback) { + if ($this->debug >= $level) { + call_user_func($this->current_callback, 'output', $msg); + } + return; + } + return parent::log($level, $msg, $append_crlf); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/ChannelFile.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/ChannelFile.php new file mode 100644 index 0000000..f993764 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/ChannelFile.php @@ -0,0 +1,1560 @@ + + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * Needed for error handling + */ +require_once 'PEAR/ErrorStack.php'; +require_once 'PEAR/XMLParser.php'; +require_once 'PEAR/Common.php'; + +/** + * Error code if the channel.xml tag does not contain a valid version + */ +define('PEAR_CHANNELFILE_ERROR_NO_VERSION', 1); +/** + * Error code if the channel.xml tag version is not supported (version 1.0 is the only supported version, + * currently + */ +define('PEAR_CHANNELFILE_ERROR_INVALID_VERSION', 2); + +/** + * Error code if parsing is attempted with no xml extension + */ +define('PEAR_CHANNELFILE_ERROR_NO_XML_EXT', 3); + +/** + * Error code if creating the xml parser resource fails + */ +define('PEAR_CHANNELFILE_ERROR_CANT_MAKE_PARSER', 4); + +/** + * Error code used for all sax xml parsing errors + */ +define('PEAR_CHANNELFILE_ERROR_PARSER_ERROR', 5); + +/**#@+ + * Validation errors + */ +/** + * Error code when channel name is missing + */ +define('PEAR_CHANNELFILE_ERROR_NO_NAME', 6); +/** + * Error code when channel name is invalid + */ +define('PEAR_CHANNELFILE_ERROR_INVALID_NAME', 7); +/** + * Error code when channel summary is missing + */ +define('PEAR_CHANNELFILE_ERROR_NO_SUMMARY', 8); +/** + * Error code when channel summary is multi-line + */ +define('PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY', 9); +/** + * Error code when channel server is missing for protocol + */ +define('PEAR_CHANNELFILE_ERROR_NO_HOST', 10); +/** + * Error code when channel server is invalid for protocol + */ +define('PEAR_CHANNELFILE_ERROR_INVALID_HOST', 11); +/** + * Error code when a mirror name is invalid + */ +define('PEAR_CHANNELFILE_ERROR_INVALID_MIRROR', 21); +/** + * Error code when a mirror type is invalid + */ +define('PEAR_CHANNELFILE_ERROR_INVALID_MIRRORTYPE', 22); +/** + * Error code when an attempt is made to generate xml, but the parsed content is invalid + */ +define('PEAR_CHANNELFILE_ERROR_INVALID', 23); +/** + * Error code when an empty package name validate regex is passed in + */ +define('PEAR_CHANNELFILE_ERROR_EMPTY_REGEX', 24); +/** + * Error code when a tag has no version + */ +define('PEAR_CHANNELFILE_ERROR_NO_FUNCTIONVERSION', 25); +/** + * Error code when a tag has no name + */ +define('PEAR_CHANNELFILE_ERROR_NO_FUNCTIONNAME', 26); +/** + * Error code when a tag has no name + */ +define('PEAR_CHANNELFILE_ERROR_NOVALIDATE_NAME', 27); +/** + * Error code when a tag has no version attribute + */ +define('PEAR_CHANNELFILE_ERROR_NOVALIDATE_VERSION', 28); +/** + * Error code when a mirror does not exist but is called for in one of the set* + * methods. + */ +define('PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND', 32); +/** + * Error code when a server port is not numeric + */ +define('PEAR_CHANNELFILE_ERROR_INVALID_PORT', 33); +/** + * Error code when contains no version attribute + */ +define('PEAR_CHANNELFILE_ERROR_NO_STATICVERSION', 34); +/** + * Error code when contains no type attribute in a protocol definition + */ +define('PEAR_CHANNELFILE_ERROR_NOBASEURLTYPE', 35); +/** + * Error code when a mirror is defined and the channel.xml represents the __uri pseudo-channel + */ +define('PEAR_CHANNELFILE_URI_CANT_MIRROR', 36); +/** + * Error code when ssl attribute is present and is not "yes" + */ +define('PEAR_CHANNELFILE_ERROR_INVALID_SSL', 37); +/**#@-*/ + +/** + * Mirror types allowed. Currently only internet servers are recognized. + */ +$GLOBALS['_PEAR_CHANNELS_MIRROR_TYPES'] = array('server'); + + +/** + * The Channel handling class + * + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_ChannelFile +{ + /** + * @access private + * @var PEAR_ErrorStack + * @access private + */ + var $_stack; + + /** + * Supported channel.xml versions, for parsing + * @var array + * @access private + */ + var $_supportedVersions = array('1.0'); + + /** + * Parsed channel information + * @var array + * @access private + */ + var $_channelInfo; + + /** + * index into the subchannels array, used for parsing xml + * @var int + * @access private + */ + var $_subchannelIndex; + + /** + * index into the mirrors array, used for parsing xml + * @var int + * @access private + */ + var $_mirrorIndex; + + /** + * Flag used to determine the validity of parsed content + * @var boolean + * @access private + */ + var $_isValid = false; + + function __construct() + { + $this->_stack = new PEAR_ErrorStack('PEAR_ChannelFile'); + $this->_stack->setErrorMessageTemplate($this->_getErrorMessage()); + $this->_isValid = false; + } + + /** + * @return array + * @access protected + */ + function _getErrorMessage() + { + return + array( + PEAR_CHANNELFILE_ERROR_INVALID_VERSION => + 'While parsing channel.xml, an invalid version number "%version% was passed in, expecting one of %versions%', + PEAR_CHANNELFILE_ERROR_NO_VERSION => + 'No version number found in tag', + PEAR_CHANNELFILE_ERROR_NO_XML_EXT => + '%error%', + PEAR_CHANNELFILE_ERROR_CANT_MAKE_PARSER => + 'Unable to create XML parser', + PEAR_CHANNELFILE_ERROR_PARSER_ERROR => + '%error%', + PEAR_CHANNELFILE_ERROR_NO_NAME => + 'Missing channel name', + PEAR_CHANNELFILE_ERROR_INVALID_NAME => + 'Invalid channel %tag% "%name%"', + PEAR_CHANNELFILE_ERROR_NO_SUMMARY => + 'Missing channel summary', + PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY => + 'Channel summary should be on one line, but is multi-line', + PEAR_CHANNELFILE_ERROR_NO_HOST => + 'Missing channel server for %type% server', + PEAR_CHANNELFILE_ERROR_INVALID_HOST => + 'Server name "%server%" is invalid for %type% server', + PEAR_CHANNELFILE_ERROR_INVALID_MIRROR => + 'Invalid mirror name "%name%", mirror type %type%', + PEAR_CHANNELFILE_ERROR_INVALID_MIRRORTYPE => + 'Invalid mirror type "%type%"', + PEAR_CHANNELFILE_ERROR_INVALID => + 'Cannot generate xml, contents are invalid', + PEAR_CHANNELFILE_ERROR_EMPTY_REGEX => + 'packagenameregex cannot be empty', + PEAR_CHANNELFILE_ERROR_NO_FUNCTIONVERSION => + '%parent% %protocol% function has no version', + PEAR_CHANNELFILE_ERROR_NO_FUNCTIONNAME => + '%parent% %protocol% function has no name', + PEAR_CHANNELFILE_ERROR_NOBASEURLTYPE => + '%parent% rest baseurl has no type', + PEAR_CHANNELFILE_ERROR_NOVALIDATE_NAME => + 'Validation package has no name in tag', + PEAR_CHANNELFILE_ERROR_NOVALIDATE_VERSION => + 'Validation package "%package%" has no version', + PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND => + 'Mirror "%mirror%" does not exist', + PEAR_CHANNELFILE_ERROR_INVALID_PORT => + 'Port "%port%" must be numeric', + PEAR_CHANNELFILE_ERROR_NO_STATICVERSION => + ' tag must contain version attribute', + PEAR_CHANNELFILE_URI_CANT_MIRROR => + 'The __uri pseudo-channel cannot have mirrors', + PEAR_CHANNELFILE_ERROR_INVALID_SSL => + '%server% has invalid ssl attribute "%ssl%" can only be yes or not present', + ); + } + + /** + * @param string contents of package.xml file + * @return bool success of parsing + */ + function fromXmlString($data) + { + if (preg_match('/_supportedVersions)) { + $this->_stack->push(PEAR_CHANNELFILE_ERROR_INVALID_VERSION, 'error', + array('version' => $channelversion[1])); + return false; + } + $parser = new PEAR_XMLParser; + $result = $parser->parse($data); + if ($result !== true) { + if ($result->getCode() == 1) { + $this->_stack->push(PEAR_CHANNELFILE_ERROR_NO_XML_EXT, 'error', + array('error' => $result->getMessage())); + } else { + $this->_stack->push(PEAR_CHANNELFILE_ERROR_CANT_MAKE_PARSER, 'error'); + } + return false; + } + $this->_channelInfo = $parser->getData(); + return true; + } else { + $this->_stack->push(PEAR_CHANNELFILE_ERROR_NO_VERSION, 'error', array('xml' => $data)); + return false; + } + } + + /** + * @return array + */ + function toArray() + { + if (!$this->_isValid && !$this->validate()) { + return false; + } + return $this->_channelInfo; + } + + /** + * @param array + * + * @return PEAR_ChannelFile|false false if invalid + */ + public static function &fromArray( + $data, $compatibility = false, $stackClass = 'PEAR_ErrorStack' + ) { + $a = new PEAR_ChannelFile($compatibility, $stackClass); + $a->_fromArray($data); + if (!$a->validate()) { + $a = false; + return $a; + } + return $a; + } + + /** + * Unlike {@link fromArray()} this does not do any validation + * + * @param array + * + * @return PEAR_ChannelFile + */ + public static function &fromArrayWithErrors( + $data, $compatibility = false, $stackClass = 'PEAR_ErrorStack' + ) { + $a = new PEAR_ChannelFile($compatibility, $stackClass); + $a->_fromArray($data); + return $a; + } + + /** + * @param array + * @access private + */ + function _fromArray($data) + { + $this->_channelInfo = $data; + } + + /** + * Wrapper to {@link PEAR_ErrorStack::getErrors()} + * @param boolean determines whether to purge the error stack after retrieving + * @return array + */ + function getErrors($purge = false) + { + return $this->_stack->getErrors($purge); + } + + /** + * Unindent given string (?) + * + * @param string $str The string that has to be unindented. + * @return string + * @access private + */ + function _unIndent($str) + { + // remove leading newlines + $str = preg_replace('/^[\r\n]+/', '', $str); + // find whitespace at the beginning of the first line + $indent_len = strspn($str, " \t"); + $indent = substr($str, 0, $indent_len); + $data = ''; + // remove the same amount of whitespace from following lines + foreach (explode("\n", $str) as $line) { + if (substr($line, 0, $indent_len) == $indent) { + $data .= substr($line, $indent_len) . "\n"; + } + } + return $data; + } + + /** + * Parse a channel.xml file. Expects the name of + * a channel xml file as input. + * + * @param string $descfile name of channel xml file + * @return bool success of parsing + */ + function fromXmlFile($descfile) + { + if (!file_exists($descfile) || !is_file($descfile) || !is_readable($descfile) || + (!$fp = fopen($descfile, 'r'))) { + require_once 'PEAR.php'; + return PEAR::raiseError("Unable to open $descfile"); + } + + // read the whole thing so we only get one cdata callback + // for each block of cdata + fclose($fp); + $data = file_get_contents($descfile); + return $this->fromXmlString($data); + } + + /** + * Parse channel information from different sources + * + * This method is able to extract information about a channel + * from an .xml file or a string + * + * @access public + * @param string Filename of the source or the source itself + * @return bool + */ + function fromAny($info) + { + if (is_string($info) && file_exists($info) && strlen($info) < 255) { + $tmp = substr($info, -4); + if ($tmp == '.xml') { + $info = $this->fromXmlFile($info); + } else { + $fp = fopen($info, "r"); + $test = fread($fp, 5); + fclose($fp); + if ($test == "fromXmlFile($info); + } + } + if (PEAR::isError($info)) { + require_once 'PEAR.php'; + return PEAR::raiseError($info); + } + } + if (is_string($info)) { + $info = $this->fromXmlString($info); + } + return $info; + } + + /** + * Return an XML document based on previous parsing and modifications + * + * @return string XML data + * + * @access public + */ + function toXml() + { + if (!$this->_isValid && !$this->validate()) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID); + return false; + } + if (!isset($this->_channelInfo['attribs']['version'])) { + $this->_channelInfo['attribs']['version'] = '1.0'; + } + $channelInfo = $this->_channelInfo; + $ret = "\n"; + $ret .= " + $channelInfo[name] + " . htmlspecialchars($channelInfo['summary'])." +"; + if (isset($channelInfo['suggestedalias'])) { + $ret .= ' ' . $channelInfo['suggestedalias'] . "\n"; + } + if (isset($channelInfo['validatepackage'])) { + $ret .= ' ' . + htmlspecialchars($channelInfo['validatepackage']['_content']) . + "\n"; + } + $ret .= " \n"; + $ret .= ' _makeRestXml($channelInfo['servers']['primary']['rest'], ' '); + } + $ret .= " \n"; + if (isset($channelInfo['servers']['mirror'])) { + $ret .= $this->_makeMirrorsXml($channelInfo); + } + $ret .= " \n"; + $ret .= ""; + return str_replace("\r", "\n", str_replace("\r\n", "\n", $ret)); + } + + /** + * Generate the tag + * @access private + */ + function _makeRestXml($info, $indent) + { + $ret = $indent . "\n"; + if (isset($info['baseurl']) && !isset($info['baseurl'][0])) { + $info['baseurl'] = array($info['baseurl']); + } + + if (isset($info['baseurl'])) { + foreach ($info['baseurl'] as $url) { + $ret .= "$indent \n"; + } + } + $ret .= $indent . "\n"; + return $ret; + } + + /** + * Generate the tag + * @access private + */ + function _makeMirrorsXml($channelInfo) + { + $ret = ""; + if (!isset($channelInfo['servers']['mirror'][0])) { + $channelInfo['servers']['mirror'] = array($channelInfo['servers']['mirror']); + } + foreach ($channelInfo['servers']['mirror'] as $mirror) { + $ret .= ' _makeRestXml($mirror['rest'], ' '); + } + $ret .= " \n"; + } else { + $ret .= "/>\n"; + } + } + return $ret; + } + + /** + * Generate the tag + * @access private + */ + function _makeFunctionsXml($functions, $indent, $rest = false) + { + $ret = ''; + if (!isset($functions[0])) { + $functions = array($functions); + } + foreach ($functions as $function) { + $ret .= "$indent\n"; + } + return $ret; + } + + /** + * Validation error. Also marks the object contents as invalid + * @param error code + * @param array error information + * @access private + */ + function _validateError($code, $params = array()) + { + $this->_stack->push($code, 'error', $params); + $this->_isValid = false; + } + + /** + * Validation warning. Does not mark the object contents invalid. + * @param error code + * @param array error information + * @access private + */ + function _validateWarning($code, $params = array()) + { + $this->_stack->push($code, 'warning', $params); + } + + /** + * Validate parsed file. + * + * @access public + * @return boolean + */ + function validate() + { + $this->_isValid = true; + $info = $this->_channelInfo; + if (empty($info['name'])) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_NAME); + } elseif (!$this->validChannelServer($info['name'])) { + if ($info['name'] != '__uri') { + $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME, array('tag' => 'name', + 'name' => $info['name'])); + } + } + if (empty($info['summary'])) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_SUMMARY); + } elseif (strpos(trim($info['summary']), "\n") !== false) { + $this->_validateWarning(PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY, + array('summary' => $info['summary'])); + } + if (isset($info['suggestedalias'])) { + if (!$this->validChannelServer($info['suggestedalias'])) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME, + array('tag' => 'suggestedalias', 'name' =>$info['suggestedalias'])); + } + } + if (isset($info['localalias'])) { + if (!$this->validChannelServer($info['localalias'])) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME, + array('tag' => 'localalias', 'name' =>$info['localalias'])); + } + } + if (isset($info['validatepackage'])) { + if (!isset($info['validatepackage']['_content'])) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_NOVALIDATE_NAME); + } + if (!isset($info['validatepackage']['attribs']['version'])) { + $content = isset($info['validatepackage']['_content']) ? + $info['validatepackage']['_content'] : + null; + $this->_validateError(PEAR_CHANNELFILE_ERROR_NOVALIDATE_VERSION, + array('package' => $content)); + } + } + + if (isset($info['servers']['primary']['attribs'], $info['servers']['primary']['attribs']['port']) && + !is_numeric($info['servers']['primary']['attribs']['port'])) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_PORT, + array('port' => $info['servers']['primary']['attribs']['port'])); + } + + if (isset($info['servers']['primary']['attribs'], $info['servers']['primary']['attribs']['ssl']) && + $info['servers']['primary']['attribs']['ssl'] != 'yes') { + $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_SSL, + array('ssl' => $info['servers']['primary']['attribs']['ssl'], + 'server' => $info['name'])); + } + + if (isset($info['servers']['primary']['rest']) && + isset($info['servers']['primary']['rest']['baseurl'])) { + $this->_validateFunctions('rest', $info['servers']['primary']['rest']['baseurl']); + } + if (isset($info['servers']['mirror'])) { + if ($this->_channelInfo['name'] == '__uri') { + $this->_validateError(PEAR_CHANNELFILE_URI_CANT_MIRROR); + } + if (!isset($info['servers']['mirror'][0])) { + $info['servers']['mirror'] = array($info['servers']['mirror']); + } + foreach ($info['servers']['mirror'] as $mirror) { + if (!isset($mirror['attribs']['host'])) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_HOST, + array('type' => 'mirror')); + } elseif (!$this->validChannelServer($mirror['attribs']['host'])) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_HOST, + array('server' => $mirror['attribs']['host'], 'type' => 'mirror')); + } + if (isset($mirror['attribs']['ssl']) && $mirror['attribs']['ssl'] != 'yes') { + $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_SSL, + array('ssl' => $info['ssl'], 'server' => $mirror['attribs']['host'])); + } + if (isset($mirror['rest'])) { + $this->_validateFunctions('rest', $mirror['rest']['baseurl'], + $mirror['attribs']['host']); + } + } + } + return $this->_isValid; + } + + /** + * @param string rest - protocol name this function applies to + * @param array the functions + * @param string the name of the parent element (mirror name, for instance) + */ + function _validateFunctions($protocol, $functions, $parent = '') + { + if (!isset($functions[0])) { + $functions = array($functions); + } + + foreach ($functions as $function) { + if (!isset($function['_content']) || empty($function['_content'])) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_FUNCTIONNAME, + array('parent' => $parent, 'protocol' => $protocol)); + } + + if ($protocol == 'rest') { + if (!isset($function['attribs']['type']) || + empty($function['attribs']['type'])) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_NOBASEURLTYPE, + array('parent' => $parent, 'protocol' => $protocol)); + } + } else { + if (!isset($function['attribs']['version']) || + empty($function['attribs']['version'])) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_FUNCTIONVERSION, + array('parent' => $parent, 'protocol' => $protocol)); + } + } + } + } + + /** + * Test whether a string contains a valid channel server. + * @param string $ver the package version to test + * @return bool + */ + function validChannelServer($server) + { + if ($server == '__uri') { + return true; + } + return (bool) preg_match(PEAR_CHANNELS_SERVER_PREG, $server); + } + + /** + * @return string|false + */ + function getName() + { + if (isset($this->_channelInfo['name'])) { + return $this->_channelInfo['name']; + } + + return false; + } + + /** + * @return string|false + */ + function getServer() + { + if (isset($this->_channelInfo['name'])) { + return $this->_channelInfo['name']; + } + + return false; + } + + /** + * @return int|80 port number to connect to + */ + function getPort($mirror = false) + { + if ($mirror) { + if ($mir = $this->getMirror($mirror)) { + if (isset($mir['attribs']['port'])) { + return $mir['attribs']['port']; + } + + if ($this->getSSL($mirror)) { + return 443; + } + + return 80; + } + + return false; + } + + if (isset($this->_channelInfo['servers']['primary']['attribs']['port'])) { + return $this->_channelInfo['servers']['primary']['attribs']['port']; + } + + if ($this->getSSL()) { + return 443; + } + + return 80; + } + + /** + * @return bool Determines whether secure sockets layer (SSL) is used to connect to this channel + */ + function getSSL($mirror = false) + { + if ($mirror) { + if ($mir = $this->getMirror($mirror)) { + if (isset($mir['attribs']['ssl'])) { + return true; + } + + return false; + } + + return false; + } + + if (isset($this->_channelInfo['servers']['primary']['attribs']['ssl'])) { + return true; + } + + return false; + } + + /** + * @return string|false + */ + function getSummary() + { + if (isset($this->_channelInfo['summary'])) { + return $this->_channelInfo['summary']; + } + + return false; + } + + /** + * @param string protocol type + * @param string Mirror name + * @return array|false + */ + function getFunctions($protocol, $mirror = false) + { + if ($this->getName() == '__uri') { + return false; + } + + $function = $protocol == 'rest' ? 'baseurl' : 'function'; + if ($mirror) { + if ($mir = $this->getMirror($mirror)) { + if (isset($mir[$protocol][$function])) { + return $mir[$protocol][$function]; + } + } + + return false; + } + + if (isset($this->_channelInfo['servers']['primary'][$protocol][$function])) { + return $this->_channelInfo['servers']['primary'][$protocol][$function]; + } + + return false; + } + + /** + * @param string Protocol type + * @param string Function name (null to return the + * first protocol of the type requested) + * @param string Mirror name, if any + * @return array + */ + function getFunction($type, $name = null, $mirror = false) + { + $protocols = $this->getFunctions($type, $mirror); + if (!$protocols) { + return false; + } + + foreach ($protocols as $protocol) { + if ($name === null) { + return $protocol; + } + + if ($protocol['_content'] != $name) { + continue; + } + + return $protocol; + } + + return false; + } + + /** + * @param string protocol type + * @param string protocol name + * @param string version + * @param string mirror name + * @return boolean + */ + function supports($type, $name = null, $mirror = false, $version = '1.0') + { + $protocols = $this->getFunctions($type, $mirror); + if (!$protocols) { + return false; + } + + foreach ($protocols as $protocol) { + if ($protocol['attribs']['version'] != $version) { + continue; + } + + if ($name === null) { + return true; + } + + if ($protocol['_content'] != $name) { + continue; + } + + return true; + } + + return false; + } + + /** + * Determines whether a channel supports Representational State Transfer (REST) protocols + * for retrieving channel information + * @param string + * @return bool + */ + function supportsREST($mirror = false) + { + if ($mirror == $this->_channelInfo['name']) { + $mirror = false; + } + + if ($mirror) { + if ($mir = $this->getMirror($mirror)) { + return isset($mir['rest']); + } + + return false; + } + + return isset($this->_channelInfo['servers']['primary']['rest']); + } + + /** + * Get the URL to access a base resource. + * + * Hyperlinks in the returned xml will be used to retrieve the proper information + * needed. This allows extreme extensibility and flexibility in implementation + * @param string Resource Type to retrieve + */ + function getBaseURL($resourceType, $mirror = false) + { + if ($mirror == $this->_channelInfo['name']) { + $mirror = false; + } + + if ($mirror) { + $mir = $this->getMirror($mirror); + if (!$mir) { + return false; + } + + $rest = $mir['rest']; + } else { + $rest = $this->_channelInfo['servers']['primary']['rest']; + } + + if (!isset($rest['baseurl'][0])) { + $rest['baseurl'] = array($rest['baseurl']); + } + + foreach ($rest['baseurl'] as $baseurl) { + if (strtolower($baseurl['attribs']['type']) == strtolower($resourceType)) { + return $baseurl['_content']; + } + } + + return false; + } + + /** + * Since REST does not implement RPC, provide this as a logical wrapper around + * resetFunctions for REST + * @param string|false mirror name, if any + */ + function resetREST($mirror = false) + { + return $this->resetFunctions('rest', $mirror); + } + + /** + * Empty all protocol definitions + * @param string protocol type + * @param string|false mirror name, if any + */ + function resetFunctions($type, $mirror = false) + { + if ($mirror) { + if (isset($this->_channelInfo['servers']['mirror'])) { + $mirrors = $this->_channelInfo['servers']['mirror']; + if (!isset($mirrors[0])) { + $mirrors = array($mirrors); + } + + foreach ($mirrors as $i => $mir) { + if ($mir['attribs']['host'] == $mirror) { + if (isset($this->_channelInfo['servers']['mirror'][$i][$type])) { + unset($this->_channelInfo['servers']['mirror'][$i][$type]); + } + + return true; + } + } + + return false; + } + + return false; + } + + if (isset($this->_channelInfo['servers']['primary'][$type])) { + unset($this->_channelInfo['servers']['primary'][$type]); + } + + return true; + } + + /** + * Set a channel's protocols to the protocols supported by pearweb + */ + function setDefaultPEARProtocols($version = '1.0', $mirror = false) + { + switch ($version) { + case '1.0' : + $this->resetREST($mirror); + + if (!isset($this->_channelInfo['servers'])) { + $this->_channelInfo['servers'] = array('primary' => + array('rest' => array())); + } elseif (!isset($this->_channelInfo['servers']['primary'])) { + $this->_channelInfo['servers']['primary'] = array('rest' => array()); + } + + return true; + break; + default : + return false; + break; + } + } + + /** + * @return array + */ + function getMirrors() + { + if (isset($this->_channelInfo['servers']['mirror'])) { + $mirrors = $this->_channelInfo['servers']['mirror']; + if (!isset($mirrors[0])) { + $mirrors = array($mirrors); + } + + return $mirrors; + } + + return array(); + } + + /** + * Get the unserialized XML representing a mirror + * @return array|false + */ + function getMirror($server) + { + foreach ($this->getMirrors() as $mirror) { + if ($mirror['attribs']['host'] == $server) { + return $mirror; + } + } + + return false; + } + + /** + * @param string + * @return string|false + * @error PEAR_CHANNELFILE_ERROR_NO_NAME + * @error PEAR_CHANNELFILE_ERROR_INVALID_NAME + */ + function setName($name) + { + return $this->setServer($name); + } + + /** + * Set the socket number (port) that is used to connect to this channel + * @param integer + * @param string|false name of the mirror server, or false for the primary + */ + function setPort($port, $mirror = false) + { + if ($mirror) { + if (!isset($this->_channelInfo['servers']['mirror'])) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND, + array('mirror' => $mirror)); + return false; + } + + if (isset($this->_channelInfo['servers']['mirror'][0])) { + foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) { + if ($mirror == $mir['attribs']['host']) { + $this->_channelInfo['servers']['mirror'][$i]['attribs']['port'] = $port; + return true; + } + } + + return false; + } elseif ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) { + $this->_channelInfo['servers']['mirror']['attribs']['port'] = $port; + $this->_isValid = false; + return true; + } + } + + $this->_channelInfo['servers']['primary']['attribs']['port'] = $port; + $this->_isValid = false; + return true; + } + + /** + * Set the socket number (port) that is used to connect to this channel + * @param bool Determines whether to turn on SSL support or turn it off + * @param string|false name of the mirror server, or false for the primary + */ + function setSSL($ssl = true, $mirror = false) + { + if ($mirror) { + if (!isset($this->_channelInfo['servers']['mirror'])) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND, + array('mirror' => $mirror)); + return false; + } + + if (isset($this->_channelInfo['servers']['mirror'][0])) { + foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) { + if ($mirror == $mir['attribs']['host']) { + if (!$ssl) { + if (isset($this->_channelInfo['servers']['mirror'][$i] + ['attribs']['ssl'])) { + unset($this->_channelInfo['servers']['mirror'][$i]['attribs']['ssl']); + } + } else { + $this->_channelInfo['servers']['mirror'][$i]['attribs']['ssl'] = 'yes'; + } + + return true; + } + } + + return false; + } elseif ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) { + if (!$ssl) { + if (isset($this->_channelInfo['servers']['mirror']['attribs']['ssl'])) { + unset($this->_channelInfo['servers']['mirror']['attribs']['ssl']); + } + } else { + $this->_channelInfo['servers']['mirror']['attribs']['ssl'] = 'yes'; + } + + $this->_isValid = false; + return true; + } + } + + if ($ssl) { + $this->_channelInfo['servers']['primary']['attribs']['ssl'] = 'yes'; + } else { + if (isset($this->_channelInfo['servers']['primary']['attribs']['ssl'])) { + unset($this->_channelInfo['servers']['primary']['attribs']['ssl']); + } + } + + $this->_isValid = false; + return true; + } + + /** + * @param string + * @return string|false + * @error PEAR_CHANNELFILE_ERROR_NO_SERVER + * @error PEAR_CHANNELFILE_ERROR_INVALID_SERVER + */ + function setServer($server, $mirror = false) + { + if (empty($server)) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_SERVER); + return false; + } elseif (!$this->validChannelServer($server)) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME, + array('tag' => 'name', 'name' => $server)); + return false; + } + + if ($mirror) { + $found = false; + foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) { + if ($mirror == $mir['attribs']['host']) { + $found = true; + break; + } + } + + if (!$found) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND, + array('mirror' => $mirror)); + return false; + } + + $this->_channelInfo['mirror'][$i]['attribs']['host'] = $server; + return true; + } + + $this->_channelInfo['name'] = $server; + return true; + } + + /** + * @param string + * @return boolean success + * @error PEAR_CHANNELFILE_ERROR_NO_SUMMARY + * @warning PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY + */ + function setSummary($summary) + { + if (empty($summary)) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_SUMMARY); + return false; + } elseif (strpos(trim($summary), "\n") !== false) { + $this->_validateWarning(PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY, + array('summary' => $summary)); + } + + $this->_channelInfo['summary'] = $summary; + return true; + } + + /** + * @param string + * @param boolean determines whether the alias is in channel.xml or local + * @return boolean success + */ + function setAlias($alias, $local = false) + { + if (!$this->validChannelServer($alias)) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME, + array('tag' => 'suggestedalias', 'name' => $alias)); + return false; + } + + if ($local) { + $this->_channelInfo['localalias'] = $alias; + } else { + $this->_channelInfo['suggestedalias'] = $alias; + } + + return true; + } + + /** + * @return string + */ + function getAlias() + { + if (isset($this->_channelInfo['localalias'])) { + return $this->_channelInfo['localalias']; + } + if (isset($this->_channelInfo['suggestedalias'])) { + return $this->_channelInfo['suggestedalias']; + } + if (isset($this->_channelInfo['name'])) { + return $this->_channelInfo['name']; + } + return ''; + } + + /** + * Set the package validation object if it differs from PEAR's default + * The class must be includeable via changing _ in the classname to path separator, + * but no checking of this is made. + * @param string|false pass in false to reset to the default packagename regex + * @return boolean success + */ + function setValidationPackage($validateclass, $version) + { + if (empty($validateclass)) { + unset($this->_channelInfo['validatepackage']); + } + $this->_channelInfo['validatepackage'] = array('_content' => $validateclass); + $this->_channelInfo['validatepackage']['attribs'] = array('version' => $version); + } + + /** + * Add a protocol to the provides section + * @param string protocol type + * @param string protocol version + * @param string protocol name, if any + * @param string mirror name, if this is a mirror's protocol + * @return bool + */ + function addFunction($type, $version, $name = '', $mirror = false) + { + if ($mirror) { + return $this->addMirrorFunction($mirror, $type, $version, $name); + } + + $set = array('attribs' => array('version' => $version), '_content' => $name); + if (!isset($this->_channelInfo['servers']['primary'][$type]['function'])) { + if (!isset($this->_channelInfo['servers'])) { + $this->_channelInfo['servers'] = array('primary' => + array($type => array())); + } elseif (!isset($this->_channelInfo['servers']['primary'])) { + $this->_channelInfo['servers']['primary'] = array($type => array()); + } + + $this->_channelInfo['servers']['primary'][$type]['function'] = $set; + $this->_isValid = false; + return true; + } elseif (!isset($this->_channelInfo['servers']['primary'][$type]['function'][0])) { + $this->_channelInfo['servers']['primary'][$type]['function'] = array( + $this->_channelInfo['servers']['primary'][$type]['function']); + } + + $this->_channelInfo['servers']['primary'][$type]['function'][] = $set; + return true; + } + /** + * Add a protocol to a mirror's provides section + * @param string mirror name (server) + * @param string protocol type + * @param string protocol version + * @param string protocol name, if any + */ + function addMirrorFunction($mirror, $type, $version, $name = '') + { + if (!isset($this->_channelInfo['servers']['mirror'])) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND, + array('mirror' => $mirror)); + return false; + } + + $setmirror = false; + if (isset($this->_channelInfo['servers']['mirror'][0])) { + foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) { + if ($mirror == $mir['attribs']['host']) { + $setmirror = &$this->_channelInfo['servers']['mirror'][$i]; + break; + } + } + } else { + if ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) { + $setmirror = &$this->_channelInfo['servers']['mirror']; + } + } + + if (!$setmirror) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND, + array('mirror' => $mirror)); + return false; + } + + $set = array('attribs' => array('version' => $version), '_content' => $name); + if (!isset($setmirror[$type]['function'])) { + $setmirror[$type]['function'] = $set; + $this->_isValid = false; + return true; + } elseif (!isset($setmirror[$type]['function'][0])) { + $setmirror[$type]['function'] = array($setmirror[$type]['function']); + } + + $setmirror[$type]['function'][] = $set; + $this->_isValid = false; + return true; + } + + /** + * @param string Resource Type this url links to + * @param string URL + * @param string|false mirror name, if this is not a primary server REST base URL + */ + function setBaseURL($resourceType, $url, $mirror = false) + { + if ($mirror) { + if (!isset($this->_channelInfo['servers']['mirror'])) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND, + array('mirror' => $mirror)); + return false; + } + + $setmirror = false; + if (isset($this->_channelInfo['servers']['mirror'][0])) { + foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) { + if ($mirror == $mir['attribs']['host']) { + $setmirror = &$this->_channelInfo['servers']['mirror'][$i]; + break; + } + } + } else { + if ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) { + $setmirror = &$this->_channelInfo['servers']['mirror']; + } + } + } else { + $setmirror = &$this->_channelInfo['servers']['primary']; + } + + $set = array('attribs' => array('type' => $resourceType), '_content' => $url); + if (!isset($setmirror['rest'])) { + $setmirror['rest'] = array(); + } + + if (!isset($setmirror['rest']['baseurl'])) { + $setmirror['rest']['baseurl'] = $set; + $this->_isValid = false; + return true; + } elseif (!isset($setmirror['rest']['baseurl'][0])) { + $setmirror['rest']['baseurl'] = array($setmirror['rest']['baseurl']); + } + + foreach ($setmirror['rest']['baseurl'] as $i => $url) { + if ($url['attribs']['type'] == $resourceType) { + $this->_isValid = false; + $setmirror['rest']['baseurl'][$i] = $set; + return true; + } + } + + $setmirror['rest']['baseurl'][] = $set; + $this->_isValid = false; + return true; + } + + /** + * @param string mirror server + * @param int mirror http port + * @return boolean + */ + function addMirror($server, $port = null) + { + if ($this->_channelInfo['name'] == '__uri') { + return false; // the __uri channel cannot have mirrors by definition + } + + $set = array('attribs' => array('host' => $server)); + if (is_numeric($port)) { + $set['attribs']['port'] = $port; + } + + if (!isset($this->_channelInfo['servers']['mirror'])) { + $this->_channelInfo['servers']['mirror'] = $set; + return true; + } + + if (!isset($this->_channelInfo['servers']['mirror'][0])) { + $this->_channelInfo['servers']['mirror'] = + array($this->_channelInfo['servers']['mirror']); + } + + $this->_channelInfo['servers']['mirror'][] = $set; + return true; + } + + /** + * Retrieve the name of the validation package for this channel + * @return string|false + */ + function getValidationPackage() + { + if (!$this->_isValid && !$this->validate()) { + return false; + } + + if (!isset($this->_channelInfo['validatepackage'])) { + return array('attribs' => array('version' => 'default'), + '_content' => 'PEAR_Validate'); + } + + return $this->_channelInfo['validatepackage']; + } + + /** + * Retrieve the object that can be used for custom validation + * @param string|false the name of the package to validate. If the package is + * the channel validation package, PEAR_Validate is returned + * @return PEAR_Validate|false false is returned if the validation package + * cannot be located + */ + function &getValidationObject($package = false) + { + if (!class_exists('PEAR_Validate')) { + require_once 'PEAR/Validate.php'; + } + + if (!$this->_isValid) { + if (!$this->validate()) { + $a = false; + return $a; + } + } + + if (isset($this->_channelInfo['validatepackage'])) { + if ($package == $this->_channelInfo['validatepackage']) { + // channel validation packages are always validated by PEAR_Validate + $val = new PEAR_Validate; + return $val; + } + + if (!class_exists(str_replace('.', '_', + $this->_channelInfo['validatepackage']['_content']))) { + if ($this->isIncludeable(str_replace('_', '/', + $this->_channelInfo['validatepackage']['_content']) . '.php')) { + include_once str_replace('_', '/', + $this->_channelInfo['validatepackage']['_content']) . '.php'; + $vclass = str_replace('.', '_', + $this->_channelInfo['validatepackage']['_content']); + $val = new $vclass; + } else { + $a = false; + return $a; + } + } else { + $vclass = str_replace('.', '_', + $this->_channelInfo['validatepackage']['_content']); + $val = new $vclass; + } + } else { + $val = new PEAR_Validate; + } + + return $val; + } + + function isIncludeable($path) + { + $possibilities = explode(PATH_SEPARATOR, ini_get('include_path')); + foreach ($possibilities as $dir) { + if (file_exists($dir . DIRECTORY_SEPARATOR . $path) + && is_readable($dir . DIRECTORY_SEPARATOR . $path)) { + return true; + } + } + + return false; + } + + /** + * This function is used by the channel updater and retrieves a value set by + * the registry, or the current time if it has not been set + * @return string + */ + function lastModified() + { + if (isset($this->_channelInfo['_lastmodified'])) { + return $this->_channelInfo['_lastmodified']; + } + + return time(); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/ChannelFile/Parser.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/ChannelFile/Parser.php new file mode 100644 index 0000000..a27e8fd --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/ChannelFile/Parser.php @@ -0,0 +1,67 @@ + + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * base xml parser class + */ +require_once 'PEAR/XMLParser.php'; +require_once 'PEAR/ChannelFile.php'; +/** + * Parser for channel.xml + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_ChannelFile_Parser extends PEAR_XMLParser +{ + var $_config; + var $_logger; + var $_registry; + + function setConfig(&$c) + { + $this->_config = &$c; + $this->_registry = &$c->getRegistry(); + } + + function setLogger(&$l) + { + $this->_logger = &$l; + } + + function parse($data, $file) + { + if (PEAR::isError($err = parent::parse($data, $file))) { + return $err; + } + + $ret = new PEAR_ChannelFile; + $ret->setConfig($this->_config); + if (isset($this->_logger)) { + $ret->setLogger($this->_logger); + } + + $ret->fromArray($this->_unserializedData); + // make sure the filelist is in the easy to read format needed + $ret->flattenFilelist(); + $ret->setPackagefile($file, $archive); + return $ret; + } +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Command.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Command.php new file mode 100644 index 0000000..9ec5550 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Command.php @@ -0,0 +1,389 @@ + + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 0.1 + */ + +/** + * Needed for error handling + */ +require_once 'PEAR.php'; +require_once 'PEAR/Frontend.php'; +require_once 'PEAR/XMLParser.php'; + +/** + * List of commands and what classes they are implemented in. + * @var array command => implementing class + */ +$GLOBALS['_PEAR_Command_commandlist'] = array(); + +/** + * List of commands and their descriptions + * @var array command => description + */ +$GLOBALS['_PEAR_Command_commanddesc'] = array(); + +/** + * List of shortcuts to common commands. + * @var array shortcut => command + */ +$GLOBALS['_PEAR_Command_shortcuts'] = array(); + +/** + * Array of command objects + * @var array class => object + */ +$GLOBALS['_PEAR_Command_objects'] = array(); + +/** + * PEAR command class, a simple factory class for administrative + * commands. + * + * How to implement command classes: + * + * - The class must be called PEAR_Command_Nnn, installed in the + * "PEAR/Common" subdir, with a method called getCommands() that + * returns an array of the commands implemented by the class (see + * PEAR/Command/Install.php for an example). + * + * - The class must implement a run() function that is called with three + * params: + * + * (string) command name + * (array) assoc array with options, freely defined by each + * command, for example: + * array('force' => true) + * (array) list of the other parameters + * + * The run() function returns a PEAR_CommandResponse object. Use + * these methods to get information: + * + * int getStatus() Returns PEAR_COMMAND_(SUCCESS|FAILURE|PARTIAL) + * *_PARTIAL means that you need to issue at least + * one more command to complete the operation + * (used for example for validation steps). + * + * string getMessage() Returns a message for the user. Remember, + * no HTML or other interface-specific markup. + * + * If something unexpected happens, run() returns a PEAR error. + * + * - DON'T OUTPUT ANYTHING! Return text for output instead. + * + * - DON'T USE HTML! The text you return will be used from both Gtk, + * web and command-line interfaces, so for now, keep everything to + * plain text. + * + * - DON'T USE EXIT OR DIE! Always use pear errors. From static + * classes do PEAR::raiseError(), from other classes do + * $this->raiseError(). + * @category pear + * @package PEAR + * @author Stig Bakken + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 0.1 + */ +class PEAR_Command +{ + // {{{ factory() + + /** + * Get the right object for executing a command. + * + * @param string $command The name of the command + * @param object $config Instance of PEAR_Config object + * + * @return object the command object or a PEAR error + */ + public static function &factory($command, &$config) + { + if (empty($GLOBALS['_PEAR_Command_commandlist'])) { + PEAR_Command::registerCommands(); + } + if (isset($GLOBALS['_PEAR_Command_shortcuts'][$command])) { + $command = $GLOBALS['_PEAR_Command_shortcuts'][$command]; + } + if (!isset($GLOBALS['_PEAR_Command_commandlist'][$command])) { + $a = PEAR::raiseError("unknown command `$command'"); + return $a; + } + $class = $GLOBALS['_PEAR_Command_commandlist'][$command]; + if (!class_exists($class)) { + require_once $GLOBALS['_PEAR_Command_objects'][$class]; + } + if (!class_exists($class)) { + $a = PEAR::raiseError("unknown command `$command'"); + return $a; + } + $ui =& PEAR_Command::getFrontendObject(); + $obj = new $class($ui, $config); + return $obj; + } + + // }}} + // {{{ & getObject() + public static function &getObject($command) + { + $class = $GLOBALS['_PEAR_Command_commandlist'][$command]; + if (!class_exists($class)) { + require_once $GLOBALS['_PEAR_Command_objects'][$class]; + } + if (!class_exists($class)) { + return PEAR::raiseError("unknown command `$command'"); + } + $ui =& PEAR_Command::getFrontendObject(); + $config = &PEAR_Config::singleton(); + $obj = new $class($ui, $config); + return $obj; + } + + // }}} + // {{{ & getFrontendObject() + + /** + * Get instance of frontend object. + * + * @return object|PEAR_Error + */ + public static function &getFrontendObject() + { + $a = &PEAR_Frontend::singleton(); + return $a; + } + + // }}} + // {{{ & setFrontendClass() + + /** + * Load current frontend class. + * + * @param string $uiclass Name of class implementing the frontend + * + * @return object the frontend object, or a PEAR error + */ + public static function &setFrontendClass($uiclass) + { + $a = &PEAR_Frontend::setFrontendClass($uiclass); + return $a; + } + + // }}} + // {{{ setFrontendType() + + /** + * Set current frontend. + * + * @param string $uitype Name of the frontend type (for example "CLI") + * + * @return object the frontend object, or a PEAR error + */ + public static function setFrontendType($uitype) + { + $uiclass = 'PEAR_Frontend_' . $uitype; + return PEAR_Command::setFrontendClass($uiclass); + } + + // }}} + // {{{ registerCommands() + + /** + * Scan through the Command directory looking for classes + * and see what commands they implement. + * + * @param bool (optional) if FALSE (default), the new list of + * commands should replace the current one. If TRUE, + * new entries will be merged with old. + * + * @param string (optional) where (what directory) to look for + * classes, defaults to the Command subdirectory of + * the directory from where this file (__FILE__) is + * included. + * + * @return bool TRUE on success, a PEAR error on failure + */ + public static function registerCommands($merge = false, $dir = null) + { + $parser = new PEAR_XMLParser; + if ($dir === null) { + $dir = dirname(__FILE__) . '/Command'; + } + if (!is_dir($dir)) { + return PEAR::raiseError("registerCommands: opendir($dir) '$dir' does not exist or is not a directory"); + } + $dp = @opendir($dir); + if (empty($dp)) { + return PEAR::raiseError("registerCommands: opendir($dir) failed"); + } + if (!$merge) { + $GLOBALS['_PEAR_Command_commandlist'] = array(); + } + + while ($file = readdir($dp)) { + if ($file{0} == '.' || substr($file, -4) != '.xml') { + continue; + } + + $f = substr($file, 0, -4); + $class = "PEAR_Command_" . $f; + // List of commands + if (empty($GLOBALS['_PEAR_Command_objects'][$class])) { + $GLOBALS['_PEAR_Command_objects'][$class] = "$dir/" . $f . '.php'; + } + + $parser->parse(file_get_contents("$dir/$file")); + $implements = $parser->getData(); + foreach ($implements as $command => $desc) { + if ($command == 'attribs') { + continue; + } + + if (isset($GLOBALS['_PEAR_Command_commandlist'][$command])) { + return PEAR::raiseError('Command "' . $command . '" already registered in ' . + 'class "' . $GLOBALS['_PEAR_Command_commandlist'][$command] . '"'); + } + + $GLOBALS['_PEAR_Command_commandlist'][$command] = $class; + $GLOBALS['_PEAR_Command_commanddesc'][$command] = $desc['summary']; + if (isset($desc['shortcut'])) { + $shortcut = $desc['shortcut']; + if (isset($GLOBALS['_PEAR_Command_shortcuts'][$shortcut])) { + return PEAR::raiseError('Command shortcut "' . $shortcut . '" already ' . + 'registered to command "' . $command . '" in class "' . + $GLOBALS['_PEAR_Command_commandlist'][$command] . '"'); + } + $GLOBALS['_PEAR_Command_shortcuts'][$shortcut] = $command; + } + + if (isset($desc['options']) && $desc['options']) { + foreach ($desc['options'] as $oname => $option) { + if (isset($option['shortopt']) && strlen($option['shortopt']) > 1) { + return PEAR::raiseError('Option "' . $oname . '" short option "' . + $option['shortopt'] . '" must be ' . + 'only 1 character in Command "' . $command . '" in class "' . + $class . '"'); + } + } + } + } + } + + ksort($GLOBALS['_PEAR_Command_shortcuts']); + ksort($GLOBALS['_PEAR_Command_commandlist']); + @closedir($dp); + return true; + } + + // }}} + // {{{ getCommands() + + /** + * Get the list of currently supported commands, and what + * classes implement them. + * + * @return array command => implementing class + */ + public static function getCommands() + { + if (empty($GLOBALS['_PEAR_Command_commandlist'])) { + PEAR_Command::registerCommands(); + } + return $GLOBALS['_PEAR_Command_commandlist']; + } + + // }}} + // {{{ getShortcuts() + + /** + * Get the list of command shortcuts. + * + * @return array shortcut => command + */ + public static function getShortcuts() + { + if (empty($GLOBALS['_PEAR_Command_shortcuts'])) { + PEAR_Command::registerCommands(); + } + return $GLOBALS['_PEAR_Command_shortcuts']; + } + + // }}} + // {{{ getGetoptArgs() + + /** + * Compiles arguments for getopt. + * + * @param string $command command to get optstring for + * @param string $short_args (reference) short getopt format + * @param array $long_args (reference) long getopt format + * + * @return void + */ + public static function getGetoptArgs($command, &$short_args, &$long_args) + { + if (empty($GLOBALS['_PEAR_Command_commandlist'])) { + PEAR_Command::registerCommands(); + } + if (isset($GLOBALS['_PEAR_Command_shortcuts'][$command])) { + $command = $GLOBALS['_PEAR_Command_shortcuts'][$command]; + } + if (!isset($GLOBALS['_PEAR_Command_commandlist'][$command])) { + return null; + } + $obj = &PEAR_Command::getObject($command); + return $obj->getGetoptArgs($command, $short_args, $long_args); + } + + // }}} + // {{{ getDescription() + + /** + * Get description for a command. + * + * @param string $command Name of the command + * + * @return string command description + */ + public static function getDescription($command) + { + if (!isset($GLOBALS['_PEAR_Command_commanddesc'][$command])) { + return null; + } + return $GLOBALS['_PEAR_Command_commanddesc'][$command]; + } + + // }}} + // {{{ getHelp() + + /** + * Get help for command. + * + * @param string $command Name of the command to return help for + */ + public static function getHelp($command) + { + $cmds = PEAR_Command::getCommands(); + if (isset($GLOBALS['_PEAR_Command_shortcuts'][$command])) { + $command = $GLOBALS['_PEAR_Command_shortcuts'][$command]; + } + if (isset($cmds[$command])) { + $obj = &PEAR_Command::getObject($command); + return $obj->getHelp($command); + } + return false; + } + // }}} +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Command/Auth.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Command/Auth.php new file mode 100644 index 0000000..aa021ec --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Command/Auth.php @@ -0,0 +1,80 @@ + + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 0.1 + * @deprecated since 1.8.0alpha1 + */ + +/** + * base class + */ +require_once 'PEAR/Command/Channels.php'; + +/** + * PEAR commands for login/logout + * + * @category pear + * @package PEAR + * @author Stig Bakken + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 0.1 + * @deprecated since 1.8.0alpha1 + */ +class PEAR_Command_Auth extends PEAR_Command_Channels +{ + var $commands = array( + 'login' => array( + 'summary' => 'Connects and authenticates to remote server [Deprecated in favor of channel-login]', + 'shortcut' => 'li', + 'function' => 'doLogin', + 'options' => array(), + 'doc' => ' +WARNING: This function is deprecated in favor of using channel-login + +Log in to a remote channel server. If is not supplied, +the default channel is used. To use remote functions in the installer +that require any kind of privileges, you need to log in first. The +username and password you enter here will be stored in your per-user +PEAR configuration (~/.pearrc on Unix-like systems). After logging +in, your username and password will be sent along in subsequent +operations on the remote server.', + ), + 'logout' => array( + 'summary' => 'Logs out from the remote server [Deprecated in favor of channel-logout]', + 'shortcut' => 'lo', + 'function' => 'doLogout', + 'options' => array(), + 'doc' => ' +WARNING: This function is deprecated in favor of using channel-logout + +Logs out from the remote server. This command does not actually +connect to the remote server, it only deletes the stored username and +password from your user configuration.', + ) + + ); + + /** + * PEAR_Command_Auth constructor. + * + * @access public + */ + function __construct(&$ui, &$config) + { + parent::__construct($ui, $config); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Command/Build.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Command/Build.php new file mode 100644 index 0000000..7f85193 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Command/Build.php @@ -0,0 +1,84 @@ + + * @author Tomas V.V.Cox + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 0.1 + */ + +/** + * base class + */ +require_once 'PEAR/Command/Common.php'; + +/** + * PEAR commands for building extensions. + * + * @category pear + * @package PEAR + * @author Stig Bakken + * @author Tomas V.V.Cox + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 0.1 + */ +class PEAR_Command_Build extends PEAR_Command_Common +{ + var $commands = array( + 'build' => array( + 'summary' => 'Build an Extension From C Source', + 'function' => 'doBuild', + 'shortcut' => 'b', + 'options' => array(), + 'doc' => '[package.xml] +Builds one or more extensions contained in a package.' + ), + ); + + /** + * PEAR_Command_Build constructor. + * + * @access public + */ + function __construct(&$ui, &$config) + { + parent::__construct($ui, $config); + } + + function doBuild($command, $options, $params) + { + require_once 'PEAR/Builder.php'; + if (sizeof($params) < 1) { + $params[0] = 'package.xml'; + } + + $builder = new PEAR_Builder($this->ui); + $this->debug = $this->config->get('verbose'); + $err = $builder->build($params[0], array(&$this, 'buildCallback')); + if (PEAR::isError($err)) { + return $err; + } + + return true; + } + + function buildCallback($what, $data) + { + if (($what == 'cmdoutput' && $this->debug > 1) || + ($what == 'output' && $this->debug > 0)) { + $this->ui->outputData(rtrim($data), 'build'); + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Command/Channels.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Command/Channels.php new file mode 100644 index 0000000..690483d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Command/Channels.php @@ -0,0 +1,882 @@ + + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * base class + */ +require_once 'PEAR/Command/Common.php'; + +define('PEAR_COMMAND_CHANNELS_CHANNEL_EXISTS', -500); + +/** + * PEAR commands for managing channels. + * + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Command_Channels extends PEAR_Command_Common +{ + var $commands = array( + 'list-channels' => array( + 'summary' => 'List Available Channels', + 'function' => 'doList', + 'shortcut' => 'lc', + 'options' => array(), + 'doc' => ' +List all available channels for installation. +', + ), + 'update-channels' => array( + 'summary' => 'Update the Channel List', + 'function' => 'doUpdateAll', + 'shortcut' => 'uc', + 'options' => array(), + 'doc' => ' +List all installed packages in all channels. +' + ), + 'channel-delete' => array( + 'summary' => 'Remove a Channel From the List', + 'function' => 'doDelete', + 'shortcut' => 'cde', + 'options' => array(), + 'doc' => ' +Delete a channel from the registry. You may not +remove any channel that has installed packages. +' + ), + 'channel-add' => array( + 'summary' => 'Add a Channel', + 'function' => 'doAdd', + 'shortcut' => 'ca', + 'options' => array(), + 'doc' => ' +Add a private channel to the channel list. Note that all +public channels should be synced using "update-channels". +Parameter may be either a local file or remote URL to a +channel.xml. +' + ), + 'channel-update' => array( + 'summary' => 'Update an Existing Channel', + 'function' => 'doUpdate', + 'shortcut' => 'cu', + 'options' => array( + 'force' => array( + 'shortopt' => 'f', + 'doc' => 'will force download of new channel.xml if an existing channel name is used', + ), + 'channel' => array( + 'shortopt' => 'c', + 'arg' => 'CHANNEL', + 'doc' => 'will force download of new channel.xml if an existing channel name is used', + ), +), + 'doc' => '[|] +Update a channel in the channel list directly. Note that all +public channels can be synced using "update-channels". +Parameter may be a local or remote channel.xml, or the name of +an existing channel. +' + ), + 'channel-info' => array( + 'summary' => 'Retrieve Information on a Channel', + 'function' => 'doInfo', + 'shortcut' => 'ci', + 'options' => array(), + 'doc' => ' +List the files in an installed package. +' + ), + 'channel-alias' => array( + 'summary' => 'Specify an alias to a channel name', + 'function' => 'doAlias', + 'shortcut' => 'cha', + 'options' => array(), + 'doc' => ' +Specify a specific alias to use for a channel name. +The alias may not be an existing channel name or +alias. +' + ), + 'channel-discover' => array( + 'summary' => 'Initialize a Channel from its server', + 'function' => 'doDiscover', + 'shortcut' => 'di', + 'options' => array(), + 'doc' => '[|] +Initialize a channel from its server and create a local channel.xml. +If is in the format ":@" then + and will be set as the login username/password for +. Use caution when passing the username/password in this way, as +it may allow other users on your computer to briefly view your username/ +password via the system\'s process list. +' + ), + 'channel-login' => array( + 'summary' => 'Connects and authenticates to remote channel server', + 'shortcut' => 'cli', + 'function' => 'doLogin', + 'options' => array(), + 'doc' => ' +Log in to a remote channel server. If is not supplied, +the default channel is used. To use remote functions in the installer +that require any kind of privileges, you need to log in first. The +username and password you enter here will be stored in your per-user +PEAR configuration (~/.pearrc on Unix-like systems). After logging +in, your username and password will be sent along in subsequent +operations on the remote server.', + ), + 'channel-logout' => array( + 'summary' => 'Logs out from the remote channel server', + 'shortcut' => 'clo', + 'function' => 'doLogout', + 'options' => array(), + 'doc' => ' +Logs out from a remote channel server. If is not supplied, +the default channel is used. This command does not actually connect to the +remote server, it only deletes the stored username and password from your user +configuration.', + ), + ); + + /** + * PEAR_Command_Registry constructor. + * + * @access public + */ + function __construct(&$ui, &$config) + { + parent::__construct($ui, $config); + } + + function _sortChannels($a, $b) + { + return strnatcasecmp($a->getName(), $b->getName()); + } + + function doList($command, $options, $params) + { + $reg = &$this->config->getRegistry(); + $registered = $reg->getChannels(); + usort($registered, array(&$this, '_sortchannels')); + $i = $j = 0; + $data = array( + 'caption' => 'Registered Channels:', + 'border' => true, + 'headline' => array('Channel', 'Alias', 'Summary') + ); + foreach ($registered as $channel) { + $data['data'][] = array($channel->getName(), + $channel->getAlias(), + $channel->getSummary()); + } + + if (count($registered) === 0) { + $data = '(no registered channels)'; + } + $this->ui->outputData($data, $command); + return true; + } + + function doUpdateAll($command, $options, $params) + { + $reg = &$this->config->getRegistry(); + $channels = $reg->getChannels(); + + $success = true; + foreach ($channels as $channel) { + if ($channel->getName() != '__uri') { + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $err = $this->doUpdate('channel-update', + $options, + array($channel->getName())); + if (PEAR::isError($err)) { + $this->ui->outputData($err->getMessage(), $command); + $success = false; + } else { + $success &= $err; + } + } + } + return $success; + } + + function doInfo($command, $options, $params) + { + if (count($params) !== 1) { + return $this->raiseError("No channel specified"); + } + + $reg = &$this->config->getRegistry(); + $channel = strtolower($params[0]); + if ($reg->channelExists($channel)) { + $chan = $reg->getChannel($channel); + if (PEAR::isError($chan)) { + return $this->raiseError($chan); + } + } else { + if (strpos($channel, '://')) { + $downloader = &$this->getDownloader(); + $tmpdir = $this->config->get('temp_dir'); + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $loc = $downloader->downloadHttp($channel, $this->ui, $tmpdir); + PEAR::staticPopErrorHandling(); + if (PEAR::isError($loc)) { + return $this->raiseError('Cannot open "' . $channel . + '" (' . $loc->getMessage() . ')'); + } else { + $contents = implode('', file($loc)); + } + } else { + if (!file_exists($params[0])) { + return $this->raiseError('Unknown channel "' . $channel . '"'); + } + + $fp = fopen($params[0], 'r'); + if (!$fp) { + return $this->raiseError('Cannot open "' . $params[0] . '"'); + } + + $contents = ''; + while (!feof($fp)) { + $contents .= fread($fp, 1024); + } + fclose($fp); + } + + if (!class_exists('PEAR_ChannelFile')) { + require_once 'PEAR/ChannelFile.php'; + } + + $chan = new PEAR_ChannelFile; + $chan->fromXmlString($contents); + $chan->validate(); + if ($errs = $chan->getErrors(true)) { + foreach ($errs as $err) { + $this->ui->outputData($err['level'] . ': ' . $err['message']); + } + return $this->raiseError('Channel file "' . $params[0] . '" is not valid'); + } + } + + if (!$chan) { + return $this->raiseError('Serious error: Channel "' . $params[0] . + '" has a corrupted registry entry'); + } + + $channel = $chan->getName(); + $caption = 'Channel ' . $channel . ' Information:'; + $data1 = array( + 'caption' => $caption, + 'border' => true); + $data1['data']['server'] = array('Name and Server', $chan->getName()); + if ($chan->getAlias() != $chan->getName()) { + $data1['data']['alias'] = array('Alias', $chan->getAlias()); + } + + $data1['data']['summary'] = array('Summary', $chan->getSummary()); + $validate = $chan->getValidationPackage(); + $data1['data']['vpackage'] = array('Validation Package Name', $validate['_content']); + $data1['data']['vpackageversion'] = + array('Validation Package Version', $validate['attribs']['version']); + $d = array(); + $d['main'] = $data1; + + $data['data'] = array(); + $data['caption'] = 'Server Capabilities'; + $data['headline'] = array('Type', 'Version/REST type', 'Function Name/REST base'); + if ($chan->supportsREST()) { + if ($chan->supportsREST()) { + $funcs = $chan->getFunctions('rest'); + if (!isset($funcs[0])) { + $funcs = array($funcs); + } + foreach ($funcs as $protocol) { + $data['data'][] = array('rest', $protocol['attribs']['type'], + $protocol['_content']); + } + } + } else { + $data['data'][] = array('No supported protocols'); + } + + $d['protocols'] = $data; + $data['data'] = array(); + $mirrors = $chan->getMirrors(); + if ($mirrors) { + $data['caption'] = 'Channel ' . $channel . ' Mirrors:'; + unset($data['headline']); + foreach ($mirrors as $mirror) { + $data['data'][] = array($mirror['attribs']['host']); + $d['mirrors'] = $data; + } + + foreach ($mirrors as $i => $mirror) { + $data['data'] = array(); + $data['caption'] = 'Mirror ' . $mirror['attribs']['host'] . ' Capabilities'; + $data['headline'] = array('Type', 'Version/REST type', 'Function Name/REST base'); + if ($chan->supportsREST($mirror['attribs']['host'])) { + if ($chan->supportsREST($mirror['attribs']['host'])) { + $funcs = $chan->getFunctions('rest', $mirror['attribs']['host']); + if (!isset($funcs[0])) { + $funcs = array($funcs); + } + + foreach ($funcs as $protocol) { + $data['data'][] = array('rest', $protocol['attribs']['type'], + $protocol['_content']); + } + } + } else { + $data['data'][] = array('No supported protocols'); + } + $d['mirrorprotocols' . $i] = $data; + } + } + $this->ui->outputData($d, 'channel-info'); + } + + // }}} + + function doDelete($command, $options, $params) + { + if (count($params) !== 1) { + return $this->raiseError('channel-delete: no channel specified'); + } + + $reg = &$this->config->getRegistry(); + if (!$reg->channelExists($params[0])) { + return $this->raiseError('channel-delete: channel "' . $params[0] . '" does not exist'); + } + + $channel = $reg->channelName($params[0]); + if ($channel == 'pear.php.net') { + return $this->raiseError('Cannot delete the pear.php.net channel'); + } + + if ($channel == 'pecl.php.net') { + return $this->raiseError('Cannot delete the pecl.php.net channel'); + } + + if ($channel == 'doc.php.net') { + return $this->raiseError('Cannot delete the doc.php.net channel'); + } + + if ($channel == '__uri') { + return $this->raiseError('Cannot delete the __uri pseudo-channel'); + } + + if (PEAR::isError($err = $reg->listPackages($channel))) { + return $err; + } + + if (count($err)) { + return $this->raiseError('Channel "' . $channel . + '" has installed packages, cannot delete'); + } + + if (!$reg->deleteChannel($channel)) { + return $this->raiseError('Channel "' . $channel . '" deletion failed'); + } else { + $this->config->deleteChannel($channel); + $this->ui->outputData('Channel "' . $channel . '" deleted', $command); + } + } + + function doAdd($command, $options, $params) + { + if (count($params) !== 1) { + return $this->raiseError('channel-add: no channel file specified'); + } + + if (strpos($params[0], '://')) { + $downloader = &$this->getDownloader(); + $tmpdir = $this->config->get('temp_dir'); + if (!file_exists($tmpdir)) { + require_once 'System.php'; + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $err = System::mkdir(array('-p', $tmpdir)); + PEAR::staticPopErrorHandling(); + if (PEAR::isError($err)) { + return $this->raiseError('channel-add: temp_dir does not exist: "' . + $tmpdir . + '" - You can change this location with "pear config-set temp_dir"'); + } + } + + if (!is_writable($tmpdir)) { + return $this->raiseError('channel-add: temp_dir is not writable: "' . + $tmpdir . + '" - You can change this location with "pear config-set temp_dir"'); + } + + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $loc = $downloader->downloadHttp($params[0], $this->ui, $tmpdir, null, false); + PEAR::staticPopErrorHandling(); + if (PEAR::isError($loc)) { + return $this->raiseError('channel-add: Cannot open "' . $params[0] . + '" (' . $loc->getMessage() . ')'); + } + + list($loc, $lastmodified) = $loc; + $contents = implode('', file($loc)); + } else { + $lastmodified = $fp = false; + if (file_exists($params[0])) { + $fp = fopen($params[0], 'r'); + } + + if (!$fp) { + return $this->raiseError('channel-add: cannot open "' . $params[0] . '"'); + } + + $contents = ''; + while (!feof($fp)) { + $contents .= fread($fp, 1024); + } + fclose($fp); + } + + if (!class_exists('PEAR_ChannelFile')) { + require_once 'PEAR/ChannelFile.php'; + } + + $channel = new PEAR_ChannelFile; + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $result = $channel->fromXmlString($contents); + PEAR::staticPopErrorHandling(); + if (!$result) { + $exit = false; + if (count($errors = $channel->getErrors(true))) { + foreach ($errors as $error) { + $this->ui->outputData(ucfirst($error['level'] . ': ' . $error['message'])); + if (!$exit) { + $exit = $error['level'] == 'error' ? true : false; + } + } + if ($exit) { + return $this->raiseError('channel-add: invalid channel.xml file'); + } + } + } + + $reg = &$this->config->getRegistry(); + if ($reg->channelExists($channel->getName())) { + return $this->raiseError('channel-add: Channel "' . $channel->getName() . + '" exists, use channel-update to update entry', PEAR_COMMAND_CHANNELS_CHANNEL_EXISTS); + } + + $ret = $reg->addChannel($channel, $lastmodified); + if (PEAR::isError($ret)) { + return $ret; + } + + if (!$ret) { + return $this->raiseError('channel-add: adding Channel "' . $channel->getName() . + '" to registry failed'); + } + + $this->config->setChannels($reg->listChannels()); + $this->config->writeConfigFile(); + $this->ui->outputData('Adding Channel "' . $channel->getName() . '" succeeded', $command); + } + + function doUpdate($command, $options, $params) + { + if (count($params) !== 1) { + return $this->raiseError("No channel file specified"); + } + + $tmpdir = $this->config->get('temp_dir'); + if (!file_exists($tmpdir)) { + require_once 'System.php'; + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $err = System::mkdir(array('-p', $tmpdir)); + PEAR::staticPopErrorHandling(); + if (PEAR::isError($err)) { + return $this->raiseError('channel-add: temp_dir does not exist: "' . + $tmpdir . + '" - You can change this location with "pear config-set temp_dir"'); + } + } + + if (!is_writable($tmpdir)) { + return $this->raiseError('channel-add: temp_dir is not writable: "' . + $tmpdir . + '" - You can change this location with "pear config-set temp_dir"'); + } + + $reg = &$this->config->getRegistry(); + $lastmodified = false; + if ((!file_exists($params[0]) || is_dir($params[0])) + && $reg->channelExists(strtolower($params[0]))) { + $c = $reg->getChannel(strtolower($params[0])); + if (PEAR::isError($c)) { + return $this->raiseError($c); + } + + $this->ui->outputData("Updating channel \"$params[0]\"", $command); + $dl = &$this->getDownloader(array()); + // if force is specified, use a timestamp of "1" to force retrieval + $lastmodified = isset($options['force']) ? false : $c->lastModified(); + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $contents = $dl->downloadHttp('http://' . $c->getName() . '/channel.xml', + $this->ui, $tmpdir, null, $lastmodified); + PEAR::staticPopErrorHandling(); + if (PEAR::isError($contents)) { + // Attempt to fall back to https + $this->ui->outputData("Channel \"$params[0]\" is not responding over http://, failed with message: " . $contents->getMessage()); + $this->ui->outputData("Trying channel \"$params[0]\" over https:// instead"); + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $contents = $dl->downloadHttp('https://' . $c->getName() . '/channel.xml', + $this->ui, $tmpdir, null, $lastmodified); + PEAR::staticPopErrorHandling(); + if (PEAR::isError($contents)) { + return $this->raiseError('Cannot retrieve channel.xml for channel "' . + $c->getName() . '" (' . $contents->getMessage() . ')'); + } + } + + list($contents, $lastmodified) = $contents; + if (!$contents) { + $this->ui->outputData("Channel \"$params[0]\" is up to date"); + return; + } + + $contents = implode('', file($contents)); + if (!class_exists('PEAR_ChannelFile')) { + require_once 'PEAR/ChannelFile.php'; + } + + $channel = new PEAR_ChannelFile; + $channel->fromXmlString($contents); + if (!$channel->getErrors()) { + // security check: is the downloaded file for the channel we got it from? + if (strtolower($channel->getName()) != strtolower($c->getName())) { + if (!isset($options['force'])) { + return $this->raiseError('ERROR: downloaded channel definition file' . + ' for channel "' . $channel->getName() . '" from channel "' . + strtolower($c->getName()) . '"'); + } + + $this->ui->log(0, 'WARNING: downloaded channel definition file' . + ' for channel "' . $channel->getName() . '" from channel "' . + strtolower($c->getName()) . '"'); + } + } + } else { + if (strpos($params[0], '://')) { + $dl = &$this->getDownloader(); + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $loc = $dl->downloadHttp($params[0], + $this->ui, $tmpdir, null, $lastmodified); + PEAR::staticPopErrorHandling(); + if (PEAR::isError($loc)) { + return $this->raiseError("Cannot open " . $params[0] . + ' (' . $loc->getMessage() . ')'); + } + + list($loc, $lastmodified) = $loc; + $contents = implode('', file($loc)); + } else { + $fp = false; + if (file_exists($params[0])) { + $fp = fopen($params[0], 'r'); + } + + if (!$fp) { + return $this->raiseError("Cannot open " . $params[0]); + } + + $contents = ''; + while (!feof($fp)) { + $contents .= fread($fp, 1024); + } + fclose($fp); + } + + if (!class_exists('PEAR_ChannelFile')) { + require_once 'PEAR/ChannelFile.php'; + } + + $channel = new PEAR_ChannelFile; + $channel->fromXmlString($contents); + } + + $exit = false; + if (count($errors = $channel->getErrors(true))) { + foreach ($errors as $error) { + $this->ui->outputData(ucfirst($error['level'] . ': ' . $error['message'])); + if (!$exit) { + $exit = $error['level'] == 'error' ? true : false; + } + } + if ($exit) { + return $this->raiseError('Invalid channel.xml file'); + } + } + + if (!$reg->channelExists($channel->getName())) { + return $this->raiseError('Error: Channel "' . $channel->getName() . + '" does not exist, use channel-add to add an entry'); + } + + $ret = $reg->updateChannel($channel, $lastmodified); + if (PEAR::isError($ret)) { + return $ret; + } + + if (!$ret) { + return $this->raiseError('Updating Channel "' . $channel->getName() . + '" in registry failed'); + } + + $this->config->setChannels($reg->listChannels()); + $this->config->writeConfigFile(); + $this->ui->outputData('Update of Channel "' . $channel->getName() . '" succeeded'); + } + + function &getDownloader() + { + if (!class_exists('PEAR_Downloader')) { + require_once 'PEAR/Downloader.php'; + } + $a = new PEAR_Downloader($this->ui, array(), $this->config); + return $a; + } + + function doAlias($command, $options, $params) + { + if (count($params) === 1) { + return $this->raiseError('No channel alias specified'); + } + + if (count($params) !== 2 || (!empty($params[1]) && $params[1]{0} == '-')) { + return $this->raiseError( + 'Invalid format, correct is: channel-alias channel alias'); + } + + $reg = &$this->config->getRegistry(); + if (!$reg->channelExists($params[0], true)) { + $extra = ''; + if ($reg->isAlias($params[0])) { + $extra = ' (use "channel-alias ' . $reg->channelName($params[0]) . ' ' . + strtolower($params[1]) . '")'; + } + + return $this->raiseError('"' . $params[0] . '" is not a valid channel' . $extra); + } + + if ($reg->isAlias($params[1])) { + return $this->raiseError('Channel "' . $reg->channelName($params[1]) . '" is ' . + 'already aliased to "' . strtolower($params[1]) . '", cannot re-alias'); + } + + $chan = $reg->getChannel($params[0]); + if (PEAR::isError($chan)) { + return $this->raiseError('Corrupt registry? Error retrieving channel "' . $params[0] . + '" information (' . $chan->getMessage() . ')'); + } + + // make it a local alias + if (!$chan->setAlias(strtolower($params[1]), true)) { + return $this->raiseError('Alias "' . strtolower($params[1]) . + '" is not a valid channel alias'); + } + + $reg->updateChannel($chan); + $this->ui->outputData('Channel "' . $chan->getName() . '" aliased successfully to "' . + strtolower($params[1]) . '"'); + } + + /** + * The channel-discover command + * + * @param string $command command name + * @param array $options option_name => value + * @param array $params list of additional parameters. + * $params[0] should contain a string with either: + * - or + * - :@ + * @return null|PEAR_Error + */ + function doDiscover($command, $options, $params) + { + if (count($params) !== 1) { + return $this->raiseError("No channel server specified"); + } + + // Look for the possible input format ":@" + if (preg_match('/^(.+):(.+)@(.+)\\z/', $params[0], $matches)) { + $username = $matches[1]; + $password = $matches[2]; + $channel = $matches[3]; + } else { + $channel = $params[0]; + } + + $reg = &$this->config->getRegistry(); + if ($reg->channelExists($channel)) { + if (!$reg->isAlias($channel)) { + return $this->raiseError("Channel \"$channel\" is already initialized", PEAR_COMMAND_CHANNELS_CHANNEL_EXISTS); + } + + return $this->raiseError("A channel alias named \"$channel\" " . + 'already exists, aliasing channel "' . $reg->channelName($channel) + . '"'); + } + + $this->pushErrorHandling(PEAR_ERROR_RETURN); + $err = $this->doAdd($command, $options, array('http://' . $channel . '/channel.xml')); + $this->popErrorHandling(); + if (PEAR::isError($err)) { + if ($err->getCode() === PEAR_COMMAND_CHANNELS_CHANNEL_EXISTS) { + return $this->raiseError("Discovery of channel \"$channel\" failed (" . + $err->getMessage() . ')'); + } + // Attempt fetch via https + $this->ui->outputData("Discovering channel $channel over http:// failed with message: " . $err->getMessage()); + $this->ui->outputData("Trying to discover channel $channel over https:// instead"); + $this->pushErrorHandling(PEAR_ERROR_RETURN); + $err = $this->doAdd($command, $options, array('https://' . $channel . '/channel.xml')); + $this->popErrorHandling(); + if (PEAR::isError($err)) { + return $this->raiseError("Discovery of channel \"$channel\" failed (" . + $err->getMessage() . ')'); + } + } + + // Store username/password if they were given + // Arguably we should do a logintest on the channel here, but since + // that's awkward on a REST-based channel (even "pear login" doesn't + // do it for those), and XML-RPC is deprecated, it's fairly pointless. + if (isset($username)) { + $this->config->set('username', $username, 'user', $channel); + $this->config->set('password', $password, 'user', $channel); + $this->config->store(); + $this->ui->outputData("Stored login for channel \"$channel\" using username \"$username\"", $command); + } + + $this->ui->outputData("Discovery of channel \"$channel\" succeeded", $command); + } + + /** + * Execute the 'login' command. + * + * @param string $command command name + * @param array $options option_name => value + * @param array $params list of additional parameters + * + * @return bool TRUE on success or + * a PEAR error on failure + * + * @access public + */ + function doLogin($command, $options, $params) + { + $reg = &$this->config->getRegistry(); + + // If a parameter is supplied, use that as the channel to log in to + $channel = isset($params[0]) ? $params[0] : $this->config->get('default_channel'); + + $chan = $reg->getChannel($channel); + if (PEAR::isError($chan)) { + return $this->raiseError($chan); + } + + $server = $this->config->get('preferred_mirror', null, $channel); + $username = $this->config->get('username', null, $channel); + if (empty($username)) { + $username = isset($_ENV['USER']) ? $_ENV['USER'] : null; + } + $this->ui->outputData("Logging in to $server.", $command); + + list($username, $password) = $this->ui->userDialog( + $command, + array('Username', 'Password'), + array('text', 'password'), + array($username, '') + ); + $username = trim($username); + $password = trim($password); + + $ourfile = $this->config->getConfFile('user'); + if (!$ourfile) { + $ourfile = $this->config->getConfFile('system'); + } + + $this->config->set('username', $username, 'user', $channel); + $this->config->set('password', $password, 'user', $channel); + + if ($chan->supportsREST()) { + $ok = true; + } + + if ($ok !== true) { + return $this->raiseError('Login failed!'); + } + + $this->ui->outputData("Logged in.", $command); + // avoid changing any temporary settings changed with -d + $ourconfig = new PEAR_Config($ourfile, $ourfile); + $ourconfig->set('username', $username, 'user', $channel); + $ourconfig->set('password', $password, 'user', $channel); + $ourconfig->store(); + + return true; + } + + /** + * Execute the 'logout' command. + * + * @param string $command command name + * @param array $options option_name => value + * @param array $params list of additional parameters + * + * @return bool TRUE on success or + * a PEAR error on failure + * + * @access public + */ + function doLogout($command, $options, $params) + { + $reg = &$this->config->getRegistry(); + + // If a parameter is supplied, use that as the channel to log in to + $channel = isset($params[0]) ? $params[0] : $this->config->get('default_channel'); + + $chan = $reg->getChannel($channel); + if (PEAR::isError($chan)) { + return $this->raiseError($chan); + } + + $server = $this->config->get('preferred_mirror', null, $channel); + $this->ui->outputData("Logging out from $server.", $command); + $this->config->remove('username', 'user', $channel); + $this->config->remove('password', 'user', $channel); + $this->config->store(); + return true; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Command/Common.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Command/Common.php new file mode 100644 index 0000000..4be5376 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Command/Common.php @@ -0,0 +1,272 @@ + + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 0.1 + */ + +/** + * base class + */ +require_once 'PEAR.php'; + +/** + * PEAR commands base class + * + * @category pear + * @package PEAR + * @author Stig Bakken + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 0.1 + */ +class PEAR_Command_Common extends PEAR +{ + /** + * PEAR_Config object used to pass user system and configuration + * on when executing commands + * + * @var PEAR_Config + */ + var $config; + /** + * @var PEAR_Registry + * @access protected + */ + var $_registry; + + /** + * User Interface object, for all interaction with the user. + * @var object + */ + var $ui; + + var $_deps_rel_trans = array( + 'lt' => '<', + 'le' => '<=', + 'eq' => '=', + 'ne' => '!=', + 'gt' => '>', + 'ge' => '>=', + 'has' => '==' + ); + + var $_deps_type_trans = array( + 'pkg' => 'package', + 'ext' => 'extension', + 'php' => 'PHP', + 'prog' => 'external program', + 'ldlib' => 'external library for linking', + 'rtlib' => 'external runtime library', + 'os' => 'operating system', + 'websrv' => 'web server', + 'sapi' => 'SAPI backend' + ); + + /** + * PEAR_Command_Common constructor. + * + * @access public + */ + function __construct(&$ui, &$config) + { + parent::__construct(); + $this->config = &$config; + $this->ui = &$ui; + } + + /** + * Return a list of all the commands defined by this class. + * @return array list of commands + * @access public + */ + function getCommands() + { + $ret = array(); + foreach (array_keys($this->commands) as $command) { + $ret[$command] = $this->commands[$command]['summary']; + } + + return $ret; + } + + /** + * Return a list of all the command shortcuts defined by this class. + * @return array shortcut => command + * @access public + */ + function getShortcuts() + { + $ret = array(); + foreach (array_keys($this->commands) as $command) { + if (isset($this->commands[$command]['shortcut'])) { + $ret[$this->commands[$command]['shortcut']] = $command; + } + } + + return $ret; + } + + function getOptions($command) + { + $shortcuts = $this->getShortcuts(); + if (isset($shortcuts[$command])) { + $command = $shortcuts[$command]; + } + + if (isset($this->commands[$command]) && + isset($this->commands[$command]['options'])) { + return $this->commands[$command]['options']; + } + + return null; + } + + function getGetoptArgs($command, &$short_args, &$long_args) + { + $short_args = ''; + $long_args = array(); + if (empty($this->commands[$command]) || empty($this->commands[$command]['options'])) { + return; + } + + reset($this->commands[$command]['options']); + while (list($option, $info) = each($this->commands[$command]['options'])) { + $larg = $sarg = ''; + if (isset($info['arg'])) { + if ($info['arg']{0} == '(') { + $larg = '=='; + $sarg = '::'; + $arg = substr($info['arg'], 1, -1); + } else { + $larg = '='; + $sarg = ':'; + $arg = $info['arg']; + } + } + + if (isset($info['shortopt'])) { + $short_args .= $info['shortopt'] . $sarg; + } + + $long_args[] = $option . $larg; + } + } + + /** + * Returns the help message for the given command + * + * @param string $command The command + * @return mixed A fail string if the command does not have help or + * a two elements array containing [0]=>help string, + * [1]=> help string for the accepted cmd args + */ + function getHelp($command) + { + $config = &PEAR_Config::singleton(); + if (!isset($this->commands[$command])) { + return "No such command \"$command\""; + } + + $help = null; + if (isset($this->commands[$command]['doc'])) { + $help = $this->commands[$command]['doc']; + } + + if (empty($help)) { + // XXX (cox) Fallback to summary if there is no doc (show both?) + if (!isset($this->commands[$command]['summary'])) { + return "No help for command \"$command\""; + } + $help = $this->commands[$command]['summary']; + } + + if (preg_match_all('/{config\s+([^\}]+)}/e', $help, $matches)) { + foreach($matches[0] as $k => $v) { + $help = preg_replace("/$v/", $config->get($matches[1][$k]), $help); + } + } + + return array($help, $this->getHelpArgs($command)); + } + + /** + * Returns the help for the accepted arguments of a command + * + * @param string $command + * @return string The help string + */ + function getHelpArgs($command) + { + if (isset($this->commands[$command]['options']) && + count($this->commands[$command]['options'])) + { + $help = "Options:\n"; + foreach ($this->commands[$command]['options'] as $k => $v) { + if (isset($v['arg'])) { + if ($v['arg'][0] == '(') { + $arg = substr($v['arg'], 1, -1); + $sapp = " [$arg]"; + $lapp = "[=$arg]"; + } else { + $sapp = " $v[arg]"; + $lapp = "=$v[arg]"; + } + } else { + $sapp = $lapp = ""; + } + + if (isset($v['shortopt'])) { + $s = $v['shortopt']; + $help .= " -$s$sapp, --$k$lapp\n"; + } else { + $help .= " --$k$lapp\n"; + } + + $p = " "; + $doc = rtrim(str_replace("\n", "\n$p", $v['doc'])); + $help .= " $doc\n"; + } + + return $help; + } + + return null; + } + + function run($command, $options, $params) + { + if (empty($this->commands[$command]['function'])) { + // look for shortcuts + foreach (array_keys($this->commands) as $cmd) { + if (isset($this->commands[$cmd]['shortcut']) && $this->commands[$cmd]['shortcut'] == $command) { + if (empty($this->commands[$cmd]['function'])) { + return $this->raiseError("unknown command `$command'"); + } else { + $func = $this->commands[$cmd]['function']; + } + $command = $cmd; + + //$command = $this->commands[$cmd]['function']; + break; + } + } + } else { + $func = $this->commands[$command]['function']; + } + + return $this->$func($command, $options, $params); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Command/Config.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Command/Config.php new file mode 100644 index 0000000..705a7cb --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Command/Config.php @@ -0,0 +1,414 @@ + + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 0.1 + */ + +/** + * base class + */ +require_once 'PEAR/Command/Common.php'; + +/** + * PEAR commands for managing configuration data. + * + * @category pear + * @package PEAR + * @author Stig Bakken + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 0.1 + */ +class PEAR_Command_Config extends PEAR_Command_Common +{ + var $commands = array( + 'config-show' => array( + 'summary' => 'Show All Settings', + 'function' => 'doConfigShow', + 'shortcut' => 'csh', + 'options' => array( + 'channel' => array( + 'shortopt' => 'c', + 'doc' => 'show configuration variables for another channel', + 'arg' => 'CHAN', + ), +), + 'doc' => '[layer] +Displays all configuration values. An optional argument +may be used to tell which configuration layer to display. Valid +configuration layers are "user", "system" and "default". To display +configurations for different channels, set the default_channel +configuration variable and run config-show again. +', + ), + 'config-get' => array( + 'summary' => 'Show One Setting', + 'function' => 'doConfigGet', + 'shortcut' => 'cg', + 'options' => array( + 'channel' => array( + 'shortopt' => 'c', + 'doc' => 'show configuration variables for another channel', + 'arg' => 'CHAN', + ), +), + 'doc' => ' [layer] +Displays the value of one configuration parameter. The +first argument is the name of the parameter, an optional second argument +may be used to tell which configuration layer to look in. Valid configuration +layers are "user", "system" and "default". If no layer is specified, a value +will be picked from the first layer that defines the parameter, in the order +just specified. The configuration value will be retrieved for the channel +specified by the default_channel configuration variable. +', + ), + 'config-set' => array( + 'summary' => 'Change Setting', + 'function' => 'doConfigSet', + 'shortcut' => 'cs', + 'options' => array( + 'channel' => array( + 'shortopt' => 'c', + 'doc' => 'show configuration variables for another channel', + 'arg' => 'CHAN', + ), +), + 'doc' => ' [layer] +Sets the value of one configuration parameter. The first argument is +the name of the parameter, the second argument is the new value. Some +parameters are subject to validation, and the command will fail with +an error message if the new value does not make sense. An optional +third argument may be used to specify in which layer to set the +configuration parameter. The default layer is "user". The +configuration value will be set for the current channel, which +is controlled by the default_channel configuration variable. +', + ), + 'config-help' => array( + 'summary' => 'Show Information About Setting', + 'function' => 'doConfigHelp', + 'shortcut' => 'ch', + 'options' => array(), + 'doc' => '[parameter] +Displays help for a configuration parameter. Without arguments it +displays help for all configuration parameters. +', + ), + 'config-create' => array( + 'summary' => 'Create a Default configuration file', + 'function' => 'doConfigCreate', + 'shortcut' => 'coc', + 'options' => array( + 'windows' => array( + 'shortopt' => 'w', + 'doc' => 'create a config file for a windows install', + ), + ), + 'doc' => ' +Create a default configuration file with all directory configuration +variables set to subdirectories of , and save it as . +This is useful especially for creating a configuration file for a remote +PEAR installation (using the --remoteconfig option of install, upgrade, +and uninstall). +', + ), + ); + + /** + * PEAR_Command_Config constructor. + * + * @access public + */ + function __construct(&$ui, &$config) + { + parent::__construct($ui, $config); + } + + function doConfigShow($command, $options, $params) + { + $layer = null; + if (is_array($params)) { + $layer = isset($params[0]) ? $params[0] : null; + } + + // $params[0] -> the layer + if ($error = $this->_checkLayer($layer)) { + return $this->raiseError("config-show:$error"); + } + + $keys = $this->config->getKeys(); + sort($keys); + $channel = isset($options['channel']) ? $options['channel'] : + $this->config->get('default_channel'); + $reg = &$this->config->getRegistry(); + if (!$reg->channelExists($channel)) { + return $this->raiseError('Channel "' . $channel . '" does not exist'); + } + + $channel = $reg->channelName($channel); + $data = array('caption' => 'Configuration (channel ' . $channel . '):'); + foreach ($keys as $key) { + $type = $this->config->getType($key); + $value = $this->config->get($key, $layer, $channel); + if ($type == 'password' && $value) { + $value = '********'; + } + + if ($value === false) { + $value = 'false'; + } elseif ($value === true) { + $value = 'true'; + } + + $data['data'][$this->config->getGroup($key)][] = array($this->config->getPrompt($key) , $key, $value); + } + + foreach ($this->config->getLayers() as $layer) { + $data['data']['Config Files'][] = array(ucfirst($layer) . ' Configuration File', 'Filename' , $this->config->getConfFile($layer)); + } + + $this->ui->outputData($data, $command); + return true; + } + + function doConfigGet($command, $options, $params) + { + $args_cnt = is_array($params) ? count($params) : 0; + switch ($args_cnt) { + case 1: + $config_key = $params[0]; + $layer = null; + break; + case 2: + $config_key = $params[0]; + $layer = $params[1]; + if ($error = $this->_checkLayer($layer)) { + return $this->raiseError("config-get:$error"); + } + break; + case 0: + default: + return $this->raiseError("config-get expects 1 or 2 parameters"); + } + + $reg = &$this->config->getRegistry(); + $channel = isset($options['channel']) ? $options['channel'] : $this->config->get('default_channel'); + if (!$reg->channelExists($channel)) { + return $this->raiseError('Channel "' . $channel . '" does not exist'); + } + + $channel = $reg->channelName($channel); + $this->ui->outputData($this->config->get($config_key, $layer, $channel), $command); + return true; + } + + function doConfigSet($command, $options, $params) + { + // $param[0] -> a parameter to set + // $param[1] -> the value for the parameter + // $param[2] -> the layer + $failmsg = ''; + if (count($params) < 2 || count($params) > 3) { + $failmsg .= "config-set expects 2 or 3 parameters"; + return PEAR::raiseError($failmsg); + } + + if (isset($params[2]) && ($error = $this->_checkLayer($params[2]))) { + $failmsg .= $error; + return PEAR::raiseError("config-set:$failmsg"); + } + + $channel = isset($options['channel']) ? $options['channel'] : $this->config->get('default_channel'); + $reg = &$this->config->getRegistry(); + if (!$reg->channelExists($channel)) { + return $this->raiseError('Channel "' . $channel . '" does not exist'); + } + + $channel = $reg->channelName($channel); + if ($params[0] == 'default_channel' && !$reg->channelExists($params[1])) { + return $this->raiseError('Channel "' . $params[1] . '" does not exist'); + } + + if ($params[0] == 'preferred_mirror' + && ( + !$reg->mirrorExists($channel, $params[1]) && + (!$reg->channelExists($params[1]) || $channel != $params[1]) + ) + ) { + $msg = 'Channel Mirror "' . $params[1] . '" does not exist'; + $msg .= ' in your registry for channel "' . $channel . '".'; + $msg .= "\n" . 'Attempt to run "pear channel-update ' . $channel .'"'; + $msg .= ' if you believe this mirror should exist as you may'; + $msg .= ' have outdated channel information.'; + return $this->raiseError($msg); + } + + if (count($params) == 2) { + array_push($params, 'user'); + $layer = 'user'; + } else { + $layer = $params[2]; + } + + array_push($params, $channel); + if (!call_user_func_array(array(&$this->config, 'set'), $params)) { + array_pop($params); + $failmsg = "config-set (" . implode(", ", $params) . ") failed, channel $channel"; + } else { + $this->config->store($layer); + } + + if ($failmsg) { + return $this->raiseError($failmsg); + } + + $this->ui->outputData('config-set succeeded', $command); + return true; + } + + function doConfigHelp($command, $options, $params) + { + if (empty($params)) { + $params = $this->config->getKeys(); + } + + $data['caption'] = "Config help" . ((count($params) == 1) ? " for $params[0]" : ''); + $data['headline'] = array('Name', 'Type', 'Description'); + $data['border'] = true; + foreach ($params as $name) { + $type = $this->config->getType($name); + $docs = $this->config->getDocs($name); + if ($type == 'set') { + $docs = rtrim($docs) . "\nValid set: " . + implode(' ', $this->config->getSetValues($name)); + } + + $data['data'][] = array($name, $type, $docs); + } + + $this->ui->outputData($data, $command); + } + + function doConfigCreate($command, $options, $params) + { + if (count($params) != 2) { + return PEAR::raiseError('config-create: must have 2 parameters, root path and ' . + 'filename to save as'); + } + + $root = $params[0]; + // Clean up the DIRECTORY_SEPARATOR mess + $ds2 = DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR; + $root = preg_replace(array('!\\\\+!', '!/+!', "!$ds2+!"), + array('/', '/', '/'), + $root); + if ($root{0} != '/') { + if (!isset($options['windows'])) { + return PEAR::raiseError('Root directory must be an absolute path beginning ' . + 'with "/", was: "' . $root . '"'); + } + + if (!preg_match('/^[A-Za-z]:/', $root)) { + return PEAR::raiseError('Root directory must be an absolute path beginning ' . + 'with "\\" or "C:\\", was: "' . $root . '"'); + } + } + + $windows = isset($options['windows']); + if ($windows) { + $root = str_replace('/', '\\', $root); + } + + if (!file_exists($params[1]) && !@touch($params[1])) { + return PEAR::raiseError('Could not create "' . $params[1] . '"'); + } + + $params[1] = realpath($params[1]); + $config = new PEAR_Config($params[1], '#no#system#config#', false, false); + if ($root{strlen($root) - 1} == '/') { + $root = substr($root, 0, strlen($root) - 1); + } + + $config->noRegistry(); + $config->set('php_dir', $windows ? "$root\\pear\\php" : "$root/pear/php", 'user'); + $config->set('data_dir', $windows ? "$root\\pear\\data" : "$root/pear/data"); + $config->set('www_dir', $windows ? "$root\\pear\\www" : "$root/pear/www"); + $config->set('cfg_dir', $windows ? "$root\\pear\\cfg" : "$root/pear/cfg"); + $config->set('ext_dir', $windows ? "$root\\pear\\ext" : "$root/pear/ext"); + $config->set('doc_dir', $windows ? "$root\\pear\\docs" : "$root/pear/docs"); + $config->set('test_dir', $windows ? "$root\\pear\\tests" : "$root/pear/tests"); + $config->set('cache_dir', $windows ? "$root\\pear\\cache" : "$root/pear/cache"); + $config->set('download_dir', $windows ? "$root\\pear\\download" : "$root/pear/download"); + $config->set('temp_dir', $windows ? "$root\\pear\\temp" : "$root/pear/temp"); + $config->set('bin_dir', $windows ? "$root\\pear" : "$root/pear"); + $config->set('man_dir', $windows ? "$root\\pear\\man" : "$root/pear/man"); + $config->writeConfigFile(); + $this->_showConfig($config); + $this->ui->outputData('Successfully created default configuration file "' . $params[1] . '"', + $command); + } + + function _showConfig(&$config) + { + $params = array('user'); + $keys = $config->getKeys(); + sort($keys); + $channel = 'pear.php.net'; + $data = array('caption' => 'Configuration (channel ' . $channel . '):'); + foreach ($keys as $key) { + $type = $config->getType($key); + $value = $config->get($key, 'user', $channel); + if ($type == 'password' && $value) { + $value = '********'; + } + + if ($value === false) { + $value = 'false'; + } elseif ($value === true) { + $value = 'true'; + } + $data['data'][$config->getGroup($key)][] = + array($config->getPrompt($key) , $key, $value); + } + + foreach ($config->getLayers() as $layer) { + $data['data']['Config Files'][] = + array(ucfirst($layer) . ' Configuration File', 'Filename' , + $config->getConfFile($layer)); + } + + $this->ui->outputData($data, 'config-show'); + return true; + } + + /** + * Checks if a layer is defined or not + * + * @param string $layer The layer to search for + * @return mixed False on no error or the error message + */ + function _checkLayer($layer = null) + { + if (!empty($layer) && $layer != 'default') { + $layers = $this->config->getLayers(); + if (!in_array($layer, $layers)) { + return " only the layers: \"" . implode('" or "', $layers) . "\" are supported"; + } + } + + return false; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Command/Install.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Command/Install.php new file mode 100644 index 0000000..9d572ed --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Command/Install.php @@ -0,0 +1,1269 @@ + + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 0.1 + */ + +/** + * base class + */ +require_once 'PEAR/Command/Common.php'; + +/** + * PEAR commands for installation or deinstallation/upgrading of + * packages. + * + * @category pear + * @package PEAR + * @author Stig Bakken + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 0.1 + */ +class PEAR_Command_Install extends PEAR_Command_Common +{ + // {{{ properties + + var $commands = array( + 'install' => array( + 'summary' => 'Install Package', + 'function' => 'doInstall', + 'shortcut' => 'i', + 'options' => array( + 'force' => array( + 'shortopt' => 'f', + 'doc' => 'will overwrite newer installed packages', + ), + 'loose' => array( + 'shortopt' => 'l', + 'doc' => 'do not check for recommended dependency version', + ), + 'nodeps' => array( + 'shortopt' => 'n', + 'doc' => 'ignore dependencies, install anyway', + ), + 'register-only' => array( + 'shortopt' => 'r', + 'doc' => 'do not install files, only register the package as installed', + ), + 'soft' => array( + 'shortopt' => 's', + 'doc' => 'soft install, fail silently, or upgrade if already installed', + ), + 'nobuild' => array( + 'shortopt' => 'B', + 'doc' => 'don\'t build C extensions', + ), + 'nocompress' => array( + 'shortopt' => 'Z', + 'doc' => 'request uncompressed files when downloading', + ), + 'installroot' => array( + 'shortopt' => 'R', + 'arg' => 'DIR', + 'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT), use packagingroot for RPM', + ), + 'packagingroot' => array( + 'shortopt' => 'P', + 'arg' => 'DIR', + 'doc' => 'root directory used when packaging files, like RPM packaging', + ), + 'ignore-errors' => array( + 'doc' => 'force install even if there were errors', + ), + 'alldeps' => array( + 'shortopt' => 'a', + 'doc' => 'install all required and optional dependencies', + ), + 'onlyreqdeps' => array( + 'shortopt' => 'o', + 'doc' => 'install all required dependencies', + ), + 'offline' => array( + 'shortopt' => 'O', + 'doc' => 'do not attempt to download any urls or contact channels', + ), + 'pretend' => array( + 'shortopt' => 'p', + 'doc' => 'Only list the packages that would be downloaded', + ), + ), + 'doc' => '[channel/] ... +Installs one or more PEAR packages. You can specify a package to +install in four ways: + +"Package-1.0.tgz" : installs from a local file + +"http://example.com/Package-1.0.tgz" : installs from +anywhere on the net. + +"package.xml" : installs the package described in +package.xml. Useful for testing, or for wrapping a PEAR package in +another package manager such as RPM. + +"Package[-version/state][.tar]" : queries your default channel\'s server +({config master_server}) and downloads the newest package with +the preferred quality/state ({config preferred_state}). + +To retrieve Package version 1.1, use "Package-1.1," to retrieve +Package state beta, use "Package-beta." To retrieve an uncompressed +file, append .tar (make sure there is no file by the same name first) + +To download a package from another channel, prefix with the channel name like +"channel/Package" + +More than one package may be specified at once. It is ok to mix these +four ways of specifying packages. +'), + 'upgrade' => array( + 'summary' => 'Upgrade Package', + 'function' => 'doInstall', + 'shortcut' => 'up', + 'options' => array( + 'channel' => array( + 'shortopt' => 'c', + 'doc' => 'upgrade packages from a specific channel', + 'arg' => 'CHAN', + ), + 'force' => array( + 'shortopt' => 'f', + 'doc' => 'overwrite newer installed packages', + ), + 'loose' => array( + 'shortopt' => 'l', + 'doc' => 'do not check for recommended dependency version', + ), + 'nodeps' => array( + 'shortopt' => 'n', + 'doc' => 'ignore dependencies, upgrade anyway', + ), + 'register-only' => array( + 'shortopt' => 'r', + 'doc' => 'do not install files, only register the package as upgraded', + ), + 'nobuild' => array( + 'shortopt' => 'B', + 'doc' => 'don\'t build C extensions', + ), + 'nocompress' => array( + 'shortopt' => 'Z', + 'doc' => 'request uncompressed files when downloading', + ), + 'installroot' => array( + 'shortopt' => 'R', + 'arg' => 'DIR', + 'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT)', + ), + 'ignore-errors' => array( + 'doc' => 'force install even if there were errors', + ), + 'alldeps' => array( + 'shortopt' => 'a', + 'doc' => 'install all required and optional dependencies', + ), + 'onlyreqdeps' => array( + 'shortopt' => 'o', + 'doc' => 'install all required dependencies', + ), + 'offline' => array( + 'shortopt' => 'O', + 'doc' => 'do not attempt to download any urls or contact channels', + ), + 'pretend' => array( + 'shortopt' => 'p', + 'doc' => 'Only list the packages that would be downloaded', + ), + ), + 'doc' => ' ... +Upgrades one or more PEAR packages. See documentation for the +"install" command for ways to specify a package. + +When upgrading, your package will be updated if the provided new +package has a higher version number (use the -f option if you need to +upgrade anyway). + +More than one package may be specified at once. +'), + 'upgrade-all' => array( + 'summary' => 'Upgrade All Packages [Deprecated in favor of calling upgrade with no parameters]', + 'function' => 'doUpgradeAll', + 'shortcut' => 'ua', + 'options' => array( + 'channel' => array( + 'shortopt' => 'c', + 'doc' => 'upgrade packages from a specific channel', + 'arg' => 'CHAN', + ), + 'nodeps' => array( + 'shortopt' => 'n', + 'doc' => 'ignore dependencies, upgrade anyway', + ), + 'register-only' => array( + 'shortopt' => 'r', + 'doc' => 'do not install files, only register the package as upgraded', + ), + 'nobuild' => array( + 'shortopt' => 'B', + 'doc' => 'don\'t build C extensions', + ), + 'nocompress' => array( + 'shortopt' => 'Z', + 'doc' => 'request uncompressed files when downloading', + ), + 'installroot' => array( + 'shortopt' => 'R', + 'arg' => 'DIR', + 'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT), use packagingroot for RPM', + ), + 'ignore-errors' => array( + 'doc' => 'force install even if there were errors', + ), + 'loose' => array( + 'doc' => 'do not check for recommended dependency version', + ), + ), + 'doc' => ' +WARNING: This function is deprecated in favor of using the upgrade command with no params + +Upgrades all packages that have a newer release available. Upgrades are +done only if there is a release available of the state specified in +"preferred_state" (currently {config preferred_state}), or a state considered +more stable. +'), + 'uninstall' => array( + 'summary' => 'Un-install Package', + 'function' => 'doUninstall', + 'shortcut' => 'un', + 'options' => array( + 'nodeps' => array( + 'shortopt' => 'n', + 'doc' => 'ignore dependencies, uninstall anyway', + ), + 'register-only' => array( + 'shortopt' => 'r', + 'doc' => 'do not remove files, only register the packages as not installed', + ), + 'installroot' => array( + 'shortopt' => 'R', + 'arg' => 'DIR', + 'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT)', + ), + 'ignore-errors' => array( + 'doc' => 'force install even if there were errors', + ), + 'offline' => array( + 'shortopt' => 'O', + 'doc' => 'do not attempt to uninstall remotely', + ), + ), + 'doc' => '[channel/] ... +Uninstalls one or more PEAR packages. More than one package may be +specified at once. Prefix with channel name to uninstall from a +channel not in your default channel ({config default_channel}) +'), + 'bundle' => array( + 'summary' => 'Unpacks a Pecl Package', + 'function' => 'doBundle', + 'shortcut' => 'bun', + 'options' => array( + 'destination' => array( + 'shortopt' => 'd', + 'arg' => 'DIR', + 'doc' => 'Optional destination directory for unpacking (defaults to current path or "ext" if exists)', + ), + 'force' => array( + 'shortopt' => 'f', + 'doc' => 'Force the unpacking even if there were errors in the package', + ), + ), + 'doc' => ' +Unpacks a Pecl Package into the selected location. It will download the +package if needed. +'), + 'run-scripts' => array( + 'summary' => 'Run Post-Install Scripts bundled with a package', + 'function' => 'doRunScripts', + 'shortcut' => 'rs', + 'options' => array( + ), + 'doc' => ' +Run post-installation scripts in package , if any exist. +'), + ); + + // }}} + // {{{ constructor + + /** + * PEAR_Command_Install constructor. + * + * @access public + */ + function __construct(&$ui, &$config) + { + parent::__construct($ui, $config); + } + + // }}} + + /** + * For unit testing purposes + */ + function &getDownloader(&$ui, $options, &$config) + { + if (!class_exists('PEAR_Downloader')) { + require_once 'PEAR/Downloader.php'; + } + $a = new PEAR_Downloader($ui, $options, $config); + return $a; + } + + /** + * For unit testing purposes + */ + function &getInstaller(&$ui) + { + if (!class_exists('PEAR_Installer')) { + require_once 'PEAR/Installer.php'; + } + $a = new PEAR_Installer($ui); + return $a; + } + + function enableExtension($binaries, $type) + { + if (!($phpini = $this->config->get('php_ini', null, 'pear.php.net'))) { + return PEAR::raiseError('configuration option "php_ini" is not set to php.ini location'); + } + $ini = $this->_parseIni($phpini); + if (PEAR::isError($ini)) { + return $ini; + } + $line = 0; + if ($type == 'extsrc' || $type == 'extbin') { + $search = 'extensions'; + $enable = 'extension'; + } else { + $search = 'zend_extensions'; + ob_start(); + phpinfo(INFO_GENERAL); + $info = ob_get_contents(); + ob_end_clean(); + $debug = function_exists('leak') ? '_debug' : ''; + $ts = preg_match('/Thread Safety.+enabled/', $info) ? '_ts' : ''; + $enable = 'zend_extension' . $debug . $ts; + } + foreach ($ini[$search] as $line => $extension) { + if (in_array($extension, $binaries, true) || in_array( + $ini['extension_dir'] . DIRECTORY_SEPARATOR . $extension, $binaries, true)) { + // already enabled - assume if one is, all are + return true; + } + } + if ($line) { + $newini = array_slice($ini['all'], 0, $line); + } else { + $newini = array(); + } + foreach ($binaries as $binary) { + if ($ini['extension_dir']) { + $binary = basename($binary); + } + $newini[] = $enable . '="' . $binary . '"' . (OS_UNIX ? "\n" : "\r\n"); + } + $newini = array_merge($newini, array_slice($ini['all'], $line)); + $fp = @fopen($phpini, 'wb'); + if (!$fp) { + return PEAR::raiseError('cannot open php.ini "' . $phpini . '" for writing'); + } + foreach ($newini as $line) { + fwrite($fp, $line); + } + fclose($fp); + return true; + } + + function disableExtension($binaries, $type) + { + if (!($phpini = $this->config->get('php_ini', null, 'pear.php.net'))) { + return PEAR::raiseError('configuration option "php_ini" is not set to php.ini location'); + } + $ini = $this->_parseIni($phpini); + if (PEAR::isError($ini)) { + return $ini; + } + $line = 0; + if ($type == 'extsrc' || $type == 'extbin') { + $search = 'extensions'; + $enable = 'extension'; + } else { + $search = 'zend_extensions'; + ob_start(); + phpinfo(INFO_GENERAL); + $info = ob_get_contents(); + ob_end_clean(); + $debug = function_exists('leak') ? '_debug' : ''; + $ts = preg_match('/Thread Safety.+enabled/', $info) ? '_ts' : ''; + $enable = 'zend_extension' . $debug . $ts; + } + $found = false; + foreach ($ini[$search] as $line => $extension) { + if (in_array($extension, $binaries, true) || in_array( + $ini['extension_dir'] . DIRECTORY_SEPARATOR . $extension, $binaries, true)) { + $found = true; + break; + } + } + if (!$found) { + // not enabled + return true; + } + $fp = @fopen($phpini, 'wb'); + if (!$fp) { + return PEAR::raiseError('cannot open php.ini "' . $phpini . '" for writing'); + } + if ($line) { + $newini = array_slice($ini['all'], 0, $line); + // delete the enable line + $newini = array_merge($newini, array_slice($ini['all'], $line + 1)); + } else { + $newini = array_slice($ini['all'], 1); + } + foreach ($newini as $line) { + fwrite($fp, $line); + } + fclose($fp); + return true; + } + + function _parseIni($filename) + { + if (!file_exists($filename)) { + return PEAR::raiseError('php.ini "' . $filename . '" does not exist'); + } + + if (filesize($filename) > 300000) { + return PEAR::raiseError('php.ini "' . $filename . '" is too large, aborting'); + } + + ob_start(); + phpinfo(INFO_GENERAL); + $info = ob_get_contents(); + ob_end_clean(); + $debug = function_exists('leak') ? '_debug' : ''; + $ts = preg_match('/Thread Safety.+enabled/', $info) ? '_ts' : ''; + $zend_extension_line = 'zend_extension' . $debug . $ts; + $all = @file($filename); + if ($all === false) { + return PEAR::raiseError('php.ini "' . $filename .'" could not be read'); + } + $zend_extensions = $extensions = array(); + // assume this is right, but pull from the php.ini if it is found + $extension_dir = ini_get('extension_dir'); + foreach ($all as $linenum => $line) { + $line = trim($line); + if (!$line) { + continue; + } + if ($line[0] == ';') { + continue; + } + if (strtolower(substr($line, 0, 13)) == 'extension_dir') { + $line = trim(substr($line, 13)); + if ($line[0] == '=') { + $x = trim(substr($line, 1)); + $x = explode(';', $x); + $extension_dir = str_replace('"', '', array_shift($x)); + continue; + } + } + if (strtolower(substr($line, 0, 9)) == 'extension') { + $line = trim(substr($line, 9)); + if ($line[0] == '=') { + $x = trim(substr($line, 1)); + $x = explode(';', $x); + $extensions[$linenum] = str_replace('"', '', array_shift($x)); + continue; + } + } + if (strtolower(substr($line, 0, strlen($zend_extension_line))) == + $zend_extension_line) { + $line = trim(substr($line, strlen($zend_extension_line))); + if ($line[0] == '=') { + $x = trim(substr($line, 1)); + $x = explode(';', $x); + $zend_extensions[$linenum] = str_replace('"', '', array_shift($x)); + continue; + } + } + } + return array( + 'extensions' => $extensions, + 'zend_extensions' => $zend_extensions, + 'extension_dir' => $extension_dir, + 'all' => $all, + ); + } + + // {{{ doInstall() + + function doInstall($command, $options, $params) + { + if (!class_exists('PEAR_PackageFile')) { + require_once 'PEAR/PackageFile.php'; + } + + if (isset($options['installroot']) && isset($options['packagingroot'])) { + return $this->raiseError('ERROR: cannot use both --installroot and --packagingroot'); + } + + $reg = &$this->config->getRegistry(); + $channel = isset($options['channel']) ? $options['channel'] : $this->config->get('default_channel'); + if (!$reg->channelExists($channel)) { + return $this->raiseError('Channel "' . $channel . '" does not exist'); + } + + if (empty($this->installer)) { + $this->installer = &$this->getInstaller($this->ui); + } + + if ($command == 'upgrade' || $command == 'upgrade-all') { + // If people run the upgrade command but pass nothing, emulate a upgrade-all + if ($command == 'upgrade' && empty($params)) { + return $this->doUpgradeAll($command, $options, $params); + } + $options['upgrade'] = true; + } else { + $packages = $params; + } + + $instreg = &$reg; // instreg used to check if package is installed + if (isset($options['packagingroot']) && !isset($options['upgrade'])) { + $packrootphp_dir = $this->installer->_prependPath( + $this->config->get('php_dir', null, 'pear.php.net'), + $options['packagingroot']); + $metadata_dir = $this->config->get('metadata_dir', null, 'pear.php.net'); + if ($metadata_dir) { + $metadata_dir = $this->installer->_prependPath( + $metadata_dir, + $options['packagingroot']); + } + $instreg = new PEAR_Registry($packrootphp_dir, false, false, $metadata_dir); // other instreg! + + if ($this->config->get('verbose') > 2) { + $this->ui->outputData('using package root: ' . $options['packagingroot']); + } + } + + $abstractpackages = $otherpackages = array(); + // parse params + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + + foreach ($params as $param) { + if (strpos($param, 'http://') === 0) { + $otherpackages[] = $param; + continue; + } + + if (strpos($param, 'channel://') === false && @file_exists($param)) { + if (isset($options['force'])) { + $otherpackages[] = $param; + continue; + } + + $pkg = new PEAR_PackageFile($this->config); + $pf = $pkg->fromAnyFile($param, PEAR_VALIDATE_DOWNLOADING); + if (PEAR::isError($pf)) { + $otherpackages[] = $param; + continue; + } + + $exists = $reg->packageExists($pf->getPackage(), $pf->getChannel()); + $pversion = $reg->packageInfo($pf->getPackage(), 'version', $pf->getChannel()); + $version_compare = version_compare($pf->getVersion(), $pversion, '<='); + if ($exists && $version_compare) { + if ($this->config->get('verbose')) { + $this->ui->outputData('Ignoring installed package ' . + $reg->parsedPackageNameToString( + array('package' => $pf->getPackage(), + 'channel' => $pf->getChannel()), true)); + } + continue; + } + $otherpackages[] = $param; + continue; + } + + $e = $reg->parsePackageName($param, $channel); + if (PEAR::isError($e)) { + $otherpackages[] = $param; + } else { + $abstractpackages[] = $e; + } + } + PEAR::staticPopErrorHandling(); + + // if there are any local package .tgz or remote static url, we can't + // filter. The filter only works for abstract packages + if (count($abstractpackages) && !isset($options['force'])) { + // when not being forced, only do necessary upgrades/installs + if (isset($options['upgrade'])) { + $abstractpackages = $this->_filterUptodatePackages($abstractpackages, $command); + } else { + $count = count($abstractpackages); + foreach ($abstractpackages as $i => $package) { + if (isset($package['group'])) { + // do not filter out install groups + continue; + } + + if ($instreg->packageExists($package['package'], $package['channel'])) { + if ($count > 1) { + if ($this->config->get('verbose')) { + $this->ui->outputData('Ignoring installed package ' . + $reg->parsedPackageNameToString($package, true)); + } + unset($abstractpackages[$i]); + } elseif ($count === 1) { + // Lets try to upgrade it since it's already installed + $options['upgrade'] = true; + } + } + } + } + $abstractpackages = + array_map(array($reg, 'parsedPackageNameToString'), $abstractpackages); + } elseif (count($abstractpackages)) { + $abstractpackages = + array_map(array($reg, 'parsedPackageNameToString'), $abstractpackages); + } + + $packages = array_merge($abstractpackages, $otherpackages); + if (!count($packages)) { + $c = ''; + if (isset($options['channel'])){ + $c .= ' in channel "' . $options['channel'] . '"'; + } + $this->ui->outputData('Nothing to ' . $command . $c); + return true; + } + + $this->downloader = &$this->getDownloader($this->ui, $options, $this->config); + $errors = $downloaded = $binaries = array(); + $downloaded = &$this->downloader->download($packages); + if (PEAR::isError($downloaded)) { + return $this->raiseError($downloaded); + } + + $errors = $this->downloader->getErrorMsgs(); + if (count($errors)) { + $err = array(); + $err['data'] = array(); + foreach ($errors as $error) { + if ($error !== null) { + $err['data'][] = array($error); + } + } + + if (!empty($err['data'])) { + $err['headline'] = 'Install Errors'; + $this->ui->outputData($err); + } + + if (!count($downloaded)) { + return $this->raiseError("$command failed"); + } + } + + $data = array( + 'headline' => 'Packages that would be Installed' + ); + + if (isset($options['pretend'])) { + foreach ($downloaded as $package) { + $data['data'][] = array($reg->parsedPackageNameToString($package->getParsedPackage())); + } + $this->ui->outputData($data, 'pretend'); + return true; + } + + $this->installer->setOptions($options); + $this->installer->sortPackagesForInstall($downloaded); + if (PEAR::isError($err = $this->installer->setDownloadedPackages($downloaded))) { + $this->raiseError($err->getMessage()); + return true; + } + + $binaries = $extrainfo = array(); + foreach ($downloaded as $param) { + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $info = $this->installer->install($param, $options); + PEAR::staticPopErrorHandling(); + if (PEAR::isError($info)) { + $oldinfo = $info; + $pkg = &$param->getPackageFile(); + if ($info->getCode() != PEAR_INSTALLER_NOBINARY) { + if (!($info = $pkg->installBinary($this->installer))) { + $this->ui->outputData('ERROR: ' .$oldinfo->getMessage()); + continue; + } + + // we just installed a different package than requested, + // let's change the param and info so that the rest of this works + $param = $info[0]; + $info = $info[1]; + } + } + + if (!is_array($info)) { + return $this->raiseError("$command failed"); + } + + if ($param->getPackageType() == 'extsrc' || + $param->getPackageType() == 'extbin' || + $param->getPackageType() == 'zendextsrc' || + $param->getPackageType() == 'zendextbin' + ) { + $pkg = &$param->getPackageFile(); + if ($instbin = $pkg->getInstalledBinary()) { + $instpkg = &$instreg->getPackage($instbin, $pkg->getChannel()); + } else { + $instpkg = &$instreg->getPackage($pkg->getPackage(), $pkg->getChannel()); + } + + foreach ($instpkg->getFilelist() as $name => $atts) { + $pinfo = pathinfo($atts['installed_as']); + if (!isset($pinfo['extension']) || + in_array($pinfo['extension'], array('c', 'h')) + ) { + continue; // make sure we don't match php_blah.h + } + + if ((strpos($pinfo['basename'], 'php_') === 0 && + $pinfo['extension'] == 'dll') || + // most unices + $pinfo['extension'] == 'so' || + // hp-ux + $pinfo['extension'] == 'sl') { + $binaries[] = array($atts['installed_as'], $pinfo); + break; + } + } + + if (count($binaries)) { + foreach ($binaries as $pinfo) { + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $ret = $this->enableExtension(array($pinfo[0]), $param->getPackageType()); + PEAR::staticPopErrorHandling(); + if (PEAR::isError($ret)) { + $extrainfo[] = $ret->getMessage(); + if ($param->getPackageType() == 'extsrc' || + $param->getPackageType() == 'extbin') { + $exttype = 'extension'; + $extpath = $pinfo[1]['basename']; + } else { + $exttype = 'zend_extension'; + $extpath = $atts['installed_as']; + } + $extrainfo[] = 'You should add "' . $exttype . '=' . + $extpath . '" to php.ini'; + } else { + $extrainfo[] = 'Extension ' . $instpkg->getProvidesExtension() . + ' enabled in php.ini'; + } + } + } + } + + if ($this->config->get('verbose') > 0) { + $chan = $param->getChannel(); + $label = $reg->parsedPackageNameToString( + array( + 'channel' => $chan, + 'package' => $param->getPackage(), + 'version' => $param->getVersion(), + )); + $out = array('data' => "$command ok: $label"); + if (isset($info['release_warnings'])) { + $out['release_warnings'] = $info['release_warnings']; + } + $this->ui->outputData($out, $command); + + if (!isset($options['register-only']) && !isset($options['offline'])) { + if ($this->config->isDefinedLayer('ftp')) { + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $info = $this->installer->ftpInstall($param); + PEAR::staticPopErrorHandling(); + if (PEAR::isError($info)) { + $this->ui->outputData($info->getMessage()); + $this->ui->outputData("remote install failed: $label"); + } else { + $this->ui->outputData("remote install ok: $label"); + } + } + } + } + + $deps = $param->getDeps(); + if ($deps) { + if (isset($deps['group'])) { + $groups = $deps['group']; + if (!isset($groups[0])) { + $groups = array($groups); + } + + foreach ($groups as $group) { + if ($group['attribs']['name'] == 'default') { + // default group is always installed, unless the user + // explicitly chooses to install another group + continue; + } + $extrainfo[] = $param->getPackage() . ': Optional feature ' . + $group['attribs']['name'] . ' available (' . + $group['attribs']['hint'] . ')'; + } + + $extrainfo[] = $param->getPackage() . + ': To install optional features use "pear install ' . + $reg->parsedPackageNameToString( + array('package' => $param->getPackage(), + 'channel' => $param->getChannel()), true) . + '#featurename"'; + } + } + + $pkg = &$instreg->getPackage($param->getPackage(), $param->getChannel()); + // $pkg may be NULL if install is a 'fake' install via --packagingroot + if (is_object($pkg)) { + $pkg->setConfig($this->config); + if ($list = $pkg->listPostinstallScripts()) { + $pn = $reg->parsedPackageNameToString(array('channel' => + $param->getChannel(), 'package' => $param->getPackage()), true); + $extrainfo[] = $pn . ' has post-install scripts:'; + foreach ($list as $file) { + $extrainfo[] = $file; + } + $extrainfo[] = $param->getPackage() . + ': Use "pear run-scripts ' . $pn . '" to finish setup.'; + $extrainfo[] = 'DO NOT RUN SCRIPTS FROM UNTRUSTED SOURCES'; + } + } + } + + if (count($extrainfo)) { + foreach ($extrainfo as $info) { + $this->ui->outputData($info); + } + } + + return true; + } + + // }}} + // {{{ doUpgradeAll() + + function doUpgradeAll($command, $options, $params) + { + $reg = &$this->config->getRegistry(); + $upgrade = array(); + + if (isset($options['channel'])) { + $channels = array($options['channel']); + } else { + $channels = $reg->listChannels(); + } + + foreach ($channels as $channel) { + if ($channel == '__uri') { + continue; + } + + // parse name with channel + foreach ($reg->listPackages($channel) as $name) { + $upgrade[] = $reg->parsedPackageNameToString(array( + 'channel' => $channel, + 'package' => $name + )); + } + } + + $err = $this->doInstall($command, $options, $upgrade); + if (PEAR::isError($err)) { + $this->ui->outputData($err->getMessage(), $command); + } + } + + // }}} + // {{{ doUninstall() + + function doUninstall($command, $options, $params) + { + if (count($params) < 1) { + return $this->raiseError("Please supply the package(s) you want to uninstall"); + } + + if (empty($this->installer)) { + $this->installer = &$this->getInstaller($this->ui); + } + + if (isset($options['remoteconfig'])) { + $e = $this->config->readFTPConfigFile($options['remoteconfig']); + if (!PEAR::isError($e)) { + $this->installer->setConfig($this->config); + } + } + + $reg = &$this->config->getRegistry(); + $newparams = array(); + $binaries = array(); + $badparams = array(); + foreach ($params as $pkg) { + $channel = $this->config->get('default_channel'); + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $parsed = $reg->parsePackageName($pkg, $channel); + PEAR::staticPopErrorHandling(); + if (!$parsed || PEAR::isError($parsed)) { + $badparams[] = $pkg; + continue; + } + $package = $parsed['package']; + $channel = $parsed['channel']; + $info = &$reg->getPackage($package, $channel); + if ($info === null && + ($channel == 'pear.php.net' || $channel == 'pecl.php.net')) { + // make sure this isn't a package that has flipped from pear to pecl but + // used a package.xml 1.0 + $testc = ($channel == 'pear.php.net') ? 'pecl.php.net' : 'pear.php.net'; + $info = &$reg->getPackage($package, $testc); + if ($info !== null) { + $channel = $testc; + } + } + if ($info === null) { + $badparams[] = $pkg; + } else { + $newparams[] = &$info; + // check for binary packages (this is an alias for those packages if so) + if ($installedbinary = $info->getInstalledBinary()) { + $this->ui->log('adding binary package ' . + $reg->parsedPackageNameToString(array('channel' => $channel, + 'package' => $installedbinary), true)); + $newparams[] = &$reg->getPackage($installedbinary, $channel); + } + // add the contents of a dependency group to the list of installed packages + if (isset($parsed['group'])) { + $group = $info->getDependencyGroup($parsed['group']); + if ($group) { + $installed = $reg->getInstalledGroup($group); + if ($installed) { + foreach ($installed as $i => $p) { + $newparams[] = &$installed[$i]; + } + } + } + } + } + } + $err = $this->installer->sortPackagesForUninstall($newparams); + if (PEAR::isError($err)) { + $this->ui->outputData($err->getMessage(), $command); + return true; + } + $params = $newparams; + // twist this to use it to check on whether dependent packages are also being uninstalled + // for circular dependencies like subpackages + $this->installer->setUninstallPackages($newparams); + $params = array_merge($params, $badparams); + $binaries = array(); + foreach ($params as $pkg) { + $this->installer->pushErrorHandling(PEAR_ERROR_RETURN); + if ($err = $this->installer->uninstall($pkg, $options)) { + $this->installer->popErrorHandling(); + if (PEAR::isError($err)) { + $this->ui->outputData($err->getMessage(), $command); + continue; + } + if ($pkg->getPackageType() == 'extsrc' || + $pkg->getPackageType() == 'extbin' || + $pkg->getPackageType() == 'zendextsrc' || + $pkg->getPackageType() == 'zendextbin') { + if ($instbin = $pkg->getInstalledBinary()) { + continue; // this will be uninstalled later + } + + foreach ($pkg->getFilelist() as $name => $atts) { + $pinfo = pathinfo($atts['installed_as']); + if (!isset($pinfo['extension']) || + in_array($pinfo['extension'], array('c', 'h'))) { + continue; // make sure we don't match php_blah.h + } + if ((strpos($pinfo['basename'], 'php_') === 0 && + $pinfo['extension'] == 'dll') || + // most unices + $pinfo['extension'] == 'so' || + // hp-ux + $pinfo['extension'] == 'sl') { + $binaries[] = array($atts['installed_as'], $pinfo); + break; + } + } + if (count($binaries)) { + foreach ($binaries as $pinfo) { + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $ret = $this->disableExtension(array($pinfo[0]), $pkg->getPackageType()); + PEAR::staticPopErrorHandling(); + if (PEAR::isError($ret)) { + $extrainfo[] = $ret->getMessage(); + if ($pkg->getPackageType() == 'extsrc' || + $pkg->getPackageType() == 'extbin') { + $exttype = 'extension'; + } else { + ob_start(); + phpinfo(INFO_GENERAL); + $info = ob_get_contents(); + ob_end_clean(); + $debug = function_exists('leak') ? '_debug' : ''; + $ts = preg_match('/Thread Safety.+enabled/', $info) ? '_ts' : ''; + $exttype = 'zend_extension' . $debug . $ts; + } + $this->ui->outputData('Unable to remove "' . $exttype . '=' . + $pinfo[1]['basename'] . '" from php.ini', $command); + } else { + $this->ui->outputData('Extension ' . $pkg->getProvidesExtension() . + ' disabled in php.ini', $command); + } + } + } + } + $savepkg = $pkg; + if ($this->config->get('verbose') > 0) { + if (is_object($pkg)) { + $pkg = $reg->parsedPackageNameToString($pkg); + } + $this->ui->outputData("uninstall ok: $pkg", $command); + } + if (!isset($options['offline']) && is_object($savepkg) && + defined('PEAR_REMOTEINSTALL_OK')) { + if ($this->config->isDefinedLayer('ftp')) { + $this->installer->pushErrorHandling(PEAR_ERROR_RETURN); + $info = $this->installer->ftpUninstall($savepkg); + $this->installer->popErrorHandling(); + if (PEAR::isError($info)) { + $this->ui->outputData($info->getMessage()); + $this->ui->outputData("remote uninstall failed: $pkg"); + } else { + $this->ui->outputData("remote uninstall ok: $pkg"); + } + } + } + } else { + $this->installer->popErrorHandling(); + if (!is_object($pkg)) { + return $this->raiseError("uninstall failed: $pkg"); + } + $pkg = $reg->parsedPackageNameToString($pkg); + } + } + + return true; + } + + // }}} + + + // }}} + // {{{ doBundle() + /* + (cox) It just downloads and untars the package, does not do + any check that the PEAR_Installer::_installFile() does. + */ + + function doBundle($command, $options, $params) + { + $opts = array( + 'force' => true, + 'nodeps' => true, + 'soft' => true, + 'downloadonly' => true + ); + $downloader = &$this->getDownloader($this->ui, $opts, $this->config); + $reg = &$this->config->getRegistry(); + if (count($params) < 1) { + return $this->raiseError("Please supply the package you want to bundle"); + } + + if (isset($options['destination'])) { + if (!is_dir($options['destination'])) { + System::mkdir('-p ' . $options['destination']); + } + $dest = realpath($options['destination']); + } else { + $pwd = getcwd(); + $dir = $pwd . DIRECTORY_SEPARATOR . 'ext'; + $dest = is_dir($dir) ? $dir : $pwd; + } + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $err = $downloader->setDownloadDir($dest); + PEAR::staticPopErrorHandling(); + if (PEAR::isError($err)) { + return PEAR::raiseError('download directory "' . $dest . + '" is not writeable.'); + } + $result = &$downloader->download(array($params[0])); + if (PEAR::isError($result)) { + return $result; + } + if (!isset($result[0])) { + return $this->raiseError('unable to unpack ' . $params[0]); + } + $pkgfile = &$result[0]->getPackageFile(); + $pkgname = $pkgfile->getName(); + $pkgversion = $pkgfile->getVersion(); + + // Unpacking ------------------------------------------------- + $dest .= DIRECTORY_SEPARATOR . $pkgname; + $orig = $pkgname . '-' . $pkgversion; + + $tar = new Archive_Tar($pkgfile->getArchiveFile()); + if (!$tar->extractModify($dest, $orig)) { + return $this->raiseError('unable to unpack ' . $pkgfile->getArchiveFile()); + } + $this->ui->outputData("Package ready at '$dest'"); + // }}} + } + + // }}} + + function doRunScripts($command, $options, $params) + { + if (!isset($params[0])) { + return $this->raiseError('run-scripts expects 1 parameter: a package name'); + } + + $reg = &$this->config->getRegistry(); + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $parsed = $reg->parsePackageName($params[0], $this->config->get('default_channel')); + PEAR::staticPopErrorHandling(); + if (PEAR::isError($parsed)) { + return $this->raiseError($parsed); + } + + $package = &$reg->getPackage($parsed['package'], $parsed['channel']); + if (!is_object($package)) { + return $this->raiseError('Could not retrieve package "' . $params[0] . '" from registry'); + } + + $package->setConfig($this->config); + $package->runPostinstallScripts(); + $this->ui->outputData('Install scripts complete', $command); + return true; + } + + /** + * Given a list of packages, filter out those ones that are already up to date + * + * @param $packages: packages, in parsed array format ! + * @return list of packages that can be upgraded + */ + function _filterUptodatePackages($packages, $command) + { + $reg = &$this->config->getRegistry(); + $latestReleases = array(); + + $ret = array(); + foreach ($packages as $package) { + if (isset($package['group'])) { + $ret[] = $package; + continue; + } + + $channel = $package['channel']; + $name = $package['package']; + if (!$reg->packageExists($name, $channel)) { + $ret[] = $package; + continue; + } + + if (!isset($latestReleases[$channel])) { + // fill in cache for this channel + $chan = $reg->getChannel($channel); + if (PEAR::isError($chan)) { + return $this->raiseError($chan); + } + + $base2 = false; + $preferred_mirror = $this->config->get('preferred_mirror', null, $channel); + if ($chan->supportsREST($preferred_mirror) && + ( + //($base2 = $chan->getBaseURL('REST1.4', $preferred_mirror)) || + ($base = $chan->getBaseURL('REST1.0', $preferred_mirror)) + ) + ) { + $dorest = true; + } + + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + if (!isset($package['state'])) { + $state = $this->config->get('preferred_state', null, $channel); + } else { + $state = $package['state']; + } + + if ($dorest) { + if ($base2) { + $rest = &$this->config->getREST('1.4', array()); + $base = $base2; + } else { + $rest = &$this->config->getREST('1.0', array()); + } + + $installed = array_flip($reg->listPackages($channel)); + $latest = $rest->listLatestUpgrades($base, $state, $installed, $channel, $reg); + } + + PEAR::staticPopErrorHandling(); + if (PEAR::isError($latest)) { + $this->ui->outputData('Error getting channel info from ' . $channel . + ': ' . $latest->getMessage()); + continue; + } + + $latestReleases[$channel] = array_change_key_case($latest); + } + + // check package for latest release + $name_lower = strtolower($name); + if (isset($latestReleases[$channel][$name_lower])) { + // if not set, up to date + $inst_version = $reg->packageInfo($name, 'version', $channel); + $channel_version = $latestReleases[$channel][$name_lower]['version']; + if (version_compare($channel_version, $inst_version, 'le')) { + // installed version is up-to-date + continue; + } + + // maintain BC + if ($command == 'upgrade-all') { + $this->ui->outputData(array('data' => 'Will upgrade ' . + $reg->parsedPackageNameToString($package)), $command); + } + $ret[] = $package; + } + } + + return $ret; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Command/Mirror.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Command/Mirror.php new file mode 100644 index 0000000..bae7ad1 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Command/Mirror.php @@ -0,0 +1,138 @@ + + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.2.0 + */ + +/** + * base class + */ +require_once 'PEAR/Command/Common.php'; + +/** + * PEAR commands for providing file mirrors + * + * @category pear + * @package PEAR + * @author Alexander Merz + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.2.0 + */ +class PEAR_Command_Mirror extends PEAR_Command_Common +{ + var $commands = array( + 'download-all' => array( + 'summary' => 'Downloads each available package from the default channel', + 'function' => 'doDownloadAll', + 'shortcut' => 'da', + 'options' => array( + 'channel' => + array( + 'shortopt' => 'c', + 'doc' => 'specify a channel other than the default channel', + 'arg' => 'CHAN', + ), + ), + 'doc' => ' +Requests a list of available packages from the default channel ({config default_channel}) +and downloads them to current working directory. Note: only +packages within preferred_state ({config preferred_state}) will be downloaded' + ), + ); + + /** + * PEAR_Command_Mirror constructor. + * + * @access public + * @param object PEAR_Frontend a reference to an frontend + * @param object PEAR_Config a reference to the configuration data + */ + function __construct(&$ui, &$config) + { + parent::__construct($ui, $config); + } + + /** + * For unit-testing + */ + function &factory($a) + { + $a = &PEAR_Command::factory($a, $this->config); + return $a; + } + + /** + * retrieves a list of avaible Packages from master server + * and downloads them + * + * @access public + * @param string $command the command + * @param array $options the command options before the command + * @param array $params the stuff after the command name + * @return bool true if successful + * @throw PEAR_Error + */ + function doDownloadAll($command, $options, $params) + { + $savechannel = $this->config->get('default_channel'); + $reg = &$this->config->getRegistry(); + $channel = isset($options['channel']) ? $options['channel'] : + $this->config->get('default_channel'); + if (!$reg->channelExists($channel)) { + $this->config->set('default_channel', $savechannel); + return $this->raiseError('Channel "' . $channel . '" does not exist'); + } + $this->config->set('default_channel', $channel); + + $this->ui->outputData('Using Channel ' . $this->config->get('default_channel')); + $chan = $reg->getChannel($channel); + if (PEAR::isError($chan)) { + return $this->raiseError($chan); + } + + if ($chan->supportsREST($this->config->get('preferred_mirror')) && + $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) { + $rest = &$this->config->getREST('1.0', array()); + $remoteInfo = array_flip($rest->listPackages($base, $channel)); + } + + if (PEAR::isError($remoteInfo)) { + return $remoteInfo; + } + + $cmd = &$this->factory("download"); + if (PEAR::isError($cmd)) { + return $cmd; + } + + $this->ui->outputData('Using Preferred State of ' . + $this->config->get('preferred_state')); + $this->ui->outputData('Gathering release information, please wait...'); + + /** + * Error handling not necessary, because already done by + * the download command + */ + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $err = $cmd->run('download', array('downloadonly' => true), array_keys($remoteInfo)); + PEAR::staticPopErrorHandling(); + $this->config->set('default_channel', $savechannel); + if (PEAR::isError($err)) { + $this->ui->outputData($err->getMessage()); + } + + return true; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Command/Package.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Command/Package.php new file mode 100644 index 0000000..6904c01 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Command/Package.php @@ -0,0 +1,1123 @@ + + * @author Martin Jansen + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 0.1 + */ + +/** + * base class + */ +require_once 'PEAR/Command/Common.php'; + +/** + * PEAR commands for login/logout + * + * @category pear + * @package PEAR + * @author Stig Bakken + * @author Martin Jansen + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 0.1 + */ + +class PEAR_Command_Package extends PEAR_Command_Common +{ + var $commands = array( + 'package' => array( + 'summary' => 'Build Package', + 'function' => 'doPackage', + 'shortcut' => 'p', + 'options' => array( + 'nocompress' => array( + 'shortopt' => 'Z', + 'doc' => 'Do not gzip the package file' + ), + 'showname' => array( + 'shortopt' => 'n', + 'doc' => 'Print the name of the packaged file.', + ), + ), + 'doc' => '[descfile] [descfile2] +Creates a PEAR package from its description file (usually called +package.xml). If a second packagefile is passed in, then +the packager will check to make sure that one is a package.xml +version 1.0, and the other is a package.xml version 2.0. The +package.xml version 1.0 will be saved as "package.xml" in the archive, +and the other as "package2.xml" in the archive" +' + ), + 'package-validate' => array( + 'summary' => 'Validate Package Consistency', + 'function' => 'doPackageValidate', + 'shortcut' => 'pv', + 'options' => array(), + 'doc' => ' +', + ), + 'cvsdiff' => array( + 'summary' => 'Run a "cvs diff" for all files in a package', + 'function' => 'doCvsDiff', + 'shortcut' => 'cd', + 'options' => array( + 'quiet' => array( + 'shortopt' => 'q', + 'doc' => 'Be quiet', + ), + 'reallyquiet' => array( + 'shortopt' => 'Q', + 'doc' => 'Be really quiet', + ), + 'date' => array( + 'shortopt' => 'D', + 'doc' => 'Diff against revision of DATE', + 'arg' => 'DATE', + ), + 'release' => array( + 'shortopt' => 'R', + 'doc' => 'Diff against tag for package release REL', + 'arg' => 'REL', + ), + 'revision' => array( + 'shortopt' => 'r', + 'doc' => 'Diff against revision REV', + 'arg' => 'REV', + ), + 'context' => array( + 'shortopt' => 'c', + 'doc' => 'Generate context diff', + ), + 'unified' => array( + 'shortopt' => 'u', + 'doc' => 'Generate unified diff', + ), + 'ignore-case' => array( + 'shortopt' => 'i', + 'doc' => 'Ignore case, consider upper- and lower-case letters equivalent', + ), + 'ignore-whitespace' => array( + 'shortopt' => 'b', + 'doc' => 'Ignore changes in amount of white space', + ), + 'ignore-blank-lines' => array( + 'shortopt' => 'B', + 'doc' => 'Ignore changes that insert or delete blank lines', + ), + 'brief' => array( + 'doc' => 'Report only whether the files differ, no details', + ), + 'dry-run' => array( + 'shortopt' => 'n', + 'doc' => 'Don\'t do anything, just pretend', + ), + ), + 'doc' => ' +Compares all the files in a package. Without any options, this +command will compare the current code with the last checked-in code. +Using the -r or -R option you may compare the current code with that +of a specific release. +', + ), + 'svntag' => array( + 'summary' => 'Set SVN Release Tag', + 'function' => 'doSvnTag', + 'shortcut' => 'sv', + 'options' => array( + 'quiet' => array( + 'shortopt' => 'q', + 'doc' => 'Be quiet', + ), + 'slide' => array( + 'shortopt' => 'F', + 'doc' => 'Move (slide) tag if it exists', + ), + 'delete' => array( + 'shortopt' => 'd', + 'doc' => 'Remove tag', + ), + 'dry-run' => array( + 'shortopt' => 'n', + 'doc' => 'Don\'t do anything, just pretend', + ), + ), + 'doc' => ' [files...] + Sets a SVN tag on all files in a package. Use this command after you have + packaged a distribution tarball with the "package" command to tag what + revisions of what files were in that release. If need to fix something + after running svntag once, but before the tarball is released to the public, + use the "slide" option to move the release tag. + + to include files (such as a second package.xml, or tests not included in the + release), pass them as additional parameters. + ', + ), + 'cvstag' => array( + 'summary' => 'Set CVS Release Tag', + 'function' => 'doCvsTag', + 'shortcut' => 'ct', + 'options' => array( + 'quiet' => array( + 'shortopt' => 'q', + 'doc' => 'Be quiet', + ), + 'reallyquiet' => array( + 'shortopt' => 'Q', + 'doc' => 'Be really quiet', + ), + 'slide' => array( + 'shortopt' => 'F', + 'doc' => 'Move (slide) tag if it exists', + ), + 'delete' => array( + 'shortopt' => 'd', + 'doc' => 'Remove tag', + ), + 'dry-run' => array( + 'shortopt' => 'n', + 'doc' => 'Don\'t do anything, just pretend', + ), + ), + 'doc' => ' [files...] +Sets a CVS tag on all files in a package. Use this command after you have +packaged a distribution tarball with the "package" command to tag what +revisions of what files were in that release. If need to fix something +after running cvstag once, but before the tarball is released to the public, +use the "slide" option to move the release tag. + +to include files (such as a second package.xml, or tests not included in the +release), pass them as additional parameters. +', + ), + 'package-dependencies' => array( + 'summary' => 'Show package dependencies', + 'function' => 'doPackageDependencies', + 'shortcut' => 'pd', + 'options' => array(), + 'doc' => ' or or +List all dependencies the package has. +Can take a tgz / tar file, package.xml or a package name of an installed package.' + ), + 'sign' => array( + 'summary' => 'Sign a package distribution file', + 'function' => 'doSign', + 'shortcut' => 'si', + 'options' => array( + 'verbose' => array( + 'shortopt' => 'v', + 'doc' => 'Display GnuPG output', + ), + ), + 'doc' => ' +Signs a package distribution (.tar or .tgz) file with GnuPG.', + ), + 'makerpm' => array( + 'summary' => 'Builds an RPM spec file from a PEAR package', + 'function' => 'doMakeRPM', + 'shortcut' => 'rpm', + 'options' => array( + 'spec-template' => array( + 'shortopt' => 't', + 'arg' => 'FILE', + 'doc' => 'Use FILE as RPM spec file template' + ), + 'rpm-pkgname' => array( + 'shortopt' => 'p', + 'arg' => 'FORMAT', + 'doc' => 'Use FORMAT as format string for RPM package name, %s is replaced +by the PEAR package name, defaults to "PEAR::%s".', + ), + ), + 'doc' => ' + +Creates an RPM .spec file for wrapping a PEAR package inside an RPM +package. Intended to be used from the SPECS directory, with the PEAR +package tarball in the SOURCES directory: + +$ pear makerpm ../SOURCES/Net_Socket-1.0.tgz +Wrote RPM spec file PEAR::Net_Geo-1.0.spec +$ rpm -bb PEAR::Net_Socket-1.0.spec +... +Wrote: /usr/src/redhat/RPMS/i386/PEAR::Net_Socket-1.0-1.i386.rpm +', + ), + 'convert' => array( + 'summary' => 'Convert a package.xml 1.0 to package.xml 2.0 format', + 'function' => 'doConvert', + 'shortcut' => 'c2', + 'options' => array( + 'flat' => array( + 'shortopt' => 'f', + 'doc' => 'do not beautify the filelist.', + ), + ), + 'doc' => '[descfile] [descfile2] +Converts a package.xml in 1.0 format into a package.xml +in 2.0 format. The new file will be named package2.xml by default, +and package.xml will be used as the old file by default. +This is not the most intelligent conversion, and should only be +used for automated conversion or learning the format. +' + ), + ); + + var $output; + + /** + * PEAR_Command_Package constructor. + * + * @access public + */ + function __construct(&$ui, &$config) + { + parent::__construct($ui, $config); + } + + function _displayValidationResults($err, $warn, $strict = false) + { + foreach ($err as $e) { + $this->output .= "Error: $e\n"; + } + foreach ($warn as $w) { + $this->output .= "Warning: $w\n"; + } + $this->output .= sprintf('Validation: %d error(s), %d warning(s)'."\n", + sizeof($err), sizeof($warn)); + if ($strict && count($err) > 0) { + $this->output .= "Fix these errors and try again."; + return false; + } + return true; + } + + function &getPackager() + { + if (!class_exists('PEAR_Packager')) { + require_once 'PEAR/Packager.php'; + } + $a = new PEAR_Packager; + return $a; + } + + function &getPackageFile($config, $debug = false) + { + if (!class_exists('PEAR_Common')) { + require_once 'PEAR/Common.php'; + } + if (!class_exists('PEAR_PackageFile')) { + require_once 'PEAR/PackageFile.php'; + } + $a = new PEAR_PackageFile($config, $debug); + $common = new PEAR_Common; + $common->ui = $this->ui; + $a->setLogger($common); + return $a; + } + + function doPackage($command, $options, $params) + { + $this->output = ''; + $pkginfofile = isset($params[0]) ? $params[0] : 'package.xml'; + $pkg2 = isset($params[1]) ? $params[1] : null; + if (!$pkg2 && !isset($params[0]) && file_exists('package2.xml')) { + $pkg2 = 'package2.xml'; + } + + $packager = &$this->getPackager(); + $compress = empty($options['nocompress']) ? true : false; + $result = $packager->package($pkginfofile, $compress, $pkg2); + if (PEAR::isError($result)) { + return $this->raiseError($result); + } + + // Don't want output, only the package file name just created + if (isset($options['showname'])) { + $this->output = $result; + } + + if ($this->output) { + $this->ui->outputData($this->output, $command); + } + + return true; + } + + function doPackageValidate($command, $options, $params) + { + $this->output = ''; + if (count($params) < 1) { + $params[0] = 'package.xml'; + } + + $obj = &$this->getPackageFile($this->config, $this->_debug); + $obj->rawReturn(); + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $info = $obj->fromTgzFile($params[0], PEAR_VALIDATE_NORMAL); + if (PEAR::isError($info)) { + $info = $obj->fromPackageFile($params[0], PEAR_VALIDATE_NORMAL); + } else { + $archive = $info->getArchiveFile(); + $tar = new Archive_Tar($archive); + $tar->extract(dirname($info->getPackageFile())); + $info->setPackageFile(dirname($info->getPackageFile()) . DIRECTORY_SEPARATOR . + $info->getPackage() . '-' . $info->getVersion() . DIRECTORY_SEPARATOR . + basename($info->getPackageFile())); + } + + PEAR::staticPopErrorHandling(); + if (PEAR::isError($info)) { + return $this->raiseError($info); + } + + $valid = false; + if ($info->getPackagexmlVersion() == '2.0') { + if ($valid = $info->validate(PEAR_VALIDATE_NORMAL)) { + $info->flattenFileList(); + $valid = $info->validate(PEAR_VALIDATE_PACKAGING); + } + } else { + $valid = $info->validate(PEAR_VALIDATE_PACKAGING); + } + + $err = $warn = array(); + if ($errors = $info->getValidationWarnings()) { + foreach ($errors as $error) { + if ($error['level'] == 'warning') { + $warn[] = $error['message']; + } else { + $err[] = $error['message']; + } + } + } + + $this->_displayValidationResults($err, $warn); + $this->ui->outputData($this->output, $command); + return true; + } + + function doSvnTag($command, $options, $params) + { + $this->output = ''; + $_cmd = $command; + if (count($params) < 1) { + $help = $this->getHelp($command); + return $this->raiseError("$command: missing parameter: $help[0]"); + } + + $packageFile = realpath($params[0]); + $dir = dirname($packageFile); + $dir = substr($dir, strrpos($dir, DIRECTORY_SEPARATOR) + 1); + $obj = &$this->getPackageFile($this->config, $this->_debug); + $info = $obj->fromAnyFile($packageFile, PEAR_VALIDATE_NORMAL); + if (PEAR::isError($info)) { + return $this->raiseError($info); + } + + $err = $warn = array(); + if (!$info->validate()) { + foreach ($info->getValidationWarnings() as $error) { + if ($error['level'] == 'warning') { + $warn[] = $error['message']; + } else { + $err[] = $error['message']; + } + } + } + + if (!$this->_displayValidationResults($err, $warn, true)) { + $this->ui->outputData($this->output, $command); + return $this->raiseError('SVN tag failed'); + } + + $version = $info->getVersion(); + $package = $info->getName(); + $svntag = "$package-$version"; + + if (isset($options['delete'])) { + return $this->_svnRemoveTag($version, $package, $svntag, $packageFile, $options); + } + + $path = $this->_svnFindPath($packageFile); + + // Check if there are any modified files + $fp = popen('svn st --xml ' . dirname($packageFile), "r"); + $out = ''; + while ($line = fgets($fp, 1024)) { + $out .= rtrim($line)."\n"; + } + pclose($fp); + + if (!isset($options['quiet']) && strpos($out, 'item="modified"')) { + $params = array(array( + 'name' => 'modified', + 'type' => 'yesno', + 'default' => 'no', + 'prompt' => 'You have files in your SVN checkout (' . $path['from'] . ') that have been modified but not committed, do you still want to tag ' . $version . '?', + )); + $answers = $this->ui->confirmDialog($params); + + if (!in_array($answers['modified'], array('y', 'yes', 'on', '1'))) { + return true; + } + } + + if (isset($options['slide'])) { + $this->_svnRemoveTag($version, $package, $svntag, $packageFile, $options); + } + + // Check if tag already exists + $releaseTag = $path['local']['base'] . 'tags' . DIRECTORY_SEPARATOR . $svntag; + $existsCommand = 'svn ls ' . $path['base'] . 'tags/'; + + $fp = popen($existsCommand, "r"); + $out = ''; + while ($line = fgets($fp, 1024)) { + $out .= rtrim($line)."\n"; + } + pclose($fp); + + if (in_array($svntag . DIRECTORY_SEPARATOR, explode("\n", $out))) { + $this->ui->outputData($this->output, $command); + return $this->raiseError('SVN tag ' . $svntag . ' for ' . $package . ' already exists.'); + } elseif (file_exists($path['local']['base'] . 'tags') === false) { + return $this->raiseError('Can not locate the tags directory at ' . $path['local']['base'] . 'tags'); + } elseif (is_writeable($path['local']['base'] . 'tags') === false) { + return $this->raiseError('Can not write to the tag directory at ' . $path['local']['base'] . 'tags'); + } else { + $makeCommand = 'svn mkdir ' . $releaseTag; + $this->output .= "+ $makeCommand\n"; + if (empty($options['dry-run'])) { + // We need to create the tag dir. + $fp = popen($makeCommand, "r"); + $out = ''; + while ($line = fgets($fp, 1024)) { + $out .= rtrim($line)."\n"; + } + pclose($fp); + $this->output .= "$out\n"; + } + } + + $command = 'svn'; + if (isset($options['quiet'])) { + $command .= ' -q'; + } + + $command .= ' copy --parents '; + + $dir = dirname($packageFile); + $dir = substr($dir, strrpos($dir, DIRECTORY_SEPARATOR) + 1); + $files = array_keys($info->getFilelist()); + if (!in_array(basename($packageFile), $files)) { + $files[] = basename($packageFile); + } + + array_shift($params); + if (count($params)) { + // add in additional files to be tagged (package files and such) + $files = array_merge($files, $params); + } + + $commands = array(); + foreach ($files as $file) { + if (!file_exists($file)) { + $file = $dir . DIRECTORY_SEPARATOR . $file; + } + $commands[] = $command . ' ' . escapeshellarg($file) . ' ' . + escapeshellarg($releaseTag . DIRECTORY_SEPARATOR . $file); + } + + $this->output .= implode("\n", $commands) . "\n"; + if (empty($options['dry-run'])) { + foreach ($commands as $command) { + $fp = popen($command, "r"); + while ($line = fgets($fp, 1024)) { + $this->output .= rtrim($line)."\n"; + } + pclose($fp); + } + } + + $command = 'svn ci -m "Tagging the ' . $version . ' release" ' . $releaseTag . "\n"; + $this->output .= "+ $command\n"; + if (empty($options['dry-run'])) { + $fp = popen($command, "r"); + while ($line = fgets($fp, 1024)) { + $this->output .= rtrim($line)."\n"; + } + pclose($fp); + } + + $this->ui->outputData($this->output, $_cmd); + return true; + } + + function _svnFindPath($file) + { + $xml = ''; + $command = "svn info --xml $file"; + $fp = popen($command, "r"); + while ($line = fgets($fp, 1024)) { + $xml .= rtrim($line)."\n"; + } + pclose($fp); + $url_tag = strpos($xml, ''); + $url = substr($xml, $url_tag + 5, strpos($xml, '', $url_tag + 5) - ($url_tag + 5)); + + $path = array(); + $path['from'] = substr($url, 0, strrpos($url, '/')); + $path['base'] = substr($path['from'], 0, strrpos($path['from'], '/') + 1); + + // Figure out the local paths - see http://pear.php.net/bugs/17463 + $pos = strpos($file, DIRECTORY_SEPARATOR . 'trunk' . DIRECTORY_SEPARATOR); + if ($pos === false) { + $pos = strpos($file, DIRECTORY_SEPARATOR . 'branches' . DIRECTORY_SEPARATOR); + } + $path['local']['base'] = substr($file, 0, $pos + 1); + + return $path; + } + + function _svnRemoveTag($version, $package, $tag, $packageFile, $options) + { + $command = 'svn'; + + if (isset($options['quiet'])) { + $command .= ' -q'; + } + + $command .= ' remove'; + $command .= ' -m "Removing tag for the ' . $version . ' release."'; + + $path = $this->_svnFindPath($packageFile); + $command .= ' ' . $path['base'] . 'tags/' . $tag; + + + if ($this->config->get('verbose') > 1) { + $this->output .= "+ $command\n"; + } + + $this->output .= "+ $command\n"; + if (empty($options['dry-run'])) { + $fp = popen($command, "r"); + while ($line = fgets($fp, 1024)) { + $this->output .= rtrim($line)."\n"; + } + pclose($fp); + } + + $this->ui->outputData($this->output, $command); + return true; + } + + function doCvsTag($command, $options, $params) + { + $this->output = ''; + $_cmd = $command; + if (count($params) < 1) { + $help = $this->getHelp($command); + return $this->raiseError("$command: missing parameter: $help[0]"); + } + + $packageFile = realpath($params[0]); + $obj = &$this->getPackageFile($this->config, $this->_debug); + $info = $obj->fromAnyFile($packageFile, PEAR_VALIDATE_NORMAL); + if (PEAR::isError($info)) { + return $this->raiseError($info); + } + + $err = $warn = array(); + if (!$info->validate()) { + foreach ($info->getValidationWarnings() as $error) { + if ($error['level'] == 'warning') { + $warn[] = $error['message']; + } else { + $err[] = $error['message']; + } + } + } + + if (!$this->_displayValidationResults($err, $warn, true)) { + $this->ui->outputData($this->output, $command); + return $this->raiseError('CVS tag failed'); + } + + $version = $info->getVersion(); + $cvsversion = preg_replace('/[^a-z0-9]/i', '_', $version); + $cvstag = "RELEASE_$cvsversion"; + $files = array_keys($info->getFilelist()); + $command = 'cvs'; + if (isset($options['quiet'])) { + $command .= ' -q'; + } + + if (isset($options['reallyquiet'])) { + $command .= ' -Q'; + } + + $command .= ' tag'; + if (isset($options['slide'])) { + $command .= ' -F'; + } + + if (isset($options['delete'])) { + $command .= ' -d'; + } + + $command .= ' ' . $cvstag . ' ' . escapeshellarg($params[0]); + array_shift($params); + if (count($params)) { + // add in additional files to be tagged + $files = array_merge($files, $params); + } + + $dir = dirname($packageFile); + $dir = substr($dir, strrpos($dir, '/') + 1); + foreach ($files as $file) { + if (!file_exists($file)) { + $file = $dir . DIRECTORY_SEPARATOR . $file; + } + $command .= ' ' . escapeshellarg($file); + } + + if ($this->config->get('verbose') > 1) { + $this->output .= "+ $command\n"; + } + + $this->output .= "+ $command\n"; + if (empty($options['dry-run'])) { + $fp = popen($command, "r"); + while ($line = fgets($fp, 1024)) { + $this->output .= rtrim($line)."\n"; + } + pclose($fp); + } + + $this->ui->outputData($this->output, $_cmd); + return true; + } + + function doCvsDiff($command, $options, $params) + { + $this->output = ''; + if (sizeof($params) < 1) { + $help = $this->getHelp($command); + return $this->raiseError("$command: missing parameter: $help[0]"); + } + + $file = realpath($params[0]); + $obj = &$this->getPackageFile($this->config, $this->_debug); + $info = $obj->fromAnyFile($file, PEAR_VALIDATE_NORMAL); + if (PEAR::isError($info)) { + return $this->raiseError($info); + } + + $err = $warn = array(); + if (!$info->validate()) { + foreach ($info->getValidationWarnings() as $error) { + if ($error['level'] == 'warning') { + $warn[] = $error['message']; + } else { + $err[] = $error['message']; + } + } + } + + if (!$this->_displayValidationResults($err, $warn, true)) { + $this->ui->outputData($this->output, $command); + return $this->raiseError('CVS diff failed'); + } + + $info1 = $info->getFilelist(); + $files = $info1; + $cmd = "cvs"; + if (isset($options['quiet'])) { + $cmd .= ' -q'; + unset($options['quiet']); + } + + if (isset($options['reallyquiet'])) { + $cmd .= ' -Q'; + unset($options['reallyquiet']); + } + + if (isset($options['release'])) { + $cvsversion = preg_replace('/[^a-z0-9]/i', '_', $options['release']); + $cvstag = "RELEASE_$cvsversion"; + $options['revision'] = $cvstag; + unset($options['release']); + } + + $execute = true; + if (isset($options['dry-run'])) { + $execute = false; + unset($options['dry-run']); + } + + $cmd .= ' diff'; + // the rest of the options are passed right on to "cvs diff" + foreach ($options as $option => $optarg) { + $arg = $short = false; + if (isset($this->commands[$command]['options'][$option])) { + $arg = $this->commands[$command]['options'][$option]['arg']; + $short = $this->commands[$command]['options'][$option]['shortopt']; + } + $cmd .= $short ? " -$short" : " --$option"; + if ($arg && $optarg) { + $cmd .= ($short ? '' : '=') . escapeshellarg($optarg); + } + } + + foreach ($files as $file) { + $cmd .= ' ' . escapeshellarg($file['name']); + } + + if ($this->config->get('verbose') > 1) { + $this->output .= "+ $cmd\n"; + } + + if ($execute) { + $fp = popen($cmd, "r"); + while ($line = fgets($fp, 1024)) { + $this->output .= rtrim($line)."\n"; + } + pclose($fp); + } + + $this->ui->outputData($this->output, $command); + return true; + } + + function doPackageDependencies($command, $options, $params) + { + // $params[0] -> the PEAR package to list its information + if (count($params) !== 1) { + return $this->raiseError("bad parameter(s), try \"help $command\""); + } + + $obj = &$this->getPackageFile($this->config, $this->_debug); + if (is_file($params[0]) || strpos($params[0], '.xml') > 0) { + $info = $obj->fromAnyFile($params[0], PEAR_VALIDATE_NORMAL); + } else { + $reg = $this->config->getRegistry(); + $info = $obj->fromArray($reg->packageInfo($params[0])); + } + + if (PEAR::isError($info)) { + return $this->raiseError($info); + } + + $deps = $info->getDeps(); + if (is_array($deps)) { + if ($info->getPackagexmlVersion() == '1.0') { + $data = array( + 'caption' => 'Dependencies for pear/' . $info->getPackage(), + 'border' => true, + 'headline' => array("Required?", "Type", "Name", "Relation", "Version"), + ); + + foreach ($deps as $d) { + if (isset($d['optional'])) { + if ($d['optional'] == 'yes') { + $req = 'No'; + } else { + $req = 'Yes'; + } + } else { + $req = 'Yes'; + } + + if (isset($this->_deps_rel_trans[$d['rel']])) { + $rel = $this->_deps_rel_trans[$d['rel']]; + } else { + $rel = $d['rel']; + } + + if (isset($this->_deps_type_trans[$d['type']])) { + $type = ucfirst($this->_deps_type_trans[$d['type']]); + } else { + $type = $d['type']; + } + + if (isset($d['name'])) { + $name = $d['name']; + } else { + $name = ''; + } + + if (isset($d['version'])) { + $version = $d['version']; + } else { + $version = ''; + } + + $data['data'][] = array($req, $type, $name, $rel, $version); + } + } else { // package.xml 2.0 dependencies display + require_once 'PEAR/Dependency2.php'; + $deps = $info->getDependencies(); + $reg = &$this->config->getRegistry(); + if (is_array($deps)) { + $d = new PEAR_Dependency2($this->config, array(), ''); + $data = array( + 'caption' => 'Dependencies for ' . $info->getPackage(), + 'border' => true, + 'headline' => array("Required?", "Type", "Name", 'Versioning', 'Group'), + ); + foreach ($deps as $type => $subd) { + $req = ($type == 'required') ? 'Yes' : 'No'; + if ($type == 'group' && isset($subd['attribs']['name'])) { + $group = $subd['attribs']['name']; + } else { + $group = ''; + } + + if (!isset($subd[0])) { + $subd = array($subd); + } + + foreach ($subd as $groupa) { + foreach ($groupa as $deptype => $depinfo) { + if ($deptype == 'attribs') { + continue; + } + + if ($deptype == 'pearinstaller') { + $deptype = 'pear Installer'; + } + + if (!isset($depinfo[0])) { + $depinfo = array($depinfo); + } + + foreach ($depinfo as $inf) { + $name = ''; + if (isset($inf['channel'])) { + $alias = $reg->channelAlias($inf['channel']); + if (!$alias) { + $alias = '(channel?) ' .$inf['channel']; + } + $name = $alias . '/'; + + } + if (isset($inf['name'])) { + $name .= $inf['name']; + } elseif (isset($inf['pattern'])) { + $name .= $inf['pattern']; + } else { + $name .= ''; + } + + if (isset($inf['uri'])) { + $name .= ' [' . $inf['uri'] . ']'; + } + + if (isset($inf['conflicts'])) { + $ver = 'conflicts'; + } else { + $ver = $d->_getExtraString($inf); + } + + $data['data'][] = array($req, ucfirst($deptype), $name, + $ver, $group); + } + } + } + } + } + } + + $this->ui->outputData($data, $command); + return true; + } + + // Fallback + $this->ui->outputData("This package does not have any dependencies.", $command); + } + + function doSign($command, $options, $params) + { + // should move most of this code into PEAR_Packager + // so it'll be easy to implement "pear package --sign" + if (count($params) !== 1) { + return $this->raiseError("bad parameter(s), try \"help $command\""); + } + + require_once 'System.php'; + require_once 'Archive/Tar.php'; + + if (!file_exists($params[0])) { + return $this->raiseError("file does not exist: $params[0]"); + } + + $obj = $this->getPackageFile($this->config, $this->_debug); + $info = $obj->fromTgzFile($params[0], PEAR_VALIDATE_NORMAL); + if (PEAR::isError($info)) { + return $this->raiseError($info); + } + + $tar = new Archive_Tar($params[0]); + + $tmpdir = $this->config->get('temp_dir'); + $tmpdir = System::mktemp(' -t "' . $tmpdir . '" -d pearsign'); + if (!$tar->extractList('package2.xml package.xml package.sig', $tmpdir)) { + return $this->raiseError("failed to extract tar file"); + } + + if (file_exists("$tmpdir/package.sig")) { + return $this->raiseError("package already signed"); + } + + $packagexml = 'package.xml'; + if (file_exists("$tmpdir/package2.xml")) { + $packagexml = 'package2.xml'; + } + + if (file_exists("$tmpdir/package.sig")) { + unlink("$tmpdir/package.sig"); + } + + if (!file_exists("$tmpdir/$packagexml")) { + return $this->raiseError("Extracted file $tmpdir/$packagexml not found."); + } + + $input = $this->ui->userDialog($command, + array('GnuPG Passphrase'), + array('password')); + if (!isset($input[0])) { + //use empty passphrase + $input[0] = ''; + } + + $devnull = (isset($options['verbose'])) ? '' : ' 2>/dev/null'; + $gpg = popen("gpg --batch --passphrase-fd 0 --armor --detach-sign --output $tmpdir/package.sig $tmpdir/$packagexml" . $devnull, "w"); + if (!$gpg) { + return $this->raiseError("gpg command failed"); + } + + fwrite($gpg, "$input[0]\n"); + if (pclose($gpg) || !file_exists("$tmpdir/package.sig")) { + return $this->raiseError("gpg sign failed"); + } + + if (!$tar->addModify("$tmpdir/package.sig", '', $tmpdir)) { + return $this->raiseError('failed adding signature to file'); + } + + $this->ui->outputData("Package signed.", $command); + return true; + } + + /** + * For unit testing purposes + */ + function &getInstaller(&$ui) + { + if (!class_exists('PEAR_Installer')) { + require_once 'PEAR/Installer.php'; + } + $a = new PEAR_Installer($ui); + return $a; + } + + /** + * For unit testing purposes + */ + function &getCommandPackaging(&$ui, &$config) + { + if (!class_exists('PEAR_Command_Packaging')) { + if ($fp = @fopen('PEAR/Command/Packaging.php', 'r', true)) { + fclose($fp); + include_once 'PEAR/Command/Packaging.php'; + } + } + + if (class_exists('PEAR_Command_Packaging')) { + $a = new PEAR_Command_Packaging($ui, $config); + } else { + $a = null; + } + + return $a; + } + + function doMakeRPM($command, $options, $params) + { + + // Check to see if PEAR_Command_Packaging is installed, and + // transparently switch to use the "make-rpm-spec" command from it + // instead, if it does. Otherwise, continue to use the old version + // of "makerpm" supplied with this package (PEAR). + $packaging_cmd = $this->getCommandPackaging($this->ui, $this->config); + if ($packaging_cmd !== null) { + $this->ui->outputData('PEAR_Command_Packaging is installed; using '. + 'newer "make-rpm-spec" command instead'); + return $packaging_cmd->run('make-rpm-spec', $options, $params); + } + + $this->ui->outputData('WARNING: "pear makerpm" is no longer available; an '. + 'improved version is available via "pear make-rpm-spec", which '. + 'is available by installing PEAR_Command_Packaging'); + return true; + } + + function doConvert($command, $options, $params) + { + $packagexml = isset($params[0]) ? $params[0] : 'package.xml'; + $newpackagexml = isset($params[1]) ? $params[1] : dirname($packagexml) . + DIRECTORY_SEPARATOR . 'package2.xml'; + $pkg = &$this->getPackageFile($this->config, $this->_debug); + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $pf = $pkg->fromPackageFile($packagexml, PEAR_VALIDATE_NORMAL); + PEAR::staticPopErrorHandling(); + if (PEAR::isError($pf)) { + if (is_array($pf->getUserInfo())) { + foreach ($pf->getUserInfo() as $warning) { + $this->ui->outputData($warning['message']); + } + } + return $this->raiseError($pf); + } + + if (is_a($pf, 'PEAR_PackageFile_v2')) { + $this->ui->outputData($packagexml . ' is already a package.xml version 2.0'); + return true; + } + + $gen = &$pf->getDefaultGenerator(); + $newpf = &$gen->toV2(); + $newpf->setPackagefile($newpackagexml); + $gen = &$newpf->getDefaultGenerator(); + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $state = (isset($options['flat']) ? PEAR_VALIDATE_PACKAGING : PEAR_VALIDATE_NORMAL); + $saved = $gen->toPackageFile(dirname($newpackagexml), $state, basename($newpackagexml)); + PEAR::staticPopErrorHandling(); + if (PEAR::isError($saved)) { + if (is_array($saved->getUserInfo())) { + foreach ($saved->getUserInfo() as $warning) { + $this->ui->outputData($warning['message']); + } + } + + $this->ui->outputData($saved->getMessage()); + return true; + } + + $this->ui->outputData('Wrote new version 2.0 package.xml to "' . $saved . '"'); + return true; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Command/Pickle.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Command/Pickle.php new file mode 100644 index 0000000..af6079b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Command/Pickle.php @@ -0,0 +1,420 @@ + + * @copyright 2005-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.1 + */ + +/** + * base class + */ +require_once 'PEAR/Command/Common.php'; + +/** + * PEAR commands for login/logout + * + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 2005-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.1 + */ + +class PEAR_Command_Pickle extends PEAR_Command_Common +{ + var $commands = array( + 'pickle' => array( + 'summary' => 'Build PECL Package', + 'function' => 'doPackage', + 'shortcut' => 'pi', + 'options' => array( + 'nocompress' => array( + 'shortopt' => 'Z', + 'doc' => 'Do not gzip the package file' + ), + 'showname' => array( + 'shortopt' => 'n', + 'doc' => 'Print the name of the packaged file.', + ), + ), + 'doc' => '[descfile] +Creates a PECL package from its package2.xml file. + +An automatic conversion will be made to a package.xml 1.0 and written out to +disk in the current directory as "package.xml". Note that +only simple package.xml 2.0 will be converted. package.xml 2.0 with: + + - dependency types other than required/optional PECL package/ext/php/pearinstaller + - more than one extsrcrelease or zendextsrcrelease + - zendextbinrelease, extbinrelease, phprelease, or bundle release type + - dependency groups + - ignore tags in release filelist + - tasks other than replace + - custom roles + +will cause pickle to fail, and output an error message. If your package2.xml +uses any of these features, you are best off using PEAR_PackageFileManager to +generate both package.xml. +' + ), + ); + + /** + * PEAR_Command_Package constructor. + * + * @access public + */ + function __construct(&$ui, &$config) + { + parent::__construct($ui, $config); + } + + /** + * For unit-testing ease + * + * @return PEAR_Packager + */ + function &getPackager() + { + if (!class_exists('PEAR_Packager')) { + require_once 'PEAR/Packager.php'; + } + + $a = new PEAR_Packager; + return $a; + } + + /** + * For unit-testing ease + * + * @param PEAR_Config $config + * @param bool $debug + * @param string|null $tmpdir + * @return PEAR_PackageFile + */ + function &getPackageFile($config, $debug = false) + { + if (!class_exists('PEAR_Common')) { + require_once 'PEAR/Common.php'; + } + + if (!class_exists('PEAR_PackageFile')) { + require_once 'PEAR/PackageFile.php'; + } + + $a = new PEAR_PackageFile($config, $debug); + $common = new PEAR_Common; + $common->ui = $this->ui; + $a->setLogger($common); + return $a; + } + + function doPackage($command, $options, $params) + { + $this->output = ''; + $pkginfofile = isset($params[0]) ? $params[0] : 'package2.xml'; + $packager = &$this->getPackager(); + if (PEAR::isError($err = $this->_convertPackage($pkginfofile))) { + return $err; + } + + $compress = empty($options['nocompress']) ? true : false; + $result = $packager->package($pkginfofile, $compress, 'package.xml'); + if (PEAR::isError($result)) { + return $this->raiseError($result); + } + + // Don't want output, only the package file name just created + if (isset($options['showname'])) { + $this->ui->outputData($result, $command); + } + + return true; + } + + function _convertPackage($packagexml) + { + $pkg = &$this->getPackageFile($this->config); + $pf2 = &$pkg->fromPackageFile($packagexml, PEAR_VALIDATE_NORMAL); + if (!is_a($pf2, 'PEAR_PackageFile_v2')) { + return $this->raiseError('Cannot process "' . + $packagexml . '", is not a package.xml 2.0'); + } + + require_once 'PEAR/PackageFile/v1.php'; + $pf = new PEAR_PackageFile_v1; + $pf->setConfig($this->config); + if ($pf2->getPackageType() != 'extsrc' && $pf2->getPackageType() != 'zendextsrc') { + return $this->raiseError('Cannot safely convert "' . $packagexml . + '", is not an extension source package. Using a PEAR_PackageFileManager-based ' . + 'script is an option'); + } + + if (is_array($pf2->getUsesRole())) { + return $this->raiseError('Cannot safely convert "' . $packagexml . + '", contains custom roles. Using a PEAR_PackageFileManager-based script or ' . + 'the convert command is an option'); + } + + if (is_array($pf2->getUsesTask())) { + return $this->raiseError('Cannot safely convert "' . $packagexml . + '", contains custom tasks. Using a PEAR_PackageFileManager-based script or ' . + 'the convert command is an option'); + } + + $deps = $pf2->getDependencies(); + if (isset($deps['group'])) { + return $this->raiseError('Cannot safely convert "' . $packagexml . + '", contains dependency groups. Using a PEAR_PackageFileManager-based script ' . + 'or the convert command is an option'); + } + + if (isset($deps['required']['subpackage']) || + isset($deps['optional']['subpackage'])) { + return $this->raiseError('Cannot safely convert "' . $packagexml . + '", contains subpackage dependencies. Using a PEAR_PackageFileManager-based '. + 'script is an option'); + } + + if (isset($deps['required']['os'])) { + return $this->raiseError('Cannot safely convert "' . $packagexml . + '", contains os dependencies. Using a PEAR_PackageFileManager-based '. + 'script is an option'); + } + + if (isset($deps['required']['arch'])) { + return $this->raiseError('Cannot safely convert "' . $packagexml . + '", contains arch dependencies. Using a PEAR_PackageFileManager-based '. + 'script is an option'); + } + + $pf->setPackage($pf2->getPackage()); + $pf->setSummary($pf2->getSummary()); + $pf->setDescription($pf2->getDescription()); + foreach ($pf2->getMaintainers() as $maintainer) { + $pf->addMaintainer($maintainer['role'], $maintainer['handle'], + $maintainer['name'], $maintainer['email']); + } + + $pf->setVersion($pf2->getVersion()); + $pf->setDate($pf2->getDate()); + $pf->setLicense($pf2->getLicense()); + $pf->setState($pf2->getState()); + $pf->setNotes($pf2->getNotes()); + $pf->addPhpDep($deps['required']['php']['min'], 'ge'); + if (isset($deps['required']['php']['max'])) { + $pf->addPhpDep($deps['required']['php']['max'], 'le'); + } + + if (isset($deps['required']['package'])) { + if (!isset($deps['required']['package'][0])) { + $deps['required']['package'] = array($deps['required']['package']); + } + + foreach ($deps['required']['package'] as $dep) { + if (!isset($dep['channel'])) { + return $this->raiseError('Cannot safely convert "' . $packagexml . '"' . + ' contains uri-based dependency on a package. Using a ' . + 'PEAR_PackageFileManager-based script is an option'); + } + + if ($dep['channel'] != 'pear.php.net' + && $dep['channel'] != 'pecl.php.net' + && $dep['channel'] != 'doc.php.net') { + return $this->raiseError('Cannot safely convert "' . $packagexml . '"' . + ' contains dependency on a non-standard channel package. Using a ' . + 'PEAR_PackageFileManager-based script is an option'); + } + + if (isset($dep['conflicts'])) { + return $this->raiseError('Cannot safely convert "' . $packagexml . '"' . + ' contains conflicts dependency. Using a ' . + 'PEAR_PackageFileManager-based script is an option'); + } + + if (isset($dep['exclude'])) { + $this->ui->outputData('WARNING: exclude tags are ignored in conversion'); + } + + if (isset($dep['min'])) { + $pf->addPackageDep($dep['name'], $dep['min'], 'ge'); + } + + if (isset($dep['max'])) { + $pf->addPackageDep($dep['name'], $dep['max'], 'le'); + } + } + } + + if (isset($deps['required']['extension'])) { + if (!isset($deps['required']['extension'][0])) { + $deps['required']['extension'] = array($deps['required']['extension']); + } + + foreach ($deps['required']['extension'] as $dep) { + if (isset($dep['conflicts'])) { + return $this->raiseError('Cannot safely convert "' . $packagexml . '"' . + ' contains conflicts dependency. Using a ' . + 'PEAR_PackageFileManager-based script is an option'); + } + + if (isset($dep['exclude'])) { + $this->ui->outputData('WARNING: exclude tags are ignored in conversion'); + } + + if (isset($dep['min'])) { + $pf->addExtensionDep($dep['name'], $dep['min'], 'ge'); + } + + if (isset($dep['max'])) { + $pf->addExtensionDep($dep['name'], $dep['max'], 'le'); + } + } + } + + if (isset($deps['optional']['package'])) { + if (!isset($deps['optional']['package'][0])) { + $deps['optional']['package'] = array($deps['optional']['package']); + } + + foreach ($deps['optional']['package'] as $dep) { + if (!isset($dep['channel'])) { + return $this->raiseError('Cannot safely convert "' . $packagexml . '"' . + ' contains uri-based dependency on a package. Using a ' . + 'PEAR_PackageFileManager-based script is an option'); + } + + if ($dep['channel'] != 'pear.php.net' + && $dep['channel'] != 'pecl.php.net' + && $dep['channel'] != 'doc.php.net') { + return $this->raiseError('Cannot safely convert "' . $packagexml . '"' . + ' contains dependency on a non-standard channel package. Using a ' . + 'PEAR_PackageFileManager-based script is an option'); + } + + if (isset($dep['exclude'])) { + $this->ui->outputData('WARNING: exclude tags are ignored in conversion'); + } + + if (isset($dep['min'])) { + $pf->addPackageDep($dep['name'], $dep['min'], 'ge', 'yes'); + } + + if (isset($dep['max'])) { + $pf->addPackageDep($dep['name'], $dep['max'], 'le', 'yes'); + } + } + } + + if (isset($deps['optional']['extension'])) { + if (!isset($deps['optional']['extension'][0])) { + $deps['optional']['extension'] = array($deps['optional']['extension']); + } + + foreach ($deps['optional']['extension'] as $dep) { + if (isset($dep['exclude'])) { + $this->ui->outputData('WARNING: exclude tags are ignored in conversion'); + } + + if (isset($dep['min'])) { + $pf->addExtensionDep($dep['name'], $dep['min'], 'ge', 'yes'); + } + + if (isset($dep['max'])) { + $pf->addExtensionDep($dep['name'], $dep['max'], 'le', 'yes'); + } + } + } + + $contents = $pf2->getContents(); + $release = $pf2->getReleases(); + if (isset($releases[0])) { + return $this->raiseError('Cannot safely process "' . $packagexml . '" contains ' + . 'multiple extsrcrelease/zendextsrcrelease tags. Using a PEAR_PackageFileManager-based script ' . + 'or the convert command is an option'); + } + + if ($configoptions = $pf2->getConfigureOptions()) { + foreach ($configoptions as $option) { + $default = isset($option['default']) ? $option['default'] : false; + $pf->addConfigureOption($option['name'], $option['prompt'], $default); + } + } + + if (isset($release['filelist']['ignore'])) { + return $this->raiseError('Cannot safely process "' . $packagexml . '" contains ' + . 'ignore tags. Using a PEAR_PackageFileManager-based script or the convert' . + ' command is an option'); + } + + if (isset($release['filelist']['install']) && + !isset($release['filelist']['install'][0])) { + $release['filelist']['install'] = array($release['filelist']['install']); + } + + if (isset($contents['dir']['attribs']['baseinstalldir'])) { + $baseinstalldir = $contents['dir']['attribs']['baseinstalldir']; + } else { + $baseinstalldir = false; + } + + if (!isset($contents['dir']['file'][0])) { + $contents['dir']['file'] = array($contents['dir']['file']); + } + + foreach ($contents['dir']['file'] as $file) { + if ($baseinstalldir && !isset($file['attribs']['baseinstalldir'])) { + $file['attribs']['baseinstalldir'] = $baseinstalldir; + } + + $processFile = $file; + unset($processFile['attribs']); + if (count($processFile)) { + foreach ($processFile as $name => $task) { + if ($name != $pf2->getTasksNs() . ':replace') { + return $this->raiseError('Cannot safely process "' . $packagexml . + '" contains tasks other than replace. Using a ' . + 'PEAR_PackageFileManager-based script is an option.'); + } + $file['attribs']['replace'][] = $task; + } + } + + if (!in_array($file['attribs']['role'], PEAR_Common::getFileRoles())) { + return $this->raiseError('Cannot safely convert "' . $packagexml . + '", contains custom roles. Using a PEAR_PackageFileManager-based script ' . + 'or the convert command is an option'); + } + + if (isset($release['filelist']['install'])) { + foreach ($release['filelist']['install'] as $installas) { + if ($installas['attribs']['name'] == $file['attribs']['name']) { + $file['attribs']['install-as'] = $installas['attribs']['as']; + } + } + } + + $pf->addFile('/', $file['attribs']['name'], $file['attribs']); + } + + if ($pf2->getChangeLog()) { + $this->ui->outputData('WARNING: changelog is not translated to package.xml ' . + '1.0, use PEAR_PackageFileManager-based script if you need changelog-' . + 'translation for package.xml 1.0'); + } + + $gen = &$pf->getDefaultGenerator(); + $gen->toPackageFile('.'); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Command/Registry.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Command/Registry.php new file mode 100644 index 0000000..37ee48b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Command/Registry.php @@ -0,0 +1,1144 @@ + + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 0.1 + */ + +/** + * base class + */ +require_once 'PEAR/Command/Common.php'; + +/** + * PEAR commands for registry manipulation + * + * @category pear + * @package PEAR + * @author Stig Bakken + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 0.1 + */ +class PEAR_Command_Registry extends PEAR_Command_Common +{ + var $commands = array( + 'list' => array( + 'summary' => 'List Installed Packages In The Default Channel', + 'function' => 'doList', + 'shortcut' => 'l', + 'options' => array( + 'channel' => array( + 'shortopt' => 'c', + 'doc' => 'list installed packages from this channel', + 'arg' => 'CHAN', + ), + 'allchannels' => array( + 'shortopt' => 'a', + 'doc' => 'list installed packages from all channels', + ), + 'channelinfo' => array( + 'shortopt' => 'i', + 'doc' => 'output fully channel-aware data, even on failure', + ), + ), + 'doc' => ' +If invoked without parameters, this command lists the PEAR packages +installed in your php_dir ({config php_dir}). With a parameter, it +lists the files in a package. +', + ), + 'list-files' => array( + 'summary' => 'List Files In Installed Package', + 'function' => 'doFileList', + 'shortcut' => 'fl', + 'options' => array(), + 'doc' => ' +List the files in an installed package. +' + ), + 'shell-test' => array( + 'summary' => 'Shell Script Test', + 'function' => 'doShellTest', + 'shortcut' => 'st', + 'options' => array(), + 'doc' => ' [[relation] version] +Tests if a package is installed in the system. Will exit(1) if it is not. + The version comparison operator. One of: + <, lt, <=, le, >, gt, >=, ge, ==, =, eq, !=, <>, ne + The version to compare with +'), + 'info' => array( + 'summary' => 'Display information about a package', + 'function' => 'doInfo', + 'shortcut' => 'in', + 'options' => array(), + 'doc' => ' +Displays information about a package. The package argument may be a +local package file, an URL to a package file, or the name of an +installed package.' + ) + ); + + /** + * PEAR_Command_Registry constructor. + * + * @access public + */ + function __construct(&$ui, &$config) + { + parent::__construct($ui, $config); + } + + function _sortinfo($a, $b) + { + $apackage = isset($a['package']) ? $a['package'] : $a['name']; + $bpackage = isset($b['package']) ? $b['package'] : $b['name']; + return strcmp($apackage, $bpackage); + } + + function doList($command, $options, $params) + { + $reg = &$this->config->getRegistry(); + $channelinfo = isset($options['channelinfo']); + if (isset($options['allchannels']) && !$channelinfo) { + return $this->doListAll($command, array(), $params); + } + + if (isset($options['allchannels']) && $channelinfo) { + // allchannels with $channelinfo + unset($options['allchannels']); + $channels = $reg->getChannels(); + $errors = array(); + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + foreach ($channels as $channel) { + $options['channel'] = $channel->getName(); + $ret = $this->doList($command, $options, $params); + + if (PEAR::isError($ret)) { + $errors[] = $ret; + } + } + + PEAR::staticPopErrorHandling(); + if (count($errors)) { + // for now, only give first error + return PEAR::raiseError($errors[0]); + } + + return true; + } + + if (count($params) === 1) { + return $this->doFileList($command, $options, $params); + } + + if (isset($options['channel'])) { + if (!$reg->channelExists($options['channel'])) { + return $this->raiseError('Channel "' . $options['channel'] .'" does not exist'); + } + + $channel = $reg->channelName($options['channel']); + } else { + $channel = $this->config->get('default_channel'); + } + + $installed = $reg->packageInfo(null, null, $channel); + usort($installed, array(&$this, '_sortinfo')); + + $data = array( + 'caption' => 'Installed packages, channel ' . + $channel . ':', + 'border' => true, + 'headline' => array('Package', 'Version', 'State'), + 'channel' => $channel, + ); + if ($channelinfo) { + $data['headline'] = array('Channel', 'Package', 'Version', 'State'); + } + + if (count($installed) && !isset($data['data'])) { + $data['data'] = array(); + } + + foreach ($installed as $package) { + $pobj = $reg->getPackage(isset($package['package']) ? + $package['package'] : $package['name'], $channel); + if ($channelinfo) { + $packageinfo = array($pobj->getChannel(), $pobj->getPackage(), $pobj->getVersion(), + $pobj->getState() ? $pobj->getState() : null); + } else { + $packageinfo = array($pobj->getPackage(), $pobj->getVersion(), + $pobj->getState() ? $pobj->getState() : null); + } + $data['data'][] = $packageinfo; + } + + if (count($installed) === 0) { + if (!$channelinfo) { + $data = '(no packages installed from channel ' . $channel . ')'; + } else { + $data = array( + 'caption' => 'Installed packages, channel ' . + $channel . ':', + 'border' => true, + 'channel' => $channel, + 'data' => array(array('(no packages installed)')), + ); + } + } + + $this->ui->outputData($data, $command); + return true; + } + + function doListAll($command, $options, $params) + { + // This duplicate code is deprecated over + // list --channelinfo, which gives identical + // output for list and list --allchannels. + $reg = &$this->config->getRegistry(); + $installed = $reg->packageInfo(null, null, null); + foreach ($installed as $channel => $packages) { + usort($packages, array($this, '_sortinfo')); + $data = array( + 'caption' => 'Installed packages, channel ' . $channel . ':', + 'border' => true, + 'headline' => array('Package', 'Version', 'State'), + 'channel' => $channel + ); + + foreach ($packages as $package) { + $p = isset($package['package']) ? $package['package'] : $package['name']; + $pobj = $reg->getPackage($p, $channel); + $data['data'][] = array($pobj->getPackage(), $pobj->getVersion(), + $pobj->getState() ? $pobj->getState() : null); + } + + // Adds a blank line after each section + $data['data'][] = array(); + + if (count($packages) === 0) { + $data = array( + 'caption' => 'Installed packages, channel ' . $channel . ':', + 'border' => true, + 'data' => array(array('(no packages installed)'), array()), + 'channel' => $channel + ); + } + $this->ui->outputData($data, $command); + } + return true; + } + + function doFileList($command, $options, $params) + { + if (count($params) !== 1) { + return $this->raiseError('list-files expects 1 parameter'); + } + + $reg = &$this->config->getRegistry(); + $fp = false; + if (!is_dir($params[0]) && (file_exists($params[0]) || $fp = @fopen($params[0], 'r'))) { + if ($fp) { + fclose($fp); + } + + if (!class_exists('PEAR_PackageFile')) { + require_once 'PEAR/PackageFile.php'; + } + + $pkg = new PEAR_PackageFile($this->config, $this->_debug); + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $info = &$pkg->fromAnyFile($params[0], PEAR_VALIDATE_NORMAL); + PEAR::staticPopErrorHandling(); + $headings = array('Package File', 'Install Path'); + $installed = false; + } else { + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $parsed = $reg->parsePackageName($params[0], $this->config->get('default_channel')); + PEAR::staticPopErrorHandling(); + if (PEAR::isError($parsed)) { + return $this->raiseError($parsed); + } + + $info = &$reg->getPackage($parsed['package'], $parsed['channel']); + $headings = array('Type', 'Install Path'); + $installed = true; + } + + if (PEAR::isError($info)) { + return $this->raiseError($info); + } + + if ($info === null) { + return $this->raiseError("`$params[0]' not installed"); + } + + $list = ($info->getPackagexmlVersion() == '1.0' || $installed) ? + $info->getFilelist() : $info->getContents(); + if ($installed) { + $caption = 'Installed Files For ' . $params[0]; + } else { + $caption = 'Contents of ' . basename($params[0]); + } + + $data = array( + 'caption' => $caption, + 'border' => true, + 'headline' => $headings); + if ($info->getPackagexmlVersion() == '1.0' || $installed) { + foreach ($list as $file => $att) { + if ($installed) { + if (empty($att['installed_as'])) { + continue; + } + $data['data'][] = array($att['role'], $att['installed_as']); + } else { + if (isset($att['baseinstalldir']) && !in_array($att['role'], + array('test', 'data', 'doc'))) { + $dest = $att['baseinstalldir'] . DIRECTORY_SEPARATOR . + $file; + } else { + $dest = $file; + } + switch ($att['role']) { + case 'test': + case 'data': + case 'doc': + $role = $att['role']; + if ($role == 'test') { + $role .= 's'; + } + $dest = $this->config->get($role . '_dir') . DIRECTORY_SEPARATOR . + $info->getPackage() . DIRECTORY_SEPARATOR . $dest; + break; + case 'php': + default: + $dest = $this->config->get('php_dir') . DIRECTORY_SEPARATOR . + $dest; + } + $ds2 = DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR; + $dest = preg_replace(array('!\\\\+!', '!/!', "!$ds2+!"), + array(DIRECTORY_SEPARATOR, + DIRECTORY_SEPARATOR, + DIRECTORY_SEPARATOR), + $dest); + $file = preg_replace('!/+!', '/', $file); + $data['data'][] = array($file, $dest); + } + } + } else { // package.xml 2.0, not installed + if (!isset($list['dir']['file'][0])) { + $list['dir']['file'] = array($list['dir']['file']); + } + + foreach ($list['dir']['file'] as $att) { + $att = $att['attribs']; + $file = $att['name']; + $role = &PEAR_Installer_Role::factory($info, $att['role'], $this->config); + $role->setup($this, $info, $att, $file); + if (!$role->isInstallable()) { + $dest = '(not installable)'; + } else { + $dest = $role->processInstallation($info, $att, $file, ''); + if (PEAR::isError($dest)) { + $dest = '(Unknown role "' . $att['role'] . ')'; + } else { + list(,, $dest) = $dest; + } + } + $data['data'][] = array($file, $dest); + } + } + + $this->ui->outputData($data, $command); + return true; + } + + function doShellTest($command, $options, $params) + { + if (count($params) < 1) { + return PEAR::raiseError('ERROR, usage: pear shell-test packagename [[relation] version]'); + } + + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $reg = &$this->config->getRegistry(); + $info = $reg->parsePackageName($params[0], $this->config->get('default_channel')); + if (PEAR::isError($info)) { + exit(1); // invalid package name + } + + $package = $info['package']; + $channel = $info['channel']; + // "pear shell-test Foo" + if (!$reg->packageExists($package, $channel)) { + if ($channel == 'pecl.php.net') { + if ($reg->packageExists($package, 'pear.php.net')) { + $channel = 'pear.php.net'; // magically change channels for extensions + } + } + } + + if (count($params) === 1) { + if (!$reg->packageExists($package, $channel)) { + exit(1); + } + // "pear shell-test Foo 1.0" + } elseif (count($params) === 2) { + $v = $reg->packageInfo($package, 'version', $channel); + if (!$v || !version_compare("$v", "{$params[1]}", "ge")) { + exit(1); + } + // "pear shell-test Foo ge 1.0" + } elseif (count($params) === 3) { + $v = $reg->packageInfo($package, 'version', $channel); + if (!$v || !version_compare("$v", "{$params[2]}", $params[1])) { + exit(1); + } + } else { + PEAR::staticPopErrorHandling(); + $this->raiseError("$command: expects 1 to 3 parameters"); + exit(1); + } + } + + function doInfo($command, $options, $params) + { + if (count($params) !== 1) { + return $this->raiseError('pear info expects 1 parameter'); + } + + $info = $fp = false; + $reg = &$this->config->getRegistry(); + if (is_file($params[0]) && !is_dir($params[0]) && + (file_exists($params[0]) || $fp = @fopen($params[0], 'r')) + ) { + if ($fp) { + fclose($fp); + } + + if (!class_exists('PEAR_PackageFile')) { + require_once 'PEAR/PackageFile.php'; + } + + $pkg = new PEAR_PackageFile($this->config, $this->_debug); + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $obj = &$pkg->fromAnyFile($params[0], PEAR_VALIDATE_NORMAL); + PEAR::staticPopErrorHandling(); + if (PEAR::isError($obj)) { + $uinfo = $obj->getUserInfo(); + if (is_array($uinfo)) { + foreach ($uinfo as $message) { + if (is_array($message)) { + $message = $message['message']; + } + $this->ui->outputData($message); + } + } + + return $this->raiseError($obj); + } + + if ($obj->getPackagexmlVersion() != '1.0') { + return $this->_doInfo2($command, $options, $params, $obj, false); + } + + $info = $obj->toArray(); + } else { + $parsed = $reg->parsePackageName($params[0], $this->config->get('default_channel')); + if (PEAR::isError($parsed)) { + return $this->raiseError($parsed); + } + + $package = $parsed['package']; + $channel = $parsed['channel']; + $info = $reg->packageInfo($package, null, $channel); + if (isset($info['old'])) { + $obj = $reg->getPackage($package, $channel); + return $this->_doInfo2($command, $options, $params, $obj, true); + } + } + + if (PEAR::isError($info)) { + return $info; + } + + if (empty($info)) { + $this->raiseError("No information found for `$params[0]'"); + return; + } + + unset($info['filelist']); + unset($info['dirtree']); + unset($info['changelog']); + if (isset($info['xsdversion'])) { + $info['package.xml version'] = $info['xsdversion']; + unset($info['xsdversion']); + } + + if (isset($info['packagerversion'])) { + $info['packaged with PEAR version'] = $info['packagerversion']; + unset($info['packagerversion']); + } + + $keys = array_keys($info); + $longtext = array('description', 'summary'); + foreach ($keys as $key) { + if (is_array($info[$key])) { + switch ($key) { + case 'maintainers': { + $i = 0; + $mstr = ''; + foreach ($info[$key] as $m) { + if ($i++ > 0) { + $mstr .= "\n"; + } + $mstr .= $m['name'] . " <"; + if (isset($m['email'])) { + $mstr .= $m['email']; + } else { + $mstr .= $m['handle'] . '@php.net'; + } + $mstr .= "> ($m[role])"; + } + $info[$key] = $mstr; + break; + } + case 'release_deps': { + $i = 0; + $dstr = ''; + foreach ($info[$key] as $d) { + if (isset($this->_deps_rel_trans[$d['rel']])) { + $rel = $this->_deps_rel_trans[$d['rel']]; + } else { + $rel = $d['rel']; + } + if (isset($this->_deps_type_trans[$d['type']])) { + $type = ucfirst($this->_deps_type_trans[$d['type']]); + } else { + $type = $d['type']; + } + if (isset($d['name'])) { + $name = $d['name'] . ' '; + } else { + $name = ''; + } + if (isset($d['version'])) { + $version = $d['version'] . ' '; + } else { + $version = ''; + } + if (isset($d['optional']) && $d['optional'] == 'yes') { + $optional = ' (optional)'; + } else { + $optional = ''; + } + $dstr .= "$type $name$rel $version$optional\n"; + } + $info[$key] = $dstr; + break; + } + case 'provides' : { + $debug = $this->config->get('verbose'); + if ($debug < 2) { + $pstr = 'Classes: '; + } else { + $pstr = ''; + } + $i = 0; + foreach ($info[$key] as $p) { + if ($debug < 2 && $p['type'] != "class") { + continue; + } + // Only print classes when verbosity mode is < 2 + if ($debug < 2) { + if ($i++ > 0) { + $pstr .= ", "; + } + $pstr .= $p['name']; + } else { + if ($i++ > 0) { + $pstr .= "\n"; + } + $pstr .= ucfirst($p['type']) . " " . $p['name']; + if (isset($p['explicit']) && $p['explicit'] == 1) { + $pstr .= " (explicit)"; + } + } + } + $info[$key] = $pstr; + break; + } + case 'configure_options' : { + foreach ($info[$key] as $i => $p) { + $info[$key][$i] = array_map(null, array_keys($p), array_values($p)); + $info[$key][$i] = array_map(create_function('$a', + 'return join(" = ",$a);'), $info[$key][$i]); + $info[$key][$i] = implode(', ', $info[$key][$i]); + } + $info[$key] = implode("\n", $info[$key]); + break; + } + default: { + $info[$key] = implode(", ", $info[$key]); + break; + } + } + } + + if ($key == '_lastmodified') { + $hdate = date('Y-m-d', $info[$key]); + unset($info[$key]); + $info['Last Modified'] = $hdate; + } elseif ($key == '_lastversion') { + $info['Previous Installed Version'] = $info[$key] ? $info[$key] : '- None -'; + unset($info[$key]); + } else { + $info[$key] = trim($info[$key]); + if (in_array($key, $longtext)) { + $info[$key] = preg_replace('/ +/', ' ', $info[$key]); + } + } + } + + $caption = 'About ' . $info['package'] . '-' . $info['version']; + $data = array( + 'caption' => $caption, + 'border' => true); + foreach ($info as $key => $value) { + $key = ucwords(trim(str_replace('_', ' ', $key))); + $data['data'][] = array($key, $value); + } + $data['raw'] = $info; + + $this->ui->outputData($data, 'package-info'); + } + + /** + * @access private + */ + function _doInfo2($command, $options, $params, &$obj, $installed) + { + $reg = &$this->config->getRegistry(); + $caption = 'About ' . $obj->getChannel() . '/' .$obj->getPackage() . '-' . + $obj->getVersion(); + $data = array( + 'caption' => $caption, + 'border' => true); + switch ($obj->getPackageType()) { + case 'php' : + $release = 'PEAR-style PHP-based Package'; + break; + case 'extsrc' : + $release = 'PECL-style PHP extension (source code)'; + break; + case 'zendextsrc' : + $release = 'PECL-style Zend extension (source code)'; + break; + case 'extbin' : + $release = 'PECL-style PHP extension (binary)'; + break; + case 'zendextbin' : + $release = 'PECL-style Zend extension (binary)'; + break; + case 'bundle' : + $release = 'Package bundle (collection of packages)'; + break; + } + $extends = $obj->getExtends(); + $extends = $extends ? + $obj->getPackage() . ' (extends ' . $extends . ')' : $obj->getPackage(); + if ($src = $obj->getSourcePackage()) { + $extends .= ' (source package ' . $src['channel'] . '/' . $src['package'] . ')'; + } + + $info = array( + 'Release Type' => $release, + 'Name' => $extends, + 'Channel' => $obj->getChannel(), + 'Summary' => preg_replace('/ +/', ' ', $obj->getSummary()), + 'Description' => preg_replace('/ +/', ' ', $obj->getDescription()), + ); + $info['Maintainers'] = ''; + foreach (array('lead', 'developer', 'contributor', 'helper') as $role) { + $leads = $obj->{"get{$role}s"}(); + if (!$leads) { + continue; + } + + if (isset($leads['active'])) { + $leads = array($leads); + } + + foreach ($leads as $lead) { + if (!empty($info['Maintainers'])) { + $info['Maintainers'] .= "\n"; + } + + $active = $lead['active'] == 'no' ? ', inactive' : ''; + $info['Maintainers'] .= $lead['name'] . ' <'; + $info['Maintainers'] .= $lead['email'] . "> ($role$active)"; + } + } + + $info['Release Date'] = $obj->getDate(); + if ($time = $obj->getTime()) { + $info['Release Date'] .= ' ' . $time; + } + + $info['Release Version'] = $obj->getVersion() . ' (' . $obj->getState() . ')'; + $info['API Version'] = $obj->getVersion('api') . ' (' . $obj->getState('api') . ')'; + $info['License'] = $obj->getLicense(); + $uri = $obj->getLicenseLocation(); + if ($uri) { + if (isset($uri['uri'])) { + $info['License'] .= ' (' . $uri['uri'] . ')'; + } else { + $extra = $obj->getInstalledLocation($info['filesource']); + if ($extra) { + $info['License'] .= ' (' . $uri['filesource'] . ')'; + } + } + } + + $info['Release Notes'] = $obj->getNotes(); + if ($compat = $obj->getCompatible()) { + if (!isset($compat[0])) { + $compat = array($compat); + } + + $info['Compatible with'] = ''; + foreach ($compat as $package) { + $info['Compatible with'] .= $package['channel'] . '/' . $package['name'] . + "\nVersions >= " . $package['min'] . ', <= ' . $package['max']; + if (isset($package['exclude'])) { + if (is_array($package['exclude'])) { + $package['exclude'] = implode(', ', $package['exclude']); + } + + if (!isset($info['Not Compatible with'])) { + $info['Not Compatible with'] = ''; + } else { + $info['Not Compatible with'] .= "\n"; + } + $info['Not Compatible with'] .= $package['channel'] . '/' . + $package['name'] . "\nVersions " . $package['exclude']; + } + } + } + + $usesrole = $obj->getUsesrole(); + if ($usesrole) { + if (!isset($usesrole[0])) { + $usesrole = array($usesrole); + } + + foreach ($usesrole as $roledata) { + if (isset($info['Uses Custom Roles'])) { + $info['Uses Custom Roles'] .= "\n"; + } else { + $info['Uses Custom Roles'] = ''; + } + + if (isset($roledata['package'])) { + $rolepackage = $reg->parsedPackageNameToString($roledata, true); + } else { + $rolepackage = $roledata['uri']; + } + $info['Uses Custom Roles'] .= $roledata['role'] . ' (' . $rolepackage . ')'; + } + } + + $usestask = $obj->getUsestask(); + if ($usestask) { + if (!isset($usestask[0])) { + $usestask = array($usestask); + } + + foreach ($usestask as $taskdata) { + if (isset($info['Uses Custom Tasks'])) { + $info['Uses Custom Tasks'] .= "\n"; + } else { + $info['Uses Custom Tasks'] = ''; + } + + if (isset($taskdata['package'])) { + $taskpackage = $reg->parsedPackageNameToString($taskdata, true); + } else { + $taskpackage = $taskdata['uri']; + } + $info['Uses Custom Tasks'] .= $taskdata['task'] . ' (' . $taskpackage . ')'; + } + } + + $deps = $obj->getDependencies(); + $info['Required Dependencies'] = 'PHP version ' . $deps['required']['php']['min']; + if (isset($deps['required']['php']['max'])) { + $info['Required Dependencies'] .= '-' . $deps['required']['php']['max'] . "\n"; + } else { + $info['Required Dependencies'] .= "\n"; + } + + if (isset($deps['required']['php']['exclude'])) { + if (!isset($info['Not Compatible with'])) { + $info['Not Compatible with'] = ''; + } else { + $info['Not Compatible with'] .= "\n"; + } + + if (is_array($deps['required']['php']['exclude'])) { + $deps['required']['php']['exclude'] = + implode(', ', $deps['required']['php']['exclude']); + } + $info['Not Compatible with'] .= "PHP versions\n " . + $deps['required']['php']['exclude']; + } + + $info['Required Dependencies'] .= 'PEAR installer version'; + if (isset($deps['required']['pearinstaller']['max'])) { + $info['Required Dependencies'] .= 's ' . + $deps['required']['pearinstaller']['min'] . '-' . + $deps['required']['pearinstaller']['max']; + } else { + $info['Required Dependencies'] .= ' ' . + $deps['required']['pearinstaller']['min'] . ' or newer'; + } + + if (isset($deps['required']['pearinstaller']['exclude'])) { + if (!isset($info['Not Compatible with'])) { + $info['Not Compatible with'] = ''; + } else { + $info['Not Compatible with'] .= "\n"; + } + + if (is_array($deps['required']['pearinstaller']['exclude'])) { + $deps['required']['pearinstaller']['exclude'] = + implode(', ', $deps['required']['pearinstaller']['exclude']); + } + $info['Not Compatible with'] .= "PEAR installer\n Versions " . + $deps['required']['pearinstaller']['exclude']; + } + + foreach (array('Package', 'Extension') as $type) { + $index = strtolower($type); + if (isset($deps['required'][$index])) { + if (isset($deps['required'][$index]['name'])) { + $deps['required'][$index] = array($deps['required'][$index]); + } + + foreach ($deps['required'][$index] as $package) { + if (isset($package['conflicts'])) { + $infoindex = 'Not Compatible with'; + if (!isset($info['Not Compatible with'])) { + $info['Not Compatible with'] = ''; + } else { + $info['Not Compatible with'] .= "\n"; + } + } else { + $infoindex = 'Required Dependencies'; + $info[$infoindex] .= "\n"; + } + + if ($index == 'extension') { + $name = $package['name']; + } else { + if (isset($package['channel'])) { + $name = $package['channel'] . '/' . $package['name']; + } else { + $name = '__uri/' . $package['name'] . ' (static URI)'; + } + } + + $info[$infoindex] .= "$type $name"; + if (isset($package['uri'])) { + $info[$infoindex] .= "\n Download URI: $package[uri]"; + continue; + } + + if (isset($package['max']) && isset($package['min'])) { + $info[$infoindex] .= " \n Versions " . + $package['min'] . '-' . $package['max']; + } elseif (isset($package['min'])) { + $info[$infoindex] .= " \n Version " . + $package['min'] . ' or newer'; + } elseif (isset($package['max'])) { + $info[$infoindex] .= " \n Version " . + $package['max'] . ' or older'; + } + + if (isset($package['recommended'])) { + $info[$infoindex] .= "\n Recommended version: $package[recommended]"; + } + + if (isset($package['exclude'])) { + if (!isset($info['Not Compatible with'])) { + $info['Not Compatible with'] = ''; + } else { + $info['Not Compatible with'] .= "\n"; + } + + if (is_array($package['exclude'])) { + $package['exclude'] = implode(', ', $package['exclude']); + } + + $package['package'] = $package['name']; // for parsedPackageNameToString + if (isset($package['conflicts'])) { + $info['Not Compatible with'] .= '=> except '; + } + $info['Not Compatible with'] .= 'Package ' . + $reg->parsedPackageNameToString($package, true); + $info['Not Compatible with'] .= "\n Versions " . $package['exclude']; + } + } + } + } + + if (isset($deps['required']['os'])) { + if (isset($deps['required']['os']['name'])) { + $dep['required']['os']['name'] = array($dep['required']['os']['name']); + } + + foreach ($dep['required']['os'] as $os) { + if (isset($os['conflicts']) && $os['conflicts'] == 'yes') { + if (!isset($info['Not Compatible with'])) { + $info['Not Compatible with'] = ''; + } else { + $info['Not Compatible with'] .= "\n"; + } + $info['Not Compatible with'] .= "$os[name] Operating System"; + } else { + $info['Required Dependencies'] .= "\n"; + $info['Required Dependencies'] .= "$os[name] Operating System"; + } + } + } + + if (isset($deps['required']['arch'])) { + if (isset($deps['required']['arch']['pattern'])) { + $dep['required']['arch']['pattern'] = array($dep['required']['os']['pattern']); + } + + foreach ($dep['required']['arch'] as $os) { + if (isset($os['conflicts']) && $os['conflicts'] == 'yes') { + if (!isset($info['Not Compatible with'])) { + $info['Not Compatible with'] = ''; + } else { + $info['Not Compatible with'] .= "\n"; + } + $info['Not Compatible with'] .= "OS/Arch matching pattern '/$os[pattern]/'"; + } else { + $info['Required Dependencies'] .= "\n"; + $info['Required Dependencies'] .= "OS/Arch matching pattern '/$os[pattern]/'"; + } + } + } + + if (isset($deps['optional'])) { + foreach (array('Package', 'Extension') as $type) { + $index = strtolower($type); + if (isset($deps['optional'][$index])) { + if (isset($deps['optional'][$index]['name'])) { + $deps['optional'][$index] = array($deps['optional'][$index]); + } + + foreach ($deps['optional'][$index] as $package) { + if (isset($package['conflicts']) && $package['conflicts'] == 'yes') { + $infoindex = 'Not Compatible with'; + if (!isset($info['Not Compatible with'])) { + $info['Not Compatible with'] = ''; + } else { + $info['Not Compatible with'] .= "\n"; + } + } else { + $infoindex = 'Optional Dependencies'; + if (!isset($info['Optional Dependencies'])) { + $info['Optional Dependencies'] = ''; + } else { + $info['Optional Dependencies'] .= "\n"; + } + } + + if ($index == 'extension') { + $name = $package['name']; + } else { + if (isset($package['channel'])) { + $name = $package['channel'] . '/' . $package['name']; + } else { + $name = '__uri/' . $package['name'] . ' (static URI)'; + } + } + + $info[$infoindex] .= "$type $name"; + if (isset($package['uri'])) { + $info[$infoindex] .= "\n Download URI: $package[uri]"; + continue; + } + + if ($infoindex == 'Not Compatible with') { + // conflicts is only used to say that all versions conflict + continue; + } + + if (isset($package['max']) && isset($package['min'])) { + $info[$infoindex] .= " \n Versions " . + $package['min'] . '-' . $package['max']; + } elseif (isset($package['min'])) { + $info[$infoindex] .= " \n Version " . + $package['min'] . ' or newer'; + } elseif (isset($package['max'])) { + $info[$infoindex] .= " \n Version " . + $package['min'] . ' or older'; + } + + if (isset($package['recommended'])) { + $info[$infoindex] .= "\n Recommended version: $package[recommended]"; + } + + if (isset($package['exclude'])) { + if (!isset($info['Not Compatible with'])) { + $info['Not Compatible with'] = ''; + } else { + $info['Not Compatible with'] .= "\n"; + } + + if (is_array($package['exclude'])) { + $package['exclude'] = implode(', ', $package['exclude']); + } + + $info['Not Compatible with'] .= "Package $package\n Versions " . + $package['exclude']; + } + } + } + } + } + + if (isset($deps['group'])) { + if (!isset($deps['group'][0])) { + $deps['group'] = array($deps['group']); + } + + foreach ($deps['group'] as $group) { + $info['Dependency Group ' . $group['attribs']['name']] = $group['attribs']['hint']; + $groupindex = $group['attribs']['name'] . ' Contents'; + $info[$groupindex] = ''; + foreach (array('Package', 'Extension') as $type) { + $index = strtolower($type); + if (isset($group[$index])) { + if (isset($group[$index]['name'])) { + $group[$index] = array($group[$index]); + } + + foreach ($group[$index] as $package) { + if (!empty($info[$groupindex])) { + $info[$groupindex] .= "\n"; + } + + if ($index == 'extension') { + $name = $package['name']; + } else { + if (isset($package['channel'])) { + $name = $package['channel'] . '/' . $package['name']; + } else { + $name = '__uri/' . $package['name'] . ' (static URI)'; + } + } + + if (isset($package['uri'])) { + if (isset($package['conflicts']) && $package['conflicts'] == 'yes') { + $info[$groupindex] .= "Not Compatible with $type $name"; + } else { + $info[$groupindex] .= "$type $name"; + } + + $info[$groupindex] .= "\n Download URI: $package[uri]"; + continue; + } + + if (isset($package['conflicts']) && $package['conflicts'] == 'yes') { + $info[$groupindex] .= "Not Compatible with $type $name"; + continue; + } + + $info[$groupindex] .= "$type $name"; + if (isset($package['max']) && isset($package['min'])) { + $info[$groupindex] .= " \n Versions " . + $package['min'] . '-' . $package['max']; + } elseif (isset($package['min'])) { + $info[$groupindex] .= " \n Version " . + $package['min'] . ' or newer'; + } elseif (isset($package['max'])) { + $info[$groupindex] .= " \n Version " . + $package['min'] . ' or older'; + } + + if (isset($package['recommended'])) { + $info[$groupindex] .= "\n Recommended version: $package[recommended]"; + } + + if (isset($package['exclude'])) { + if (!isset($info['Not Compatible with'])) { + $info['Not Compatible with'] = ''; + } else { + $info[$groupindex] .= "Not Compatible with\n"; + } + + if (is_array($package['exclude'])) { + $package['exclude'] = implode(', ', $package['exclude']); + } + $info[$groupindex] .= " Package $package\n Versions " . + $package['exclude']; + } + } + } + } + } + } + + if ($obj->getPackageType() == 'bundle') { + $info['Bundled Packages'] = ''; + foreach ($obj->getBundledPackages() as $package) { + if (!empty($info['Bundled Packages'])) { + $info['Bundled Packages'] .= "\n"; + } + + if (isset($package['uri'])) { + $info['Bundled Packages'] .= '__uri/' . $package['name']; + $info['Bundled Packages'] .= "\n (URI: $package[uri]"; + } else { + $info['Bundled Packages'] .= $package['channel'] . '/' . $package['name']; + } + } + } + + $info['package.xml version'] = '2.0'; + if ($installed) { + if ($obj->getLastModified()) { + $info['Last Modified'] = date('Y-m-d H:i', $obj->getLastModified()); + } + + $v = $obj->getLastInstalledVersion(); + $info['Previous Installed Version'] = $v ? $v : '- None -'; + } + + foreach ($info as $key => $value) { + $data['data'][] = array($key, $value); + } + + $data['raw'] = $obj->getArray(); // no validation needed + $this->ui->outputData($data, 'package-info'); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Command/Remote.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Command/Remote.php new file mode 100644 index 0000000..f73db24 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Command/Remote.php @@ -0,0 +1,809 @@ + + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 0.1 + */ + +/** + * base class + */ +require_once 'PEAR/Command/Common.php'; +require_once 'PEAR/REST.php'; + +/** + * PEAR commands for remote server querying + * + * @category pear + * @package PEAR + * @author Stig Bakken + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 0.1 + */ +class PEAR_Command_Remote extends PEAR_Command_Common +{ + var $commands = array( + 'remote-info' => array( + 'summary' => 'Information About Remote Packages', + 'function' => 'doRemoteInfo', + 'shortcut' => 'ri', + 'options' => array(), + 'doc' => ' +Get details on a package from the server.', + ), + 'list-upgrades' => array( + 'summary' => 'List Available Upgrades', + 'function' => 'doListUpgrades', + 'shortcut' => 'lu', + 'options' => array( + 'channelinfo' => array( + 'shortopt' => 'i', + 'doc' => 'output fully channel-aware data, even on failure', + ), + ), + 'doc' => '[preferred_state] +List releases on the server of packages you have installed where +a newer version is available with the same release state (stable etc.) +or the state passed as the second parameter.' + ), + 'remote-list' => array( + 'summary' => 'List Remote Packages', + 'function' => 'doRemoteList', + 'shortcut' => 'rl', + 'options' => array( + 'channel' => + array( + 'shortopt' => 'c', + 'doc' => 'specify a channel other than the default channel', + 'arg' => 'CHAN', + ) + ), + 'doc' => ' +Lists the packages available on the configured server along with the +latest stable release of each package.', + ), + 'search' => array( + 'summary' => 'Search remote package database', + 'function' => 'doSearch', + 'shortcut' => 'sp', + 'options' => array( + 'channel' => + array( + 'shortopt' => 'c', + 'doc' => 'specify a channel other than the default channel', + 'arg' => 'CHAN', + ), + 'allchannels' => array( + 'shortopt' => 'a', + 'doc' => 'search packages from all known channels', + ), + 'channelinfo' => array( + 'shortopt' => 'i', + 'doc' => 'output fully channel-aware data, even on failure', + ), + ), + 'doc' => '[packagename] [packageinfo] +Lists all packages which match the search parameters. The first +parameter is a fragment of a packagename. The default channel +will be used unless explicitly overridden. The second parameter +will be used to match any portion of the summary/description', + ), + 'list-all' => array( + 'summary' => 'List All Packages', + 'function' => 'doListAll', + 'shortcut' => 'la', + 'options' => array( + 'channel' => + array( + 'shortopt' => 'c', + 'doc' => 'specify a channel other than the default channel', + 'arg' => 'CHAN', + ), + 'channelinfo' => array( + 'shortopt' => 'i', + 'doc' => 'output fully channel-aware data, even on failure', + ), + ), + 'doc' => ' +Lists the packages available on the configured server along with the +latest stable release of each package.', + ), + 'download' => array( + 'summary' => 'Download Package', + 'function' => 'doDownload', + 'shortcut' => 'd', + 'options' => array( + 'nocompress' => array( + 'shortopt' => 'Z', + 'doc' => 'download an uncompressed (.tar) file', + ), + ), + 'doc' => '... +Download package tarballs. The files will be named as suggested by the +server, for example if you download the DB package and the latest stable +version of DB is 1.6.5, the downloaded file will be DB-1.6.5.tgz.', + ), + 'clear-cache' => array( + 'summary' => 'Clear Web Services Cache', + 'function' => 'doClearCache', + 'shortcut' => 'cc', + 'options' => array(), + 'doc' => ' +Clear the REST cache. See also the cache_ttl configuration +parameter. +', + ), + ); + + /** + * PEAR_Command_Remote constructor. + * + * @access public + */ + function __construct(&$ui, &$config) + { + parent::__construct($ui, $config); + } + + function _checkChannelForStatus($channel, $chan) + { + if (PEAR::isError($chan)) { + $this->raiseError($chan); + } + if (!is_a($chan, 'PEAR_ChannelFile')) { + return $this->raiseError('Internal corruption error: invalid channel "' . + $channel . '"'); + } + $rest = new PEAR_REST($this->config); + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $mirror = $this->config->get('preferred_mirror', null, + $channel); + $a = $rest->downloadHttp('http://' . $channel . + '/channel.xml', $chan->lastModified()); + PEAR::staticPopErrorHandling(); + if (!PEAR::isError($a) && $a) { + $this->ui->outputData('WARNING: channel "' . $channel . '" has ' . + 'updated its protocols, use "' . PEAR_RUNTYPE . ' channel-update ' . $channel . + '" to update'); + } + } + + function doRemoteInfo($command, $options, $params) + { + if (sizeof($params) != 1) { + return $this->raiseError("$command expects one param: the remote package name"); + } + $savechannel = $channel = $this->config->get('default_channel'); + $reg = &$this->config->getRegistry(); + $package = $params[0]; + $parsed = $reg->parsePackageName($package, $channel); + if (PEAR::isError($parsed)) { + return $this->raiseError('Invalid package name "' . $package . '"'); + } + + $channel = $parsed['channel']; + $this->config->set('default_channel', $channel); + $chan = $reg->getChannel($channel); + if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) { + return $e; + } + + $mirror = $this->config->get('preferred_mirror'); + if ($chan->supportsREST($mirror) && $base = $chan->getBaseURL('REST1.0', $mirror)) { + $rest = &$this->config->getREST('1.0', array()); + $info = $rest->packageInfo($base, $parsed['package'], $channel); + } + + if (!isset($info)) { + return $this->raiseError('No supported protocol was found'); + } + + if (PEAR::isError($info)) { + $this->config->set('default_channel', $savechannel); + return $this->raiseError($info); + } + + if (!isset($info['name'])) { + return $this->raiseError('No remote package "' . $package . '" was found'); + } + + $installed = $reg->packageInfo($info['name'], null, $channel); + $info['installed'] = $installed['version'] ? $installed['version'] : '- no -'; + if (is_array($info['installed'])) { + $info['installed'] = $info['installed']['release']; + } + + $this->ui->outputData($info, $command); + $this->config->set('default_channel', $savechannel); + + return true; + } + + function doRemoteList($command, $options, $params) + { + $savechannel = $channel = $this->config->get('default_channel'); + $reg = &$this->config->getRegistry(); + if (isset($options['channel'])) { + $channel = $options['channel']; + if (!$reg->channelExists($channel)) { + return $this->raiseError('Channel "' . $channel . '" does not exist'); + } + + $this->config->set('default_channel', $channel); + } + + $chan = $reg->getChannel($channel); + if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) { + return $e; + } + + $list_options = false; + if ($this->config->get('preferred_state') == 'stable') { + $list_options = true; + } + + $available = array(); + if ($chan->supportsREST($this->config->get('preferred_mirror')) && + $base = $chan->getBaseURL('REST1.1', $this->config->get('preferred_mirror')) + ) { + // use faster list-all if available + $rest = &$this->config->getREST('1.1', array()); + $available = $rest->listAll($base, $list_options, true, false, false, $chan->getName()); + } elseif ($chan->supportsREST($this->config->get('preferred_mirror')) && + $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) { + $rest = &$this->config->getREST('1.0', array()); + $available = $rest->listAll($base, $list_options, true, false, false, $chan->getName()); + } + + if (PEAR::isError($available)) { + $this->config->set('default_channel', $savechannel); + return $this->raiseError($available); + } + + $i = $j = 0; + $data = array( + 'caption' => 'Channel ' . $channel . ' Available packages:', + 'border' => true, + 'headline' => array('Package', 'Version'), + 'channel' => $channel + ); + + if (count($available) == 0) { + $data = '(no packages available yet)'; + } else { + foreach ($available as $name => $info) { + $version = (isset($info['stable']) && $info['stable']) ? $info['stable'] : '-n/a-'; + $data['data'][] = array($name, $version); + } + } + $this->ui->outputData($data, $command); + $this->config->set('default_channel', $savechannel); + return true; + } + + function doListAll($command, $options, $params) + { + $savechannel = $channel = $this->config->get('default_channel'); + $reg = &$this->config->getRegistry(); + if (isset($options['channel'])) { + $channel = $options['channel']; + if (!$reg->channelExists($channel)) { + return $this->raiseError("Channel \"$channel\" does not exist"); + } + + $this->config->set('default_channel', $channel); + } + + $list_options = false; + if ($this->config->get('preferred_state') == 'stable') { + $list_options = true; + } + + $chan = $reg->getChannel($channel); + if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) { + return $e; + } + + if ($chan->supportsREST($this->config->get('preferred_mirror')) && + $base = $chan->getBaseURL('REST1.1', $this->config->get('preferred_mirror'))) { + // use faster list-all if available + $rest = &$this->config->getREST('1.1', array()); + $available = $rest->listAll($base, $list_options, false, false, false, $chan->getName()); + } elseif ($chan->supportsREST($this->config->get('preferred_mirror')) && + $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) { + $rest = &$this->config->getREST('1.0', array()); + $available = $rest->listAll($base, $list_options, false, false, false, $chan->getName()); + } + + if (PEAR::isError($available)) { + $this->config->set('default_channel', $savechannel); + return $this->raiseError('The package list could not be fetched from the remote server. Please try again. (Debug info: "' . $available->getMessage() . '")'); + } + + $data = array( + 'caption' => 'All packages [Channel ' . $channel . ']:', + 'border' => true, + 'headline' => array('Package', 'Latest', 'Local'), + 'channel' => $channel, + ); + + if (isset($options['channelinfo'])) { + // add full channelinfo + $data['caption'] = 'Channel ' . $channel . ' All packages:'; + $data['headline'] = array('Channel', 'Package', 'Latest', 'Local', + 'Description', 'Dependencies'); + } + $local_pkgs = $reg->listPackages($channel); + + foreach ($available as $name => $info) { + $installed = $reg->packageInfo($name, null, $channel); + if (is_array($installed['version'])) { + $installed['version'] = $installed['version']['release']; + } + $desc = $info['summary']; + if (isset($params[$name])) { + $desc .= "\n\n".$info['description']; + } + if (isset($options['mode'])) + { + if ($options['mode'] == 'installed' && !isset($installed['version'])) { + continue; + } + if ($options['mode'] == 'notinstalled' && isset($installed['version'])) { + continue; + } + if ($options['mode'] == 'upgrades' + && (!isset($installed['version']) || version_compare($installed['version'], + $info['stable'], '>='))) { + continue; + } + } + $pos = array_search(strtolower($name), $local_pkgs); + if ($pos !== false) { + unset($local_pkgs[$pos]); + } + + if (isset($info['stable']) && !$info['stable']) { + $info['stable'] = null; + } + + if (isset($options['channelinfo'])) { + // add full channelinfo + if ($info['stable'] === $info['unstable']) { + $state = $info['state']; + } else { + $state = 'stable'; + } + $latest = $info['stable'].' ('.$state.')'; + $local = ''; + if (isset($installed['version'])) { + $inst_state = $reg->packageInfo($name, 'release_state', $channel); + $local = $installed['version'].' ('.$inst_state.')'; + } + + $packageinfo = array( + $channel, + $name, + $latest, + $local, + isset($desc) ? $desc : null, + isset($info['deps']) ? $info['deps'] : null, + ); + } else { + $packageinfo = array( + $reg->channelAlias($channel) . '/' . $name, + isset($info['stable']) ? $info['stable'] : null, + isset($installed['version']) ? $installed['version'] : null, + isset($desc) ? $desc : null, + isset($info['deps']) ? $info['deps'] : null, + ); + } + $data['data'][$info['category']][] = $packageinfo; + } + + if (isset($options['mode']) && in_array($options['mode'], array('notinstalled', 'upgrades'))) { + $this->config->set('default_channel', $savechannel); + $this->ui->outputData($data, $command); + return true; + } + + foreach ($local_pkgs as $name) { + $info = &$reg->getPackage($name, $channel); + $data['data']['Local'][] = array( + $reg->channelAlias($channel) . '/' . $info->getPackage(), + '', + $info->getVersion(), + $info->getSummary(), + $info->getDeps() + ); + } + + $this->config->set('default_channel', $savechannel); + $this->ui->outputData($data, $command); + return true; + } + + function doSearch($command, $options, $params) + { + if ((!isset($params[0]) || empty($params[0])) + && (!isset($params[1]) || empty($params[1]))) + { + return $this->raiseError('no valid search string supplied'); + } + + $channelinfo = isset($options['channelinfo']); + $reg = &$this->config->getRegistry(); + if (isset($options['allchannels'])) { + // search all channels + unset($options['allchannels']); + $channels = $reg->getChannels(); + $errors = array(); + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + foreach ($channels as $channel) { + if ($channel->getName() != '__uri') { + $options['channel'] = $channel->getName(); + $ret = $this->doSearch($command, $options, $params); + if (PEAR::isError($ret)) { + $errors[] = $ret; + } + } + } + + PEAR::staticPopErrorHandling(); + if (count($errors) !== 0) { + // for now, only give first error + return PEAR::raiseError($errors[0]); + } + + return true; + } + + $savechannel = $channel = $this->config->get('default_channel'); + $package = strtolower($params[0]); + $summary = isset($params[1]) ? $params[1] : false; + if (isset($options['channel'])) { + $reg = &$this->config->getRegistry(); + $channel = $options['channel']; + if (!$reg->channelExists($channel)) { + return $this->raiseError('Channel "' . $channel . '" does not exist'); + } + + $this->config->set('default_channel', $channel); + } + + $chan = $reg->getChannel($channel); + if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) { + return $e; + } + + if ($chan->supportsREST($this->config->get('preferred_mirror')) && + $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) { + $rest = &$this->config->getREST('1.0', array()); + $available = $rest->listAll($base, false, false, $package, $summary, $chan->getName()); + } + + if (PEAR::isError($available)) { + $this->config->set('default_channel', $savechannel); + return $this->raiseError($available); + } + + if (!$available && !$channelinfo) { + // clean exit when not found, no error ! + $data = 'no packages found that match pattern "' . $package . '", for channel '.$channel.'.'; + $this->ui->outputData($data); + $this->config->set('default_channel', $channel); + return true; + } + + if ($channelinfo) { + $data = array( + 'caption' => 'Matched packages, channel ' . $channel . ':', + 'border' => true, + 'headline' => array('Channel', 'Package', 'Stable/(Latest)', 'Local'), + 'channel' => $channel + ); + } else { + $data = array( + 'caption' => 'Matched packages, channel ' . $channel . ':', + 'border' => true, + 'headline' => array('Package', 'Stable/(Latest)', 'Local'), + 'channel' => $channel + ); + } + + if (!$available && $channelinfo) { + unset($data['headline']); + $data['data'] = 'No packages found that match pattern "' . $package . '".'; + $available = array(); + } + + foreach ($available as $name => $info) { + $installed = $reg->packageInfo($name, null, $channel); + $desc = $info['summary']; + if (isset($params[$name])) + $desc .= "\n\n".$info['description']; + + if (!isset($info['stable']) || !$info['stable']) { + $version_remote = 'none'; + } else { + if ($info['unstable']) { + $version_remote = $info['unstable']; + } else { + $version_remote = $info['stable']; + } + $version_remote .= ' ('.$info['state'].')'; + } + $version = is_array($installed['version']) ? $installed['version']['release'] : + $installed['version']; + if ($channelinfo) { + $packageinfo = array( + $channel, + $name, + $version_remote, + $version, + $desc, + ); + } else { + $packageinfo = array( + $name, + $version_remote, + $version, + $desc, + ); + } + $data['data'][$info['category']][] = $packageinfo; + } + + $this->ui->outputData($data, $command); + $this->config->set('default_channel', $channel); + return true; + } + + function &getDownloader($options) + { + if (!class_exists('PEAR_Downloader')) { + require_once 'PEAR/Downloader.php'; + } + $a = new PEAR_Downloader($this->ui, $options, $this->config); + return $a; + } + + function doDownload($command, $options, $params) + { + // make certain that dependencies are ignored + $options['downloadonly'] = 1; + + // eliminate error messages for preferred_state-related errors + /* TODO: Should be an option, but until now download does respect + prefered state */ + /* $options['ignorepreferred_state'] = 1; */ + // eliminate error messages for preferred_state-related errors + + $downloader = &$this->getDownloader($options); + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $e = $downloader->setDownloadDir(getcwd()); + PEAR::staticPopErrorHandling(); + if (PEAR::isError($e)) { + return $this->raiseError('Current directory is not writeable, cannot download'); + } + + $errors = array(); + $downloaded = array(); + $err = $downloader->download($params); + if (PEAR::isError($err)) { + return $err; + } + + $errors = $downloader->getErrorMsgs(); + if (count($errors)) { + foreach ($errors as $error) { + if ($error !== null) { + $this->ui->outputData($error); + } + } + + return $this->raiseError("$command failed"); + } + + $downloaded = $downloader->getDownloadedPackages(); + foreach ($downloaded as $pkg) { + $this->ui->outputData("File $pkg[file] downloaded", $command); + } + + return true; + } + + function downloadCallback($msg, $params = null) + { + if ($msg == 'done') { + $this->bytes_downloaded = $params; + } + } + + function doListUpgrades($command, $options, $params) + { + require_once 'PEAR/Common.php'; + if (isset($params[0]) && !is_array(PEAR_Common::betterStates($params[0]))) { + return $this->raiseError($params[0] . ' is not a valid state (stable/beta/alpha/devel/etc.) try "pear help list-upgrades"'); + } + + $savechannel = $channel = $this->config->get('default_channel'); + $reg = &$this->config->getRegistry(); + foreach ($reg->listChannels() as $channel) { + $inst = array_flip($reg->listPackages($channel)); + if (!count($inst)) { + continue; + } + + if ($channel == '__uri') { + continue; + } + + $this->config->set('default_channel', $channel); + $state = empty($params[0]) ? $this->config->get('preferred_state') : $params[0]; + + $caption = $channel . ' Available Upgrades'; + $chan = $reg->getChannel($channel); + if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) { + return $e; + } + + $latest = array(); + $base2 = false; + $preferred_mirror = $this->config->get('preferred_mirror'); + if ($chan->supportsREST($preferred_mirror) && + ( + ($base2 = $chan->getBaseURL('REST1.3', $preferred_mirror)) + || ($base = $chan->getBaseURL('REST1.0', $preferred_mirror)) + ) + + ) { + if ($base2) { + $rest = &$this->config->getREST('1.3', array()); + $base = $base2; + } else { + $rest = &$this->config->getREST('1.0', array()); + } + + if (empty($state) || $state == 'any') { + $state = false; + } else { + $caption .= ' (' . implode(', ', PEAR_Common::betterStates($state, true)) . ')'; + } + + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $latest = $rest->listLatestUpgrades($base, $state, $inst, $channel, $reg); + PEAR::staticPopErrorHandling(); + } + + if (PEAR::isError($latest)) { + $this->ui->outputData($latest->getMessage()); + continue; + } + + $caption .= ':'; + if (PEAR::isError($latest)) { + $this->config->set('default_channel', $savechannel); + return $latest; + } + + $data = array( + 'caption' => $caption, + 'border' => 1, + 'headline' => array('Channel', 'Package', 'Local', 'Remote', 'Size'), + 'channel' => $channel + ); + + foreach ((array)$latest as $pkg => $info) { + $package = strtolower($pkg); + if (!isset($inst[$package])) { + // skip packages we don't have installed + continue; + } + + extract($info); + $inst_version = $reg->packageInfo($package, 'version', $channel); + $inst_state = $reg->packageInfo($package, 'release_state', $channel); + if (version_compare("$version", "$inst_version", "le")) { + // installed version is up-to-date + continue; + } + + if ($filesize >= 20480) { + $filesize += 1024 - ($filesize % 1024); + $fs = sprintf("%dkB", $filesize / 1024); + } elseif ($filesize > 0) { + $filesize += 103 - ($filesize % 103); + $fs = sprintf("%.1fkB", $filesize / 1024.0); + } else { + $fs = " -"; // XXX center instead + } + + $data['data'][] = array($channel, $pkg, "$inst_version ($inst_state)", "$version ($state)", $fs); + } + + if (isset($options['channelinfo'])) { + if (empty($data['data'])) { + unset($data['headline']); + if (count($inst) == 0) { + $data['data'] = '(no packages installed)'; + } else { + $data['data'] = '(no upgrades available)'; + } + } + $this->ui->outputData($data, $command); + } else { + if (empty($data['data'])) { + $this->ui->outputData('Channel ' . $channel . ': No upgrades available'); + } else { + $this->ui->outputData($data, $command); + } + } + } + + $this->config->set('default_channel', $savechannel); + return true; + } + + function doClearCache($command, $options, $params) + { + $cache_dir = $this->config->get('cache_dir'); + $verbose = $this->config->get('verbose'); + $output = ''; + if (!file_exists($cache_dir) || !is_dir($cache_dir)) { + return $this->raiseError("$cache_dir does not exist or is not a directory"); + } + + if (!($dp = @opendir($cache_dir))) { + return $this->raiseError("opendir($cache_dir) failed: $php_errormsg"); + } + + if ($verbose >= 1) { + $output .= "reading directory $cache_dir\n"; + } + + $num = 0; + while ($ent = readdir($dp)) { + if (preg_match('/rest.cache(file|id)\\z/', $ent)) { + $path = $cache_dir . DIRECTORY_SEPARATOR . $ent; + if (file_exists($path)) { + $ok = @unlink($path); + } else { + $ok = false; + $php_errormsg = ''; + } + + if ($ok) { + if ($verbose >= 2) { + $output .= "deleted $path\n"; + } + $num++; + } elseif ($verbose >= 1) { + $output .= "failed to delete $path $php_errormsg\n"; + } + } + } + + closedir($dp); + if ($verbose >= 1) { + $output .= "$num cache entries cleared\n"; + } + + $this->ui->outputData(rtrim($output), $command); + return $num; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Command/Test.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Command/Test.php new file mode 100644 index 0000000..a59b1cf --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Command/Test.php @@ -0,0 +1,343 @@ + + * @author Martin Jansen + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 0.1 + */ + +/** + * base class + */ +require_once 'PEAR/Command/Common.php'; + +/** + * PEAR commands for login/logout + * + * @category pear + * @package PEAR + * @author Stig Bakken + * @author Martin Jansen + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 0.1 + */ + +class PEAR_Command_Test extends PEAR_Command_Common +{ + var $commands = array( + 'run-tests' => array( + 'summary' => 'Run Regression Tests', + 'function' => 'doRunTests', + 'shortcut' => 'rt', + 'options' => array( + 'recur' => array( + 'shortopt' => 'r', + 'doc' => 'Run tests in child directories, recursively. 4 dirs deep maximum', + ), + 'ini' => array( + 'shortopt' => 'i', + 'doc' => 'actual string of settings to pass to php in format " -d setting=blah"', + 'arg' => 'SETTINGS' + ), + 'realtimelog' => array( + 'shortopt' => 'l', + 'doc' => 'Log test runs/results as they are run', + ), + 'quiet' => array( + 'shortopt' => 'q', + 'doc' => 'Only display detail for failed tests', + ), + 'simple' => array( + 'shortopt' => 's', + 'doc' => 'Display simple output for all tests', + ), + 'package' => array( + 'shortopt' => 'p', + 'doc' => 'Treat parameters as installed packages from which to run tests', + ), + 'phpunit' => array( + 'shortopt' => 'u', + 'doc' => 'Search parameters for AllTests.php, and use that to run phpunit-based tests +If none is found, all .phpt tests will be tried instead.', + ), + 'tapoutput' => array( + 'shortopt' => 't', + 'doc' => 'Output run-tests.log in TAP-compliant format', + ), + 'cgi' => array( + 'shortopt' => 'c', + 'doc' => 'CGI php executable (needed for tests with POST/GET section)', + 'arg' => 'PHPCGI', + ), + 'coverage' => array( + 'shortopt' => 'x', + 'doc' => 'Generate a code coverage report (requires Xdebug 2.0.0+)', + ), + 'showdiff' => array( + 'shortopt' => 'd', + 'doc' => 'Output diff on test failure', + ), + ), + 'doc' => '[testfile|dir ...] +Run regression tests with PHP\'s regression testing script (run-tests.php).', + ), + ); + + var $output; + + /** + * PEAR_Command_Test constructor. + * + * @access public + */ + function __construct(&$ui, &$config) + { + parent::__construct($ui, $config); + } + + function doRunTests($command, $options, $params) + { + if (isset($options['phpunit']) && isset($options['tapoutput'])) { + return $this->raiseError('ERROR: cannot use both --phpunit and --tapoutput at the same time'); + } + + require_once 'PEAR/Common.php'; + require_once 'System.php'; + $log = new PEAR_Common; + $log->ui = &$this->ui; // slightly hacky, but it will work + $tests = array(); + $depth = isset($options['recur']) ? 14 : 1; + + if (!count($params)) { + $params[] = '.'; + } + + if (isset($options['package'])) { + $oldparams = $params; + $params = array(); + $reg = &$this->config->getRegistry(); + foreach ($oldparams as $param) { + $pname = $reg->parsePackageName($param, $this->config->get('default_channel')); + if (PEAR::isError($pname)) { + return $this->raiseError($pname); + } + + $package = &$reg->getPackage($pname['package'], $pname['channel']); + if (!$package) { + return PEAR::raiseError('Unknown package "' . + $reg->parsedPackageNameToString($pname) . '"'); + } + + $filelist = $package->getFilelist(); + foreach ($filelist as $name => $atts) { + if (isset($atts['role']) && $atts['role'] != 'test') { + continue; + } + + if (isset($options['phpunit']) && preg_match('/AllTests\.php\\z/i', $name)) { + $params[] = $atts['installed_as']; + continue; + } elseif (!preg_match('/\.phpt\\z/', $name)) { + continue; + } + $params[] = $atts['installed_as']; + } + } + } + + foreach ($params as $p) { + if (is_dir($p)) { + if (isset($options['phpunit'])) { + $dir = System::find(array($p, '-type', 'f', + '-maxdepth', $depth, + '-name', 'AllTests.php')); + if (count($dir)) { + foreach ($dir as $p) { + $p = realpath($p); + if (!count($tests) || + (count($tests) && strlen($p) < strlen($tests[0]))) { + // this is in a higher-level directory, use this one instead. + $tests = array($p); + } + } + } + continue; + } + + $args = array($p, '-type', 'f', '-name', '*.phpt'); + } else { + if (isset($options['phpunit'])) { + if (preg_match('/AllTests\.php\\z/i', $p)) { + $p = realpath($p); + if (!count($tests) || + (count($tests) && strlen($p) < strlen($tests[0]))) { + // this is in a higher-level directory, use this one instead. + $tests = array($p); + } + } + continue; + } + + if (file_exists($p) && preg_match('/\.phpt$/', $p)) { + $tests[] = $p; + continue; + } + + if (!preg_match('/\.phpt\\z/', $p)) { + $p .= '.phpt'; + } + + $args = array(dirname($p), '-type', 'f', '-name', $p); + } + + if (!isset($options['recur'])) { + $args[] = '-maxdepth'; + $args[] = 1; + } + + $dir = System::find($args); + $tests = array_merge($tests, $dir); + } + + $ini_settings = ''; + if (isset($options['ini'])) { + $ini_settings .= $options['ini']; + } + + if (isset($_ENV['TEST_PHP_INCLUDE_PATH'])) { + $ini_settings .= " -d include_path={$_ENV['TEST_PHP_INCLUDE_PATH']}"; + } + + if ($ini_settings) { + $this->ui->outputData('Using INI settings: "' . $ini_settings . '"'); + } + + $skipped = $passed = $failed = array(); + $tests_count = count($tests); + $this->ui->outputData('Running ' . $tests_count . ' tests', $command); + $start = time(); + if (isset($options['realtimelog']) && file_exists('run-tests.log')) { + unlink('run-tests.log'); + } + + if (isset($options['tapoutput'])) { + $tap = '1..' . $tests_count . "\n"; + } + + require_once 'PEAR/RunTest.php'; + $run = new PEAR_RunTest($log, $options); + $run->tests_count = $tests_count; + + if (isset($options['coverage']) && extension_loaded('xdebug')){ + $run->xdebug_loaded = true; + } else { + $run->xdebug_loaded = false; + } + + $j = $i = 1; + foreach ($tests as $t) { + if (isset($options['realtimelog'])) { + $fp = @fopen('run-tests.log', 'a'); + if ($fp) { + fwrite($fp, "Running test [$i / $tests_count] $t..."); + fclose($fp); + } + } + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + if (isset($options['phpunit'])) { + $result = $run->runPHPUnit($t, $ini_settings); + } else { + $result = $run->run($t, $ini_settings, $j); + } + PEAR::staticPopErrorHandling(); + if (PEAR::isError($result)) { + $this->ui->log($result->getMessage()); + continue; + } + + if (isset($options['tapoutput'])) { + $tap .= $result[0] . ' ' . $i . $result[1] . "\n"; + continue; + } + + if (isset($options['realtimelog'])) { + $fp = @fopen('run-tests.log', 'a'); + if ($fp) { + fwrite($fp, "$result\n"); + fclose($fp); + } + } + + if ($result == 'FAILED') { + $failed[] = $t; + } + if ($result == 'PASSED') { + $passed[] = $t; + } + if ($result == 'SKIPPED') { + $skipped[] = $t; + } + + $j++; + } + + $total = date('i:s', time() - $start); + if (isset($options['tapoutput'])) { + $fp = @fopen('run-tests.log', 'w'); + if ($fp) { + fwrite($fp, $tap, strlen($tap)); + fclose($fp); + $this->ui->outputData('wrote TAP-format log to "' .realpath('run-tests.log') . + '"', $command); + } + } else { + if (count($failed)) { + $output = "TOTAL TIME: $total\n"; + $output .= count($passed) . " PASSED TESTS\n"; + $output .= count($skipped) . " SKIPPED TESTS\n"; + $output .= count($failed) . " FAILED TESTS:\n"; + foreach ($failed as $failure) { + $output .= $failure . "\n"; + } + + $mode = isset($options['realtimelog']) ? 'a' : 'w'; + $fp = @fopen('run-tests.log', $mode); + + if ($fp) { + fwrite($fp, $output, strlen($output)); + fclose($fp); + $this->ui->outputData('wrote log to "' . realpath('run-tests.log') . '"', $command); + } + } elseif (file_exists('run-tests.log') && !is_dir('run-tests.log')) { + @unlink('run-tests.log'); + } + } + $this->ui->outputData('TOTAL TIME: ' . $total); + $this->ui->outputData(count($passed) . ' PASSED TESTS', $command); + $this->ui->outputData(count($skipped) . ' SKIPPED TESTS', $command); + if (count($failed)) { + $this->ui->outputData(count($failed) . ' FAILED TESTS:', $command); + foreach ($failed as $failure) { + $this->ui->outputData($failure, $command); + } + } + + if (count($failed) == 0) { + return true; + } + return $this->raiseError('Some tests failed'); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Common.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Common.php new file mode 100644 index 0000000..5fe76ad --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Common.php @@ -0,0 +1,838 @@ + + * @author Tomas V. V. Cox + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 0.1.0 + * @deprecated File deprecated since Release 1.4.0a1 + */ + +/** + * Include error handling + */ +require_once 'PEAR.php'; + +/** + * PEAR_Common error when an invalid PHP file is passed to PEAR_Common::analyzeSourceCode() + */ +define('PEAR_COMMON_ERROR_INVALIDPHP', 1); +define('_PEAR_COMMON_PACKAGE_NAME_PREG', '[A-Za-z][a-zA-Z0-9_]+'); +define('PEAR_COMMON_PACKAGE_NAME_PREG', '/^' . _PEAR_COMMON_PACKAGE_NAME_PREG . '\\z/'); + +// this should allow: 1, 1.0, 1.0RC1, 1.0dev, 1.0dev123234234234, 1.0a1, 1.0b1, 1.0pl1 +define('_PEAR_COMMON_PACKAGE_VERSION_PREG', '\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?'); +define('PEAR_COMMON_PACKAGE_VERSION_PREG', '/^' . _PEAR_COMMON_PACKAGE_VERSION_PREG . '\\z/i'); + +// XXX far from perfect :-) +define('_PEAR_COMMON_PACKAGE_DOWNLOAD_PREG', '(' . _PEAR_COMMON_PACKAGE_NAME_PREG . + ')(-([.0-9a-zA-Z]+))?'); +define('PEAR_COMMON_PACKAGE_DOWNLOAD_PREG', '/^' . _PEAR_COMMON_PACKAGE_DOWNLOAD_PREG . + '\\z/'); + +define('_PEAR_CHANNELS_NAME_PREG', '[A-Za-z][a-zA-Z0-9\.]+'); +define('PEAR_CHANNELS_NAME_PREG', '/^' . _PEAR_CHANNELS_NAME_PREG . '\\z/'); + +// this should allow any dns or IP address, plus a path - NO UNDERSCORES ALLOWED +define('_PEAR_CHANNELS_SERVER_PREG', '[a-zA-Z0-9\-]+(?:\.[a-zA-Z0-9\-]+)*(\/[a-zA-Z0-9\-]+)*'); +define('PEAR_CHANNELS_SERVER_PREG', '/^' . _PEAR_CHANNELS_SERVER_PREG . '\\z/i'); + +define('_PEAR_CHANNELS_PACKAGE_PREG', '(' ._PEAR_CHANNELS_SERVER_PREG . ')\/(' + . _PEAR_COMMON_PACKAGE_NAME_PREG . ')'); +define('PEAR_CHANNELS_PACKAGE_PREG', '/^' . _PEAR_CHANNELS_PACKAGE_PREG . '\\z/i'); + +define('_PEAR_COMMON_CHANNEL_DOWNLOAD_PREG', '(' . _PEAR_CHANNELS_NAME_PREG . ')::(' + . _PEAR_COMMON_PACKAGE_NAME_PREG . ')(-([.0-9a-zA-Z]+))?'); +define('PEAR_COMMON_CHANNEL_DOWNLOAD_PREG', '/^' . _PEAR_COMMON_CHANNEL_DOWNLOAD_PREG . '\\z/'); + +/** + * List of temporary files and directories registered by + * PEAR_Common::addTempFile(). + * @var array + */ +$GLOBALS['_PEAR_Common_tempfiles'] = array(); + +/** + * Valid maintainer roles + * @var array + */ +$GLOBALS['_PEAR_Common_maintainer_roles'] = array('lead','developer','contributor','helper'); + +/** + * Valid release states + * @var array + */ +$GLOBALS['_PEAR_Common_release_states'] = array('alpha','beta','stable','snapshot','devel'); + +/** + * Valid dependency types + * @var array + */ +$GLOBALS['_PEAR_Common_dependency_types'] = array('pkg','ext','php','prog','ldlib','rtlib','os','websrv','sapi'); + +/** + * Valid dependency relations + * @var array + */ +$GLOBALS['_PEAR_Common_dependency_relations'] = array('has','eq','lt','le','gt','ge','not', 'ne'); + +/** + * Valid file roles + * @var array + */ +$GLOBALS['_PEAR_Common_file_roles'] = array('php','ext','test','doc','data','src','script'); + +/** + * Valid replacement types + * @var array + */ +$GLOBALS['_PEAR_Common_replacement_types'] = array('php-const', 'pear-config', 'package-info'); + +/** + * Valid "provide" types + * @var array + */ +$GLOBALS['_PEAR_Common_provide_types'] = array('ext', 'prog', 'class', 'function', 'feature', 'api'); + +/** + * Valid "provide" types + * @var array + */ +$GLOBALS['_PEAR_Common_script_phases'] = array('pre-install', 'post-install', 'pre-uninstall', 'post-uninstall', 'pre-build', 'post-build', 'pre-configure', 'post-configure', 'pre-setup', 'post-setup'); + +/** + * Class providing common functionality for PEAR administration classes. + * @category pear + * @package PEAR + * @author Stig Bakken + * @author Tomas V. V. Cox + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + * @deprecated This class will disappear, and its components will be spread + * into smaller classes, like the AT&T breakup, as of Release 1.4.0a1 + */ +class PEAR_Common extends PEAR +{ + /** + * User Interface object (PEAR_Frontend_* class). If null, + * the log() method uses print. + * @var object + */ + var $ui = null; + + /** + * Configuration object (PEAR_Config). + * @var PEAR_Config + */ + var $config = null; + + /** stack of elements, gives some sort of XML context */ + var $element_stack = array(); + + /** name of currently parsed XML element */ + var $current_element; + + /** array of attributes of the currently parsed XML element */ + var $current_attributes = array(); + + /** assoc with information about a package */ + var $pkginfo = array(); + + var $current_path = null; + + /** + * Flag variable used to mark a valid package file + * @var boolean + * @access private + */ + var $_validPackageFile; + + /** + * PEAR_Common constructor + * + * @access public + */ + function __construct() + { + parent::__construct(); + $this->config = &PEAR_Config::singleton(); + $this->debug = $this->config->get('verbose'); + } + + /** + * PEAR_Common destructor + * + * @access private + */ + function _PEAR_Common() + { + // doesn't work due to bug #14744 + //$tempfiles = $this->_tempfiles; + $tempfiles =& $GLOBALS['_PEAR_Common_tempfiles']; + while ($file = array_shift($tempfiles)) { + if (@is_dir($file)) { + if (!class_exists('System')) { + require_once 'System.php'; + } + + System::rm(array('-rf', $file)); + } elseif (file_exists($file)) { + unlink($file); + } + } + } + + /** + * Register a temporary file or directory. When the destructor is + * executed, all registered temporary files and directories are + * removed. + * + * @param string $file name of file or directory + * + * @return void + * + * @access public + */ + function addTempFile($file) + { + if (!class_exists('PEAR_Frontend')) { + require_once 'PEAR/Frontend.php'; + } + PEAR_Frontend::addTempFile($file); + } + + /** + * Wrapper to System::mkDir(), creates a directory as well as + * any necessary parent directories. + * + * @param string $dir directory name + * + * @return bool TRUE on success, or a PEAR error + * + * @access public + */ + function mkDirHier($dir) + { + // Only used in Installer - move it there ? + $this->log(2, "+ create dir $dir"); + if (!class_exists('System')) { + require_once 'System.php'; + } + return System::mkDir(array('-p', $dir)); + } + + /** + * Logging method. + * + * @param int $level log level (0 is quiet, higher is noisier) + * @param string $msg message to write to the log + * + * @return void + */ + public function log($level, $msg, $append_crlf = true) + { + if ($this->debug >= $level) { + if (!class_exists('PEAR_Frontend')) { + require_once 'PEAR/Frontend.php'; + } + + $ui = &PEAR_Frontend::singleton(); + if (is_a($ui, 'PEAR_Frontend')) { + $ui->log($msg, $append_crlf); + } else { + print "$msg\n"; + } + } + } + + /** + * Create and register a temporary directory. + * + * @param string $tmpdir (optional) Directory to use as tmpdir. + * Will use system defaults (for example + * /tmp or c:\windows\temp) if not specified + * + * @return string name of created directory + * + * @access public + */ + function mkTempDir($tmpdir = '') + { + $topt = $tmpdir ? array('-t', $tmpdir) : array(); + $topt = array_merge($topt, array('-d', 'pear')); + if (!class_exists('System')) { + require_once 'System.php'; + } + + if (!$tmpdir = System::mktemp($topt)) { + return false; + } + + $this->addTempFile($tmpdir); + return $tmpdir; + } + + /** + * Set object that represents the frontend to be used. + * + * @param object Reference of the frontend object + * @return void + * @access public + */ + function setFrontendObject(&$ui) + { + $this->ui = &$ui; + } + + /** + * Return an array containing all of the states that are more stable than + * or equal to the passed in state + * + * @param string Release state + * @param boolean Determines whether to include $state in the list + * @return false|array False if $state is not a valid release state + */ + function betterStates($state, $include = false) + { + static $states = array('snapshot', 'devel', 'alpha', 'beta', 'stable'); + $i = array_search($state, $states); + if ($i === false) { + return false; + } + if ($include) { + $i--; + } + return array_slice($states, $i + 1); + } + + /** + * Get the valid roles for a PEAR package maintainer + * + * @return array + */ + public static function getUserRoles() + { + return $GLOBALS['_PEAR_Common_maintainer_roles']; + } + + /** + * Get the valid package release states of packages + * + * @return array + */ + public static function getReleaseStates() + { + return $GLOBALS['_PEAR_Common_release_states']; + } + + /** + * Get the implemented dependency types (php, ext, pkg etc.) + * + * @return array + */ + public static function getDependencyTypes() + { + return $GLOBALS['_PEAR_Common_dependency_types']; + } + + /** + * Get the implemented dependency relations (has, lt, ge etc.) + * + * @return array + */ + public static function getDependencyRelations() + { + return $GLOBALS['_PEAR_Common_dependency_relations']; + } + + /** + * Get the implemented file roles + * + * @return array + */ + public static function getFileRoles() + { + return $GLOBALS['_PEAR_Common_file_roles']; + } + + /** + * Get the implemented file replacement types in + * + * @return array + */ + public static function getReplacementTypes() + { + return $GLOBALS['_PEAR_Common_replacement_types']; + } + + /** + * Get the implemented file replacement types in + * + * @return array + */ + public static function getProvideTypes() + { + return $GLOBALS['_PEAR_Common_provide_types']; + } + + /** + * Get the implemented file replacement types in + * + * @return array + */ + public static function getScriptPhases() + { + return $GLOBALS['_PEAR_Common_script_phases']; + } + + /** + * Test whether a string contains a valid package name. + * + * @param string $name the package name to test + * + * @return bool + * + * @access public + */ + function validPackageName($name) + { + return (bool)preg_match(PEAR_COMMON_PACKAGE_NAME_PREG, $name); + } + + /** + * Test whether a string contains a valid package version. + * + * @param string $ver the package version to test + * + * @return bool + * + * @access public + */ + function validPackageVersion($ver) + { + return (bool)preg_match(PEAR_COMMON_PACKAGE_VERSION_PREG, $ver); + } + + /** + * @param string $path relative or absolute include path + * @return boolean + */ + public static function isIncludeable($path) + { + if (file_exists($path) && is_readable($path)) { + return true; + } + + $ipath = explode(PATH_SEPARATOR, ini_get('include_path')); + foreach ($ipath as $include) { + $test = realpath($include . DIRECTORY_SEPARATOR . $path); + if (file_exists($test) && is_readable($test)) { + return true; + } + } + + return false; + } + + function _postProcessChecks($pf) + { + if (!PEAR::isError($pf)) { + return $this->_postProcessValidPackagexml($pf); + } + + $errs = $pf->getUserinfo(); + if (is_array($errs)) { + foreach ($errs as $error) { + $e = $this->raiseError($error['message'], $error['code'], null, null, $error); + } + } + + return $pf; + } + + /** + * Returns information about a package file. Expects the name of + * a gzipped tar file as input. + * + * @param string $file name of .tgz file + * + * @return array array with package information + * + * @access public + * @deprecated use PEAR_PackageFile->fromTgzFile() instead + * + */ + function infoFromTgzFile($file) + { + $packagefile = new PEAR_PackageFile($this->config); + $pf = &$packagefile->fromTgzFile($file, PEAR_VALIDATE_NORMAL); + return $this->_postProcessChecks($pf); + } + + /** + * Returns information about a package file. Expects the name of + * a package xml file as input. + * + * @param string $descfile name of package xml file + * + * @return array array with package information + * + * @access public + * @deprecated use PEAR_PackageFile->fromPackageFile() instead + * + */ + function infoFromDescriptionFile($descfile) + { + $packagefile = new PEAR_PackageFile($this->config); + $pf = &$packagefile->fromPackageFile($descfile, PEAR_VALIDATE_NORMAL); + return $this->_postProcessChecks($pf); + } + + /** + * Returns information about a package file. Expects the contents + * of a package xml file as input. + * + * @param string $data contents of package.xml file + * + * @return array array with package information + * + * @access public + * @deprecated use PEAR_PackageFile->fromXmlstring() instead + * + */ + function infoFromString($data) + { + $packagefile = new PEAR_PackageFile($this->config); + $pf = &$packagefile->fromXmlString($data, PEAR_VALIDATE_NORMAL, false); + return $this->_postProcessChecks($pf); + } + + /** + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * @return array + */ + function _postProcessValidPackagexml(&$pf) + { + if (!is_a($pf, 'PEAR_PackageFile_v2')) { + $this->pkginfo = $pf->toArray(); + return $this->pkginfo; + } + + // sort of make this into a package.xml 1.0-style array + // changelog is not converted to old format. + $arr = $pf->toArray(true); + $arr = array_merge($arr, $arr['old']); + unset($arr['old'], $arr['xsdversion'], $arr['contents'], $arr['compatible'], + $arr['channel'], $arr['uri'], $arr['dependencies'], $arr['phprelease'], + $arr['extsrcrelease'], $arr['zendextsrcrelease'], $arr['extbinrelease'], + $arr['zendextbinrelease'], $arr['bundle'], $arr['lead'], $arr['developer'], + $arr['helper'], $arr['contributor']); + $arr['filelist'] = $pf->getFilelist(); + $this->pkginfo = $arr; + return $arr; + } + + /** + * Returns package information from different sources + * + * This method is able to extract information about a package + * from a .tgz archive or from a XML package definition file. + * + * @access public + * @param string Filename of the source ('package.xml', '.tgz') + * @return string + * @deprecated use PEAR_PackageFile->fromAnyFile() instead + */ + function infoFromAny($info) + { + if (is_string($info) && file_exists($info)) { + $packagefile = new PEAR_PackageFile($this->config); + $pf = &$packagefile->fromAnyFile($info, PEAR_VALIDATE_NORMAL); + if (PEAR::isError($pf)) { + $errs = $pf->getUserinfo(); + if (is_array($errs)) { + foreach ($errs as $error) { + $e = $this->raiseError($error['message'], $error['code'], null, null, $error); + } + } + + return $pf; + } + + return $this->_postProcessValidPackagexml($pf); + } + + return $info; + } + + /** + * Return an XML document based on the package info (as returned + * by the PEAR_Common::infoFrom* methods). + * + * @param array $pkginfo package info + * + * @return string XML data + * + * @access public + * @deprecated use a PEAR_PackageFile_v* object's generator instead + */ + function xmlFromInfo($pkginfo) + { + $config = &PEAR_Config::singleton(); + $packagefile = new PEAR_PackageFile($config); + $pf = &$packagefile->fromArray($pkginfo); + $gen = &$pf->getDefaultGenerator(); + return $gen->toXml(PEAR_VALIDATE_PACKAGING); + } + + /** + * Validate XML package definition file. + * + * @param string $info Filename of the package archive or of the + * package definition file + * @param array $errors Array that will contain the errors + * @param array $warnings Array that will contain the warnings + * @param string $dir_prefix (optional) directory where source files + * may be found, or empty if they are not available + * @access public + * @return boolean + * @deprecated use the validation of PEAR_PackageFile objects + */ + function validatePackageInfo($info, &$errors, &$warnings, $dir_prefix = '') + { + $config = &PEAR_Config::singleton(); + $packagefile = new PEAR_PackageFile($config); + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + if (strpos($info, 'fromXmlString($info, PEAR_VALIDATE_NORMAL, ''); + } else { + $pf = &$packagefile->fromAnyFile($info, PEAR_VALIDATE_NORMAL); + } + + PEAR::staticPopErrorHandling(); + if (PEAR::isError($pf)) { + $errs = $pf->getUserinfo(); + if (is_array($errs)) { + foreach ($errs as $error) { + if ($error['level'] == 'error') { + $errors[] = $error['message']; + } else { + $warnings[] = $error['message']; + } + } + } + + return false; + } + + return true; + } + + /** + * Build a "provides" array from data returned by + * analyzeSourceCode(). The format of the built array is like + * this: + * + * array( + * 'class;MyClass' => 'array('type' => 'class', 'name' => 'MyClass'), + * ... + * ) + * + * + * @param array $srcinfo array with information about a source file + * as returned by the analyzeSourceCode() method. + * + * @return void + * + * @access public + * + */ + function buildProvidesArray($srcinfo) + { + $file = basename($srcinfo['source_file']); + $pn = ''; + if (isset($this->_packageName)) { + $pn = $this->_packageName; + } + + $pnl = strlen($pn); + foreach ($srcinfo['declared_classes'] as $class) { + $key = "class;$class"; + if (isset($this->pkginfo['provides'][$key])) { + continue; + } + + $this->pkginfo['provides'][$key] = + array('file'=> $file, 'type' => 'class', 'name' => $class); + if (isset($srcinfo['inheritance'][$class])) { + $this->pkginfo['provides'][$key]['extends'] = + $srcinfo['inheritance'][$class]; + } + } + + foreach ($srcinfo['declared_methods'] as $class => $methods) { + foreach ($methods as $method) { + $function = "$class::$method"; + $key = "function;$function"; + if ($method{0} == '_' || !strcasecmp($method, $class) || + isset($this->pkginfo['provides'][$key])) { + continue; + } + + $this->pkginfo['provides'][$key] = + array('file'=> $file, 'type' => 'function', 'name' => $function); + } + } + + foreach ($srcinfo['declared_functions'] as $function) { + $key = "function;$function"; + if ($function{0} == '_' || isset($this->pkginfo['provides'][$key])) { + continue; + } + + if (!strstr($function, '::') && strncasecmp($function, $pn, $pnl)) { + $warnings[] = "in1 " . $file . ": function \"$function\" not prefixed with package name \"$pn\""; + } + + $this->pkginfo['provides'][$key] = + array('file'=> $file, 'type' => 'function', 'name' => $function); + } + } + + /** + * Analyze the source code of the given PHP file + * + * @param string Filename of the PHP file + * @return mixed + * @access public + */ + function analyzeSourceCode($file) + { + if (!class_exists('PEAR_PackageFile_v2_Validator')) { + require_once 'PEAR/PackageFile/v2/Validator.php'; + } + + $a = new PEAR_PackageFile_v2_Validator; + return $a->analyzeSourceCode($file); + } + + function detectDependencies($any, $status_callback = null) + { + if (!function_exists("token_get_all")) { + return false; + } + + if (PEAR::isError($info = $this->infoFromAny($any))) { + return $this->raiseError($info); + } + + if (!is_array($info)) { + return false; + } + + $deps = array(); + $used_c = $decl_c = $decl_f = $decl_m = array(); + foreach ($info['filelist'] as $file => $fa) { + $tmp = $this->analyzeSourceCode($file); + $used_c = @array_merge($used_c, $tmp['used_classes']); + $decl_c = @array_merge($decl_c, $tmp['declared_classes']); + $decl_f = @array_merge($decl_f, $tmp['declared_functions']); + $decl_m = @array_merge($decl_m, $tmp['declared_methods']); + $inheri = @array_merge($inheri, $tmp['inheritance']); + } + + $used_c = array_unique($used_c); + $decl_c = array_unique($decl_c); + $undecl_c = array_diff($used_c, $decl_c); + + return array('used_classes' => $used_c, + 'declared_classes' => $decl_c, + 'declared_methods' => $decl_m, + 'declared_functions' => $decl_f, + 'undeclared_classes' => $undecl_c, + 'inheritance' => $inheri, + ); + } + + /** + * Download a file through HTTP. Considers suggested file name in + * Content-disposition: header and can run a callback function for + * different events. The callback will be called with two + * parameters: the callback type, and parameters. The implemented + * callback types are: + * + * 'setup' called at the very beginning, parameter is a UI object + * that should be used for all output + * 'message' the parameter is a string with an informational message + * 'saveas' may be used to save with a different file name, the + * parameter is the filename that is about to be used. + * If a 'saveas' callback returns a non-empty string, + * that file name will be used as the filename instead. + * Note that $save_dir will not be affected by this, only + * the basename of the file. + * 'start' download is starting, parameter is number of bytes + * that are expected, or -1 if unknown + * 'bytesread' parameter is the number of bytes read so far + * 'done' download is complete, parameter is the total number + * of bytes read + * 'connfailed' if the TCP connection fails, this callback is called + * with array(host,port,errno,errmsg) + * 'writefailed' if writing to disk fails, this callback is called + * with array(destfile,errmsg) + * + * If an HTTP proxy has been configured (http_proxy PEAR_Config + * setting), the proxy will be used. + * + * @param string $url the URL to download + * @param object $ui PEAR_Frontend_* instance + * @param object $config PEAR_Config instance + * @param string $save_dir (optional) directory to save file in + * @param mixed $callback (optional) function/method to call for status + * updates + * @param false|string|array $lastmodified header values to check against + * for caching + * use false to return the header + * values from this download + * @param false|array $accept Accept headers to send + * @param false|string $channel Channel to use for retrieving + * authentication + * + * @return mixed Returns the full path of the downloaded file or a PEAR + * error on failure. If the error is caused by + * socket-related errors, the error object will + * have the fsockopen error code available through + * getCode(). If caching is requested, then return the header + * values. + * If $lastmodified was given and the there are no changes, + * boolean false is returned. + * + * @access public + */ + function downloadHttp( + $url, &$ui, $save_dir = '.', $callback = null, $lastmodified = null, + $accept = false, $channel = false + ) { + if (!class_exists('PEAR_Downloader')) { + require_once 'PEAR/Downloader.php'; + } + return PEAR_Downloader::_downloadHttp( + $this, $url, $ui, $save_dir, $callback, $lastmodified, + $accept, $channel + ); + } +} + +require_once 'PEAR/Config.php'; +require_once 'PEAR/PackageFile.php'; diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Config.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Config.php new file mode 100644 index 0000000..3856acb --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Config.php @@ -0,0 +1,2131 @@ + + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 0.1 + */ + +/** + * Required for error handling + */ +require_once 'PEAR.php'; +require_once 'PEAR/Registry.php'; +require_once 'PEAR/Installer/Role.php'; +require_once 'System.php'; + +/** + * Last created PEAR_Config instance. + * @var object + */ +$GLOBALS['_PEAR_Config_instance'] = null; +if (!defined('PEAR_INSTALL_DIR') || !PEAR_INSTALL_DIR) { + $PEAR_INSTALL_DIR = PHP_LIBDIR . DIRECTORY_SEPARATOR . 'pear'; +} else { + $PEAR_INSTALL_DIR = PEAR_INSTALL_DIR; +} + +// Below we define constants with default values for all configuration +// parameters except username/password. All of them can have their +// defaults set through environment variables. The reason we use the +// PHP_ prefix is for some security, PHP protects environment +// variables starting with PHP_*. + +// default channel and preferred mirror is based on whether we are invoked through +// the "pear" or the "pecl" command +if (!defined('PEAR_RUNTYPE')) { + define('PEAR_RUNTYPE', 'pear'); +} + +if (PEAR_RUNTYPE == 'pear') { + define('PEAR_CONFIG_DEFAULT_CHANNEL', 'pear.php.net'); +} else { + define('PEAR_CONFIG_DEFAULT_CHANNEL', 'pecl.php.net'); +} + +if (getenv('PHP_PEAR_SYSCONF_DIR')) { + define('PEAR_CONFIG_SYSCONFDIR', getenv('PHP_PEAR_SYSCONF_DIR')); +} elseif (getenv('SystemRoot')) { + define('PEAR_CONFIG_SYSCONFDIR', getenv('SystemRoot')); +} else { + define('PEAR_CONFIG_SYSCONFDIR', PHP_SYSCONFDIR); +} + +// Default for master_server +if (getenv('PHP_PEAR_MASTER_SERVER')) { + define('PEAR_CONFIG_DEFAULT_MASTER_SERVER', getenv('PHP_PEAR_MASTER_SERVER')); +} else { + define('PEAR_CONFIG_DEFAULT_MASTER_SERVER', 'pear.php.net'); +} + +// Default for http_proxy +if (getenv('PHP_PEAR_HTTP_PROXY')) { + define('PEAR_CONFIG_DEFAULT_HTTP_PROXY', getenv('PHP_PEAR_HTTP_PROXY')); +} elseif (getenv('http_proxy')) { + define('PEAR_CONFIG_DEFAULT_HTTP_PROXY', getenv('http_proxy')); +} else { + define('PEAR_CONFIG_DEFAULT_HTTP_PROXY', ''); +} + +// Default for php_dir +if (getenv('PHP_PEAR_INSTALL_DIR')) { + define('PEAR_CONFIG_DEFAULT_PHP_DIR', getenv('PHP_PEAR_INSTALL_DIR')); +} else { + if (@file_exists($PEAR_INSTALL_DIR) && is_dir($PEAR_INSTALL_DIR)) { + define('PEAR_CONFIG_DEFAULT_PHP_DIR', $PEAR_INSTALL_DIR); + } else { + define('PEAR_CONFIG_DEFAULT_PHP_DIR', $PEAR_INSTALL_DIR); + } +} + +// Default for metadata_dir +if (getenv('PHP_PEAR_METADATA_DIR')) { + define('PEAR_CONFIG_DEFAULT_METADATA_DIR', getenv('PHP_PEAR_METADATA_DIR')); +} else { + define('PEAR_CONFIG_DEFAULT_METADATA_DIR', ''); +} + +// Default for ext_dir +if (getenv('PHP_PEAR_EXTENSION_DIR')) { + define('PEAR_CONFIG_DEFAULT_EXT_DIR', getenv('PHP_PEAR_EXTENSION_DIR')); +} else { + if (ini_get('extension_dir')) { + define('PEAR_CONFIG_DEFAULT_EXT_DIR', ini_get('extension_dir')); + } elseif (defined('PEAR_EXTENSION_DIR') && + file_exists(PEAR_EXTENSION_DIR) && is_dir(PEAR_EXTENSION_DIR)) { + define('PEAR_CONFIG_DEFAULT_EXT_DIR', PEAR_EXTENSION_DIR); + } elseif (defined('PHP_EXTENSION_DIR')) { + define('PEAR_CONFIG_DEFAULT_EXT_DIR', PHP_EXTENSION_DIR); + } else { + define('PEAR_CONFIG_DEFAULT_EXT_DIR', '.'); + } +} + +// Default for doc_dir +if (getenv('PHP_PEAR_DOC_DIR')) { + define('PEAR_CONFIG_DEFAULT_DOC_DIR', getenv('PHP_PEAR_DOC_DIR')); +} else { + define('PEAR_CONFIG_DEFAULT_DOC_DIR', + $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'docs'); +} + +// Default for bin_dir +if (getenv('PHP_PEAR_BIN_DIR')) { + define('PEAR_CONFIG_DEFAULT_BIN_DIR', getenv('PHP_PEAR_BIN_DIR')); +} else { + define('PEAR_CONFIG_DEFAULT_BIN_DIR', PHP_BINDIR); +} + +// Default for data_dir +if (getenv('PHP_PEAR_DATA_DIR')) { + define('PEAR_CONFIG_DEFAULT_DATA_DIR', getenv('PHP_PEAR_DATA_DIR')); +} else { + define('PEAR_CONFIG_DEFAULT_DATA_DIR', + $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'data'); +} + +// Default for cfg_dir +if (getenv('PHP_PEAR_CFG_DIR')) { + define('PEAR_CONFIG_DEFAULT_CFG_DIR', getenv('PHP_PEAR_CFG_DIR')); +} else { + define('PEAR_CONFIG_DEFAULT_CFG_DIR', + $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'cfg'); +} + +// Default for www_dir +if (getenv('PHP_PEAR_WWW_DIR')) { + define('PEAR_CONFIG_DEFAULT_WWW_DIR', getenv('PHP_PEAR_WWW_DIR')); +} else { + define('PEAR_CONFIG_DEFAULT_WWW_DIR', + $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'www'); +} + +// Default for man_dir +if (getenv('PHP_PEAR_MAN_DIR')) { + define('PEAR_CONFIG_DEFAULT_MAN_DIR', getenv('PHP_PEAR_MAN_DIR')); +} else { + if (defined('PHP_MANDIR')) { // Added in PHP5.3.7 + define('PEAR_CONFIG_DEFAULT_MAN_DIR', PHP_MANDIR); + } else { + define('PEAR_CONFIG_DEFAULT_MAN_DIR', PHP_PREFIX . DIRECTORY_SEPARATOR . + 'local' . DIRECTORY_SEPARATOR .'man'); + } +} + +// Default for test_dir +if (getenv('PHP_PEAR_TEST_DIR')) { + define('PEAR_CONFIG_DEFAULT_TEST_DIR', getenv('PHP_PEAR_TEST_DIR')); +} else { + define('PEAR_CONFIG_DEFAULT_TEST_DIR', + $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'tests'); +} + +// Default for temp_dir +if (getenv('PHP_PEAR_TEMP_DIR')) { + define('PEAR_CONFIG_DEFAULT_TEMP_DIR', getenv('PHP_PEAR_TEMP_DIR')); +} else { + define('PEAR_CONFIG_DEFAULT_TEMP_DIR', + System::tmpdir() . DIRECTORY_SEPARATOR . 'pear' . + DIRECTORY_SEPARATOR . 'temp'); +} + +// Default for cache_dir +if (getenv('PHP_PEAR_CACHE_DIR')) { + define('PEAR_CONFIG_DEFAULT_CACHE_DIR', getenv('PHP_PEAR_CACHE_DIR')); +} else { + define('PEAR_CONFIG_DEFAULT_CACHE_DIR', + System::tmpdir() . DIRECTORY_SEPARATOR . 'pear' . + DIRECTORY_SEPARATOR . 'cache'); +} + +// Default for download_dir +if (getenv('PHP_PEAR_DOWNLOAD_DIR')) { + define('PEAR_CONFIG_DEFAULT_DOWNLOAD_DIR', getenv('PHP_PEAR_DOWNLOAD_DIR')); +} else { + define('PEAR_CONFIG_DEFAULT_DOWNLOAD_DIR', + System::tmpdir() . DIRECTORY_SEPARATOR . 'pear' . + DIRECTORY_SEPARATOR . 'download'); +} + +// Default for php_bin +if (getenv('PHP_PEAR_PHP_BIN')) { + define('PEAR_CONFIG_DEFAULT_PHP_BIN', getenv('PHP_PEAR_PHP_BIN')); +} else { + define('PEAR_CONFIG_DEFAULT_PHP_BIN', PEAR_CONFIG_DEFAULT_BIN_DIR. + DIRECTORY_SEPARATOR.'php'.(OS_WINDOWS ? '.exe' : '')); +} + +// Default for verbose +if (getenv('PHP_PEAR_VERBOSE')) { + define('PEAR_CONFIG_DEFAULT_VERBOSE', getenv('PHP_PEAR_VERBOSE')); +} else { + define('PEAR_CONFIG_DEFAULT_VERBOSE', 1); +} + +// Default for preferred_state +if (getenv('PHP_PEAR_PREFERRED_STATE')) { + define('PEAR_CONFIG_DEFAULT_PREFERRED_STATE', getenv('PHP_PEAR_PREFERRED_STATE')); +} else { + define('PEAR_CONFIG_DEFAULT_PREFERRED_STATE', 'stable'); +} + +// Default for umask +if (getenv('PHP_PEAR_UMASK')) { + define('PEAR_CONFIG_DEFAULT_UMASK', getenv('PHP_PEAR_UMASK')); +} else { + define('PEAR_CONFIG_DEFAULT_UMASK', decoct(umask())); +} + +// Default for cache_ttl +if (getenv('PHP_PEAR_CACHE_TTL')) { + define('PEAR_CONFIG_DEFAULT_CACHE_TTL', getenv('PHP_PEAR_CACHE_TTL')); +} else { + define('PEAR_CONFIG_DEFAULT_CACHE_TTL', 3600); +} + +// Default for sig_type +if (getenv('PHP_PEAR_SIG_TYPE')) { + define('PEAR_CONFIG_DEFAULT_SIG_TYPE', getenv('PHP_PEAR_SIG_TYPE')); +} else { + define('PEAR_CONFIG_DEFAULT_SIG_TYPE', 'gpg'); +} + +// Default for sig_bin +if (getenv('PHP_PEAR_SIG_BIN')) { + define('PEAR_CONFIG_DEFAULT_SIG_BIN', getenv('PHP_PEAR_SIG_BIN')); +} else { + define('PEAR_CONFIG_DEFAULT_SIG_BIN', + System::which( + 'gpg', OS_WINDOWS ? 'c:\gnupg\gpg.exe' : '/usr/local/bin/gpg')); +} + +// Default for sig_keydir +if (getenv('PHP_PEAR_SIG_KEYDIR')) { + define('PEAR_CONFIG_DEFAULT_SIG_KEYDIR', getenv('PHP_PEAR_SIG_KEYDIR')); +} else { + define('PEAR_CONFIG_DEFAULT_SIG_KEYDIR', + PEAR_CONFIG_SYSCONFDIR . DIRECTORY_SEPARATOR . 'pearkeys'); +} + +/** + * This is a class for storing configuration data, keeping track of + * which are system-defined, user-defined or defaulted. + * @category pear + * @package PEAR + * @author Stig Bakken + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 0.1 + */ +class PEAR_Config extends PEAR +{ + /** + * Array of config files used. + * + * @var array layer => config file + */ + var $files = array( + 'system' => '', + 'user' => '', + ); + + var $layers = array(); + + /** + * Configuration data, two-dimensional array where the first + * dimension is the config layer ('user', 'system' and 'default'), + * and the second dimension is keyname => value. + * + * The order in the first dimension is important! Earlier + * layers will shadow later ones when a config value is + * requested (if a 'user' value exists, it will be returned first, + * then 'system' and finally 'default'). + * + * @var array layer => array(keyname => value, ...) + */ + var $configuration = array( + 'user' => array(), + 'system' => array(), + 'default' => array(), + ); + + /** + * Configuration values that can be set for a channel + * + * All other configuration values can only have a global value + * @var array + * @access private + */ + var $_channelConfigInfo = array( + 'php_dir', 'ext_dir', 'doc_dir', 'bin_dir', 'data_dir', 'cfg_dir', + 'test_dir', 'www_dir', 'php_bin', 'php_prefix', 'php_suffix', 'username', + 'password', 'verbose', 'preferred_state', 'umask', 'preferred_mirror', 'php_ini' + ); + + /** + * Channels that can be accessed + * @see setChannels() + * @var array + * @access private + */ + var $_channels = array('pear.php.net', 'pecl.php.net', '__uri'); + + /** + * This variable is used to control the directory values returned + * @see setInstallRoot(); + * @var string|false + * @access private + */ + var $_installRoot = false; + + /** + * If requested, this will always refer to the registry + * contained in php_dir + * @var PEAR_Registry + */ + var $_registry = array(); + + /** + * @var array + * @access private + */ + var $_regInitialized = array(); + + /** + * @var bool + * @access private + */ + var $_noRegistry = false; + + /** + * amount of errors found while parsing config + * @var integer + * @access private + */ + var $_errorsFound = 0; + var $_lastError = null; + + /** + * Information about the configuration data. Stores the type, + * default value and a documentation string for each configuration + * value. + * + * @var array layer => array(infotype => value, ...) + */ + var $configuration_info = array( + // Channels/Internet Access + 'default_channel' => array( + 'type' => 'string', + 'default' => PEAR_CONFIG_DEFAULT_CHANNEL, + 'doc' => 'the default channel to use for all non explicit commands', + 'prompt' => 'Default Channel', + 'group' => 'Internet Access', + ), + 'preferred_mirror' => array( + 'type' => 'string', + 'default' => PEAR_CONFIG_DEFAULT_CHANNEL, + 'doc' => 'the default server or mirror to use for channel actions', + 'prompt' => 'Default Channel Mirror', + 'group' => 'Internet Access', + ), + 'remote_config' => array( + 'type' => 'password', + 'default' => '', + 'doc' => 'ftp url of remote configuration file to use for synchronized install', + 'prompt' => 'Remote Configuration File', + 'group' => 'Internet Access', + ), + 'auto_discover' => array( + 'type' => 'integer', + 'default' => 0, + 'doc' => 'whether to automatically discover new channels', + 'prompt' => 'Auto-discover new Channels', + 'group' => 'Internet Access', + ), + // Internet Access + 'master_server' => array( + 'type' => 'string', + 'default' => 'pear.php.net', + 'doc' => 'name of the main PEAR server [NOT USED IN THIS VERSION]', + 'prompt' => 'PEAR server [DEPRECATED]', + 'group' => 'Internet Access', + ), + 'http_proxy' => array( + 'type' => 'string', + 'default' => PEAR_CONFIG_DEFAULT_HTTP_PROXY, + 'doc' => 'HTTP proxy (host:port) to use when downloading packages', + 'prompt' => 'HTTP Proxy Server Address', + 'group' => 'Internet Access', + ), + // File Locations + 'php_dir' => array( + 'type' => 'directory', + 'default' => PEAR_CONFIG_DEFAULT_PHP_DIR, + 'doc' => 'directory where .php files are installed', + 'prompt' => 'PEAR directory', + 'group' => 'File Locations', + ), + 'ext_dir' => array( + 'type' => 'directory', + 'default' => PEAR_CONFIG_DEFAULT_EXT_DIR, + 'doc' => 'directory where loadable extensions are installed', + 'prompt' => 'PHP extension directory', + 'group' => 'File Locations', + ), + 'doc_dir' => array( + 'type' => 'directory', + 'default' => PEAR_CONFIG_DEFAULT_DOC_DIR, + 'doc' => 'directory where documentation is installed', + 'prompt' => 'PEAR documentation directory', + 'group' => 'File Locations', + ), + 'bin_dir' => array( + 'type' => 'directory', + 'default' => PEAR_CONFIG_DEFAULT_BIN_DIR, + 'doc' => 'directory where executables are installed', + 'prompt' => 'PEAR executables directory', + 'group' => 'File Locations', + ), + 'data_dir' => array( + 'type' => 'directory', + 'default' => PEAR_CONFIG_DEFAULT_DATA_DIR, + 'doc' => 'directory where data files are installed', + 'prompt' => 'PEAR data directory', + 'group' => 'File Locations (Advanced)', + ), + 'cfg_dir' => array( + 'type' => 'directory', + 'default' => PEAR_CONFIG_DEFAULT_CFG_DIR, + 'doc' => 'directory where modifiable configuration files are installed', + 'prompt' => 'PEAR configuration file directory', + 'group' => 'File Locations (Advanced)', + ), + 'www_dir' => array( + 'type' => 'directory', + 'default' => PEAR_CONFIG_DEFAULT_WWW_DIR, + 'doc' => 'directory where www frontend files (html/js) are installed', + 'prompt' => 'PEAR www files directory', + 'group' => 'File Locations (Advanced)', + ), + 'man_dir' => array( + 'type' => 'directory', + 'default' => PEAR_CONFIG_DEFAULT_MAN_DIR, + 'doc' => 'directory where unix manual pages are installed', + 'prompt' => 'Systems manpage files directory', + 'group' => 'File Locations (Advanced)', + ), + 'test_dir' => array( + 'type' => 'directory', + 'default' => PEAR_CONFIG_DEFAULT_TEST_DIR, + 'doc' => 'directory where regression tests are installed', + 'prompt' => 'PEAR test directory', + 'group' => 'File Locations (Advanced)', + ), + 'cache_dir' => array( + 'type' => 'directory', + 'default' => PEAR_CONFIG_DEFAULT_CACHE_DIR, + 'doc' => 'directory which is used for web service cache', + 'prompt' => 'PEAR Installer cache directory', + 'group' => 'File Locations (Advanced)', + ), + 'temp_dir' => array( + 'type' => 'directory', + 'default' => PEAR_CONFIG_DEFAULT_TEMP_DIR, + 'doc' => 'directory which is used for all temp files', + 'prompt' => 'PEAR Installer temp directory', + 'group' => 'File Locations (Advanced)', + ), + 'download_dir' => array( + 'type' => 'directory', + 'default' => PEAR_CONFIG_DEFAULT_DOWNLOAD_DIR, + 'doc' => 'directory which is used for all downloaded files', + 'prompt' => 'PEAR Installer download directory', + 'group' => 'File Locations (Advanced)', + ), + 'php_bin' => array( + 'type' => 'file', + 'default' => PEAR_CONFIG_DEFAULT_PHP_BIN, + 'doc' => 'PHP CLI/CGI binary for executing scripts', + 'prompt' => 'PHP CLI/CGI binary', + 'group' => 'File Locations (Advanced)', + ), + 'php_prefix' => array( + 'type' => 'string', + 'default' => '', + 'doc' => '--program-prefix for php_bin\'s ./configure, used for pecl installs', + 'prompt' => '--program-prefix passed to PHP\'s ./configure', + 'group' => 'File Locations (Advanced)', + ), + 'php_suffix' => array( + 'type' => 'string', + 'default' => '', + 'doc' => '--program-suffix for php_bin\'s ./configure, used for pecl installs', + 'prompt' => '--program-suffix passed to PHP\'s ./configure', + 'group' => 'File Locations (Advanced)', + ), + 'php_ini' => array( + 'type' => 'file', + 'default' => '', + 'doc' => 'location of php.ini in which to enable PECL extensions on install', + 'prompt' => 'php.ini location', + 'group' => 'File Locations (Advanced)', + ), + 'metadata_dir' => array( + 'type' => 'directory', + 'default' => PEAR_CONFIG_DEFAULT_METADATA_DIR, + 'doc' => 'directory where metadata files are installed (registry, filemap, channels, ...)', + 'prompt' => 'PEAR metadata directory', + 'group' => 'File Locations (Advanced)', + ), + // Maintainers + 'username' => array( + 'type' => 'string', + 'default' => '', + 'doc' => '(maintainers) your PEAR account name', + 'prompt' => 'PEAR username (for maintainers)', + 'group' => 'Maintainers', + ), + 'password' => array( + 'type' => 'password', + 'default' => '', + 'doc' => '(maintainers) your PEAR account password', + 'prompt' => 'PEAR password (for maintainers)', + 'group' => 'Maintainers', + ), + // Advanced + 'verbose' => array( + 'type' => 'integer', + 'default' => PEAR_CONFIG_DEFAULT_VERBOSE, + 'doc' => 'verbosity level +0: really quiet +1: somewhat quiet +2: verbose +3: debug', + 'prompt' => 'Debug Log Level', + 'group' => 'Advanced', + ), + 'preferred_state' => array( + 'type' => 'set', + 'default' => PEAR_CONFIG_DEFAULT_PREFERRED_STATE, + 'doc' => 'the installer will prefer releases with this state when installing packages without a version or state specified', + 'valid_set' => array( + 'stable', 'beta', 'alpha', 'devel', 'snapshot'), + 'prompt' => 'Preferred Package State', + 'group' => 'Advanced', + ), + 'umask' => array( + 'type' => 'mask', + 'default' => PEAR_CONFIG_DEFAULT_UMASK, + 'doc' => 'umask used when creating files (Unix-like systems only)', + 'prompt' => 'Unix file mask', + 'group' => 'Advanced', + ), + 'cache_ttl' => array( + 'type' => 'integer', + 'default' => PEAR_CONFIG_DEFAULT_CACHE_TTL, + 'doc' => 'amount of secs where the local cache is used and not updated', + 'prompt' => 'Cache TimeToLive', + 'group' => 'Advanced', + ), + 'sig_type' => array( + 'type' => 'set', + 'default' => PEAR_CONFIG_DEFAULT_SIG_TYPE, + 'doc' => 'which package signature mechanism to use', + 'valid_set' => array('gpg'), + 'prompt' => 'Package Signature Type', + 'group' => 'Maintainers', + ), + 'sig_bin' => array( + 'type' => 'string', + 'default' => PEAR_CONFIG_DEFAULT_SIG_BIN, + 'doc' => 'which package signature mechanism to use', + 'prompt' => 'Signature Handling Program', + 'group' => 'Maintainers', + ), + 'sig_keyid' => array( + 'type' => 'string', + 'default' => '', + 'doc' => 'which key to use for signing with', + 'prompt' => 'Signature Key Id', + 'group' => 'Maintainers', + ), + 'sig_keydir' => array( + 'type' => 'directory', + 'default' => PEAR_CONFIG_DEFAULT_SIG_KEYDIR, + 'doc' => 'directory where signature keys are located', + 'prompt' => 'Signature Key Directory', + 'group' => 'Maintainers', + ), + // __channels is reserved - used for channel-specific configuration + ); + + /** + * Constructor. + * + * @param string file to read user-defined options from + * @param string file to read system-wide defaults from + * @param bool determines whether a registry object "follows" + * the value of php_dir (is automatically created + * and moved when php_dir is changed) + * @param bool if true, fails if configuration files cannot be loaded + * + * @access public + * + * @see PEAR_Config::singleton + */ + function __construct($user_file = '', $system_file = '', $ftp_file = false, + $strict = true) + { + parent::__construct(); + PEAR_Installer_Role::initializeConfig($this); + $sl = DIRECTORY_SEPARATOR; + if (empty($user_file)) { + if (OS_WINDOWS) { + $user_file = PEAR_CONFIG_SYSCONFDIR . $sl . 'pear.ini'; + } else { + $user_file = getenv('HOME') . $sl . '.pearrc'; + } + } + + if (empty($system_file)) { + $system_file = PEAR_CONFIG_SYSCONFDIR . $sl; + if (OS_WINDOWS) { + $system_file .= 'pearsys.ini'; + } else { + $system_file .= 'pear.conf'; + } + } + + $this->layers = array_keys($this->configuration); + $this->files['user'] = $user_file; + $this->files['system'] = $system_file; + if ($user_file && file_exists($user_file)) { + $this->pushErrorHandling(PEAR_ERROR_RETURN); + $this->readConfigFile($user_file, 'user', $strict); + $this->popErrorHandling(); + if ($this->_errorsFound > 0) { + return; + } + } + + if ($system_file && @file_exists($system_file)) { + $this->mergeConfigFile($system_file, false, 'system', $strict); + if ($this->_errorsFound > 0) { + return; + } + + } + + if (!$ftp_file) { + $ftp_file = $this->get('remote_config'); + } + + if ($ftp_file && defined('PEAR_REMOTEINSTALL_OK')) { + $this->readFTPConfigFile($ftp_file); + } + + foreach ($this->configuration_info as $key => $info) { + $this->configuration['default'][$key] = $info['default']; + } + + $this->_registry['default'] = new PEAR_Registry( + $this->configuration['default']['php_dir'], false, false, + $this->configuration['default']['metadata_dir']); + $this->_registry['default']->setConfig($this, false); + $this->_regInitialized['default'] = false; + //$GLOBALS['_PEAR_Config_instance'] = &$this; + } + + /** + * Return the default locations of user and system configuration files + */ + public static function getDefaultConfigFiles() + { + $sl = DIRECTORY_SEPARATOR; + if (OS_WINDOWS) { + return array( + 'user' => PEAR_CONFIG_SYSCONFDIR . $sl . 'pear.ini', + 'system' => PEAR_CONFIG_SYSCONFDIR . $sl . 'pearsys.ini' + ); + } + + return array( + 'user' => getenv('HOME') . $sl . '.pearrc', + 'system' => PEAR_CONFIG_SYSCONFDIR . $sl . 'pear.conf' + ); + } + + /** + * Static singleton method. If you want to keep only one instance + * of this class in use, this method will give you a reference to + * the last created PEAR_Config object if one exists, or create a + * new object. + * + * @param string (optional) file to read user-defined options from + * @param string (optional) file to read system-wide defaults from + * + * @return object an existing or new PEAR_Config instance + * + * @see PEAR_Config::PEAR_Config + */ + public static function &singleton($user_file = '', $system_file = '', $strict = true) + { + if (is_object($GLOBALS['_PEAR_Config_instance'])) { + return $GLOBALS['_PEAR_Config_instance']; + } + + $t_conf = new PEAR_Config($user_file, $system_file, false, $strict); + if ($t_conf->_errorsFound > 0) { + return $t_conf->lastError; + } + + $GLOBALS['_PEAR_Config_instance'] = &$t_conf; + return $GLOBALS['_PEAR_Config_instance']; + } + + /** + * Determine whether any configuration files have been detected, and whether a + * registry object can be retrieved from this configuration. + * @return bool + * @since PEAR 1.4.0a1 + */ + function validConfiguration() + { + if ($this->isDefinedLayer('user') || $this->isDefinedLayer('system')) { + return true; + } + + return false; + } + + /** + * Reads configuration data from a file. All existing values in + * the config layer are discarded and replaced with data from the + * file. + * @param string file to read from, if NULL or not specified, the + * last-used file for the same layer (second param) is used + * @param string config layer to insert data into ('user' or 'system') + * @return bool TRUE on success or a PEAR error on failure + */ + function readConfigFile($file = null, $layer = 'user', $strict = true) + { + if (empty($this->files[$layer])) { + return $this->raiseError("unknown config layer `$layer'"); + } + + if ($file === null) { + $file = $this->files[$layer]; + } + + $data = $this->_readConfigDataFrom($file); + if (PEAR::isError($data)) { + if (!$strict) { + return true; + } + + $this->_errorsFound++; + $this->lastError = $data; + + return $data; + } + + $this->files[$layer] = $file; + $this->_decodeInput($data); + $this->configuration[$layer] = $data; + $this->_setupChannels(); + if (!$this->_noRegistry && ($phpdir = $this->get('php_dir', $layer, 'pear.php.net'))) { + $this->_registry[$layer] = new PEAR_Registry( + $phpdir, false, false, + $this->get('metadata_dir', $layer, 'pear.php.net')); + $this->_registry[$layer]->setConfig($this, false); + $this->_regInitialized[$layer] = false; + } else { + unset($this->_registry[$layer]); + } + return true; + } + + /** + * @param string url to the remote config file, like ftp://www.example.com/pear/config.ini + * @return true|PEAR_Error + */ + function readFTPConfigFile($path) + { + do { // poor man's try + if (!class_exists('PEAR_FTP')) { + if (!class_exists('PEAR_Common')) { + require_once 'PEAR/Common.php'; + } + if (PEAR_Common::isIncludeable('PEAR/FTP.php')) { + require_once 'PEAR/FTP.php'; + } + } + + if (!class_exists('PEAR_FTP')) { + return PEAR::raiseError('PEAR_RemoteInstaller must be installed to use remote config'); + } + + $this->_ftp = new PEAR_FTP; + $this->_ftp->pushErrorHandling(PEAR_ERROR_RETURN); + $e = $this->_ftp->init($path); + if (PEAR::isError($e)) { + $this->_ftp->popErrorHandling(); + return $e; + } + + $tmp = System::mktemp('-d'); + PEAR_Common::addTempFile($tmp); + $e = $this->_ftp->get(basename($path), $tmp . DIRECTORY_SEPARATOR . + 'pear.ini', false, FTP_BINARY); + if (PEAR::isError($e)) { + $this->_ftp->popErrorHandling(); + return $e; + } + + PEAR_Common::addTempFile($tmp . DIRECTORY_SEPARATOR . 'pear.ini'); + $this->_ftp->disconnect(); + $this->_ftp->popErrorHandling(); + $this->files['ftp'] = $tmp . DIRECTORY_SEPARATOR . 'pear.ini'; + $e = $this->readConfigFile(null, 'ftp'); + if (PEAR::isError($e)) { + return $e; + } + + $fail = array(); + foreach ($this->configuration_info as $key => $val) { + if (in_array($this->getGroup($key), + array('File Locations', 'File Locations (Advanced)')) && + $this->getType($key) == 'directory') { + // any directory configs must be set for this to work + if (!isset($this->configuration['ftp'][$key])) { + $fail[] = $key; + } + } + } + + if (!count($fail)) { + return true; + } + + $fail = '"' . implode('", "', $fail) . '"'; + unset($this->files['ftp']); + unset($this->configuration['ftp']); + return PEAR::raiseError('ERROR: Ftp configuration file must set all ' . + 'directory configuration variables. These variables were not set: ' . + $fail); + } while (false); // poor man's catch + unset($this->files['ftp']); + return PEAR::raiseError('no remote host specified'); + } + + /** + * Reads the existing configurations and creates the _channels array from it + */ + function _setupChannels() + { + $set = array_flip(array_values($this->_channels)); + foreach ($this->configuration as $layer => $data) { + $i = 1000; + if (isset($data['__channels']) && is_array($data['__channels'])) { + foreach ($data['__channels'] as $channel => $info) { + $set[$channel] = $i++; + } + } + } + $this->_channels = array_values(array_flip($set)); + $this->setChannels($this->_channels); + } + + function deleteChannel($channel) + { + $ch = strtolower($channel); + foreach ($this->configuration as $layer => $data) { + if (isset($data['__channels']) && isset($data['__channels'][$ch])) { + unset($this->configuration[$layer]['__channels'][$ch]); + } + } + + $this->_channels = array_flip($this->_channels); + unset($this->_channels[$ch]); + $this->_channels = array_flip($this->_channels); + } + + /** + * Merges data into a config layer from a file. Does the same + * thing as readConfigFile, except it does not replace all + * existing values in the config layer. + * @param string file to read from + * @param bool whether to overwrite existing data (default TRUE) + * @param string config layer to insert data into ('user' or 'system') + * @param string if true, errors are returned if file opening fails + * @return bool TRUE on success or a PEAR error on failure + */ + function mergeConfigFile($file, $override = true, $layer = 'user', $strict = true) + { + if (empty($this->files[$layer])) { + return $this->raiseError("unknown config layer `$layer'"); + } + + if ($file === null) { + $file = $this->files[$layer]; + } + + $data = $this->_readConfigDataFrom($file); + if (PEAR::isError($data)) { + if (!$strict) { + return true; + } + + $this->_errorsFound++; + $this->lastError = $data; + + return $data; + } + + $this->_decodeInput($data); + if ($override) { + $this->configuration[$layer] = + PEAR_Config::arrayMergeRecursive($this->configuration[$layer], $data); + } else { + $this->configuration[$layer] = + PEAR_Config::arrayMergeRecursive($data, $this->configuration[$layer]); + } + + $this->_setupChannels(); + if (!$this->_noRegistry && ($phpdir = $this->get('php_dir', $layer, 'pear.php.net'))) { + $this->_registry[$layer] = new PEAR_Registry( + $phpdir, false, false, + $this->get('metadata_dir', $layer, 'pear.php.net')); + $this->_registry[$layer]->setConfig($this, false); + $this->_regInitialized[$layer] = false; + } else { + unset($this->_registry[$layer]); + } + return true; + } + + /** + * @param array + * @param array + * @return array + */ + public static function arrayMergeRecursive($arr2, $arr1) + { + $ret = array(); + foreach ($arr2 as $key => $data) { + if (!isset($arr1[$key])) { + $ret[$key] = $data; + unset($arr1[$key]); + continue; + } + if (is_array($data)) { + if (!is_array($arr1[$key])) { + $ret[$key] = $arr1[$key]; + unset($arr1[$key]); + continue; + } + $ret[$key] = PEAR_Config::arrayMergeRecursive($arr1[$key], $arr2[$key]); + unset($arr1[$key]); + } + } + + return array_merge($ret, $arr1); + } + + /** + * Writes data into a config layer from a file. + * + * @param string|null file to read from, or null for default + * @param string config layer to insert data into ('user' or + * 'system') + * @param string|null data to write to config file or null for internal data [DEPRECATED] + * @return bool TRUE on success or a PEAR error on failure + */ + function writeConfigFile($file = null, $layer = 'user', $data = null) + { + $this->_lazyChannelSetup($layer); + if ($layer == 'both' || $layer == 'all') { + foreach ($this->files as $type => $file) { + $err = $this->writeConfigFile($file, $type, $data); + if (PEAR::isError($err)) { + return $err; + } + } + return true; + } + + if (empty($this->files[$layer])) { + return $this->raiseError("unknown config file type `$layer'"); + } + + if ($file === null) { + $file = $this->files[$layer]; + } + + $data = ($data === null) ? $this->configuration[$layer] : $data; + $this->_encodeOutput($data); + $opt = array('-p', dirname($file)); + if (!@System::mkDir($opt)) { + return $this->raiseError("could not create directory: " . dirname($file)); + } + + if (file_exists($file) && is_file($file) && !is_writeable($file)) { + return $this->raiseError("no write access to $file!"); + } + + $fp = @fopen($file, "w"); + if (!$fp) { + return $this->raiseError("PEAR_Config::writeConfigFile fopen('$file','w') failed ($php_errormsg)"); + } + + $contents = "#PEAR_Config 0.9\n" . serialize($data); + if (!@fwrite($fp, $contents)) { + return $this->raiseError("PEAR_Config::writeConfigFile: fwrite failed ($php_errormsg)"); + } + return true; + } + + /** + * Reads configuration data from a file and returns the parsed data + * in an array. + * + * @param string file to read from + * @return array configuration data or a PEAR error on failure + * @access private + */ + function _readConfigDataFrom($file) + { + $fp = false; + if (file_exists($file)) { + $fp = @fopen($file, "r"); + } + + if (!$fp) { + return $this->raiseError("PEAR_Config::readConfigFile fopen('$file','r') failed"); + } + + $size = filesize($file); + fclose($fp); + $contents = file_get_contents($file); + if (empty($contents)) { + return $this->raiseError('Configuration file "' . $file . '" is empty'); + } + + $version = false; + if (preg_match('/^#PEAR_Config\s+(\S+)\s+/si', $contents, $matches)) { + $version = $matches[1]; + $contents = substr($contents, strlen($matches[0])); + } else { + // Museum config file + if (substr($contents,0,2) == 'a:') { + $version = '0.1'; + } + } + + if ($version && version_compare("$version", '1', '<')) { + // no '@', it is possible that unserialize + // raises a notice but it seems to block IO to + // STDOUT if a '@' is used and a notice is raise + $data = unserialize($contents); + + if (!is_array($data) && !$data) { + if ($contents == serialize(false)) { + $data = array(); + } else { + $err = $this->raiseError("PEAR_Config: bad data in $file"); + return $err; + } + } + if (!is_array($data)) { + if (strlen(trim($contents)) > 0) { + $error = "PEAR_Config: bad data in $file"; + $err = $this->raiseError($error); + return $err; + } + + $data = array(); + } + // add parsing of newer formats here... + } else { + $err = $this->raiseError("$file: unknown version `$version'"); + return $err; + } + + return $data; + } + + /** + * Gets the file used for storing the config for a layer + * + * @param string $layer 'user' or 'system' + */ + function getConfFile($layer) + { + return $this->files[$layer]; + } + + /** + * @param string Configuration class name, used for detecting duplicate calls + * @param array information on a role as parsed from its xml file + * @return true|PEAR_Error + * @access private + */ + function _addConfigVars($class, $vars) + { + static $called = array(); + if (isset($called[$class])) { + return; + } + + $called[$class] = 1; + if (count($vars) > 3) { + return $this->raiseError('Roles can only define 3 new config variables or less'); + } + + foreach ($vars as $name => $var) { + if (!is_array($var)) { + return $this->raiseError('Configuration information must be an array'); + } + + if (!isset($var['type'])) { + return $this->raiseError('Configuration information must contain a type'); + } elseif (!in_array($var['type'], + array('string', 'mask', 'password', 'directory', 'file', 'set'))) { + return $this->raiseError( + 'Configuration type must be one of directory, file, string, ' . + 'mask, set, or password'); + } + if (!isset($var['default'])) { + return $this->raiseError( + 'Configuration information must contain a default value ("default" index)'); + } + + if (is_array($var['default'])) { + $real_default = ''; + foreach ($var['default'] as $config_var => $val) { + if (strpos($config_var, 'text') === 0) { + $real_default .= $val; + } elseif (strpos($config_var, 'constant') === 0) { + if (!defined($val)) { + return $this->raiseError( + 'Unknown constant "' . $val . '" requested in ' . + 'default value for configuration variable "' . + $name . '"'); + } + + $real_default .= constant($val); + } elseif (isset($this->configuration_info[$config_var])) { + $real_default .= + $this->configuration_info[$config_var]['default']; + } else { + return $this->raiseError( + 'Unknown request for "' . $config_var . '" value in ' . + 'default value for configuration variable "' . + $name . '"'); + } + } + $var['default'] = $real_default; + } + + if ($var['type'] == 'integer') { + $var['default'] = (integer) $var['default']; + } + + if (!isset($var['doc'])) { + return $this->raiseError( + 'Configuration information must contain a summary ("doc" index)'); + } + + if (!isset($var['prompt'])) { + return $this->raiseError( + 'Configuration information must contain a simple prompt ("prompt" index)'); + } + + if (!isset($var['group'])) { + return $this->raiseError( + 'Configuration information must contain a simple group ("group" index)'); + } + + if (isset($this->configuration_info[$name])) { + return $this->raiseError('Configuration variable "' . $name . + '" already exists'); + } + + $this->configuration_info[$name] = $var; + // fix bug #7351: setting custom config variable in a channel fails + $this->_channelConfigInfo[] = $name; + } + + return true; + } + + /** + * Encodes/scrambles configuration data before writing to files. + * Currently, 'password' values will be base64-encoded as to avoid + * that people spot cleartext passwords by accident. + * + * @param array (reference) array to encode values in + * @return bool TRUE on success + * @access private + */ + function _encodeOutput(&$data) + { + foreach ($data as $key => $value) { + if ($key == '__channels') { + foreach ($data['__channels'] as $channel => $blah) { + $this->_encodeOutput($data['__channels'][$channel]); + } + } + + if (!isset($this->configuration_info[$key])) { + continue; + } + + $type = $this->configuration_info[$key]['type']; + switch ($type) { + // we base64-encode passwords so they are at least + // not shown in plain by accident + case 'password': { + $data[$key] = base64_encode($data[$key]); + break; + } + case 'mask': { + $data[$key] = octdec($data[$key]); + break; + } + } + } + + return true; + } + + /** + * Decodes/unscrambles configuration data after reading from files. + * + * @param array (reference) array to encode values in + * @return bool TRUE on success + * @access private + * + * @see PEAR_Config::_encodeOutput + */ + function _decodeInput(&$data) + { + if (!is_array($data)) { + return true; + } + + foreach ($data as $key => $value) { + if ($key == '__channels') { + foreach ($data['__channels'] as $channel => $blah) { + $this->_decodeInput($data['__channels'][$channel]); + } + } + + if (!isset($this->configuration_info[$key])) { + continue; + } + + $type = $this->configuration_info[$key]['type']; + switch ($type) { + case 'password': { + $data[$key] = base64_decode($data[$key]); + break; + } + case 'mask': { + $data[$key] = decoct($data[$key]); + break; + } + } + } + + return true; + } + + /** + * Retrieve the default channel. + * + * On startup, channels are not initialized, so if the default channel is not + * pear.php.net, then initialize the config. + * @param string registry layer + * @return string|false + */ + function getDefaultChannel($layer = null) + { + $ret = false; + if ($layer === null) { + foreach ($this->layers as $layer) { + if (isset($this->configuration[$layer]['default_channel'])) { + $ret = $this->configuration[$layer]['default_channel']; + break; + } + } + } elseif (isset($this->configuration[$layer]['default_channel'])) { + $ret = $this->configuration[$layer]['default_channel']; + } + + if ($ret == 'pear.php.net' && defined('PEAR_RUNTYPE') && PEAR_RUNTYPE == 'pecl') { + $ret = 'pecl.php.net'; + } + + if ($ret) { + if ($ret != 'pear.php.net') { + $this->_lazyChannelSetup(); + } + + return $ret; + } + + return PEAR_CONFIG_DEFAULT_CHANNEL; + } + + /** + * Returns a configuration value, prioritizing layers as per the + * layers property. + * + * @param string config key + * @return mixed the config value, or NULL if not found + * @access public + */ + function get($key, $layer = null, $channel = false) + { + if (!isset($this->configuration_info[$key])) { + return null; + } + + if ($key == '__channels') { + return null; + } + + if ($key == 'default_channel') { + return $this->getDefaultChannel($layer); + } + + if (!$channel) { + $channel = $this->getDefaultChannel(); + } elseif ($channel != 'pear.php.net') { + $this->_lazyChannelSetup(); + } + $channel = strtolower($channel); + + $test = (in_array($key, $this->_channelConfigInfo)) ? + $this->_getChannelValue($key, $layer, $channel) : + null; + if ($test !== null) { + if ($this->_installRoot) { + if (in_array($this->getGroup($key), + array('File Locations', 'File Locations (Advanced)')) && + $this->getType($key) == 'directory') { + return $this->_prependPath($test, $this->_installRoot); + } + } + return $test; + } + + if ($layer === null) { + foreach ($this->layers as $layer) { + if (isset($this->configuration[$layer][$key])) { + $test = $this->configuration[$layer][$key]; + if ($this->_installRoot) { + if (in_array($this->getGroup($key), + array('File Locations', 'File Locations (Advanced)')) && + $this->getType($key) == 'directory') { + return $this->_prependPath($test, $this->_installRoot); + } + } + + if ($key == 'preferred_mirror') { + $reg = &$this->getRegistry(); + if (is_object($reg)) { + $chan = $reg->getChannel($channel); + if (PEAR::isError($chan)) { + return $channel; + } + + if (!$chan->getMirror($test) && $chan->getName() != $test) { + return $channel; // mirror does not exist + } + } + } + return $test; + } + } + } elseif (isset($this->configuration[$layer][$key])) { + $test = $this->configuration[$layer][$key]; + if ($this->_installRoot) { + if (in_array($this->getGroup($key), + array('File Locations', 'File Locations (Advanced)')) && + $this->getType($key) == 'directory') { + return $this->_prependPath($test, $this->_installRoot); + } + } + + if ($key == 'preferred_mirror') { + $reg = &$this->getRegistry(); + if (is_object($reg)) { + $chan = $reg->getChannel($channel); + if (PEAR::isError($chan)) { + return $channel; + } + + if (!$chan->getMirror($test) && $chan->getName() != $test) { + return $channel; // mirror does not exist + } + } + } + + return $test; + } + + return null; + } + + /** + * Returns a channel-specific configuration value, prioritizing layers as per the + * layers property. + * + * @param string config key + * @return mixed the config value, or NULL if not found + * @access private + */ + function _getChannelValue($key, $layer, $channel) + { + if ($key == '__channels' || $channel == 'pear.php.net') { + return null; + } + + $ret = null; + if ($layer === null) { + foreach ($this->layers as $ilayer) { + if (isset($this->configuration[$ilayer]['__channels'][$channel][$key])) { + $ret = $this->configuration[$ilayer]['__channels'][$channel][$key]; + break; + } + } + } elseif (isset($this->configuration[$layer]['__channels'][$channel][$key])) { + $ret = $this->configuration[$layer]['__channels'][$channel][$key]; + } + + if ($key != 'preferred_mirror') { + return $ret; + } + + + if ($ret !== null) { + $reg = &$this->getRegistry($layer); + if (is_object($reg)) { + $chan = $reg->getChannel($channel); + if (PEAR::isError($chan)) { + return $channel; + } + + if (!$chan->getMirror($ret) && $chan->getName() != $ret) { + return $channel; // mirror does not exist + } + } + + return $ret; + } + + if ($channel != $this->getDefaultChannel($layer)) { + return $channel; // we must use the channel name as the preferred mirror + // if the user has not chosen an alternate + } + + return $this->getDefaultChannel($layer); + } + + /** + * Set a config value in a specific layer (defaults to 'user'). + * Enforces the types defined in the configuration_info array. An + * integer config variable will be cast to int, and a set config + * variable will be validated against its legal values. + * + * @param string config key + * @param string config value + * @param string (optional) config layer + * @param string channel to set this value for, or null for global value + * @return bool TRUE on success, FALSE on failure + */ + function set($key, $value, $layer = 'user', $channel = false) + { + if ($key == '__channels') { + return false; + } + + if (!isset($this->configuration[$layer])) { + return false; + } + + if ($key == 'default_channel') { + // can only set this value globally + $channel = 'pear.php.net'; + if ($value != 'pear.php.net') { + $this->_lazyChannelSetup($layer); + } + } + + if ($key == 'preferred_mirror') { + if ($channel == '__uri') { + return false; // can't set the __uri pseudo-channel's mirror + } + + $reg = &$this->getRegistry($layer); + if (is_object($reg)) { + $chan = $reg->getChannel($channel ? $channel : 'pear.php.net'); + if (PEAR::isError($chan)) { + return false; + } + + if (!$chan->getMirror($value) && $chan->getName() != $value) { + return false; // mirror does not exist + } + } + } + + if (!isset($this->configuration_info[$key])) { + return false; + } + + extract($this->configuration_info[$key]); + switch ($type) { + case 'integer': + $value = (int)$value; + break; + case 'set': { + // If a valid_set is specified, require the value to + // be in the set. If there is no valid_set, accept + // any value. + if ($valid_set) { + reset($valid_set); + if ((key($valid_set) === 0 && !in_array($value, $valid_set)) || + (key($valid_set) !== 0 && empty($valid_set[$value]))) + { + return false; + } + } + break; + } + } + + if (!$channel) { + $channel = $this->get('default_channel', null, 'pear.php.net'); + } + + if (!in_array($channel, $this->_channels)) { + $this->_lazyChannelSetup($layer); + $reg = &$this->getRegistry($layer); + if ($reg) { + $channel = $reg->channelName($channel); + } + + if (!in_array($channel, $this->_channels)) { + return false; + } + } + + if ($channel != 'pear.php.net') { + if (in_array($key, $this->_channelConfigInfo)) { + $this->configuration[$layer]['__channels'][$channel][$key] = $value; + return true; + } + + return false; + } + + if ($key == 'default_channel') { + if (!isset($reg)) { + $reg = &$this->getRegistry($layer); + if (!$reg) { + $reg = &$this->getRegistry(); + } + } + + if ($reg) { + $value = $reg->channelName($value); + } + + if (!$value) { + return false; + } + } + + $this->configuration[$layer][$key] = $value; + if ($key == 'php_dir' && !$this->_noRegistry) { + if (!isset($this->_registry[$layer]) || + $value != $this->_registry[$layer]->install_dir) { + $this->_registry[$layer] = new PEAR_Registry($value); + $this->_regInitialized[$layer] = false; + $this->_registry[$layer]->setConfig($this, false); + } + } + + return true; + } + + function _lazyChannelSetup($uselayer = false) + { + if ($this->_noRegistry) { + return; + } + + $merge = false; + foreach ($this->_registry as $layer => $p) { + if ($uselayer && $uselayer != $layer) { + continue; + } + + if (!$this->_regInitialized[$layer]) { + if ($layer == 'default' && isset($this->_registry['user']) || + isset($this->_registry['system'])) { + // only use the default registry if there are no alternatives + continue; + } + + if (!is_object($this->_registry[$layer])) { + if ($phpdir = $this->get('php_dir', $layer, 'pear.php.net')) { + $this->_registry[$layer] = new PEAR_Registry( + $phpdir, false, false, + $this->get('metadata_dir', $layer, 'pear.php.net')); + $this->_registry[$layer]->setConfig($this, false); + $this->_regInitialized[$layer] = false; + } else { + unset($this->_registry[$layer]); + return; + } + } + + $this->setChannels($this->_registry[$layer]->listChannels(), $merge); + $this->_regInitialized[$layer] = true; + $merge = true; + } + } + } + + /** + * Set the list of channels. + * + * This should be set via a call to {@link PEAR_Registry::listChannels()} + * @param array + * @param bool + * @return bool success of operation + */ + function setChannels($channels, $merge = false) + { + if (!is_array($channels)) { + return false; + } + + if ($merge) { + $this->_channels = array_merge($this->_channels, $channels); + } else { + $this->_channels = $channels; + } + + foreach ($channels as $channel) { + $channel = strtolower($channel); + if ($channel == 'pear.php.net') { + continue; + } + + foreach ($this->layers as $layer) { + if (!isset($this->configuration[$layer]['__channels'])) { + $this->configuration[$layer]['__channels'] = array(); + } + if (!isset($this->configuration[$layer]['__channels'][$channel]) + || !is_array($this->configuration[$layer]['__channels'][$channel])) { + $this->configuration[$layer]['__channels'][$channel] = array(); + } + } + } + + return true; + } + + /** + * Get the type of a config value. + * + * @param string config key + * + * @return string type, one of "string", "integer", "file", + * "directory", "set" or "password". + * + * @access public + * + */ + function getType($key) + { + if (isset($this->configuration_info[$key])) { + return $this->configuration_info[$key]['type']; + } + return false; + } + + /** + * Get the documentation for a config value. + * + * @param string config key + * @return string documentation string + * + * @access public + * + */ + function getDocs($key) + { + if (isset($this->configuration_info[$key])) { + return $this->configuration_info[$key]['doc']; + } + + return false; + } + + /** + * Get the short documentation for a config value. + * + * @param string config key + * @return string short documentation string + * + * @access public + * + */ + function getPrompt($key) + { + if (isset($this->configuration_info[$key])) { + return $this->configuration_info[$key]['prompt']; + } + + return false; + } + + /** + * Get the parameter group for a config key. + * + * @param string config key + * @return string parameter group + * + * @access public + * + */ + function getGroup($key) + { + if (isset($this->configuration_info[$key])) { + return $this->configuration_info[$key]['group']; + } + + return false; + } + + /** + * Get the list of parameter groups. + * + * @return array list of parameter groups + * + * @access public + * + */ + function getGroups() + { + $tmp = array(); + foreach ($this->configuration_info as $key => $info) { + $tmp[$info['group']] = 1; + } + + return array_keys($tmp); + } + + /** + * Get the list of the parameters in a group. + * + * @param string $group parameter group + * @return array list of parameters in $group + * + * @access public + * + */ + function getGroupKeys($group) + { + $keys = array(); + foreach ($this->configuration_info as $key => $info) { + if ($info['group'] == $group) { + $keys[] = $key; + } + } + + return $keys; + } + + /** + * Get the list of allowed set values for a config value. Returns + * NULL for config values that are not sets. + * + * @param string config key + * @return array enumerated array of set values, or NULL if the + * config key is unknown or not a set + * + * @access public + * + */ + function getSetValues($key) + { + if (isset($this->configuration_info[$key]) && + isset($this->configuration_info[$key]['type']) && + $this->configuration_info[$key]['type'] == 'set') + { + $valid_set = $this->configuration_info[$key]['valid_set']; + reset($valid_set); + if (key($valid_set) === 0) { + return $valid_set; + } + + return array_keys($valid_set); + } + + return null; + } + + /** + * Get all the current config keys. + * + * @return array simple array of config keys + * + * @access public + */ + function getKeys() + { + $keys = array(); + foreach ($this->layers as $layer) { + $test = $this->configuration[$layer]; + if (isset($test['__channels'])) { + foreach ($test['__channels'] as $channel => $configs) { + $keys = array_merge($keys, $configs); + } + } + + unset($test['__channels']); + $keys = array_merge($keys, $test); + + } + return array_keys($keys); + } + + /** + * Remove the a config key from a specific config layer. + * + * @param string config key + * @param string (optional) config layer + * @param string (optional) channel (defaults to default channel) + * @return bool TRUE on success, FALSE on failure + * + * @access public + */ + function remove($key, $layer = 'user', $channel = null) + { + if ($channel === null) { + $channel = $this->getDefaultChannel(); + } + + if ($channel !== 'pear.php.net') { + if (isset($this->configuration[$layer]['__channels'][$channel][$key])) { + unset($this->configuration[$layer]['__channels'][$channel][$key]); + return true; + } + } + + if (isset($this->configuration[$layer][$key])) { + unset($this->configuration[$layer][$key]); + return true; + } + + return false; + } + + /** + * Temporarily remove an entire config layer. USE WITH CARE! + * + * @param string config key + * @param string (optional) config layer + * @return bool TRUE on success, FALSE on failure + * + * @access public + */ + function removeLayer($layer) + { + if (isset($this->configuration[$layer])) { + $this->configuration[$layer] = array(); + return true; + } + + return false; + } + + /** + * Stores configuration data in a layer. + * + * @param string config layer to store + * @return bool TRUE on success, or PEAR error on failure + * + * @access public + */ + function store($layer = 'user', $data = null) + { + return $this->writeConfigFile(null, $layer, $data); + } + + /** + * Tells what config layer that gets to define a key. + * + * @param string config key + * @param boolean return the defining channel + * + * @return string|array the config layer, or an empty string if not found. + * + * if $returnchannel, the return is an array array('layer' => layername, + * 'channel' => channelname), or an empty string if not found + * + * @access public + */ + function definedBy($key, $returnchannel = false) + { + foreach ($this->layers as $layer) { + $channel = $this->getDefaultChannel(); + if ($channel !== 'pear.php.net') { + if (isset($this->configuration[$layer]['__channels'][$channel][$key])) { + if ($returnchannel) { + return array('layer' => $layer, 'channel' => $channel); + } + return $layer; + } + } + + if (isset($this->configuration[$layer][$key])) { + if ($returnchannel) { + return array('layer' => $layer, 'channel' => 'pear.php.net'); + } + return $layer; + } + } + + return ''; + } + + /** + * Tells whether a given key exists as a config value. + * + * @param string config key + * @return bool whether exists in this object + * + * @access public + */ + function isDefined($key) + { + foreach ($this->layers as $layer) { + if (isset($this->configuration[$layer][$key])) { + return true; + } + } + + return false; + } + + /** + * Tells whether a given config layer exists. + * + * @param string config layer + * @return bool whether exists in this object + * + * @access public + */ + function isDefinedLayer($layer) + { + return isset($this->configuration[$layer]); + } + + /** + * Returns the layers defined (except the 'default' one) + * + * @return array of the defined layers + */ + function getLayers() + { + $cf = $this->configuration; + unset($cf['default']); + return array_keys($cf); + } + + function apiVersion() + { + return '1.1'; + } + + /** + * @return PEAR_Registry + */ + function &getRegistry($use = null) + { + $layer = $use === null ? 'user' : $use; + if (isset($this->_registry[$layer])) { + return $this->_registry[$layer]; + } elseif ($use === null && isset($this->_registry['system'])) { + return $this->_registry['system']; + } elseif ($use === null && isset($this->_registry['default'])) { + return $this->_registry['default']; + } elseif ($use) { + $a = false; + return $a; + } + + // only go here if null was passed in + echo "CRITICAL ERROR: Registry could not be initialized from any value"; + exit(1); + } + + /** + * This is to allow customization like the use of installroot + * @param PEAR_Registry + * @return bool + */ + function setRegistry(&$reg, $layer = 'user') + { + if ($this->_noRegistry) { + return false; + } + + if (!in_array($layer, array('user', 'system'))) { + return false; + } + + $this->_registry[$layer] = &$reg; + if (is_object($reg)) { + $this->_registry[$layer]->setConfig($this, false); + } + + return true; + } + + function noRegistry() + { + $this->_noRegistry = true; + } + + /** + * @return PEAR_REST + */ + function &getREST($version, $options = array()) + { + $version = str_replace('.', '', $version); + if (!class_exists($class = 'PEAR_REST_' . $version)) { + require_once 'PEAR/REST/' . $version . '.php'; + } + + $remote = new $class($this, $options); + return $remote; + } + + /** + * The ftp server is set in {@link readFTPConfigFile()}. It exists only if a + * remote configuration file has been specified + * @return PEAR_FTP|false + */ + function &getFTP() + { + if (isset($this->_ftp)) { + return $this->_ftp; + } + + $a = false; + return $a; + } + + function _prependPath($path, $prepend) + { + if (strlen($prepend) > 0) { + if (OS_WINDOWS && preg_match('/^[a-z]:/i', $path)) { + if (preg_match('/^[a-z]:/i', $prepend)) { + $prepend = substr($prepend, 2); + } elseif ($prepend{0} != '\\') { + $prepend = "\\$prepend"; + } + $path = substr($path, 0, 2) . $prepend . substr($path, 2); + } else { + $path = $prepend . $path; + } + } + return $path; + } + + /** + * @param string|false installation directory to prepend to all _dir variables, or false to + * disable + */ + function setInstallRoot($root) + { + if (substr($root, -1) == DIRECTORY_SEPARATOR) { + $root = substr($root, 0, -1); + } + $old = $this->_installRoot; + $this->_installRoot = $root; + if (($old != $root) && !$this->_noRegistry) { + foreach (array_keys($this->_registry) as $layer) { + if ($layer == 'ftp' || !isset($this->_registry[$layer])) { + continue; + } + $this->_registry[$layer] = + new PEAR_Registry( + $this->get('php_dir', $layer, 'pear.php.net'), false, false, + $this->get('metadata_dir', $layer, 'pear.php.net')); + $this->_registry[$layer]->setConfig($this, false); + $this->_regInitialized[$layer] = false; + } + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Dependency2.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Dependency2.php new file mode 100644 index 0000000..635c551 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Dependency2.php @@ -0,0 +1,1357 @@ + + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * Required for the PEAR_VALIDATE_* constants + */ +require_once 'PEAR/Validate.php'; + +/** + * Dependency check for PEAR packages + * + * This class handles both version 1.0 and 2.0 dependencies + * WARNING: *any* changes to this class must be duplicated in the + * test_PEAR_Dependency2 class found in tests/PEAR_Dependency2/setup.php.inc, + * or unit tests will not actually validate the changes + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Dependency2 +{ + /** + * One of the PEAR_VALIDATE_* states + * @see PEAR_VALIDATE_NORMAL + * @var integer + */ + var $_state; + + /** + * Command-line options to install/upgrade/uninstall commands + * @param array + */ + var $_options; + + /** + * @var OS_Guess + */ + var $_os; + + /** + * @var PEAR_Registry + */ + var $_registry; + + /** + * @var PEAR_Config + */ + var $_config; + + /** + * @var PEAR_DependencyDB + */ + var $_dependencydb; + + /** + * Output of PEAR_Registry::parsedPackageName() + * @var array + */ + var $_currentPackage; + + /** + * @param PEAR_Config + * @param array installation options + * @param array format of PEAR_Registry::parsedPackageName() + * @param int installation state (one of PEAR_VALIDATE_*) + */ + function __construct(&$config, $installoptions, $package, + $state = PEAR_VALIDATE_INSTALLING) + { + $this->_config = &$config; + if (!class_exists('PEAR_DependencyDB')) { + require_once 'PEAR/DependencyDB.php'; + } + + if (isset($installoptions['packagingroot'])) { + // make sure depdb is in the right location + $config->setInstallRoot($installoptions['packagingroot']); + } + + $this->_registry = &$config->getRegistry(); + $this->_dependencydb = &PEAR_DependencyDB::singleton($config); + if (isset($installoptions['packagingroot'])) { + $config->setInstallRoot(false); + } + + $this->_options = $installoptions; + $this->_state = $state; + if (!class_exists('OS_Guess')) { + require_once 'OS/Guess.php'; + } + + $this->_os = new OS_Guess; + $this->_currentPackage = $package; + } + + function _getExtraString($dep) + { + $extra = ' ('; + if (isset($dep['uri'])) { + return ''; + } + + if (isset($dep['recommended'])) { + $extra .= 'recommended version ' . $dep['recommended']; + } else { + if (isset($dep['min'])) { + $extra .= 'version >= ' . $dep['min']; + } + + if (isset($dep['max'])) { + if ($extra != ' (') { + $extra .= ', '; + } + $extra .= 'version <= ' . $dep['max']; + } + + if (isset($dep['exclude'])) { + if (!is_array($dep['exclude'])) { + $dep['exclude'] = array($dep['exclude']); + } + + if ($extra != ' (') { + $extra .= ', '; + } + + $extra .= 'excluded versions: '; + foreach ($dep['exclude'] as $i => $exclude) { + if ($i) { + $extra .= ', '; + } + $extra .= $exclude; + } + } + } + + $extra .= ')'; + if ($extra == ' ()') { + $extra = ''; + } + + return $extra; + } + + /** + * This makes unit-testing a heck of a lot easier + */ + function getPHP_OS() + { + return PHP_OS; + } + + /** + * This makes unit-testing a heck of a lot easier + */ + function getsysname() + { + return $this->_os->getSysname(); + } + + /** + * Specify a dependency on an OS. Use arch for detailed os/processor information + * + * There are two generic OS dependencies that will be the most common, unix and windows. + * Other options are linux, freebsd, darwin (OS X), sunos, irix, hpux, aix + */ + function validateOsDependency($dep) + { + if ($this->_state != PEAR_VALIDATE_INSTALLING && $this->_state != PEAR_VALIDATE_DOWNLOADING) { + return true; + } + + if ($dep['name'] == '*') { + return true; + } + + $not = isset($dep['conflicts']) ? true : false; + switch (strtolower($dep['name'])) { + case 'windows' : + if ($not) { + if (strtolower(substr($this->getPHP_OS(), 0, 3)) == 'win') { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError("Cannot install %s on Windows"); + } + + return $this->warning("warning: Cannot install %s on Windows"); + } + } else { + if (strtolower(substr($this->getPHP_OS(), 0, 3)) != 'win') { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError("Can only install %s on Windows"); + } + + return $this->warning("warning: Can only install %s on Windows"); + } + } + break; + case 'unix' : + $unices = array('linux', 'freebsd', 'darwin', 'sunos', 'irix', 'hpux', 'aix'); + if ($not) { + if (in_array($this->getSysname(), $unices)) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError("Cannot install %s on any Unix system"); + } + + return $this->warning( "warning: Cannot install %s on any Unix system"); + } + } else { + if (!in_array($this->getSysname(), $unices)) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError("Can only install %s on a Unix system"); + } + + return $this->warning("warning: Can only install %s on a Unix system"); + } + } + break; + default : + if ($not) { + if (strtolower($dep['name']) == strtolower($this->getSysname())) { + if (!isset($this->_options['nodeps']) && + !isset($this->_options['force'])) { + return $this->raiseError('Cannot install %s on ' . $dep['name'] . + ' operating system'); + } + + return $this->warning('warning: Cannot install %s on ' . + $dep['name'] . ' operating system'); + } + } else { + if (strtolower($dep['name']) != strtolower($this->getSysname())) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('Cannot install %s on ' . + $this->getSysname() . + ' operating system, can only install on ' . $dep['name']); + } + + return $this->warning('warning: Cannot install %s on ' . + $this->getSysname() . + ' operating system, can only install on ' . $dep['name']); + } + } + } + return true; + } + + /** + * This makes unit-testing a heck of a lot easier + */ + function matchSignature($pattern) + { + return $this->_os->matchSignature($pattern); + } + + /** + * Specify a complex dependency on an OS/processor/kernel version, + * Use OS for simple operating system dependency. + * + * This is the only dependency that accepts an eregable pattern. The pattern + * will be matched against the php_uname() output parsed by OS_Guess + */ + function validateArchDependency($dep) + { + if ($this->_state != PEAR_VALIDATE_INSTALLING) { + return true; + } + + $not = isset($dep['conflicts']) ? true : false; + if (!$this->matchSignature($dep['pattern'])) { + if (!$not) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s Architecture dependency failed, does not ' . + 'match "' . $dep['pattern'] . '"'); + } + + return $this->warning('warning: %s Architecture dependency failed, does ' . + 'not match "' . $dep['pattern'] . '"'); + } + + return true; + } + + if ($not) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s Architecture dependency failed, required "' . + $dep['pattern'] . '"'); + } + + return $this->warning('warning: %s Architecture dependency failed, ' . + 'required "' . $dep['pattern'] . '"'); + } + + return true; + } + + /** + * This makes unit-testing a heck of a lot easier + */ + function extension_loaded($name) + { + return extension_loaded($name); + } + + /** + * This makes unit-testing a heck of a lot easier + */ + function phpversion($name = null) + { + if ($name !== null) { + return phpversion($name); + } + + return phpversion(); + } + + function validateExtensionDependency($dep, $required = true) + { + if ($this->_state != PEAR_VALIDATE_INSTALLING && + $this->_state != PEAR_VALIDATE_DOWNLOADING) { + return true; + } + + $loaded = $this->extension_loaded($dep['name']); + $extra = $this->_getExtraString($dep); + if (isset($dep['exclude'])) { + if (!is_array($dep['exclude'])) { + $dep['exclude'] = array($dep['exclude']); + } + } + + if (!isset($dep['min']) && !isset($dep['max']) && + !isset($dep['recommended']) && !isset($dep['exclude']) + ) { + if ($loaded) { + if (isset($dep['conflicts'])) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s conflicts with PHP extension "' . + $dep['name'] . '"' . $extra); + } + + return $this->warning('warning: %s conflicts with PHP extension "' . + $dep['name'] . '"' . $extra); + } + + return true; + } + + if (isset($dep['conflicts'])) { + return true; + } + + if ($required) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s requires PHP extension "' . + $dep['name'] . '"' . $extra); + } + + return $this->warning('warning: %s requires PHP extension "' . + $dep['name'] . '"' . $extra); + } + + return $this->warning('%s can optionally use PHP extension "' . + $dep['name'] . '"' . $extra); + } + + if (!$loaded) { + if (isset($dep['conflicts'])) { + return true; + } + + if (!$required) { + return $this->warning('%s can optionally use PHP extension "' . + $dep['name'] . '"' . $extra); + } + + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s requires PHP extension "' . $dep['name'] . + '"' . $extra); + } + + return $this->warning('warning: %s requires PHP extension "' . $dep['name'] . + '"' . $extra); + } + + $version = (string) $this->phpversion($dep['name']); + if (empty($version)) { + $version = '0'; + } + + $fail = false; + if (isset($dep['min']) && !version_compare($version, $dep['min'], '>=')) { + $fail = true; + } + + if (isset($dep['max']) && !version_compare($version, $dep['max'], '<=')) { + $fail = true; + } + + if ($fail && !isset($dep['conflicts'])) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s requires PHP extension "' . $dep['name'] . + '"' . $extra . ', installed version is ' . $version); + } + + return $this->warning('warning: %s requires PHP extension "' . $dep['name'] . + '"' . $extra . ', installed version is ' . $version); + } elseif ((isset($dep['min']) || isset($dep['max'])) && !$fail && isset($dep['conflicts'])) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s conflicts with PHP extension "' . + $dep['name'] . '"' . $extra . ', installed version is ' . $version); + } + + return $this->warning('warning: %s conflicts with PHP extension "' . + $dep['name'] . '"' . $extra . ', installed version is ' . $version); + } + + if (isset($dep['exclude'])) { + foreach ($dep['exclude'] as $exclude) { + if (version_compare($version, $exclude, '==')) { + if (isset($dep['conflicts'])) { + continue; + } + + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s is not compatible with PHP extension "' . + $dep['name'] . '" version ' . + $exclude); + } + + return $this->warning('warning: %s is not compatible with PHP extension "' . + $dep['name'] . '" version ' . + $exclude); + } elseif (version_compare($version, $exclude, '!=') && isset($dep['conflicts'])) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s conflicts with PHP extension "' . + $dep['name'] . '"' . $extra . ', installed version is ' . $version); + } + + return $this->warning('warning: %s conflicts with PHP extension "' . + $dep['name'] . '"' . $extra . ', installed version is ' . $version); + } + } + } + + if (isset($dep['recommended'])) { + if (version_compare($version, $dep['recommended'], '==')) { + return true; + } + + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s dependency: PHP extension ' . $dep['name'] . + ' version "' . $version . '"' . + ' is not the recommended version "' . $dep['recommended'] . + '", but may be compatible, use --force to install'); + } + + return $this->warning('warning: %s dependency: PHP extension ' . + $dep['name'] . ' version "' . $version . '"' . + ' is not the recommended version "' . $dep['recommended'].'"'); + } + + return true; + } + + function validatePhpDependency($dep) + { + if ($this->_state != PEAR_VALIDATE_INSTALLING && + $this->_state != PEAR_VALIDATE_DOWNLOADING) { + return true; + } + + $version = $this->phpversion(); + $extra = $this->_getExtraString($dep); + if (isset($dep['exclude'])) { + if (!is_array($dep['exclude'])) { + $dep['exclude'] = array($dep['exclude']); + } + } + + if (isset($dep['min'])) { + if (!version_compare($version, $dep['min'], '>=')) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s requires PHP' . + $extra . ', installed version is ' . $version); + } + + return $this->warning('warning: %s requires PHP' . + $extra . ', installed version is ' . $version); + } + } + + if (isset($dep['max'])) { + if (!version_compare($version, $dep['max'], '<=')) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s requires PHP' . + $extra . ', installed version is ' . $version); + } + + return $this->warning('warning: %s requires PHP' . + $extra . ', installed version is ' . $version); + } + } + + if (isset($dep['exclude'])) { + foreach ($dep['exclude'] as $exclude) { + if (version_compare($version, $exclude, '==')) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s is not compatible with PHP version ' . + $exclude); + } + + return $this->warning( + 'warning: %s is not compatible with PHP version ' . + $exclude); + } + } + } + + return true; + } + + /** + * This makes unit-testing a heck of a lot easier + */ + function getPEARVersion() + { + return '1.10.1'; + } + + function validatePearinstallerDependency($dep) + { + $pearversion = $this->getPEARVersion(); + $extra = $this->_getExtraString($dep); + if (isset($dep['exclude'])) { + if (!is_array($dep['exclude'])) { + $dep['exclude'] = array($dep['exclude']); + } + } + + if (version_compare($pearversion, $dep['min'], '<')) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s requires PEAR Installer' . $extra . + ', installed version is ' . $pearversion); + } + + return $this->warning('warning: %s requires PEAR Installer' . $extra . + ', installed version is ' . $pearversion); + } + + if (isset($dep['max'])) { + if (version_compare($pearversion, $dep['max'], '>')) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s requires PEAR Installer' . $extra . + ', installed version is ' . $pearversion); + } + + return $this->warning('warning: %s requires PEAR Installer' . $extra . + ', installed version is ' . $pearversion); + } + } + + if (isset($dep['exclude'])) { + if (!isset($dep['exclude'][0])) { + $dep['exclude'] = array($dep['exclude']); + } + + foreach ($dep['exclude'] as $exclude) { + if (version_compare($exclude, $pearversion, '==')) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s is not compatible with PEAR Installer ' . + 'version ' . $exclude); + } + + return $this->warning('warning: %s is not compatible with PEAR ' . + 'Installer version ' . $exclude); + } + } + } + + return true; + } + + function validateSubpackageDependency($dep, $required, $params) + { + return $this->validatePackageDependency($dep, $required, $params); + } + + /** + * @param array dependency information (2.0 format) + * @param boolean whether this is a required dependency + * @param array a list of downloaded packages to be installed, if any + * @param boolean if true, then deps on pear.php.net that fail will also check + * against pecl.php.net packages to accommodate extensions that have + * moved to pecl.php.net from pear.php.net + */ + function validatePackageDependency($dep, $required, $params, $depv1 = false) + { + if ($this->_state != PEAR_VALIDATE_INSTALLING && + $this->_state != PEAR_VALIDATE_DOWNLOADING) { + return true; + } + + if (isset($dep['providesextension'])) { + if ($this->extension_loaded($dep['providesextension'])) { + $save = $dep; + $subdep = $dep; + $subdep['name'] = $subdep['providesextension']; + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $ret = $this->validateExtensionDependency($subdep, $required); + PEAR::popErrorHandling(); + if (!PEAR::isError($ret)) { + return true; + } + } + } + + if ($this->_state == PEAR_VALIDATE_INSTALLING) { + return $this->_validatePackageInstall($dep, $required, $depv1); + } + + if ($this->_state == PEAR_VALIDATE_DOWNLOADING) { + return $this->_validatePackageDownload($dep, $required, $params, $depv1); + } + } + + function _validatePackageDownload($dep, $required, $params, $depv1 = false) + { + $dep['package'] = $dep['name']; + if (isset($dep['uri'])) { + $dep['channel'] = '__uri'; + } + + $depname = $this->_registry->parsedPackageNameToString($dep, true); + $found = false; + foreach ($params as $param) { + if ($param->isEqual( + array('package' => $dep['name'], + 'channel' => $dep['channel']))) { + $found = true; + break; + } + + if ($depv1 && $dep['channel'] == 'pear.php.net') { + if ($param->isEqual( + array('package' => $dep['name'], + 'channel' => 'pecl.php.net'))) { + $found = true; + break; + } + } + } + + if (!$found && isset($dep['providesextension'])) { + foreach ($params as $param) { + if ($param->isExtension($dep['providesextension'])) { + $found = true; + break; + } + } + } + + if ($found) { + $version = $param->getVersion(); + $installed = false; + $downloaded = true; + } else { + if ($this->_registry->packageExists($dep['name'], $dep['channel'])) { + $installed = true; + $downloaded = false; + $version = $this->_registry->packageinfo($dep['name'], 'version', + $dep['channel']); + } else { + if ($dep['channel'] == 'pecl.php.net' && $this->_registry->packageExists($dep['name'], + 'pear.php.net')) { + $installed = true; + $downloaded = false; + $version = $this->_registry->packageinfo($dep['name'], 'version', + 'pear.php.net'); + } else { + $version = 'not installed or downloaded'; + $installed = false; + $downloaded = false; + } + } + } + + $extra = $this->_getExtraString($dep); + if (isset($dep['exclude']) && !is_array($dep['exclude'])) { + $dep['exclude'] = array($dep['exclude']); + } + + if (!isset($dep['min']) && !isset($dep['max']) && + !isset($dep['recommended']) && !isset($dep['exclude']) + ) { + if ($installed || $downloaded) { + $installed = $installed ? 'installed' : 'downloaded'; + if (isset($dep['conflicts'])) { + $rest = ''; + if ($version) { + $rest = ", $installed version is " . $version; + } + + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s conflicts with package "' . $depname . '"' . $extra . $rest); + } + + return $this->warning('warning: %s conflicts with package "' . $depname . '"' . $extra . $rest); + } + + return true; + } + + if (isset($dep['conflicts'])) { + return true; + } + + if ($required) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s requires package "' . $depname . '"' . $extra); + } + + return $this->warning('warning: %s requires package "' . $depname . '"' . $extra); + } + + return $this->warning('%s can optionally use package "' . $depname . '"' . $extra); + } + + if (!$installed && !$downloaded) { + if (isset($dep['conflicts'])) { + return true; + } + + if ($required) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s requires package "' . $depname . '"' . $extra); + } + + return $this->warning('warning: %s requires package "' . $depname . '"' . $extra); + } + + return $this->warning('%s can optionally use package "' . $depname . '"' . $extra); + } + + $fail = false; + if (isset($dep['min']) && version_compare($version, $dep['min'], '<')) { + $fail = true; + } + + if (isset($dep['max']) && version_compare($version, $dep['max'], '>')) { + $fail = true; + } + + if ($fail && !isset($dep['conflicts'])) { + $installed = $installed ? 'installed' : 'downloaded'; + $dep['package'] = $dep['name']; + $dep = $this->_registry->parsedPackageNameToString($dep, true); + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s requires package "' . $depname . '"' . + $extra . ", $installed version is " . $version); + } + + return $this->warning('warning: %s requires package "' . $depname . '"' . + $extra . ", $installed version is " . $version); + } elseif ((isset($dep['min']) || isset($dep['max'])) && !$fail && + isset($dep['conflicts']) && !isset($dep['exclude'])) { + $installed = $installed ? 'installed' : 'downloaded'; + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s conflicts with package "' . $depname . '"' . $extra . + ", $installed version is " . $version); + } + + return $this->warning('warning: %s conflicts with package "' . $depname . '"' . + $extra . ", $installed version is " . $version); + } + + if (isset($dep['exclude'])) { + $installed = $installed ? 'installed' : 'downloaded'; + foreach ($dep['exclude'] as $exclude) { + if (version_compare($version, $exclude, '==') && !isset($dep['conflicts'])) { + if (!isset($this->_options['nodeps']) && + !isset($this->_options['force']) + ) { + return $this->raiseError('%s is not compatible with ' . + $installed . ' package "' . + $depname . '" version ' . + $exclude); + } + + return $this->warning('warning: %s is not compatible with ' . + $installed . ' package "' . + $depname . '" version ' . + $exclude); + } elseif (version_compare($version, $exclude, '!=') && isset($dep['conflicts'])) { + $installed = $installed ? 'installed' : 'downloaded'; + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s conflicts with package "' . $depname . '"' . + $extra . ", $installed version is " . $version); + } + + return $this->warning('warning: %s conflicts with package "' . $depname . '"' . + $extra . ", $installed version is " . $version); + } + } + } + + if (isset($dep['recommended'])) { + $installed = $installed ? 'installed' : 'downloaded'; + if (version_compare($version, $dep['recommended'], '==')) { + return true; + } + + if (!$found && $installed) { + $param = $this->_registry->getPackage($dep['name'], $dep['channel']); + } + + if ($param) { + $found = false; + foreach ($params as $parent) { + if ($parent->isEqual($this->_currentPackage)) { + $found = true; + break; + } + } + + if ($found) { + if ($param->isCompatible($parent)) { + return true; + } + } else { // this is for validPackage() calls + $parent = $this->_registry->getPackage($this->_currentPackage['package'], + $this->_currentPackage['channel']); + if ($parent !== null && $param->isCompatible($parent)) { + return true; + } + } + } + + if (!isset($this->_options['nodeps']) && !isset($this->_options['force']) && + !isset($this->_options['loose']) + ) { + return $this->raiseError('%s dependency package "' . $depname . + '" ' . $installed . ' version ' . $version . + ' is not the recommended version ' . $dep['recommended'] . + ', but may be compatible, use --force to install'); + } + + return $this->warning('warning: %s dependency package "' . $depname . + '" ' . $installed . ' version ' . $version . + ' is not the recommended version ' . $dep['recommended']); + } + + return true; + } + + function _validatePackageInstall($dep, $required, $depv1 = false) + { + return $this->_validatePackageDownload($dep, $required, array(), $depv1); + } + + /** + * Verify that uninstalling packages passed in to command line is OK. + * + * @param PEAR_Installer $dl + * @return PEAR_Error|true + */ + function validatePackageUninstall(&$dl) + { + if (PEAR::isError($this->_dependencydb)) { + return $this->_dependencydb; + } + + $params = array(); + // construct an array of "downloaded" packages to fool the package dependency checker + // into using these to validate uninstalls of circular dependencies + $downloaded = &$dl->getUninstallPackages(); + foreach ($downloaded as $i => $pf) { + if (!class_exists('PEAR_Downloader_Package')) { + require_once 'PEAR/Downloader/Package.php'; + } + $dp = new PEAR_Downloader_Package($dl); + $dp->setPackageFile($downloaded[$i]); + $params[$i] = $dp; + } + + // check cache + $memyselfandI = strtolower($this->_currentPackage['channel']) . '/' . + strtolower($this->_currentPackage['package']); + if (isset($dl->___uninstall_package_cache)) { + $badpackages = $dl->___uninstall_package_cache; + if (isset($badpackages[$memyselfandI]['warnings'])) { + foreach ($badpackages[$memyselfandI]['warnings'] as $warning) { + $dl->log(0, $warning[0]); + } + } + + if (isset($badpackages[$memyselfandI]['errors'])) { + foreach ($badpackages[$memyselfandI]['errors'] as $error) { + if (is_array($error)) { + $dl->log(0, $error[0]); + } else { + $dl->log(0, $error->getMessage()); + } + } + + if (isset($this->_options['nodeps']) || isset($this->_options['force'])) { + return $this->warning( + 'warning: %s should not be uninstalled, other installed packages depend ' . + 'on this package'); + } + + return $this->raiseError( + '%s cannot be uninstalled, other installed packages depend on this package'); + } + + return true; + } + + // first, list the immediate parents of each package to be uninstalled + $perpackagelist = array(); + $allparents = array(); + foreach ($params as $i => $param) { + $a = array( + 'channel' => strtolower($param->getChannel()), + 'package' => strtolower($param->getPackage()) + ); + + $deps = $this->_dependencydb->getDependentPackages($a); + if ($deps) { + foreach ($deps as $d) { + $pardeps = $this->_dependencydb->getDependencies($d); + foreach ($pardeps as $dep) { + if (strtolower($dep['dep']['channel']) == $a['channel'] && + strtolower($dep['dep']['name']) == $a['package']) { + if (!isset($perpackagelist[$a['channel'] . '/' . $a['package']])) { + $perpackagelist[$a['channel'] . '/' . $a['package']] = array(); + } + $perpackagelist[$a['channel'] . '/' . $a['package']][] + = array($d['channel'] . '/' . $d['package'], $dep); + if (!isset($allparents[$d['channel'] . '/' . $d['package']])) { + $allparents[$d['channel'] . '/' . $d['package']] = array(); + } + if (!isset($allparents[$d['channel'] . '/' . $d['package']][$a['channel'] . '/' . $a['package']])) { + $allparents[$d['channel'] . '/' . $d['package']][$a['channel'] . '/' . $a['package']] = array(); + } + $allparents[$d['channel'] . '/' . $d['package']] + [$a['channel'] . '/' . $a['package']][] + = array($d, $dep); + } + } + } + } + } + + // next, remove any packages from the parents list that are not installed + $remove = array(); + foreach ($allparents as $parent => $d1) { + foreach ($d1 as $d) { + if ($this->_registry->packageExists($d[0][0]['package'], $d[0][0]['channel'])) { + continue; + } + $remove[$parent] = true; + } + } + + // next remove any packages from the parents list that are not passed in for + // uninstallation + foreach ($allparents as $parent => $d1) { + foreach ($d1 as $d) { + foreach ($params as $param) { + if (strtolower($param->getChannel()) == $d[0][0]['channel'] && + strtolower($param->getPackage()) == $d[0][0]['package']) { + // found it + continue 3; + } + } + $remove[$parent] = true; + } + } + + // remove all packages whose dependencies fail + // save which ones failed for error reporting + $badchildren = array(); + do { + $fail = false; + foreach ($remove as $package => $unused) { + if (!isset($allparents[$package])) { + continue; + } + + foreach ($allparents[$package] as $kid => $d1) { + foreach ($d1 as $depinfo) { + if ($depinfo[1]['type'] != 'optional') { + if (isset($badchildren[$kid])) { + continue; + } + $badchildren[$kid] = true; + $remove[$kid] = true; + $fail = true; + continue 2; + } + } + } + if ($fail) { + // start over, we removed some children + continue 2; + } + } + } while ($fail); + + // next, construct the list of packages that can't be uninstalled + $badpackages = array(); + $save = $this->_currentPackage; + foreach ($perpackagelist as $package => $packagedeps) { + foreach ($packagedeps as $parent) { + if (!isset($remove[$parent[0]])) { + continue; + } + + $packagename = $this->_registry->parsePackageName($parent[0]); + $packagename['channel'] = $this->_registry->channelAlias($packagename['channel']); + $pa = $this->_registry->getPackage($packagename['package'], $packagename['channel']); + $packagename['package'] = $pa->getPackage(); + $this->_currentPackage = $packagename; + // parent is not present in uninstall list, make sure we can actually + // uninstall it (parent dep is optional) + $parentname['channel'] = $this->_registry->channelAlias($parent[1]['dep']['channel']); + $pa = $this->_registry->getPackage($parent[1]['dep']['name'], $parent[1]['dep']['channel']); + $parentname['package'] = $pa->getPackage(); + $parent[1]['dep']['package'] = $parentname['package']; + $parent[1]['dep']['channel'] = $parentname['channel']; + if ($parent[1]['type'] == 'optional') { + $test = $this->_validatePackageUninstall($parent[1]['dep'], false, $dl); + if ($test !== true) { + $badpackages[$package]['warnings'][] = $test; + } + } else { + $test = $this->_validatePackageUninstall($parent[1]['dep'], true, $dl); + if ($test !== true) { + $badpackages[$package]['errors'][] = $test; + } + } + } + } + + $this->_currentPackage = $save; + $dl->___uninstall_package_cache = $badpackages; + if (isset($badpackages[$memyselfandI])) { + if (isset($badpackages[$memyselfandI]['warnings'])) { + foreach ($badpackages[$memyselfandI]['warnings'] as $warning) { + $dl->log(0, $warning[0]); + } + } + + if (isset($badpackages[$memyselfandI]['errors'])) { + foreach ($badpackages[$memyselfandI]['errors'] as $error) { + if (is_array($error)) { + $dl->log(0, $error[0]); + } else { + $dl->log(0, $error->getMessage()); + } + } + + if (isset($this->_options['nodeps']) || isset($this->_options['force'])) { + return $this->warning( + 'warning: %s should not be uninstalled, other installed packages depend ' . + 'on this package'); + } + + return $this->raiseError( + '%s cannot be uninstalled, other installed packages depend on this package'); + } + } + + return true; + } + + function _validatePackageUninstall($dep, $required, $dl) + { + $depname = $this->_registry->parsedPackageNameToString($dep, true); + $version = $this->_registry->packageinfo($dep['package'], 'version', $dep['channel']); + if (!$version) { + return true; + } + + $extra = $this->_getExtraString($dep); + if (isset($dep['exclude']) && !is_array($dep['exclude'])) { + $dep['exclude'] = array($dep['exclude']); + } + + if (isset($dep['conflicts'])) { + return true; // uninstall OK - these packages conflict (probably installed with --force) + } + + if (!isset($dep['min']) && !isset($dep['max'])) { + if (!$required) { + return $this->warning('"' . $depname . '" can be optionally used by ' . + 'installed package %s' . $extra); + } + + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('"' . $depname . '" is required by ' . + 'installed package %s' . $extra); + } + + return $this->warning('warning: "' . $depname . '" is required by ' . + 'installed package %s' . $extra); + } + + $fail = false; + if (isset($dep['min']) && version_compare($version, $dep['min'], '>=')) { + $fail = true; + } + + if (isset($dep['max']) && version_compare($version, $dep['max'], '<=')) { + $fail = true; + } + + // we re-use this variable, preserve the original value + $saverequired = $required; + if (!$required) { + return $this->warning($depname . $extra . ' can be optionally used by installed package' . + ' "%s"'); + } + + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError($depname . $extra . ' is required by installed package' . + ' "%s"'); + } + + return $this->raiseError('warning: ' . $depname . $extra . + ' is required by installed package "%s"'); + } + + /** + * validate a downloaded package against installed packages + * + * As of PEAR 1.4.3, this will only validate + * + * @param array|PEAR_Downloader_Package|PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * $pkg package identifier (either + * array('package' => blah, 'channel' => blah) or an array with + * index 'info' referencing an object) + * @param PEAR_Downloader $dl + * @param array $params full list of packages to install + * @return true|PEAR_Error + */ + function validatePackage($pkg, &$dl, $params = array()) + { + if (is_array($pkg) && isset($pkg['info'])) { + $deps = $this->_dependencydb->getDependentPackageDependencies($pkg['info']); + } else { + $deps = $this->_dependencydb->getDependentPackageDependencies($pkg); + } + + $fail = false; + if ($deps) { + if (!class_exists('PEAR_Downloader_Package')) { + require_once 'PEAR/Downloader/Package.php'; + } + + $dp = new PEAR_Downloader_Package($dl); + if (is_object($pkg)) { + $dp->setPackageFile($pkg); + } else { + $dp->setDownloadURL($pkg); + } + + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + foreach ($deps as $channel => $info) { + foreach ($info as $package => $ds) { + foreach ($params as $packd) { + if (strtolower($packd->getPackage()) == strtolower($package) && + $packd->getChannel() == $channel) { + $dl->log(3, 'skipping installed package check of "' . + $this->_registry->parsedPackageNameToString( + array('channel' => $channel, 'package' => $package), + true) . + '", version "' . $packd->getVersion() . '" will be ' . + 'downloaded and installed'); + continue 2; // jump to next package + } + } + + foreach ($ds as $d) { + $checker = new PEAR_Dependency2($this->_config, $this->_options, + array('channel' => $channel, 'package' => $package), $this->_state); + $dep = $d['dep']; + $required = $d['type'] == 'required'; + $ret = $checker->_validatePackageDownload($dep, $required, array(&$dp)); + if (is_array($ret)) { + $dl->log(0, $ret[0]); + } elseif (PEAR::isError($ret)) { + $dl->log(0, $ret->getMessage()); + $fail = true; + } + } + } + } + PEAR::popErrorHandling(); + } + + if ($fail) { + return $this->raiseError( + '%s cannot be installed, conflicts with installed packages'); + } + + return true; + } + + /** + * validate a package.xml 1.0 dependency + */ + function validateDependency1($dep, $params = array()) + { + if (!isset($dep['optional'])) { + $dep['optional'] = 'no'; + } + + list($newdep, $type) = $this->normalizeDep($dep); + if (!$newdep) { + return $this->raiseError("Invalid Dependency"); + } + + if (method_exists($this, "validate{$type}Dependency")) { + return $this->{"validate{$type}Dependency"}($newdep, $dep['optional'] == 'no', + $params, true); + } + } + + /** + * Convert a 1.0 dep into a 2.0 dep + */ + function normalizeDep($dep) + { + $types = array( + 'pkg' => 'Package', + 'ext' => 'Extension', + 'os' => 'Os', + 'php' => 'Php' + ); + + if (!isset($types[$dep['type']])) { + return array(false, false); + } + + $type = $types[$dep['type']]; + + $newdep = array(); + switch ($type) { + case 'Package' : + $newdep['channel'] = 'pear.php.net'; + case 'Extension' : + case 'Os' : + $newdep['name'] = $dep['name']; + break; + } + + $dep['rel'] = PEAR_Dependency2::signOperator($dep['rel']); + switch ($dep['rel']) { + case 'has' : + return array($newdep, $type); + break; + case 'not' : + $newdep['conflicts'] = true; + break; + case '>=' : + case '>' : + $newdep['min'] = $dep['version']; + if ($dep['rel'] == '>') { + $newdep['exclude'] = $dep['version']; + } + break; + case '<=' : + case '<' : + $newdep['max'] = $dep['version']; + if ($dep['rel'] == '<') { + $newdep['exclude'] = $dep['version']; + } + break; + case 'ne' : + case '!=' : + $newdep['min'] = '0'; + $newdep['max'] = '100000'; + $newdep['exclude'] = $dep['version']; + break; + case '==' : + $newdep['min'] = $dep['version']; + $newdep['max'] = $dep['version']; + break; + } + if ($type == 'Php') { + if (!isset($newdep['min'])) { + $newdep['min'] = '4.4.0'; + } + + if (!isset($newdep['max'])) { + $newdep['max'] = '6.0.0'; + } + } + return array($newdep, $type); + } + + /** + * Converts text comparing operators to them sign equivalents + * + * Example: 'ge' to '>=' + * + * @access public + * @param string Operator + * @return string Sign equivalent + */ + function signOperator($operator) + { + switch($operator) { + case 'lt': return '<'; + case 'le': return '<='; + case 'gt': return '>'; + case 'ge': return '>='; + case 'eq': return '=='; + case 'ne': return '!='; + default: + return $operator; + } + } + + function raiseError($msg) + { + if (isset($this->_options['ignore-errors'])) { + return $this->warning($msg); + } + + return PEAR::raiseError(sprintf($msg, $this->_registry->parsedPackageNameToString( + $this->_currentPackage, true))); + } + + function warning($msg) + { + return array(sprintf($msg, $this->_registry->parsedPackageNameToString( + $this->_currentPackage, true))); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/DependencyDB.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/DependencyDB.php new file mode 100644 index 0000000..1ee6043 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/DependencyDB.php @@ -0,0 +1,764 @@ + + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * Needed for error handling + */ +require_once 'PEAR.php'; +require_once 'PEAR/Config.php'; + +$GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'] = array(); +/** + * Track dependency relationships between installed packages + * @category pear + * @package PEAR + * @author Greg Beaver + * @author Tomas V.V.Cox + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_DependencyDB +{ + // {{{ properties + + /** + * This is initialized by {@link setConfig()} + * @var PEAR_Config + * @access private + */ + var $_config; + /** + * This is initialized by {@link setConfig()} + * @var PEAR_Registry + * @access private + */ + var $_registry; + /** + * Filename of the dependency DB (usually .depdb) + * @var string + * @access private + */ + var $_depdb = false; + /** + * File name of the lockfile (usually .depdblock) + * @var string + * @access private + */ + var $_lockfile = false; + /** + * Open file resource for locking the lockfile + * @var resource|false + * @access private + */ + var $_lockFp = false; + /** + * API version of this class, used to validate a file on-disk + * @var string + * @access private + */ + var $_version = '1.0'; + /** + * Cached dependency database file + * @var array|null + * @access private + */ + var $_cache; + + // }}} + // {{{ & singleton() + + /** + * Get a raw dependency database. Calls setConfig() and assertDepsDB() + * @param PEAR_Config + * @param string|false full path to the dependency database, or false to use default + * @return PEAR_DependencyDB|PEAR_Error + */ + public static function &singleton(&$config, $depdb = false) + { + $phpdir = $config->get('php_dir', null, 'pear.php.net'); + if (!isset($GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'][$phpdir])) { + $a = new PEAR_DependencyDB; + $GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'][$phpdir] = &$a; + $a->setConfig($config, $depdb); + $e = $a->assertDepsDB(); + if (PEAR::isError($e)) { + return $e; + } + } + + return $GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'][$phpdir]; + } + + /** + * Set up the registry/location of dependency DB + * @param PEAR_Config|false + * @param string|false full path to the dependency database, or false to use default + */ + function setConfig(&$config, $depdb = false) + { + if (!$config) { + $this->_config = &PEAR_Config::singleton(); + } else { + $this->_config = &$config; + } + + $this->_registry = &$this->_config->getRegistry(); + if (!$depdb) { + $dir = $this->_config->get('metadata_dir', null, 'pear.php.net'); + if (!$dir) { + $dir = $this->_config->get('php_dir', null, 'pear.php.net'); + } + $this->_depdb = $dir . DIRECTORY_SEPARATOR . '.depdb'; + } else { + $this->_depdb = $depdb; + } + + $this->_lockfile = dirname($this->_depdb) . DIRECTORY_SEPARATOR . '.depdblock'; + } + // }}} + + function hasWriteAccess() + { + if (!file_exists($this->_depdb)) { + $dir = $this->_depdb; + while ($dir && $dir != '.') { + $dir = dirname($dir); // cd .. + if ($dir != '.' && file_exists($dir)) { + if (is_writeable($dir)) { + return true; + } + + return false; + } + } + + return false; + } + + return is_writeable($this->_depdb); + } + + // {{{ assertDepsDB() + + /** + * Create the dependency database, if it doesn't exist. Error if the database is + * newer than the code reading it. + * @return void|PEAR_Error + */ + function assertDepsDB() + { + if (!is_file($this->_depdb)) { + $this->rebuildDB(); + return; + } + + $depdb = $this->_getDepDB(); + // Datatype format has been changed, rebuild the Deps DB + if ($depdb['_version'] < $this->_version) { + $this->rebuildDB(); + } + + if ($depdb['_version']{0} > $this->_version{0}) { + return PEAR::raiseError('Dependency database is version ' . + $depdb['_version'] . ', and we are version ' . + $this->_version . ', cannot continue'); + } + } + + /** + * Get a list of installed packages that depend on this package + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array + * @return array|false + */ + function getDependentPackages(&$pkg) + { + $data = $this->_getDepDB(); + if (is_object($pkg)) { + $channel = strtolower($pkg->getChannel()); + $package = strtolower($pkg->getPackage()); + } else { + $channel = strtolower($pkg['channel']); + $package = strtolower($pkg['package']); + } + + if (isset($data['packages'][$channel][$package])) { + return $data['packages'][$channel][$package]; + } + + return false; + } + + /** + * Get a list of the actual dependencies of installed packages that depend on + * a package. + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array + * @return array|false + */ + function getDependentPackageDependencies(&$pkg) + { + $data = $this->_getDepDB(); + if (is_object($pkg)) { + $channel = strtolower($pkg->getChannel()); + $package = strtolower($pkg->getPackage()); + } else { + $channel = strtolower($pkg['channel']); + $package = strtolower($pkg['package']); + } + + $depend = $this->getDependentPackages($pkg); + if (!$depend) { + return false; + } + + $dependencies = array(); + foreach ($depend as $info) { + $temp = $this->getDependencies($info); + foreach ($temp as $dep) { + if ( + isset($dep['dep'], $dep['dep']['channel'], $dep['dep']['name']) && + strtolower($dep['dep']['channel']) == $channel && + strtolower($dep['dep']['name']) == $package + ) { + if (!isset($dependencies[$info['channel']])) { + $dependencies[$info['channel']] = array(); + } + + if (!isset($dependencies[$info['channel']][$info['package']])) { + $dependencies[$info['channel']][$info['package']] = array(); + } + $dependencies[$info['channel']][$info['package']][] = $dep; + } + } + } + + return $dependencies; + } + + /** + * Get a list of dependencies of this installed package + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array + * @return array|false + */ + function getDependencies(&$pkg) + { + if (is_object($pkg)) { + $channel = strtolower($pkg->getChannel()); + $package = strtolower($pkg->getPackage()); + } else { + $channel = strtolower($pkg['channel']); + $package = strtolower($pkg['package']); + } + + $data = $this->_getDepDB(); + if (isset($data['dependencies'][$channel][$package])) { + return $data['dependencies'][$channel][$package]; + } + + return false; + } + + /** + * Determine whether $parent depends on $child, near or deep + * @param array|PEAR_PackageFile_v2|PEAR_PackageFile_v2 + * @param array|PEAR_PackageFile_v2|PEAR_PackageFile_v2 + */ + function dependsOn($parent, $child) + { + $c = array(); + $this->_getDepDB(); + return $this->_dependsOn($parent, $child, $c); + } + + function _dependsOn($parent, $child, &$checked) + { + if (is_object($parent)) { + $channel = strtolower($parent->getChannel()); + $package = strtolower($parent->getPackage()); + } else { + $channel = strtolower($parent['channel']); + $package = strtolower($parent['package']); + } + + if (is_object($child)) { + $depchannel = strtolower($child->getChannel()); + $deppackage = strtolower($child->getPackage()); + } else { + $depchannel = strtolower($child['channel']); + $deppackage = strtolower($child['package']); + } + + if (isset($checked[$channel][$package][$depchannel][$deppackage])) { + return false; // avoid endless recursion + } + + $checked[$channel][$package][$depchannel][$deppackage] = true; + if (!isset($this->_cache['dependencies'][$channel][$package])) { + return false; + } + + foreach ($this->_cache['dependencies'][$channel][$package] as $info) { + if (isset($info['dep']['uri'])) { + if (is_object($child)) { + if ($info['dep']['uri'] == $child->getURI()) { + return true; + } + } elseif (isset($child['uri'])) { + if ($info['dep']['uri'] == $child['uri']) { + return true; + } + } + return false; + } + + if (strtolower($info['dep']['channel']) == $depchannel && + strtolower($info['dep']['name']) == $deppackage) { + return true; + } + } + + foreach ($this->_cache['dependencies'][$channel][$package] as $info) { + if (isset($info['dep']['uri'])) { + if ($this->_dependsOn(array( + 'uri' => $info['dep']['uri'], + 'package' => $info['dep']['name']), $child, $checked)) { + return true; + } + } else { + if ($this->_dependsOn(array( + 'channel' => $info['dep']['channel'], + 'package' => $info['dep']['name']), $child, $checked)) { + return true; + } + } + } + + return false; + } + + /** + * Register dependencies of a package that is being installed or upgraded + * @param PEAR_PackageFile_v2|PEAR_PackageFile_v2 + */ + function installPackage(&$package) + { + $data = $this->_getDepDB(); + unset($this->_cache); + $this->_setPackageDeps($data, $package); + $this->_writeDepDB($data); + } + + /** + * Remove dependencies of a package that is being uninstalled, or upgraded. + * + * Upgraded packages first uninstall, then install + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array If an array, then it must have + * indices 'channel' and 'package' + */ + function uninstallPackage(&$pkg) + { + $data = $this->_getDepDB(); + unset($this->_cache); + if (is_object($pkg)) { + $channel = strtolower($pkg->getChannel()); + $package = strtolower($pkg->getPackage()); + } else { + $channel = strtolower($pkg['channel']); + $package = strtolower($pkg['package']); + } + + if (!isset($data['dependencies'][$channel][$package])) { + return true; + } + + foreach ($data['dependencies'][$channel][$package] as $dep) { + $found = false; + $depchannel = isset($dep['dep']['uri']) ? '__uri' : strtolower($dep['dep']['channel']); + $depname = strtolower($dep['dep']['name']); + if (isset($data['packages'][$depchannel][$depname])) { + foreach ($data['packages'][$depchannel][$depname] as $i => $info) { + if ($info['channel'] == $channel && $info['package'] == $package) { + $found = true; + break; + } + } + } + + if ($found) { + unset($data['packages'][$depchannel][$depname][$i]); + if (!count($data['packages'][$depchannel][$depname])) { + unset($data['packages'][$depchannel][$depname]); + if (!count($data['packages'][$depchannel])) { + unset($data['packages'][$depchannel]); + } + } else { + $data['packages'][$depchannel][$depname] = + array_values($data['packages'][$depchannel][$depname]); + } + } + } + + unset($data['dependencies'][$channel][$package]); + if (!count($data['dependencies'][$channel])) { + unset($data['dependencies'][$channel]); + } + + if (!count($data['dependencies'])) { + unset($data['dependencies']); + } + + if (!count($data['packages'])) { + unset($data['packages']); + } + + $this->_writeDepDB($data); + } + + /** + * Rebuild the dependency DB by reading registry entries. + * @return true|PEAR_Error + */ + function rebuildDB() + { + $depdb = array('_version' => $this->_version); + if (!$this->hasWriteAccess()) { + // allow startup for read-only with older Registry + return $depdb; + } + + $packages = $this->_registry->listAllPackages(); + if (PEAR::isError($packages)) { + return $packages; + } + + foreach ($packages as $channel => $ps) { + foreach ($ps as $package) { + $package = $this->_registry->getPackage($package, $channel); + if (PEAR::isError($package)) { + return $package; + } + $this->_setPackageDeps($depdb, $package); + } + } + + $error = $this->_writeDepDB($depdb); + if (PEAR::isError($error)) { + return $error; + } + + $this->_cache = $depdb; + return true; + } + + /** + * Register usage of the dependency DB to prevent race conditions + * @param int one of the LOCK_* constants + * @return true|PEAR_Error + * @access private + */ + function _lock($mode = LOCK_EX) + { + if (stristr(php_uname(), 'Windows 9')) { + return true; + } + + if ($mode != LOCK_UN && is_resource($this->_lockFp)) { + // XXX does not check type of lock (LOCK_SH/LOCK_EX) + return true; + } + + $open_mode = 'w'; + // XXX People reported problems with LOCK_SH and 'w' + if ($mode === LOCK_SH) { + if (!file_exists($this->_lockfile)) { + touch($this->_lockfile); + } elseif (!is_file($this->_lockfile)) { + return PEAR::raiseError('could not create Dependency lock file, ' . + 'it exists and is not a regular file'); + } + $open_mode = 'r'; + } + + if (!is_resource($this->_lockFp)) { + $this->_lockFp = @fopen($this->_lockfile, $open_mode); + } + + if (!is_resource($this->_lockFp)) { + return PEAR::raiseError("could not create Dependency lock file" . + (isset($php_errormsg) ? ": " . $php_errormsg : "")); + } + + if (!(int)flock($this->_lockFp, $mode)) { + switch ($mode) { + case LOCK_SH: $str = 'shared'; break; + case LOCK_EX: $str = 'exclusive'; break; + case LOCK_UN: $str = 'unlock'; break; + default: $str = 'unknown'; break; + } + + return PEAR::raiseError("could not acquire $str lock ($this->_lockfile)"); + } + + return true; + } + + /** + * Release usage of dependency DB + * @return true|PEAR_Error + * @access private + */ + function _unlock() + { + $ret = $this->_lock(LOCK_UN); + if (is_resource($this->_lockFp)) { + fclose($this->_lockFp); + } + $this->_lockFp = null; + return $ret; + } + + /** + * Load the dependency database from disk, or return the cache + * @return array|PEAR_Error + */ + function _getDepDB() + { + if (!$this->hasWriteAccess()) { + return array('_version' => $this->_version); + } + + if (isset($this->_cache)) { + return $this->_cache; + } + + if (!$fp = fopen($this->_depdb, 'r')) { + $err = PEAR::raiseError("Could not open dependencies file `".$this->_depdb."'"); + return $err; + } + + clearstatcache(); + fclose($fp); + $data = unserialize(file_get_contents($this->_depdb)); + $this->_cache = $data; + return $data; + } + + /** + * Write out the dependency database to disk + * @param array the database + * @return true|PEAR_Error + * @access private + */ + function _writeDepDB(&$deps) + { + if (PEAR::isError($e = $this->_lock(LOCK_EX))) { + return $e; + } + + if (!$fp = fopen($this->_depdb, 'wb')) { + $this->_unlock(); + return PEAR::raiseError("Could not open dependencies file `".$this->_depdb."' for writing"); + } + + fwrite($fp, serialize($deps)); + fclose($fp); + $this->_unlock(); + $this->_cache = $deps; + return true; + } + + /** + * Register all dependencies from a package in the dependencies database, in essence + * "installing" the package's dependency information + * @param array the database + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * @access private + */ + function _setPackageDeps(&$data, &$pkg) + { + $pkg->setConfig($this->_config); + if ($pkg->getPackagexmlVersion() == '1.0') { + $gen = &$pkg->getDefaultGenerator(); + $deps = $gen->dependenciesToV2(); + } else { + $deps = $pkg->getDeps(true); + } + + if (!$deps) { + return; + } + + if (!is_array($data)) { + $data = array(); + } + + if (!isset($data['dependencies'])) { + $data['dependencies'] = array(); + } + + $channel = strtolower($pkg->getChannel()); + $package = strtolower($pkg->getPackage()); + + if (!isset($data['dependencies'][$channel])) { + $data['dependencies'][$channel] = array(); + } + + $data['dependencies'][$channel][$package] = array(); + if (isset($deps['required']['package'])) { + if (!isset($deps['required']['package'][0])) { + $deps['required']['package'] = array($deps['required']['package']); + } + + foreach ($deps['required']['package'] as $dep) { + $this->_registerDep($data, $pkg, $dep, 'required'); + } + } + + if (isset($deps['optional']['package'])) { + if (!isset($deps['optional']['package'][0])) { + $deps['optional']['package'] = array($deps['optional']['package']); + } + + foreach ($deps['optional']['package'] as $dep) { + $this->_registerDep($data, $pkg, $dep, 'optional'); + } + } + + if (isset($deps['required']['subpackage'])) { + if (!isset($deps['required']['subpackage'][0])) { + $deps['required']['subpackage'] = array($deps['required']['subpackage']); + } + + foreach ($deps['required']['subpackage'] as $dep) { + $this->_registerDep($data, $pkg, $dep, 'required'); + } + } + + if (isset($deps['optional']['subpackage'])) { + if (!isset($deps['optional']['subpackage'][0])) { + $deps['optional']['subpackage'] = array($deps['optional']['subpackage']); + } + + foreach ($deps['optional']['subpackage'] as $dep) { + $this->_registerDep($data, $pkg, $dep, 'optional'); + } + } + + if (isset($deps['group'])) { + if (!isset($deps['group'][0])) { + $deps['group'] = array($deps['group']); + } + + foreach ($deps['group'] as $group) { + if (isset($group['package'])) { + if (!isset($group['package'][0])) { + $group['package'] = array($group['package']); + } + + foreach ($group['package'] as $dep) { + $this->_registerDep($data, $pkg, $dep, 'optional', + $group['attribs']['name']); + } + } + + if (isset($group['subpackage'])) { + if (!isset($group['subpackage'][0])) { + $group['subpackage'] = array($group['subpackage']); + } + + foreach ($group['subpackage'] as $dep) { + $this->_registerDep($data, $pkg, $dep, 'optional', + $group['attribs']['name']); + } + } + } + } + + if ($data['dependencies'][$channel][$package] == array()) { + unset($data['dependencies'][$channel][$package]); + if (!count($data['dependencies'][$channel])) { + unset($data['dependencies'][$channel]); + } + } + } + + /** + * @param array the database + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * @param array the specific dependency + * @param required|optional whether this is a required or an optional dep + * @param string|false dependency group this dependency is from, or false for ordinary dep + */ + function _registerDep(&$data, &$pkg, $dep, $type, $group = false) + { + $info = array( + 'dep' => $dep, + 'type' => $type, + 'group' => $group + ); + + $dep = array_map('strtolower', $dep); + $depchannel = isset($dep['channel']) ? $dep['channel'] : '__uri'; + if (!isset($data['dependencies'])) { + $data['dependencies'] = array(); + } + + $channel = strtolower($pkg->getChannel()); + $package = strtolower($pkg->getPackage()); + + if (!isset($data['dependencies'][$channel])) { + $data['dependencies'][$channel] = array(); + } + + if (!isset($data['dependencies'][$channel][$package])) { + $data['dependencies'][$channel][$package] = array(); + } + + $data['dependencies'][$channel][$package][] = $info; + if (isset($data['packages'][$depchannel][$dep['name']])) { + $found = false; + foreach ($data['packages'][$depchannel][$dep['name']] as $i => $p) { + if ($p['channel'] == $channel && $p['package'] == $package) { + $found = true; + break; + } + } + } else { + if (!isset($data['packages'])) { + $data['packages'] = array(); + } + + if (!isset($data['packages'][$depchannel])) { + $data['packages'][$depchannel] = array(); + } + + if (!isset($data['packages'][$depchannel][$dep['name']])) { + $data['packages'][$depchannel][$dep['name']] = array(); + } + + $found = false; + } + + if (!$found) { + $data['packages'][$depchannel][$dep['name']][] = array( + 'channel' => $channel, + 'package' => $package + ); + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Downloader.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Downloader.php new file mode 100644 index 0000000..6d6cdd7 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Downloader.php @@ -0,0 +1,1788 @@ + + * @author Stig Bakken + * @author Tomas V. V. Cox + * @author Martin Jansen + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.3.0 + */ + +/** + * Needed for constants, extending + */ +require_once 'PEAR/Common.php'; + +define('PEAR_INSTALLER_OK', 1); +define('PEAR_INSTALLER_FAILED', 0); +define('PEAR_INSTALLER_SKIPPED', -1); +define('PEAR_INSTALLER_ERROR_NO_PREF_STATE', 2); + +/** + * Administration class used to download anything from the internet (PEAR Packages, + * static URLs, xml files) + * + * @category pear + * @package PEAR + * @author Greg Beaver + * @author Stig Bakken + * @author Tomas V. V. Cox + * @author Martin Jansen + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.3.0 + */ +class PEAR_Downloader extends PEAR_Common +{ + /** + * @var PEAR_Registry + * @access private + */ + var $_registry; + + /** + * Preferred Installation State (snapshot, devel, alpha, beta, stable) + * @var string|null + * @access private + */ + var $_preferredState; + + /** + * Options from command-line passed to Install. + * + * Recognized options:
    + * - onlyreqdeps : install all required dependencies as well + * - alldeps : install all dependencies, including optional + * - installroot : base relative path to install files in + * - force : force a download even if warnings would prevent it + * - nocompress : download uncompressed tarballs + * @see PEAR_Command_Install + * @access private + * @var array + */ + var $_options; + + /** + * Downloaded Packages after a call to download(). + * + * Format of each entry: + * + * + * array('pkg' => 'package_name', 'file' => '/path/to/local/file', + * 'info' => array() // parsed package.xml + * ); + * + * @access private + * @var array + */ + var $_downloadedPackages = array(); + + /** + * Packages slated for download. + * + * This is used to prevent downloading a package more than once should it be a dependency + * for two packages to be installed. + * Format of each entry: + * + *
    +     * array('package_name1' => parsed package.xml, 'package_name2' => parsed package.xml,
    +     * );
    +     * 
    + * @access private + * @var array + */ + var $_toDownload = array(); + + /** + * Array of every package installed, with names lower-cased. + * + * Format: + * + * array('package1' => 0, 'package2' => 1, ); + * + * @var array + */ + var $_installed = array(); + + /** + * @var array + * @access private + */ + var $_errorStack = array(); + + /** + * @var boolean + * @access private + */ + var $_internalDownload = false; + + /** + * Temporary variable used in sorting packages by dependency in {@link sortPkgDeps()} + * @var array + * @access private + */ + var $_packageSortTree; + + /** + * Temporary directory, or configuration value where downloads will occur + * @var string + */ + var $_downloadDir; + + /** + * List of methods that can be called both statically and non-statically. + * @var array + */ + protected static $bivalentMethods = array( + 'setErrorHandling' => true, + 'raiseError' => true, + 'throwError' => true, + 'pushErrorHandling' => true, + 'popErrorHandling' => true, + 'downloadHttp' => true, + ); + + /** + * @param PEAR_Frontend_* + * @param array + * @param PEAR_Config + */ + function __construct($ui = null, $options = array(), $config = null) + { + parent::__construct(); + $this->_options = $options; + if ($config !== null) { + $this->config = &$config; + $this->_preferredState = $this->config->get('preferred_state'); + } + $this->ui = &$ui; + if (!$this->_preferredState) { + // don't inadvertantly use a non-set preferred_state + $this->_preferredState = null; + } + + if ($config !== null) { + if (isset($this->_options['installroot'])) { + $this->config->setInstallRoot($this->_options['installroot']); + } + $this->_registry = &$config->getRegistry(); + } + + if (isset($this->_options['alldeps']) || isset($this->_options['onlyreqdeps'])) { + $this->_installed = $this->_registry->listAllPackages(); + foreach ($this->_installed as $key => $unused) { + if (!count($unused)) { + continue; + } + $strtolower = create_function('$a','return strtolower($a);'); + array_walk($this->_installed[$key], $strtolower); + } + } + } + + /** + * Attempt to discover a channel's remote capabilities from + * its server name + * @param string + * @return boolean + */ + function discover($channel) + { + $this->log(1, 'Attempting to discover channel "' . $channel . '"...'); + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $callback = $this->ui ? array(&$this, '_downloadCallback') : null; + if (!class_exists('System')) { + require_once 'System.php'; + } + + $tmpdir = $this->config->get('temp_dir'); + $tmp = System::mktemp('-d -t "' . $tmpdir . '"'); + $a = $this->downloadHttp('http://' . $channel . '/channel.xml', $this->ui, $tmp, $callback, false); + PEAR::popErrorHandling(); + if (PEAR::isError($a)) { + // Attempt to fallback to https automatically. + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $this->log(1, 'Attempting fallback to https instead of http on channel "' . $channel . '"...'); + $a = $this->downloadHttp('https://' . $channel . '/channel.xml', $this->ui, $tmp, $callback, false); + PEAR::popErrorHandling(); + if (PEAR::isError($a)) { + return false; + } + } + + list($a, $lastmodified) = $a; + if (!class_exists('PEAR_ChannelFile')) { + require_once 'PEAR/ChannelFile.php'; + } + + $b = new PEAR_ChannelFile; + if ($b->fromXmlFile($a)) { + unlink($a); + if ($this->config->get('auto_discover')) { + $this->_registry->addChannel($b, $lastmodified); + $alias = $b->getName(); + if ($b->getName() == $this->_registry->channelName($b->getAlias())) { + $alias = $b->getAlias(); + } + + $this->log(1, 'Auto-discovered channel "' . $channel . + '", alias "' . $alias . '", adding to registry'); + } + + return true; + } + + unlink($a); + return false; + } + + /** + * For simpler unit-testing + * @param PEAR_Downloader + * @return PEAR_Downloader_Package + */ + function newDownloaderPackage(&$t) + { + if (!class_exists('PEAR_Downloader_Package')) { + require_once 'PEAR/Downloader/Package.php'; + } + $a = new PEAR_Downloader_Package($t); + return $a; + } + + /** + * For simpler unit-testing + * @param PEAR_Config + * @param array + * @param array + * @param int + */ + function &getDependency2Object(&$c, $i, $p, $s) + { + if (!class_exists('PEAR_Dependency2')) { + require_once 'PEAR/Dependency2.php'; + } + $z = new PEAR_Dependency2($c, $i, $p, $s); + return $z; + } + + function &download($params) + { + if (!count($params)) { + $a = array(); + return $a; + } + + if (!isset($this->_registry)) { + $this->_registry = &$this->config->getRegistry(); + } + + $channelschecked = array(); + // convert all parameters into PEAR_Downloader_Package objects + foreach ($params as $i => $param) { + $params[$i] = $this->newDownloaderPackage($this); + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $err = $params[$i]->initialize($param); + PEAR::staticPopErrorHandling(); + if (!$err) { + // skip parameters that were missed by preferred_state + continue; + } + + if (PEAR::isError($err)) { + if (!isset($this->_options['soft']) && $err->getMessage() !== '') { + $this->log(0, $err->getMessage()); + } + + $params[$i] = false; + if (is_object($param)) { + $param = $param->getChannel() . '/' . $param->getPackage(); + } + + if (!isset($this->_options['soft'])) { + $this->log(2, 'Package "' . $param . '" is not valid'); + } + + // Message logged above in a specific verbose mode, passing null to not show up on CLI + $this->pushError(null, PEAR_INSTALLER_SKIPPED); + } else { + do { + if ($params[$i] && $params[$i]->getType() == 'local') { + // bug #7090 skip channel.xml check for local packages + break; + } + + if ($params[$i] && !isset($channelschecked[$params[$i]->getChannel()]) && + !isset($this->_options['offline']) + ) { + $channelschecked[$params[$i]->getChannel()] = true; + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + if (!class_exists('System')) { + require_once 'System.php'; + } + + $curchannel = $this->_registry->getChannel($params[$i]->getChannel()); + if (PEAR::isError($curchannel)) { + PEAR::staticPopErrorHandling(); + return $this->raiseError($curchannel); + } + + if (PEAR::isError($dir = $this->getDownloadDir())) { + PEAR::staticPopErrorHandling(); + break; + } + + $mirror = $this->config->get('preferred_mirror', null, $params[$i]->getChannel()); + $url = 'http://' . $mirror . '/channel.xml'; + $a = $this->downloadHttp($url, $this->ui, $dir, null, $curchannel->lastModified()); + + PEAR::staticPopErrorHandling(); + if ($a === false) { + //channel.xml not modified + break; + } else if (PEAR::isError($a)) { + // Attempt fallback to https automatically + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $a = $this->downloadHttp('https://' . $mirror . + '/channel.xml', $this->ui, $dir, null, $curchannel->lastModified()); + + PEAR::staticPopErrorHandling(); + if (PEAR::isError($a) || !$a) { + break; + } + } + $this->log(0, 'WARNING: channel "' . $params[$i]->getChannel() . '" has ' . + 'updated its protocols, use "' . PEAR_RUNTYPE . ' channel-update ' . $params[$i]->getChannel() . + '" to update'); + } + } while (false); + + if ($params[$i] && !isset($this->_options['downloadonly'])) { + if (isset($this->_options['packagingroot'])) { + $checkdir = $this->_prependPath( + $this->config->get('php_dir', null, $params[$i]->getChannel()), + $this->_options['packagingroot']); + } else { + $checkdir = $this->config->get('php_dir', + null, $params[$i]->getChannel()); + } + + while ($checkdir && $checkdir != '/' && !file_exists($checkdir)) { + $checkdir = dirname($checkdir); + } + + if ($checkdir == '.') { + $checkdir = '/'; + } + + if (!is_writeable($checkdir)) { + return PEAR::raiseError('Cannot install, php_dir for channel "' . + $params[$i]->getChannel() . '" is not writeable by the current user'); + } + } + } + } + + unset($channelschecked); + PEAR_Downloader_Package::removeDuplicates($params); + if (!count($params)) { + $a = array(); + return $a; + } + + if (!isset($this->_options['nodeps']) && !isset($this->_options['offline'])) { + $reverify = true; + while ($reverify) { + $reverify = false; + foreach ($params as $i => $param) { + //PHP Bug 40768 / PEAR Bug #10944 + //Nested foreaches fail in PHP 5.2.1 + key($params); + $ret = $params[$i]->detectDependencies($params); + if (PEAR::isError($ret)) { + $reverify = true; + $params[$i] = false; + PEAR_Downloader_Package::removeDuplicates($params); + if (!isset($this->_options['soft'])) { + $this->log(0, $ret->getMessage()); + } + continue 2; + } + } + } + } + + if (isset($this->_options['offline'])) { + $this->log(3, 'Skipping dependency download check, --offline specified'); + } + + if (!count($params)) { + $a = array(); + return $a; + } + + while (PEAR_Downloader_Package::mergeDependencies($params)); + PEAR_Downloader_Package::removeDuplicates($params, true); + $errorparams = array(); + if (PEAR_Downloader_Package::detectStupidDuplicates($params, $errorparams)) { + if (count($errorparams)) { + foreach ($errorparams as $param) { + $name = $this->_registry->parsedPackageNameToString($param->getParsedPackage()); + $this->pushError('Duplicate package ' . $name . ' found', PEAR_INSTALLER_FAILED); + } + $a = array(); + return $a; + } + } + + PEAR_Downloader_Package::removeInstalled($params); + if (!count($params)) { + $this->pushError('No valid packages found', PEAR_INSTALLER_FAILED); + $a = array(); + return $a; + } + + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $err = $this->analyzeDependencies($params); + PEAR::popErrorHandling(); + if (!count($params)) { + $this->pushError('No valid packages found', PEAR_INSTALLER_FAILED); + $a = array(); + return $a; + } + + $ret = array(); + $newparams = array(); + if (isset($this->_options['pretend'])) { + return $params; + } + + $somefailed = false; + foreach ($params as $i => $package) { + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $pf = &$params[$i]->download(); + PEAR::staticPopErrorHandling(); + if (PEAR::isError($pf)) { + if (!isset($this->_options['soft'])) { + $this->log(1, $pf->getMessage()); + $this->log(0, 'Error: cannot download "' . + $this->_registry->parsedPackageNameToString($package->getParsedPackage(), + true) . + '"'); + } + $somefailed = true; + continue; + } + + $newparams[] = &$params[$i]; + $ret[] = array( + 'file' => $pf->getArchiveFile(), + 'info' => &$pf, + 'pkg' => $pf->getPackage() + ); + } + + if ($somefailed) { + // remove params that did not download successfully + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $err = $this->analyzeDependencies($newparams, true); + PEAR::popErrorHandling(); + if (!count($newparams)) { + $this->pushError('Download failed', PEAR_INSTALLER_FAILED); + $a = array(); + return $a; + } + } + + $this->_downloadedPackages = $ret; + return $newparams; + } + + /** + * @param array all packages to be installed + */ + function analyzeDependencies(&$params, $force = false) + { + if (isset($this->_options['downloadonly'])) { + return; + } + + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $redo = true; + $reset = $hasfailed = $failed = false; + while ($redo) { + $redo = false; + foreach ($params as $i => $param) { + $deps = $param->getDeps(); + if (!$deps) { + $depchecker = &$this->getDependency2Object($this->config, $this->getOptions(), + $param->getParsedPackage(), PEAR_VALIDATE_DOWNLOADING); + $send = $param->getPackageFile(); + + $installcheck = $depchecker->validatePackage($send, $this, $params); + if (PEAR::isError($installcheck)) { + if (!isset($this->_options['soft'])) { + $this->log(0, $installcheck->getMessage()); + } + $hasfailed = true; + $params[$i] = false; + $reset = true; + $redo = true; + $failed = false; + PEAR_Downloader_Package::removeDuplicates($params); + continue 2; + } + continue; + } + + if (!$reset && $param->alreadyValidated() && !$force) { + continue; + } + + if (count($deps)) { + $depchecker = &$this->getDependency2Object($this->config, $this->getOptions(), + $param->getParsedPackage(), PEAR_VALIDATE_DOWNLOADING); + $send = $param->getPackageFile(); + if ($send === null) { + $send = $param->getDownloadURL(); + } + + $installcheck = $depchecker->validatePackage($send, $this, $params); + if (PEAR::isError($installcheck)) { + if (!isset($this->_options['soft'])) { + $this->log(0, $installcheck->getMessage()); + } + $hasfailed = true; + $params[$i] = false; + $reset = true; + $redo = true; + $failed = false; + PEAR_Downloader_Package::removeDuplicates($params); + continue 2; + } + + $failed = false; + if (isset($deps['required']) && is_array($deps['required'])) { + foreach ($deps['required'] as $type => $dep) { + // note: Dependency2 will never return a PEAR_Error if ignore-errors + // is specified, so soft is needed to turn off logging + if (!isset($dep[0])) { + if (PEAR::isError($e = $depchecker->{"validate{$type}Dependency"}($dep, + true, $params))) { + $failed = true; + if (!isset($this->_options['soft'])) { + $this->log(0, $e->getMessage()); + } + } elseif (is_array($e) && !$param->alreadyValidated()) { + if (!isset($this->_options['soft'])) { + $this->log(0, $e[0]); + } + } + } else { + foreach ($dep as $d) { + if (PEAR::isError($e = + $depchecker->{"validate{$type}Dependency"}($d, + true, $params))) { + $failed = true; + if (!isset($this->_options['soft'])) { + $this->log(0, $e->getMessage()); + } + } elseif (is_array($e) && !$param->alreadyValidated()) { + if (!isset($this->_options['soft'])) { + $this->log(0, $e[0]); + } + } + } + } + } + + if (isset($deps['optional']) && is_array($deps['optional'])) { + foreach ($deps['optional'] as $type => $dep) { + if (!isset($dep[0])) { + if (PEAR::isError($e = + $depchecker->{"validate{$type}Dependency"}($dep, + false, $params))) { + $failed = true; + if (!isset($this->_options['soft'])) { + $this->log(0, $e->getMessage()); + } + } elseif (is_array($e) && !$param->alreadyValidated()) { + if (!isset($this->_options['soft'])) { + $this->log(0, $e[0]); + } + } + } else { + foreach ($dep as $d) { + if (PEAR::isError($e = + $depchecker->{"validate{$type}Dependency"}($d, + false, $params))) { + $failed = true; + if (!isset($this->_options['soft'])) { + $this->log(0, $e->getMessage()); + } + } elseif (is_array($e) && !$param->alreadyValidated()) { + if (!isset($this->_options['soft'])) { + $this->log(0, $e[0]); + } + } + } + } + } + } + + $groupname = $param->getGroup(); + if (isset($deps['group']) && $groupname) { + if (!isset($deps['group'][0])) { + $deps['group'] = array($deps['group']); + } + + $found = false; + foreach ($deps['group'] as $group) { + if ($group['attribs']['name'] == $groupname) { + $found = true; + break; + } + } + + if ($found) { + unset($group['attribs']); + foreach ($group as $type => $dep) { + if (!isset($dep[0])) { + if (PEAR::isError($e = + $depchecker->{"validate{$type}Dependency"}($dep, + false, $params))) { + $failed = true; + if (!isset($this->_options['soft'])) { + $this->log(0, $e->getMessage()); + } + } elseif (is_array($e) && !$param->alreadyValidated()) { + if (!isset($this->_options['soft'])) { + $this->log(0, $e[0]); + } + } + } else { + foreach ($dep as $d) { + if (PEAR::isError($e = + $depchecker->{"validate{$type}Dependency"}($d, + false, $params))) { + $failed = true; + if (!isset($this->_options['soft'])) { + $this->log(0, $e->getMessage()); + } + } elseif (is_array($e) && !$param->alreadyValidated()) { + if (!isset($this->_options['soft'])) { + $this->log(0, $e[0]); + } + } + } + } + } + } + } + } else { + foreach ($deps as $dep) { + if (PEAR::isError($e = $depchecker->validateDependency1($dep, $params))) { + $failed = true; + if (!isset($this->_options['soft'])) { + $this->log(0, $e->getMessage()); + } + } elseif (is_array($e) && !$param->alreadyValidated()) { + if (!isset($this->_options['soft'])) { + $this->log(0, $e[0]); + } + } + } + } + $params[$i]->setValidated(); + } + + if ($failed) { + $hasfailed = true; + $params[$i] = false; + $reset = true; + $redo = true; + $failed = false; + PEAR_Downloader_Package::removeDuplicates($params); + continue 2; + } + } + } + + PEAR::staticPopErrorHandling(); + if ($hasfailed && (isset($this->_options['ignore-errors']) || + isset($this->_options['nodeps']))) { + // this is probably not needed, but just in case + if (!isset($this->_options['soft'])) { + $this->log(0, 'WARNING: dependencies failed'); + } + } + } + + /** + * Retrieve the directory that downloads will happen in + * @access private + * @return string + */ + function getDownloadDir() + { + if (isset($this->_downloadDir)) { + return $this->_downloadDir; + } + + $downloaddir = $this->config->get('download_dir'); + if (empty($downloaddir) || (is_dir($downloaddir) && !is_writable($downloaddir))) { + if (is_dir($downloaddir) && !is_writable($downloaddir)) { + $this->log(0, 'WARNING: configuration download directory "' . $downloaddir . + '" is not writeable. Change download_dir config variable to ' . + 'a writeable dir to avoid this warning'); + } + + if (!class_exists('System')) { + require_once 'System.php'; + } + + if (PEAR::isError($downloaddir = System::mktemp('-d'))) { + return $downloaddir; + } + $this->log(3, '+ tmp dir created at ' . $downloaddir); + } + + if (!is_writable($downloaddir)) { + if (PEAR::isError(System::mkdir(array('-p', $downloaddir))) || + !is_writable($downloaddir)) { + return PEAR::raiseError('download directory "' . $downloaddir . + '" is not writeable. Change download_dir config variable to ' . + 'a writeable dir'); + } + } + + return $this->_downloadDir = $downloaddir; + } + + function setDownloadDir($dir) + { + if (!@is_writable($dir)) { + if (PEAR::isError(System::mkdir(array('-p', $dir)))) { + return PEAR::raiseError('download directory "' . $dir . + '" is not writeable. Change download_dir config variable to ' . + 'a writeable dir'); + } + } + $this->_downloadDir = $dir; + } + + function configSet($key, $value, $layer = 'user', $channel = false) + { + $this->config->set($key, $value, $layer, $channel); + $this->_preferredState = $this->config->get('preferred_state', null, $channel); + if (!$this->_preferredState) { + // don't inadvertantly use a non-set preferred_state + $this->_preferredState = null; + } + } + + function setOptions($options) + { + $this->_options = $options; + } + + function getOptions() + { + return $this->_options; + } + + + /** + * @param array output of {@link parsePackageName()} + * @access private + */ + function _getPackageDownloadUrl($parr) + { + $curchannel = $this->config->get('default_channel'); + $this->configSet('default_channel', $parr['channel']); + // getDownloadURL returns an array. On error, it only contains information + // on the latest release as array(version, info). On success it contains + // array(version, info, download url string) + $state = isset($parr['state']) ? $parr['state'] : $this->config->get('preferred_state'); + if (!$this->_registry->channelExists($parr['channel'])) { + do { + if ($this->config->get('auto_discover') && $this->discover($parr['channel'])) { + break; + } + + $this->configSet('default_channel', $curchannel); + return PEAR::raiseError('Unknown remote channel: ' . $parr['channel']); + } while (false); + } + + $chan = $this->_registry->getChannel($parr['channel']); + if (PEAR::isError($chan)) { + return $chan; + } + + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $version = $this->_registry->packageInfo($parr['package'], 'version', $parr['channel']); + $stability = $this->_registry->packageInfo($parr['package'], 'stability', $parr['channel']); + // package is installed - use the installed release stability level + if (!isset($parr['state']) && $stability !== null) { + $state = $stability['release']; + } + PEAR::staticPopErrorHandling(); + $base2 = false; + + $preferred_mirror = $this->config->get('preferred_mirror'); + if (!$chan->supportsREST($preferred_mirror) || + ( + !($base2 = $chan->getBaseURL('REST1.3', $preferred_mirror)) + && + !($base = $chan->getBaseURL('REST1.0', $preferred_mirror)) + ) + ) { + return $this->raiseError($parr['channel'] . ' is using a unsupported protocol - This should never happen.'); + } + + if ($base2) { + $rest = &$this->config->getREST('1.3', $this->_options); + $base = $base2; + } else { + $rest = &$this->config->getREST('1.0', $this->_options); + } + + $downloadVersion = false; + if (!isset($parr['version']) && !isset($parr['state']) && $version + && !PEAR::isError($version) + && !isset($this->_options['downloadonly']) + ) { + $downloadVersion = $version; + } + + $url = $rest->getDownloadURL($base, $parr, $state, $downloadVersion, $chan->getName()); + if (PEAR::isError($url)) { + $this->configSet('default_channel', $curchannel); + return $url; + } + + if ($parr['channel'] != $curchannel) { + $this->configSet('default_channel', $curchannel); + } + + if (!is_array($url)) { + return $url; + } + + $url['raw'] = false; // no checking is necessary for REST + if (!is_array($url['info'])) { + return PEAR::raiseError('Invalid remote dependencies retrieved from REST - ' . + 'this should never happen'); + } + + if (!isset($this->_options['force']) && + !isset($this->_options['downloadonly']) && + $version && + !PEAR::isError($version) && + !isset($parr['group']) + ) { + if (version_compare($version, $url['version'], '=')) { + return PEAR::raiseError($this->_registry->parsedPackageNameToString( + $parr, true) . ' is already installed and is the same as the ' . + 'released version ' . $url['version'], -976); + } + + if (version_compare($version, $url['version'], '>')) { + return PEAR::raiseError($this->_registry->parsedPackageNameToString( + $parr, true) . ' is already installed and is newer than detected ' . + 'released version ' . $url['version'], -976); + } + } + + if (isset($url['info']['required']) || $url['compatible']) { + require_once 'PEAR/PackageFile/v2.php'; + $pf = new PEAR_PackageFile_v2; + $pf->setRawChannel($parr['channel']); + if ($url['compatible']) { + $pf->setRawCompatible($url['compatible']); + } + } else { + require_once 'PEAR/PackageFile/v1.php'; + $pf = new PEAR_PackageFile_v1; + } + + $pf->setRawPackage($url['package']); + $pf->setDeps($url['info']); + if ($url['compatible']) { + $pf->setCompatible($url['compatible']); + } + + $pf->setRawState($url['stability']); + $url['info'] = &$pf; + if (!extension_loaded("zlib") || isset($this->_options['nocompress'])) { + $ext = '.tar'; + } else { + $ext = '.tgz'; + } + + if (is_array($url) && isset($url['url'])) { + $url['url'] .= $ext; + } + + return $url; + } + + /** + * @param array dependency array + * @access private + */ + function _getDepPackageDownloadUrl($dep, $parr) + { + $xsdversion = isset($dep['rel']) ? '1.0' : '2.0'; + $curchannel = $this->config->get('default_channel'); + if (isset($dep['uri'])) { + $xsdversion = '2.0'; + $chan = $this->_registry->getChannel('__uri'); + if (PEAR::isError($chan)) { + return $chan; + } + + $version = $this->_registry->packageInfo($dep['name'], 'version', '__uri'); + $this->configSet('default_channel', '__uri'); + } else { + if (isset($dep['channel'])) { + $remotechannel = $dep['channel']; + } else { + $remotechannel = 'pear.php.net'; + } + + if (!$this->_registry->channelExists($remotechannel)) { + do { + if ($this->config->get('auto_discover')) { + if ($this->discover($remotechannel)) { + break; + } + } + return PEAR::raiseError('Unknown remote channel: ' . $remotechannel); + } while (false); + } + + $chan = $this->_registry->getChannel($remotechannel); + if (PEAR::isError($chan)) { + return $chan; + } + + $version = $this->_registry->packageInfo($dep['name'], 'version', $remotechannel); + $this->configSet('default_channel', $remotechannel); + } + + $state = isset($parr['state']) ? $parr['state'] : $this->config->get('preferred_state'); + if (isset($parr['state']) && isset($parr['version'])) { + unset($parr['state']); + } + + if (isset($dep['uri'])) { + $info = $this->newDownloaderPackage($this); + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $err = $info->initialize($dep); + PEAR::staticPopErrorHandling(); + if (!$err) { + // skip parameters that were missed by preferred_state + return PEAR::raiseError('Cannot initialize dependency'); + } + + if (PEAR::isError($err)) { + if (!isset($this->_options['soft'])) { + $this->log(0, $err->getMessage()); + } + + if (is_object($info)) { + $param = $info->getChannel() . '/' . $info->getPackage(); + } + return PEAR::raiseError('Package "' . $param . '" is not valid'); + } + return $info; + } elseif ($chan->supportsREST($this->config->get('preferred_mirror')) + && + ( + ($base2 = $chan->getBaseURL('REST1.3', $this->config->get('preferred_mirror'))) + || + ($base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) + ) + ) { + if ($base2) { + $base = $base2; + $rest = &$this->config->getREST('1.3', $this->_options); + } else { + $rest = &$this->config->getREST('1.0', $this->_options); + } + + $url = $rest->getDepDownloadURL($base, $xsdversion, $dep, $parr, + $state, $version, $chan->getName()); + if (PEAR::isError($url)) { + return $url; + } + + if ($parr['channel'] != $curchannel) { + $this->configSet('default_channel', $curchannel); + } + + if (!is_array($url)) { + return $url; + } + + $url['raw'] = false; // no checking is necessary for REST + if (!is_array($url['info'])) { + return PEAR::raiseError('Invalid remote dependencies retrieved from REST - ' . + 'this should never happen'); + } + + if (isset($url['info']['required'])) { + if (!class_exists('PEAR_PackageFile_v2')) { + require_once 'PEAR/PackageFile/v2.php'; + } + $pf = new PEAR_PackageFile_v2; + $pf->setRawChannel($remotechannel); + } else { + if (!class_exists('PEAR_PackageFile_v1')) { + require_once 'PEAR/PackageFile/v1.php'; + } + $pf = new PEAR_PackageFile_v1; + + } + $pf->setRawPackage($url['package']); + $pf->setDeps($url['info']); + if ($url['compatible']) { + $pf->setCompatible($url['compatible']); + } + + $pf->setRawState($url['stability']); + $url['info'] = &$pf; + if (!extension_loaded("zlib") || isset($this->_options['nocompress'])) { + $ext = '.tar'; + } else { + $ext = '.tgz'; + } + + if (is_array($url) && isset($url['url'])) { + $url['url'] .= $ext; + } + + return $url; + } + + return $this->raiseError($parr['channel'] . ' is using a unsupported protocol - This should never happen.'); + } + + /** + * @deprecated in favor of _getPackageDownloadUrl + */ + function getPackageDownloadUrl($package, $version = null, $channel = false) + { + if ($version) { + $package .= "-$version"; + } + if ($this === null || $this->_registry === null) { + $package = "http://pear.php.net/get/$package"; + } else { + $chan = $this->_registry->getChannel($channel); + if (PEAR::isError($chan)) { + return ''; + } + $package = "http://" . $chan->getServer() . "/get/$package"; + } + if (!extension_loaded("zlib")) { + $package .= '?uncompress=yes'; + } + return $package; + } + + /** + * Retrieve a list of downloaded packages after a call to {@link download()}. + * + * Also resets the list of downloaded packages. + * @return array + */ + function getDownloadedPackages() + { + $ret = $this->_downloadedPackages; + $this->_downloadedPackages = array(); + $this->_toDownload = array(); + return $ret; + } + + function _downloadCallback($msg, $params = null) + { + switch ($msg) { + case 'saveas': + $this->log(1, "downloading $params ..."); + break; + case 'done': + $this->log(1, '...done: ' . number_format($params, 0, '', ',') . ' bytes'); + break; + case 'bytesread': + static $bytes; + if (empty($bytes)) { + $bytes = 0; + } + if (!($bytes % 10240)) { + $this->log(1, '.', false); + } + $bytes += $params; + break; + case 'start': + if($params[1] == -1) { + $length = "Unknown size"; + } else { + $length = number_format($params[1], 0, '', ',')." bytes"; + } + $this->log(1, "Starting to download {$params[0]} ($length)"); + break; + } + if (method_exists($this->ui, '_downloadCallback')) + $this->ui->_downloadCallback($msg, $params); + } + + function _prependPath($path, $prepend) + { + if (strlen($prepend) > 0) { + if (OS_WINDOWS && preg_match('/^[a-z]:/i', $path)) { + if (preg_match('/^[a-z]:/i', $prepend)) { + $prepend = substr($prepend, 2); + } elseif ($prepend{0} != '\\') { + $prepend = "\\$prepend"; + } + $path = substr($path, 0, 2) . $prepend . substr($path, 2); + } else { + $path = $prepend . $path; + } + } + return $path; + } + + /** + * @param string + * @param integer + */ + function pushError($errmsg, $code = -1) + { + array_push($this->_errorStack, array($errmsg, $code)); + } + + function getErrorMsgs() + { + $msgs = array(); + $errs = $this->_errorStack; + foreach ($errs as $err) { + $msgs[] = $err[0]; + } + $this->_errorStack = array(); + return $msgs; + } + + /** + * for BC + * + * @deprecated + */ + function sortPkgDeps(&$packages, $uninstall = false) + { + $uninstall ? + $this->sortPackagesForUninstall($packages) : + $this->sortPackagesForInstall($packages); + } + + /** + * Sort a list of arrays of array(downloaded packagefilename) by dependency. + * + * This uses the topological sort method from graph theory, and the + * Structures_Graph package to properly sort dependencies for installation. + * @param array an array of downloaded PEAR_Downloader_Packages + * @return array array of array(packagefilename, package.xml contents) + */ + function sortPackagesForInstall(&$packages) + { + require_once 'Structures/Graph.php'; + require_once 'Structures/Graph/Node.php'; + require_once 'Structures/Graph/Manipulator/TopologicalSorter.php'; + $depgraph = new Structures_Graph(true); + $nodes = array(); + $reg = &$this->config->getRegistry(); + foreach ($packages as $i => $package) { + $pname = $reg->parsedPackageNameToString( + array( + 'channel' => $package->getChannel(), + 'package' => strtolower($package->getPackage()), + )); + $nodes[$pname] = new Structures_Graph_Node; + $nodes[$pname]->setData($packages[$i]); + $depgraph->addNode($nodes[$pname]); + } + + $deplinks = array(); + foreach ($nodes as $package => $node) { + $pf = &$node->getData(); + $pdeps = $pf->getDeps(true); + if (!$pdeps) { + continue; + } + + if ($pf->getPackagexmlVersion() == '1.0') { + foreach ($pdeps as $dep) { + if ($dep['type'] != 'pkg' || + (isset($dep['optional']) && $dep['optional'] == 'yes')) { + continue; + } + + $dname = $reg->parsedPackageNameToString( + array( + 'channel' => 'pear.php.net', + 'package' => strtolower($dep['name']), + )); + + if (isset($nodes[$dname])) { + if (!isset($deplinks[$dname])) { + $deplinks[$dname] = array(); + } + + $deplinks[$dname][$package] = 1; + // dependency is in installed packages + continue; + } + + $dname = $reg->parsedPackageNameToString( + array( + 'channel' => 'pecl.php.net', + 'package' => strtolower($dep['name']), + )); + + if (isset($nodes[$dname])) { + if (!isset($deplinks[$dname])) { + $deplinks[$dname] = array(); + } + + $deplinks[$dname][$package] = 1; + // dependency is in installed packages + continue; + } + } + } else { + // the only ordering we care about is: + // 1) subpackages must be installed before packages that depend on them + // 2) required deps must be installed before packages that depend on them + if (isset($pdeps['required']['subpackage'])) { + $t = $pdeps['required']['subpackage']; + if (!isset($t[0])) { + $t = array($t); + } + + $this->_setupGraph($t, $reg, $deplinks, $nodes, $package); + } + + if (isset($pdeps['group'])) { + if (!isset($pdeps['group'][0])) { + $pdeps['group'] = array($pdeps['group']); + } + + foreach ($pdeps['group'] as $group) { + if (isset($group['subpackage'])) { + $t = $group['subpackage']; + if (!isset($t[0])) { + $t = array($t); + } + + $this->_setupGraph($t, $reg, $deplinks, $nodes, $package); + } + } + } + + if (isset($pdeps['optional']['subpackage'])) { + $t = $pdeps['optional']['subpackage']; + if (!isset($t[0])) { + $t = array($t); + } + + $this->_setupGraph($t, $reg, $deplinks, $nodes, $package); + } + + if (isset($pdeps['required']['package'])) { + $t = $pdeps['required']['package']; + if (!isset($t[0])) { + $t = array($t); + } + + $this->_setupGraph($t, $reg, $deplinks, $nodes, $package); + } + + if (isset($pdeps['group'])) { + if (!isset($pdeps['group'][0])) { + $pdeps['group'] = array($pdeps['group']); + } + + foreach ($pdeps['group'] as $group) { + if (isset($group['package'])) { + $t = $group['package']; + if (!isset($t[0])) { + $t = array($t); + } + + $this->_setupGraph($t, $reg, $deplinks, $nodes, $package); + } + } + } + } + } + + $this->_detectDepCycle($deplinks); + foreach ($deplinks as $dependent => $parents) { + foreach ($parents as $parent => $unused) { + $nodes[$dependent]->connectTo($nodes[$parent]); + } + } + + $installOrder = Structures_Graph_Manipulator_TopologicalSorter::sort($depgraph); + $ret = array(); + for ($i = 0, $count = count($installOrder); $i < $count; $i++) { + foreach ($installOrder[$i] as $index => $sortedpackage) { + $data = &$installOrder[$i][$index]->getData(); + $ret[] = &$nodes[$reg->parsedPackageNameToString( + array( + 'channel' => $data->getChannel(), + 'package' => strtolower($data->getPackage()), + ))]->getData(); + } + } + + $packages = $ret; + return; + } + + /** + * Detect recursive links between dependencies and break the cycles + * + * @param array + * @access private + */ + function _detectDepCycle(&$deplinks) + { + do { + $keepgoing = false; + foreach ($deplinks as $dep => $parents) { + foreach ($parents as $parent => $unused) { + // reset the parent cycle detector + $this->_testCycle(null, null, null); + if ($this->_testCycle($dep, $deplinks, $parent)) { + $keepgoing = true; + unset($deplinks[$dep][$parent]); + if (count($deplinks[$dep]) == 0) { + unset($deplinks[$dep]); + } + + continue 3; + } + } + } + } while ($keepgoing); + } + + function _testCycle($test, $deplinks, $dep) + { + static $visited = array(); + if ($test === null) { + $visited = array(); + return; + } + + // this happens when a parent has a dep cycle on another dependency + // but the child is not part of the cycle + if (isset($visited[$dep])) { + return false; + } + + $visited[$dep] = 1; + if ($test == $dep) { + return true; + } + + if (isset($deplinks[$dep])) { + if (in_array($test, array_keys($deplinks[$dep]), true)) { + return true; + } + + foreach ($deplinks[$dep] as $parent => $unused) { + if ($this->_testCycle($test, $deplinks, $parent)) { + return true; + } + } + } + + return false; + } + + /** + * Set up the dependency for installation parsing + * + * @param array $t dependency information + * @param PEAR_Registry $reg + * @param array $deplinks list of dependency links already established + * @param array $nodes all existing package nodes + * @param string $package parent package name + * @access private + */ + function _setupGraph($t, $reg, &$deplinks, &$nodes, $package) + { + foreach ($t as $dep) { + $depchannel = !isset($dep['channel']) ? '__uri': $dep['channel']; + $dname = $reg->parsedPackageNameToString( + array( + 'channel' => $depchannel, + 'package' => strtolower($dep['name']), + )); + + if (isset($nodes[$dname])) { + if (!isset($deplinks[$dname])) { + $deplinks[$dname] = array(); + } + $deplinks[$dname][$package] = 1; + } + } + } + + function _dependsOn($a, $b) + { + return $this->_checkDepTree(strtolower($a->getChannel()), strtolower($a->getPackage()), $b); + } + + function _checkDepTree($channel, $package, $b, $checked = array()) + { + $checked[$channel][$package] = true; + if (!isset($this->_depTree[$channel][$package])) { + return false; + } + + if (isset($this->_depTree[$channel][$package][strtolower($b->getChannel())] + [strtolower($b->getPackage())])) { + return true; + } + + foreach ($this->_depTree[$channel][$package] as $ch => $packages) { + foreach ($packages as $pa => $true) { + if ($this->_checkDepTree($ch, $pa, $b, $checked)) { + return true; + } + } + } + + return false; + } + + function _sortInstall($a, $b) + { + if (!$a->getDeps() && !$b->getDeps()) { + return 0; // neither package has dependencies, order is insignificant + } + if ($a->getDeps() && !$b->getDeps()) { + return 1; // $a must be installed after $b because $a has dependencies + } + if (!$a->getDeps() && $b->getDeps()) { + return -1; // $b must be installed after $a because $b has dependencies + } + // both packages have dependencies + if ($this->_dependsOn($a, $b)) { + return 1; + } + if ($this->_dependsOn($b, $a)) { + return -1; + } + return 0; + } + + /** + * Download a file through HTTP. Considers suggested file name in + * Content-disposition: header and can run a callback function for + * different events. The callback will be called with two + * parameters: the callback type, and parameters. The implemented + * callback types are: + * + * 'setup' called at the very beginning, parameter is a UI object + * that should be used for all output + * 'message' the parameter is a string with an informational message + * 'saveas' may be used to save with a different file name, the + * parameter is the filename that is about to be used. + * If a 'saveas' callback returns a non-empty string, + * that file name will be used as the filename instead. + * Note that $save_dir will not be affected by this, only + * the basename of the file. + * 'start' download is starting, parameter is number of bytes + * that are expected, or -1 if unknown + * 'bytesread' parameter is the number of bytes read so far + * 'done' download is complete, parameter is the total number + * of bytes read + * 'connfailed' if the TCP/SSL connection fails, this callback is called + * with array(host,port,errno,errmsg) + * 'writefailed' if writing to disk fails, this callback is called + * with array(destfile,errmsg) + * + * If an HTTP proxy has been configured (http_proxy PEAR_Config + * setting), the proxy will be used. + * + * @param string $url the URL to download + * @param object $ui PEAR_Frontend_* instance + * @param object $config PEAR_Config instance + * @param string $save_dir directory to save file in + * @param mixed $callback function/method to call for status + * updates + * @param false|string|array $lastmodified header values to check against for caching + * use false to return the header values from this download + * @param false|array $accept Accept headers to send + * @param false|string $channel Channel to use for retrieving authentication + * @return mixed Returns the full path of the downloaded file or a PEAR + * error on failure. If the error is caused by + * socket-related errors, the error object will + * have the fsockopen error code available through + * getCode(). If caching is requested, then return the header + * values. + * If $lastmodified was given and the there are no changes, + * boolean false is returned. + * + * @access public + */ + public static function _downloadHttp( + $object, $url, &$ui, $save_dir = '.', $callback = null, $lastmodified = null, + $accept = false, $channel = false + ) { + static $redirect = 0; + // always reset , so we are clean case of error + $wasredirect = $redirect; + $redirect = 0; + if ($callback) { + call_user_func($callback, 'setup', array(&$ui)); + } + + $info = parse_url($url); + if (!isset($info['scheme']) || !in_array($info['scheme'], array('http', 'https'))) { + return PEAR::raiseError('Cannot download non-http URL "' . $url . '"'); + } + + if (!isset($info['host'])) { + return PEAR::raiseError('Cannot download from non-URL "' . $url . '"'); + } + + $host = isset($info['host']) ? $info['host'] : null; + $port = isset($info['port']) ? $info['port'] : null; + $path = isset($info['path']) ? $info['path'] : null; + + if ($object !== null) { + $config = $object->config; + } else { + $config = &PEAR_Config::singleton(); + } + + $proxy_host = $proxy_port = $proxy_user = $proxy_pass = ''; + if ($config->get('http_proxy') && + $proxy = parse_url($config->get('http_proxy'))) { + $proxy_host = isset($proxy['host']) ? $proxy['host'] : null; + if (isset($proxy['scheme']) && $proxy['scheme'] == 'https') { + $proxy_host = 'ssl://' . $proxy_host; + } + $proxy_port = isset($proxy['port']) ? $proxy['port'] : 8080; + $proxy_user = isset($proxy['user']) ? urldecode($proxy['user']) : null; + $proxy_pass = isset($proxy['pass']) ? urldecode($proxy['pass']) : null; + + if ($callback) { + call_user_func($callback, 'message', "Using HTTP proxy $host:$port"); + } + } + + if (empty($port)) { + $port = (isset($info['scheme']) && $info['scheme'] == 'https') ? 443 : 80; + } + + $scheme = (isset($info['scheme']) && $info['scheme'] == 'https') ? 'https' : 'http'; + + if ($proxy_host != '') { + $fp = @fsockopen($proxy_host, $proxy_port, $errno, $errstr); + if (!$fp) { + if ($callback) { + call_user_func($callback, 'connfailed', array($proxy_host, $proxy_port, + $errno, $errstr)); + } + return PEAR::raiseError("Connection to `$proxy_host:$proxy_port' failed: $errstr", $errno); + } + + if ($lastmodified === false || $lastmodified) { + $request = "GET $url HTTP/1.1\r\n"; + $request .= "Host: $host\r\n"; + } else { + $request = "GET $url HTTP/1.0\r\n"; + $request .= "Host: $host\r\n"; + } + } else { + $network_host = $host; + if (isset($info['scheme']) && $info['scheme'] == 'https') { + $network_host = 'ssl://' . $host; + } + + $fp = @fsockopen($network_host, $port, $errno, $errstr); + if (!$fp) { + if ($callback) { + call_user_func($callback, 'connfailed', array($host, $port, + $errno, $errstr)); + } + return PEAR::raiseError("Connection to `$host:$port' failed: $errstr", $errno); + } + + if ($lastmodified === false || $lastmodified) { + $request = "GET $path HTTP/1.1\r\n"; + $request .= "Host: $host\r\n"; + } else { + $request = "GET $path HTTP/1.0\r\n"; + $request .= "Host: $host\r\n"; + } + } + + $ifmodifiedsince = ''; + if (is_array($lastmodified)) { + if (isset($lastmodified['Last-Modified'])) { + $ifmodifiedsince = 'If-Modified-Since: ' . $lastmodified['Last-Modified'] . "\r\n"; + } + + if (isset($lastmodified['ETag'])) { + $ifmodifiedsince .= "If-None-Match: $lastmodified[ETag]\r\n"; + } + } else { + $ifmodifiedsince = ($lastmodified ? "If-Modified-Since: $lastmodified\r\n" : ''); + } + + $request .= $ifmodifiedsince . + "User-Agent: PEAR/1.10.1/PHP/" . PHP_VERSION . "\r\n"; + + if ($object !== null) { // only pass in authentication for non-static calls + $username = $config->get('username', null, $channel); + $password = $config->get('password', null, $channel); + if ($username && $password) { + $tmp = base64_encode("$username:$password"); + $request .= "Authorization: Basic $tmp\r\n"; + } + } + + if ($proxy_host != '' && $proxy_user != '') { + $request .= 'Proxy-Authorization: Basic ' . + base64_encode($proxy_user . ':' . $proxy_pass) . "\r\n"; + } + + if ($accept) { + $request .= 'Accept: ' . implode(', ', $accept) . "\r\n"; + } + + $request .= "Connection: close\r\n"; + $request .= "\r\n"; + fwrite($fp, $request); + $headers = array(); + $reply = 0; + while (trim($line = fgets($fp, 1024))) { + if (preg_match('/^([^:]+):\s+(.*)\s*\\z/', $line, $matches)) { + $headers[strtolower($matches[1])] = trim($matches[2]); + } elseif (preg_match('|^HTTP/1.[01] ([0-9]{3}) |', $line, $matches)) { + $reply = (int)$matches[1]; + if ($reply == 304 && ($lastmodified || ($lastmodified === false))) { + return false; + } + + if (!in_array($reply, array(200, 301, 302, 303, 305, 307))) { + return PEAR::raiseError("File $scheme://$host:$port$path not valid (received: $line)"); + } + } + } + + if ($reply != 200) { + if (!isset($headers['location'])) { + return PEAR::raiseError("File $scheme://$host:$port$path not valid (redirected but no location)"); + } + + if ($wasredirect > 4) { + return PEAR::raiseError("File $scheme://$host:$port$path not valid (redirection looped more than 5 times)"); + } + + $redirect = $wasredirect + 1; + return static::_downloadHttp($object, $headers['location'], + $ui, $save_dir, $callback, $lastmodified, $accept); + } + + if (isset($headers['content-disposition']) && + preg_match('/\sfilename=\"([^;]*\S)\"\s*(;|\\z)/', $headers['content-disposition'], $matches)) { + $save_as = basename($matches[1]); + } else { + $save_as = basename($url); + } + + if ($callback) { + $tmp = call_user_func($callback, 'saveas', $save_as); + if ($tmp) { + $save_as = $tmp; + } + } + + $dest_file = $save_dir . DIRECTORY_SEPARATOR . $save_as; + if (is_link($dest_file)) { + return PEAR::raiseError('SECURITY ERROR: Will not write to ' . $dest_file . ' as it is symlinked to ' . readlink($dest_file) . ' - Possible symlink attack'); + } + + if (!$wp = @fopen($dest_file, 'wb')) { + fclose($fp); + if ($callback) { + call_user_func($callback, 'writefailed', array($dest_file, $php_errormsg)); + } + return PEAR::raiseError("could not open $dest_file for writing"); + } + + $length = isset($headers['content-length']) ? $headers['content-length'] : -1; + + $bytes = 0; + if ($callback) { + call_user_func($callback, 'start', array(basename($dest_file), $length)); + } + + while ($data = fread($fp, 1024)) { + $bytes += strlen($data); + if ($callback) { + call_user_func($callback, 'bytesread', $bytes); + } + if (!@fwrite($wp, $data)) { + fclose($fp); + if ($callback) { + call_user_func($callback, 'writefailed', array($dest_file, $php_errormsg)); + } + return PEAR::raiseError("$dest_file: write failed ($php_errormsg)"); + } + } + + fclose($fp); + fclose($wp); + if ($callback) { + call_user_func($callback, 'done', $bytes); + } + + if ($lastmodified === false || $lastmodified) { + if (isset($headers['etag'])) { + $lastmodified = array('ETag' => $headers['etag']); + } + + if (isset($headers['last-modified'])) { + if (is_array($lastmodified)) { + $lastmodified['Last-Modified'] = $headers['last-modified']; + } else { + $lastmodified = $headers['last-modified']; + } + } + return array($dest_file, $lastmodified, $headers); + } + return $dest_file; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Downloader/Package.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Downloader/Package.php new file mode 100644 index 0000000..fe979eb --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Downloader/Package.php @@ -0,0 +1,1981 @@ + + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * Error code when parameter initialization fails because no releases + * exist within preferred_state, but releases do exist + */ +define('PEAR_DOWNLOADER_PACKAGE_STATE', -1003); +/** + * Error code when parameter initialization fails because no releases + * exist that will work with the existing PHP version + */ +define('PEAR_DOWNLOADER_PACKAGE_PHPVERSION', -1004); + +/** + * Coordinates download parameters and manages their dependencies + * prior to downloading them. + * + * Input can come from three sources: + * + * - local files (archives or package.xml) + * - remote files (downloadable urls) + * - abstract package names + * + * The first two elements are handled cleanly by PEAR_PackageFile, but the third requires + * accessing pearweb's xml-rpc interface to determine necessary dependencies, and the + * format returned of dependencies is slightly different from that used in package.xml. + * + * This class hides the differences between these elements, and makes automatic + * dependency resolution a piece of cake. It also manages conflicts when + * two classes depend on incompatible dependencies, or differing versions of the same + * package dependency. In addition, download will not be attempted if the php version is + * not supported, PEAR installer version is not supported, or non-PECL extensions are not + * installed. + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Downloader_Package +{ + /** + * @var PEAR_Downloader + */ + var $_downloader; + /** + * @var PEAR_Config + */ + var $_config; + /** + * @var PEAR_Registry + */ + var $_registry; + /** + * Used to implement packagingroot properly + * @var PEAR_Registry + */ + var $_installRegistry; + /** + * @var PEAR_PackageFile_v1|PEAR_PackageFile|v2 + */ + var $_packagefile; + /** + * @var array + */ + var $_parsedname; + /** + * @var array + */ + var $_downloadURL; + /** + * @var array + */ + var $_downloadDeps = array(); + /** + * @var boolean + */ + var $_valid = false; + /** + * @var boolean + */ + var $_analyzed = false; + /** + * if this or a parent package was invoked with Package-state, this is set to the + * state variable. + * + * This allows temporary reassignment of preferred_state for a parent package and all of + * its dependencies. + * @var string|false + */ + var $_explicitState = false; + /** + * If this package is invoked with Package#group, this variable will be true + */ + var $_explicitGroup = false; + /** + * Package type local|url + * @var string + */ + var $_type; + /** + * Contents of package.xml, if downloaded from a remote channel + * @var string|false + * @access private + */ + var $_rawpackagefile; + /** + * @var boolean + * @access private + */ + var $_validated = false; + + /** + * @param PEAR_Downloader + */ + function __construct(&$downloader) + { + $this->_downloader = &$downloader; + $this->_config = &$this->_downloader->config; + $this->_registry = &$this->_config->getRegistry(); + $options = $downloader->getOptions(); + if (isset($options['packagingroot'])) { + $this->_config->setInstallRoot($options['packagingroot']); + $this->_installRegistry = &$this->_config->getRegistry(); + $this->_config->setInstallRoot(false); + } else { + $this->_installRegistry = &$this->_registry; + } + $this->_valid = $this->_analyzed = false; + } + + /** + * Parse the input and determine whether this is a local file, a remote uri, or an + * abstract package name. + * + * This is the heart of the PEAR_Downloader_Package(), and is used in + * {@link PEAR_Downloader::download()} + * @param string + * @return bool|PEAR_Error + */ + function initialize($param) + { + $origErr = $this->_fromFile($param); + if ($this->_valid) { + return true; + } + + $options = $this->_downloader->getOptions(); + if (isset($options['offline'])) { + if (PEAR::isError($origErr) && !isset($options['soft'])) { + foreach ($origErr->getUserInfo() as $userInfo) { + if (isset($userInfo['message'])) { + $this->_downloader->log(0, $userInfo['message']); + } + } + + $this->_downloader->log(0, $origErr->getMessage()); + } + + return PEAR::raiseError('Cannot download non-local package "' . $param . '"'); + } + + $err = $this->_fromUrl($param); + if (PEAR::isError($err) || !$this->_valid) { + if ($this->_type == 'url') { + if (PEAR::isError($err) && !isset($options['soft'])) { + $this->_downloader->log(0, $err->getMessage()); + } + + return PEAR::raiseError("Invalid or missing remote package file"); + } + + $err = $this->_fromString($param); + if (PEAR::isError($err) || !$this->_valid) { + if (PEAR::isError($err) && $err->getCode() == PEAR_DOWNLOADER_PACKAGE_STATE) { + return false; // instruct the downloader to silently skip + } + + if (isset($this->_type) && $this->_type == 'local' && PEAR::isError($origErr)) { + if (is_array($origErr->getUserInfo())) { + foreach ($origErr->getUserInfo() as $err) { + if (is_array($err)) { + $err = $err['message']; + } + + if (!isset($options['soft'])) { + $this->_downloader->log(0, $err); + } + } + } + + if (!isset($options['soft'])) { + $this->_downloader->log(0, $origErr->getMessage()); + } + + if (is_array($param)) { + $param = $this->_registry->parsedPackageNameToString($param, true); + } + + if (!isset($options['soft'])) { + $this->_downloader->log(2, "Cannot initialize '$param', invalid or missing package file"); + } + + // Passing no message back - already logged above + return PEAR::raiseError(); + } + + if (PEAR::isError($err) && !isset($options['soft'])) { + $this->_downloader->log(0, $err->getMessage()); + } + + if (is_array($param)) { + $param = $this->_registry->parsedPackageNameToString($param, true); + } + + if (!isset($options['soft'])) { + $this->_downloader->log(2, "Cannot initialize '$param', invalid or missing package file"); + } + + // Passing no message back - already logged above + return PEAR::raiseError(); + } + } + + return true; + } + + /** + * Retrieve any non-local packages + * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2|PEAR_Error + */ + function &download() + { + if (isset($this->_packagefile)) { + return $this->_packagefile; + } + + if (isset($this->_downloadURL['url'])) { + $this->_isvalid = false; + $info = $this->getParsedPackage(); + foreach ($info as $i => $p) { + $info[$i] = strtolower($p); + } + + $err = $this->_fromUrl($this->_downloadURL['url'], + $this->_registry->parsedPackageNameToString($this->_parsedname, true)); + $newinfo = $this->getParsedPackage(); + foreach ($newinfo as $i => $p) { + $newinfo[$i] = strtolower($p); + } + + if ($info != $newinfo) { + do { + if ($info['channel'] == 'pecl.php.net' && $newinfo['channel'] == 'pear.php.net') { + $info['channel'] = 'pear.php.net'; + if ($info == $newinfo) { + // skip the channel check if a pecl package says it's a PEAR package + break; + } + } + if ($info['channel'] == 'pear.php.net' && $newinfo['channel'] == 'pecl.php.net') { + $info['channel'] = 'pecl.php.net'; + if ($info == $newinfo) { + // skip the channel check if a pecl package says it's a PEAR package + break; + } + } + + return PEAR::raiseError('CRITICAL ERROR: We are ' . + $this->_registry->parsedPackageNameToString($info) . ', but the file ' . + 'downloaded claims to be ' . + $this->_registry->parsedPackageNameToString($this->getParsedPackage())); + } while (false); + } + + if (PEAR::isError($err) || !$this->_valid) { + return $err; + } + } + + $this->_type = 'local'; + return $this->_packagefile; + } + + function &getPackageFile() + { + return $this->_packagefile; + } + + function &getDownloader() + { + return $this->_downloader; + } + + function getType() + { + return $this->_type; + } + + /** + * Like {@link initialize()}, but operates on a dependency + */ + function fromDepURL($dep) + { + $this->_downloadURL = $dep; + if (isset($dep['uri'])) { + $options = $this->_downloader->getOptions(); + if (!extension_loaded("zlib") || isset($options['nocompress'])) { + $ext = '.tar'; + } else { + $ext = '.tgz'; + } + + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $err = $this->_fromUrl($dep['uri'] . $ext); + PEAR::popErrorHandling(); + if (PEAR::isError($err)) { + if (!isset($options['soft'])) { + $this->_downloader->log(0, $err->getMessage()); + } + + return PEAR::raiseError('Invalid uri dependency "' . $dep['uri'] . $ext . '", ' . + 'cannot download'); + } + } else { + $this->_parsedname = + array( + 'package' => $dep['info']->getPackage(), + 'channel' => $dep['info']->getChannel(), + 'version' => $dep['version'] + ); + if (!isset($dep['nodefault'])) { + $this->_parsedname['group'] = 'default'; // download the default dependency group + $this->_explicitGroup = false; + } + + $this->_rawpackagefile = $dep['raw']; + } + } + + function detectDependencies($params) + { + $options = $this->_downloader->getOptions(); + if (isset($options['downloadonly'])) { + return; + } + + if (isset($options['offline'])) { + $this->_downloader->log(3, 'Skipping dependency download check, --offline specified'); + return; + } + + $pname = $this->getParsedPackage(); + if (!$pname) { + return; + } + + $deps = $this->getDeps(); + if (!$deps) { + return; + } + + if (isset($deps['required'])) { // package.xml 2.0 + return $this->_detect2($deps, $pname, $options, $params); + } + + return $this->_detect1($deps, $pname, $options, $params); + } + + function setValidated() + { + $this->_validated = true; + } + + function alreadyValidated() + { + return $this->_validated; + } + + /** + * Remove packages to be downloaded that are already installed + * @param array of PEAR_Downloader_Package objects + */ + public static function removeInstalled(&$params) + { + if (!isset($params[0])) { + return; + } + + $options = $params[0]->_downloader->getOptions(); + if (!isset($options['downloadonly'])) { + foreach ($params as $i => $param) { + $package = $param->getPackage(); + $channel = $param->getChannel(); + // remove self if already installed with this version + // this does not need any pecl magic - we only remove exact matches + if ($param->_installRegistry->packageExists($package, $channel)) { + $packageVersion = $param->_installRegistry->packageInfo($package, 'version', $channel); + if (version_compare($packageVersion, $param->getVersion(), '==')) { + if (!isset($options['force']) && !isset($options['packagingroot'])) { + $info = $param->getParsedPackage(); + unset($info['version']); + unset($info['state']); + if (!isset($options['soft'])) { + $param->_downloader->log(1, 'Skipping package "' . + $param->getShortName() . + '", already installed as version ' . $packageVersion); + } + $params[$i] = false; + } + } elseif (!isset($options['force']) && !isset($options['upgrade']) && + !isset($options['soft']) && !isset($options['packagingroot'])) { + $info = $param->getParsedPackage(); + $param->_downloader->log(1, 'Skipping package "' . + $param->getShortName() . + '", already installed as version ' . $packageVersion); + $params[$i] = false; + } + } + } + } + + PEAR_Downloader_Package::removeDuplicates($params); + } + + function _detect2($deps, $pname, $options, $params) + { + $this->_downloadDeps = array(); + $groupnotfound = false; + foreach (array('package', 'subpackage') as $packagetype) { + // get required dependency group + if (isset($deps['required'][$packagetype])) { + if (isset($deps['required'][$packagetype][0])) { + foreach ($deps['required'][$packagetype] as $dep) { + if (isset($dep['conflicts'])) { + // skip any package that this package conflicts with + continue; + } + $ret = $this->_detect2Dep($dep, $pname, 'required', $params); + if (is_array($ret)) { + $this->_downloadDeps[] = $ret; + } elseif (PEAR::isError($ret) && !isset($options['soft'])) { + $this->_downloader->log(0, $ret->getMessage()); + } + } + } else { + $dep = $deps['required'][$packagetype]; + if (!isset($dep['conflicts'])) { + // skip any package that this package conflicts with + $ret = $this->_detect2Dep($dep, $pname, 'required', $params); + if (is_array($ret)) { + $this->_downloadDeps[] = $ret; + } elseif (PEAR::isError($ret) && !isset($options['soft'])) { + $this->_downloader->log(0, $ret->getMessage()); + } + } + } + } + + // get optional dependency group, if any + if (isset($deps['optional'][$packagetype])) { + $skipnames = array(); + if (!isset($deps['optional'][$packagetype][0])) { + $deps['optional'][$packagetype] = array($deps['optional'][$packagetype]); + } + + foreach ($deps['optional'][$packagetype] as $dep) { + $skip = false; + if (!isset($options['alldeps'])) { + $dep['package'] = $dep['name']; + if (!isset($options['soft'])) { + $this->_downloader->log(3, 'Notice: package "' . + $this->_registry->parsedPackageNameToString($this->getParsedPackage(), + true) . '" optional dependency "' . + $this->_registry->parsedPackageNameToString(array('package' => + $dep['name'], 'channel' => 'pear.php.net'), true) . + '" will not be automatically downloaded'); + } + $skipnames[] = $this->_registry->parsedPackageNameToString($dep, true); + $skip = true; + unset($dep['package']); + } + + $ret = $this->_detect2Dep($dep, $pname, 'optional', $params); + if (PEAR::isError($ret) && !isset($options['soft'])) { + $this->_downloader->log(0, $ret->getMessage()); + } + + if (!$ret) { + $dep['package'] = $dep['name']; + $skip = count($skipnames) ? + $skipnames[count($skipnames) - 1] : ''; + if ($skip == + $this->_registry->parsedPackageNameToString($dep, true)) { + array_pop($skipnames); + } + } + + if (!$skip && is_array($ret)) { + $this->_downloadDeps[] = $ret; + } + } + + if (count($skipnames)) { + if (!isset($options['soft'])) { + $this->_downloader->log(1, 'Did not download optional dependencies: ' . + implode(', ', $skipnames) . + ', use --alldeps to download automatically'); + } + } + } + + // get requested dependency group, if any + $groupname = $this->getGroup(); + $explicit = $this->_explicitGroup; + if (!$groupname) { + if (!$this->canDefault()) { + continue; + } + + $groupname = 'default'; // try the default dependency group + } + + if ($groupnotfound) { + continue; + } + + if (isset($deps['group'])) { + if (isset($deps['group']['attribs'])) { + if (strtolower($deps['group']['attribs']['name']) == strtolower($groupname)) { + $group = $deps['group']; + } elseif ($explicit) { + if (!isset($options['soft'])) { + $this->_downloader->log(0, 'Warning: package "' . + $this->_registry->parsedPackageNameToString($pname, true) . + '" has no dependency ' . 'group named "' . $groupname . '"'); + } + + $groupnotfound = true; + continue; + } + } else { + $found = false; + foreach ($deps['group'] as $group) { + if (strtolower($group['attribs']['name']) == strtolower($groupname)) { + $found = true; + break; + } + } + + if (!$found) { + if ($explicit) { + if (!isset($options['soft'])) { + $this->_downloader->log(0, 'Warning: package "' . + $this->_registry->parsedPackageNameToString($pname, true) . + '" has no dependency ' . 'group named "' . $groupname . '"'); + } + } + + $groupnotfound = true; + continue; + } + } + } + + if (isset($group) && isset($group[$packagetype])) { + if (isset($group[$packagetype][0])) { + foreach ($group[$packagetype] as $dep) { + $ret = $this->_detect2Dep($dep, $pname, 'dependency group "' . + $group['attribs']['name'] . '"', $params); + if (is_array($ret)) { + $this->_downloadDeps[] = $ret; + } elseif (PEAR::isError($ret) && !isset($options['soft'])) { + $this->_downloader->log(0, $ret->getMessage()); + } + } + } else { + $ret = $this->_detect2Dep($group[$packagetype], $pname, + 'dependency group "' . + $group['attribs']['name'] . '"', $params); + if (is_array($ret)) { + $this->_downloadDeps[] = $ret; + } elseif (PEAR::isError($ret) && !isset($options['soft'])) { + $this->_downloader->log(0, $ret->getMessage()); + } + } + } + } + } + + function _detect2Dep($dep, $pname, $group, $params) + { + if (isset($dep['conflicts'])) { + return true; + } + + $options = $this->_downloader->getOptions(); + if (isset($dep['uri'])) { + return array('uri' => $dep['uri'], 'dep' => $dep);; + } + + $testdep = $dep; + $testdep['package'] = $dep['name']; + if (PEAR_Downloader_Package::willDownload($testdep, $params)) { + $dep['package'] = $dep['name']; + if (!isset($options['soft'])) { + $this->_downloader->log(2, $this->getShortName() . ': Skipping ' . $group . + ' dependency "' . + $this->_registry->parsedPackageNameToString($dep, true) . + '", will be installed'); + } + return false; + } + + $options = $this->_downloader->getOptions(); + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + if ($this->_explicitState) { + $pname['state'] = $this->_explicitState; + } + + $url = $this->_downloader->_getDepPackageDownloadUrl($dep, $pname); + if (PEAR::isError($url)) { + PEAR::popErrorHandling(); + return $url; + } + + $dep['package'] = $dep['name']; + $ret = $this->_analyzeDownloadURL($url, 'dependency', $dep, $params, $group == 'optional' && + !isset($options['alldeps']), true); + PEAR::popErrorHandling(); + if (PEAR::isError($ret)) { + if (!isset($options['soft'])) { + $this->_downloader->log(0, $ret->getMessage()); + } + + return false; + } + + // check to see if a dep is already installed and is the same or newer + if (!isset($dep['min']) && !isset($dep['max']) && !isset($dep['recommended'])) { + $oper = 'has'; + } else { + $oper = 'gt'; + } + + // do not try to move this before getDepPackageDownloadURL + // we can't determine whether upgrade is necessary until we know what + // version would be downloaded + if (!isset($options['force']) && $this->isInstalled($ret, $oper)) { + $version = $this->_installRegistry->packageInfo($dep['name'], 'version', $dep['channel']); + $dep['package'] = $dep['name']; + if (!isset($options['soft'])) { + $this->_downloader->log(3, $this->getShortName() . ': Skipping ' . $group . + ' dependency "' . + $this->_registry->parsedPackageNameToString($dep, true) . + '" version ' . $url['version'] . ', already installed as version ' . + $version); + } + + return false; + } + + if (isset($dep['nodefault'])) { + $ret['nodefault'] = true; + } + + return $ret; + } + + function _detect1($deps, $pname, $options, $params) + { + $this->_downloadDeps = array(); + $skipnames = array(); + foreach ($deps as $dep) { + $nodownload = false; + if (isset ($dep['type']) && $dep['type'] === 'pkg') { + $dep['channel'] = 'pear.php.net'; + $dep['package'] = $dep['name']; + switch ($dep['rel']) { + case 'not' : + continue 2; + case 'ge' : + case 'eq' : + case 'gt' : + case 'has' : + $group = (!isset($dep['optional']) || $dep['optional'] == 'no') ? + 'required' : + 'optional'; + if (PEAR_Downloader_Package::willDownload($dep, $params)) { + $this->_downloader->log(2, $this->getShortName() . ': Skipping ' . $group + . ' dependency "' . + $this->_registry->parsedPackageNameToString($dep, true) . + '", will be installed'); + continue 2; + } + $fakedp = new PEAR_PackageFile_v1; + $fakedp->setPackage($dep['name']); + // skip internet check if we are not upgrading (bug #5810) + if (!isset($options['upgrade']) && $this->isInstalled( + $fakedp, $dep['rel'])) { + $this->_downloader->log(2, $this->getShortName() . ': Skipping ' . $group + . ' dependency "' . + $this->_registry->parsedPackageNameToString($dep, true) . + '", is already installed'); + continue 2; + } + } + + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + if ($this->_explicitState) { + $pname['state'] = $this->_explicitState; + } + + $url = $this->_downloader->_getDepPackageDownloadUrl($dep, $pname); + $chan = 'pear.php.net'; + if (PEAR::isError($url)) { + // check to see if this is a pecl package that has jumped + // from pear.php.net to pecl.php.net channel + if (!class_exists('PEAR_Dependency2')) { + require_once 'PEAR/Dependency2.php'; + } + + $newdep = PEAR_Dependency2::normalizeDep($dep); + $newdep = $newdep[0]; + $newdep['channel'] = 'pecl.php.net'; + $chan = 'pecl.php.net'; + $url = $this->_downloader->_getDepPackageDownloadUrl($newdep, $pname); + $obj = &$this->_installRegistry->getPackage($dep['name']); + if (PEAR::isError($url)) { + PEAR::popErrorHandling(); + if ($obj !== null && $this->isInstalled($obj, $dep['rel'])) { + $group = (!isset($dep['optional']) || $dep['optional'] == 'no') ? + 'required' : + 'optional'; + $dep['package'] = $dep['name']; + if (!isset($options['soft'])) { + $this->_downloader->log(3, $this->getShortName() . + ': Skipping ' . $group . ' dependency "' . + $this->_registry->parsedPackageNameToString($dep, true) . + '", already installed as version ' . $obj->getVersion()); + } + $skip = count($skipnames) ? + $skipnames[count($skipnames) - 1] : ''; + if ($skip == + $this->_registry->parsedPackageNameToString($dep, true)) { + array_pop($skipnames); + } + continue; + } else { + if (isset($dep['optional']) && $dep['optional'] == 'yes') { + $this->_downloader->log(2, $this->getShortName() . + ': Skipping optional dependency "' . + $this->_registry->parsedPackageNameToString($dep, true) . + '", no releases exist'); + continue; + } else { + return $url; + } + } + } + } + + PEAR::popErrorHandling(); + if (!isset($options['alldeps'])) { + if (isset($dep['optional']) && $dep['optional'] == 'yes') { + if (!isset($options['soft'])) { + $this->_downloader->log(3, 'Notice: package "' . + $this->getShortName() . + '" optional dependency "' . + $this->_registry->parsedPackageNameToString( + array('channel' => $chan, 'package' => + $dep['name']), true) . + '" will not be automatically downloaded'); + } + $skipnames[] = $this->_registry->parsedPackageNameToString( + array('channel' => $chan, 'package' => + $dep['name']), true); + $nodownload = true; + } + } + + if (!isset($options['alldeps']) && !isset($options['onlyreqdeps'])) { + if (!isset($dep['optional']) || $dep['optional'] == 'no') { + if (!isset($options['soft'])) { + $this->_downloader->log(3, 'Notice: package "' . + $this->getShortName() . + '" required dependency "' . + $this->_registry->parsedPackageNameToString( + array('channel' => $chan, 'package' => + $dep['name']), true) . + '" will not be automatically downloaded'); + } + $skipnames[] = $this->_registry->parsedPackageNameToString( + array('channel' => $chan, 'package' => + $dep['name']), true); + $nodownload = true; + } + } + + // check to see if a dep is already installed + // do not try to move this before getDepPackageDownloadURL + // we can't determine whether upgrade is necessary until we know what + // version would be downloaded + if (!isset($options['force']) && $this->isInstalled( + $url, $dep['rel'])) { + $group = (!isset($dep['optional']) || $dep['optional'] == 'no') ? + 'required' : + 'optional'; + $dep['package'] = $dep['name']; + if (isset($newdep)) { + $version = $this->_installRegistry->packageInfo($newdep['name'], 'version', $newdep['channel']); + } else { + $version = $this->_installRegistry->packageInfo($dep['name'], 'version'); + } + + $dep['version'] = $url['version']; + if (!isset($options['soft'])) { + $this->_downloader->log(3, $this->getShortName() . ': Skipping ' . $group . + ' dependency "' . + $this->_registry->parsedPackageNameToString($dep, true) . + '", already installed as version ' . $version); + } + + $skip = count($skipnames) ? + $skipnames[count($skipnames) - 1] : ''; + if ($skip == + $this->_registry->parsedPackageNameToString($dep, true)) { + array_pop($skipnames); + } + + continue; + } + + if ($nodownload) { + continue; + } + + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + if (isset($newdep)) { + $dep = $newdep; + } + + $dep['package'] = $dep['name']; + $ret = $this->_analyzeDownloadURL($url, 'dependency', $dep, $params, + isset($dep['optional']) && $dep['optional'] == 'yes' && + !isset($options['alldeps']), true); + PEAR::popErrorHandling(); + if (PEAR::isError($ret)) { + if (!isset($options['soft'])) { + $this->_downloader->log(0, $ret->getMessage()); + } + continue; + } + + $this->_downloadDeps[] = $ret; + } + } + + if (count($skipnames)) { + if (!isset($options['soft'])) { + $this->_downloader->log(1, 'Did not download dependencies: ' . + implode(', ', $skipnames) . + ', use --alldeps or --onlyreqdeps to download automatically'); + } + } + } + + function setDownloadURL($pkg) + { + $this->_downloadURL = $pkg; + } + + /** + * Set the package.xml object for this downloaded package + * + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 $pkg + */ + function setPackageFile(&$pkg) + { + $this->_packagefile = &$pkg; + } + + function getShortName() + { + return $this->_registry->parsedPackageNameToString(array('channel' => $this->getChannel(), + 'package' => $this->getPackage()), true); + } + + function getParsedPackage() + { + if (isset($this->_packagefile) || isset($this->_parsedname)) { + return array('channel' => $this->getChannel(), + 'package' => $this->getPackage(), + 'version' => $this->getVersion()); + } + + return false; + } + + function getDownloadURL() + { + return $this->_downloadURL; + } + + function canDefault() + { + if (isset($this->_downloadURL) && isset($this->_downloadURL['nodefault'])) { + return false; + } + + return true; + } + + function getPackage() + { + if (isset($this->_packagefile)) { + return $this->_packagefile->getPackage(); + } elseif (isset($this->_downloadURL['info'])) { + return $this->_downloadURL['info']->getPackage(); + } + + return false; + } + + /** + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 + */ + function isSubpackage(&$pf) + { + if (isset($this->_packagefile)) { + return $this->_packagefile->isSubpackage($pf); + } elseif (isset($this->_downloadURL['info'])) { + return $this->_downloadURL['info']->isSubpackage($pf); + } + + return false; + } + + function getPackageType() + { + if (isset($this->_packagefile)) { + return $this->_packagefile->getPackageType(); + } elseif (isset($this->_downloadURL['info'])) { + return $this->_downloadURL['info']->getPackageType(); + } + + return false; + } + + function isBundle() + { + if (isset($this->_packagefile)) { + return $this->_packagefile->getPackageType() == 'bundle'; + } + + return false; + } + + function getPackageXmlVersion() + { + if (isset($this->_packagefile)) { + return $this->_packagefile->getPackagexmlVersion(); + } elseif (isset($this->_downloadURL['info'])) { + return $this->_downloadURL['info']->getPackagexmlVersion(); + } + + return '1.0'; + } + + function getChannel() + { + if (isset($this->_packagefile)) { + return $this->_packagefile->getChannel(); + } elseif (isset($this->_downloadURL['info'])) { + return $this->_downloadURL['info']->getChannel(); + } + + return false; + } + + function getURI() + { + if (isset($this->_packagefile)) { + return $this->_packagefile->getURI(); + } elseif (isset($this->_downloadURL['info'])) { + return $this->_downloadURL['info']->getURI(); + } + + return false; + } + + function getVersion() + { + if (isset($this->_packagefile)) { + return $this->_packagefile->getVersion(); + } elseif (isset($this->_downloadURL['version'])) { + return $this->_downloadURL['version']; + } + + return false; + } + + function isCompatible($pf) + { + if (isset($this->_packagefile)) { + return $this->_packagefile->isCompatible($pf); + } elseif (isset($this->_downloadURL['info'])) { + return $this->_downloadURL['info']->isCompatible($pf); + } + + return true; + } + + function setGroup($group) + { + $this->_parsedname['group'] = $group; + } + + function getGroup() + { + if (isset($this->_parsedname['group'])) { + return $this->_parsedname['group']; + } + + return ''; + } + + function isExtension($name) + { + if (isset($this->_packagefile)) { + return $this->_packagefile->isExtension($name); + } elseif (isset($this->_downloadURL['info'])) { + if ($this->_downloadURL['info']->getPackagexmlVersion() == '2.0') { + return $this->_downloadURL['info']->getProvidesExtension() == $name; + } + + return false; + } + + return false; + } + + function getDeps() + { + if (isset($this->_packagefile)) { + $ver = $this->_packagefile->getPackagexmlVersion(); + if (version_compare($ver, '2.0', '>=')) { + return $this->_packagefile->getDeps(true); + } + + return $this->_packagefile->getDeps(); + } elseif (isset($this->_downloadURL['info'])) { + $ver = $this->_downloadURL['info']->getPackagexmlVersion(); + if (version_compare($ver, '2.0', '>=')) { + return $this->_downloadURL['info']->getDeps(true); + } + + return $this->_downloadURL['info']->getDeps(); + } + + return array(); + } + + /** + * @param array Parsed array from {@link PEAR_Registry::parsePackageName()} or a dependency + * returned from getDepDownloadURL() + */ + function isEqual($param) + { + if (is_object($param)) { + $channel = $param->getChannel(); + $package = $param->getPackage(); + if ($param->getURI()) { + $param = array( + 'channel' => $param->getChannel(), + 'package' => $param->getPackage(), + 'version' => $param->getVersion(), + 'uri' => $param->getURI(), + ); + } else { + $param = array( + 'channel' => $param->getChannel(), + 'package' => $param->getPackage(), + 'version' => $param->getVersion(), + ); + } + } else { + if (isset($param['uri'])) { + if ($this->getChannel() != '__uri') { + return false; + } + return $param['uri'] == $this->getURI(); + } + + $package = isset($param['package']) ? $param['package'] : $param['info']->getPackage(); + $channel = isset($param['channel']) ? $param['channel'] : $param['info']->getChannel(); + if (isset($param['rel'])) { + if (!class_exists('PEAR_Dependency2')) { + require_once 'PEAR/Dependency2.php'; + } + + $newdep = PEAR_Dependency2::normalizeDep($param); + $newdep = $newdep[0]; + } elseif (isset($param['min'])) { + $newdep = $param; + } + } + + if (isset($newdep)) { + if (!isset($newdep['min'])) { + $newdep['min'] = '0'; + } + + if (!isset($newdep['max'])) { + $newdep['max'] = '100000000000000000000'; + } + + // use magic to support pecl packages suddenly jumping to the pecl channel + // we need to support both dependency possibilities + if ($channel == 'pear.php.net' && $this->getChannel() == 'pecl.php.net') { + if ($package == $this->getPackage()) { + $channel = 'pecl.php.net'; + } + } + if ($channel == 'pecl.php.net' && $this->getChannel() == 'pear.php.net') { + if ($package == $this->getPackage()) { + $channel = 'pear.php.net'; + } + } + + return (strtolower($package) == strtolower($this->getPackage()) && + $channel == $this->getChannel() && + version_compare($newdep['min'], $this->getVersion(), '<=') && + version_compare($newdep['max'], $this->getVersion(), '>=')); + } + + // use magic to support pecl packages suddenly jumping to the pecl channel + if ($channel == 'pecl.php.net' && $this->getChannel() == 'pear.php.net') { + if (strtolower($package) == strtolower($this->getPackage())) { + $channel = 'pear.php.net'; + } + } + + if (isset($param['version'])) { + return (strtolower($package) == strtolower($this->getPackage()) && + $channel == $this->getChannel() && + $param['version'] == $this->getVersion()); + } + + return strtolower($package) == strtolower($this->getPackage()) && + $channel == $this->getChannel(); + } + + function isInstalled($dep, $oper = '==') + { + if (!$dep) { + return false; + } + + if ($oper != 'ge' && $oper != 'gt' && $oper != 'has' && $oper != '==') { + return false; + } + + if (is_object($dep)) { + $package = $dep->getPackage(); + $channel = $dep->getChannel(); + if ($dep->getURI()) { + $dep = array( + 'uri' => $dep->getURI(), + 'version' => $dep->getVersion(), + ); + } else { + $dep = array( + 'version' => $dep->getVersion(), + ); + } + } else { + if (isset($dep['uri'])) { + $channel = '__uri'; + $package = $dep['dep']['name']; + } else { + $channel = $dep['info']->getChannel(); + $package = $dep['info']->getPackage(); + } + } + + $options = $this->_downloader->getOptions(); + $test = $this->_installRegistry->packageExists($package, $channel); + if (!$test && $channel == 'pecl.php.net') { + // do magic to allow upgrading from old pecl packages to new ones + $test = $this->_installRegistry->packageExists($package, 'pear.php.net'); + $channel = 'pear.php.net'; + } + + if ($test) { + if (isset($dep['uri'])) { + if ($this->_installRegistry->packageInfo($package, 'uri', '__uri') == $dep['uri']) { + return true; + } + } + + if (isset($options['upgrade'])) { + $packageVersion = $this->_installRegistry->packageInfo($package, 'version', $channel); + if (version_compare($packageVersion, $dep['version'], '>=')) { + return true; + } + + return false; + } + + return true; + } + + return false; + } + + /** + * Detect duplicate package names with differing versions + * + * If a user requests to install Date 1.4.6 and Date 1.4.7, + * for instance, this is a logic error. This method + * detects this situation. + * + * @param array $params array of PEAR_Downloader_Package objects + * @param array $errorparams empty array + * @return array array of stupid duplicated packages in PEAR_Downloader_Package obejcts + */ + public static function detectStupidDuplicates($params, &$errorparams) + { + $existing = array(); + foreach ($params as $i => $param) { + $package = $param->getPackage(); + $channel = $param->getChannel(); + $group = $param->getGroup(); + if (!isset($existing[$channel . '/' . $package])) { + $existing[$channel . '/' . $package] = array(); + } + + if (!isset($existing[$channel . '/' . $package][$group])) { + $existing[$channel . '/' . $package][$group] = array(); + } + + $existing[$channel . '/' . $package][$group][] = $i; + } + + $indices = array(); + foreach ($existing as $package => $groups) { + foreach ($groups as $group => $dupes) { + if (count($dupes) > 1) { + $indices = $indices + $dupes; + } + } + } + + $indices = array_unique($indices); + foreach ($indices as $index) { + $errorparams[] = $params[$index]; + } + + return count($errorparams); + } + + /** + * @param array + * @param bool ignore install groups - for final removal of dupe packages + */ + public static function removeDuplicates(&$params, $ignoreGroups = false) + { + $pnames = array(); + foreach ($params as $i => $param) { + if (!$param) { + continue; + } + + if ($param->getPackage()) { + $group = $ignoreGroups ? '' : $param->getGroup(); + $pnames[$i] = $param->getChannel() . '/' . + $param->getPackage() . '-' . $param->getVersion() . '#' . $group; + } + } + + $pnames = array_unique($pnames); + $unset = array_diff(array_keys($params), array_keys($pnames)); + $testp = array_flip($pnames); + foreach ($params as $i => $param) { + if (!$param) { + $unset[] = $i; + continue; + } + + if (!is_a($param, 'PEAR_Downloader_Package')) { + $unset[] = $i; + continue; + } + + $group = $ignoreGroups ? '' : $param->getGroup(); + if (!isset($testp[$param->getChannel() . '/' . $param->getPackage() . '-' . + $param->getVersion() . '#' . $group])) { + $unset[] = $i; + } + } + + foreach ($unset as $i) { + unset($params[$i]); + } + + $ret = array(); + foreach ($params as $i => $param) { + $ret[] = &$params[$i]; + } + + $params = array(); + foreach ($ret as $i => $param) { + $params[] = &$ret[$i]; + } + } + + function explicitState() + { + return $this->_explicitState; + } + + function setExplicitState($s) + { + $this->_explicitState = $s; + } + + /** + */ + public static function mergeDependencies(&$params) + { + $bundles = $newparams = array(); + foreach ($params as $i => $param) { + if (!$param->isBundle()) { + continue; + } + + $bundles[] = $i; + $pf = &$param->getPackageFile(); + $newdeps = array(); + $contents = $pf->getBundledPackages(); + if (!is_array($contents)) { + $contents = array($contents); + } + + foreach ($contents as $file) { + $filecontents = $pf->getFileContents($file); + $dl = &$param->getDownloader(); + $options = $dl->getOptions(); + if (PEAR::isError($dir = $dl->getDownloadDir())) { + return $dir; + } + + $fp = @fopen($dir . DIRECTORY_SEPARATOR . $file, 'wb'); + if (!$fp) { + continue; + } + + // FIXME do symlink check + + fwrite($fp, $filecontents, strlen($filecontents)); + fclose($fp); + if ($s = $params[$i]->explicitState()) { + $obj->setExplicitState($s); + } + + $obj = new PEAR_Downloader_Package($params[$i]->getDownloader()); + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + if (PEAR::isError($dir = $dl->getDownloadDir())) { + PEAR::popErrorHandling(); + return $dir; + } + $a = $dir . DIRECTORY_SEPARATOR . $file; + $e = $obj->_fromFile($a); + PEAR::popErrorHandling(); + if (PEAR::isError($e)) { + if (!isset($options['soft'])) { + $dl->log(0, $e->getMessage()); + } + continue; + } + + if (!PEAR_Downloader_Package::willDownload($obj, + array_merge($params, $newparams)) && !$param->isInstalled($obj)) { + $newparams[] = $obj; + } + } + } + + foreach ($bundles as $i) { + unset($params[$i]); // remove bundles - only their contents matter for installation + } + + PEAR_Downloader_Package::removeDuplicates($params); // strip any unset indices + if (count($newparams)) { // add in bundled packages for install + foreach ($newparams as $i => $unused) { + $params[] = &$newparams[$i]; + } + $newparams = array(); + } + + foreach ($params as $i => $param) { + $newdeps = array(); + foreach ($param->_downloadDeps as $dep) { + $merge = array_merge($params, $newparams); + if (!PEAR_Downloader_Package::willDownload($dep, $merge) + && !$param->isInstalled($dep) + ) { + $newdeps[] = $dep; + } else { + //var_dump($dep); + // detect versioning conflicts here + } + } + + // convert the dependencies into PEAR_Downloader_Package objects for the next time around + $params[$i]->_downloadDeps = array(); + foreach ($newdeps as $dep) { + $obj = new PEAR_Downloader_Package($params[$i]->getDownloader()); + if ($s = $params[$i]->explicitState()) { + $obj->setExplicitState($s); + } + + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $e = $obj->fromDepURL($dep); + PEAR::popErrorHandling(); + if (PEAR::isError($e)) { + if (!isset($options['soft'])) { + $obj->_downloader->log(0, $e->getMessage()); + } + continue; + } + + $e = $obj->detectDependencies($params); + if (PEAR::isError($e)) { + if (!isset($options['soft'])) { + $obj->_downloader->log(0, $e->getMessage()); + } + } + + $newparams[] = $obj; + } + } + + if (count($newparams)) { + foreach ($newparams as $i => $unused) { + $params[] = &$newparams[$i]; + } + return true; + } + + return false; + } + + + /** + */ + public static function willDownload($param, $params) + { + if (!is_array($params)) { + return false; + } + + foreach ($params as $obj) { + if ($obj->isEqual($param)) { + return true; + } + } + + return false; + } + + /** + * For simpler unit-testing + * @param PEAR_Config + * @param int + * @param string + */ + function &getPackagefileObject(&$c, $d) + { + $a = new PEAR_PackageFile($c, $d); + return $a; + } + + /** + * This will retrieve from a local file if possible, and parse out + * a group name as well. The original parameter will be modified to reflect this. + * @param string|array can be a parsed package name as well + * @access private + */ + function _fromFile(&$param) + { + $saveparam = $param; + if (is_string($param)) { + if (!@file_exists($param)) { + $test = explode('#', $param); + $group = array_pop($test); + if (@file_exists(implode('#', $test))) { + $this->setGroup($group); + $param = implode('#', $test); + $this->_explicitGroup = true; + } + } + + if (@is_file($param)) { + $this->_type = 'local'; + $options = $this->_downloader->getOptions(); + $pkg = &$this->getPackagefileObject($this->_config, $this->_downloader->_debug); + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $pf = &$pkg->fromAnyFile($param, PEAR_VALIDATE_INSTALLING); + PEAR::popErrorHandling(); + if (PEAR::isError($pf)) { + $this->_valid = false; + $param = $saveparam; + return $pf; + } + $this->_packagefile = &$pf; + if (!$this->getGroup()) { + $this->setGroup('default'); // install the default dependency group + } + return $this->_valid = true; + } + } + $param = $saveparam; + return $this->_valid = false; + } + + function _fromUrl($param, $saveparam = '') + { + if (!is_array($param) && (preg_match('#^(http|https|ftp)://#', $param))) { + $options = $this->_downloader->getOptions(); + $this->_type = 'url'; + $callback = $this->_downloader->ui ? + array(&$this->_downloader, '_downloadCallback') : null; + $this->_downloader->pushErrorHandling(PEAR_ERROR_RETURN); + if (PEAR::isError($dir = $this->_downloader->getDownloadDir())) { + $this->_downloader->popErrorHandling(); + return $dir; + } + + $this->_downloader->log(3, 'Downloading "' . $param . '"'); + $file = $this->_downloader->downloadHttp($param, $this->_downloader->ui, + $dir, $callback, null, false, $this->getChannel()); + $this->_downloader->popErrorHandling(); + if (PEAR::isError($file)) { + if (!empty($saveparam)) { + $saveparam = ", cannot download \"$saveparam\""; + } + $err = PEAR::raiseError('Could not download from "' . $param . + '"' . $saveparam . ' (' . $file->getMessage() . ')'); + return $err; + } + + if ($this->_rawpackagefile) { + require_once 'Archive/Tar.php'; + $tar = new Archive_Tar($file); + $packagexml = $tar->extractInString('package2.xml'); + if (!$packagexml) { + $packagexml = $tar->extractInString('package.xml'); + } + + if (str_replace(array("\n", "\r"), array('',''), $packagexml) != + str_replace(array("\n", "\r"), array('',''), $this->_rawpackagefile)) { + if ($this->getChannel() != 'pear.php.net') { + return PEAR::raiseError('CRITICAL ERROR: package.xml downloaded does ' . + 'not match value returned from xml-rpc'); + } + + // be more lax for the existing PEAR packages that have not-ok + // characters in their package.xml + $this->_downloader->log(0, 'CRITICAL WARNING: The "' . + $this->getPackage() . '" package has invalid characters in its ' . + 'package.xml. The next version of PEAR may not be able to install ' . + 'this package for security reasons. Please open a bug report at ' . + 'http://pear.php.net/package/' . $this->getPackage() . '/bugs'); + } + } + + // whew, download worked! + $pkg = &$this->getPackagefileObject($this->_config, $this->_downloader->debug); + + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $pf = &$pkg->fromAnyFile($file, PEAR_VALIDATE_INSTALLING); + PEAR::popErrorHandling(); + if (PEAR::isError($pf)) { + if (is_array($pf->getUserInfo())) { + foreach ($pf->getUserInfo() as $err) { + if (is_array($err)) { + $err = $err['message']; + } + + if (!isset($options['soft'])) { + $this->_downloader->log(0, "Validation Error: $err"); + } + } + } + + if (!isset($options['soft'])) { + $this->_downloader->log(0, $pf->getMessage()); + } + + ///FIXME need to pass back some error code that we can use to match with to cancel all further operations + /// At least stop all deps of this package from being installed + $out = $saveparam ? $saveparam : $param; + $err = PEAR::raiseError('Download of "' . $out . '" succeeded, but it is not a valid package archive'); + $this->_valid = false; + return $err; + } + + $this->_packagefile = &$pf; + $this->setGroup('default'); // install the default dependency group + return $this->_valid = true; + } + + return $this->_valid = false; + } + + /** + * + * @param string|array pass in an array of format + * array( + * 'package' => 'pname', + * ['channel' => 'channame',] + * ['version' => 'version',] + * ['state' => 'state',]) + * or a string of format [channame/]pname[-version|-state] + */ + function _fromString($param) + { + $options = $this->_downloader->getOptions(); + $channel = $this->_config->get('default_channel'); + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $pname = $this->_registry->parsePackageName($param, $channel); + PEAR::popErrorHandling(); + if (PEAR::isError($pname)) { + if ($pname->getCode() == 'invalid') { + $this->_valid = false; + return false; + } + + if ($pname->getCode() == 'channel') { + $parsed = $pname->getUserInfo(); + if ($this->_downloader->discover($parsed['channel'])) { + if ($this->_config->get('auto_discover')) { + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $pname = $this->_registry->parsePackageName($param, $channel); + PEAR::popErrorHandling(); + } else { + if (!isset($options['soft'])) { + $this->_downloader->log(0, 'Channel "' . $parsed['channel'] . + '" is not initialized, use ' . + '"pear channel-discover ' . $parsed['channel'] . '" to initialize' . + 'or pear config-set auto_discover 1'); + } + } + } + + if (PEAR::isError($pname)) { + if (!isset($options['soft'])) { + $this->_downloader->log(0, $pname->getMessage()); + } + + if (is_array($param)) { + $param = $this->_registry->parsedPackageNameToString($param); + } + + $err = PEAR::raiseError('invalid package name/package file "' . $param . '"'); + $this->_valid = false; + return $err; + } + } else { + if (!isset($options['soft'])) { + $this->_downloader->log(0, $pname->getMessage()); + } + + $err = PEAR::raiseError('invalid package name/package file "' . $param . '"'); + $this->_valid = false; + return $err; + } + } + + if (!isset($this->_type)) { + $this->_type = 'rest'; + } + + $this->_parsedname = $pname; + $this->_explicitState = isset($pname['state']) ? $pname['state'] : false; + $this->_explicitGroup = isset($pname['group']) ? true : false; + + $info = $this->_downloader->_getPackageDownloadUrl($pname); + if (PEAR::isError($info)) { + if ($info->getCode() != -976 && $pname['channel'] == 'pear.php.net') { + // try pecl + $pname['channel'] = 'pecl.php.net'; + if ($test = $this->_downloader->_getPackageDownloadUrl($pname)) { + if (!PEAR::isError($test)) { + $info = PEAR::raiseError($info->getMessage() . ' - package ' . + $this->_registry->parsedPackageNameToString($pname, true) . + ' can be installed with "pecl install ' . $pname['package'] . + '"'); + } else { + $pname['channel'] = 'pear.php.net'; + } + } else { + $pname['channel'] = 'pear.php.net'; + } + } + + return $info; + } + + $this->_rawpackagefile = $info['raw']; + $ret = $this->_analyzeDownloadURL($info, $param, $pname); + if (PEAR::isError($ret)) { + return $ret; + } + + if ($ret) { + $this->_downloadURL = $ret; + return $this->_valid = (bool) $ret; + } + } + + /** + * @param array output of package.getDownloadURL + * @param string|array|object information for detecting packages to be downloaded, and + * for errors + * @param array name information of the package + * @param array|null packages to be downloaded + * @param bool is this an optional dependency? + * @param bool is this any kind of dependency? + * @access private + */ + function _analyzeDownloadURL($info, $param, $pname, $params = null, $optional = false, + $isdependency = false) + { + if (!is_string($param) && PEAR_Downloader_Package::willDownload($param, $params)) { + return false; + } + + if ($info === false) { + $saveparam = !is_string($param) ? ", cannot download \"$param\"" : ''; + + // no releases exist + return PEAR::raiseError('No releases for package "' . + $this->_registry->parsedPackageNameToString($pname, true) . '" exist' . $saveparam); + } + + if (strtolower($info['info']->getChannel()) != strtolower($pname['channel'])) { + $err = false; + if ($pname['channel'] == 'pecl.php.net') { + if ($info['info']->getChannel() != 'pear.php.net') { + $err = true; + } + } elseif ($info['info']->getChannel() == 'pecl.php.net') { + if ($pname['channel'] != 'pear.php.net') { + $err = true; + } + } else { + $err = true; + } + + if ($err) { + return PEAR::raiseError('SECURITY ERROR: package in channel "' . $pname['channel'] . + '" retrieved another channel\'s name for download! ("' . + $info['info']->getChannel() . '")'); + } + } + + $preferred_state = $this->_config->get('preferred_state'); + if (!isset($info['url'])) { + $package_version = $this->_registry->packageInfo($info['info']->getPackage(), + 'version', $info['info']->getChannel()); + if ($this->isInstalled($info)) { + if ($isdependency && version_compare($info['version'], $package_version, '<=')) { + // ignore bogus errors of "failed to download dependency" + // if it is already installed and the one that would be + // downloaded is older or the same version (Bug #7219) + return false; + } + } + + if ($info['version'] === $package_version) { + if (!isset($options['soft'])) { + $this->_downloader->log(1, 'WARNING: failed to download ' . $pname['channel'] . + '/' . $pname['package'] . '-' . $package_version. ', additionally the suggested version' . + ' (' . $package_version . ') is the same as the locally installed one.'); + } + + return false; + } + + if (version_compare($info['version'], $package_version, '<=')) { + if (!isset($options['soft'])) { + $this->_downloader->log(1, 'WARNING: failed to download ' . $pname['channel'] . + '/' . $pname['package'] . '-' . $package_version . ', additionally the suggested version' . + ' (' . $info['version'] . ') is a lower version than the locally installed one (' . $package_version . ').'); + } + + return false; + } + + $instead = ', will instead download version ' . $info['version'] . + ', stability "' . $info['info']->getState() . '"'; + // releases exist, but we failed to get any + if (isset($this->_downloader->_options['force'])) { + if (isset($pname['version'])) { + $vs = ', version "' . $pname['version'] . '"'; + } elseif (isset($pname['state'])) { + $vs = ', stability "' . $pname['state'] . '"'; + } elseif ($param == 'dependency') { + if (!class_exists('PEAR_Common')) { + require_once 'PEAR/Common.php'; + } + + if (!in_array($info['info']->getState(), + PEAR_Common::betterStates($preferred_state, true))) { + if ($optional) { + // don't spit out confusing error message + return $this->_downloader->_getPackageDownloadUrl( + array('package' => $pname['package'], + 'channel' => $pname['channel'], + 'version' => $info['version'])); + } + $vs = ' within preferred state "' . $preferred_state . + '"'; + } else { + if (!class_exists('PEAR_Dependency2')) { + require_once 'PEAR/Dependency2.php'; + } + + if ($optional) { + // don't spit out confusing error message + return $this->_downloader->_getPackageDownloadUrl( + array('package' => $pname['package'], + 'channel' => $pname['channel'], + 'version' => $info['version'])); + } + $vs = PEAR_Dependency2::_getExtraString($pname); + $instead = ''; + } + } else { + $vs = ' within preferred state "' . $preferred_state . '"'; + } + + if (!isset($options['soft'])) { + $this->_downloader->log(1, 'WARNING: failed to download ' . $pname['channel'] . + '/' . $pname['package'] . $vs . $instead); + } + + // download the latest release + return $this->_downloader->_getPackageDownloadUrl( + array('package' => $pname['package'], + 'channel' => $pname['channel'], + 'version' => $info['version'])); + } else { + if (isset($info['php']) && $info['php']) { + $err = PEAR::raiseError('Failed to download ' . + $this->_registry->parsedPackageNameToString( + array('channel' => $pname['channel'], + 'package' => $pname['package']), + true) . + ', latest release is version ' . $info['php']['v'] . + ', but it requires PHP version "' . + $info['php']['m'] . '", use "' . + $this->_registry->parsedPackageNameToString( + array('channel' => $pname['channel'], 'package' => $pname['package'], + 'version' => $info['php']['v'])) . '" to install', + PEAR_DOWNLOADER_PACKAGE_PHPVERSION); + return $err; + } + + // construct helpful error message + if (isset($pname['version'])) { + $vs = ', version "' . $pname['version'] . '"'; + } elseif (isset($pname['state'])) { + $vs = ', stability "' . $pname['state'] . '"'; + } elseif ($param == 'dependency') { + if (!class_exists('PEAR_Common')) { + require_once 'PEAR/Common.php'; + } + + if (!in_array($info['info']->getState(), + PEAR_Common::betterStates($preferred_state, true))) { + if ($optional) { + // don't spit out confusing error message, and don't die on + // optional dep failure! + return $this->_downloader->_getPackageDownloadUrl( + array('package' => $pname['package'], + 'channel' => $pname['channel'], + 'version' => $info['version'])); + } + $vs = ' within preferred state "' . $preferred_state . '"'; + } else { + if (!class_exists('PEAR_Dependency2')) { + require_once 'PEAR/Dependency2.php'; + } + + if ($optional) { + // don't spit out confusing error message, and don't die on + // optional dep failure! + return $this->_downloader->_getPackageDownloadUrl( + array('package' => $pname['package'], + 'channel' => $pname['channel'], + 'version' => $info['version'])); + } + $vs = PEAR_Dependency2::_getExtraString($pname); + } + } else { + $vs = ' within preferred state "' . $this->_downloader->config->get('preferred_state') . '"'; + } + + $options = $this->_downloader->getOptions(); + // this is only set by the "download-all" command + if (isset($options['ignorepreferred_state'])) { + $err = PEAR::raiseError( + 'Failed to download ' . $this->_registry->parsedPackageNameToString( + array('channel' => $pname['channel'], 'package' => $pname['package']), + true) + . $vs . + ', latest release is version ' . $info['version'] . + ', stability "' . $info['info']->getState() . '", use "' . + $this->_registry->parsedPackageNameToString( + array('channel' => $pname['channel'], 'package' => $pname['package'], + 'version' => $info['version'])) . '" to install', + PEAR_DOWNLOADER_PACKAGE_STATE); + return $err; + } + + // Checks if the user has a package installed already and checks the release against + // the state against the installed package, this allows upgrades for packages + // with lower stability than the preferred_state + $stability = $this->_registry->packageInfo($pname['package'], 'stability', $pname['channel']); + if (!$this->isInstalled($info) + || !in_array($info['info']->getState(), PEAR_Common::betterStates($stability['release'], true)) + ) { + $err = PEAR::raiseError( + 'Failed to download ' . $this->_registry->parsedPackageNameToString( + array('channel' => $pname['channel'], 'package' => $pname['package']), + true) + . $vs . + ', latest release is version ' . $info['version'] . + ', stability "' . $info['info']->getState() . '", use "' . + $this->_registry->parsedPackageNameToString( + array('channel' => $pname['channel'], 'package' => $pname['package'], + 'version' => $info['version'])) . '" to install'); + return $err; + } + } + } + + if (isset($info['deprecated']) && $info['deprecated']) { + $this->_downloader->log(0, + 'WARNING: "' . + $this->_registry->parsedPackageNameToString( + array('channel' => $info['info']->getChannel(), + 'package' => $info['info']->getPackage()), true) . + '" is deprecated in favor of "' . + $this->_registry->parsedPackageNameToString($info['deprecated'], true) . + '"'); + } + + return $info; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/ErrorStack.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/ErrorStack.php new file mode 100644 index 0000000..7b705bd --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/ErrorStack.php @@ -0,0 +1,979 @@ + + * @copyright 2004-2008 Greg Beaver + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR_ErrorStack + */ + +/** + * Singleton storage + * + * Format: + *
    + * array(
    + *  'package1' => PEAR_ErrorStack object,
    + *  'package2' => PEAR_ErrorStack object,
    + *  ...
    + * )
    + * 
    + * @access private + * @global array $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] + */ +$GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] = array(); + +/** + * Global error callback (default) + * + * This is only used if set to non-false. * is the default callback for + * all packages, whereas specific packages may set a default callback + * for all instances, regardless of whether they are a singleton or not. + * + * To exclude non-singletons, only set the local callback for the singleton + * @see PEAR_ErrorStack::setDefaultCallback() + * @access private + * @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'] + */ +$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'] = array( + '*' => false, +); + +/** + * Global Log object (default) + * + * This is only used if set to non-false. Use to set a default log object for + * all stacks, regardless of instantiation order or location + * @see PEAR_ErrorStack::setDefaultLogger() + * @access private + * @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] + */ +$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = false; + +/** + * Global Overriding Callback + * + * This callback will override any error callbacks that specific loggers have set. + * Use with EXTREME caution + * @see PEAR_ErrorStack::staticPushCallback() + * @access private + * @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] + */ +$GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'] = array(); + +/**#@+ + * One of four possible return values from the error Callback + * @see PEAR_ErrorStack::_errorCallback() + */ +/** + * If this is returned, then the error will be both pushed onto the stack + * and logged. + */ +define('PEAR_ERRORSTACK_PUSHANDLOG', 1); +/** + * If this is returned, then the error will only be pushed onto the stack, + * and not logged. + */ +define('PEAR_ERRORSTACK_PUSH', 2); +/** + * If this is returned, then the error will only be logged, but not pushed + * onto the error stack. + */ +define('PEAR_ERRORSTACK_LOG', 3); +/** + * If this is returned, then the error is completely ignored. + */ +define('PEAR_ERRORSTACK_IGNORE', 4); +/** + * If this is returned, then the error is logged and die() is called. + */ +define('PEAR_ERRORSTACK_DIE', 5); +/**#@-*/ + +/** + * Error code for an attempt to instantiate a non-class as a PEAR_ErrorStack in + * the singleton method. + */ +define('PEAR_ERRORSTACK_ERR_NONCLASS', 1); + +/** + * Error code for an attempt to pass an object into {@link PEAR_ErrorStack::getMessage()} + * that has no __toString() method + */ +define('PEAR_ERRORSTACK_ERR_OBJTOSTRING', 2); +/** + * Error Stack Implementation + * + * Usage: + * + * // global error stack + * $global_stack = &PEAR_ErrorStack::singleton('MyPackage'); + * // local error stack + * $local_stack = new PEAR_ErrorStack('MyPackage'); + * + * @author Greg Beaver + * @version 1.10.1 + * @package PEAR_ErrorStack + * @category Debugging + * @copyright 2004-2008 Greg Beaver + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR_ErrorStack + */ +class PEAR_ErrorStack { + /** + * Errors are stored in the order that they are pushed on the stack. + * @since 0.4alpha Errors are no longer organized by error level. + * This renders pop() nearly unusable, and levels could be more easily + * handled in a callback anyway + * @var array + * @access private + */ + var $_errors = array(); + + /** + * Storage of errors by level. + * + * Allows easy retrieval and deletion of only errors from a particular level + * @since PEAR 1.4.0dev + * @var array + * @access private + */ + var $_errorsByLevel = array(); + + /** + * Package name this error stack represents + * @var string + * @access protected + */ + var $_package; + + /** + * Determines whether a PEAR_Error is thrown upon every error addition + * @var boolean + * @access private + */ + var $_compat = false; + + /** + * If set to a valid callback, this will be used to generate the error + * message from the error code, otherwise the message passed in will be + * used + * @var false|string|array + * @access private + */ + var $_msgCallback = false; + + /** + * If set to a valid callback, this will be used to generate the error + * context for an error. For PHP-related errors, this will be a file + * and line number as retrieved from debug_backtrace(), but can be + * customized for other purposes. The error might actually be in a separate + * configuration file, or in a database query. + * @var false|string|array + * @access protected + */ + var $_contextCallback = false; + + /** + * If set to a valid callback, this will be called every time an error + * is pushed onto the stack. The return value will be used to determine + * whether to allow an error to be pushed or logged. + * + * The return value must be one an PEAR_ERRORSTACK_* constant + * @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG + * @var false|string|array + * @access protected + */ + var $_errorCallback = array(); + + /** + * PEAR::Log object for logging errors + * @var false|Log + * @access protected + */ + var $_logger = false; + + /** + * Error messages - designed to be overridden + * @var array + * @abstract + */ + var $_errorMsgs = array(); + + /** + * Set up a new error stack + * + * @param string $package name of the package this error stack represents + * @param callback $msgCallback callback used for error message generation + * @param callback $contextCallback callback used for context generation, + * defaults to {@link getFileLine()} + * @param boolean $throwPEAR_Error + */ + function __construct($package, $msgCallback = false, $contextCallback = false, + $throwPEAR_Error = false) + { + $this->_package = $package; + $this->setMessageCallback($msgCallback); + $this->setContextCallback($contextCallback); + $this->_compat = $throwPEAR_Error; + } + + /** + * Return a single error stack for this package. + * + * Note that all parameters are ignored if the stack for package $package + * has already been instantiated + * @param string $package name of the package this error stack represents + * @param callback $msgCallback callback used for error message generation + * @param callback $contextCallback callback used for context generation, + * defaults to {@link getFileLine()} + * @param boolean $throwPEAR_Error + * @param string $stackClass class to instantiate + * + * @return PEAR_ErrorStack + */ + public static function &singleton( + $package, $msgCallback = false, $contextCallback = false, + $throwPEAR_Error = false, $stackClass = 'PEAR_ErrorStack' + ) { + if (isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) { + return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]; + } + if (!class_exists($stackClass)) { + if (function_exists('debug_backtrace')) { + $trace = debug_backtrace(); + } + PEAR_ErrorStack::staticPush('PEAR_ErrorStack', PEAR_ERRORSTACK_ERR_NONCLASS, + 'exception', array('stackclass' => $stackClass), + 'stack class "%stackclass%" is not a valid class name (should be like PEAR_ErrorStack)', + false, $trace); + } + $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package] = + new $stackClass($package, $msgCallback, $contextCallback, $throwPEAR_Error); + + return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]; + } + + /** + * Internal error handler for PEAR_ErrorStack class + * + * Dies if the error is an exception (and would have died anyway) + * @access private + */ + function _handleError($err) + { + if ($err['level'] == 'exception') { + $message = $err['message']; + if (isset($_SERVER['REQUEST_URI'])) { + echo '
    '; + } else { + echo "\n"; + } + var_dump($err['context']); + die($message); + } + } + + /** + * Set up a PEAR::Log object for all error stacks that don't have one + * @param Log $log + */ + public static function setDefaultLogger(&$log) + { + if (is_object($log) && method_exists($log, 'log') ) { + $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = &$log; + } elseif (is_callable($log)) { + $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = &$log; + } + } + + /** + * Set up a PEAR::Log object for this error stack + * @param Log $log + */ + function setLogger(&$log) + { + if (is_object($log) && method_exists($log, 'log') ) { + $this->_logger = &$log; + } elseif (is_callable($log)) { + $this->_logger = &$log; + } + } + + /** + * Set an error code => error message mapping callback + * + * This method sets the callback that can be used to generate error + * messages for any instance + * @param array|string Callback function/method + */ + function setMessageCallback($msgCallback) + { + if (!$msgCallback) { + $this->_msgCallback = array(&$this, 'getErrorMessage'); + } else { + if (is_callable($msgCallback)) { + $this->_msgCallback = $msgCallback; + } + } + } + + /** + * Get an error code => error message mapping callback + * + * This method returns the current callback that can be used to generate error + * messages + * @return array|string|false Callback function/method or false if none + */ + function getMessageCallback() + { + return $this->_msgCallback; + } + + /** + * Sets a default callback to be used by all error stacks + * + * This method sets the callback that can be used to generate error + * messages for a singleton + * @param array|string Callback function/method + * @param string Package name, or false for all packages + */ + public static function setDefaultCallback($callback = false, $package = false) + { + if (!is_callable($callback)) { + $callback = false; + } + $package = $package ? $package : '*'; + $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$package] = $callback; + } + + /** + * Set a callback that generates context information (location of error) for an error stack + * + * This method sets the callback that can be used to generate context + * information for an error. Passing in NULL will disable context generation + * and remove the expensive call to debug_backtrace() + * @param array|string|null Callback function/method + */ + function setContextCallback($contextCallback) + { + if ($contextCallback === null) { + return $this->_contextCallback = false; + } + if (!$contextCallback) { + $this->_contextCallback = array(&$this, 'getFileLine'); + } else { + if (is_callable($contextCallback)) { + $this->_contextCallback = $contextCallback; + } + } + } + + /** + * Set an error Callback + * If set to a valid callback, this will be called every time an error + * is pushed onto the stack. The return value will be used to determine + * whether to allow an error to be pushed or logged. + * + * The return value must be one of the ERRORSTACK_* constants. + * + * This functionality can be used to emulate PEAR's pushErrorHandling, and + * the PEAR_ERROR_CALLBACK mode, without affecting the integrity of + * the error stack or logging + * @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG + * @see popCallback() + * @param string|array $cb + */ + function pushCallback($cb) + { + array_push($this->_errorCallback, $cb); + } + + /** + * Remove a callback from the error callback stack + * @see pushCallback() + * @return array|string|false + */ + function popCallback() + { + if (!count($this->_errorCallback)) { + return false; + } + return array_pop($this->_errorCallback); + } + + /** + * Set a temporary overriding error callback for every package error stack + * + * Use this to temporarily disable all existing callbacks (can be used + * to emulate the @ operator, for instance) + * @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG + * @see staticPopCallback(), pushCallback() + * @param string|array $cb + */ + public static function staticPushCallback($cb) + { + array_push($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'], $cb); + } + + /** + * Remove a temporary overriding error callback + * @see staticPushCallback() + * @return array|string|false + */ + public static function staticPopCallback() + { + $ret = array_pop($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK']); + if (!is_array($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'])) { + $GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'] = array(); + } + return $ret; + } + + /** + * Add an error to the stack + * + * If the message generator exists, it is called with 2 parameters. + * - the current Error Stack object + * - an array that is in the same format as an error. Available indices + * are 'code', 'package', 'time', 'params', 'level', and 'context' + * + * Next, if the error should contain context information, this is + * handled by the context grabbing method. + * Finally, the error is pushed onto the proper error stack + * @param int $code Package-specific error code + * @param string $level Error level. This is NOT spell-checked + * @param array $params associative array of error parameters + * @param string $msg Error message, or a portion of it if the message + * is to be generated + * @param array $repackage If this error re-packages an error pushed by + * another package, place the array returned from + * {@link pop()} in this parameter + * @param array $backtrace Protected parameter: use this to pass in the + * {@link debug_backtrace()} that should be used + * to find error context + * @return PEAR_Error|array if compatibility mode is on, a PEAR_Error is also + * thrown. If a PEAR_Error is returned, the userinfo + * property is set to the following array: + * + * + * array( + * 'code' => $code, + * 'params' => $params, + * 'package' => $this->_package, + * 'level' => $level, + * 'time' => time(), + * 'context' => $context, + * 'message' => $msg, + * //['repackage' => $err] repackaged error array/Exception class + * ); + * + * + * Normally, the previous array is returned. + */ + function push($code, $level = 'error', $params = array(), $msg = false, + $repackage = false, $backtrace = false) + { + $context = false; + // grab error context + if ($this->_contextCallback) { + if (!$backtrace) { + $backtrace = debug_backtrace(); + } + $context = call_user_func($this->_contextCallback, $code, $params, $backtrace); + } + + // save error + $time = explode(' ', microtime()); + $time = $time[1] + $time[0]; + $err = array( + 'code' => $code, + 'params' => $params, + 'package' => $this->_package, + 'level' => $level, + 'time' => $time, + 'context' => $context, + 'message' => $msg, + ); + + if ($repackage) { + $err['repackage'] = $repackage; + } + + // set up the error message, if necessary + if ($this->_msgCallback) { + $msg = call_user_func_array($this->_msgCallback, + array(&$this, $err)); + $err['message'] = $msg; + } + $push = $log = true; + $die = false; + // try the overriding callback first + $callback = $this->staticPopCallback(); + if ($callback) { + $this->staticPushCallback($callback); + } + if (!is_callable($callback)) { + // try the local callback next + $callback = $this->popCallback(); + if (is_callable($callback)) { + $this->pushCallback($callback); + } else { + // try the default callback + $callback = isset($GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$this->_package]) ? + $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$this->_package] : + $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK']['*']; + } + } + if (is_callable($callback)) { + switch(call_user_func($callback, $err)){ + case PEAR_ERRORSTACK_IGNORE: + return $err; + break; + case PEAR_ERRORSTACK_PUSH: + $log = false; + break; + case PEAR_ERRORSTACK_LOG: + $push = false; + break; + case PEAR_ERRORSTACK_DIE: + $die = true; + break; + // anything else returned has the same effect as pushandlog + } + } + if ($push) { + array_unshift($this->_errors, $err); + if (!isset($this->_errorsByLevel[$err['level']])) { + $this->_errorsByLevel[$err['level']] = array(); + } + $this->_errorsByLevel[$err['level']][] = &$this->_errors[0]; + } + if ($log) { + if ($this->_logger || $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']) { + $this->_log($err); + } + } + if ($die) { + die(); + } + if ($this->_compat && $push) { + return $this->raiseError($msg, $code, null, null, $err); + } + return $err; + } + + /** + * Static version of {@link push()} + * + * @param string $package Package name this error belongs to + * @param int $code Package-specific error code + * @param string $level Error level. This is NOT spell-checked + * @param array $params associative array of error parameters + * @param string $msg Error message, or a portion of it if the message + * is to be generated + * @param array $repackage If this error re-packages an error pushed by + * another package, place the array returned from + * {@link pop()} in this parameter + * @param array $backtrace Protected parameter: use this to pass in the + * {@link debug_backtrace()} that should be used + * to find error context + * @return PEAR_Error|array if compatibility mode is on, a PEAR_Error is also + * thrown. see docs for {@link push()} + */ + public static function staticPush( + $package, $code, $level = 'error', $params = array(), + $msg = false, $repackage = false, $backtrace = false + ) { + $s = &PEAR_ErrorStack::singleton($package); + if ($s->_contextCallback) { + if (!$backtrace) { + if (function_exists('debug_backtrace')) { + $backtrace = debug_backtrace(); + } + } + } + return $s->push($code, $level, $params, $msg, $repackage, $backtrace); + } + + /** + * Log an error using PEAR::Log + * @param array $err Error array + * @param array $levels Error level => Log constant map + * @access protected + */ + function _log($err) + { + if ($this->_logger) { + $logger = &$this->_logger; + } else { + $logger = &$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']; + } + if (is_a($logger, 'Log')) { + $levels = array( + 'exception' => PEAR_LOG_CRIT, + 'alert' => PEAR_LOG_ALERT, + 'critical' => PEAR_LOG_CRIT, + 'error' => PEAR_LOG_ERR, + 'warning' => PEAR_LOG_WARNING, + 'notice' => PEAR_LOG_NOTICE, + 'info' => PEAR_LOG_INFO, + 'debug' => PEAR_LOG_DEBUG); + if (isset($levels[$err['level']])) { + $level = $levels[$err['level']]; + } else { + $level = PEAR_LOG_INFO; + } + $logger->log($err['message'], $level, $err); + } else { // support non-standard logs + call_user_func($logger, $err); + } + } + + + /** + * Pop an error off of the error stack + * + * @return false|array + * @since 0.4alpha it is no longer possible to specify a specific error + * level to return - the last error pushed will be returned, instead + */ + function pop() + { + $err = @array_shift($this->_errors); + if (!is_null($err)) { + @array_pop($this->_errorsByLevel[$err['level']]); + if (!count($this->_errorsByLevel[$err['level']])) { + unset($this->_errorsByLevel[$err['level']]); + } + } + return $err; + } + + /** + * Pop an error off of the error stack, static method + * + * @param string package name + * @return boolean + * @since PEAR1.5.0a1 + */ + function staticPop($package) + { + if ($package) { + if (!isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) { + return false; + } + return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->pop(); + } + } + + /** + * Determine whether there are any errors on the stack + * @param string|array Level name. Use to determine if any errors + * of level (string), or levels (array) have been pushed + * @return boolean + */ + function hasErrors($level = false) + { + if ($level) { + return isset($this->_errorsByLevel[$level]); + } + return count($this->_errors); + } + + /** + * Retrieve all errors since last purge + * + * @param boolean set in order to empty the error stack + * @param string level name, to return only errors of a particular severity + * @return array + */ + function getErrors($purge = false, $level = false) + { + if (!$purge) { + if ($level) { + if (!isset($this->_errorsByLevel[$level])) { + return array(); + } else { + return $this->_errorsByLevel[$level]; + } + } else { + return $this->_errors; + } + } + if ($level) { + $ret = $this->_errorsByLevel[$level]; + foreach ($this->_errorsByLevel[$level] as $i => $unused) { + // entries are references to the $_errors array + $this->_errorsByLevel[$level][$i] = false; + } + // array_filter removes all entries === false + $this->_errors = array_filter($this->_errors); + unset($this->_errorsByLevel[$level]); + return $ret; + } + $ret = $this->_errors; + $this->_errors = array(); + $this->_errorsByLevel = array(); + return $ret; + } + + /** + * Determine whether there are any errors on a single error stack, or on any error stack + * + * The optional parameter can be used to test the existence of any errors without the need of + * singleton instantiation + * @param string|false Package name to check for errors + * @param string Level name to check for a particular severity + * @return boolean + */ + public static function staticHasErrors($package = false, $level = false) + { + if ($package) { + if (!isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) { + return false; + } + return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->hasErrors($level); + } + foreach ($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] as $package => $obj) { + if ($obj->hasErrors($level)) { + return true; + } + } + return false; + } + + /** + * Get a list of all errors since last purge, organized by package + * @since PEAR 1.4.0dev BC break! $level is now in the place $merge used to be + * @param boolean $purge Set to purge the error stack of existing errors + * @param string $level Set to a level name in order to retrieve only errors of a particular level + * @param boolean $merge Set to return a flat array, not organized by package + * @param array $sortfunc Function used to sort a merged array - default + * sorts by time, and should be good for most cases + * + * @return array + */ + public static function staticGetErrors( + $purge = false, $level = false, $merge = false, + $sortfunc = array('PEAR_ErrorStack', '_sortErrors') + ) { + $ret = array(); + if (!is_callable($sortfunc)) { + $sortfunc = array('PEAR_ErrorStack', '_sortErrors'); + } + foreach ($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] as $package => $obj) { + $test = $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->getErrors($purge, $level); + if ($test) { + if ($merge) { + $ret = array_merge($ret, $test); + } else { + $ret[$package] = $test; + } + } + } + if ($merge) { + usort($ret, $sortfunc); + } + return $ret; + } + + /** + * Error sorting function, sorts by time + * @access private + */ + public static function _sortErrors($a, $b) + { + if ($a['time'] == $b['time']) { + return 0; + } + if ($a['time'] < $b['time']) { + return 1; + } + return -1; + } + + /** + * Standard file/line number/function/class context callback + * + * This function uses a backtrace generated from {@link debug_backtrace()} + * and so will not work at all in PHP < 4.3.0. The frame should + * reference the frame that contains the source of the error. + * @return array|false either array('file' => file, 'line' => line, + * 'function' => function name, 'class' => class name) or + * if this doesn't work, then false + * @param unused + * @param integer backtrace frame. + * @param array Results of debug_backtrace() + */ + public static function getFileLine($code, $params, $backtrace = null) + { + if ($backtrace === null) { + return false; + } + $frame = 0; + $functionframe = 1; + if (!isset($backtrace[1])) { + $functionframe = 0; + } else { + while (isset($backtrace[$functionframe]['function']) && + $backtrace[$functionframe]['function'] == 'eval' && + isset($backtrace[$functionframe + 1])) { + $functionframe++; + } + } + if (isset($backtrace[$frame])) { + if (!isset($backtrace[$frame]['file'])) { + $frame++; + } + $funcbacktrace = $backtrace[$functionframe]; + $filebacktrace = $backtrace[$frame]; + $ret = array('file' => $filebacktrace['file'], + 'line' => $filebacktrace['line']); + // rearrange for eval'd code or create function errors + if (strpos($filebacktrace['file'], '(') && + preg_match(';^(.*?)\((\d+)\) : (.*?)\\z;', $filebacktrace['file'], + $matches)) { + $ret['file'] = $matches[1]; + $ret['line'] = $matches[2] + 0; + } + if (isset($funcbacktrace['function']) && isset($backtrace[1])) { + if ($funcbacktrace['function'] != 'eval') { + if ($funcbacktrace['function'] == '__lambda_func') { + $ret['function'] = 'create_function() code'; + } else { + $ret['function'] = $funcbacktrace['function']; + } + } + } + if (isset($funcbacktrace['class']) && isset($backtrace[1])) { + $ret['class'] = $funcbacktrace['class']; + } + return $ret; + } + return false; + } + + /** + * Standard error message generation callback + * + * This method may also be called by a custom error message generator + * to fill in template values from the params array, simply + * set the third parameter to the error message template string to use + * + * The special variable %__msg% is reserved: use it only to specify + * where a message passed in by the user should be placed in the template, + * like so: + * + * Error message: %msg% - internal error + * + * If the message passed like so: + * + * + * $stack->push(ERROR_CODE, 'error', array(), 'server error 500'); + * + * + * The returned error message will be "Error message: server error 500 - + * internal error" + * @param PEAR_ErrorStack + * @param array + * @param string|false Pre-generated error message template + * + * @return string + */ + public static function getErrorMessage(&$stack, $err, $template = false) + { + if ($template) { + $mainmsg = $template; + } else { + $mainmsg = $stack->getErrorMessageTemplate($err['code']); + } + $mainmsg = str_replace('%__msg%', $err['message'], $mainmsg); + if (is_array($err['params']) && count($err['params'])) { + foreach ($err['params'] as $name => $val) { + if (is_array($val)) { + // @ is needed in case $val is a multi-dimensional array + $val = @implode(', ', $val); + } + if (is_object($val)) { + if (method_exists($val, '__toString')) { + $val = $val->__toString(); + } else { + PEAR_ErrorStack::staticPush('PEAR_ErrorStack', PEAR_ERRORSTACK_ERR_OBJTOSTRING, + 'warning', array('obj' => get_class($val)), + 'object %obj% passed into getErrorMessage, but has no __toString() method'); + $val = 'Object'; + } + } + $mainmsg = str_replace('%' . $name . '%', $val, $mainmsg); + } + } + return $mainmsg; + } + + /** + * Standard Error Message Template generator from code + * @return string + */ + function getErrorMessageTemplate($code) + { + if (!isset($this->_errorMsgs[$code])) { + return '%__msg%'; + } + return $this->_errorMsgs[$code]; + } + + /** + * Set the Error Message Template array + * + * The array format must be: + *
    +     * array(error code => 'message template',...)
    +     * 
    + * + * Error message parameters passed into {@link push()} will be used as input + * for the error message. If the template is 'message %foo% was %bar%', and the + * parameters are array('foo' => 'one', 'bar' => 'six'), the error message returned will + * be 'message one was six' + * @return string + */ + function setErrorMessageTemplate($template) + { + $this->_errorMsgs = $template; + } + + + /** + * emulate PEAR::raiseError() + * + * @return PEAR_Error + */ + function raiseError() + { + require_once 'PEAR.php'; + $args = func_get_args(); + return call_user_func_array(array('PEAR', 'raiseError'), $args); + } +} +$stack = &PEAR_ErrorStack::singleton('PEAR_ErrorStack'); +$stack->pushCallback(array('PEAR_ErrorStack', '_handleError')); +?> diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Exception.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Exception.php new file mode 100644 index 0000000..0aba171 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Exception.php @@ -0,0 +1,388 @@ + + * @author Hans Lellelid + * @author Bertrand Mansion + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.3.3 + */ + + +/** + * Base PEAR_Exception Class + * + * 1) Features: + * + * - Nestable exceptions (throw new PEAR_Exception($msg, $prev_exception)) + * - Definable triggers, shot when exceptions occur + * - Pretty and informative error messages + * - Added more context info available (like class, method or cause) + * - cause can be a PEAR_Exception or an array of mixed + * PEAR_Exceptions/PEAR_ErrorStack warnings + * - callbacks for specific exception classes and their children + * + * 2) Ideas: + * + * - Maybe a way to define a 'template' for the output + * + * 3) Inherited properties from PHP Exception Class: + * + * protected $message + * protected $code + * protected $line + * protected $file + * private $trace + * + * 4) Inherited methods from PHP Exception Class: + * + * __clone + * __construct + * getMessage + * getCode + * getFile + * getLine + * getTraceSafe + * getTraceSafeAsString + * __toString + * + * 5) Usage example + * + * + * require_once 'PEAR/Exception.php'; + * + * class Test { + * function foo() { + * throw new PEAR_Exception('Error Message', ERROR_CODE); + * } + * } + * + * function myLogger($pear_exception) { + * echo $pear_exception->getMessage(); + * } + * // each time a exception is thrown the 'myLogger' will be called + * // (its use is completely optional) + * PEAR_Exception::addObserver('myLogger'); + * $test = new Test; + * try { + * $test->foo(); + * } catch (PEAR_Exception $e) { + * print $e; + * } + * + * + * @category pear + * @package PEAR + * @author Tomas V.V.Cox + * @author Hans Lellelid + * @author Bertrand Mansion + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.3.3 + * + */ +class PEAR_Exception extends Exception +{ + const OBSERVER_PRINT = -2; + const OBSERVER_TRIGGER = -4; + const OBSERVER_DIE = -8; + protected $cause; + private static $_observers = array(); + private static $_uniqueid = 0; + private $_trace; + + /** + * Supported signatures: + * - PEAR_Exception(string $message); + * - PEAR_Exception(string $message, int $code); + * - PEAR_Exception(string $message, Exception $cause); + * - PEAR_Exception(string $message, Exception $cause, int $code); + * - PEAR_Exception(string $message, PEAR_Error $cause); + * - PEAR_Exception(string $message, PEAR_Error $cause, int $code); + * - PEAR_Exception(string $message, array $causes); + * - PEAR_Exception(string $message, array $causes, int $code); + * @param string exception message + * @param int|Exception|PEAR_Error|array|null exception cause + * @param int|null exception code or null + */ + public function __construct($message, $p2 = null, $p3 = null) + { + if (is_int($p2)) { + $code = $p2; + $this->cause = null; + } elseif (is_object($p2) || is_array($p2)) { + // using is_object allows both Exception and PEAR_Error + if (is_object($p2) && !($p2 instanceof Exception)) { + if (!class_exists('PEAR_Error') || !($p2 instanceof PEAR_Error)) { + throw new PEAR_Exception('exception cause must be Exception, ' . + 'array, or PEAR_Error'); + } + } + $code = $p3; + if (is_array($p2) && isset($p2['message'])) { + // fix potential problem of passing in a single warning + $p2 = array($p2); + } + $this->cause = $p2; + } else { + $code = null; + $this->cause = null; + } + parent::__construct($message, $code); + $this->signal(); + } + + /** + * @param mixed $callback - A valid php callback, see php func is_callable() + * - A PEAR_Exception::OBSERVER_* constant + * - An array(const PEAR_Exception::OBSERVER_*, + * mixed $options) + * @param string $label The name of the observer. Use this if you want + * to remove it later with removeObserver() + */ + public static function addObserver($callback, $label = 'default') + { + self::$_observers[$label] = $callback; + } + + public static function removeObserver($label = 'default') + { + unset(self::$_observers[$label]); + } + + /** + * @return int unique identifier for an observer + */ + public static function getUniqueId() + { + return self::$_uniqueid++; + } + + private function signal() + { + foreach (self::$_observers as $func) { + if (is_callable($func)) { + call_user_func($func, $this); + continue; + } + settype($func, 'array'); + switch ($func[0]) { + case self::OBSERVER_PRINT : + $f = (isset($func[1])) ? $func[1] : '%s'; + printf($f, $this->getMessage()); + break; + case self::OBSERVER_TRIGGER : + $f = (isset($func[1])) ? $func[1] : E_USER_NOTICE; + trigger_error($this->getMessage(), $f); + break; + case self::OBSERVER_DIE : + $f = (isset($func[1])) ? $func[1] : '%s'; + die(printf($f, $this->getMessage())); + break; + default: + trigger_error('invalid observer type', E_USER_WARNING); + } + } + } + + /** + * Return specific error information that can be used for more detailed + * error messages or translation. + * + * This method may be overridden in child exception classes in order + * to add functionality not present in PEAR_Exception and is a placeholder + * to define API + * + * The returned array must be an associative array of parameter => value like so: + *
    +     * array('name' => $name, 'context' => array(...))
    +     * 
    + * @return array + */ + public function getErrorData() + { + return array(); + } + + /** + * Returns the exception that caused this exception to be thrown + * @access public + * @return Exception|array The context of the exception + */ + public function getCause() + { + return $this->cause; + } + + /** + * Function must be public to call on caused exceptions + * @param array + */ + public function getCauseMessage(&$causes) + { + $trace = $this->getTraceSafe(); + $cause = array('class' => get_class($this), + 'message' => $this->message, + 'file' => 'unknown', + 'line' => 'unknown'); + if (isset($trace[0])) { + if (isset($trace[0]['file'])) { + $cause['file'] = $trace[0]['file']; + $cause['line'] = $trace[0]['line']; + } + } + $causes[] = $cause; + if ($this->cause instanceof PEAR_Exception) { + $this->cause->getCauseMessage($causes); + } elseif ($this->cause instanceof Exception) { + $causes[] = array('class' => get_class($this->cause), + 'message' => $this->cause->getMessage(), + 'file' => $this->cause->getFile(), + 'line' => $this->cause->getLine()); + } elseif (class_exists('PEAR_Error') && $this->cause instanceof PEAR_Error) { + $causes[] = array('class' => get_class($this->cause), + 'message' => $this->cause->getMessage(), + 'file' => 'unknown', + 'line' => 'unknown'); + } elseif (is_array($this->cause)) { + foreach ($this->cause as $cause) { + if ($cause instanceof PEAR_Exception) { + $cause->getCauseMessage($causes); + } elseif ($cause instanceof Exception) { + $causes[] = array('class' => get_class($cause), + 'message' => $cause->getMessage(), + 'file' => $cause->getFile(), + 'line' => $cause->getLine()); + } elseif (class_exists('PEAR_Error') && $cause instanceof PEAR_Error) { + $causes[] = array('class' => get_class($cause), + 'message' => $cause->getMessage(), + 'file' => 'unknown', + 'line' => 'unknown'); + } elseif (is_array($cause) && isset($cause['message'])) { + // PEAR_ErrorStack warning + $causes[] = array( + 'class' => $cause['package'], + 'message' => $cause['message'], + 'file' => isset($cause['context']['file']) ? + $cause['context']['file'] : + 'unknown', + 'line' => isset($cause['context']['line']) ? + $cause['context']['line'] : + 'unknown', + ); + } + } + } + } + + public function getTraceSafe() + { + if (!isset($this->_trace)) { + $this->_trace = $this->getTrace(); + if (empty($this->_trace)) { + $backtrace = debug_backtrace(); + $this->_trace = array($backtrace[count($backtrace)-1]); + } + } + return $this->_trace; + } + + public function getErrorClass() + { + $trace = $this->getTraceSafe(); + return $trace[0]['class']; + } + + public function getErrorMethod() + { + $trace = $this->getTraceSafe(); + return $trace[0]['function']; + } + + public function __toString() + { + if (isset($_SERVER['REQUEST_URI'])) { + return $this->toHtml(); + } + return $this->toText(); + } + + public function toHtml() + { + $trace = $this->getTraceSafe(); + $causes = array(); + $this->getCauseMessage($causes); + $html = '' . "\n"; + foreach ($causes as $i => $cause) { + $html .= '\n"; + } + $html .= '' . "\n" + . '' + . '' + . '' . "\n"; + + foreach ($trace as $k => $v) { + $html .= '' + . '' + . '' . "\n"; + } + $html .= '' + . '' + . '' . "\n" + . '
    ' + . str_repeat('-', $i) . ' ' . $cause['class'] . ': ' + . htmlspecialchars($cause['message']) . ' in ' . $cause['file'] . ' ' + . 'on line ' . $cause['line'] . '' + . "
    Exception trace
    #FunctionLocation
    ' . $k . ''; + if (!empty($v['class'])) { + $html .= $v['class'] . $v['type']; + } + $html .= $v['function']; + $args = array(); + if (!empty($v['args'])) { + foreach ($v['args'] as $arg) { + if (is_null($arg)) $args[] = 'null'; + elseif (is_array($arg)) $args[] = 'Array'; + elseif (is_object($arg)) $args[] = 'Object('.get_class($arg).')'; + elseif (is_bool($arg)) $args[] = $arg ? 'true' : 'false'; + elseif (is_int($arg) || is_double($arg)) $args[] = $arg; + else { + $arg = (string)$arg; + $str = htmlspecialchars(substr($arg, 0, 16)); + if (strlen($arg) > 16) $str .= '…'; + $args[] = "'" . $str . "'"; + } + } + } + $html .= '(' . implode(', ',$args) . ')' + . '' . (isset($v['file']) ? $v['file'] : 'unknown') + . ':' . (isset($v['line']) ? $v['line'] : 'unknown') + . '
    ' . ($k+1) . '{main} 
    '; + return $html; + } + + public function toText() + { + $causes = array(); + $this->getCauseMessage($causes); + $causeMsg = ''; + foreach ($causes as $i => $cause) { + $causeMsg .= str_repeat(' ', $i) . $cause['class'] . ': ' + . $cause['message'] . ' in ' . $cause['file'] + . ' on line ' . $cause['line'] . "\n"; + } + return $causeMsg . $this->getTraceAsString(); + } +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Frontend.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Frontend.php new file mode 100644 index 0000000..8c8c8c6 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Frontend.php @@ -0,0 +1,223 @@ + + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * Include error handling + */ +//require_once 'PEAR.php'; + +/** + * Which user interface class is being used. + * @var string class name + */ +$GLOBALS['_PEAR_FRONTEND_CLASS'] = 'PEAR_Frontend_CLI'; + +/** + * Instance of $_PEAR_Command_uiclass. + * @var object + */ +$GLOBALS['_PEAR_FRONTEND_SINGLETON'] = null; + +/** + * Singleton-based frontend for PEAR user input/output + * + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Frontend extends PEAR +{ + /** + * Retrieve the frontend object + * @return PEAR_Frontend_CLI|PEAR_Frontend_Web|PEAR_Frontend_Gtk + */ + public static function &singleton($type = null) + { + if ($type === null) { + if (!isset($GLOBALS['_PEAR_FRONTEND_SINGLETON'])) { + $a = false; + return $a; + } + return $GLOBALS['_PEAR_FRONTEND_SINGLETON']; + } + + $a = PEAR_Frontend::setFrontendClass($type); + return $a; + } + + /** + * Set the frontend class that will be used by calls to {@link singleton()} + * + * Frontends are expected to conform to the PEAR naming standard of + * _ => DIRECTORY_SEPARATOR (PEAR_Frontend_CLI is in PEAR/Frontend/CLI.php) + * @param string $uiclass full class name + * @return PEAR_Frontend + */ + public static function &setFrontendClass($uiclass) + { + if (is_object($GLOBALS['_PEAR_FRONTEND_SINGLETON']) && + is_a($GLOBALS['_PEAR_FRONTEND_SINGLETON'], $uiclass)) { + return $GLOBALS['_PEAR_FRONTEND_SINGLETON']; + } + + if (!class_exists($uiclass)) { + $file = str_replace('_', '/', $uiclass) . '.php'; + if (PEAR_Frontend::isIncludeable($file)) { + include_once $file; + } + } + + if (class_exists($uiclass)) { + $obj = new $uiclass; + // quick test to see if this class implements a few of the most + // important frontend methods + if (is_a($obj, 'PEAR_Frontend')) { + $GLOBALS['_PEAR_FRONTEND_SINGLETON'] = &$obj; + $GLOBALS['_PEAR_FRONTEND_CLASS'] = $uiclass; + return $obj; + } + + $err = PEAR::raiseError("not a frontend class: $uiclass"); + return $err; + } + + $err = PEAR::raiseError("no such class: $uiclass"); + return $err; + } + + /** + * Set the frontend class that will be used by calls to {@link singleton()} + * + * Frontends are expected to be a descendant of PEAR_Frontend + * @param PEAR_Frontend + * @return PEAR_Frontend + */ + public static function &setFrontendObject($uiobject) + { + if (is_object($GLOBALS['_PEAR_FRONTEND_SINGLETON']) && + is_a($GLOBALS['_PEAR_FRONTEND_SINGLETON'], get_class($uiobject))) { + return $GLOBALS['_PEAR_FRONTEND_SINGLETON']; + } + + if (!is_a($uiobject, 'PEAR_Frontend')) { + $err = PEAR::raiseError('not a valid frontend class: (' . + get_class($uiobject) . ')'); + return $err; + } + + $GLOBALS['_PEAR_FRONTEND_SINGLETON'] = &$uiobject; + $GLOBALS['_PEAR_FRONTEND_CLASS'] = get_class($uiobject); + return $uiobject; + } + + /** + * @param string $path relative or absolute include path + * @return boolean + */ + public static function isIncludeable($path) + { + if (file_exists($path) && is_readable($path)) { + return true; + } + + $fp = @fopen($path, 'r', true); + if ($fp) { + fclose($fp); + return true; + } + + return false; + } + + /** + * @param PEAR_Config + */ + function setConfig(&$config) + { + } + + /** + * This can be overridden to allow session-based temporary file management + * + * By default, all files are deleted at the end of a session. The web installer + * needs to be able to sustain a list over many sessions in order to support + * user interaction with install scripts + */ + function addTempFile($file) + { + $GLOBALS['_PEAR_Common_tempfiles'][] = $file; + } + + /** + * Log an action + * + * @param string $msg the message to log + * @param boolean $append_crlf + * @return boolean true + * @abstract + */ + function log($msg, $append_crlf = true) + { + } + + /** + * Run a post-installation script + * + * @param array $scripts array of post-install scripts + * @abstract + */ + function runPostinstallScripts(&$scripts) + { + } + + /** + * Display human-friendly output formatted depending on the + * $command parameter. + * + * This should be able to handle basic output data with no command + * @param mixed $data data structure containing the information to display + * @param string $command command from which this method was called + * @abstract + */ + function outputData($data, $command = '_default') + { + } + + /** + * Display a modal form dialog and return the given input + * + * A frontend that requires multiple requests to retrieve and process + * data must take these needs into account, and implement the request + * handling code. + * @param string $command command from which this method was called + * @param array $prompts associative array. keys are the input field names + * and values are the description + * @param array $types array of input field types (text, password, + * etc.) keys have to be the same like in $prompts + * @param array $defaults array of default values. again keys have + * to be the same like in $prompts. Do not depend + * on a default value being set. + * @return array input sent by the user + * @abstract + */ + function userDialog($command, $prompts, $types = array(), $defaults = array()) + { + } +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Frontend/CLI.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Frontend/CLI.php new file mode 100644 index 0000000..f0723d0 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Frontend/CLI.php @@ -0,0 +1,750 @@ + + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 0.1 + */ +/** + * base class + */ +require_once 'PEAR/Frontend.php'; + +/** + * Command-line Frontend for the PEAR Installer + * @category pear + * @package PEAR + * @author Stig Bakken + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 0.1 + */ +class PEAR_Frontend_CLI extends PEAR_Frontend +{ + /** + * What type of user interface this frontend is for. + * @var string + * @access public + */ + var $type = 'CLI'; + var $lp = ''; // line prefix + + var $params = array(); + var $term = array( + 'bold' => '', + 'normal' => '', + ); + + function __construct() + { + parent::__construct(); + $term = getenv('TERM'); //(cox) $_ENV is empty for me in 4.1.1 + if (function_exists('posix_isatty') && !posix_isatty(1)) { + // output is being redirected to a file or through a pipe + } elseif ($term) { + if (preg_match('/^(xterm|vt220|linux)/', $term)) { + $this->term['bold'] = sprintf("%c%c%c%c", 27, 91, 49, 109); + $this->term['normal'] = sprintf("%c%c%c", 27, 91, 109); + } elseif (preg_match('/^vt100/', $term)) { + $this->term['bold'] = sprintf("%c%c%c%c%c%c", 27, 91, 49, 109, 0, 0); + $this->term['normal'] = sprintf("%c%c%c%c%c", 27, 91, 109, 0, 0); + } + } elseif (OS_WINDOWS) { + // XXX add ANSI codes here + } + } + + /** + * @param object PEAR_Error object + */ + function displayError($e) + { + return $this->_displayLine($e->getMessage()); + } + + /** + * @param object PEAR_Error object + */ + function displayFatalError($eobj) + { + $this->displayError($eobj); + if (class_exists('PEAR_Config')) { + $config = &PEAR_Config::singleton(); + if ($config->get('verbose') > 5) { + if (function_exists('debug_print_backtrace')) { + debug_print_backtrace(); + exit(1); + } + + $raised = false; + foreach (debug_backtrace() as $i => $frame) { + if (!$raised) { + if (isset($frame['class']) + && strtolower($frame['class']) == 'pear' + && strtolower($frame['function']) == 'raiseerror' + ) { + $raised = true; + } else { + continue; + } + } + + $frame['class'] = !isset($frame['class']) ? '' : $frame['class']; + $frame['type'] = !isset($frame['type']) ? '' : $frame['type']; + $frame['function'] = !isset($frame['function']) ? '' : $frame['function']; + $frame['line'] = !isset($frame['line']) ? '' : $frame['line']; + $this->_displayLine("#$i: $frame[class]$frame[type]$frame[function] $frame[line]"); + } + } + } + + exit(1); + } + + /** + * Instruct the runInstallScript method to skip a paramgroup that matches the + * id value passed in. + * + * This method is useful for dynamically configuring which sections of a post-install script + * will be run based on the user's setup, which is very useful for making flexible + * post-install scripts without losing the cross-Frontend ability to retrieve user input + * @param string + */ + function skipParamgroup($id) + { + $this->_skipSections[$id] = true; + } + + function runPostinstallScripts(&$scripts) + { + foreach ($scripts as $i => $script) { + $this->runInstallScript($scripts[$i]->_params, $scripts[$i]->_obj); + } + } + + /** + * @param array $xml contents of postinstallscript tag + * @param object $script post-installation script + * @param string install|upgrade + */ + function runInstallScript($xml, &$script) + { + $this->_skipSections = array(); + if (!is_array($xml) || !isset($xml['paramgroup'])) { + $script->run(array(), '_default'); + return; + } + + $completedPhases = array(); + if (!isset($xml['paramgroup'][0])) { + $xml['paramgroup'] = array($xml['paramgroup']); + } + + foreach ($xml['paramgroup'] as $group) { + if (isset($this->_skipSections[$group['id']])) { + // the post-install script chose to skip this section dynamically + continue; + } + + if (isset($group['name'])) { + $paramname = explode('::', $group['name']); + if ($lastgroup['id'] != $paramname[0]) { + continue; + } + + $group['name'] = $paramname[1]; + if (!isset($answers)) { + return; + } + + if (isset($answers[$group['name']])) { + switch ($group['conditiontype']) { + case '=' : + if ($answers[$group['name']] != $group['value']) { + continue 2; + } + break; + case '!=' : + if ($answers[$group['name']] == $group['value']) { + continue 2; + } + break; + case 'preg_match' : + if (!@preg_match('/' . $group['value'] . '/', + $answers[$group['name']])) { + continue 2; + } + break; + default : + return; + } + } + } + + $lastgroup = $group; + if (isset($group['instructions'])) { + $this->_display($group['instructions']); + } + + if (!isset($group['param'][0])) { + $group['param'] = array($group['param']); + } + + if (isset($group['param'])) { + if (method_exists($script, 'postProcessPrompts')) { + $prompts = $script->postProcessPrompts($group['param'], $group['id']); + if (!is_array($prompts) || count($prompts) != count($group['param'])) { + $this->outputData('postinstall', 'Error: post-install script did not ' . + 'return proper post-processed prompts'); + $prompts = $group['param']; + } else { + foreach ($prompts as $i => $var) { + if (!is_array($var) || !isset($var['prompt']) || + !isset($var['name']) || + ($var['name'] != $group['param'][$i]['name']) || + ($var['type'] != $group['param'][$i]['type']) + ) { + $this->outputData('postinstall', 'Error: post-install script ' . + 'modified the variables or prompts, severe security risk. ' . + 'Will instead use the defaults from the package.xml'); + $prompts = $group['param']; + } + } + } + + $answers = $this->confirmDialog($prompts); + } else { + $answers = $this->confirmDialog($group['param']); + } + } + + if ((isset($answers) && $answers) || !isset($group['param'])) { + if (!isset($answers)) { + $answers = array(); + } + + array_unshift($completedPhases, $group['id']); + if (!$script->run($answers, $group['id'])) { + $script->run($completedPhases, '_undoOnError'); + return; + } + } else { + $script->run($completedPhases, '_undoOnError'); + return; + } + } + } + + /** + * Ask for user input, confirm the answers and continue until the user is satisfied + * @param array an array of arrays, format array('name' => 'paramname', 'prompt' => + * 'text to display', 'type' => 'string'[, default => 'default value']) + * @return array + */ + function confirmDialog($params) + { + $answers = $prompts = $types = array(); + foreach ($params as $param) { + $prompts[$param['name']] = $param['prompt']; + $types[$param['name']] = $param['type']; + $answers[$param['name']] = isset($param['default']) ? $param['default'] : ''; + } + + $tried = false; + do { + if ($tried) { + $i = 1; + foreach ($answers as $var => $value) { + if (!strlen($value)) { + echo $this->bold("* Enter an answer for #" . $i . ": ({$prompts[$var]})\n"); + } + $i++; + } + } + + $answers = $this->userDialog('', $prompts, $types, $answers); + $tried = true; + } while (is_array($answers) && count(array_filter($answers)) != count($prompts)); + + return $answers; + } + + function userDialog($command, $prompts, $types = array(), $defaults = array(), $screensize = 20) + { + if (!is_array($prompts)) { + return array(); + } + + $testprompts = array_keys($prompts); + $result = $defaults; + + reset($prompts); + if (count($prompts) === 1) { + foreach ($prompts as $key => $prompt) { + $type = $types[$key]; + $default = @$defaults[$key]; + print "$prompt "; + if ($default) { + print "[$default] "; + } + print ": "; + + $line = fgets(STDIN, 2048); + $result[$key] = ($default && trim($line) == '') ? $default : trim($line); + } + + return $result; + } + + $first_run = true; + while (true) { + $descLength = max(array_map('strlen', $prompts)); + $descFormat = "%-{$descLength}s"; + $last = count($prompts); + + $i = 0; + foreach ($prompts as $n => $var) { + $res = isset($result[$n]) ? $result[$n] : null; + printf("%2d. $descFormat : %s\n", ++$i, $prompts[$n], $res); + } + print "\n1-$last, 'all', 'abort', or Enter to continue: "; + + $tmp = trim(fgets(STDIN, 1024)); + if (empty($tmp)) { + break; + } + + if ($tmp == 'abort') { + return false; + } + + if (isset($testprompts[(int)$tmp - 1])) { + $var = $testprompts[(int)$tmp - 1]; + $desc = $prompts[$var]; + $current = @$result[$var]; + print "$desc [$current] : "; + $tmp = trim(fgets(STDIN, 1024)); + if ($tmp !== '') { + $result[$var] = $tmp; + } + } elseif ($tmp == 'all') { + foreach ($prompts as $var => $desc) { + $current = $result[$var]; + print "$desc [$current] : "; + $tmp = trim(fgets(STDIN, 1024)); + if (trim($tmp) !== '') { + $result[$var] = trim($tmp); + } + } + } + + $first_run = false; + } + + return $result; + } + + function userConfirm($prompt, $default = 'yes') + { + trigger_error("PEAR_Frontend_CLI::userConfirm not yet converted", E_USER_ERROR); + static $positives = array('y', 'yes', 'on', '1'); + static $negatives = array('n', 'no', 'off', '0'); + print "$this->lp$prompt [$default] : "; + $fp = fopen("php://stdin", "r"); + $line = fgets($fp, 2048); + fclose($fp); + $answer = strtolower(trim($line)); + if (empty($answer)) { + $answer = $default; + } + if (in_array($answer, $positives)) { + return true; + } + if (in_array($answer, $negatives)) { + return false; + } + if (in_array($default, $positives)) { + return true; + } + return false; + } + + function outputData($data, $command = '_default') + { + switch ($command) { + case 'channel-info': + foreach ($data as $type => $section) { + if ($type == 'main') { + $section['data'] = array_values($section['data']); + } + + $this->outputData($section); + } + break; + case 'install': + case 'upgrade': + case 'upgrade-all': + if (is_array($data) && isset($data['release_warnings'])) { + $this->_displayLine(''); + $this->_startTable(array( + 'border' => false, + 'caption' => 'Release Warnings' + )); + $this->_tableRow(array($data['release_warnings']), null, array(1 => array('wrap' => 55))); + $this->_endTable(); + $this->_displayLine(''); + } + + $this->_displayLine(is_array($data) ? $data['data'] : $data); + break; + case 'search': + $this->_startTable($data); + if (isset($data['headline']) && is_array($data['headline'])) { + $this->_tableRow($data['headline'], array('bold' => true), array(1 => array('wrap' => 55))); + } + + $packages = array(); + foreach($data['data'] as $category) { + foreach($category as $name => $pkg) { + $packages[$pkg[0]] = $pkg; + } + } + + $p = array_keys($packages); + natcasesort($p); + foreach ($p as $name) { + $this->_tableRow($packages[$name], null, array(1 => array('wrap' => 55))); + } + + $this->_endTable(); + break; + case 'list-all': + if (!isset($data['data'])) { + $this->_displayLine('No packages in channel'); + break; + } + + $this->_startTable($data); + if (isset($data['headline']) && is_array($data['headline'])) { + $this->_tableRow($data['headline'], array('bold' => true), array(1 => array('wrap' => 55))); + } + + $packages = array(); + foreach($data['data'] as $category) { + foreach($category as $name => $pkg) { + $packages[$pkg[0]] = $pkg; + } + } + + $p = array_keys($packages); + natcasesort($p); + foreach ($p as $name) { + $pkg = $packages[$name]; + unset($pkg[4], $pkg[5]); + $this->_tableRow($pkg, null, array(1 => array('wrap' => 55))); + } + + $this->_endTable(); + break; + case 'config-show': + $data['border'] = false; + $opts = array( + 0 => array('wrap' => 30), + 1 => array('wrap' => 20), + 2 => array('wrap' => 35) + ); + + $this->_startTable($data); + if (isset($data['headline']) && is_array($data['headline'])) { + $this->_tableRow($data['headline'], array('bold' => true), $opts); + } + + foreach ($data['data'] as $group) { + foreach ($group as $value) { + if ($value[2] == '') { + $value[2] = ""; + } + + $this->_tableRow($value, null, $opts); + } + } + + $this->_endTable(); + break; + case 'remote-info': + $d = $data; + $data = array( + 'caption' => 'Package details:', + 'border' => false, + 'data' => array( + array("Latest", $data['stable']), + array("Installed", $data['installed']), + array("Package", $data['name']), + array("License", $data['license']), + array("Category", $data['category']), + array("Summary", $data['summary']), + array("Description", $data['description']), + ), + ); + + if (isset($d['deprecated']) && $d['deprecated']) { + $conf = &PEAR_Config::singleton(); + $reg = $conf->getRegistry(); + $name = $reg->parsedPackageNameToString($d['deprecated'], true); + $data['data'][] = array('Deprecated! use', $name); + } + default: { + if (is_array($data)) { + $this->_startTable($data); + $count = count($data['data'][0]); + if ($count == 2) { + $opts = array(0 => array('wrap' => 25), + 1 => array('wrap' => 48) + ); + } elseif ($count == 3) { + $opts = array(0 => array('wrap' => 30), + 1 => array('wrap' => 20), + 2 => array('wrap' => 35) + ); + } else { + $opts = null; + } + if (isset($data['headline']) && is_array($data['headline'])) { + $this->_tableRow($data['headline'], + array('bold' => true), + $opts); + } + + if (is_array($data['data'])) { + foreach($data['data'] as $row) { + $this->_tableRow($row, null, $opts); + } + } else { + $this->_tableRow(array($data['data']), null, $opts); + } + $this->_endTable(); + } else { + $this->_displayLine($data); + } + } + } + } + + function log($text, $append_crlf = true) + { + if ($append_crlf) { + return $this->_displayLine($text); + } + + return $this->_display($text); + } + + function bold($text) + { + if (empty($this->term['bold'])) { + return strtoupper($text); + } + + return $this->term['bold'] . $text . $this->term['normal']; + } + + function _displayHeading($title) + { + print $this->lp.$this->bold($title)."\n"; + print $this->lp.str_repeat("=", strlen($title))."\n"; + } + + function _startTable($params = array()) + { + $params['table_data'] = array(); + $params['widest'] = array(); // indexed by column + $params['highest'] = array(); // indexed by row + $params['ncols'] = 0; + $this->params = $params; + } + + function _tableRow($columns, $rowparams = array(), $colparams = array()) + { + $highest = 1; + for ($i = 0; $i < count($columns); $i++) { + $col = &$columns[$i]; + if (isset($colparams[$i]) && !empty($colparams[$i]['wrap'])) { + $col = wordwrap($col, $colparams[$i]['wrap']); + } + + if (strpos($col, "\n") !== false) { + $multiline = explode("\n", $col); + $w = 0; + foreach ($multiline as $n => $line) { + $len = strlen($line); + if ($len > $w) { + $w = $len; + } + } + $lines = count($multiline); + } else { + $w = strlen($col); + } + + if (isset($this->params['widest'][$i])) { + if ($w > $this->params['widest'][$i]) { + $this->params['widest'][$i] = $w; + } + } else { + $this->params['widest'][$i] = $w; + } + + $tmp = count_chars($columns[$i], 1); + // handle unix, mac and windows formats + $lines = (isset($tmp[10]) ? $tmp[10] : (isset($tmp[13]) ? $tmp[13] : 0)) + 1; + if ($lines > $highest) { + $highest = $lines; + } + } + + if (count($columns) > $this->params['ncols']) { + $this->params['ncols'] = count($columns); + } + + $new_row = array( + 'data' => $columns, + 'height' => $highest, + 'rowparams' => $rowparams, + 'colparams' => $colparams, + ); + $this->params['table_data'][] = $new_row; + } + + function _endTable() + { + extract($this->params); + if (!empty($caption)) { + $this->_displayHeading($caption); + } + + if (count($table_data) === 0) { + return; + } + + if (!isset($width)) { + $width = $widest; + } else { + for ($i = 0; $i < $ncols; $i++) { + if (!isset($width[$i])) { + $width[$i] = $widest[$i]; + } + } + } + + $border = false; + if (empty($border)) { + $cellstart = ''; + $cellend = ' '; + $rowend = ''; + $padrowend = false; + $borderline = ''; + } else { + $cellstart = '| '; + $cellend = ' '; + $rowend = '|'; + $padrowend = true; + $borderline = '+'; + foreach ($width as $w) { + $borderline .= str_repeat('-', $w + strlen($cellstart) + strlen($cellend) - 1); + $borderline .= '+'; + } + } + + if ($borderline) { + $this->_displayLine($borderline); + } + + for ($i = 0; $i < count($table_data); $i++) { + extract($table_data[$i]); + if (!is_array($rowparams)) { + $rowparams = array(); + } + + if (!is_array($colparams)) { + $colparams = array(); + } + + $rowlines = array(); + if ($height > 1) { + for ($c = 0; $c < count($data); $c++) { + $rowlines[$c] = preg_split('/(\r?\n|\r)/', $data[$c]); + if (count($rowlines[$c]) < $height) { + $rowlines[$c] = array_pad($rowlines[$c], $height, ''); + } + } + } else { + for ($c = 0; $c < count($data); $c++) { + $rowlines[$c] = array($data[$c]); + } + } + + for ($r = 0; $r < $height; $r++) { + $rowtext = ''; + for ($c = 0; $c < count($data); $c++) { + if (isset($colparams[$c])) { + $attribs = array_merge($rowparams, $colparams); + } else { + $attribs = $rowparams; + } + + $w = isset($width[$c]) ? $width[$c] : 0; + //$cell = $data[$c]; + $cell = $rowlines[$c][$r]; + $l = strlen($cell); + if ($l > $w) { + $cell = substr($cell, 0, $w); + } + + if (isset($attribs['bold'])) { + $cell = $this->bold($cell); + } + + if ($l < $w) { + // not using str_pad here because we may + // add bold escape characters to $cell + $cell .= str_repeat(' ', $w - $l); + } + + $rowtext .= $cellstart . $cell . $cellend; + } + + if (!$border) { + $rowtext = rtrim($rowtext); + } + + $rowtext .= $rowend; + $this->_displayLine($rowtext); + } + } + + if ($borderline) { + $this->_displayLine($borderline); + } + } + + function _displayLine($text) + { + print "$this->lp$text\n"; + } + + function _display($text) + { + print $text; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Installer.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Installer.php new file mode 100644 index 0000000..d5cc7df --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Installer.php @@ -0,0 +1,1794 @@ + + * @author Tomas V.V. Cox + * @author Martin Jansen + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 0.1 + */ + +/** + * Used for installation groups in package.xml 2.0 and platform exceptions + */ +require_once 'OS/Guess.php'; +require_once 'PEAR/Downloader.php'; + +define('PEAR_INSTALLER_NOBINARY', -240); +/** + * Administration class used to install PEAR packages and maintain the + * installed package database. + * + * @category pear + * @package PEAR + * @author Stig Bakken + * @author Tomas V.V. Cox + * @author Martin Jansen + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 0.1 + */ +class PEAR_Installer extends PEAR_Downloader +{ + // {{{ properties + + /** name of the package directory, for example Foo-1.0 + * @var string + */ + var $pkgdir; + + /** directory where PHP code files go + * @var string + */ + var $phpdir; + + /** directory where PHP extension files go + * @var string + */ + var $extdir; + + /** directory where documentation goes + * @var string + */ + var $docdir; + + /** installation root directory (ala PHP's INSTALL_ROOT or + * automake's DESTDIR + * @var string + */ + var $installroot = ''; + + /** debug level + * @var int + */ + var $debug = 1; + + /** temporary directory + * @var string + */ + var $tmpdir; + + /** + * PEAR_Registry object used by the installer + * @var PEAR_Registry + */ + var $registry; + + /** + * array of PEAR_Downloader_Packages + * @var array + */ + var $_downloadedPackages; + + /** List of file transactions queued for an install/upgrade/uninstall. + * + * Format: + * array( + * 0 => array("rename => array("from-file", "to-file")), + * 1 => array("delete" => array("file-to-delete")), + * ... + * ) + * + * @var array + */ + var $file_operations = array(); + + // }}} + + // {{{ constructor + + /** + * PEAR_Installer constructor. + * + * @param object $ui user interface object (instance of PEAR_Frontend_*) + * + * @access public + */ + function __construct(&$ui) + { + parent::__construct($ui, array(), null); + $this->setFrontendObject($ui); + $this->debug = $this->config->get('verbose'); + } + + function setOptions($options) + { + $this->_options = $options; + } + + function setConfig(&$config) + { + $this->config = &$config; + $this->_registry = &$config->getRegistry(); + } + + // }}} + + function _removeBackups($files) + { + foreach ($files as $path) { + $this->addFileOperation('removebackup', array($path)); + } + } + + // {{{ _deletePackageFiles() + + /** + * Delete a package's installed files, does not remove empty directories. + * + * @param string package name + * @param string channel name + * @param bool if true, then files are backed up first + * @return bool TRUE on success, or a PEAR error on failure + * @access protected + */ + function _deletePackageFiles($package, $channel = false, $backup = false) + { + if (!$channel) { + $channel = 'pear.php.net'; + } + + if (!strlen($package)) { + return $this->raiseError("No package to uninstall given"); + } + + if (strtolower($package) == 'pear' && $channel == 'pear.php.net') { + // to avoid race conditions, include all possible needed files + require_once 'PEAR/Task/Common.php'; + require_once 'PEAR/Task/Replace.php'; + require_once 'PEAR/Task/Unixeol.php'; + require_once 'PEAR/Task/Windowseol.php'; + require_once 'PEAR/PackageFile/v1.php'; + require_once 'PEAR/PackageFile/v2.php'; + require_once 'PEAR/PackageFile/Generator/v1.php'; + require_once 'PEAR/PackageFile/Generator/v2.php'; + } + + $filelist = $this->_registry->packageInfo($package, 'filelist', $channel); + if ($filelist == null) { + return $this->raiseError("$channel/$package not installed"); + } + + $ret = array(); + foreach ($filelist as $file => $props) { + if (empty($props['installed_as'])) { + continue; + } + + $path = $props['installed_as']; + if ($backup) { + $this->addFileOperation('backup', array($path)); + $ret[] = $path; + } + + $this->addFileOperation('delete', array($path)); + } + + if ($backup) { + return $ret; + } + + return true; + } + + // }}} + // {{{ _installFile() + + /** + * @param string filename + * @param array attributes from tag in package.xml + * @param string path to install the file in + * @param array options from command-line + * @access private + */ + function _installFile($file, $atts, $tmp_path, $options) + { + // {{{ return if this file is meant for another platform + static $os; + if (!isset($this->_registry)) { + $this->_registry = &$this->config->getRegistry(); + } + + if (isset($atts['platform'])) { + if (empty($os)) { + $os = new OS_Guess(); + } + + if (strlen($atts['platform']) && $atts['platform']{0} == '!') { + $negate = true; + $platform = substr($atts['platform'], 1); + } else { + $negate = false; + $platform = $atts['platform']; + } + + if ((bool) $os->matchSignature($platform) === $negate) { + $this->log(3, "skipped $file (meant for $atts[platform], we are ".$os->getSignature().")"); + return PEAR_INSTALLER_SKIPPED; + } + } + // }}} + + $channel = $this->pkginfo->getChannel(); + // {{{ assemble the destination paths + switch ($atts['role']) { + case 'src': + case 'extsrc': + $this->source_files++; + return; + case 'doc': + case 'data': + case 'test': + $dest_dir = $this->config->get($atts['role'] . '_dir', null, $channel) . + DIRECTORY_SEPARATOR . $this->pkginfo->getPackage(); + unset($atts['baseinstalldir']); + break; + case 'ext': + case 'php': + $dest_dir = $this->config->get($atts['role'] . '_dir', null, $channel); + break; + case 'script': + $dest_dir = $this->config->get('bin_dir', null, $channel); + break; + default: + return $this->raiseError("Invalid role `$atts[role]' for file $file"); + } + + $save_destdir = $dest_dir; + if (!empty($atts['baseinstalldir'])) { + $dest_dir .= DIRECTORY_SEPARATOR . $atts['baseinstalldir']; + } + + if (dirname($file) != '.' && empty($atts['install-as'])) { + $dest_dir .= DIRECTORY_SEPARATOR . dirname($file); + } + + if (empty($atts['install-as'])) { + $dest_file = $dest_dir . DIRECTORY_SEPARATOR . basename($file); + } else { + $dest_file = $dest_dir . DIRECTORY_SEPARATOR . $atts['install-as']; + } + $orig_file = $tmp_path . DIRECTORY_SEPARATOR . $file; + + // Clean up the DIRECTORY_SEPARATOR mess + $ds2 = DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR; + list($dest_file, $orig_file) = preg_replace(array('!\\\\+!', '!/!', "!$ds2+!"), + array(DIRECTORY_SEPARATOR, + DIRECTORY_SEPARATOR, + DIRECTORY_SEPARATOR), + array($dest_file, $orig_file)); + $final_dest_file = $installed_as = $dest_file; + if (isset($this->_options['packagingroot'])) { + $installedas_dest_dir = dirname($final_dest_file); + $installedas_dest_file = $dest_dir . DIRECTORY_SEPARATOR . '.tmp' . basename($final_dest_file); + $final_dest_file = $this->_prependPath($final_dest_file, $this->_options['packagingroot']); + } else { + $installedas_dest_dir = dirname($final_dest_file); + $installedas_dest_file = $installedas_dest_dir . DIRECTORY_SEPARATOR . '.tmp' . basename($final_dest_file); + } + + $dest_dir = dirname($final_dest_file); + $dest_file = $dest_dir . DIRECTORY_SEPARATOR . '.tmp' . basename($final_dest_file); + if (preg_match('~/\.\.(/|\\z)|^\.\./~', str_replace('\\', '/', $dest_file))) { + return $this->raiseError("SECURITY ERROR: file $file (installed to $dest_file) contains parent directory reference ..", PEAR_INSTALLER_FAILED); + } + // }}} + + if (empty($this->_options['register-only']) && + (!file_exists($dest_dir) || !is_dir($dest_dir))) { + if (!$this->mkDirHier($dest_dir)) { + return $this->raiseError("failed to mkdir $dest_dir", + PEAR_INSTALLER_FAILED); + } + $this->log(3, "+ mkdir $dest_dir"); + } + + // pretty much nothing happens if we are only registering the install + if (empty($this->_options['register-only'])) { + if (empty($atts['replacements'])) { + if (!file_exists($orig_file)) { + return $this->raiseError("file $orig_file does not exist", + PEAR_INSTALLER_FAILED); + } + + if (!@copy($orig_file, $dest_file)) { + return $this->raiseError("failed to write $dest_file: $php_errormsg", + PEAR_INSTALLER_FAILED); + } + + $this->log(3, "+ cp $orig_file $dest_file"); + if (isset($atts['md5sum'])) { + $md5sum = md5_file($dest_file); + } + } else { + // {{{ file with replacements + if (!file_exists($orig_file)) { + return $this->raiseError("file does not exist", + PEAR_INSTALLER_FAILED); + } + + $contents = file_get_contents($orig_file); + if ($contents === false) { + $contents = ''; + } + + if (isset($atts['md5sum'])) { + $md5sum = md5($contents); + } + + $subst_from = $subst_to = array(); + foreach ($atts['replacements'] as $a) { + $to = ''; + if ($a['type'] == 'php-const') { + if (preg_match('/^[a-z0-9_]+\\z/i', $a['to'])) { + eval("\$to = $a[to];"); + } else { + if (!isset($options['soft'])) { + $this->log(0, "invalid php-const replacement: $a[to]"); + } + continue; + } + } elseif ($a['type'] == 'pear-config') { + if ($a['to'] == 'master_server') { + $chan = $this->_registry->getChannel($channel); + if (!PEAR::isError($chan)) { + $to = $chan->getServer(); + } else { + $to = $this->config->get($a['to'], null, $channel); + } + } else { + $to = $this->config->get($a['to'], null, $channel); + } + if (is_null($to)) { + if (!isset($options['soft'])) { + $this->log(0, "invalid pear-config replacement: $a[to]"); + } + continue; + } + } elseif ($a['type'] == 'package-info') { + if ($t = $this->pkginfo->packageInfo($a['to'])) { + $to = $t; + } else { + if (!isset($options['soft'])) { + $this->log(0, "invalid package-info replacement: $a[to]"); + } + continue; + } + } + if (!is_null($to)) { + $subst_from[] = $a['from']; + $subst_to[] = $to; + } + } + + $this->log(3, "doing ".sizeof($subst_from)." substitution(s) for $final_dest_file"); + if (sizeof($subst_from)) { + $contents = str_replace($subst_from, $subst_to, $contents); + } + + $wp = @fopen($dest_file, "wb"); + if (!is_resource($wp)) { + return $this->raiseError("failed to create $dest_file: $php_errormsg", + PEAR_INSTALLER_FAILED); + } + + if (@fwrite($wp, $contents) === false) { + return $this->raiseError("failed writing to $dest_file: $php_errormsg", + PEAR_INSTALLER_FAILED); + } + + fclose($wp); + // }}} + } + + // {{{ check the md5 + if (isset($md5sum)) { + if (strtolower($md5sum) === strtolower($atts['md5sum'])) { + $this->log(2, "md5sum ok: $final_dest_file"); + } else { + if (empty($options['force'])) { + // delete the file + if (file_exists($dest_file)) { + unlink($dest_file); + } + + if (!isset($options['ignore-errors'])) { + return $this->raiseError("bad md5sum for file $final_dest_file", + PEAR_INSTALLER_FAILED); + } + + if (!isset($options['soft'])) { + $this->log(0, "warning : bad md5sum for file $final_dest_file"); + } + } else { + if (!isset($options['soft'])) { + $this->log(0, "warning : bad md5sum for file $final_dest_file"); + } + } + } + } + // }}} + // {{{ set file permissions + if (!OS_WINDOWS) { + if ($atts['role'] == 'script') { + $mode = 0777 & ~(int)octdec($this->config->get('umask')); + $this->log(3, "+ chmod +x $dest_file"); + } else { + $mode = 0666 & ~(int)octdec($this->config->get('umask')); + } + + if ($atts['role'] != 'src') { + $this->addFileOperation("chmod", array($mode, $dest_file)); + if (!@chmod($dest_file, $mode)) { + if (!isset($options['soft'])) { + $this->log(0, "failed to change mode of $dest_file: $php_errormsg"); + } + } + } + } + // }}} + + if ($atts['role'] == 'src') { + rename($dest_file, $final_dest_file); + $this->log(2, "renamed source file $dest_file to $final_dest_file"); + } else { + $this->addFileOperation("rename", array($dest_file, $final_dest_file, + $atts['role'] == 'ext')); + } + } + + // Store the full path where the file was installed for easy unistall + if ($atts['role'] != 'script') { + $loc = $this->config->get($atts['role'] . '_dir'); + } else { + $loc = $this->config->get('bin_dir'); + } + + if ($atts['role'] != 'src') { + $this->addFileOperation("installed_as", array($file, $installed_as, + $loc, + dirname(substr($installedas_dest_file, strlen($loc))))); + } + + //$this->log(2, "installed: $dest_file"); + return PEAR_INSTALLER_OK; + } + + // }}} + // {{{ _installFile2() + + /** + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * @param string filename + * @param array attributes from tag in package.xml + * @param string path to install the file in + * @param array options from command-line + * @access private + */ + function _installFile2(&$pkg, $file, &$real_atts, $tmp_path, $options) + { + $atts = $real_atts; + if (!isset($this->_registry)) { + $this->_registry = &$this->config->getRegistry(); + } + + $channel = $pkg->getChannel(); + // {{{ assemble the destination paths + if (!in_array($atts['attribs']['role'], + PEAR_Installer_Role::getValidRoles($pkg->getPackageType()))) { + return $this->raiseError('Invalid role `' . $atts['attribs']['role'] . + "' for file $file"); + } + + $role = &PEAR_Installer_Role::factory($pkg, $atts['attribs']['role'], $this->config); + $err = $role->setup($this, $pkg, $atts['attribs'], $file); + if (PEAR::isError($err)) { + return $err; + } + + if (!$role->isInstallable()) { + return; + } + + $info = $role->processInstallation($pkg, $atts['attribs'], $file, $tmp_path); + if (PEAR::isError($info)) { + return $info; + } + + list($save_destdir, $dest_dir, $dest_file, $orig_file) = $info; + if (preg_match('~/\.\.(/|\\z)|^\.\./~', str_replace('\\', '/', $dest_file))) { + return $this->raiseError("SECURITY ERROR: file $file (installed to $dest_file) contains parent directory reference ..", PEAR_INSTALLER_FAILED); + } + + $final_dest_file = $installed_as = $dest_file; + if (isset($this->_options['packagingroot'])) { + $final_dest_file = $this->_prependPath($final_dest_file, + $this->_options['packagingroot']); + } + + $dest_dir = dirname($final_dest_file); + $dest_file = $dest_dir . DIRECTORY_SEPARATOR . '.tmp' . basename($final_dest_file); + // }}} + + if (empty($this->_options['register-only'])) { + if (!file_exists($dest_dir) || !is_dir($dest_dir)) { + if (!$this->mkDirHier($dest_dir)) { + return $this->raiseError("failed to mkdir $dest_dir", + PEAR_INSTALLER_FAILED); + } + $this->log(3, "+ mkdir $dest_dir"); + } + } + + $attribs = $atts['attribs']; + unset($atts['attribs']); + // pretty much nothing happens if we are only registering the install + if (empty($this->_options['register-only'])) { + if (!count($atts)) { // no tasks + if (!file_exists($orig_file)) { + return $this->raiseError("file $orig_file does not exist", + PEAR_INSTALLER_FAILED); + } + + if (!@copy($orig_file, $dest_file)) { + return $this->raiseError("failed to write $dest_file: $php_errormsg", + PEAR_INSTALLER_FAILED); + } + + $this->log(3, "+ cp $orig_file $dest_file"); + if (isset($attribs['md5sum'])) { + $md5sum = md5_file($dest_file); + } + } else { // file with tasks + if (!file_exists($orig_file)) { + return $this->raiseError("file $orig_file does not exist", + PEAR_INSTALLER_FAILED); + } + + $contents = file_get_contents($orig_file); + if ($contents === false) { + $contents = ''; + } + + if (isset($attribs['md5sum'])) { + $md5sum = md5($contents); + } + + foreach ($atts as $tag => $raw) { + $tag = str_replace(array($pkg->getTasksNs() . ':', '-'), array('', '_'), $tag); + $task = "PEAR_Task_$tag"; + $task = new $task($this->config, $this, PEAR_TASK_INSTALL); + if (!$task->isScript()) { // scripts are only handled after installation + $task->init($raw, $attribs, $pkg->getLastInstalledVersion()); + $res = $task->startSession($pkg, $contents, $final_dest_file); + if ($res === false) { + continue; // skip this file + } + + if (PEAR::isError($res)) { + return $res; + } + + $contents = $res; // save changes + } + + $wp = @fopen($dest_file, "wb"); + if (!is_resource($wp)) { + return $this->raiseError("failed to create $dest_file: $php_errormsg", + PEAR_INSTALLER_FAILED); + } + + if (fwrite($wp, $contents) === false) { + return $this->raiseError("failed writing to $dest_file: $php_errormsg", + PEAR_INSTALLER_FAILED); + } + + fclose($wp); + } + } + + // {{{ check the md5 + if (isset($md5sum)) { + // Make sure the original md5 sum matches with expected + if (strtolower($md5sum) === strtolower($attribs['md5sum'])) { + $this->log(2, "md5sum ok: $final_dest_file"); + + if (isset($contents)) { + // set md5 sum based on $content in case any tasks were run. + $real_atts['attribs']['md5sum'] = md5($contents); + } + } else { + if (empty($options['force'])) { + // delete the file + if (file_exists($dest_file)) { + unlink($dest_file); + } + + if (!isset($options['ignore-errors'])) { + return $this->raiseError("bad md5sum for file $final_dest_file", + PEAR_INSTALLER_FAILED); + } + + if (!isset($options['soft'])) { + $this->log(0, "warning : bad md5sum for file $final_dest_file"); + } + } else { + if (!isset($options['soft'])) { + $this->log(0, "warning : bad md5sum for file $final_dest_file"); + } + } + } + } else { + $real_atts['attribs']['md5sum'] = md5_file($dest_file); + } + + // }}} + // {{{ set file permissions + if (!OS_WINDOWS) { + if ($role->isExecutable()) { + $mode = 0777 & ~(int)octdec($this->config->get('umask')); + $this->log(3, "+ chmod +x $dest_file"); + } else { + $mode = 0666 & ~(int)octdec($this->config->get('umask')); + } + + if ($attribs['role'] != 'src') { + $this->addFileOperation("chmod", array($mode, $dest_file)); + if (!@chmod($dest_file, $mode)) { + if (!isset($options['soft'])) { + $this->log(0, "failed to change mode of $dest_file: $php_errormsg"); + } + } + } + } + // }}} + + if ($attribs['role'] == 'src') { + rename($dest_file, $final_dest_file); + $this->log(2, "renamed source file $dest_file to $final_dest_file"); + } else { + $this->addFileOperation("rename", array($dest_file, $final_dest_file, $role->isExtension())); + } + } + + // Store the full path where the file was installed for easy uninstall + if ($attribs['role'] != 'src') { + $loc = $this->config->get($role->getLocationConfig(), null, $channel); + $this->addFileOperation('installed_as', array($file, $installed_as, + $loc, + dirname(substr($installed_as, strlen($loc))))); + } + + //$this->log(2, "installed: $dest_file"); + return PEAR_INSTALLER_OK; + } + + // }}} + // {{{ addFileOperation() + + /** + * Add a file operation to the current file transaction. + * + * @see startFileTransaction() + * @param string $type This can be one of: + * - rename: rename a file ($data has 3 values) + * - backup: backup an existing file ($data has 1 value) + * - removebackup: clean up backups created during install ($data has 1 value) + * - chmod: change permissions on a file ($data has 2 values) + * - delete: delete a file ($data has 1 value) + * - rmdir: delete a directory if empty ($data has 1 value) + * - installed_as: mark a file as installed ($data has 4 values). + * @param array $data For all file operations, this array must contain the + * full path to the file or directory that is being operated on. For + * the rename command, the first parameter must be the file to rename, + * the second its new name, the third whether this is a PHP extension. + * + * The installed_as operation contains 4 elements in this order: + * 1. Filename as listed in the filelist element from package.xml + * 2. Full path to the installed file + * 3. Full path from the php_dir configuration variable used in this + * installation + * 4. Relative path from the php_dir that this file is installed in + */ + function addFileOperation($type, $data) + { + if (!is_array($data)) { + return $this->raiseError('Internal Error: $data in addFileOperation' + . ' must be an array, was ' . gettype($data)); + } + + if ($type == 'chmod') { + $octmode = decoct($data[0]); + $this->log(3, "adding to transaction: $type $octmode $data[1]"); + } else { + $this->log(3, "adding to transaction: $type " . implode(" ", $data)); + } + $this->file_operations[] = array($type, $data); + } + + // }}} + // {{{ startFileTransaction() + + function startFileTransaction($rollback_in_case = false) + { + if (count($this->file_operations) && $rollback_in_case) { + $this->rollbackFileTransaction(); + } + $this->file_operations = array(); + } + + // }}} + // {{{ commitFileTransaction() + + function commitFileTransaction() + { + // {{{ first, check permissions and such manually + $errors = array(); + foreach ($this->file_operations as $key => $tr) { + list($type, $data) = $tr; + switch ($type) { + case 'rename': + if (!file_exists($data[0])) { + $errors[] = "cannot rename file $data[0], doesn't exist"; + } + + // check that dest dir. is writable + if (!is_writable(dirname($data[1]))) { + $errors[] = "permission denied ($type): $data[1]"; + } + break; + case 'chmod': + // check that file is writable + if (!is_writable($data[1])) { + $errors[] = "permission denied ($type): $data[1] " . decoct($data[0]); + } + break; + case 'delete': + if (!file_exists($data[0])) { + $this->log(2, "warning: file $data[0] doesn't exist, can't be deleted"); + } + // check that directory is writable + if (file_exists($data[0])) { + if (!is_writable(dirname($data[0]))) { + $errors[] = "permission denied ($type): $data[0]"; + } else { + // make sure the file to be deleted can be opened for writing + $fp = false; + if (!is_dir($data[0]) && + (!is_writable($data[0]) || !($fp = @fopen($data[0], 'a')))) { + $errors[] = "permission denied ($type): $data[0]"; + } elseif ($fp) { + fclose($fp); + } + } + + /* Verify we are not deleting a file owned by another package + * This can happen when a file moves from package A to B in + * an upgrade ala http://pear.php.net/17986 + */ + $info = array( + 'package' => strtolower($this->pkginfo->getName()), + 'channel' => strtolower($this->pkginfo->getChannel()), + ); + $result = $this->_registry->checkFileMap($data[0], $info, '1.1'); + if (is_array($result)) { + $res = array_diff($result, $info); + if (!empty($res)) { + $new = $this->_registry->getPackage($result[1], $result[0]); + $this->file_operations[$key] = false; + $pkginfoName = $this->pkginfo->getName(); + $newChannel = $new->getChannel(); + $newPackage = $new->getName(); + $this->log(3, "file $data[0] was scheduled for removal from $pkginfoName but is owned by $newChannel/$newPackage, removal has been cancelled."); + } + } + } + break; + } + + } + // }}} + + $n = count($this->file_operations); + $this->log(2, "about to commit $n file operations for " . $this->pkginfo->getName()); + + $m = count($errors); + if ($m > 0) { + foreach ($errors as $error) { + if (!isset($this->_options['soft'])) { + $this->log(1, $error); + } + } + + if (!isset($this->_options['ignore-errors'])) { + return false; + } + } + + $this->_dirtree = array(); + // {{{ really commit the transaction + foreach ($this->file_operations as $i => $tr) { + if (!$tr) { + // support removal of non-existing backups + continue; + } + + list($type, $data) = $tr; + switch ($type) { + case 'backup': + if (!file_exists($data[0])) { + $this->file_operations[$i] = false; + break; + } + + if (!@copy($data[0], $data[0] . '.bak')) { + $this->log(1, 'Could not copy ' . $data[0] . ' to ' . $data[0] . + '.bak ' . $php_errormsg); + return false; + } + $this->log(3, "+ backup $data[0] to $data[0].bak"); + break; + case 'removebackup': + if (file_exists($data[0] . '.bak') && is_writable($data[0] . '.bak')) { + unlink($data[0] . '.bak'); + $this->log(3, "+ rm backup of $data[0] ($data[0].bak)"); + } + break; + case 'rename': + $test = file_exists($data[1]) ? @unlink($data[1]) : null; + if (!$test && file_exists($data[1])) { + if ($data[2]) { + $extra = ', this extension must be installed manually. Rename to "' . + basename($data[1]) . '"'; + } else { + $extra = ''; + } + + if (!isset($this->_options['soft'])) { + $this->log(1, 'Could not delete ' . $data[1] . ', cannot rename ' . + $data[0] . $extra); + } + + if (!isset($this->_options['ignore-errors'])) { + return false; + } + } + + // permissions issues with rename - copy() is far superior + $perms = @fileperms($data[0]); + if (!@copy($data[0], $data[1])) { + $this->log(1, 'Could not rename ' . $data[0] . ' to ' . $data[1] . + ' ' . $php_errormsg); + return false; + } + + // copy over permissions, otherwise they are lost + @chmod($data[1], $perms); + @unlink($data[0]); + $this->log(3, "+ mv $data[0] $data[1]"); + break; + case 'chmod': + if (!@chmod($data[1], $data[0])) { + $this->log(1, 'Could not chmod ' . $data[1] . ' to ' . + decoct($data[0]) . ' ' . $php_errormsg); + return false; + } + + $octmode = decoct($data[0]); + $this->log(3, "+ chmod $octmode $data[1]"); + break; + case 'delete': + if (file_exists($data[0])) { + if (!@unlink($data[0])) { + $this->log(1, 'Could not delete ' . $data[0] . ' ' . + $php_errormsg); + return false; + } + $this->log(3, "+ rm $data[0]"); + } + break; + case 'rmdir': + if (file_exists($data[0])) { + do { + $testme = opendir($data[0]); + while (false !== ($entry = readdir($testme))) { + if ($entry == '.' || $entry == '..') { + continue; + } + closedir($testme); + break 2; // this directory is not empty and can't be + // deleted + } + + closedir($testme); + if (!@rmdir($data[0])) { + $this->log(1, 'Could not rmdir ' . $data[0] . ' ' . + $php_errormsg); + return false; + } + $this->log(3, "+ rmdir $data[0]"); + } while (false); + } + break; + case 'installed_as': + $this->pkginfo->setInstalledAs($data[0], $data[1]); + if (!isset($this->_dirtree[dirname($data[1])])) { + $this->_dirtree[dirname($data[1])] = true; + $this->pkginfo->setDirtree(dirname($data[1])); + + while(!empty($data[3]) && dirname($data[3]) != $data[3] && + $data[3] != '/' && $data[3] != '\\') { + $this->pkginfo->setDirtree($pp = + $this->_prependPath($data[3], $data[2])); + $this->_dirtree[$pp] = true; + $data[3] = dirname($data[3]); + } + } + break; + } + } + // }}} + $this->log(2, "successfully committed $n file operations"); + $this->file_operations = array(); + return true; + } + + // }}} + // {{{ rollbackFileTransaction() + + function rollbackFileTransaction() + { + $n = count($this->file_operations); + $this->log(2, "rolling back $n file operations"); + foreach ($this->file_operations as $tr) { + list($type, $data) = $tr; + switch ($type) { + case 'backup': + if (file_exists($data[0] . '.bak')) { + if (file_exists($data[0] && is_writable($data[0]))) { + unlink($data[0]); + } + @copy($data[0] . '.bak', $data[0]); + $this->log(3, "+ restore $data[0] from $data[0].bak"); + } + break; + case 'removebackup': + if (file_exists($data[0] . '.bak') && is_writable($data[0] . '.bak')) { + unlink($data[0] . '.bak'); + $this->log(3, "+ rm backup of $data[0] ($data[0].bak)"); + } + break; + case 'rename': + @unlink($data[0]); + $this->log(3, "+ rm $data[0]"); + break; + case 'mkdir': + @rmdir($data[0]); + $this->log(3, "+ rmdir $data[0]"); + break; + case 'chmod': + break; + case 'delete': + break; + case 'installed_as': + $this->pkginfo->setInstalledAs($data[0], false); + break; + } + } + $this->pkginfo->resetDirtree(); + $this->file_operations = array(); + } + + // }}} + // {{{ mkDirHier($dir) + + function mkDirHier($dir) + { + $this->addFileOperation('mkdir', array($dir)); + return parent::mkDirHier($dir); + } + + // }}} + // {{{ _parsePackageXml() + + function _parsePackageXml(&$descfile) + { + // Parse xml file ----------------------------------------------- + $pkg = new PEAR_PackageFile($this->config, $this->debug); + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $p = &$pkg->fromAnyFile($descfile, PEAR_VALIDATE_INSTALLING); + PEAR::staticPopErrorHandling(); + if (PEAR::isError($p)) { + if (is_array($p->getUserInfo())) { + foreach ($p->getUserInfo() as $err) { + $loglevel = $err['level'] == 'error' ? 0 : 1; + if (!isset($this->_options['soft'])) { + $this->log($loglevel, ucfirst($err['level']) . ': ' . $err['message']); + } + } + } + return $this->raiseError('Installation failed: invalid package file'); + } + + $descfile = $p->getPackageFile(); + return $p; + } + + // }}} + /** + * Set the list of PEAR_Downloader_Package objects to allow more sane + * dependency validation + * @param array + */ + function setDownloadedPackages(&$pkgs) + { + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $err = $this->analyzeDependencies($pkgs); + PEAR::popErrorHandling(); + if (PEAR::isError($err)) { + return $err; + } + $this->_downloadedPackages = &$pkgs; + } + + /** + * Set the list of PEAR_Downloader_Package objects to allow more sane + * dependency validation + * @param array + */ + function setUninstallPackages(&$pkgs) + { + $this->_downloadedPackages = &$pkgs; + } + + function getInstallPackages() + { + return $this->_downloadedPackages; + } + + // {{{ install() + + /** + * Installs the files within the package file specified. + * + * @param string|PEAR_Downloader_Package $pkgfile path to the package file, + * or a pre-initialized packagefile object + * @param array $options + * recognized options: + * - installroot : optional prefix directory for installation + * - force : force installation + * - register-only : update registry but don't install files + * - upgrade : upgrade existing install + * - soft : fail silently + * - nodeps : ignore dependency conflicts/missing dependencies + * - alldeps : install all dependencies + * - onlyreqdeps : install only required dependencies + * + * @return array|PEAR_Error package info if successful + */ + function install($pkgfile, $options = array()) + { + $this->_options = $options; + $this->_registry = &$this->config->getRegistry(); + if (is_object($pkgfile)) { + $dlpkg = &$pkgfile; + $pkg = $pkgfile->getPackageFile(); + $pkgfile = $pkg->getArchiveFile(); + $descfile = $pkg->getPackageFile(); + } else { + $descfile = $pkgfile; + $pkg = $this->_parsePackageXml($descfile); + if (PEAR::isError($pkg)) { + return $pkg; + } + } + + $tmpdir = dirname($descfile); + if (realpath($descfile) != realpath($pkgfile)) { + // Use the temp_dir since $descfile can contain the download dir path + $tmpdir = $this->config->get('temp_dir', null, 'pear.php.net'); + $tmpdir = System::mktemp('-d -t "' . $tmpdir . '"'); + + $tar = new Archive_Tar($pkgfile); + if (!$tar->extract($tmpdir)) { + return $this->raiseError("unable to unpack $pkgfile"); + } + } + + $pkgname = $pkg->getName(); + $channel = $pkg->getChannel(); + + if (isset($options['installroot'])) { + $this->config->setInstallRoot($options['installroot']); + $this->_registry = &$this->config->getRegistry(); + $installregistry = &$this->_registry; + $this->installroot = ''; // all done automagically now + $php_dir = $this->config->get('php_dir', null, $channel); + } else { + $this->config->setInstallRoot(false); + $this->_registry = &$this->config->getRegistry(); + if (isset($this->_options['packagingroot'])) { + $regdir = $this->_prependPath( + $this->config->get('php_dir', null, 'pear.php.net'), + $this->_options['packagingroot']); + + $metadata_dir = $this->config->get('metadata_dir', null, 'pear.php.net'); + if ($metadata_dir) { + $metadata_dir = $this->_prependPath( + $metadata_dir, + $this->_options['packagingroot']); + } + $packrootphp_dir = $this->_prependPath( + $this->config->get('php_dir', null, $channel), + $this->_options['packagingroot']); + + $installregistry = new PEAR_Registry($regdir, false, false, $metadata_dir); + if (!$installregistry->channelExists($channel, true)) { + // we need to fake a channel-discover of this channel + $chanobj = $this->_registry->getChannel($channel, true); + $installregistry->addChannel($chanobj); + } + $php_dir = $packrootphp_dir; + } else { + $installregistry = &$this->_registry; + $php_dir = $this->config->get('php_dir', null, $channel); + } + $this->installroot = ''; + } + + // {{{ checks to do when not in "force" mode + if (empty($options['force']) && + (file_exists($this->config->get('php_dir')) && + is_dir($this->config->get('php_dir')))) { + $testp = $channel == 'pear.php.net' ? $pkgname : array($channel, $pkgname); + $instfilelist = $pkg->getInstallationFileList(true); + if (PEAR::isError($instfilelist)) { + return $instfilelist; + } + + // ensure we have the most accurate registry + $installregistry->flushFileMap(); + $test = $installregistry->checkFileMap($instfilelist, $testp, '1.1'); + if (PEAR::isError($test)) { + return $test; + } + + if (sizeof($test)) { + $pkgs = $this->getInstallPackages(); + $found = false; + foreach ($pkgs as $param) { + if ($pkg->isSubpackageOf($param)) { + $found = true; + break; + } + } + + if ($found) { + // subpackages can conflict with earlier versions of parent packages + $parentreg = $installregistry->packageInfo($param->getPackage(), null, $param->getChannel()); + $tmp = $test; + foreach ($tmp as $file => $info) { + if (is_array($info)) { + if (strtolower($info[1]) == strtolower($param->getPackage()) && + strtolower($info[0]) == strtolower($param->getChannel()) + ) { + if (isset($parentreg['filelist'][$file])) { + unset($parentreg['filelist'][$file]); + } else{ + $pos = strpos($file, '/'); + $basedir = substr($file, 0, $pos); + $file2 = substr($file, $pos + 1); + if (isset($parentreg['filelist'][$file2]['baseinstalldir']) + && $parentreg['filelist'][$file2]['baseinstalldir'] === $basedir + ) { + unset($parentreg['filelist'][$file2]); + } + } + + unset($test[$file]); + } + } else { + if (strtolower($param->getChannel()) != 'pear.php.net') { + continue; + } + + if (strtolower($info) == strtolower($param->getPackage())) { + if (isset($parentreg['filelist'][$file])) { + unset($parentreg['filelist'][$file]); + } else{ + $pos = strpos($file, '/'); + $basedir = substr($file, 0, $pos); + $file2 = substr($file, $pos + 1); + if (isset($parentreg['filelist'][$file2]['baseinstalldir']) + && $parentreg['filelist'][$file2]['baseinstalldir'] === $basedir + ) { + unset($parentreg['filelist'][$file2]); + } + } + + unset($test[$file]); + } + } + } + + $pfk = new PEAR_PackageFile($this->config); + $parentpkg = &$pfk->fromArray($parentreg); + $installregistry->updatePackage2($parentpkg); + } + + if ($param->getChannel() == 'pecl.php.net' && isset($options['upgrade'])) { + $tmp = $test; + foreach ($tmp as $file => $info) { + if (is_string($info)) { + // pear.php.net packages are always stored as strings + if (strtolower($info) == strtolower($param->getPackage())) { + // upgrading existing package + unset($test[$file]); + } + } + } + } + + if (count($test)) { + $msg = "$channel/$pkgname: conflicting files found:\n"; + $longest = max(array_map("strlen", array_keys($test))); + $fmt = "%${longest}s (%s)\n"; + foreach ($test as $file => $info) { + if (!is_array($info)) { + $info = array('pear.php.net', $info); + } + $info = $info[0] . '/' . $info[1]; + $msg .= sprintf($fmt, $file, $info); + } + + if (!isset($options['ignore-errors'])) { + return $this->raiseError($msg); + } + + if (!isset($options['soft'])) { + $this->log(0, "WARNING: $msg"); + } + } + } + } + // }}} + + $this->startFileTransaction(); + + $usechannel = $channel; + if ($channel == 'pecl.php.net') { + $test = $installregistry->packageExists($pkgname, $channel); + if (!$test) { + $test = $installregistry->packageExists($pkgname, 'pear.php.net'); + $usechannel = 'pear.php.net'; + } + } else { + $test = $installregistry->packageExists($pkgname, $channel); + } + + if (empty($options['upgrade']) && empty($options['soft'])) { + // checks to do only when installing new packages + if (empty($options['force']) && $test) { + return $this->raiseError("$channel/$pkgname is already installed"); + } + } else { + // Upgrade + if ($test) { + $v1 = $installregistry->packageInfo($pkgname, 'version', $usechannel); + $v2 = $pkg->getVersion(); + $cmp = version_compare("$v1", "$v2", 'gt'); + if (empty($options['force']) && !version_compare("$v2", "$v1", 'gt')) { + return $this->raiseError("upgrade to a newer version ($v2 is not newer than $v1)"); + } + } + } + + // Do cleanups for upgrade and install, remove old release's files first + if ($test && empty($options['register-only'])) { + // when upgrading, remove old release's files first: + if (PEAR::isError($err = $this->_deletePackageFiles($pkgname, $usechannel, + true))) { + if (!isset($options['ignore-errors'])) { + return $this->raiseError($err); + } + + if (!isset($options['soft'])) { + $this->log(0, 'WARNING: ' . $err->getMessage()); + } + } else { + $backedup = $err; + } + } + + // {{{ Copy files to dest dir --------------------------------------- + + // info from the package it self we want to access from _installFile + $this->pkginfo = &$pkg; + // used to determine whether we should build any C code + $this->source_files = 0; + + $savechannel = $this->config->get('default_channel'); + if (empty($options['register-only']) && !is_dir($php_dir)) { + if (PEAR::isError(System::mkdir(array('-p'), $php_dir))) { + return $this->raiseError("no installation destination directory '$php_dir'\n"); + } + } + + if (substr($pkgfile, -4) != '.xml') { + $tmpdir .= DIRECTORY_SEPARATOR . $pkgname . '-' . $pkg->getVersion(); + } + + $this->configSet('default_channel', $channel); + // {{{ install files + + $ver = $pkg->getPackagexmlVersion(); + if (version_compare($ver, '2.0', '>=')) { + $filelist = $pkg->getInstallationFilelist(); + } else { + $filelist = $pkg->getFileList(); + } + + if (PEAR::isError($filelist)) { + return $filelist; + } + + $p = &$installregistry->getPackage($pkgname, $channel); + $dirtree = (empty($options['register-only']) && $p) ? $p->getDirTree() : false; + + $pkg->resetFilelist(); + $pkg->setLastInstalledVersion($installregistry->packageInfo($pkg->getPackage(), + 'version', $pkg->getChannel())); + foreach ($filelist as $file => $atts) { + $this->expectError(PEAR_INSTALLER_FAILED); + if ($pkg->getPackagexmlVersion() == '1.0') { + $res = $this->_installFile($file, $atts, $tmpdir, $options); + } else { + $res = $this->_installFile2($pkg, $file, $atts, $tmpdir, $options); + } + $this->popExpect(); + + if (PEAR::isError($res)) { + if (empty($options['ignore-errors'])) { + $this->rollbackFileTransaction(); + if ($res->getMessage() == "file does not exist") { + $this->raiseError("file $file in package.xml does not exist"); + } + + return $this->raiseError($res); + } + + if (!isset($options['soft'])) { + $this->log(0, "Warning: " . $res->getMessage()); + } + } + + $real = isset($atts['attribs']) ? $atts['attribs'] : $atts; + if ($res == PEAR_INSTALLER_OK && $real['role'] != 'src') { + // Register files that were installed + $pkg->installedFile($file, $atts); + } + } + // }}} + + // {{{ compile and install source files + if ($this->source_files > 0 && empty($options['nobuild'])) { + if (PEAR::isError($err = + $this->_compileSourceFiles($savechannel, $pkg))) { + return $err; + } + } + // }}} + + if (isset($backedup)) { + $this->_removeBackups($backedup); + } + + if (!$this->commitFileTransaction()) { + $this->rollbackFileTransaction(); + $this->configSet('default_channel', $savechannel); + return $this->raiseError("commit failed", PEAR_INSTALLER_FAILED); + } + // }}} + + $ret = false; + $installphase = 'install'; + $oldversion = false; + // {{{ Register that the package is installed ----------------------- + if (empty($options['upgrade'])) { + // if 'force' is used, replace the info in registry + $usechannel = $channel; + if ($channel == 'pecl.php.net') { + $test = $installregistry->packageExists($pkgname, $channel); + if (!$test) { + $test = $installregistry->packageExists($pkgname, 'pear.php.net'); + $usechannel = 'pear.php.net'; + } + } else { + $test = $installregistry->packageExists($pkgname, $channel); + } + + if (!empty($options['force']) && $test) { + $oldversion = $installregistry->packageInfo($pkgname, 'version', $usechannel); + $installregistry->deletePackage($pkgname, $usechannel); + } + $ret = $installregistry->addPackage2($pkg); + } else { + if ($dirtree) { + $this->startFileTransaction(); + // attempt to delete empty directories + uksort($dirtree, array($this, '_sortDirs')); + foreach($dirtree as $dir => $notused) { + $this->addFileOperation('rmdir', array($dir)); + } + $this->commitFileTransaction(); + } + + $usechannel = $channel; + if ($channel == 'pecl.php.net') { + $test = $installregistry->packageExists($pkgname, $channel); + if (!$test) { + $test = $installregistry->packageExists($pkgname, 'pear.php.net'); + $usechannel = 'pear.php.net'; + } + } else { + $test = $installregistry->packageExists($pkgname, $channel); + } + + // new: upgrade installs a package if it isn't installed + if (!$test) { + $ret = $installregistry->addPackage2($pkg); + } else { + if ($usechannel != $channel) { + $installregistry->deletePackage($pkgname, $usechannel); + $ret = $installregistry->addPackage2($pkg); + } else { + $ret = $installregistry->updatePackage2($pkg); + } + $installphase = 'upgrade'; + } + } + + if (!$ret) { + $this->configSet('default_channel', $savechannel); + return $this->raiseError("Adding package $channel/$pkgname to registry failed"); + } + // }}} + + $this->configSet('default_channel', $savechannel); + if (class_exists('PEAR_Task_Common')) { // this is auto-included if any tasks exist + if (PEAR_Task_Common::hasPostinstallTasks()) { + PEAR_Task_Common::runPostinstallTasks($installphase); + } + } + + return $pkg->toArray(true); + } + + // }}} + + // {{{ _compileSourceFiles() + /** + * @param string + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 + */ + function _compileSourceFiles($savechannel, &$filelist) + { + require_once 'PEAR/Builder.php'; + $this->log(1, "$this->source_files source files, building"); + $bob = new PEAR_Builder($this->ui); + $bob->debug = $this->debug; + $built = $bob->build($filelist, array(&$this, '_buildCallback')); + if (PEAR::isError($built)) { + $this->rollbackFileTransaction(); + $this->configSet('default_channel', $savechannel); + return $built; + } + + $this->log(1, "\nBuild process completed successfully"); + foreach ($built as $ext) { + $bn = basename($ext['file']); + list($_ext_name, $_ext_suff) = explode('.', $bn); + if ($_ext_suff == '.so' || $_ext_suff == '.dll') { + if (extension_loaded($_ext_name)) { + $this->raiseError("Extension '$_ext_name' already loaded. " . + 'Please unload it in your php.ini file ' . + 'prior to install or upgrade'); + } + $role = 'ext'; + } else { + $role = 'src'; + } + + $dest = $ext['dest']; + $packagingroot = ''; + if (isset($this->_options['packagingroot'])) { + $packagingroot = $this->_options['packagingroot']; + } + + $copyto = $this->_prependPath($dest, $packagingroot); + $extra = $copyto != $dest ? " as '$copyto'" : ''; + $this->log(1, "Installing '$dest'$extra"); + + $copydir = dirname($copyto); + // pretty much nothing happens if we are only registering the install + if (empty($this->_options['register-only'])) { + if (!file_exists($copydir) || !is_dir($copydir)) { + if (!$this->mkDirHier($copydir)) { + return $this->raiseError("failed to mkdir $copydir", + PEAR_INSTALLER_FAILED); + } + + $this->log(3, "+ mkdir $copydir"); + } + + if (!@copy($ext['file'], $copyto)) { + return $this->raiseError("failed to write $copyto ($php_errormsg)", PEAR_INSTALLER_FAILED); + } + + $this->log(3, "+ cp $ext[file] $copyto"); + $this->addFileOperation('rename', array($ext['file'], $copyto)); + if (!OS_WINDOWS) { + $mode = 0666 & ~(int)octdec($this->config->get('umask')); + $this->addFileOperation('chmod', array($mode, $copyto)); + if (!@chmod($copyto, $mode)) { + $this->log(0, "failed to change mode of $copyto ($php_errormsg)"); + } + } + } + + + $data = array( + 'role' => $role, + 'name' => $bn, + 'installed_as' => $dest, + 'php_api' => $ext['php_api'], + 'zend_mod_api' => $ext['zend_mod_api'], + 'zend_ext_api' => $ext['zend_ext_api'], + ); + + if ($filelist->getPackageXmlVersion() == '1.0') { + $filelist->installedFile($bn, $data); + } else { + $filelist->installedFile($bn, array('attribs' => $data)); + } + } + } + + // }}} + function &getUninstallPackages() + { + return $this->_downloadedPackages; + } + // {{{ uninstall() + + /** + * Uninstall a package + * + * This method removes all files installed by the application, and then + * removes any empty directories. + * @param string package name + * @param array Command-line options. Possibilities include: + * + * - installroot: base installation dir, if not the default + * - register-only : update registry but don't remove files + * - nodeps: do not process dependencies of other packages to ensure + * uninstallation does not break things + */ + function uninstall($package, $options = array()) + { + $installRoot = isset($options['installroot']) ? $options['installroot'] : ''; + $this->config->setInstallRoot($installRoot); + + $this->installroot = ''; + $this->_registry = &$this->config->getRegistry(); + if (is_object($package)) { + $channel = $package->getChannel(); + $pkg = $package; + $package = $pkg->getPackage(); + } else { + $pkg = false; + $info = $this->_registry->parsePackageName($package, + $this->config->get('default_channel')); + $channel = $info['channel']; + $package = $info['package']; + } + + $savechannel = $this->config->get('default_channel'); + $this->configSet('default_channel', $channel); + if (!is_object($pkg)) { + $pkg = $this->_registry->getPackage($package, $channel); + } + + if (!$pkg) { + $this->configSet('default_channel', $savechannel); + return $this->raiseError($this->_registry->parsedPackageNameToString( + array( + 'channel' => $channel, + 'package' => $package + ), true) . ' not installed'); + } + + if ($pkg->getInstalledBinary()) { + // this is just an alias for a binary package + return $this->_registry->deletePackage($package, $channel); + } + + $filelist = $pkg->getFilelist(); + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + if (!class_exists('PEAR_Dependency2')) { + require_once 'PEAR/Dependency2.php'; + } + + $depchecker = new PEAR_Dependency2($this->config, $options, + array('channel' => $channel, 'package' => $package), + PEAR_VALIDATE_UNINSTALLING); + $e = $depchecker->validatePackageUninstall($this); + PEAR::staticPopErrorHandling(); + if (PEAR::isError($e)) { + if (!isset($options['ignore-errors'])) { + return $this->raiseError($e); + } + + if (!isset($options['soft'])) { + $this->log(0, 'WARNING: ' . $e->getMessage()); + } + } elseif (is_array($e)) { + if (!isset($options['soft'])) { + $this->log(0, $e[0]); + } + } + + $this->pkginfo = &$pkg; + // pretty much nothing happens if we are only registering the uninstall + if (empty($options['register-only'])) { + // {{{ Delete the files + $this->startFileTransaction(); + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + if (PEAR::isError($err = $this->_deletePackageFiles($package, $channel))) { + PEAR::popErrorHandling(); + $this->rollbackFileTransaction(); + $this->configSet('default_channel', $savechannel); + if (!isset($options['ignore-errors'])) { + return $this->raiseError($err); + } + + if (!isset($options['soft'])) { + $this->log(0, 'WARNING: ' . $err->getMessage()); + } + } else { + PEAR::popErrorHandling(); + } + + if (!$this->commitFileTransaction()) { + $this->rollbackFileTransaction(); + if (!isset($options['ignore-errors'])) { + return $this->raiseError("uninstall failed"); + } + + if (!isset($options['soft'])) { + $this->log(0, 'WARNING: uninstall failed'); + } + } else { + $this->startFileTransaction(); + $dirtree = $pkg->getDirTree(); + if ($dirtree === false) { + $this->configSet('default_channel', $savechannel); + return $this->_registry->deletePackage($package, $channel); + } + + // attempt to delete empty directories + uksort($dirtree, array($this, '_sortDirs')); + foreach($dirtree as $dir => $notused) { + $this->addFileOperation('rmdir', array($dir)); + } + + if (!$this->commitFileTransaction()) { + $this->rollbackFileTransaction(); + if (!isset($options['ignore-errors'])) { + return $this->raiseError("uninstall failed"); + } + + if (!isset($options['soft'])) { + $this->log(0, 'WARNING: uninstall failed'); + } + } + } + // }}} + } + + $this->configSet('default_channel', $savechannel); + // Register that the package is no longer installed + return $this->_registry->deletePackage($package, $channel); + } + + /** + * Sort a list of arrays of array(downloaded packagefilename) by dependency. + * + * It also removes duplicate dependencies + * @param array an array of PEAR_PackageFile_v[1/2] objects + * @return array|PEAR_Error array of array(packagefilename, package.xml contents) + */ + function sortPackagesForUninstall(&$packages) + { + $this->_dependencyDB = &PEAR_DependencyDB::singleton($this->config); + if (PEAR::isError($this->_dependencyDB)) { + return $this->_dependencyDB; + } + usort($packages, array(&$this, '_sortUninstall')); + } + + function _sortUninstall($a, $b) + { + if (!$a->getDeps() && !$b->getDeps()) { + return 0; // neither package has dependencies, order is insignificant + } + if ($a->getDeps() && !$b->getDeps()) { + return -1; // $a must be installed after $b because $a has dependencies + } + if (!$a->getDeps() && $b->getDeps()) { + return 1; // $b must be installed after $a because $b has dependencies + } + // both packages have dependencies + if ($this->_dependencyDB->dependsOn($a, $b)) { + return -1; + } + if ($this->_dependencyDB->dependsOn($b, $a)) { + return 1; + } + return 0; + } + + // }}} + // {{{ _sortDirs() + function _sortDirs($a, $b) + { + if (strnatcmp($a, $b) == -1) return 1; + if (strnatcmp($a, $b) == 1) return -1; + return 0; + } + + // }}} + + // {{{ _buildCallback() + + function _buildCallback($what, $data) + { + if (($what == 'cmdoutput' && $this->debug > 1) || + ($what == 'output' && $this->debug > 0)) { + $this->ui->outputData(rtrim($data), 'build'); + } + } + + // }}} +} diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Installer/Role.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Installer/Role.php new file mode 100644 index 0000000..0623424 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Installer/Role.php @@ -0,0 +1,266 @@ + + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * base class for installer roles + */ +require_once 'PEAR/Installer/Role/Common.php'; +require_once 'PEAR/XMLParser.php'; +/** + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Installer_Role +{ + /** + * Set up any additional configuration variables that file roles require + * + * Never call this directly, it is called by the PEAR_Config constructor + * @param PEAR_Config + */ + public static function initializeConfig(&$config) + { + if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) { + PEAR_Installer_Role::registerRoles(); + } + + foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $class => $info) { + if (!$info['config_vars']) { + continue; + } + + $config->_addConfigVars($class, $info['config_vars']); + } + } + + /** + * @param PEAR_PackageFile_v2 + * @param string role name + * @param PEAR_Config + * @return PEAR_Installer_Role_Common + */ + public static function &factory($pkg, $role, &$config) + { + if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) { + PEAR_Installer_Role::registerRoles(); + } + + if (!in_array($role, PEAR_Installer_Role::getValidRoles($pkg->getPackageType()))) { + $a = false; + return $a; + } + + $a = 'PEAR_Installer_Role_' . ucfirst($role); + if (!class_exists($a)) { + require_once str_replace('_', '/', $a) . '.php'; + } + + $b = new $a($config); + return $b; + } + + /** + * Get a list of file roles that are valid for the particular release type. + * + * For instance, src files serve no purpose in regular php releases. + * @param string + * @param bool clear cache + * @return array + */ + public static function getValidRoles($release, $clear = false) + { + if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) { + PEAR_Installer_Role::registerRoles(); + } + + static $ret = array(); + if ($clear) { + $ret = array(); + } + + if (isset($ret[$release])) { + return $ret[$release]; + } + + $ret[$release] = array(); + foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) { + if (in_array($release, $okreleases['releasetypes'])) { + $ret[$release][] = strtolower(str_replace('PEAR_Installer_Role_', '', $role)); + } + } + + return $ret[$release]; + } + + /** + * Get a list of roles that require their files to be installed + * + * Most roles must be installed, but src and package roles, for instance + * are pseudo-roles. src files are compiled into a new extension. Package + * roles are actually fully bundled releases of a package + * @param bool clear cache + * @return array + */ + public static function getInstallableRoles($clear = false) + { + if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) { + PEAR_Installer_Role::registerRoles(); + } + + static $ret; + if ($clear) { + unset($ret); + } + + if (isset($ret)) { + return $ret; + } + + $ret = array(); + foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) { + if ($okreleases['installable']) { + $ret[] = strtolower(str_replace('PEAR_Installer_Role_', '', $role)); + } + } + + return $ret; + } + + /** + * Return an array of roles that are affected by the baseinstalldir attribute + * + * Most roles ignore this attribute, and instead install directly into: + * PackageName/filepath + * so a tests file tests/file.phpt is installed into PackageName/tests/filepath.php + * @param bool clear cache + * @return array + */ + public static function getBaseinstallRoles($clear = false) + { + if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) { + PEAR_Installer_Role::registerRoles(); + } + + static $ret; + if ($clear) { + unset($ret); + } + + if (isset($ret)) { + return $ret; + } + + $ret = array(); + foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) { + if ($okreleases['honorsbaseinstall']) { + $ret[] = strtolower(str_replace('PEAR_Installer_Role_', '', $role)); + } + } + + return $ret; + } + + /** + * Return an array of file roles that should be analyzed for PHP content at package time, + * like the "php" role. + * @param bool clear cache + * @return array + */ + public static function getPhpRoles($clear = false) + { + if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) { + PEAR_Installer_Role::registerRoles(); + } + + static $ret; + if ($clear) { + unset($ret); + } + + if (isset($ret)) { + return $ret; + } + + $ret = array(); + foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) { + if ($okreleases['phpfile']) { + $ret[] = strtolower(str_replace('PEAR_Installer_Role_', '', $role)); + } + } + + return $ret; + } + + /** + * Scan through the Command directory looking for classes + * and see what commands they implement. + * @param string which directory to look for classes, defaults to + * the Installer/Roles subdirectory of + * the directory from where this file (__FILE__) is + * included. + * + * @return bool TRUE on success, a PEAR error on failure + */ + public static function registerRoles($dir = null) + { + $GLOBALS['_PEAR_INSTALLER_ROLES'] = array(); + $parser = new PEAR_XMLParser; + if ($dir === null) { + $dir = dirname(__FILE__) . '/Role'; + } + + if (!file_exists($dir) || !is_dir($dir)) { + return PEAR::raiseError("registerRoles: opendir($dir) failed: does not exist/is not directory"); + } + + $dp = @opendir($dir); + if (empty($dp)) { + return PEAR::raiseError("registerRoles: opendir($dir) failed: $php_errmsg"); + } + + while ($entry = readdir($dp)) { + if ($entry{0} == '.' || substr($entry, -4) != '.xml') { + continue; + } + + $class = "PEAR_Installer_Role_".substr($entry, 0, -4); + // List of roles + if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'][$class])) { + $file = "$dir/$entry"; + $parser->parse(file_get_contents($file)); + $data = $parser->getData(); + if (!is_array($data['releasetypes'])) { + $data['releasetypes'] = array($data['releasetypes']); + } + + $GLOBALS['_PEAR_INSTALLER_ROLES'][$class] = $data; + } + } + + closedir($dp); + ksort($GLOBALS['_PEAR_INSTALLER_ROLES']); + PEAR_Installer_Role::getBaseinstallRoles(true); + PEAR_Installer_Role::getInstallableRoles(true); + PEAR_Installer_Role::getPhpRoles(true); + PEAR_Installer_Role::getValidRoles('****', true); + return true; + } +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Installer/Role/Cfg.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Installer/Role/Cfg.php new file mode 100644 index 0000000..903b1d6 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Installer/Role/Cfg.php @@ -0,0 +1,105 @@ + + * @copyright 2007-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.7.0 + */ + +/** + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 2007-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.7.0 + */ +class PEAR_Installer_Role_Cfg extends PEAR_Installer_Role_Common +{ + /** + * @var PEAR_Installer + */ + var $installer; + + /** + * the md5 of the original file + * + * @var unknown_type + */ + var $md5 = null; + + /** + * Do any unusual setup here + * @param PEAR_Installer + * @param PEAR_PackageFile_v2 + * @param array file attributes + * @param string file name + */ + function setup(&$installer, $pkg, $atts, $file) + { + $this->installer = &$installer; + $reg = &$this->installer->config->getRegistry(); + $package = $reg->getPackage($pkg->getPackage(), $pkg->getChannel()); + if ($package) { + $filelist = $package->getFilelist(); + if (isset($filelist[$file]) && isset($filelist[$file]['md5sum'])) { + $this->md5 = $filelist[$file]['md5sum']; + } + } + } + + function processInstallation($pkg, $atts, $file, $tmp_path, $layer = null) + { + $test = parent::processInstallation($pkg, $atts, $file, $tmp_path, $layer); + if (@file_exists($test[2]) && @file_exists($test[3])) { + $md5 = md5_file($test[2]); + // configuration has already been installed, check for mods + if ($md5 !== $this->md5 && $md5 !== md5_file($test[3])) { + // configuration has been modified, so save our version as + // configfile-version + $old = $test[2]; + $test[2] .= '.new-' . $pkg->getVersion(); + // backup original and re-install it + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $tmpcfg = $this->config->get('temp_dir'); + $newloc = System::mkdir(array('-p', $tmpcfg)); + if (!$newloc) { + // try temp_dir + $newloc = System::mktemp(array('-d')); + if (!$newloc || PEAR::isError($newloc)) { + PEAR::popErrorHandling(); + return PEAR::raiseError('Could not save existing configuration file '. + $old . ', unable to install. Please set temp_dir ' . + 'configuration variable to a writeable location and try again'); + } + } else { + $newloc = $tmpcfg; + } + + $temp_file = $newloc . DIRECTORY_SEPARATOR . uniqid('savefile'); + if (!@copy($old, $temp_file)) { + PEAR::popErrorHandling(); + return PEAR::raiseError('Could not save existing configuration file '. + $old . ', unable to install. Please set temp_dir ' . + 'configuration variable to a writeable location and try again'); + } + + PEAR::popErrorHandling(); + $this->installer->log(0, "WARNING: configuration file $old is being installed as $test[2], you should manually merge in changes to the existing configuration file"); + $this->installer->addFileOperation('rename', array($temp_file, $old, false)); + $this->installer->addFileOperation('delete', array($temp_file)); + } + } + + return $test; + } +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Installer/Role/Common.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Installer/Role/Common.php new file mode 100644 index 0000000..df0b3c6 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Installer/Role/Common.php @@ -0,0 +1,173 @@ + + * @copyright 1997-2006 The PHP Group + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ +/** + * Base class for all installation roles. + * + * This class allows extensibility of file roles. Packages with complex + * customization can now provide custom file roles along with the possibility of + * adding configuration values to match. + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2006 The PHP Group + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Installer_Role_Common +{ + /** + * @var PEAR_Config + * @access protected + */ + var $config; + + /** + * @param PEAR_Config + */ + function __construct(&$config) + { + $this->config = $config; + } + + /** + * Retrieve configuration information about a file role from its XML info + * + * @param string $role Role Classname, as in "PEAR_Installer_Role_Data" + * @return array + */ + function getInfo($role) + { + if (empty($GLOBALS['_PEAR_INSTALLER_ROLES'][$role])) { + return PEAR::raiseError('Unknown Role class: "' . $role . '"'); + } + return $GLOBALS['_PEAR_INSTALLER_ROLES'][$role]; + } + + /** + * This is called for each file to set up the directories and files + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * @param array attributes from the tag + * @param string file name + * @return array an array consisting of: + * + * 1 the original, pre-baseinstalldir installation directory + * 2 the final installation directory + * 3 the full path to the final location of the file + * 4 the location of the pre-installation file + */ + function processInstallation($pkg, $atts, $file, $tmp_path, $layer = null) + { + $roleInfo = PEAR_Installer_Role_Common::getInfo('PEAR_Installer_Role_' . + ucfirst(str_replace('pear_installer_role_', '', strtolower(get_class($this))))); + if (PEAR::isError($roleInfo)) { + return $roleInfo; + } + if (!$roleInfo['locationconfig']) { + return false; + } + if ($roleInfo['honorsbaseinstall']) { + $dest_dir = $save_destdir = $this->config->get($roleInfo['locationconfig'], $layer, + $pkg->getChannel()); + if (!empty($atts['baseinstalldir'])) { + $dest_dir .= DIRECTORY_SEPARATOR . $atts['baseinstalldir']; + } + } elseif ($roleInfo['unusualbaseinstall']) { + $dest_dir = $save_destdir = $this->config->get($roleInfo['locationconfig'], + $layer, $pkg->getChannel()) . DIRECTORY_SEPARATOR . $pkg->getPackage(); + if (!empty($atts['baseinstalldir'])) { + $dest_dir .= DIRECTORY_SEPARATOR . $atts['baseinstalldir']; + } + } else { + $dest_dir = $save_destdir = $this->config->get($roleInfo['locationconfig'], + $layer, $pkg->getChannel()) . DIRECTORY_SEPARATOR . $pkg->getPackage(); + } + if (dirname($file) != '.' && empty($atts['install-as'])) { + $dest_dir .= DIRECTORY_SEPARATOR . dirname($file); + } + if (empty($atts['install-as'])) { + $dest_file = $dest_dir . DIRECTORY_SEPARATOR . basename($file); + } else { + $dest_file = $dest_dir . DIRECTORY_SEPARATOR . $atts['install-as']; + } + $orig_file = $tmp_path . DIRECTORY_SEPARATOR . $file; + + // Clean up the DIRECTORY_SEPARATOR mess + $ds2 = DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR; + + list($dest_dir, $dest_file, $orig_file) = preg_replace(array('!\\\\+!', '!/!', "!$ds2+!"), + array(DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR, + DIRECTORY_SEPARATOR), + array($dest_dir, $dest_file, $orig_file)); + return array($save_destdir, $dest_dir, $dest_file, $orig_file); + } + + /** + * Get the name of the configuration variable that specifies the location of this file + * @return string|false + */ + function getLocationConfig() + { + $roleInfo = PEAR_Installer_Role_Common::getInfo('PEAR_Installer_Role_' . + ucfirst(str_replace('pear_installer_role_', '', strtolower(get_class($this))))); + if (PEAR::isError($roleInfo)) { + return $roleInfo; + } + return $roleInfo['locationconfig']; + } + + /** + * Do any unusual setup here + * @param PEAR_Installer + * @param PEAR_PackageFile_v2 + * @param array file attributes + * @param string file name + */ + function setup(&$installer, $pkg, $atts, $file) + { + } + + function isExecutable() + { + $roleInfo = PEAR_Installer_Role_Common::getInfo('PEAR_Installer_Role_' . + ucfirst(str_replace('pear_installer_role_', '', strtolower(get_class($this))))); + if (PEAR::isError($roleInfo)) { + return $roleInfo; + } + return $roleInfo['executable']; + } + + function isInstallable() + { + $roleInfo = PEAR_Installer_Role_Common::getInfo('PEAR_Installer_Role_' . + ucfirst(str_replace('pear_installer_role_', '', strtolower(get_class($this))))); + if (PEAR::isError($roleInfo)) { + return $roleInfo; + } + return $roleInfo['installable']; + } + + function isExtension() + { + $roleInfo = PEAR_Installer_Role_Common::getInfo('PEAR_Installer_Role_' . + ucfirst(str_replace('pear_installer_role_', '', strtolower(get_class($this))))); + if (PEAR::isError($roleInfo)) { + return $roleInfo; + } + return $roleInfo['phpextension']; + } +} +?> diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Installer/Role/Data.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Installer/Role/Data.php new file mode 100644 index 0000000..1a2c9c3 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Installer/Role/Data.php @@ -0,0 +1,27 @@ + + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Installer_Role_Data extends PEAR_Installer_Role_Common {} +?> \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Installer/Role/Doc.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Installer/Role/Doc.php new file mode 100644 index 0000000..675cc87 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Installer/Role/Doc.php @@ -0,0 +1,27 @@ + + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Installer_Role_Doc extends PEAR_Installer_Role_Common {} +?> \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Installer/Role/Ext.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Installer/Role/Ext.php new file mode 100644 index 0000000..6224e2b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Installer/Role/Ext.php @@ -0,0 +1,27 @@ + + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Installer_Role_Ext extends PEAR_Installer_Role_Common {} +?> \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Installer/Role/Man.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Installer/Role/Man.php new file mode 100644 index 0000000..5c3a842 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Installer/Role/Man.php @@ -0,0 +1,28 @@ + + * @copyright 2011 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version SVN: $Id: $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.10.0 + */ + +/** + * @category pear + * @package PEAR + * @author Hannes Magnusson + * @copyright 2011 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.10.0 + */ +class PEAR_Installer_Role_Man extends PEAR_Installer_Role_Common {} +?> diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Installer/Role/Php.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Installer/Role/Php.php new file mode 100644 index 0000000..d1b97a8 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Installer/Role/Php.php @@ -0,0 +1,27 @@ + + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Installer_Role_Php extends PEAR_Installer_Role_Common {} +?> \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Installer/Role/Script.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Installer/Role/Script.php new file mode 100644 index 0000000..f1eeda0 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Installer/Role/Script.php @@ -0,0 +1,27 @@ + + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Installer_Role_Script extends PEAR_Installer_Role_Common {} +?> \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Installer/Role/Src.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Installer/Role/Src.php new file mode 100644 index 0000000..2c7ae21 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Installer/Role/Src.php @@ -0,0 +1,33 @@ + + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Installer_Role_Src extends PEAR_Installer_Role_Common +{ + function setup(&$installer, $pkg, $atts, $file) + { + $installer->source_files++; + } +} +?> \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Installer/Role/Test.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Installer/Role/Test.php new file mode 100644 index 0000000..c19c5dc --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Installer/Role/Test.php @@ -0,0 +1,27 @@ + + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Installer_Role_Test extends PEAR_Installer_Role_Common {} +?> \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Installer/Role/Www.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Installer/Role/Www.php new file mode 100644 index 0000000..42b197a --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Installer/Role/Www.php @@ -0,0 +1,27 @@ + + * @copyright 2007-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.7.0 + */ + +/** + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 2007-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.7.0 + */ +class PEAR_Installer_Role_Www extends PEAR_Installer_Role_Common {} +?> \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/PackageFile.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/PackageFile.php new file mode 100644 index 0000000..8fb6e41 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/PackageFile.php @@ -0,0 +1,491 @@ + + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * needed for PEAR_VALIDATE_* constants + */ +require_once 'PEAR/Validate.php'; +/** + * Error code if the package.xml tag does not contain a valid version + */ +define('PEAR_PACKAGEFILE_ERROR_NO_PACKAGEVERSION', 1); +/** + * Error code if the package.xml tag version is not supported (version 1.0 and 1.1 are the only supported versions, + * currently + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_PACKAGEVERSION', 2); +/** + * Abstraction for the package.xml package description file + * + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_PackageFile +{ + /** + * @var PEAR_Config + */ + var $_config; + var $_debug; + + var $_logger = false; + /** + * @var boolean + */ + var $_rawReturn = false; + + /** + * helper for extracting Archive_Tar errors + * @var array + * @access private + */ + var $_extractErrors = array(); + + /** + * + * @param PEAR_Config $config + * @param ? $debug + * @param string @tmpdir Optional temporary directory for uncompressing + * files + */ + function __construct(&$config, $debug = false) + { + $this->_config = $config; + $this->_debug = $debug; + } + + /** + * Turn off validation - return a parsed package.xml without checking it + * + * This is used by the package-validate command + */ + function rawReturn() + { + $this->_rawReturn = true; + } + + function setLogger(&$l) + { + $this->_logger = &$l; + } + + /** + * Create a PEAR_PackageFile_Parser_v* of a given version. + * @param int $version + * @return PEAR_PackageFile_Parser_v1|PEAR_PackageFile_Parser_v1 + */ + function &parserFactory($version) + { + if (!in_array($version{0}, array('1', '2'))) { + $a = false; + return $a; + } + + include_once 'PEAR/PackageFile/Parser/v' . $version{0} . '.php'; + $version = $version{0}; + $class = "PEAR_PackageFile_Parser_v$version"; + $a = new $class; + return $a; + } + + /** + * For simpler unit-testing + * @return string + */ + function getClassPrefix() + { + return 'PEAR_PackageFile_v'; + } + + /** + * Create a PEAR_PackageFile_v* of a given version. + * @param int $version + * @return PEAR_PackageFile_v1|PEAR_PackageFile_v1 + */ + function &factory($version) + { + if (!in_array($version{0}, array('1', '2'))) { + $a = false; + return $a; + } + + include_once 'PEAR/PackageFile/v' . $version{0} . '.php'; + $version = $version{0}; + $class = $this->getClassPrefix() . $version; + $a = new $class; + return $a; + } + + /** + * Create a PEAR_PackageFile_v* from its toArray() method + * + * WARNING: no validation is performed, the array is assumed to be valid, + * always parse from xml if you want validation. + * @param array $arr + * @return PEAR_PackageFileManager_v1|PEAR_PackageFileManager_v2 + * @uses factory() to construct the returned object. + */ + function &fromArray($arr) + { + if (isset($arr['xsdversion'])) { + $obj = &$this->factory($arr['xsdversion']); + if ($this->_logger) { + $obj->setLogger($this->_logger); + } + + $obj->setConfig($this->_config); + $obj->fromArray($arr); + return $obj; + } + + if (isset($arr['package']['attribs']['version'])) { + $obj = &$this->factory($arr['package']['attribs']['version']); + } else { + $obj = &$this->factory('1.0'); + } + + if ($this->_logger) { + $obj->setLogger($this->_logger); + } + + $obj->setConfig($this->_config); + $obj->fromArray($arr); + return $obj; + } + + /** + * Create a PEAR_PackageFile_v* from an XML string. + * @access public + * @param string $data contents of package.xml file + * @param int $state package state (one of PEAR_VALIDATE_* constants) + * @param string $file full path to the package.xml file (and the files + * it references) + * @param string $archive optional name of the archive that the XML was + * extracted from, if any + * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * @uses parserFactory() to construct a parser to load the package. + */ + function &fromXmlString($data, $state, $file, $archive = false) + { + if (preg_match('/]+version=[\'"]([0-9]+\.[0-9]+)[\'"]/', $data, $packageversion)) { + if (!in_array($packageversion[1], array('1.0', '2.0', '2.1'))) { + return PEAR::raiseError('package.xml version "' . $packageversion[1] . + '" is not supported, only 1.0, 2.0, and 2.1 are supported.'); + } + + $object = &$this->parserFactory($packageversion[1]); + if ($this->_logger) { + $object->setLogger($this->_logger); + } + + $object->setConfig($this->_config); + $pf = $object->parse($data, $file, $archive); + if (PEAR::isError($pf)) { + return $pf; + } + + if ($this->_rawReturn) { + return $pf; + } + + if (!$pf->validate($state)) {; + if ($this->_config->get('verbose') > 0 + && $this->_logger && $pf->getValidationWarnings(false) + ) { + foreach ($pf->getValidationWarnings(false) as $warning) { + $this->_logger->log(0, 'ERROR: ' . $warning['message']); + } + } + + $a = PEAR::raiseError('Parsing of package.xml from file "' . $file . '" failed', + 2, null, null, $pf->getValidationWarnings()); + return $a; + } + + if ($this->_logger && $pf->getValidationWarnings(false)) { + foreach ($pf->getValidationWarnings() as $warning) { + $this->_logger->log(0, 'WARNING: ' . $warning['message']); + } + } + + if (method_exists($pf, 'flattenFilelist')) { + $pf->flattenFilelist(); // for v2 + } + + return $pf; + } elseif (preg_match('/]+version=[\'"]([^"\']+)[\'"]/', $data, $packageversion)) { + $a = PEAR::raiseError('package.xml file "' . $file . + '" has unsupported package.xml version "' . $packageversion[1] . '"'); + return $a; + } else { + if (!class_exists('PEAR_ErrorStack')) { + require_once 'PEAR/ErrorStack.php'; + } + + PEAR_ErrorStack::staticPush('PEAR_PackageFile', + PEAR_PACKAGEFILE_ERROR_NO_PACKAGEVERSION, + 'warning', array('xml' => $data), 'package.xml "' . $file . + '" has no package.xml version'); + $object = &$this->parserFactory('1.0'); + $object->setConfig($this->_config); + $pf = $object->parse($data, $file, $archive); + if (PEAR::isError($pf)) { + return $pf; + } + + if ($this->_rawReturn) { + return $pf; + } + + if (!$pf->validate($state)) { + $a = PEAR::raiseError('Parsing of package.xml from file "' . $file . '" failed', + 2, null, null, $pf->getValidationWarnings()); + return $a; + } + + if ($this->_logger && $pf->getValidationWarnings(false)) { + foreach ($pf->getValidationWarnings() as $warning) { + $this->_logger->log(0, 'WARNING: ' . $warning['message']); + } + } + + if (method_exists($pf, 'flattenFilelist')) { + $pf->flattenFilelist(); // for v2 + } + + return $pf; + } + } + + /** + * Register a temporary file or directory. When the destructor is + * executed, all registered temporary files and directories are + * removed. + * + * @param string $file name of file or directory + * @return void + */ + function addTempFile($file) + { + $GLOBALS['_PEAR_Common_tempfiles'][] = $file; + } + + /** + * Create a PEAR_PackageFile_v* from a compresed Tar or Tgz file. + * @access public + * @param string contents of package.xml file + * @param int package state (one of PEAR_VALIDATE_* constants) + * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * @using Archive_Tar to extract the files + * @using fromPackageFile() to load the package after the package.xml + * file is extracted. + */ + function &fromTgzFile($file, $state) + { + if (!class_exists('Archive_Tar')) { + require_once 'Archive/Tar.php'; + } + + $tar = new Archive_Tar($file); + if ($this->_debug <= 1) { + $tar->pushErrorHandling(PEAR_ERROR_RETURN); + } + + $content = $tar->listContent(); + if ($this->_debug <= 1) { + $tar->popErrorHandling(); + } + + if (!is_array($content)) { + if (is_string($file) && strlen($file < 255) && + (!file_exists($file) || !@is_file($file))) { + $ret = PEAR::raiseError("could not open file \"$file\""); + return $ret; + } + + $file = realpath($file); + $ret = PEAR::raiseError("Could not get contents of package \"$file\"". + '. Invalid tgz file.'); + return $ret; + } + + if (!count($content) && !@is_file($file)) { + $ret = PEAR::raiseError("could not open file \"$file\""); + return $ret; + } + + $xml = null; + $origfile = $file; + foreach ($content as $file) { + $name = $file['filename']; + if ($name == 'package2.xml') { // allow a .tgz to distribute both versions + $xml = $name; + break; + } + + if ($name == 'package.xml') { + $xml = $name; + break; + } elseif (preg_match('/package.xml$/', $name, $match)) { + $xml = $name; + break; + } + } + + $tmpdir = System::mktemp('-t "' . $this->_config->get('temp_dir') . '" -d pear'); + if ($tmpdir === false) { + $ret = PEAR::raiseError("there was a problem with getting the configured temp directory"); + return $ret; + } + + PEAR_PackageFile::addTempFile($tmpdir); + + $this->_extractErrors(); + PEAR::staticPushErrorHandling(PEAR_ERROR_CALLBACK, array($this, '_extractErrors')); + + if (!$xml || !$tar->extractList(array($xml), $tmpdir)) { + $extra = implode("\n", $this->_extractErrors()); + if ($extra) { + $extra = ' ' . $extra; + } + + PEAR::staticPopErrorHandling(); + $ret = PEAR::raiseError('could not extract the package.xml file from "' . + $origfile . '"' . $extra); + return $ret; + } + + PEAR::staticPopErrorHandling(); + $ret = &PEAR_PackageFile::fromPackageFile("$tmpdir/$xml", $state, $origfile); + return $ret; + } + + /** + * helper callback for extracting Archive_Tar errors + * + * @param PEAR_Error|null $err + * @return array + * @access private + */ + function _extractErrors($err = null) + { + static $errors = array(); + if ($err === null) { + $e = $errors; + $errors = array(); + return $e; + } + $errors[] = $err->getMessage(); + } + + /** + * Create a PEAR_PackageFile_v* from a package.xml file. + * + * @access public + * @param string $descfile name of package xml file + * @param int $state package state (one of PEAR_VALIDATE_* constants) + * @param string|false $archive name of the archive this package.xml came + * from, if any + * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * @uses PEAR_PackageFile::fromXmlString to create the oject after the + * XML is loaded from the package.xml file. + */ + function &fromPackageFile($descfile, $state, $archive = false) + { + $fp = false; + if (is_string($descfile) && strlen($descfile) < 255 && + ( + !file_exists($descfile) || !is_file($descfile) || !is_readable($descfile) + || (!$fp = @fopen($descfile, 'r')) + ) + ) { + $a = PEAR::raiseError("Unable to open $descfile"); + return $a; + } + + // read the whole thing so we only get one cdata callback + // for each block of cdata + fclose($fp); + $data = file_get_contents($descfile); + $ret = &PEAR_PackageFile::fromXmlString($data, $state, $descfile, $archive); + return $ret; + } + + /** + * Create a PEAR_PackageFile_v* from a .tgz archive or package.xml file. + * + * This method is able to extract information about a package from a .tgz + * archive or from a XML package definition file. + * + * @access public + * @param string $info file name + * @param int $state package state (one of PEAR_VALIDATE_* constants) + * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * @uses fromPackageFile() if the file appears to be XML + * @uses fromTgzFile() to load all non-XML files + */ + function &fromAnyFile($info, $state) + { + if (is_dir($info)) { + $dir_name = realpath($info); + if (file_exists($dir_name . '/package.xml')) { + $info = PEAR_PackageFile::fromPackageFile($dir_name . '/package.xml', $state); + } elseif (file_exists($dir_name . '/package2.xml')) { + $info = PEAR_PackageFile::fromPackageFile($dir_name . '/package2.xml', $state); + } else { + $info = PEAR::raiseError("No package definition found in '$info' directory"); + } + + return $info; + } + + $fp = false; + if (is_string($info) && strlen($info) < 255 && + (file_exists($info) || ($fp = @fopen($info, 'r'))) + ) { + + if ($fp) { + fclose($fp); + } + + $tmp = substr($info, -4); + if ($tmp == '.xml') { + $info = &PEAR_PackageFile::fromPackageFile($info, $state); + } elseif ($tmp == '.tar' || $tmp == '.tgz') { + $info = &PEAR_PackageFile::fromTgzFile($info, $state); + } else { + $fp = fopen($info, 'r'); + $test = fread($fp, 5); + fclose($fp); + if ($test == ' + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ +/** + * needed for PEAR_VALIDATE_* constants + */ +require_once 'PEAR/Validate.php'; +require_once 'System.php'; +require_once 'PEAR/PackageFile/v2.php'; +/** + * This class converts a PEAR_PackageFile_v1 object into any output format. + * + * Supported output formats include array, XML string, and a PEAR_PackageFile_v2 + * object, for converting package.xml 1.0 into package.xml 2.0 with no sweat. + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_PackageFile_Generator_v1 +{ + /** + * @var PEAR_PackageFile_v1 + */ + var $_packagefile; + function __construct(&$packagefile) + { + $this->_packagefile = &$packagefile; + } + + function getPackagerVersion() + { + return '1.10.1'; + } + + /** + * @param PEAR_Packager + * @param bool if true, a .tgz is written, otherwise a .tar is written + * @param string|null directory in which to save the .tgz + * @return string|PEAR_Error location of package or error object + */ + function toTgz(&$packager, $compress = true, $where = null) + { + require_once 'Archive/Tar.php'; + if ($where === null) { + if (!($where = System::mktemp(array('-d')))) { + return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: mktemp failed'); + } + } elseif (!@System::mkDir(array('-p', $where))) { + return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: "' . $where . '" could' . + ' not be created'); + } + if (file_exists($where . DIRECTORY_SEPARATOR . 'package.xml') && + !is_file($where . DIRECTORY_SEPARATOR . 'package.xml')) { + return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: unable to save package.xml as' . + ' "' . $where . DIRECTORY_SEPARATOR . 'package.xml"'); + } + if (!$this->_packagefile->validate(PEAR_VALIDATE_PACKAGING)) { + return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: invalid package file'); + } + $pkginfo = $this->_packagefile->getArray(); + $ext = $compress ? '.tgz' : '.tar'; + $pkgver = $pkginfo['package'] . '-' . $pkginfo['version']; + $dest_package = getcwd() . DIRECTORY_SEPARATOR . $pkgver . $ext; + if (file_exists(getcwd() . DIRECTORY_SEPARATOR . $pkgver . $ext) && + !is_file(getcwd() . DIRECTORY_SEPARATOR . $pkgver . $ext)) { + return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: cannot create tgz file "' . + getcwd() . DIRECTORY_SEPARATOR . $pkgver . $ext . '"'); + } + if ($pkgfile = $this->_packagefile->getPackageFile()) { + $pkgdir = dirname(realpath($pkgfile)); + $pkgfile = basename($pkgfile); + } else { + return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: package file object must ' . + 'be created from a real file'); + } + // {{{ Create the package file list + $filelist = array(); + $i = 0; + + foreach ($this->_packagefile->getFilelist() as $fname => $atts) { + $file = $pkgdir . DIRECTORY_SEPARATOR . $fname; + if (!file_exists($file)) { + return PEAR::raiseError("File does not exist: $fname"); + } else { + $filelist[$i++] = $file; + if (!isset($atts['md5sum'])) { + $this->_packagefile->setFileAttribute($fname, 'md5sum', md5_file($file)); + } + $packager->log(2, "Adding file $fname"); + } + } + // }}} + $packagexml = $this->toPackageFile($where, PEAR_VALIDATE_PACKAGING, 'package.xml', true); + if ($packagexml) { + $tar = new Archive_Tar($dest_package, $compress); + $tar->setErrorHandling(PEAR_ERROR_RETURN); // XXX Don't print errors + // ----- Creates with the package.xml file + $ok = $tar->createModify(array($packagexml), '', $where); + if (PEAR::isError($ok)) { + return $ok; + } elseif (!$ok) { + return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: tarball creation failed'); + } + // ----- Add the content of the package + if (!$tar->addModify($filelist, $pkgver, $pkgdir)) { + return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: tarball creation failed'); + } + return $dest_package; + } + } + + /** + * @param string|null directory to place the package.xml in, or null for a temporary dir + * @param int one of the PEAR_VALIDATE_* constants + * @param string name of the generated file + * @param bool if true, then no analysis will be performed on role="php" files + * @return string|PEAR_Error path to the created file on success + */ + function toPackageFile($where = null, $state = PEAR_VALIDATE_NORMAL, $name = 'package.xml', + $nofilechecking = false) + { + if (!$this->_packagefile->validate($state, $nofilechecking)) { + return PEAR::raiseError('PEAR_Packagefile_v1::toPackageFile: invalid package.xml', + null, null, null, $this->_packagefile->getValidationWarnings()); + } + if ($where === null) { + if (!($where = System::mktemp(array('-d')))) { + return PEAR::raiseError('PEAR_Packagefile_v1::toPackageFile: mktemp failed'); + } + } elseif (!@System::mkDir(array('-p', $where))) { + return PEAR::raiseError('PEAR_Packagefile_v1::toPackageFile: "' . $where . '" could' . + ' not be created'); + } + $newpkgfile = $where . DIRECTORY_SEPARATOR . $name; + $np = @fopen($newpkgfile, 'wb'); + if (!$np) { + return PEAR::raiseError('PEAR_Packagefile_v1::toPackageFile: unable to save ' . + "$name as $newpkgfile"); + } + fwrite($np, $this->toXml($state, true)); + fclose($np); + return $newpkgfile; + } + + /** + * fix both XML encoding to be UTF8, and replace standard XML entities < > " & ' + * + * @param string $string + * @return string + * @access private + */ + function _fixXmlEncoding($string) + { + return strtr($string, array( + '&' => '&', + '>' => '>', + '<' => '<', + '"' => '"', + '\'' => ''' )); + } + + /** + * Return an XML document based on the package info (as returned + * by the PEAR_Common::infoFrom* methods). + * + * @return string XML data + */ + function toXml($state = PEAR_VALIDATE_NORMAL, $nofilevalidation = false) + { + $this->_packagefile->setDate(date('Y-m-d')); + if (!$this->_packagefile->validate($state, $nofilevalidation)) { + return false; + } + $pkginfo = $this->_packagefile->getArray(); + static $maint_map = array( + "handle" => "user", + "name" => "name", + "email" => "email", + "role" => "role", + ); + $ret = "\n"; + $ret .= "\n"; + $ret .= "\n" . +" $pkginfo[package]"; + if (isset($pkginfo['extends'])) { + $ret .= "\n$pkginfo[extends]"; + } + $ret .= + "\n ".$this->_fixXmlEncoding($pkginfo['summary'])."\n" . +" ".trim($this->_fixXmlEncoding($pkginfo['description']))."\n \n" . +" \n"; + foreach ($pkginfo['maintainers'] as $maint) { + $ret .= " \n"; + foreach ($maint_map as $idx => $elm) { + $ret .= " <$elm>"; + $ret .= $this->_fixXmlEncoding($maint[$idx]); + $ret .= "\n"; + } + $ret .= " \n"; + } + $ret .= " \n"; + $ret .= $this->_makeReleaseXml($pkginfo, false, $state); + if (isset($pkginfo['changelog']) && count($pkginfo['changelog']) > 0) { + $ret .= " \n"; + foreach ($pkginfo['changelog'] as $oldrelease) { + $ret .= $this->_makeReleaseXml($oldrelease, true); + } + $ret .= " \n"; + } + $ret .= "\n"; + return $ret; + } + + // }}} + // {{{ _makeReleaseXml() + + /** + * Generate part of an XML description with release information. + * + * @param array $pkginfo array with release information + * @param bool $changelog whether the result will be in a changelog element + * + * @return string XML data + * + * @access private + */ + function _makeReleaseXml($pkginfo, $changelog = false, $state = PEAR_VALIDATE_NORMAL) + { + // XXX QUOTE ENTITIES IN PCDATA, OR EMBED IN CDATA BLOCKS!! + $indent = $changelog ? " " : ""; + $ret = "$indent \n"; + if (!empty($pkginfo['version'])) { + $ret .= "$indent $pkginfo[version]\n"; + } + if (!empty($pkginfo['release_date'])) { + $ret .= "$indent $pkginfo[release_date]\n"; + } + if (!empty($pkginfo['release_license'])) { + $ret .= "$indent $pkginfo[release_license]\n"; + } + if (!empty($pkginfo['release_state'])) { + $ret .= "$indent $pkginfo[release_state]\n"; + } + if (!empty($pkginfo['release_notes'])) { + $ret .= "$indent ".trim($this->_fixXmlEncoding($pkginfo['release_notes'])) + ."\n$indent \n"; + } + if (!empty($pkginfo['release_warnings'])) { + $ret .= "$indent ".$this->_fixXmlEncoding($pkginfo['release_warnings'])."\n"; + } + if (isset($pkginfo['release_deps']) && sizeof($pkginfo['release_deps']) > 0) { + $ret .= "$indent \n"; + foreach ($pkginfo['release_deps'] as $dep) { + $ret .= "$indent _fixXmlEncoding($c['name']) . "\""; + if (isset($c['default'])) { + $ret .= " default=\"" . $this->_fixXmlEncoding($c['default']) . "\""; + } + $ret .= " prompt=\"" . $this->_fixXmlEncoding($c['prompt']) . "\""; + $ret .= "/>\n"; + } + $ret .= "$indent \n"; + } + if (isset($pkginfo['provides'])) { + foreach ($pkginfo['provides'] as $key => $what) { + $ret .= "$indent recursiveXmlFilelist($pkginfo['filelist']); + } else { + foreach ($pkginfo['filelist'] as $file => $fa) { + if (!isset($fa['role'])) { + $fa['role'] = ''; + } + $ret .= "$indent _fixXmlEncoding($fa['baseinstalldir']) . '"'; + } + if (isset($fa['md5sum'])) { + $ret .= " md5sum=\"$fa[md5sum]\""; + } + if (isset($fa['platform'])) { + $ret .= " platform=\"$fa[platform]\""; + } + if (!empty($fa['install-as'])) { + $ret .= ' install-as="' . + $this->_fixXmlEncoding($fa['install-as']) . '"'; + } + $ret .= ' name="' . $this->_fixXmlEncoding($file) . '"'; + if (empty($fa['replacements'])) { + $ret .= "/>\n"; + } else { + $ret .= ">\n"; + foreach ($fa['replacements'] as $r) { + $ret .= "$indent $v) { + $ret .= " $k=\"" . $this->_fixXmlEncoding($v) .'"'; + } + $ret .= "/>\n"; + } + $ret .= "$indent \n"; + } + } + } + $ret .= "$indent \n"; + } + $ret .= "$indent \n"; + return $ret; + } + + /** + * @param array + * @access protected + */ + function recursiveXmlFilelist($list) + { + $this->_dirs = array(); + foreach ($list as $file => $attributes) { + $this->_addDir($this->_dirs, explode('/', dirname($file)), $file, $attributes); + } + return $this->_formatDir($this->_dirs); + } + + /** + * @param array + * @param array + * @param string|null + * @param array|null + * @access private + */ + function _addDir(&$dirs, $dir, $file = null, $attributes = null) + { + if ($dir == array() || $dir == array('.')) { + $dirs['files'][basename($file)] = $attributes; + return; + } + $curdir = array_shift($dir); + if (!isset($dirs['dirs'][$curdir])) { + $dirs['dirs'][$curdir] = array(); + } + $this->_addDir($dirs['dirs'][$curdir], $dir, $file, $attributes); + } + + /** + * @param array + * @param string + * @param string + * @access private + */ + function _formatDir($dirs, $indent = '', $curdir = '') + { + $ret = ''; + if (!count($dirs)) { + return ''; + } + if (isset($dirs['dirs'])) { + uksort($dirs['dirs'], 'strnatcasecmp'); + foreach ($dirs['dirs'] as $dir => $contents) { + $usedir = "$curdir/$dir"; + $ret .= "$indent \n"; + $ret .= $this->_formatDir($contents, "$indent ", $usedir); + $ret .= "$indent \n"; + } + } + if (isset($dirs['files'])) { + uksort($dirs['files'], 'strnatcasecmp'); + foreach ($dirs['files'] as $file => $attribs) { + $ret .= $this->_formatFile($file, $attribs, $indent); + } + } + return $ret; + } + + /** + * @param string + * @param array + * @param string + * @access private + */ + function _formatFile($file, $attributes, $indent) + { + $ret = "$indent _fixXmlEncoding($attributes['baseinstalldir']) . '"'; + } + if (isset($attributes['md5sum'])) { + $ret .= " md5sum=\"$attributes[md5sum]\""; + } + if (isset($attributes['platform'])) { + $ret .= " platform=\"$attributes[platform]\""; + } + if (!empty($attributes['install-as'])) { + $ret .= ' install-as="' . + $this->_fixXmlEncoding($attributes['install-as']) . '"'; + } + $ret .= ' name="' . $this->_fixXmlEncoding($file) . '"'; + if (empty($attributes['replacements'])) { + $ret .= "/>\n"; + } else { + $ret .= ">\n"; + foreach ($attributes['replacements'] as $r) { + $ret .= "$indent $v) { + $ret .= " $k=\"" . $this->_fixXmlEncoding($v) .'"'; + } + $ret .= "/>\n"; + } + $ret .= "$indent \n"; + } + return $ret; + } + + // {{{ _unIndent() + + /** + * Unindent given string (?) + * + * @param string $str The string that has to be unindented. + * @return string + * @access private + */ + function _unIndent($str) + { + // remove leading newlines + $str = preg_replace('/^[\r\n]+/', '', $str); + // find whitespace at the beginning of the first line + $indent_len = strspn($str, " \t"); + $indent = substr($str, 0, $indent_len); + $data = ''; + // remove the same amount of whitespace from following lines + foreach (explode("\n", $str) as $line) { + if (substr($line, 0, $indent_len) == $indent) { + $data .= substr($line, $indent_len) . "\n"; + } + } + return $data; + } + + /** + * @return array + */ + function dependenciesToV2() + { + $arr = array(); + $this->_convertDependencies2_0($arr); + return $arr['dependencies']; + } + + /** + * Convert a package.xml version 1.0 into version 2.0 + * + * Note that this does a basic conversion, to allow more advanced + * features like bundles and multiple releases + * @param string the classname to instantiate and return. This must be + * PEAR_PackageFile_v2 or a descendant + * @param boolean if true, only valid, deterministic package.xml 1.0 as defined by the + * strictest parameters will be converted + * @return PEAR_PackageFile_v2|PEAR_Error + */ + function &toV2($class = 'PEAR_PackageFile_v2', $strict = false) + { + if ($strict) { + if (!$this->_packagefile->validate()) { + $a = PEAR::raiseError('invalid package.xml version 1.0 cannot be converted' . + ' to version 2.0', null, null, null, + $this->_packagefile->getValidationWarnings(true)); + return $a; + } + } + + $arr = array( + 'attribs' => array( + 'version' => '2.0', + 'xmlns' => 'http://pear.php.net/dtd/package-2.0', + 'xmlns:tasks' => 'http://pear.php.net/dtd/tasks-1.0', + 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', + 'xsi:schemaLocation' => "http://pear.php.net/dtd/tasks-1.0\n" . +"http://pear.php.net/dtd/tasks-1.0.xsd\n" . +"http://pear.php.net/dtd/package-2.0\n" . +'http://pear.php.net/dtd/package-2.0.xsd', + ), + 'name' => $this->_packagefile->getPackage(), + 'channel' => 'pear.php.net', + ); + $arr['summary'] = $this->_packagefile->getSummary(); + $arr['description'] = $this->_packagefile->getDescription(); + $maintainers = $this->_packagefile->getMaintainers(); + foreach ($maintainers as $maintainer) { + if ($maintainer['role'] != 'lead') { + continue; + } + $new = array( + 'name' => $maintainer['name'], + 'user' => $maintainer['handle'], + 'email' => $maintainer['email'], + 'active' => 'yes', + ); + $arr['lead'][] = $new; + } + + if (!isset($arr['lead'])) { // some people... you know? + $arr['lead'] = array( + 'name' => 'unknown', + 'user' => 'unknown', + 'email' => 'noleadmaintainer@example.com', + 'active' => 'no', + ); + } + + if (count($arr['lead']) == 1) { + $arr['lead'] = $arr['lead'][0]; + } + + foreach ($maintainers as $maintainer) { + if ($maintainer['role'] == 'lead') { + continue; + } + $new = array( + 'name' => $maintainer['name'], + 'user' => $maintainer['handle'], + 'email' => $maintainer['email'], + 'active' => 'yes', + ); + $arr[$maintainer['role']][] = $new; + } + + if (isset($arr['developer']) && count($arr['developer']) == 1) { + $arr['developer'] = $arr['developer'][0]; + } + + if (isset($arr['contributor']) && count($arr['contributor']) == 1) { + $arr['contributor'] = $arr['contributor'][0]; + } + + if (isset($arr['helper']) && count($arr['helper']) == 1) { + $arr['helper'] = $arr['helper'][0]; + } + + $arr['date'] = $this->_packagefile->getDate(); + $arr['version'] = + array( + 'release' => $this->_packagefile->getVersion(), + 'api' => $this->_packagefile->getVersion(), + ); + $arr['stability'] = + array( + 'release' => $this->_packagefile->getState(), + 'api' => $this->_packagefile->getState(), + ); + $licensemap = + array( + 'php' => 'http://www.php.net/license', + 'php license' => 'http://www.php.net/license', + 'lgpl' => 'http://www.gnu.org/copyleft/lesser.html', + 'bsd' => 'http://www.opensource.org/licenses/bsd-license.php', + 'bsd style' => 'http://www.opensource.org/licenses/bsd-license.php', + 'bsd-style' => 'http://www.opensource.org/licenses/bsd-license.php', + 'mit' => 'http://www.opensource.org/licenses/mit-license.php', + 'gpl' => 'http://www.gnu.org/copyleft/gpl.html', + 'apache' => 'http://www.opensource.org/licenses/apache2.0.php' + ); + + if (isset($licensemap[strtolower($this->_packagefile->getLicense())])) { + $arr['license'] = array( + 'attribs' => array('uri' => + $licensemap[strtolower($this->_packagefile->getLicense())]), + '_content' => $this->_packagefile->getLicense() + ); + } else { + // don't use bogus uri + $arr['license'] = $this->_packagefile->getLicense(); + } + + $arr['notes'] = $this->_packagefile->getNotes(); + $temp = array(); + $arr['contents'] = $this->_convertFilelist2_0($temp); + $this->_convertDependencies2_0($arr); + $release = ($this->_packagefile->getConfigureOptions() || $this->_isExtension) ? + 'extsrcrelease' : 'phprelease'; + if ($release == 'extsrcrelease') { + $arr['channel'] = 'pecl.php.net'; + $arr['providesextension'] = $arr['name']; // assumption + } + + $arr[$release] = array(); + if ($this->_packagefile->getConfigureOptions()) { + $arr[$release]['configureoption'] = $this->_packagefile->getConfigureOptions(); + foreach ($arr[$release]['configureoption'] as $i => $opt) { + $arr[$release]['configureoption'][$i] = array('attribs' => $opt); + } + if (count($arr[$release]['configureoption']) == 1) { + $arr[$release]['configureoption'] = $arr[$release]['configureoption'][0]; + } + } + + $this->_convertRelease2_0($arr[$release], $temp); + if ($release == 'extsrcrelease' && count($arr[$release]) > 1) { + // multiple extsrcrelease tags added in PEAR 1.4.1 + $arr['dependencies']['required']['pearinstaller']['min'] = '1.4.1'; + } + + if ($cl = $this->_packagefile->getChangelog()) { + foreach ($cl as $release) { + $rel = array(); + $rel['version'] = + array( + 'release' => $release['version'], + 'api' => $release['version'], + ); + if (!isset($release['release_state'])) { + $release['release_state'] = 'stable'; + } + + $rel['stability'] = + array( + 'release' => $release['release_state'], + 'api' => $release['release_state'], + ); + if (isset($release['release_date'])) { + $rel['date'] = $release['release_date']; + } else { + $rel['date'] = date('Y-m-d'); + } + + if (isset($release['release_license'])) { + if (isset($licensemap[strtolower($release['release_license'])])) { + $uri = $licensemap[strtolower($release['release_license'])]; + } else { + $uri = 'http://www.example.com'; + } + $rel['license'] = array( + 'attribs' => array('uri' => $uri), + '_content' => $release['release_license'] + ); + } else { + $rel['license'] = $arr['license']; + } + + if (!isset($release['release_notes'])) { + $release['release_notes'] = 'no release notes'; + } + + $rel['notes'] = $release['release_notes']; + $arr['changelog']['release'][] = $rel; + } + } + + $ret = new $class; + $ret->setConfig($this->_packagefile->_config); + if (isset($this->_packagefile->_logger) && is_object($this->_packagefile->_logger)) { + $ret->setLogger($this->_packagefile->_logger); + } + + $ret->fromArray($arr); + return $ret; + } + + /** + * @param array + * @param bool + * @access private + */ + function _convertDependencies2_0(&$release, $internal = false) + { + $peardep = array('pearinstaller' => + array('min' => '1.4.0b1')); // this is a lot safer + $required = $optional = array(); + $release['dependencies'] = array('required' => array()); + if ($this->_packagefile->hasDeps()) { + foreach ($this->_packagefile->getDeps() as $dep) { + if (!isset($dep['optional']) || $dep['optional'] == 'no') { + $required[] = $dep; + } else { + $optional[] = $dep; + } + } + foreach (array('required', 'optional') as $arr) { + $deps = array(); + foreach ($$arr as $dep) { + // organize deps by dependency type and name + if (!isset($deps[$dep['type']])) { + $deps[$dep['type']] = array(); + } + if (isset($dep['name'])) { + $deps[$dep['type']][$dep['name']][] = $dep; + } else { + $deps[$dep['type']][] = $dep; + } + } + do { + if (isset($deps['php'])) { + $php = array(); + if (count($deps['php']) > 1) { + $php = $this->_processPhpDeps($deps['php']); + } else { + if (!isset($deps['php'][0])) { + list($key, $blah) = each ($deps['php']); // stupid buggy versions + $deps['php'] = array($blah[0]); + } + $php = $this->_processDep($deps['php'][0]); + if (!$php) { + break; // poor mans throw + } + } + $release['dependencies'][$arr]['php'] = $php; + } + } while (false); + do { + if (isset($deps['pkg'])) { + $pkg = array(); + $pkg = $this->_processMultipleDepsName($deps['pkg']); + if (!$pkg) { + break; // poor mans throw + } + $release['dependencies'][$arr]['package'] = $pkg; + } + } while (false); + do { + if (isset($deps['ext'])) { + $pkg = array(); + $pkg = $this->_processMultipleDepsName($deps['ext']); + $release['dependencies'][$arr]['extension'] = $pkg; + } + } while (false); + // skip sapi - it's not supported so nobody will have used it + // skip os - it's not supported in 1.0 + } + } + if (isset($release['dependencies']['required'])) { + $release['dependencies']['required'] = + array_merge($peardep, $release['dependencies']['required']); + } else { + $release['dependencies']['required'] = $peardep; + } + if (!isset($release['dependencies']['required']['php'])) { + $release['dependencies']['required']['php'] = + array('min' => '4.0.0'); + } + $order = array(); + $bewm = $release['dependencies']['required']; + $order['php'] = $bewm['php']; + $order['pearinstaller'] = $bewm['pearinstaller']; + isset($bewm['package']) ? $order['package'] = $bewm['package'] :0; + isset($bewm['extension']) ? $order['extension'] = $bewm['extension'] :0; + $release['dependencies']['required'] = $order; + } + + /** + * @param array + * @access private + */ + function _convertFilelist2_0(&$package) + { + $ret = array('dir' => + array( + 'attribs' => array('name' => '/'), + 'file' => array() + ) + ); + $package['platform'] = + $package['install-as'] = array(); + $this->_isExtension = false; + foreach ($this->_packagefile->getFilelist() as $name => $file) { + $file['name'] = $name; + if (isset($file['role']) && $file['role'] == 'src') { + $this->_isExtension = true; + } + if (isset($file['replacements'])) { + $repl = $file['replacements']; + unset($file['replacements']); + } else { + unset($repl); + } + if (isset($file['install-as'])) { + $package['install-as'][$name] = $file['install-as']; + unset($file['install-as']); + } + if (isset($file['platform'])) { + $package['platform'][$name] = $file['platform']; + unset($file['platform']); + } + $file = array('attribs' => $file); + if (isset($repl)) { + foreach ($repl as $replace ) { + $file['tasks:replace'][] = array('attribs' => $replace); + } + if (count($repl) == 1) { + $file['tasks:replace'] = $file['tasks:replace'][0]; + } + } + $ret['dir']['file'][] = $file; + } + return $ret; + } + + /** + * Post-process special files with install-as/platform attributes and + * make the release tag. + * + * This complex method follows this work-flow to create the release tags: + * + *
    +     * - if any install-as/platform exist, create a generic release and fill it with
    +     *   o  tags for 
    +     *   o  tags for 
    +     *   o  tags for 
    +     *   o  tags for 
    +     * - create a release for each platform encountered and fill with
    +     *   o  tags for 
    +     *   o  tags for 
    +     *   o  tags for 
    +     *   o  tags for 
    +     *   o  tags for 
    +     *   o  tags for 
    +     *   o  tags for 
    +     * 
    + * + * It does this by accessing the $package parameter, which contains an array with + * indices: + * + * - platform: mapping of file => OS the file should be installed on + * - install-as: mapping of file => installed name + * - osmap: mapping of OS => list of files that should be installed + * on that OS + * - notosmap: mapping of OS => list of files that should not be + * installed on that OS + * + * @param array + * @param array + * @access private + */ + function _convertRelease2_0(&$release, $package) + { + //- if any install-as/platform exist, create a generic release and fill it with + if (count($package['platform']) || count($package['install-as'])) { + $generic = array(); + $genericIgnore = array(); + foreach ($package['install-as'] as $file => $as) { + //o tags for + if (!isset($package['platform'][$file])) { + $generic[] = $file; + continue; + } + //o tags for + if (isset($package['platform'][$file]) && + $package['platform'][$file]{0} == '!') { + $generic[] = $file; + continue; + } + //o tags for + if (isset($package['platform'][$file]) && + $package['platform'][$file]{0} != '!') { + $genericIgnore[] = $file; + continue; + } + } + foreach ($package['platform'] as $file => $platform) { + if (isset($package['install-as'][$file])) { + continue; + } + if ($platform{0} != '!') { + //o tags for + $genericIgnore[] = $file; + } + } + if (count($package['platform'])) { + $oses = $notplatform = $platform = array(); + foreach ($package['platform'] as $file => $os) { + // get a list of oses + if ($os{0} == '!') { + if (isset($oses[substr($os, 1)])) { + continue; + } + $oses[substr($os, 1)] = count($oses); + } else { + if (isset($oses[$os])) { + continue; + } + $oses[$os] = count($oses); + } + } + //- create a release for each platform encountered and fill with + foreach ($oses as $os => $releaseNum) { + $release[$releaseNum]['installconditions']['os']['name'] = $os; + $release[$releaseNum]['filelist'] = array('install' => array(), + 'ignore' => array()); + foreach ($package['install-as'] as $file => $as) { + //o tags for + if (!isset($package['platform'][$file])) { + $release[$releaseNum]['filelist']['install'][] = + array( + 'attribs' => array( + 'name' => $file, + 'as' => $as, + ), + ); + continue; + } + //o tags for + // + if (isset($package['platform'][$file]) && + $package['platform'][$file] == $os) { + $release[$releaseNum]['filelist']['install'][] = + array( + 'attribs' => array( + 'name' => $file, + 'as' => $as, + ), + ); + continue; + } + //o tags for + // + if (isset($package['platform'][$file]) && + $package['platform'][$file] != "!$os" && + $package['platform'][$file]{0} == '!') { + $release[$releaseNum]['filelist']['install'][] = + array( + 'attribs' => array( + 'name' => $file, + 'as' => $as, + ), + ); + continue; + } + //o tags for + // + if (isset($package['platform'][$file]) && + $package['platform'][$file] == "!$os") { + $release[$releaseNum]['filelist']['ignore'][] = + array( + 'attribs' => array( + 'name' => $file, + ), + ); + continue; + } + //o tags for + // + if (isset($package['platform'][$file]) && + $package['platform'][$file]{0} != '!' && + $package['platform'][$file] != $os) { + $release[$releaseNum]['filelist']['ignore'][] = + array( + 'attribs' => array( + 'name' => $file, + ), + ); + continue; + } + } + foreach ($package['platform'] as $file => $platform) { + if (isset($package['install-as'][$file])) { + continue; + } + //o tags for + if ($platform == "!$os") { + $release[$releaseNum]['filelist']['ignore'][] = + array( + 'attribs' => array( + 'name' => $file, + ), + ); + continue; + } + //o tags for + if ($platform{0} != '!' && $platform != $os) { + $release[$releaseNum]['filelist']['ignore'][] = + array( + 'attribs' => array( + 'name' => $file, + ), + ); + } + } + if (!count($release[$releaseNum]['filelist']['install'])) { + unset($release[$releaseNum]['filelist']['install']); + } + if (!count($release[$releaseNum]['filelist']['ignore'])) { + unset($release[$releaseNum]['filelist']['ignore']); + } + } + if (count($generic) || count($genericIgnore)) { + $release[count($oses)] = array(); + if (count($generic)) { + foreach ($generic as $file) { + if (isset($package['install-as'][$file])) { + $installas = $package['install-as'][$file]; + } else { + $installas = $file; + } + $release[count($oses)]['filelist']['install'][] = + array( + 'attribs' => array( + 'name' => $file, + 'as' => $installas, + ) + ); + } + } + if (count($genericIgnore)) { + foreach ($genericIgnore as $file) { + $release[count($oses)]['filelist']['ignore'][] = + array( + 'attribs' => array( + 'name' => $file, + ) + ); + } + } + } + // cleanup + foreach ($release as $i => $rel) { + if (isset($rel['filelist']['install']) && + count($rel['filelist']['install']) == 1) { + $release[$i]['filelist']['install'] = + $release[$i]['filelist']['install'][0]; + } + if (isset($rel['filelist']['ignore']) && + count($rel['filelist']['ignore']) == 1) { + $release[$i]['filelist']['ignore'] = + $release[$i]['filelist']['ignore'][0]; + } + } + if (count($release) == 1) { + $release = $release[0]; + } + } else { + // no platform atts, but some install-as atts + foreach ($package['install-as'] as $file => $value) { + $release['filelist']['install'][] = + array( + 'attribs' => array( + 'name' => $file, + 'as' => $value + ) + ); + } + if (count($release['filelist']['install']) == 1) { + $release['filelist']['install'] = $release['filelist']['install'][0]; + } + } + } + } + + /** + * @param array + * @return array + * @access private + */ + function _processDep($dep) + { + if ($dep['type'] == 'php') { + if ($dep['rel'] == 'has') { + // come on - everyone has php! + return false; + } + } + $php = array(); + if ($dep['type'] != 'php') { + $php['name'] = $dep['name']; + if ($dep['type'] == 'pkg') { + $php['channel'] = 'pear.php.net'; + } + } + switch ($dep['rel']) { + case 'gt' : + $php['min'] = $dep['version']; + $php['exclude'] = $dep['version']; + break; + case 'ge' : + if (!isset($dep['version'])) { + if ($dep['type'] == 'php') { + if (isset($dep['name'])) { + $dep['version'] = $dep['name']; + } + } + } + $php['min'] = $dep['version']; + break; + case 'lt' : + $php['max'] = $dep['version']; + $php['exclude'] = $dep['version']; + break; + case 'le' : + $php['max'] = $dep['version']; + break; + case 'eq' : + $php['min'] = $dep['version']; + $php['max'] = $dep['version']; + break; + case 'ne' : + $php['exclude'] = $dep['version']; + break; + case 'not' : + $php['conflicts'] = 'yes'; + break; + } + return $php; + } + + /** + * @param array + * @return array + */ + function _processPhpDeps($deps) + { + $test = array(); + foreach ($deps as $dep) { + $test[] = $this->_processDep($dep); + } + $min = array(); + $max = array(); + foreach ($test as $dep) { + if (!$dep) { + continue; + } + if (isset($dep['min'])) { + $min[$dep['min']] = count($min); + } + if (isset($dep['max'])) { + $max[$dep['max']] = count($max); + } + } + if (count($min) > 0) { + uksort($min, 'version_compare'); + } + if (count($max) > 0) { + uksort($max, 'version_compare'); + } + if (count($min)) { + // get the highest minimum + $a = array_flip($min); + $min = array_pop($a); + } else { + $min = false; + } + if (count($max)) { + // get the lowest maximum + $a = array_flip($max); + $max = array_shift($a); + } else { + $max = false; + } + if ($min) { + $php['min'] = $min; + } + if ($max) { + $php['max'] = $max; + } + $exclude = array(); + foreach ($test as $dep) { + if (!isset($dep['exclude'])) { + continue; + } + $exclude[] = $dep['exclude']; + } + if (count($exclude)) { + $php['exclude'] = $exclude; + } + return $php; + } + + /** + * process multiple dependencies that have a name, like package deps + * @param array + * @return array + * @access private + */ + function _processMultipleDepsName($deps) + { + $ret = $tests = array(); + foreach ($deps as $name => $dep) { + foreach ($dep as $d) { + $tests[$name][] = $this->_processDep($d); + } + } + + foreach ($tests as $name => $test) { + $max = $min = $php = array(); + $php['name'] = $name; + foreach ($test as $dep) { + if (!$dep) { + continue; + } + if (isset($dep['channel'])) { + $php['channel'] = 'pear.php.net'; + } + if (isset($dep['conflicts']) && $dep['conflicts'] == 'yes') { + $php['conflicts'] = 'yes'; + } + if (isset($dep['min'])) { + $min[$dep['min']] = count($min); + } + if (isset($dep['max'])) { + $max[$dep['max']] = count($max); + } + } + if (count($min) > 0) { + uksort($min, 'version_compare'); + } + if (count($max) > 0) { + uksort($max, 'version_compare'); + } + if (count($min)) { + // get the highest minimum + $a = array_flip($min); + $min = array_pop($a); + } else { + $min = false; + } + if (count($max)) { + // get the lowest maximum + $a = array_flip($max); + $max = array_shift($a); + } else { + $max = false; + } + if ($min) { + $php['min'] = $min; + } + if ($max) { + $php['max'] = $max; + } + $exclude = array(); + foreach ($test as $dep) { + if (!isset($dep['exclude'])) { + continue; + } + $exclude[] = $dep['exclude']; + } + if (count($exclude)) { + $php['exclude'] = $exclude; + } + $ret[] = $php; + } + return $ret; + } +} +?> diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/PackageFile/Generator/v2.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/PackageFile/Generator/v2.php new file mode 100644 index 0000000..24e89f3 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/PackageFile/Generator/v2.php @@ -0,0 +1,886 @@ + + * @author Stephan Schmidt (original XML_Serializer code) + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ +/** + * file/dir manipulation routines + */ +require_once 'System.php'; +require_once 'XML/Util.php'; + +/** + * This class converts a PEAR_PackageFile_v2 object into any output format. + * + * Supported output formats include array, XML string (using S. Schmidt's + * XML_Serializer, slightly customized) + * @category pear + * @package PEAR + * @author Greg Beaver + * @author Stephan Schmidt (original XML_Serializer code) + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_PackageFile_Generator_v2 +{ + /** + * default options for the serialization + * @access private + * @var array $_defaultOptions + */ + var $_defaultOptions = array( + 'indent' => ' ', // string used for indentation + 'linebreak' => "\n", // string used for newlines + 'typeHints' => false, // automatically add type hin attributes + 'addDecl' => true, // add an XML declaration + 'defaultTagName' => 'XML_Serializer_Tag', // tag used for indexed arrays or invalid names + 'classAsTagName' => false, // use classname for objects in indexed arrays + 'keyAttribute' => '_originalKey', // attribute where original key is stored + 'typeAttribute' => '_type', // attribute for type (only if typeHints => true) + 'classAttribute' => '_class', // attribute for class of objects (only if typeHints => true) + 'scalarAsAttributes' => false, // scalar values (strings, ints,..) will be serialized as attribute + 'prependAttributes' => '', // prepend string for attributes + 'indentAttributes' => false, // indent the attributes, if set to '_auto', it will indent attributes so they all start at the same column + 'mode' => 'simplexml', // use 'simplexml' to use parent name as tagname if transforming an indexed array + 'addDoctype' => false, // add a doctype declaration + 'doctype' => null, // supply a string or an array with id and uri ({@see XML_Util::getDoctypeDeclaration()} + 'rootName' => 'package', // name of the root tag + 'rootAttributes' => array( + 'version' => '2.0', + 'xmlns' => 'http://pear.php.net/dtd/package-2.0', + 'xmlns:tasks' => 'http://pear.php.net/dtd/tasks-1.0', + 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', + 'xsi:schemaLocation' => 'http://pear.php.net/dtd/tasks-1.0 +http://pear.php.net/dtd/tasks-1.0.xsd +http://pear.php.net/dtd/package-2.0 +http://pear.php.net/dtd/package-2.0.xsd', + ), // attributes of the root tag + 'attributesArray' => 'attribs', // all values in this key will be treated as attributes + 'contentName' => '_content', // this value will be used directly as content, instead of creating a new tag, may only be used in conjunction with attributesArray + 'beautifyFilelist' => false, + 'encoding' => 'UTF-8', + ); + + /** + * options for the serialization + * @access private + * @var array $options + */ + var $options = array(); + + /** + * current tag depth + * @var integer $_tagDepth + */ + var $_tagDepth = 0; + + /** + * serilialized representation of the data + * @var string $_serializedData + */ + var $_serializedData = null; + /** + * @var PEAR_PackageFile_v2 + */ + var $_packagefile; + /** + * @param PEAR_PackageFile_v2 + */ + function __construct(&$packagefile) + { + $this->_packagefile = &$packagefile; + if (isset($this->_packagefile->encoding)) { + $this->_defaultOptions['encoding'] = $this->_packagefile->encoding; + } + } + + /** + * @return string + */ + function getPackagerVersion() + { + return '1.10.1'; + } + + /** + * @param PEAR_Packager + * @param bool generate a .tgz or a .tar + * @param string|null temporary directory to package in + */ + function toTgz(&$packager, $compress = true, $where = null) + { + $a = null; + return $this->toTgz2($packager, $a, $compress, $where); + } + + /** + * Package up both a package.xml and package2.xml for the same release + * @param PEAR_Packager + * @param PEAR_PackageFile_v1 + * @param bool generate a .tgz or a .tar + * @param string|null temporary directory to package in + */ + function toTgz2(&$packager, &$pf1, $compress = true, $where = null) + { + require_once 'Archive/Tar.php'; + if (!$this->_packagefile->isEquivalent($pf1)) { + return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: "' . + basename($pf1->getPackageFile()) . + '" is not equivalent to "' . basename($this->_packagefile->getPackageFile()) + . '"'); + } + + if ($where === null) { + if (!($where = System::mktemp(array('-d')))) { + return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: mktemp failed'); + } + } elseif (!@System::mkDir(array('-p', $where))) { + return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: "' . $where . '" could' . + ' not be created'); + } + + $file = $where . DIRECTORY_SEPARATOR . 'package.xml'; + if (file_exists($file) && !is_file($file)) { + return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: unable to save package.xml as' . + ' "' . $file .'"'); + } + + if (!$this->_packagefile->validate(PEAR_VALIDATE_PACKAGING)) { + return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: invalid package.xml'); + } + + $ext = $compress ? '.tgz' : '.tar'; + $pkgver = $this->_packagefile->getPackage() . '-' . $this->_packagefile->getVersion(); + $dest_package = getcwd() . DIRECTORY_SEPARATOR . $pkgver . $ext; + if (file_exists($dest_package) && !is_file($dest_package)) { + return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: cannot create tgz file "' . + $dest_package . '"'); + } + + $pkgfile = $this->_packagefile->getPackageFile(); + if (!$pkgfile) { + return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: package file object must ' . + 'be created from a real file'); + } + + $pkgdir = dirname(realpath($pkgfile)); + $pkgfile = basename($pkgfile); + + // {{{ Create the package file list + $filelist = array(); + $i = 0; + $this->_packagefile->flattenFilelist(); + $contents = $this->_packagefile->getContents(); + if (isset($contents['bundledpackage'])) { // bundles of packages + $contents = $contents['bundledpackage']; + if (!isset($contents[0])) { + $contents = array($contents); + } + + $packageDir = $where; + foreach ($contents as $i => $package) { + $fname = $package; + $file = $pkgdir . DIRECTORY_SEPARATOR . $fname; + if (!file_exists($file)) { + return $packager->raiseError("File does not exist: $fname"); + } + + $tfile = $packageDir . DIRECTORY_SEPARATOR . $fname; + System::mkdir(array('-p', dirname($tfile))); + copy($file, $tfile); + $filelist[$i++] = $tfile; + $packager->log(2, "Adding package $fname"); + } + } else { // normal packages + $contents = $contents['dir']['file']; + if (!isset($contents[0])) { + $contents = array($contents); + } + + $packageDir = $where; + foreach ($contents as $i => $file) { + $fname = $file['attribs']['name']; + $atts = $file['attribs']; + $orig = $file; + $file = $pkgdir . DIRECTORY_SEPARATOR . $fname; + if (!file_exists($file)) { + return $packager->raiseError("File does not exist: $fname"); + } + + $origperms = fileperms($file); + $tfile = $packageDir . DIRECTORY_SEPARATOR . $fname; + unset($orig['attribs']); + if (count($orig)) { // file with tasks + // run any package-time tasks + $contents = file_get_contents($file); + foreach ($orig as $tag => $raw) { + $tag = str_replace( + array($this->_packagefile->getTasksNs() . ':', '-'), + array('', '_'), $tag); + $task = "PEAR_Task_$tag"; + $task = new $task($this->_packagefile->_config, + $this->_packagefile->_logger, + PEAR_TASK_PACKAGE); + $task->init($raw, $atts, null); + $res = $task->startSession($this->_packagefile, $contents, $tfile); + if (!$res) { + continue; // skip this task + } + + if (PEAR::isError($res)) { + return $res; + } + + $contents = $res; // save changes + System::mkdir(array('-p', dirname($tfile))); + $wp = fopen($tfile, "wb"); + fwrite($wp, $contents); + fclose($wp); + } + } + + if (!file_exists($tfile)) { + System::mkdir(array('-p', dirname($tfile))); + copy($file, $tfile); + } + + chmod($tfile, $origperms); + $filelist[$i++] = $tfile; + $this->_packagefile->setFileAttribute($fname, 'md5sum', md5_file($tfile), $i - 1); + $packager->log(2, "Adding file $fname"); + } + } + // }}} + + $name = $pf1 !== null ? 'package2.xml' : 'package.xml'; + $packagexml = $this->toPackageFile($where, PEAR_VALIDATE_PACKAGING, $name); + if ($packagexml) { + $tar = new Archive_Tar($dest_package, $compress); + $tar->setErrorHandling(PEAR_ERROR_RETURN); // XXX Don't print errors + // ----- Creates with the package.xml file + $ok = $tar->createModify(array($packagexml), '', $where); + if (PEAR::isError($ok)) { + return $packager->raiseError($ok); + } elseif (!$ok) { + return $packager->raiseError('PEAR_Packagefile_v2::toTgz(): adding ' . $name . + ' failed'); + } + + // ----- Add the content of the package + if (!$tar->addModify($filelist, $pkgver, $where)) { + return $packager->raiseError( + 'PEAR_Packagefile_v2::toTgz(): tarball creation failed'); + } + + // add the package.xml version 1.0 + if ($pf1 !== null) { + $pfgen = &$pf1->getDefaultGenerator(); + $packagexml1 = $pfgen->toPackageFile($where, PEAR_VALIDATE_PACKAGING, 'package.xml', true); + if (!$tar->addModify(array($packagexml1), '', $where)) { + return $packager->raiseError( + 'PEAR_Packagefile_v2::toTgz(): adding package.xml failed'); + } + } + + return $dest_package; + } + } + + function toPackageFile($where = null, $state = PEAR_VALIDATE_NORMAL, $name = 'package.xml') + { + if (!$this->_packagefile->validate($state)) { + return PEAR::raiseError('PEAR_Packagefile_v2::toPackageFile: invalid package.xml', + null, null, null, $this->_packagefile->getValidationWarnings()); + } + + if ($where === null) { + if (!($where = System::mktemp(array('-d')))) { + return PEAR::raiseError('PEAR_Packagefile_v2::toPackageFile: mktemp failed'); + } + } elseif (!@System::mkDir(array('-p', $where))) { + return PEAR::raiseError('PEAR_Packagefile_v2::toPackageFile: "' . $where . '" could' . + ' not be created'); + } + + $newpkgfile = $where . DIRECTORY_SEPARATOR . $name; + $np = @fopen($newpkgfile, 'wb'); + if (!$np) { + return PEAR::raiseError('PEAR_Packagefile_v2::toPackageFile: unable to save ' . + "$name as $newpkgfile"); + } + fwrite($np, $this->toXml($state)); + fclose($np); + return $newpkgfile; + } + + function &toV2() + { + return $this->_packagefile; + } + + /** + * Return an XML document based on the package info (as returned + * by the PEAR_Common::infoFrom* methods). + * + * @return string XML data + */ + function toXml($state = PEAR_VALIDATE_NORMAL, $options = array()) + { + $this->_packagefile->setDate(date('Y-m-d')); + $this->_packagefile->setTime(date('H:i:s')); + if (!$this->_packagefile->validate($state)) { + return false; + } + + if (is_array($options)) { + $this->options = array_merge($this->_defaultOptions, $options); + } else { + $this->options = $this->_defaultOptions; + } + + $arr = $this->_packagefile->getArray(); + if (isset($arr['filelist'])) { + unset($arr['filelist']); + } + + if (isset($arr['_lastversion'])) { + unset($arr['_lastversion']); + } + + // Fix the notes a little bit + if (isset($arr['notes'])) { + // This trims out the indenting, needs fixing + $arr['notes'] = "\n" . trim($arr['notes']) . "\n"; + } + + if (isset($arr['changelog']) && !empty($arr['changelog'])) { + // Fix for inconsistency how the array is filled depending on the changelog release amount + if (!isset($arr['changelog']['release'][0])) { + $release = $arr['changelog']['release']; + unset($arr['changelog']['release']); + + $arr['changelog']['release'] = array(); + $arr['changelog']['release'][0] = $release; + } + + foreach (array_keys($arr['changelog']['release']) as $key) { + $c =& $arr['changelog']['release'][$key]; + if (isset($c['notes'])) { + // This trims out the indenting, needs fixing + $c['notes'] = "\n" . trim($c['notes']) . "\n"; + } + } + } + + if ($state ^ PEAR_VALIDATE_PACKAGING && !isset($arr['bundle'])) { + $use = $this->_recursiveXmlFilelist($arr['contents']['dir']['file']); + unset($arr['contents']['dir']['file']); + if (isset($use['dir'])) { + $arr['contents']['dir']['dir'] = $use['dir']; + } + if (isset($use['file'])) { + $arr['contents']['dir']['file'] = $use['file']; + } + $this->options['beautifyFilelist'] = true; + } + + $arr['attribs']['packagerversion'] = '1.10.1'; + if ($this->serialize($arr, $options)) { + return $this->_serializedData . "\n"; + } + + return false; + } + + + function _recursiveXmlFilelist($list) + { + $dirs = array(); + if (isset($list['attribs'])) { + $file = $list['attribs']['name']; + unset($list['attribs']['name']); + $attributes = $list['attribs']; + $this->_addDir($dirs, explode('/', dirname($file)), $file, $attributes); + } else { + foreach ($list as $a) { + $file = $a['attribs']['name']; + $attributes = $a['attribs']; + unset($a['attribs']); + $this->_addDir($dirs, explode('/', dirname($file)), $file, $attributes, $a); + } + } + $this->_formatDir($dirs); + $this->_deFormat($dirs); + return $dirs; + } + + function _addDir(&$dirs, $dir, $file = null, $attributes = null, $tasks = null) + { + if (!$tasks) { + $tasks = array(); + } + if ($dir == array() || $dir == array('.')) { + $dirs['file'][basename($file)] = $tasks; + $attributes['name'] = basename($file); + $dirs['file'][basename($file)]['attribs'] = $attributes; + return; + } + $curdir = array_shift($dir); + if (!isset($dirs['dir'][$curdir])) { + $dirs['dir'][$curdir] = array(); + } + $this->_addDir($dirs['dir'][$curdir], $dir, $file, $attributes, $tasks); + } + + function _formatDir(&$dirs) + { + if (!count($dirs)) { + return array(); + } + $newdirs = array(); + if (isset($dirs['dir'])) { + $newdirs['dir'] = $dirs['dir']; + } + if (isset($dirs['file'])) { + $newdirs['file'] = $dirs['file']; + } + $dirs = $newdirs; + if (isset($dirs['dir'])) { + uksort($dirs['dir'], 'strnatcasecmp'); + foreach ($dirs['dir'] as $dir => $contents) { + $this->_formatDir($dirs['dir'][$dir]); + } + } + if (isset($dirs['file'])) { + uksort($dirs['file'], 'strnatcasecmp'); + }; + } + + function _deFormat(&$dirs) + { + if (!count($dirs)) { + return array(); + } + $newdirs = array(); + if (isset($dirs['dir'])) { + foreach ($dirs['dir'] as $dir => $contents) { + $newdir = array(); + $newdir['attribs']['name'] = $dir; + $this->_deFormat($contents); + foreach ($contents as $tag => $val) { + $newdir[$tag] = $val; + } + $newdirs['dir'][] = $newdir; + } + if (count($newdirs['dir']) == 1) { + $newdirs['dir'] = $newdirs['dir'][0]; + } + } + if (isset($dirs['file'])) { + foreach ($dirs['file'] as $name => $file) { + $newdirs['file'][] = $file; + } + if (count($newdirs['file']) == 1) { + $newdirs['file'] = $newdirs['file'][0]; + } + } + $dirs = $newdirs; + } + + /** + * reset all options to default options + * + * @access public + * @see setOption(), XML_Unserializer() + */ + function resetOptions() + { + $this->options = $this->_defaultOptions; + } + + /** + * set an option + * + * You can use this method if you do not want to set all options in the constructor + * + * @access public + * @see resetOption(), XML_Serializer() + */ + function setOption($name, $value) + { + $this->options[$name] = $value; + } + + /** + * sets several options at once + * + * You can use this method if you do not want to set all options in the constructor + * + * @access public + * @see resetOption(), XML_Unserializer(), setOption() + */ + function setOptions($options) + { + $this->options = array_merge($this->options, $options); + } + + /** + * serialize data + * + * @access public + * @param mixed $data data to serialize + * @return boolean true on success, pear error on failure + */ + function serialize($data, $options = null) + { + // if options have been specified, use them instead + // of the previously defined ones + if (is_array($options)) { + $optionsBak = $this->options; + if (isset($options['overrideOptions']) && $options['overrideOptions'] == true) { + $this->options = array_merge($this->_defaultOptions, $options); + } else { + $this->options = array_merge($this->options, $options); + } + } else { + $optionsBak = null; + } + + // start depth is zero + $this->_tagDepth = 0; + $this->_serializedData = ''; + // serialize an array + if (is_array($data)) { + $tagName = isset($this->options['rootName']) ? $this->options['rootName'] : 'array'; + $this->_serializedData .= $this->_serializeArray($data, $tagName, $this->options['rootAttributes']); + } + + // add doctype declaration + if ($this->options['addDoctype'] === true) { + $this->_serializedData = XML_Util::getDoctypeDeclaration($tagName, $this->options['doctype']) + . $this->options['linebreak'] + . $this->_serializedData; + } + + // build xml declaration + if ($this->options['addDecl']) { + $atts = array(); + $encoding = isset($this->options['encoding']) ? $this->options['encoding'] : null; + $this->_serializedData = XML_Util::getXMLDeclaration('1.0', $encoding) + . $this->options['linebreak'] + . $this->_serializedData; + } + + + if ($optionsBak !== null) { + $this->options = $optionsBak; + } + + return true; + } + + /** + * get the result of the serialization + * + * @access public + * @return string serialized XML + */ + function getSerializedData() + { + if ($this->_serializedData === null) { + return $this->raiseError('No serialized data available. Use XML_Serializer::serialize() first.', XML_SERIALIZER_ERROR_NO_SERIALIZATION); + } + return $this->_serializedData; + } + + /** + * serialize any value + * + * This method checks for the type of the value and calls the appropriate method + * + * @access private + * @param mixed $value + * @param string $tagName + * @param array $attributes + * @return string + */ + function _serializeValue($value, $tagName = null, $attributes = array()) + { + if (is_array($value)) { + $xml = $this->_serializeArray($value, $tagName, $attributes); + } elseif (is_object($value)) { + $xml = $this->_serializeObject($value, $tagName); + } else { + $tag = array( + 'qname' => $tagName, + 'attributes' => $attributes, + 'content' => $value + ); + $xml = $this->_createXMLTag($tag); + } + return $xml; + } + + /** + * serialize an array + * + * @access private + * @param array $array array to serialize + * @param string $tagName name of the root tag + * @param array $attributes attributes for the root tag + * @return string $string serialized data + * @uses XML_Util::isValidName() to check, whether key has to be substituted + */ + function _serializeArray(&$array, $tagName = null, $attributes = array()) + { + $_content = null; + + /** + * check for special attributes + */ + if ($this->options['attributesArray'] !== null) { + if (isset($array[$this->options['attributesArray']])) { + $attributes = $array[$this->options['attributesArray']]; + unset($array[$this->options['attributesArray']]); + } + /** + * check for special content + */ + if ($this->options['contentName'] !== null) { + if (isset($array[$this->options['contentName']])) { + $_content = $array[$this->options['contentName']]; + unset($array[$this->options['contentName']]); + } + } + } + + /* + * if mode is set to simpleXML, check whether + * the array is associative or indexed + */ + if (is_array($array) && $this->options['mode'] == 'simplexml') { + $indexed = true; + if (!count($array)) { + $indexed = false; + } + foreach ($array as $key => $val) { + if (!is_int($key)) { + $indexed = false; + break; + } + } + + if ($indexed && $this->options['mode'] == 'simplexml') { + $string = ''; + foreach ($array as $key => $val) { + if ($this->options['beautifyFilelist'] && $tagName == 'dir') { + if (!isset($this->_curdir)) { + $this->_curdir = ''; + } + $savedir = $this->_curdir; + if (isset($val['attribs'])) { + if ($val['attribs']['name'] == '/') { + $this->_curdir = '/'; + } else { + if ($this->_curdir == '/') { + $this->_curdir = ''; + } + $this->_curdir .= '/' . $val['attribs']['name']; + } + } + } + $string .= $this->_serializeValue( $val, $tagName, $attributes); + if ($this->options['beautifyFilelist'] && $tagName == 'dir') { + $string .= ' '; + if (empty($savedir)) { + unset($this->_curdir); + } else { + $this->_curdir = $savedir; + } + } + + $string .= $this->options['linebreak']; + // do indentation + if ($this->options['indent'] !== null && $this->_tagDepth > 0) { + $string .= str_repeat($this->options['indent'], $this->_tagDepth); + } + } + return rtrim($string); + } + } + + if ($this->options['scalarAsAttributes'] === true) { + foreach ($array as $key => $value) { + if (is_scalar($value) && (XML_Util::isValidName($key) === true)) { + unset($array[$key]); + $attributes[$this->options['prependAttributes'].$key] = $value; + } + } + } + + // check for empty array => create empty tag + if (empty($array)) { + $tag = array( + 'qname' => $tagName, + 'content' => $_content, + 'attributes' => $attributes + ); + + } else { + $this->_tagDepth++; + $tmp = $this->options['linebreak']; + foreach ($array as $key => $value) { + // do indentation + if ($this->options['indent'] !== null && $this->_tagDepth > 0) { + $tmp .= str_repeat($this->options['indent'], $this->_tagDepth); + } + + // copy key + $origKey = $key; + // key cannot be used as tagname => use default tag + $valid = XML_Util::isValidName($key); + if (PEAR::isError($valid)) { + if ($this->options['classAsTagName'] && is_object($value)) { + $key = get_class($value); + } else { + $key = $this->options['defaultTagName']; + } + } + $atts = array(); + if ($this->options['typeHints'] === true) { + $atts[$this->options['typeAttribute']] = gettype($value); + if ($key !== $origKey) { + $atts[$this->options['keyAttribute']] = (string)$origKey; + } + + } + if ($this->options['beautifyFilelist'] && $key == 'dir') { + if (!isset($this->_curdir)) { + $this->_curdir = ''; + } + $savedir = $this->_curdir; + if (isset($value['attribs'])) { + if ($value['attribs']['name'] == '/') { + $this->_curdir = '/'; + } else { + $this->_curdir .= '/' . $value['attribs']['name']; + } + } + } + + if (is_string($value) && $value && ($value{strlen($value) - 1} == "\n")) { + $value .= str_repeat($this->options['indent'], $this->_tagDepth); + } + $tmp .= $this->_createXMLTag(array( + 'qname' => $key, + 'attributes' => $atts, + 'content' => $value ) + ); + if ($this->options['beautifyFilelist'] && $key == 'dir') { + if (isset($value['attribs'])) { + $tmp .= ' '; + if (empty($savedir)) { + unset($this->_curdir); + } else { + $this->_curdir = $savedir; + } + } + } + $tmp .= $this->options['linebreak']; + } + + $this->_tagDepth--; + if ($this->options['indent']!==null && $this->_tagDepth>0) { + $tmp .= str_repeat($this->options['indent'], $this->_tagDepth); + } + + if (trim($tmp) === '') { + $tmp = null; + } + + $tag = array( + 'qname' => $tagName, + 'content' => $tmp, + 'attributes' => $attributes + ); + } + if ($this->options['typeHints'] === true) { + if (!isset($tag['attributes'][$this->options['typeAttribute']])) { + $tag['attributes'][$this->options['typeAttribute']] = 'array'; + } + } + + $string = $this->_createXMLTag($tag, false); + return $string; + } + + /** + * create a tag from an array + * this method awaits an array in the following format + * array( + * 'qname' => $tagName, + * 'attributes' => array(), + * 'content' => $content, // optional + * 'namespace' => $namespace // optional + * 'namespaceUri' => $namespaceUri // optional + * ) + * + * @access private + * @param array $tag tag definition + * @param boolean $replaceEntities whether to replace XML entities in content or not + * @return string $string XML tag + */ + function _createXMLTag($tag, $replaceEntities = true) + { + if ($this->options['indentAttributes'] !== false) { + $multiline = true; + $indent = str_repeat($this->options['indent'], $this->_tagDepth); + + if ($this->options['indentAttributes'] == '_auto') { + $indent .= str_repeat(' ', (strlen($tag['qname'])+2)); + + } else { + $indent .= $this->options['indentAttributes']; + } + } else { + $indent = $multiline = false; + } + + if (is_array($tag['content'])) { + if (empty($tag['content'])) { + $tag['content'] = ''; + } + } elseif(is_scalar($tag['content']) && (string)$tag['content'] == '') { + $tag['content'] = ''; + } + + if (is_scalar($tag['content']) || is_null($tag['content'])) { + if ($replaceEntities === true) { + $replaceEntities = XML_UTIL_ENTITIES_XML; + } + + $tag = XML_Util::createTagFromArray($tag, $replaceEntities, $multiline, $indent, $this->options['linebreak']); + } elseif (is_array($tag['content'])) { + $tag = $this->_serializeArray($tag['content'], $tag['qname'], $tag['attributes']); + } elseif (is_object($tag['content'])) { + $tag = $this->_serializeObject($tag['content'], $tag['qname'], $tag['attributes']); + } elseif (is_resource($tag['content'])) { + settype($tag['content'], 'string'); + $tag = XML_Util::createTagFromArray($tag, $replaceEntities); + } + return $tag; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/PackageFile/Parser/v1.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/PackageFile/Parser/v1.php new file mode 100644 index 0000000..8e08e0b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/PackageFile/Parser/v1.php @@ -0,0 +1,458 @@ + + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ +/** + * package.xml abstraction class + */ +require_once 'PEAR/PackageFile/v1.php'; +/** + * Parser for package.xml version 1.0 + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: @PEAR-VER@ + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_PackageFile_Parser_v1 +{ + var $_registry; + var $_config; + var $_logger; + /** + * BC hack to allow PEAR_Common::infoFromString() to sort of + * work with the version 2.0 format - there's no filelist though + * @param PEAR_PackageFile_v2 + */ + function fromV2($packagefile) + { + $info = $packagefile->getArray(true); + $ret = new PEAR_PackageFile_v1; + $ret->fromArray($info['old']); + } + + function setConfig(&$c) + { + $this->_config = &$c; + $this->_registry = &$c->getRegistry(); + } + + function setLogger(&$l) + { + $this->_logger = &$l; + } + + /** + * @param string contents of package.xml file, version 1.0 + * @return bool success of parsing + */ + function &parse($data, $file, $archive = false) + { + if (!extension_loaded('xml')) { + return PEAR::raiseError('Cannot create xml parser for parsing package.xml, no xml extension'); + } + $xp = xml_parser_create(); + if (!$xp) { + $a = &PEAR::raiseError('Cannot create xml parser for parsing package.xml'); + return $a; + } + xml_set_object($xp, $this); + xml_set_element_handler($xp, '_element_start_1_0', '_element_end_1_0'); + xml_set_character_data_handler($xp, '_pkginfo_cdata_1_0'); + xml_parser_set_option($xp, XML_OPTION_CASE_FOLDING, false); + + $this->element_stack = array(); + $this->_packageInfo = array('provides' => array()); + $this->current_element = false; + unset($this->dir_install); + $this->_packageInfo['filelist'] = array(); + $this->filelist =& $this->_packageInfo['filelist']; + $this->dir_names = array(); + $this->in_changelog = false; + $this->d_i = 0; + $this->cdata = ''; + $this->_isValid = true; + + if (!xml_parse($xp, $data, 1)) { + $code = xml_get_error_code($xp); + $line = xml_get_current_line_number($xp); + xml_parser_free($xp); + $a = PEAR::raiseError(sprintf("XML error: %s at line %d", + $str = xml_error_string($code), $line), 2); + return $a; + } + + xml_parser_free($xp); + + $pf = new PEAR_PackageFile_v1; + $pf->setConfig($this->_config); + if (isset($this->_logger)) { + $pf->setLogger($this->_logger); + } + $pf->setPackagefile($file, $archive); + $pf->fromArray($this->_packageInfo); + return $pf; + } + // {{{ _unIndent() + + /** + * Unindent given string + * + * @param string $str The string that has to be unindented. + * @return string + * @access private + */ + function _unIndent($str) + { + // remove leading newlines + $str = preg_replace('/^[\r\n]+/', '', $str); + // find whitespace at the beginning of the first line + $indent_len = strspn($str, " \t"); + $indent = substr($str, 0, $indent_len); + $data = ''; + // remove the same amount of whitespace from following lines + foreach (explode("\n", $str) as $line) { + if (substr($line, 0, $indent_len) == $indent) { + $data .= substr($line, $indent_len) . "\n"; + } elseif (trim(substr($line, 0, $indent_len))) { + $data .= ltrim($line); + } + } + return $data; + } + + // Support for package DTD v1.0: + // {{{ _element_start_1_0() + + /** + * XML parser callback for ending elements. Used for version 1.0 + * packages. + * + * @param resource $xp XML parser resource + * @param string $name name of ending element + * + * @return void + * + * @access private + */ + function _element_start_1_0($xp, $name, $attribs) + { + array_push($this->element_stack, $name); + $this->current_element = $name; + $spos = sizeof($this->element_stack) - 2; + $this->prev_element = ($spos >= 0) ? $this->element_stack[$spos] : ''; + $this->current_attributes = $attribs; + $this->cdata = ''; + switch ($name) { + case 'dir': + if ($this->in_changelog) { + break; + } + if (array_key_exists('name', $attribs) && $attribs['name'] != '/') { + $attribs['name'] = preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'), + $attribs['name']); + if (strrpos($attribs['name'], '/') === strlen($attribs['name']) - 1) { + $attribs['name'] = substr($attribs['name'], 0, + strlen($attribs['name']) - 1); + } + if (strpos($attribs['name'], '/') === 0) { + $attribs['name'] = substr($attribs['name'], 1); + } + $this->dir_names[] = $attribs['name']; + } + if (isset($attribs['baseinstalldir'])) { + $this->dir_install = $attribs['baseinstalldir']; + } + if (isset($attribs['role'])) { + $this->dir_role = $attribs['role']; + } + break; + case 'file': + if ($this->in_changelog) { + break; + } + if (isset($attribs['name'])) { + $path = ''; + if (count($this->dir_names)) { + foreach ($this->dir_names as $dir) { + $path .= $dir . '/'; + } + } + $path .= preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'), + $attribs['name']); + unset($attribs['name']); + $this->current_path = $path; + $this->filelist[$path] = $attribs; + // Set the baseinstalldir only if the file don't have this attrib + if (!isset($this->filelist[$path]['baseinstalldir']) && + isset($this->dir_install)) + { + $this->filelist[$path]['baseinstalldir'] = $this->dir_install; + } + // Set the Role + if (!isset($this->filelist[$path]['role']) && isset($this->dir_role)) { + $this->filelist[$path]['role'] = $this->dir_role; + } + } + break; + case 'replace': + if (!$this->in_changelog) { + $this->filelist[$this->current_path]['replacements'][] = $attribs; + } + break; + case 'maintainers': + $this->_packageInfo['maintainers'] = array(); + $this->m_i = 0; // maintainers array index + break; + case 'maintainer': + // compatibility check + if (!isset($this->_packageInfo['maintainers'])) { + $this->_packageInfo['maintainers'] = array(); + $this->m_i = 0; + } + $this->_packageInfo['maintainers'][$this->m_i] = array(); + $this->current_maintainer =& $this->_packageInfo['maintainers'][$this->m_i]; + break; + case 'changelog': + $this->_packageInfo['changelog'] = array(); + $this->c_i = 0; // changelog array index + $this->in_changelog = true; + break; + case 'release': + if ($this->in_changelog) { + $this->_packageInfo['changelog'][$this->c_i] = array(); + $this->current_release = &$this->_packageInfo['changelog'][$this->c_i]; + } else { + $this->current_release = &$this->_packageInfo; + } + break; + case 'deps': + if (!$this->in_changelog) { + $this->_packageInfo['release_deps'] = array(); + } + break; + case 'dep': + // dependencies array index + if (!$this->in_changelog) { + $this->d_i++; + isset($attribs['type']) ? ($attribs['type'] = strtolower($attribs['type'])) : false; + $this->_packageInfo['release_deps'][$this->d_i] = $attribs; + } + break; + case 'configureoptions': + if (!$this->in_changelog) { + $this->_packageInfo['configure_options'] = array(); + } + break; + case 'configureoption': + if (!$this->in_changelog) { + $this->_packageInfo['configure_options'][] = $attribs; + } + break; + case 'provides': + if (empty($attribs['type']) || empty($attribs['name'])) { + break; + } + $attribs['explicit'] = true; + $this->_packageInfo['provides']["$attribs[type];$attribs[name]"] = $attribs; + break; + case 'package' : + if (isset($attribs['version'])) { + $this->_packageInfo['xsdversion'] = trim($attribs['version']); + } else { + $this->_packageInfo['xsdversion'] = '1.0'; + } + if (isset($attribs['packagerversion'])) { + $this->_packageInfo['packagerversion'] = $attribs['packagerversion']; + } + break; + } + } + + // }}} + // {{{ _element_end_1_0() + + /** + * XML parser callback for ending elements. Used for version 1.0 + * packages. + * + * @param resource $xp XML parser resource + * @param string $name name of ending element + * + * @return void + * + * @access private + */ + function _element_end_1_0($xp, $name) + { + $data = trim($this->cdata); + switch ($name) { + case 'name': + switch ($this->prev_element) { + case 'package': + $this->_packageInfo['package'] = $data; + break; + case 'maintainer': + $this->current_maintainer['name'] = $data; + break; + } + break; + case 'extends' : + $this->_packageInfo['extends'] = $data; + break; + case 'summary': + $this->_packageInfo['summary'] = $data; + break; + case 'description': + $data = $this->_unIndent($this->cdata); + $this->_packageInfo['description'] = $data; + break; + case 'user': + $this->current_maintainer['handle'] = $data; + break; + case 'email': + $this->current_maintainer['email'] = $data; + break; + case 'role': + $this->current_maintainer['role'] = $data; + break; + case 'version': + if ($this->in_changelog) { + $this->current_release['version'] = $data; + } else { + $this->_packageInfo['version'] = $data; + } + break; + case 'date': + if ($this->in_changelog) { + $this->current_release['release_date'] = $data; + } else { + $this->_packageInfo['release_date'] = $data; + } + break; + case 'notes': + // try to "de-indent" release notes in case someone + // has been over-indenting their xml ;-) + // Trim only on the right side + $data = rtrim($this->_unIndent($this->cdata)); + if ($this->in_changelog) { + $this->current_release['release_notes'] = $data; + } else { + $this->_packageInfo['release_notes'] = $data; + } + break; + case 'warnings': + if ($this->in_changelog) { + $this->current_release['release_warnings'] = $data; + } else { + $this->_packageInfo['release_warnings'] = $data; + } + break; + case 'state': + if ($this->in_changelog) { + $this->current_release['release_state'] = $data; + } else { + $this->_packageInfo['release_state'] = $data; + } + break; + case 'license': + if ($this->in_changelog) { + $this->current_release['release_license'] = $data; + } else { + $this->_packageInfo['release_license'] = $data; + } + break; + case 'dep': + if ($data && !$this->in_changelog) { + $this->_packageInfo['release_deps'][$this->d_i]['name'] = $data; + } + break; + case 'dir': + if ($this->in_changelog) { + break; + } + array_pop($this->dir_names); + break; + case 'file': + if ($this->in_changelog) { + break; + } + if ($data) { + $path = ''; + if (count($this->dir_names)) { + foreach ($this->dir_names as $dir) { + $path .= $dir . '/'; + } + } + $path .= $data; + $this->filelist[$path] = $this->current_attributes; + // Set the baseinstalldir only if the file don't have this attrib + if (!isset($this->filelist[$path]['baseinstalldir']) && + isset($this->dir_install)) + { + $this->filelist[$path]['baseinstalldir'] = $this->dir_install; + } + // Set the Role + if (!isset($this->filelist[$path]['role']) && isset($this->dir_role)) { + $this->filelist[$path]['role'] = $this->dir_role; + } + } + break; + case 'maintainer': + if (empty($this->_packageInfo['maintainers'][$this->m_i]['role'])) { + $this->_packageInfo['maintainers'][$this->m_i]['role'] = 'lead'; + } + $this->m_i++; + break; + case 'release': + if ($this->in_changelog) { + $this->c_i++; + } + break; + case 'changelog': + $this->in_changelog = false; + break; + } + array_pop($this->element_stack); + $spos = sizeof($this->element_stack) - 1; + $this->current_element = ($spos > 0) ? $this->element_stack[$spos] : ''; + $this->cdata = ''; + } + + // }}} + // {{{ _pkginfo_cdata_1_0() + + /** + * XML parser callback for character data. Used for version 1.0 + * packages. + * + * @param resource $xp XML parser resource + * @param string $name character data + * + * @return void + * + * @access private + */ + function _pkginfo_cdata_1_0($xp, $data) + { + if (isset($this->cdata)) { + $this->cdata .= $data; + } + } + + // }}} +} +?> \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/PackageFile/Parser/v2.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/PackageFile/Parser/v2.php new file mode 100644 index 0000000..49a29f1 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/PackageFile/Parser/v2.php @@ -0,0 +1,112 @@ + + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ +/** + * base xml parser class + */ +require_once 'PEAR/XMLParser.php'; +require_once 'PEAR/PackageFile/v2.php'; +/** + * Parser for package.xml version 2.0 + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: @PEAR-VER@ + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_PackageFile_Parser_v2 extends PEAR_XMLParser +{ + var $_config; + var $_logger; + var $_registry; + + function setConfig(&$c) + { + $this->_config = &$c; + $this->_registry = &$c->getRegistry(); + } + + function setLogger(&$l) + { + $this->_logger = &$l; + } + /** + * Unindent given string + * + * @param string $str The string that has to be unindented. + * @return string + * @access private + */ + function _unIndent($str) + { + // remove leading newlines + $str = preg_replace('/^[\r\n]+/', '', $str); + // find whitespace at the beginning of the first line + $indent_len = strspn($str, " \t"); + $indent = substr($str, 0, $indent_len); + $data = ''; + // remove the same amount of whitespace from following lines + foreach (explode("\n", $str) as $line) { + if (substr($line, 0, $indent_len) == $indent) { + $data .= substr($line, $indent_len) . "\n"; + } else { + $data .= $line . "\n"; + } + } + return $data; + } + + /** + * post-process data + * + * @param string $data + * @param string $element element name + */ + function postProcess($data, $element) + { + if ($element == 'notes') { + return trim($this->_unIndent($data)); + } + return trim($data); + } + + /** + * @param string + * @param string file name of the package.xml + * @param string|false name of the archive this package.xml came from, if any + * @param string class name to instantiate and return. This must be PEAR_PackageFile_v2 or + * a subclass + * @return PEAR_PackageFile_v2 + */ + function parse($data, $file = null, $archive = false, $class = 'PEAR_PackageFile_v2') + { + if (PEAR::isError($err = parent::parse($data))) { + return $err; + } + + $ret = new $class; + $ret->encoding = $this->encoding; + $ret->setConfig($this->_config); + if (isset($this->_logger)) { + $ret->setLogger($this->_logger); + } + + $ret->fromArray($this->_unserializedData); + $ret->setPackagefile($file, $archive); + return $ret; + } +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/PackageFile/v1.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/PackageFile/v1.php new file mode 100644 index 0000000..413db67 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/PackageFile/v1.php @@ -0,0 +1,1602 @@ + + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ +/** + * For error handling + */ +require_once 'PEAR/ErrorStack.php'; + +/** + * Error code if parsing is attempted with no xml extension + */ +define('PEAR_PACKAGEFILE_ERROR_NO_XML_EXT', 3); + +/** + * Error code if creating the xml parser resource fails + */ +define('PEAR_PACKAGEFILE_ERROR_CANT_MAKE_PARSER', 4); + +/** + * Error code used for all sax xml parsing errors + */ +define('PEAR_PACKAGEFILE_ERROR_PARSER_ERROR', 5); + +/** + * Error code used when there is no name + */ +define('PEAR_PACKAGEFILE_ERROR_NO_NAME', 6); + +/** + * Error code when a package name is not valid + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_NAME', 7); + +/** + * Error code used when no summary is parsed + */ +define('PEAR_PACKAGEFILE_ERROR_NO_SUMMARY', 8); + +/** + * Error code for summaries that are more than 1 line + */ +define('PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY', 9); + +/** + * Error code used when no description is present + */ +define('PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION', 10); + +/** + * Error code used when no license is present + */ +define('PEAR_PACKAGEFILE_ERROR_NO_LICENSE', 11); + +/** + * Error code used when a version number is not present + */ +define('PEAR_PACKAGEFILE_ERROR_NO_VERSION', 12); + +/** + * Error code used when a version number is invalid + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_VERSION', 13); + +/** + * Error code when release state is missing + */ +define('PEAR_PACKAGEFILE_ERROR_NO_STATE', 14); + +/** + * Error code when release state is invalid + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_STATE', 15); + +/** + * Error code when release state is missing + */ +define('PEAR_PACKAGEFILE_ERROR_NO_DATE', 16); + +/** + * Error code when release state is invalid + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_DATE', 17); + +/** + * Error code when no release notes are found + */ +define('PEAR_PACKAGEFILE_ERROR_NO_NOTES', 18); + +/** + * Error code when no maintainers are found + */ +define('PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS', 19); + +/** + * Error code when a maintainer has no handle + */ +define('PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE', 20); + +/** + * Error code when a maintainer has no handle + */ +define('PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE', 21); + +/** + * Error code when a maintainer has no name + */ +define('PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME', 22); + +/** + * Error code when a maintainer has no email + */ +define('PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL', 23); + +/** + * Error code when a maintainer has no handle + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_MAINTROLE', 24); + +/** + * Error code when a dependency is not a PHP dependency, but has no name + */ +define('PEAR_PACKAGEFILE_ERROR_NO_DEPNAME', 25); + +/** + * Error code when a dependency has no type (pkg, php, etc.) + */ +define('PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE', 26); + +/** + * Error code when a dependency has no relation (lt, ge, has, etc.) + */ +define('PEAR_PACKAGEFILE_ERROR_NO_DEPREL', 27); + +/** + * Error code when a dependency is not a 'has' relation, but has no version + */ +define('PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION', 28); + +/** + * Error code when a dependency has an invalid relation + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPREL', 29); + +/** + * Error code when a dependency has an invalid type + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPTYPE', 30); + +/** + * Error code when a dependency has an invalid optional option + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL', 31); + +/** + * Error code when a dependency is a pkg dependency, and has an invalid package name + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPNAME', 32); + +/** + * Error code when a dependency has a channel="foo" attribute, and foo is not a registered channel + */ +define('PEAR_PACKAGEFILE_ERROR_UNKNOWN_DEPCHANNEL', 33); + +/** + * Error code when rel="has" and version attribute is present. + */ +define('PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED', 34); + +/** + * Error code when type="php" and dependency name is present + */ +define('PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED', 35); + +/** + * Error code when a configure option has no name + */ +define('PEAR_PACKAGEFILE_ERROR_NO_CONFNAME', 36); + +/** + * Error code when a configure option has no name + */ +define('PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT', 37); + +/** + * Error code when a file in the filelist has an invalid role + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE', 38); + +/** + * Error code when a file in the filelist has no role + */ +define('PEAR_PACKAGEFILE_ERROR_NO_FILEROLE', 39); + +/** + * Error code when analyzing a php source file that has parse errors + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE', 40); + +/** + * Error code when analyzing a php source file reveals a source element + * without a package name prefix + */ +define('PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX', 41); + +/** + * Error code when an unknown channel is specified + */ +define('PEAR_PACKAGEFILE_ERROR_UNKNOWN_CHANNEL', 42); + +/** + * Error code when no files are found in the filelist + */ +define('PEAR_PACKAGEFILE_ERROR_NO_FILES', 43); + +/** + * Error code when a file is not valid php according to _analyzeSourceCode() + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_FILE', 44); + +/** + * Error code when the channel validator returns an error or warning + */ +define('PEAR_PACKAGEFILE_ERROR_CHANNELVAL', 45); + +/** + * Error code when a php5 package is packaged in php4 (analysis doesn't work) + */ +define('PEAR_PACKAGEFILE_ERROR_PHP5', 46); + +/** + * Error code when a file is listed in package.xml but does not exist + */ +define('PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND', 47); + +/** + * Error code when a + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_PackageFile_v1 +{ + /** + * @access private + * @var PEAR_ErrorStack + * @access private + */ + var $_stack; + + /** + * A registry object, used to access the package name validation regex for non-standard channels + * @var PEAR_Registry + * @access private + */ + var $_registry; + + /** + * An object that contains a log method that matches PEAR_Common::log's signature + * @var object + * @access private + */ + var $_logger; + + /** + * Parsed package information + * @var array + * @access private + */ + var $_packageInfo; + + /** + * path to package.xml + * @var string + * @access private + */ + var $_packageFile; + + /** + * path to package .tgz or false if this is a local/extracted package.xml + * @var string + * @access private + */ + var $_archiveFile; + + /** + * @var int + * @access private + */ + var $_isValid = 0; + + /** + * Determines whether this packagefile was initialized only with partial package info + * + * If this package file was constructed via parsing REST, it will only contain + * + * - package name + * - channel name + * - dependencies + * @var boolean + * @access private + */ + var $_incomplete = true; + + /** + * @param bool determines whether to return a PEAR_Error object, or use the PEAR_ErrorStack + * @param string Name of Error Stack class to use. + */ + function __construct() + { + $this->_stack = new PEAR_ErrorStack('PEAR_PackageFile_v1'); + $this->_stack->setErrorMessageTemplate($this->_getErrorMessage()); + $this->_isValid = 0; + } + + function installBinary($installer) + { + return false; + } + + function isExtension($name) + { + return false; + } + + function setConfig(&$config) + { + $this->_config = &$config; + $this->_registry = &$config->getRegistry(); + } + + function setRequestedGroup() + { + // placeholder + } + + /** + * For saving in the registry. + * + * Set the last version that was installed + * @param string + */ + function setLastInstalledVersion($version) + { + $this->_packageInfo['_lastversion'] = $version; + } + + /** + * @return string|false + */ + function getLastInstalledVersion() + { + if (isset($this->_packageInfo['_lastversion'])) { + return $this->_packageInfo['_lastversion']; + } + return false; + } + + function getInstalledBinary() + { + return false; + } + + function listPostinstallScripts() + { + return false; + } + + function initPostinstallScripts() + { + return false; + } + + function setLogger(&$logger) + { + if ($logger && (!is_object($logger) || !method_exists($logger, 'log'))) { + return PEAR::raiseError('Logger must be compatible with PEAR_Common::log'); + } + $this->_logger = &$logger; + } + + function setPackagefile($file, $archive = false) + { + $this->_packageFile = $file; + $this->_archiveFile = $archive ? $archive : $file; + } + + function getPackageFile() + { + return isset($this->_packageFile) ? $this->_packageFile : false; + } + + function getPackageType() + { + return 'php'; + } + + function getArchiveFile() + { + return $this->_archiveFile; + } + + function packageInfo($field) + { + if (!is_string($field) || empty($field) || + !isset($this->_packageInfo[$field])) { + return false; + } + return $this->_packageInfo[$field]; + } + + function setDirtree($path) + { + if (!isset($this->_packageInfo['dirtree'])) { + $this->_packageInfo['dirtree'] = array(); + } + $this->_packageInfo['dirtree'][$path] = true; + } + + function getDirtree() + { + if (isset($this->_packageInfo['dirtree']) && count($this->_packageInfo['dirtree'])) { + return $this->_packageInfo['dirtree']; + } + return false; + } + + function resetDirtree() + { + unset($this->_packageInfo['dirtree']); + } + + function fromArray($pinfo) + { + $this->_incomplete = false; + $this->_packageInfo = $pinfo; + } + + function isIncomplete() + { + return $this->_incomplete; + } + + function getChannel() + { + return 'pear.php.net'; + } + + function getUri() + { + return false; + } + + function getTime() + { + return false; + } + + function getExtends() + { + if (isset($this->_packageInfo['extends'])) { + return $this->_packageInfo['extends']; + } + return false; + } + + /** + * @return array + */ + function toArray() + { + if (!$this->validate(PEAR_VALIDATE_NORMAL)) { + return false; + } + return $this->getArray(); + } + + function getArray() + { + return $this->_packageInfo; + } + + function getName() + { + return $this->getPackage(); + } + + function getPackage() + { + if (isset($this->_packageInfo['package'])) { + return $this->_packageInfo['package']; + } + return false; + } + + /** + * WARNING - don't use this unless you know what you are doing + */ + function setRawPackage($package) + { + $this->_packageInfo['package'] = $package; + } + + function setPackage($package) + { + $this->_packageInfo['package'] = $package; + $this->_isValid = false; + } + + function getVersion() + { + if (isset($this->_packageInfo['version'])) { + return $this->_packageInfo['version']; + } + return false; + } + + function setVersion($version) + { + $this->_packageInfo['version'] = $version; + $this->_isValid = false; + } + + function clearMaintainers() + { + unset($this->_packageInfo['maintainers']); + } + + function getMaintainers() + { + if (isset($this->_packageInfo['maintainers'])) { + return $this->_packageInfo['maintainers']; + } + return false; + } + + /** + * Adds a new maintainer - no checking of duplicates is performed, use + * updatemaintainer for that purpose. + */ + function addMaintainer($role, $handle, $name, $email) + { + $this->_packageInfo['maintainers'][] = + array('handle' => $handle, 'role' => $role, 'email' => $email, 'name' => $name); + $this->_isValid = false; + } + + function updateMaintainer($role, $handle, $name, $email) + { + $found = false; + if (!isset($this->_packageInfo['maintainers']) || + !is_array($this->_packageInfo['maintainers'])) { + return $this->addMaintainer($role, $handle, $name, $email); + } + foreach ($this->_packageInfo['maintainers'] as $i => $maintainer) { + if ($maintainer['handle'] == $handle) { + $found = $i; + break; + } + } + if ($found !== false) { + unset($this->_packageInfo['maintainers'][$found]); + $this->_packageInfo['maintainers'] = + array_values($this->_packageInfo['maintainers']); + } + $this->addMaintainer($role, $handle, $name, $email); + } + + function deleteMaintainer($handle) + { + $found = false; + foreach ($this->_packageInfo['maintainers'] as $i => $maintainer) { + if ($maintainer['handle'] == $handle) { + $found = $i; + break; + } + } + if ($found !== false) { + unset($this->_packageInfo['maintainers'][$found]); + $this->_packageInfo['maintainers'] = + array_values($this->_packageInfo['maintainers']); + return true; + } + return false; + } + + function getState() + { + if (isset($this->_packageInfo['release_state'])) { + return $this->_packageInfo['release_state']; + } + return false; + } + + function setRawState($state) + { + $this->_packageInfo['release_state'] = $state; + } + + function setState($state) + { + $this->_packageInfo['release_state'] = $state; + $this->_isValid = false; + } + + function getDate() + { + if (isset($this->_packageInfo['release_date'])) { + return $this->_packageInfo['release_date']; + } + return false; + } + + function setDate($date) + { + $this->_packageInfo['release_date'] = $date; + $this->_isValid = false; + } + + function getLicense() + { + if (isset($this->_packageInfo['release_license'])) { + return $this->_packageInfo['release_license']; + } + return false; + } + + function setLicense($date) + { + $this->_packageInfo['release_license'] = $date; + $this->_isValid = false; + } + + function getSummary() + { + if (isset($this->_packageInfo['summary'])) { + return $this->_packageInfo['summary']; + } + return false; + } + + function setSummary($summary) + { + $this->_packageInfo['summary'] = $summary; + $this->_isValid = false; + } + + function getDescription() + { + if (isset($this->_packageInfo['description'])) { + return $this->_packageInfo['description']; + } + return false; + } + + function setDescription($desc) + { + $this->_packageInfo['description'] = $desc; + $this->_isValid = false; + } + + function getNotes() + { + if (isset($this->_packageInfo['release_notes'])) { + return $this->_packageInfo['release_notes']; + } + return false; + } + + function setNotes($notes) + { + $this->_packageInfo['release_notes'] = $notes; + $this->_isValid = false; + } + + function getDeps() + { + if (isset($this->_packageInfo['release_deps'])) { + return $this->_packageInfo['release_deps']; + } + return false; + } + + /** + * Reset dependencies prior to adding new ones + */ + function clearDeps() + { + unset($this->_packageInfo['release_deps']); + } + + function addPhpDep($version, $rel) + { + $this->_isValid = false; + $this->_packageInfo['release_deps'][] = + array('type' => 'php', + 'rel' => $rel, + 'version' => $version); + } + + function addPackageDep($name, $version, $rel, $optional = 'no') + { + $this->_isValid = false; + $dep = + array('type' => 'pkg', + 'name' => $name, + 'rel' => $rel, + 'optional' => $optional); + if ($rel != 'has' && $rel != 'not') { + $dep['version'] = $version; + } + $this->_packageInfo['release_deps'][] = $dep; + } + + function addExtensionDep($name, $version, $rel, $optional = 'no') + { + $this->_isValid = false; + $this->_packageInfo['release_deps'][] = + array('type' => 'ext', + 'name' => $name, + 'rel' => $rel, + 'version' => $version, + 'optional' => $optional); + } + + /** + * WARNING - do not use this function directly unless you know what you're doing + */ + function setDeps($deps) + { + $this->_packageInfo['release_deps'] = $deps; + } + + function hasDeps() + { + return isset($this->_packageInfo['release_deps']) && + count($this->_packageInfo['release_deps']); + } + + function getDependencyGroup($group) + { + return false; + } + + function isCompatible($pf) + { + return false; + } + + function isSubpackageOf($p) + { + return $p->isSubpackage($this); + } + + function isSubpackage($p) + { + return false; + } + + function dependsOn($package, $channel) + { + if (strtolower($channel) != 'pear.php.net') { + return false; + } + if (!($deps = $this->getDeps())) { + return false; + } + foreach ($deps as $dep) { + if ($dep['type'] != 'pkg') { + continue; + } + if (strtolower($dep['name']) == strtolower($package)) { + return true; + } + } + return false; + } + + function getConfigureOptions() + { + if (isset($this->_packageInfo['configure_options'])) { + return $this->_packageInfo['configure_options']; + } + return false; + } + + function hasConfigureOptions() + { + return isset($this->_packageInfo['configure_options']) && + count($this->_packageInfo['configure_options']); + } + + function addConfigureOption($name, $prompt, $default = false) + { + $o = array('name' => $name, 'prompt' => $prompt); + if ($default !== false) { + $o['default'] = $default; + } + if (!isset($this->_packageInfo['configure_options'])) { + $this->_packageInfo['configure_options'] = array(); + } + $this->_packageInfo['configure_options'][] = $o; + } + + function clearConfigureOptions() + { + unset($this->_packageInfo['configure_options']); + } + + function getProvides() + { + if (isset($this->_packageInfo['provides'])) { + return $this->_packageInfo['provides']; + } + return false; + } + + function getProvidesExtension() + { + return false; + } + + function addFile($dir, $file, $attrs) + { + $dir = preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'), $dir); + if ($dir == '/' || $dir == '') { + $dir = ''; + } else { + $dir .= '/'; + } + $file = $dir . $file; + $file = preg_replace('![\\/]+!', '/', $file); + $this->_packageInfo['filelist'][$file] = $attrs; + } + + function getInstallationFilelist() + { + return $this->getFilelist(); + } + + function getFilelist() + { + if (isset($this->_packageInfo['filelist'])) { + return $this->_packageInfo['filelist']; + } + return false; + } + + function setFileAttribute($file, $attr, $value) + { + $this->_packageInfo['filelist'][$file][$attr] = $value; + } + + function resetFilelist() + { + $this->_packageInfo['filelist'] = array(); + } + + function setInstalledAs($file, $path) + { + if ($path) { + return $this->_packageInfo['filelist'][$file]['installed_as'] = $path; + } + unset($this->_packageInfo['filelist'][$file]['installed_as']); + } + + function installedFile($file, $atts) + { + if (isset($this->_packageInfo['filelist'][$file])) { + $this->_packageInfo['filelist'][$file] = + array_merge($this->_packageInfo['filelist'][$file], $atts); + } else { + $this->_packageInfo['filelist'][$file] = $atts; + } + } + + function getChangelog() + { + if (isset($this->_packageInfo['changelog'])) { + return $this->_packageInfo['changelog']; + } + return false; + } + + function getPackagexmlVersion() + { + return '1.0'; + } + + /** + * Wrapper to {@link PEAR_ErrorStack::getErrors()} + * @param boolean determines whether to purge the error stack after retrieving + * @return array + */ + function getValidationWarnings($purge = true) + { + return $this->_stack->getErrors($purge); + } + + // }}} + /** + * Validation error. Also marks the object contents as invalid + * @param error code + * @param array error information + * @access private + */ + function _validateError($code, $params = array()) + { + $this->_stack->push($code, 'error', $params, false, false, debug_backtrace()); + $this->_isValid = false; + } + + /** + * Validation warning. Does not mark the object contents invalid. + * @param error code + * @param array error information + * @access private + */ + function _validateWarning($code, $params = array()) + { + $this->_stack->push($code, 'warning', $params, false, false, debug_backtrace()); + } + + /** + * @param integer error code + * @access protected + */ + function _getErrorMessage() + { + return array( + PEAR_PACKAGEFILE_ERROR_NO_NAME => + 'Missing Package Name', + PEAR_PACKAGEFILE_ERROR_NO_SUMMARY => + 'No summary found', + PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY => + 'Summary should be on one line', + PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION => + 'Missing description', + PEAR_PACKAGEFILE_ERROR_NO_LICENSE => + 'Missing license', + PEAR_PACKAGEFILE_ERROR_NO_VERSION => + 'No release version found', + PEAR_PACKAGEFILE_ERROR_NO_STATE => + 'No release state found', + PEAR_PACKAGEFILE_ERROR_NO_DATE => + 'No release date found', + PEAR_PACKAGEFILE_ERROR_NO_NOTES => + 'No release notes found', + PEAR_PACKAGEFILE_ERROR_NO_LEAD => + 'Package must have at least one lead maintainer', + PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS => + 'No maintainers found, at least one must be defined', + PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE => + 'Maintainer %index% has no handle (user ID at channel server)', + PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE => + 'Maintainer %index% has no role', + PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME => + 'Maintainer %index% has no name', + PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL => + 'Maintainer %index% has no email', + PEAR_PACKAGEFILE_ERROR_NO_DEPNAME => + 'Dependency %index% is not a php dependency, and has no name', + PEAR_PACKAGEFILE_ERROR_NO_DEPREL => + 'Dependency %index% has no relation (rel)', + PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE => + 'Dependency %index% has no type', + PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED => + 'PHP Dependency %index% has a name attribute of "%name%" which will be' . + ' ignored!', + PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION => + 'Dependency %index% is not a rel="has" or rel="not" dependency, ' . + 'and has no version', + PEAR_PACKAGEFILE_ERROR_NO_DEPPHPVERSION => + 'Dependency %index% is a type="php" dependency, ' . + 'and has no version', + PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED => + 'Dependency %index% is a rel="%rel%" dependency, versioning is ignored', + PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL => + 'Dependency %index% has invalid optional value "%opt%", should be yes or no', + PEAR_PACKAGEFILE_PHP_NO_NOT => + 'Dependency %index%: php dependencies cannot use "not" rel, use "ne"' . + ' to exclude specific versions', + PEAR_PACKAGEFILE_ERROR_NO_CONFNAME => + 'Configure Option %index% has no name', + PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT => + 'Configure Option %index% has no prompt', + PEAR_PACKAGEFILE_ERROR_NO_FILES => + 'No files in section of package.xml', + PEAR_PACKAGEFILE_ERROR_NO_FILEROLE => + 'File "%file%" has no role, expecting one of "%roles%"', + PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE => + 'File "%file%" has invalid role "%role%", expecting one of "%roles%"', + PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME => + 'File "%file%" cannot start with ".", cannot package or install', + PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE => + 'Parser error: invalid PHP found in file "%file%"', + PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX => + 'in %file%: %type% "%name%" not prefixed with package name "%package%"', + PEAR_PACKAGEFILE_ERROR_INVALID_FILE => + 'Parser error: invalid PHP file "%file%"', + PEAR_PACKAGEFILE_ERROR_CHANNELVAL => + 'Channel validator error: field "%field%" - %reason%', + PEAR_PACKAGEFILE_ERROR_PHP5 => + 'Error, PHP5 token encountered in %file%, analysis should be in PHP5', + PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND => + 'File "%file%" in package.xml does not exist', + PEAR_PACKAGEFILE_ERROR_NON_ISO_CHARS => + 'Package.xml contains non-ISO-8859-1 characters, and may not validate', + ); + } + + /** + * Validate XML package definition file. + * + * @access public + * @return boolean + */ + function validate($state = PEAR_VALIDATE_NORMAL, $nofilechecking = false) + { + if (($this->_isValid & $state) == $state) { + return true; + } + $this->_isValid = true; + $info = $this->_packageInfo; + if (empty($info['package'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_NAME); + $this->_packageName = $pn = 'unknown'; + } else { + $this->_packageName = $pn = $info['package']; + } + + if (empty($info['summary'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_SUMMARY); + } elseif (strpos(trim($info['summary']), "\n") !== false) { + $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY, + array('summary' => $info['summary'])); + } + if (empty($info['description'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION); + } + if (empty($info['release_license'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_LICENSE); + } + if (empty($info['version'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_VERSION); + } + if (empty($info['release_state'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_STATE); + } + if (empty($info['release_date'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DATE); + } + if (empty($info['release_notes'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_NOTES); + } + if (empty($info['maintainers'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS); + } else { + $haslead = false; + $i = 1; + foreach ($info['maintainers'] as $m) { + if (empty($m['handle'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE, + array('index' => $i)); + } + if (empty($m['role'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE, + array('index' => $i, 'roles' => PEAR_Common::getUserRoles())); + } elseif ($m['role'] == 'lead') { + $haslead = true; + } + if (empty($m['name'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME, + array('index' => $i)); + } + if (empty($m['email'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL, + array('index' => $i)); + } + $i++; + } + if (!$haslead) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_LEAD); + } + } + if (!empty($info['release_deps'])) { + $i = 1; + foreach ($info['release_deps'] as $d) { + if (!isset($d['type']) || empty($d['type'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE, + array('index' => $i, 'types' => PEAR_Common::getDependencyTypes())); + continue; + } + if (!isset($d['rel']) || empty($d['rel'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPREL, + array('index' => $i, 'rels' => PEAR_Common::getDependencyRelations())); + continue; + } + if (!empty($d['optional'])) { + if (!in_array($d['optional'], array('yes', 'no'))) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL, + array('index' => $i, 'opt' => $d['optional'])); + } + } + if ($d['rel'] != 'has' && $d['rel'] != 'not' && empty($d['version'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION, + array('index' => $i)); + } elseif (($d['rel'] == 'has' || $d['rel'] == 'not') && !empty($d['version'])) { + $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED, + array('index' => $i, 'rel' => $d['rel'])); + } + if ($d['type'] == 'php' && !empty($d['name'])) { + $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED, + array('index' => $i, 'name' => $d['name'])); + } elseif ($d['type'] != 'php' && empty($d['name'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPNAME, + array('index' => $i)); + } + if ($d['type'] == 'php' && empty($d['version'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPPHPVERSION, + array('index' => $i)); + } + if (($d['rel'] == 'not') && ($d['type'] == 'php')) { + $this->_validateError(PEAR_PACKAGEFILE_PHP_NO_NOT, + array('index' => $i)); + } + $i++; + } + } + if (!empty($info['configure_options'])) { + $i = 1; + foreach ($info['configure_options'] as $c) { + if (empty($c['name'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_CONFNAME, + array('index' => $i)); + } + if (empty($c['prompt'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT, + array('index' => $i)); + } + $i++; + } + } + if (empty($info['filelist'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_FILES); + $errors[] = 'no files'; + } else { + foreach ($info['filelist'] as $file => $fa) { + if (empty($fa['role'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_FILEROLE, + array('file' => $file, 'roles' => PEAR_Common::getFileRoles())); + continue; + } elseif (!in_array($fa['role'], PEAR_Common::getFileRoles())) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE, + array('file' => $file, 'role' => $fa['role'], 'roles' => PEAR_Common::getFileRoles())); + } + if (preg_match('~/\.\.?(/|\\z)|^\.\.?/~', str_replace('\\', '/', $file))) { + // file contains .. parent directory or . cur directory references + $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME, + array('file' => $file)); + } + if (isset($fa['install-as']) && + preg_match('~/\.\.?(/|\\z)|^\.\.?/~', + str_replace('\\', '/', $fa['install-as']))) { + // install-as contains .. parent directory or . cur directory references + $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME, + array('file' => $file . ' [installed as ' . $fa['install-as'] . ']')); + } + if (isset($fa['baseinstalldir']) && + preg_match('~/\.\.?(/|\\z)|^\.\.?/~', + str_replace('\\', '/', $fa['baseinstalldir']))) { + // install-as contains .. parent directory or . cur directory references + $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME, + array('file' => $file . ' [baseinstalldir ' . $fa['baseinstalldir'] . ']')); + } + } + } + if (isset($this->_registry) && $this->_isValid) { + $chan = $this->_registry->getChannel('pear.php.net'); + if (PEAR::isError($chan)) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $chan->getMessage()); + return $this->_isValid = 0; + } + $validator = $chan->getValidationObject(); + $validator->setPackageFile($this); + $validator->validate($state); + $failures = $validator->getFailures(); + foreach ($failures['errors'] as $error) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $error); + } + foreach ($failures['warnings'] as $warning) { + $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $warning); + } + } + if ($this->_isValid && $state == PEAR_VALIDATE_PACKAGING && !$nofilechecking) { + if ($this->_analyzePhpFiles()) { + $this->_isValid = true; + } + } + if ($this->_isValid) { + return $this->_isValid = $state; + } + return $this->_isValid = 0; + } + + function _analyzePhpFiles() + { + if (!$this->_isValid) { + return false; + } + if (!isset($this->_packageFile)) { + return false; + } + $dir_prefix = dirname($this->_packageFile); + $common = new PEAR_Common; + $log = isset($this->_logger) ? array(&$this->_logger, 'log') : + array($common, 'log'); + $info = $this->getFilelist(); + foreach ($info as $file => $fa) { + if (!file_exists($dir_prefix . DIRECTORY_SEPARATOR . $file)) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND, + array('file' => realpath($dir_prefix) . DIRECTORY_SEPARATOR . $file)); + continue; + } + if ($fa['role'] == 'php' && $dir_prefix) { + call_user_func_array($log, array(1, "Analyzing $file")); + $srcinfo = $this->_analyzeSourceCode($dir_prefix . DIRECTORY_SEPARATOR . $file); + if ($srcinfo) { + $this->_buildProvidesArray($srcinfo); + } + } + } + $this->_packageName = $pn = $this->getPackage(); + $pnl = strlen($pn); + if (isset($this->_packageInfo['provides'])) { + foreach ((array) $this->_packageInfo['provides'] as $key => $what) { + if (isset($what['explicit'])) { + // skip conformance checks if the provides entry is + // specified in the package.xml file + continue; + } + extract($what); + if ($type == 'class') { + if (!strncasecmp($name, $pn, $pnl)) { + continue; + } + $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX, + array('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn)); + } elseif ($type == 'function') { + if (strstr($name, '::') || !strncasecmp($name, $pn, $pnl)) { + continue; + } + $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX, + array('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn)); + } + } + } + return $this->_isValid; + } + + /** + * Get the default xml generator object + * + * @return PEAR_PackageFile_Generator_v1 + */ + function &getDefaultGenerator() + { + if (!class_exists('PEAR_PackageFile_Generator_v1')) { + require_once 'PEAR/PackageFile/Generator/v1.php'; + } + $a = new PEAR_PackageFile_Generator_v1($this); + return $a; + } + + /** + * Get the contents of a file listed within the package.xml + * @param string + * @return string + */ + function getFileContents($file) + { + if ($this->_archiveFile == $this->_packageFile) { // unpacked + $dir = dirname($this->_packageFile); + $file = $dir . DIRECTORY_SEPARATOR . $file; + $file = str_replace(array('/', '\\'), + array(DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR), $file); + if (file_exists($file) && is_readable($file)) { + return implode('', file($file)); + } + } else { // tgz + if (!class_exists('Archive_Tar')) { + require_once 'Archive/Tar.php'; + } + $tar = new Archive_Tar($this->_archiveFile); + $tar->pushErrorHandling(PEAR_ERROR_RETURN); + if ($file != 'package.xml' && $file != 'package2.xml') { + $file = $this->getPackage() . '-' . $this->getVersion() . '/' . $file; + } + $file = $tar->extractInString($file); + $tar->popErrorHandling(); + if (PEAR::isError($file)) { + return PEAR::raiseError("Cannot locate file '$file' in archive"); + } + return $file; + } + } + + // {{{ analyzeSourceCode() + /** + * Analyze the source code of the given PHP file + * + * @param string Filename of the PHP file + * @return mixed + * @access private + */ + function _analyzeSourceCode($file) + { + if (!function_exists("token_get_all")) { + return false; + } + if (!defined('T_DOC_COMMENT')) { + define('T_DOC_COMMENT', T_COMMENT); + } + if (!defined('T_INTERFACE')) { + define('T_INTERFACE', -1); + } + if (!defined('T_IMPLEMENTS')) { + define('T_IMPLEMENTS', -1); + } + if (!$fp = @fopen($file, "r")) { + return false; + } + fclose($fp); + $contents = file_get_contents($file); + $tokens = token_get_all($contents); +/* + for ($i = 0; $i < sizeof($tokens); $i++) { + @list($token, $data) = $tokens[$i]; + if (is_string($token)) { + var_dump($token); + } else { + print token_name($token) . ' '; + var_dump(rtrim($data)); + } + } +*/ + $look_for = 0; + $paren_level = 0; + $bracket_level = 0; + $brace_level = 0; + $lastphpdoc = ''; + $current_class = ''; + $current_interface = ''; + $current_class_level = -1; + $current_function = ''; + $current_function_level = -1; + $declared_classes = array(); + $declared_interfaces = array(); + $declared_functions = array(); + $declared_methods = array(); + $used_classes = array(); + $used_functions = array(); + $extends = array(); + $implements = array(); + $nodeps = array(); + $inquote = false; + $interface = false; + for ($i = 0; $i < sizeof($tokens); $i++) { + if (is_array($tokens[$i])) { + list($token, $data) = $tokens[$i]; + } else { + $token = $tokens[$i]; + $data = ''; + } + if ($inquote) { + if ($token != '"' && $token != T_END_HEREDOC) { + continue; + } else { + $inquote = false; + continue; + } + } + switch ($token) { + case T_WHITESPACE : + continue; + case ';': + if ($interface) { + $current_function = ''; + $current_function_level = -1; + } + break; + case '"': + case T_START_HEREDOC: + $inquote = true; + break; + case T_CURLY_OPEN: + case T_DOLLAR_OPEN_CURLY_BRACES: + case '{': $brace_level++; continue 2; + case '}': + $brace_level--; + if ($current_class_level == $brace_level) { + $current_class = ''; + $current_class_level = -1; + } + if ($current_function_level == $brace_level) { + $current_function = ''; + $current_function_level = -1; + } + continue 2; + case '[': $bracket_level++; continue 2; + case ']': $bracket_level--; continue 2; + case '(': $paren_level++; continue 2; + case ')': $paren_level--; continue 2; + case T_INTERFACE: + $interface = true; + case T_CLASS: + if (($current_class_level != -1) || ($current_function_level != -1)) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE, + array('file' => $file)); + return false; + } + case T_FUNCTION: + case T_NEW: + case T_EXTENDS: + case T_IMPLEMENTS: + $look_for = $token; + continue 2; + case T_STRING: + if ($look_for == T_CLASS) { + $current_class = $data; + $current_class_level = $brace_level; + $declared_classes[] = $current_class; + } elseif ($look_for == T_INTERFACE) { + $current_interface = $data; + $current_class_level = $brace_level; + $declared_interfaces[] = $current_interface; + } elseif ($look_for == T_IMPLEMENTS) { + $implements[$current_class] = $data; + } elseif ($look_for == T_EXTENDS) { + $extends[$current_class] = $data; + } elseif ($look_for == T_FUNCTION) { + if ($current_class) { + $current_function = "$current_class::$data"; + $declared_methods[$current_class][] = $data; + } elseif ($current_interface) { + $current_function = "$current_interface::$data"; + $declared_methods[$current_interface][] = $data; + } else { + $current_function = $data; + $declared_functions[] = $current_function; + } + $current_function_level = $brace_level; + $m = array(); + } elseif ($look_for == T_NEW) { + $used_classes[$data] = true; + } + $look_for = 0; + continue 2; + case T_VARIABLE: + $look_for = 0; + continue 2; + case T_DOC_COMMENT: + case T_COMMENT: + if (preg_match('!^/\*\*\s!', $data)) { + $lastphpdoc = $data; + if (preg_match_all('/@nodep\s+(\S+)/', $lastphpdoc, $m)) { + $nodeps = array_merge($nodeps, $m[1]); + } + } + continue 2; + case T_DOUBLE_COLON: + if (!($tokens[$i - 1][0] == T_WHITESPACE || $tokens[$i - 1][0] == T_STRING)) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE, + array('file' => $file)); + return false; + } + $class = $tokens[$i - 1][1]; + if (strtolower($class) != 'parent') { + $used_classes[$class] = true; + } + continue 2; + } + } + return array( + "source_file" => $file, + "declared_classes" => $declared_classes, + "declared_interfaces" => $declared_interfaces, + "declared_methods" => $declared_methods, + "declared_functions" => $declared_functions, + "used_classes" => array_diff(array_keys($used_classes), $nodeps), + "inheritance" => $extends, + "implements" => $implements, + ); + } + + /** + * Build a "provides" array from data returned by + * analyzeSourceCode(). The format of the built array is like + * this: + * + * array( + * 'class;MyClass' => 'array('type' => 'class', 'name' => 'MyClass'), + * ... + * ) + * + * + * @param array $srcinfo array with information about a source file + * as returned by the analyzeSourceCode() method. + * + * @return void + * + * @access private + * + */ + function _buildProvidesArray($srcinfo) + { + if (!$this->_isValid) { + return false; + } + $file = basename($srcinfo['source_file']); + $pn = $this->getPackage(); + $pnl = strlen($pn); + foreach ($srcinfo['declared_classes'] as $class) { + $key = "class;$class"; + if (isset($this->_packageInfo['provides'][$key])) { + continue; + } + $this->_packageInfo['provides'][$key] = + array('file'=> $file, 'type' => 'class', 'name' => $class); + if (isset($srcinfo['inheritance'][$class])) { + $this->_packageInfo['provides'][$key]['extends'] = + $srcinfo['inheritance'][$class]; + } + } + foreach ($srcinfo['declared_methods'] as $class => $methods) { + foreach ($methods as $method) { + $function = "$class::$method"; + $key = "function;$function"; + if ($method{0} == '_' || !strcasecmp($method, $class) || + isset($this->_packageInfo['provides'][$key])) { + continue; + } + $this->_packageInfo['provides'][$key] = + array('file'=> $file, 'type' => 'function', 'name' => $function); + } + } + + foreach ($srcinfo['declared_functions'] as $function) { + $key = "function;$function"; + if ($function{0} == '_' || isset($this->_packageInfo['provides'][$key])) { + continue; + } + if (!strstr($function, '::') && strncasecmp($function, $pn, $pnl)) { + $warnings[] = "in1 " . $file . ": function \"$function\" not prefixed with package name \"$pn\""; + } + $this->_packageInfo['provides'][$key] = + array('file'=> $file, 'type' => 'function', 'name' => $function); + } + } + + // }}} +} +?> diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/PackageFile/v2.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/PackageFile/v2.php new file mode 100644 index 0000000..ae0a1fa --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/PackageFile/v2.php @@ -0,0 +1,2060 @@ + + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ +/** + * For error handling + */ +require_once 'PEAR/ErrorStack.php'; +/** + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_PackageFile_v2 +{ + + /** + * Parsed package information + * @var array + * @access private + */ + var $_packageInfo = array(); + + /** + * path to package .tgz or false if this is a local/extracted package.xml + * @var string|false + * @access private + */ + var $_archiveFile; + + /** + * path to package .xml or false if this is an abstract parsed-from-string xml + * @var string|false + * @access private + */ + var $_packageFile; + + /** + * This is used by file analysis routines to log progress information + * @var PEAR_Common + * @access protected + */ + var $_logger; + + /** + * This is set to the highest validation level that has been validated + * + * If the package.xml is invalid or unknown, this is set to 0. If + * normal validation has occurred, this is set to PEAR_VALIDATE_NORMAL. If + * downloading/installation validation has occurred it is set to PEAR_VALIDATE_DOWNLOADING + * or INSTALLING, and so on up to PEAR_VALIDATE_PACKAGING. This allows validation + * "caching" to occur, which is particularly important for package validation, so + * that PHP files are not validated twice + * @var int + * @access private + */ + var $_isValid = 0; + + /** + * True if the filelist has been validated + * @param bool + */ + var $_filesValid = false; + + /** + * @var PEAR_Registry + * @access protected + */ + var $_registry; + + /** + * @var PEAR_Config + * @access protected + */ + var $_config; + + /** + * Optional Dependency group requested for installation + * @var string + * @access private + */ + var $_requestedGroup = false; + + /** + * @var PEAR_ErrorStack + * @access protected + */ + var $_stack; + + /** + * Namespace prefix used for tasks in this package.xml - use tasks: whenever possible + */ + var $_tasksNs; + + /** + * Determines whether this packagefile was initialized only with partial package info + * + * If this package file was constructed via parsing REST, it will only contain + * + * - package name + * - channel name + * - dependencies + * @var boolean + * @access private + */ + var $_incomplete = true; + + /** + * @var PEAR_PackageFile_v2_Validator + */ + var $_v2Validator; + + /** + * The constructor merely sets up the private error stack + */ + function __construct() + { + $this->_stack = new PEAR_ErrorStack('PEAR_PackageFile_v2', false, null); + $this->_isValid = false; + } + + /** + * PHP 4 style constructor for backwards compatibility. + * Used by PEAR_PackageFileManager2 + */ + public function PEAR_PackageFile_v2() + { + $this->__construct(); + } + + /** + * To make unit-testing easier + * @param PEAR_Frontend_* + * @param array options + * @param PEAR_Config + * @return PEAR_Downloader + * @access protected + */ + function &getPEARDownloader(&$i, $o, &$c) + { + $z = new PEAR_Downloader($i, $o, $c); + return $z; + } + + /** + * To make unit-testing easier + * @param PEAR_Config + * @param array options + * @param array package name as returned from {@link PEAR_Registry::parsePackageName()} + * @param int PEAR_VALIDATE_* constant + * @return PEAR_Dependency2 + * @access protected + */ + function &getPEARDependency2(&$c, $o, $p, $s = PEAR_VALIDATE_INSTALLING) + { + if (!class_exists('PEAR_Dependency2')) { + require_once 'PEAR/Dependency2.php'; + } + $z = new PEAR_Dependency2($c, $o, $p, $s); + return $z; + } + + function getInstalledBinary() + { + return isset($this->_packageInfo['#binarypackage']) ? $this->_packageInfo['#binarypackage'] : + false; + } + + /** + * Installation of source package has failed, attempt to download and install the + * binary version of this package. + * @param PEAR_Installer + * @return array|false + */ + function installBinary(&$installer) + { + if (!OS_WINDOWS) { + $a = false; + return $a; + } + if ($this->getPackageType() == 'extsrc' || $this->getPackageType() == 'zendextsrc') { + $releasetype = $this->getPackageType() . 'release'; + if (!is_array($installer->getInstallPackages())) { + $a = false; + return $a; + } + foreach ($installer->getInstallPackages() as $p) { + if ($p->isExtension($this->_packageInfo['providesextension'])) { + if ($p->getPackageType() != 'extsrc' && $p->getPackageType() != 'zendextsrc') { + $a = false; + return $a; // the user probably downloaded it separately + } + } + } + if (isset($this->_packageInfo[$releasetype]['binarypackage'])) { + $installer->log(0, 'Attempting to download binary version of extension "' . + $this->_packageInfo['providesextension'] . '"'); + $params = $this->_packageInfo[$releasetype]['binarypackage']; + if (!is_array($params) || !isset($params[0])) { + $params = array($params); + } + if (isset($this->_packageInfo['channel'])) { + foreach ($params as $i => $param) { + $params[$i] = array('channel' => $this->_packageInfo['channel'], + 'package' => $param, 'version' => $this->getVersion()); + } + } + $dl = &$this->getPEARDownloader($installer->ui, $installer->getOptions(), + $installer->config); + $verbose = $dl->config->get('verbose'); + $dl->config->set('verbose', -1); + foreach ($params as $param) { + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $ret = $dl->download(array($param)); + PEAR::popErrorHandling(); + if (is_array($ret) && count($ret)) { + break; + } + } + $dl->config->set('verbose', $verbose); + if (is_array($ret)) { + if (count($ret) == 1) { + $pf = $ret[0]->getPackageFile(); + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $err = $installer->install($ret[0]); + PEAR::popErrorHandling(); + if (is_array($err)) { + $this->_packageInfo['#binarypackage'] = $ret[0]->getPackage(); + // "install" self, so all dependencies will work transparently + $this->_registry->addPackage2($this); + $installer->log(0, 'Download and install of binary extension "' . + $this->_registry->parsedPackageNameToString( + array('channel' => $pf->getChannel(), + 'package' => $pf->getPackage()), true) . '" successful'); + $a = array($ret[0], $err); + return $a; + } + $installer->log(0, 'Download and install of binary extension "' . + $this->_registry->parsedPackageNameToString( + array('channel' => $pf->getChannel(), + 'package' => $pf->getPackage()), true) . '" failed'); + } + } + } + } + $a = false; + return $a; + } + + /** + * @return string|false Extension name + */ + function getProvidesExtension() + { + if (in_array($this->getPackageType(), + array('extsrc', 'extbin', 'zendextsrc', 'zendextbin'))) { + if (isset($this->_packageInfo['providesextension'])) { + return $this->_packageInfo['providesextension']; + } + } + return false; + } + + /** + * @param string Extension name + * @return bool + */ + function isExtension($extension) + { + if (in_array($this->getPackageType(), + array('extsrc', 'extbin', 'zendextsrc', 'zendextbin'))) { + return $this->_packageInfo['providesextension'] == $extension; + } + return false; + } + + /** + * Tests whether every part of the package.xml 1.0 is represented in + * this package.xml 2.0 + * @param PEAR_PackageFile_v1 + * @return bool + */ + function isEquivalent($pf1) + { + if (!$pf1) { + return true; + } + if ($this->getPackageType() == 'bundle') { + return false; + } + $this->_stack->getErrors(true); + if (!$pf1->validate(PEAR_VALIDATE_NORMAL)) { + return false; + } + $pass = true; + if ($pf1->getPackage() != $this->getPackage()) { + $this->_differentPackage($pf1->getPackage()); + $pass = false; + } + if ($pf1->getVersion() != $this->getVersion()) { + $this->_differentVersion($pf1->getVersion()); + $pass = false; + } + if (trim($pf1->getSummary()) != $this->getSummary()) { + $this->_differentSummary($pf1->getSummary()); + $pass = false; + } + if (preg_replace('/\s+/', '', $pf1->getDescription()) != + preg_replace('/\s+/', '', $this->getDescription())) { + $this->_differentDescription($pf1->getDescription()); + $pass = false; + } + if ($pf1->getState() != $this->getState()) { + $this->_differentState($pf1->getState()); + $pass = false; + } + if (!strstr(preg_replace('/\s+/', '', $this->getNotes()), + preg_replace('/\s+/', '', $pf1->getNotes()))) { + $this->_differentNotes($pf1->getNotes()); + $pass = false; + } + $mymaintainers = $this->getMaintainers(); + $yourmaintainers = $pf1->getMaintainers(); + for ($i1 = 0; $i1 < count($yourmaintainers); $i1++) { + $reset = false; + for ($i2 = 0; $i2 < count($mymaintainers); $i2++) { + if ($mymaintainers[$i2]['handle'] == $yourmaintainers[$i1]['handle']) { + if ($mymaintainers[$i2]['role'] != $yourmaintainers[$i1]['role']) { + $this->_differentRole($mymaintainers[$i2]['handle'], + $yourmaintainers[$i1]['role'], $mymaintainers[$i2]['role']); + $pass = false; + } + if ($mymaintainers[$i2]['email'] != $yourmaintainers[$i1]['email']) { + $this->_differentEmail($mymaintainers[$i2]['handle'], + $yourmaintainers[$i1]['email'], $mymaintainers[$i2]['email']); + $pass = false; + } + if ($mymaintainers[$i2]['name'] != $yourmaintainers[$i1]['name']) { + $this->_differentName($mymaintainers[$i2]['handle'], + $yourmaintainers[$i1]['name'], $mymaintainers[$i2]['name']); + $pass = false; + } + unset($mymaintainers[$i2]); + $mymaintainers = array_values($mymaintainers); + unset($yourmaintainers[$i1]); + $yourmaintainers = array_values($yourmaintainers); + $reset = true; + break; + } + } + if ($reset) { + $i1 = -1; + } + } + $this->_unmatchedMaintainers($mymaintainers, $yourmaintainers); + $filelist = $this->getFilelist(); + foreach ($pf1->getFilelist() as $file => $atts) { + if (!isset($filelist[$file])) { + $this->_missingFile($file); + $pass = false; + } + } + return $pass; + } + + function _differentPackage($package) + { + $this->_stack->push(__FUNCTION__, 'error', array('package' => $package, + 'self' => $this->getPackage()), + 'package.xml 1.0 package "%package%" does not match "%self%"'); + } + + function _differentVersion($version) + { + $this->_stack->push(__FUNCTION__, 'error', array('version' => $version, + 'self' => $this->getVersion()), + 'package.xml 1.0 version "%version%" does not match "%self%"'); + } + + function _differentState($state) + { + $this->_stack->push(__FUNCTION__, 'error', array('state' => $state, + 'self' => $this->getState()), + 'package.xml 1.0 state "%state%" does not match "%self%"'); + } + + function _differentRole($handle, $role, $selfrole) + { + $this->_stack->push(__FUNCTION__, 'error', array('handle' => $handle, + 'role' => $role, 'self' => $selfrole), + 'package.xml 1.0 maintainer "%handle%" role "%role%" does not match "%self%"'); + } + + function _differentEmail($handle, $email, $selfemail) + { + $this->_stack->push(__FUNCTION__, 'error', array('handle' => $handle, + 'email' => $email, 'self' => $selfemail), + 'package.xml 1.0 maintainer "%handle%" email "%email%" does not match "%self%"'); + } + + function _differentName($handle, $name, $selfname) + { + $this->_stack->push(__FUNCTION__, 'error', array('handle' => $handle, + 'name' => $name, 'self' => $selfname), + 'package.xml 1.0 maintainer "%handle%" name "%name%" does not match "%self%"'); + } + + function _unmatchedMaintainers($my, $yours) + { + if ($my) { + array_walk($my, create_function('&$i, $k', '$i = $i["handle"];')); + $this->_stack->push(__FUNCTION__, 'error', array('handles' => $my), + 'package.xml 2.0 has unmatched extra maintainers "%handles%"'); + } + if ($yours) { + array_walk($yours, create_function('&$i, $k', '$i = $i["handle"];')); + $this->_stack->push(__FUNCTION__, 'error', array('handles' => $yours), + 'package.xml 1.0 has unmatched extra maintainers "%handles%"'); + } + } + + function _differentNotes($notes) + { + $truncnotes = strlen($notes) < 25 ? $notes : substr($notes, 0, 24) . '...'; + $truncmynotes = strlen($this->getNotes()) < 25 ? $this->getNotes() : + substr($this->getNotes(), 0, 24) . '...'; + $this->_stack->push(__FUNCTION__, 'error', array('notes' => $truncnotes, + 'self' => $truncmynotes), + 'package.xml 1.0 release notes "%notes%" do not match "%self%"'); + } + + function _differentSummary($summary) + { + $truncsummary = strlen($summary) < 25 ? $summary : substr($summary, 0, 24) . '...'; + $truncmysummary = strlen($this->getsummary()) < 25 ? $this->getSummary() : + substr($this->getsummary(), 0, 24) . '...'; + $this->_stack->push(__FUNCTION__, 'error', array('summary' => $truncsummary, + 'self' => $truncmysummary), + 'package.xml 1.0 summary "%summary%" does not match "%self%"'); + } + + function _differentDescription($description) + { + $truncdescription = trim(strlen($description) < 25 ? $description : substr($description, 0, 24) . '...'); + $truncmydescription = trim(strlen($this->getDescription()) < 25 ? $this->getDescription() : + substr($this->getdescription(), 0, 24) . '...'); + $this->_stack->push(__FUNCTION__, 'error', array('description' => $truncdescription, + 'self' => $truncmydescription), + 'package.xml 1.0 description "%description%" does not match "%self%"'); + } + + function _missingFile($file) + { + $this->_stack->push(__FUNCTION__, 'error', array('file' => $file), + 'package.xml 1.0 file "%file%" is not present in '); + } + + /** + * WARNING - do not use this function unless you know what you're doing + */ + function setRawState($state) + { + if (!isset($this->_packageInfo['stability'])) { + $this->_packageInfo['stability'] = array(); + } + $this->_packageInfo['stability']['release'] = $state; + } + + /** + * WARNING - do not use this function unless you know what you're doing + */ + function setRawCompatible($compatible) + { + $this->_packageInfo['compatible'] = $compatible; + } + + /** + * WARNING - do not use this function unless you know what you're doing + */ + function setRawPackage($package) + { + $this->_packageInfo['name'] = $package; + } + + /** + * WARNING - do not use this function unless you know what you're doing + */ + function setRawChannel($channel) + { + $this->_packageInfo['channel'] = $channel; + } + + function setRequestedGroup($group) + { + $this->_requestedGroup = $group; + } + + function getRequestedGroup() + { + if (isset($this->_requestedGroup)) { + return $this->_requestedGroup; + } + return false; + } + + /** + * For saving in the registry. + * + * Set the last version that was installed + * @param string + */ + function setLastInstalledVersion($version) + { + $this->_packageInfo['_lastversion'] = $version; + } + + /** + * @return string|false + */ + function getLastInstalledVersion() + { + if (isset($this->_packageInfo['_lastversion'])) { + return $this->_packageInfo['_lastversion']; + } + return false; + } + + /** + * Determines whether this package.xml has post-install scripts or not + * @return array|false + */ + function listPostinstallScripts() + { + $filelist = $this->getFilelist(); + $contents = $this->getContents(); + $contents = $contents['dir']['file']; + if (!is_array($contents) || !isset($contents[0])) { + $contents = array($contents); + } + $taskfiles = array(); + foreach ($contents as $file) { + $atts = $file['attribs']; + unset($file['attribs']); + if (count($file)) { + $taskfiles[$atts['name']] = $file; + } + } + $common = new PEAR_Common; + $common->debug = $this->_config->get('verbose'); + $this->_scripts = array(); + $ret = array(); + foreach ($taskfiles as $name => $tasks) { + if (!isset($filelist[$name])) { + // ignored files will not be in the filelist + continue; + } + $atts = $filelist[$name]; + foreach ($tasks as $tag => $raw) { + $task = $this->getTask($tag); + $task = new $task($this->_config, $common, PEAR_TASK_INSTALL); + if ($task->isScript()) { + $ret[] = $filelist[$name]['installed_as']; + } + } + } + if (count($ret)) { + return $ret; + } + return false; + } + + /** + * Initialize post-install scripts for running + * + * This method can be used to detect post-install scripts, as the return value + * indicates whether any exist + * @return bool + */ + function initPostinstallScripts() + { + $filelist = $this->getFilelist(); + $contents = $this->getContents(); + $contents = $contents['dir']['file']; + if (!is_array($contents) || !isset($contents[0])) { + $contents = array($contents); + } + $taskfiles = array(); + foreach ($contents as $file) { + $atts = $file['attribs']; + unset($file['attribs']); + if (count($file)) { + $taskfiles[$atts['name']] = $file; + } + } + $common = new PEAR_Common; + $common->debug = $this->_config->get('verbose'); + $this->_scripts = array(); + foreach ($taskfiles as $name => $tasks) { + if (!isset($filelist[$name])) { + // file was not installed due to installconditions + continue; + } + $atts = $filelist[$name]; + foreach ($tasks as $tag => $raw) { + $taskname = $this->getTask($tag); + $task = new $taskname($this->_config, $common, PEAR_TASK_INSTALL); + if (!$task->isScript()) { + continue; // scripts are only handled after installation + } + $lastversion = isset($this->_packageInfo['_lastversion']) ? + $this->_packageInfo['_lastversion'] : null; + $task->init($raw, $atts, $lastversion); + $res = $task->startSession($this, $atts['installed_as']); + if (!$res) { + continue; // skip this file + } + if (PEAR::isError($res)) { + return $res; + } + $assign = &$task; + $this->_scripts[] = &$assign; + } + } + if (count($this->_scripts)) { + return true; + } + return false; + } + + function runPostinstallScripts() + { + if ($this->initPostinstallScripts()) { + $ui = &PEAR_Frontend::singleton(); + if ($ui) { + $ui->runPostinstallScripts($this->_scripts, $this); + } + } + } + + + /** + * Convert a recursive set of and tags into a single tag with + * tags. + */ + function flattenFilelist() + { + if (isset($this->_packageInfo['bundle'])) { + return; + } + $filelist = array(); + if (isset($this->_packageInfo['contents']['dir']['dir'])) { + $this->_getFlattenedFilelist($filelist, $this->_packageInfo['contents']['dir']); + if (!isset($filelist[1])) { + $filelist = $filelist[0]; + } + $this->_packageInfo['contents']['dir']['file'] = $filelist; + unset($this->_packageInfo['contents']['dir']['dir']); + } else { + // else already flattened but check for baseinstalldir propagation + if (isset($this->_packageInfo['contents']['dir']['attribs']['baseinstalldir'])) { + if (isset($this->_packageInfo['contents']['dir']['file'][0])) { + foreach ($this->_packageInfo['contents']['dir']['file'] as $i => $file) { + if (isset($file['attribs']['baseinstalldir'])) { + continue; + } + $this->_packageInfo['contents']['dir']['file'][$i]['attribs']['baseinstalldir'] + = $this->_packageInfo['contents']['dir']['attribs']['baseinstalldir']; + } + } else { + if (!isset($this->_packageInfo['contents']['dir']['file']['attribs']['baseinstalldir'])) { + $this->_packageInfo['contents']['dir']['file']['attribs']['baseinstalldir'] + = $this->_packageInfo['contents']['dir']['attribs']['baseinstalldir']; + } + } + } + } + } + + /** + * @param array the final flattened file list + * @param array the current directory being processed + * @param string|false any recursively inherited baeinstalldir attribute + * @param string private recursion variable + * @return array + * @access protected + */ + function _getFlattenedFilelist(&$files, $dir, $baseinstall = false, $path = '') + { + if (isset($dir['attribs']) && isset($dir['attribs']['baseinstalldir'])) { + $baseinstall = $dir['attribs']['baseinstalldir']; + } + if (isset($dir['dir'])) { + if (!isset($dir['dir'][0])) { + $dir['dir'] = array($dir['dir']); + } + foreach ($dir['dir'] as $subdir) { + if (!isset($subdir['attribs']) || !isset($subdir['attribs']['name'])) { + $name = '*unknown*'; + } else { + $name = $subdir['attribs']['name']; + } + $newpath = empty($path) ? $name : + $path . '/' . $name; + $this->_getFlattenedFilelist($files, $subdir, + $baseinstall, $newpath); + } + } + if (isset($dir['file'])) { + if (!isset($dir['file'][0])) { + $dir['file'] = array($dir['file']); + } + foreach ($dir['file'] as $file) { + $attrs = $file['attribs']; + $name = $attrs['name']; + if ($baseinstall && !isset($attrs['baseinstalldir'])) { + $attrs['baseinstalldir'] = $baseinstall; + } + $attrs['name'] = empty($path) ? $name : $path . '/' . $name; + $attrs['name'] = preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'), + $attrs['name']); + $file['attribs'] = $attrs; + $files[] = $file; + } + } + } + + function setConfig(&$config) + { + $this->_config = &$config; + $this->_registry = &$config->getRegistry(); + } + + function setLogger(&$logger) + { + if (!is_object($logger) || !method_exists($logger, 'log')) { + return PEAR::raiseError('Logger must be compatible with PEAR_Common::log'); + } + $this->_logger = &$logger; + } + + /** + * WARNING - do not use this function directly unless you know what you're doing + */ + function setDeps($deps) + { + $this->_packageInfo['dependencies'] = $deps; + } + + /** + * WARNING - do not use this function directly unless you know what you're doing + */ + function setCompatible($compat) + { + $this->_packageInfo['compatible'] = $compat; + } + + function setPackagefile($file, $archive = false) + { + $this->_packageFile = $file; + $this->_archiveFile = $archive ? $archive : $file; + } + + /** + * Wrapper to {@link PEAR_ErrorStack::getErrors()} + * @param boolean determines whether to purge the error stack after retrieving + * @return array + */ + function getValidationWarnings($purge = true) + { + return $this->_stack->getErrors($purge); + } + + function getPackageFile() + { + return $this->_packageFile; + } + + function getArchiveFile() + { + return $this->_archiveFile; + } + + + /** + * Directly set the array that defines this packagefile + * + * WARNING: no validation. This should only be performed by internal methods + * inside PEAR or by inputting an array saved from an existing PEAR_PackageFile_v2 + * @param array + */ + function fromArray($pinfo) + { + unset($pinfo['old']); + unset($pinfo['xsdversion']); + // If the changelog isn't an array then it was passed in as an empty tag + if (isset($pinfo['changelog']) && !is_array($pinfo['changelog'])) { + unset($pinfo['changelog']); + } + $this->_incomplete = false; + $this->_packageInfo = $pinfo; + } + + function isIncomplete() + { + return $this->_incomplete; + } + + /** + * @return array + */ + function toArray($forreg = false) + { + if (!$this->validate(PEAR_VALIDATE_NORMAL)) { + return false; + } + return $this->getArray($forreg); + } + + function getArray($forReg = false) + { + if ($forReg) { + $arr = $this->_packageInfo; + $arr['old'] = array(); + $arr['old']['version'] = $this->getVersion(); + $arr['old']['release_date'] = $this->getDate(); + $arr['old']['release_state'] = $this->getState(); + $arr['old']['release_license'] = $this->getLicense(); + $arr['old']['release_notes'] = $this->getNotes(); + $arr['old']['release_deps'] = $this->getDeps(); + $arr['old']['maintainers'] = $this->getMaintainers(); + $arr['xsdversion'] = '2.0'; + return $arr; + } else { + $info = $this->_packageInfo; + unset($info['dirtree']); + if (isset($info['_lastversion'])) { + unset($info['_lastversion']); + } + if (isset($info['#binarypackage'])) { + unset($info['#binarypackage']); + } + return $info; + } + } + + function packageInfo($field) + { + $arr = $this->getArray(true); + if ($field == 'state') { + return $arr['stability']['release']; + } + if ($field == 'api-version') { + return $arr['version']['api']; + } + if ($field == 'api-state') { + return $arr['stability']['api']; + } + if (isset($arr['old'][$field])) { + if (!is_string($arr['old'][$field])) { + return null; + } + return $arr['old'][$field]; + } + if (isset($arr[$field])) { + if (!is_string($arr[$field])) { + return null; + } + return $arr[$field]; + } + return null; + } + + function getName() + { + return $this->getPackage(); + } + + function getPackage() + { + if (isset($this->_packageInfo['name'])) { + return $this->_packageInfo['name']; + } + return false; + } + + function getChannel() + { + if (isset($this->_packageInfo['uri'])) { + return '__uri'; + } + if (isset($this->_packageInfo['channel'])) { + return strtolower($this->_packageInfo['channel']); + } + return false; + } + + function getUri() + { + if (isset($this->_packageInfo['uri'])) { + return $this->_packageInfo['uri']; + } + return false; + } + + function getExtends() + { + if (isset($this->_packageInfo['extends'])) { + return $this->_packageInfo['extends']; + } + return false; + } + + function getSummary() + { + if (isset($this->_packageInfo['summary'])) { + return $this->_packageInfo['summary']; + } + return false; + } + + function getDescription() + { + if (isset($this->_packageInfo['description'])) { + return $this->_packageInfo['description']; + } + return false; + } + + function getMaintainers($raw = false) + { + if (!isset($this->_packageInfo['lead'])) { + return false; + } + if ($raw) { + $ret = array('lead' => $this->_packageInfo['lead']); + (isset($this->_packageInfo['developer'])) ? + $ret['developer'] = $this->_packageInfo['developer'] :null; + (isset($this->_packageInfo['contributor'])) ? + $ret['contributor'] = $this->_packageInfo['contributor'] :null; + (isset($this->_packageInfo['helper'])) ? + $ret['helper'] = $this->_packageInfo['helper'] :null; + return $ret; + } else { + $ret = array(); + $leads = isset($this->_packageInfo['lead'][0]) ? $this->_packageInfo['lead'] : + array($this->_packageInfo['lead']); + foreach ($leads as $lead) { + $s = $lead; + $s['handle'] = $s['user']; + unset($s['user']); + $s['role'] = 'lead'; + $ret[] = $s; + } + if (isset($this->_packageInfo['developer'])) { + $leads = isset($this->_packageInfo['developer'][0]) ? + $this->_packageInfo['developer'] : + array($this->_packageInfo['developer']); + foreach ($leads as $maintainer) { + $s = $maintainer; + $s['handle'] = $s['user']; + unset($s['user']); + $s['role'] = 'developer'; + $ret[] = $s; + } + } + if (isset($this->_packageInfo['contributor'])) { + $leads = isset($this->_packageInfo['contributor'][0]) ? + $this->_packageInfo['contributor'] : + array($this->_packageInfo['contributor']); + foreach ($leads as $maintainer) { + $s = $maintainer; + $s['handle'] = $s['user']; + unset($s['user']); + $s['role'] = 'contributor'; + $ret[] = $s; + } + } + if (isset($this->_packageInfo['helper'])) { + $leads = isset($this->_packageInfo['helper'][0]) ? + $this->_packageInfo['helper'] : + array($this->_packageInfo['helper']); + foreach ($leads as $maintainer) { + $s = $maintainer; + $s['handle'] = $s['user']; + unset($s['user']); + $s['role'] = 'helper'; + $ret[] = $s; + } + } + return $ret; + } + return false; + } + + function getLeads() + { + if (isset($this->_packageInfo['lead'])) { + return $this->_packageInfo['lead']; + } + return false; + } + + function getDevelopers() + { + if (isset($this->_packageInfo['developer'])) { + return $this->_packageInfo['developer']; + } + return false; + } + + function getContributors() + { + if (isset($this->_packageInfo['contributor'])) { + return $this->_packageInfo['contributor']; + } + return false; + } + + function getHelpers() + { + if (isset($this->_packageInfo['helper'])) { + return $this->_packageInfo['helper']; + } + return false; + } + + function setDate($date) + { + if (!isset($this->_packageInfo['date'])) { + // ensure that the extends tag is set up in the right location + $this->_packageInfo = $this->_insertBefore($this->_packageInfo, + array('time', 'version', + 'stability', 'license', 'notes', 'contents', 'compatible', + 'dependencies', 'providesextension', 'srcpackage', 'srcuri', + 'phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', + 'zendextbinrelease', 'bundle', 'changelog'), array(), 'date'); + } + $this->_packageInfo['date'] = $date; + $this->_isValid = 0; + } + + function setTime($time) + { + $this->_isValid = 0; + if (!isset($this->_packageInfo['time'])) { + // ensure that the time tag is set up in the right location + $this->_packageInfo = $this->_insertBefore($this->_packageInfo, + array('version', + 'stability', 'license', 'notes', 'contents', 'compatible', + 'dependencies', 'providesextension', 'srcpackage', 'srcuri', + 'phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', + 'zendextbinrelease', 'bundle', 'changelog'), $time, 'time'); + } + $this->_packageInfo['time'] = $time; + } + + function getDate() + { + if (isset($this->_packageInfo['date'])) { + return $this->_packageInfo['date']; + } + return false; + } + + function getTime() + { + if (isset($this->_packageInfo['time'])) { + return $this->_packageInfo['time']; + } + return false; + } + + /** + * @param package|api version category to return + */ + function getVersion($key = 'release') + { + if (isset($this->_packageInfo['version'][$key])) { + return $this->_packageInfo['version'][$key]; + } + return false; + } + + function getStability() + { + if (isset($this->_packageInfo['stability'])) { + return $this->_packageInfo['stability']; + } + return false; + } + + function getState($key = 'release') + { + if (isset($this->_packageInfo['stability'][$key])) { + return $this->_packageInfo['stability'][$key]; + } + return false; + } + + function getLicense($raw = false) + { + if (isset($this->_packageInfo['license'])) { + if ($raw) { + return $this->_packageInfo['license']; + } + if (is_array($this->_packageInfo['license'])) { + return $this->_packageInfo['license']['_content']; + } else { + return $this->_packageInfo['license']; + } + } + return false; + } + + function getLicenseLocation() + { + if (!isset($this->_packageInfo['license']) || !is_array($this->_packageInfo['license'])) { + return false; + } + return $this->_packageInfo['license']['attribs']; + } + + function getNotes() + { + if (isset($this->_packageInfo['notes'])) { + return $this->_packageInfo['notes']; + } + return false; + } + + /** + * Return the tag contents, if any + * @return array|false + */ + function getUsesrole() + { + if (isset($this->_packageInfo['usesrole'])) { + return $this->_packageInfo['usesrole']; + } + return false; + } + + /** + * Return the tag contents, if any + * @return array|false + */ + function getUsestask() + { + if (isset($this->_packageInfo['usestask'])) { + return $this->_packageInfo['usestask']; + } + return false; + } + + /** + * This should only be used to retrieve filenames and install attributes + */ + function getFilelist($preserve = false) + { + if (isset($this->_packageInfo['filelist']) && !$preserve) { + return $this->_packageInfo['filelist']; + } + $this->flattenFilelist(); + if ($contents = $this->getContents()) { + $ret = array(); + if (!isset($contents['dir'])) { + return false; + } + if (!isset($contents['dir']['file'][0])) { + $contents['dir']['file'] = array($contents['dir']['file']); + } + foreach ($contents['dir']['file'] as $file) { + if (!isset($file['attribs']['name'])) { + continue; + } + $name = $file['attribs']['name']; + if (!$preserve) { + $file = $file['attribs']; + } + $ret[$name] = $file; + } + if (!$preserve) { + $this->_packageInfo['filelist'] = $ret; + } + return $ret; + } + return false; + } + + /** + * Return configure options array, if any + * + * @return array|false + */ + function getConfigureOptions() + { + if ($this->getPackageType() != 'extsrc' && $this->getPackageType() != 'zendextsrc') { + return false; + } + + $releases = $this->getReleases(); + if (isset($releases[0])) { + $releases = $releases[0]; + } + + if (isset($releases['configureoption'])) { + if (!isset($releases['configureoption'][0])) { + $releases['configureoption'] = array($releases['configureoption']); + } + + for ($i = 0; $i < count($releases['configureoption']); $i++) { + $releases['configureoption'][$i] = $releases['configureoption'][$i]['attribs']; + } + + return $releases['configureoption']; + } + + return false; + } + + /** + * This is only used at install-time, after all serialization + * is over. + */ + function resetFilelist() + { + $this->_packageInfo['filelist'] = array(); + } + + /** + * Retrieve a list of files that should be installed on this computer + * @return array + */ + function getInstallationFilelist($forfilecheck = false) + { + $contents = $this->getFilelist(true); + if (isset($contents['dir']['attribs']['baseinstalldir'])) { + $base = $contents['dir']['attribs']['baseinstalldir']; + } + if (isset($this->_packageInfo['bundle'])) { + return PEAR::raiseError( + 'Exception: bundles should be handled in download code only'); + } + $release = $this->getReleases(); + if ($release) { + if (!isset($release[0])) { + if (!isset($release['installconditions']) && !isset($release['filelist'])) { + if ($forfilecheck) { + return $this->getFilelist(); + } + return $contents; + } + $release = array($release); + } + $depchecker = &$this->getPEARDependency2($this->_config, array(), + array('channel' => $this->getChannel(), 'package' => $this->getPackage()), + PEAR_VALIDATE_INSTALLING); + foreach ($release as $instance) { + if (isset($instance['installconditions'])) { + $installconditions = $instance['installconditions']; + if (is_array($installconditions)) { + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + foreach ($installconditions as $type => $conditions) { + if (!isset($conditions[0])) { + $conditions = array($conditions); + } + foreach ($conditions as $condition) { + $ret = $depchecker->{"validate{$type}Dependency"}($condition); + if (PEAR::isError($ret)) { + PEAR::popErrorHandling(); + continue 3; // skip this release + } + } + } + PEAR::popErrorHandling(); + } + } + // this is the release to use + if (isset($instance['filelist'])) { + // ignore files + if (isset($instance['filelist']['ignore'])) { + $ignore = isset($instance['filelist']['ignore'][0]) ? + $instance['filelist']['ignore'] : + array($instance['filelist']['ignore']); + foreach ($ignore as $ig) { + unset ($contents[$ig['attribs']['name']]); + } + } + // install files as this name + if (isset($instance['filelist']['install'])) { + $installas = isset($instance['filelist']['install'][0]) ? + $instance['filelist']['install'] : + array($instance['filelist']['install']); + foreach ($installas as $as) { + $contents[$as['attribs']['name']]['attribs']['install-as'] = + $as['attribs']['as']; + } + } + } + if ($forfilecheck) { + foreach ($contents as $file => $attrs) { + $contents[$file] = $attrs['attribs']; + } + } + return $contents; + } + } else { // simple release - no installconditions or install-as + if ($forfilecheck) { + return $this->getFilelist(); + } + return $contents; + } + // no releases matched + return PEAR::raiseError('No releases in package.xml matched the existing operating ' . + 'system, extensions installed, or architecture, cannot install'); + } + + /** + * This is only used at install-time, after all serialization + * is over. + * @param string file name + * @param string installed path + */ + function setInstalledAs($file, $path) + { + if ($path) { + return $this->_packageInfo['filelist'][$file]['installed_as'] = $path; + } + unset($this->_packageInfo['filelist'][$file]['installed_as']); + } + + function getInstalledLocation($file) + { + if (isset($this->_packageInfo['filelist'][$file]['installed_as'])) { + return $this->_packageInfo['filelist'][$file]['installed_as']; + } + return false; + } + + /** + * This is only used at install-time, after all serialization + * is over. + */ + function installedFile($file, $atts) + { + if (isset($this->_packageInfo['filelist'][$file])) { + $this->_packageInfo['filelist'][$file] = + array_merge($this->_packageInfo['filelist'][$file], $atts['attribs']); + } else { + $this->_packageInfo['filelist'][$file] = $atts['attribs']; + } + } + + /** + * Retrieve the contents tag + */ + function getContents() + { + if (isset($this->_packageInfo['contents'])) { + return $this->_packageInfo['contents']; + } + return false; + } + + /** + * @param string full path to file + * @param string attribute name + * @param string attribute value + * @param int risky but fast - use this to choose a file based on its position in the list + * of files. Index is zero-based like PHP arrays. + * @return bool success of operation + */ + function setFileAttribute($filename, $attr, $value, $index = false) + { + $this->_isValid = 0; + if (in_array($attr, array('role', 'name', 'baseinstalldir'))) { + $this->_filesValid = false; + } + if ($index !== false && + isset($this->_packageInfo['contents']['dir']['file'][$index]['attribs'])) { + $this->_packageInfo['contents']['dir']['file'][$index]['attribs'][$attr] = $value; + return true; + } + if (!isset($this->_packageInfo['contents']['dir']['file'])) { + return false; + } + $files = $this->_packageInfo['contents']['dir']['file']; + if (!isset($files[0])) { + $files = array($files); + $ind = false; + } else { + $ind = true; + } + foreach ($files as $i => $file) { + if (isset($file['attribs'])) { + if ($file['attribs']['name'] == $filename) { + if ($ind) { + $this->_packageInfo['contents']['dir']['file'][$i]['attribs'][$attr] = $value; + } else { + $this->_packageInfo['contents']['dir']['file']['attribs'][$attr] = $value; + } + return true; + } + } + } + return false; + } + + function setDirtree($path) + { + if (!isset($this->_packageInfo['dirtree'])) { + $this->_packageInfo['dirtree'] = array(); + } + $this->_packageInfo['dirtree'][$path] = true; + } + + function getDirtree() + { + if (isset($this->_packageInfo['dirtree']) && count($this->_packageInfo['dirtree'])) { + return $this->_packageInfo['dirtree']; + } + return false; + } + + function resetDirtree() + { + unset($this->_packageInfo['dirtree']); + } + + /** + * Determines whether this package claims it is compatible with the version of + * the package that has a recommended version dependency + * @param PEAR_PackageFile_v2|PEAR_PackageFile_v1|PEAR_Downloader_Package + * @return boolean + */ + function isCompatible($pf) + { + if (!isset($this->_packageInfo['compatible'])) { + return false; + } + if (!isset($this->_packageInfo['channel'])) { + return false; + } + $me = $pf->getVersion(); + $compatible = $this->_packageInfo['compatible']; + if (!isset($compatible[0])) { + $compatible = array($compatible); + } + $found = false; + foreach ($compatible as $info) { + if (strtolower($info['name']) == strtolower($pf->getPackage())) { + if (strtolower($info['channel']) == strtolower($pf->getChannel())) { + $found = true; + break; + } + } + } + if (!$found) { + return false; + } + if (isset($info['exclude'])) { + if (!isset($info['exclude'][0])) { + $info['exclude'] = array($info['exclude']); + } + foreach ($info['exclude'] as $exclude) { + if (version_compare($me, $exclude, '==')) { + return false; + } + } + } + if (version_compare($me, $info['min'], '>=') && version_compare($me, $info['max'], '<=')) { + return true; + } + return false; + } + + /** + * @return array|false + */ + function getCompatible() + { + if (isset($this->_packageInfo['compatible'])) { + return $this->_packageInfo['compatible']; + } + return false; + } + + function getDependencies() + { + if (isset($this->_packageInfo['dependencies'])) { + return $this->_packageInfo['dependencies']; + } + return false; + } + + function isSubpackageOf($p) + { + return $p->isSubpackage($this); + } + + /** + * Determines whether the passed in package is a subpackage of this package. + * + * No version checking is done, only name verification. + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * @return bool + */ + function isSubpackage($p) + { + $sub = array(); + if (isset($this->_packageInfo['dependencies']['required']['subpackage'])) { + $sub = $this->_packageInfo['dependencies']['required']['subpackage']; + if (!isset($sub[0])) { + $sub = array($sub); + } + } + if (isset($this->_packageInfo['dependencies']['optional']['subpackage'])) { + $sub1 = $this->_packageInfo['dependencies']['optional']['subpackage']; + if (!isset($sub1[0])) { + $sub1 = array($sub1); + } + $sub = array_merge($sub, $sub1); + } + if (isset($this->_packageInfo['dependencies']['group'])) { + $group = $this->_packageInfo['dependencies']['group']; + if (!isset($group[0])) { + $group = array($group); + } + foreach ($group as $deps) { + if (isset($deps['subpackage'])) { + $sub2 = $deps['subpackage']; + if (!isset($sub2[0])) { + $sub2 = array($sub2); + } + $sub = array_merge($sub, $sub2); + } + } + } + foreach ($sub as $dep) { + if (strtolower($dep['name']) == strtolower($p->getPackage())) { + if (isset($dep['channel'])) { + if (strtolower($dep['channel']) == strtolower($p->getChannel())) { + return true; + } + } else { + if ($dep['uri'] == $p->getURI()) { + return true; + } + } + } + } + return false; + } + + function dependsOn($package, $channel) + { + if (!($deps = $this->getDependencies())) { + return false; + } + foreach (array('package', 'subpackage') as $type) { + foreach (array('required', 'optional') as $needed) { + if (isset($deps[$needed][$type])) { + if (!isset($deps[$needed][$type][0])) { + $deps[$needed][$type] = array($deps[$needed][$type]); + } + foreach ($deps[$needed][$type] as $dep) { + $depchannel = isset($dep['channel']) ? $dep['channel'] : '__uri'; + if (strtolower($dep['name']) == strtolower($package) && + $depchannel == $channel) { + return true; + } + } + } + } + if (isset($deps['group'])) { + if (!isset($deps['group'][0])) { + $dep['group'] = array($deps['group']); + } + foreach ($deps['group'] as $group) { + if (isset($group[$type])) { + if (!is_array($group[$type])) { + $group[$type] = array($group[$type]); + } + foreach ($group[$type] as $dep) { + $depchannel = isset($dep['channel']) ? $dep['channel'] : '__uri'; + if (strtolower($dep['name']) == strtolower($package) && + $depchannel == $channel) { + return true; + } + } + } + } + } + } + return false; + } + + /** + * Get the contents of a dependency group + * @param string + * @return array|false + */ + function getDependencyGroup($name) + { + $name = strtolower($name); + if (!isset($this->_packageInfo['dependencies']['group'])) { + return false; + } + $groups = $this->_packageInfo['dependencies']['group']; + if (!isset($groups[0])) { + $groups = array($groups); + } + foreach ($groups as $group) { + if (strtolower($group['attribs']['name']) == $name) { + return $group; + } + } + return false; + } + + /** + * Retrieve a partial package.xml 1.0 representation of dependencies + * + * a very limited representation of dependencies is returned by this method. + * The tag for excluding certain versions of a dependency is + * completely ignored. In addition, dependency groups are ignored, with the + * assumption that all dependencies in dependency groups are also listed in + * the optional group that work with all dependency groups + * @param boolean return package.xml 2.0 tag + * @return array|false + */ + function getDeps($raw = false, $nopearinstaller = false) + { + if (isset($this->_packageInfo['dependencies'])) { + if ($raw) { + return $this->_packageInfo['dependencies']; + } + $ret = array(); + $map = array( + 'php' => 'php', + 'package' => 'pkg', + 'subpackage' => 'pkg', + 'extension' => 'ext', + 'os' => 'os', + 'pearinstaller' => 'pkg', + ); + foreach (array('required', 'optional') as $type) { + $optional = ($type == 'optional') ? 'yes' : 'no'; + if (!isset($this->_packageInfo['dependencies'][$type]) + || empty($this->_packageInfo['dependencies'][$type])) { + continue; + } + foreach ($this->_packageInfo['dependencies'][$type] as $dtype => $deps) { + if ($dtype == 'pearinstaller' && $nopearinstaller) { + continue; + } + if (!isset($deps[0])) { + $deps = array($deps); + } + foreach ($deps as $dep) { + if (!isset($map[$dtype])) { + // no support for arch type + continue; + } + if ($dtype == 'pearinstaller') { + $dep['name'] = 'PEAR'; + $dep['channel'] = 'pear.php.net'; + } + $s = array('type' => $map[$dtype]); + if (isset($dep['channel'])) { + $s['channel'] = $dep['channel']; + } + if (isset($dep['uri'])) { + $s['uri'] = $dep['uri']; + } + if (isset($dep['name'])) { + $s['name'] = $dep['name']; + } + if (isset($dep['conflicts'])) { + $s['rel'] = 'not'; + } else { + if (!isset($dep['min']) && + !isset($dep['max'])) { + $s['rel'] = 'has'; + $s['optional'] = $optional; + } elseif (isset($dep['min']) && + isset($dep['max'])) { + $s['rel'] = 'ge'; + $s1 = $s; + $s1['rel'] = 'le'; + $s['version'] = $dep['min']; + $s1['version'] = $dep['max']; + if (isset($dep['channel'])) { + $s1['channel'] = $dep['channel']; + } + if ($dtype != 'php') { + $s['name'] = $dep['name']; + $s1['name'] = $dep['name']; + } + $s['optional'] = $optional; + $s1['optional'] = $optional; + $ret[] = $s1; + } elseif (isset($dep['min'])) { + if (isset($dep['exclude']) && + $dep['exclude'] == $dep['min']) { + $s['rel'] = 'gt'; + } else { + $s['rel'] = 'ge'; + } + $s['version'] = $dep['min']; + $s['optional'] = $optional; + if ($dtype != 'php') { + $s['name'] = $dep['name']; + } + } elseif (isset($dep['max'])) { + if (isset($dep['exclude']) && + $dep['exclude'] == $dep['max']) { + $s['rel'] = 'lt'; + } else { + $s['rel'] = 'le'; + } + $s['version'] = $dep['max']; + $s['optional'] = $optional; + if ($dtype != 'php') { + $s['name'] = $dep['name']; + } + } + } + $ret[] = $s; + } + } + } + if (count($ret)) { + return $ret; + } + } + return false; + } + + /** + * @return php|extsrc|extbin|zendextsrc|zendextbin|bundle|false + */ + function getPackageType() + { + if (isset($this->_packageInfo['phprelease'])) { + return 'php'; + } + if (isset($this->_packageInfo['extsrcrelease'])) { + return 'extsrc'; + } + if (isset($this->_packageInfo['extbinrelease'])) { + return 'extbin'; + } + if (isset($this->_packageInfo['zendextsrcrelease'])) { + return 'zendextsrc'; + } + if (isset($this->_packageInfo['zendextbinrelease'])) { + return 'zendextbin'; + } + if (isset($this->_packageInfo['bundle'])) { + return 'bundle'; + } + return false; + } + + /** + * @return array|false + */ + function getReleases() + { + $type = $this->getPackageType(); + if ($type != 'bundle') { + $type .= 'release'; + } + if ($this->getPackageType() && isset($this->_packageInfo[$type])) { + return $this->_packageInfo[$type]; + } + return false; + } + + /** + * @return array + */ + function getChangelog() + { + if (isset($this->_packageInfo['changelog'])) { + return $this->_packageInfo['changelog']; + } + return false; + } + + function hasDeps() + { + return isset($this->_packageInfo['dependencies']); + } + + function getPackagexmlVersion() + { + if (isset($this->_packageInfo['zendextsrcrelease'])) { + return '2.1'; + } + if (isset($this->_packageInfo['zendextbinrelease'])) { + return '2.1'; + } + return '2.0'; + } + + /** + * @return array|false + */ + function getSourcePackage() + { + if (isset($this->_packageInfo['extbinrelease']) || + isset($this->_packageInfo['zendextbinrelease'])) { + return array('channel' => $this->_packageInfo['srcchannel'], + 'package' => $this->_packageInfo['srcpackage']); + } + return false; + } + + function getBundledPackages() + { + if (isset($this->_packageInfo['bundle'])) { + return $this->_packageInfo['contents']['bundledpackage']; + } + return false; + } + + function getLastModified() + { + if (isset($this->_packageInfo['_lastmodified'])) { + return $this->_packageInfo['_lastmodified']; + } + return false; + } + + /** + * Get the contents of a file listed within the package.xml + * @param string + * @return string + */ + function getFileContents($file) + { + if ($this->_archiveFile == $this->_packageFile) { // unpacked + $dir = dirname($this->_packageFile); + $file = $dir . DIRECTORY_SEPARATOR . $file; + $file = str_replace(array('/', '\\'), + array(DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR), $file); + if (file_exists($file) && is_readable($file)) { + return implode('', file($file)); + } + } else { // tgz + $tar = new Archive_Tar($this->_archiveFile); + $tar->pushErrorHandling(PEAR_ERROR_RETURN); + if ($file != 'package.xml' && $file != 'package2.xml') { + $file = $this->getPackage() . '-' . $this->getVersion() . '/' . $file; + } + $file = $tar->extractInString($file); + $tar->popErrorHandling(); + if (PEAR::isError($file)) { + return PEAR::raiseError("Cannot locate file '$file' in archive"); + } + return $file; + } + } + + function &getRW() + { + if (!class_exists('PEAR_PackageFile_v2_rw')) { + require_once 'PEAR/PackageFile/v2/rw.php'; + } + $a = new PEAR_PackageFile_v2_rw; + foreach (get_object_vars($this) as $name => $unused) { + if (!isset($this->$name)) { + continue; + } + if ($name == '_config' || $name == '_logger'|| $name == '_registry' || + $name == '_stack') { + $a->$name = &$this->$name; + } else { + $a->$name = $this->$name; + } + } + return $a; + } + + function &getDefaultGenerator() + { + if (!class_exists('PEAR_PackageFile_Generator_v2')) { + require_once 'PEAR/PackageFile/Generator/v2.php'; + } + $a = new PEAR_PackageFile_Generator_v2($this); + return $a; + } + + function analyzeSourceCode($file, $string = false) + { + if (!isset($this->_v2Validator) || + !is_a($this->_v2Validator, 'PEAR_PackageFile_v2_Validator')) { + if (!class_exists('PEAR_PackageFile_v2_Validator')) { + require_once 'PEAR/PackageFile/v2/Validator.php'; + } + $this->_v2Validator = new PEAR_PackageFile_v2_Validator; + } + return $this->_v2Validator->analyzeSourceCode($file, $string); + } + + function validate($state = PEAR_VALIDATE_NORMAL) + { + if (!isset($this->_packageInfo) || !is_array($this->_packageInfo)) { + return false; + } + if (!isset($this->_v2Validator) || + !is_a($this->_v2Validator, 'PEAR_PackageFile_v2_Validator')) { + if (!class_exists('PEAR_PackageFile_v2_Validator')) { + require_once 'PEAR/PackageFile/v2/Validator.php'; + } + $this->_v2Validator = new PEAR_PackageFile_v2_Validator; + } + if (isset($this->_packageInfo['xsdversion'])) { + unset($this->_packageInfo['xsdversion']); + } + return $this->_v2Validator->validate($this, $state); + } + + function getTasksNs() + { + if (!isset($this->_tasksNs)) { + if (isset($this->_packageInfo['attribs'])) { + foreach ($this->_packageInfo['attribs'] as $name => $value) { + if ($value == 'http://pear.php.net/dtd/tasks-1.0') { + $this->_tasksNs = str_replace('xmlns:', '', $name); + break; + } + } + } + } + return $this->_tasksNs; + } + + /** + * Determine whether a task name is a valid task. Custom tasks may be defined + * using subdirectories by putting a "-" in the name, as in + * + * Note that this method will auto-load the task class file and test for the existence + * of the name with "-" replaced by "_" as in PEAR/Task/mycustom/task.php makes class + * PEAR_Task_mycustom_task + * @param string + * @return boolean + */ + function getTask($task) + { + $this->getTasksNs(); + // transform all '-' to '/' and 'tasks:' to '' so tasks:replace becomes replace + $task = str_replace(array($this->_tasksNs . ':', '-'), array('', ' '), $task); + $taskfile = str_replace(' ', '/', ucwords($task)); + $task = str_replace(array(' ', '/'), '_', ucwords($task)); + if (class_exists("PEAR_Task_$task")) { + return "PEAR_Task_$task"; + } + $fp = @fopen("PEAR/Task/$taskfile.php", 'r', true); + if ($fp) { + fclose($fp); + require_once "PEAR/Task/$taskfile.php"; + return "PEAR_Task_$task"; + } + return false; + } + + /** + * Key-friendly array_splice + * @param tagname to splice a value in before + * @param mixed the value to splice in + * @param string the new tag name + */ + function _ksplice($array, $key, $value, $newkey) + { + $offset = array_search($key, array_keys($array)); + $after = array_slice($array, $offset); + $before = array_slice($array, 0, $offset); + $before[$newkey] = $value; + return array_merge($before, $after); + } + + /** + * @param array a list of possible keys, in the order they may occur + * @param mixed contents of the new package.xml tag + * @param string tag name + * @access private + */ + function _insertBefore($array, $keys, $contents, $newkey) + { + foreach ($keys as $key) { + if (isset($array[$key])) { + return $array = $this->_ksplice($array, $key, $contents, $newkey); + } + } + $array[$newkey] = $contents; + return $array; + } + + /** + * @param subsection of {@link $_packageInfo} + * @param array|string tag contents + * @param array format: + *
    +     * array(
    +     *   tagname => array(list of tag names that follow this one),
    +     *   childtagname => array(list of child tag names that follow this one),
    +     * )
    +     * 
    + * + * This allows construction of nested tags + * @access private + */ + function _mergeTag($manip, $contents, $order) + { + if (count($order)) { + foreach ($order as $tag => $curorder) { + if (!isset($manip[$tag])) { + // ensure that the tag is set up + $manip = $this->_insertBefore($manip, $curorder, array(), $tag); + } + if (count($order) > 1) { + $manip[$tag] = $this->_mergeTag($manip[$tag], $contents, array_slice($order, 1)); + return $manip; + } + } + } else { + return $manip; + } + if (is_array($manip[$tag]) && !empty($manip[$tag]) && isset($manip[$tag][0])) { + $manip[$tag][] = $contents; + } else { + if (!count($manip[$tag])) { + $manip[$tag] = $contents; + } else { + $manip[$tag] = array($manip[$tag]); + $manip[$tag][] = $contents; + } + } + return $manip; + } +} +?> diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/PackageFile/v2/Validator.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/PackageFile/v2/Validator.php new file mode 100644 index 0000000..eff9d03 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/PackageFile/v2/Validator.php @@ -0,0 +1,2135 @@ + + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a8 + */ +/** + * Private validation class used by PEAR_PackageFile_v2 - do not use directly, its + * sole purpose is to split up the PEAR/PackageFile/v2.php file to make it smaller + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a8 + * @access private + */ +class PEAR_PackageFile_v2_Validator +{ + /** + * @var array + */ + var $_packageInfo; + /** + * @var PEAR_PackageFile_v2 + */ + var $_pf; + /** + * @var PEAR_ErrorStack + */ + var $_stack; + /** + * @var int + */ + var $_isValid = 0; + /** + * @var int + */ + var $_filesValid = 0; + /** + * @var int + */ + var $_curState = 0; + /** + * @param PEAR_PackageFile_v2 + * @param int + */ + function validate(&$pf, $state = PEAR_VALIDATE_NORMAL) + { + $this->_pf = &$pf; + $this->_curState = $state; + $this->_packageInfo = $this->_pf->getArray(); + $this->_isValid = $this->_pf->_isValid; + $this->_filesValid = $this->_pf->_filesValid; + $this->_stack = &$pf->_stack; + $this->_stack->getErrors(true); + if (($this->_isValid & $state) == $state) { + return true; + } + if (!isset($this->_packageInfo) || !is_array($this->_packageInfo)) { + return false; + } + if (!isset($this->_packageInfo['attribs']['version']) || + ($this->_packageInfo['attribs']['version'] != '2.0' && + $this->_packageInfo['attribs']['version'] != '2.1') + ) { + $this->_noPackageVersion(); + } + $structure = + array( + 'name', + 'channel|uri', + '*extends', // can't be multiple, but this works fine + 'summary', + 'description', + '+lead', // these all need content checks + '*developer', + '*contributor', + '*helper', + 'date', + '*time', + 'version', + 'stability', + 'license->?uri->?filesource', + 'notes', + 'contents', //special validation needed + '*compatible', + 'dependencies', //special validation needed + '*usesrole', + '*usestask', // reserve these for 1.4.0a1 to implement + // this will allow a package.xml to gracefully say it + // needs a certain package installed in order to implement a role or task + '*providesextension', + '*srcpackage|*srcuri', + '+phprelease|+extsrcrelease|+extbinrelease|' . + '+zendextsrcrelease|+zendextbinrelease|bundle', //special validation needed + '*changelog', + ); + $test = $this->_packageInfo; + if (isset($test['dependencies']) && + isset($test['dependencies']['required']) && + isset($test['dependencies']['required']['pearinstaller']) && + isset($test['dependencies']['required']['pearinstaller']['min']) && + '1.10.1' != '@package' . '_version@' && + version_compare('1.10.1', + $test['dependencies']['required']['pearinstaller']['min'], '<') + ) { + $this->_pearVersionTooLow($test['dependencies']['required']['pearinstaller']['min']); + return false; + } + // ignore post-installation array fields + if (array_key_exists('filelist', $test)) { + unset($test['filelist']); + } + if (array_key_exists('_lastmodified', $test)) { + unset($test['_lastmodified']); + } + if (array_key_exists('#binarypackage', $test)) { + unset($test['#binarypackage']); + } + if (array_key_exists('old', $test)) { + unset($test['old']); + } + if (array_key_exists('_lastversion', $test)) { + unset($test['_lastversion']); + } + if (!$this->_stupidSchemaValidate($structure, $test, '')) { + return false; + } + if (empty($this->_packageInfo['name'])) { + $this->_tagCannotBeEmpty('name'); + } + $test = isset($this->_packageInfo['uri']) ? 'uri' :'channel'; + if (empty($this->_packageInfo[$test])) { + $this->_tagCannotBeEmpty($test); + } + if (is_array($this->_packageInfo['license']) && + (!isset($this->_packageInfo['license']['_content']) || + empty($this->_packageInfo['license']['_content']))) { + $this->_tagCannotBeEmpty('license'); + } elseif (empty($this->_packageInfo['license'])) { + $this->_tagCannotBeEmpty('license'); + } + if (empty($this->_packageInfo['summary'])) { + $this->_tagCannotBeEmpty('summary'); + } + if (empty($this->_packageInfo['description'])) { + $this->_tagCannotBeEmpty('description'); + } + if (empty($this->_packageInfo['date'])) { + $this->_tagCannotBeEmpty('date'); + } + if (empty($this->_packageInfo['notes'])) { + $this->_tagCannotBeEmpty('notes'); + } + if (isset($this->_packageInfo['time']) && empty($this->_packageInfo['time'])) { + $this->_tagCannotBeEmpty('time'); + } + if (isset($this->_packageInfo['dependencies'])) { + $this->_validateDependencies(); + } + if (isset($this->_packageInfo['compatible'])) { + $this->_validateCompatible(); + } + if (!isset($this->_packageInfo['bundle'])) { + if (empty($this->_packageInfo['contents'])) { + $this->_tagCannotBeEmpty('contents'); + } + if (!isset($this->_packageInfo['contents']['dir'])) { + $this->_filelistMustContainDir('contents'); + return false; + } + if (isset($this->_packageInfo['contents']['file'])) { + $this->_filelistCannotContainFile('contents'); + return false; + } + } + $this->_validateMaintainers(); + $this->_validateStabilityVersion(); + $fail = false; + if (array_key_exists('usesrole', $this->_packageInfo)) { + $roles = $this->_packageInfo['usesrole']; + if (!is_array($roles) || !isset($roles[0])) { + $roles = array($roles); + } + foreach ($roles as $role) { + if (!isset($role['role'])) { + $this->_usesroletaskMustHaveRoleTask('usesrole', 'role'); + $fail = true; + } else { + if (!isset($role['channel'])) { + if (!isset($role['uri'])) { + $this->_usesroletaskMustHaveChannelOrUri($role['role'], 'usesrole'); + $fail = true; + } + } elseif (!isset($role['package'])) { + $this->_usesroletaskMustHavePackage($role['role'], 'usesrole'); + $fail = true; + } + } + } + } + if (array_key_exists('usestask', $this->_packageInfo)) { + $roles = $this->_packageInfo['usestask']; + if (!is_array($roles) || !isset($roles[0])) { + $roles = array($roles); + } + foreach ($roles as $role) { + if (!isset($role['task'])) { + $this->_usesroletaskMustHaveRoleTask('usestask', 'task'); + $fail = true; + } else { + if (!isset($role['channel'])) { + if (!isset($role['uri'])) { + $this->_usesroletaskMustHaveChannelOrUri($role['task'], 'usestask'); + $fail = true; + } + } elseif (!isset($role['package'])) { + $this->_usesroletaskMustHavePackage($role['task'], 'usestask'); + $fail = true; + } + } + } + } + + if ($fail) { + return false; + } + + $list = $this->_packageInfo['contents']; + if (isset($list['dir']) && is_array($list['dir']) && isset($list['dir'][0])) { + $this->_multipleToplevelDirNotAllowed(); + return $this->_isValid = 0; + } + + $this->_validateFilelist(); + $this->_validateRelease(); + if (!$this->_stack->hasErrors()) { + $chan = $this->_pf->_registry->getChannel($this->_pf->getChannel(), true); + if (PEAR::isError($chan)) { + $this->_unknownChannel($this->_pf->getChannel()); + } else { + $valpack = $chan->getValidationPackage(); + // for channel validator packages, always use the default PEAR validator. + // otherwise, they can't be installed or packaged + $validator = $chan->getValidationObject($this->_pf->getPackage()); + if (!$validator) { + $this->_stack->push(__FUNCTION__, 'error', + array('channel' => $chan->getName(), + 'package' => $this->_pf->getPackage(), + 'name' => $valpack['_content'], + 'version' => $valpack['attribs']['version']), + 'package "%channel%/%package%" cannot be properly validated without ' . + 'validation package "%channel%/%name%-%version%"'); + return $this->_isValid = 0; + } + $validator->setPackageFile($this->_pf); + $validator->validate($state); + $failures = $validator->getFailures(); + foreach ($failures['errors'] as $error) { + $this->_stack->push(__FUNCTION__, 'error', $error, + 'Channel validator error: field "%field%" - %reason%'); + } + foreach ($failures['warnings'] as $warning) { + $this->_stack->push(__FUNCTION__, 'warning', $warning, + 'Channel validator warning: field "%field%" - %reason%'); + } + } + } + + $this->_pf->_isValid = $this->_isValid = !$this->_stack->hasErrors('error'); + if ($this->_isValid && $state == PEAR_VALIDATE_PACKAGING && !$this->_filesValid) { + if ($this->_pf->getPackageType() == 'bundle') { + if ($this->_analyzeBundledPackages()) { + $this->_filesValid = $this->_pf->_filesValid = true; + } else { + $this->_pf->_isValid = $this->_isValid = 0; + } + } else { + if (!$this->_analyzePhpFiles()) { + $this->_pf->_isValid = $this->_isValid = 0; + } else { + $this->_filesValid = $this->_pf->_filesValid = true; + } + } + } + + if ($this->_isValid) { + return $this->_pf->_isValid = $this->_isValid = $state; + } + + return $this->_pf->_isValid = $this->_isValid = 0; + } + + function _stupidSchemaValidate($structure, $xml, $root) + { + if (!is_array($xml)) { + $xml = array(); + } + $keys = array_keys($xml); + reset($keys); + $key = current($keys); + while ($key == 'attribs' || $key == '_contents') { + $key = next($keys); + } + $unfoundtags = $optionaltags = array(); + $ret = true; + $mismatch = false; + foreach ($structure as $struc) { + if ($key) { + $tag = $xml[$key]; + } + $test = $this->_processStructure($struc); + if (isset($test['choices'])) { + $loose = true; + foreach ($test['choices'] as $choice) { + if ($key == $choice['tag']) { + $key = next($keys); + while ($key == 'attribs' || $key == '_contents') { + $key = next($keys); + } + $unfoundtags = $optionaltags = array(); + $mismatch = false; + if ($key && $key != $choice['tag'] && isset($choice['multiple'])) { + $unfoundtags[] = $choice['tag']; + $optionaltags[] = $choice['tag']; + if ($key) { + $mismatch = true; + } + } + $ret &= $this->_processAttribs($choice, $tag, $root); + continue 2; + } else { + $unfoundtags[] = $choice['tag']; + $mismatch = true; + } + if (!isset($choice['multiple']) || $choice['multiple'] != '*') { + $loose = false; + } else { + $optionaltags[] = $choice['tag']; + } + } + if (!$loose) { + $this->_invalidTagOrder($unfoundtags, $key, $root); + return false; + } + } else { + if ($key != $test['tag']) { + if (isset($test['multiple']) && $test['multiple'] != '*') { + $unfoundtags[] = $test['tag']; + $this->_invalidTagOrder($unfoundtags, $key, $root); + return false; + } else { + if ($key) { + $mismatch = true; + } + $unfoundtags[] = $test['tag']; + $optionaltags[] = $test['tag']; + } + if (!isset($test['multiple'])) { + $this->_invalidTagOrder($unfoundtags, $key, $root); + return false; + } + continue; + } else { + $unfoundtags = $optionaltags = array(); + $mismatch = false; + } + $key = next($keys); + while ($key == 'attribs' || $key == '_contents') { + $key = next($keys); + } + if ($key && $key != $test['tag'] && isset($test['multiple'])) { + $unfoundtags[] = $test['tag']; + $optionaltags[] = $test['tag']; + $mismatch = true; + } + $ret &= $this->_processAttribs($test, $tag, $root); + continue; + } + } + if (!$mismatch && count($optionaltags)) { + // don't error out on any optional tags + $unfoundtags = array_diff($unfoundtags, $optionaltags); + } + if (count($unfoundtags)) { + $this->_invalidTagOrder($unfoundtags, $key, $root); + } elseif ($key) { + // unknown tags + $this->_invalidTagOrder('*no tags allowed here*', $key, $root); + while ($key = next($keys)) { + $this->_invalidTagOrder('*no tags allowed here*', $key, $root); + } + } + return $ret; + } + + function _processAttribs($choice, $tag, $context) + { + if (isset($choice['attribs'])) { + if (!is_array($tag)) { + $tag = array($tag); + } + $tags = $tag; + if (!isset($tags[0])) { + $tags = array($tags); + } + $ret = true; + foreach ($tags as $i => $tag) { + if (!is_array($tag) || !isset($tag['attribs'])) { + foreach ($choice['attribs'] as $attrib) { + if ($attrib{0} != '?') { + $ret &= $this->_tagHasNoAttribs($choice['tag'], + $context); + continue 2; + } + } + } + foreach ($choice['attribs'] as $attrib) { + if ($attrib{0} != '?') { + if (!isset($tag['attribs'][$attrib])) { + $ret &= $this->_tagMissingAttribute($choice['tag'], + $attrib, $context); + } + } + } + } + return $ret; + } + return true; + } + + function _processStructure($key) + { + $ret = array(); + if (count($pieces = explode('|', $key)) > 1) { + $ret['choices'] = array(); + foreach ($pieces as $piece) { + $ret['choices'][] = $this->_processStructure($piece); + } + return $ret; + } + $multi = $key{0}; + if ($multi == '+' || $multi == '*') { + $ret['multiple'] = $key{0}; + $key = substr($key, 1); + } + if (count($attrs = explode('->', $key)) > 1) { + $ret['tag'] = array_shift($attrs); + $ret['attribs'] = $attrs; + } else { + $ret['tag'] = $key; + } + return $ret; + } + + function _validateStabilityVersion() + { + $structure = array('release', 'api'); + $a = $this->_stupidSchemaValidate($structure, $this->_packageInfo['version'], ''); + $a &= $this->_stupidSchemaValidate($structure, $this->_packageInfo['stability'], ''); + if ($a) { + if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', + $this->_packageInfo['version']['release'])) { + $this->_invalidVersion('release', $this->_packageInfo['version']['release']); + } + if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', + $this->_packageInfo['version']['api'])) { + $this->_invalidVersion('api', $this->_packageInfo['version']['api']); + } + if (!in_array($this->_packageInfo['stability']['release'], + array('snapshot', 'devel', 'alpha', 'beta', 'stable'))) { + $this->_invalidState('release', $this->_packageInfo['stability']['release']); + } + if (!in_array($this->_packageInfo['stability']['api'], + array('devel', 'alpha', 'beta', 'stable'))) { + $this->_invalidState('api', $this->_packageInfo['stability']['api']); + } + } + } + + function _validateMaintainers() + { + $structure = + array( + 'name', + 'user', + 'email', + 'active', + ); + foreach (array('lead', 'developer', 'contributor', 'helper') as $type) { + if (!isset($this->_packageInfo[$type])) { + continue; + } + if (isset($this->_packageInfo[$type][0])) { + foreach ($this->_packageInfo[$type] as $lead) { + $this->_stupidSchemaValidate($structure, $lead, '<' . $type . '>'); + } + } else { + $this->_stupidSchemaValidate($structure, $this->_packageInfo[$type], + '<' . $type . '>'); + } + } + } + + function _validatePhpDep($dep, $installcondition = false) + { + $structure = array( + 'min', + '*max', + '*exclude', + ); + $type = $installcondition ? '' : ''; + $this->_stupidSchemaValidate($structure, $dep, $type); + if (isset($dep['min'])) { + if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?(?:-[a-zA-Z0-9]+)?\\z/', + $dep['min'])) { + $this->_invalidVersion($type . '', $dep['min']); + } + } + if (isset($dep['max'])) { + if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?(?:-[a-zA-Z0-9]+)?\\z/', + $dep['max'])) { + $this->_invalidVersion($type . '', $dep['max']); + } + } + if (isset($dep['exclude'])) { + if (!is_array($dep['exclude'])) { + $dep['exclude'] = array($dep['exclude']); + } + foreach ($dep['exclude'] as $exclude) { + if (!preg_match( + '/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?(?:-[a-zA-Z0-9]+)?\\z/', + $exclude)) { + $this->_invalidVersion($type . '', $exclude); + } + } + } + } + + function _validatePearinstallerDep($dep) + { + $structure = array( + 'min', + '*max', + '*recommended', + '*exclude', + ); + $this->_stupidSchemaValidate($structure, $dep, ''); + if (isset($dep['min'])) { + if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', + $dep['min'])) { + $this->_invalidVersion('', + $dep['min']); + } + } + if (isset($dep['max'])) { + if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', + $dep['max'])) { + $this->_invalidVersion('', + $dep['max']); + } + } + if (isset($dep['recommended'])) { + if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', + $dep['recommended'])) { + $this->_invalidVersion('', + $dep['recommended']); + } + } + if (isset($dep['exclude'])) { + if (!is_array($dep['exclude'])) { + $dep['exclude'] = array($dep['exclude']); + } + foreach ($dep['exclude'] as $exclude) { + if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', + $exclude)) { + $this->_invalidVersion('', + $exclude); + } + } + } + } + + function _validatePackageDep($dep, $group, $type = '') + { + if (isset($dep['uri'])) { + if (isset($dep['conflicts'])) { + $structure = array( + 'name', + 'uri', + 'conflicts', + '*providesextension', + ); + } else { + $structure = array( + 'name', + 'uri', + '*providesextension', + ); + } + } else { + if (isset($dep['conflicts'])) { + $structure = array( + 'name', + 'channel', + '*min', + '*max', + '*exclude', + 'conflicts', + '*providesextension', + ); + } else { + $structure = array( + 'name', + 'channel', + '*min', + '*max', + '*recommended', + '*exclude', + '*nodefault', + '*providesextension', + ); + } + } + if (isset($dep['name'])) { + $type .= '' . $dep['name'] . ''; + } + $this->_stupidSchemaValidate($structure, $dep, '' . $group . $type); + if (isset($dep['uri']) && (isset($dep['min']) || isset($dep['max']) || + isset($dep['recommended']) || isset($dep['exclude']))) { + $this->_uriDepsCannotHaveVersioning('' . $group . $type); + } + if (isset($dep['channel']) && strtolower($dep['channel']) == '__uri') { + $this->_DepchannelCannotBeUri('' . $group . $type); + } + if (isset($dep['min'])) { + if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', + $dep['min'])) { + $this->_invalidVersion('' . $group . $type . '', $dep['min']); + } + } + if (isset($dep['max'])) { + if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', + $dep['max'])) { + $this->_invalidVersion('' . $group . $type . '', $dep['max']); + } + } + if (isset($dep['recommended'])) { + if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', + $dep['recommended'])) { + $this->_invalidVersion('' . $group . $type . '', + $dep['recommended']); + } + } + if (isset($dep['exclude'])) { + if (!is_array($dep['exclude'])) { + $dep['exclude'] = array($dep['exclude']); + } + foreach ($dep['exclude'] as $exclude) { + if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', + $exclude)) { + $this->_invalidVersion('' . $group . $type . '', + $exclude); + } + } + } + } + + function _validateSubpackageDep($dep, $group) + { + $this->_validatePackageDep($dep, $group, ''); + if (isset($dep['providesextension'])) { + $this->_subpackageCannotProvideExtension(isset($dep['name']) ? $dep['name'] : ''); + } + if (isset($dep['conflicts'])) { + $this->_subpackagesCannotConflict(isset($dep['name']) ? $dep['name'] : ''); + } + } + + function _validateExtensionDep($dep, $group = false, $installcondition = false) + { + if (isset($dep['conflicts'])) { + $structure = array( + 'name', + '*min', + '*max', + '*exclude', + 'conflicts', + ); + } else { + $structure = array( + 'name', + '*min', + '*max', + '*recommended', + '*exclude', + ); + } + if ($installcondition) { + $type = ''; + } else { + $type = '' . $group . ''; + } + if (isset($dep['name'])) { + $type .= '' . $dep['name'] . ''; + } + $this->_stupidSchemaValidate($structure, $dep, $type); + if (isset($dep['min'])) { + if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', + $dep['min'])) { + $this->_invalidVersion(substr($type, 1) . '_invalidVersion(substr($type, 1) . '_invalidVersion(substr($type, 1) . '_invalidVersion(substr($type, 1) . '' : ''; + if ($this->_stupidSchemaValidate($structure, $dep, $type)) { + if ($dep['name'] == '*') { + if (array_key_exists('conflicts', $dep)) { + $this->_cannotConflictWithAllOs($type); + } + } + } + } + + function _validateArchDep($dep, $installcondition = false) + { + $structure = array( + 'pattern', + '*conflicts', + ); + $type = $installcondition ? '' : ''; + $this->_stupidSchemaValidate($structure, $dep, $type); + } + + function _validateInstallConditions($cond, $release) + { + $structure = array( + '*php', + '*extension', + '*os', + '*arch', + ); + if (!$this->_stupidSchemaValidate($structure, + $cond, $release)) { + return false; + } + foreach (array('php', 'extension', 'os', 'arch') as $type) { + if (isset($cond[$type])) { + $iter = $cond[$type]; + if (!is_array($iter) || !isset($iter[0])) { + $iter = array($iter); + } + foreach ($iter as $package) { + if ($type == 'extension') { + $this->{"_validate{$type}Dep"}($package, false, true); + } else { + $this->{"_validate{$type}Dep"}($package, true); + } + } + } + } + } + + function _validateDependencies() + { + $structure = array( + 'required', + '*optional', + '*group->name->hint' + ); + if (!$this->_stupidSchemaValidate($structure, + $this->_packageInfo['dependencies'], '')) { + return false; + } + foreach (array('required', 'optional') as $simpledep) { + if (isset($this->_packageInfo['dependencies'][$simpledep])) { + if ($simpledep == 'optional') { + $structure = array( + '*package', + '*subpackage', + '*extension', + ); + } else { + $structure = array( + 'php', + 'pearinstaller', + '*package', + '*subpackage', + '*extension', + '*os', + '*arch', + ); + } + if ($this->_stupidSchemaValidate($structure, + $this->_packageInfo['dependencies'][$simpledep], + "<$simpledep>")) { + foreach (array('package', 'subpackage', 'extension') as $type) { + if (isset($this->_packageInfo['dependencies'][$simpledep][$type])) { + $iter = $this->_packageInfo['dependencies'][$simpledep][$type]; + if (!isset($iter[0])) { + $iter = array($iter); + } + foreach ($iter as $package) { + if ($type != 'extension') { + if (isset($package['uri'])) { + if (isset($package['channel'])) { + $this->_UrlOrChannel($type, + $package['name']); + } + } else { + if (!isset($package['channel'])) { + $this->_NoChannel($type, $package['name']); + } + } + } + $this->{"_validate{$type}Dep"}($package, "<$simpledep>"); + } + } + } + if ($simpledep == 'optional') { + continue; + } + foreach (array('php', 'pearinstaller', 'os', 'arch') as $type) { + if (isset($this->_packageInfo['dependencies'][$simpledep][$type])) { + $iter = $this->_packageInfo['dependencies'][$simpledep][$type]; + if (!isset($iter[0])) { + $iter = array($iter); + } + foreach ($iter as $package) { + $this->{"_validate{$type}Dep"}($package); + } + } + } + } + } + } + if (isset($this->_packageInfo['dependencies']['group'])) { + $groups = $this->_packageInfo['dependencies']['group']; + if (!isset($groups[0])) { + $groups = array($groups); + } + $structure = array( + '*package', + '*subpackage', + '*extension', + ); + foreach ($groups as $group) { + if ($this->_stupidSchemaValidate($structure, $group, '')) { + if (!PEAR_Validate::validGroupName($group['attribs']['name'])) { + $this->_invalidDepGroupName($group['attribs']['name']); + } + foreach (array('package', 'subpackage', 'extension') as $type) { + if (isset($group[$type])) { + $iter = $group[$type]; + if (!isset($iter[0])) { + $iter = array($iter); + } + foreach ($iter as $package) { + if ($type != 'extension') { + if (isset($package['uri'])) { + if (isset($package['channel'])) { + $this->_UrlOrChannelGroup($type, + $package['name'], + $group['name']); + } + } else { + if (!isset($package['channel'])) { + $this->_NoChannelGroup($type, + $package['name'], + $group['name']); + } + } + } + $this->{"_validate{$type}Dep"}($package, ''); + } + } + } + } + } + } + } + + function _validateCompatible() + { + $compat = $this->_packageInfo['compatible']; + if (!isset($compat[0])) { + $compat = array($compat); + } + $required = array('name', 'channel', 'min', 'max', '*exclude'); + foreach ($compat as $package) { + $type = ''; + if (is_array($package) && array_key_exists('name', $package)) { + $type .= '' . $package['name'] . ''; + } + $this->_stupidSchemaValidate($required, $package, $type); + if (is_array($package) && array_key_exists('min', $package)) { + if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', + $package['min'])) { + $this->_invalidVersion(substr($type, 1) . '_invalidVersion(substr($type, 1) . '_invalidVersion(substr($type, 1) . '_NoBundledPackages(); + } + if (!is_array($list['bundledpackage']) || !isset($list['bundledpackage'][0])) { + return $this->_AtLeast2BundledPackages(); + } + foreach ($list['bundledpackage'] as $package) { + if (!is_string($package)) { + $this->_bundledPackagesMustBeFilename(); + } + } + } + + function _validateFilelist($list = false, $allowignore = false, $dirs = '') + { + $iscontents = false; + if (!$list) { + $iscontents = true; + $list = $this->_packageInfo['contents']; + if (isset($this->_packageInfo['bundle'])) { + return $this->_validateBundle($list); + } + } + if ($allowignore) { + $struc = array( + '*install->name->as', + '*ignore->name' + ); + } else { + $struc = array( + '*dir->name->?baseinstalldir', + '*file->name->role->?baseinstalldir->?md5sum' + ); + if (isset($list['dir']) && isset($list['file'])) { + // stave off validation errors without requiring a set order. + $_old = $list; + if (isset($list['attribs'])) { + $list = array('attribs' => $_old['attribs']); + } + $list['dir'] = $_old['dir']; + $list['file'] = $_old['file']; + } + } + if (!isset($list['attribs']) || !isset($list['attribs']['name'])) { + $unknown = $allowignore ? '' : ''; + $dirname = $iscontents ? '' : $unknown; + } else { + $dirname = ''; + if (preg_match('~/\.\.?(/|\\z)|^\.\.?/~', + str_replace('\\', '/', $list['attribs']['name']))) { + // file contains .. parent directory or . cur directory + $this->_invalidDirName($list['attribs']['name']); + } + } + $res = $this->_stupidSchemaValidate($struc, $list, $dirname); + if ($allowignore && $res) { + $ignored_or_installed = array(); + $this->_pf->getFilelist(); + $fcontents = $this->_pf->getContents(); + $filelist = array(); + if (!isset($fcontents['dir']['file'][0])) { + $fcontents['dir']['file'] = array($fcontents['dir']['file']); + } + foreach ($fcontents['dir']['file'] as $file) { + $filelist[$file['attribs']['name']] = true; + } + if (isset($list['install'])) { + if (!isset($list['install'][0])) { + $list['install'] = array($list['install']); + } + foreach ($list['install'] as $file) { + if (!isset($filelist[$file['attribs']['name']])) { + $this->_notInContents($file['attribs']['name'], 'install'); + continue; + } + if (array_key_exists($file['attribs']['name'], $ignored_or_installed)) { + $this->_multipleInstallAs($file['attribs']['name']); + } + if (!isset($ignored_or_installed[$file['attribs']['name']])) { + $ignored_or_installed[$file['attribs']['name']] = array(); + } + $ignored_or_installed[$file['attribs']['name']][] = 1; + if (preg_match('~/\.\.?(/|\\z)|^\.\.?/~', + str_replace('\\', '/', $file['attribs']['as']))) { + // file contains .. parent directory or . cur directory references + $this->_invalidFileInstallAs($file['attribs']['name'], + $file['attribs']['as']); + } + } + } + if (isset($list['ignore'])) { + if (!isset($list['ignore'][0])) { + $list['ignore'] = array($list['ignore']); + } + foreach ($list['ignore'] as $file) { + if (!isset($filelist[$file['attribs']['name']])) { + $this->_notInContents($file['attribs']['name'], 'ignore'); + continue; + } + if (array_key_exists($file['attribs']['name'], $ignored_or_installed)) { + $this->_ignoreAndInstallAs($file['attribs']['name']); + } + } + } + } + if (!$allowignore && isset($list['file'])) { + if (is_string($list['file'])) { + $this->_oldStyleFileNotAllowed(); + return false; + } + if (!isset($list['file'][0])) { + // single file + $list['file'] = array($list['file']); + } + foreach ($list['file'] as $i => $file) + { + if (isset($file['attribs']) && isset($file['attribs']['name'])) { + if ($file['attribs']['name']{0} == '.' && + $file['attribs']['name']{1} == '/') { + // name is something like "./doc/whatever.txt" + $this->_invalidFileName($file['attribs']['name'], $dirname); + } + if (preg_match('~/\.\.?(/|\\z)|^\.\.?/~', + str_replace('\\', '/', $file['attribs']['name']))) { + // file contains .. parent directory or . cur directory + $this->_invalidFileName($file['attribs']['name'], $dirname); + } + } + if (isset($file['attribs']) && isset($file['attribs']['role'])) { + if (!$this->_validateRole($file['attribs']['role'])) { + if (isset($this->_packageInfo['usesrole'])) { + $roles = $this->_packageInfo['usesrole']; + if (!isset($roles[0])) { + $roles = array($roles); + } + foreach ($roles as $role) { + if ($role['role'] = $file['attribs']['role']) { + $msg = 'This package contains role "%role%" and requires ' . + 'package "%package%" to be used'; + if (isset($role['uri'])) { + $params = array('role' => $role['role'], + 'package' => $role['uri']); + } else { + $params = array('role' => $role['role'], + 'package' => $this->_pf->_registry-> + parsedPackageNameToString(array('package' => + $role['package'], 'channel' => $role['channel']), + true)); + } + $this->_stack->push('_mustInstallRole', 'error', $params, $msg); + } + } + } + $this->_invalidFileRole($file['attribs']['name'], + $dirname, $file['attribs']['role']); + } + } + if (!isset($file['attribs'])) { + continue; + } + $save = $file['attribs']; + if ($dirs) { + $save['name'] = $dirs . '/' . $save['name']; + } + unset($file['attribs']); + if (count($file) && $this->_curState != PEAR_VALIDATE_DOWNLOADING) { // has tasks + foreach ($file as $task => $value) { + if ($tagClass = $this->_pf->getTask($task)) { + if (!is_array($value) || !isset($value[0])) { + $value = array($value); + } + foreach ($value as $v) { + $ret = call_user_func(array($tagClass, 'validateXml'), + $this->_pf, $v, $this->_pf->_config, $save); + if (is_array($ret)) { + $this->_invalidTask($task, $ret, isset($save['name']) ? + $save['name'] : ''); + } + } + } else { + if (isset($this->_packageInfo['usestask'])) { + $roles = $this->_packageInfo['usestask']; + if (!isset($roles[0])) { + $roles = array($roles); + } + foreach ($roles as $role) { + if ($role['task'] = $task) { + $msg = 'This package contains task "%task%" and requires ' . + 'package "%package%" to be used'; + if (isset($role['uri'])) { + $params = array('task' => $role['task'], + 'package' => $role['uri']); + } else { + $params = array('task' => $role['task'], + 'package' => $this->_pf->_registry-> + parsedPackageNameToString(array('package' => + $role['package'], 'channel' => $role['channel']), + true)); + } + $this->_stack->push('_mustInstallTask', 'error', + $params, $msg); + } + } + } + $this->_unknownTask($task, $save['name']); + } + } + } + } + } + if (isset($list['ignore'])) { + if (!$allowignore) { + $this->_ignoreNotAllowed('ignore'); + } + } + if (isset($list['install'])) { + if (!$allowignore) { + $this->_ignoreNotAllowed('install'); + } + } + if (isset($list['file'])) { + if ($allowignore) { + $this->_fileNotAllowed('file'); + } + } + if (isset($list['dir'])) { + if ($allowignore) { + $this->_fileNotAllowed('dir'); + } else { + if (!isset($list['dir'][0])) { + $list['dir'] = array($list['dir']); + } + foreach ($list['dir'] as $dir) { + if (isset($dir['attribs']) && isset($dir['attribs']['name'])) { + if ($dir['attribs']['name'] == '/' || + !isset($this->_packageInfo['contents']['dir']['dir'])) { + // always use nothing if the filelist has already been flattened + $newdirs = ''; + } elseif ($dirs == '') { + $newdirs = $dir['attribs']['name']; + } else { + $newdirs = $dirs . '/' . $dir['attribs']['name']; + } + } else { + $newdirs = $dirs; + } + $this->_validateFilelist($dir, $allowignore, $newdirs); + } + } + } + } + + function _validateRelease() + { + if (isset($this->_packageInfo['phprelease'])) { + $release = 'phprelease'; + if (isset($this->_packageInfo['providesextension'])) { + $this->_cannotProvideExtension($release); + } + if (isset($this->_packageInfo['srcpackage']) || isset($this->_packageInfo['srcuri'])) { + $this->_cannotHaveSrcpackage($release); + } + $releases = $this->_packageInfo['phprelease']; + if (!is_array($releases)) { + return true; + } + if (!isset($releases[0])) { + $releases = array($releases); + } + foreach ($releases as $rel) { + $this->_stupidSchemaValidate(array( + '*installconditions', + '*filelist', + ), $rel, ''); + } + } + foreach (array('', 'zend') as $prefix) { + $releasetype = $prefix . 'extsrcrelease'; + if (isset($this->_packageInfo[$releasetype])) { + $release = $releasetype; + if (!isset($this->_packageInfo['providesextension'])) { + $this->_mustProvideExtension($release); + } + if (isset($this->_packageInfo['srcpackage']) || isset($this->_packageInfo['srcuri'])) { + $this->_cannotHaveSrcpackage($release); + } + $releases = $this->_packageInfo[$releasetype]; + if (!is_array($releases)) { + return true; + } + if (!isset($releases[0])) { + $releases = array($releases); + } + foreach ($releases as $rel) { + $this->_stupidSchemaValidate(array( + '*installconditions', + '*configureoption->name->prompt->?default', + '*binarypackage', + '*filelist', + ), $rel, '<' . $releasetype . '>'); + if (isset($rel['binarypackage'])) { + if (!is_array($rel['binarypackage']) || !isset($rel['binarypackage'][0])) { + $rel['binarypackage'] = array($rel['binarypackage']); + } + foreach ($rel['binarypackage'] as $bin) { + if (!is_string($bin)) { + $this->_binaryPackageMustBePackagename(); + } + } + } + } + } + $releasetype = 'extbinrelease'; + if (isset($this->_packageInfo[$releasetype])) { + $release = $releasetype; + if (!isset($this->_packageInfo['providesextension'])) { + $this->_mustProvideExtension($release); + } + if (isset($this->_packageInfo['channel']) && + !isset($this->_packageInfo['srcpackage'])) { + $this->_mustSrcPackage($release); + } + if (isset($this->_packageInfo['uri']) && !isset($this->_packageInfo['srcuri'])) { + $this->_mustSrcuri($release); + } + $releases = $this->_packageInfo[$releasetype]; + if (!is_array($releases)) { + return true; + } + if (!isset($releases[0])) { + $releases = array($releases); + } + foreach ($releases as $rel) { + $this->_stupidSchemaValidate(array( + '*installconditions', + '*filelist', + ), $rel, '<' . $releasetype . '>'); + } + } + } + if (isset($this->_packageInfo['bundle'])) { + $release = 'bundle'; + if (isset($this->_packageInfo['providesextension'])) { + $this->_cannotProvideExtension($release); + } + if (isset($this->_packageInfo['srcpackage']) || isset($this->_packageInfo['srcuri'])) { + $this->_cannotHaveSrcpackage($release); + } + $releases = $this->_packageInfo['bundle']; + if (!is_array($releases) || !isset($releases[0])) { + $releases = array($releases); + } + foreach ($releases as $rel) { + $this->_stupidSchemaValidate(array( + '*installconditions', + '*filelist', + ), $rel, ''); + } + } + foreach ($releases as $rel) { + if (is_array($rel) && array_key_exists('installconditions', $rel)) { + $this->_validateInstallConditions($rel['installconditions'], + "<$release>"); + } + if (is_array($rel) && array_key_exists('filelist', $rel)) { + if ($rel['filelist']) { + + $this->_validateFilelist($rel['filelist'], true); + } + } + } + } + + /** + * This is here to allow role extension through plugins + * @param string + */ + function _validateRole($role) + { + return in_array($role, PEAR_Installer_Role::getValidRoles($this->_pf->getPackageType())); + } + + function _pearVersionTooLow($version) + { + $this->_stack->push(__FUNCTION__, 'error', + array('version' => $version), + 'This package.xml requires PEAR version %version% to parse properly, we are ' . + 'version 1.10.1'); + } + + function _invalidTagOrder($oktags, $actual, $root) + { + $this->_stack->push(__FUNCTION__, 'error', + array('oktags' => $oktags, 'actual' => $actual, 'root' => $root), + 'Invalid tag order in %root%, found <%actual%> expected one of "%oktags%"'); + } + + function _ignoreNotAllowed($type) + { + $this->_stack->push(__FUNCTION__, 'error', array('type' => $type), + '<%type%> is not allowed inside global , only inside ' . + '//, use and only'); + } + + function _fileNotAllowed($type) + { + $this->_stack->push(__FUNCTION__, 'error', array('type' => $type), + '<%type%> is not allowed inside release , only inside ' . + ', use and only'); + } + + function _oldStyleFileNotAllowed() + { + $this->_stack->push(__FUNCTION__, 'error', array(), + 'Old-style name is not allowed. Use' . + ''); + } + + function _tagMissingAttribute($tag, $attr, $context) + { + $this->_stack->push(__FUNCTION__, 'error', array('tag' => $tag, + 'attribute' => $attr, 'context' => $context), + 'tag <%tag%> in context "%context%" has no attribute "%attribute%"'); + } + + function _tagHasNoAttribs($tag, $context) + { + $this->_stack->push(__FUNCTION__, 'error', array('tag' => $tag, + 'context' => $context), + 'tag <%tag%> has no attributes in context "%context%"'); + } + + function _invalidInternalStructure() + { + $this->_stack->push(__FUNCTION__, 'exception', array(), + 'internal array was not generated by compatible parser, or extreme parser error, cannot continue'); + } + + function _invalidFileRole($file, $dir, $role) + { + $this->_stack->push(__FUNCTION__, 'error', array( + 'file' => $file, 'dir' => $dir, 'role' => $role, + 'roles' => PEAR_Installer_Role::getValidRoles($this->_pf->getPackageType())), + 'File "%file%" in directory "%dir%" has invalid role "%role%", should be one of %roles%'); + } + + function _invalidFileName($file, $dir) + { + $this->_stack->push(__FUNCTION__, 'error', array( + 'file' => $file), + 'File "%file%" in directory "%dir%" cannot begin with "./" or contain ".."'); + } + + function _invalidFileInstallAs($file, $as) + { + $this->_stack->push(__FUNCTION__, 'error', array( + 'file' => $file, 'as' => $as), + 'File "%file%" cannot contain "./" or contain ".."'); + } + + function _invalidDirName($dir) + { + $this->_stack->push(__FUNCTION__, 'error', array( + 'dir' => $file), + 'Directory "%dir%" cannot begin with "./" or contain ".."'); + } + + function _filelistCannotContainFile($filelist) + { + $this->_stack->push(__FUNCTION__, 'error', array('tag' => $filelist), + '<%tag%> can only contain , contains . Use ' . + ' as the first dir element'); + } + + function _filelistMustContainDir($filelist) + { + $this->_stack->push(__FUNCTION__, 'error', array('tag' => $filelist), + '<%tag%> must contain . Use as the ' . + 'first dir element'); + } + + function _tagCannotBeEmpty($tag) + { + $this->_stack->push(__FUNCTION__, 'error', array('tag' => $tag), + '<%tag%> cannot be empty (<%tag%/>)'); + } + + function _UrlOrChannel($type, $name) + { + $this->_stack->push(__FUNCTION__, 'error', array('type' => $type, + 'name' => $name), + 'Required dependency <%type%> "%name%" can have either url OR ' . + 'channel attributes, and not both'); + } + + function _NoChannel($type, $name) + { + $this->_stack->push(__FUNCTION__, 'error', array('type' => $type, + 'name' => $name), + 'Required dependency <%type%> "%name%" must have either url OR ' . + 'channel attributes'); + } + + function _UrlOrChannelGroup($type, $name, $group) + { + $this->_stack->push(__FUNCTION__, 'error', array('type' => $type, + 'name' => $name, 'group' => $group), + 'Group "%group%" dependency <%type%> "%name%" can have either url OR ' . + 'channel attributes, and not both'); + } + + function _NoChannelGroup($type, $name, $group) + { + $this->_stack->push(__FUNCTION__, 'error', array('type' => $type, + 'name' => $name, 'group' => $group), + 'Group "%group%" dependency <%type%> "%name%" must have either url OR ' . + 'channel attributes'); + } + + function _unknownChannel($channel) + { + $this->_stack->push(__FUNCTION__, 'error', array('channel' => $channel), + 'Unknown channel "%channel%"'); + } + + function _noPackageVersion() + { + $this->_stack->push(__FUNCTION__, 'error', array(), + 'package.xml tag has no version attribute, or version is not 2.0'); + } + + function _NoBundledPackages() + { + $this->_stack->push(__FUNCTION__, 'error', array(), + 'No tag was found in , required for bundle packages'); + } + + function _AtLeast2BundledPackages() + { + $this->_stack->push(__FUNCTION__, 'error', array(), + 'At least 2 packages must be bundled in a bundle package'); + } + + function _ChannelOrUri($name) + { + $this->_stack->push(__FUNCTION__, 'error', array('name' => $name), + 'Bundled package "%name%" can have either a uri or a channel, not both'); + } + + function _noChildTag($child, $tag) + { + $this->_stack->push(__FUNCTION__, 'error', array('child' => $child, 'tag' => $tag), + 'Tag <%tag%> is missing child tag <%child%>'); + } + + function _invalidVersion($type, $value) + { + $this->_stack->push(__FUNCTION__, 'error', array('type' => $type, 'value' => $value), + 'Version type <%type%> is not a valid version (%value%)'); + } + + function _invalidState($type, $value) + { + $states = array('stable', 'beta', 'alpha', 'devel'); + if ($type != 'api') { + $states[] = 'snapshot'; + } + if (strtolower($value) == 'rc') { + $this->_stack->push(__FUNCTION__, 'error', + array('version' => $this->_packageInfo['version']['release']), + 'RC is not a state, it is a version postfix, try %version%RC1, stability beta'); + } + $this->_stack->push(__FUNCTION__, 'error', array('type' => $type, 'value' => $value, + 'types' => $states), + 'Stability type <%type%> is not a valid stability (%value%), must be one of ' . + '%types%'); + } + + function _invalidTask($task, $ret, $file) + { + switch ($ret[0]) { + case PEAR_TASK_ERROR_MISSING_ATTRIB : + $info = array('attrib' => $ret[1], 'task' => $task, 'file' => $file); + $msg = 'task <%task%> is missing attribute "%attrib%" in file %file%'; + break; + case PEAR_TASK_ERROR_NOATTRIBS : + $info = array('task' => $task, 'file' => $file); + $msg = 'task <%task%> has no attributes in file %file%'; + break; + case PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE : + $info = array('attrib' => $ret[1], 'values' => $ret[3], + 'was' => $ret[2], 'task' => $task, 'file' => $file); + $msg = 'task <%task%> attribute "%attrib%" has the wrong value "%was%" '. + 'in file %file%, expecting one of "%values%"'; + break; + case PEAR_TASK_ERROR_INVALID : + $info = array('reason' => $ret[1], 'task' => $task, 'file' => $file); + $msg = 'task <%task%> in file %file% is invalid because of "%reason%"'; + break; + } + $this->_stack->push(__FUNCTION__, 'error', $info, $msg); + } + + function _unknownTask($task, $file) + { + $this->_stack->push(__FUNCTION__, 'error', array('task' => $task, 'file' => $file), + 'Unknown task "%task%" passed in file '); + } + + function _subpackageCannotProvideExtension($name) + { + $this->_stack->push(__FUNCTION__, 'error', array('name' => $name), + 'Subpackage dependency "%name%" cannot use , ' . + 'only package dependencies can use this tag'); + } + + function _subpackagesCannotConflict($name) + { + $this->_stack->push(__FUNCTION__, 'error', array('name' => $name), + 'Subpackage dependency "%name%" cannot use , ' . + 'only package dependencies can use this tag'); + } + + function _cannotProvideExtension($release) + { + $this->_stack->push(__FUNCTION__, 'error', array('release' => $release), + '<%release%> packages cannot use , only extbinrelease, extsrcrelease, zendextsrcrelease, and zendextbinrelease can provide a PHP extension'); + } + + function _mustProvideExtension($release) + { + $this->_stack->push(__FUNCTION__, 'error', array('release' => $release), + '<%release%> packages must use to indicate which PHP extension is provided'); + } + + function _cannotHaveSrcpackage($release) + { + $this->_stack->push(__FUNCTION__, 'error', array('release' => $release), + '<%release%> packages cannot specify a source code package, only extension binaries may use the tag'); + } + + function _mustSrcPackage($release) + { + $this->_stack->push(__FUNCTION__, 'error', array('release' => $release), + '/ packages must specify a source code package with '); + } + + function _mustSrcuri($release) + { + $this->_stack->push(__FUNCTION__, 'error', array('release' => $release), + '/ packages must specify a source code package with '); + } + + function _uriDepsCannotHaveVersioning($type) + { + $this->_stack->push(__FUNCTION__, 'error', array('type' => $type), + '%type%: dependencies with a tag cannot have any versioning information'); + } + + function _conflictingDepsCannotHaveVersioning($type) + { + $this->_stack->push(__FUNCTION__, 'error', array('type' => $type), + '%type%: conflicting dependencies cannot have versioning info, use to ' . + 'exclude specific versions of a dependency'); + } + + function _DepchannelCannotBeUri($type) + { + $this->_stack->push(__FUNCTION__, 'error', array('type' => $type), + '%type%: channel cannot be __uri, this is a pseudo-channel reserved for uri ' . + 'dependencies only'); + } + + function _bundledPackagesMustBeFilename() + { + $this->_stack->push(__FUNCTION__, 'error', array(), + ' tags must contain only the filename of a package release ' . + 'in the bundle'); + } + + function _binaryPackageMustBePackagename() + { + $this->_stack->push(__FUNCTION__, 'error', array(), + ' tags must contain the name of a package that is ' . + 'a compiled version of this extsrc/zendextsrc package'); + } + + function _fileNotFound($file) + { + $this->_stack->push(__FUNCTION__, 'error', array('file' => $file), + 'File "%file%" in package.xml does not exist'); + } + + function _notInContents($file, $tag) + { + $this->_stack->push(__FUNCTION__, 'error', array('file' => $file, 'tag' => $tag), + '<%tag% name="%file%"> is invalid, file is not in '); + } + + function _cannotValidateNoPathSet() + { + $this->_stack->push(__FUNCTION__, 'error', array(), + 'Cannot validate files, no path to package file is set (use setPackageFile())'); + } + + function _usesroletaskMustHaveChannelOrUri($role, $tag) + { + $this->_stack->push(__FUNCTION__, 'error', array('role' => $role, 'tag' => $tag), + '<%tag%> for role "%role%" must contain either , or and '); + } + + function _usesroletaskMustHavePackage($role, $tag) + { + $this->_stack->push(__FUNCTION__, 'error', array('role' => $role, 'tag' => $tag), + '<%tag%> for role "%role%" must contain '); + } + + function _usesroletaskMustHaveRoleTask($tag, $type) + { + $this->_stack->push(__FUNCTION__, 'error', array('tag' => $tag, 'type' => $type), + '<%tag%> must contain <%type%> defining the %type% to be used'); + } + + function _cannotConflictWithAllOs($type) + { + $this->_stack->push(__FUNCTION__, 'error', array('tag' => $tag), + '%tag% cannot conflict with all OSes'); + } + + function _invalidDepGroupName($name) + { + $this->_stack->push(__FUNCTION__, 'error', array('name' => $name), + 'Invalid dependency group name "%name%"'); + } + + function _multipleToplevelDirNotAllowed() + { + $this->_stack->push(__FUNCTION__, 'error', array(), + 'Multiple top-level tags are not allowed. Enclose them ' . + 'in a '); + } + + function _multipleInstallAs($file) + { + $this->_stack->push(__FUNCTION__, 'error', array('file' => $file), + 'Only one tag is allowed for file "%file%"'); + } + + function _ignoreAndInstallAs($file) + { + $this->_stack->push(__FUNCTION__, 'error', array('file' => $file), + 'Cannot have both and tags for file "%file%"'); + } + + function _analyzeBundledPackages() + { + if (!$this->_isValid) { + return false; + } + if (!$this->_pf->getPackageType() == 'bundle') { + return false; + } + if (!isset($this->_pf->_packageFile)) { + return false; + } + $dir_prefix = dirname($this->_pf->_packageFile); + $common = new PEAR_Common; + $log = isset($this->_pf->_logger) ? array(&$this->_pf->_logger, 'log') : + array($common, 'log'); + $info = $this->_pf->getContents(); + $info = $info['bundledpackage']; + if (!is_array($info)) { + $info = array($info); + } + $pkg = new PEAR_PackageFile($this->_pf->_config); + foreach ($info as $package) { + if (!file_exists($dir_prefix . DIRECTORY_SEPARATOR . $package)) { + $this->_fileNotFound($dir_prefix . DIRECTORY_SEPARATOR . $package); + $this->_isValid = 0; + continue; + } + call_user_func_array($log, array(1, "Analyzing bundled package $package")); + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $ret = $pkg->fromAnyFile($dir_prefix . DIRECTORY_SEPARATOR . $package, + PEAR_VALIDATE_NORMAL); + PEAR::popErrorHandling(); + if (PEAR::isError($ret)) { + call_user_func_array($log, array(0, "ERROR: package $package is not a valid " . + 'package')); + $inf = $ret->getUserInfo(); + if (is_array($inf)) { + foreach ($inf as $err) { + call_user_func_array($log, array(1, $err['message'])); + } + } + return false; + } + } + return true; + } + + function _analyzePhpFiles() + { + if (!$this->_isValid) { + return false; + } + if (!isset($this->_pf->_packageFile)) { + $this->_cannotValidateNoPathSet(); + return false; + } + $dir_prefix = dirname($this->_pf->_packageFile); + $common = new PEAR_Common; + $log = isset($this->_pf->_logger) ? array(&$this->_pf->_logger, 'log') : + array(&$common, 'log'); + $info = $this->_pf->getContents(); + if (!$info || !isset($info['dir']['file'])) { + $this->_tagCannotBeEmpty('contents>_fileNotFound($dir_prefix . DIRECTORY_SEPARATOR . $file); + $this->_isValid = 0; + continue; + } + if (in_array($fa['role'], PEAR_Installer_Role::getPhpRoles()) && $dir_prefix) { + call_user_func_array($log, array(1, "Analyzing $file")); + $srcinfo = $this->analyzeSourceCode($dir_prefix . DIRECTORY_SEPARATOR . $file); + if ($srcinfo) { + $provides = array_merge($provides, $this->_buildProvidesArray($srcinfo)); + } + } + } + $this->_packageName = $pn = $this->_pf->getPackage(); + $pnl = strlen($pn); + foreach ($provides as $key => $what) { + if (isset($what['explicit']) || !$what) { + // skip conformance checks if the provides entry is + // specified in the package.xml file + continue; + } + extract($what); + if ($type == 'class') { + if (!strncasecmp($name, $pn, $pnl)) { + continue; + } + $this->_stack->push(__FUNCTION__, 'warning', + array('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn), + 'in %file%: %type% "%name%" not prefixed with package name "%package%"'); + } elseif ($type == 'function') { + if (strstr($name, '::') || !strncasecmp($name, $pn, $pnl)) { + continue; + } + $this->_stack->push(__FUNCTION__, 'warning', + array('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn), + 'in %file%: %type% "%name%" not prefixed with package name "%package%"'); + } + } + return $this->_isValid; + } + + /** + * Analyze the source code of the given PHP file + * + * @param string Filename of the PHP file + * @param boolean whether to analyze $file as the file contents + * @return mixed + */ + function analyzeSourceCode($file, $string = false) + { + if (!function_exists("token_get_all")) { + $this->_stack->push(__FUNCTION__, 'error', array('file' => $file), + 'Parser error: token_get_all() function must exist to analyze source code, PHP may have been compiled with --disable-tokenizer'); + return false; + } + + if (!defined('T_DOC_COMMENT')) { + define('T_DOC_COMMENT', T_COMMENT); + } + + if (!defined('T_INTERFACE')) { + define('T_INTERFACE', -1); + } + + if (!defined('T_IMPLEMENTS')) { + define('T_IMPLEMENTS', -1); + } + + if ($string) { + $contents = $file; + } else { + if (!$fp = @fopen($file, "r")) { + return false; + } + fclose($fp); + $contents = file_get_contents($file); + } + + // Silence this function so we can catch PHP Warnings and show our own custom message + $tokens = @token_get_all($contents); + if (isset($php_errormsg)) { + if (isset($this->_stack)) { + $pn = $this->_pf->getPackage(); + $this->_stack->push(__FUNCTION__, 'warning', + array('file' => $file, 'package' => $pn), + 'in %file%: Could not process file for unknown reasons,' . + ' possibly a PHP parse error in %file% from %package%'); + } + } +/* + for ($i = 0; $i < sizeof($tokens); $i++) { + @list($token, $data) = $tokens[$i]; + if (is_string($token)) { + var_dump($token); + } else { + print token_name($token) . ' '; + var_dump(rtrim($data)); + } + } +*/ + $look_for = 0; + $paren_level = 0; + $bracket_level = 0; + $brace_level = 0; + $lastphpdoc = ''; + $current_class = ''; + $current_interface = ''; + $current_class_level = -1; + $current_function = ''; + $current_function_level = -1; + $declared_classes = array(); + $declared_interfaces = array(); + $declared_functions = array(); + $declared_methods = array(); + $used_classes = array(); + $used_functions = array(); + $extends = array(); + $implements = array(); + $nodeps = array(); + $inquote = false; + $interface = false; + for ($i = 0; $i < sizeof($tokens); $i++) { + if (is_array($tokens[$i])) { + list($token, $data) = $tokens[$i]; + } else { + $token = $tokens[$i]; + $data = ''; + } + + if ($inquote) { + if ($token != '"' && $token != T_END_HEREDOC) { + continue; + } else { + $inquote = false; + continue; + } + } + + switch ($token) { + case T_WHITESPACE : + continue; + case ';': + if ($interface) { + $current_function = ''; + $current_function_level = -1; + } + break; + case '"': + case T_START_HEREDOC: + $inquote = true; + break; + case T_CURLY_OPEN: + case T_DOLLAR_OPEN_CURLY_BRACES: + case '{': $brace_level++; continue 2; + case '}': + $brace_level--; + if ($current_class_level == $brace_level) { + $current_class = ''; + $current_class_level = -1; + } + if ($current_function_level == $brace_level) { + $current_function = ''; + $current_function_level = -1; + } + continue 2; + case '[': $bracket_level++; continue 2; + case ']': $bracket_level--; continue 2; + case '(': $paren_level++; continue 2; + case ')': $paren_level--; continue 2; + case T_INTERFACE: + $interface = true; + case T_CLASS: + if (($current_class_level != -1) || ($current_function_level != -1)) { + if (isset($this->_stack)) { + $this->_stack->push(__FUNCTION__, 'error', array('file' => $file), + 'Parser error: invalid PHP found in file "%file%"'); + } else { + PEAR::raiseError("Parser error: invalid PHP found in file \"$file\"", + PEAR_COMMON_ERROR_INVALIDPHP); + } + + return false; + } + case T_FUNCTION: + case T_NEW: + case T_EXTENDS: + case T_IMPLEMENTS: + $look_for = $token; + continue 2; + case T_STRING: + if ($look_for == T_CLASS) { + $current_class = $data; + $current_class_level = $brace_level; + $declared_classes[] = $current_class; + } elseif ($look_for == T_INTERFACE) { + $current_interface = $data; + $current_class_level = $brace_level; + $declared_interfaces[] = $current_interface; + } elseif ($look_for == T_IMPLEMENTS) { + $implements[$current_class] = $data; + } elseif ($look_for == T_EXTENDS) { + $extends[$current_class] = $data; + } elseif ($look_for == T_FUNCTION) { + if ($current_class) { + $current_function = "$current_class::$data"; + $declared_methods[$current_class][] = $data; + } elseif ($current_interface) { + $current_function = "$current_interface::$data"; + $declared_methods[$current_interface][] = $data; + } else { + $current_function = $data; + $declared_functions[] = $current_function; + } + + $current_function_level = $brace_level; + $m = array(); + } elseif ($look_for == T_NEW) { + $used_classes[$data] = true; + } + + $look_for = 0; + continue 2; + case T_VARIABLE: + $look_for = 0; + continue 2; + case T_DOC_COMMENT: + case T_COMMENT: + if (preg_match('!^/\*\*\s!', $data)) { + $lastphpdoc = $data; + if (preg_match_all('/@nodep\s+(\S+)/', $lastphpdoc, $m)) { + $nodeps = array_merge($nodeps, $m[1]); + } + } + continue 2; + case T_DOUBLE_COLON: + $token = $tokens[$i - 1][0]; + if (!($token == T_WHITESPACE || $token == T_STRING || $token == T_STATIC || $token == T_VARIABLE)) { + if (isset($this->_stack)) { + $this->_stack->push(__FUNCTION__, 'warning', array('file' => $file), + 'Parser error: invalid PHP found in file "%file%"'); + } else { + PEAR::raiseError("Parser error: invalid PHP found in file \"$file\"", + PEAR_COMMON_ERROR_INVALIDPHP); + } + + return false; + } + + $class = $tokens[$i - 1][1]; + if (strtolower($class) != 'parent') { + $used_classes[$class] = true; + } + + continue 2; + } + } + + return array( + "source_file" => $file, + "declared_classes" => $declared_classes, + "declared_interfaces" => $declared_interfaces, + "declared_methods" => $declared_methods, + "declared_functions" => $declared_functions, + "used_classes" => array_diff(array_keys($used_classes), $nodeps), + "inheritance" => $extends, + "implements" => $implements, + ); + } + + /** + * Build a "provides" array from data returned by + * analyzeSourceCode(). The format of the built array is like + * this: + * + * array( + * 'class;MyClass' => 'array('type' => 'class', 'name' => 'MyClass'), + * ... + * ) + * + * + * @param array $srcinfo array with information about a source file + * as returned by the analyzeSourceCode() method. + * + * @return void + * + * @access private + * + */ + function _buildProvidesArray($srcinfo) + { + if (!$this->_isValid) { + return array(); + } + + $providesret = array(); + $file = basename($srcinfo['source_file']); + $pn = isset($this->_pf) ? $this->_pf->getPackage() : ''; + $pnl = strlen($pn); + foreach ($srcinfo['declared_classes'] as $class) { + $key = "class;$class"; + if (isset($providesret[$key])) { + continue; + } + + $providesret[$key] = + array('file'=> $file, 'type' => 'class', 'name' => $class); + if (isset($srcinfo['inheritance'][$class])) { + $providesret[$key]['extends'] = + $srcinfo['inheritance'][$class]; + } + } + + foreach ($srcinfo['declared_methods'] as $class => $methods) { + foreach ($methods as $method) { + $function = "$class::$method"; + $key = "function;$function"; + if ($method{0} == '_' || !strcasecmp($method, $class) || + isset($providesret[$key])) { + continue; + } + + $providesret[$key] = + array('file'=> $file, 'type' => 'function', 'name' => $function); + } + } + + foreach ($srcinfo['declared_functions'] as $function) { + $key = "function;$function"; + if ($function{0} == '_' || isset($providesret[$key])) { + continue; + } + + if (!strstr($function, '::') && strncasecmp($function, $pn, $pnl)) { + $warnings[] = "in1 " . $file . ": function \"$function\" not prefixed with package name \"$pn\""; + } + + $providesret[$key] = + array('file'=> $file, 'type' => 'function', 'name' => $function); + } + + return $providesret; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/PackageFile/v2/rw.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/PackageFile/v2/rw.php new file mode 100644 index 0000000..f2b58e3 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/PackageFile/v2/rw.php @@ -0,0 +1,1603 @@ + + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a8 + */ +/** + * For base class + */ +require_once 'PEAR/PackageFile/v2.php'; +/** + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a8 + */ +class PEAR_PackageFile_v2_rw extends PEAR_PackageFile_v2 +{ + /** + * @param string Extension name + * @return bool success of operation + */ + function setProvidesExtension($extension) + { + if (in_array($this->getPackageType(), + array('extsrc', 'extbin', 'zendextsrc', 'zendextbin'))) { + if (!isset($this->_packageInfo['providesextension'])) { + // ensure that the channel tag is set up in the right location + $this->_packageInfo = $this->_insertBefore($this->_packageInfo, + array('usesrole', 'usestask', 'srcpackage', 'srcuri', 'phprelease', + 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease', + 'bundle', 'changelog'), + $extension, 'providesextension'); + } + $this->_packageInfo['providesextension'] = $extension; + return true; + } + return false; + } + + function setPackage($package) + { + $this->_isValid = 0; + if (!isset($this->_packageInfo['attribs'])) { + $this->_packageInfo = array_merge(array('attribs' => array( + 'version' => '2.0', + 'xmlns' => 'http://pear.php.net/dtd/package-2.0', + 'xmlns:tasks' => 'http://pear.php.net/dtd/tasks-1.0', + 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', + 'xsi:schemaLocation' => 'http://pear.php.net/dtd/tasks-1.0 + http://pear.php.net/dtd/tasks-1.0.xsd + http://pear.php.net/dtd/package-2.0 + http://pear.php.net/dtd/package-2.0.xsd', + )), $this->_packageInfo); + } + if (!isset($this->_packageInfo['name'])) { + return $this->_packageInfo = array_merge(array('name' => $package), + $this->_packageInfo); + } + $this->_packageInfo['name'] = $package; + } + + /** + * set this as a package.xml version 2.1 + * @access private + */ + function _setPackageVersion2_1() + { + $info = array( + 'version' => '2.1', + 'xmlns' => 'http://pear.php.net/dtd/package-2.1', + 'xmlns:tasks' => 'http://pear.php.net/dtd/tasks-1.0', + 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', + 'xsi:schemaLocation' => 'http://pear.php.net/dtd/tasks-1.0 + http://pear.php.net/dtd/tasks-1.0.xsd + http://pear.php.net/dtd/package-2.1 + http://pear.php.net/dtd/package-2.1.xsd', + ); + if (!isset($this->_packageInfo['attribs'])) { + $this->_packageInfo = array_merge(array('attribs' => $info), $this->_packageInfo); + } else { + $this->_packageInfo['attribs'] = $info; + } + } + + function setUri($uri) + { + unset($this->_packageInfo['channel']); + $this->_isValid = 0; + if (!isset($this->_packageInfo['uri'])) { + // ensure that the uri tag is set up in the right location + $this->_packageInfo = $this->_insertBefore($this->_packageInfo, + array('extends', 'summary', 'description', 'lead', + 'developer', 'contributor', 'helper', 'date', 'time', 'version', + 'stability', 'license', 'notes', 'contents', 'compatible', + 'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', + 'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease', + 'extbinrelease', 'bundle', 'changelog'), $uri, 'uri'); + } + $this->_packageInfo['uri'] = $uri; + } + + function setChannel($channel) + { + unset($this->_packageInfo['uri']); + $this->_isValid = 0; + if (!isset($this->_packageInfo['channel'])) { + // ensure that the channel tag is set up in the right location + $this->_packageInfo = $this->_insertBefore($this->_packageInfo, + array('extends', 'summary', 'description', 'lead', + 'developer', 'contributor', 'helper', 'date', 'time', 'version', + 'stability', 'license', 'notes', 'contents', 'compatible', + 'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', + 'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease', + 'extbinrelease', 'bundle', 'changelog'), $channel, 'channel'); + } + $this->_packageInfo['channel'] = $channel; + } + + function setExtends($extends) + { + $this->_isValid = 0; + if (!isset($this->_packageInfo['extends'])) { + // ensure that the extends tag is set up in the right location + $this->_packageInfo = $this->_insertBefore($this->_packageInfo, + array('summary', 'description', 'lead', + 'developer', 'contributor', 'helper', 'date', 'time', 'version', + 'stability', 'license', 'notes', 'contents', 'compatible', + 'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', + 'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease', + 'extbinrelease', 'bundle', 'changelog'), $extends, 'extends'); + } + $this->_packageInfo['extends'] = $extends; + } + + function setSummary($summary) + { + $this->_isValid = 0; + if (!isset($this->_packageInfo['summary'])) { + // ensure that the summary tag is set up in the right location + $this->_packageInfo = $this->_insertBefore($this->_packageInfo, + array('description', 'lead', + 'developer', 'contributor', 'helper', 'date', 'time', 'version', + 'stability', 'license', 'notes', 'contents', 'compatible', + 'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', + 'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease', + 'extbinrelease', 'bundle', 'changelog'), $summary, 'summary'); + } + $this->_packageInfo['summary'] = $summary; + } + + function setDescription($desc) + { + $this->_isValid = 0; + if (!isset($this->_packageInfo['description'])) { + // ensure that the description tag is set up in the right location + $this->_packageInfo = $this->_insertBefore($this->_packageInfo, + array('lead', + 'developer', 'contributor', 'helper', 'date', 'time', 'version', + 'stability', 'license', 'notes', 'contents', 'compatible', + 'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', + 'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease', + 'extbinrelease', 'bundle', 'changelog'), $desc, 'description'); + } + $this->_packageInfo['description'] = $desc; + } + + /** + * Adds a new maintainer - no checking of duplicates is performed, use + * updatemaintainer for that purpose. + */ + function addMaintainer($role, $handle, $name, $email, $active = 'yes') + { + if (!in_array($role, array('lead', 'developer', 'contributor', 'helper'))) { + return false; + } + if (isset($this->_packageInfo[$role])) { + if (!isset($this->_packageInfo[$role][0])) { + $this->_packageInfo[$role] = array($this->_packageInfo[$role]); + } + $this->_packageInfo[$role][] = + array( + 'name' => $name, + 'user' => $handle, + 'email' => $email, + 'active' => $active, + ); + } else { + $testarr = array('lead', + 'developer', 'contributor', 'helper', 'date', 'time', 'version', + 'stability', 'license', 'notes', 'contents', 'compatible', + 'dependencies', 'providesextension', 'usesrole', 'usestask', + 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', + 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'); + foreach (array('lead', 'developer', 'contributor', 'helper') as $testrole) { + array_shift($testarr); + if ($role == $testrole) { + break; + } + } + if (!isset($this->_packageInfo[$role])) { + // ensure that the extends tag is set up in the right location + $this->_packageInfo = $this->_insertBefore($this->_packageInfo, $testarr, + array(), $role); + } + $this->_packageInfo[$role] = + array( + 'name' => $name, + 'user' => $handle, + 'email' => $email, + 'active' => $active, + ); + } + $this->_isValid = 0; + } + + function updateMaintainer($newrole, $handle, $name, $email, $active = 'yes') + { + $found = false; + foreach (array('lead', 'developer', 'contributor', 'helper') as $role) { + if (!isset($this->_packageInfo[$role])) { + continue; + } + $info = $this->_packageInfo[$role]; + if (!isset($info[0])) { + if ($info['user'] == $handle) { + $found = true; + break; + } + } + foreach ($info as $i => $maintainer) { + if (is_array($maintainer) && $maintainer['user'] == $handle) { + $found = $i; + break 2; + } + } + } + if ($found === false) { + return $this->addMaintainer($newrole, $handle, $name, $email, $active); + } + if ($found !== false) { + if ($found === true) { + unset($this->_packageInfo[$role]); + } else { + unset($this->_packageInfo[$role][$found]); + $this->_packageInfo[$role] = array_values($this->_packageInfo[$role]); + } + } + $this->addMaintainer($newrole, $handle, $name, $email, $active); + $this->_isValid = 0; + } + + function deleteMaintainer($handle) + { + $found = false; + foreach (array('lead', 'developer', 'contributor', 'helper') as $role) { + if (!isset($this->_packageInfo[$role])) { + continue; + } + if (!isset($this->_packageInfo[$role][0])) { + $this->_packageInfo[$role] = array($this->_packageInfo[$role]); + } + foreach ($this->_packageInfo[$role] as $i => $maintainer) { + if ($maintainer['user'] == $handle) { + $found = $i; + break; + } + } + if ($found !== false) { + unset($this->_packageInfo[$role][$found]); + if (!count($this->_packageInfo[$role]) && $role == 'lead') { + $this->_isValid = 0; + } + if (!count($this->_packageInfo[$role])) { + unset($this->_packageInfo[$role]); + return true; + } + $this->_packageInfo[$role] = + array_values($this->_packageInfo[$role]); + if (count($this->_packageInfo[$role]) == 1) { + $this->_packageInfo[$role] = $this->_packageInfo[$role][0]; + } + return true; + } + if (count($this->_packageInfo[$role]) == 1) { + $this->_packageInfo[$role] = $this->_packageInfo[$role][0]; + } + } + return false; + } + + function setReleaseVersion($version) + { + if (isset($this->_packageInfo['version']) && + isset($this->_packageInfo['version']['release'])) { + unset($this->_packageInfo['version']['release']); + } + $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $version, array( + 'version' => array('stability', 'license', 'notes', 'contents', 'compatible', + 'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', + 'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease', + 'extbinrelease', 'bundle', 'changelog'), + 'release' => array('api'))); + $this->_isValid = 0; + } + + function setAPIVersion($version) + { + if (isset($this->_packageInfo['version']) && + isset($this->_packageInfo['version']['api'])) { + unset($this->_packageInfo['version']['api']); + } + $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $version, array( + 'version' => array('stability', 'license', 'notes', 'contents', 'compatible', + 'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', + 'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease', + 'extbinrelease', 'bundle', 'changelog'), + 'api' => array())); + $this->_isValid = 0; + } + + /** + * snapshot|devel|alpha|beta|stable + */ + function setReleaseStability($state) + { + if (isset($this->_packageInfo['stability']) && + isset($this->_packageInfo['stability']['release'])) { + unset($this->_packageInfo['stability']['release']); + } + $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $state, array( + 'stability' => array('license', 'notes', 'contents', 'compatible', + 'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', + 'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease', + 'extbinrelease', 'bundle', 'changelog'), + 'release' => array('api'))); + $this->_isValid = 0; + } + + /** + * @param devel|alpha|beta|stable + */ + function setAPIStability($state) + { + if (isset($this->_packageInfo['stability']) && + isset($this->_packageInfo['stability']['api'])) { + unset($this->_packageInfo['stability']['api']); + } + $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $state, array( + 'stability' => array('license', 'notes', 'contents', 'compatible', + 'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', + 'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease', + 'extbinrelease', 'bundle', 'changelog'), + 'api' => array())); + $this->_isValid = 0; + } + + function setLicense($license, $uri = false, $filesource = false) + { + if (!isset($this->_packageInfo['license'])) { + // ensure that the license tag is set up in the right location + $this->_packageInfo = $this->_insertBefore($this->_packageInfo, + array('notes', 'contents', 'compatible', + 'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', + 'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease', + 'extbinrelease', 'bundle', 'changelog'), 0, 'license'); + } + if ($uri || $filesource) { + $attribs = array(); + if ($uri) { + $attribs['uri'] = $uri; + } + $uri = true; // for test below + if ($filesource) { + $attribs['filesource'] = $filesource; + } + } + $license = $uri ? array('attribs' => $attribs, '_content' => $license) : $license; + $this->_packageInfo['license'] = $license; + $this->_isValid = 0; + } + + function setNotes($notes) + { + $this->_isValid = 0; + if (!isset($this->_packageInfo['notes'])) { + // ensure that the notes tag is set up in the right location + $this->_packageInfo = $this->_insertBefore($this->_packageInfo, + array('contents', 'compatible', + 'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', + 'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease', + 'extbinrelease', 'bundle', 'changelog'), $notes, 'notes'); + } + $this->_packageInfo['notes'] = $notes; + } + + /** + * This is only used at install-time, after all serialization + * is over. + * @param string file name + * @param string installed path + */ + function setInstalledAs($file, $path) + { + if ($path) { + return $this->_packageInfo['filelist'][$file]['installed_as'] = $path; + } + unset($this->_packageInfo['filelist'][$file]['installed_as']); + } + + /** + * This is only used at install-time, after all serialization + * is over. + */ + function installedFile($file, $atts) + { + if (isset($this->_packageInfo['filelist'][$file])) { + $this->_packageInfo['filelist'][$file] = + array_merge($this->_packageInfo['filelist'][$file], $atts['attribs']); + } else { + $this->_packageInfo['filelist'][$file] = $atts['attribs']; + } + } + + /** + * Reset the listing of package contents + * @param string base installation dir for the whole package, if any + */ + function clearContents($baseinstall = false) + { + $this->_filesValid = false; + $this->_isValid = 0; + if (!isset($this->_packageInfo['contents'])) { + $this->_packageInfo = $this->_insertBefore($this->_packageInfo, + array('compatible', + 'dependencies', 'providesextension', 'usesrole', 'usestask', + 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', + 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease', + 'bundle', 'changelog'), array(), 'contents'); + } + if ($this->getPackageType() != 'bundle') { + $this->_packageInfo['contents'] = + array('dir' => array('attribs' => array('name' => '/'))); + if ($baseinstall) { + $this->_packageInfo['contents']['dir']['attribs']['baseinstalldir'] = $baseinstall; + } + } else { + $this->_packageInfo['contents'] = array('bundledpackage' => array()); + } + } + + /** + * @param string relative path of the bundled package. + */ + function addBundledPackage($path) + { + if ($this->getPackageType() != 'bundle') { + return false; + } + $this->_filesValid = false; + $this->_isValid = 0; + $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $path, array( + 'contents' => array('compatible', 'dependencies', 'providesextension', + 'usesrole', 'usestask', 'srcpackage', 'srcuri', 'phprelease', + 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease', + 'bundle', 'changelog'), + 'bundledpackage' => array())); + } + + /** + * @param string file name + * @param PEAR_Task_Common a read/write task + */ + function addTaskToFile($filename, $task) + { + if (!method_exists($task, 'getXml')) { + return false; + } + if (!method_exists($task, 'getName')) { + return false; + } + if (!method_exists($task, 'validate')) { + return false; + } + if (!$task->validate()) { + return false; + } + if (!isset($this->_packageInfo['contents']['dir']['file'])) { + return false; + } + $this->getTasksNs(); // discover the tasks namespace if not done already + $files = $this->_packageInfo['contents']['dir']['file']; + if (!isset($files[0])) { + $files = array($files); + $ind = false; + } else { + $ind = true; + } + foreach ($files as $i => $file) { + if (isset($file['attribs'])) { + if ($file['attribs']['name'] == $filename) { + if ($ind) { + $t = isset($this->_packageInfo['contents']['dir']['file'][$i] + ['attribs'][$this->_tasksNs . + ':' . $task->getName()]) ? + $this->_packageInfo['contents']['dir']['file'][$i] + ['attribs'][$this->_tasksNs . + ':' . $task->getName()] : false; + if ($t && !isset($t[0])) { + $this->_packageInfo['contents']['dir']['file'][$i] + [$this->_tasksNs . ':' . $task->getName()] = array($t); + } + $this->_packageInfo['contents']['dir']['file'][$i][$this->_tasksNs . + ':' . $task->getName()][] = $task->getXml(); + } else { + $t = isset($this->_packageInfo['contents']['dir']['file'] + ['attribs'][$this->_tasksNs . + ':' . $task->getName()]) ? $this->_packageInfo['contents']['dir']['file'] + ['attribs'][$this->_tasksNs . + ':' . $task->getName()] : false; + if ($t && !isset($t[0])) { + $this->_packageInfo['contents']['dir']['file'] + [$this->_tasksNs . ':' . $task->getName()] = array($t); + } + $this->_packageInfo['contents']['dir']['file'][$this->_tasksNs . + ':' . $task->getName()][] = $task->getXml(); + } + return true; + } + } + } + return false; + } + + /** + * @param string path to the file + * @param string filename + * @param array extra attributes + */ + function addFile($dir, $file, $attrs) + { + if ($this->getPackageType() == 'bundle') { + return false; + } + $this->_filesValid = false; + $this->_isValid = 0; + $dir = preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'), $dir); + if ($dir == '/' || $dir == '') { + $dir = ''; + } else { + $dir .= '/'; + } + $attrs['name'] = $dir . $file; + if (!isset($this->_packageInfo['contents'])) { + // ensure that the contents tag is set up + $this->_packageInfo = $this->_insertBefore($this->_packageInfo, + array('compatible', 'dependencies', 'providesextension', 'usesrole', 'usestask', + 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', + 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease', + 'bundle', 'changelog'), array(), 'contents'); + } + if (isset($this->_packageInfo['contents']['dir']['file'])) { + if (!isset($this->_packageInfo['contents']['dir']['file'][0])) { + $this->_packageInfo['contents']['dir']['file'] = + array($this->_packageInfo['contents']['dir']['file']); + } + $this->_packageInfo['contents']['dir']['file'][]['attribs'] = $attrs; + } else { + $this->_packageInfo['contents']['dir']['file']['attribs'] = $attrs; + } + } + + /** + * @param string Dependent package name + * @param string Dependent package's channel name + * @param string minimum version of specified package that this release is guaranteed to be + * compatible with + * @param string maximum version of specified package that this release is guaranteed to be + * compatible with + * @param string versions of specified package that this release is not compatible with + */ + function addCompatiblePackage($name, $channel, $min, $max, $exclude = false) + { + $this->_isValid = 0; + $set = array( + 'name' => $name, + 'channel' => $channel, + 'min' => $min, + 'max' => $max, + ); + if ($exclude) { + $set['exclude'] = $exclude; + } + $this->_isValid = 0; + $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $set, array( + 'compatible' => array('dependencies', 'providesextension', 'usesrole', 'usestask', + 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', + 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog') + )); + } + + /** + * Removes the tag entirely + */ + function resetUsesrole() + { + if (isset($this->_packageInfo['usesrole'])) { + unset($this->_packageInfo['usesrole']); + } + } + + /** + * @param string + * @param string package name or uri + * @param string channel name if non-uri + */ + function addUsesrole($role, $packageOrUri, $channel = false) { + $set = array('role' => $role); + if ($channel) { + $set['package'] = $packageOrUri; + $set['channel'] = $channel; + } else { + $set['uri'] = $packageOrUri; + } + $this->_isValid = 0; + $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $set, array( + 'usesrole' => array('usestask', 'srcpackage', 'srcuri', + 'phprelease', 'extsrcrelease', 'extbinrelease', + 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog') + )); + } + + /** + * Removes the tag entirely + */ + function resetUsestask() + { + if (isset($this->_packageInfo['usestask'])) { + unset($this->_packageInfo['usestask']); + } + } + + + /** + * @param string + * @param string package name or uri + * @param string channel name if non-uri + */ + function addUsestask($task, $packageOrUri, $channel = false) { + $set = array('task' => $task); + if ($channel) { + $set['package'] = $packageOrUri; + $set['channel'] = $channel; + } else { + $set['uri'] = $packageOrUri; + } + $this->_isValid = 0; + $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $set, array( + 'usestask' => array('srcpackage', 'srcuri', + 'phprelease', 'extsrcrelease', 'extbinrelease', + 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog') + )); + } + + /** + * Remove all compatible tags + */ + function clearCompatible() + { + unset($this->_packageInfo['compatible']); + } + + /** + * Reset dependencies prior to adding new ones + */ + function clearDeps() + { + if (!isset($this->_packageInfo['dependencies'])) { + $this->_packageInfo = $this->_mergeTag($this->_packageInfo, array(), + array( + 'dependencies' => array('providesextension', 'usesrole', 'usestask', + 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', + 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'))); + } + $this->_packageInfo['dependencies'] = array(); + } + + /** + * @param string minimum PHP version allowed + * @param string maximum PHP version allowed + * @param array $exclude incompatible PHP versions + */ + function setPhpDep($min, $max = false, $exclude = false) + { + $this->_isValid = 0; + $dep = + array( + 'min' => $min, + ); + if ($max) { + $dep['max'] = $max; + } + if ($exclude) { + if (count($exclude) == 1) { + $exclude = $exclude[0]; + } + $dep['exclude'] = $exclude; + } + if (isset($this->_packageInfo['dependencies']['required']['php'])) { + $this->_stack->push(__FUNCTION__, 'warning', array('dep' => + $this->_packageInfo['dependencies']['required']['php']), + 'warning: PHP dependency already exists, overwriting'); + unset($this->_packageInfo['dependencies']['required']['php']); + } + $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep, + array( + 'dependencies' => array('providesextension', 'usesrole', 'usestask', + 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', + 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'), + 'required' => array('optional', 'group'), + 'php' => array('pearinstaller', 'package', 'subpackage', 'extension', 'os', 'arch') + )); + return true; + } + + /** + * @param string minimum allowed PEAR installer version + * @param string maximum allowed PEAR installer version + * @param string recommended PEAR installer version + * @param array incompatible version of the PEAR installer + */ + function setPearinstallerDep($min, $max = false, $recommended = false, $exclude = false) + { + $this->_isValid = 0; + $dep = + array( + 'min' => $min, + ); + if ($max) { + $dep['max'] = $max; + } + if ($recommended) { + $dep['recommended'] = $recommended; + } + if ($exclude) { + if (count($exclude) == 1) { + $exclude = $exclude[0]; + } + $dep['exclude'] = $exclude; + } + if (isset($this->_packageInfo['dependencies']['required']['pearinstaller'])) { + $this->_stack->push(__FUNCTION__, 'warning', array('dep' => + $this->_packageInfo['dependencies']['required']['pearinstaller']), + 'warning: PEAR Installer dependency already exists, overwriting'); + unset($this->_packageInfo['dependencies']['required']['pearinstaller']); + } + $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep, + array( + 'dependencies' => array('providesextension', 'usesrole', 'usestask', + 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', + 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'), + 'required' => array('optional', 'group'), + 'pearinstaller' => array('package', 'subpackage', 'extension', 'os', 'arch') + )); + } + + /** + * Mark a package as conflicting with this package + * @param string package name + * @param string package channel + * @param string extension this package provides, if any + * @param string|false minimum version required + * @param string|false maximum version allowed + * @param array|false versions to exclude from installation + */ + function addConflictingPackageDepWithChannel($name, $channel, + $providesextension = false, $min = false, $max = false, $exclude = false) + { + $this->_isValid = 0; + $dep = $this->_constructDep($name, $channel, false, $min, $max, false, + $exclude, $providesextension, false, true); + $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep, + array( + 'dependencies' => array('providesextension', 'usesrole', 'usestask', + 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', + 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'), + 'required' => array('optional', 'group'), + 'package' => array('subpackage', 'extension', 'os', 'arch') + )); + } + + /** + * Mark a package as conflicting with this package + * @param string package name + * @param string package channel + * @param string extension this package provides, if any + */ + function addConflictingPackageDepWithUri($name, $uri, $providesextension = false) + { + $this->_isValid = 0; + $dep = + array( + 'name' => $name, + 'uri' => $uri, + 'conflicts' => '', + ); + if ($providesextension) { + $dep['providesextension'] = $providesextension; + } + $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep, + array( + 'dependencies' => array('providesextension', 'usesrole', 'usestask', + 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', + 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'), + 'required' => array('optional', 'group'), + 'package' => array('subpackage', 'extension', 'os', 'arch') + )); + } + + function addDependencyGroup($name, $hint) + { + $this->_isValid = 0; + $this->_packageInfo = $this->_mergeTag($this->_packageInfo, + array('attribs' => array('name' => $name, 'hint' => $hint)), + array( + 'dependencies' => array('providesextension', 'usesrole', 'usestask', + 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', + 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'), + 'group' => array(), + )); + } + + /** + * @param string package name + * @param string|false channel name, false if this is a uri + * @param string|false uri name, false if this is a channel + * @param string|false minimum version required + * @param string|false maximum version allowed + * @param string|false recommended installation version + * @param array|false versions to exclude from installation + * @param string extension this package provides, if any + * @param bool if true, tells the installer to ignore the default optional dependency group + * when installing this package + * @param bool if true, tells the installer to negate this dependency (conflicts) + * @return array + * @access private + */ + function _constructDep($name, $channel, $uri, $min, $max, $recommended, $exclude, + $providesextension = false, $nodefault = false, + $conflicts = false) + { + $dep = + array( + 'name' => $name, + ); + if ($channel) { + $dep['channel'] = $channel; + } elseif ($uri) { + $dep['uri'] = $uri; + } + if ($min) { + $dep['min'] = $min; + } + if ($max) { + $dep['max'] = $max; + } + if ($recommended) { + $dep['recommended'] = $recommended; + } + if ($exclude) { + if (is_array($exclude) && count($exclude) == 1) { + $exclude = $exclude[0]; + } + $dep['exclude'] = $exclude; + } + if ($conflicts) { + $dep['conflicts'] = ''; + } + if ($nodefault) { + $dep['nodefault'] = ''; + } + if ($providesextension) { + $dep['providesextension'] = $providesextension; + } + return $dep; + } + + /** + * @param package|subpackage + * @param string group name + * @param string package name + * @param string package channel + * @param string minimum version + * @param string maximum version + * @param string recommended version + * @param array|false optional excluded versions + * @param string extension this package provides, if any + * @param bool if true, tells the installer to ignore the default optional dependency group + * when installing this package + * @return bool false if the dependency group has not been initialized with + * {@link addDependencyGroup()}, or a subpackage is added with + * a providesextension + */ + function addGroupPackageDepWithChannel($type, $groupname, $name, $channel, $min = false, + $max = false, $recommended = false, $exclude = false, + $providesextension = false, $nodefault = false) + { + if ($type == 'subpackage' && $providesextension) { + return false; // subpackages must be php packages + } + $dep = $this->_constructDep($name, $channel, false, $min, $max, $recommended, $exclude, + $providesextension, $nodefault); + return $this->_addGroupDependency($type, $dep, $groupname); + } + + /** + * @param package|subpackage + * @param string group name + * @param string package name + * @param string package uri + * @param string extension this package provides, if any + * @param bool if true, tells the installer to ignore the default optional dependency group + * when installing this package + * @return bool false if the dependency group has not been initialized with + * {@link addDependencyGroup()} + */ + function addGroupPackageDepWithURI($type, $groupname, $name, $uri, $providesextension = false, + $nodefault = false) + { + if ($type == 'subpackage' && $providesextension) { + return false; // subpackages must be php packages + } + $dep = $this->_constructDep($name, false, $uri, false, false, false, false, + $providesextension, $nodefault); + return $this->_addGroupDependency($type, $dep, $groupname); + } + + /** + * @param string group name (must be pre-existing) + * @param string extension name + * @param string minimum version allowed + * @param string maximum version allowed + * @param string recommended version + * @param array incompatible versions + */ + function addGroupExtensionDep($groupname, $name, $min = false, $max = false, + $recommended = false, $exclude = false) + { + $this->_isValid = 0; + $dep = $this->_constructDep($name, false, false, $min, $max, $recommended, $exclude); + return $this->_addGroupDependency('extension', $dep, $groupname); + } + + /** + * @param package|subpackage|extension + * @param array dependency contents + * @param string name of the dependency group to add this to + * @return boolean + * @access private + */ + function _addGroupDependency($type, $dep, $groupname) + { + $arr = array('subpackage', 'extension'); + if ($type != 'package') { + array_shift($arr); + } + if ($type == 'extension') { + array_shift($arr); + } + if (!isset($this->_packageInfo['dependencies']['group'])) { + return false; + } else { + if (!isset($this->_packageInfo['dependencies']['group'][0])) { + if ($this->_packageInfo['dependencies']['group']['attribs']['name'] == $groupname) { + $this->_packageInfo['dependencies']['group'] = $this->_mergeTag( + $this->_packageInfo['dependencies']['group'], $dep, + array( + $type => $arr + )); + $this->_isValid = 0; + return true; + } else { + return false; + } + } else { + foreach ($this->_packageInfo['dependencies']['group'] as $i => $group) { + if ($group['attribs']['name'] == $groupname) { + $this->_packageInfo['dependencies']['group'][$i] = $this->_mergeTag( + $this->_packageInfo['dependencies']['group'][$i], $dep, + array( + $type => $arr + )); + $this->_isValid = 0; + return true; + } + } + return false; + } + } + } + + /** + * @param optional|required + * @param string package name + * @param string package channel + * @param string minimum version + * @param string maximum version + * @param string recommended version + * @param string extension this package provides, if any + * @param bool if true, tells the installer to ignore the default optional dependency group + * when installing this package + * @param array|false optional excluded versions + */ + function addPackageDepWithChannel($type, $name, $channel, $min = false, $max = false, + $recommended = false, $exclude = false, + $providesextension = false, $nodefault = false) + { + if (!in_array($type, array('optional', 'required'), true)) { + $type = 'required'; + } + $this->_isValid = 0; + $arr = array('optional', 'group'); + if ($type != 'required') { + array_shift($arr); + } + $dep = $this->_constructDep($name, $channel, false, $min, $max, $recommended, $exclude, + $providesextension, $nodefault); + $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep, + array( + 'dependencies' => array('providesextension', 'usesrole', 'usestask', + 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', + 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'), + $type => $arr, + 'package' => array('subpackage', 'extension', 'os', 'arch') + )); + } + + /** + * @param optional|required + * @param string name of the package + * @param string uri of the package + * @param string extension this package provides, if any + * @param bool if true, tells the installer to ignore the default optional dependency group + * when installing this package + */ + function addPackageDepWithUri($type, $name, $uri, $providesextension = false, + $nodefault = false) + { + $this->_isValid = 0; + $arr = array('optional', 'group'); + if ($type != 'required') { + array_shift($arr); + } + $dep = $this->_constructDep($name, false, $uri, false, false, false, false, + $providesextension, $nodefault); + $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep, + array( + 'dependencies' => array('providesextension', 'usesrole', 'usestask', + 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', + 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'), + $type => $arr, + 'package' => array('subpackage', 'extension', 'os', 'arch') + )); + } + + /** + * @param optional|required optional, required + * @param string package name + * @param string package channel + * @param string minimum version + * @param string maximum version + * @param string recommended version + * @param array incompatible versions + * @param bool if true, tells the installer to ignore the default optional dependency group + * when installing this package + */ + function addSubpackageDepWithChannel($type, $name, $channel, $min = false, $max = false, + $recommended = false, $exclude = false, + $nodefault = false) + { + $this->_isValid = 0; + $arr = array('optional', 'group'); + if ($type != 'required') { + array_shift($arr); + } + $dep = $this->_constructDep($name, $channel, false, $min, $max, $recommended, $exclude, + $nodefault); + $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep, + array( + 'dependencies' => array('providesextension', 'usesrole', 'usestask', + 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', + 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'), + $type => $arr, + 'subpackage' => array('extension', 'os', 'arch') + )); + } + + /** + * @param optional|required optional, required + * @param string package name + * @param string package uri for download + * @param bool if true, tells the installer to ignore the default optional dependency group + * when installing this package + */ + function addSubpackageDepWithUri($type, $name, $uri, $nodefault = false) + { + $this->_isValid = 0; + $arr = array('optional', 'group'); + if ($type != 'required') { + array_shift($arr); + } + $dep = $this->_constructDep($name, false, $uri, false, false, false, false, $nodefault); + $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep, + array( + 'dependencies' => array('providesextension', 'usesrole', 'usestask', + 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', + 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'), + $type => $arr, + 'subpackage' => array('extension', 'os', 'arch') + )); + } + + /** + * @param optional|required optional, required + * @param string extension name + * @param string minimum version + * @param string maximum version + * @param string recommended version + * @param array incompatible versions + */ + function addExtensionDep($type, $name, $min = false, $max = false, $recommended = false, + $exclude = false) + { + $this->_isValid = 0; + $arr = array('optional', 'group'); + if ($type != 'required') { + array_shift($arr); + } + $dep = $this->_constructDep($name, false, false, $min, $max, $recommended, $exclude); + $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep, + array( + 'dependencies' => array('providesextension', 'usesrole', 'usestask', + 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', + 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'), + $type => $arr, + 'extension' => array('os', 'arch') + )); + } + + /** + * @param string Operating system name + * @param boolean true if this package cannot be installed on this OS + */ + function addOsDep($name, $conflicts = false) + { + $this->_isValid = 0; + $dep = array('name' => $name); + if ($conflicts) { + $dep['conflicts'] = ''; + } + $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep, + array( + 'dependencies' => array('providesextension', 'usesrole', 'usestask', + 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', + 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'), + 'required' => array('optional', 'group'), + 'os' => array('arch') + )); + } + + /** + * @param string Architecture matching pattern + * @param boolean true if this package cannot be installed on this architecture + */ + function addArchDep($pattern, $conflicts = false) + { + $this->_isValid = 0; + $dep = array('pattern' => $pattern); + if ($conflicts) { + $dep['conflicts'] = ''; + } + $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep, + array( + 'dependencies' => array('providesextension', 'usesrole', 'usestask', + 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', + 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'), + 'required' => array('optional', 'group'), + 'arch' => array() + )); + } + + /** + * Set the kind of package, and erase all release tags + * + * - a php package is a PEAR-style package + * - an extbin package is a PECL-style extension binary + * - an extsrc package is a PECL-style source for a binary + * - an zendextbin package is a PECL-style zend extension binary + * - an zendextsrc package is a PECL-style source for a zend extension binary + * - a bundle package is a collection of other pre-packaged packages + * @param php|extbin|extsrc|zendextsrc|zendextbin|bundle + * @return bool success + */ + function setPackageType($type) + { + $this->_isValid = 0; + if (!in_array($type, array('php', 'extbin', 'extsrc', 'zendextsrc', + 'zendextbin', 'bundle'))) { + return false; + } + + if (in_array($type, array('zendextsrc', 'zendextbin'))) { + $this->_setPackageVersion2_1(); + } + + if ($type != 'bundle') { + $type .= 'release'; + } + + foreach (array('phprelease', 'extbinrelease', 'extsrcrelease', + 'zendextsrcrelease', 'zendextbinrelease', 'bundle') as $test) { + unset($this->_packageInfo[$test]); + } + + if (!isset($this->_packageInfo[$type])) { + // ensure that the release tag is set up + $this->_packageInfo = $this->_insertBefore($this->_packageInfo, array('changelog'), + array(), $type); + } + + $this->_packageInfo[$type] = array(); + return true; + } + + /** + * @return bool true if package type is set up + */ + function addRelease() + { + if ($type = $this->getPackageType()) { + if ($type != 'bundle') { + $type .= 'release'; + } + $this->_packageInfo = $this->_mergeTag($this->_packageInfo, array(), + array($type => array('changelog'))); + return true; + } + return false; + } + + /** + * Get the current release tag in order to add to it + * @param bool returns only releases that have installcondition if true + * @return array|null + */ + function &_getCurrentRelease($strict = true) + { + if ($p = $this->getPackageType()) { + if ($strict) { + if ($p == 'extsrc' || $p == 'zendextsrc') { + $a = null; + return $a; + } + } + if ($p != 'bundle') { + $p .= 'release'; + } + if (isset($this->_packageInfo[$p][0])) { + return $this->_packageInfo[$p][count($this->_packageInfo[$p]) - 1]; + } else { + return $this->_packageInfo[$p]; + } + } else { + $a = null; + return $a; + } + } + + /** + * Add a file to the current release that should be installed under a different name + * @param string path to file + * @param string name the file should be installed as + */ + function addInstallAs($path, $as) + { + $r = &$this->_getCurrentRelease(); + if ($r === null) { + return false; + } + $this->_isValid = 0; + $r = $this->_mergeTag($r, array('attribs' => array('name' => $path, 'as' => $as)), + array( + 'filelist' => array(), + 'install' => array('ignore') + )); + } + + /** + * Add a file to the current release that should be ignored + * @param string path to file + * @return bool success of operation + */ + function addIgnore($path) + { + $r = &$this->_getCurrentRelease(); + if ($r === null) { + return false; + } + $this->_isValid = 0; + $r = $this->_mergeTag($r, array('attribs' => array('name' => $path)), + array( + 'filelist' => array(), + 'ignore' => array() + )); + } + + /** + * Add an extension binary package for this extension source code release + * + * Note that the package must be from the same channel as the extension source package + * @param string + */ + function addBinarypackage($package) + { + if ($this->getPackageType() != 'extsrc' && $this->getPackageType() != 'zendextsrc') { + return false; + } + $r = &$this->_getCurrentRelease(false); + if ($r === null) { + return false; + } + $this->_isValid = 0; + $r = $this->_mergeTag($r, $package, + array( + 'binarypackage' => array('filelist'), + )); + } + + /** + * Add a configureoption to an extension source package + * @param string + * @param string + * @param string + */ + function addConfigureOption($name, $prompt, $default = null) + { + if ($this->getPackageType() != 'extsrc' && $this->getPackageType() != 'zendextsrc') { + return false; + } + + $r = &$this->_getCurrentRelease(false); + if ($r === null) { + return false; + } + + $opt = array('attribs' => array('name' => $name, 'prompt' => $prompt)); + if ($default !== null) { + $opt['attribs']['default'] = $default; + } + + $this->_isValid = 0; + $r = $this->_mergeTag($r, $opt, + array( + 'configureoption' => array('binarypackage', 'filelist'), + )); + } + + /** + * Set an installation condition based on php version for the current release set + * @param string minimum version + * @param string maximum version + * @param false|array incompatible versions of PHP + */ + function setPhpInstallCondition($min, $max, $exclude = false) + { + $r = &$this->_getCurrentRelease(); + if ($r === null) { + return false; + } + $this->_isValid = 0; + if (isset($r['installconditions']['php'])) { + unset($r['installconditions']['php']); + } + $dep = array('min' => $min, 'max' => $max); + if ($exclude) { + if (is_array($exclude) && count($exclude) == 1) { + $exclude = $exclude[0]; + } + $dep['exclude'] = $exclude; + } + if ($this->getPackageType() == 'extsrc' || $this->getPackageType() == 'zendextsrc') { + $r = $this->_mergeTag($r, $dep, + array( + 'installconditions' => array('configureoption', 'binarypackage', + 'filelist'), + 'php' => array('extension', 'os', 'arch') + )); + } else { + $r = $this->_mergeTag($r, $dep, + array( + 'installconditions' => array('filelist'), + 'php' => array('extension', 'os', 'arch') + )); + } + } + + /** + * @param optional|required optional, required + * @param string extension name + * @param string minimum version + * @param string maximum version + * @param string recommended version + * @param array incompatible versions + */ + function addExtensionInstallCondition($name, $min = false, $max = false, $recommended = false, + $exclude = false) + { + $r = &$this->_getCurrentRelease(); + if ($r === null) { + return false; + } + $this->_isValid = 0; + $dep = $this->_constructDep($name, false, false, $min, $max, $recommended, $exclude); + if ($this->getPackageType() == 'extsrc' || $this->getPackageType() == 'zendextsrc') { + $r = $this->_mergeTag($r, $dep, + array( + 'installconditions' => array('configureoption', 'binarypackage', + 'filelist'), + 'extension' => array('os', 'arch') + )); + } else { + $r = $this->_mergeTag($r, $dep, + array( + 'installconditions' => array('filelist'), + 'extension' => array('os', 'arch') + )); + } + } + + /** + * Set an installation condition based on operating system for the current release set + * @param string OS name + * @param bool whether this OS is incompatible with the current release + */ + function setOsInstallCondition($name, $conflicts = false) + { + $r = &$this->_getCurrentRelease(); + if ($r === null) { + return false; + } + $this->_isValid = 0; + if (isset($r['installconditions']['os'])) { + unset($r['installconditions']['os']); + } + $dep = array('name' => $name); + if ($conflicts) { + $dep['conflicts'] = ''; + } + if ($this->getPackageType() == 'extsrc' || $this->getPackageType() == 'zendextsrc') { + $r = $this->_mergeTag($r, $dep, + array( + 'installconditions' => array('configureoption', 'binarypackage', + 'filelist'), + 'os' => array('arch') + )); + } else { + $r = $this->_mergeTag($r, $dep, + array( + 'installconditions' => array('filelist'), + 'os' => array('arch') + )); + } + } + + /** + * Set an installation condition based on architecture for the current release set + * @param string architecture pattern + * @param bool whether this arch is incompatible with the current release + */ + function setArchInstallCondition($pattern, $conflicts = false) + { + $r = &$this->_getCurrentRelease(); + if ($r === null) { + return false; + } + $this->_isValid = 0; + if (isset($r['installconditions']['arch'])) { + unset($r['installconditions']['arch']); + } + $dep = array('pattern' => $pattern); + if ($conflicts) { + $dep['conflicts'] = ''; + } + if ($this->getPackageType() == 'extsrc' || $this->getPackageType() == 'zendextsrc') { + $r = $this->_mergeTag($r, $dep, + array( + 'installconditions' => array('configureoption', 'binarypackage', + 'filelist'), + 'arch' => array() + )); + } else { + $r = $this->_mergeTag($r, $dep, + array( + 'installconditions' => array('filelist'), + 'arch' => array() + )); + } + } + + /** + * For extension binary releases, this is used to specify either the + * static URI to a source package, or the package name and channel of the extsrc/zendextsrc + * package it is based on. + * @param string Package name, or full URI to source package (extsrc/zendextsrc type) + */ + function setSourcePackage($packageOrUri) + { + $this->_isValid = 0; + if (isset($this->_packageInfo['channel'])) { + $this->_packageInfo = $this->_insertBefore($this->_packageInfo, array('phprelease', + 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease', + 'bundle', 'changelog'), + $packageOrUri, 'srcpackage'); + } else { + $this->_packageInfo = $this->_insertBefore($this->_packageInfo, array('phprelease', + 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease', + 'bundle', 'changelog'), $packageOrUri, 'srcuri'); + } + } + + /** + * Generate a valid change log entry from the current package.xml + * @param string|false + */ + function generateChangeLogEntry($notes = false) + { + return array( + 'version' => + array( + 'release' => $this->getVersion('release'), + 'api' => $this->getVersion('api'), + ), + 'stability' => + $this->getStability(), + 'date' => $this->getDate(), + 'license' => $this->getLicense(true), + 'notes' => $notes ? $notes : $this->getNotes() + ); + } + + /** + * @param string release version to set change log notes for + * @param array output of {@link generateChangeLogEntry()} + */ + function setChangelogEntry($releaseversion, $contents) + { + if (!isset($this->_packageInfo['changelog'])) { + $this->_packageInfo['changelog']['release'] = $contents; + return; + } + if (!isset($this->_packageInfo['changelog']['release'][0])) { + if ($this->_packageInfo['changelog']['release']['version']['release'] == $releaseversion) { + $this->_packageInfo['changelog']['release'] = array( + $this->_packageInfo['changelog']['release']); + } else { + $this->_packageInfo['changelog']['release'] = array( + $this->_packageInfo['changelog']['release']); + return $this->_packageInfo['changelog']['release'][] = $contents; + } + } + foreach($this->_packageInfo['changelog']['release'] as $index => $changelog) { + if (isset($changelog['version']) && + strnatcasecmp($changelog['version']['release'], $releaseversion) == 0) { + $curlog = $index; + } + } + if (isset($curlog)) { + $this->_packageInfo['changelog']['release'][$curlog] = $contents; + } else { + $this->_packageInfo['changelog']['release'][] = $contents; + } + } + + /** + * Remove the changelog entirely + */ + function clearChangeLog() + { + unset($this->_packageInfo['changelog']); + } +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Packager.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Packager.php new file mode 100644 index 0000000..3303f4c --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Packager.php @@ -0,0 +1,200 @@ + + * @author Tomas V. V. Cox + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 0.1 + */ + +/** + * base class + */ +require_once 'PEAR/Common.php'; +require_once 'PEAR/PackageFile.php'; +require_once 'System.php'; + +/** + * Administration class used to make a PEAR release tarball. + * + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 0.1 + */ +class PEAR_Packager extends PEAR_Common +{ + /** + * @var PEAR_Registry + */ + var $_registry; + + function package($pkgfile = null, $compress = true, $pkg2 = null) + { + // {{{ validate supplied package.xml file + if (empty($pkgfile)) { + $pkgfile = 'package.xml'; + } + + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $pkg = new PEAR_PackageFile($this->config, $this->debug); + $pf = &$pkg->fromPackageFile($pkgfile, PEAR_VALIDATE_NORMAL); + $main = &$pf; + PEAR::staticPopErrorHandling(); + if (PEAR::isError($pf)) { + if (is_array($pf->getUserInfo())) { + foreach ($pf->getUserInfo() as $error) { + $this->log(0, 'Error: ' . $error['message']); + } + } + + $this->log(0, $pf->getMessage()); + return $this->raiseError("Cannot package, errors in package file"); + } + + foreach ($pf->getValidationWarnings() as $warning) { + $this->log(1, 'Warning: ' . $warning['message']); + } + + // }}} + if ($pkg2) { + $this->log(0, 'Attempting to process the second package file'); + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $pf2 = &$pkg->fromPackageFile($pkg2, PEAR_VALIDATE_NORMAL); + PEAR::staticPopErrorHandling(); + if (PEAR::isError($pf2)) { + if (is_array($pf2->getUserInfo())) { + foreach ($pf2->getUserInfo() as $error) { + $this->log(0, 'Error: ' . $error['message']); + } + } + $this->log(0, $pf2->getMessage()); + return $this->raiseError("Cannot package, errors in second package file"); + } + + foreach ($pf2->getValidationWarnings() as $warning) { + $this->log(1, 'Warning: ' . $warning['message']); + } + + if ($pf2->getPackagexmlVersion() == '2.0' || + $pf2->getPackagexmlVersion() == '2.1' + ) { + $main = &$pf2; + $other = &$pf; + } else { + $main = &$pf; + $other = &$pf2; + } + + if ($main->getPackagexmlVersion() != '2.0' && + $main->getPackagexmlVersion() != '2.1') { + return PEAR::raiseError('Error: cannot package two package.xml version 1.0, can ' . + 'only package together a package.xml 1.0 and package.xml 2.0'); + } + + if ($other->getPackagexmlVersion() != '1.0') { + return PEAR::raiseError('Error: cannot package two package.xml version 2.0, can ' . + 'only package together a package.xml 1.0 and package.xml 2.0'); + } + } + + $main->setLogger($this); + if (!$main->validate(PEAR_VALIDATE_PACKAGING)) { + foreach ($main->getValidationWarnings() as $warning) { + $this->log(0, 'Error: ' . $warning['message']); + } + return $this->raiseError("Cannot package, errors in package"); + } + + foreach ($main->getValidationWarnings() as $warning) { + $this->log(1, 'Warning: ' . $warning['message']); + } + + if ($pkg2) { + $other->setLogger($this); + $a = false; + if (!$other->validate(PEAR_VALIDATE_NORMAL) || $a = !$main->isEquivalent($other)) { + foreach ($other->getValidationWarnings() as $warning) { + $this->log(0, 'Error: ' . $warning['message']); + } + + foreach ($main->getValidationWarnings() as $warning) { + $this->log(0, 'Error: ' . $warning['message']); + } + + if ($a) { + return $this->raiseError('The two package.xml files are not equivalent!'); + } + + return $this->raiseError("Cannot package, errors in package"); + } + + foreach ($other->getValidationWarnings() as $warning) { + $this->log(1, 'Warning: ' . $warning['message']); + } + + $gen = &$main->getDefaultGenerator(); + $tgzfile = $gen->toTgz2($this, $other, $compress); + if (PEAR::isError($tgzfile)) { + return $tgzfile; + } + + $dest_package = basename($tgzfile); + $pkgdir = dirname($pkgfile); + + // TAR the Package ------------------------------------------- + $this->log(1, "Package $dest_package done"); + if (file_exists("$pkgdir/CVS/Root")) { + $cvsversion = preg_replace('/[^a-z0-9]/i', '_', $pf->getVersion()); + $cvstag = "RELEASE_$cvsversion"; + $this->log(1, 'Tag the released code with "pear cvstag ' . + $main->getPackageFile() . '"'); + $this->log(1, "(or set the CVS tag $cvstag by hand)"); + } elseif (file_exists("$pkgdir/.svn")) { + $svnversion = preg_replace('/[^a-z0-9]/i', '.', $pf->getVersion()); + $svntag = $pf->getName() . "-$svnversion"; + $this->log(1, 'Tag the released code with "pear svntag ' . + $main->getPackageFile() . '"'); + $this->log(1, "(or set the SVN tag $svntag by hand)"); + } + } else { // this branch is executed for single packagefile packaging + $gen = &$pf->getDefaultGenerator(); + $tgzfile = $gen->toTgz($this, $compress); + if (PEAR::isError($tgzfile)) { + $this->log(0, $tgzfile->getMessage()); + return $this->raiseError("Cannot package, errors in package"); + } + + $dest_package = basename($tgzfile); + $pkgdir = dirname($pkgfile); + + // TAR the Package ------------------------------------------- + $this->log(1, "Package $dest_package done"); + if (file_exists("$pkgdir/CVS/Root")) { + $cvsversion = preg_replace('/[^a-z0-9]/i', '_', $pf->getVersion()); + $cvstag = "RELEASE_$cvsversion"; + $this->log(1, "Tag the released code with `pear cvstag $pkgfile'"); + $this->log(1, "(or set the CVS tag $cvstag by hand)"); + } elseif (file_exists("$pkgdir/.svn")) { + $svnversion = preg_replace('/[^a-z0-9]/i', '.', $pf->getVersion()); + $svntag = $pf->getName() . "-$svnversion"; + $this->log(1, "Tag the released code with `pear svntag $pkgfile'"); + $this->log(1, "(or set the SVN tag $svntag by hand)"); + } + } + + return $dest_package; + } +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/REST.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/REST.php new file mode 100644 index 0000000..c0dfeaa --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/REST.php @@ -0,0 +1,496 @@ + + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * For downloading xml files + */ +require_once 'PEAR.php'; +require_once 'PEAR/XMLParser.php'; + +/** + * Intelligently retrieve data, following hyperlinks if necessary, and re-directing + * as well + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_REST +{ + var $config; + var $_options; + + function __construct(&$config, $options = array()) + { + $this->config = &$config; + $this->_options = $options; + } + + /** + * Retrieve REST data, but always retrieve the local cache if it is available. + * + * This is useful for elements that should never change, such as information on a particular + * release + * @param string full URL to this resource + * @param array|false contents of the accept-encoding header + * @param boolean if true, xml will be returned as a string, otherwise, xml will be + * parsed using PEAR_XMLParser + * @return string|array + */ + function retrieveCacheFirst($url, $accept = false, $forcestring = false, $channel = false) + { + $cachefile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR . + md5($url) . 'rest.cachefile'; + + if (file_exists($cachefile)) { + return unserialize(implode('', file($cachefile))); + } + + return $this->retrieveData($url, $accept, $forcestring, $channel); + } + + /** + * Retrieve a remote REST resource + * @param string full URL to this resource + * @param array|false contents of the accept-encoding header + * @param boolean if true, xml will be returned as a string, otherwise, xml will be + * parsed using PEAR_XMLParser + * @return string|array + */ + function retrieveData($url, $accept = false, $forcestring = false, $channel = false) + { + $cacheId = $this->getCacheId($url); + if ($ret = $this->useLocalCache($url, $cacheId)) { + return $ret; + } + + $file = $trieddownload = false; + if (!isset($this->_options['offline'])) { + $trieddownload = true; + $file = $this->downloadHttp($url, $cacheId ? $cacheId['lastChange'] : false, $accept, $channel); + } + + if (PEAR::isError($file)) { + if ($file->getCode() !== -9276) { + return $file; + } + + $trieddownload = false; + $file = false; // use local copy if available on socket connect error + } + + if (!$file) { + $ret = $this->getCache($url); + if (!PEAR::isError($ret) && $trieddownload) { + // reset the age of the cache if the server says it was unmodified + $result = $this->saveCache($url, $ret, null, true, $cacheId); + if (PEAR::isError($result)) { + return PEAR::raiseError($result->getMessage()); + } + } + + return $ret; + } + + if (is_array($file)) { + $headers = $file[2]; + $lastmodified = $file[1]; + $content = $file[0]; + } else { + $headers = array(); + $lastmodified = false; + $content = $file; + } + + if ($forcestring) { + $result = $this->saveCache($url, $content, $lastmodified, false, $cacheId); + if (PEAR::isError($result)) { + return PEAR::raiseError($result->getMessage()); + } + + return $content; + } + + if (isset($headers['content-type'])) { + $content_type = explode(";", $headers['content-type']); + $content_type = $content_type[0]; + switch ($content_type) { + case 'text/xml' : + case 'application/xml' : + case 'text/plain' : + if ($content_type === 'text/plain') { + $check = substr($content, 0, 5); + if ($check !== 'parse($content); + PEAR::popErrorHandling(); + if (PEAR::isError($err)) { + return PEAR::raiseError('Invalid xml downloaded from "' . $url . '": ' . + $err->getMessage()); + } + $content = $parser->getData(); + case 'text/html' : + default : + // use it as a string + } + } else { + // assume XML + $parser = new PEAR_XMLParser; + $parser->parse($content); + $content = $parser->getData(); + } + + $result = $this->saveCache($url, $content, $lastmodified, false, $cacheId); + if (PEAR::isError($result)) { + return PEAR::raiseError($result->getMessage()); + } + + return $content; + } + + function useLocalCache($url, $cacheid = null) + { + if ($cacheid === null) { + $cacheidfile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR . + md5($url) . 'rest.cacheid'; + if (!file_exists($cacheidfile)) { + return false; + } + + $cacheid = unserialize(implode('', file($cacheidfile))); + } + + $cachettl = $this->config->get('cache_ttl'); + // If cache is newer than $cachettl seconds, we use the cache! + if (time() - $cacheid['age'] < $cachettl) { + return $this->getCache($url); + } + + return false; + } + + function getCacheId($url) + { + $cacheidfile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR . + md5($url) . 'rest.cacheid'; + + if (!file_exists($cacheidfile)) { + return false; + } + + $ret = unserialize(implode('', file($cacheidfile))); + return $ret; + } + + function getCache($url) + { + $cachefile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR . + md5($url) . 'rest.cachefile'; + + if (!file_exists($cachefile)) { + return PEAR::raiseError('No cached content available for "' . $url . '"'); + } + + return unserialize(implode('', file($cachefile))); + } + + /** + * @param string full URL to REST resource + * @param string original contents of the REST resource + * @param array HTTP Last-Modified and ETag headers + * @param bool if true, then the cache id file should be regenerated to + * trigger a new time-to-live value + */ + function saveCache($url, $contents, $lastmodified, $nochange = false, $cacheid = null) + { + $cache_dir = $this->config->get('cache_dir'); + $d = $cache_dir . DIRECTORY_SEPARATOR . md5($url); + $cacheidfile = $d . 'rest.cacheid'; + $cachefile = $d . 'rest.cachefile'; + + if (!is_dir($cache_dir)) { + if (System::mkdir(array('-p', $cache_dir)) === false) { + return PEAR::raiseError("The value of config option cache_dir ($cache_dir) is not a directory and attempts to create the directory failed."); + } + } + + if (!is_writeable($cache_dir)) { + // If writing to the cache dir is not going to work, silently do nothing. + // An ugly hack, but retains compat with PEAR 1.9.1 where many commands + // work fine as non-root user (w/out write access to default cache dir). + return true; + } + + if ($cacheid === null && $nochange) { + $cacheid = unserialize(implode('', file($cacheidfile))); + } + + $idData = serialize(array( + 'age' => time(), + 'lastChange' => ($nochange ? $cacheid['lastChange'] : $lastmodified), + )); + + $result = $this->saveCacheFile($cacheidfile, $idData); + if (PEAR::isError($result)) { + return $result; + } elseif ($nochange) { + return true; + } + + $result = $this->saveCacheFile($cachefile, serialize($contents)); + if (PEAR::isError($result)) { + if (file_exists($cacheidfile)) { + @unlink($cacheidfile); + } + + return $result; + } + + return true; + } + + function saveCacheFile($file, $contents) + { + $len = strlen($contents); + + $cachefile_fp = @fopen($file, 'xb'); // x is the O_CREAT|O_EXCL mode + if ($cachefile_fp !== false) { // create file + if (fwrite($cachefile_fp, $contents, $len) < $len) { + fclose($cachefile_fp); + return PEAR::raiseError("Could not write $file."); + } + } else { // update file + $cachefile_fp = @fopen($file, 'r+b'); // do not truncate file + if (!$cachefile_fp) { + return PEAR::raiseError("Could not open $file for writing."); + } + + if (OS_WINDOWS) { + $not_symlink = !is_link($file); // see bug #18834 + } else { + $cachefile_lstat = lstat($file); + $cachefile_fstat = fstat($cachefile_fp); + $not_symlink = $cachefile_lstat['mode'] == $cachefile_fstat['mode'] + && $cachefile_lstat['ino'] == $cachefile_fstat['ino'] + && $cachefile_lstat['dev'] == $cachefile_fstat['dev'] + && $cachefile_fstat['nlink'] === 1; + } + + if ($not_symlink) { + ftruncate($cachefile_fp, 0); // NOW truncate + if (fwrite($cachefile_fp, $contents, $len) < $len) { + fclose($cachefile_fp); + return PEAR::raiseError("Could not write $file."); + } + } else { + fclose($cachefile_fp); + $link = function_exists('readlink') ? readlink($file) : $file; + return PEAR::raiseError('SECURITY ERROR: Will not write to ' . $file . ' as it is symlinked to ' . $link . ' - Possible symlink attack'); + } + } + + fclose($cachefile_fp); + return true; + } + + /** + * Efficiently Download a file through HTTP. Returns downloaded file as a string in-memory + * This is best used for small files + * + * If an HTTP proxy has been configured (http_proxy PEAR_Config + * setting), the proxy will be used. + * + * @param string $url the URL to download + * @param string $save_dir directory to save file in + * @param false|string|array $lastmodified header values to check against for caching + * use false to return the header values from this download + * @param false|array $accept Accept headers to send + * @return string|array Returns the contents of the downloaded file or a PEAR + * error on failure. If the error is caused by + * socket-related errors, the error object will + * have the fsockopen error code available through + * getCode(). If caching is requested, then return the header + * values. + * + * @access public + */ + function downloadHttp($url, $lastmodified = null, $accept = false, $channel = false) + { + static $redirect = 0; + // always reset , so we are clean case of error + $wasredirect = $redirect; + $redirect = 0; + + $info = parse_url($url); + if (!isset($info['scheme']) || !in_array($info['scheme'], array('http', 'https'))) { + return PEAR::raiseError('Cannot download non-http URL "' . $url . '"'); + } + + if (!isset($info['host'])) { + return PEAR::raiseError('Cannot download from non-URL "' . $url . '"'); + } + + $host = isset($info['host']) ? $info['host'] : null; + $port = isset($info['port']) ? $info['port'] : null; + $path = isset($info['path']) ? $info['path'] : null; + $schema = (isset($info['scheme']) && $info['scheme'] == 'https') ? 'https' : 'http'; + + $proxy_host = $proxy_port = $proxy_user = $proxy_pass = ''; + if ($this->config->get('http_proxy')&& + $proxy = parse_url($this->config->get('http_proxy')) + ) { + $proxy_host = isset($proxy['host']) ? $proxy['host'] : null; + if ($schema === 'https') { + $proxy_host = 'ssl://' . $proxy_host; + } + + $proxy_port = isset($proxy['port']) ? $proxy['port'] : 8080; + $proxy_user = isset($proxy['user']) ? urldecode($proxy['user']) : null; + $proxy_pass = isset($proxy['pass']) ? urldecode($proxy['pass']) : null; + $proxy_schema = (isset($proxy['scheme']) && $proxy['scheme'] == 'https') ? 'https' : 'http'; + } + + if (empty($port)) { + $port = (isset($info['scheme']) && $info['scheme'] == 'https') ? 443 : 80; + } + + if (isset($proxy['host'])) { + $request = "GET $url HTTP/1.1\r\n"; + } else { + $request = "GET $path HTTP/1.1\r\n"; + } + + $request .= "Host: $host\r\n"; + $ifmodifiedsince = ''; + if (is_array($lastmodified)) { + if (isset($lastmodified['Last-Modified'])) { + $ifmodifiedsince = 'If-Modified-Since: ' . $lastmodified['Last-Modified'] . "\r\n"; + } + + if (isset($lastmodified['ETag'])) { + $ifmodifiedsince .= "If-None-Match: $lastmodified[ETag]\r\n"; + } + } else { + $ifmodifiedsince = ($lastmodified ? "If-Modified-Since: $lastmodified\r\n" : ''); + } + + $request .= $ifmodifiedsince . + "User-Agent: PEAR/1.10.1/PHP/" . PHP_VERSION . "\r\n"; + + $username = $this->config->get('username', null, $channel); + $password = $this->config->get('password', null, $channel); + + if ($username && $password) { + $tmp = base64_encode("$username:$password"); + $request .= "Authorization: Basic $tmp\r\n"; + } + + if ($proxy_host != '' && $proxy_user != '') { + $request .= 'Proxy-Authorization: Basic ' . + base64_encode($proxy_user . ':' . $proxy_pass) . "\r\n"; + } + + if ($accept) { + $request .= 'Accept: ' . implode(', ', $accept) . "\r\n"; + } + + $request .= "Accept-Encoding:\r\n"; + $request .= "Connection: close\r\n"; + $request .= "\r\n"; + + if ($proxy_host != '') { + $fp = @fsockopen($proxy_host, $proxy_port, $errno, $errstr, 15); + if (!$fp) { + return PEAR::raiseError("Connection to `$proxy_host:$proxy_port' failed: $errstr", -9276); + } + } else { + if ($schema === 'https') { + $host = 'ssl://' . $host; + } + + $fp = @fsockopen($host, $port, $errno, $errstr); + if (!$fp) { + return PEAR::raiseError("Connection to `$host:$port' failed: $errstr", $errno); + } + } + + fwrite($fp, $request); + + $headers = array(); + $reply = 0; + while ($line = trim(fgets($fp, 1024))) { + if (preg_match('/^([^:]+):\s+(.*)\s*\\z/', $line, $matches)) { + $headers[strtolower($matches[1])] = trim($matches[2]); + } elseif (preg_match('|^HTTP/1.[01] ([0-9]{3}) |', $line, $matches)) { + $reply = (int)$matches[1]; + if ($reply == 304 && ($lastmodified || ($lastmodified === false))) { + return false; + } + + if (!in_array($reply, array(200, 301, 302, 303, 305, 307))) { + return PEAR::raiseError("File $schema://$host:$port$path not valid (received: $line)"); + } + } + } + + if ($reply != 200) { + if (!isset($headers['location'])) { + return PEAR::raiseError("File $schema://$host:$port$path not valid (redirected but no location)"); + } + + if ($wasredirect > 4) { + return PEAR::raiseError("File $schema://$host:$port$path not valid (redirection looped more than 5 times)"); + } + + $redirect = $wasredirect + 1; + return $this->downloadHttp($headers['location'], $lastmodified, $accept, $channel); + } + + $length = isset($headers['content-length']) ? $headers['content-length'] : -1; + + $data = ''; + while ($chunk = @fread($fp, 8192)) { + $data .= $chunk; + } + fclose($fp); + + if ($lastmodified === false || $lastmodified) { + if (isset($headers['etag'])) { + $lastmodified = array('ETag' => $headers['etag']); + } + + if (isset($headers['last-modified'])) { + if (is_array($lastmodified)) { + $lastmodified['Last-Modified'] = $headers['last-modified']; + } else { + $lastmodified = $headers['last-modified']; + } + } + + return array($data, $lastmodified, $headers); + } + + return $data; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/REST/10.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/REST/10.php new file mode 100644 index 0000000..affcc18 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/REST/10.php @@ -0,0 +1,870 @@ + + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a12 + */ + +/** + * For downloading REST xml/txt files + */ +require_once 'PEAR/REST.php'; + +/** + * Implement REST 1.0 + * + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a12 + */ +class PEAR_REST_10 +{ + /** + * @var PEAR_REST + */ + var $_rest; + function __construct($config, $options = array()) + { + $this->_rest = new PEAR_REST($config, $options); + } + + /** + * Retrieve information about a remote package to be downloaded from a REST server + * + * @param string $base The uri to prepend to all REST calls + * @param array $packageinfo an array of format: + *
    +     *  array(
    +     *   'package' => 'packagename',
    +     *   'channel' => 'channelname',
    +     *  ['state' => 'alpha' (or valid state),]
    +     *  -or-
    +     *  ['version' => '1.whatever']
    +     * 
    + * @param string $prefstate Current preferred_state config variable value + * @param bool $installed the installed version of this package to compare against + * @return array|false|PEAR_Error see {@link _returnDownloadURL()} + */ + function getDownloadURL($base, $packageinfo, $prefstate, $installed, $channel = false) + { + $states = $this->betterStates($prefstate, true); + if (!$states) { + return PEAR::raiseError('"' . $prefstate . '" is not a valid state'); + } + + $channel = $packageinfo['channel']; + $package = $packageinfo['package']; + $state = isset($packageinfo['state']) ? $packageinfo['state'] : null; + $version = isset($packageinfo['version']) ? $packageinfo['version'] : null; + $restFile = $base . 'r/' . strtolower($package) . '/allreleases.xml'; + + $info = $this->_rest->retrieveData($restFile, false, false, $channel); + if (PEAR::isError($info)) { + return PEAR::raiseError('No releases available for package "' . + $channel . '/' . $package . '"'); + } + + if (!isset($info['r'])) { + return false; + } + + $release = $found = false; + if (!is_array($info['r']) || !isset($info['r'][0])) { + $info['r'] = array($info['r']); + } + + foreach ($info['r'] as $release) { + if (!isset($this->_rest->_options['force']) && ($installed && + version_compare($release['v'], $installed, '<'))) { + continue; + } + + if (isset($state)) { + // try our preferred state first + if ($release['s'] == $state) { + $found = true; + break; + } + // see if there is something newer and more stable + // bug #7221 + if (in_array($release['s'], $this->betterStates($state), true)) { + $found = true; + break; + } + } elseif (isset($version)) { + if ($release['v'] == $version) { + $found = true; + break; + } + } else { + if (in_array($release['s'], $states)) { + $found = true; + break; + } + } + } + + return $this->_returnDownloadURL($base, $package, $release, $info, $found, false, $channel); + } + + function getDepDownloadURL($base, $xsdversion, $dependency, $deppackage, + $prefstate = 'stable', $installed = false, $channel = false) + { + $states = $this->betterStates($prefstate, true); + if (!$states) { + return PEAR::raiseError('"' . $prefstate . '" is not a valid state'); + } + + $channel = $dependency['channel']; + $package = $dependency['name']; + $state = isset($dependency['state']) ? $dependency['state'] : null; + $version = isset($dependency['version']) ? $dependency['version'] : null; + $restFile = $base . 'r/' . strtolower($package) . '/allreleases.xml'; + + $info = $this->_rest->retrieveData($restFile, false, false, $channel); + if (PEAR::isError($info)) { + return PEAR::raiseError('Package "' . $deppackage['channel'] . '/' . $deppackage['package'] + . '" dependency "' . $channel . '/' . $package . '" has no releases'); + } + + if (!is_array($info) || !isset($info['r'])) { + return false; + } + + $exclude = array(); + $min = $max = $recommended = false; + if ($xsdversion == '1.0') { + switch ($dependency['rel']) { + case 'ge' : + $min = $dependency['version']; + break; + case 'gt' : + $min = $dependency['version']; + $exclude = array($dependency['version']); + break; + case 'eq' : + $recommended = $dependency['version']; + break; + case 'lt' : + $max = $dependency['version']; + $exclude = array($dependency['version']); + break; + case 'le' : + $max = $dependency['version']; + break; + case 'ne' : + $exclude = array($dependency['version']); + break; + } + } else { + $min = isset($dependency['min']) ? $dependency['min'] : false; + $max = isset($dependency['max']) ? $dependency['max'] : false; + $recommended = isset($dependency['recommended']) ? + $dependency['recommended'] : false; + if (isset($dependency['exclude'])) { + if (!isset($dependency['exclude'][0])) { + $exclude = array($dependency['exclude']); + } + } + } + $release = $found = false; + if (!is_array($info['r']) || !isset($info['r'][0])) { + $info['r'] = array($info['r']); + } + foreach ($info['r'] as $release) { + if (!isset($this->_rest->_options['force']) && ($installed && + version_compare($release['v'], $installed, '<'))) { + continue; + } + if (in_array($release['v'], $exclude)) { // skip excluded versions + continue; + } + // allow newer releases to say "I'm OK with the dependent package" + if ($xsdversion == '2.0' && isset($release['co'])) { + if (!is_array($release['co']) || !isset($release['co'][0])) { + $release['co'] = array($release['co']); + } + foreach ($release['co'] as $entry) { + if (isset($entry['x']) && !is_array($entry['x'])) { + $entry['x'] = array($entry['x']); + } elseif (!isset($entry['x'])) { + $entry['x'] = array(); + } + if ($entry['c'] == $deppackage['channel'] && + strtolower($entry['p']) == strtolower($deppackage['package']) && + version_compare($deppackage['version'], $entry['min'], '>=') && + version_compare($deppackage['version'], $entry['max'], '<=') && + !in_array($release['v'], $entry['x'])) { + $recommended = $release['v']; + break; + } + } + } + if ($recommended) { + if ($release['v'] != $recommended) { // if we want a specific + // version, then skip all others + continue; + } else { + if (!in_array($release['s'], $states)) { + // the stability is too low, but we must return the + // recommended version if possible + return $this->_returnDownloadURL($base, $package, $release, $info, true, false, $channel); + } + } + } + if ($min && version_compare($release['v'], $min, 'lt')) { // skip too old versions + continue; + } + if ($max && version_compare($release['v'], $max, 'gt')) { // skip too new versions + continue; + } + if ($installed && version_compare($release['v'], $installed, '<')) { + continue; + } + if (in_array($release['s'], $states)) { // if in the preferred state... + $found = true; // ... then use it + break; + } + } + return $this->_returnDownloadURL($base, $package, $release, $info, $found, false, $channel); + } + + /** + * Take raw data and return the array needed for processing a download URL + * + * @param string $base REST base uri + * @param string $package Package name + * @param array $release an array of format array('v' => version, 's' => state) + * describing the release to download + * @param array $info list of all releases as defined by allreleases.xml + * @param bool|null $found determines whether the release was found or this is the next + * best alternative. If null, then versions were skipped because + * of PHP dependency + * @return array|PEAR_Error + * @access private + */ + function _returnDownloadURL($base, $package, $release, $info, $found, $phpversion = false, $channel = false) + { + if (!$found) { + $release = $info['r'][0]; + } + + $packageLower = strtolower($package); + $pinfo = $this->_rest->retrieveCacheFirst($base . 'p/' . $packageLower . '/' . + 'info.xml', false, false, $channel); + if (PEAR::isError($pinfo)) { + return PEAR::raiseError('Package "' . $package . + '" does not have REST info xml available'); + } + + $releaseinfo = $this->_rest->retrieveCacheFirst($base . 'r/' . $packageLower . '/' . + $release['v'] . '.xml', false, false, $channel); + if (PEAR::isError($releaseinfo)) { + return PEAR::raiseError('Package "' . $package . '" Version "' . $release['v'] . + '" does not have REST xml available'); + } + + $packagexml = $this->_rest->retrieveCacheFirst($base . 'r/' . $packageLower . '/' . + 'deps.' . $release['v'] . '.txt', false, true, $channel); + if (PEAR::isError($packagexml)) { + return PEAR::raiseError('Package "' . $package . '" Version "' . $release['v'] . + '" does not have REST dependency information available'); + } + + $packagexml = unserialize($packagexml); + if (!$packagexml) { + $packagexml = array(); + } + + $allinfo = $this->_rest->retrieveData($base . 'r/' . $packageLower . + '/allreleases.xml', false, false, $channel); + if (PEAR::isError($allinfo)) { + return $allinfo; + } + + if (!is_array($allinfo['r']) || !isset($allinfo['r'][0])) { + $allinfo['r'] = array($allinfo['r']); + } + + $compatible = false; + foreach ($allinfo['r'] as $release) { + if ($release['v'] != $releaseinfo['v']) { + continue; + } + + if (!isset($release['co'])) { + break; + } + + $compatible = array(); + if (!is_array($release['co']) || !isset($release['co'][0])) { + $release['co'] = array($release['co']); + } + + foreach ($release['co'] as $entry) { + $comp = array(); + $comp['name'] = $entry['p']; + $comp['channel'] = $entry['c']; + $comp['min'] = $entry['min']; + $comp['max'] = $entry['max']; + if (isset($entry['x']) && !is_array($entry['x'])) { + $comp['exclude'] = $entry['x']; + } + + $compatible[] = $comp; + } + + if (count($compatible) == 1) { + $compatible = $compatible[0]; + } + + break; + } + + $deprecated = false; + if (isset($pinfo['dc']) && isset($pinfo['dp'])) { + if (is_array($pinfo['dp'])) { + $deprecated = array('channel' => (string) $pinfo['dc'], + 'package' => trim($pinfo['dp']['_content'])); + } else { + $deprecated = array('channel' => (string) $pinfo['dc'], + 'package' => trim($pinfo['dp'])); + } + } + + $return = array( + 'version' => $releaseinfo['v'], + 'info' => $packagexml, + 'package' => $releaseinfo['p']['_content'], + 'stability' => $releaseinfo['st'], + 'compatible' => $compatible, + 'deprecated' => $deprecated, + ); + + if ($found) { + $return['url'] = $releaseinfo['g']; + return $return; + } + + $return['php'] = $phpversion; + return $return; + } + + function listPackages($base, $channel = false) + { + $packagelist = $this->_rest->retrieveData($base . 'p/packages.xml', false, false, $channel); + if (PEAR::isError($packagelist)) { + return $packagelist; + } + + if (!is_array($packagelist) || !isset($packagelist['p'])) { + return array(); + } + + if (!is_array($packagelist['p'])) { + $packagelist['p'] = array($packagelist['p']); + } + + return $packagelist['p']; + } + + /** + * List all categories of a REST server + * + * @param string $base base URL of the server + * @return array of categorynames + */ + function listCategories($base, $channel = false) + { + $categories = array(); + + // c/categories.xml does not exist; + // check for every package its category manually + // This is SLOOOWWWW : /// + $packagelist = $this->_rest->retrieveData($base . 'p/packages.xml', false, false, $channel); + if (PEAR::isError($packagelist)) { + return $packagelist; + } + + if (!is_array($packagelist) || !isset($packagelist['p'])) { + $ret = array(); + return $ret; + } + + if (!is_array($packagelist['p'])) { + $packagelist['p'] = array($packagelist['p']); + } + + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + foreach ($packagelist['p'] as $package) { + $inf = $this->_rest->retrieveData($base . 'p/' . strtolower($package) . '/info.xml', false, false, $channel); + if (PEAR::isError($inf)) { + PEAR::popErrorHandling(); + return $inf; + } + $cat = $inf['ca']['_content']; + if (!isset($categories[$cat])) { + $categories[$cat] = $inf['ca']; + } + } + + return array_values($categories); + } + + /** + * List a category of a REST server + * + * @param string $base base URL of the server + * @param string $category name of the category + * @param boolean $info also download full package info + * @return array of packagenames + */ + function listCategory($base, $category, $info = false, $channel = false) + { + // gives '404 Not Found' error when category doesn't exist + $packagelist = $this->_rest->retrieveData($base.'c/'.urlencode($category).'/packages.xml', false, false, $channel); + if (PEAR::isError($packagelist)) { + return $packagelist; + } + + if (!is_array($packagelist) || !isset($packagelist['p'])) { + return array(); + } + + if (!is_array($packagelist['p']) || + !isset($packagelist['p'][0])) { // only 1 pkg + $packagelist = array($packagelist['p']); + } else { + $packagelist = $packagelist['p']; + } + + if ($info == true) { + // get individual package info + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + foreach ($packagelist as $i => $packageitem) { + $url = sprintf('%s'.'r/%s/latest.txt', + $base, + strtolower($packageitem['_content'])); + $version = $this->_rest->retrieveData($url, false, false, $channel); + if (PEAR::isError($version)) { + break; // skipit + } + $url = sprintf('%s'.'r/%s/%s.xml', + $base, + strtolower($packageitem['_content']), + $version); + $info = $this->_rest->retrieveData($url, false, false, $channel); + if (PEAR::isError($info)) { + break; // skipit + } + $packagelist[$i]['info'] = $info; + } + PEAR::popErrorHandling(); + } + + return $packagelist; + } + + + function listAll($base, $dostable, $basic = true, $searchpackage = false, $searchsummary = false, $channel = false) + { + $packagelist = $this->_rest->retrieveData($base . 'p/packages.xml', false, false, $channel); + if (PEAR::isError($packagelist)) { + return $packagelist; + } + if ($this->_rest->config->get('verbose') > 0) { + $ui = &PEAR_Frontend::singleton(); + $ui->log('Retrieving data...0%', true); + } + $ret = array(); + if (!is_array($packagelist) || !isset($packagelist['p'])) { + return $ret; + } + if (!is_array($packagelist['p'])) { + $packagelist['p'] = array($packagelist['p']); + } + + // only search-packagename = quicksearch ! + if ($searchpackage && (!$searchsummary || empty($searchpackage))) { + $newpackagelist = array(); + foreach ($packagelist['p'] as $package) { + if (!empty($searchpackage) && stristr($package, $searchpackage) !== false) { + $newpackagelist[] = $package; + } + } + $packagelist['p'] = $newpackagelist; + } + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $next = .1; + foreach ($packagelist['p'] as $progress => $package) { + if ($this->_rest->config->get('verbose') > 0) { + if ($progress / count($packagelist['p']) >= $next) { + if ($next == .5) { + $ui->log('50%', false); + } else { + $ui->log('.', false); + } + $next += .1; + } + } + + if ($basic) { // remote-list command + if ($dostable) { + $latest = $this->_rest->retrieveData($base . 'r/' . strtolower($package) . + '/stable.txt', false, false, $channel); + } else { + $latest = $this->_rest->retrieveData($base . 'r/' . strtolower($package) . + '/latest.txt', false, false, $channel); + } + if (PEAR::isError($latest)) { + $latest = false; + } + $info = array('stable' => $latest); + } else { // list-all command + $inf = $this->_rest->retrieveData($base . 'p/' . strtolower($package) . '/info.xml', false, false, $channel); + if (PEAR::isError($inf)) { + PEAR::popErrorHandling(); + return $inf; + } + if ($searchpackage) { + $found = (!empty($searchpackage) && stristr($package, $searchpackage) !== false); + if (!$found && !(isset($searchsummary) && !empty($searchsummary) + && (stristr($inf['s'], $searchsummary) !== false + || stristr($inf['d'], $searchsummary) !== false))) + { + continue; + }; + } + $releases = $this->_rest->retrieveData($base . 'r/' . strtolower($package) . + '/allreleases.xml', false, false, $channel); + if (PEAR::isError($releases)) { + continue; + } + if (!isset($releases['r'][0])) { + $releases['r'] = array($releases['r']); + } + unset($latest); + unset($unstable); + unset($stable); + unset($state); + foreach ($releases['r'] as $release) { + if (!isset($latest)) { + if ($dostable && $release['s'] == 'stable') { + $latest = $release['v']; + $state = 'stable'; + } + if (!$dostable) { + $latest = $release['v']; + $state = $release['s']; + } + } + if (!isset($stable) && $release['s'] == 'stable') { + $stable = $release['v']; + if (!isset($unstable)) { + $unstable = $stable; + } + } + if (!isset($unstable) && $release['s'] != 'stable') { + $latest = $unstable = $release['v']; + $state = $release['s']; + } + if (isset($latest) && !isset($state)) { + $state = $release['s']; + } + if (isset($latest) && isset($stable) && isset($unstable)) { + break; + } + } + $deps = array(); + if (!isset($unstable)) { + $unstable = false; + $state = 'stable'; + if (isset($stable)) { + $latest = $unstable = $stable; + } + } else { + $latest = $unstable; + } + if (!isset($latest)) { + $latest = false; + } + if ($latest) { + $d = $this->_rest->retrieveCacheFirst($base . 'r/' . strtolower($package) . '/deps.' . + $latest . '.txt', false, false, $channel); + if (!PEAR::isError($d)) { + $d = unserialize($d); + if ($d) { + if (isset($d['required'])) { + if (!class_exists('PEAR_PackageFile_v2')) { + require_once 'PEAR/PackageFile/v2.php'; + } + if (!isset($pf)) { + $pf = new PEAR_PackageFile_v2; + } + $pf->setDeps($d); + $tdeps = $pf->getDeps(); + } else { + $tdeps = $d; + } + foreach ($tdeps as $dep) { + if ($dep['type'] !== 'pkg') { + continue; + } + $deps[] = $dep; + } + } + } + } + if (!isset($stable)) { + $stable = '-n/a-'; + } + if (!$searchpackage) { + $info = array('stable' => $latest, 'summary' => $inf['s'], 'description' => + $inf['d'], 'deps' => $deps, 'category' => $inf['ca']['_content'], + 'unstable' => $unstable, 'state' => $state); + } else { + $info = array('stable' => $stable, 'summary' => $inf['s'], 'description' => + $inf['d'], 'deps' => $deps, 'category' => $inf['ca']['_content'], + 'unstable' => $unstable, 'state' => $state); + } + } + $ret[$package] = $info; + } + PEAR::popErrorHandling(); + return $ret; + } + + function listLatestUpgrades($base, $pref_state, $installed, $channel, &$reg) + { + $packagelist = $this->_rest->retrieveData($base . 'p/packages.xml', false, false, $channel); + if (PEAR::isError($packagelist)) { + return $packagelist; + } + + $ret = array(); + if (!is_array($packagelist) || !isset($packagelist['p'])) { + return $ret; + } + + if (!is_array($packagelist['p'])) { + $packagelist['p'] = array($packagelist['p']); + } + + foreach ($packagelist['p'] as $package) { + if (!isset($installed[strtolower($package)])) { + continue; + } + + $inst_version = $reg->packageInfo($package, 'version', $channel); + $inst_state = $reg->packageInfo($package, 'release_state', $channel); + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $info = $this->_rest->retrieveData($base . 'r/' . strtolower($package) . + '/allreleases.xml', false, false, $channel); + PEAR::popErrorHandling(); + if (PEAR::isError($info)) { + continue; // no remote releases + } + + if (!isset($info['r'])) { + continue; + } + + $release = $found = false; + if (!is_array($info['r']) || !isset($info['r'][0])) { + $info['r'] = array($info['r']); + } + + // $info['r'] is sorted by version number + usort($info['r'], array($this, '_sortReleasesByVersionNumber')); + foreach ($info['r'] as $release) { + if ($inst_version && version_compare($release['v'], $inst_version, '<=')) { + // not newer than the one installed + break; + } + + // new version > installed version + if (!$pref_state) { + // every state is a good state + $found = true; + break; + } else { + $new_state = $release['s']; + // if new state >= installed state: go + if (in_array($new_state, $this->betterStates($inst_state, true))) { + $found = true; + break; + } else { + // only allow to lower the state of package, + // if new state >= preferred state: go + if (in_array($new_state, $this->betterStates($pref_state, true))) { + $found = true; + break; + } + } + } + } + + if (!$found) { + continue; + } + + $relinfo = $this->_rest->retrieveCacheFirst($base . 'r/' . strtolower($package) . '/' . + $release['v'] . '.xml', false, false, $channel); + if (PEAR::isError($relinfo)) { + return $relinfo; + } + + $ret[$package] = array( + 'version' => $release['v'], + 'state' => $release['s'], + 'filesize' => $relinfo['f'], + ); + } + + return $ret; + } + + function packageInfo($base, $package, $channel = false) + { + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $pinfo = $this->_rest->retrieveData($base . 'p/' . strtolower($package) . '/info.xml', false, false, $channel); + if (PEAR::isError($pinfo)) { + PEAR::popErrorHandling(); + return PEAR::raiseError('Unknown package: "' . $package . '" in channel "' . $channel . '"' . "\n". 'Debug: ' . + $pinfo->getMessage()); + } + + $releases = array(); + $allreleases = $this->_rest->retrieveData($base . 'r/' . strtolower($package) . + '/allreleases.xml', false, false, $channel); + if (!PEAR::isError($allreleases)) { + if (!class_exists('PEAR_PackageFile_v2')) { + require_once 'PEAR/PackageFile/v2.php'; + } + + if (!is_array($allreleases['r']) || !isset($allreleases['r'][0])) { + $allreleases['r'] = array($allreleases['r']); + } + + $pf = new PEAR_PackageFile_v2; + foreach ($allreleases['r'] as $release) { + $ds = $this->_rest->retrieveCacheFirst($base . 'r/' . strtolower($package) . '/deps.' . + $release['v'] . '.txt', false, false, $channel); + if (PEAR::isError($ds)) { + continue; + } + + if (!isset($latest)) { + $latest = $release['v']; + } + + $pf->setDeps(unserialize($ds)); + $ds = $pf->getDeps(); + $info = $this->_rest->retrieveCacheFirst($base . 'r/' . strtolower($package) + . '/' . $release['v'] . '.xml', false, false, $channel); + + if (PEAR::isError($info)) { + continue; + } + + $releases[$release['v']] = array( + 'doneby' => $info['m'], + 'license' => $info['l'], + 'summary' => $info['s'], + 'description' => $info['d'], + 'releasedate' => $info['da'], + 'releasenotes' => $info['n'], + 'state' => $release['s'], + 'deps' => $ds ? $ds : array(), + ); + } + } else { + $latest = ''; + } + + PEAR::popErrorHandling(); + if (isset($pinfo['dc']) && isset($pinfo['dp'])) { + if (is_array($pinfo['dp'])) { + $deprecated = array('channel' => (string) $pinfo['dc'], + 'package' => trim($pinfo['dp']['_content'])); + } else { + $deprecated = array('channel' => (string) $pinfo['dc'], + 'package' => trim($pinfo['dp'])); + } + } else { + $deprecated = false; + } + + if (!isset($latest)) { + $latest = ''; + } + + return array( + 'name' => $pinfo['n'], + 'channel' => $pinfo['c'], + 'category' => $pinfo['ca']['_content'], + 'stable' => $latest, + 'license' => $pinfo['l'], + 'summary' => $pinfo['s'], + 'description' => $pinfo['d'], + 'releases' => $releases, + 'deprecated' => $deprecated, + ); + } + + /** + * Return an array containing all of the states that are more stable than + * or equal to the passed in state + * + * @param string Release state + * @param boolean Determines whether to include $state in the list + * @return false|array False if $state is not a valid release state + */ + function betterStates($state, $include = false) + { + static $states = array('snapshot', 'devel', 'alpha', 'beta', 'stable'); + $i = array_search($state, $states); + if ($i === false) { + return false; + } + + if ($include) { + $i--; + } + + return array_slice($states, $i + 1); + } + + /** + * Sort releases by version number + * + * @access private + */ + function _sortReleasesByVersionNumber($a, $b) + { + if (version_compare($a['v'], $b['v'], '=')) { + return 0; + } + + if (version_compare($a['v'], $b['v'], '>')) { + return -1; + } + + if (version_compare($a['v'], $b['v'], '<')) { + return 1; + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/REST/11.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/REST/11.php new file mode 100644 index 0000000..9bd51ba --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/REST/11.php @@ -0,0 +1,340 @@ + + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.3 + */ + +/** + * For downloading REST xml/txt files + */ +require_once 'PEAR/REST.php'; + +/** + * Implement REST 1.1 + * + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.3 + */ +class PEAR_REST_11 +{ + /** + * @var PEAR_REST + */ + var $_rest; + + function __construct($config, $options = array()) + { + $this->_rest = new PEAR_REST($config, $options); + } + + function listAll($base, $dostable, $basic = true, $searchpackage = false, $searchsummary = false, $channel = false) + { + $categorylist = $this->_rest->retrieveData($base . 'c/categories.xml', false, false, $channel); + if (PEAR::isError($categorylist)) { + return $categorylist; + } + + $ret = array(); + if (!is_array($categorylist['c']) || !isset($categorylist['c'][0])) { + $categorylist['c'] = array($categorylist['c']); + } + + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + + foreach ($categorylist['c'] as $progress => $category) { + $category = $category['_content']; + $packagesinfo = $this->_rest->retrieveData($base . + 'c/' . urlencode($category) . '/packagesinfo.xml', false, false, $channel); + + if (PEAR::isError($packagesinfo)) { + continue; + } + + if (!is_array($packagesinfo) || !isset($packagesinfo['pi'])) { + continue; + } + + if (!is_array($packagesinfo['pi']) || !isset($packagesinfo['pi'][0])) { + $packagesinfo['pi'] = array($packagesinfo['pi']); + } + + foreach ($packagesinfo['pi'] as $packageinfo) { + if (empty($packageinfo)) { + continue; + } + + $info = $packageinfo['p']; + $package = $info['n']; + $releases = isset($packageinfo['a']) ? $packageinfo['a'] : false; + unset($latest); + unset($unstable); + unset($stable); + unset($state); + + if ($releases) { + if (!isset($releases['r'][0])) { + $releases['r'] = array($releases['r']); + } + + foreach ($releases['r'] as $release) { + if (!isset($latest)) { + if ($dostable && $release['s'] == 'stable') { + $latest = $release['v']; + $state = 'stable'; + } + if (!$dostable) { + $latest = $release['v']; + $state = $release['s']; + } + } + + if (!isset($stable) && $release['s'] == 'stable') { + $stable = $release['v']; + if (!isset($unstable)) { + $unstable = $stable; + } + } + + if (!isset($unstable) && $release['s'] != 'stable') { + $unstable = $release['v']; + $state = $release['s']; + } + + if (isset($latest) && !isset($state)) { + $state = $release['s']; + } + + if (isset($latest) && isset($stable) && isset($unstable)) { + break; + } + } + } + + if ($basic) { // remote-list command + if (!isset($latest)) { + $latest = false; + } + + if ($dostable) { + // $state is not set if there are no releases + if (isset($state) && $state == 'stable') { + $ret[$package] = array('stable' => $latest); + } else { + $ret[$package] = array('stable' => '-n/a-'); + } + } else { + $ret[$package] = array('stable' => $latest); + } + + continue; + } + + // list-all command + if (!isset($unstable)) { + $unstable = false; + $state = 'stable'; + if (isset($stable)) { + $latest = $unstable = $stable; + } + } else { + $latest = $unstable; + } + + if (!isset($latest)) { + $latest = false; + } + + $deps = array(); + if ($latest && isset($packageinfo['deps'])) { + if (!is_array($packageinfo['deps']) || + !isset($packageinfo['deps'][0]) + ) { + $packageinfo['deps'] = array($packageinfo['deps']); + } + + $d = false; + foreach ($packageinfo['deps'] as $dep) { + if ($dep['v'] == $latest) { + $d = unserialize($dep['d']); + } + } + + if ($d) { + if (isset($d['required'])) { + if (!class_exists('PEAR_PackageFile_v2')) { + require_once 'PEAR/PackageFile/v2.php'; + } + + if (!isset($pf)) { + $pf = new PEAR_PackageFile_v2; + } + + $pf->setDeps($d); + $tdeps = $pf->getDeps(); + } else { + $tdeps = $d; + } + + foreach ($tdeps as $dep) { + if ($dep['type'] !== 'pkg') { + continue; + } + + $deps[] = $dep; + } + } + } + + $info = array( + 'stable' => $latest, + 'summary' => $info['s'], + 'description' => $info['d'], + 'deps' => $deps, + 'category' => $info['ca']['_content'], + 'unstable' => $unstable, + 'state' => $state + ); + $ret[$package] = $info; + } + } + + PEAR::popErrorHandling(); + return $ret; + } + + /** + * List all categories of a REST server + * + * @param string $base base URL of the server + * @return array of categorynames + */ + function listCategories($base, $channel = false) + { + $categorylist = $this->_rest->retrieveData($base . 'c/categories.xml', false, false, $channel); + if (PEAR::isError($categorylist)) { + return $categorylist; + } + + if (!is_array($categorylist) || !isset($categorylist['c'])) { + return array(); + } + + if (isset($categorylist['c']['_content'])) { + // only 1 category + $categorylist['c'] = array($categorylist['c']); + } + + return $categorylist['c']; + } + + /** + * List packages in a category of a REST server + * + * @param string $base base URL of the server + * @param string $category name of the category + * @param boolean $info also download full package info + * @return array of packagenames + */ + function listCategory($base, $category, $info = false, $channel = false) + { + if ($info == false) { + $url = '%s'.'c/%s/packages.xml'; + } else { + $url = '%s'.'c/%s/packagesinfo.xml'; + } + $url = sprintf($url, + $base, + urlencode($category)); + + // gives '404 Not Found' error when category doesn't exist + $packagelist = $this->_rest->retrieveData($url, false, false, $channel); + if (PEAR::isError($packagelist)) { + return $packagelist; + } + if (!is_array($packagelist)) { + return array(); + } + + if ($info == false) { + if (!isset($packagelist['p'])) { + return array(); + } + if (!is_array($packagelist['p']) || + !isset($packagelist['p'][0])) { // only 1 pkg + $packagelist = array($packagelist['p']); + } else { + $packagelist = $packagelist['p']; + } + return $packagelist; + } + + // info == true + if (!isset($packagelist['pi'])) { + return array(); + } + + if (!is_array($packagelist['pi']) || + !isset($packagelist['pi'][0])) { // only 1 pkg + $packagelist_pre = array($packagelist['pi']); + } else { + $packagelist_pre = $packagelist['pi']; + } + + $packagelist = array(); + foreach ($packagelist_pre as $i => $item) { + // compatibility with r/.xml + if (isset($item['a']['r'][0])) { + // multiple releases + $item['p']['v'] = $item['a']['r'][0]['v']; + $item['p']['st'] = $item['a']['r'][0]['s']; + } elseif (isset($item['a'])) { + // first and only release + $item['p']['v'] = $item['a']['r']['v']; + $item['p']['st'] = $item['a']['r']['s']; + } + + $packagelist[$i] = array('attribs' => $item['p']['r'], + '_content' => $item['p']['n'], + 'info' => $item['p']); + } + + return $packagelist; + } + + /** + * Return an array containing all of the states that are more stable than + * or equal to the passed in state + * + * @param string Release state + * @param boolean Determines whether to include $state in the list + * @return false|array False if $state is not a valid release state + */ + function betterStates($state, $include = false) + { + static $states = array('snapshot', 'devel', 'alpha', 'beta', 'stable'); + $i = array_search($state, $states); + if ($i === false) { + return false; + } + if ($include) { + $i--; + } + return array_slice($states, $i + 1); + } +} +?> diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/REST/13.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/REST/13.php new file mode 100644 index 0000000..3855c6e --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/REST/13.php @@ -0,0 +1,396 @@ + + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a12 + */ + +/** + * For downloading REST xml/txt files + */ +require_once 'PEAR/REST.php'; +require_once 'PEAR/REST/10.php'; + +/** + * Implement REST 1.3 + * + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a12 + */ +class PEAR_REST_13 extends PEAR_REST_10 +{ + /** + * Retrieve information about a remote package to be downloaded from a REST server + * + * This is smart enough to resolve the minimum PHP version dependency prior to download + * @param string $base The uri to prepend to all REST calls + * @param array $packageinfo an array of format: + *
    +     *  array(
    +     *   'package' => 'packagename',
    +     *   'channel' => 'channelname',
    +     *  ['state' => 'alpha' (or valid state),]
    +     *  -or-
    +     *  ['version' => '1.whatever']
    +     * 
    + * @param string $prefstate Current preferred_state config variable value + * @param bool $installed the installed version of this package to compare against + * @return array|false|PEAR_Error see {@link _returnDownloadURL()} + */ + function getDownloadURL($base, $packageinfo, $prefstate, $installed, $channel = false) + { + $states = $this->betterStates($prefstate, true); + if (!$states) { + return PEAR::raiseError('"' . $prefstate . '" is not a valid state'); + } + + $channel = $packageinfo['channel']; + $package = $packageinfo['package']; + $state = isset($packageinfo['state']) ? $packageinfo['state'] : null; + $version = isset($packageinfo['version']) ? $packageinfo['version'] : null; + $restFile = $base . 'r/' . strtolower($package) . '/allreleases2.xml'; + + $info = $this->_rest->retrieveData($restFile, false, false, $channel); + if (PEAR::isError($info)) { + return PEAR::raiseError('No releases available for package "' . + $channel . '/' . $package . '"'); + } + + if (!isset($info['r'])) { + return false; + } + + $release = $found = false; + if (!is_array($info['r']) || !isset($info['r'][0])) { + $info['r'] = array($info['r']); + } + + $skippedphp = false; + foreach ($info['r'] as $release) { + if (!isset($this->_rest->_options['force']) && ($installed && + version_compare($release['v'], $installed, '<'))) { + continue; + } + + if (isset($state)) { + // try our preferred state first + if ($release['s'] == $state) { + if (!isset($version) && version_compare($release['m'], phpversion(), '>')) { + // skip releases that require a PHP version newer than our PHP version + $skippedphp = $release; + continue; + } + $found = true; + break; + } + + // see if there is something newer and more stable + // bug #7221 + if (in_array($release['s'], $this->betterStates($state), true)) { + if (!isset($version) && version_compare($release['m'], phpversion(), '>')) { + // skip releases that require a PHP version newer than our PHP version + $skippedphp = $release; + continue; + } + $found = true; + break; + } + } elseif (isset($version)) { + if ($release['v'] == $version) { + if (!isset($this->_rest->_options['force']) && + !isset($version) && + version_compare($release['m'], phpversion(), '>')) { + // skip releases that require a PHP version newer than our PHP version + $skippedphp = $release; + continue; + } + $found = true; + break; + } + } else { + if (in_array($release['s'], $states)) { + if (version_compare($release['m'], phpversion(), '>')) { + // skip releases that require a PHP version newer than our PHP version + $skippedphp = $release; + continue; + } + $found = true; + break; + } + } + } + + if (!$found && $skippedphp) { + $found = null; + } + + return $this->_returnDownloadURL($base, $package, $release, $info, $found, $skippedphp, $channel); + } + + function getDepDownloadURL($base, $xsdversion, $dependency, $deppackage, + $prefstate = 'stable', $installed = false, $channel = false) + { + $states = $this->betterStates($prefstate, true); + if (!$states) { + return PEAR::raiseError('"' . $prefstate . '" is not a valid state'); + } + + $channel = $dependency['channel']; + $package = $dependency['name']; + $state = isset($dependency['state']) ? $dependency['state'] : null; + $version = isset($dependency['version']) ? $dependency['version'] : null; + $restFile = $base . 'r/' . strtolower($package) .'/allreleases2.xml'; + + $info = $this->_rest->retrieveData($restFile, false, false, $channel); + if (PEAR::isError($info)) { + return PEAR::raiseError('Package "' . $deppackage['channel'] . '/' . $deppackage['package'] + . '" dependency "' . $channel . '/' . $package . '" has no releases'); + } + + if (!is_array($info) || !isset($info['r'])) { + return false; + } + + $exclude = array(); + $min = $max = $recommended = false; + if ($xsdversion == '1.0') { + $pinfo['package'] = $dependency['name']; + $pinfo['channel'] = 'pear.php.net'; // this is always true - don't change this + switch ($dependency['rel']) { + case 'ge' : + $min = $dependency['version']; + break; + case 'gt' : + $min = $dependency['version']; + $exclude = array($dependency['version']); + break; + case 'eq' : + $recommended = $dependency['version']; + break; + case 'lt' : + $max = $dependency['version']; + $exclude = array($dependency['version']); + break; + case 'le' : + $max = $dependency['version']; + break; + case 'ne' : + $exclude = array($dependency['version']); + break; + } + } else { + $pinfo['package'] = $dependency['name']; + $min = isset($dependency['min']) ? $dependency['min'] : false; + $max = isset($dependency['max']) ? $dependency['max'] : false; + $recommended = isset($dependency['recommended']) ? + $dependency['recommended'] : false; + if (isset($dependency['exclude'])) { + if (!isset($dependency['exclude'][0])) { + $exclude = array($dependency['exclude']); + } + } + } + + $skippedphp = $found = $release = false; + if (!is_array($info['r']) || !isset($info['r'][0])) { + $info['r'] = array($info['r']); + } + + foreach ($info['r'] as $release) { + if (!isset($this->_rest->_options['force']) && ($installed && + version_compare($release['v'], $installed, '<'))) { + continue; + } + + if (in_array($release['v'], $exclude)) { // skip excluded versions + continue; + } + + // allow newer releases to say "I'm OK with the dependent package" + if ($xsdversion == '2.0' && isset($release['co'])) { + if (!is_array($release['co']) || !isset($release['co'][0])) { + $release['co'] = array($release['co']); + } + + foreach ($release['co'] as $entry) { + if (isset($entry['x']) && !is_array($entry['x'])) { + $entry['x'] = array($entry['x']); + } elseif (!isset($entry['x'])) { + $entry['x'] = array(); + } + + if ($entry['c'] == $deppackage['channel'] && + strtolower($entry['p']) == strtolower($deppackage['package']) && + version_compare($deppackage['version'], $entry['min'], '>=') && + version_compare($deppackage['version'], $entry['max'], '<=') && + !in_array($release['v'], $entry['x'])) { + if (version_compare($release['m'], phpversion(), '>')) { + // skip dependency releases that require a PHP version + // newer than our PHP version + $skippedphp = $release; + continue; + } + + $recommended = $release['v']; + break; + } + } + } + + if ($recommended) { + if ($release['v'] != $recommended) { // if we want a specific + // version, then skip all others + continue; + } + + if (!in_array($release['s'], $states)) { + // the stability is too low, but we must return the + // recommended version if possible + return $this->_returnDownloadURL($base, $package, $release, $info, true, false, $channel); + } + } + + if ($min && version_compare($release['v'], $min, 'lt')) { // skip too old versions + continue; + } + + if ($max && version_compare($release['v'], $max, 'gt')) { // skip too new versions + continue; + } + + if ($installed && version_compare($release['v'], $installed, '<')) { + continue; + } + + if (in_array($release['s'], $states)) { // if in the preferred state... + if (version_compare($release['m'], phpversion(), '>')) { + // skip dependency releases that require a PHP version + // newer than our PHP version + $skippedphp = $release; + continue; + } + + $found = true; // ... then use it + break; + } + } + + if (!$found && $skippedphp) { + $found = null; + } + + return $this->_returnDownloadURL($base, $package, $release, $info, $found, $skippedphp, $channel); + } + + /** + * List package upgrades but take the PHP version into account. + */ + function listLatestUpgrades($base, $pref_state, $installed, $channel, &$reg) + { + $packagelist = $this->_rest->retrieveData($base . 'p/packages.xml', false, false, $channel); + if (PEAR::isError($packagelist)) { + return $packagelist; + } + + $ret = array(); + if (!is_array($packagelist) || !isset($packagelist['p'])) { + return $ret; + } + + if (!is_array($packagelist['p'])) { + $packagelist['p'] = array($packagelist['p']); + } + + foreach ($packagelist['p'] as $package) { + if (!isset($installed[strtolower($package)])) { + continue; + } + + $inst_version = $reg->packageInfo($package, 'version', $channel); + $inst_state = $reg->packageInfo($package, 'release_state', $channel); + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $info = $this->_rest->retrieveData($base . 'r/' . strtolower($package) . + '/allreleases2.xml', false, false, $channel); + PEAR::popErrorHandling(); + if (PEAR::isError($info)) { + continue; // no remote releases + } + + if (!isset($info['r'])) { + continue; + } + + $release = $found = false; + if (!is_array($info['r']) || !isset($info['r'][0])) { + $info['r'] = array($info['r']); + } + + // $info['r'] is sorted by version number + usort($info['r'], array($this, '_sortReleasesByVersionNumber')); + foreach ($info['r'] as $release) { + if ($inst_version && version_compare($release['v'], $inst_version, '<=')) { + // not newer than the one installed + break; + } + if (version_compare($release['m'], phpversion(), '>')) { + // skip dependency releases that require a PHP version + // newer than our PHP version + continue; + } + + // new version > installed version + if (!$pref_state) { + // every state is a good state + $found = true; + break; + } else { + $new_state = $release['s']; + // if new state >= installed state: go + if (in_array($new_state, $this->betterStates($inst_state, true))) { + $found = true; + break; + } else { + // only allow to lower the state of package, + // if new state >= preferred state: go + if (in_array($new_state, $this->betterStates($pref_state, true))) { + $found = true; + break; + } + } + } + } + + if (!$found) { + continue; + } + + $relinfo = $this->_rest->retrieveCacheFirst($base . 'r/' . strtolower($package) . '/' . + $release['v'] . '.xml', false, false, $channel); + if (PEAR::isError($relinfo)) { + return $relinfo; + } + + $ret[$package] = array( + 'version' => $release['v'], + 'state' => $release['s'], + 'filesize' => $relinfo['f'], + ); + } + + return $ret; + } +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Registry.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Registry.php new file mode 100644 index 0000000..c22d82f --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Registry.php @@ -0,0 +1,2388 @@ + + * @author Tomas V. V. Cox + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 0.1 + */ + +/** + * for PEAR_Error + */ +require_once 'PEAR.php'; +require_once 'PEAR/DependencyDB.php'; + +define('PEAR_REGISTRY_ERROR_LOCK', -2); +define('PEAR_REGISTRY_ERROR_FORMAT', -3); +define('PEAR_REGISTRY_ERROR_FILE', -4); +define('PEAR_REGISTRY_ERROR_CONFLICT', -5); +define('PEAR_REGISTRY_ERROR_CHANNEL_FILE', -6); + +/** + * Administration class used to maintain the installed package database. + * @category pear + * @package PEAR + * @author Stig Bakken + * @author Tomas V. V. Cox + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Registry extends PEAR +{ + /** + * File containing all channel information. + * @var string + */ + var $channels = ''; + + /** Directory where registry files are stored. + * @var string + */ + var $statedir = ''; + + /** File where the file map is stored + * @var string + */ + var $filemap = ''; + + /** Directory where registry files for channels are stored. + * @var string + */ + var $channelsdir = ''; + + /** Name of file used for locking the registry + * @var string + */ + var $lockfile = ''; + + /** File descriptor used during locking + * @var resource + */ + var $lock_fp = null; + + /** Mode used during locking + * @var int + */ + var $lock_mode = 0; // XXX UNUSED + + /** Cache of package information. Structure: + * array( + * 'package' => array('id' => ... ), + * ... ) + * @var array + */ + var $pkginfo_cache = array(); + + /** Cache of file map. Structure: + * array( '/path/to/file' => 'package', ... ) + * @var array + */ + var $filemap_cache = array(); + + /** + * @var false|PEAR_ChannelFile + */ + var $_pearChannel; + + /** + * @var false|PEAR_ChannelFile + */ + var $_peclChannel; + + /** + * @var false|PEAR_ChannelFile + */ + var $_docChannel; + + /** + * @var PEAR_DependencyDB + */ + var $_dependencyDB; + + /** + * @var PEAR_Config + */ + var $_config; + + /** + * PEAR_Registry constructor. + * + * @param string (optional) PEAR install directory (for .php files) + * @param PEAR_ChannelFile PEAR_ChannelFile object representing the PEAR channel, if + * default values are not desired. Only used the very first time a PEAR + * repository is initialized + * @param PEAR_ChannelFile PEAR_ChannelFile object representing the PECL channel, if + * default values are not desired. Only used the very first time a PEAR + * repository is initialized + * + * @access public + */ + function __construct($pear_install_dir = PEAR_INSTALL_DIR, $pear_channel = false, + $pecl_channel = false, $pear_metadata_dir = '') + { + parent::__construct(); + $this->setInstallDir($pear_install_dir, $pear_metadata_dir); + $this->_pearChannel = $pear_channel; + $this->_peclChannel = $pecl_channel; + $this->_config = false; + } + + function setInstallDir($pear_install_dir = PEAR_INSTALL_DIR, $pear_metadata_dir = '') + { + $ds = DIRECTORY_SEPARATOR; + $this->install_dir = $pear_install_dir; + if (!$pear_metadata_dir) { + $pear_metadata_dir = $pear_install_dir; + } + $this->channelsdir = $pear_metadata_dir.$ds.'.channels'; + $this->statedir = $pear_metadata_dir.$ds.'.registry'; + $this->filemap = $pear_metadata_dir.$ds.'.filemap'; + $this->lockfile = $pear_metadata_dir.$ds.'.lock'; + } + + function hasWriteAccess() + { + if (!file_exists($this->install_dir)) { + $dir = $this->install_dir; + while ($dir && $dir != '.') { + $olddir = $dir; + $dir = dirname($dir); + if ($dir != '.' && file_exists($dir)) { + if (is_writeable($dir)) { + return true; + } + + return false; + } + + if ($dir == $olddir) { // this can happen in safe mode + return @is_writable($dir); + } + } + + return false; + } + + return is_writeable($this->install_dir); + } + + function setConfig(&$config, $resetInstallDir = true) + { + $this->_config = &$config; + if ($resetInstallDir) { + $this->setInstallDir($config->get('php_dir'), $config->get('metadata_dir')); + } + } + + function _initializeChannelDirs() + { + static $running = false; + if (!$running) { + $running = true; + $ds = DIRECTORY_SEPARATOR; + if (!is_dir($this->channelsdir) || + !file_exists($this->channelsdir . $ds . 'pear.php.net.reg') || + !file_exists($this->channelsdir . $ds . 'pecl.php.net.reg') || + !file_exists($this->channelsdir . $ds . 'doc.php.net.reg') || + !file_exists($this->channelsdir . $ds . '__uri.reg')) { + if (!file_exists($this->channelsdir . $ds . 'pear.php.net.reg')) { + $pear_channel = $this->_pearChannel; + if (!is_a($pear_channel, 'PEAR_ChannelFile') || !$pear_channel->validate()) { + if (!class_exists('PEAR_ChannelFile')) { + require_once 'PEAR/ChannelFile.php'; + } + + $pear_channel = new PEAR_ChannelFile; + $pear_channel->setAlias('pear'); + $pear_channel->setServer('pear.php.net'); + $pear_channel->setSummary('PHP Extension and Application Repository'); + $pear_channel->setDefaultPEARProtocols(); + $pear_channel->setBaseURL('REST1.0', 'http://pear.php.net/rest/'); + $pear_channel->setBaseURL('REST1.1', 'http://pear.php.net/rest/'); + $pear_channel->setBaseURL('REST1.3', 'http://pear.php.net/rest/'); + //$pear_channel->setBaseURL('REST1.4', 'http://pear.php.net/rest/'); + } else { + $pear_channel->setServer('pear.php.net'); + $pear_channel->setAlias('pear'); + } + + $pear_channel->validate(); + $this->_addChannel($pear_channel); + } + + if (!file_exists($this->channelsdir . $ds . 'pecl.php.net.reg')) { + $pecl_channel = $this->_peclChannel; + if (!is_a($pecl_channel, 'PEAR_ChannelFile') || !$pecl_channel->validate()) { + if (!class_exists('PEAR_ChannelFile')) { + require_once 'PEAR/ChannelFile.php'; + } + + $pecl_channel = new PEAR_ChannelFile; + $pecl_channel->setAlias('pecl'); + $pecl_channel->setServer('pecl.php.net'); + $pecl_channel->setSummary('PHP Extension Community Library'); + $pecl_channel->setDefaultPEARProtocols(); + $pecl_channel->setBaseURL('REST1.0', 'http://pecl.php.net/rest/'); + $pecl_channel->setBaseURL('REST1.1', 'http://pecl.php.net/rest/'); + $pecl_channel->setValidationPackage('PEAR_Validator_PECL', '1.0'); + } else { + $pecl_channel->setServer('pecl.php.net'); + $pecl_channel->setAlias('pecl'); + } + + $pecl_channel->validate(); + $this->_addChannel($pecl_channel); + } + + if (!file_exists($this->channelsdir . $ds . 'doc.php.net.reg')) { + $doc_channel = $this->_docChannel; + if (!is_a($doc_channel, 'PEAR_ChannelFile') || !$doc_channel->validate()) { + if (!class_exists('PEAR_ChannelFile')) { + require_once 'PEAR/ChannelFile.php'; + } + + $doc_channel = new PEAR_ChannelFile; + $doc_channel->setAlias('phpdocs'); + $doc_channel->setServer('doc.php.net'); + $doc_channel->setSummary('PHP Documentation Team'); + $doc_channel->setDefaultPEARProtocols(); + $doc_channel->setBaseURL('REST1.0', 'http://doc.php.net/rest/'); + $doc_channel->setBaseURL('REST1.1', 'http://doc.php.net/rest/'); + $doc_channel->setBaseURL('REST1.3', 'http://doc.php.net/rest/'); + } else { + $doc_channel->setServer('doc.php.net'); + $doc_channel->setAlias('doc'); + } + + $doc_channel->validate(); + $this->_addChannel($doc_channel); + } + + if (!file_exists($this->channelsdir . $ds . '__uri.reg')) { + if (!class_exists('PEAR_ChannelFile')) { + require_once 'PEAR/ChannelFile.php'; + } + + $private = new PEAR_ChannelFile; + $private->setName('__uri'); + $private->setDefaultPEARProtocols(); + $private->setBaseURL('REST1.0', '****'); + $private->setSummary('Pseudo-channel for static packages'); + $this->_addChannel($private); + } + $this->_rebuildFileMap(); + } + + $running = false; + } + } + + function _initializeDirs() + { + $ds = DIRECTORY_SEPARATOR; + // XXX Compatibility code should be removed in the future + // rename all registry files if any to lowercase + if (!OS_WINDOWS && file_exists($this->statedir) && is_dir($this->statedir) && + $handle = opendir($this->statedir)) { + $dest = $this->statedir . $ds; + while (false !== ($file = readdir($handle))) { + if (preg_match('/^.*[A-Z].*\.reg\\z/', $file)) { + rename($dest . $file, $dest . strtolower($file)); + } + } + closedir($handle); + } + + $this->_initializeChannelDirs(); + if (!file_exists($this->filemap)) { + $this->_rebuildFileMap(); + } + $this->_initializeDepDB(); + } + + function _initializeDepDB() + { + if (!isset($this->_dependencyDB)) { + static $initializing = false; + if (!$initializing) { + $initializing = true; + if (!$this->_config) { // never used? + $file = OS_WINDOWS ? 'pear.ini' : '.pearrc'; + $this->_config = new PEAR_Config($this->statedir . DIRECTORY_SEPARATOR . + $file); + $this->_config->setRegistry($this); + $this->_config->set('php_dir', $this->install_dir); + } + + $this->_dependencyDB = &PEAR_DependencyDB::singleton($this->_config); + if (PEAR::isError($this->_dependencyDB)) { + // attempt to recover by removing the dep db + if (file_exists($this->_config->get('metadata_dir', null, 'pear.php.net') . + DIRECTORY_SEPARATOR . '.depdb')) { + @unlink($this->_config->get('metadata_dir', null, 'pear.php.net') . + DIRECTORY_SEPARATOR . '.depdb'); + } + + $this->_dependencyDB = &PEAR_DependencyDB::singleton($this->_config); + if (PEAR::isError($this->_dependencyDB)) { + echo $this->_dependencyDB->getMessage(); + echo 'Unrecoverable error'; + exit(1); + } + } + + $initializing = false; + } + } + } + + /** + * PEAR_Registry destructor. Makes sure no locks are forgotten. + * + * @access private + */ + function _PEAR_Registry() + { + parent::_PEAR(); + if (is_resource($this->lock_fp)) { + $this->_unlock(); + } + } + + /** + * Make sure the directory where we keep registry files exists. + * + * @return bool TRUE if directory exists, FALSE if it could not be + * created + * + * @access private + */ + function _assertStateDir($channel = false) + { + if ($channel && $this->_getChannelFromAlias($channel) != 'pear.php.net') { + return $this->_assertChannelStateDir($channel); + } + + static $init = false; + if (!file_exists($this->statedir)) { + if (!$this->hasWriteAccess()) { + return false; + } + + require_once 'System.php'; + if (!System::mkdir(array('-p', $this->statedir))) { + return $this->raiseError("could not create directory '{$this->statedir}'"); + } + $init = true; + } elseif (!is_dir($this->statedir)) { + return $this->raiseError('Cannot create directory ' . $this->statedir . ', ' . + 'it already exists and is not a directory'); + } + + $ds = DIRECTORY_SEPARATOR; + if (!file_exists($this->channelsdir)) { + if (!file_exists($this->channelsdir . $ds . 'pear.php.net.reg') || + !file_exists($this->channelsdir . $ds . 'pecl.php.net.reg') || + !file_exists($this->channelsdir . $ds . 'doc.php.net.reg') || + !file_exists($this->channelsdir . $ds . '__uri.reg')) { + $init = true; + } + } elseif (!is_dir($this->channelsdir)) { + return $this->raiseError('Cannot create directory ' . $this->channelsdir . ', ' . + 'it already exists and is not a directory'); + } + + if ($init) { + static $running = false; + if (!$running) { + $running = true; + $this->_initializeDirs(); + $running = false; + $init = false; + } + } else { + $this->_initializeDepDB(); + } + + return true; + } + + /** + * Make sure the directory where we keep registry files exists for a non-standard channel. + * + * @param string channel name + * @return bool TRUE if directory exists, FALSE if it could not be + * created + * + * @access private + */ + function _assertChannelStateDir($channel) + { + $ds = DIRECTORY_SEPARATOR; + if (!$channel || $this->_getChannelFromAlias($channel) == 'pear.php.net') { + if (!file_exists($this->channelsdir . $ds . 'pear.php.net.reg')) { + $this->_initializeChannelDirs(); + } + return $this->_assertStateDir($channel); + } + + $channelDir = $this->_channelDirectoryName($channel); + if (!is_dir($this->channelsdir) || + !file_exists($this->channelsdir . $ds . 'pear.php.net.reg')) { + $this->_initializeChannelDirs(); + } + + if (!file_exists($channelDir)) { + if (!$this->hasWriteAccess()) { + return false; + } + + require_once 'System.php'; + if (!System::mkdir(array('-p', $channelDir))) { + return $this->raiseError("could not create directory '" . $channelDir . + "'"); + } + } elseif (!is_dir($channelDir)) { + return $this->raiseError("could not create directory '" . $channelDir . + "', already exists and is not a directory"); + } + + return true; + } + + /** + * Make sure the directory where we keep registry files for channels exists + * + * @return bool TRUE if directory exists, FALSE if it could not be + * created + * + * @access private + */ + function _assertChannelDir() + { + if (!file_exists($this->channelsdir)) { + if (!$this->hasWriteAccess()) { + return false; + } + + require_once 'System.php'; + if (!System::mkdir(array('-p', $this->channelsdir))) { + return $this->raiseError("could not create directory '{$this->channelsdir}'"); + } + } elseif (!is_dir($this->channelsdir)) { + return $this->raiseError("could not create directory '{$this->channelsdir}" . + "', it already exists and is not a directory"); + } + + if (!file_exists($this->channelsdir . DIRECTORY_SEPARATOR . '.alias')) { + if (!$this->hasWriteAccess()) { + return false; + } + + require_once 'System.php'; + if (!System::mkdir(array('-p', $this->channelsdir . DIRECTORY_SEPARATOR . '.alias'))) { + return $this->raiseError("could not create directory '{$this->channelsdir}/.alias'"); + } + } elseif (!is_dir($this->channelsdir . DIRECTORY_SEPARATOR . '.alias')) { + return $this->raiseError("could not create directory '{$this->channelsdir}" . + "/.alias', it already exists and is not a directory"); + } + + return true; + } + + /** + * Get the name of the file where data for a given package is stored. + * + * @param string channel name, or false if this is a PEAR package + * @param string package name + * + * @return string registry file name + * + * @access public + */ + function _packageFileName($package, $channel = false) + { + if ($channel && $this->_getChannelFromAlias($channel) != 'pear.php.net') { + return $this->_channelDirectoryName($channel) . DIRECTORY_SEPARATOR . + strtolower($package) . '.reg'; + } + + return $this->statedir . DIRECTORY_SEPARATOR . strtolower($package) . '.reg'; + } + + /** + * Get the name of the file where data for a given channel is stored. + * @param string channel name + * @return string registry file name + */ + function _channelFileName($channel, $noaliases = false) + { + if (!$noaliases) { + if (file_exists($this->_getChannelAliasFileName($channel))) { + $channel = implode('', file($this->_getChannelAliasFileName($channel))); + } + } + return $this->channelsdir . DIRECTORY_SEPARATOR . str_replace('/', '_', + strtolower($channel)) . '.reg'; + } + + /** + * @param string + * @return string + */ + function _getChannelAliasFileName($alias) + { + return $this->channelsdir . DIRECTORY_SEPARATOR . '.alias' . + DIRECTORY_SEPARATOR . str_replace('/', '_', strtolower($alias)) . '.txt'; + } + + /** + * Get the name of a channel from its alias + */ + function _getChannelFromAlias($channel) + { + if (!$this->_channelExists($channel)) { + if ($channel == 'pear.php.net') { + return 'pear.php.net'; + } + + if ($channel == 'pecl.php.net') { + return 'pecl.php.net'; + } + + if ($channel == 'doc.php.net') { + return 'doc.php.net'; + } + + if ($channel == '__uri') { + return '__uri'; + } + + return false; + } + + $channel = strtolower($channel); + if (file_exists($this->_getChannelAliasFileName($channel))) { + // translate an alias to an actual channel + return implode('', file($this->_getChannelAliasFileName($channel))); + } + + return $channel; + } + + /** + * Get the alias of a channel from its alias or its name + */ + function _getAlias($channel) + { + if (!$this->_channelExists($channel)) { + if ($channel == 'pear.php.net') { + return 'pear'; + } + + if ($channel == 'pecl.php.net') { + return 'pecl'; + } + + if ($channel == 'doc.php.net') { + return 'phpdocs'; + } + + return false; + } + + $channel = $this->_getChannel($channel); + if (PEAR::isError($channel)) { + return $channel; + } + + return $channel->getAlias(); + } + + /** + * Get the name of the file where data for a given package is stored. + * + * @param string channel name, or false if this is a PEAR package + * @param string package name + * + * @return string registry file name + * + * @access public + */ + function _channelDirectoryName($channel) + { + if (!$channel || $this->_getChannelFromAlias($channel) == 'pear.php.net') { + return $this->statedir; + } + + $ch = $this->_getChannelFromAlias($channel); + if (!$ch) { + $ch = $channel; + } + + return $this->statedir . DIRECTORY_SEPARATOR . strtolower('.channel.' . + str_replace('/', '_', $ch)); + } + + function _openPackageFile($package, $mode, $channel = false) + { + if (!$this->_assertStateDir($channel)) { + return null; + } + + if (!in_array($mode, array('r', 'rb')) && !$this->hasWriteAccess()) { + return null; + } + + $file = $this->_packageFileName($package, $channel); + if (!file_exists($file) && $mode == 'r' || $mode == 'rb') { + return null; + } + + $fp = @fopen($file, $mode); + if (!$fp) { + return null; + } + + return $fp; + } + + function _closePackageFile($fp) + { + fclose($fp); + } + + function _openChannelFile($channel, $mode) + { + if (!$this->_assertChannelDir()) { + return null; + } + + if (!in_array($mode, array('r', 'rb')) && !$this->hasWriteAccess()) { + return null; + } + + $file = $this->_channelFileName($channel); + if (!file_exists($file) && $mode == 'r' || $mode == 'rb') { + return null; + } + + $fp = @fopen($file, $mode); + if (!$fp) { + return null; + } + + return $fp; + } + + function _closeChannelFile($fp) + { + fclose($fp); + } + + function _rebuildFileMap() + { + if (!class_exists('PEAR_Installer_Role')) { + require_once 'PEAR/Installer/Role.php'; + } + + $channels = $this->_listAllPackages(); + $files = array(); + foreach ($channels as $channel => $packages) { + foreach ($packages as $package) { + $version = $this->_packageInfo($package, 'version', $channel); + $filelist = $this->_packageInfo($package, 'filelist', $channel); + if (!is_array($filelist)) { + continue; + } + + foreach ($filelist as $name => $attrs) { + if (isset($attrs['attribs'])) { + $attrs = $attrs['attribs']; + } + + // it is possible for conflicting packages in different channels to + // conflict with data files/doc files + if ($name == 'dirtree') { + continue; + } + + if (isset($attrs['role']) && !in_array($attrs['role'], + PEAR_Installer_Role::getInstallableRoles())) { + // these are not installed + continue; + } + + if (isset($attrs['role']) && !in_array($attrs['role'], + PEAR_Installer_Role::getBaseinstallRoles())) { + $attrs['baseinstalldir'] = $package; + } + + if (isset($attrs['baseinstalldir'])) { + $file = $attrs['baseinstalldir'].DIRECTORY_SEPARATOR.$name; + } else { + $file = $name; + } + + $file = preg_replace(',^/+,', '', $file); + if ($channel != 'pear.php.net') { + if (!isset($files[$attrs['role']])) { + $files[$attrs['role']] = array(); + } + $files[$attrs['role']][$file] = array(strtolower($channel), + strtolower($package)); + } else { + if (!isset($files[$attrs['role']])) { + $files[$attrs['role']] = array(); + } + $files[$attrs['role']][$file] = strtolower($package); + } + } + } + } + + + $this->_assertStateDir(); + if (!$this->hasWriteAccess()) { + return false; + } + + $fp = @fopen($this->filemap, 'wb'); + if (!$fp) { + return false; + } + + $this->filemap_cache = $files; + fwrite($fp, serialize($files)); + fclose($fp); + return true; + } + + function _readFileMap() + { + if (!file_exists($this->filemap)) { + return array(); + } + + $fp = @fopen($this->filemap, 'r'); + if (!$fp) { + return $this->raiseError('PEAR_Registry: could not open filemap "' . $this->filemap . '"', PEAR_REGISTRY_ERROR_FILE, null, null, $php_errormsg); + } + + clearstatcache(); + $fsize = filesize($this->filemap); + fclose($fp); + $data = file_get_contents($this->filemap); + $tmp = unserialize($data); + if (!$tmp && $fsize > 7) { + return $this->raiseError('PEAR_Registry: invalid filemap data', PEAR_REGISTRY_ERROR_FORMAT, null, null, $data); + } + + $this->filemap_cache = $tmp; + return true; + } + + /** + * Lock the registry. + * + * @param integer lock mode, one of LOCK_EX, LOCK_SH or LOCK_UN. + * See flock manual for more information. + * + * @return bool TRUE on success, FALSE if locking failed, or a + * PEAR error if some other error occurs (such as the + * lock file not being writable). + * + * @access private + */ + function _lock($mode = LOCK_EX) + { + if (stristr(php_uname(), 'Windows 9')) { + return true; + } + + if ($mode != LOCK_UN && is_resource($this->lock_fp)) { + // XXX does not check type of lock (LOCK_SH/LOCK_EX) + return true; + } + + if (!$this->_assertStateDir()) { + if ($mode == LOCK_EX) { + return $this->raiseError('Registry directory is not writeable by the current user'); + } + + return true; + } + + $open_mode = 'w'; + // XXX People reported problems with LOCK_SH and 'w' + if ($mode === LOCK_SH || $mode === LOCK_UN) { + if (!file_exists($this->lockfile)) { + touch($this->lockfile); + } + $open_mode = 'r'; + } + + if (!is_resource($this->lock_fp)) { + $this->lock_fp = @fopen($this->lockfile, $open_mode); + } + + if (!is_resource($this->lock_fp)) { + $this->lock_fp = null; + return $this->raiseError("could not create lock file" . + (isset($php_errormsg) ? ": " . $php_errormsg : "")); + } + + if (!(int)flock($this->lock_fp, $mode)) { + switch ($mode) { + case LOCK_SH: $str = 'shared'; break; + case LOCK_EX: $str = 'exclusive'; break; + case LOCK_UN: $str = 'unlock'; break; + default: $str = 'unknown'; break; + } + + //is resource at this point, close it on error. + fclose($this->lock_fp); + $this->lock_fp = null; + return $this->raiseError("could not acquire $str lock ($this->lockfile)", + PEAR_REGISTRY_ERROR_LOCK); + } + + return true; + } + + function _unlock() + { + $ret = $this->_lock(LOCK_UN); + if (is_resource($this->lock_fp)) { + fclose($this->lock_fp); + } + + $this->lock_fp = null; + return $ret; + } + + function _packageExists($package, $channel = false) + { + return file_exists($this->_packageFileName($package, $channel)); + } + + /** + * Determine whether a channel exists in the registry + * + * @param string Channel name + * @param bool if true, then aliases will be ignored + * @return boolean + */ + function _channelExists($channel, $noaliases = false) + { + $a = file_exists($this->_channelFileName($channel, $noaliases)); + if (!$a && $channel == 'pear.php.net') { + return true; + } + + if (!$a && $channel == 'pecl.php.net') { + return true; + } + + if (!$a && $channel == 'doc.php.net') { + return true; + } + + return $a; + } + + /** + * Determine whether a mirror exists within the deafult channel in the registry + * + * @param string Channel name + * @param string Mirror name + * + * @return boolean + */ + function _mirrorExists($channel, $mirror) + { + $data = $this->_channelInfo($channel); + if (!isset($data['servers']['mirror'])) { + return false; + } + + foreach ($data['servers']['mirror'] as $m) { + if ($m['attribs']['host'] == $mirror) { + return true; + } + } + + return false; + } + + /** + * @param PEAR_ChannelFile Channel object + * @param donotuse + * @param string Last-Modified HTTP tag from remote request + * @return boolean|PEAR_Error True on creation, false if it already exists + */ + function _addChannel($channel, $update = false, $lastmodified = false) + { + if (!is_a($channel, 'PEAR_ChannelFile')) { + return false; + } + + if (!$channel->validate()) { + return false; + } + + if (file_exists($this->_channelFileName($channel->getName()))) { + if (!$update) { + return false; + } + + $checker = $this->_getChannel($channel->getName()); + if (PEAR::isError($checker)) { + return $checker; + } + + if ($channel->getAlias() != $checker->getAlias()) { + if (file_exists($this->_getChannelAliasFileName($checker->getAlias()))) { + @unlink($this->_getChannelAliasFileName($checker->getAlias())); + } + } + } else { + if ($update && !in_array($channel->getName(), array('pear.php.net', 'pecl.php.net', 'doc.php.net'))) { + return false; + } + } + + $ret = $this->_assertChannelDir(); + if (PEAR::isError($ret)) { + return $ret; + } + + $ret = $this->_assertChannelStateDir($channel->getName()); + if (PEAR::isError($ret)) { + return $ret; + } + + if ($channel->getAlias() != $channel->getName()) { + if (file_exists($this->_getChannelAliasFileName($channel->getAlias())) && + $this->_getChannelFromAlias($channel->getAlias()) != $channel->getName()) { + $channel->setAlias($channel->getName()); + } + + if (!$this->hasWriteAccess()) { + return false; + } + + $fp = @fopen($this->_getChannelAliasFileName($channel->getAlias()), 'w'); + if (!$fp) { + return false; + } + + fwrite($fp, $channel->getName()); + fclose($fp); + } + + if (!$this->hasWriteAccess()) { + return false; + } + + $fp = @fopen($this->_channelFileName($channel->getName()), 'wb'); + if (!$fp) { + return false; + } + + $info = $channel->toArray(); + if ($lastmodified) { + $info['_lastmodified'] = $lastmodified; + } else { + $info['_lastmodified'] = date('r'); + } + + fwrite($fp, serialize($info)); + fclose($fp); + return true; + } + + /** + * Deletion fails if there are any packages installed from the channel + * @param string|PEAR_ChannelFile channel name + * @return boolean|PEAR_Error True on deletion, false if it doesn't exist + */ + function _deleteChannel($channel) + { + if (!is_string($channel)) { + if (!is_a($channel, 'PEAR_ChannelFile')) { + return false; + } + + if (!$channel->validate()) { + return false; + } + $channel = $channel->getName(); + } + + if ($this->_getChannelFromAlias($channel) == '__uri') { + return false; + } + + if ($this->_getChannelFromAlias($channel) == 'pecl.php.net') { + return false; + } + + if ($this->_getChannelFromAlias($channel) == 'doc.php.net') { + return false; + } + + if (!$this->_channelExists($channel)) { + return false; + } + + if (!$channel || $this->_getChannelFromAlias($channel) == 'pear.php.net') { + return false; + } + + $channel = $this->_getChannelFromAlias($channel); + if ($channel == 'pear.php.net') { + return false; + } + + $test = $this->_listChannelPackages($channel); + if (count($test)) { + return false; + } + + $test = @rmdir($this->_channelDirectoryName($channel)); + if (!$test) { + return false; + } + + $file = $this->_getChannelAliasFileName($this->_getAlias($channel)); + if (file_exists($file)) { + $test = @unlink($file); + if (!$test) { + return false; + } + } + + $file = $this->_channelFileName($channel); + $ret = true; + if (file_exists($file)) { + $ret = @unlink($file); + } + + return $ret; + } + + /** + * Determine whether a channel exists in the registry + * @param string Channel Alias + * @return boolean + */ + function _isChannelAlias($alias) + { + return file_exists($this->_getChannelAliasFileName($alias)); + } + + /** + * @param string|null + * @param string|null + * @param string|null + * @return array|null + * @access private + */ + function _packageInfo($package = null, $key = null, $channel = 'pear.php.net') + { + if ($package === null) { + if ($channel === null) { + $channels = $this->_listChannels(); + $ret = array(); + foreach ($channels as $channel) { + $channel = strtolower($channel); + $ret[$channel] = array(); + $packages = $this->_listPackages($channel); + foreach ($packages as $package) { + $ret[$channel][] = $this->_packageInfo($package, null, $channel); + } + } + + return $ret; + } + + $ps = $this->_listPackages($channel); + if (!count($ps)) { + return array(); + } + return array_map(array(&$this, '_packageInfo'), + $ps, array_fill(0, count($ps), null), + array_fill(0, count($ps), $channel)); + } + + $fp = $this->_openPackageFile($package, 'r', $channel); + if ($fp === null) { + return null; + } + + clearstatcache(); + $this->_closePackageFile($fp); + $data = file_get_contents($this->_packageFileName($package, $channel)); + $data = unserialize($data); + if ($key === null) { + return $data; + } + + // compatibility for package.xml version 2.0 + if (isset($data['old'][$key])) { + return $data['old'][$key]; + } + + if (isset($data[$key])) { + return $data[$key]; + } + + return null; + } + + /** + * @param string Channel name + * @param bool whether to strictly retrieve info of channels, not just aliases + * @return array|null + */ + function _channelInfo($channel, $noaliases = false) + { + if (!$this->_channelExists($channel, $noaliases)) { + return null; + } + + $fp = $this->_openChannelFile($channel, 'r'); + if ($fp === null) { + return null; + } + + clearstatcache(); + $this->_closeChannelFile($fp); + $data = file_get_contents($this->_channelFileName($channel)); + $data = unserialize($data); + return $data; + } + + function _listChannels() + { + $channellist = array(); + if (!file_exists($this->channelsdir) || !is_dir($this->channelsdir)) { + return array('pear.php.net', 'pecl.php.net', 'doc.php.net', '__uri'); + } + + $dp = opendir($this->channelsdir); + while ($ent = readdir($dp)) { + if ($ent{0} == '.' || substr($ent, -4) != '.reg') { + continue; + } + + if ($ent == '__uri.reg') { + $channellist[] = '__uri'; + continue; + } + + $channellist[] = str_replace('_', '/', substr($ent, 0, -4)); + } + + closedir($dp); + if (!in_array('pear.php.net', $channellist)) { + $channellist[] = 'pear.php.net'; + } + + if (!in_array('pecl.php.net', $channellist)) { + $channellist[] = 'pecl.php.net'; + } + + if (!in_array('doc.php.net', $channellist)) { + $channellist[] = 'doc.php.net'; + } + + + if (!in_array('__uri', $channellist)) { + $channellist[] = '__uri'; + } + + natsort($channellist); + return $channellist; + } + + function _listPackages($channel = false) + { + if ($channel && $this->_getChannelFromAlias($channel) != 'pear.php.net') { + return $this->_listChannelPackages($channel); + } + + if (!file_exists($this->statedir) || !is_dir($this->statedir)) { + return array(); + } + + $pkglist = array(); + $dp = opendir($this->statedir); + if (!$dp) { + return $pkglist; + } + + while ($ent = readdir($dp)) { + if ($ent{0} == '.' || substr($ent, -4) != '.reg') { + continue; + } + + $pkglist[] = substr($ent, 0, -4); + } + closedir($dp); + return $pkglist; + } + + function _listChannelPackages($channel) + { + $pkglist = array(); + if (!file_exists($this->_channelDirectoryName($channel)) || + !is_dir($this->_channelDirectoryName($channel))) { + return array(); + } + + $dp = opendir($this->_channelDirectoryName($channel)); + if (!$dp) { + return $pkglist; + } + + while ($ent = readdir($dp)) { + if ($ent{0} == '.' || substr($ent, -4) != '.reg') { + continue; + } + $pkglist[] = substr($ent, 0, -4); + } + + closedir($dp); + return $pkglist; + } + + function _listAllPackages() + { + $ret = array(); + foreach ($this->_listChannels() as $channel) { + $ret[$channel] = $this->_listPackages($channel); + } + + return $ret; + } + + /** + * Add an installed package to the registry + * @param string package name + * @param array package info (parsed by PEAR_Common::infoFrom*() methods) + * @return bool success of saving + * @access private + */ + function _addPackage($package, $info) + { + if ($this->_packageExists($package)) { + return false; + } + + $fp = $this->_openPackageFile($package, 'wb'); + if ($fp === null) { + return false; + } + + $info['_lastmodified'] = time(); + fwrite($fp, serialize($info)); + $this->_closePackageFile($fp); + if (isset($info['filelist'])) { + $this->_rebuildFileMap(); + } + + return true; + } + + /** + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * @return bool + * @access private + */ + function _addPackage2($info) + { + if (!is_a($info, 'PEAR_PackageFile_v1') && !is_a($info, 'PEAR_PackageFile_v2')) { + return false; + } + + if (!$info->validate()) { + if (class_exists('PEAR_Common')) { + $ui = PEAR_Frontend::singleton(); + if ($ui) { + foreach ($info->getValidationWarnings() as $err) { + $ui->log($err['message'], true); + } + } + } + return false; + } + + $channel = $info->getChannel(); + $package = $info->getPackage(); + $save = $info; + if ($this->_packageExists($package, $channel)) { + return false; + } + + if (!$this->_channelExists($channel, true)) { + return false; + } + + $info = $info->toArray(true); + if (!$info) { + return false; + } + + $fp = $this->_openPackageFile($package, 'wb', $channel); + if ($fp === null) { + return false; + } + + $info['_lastmodified'] = time(); + fwrite($fp, serialize($info)); + $this->_closePackageFile($fp); + $this->_rebuildFileMap(); + return true; + } + + /** + * @param string Package name + * @param array parsed package.xml 1.0 + * @param bool this parameter is only here for BC. Don't use it. + * @access private + */ + function _updatePackage($package, $info, $merge = true) + { + $oldinfo = $this->_packageInfo($package); + if (empty($oldinfo)) { + return false; + } + + $fp = $this->_openPackageFile($package, 'w'); + if ($fp === null) { + return false; + } + + if (is_object($info)) { + $info = $info->toArray(); + } + $info['_lastmodified'] = time(); + + $newinfo = $info; + if ($merge) { + $info = array_merge($oldinfo, $info); + } else { + $diff = $info; + } + + fwrite($fp, serialize($info)); + $this->_closePackageFile($fp); + if (isset($newinfo['filelist'])) { + $this->_rebuildFileMap(); + } + + return true; + } + + /** + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * @return bool + * @access private + */ + function _updatePackage2($info) + { + if (!$this->_packageExists($info->getPackage(), $info->getChannel())) { + return false; + } + + $fp = $this->_openPackageFile($info->getPackage(), 'w', $info->getChannel()); + if ($fp === null) { + return false; + } + + $save = $info; + $info = $save->getArray(true); + $info['_lastmodified'] = time(); + fwrite($fp, serialize($info)); + $this->_closePackageFile($fp); + $this->_rebuildFileMap(); + return true; + } + + /** + * @param string Package name + * @param string Channel name + * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2|null + * @access private + */ + function &_getPackage($package, $channel = 'pear.php.net') + { + $info = $this->_packageInfo($package, null, $channel); + if ($info === null) { + return $info; + } + + $a = $this->_config; + if (!$a) { + $this->_config = new PEAR_Config; + $this->_config->set('php_dir', $this->statedir); + } + + if (!class_exists('PEAR_PackageFile')) { + require_once 'PEAR/PackageFile.php'; + } + + $pkg = new PEAR_PackageFile($this->_config); + $pf = &$pkg->fromArray($info); + return $pf; + } + + /** + * @param string channel name + * @param bool whether to strictly retrieve channel names + * @return PEAR_ChannelFile|PEAR_Error + * @access private + */ + function &_getChannel($channel, $noaliases = false) + { + $ch = false; + if ($this->_channelExists($channel, $noaliases)) { + $chinfo = $this->_channelInfo($channel, $noaliases); + if ($chinfo) { + if (!class_exists('PEAR_ChannelFile')) { + require_once 'PEAR/ChannelFile.php'; + } + + $ch = &PEAR_ChannelFile::fromArrayWithErrors($chinfo); + } + } + + if ($ch) { + if ($ch->validate()) { + return $ch; + } + + foreach ($ch->getErrors(true) as $err) { + $message = $err['message'] . "\n"; + } + + $ch = PEAR::raiseError($message); + return $ch; + } + + if ($this->_getChannelFromAlias($channel) == 'pear.php.net') { + // the registry is not properly set up, so use defaults + if (!class_exists('PEAR_ChannelFile')) { + require_once 'PEAR/ChannelFile.php'; + } + + $pear_channel = new PEAR_ChannelFile; + $pear_channel->setServer('pear.php.net'); + $pear_channel->setAlias('pear'); + $pear_channel->setSummary('PHP Extension and Application Repository'); + $pear_channel->setDefaultPEARProtocols(); + $pear_channel->setBaseURL('REST1.0', 'http://pear.php.net/rest/'); + $pear_channel->setBaseURL('REST1.1', 'http://pear.php.net/rest/'); + $pear_channel->setBaseURL('REST1.3', 'http://pear.php.net/rest/'); + return $pear_channel; + } + + if ($this->_getChannelFromAlias($channel) == 'pecl.php.net') { + // the registry is not properly set up, so use defaults + if (!class_exists('PEAR_ChannelFile')) { + require_once 'PEAR/ChannelFile.php'; + } + $pear_channel = new PEAR_ChannelFile; + $pear_channel->setServer('pecl.php.net'); + $pear_channel->setAlias('pecl'); + $pear_channel->setSummary('PHP Extension Community Library'); + $pear_channel->setDefaultPEARProtocols(); + $pear_channel->setBaseURL('REST1.0', 'http://pecl.php.net/rest/'); + $pear_channel->setBaseURL('REST1.1', 'http://pecl.php.net/rest/'); + $pear_channel->setValidationPackage('PEAR_Validator_PECL', '1.0'); + return $pear_channel; + } + + if ($this->_getChannelFromAlias($channel) == 'doc.php.net') { + // the registry is not properly set up, so use defaults + if (!class_exists('PEAR_ChannelFile')) { + require_once 'PEAR/ChannelFile.php'; + } + + $doc_channel = new PEAR_ChannelFile; + $doc_channel->setServer('doc.php.net'); + $doc_channel->setAlias('phpdocs'); + $doc_channel->setSummary('PHP Documentation Team'); + $doc_channel->setDefaultPEARProtocols(); + $doc_channel->setBaseURL('REST1.0', 'http://doc.php.net/rest/'); + $doc_channel->setBaseURL('REST1.1', 'http://doc.php.net/rest/'); + $doc_channel->setBaseURL('REST1.3', 'http://doc.php.net/rest/'); + return $doc_channel; + } + + + if ($this->_getChannelFromAlias($channel) == '__uri') { + // the registry is not properly set up, so use defaults + if (!class_exists('PEAR_ChannelFile')) { + require_once 'PEAR/ChannelFile.php'; + } + + $private = new PEAR_ChannelFile; + $private->setName('__uri'); + $private->setDefaultPEARProtocols(); + $private->setBaseURL('REST1.0', '****'); + $private->setSummary('Pseudo-channel for static packages'); + return $private; + } + + return $ch; + } + + /** + * @param string Package name + * @param string Channel name + * @return bool + */ + function packageExists($package, $channel = 'pear.php.net') + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_packageExists($package, $channel); + $this->_unlock(); + return $ret; + } + + // }}} + + // {{{ channelExists() + + /** + * @param string channel name + * @param bool if true, then aliases will be ignored + * @return bool + */ + function channelExists($channel, $noaliases = false) + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_channelExists($channel, $noaliases); + $this->_unlock(); + return $ret; + } + + // }}} + + /** + * @param string channel name mirror is in + * @param string mirror name + * + * @return bool + */ + function mirrorExists($channel, $mirror) + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + + $ret = $this->_mirrorExists($channel, $mirror); + $this->_unlock(); + return $ret; + } + + // {{{ isAlias() + + /** + * Determines whether the parameter is an alias of a channel + * @param string + * @return bool + */ + function isAlias($alias) + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_isChannelAlias($alias); + $this->_unlock(); + return $ret; + } + + // }}} + // {{{ packageInfo() + + /** + * @param string|null + * @param string|null + * @param string + * @return array|null + */ + function packageInfo($package = null, $key = null, $channel = 'pear.php.net') + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_packageInfo($package, $key, $channel); + $this->_unlock(); + return $ret; + } + + // }}} + // {{{ channelInfo() + + /** + * Retrieve a raw array of channel data. + * + * Do not use this, instead use {@link getChannel()} for normal + * operations. Array structure is undefined in this method + * @param string channel name + * @param bool whether to strictly retrieve information only on non-aliases + * @return array|null|PEAR_Error + */ + function channelInfo($channel = null, $noaliases = false) + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_channelInfo($channel, $noaliases); + $this->_unlock(); + return $ret; + } + + // }}} + + /** + * @param string + */ + function channelName($channel) + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_getChannelFromAlias($channel); + $this->_unlock(); + return $ret; + } + + /** + * @param string + */ + function channelAlias($channel) + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_getAlias($channel); + $this->_unlock(); + return $ret; + } + // {{{ listPackages() + + function listPackages($channel = false) + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_listPackages($channel); + $this->_unlock(); + return $ret; + } + + // }}} + // {{{ listAllPackages() + + function listAllPackages() + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_listAllPackages(); + $this->_unlock(); + return $ret; + } + + // }}} + // {{{ listChannel() + + function listChannels() + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_listChannels(); + $this->_unlock(); + return $ret; + } + + // }}} + // {{{ addPackage() + + /** + * Add an installed package to the registry + * @param string|PEAR_PackageFile_v1|PEAR_PackageFile_v2 package name or object + * that will be passed to {@link addPackage2()} + * @param array package info (parsed by PEAR_Common::infoFrom*() methods) + * @return bool success of saving + */ + function addPackage($package, $info) + { + if (is_object($info)) { + return $this->addPackage2($info); + } + if (PEAR::isError($e = $this->_lock(LOCK_EX))) { + return $e; + } + $ret = $this->_addPackage($package, $info); + $this->_unlock(); + if ($ret) { + if (!class_exists('PEAR_PackageFile_v1')) { + require_once 'PEAR/PackageFile/v1.php'; + } + $pf = new PEAR_PackageFile_v1; + $pf->setConfig($this->_config); + $pf->fromArray($info); + $this->_dependencyDB->uninstallPackage($pf); + $this->_dependencyDB->installPackage($pf); + } + return $ret; + } + + // }}} + // {{{ addPackage2() + + function addPackage2($info) + { + if (!is_object($info)) { + return $this->addPackage($info['package'], $info); + } + if (PEAR::isError($e = $this->_lock(LOCK_EX))) { + return $e; + } + $ret = $this->_addPackage2($info); + $this->_unlock(); + if ($ret) { + $this->_dependencyDB->uninstallPackage($info); + $this->_dependencyDB->installPackage($info); + } + return $ret; + } + + // }}} + // {{{ updateChannel() + + /** + * For future expandibility purposes, separate this + * @param PEAR_ChannelFile + */ + function updateChannel($channel, $lastmodified = null) + { + if ($channel->getName() == '__uri') { + return false; + } + return $this->addChannel($channel, $lastmodified, true); + } + + // }}} + // {{{ deleteChannel() + + /** + * Deletion fails if there are any packages installed from the channel + * @param string|PEAR_ChannelFile channel name + * @return boolean|PEAR_Error True on deletion, false if it doesn't exist + */ + function deleteChannel($channel) + { + if (PEAR::isError($e = $this->_lock(LOCK_EX))) { + return $e; + } + + $ret = $this->_deleteChannel($channel); + $this->_unlock(); + if ($ret && is_a($this->_config, 'PEAR_Config')) { + $this->_config->setChannels($this->listChannels()); + } + + return $ret; + } + + // }}} + // {{{ addChannel() + + /** + * @param PEAR_ChannelFile Channel object + * @param string Last-Modified header from HTTP for caching + * @return boolean|PEAR_Error True on creation, false if it already exists + */ + function addChannel($channel, $lastmodified = false, $update = false) + { + if (!is_a($channel, 'PEAR_ChannelFile') || !$channel->validate()) { + return false; + } + + if (PEAR::isError($e = $this->_lock(LOCK_EX))) { + return $e; + } + + $ret = $this->_addChannel($channel, $update, $lastmodified); + $this->_unlock(); + if (!$update && $ret && is_a($this->_config, 'PEAR_Config')) { + $this->_config->setChannels($this->listChannels()); + } + + return $ret; + } + + // }}} + // {{{ deletePackage() + + function deletePackage($package, $channel = 'pear.php.net') + { + if (PEAR::isError($e = $this->_lock(LOCK_EX))) { + return $e; + } + + $file = $this->_packageFileName($package, $channel); + $ret = file_exists($file) ? @unlink($file) : false; + $this->_rebuildFileMap(); + $this->_unlock(); + $p = array('channel' => $channel, 'package' => $package); + $this->_dependencyDB->uninstallPackage($p); + return $ret; + } + + // }}} + // {{{ updatePackage() + + function updatePackage($package, $info, $merge = true) + { + if (is_object($info)) { + return $this->updatePackage2($info, $merge); + } + if (PEAR::isError($e = $this->_lock(LOCK_EX))) { + return $e; + } + $ret = $this->_updatePackage($package, $info, $merge); + $this->_unlock(); + if ($ret) { + if (!class_exists('PEAR_PackageFile_v1')) { + require_once 'PEAR/PackageFile/v1.php'; + } + $pf = new PEAR_PackageFile_v1; + $pf->setConfig($this->_config); + $pf->fromArray($this->packageInfo($package)); + $this->_dependencyDB->uninstallPackage($pf); + $this->_dependencyDB->installPackage($pf); + } + return $ret; + } + + // }}} + // {{{ updatePackage2() + + function updatePackage2($info) + { + + if (!is_object($info)) { + return $this->updatePackage($info['package'], $info, $merge); + } + + if (!$info->validate(PEAR_VALIDATE_DOWNLOADING)) { + return false; + } + + if (PEAR::isError($e = $this->_lock(LOCK_EX))) { + return $e; + } + + $ret = $this->_updatePackage2($info); + $this->_unlock(); + if ($ret) { + $this->_dependencyDB->uninstallPackage($info); + $this->_dependencyDB->installPackage($info); + } + + return $ret; + } + + // }}} + // {{{ getChannel() + /** + * @param string channel name + * @param bool whether to strictly return raw channels (no aliases) + * @return PEAR_ChannelFile|PEAR_Error + */ + function getChannel($channel, $noaliases = false) + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_getChannel($channel, $noaliases); + $this->_unlock(); + if (!$ret) { + return PEAR::raiseError('Unknown channel: ' . $channel); + } + return $ret; + } + + // }}} + // {{{ getPackage() + /** + * @param string package name + * @param string channel name + * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2|null + */ + function &getPackage($package, $channel = 'pear.php.net') + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $pf = &$this->_getPackage($package, $channel); + $this->_unlock(); + return $pf; + } + + // }}} + + /** + * Get PEAR_PackageFile_v[1/2] objects representing the contents of + * a dependency group that are installed. + * + * This is used at uninstall-time + * @param array + * @return array|false + */ + function getInstalledGroup($group) + { + $ret = array(); + if (isset($group['package'])) { + if (!isset($group['package'][0])) { + $group['package'] = array($group['package']); + } + foreach ($group['package'] as $package) { + $depchannel = isset($package['channel']) ? $package['channel'] : '__uri'; + $p = &$this->getPackage($package['name'], $depchannel); + if ($p) { + $save = &$p; + $ret[] = &$save; + } + } + } + if (isset($group['subpackage'])) { + if (!isset($group['subpackage'][0])) { + $group['subpackage'] = array($group['subpackage']); + } + foreach ($group['subpackage'] as $package) { + $depchannel = isset($package['channel']) ? $package['channel'] : '__uri'; + $p = &$this->getPackage($package['name'], $depchannel); + if ($p) { + $save = &$p; + $ret[] = &$save; + } + } + } + if (!count($ret)) { + return false; + } + return $ret; + } + + // {{{ getChannelValidator() + /** + * @param string channel name + * @return PEAR_Validate|false + */ + function &getChannelValidator($channel) + { + $chan = $this->getChannel($channel); + if (PEAR::isError($chan)) { + return $chan; + } + $val = $chan->getValidationObject(); + return $val; + } + // }}} + // {{{ getChannels() + /** + * @param string channel name + * @return array an array of PEAR_ChannelFile objects representing every installed channel + */ + function &getChannels() + { + $ret = array(); + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + foreach ($this->_listChannels() as $channel) { + $e = &$this->_getChannel($channel); + if (!$e || PEAR::isError($e)) { + continue; + } + $ret[] = $e; + } + $this->_unlock(); + return $ret; + } + + // }}} + // {{{ checkFileMap() + + /** + * Test whether a file or set of files belongs to a package. + * + * If an array is passed in + * @param string|array file path, absolute or relative to the pear + * install dir + * @param string|array name of PEAR package or array('package' => name, 'channel' => + * channel) of a package that will be ignored + * @param string API version - 1.1 will exclude any files belonging to a package + * @param array private recursion variable + * @return array|false which package and channel the file belongs to, or an empty + * string if the file does not belong to an installed package, + * or belongs to the second parameter's package + */ + function checkFileMap($path, $package = false, $api = '1.0', $attrs = false) + { + if (is_array($path)) { + static $notempty; + if (empty($notempty)) { + if (!class_exists('PEAR_Installer_Role')) { + require_once 'PEAR/Installer/Role.php'; + } + $notempty = create_function('$a','return !empty($a);'); + } + $package = is_array($package) ? array(strtolower($package[0]), strtolower($package[1])) + : strtolower($package); + $pkgs = array(); + foreach ($path as $name => $attrs) { + if (is_array($attrs)) { + if (isset($attrs['install-as'])) { + $name = $attrs['install-as']; + } + if (!in_array($attrs['role'], PEAR_Installer_Role::getInstallableRoles())) { + // these are not installed + continue; + } + if (!in_array($attrs['role'], PEAR_Installer_Role::getBaseinstallRoles())) { + $attrs['baseinstalldir'] = is_array($package) ? $package[1] : $package; + } + if (isset($attrs['baseinstalldir'])) { + $name = $attrs['baseinstalldir'] . DIRECTORY_SEPARATOR . $name; + } + } + $pkgs[$name] = $this->checkFileMap($name, $package, $api, $attrs); + if (PEAR::isError($pkgs[$name])) { + return $pkgs[$name]; + } + } + return array_filter($pkgs, $notempty); + } + if (empty($this->filemap_cache)) { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $err = $this->_readFileMap(); + $this->_unlock(); + if (PEAR::isError($err)) { + return $err; + } + } + if (!$attrs) { + $attrs = array('role' => 'php'); // any old call would be for PHP role only + } + if (isset($this->filemap_cache[$attrs['role']][$path])) { + if ($api >= '1.1' && $this->filemap_cache[$attrs['role']][$path] == $package) { + return false; + } + return $this->filemap_cache[$attrs['role']][$path]; + } + $l = strlen($this->install_dir); + if (substr($path, 0, $l) == $this->install_dir) { + $path = preg_replace('!^'.DIRECTORY_SEPARATOR.'+!', '', substr($path, $l)); + } + if (isset($this->filemap_cache[$attrs['role']][$path])) { + if ($api >= '1.1' && $this->filemap_cache[$attrs['role']][$path] == $package) { + return false; + } + return $this->filemap_cache[$attrs['role']][$path]; + } + return false; + } + + // }}} + // {{{ flush() + /** + * Force a reload of the filemap + * @since 1.5.0RC3 + */ + function flushFileMap() + { + $this->filemap_cache = null; + clearstatcache(); // ensure that the next read gets the full, current filemap + } + + // }}} + // {{{ apiVersion() + /** + * Get the expected API version. Channels API is version 1.1, as it is backwards + * compatible with 1.0 + * @return string + */ + function apiVersion() + { + return '1.1'; + } + // }}} + + + /** + * Parse a package name, or validate a parsed package name array + * @param string|array pass in an array of format + * array( + * 'package' => 'pname', + * ['channel' => 'channame',] + * ['version' => 'version',] + * ['state' => 'state',] + * ['group' => 'groupname']) + * or a string of format + * [channel://][channame/]pname[-version|-state][/group=groupname] + * @return array|PEAR_Error + */ + function parsePackageName($param, $defaultchannel = 'pear.php.net') + { + $saveparam = $param; + if (is_array($param)) { + // convert to string for error messages + $saveparam = $this->parsedPackageNameToString($param); + // process the array + if (!isset($param['package'])) { + return PEAR::raiseError('parsePackageName(): array $param ' . + 'must contain a valid package name in index "param"', + 'package', null, null, $param); + } + if (!isset($param['uri'])) { + if (!isset($param['channel'])) { + $param['channel'] = $defaultchannel; + } + } else { + $param['channel'] = '__uri'; + } + } else { + $components = @parse_url((string) $param); + if (isset($components['scheme'])) { + if ($components['scheme'] == 'http') { + // uri package + $param = array('uri' => $param, 'channel' => '__uri'); + } elseif($components['scheme'] != 'channel') { + return PEAR::raiseError('parsePackageName(): only channel:// uris may ' . + 'be downloaded, not "' . $param . '"', 'invalid', null, null, $param); + } + } + if (!isset($components['path'])) { + return PEAR::raiseError('parsePackageName(): array $param ' . + 'must contain a valid package name in "' . $param . '"', + 'package', null, null, $param); + } + if (isset($components['host'])) { + // remove the leading "/" + $components['path'] = substr($components['path'], 1); + } + if (!isset($components['scheme'])) { + if (strpos($components['path'], '/') !== false) { + if ($components['path']{0} == '/') { + return PEAR::raiseError('parsePackageName(): this is not ' . + 'a package name, it begins with "/" in "' . $param . '"', + 'invalid', null, null, $param); + } + $parts = explode('/', $components['path']); + $components['host'] = array_shift($parts); + if (count($parts) > 1) { + $components['path'] = array_pop($parts); + $components['host'] .= '/' . implode('/', $parts); + } else { + $components['path'] = implode('/', $parts); + } + } else { + $components['host'] = $defaultchannel; + } + } else { + if (strpos($components['path'], '/')) { + $parts = explode('/', $components['path']); + $components['path'] = array_pop($parts); + $components['host'] .= '/' . implode('/', $parts); + } + } + + if (is_array($param)) { + $param['package'] = $components['path']; + } else { + $param = array( + 'package' => $components['path'] + ); + if (isset($components['host'])) { + $param['channel'] = $components['host']; + } + } + if (isset($components['fragment'])) { + $param['group'] = $components['fragment']; + } + if (isset($components['user'])) { + $param['user'] = $components['user']; + } + if (isset($components['pass'])) { + $param['pass'] = $components['pass']; + } + if (isset($components['query'])) { + parse_str($components['query'], $param['opts']); + } + // check for extension + $pathinfo = pathinfo($param['package']); + if (isset($pathinfo['extension']) && + in_array(strtolower($pathinfo['extension']), array('tgz', 'tar'))) { + $param['extension'] = $pathinfo['extension']; + $param['package'] = substr($pathinfo['basename'], 0, + strlen($pathinfo['basename']) - 4); + } + // check for version + if (strpos($param['package'], '-')) { + $test = explode('-', $param['package']); + if (count($test) != 2) { + return PEAR::raiseError('parsePackageName(): only one version/state ' . + 'delimiter "-" is allowed in "' . $saveparam . '"', + 'version', null, null, $param); + } + list($param['package'], $param['version']) = $test; + } + } + // validation + $info = $this->channelExists($param['channel']); + if (PEAR::isError($info)) { + return $info; + } + if (!$info) { + return PEAR::raiseError('unknown channel "' . $param['channel'] . + '" in "' . $saveparam . '"', 'channel', null, null, $param); + } + $chan = $this->getChannel($param['channel']); + if (PEAR::isError($chan)) { + return $chan; + } + if (!$chan) { + return PEAR::raiseError("Exception: corrupt registry, could not " . + "retrieve channel " . $param['channel'] . " information", + 'registry', null, null, $param); + } + $param['channel'] = $chan->getName(); + $validate = $chan->getValidationObject(); + $vpackage = $chan->getValidationPackage(); + // validate package name + if (!$validate->validPackageName($param['package'], $vpackage['_content'])) { + return PEAR::raiseError('parsePackageName(): invalid package name "' . + $param['package'] . '" in "' . $saveparam . '"', + 'package', null, null, $param); + } + if (isset($param['group'])) { + if (!PEAR_Validate::validGroupName($param['group'])) { + return PEAR::raiseError('parsePackageName(): dependency group "' . $param['group'] . + '" is not a valid group name in "' . $saveparam . '"', 'group', null, null, + $param); + } + } + if (isset($param['state'])) { + if (!in_array(strtolower($param['state']), $validate->getValidStates())) { + return PEAR::raiseError('parsePackageName(): state "' . $param['state'] + . '" is not a valid state in "' . $saveparam . '"', + 'state', null, null, $param); + } + } + if (isset($param['version'])) { + if (isset($param['state'])) { + return PEAR::raiseError('parsePackageName(): cannot contain both ' . + 'a version and a stability (state) in "' . $saveparam . '"', + 'version/state', null, null, $param); + } + // check whether version is actually a state + if (in_array(strtolower($param['version']), $validate->getValidStates())) { + $param['state'] = strtolower($param['version']); + unset($param['version']); + } else { + if (!$validate->validVersion($param['version'])) { + return PEAR::raiseError('parsePackageName(): "' . $param['version'] . + '" is neither a valid version nor a valid state in "' . + $saveparam . '"', 'version/state', null, null, $param); + } + } + } + return $param; + } + + /** + * @param array + * @return string + */ + function parsedPackageNameToString($parsed, $brief = false) + { + if (is_string($parsed)) { + return $parsed; + } + if (is_object($parsed)) { + $p = $parsed; + $parsed = array( + 'package' => $p->getPackage(), + 'channel' => $p->getChannel(), + 'version' => $p->getVersion(), + ); + } + if (isset($parsed['uri'])) { + return $parsed['uri']; + } + if ($brief) { + if ($channel = $this->channelAlias($parsed['channel'])) { + return $channel . '/' . $parsed['package']; + } + } + $upass = ''; + if (isset($parsed['user'])) { + $upass = $parsed['user']; + if (isset($parsed['pass'])) { + $upass .= ':' . $parsed['pass']; + } + $upass = "$upass@"; + } + $ret = 'channel://' . $upass . $parsed['channel'] . '/' . $parsed['package']; + if (isset($parsed['version']) || isset($parsed['state'])) { + $ver = isset($parsed['version']) ? $parsed['version'] : ''; + $ver .= isset($parsed['state']) ? $parsed['state'] : ''; + $ret .= '-' . $ver; + } + if (isset($parsed['extension'])) { + $ret .= '.' . $parsed['extension']; + } + if (isset($parsed['opts'])) { + $ret .= '?'; + foreach ($parsed['opts'] as $name => $value) { + $parsed['opts'][$name] = "$name=$value"; + } + $ret .= implode('&', $parsed['opts']); + } + if (isset($parsed['group'])) { + $ret .= '#' . $parsed['group']; + } + return $ret; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/RunTest.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/RunTest.php new file mode 100644 index 0000000..59dedbf --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/RunTest.php @@ -0,0 +1,972 @@ + + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.3.3 + */ + +/** + * for error handling + */ +require_once 'PEAR.php'; +require_once 'PEAR/Config.php'; + +define('DETAILED', 1); +putenv("PHP_PEAR_RUNTESTS=1"); + +/** + * Simplified version of PHP's test suite + * + * Try it with: + * + * $ php -r 'include "../PEAR/RunTest.php"; $t=new PEAR_RunTest; $o=$t->run("./pear_system.phpt");print_r($o);' + * + * + * @category pear + * @package PEAR + * @author Tomas V.V.Cox + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.3.3 + */ +class PEAR_RunTest +{ + var $_headers = array(); + var $_logger; + var $_options; + var $_php; + var $tests_count; + var $xdebug_loaded; + /** + * Saved value of php executable, used to reset $_php when we + * have a test that uses cgi + * + * @var unknown_type + */ + var $_savephp; + var $ini_overwrites = array( + 'output_handler=', + 'open_basedir=', + 'disable_functions=', + 'output_buffering=Off', + 'display_errors=1', + 'log_errors=0', + 'html_errors=0', + 'track_errors=1', + 'report_memleaks=0', + 'report_zend_debug=0', + 'docref_root=', + 'docref_ext=.html', + 'error_prepend_string=', + 'error_append_string=', + 'auto_prepend_file=', + 'auto_append_file=', + 'xdebug.default_enable=0', + 'allow_url_fopen=1', + ); + + /** + * An object that supports the PEAR_Common->log() signature, or null + * @param PEAR_Common|null + */ + function __construct($logger = null, $options = array()) + { + if (!defined('E_DEPRECATED')) { + define('E_DEPRECATED', 0); + } + if (!defined('E_STRICT')) { + define('E_STRICT', 0); + } + $this->ini_overwrites[] = 'error_reporting=' . (E_ALL & ~(E_DEPRECATED | E_STRICT)); + if (is_null($logger)) { + require_once 'PEAR/Common.php'; + $logger = new PEAR_Common; + } + $this->_logger = $logger; + $this->_options = $options; + + $conf = &PEAR_Config::singleton(); + $this->_php = $conf->get('php_bin'); + } + + /** + * Taken from php-src/run-tests.php + * + * @param string $commandline command name + * @param array $env + * @param string $stdin standard input to pass to the command + * @return unknown + */ + function system_with_timeout($commandline, $env = null, $stdin = null) + { + $data = ''; + $proc = proc_open($commandline, array( + 0 => array('pipe', 'r'), + 1 => array('pipe', 'w'), + 2 => array('pipe', 'w') + ), $pipes, null, $env, array('suppress_errors' => true)); + + if (!$proc) { + return false; + } + + if (is_string($stdin)) { + fwrite($pipes[0], $stdin); + } + fclose($pipes[0]); + + while (true) { + /* hide errors from interrupted syscalls */ + $r = $pipes; + $e = $w = null; + $n = @stream_select($r, $w, $e, 60); + + if ($n === 0) { + /* timed out */ + $data .= "\n ** ERROR: process timed out **\n"; + proc_terminate($proc); + return array(1234567890, $data); + } else if ($n > 0) { + $line = fread($pipes[1], 8192); + if (strlen($line) == 0) { + /* EOF */ + break; + } + $data .= $line; + } + } + if (function_exists('proc_get_status')) { + $stat = proc_get_status($proc); + if ($stat['signaled']) { + $data .= "\nTermsig=".$stat['stopsig']; + } + } + $code = proc_close($proc); + if (function_exists('proc_get_status')) { + $code = $stat['exitcode']; + } + return array($code, $data); + } + + /** + * Turns a PHP INI string into an array + * + * Turns -d "include_path=/foo/bar" into this: + * array( + * 'include_path' => array( + * 'operator' => '-d', + * 'value' => '/foo/bar', + * ) + * ) + * Works both with quotes and without + * + * @param string an PHP INI string, -d "include_path=/foo/bar" + * @return array + */ + function iniString2array($ini_string) + { + if (!$ini_string) { + return array(); + } + $split = preg_split('/[\s]|=/', $ini_string, -1, PREG_SPLIT_NO_EMPTY); + $key = $split[1][0] == '"' ? substr($split[1], 1) : $split[1]; + $value = $split[2][strlen($split[2]) - 1] == '"' ? substr($split[2], 0, -1) : $split[2]; + // FIXME review if this is really the struct to go with + $array = array($key => array('operator' => $split[0], 'value' => $value)); + return $array; + } + + function settings2array($settings, $ini_settings) + { + foreach ($settings as $setting) { + if (strpos($setting, '=') !== false) { + $setting = explode('=', $setting, 2); + $name = trim(strtolower($setting[0])); + $value = trim($setting[1]); + $ini_settings[$name] = $value; + } + } + return $ini_settings; + } + + function settings2params($ini_settings) + { + $settings = ''; + foreach ($ini_settings as $name => $value) { + if (is_array($value)) { + $operator = $value['operator']; + $value = $value['value']; + } else { + $operator = '-d'; + } + $value = addslashes($value); + $settings .= " $operator \"$name=$value\""; + } + return $settings; + } + + function _preparePhpBin($php, $file, $ini_settings) + { + $file = escapeshellarg($file); + $cmd = $php . $ini_settings . ' -f ' . $file; + + return $cmd; + } + + function runPHPUnit($file, $ini_settings = '') + { + if (!file_exists($file) && file_exists(getcwd() . DIRECTORY_SEPARATOR . $file)) { + $file = realpath(getcwd() . DIRECTORY_SEPARATOR . $file); + } elseif (file_exists($file)) { + $file = realpath($file); + } + + $cmd = $this->_preparePhpBin($this->_php, $file, $ini_settings); + if (isset($this->_logger)) { + $this->_logger->log(2, 'Running command "' . $cmd . '"'); + } + + $savedir = getcwd(); // in case the test moves us around + chdir(dirname($file)); + echo `$cmd`; + chdir($savedir); + return 'PASSED'; // we have no way of knowing this information so assume passing + } + + /** + * Runs an individual test case. + * + * @param string The filename of the test + * @param array|string INI settings to be applied to the test run + * @param integer Number what the current running test is of the + * whole test suite being runned. + * + * @return string|object Returns PASSED, WARNED, FAILED depending on how the + * test came out. + * PEAR Error when the tester it self fails + */ + function run($file, $ini_settings = array(), $test_number = 1) + { + $this->_restorePHPBinary(); + + if (empty($this->_options['cgi'])) { + // try to see if php-cgi is in the path + $res = $this->system_with_timeout('php-cgi -v'); + if (false !== $res && !(is_array($res) && in_array($res[0], array(-1, 127)))) { + $this->_options['cgi'] = 'php-cgi'; + } + } + if (1 < $len = strlen($this->tests_count)) { + $test_number = str_pad($test_number, $len, ' ', STR_PAD_LEFT); + $test_nr = "[$test_number/$this->tests_count] "; + } else { + $test_nr = ''; + } + + $file = realpath($file); + $section_text = $this->_readFile($file); + if (PEAR::isError($section_text)) { + return $section_text; + } + + if (isset($section_text['POST_RAW']) && isset($section_text['UPLOAD'])) { + return PEAR::raiseError("Cannot contain both POST_RAW and UPLOAD in test file: $file"); + } + + $cwd = getcwd(); + + $pass_options = ''; + if (!empty($this->_options['ini'])) { + $pass_options = $this->_options['ini']; + } + + if (is_string($ini_settings)) { + $ini_settings = $this->iniString2array($ini_settings); + } + + $ini_settings = $this->settings2array($this->ini_overwrites, $ini_settings); + if ($section_text['INI']) { + if (strpos($section_text['INI'], '{PWD}') !== false) { + $section_text['INI'] = str_replace('{PWD}', dirname($file), $section_text['INI']); + } + $ini = preg_split( "/[\n\r]+/", $section_text['INI']); + $ini_settings = $this->settings2array($ini, $ini_settings); + } + $ini_settings = $this->settings2params($ini_settings); + $shortname = str_replace($cwd . DIRECTORY_SEPARATOR, '', $file); + + $tested = trim($section_text['TEST']); + $tested.= !isset($this->_options['simple']) ? "[$shortname]" : ' '; + + if (!empty($section_text['POST']) || !empty($section_text['POST_RAW']) || + !empty($section_text['UPLOAD']) || !empty($section_text['GET']) || + !empty($section_text['COOKIE']) || !empty($section_text['EXPECTHEADERS'])) { + if (empty($this->_options['cgi'])) { + if (!isset($this->_options['quiet'])) { + $this->_logger->log(0, "SKIP $test_nr$tested (reason: --cgi option needed for this test, type 'pear help run-tests')"); + } + if (isset($this->_options['tapoutput'])) { + return array('ok', ' # skip --cgi option needed for this test, "pear help run-tests" for info'); + } + return 'SKIPPED'; + } + $this->_savePHPBinary(); + $this->_php = $this->_options['cgi']; + } + + $temp_dir = realpath(dirname($file)); + $main_file_name = basename($file, 'phpt'); + $diff_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'diff'; + $log_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'log'; + $exp_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'exp'; + $output_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'out'; + $memcheck_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'mem'; + $temp_file = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'php'; + $temp_skipif = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'skip.php'; + $temp_clean = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'clean.php'; + $tmp_post = $temp_dir . DIRECTORY_SEPARATOR . uniqid('phpt.'); + + // unlink old test results + $this->_cleanupOldFiles($file); + + // Check if test should be skipped. + $res = $this->_runSkipIf($section_text, $temp_skipif, $tested, $ini_settings); + if (count($res) != 2) { + return $res; + } + $info = $res['info']; + $warn = $res['warn']; + + // We've satisfied the preconditions - run the test! + if (isset($this->_options['coverage']) && $this->xdebug_loaded) { + $xdebug_file = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'xdebug'; + $text = "\n" . 'function coverage_shutdown() {' . + "\n" . ' $xdebug = var_export(xdebug_get_code_coverage(), true);'; + if (!function_exists('file_put_contents')) { + $text .= "\n" . ' $fh = fopen(\'' . $xdebug_file . '\', "wb");' . + "\n" . ' if ($fh !== false) {' . + "\n" . ' fwrite($fh, $xdebug);' . + "\n" . ' fclose($fh);' . + "\n" . ' }'; + } else { + $text .= "\n" . ' file_put_contents(\'' . $xdebug_file . '\', $xdebug);'; + } + + // Workaround for http://pear.php.net/bugs/bug.php?id=17292 + $lines = explode("\n", $section_text['FILE']); + $numLines = count($lines); + $namespace = ''; + $coverage_shutdown = 'coverage_shutdown'; + + if ( + substr($lines[0], 0, 2) == 'save_text($temp_file, "save_text($temp_file, $section_text['FILE']); + } + + $args = $section_text['ARGS'] ? ' -- '.$section_text['ARGS'] : ''; + $cmd = $this->_preparePhpBin($this->_php, $temp_file, $ini_settings); + $cmd.= "$args 2>&1"; + if (isset($this->_logger)) { + $this->_logger->log(2, 'Running command "' . $cmd . '"'); + } + + // Reset environment from any previous test. + $env = $this->_resetEnv($section_text, $temp_file); + + $section_text = $this->_processUpload($section_text, $file); + if (PEAR::isError($section_text)) { + return $section_text; + } + + if (array_key_exists('POST_RAW', $section_text) && !empty($section_text['POST_RAW'])) { + $post = trim($section_text['POST_RAW']); + $raw_lines = explode("\n", $post); + + $request = ''; + $started = false; + foreach ($raw_lines as $i => $line) { + if (empty($env['CONTENT_TYPE']) && + preg_match('/^Content-Type:(.*)/i', $line, $res)) { + $env['CONTENT_TYPE'] = trim(str_replace("\r", '', $res[1])); + continue; + } + if ($started) { + $request .= "\n"; + } + $started = true; + $request .= $line; + } + + $env['CONTENT_LENGTH'] = strlen($request); + $env['REQUEST_METHOD'] = 'POST'; + + $this->save_text($tmp_post, $request); + $cmd = "$this->_php$pass_options$ini_settings \"$temp_file\" 2>&1 < $tmp_post"; + } elseif (array_key_exists('POST', $section_text) && !empty($section_text['POST'])) { + $post = trim($section_text['POST']); + $this->save_text($tmp_post, $post); + $content_length = strlen($post); + + $env['REQUEST_METHOD'] = 'POST'; + $env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded'; + $env['CONTENT_LENGTH'] = $content_length; + + $cmd = "$this->_php$pass_options$ini_settings \"$temp_file\" 2>&1 < $tmp_post"; + } else { + $env['REQUEST_METHOD'] = 'GET'; + $env['CONTENT_TYPE'] = ''; + $env['CONTENT_LENGTH'] = ''; + } + + if (OS_WINDOWS && isset($section_text['RETURNS'])) { + ob_start(); + system($cmd, $return_value); + $out = ob_get_contents(); + ob_end_clean(); + $section_text['RETURNS'] = (int) trim($section_text['RETURNS']); + $returnfail = ($return_value != $section_text['RETURNS']); + } else { + $returnfail = false; + $stdin = isset($section_text['STDIN']) ? $section_text['STDIN'] : null; + $out = $this->system_with_timeout($cmd, $env, $stdin); + $return_value = $out[0]; + $out = $out[1]; + } + + $output = preg_replace('/\r\n/', "\n", trim($out)); + + if (isset($tmp_post) && realpath($tmp_post) && file_exists($tmp_post)) { + @unlink(realpath($tmp_post)); + } + chdir($cwd); // in case the test moves us around + + /* when using CGI, strip the headers from the output */ + $output = $this->_stripHeadersCGI($output); + + if (isset($section_text['EXPECTHEADERS'])) { + $testheaders = $this->_processHeaders($section_text['EXPECTHEADERS']); + $missing = array_diff_assoc($testheaders, $this->_headers); + $changed = ''; + foreach ($missing as $header => $value) { + if (isset($this->_headers[$header])) { + $changed .= "-$header: $value\n+$header: "; + $changed .= $this->_headers[$header]; + } else { + $changed .= "-$header: $value\n"; + } + } + if ($missing) { + // tack on failed headers to output: + $output .= "\n====EXPECTHEADERS FAILURE====:\n$changed"; + } + } + + $this->_testCleanup($section_text, $temp_clean); + + // Does the output match what is expected? + do { + if (isset($section_text['EXPECTF']) || isset($section_text['EXPECTREGEX'])) { + if (isset($section_text['EXPECTF'])) { + $wanted = trim($section_text['EXPECTF']); + } else { + $wanted = trim($section_text['EXPECTREGEX']); + } + $wanted_re = preg_replace('/\r\n/', "\n", $wanted); + if (isset($section_text['EXPECTF'])) { + $wanted_re = preg_quote($wanted_re, '/'); + // Stick to basics + $wanted_re = str_replace("%s", ".+?", $wanted_re); //not greedy + $wanted_re = str_replace("%i", "[+\-]?[0-9]+", $wanted_re); + $wanted_re = str_replace("%d", "[0-9]+", $wanted_re); + $wanted_re = str_replace("%x", "[0-9a-fA-F]+", $wanted_re); + $wanted_re = str_replace("%f", "[+\-]?\.?[0-9]+\.?[0-9]*(E-?[0-9]+)?", $wanted_re); + $wanted_re = str_replace("%c", ".", $wanted_re); + // %f allows two points "-.0.0" but that is the best *simple* expression + } + + /* DEBUG YOUR REGEX HERE + var_dump($wanted_re); + print(str_repeat('=', 80) . "\n"); + var_dump($output); + */ + if (!$returnfail && preg_match("/^$wanted_re\$/s", $output)) { + if (file_exists($temp_file)) { + unlink($temp_file); + } + if (array_key_exists('FAIL', $section_text)) { + break; + } + if (!isset($this->_options['quiet'])) { + $this->_logger->log(0, "PASS $test_nr$tested$info"); + } + if (isset($this->_options['tapoutput'])) { + return array('ok', ' - ' . $tested); + } + return 'PASSED'; + } + } else { + if (isset($section_text['EXPECTFILE'])) { + $f = $temp_dir . '/' . trim($section_text['EXPECTFILE']); + if (!($fp = @fopen($f, 'rb'))) { + return PEAR::raiseError('--EXPECTFILE-- section file ' . + $f . ' not found'); + } + fclose($fp); + $section_text['EXPECT'] = file_get_contents($f); + } + + if (isset($section_text['EXPECT'])) { + $wanted = preg_replace('/\r\n/', "\n", trim($section_text['EXPECT'])); + } else { + $wanted = ''; + } + + // compare and leave on success + if (!$returnfail && 0 == strcmp($output, $wanted)) { + if (file_exists($temp_file)) { + unlink($temp_file); + } + if (array_key_exists('FAIL', $section_text)) { + break; + } + if (!isset($this->_options['quiet'])) { + $this->_logger->log(0, "PASS $test_nr$tested$info"); + } + if (isset($this->_options['tapoutput'])) { + return array('ok', ' - ' . $tested); + } + return 'PASSED'; + } + } + } while (false); + + if (array_key_exists('FAIL', $section_text)) { + // we expect a particular failure + // this is only used for testing PEAR_RunTest + $expectf = isset($section_text['EXPECTF']) ? $wanted_re : null; + $faildiff = $this->generate_diff($wanted, $output, null, $expectf); + $faildiff = preg_replace('/\r/', '', $faildiff); + $wanted = preg_replace('/\r/', '', trim($section_text['FAIL'])); + if ($faildiff == $wanted) { + if (!isset($this->_options['quiet'])) { + $this->_logger->log(0, "PASS $test_nr$tested$info"); + } + if (isset($this->_options['tapoutput'])) { + return array('ok', ' - ' . $tested); + } + return 'PASSED'; + } + unset($section_text['EXPECTF']); + $output = $faildiff; + if (isset($section_text['RETURNS'])) { + return PEAR::raiseError('Cannot have both RETURNS and FAIL in the same test: ' . + $file); + } + } + + // Test failed so we need to report details. + $txt = $warn ? 'WARN ' : 'FAIL '; + $this->_logger->log(0, $txt . $test_nr . $tested . $info); + + // write .exp + $res = $this->_writeLog($exp_filename, $wanted); + if (PEAR::isError($res)) { + return $res; + } + + // write .out + $res = $this->_writeLog($output_filename, $output); + if (PEAR::isError($res)) { + return $res; + } + + // write .diff + $returns = isset($section_text['RETURNS']) ? + array(trim($section_text['RETURNS']), $return_value) : null; + $expectf = isset($section_text['EXPECTF']) ? $wanted_re : null; + $data = $this->generate_diff($wanted, $output, $returns, $expectf); + $res = $this->_writeLog($diff_filename, $data); + if (isset($this->_options['showdiff'])) { + $this->_logger->log(0, "========DIFF========"); + $this->_logger->log(0, $data); + $this->_logger->log(0, "========DONE========"); + } + if (PEAR::isError($res)) { + return $res; + } + + // write .log + $data = " +---- EXPECTED OUTPUT +$wanted +---- ACTUAL OUTPUT +$output +---- FAILED +"; + + if ($returnfail) { + $data .= " +---- EXPECTED RETURN +$section_text[RETURNS] +---- ACTUAL RETURN +$return_value +"; + } + + $res = $this->_writeLog($log_filename, $data); + if (PEAR::isError($res)) { + return $res; + } + + if (isset($this->_options['tapoutput'])) { + $wanted = explode("\n", $wanted); + $wanted = "# Expected output:\n#\n#" . implode("\n#", $wanted); + $output = explode("\n", $output); + $output = "#\n#\n# Actual output:\n#\n#" . implode("\n#", $output); + return array($wanted . $output . 'not ok', ' - ' . $tested); + } + return $warn ? 'WARNED' : 'FAILED'; + } + + function generate_diff($wanted, $output, $rvalue, $wanted_re) + { + $w = explode("\n", $wanted); + $o = explode("\n", $output); + $wr = explode("\n", $wanted_re); + $w1 = array_diff_assoc($w, $o); + $o1 = array_diff_assoc($o, $w); + $o2 = $w2 = array(); + foreach ($w1 as $idx => $val) { + if (!$wanted_re || !isset($wr[$idx]) || !isset($o1[$idx]) || + !preg_match('/^' . $wr[$idx] . '\\z/', $o1[$idx])) { + $w2[sprintf("%03d<", $idx)] = sprintf("%03d- ", $idx + 1) . $val; + } + } + foreach ($o1 as $idx => $val) { + if (!$wanted_re || !isset($wr[$idx]) || + !preg_match('/^' . $wr[$idx] . '\\z/', $val)) { + $o2[sprintf("%03d>", $idx)] = sprintf("%03d+ ", $idx + 1) . $val; + } + } + $diff = array_merge($w2, $o2); + ksort($diff); + $extra = $rvalue ? "##EXPECTED: $rvalue[0]\r\n##RETURNED: $rvalue[1]" : ''; + return implode("\r\n", $diff) . $extra; + } + + // Write the given text to a temporary file, and return the filename. + function save_text($filename, $text) + { + if (!$fp = fopen($filename, 'w')) { + return PEAR::raiseError("Cannot open file '" . $filename . "' (save_text)"); + } + fwrite($fp, $text); + fclose($fp); + if (1 < DETAILED) echo " +FILE $filename {{{ +$text +}}} +"; + } + + function _cleanupOldFiles($file) + { + $temp_dir = realpath(dirname($file)); + $mainFileName = basename($file, 'phpt'); + $diff_filename = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'diff'; + $log_filename = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'log'; + $exp_filename = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'exp'; + $output_filename = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'out'; + $memcheck_filename = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'mem'; + $temp_file = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'php'; + $temp_skipif = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'skip.php'; + $temp_clean = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'clean.php'; + $tmp_post = $temp_dir . DIRECTORY_SEPARATOR . uniqid('phpt.'); + + // unlink old test results + @unlink($diff_filename); + @unlink($log_filename); + @unlink($exp_filename); + @unlink($output_filename); + @unlink($memcheck_filename); + @unlink($temp_file); + @unlink($temp_skipif); + @unlink($tmp_post); + @unlink($temp_clean); + } + + function _runSkipIf($section_text, $temp_skipif, $tested, $ini_settings) + { + $info = ''; + $warn = false; + if (array_key_exists('SKIPIF', $section_text) && trim($section_text['SKIPIF'])) { + $this->save_text($temp_skipif, $section_text['SKIPIF']); + $output = $this->system_with_timeout("$this->_php$ini_settings -f \"$temp_skipif\""); + $output = $output[1]; + $loutput = ltrim($output); + unlink($temp_skipif); + if (!strncasecmp('skip', $loutput, 4)) { + $skipreason = "SKIP $tested"; + if (preg_match('/^\s*skip\s*(.+)\s*/i', $output, $m)) { + $skipreason .= '(reason: ' . $m[1] . ')'; + } + if (!isset($this->_options['quiet'])) { + $this->_logger->log(0, $skipreason); + } + if (isset($this->_options['tapoutput'])) { + return array('ok', ' # skip ' . $reason); + } + return 'SKIPPED'; + } + + if (!strncasecmp('info', $loutput, 4) + && preg_match('/^\s*info\s*(.+)\s*/i', $output, $m)) { + $info = " (info: $m[1])"; + } + + if (!strncasecmp('warn', $loutput, 4) + && preg_match('/^\s*warn\s*(.+)\s*/i', $output, $m)) { + $warn = true; /* only if there is a reason */ + $info = " (warn: $m[1])"; + } + } + + return array('warn' => $warn, 'info' => $info); + } + + function _stripHeadersCGI($output) + { + $this->headers = array(); + if (!empty($this->_options['cgi']) && + $this->_php == $this->_options['cgi'] && + preg_match("/^(.*?)(?:\n\n(.*)|\\z)/s", $output, $match)) { + $output = isset($match[2]) ? trim($match[2]) : ''; + $this->_headers = $this->_processHeaders($match[1]); + } + + return $output; + } + + /** + * Return an array that can be used with array_diff() to compare headers + * + * @param string $text + */ + function _processHeaders($text) + { + $headers = array(); + $rh = preg_split("/[\n\r]+/", $text); + foreach ($rh as $line) { + if (strpos($line, ':')!== false) { + $line = explode(':', $line, 2); + $headers[trim($line[0])] = trim($line[1]); + } + } + return $headers; + } + + function _readFile($file) + { + // Load the sections of the test file. + $section_text = array( + 'TEST' => '(unnamed test)', + 'SKIPIF' => '', + 'GET' => '', + 'COOKIE' => '', + 'POST' => '', + 'ARGS' => '', + 'INI' => '', + 'CLEAN' => '', + ); + + if (!is_file($file) || !$fp = fopen($file, "r")) { + return PEAR::raiseError("Cannot open test file: $file"); + } + + $section = ''; + while (!feof($fp)) { + $line = fgets($fp); + + // Match the beginning of a section. + if (preg_match('/^--([_A-Z]+)--/', $line, $r)) { + $section = $r[1]; + $section_text[$section] = ''; + continue; + } elseif (empty($section)) { + fclose($fp); + return PEAR::raiseError("Invalid sections formats in test file: $file"); + } + + // Add to the section text. + $section_text[$section] .= $line; + } + fclose($fp); + + return $section_text; + } + + function _writeLog($logname, $data) + { + if (!$log = fopen($logname, 'w')) { + return PEAR::raiseError("Cannot create test log - $logname"); + } + fwrite($log, $data); + fclose($log); + } + + function _resetEnv($section_text, $temp_file) + { + $env = $_ENV; + $env['REDIRECT_STATUS'] = ''; + $env['QUERY_STRING'] = ''; + $env['PATH_TRANSLATED'] = ''; + $env['SCRIPT_FILENAME'] = ''; + $env['REQUEST_METHOD'] = ''; + $env['CONTENT_TYPE'] = ''; + $env['CONTENT_LENGTH'] = ''; + if (!empty($section_text['ENV'])) { + if (strpos($section_text['ENV'], '{PWD}') !== false) { + $section_text['ENV'] = str_replace('{PWD}', dirname($temp_file), $section_text['ENV']); + } + foreach (explode("\n", trim($section_text['ENV'])) as $e) { + $e = explode('=', trim($e), 2); + if (!empty($e[0]) && isset($e[1])) { + $env[$e[0]] = $e[1]; + } + } + } + if (array_key_exists('GET', $section_text)) { + $env['QUERY_STRING'] = trim($section_text['GET']); + } else { + $env['QUERY_STRING'] = ''; + } + if (array_key_exists('COOKIE', $section_text)) { + $env['HTTP_COOKIE'] = trim($section_text['COOKIE']); + } else { + $env['HTTP_COOKIE'] = ''; + } + $env['REDIRECT_STATUS'] = '1'; + $env['PATH_TRANSLATED'] = $temp_file; + $env['SCRIPT_FILENAME'] = $temp_file; + + return $env; + } + + function _processUpload($section_text, $file) + { + if (array_key_exists('UPLOAD', $section_text) && !empty($section_text['UPLOAD'])) { + $upload_files = trim($section_text['UPLOAD']); + $upload_files = explode("\n", $upload_files); + + $request = "Content-Type: multipart/form-data; boundary=---------------------------20896060251896012921717172737\n" . + "-----------------------------20896060251896012921717172737\n"; + foreach ($upload_files as $fileinfo) { + $fileinfo = explode('=', $fileinfo); + if (count($fileinfo) != 2) { + return PEAR::raiseError("Invalid UPLOAD section in test file: $file"); + } + if (!realpath(dirname($file) . '/' . $fileinfo[1])) { + return PEAR::raiseError("File for upload does not exist: $fileinfo[1] " . + "in test file: $file"); + } + $file_contents = file_get_contents(dirname($file) . '/' . $fileinfo[1]); + $fileinfo[1] = basename($fileinfo[1]); + $request .= "Content-Disposition: form-data; name=\"$fileinfo[0]\"; filename=\"$fileinfo[1]\"\n"; + $request .= "Content-Type: text/plain\n\n"; + $request .= $file_contents . "\n" . + "-----------------------------20896060251896012921717172737\n"; + } + + if (array_key_exists('POST', $section_text) && !empty($section_text['POST'])) { + // encode POST raw + $post = trim($section_text['POST']); + $post = explode('&', $post); + foreach ($post as $i => $post_info) { + $post_info = explode('=', $post_info); + if (count($post_info) != 2) { + return PEAR::raiseError("Invalid POST data in test file: $file"); + } + $post_info[0] = rawurldecode($post_info[0]); + $post_info[1] = rawurldecode($post_info[1]); + $post[$i] = $post_info; + } + foreach ($post as $post_info) { + $request .= "Content-Disposition: form-data; name=\"$post_info[0]\"\n\n"; + $request .= $post_info[1] . "\n" . + "-----------------------------20896060251896012921717172737\n"; + } + unset($section_text['POST']); + } + $section_text['POST_RAW'] = $request; + } + + return $section_text; + } + + function _testCleanup($section_text, $temp_clean) + { + if ($section_text['CLEAN']) { + $this->_restorePHPBinary(); + + // perform test cleanup + $this->save_text($temp_clean, $section_text['CLEAN']); + $output = $this->system_with_timeout("$this->_php $temp_clean 2>&1"); + if (strlen($output[1])) { + echo "BORKED --CLEAN-- section! output:\n", $output[1]; + } + if (file_exists($temp_clean)) { + unlink($temp_clean); + } + } + } + + function _savePHPBinary() + { + $this->_savephp = $this->_php; + } + + function _restorePHPBinary() + { + if (isset($this->_savephp)) + { + $this->_php = $this->_savephp; + unset($this->_savephp); + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Task/Common.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Task/Common.php new file mode 100644 index 0000000..ebb71dc --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Task/Common.php @@ -0,0 +1,207 @@ + + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ +/**#@+ + * Error codes for task validation routines + */ +define('PEAR_TASK_ERROR_NOATTRIBS', 1); +define('PEAR_TASK_ERROR_MISSING_ATTRIB', 2); +define('PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE', 3); +define('PEAR_TASK_ERROR_INVALID', 4); +/**#@-*/ +define('PEAR_TASK_PACKAGE', 1); +define('PEAR_TASK_INSTALL', 2); +define('PEAR_TASK_PACKAGEANDINSTALL', 3); +/** + * A task is an operation that manipulates the contents of a file. + * + * Simple tasks operate on 1 file. Multiple tasks are executed after all files have been + * processed and installed, and are designed to operate on all files containing the task. + * The Post-install script task simply takes advantage of the fact that it will be run + * after installation, replace is a simple task. + * + * Combining tasks is possible, but ordering is significant. + * + * + * + * + * + * + * This will first replace any instance of @data-dir@ in the test.php file + * with the path to the current data directory. Then, it will include the + * test.php file and run the script it contains to configure the package post-installation. + * + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + * @abstract + */ +class PEAR_Task_Common +{ + /** + * Valid types for this version are 'simple' and 'multiple' + * + * - simple tasks operate on the contents of a file and write out changes to disk + * - multiple tasks operate on the contents of many files and write out the + * changes directly to disk + * + * Child task classes must override this property. + * + * @access protected + */ + protected $type = 'simple'; + /** + * Determines which install phase this task is executed under + */ + public $phase = PEAR_TASK_INSTALL; + /** + * @access protected + */ + protected $config; + /** + * @access protected + */ + protected $registry; + /** + * @access protected + */ + public $logger; + /** + * @access protected + */ + protected $installphase; + /** + * @param PEAR_Config + * @param PEAR_Common + */ + function __construct(&$config, &$logger, $phase) + { + $this->config = &$config; + $this->registry = &$config->getRegistry(); + $this->logger = &$logger; + $this->installphase = $phase; + if ($this->type == 'multiple') { + $GLOBALS['_PEAR_TASK_POSTINSTANCES'][get_class($this)][] = &$this; + } + } + + /** + * Validate the basic contents of a task tag. + * + * @param PEAR_PackageFile_v2 + * @param array + * @param PEAR_Config + * @param array the entire parsed tag + * + * @return true|array On error, return an array in format: + * array(PEAR_TASK_ERROR_???[, param1][, param2][, ...]) + * + * For PEAR_TASK_ERROR_MISSING_ATTRIB, pass the attribute name in + * For PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE, pass the attribute name and + * an array of legal values in + * + * @abstract + */ + public static function validateXml($pkg, $xml, $config, $fileXml) + { + } + + /** + * Initialize a task instance with the parameters + * + * @param array raw, parsed xml + * @param array attributes from the tag containing this task + * @param string|null last installed version of this package + * @abstract + */ + public function init($xml, $fileAttributes, $lastVersion) + { + } + + /** + * Begin a task processing session. All multiple tasks will be processed + * after each file has been successfully installed, all simple tasks should + * perform their task here and return any errors using the custom + * throwError() method to allow forward compatibility + * + * This method MUST NOT write out any changes to disk + * + * @param PEAR_PackageFile_v2 + * @param string file contents + * @param string the eventual final file location (informational only) + * @return string|false|PEAR_Error false to skip this file, PEAR_Error to fail + * (use $this->throwError), otherwise return the new contents + * @abstract + */ + public function startSession($pkg, $contents, $dest) + { + } + + /** + * This method is used to process each of the tasks for a particular + * multiple class type. Simple tasks need not implement this method. + * + * @param array an array of tasks + * @access protected + */ + public static function run($tasks) + { + } + + /** + * @final + */ + public static function hasPostinstallTasks() + { + return isset($GLOBALS['_PEAR_TASK_POSTINSTANCES']); + } + + /** + * @final + */ + public static function runPostinstallTasks() + { + foreach ($GLOBALS['_PEAR_TASK_POSTINSTANCES'] as $class => $tasks) { + $err = call_user_func( + array($class, 'run'), + $GLOBALS['_PEAR_TASK_POSTINSTANCES'][$class] + ); + if ($err) { + return PEAR_Task_Common::throwError($err); + } + } + unset($GLOBALS['_PEAR_TASK_POSTINSTANCES']); + } + + /** + * Determines whether a role is a script + * @return bool + */ + public function isScript() + { + return $this->type == 'script'; + } + + public function throwError($msg, $code = -1) + { + include_once 'PEAR.php'; + + return PEAR::raiseError($msg, $code); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Task/Postinstallscript.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Task/Postinstallscript.php new file mode 100644 index 0000000..950deb5 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Task/Postinstallscript.php @@ -0,0 +1,349 @@ + + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ +/** + * Base class + */ +require_once 'PEAR/Task/Common.php'; +/** + * Implements the postinstallscript file task. + * + * Note that post-install scripts are handled separately from installation, by the + * "pear run-scripts" command + * + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Task_Postinstallscript extends PEAR_Task_Common +{ + public $type = 'script'; + public $_class; + public $_params; + public $_obj; + /** + * + * @var PEAR_PackageFile_v2 + */ + public $_pkg; + public $_contents; + public $phase = PEAR_TASK_INSTALL; + + /** + * Validate the raw xml at parsing-time. + * + * This also attempts to validate the script to make sure it meets the criteria + * for a post-install script + * + * @param PEAR_PackageFile_v2 + * @param array The XML contents of the tag + * @param PEAR_Config + * @param array the entire parsed tag + */ + public static function validateXml($pkg, $xml, $config, $fileXml) + { + if ($fileXml['role'] != 'php') { + return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "'. + $fileXml['name'].'" must be role="php"', ); + } + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $file = $pkg->getFileContents($fileXml['name']); + if (PEAR::isError($file)) { + PEAR::popErrorHandling(); + + return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "'. + $fileXml['name'].'" is not valid: '. + $file->getMessage(), ); + } elseif ($file === null) { + return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "'. + $fileXml['name'].'" could not be retrieved for processing!', ); + } else { + $analysis = $pkg->analyzeSourceCode($file, true); + if (!$analysis) { + PEAR::popErrorHandling(); + $warnings = ''; + foreach ($pkg->getValidationWarnings() as $warn) { + $warnings .= $warn['message']."\n"; + } + + return array(PEAR_TASK_ERROR_INVALID, 'Analysis of post-install script "'. + $fileXml['name'].'" failed: '.$warnings, ); + } + if (count($analysis['declared_classes']) != 1) { + PEAR::popErrorHandling(); + + return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "'. + $fileXml['name'].'" must declare exactly 1 class', ); + } + $class = $analysis['declared_classes'][0]; + if ($class != str_replace( + array('/', '.php'), array('_', ''), + $fileXml['name'] + ).'_postinstall') { + PEAR::popErrorHandling(); + + return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "'. + $fileXml['name'].'" class "'.$class.'" must be named "'. + str_replace( + array('/', '.php'), array('_', ''), + $fileXml['name'] + ).'_postinstall"', ); + } + if (!isset($analysis['declared_methods'][$class])) { + PEAR::popErrorHandling(); + + return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "'. + $fileXml['name'].'" must declare methods init() and run()', ); + } + $methods = array('init' => 0, 'run' => 1); + foreach ($analysis['declared_methods'][$class] as $method) { + if (isset($methods[$method])) { + unset($methods[$method]); + } + } + if (count($methods)) { + PEAR::popErrorHandling(); + + return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "'. + $fileXml['name'].'" must declare methods init() and run()', ); + } + } + PEAR::popErrorHandling(); + $definedparams = array(); + $tasksNamespace = $pkg->getTasksNs().':'; + if (!isset($xml[$tasksNamespace.'paramgroup']) && isset($xml['paramgroup'])) { + // in order to support the older betas, which did not expect internal tags + // to also use the namespace + $tasksNamespace = ''; + } + if (isset($xml[$tasksNamespace.'paramgroup'])) { + $params = $xml[$tasksNamespace.'paramgroup']; + if (!is_array($params) || !isset($params[0])) { + $params = array($params); + } + foreach ($params as $param) { + if (!isset($param[$tasksNamespace.'id'])) { + return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "'. + $fileXml['name'].'" must have '. + 'an '.$tasksNamespace.'id> tag', ); + } + if (isset($param[$tasksNamespace.'name'])) { + if (!in_array($param[$tasksNamespace.'name'], $definedparams)) { + return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "'. + $fileXml['name'].'" '.$tasksNamespace. + 'paramgroup> id "'.$param[$tasksNamespace.'id']. + '" parameter "'.$param[$tasksNamespace.'name']. + '" has not been previously defined', ); + } + if (!isset($param[$tasksNamespace.'conditiontype'])) { + return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "'. + $fileXml['name'].'" '.$tasksNamespace. + 'paramgroup> id "'.$param[$tasksNamespace.'id']. + '" must have a '.$tasksNamespace. + 'conditiontype> tag containing either "=", '. + '"!=", or "preg_match"', ); + } + if (!in_array( + $param[$tasksNamespace.'conditiontype'], + array('=', '!=', 'preg_match') + )) { + return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "'. + $fileXml['name'].'" '.$tasksNamespace. + 'paramgroup> id "'.$param[$tasksNamespace.'id']. + '" must have a '.$tasksNamespace. + 'conditiontype> tag containing either "=", '. + '"!=", or "preg_match"', ); + } + if (!isset($param[$tasksNamespace.'value'])) { + return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "'. + $fileXml['name'].'" '.$tasksNamespace. + 'paramgroup> id "'.$param[$tasksNamespace.'id']. + '" must have a '.$tasksNamespace. + 'value> tag containing expected parameter value', ); + } + } + if (isset($param[$tasksNamespace.'instructions'])) { + if (!is_string($param[$tasksNamespace.'instructions'])) { + return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "'. + $fileXml['name'].'" '.$tasksNamespace. + 'paramgroup> id "'.$param[$tasksNamespace.'id']. + '" '.$tasksNamespace.'instructions> must be simple text', ); + } + } + if (!isset($param[$tasksNamespace.'param'])) { + continue; // is no longer required + } + $subparams = $param[$tasksNamespace.'param']; + if (!is_array($subparams) || !isset($subparams[0])) { + $subparams = array($subparams); + } + foreach ($subparams as $subparam) { + if (!isset($subparam[$tasksNamespace.'name'])) { + return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "'. + $fileXml['name'].'" parameter for '. + $tasksNamespace.'paramgroup> id "'. + $param[$tasksNamespace.'id'].'" must have '. + 'a '.$tasksNamespace.'name> tag', ); + } + if (!preg_match( + '/[a-zA-Z0-9]+/', + $subparam[$tasksNamespace.'name'] + )) { + return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "'. + $fileXml['name'].'" parameter "'. + $subparam[$tasksNamespace.'name']. + '" for '.$tasksNamespace.'paramgroup> id "'. + $param[$tasksNamespace.'id']. + '" is not a valid name. Must contain only alphanumeric characters', ); + } + if (!isset($subparam[$tasksNamespace.'prompt'])) { + return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "'. + $fileXml['name'].'" parameter "'. + $subparam[$tasksNamespace.'name']. + '" for '.$tasksNamespace.'paramgroup> id "'. + $param[$tasksNamespace.'id']. + '" must have a '.$tasksNamespace.'prompt> tag', ); + } + if (!isset($subparam[$tasksNamespace.'type'])) { + return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "'. + $fileXml['name'].'" parameter "'. + $subparam[$tasksNamespace.'name']. + '" for '.$tasksNamespace.'paramgroup> id "'. + $param[$tasksNamespace.'id']. + '" must have a '.$tasksNamespace.'type> tag', ); + } + $definedparams[] = $param[$tasksNamespace.'id'].'::'. + $subparam[$tasksNamespace.'name']; + } + } + } + + return true; + } + + /** + * Initialize a task instance with the parameters + * @param array $xml raw, parsed xml + * @param array $fileattribs attributes from the tag containing + * this task + * @param string|null $lastversion last installed version of this package, + * if any (useful for upgrades) + */ + public function init($xml, $fileattribs, $lastversion) + { + $this->_class = str_replace('/', '_', $fileattribs['name']); + $this->_filename = $fileattribs['name']; + $this->_class = str_replace('.php', '', $this->_class).'_postinstall'; + $this->_params = $xml; + $this->_lastversion = $lastversion; + } + + /** + * Strip the tasks: namespace from internal params + * + * @access private + */ + public function _stripNamespace($params = null) + { + if ($params === null) { + $params = array(); + if (!is_array($this->_params)) { + return; + } + foreach ($this->_params as $i => $param) { + if (is_array($param)) { + $param = $this->_stripNamespace($param); + } + $params[str_replace($this->_pkg->getTasksNs().':', '', $i)] = $param; + } + $this->_params = $params; + } else { + $newparams = array(); + foreach ($params as $i => $param) { + if (is_array($param)) { + $param = $this->_stripNamespace($param); + } + $newparams[str_replace($this->_pkg->getTasksNs().':', '', $i)] = $param; + } + + return $newparams; + } + } + + /** + * Unlike other tasks, the installed file name is passed in instead of the + * file contents, because this task is handled post-installation + * + * @param mixed $pkg PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * @param string $contents file name + * + * @return bool|PEAR_Error false to skip this file, PEAR_Error to fail + * (use $this->throwError) + */ + public function startSession($pkg, $contents) + { + if ($this->installphase != PEAR_TASK_INSTALL) { + return false; + } + // remove the tasks: namespace if present + $this->_pkg = $pkg; + $this->_stripNamespace(); + $this->logger->log( + 0, 'Including external post-installation script "'. + $contents.'" - any errors are in this script' + ); + include_once $contents; + if (class_exists($this->_class)) { + $this->logger->log(0, 'Inclusion succeeded'); + } else { + return $this->throwError( + 'init of post-install script class "'.$this->_class + .'" failed' + ); + } + $this->_obj = new $this->_class(); + $this->logger->log(1, 'running post-install script "'.$this->_class.'->init()"'); + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $res = $this->_obj->init($this->config, $pkg, $this->_lastversion); + PEAR::popErrorHandling(); + if ($res) { + $this->logger->log(0, 'init succeeded'); + } else { + return $this->throwError( + 'init of post-install script "'.$this->_class. + '->init()" failed' + ); + } + $this->_contents = $contents; + + return true; + } + + /** + * No longer used + * + * @see PEAR_PackageFile_v2::runPostinstallScripts() + * @param array an array of tasks + * @param string install or upgrade + * @access protected + */ + public static function run() + { + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Task/Postinstallscript/rw.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Task/Postinstallscript/rw.php new file mode 100644 index 0000000..6629600 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Task/Postinstallscript/rw.php @@ -0,0 +1,182 @@ + - read/write version + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a10 + */ +/** + * Base class + */ +require_once 'PEAR/Task/Postinstallscript.php'; +/** + * Abstracts the postinstallscript file task xml. + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a10 + */ +class PEAR_Task_Postinstallscript_rw extends PEAR_Task_Postinstallscript +{ + /** + * parent package file object + * + * @var PEAR_PackageFile_v2_rw + */ + public $_pkg; + /** + * Enter description here... + * + * @param PEAR_PackageFile_v2_rw $pkg Package + * @param PEAR_Config $config Config + * @param PEAR_Frontend $logger Logger + * @param array $fileXml XML + * + * @return PEAR_Task_Postinstallscript_rw + */ + function __construct(&$pkg, &$config, &$logger, $fileXml) + { + parent::__construct($config, $logger, PEAR_TASK_PACKAGE); + $this->_contents = $fileXml; + $this->_pkg = &$pkg; + $this->_params = array(); + } + + public function validate() + { + return $this->validateXml($this->_pkg, $this->_params, $this->config, $this->_contents); + } + + public function getName() + { + return 'postinstallscript'; + } + + /** + * add a simple to the post-install script + * + * Order is significant, so call this method in the same + * sequence the users should see the paramgroups. The $params + * parameter should either be the result of a call to {@link getParam()} + * or an array of calls to getParam(). + * + * Use {@link addConditionTypeGroup()} to add a containing + * a tag + * + * @param string $id id as seen by the script + * @param array|false $params array of getParam() calls, or false for no params + * @param string|false $instructions + */ + public function addParamGroup($id, $params = false, $instructions = false) + { + if ($params && isset($params[0]) && !isset($params[1])) { + $params = $params[0]; + } + $stuff = + array( + $this->_pkg->getTasksNs().':id' => $id, + ); + if ($instructions) { + $stuff[$this->_pkg->getTasksNs().':instructions'] = $instructions; + } + if ($params) { + $stuff[$this->_pkg->getTasksNs().':param'] = $params; + } + $this->_params[$this->_pkg->getTasksNs().':paramgroup'][] = $stuff; + } + + /** + * Add a complex to the post-install script with conditions + * + * This inserts a with + * + * Order is significant, so call this method in the same + * sequence the users should see the paramgroups. The $params + * parameter should either be the result of a call to {@link getParam()} + * or an array of calls to getParam(). + * + * Use {@link addParamGroup()} to add a simple + * + * @param string $id id as seen by the script + * @param string $oldgroup id of the section referenced by + * + * @param string $param name of the from the older section referenced + * by + * @param string $value value to match of the parameter + * @param string $conditiontype one of '=', '!=', 'preg_match' + * @param array|false $params array of getParam() calls, or false for no params + * @param string|false $instructions + */ + public function addConditionTypeGroup($id, + $oldgroup, + $param, + $value, + $conditiontype = '=', + $params = false, + $instructions = false + ) { + if ($params && isset($params[0]) && !isset($params[1])) { + $params = $params[0]; + } + $stuff = array( + $this->_pkg->getTasksNs().':id' => $id, + ); + if ($instructions) { + $stuff[$this->_pkg->getTasksNs().':instructions'] = $instructions; + } + $stuff[$this->_pkg->getTasksNs().':name'] = $oldgroup.'::'.$param; + $stuff[$this->_pkg->getTasksNs().':conditiontype'] = $conditiontype; + $stuff[$this->_pkg->getTasksNs().':value'] = $value; + if ($params) { + $stuff[$this->_pkg->getTasksNs().':param'] = $params; + } + $this->_params[$this->_pkg->getTasksNs().':paramgroup'][] = $stuff; + } + + public function getXml() + { + return $this->_params; + } + + /** + * Use to set up a param tag for use in creating a paramgroup + * + * @param mixed $name Name of parameter + * @param mixed $prompt Prompt + * @param string $type Type, defaults to 'string' + * @param mixed $default Default value + * + * @return array + */ + public static function getParam( + $name, $prompt, $type = 'string', $default = null + ) { + if ($default !== null) { + return + array( + $this->_pkg->getTasksNs().':name' => $name, + $this->_pkg->getTasksNs().':prompt' => $prompt, + $this->_pkg->getTasksNs().':type' => $type, + $this->_pkg->getTasksNs().':default' => $default, + ); + } + + return + array( + $this->_pkg->getTasksNs().':name' => $name, + $this->_pkg->getTasksNs().':prompt' => $prompt, + $this->_pkg->getTasksNs().':type' => $type, + ); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Task/Replace.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Task/Replace.php new file mode 100644 index 0000000..7483282 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Task/Replace.php @@ -0,0 +1,186 @@ + + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ +/** + * Base class + */ +require_once 'PEAR/Task/Common.php'; +/** + * Implements the replace file task. + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Task_Replace extends PEAR_Task_Common +{ + public $type = 'simple'; + public $phase = PEAR_TASK_PACKAGEANDINSTALL; + public $_replacements; + + /** + * Validate the raw xml at parsing-time. + * + * @param PEAR_PackageFile_v2 + * @param array raw, parsed xml + * @param PEAR_Config + */ + public static function validateXml($pkg, $xml, $config, $fileXml) + { + if (!isset($xml['attribs'])) { + return array(PEAR_TASK_ERROR_NOATTRIBS); + } + if (!isset($xml['attribs']['type'])) { + return array(PEAR_TASK_ERROR_MISSING_ATTRIB, 'type'); + } + if (!isset($xml['attribs']['to'])) { + return array(PEAR_TASK_ERROR_MISSING_ATTRIB, 'to'); + } + if (!isset($xml['attribs']['from'])) { + return array(PEAR_TASK_ERROR_MISSING_ATTRIB, 'from'); + } + if ($xml['attribs']['type'] == 'pear-config') { + if (!in_array($xml['attribs']['to'], $config->getKeys())) { + return array(PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE, 'to', $xml['attribs']['to'], + $config->getKeys(), ); + } + } elseif ($xml['attribs']['type'] == 'php-const') { + if (defined($xml['attribs']['to'])) { + return true; + } else { + return array(PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE, 'to', $xml['attribs']['to'], + array('valid PHP constant'), ); + } + } elseif ($xml['attribs']['type'] == 'package-info') { + if (in_array( + $xml['attribs']['to'], + array('name', 'summary', 'channel', 'notes', 'extends', 'description', + 'release_notes', 'license', 'release-license', 'license-uri', + 'version', 'api-version', 'state', 'api-state', 'release_date', + 'date', 'time', ) + )) { + return true; + } else { + return array(PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE, 'to', $xml['attribs']['to'], + array('name', 'summary', 'channel', 'notes', 'extends', 'description', + 'release_notes', 'license', 'release-license', 'license-uri', + 'version', 'api-version', 'state', 'api-state', 'release_date', + 'date', 'time', ), ); + } + } else { + return array(PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE, 'type', $xml['attribs']['type'], + array('pear-config', 'package-info', 'php-const'), ); + } + + return true; + } + + /** + * Initialize a task instance with the parameters + * @param array raw, parsed xml + * @param unused + * @param unused + */ + public function init($xml, $attribs, $lastVersion = null) + { + $this->_replacements = isset($xml['attribs']) ? array($xml) : $xml; + } + + /** + * Do a package.xml 1.0 replacement, with additional package-info fields available + * + * See validateXml() source for the complete list of allowed fields + * + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * @param string file contents + * @param string the eventual final file location (informational only) + * @return string|false|PEAR_Error false to skip this file, PEAR_Error to fail + * (use $this->throwError), otherwise return the new contents + */ + public function startSession($pkg, $contents, $dest) + { + $subst_from = $subst_to = array(); + foreach ($this->_replacements as $a) { + $a = $a['attribs']; + $to = ''; + if ($a['type'] == 'pear-config') { + if ($this->installphase == PEAR_TASK_PACKAGE) { + return false; + } + if ($a['to'] == 'master_server') { + $chan = $this->registry->getChannel($pkg->getChannel()); + if (!PEAR::isError($chan)) { + $to = $chan->getServer(); + } else { + $this->logger->log(0, "$dest: invalid pear-config replacement: $a[to]"); + + return false; + } + } else { + if ($this->config->isDefinedLayer('ftp')) { + // try the remote config file first + $to = $this->config->get($a['to'], 'ftp', $pkg->getChannel()); + if (is_null($to)) { + // then default to local + $to = $this->config->get($a['to'], null, $pkg->getChannel()); + } + } else { + $to = $this->config->get($a['to'], null, $pkg->getChannel()); + } + } + if (is_null($to)) { + $this->logger->log(0, "$dest: invalid pear-config replacement: $a[to]"); + + return false; + } + } elseif ($a['type'] == 'php-const') { + if ($this->installphase == PEAR_TASK_PACKAGE) { + return false; + } + if (defined($a['to'])) { + $to = constant($a['to']); + } else { + $this->logger->log(0, "$dest: invalid php-const replacement: $a[to]"); + + return false; + } + } else { + if ($t = $pkg->packageInfo($a['to'])) { + $to = $t; + } else { + $this->logger->log(0, "$dest: invalid package-info replacement: $a[to]"); + + return false; + } + } + if (!is_null($to)) { + $subst_from[] = $a['from']; + $subst_to[] = $to; + } + } + $this->logger->log( + 3, "doing ".sizeof($subst_from). + " substitution(s) for $dest" + ); + if (sizeof($subst_from)) { + $contents = str_replace($subst_from, $subst_to, $contents); + } + + return $contents; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Task/Replace/rw.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Task/Replace/rw.php new file mode 100644 index 0000000..ace1e9e --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Task/Replace/rw.php @@ -0,0 +1,59 @@ + - read/write version + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a10 + */ +/** + * Base class + */ +require_once 'PEAR/Task/Replace.php'; +/** + * Abstracts the replace task xml. + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a10 + */ +class PEAR_Task_Replace_rw extends PEAR_Task_Replace +{ + public function __construct(&$pkg, &$config, &$logger, $fileXml) + { + parent::__construct($config, $logger, PEAR_TASK_PACKAGE); + $this->_contents = $fileXml; + $this->_pkg = &$pkg; + $this->_params = array(); + } + + public function validate() + { + return $this->validateXml($this->_pkg, $this->_params, $this->config, $this->_contents); + } + + public function setInfo($from, $to, $type) + { + $this->_params = array('attribs' => array('from' => $from, 'to' => $to, 'type' => $type)); + } + + public function getName() + { + return 'replace'; + } + + public function getXml() + { + return $this->_params; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Task/Unixeol.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Task/Unixeol.php new file mode 100644 index 0000000..6ef7174 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Task/Unixeol.php @@ -0,0 +1,79 @@ + + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ +/** + * Base class + */ +require_once 'PEAR/Task/Common.php'; +/** + * Implements the unix line endings file task. + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Task_Unixeol extends PEAR_Task_Common +{ + public $type = 'simple'; + public $phase = PEAR_TASK_PACKAGE; + public $_replacements; + + /** + * Validate the raw xml at parsing-time. + * + * @param PEAR_PackageFile_v2 + * @param array raw, parsed xml + * @param PEAR_Config + */ + public static function validateXml($pkg, $xml, $config, $fileXml) + { + if ($xml != '') { + return array(PEAR_TASK_ERROR_INVALID, 'no attributes allowed'); + } + + return true; + } + + /** + * Initialize a task instance with the parameters + * @param array raw, parsed xml + * @param unused + * @param unused + */ + public function init($xml, $attribs, $lastVersion = null) + { + } + + /** + * Replace all line endings with line endings customized for the current OS + * + * See validateXml() source for the complete list of allowed fields + * + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * @param string file contents + * @param string the eventual final file location (informational only) + * @return string|false|PEAR_Error false to skip this file, PEAR_Error to fail + * (use $this->throwError), otherwise return the new contents + */ + public function startSession($pkg, $contents, $dest) + { + $this->logger->log(3, "replacing all line endings with \\n in $dest"); + + return preg_replace("/\r\n|\n\r|\r|\n/", "\n", $contents); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Task/Unixeol/rw.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Task/Unixeol/rw.php new file mode 100644 index 0000000..9134e2c --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Task/Unixeol/rw.php @@ -0,0 +1,55 @@ + - read/write version + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a10 + */ +/** + * Base class + */ +require_once 'PEAR/Task/Unixeol.php'; +/** + * Abstracts the unixeol task xml. + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a10 + */ +class PEAR_Task_Unixeol_rw extends PEAR_Task_Unixeol +{ + function __construct(&$pkg, &$config, &$logger, $fileXml) + { + parent::__construct($config, $logger, PEAR_TASK_PACKAGE); + $this->_contents = $fileXml; + $this->_pkg = &$pkg; + $this->_params = array(); + } + + public function validate() + { + return true; + } + + public function getName() + { + return 'unixeol'; + } + + public function getXml() + { + return ''; + } +} +?> diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Task/Windowseol.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Task/Windowseol.php new file mode 100644 index 0000000..620c940 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Task/Windowseol.php @@ -0,0 +1,80 @@ + + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ +/** + * Base class + */ +require_once 'PEAR/Task/Common.php'; +/** + * Implements the windows line endsings file task. + * + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Task_Windowseol extends PEAR_Task_Common +{ + public $type = 'simple'; + public $phase = PEAR_TASK_PACKAGE; + public $_replacements; + + /** + * Validate the raw xml at parsing-time. + * + * @param PEAR_PackageFile_v2 + * @param array raw, parsed xml + * @param PEAR_Config + */ + public static function validateXml($pkg, $xml, $config, $fileXml) + { + if ($xml != '') { + return array(PEAR_TASK_ERROR_INVALID, 'no attributes allowed'); + } + + return true; + } + + /** + * Initialize a task instance with the parameters + * @param array raw, parsed xml + * @param unused + * @param unused + */ + public function init($xml, $attribs, $lastVersion = null) + { + } + + /** + * Replace all line endings with windows line endings + * + * See validateXml() source for the complete list of allowed fields + * + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * @param string file contents + * @param string the eventual final file location (informational only) + * @return string|false|PEAR_Error false to skip this file, PEAR_Error to fail + * (use $this->throwError), otherwise return the new contents + */ + public function startSession($pkg, $contents, $dest) + { + $this->logger->log(3, "replacing all line endings with \\r\\n in $dest"); + + return preg_replace("/\r\n|\n\r|\r|\n/", "\r\n", $contents); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Task/Windowseol/rw.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Task/Windowseol/rw.php new file mode 100644 index 0000000..e3cf005 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Task/Windowseol/rw.php @@ -0,0 +1,56 @@ + - read/write version + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a10 + */ +/** + * Base class + */ +require_once 'PEAR/Task/Windowseol.php'; +/** + * Abstracts the windowseol task xml. + * + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a10 + */ +class PEAR_Task_Windowseol_rw extends PEAR_Task_Windowseol +{ + function __construct(&$pkg, &$config, &$logger, $fileXml) + { + parent::__construct($config, $logger, PEAR_TASK_PACKAGE); + $this->_contents = $fileXml; + $this->_pkg = &$pkg; + $this->_params = array(); + } + + public function validate() + { + return true; + } + + public function getName() + { + return 'windowseol'; + } + + public function getXml() + { + return ''; + } +} +?> diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Validate.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Validate.php new file mode 100644 index 0000000..8e29b7c --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Validate.php @@ -0,0 +1,625 @@ + + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ +/**#@+ + * Constants for install stage + */ +define('PEAR_VALIDATE_INSTALLING', 1); +define('PEAR_VALIDATE_UNINSTALLING', 2); // this is not bit-mapped like the others +define('PEAR_VALIDATE_NORMAL', 3); +define('PEAR_VALIDATE_DOWNLOADING', 4); // this is not bit-mapped like the others +define('PEAR_VALIDATE_PACKAGING', 7); +/**#@-*/ +require_once 'PEAR/Common.php'; +require_once 'PEAR/Validator/PECL.php'; + +/** + * Validation class for package.xml - channel-level advanced validation + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Validate +{ + var $packageregex = _PEAR_COMMON_PACKAGE_NAME_PREG; + /** + * @var PEAR_PackageFile_v1|PEAR_PackageFile_v2 + */ + var $_packagexml; + /** + * @var int one of the PEAR_VALIDATE_* constants + */ + var $_state = PEAR_VALIDATE_NORMAL; + /** + * Format: ('error' => array('field' => name, 'reason' => reason), 'warning' => same) + * @var array + * @access private + */ + var $_failures = array('error' => array(), 'warning' => array()); + + /** + * Override this method to handle validation of normal package names + * @param string + * @return bool + * @access protected + */ + function _validPackageName($name) + { + return (bool) preg_match('/^' . $this->packageregex . '\\z/', $name); + } + + /** + * @param string package name to validate + * @param string name of channel-specific validation package + * @final + */ + function validPackageName($name, $validatepackagename = false) + { + if ($validatepackagename) { + if (strtolower($name) == strtolower($validatepackagename)) { + return (bool) preg_match('/^[a-zA-Z0-9_]+(?:\.[a-zA-Z0-9_]+)*\\z/', $name); + } + } + return $this->_validPackageName($name); + } + + /** + * This validates a bundle name, and bundle names must conform + * to the PEAR naming convention, so the method is final and static. + * @param string + * @final + */ + public static function validGroupName($name) + { + return (bool) preg_match('/^' . _PEAR_COMMON_PACKAGE_NAME_PREG . '\\z/', $name); + } + + /** + * Determine whether $state represents a valid stability level + * @param string + * @return bool + * @final + */ + public static function validState($state) + { + return in_array($state, array('snapshot', 'devel', 'alpha', 'beta', 'stable')); + } + + /** + * Get a list of valid stability levels + * @return array + * @final + */ + public static function getValidStates() + { + return array('snapshot', 'devel', 'alpha', 'beta', 'stable'); + } + + /** + * Determine whether a version is a properly formatted version number that can be used + * by version_compare + * @param string + * @return bool + * @final + */ + public static function validVersion($ver) + { + return (bool) preg_match(PEAR_COMMON_PACKAGE_VERSION_PREG, $ver); + } + + /** + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 + */ + function setPackageFile(&$pf) + { + $this->_packagexml = &$pf; + } + + /** + * @access private + */ + function _addFailure($field, $reason) + { + $this->_failures['errors'][] = array('field' => $field, 'reason' => $reason); + } + + /** + * @access private + */ + function _addWarning($field, $reason) + { + $this->_failures['warnings'][] = array('field' => $field, 'reason' => $reason); + } + + function getFailures() + { + $failures = $this->_failures; + $this->_failures = array('warnings' => array(), 'errors' => array()); + return $failures; + } + + /** + * @param int one of the PEAR_VALIDATE_* constants + */ + function validate($state = null) + { + if (!isset($this->_packagexml)) { + return false; + } + if ($state !== null) { + $this->_state = $state; + } + $this->_failures = array('warnings' => array(), 'errors' => array()); + $this->validatePackageName(); + $this->validateVersion(); + $this->validateMaintainers(); + $this->validateDate(); + $this->validateSummary(); + $this->validateDescription(); + $this->validateLicense(); + $this->validateNotes(); + if ($this->_packagexml->getPackagexmlVersion() == '1.0') { + $this->validateState(); + $this->validateFilelist(); + } elseif ($this->_packagexml->getPackagexmlVersion() == '2.0' || + $this->_packagexml->getPackagexmlVersion() == '2.1') { + $this->validateTime(); + $this->validateStability(); + $this->validateDeps(); + $this->validateMainFilelist(); + $this->validateReleaseFilelist(); + //$this->validateGlobalTasks(); + $this->validateChangelog(); + } + return !((bool) count($this->_failures['errors'])); + } + + /** + * @access protected + */ + function validatePackageName() + { + if ($this->_state == PEAR_VALIDATE_PACKAGING || + $this->_state == PEAR_VALIDATE_NORMAL) { + if (($this->_packagexml->getPackagexmlVersion() == '2.0' || + $this->_packagexml->getPackagexmlVersion() == '2.1') && + $this->_packagexml->getExtends()) { + $version = $this->_packagexml->getVersion() . ''; + $name = $this->_packagexml->getPackage(); + $a = explode('.', $version); + $test = array_shift($a); + if ($test == '0') { + return true; + } + $vlen = strlen($test); + $majver = substr($name, strlen($name) - $vlen); + while ($majver && !is_numeric($majver{0})) { + $majver = substr($majver, 1); + } + if ($majver != $test) { + $this->_addWarning('package', "package $name extends package " . + $this->_packagexml->getExtends() . ' and so the name should ' . + 'have a postfix equal to the major version like "' . + $this->_packagexml->getExtends() . $test . '"'); + return true; + } elseif (substr($name, 0, strlen($name) - $vlen) != + $this->_packagexml->getExtends()) { + $this->_addWarning('package', "package $name extends package " . + $this->_packagexml->getExtends() . ' and so the name must ' . + 'be an extension like "' . $this->_packagexml->getExtends() . + $test . '"'); + return true; + } + } + } + if (!$this->validPackageName($this->_packagexml->getPackage())) { + $this->_addFailure('name', 'package name "' . + $this->_packagexml->getPackage() . '" is invalid'); + return false; + } + } + + /** + * @access protected + */ + function validateVersion() + { + if ($this->_state != PEAR_VALIDATE_PACKAGING) { + if (!$this->validVersion($this->_packagexml->getVersion())) { + $this->_addFailure('version', + 'Invalid version number "' . $this->_packagexml->getVersion() . '"'); + } + return false; + } + $version = $this->_packagexml->getVersion(); + $versioncomponents = explode('.', $version); + if (count($versioncomponents) != 3) { + $this->_addWarning('version', + 'A version number should have 3 decimals (x.y.z)'); + return true; + } + $name = $this->_packagexml->getPackage(); + // version must be based upon state + switch ($this->_packagexml->getState()) { + case 'snapshot' : + return true; + case 'devel' : + if ($versioncomponents[0] . 'a' == '0a') { + return true; + } + if ($versioncomponents[0] == 0) { + $versioncomponents[0] = '0'; + $this->_addWarning('version', + 'version "' . $version . '" should be "' . + implode('.' ,$versioncomponents) . '"'); + } else { + $this->_addWarning('version', + 'packages with devel stability must be < version 1.0.0'); + } + return true; + break; + case 'alpha' : + case 'beta' : + // check for a package that extends a package, + // like Foo and Foo2 + if ($this->_state == PEAR_VALIDATE_PACKAGING) { + if (substr($versioncomponents[2], 1, 2) == 'rc') { + $this->_addFailure('version', 'Release Candidate versions ' . + 'must have capital RC, not lower-case rc'); + return false; + } + } + if (!$this->_packagexml->getExtends()) { + if ($versioncomponents[0] == '1') { + if ($versioncomponents[2]{0} == '0') { + if ($versioncomponents[2] == '0') { + // version 1.*.0000 + $this->_addWarning('version', + 'version 1.' . $versioncomponents[1] . + '.0 probably should not be alpha or beta'); + return true; + } elseif (strlen($versioncomponents[2]) > 1) { + // version 1.*.0RC1 or 1.*.0beta24 etc. + return true; + } else { + // version 1.*.0 + $this->_addWarning('version', + 'version 1.' . $versioncomponents[1] . + '.0 probably should not be alpha or beta'); + return true; + } + } else { + $this->_addWarning('version', + 'bugfix versions (1.3.x where x > 0) probably should ' . + 'not be alpha or beta'); + return true; + } + } elseif ($versioncomponents[0] != '0') { + $this->_addWarning('version', + 'major versions greater than 1 are not allowed for packages ' . + 'without an tag or an identical postfix (foo2 v2.0.0)'); + return true; + } + if ($versioncomponents[0] . 'a' == '0a') { + return true; + } + if ($versioncomponents[0] == 0) { + $versioncomponents[0] = '0'; + $this->_addWarning('version', + 'version "' . $version . '" should be "' . + implode('.' ,$versioncomponents) . '"'); + } + } else { + $vlen = strlen($versioncomponents[0] . ''); + $majver = substr($name, strlen($name) - $vlen); + while ($majver && !is_numeric($majver{0})) { + $majver = substr($majver, 1); + } + if (($versioncomponents[0] != 0) && $majver != $versioncomponents[0]) { + $this->_addWarning('version', 'first version number "' . + $versioncomponents[0] . '" must match the postfix of ' . + 'package name "' . $name . '" (' . + $majver . ')'); + return true; + } + if ($versioncomponents[0] == $majver) { + if ($versioncomponents[2]{0} == '0') { + if ($versioncomponents[2] == '0') { + // version 2.*.0000 + $this->_addWarning('version', + "version $majver." . $versioncomponents[1] . + '.0 probably should not be alpha or beta'); + return false; + } elseif (strlen($versioncomponents[2]) > 1) { + // version 2.*.0RC1 or 2.*.0beta24 etc. + return true; + } else { + // version 2.*.0 + $this->_addWarning('version', + "version $majver." . $versioncomponents[1] . + '.0 cannot be alpha or beta'); + return true; + } + } else { + $this->_addWarning('version', + "bugfix versions ($majver.x.y where y > 0) should " . + 'not be alpha or beta'); + return true; + } + } elseif ($versioncomponents[0] != '0') { + $this->_addWarning('version', + "only versions 0.x.y and $majver.x.y are allowed for alpha/beta releases"); + return true; + } + if ($versioncomponents[0] . 'a' == '0a') { + return true; + } + if ($versioncomponents[0] == 0) { + $versioncomponents[0] = '0'; + $this->_addWarning('version', + 'version "' . $version . '" should be "' . + implode('.' ,$versioncomponents) . '"'); + } + } + return true; + break; + case 'stable' : + if ($versioncomponents[0] == '0') { + $this->_addWarning('version', 'versions less than 1.0.0 cannot ' . + 'be stable'); + return true; + } + if (!is_numeric($versioncomponents[2])) { + if (preg_match('/\d+(rc|a|alpha|b|beta)\d*/i', + $versioncomponents[2])) { + $this->_addWarning('version', 'version "' . $version . '" or any ' . + 'RC/beta/alpha version cannot be stable'); + return true; + } + } + // check for a package that extends a package, + // like Foo and Foo2 + if ($this->_packagexml->getExtends()) { + $vlen = strlen($versioncomponents[0] . ''); + $majver = substr($name, strlen($name) - $vlen); + while ($majver && !is_numeric($majver{0})) { + $majver = substr($majver, 1); + } + if (($versioncomponents[0] != 0) && $majver != $versioncomponents[0]) { + $this->_addWarning('version', 'first version number "' . + $versioncomponents[0] . '" must match the postfix of ' . + 'package name "' . $name . '" (' . + $majver . ')'); + return true; + } + } elseif ($versioncomponents[0] > 1) { + $this->_addWarning('version', 'major version x in x.y.z may not be greater than ' . + '1 for any package that does not have an tag'); + } + return true; + break; + default : + return false; + break; + } + } + + /** + * @access protected + */ + function validateMaintainers() + { + // maintainers can only be truly validated server-side for most channels + // but allow this customization for those who wish it + return true; + } + + /** + * @access protected + */ + function validateDate() + { + if ($this->_state == PEAR_VALIDATE_NORMAL || + $this->_state == PEAR_VALIDATE_PACKAGING) { + + if (!preg_match('/(\d\d\d\d)\-(\d\d)\-(\d\d)/', + $this->_packagexml->getDate(), $res) || + count($res) < 4 + || !checkdate($res[2], $res[3], $res[1]) + ) { + $this->_addFailure('date', 'invalid release date "' . + $this->_packagexml->getDate() . '"'); + return false; + } + + if ($this->_state == PEAR_VALIDATE_PACKAGING && + $this->_packagexml->getDate() != date('Y-m-d')) { + $this->_addWarning('date', 'Release Date "' . + $this->_packagexml->getDate() . '" is not today'); + } + } + return true; + } + + /** + * @access protected + */ + function validateTime() + { + if (!$this->_packagexml->getTime()) { + // default of no time value set + return true; + } + + // packager automatically sets time, so only validate if pear validate is called + if ($this->_state = PEAR_VALIDATE_NORMAL) { + if (!preg_match('/\d\d:\d\d:\d\d/', + $this->_packagexml->getTime())) { + $this->_addFailure('time', 'invalid release time "' . + $this->_packagexml->getTime() . '"'); + return false; + } + + $result = preg_match('|\d{2}\:\d{2}\:\d{2}|', $this->_packagexml->getTime(), $matches); + if ($result === false || empty($matches)) { + $this->_addFailure('time', 'invalid release time "' . + $this->_packagexml->getTime() . '"'); + return false; + } + } + + return true; + } + + /** + * @access protected + */ + function validateState() + { + // this is the closest to "final" php4 can get + if (!PEAR_Validate::validState($this->_packagexml->getState())) { + if (strtolower($this->_packagexml->getState() == 'rc')) { + $this->_addFailure('state', 'RC is not a state, it is a version ' . + 'postfix, use ' . $this->_packagexml->getVersion() . 'RC1, state beta'); + } + $this->_addFailure('state', 'invalid release state "' . + $this->_packagexml->getState() . '", must be one of: ' . + implode(', ', PEAR_Validate::getValidStates())); + return false; + } + return true; + } + + /** + * @access protected + */ + function validateStability() + { + $ret = true; + $packagestability = $this->_packagexml->getState(); + $apistability = $this->_packagexml->getState('api'); + if (!PEAR_Validate::validState($packagestability)) { + $this->_addFailure('state', 'invalid release stability "' . + $this->_packagexml->getState() . '", must be one of: ' . + implode(', ', PEAR_Validate::getValidStates())); + $ret = false; + } + $apistates = PEAR_Validate::getValidStates(); + array_shift($apistates); // snapshot is not allowed + if (!in_array($apistability, $apistates)) { + $this->_addFailure('state', 'invalid API stability "' . + $this->_packagexml->getState('api') . '", must be one of: ' . + implode(', ', $apistates)); + $ret = false; + } + return $ret; + } + + /** + * @access protected + */ + function validateSummary() + { + return true; + } + + /** + * @access protected + */ + function validateDescription() + { + return true; + } + + /** + * @access protected + */ + function validateLicense() + { + return true; + } + + /** + * @access protected + */ + function validateNotes() + { + return true; + } + + /** + * for package.xml 2.0 only - channels can't use package.xml 1.0 + * @access protected + */ + function validateDependencies() + { + return true; + } + + /** + * for package.xml 1.0 only + * @access private + */ + function _validateFilelist() + { + return true; // placeholder for now + } + + /** + * for package.xml 2.0 only + * @access protected + */ + function validateMainFilelist() + { + return true; // placeholder for now + } + + /** + * for package.xml 2.0 only + * @access protected + */ + function validateReleaseFilelist() + { + return true; // placeholder for now + } + + /** + * @access protected + */ + function validateChangelog() + { + return true; + } + + /** + * @access protected + */ + function validateFilelist() + { + return true; + } + + /** + * @access protected + */ + function validateDeps() + { + return true; + } +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Validator/PECL.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Validator/PECL.php new file mode 100644 index 0000000..830c8e9 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/Validator/PECL.php @@ -0,0 +1,62 @@ + + * @copyright 1997-2006 The PHP Group + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a5 + */ +/** + * This is the parent class for all validators + */ +require_once 'PEAR/Validate.php'; +/** + * Channel Validator for the pecl.php.net channel + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a5 + */ +class PEAR_Validator_PECL extends PEAR_Validate +{ + function validateVersion() + { + if ($this->_state == PEAR_VALIDATE_PACKAGING) { + $version = $this->_packagexml->getVersion(); + $versioncomponents = explode('.', $version); + $last = array_pop($versioncomponents); + if (substr($last, 1, 2) == 'rc') { + $this->_addFailure('version', 'Release Candidate versions must have ' . + 'upper-case RC, not lower-case rc'); + return false; + } + } + return true; + } + + function validatePackageName() + { + $ret = parent::validatePackageName(); + if ($this->_packagexml->getPackageType() == 'extsrc' || + $this->_packagexml->getPackageType() == 'zendextsrc') { + if (strtolower($this->_packagexml->getPackage()) != + strtolower($this->_packagexml->getProvidesExtension())) { + $this->_addWarning('providesextension', 'package name "' . + $this->_packagexml->getPackage() . '" is different from extension name "' . + $this->_packagexml->getProvidesExtension() . '"'); + } + } + return $ret; + } +} +?> \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/XMLParser.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/XMLParser.php new file mode 100644 index 0000000..619743b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/PEAR/XMLParser.php @@ -0,0 +1,247 @@ + + * @author Stephan Schmidt (original XML_Unserializer code) + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * Parser for any xml file + * @category pear + * @package PEAR + * @author Greg Beaver + * @author Stephan Schmidt (original XML_Unserializer code) + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license New BSD License + * @version Release: 1.10.1 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_XMLParser +{ + /** + * unserilialized data + * @var string $_serializedData + */ + var $_unserializedData = null; + + /** + * name of the root tag + * @var string $_root + */ + var $_root = null; + + /** + * stack for all data that is found + * @var array $_dataStack + */ + var $_dataStack = array(); + + /** + * stack for all values that are generated + * @var array $_valStack + */ + var $_valStack = array(); + + /** + * current tag depth + * @var int $_depth + */ + var $_depth = 0; + + /** + * The XML encoding to use + * @var string $encoding + */ + var $encoding = 'ISO-8859-1'; + + /** + * @return array + */ + function getData() + { + return $this->_unserializedData; + } + + /** + * @param string xml content + * @return true|PEAR_Error + */ + function parse($data) + { + if (!extension_loaded('xml')) { + include_once 'PEAR.php'; + return PEAR::raiseError("XML Extension not found", 1); + } + $this->_dataStack = $this->_valStack = array(); + $this->_depth = 0; + + if ( + strpos($data, 'encoding="UTF-8"') + || strpos($data, 'encoding="utf-8"') + || strpos($data, "encoding='UTF-8'") + || strpos($data, "encoding='utf-8'") + ) { + $this->encoding = 'UTF-8'; + } + + $xp = xml_parser_create($this->encoding); + xml_parser_set_option($xp, XML_OPTION_CASE_FOLDING, 0); + xml_set_object($xp, $this); + xml_set_element_handler($xp, 'startHandler', 'endHandler'); + xml_set_character_data_handler($xp, 'cdataHandler'); + if (!xml_parse($xp, $data)) { + $msg = xml_error_string(xml_get_error_code($xp)); + $line = xml_get_current_line_number($xp); + xml_parser_free($xp); + include_once 'PEAR.php'; + return PEAR::raiseError("XML Error: '$msg' on line '$line'", 2); + } + xml_parser_free($xp); + return true; + } + + /** + * Start element handler for XML parser + * + * @access private + * @param object $parser XML parser object + * @param string $element XML element + * @param array $attribs attributes of XML tag + * @return void + */ + function startHandler($parser, $element, $attribs) + { + $this->_depth++; + $this->_dataStack[$this->_depth] = null; + + $val = array( + 'name' => $element, + 'value' => null, + 'type' => 'string', + 'childrenKeys' => array(), + 'aggregKeys' => array() + ); + + if (count($attribs) > 0) { + $val['children'] = array(); + $val['type'] = 'array'; + $val['children']['attribs'] = $attribs; + } + + array_push($this->_valStack, $val); + } + + /** + * post-process data + * + * @param string $data + * @param string $element element name + */ + function postProcess($data, $element) + { + return trim($data); + } + + /** + * End element handler for XML parser + * + * @access private + * @param object XML parser object + * @param string + * @return void + */ + function endHandler($parser, $element) + { + $value = array_pop($this->_valStack); + $data = $this->postProcess($this->_dataStack[$this->_depth], $element); + + // adjust type of the value + switch (strtolower($value['type'])) { + // unserialize an array + case 'array': + if ($data !== '') { + $value['children']['_content'] = $data; + } + + $value['value'] = isset($value['children']) ? $value['children'] : array(); + break; + + /* + * unserialize a null value + */ + case 'null': + $data = null; + break; + + /* + * unserialize any scalar value + */ + default: + settype($data, $value['type']); + $value['value'] = $data; + break; + } + + $parent = array_pop($this->_valStack); + if ($parent === null) { + $this->_unserializedData = &$value['value']; + $this->_root = &$value['name']; + return true; + } + + // parent has to be an array + if (!isset($parent['children']) || !is_array($parent['children'])) { + $parent['children'] = array(); + if ($parent['type'] != 'array') { + $parent['type'] = 'array'; + } + } + + if (!empty($value['name'])) { + // there already has been a tag with this name + if (in_array($value['name'], $parent['childrenKeys'])) { + // no aggregate has been created for this tag + if (!in_array($value['name'], $parent['aggregKeys'])) { + if (isset($parent['children'][$value['name']])) { + $parent['children'][$value['name']] = array($parent['children'][$value['name']]); + } else { + $parent['children'][$value['name']] = array(); + } + array_push($parent['aggregKeys'], $value['name']); + } + array_push($parent['children'][$value['name']], $value['value']); + } else { + $parent['children'][$value['name']] = &$value['value']; + array_push($parent['childrenKeys'], $value['name']); + } + } else { + array_push($parent['children'],$value['value']); + } + array_push($this->_valStack, $parent); + + $this->_depth--; + } + + /** + * Handler for character data + * + * @access private + * @param object XML parser object + * @param string CDATA + * @return void + */ + function cdataHandler($parser, $cdata) + { + $this->_dataStack[$this->_depth] .= $cdata; + } +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/System.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/System.php new file mode 100644 index 0000000..9ff3fed --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/System.php @@ -0,0 +1,622 @@ + + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + * @since File available since Release 0.1 + */ + +/** + * base class + */ +require_once 'PEAR.php'; +require_once 'Console/Getopt.php'; + +$GLOBALS['_System_temp_files'] = array(); + +/** +* System offers cross plattform compatible system functions +* +* Static functions for different operations. Should work under +* Unix and Windows. The names and usage has been taken from its respectively +* GNU commands. The functions will return (bool) false on error and will +* trigger the error with the PHP trigger_error() function (you can silence +* the error by prefixing a '@' sign after the function call, but this +* is not recommended practice. Instead use an error handler with +* {@link set_error_handler()}). +* +* Documentation on this class you can find in: +* http://pear.php.net/manual/ +* +* Example usage: +* if (!@System::rm('-r file1 dir1')) { +* print "could not delete file1 or dir1"; +* } +* +* In case you need to to pass file names with spaces, +* pass the params as an array: +* +* System::rm(array('-r', $file1, $dir1)); +* +* @category pear +* @package System +* @author Tomas V.V. Cox +* @copyright 1997-2006 The PHP Group +* @license http://opensource.org/licenses/bsd-license.php New BSD License +* @version Release: 1.10.1 +* @link http://pear.php.net/package/PEAR +* @since Class available since Release 0.1 +* @static +*/ +class System +{ + /** + * returns the commandline arguments of a function + * + * @param string $argv the commandline + * @param string $short_options the allowed option short-tags + * @param string $long_options the allowed option long-tags + * @return array the given options and there values + */ + public static function _parseArgs($argv, $short_options, $long_options = null) + { + if (!is_array($argv) && $argv !== null) { + /* + // Quote all items that are a short option + $av = preg_split('/(\A| )--?[a-z0-9]+[ =]?((? $a) { + if (empty($a)) { + continue; + } + $argv[$k] = trim($a) ; + } + } + + return Console_Getopt::getopt2($argv, $short_options, $long_options); + } + + /** + * Output errors with PHP trigger_error(). You can silence the errors + * with prefixing a "@" sign to the function call: @System::mkdir(..); + * + * @param mixed $error a PEAR error or a string with the error message + * @return bool false + */ + protected static function raiseError($error) + { + if (PEAR::isError($error)) { + $error = $error->getMessage(); + } + trigger_error($error, E_USER_WARNING); + return false; + } + + /** + * Creates a nested array representing the structure of a directory + * + * System::_dirToStruct('dir1', 0) => + * Array + * ( + * [dirs] => Array + * ( + * [0] => dir1 + * ) + * + * [files] => Array + * ( + * [0] => dir1/file2 + * [1] => dir1/file3 + * ) + * ) + * @param string $sPath Name of the directory + * @param integer $maxinst max. deep of the lookup + * @param integer $aktinst starting deep of the lookup + * @param bool $silent if true, do not emit errors. + * @return array the structure of the dir + */ + protected static function _dirToStruct($sPath, $maxinst, $aktinst = 0, $silent = false) + { + $struct = array('dirs' => array(), 'files' => array()); + if (($dir = @opendir($sPath)) === false) { + if (!$silent) { + System::raiseError("Could not open dir $sPath"); + } + return $struct; // XXX could not open error + } + + $struct['dirs'][] = $sPath = realpath($sPath); // XXX don't add if '.' or '..' ? + $list = array(); + while (false !== ($file = readdir($dir))) { + if ($file != '.' && $file != '..') { + $list[] = $file; + } + } + + closedir($dir); + natsort($list); + if ($aktinst < $maxinst || $maxinst == 0) { + foreach ($list as $val) { + $path = $sPath . DIRECTORY_SEPARATOR . $val; + if (is_dir($path) && !is_link($path)) { + $tmp = System::_dirToStruct($path, $maxinst, $aktinst+1, $silent); + $struct = array_merge_recursive($struct, $tmp); + } else { + $struct['files'][] = $path; + } + } + } + + return $struct; + } + + /** + * Creates a nested array representing the structure of a directory and files + * + * @param array $files Array listing files and dirs + * @return array + * @static + * @see System::_dirToStruct() + */ + protected static function _multipleToStruct($files) + { + $struct = array('dirs' => array(), 'files' => array()); + settype($files, 'array'); + foreach ($files as $file) { + if (is_dir($file) && !is_link($file)) { + $tmp = System::_dirToStruct($file, 0); + $struct = array_merge_recursive($tmp, $struct); + } else { + if (!in_array($file, $struct['files'])) { + $struct['files'][] = $file; + } + } + } + return $struct; + } + + /** + * The rm command for removing files. + * Supports multiple files and dirs and also recursive deletes + * + * @param string $args the arguments for rm + * @return mixed PEAR_Error or true for success + * @static + * @access public + */ + public static function rm($args) + { + $opts = System::_parseArgs($args, 'rf'); // "f" does nothing but I like it :-) + if (PEAR::isError($opts)) { + return System::raiseError($opts); + } + foreach ($opts[0] as $opt) { + if ($opt[0] == 'r') { + $do_recursive = true; + } + } + $ret = true; + if (isset($do_recursive)) { + $struct = System::_multipleToStruct($opts[1]); + foreach ($struct['files'] as $file) { + if (!@unlink($file)) { + $ret = false; + } + } + + rsort($struct['dirs']); + foreach ($struct['dirs'] as $dir) { + if (!@rmdir($dir)) { + $ret = false; + } + } + } else { + foreach ($opts[1] as $file) { + $delete = (is_dir($file)) ? 'rmdir' : 'unlink'; + if (!@$delete($file)) { + $ret = false; + } + } + } + return $ret; + } + + /** + * Make directories. + * + * The -p option will create parent directories + * @param string $args the name of the director(y|ies) to create + * @return bool True for success + */ + public static function mkDir($args) + { + $opts = System::_parseArgs($args, 'pm:'); + if (PEAR::isError($opts)) { + return System::raiseError($opts); + } + + $mode = 0777; // default mode + foreach ($opts[0] as $opt) { + if ($opt[0] == 'p') { + $create_parents = true; + } elseif ($opt[0] == 'm') { + // if the mode is clearly an octal number (starts with 0) + // convert it to decimal + if (strlen($opt[1]) && $opt[1]{0} == '0') { + $opt[1] = octdec($opt[1]); + } else { + // convert to int + $opt[1] += 0; + } + $mode = $opt[1]; + } + } + + $ret = true; + if (isset($create_parents)) { + foreach ($opts[1] as $dir) { + $dirstack = array(); + while ((!file_exists($dir) || !is_dir($dir)) && + $dir != DIRECTORY_SEPARATOR) { + array_unshift($dirstack, $dir); + $dir = dirname($dir); + } + + while ($newdir = array_shift($dirstack)) { + if (!is_writeable(dirname($newdir))) { + $ret = false; + break; + } + + if (!mkdir($newdir, $mode)) { + $ret = false; + } + } + } + } else { + foreach($opts[1] as $dir) { + if ((@file_exists($dir) || !is_dir($dir)) && !mkdir($dir, $mode)) { + $ret = false; + } + } + } + + return $ret; + } + + /** + * Concatenate files + * + * Usage: + * 1) $var = System::cat('sample.txt test.txt'); + * 2) System::cat('sample.txt test.txt > final.txt'); + * 3) System::cat('sample.txt test.txt >> final.txt'); + * + * Note: as the class use fopen, urls should work also (test that) + * + * @param string $args the arguments + * @return boolean true on success + */ + public static function &cat($args) + { + $ret = null; + $files = array(); + if (!is_array($args)) { + $args = preg_split('/\s+/', $args, -1, PREG_SPLIT_NO_EMPTY); + } + + $count_args = count($args); + for ($i = 0; $i < $count_args; $i++) { + if ($args[$i] == '>') { + $mode = 'wb'; + $outputfile = $args[$i+1]; + break; + } elseif ($args[$i] == '>>') { + $mode = 'ab+'; + $outputfile = $args[$i+1]; + break; + } else { + $files[] = $args[$i]; + } + } + $outputfd = false; + if (isset($mode)) { + if (!$outputfd = fopen($outputfile, $mode)) { + $err = System::raiseError("Could not open $outputfile"); + return $err; + } + $ret = true; + } + foreach ($files as $file) { + if (!$fd = fopen($file, 'r')) { + System::raiseError("Could not open $file"); + continue; + } + while ($cont = fread($fd, 2048)) { + if (is_resource($outputfd)) { + fwrite($outputfd, $cont); + } else { + $ret .= $cont; + } + } + fclose($fd); + } + if (is_resource($outputfd)) { + fclose($outputfd); + } + return $ret; + } + + /** + * Creates temporary files or directories. This function will remove + * the created files when the scripts finish its execution. + * + * Usage: + * 1) $tempfile = System::mktemp("prefix"); + * 2) $tempdir = System::mktemp("-d prefix"); + * 3) $tempfile = System::mktemp(); + * 4) $tempfile = System::mktemp("-t /var/tmp prefix"); + * + * prefix -> The string that will be prepended to the temp name + * (defaults to "tmp"). + * -d -> A temporary dir will be created instead of a file. + * -t -> The target dir where the temporary (file|dir) will be created. If + * this param is missing by default the env vars TMP on Windows or + * TMPDIR in Unix will be used. If these vars are also missing + * c:\windows\temp or /tmp will be used. + * + * @param string $args The arguments + * @return mixed the full path of the created (file|dir) or false + * @see System::tmpdir() + */ + public static function mktemp($args = null) + { + static $first_time = true; + $opts = System::_parseArgs($args, 't:d'); + if (PEAR::isError($opts)) { + return System::raiseError($opts); + } + + foreach ($opts[0] as $opt) { + if ($opt[0] == 'd') { + $tmp_is_dir = true; + } elseif ($opt[0] == 't') { + $tmpdir = $opt[1]; + } + } + + $prefix = (isset($opts[1][0])) ? $opts[1][0] : 'tmp'; + if (!isset($tmpdir)) { + $tmpdir = System::tmpdir(); + } + + if (!System::mkDir(array('-p', $tmpdir))) { + return false; + } + + $tmp = tempnam($tmpdir, $prefix); + if (isset($tmp_is_dir)) { + unlink($tmp); // be careful possible race condition here + if (!mkdir($tmp, 0700)) { + return System::raiseError("Unable to create temporary directory $tmpdir"); + } + } + + $GLOBALS['_System_temp_files'][] = $tmp; + if (isset($tmp_is_dir)) { + //$GLOBALS['_System_temp_files'][] = dirname($tmp); + } + + if ($first_time) { + PEAR::registerShutdownFunc(array('System', '_removeTmpFiles')); + $first_time = false; + } + + return $tmp; + } + + /** + * Remove temporary files created my mkTemp. This function is executed + * at script shutdown time + */ + public static function _removeTmpFiles() + { + if (count($GLOBALS['_System_temp_files'])) { + $delete = $GLOBALS['_System_temp_files']; + array_unshift($delete, '-r'); + System::rm($delete); + $GLOBALS['_System_temp_files'] = array(); + } + } + + /** + * Get the path of the temporal directory set in the system + * by looking in its environments variables. + * Note: php.ini-recommended removes the "E" from the variables_order setting, + * making unavaible the $_ENV array, that s why we do tests with _ENV + * + * @return string The temporary directory on the system + */ + public static function tmpdir() + { + if (OS_WINDOWS) { + if ($var = isset($_ENV['TMP']) ? $_ENV['TMP'] : getenv('TMP')) { + return $var; + } + if ($var = isset($_ENV['TEMP']) ? $_ENV['TEMP'] : getenv('TEMP')) { + return $var; + } + if ($var = isset($_ENV['USERPROFILE']) ? $_ENV['USERPROFILE'] : getenv('USERPROFILE')) { + return $var; + } + if ($var = isset($_ENV['windir']) ? $_ENV['windir'] : getenv('windir')) { + return $var; + } + return getenv('SystemRoot') . '\temp'; + } + if ($var = isset($_ENV['TMPDIR']) ? $_ENV['TMPDIR'] : getenv('TMPDIR')) { + return $var; + } + return realpath('/tmp'); + } + + /** + * The "which" command (show the full path of a command) + * + * @param string $program The command to search for + * @param mixed $fallback Value to return if $program is not found + * + * @return mixed A string with the full path or false if not found + * @author Stig Bakken + */ + public static function which($program, $fallback = false) + { + // enforce API + if (!is_string($program) || '' == $program) { + return $fallback; + } + + // full path given + if (basename($program) != $program) { + $path_elements[] = dirname($program); + $program = basename($program); + } else { + $path = getenv('PATH'); + if (!$path) { + $path = getenv('Path'); // some OSes are just stupid enough to do this + } + + $path_elements = explode(PATH_SEPARATOR, $path); + } + + if (OS_WINDOWS) { + $exe_suffixes = getenv('PATHEXT') + ? explode(PATH_SEPARATOR, getenv('PATHEXT')) + : array('.exe','.bat','.cmd','.com'); + // allow passing a command.exe param + if (strpos($program, '.') !== false) { + array_unshift($exe_suffixes, ''); + } + } else { + $exe_suffixes = array(''); + } + + foreach ($exe_suffixes as $suff) { + foreach ($path_elements as $dir) { + $file = $dir . DIRECTORY_SEPARATOR . $program . $suff; + if (is_executable($file)) { + return $file; + } + } + } + return $fallback; + } + + /** + * The "find" command + * + * Usage: + * + * System::find($dir); + * System::find("$dir -type d"); + * System::find("$dir -type f"); + * System::find("$dir -name *.php"); + * System::find("$dir -name *.php -name *.htm*"); + * System::find("$dir -maxdepth 1"); + * + * Params implmented: + * $dir -> Start the search at this directory + * -type d -> return only directories + * -type f -> return only files + * -maxdepth -> max depth of recursion + * -name -> search pattern (bash style). Multiple -name param allowed + * + * @param mixed Either array or string with the command line + * @return array Array of found files + */ + public static function find($args) + { + if (!is_array($args)) { + $args = preg_split('/\s+/', $args, -1, PREG_SPLIT_NO_EMPTY); + } + $dir = realpath(array_shift($args)); + if (!$dir) { + return array(); + } + $patterns = array(); + $depth = 0; + $do_files = $do_dirs = true; + $args_count = count($args); + for ($i = 0; $i < $args_count; $i++) { + switch ($args[$i]) { + case '-type': + if (in_array($args[$i+1], array('d', 'f'))) { + if ($args[$i+1] == 'd') { + $do_files = false; + } else { + $do_dirs = false; + } + } + $i++; + break; + case '-name': + $name = preg_quote($args[$i+1], '#'); + // our magic characters ? and * have just been escaped, + // so now we change the escaped versions to PCRE operators + $name = strtr($name, array('\?' => '.', '\*' => '.*')); + $patterns[] = '('.$name.')'; + $i++; + break; + case '-maxdepth': + $depth = $args[$i+1]; + break; + } + } + $path = System::_dirToStruct($dir, $depth, 0, true); + if ($do_files && $do_dirs) { + $files = array_merge($path['files'], $path['dirs']); + } elseif ($do_dirs) { + $files = $path['dirs']; + } else { + $files = $path['files']; + } + if (count($patterns)) { + $dsq = preg_quote(DIRECTORY_SEPARATOR, '#'); + $pattern = '#(^|'.$dsq.')'.implode('|', $patterns).'($|'.$dsq.')#'; + $ret = array(); + $files_count = count($files); + for ($i = 0; $i < $files_count; $i++) { + // only search in the part of the file below the current directory + $filepart = basename($files[$i]); + if (preg_match($pattern, $filepart)) { + $ret[] = $files[$i]; + } + } + return $ret; + } + return $files; + } +} \ No newline at end of file diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/pearcmd.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/pearcmd.php new file mode 100644 index 0000000..63da38c --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/pearcmd.php @@ -0,0 +1,497 @@ + + * @author Tomas V.V.Cox + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + */ + +@ob_end_clean(); +if (!defined('PEAR_RUNTYPE')) { + // this is defined in peclcmd.php as 'pecl' + define('PEAR_RUNTYPE', 'pear'); +} +define('PEAR_IGNORE_BACKTRACE', 1); +/** + * @nodep Gtk + */ +//the space is needed for windows include paths with trailing backslash +// http://pear.php.net/bugs/bug.php?id=19482 +if ('/home/zaak/workspace/js/ckfinder/vendor/pear-pear.php.net/PEAR ' != '@'.'include_path'.'@ ') { + ini_set('include_path', trim('/home/zaak/workspace/js/ckfinder/vendor/pear-pear.php.net/PEAR '). PATH_SEPARATOR . get_include_path()); + $raw = false; +} else { + // this is a raw, uninstalled pear, either a cvs checkout, or php distro + $raw = true; +} +@ini_set('allow_url_fopen', true); +@set_time_limit(0); +ob_implicit_flush(true); +@ini_set('track_errors', true); +@ini_set('html_errors', false); +$_PEAR_PHPDIR = '#$%^&*'; +set_error_handler('error_handler'); + +$pear_package_version = "1.10.1"; + +require_once 'PEAR.php'; +require_once 'PEAR/Frontend.php'; +require_once 'PEAR/Config.php'; +require_once 'PEAR/Command.php'; +require_once 'Console/Getopt.php'; + + +PEAR_Command::setFrontendType('CLI'); +$all_commands = PEAR_Command::getCommands(); + +// remove this next part when we stop supporting that crap-ass PHP 4.2 +if (!isset($_SERVER['argv']) && !isset($argv) && !isset($HTTP_SERVER_VARS['argv'])) { + echo 'ERROR: either use the CLI php executable, ' . + 'or set register_argc_argv=On in php.ini'; + exit(1); +} + +$argv = Console_Getopt::readPHPArgv(); +// fix CGI sapi oddity - the -- in pear.bat/pear is not removed +if (php_sapi_name() != 'cli' && isset($argv[1]) && $argv[1] == '--') { + unset($argv[1]); + $argv = array_values($argv); +} +$progname = PEAR_RUNTYPE; +array_shift($argv); +$options = Console_Getopt::getopt2($argv, "c:C:d:D:Gh?sSqu:vV"); +if (PEAR::isError($options)) { + usage($options); +} + +$opts = $options[0]; + +$fetype = 'CLI'; +if ($progname == 'gpear' || $progname == 'pear-gtk') { + $fetype = 'Gtk2'; +} else { + foreach ($opts as $opt) { + if ($opt[0] == 'G') { + $fetype = 'Gtk2'; + } + } +} + +$pear_user_config = ''; +$pear_system_config = ''; +$store_user_config = false; +$store_system_config = false; +$verbose = 1; + +foreach ($opts as $opt) { + switch ($opt[0]) { + case 'c': + $pear_user_config = $opt[1]; + break; + case 'C': + $pear_system_config = $opt[1]; + break; + } +} + +PEAR_Command::setFrontendType($fetype); +$ui = &PEAR_Command::getFrontendObject(); +$config = &PEAR_Config::singleton($pear_user_config, $pear_system_config); + +if (PEAR::isError($config)) { + $_file = ''; + if ($pear_user_config !== false) { + $_file .= $pear_user_config; + } + if ($pear_system_config !== false) { + $_file .= '/' . $pear_system_config; + } + if ($_file == '/') { + $_file = 'The default config file'; + } + $config->getMessage(); + $ui->outputData("ERROR: $_file is not a valid config file or is corrupted."); + // We stop, we have no idea where we are :) + exit(1); +} + +// this is used in the error handler to retrieve a relative path +$_PEAR_PHPDIR = $config->get('php_dir'); +$ui->setConfig($config); +PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($ui, "displayFatalError")); + +$verbose = $config->get("verbose"); +$cmdopts = array(); + +if ($raw) { + if (!$config->isDefinedLayer('user') && !$config->isDefinedLayer('system')) { + $found = false; + foreach ($opts as $opt) { + if ($opt[0] == 'd' || $opt[0] == 'D') { + // the user knows what they are doing, and are setting config values + $found = true; + } + } + if (!$found) { + // no prior runs, try to install PEAR + $parent = dirname(__FILE__); + if (strpos($parent, 'scripts')) { + $grandparent = dirname($parent); + $packagexml = $grandparent . DIRECTORY_SEPARATOR . 'package2.xml'; + $pearbase = $grandparent; + } else { + $packagexml = $parent . DIRECTORY_SEPARATOR . 'package2.xml'; + $pearbase = $parent; + } + if (file_exists($packagexml)) { + $options[1] = array( + 'install', + $packagexml + ); + $config->set('php_dir', $pearbase . DIRECTORY_SEPARATOR . 'php'); + $config->set('data_dir', $pearbase . DIRECTORY_SEPARATOR . 'data'); + $config->set('doc_dir', $pearbase . DIRECTORY_SEPARATOR . 'docs'); + $config->set('test_dir', $pearbase . DIRECTORY_SEPARATOR . 'tests'); + $config->set( + 'ext_dir', + $pearbase . DIRECTORY_SEPARATOR . 'extensions' + ); + $config->set('bin_dir', $pearbase); + $config->mergeConfigFile($pearbase . 'pear.ini', false); + $config->store(); + $config->set('auto_discover', 1); + } + } + } +} +foreach ($opts as $opt) { + $param = !empty($opt[1]) ? $opt[1] : true; + switch ($opt[0]) { + case 'd': + if ($param === true) { + die( + 'Invalid usage of "-d" option, expected -d config_value=value, ' . + 'received "-d"' . "\n" + ); + } + $possible = explode('=', $param); + if (count($possible) != 2) { + die( + 'Invalid usage of "-d" option, expected ' . + '-d config_value=value, received "' . $param . '"' . "\n" + ); + } + list($key, $value) = explode('=', $param); + $config->set($key, $value, 'user'); + break; + case 'D': + if ($param === true) { + die( + 'Invalid usage of "-d" option, expected ' . + '-d config_value=value, received "-d"' . "\n" + ); + } + $possible = explode('=', $param); + if (count($possible) != 2) { + die( + 'Invalid usage of "-d" option, expected ' . + '-d config_value=value, received "' . $param . '"' . "\n" + ); + } + list($key, $value) = explode('=', $param); + $config->set($key, $value, 'system'); + break; + case 's': + $store_user_config = true; + break; + case 'S': + $store_system_config = true; + break; + case 'u': + $config->remove($param, 'user'); + break; + case 'v': + $config->set('verbose', $config->get('verbose') + 1); + break; + case 'q': + $config->set('verbose', $config->get('verbose') - 1); + break; + case 'V': + usage(null, 'version'); + case 'c': + case 'C': + break; + default: + // all non pear params goes to the command + $cmdopts[$opt[0]] = $param; + break; + } +} + +if ($store_system_config) { + $config->store('system'); +} + +if ($store_user_config) { + $config->store('user'); +} + +$command = (isset($options[1][0])) ? $options[1][0] : null; +if (empty($command) && ($store_user_config || $store_system_config)) { + exit; +} + +if ($fetype == 'Gtk2') { + if (!$config->validConfiguration()) { + PEAR::raiseError( + "CRITICAL ERROR: no existing valid configuration files found in " . + "files '$pear_user_config' or '$pear_system_config', " . + "please copy an existing configuration file to one of these " . + "locations, or use the -c and -s options to create one" + ); + } + Gtk::main(); +} else { + do { + if ($command == 'help') { + usage(null, isset($options[1][1]) ? $options[1][1] : null); + } + + if (!$config->validConfiguration()) { + PEAR::raiseError( + "CRITICAL ERROR: no existing valid configuration files found " . + "in files '$pear_user_config' or '$pear_system_config', " . + "please copy an existing configuration file to one of " . + "these locations, or use the -c and -s options to create one" + ); + } + + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $cmd = PEAR_Command::factory($command, $config); + PEAR::popErrorHandling(); + if (PEAR::isError($cmd)) { + usage(null, isset($options[1][0]) ? $options[1][0] : null); + } + + $short_args = $long_args = null; + PEAR_Command::getGetoptArgs($command, $short_args, $long_args); + array_shift($options[1]); + $tmp = Console_Getopt::getopt2($options[1], $short_args, $long_args); + + if (PEAR::isError($tmp)) { + break; + } + + list($tmpopt, $params) = $tmp; + $opts = array(); + foreach ($tmpopt as $foo => $tmp2) { + list($opt, $value) = $tmp2; + if ($value === null) { + $value = true; // options without args + } + + if (strlen($opt) == 1) { + $cmdoptions = $cmd->getOptions($command); + foreach ($cmdoptions as $o => $d) { + if (isset($d['shortopt']) && $d['shortopt'] == $opt) { + $opts[$o] = $value; + } + } + } else { + if (substr($opt, 0, 2) == '--') { + $opts[substr($opt, 2)] = $value; + } + } + } + + $ok = $cmd->run($command, $opts, $params); + if ($ok === false) { + PEAR::raiseError("unknown command `$command'"); + } + + if (PEAR::isError($ok)) { + PEAR::setErrorHandling( + PEAR_ERROR_CALLBACK, array($ui, "displayFatalError") + ); + PEAR::raiseError($ok); + } + } while (false); +} + +// {{{ usage() + +/** + * Display usage information + * + * @param mixed $error Optional error message + * @param mixed $helpsubject Optional subject/command to display help for + * + * @return void + */ +function usage($error = null, $helpsubject = null) +{ + global $progname, $all_commands; + $stdout = fopen('php://stdout', 'w'); + if (PEAR::isError($error)) { + fputs($stdout, $error->getMessage() . "\n"); + } elseif ($error !== null) { + fputs($stdout, "$error\n"); + } + + if ($helpsubject != null) { + $put = cmdHelp($helpsubject); + } else { + $put = "Commands:\n"; + $maxlen = max(array_map("strlen", $all_commands)); + $formatstr = "%-{$maxlen}s %s\n"; + ksort($all_commands); + foreach ($all_commands as $cmd => $class) { + $put .= sprintf($formatstr, $cmd, PEAR_Command::getDescription($cmd)); + } + $put .= + "Usage: $progname [options] command [command-options] \n". + "Type \"$progname help options\" to list all options.\n". + "Type \"$progname help shortcuts\" to list all command shortcuts.\n". + "Type \"$progname help version\" or ". + "\"$progname version\" to list version information.\n". + "Type \"$progname help \" to get the help ". + "for the specified command."; + } + fputs($stdout, "$put\n"); + fclose($stdout); + + if ($error === null) { + exit(0); + } + exit(1); +} + +/** + * Return help string for specified command + * + * @param string $command Command to return help for + * + * @return void + */ +function cmdHelp($command) +{ + global $progname, $all_commands, $config; + if ($command == "options") { + return + "Options:\n". + " -v increase verbosity level (default 1)\n". + " -q be quiet, decrease verbosity level\n". + " -c file find user configuration in `file'\n". + " -C file find system configuration in `file'\n". + " -d foo=bar set user config variable `foo' to `bar'\n". + " -D foo=bar set system config variable `foo' to `bar'\n". + " -G start in graphical (Gtk) mode\n". + " -s store user configuration\n". + " -S store system configuration\n". + " -u foo unset `foo' in the user configuration\n". + " -h, -? display help/usage (this message)\n". + " -V version information\n"; + } elseif ($command == "shortcuts") { + $sc = PEAR_Command::getShortcuts(); + $ret = "Shortcuts:\n"; + foreach ($sc as $s => $c) { + $ret .= sprintf(" %-8s %s\n", $s, $c); + } + return $ret; + + } elseif ($command == "version") { + return "PEAR Version: ".$GLOBALS['pear_package_version']. + "\nPHP Version: ".phpversion(). + "\nZend Engine Version: ".zend_version(). + "\nRunning on: ".php_uname(); + + } elseif ($help = PEAR_Command::getHelp($command)) { + if (is_string($help)) { + return "$progname $command [options] $help\n"; + } + + if ($help[1] === null) { + return "$progname $command $help[0]"; + } + + return "$progname $command [options] $help[0]\n$help[1]"; + } + + return "Command '$command' is not valid, try '$progname help'"; +} + +// }}} + +/** + * error_handler + * + * @param mixed $errno Error number + * @param mixed $errmsg Message + * @param mixed $file Filename + * @param mixed $line Line number + * @param mixed $vars Variables + * + * @access public + * @return boolean + */ +function error_handler($errno, $errmsg, $file, $line, $vars) +{ + if ($errno & E_STRICT + || $errno & E_DEPRECATED + || !error_reporting() + ) { + if ($errno & E_STRICT) { + return; // E_STRICT + } + if ($errno & E_DEPRECATED) { + return; // E_DEPRECATED + } + if (!error_reporting() && isset($GLOBALS['config']) && $GLOBALS['config']->get('verbose') < 4) { + return false; // @silenced error, show all if debug is high enough + } + } + $errortype = array ( + E_DEPRECATED => 'Deprecated Warning', + E_ERROR => "Error", + E_WARNING => "Warning", + E_PARSE => "Parsing Error", + E_STRICT => 'Strict Warning', + E_NOTICE => "Notice", + E_CORE_ERROR => "Core Error", + E_CORE_WARNING => "Core Warning", + E_COMPILE_ERROR => "Compile Error", + E_COMPILE_WARNING => "Compile Warning", + E_USER_ERROR => "User Error", + E_USER_WARNING => "User Warning", + E_USER_NOTICE => "User Notice" + ); + $prefix = $errortype[$errno]; + global $_PEAR_PHPDIR; + if (stristr($file, $_PEAR_PHPDIR)) { + $file = substr($file, strlen($_PEAR_PHPDIR) + 1); + } else { + $file = basename($file); + } + print "\n$prefix: $errmsg in $file on line $line\n"; + return false; +} + + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * indent-tabs-mode: nil + * mode: php + * End: + */ +// vim600:syn=php diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/peclcmd.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/peclcmd.php new file mode 100644 index 0000000..7f8f04d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/PEAR/peclcmd.php @@ -0,0 +1,42 @@ + + * @author Tomas V.V.Cox + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR + */ + +/** + * @nodep Gtk + */ +//the space is needed for windows include paths with trailing backslash +// http://pear.php.net/bugs/bug.php?id=19482 +if ('/home/zaak/workspace/js/ckfinder/vendor/pear-pear.php.net/PEAR ' != '@'.'include_path'.'@ ') { + ini_set('include_path', trim('/home/zaak/workspace/js/ckfinder/vendor/pear-pear.php.net/PEAR '). PATH_SEPARATOR . get_include_path()); + $raw = false; +} else { + // this is a raw, uninstalled pear, either a cvs checkout, or php distro + $raw = true; +} +define('PEAR_RUNTYPE', 'pecl'); +require_once 'pearcmd.php'; +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * indent-tabs-mode: nil + * mode: php + * End: + */ +// vim600:syn=php + +?> diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/Structures_Graph/Structures/Graph.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/Structures_Graph/Structures/Graph.php new file mode 100644 index 0000000..5a64f6e --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/Structures_Graph/Structures/Graph.php @@ -0,0 +1,176 @@ + | +// +-----------------------------------------------------------------------------+ +// +/** + * The Graph.php file contains the definition of the Structures_Graph class + * + * @package Structures_Graph + */ + +/* dependencies {{{ */ +require_once 'PEAR.php'; +require_once 'Structures/Graph/Node.php'; +/* }}} */ + +define('STRUCTURES_GRAPH_ERROR_GENERIC', 100); + +/* class Structures_Graph {{{ */ +/** + * The Structures_Graph class represents a graph data structure. + * + * A Graph is a data structure composed by a set of nodes, connected by arcs. + * Graphs may either be directed or undirected. In a directed graph, arcs are + * directional, and can be traveled only one way. In an undirected graph, arcs + * are bidirectional, and can be traveled both ways. + * + * @author Srgio Carvalho + * @copyright (c) 2004 by Srgio Carvalho + * @package Structures_Graph + */ +/* }}} */ +class Structures_Graph +{ + /** + * List of node objects in this graph + * @access private + */ + var $_nodes = array(); + + /** + * If the graph is directed or not + * @access private + */ + var $_directed = false; + + + /** + * Constructor + * + * @param boolean $directed Set to true if the graph is directed. + * Set to false if it is not directed. + */ + public function __construct($directed = true) + { + $this->_directed = $directed; + } + + /** + * Old constructor (PHP4-style; kept for BC with extending classes) + * + * @param boolean $directed Set to true if the graph is directed. + * Set to false if it is not directed. + * + * @return void + */ + public function Structures_Graph($directed = true) + { + $this->__construct($directed); + } + + /** + * Return true if a graph is directed + * + * @return boolean true if the graph is directed + */ + public function isDirected() + { + return (boolean) $this->_directed; + } + + /** + * Add a Node to the Graph + * + * @param Structures_Graph_Node $newNode The node to be added. + * + * @return void + */ + public function addNode(&$newNode) + { + // We only add nodes + if (!is_a($newNode, 'Structures_Graph_Node')) { + return Pear::raiseError( + 'Structures_Graph::addNode received an object that is not' + . ' a Structures_Graph_Node', + STRUCTURES_GRAPH_ERROR_GENERIC + ); + } + + //Graphs are node *sets*, so duplicates are forbidden. + // We allow nodes that are exactly equal, but disallow equal references. + foreach ($this->_nodes as $key => $node) { + /* + ZE1 equality operators choke on the recursive cycle introduced + by the _graph field in the Node object. + So, we'll check references the hard way + (change $this->_nodes[$key] and check if the change reflects in + $node) + */ + $savedData = $this->_nodes[$key]; + $referenceIsEqualFlag = false; + $this->_nodes[$key] = true; + if ($node === true) { + $this->_nodes[$key] = false; + if ($node === false) { + $referenceIsEqualFlag = true; + } + } + $this->_nodes[$key] = $savedData; + if ($referenceIsEqualFlag) { + return Pear::raiseError( + 'Structures_Graph::addNode received an object that is' + . ' a duplicate for this dataset', + STRUCTURES_GRAPH_ERROR_GENERIC + ); + } + } + $this->_nodes[] =& $newNode; + $newNode->setGraph($this); + } + + /** + * Remove a Node from the Graph + * + * @param Structures_Graph_Node $node The node to be removed from the graph + * + * @return void + * @todo This is unimplemented + */ + public function removeNode(&$node) + { + } + + /** + * Return the node set, in no particular order. + * For ordered node sets, use a Graph Manipulator insted. + * + * @return array The set of nodes in this graph + * @see Structures_Graph_Manipulator_TopologicalSorter + */ + public function &getNodes() + { + return $this->_nodes; + } +} +?> diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/Structures_Graph/Structures/Graph/Manipulator/AcyclicTest.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/Structures_Graph/Structures/Graph/Manipulator/AcyclicTest.php new file mode 100644 index 0000000..7ecd756 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/Structures_Graph/Structures/Graph/Manipulator/AcyclicTest.php @@ -0,0 +1,134 @@ + | +// +-----------------------------------------------------------------------------+ +// +/** + * This file contains the definition of the Structures_Graph_Manipulator_AcyclicTest graph manipulator. + * + * @see Structures_Graph_Manipulator_AcyclicTest + * @package Structures_Graph + */ + +/* dependencies {{{ */ +/** */ +require_once 'PEAR.php'; +/** */ +require_once 'Structures/Graph.php'; +/** */ +require_once 'Structures/Graph/Node.php'; +/* }}} */ + +/* class Structures_Graph_Manipulator_AcyclicTest {{{ */ +/** + * The Structures_Graph_Manipulator_AcyclicTest is a graph manipulator + * which tests whether a graph contains a cycle. + * + * The definition of an acyclic graph used in this manipulator is that of a + * DAG. The graph must be directed, or else it is considered cyclic, even when + * there are no arcs. + * + * @author Srgio Carvalho + * @copyright (c) 2004 by Srgio Carvalho + * @package Structures_Graph + */ +class Structures_Graph_Manipulator_AcyclicTest { + /* _nonVisitedInDegree {{{ */ + /** + * + * This is a variant of Structures_Graph::inDegree which does + * not count nodes marked as visited. + * + * @return integer Number of non-visited nodes that link to this one + */ + protected static function _nonVisitedInDegree(&$node) { + $result = 0; + $graphNodes =& $node->_graph->getNodes(); + foreach (array_keys($graphNodes) as $key) { + if ((!$graphNodes[$key]->getMetadata('acyclic-test-visited')) && $graphNodes[$key]->connectsTo($node)) $result++; + } + return $result; + + } + /* }}} */ + + /* _isAcyclic {{{ */ + /** + * Check if the graph is acyclic + */ + protected static function _isAcyclic(&$graph) { + // Mark every node as not visited + $nodes =& $graph->getNodes(); + $nodeKeys = array_keys($nodes); + $refGenerator = array(); + foreach($nodeKeys as $key) { + $refGenerator[] = false; + $nodes[$key]->setMetadata('acyclic-test-visited', $refGenerator[sizeof($refGenerator) - 1]); + } + + // Iteratively peel off leaf nodes + do { + // Find out which nodes are leafs (excluding visited nodes) + $leafNodes = array(); + foreach($nodeKeys as $key) { + if ((!$nodes[$key]->getMetadata('acyclic-test-visited')) && Structures_Graph_Manipulator_AcyclicTest::_nonVisitedInDegree($nodes[$key]) == 0) { + $leafNodes[] =& $nodes[$key]; + } + } + // Mark leafs as visited + for ($i=sizeof($leafNodes) - 1; $i>=0; $i--) { + $visited =& $leafNodes[$i]->getMetadata('acyclic-test-visited'); + $visited = true; + $leafNodes[$i]->setMetadata('acyclic-test-visited', $visited); + } + } while (sizeof($leafNodes) > 0); + + // If graph is a DAG, there should be no non-visited nodes. Let's try to prove otherwise + $result = true; + foreach($nodeKeys as $key) if (!$nodes[$key]->getMetadata('acyclic-test-visited')) $result = false; + + // Cleanup visited marks + foreach($nodeKeys as $key) $nodes[$key]->unsetMetadata('acyclic-test-visited'); + + return $result; + } + /* }}} */ + + /* isAcyclic {{{ */ + /** + * + * isAcyclic returns true if a graph contains no cycles, false otherwise. + * + * @return boolean true iff graph is acyclic + */ + public static function isAcyclic(&$graph) { + // We only test graphs + if (!is_a($graph, 'Structures_Graph')) return Pear::raiseError('Structures_Graph_Manipulator_AcyclicTest::isAcyclic received an object that is not a Structures_Graph', STRUCTURES_GRAPH_ERROR_GENERIC); + if (!$graph->isDirected()) return false; // Only directed graphs may be acyclic + + return Structures_Graph_Manipulator_AcyclicTest::_isAcyclic($graph); + } + /* }}} */ +} +/* }}} */ +?> diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/Structures_Graph/Structures/Graph/Manipulator/TopologicalSorter.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/Structures_Graph/Structures/Graph/Manipulator/TopologicalSorter.php new file mode 100644 index 0000000..f57ee10 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/Structures_Graph/Structures/Graph/Manipulator/TopologicalSorter.php @@ -0,0 +1,176 @@ + | +// +-----------------------------------------------------------------------------+ +// +/** + * This file contains the definition of the Structures_Graph_Manipulator_TopologicalSorter class. + * + * @package Structures_Graph + */ + +require_once 'PEAR.php'; +require_once 'Structures/Graph.php'; +require_once 'Structures/Graph/Node.php'; +require_once 'Structures/Graph/Manipulator/AcyclicTest.php'; + +/** + * The Structures_Graph_Manipulator_TopologicalSorter is a manipulator + * which is able to return the set of nodes in a graph, sorted by topological + * order. + * + * A graph may only be sorted topologically iff it's a DAG. You can test it + * with the Structures_Graph_Manipulator_AcyclicTest. + * + * @author Srgio Carvalho + * @copyright (c) 2004 by Srgio Carvalho + * @see Structures_Graph_Manipulator_AcyclicTest + * @package Structures_Graph + */ +class Structures_Graph_Manipulator_TopologicalSorter +{ + /** + * This is a variant of Structures_Graph::inDegree which does + * not count nodes marked as visited. + * + * @param object $node Node to check + * + * @return integer Number of non-visited nodes that link to this one + */ + protected static function _nonVisitedInDegree(&$node) + { + $result = 0; + $graphNodes =& $node->_graph->getNodes(); + foreach (array_keys($graphNodes) as $key) { + if ((!$graphNodes[$key]->getMetadata('topological-sort-visited')) + && $graphNodes[$key]->connectsTo($node) + ) { + $result++; + } + } + return $result; + + } + + /** + * Sort implementation + * + * @param object $graph Graph to sort + * + * @return void + */ + protected static function _sort(&$graph) + { + // Mark every node as not visited + $nodes =& $graph->getNodes(); + $nodeKeys = array_keys($nodes); + $refGenerator = array(); + foreach ($nodeKeys as $key) { + $refGenerator[] = false; + $nodes[$key]->setMetadata( + 'topological-sort-visited', + $refGenerator[sizeof($refGenerator) - 1] + ); + } + + // Iteratively peel off leaf nodes + $topologicalLevel = 0; + do { + // Find out which nodes are leafs (excluding visited nodes) + $leafNodes = array(); + foreach ($nodeKeys as $key) { + if ((!$nodes[$key]->getMetadata('topological-sort-visited')) + && static::_nonVisitedInDegree($nodes[$key]) == 0 + ) { + $leafNodes[] =& $nodes[$key]; + } + } + // Mark leafs as visited + $refGenerator[] = $topologicalLevel; + for ($i = sizeof($leafNodes) - 1; $i>=0; $i--) { + $visited =& $leafNodes[$i]->getMetadata('topological-sort-visited'); + $visited = true; + $leafNodes[$i]->setMetadata('topological-sort-visited', $visited); + $leafNodes[$i]->setMetadata( + 'topological-sort-level', + $refGenerator[sizeof($refGenerator) - 1] + ); + } + $topologicalLevel++; + } while (sizeof($leafNodes) > 0); + + // Cleanup visited marks + foreach ($nodeKeys as $key) { + $nodes[$key]->unsetMetadata('topological-sort-visited'); + } + } + + /** + * Sort returns the graph's nodes, sorted by topological order. + * + * The result is an array with as many entries as topological levels. + * Each entry in this array is an array of nodes within + * the given topological level. + * + * @param object $graph Graph to sort + * + * @return array The graph's nodes, sorted by topological order. + */ + public static function sort(&$graph) + { + // We only sort graphs + if (!is_a($graph, 'Structures_Graph')) { + return Pear::raiseError( + 'Structures_Graph_Manipulator_TopologicalSorter::sort received' + . ' an object that is not a Structures_Graph', + STRUCTURES_GRAPH_ERROR_GENERIC + ); + } + if (!Structures_Graph_Manipulator_AcyclicTest::isAcyclic($graph)) { + return Pear::raiseError( + 'Structures_Graph_Manipulator_TopologicalSorter::sort' + . ' received an graph that has cycles', + STRUCTURES_GRAPH_ERROR_GENERIC + ); + } + + Structures_Graph_Manipulator_TopologicalSorter::_sort($graph); + $result = array(); + + // Fill out result array + $nodes =& $graph->getNodes(); + $nodeKeys = array_keys($nodes); + foreach ($nodeKeys as $key) { + if (!array_key_exists($nodes[$key]->getMetadata('topological-sort-level'), $result)) { + $result[$nodes[$key]->getMetadata('topological-sort-level')] + = array(); + } + $result[$nodes[$key]->getMetadata('topological-sort-level')][] + =& $nodes[$key]; + $nodes[$key]->unsetMetadata('topological-sort-level'); + } + + return $result; + } +} +?> diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/Structures_Graph/Structures/Graph/Node.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/Structures_Graph/Structures/Graph/Node.php new file mode 100644 index 0000000..a4b917b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/Structures_Graph/Structures/Graph/Node.php @@ -0,0 +1,342 @@ + | +// +-----------------------------------------------------------------------------+ +// +/** + * This file contains the definition of the Structures_Graph_Node class + * + * @see Structures_Graph_Node + * @package Structures_Graph + */ + +/* dependencies {{{ */ +/** */ +require_once 'PEAR.php'; +/** */ +require_once 'Structures/Graph.php'; +/* }}} */ + +/* class Structures_Graph_Node {{{ */ +/** + * The Structures_Graph_Node class represents a Node that can be member of a + * graph node set. + * + * A graph node can contain data. Under this API, the node contains default data, + * and key index data. It behaves, thus, both as a regular data node, and as a + * dictionary (or associative array) node. + * + * Regular data is accessed via getData and setData. Key indexed data is accessed + * via getMetadata and setMetadata. + * + * @author Srgio Carvalho + * @copyright (c) 2004 by Srgio Carvalho + * @package Structures_Graph + */ +/* }}} */ +class Structures_Graph_Node { + /* fields {{{ */ + /** + * @access private + */ + var $_data = null; + /** @access private */ + var $_metadata = array(); + /** @access private */ + var $_arcs = array(); + /** @access private */ + var $_graph = null; + /* }}} */ + + /* Constructor {{{ */ + /** + * + * Constructor + * + * @access public + */ + function __construct() { + } + /* }}} */ + + /* getGraph {{{ */ + /** + * + * Node graph getter + * + * @return Structures_Graph Graph where node is stored + * @access public + */ + function &getGraph() { + return $this->_graph; + } + /* }}} */ + + /* setGraph {{{ */ + /** + * + * Node graph setter. This method should not be called directly. Use Graph::addNode instead. + * + * @param Structures_Graph Set the graph for this node. + * @see Structures_Graph::addNode() + * @access public + */ + function setGraph(&$graph) { + $this->_graph =& $graph; + } + /* }}} */ + + /* getData {{{ */ + /** + * + * Node data getter. + * + * Each graph node can contain a reference to one variable. This is the getter for that reference. + * + * @return mixed Data stored in node + * @access public + */ + function &getData() { + return $this->_data; + } + /* }}} */ + + /* setData {{{ */ + /** + * + * Node data setter + * + * Each graph node can contain a reference to one variable. This is the setter for that reference. + * + * @return mixed Data to store in node + * @access public + */ + function setData(&$data) { + $this->_data =& $data; + } + /* }}} */ + + /* metadataKeyExists {{{ */ + /** + * + * Test for existence of metadata under a given key. + * + * Each graph node can contain multiple 'metadata' entries, each stored under a different key, as in an + * associative array or in a dictionary. This method tests whether a given metadata key exists for this node. + * + * @param string Key to test + * @return boolean + * @access public + */ + function metadataKeyExists($key) { + return array_key_exists($key, $this->_metadata); + } + /* }}} */ + + /* getMetadata {{{ */ + /** + * + * Node metadata getter + * + * Each graph node can contain multiple 'metadata' entries, each stored under a different key, as in an + * associative array or in a dictionary. This method gets the data under the given key. If the key does + * not exist, an error will be thrown, so testing using metadataKeyExists might be needed. + * + * @param string Key + * @param boolean nullIfNonexistent (defaults to false). + * @return mixed Metadata Data stored in node under given key + * @see metadataKeyExists + * @access public + */ + function &getMetadata($key, $nullIfNonexistent = false) { + if (array_key_exists($key, $this->_metadata)) { + return $this->_metadata[$key]; + } else { + if ($nullIfNonexistent) { + $a = null; + return $a; + } else { + $a = Pear::raiseError('Structures_Graph_Node::getMetadata: Requested key does not exist', STRUCTURES_GRAPH_ERROR_GENERIC); + return $a; + } + } + } + /* }}} */ + + /* unsetMetadata {{{ */ + /** + * + * Delete metadata by key + * + * Each graph node can contain multiple 'metadata' entries, each stored under a different key, as in an + * associative array or in a dictionary. This method removes any data that might be stored under the provided key. + * If the key does not exist, no error is thrown, so it is safe using this method without testing for key existence. + * + * @param string Key + * @access public + */ + function unsetMetadata($key) { + if (array_key_exists($key, $this->_metadata)) unset($this->_metadata[$key]); + } + /* }}} */ + + /* setMetadata {{{ */ + /** + * + * Node metadata setter + * + * Each graph node can contain multiple 'metadata' entries, each stored under a different key, as in an + * associative array or in a dictionary. This method stores data under the given key. If the key already exists, + * previously stored data is discarded. + * + * @param string Key + * @param mixed Data + * @access public + */ + function setMetadata($key, &$data) { + $this->_metadata[$key] =& $data; + } + /* }}} */ + + /* _connectTo {{{ */ + /** @access private */ + function _connectTo(&$destinationNode) { + $this->_arcs[] =& $destinationNode; + } + /* }}} */ + + /* connectTo {{{ */ + /** + * + * Connect this node to another one. + * + * If the graph is not directed, the reverse arc, connecting $destinationNode to $this is also created. + * + * @param Structures_Graph_Node Node to connect to + * @access public + */ + function connectTo(&$destinationNode) { + // We only connect to nodes + if (!is_a($destinationNode, 'Structures_Graph_Node')) return Pear::raiseError('Structures_Graph_Node::connectTo received an object that is not a Structures_Graph_Node', STRUCTURES_GRAPH_ERROR_GENERIC); + // Nodes must already be in graphs to be connected + if ($this->_graph == null) return Pear::raiseError('Structures_Graph_Node::connectTo Tried to connect a node that is not in a graph', STRUCTURES_GRAPH_ERROR_GENERIC); + if ($destinationNode->getGraph() == null) return Pear::raiseError('Structures_Graph_Node::connectTo Tried to connect to a node that is not in a graph', STRUCTURES_GRAPH_ERROR_GENERIC); + // Connect here + $this->_connectTo($destinationNode); + // If graph is undirected, connect back + if (!$this->_graph->isDirected()) { + $destinationNode->_connectTo($this); + } + } + /* }}} */ + + /* getNeighbours {{{ */ + /** + * + * Return nodes connected to this one. + * + * @return array Array of nodes + * @access public + */ + function getNeighbours() { + return $this->_arcs; + } + /* }}} */ + + /* connectsTo {{{ */ + /** + * + * Test wether this node has an arc to the target node + * + * @return boolean True if the two nodes are connected + * @access public + */ + function connectsTo(&$target) { + if (version_compare(PHP_VERSION, '5.0.0') >= 0) { + return in_array($target, $this->getNeighbours(), true); + } + + $copy = $target; + $arcKeys = array_keys($this->_arcs); + foreach($arcKeys as $key) { + /* ZE1 chokes on this expression: + if ($target === $arc) return true; + so, we'll use more convoluted stuff + */ + $arc =& $this->_arcs[$key]; + $target = true; + if ($arc === true) { + $target = false; + if ($arc === false) { + $target = $copy; + return true; + } + } + } + $target = $copy; + return false; + } + /* }}} */ + + /* inDegree {{{ */ + /** + * + * Calculate the in degree of the node. + * + * The indegree for a node is the number of arcs entering the node. For non directed graphs, + * the indegree is equal to the outdegree. + * + * @return integer In degree of the node + * @access public + */ + function inDegree() { + if ($this->_graph == null) return 0; + if (!$this->_graph->isDirected()) return $this->outDegree(); + $result = 0; + $graphNodes =& $this->_graph->getNodes(); + foreach (array_keys($graphNodes) as $key) { + if ($graphNodes[$key]->connectsTo($this)) $result++; + } + return $result; + + } + /* }}} */ + + /* outDegree {{{ */ + /** + * + * Calculate the out degree of the node. + * + * The outdegree for a node is the number of arcs exiting the node. For non directed graphs, + * the outdegree is always equal to the indegree. + * + * @return integer Out degree of the node + * @access public + */ + function outDegree() { + if ($this->_graph == null) return 0; + return sizeof($this->_arcs); + } + /* }}} */ +} +?> diff --git a/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/XML_Util/XML/Util.php b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/XML_Util/XML/Util.php new file mode 100644 index 0000000..e3dbdea --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pear-pear.php.net/XML_Util/XML/Util.php @@ -0,0 +1,921 @@ + + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * @category XML + * @package XML_Util + * @author Stephan Schmidt + * @copyright 2003-2008 Stephan Schmidt + * @license http://opensource.org/licenses/bsd-license New BSD License + * @version CVS: $Id$ + * @link http://pear.php.net/package/XML_Util + */ + +/** + * Error code for invalid chars in XML name + */ +define('XML_UTIL_ERROR_INVALID_CHARS', 51); + +/** + * Error code for invalid chars in XML name + */ +define('XML_UTIL_ERROR_INVALID_START', 52); + +/** + * Error code for non-scalar tag content + */ +define('XML_UTIL_ERROR_NON_SCALAR_CONTENT', 60); + +/** + * Error code for missing tag name + */ +define('XML_UTIL_ERROR_NO_TAG_NAME', 61); + +/** + * Replace XML entities + */ +define('XML_UTIL_REPLACE_ENTITIES', 1); + +/** + * Embedd content in a CData Section + */ +define('XML_UTIL_CDATA_SECTION', 5); + +/** + * Do not replace entitites + */ +define('XML_UTIL_ENTITIES_NONE', 0); + +/** + * Replace all XML entitites + * This setting will replace <, >, ", ' and & + */ +define('XML_UTIL_ENTITIES_XML', 1); + +/** + * Replace only required XML entitites + * This setting will replace <, " and & + */ +define('XML_UTIL_ENTITIES_XML_REQUIRED', 2); + +/** + * Replace HTML entitites + * @link http://www.php.net/htmlentities + */ +define('XML_UTIL_ENTITIES_HTML', 3); + +/** + * Collapse all empty tags. + */ +define('XML_UTIL_COLLAPSE_ALL', 1); + +/** + * Collapse only empty XHTML tags that have no end tag. + */ +define('XML_UTIL_COLLAPSE_XHTML_ONLY', 2); + +/** + * Utility class for working with XML documents + * + * @category XML + * @package XML_Util + * @author Stephan Schmidt + * @copyright 2003-2008 Stephan Schmidt + * @license http://opensource.org/licenses/bsd-license New BSD License + * @version Release: 1.3.0 + * @link http://pear.php.net/package/XML_Util + */ +class XML_Util +{ + /** + * Return API version + * + * @return string $version API version + */ + public static function apiVersion() + { + return '1.1'; + } + + /** + * Replace XML entities + * + * With the optional second parameter, you may select, which + * entities should be replaced. + * + * + * require_once 'XML/Util.php'; + * + * // replace XML entites: + * $string = XML_Util::replaceEntities('This string contains < & >.'); + * + * + * With the optional third parameter, you may pass the character encoding + * + * require_once 'XML/Util.php'; + * + * // replace XML entites in UTF-8: + * $string = XML_Util::replaceEntities( + * 'This string contains < & > as well as ä, ö, ß, à and ê', + * XML_UTIL_ENTITIES_HTML, + * 'UTF-8' + * ); + * + * + * @param string $string string where XML special chars + * should be replaced + * @param int $replaceEntities setting for entities in attribute values + * (one of XML_UTIL_ENTITIES_XML, + * XML_UTIL_ENTITIES_XML_REQUIRED, + * XML_UTIL_ENTITIES_HTML) + * @param string $encoding encoding value (if any)... + * must be a valid encoding as determined + * by the htmlentities() function + * + * @return string string with replaced chars + * @see reverseEntities() + */ + public static function replaceEntities( + $string, $replaceEntities = XML_UTIL_ENTITIES_XML, $encoding = 'ISO-8859-1' + ) { + switch ($replaceEntities) { + case XML_UTIL_ENTITIES_XML: + return strtr( + $string, + array( + '&' => '&', + '>' => '>', + '<' => '<', + '"' => '"', + '\'' => ''' + ) + ); + break; + case XML_UTIL_ENTITIES_XML_REQUIRED: + return strtr( + $string, + array( + '&' => '&', + '<' => '<', + '"' => '"' + ) + ); + break; + case XML_UTIL_ENTITIES_HTML: + return htmlentities($string, ENT_COMPAT, $encoding); + break; + } + return $string; + } + + /** + * Reverse XML entities + * + * With the optional second parameter, you may select, which + * entities should be reversed. + * + * + * require_once 'XML/Util.php'; + * + * // reverse XML entites: + * $string = XML_Util::reverseEntities('This string contains < & >.'); + * + * + * With the optional third parameter, you may pass the character encoding + * + * require_once 'XML/Util.php'; + * + * // reverse XML entites in UTF-8: + * $string = XML_Util::reverseEntities( + * 'This string contains < & > as well as' + * . ' ä, ö, ß, à and ê', + * XML_UTIL_ENTITIES_HTML, + * 'UTF-8' + * ); + * + * + * @param string $string string where XML special chars + * should be replaced + * @param int $replaceEntities setting for entities in attribute values + * (one of XML_UTIL_ENTITIES_XML, + * XML_UTIL_ENTITIES_XML_REQUIRED, + * XML_UTIL_ENTITIES_HTML) + * @param string $encoding encoding value (if any)... + * must be a valid encoding as determined + * by the html_entity_decode() function + * + * @return string string with replaced chars + * @see replaceEntities() + */ + public static function reverseEntities( + $string, $replaceEntities = XML_UTIL_ENTITIES_XML, $encoding = 'ISO-8859-1' + ) { + switch ($replaceEntities) { + case XML_UTIL_ENTITIES_XML: + return strtr( + $string, + array( + '&' => '&', + '>' => '>', + '<' => '<', + '"' => '"', + ''' => '\'' + ) + ); + break; + case XML_UTIL_ENTITIES_XML_REQUIRED: + return strtr( + $string, + array( + '&' => '&', + '<' => '<', + '"' => '"' + ) + ); + break; + case XML_UTIL_ENTITIES_HTML: + return html_entity_decode($string, ENT_COMPAT, $encoding); + break; + } + return $string; + } + + /** + * Build an xml declaration + * + * + * require_once 'XML/Util.php'; + * + * // get an XML declaration: + * $xmlDecl = XML_Util::getXMLDeclaration('1.0', 'UTF-8', true); + * + * + * @param string $version xml version + * @param string $encoding character encoding + * @param bool $standalone document is standalone (or not) + * + * @return string xml declaration + * @uses attributesToString() to serialize the attributes of the + * XML declaration + */ + public static function getXMLDeclaration( + $version = '1.0', $encoding = null, $standalone = null + ) { + $attributes = array( + 'version' => $version, + ); + // add encoding + if ($encoding !== null) { + $attributes['encoding'] = $encoding; + } + // add standalone, if specified + if ($standalone !== null) { + $attributes['standalone'] = $standalone ? 'yes' : 'no'; + } + + return sprintf( + '', + XML_Util::attributesToString($attributes, false) + ); + } + + /** + * Build a document type declaration + * + * + * require_once 'XML/Util.php'; + * + * // get a doctype declaration: + * $xmlDecl = XML_Util::getDocTypeDeclaration('rootTag','myDocType.dtd'); + * + * + * @param string $root name of the root tag + * @param string $uri uri of the doctype definition + * (or array with uri and public id) + * @param string $internalDtd internal dtd entries + * + * @return string doctype declaration + * @since 0.2 + */ + public static function getDocTypeDeclaration( + $root, $uri = null, $internalDtd = null + ) { + if (is_array($uri)) { + $ref = sprintf(' PUBLIC "%s" "%s"', $uri['id'], $uri['uri']); + } elseif (!empty($uri)) { + $ref = sprintf(' SYSTEM "%s"', $uri); + } else { + $ref = ''; + } + + if (empty($internalDtd)) { + return sprintf('', $root, $ref); + } else { + return sprintf("", $root, $ref, $internalDtd); + } + } + + /** + * Create string representation of an attribute list + * + * + * require_once 'XML/Util.php'; + * + * // build an attribute string + * $att = array( + * 'foo' => 'bar', + * 'argh' => 'tomato' + * ); + * + * $attList = XML_Util::attributesToString($att); + * + * + * @param array $attributes attribute array + * @param bool|array $sort sort attribute list alphabetically, + * may also be an assoc array containing + * the keys 'sort', 'multiline', 'indent', + * 'linebreak' and 'entities' + * @param bool $multiline use linebreaks, if more than + * one attribute is given + * @param string $indent string used for indentation of + * multiline attributes + * @param string $linebreak string used for linebreaks of + * multiline attributes + * @param int $entities setting for entities in attribute values + * (one of XML_UTIL_ENTITIES_NONE, + * XML_UTIL_ENTITIES_XML, + * XML_UTIL_ENTITIES_XML_REQUIRED, + * XML_UTIL_ENTITIES_HTML) + * + * @return string string representation of the attributes + * @uses replaceEntities() to replace XML entities in attribute values + * @todo allow sort also to be an options array + */ + public static function attributesToString( + $attributes, $sort = true, $multiline = false, + $indent = ' ', $linebreak = "\n", $entities = XML_UTIL_ENTITIES_XML + ) { + /* + * second parameter may be an array + */ + if (is_array($sort)) { + if (isset($sort['multiline'])) { + $multiline = $sort['multiline']; + } + if (isset($sort['indent'])) { + $indent = $sort['indent']; + } + if (isset($sort['linebreak'])) { + $multiline = $sort['linebreak']; + } + if (isset($sort['entities'])) { + $entities = $sort['entities']; + } + if (isset($sort['sort'])) { + $sort = $sort['sort']; + } else { + $sort = true; + } + } + $string = ''; + if (is_array($attributes) && !empty($attributes)) { + if ($sort) { + ksort($attributes); + } + if (!$multiline || count($attributes) == 1) { + foreach ($attributes as $key => $value) { + if ($entities != XML_UTIL_ENTITIES_NONE) { + if ($entities === XML_UTIL_CDATA_SECTION) { + $entities = XML_UTIL_ENTITIES_XML; + } + $value = XML_Util::replaceEntities($value, $entities); + } + $string .= ' ' . $key . '="' . $value . '"'; + } + } else { + $first = true; + foreach ($attributes as $key => $value) { + if ($entities != XML_UTIL_ENTITIES_NONE) { + $value = XML_Util::replaceEntities($value, $entities); + } + if ($first) { + $string .= ' ' . $key . '="' . $value . '"'; + $first = false; + } else { + $string .= $linebreak . $indent . $key . '="' . $value . '"'; + } + } + } + } + return $string; + } + + /** + * Collapses empty tags. + * + * @param string $xml XML + * @param int $mode Whether to collapse all empty tags (XML_UTIL_COLLAPSE_ALL) + * or only XHTML (XML_UTIL_COLLAPSE_XHTML_ONLY) ones. + * + * @return string XML + */ + public static function collapseEmptyTags($xml, $mode = XML_UTIL_COLLAPSE_ALL) + { + if ($mode == XML_UTIL_COLLAPSE_XHTML_ONLY) { + return preg_replace( + '/<(area|base(?:font)?|br|col|frame|hr|img|input|isindex|link|meta|' + . 'param)([^>]*)><\/\\1>/s', + '<\\1\\2 />', + $xml + ); + } else { + return preg_replace('/<(\w+)([^>]*)><\/\\1>/s', '<\\1\\2 />', $xml); + } + } + + /** + * Create a tag + * + * This method will call XML_Util::createTagFromArray(), which + * is more flexible. + * + * + * require_once 'XML/Util.php'; + * + * // create an XML tag: + * $tag = XML_Util::createTag('myNs:myTag', + * array('foo' => 'bar'), + * 'This is inside the tag', + * 'http://www.w3c.org/myNs#'); + * + * + * @param string $qname qualified tagname (including namespace) + * @param array $attributes array containg attributes + * @param mixed $content the content + * @param string $namespaceUri URI of the namespace + * @param int $replaceEntities whether to replace XML special chars in + * content, embedd it in a CData section + * or none of both + * @param bool $multiline whether to create a multiline tag where + * each attribute gets written to a single line + * @param string $indent string used to indent attributes + * (_auto indents attributes so they start + * at the same column) + * @param string $linebreak string used for linebreaks + * @param bool $sortAttributes Whether to sort the attributes or not + * + * @return string XML tag + * @see createTagFromArray() + * @uses createTagFromArray() to create the tag + */ + public static function createTag( + $qname, $attributes = array(), $content = null, + $namespaceUri = null, $replaceEntities = XML_UTIL_REPLACE_ENTITIES, + $multiline = false, $indent = '_auto', $linebreak = "\n", + $sortAttributes = true + ) { + $tag = array( + 'qname' => $qname, + 'attributes' => $attributes + ); + + // add tag content + if ($content !== null) { + $tag['content'] = $content; + } + + // add namespace Uri + if ($namespaceUri !== null) { + $tag['namespaceUri'] = $namespaceUri; + } + + return XML_Util::createTagFromArray( + $tag, $replaceEntities, $multiline, + $indent, $linebreak, $sortAttributes + ); + } + + /** + * Create a tag from an array. + * This method awaits an array in the following format + *
    +     * array(
    +     *     // qualified name of the tag
    +     *     'qname' => $qname
    +     *
    +     *     // namespace prefix (optional, if qname is specified or no namespace)
    +     *     'namespace' => $namespace
    +     *
    +     *     // local part of the tagname (optional, if qname is specified)
    +     *     'localpart' => $localpart,
    +     *
    +     *     // array containing all attributes (optional)
    +     *     'attributes' => array(),
    +     *
    +     *     // tag content (optional)
    +     *     'content' => $content,
    +     *
    +     *     // namespaceUri for the given namespace (optional)
    +     *     'namespaceUri' => $namespaceUri
    +     * )
    +     * 
    + * + * + * require_once 'XML/Util.php'; + * + * $tag = array( + * 'qname' => 'foo:bar', + * 'namespaceUri' => 'http://foo.com', + * 'attributes' => array('key' => 'value', 'argh' => 'fruit&vegetable'), + * 'content' => 'I\'m inside the tag', + * ); + * // creating a tag with qualified name and namespaceUri + * $string = XML_Util::createTagFromArray($tag); + * + * + * @param array $tag tag definition + * @param int $replaceEntities whether to replace XML special chars in + * content, embedd it in a CData section + * or none of both + * @param bool $multiline whether to create a multiline tag where each + * attribute gets written to a single line + * @param string $indent string used to indent attributes + * (_auto indents attributes so they start + * at the same column) + * @param string $linebreak string used for linebreaks + * @param bool $sortAttributes Whether to sort the attributes or not + * + * @return string XML tag + * + * @see createTag() + * @uses attributesToString() to serialize the attributes of the tag + * @uses splitQualifiedName() to get local part and namespace of a qualified name + * @uses createCDataSection() + * @uses raiseError() + */ + public static function createTagFromArray( + $tag, $replaceEntities = XML_UTIL_REPLACE_ENTITIES, + $multiline = false, $indent = '_auto', $linebreak = "\n", + $sortAttributes = true + ) { + if (isset($tag['content']) && !is_scalar($tag['content'])) { + return XML_Util::raiseError( + 'Supplied non-scalar value as tag content', + XML_UTIL_ERROR_NON_SCALAR_CONTENT + ); + } + + if (!isset($tag['qname']) && !isset($tag['localPart'])) { + return XML_Util::raiseError( + 'You must either supply a qualified name ' + . '(qname) or local tag name (localPart).', + XML_UTIL_ERROR_NO_TAG_NAME + ); + } + + // if no attributes hav been set, use empty attributes + if (!isset($tag['attributes']) || !is_array($tag['attributes'])) { + $tag['attributes'] = array(); + } + + if (isset($tag['namespaces'])) { + foreach ($tag['namespaces'] as $ns => $uri) { + $tag['attributes']['xmlns:' . $ns] = $uri; + } + } + + if (!isset($tag['qname'])) { + // qualified name is not given + + // check for namespace + if (isset($tag['namespace']) && !empty($tag['namespace'])) { + $tag['qname'] = $tag['namespace'] . ':' . $tag['localPart']; + } else { + $tag['qname'] = $tag['localPart']; + } + } elseif (isset($tag['namespaceUri']) && !isset($tag['namespace'])) { + // namespace URI is set, but no namespace + + $parts = XML_Util::splitQualifiedName($tag['qname']); + + $tag['localPart'] = $parts['localPart']; + if (isset($parts['namespace'])) { + $tag['namespace'] = $parts['namespace']; + } + } + + if (isset($tag['namespaceUri']) && !empty($tag['namespaceUri'])) { + // is a namespace given + if (isset($tag['namespace']) && !empty($tag['namespace'])) { + $tag['attributes']['xmlns:' . $tag['namespace']] + = $tag['namespaceUri']; + } else { + // define this Uri as the default namespace + $tag['attributes']['xmlns'] = $tag['namespaceUri']; + } + } + + // check for multiline attributes + if ($multiline === true) { + if ($indent === '_auto') { + $indent = str_repeat(' ', (strlen($tag['qname'])+2)); + } + } + + // create attribute list + $attList = XML_Util::attributesToString( + $tag['attributes'], + $sortAttributes, $multiline, $indent, $linebreak + ); + if (!isset($tag['content']) || (string)$tag['content'] == '') { + $tag = sprintf('<%s%s />', $tag['qname'], $attList); + } else { + switch ($replaceEntities) { + case XML_UTIL_ENTITIES_NONE: + break; + case XML_UTIL_CDATA_SECTION: + $tag['content'] = XML_Util::createCDataSection($tag['content']); + break; + default: + $tag['content'] = XML_Util::replaceEntities( + $tag['content'], $replaceEntities + ); + break; + } + $tag = sprintf( + '<%s%s>%s', $tag['qname'], $attList, $tag['content'], + $tag['qname'] + ); + } + return $tag; + } + + /** + * Create a start element + * + * + * require_once 'XML/Util.php'; + * + * // create an XML start element: + * $tag = XML_Util::createStartElement('myNs:myTag', + * array('foo' => 'bar') ,'http://www.w3c.org/myNs#'); + * + * + * @param string $qname qualified tagname (including namespace) + * @param array $attributes array containg attributes + * @param string $namespaceUri URI of the namespace + * @param bool $multiline whether to create a multiline tag where each + * attribute gets written to a single line + * @param string $indent string used to indent attributes (_auto indents + * attributes so they start at the same column) + * @param string $linebreak string used for linebreaks + * @param bool $sortAttributes Whether to sort the attributes or not + * + * @return string XML start element + * @see createEndElement(), createTag() + */ + public static function createStartElement( + $qname, $attributes = array(), $namespaceUri = null, + $multiline = false, $indent = '_auto', $linebreak = "\n", + $sortAttributes = true + ) { + // if no attributes hav been set, use empty attributes + if (!isset($attributes) || !is_array($attributes)) { + $attributes = array(); + } + + if ($namespaceUri != null) { + $parts = XML_Util::splitQualifiedName($qname); + } + + // check for multiline attributes + if ($multiline === true) { + if ($indent === '_auto') { + $indent = str_repeat(' ', (strlen($qname)+2)); + } + } + + if ($namespaceUri != null) { + // is a namespace given + if (isset($parts['namespace']) && !empty($parts['namespace'])) { + $attributes['xmlns:' . $parts['namespace']] = $namespaceUri; + } else { + // define this Uri as the default namespace + $attributes['xmlns'] = $namespaceUri; + } + } + + // create attribute list + $attList = XML_Util::attributesToString( + $attributes, $sortAttributes, + $multiline, $indent, $linebreak + ); + $element = sprintf('<%s%s>', $qname, $attList); + return $element; + } + + /** + * Create an end element + * + * + * require_once 'XML/Util.php'; + * + * // create an XML start element: + * $tag = XML_Util::createEndElement('myNs:myTag'); + * + * + * @param string $qname qualified tagname (including namespace) + * + * @return string XML end element + * @see createStartElement(), createTag() + */ + public static function createEndElement($qname) + { + $element = sprintf('', $qname); + return $element; + } + + /** + * Create an XML comment + * + * + * require_once 'XML/Util.php'; + * + * // create an XML start element: + * $tag = XML_Util::createComment('I am a comment'); + * + * + * @param string $content content of the comment + * + * @return string XML comment + */ + public static function createComment($content) + { + $comment = sprintf('', $content); + return $comment; + } + + /** + * Create a CData section + * + * + * require_once 'XML/Util.php'; + * + * // create a CData section + * $tag = XML_Util::createCDataSection('I am content.'); + * + * + * @param string $data data of the CData section + * + * @return string CData section with content + */ + public static function createCDataSection($data) + { + return sprintf( + '', + preg_replace('/\]\]>/', ']]]]>', strval($data)) + ); + } + + /** + * Split qualified name and return namespace and local part + * + * + * require_once 'XML/Util.php'; + * + * // split qualified tag + * $parts = XML_Util::splitQualifiedName('xslt:stylesheet'); + * + * the returned array will contain two elements: + *
    +     * array(
    +     *     'namespace' => 'xslt',
    +     *     'localPart' => 'stylesheet'
    +     * );
    +     * 
    + * + * @param string $qname qualified tag name + * @param string $defaultNs default namespace (optional) + * + * @return array array containing namespace and local part + */ + public static function splitQualifiedName($qname, $defaultNs = null) + { + if (strstr($qname, ':')) { + $tmp = explode(':', $qname); + return array( + 'namespace' => $tmp[0], + 'localPart' => $tmp[1] + ); + } + return array( + 'namespace' => $defaultNs, + 'localPart' => $qname + ); + } + + /** + * Check, whether string is valid XML name + * + *

    XML names are used for tagname, attribute names and various + * other, lesser known entities.

    + *

    An XML name may only consist of alphanumeric characters, + * dashes, undescores and periods, and has to start with a letter + * or an underscore.

    + * + * + * require_once 'XML/Util.php'; + * + * // verify tag name + * $result = XML_Util::isValidName('invalidTag?'); + * if (is_a($result, 'PEAR_Error')) { + * print 'Invalid XML name: ' . $result->getMessage(); + * } + * + * + * @param string $string string that should be checked + * + * @return mixed true, if string is a valid XML name, PEAR error otherwise + * + * @todo support for other charsets + * @todo PEAR CS - unable to avoid 85-char limit on second preg_match + */ + public static function isValidName($string) + { + // check for invalid chars + if (!preg_match('/^[[:alpha:]_]\\z/', $string{0})) { + return XML_Util::raiseError( + 'XML names may only start with letter or underscore', + XML_UTIL_ERROR_INVALID_START + ); + } + + // check for invalid chars + $match = preg_match( + '/^([[:alpha:]_]([[:alnum:]\-\.]*)?:)?' + . '[[:alpha:]_]([[:alnum:]\_\-\.]+)?\\z/', + $string + ); + if (!$match) { + return XML_Util::raiseError( + 'XML names may only contain alphanumeric ' + . 'chars, period, hyphen, colon and underscores', + XML_UTIL_ERROR_INVALID_CHARS + ); + } + // XML name is valid + return true; + } + + /** + * Replacement for XML_Util::raiseError + * + * Avoids the necessity to always require + * PEAR.php + * + * @param string $msg error message + * @param int $code error code + * + * @return PEAR_Error + * @todo PEAR CS - should this use include_once instead? + */ + public static function raiseError($msg, $code) + { + include_once 'PEAR.php'; + return PEAR::raiseError($msg, $code); + } +} +?> diff --git a/lib/ckfinder/core/connector/php/vendor/pimple/pimple/src/Pimple/Container.php b/lib/ckfinder/core/connector/php/vendor/pimple/pimple/src/Pimple/Container.php new file mode 100644 index 0000000..c976431 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pimple/pimple/src/Pimple/Container.php @@ -0,0 +1,282 @@ +factories = new \SplObjectStorage(); + $this->protected = new \SplObjectStorage(); + + foreach ($values as $key => $value) { + $this->offsetSet($key, $value); + } + } + + /** + * Sets a parameter or an object. + * + * Objects must be defined as Closures. + * + * Allowing any PHP callable leads to difficult to debug problems + * as function names (strings) are callable (creating a function with + * the same name as an existing parameter would break your container). + * + * @param string $id The unique identifier for the parameter or object + * @param mixed $value The value of the parameter or a closure to define an object + * + * @throws \RuntimeException Prevent override of a frozen service + */ + public function offsetSet($id, $value) + { + if (isset($this->frozen[$id])) { + throw new \RuntimeException(sprintf('Cannot override frozen service "%s".', $id)); + } + + $this->values[$id] = $value; + $this->keys[$id] = true; + } + + /** + * Gets a parameter or an object. + * + * @param string $id The unique identifier for the parameter or object + * + * @return mixed The value of the parameter or an object + * + * @throws \InvalidArgumentException if the identifier is not defined + */ + public function offsetGet($id) + { + if (!isset($this->keys[$id])) { + throw new \InvalidArgumentException(sprintf('Identifier "%s" is not defined.', $id)); + } + + if ( + isset($this->raw[$id]) + || !is_object($this->values[$id]) + || isset($this->protected[$this->values[$id]]) + || !method_exists($this->values[$id], '__invoke') + ) { + return $this->values[$id]; + } + + if (isset($this->factories[$this->values[$id]])) { + return $this->values[$id]($this); + } + + $raw = $this->values[$id]; + $val = $this->values[$id] = $raw($this); + $this->raw[$id] = $raw; + + $this->frozen[$id] = true; + + return $val; + } + + /** + * Checks if a parameter or an object is set. + * + * @param string $id The unique identifier for the parameter or object + * + * @return bool + */ + public function offsetExists($id) + { + return isset($this->keys[$id]); + } + + /** + * Unsets a parameter or an object. + * + * @param string $id The unique identifier for the parameter or object + */ + public function offsetUnset($id) + { + if (isset($this->keys[$id])) { + if (is_object($this->values[$id])) { + unset($this->factories[$this->values[$id]], $this->protected[$this->values[$id]]); + } + + unset($this->values[$id], $this->frozen[$id], $this->raw[$id], $this->keys[$id]); + } + } + + /** + * Marks a callable as being a factory service. + * + * @param callable $callable A service definition to be used as a factory + * + * @return callable The passed callable + * + * @throws \InvalidArgumentException Service definition has to be a closure of an invokable object + */ + public function factory($callable) + { + if (!method_exists($callable, '__invoke')) { + throw new \InvalidArgumentException('Service definition is not a Closure or invokable object.'); + } + + $this->factories->attach($callable); + + return $callable; + } + + /** + * Protects a callable from being interpreted as a service. + * + * This is useful when you want to store a callable as a parameter. + * + * @param callable $callable A callable to protect from being evaluated + * + * @return callable The passed callable + * + * @throws \InvalidArgumentException Service definition has to be a closure of an invokable object + */ + public function protect($callable) + { + if (!method_exists($callable, '__invoke')) { + throw new \InvalidArgumentException('Callable is not a Closure or invokable object.'); + } + + $this->protected->attach($callable); + + return $callable; + } + + /** + * Gets a parameter or the closure defining an object. + * + * @param string $id The unique identifier for the parameter or object + * + * @return mixed The value of the parameter or the closure defining an object + * + * @throws \InvalidArgumentException if the identifier is not defined + */ + public function raw($id) + { + if (!isset($this->keys[$id])) { + throw new \InvalidArgumentException(sprintf('Identifier "%s" is not defined.', $id)); + } + + if (isset($this->raw[$id])) { + return $this->raw[$id]; + } + + return $this->values[$id]; + } + + /** + * Extends an object definition. + * + * Useful when you want to extend an existing object definition, + * without necessarily loading that object. + * + * @param string $id The unique identifier for the object + * @param callable $callable A service definition to extend the original + * + * @return callable The wrapped callable + * + * @throws \InvalidArgumentException if the identifier is not defined or not a service definition + */ + public function extend($id, $callable) + { + if (!isset($this->keys[$id])) { + throw new \InvalidArgumentException(sprintf('Identifier "%s" is not defined.', $id)); + } + + if (!is_object($this->values[$id]) || !method_exists($this->values[$id], '__invoke')) { + throw new \InvalidArgumentException(sprintf('Identifier "%s" does not contain an object definition.', $id)); + } + + if (!is_object($callable) || !method_exists($callable, '__invoke')) { + throw new \InvalidArgumentException('Extension service definition is not a Closure or invokable object.'); + } + + $factory = $this->values[$id]; + + $extended = function ($c) use ($callable, $factory) { + return $callable($factory($c), $c); + }; + + if (isset($this->factories[$factory])) { + $this->factories->detach($factory); + $this->factories->attach($extended); + } + + return $this[$id] = $extended; + } + + /** + * Returns all defined value names. + * + * @return array An array of value names + */ + public function keys() + { + return array_keys($this->values); + } + + /** + * Registers a service provider. + * + * @param ServiceProviderInterface $provider A ServiceProviderInterface instance + * @param array $values An array of values that customizes the provider + * + * @return static + */ + public function register(ServiceProviderInterface $provider, array $values = array()) + { + $provider->register($this); + + foreach ($values as $key => $value) { + $this[$key] = $value; + } + + return $this; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/pimple/pimple/src/Pimple/ServiceProviderInterface.php b/lib/ckfinder/core/connector/php/vendor/pimple/pimple/src/Pimple/ServiceProviderInterface.php new file mode 100644 index 0000000..c004594 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/pimple/pimple/src/Pimple/ServiceProviderInterface.php @@ -0,0 +1,46 @@ +log(LogLevel::EMERGENCY, $message, $context); + } + + /** + * Action must be taken immediately. + * + * Example: Entire website down, database unavailable, etc. This should + * trigger the SMS alerts and wake you up. + * + * @param string $message + * @param array $context + * + * @return null + */ + public function alert($message, array $context = array()) + { + $this->log(LogLevel::ALERT, $message, $context); + } + + /** + * Critical conditions. + * + * Example: Application component unavailable, unexpected exception. + * + * @param string $message + * @param array $context + * + * @return null + */ + public function critical($message, array $context = array()) + { + $this->log(LogLevel::CRITICAL, $message, $context); + } + + /** + * Runtime errors that do not require immediate action but should typically + * be logged and monitored. + * + * @param string $message + * @param array $context + * + * @return null + */ + public function error($message, array $context = array()) + { + $this->log(LogLevel::ERROR, $message, $context); + } + + /** + * Exceptional occurrences that are not errors. + * + * Example: Use of deprecated APIs, poor use of an API, undesirable things + * that are not necessarily wrong. + * + * @param string $message + * @param array $context + * + * @return null + */ + public function warning($message, array $context = array()) + { + $this->log(LogLevel::WARNING, $message, $context); + } + + /** + * Normal but significant events. + * + * @param string $message + * @param array $context + * + * @return null + */ + public function notice($message, array $context = array()) + { + $this->log(LogLevel::NOTICE, $message, $context); + } + + /** + * Interesting events. + * + * Example: User logs in, SQL logs. + * + * @param string $message + * @param array $context + * + * @return null + */ + public function info($message, array $context = array()) + { + $this->log(LogLevel::INFO, $message, $context); + } + + /** + * Detailed debug information. + * + * @param string $message + * @param array $context + * + * @return null + */ + public function debug($message, array $context = array()) + { + $this->log(LogLevel::DEBUG, $message, $context); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/psr/log/Psr/Log/InvalidArgumentException.php b/lib/ckfinder/core/connector/php/vendor/psr/log/Psr/Log/InvalidArgumentException.php new file mode 100644 index 0000000..67f852d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/psr/log/Psr/Log/InvalidArgumentException.php @@ -0,0 +1,7 @@ +logger = $logger; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/psr/log/Psr/Log/LoggerInterface.php b/lib/ckfinder/core/connector/php/vendor/psr/log/Psr/Log/LoggerInterface.php new file mode 100644 index 0000000..16c04ad --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/psr/log/Psr/Log/LoggerInterface.php @@ -0,0 +1,123 @@ +log(LogLevel::EMERGENCY, $message, $context); + } + + /** + * Action must be taken immediately. + * + * Example: Entire website down, database unavailable, etc. This should + * trigger the SMS alerts and wake you up. + * + * @param string $message + * @param array $context + * + * @return null + */ + public function alert($message, array $context = array()) + { + $this->log(LogLevel::ALERT, $message, $context); + } + + /** + * Critical conditions. + * + * Example: Application component unavailable, unexpected exception. + * + * @param string $message + * @param array $context + * + * @return null + */ + public function critical($message, array $context = array()) + { + $this->log(LogLevel::CRITICAL, $message, $context); + } + + /** + * Runtime errors that do not require immediate action but should typically + * be logged and monitored. + * + * @param string $message + * @param array $context + * + * @return null + */ + public function error($message, array $context = array()) + { + $this->log(LogLevel::ERROR, $message, $context); + } + + /** + * Exceptional occurrences that are not errors. + * + * Example: Use of deprecated APIs, poor use of an API, undesirable things + * that are not necessarily wrong. + * + * @param string $message + * @param array $context + * + * @return null + */ + public function warning($message, array $context = array()) + { + $this->log(LogLevel::WARNING, $message, $context); + } + + /** + * Normal but significant events. + * + * @param string $message + * @param array $context + * + * @return null + */ + public function notice($message, array $context = array()) + { + $this->log(LogLevel::NOTICE, $message, $context); + } + + /** + * Interesting events. + * + * Example: User logs in, SQL logs. + * + * @param string $message + * @param array $context + * + * @return null + */ + public function info($message, array $context = array()) + { + $this->log(LogLevel::INFO, $message, $context); + } + + /** + * Detailed debug information. + * + * @param string $message + * @param array $context + * + * @return null + */ + public function debug($message, array $context = array()) + { + $this->log(LogLevel::DEBUG, $message, $context); + } + + /** + * Logs with an arbitrary level. + * + * @param mixed $level + * @param string $message + * @param array $context + * + * @return null + */ + abstract public function log($level, $message, array $context = array()); +} diff --git a/lib/ckfinder/core/connector/php/vendor/psr/log/Psr/Log/NullLogger.php b/lib/ckfinder/core/connector/php/vendor/psr/log/Psr/Log/NullLogger.php new file mode 100644 index 0000000..3fc5100 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/psr/log/Psr/Log/NullLogger.php @@ -0,0 +1,28 @@ +logger) { }` + * blocks. + */ +class NullLogger extends AbstractLogger +{ + /** + * Logs with an arbitrary level. + * + * @param mixed $level + * @param string $message + * @param array $context + * + * @return null + */ + public function log($level, $message, array $context = array()) + { + // noop + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/debug/BufferingLogger.php b/lib/ckfinder/core/connector/php/vendor/symfony/debug/BufferingLogger.php new file mode 100644 index 0000000..a2ed75b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/debug/BufferingLogger.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Debug; + +use Psr\Log\AbstractLogger; + +/** + * A buffering logger that stacks logs for later. + * + * @author Nicolas Grekas + */ +class BufferingLogger extends AbstractLogger +{ + private $logs = array(); + + public function log($level, $message, array $context = array()) + { + $this->logs[] = array($level, $message, $context); + } + + public function cleanLogs() + { + $logs = $this->logs; + $this->logs = array(); + + return $logs; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/debug/Debug.php b/lib/ckfinder/core/connector/php/vendor/symfony/debug/Debug.php new file mode 100644 index 0000000..9404992 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/debug/Debug.php @@ -0,0 +1,63 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Debug; + +/** + * Registers all the debug tools. + * + * @author Fabien Potencier + */ +class Debug +{ + private static $enabled = false; + + /** + * Enables the debug tools. + * + * This method registers an error handler and an exception handler. + * + * If the Symfony ClassLoader component is available, a special + * class loader is also registered. + * + * @param int $errorReportingLevel The level of error reporting you want + * @param bool $displayErrors Whether to display errors (for development) or just log them (for production) + */ + public static function enable($errorReportingLevel = null, $displayErrors = true) + { + if (static::$enabled) { + return; + } + + static::$enabled = true; + + if (null !== $errorReportingLevel) { + error_reporting($errorReportingLevel); + } else { + error_reporting(-1); + } + + if ('cli' !== PHP_SAPI) { + ini_set('display_errors', 0); + ExceptionHandler::register(); + } elseif ($displayErrors && (!ini_get('log_errors') || ini_get('error_log'))) { + // CLI - display errors only if they're not already logged to STDERR + ini_set('display_errors', 1); + } + if ($displayErrors) { + ErrorHandler::register(new ErrorHandler(new BufferingLogger())); + } else { + ErrorHandler::register()->throwAt(0, true); + } + + DebugClassLoader::enable(); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/debug/DebugClassLoader.php b/lib/ckfinder/core/connector/php/vendor/symfony/debug/DebugClassLoader.php new file mode 100644 index 0000000..12d379a --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/debug/DebugClassLoader.php @@ -0,0 +1,349 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Debug; + +/** + * Autoloader checking if the class is really defined in the file found. + * + * The ClassLoader will wrap all registered autoloaders + * and will throw an exception if a file is found but does + * not declare the class. + * + * @author Fabien Potencier + * @author Christophe Coevoet + * @author Nicolas Grekas + */ +class DebugClassLoader +{ + private $classLoader; + private $isFinder; + private $wasFinder; + private static $caseCheck; + private static $deprecated = array(); + private static $php7Reserved = array('int', 'float', 'bool', 'string', 'true', 'false', 'null'); + private static $darwinCache = array('/' => array('/', array())); + + /** + * Constructor. + * + * @param callable|object $classLoader Passing an object is @deprecated since version 2.5 and support for it will be removed in 3.0 + */ + public function __construct($classLoader) + { + $this->wasFinder = is_object($classLoader) && method_exists($classLoader, 'findFile'); + + if ($this->wasFinder) { + @trigger_error('The '.__METHOD__.' method will no longer support receiving an object into its $classLoader argument in 3.0.', E_USER_DEPRECATED); + $this->classLoader = array($classLoader, 'loadClass'); + $this->isFinder = true; + } else { + $this->classLoader = $classLoader; + $this->isFinder = is_array($classLoader) && method_exists($classLoader[0], 'findFile'); + } + + if (!isset(self::$caseCheck)) { + $file = file_exists(__FILE__) ? __FILE__ : rtrim(realpath('.'), DIRECTORY_SEPARATOR); + $i = strrpos($file, DIRECTORY_SEPARATOR); + $dir = substr($file, 0, 1 + $i); + $file = substr($file, 1 + $i); + $test = strtoupper($file) === $file ? strtolower($file) : strtoupper($file); + $test = realpath($dir.$test); + + if (false === $test || false === $i) { + // filesystem is case sensitive + self::$caseCheck = 0; + } elseif (substr($test, -strlen($file)) === $file) { + // filesystem is case insensitive and realpath() normalizes the case of characters + self::$caseCheck = 1; + } elseif (false !== stripos(PHP_OS, 'darwin')) { + // on MacOSX, HFS+ is case insensitive but realpath() doesn't normalize the case of characters + self::$caseCheck = 2; + } else { + // filesystem case checks failed, fallback to disabling them + self::$caseCheck = 0; + } + } + } + + /** + * Gets the wrapped class loader. + * + * @return callable|object A class loader. Since version 2.5, returning an object is @deprecated and support for it will be removed in 3.0 + */ + public function getClassLoader() + { + return $this->wasFinder ? $this->classLoader[0] : $this->classLoader; + } + + /** + * Wraps all autoloaders. + */ + public static function enable() + { + // Ensures we don't hit https://bugs.php.net/42098 + class_exists('Symfony\Component\Debug\ErrorHandler'); + class_exists('Psr\Log\LogLevel'); + + if (!is_array($functions = spl_autoload_functions())) { + return; + } + + foreach ($functions as $function) { + spl_autoload_unregister($function); + } + + foreach ($functions as $function) { + if (!is_array($function) || !$function[0] instanceof self) { + $function = array(new static($function), 'loadClass'); + } + + spl_autoload_register($function); + } + } + + /** + * Disables the wrapping. + */ + public static function disable() + { + if (!is_array($functions = spl_autoload_functions())) { + return; + } + + foreach ($functions as $function) { + spl_autoload_unregister($function); + } + + foreach ($functions as $function) { + if (is_array($function) && $function[0] instanceof self) { + $function = $function[0]->getClassLoader(); + } + + spl_autoload_register($function); + } + } + + /** + * Finds a file by class name. + * + * @param string $class A class name to resolve to file + * + * @return string|null + * + * @deprecated since version 2.5, to be removed in 3.0. + */ + public function findFile($class) + { + @trigger_error('The '.__METHOD__.' method is deprecated since version 2.5 and will be removed in 3.0.', E_USER_DEPRECATED); + + if ($this->wasFinder) { + return $this->classLoader[0]->findFile($class); + } + } + + /** + * Loads the given class or interface. + * + * @param string $class The name of the class + * + * @return bool|null True, if loaded + * + * @throws \RuntimeException + */ + public function loadClass($class) + { + ErrorHandler::stackErrors(); + + try { + if ($this->isFinder) { + if ($file = $this->classLoader[0]->findFile($class)) { + require_once $file; + } + } else { + call_user_func($this->classLoader, $class); + $file = false; + } + } catch (\Exception $e) { + ErrorHandler::unstackErrors(); + + throw $e; + } catch (\Throwable $e) { + ErrorHandler::unstackErrors(); + + throw $e; + } + + ErrorHandler::unstackErrors(); + + $exists = class_exists($class, false) || interface_exists($class, false) || (function_exists('trait_exists') && trait_exists($class, false)); + + if ('\\' === $class[0]) { + $class = substr($class, 1); + } + + if ($exists) { + $refl = new \ReflectionClass($class); + $name = $refl->getName(); + + if ($name !== $class && 0 === strcasecmp($name, $class)) { + throw new \RuntimeException(sprintf('Case mismatch between loaded and declared class names: %s vs %s', $class, $name)); + } + + if (in_array(strtolower($refl->getShortName()), self::$php7Reserved)) { + @trigger_error(sprintf('%s uses a reserved class name (%s) that will break on PHP 7 and higher', $name, $refl->getShortName()), E_USER_DEPRECATED); + } elseif (preg_match('#\n \* @deprecated (.*?)\r?\n \*(?: @|/$)#s', $refl->getDocComment(), $notice)) { + self::$deprecated[$name] = preg_replace('#\s*\r?\n \* +#', ' ', $notice[1]); + } else { + if (2 > $len = 1 + (strpos($name, '\\', 1 + strpos($name, '\\')) ?: strpos($name, '_'))) { + $len = 0; + $ns = ''; + } else { + switch ($ns = substr($name, 0, $len)) { + case 'Symfony\Bridge\\': + case 'Symfony\Bundle\\': + case 'Symfony\Component\\': + $ns = 'Symfony\\'; + $len = strlen($ns); + break; + } + } + $parent = get_parent_class($class); + + if (!$parent || strncmp($ns, $parent, $len)) { + if ($parent && isset(self::$deprecated[$parent]) && strncmp($ns, $parent, $len)) { + @trigger_error(sprintf('The %s class extends %s that is deprecated %s', $name, $parent, self::$deprecated[$parent]), E_USER_DEPRECATED); + } + + $parentInterfaces = array(); + $deprecatedInterfaces = array(); + if ($parent) { + foreach (class_implements($parent) as $interface) { + $parentInterfaces[$interface] = 1; + } + } + + foreach ($refl->getInterfaceNames() as $interface) { + if (isset(self::$deprecated[$interface]) && strncmp($ns, $interface, $len)) { + $deprecatedInterfaces[] = $interface; + } + foreach (class_implements($interface) as $interface) { + $parentInterfaces[$interface] = 1; + } + } + + foreach ($deprecatedInterfaces as $interface) { + if (!isset($parentInterfaces[$interface])) { + @trigger_error(sprintf('The %s %s %s that is deprecated %s', $name, $refl->isInterface() ? 'interface extends' : 'class implements', $interface, self::$deprecated[$interface]), E_USER_DEPRECATED); + } + } + } + } + } + + if ($file) { + if (!$exists) { + if (false !== strpos($class, '/')) { + throw new \RuntimeException(sprintf('Trying to autoload a class with an invalid name "%s". Be careful that the namespace separator is "\" in PHP, not "/".', $class)); + } + + throw new \RuntimeException(sprintf('The autoloader expected class "%s" to be defined in file "%s". The file was found but the class was not in it, the class name or namespace probably has a typo.', $class, $file)); + } + if (self::$caseCheck) { + $real = explode('\\', $class.strrchr($file, '.')); + $tail = explode(DIRECTORY_SEPARATOR, str_replace('/', DIRECTORY_SEPARATOR, $file)); + + $i = count($tail) - 1; + $j = count($real) - 1; + + while (isset($tail[$i], $real[$j]) && $tail[$i] === $real[$j]) { + --$i; + --$j; + } + + array_splice($tail, 0, $i + 1); + } + if (self::$caseCheck && $tail) { + $tail = DIRECTORY_SEPARATOR.implode(DIRECTORY_SEPARATOR, $tail); + $tailLen = strlen($tail); + $real = $refl->getFileName(); + + if (2 === self::$caseCheck) { + // realpath() on MacOSX doesn't normalize the case of characters + + $i = 1 + strrpos($real, '/'); + $file = substr($real, $i); + $real = substr($real, 0, $i); + + if (isset(self::$darwinCache[$real])) { + $kDir = $real; + } else { + $kDir = strtolower($real); + + if (isset(self::$darwinCache[$kDir])) { + $real = self::$darwinCache[$kDir][0]; + } else { + $dir = getcwd(); + chdir($real); + $real = getcwd().'/'; + chdir($dir); + + $dir = $real; + $k = $kDir; + $i = strlen($dir) - 1; + while (!isset(self::$darwinCache[$k])) { + self::$darwinCache[$k] = array($dir, array()); + self::$darwinCache[$dir] = &self::$darwinCache[$k]; + + while ('/' !== $dir[--$i]) { + } + $k = substr($k, 0, ++$i); + $dir = substr($dir, 0, $i--); + } + } + } + + $dirFiles = self::$darwinCache[$kDir][1]; + + if (isset($dirFiles[$file])) { + $kFile = $file; + } else { + $kFile = strtolower($file); + + if (!isset($dirFiles[$kFile])) { + foreach (scandir($real, 2) as $f) { + if ('.' !== $f[0]) { + $dirFiles[$f] = $f; + if ($f === $file) { + $kFile = $k = $file; + } elseif ($f !== $k = strtolower($f)) { + $dirFiles[$k] = $f; + } + } + } + self::$darwinCache[$kDir][1] = $dirFiles; + } + } + + $real .= $dirFiles[$kFile]; + } + + if (0 === substr_compare($real, $tail, -$tailLen, $tailLen, true) + && 0 !== substr_compare($real, $tail, -$tailLen, $tailLen, false) + ) { + throw new \RuntimeException(sprintf('Case mismatch between class and real file names: %s vs %s in %s', substr($tail, -$tailLen + 1), substr($real, -$tailLen + 1), substr($real, 0, -$tailLen + 1))); + } + } + + return true; + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/debug/ErrorHandler.php b/lib/ckfinder/core/connector/php/vendor/symfony/debug/ErrorHandler.php new file mode 100644 index 0000000..4739455 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/debug/ErrorHandler.php @@ -0,0 +1,829 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Debug; + +use Psr\Log\LogLevel; +use Psr\Log\LoggerInterface; +use Symfony\Component\Debug\Exception\ContextErrorException; +use Symfony\Component\Debug\Exception\FatalErrorException; +use Symfony\Component\Debug\Exception\FatalThrowableError; +use Symfony\Component\Debug\Exception\OutOfMemoryException; +use Symfony\Component\Debug\FatalErrorHandler\UndefinedFunctionFatalErrorHandler; +use Symfony\Component\Debug\FatalErrorHandler\UndefinedMethodFatalErrorHandler; +use Symfony\Component\Debug\FatalErrorHandler\ClassNotFoundFatalErrorHandler; +use Symfony\Component\Debug\FatalErrorHandler\FatalErrorHandlerInterface; + +/** + * A generic ErrorHandler for the PHP engine. + * + * Provides five bit fields that control how errors are handled: + * - thrownErrors: errors thrown as \ErrorException + * - loggedErrors: logged errors, when not @-silenced + * - scopedErrors: errors thrown or logged with their local context + * - tracedErrors: errors logged with their stack trace, only once for repeated errors + * - screamedErrors: never @-silenced errors + * + * Each error level can be logged by a dedicated PSR-3 logger object. + * Screaming only applies to logging. + * Throwing takes precedence over logging. + * Uncaught exceptions are logged as E_ERROR. + * E_DEPRECATED and E_USER_DEPRECATED levels never throw. + * E_RECOVERABLE_ERROR and E_USER_ERROR levels always throw. + * Non catchable errors that can be detected at shutdown time are logged when the scream bit field allows so. + * As errors have a performance cost, repeated errors are all logged, so that the developer + * can see them and weight them as more important to fix than others of the same level. + * + * @author Nicolas Grekas + */ +class ErrorHandler +{ + /** + * @deprecated since version 2.6, to be removed in 3.0. + */ + const TYPE_DEPRECATION = -100; + + private $levels = array( + E_DEPRECATED => 'Deprecated', + E_USER_DEPRECATED => 'User Deprecated', + E_NOTICE => 'Notice', + E_USER_NOTICE => 'User Notice', + E_STRICT => 'Runtime Notice', + E_WARNING => 'Warning', + E_USER_WARNING => 'User Warning', + E_COMPILE_WARNING => 'Compile Warning', + E_CORE_WARNING => 'Core Warning', + E_USER_ERROR => 'User Error', + E_RECOVERABLE_ERROR => 'Catchable Fatal Error', + E_COMPILE_ERROR => 'Compile Error', + E_PARSE => 'Parse Error', + E_ERROR => 'Error', + E_CORE_ERROR => 'Core Error', + ); + + private $loggers = array( + E_DEPRECATED => array(null, LogLevel::INFO), + E_USER_DEPRECATED => array(null, LogLevel::INFO), + E_NOTICE => array(null, LogLevel::WARNING), + E_USER_NOTICE => array(null, LogLevel::WARNING), + E_STRICT => array(null, LogLevel::WARNING), + E_WARNING => array(null, LogLevel::WARNING), + E_USER_WARNING => array(null, LogLevel::WARNING), + E_COMPILE_WARNING => array(null, LogLevel::WARNING), + E_CORE_WARNING => array(null, LogLevel::WARNING), + E_USER_ERROR => array(null, LogLevel::CRITICAL), + E_RECOVERABLE_ERROR => array(null, LogLevel::CRITICAL), + E_COMPILE_ERROR => array(null, LogLevel::CRITICAL), + E_PARSE => array(null, LogLevel::CRITICAL), + E_ERROR => array(null, LogLevel::CRITICAL), + E_CORE_ERROR => array(null, LogLevel::CRITICAL), + ); + + private $thrownErrors = 0x1FFF; // E_ALL - E_DEPRECATED - E_USER_DEPRECATED + private $scopedErrors = 0x1FFF; // E_ALL - E_DEPRECATED - E_USER_DEPRECATED + private $tracedErrors = 0x77FB; // E_ALL - E_STRICT - E_PARSE + private $screamedErrors = 0x55; // E_ERROR + E_CORE_ERROR + E_COMPILE_ERROR + E_PARSE + private $loggedErrors = 0; + + private $loggedTraces = array(); + private $isRecursive = 0; + private $isRoot = false; + private $exceptionHandler; + private $bootstrappingLogger; + + private static $reservedMemory; + private static $stackedErrors = array(); + private static $stackedErrorLevels = array(); + private static $toStringException = null; + + /** + * Same init value as thrownErrors. + * + * @deprecated since version 2.6, to be removed in 3.0. + */ + private $displayErrors = 0x1FFF; + + /** + * Registers the error handler. + * + * @param self|null|int $handler The handler to register, or @deprecated (since version 2.6, to be removed in 3.0) bit field of thrown levels + * @param bool $replace Whether to replace or not any existing handler + * + * @return self The registered error handler + */ + public static function register($handler = null, $replace = true) + { + if (null === self::$reservedMemory) { + self::$reservedMemory = str_repeat('x', 10240); + register_shutdown_function(__CLASS__.'::handleFatalError'); + } + + $levels = -1; + + if ($handlerIsNew = !$handler instanceof self) { + // @deprecated polymorphism, to be removed in 3.0 + if (null !== $handler) { + $levels = $replace ? $handler : 0; + $replace = true; + } + $handler = new static(); + } + + if (null === $prev = set_error_handler(array($handler, 'handleError'))) { + restore_error_handler(); + // Specifying the error types earlier would expose us to https://bugs.php.net/63206 + set_error_handler(array($handler, 'handleError'), $handler->thrownErrors | $handler->loggedErrors); + $handler->isRoot = true; + } + + if ($handlerIsNew && is_array($prev) && $prev[0] instanceof self) { + $handler = $prev[0]; + $replace = false; + } + if ($replace || !$prev) { + $handler->setExceptionHandler(set_exception_handler(array($handler, 'handleException'))); + } else { + restore_error_handler(); + } + + $handler->throwAt($levels & $handler->thrownErrors, true); + + return $handler; + } + + public function __construct(BufferingLogger $bootstrappingLogger = null) + { + if ($bootstrappingLogger) { + $this->bootstrappingLogger = $bootstrappingLogger; + $this->setDefaultLogger($bootstrappingLogger); + } + } + + /** + * Sets a logger to non assigned errors levels. + * + * @param LoggerInterface $logger A PSR-3 logger to put as default for the given levels + * @param array|int $levels An array map of E_* to LogLevel::* or an integer bit field of E_* constants + * @param bool $replace Whether to replace or not any existing logger + */ + public function setDefaultLogger(LoggerInterface $logger, $levels = null, $replace = false) + { + $loggers = array(); + + if (is_array($levels)) { + foreach ($levels as $type => $logLevel) { + if (empty($this->loggers[$type][0]) || $replace || $this->loggers[$type][0] === $this->bootstrappingLogger) { + $loggers[$type] = array($logger, $logLevel); + } + } + } else { + if (null === $levels) { + $levels = E_ALL | E_STRICT; + } + foreach ($this->loggers as $type => $log) { + if (($type & $levels) && (empty($log[0]) || $replace || $log[0] === $this->bootstrappingLogger)) { + $log[0] = $logger; + $loggers[$type] = $log; + } + } + } + + $this->setLoggers($loggers); + } + + /** + * Sets a logger for each error level. + * + * @param array $loggers Error levels to [LoggerInterface|null, LogLevel::*] map + * + * @return array The previous map + * + * @throws \InvalidArgumentException + */ + public function setLoggers(array $loggers) + { + $prevLogged = $this->loggedErrors; + $prev = $this->loggers; + $flush = array(); + + foreach ($loggers as $type => $log) { + if (!isset($prev[$type])) { + throw new \InvalidArgumentException('Unknown error type: '.$type); + } + if (!is_array($log)) { + $log = array($log); + } elseif (!array_key_exists(0, $log)) { + throw new \InvalidArgumentException('No logger provided'); + } + if (null === $log[0]) { + $this->loggedErrors &= ~$type; + } elseif ($log[0] instanceof LoggerInterface) { + $this->loggedErrors |= $type; + } else { + throw new \InvalidArgumentException('Invalid logger provided'); + } + $this->loggers[$type] = $log + $prev[$type]; + + if ($this->bootstrappingLogger && $prev[$type][0] === $this->bootstrappingLogger) { + $flush[$type] = $type; + } + } + $this->reRegister($prevLogged | $this->thrownErrors); + + if ($flush) { + foreach ($this->bootstrappingLogger->cleanLogs() as $log) { + $type = $log[2]['type']; + if (!isset($flush[$type])) { + $this->bootstrappingLogger->log($log[0], $log[1], $log[2]); + } elseif ($this->loggers[$type][0]) { + $this->loggers[$type][0]->log($this->loggers[$type][1], $log[1], $log[2]); + } + } + } + + return $prev; + } + + /** + * Sets a user exception handler. + * + * @param callable $handler A handler that will be called on Exception + * + * @return callable|null The previous exception handler + * + * @throws \InvalidArgumentException + */ + public function setExceptionHandler($handler) + { + if (null !== $handler && !is_callable($handler)) { + throw new \LogicException('The exception handler must be a valid PHP callable.'); + } + $prev = $this->exceptionHandler; + $this->exceptionHandler = $handler; + + return $prev; + } + + /** + * Sets the PHP error levels that throw an exception when a PHP error occurs. + * + * @param int $levels A bit field of E_* constants for thrown errors + * @param bool $replace Replace or amend the previous value + * + * @return int The previous value + */ + public function throwAt($levels, $replace = false) + { + $prev = $this->thrownErrors; + $this->thrownErrors = ($levels | E_RECOVERABLE_ERROR | E_USER_ERROR) & ~E_USER_DEPRECATED & ~E_DEPRECATED; + if (!$replace) { + $this->thrownErrors |= $prev; + } + $this->reRegister($prev | $this->loggedErrors); + + // $this->displayErrors is @deprecated since version 2.6 + $this->displayErrors = $this->thrownErrors; + + return $prev; + } + + /** + * Sets the PHP error levels for which local variables are preserved. + * + * @param int $levels A bit field of E_* constants for scoped errors + * @param bool $replace Replace or amend the previous value + * + * @return int The previous value + */ + public function scopeAt($levels, $replace = false) + { + $prev = $this->scopedErrors; + $this->scopedErrors = (int) $levels; + if (!$replace) { + $this->scopedErrors |= $prev; + } + + return $prev; + } + + /** + * Sets the PHP error levels for which the stack trace is preserved. + * + * @param int $levels A bit field of E_* constants for traced errors + * @param bool $replace Replace or amend the previous value + * + * @return int The previous value + */ + public function traceAt($levels, $replace = false) + { + $prev = $this->tracedErrors; + $this->tracedErrors = (int) $levels; + if (!$replace) { + $this->tracedErrors |= $prev; + } + + return $prev; + } + + /** + * Sets the error levels where the @-operator is ignored. + * + * @param int $levels A bit field of E_* constants for screamed errors + * @param bool $replace Replace or amend the previous value + * + * @return int The previous value + */ + public function screamAt($levels, $replace = false) + { + $prev = $this->screamedErrors; + $this->screamedErrors = (int) $levels; + if (!$replace) { + $this->screamedErrors |= $prev; + } + + return $prev; + } + + /** + * Re-registers as a PHP error handler if levels changed. + */ + private function reRegister($prev) + { + if ($prev !== $this->thrownErrors | $this->loggedErrors) { + $handler = set_error_handler('var_dump'); + $handler = is_array($handler) ? $handler[0] : null; + restore_error_handler(); + if ($handler === $this) { + restore_error_handler(); + if ($this->isRoot) { + set_error_handler(array($this, 'handleError'), $this->thrownErrors | $this->loggedErrors); + } else { + set_error_handler(array($this, 'handleError')); + } + } + } + } + + /** + * Handles errors by filtering then logging them according to the configured bit fields. + * + * @param int $type One of the E_* constants + * @param string $message + * @param string $file + * @param int $line + * @param array $context + * @param array $backtrace + * + * @return bool Returns false when no handling happens so that the PHP engine can handle the error itself + * + * @throws \ErrorException When $this->thrownErrors requests so + * + * @internal + */ + public function handleError($type, $message, $file, $line, array $context, array $backtrace = null) + { + $level = error_reporting() | E_RECOVERABLE_ERROR | E_USER_ERROR | E_DEPRECATED | E_USER_DEPRECATED; + $log = $this->loggedErrors & $type; + $throw = $this->thrownErrors & $type & $level; + $type &= $level | $this->screamedErrors; + + if (!$type || (!$log && !$throw)) { + return $type && $log; + } + + if (PHP_VERSION_ID < 50400 && isset($context['GLOBALS']) && ($this->scopedErrors & $type)) { + $e = $context; // Whatever the signature of the method, + unset($e['GLOBALS'], $context); // $context is always a reference in 5.3 + $context = $e; + } + + if (null !== $backtrace && $type & E_ERROR) { + // E_ERROR fatal errors are triggered on HHVM when + // hhvm.error_handling.call_user_handler_on_fatals=1 + // which is the way to get their backtrace. + $this->handleFatalError(compact('type', 'message', 'file', 'line', 'backtrace')); + + return true; + } + + if ($throw) { + if (null !== self::$toStringException) { + $throw = self::$toStringException; + self::$toStringException = null; + } elseif (($this->scopedErrors & $type) && class_exists('Symfony\Component\Debug\Exception\ContextErrorException')) { + // Checking for class existence is a work around for https://bugs.php.net/42098 + $throw = new ContextErrorException($this->levels[$type].': '.$message, 0, $type, $file, $line, $context); + } else { + $throw = new \ErrorException($this->levels[$type].': '.$message, 0, $type, $file, $line); + } + + if (PHP_VERSION_ID <= 50407 && (PHP_VERSION_ID >= 50400 || PHP_VERSION_ID <= 50317)) { + // Exceptions thrown from error handlers are sometimes not caught by the exception + // handler and shutdown handlers are bypassed before 5.4.8/5.3.18. + // We temporarily re-enable display_errors to prevent any blank page related to this bug. + + $throw->errorHandlerCanary = new ErrorHandlerCanary(); + } + + if (E_USER_ERROR & $type) { + $backtrace = $backtrace ?: $throw->getTrace(); + + for ($i = 1; isset($backtrace[$i]); ++$i) { + if (isset($backtrace[$i]['function'], $backtrace[$i]['type'], $backtrace[$i - 1]['function']) + && '__toString' === $backtrace[$i]['function'] + && '->' === $backtrace[$i]['type'] + && !isset($backtrace[$i - 1]['class']) + && ('trigger_error' === $backtrace[$i - 1]['function'] || 'user_error' === $backtrace[$i - 1]['function']) + ) { + // Here, we know trigger_error() has been called from __toString(). + // HHVM is fine with throwing from __toString() but PHP triggers a fatal error instead. + // A small convention allows working around the limitation: + // given a caught $e exception in __toString(), quitting the method with + // `return trigger_error($e, E_USER_ERROR);` allows this error handler + // to make $e get through the __toString() barrier. + + foreach ($context as $e) { + if (($e instanceof \Exception || $e instanceof \Throwable) && $e->__toString() === $message) { + if (1 === $i) { + // On HHVM + $throw = $e; + break; + } + self::$toStringException = $e; + + return true; + } + } + + if (1 < $i) { + // On PHP (not on HHVM), display the original error message instead of the default one. + $this->handleException($throw); + + // Stop the process by giving back the error to the native handler. + return false; + } + } + } + } + + throw $throw; + } + + // For duplicated errors, log the trace only once + $e = md5("{$type}/{$line}/{$file}\x00{$message}", true); + $trace = true; + + if (!($this->tracedErrors & $type) || isset($this->loggedTraces[$e])) { + $trace = false; + } else { + $this->loggedTraces[$e] = 1; + } + + $e = compact('type', 'file', 'line', 'level'); + + if ($type & $level) { + if ($this->scopedErrors & $type) { + $e['scope_vars'] = $context; + if ($trace) { + $e['stack'] = $backtrace ?: debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT); + } + } elseif ($trace) { + if (null === $backtrace) { + $e['stack'] = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); + } else { + foreach ($backtrace as &$frame) { + unset($frame['args'], $frame); + } + $e['stack'] = $backtrace; + } + } + } + + if ($this->isRecursive) { + $log = 0; + } elseif (self::$stackedErrorLevels) { + self::$stackedErrors[] = array($this->loggers[$type][0], ($type & $level) ? $this->loggers[$type][1] : LogLevel::DEBUG, $message, $e); + } else { + try { + $this->isRecursive = true; + $this->loggers[$type][0]->log(($type & $level) ? $this->loggers[$type][1] : LogLevel::DEBUG, $message, $e); + $this->isRecursive = false; + } catch (\Exception $e) { + $this->isRecursive = false; + + throw $e; + } catch (\Throwable $e) { + $this->isRecursive = false; + + throw $e; + } + } + + return $type && $log; + } + + /** + * Handles an exception by logging then forwarding it to another handler. + * + * @param \Exception|\Throwable $exception An exception to handle + * @param array $error An array as returned by error_get_last() + * + * @internal + */ + public function handleException($exception, array $error = null) + { + if (!$exception instanceof \Exception) { + $exception = new FatalThrowableError($exception); + } + $type = $exception instanceof FatalErrorException ? $exception->getSeverity() : E_ERROR; + + if (($this->loggedErrors & $type) || $exception instanceof FatalThrowableError) { + $e = array( + 'type' => $type, + 'file' => $exception->getFile(), + 'line' => $exception->getLine(), + 'level' => error_reporting(), + 'stack' => $exception->getTrace(), + ); + if ($exception instanceof FatalErrorException) { + if ($exception instanceof FatalThrowableError) { + $error = array( + 'type' => $type, + 'message' => $message = $exception->getMessage(), + 'file' => $e['file'], + 'line' => $e['line'], + ); + } else { + $message = 'Fatal '.$exception->getMessage(); + } + } elseif ($exception instanceof \ErrorException) { + $message = 'Uncaught '.$exception->getMessage(); + if ($exception instanceof ContextErrorException) { + $e['context'] = $exception->getContext(); + } + } else { + $message = 'Uncaught Exception: '.$exception->getMessage(); + } + } + if ($this->loggedErrors & $type) { + $this->loggers[$type][0]->log($this->loggers[$type][1], $message, $e); + } + if ($exception instanceof FatalErrorException && !$exception instanceof OutOfMemoryException && $error) { + foreach ($this->getFatalErrorHandlers() as $handler) { + if ($e = $handler->handleError($error, $exception)) { + $exception = $e; + break; + } + } + } + if (empty($this->exceptionHandler)) { + throw $exception; // Give back $exception to the native handler + } + try { + call_user_func($this->exceptionHandler, $exception); + } catch (\Exception $handlerException) { + } catch (\Throwable $handlerException) { + } + if (isset($handlerException)) { + $this->exceptionHandler = null; + $this->handleException($handlerException); + } + } + + /** + * Shutdown registered function for handling PHP fatal errors. + * + * @param array $error An array as returned by error_get_last() + * + * @internal + */ + public static function handleFatalError(array $error = null) + { + if (null === self::$reservedMemory) { + return; + } + + self::$reservedMemory = null; + + $handler = set_error_handler('var_dump'); + $handler = is_array($handler) ? $handler[0] : null; + restore_error_handler(); + + if (!$handler instanceof self) { + return; + } + + if (null === $error) { + $error = error_get_last(); + } + + try { + while (self::$stackedErrorLevels) { + static::unstackErrors(); + } + } catch (\Exception $exception) { + // Handled below + } catch (\Throwable $exception) { + // Handled below + } + + if ($error && $error['type'] &= E_PARSE | E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR) { + // Let's not throw anymore but keep logging + $handler->throwAt(0, true); + $trace = isset($error['backtrace']) ? $error['backtrace'] : null; + + if (0 === strpos($error['message'], 'Allowed memory') || 0 === strpos($error['message'], 'Out of memory')) { + $exception = new OutOfMemoryException($handler->levels[$error['type']].': '.$error['message'], 0, $error['type'], $error['file'], $error['line'], 2, false, $trace); + } else { + $exception = new FatalErrorException($handler->levels[$error['type']].': '.$error['message'], 0, $error['type'], $error['file'], $error['line'], 2, true, $trace); + } + } elseif (!isset($exception)) { + return; + } + + try { + $handler->handleException($exception, $error); + } catch (FatalErrorException $e) { + // Ignore this re-throw + } + } + + /** + * Configures the error handler for delayed handling. + * Ensures also that non-catchable fatal errors are never silenced. + * + * As shown by http://bugs.php.net/42098 and http://bugs.php.net/60724 + * PHP has a compile stage where it behaves unusually. To workaround it, + * we plug an error handler that only stacks errors for later. + * + * The most important feature of this is to prevent + * autoloading until unstackErrors() is called. + */ + public static function stackErrors() + { + self::$stackedErrorLevels[] = error_reporting(error_reporting() | E_PARSE | E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR); + } + + /** + * Unstacks stacked errors and forwards to the logger. + */ + public static function unstackErrors() + { + $level = array_pop(self::$stackedErrorLevels); + + if (null !== $level) { + $e = error_reporting($level); + if ($e !== ($level | E_PARSE | E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR)) { + // If the user changed the error level, do not overwrite it + error_reporting($e); + } + } + + if (empty(self::$stackedErrorLevels)) { + $errors = self::$stackedErrors; + self::$stackedErrors = array(); + + foreach ($errors as $e) { + $e[0]->log($e[1], $e[2], $e[3]); + } + } + } + + /** + * Gets the fatal error handlers. + * + * Override this method if you want to define more fatal error handlers. + * + * @return FatalErrorHandlerInterface[] An array of FatalErrorHandlerInterface + */ + protected function getFatalErrorHandlers() + { + return array( + new UndefinedFunctionFatalErrorHandler(), + new UndefinedMethodFatalErrorHandler(), + new ClassNotFoundFatalErrorHandler(), + ); + } + + /** + * Sets the level at which the conversion to Exception is done. + * + * @param int|null $level The level (null to use the error_reporting() value and 0 to disable) + * + * @deprecated since version 2.6, to be removed in 3.0. Use throwAt() instead. + */ + public function setLevel($level) + { + @trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the throwAt() method instead.', E_USER_DEPRECATED); + + $level = null === $level ? error_reporting() : $level; + $this->throwAt($level, true); + } + + /** + * Sets the display_errors flag value. + * + * @param int $displayErrors The display_errors flag value + * + * @deprecated since version 2.6, to be removed in 3.0. Use throwAt() instead. + */ + public function setDisplayErrors($displayErrors) + { + @trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the throwAt() method instead.', E_USER_DEPRECATED); + + if ($displayErrors) { + $this->throwAt($this->displayErrors, true); + } else { + $displayErrors = $this->displayErrors; + $this->throwAt(0, true); + $this->displayErrors = $displayErrors; + } + } + + /** + * Sets a logger for the given channel. + * + * @param LoggerInterface $logger A logger interface + * @param string $channel The channel associated with the logger (deprecation, emergency or scream) + * + * @deprecated since version 2.6, to be removed in 3.0. Use setLoggers() or setDefaultLogger() instead. + */ + public static function setLogger(LoggerInterface $logger, $channel = 'deprecation') + { + @trigger_error('The '.__METHOD__.' static method is deprecated since version 2.6 and will be removed in 3.0. Use the setLoggers() or setDefaultLogger() methods instead.', E_USER_DEPRECATED); + + $handler = set_error_handler('var_dump'); + $handler = is_array($handler) ? $handler[0] : null; + restore_error_handler(); + if (!$handler instanceof self) { + return; + } + if ('deprecation' === $channel) { + $handler->setDefaultLogger($logger, E_DEPRECATED | E_USER_DEPRECATED, true); + $handler->screamAt(E_DEPRECATED | E_USER_DEPRECATED); + } elseif ('scream' === $channel) { + $handler->setDefaultLogger($logger, E_ALL | E_STRICT, false); + $handler->screamAt(E_ALL | E_STRICT); + } elseif ('emergency' === $channel) { + $handler->setDefaultLogger($logger, E_PARSE | E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR, true); + $handler->screamAt(E_PARSE | E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR); + } + } + + /** + * @deprecated since version 2.6, to be removed in 3.0. Use handleError() instead. + */ + public function handle($level, $message, $file = 'unknown', $line = 0, $context = array()) + { + $this->handleError(E_USER_DEPRECATED, 'The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the handleError() method instead.', __FILE__, __LINE__, array()); + + return $this->handleError($level, $message, $file, $line, (array) $context); + } + + /** + * Handles PHP fatal errors. + * + * @deprecated since version 2.6, to be removed in 3.0. Use handleFatalError() instead. + */ + public function handleFatal() + { + @trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the handleFatalError() method instead.', E_USER_DEPRECATED); + + static::handleFatalError(); + } +} + +/** + * Private class used to work around https://bugs.php.net/54275. + * + * @author Nicolas Grekas + * + * @internal + */ +class ErrorHandlerCanary +{ + private static $displayErrors = null; + + public function __construct() + { + if (null === self::$displayErrors) { + self::$displayErrors = ini_set('display_errors', 1); + } + } + + public function __destruct() + { + if (null !== self::$displayErrors) { + ini_set('display_errors', self::$displayErrors); + self::$displayErrors = null; + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/debug/Exception/ClassNotFoundException.php b/lib/ckfinder/core/connector/php/vendor/symfony/debug/Exception/ClassNotFoundException.php new file mode 100644 index 0000000..b91bf46 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/debug/Exception/ClassNotFoundException.php @@ -0,0 +1,33 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Debug\Exception; + +/** + * Class (or Trait or Interface) Not Found Exception. + * + * @author Konstanton Myakshin + */ +class ClassNotFoundException extends FatalErrorException +{ + public function __construct($message, \ErrorException $previous) + { + parent::__construct( + $message, + $previous->getCode(), + $previous->getSeverity(), + $previous->getFile(), + $previous->getLine(), + $previous->getPrevious() + ); + $this->setTrace($previous->getTrace()); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/debug/Exception/ContextErrorException.php b/lib/ckfinder/core/connector/php/vendor/symfony/debug/Exception/ContextErrorException.php new file mode 100644 index 0000000..54f0198 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/debug/Exception/ContextErrorException.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Debug\Exception; + +/** + * Error Exception with Variable Context. + * + * @author Christian Sciberras + */ +class ContextErrorException extends \ErrorException +{ + private $context = array(); + + public function __construct($message, $code, $severity, $filename, $lineno, $context = array()) + { + parent::__construct($message, $code, $severity, $filename, $lineno); + $this->context = $context; + } + + /** + * @return array Array of variables that existed when the exception occurred + */ + public function getContext() + { + return $this->context; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/debug/Exception/DummyException.php b/lib/ckfinder/core/connector/php/vendor/symfony/debug/Exception/DummyException.php new file mode 100644 index 0000000..c836f87 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/debug/Exception/DummyException.php @@ -0,0 +1,23 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Debug\Exception; + +@trigger_error('The '.__NAMESPACE__.'\DummyException class is deprecated since version 2.5 and will be removed in 3.0.', E_USER_DEPRECATED); + +/** + * @author Fabien Potencier + * + * @deprecated since version 2.5, to be removed in 3.0. + */ +class DummyException extends \ErrorException +{ +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/debug/Exception/FatalErrorException.php b/lib/ckfinder/core/connector/php/vendor/symfony/debug/Exception/FatalErrorException.php new file mode 100644 index 0000000..db2fb43 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/debug/Exception/FatalErrorException.php @@ -0,0 +1,99 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Exception; + +/** + * Fatal Error Exception. + * + * @author Fabien Potencier + * @author Konstanton Myakshin + * @author Nicolas Grekas + * + * @deprecated Deprecated in 2.3, to be removed in 3.0. Use the same class from the Debug component instead. + */ +class FatalErrorException extends \ErrorException +{ +} + +namespace Symfony\Component\Debug\Exception; + +use Symfony\Component\HttpKernel\Exception\FatalErrorException as LegacyFatalErrorException; + +/** + * Fatal Error Exception. + * + * @author Konstanton Myakshin + */ +class FatalErrorException extends LegacyFatalErrorException +{ + public function __construct($message, $code, $severity, $filename, $lineno, $traceOffset = null, $traceArgs = true, array $trace = null) + { + parent::__construct($message, $code, $severity, $filename, $lineno); + + if (null !== $trace) { + if (!$traceArgs) { + foreach ($trace as &$frame) { + unset($frame['args'], $frame['this'], $frame); + } + } + + $this->setTrace($trace); + } elseif (null !== $traceOffset) { + if (function_exists('xdebug_get_function_stack')) { + $trace = xdebug_get_function_stack(); + if (0 < $traceOffset) { + array_splice($trace, -$traceOffset); + } + + foreach ($trace as &$frame) { + if (!isset($frame['type'])) { + // XDebug pre 2.1.1 doesn't currently set the call type key http://bugs.xdebug.org/view.php?id=695 + if (isset($frame['class'])) { + $frame['type'] = '::'; + } + } elseif ('dynamic' === $frame['type']) { + $frame['type'] = '->'; + } elseif ('static' === $frame['type']) { + $frame['type'] = '::'; + } + + // XDebug also has a different name for the parameters array + if (!$traceArgs) { + unset($frame['params'], $frame['args']); + } elseif (isset($frame['params']) && !isset($frame['args'])) { + $frame['args'] = $frame['params']; + unset($frame['params']); + } + } + + unset($frame); + $trace = array_reverse($trace); + } elseif (function_exists('symfony_debug_backtrace')) { + $trace = symfony_debug_backtrace(); + if (0 < $traceOffset) { + array_splice($trace, 0, $traceOffset); + } + } else { + $trace = array(); + } + + $this->setTrace($trace); + } + } + + protected function setTrace($trace) + { + $traceReflector = new \ReflectionProperty('Exception', 'trace'); + $traceReflector->setAccessible(true); + $traceReflector->setValue($this, $trace); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/debug/Exception/FatalThrowableError.php b/lib/ckfinder/core/connector/php/vendor/symfony/debug/Exception/FatalThrowableError.php new file mode 100644 index 0000000..34f43b1 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/debug/Exception/FatalThrowableError.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Debug\Exception; + +/** + * Fatal Throwable Error. + * + * @author Nicolas Grekas + */ +class FatalThrowableError extends FatalErrorException +{ + public function __construct(\Throwable $e) + { + if ($e instanceof \ParseError) { + $message = 'Parse error: '.$e->getMessage(); + $severity = E_PARSE; + } elseif ($e instanceof \TypeError) { + $message = 'Type error: '.$e->getMessage(); + $severity = E_RECOVERABLE_ERROR; + } else { + $message = $e->getMessage(); + $severity = E_ERROR; + } + + \ErrorException::__construct( + $message, + $e->getCode(), + $severity, + $e->getFile(), + $e->getLine() + ); + + $this->setTrace($e->getTrace()); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/debug/Exception/FlattenException.php b/lib/ckfinder/core/connector/php/vendor/symfony/debug/Exception/FlattenException.php new file mode 100644 index 0000000..b3a98ac --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/debug/Exception/FlattenException.php @@ -0,0 +1,297 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Exception; + +use Symfony\Component\Debug\Exception\FlattenException as DebugFlattenException; + +/** + * FlattenException wraps a PHP Exception to be able to serialize it. + * + * Basically, this class removes all objects from the trace. + * + * @author Fabien Potencier + * + * @deprecated Deprecated in 2.3, to be removed in 3.0. Use the same class from the Debug component instead. + */ +class FlattenException +{ + private $handler; + + public static function __callStatic($method, $args) + { + if (!method_exists('Symfony\Component\Debug\Exception\FlattenException', $method)) { + throw new \BadMethodCallException(sprintf('Call to undefined method %s::%s()', get_called_class(), $method)); + } + + return call_user_func_array(array('Symfony\Component\Debug\Exception\FlattenException', $method), $args); + } + + public function __call($method, $args) + { + if (!isset($this->handler)) { + $this->handler = new DebugFlattenException(); + } + + if (!method_exists($this->handler, $method)) { + throw new \BadMethodCallException(sprintf('Call to undefined method %s::%s()', get_class($this), $method)); + } + + return call_user_func_array(array($this->handler, $method), $args); + } +} + +namespace Symfony\Component\Debug\Exception; + +use Symfony\Component\HttpKernel\Exception\FlattenException as LegacyFlattenException; +use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; + +/** + * FlattenException wraps a PHP Exception to be able to serialize it. + * + * Basically, this class removes all objects from the trace. + * + * @author Fabien Potencier + */ +class FlattenException extends LegacyFlattenException +{ + private $message; + private $code; + private $previous; + private $trace; + private $class; + private $statusCode; + private $headers; + private $file; + private $line; + + public static function create(\Exception $exception, $statusCode = null, array $headers = array()) + { + $e = new static(); + $e->setMessage($exception->getMessage()); + $e->setCode($exception->getCode()); + + if ($exception instanceof HttpExceptionInterface) { + $statusCode = $exception->getStatusCode(); + $headers = array_merge($headers, $exception->getHeaders()); + } + + if (null === $statusCode) { + $statusCode = 500; + } + + $e->setStatusCode($statusCode); + $e->setHeaders($headers); + $e->setTraceFromException($exception); + $e->setClass(get_class($exception)); + $e->setFile($exception->getFile()); + $e->setLine($exception->getLine()); + + $previous = $exception->getPrevious(); + + if ($previous instanceof \Exception) { + $e->setPrevious(static::create($previous)); + } elseif ($previous instanceof \Throwable) { + $e->setPrevious(static::create(new FatalThrowableError($previous))); + } + + return $e; + } + + public function toArray() + { + $exceptions = array(); + foreach (array_merge(array($this), $this->getAllPrevious()) as $exception) { + $exceptions[] = array( + 'message' => $exception->getMessage(), + 'class' => $exception->getClass(), + 'trace' => $exception->getTrace(), + ); + } + + return $exceptions; + } + + public function getStatusCode() + { + return $this->statusCode; + } + + public function setStatusCode($code) + { + $this->statusCode = $code; + } + + public function getHeaders() + { + return $this->headers; + } + + public function setHeaders(array $headers) + { + $this->headers = $headers; + } + + public function getClass() + { + return $this->class; + } + + public function setClass($class) + { + $this->class = $class; + } + + public function getFile() + { + return $this->file; + } + + public function setFile($file) + { + $this->file = $file; + } + + public function getLine() + { + return $this->line; + } + + public function setLine($line) + { + $this->line = $line; + } + + public function getMessage() + { + return $this->message; + } + + public function setMessage($message) + { + $this->message = $message; + } + + public function getCode() + { + return $this->code; + } + + public function setCode($code) + { + $this->code = $code; + } + + public function getPrevious() + { + return $this->previous; + } + + public function setPrevious(FlattenException $previous) + { + $this->previous = $previous; + } + + public function getAllPrevious() + { + $exceptions = array(); + $e = $this; + while ($e = $e->getPrevious()) { + $exceptions[] = $e; + } + + return $exceptions; + } + + public function getTrace() + { + return $this->trace; + } + + public function setTraceFromException(\Exception $exception) + { + $this->setTrace($exception->getTrace(), $exception->getFile(), $exception->getLine()); + } + + public function setTrace($trace, $file, $line) + { + $this->trace = array(); + $this->trace[] = array( + 'namespace' => '', + 'short_class' => '', + 'class' => '', + 'type' => '', + 'function' => '', + 'file' => $file, + 'line' => $line, + 'args' => array(), + ); + foreach ($trace as $entry) { + $class = ''; + $namespace = ''; + if (isset($entry['class'])) { + $parts = explode('\\', $entry['class']); + $class = array_pop($parts); + $namespace = implode('\\', $parts); + } + + $this->trace[] = array( + 'namespace' => $namespace, + 'short_class' => $class, + 'class' => isset($entry['class']) ? $entry['class'] : '', + 'type' => isset($entry['type']) ? $entry['type'] : '', + 'function' => isset($entry['function']) ? $entry['function'] : null, + 'file' => isset($entry['file']) ? $entry['file'] : null, + 'line' => isset($entry['line']) ? $entry['line'] : null, + 'args' => isset($entry['args']) ? $this->flattenArgs($entry['args']) : array(), + ); + } + } + + private function flattenArgs($args, $level = 0, &$count = 0) + { + $result = array(); + foreach ($args as $key => $value) { + if (++$count > 1e4) { + return array('array', '*SKIPPED over 10000 entries*'); + } + if ($value instanceof \__PHP_Incomplete_Class) { + // is_object() returns false on PHP<=7.1 + $result[$key] = array('incomplete-object', $this->getClassNameFromIncomplete($value)); + } elseif (is_object($value)) { + $result[$key] = array('object', get_class($value)); + } elseif (is_array($value)) { + if ($level > 10) { + $result[$key] = array('array', '*DEEP NESTED ARRAY*'); + } else { + $result[$key] = array('array', $this->flattenArgs($value, $level + 1, $count)); + } + } elseif (null === $value) { + $result[$key] = array('null', null); + } elseif (is_bool($value)) { + $result[$key] = array('boolean', $value); + } elseif (is_resource($value)) { + $result[$key] = array('resource', get_resource_type($value)); + } else { + $result[$key] = array('string', (string) $value); + } + } + + return $result; + } + + private function getClassNameFromIncomplete(\__PHP_Incomplete_Class $value) + { + $array = new \ArrayObject($value); + + return $array['__PHP_Incomplete_Class_Name']; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/debug/Exception/OutOfMemoryException.php b/lib/ckfinder/core/connector/php/vendor/symfony/debug/Exception/OutOfMemoryException.php new file mode 100644 index 0000000..fec1979 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/debug/Exception/OutOfMemoryException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Debug\Exception; + +/** + * Out of memory exception. + * + * @author Nicolas Grekas + */ +class OutOfMemoryException extends FatalErrorException +{ +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/debug/Exception/UndefinedFunctionException.php b/lib/ckfinder/core/connector/php/vendor/symfony/debug/Exception/UndefinedFunctionException.php new file mode 100644 index 0000000..a66ae2a --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/debug/Exception/UndefinedFunctionException.php @@ -0,0 +1,33 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Debug\Exception; + +/** + * Undefined Function Exception. + * + * @author Konstanton Myakshin + */ +class UndefinedFunctionException extends FatalErrorException +{ + public function __construct($message, \ErrorException $previous) + { + parent::__construct( + $message, + $previous->getCode(), + $previous->getSeverity(), + $previous->getFile(), + $previous->getLine(), + $previous->getPrevious() + ); + $this->setTrace($previous->getTrace()); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/debug/Exception/UndefinedMethodException.php b/lib/ckfinder/core/connector/php/vendor/symfony/debug/Exception/UndefinedMethodException.php new file mode 100644 index 0000000..350dc31 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/debug/Exception/UndefinedMethodException.php @@ -0,0 +1,33 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Debug\Exception; + +/** + * Undefined Method Exception. + * + * @author Grégoire Pineau + */ +class UndefinedMethodException extends FatalErrorException +{ + public function __construct($message, \ErrorException $previous) + { + parent::__construct( + $message, + $previous->getCode(), + $previous->getSeverity(), + $previous->getFile(), + $previous->getLine(), + $previous->getPrevious() + ); + $this->setTrace($previous->getTrace()); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/debug/ExceptionHandler.php b/lib/ckfinder/core/connector/php/vendor/symfony/debug/ExceptionHandler.php new file mode 100644 index 0000000..2e6c204 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/debug/ExceptionHandler.php @@ -0,0 +1,496 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Debug; + +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\Debug\Exception\FlattenException; +use Symfony\Component\Debug\Exception\OutOfMemoryException; + +/** + * ExceptionHandler converts an exception to a Response object. + * + * It is mostly useful in debug mode to replace the default PHP/XDebug + * output with something prettier and more useful. + * + * As this class is mainly used during Kernel boot, where nothing is yet + * available, the Response content is always HTML. + * + * @author Fabien Potencier + * @author Nicolas Grekas + */ +class ExceptionHandler +{ + private $debug; + private $charset; + private $handler; + private $caughtBuffer; + private $caughtLength; + private $fileLinkFormat; + + public function __construct($debug = true, $charset = null, $fileLinkFormat = null) + { + if (false !== strpos($charset, '%')) { + @trigger_error('Providing $fileLinkFormat as second argument to '.__METHOD__.' is deprecated since version 2.8 and will be unsupported in 3.0. Please provide it as third argument, after $charset.', E_USER_DEPRECATED); + + // Swap $charset and $fileLinkFormat for BC reasons + $pivot = $fileLinkFormat; + $fileLinkFormat = $charset; + $charset = $pivot; + } + $this->debug = $debug; + $this->charset = $charset ?: ini_get('default_charset') ?: 'UTF-8'; + $this->fileLinkFormat = $fileLinkFormat ?: ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format'); + } + + /** + * Registers the exception handler. + * + * @param bool $debug Enable/disable debug mode, where the stack trace is displayed + * @param string|null $charset The charset used by exception messages + * @param string|null $fileLinkFormat The IDE link template + * + * @return ExceptionHandler The registered exception handler + */ + public static function register($debug = true, $charset = null, $fileLinkFormat = null) + { + $handler = new static($debug, $charset, $fileLinkFormat); + + $prev = set_exception_handler(array($handler, 'handle')); + if (is_array($prev) && $prev[0] instanceof ErrorHandler) { + restore_exception_handler(); + $prev[0]->setExceptionHandler(array($handler, 'handle')); + } + + return $handler; + } + + /** + * Sets a user exception handler. + * + * @param callable $handler An handler that will be called on Exception + * + * @return callable|null The previous exception handler if any + */ + public function setHandler($handler) + { + if (null !== $handler && !is_callable($handler)) { + throw new \LogicException('The exception handler must be a valid PHP callable.'); + } + $old = $this->handler; + $this->handler = $handler; + + return $old; + } + + /** + * Sets the format for links to source files. + * + * @param string $format The format for links to source files + * + * @return string The previous file link format + */ + public function setFileLinkFormat($format) + { + $old = $this->fileLinkFormat; + $this->fileLinkFormat = $format; + + return $old; + } + + /** + * Sends a response for the given Exception. + * + * To be as fail-safe as possible, the exception is first handled + * by our simple exception handler, then by the user exception handler. + * The latter takes precedence and any output from the former is cancelled, + * if and only if nothing bad happens in this handling path. + */ + public function handle(\Exception $exception) + { + if (null === $this->handler || $exception instanceof OutOfMemoryException) { + $this->failSafeHandle($exception); + + return; + } + + $caughtLength = $this->caughtLength = 0; + + ob_start(array($this, 'catchOutput')); + $this->failSafeHandle($exception); + while (null === $this->caughtBuffer && ob_end_flush()) { + // Empty loop, everything is in the condition + } + if (isset($this->caughtBuffer[0])) { + ob_start(array($this, 'cleanOutput')); + echo $this->caughtBuffer; + $caughtLength = ob_get_length(); + } + $this->caughtBuffer = null; + + try { + call_user_func($this->handler, $exception); + $this->caughtLength = $caughtLength; + } catch (\Exception $e) { + if (!$caughtLength) { + // All handlers failed. Let PHP handle that now. + throw $exception; + } + } + } + + /** + * Sends a response for the given Exception. + * + * If you have the Symfony HttpFoundation component installed, + * this method will use it to create and send the response. If not, + * it will fallback to plain PHP functions. + * + * @param \Exception $exception An \Exception instance + */ + private function failSafeHandle(\Exception $exception) + { + if (class_exists('Symfony\Component\HttpFoundation\Response', false) + && __CLASS__ !== get_class($this) + && ($reflector = new \ReflectionMethod($this, 'createResponse')) + && __CLASS__ !== $reflector->class + ) { + $response = $this->createResponse($exception); + $response->sendHeaders(); + $response->sendContent(); + @trigger_error(sprintf("The %s::createResponse method is deprecated since 2.8 and won't be called anymore when handling an exception in 3.0.", $reflector->class), E_USER_DEPRECATED); + + return; + } + + $this->sendPhpResponse($exception); + } + + /** + * Sends the error associated with the given Exception as a plain PHP response. + * + * This method uses plain PHP functions like header() and echo to output + * the response. + * + * @param \Exception|FlattenException $exception An \Exception or FlattenException instance + */ + public function sendPhpResponse($exception) + { + if (!$exception instanceof FlattenException) { + $exception = FlattenException::create($exception); + } + + if (!headers_sent()) { + header(sprintf('HTTP/1.0 %s', $exception->getStatusCode())); + foreach ($exception->getHeaders() as $name => $value) { + header($name.': '.$value, false); + } + header('Content-Type: text/html; charset='.$this->charset); + } + + echo $this->decorate($this->getContent($exception), $this->getStylesheet($exception)); + } + + /** + * Creates the error Response associated with the given Exception. + * + * @param \Exception|FlattenException $exception An \Exception or FlattenException instance + * + * @return Response A Response instance + * + * @deprecated since 2.8, to be removed in 3.0. + */ + public function createResponse($exception) + { + @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED); + + if (!$exception instanceof FlattenException) { + $exception = FlattenException::create($exception); + } + + return Response::create($this->getHtml($exception), $exception->getStatusCode(), $exception->getHeaders())->setCharset($this->charset); + } + + /** + * Gets the full HTML content associated with the given exception. + * + * @param \Exception|FlattenException $exception An \Exception or FlattenException instance + * + * @return string The HTML content as a string + */ + public function getHtml($exception) + { + if (!$exception instanceof FlattenException) { + $exception = FlattenException::create($exception); + } + + return $this->decorate($this->getContent($exception), $this->getStylesheet($exception)); + } + + /** + * Gets the HTML content associated with the given exception. + * + * @param FlattenException $exception A FlattenException instance + * + * @return string The content as a string + */ + public function getContent(FlattenException $exception) + { + switch ($exception->getStatusCode()) { + case 404: + $title = 'Sorry, the page you are looking for could not be found.'; + break; + default: + $title = 'Whoops, looks like something went wrong.'; + } + + $content = ''; + if ($this->debug) { + try { + $count = count($exception->getAllPrevious()); + $total = $count + 1; + foreach ($exception->toArray() as $position => $e) { + $ind = $count - $position + 1; + $class = $this->formatClass($e['class']); + $message = nl2br($this->escapeHtml($e['message'])); + $content .= sprintf(<<<'EOF' +

    + %d/%d + %s%s: + %s +

    +
    +
      + +EOF + , $ind, $total, $class, $this->formatPath($e['trace'][0]['file'], $e['trace'][0]['line']), $message); + foreach ($e['trace'] as $trace) { + $content .= '
    1. '; + if ($trace['function']) { + $content .= sprintf('at %s%s%s(%s)', $this->formatClass($trace['class']), $trace['type'], $trace['function'], $this->formatArgs($trace['args'])); + } + if (isset($trace['file']) && isset($trace['line'])) { + $content .= $this->formatPath($trace['file'], $trace['line']); + } + $content .= "
    2. \n"; + } + + $content .= "
    \n
    \n"; + } + } catch (\Exception $e) { + // something nasty happened and we cannot throw an exception anymore + if ($this->debug) { + $title = sprintf('Exception thrown when handling an exception (%s: %s)', get_class($e), $this->escapeHtml($e->getMessage())); + } else { + $title = 'Whoops, looks like something went wrong.'; + } + } + } + + return << +

    $title

    + $content + +EOF; + } + + /** + * Gets the stylesheet associated with the given exception. + * + * @param FlattenException $exception A FlattenException instance + * + * @return string The stylesheet as a string + */ + public function getStylesheet(FlattenException $exception) + { + return <<<'EOF' + .sf-reset { font: 11px Verdana, Arial, sans-serif; color: #333 } + .sf-reset .clear { clear:both; height:0; font-size:0; line-height:0; } + .sf-reset .clear_fix:after { display:block; height:0; clear:both; visibility:hidden; } + .sf-reset .clear_fix { display:inline-block; } + .sf-reset * html .clear_fix { height:1%; } + .sf-reset .clear_fix { display:block; } + .sf-reset, .sf-reset .block { margin: auto } + .sf-reset abbr { border-bottom: 1px dotted #000; cursor: help; } + .sf-reset p { font-size:14px; line-height:20px; color:#868686; padding-bottom:20px } + .sf-reset strong { font-weight:bold; } + .sf-reset a { color:#6c6159; cursor: default; } + .sf-reset a img { border:none; } + .sf-reset a:hover { text-decoration:underline; } + .sf-reset em { font-style:italic; } + .sf-reset h1, .sf-reset h2 { font: 20px Georgia, "Times New Roman", Times, serif } + .sf-reset .exception_counter { background-color: #fff; color: #333; padding: 6px; float: left; margin-right: 10px; float: left; display: block; } + .sf-reset .exception_title { margin-left: 3em; margin-bottom: 0.7em; display: block; } + .sf-reset .exception_message { margin-left: 3em; display: block; } + .sf-reset .traces li { font-size:12px; padding: 2px 4px; list-style-type:decimal; margin-left:20px; } + .sf-reset .block { background-color:#FFFFFF; padding:10px 28px; margin-bottom:20px; + -webkit-border-bottom-right-radius: 16px; + -webkit-border-bottom-left-radius: 16px; + -moz-border-radius-bottomright: 16px; + -moz-border-radius-bottomleft: 16px; + border-bottom-right-radius: 16px; + border-bottom-left-radius: 16px; + border-bottom:1px solid #ccc; + border-right:1px solid #ccc; + border-left:1px solid #ccc; + word-wrap: break-word; + } + .sf-reset .block_exception { background-color:#ddd; color: #333; padding:20px; + -webkit-border-top-left-radius: 16px; + -webkit-border-top-right-radius: 16px; + -moz-border-radius-topleft: 16px; + -moz-border-radius-topright: 16px; + border-top-left-radius: 16px; + border-top-right-radius: 16px; + border-top:1px solid #ccc; + border-right:1px solid #ccc; + border-left:1px solid #ccc; + overflow: hidden; + word-wrap: break-word; + } + .sf-reset a { background:none; color:#868686; text-decoration:none; } + .sf-reset a:hover { background:none; color:#313131; text-decoration:underline; } + .sf-reset ol { padding: 10px 0; } + .sf-reset h1 { background-color:#FFFFFF; padding: 15px 28px; margin-bottom: 20px; + -webkit-border-radius: 10px; + -moz-border-radius: 10px; + border-radius: 10px; + border: 1px solid #ccc; + } +EOF; + } + + private function decorate($content, $css) + { + return << + + + + + + + + $content + + +EOF; + } + + private function formatClass($class) + { + $parts = explode('\\', $class); + + return sprintf('%s', $class, array_pop($parts)); + } + + private function formatPath($path, $line) + { + $path = $this->escapeHtml($path); + $file = preg_match('#[^/\\\\]*$#', $path, $file) ? $file[0] : $path; + + if ($linkFormat = $this->fileLinkFormat) { + $link = strtr($this->escapeHtml($linkFormat), array('%f' => $path, '%l' => (int) $line)); + + return sprintf(' in %s line %d', $link, $file, $line); + } + + return sprintf(' in %s line %d', $path, $file, $line); + } + + /** + * Formats an array as a string. + * + * @param array $args The argument array + * + * @return string + */ + private function formatArgs(array $args) + { + $result = array(); + foreach ($args as $key => $item) { + if ('object' === $item[0]) { + $formattedValue = sprintf('object(%s)', $this->formatClass($item[1])); + } elseif ('array' === $item[0]) { + $formattedValue = sprintf('array(%s)', is_array($item[1]) ? $this->formatArgs($item[1]) : $item[1]); + } elseif ('string' === $item[0]) { + $formattedValue = sprintf("'%s'", $this->escapeHtml($item[1])); + } elseif ('null' === $item[0]) { + $formattedValue = 'null'; + } elseif ('boolean' === $item[0]) { + $formattedValue = ''.strtolower(var_export($item[1], true)).''; + } elseif ('resource' === $item[0]) { + $formattedValue = 'resource'; + } else { + $formattedValue = str_replace("\n", '', var_export($this->escapeHtml((string) $item[1]), true)); + } + + $result[] = is_int($key) ? $formattedValue : sprintf("'%s' => %s", $key, $formattedValue); + } + + return implode(', ', $result); + } + + /** + * Returns an UTF-8 and HTML encoded string. + * + * @deprecated since version 2.7, to be removed in 3.0. + */ + protected static function utf8Htmlize($str) + { + @trigger_error('The '.__METHOD__.' method is deprecated since version 2.7 and will be removed in 3.0.', E_USER_DEPRECATED); + + return htmlspecialchars($str, ENT_QUOTES | (PHP_VERSION_ID >= 50400 ? ENT_SUBSTITUTE : 0), 'UTF-8'); + } + + /** + * HTML-encodes a string. + */ + private function escapeHtml($str) + { + return htmlspecialchars($str, ENT_QUOTES | (PHP_VERSION_ID >= 50400 ? ENT_SUBSTITUTE : 0), $this->charset); + } + + /** + * @internal + */ + public function catchOutput($buffer) + { + $this->caughtBuffer = $buffer; + + return ''; + } + + /** + * @internal + */ + public function cleanOutput($buffer) + { + if ($this->caughtLength) { + // use substr_replace() instead of substr() for mbstring overloading resistance + $cleanBuffer = substr_replace($buffer, '', 0, $this->caughtLength); + if (isset($cleanBuffer[0])) { + $buffer = $cleanBuffer; + } + } + + return $buffer; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/debug/FatalErrorHandler/ClassNotFoundFatalErrorHandler.php b/lib/ckfinder/core/connector/php/vendor/symfony/debug/FatalErrorHandler/ClassNotFoundFatalErrorHandler.php new file mode 100644 index 0000000..abfe90d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/debug/FatalErrorHandler/ClassNotFoundFatalErrorHandler.php @@ -0,0 +1,212 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Debug\FatalErrorHandler; + +use Symfony\Component\Debug\Exception\ClassNotFoundException; +use Symfony\Component\Debug\Exception\FatalErrorException; +use Symfony\Component\Debug\DebugClassLoader; +use Composer\Autoload\ClassLoader as ComposerClassLoader; +use Symfony\Component\ClassLoader\ClassLoader as SymfonyClassLoader; +use Symfony\Component\ClassLoader\UniversalClassLoader as SymfonyUniversalClassLoader; + +/** + * ErrorHandler for classes that do not exist. + * + * @author Fabien Potencier + */ +class ClassNotFoundFatalErrorHandler implements FatalErrorHandlerInterface +{ + /** + * {@inheritdoc} + */ + public function handleError(array $error, FatalErrorException $exception) + { + $messageLen = strlen($error['message']); + $notFoundSuffix = '\' not found'; + $notFoundSuffixLen = strlen($notFoundSuffix); + if ($notFoundSuffixLen > $messageLen) { + return; + } + + if (0 !== substr_compare($error['message'], $notFoundSuffix, -$notFoundSuffixLen)) { + return; + } + + foreach (array('class', 'interface', 'trait') as $typeName) { + $prefix = ucfirst($typeName).' \''; + $prefixLen = strlen($prefix); + if (0 !== strpos($error['message'], $prefix)) { + continue; + } + + $fullyQualifiedClassName = substr($error['message'], $prefixLen, -$notFoundSuffixLen); + if (false !== $namespaceSeparatorIndex = strrpos($fullyQualifiedClassName, '\\')) { + $className = substr($fullyQualifiedClassName, $namespaceSeparatorIndex + 1); + $namespacePrefix = substr($fullyQualifiedClassName, 0, $namespaceSeparatorIndex); + $message = sprintf('Attempted to load %s "%s" from namespace "%s".', $typeName, $className, $namespacePrefix); + $tail = ' for another namespace?'; + } else { + $className = $fullyQualifiedClassName; + $message = sprintf('Attempted to load %s "%s" from the global namespace.', $typeName, $className); + $tail = '?'; + } + + if ($candidates = $this->getClassCandidates($className)) { + $tail = array_pop($candidates).'"?'; + if ($candidates) { + $tail = ' for e.g. "'.implode('", "', $candidates).'" or "'.$tail; + } else { + $tail = ' for "'.$tail; + } + } + $message .= "\nDid you forget a \"use\" statement".$tail; + + return new ClassNotFoundException($message, $exception); + } + } + + /** + * Tries to guess the full namespace for a given class name. + * + * By default, it looks for PSR-0 and PSR-4 classes registered via a Symfony or a Composer + * autoloader (that should cover all common cases). + * + * @param string $class A class name (without its namespace) + * + * @return array An array of possible fully qualified class names + */ + private function getClassCandidates($class) + { + if (!is_array($functions = spl_autoload_functions())) { + return array(); + } + + // find Symfony and Composer autoloaders + $classes = array(); + + foreach ($functions as $function) { + if (!is_array($function)) { + continue; + } + // get class loaders wrapped by DebugClassLoader + if ($function[0] instanceof DebugClassLoader) { + $function = $function[0]->getClassLoader(); + + // @deprecated since version 2.5. Returning an object from DebugClassLoader::getClassLoader() is deprecated. + if (is_object($function)) { + $function = array($function); + } + + if (!is_array($function)) { + continue; + } + } + + if ($function[0] instanceof ComposerClassLoader || $function[0] instanceof SymfonyClassLoader || $function[0] instanceof SymfonyUniversalClassLoader) { + foreach ($function[0]->getPrefixes() as $prefix => $paths) { + foreach ($paths as $path) { + $classes = array_merge($classes, $this->findClassInPath($path, $class, $prefix)); + } + } + } + if ($function[0] instanceof ComposerClassLoader) { + foreach ($function[0]->getPrefixesPsr4() as $prefix => $paths) { + foreach ($paths as $path) { + $classes = array_merge($classes, $this->findClassInPath($path, $class, $prefix)); + } + } + } + } + + return array_unique($classes); + } + + /** + * @param string $path + * @param string $class + * @param string $prefix + * + * @return array + */ + private function findClassInPath($path, $class, $prefix) + { + if (!$path = realpath($path.'/'.strtr($prefix, '\\_', '//')) ?: realpath($path.'/'.dirname(strtr($prefix, '\\_', '//'))) ?: realpath($path)) { + return array(); + } + + $classes = array(); + $filename = $class.'.php'; + foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS), \RecursiveIteratorIterator::LEAVES_ONLY) as $file) { + if ($filename == $file->getFileName() && $class = $this->convertFileToClass($path, $file->getPathName(), $prefix)) { + $classes[] = $class; + } + } + + return $classes; + } + + /** + * @param string $path + * @param string $file + * @param string $prefix + * + * @return string|null + */ + private function convertFileToClass($path, $file, $prefix) + { + $candidates = array( + // namespaced class + $namespacedClass = str_replace(array($path.DIRECTORY_SEPARATOR, '.php', '/'), array('', '', '\\'), $file), + // namespaced class (with target dir) + $prefix.$namespacedClass, + // namespaced class (with target dir and separator) + $prefix.'\\'.$namespacedClass, + // PEAR class + str_replace('\\', '_', $namespacedClass), + // PEAR class (with target dir) + str_replace('\\', '_', $prefix.$namespacedClass), + // PEAR class (with target dir and separator) + str_replace('\\', '_', $prefix.'\\'.$namespacedClass), + ); + + if ($prefix) { + $candidates = array_filter($candidates, function ($candidate) use ($prefix) {return 0 === strpos($candidate, $prefix);}); + } + + // We cannot use the autoloader here as most of them use require; but if the class + // is not found, the new autoloader call will require the file again leading to a + // "cannot redeclare class" error. + foreach ($candidates as $candidate) { + if ($this->classExists($candidate)) { + return $candidate; + } + } + + require_once $file; + + foreach ($candidates as $candidate) { + if ($this->classExists($candidate)) { + return $candidate; + } + } + } + + /** + * @param string $class + * + * @return bool + */ + private function classExists($class) + { + return class_exists($class, false) || interface_exists($class, false) || (function_exists('trait_exists') && trait_exists($class, false)); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/debug/FatalErrorHandler/FatalErrorHandlerInterface.php b/lib/ckfinder/core/connector/php/vendor/symfony/debug/FatalErrorHandler/FatalErrorHandlerInterface.php new file mode 100644 index 0000000..6b87eb3 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/debug/FatalErrorHandler/FatalErrorHandlerInterface.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Debug\FatalErrorHandler; + +use Symfony\Component\Debug\Exception\FatalErrorException; + +/** + * Attempts to convert fatal errors to exceptions. + * + * @author Fabien Potencier + */ +interface FatalErrorHandlerInterface +{ + /** + * Attempts to convert an error into an exception. + * + * @param array $error An array as returned by error_get_last() + * @param FatalErrorException $exception A FatalErrorException instance + * + * @return FatalErrorException|null A FatalErrorException instance if the class is able to convert the error, null otherwise + */ + public function handleError(array $error, FatalErrorException $exception); +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/debug/FatalErrorHandler/UndefinedFunctionFatalErrorHandler.php b/lib/ckfinder/core/connector/php/vendor/symfony/debug/FatalErrorHandler/UndefinedFunctionFatalErrorHandler.php new file mode 100644 index 0000000..c6f391a --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/debug/FatalErrorHandler/UndefinedFunctionFatalErrorHandler.php @@ -0,0 +1,84 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Debug\FatalErrorHandler; + +use Symfony\Component\Debug\Exception\UndefinedFunctionException; +use Symfony\Component\Debug\Exception\FatalErrorException; + +/** + * ErrorHandler for undefined functions. + * + * @author Fabien Potencier + */ +class UndefinedFunctionFatalErrorHandler implements FatalErrorHandlerInterface +{ + /** + * {@inheritdoc} + */ + public function handleError(array $error, FatalErrorException $exception) + { + $messageLen = strlen($error['message']); + $notFoundSuffix = '()'; + $notFoundSuffixLen = strlen($notFoundSuffix); + if ($notFoundSuffixLen > $messageLen) { + return; + } + + if (0 !== substr_compare($error['message'], $notFoundSuffix, -$notFoundSuffixLen)) { + return; + } + + $prefix = 'Call to undefined function '; + $prefixLen = strlen($prefix); + if (0 !== strpos($error['message'], $prefix)) { + return; + } + + $fullyQualifiedFunctionName = substr($error['message'], $prefixLen, -$notFoundSuffixLen); + if (false !== $namespaceSeparatorIndex = strrpos($fullyQualifiedFunctionName, '\\')) { + $functionName = substr($fullyQualifiedFunctionName, $namespaceSeparatorIndex + 1); + $namespacePrefix = substr($fullyQualifiedFunctionName, 0, $namespaceSeparatorIndex); + $message = sprintf('Attempted to call function "%s" from namespace "%s".', $functionName, $namespacePrefix); + } else { + $functionName = $fullyQualifiedFunctionName; + $message = sprintf('Attempted to call function "%s" from the global namespace.', $functionName); + } + + $candidates = array(); + foreach (get_defined_functions() as $type => $definedFunctionNames) { + foreach ($definedFunctionNames as $definedFunctionName) { + if (false !== $namespaceSeparatorIndex = strrpos($definedFunctionName, '\\')) { + $definedFunctionNameBasename = substr($definedFunctionName, $namespaceSeparatorIndex + 1); + } else { + $definedFunctionNameBasename = $definedFunctionName; + } + + if ($definedFunctionNameBasename === $functionName) { + $candidates[] = '\\'.$definedFunctionName; + } + } + } + + if ($candidates) { + sort($candidates); + $last = array_pop($candidates).'"?'; + if ($candidates) { + $candidates = 'e.g. "'.implode('", "', $candidates).'" or "'.$last; + } else { + $candidates = '"'.$last; + } + $message .= "\nDid you mean to call ".$candidates; + } + + return new UndefinedFunctionException($message, $exception); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/debug/FatalErrorHandler/UndefinedMethodFatalErrorHandler.php b/lib/ckfinder/core/connector/php/vendor/symfony/debug/FatalErrorHandler/UndefinedMethodFatalErrorHandler.php new file mode 100644 index 0000000..f734d6b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/debug/FatalErrorHandler/UndefinedMethodFatalErrorHandler.php @@ -0,0 +1,60 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Debug\FatalErrorHandler; + +use Symfony\Component\Debug\Exception\FatalErrorException; +use Symfony\Component\Debug\Exception\UndefinedMethodException; + +/** + * ErrorHandler for undefined methods. + * + * @author Grégoire Pineau + */ +class UndefinedMethodFatalErrorHandler implements FatalErrorHandlerInterface +{ + /** + * {@inheritdoc} + */ + public function handleError(array $error, FatalErrorException $exception) + { + preg_match('/^Call to undefined method (.*)::(.*)\(\)$/', $error['message'], $matches); + if (!$matches) { + return; + } + + $className = $matches[1]; + $methodName = $matches[2]; + + $message = sprintf('Attempted to call an undefined method named "%s" of class "%s".', $methodName, $className); + + $candidates = array(); + foreach (get_class_methods($className) as $definedMethodName) { + $lev = levenshtein($methodName, $definedMethodName); + if ($lev <= strlen($methodName) / 3 || false !== strpos($definedMethodName, $methodName)) { + $candidates[] = $definedMethodName; + } + } + + if ($candidates) { + sort($candidates); + $last = array_pop($candidates).'"?'; + if ($candidates) { + $candidates = 'e.g. "'.implode('", "', $candidates).'" or "'.$last; + } else { + $candidates = '"'.$last; + } + $message .= "\nDid you mean to call ".$candidates; + } + + return new UndefinedMethodException($message, $exception); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/event-dispatcher/ContainerAwareEventDispatcher.php b/lib/ckfinder/core/connector/php/vendor/symfony/event-dispatcher/ContainerAwareEventDispatcher.php new file mode 100644 index 0000000..b92defe --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/event-dispatcher/ContainerAwareEventDispatcher.php @@ -0,0 +1,187 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher; + +use Symfony\Component\DependencyInjection\ContainerInterface; + +/** + * Lazily loads listeners and subscribers from the dependency injection + * container. + * + * @author Fabien Potencier + * @author Bernhard Schussek + * @author Jordan Alliot + */ +class ContainerAwareEventDispatcher extends EventDispatcher +{ + /** + * The container from where services are loaded. + * + * @var ContainerInterface + */ + private $container; + + /** + * The service IDs of the event listeners and subscribers. + * + * @var array + */ + private $listenerIds = array(); + + /** + * The services registered as listeners. + * + * @var array + */ + private $listeners = array(); + + /** + * Constructor. + * + * @param ContainerInterface $container A ContainerInterface instance + */ + public function __construct(ContainerInterface $container) + { + $this->container = $container; + } + + /** + * Adds a service as event listener. + * + * @param string $eventName Event for which the listener is added + * @param array $callback The service ID of the listener service & the method + * name that has to be called + * @param int $priority The higher this value, the earlier an event listener + * will be triggered in the chain. + * Defaults to 0. + * + * @throws \InvalidArgumentException + */ + public function addListenerService($eventName, $callback, $priority = 0) + { + if (!is_array($callback) || 2 !== count($callback)) { + throw new \InvalidArgumentException('Expected an array("service", "method") argument'); + } + + $this->listenerIds[$eventName][] = array($callback[0], $callback[1], $priority); + } + + public function removeListener($eventName, $listener) + { + $this->lazyLoad($eventName); + + if (isset($this->listenerIds[$eventName])) { + foreach ($this->listenerIds[$eventName] as $i => $args) { + list($serviceId, $method, $priority) = $args; + $key = $serviceId.'.'.$method; + if (isset($this->listeners[$eventName][$key]) && $listener === array($this->listeners[$eventName][$key], $method)) { + unset($this->listeners[$eventName][$key]); + if (empty($this->listeners[$eventName])) { + unset($this->listeners[$eventName]); + } + unset($this->listenerIds[$eventName][$i]); + if (empty($this->listenerIds[$eventName])) { + unset($this->listenerIds[$eventName]); + } + } + } + } + + parent::removeListener($eventName, $listener); + } + + /** + * {@inheritdoc} + */ + public function hasListeners($eventName = null) + { + if (null === $eventName) { + return (bool) count($this->listenerIds) || (bool) count($this->listeners); + } + + if (isset($this->listenerIds[$eventName])) { + return true; + } + + return parent::hasListeners($eventName); + } + + /** + * {@inheritdoc} + */ + public function getListeners($eventName = null) + { + if (null === $eventName) { + foreach ($this->listenerIds as $serviceEventName => $args) { + $this->lazyLoad($serviceEventName); + } + } else { + $this->lazyLoad($eventName); + } + + return parent::getListeners($eventName); + } + + /** + * Adds a service as event subscriber. + * + * @param string $serviceId The service ID of the subscriber service + * @param string $class The service's class name (which must implement EventSubscriberInterface) + */ + public function addSubscriberService($serviceId, $class) + { + foreach ($class::getSubscribedEvents() as $eventName => $params) { + if (is_string($params)) { + $this->listenerIds[$eventName][] = array($serviceId, $params, 0); + } elseif (is_string($params[0])) { + $this->listenerIds[$eventName][] = array($serviceId, $params[0], isset($params[1]) ? $params[1] : 0); + } else { + foreach ($params as $listener) { + $this->listenerIds[$eventName][] = array($serviceId, $listener[0], isset($listener[1]) ? $listener[1] : 0); + } + } + } + } + + public function getContainer() + { + return $this->container; + } + + /** + * Lazily loads listeners for this event from the dependency injection + * container. + * + * @param string $eventName The name of the event to dispatch. The name of + * the event is the name of the method that is + * invoked on listeners. + */ + protected function lazyLoad($eventName) + { + if (isset($this->listenerIds[$eventName])) { + foreach ($this->listenerIds[$eventName] as $args) { + list($serviceId, $method, $priority) = $args; + $listener = $this->container->get($serviceId); + + $key = $serviceId.'.'.$method; + if (!isset($this->listeners[$eventName][$key])) { + $this->addListener($eventName, array($listener, $method), $priority); + } elseif ($listener !== $this->listeners[$eventName][$key]) { + parent::removeListener($eventName, array($this->listeners[$eventName][$key], $method)); + $this->addListener($eventName, array($listener, $method), $priority); + } + + $this->listeners[$eventName][$key] = $listener; + } + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php b/lib/ckfinder/core/connector/php/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php new file mode 100644 index 0000000..12e2b1c --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php @@ -0,0 +1,339 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher\Debug; + +use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\EventDispatcher\Event; +use Symfony\Component\Stopwatch\Stopwatch; +use Psr\Log\LoggerInterface; + +/** + * Collects some data about event listeners. + * + * This event dispatcher delegates the dispatching to another one. + * + * @author Fabien Potencier + */ +class TraceableEventDispatcher implements TraceableEventDispatcherInterface +{ + protected $logger; + protected $stopwatch; + + private $called; + private $dispatcher; + private $wrappedListeners; + + /** + * Constructor. + * + * @param EventDispatcherInterface $dispatcher An EventDispatcherInterface instance + * @param Stopwatch $stopwatch A Stopwatch instance + * @param LoggerInterface $logger A LoggerInterface instance + */ + public function __construct(EventDispatcherInterface $dispatcher, Stopwatch $stopwatch, LoggerInterface $logger = null) + { + $this->dispatcher = $dispatcher; + $this->stopwatch = $stopwatch; + $this->logger = $logger; + $this->called = array(); + $this->wrappedListeners = array(); + } + + /** + * {@inheritdoc} + */ + public function addListener($eventName, $listener, $priority = 0) + { + $this->dispatcher->addListener($eventName, $listener, $priority); + } + + /** + * {@inheritdoc} + */ + public function addSubscriber(EventSubscriberInterface $subscriber) + { + $this->dispatcher->addSubscriber($subscriber); + } + + /** + * {@inheritdoc} + */ + public function removeListener($eventName, $listener) + { + if (isset($this->wrappedListeners[$eventName])) { + foreach ($this->wrappedListeners[$eventName] as $index => $wrappedListener) { + if ($wrappedListener->getWrappedListener() === $listener) { + $listener = $wrappedListener; + unset($this->wrappedListeners[$eventName][$index]); + break; + } + } + } + + return $this->dispatcher->removeListener($eventName, $listener); + } + + /** + * {@inheritdoc} + */ + public function removeSubscriber(EventSubscriberInterface $subscriber) + { + return $this->dispatcher->removeSubscriber($subscriber); + } + + /** + * {@inheritdoc} + */ + public function getListeners($eventName = null) + { + return $this->dispatcher->getListeners($eventName); + } + + /** + * {@inheritdoc} + */ + public function hasListeners($eventName = null) + { + return $this->dispatcher->hasListeners($eventName); + } + + /** + * {@inheritdoc} + */ + public function dispatch($eventName, Event $event = null) + { + if (null === $event) { + $event = new Event(); + } + + if (null !== $this->logger && $event->isPropagationStopped()) { + $this->logger->debug(sprintf('The "%s" event is already stopped. No listeners have been called.', $eventName)); + } + + $this->preProcess($eventName); + $this->preDispatch($eventName, $event); + + $e = $this->stopwatch->start($eventName, 'section'); + + $this->dispatcher->dispatch($eventName, $event); + + if ($e->isStarted()) { + $e->stop(); + } + + $this->postDispatch($eventName, $event); + $this->postProcess($eventName); + + return $event; + } + + /** + * {@inheritdoc} + */ + public function getCalledListeners() + { + $called = array(); + foreach ($this->called as $eventName => $listeners) { + foreach ($listeners as $listener) { + $info = $this->getListenerInfo($listener->getWrappedListener(), $eventName); + $called[$eventName.'.'.$info['pretty']] = $info; + } + } + + return $called; + } + + /** + * {@inheritdoc} + */ + public function getNotCalledListeners() + { + try { + $allListeners = $this->getListeners(); + } catch (\Exception $e) { + if (null !== $this->logger) { + $this->logger->info('An exception was thrown while getting the uncalled listeners.', array('exception' => $e)); + } + + // unable to retrieve the uncalled listeners + return array(); + } + + $notCalled = array(); + foreach ($allListeners as $eventName => $listeners) { + foreach ($listeners as $listener) { + $called = false; + if (isset($this->called[$eventName])) { + foreach ($this->called[$eventName] as $l) { + if ($l->getWrappedListener() === $listener) { + $called = true; + + break; + } + } + } + + if (!$called) { + $info = $this->getListenerInfo($listener, $eventName); + $notCalled[$eventName.'.'.$info['pretty']] = $info; + } + } + } + + return $notCalled; + } + + /** + * Proxies all method calls to the original event dispatcher. + * + * @param string $method The method name + * @param array $arguments The method arguments + * + * @return mixed + */ + public function __call($method, $arguments) + { + return call_user_func_array(array($this->dispatcher, $method), $arguments); + } + + /** + * Called before dispatching the event. + * + * @param string $eventName The event name + * @param Event $event The event + */ + protected function preDispatch($eventName, Event $event) + { + } + + /** + * Called after dispatching the event. + * + * @param string $eventName The event name + * @param Event $event The event + */ + protected function postDispatch($eventName, Event $event) + { + } + + private function preProcess($eventName) + { + foreach ($this->dispatcher->getListeners($eventName) as $listener) { + $this->dispatcher->removeListener($eventName, $listener); + $info = $this->getListenerInfo($listener, $eventName); + $name = isset($info['class']) ? $info['class'] : $info['type']; + $wrappedListener = new WrappedListener($listener, $name, $this->stopwatch, $this); + $this->wrappedListeners[$eventName][] = $wrappedListener; + $this->dispatcher->addListener($eventName, $wrappedListener); + } + } + + private function postProcess($eventName) + { + unset($this->wrappedListeners[$eventName]); + $skipped = false; + foreach ($this->dispatcher->getListeners($eventName) as $listener) { + if (!$listener instanceof WrappedListener) { // #12845: a new listener was added during dispatch. + continue; + } + // Unwrap listener + $this->dispatcher->removeListener($eventName, $listener); + $this->dispatcher->addListener($eventName, $listener->getWrappedListener()); + + $info = $this->getListenerInfo($listener->getWrappedListener(), $eventName); + if ($listener->wasCalled()) { + if (null !== $this->logger) { + $this->logger->debug(sprintf('Notified event "%s" to listener "%s".', $eventName, $info['pretty'])); + } + + if (!isset($this->called[$eventName])) { + $this->called[$eventName] = new \SplObjectStorage(); + } + + $this->called[$eventName]->attach($listener); + } + + if (null !== $this->logger && $skipped) { + $this->logger->debug(sprintf('Listener "%s" was not called for event "%s".', $info['pretty'], $eventName)); + } + + if ($listener->stoppedPropagation()) { + if (null !== $this->logger) { + $this->logger->debug(sprintf('Listener "%s" stopped propagation of the event "%s".', $info['pretty'], $eventName)); + } + + $skipped = true; + } + } + } + + /** + * Returns information about the listener. + * + * @param object $listener The listener + * @param string $eventName The event name + * + * @return array Information about the listener + */ + private function getListenerInfo($listener, $eventName) + { + $info = array( + 'event' => $eventName, + ); + if ($listener instanceof \Closure) { + $info += array( + 'type' => 'Closure', + 'pretty' => 'closure', + ); + } elseif (is_string($listener)) { + try { + $r = new \ReflectionFunction($listener); + $file = $r->getFileName(); + $line = $r->getStartLine(); + } catch (\ReflectionException $e) { + $file = null; + $line = null; + } + $info += array( + 'type' => 'Function', + 'function' => $listener, + 'file' => $file, + 'line' => $line, + 'pretty' => $listener, + ); + } elseif (is_array($listener) || (is_object($listener) && is_callable($listener))) { + if (!is_array($listener)) { + $listener = array($listener, '__invoke'); + } + $class = is_object($listener[0]) ? get_class($listener[0]) : $listener[0]; + try { + $r = new \ReflectionMethod($class, $listener[1]); + $file = $r->getFileName(); + $line = $r->getStartLine(); + } catch (\ReflectionException $e) { + $file = null; + $line = null; + } + $info += array( + 'type' => 'Method', + 'class' => $class, + 'method' => $listener[1], + 'file' => $file, + 'line' => $line, + 'pretty' => $class.'::'.$listener[1], + ); + } + + return $info; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcherInterface.php b/lib/ckfinder/core/connector/php/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcherInterface.php new file mode 100644 index 0000000..5483e81 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcherInterface.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher\Debug; + +use Symfony\Component\EventDispatcher\EventDispatcherInterface; + +/** + * @author Fabien Potencier + */ +interface TraceableEventDispatcherInterface extends EventDispatcherInterface +{ + /** + * Gets the called listeners. + * + * @return array An array of called listeners + */ + public function getCalledListeners(); + + /** + * Gets the not called listeners. + * + * @return array An array of not called listeners + */ + public function getNotCalledListeners(); +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/event-dispatcher/Debug/WrappedListener.php b/lib/ckfinder/core/connector/php/vendor/symfony/event-dispatcher/Debug/WrappedListener.php new file mode 100644 index 0000000..e16627d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/event-dispatcher/Debug/WrappedListener.php @@ -0,0 +1,71 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher\Debug; + +use Symfony\Component\Stopwatch\Stopwatch; +use Symfony\Component\EventDispatcher\Event; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; + +/** + * @author Fabien Potencier + */ +class WrappedListener +{ + private $listener; + private $name; + private $called; + private $stoppedPropagation; + private $stopwatch; + private $dispatcher; + + public function __construct($listener, $name, Stopwatch $stopwatch, EventDispatcherInterface $dispatcher = null) + { + $this->listener = $listener; + $this->name = $name; + $this->stopwatch = $stopwatch; + $this->dispatcher = $dispatcher; + $this->called = false; + $this->stoppedPropagation = false; + } + + public function getWrappedListener() + { + return $this->listener; + } + + public function wasCalled() + { + return $this->called; + } + + public function stoppedPropagation() + { + return $this->stoppedPropagation; + } + + public function __invoke(Event $event, $eventName, EventDispatcherInterface $dispatcher) + { + $this->called = true; + + $e = $this->stopwatch->start($this->name, 'event_listener'); + + call_user_func($this->listener, $event, $eventName, $this->dispatcher ?: $dispatcher); + + if ($e->isStarted()) { + $e->stop(); + } + + if ($event->isPropagationStopped()) { + $this->stoppedPropagation = true; + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/event-dispatcher/DependencyInjection/RegisterListenersPass.php b/lib/ckfinder/core/connector/php/vendor/symfony/event-dispatcher/DependencyInjection/RegisterListenersPass.php new file mode 100644 index 0000000..326bfd1 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/event-dispatcher/DependencyInjection/RegisterListenersPass.php @@ -0,0 +1,113 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher\DependencyInjection; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; + +/** + * Compiler pass to register tagged services for an event dispatcher. + */ +class RegisterListenersPass implements CompilerPassInterface +{ + /** + * @var string + */ + protected $dispatcherService; + + /** + * @var string + */ + protected $listenerTag; + + /** + * @var string + */ + protected $subscriberTag; + + /** + * Constructor. + * + * @param string $dispatcherService Service name of the event dispatcher in processed container + * @param string $listenerTag Tag name used for listener + * @param string $subscriberTag Tag name used for subscribers + */ + public function __construct($dispatcherService = 'event_dispatcher', $listenerTag = 'kernel.event_listener', $subscriberTag = 'kernel.event_subscriber') + { + $this->dispatcherService = $dispatcherService; + $this->listenerTag = $listenerTag; + $this->subscriberTag = $subscriberTag; + } + + public function process(ContainerBuilder $container) + { + if (!$container->hasDefinition($this->dispatcherService) && !$container->hasAlias($this->dispatcherService)) { + return; + } + + $definition = $container->findDefinition($this->dispatcherService); + + foreach ($container->findTaggedServiceIds($this->listenerTag) as $id => $events) { + $def = $container->getDefinition($id); + if (!$def->isPublic()) { + throw new \InvalidArgumentException(sprintf('The service "%s" must be public as event listeners are lazy-loaded.', $id)); + } + + if ($def->isAbstract()) { + throw new \InvalidArgumentException(sprintf('The service "%s" must not be abstract as event listeners are lazy-loaded.', $id)); + } + + foreach ($events as $event) { + $priority = isset($event['priority']) ? $event['priority'] : 0; + + if (!isset($event['event'])) { + throw new \InvalidArgumentException(sprintf('Service "%s" must define the "event" attribute on "%s" tags.', $id, $this->listenerTag)); + } + + if (!isset($event['method'])) { + $event['method'] = 'on'.preg_replace_callback(array( + '/(?<=\b)[a-z]/i', + '/[^a-z0-9]/i', + ), function ($matches) { return strtoupper($matches[0]); }, $event['event']); + $event['method'] = preg_replace('/[^a-z0-9]/i', '', $event['method']); + } + + $definition->addMethodCall('addListenerService', array($event['event'], array($id, $event['method']), $priority)); + } + } + + foreach ($container->findTaggedServiceIds($this->subscriberTag) as $id => $attributes) { + $def = $container->getDefinition($id); + if (!$def->isPublic()) { + throw new \InvalidArgumentException(sprintf('The service "%s" must be public as event subscribers are lazy-loaded.', $id)); + } + + if ($def->isAbstract()) { + throw new \InvalidArgumentException(sprintf('The service "%s" must not be abstract as event subscribers are lazy-loaded.', $id)); + } + + // We must assume that the class value has been correctly filled, even if the service is created by a factory + $class = $container->getParameterBag()->resolveValue($def->getClass()); + $interface = 'Symfony\Component\EventDispatcher\EventSubscriberInterface'; + + if (!is_subclass_of($class, $interface)) { + if (!class_exists($class, false)) { + throw new \InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id)); + } + + throw new \InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $id, $interface)); + } + + $definition->addMethodCall('addSubscriberService', array($id, $class)); + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/event-dispatcher/Event.php b/lib/ckfinder/core/connector/php/vendor/symfony/event-dispatcher/Event.php new file mode 100644 index 0000000..956f726 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/event-dispatcher/Event.php @@ -0,0 +1,120 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher; + +/** + * Event is the base class for classes containing event data. + * + * This class contains no event data. It is used by events that do not pass + * state information to an event handler when an event is raised. + * + * You can call the method stopPropagation() to abort the execution of + * further listeners in your event listener. + * + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @author Bernhard Schussek + */ +class Event +{ + /** + * @var bool Whether no further event listeners should be triggered + */ + private $propagationStopped = false; + + /** + * @var EventDispatcher Dispatcher that dispatched this event + */ + private $dispatcher; + + /** + * @var string This event's name + */ + private $name; + + /** + * Returns whether further event listeners should be triggered. + * + * @see Event::stopPropagation() + * + * @return bool Whether propagation was already stopped for this event + */ + public function isPropagationStopped() + { + return $this->propagationStopped; + } + + /** + * Stops the propagation of the event to further event listeners. + * + * If multiple event listeners are connected to the same event, no + * further event listener will be triggered once any trigger calls + * stopPropagation(). + */ + public function stopPropagation() + { + $this->propagationStopped = true; + } + + /** + * Stores the EventDispatcher that dispatches this Event. + * + * @param EventDispatcherInterface $dispatcher + * + * @deprecated since version 2.4, to be removed in 3.0. The event dispatcher is passed to the listener call. + */ + public function setDispatcher(EventDispatcherInterface $dispatcher) + { + $this->dispatcher = $dispatcher; + } + + /** + * Returns the EventDispatcher that dispatches this Event. + * + * @return EventDispatcherInterface + * + * @deprecated since version 2.4, to be removed in 3.0. The event dispatcher is passed to the listener call. + */ + public function getDispatcher() + { + @trigger_error('The '.__METHOD__.' method is deprecated since version 2.4 and will be removed in 3.0. The event dispatcher instance can be received in the listener call instead.', E_USER_DEPRECATED); + + return $this->dispatcher; + } + + /** + * Gets the event's name. + * + * @return string + * + * @deprecated since version 2.4, to be removed in 3.0. The event name is passed to the listener call. + */ + public function getName() + { + @trigger_error('The '.__METHOD__.' method is deprecated since version 2.4 and will be removed in 3.0. The event name can be received in the listener call instead.', E_USER_DEPRECATED); + + return $this->name; + } + + /** + * Sets the event's name property. + * + * @param string $name The event name + * + * @deprecated since version 2.4, to be removed in 3.0. The event name is passed to the listener call. + */ + public function setName($name) + { + $this->name = $name; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/event-dispatcher/EventDispatcher.php b/lib/ckfinder/core/connector/php/vendor/symfony/event-dispatcher/EventDispatcher.php new file mode 100644 index 0000000..87aca2d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/event-dispatcher/EventDispatcher.php @@ -0,0 +1,177 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher; + +/** + * The EventDispatcherInterface is the central point of Symfony's event listener system. + * + * Listeners are registered on the manager and events are dispatched through the + * manager. + * + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @author Bernhard Schussek + * @author Fabien Potencier + * @author Jordi Boggiano + * @author Jordan Alliot + */ +class EventDispatcher implements EventDispatcherInterface +{ + private $listeners = array(); + private $sorted = array(); + + /** + * {@inheritdoc} + */ + public function dispatch($eventName, Event $event = null) + { + if (null === $event) { + $event = new Event(); + } + + $event->setDispatcher($this); + $event->setName($eventName); + + if ($listeners = $this->getListeners($eventName)) { + $this->doDispatch($listeners, $eventName, $event); + } + + return $event; + } + + /** + * {@inheritdoc} + */ + public function getListeners($eventName = null) + { + if (null !== $eventName) { + if (!isset($this->listeners[$eventName])) { + return array(); + } + + if (!isset($this->sorted[$eventName])) { + $this->sortListeners($eventName); + } + + return $this->sorted[$eventName]; + } + + foreach ($this->listeners as $eventName => $eventListeners) { + if (!isset($this->sorted[$eventName])) { + $this->sortListeners($eventName); + } + } + + return array_filter($this->sorted); + } + + /** + * {@inheritdoc} + */ + public function hasListeners($eventName = null) + { + return (bool) count($this->getListeners($eventName)); + } + + /** + * {@inheritdoc} + */ + public function addListener($eventName, $listener, $priority = 0) + { + $this->listeners[$eventName][$priority][] = $listener; + unset($this->sorted[$eventName]); + } + + /** + * {@inheritdoc} + */ + public function removeListener($eventName, $listener) + { + if (!isset($this->listeners[$eventName])) { + return; + } + + foreach ($this->listeners[$eventName] as $priority => $listeners) { + if (false !== ($key = array_search($listener, $listeners, true))) { + unset($this->listeners[$eventName][$priority][$key], $this->sorted[$eventName]); + } + } + } + + /** + * {@inheritdoc} + */ + public function addSubscriber(EventSubscriberInterface $subscriber) + { + foreach ($subscriber->getSubscribedEvents() as $eventName => $params) { + if (is_string($params)) { + $this->addListener($eventName, array($subscriber, $params)); + } elseif (is_string($params[0])) { + $this->addListener($eventName, array($subscriber, $params[0]), isset($params[1]) ? $params[1] : 0); + } else { + foreach ($params as $listener) { + $this->addListener($eventName, array($subscriber, $listener[0]), isset($listener[1]) ? $listener[1] : 0); + } + } + } + } + + /** + * {@inheritdoc} + */ + public function removeSubscriber(EventSubscriberInterface $subscriber) + { + foreach ($subscriber->getSubscribedEvents() as $eventName => $params) { + if (is_array($params) && is_array($params[0])) { + foreach ($params as $listener) { + $this->removeListener($eventName, array($subscriber, $listener[0])); + } + } else { + $this->removeListener($eventName, array($subscriber, is_string($params) ? $params : $params[0])); + } + } + } + + /** + * Triggers the listeners of an event. + * + * This method can be overridden to add functionality that is executed + * for each listener. + * + * @param callable[] $listeners The event listeners + * @param string $eventName The name of the event to dispatch + * @param Event $event The event object to pass to the event handlers/listeners + */ + protected function doDispatch($listeners, $eventName, Event $event) + { + foreach ($listeners as $listener) { + if ($event->isPropagationStopped()) { + break; + } + call_user_func($listener, $event, $eventName, $this); + } + } + + /** + * Sorts the internal list of listeners for the given event by priority. + * + * @param string $eventName The name of the event + */ + private function sortListeners($eventName) + { + $this->sorted[$eventName] = array(); + + krsort($this->listeners[$eventName]); + $this->sorted[$eventName] = call_user_func_array('array_merge', $this->listeners[$eventName]); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/event-dispatcher/EventDispatcherInterface.php b/lib/ckfinder/core/connector/php/vendor/symfony/event-dispatcher/EventDispatcherInterface.php new file mode 100644 index 0000000..abe8d28 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/event-dispatcher/EventDispatcherInterface.php @@ -0,0 +1,88 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher; + +/** + * The EventDispatcherInterface is the central point of Symfony's event listener system. + * Listeners are registered on the manager and events are dispatched through the + * manager. + * + * @author Bernhard Schussek + */ +interface EventDispatcherInterface +{ + /** + * Dispatches an event to all registered listeners. + * + * @param string $eventName The name of the event to dispatch. The name of + * the event is the name of the method that is + * invoked on listeners. + * @param Event $event The event to pass to the event handlers/listeners + * If not supplied, an empty Event instance is created. + * + * @return Event + */ + public function dispatch($eventName, Event $event = null); + + /** + * Adds an event listener that listens on the specified events. + * + * @param string $eventName The event to listen on + * @param callable $listener The listener + * @param int $priority The higher this value, the earlier an event + * listener will be triggered in the chain (defaults to 0) + */ + public function addListener($eventName, $listener, $priority = 0); + + /** + * Adds an event subscriber. + * + * The subscriber is asked for all the events he is + * interested in and added as a listener for these events. + * + * @param EventSubscriberInterface $subscriber The subscriber + */ + public function addSubscriber(EventSubscriberInterface $subscriber); + + /** + * Removes an event listener from the specified events. + * + * @param string $eventName The event to remove a listener from + * @param callable $listener The listener to remove + */ + public function removeListener($eventName, $listener); + + /** + * Removes an event subscriber. + * + * @param EventSubscriberInterface $subscriber The subscriber + */ + public function removeSubscriber(EventSubscriberInterface $subscriber); + + /** + * Gets the listeners of a specific event or all listeners sorted by descending priority. + * + * @param string $eventName The name of the event + * + * @return array The event listeners for the specified event, or all event listeners by event name + */ + public function getListeners($eventName = null); + + /** + * Checks whether an event has any registered listeners. + * + * @param string $eventName The name of the event + * + * @return bool true if the specified event has any listeners, false otherwise + */ + public function hasListeners($eventName = null); +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/event-dispatcher/EventSubscriberInterface.php b/lib/ckfinder/core/connector/php/vendor/symfony/event-dispatcher/EventSubscriberInterface.php new file mode 100644 index 0000000..8af7789 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/event-dispatcher/EventSubscriberInterface.php @@ -0,0 +1,46 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher; + +/** + * An EventSubscriber knows himself what events he is interested in. + * If an EventSubscriber is added to an EventDispatcherInterface, the manager invokes + * {@link getSubscribedEvents} and registers the subscriber as a listener for all + * returned events. + * + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @author Bernhard Schussek + */ +interface EventSubscriberInterface +{ + /** + * Returns an array of event names this subscriber wants to listen to. + * + * The array keys are event names and the value can be: + * + * * The method name to call (priority defaults to 0) + * * An array composed of the method name to call and the priority + * * An array of arrays composed of the method names to call and respective + * priorities, or 0 if unset + * + * For instance: + * + * * array('eventName' => 'methodName') + * * array('eventName' => array('methodName', $priority)) + * * array('eventName' => array(array('methodName1', $priority), array('methodName2'))) + * + * @return array The event names to listen to + */ + public static function getSubscribedEvents(); +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/event-dispatcher/GenericEvent.php b/lib/ckfinder/core/connector/php/vendor/symfony/event-dispatcher/GenericEvent.php new file mode 100644 index 0000000..2b9f40e --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/event-dispatcher/GenericEvent.php @@ -0,0 +1,186 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher; + +/** + * Event encapsulation class. + * + * Encapsulates events thus decoupling the observer from the subject they encapsulate. + * + * @author Drak + */ +class GenericEvent extends Event implements \ArrayAccess, \IteratorAggregate +{ + /** + * Event subject. + * + * @var mixed usually object or callable + */ + protected $subject; + + /** + * Array of arguments. + * + * @var array + */ + protected $arguments; + + /** + * Encapsulate an event with $subject and $args. + * + * @param mixed $subject The subject of the event, usually an object + * @param array $arguments Arguments to store in the event + */ + public function __construct($subject = null, array $arguments = array()) + { + $this->subject = $subject; + $this->arguments = $arguments; + } + + /** + * Getter for subject property. + * + * @return mixed $subject The observer subject + */ + public function getSubject() + { + return $this->subject; + } + + /** + * Get argument by key. + * + * @param string $key Key + * + * @return mixed Contents of array key + * + * @throws \InvalidArgumentException If key is not found. + */ + public function getArgument($key) + { + if ($this->hasArgument($key)) { + return $this->arguments[$key]; + } + + throw new \InvalidArgumentException(sprintf('Argument "%s" not found.', $key)); + } + + /** + * Add argument to event. + * + * @param string $key Argument name + * @param mixed $value Value + * + * @return GenericEvent + */ + public function setArgument($key, $value) + { + $this->arguments[$key] = $value; + + return $this; + } + + /** + * Getter for all arguments. + * + * @return array + */ + public function getArguments() + { + return $this->arguments; + } + + /** + * Set args property. + * + * @param array $args Arguments + * + * @return GenericEvent + */ + public function setArguments(array $args = array()) + { + $this->arguments = $args; + + return $this; + } + + /** + * Has argument. + * + * @param string $key Key of arguments array + * + * @return bool + */ + public function hasArgument($key) + { + return array_key_exists($key, $this->arguments); + } + + /** + * ArrayAccess for argument getter. + * + * @param string $key Array key + * + * @return mixed + * + * @throws \InvalidArgumentException If key does not exist in $this->args. + */ + public function offsetGet($key) + { + return $this->getArgument($key); + } + + /** + * ArrayAccess for argument setter. + * + * @param string $key Array key to set + * @param mixed $value Value + */ + public function offsetSet($key, $value) + { + $this->setArgument($key, $value); + } + + /** + * ArrayAccess for unset argument. + * + * @param string $key Array key + */ + public function offsetUnset($key) + { + if ($this->hasArgument($key)) { + unset($this->arguments[$key]); + } + } + + /** + * ArrayAccess has argument. + * + * @param string $key Array key + * + * @return bool + */ + public function offsetExists($key) + { + return $this->hasArgument($key); + } + + /** + * IteratorAggregate for iterating over the object like an array. + * + * @return \ArrayIterator + */ + public function getIterator() + { + return new \ArrayIterator($this->arguments); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/event-dispatcher/ImmutableEventDispatcher.php b/lib/ckfinder/core/connector/php/vendor/symfony/event-dispatcher/ImmutableEventDispatcher.php new file mode 100644 index 0000000..806cdd9 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/event-dispatcher/ImmutableEventDispatcher.php @@ -0,0 +1,93 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher; + +/** + * A read-only proxy for an event dispatcher. + * + * @author Bernhard Schussek + */ +class ImmutableEventDispatcher implements EventDispatcherInterface +{ + /** + * The proxied dispatcher. + * + * @var EventDispatcherInterface + */ + private $dispatcher; + + /** + * Creates an unmodifiable proxy for an event dispatcher. + * + * @param EventDispatcherInterface $dispatcher The proxied event dispatcher + */ + public function __construct(EventDispatcherInterface $dispatcher) + { + $this->dispatcher = $dispatcher; + } + + /** + * {@inheritdoc} + */ + public function dispatch($eventName, Event $event = null) + { + return $this->dispatcher->dispatch($eventName, $event); + } + + /** + * {@inheritdoc} + */ + public function addListener($eventName, $listener, $priority = 0) + { + throw new \BadMethodCallException('Unmodifiable event dispatchers must not be modified.'); + } + + /** + * {@inheritdoc} + */ + public function addSubscriber(EventSubscriberInterface $subscriber) + { + throw new \BadMethodCallException('Unmodifiable event dispatchers must not be modified.'); + } + + /** + * {@inheritdoc} + */ + public function removeListener($eventName, $listener) + { + throw new \BadMethodCallException('Unmodifiable event dispatchers must not be modified.'); + } + + /** + * {@inheritdoc} + */ + public function removeSubscriber(EventSubscriberInterface $subscriber) + { + throw new \BadMethodCallException('Unmodifiable event dispatchers must not be modified.'); + } + + /** + * {@inheritdoc} + */ + public function getListeners($eventName = null) + { + return $this->dispatcher->getListeners($eventName); + } + + /** + * {@inheritdoc} + */ + public function hasListeners($eventName = null) + { + return $this->dispatcher->hasListeners($eventName); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/AcceptHeader.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/AcceptHeader.php new file mode 100644 index 0000000..2260787 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/AcceptHeader.php @@ -0,0 +1,172 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation; + +/** + * Represents an Accept-* header. + * + * An accept header is compound with a list of items, + * sorted by descending quality. + * + * @author Jean-François Simon + */ +class AcceptHeader +{ + /** + * @var AcceptHeaderItem[] + */ + private $items = array(); + + /** + * @var bool + */ + private $sorted = true; + + /** + * Constructor. + * + * @param AcceptHeaderItem[] $items + */ + public function __construct(array $items) + { + foreach ($items as $item) { + $this->add($item); + } + } + + /** + * Builds an AcceptHeader instance from a string. + * + * @param string $headerValue + * + * @return AcceptHeader + */ + public static function fromString($headerValue) + { + $index = 0; + + return new self(array_map(function ($itemValue) use (&$index) { + $item = AcceptHeaderItem::fromString($itemValue); + $item->setIndex($index++); + + return $item; + }, preg_split('/\s*(?:,*("[^"]+"),*|,*(\'[^\']+\'),*|,+)\s*/', $headerValue, 0, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE))); + } + + /** + * Returns header value's string representation. + * + * @return string + */ + public function __toString() + { + return implode(',', $this->items); + } + + /** + * Tests if header has given value. + * + * @param string $value + * + * @return bool + */ + public function has($value) + { + return isset($this->items[$value]); + } + + /** + * Returns given value's item, if exists. + * + * @param string $value + * + * @return AcceptHeaderItem|null + */ + public function get($value) + { + return isset($this->items[$value]) ? $this->items[$value] : null; + } + + /** + * Adds an item. + * + * @param AcceptHeaderItem $item + * + * @return AcceptHeader + */ + public function add(AcceptHeaderItem $item) + { + $this->items[$item->getValue()] = $item; + $this->sorted = false; + + return $this; + } + + /** + * Returns all items. + * + * @return AcceptHeaderItem[] + */ + public function all() + { + $this->sort(); + + return $this->items; + } + + /** + * Filters items on their value using given regex. + * + * @param string $pattern + * + * @return AcceptHeader + */ + public function filter($pattern) + { + return new self(array_filter($this->items, function (AcceptHeaderItem $item) use ($pattern) { + return preg_match($pattern, $item->getValue()); + })); + } + + /** + * Returns first item. + * + * @return AcceptHeaderItem|null + */ + public function first() + { + $this->sort(); + + return !empty($this->items) ? reset($this->items) : null; + } + + /** + * Sorts items by descending quality. + */ + private function sort() + { + if (!$this->sorted) { + uasort($this->items, function ($a, $b) { + $qA = $a->getQuality(); + $qB = $b->getQuality(); + + if ($qA === $qB) { + return $a->getIndex() > $b->getIndex() ? 1 : -1; + } + + return $qA > $qB ? -1 : 1; + }); + + $this->sorted = true; + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/AcceptHeaderItem.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/AcceptHeaderItem.php new file mode 100644 index 0000000..21a5d15 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/AcceptHeaderItem.php @@ -0,0 +1,226 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation; + +/** + * Represents an Accept-* header item. + * + * @author Jean-François Simon + */ +class AcceptHeaderItem +{ + /** + * @var string + */ + private $value; + + /** + * @var float + */ + private $quality = 1.0; + + /** + * @var int + */ + private $index = 0; + + /** + * @var array + */ + private $attributes = array(); + + /** + * Constructor. + * + * @param string $value + * @param array $attributes + */ + public function __construct($value, array $attributes = array()) + { + $this->value = $value; + foreach ($attributes as $name => $value) { + $this->setAttribute($name, $value); + } + } + + /** + * Builds an AcceptHeaderInstance instance from a string. + * + * @param string $itemValue + * + * @return AcceptHeaderItem + */ + public static function fromString($itemValue) + { + $bits = preg_split('/\s*(?:;*("[^"]+");*|;*(\'[^\']+\');*|;+)\s*/', $itemValue, 0, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE); + $value = array_shift($bits); + $attributes = array(); + + $lastNullAttribute = null; + foreach ($bits as $bit) { + if (($start = substr($bit, 0, 1)) === ($end = substr($bit, -1)) && ($start === '"' || $start === '\'')) { + $attributes[$lastNullAttribute] = substr($bit, 1, -1); + } elseif ('=' === $end) { + $lastNullAttribute = $bit = substr($bit, 0, -1); + $attributes[$bit] = null; + } else { + $parts = explode('=', $bit); + $attributes[$parts[0]] = isset($parts[1]) && strlen($parts[1]) > 0 ? $parts[1] : ''; + } + } + + return new self(($start = substr($value, 0, 1)) === ($end = substr($value, -1)) && ($start === '"' || $start === '\'') ? substr($value, 1, -1) : $value, $attributes); + } + + /** + * Returns header value's string representation. + * + * @return string + */ + public function __toString() + { + $string = $this->value.($this->quality < 1 ? ';q='.$this->quality : ''); + if (count($this->attributes) > 0) { + $string .= ';'.implode(';', array_map(function ($name, $value) { + return sprintf(preg_match('/[,;=]/', $value) ? '%s="%s"' : '%s=%s', $name, $value); + }, array_keys($this->attributes), $this->attributes)); + } + + return $string; + } + + /** + * Set the item value. + * + * @param string $value + * + * @return AcceptHeaderItem + */ + public function setValue($value) + { + $this->value = $value; + + return $this; + } + + /** + * Returns the item value. + * + * @return string + */ + public function getValue() + { + return $this->value; + } + + /** + * Set the item quality. + * + * @param float $quality + * + * @return AcceptHeaderItem + */ + public function setQuality($quality) + { + $this->quality = $quality; + + return $this; + } + + /** + * Returns the item quality. + * + * @return float + */ + public function getQuality() + { + return $this->quality; + } + + /** + * Set the item index. + * + * @param int $index + * + * @return AcceptHeaderItem + */ + public function setIndex($index) + { + $this->index = $index; + + return $this; + } + + /** + * Returns the item index. + * + * @return int + */ + public function getIndex() + { + return $this->index; + } + + /** + * Tests if an attribute exists. + * + * @param string $name + * + * @return bool + */ + public function hasAttribute($name) + { + return isset($this->attributes[$name]); + } + + /** + * Returns an attribute by its name. + * + * @param string $name + * @param mixed $default + * + * @return mixed + */ + public function getAttribute($name, $default = null) + { + return isset($this->attributes[$name]) ? $this->attributes[$name] : $default; + } + + /** + * Returns all attributes. + * + * @return array + */ + public function getAttributes() + { + return $this->attributes; + } + + /** + * Set an attribute. + * + * @param string $name + * @param string $value + * + * @return AcceptHeaderItem + */ + public function setAttribute($name, $value) + { + if ('q' === $name) { + $this->quality = (float) $value; + } else { + $this->attributes[$name] = (string) $value; + } + + return $this; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/ApacheRequest.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/ApacheRequest.php new file mode 100644 index 0000000..84803eb --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/ApacheRequest.php @@ -0,0 +1,43 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation; + +/** + * Request represents an HTTP request from an Apache server. + * + * @author Fabien Potencier + */ +class ApacheRequest extends Request +{ + /** + * {@inheritdoc} + */ + protected function prepareRequestUri() + { + return $this->server->get('REQUEST_URI'); + } + + /** + * {@inheritdoc} + */ + protected function prepareBaseUrl() + { + $baseUrl = $this->server->get('SCRIPT_NAME'); + + if (false === strpos($this->server->get('REQUEST_URI'), $baseUrl)) { + // assume mod_rewrite + return rtrim(dirname($baseUrl), '/\\'); + } + + return $baseUrl; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/BinaryFileResponse.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/BinaryFileResponse.php new file mode 100644 index 0000000..a39984d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/BinaryFileResponse.php @@ -0,0 +1,359 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation; + +use Symfony\Component\HttpFoundation\File\File; +use Symfony\Component\HttpFoundation\File\Exception\FileException; + +/** + * BinaryFileResponse represents an HTTP response delivering a file. + * + * @author Niklas Fiekas + * @author stealth35 + * @author Igor Wiedler + * @author Jordan Alliot + * @author Sergey Linnik + */ +class BinaryFileResponse extends Response +{ + protected static $trustXSendfileTypeHeader = false; + + /** + * @var File + */ + protected $file; + protected $offset; + protected $maxlen; + protected $deleteFileAfterSend = false; + + /** + * Constructor. + * + * @param \SplFileInfo|string $file The file to stream + * @param int $status The response status code + * @param array $headers An array of response headers + * @param bool $public Files are public by default + * @param null|string $contentDisposition The type of Content-Disposition to set automatically with the filename + * @param bool $autoEtag Whether the ETag header should be automatically set + * @param bool $autoLastModified Whether the Last-Modified header should be automatically set + */ + public function __construct($file, $status = 200, $headers = array(), $public = true, $contentDisposition = null, $autoEtag = false, $autoLastModified = true) + { + parent::__construct(null, $status, $headers); + + $this->setFile($file, $contentDisposition, $autoEtag, $autoLastModified); + + if ($public) { + $this->setPublic(); + } + } + + /** + * @param \SplFileInfo|string $file The file to stream + * @param int $status The response status code + * @param array $headers An array of response headers + * @param bool $public Files are public by default + * @param null|string $contentDisposition The type of Content-Disposition to set automatically with the filename + * @param bool $autoEtag Whether the ETag header should be automatically set + * @param bool $autoLastModified Whether the Last-Modified header should be automatically set + * + * @return BinaryFileResponse The created response + */ + public static function create($file = null, $status = 200, $headers = array(), $public = true, $contentDisposition = null, $autoEtag = false, $autoLastModified = true) + { + return new static($file, $status, $headers, $public, $contentDisposition, $autoEtag, $autoLastModified); + } + + /** + * Sets the file to stream. + * + * @param \SplFileInfo|string $file The file to stream + * @param string $contentDisposition + * @param bool $autoEtag + * @param bool $autoLastModified + * + * @return BinaryFileResponse + * + * @throws FileException + */ + public function setFile($file, $contentDisposition = null, $autoEtag = false, $autoLastModified = true) + { + if (!$file instanceof File) { + if ($file instanceof \SplFileInfo) { + $file = new File($file->getPathname()); + } else { + $file = new File((string) $file); + } + } + + if (!$file->isReadable()) { + throw new FileException('File must be readable.'); + } + + $this->file = $file; + + if ($autoEtag) { + $this->setAutoEtag(); + } + + if ($autoLastModified) { + $this->setAutoLastModified(); + } + + if ($contentDisposition) { + $this->setContentDisposition($contentDisposition); + } + + return $this; + } + + /** + * Gets the file. + * + * @return File The file to stream + */ + public function getFile() + { + return $this->file; + } + + /** + * Automatically sets the Last-Modified header according the file modification date. + */ + public function setAutoLastModified() + { + $this->setLastModified(\DateTime::createFromFormat('U', $this->file->getMTime())); + + return $this; + } + + /** + * Automatically sets the ETag header according to the checksum of the file. + */ + public function setAutoEtag() + { + $this->setEtag(sha1_file($this->file->getPathname())); + + return $this; + } + + /** + * Sets the Content-Disposition header with the given filename. + * + * @param string $disposition ResponseHeaderBag::DISPOSITION_INLINE or ResponseHeaderBag::DISPOSITION_ATTACHMENT + * @param string $filename Optionally use this filename instead of the real name of the file + * @param string $filenameFallback A fallback filename, containing only ASCII characters. Defaults to an automatically encoded filename + * + * @return BinaryFileResponse + */ + public function setContentDisposition($disposition, $filename = '', $filenameFallback = '') + { + if ($filename === '') { + $filename = $this->file->getFilename(); + } + + if ('' === $filenameFallback && (!preg_match('/^[\x20-\x7e]*$/', $filename) || false !== strpos($filename, '%'))) { + $encoding = mb_detect_encoding($filename, null, true); + + for ($i = 0; $i < mb_strlen($filename, $encoding); ++$i) { + $char = mb_substr($filename, $i, 1, $encoding); + + if ('%' === $char || ord($char) < 32 || ord($char) > 126) { + $filenameFallback .= '_'; + } else { + $filenameFallback .= $char; + } + } + } + + $dispositionHeader = $this->headers->makeDisposition($disposition, $filename, $filenameFallback); + $this->headers->set('Content-Disposition', $dispositionHeader); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function prepare(Request $request) + { + $this->headers->set('Content-Length', $this->file->getSize()); + + if (!$this->headers->has('Accept-Ranges')) { + // Only accept ranges on safe HTTP methods + $this->headers->set('Accept-Ranges', $request->isMethodSafe() ? 'bytes' : 'none'); + } + + if (!$this->headers->has('Content-Type')) { + $this->headers->set('Content-Type', $this->file->getMimeType() ?: 'application/octet-stream'); + } + + if ('HTTP/1.0' !== $request->server->get('SERVER_PROTOCOL')) { + $this->setProtocolVersion('1.1'); + } + + $this->ensureIEOverSSLCompatibility($request); + + $this->offset = 0; + $this->maxlen = -1; + + if (self::$trustXSendfileTypeHeader && $request->headers->has('X-Sendfile-Type')) { + // Use X-Sendfile, do not send any content. + $type = $request->headers->get('X-Sendfile-Type'); + $path = $this->file->getRealPath(); + // Fall back to scheme://path for stream wrapped locations. + if (false === $path) { + $path = $this->file->getPathname(); + } + if (strtolower($type) === 'x-accel-redirect') { + // Do X-Accel-Mapping substitutions. + // @link http://wiki.nginx.org/X-accel#X-Accel-Redirect + foreach (explode(',', $request->headers->get('X-Accel-Mapping', '')) as $mapping) { + $mapping = explode('=', $mapping, 2); + + if (2 === count($mapping)) { + $pathPrefix = trim($mapping[0]); + $location = trim($mapping[1]); + + if (substr($path, 0, strlen($pathPrefix)) === $pathPrefix) { + $path = $location.substr($path, strlen($pathPrefix)); + break; + } + } + } + } + $this->headers->set($type, $path); + $this->maxlen = 0; + } elseif ($request->headers->has('Range')) { + // Process the range headers. + if (!$request->headers->has('If-Range') || $this->hasValidIfRangeHeader($request->headers->get('If-Range'))) { + $range = $request->headers->get('Range'); + $fileSize = $this->file->getSize(); + + list($start, $end) = explode('-', substr($range, 6), 2) + array(0); + + $end = ('' === $end) ? $fileSize - 1 : (int) $end; + + if ('' === $start) { + $start = $fileSize - $end; + $end = $fileSize - 1; + } else { + $start = (int) $start; + } + + if ($start <= $end) { + if ($start < 0 || $end > $fileSize - 1) { + $this->setStatusCode(416); + $this->headers->set('Content-Range', sprintf('bytes */%s', $fileSize)); + } elseif ($start !== 0 || $end !== $fileSize - 1) { + $this->maxlen = $end < $fileSize ? $end - $start + 1 : -1; + $this->offset = $start; + + $this->setStatusCode(206); + $this->headers->set('Content-Range', sprintf('bytes %s-%s/%s', $start, $end, $fileSize)); + $this->headers->set('Content-Length', $end - $start + 1); + } + } + } + } + + return $this; + } + + private function hasValidIfRangeHeader($header) + { + if ($this->getEtag() === $header) { + return true; + } + + if (null === $lastModified = $this->getLastModified()) { + return false; + } + + return $lastModified->format('D, d M Y H:i:s').' GMT' === $header; + } + + /** + * Sends the file. + * + * {@inheritdoc} + */ + public function sendContent() + { + if (!$this->isSuccessful()) { + return parent::sendContent(); + } + + if (0 === $this->maxlen) { + return $this; + } + + $out = fopen('php://output', 'wb'); + $file = fopen($this->file->getPathname(), 'rb'); + + stream_copy_to_stream($file, $out, $this->maxlen, $this->offset); + + fclose($out); + fclose($file); + + if ($this->deleteFileAfterSend) { + unlink($this->file->getPathname()); + } + + return $this; + } + + /** + * {@inheritdoc} + * + * @throws \LogicException when the content is not null + */ + public function setContent($content) + { + if (null !== $content) { + throw new \LogicException('The content cannot be set on a BinaryFileResponse instance.'); + } + } + + /** + * {@inheritdoc} + * + * @return false + */ + public function getContent() + { + return false; + } + + /** + * Trust X-Sendfile-Type header. + */ + public static function trustXSendfileTypeHeader() + { + self::$trustXSendfileTypeHeader = true; + } + + /** + * If this is set to true, the file will be unlinked after the request is send + * Note: If the X-Sendfile header is used, the deleteFileAfterSend setting will not be used. + * + * @param bool $shouldDelete + * + * @return BinaryFileResponse + */ + public function deleteFileAfterSend($shouldDelete) + { + $this->deleteFileAfterSend = $shouldDelete; + + return $this; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Cookie.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Cookie.php new file mode 100644 index 0000000..13d69f3 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Cookie.php @@ -0,0 +1,190 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation; + +/** + * Represents a cookie. + * + * @author Johannes M. Schmitt + */ +class Cookie +{ + protected $name; + protected $value; + protected $domain; + protected $expire; + protected $path; + protected $secure; + protected $httpOnly; + + /** + * Constructor. + * + * @param string $name The name of the cookie + * @param string $value The value of the cookie + * @param int|string|\DateTime|\DateTimeInterface $expire The time the cookie expires + * @param string $path The path on the server in which the cookie will be available on + * @param string $domain The domain that the cookie is available to + * @param bool $secure Whether the cookie should only be transmitted over a secure HTTPS connection from the client + * @param bool $httpOnly Whether the cookie will be made accessible only through the HTTP protocol + * + * @throws \InvalidArgumentException + */ + public function __construct($name, $value = null, $expire = 0, $path = '/', $domain = null, $secure = false, $httpOnly = true) + { + // from PHP source code + if (preg_match("/[=,; \t\r\n\013\014]/", $name)) { + throw new \InvalidArgumentException(sprintf('The cookie name "%s" contains invalid characters.', $name)); + } + + if (empty($name)) { + throw new \InvalidArgumentException('The cookie name cannot be empty.'); + } + + // convert expiration time to a Unix timestamp + if ($expire instanceof \DateTime || $expire instanceof \DateTimeInterface) { + $expire = $expire->format('U'); + } elseif (!is_numeric($expire)) { + $expire = strtotime($expire); + + if (false === $expire || -1 === $expire) { + throw new \InvalidArgumentException('The cookie expiration time is not valid.'); + } + } + + $this->name = $name; + $this->value = $value; + $this->domain = $domain; + $this->expire = $expire; + $this->path = empty($path) ? '/' : $path; + $this->secure = (bool) $secure; + $this->httpOnly = (bool) $httpOnly; + } + + /** + * Returns the cookie as a string. + * + * @return string The cookie + */ + public function __toString() + { + $str = urlencode($this->getName()).'='; + + if ('' === (string) $this->getValue()) { + $str .= 'deleted; expires='.gmdate('D, d-M-Y H:i:s T', time() - 31536001); + } else { + $str .= urlencode($this->getValue()); + + if ($this->getExpiresTime() !== 0) { + $str .= '; expires='.gmdate('D, d-M-Y H:i:s T', $this->getExpiresTime()); + } + } + + if ($this->path) { + $str .= '; path='.$this->path; + } + + if ($this->getDomain()) { + $str .= '; domain='.$this->getDomain(); + } + + if (true === $this->isSecure()) { + $str .= '; secure'; + } + + if (true === $this->isHttpOnly()) { + $str .= '; httponly'; + } + + return $str; + } + + /** + * Gets the name of the cookie. + * + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * Gets the value of the cookie. + * + * @return string + */ + public function getValue() + { + return $this->value; + } + + /** + * Gets the domain that the cookie is available to. + * + * @return string + */ + public function getDomain() + { + return $this->domain; + } + + /** + * Gets the time the cookie expires. + * + * @return int + */ + public function getExpiresTime() + { + return $this->expire; + } + + /** + * Gets the path on the server in which the cookie will be available on. + * + * @return string + */ + public function getPath() + { + return $this->path; + } + + /** + * Checks whether the cookie should only be transmitted over a secure HTTPS connection from the client. + * + * @return bool + */ + public function isSecure() + { + return $this->secure; + } + + /** + * Checks whether the cookie will be made accessible only through the HTTP protocol. + * + * @return bool + */ + public function isHttpOnly() + { + return $this->httpOnly; + } + + /** + * Whether this cookie is about to be cleared. + * + * @return bool + */ + public function isCleared() + { + return $this->expire < time(); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Exception/ConflictingHeadersException.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Exception/ConflictingHeadersException.php new file mode 100644 index 0000000..fa5f1c7 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Exception/ConflictingHeadersException.php @@ -0,0 +1,23 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Exception; + +/** + * The HTTP request contains headers with conflicting information. + * + * This exception should trigger an HTTP 400 response in your application code. + * + * @author Magnus Nordlander + */ +class ConflictingHeadersException extends \RuntimeException +{ +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/ExpressionRequestMatcher.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/ExpressionRequestMatcher.php new file mode 100644 index 0000000..e9c8441 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/ExpressionRequestMatcher.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation; + +use Symfony\Component\ExpressionLanguage\ExpressionLanguage; + +/** + * ExpressionRequestMatcher uses an expression to match a Request. + * + * @author Fabien Potencier + */ +class ExpressionRequestMatcher extends RequestMatcher +{ + private $language; + private $expression; + + public function setExpression(ExpressionLanguage $language, $expression) + { + $this->language = $language; + $this->expression = $expression; + } + + public function matches(Request $request) + { + if (!$this->language) { + throw new \LogicException('Unable to match the request as the expression language is not available.'); + } + + return $this->language->evaluate($this->expression, array( + 'request' => $request, + 'method' => $request->getMethod(), + 'path' => rawurldecode($request->getPathInfo()), + 'host' => $request->getHost(), + 'ip' => $request->getClientIp(), + 'attributes' => $request->attributes->all(), + )) && parent::matches($request); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/File/Exception/AccessDeniedException.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/File/Exception/AccessDeniedException.php new file mode 100644 index 0000000..41f7a46 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/File/Exception/AccessDeniedException.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\File\Exception; + +/** + * Thrown when the access on a file was denied. + * + * @author Bernhard Schussek + */ +class AccessDeniedException extends FileException +{ + /** + * Constructor. + * + * @param string $path The path to the accessed file + */ + public function __construct($path) + { + parent::__construct(sprintf('The file %s could not be accessed', $path)); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/File/Exception/FileException.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/File/Exception/FileException.php new file mode 100644 index 0000000..fad5133 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/File/Exception/FileException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\File\Exception; + +/** + * Thrown when an error occurred in the component File. + * + * @author Bernhard Schussek + */ +class FileException extends \RuntimeException +{ +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/File/Exception/FileNotFoundException.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/File/Exception/FileNotFoundException.php new file mode 100644 index 0000000..ac90d40 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/File/Exception/FileNotFoundException.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\File\Exception; + +/** + * Thrown when a file was not found. + * + * @author Bernhard Schussek + */ +class FileNotFoundException extends FileException +{ + /** + * Constructor. + * + * @param string $path The path to the file that was not found + */ + public function __construct($path) + { + parent::__construct(sprintf('The file "%s" does not exist', $path)); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/File/Exception/UnexpectedTypeException.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/File/Exception/UnexpectedTypeException.php new file mode 100644 index 0000000..0444b87 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/File/Exception/UnexpectedTypeException.php @@ -0,0 +1,20 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\File\Exception; + +class UnexpectedTypeException extends FileException +{ + public function __construct($value, $expectedType) + { + parent::__construct(sprintf('Expected argument of type %s, %s given', $expectedType, is_object($value) ? get_class($value) : gettype($value))); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/File/Exception/UploadException.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/File/Exception/UploadException.php new file mode 100644 index 0000000..7074e76 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/File/Exception/UploadException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\File\Exception; + +/** + * Thrown when an error occurred during file upload. + * + * @author Bernhard Schussek + */ +class UploadException extends FileException +{ +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/File/File.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/File/File.php new file mode 100644 index 0000000..4736b45 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/File/File.php @@ -0,0 +1,136 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\File; + +use Symfony\Component\HttpFoundation\File\Exception\FileException; +use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException; +use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesser; +use Symfony\Component\HttpFoundation\File\MimeType\ExtensionGuesser; + +/** + * A file in the file system. + * + * @author Bernhard Schussek + */ +class File extends \SplFileInfo +{ + /** + * Constructs a new file from the given path. + * + * @param string $path The path to the file + * @param bool $checkPath Whether to check the path or not + * + * @throws FileNotFoundException If the given path is not a file + */ + public function __construct($path, $checkPath = true) + { + if ($checkPath && !is_file($path)) { + throw new FileNotFoundException($path); + } + + parent::__construct($path); + } + + /** + * Returns the extension based on the mime type. + * + * If the mime type is unknown, returns null. + * + * This method uses the mime type as guessed by getMimeType() + * to guess the file extension. + * + * @return string|null The guessed extension or null if it cannot be guessed + * + * @see ExtensionGuesser + * @see getMimeType() + */ + public function guessExtension() + { + $type = $this->getMimeType(); + $guesser = ExtensionGuesser::getInstance(); + + return $guesser->guess($type); + } + + /** + * Returns the mime type of the file. + * + * The mime type is guessed using a MimeTypeGuesser instance, which uses finfo(), + * mime_content_type() and the system binary "file" (in this order), depending on + * which of those are available. + * + * @return string|null The guessed mime type (e.g. "application/pdf") + * + * @see MimeTypeGuesser + */ + public function getMimeType() + { + $guesser = MimeTypeGuesser::getInstance(); + + return $guesser->guess($this->getPathname()); + } + + /** + * Moves the file to a new location. + * + * @param string $directory The destination folder + * @param string $name The new file name + * + * @return File A File object representing the new file + * + * @throws FileException if the target file could not be created + */ + public function move($directory, $name = null) + { + $target = $this->getTargetFile($directory, $name); + + if (!@rename($this->getPathname(), $target)) { + $error = error_get_last(); + throw new FileException(sprintf('Could not move the file "%s" to "%s" (%s)', $this->getPathname(), $target, strip_tags($error['message']))); + } + + @chmod($target, 0666 & ~umask()); + + return $target; + } + + protected function getTargetFile($directory, $name = null) + { + if (!is_dir($directory)) { + if (false === @mkdir($directory, 0777, true) && !is_dir($directory)) { + throw new FileException(sprintf('Unable to create the "%s" directory', $directory)); + } + } elseif (!is_writable($directory)) { + throw new FileException(sprintf('Unable to write in the "%s" directory', $directory)); + } + + $target = rtrim($directory, '/\\').DIRECTORY_SEPARATOR.(null === $name ? $this->getBasename() : $this->getName($name)); + + return new self($target, false); + } + + /** + * Returns locale independent base name of the given path. + * + * @param string $name The new file name + * + * @return string containing + */ + protected function getName($name) + { + $originalName = str_replace('\\', '/', $name); + $pos = strrpos($originalName, '/'); + $originalName = false === $pos ? $originalName : substr($originalName, $pos + 1); + + return $originalName; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/File/MimeType/ExtensionGuesser.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/File/MimeType/ExtensionGuesser.php new file mode 100644 index 0000000..ec9b78a --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/File/MimeType/ExtensionGuesser.php @@ -0,0 +1,96 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\File\MimeType; + +/** + * A singleton mime type to file extension guesser. + * + * A default guesser is provided. + * You can register custom guessers by calling the register() + * method on the singleton instance: + * + * $guesser = ExtensionGuesser::getInstance(); + * $guesser->register(new MyCustomExtensionGuesser()); + * + * The last registered guesser is preferred over previously registered ones. + */ +class ExtensionGuesser implements ExtensionGuesserInterface +{ + /** + * The singleton instance. + * + * @var ExtensionGuesser + */ + private static $instance = null; + + /** + * All registered ExtensionGuesserInterface instances. + * + * @var array + */ + protected $guessers = array(); + + /** + * Returns the singleton instance. + * + * @return ExtensionGuesser + */ + public static function getInstance() + { + if (null === self::$instance) { + self::$instance = new self(); + } + + return self::$instance; + } + + /** + * Registers all natively provided extension guessers. + */ + private function __construct() + { + $this->register(new MimeTypeExtensionGuesser()); + } + + /** + * Registers a new extension guesser. + * + * When guessing, this guesser is preferred over previously registered ones. + * + * @param ExtensionGuesserInterface $guesser + */ + public function register(ExtensionGuesserInterface $guesser) + { + array_unshift($this->guessers, $guesser); + } + + /** + * Tries to guess the extension. + * + * The mime type is passed to each registered mime type guesser in reverse order + * of their registration (last registered is queried first). Once a guesser + * returns a value that is not NULL, this method terminates and returns the + * value. + * + * @param string $mimeType The mime type + * + * @return string The guessed extension or NULL, if none could be guessed + */ + public function guess($mimeType) + { + foreach ($this->guessers as $guesser) { + if (null !== $extension = $guesser->guess($mimeType)) { + return $extension; + } + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/File/MimeType/ExtensionGuesserInterface.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/File/MimeType/ExtensionGuesserInterface.php new file mode 100644 index 0000000..d19a0e5 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/File/MimeType/ExtensionGuesserInterface.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\File\MimeType; + +/** + * Guesses the file extension corresponding to a given mime type. + */ +interface ExtensionGuesserInterface +{ + /** + * Makes a best guess for a file extension, given a mime type. + * + * @param string $mimeType The mime type + * + * @return string The guessed extension or NULL, if none could be guessed + */ + public function guess($mimeType); +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/File/MimeType/FileBinaryMimeTypeGuesser.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/File/MimeType/FileBinaryMimeTypeGuesser.php new file mode 100644 index 0000000..f917a06 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/File/MimeType/FileBinaryMimeTypeGuesser.php @@ -0,0 +1,87 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\File\MimeType; + +use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException; +use Symfony\Component\HttpFoundation\File\Exception\AccessDeniedException; + +/** + * Guesses the mime type with the binary "file" (only available on *nix). + * + * @author Bernhard Schussek + */ +class FileBinaryMimeTypeGuesser implements MimeTypeGuesserInterface +{ + private $cmd; + + /** + * Constructor. + * + * The $cmd pattern must contain a "%s" string that will be replaced + * with the file name to guess. + * + * The command output must start with the mime type of the file. + * + * @param string $cmd The command to run to get the mime type of a file + */ + public function __construct($cmd = 'file -b --mime %s 2>/dev/null') + { + $this->cmd = $cmd; + } + + /** + * Returns whether this guesser is supported on the current OS. + * + * @return bool + */ + public static function isSupported() + { + return '\\' !== DIRECTORY_SEPARATOR && function_exists('passthru') && function_exists('escapeshellarg'); + } + + /** + * {@inheritdoc} + */ + public function guess($path) + { + if (!is_file($path)) { + throw new FileNotFoundException($path); + } + + if (!is_readable($path)) { + throw new AccessDeniedException($path); + } + + if (!self::isSupported()) { + return; + } + + ob_start(); + + // need to use --mime instead of -i. see #6641 + passthru(sprintf($this->cmd, escapeshellarg($path)), $return); + if ($return > 0) { + ob_end_clean(); + + return; + } + + $type = trim(ob_get_clean()); + + if (!preg_match('#^([a-z0-9\-]+/[a-z0-9\-\.]+)#i', $type, $match)) { + // it's not a type, but an error message + return; + } + + return $match[1]; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/File/MimeType/FileinfoMimeTypeGuesser.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/File/MimeType/FileinfoMimeTypeGuesser.php new file mode 100644 index 0000000..a7e4ae2 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/File/MimeType/FileinfoMimeTypeGuesser.php @@ -0,0 +1,71 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\File\MimeType; + +use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException; +use Symfony\Component\HttpFoundation\File\Exception\AccessDeniedException; + +/** + * Guesses the mime type using the PECL extension FileInfo. + * + * @author Bernhard Schussek + */ +class FileinfoMimeTypeGuesser implements MimeTypeGuesserInterface +{ + private $magicFile; + + /** + * Constructor. + * + * @param string $magicFile A magic file to use with the finfo instance + * + * @link http://www.php.net/manual/en/function.finfo-open.php + */ + public function __construct($magicFile = null) + { + $this->magicFile = $magicFile; + } + + /** + * Returns whether this guesser is supported on the current OS/PHP setup. + * + * @return bool + */ + public static function isSupported() + { + return function_exists('finfo_open'); + } + + /** + * {@inheritdoc} + */ + public function guess($path) + { + if (!is_file($path)) { + throw new FileNotFoundException($path); + } + + if (!is_readable($path)) { + throw new AccessDeniedException($path); + } + + if (!self::isSupported()) { + return; + } + + if (!$finfo = new \finfo(FILEINFO_MIME_TYPE, $this->magicFile)) { + return; + } + + return $finfo->file($path); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/File/MimeType/MimeTypeExtensionGuesser.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/File/MimeType/MimeTypeExtensionGuesser.php new file mode 100644 index 0000000..17fd344 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/File/MimeType/MimeTypeExtensionGuesser.php @@ -0,0 +1,808 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\File\MimeType; + +/** + * Provides a best-guess mapping of mime type to file extension. + */ +class MimeTypeExtensionGuesser implements ExtensionGuesserInterface +{ + /** + * A map of mime types and their default extensions. + * + * This list has been placed under the public domain by the Apache HTTPD project. + * This list has been updated from upstream on 2013-04-23. + * + * @see http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types + * + * @var array + */ + protected $defaultExtensions = array( + 'application/andrew-inset' => 'ez', + 'application/applixware' => 'aw', + 'application/atom+xml' => 'atom', + 'application/atomcat+xml' => 'atomcat', + 'application/atomsvc+xml' => 'atomsvc', + 'application/ccxml+xml' => 'ccxml', + 'application/cdmi-capability' => 'cdmia', + 'application/cdmi-container' => 'cdmic', + 'application/cdmi-domain' => 'cdmid', + 'application/cdmi-object' => 'cdmio', + 'application/cdmi-queue' => 'cdmiq', + 'application/cu-seeme' => 'cu', + 'application/davmount+xml' => 'davmount', + 'application/docbook+xml' => 'dbk', + 'application/dssc+der' => 'dssc', + 'application/dssc+xml' => 'xdssc', + 'application/ecmascript' => 'ecma', + 'application/emma+xml' => 'emma', + 'application/epub+zip' => 'epub', + 'application/exi' => 'exi', + 'application/font-tdpfr' => 'pfr', + 'application/gml+xml' => 'gml', + 'application/gpx+xml' => 'gpx', + 'application/gxf' => 'gxf', + 'application/hyperstudio' => 'stk', + 'application/inkml+xml' => 'ink', + 'application/ipfix' => 'ipfix', + 'application/java-archive' => 'jar', + 'application/java-serialized-object' => 'ser', + 'application/java-vm' => 'class', + 'application/javascript' => 'js', + 'application/json' => 'json', + 'application/jsonml+json' => 'jsonml', + 'application/lost+xml' => 'lostxml', + 'application/mac-binhex40' => 'hqx', + 'application/mac-compactpro' => 'cpt', + 'application/mads+xml' => 'mads', + 'application/marc' => 'mrc', + 'application/marcxml+xml' => 'mrcx', + 'application/mathematica' => 'ma', + 'application/mathml+xml' => 'mathml', + 'application/mbox' => 'mbox', + 'application/mediaservercontrol+xml' => 'mscml', + 'application/metalink+xml' => 'metalink', + 'application/metalink4+xml' => 'meta4', + 'application/mets+xml' => 'mets', + 'application/mods+xml' => 'mods', + 'application/mp21' => 'm21', + 'application/mp4' => 'mp4s', + 'application/msword' => 'doc', + 'application/mxf' => 'mxf', + 'application/octet-stream' => 'bin', + 'application/oda' => 'oda', + 'application/oebps-package+xml' => 'opf', + 'application/ogg' => 'ogx', + 'application/omdoc+xml' => 'omdoc', + 'application/onenote' => 'onetoc', + 'application/oxps' => 'oxps', + 'application/patch-ops-error+xml' => 'xer', + 'application/pdf' => 'pdf', + 'application/pgp-encrypted' => 'pgp', + 'application/pgp-signature' => 'asc', + 'application/pics-rules' => 'prf', + 'application/pkcs10' => 'p10', + 'application/pkcs7-mime' => 'p7m', + 'application/pkcs7-signature' => 'p7s', + 'application/pkcs8' => 'p8', + 'application/pkix-attr-cert' => 'ac', + 'application/pkix-cert' => 'cer', + 'application/pkix-crl' => 'crl', + 'application/pkix-pkipath' => 'pkipath', + 'application/pkixcmp' => 'pki', + 'application/pls+xml' => 'pls', + 'application/postscript' => 'ai', + 'application/prs.cww' => 'cww', + 'application/pskc+xml' => 'pskcxml', + 'application/rdf+xml' => 'rdf', + 'application/reginfo+xml' => 'rif', + 'application/relax-ng-compact-syntax' => 'rnc', + 'application/resource-lists+xml' => 'rl', + 'application/resource-lists-diff+xml' => 'rld', + 'application/rls-services+xml' => 'rs', + 'application/rpki-ghostbusters' => 'gbr', + 'application/rpki-manifest' => 'mft', + 'application/rpki-roa' => 'roa', + 'application/rsd+xml' => 'rsd', + 'application/rss+xml' => 'rss', + 'application/rtf' => 'rtf', + 'application/sbml+xml' => 'sbml', + 'application/scvp-cv-request' => 'scq', + 'application/scvp-cv-response' => 'scs', + 'application/scvp-vp-request' => 'spq', + 'application/scvp-vp-response' => 'spp', + 'application/sdp' => 'sdp', + 'application/set-payment-initiation' => 'setpay', + 'application/set-registration-initiation' => 'setreg', + 'application/shf+xml' => 'shf', + 'application/smil+xml' => 'smi', + 'application/sparql-query' => 'rq', + 'application/sparql-results+xml' => 'srx', + 'application/srgs' => 'gram', + 'application/srgs+xml' => 'grxml', + 'application/sru+xml' => 'sru', + 'application/ssdl+xml' => 'ssdl', + 'application/ssml+xml' => 'ssml', + 'application/tei+xml' => 'tei', + 'application/thraud+xml' => 'tfi', + 'application/timestamped-data' => 'tsd', + 'application/vnd.3gpp.pic-bw-large' => 'plb', + 'application/vnd.3gpp.pic-bw-small' => 'psb', + 'application/vnd.3gpp.pic-bw-var' => 'pvb', + 'application/vnd.3gpp2.tcap' => 'tcap', + 'application/vnd.3m.post-it-notes' => 'pwn', + 'application/vnd.accpac.simply.aso' => 'aso', + 'application/vnd.accpac.simply.imp' => 'imp', + 'application/vnd.acucobol' => 'acu', + 'application/vnd.acucorp' => 'atc', + 'application/vnd.adobe.air-application-installer-package+zip' => 'air', + 'application/vnd.adobe.formscentral.fcdt' => 'fcdt', + 'application/vnd.adobe.fxp' => 'fxp', + 'application/vnd.adobe.xdp+xml' => 'xdp', + 'application/vnd.adobe.xfdf' => 'xfdf', + 'application/vnd.ahead.space' => 'ahead', + 'application/vnd.airzip.filesecure.azf' => 'azf', + 'application/vnd.airzip.filesecure.azs' => 'azs', + 'application/vnd.amazon.ebook' => 'azw', + 'application/vnd.americandynamics.acc' => 'acc', + 'application/vnd.amiga.ami' => 'ami', + 'application/vnd.android.package-archive' => 'apk', + 'application/vnd.anser-web-certificate-issue-initiation' => 'cii', + 'application/vnd.anser-web-funds-transfer-initiation' => 'fti', + 'application/vnd.antix.game-component' => 'atx', + 'application/vnd.apple.installer+xml' => 'mpkg', + 'application/vnd.apple.mpegurl' => 'm3u8', + 'application/vnd.aristanetworks.swi' => 'swi', + 'application/vnd.astraea-software.iota' => 'iota', + 'application/vnd.audiograph' => 'aep', + 'application/vnd.blueice.multipass' => 'mpm', + 'application/vnd.bmi' => 'bmi', + 'application/vnd.businessobjects' => 'rep', + 'application/vnd.chemdraw+xml' => 'cdxml', + 'application/vnd.chipnuts.karaoke-mmd' => 'mmd', + 'application/vnd.cinderella' => 'cdy', + 'application/vnd.claymore' => 'cla', + 'application/vnd.cloanto.rp9' => 'rp9', + 'application/vnd.clonk.c4group' => 'c4g', + 'application/vnd.cluetrust.cartomobile-config' => 'c11amc', + 'application/vnd.cluetrust.cartomobile-config-pkg' => 'c11amz', + 'application/vnd.commonspace' => 'csp', + 'application/vnd.contact.cmsg' => 'cdbcmsg', + 'application/vnd.cosmocaller' => 'cmc', + 'application/vnd.crick.clicker' => 'clkx', + 'application/vnd.crick.clicker.keyboard' => 'clkk', + 'application/vnd.crick.clicker.palette' => 'clkp', + 'application/vnd.crick.clicker.template' => 'clkt', + 'application/vnd.crick.clicker.wordbank' => 'clkw', + 'application/vnd.criticaltools.wbs+xml' => 'wbs', + 'application/vnd.ctc-posml' => 'pml', + 'application/vnd.cups-ppd' => 'ppd', + 'application/vnd.curl.car' => 'car', + 'application/vnd.curl.pcurl' => 'pcurl', + 'application/vnd.dart' => 'dart', + 'application/vnd.data-vision.rdz' => 'rdz', + 'application/vnd.dece.data' => 'uvf', + 'application/vnd.dece.ttml+xml' => 'uvt', + 'application/vnd.dece.unspecified' => 'uvx', + 'application/vnd.dece.zip' => 'uvz', + 'application/vnd.denovo.fcselayout-link' => 'fe_launch', + 'application/vnd.dna' => 'dna', + 'application/vnd.dolby.mlp' => 'mlp', + 'application/vnd.dpgraph' => 'dpg', + 'application/vnd.dreamfactory' => 'dfac', + 'application/vnd.ds-keypoint' => 'kpxx', + 'application/vnd.dvb.ait' => 'ait', + 'application/vnd.dvb.service' => 'svc', + 'application/vnd.dynageo' => 'geo', + 'application/vnd.ecowin.chart' => 'mag', + 'application/vnd.enliven' => 'nml', + 'application/vnd.epson.esf' => 'esf', + 'application/vnd.epson.msf' => 'msf', + 'application/vnd.epson.quickanime' => 'qam', + 'application/vnd.epson.salt' => 'slt', + 'application/vnd.epson.ssf' => 'ssf', + 'application/vnd.eszigno3+xml' => 'es3', + 'application/vnd.ezpix-album' => 'ez2', + 'application/vnd.ezpix-package' => 'ez3', + 'application/vnd.fdf' => 'fdf', + 'application/vnd.fdsn.mseed' => 'mseed', + 'application/vnd.fdsn.seed' => 'seed', + 'application/vnd.flographit' => 'gph', + 'application/vnd.fluxtime.clip' => 'ftc', + 'application/vnd.framemaker' => 'fm', + 'application/vnd.frogans.fnc' => 'fnc', + 'application/vnd.frogans.ltf' => 'ltf', + 'application/vnd.fsc.weblaunch' => 'fsc', + 'application/vnd.fujitsu.oasys' => 'oas', + 'application/vnd.fujitsu.oasys2' => 'oa2', + 'application/vnd.fujitsu.oasys3' => 'oa3', + 'application/vnd.fujitsu.oasysgp' => 'fg5', + 'application/vnd.fujitsu.oasysprs' => 'bh2', + 'application/vnd.fujixerox.ddd' => 'ddd', + 'application/vnd.fujixerox.docuworks' => 'xdw', + 'application/vnd.fujixerox.docuworks.binder' => 'xbd', + 'application/vnd.fuzzysheet' => 'fzs', + 'application/vnd.genomatix.tuxedo' => 'txd', + 'application/vnd.geogebra.file' => 'ggb', + 'application/vnd.geogebra.tool' => 'ggt', + 'application/vnd.geometry-explorer' => 'gex', + 'application/vnd.geonext' => 'gxt', + 'application/vnd.geoplan' => 'g2w', + 'application/vnd.geospace' => 'g3w', + 'application/vnd.gmx' => 'gmx', + 'application/vnd.google-earth.kml+xml' => 'kml', + 'application/vnd.google-earth.kmz' => 'kmz', + 'application/vnd.grafeq' => 'gqf', + 'application/vnd.groove-account' => 'gac', + 'application/vnd.groove-help' => 'ghf', + 'application/vnd.groove-identity-message' => 'gim', + 'application/vnd.groove-injector' => 'grv', + 'application/vnd.groove-tool-message' => 'gtm', + 'application/vnd.groove-tool-template' => 'tpl', + 'application/vnd.groove-vcard' => 'vcg', + 'application/vnd.hal+xml' => 'hal', + 'application/vnd.handheld-entertainment+xml' => 'zmm', + 'application/vnd.hbci' => 'hbci', + 'application/vnd.hhe.lesson-player' => 'les', + 'application/vnd.hp-hpgl' => 'hpgl', + 'application/vnd.hp-hpid' => 'hpid', + 'application/vnd.hp-hps' => 'hps', + 'application/vnd.hp-jlyt' => 'jlt', + 'application/vnd.hp-pcl' => 'pcl', + 'application/vnd.hp-pclxl' => 'pclxl', + 'application/vnd.hydrostatix.sof-data' => 'sfd-hdstx', + 'application/vnd.ibm.minipay' => 'mpy', + 'application/vnd.ibm.modcap' => 'afp', + 'application/vnd.ibm.rights-management' => 'irm', + 'application/vnd.ibm.secure-container' => 'sc', + 'application/vnd.iccprofile' => 'icc', + 'application/vnd.igloader' => 'igl', + 'application/vnd.immervision-ivp' => 'ivp', + 'application/vnd.immervision-ivu' => 'ivu', + 'application/vnd.insors.igm' => 'igm', + 'application/vnd.intercon.formnet' => 'xpw', + 'application/vnd.intergeo' => 'i2g', + 'application/vnd.intu.qbo' => 'qbo', + 'application/vnd.intu.qfx' => 'qfx', + 'application/vnd.ipunplugged.rcprofile' => 'rcprofile', + 'application/vnd.irepository.package+xml' => 'irp', + 'application/vnd.is-xpr' => 'xpr', + 'application/vnd.isac.fcs' => 'fcs', + 'application/vnd.jam' => 'jam', + 'application/vnd.jcp.javame.midlet-rms' => 'rms', + 'application/vnd.jisp' => 'jisp', + 'application/vnd.joost.joda-archive' => 'joda', + 'application/vnd.kahootz' => 'ktz', + 'application/vnd.kde.karbon' => 'karbon', + 'application/vnd.kde.kchart' => 'chrt', + 'application/vnd.kde.kformula' => 'kfo', + 'application/vnd.kde.kivio' => 'flw', + 'application/vnd.kde.kontour' => 'kon', + 'application/vnd.kde.kpresenter' => 'kpr', + 'application/vnd.kde.kspread' => 'ksp', + 'application/vnd.kde.kword' => 'kwd', + 'application/vnd.kenameaapp' => 'htke', + 'application/vnd.kidspiration' => 'kia', + 'application/vnd.kinar' => 'kne', + 'application/vnd.koan' => 'skp', + 'application/vnd.kodak-descriptor' => 'sse', + 'application/vnd.las.las+xml' => 'lasxml', + 'application/vnd.llamagraphics.life-balance.desktop' => 'lbd', + 'application/vnd.llamagraphics.life-balance.exchange+xml' => 'lbe', + 'application/vnd.lotus-1-2-3' => '123', + 'application/vnd.lotus-approach' => 'apr', + 'application/vnd.lotus-freelance' => 'pre', + 'application/vnd.lotus-notes' => 'nsf', + 'application/vnd.lotus-organizer' => 'org', + 'application/vnd.lotus-screencam' => 'scm', + 'application/vnd.lotus-wordpro' => 'lwp', + 'application/vnd.macports.portpkg' => 'portpkg', + 'application/vnd.mcd' => 'mcd', + 'application/vnd.medcalcdata' => 'mc1', + 'application/vnd.mediastation.cdkey' => 'cdkey', + 'application/vnd.mfer' => 'mwf', + 'application/vnd.mfmp' => 'mfm', + 'application/vnd.micrografx.flo' => 'flo', + 'application/vnd.micrografx.igx' => 'igx', + 'application/vnd.mif' => 'mif', + 'application/vnd.mobius.daf' => 'daf', + 'application/vnd.mobius.dis' => 'dis', + 'application/vnd.mobius.mbk' => 'mbk', + 'application/vnd.mobius.mqy' => 'mqy', + 'application/vnd.mobius.msl' => 'msl', + 'application/vnd.mobius.plc' => 'plc', + 'application/vnd.mobius.txf' => 'txf', + 'application/vnd.mophun.application' => 'mpn', + 'application/vnd.mophun.certificate' => 'mpc', + 'application/vnd.mozilla.xul+xml' => 'xul', + 'application/vnd.ms-artgalry' => 'cil', + 'application/vnd.ms-cab-compressed' => 'cab', + 'application/vnd.ms-excel' => 'xls', + 'application/vnd.ms-excel.addin.macroenabled.12' => 'xlam', + 'application/vnd.ms-excel.sheet.binary.macroenabled.12' => 'xlsb', + 'application/vnd.ms-excel.sheet.macroenabled.12' => 'xlsm', + 'application/vnd.ms-excel.template.macroenabled.12' => 'xltm', + 'application/vnd.ms-fontobject' => 'eot', + 'application/vnd.ms-htmlhelp' => 'chm', + 'application/vnd.ms-ims' => 'ims', + 'application/vnd.ms-lrm' => 'lrm', + 'application/vnd.ms-officetheme' => 'thmx', + 'application/vnd.ms-pki.seccat' => 'cat', + 'application/vnd.ms-pki.stl' => 'stl', + 'application/vnd.ms-powerpoint' => 'ppt', + 'application/vnd.ms-powerpoint.addin.macroenabled.12' => 'ppam', + 'application/vnd.ms-powerpoint.presentation.macroenabled.12' => 'pptm', + 'application/vnd.ms-powerpoint.slide.macroenabled.12' => 'sldm', + 'application/vnd.ms-powerpoint.slideshow.macroenabled.12' => 'ppsm', + 'application/vnd.ms-powerpoint.template.macroenabled.12' => 'potm', + 'application/vnd.ms-project' => 'mpp', + 'application/vnd.ms-word.document.macroenabled.12' => 'docm', + 'application/vnd.ms-word.template.macroenabled.12' => 'dotm', + 'application/vnd.ms-works' => 'wps', + 'application/vnd.ms-wpl' => 'wpl', + 'application/vnd.ms-xpsdocument' => 'xps', + 'application/vnd.mseq' => 'mseq', + 'application/vnd.musician' => 'mus', + 'application/vnd.muvee.style' => 'msty', + 'application/vnd.mynfc' => 'taglet', + 'application/vnd.neurolanguage.nlu' => 'nlu', + 'application/vnd.nitf' => 'ntf', + 'application/vnd.noblenet-directory' => 'nnd', + 'application/vnd.noblenet-sealer' => 'nns', + 'application/vnd.noblenet-web' => 'nnw', + 'application/vnd.nokia.n-gage.data' => 'ngdat', + 'application/vnd.nokia.n-gage.symbian.install' => 'n-gage', + 'application/vnd.nokia.radio-preset' => 'rpst', + 'application/vnd.nokia.radio-presets' => 'rpss', + 'application/vnd.novadigm.edm' => 'edm', + 'application/vnd.novadigm.edx' => 'edx', + 'application/vnd.novadigm.ext' => 'ext', + 'application/vnd.oasis.opendocument.chart' => 'odc', + 'application/vnd.oasis.opendocument.chart-template' => 'otc', + 'application/vnd.oasis.opendocument.database' => 'odb', + 'application/vnd.oasis.opendocument.formula' => 'odf', + 'application/vnd.oasis.opendocument.formula-template' => 'odft', + 'application/vnd.oasis.opendocument.graphics' => 'odg', + 'application/vnd.oasis.opendocument.graphics-template' => 'otg', + 'application/vnd.oasis.opendocument.image' => 'odi', + 'application/vnd.oasis.opendocument.image-template' => 'oti', + 'application/vnd.oasis.opendocument.presentation' => 'odp', + 'application/vnd.oasis.opendocument.presentation-template' => 'otp', + 'application/vnd.oasis.opendocument.spreadsheet' => 'ods', + 'application/vnd.oasis.opendocument.spreadsheet-template' => 'ots', + 'application/vnd.oasis.opendocument.text' => 'odt', + 'application/vnd.oasis.opendocument.text-master' => 'odm', + 'application/vnd.oasis.opendocument.text-template' => 'ott', + 'application/vnd.oasis.opendocument.text-web' => 'oth', + 'application/vnd.olpc-sugar' => 'xo', + 'application/vnd.oma.dd2+xml' => 'dd2', + 'application/vnd.openofficeorg.extension' => 'oxt', + 'application/vnd.openxmlformats-officedocument.presentationml.presentation' => 'pptx', + 'application/vnd.openxmlformats-officedocument.presentationml.slide' => 'sldx', + 'application/vnd.openxmlformats-officedocument.presentationml.slideshow' => 'ppsx', + 'application/vnd.openxmlformats-officedocument.presentationml.template' => 'potx', + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => 'xlsx', + 'application/vnd.openxmlformats-officedocument.spreadsheetml.template' => 'xltx', + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => 'docx', + 'application/vnd.openxmlformats-officedocument.wordprocessingml.template' => 'dotx', + 'application/vnd.osgeo.mapguide.package' => 'mgp', + 'application/vnd.osgi.dp' => 'dp', + 'application/vnd.osgi.subsystem' => 'esa', + 'application/vnd.palm' => 'pdb', + 'application/vnd.pawaafile' => 'paw', + 'application/vnd.pg.format' => 'str', + 'application/vnd.pg.osasli' => 'ei6', + 'application/vnd.picsel' => 'efif', + 'application/vnd.pmi.widget' => 'wg', + 'application/vnd.pocketlearn' => 'plf', + 'application/vnd.powerbuilder6' => 'pbd', + 'application/vnd.previewsystems.box' => 'box', + 'application/vnd.proteus.magazine' => 'mgz', + 'application/vnd.publishare-delta-tree' => 'qps', + 'application/vnd.pvi.ptid1' => 'ptid', + 'application/vnd.quark.quarkxpress' => 'qxd', + 'application/vnd.realvnc.bed' => 'bed', + 'application/vnd.recordare.musicxml' => 'mxl', + 'application/vnd.recordare.musicxml+xml' => 'musicxml', + 'application/vnd.rig.cryptonote' => 'cryptonote', + 'application/vnd.rim.cod' => 'cod', + 'application/vnd.rn-realmedia' => 'rm', + 'application/vnd.rn-realmedia-vbr' => 'rmvb', + 'application/vnd.route66.link66+xml' => 'link66', + 'application/vnd.sailingtracker.track' => 'st', + 'application/vnd.seemail' => 'see', + 'application/vnd.sema' => 'sema', + 'application/vnd.semd' => 'semd', + 'application/vnd.semf' => 'semf', + 'application/vnd.shana.informed.formdata' => 'ifm', + 'application/vnd.shana.informed.formtemplate' => 'itp', + 'application/vnd.shana.informed.interchange' => 'iif', + 'application/vnd.shana.informed.package' => 'ipk', + 'application/vnd.simtech-mindmapper' => 'twd', + 'application/vnd.smaf' => 'mmf', + 'application/vnd.smart.teacher' => 'teacher', + 'application/vnd.solent.sdkm+xml' => 'sdkm', + 'application/vnd.spotfire.dxp' => 'dxp', + 'application/vnd.spotfire.sfs' => 'sfs', + 'application/vnd.stardivision.calc' => 'sdc', + 'application/vnd.stardivision.draw' => 'sda', + 'application/vnd.stardivision.impress' => 'sdd', + 'application/vnd.stardivision.math' => 'smf', + 'application/vnd.stardivision.writer' => 'sdw', + 'application/vnd.stardivision.writer-global' => 'sgl', + 'application/vnd.stepmania.package' => 'smzip', + 'application/vnd.stepmania.stepchart' => 'sm', + 'application/vnd.sun.xml.calc' => 'sxc', + 'application/vnd.sun.xml.calc.template' => 'stc', + 'application/vnd.sun.xml.draw' => 'sxd', + 'application/vnd.sun.xml.draw.template' => 'std', + 'application/vnd.sun.xml.impress' => 'sxi', + 'application/vnd.sun.xml.impress.template' => 'sti', + 'application/vnd.sun.xml.math' => 'sxm', + 'application/vnd.sun.xml.writer' => 'sxw', + 'application/vnd.sun.xml.writer.global' => 'sxg', + 'application/vnd.sun.xml.writer.template' => 'stw', + 'application/vnd.sus-calendar' => 'sus', + 'application/vnd.svd' => 'svd', + 'application/vnd.symbian.install' => 'sis', + 'application/vnd.syncml+xml' => 'xsm', + 'application/vnd.syncml.dm+wbxml' => 'bdm', + 'application/vnd.syncml.dm+xml' => 'xdm', + 'application/vnd.tao.intent-module-archive' => 'tao', + 'application/vnd.tcpdump.pcap' => 'pcap', + 'application/vnd.tmobile-livetv' => 'tmo', + 'application/vnd.trid.tpt' => 'tpt', + 'application/vnd.triscape.mxs' => 'mxs', + 'application/vnd.trueapp' => 'tra', + 'application/vnd.ufdl' => 'ufd', + 'application/vnd.uiq.theme' => 'utz', + 'application/vnd.umajin' => 'umj', + 'application/vnd.unity' => 'unityweb', + 'application/vnd.uoml+xml' => 'uoml', + 'application/vnd.vcx' => 'vcx', + 'application/vnd.visio' => 'vsd', + 'application/vnd.visionary' => 'vis', + 'application/vnd.vsf' => 'vsf', + 'application/vnd.wap.wbxml' => 'wbxml', + 'application/vnd.wap.wmlc' => 'wmlc', + 'application/vnd.wap.wmlscriptc' => 'wmlsc', + 'application/vnd.webturbo' => 'wtb', + 'application/vnd.wolfram.player' => 'nbp', + 'application/vnd.wordperfect' => 'wpd', + 'application/vnd.wqd' => 'wqd', + 'application/vnd.wt.stf' => 'stf', + 'application/vnd.xara' => 'xar', + 'application/vnd.xfdl' => 'xfdl', + 'application/vnd.yamaha.hv-dic' => 'hvd', + 'application/vnd.yamaha.hv-script' => 'hvs', + 'application/vnd.yamaha.hv-voice' => 'hvp', + 'application/vnd.yamaha.openscoreformat' => 'osf', + 'application/vnd.yamaha.openscoreformat.osfpvg+xml' => 'osfpvg', + 'application/vnd.yamaha.smaf-audio' => 'saf', + 'application/vnd.yamaha.smaf-phrase' => 'spf', + 'application/vnd.yellowriver-custom-menu' => 'cmp', + 'application/vnd.zul' => 'zir', + 'application/vnd.zzazz.deck+xml' => 'zaz', + 'application/voicexml+xml' => 'vxml', + 'application/widget' => 'wgt', + 'application/winhlp' => 'hlp', + 'application/wsdl+xml' => 'wsdl', + 'application/wspolicy+xml' => 'wspolicy', + 'application/x-7z-compressed' => '7z', + 'application/x-abiword' => 'abw', + 'application/x-ace-compressed' => 'ace', + 'application/x-apple-diskimage' => 'dmg', + 'application/x-authorware-bin' => 'aab', + 'application/x-authorware-map' => 'aam', + 'application/x-authorware-seg' => 'aas', + 'application/x-bcpio' => 'bcpio', + 'application/x-bittorrent' => 'torrent', + 'application/x-blorb' => 'blb', + 'application/x-bzip' => 'bz', + 'application/x-bzip2' => 'bz2', + 'application/x-cbr' => 'cbr', + 'application/x-cdlink' => 'vcd', + 'application/x-cfs-compressed' => 'cfs', + 'application/x-chat' => 'chat', + 'application/x-chess-pgn' => 'pgn', + 'application/x-conference' => 'nsc', + 'application/x-cpio' => 'cpio', + 'application/x-csh' => 'csh', + 'application/x-debian-package' => 'deb', + 'application/x-dgc-compressed' => 'dgc', + 'application/x-director' => 'dir', + 'application/x-doom' => 'wad', + 'application/x-dtbncx+xml' => 'ncx', + 'application/x-dtbook+xml' => 'dtb', + 'application/x-dtbresource+xml' => 'res', + 'application/x-dvi' => 'dvi', + 'application/x-envoy' => 'evy', + 'application/x-eva' => 'eva', + 'application/x-font-bdf' => 'bdf', + 'application/x-font-ghostscript' => 'gsf', + 'application/x-font-linux-psf' => 'psf', + 'application/x-font-otf' => 'otf', + 'application/x-font-pcf' => 'pcf', + 'application/x-font-snf' => 'snf', + 'application/x-font-ttf' => 'ttf', + 'application/x-font-type1' => 'pfa', + 'application/x-font-woff' => 'woff', + 'application/x-freearc' => 'arc', + 'application/x-futuresplash' => 'spl', + 'application/x-gca-compressed' => 'gca', + 'application/x-glulx' => 'ulx', + 'application/x-gnumeric' => 'gnumeric', + 'application/x-gramps-xml' => 'gramps', + 'application/x-gtar' => 'gtar', + 'application/x-hdf' => 'hdf', + 'application/x-install-instructions' => 'install', + 'application/x-iso9660-image' => 'iso', + 'application/x-java-jnlp-file' => 'jnlp', + 'application/x-latex' => 'latex', + 'application/x-lzh-compressed' => 'lzh', + 'application/x-mie' => 'mie', + 'application/x-mobipocket-ebook' => 'prc', + 'application/x-ms-application' => 'application', + 'application/x-ms-shortcut' => 'lnk', + 'application/x-ms-wmd' => 'wmd', + 'application/x-ms-wmz' => 'wmz', + 'application/x-ms-xbap' => 'xbap', + 'application/x-msaccess' => 'mdb', + 'application/x-msbinder' => 'obd', + 'application/x-mscardfile' => 'crd', + 'application/x-msclip' => 'clp', + 'application/x-msdownload' => 'exe', + 'application/x-msmediaview' => 'mvb', + 'application/x-msmetafile' => 'wmf', + 'application/x-msmoney' => 'mny', + 'application/x-mspublisher' => 'pub', + 'application/x-msschedule' => 'scd', + 'application/x-msterminal' => 'trm', + 'application/x-mswrite' => 'wri', + 'application/x-netcdf' => 'nc', + 'application/x-nzb' => 'nzb', + 'application/x-pkcs12' => 'p12', + 'application/x-pkcs7-certificates' => 'p7b', + 'application/x-pkcs7-certreqresp' => 'p7r', + 'application/x-rar-compressed' => 'rar', + 'application/x-rar' => 'rar', + 'application/x-research-info-systems' => 'ris', + 'application/x-sh' => 'sh', + 'application/x-shar' => 'shar', + 'application/x-shockwave-flash' => 'swf', + 'application/x-silverlight-app' => 'xap', + 'application/x-sql' => 'sql', + 'application/x-stuffit' => 'sit', + 'application/x-stuffitx' => 'sitx', + 'application/x-subrip' => 'srt', + 'application/x-sv4cpio' => 'sv4cpio', + 'application/x-sv4crc' => 'sv4crc', + 'application/x-t3vm-image' => 't3', + 'application/x-tads' => 'gam', + 'application/x-tar' => 'tar', + 'application/x-tcl' => 'tcl', + 'application/x-tex' => 'tex', + 'application/x-tex-tfm' => 'tfm', + 'application/x-texinfo' => 'texinfo', + 'application/x-tgif' => 'obj', + 'application/x-ustar' => 'ustar', + 'application/x-wais-source' => 'src', + 'application/x-x509-ca-cert' => 'der', + 'application/x-xfig' => 'fig', + 'application/x-xliff+xml' => 'xlf', + 'application/x-xpinstall' => 'xpi', + 'application/x-xz' => 'xz', + 'application/x-zmachine' => 'z1', + 'application/xaml+xml' => 'xaml', + 'application/xcap-diff+xml' => 'xdf', + 'application/xenc+xml' => 'xenc', + 'application/xhtml+xml' => 'xhtml', + 'application/xml' => 'xml', + 'application/xml-dtd' => 'dtd', + 'application/xop+xml' => 'xop', + 'application/xproc+xml' => 'xpl', + 'application/xslt+xml' => 'xslt', + 'application/xspf+xml' => 'xspf', + 'application/xv+xml' => 'mxml', + 'application/yang' => 'yang', + 'application/yin+xml' => 'yin', + 'application/zip' => 'zip', + 'audio/adpcm' => 'adp', + 'audio/basic' => 'au', + 'audio/midi' => 'mid', + 'audio/mp4' => 'mp4a', + 'audio/mpeg' => 'mpga', + 'audio/ogg' => 'oga', + 'audio/s3m' => 's3m', + 'audio/silk' => 'sil', + 'audio/vnd.dece.audio' => 'uva', + 'audio/vnd.digital-winds' => 'eol', + 'audio/vnd.dra' => 'dra', + 'audio/vnd.dts' => 'dts', + 'audio/vnd.dts.hd' => 'dtshd', + 'audio/vnd.lucent.voice' => 'lvp', + 'audio/vnd.ms-playready.media.pya' => 'pya', + 'audio/vnd.nuera.ecelp4800' => 'ecelp4800', + 'audio/vnd.nuera.ecelp7470' => 'ecelp7470', + 'audio/vnd.nuera.ecelp9600' => 'ecelp9600', + 'audio/vnd.rip' => 'rip', + 'audio/webm' => 'weba', + 'audio/x-aac' => 'aac', + 'audio/x-aiff' => 'aif', + 'audio/x-caf' => 'caf', + 'audio/x-flac' => 'flac', + 'audio/x-matroska' => 'mka', + 'audio/x-mpegurl' => 'm3u', + 'audio/x-ms-wax' => 'wax', + 'audio/x-ms-wma' => 'wma', + 'audio/x-pn-realaudio' => 'ram', + 'audio/x-pn-realaudio-plugin' => 'rmp', + 'audio/x-wav' => 'wav', + 'audio/xm' => 'xm', + 'chemical/x-cdx' => 'cdx', + 'chemical/x-cif' => 'cif', + 'chemical/x-cmdf' => 'cmdf', + 'chemical/x-cml' => 'cml', + 'chemical/x-csml' => 'csml', + 'chemical/x-xyz' => 'xyz', + 'image/bmp' => 'bmp', + 'image/x-ms-bmp' => 'bmp', + 'image/cgm' => 'cgm', + 'image/g3fax' => 'g3', + 'image/gif' => 'gif', + 'image/ief' => 'ief', + 'image/jpeg' => 'jpeg', + 'image/pjpeg' => 'jpeg', + 'image/ktx' => 'ktx', + 'image/png' => 'png', + 'image/prs.btif' => 'btif', + 'image/sgi' => 'sgi', + 'image/svg+xml' => 'svg', + 'image/tiff' => 'tiff', + 'image/vnd.adobe.photoshop' => 'psd', + 'image/vnd.dece.graphic' => 'uvi', + 'image/vnd.dvb.subtitle' => 'sub', + 'image/vnd.djvu' => 'djvu', + 'image/vnd.dwg' => 'dwg', + 'image/vnd.dxf' => 'dxf', + 'image/vnd.fastbidsheet' => 'fbs', + 'image/vnd.fpx' => 'fpx', + 'image/vnd.fst' => 'fst', + 'image/vnd.fujixerox.edmics-mmr' => 'mmr', + 'image/vnd.fujixerox.edmics-rlc' => 'rlc', + 'image/vnd.ms-modi' => 'mdi', + 'image/vnd.ms-photo' => 'wdp', + 'image/vnd.net-fpx' => 'npx', + 'image/vnd.wap.wbmp' => 'wbmp', + 'image/vnd.xiff' => 'xif', + 'image/webp' => 'webp', + 'image/x-3ds' => '3ds', + 'image/x-cmu-raster' => 'ras', + 'image/x-cmx' => 'cmx', + 'image/x-freehand' => 'fh', + 'image/x-icon' => 'ico', + 'image/x-mrsid-image' => 'sid', + 'image/x-pcx' => 'pcx', + 'image/x-pict' => 'pic', + 'image/x-portable-anymap' => 'pnm', + 'image/x-portable-bitmap' => 'pbm', + 'image/x-portable-graymap' => 'pgm', + 'image/x-portable-pixmap' => 'ppm', + 'image/x-rgb' => 'rgb', + 'image/x-tga' => 'tga', + 'image/x-xbitmap' => 'xbm', + 'image/x-xpixmap' => 'xpm', + 'image/x-xwindowdump' => 'xwd', + 'message/rfc822' => 'eml', + 'model/iges' => 'igs', + 'model/mesh' => 'msh', + 'model/vnd.collada+xml' => 'dae', + 'model/vnd.dwf' => 'dwf', + 'model/vnd.gdl' => 'gdl', + 'model/vnd.gtw' => 'gtw', + 'model/vnd.mts' => 'mts', + 'model/vnd.vtu' => 'vtu', + 'model/vrml' => 'wrl', + 'model/x3d+binary' => 'x3db', + 'model/x3d+vrml' => 'x3dv', + 'model/x3d+xml' => 'x3d', + 'text/cache-manifest' => 'appcache', + 'text/calendar' => 'ics', + 'text/css' => 'css', + 'text/csv' => 'csv', + 'text/html' => 'html', + 'text/n3' => 'n3', + 'text/plain' => 'txt', + 'text/prs.lines.tag' => 'dsc', + 'text/richtext' => 'rtx', + 'text/rtf' => 'rtf', + 'text/sgml' => 'sgml', + 'text/tab-separated-values' => 'tsv', + 'text/troff' => 't', + 'text/turtle' => 'ttl', + 'text/uri-list' => 'uri', + 'text/vcard' => 'vcard', + 'text/vnd.curl' => 'curl', + 'text/vnd.curl.dcurl' => 'dcurl', + 'text/vnd.curl.scurl' => 'scurl', + 'text/vnd.curl.mcurl' => 'mcurl', + 'text/vnd.dvb.subtitle' => 'sub', + 'text/vnd.fly' => 'fly', + 'text/vnd.fmi.flexstor' => 'flx', + 'text/vnd.graphviz' => 'gv', + 'text/vnd.in3d.3dml' => '3dml', + 'text/vnd.in3d.spot' => 'spot', + 'text/vnd.sun.j2me.app-descriptor' => 'jad', + 'text/vnd.wap.wml' => 'wml', + 'text/vnd.wap.wmlscript' => 'wmls', + 'text/x-asm' => 's', + 'text/x-c' => 'c', + 'text/x-fortran' => 'f', + 'text/x-pascal' => 'p', + 'text/x-java-source' => 'java', + 'text/x-opml' => 'opml', + 'text/x-nfo' => 'nfo', + 'text/x-setext' => 'etx', + 'text/x-sfv' => 'sfv', + 'text/x-uuencode' => 'uu', + 'text/x-vcalendar' => 'vcs', + 'text/x-vcard' => 'vcf', + 'video/3gpp' => '3gp', + 'video/3gpp2' => '3g2', + 'video/h261' => 'h261', + 'video/h263' => 'h263', + 'video/h264' => 'h264', + 'video/jpeg' => 'jpgv', + 'video/jpm' => 'jpm', + 'video/mj2' => 'mj2', + 'video/mp4' => 'mp4', + 'video/mpeg' => 'mpeg', + 'video/ogg' => 'ogv', + 'video/quicktime' => 'qt', + 'video/vnd.dece.hd' => 'uvh', + 'video/vnd.dece.mobile' => 'uvm', + 'video/vnd.dece.pd' => 'uvp', + 'video/vnd.dece.sd' => 'uvs', + 'video/vnd.dece.video' => 'uvv', + 'video/vnd.dvb.file' => 'dvb', + 'video/vnd.fvt' => 'fvt', + 'video/vnd.mpegurl' => 'mxu', + 'video/vnd.ms-playready.media.pyv' => 'pyv', + 'video/vnd.uvvu.mp4' => 'uvu', + 'video/vnd.vivo' => 'viv', + 'video/webm' => 'webm', + 'video/x-f4v' => 'f4v', + 'video/x-fli' => 'fli', + 'video/x-flv' => 'flv', + 'video/x-m4v' => 'm4v', + 'video/x-matroska' => 'mkv', + 'video/x-mng' => 'mng', + 'video/x-ms-asf' => 'asf', + 'video/x-ms-vob' => 'vob', + 'video/x-ms-wm' => 'wm', + 'video/x-ms-wmv' => 'wmv', + 'video/x-ms-wmx' => 'wmx', + 'video/x-ms-wvx' => 'wvx', + 'video/x-msvideo' => 'avi', + 'video/x-sgi-movie' => 'movie', + 'video/x-smv' => 'smv', + 'x-conference/x-cooltalk' => 'ice', + ); + + /** + * {@inheritdoc} + */ + public function guess($mimeType) + { + return isset($this->defaultExtensions[$mimeType]) ? $this->defaultExtensions[$mimeType] : null; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/File/MimeType/MimeTypeGuesser.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/File/MimeType/MimeTypeGuesser.php new file mode 100644 index 0000000..ecc8a30 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/File/MimeType/MimeTypeGuesser.php @@ -0,0 +1,144 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\File\MimeType; + +use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException; +use Symfony\Component\HttpFoundation\File\Exception\AccessDeniedException; + +/** + * A singleton mime type guesser. + * + * By default, all mime type guessers provided by the framework are installed + * (if available on the current OS/PHP setup). + * + * You can register custom guessers by calling the register() method on the + * singleton instance. Custom guessers are always called before any default ones. + * + * $guesser = MimeTypeGuesser::getInstance(); + * $guesser->register(new MyCustomMimeTypeGuesser()); + * + * If you want to change the order of the default guessers, just re-register your + * preferred one as a custom one. The last registered guesser is preferred over + * previously registered ones. + * + * Re-registering a built-in guesser also allows you to configure it: + * + * $guesser = MimeTypeGuesser::getInstance(); + * $guesser->register(new FileinfoMimeTypeGuesser('/path/to/magic/file')); + * + * @author Bernhard Schussek + */ +class MimeTypeGuesser implements MimeTypeGuesserInterface +{ + /** + * The singleton instance. + * + * @var MimeTypeGuesser + */ + private static $instance = null; + + /** + * All registered MimeTypeGuesserInterface instances. + * + * @var array + */ + protected $guessers = array(); + + /** + * Returns the singleton instance. + * + * @return MimeTypeGuesser + */ + public static function getInstance() + { + if (null === self::$instance) { + self::$instance = new self(); + } + + return self::$instance; + } + + /** + * Resets the singleton instance. + */ + public static function reset() + { + self::$instance = null; + } + + /** + * Registers all natively provided mime type guessers. + */ + private function __construct() + { + if (FileBinaryMimeTypeGuesser::isSupported()) { + $this->register(new FileBinaryMimeTypeGuesser()); + } + + if (FileinfoMimeTypeGuesser::isSupported()) { + $this->register(new FileinfoMimeTypeGuesser()); + } + } + + /** + * Registers a new mime type guesser. + * + * When guessing, this guesser is preferred over previously registered ones. + * + * @param MimeTypeGuesserInterface $guesser + */ + public function register(MimeTypeGuesserInterface $guesser) + { + array_unshift($this->guessers, $guesser); + } + + /** + * Tries to guess the mime type of the given file. + * + * The file is passed to each registered mime type guesser in reverse order + * of their registration (last registered is queried first). Once a guesser + * returns a value that is not NULL, this method terminates and returns the + * value. + * + * @param string $path The path to the file + * + * @return string The mime type or NULL, if none could be guessed + * + * @throws \LogicException + * @throws FileNotFoundException + * @throws AccessDeniedException + */ + public function guess($path) + { + if (!is_file($path)) { + throw new FileNotFoundException($path); + } + + if (!is_readable($path)) { + throw new AccessDeniedException($path); + } + + if (!$this->guessers) { + $msg = 'Unable to guess the mime type as no guessers are available'; + if (!FileinfoMimeTypeGuesser::isSupported()) { + $msg .= ' (Did you enable the php_fileinfo extension?)'; + } + throw new \LogicException($msg); + } + + foreach ($this->guessers as $guesser) { + if (null !== $mimeType = $guesser->guess($path)) { + return $mimeType; + } + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/File/MimeType/MimeTypeGuesserInterface.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/File/MimeType/MimeTypeGuesserInterface.php new file mode 100644 index 0000000..f8c3ad2 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/File/MimeType/MimeTypeGuesserInterface.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\File\MimeType; + +use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException; +use Symfony\Component\HttpFoundation\File\Exception\AccessDeniedException; + +/** + * Guesses the mime type of a file. + * + * @author Bernhard Schussek + */ +interface MimeTypeGuesserInterface +{ + /** + * Guesses the mime type of the file with the given path. + * + * @param string $path The path to the file + * + * @return string The mime type or NULL, if none could be guessed + * + * @throws FileNotFoundException If the file does not exist + * @throws AccessDeniedException If the file could not be read + */ + public function guess($path); +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/File/UploadedFile.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/File/UploadedFile.php new file mode 100644 index 0000000..1083772 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/File/UploadedFile.php @@ -0,0 +1,293 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\File; + +use Symfony\Component\HttpFoundation\File\Exception\FileException; +use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException; +use Symfony\Component\HttpFoundation\File\MimeType\ExtensionGuesser; + +/** + * A file uploaded through a form. + * + * @author Bernhard Schussek + * @author Florian Eckerstorfer + * @author Fabien Potencier + */ +class UploadedFile extends File +{ + /** + * Whether the test mode is activated. + * + * Local files are used in test mode hence the code should not enforce HTTP uploads. + * + * @var bool + */ + private $test = false; + + /** + * The original name of the uploaded file. + * + * @var string + */ + private $originalName; + + /** + * The mime type provided by the uploader. + * + * @var string + */ + private $mimeType; + + /** + * The file size provided by the uploader. + * + * @var int|null + */ + private $size; + + /** + * The UPLOAD_ERR_XXX constant provided by the uploader. + * + * @var int + */ + private $error; + + /** + * Accepts the information of the uploaded file as provided by the PHP global $_FILES. + * + * The file object is only created when the uploaded file is valid (i.e. when the + * isValid() method returns true). Otherwise the only methods that could be called + * on an UploadedFile instance are: + * + * * getClientOriginalName, + * * getClientMimeType, + * * isValid, + * * getError. + * + * Calling any other method on an non-valid instance will cause an unpredictable result. + * + * @param string $path The full temporary path to the file + * @param string $originalName The original file name + * @param string|null $mimeType The type of the file as provided by PHP; null defaults to application/octet-stream + * @param int|null $size The file size + * @param int|null $error The error constant of the upload (one of PHP's UPLOAD_ERR_XXX constants); null defaults to UPLOAD_ERR_OK + * @param bool $test Whether the test mode is active + * + * @throws FileException If file_uploads is disabled + * @throws FileNotFoundException If the file does not exist + */ + public function __construct($path, $originalName, $mimeType = null, $size = null, $error = null, $test = false) + { + $this->originalName = $this->getName($originalName); + $this->mimeType = $mimeType ?: 'application/octet-stream'; + $this->size = $size; + $this->error = $error ?: UPLOAD_ERR_OK; + $this->test = (bool) $test; + + parent::__construct($path, UPLOAD_ERR_OK === $this->error); + } + + /** + * Returns the original file name. + * + * It is extracted from the request from which the file has been uploaded. + * Then it should not be considered as a safe value. + * + * @return string|null The original name + */ + public function getClientOriginalName() + { + return $this->originalName; + } + + /** + * Returns the original file extension. + * + * It is extracted from the original file name that was uploaded. + * Then it should not be considered as a safe value. + * + * @return string The extension + */ + public function getClientOriginalExtension() + { + return pathinfo($this->originalName, PATHINFO_EXTENSION); + } + + /** + * Returns the file mime type. + * + * The client mime type is extracted from the request from which the file + * was uploaded, so it should not be considered as a safe value. + * + * For a trusted mime type, use getMimeType() instead (which guesses the mime + * type based on the file content). + * + * @return string|null The mime type + * + * @see getMimeType() + */ + public function getClientMimeType() + { + return $this->mimeType; + } + + /** + * Returns the extension based on the client mime type. + * + * If the mime type is unknown, returns null. + * + * This method uses the mime type as guessed by getClientMimeType() + * to guess the file extension. As such, the extension returned + * by this method cannot be trusted. + * + * For a trusted extension, use guessExtension() instead (which guesses + * the extension based on the guessed mime type for the file). + * + * @return string|null The guessed extension or null if it cannot be guessed + * + * @see guessExtension() + * @see getClientMimeType() + */ + public function guessClientExtension() + { + $type = $this->getClientMimeType(); + $guesser = ExtensionGuesser::getInstance(); + + return $guesser->guess($type); + } + + /** + * Returns the file size. + * + * It is extracted from the request from which the file has been uploaded. + * Then it should not be considered as a safe value. + * + * @return int|null The file size + */ + public function getClientSize() + { + return $this->size; + } + + /** + * Returns the upload error. + * + * If the upload was successful, the constant UPLOAD_ERR_OK is returned. + * Otherwise one of the other UPLOAD_ERR_XXX constants is returned. + * + * @return int The upload error + */ + public function getError() + { + return $this->error; + } + + /** + * Returns whether the file was uploaded successfully. + * + * @return bool True if the file has been uploaded with HTTP and no error occurred + */ + public function isValid() + { + $isOk = $this->error === UPLOAD_ERR_OK; + + return $this->test ? $isOk : $isOk && is_uploaded_file($this->getPathname()); + } + + /** + * Moves the file to a new location. + * + * @param string $directory The destination folder + * @param string $name The new file name + * + * @return File A File object representing the new file + * + * @throws FileException if, for any reason, the file could not have been moved + */ + public function move($directory, $name = null) + { + if ($this->isValid()) { + if ($this->test) { + return parent::move($directory, $name); + } + + $target = $this->getTargetFile($directory, $name); + + if (!@move_uploaded_file($this->getPathname(), $target)) { + $error = error_get_last(); + throw new FileException(sprintf('Could not move the file "%s" to "%s" (%s)', $this->getPathname(), $target, strip_tags($error['message']))); + } + + @chmod($target, 0666 & ~umask()); + + return $target; + } + + throw new FileException($this->getErrorMessage()); + } + + /** + * Returns the maximum size of an uploaded file as configured in php.ini. + * + * @return int The maximum size of an uploaded file in bytes + */ + public static function getMaxFilesize() + { + $iniMax = strtolower(ini_get('upload_max_filesize')); + + if ('' === $iniMax) { + return PHP_INT_MAX; + } + + $max = ltrim($iniMax, '+'); + if (0 === strpos($max, '0x')) { + $max = intval($max, 16); + } elseif (0 === strpos($max, '0')) { + $max = intval($max, 8); + } else { + $max = (int) $max; + } + + switch (substr($iniMax, -1)) { + case 't': $max *= 1024; + case 'g': $max *= 1024; + case 'm': $max *= 1024; + case 'k': $max *= 1024; + } + + return $max; + } + + /** + * Returns an informative upload error message. + * + * @return string The error message regarding the specified error code + */ + public function getErrorMessage() + { + static $errors = array( + UPLOAD_ERR_INI_SIZE => 'The file "%s" exceeds your upload_max_filesize ini directive (limit is %d KiB).', + UPLOAD_ERR_FORM_SIZE => 'The file "%s" exceeds the upload limit defined in your form.', + UPLOAD_ERR_PARTIAL => 'The file "%s" was only partially uploaded.', + UPLOAD_ERR_NO_FILE => 'No file was uploaded.', + UPLOAD_ERR_CANT_WRITE => 'The file "%s" could not be written on disk.', + UPLOAD_ERR_NO_TMP_DIR => 'File could not be uploaded: missing temporary directory.', + UPLOAD_ERR_EXTENSION => 'File upload was stopped by a PHP extension.', + ); + + $errorCode = $this->error; + $maxFilesize = $errorCode === UPLOAD_ERR_INI_SIZE ? self::getMaxFilesize() / 1024 : 0; + $message = isset($errors[$errorCode]) ? $errors[$errorCode] : 'The file "%s" was not uploaded due to an unknown error.'; + + return sprintf($message, $this->getClientOriginalName(), $maxFilesize); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/FileBag.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/FileBag.php new file mode 100644 index 0000000..197eab4 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/FileBag.php @@ -0,0 +1,145 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation; + +use Symfony\Component\HttpFoundation\File\UploadedFile; + +/** + * FileBag is a container for uploaded files. + * + * @author Fabien Potencier + * @author Bulat Shakirzyanov + */ +class FileBag extends ParameterBag +{ + private static $fileKeys = array('error', 'name', 'size', 'tmp_name', 'type'); + + /** + * Constructor. + * + * @param array $parameters An array of HTTP files + */ + public function __construct(array $parameters = array()) + { + $this->replace($parameters); + } + + /** + * {@inheritdoc} + */ + public function replace(array $files = array()) + { + $this->parameters = array(); + $this->add($files); + } + + /** + * {@inheritdoc} + */ + public function set($key, $value) + { + if (!is_array($value) && !$value instanceof UploadedFile) { + throw new \InvalidArgumentException('An uploaded file must be an array or an instance of UploadedFile.'); + } + + parent::set($key, $this->convertFileInformation($value)); + } + + /** + * {@inheritdoc} + */ + public function add(array $files = array()) + { + foreach ($files as $key => $file) { + $this->set($key, $file); + } + } + + /** + * Converts uploaded files to UploadedFile instances. + * + * @param array|UploadedFile $file A (multi-dimensional) array of uploaded file information + * + * @return array A (multi-dimensional) array of UploadedFile instances + */ + protected function convertFileInformation($file) + { + if ($file instanceof UploadedFile) { + return $file; + } + + $file = $this->fixPhpFilesArray($file); + if (is_array($file)) { + $keys = array_keys($file); + sort($keys); + + if ($keys == self::$fileKeys) { + if (UPLOAD_ERR_NO_FILE == $file['error']) { + $file = null; + } else { + $file = new UploadedFile($file['tmp_name'], $file['name'], $file['type'], $file['size'], $file['error']); + } + } else { + $file = array_map(array($this, 'convertFileInformation'), $file); + } + } + + return $file; + } + + /** + * Fixes a malformed PHP $_FILES array. + * + * PHP has a bug that the format of the $_FILES array differs, depending on + * whether the uploaded file fields had normal field names or array-like + * field names ("normal" vs. "parent[child]"). + * + * This method fixes the array to look like the "normal" $_FILES array. + * + * It's safe to pass an already converted array, in which case this method + * just returns the original array unmodified. + * + * @param array $data + * + * @return array + */ + protected function fixPhpFilesArray($data) + { + if (!is_array($data)) { + return $data; + } + + $keys = array_keys($data); + sort($keys); + + if (self::$fileKeys != $keys || !isset($data['name']) || !is_array($data['name'])) { + return $data; + } + + $files = $data; + foreach (self::$fileKeys as $k) { + unset($files[$k]); + } + + foreach ($data['name'] as $key => $name) { + $files[$key] = $this->fixPhpFilesArray(array( + 'error' => $data['error'][$key], + 'name' => $name, + 'type' => $data['type'][$key], + 'tmp_name' => $data['tmp_name'][$key], + 'size' => $data['size'][$key], + )); + } + + return $files; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/HeaderBag.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/HeaderBag.php new file mode 100644 index 0000000..29bac5e --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/HeaderBag.php @@ -0,0 +1,324 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation; + +/** + * HeaderBag is a container for HTTP headers. + * + * @author Fabien Potencier + */ +class HeaderBag implements \IteratorAggregate, \Countable +{ + protected $headers = array(); + protected $cacheControl = array(); + + /** + * Constructor. + * + * @param array $headers An array of HTTP headers + */ + public function __construct(array $headers = array()) + { + foreach ($headers as $key => $values) { + $this->set($key, $values); + } + } + + /** + * Returns the headers as a string. + * + * @return string The headers + */ + public function __toString() + { + if (!$this->headers) { + return ''; + } + + $max = max(array_map('strlen', array_keys($this->headers))) + 1; + $content = ''; + ksort($this->headers); + foreach ($this->headers as $name => $values) { + $name = implode('-', array_map('ucfirst', explode('-', $name))); + foreach ($values as $value) { + $content .= sprintf("%-{$max}s %s\r\n", $name.':', $value); + } + } + + return $content; + } + + /** + * Returns the headers. + * + * @return array An array of headers + */ + public function all() + { + return $this->headers; + } + + /** + * Returns the parameter keys. + * + * @return array An array of parameter keys + */ + public function keys() + { + return array_keys($this->headers); + } + + /** + * Replaces the current HTTP headers by a new set. + * + * @param array $headers An array of HTTP headers + */ + public function replace(array $headers = array()) + { + $this->headers = array(); + $this->add($headers); + } + + /** + * Adds new headers the current HTTP headers set. + * + * @param array $headers An array of HTTP headers + */ + public function add(array $headers) + { + foreach ($headers as $key => $values) { + $this->set($key, $values); + } + } + + /** + * Returns a header value by name. + * + * @param string $key The header name + * @param mixed $default The default value + * @param bool $first Whether to return the first value or all header values + * + * @return string|array The first header value if $first is true, an array of values otherwise + */ + public function get($key, $default = null, $first = true) + { + $key = str_replace('_', '-', strtolower($key)); + + if (!array_key_exists($key, $this->headers)) { + if (null === $default) { + return $first ? null : array(); + } + + return $first ? $default : array($default); + } + + if ($first) { + return count($this->headers[$key]) ? $this->headers[$key][0] : $default; + } + + return $this->headers[$key]; + } + + /** + * Sets a header by name. + * + * @param string $key The key + * @param string|array $values The value or an array of values + * @param bool $replace Whether to replace the actual value or not (true by default) + */ + public function set($key, $values, $replace = true) + { + $key = str_replace('_', '-', strtolower($key)); + + $values = array_values((array) $values); + + if (true === $replace || !isset($this->headers[$key])) { + $this->headers[$key] = $values; + } else { + $this->headers[$key] = array_merge($this->headers[$key], $values); + } + + if ('cache-control' === $key) { + $this->cacheControl = $this->parseCacheControl($values[0]); + } + } + + /** + * Returns true if the HTTP header is defined. + * + * @param string $key The HTTP header + * + * @return bool true if the parameter exists, false otherwise + */ + public function has($key) + { + return array_key_exists(str_replace('_', '-', strtolower($key)), $this->headers); + } + + /** + * Returns true if the given HTTP header contains the given value. + * + * @param string $key The HTTP header name + * @param string $value The HTTP value + * + * @return bool true if the value is contained in the header, false otherwise + */ + public function contains($key, $value) + { + return in_array($value, $this->get($key, null, false)); + } + + /** + * Removes a header. + * + * @param string $key The HTTP header name + */ + public function remove($key) + { + $key = str_replace('_', '-', strtolower($key)); + + unset($this->headers[$key]); + + if ('cache-control' === $key) { + $this->cacheControl = array(); + } + } + + /** + * Returns the HTTP header value converted to a date. + * + * @param string $key The parameter key + * @param \DateTime $default The default value + * + * @return null|\DateTime The parsed DateTime or the default value if the header does not exist + * + * @throws \RuntimeException When the HTTP header is not parseable + */ + public function getDate($key, \DateTime $default = null) + { + if (null === $value = $this->get($key)) { + return $default; + } + + if (false === $date = \DateTime::createFromFormat(DATE_RFC2822, $value)) { + throw new \RuntimeException(sprintf('The %s HTTP header is not parseable (%s).', $key, $value)); + } + + return $date; + } + + /** + * Adds a custom Cache-Control directive. + * + * @param string $key The Cache-Control directive name + * @param mixed $value The Cache-Control directive value + */ + public function addCacheControlDirective($key, $value = true) + { + $this->cacheControl[$key] = $value; + + $this->set('Cache-Control', $this->getCacheControlHeader()); + } + + /** + * Returns true if the Cache-Control directive is defined. + * + * @param string $key The Cache-Control directive + * + * @return bool true if the directive exists, false otherwise + */ + public function hasCacheControlDirective($key) + { + return array_key_exists($key, $this->cacheControl); + } + + /** + * Returns a Cache-Control directive value by name. + * + * @param string $key The directive name + * + * @return mixed|null The directive value if defined, null otherwise + */ + public function getCacheControlDirective($key) + { + return array_key_exists($key, $this->cacheControl) ? $this->cacheControl[$key] : null; + } + + /** + * Removes a Cache-Control directive. + * + * @param string $key The Cache-Control directive + */ + public function removeCacheControlDirective($key) + { + unset($this->cacheControl[$key]); + + $this->set('Cache-Control', $this->getCacheControlHeader()); + } + + /** + * Returns an iterator for headers. + * + * @return \ArrayIterator An \ArrayIterator instance + */ + public function getIterator() + { + return new \ArrayIterator($this->headers); + } + + /** + * Returns the number of headers. + * + * @return int The number of headers + */ + public function count() + { + return count($this->headers); + } + + protected function getCacheControlHeader() + { + $parts = array(); + ksort($this->cacheControl); + foreach ($this->cacheControl as $key => $value) { + if (true === $value) { + $parts[] = $key; + } else { + if (preg_match('#[^a-zA-Z0-9._-]#', $value)) { + $value = '"'.$value.'"'; + } + + $parts[] = "$key=$value"; + } + } + + return implode(', ', $parts); + } + + /** + * Parses a Cache-Control HTTP header. + * + * @param string $header The value of the Cache-Control HTTP header + * + * @return array An array representing the attribute values + */ + protected function parseCacheControl($header) + { + $cacheControl = array(); + preg_match_all('#([a-zA-Z][a-zA-Z_-]*)\s*(?:=(?:"([^"]*)"|([^ \t",;]*)))?#', $header, $matches, PREG_SET_ORDER); + foreach ($matches as $match) { + $cacheControl[strtolower($match[1])] = isset($match[3]) ? $match[3] : (isset($match[2]) ? $match[2] : true); + } + + return $cacheControl; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/IpUtils.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/IpUtils.php new file mode 100644 index 0000000..28093be --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/IpUtils.php @@ -0,0 +1,136 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation; + +/** + * Http utility functions. + * + * @author Fabien Potencier + */ +class IpUtils +{ + /** + * This class should not be instantiated. + */ + private function __construct() + { + } + + /** + * Checks if an IPv4 or IPv6 address is contained in the list of given IPs or subnets. + * + * @param string $requestIp IP to check + * @param string|array $ips List of IPs or subnets (can be a string if only a single one) + * + * @return bool Whether the IP is valid + */ + public static function checkIp($requestIp, $ips) + { + if (!is_array($ips)) { + $ips = array($ips); + } + + $method = substr_count($requestIp, ':') > 1 ? 'checkIp6' : 'checkIp4'; + + foreach ($ips as $ip) { + if (self::$method($requestIp, $ip)) { + return true; + } + } + + return false; + } + + /** + * Compares two IPv4 addresses. + * In case a subnet is given, it checks if it contains the request IP. + * + * @param string $requestIp IPv4 address to check + * @param string $ip IPv4 address or subnet in CIDR notation + * + * @return bool Whether the request IP matches the IP, or whether the request IP is within the CIDR subnet + */ + public static function checkIp4($requestIp, $ip) + { + if (!filter_var($requestIp, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { + return false; + } + + if (false !== strpos($ip, '/')) { + list($address, $netmask) = explode('/', $ip, 2); + + if ($netmask === '0') { + return filter_var($address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4); + } + + if ($netmask < 0 || $netmask > 32) { + return false; + } + } else { + $address = $ip; + $netmask = 32; + } + + return 0 === substr_compare(sprintf('%032b', ip2long($requestIp)), sprintf('%032b', ip2long($address)), 0, $netmask); + } + + /** + * Compares two IPv6 addresses. + * In case a subnet is given, it checks if it contains the request IP. + * + * @author David Soria Parra + * + * @see https://github.com/dsp/v6tools + * + * @param string $requestIp IPv6 address to check + * @param string $ip IPv6 address or subnet in CIDR notation + * + * @return bool Whether the IP is valid + * + * @throws \RuntimeException When IPV6 support is not enabled + */ + public static function checkIp6($requestIp, $ip) + { + if (!((extension_loaded('sockets') && defined('AF_INET6')) || @inet_pton('::1'))) { + throw new \RuntimeException('Unable to check Ipv6. Check that PHP was not compiled with option "disable-ipv6".'); + } + + if (false !== strpos($ip, '/')) { + list($address, $netmask) = explode('/', $ip, 2); + + if ($netmask < 1 || $netmask > 128) { + return false; + } + } else { + $address = $ip; + $netmask = 128; + } + + $bytesAddr = unpack('n*', @inet_pton($address)); + $bytesTest = unpack('n*', @inet_pton($requestIp)); + + if (!$bytesAddr || !$bytesTest) { + return false; + } + + for ($i = 1, $ceil = ceil($netmask / 16); $i <= $ceil; ++$i) { + $left = $netmask - 16 * ($i - 1); + $left = ($left <= 16) ? $left : 16; + $mask = ~(0xffff >> $left) & 0xffff; + if (($bytesAddr[$i] & $mask) != ($bytesTest[$i] & $mask)) { + return false; + } + } + + return true; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/JsonResponse.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/JsonResponse.php new file mode 100644 index 0000000..4672cdc --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/JsonResponse.php @@ -0,0 +1,237 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation; + +/** + * Response represents an HTTP response in JSON format. + * + * Note that this class does not force the returned JSON content to be an + * object. It is however recommended that you do return an object as it + * protects yourself against XSSI and JSON-JavaScript Hijacking. + * + * @see https://www.owasp.org/index.php/OWASP_AJAX_Security_Guidelines#Always_return_JSON_with_an_Object_on_the_outside + * + * @author Igor Wiedler + */ +class JsonResponse extends Response +{ + protected $data; + protected $callback; + + // Encode <, >, ', &, and " characters in the JSON, making it also safe to be embedded into HTML. + // 15 === JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT + protected $encodingOptions = 15; + + /** + * Constructor. + * + * @param mixed $data The response data + * @param int $status The response status code + * @param array $headers An array of response headers + */ + public function __construct($data = null, $status = 200, $headers = array()) + { + parent::__construct('', $status, $headers); + + if (null === $data) { + $data = new \ArrayObject(); + } + + $this->setData($data); + } + + /** + * Factory method for chainability. + * + * Example: + * + * return JsonResponse::create($data, 200) + * ->setSharedMaxAge(300); + * + * @param mixed $data The json response data + * @param int $status The response status code + * @param array $headers An array of response headers + * + * @return JsonResponse + */ + public static function create($data = null, $status = 200, $headers = array()) + { + return new static($data, $status, $headers); + } + + /** + * Sets the JSONP callback. + * + * @param string|null $callback The JSONP callback or null to use none + * + * @return JsonResponse + * + * @throws \InvalidArgumentException When the callback name is not valid + */ + public function setCallback($callback = null) + { + if (null !== $callback) { + // taken from http://www.geekality.net/2011/08/03/valid-javascript-identifier/ + $pattern = '/^[$_\p{L}][$_\p{L}\p{Mn}\p{Mc}\p{Nd}\p{Pc}\x{200C}\x{200D}]*+$/u'; + $parts = explode('.', $callback); + foreach ($parts as $part) { + if (!preg_match($pattern, $part)) { + throw new \InvalidArgumentException('The callback name is not valid.'); + } + } + } + + $this->callback = $callback; + + return $this->update(); + } + + /** + * Sets the data to be sent as JSON. + * + * @param mixed $data + * + * @return JsonResponse + * + * @throws \InvalidArgumentException + */ + public function setData($data = array()) + { + if (defined('HHVM_VERSION')) { + // HHVM does not trigger any warnings and let exceptions + // thrown from a JsonSerializable object pass through. + // If only PHP did the same... + $data = json_encode($data, $this->encodingOptions); + } else { + try { + if (PHP_VERSION_ID < 50400) { + // PHP 5.3 triggers annoying warnings for some + // types that can't be serialized as JSON (INF, resources, etc.) + // but doesn't provide the JsonSerializable interface. + set_error_handler(function () { return false; }); + $data = @json_encode($data, $this->encodingOptions); + } else { + // PHP 5.4 and up wrap exceptions thrown by JsonSerializable + // objects in a new exception that needs to be removed. + // Fortunately, PHP 5.5 and up do not trigger any warning anymore. + if (PHP_VERSION_ID < 50500) { + // Clear json_last_error() + json_encode(null); + $errorHandler = set_error_handler('var_dump'); + restore_error_handler(); + set_error_handler(function () use ($errorHandler) { + if (JSON_ERROR_NONE === json_last_error()) { + return $errorHandler && false !== call_user_func_array($errorHandler, func_get_args()); + } + }); + } + + $data = json_encode($data, $this->encodingOptions); + } + + if (PHP_VERSION_ID < 50500) { + restore_error_handler(); + } + } catch (\Exception $e) { + if (PHP_VERSION_ID < 50500) { + restore_error_handler(); + } + if (PHP_VERSION_ID >= 50400 && 'Exception' === get_class($e) && 0 === strpos($e->getMessage(), 'Failed calling ')) { + throw $e->getPrevious() ?: $e; + } + throw $e; + } + } + + if (JSON_ERROR_NONE !== json_last_error()) { + throw new \InvalidArgumentException($this->transformJsonError()); + } + + $this->data = $data; + + return $this->update(); + } + + /** + * Returns options used while encoding data to JSON. + * + * @return int + */ + public function getEncodingOptions() + { + return $this->encodingOptions; + } + + /** + * Sets options used while encoding data to JSON. + * + * @param int $encodingOptions + * + * @return JsonResponse + */ + public function setEncodingOptions($encodingOptions) + { + $this->encodingOptions = (int) $encodingOptions; + + return $this->setData(json_decode($this->data)); + } + + /** + * Updates the content and headers according to the JSON data and callback. + * + * @return JsonResponse + */ + protected function update() + { + if (null !== $this->callback) { + // Not using application/javascript for compatibility reasons with older browsers. + $this->headers->set('Content-Type', 'text/javascript'); + + return $this->setContent(sprintf('/**/%s(%s);', $this->callback, $this->data)); + } + + // Only set the header when there is none or when it equals 'text/javascript' (from a previous update with callback) + // in order to not overwrite a custom definition. + if (!$this->headers->has('Content-Type') || 'text/javascript' === $this->headers->get('Content-Type')) { + $this->headers->set('Content-Type', 'application/json'); + } + + return $this->setContent($this->data); + } + + private function transformJsonError() + { + if (function_exists('json_last_error_msg')) { + return json_last_error_msg(); + } + + switch (json_last_error()) { + case JSON_ERROR_DEPTH: + return 'Maximum stack depth exceeded.'; + + case JSON_ERROR_STATE_MISMATCH: + return 'Underflow or the modes mismatch.'; + + case JSON_ERROR_CTRL_CHAR: + return 'Unexpected control character found.'; + + case JSON_ERROR_SYNTAX: + return 'Syntax error, malformed JSON.'; + + case JSON_ERROR_UTF8: + return 'Malformed UTF-8 characters, possibly incorrectly encoded.'; + + default: + return 'Unknown error.'; + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/ParameterBag.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/ParameterBag.php new file mode 100644 index 0000000..4d082a8 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/ParameterBag.php @@ -0,0 +1,291 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation; + +/** + * ParameterBag is a container for key/value pairs. + * + * @author Fabien Potencier + */ +class ParameterBag implements \IteratorAggregate, \Countable +{ + /** + * Parameter storage. + * + * @var array + */ + protected $parameters; + + /** + * Constructor. + * + * @param array $parameters An array of parameters + */ + public function __construct(array $parameters = array()) + { + $this->parameters = $parameters; + } + + /** + * Returns the parameters. + * + * @return array An array of parameters + */ + public function all() + { + return $this->parameters; + } + + /** + * Returns the parameter keys. + * + * @return array An array of parameter keys + */ + public function keys() + { + return array_keys($this->parameters); + } + + /** + * Replaces the current parameters by a new set. + * + * @param array $parameters An array of parameters + */ + public function replace(array $parameters = array()) + { + $this->parameters = $parameters; + } + + /** + * Adds parameters. + * + * @param array $parameters An array of parameters + */ + public function add(array $parameters = array()) + { + $this->parameters = array_replace($this->parameters, $parameters); + } + + /** + * Returns a parameter by name. + * + * @param string $path The key + * @param mixed $default The default value if the parameter key does not exist + * @param bool $deep If true, a path like foo[bar] will find deeper items + * + * @return mixed + * + * @throws \InvalidArgumentException + */ + public function get($path, $default = null, $deep = false) + { + if (!$deep || false === $pos = strpos($path, '[')) { + return array_key_exists($path, $this->parameters) ? $this->parameters[$path] : $default; + } + + $root = substr($path, 0, $pos); + if (!array_key_exists($root, $this->parameters)) { + return $default; + } + + $value = $this->parameters[$root]; + $currentKey = null; + for ($i = $pos, $c = strlen($path); $i < $c; ++$i) { + $char = $path[$i]; + + if ('[' === $char) { + if (null !== $currentKey) { + throw new \InvalidArgumentException(sprintf('Malformed path. Unexpected "[" at position %d.', $i)); + } + + $currentKey = ''; + } elseif (']' === $char) { + if (null === $currentKey) { + throw new \InvalidArgumentException(sprintf('Malformed path. Unexpected "]" at position %d.', $i)); + } + + if (!is_array($value) || !array_key_exists($currentKey, $value)) { + return $default; + } + + $value = $value[$currentKey]; + $currentKey = null; + } else { + if (null === $currentKey) { + throw new \InvalidArgumentException(sprintf('Malformed path. Unexpected "%s" at position %d.', $char, $i)); + } + + $currentKey .= $char; + } + } + + if (null !== $currentKey) { + throw new \InvalidArgumentException(sprintf('Malformed path. Path must end with "]".')); + } + + return $value; + } + + /** + * Sets a parameter by name. + * + * @param string $key The key + * @param mixed $value The value + */ + public function set($key, $value) + { + $this->parameters[$key] = $value; + } + + /** + * Returns true if the parameter is defined. + * + * @param string $key The key + * + * @return bool true if the parameter exists, false otherwise + */ + public function has($key) + { + return array_key_exists($key, $this->parameters); + } + + /** + * Removes a parameter. + * + * @param string $key The key + */ + public function remove($key) + { + unset($this->parameters[$key]); + } + + /** + * Returns the alphabetic characters of the parameter value. + * + * @param string $key The parameter key + * @param string $default The default value if the parameter key does not exist + * @param bool $deep If true, a path like foo[bar] will find deeper items + * + * @return string The filtered value + */ + public function getAlpha($key, $default = '', $deep = false) + { + return preg_replace('/[^[:alpha:]]/', '', $this->get($key, $default, $deep)); + } + + /** + * Returns the alphabetic characters and digits of the parameter value. + * + * @param string $key The parameter key + * @param string $default The default value if the parameter key does not exist + * @param bool $deep If true, a path like foo[bar] will find deeper items + * + * @return string The filtered value + */ + public function getAlnum($key, $default = '', $deep = false) + { + return preg_replace('/[^[:alnum:]]/', '', $this->get($key, $default, $deep)); + } + + /** + * Returns the digits of the parameter value. + * + * @param string $key The parameter key + * @param string $default The default value if the parameter key does not exist + * @param bool $deep If true, a path like foo[bar] will find deeper items + * + * @return string The filtered value + */ + public function getDigits($key, $default = '', $deep = false) + { + // we need to remove - and + because they're allowed in the filter + return str_replace(array('-', '+'), '', $this->filter($key, $default, $deep, FILTER_SANITIZE_NUMBER_INT)); + } + + /** + * Returns the parameter value converted to integer. + * + * @param string $key The parameter key + * @param int $default The default value if the parameter key does not exist + * @param bool $deep If true, a path like foo[bar] will find deeper items + * + * @return int The filtered value + */ + public function getInt($key, $default = 0, $deep = false) + { + return (int) $this->get($key, $default, $deep); + } + + /** + * Returns the parameter value converted to boolean. + * + * @param string $key The parameter key + * @param mixed $default The default value if the parameter key does not exist + * @param bool $deep If true, a path like foo[bar] will find deeper items + * + * @return bool The filtered value + */ + public function getBoolean($key, $default = false, $deep = false) + { + return $this->filter($key, $default, $deep, FILTER_VALIDATE_BOOLEAN); + } + + /** + * Filter key. + * + * @param string $key Key + * @param mixed $default Default = null + * @param bool $deep Default = false + * @param int $filter FILTER_* constant + * @param mixed $options Filter options + * + * @see http://php.net/manual/en/function.filter-var.php + * + * @return mixed + */ + public function filter($key, $default = null, $deep = false, $filter = FILTER_DEFAULT, $options = array()) + { + $value = $this->get($key, $default, $deep); + + // Always turn $options into an array - this allows filter_var option shortcuts. + if (!is_array($options) && $options) { + $options = array('flags' => $options); + } + + // Add a convenience check for arrays. + if (is_array($value) && !isset($options['flags'])) { + $options['flags'] = FILTER_REQUIRE_ARRAY; + } + + return filter_var($value, $filter, $options); + } + + /** + * Returns an iterator for parameters. + * + * @return \ArrayIterator An \ArrayIterator instance + */ + public function getIterator() + { + return new \ArrayIterator($this->parameters); + } + + /** + * Returns the number of parameters. + * + * @return int The number of parameters + */ + public function count() + { + return count($this->parameters); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/RedirectResponse.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/RedirectResponse.php new file mode 100644 index 0000000..8d26083 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/RedirectResponse.php @@ -0,0 +1,99 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation; + +/** + * RedirectResponse represents an HTTP response doing a redirect. + * + * @author Fabien Potencier + */ +class RedirectResponse extends Response +{ + protected $targetUrl; + + /** + * Creates a redirect response so that it conforms to the rules defined for a redirect status code. + * + * @param string $url The URL to redirect to. The URL should be a full URL, with schema etc., + * but practically every browser redirects on paths only as well + * @param int $status The status code (302 by default) + * @param array $headers The headers (Location is always set to the given URL) + * + * @throws \InvalidArgumentException + * + * @see http://tools.ietf.org/html/rfc2616#section-10.3 + */ + public function __construct($url, $status = 302, $headers = array()) + { + parent::__construct('', $status, $headers); + + $this->setTargetUrl($url); + + if (!$this->isRedirect()) { + throw new \InvalidArgumentException(sprintf('The HTTP status code is not a redirect ("%s" given).', $status)); + } + } + + /** + * {@inheritdoc} + */ + public static function create($url = '', $status = 302, $headers = array()) + { + return new static($url, $status, $headers); + } + + /** + * Returns the target URL. + * + * @return string target URL + */ + public function getTargetUrl() + { + return $this->targetUrl; + } + + /** + * Sets the redirect target of this response. + * + * @param string $url The URL to redirect to + * + * @return RedirectResponse The current response + * + * @throws \InvalidArgumentException + */ + public function setTargetUrl($url) + { + if (empty($url)) { + throw new \InvalidArgumentException('Cannot redirect to an empty URL.'); + } + + $this->targetUrl = $url; + + $this->setContent( + sprintf(' + + + + + + Redirecting to %1$s + + + Redirecting to %1$s. + +', htmlspecialchars($url, ENT_QUOTES, 'UTF-8'))); + + $this->headers->set('Location', $url); + + return $this; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Request.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Request.php new file mode 100644 index 0000000..dc32f4a --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Request.php @@ -0,0 +1,1958 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation; + +use Symfony\Component\HttpFoundation\Exception\ConflictingHeadersException; +use Symfony\Component\HttpFoundation\Session\SessionInterface; + +/** + * Request represents an HTTP request. + * + * The methods dealing with URL accept / return a raw path (% encoded): + * * getBasePath + * * getBaseUrl + * * getPathInfo + * * getRequestUri + * * getUri + * * getUriForPath + * + * @author Fabien Potencier + */ +class Request +{ + const HEADER_FORWARDED = 'forwarded'; + const HEADER_CLIENT_IP = 'client_ip'; + const HEADER_CLIENT_HOST = 'client_host'; + const HEADER_CLIENT_PROTO = 'client_proto'; + const HEADER_CLIENT_PORT = 'client_port'; + + const METHOD_HEAD = 'HEAD'; + const METHOD_GET = 'GET'; + const METHOD_POST = 'POST'; + const METHOD_PUT = 'PUT'; + const METHOD_PATCH = 'PATCH'; + const METHOD_DELETE = 'DELETE'; + const METHOD_PURGE = 'PURGE'; + const METHOD_OPTIONS = 'OPTIONS'; + const METHOD_TRACE = 'TRACE'; + const METHOD_CONNECT = 'CONNECT'; + + /** + * @var string[] + */ + protected static $trustedProxies = array(); + + /** + * @var string[] + */ + protected static $trustedHostPatterns = array(); + + /** + * @var string[] + */ + protected static $trustedHosts = array(); + + /** + * Names for headers that can be trusted when + * using trusted proxies. + * + * The FORWARDED header is the standard as of rfc7239. + * + * The other headers are non-standard, but widely used + * by popular reverse proxies (like Apache mod_proxy or Amazon EC2). + */ + protected static $trustedHeaders = array( + self::HEADER_FORWARDED => 'FORWARDED', + self::HEADER_CLIENT_IP => 'X_FORWARDED_FOR', + self::HEADER_CLIENT_HOST => 'X_FORWARDED_HOST', + self::HEADER_CLIENT_PROTO => 'X_FORWARDED_PROTO', + self::HEADER_CLIENT_PORT => 'X_FORWARDED_PORT', + ); + + protected static $httpMethodParameterOverride = false; + + /** + * Custom parameters. + * + * @var \Symfony\Component\HttpFoundation\ParameterBag + */ + public $attributes; + + /** + * Request body parameters ($_POST). + * + * @var \Symfony\Component\HttpFoundation\ParameterBag + */ + public $request; + + /** + * Query string parameters ($_GET). + * + * @var \Symfony\Component\HttpFoundation\ParameterBag + */ + public $query; + + /** + * Server and execution environment parameters ($_SERVER). + * + * @var \Symfony\Component\HttpFoundation\ServerBag + */ + public $server; + + /** + * Uploaded files ($_FILES). + * + * @var \Symfony\Component\HttpFoundation\FileBag + */ + public $files; + + /** + * Cookies ($_COOKIE). + * + * @var \Symfony\Component\HttpFoundation\ParameterBag + */ + public $cookies; + + /** + * Headers (taken from the $_SERVER). + * + * @var \Symfony\Component\HttpFoundation\HeaderBag + */ + public $headers; + + /** + * @var string + */ + protected $content; + + /** + * @var array + */ + protected $languages; + + /** + * @var array + */ + protected $charsets; + + /** + * @var array + */ + protected $encodings; + + /** + * @var array + */ + protected $acceptableContentTypes; + + /** + * @var string + */ + protected $pathInfo; + + /** + * @var string + */ + protected $requestUri; + + /** + * @var string + */ + protected $baseUrl; + + /** + * @var string + */ + protected $basePath; + + /** + * @var string + */ + protected $method; + + /** + * @var string + */ + protected $format; + + /** + * @var \Symfony\Component\HttpFoundation\Session\SessionInterface + */ + protected $session; + + /** + * @var string + */ + protected $locale; + + /** + * @var string + */ + protected $defaultLocale = 'en'; + + /** + * @var array + */ + protected static $formats; + + protected static $requestFactory; + + /** + * Constructor. + * + * @param array $query The GET parameters + * @param array $request The POST parameters + * @param array $attributes The request attributes (parameters parsed from the PATH_INFO, ...) + * @param array $cookies The COOKIE parameters + * @param array $files The FILES parameters + * @param array $server The SERVER parameters + * @param string|resource $content The raw body data + */ + public function __construct(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null) + { + $this->initialize($query, $request, $attributes, $cookies, $files, $server, $content); + } + + /** + * Sets the parameters for this request. + * + * This method also re-initializes all properties. + * + * @param array $query The GET parameters + * @param array $request The POST parameters + * @param array $attributes The request attributes (parameters parsed from the PATH_INFO, ...) + * @param array $cookies The COOKIE parameters + * @param array $files The FILES parameters + * @param array $server The SERVER parameters + * @param string|resource $content The raw body data + */ + public function initialize(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null) + { + $this->request = new ParameterBag($request); + $this->query = new ParameterBag($query); + $this->attributes = new ParameterBag($attributes); + $this->cookies = new ParameterBag($cookies); + $this->files = new FileBag($files); + $this->server = new ServerBag($server); + $this->headers = new HeaderBag($this->server->getHeaders()); + + $this->content = $content; + $this->languages = null; + $this->charsets = null; + $this->encodings = null; + $this->acceptableContentTypes = null; + $this->pathInfo = null; + $this->requestUri = null; + $this->baseUrl = null; + $this->basePath = null; + $this->method = null; + $this->format = null; + } + + /** + * Creates a new request with values from PHP's super globals. + * + * @return Request A new request + */ + public static function createFromGlobals() + { + // With the php's bug #66606, the php's built-in web server + // stores the Content-Type and Content-Length header values in + // HTTP_CONTENT_TYPE and HTTP_CONTENT_LENGTH fields. + $server = $_SERVER; + if ('cli-server' === PHP_SAPI) { + if (array_key_exists('HTTP_CONTENT_LENGTH', $_SERVER)) { + $server['CONTENT_LENGTH'] = $_SERVER['HTTP_CONTENT_LENGTH']; + } + if (array_key_exists('HTTP_CONTENT_TYPE', $_SERVER)) { + $server['CONTENT_TYPE'] = $_SERVER['HTTP_CONTENT_TYPE']; + } + } + + $request = self::createRequestFromFactory($_GET, $_POST, array(), $_COOKIE, $_FILES, $server); + + if (0 === strpos($request->headers->get('CONTENT_TYPE'), 'application/x-www-form-urlencoded') + && in_array(strtoupper($request->server->get('REQUEST_METHOD', 'GET')), array('PUT', 'DELETE', 'PATCH')) + ) { + parse_str($request->getContent(), $data); + $request->request = new ParameterBag($data); + } + + return $request; + } + + /** + * Creates a Request based on a given URI and configuration. + * + * The information contained in the URI always take precedence + * over the other information (server and parameters). + * + * @param string $uri The URI + * @param string $method The HTTP method + * @param array $parameters The query (GET) or request (POST) parameters + * @param array $cookies The request cookies ($_COOKIE) + * @param array $files The request files ($_FILES) + * @param array $server The server parameters ($_SERVER) + * @param string $content The raw body data + * + * @return Request A Request instance + */ + public static function create($uri, $method = 'GET', $parameters = array(), $cookies = array(), $files = array(), $server = array(), $content = null) + { + $server = array_replace(array( + 'SERVER_NAME' => 'localhost', + 'SERVER_PORT' => 80, + 'HTTP_HOST' => 'localhost', + 'HTTP_USER_AGENT' => 'Symfony/2.X', + 'HTTP_ACCEPT' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', + 'HTTP_ACCEPT_LANGUAGE' => 'en-us,en;q=0.5', + 'HTTP_ACCEPT_CHARSET' => 'ISO-8859-1,utf-8;q=0.7,*;q=0.7', + 'REMOTE_ADDR' => '127.0.0.1', + 'SCRIPT_NAME' => '', + 'SCRIPT_FILENAME' => '', + 'SERVER_PROTOCOL' => 'HTTP/1.1', + 'REQUEST_TIME' => time(), + ), $server); + + $server['PATH_INFO'] = ''; + $server['REQUEST_METHOD'] = strtoupper($method); + + $components = parse_url($uri); + if (isset($components['host'])) { + $server['SERVER_NAME'] = $components['host']; + $server['HTTP_HOST'] = $components['host']; + } + + if (isset($components['scheme'])) { + if ('https' === $components['scheme']) { + $server['HTTPS'] = 'on'; + $server['SERVER_PORT'] = 443; + } else { + unset($server['HTTPS']); + $server['SERVER_PORT'] = 80; + } + } + + if (isset($components['port'])) { + $server['SERVER_PORT'] = $components['port']; + $server['HTTP_HOST'] = $server['HTTP_HOST'].':'.$components['port']; + } + + if (isset($components['user'])) { + $server['PHP_AUTH_USER'] = $components['user']; + } + + if (isset($components['pass'])) { + $server['PHP_AUTH_PW'] = $components['pass']; + } + + if (!isset($components['path'])) { + $components['path'] = '/'; + } + + switch (strtoupper($method)) { + case 'POST': + case 'PUT': + case 'DELETE': + if (!isset($server['CONTENT_TYPE'])) { + $server['CONTENT_TYPE'] = 'application/x-www-form-urlencoded'; + } + // no break + case 'PATCH': + $request = $parameters; + $query = array(); + break; + default: + $request = array(); + $query = $parameters; + break; + } + + $queryString = ''; + if (isset($components['query'])) { + parse_str(html_entity_decode($components['query']), $qs); + + if ($query) { + $query = array_replace($qs, $query); + $queryString = http_build_query($query, '', '&'); + } else { + $query = $qs; + $queryString = $components['query']; + } + } elseif ($query) { + $queryString = http_build_query($query, '', '&'); + } + + $server['REQUEST_URI'] = $components['path'].('' !== $queryString ? '?'.$queryString : ''); + $server['QUERY_STRING'] = $queryString; + + return self::createRequestFromFactory($query, $request, array(), $cookies, $files, $server, $content); + } + + /** + * Sets a callable able to create a Request instance. + * + * This is mainly useful when you need to override the Request class + * to keep BC with an existing system. It should not be used for any + * other purpose. + * + * @param callable|null $callable A PHP callable + */ + public static function setFactory($callable) + { + self::$requestFactory = $callable; + } + + /** + * Clones a request and overrides some of its parameters. + * + * @param array $query The GET parameters + * @param array $request The POST parameters + * @param array $attributes The request attributes (parameters parsed from the PATH_INFO, ...) + * @param array $cookies The COOKIE parameters + * @param array $files The FILES parameters + * @param array $server The SERVER parameters + * + * @return Request The duplicated request + */ + public function duplicate(array $query = null, array $request = null, array $attributes = null, array $cookies = null, array $files = null, array $server = null) + { + $dup = clone $this; + if ($query !== null) { + $dup->query = new ParameterBag($query); + } + if ($request !== null) { + $dup->request = new ParameterBag($request); + } + if ($attributes !== null) { + $dup->attributes = new ParameterBag($attributes); + } + if ($cookies !== null) { + $dup->cookies = new ParameterBag($cookies); + } + if ($files !== null) { + $dup->files = new FileBag($files); + } + if ($server !== null) { + $dup->server = new ServerBag($server); + $dup->headers = new HeaderBag($dup->server->getHeaders()); + } + $dup->languages = null; + $dup->charsets = null; + $dup->encodings = null; + $dup->acceptableContentTypes = null; + $dup->pathInfo = null; + $dup->requestUri = null; + $dup->baseUrl = null; + $dup->basePath = null; + $dup->method = null; + $dup->format = null; + + if (!$dup->get('_format') && $this->get('_format')) { + $dup->attributes->set('_format', $this->get('_format')); + } + + if (!$dup->getRequestFormat(null)) { + $dup->setRequestFormat($this->getRequestFormat(null)); + } + + return $dup; + } + + /** + * Clones the current request. + * + * Note that the session is not cloned as duplicated requests + * are most of the time sub-requests of the main one. + */ + public function __clone() + { + $this->query = clone $this->query; + $this->request = clone $this->request; + $this->attributes = clone $this->attributes; + $this->cookies = clone $this->cookies; + $this->files = clone $this->files; + $this->server = clone $this->server; + $this->headers = clone $this->headers; + } + + /** + * Returns the request as a string. + * + * @return string The request + */ + public function __toString() + { + try { + $content = $this->getContent(); + } catch (\LogicException $e) { + return trigger_error($e, E_USER_ERROR); + } + + return + sprintf('%s %s %s', $this->getMethod(), $this->getRequestUri(), $this->server->get('SERVER_PROTOCOL'))."\r\n". + $this->headers."\r\n". + $content; + } + + /** + * Overrides the PHP global variables according to this request instance. + * + * It overrides $_GET, $_POST, $_REQUEST, $_SERVER, $_COOKIE. + * $_FILES is never overridden, see rfc1867 + */ + public function overrideGlobals() + { + $this->server->set('QUERY_STRING', static::normalizeQueryString(http_build_query($this->query->all(), null, '&'))); + + $_GET = $this->query->all(); + $_POST = $this->request->all(); + $_SERVER = $this->server->all(); + $_COOKIE = $this->cookies->all(); + + foreach ($this->headers->all() as $key => $value) { + $key = strtoupper(str_replace('-', '_', $key)); + if (in_array($key, array('CONTENT_TYPE', 'CONTENT_LENGTH'))) { + $_SERVER[$key] = implode(', ', $value); + } else { + $_SERVER['HTTP_'.$key] = implode(', ', $value); + } + } + + $request = array('g' => $_GET, 'p' => $_POST, 'c' => $_COOKIE); + + $requestOrder = ini_get('request_order') ?: ini_get('variables_order'); + $requestOrder = preg_replace('#[^cgp]#', '', strtolower($requestOrder)) ?: 'gp'; + + $_REQUEST = array(); + foreach (str_split($requestOrder) as $order) { + $_REQUEST = array_merge($_REQUEST, $request[$order]); + } + } + + /** + * Sets a list of trusted proxies. + * + * You should only list the reverse proxies that you manage directly. + * + * @param array $proxies A list of trusted proxies + */ + public static function setTrustedProxies(array $proxies) + { + self::$trustedProxies = $proxies; + } + + /** + * Gets the list of trusted proxies. + * + * @return array An array of trusted proxies + */ + public static function getTrustedProxies() + { + return self::$trustedProxies; + } + + /** + * Sets a list of trusted host patterns. + * + * You should only list the hosts you manage using regexs. + * + * @param array $hostPatterns A list of trusted host patterns + */ + public static function setTrustedHosts(array $hostPatterns) + { + self::$trustedHostPatterns = array_map(function ($hostPattern) { + return sprintf('#%s#i', $hostPattern); + }, $hostPatterns); + // we need to reset trusted hosts on trusted host patterns change + self::$trustedHosts = array(); + } + + /** + * Gets the list of trusted host patterns. + * + * @return array An array of trusted host patterns + */ + public static function getTrustedHosts() + { + return self::$trustedHostPatterns; + } + + /** + * Sets the name for trusted headers. + * + * The following header keys are supported: + * + * * Request::HEADER_CLIENT_IP: defaults to X-Forwarded-For (see getClientIp()) + * * Request::HEADER_CLIENT_HOST: defaults to X-Forwarded-Host (see getHost()) + * * Request::HEADER_CLIENT_PORT: defaults to X-Forwarded-Port (see getPort()) + * * Request::HEADER_CLIENT_PROTO: defaults to X-Forwarded-Proto (see getScheme() and isSecure()) + * + * Setting an empty value allows to disable the trusted header for the given key. + * + * @param string $key The header key + * @param string $value The header name + * + * @throws \InvalidArgumentException + */ + public static function setTrustedHeaderName($key, $value) + { + if (!array_key_exists($key, self::$trustedHeaders)) { + throw new \InvalidArgumentException(sprintf('Unable to set the trusted header name for key "%s".', $key)); + } + + self::$trustedHeaders[$key] = $value; + } + + /** + * Gets the trusted proxy header name. + * + * @param string $key The header key + * + * @return string The header name + * + * @throws \InvalidArgumentException + */ + public static function getTrustedHeaderName($key) + { + if (!array_key_exists($key, self::$trustedHeaders)) { + throw new \InvalidArgumentException(sprintf('Unable to get the trusted header name for key "%s".', $key)); + } + + return self::$trustedHeaders[$key]; + } + + /** + * Normalizes a query string. + * + * It builds a normalized query string, where keys/value pairs are alphabetized, + * have consistent escaping and unneeded delimiters are removed. + * + * @param string $qs Query string + * + * @return string A normalized query string for the Request + */ + public static function normalizeQueryString($qs) + { + if ('' == $qs) { + return ''; + } + + $parts = array(); + $order = array(); + + foreach (explode('&', $qs) as $param) { + if ('' === $param || '=' === $param[0]) { + // Ignore useless delimiters, e.g. "x=y&". + // Also ignore pairs with empty key, even if there was a value, e.g. "=value", as such nameless values cannot be retrieved anyway. + // PHP also does not include them when building _GET. + continue; + } + + $keyValuePair = explode('=', $param, 2); + + // GET parameters, that are submitted from a HTML form, encode spaces as "+" by default (as defined in enctype application/x-www-form-urlencoded). + // PHP also converts "+" to spaces when filling the global _GET or when using the function parse_str. This is why we use urldecode and then normalize to + // RFC 3986 with rawurlencode. + $parts[] = isset($keyValuePair[1]) ? + rawurlencode(urldecode($keyValuePair[0])).'='.rawurlencode(urldecode($keyValuePair[1])) : + rawurlencode(urldecode($keyValuePair[0])); + $order[] = urldecode($keyValuePair[0]); + } + + array_multisort($order, SORT_ASC, $parts); + + return implode('&', $parts); + } + + /** + * Enables support for the _method request parameter to determine the intended HTTP method. + * + * Be warned that enabling this feature might lead to CSRF issues in your code. + * Check that you are using CSRF tokens when required. + * If the HTTP method parameter override is enabled, an html-form with method "POST" can be altered + * and used to send a "PUT" or "DELETE" request via the _method request parameter. + * If these methods are not protected against CSRF, this presents a possible vulnerability. + * + * The HTTP method can only be overridden when the real HTTP method is POST. + */ + public static function enableHttpMethodParameterOverride() + { + self::$httpMethodParameterOverride = true; + } + + /** + * Checks whether support for the _method request parameter is enabled. + * + * @return bool True when the _method request parameter is enabled, false otherwise + */ + public static function getHttpMethodParameterOverride() + { + return self::$httpMethodParameterOverride; + } + + /** + * Gets a "parameter" value. + * + * This method is mainly useful for libraries that want to provide some flexibility. + * + * Order of precedence: GET, PATH, POST + * + * Avoid using this method in controllers: + * + * * slow + * * prefer to get from a "named" source + * + * It is better to explicitly get request parameters from the appropriate + * public property instead (query, attributes, request). + * + * @param string $key the key + * @param mixed $default the default value if the parameter key does not exist + * @param bool $deep is parameter deep in multidimensional array + * + * @return mixed + */ + public function get($key, $default = null, $deep = false) + { + if ($this !== $result = $this->query->get($key, $this, $deep)) { + return $result; + } + + if ($this !== $result = $this->attributes->get($key, $this, $deep)) { + return $result; + } + + if ($this !== $result = $this->request->get($key, $this, $deep)) { + return $result; + } + + return $default; + } + + /** + * Gets the Session. + * + * @return SessionInterface|null The session + */ + public function getSession() + { + return $this->session; + } + + /** + * Whether the request contains a Session which was started in one of the + * previous requests. + * + * @return bool + */ + public function hasPreviousSession() + { + // the check for $this->session avoids malicious users trying to fake a session cookie with proper name + return $this->hasSession() && $this->cookies->has($this->session->getName()); + } + + /** + * Whether the request contains a Session object. + * + * This method does not give any information about the state of the session object, + * like whether the session is started or not. It is just a way to check if this Request + * is associated with a Session instance. + * + * @return bool true when the Request contains a Session object, false otherwise + */ + public function hasSession() + { + return null !== $this->session; + } + + /** + * Sets the Session. + * + * @param SessionInterface $session The Session + */ + public function setSession(SessionInterface $session) + { + $this->session = $session; + } + + /** + * Returns the client IP addresses. + * + * In the returned array the most trusted IP address is first, and the + * least trusted one last. The "real" client IP address is the last one, + * but this is also the least trusted one. Trusted proxies are stripped. + * + * Use this method carefully; you should use getClientIp() instead. + * + * @return array The client IP addresses + * + * @see getClientIp() + */ + public function getClientIps() + { + $clientIps = array(); + $ip = $this->server->get('REMOTE_ADDR'); + + if (!$this->isFromTrustedProxy()) { + return array($ip); + } + + $hasTrustedForwardedHeader = self::$trustedHeaders[self::HEADER_FORWARDED] && $this->headers->has(self::$trustedHeaders[self::HEADER_FORWARDED]); + $hasTrustedClientIpHeader = self::$trustedHeaders[self::HEADER_CLIENT_IP] && $this->headers->has(self::$trustedHeaders[self::HEADER_CLIENT_IP]); + + if ($hasTrustedForwardedHeader) { + $forwardedHeader = $this->headers->get(self::$trustedHeaders[self::HEADER_FORWARDED]); + preg_match_all('{(for)=("?\[?)([a-z0-9\.:_\-/]*)}', $forwardedHeader, $matches); + $forwardedClientIps = $matches[3]; + + $forwardedClientIps = $this->normalizeAndFilterClientIps($forwardedClientIps, $ip); + $clientIps = $forwardedClientIps; + } + + if ($hasTrustedClientIpHeader) { + $xForwardedForClientIps = array_map('trim', explode(',', $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_IP]))); + + $xForwardedForClientIps = $this->normalizeAndFilterClientIps($xForwardedForClientIps, $ip); + $clientIps = $xForwardedForClientIps; + } + + if ($hasTrustedForwardedHeader && $hasTrustedClientIpHeader && $forwardedClientIps !== $xForwardedForClientIps) { + throw new ConflictingHeadersException('The request has both a trusted Forwarded header and a trusted Client IP header, conflicting with each other with regards to the originating IP addresses of the request. This is the result of a misconfiguration. You should either configure your proxy only to send one of these headers, or configure Symfony to distrust one of them.'); + } + + if (!$hasTrustedForwardedHeader && !$hasTrustedClientIpHeader) { + return $this->normalizeAndFilterClientIps(array(), $ip); + } + + return $clientIps; + } + + /** + * Returns the client IP address. + * + * This method can read the client IP address from the "X-Forwarded-For" header + * when trusted proxies were set via "setTrustedProxies()". The "X-Forwarded-For" + * header value is a comma+space separated list of IP addresses, the left-most + * being the original client, and each successive proxy that passed the request + * adding the IP address where it received the request from. + * + * If your reverse proxy uses a different header name than "X-Forwarded-For", + * ("Client-Ip" for instance), configure it via "setTrustedHeaderName()" with + * the "client-ip" key. + * + * @return string The client IP address + * + * @see getClientIps() + * @see http://en.wikipedia.org/wiki/X-Forwarded-For + */ + public function getClientIp() + { + $ipAddresses = $this->getClientIps(); + + return $ipAddresses[0]; + } + + /** + * Returns current script name. + * + * @return string + */ + public function getScriptName() + { + return $this->server->get('SCRIPT_NAME', $this->server->get('ORIG_SCRIPT_NAME', '')); + } + + /** + * Returns the path being requested relative to the executed script. + * + * The path info always starts with a /. + * + * Suppose this request is instantiated from /mysite on localhost: + * + * * http://localhost/mysite returns an empty string + * * http://localhost/mysite/about returns '/about' + * * http://localhost/mysite/enco%20ded returns '/enco%20ded' + * * http://localhost/mysite/about?var=1 returns '/about' + * + * @return string The raw path (i.e. not urldecoded) + */ + public function getPathInfo() + { + if (null === $this->pathInfo) { + $this->pathInfo = $this->preparePathInfo(); + } + + return $this->pathInfo; + } + + /** + * Returns the root path from which this request is executed. + * + * Suppose that an index.php file instantiates this request object: + * + * * http://localhost/index.php returns an empty string + * * http://localhost/index.php/page returns an empty string + * * http://localhost/web/index.php returns '/web' + * * http://localhost/we%20b/index.php returns '/we%20b' + * + * @return string The raw path (i.e. not urldecoded) + */ + public function getBasePath() + { + if (null === $this->basePath) { + $this->basePath = $this->prepareBasePath(); + } + + return $this->basePath; + } + + /** + * Returns the root URL from which this request is executed. + * + * The base URL never ends with a /. + * + * This is similar to getBasePath(), except that it also includes the + * script filename (e.g. index.php) if one exists. + * + * @return string The raw URL (i.e. not urldecoded) + */ + public function getBaseUrl() + { + if (null === $this->baseUrl) { + $this->baseUrl = $this->prepareBaseUrl(); + } + + return $this->baseUrl; + } + + /** + * Gets the request's scheme. + * + * @return string + */ + public function getScheme() + { + return $this->isSecure() ? 'https' : 'http'; + } + + /** + * Returns the port on which the request is made. + * + * This method can read the client port from the "X-Forwarded-Port" header + * when trusted proxies were set via "setTrustedProxies()". + * + * The "X-Forwarded-Port" header must contain the client port. + * + * If your reverse proxy uses a different header name than "X-Forwarded-Port", + * configure it via "setTrustedHeaderName()" with the "client-port" key. + * + * @return string + */ + public function getPort() + { + if ($this->isFromTrustedProxy()) { + if (self::$trustedHeaders[self::HEADER_CLIENT_PORT] && $port = $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_PORT])) { + return $port; + } + + if (self::$trustedHeaders[self::HEADER_CLIENT_PROTO] && 'https' === $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_PROTO], 'http')) { + return 443; + } + } + + if ($host = $this->headers->get('HOST')) { + if ($host[0] === '[') { + $pos = strpos($host, ':', strrpos($host, ']')); + } else { + $pos = strrpos($host, ':'); + } + + if (false !== $pos) { + return (int) substr($host, $pos + 1); + } + + return 'https' === $this->getScheme() ? 443 : 80; + } + + return $this->server->get('SERVER_PORT'); + } + + /** + * Returns the user. + * + * @return string|null + */ + public function getUser() + { + return $this->headers->get('PHP_AUTH_USER'); + } + + /** + * Returns the password. + * + * @return string|null + */ + public function getPassword() + { + return $this->headers->get('PHP_AUTH_PW'); + } + + /** + * Gets the user info. + * + * @return string A user name and, optionally, scheme-specific information about how to gain authorization to access the server + */ + public function getUserInfo() + { + $userinfo = $this->getUser(); + + $pass = $this->getPassword(); + if ('' != $pass) { + $userinfo .= ":$pass"; + } + + return $userinfo; + } + + /** + * Returns the HTTP host being requested. + * + * The port name will be appended to the host if it's non-standard. + * + * @return string + */ + public function getHttpHost() + { + $scheme = $this->getScheme(); + $port = $this->getPort(); + + if (('http' == $scheme && $port == 80) || ('https' == $scheme && $port == 443)) { + return $this->getHost(); + } + + return $this->getHost().':'.$port; + } + + /** + * Returns the requested URI (path and query string). + * + * @return string The raw URI (i.e. not URI decoded) + */ + public function getRequestUri() + { + if (null === $this->requestUri) { + $this->requestUri = $this->prepareRequestUri(); + } + + return $this->requestUri; + } + + /** + * Gets the scheme and HTTP host. + * + * If the URL was called with basic authentication, the user + * and the password are not added to the generated string. + * + * @return string The scheme and HTTP host + */ + public function getSchemeAndHttpHost() + { + return $this->getScheme().'://'.$this->getHttpHost(); + } + + /** + * Generates a normalized URI (URL) for the Request. + * + * @return string A normalized URI (URL) for the Request + * + * @see getQueryString() + */ + public function getUri() + { + if (null !== $qs = $this->getQueryString()) { + $qs = '?'.$qs; + } + + return $this->getSchemeAndHttpHost().$this->getBaseUrl().$this->getPathInfo().$qs; + } + + /** + * Generates a normalized URI for the given path. + * + * @param string $path A path to use instead of the current one + * + * @return string The normalized URI for the path + */ + public function getUriForPath($path) + { + return $this->getSchemeAndHttpHost().$this->getBaseUrl().$path; + } + + /** + * Returns the path as relative reference from the current Request path. + * + * Only the URIs path component (no schema, host etc.) is relevant and must be given. + * Both paths must be absolute and not contain relative parts. + * Relative URLs from one resource to another are useful when generating self-contained downloadable document archives. + * Furthermore, they can be used to reduce the link size in documents. + * + * Example target paths, given a base path of "/a/b/c/d": + * - "/a/b/c/d" -> "" + * - "/a/b/c/" -> "./" + * - "/a/b/" -> "../" + * - "/a/b/c/other" -> "other" + * - "/a/x/y" -> "../../x/y" + * + * @param string $path The target path + * + * @return string The relative target path + */ + public function getRelativeUriForPath($path) + { + // be sure that we are dealing with an absolute path + if (!isset($path[0]) || '/' !== $path[0]) { + return $path; + } + + if ($path === $basePath = $this->getPathInfo()) { + return ''; + } + + $sourceDirs = explode('/', isset($basePath[0]) && '/' === $basePath[0] ? substr($basePath, 1) : $basePath); + $targetDirs = explode('/', isset($path[0]) && '/' === $path[0] ? substr($path, 1) : $path); + array_pop($sourceDirs); + $targetFile = array_pop($targetDirs); + + foreach ($sourceDirs as $i => $dir) { + if (isset($targetDirs[$i]) && $dir === $targetDirs[$i]) { + unset($sourceDirs[$i], $targetDirs[$i]); + } else { + break; + } + } + + $targetDirs[] = $targetFile; + $path = str_repeat('../', count($sourceDirs)).implode('/', $targetDirs); + + // A reference to the same base directory or an empty subdirectory must be prefixed with "./". + // This also applies to a segment with a colon character (e.g., "file:colon") that cannot be used + // as the first segment of a relative-path reference, as it would be mistaken for a scheme name + // (see http://tools.ietf.org/html/rfc3986#section-4.2). + return !isset($path[0]) || '/' === $path[0] + || false !== ($colonPos = strpos($path, ':')) && ($colonPos < ($slashPos = strpos($path, '/')) || false === $slashPos) + ? "./$path" : $path; + } + + /** + * Generates the normalized query string for the Request. + * + * It builds a normalized query string, where keys/value pairs are alphabetized + * and have consistent escaping. + * + * @return string|null A normalized query string for the Request + */ + public function getQueryString() + { + $qs = static::normalizeQueryString($this->server->get('QUERY_STRING')); + + return '' === $qs ? null : $qs; + } + + /** + * Checks whether the request is secure or not. + * + * This method can read the client protocol from the "X-Forwarded-Proto" header + * when trusted proxies were set via "setTrustedProxies()". + * + * The "X-Forwarded-Proto" header must contain the protocol: "https" or "http". + * + * If your reverse proxy uses a different header name than "X-Forwarded-Proto" + * ("SSL_HTTPS" for instance), configure it via "setTrustedHeaderName()" with + * the "client-proto" key. + * + * @return bool + */ + public function isSecure() + { + if ($this->isFromTrustedProxy() && self::$trustedHeaders[self::HEADER_CLIENT_PROTO] && $proto = $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_PROTO])) { + return in_array(strtolower(current(explode(',', $proto))), array('https', 'on', 'ssl', '1')); + } + + $https = $this->server->get('HTTPS'); + + return !empty($https) && 'off' !== strtolower($https); + } + + /** + * Returns the host name. + * + * This method can read the client host name from the "X-Forwarded-Host" header + * when trusted proxies were set via "setTrustedProxies()". + * + * The "X-Forwarded-Host" header must contain the client host name. + * + * If your reverse proxy uses a different header name than "X-Forwarded-Host", + * configure it via "setTrustedHeaderName()" with the "client-host" key. + * + * @return string + * + * @throws \UnexpectedValueException when the host name is invalid + */ + public function getHost() + { + if ($this->isFromTrustedProxy() && self::$trustedHeaders[self::HEADER_CLIENT_HOST] && $host = $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_HOST])) { + $elements = explode(',', $host); + + $host = $elements[count($elements) - 1]; + } elseif (!$host = $this->headers->get('HOST')) { + if (!$host = $this->server->get('SERVER_NAME')) { + $host = $this->server->get('SERVER_ADDR', ''); + } + } + + // trim and remove port number from host + // host is lowercase as per RFC 952/2181 + $host = strtolower(preg_replace('/:\d+$/', '', trim($host))); + + // as the host can come from the user (HTTP_HOST and depending on the configuration, SERVER_NAME too can come from the user) + // check that it does not contain forbidden characters (see RFC 952 and RFC 2181) + // use preg_replace() instead of preg_match() to prevent DoS attacks with long host names + if ($host && '' !== preg_replace('/(?:^\[)?[a-zA-Z0-9-:\]_]+\.?/', '', $host)) { + throw new \UnexpectedValueException(sprintf('Invalid Host "%s"', $host)); + } + + if (count(self::$trustedHostPatterns) > 0) { + // to avoid host header injection attacks, you should provide a list of trusted host patterns + + if (in_array($host, self::$trustedHosts)) { + return $host; + } + + foreach (self::$trustedHostPatterns as $pattern) { + if (preg_match($pattern, $host)) { + self::$trustedHosts[] = $host; + + return $host; + } + } + + throw new \UnexpectedValueException(sprintf('Untrusted Host "%s"', $host)); + } + + return $host; + } + + /** + * Sets the request method. + * + * @param string $method + */ + public function setMethod($method) + { + $this->method = null; + $this->server->set('REQUEST_METHOD', $method); + } + + /** + * Gets the request "intended" method. + * + * If the X-HTTP-Method-Override header is set, and if the method is a POST, + * then it is used to determine the "real" intended HTTP method. + * + * The _method request parameter can also be used to determine the HTTP method, + * but only if enableHttpMethodParameterOverride() has been called. + * + * The method is always an uppercased string. + * + * @return string The request method + * + * @see getRealMethod() + */ + public function getMethod() + { + if (null === $this->method) { + $this->method = strtoupper($this->server->get('REQUEST_METHOD', 'GET')); + + if ('POST' === $this->method) { + if ($method = $this->headers->get('X-HTTP-METHOD-OVERRIDE')) { + $this->method = strtoupper($method); + } elseif (self::$httpMethodParameterOverride) { + $this->method = strtoupper($this->request->get('_method', $this->query->get('_method', 'POST'))); + } + } + } + + return $this->method; + } + + /** + * Gets the "real" request method. + * + * @return string The request method + * + * @see getMethod() + */ + public function getRealMethod() + { + return strtoupper($this->server->get('REQUEST_METHOD', 'GET')); + } + + /** + * Gets the mime type associated with the format. + * + * @param string $format The format + * + * @return string The associated mime type (null if not found) + */ + public function getMimeType($format) + { + if (null === static::$formats) { + static::initializeFormats(); + } + + return isset(static::$formats[$format]) ? static::$formats[$format][0] : null; + } + + /** + * Gets the format associated with the mime type. + * + * @param string $mimeType The associated mime type + * + * @return string|null The format (null if not found) + */ + public function getFormat($mimeType) + { + $canonicalMimeType = null; + if (false !== $pos = strpos($mimeType, ';')) { + $canonicalMimeType = substr($mimeType, 0, $pos); + } + + if (null === static::$formats) { + static::initializeFormats(); + } + + foreach (static::$formats as $format => $mimeTypes) { + if (in_array($mimeType, (array) $mimeTypes)) { + return $format; + } + if (null !== $canonicalMimeType && in_array($canonicalMimeType, (array) $mimeTypes)) { + return $format; + } + } + } + + /** + * Associates a format with mime types. + * + * @param string $format The format + * @param string|array $mimeTypes The associated mime types (the preferred one must be the first as it will be used as the content type) + */ + public function setFormat($format, $mimeTypes) + { + if (null === static::$formats) { + static::initializeFormats(); + } + + static::$formats[$format] = is_array($mimeTypes) ? $mimeTypes : array($mimeTypes); + } + + /** + * Gets the request format. + * + * Here is the process to determine the format: + * + * * format defined by the user (with setRequestFormat()) + * * _format request parameter + * * $default + * + * @param string $default The default format + * + * @return string The request format + */ + public function getRequestFormat($default = 'html') + { + if (null === $this->format) { + $this->format = $this->get('_format', $default); + } + + return $this->format; + } + + /** + * Sets the request format. + * + * @param string $format The request format + */ + public function setRequestFormat($format) + { + $this->format = $format; + } + + /** + * Gets the format associated with the request. + * + * @return string|null The format (null if no content type is present) + */ + public function getContentType() + { + return $this->getFormat($this->headers->get('CONTENT_TYPE')); + } + + /** + * Sets the default locale. + * + * @param string $locale + */ + public function setDefaultLocale($locale) + { + $this->defaultLocale = $locale; + + if (null === $this->locale) { + $this->setPhpDefaultLocale($locale); + } + } + + /** + * Get the default locale. + * + * @return string + */ + public function getDefaultLocale() + { + return $this->defaultLocale; + } + + /** + * Sets the locale. + * + * @param string $locale + */ + public function setLocale($locale) + { + $this->setPhpDefaultLocale($this->locale = $locale); + } + + /** + * Get the locale. + * + * @return string + */ + public function getLocale() + { + return null === $this->locale ? $this->defaultLocale : $this->locale; + } + + /** + * Checks if the request method is of specified type. + * + * @param string $method Uppercase request method (GET, POST etc) + * + * @return bool + */ + public function isMethod($method) + { + return $this->getMethod() === strtoupper($method); + } + + /** + * Checks whether the method is safe or not. + * + * @return bool + */ + public function isMethodSafe() + { + return in_array($this->getMethod(), array('GET', 'HEAD', 'OPTIONS', 'TRACE')); + } + + /** + * Returns the request body content. + * + * @param bool $asResource If true, a resource will be returned + * + * @return string|resource The request body content or a resource to read the body stream + * + * @throws \LogicException + */ + public function getContent($asResource = false) + { + $currentContentIsResource = is_resource($this->content); + if (PHP_VERSION_ID < 50600 && false === $this->content) { + throw new \LogicException('getContent() can only be called once when using the resource return type and PHP below 5.6.'); + } + + if (true === $asResource) { + if ($currentContentIsResource) { + rewind($this->content); + + return $this->content; + } + + // Content passed in parameter (test) + if (is_string($this->content)) { + $resource = fopen('php://temp', 'r+'); + fwrite($resource, $this->content); + rewind($resource); + + return $resource; + } + + $this->content = false; + + return fopen('php://input', 'rb'); + } + + if ($currentContentIsResource) { + rewind($this->content); + + return stream_get_contents($this->content); + } + + if (null === $this->content || false === $this->content) { + $this->content = file_get_contents('php://input'); + } + + return $this->content; + } + + /** + * Gets the Etags. + * + * @return array The entity tags + */ + public function getETags() + { + return preg_split('/\s*,\s*/', $this->headers->get('if_none_match'), null, PREG_SPLIT_NO_EMPTY); + } + + /** + * @return bool + */ + public function isNoCache() + { + return $this->headers->hasCacheControlDirective('no-cache') || 'no-cache' == $this->headers->get('Pragma'); + } + + /** + * Returns the preferred language. + * + * @param array $locales An array of ordered available locales + * + * @return string|null The preferred locale + */ + public function getPreferredLanguage(array $locales = null) + { + $preferredLanguages = $this->getLanguages(); + + if (empty($locales)) { + return isset($preferredLanguages[0]) ? $preferredLanguages[0] : null; + } + + if (!$preferredLanguages) { + return $locales[0]; + } + + $extendedPreferredLanguages = array(); + foreach ($preferredLanguages as $language) { + $extendedPreferredLanguages[] = $language; + if (false !== $position = strpos($language, '_')) { + $superLanguage = substr($language, 0, $position); + if (!in_array($superLanguage, $preferredLanguages)) { + $extendedPreferredLanguages[] = $superLanguage; + } + } + } + + $preferredLanguages = array_values(array_intersect($extendedPreferredLanguages, $locales)); + + return isset($preferredLanguages[0]) ? $preferredLanguages[0] : $locales[0]; + } + + /** + * Gets a list of languages acceptable by the client browser. + * + * @return array Languages ordered in the user browser preferences + */ + public function getLanguages() + { + if (null !== $this->languages) { + return $this->languages; + } + + $languages = AcceptHeader::fromString($this->headers->get('Accept-Language'))->all(); + $this->languages = array(); + foreach ($languages as $lang => $acceptHeaderItem) { + if (false !== strpos($lang, '-')) { + $codes = explode('-', $lang); + if ('i' === $codes[0]) { + // Language not listed in ISO 639 that are not variants + // of any listed language, which can be registered with the + // i-prefix, such as i-cherokee + if (count($codes) > 1) { + $lang = $codes[1]; + } + } else { + for ($i = 0, $max = count($codes); $i < $max; ++$i) { + if ($i === 0) { + $lang = strtolower($codes[0]); + } else { + $lang .= '_'.strtoupper($codes[$i]); + } + } + } + } + + $this->languages[] = $lang; + } + + return $this->languages; + } + + /** + * Gets a list of charsets acceptable by the client browser. + * + * @return array List of charsets in preferable order + */ + public function getCharsets() + { + if (null !== $this->charsets) { + return $this->charsets; + } + + return $this->charsets = array_keys(AcceptHeader::fromString($this->headers->get('Accept-Charset'))->all()); + } + + /** + * Gets a list of encodings acceptable by the client browser. + * + * @return array List of encodings in preferable order + */ + public function getEncodings() + { + if (null !== $this->encodings) { + return $this->encodings; + } + + return $this->encodings = array_keys(AcceptHeader::fromString($this->headers->get('Accept-Encoding'))->all()); + } + + /** + * Gets a list of content types acceptable by the client browser. + * + * @return array List of content types in preferable order + */ + public function getAcceptableContentTypes() + { + if (null !== $this->acceptableContentTypes) { + return $this->acceptableContentTypes; + } + + return $this->acceptableContentTypes = array_keys(AcceptHeader::fromString($this->headers->get('Accept'))->all()); + } + + /** + * Returns true if the request is a XMLHttpRequest. + * + * It works if your JavaScript library sets an X-Requested-With HTTP header. + * It is known to work with common JavaScript frameworks: + * + * @link http://en.wikipedia.org/wiki/List_of_Ajax_frameworks#JavaScript + * + * @return bool true if the request is an XMLHttpRequest, false otherwise + */ + public function isXmlHttpRequest() + { + return 'XMLHttpRequest' == $this->headers->get('X-Requested-With'); + } + + /* + * The following methods are derived from code of the Zend Framework (1.10dev - 2010-01-24) + * + * Code subject to the new BSD license (http://framework.zend.com/license/new-bsd). + * + * Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + */ + + protected function prepareRequestUri() + { + $requestUri = ''; + + if ($this->headers->has('X_ORIGINAL_URL')) { + // IIS with Microsoft Rewrite Module + $requestUri = $this->headers->get('X_ORIGINAL_URL'); + $this->headers->remove('X_ORIGINAL_URL'); + $this->server->remove('HTTP_X_ORIGINAL_URL'); + $this->server->remove('UNENCODED_URL'); + $this->server->remove('IIS_WasUrlRewritten'); + } elseif ($this->headers->has('X_REWRITE_URL')) { + // IIS with ISAPI_Rewrite + $requestUri = $this->headers->get('X_REWRITE_URL'); + $this->headers->remove('X_REWRITE_URL'); + } elseif ($this->server->get('IIS_WasUrlRewritten') == '1' && $this->server->get('UNENCODED_URL') != '') { + // IIS7 with URL Rewrite: make sure we get the unencoded URL (double slash problem) + $requestUri = $this->server->get('UNENCODED_URL'); + $this->server->remove('UNENCODED_URL'); + $this->server->remove('IIS_WasUrlRewritten'); + } elseif ($this->server->has('REQUEST_URI')) { + $requestUri = $this->server->get('REQUEST_URI'); + // HTTP proxy reqs setup request URI with scheme and host [and port] + the URL path, only use URL path + $schemeAndHttpHost = $this->getSchemeAndHttpHost(); + if (strpos($requestUri, $schemeAndHttpHost) === 0) { + $requestUri = substr($requestUri, strlen($schemeAndHttpHost)); + } + } elseif ($this->server->has('ORIG_PATH_INFO')) { + // IIS 5.0, PHP as CGI + $requestUri = $this->server->get('ORIG_PATH_INFO'); + if ('' != $this->server->get('QUERY_STRING')) { + $requestUri .= '?'.$this->server->get('QUERY_STRING'); + } + $this->server->remove('ORIG_PATH_INFO'); + } + + // normalize the request URI to ease creating sub-requests from this request + $this->server->set('REQUEST_URI', $requestUri); + + return $requestUri; + } + + /** + * Prepares the base URL. + * + * @return string + */ + protected function prepareBaseUrl() + { + $filename = basename($this->server->get('SCRIPT_FILENAME')); + + if (basename($this->server->get('SCRIPT_NAME')) === $filename) { + $baseUrl = $this->server->get('SCRIPT_NAME'); + } elseif (basename($this->server->get('PHP_SELF')) === $filename) { + $baseUrl = $this->server->get('PHP_SELF'); + } elseif (basename($this->server->get('ORIG_SCRIPT_NAME')) === $filename) { + $baseUrl = $this->server->get('ORIG_SCRIPT_NAME'); // 1and1 shared hosting compatibility + } else { + // Backtrack up the script_filename to find the portion matching + // php_self + $path = $this->server->get('PHP_SELF', ''); + $file = $this->server->get('SCRIPT_FILENAME', ''); + $segs = explode('/', trim($file, '/')); + $segs = array_reverse($segs); + $index = 0; + $last = count($segs); + $baseUrl = ''; + do { + $seg = $segs[$index]; + $baseUrl = '/'.$seg.$baseUrl; + ++$index; + } while ($last > $index && (false !== $pos = strpos($path, $baseUrl)) && 0 != $pos); + } + + // Does the baseUrl have anything in common with the request_uri? + $requestUri = $this->getRequestUri(); + + if ($baseUrl && false !== $prefix = $this->getUrlencodedPrefix($requestUri, $baseUrl)) { + // full $baseUrl matches + return $prefix; + } + + if ($baseUrl && false !== $prefix = $this->getUrlencodedPrefix($requestUri, rtrim(dirname($baseUrl), '/'.DIRECTORY_SEPARATOR).'/')) { + // directory portion of $baseUrl matches + return rtrim($prefix, '/'.DIRECTORY_SEPARATOR); + } + + $truncatedRequestUri = $requestUri; + if (false !== $pos = strpos($requestUri, '?')) { + $truncatedRequestUri = substr($requestUri, 0, $pos); + } + + $basename = basename($baseUrl); + if (empty($basename) || !strpos(rawurldecode($truncatedRequestUri), $basename)) { + // no match whatsoever; set it blank + return ''; + } + + // If using mod_rewrite or ISAPI_Rewrite strip the script filename + // out of baseUrl. $pos !== 0 makes sure it is not matching a value + // from PATH_INFO or QUERY_STRING + if (strlen($requestUri) >= strlen($baseUrl) && (false !== $pos = strpos($requestUri, $baseUrl)) && $pos !== 0) { + $baseUrl = substr($requestUri, 0, $pos + strlen($baseUrl)); + } + + return rtrim($baseUrl, '/'.DIRECTORY_SEPARATOR); + } + + /** + * Prepares the base path. + * + * @return string base path + */ + protected function prepareBasePath() + { + $filename = basename($this->server->get('SCRIPT_FILENAME')); + $baseUrl = $this->getBaseUrl(); + if (empty($baseUrl)) { + return ''; + } + + if (basename($baseUrl) === $filename) { + $basePath = dirname($baseUrl); + } else { + $basePath = $baseUrl; + } + + if ('\\' === DIRECTORY_SEPARATOR) { + $basePath = str_replace('\\', '/', $basePath); + } + + return rtrim($basePath, '/'); + } + + /** + * Prepares the path info. + * + * @return string path info + */ + protected function preparePathInfo() + { + $baseUrl = $this->getBaseUrl(); + + if (null === ($requestUri = $this->getRequestUri())) { + return '/'; + } + + // Remove the query string from REQUEST_URI + if ($pos = strpos($requestUri, '?')) { + $requestUri = substr($requestUri, 0, $pos); + } + + $pathInfo = substr($requestUri, strlen($baseUrl)); + if (null !== $baseUrl && (false === $pathInfo || '' === $pathInfo)) { + // If substr() returns false then PATH_INFO is set to an empty string + return '/'; + } elseif (null === $baseUrl) { + return $requestUri; + } + + return (string) $pathInfo; + } + + /** + * Initializes HTTP request formats. + */ + protected static function initializeFormats() + { + static::$formats = array( + 'html' => array('text/html', 'application/xhtml+xml'), + 'txt' => array('text/plain'), + 'js' => array('application/javascript', 'application/x-javascript', 'text/javascript'), + 'css' => array('text/css'), + 'json' => array('application/json', 'application/x-json'), + 'xml' => array('text/xml', 'application/xml', 'application/x-xml'), + 'rdf' => array('application/rdf+xml'), + 'atom' => array('application/atom+xml'), + 'rss' => array('application/rss+xml'), + 'form' => array('application/x-www-form-urlencoded'), + ); + } + + /** + * Sets the default PHP locale. + * + * @param string $locale + */ + private function setPhpDefaultLocale($locale) + { + // if either the class Locale doesn't exist, or an exception is thrown when + // setting the default locale, the intl module is not installed, and + // the call can be ignored: + try { + if (class_exists('Locale', false)) { + \Locale::setDefault($locale); + } + } catch (\Exception $e) { + } + } + + /* + * Returns the prefix as encoded in the string when the string starts with + * the given prefix, false otherwise. + * + * @param string $string The urlencoded string + * @param string $prefix The prefix not encoded + * + * @return string|false The prefix as it is encoded in $string, or false + */ + private function getUrlencodedPrefix($string, $prefix) + { + if (0 !== strpos(rawurldecode($string), $prefix)) { + return false; + } + + $len = strlen($prefix); + + if (preg_match(sprintf('#^(%%[[:xdigit:]]{2}|.){%d}#', $len), $string, $match)) { + return $match[0]; + } + + return false; + } + + private static function createRequestFromFactory(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null) + { + if (self::$requestFactory) { + $request = call_user_func(self::$requestFactory, $query, $request, $attributes, $cookies, $files, $server, $content); + + if (!$request instanceof self) { + throw new \LogicException('The Request factory must return an instance of Symfony\Component\HttpFoundation\Request.'); + } + + return $request; + } + + return new static($query, $request, $attributes, $cookies, $files, $server, $content); + } + + private function isFromTrustedProxy() + { + return self::$trustedProxies && IpUtils::checkIp($this->server->get('REMOTE_ADDR'), self::$trustedProxies); + } + + private function normalizeAndFilterClientIps(array $clientIps, $ip) + { + $clientIps[] = $ip; // Complete the IP chain with the IP the request actually came from + $firstTrustedIp = null; + + foreach ($clientIps as $key => $clientIp) { + // Remove port (unfortunately, it does happen) + if (preg_match('{((?:\d+\.){3}\d+)\:\d+}', $clientIp, $match)) { + $clientIps[$key] = $clientIp = $match[1]; + } + + if (!filter_var($clientIp, FILTER_VALIDATE_IP)) { + unset($clientIps[$key]); + + continue; + } + + if (IpUtils::checkIp($clientIp, self::$trustedProxies)) { + unset($clientIps[$key]); + + // Fallback to this when the client IP falls into the range of trusted proxies + if (null === $firstTrustedIp) { + $firstTrustedIp = $clientIp; + } + } + } + + // Now the IP chain contains only untrusted proxies and the client IP + return $clientIps ? array_reverse($clientIps) : array($firstTrustedIp); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/RequestMatcher.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/RequestMatcher.php new file mode 100644 index 0000000..ca094ca --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/RequestMatcher.php @@ -0,0 +1,178 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation; + +/** + * RequestMatcher compares a pre-defined set of checks against a Request instance. + * + * @author Fabien Potencier + */ +class RequestMatcher implements RequestMatcherInterface +{ + /** + * @var string + */ + private $path; + + /** + * @var string + */ + private $host; + + /** + * @var array + */ + private $methods = array(); + + /** + * @var string + */ + private $ips = array(); + + /** + * @var array + */ + private $attributes = array(); + + /** + * @var string[] + */ + private $schemes = array(); + + /** + * @param string|null $path + * @param string|null $host + * @param string|string[]|null $methods + * @param string|string[]|null $ips + * @param array $attributes + * @param string|string[]|null $schemes + */ + public function __construct($path = null, $host = null, $methods = null, $ips = null, array $attributes = array(), $schemes = null) + { + $this->matchPath($path); + $this->matchHost($host); + $this->matchMethod($methods); + $this->matchIps($ips); + $this->matchScheme($schemes); + + foreach ($attributes as $k => $v) { + $this->matchAttribute($k, $v); + } + } + + /** + * Adds a check for the HTTP scheme. + * + * @param string|string[]|null $scheme An HTTP scheme or an array of HTTP schemes + */ + public function matchScheme($scheme) + { + $this->schemes = array_map('strtolower', (array) $scheme); + } + + /** + * Adds a check for the URL host name. + * + * @param string $regexp A Regexp + */ + public function matchHost($regexp) + { + $this->host = $regexp; + } + + /** + * Adds a check for the URL path info. + * + * @param string $regexp A Regexp + */ + public function matchPath($regexp) + { + $this->path = $regexp; + } + + /** + * Adds a check for the client IP. + * + * @param string $ip A specific IP address or a range specified using IP/netmask like 192.168.1.0/24 + */ + public function matchIp($ip) + { + $this->matchIps($ip); + } + + /** + * Adds a check for the client IP. + * + * @param string|string[] $ips A specific IP address or a range specified using IP/netmask like 192.168.1.0/24 + */ + public function matchIps($ips) + { + $this->ips = (array) $ips; + } + + /** + * Adds a check for the HTTP method. + * + * @param string|string[] $method An HTTP method or an array of HTTP methods + */ + public function matchMethod($method) + { + $this->methods = array_map('strtoupper', (array) $method); + } + + /** + * Adds a check for request attribute. + * + * @param string $key The request attribute name + * @param string $regexp A Regexp + */ + public function matchAttribute($key, $regexp) + { + $this->attributes[$key] = $regexp; + } + + /** + * {@inheritdoc} + */ + public function matches(Request $request) + { + if ($this->schemes && !in_array($request->getScheme(), $this->schemes)) { + return false; + } + + if ($this->methods && !in_array($request->getMethod(), $this->methods)) { + return false; + } + + foreach ($this->attributes as $key => $pattern) { + if (!preg_match('{'.$pattern.'}', $request->attributes->get($key))) { + return false; + } + } + + if (null !== $this->path && !preg_match('{'.$this->path.'}', rawurldecode($request->getPathInfo()))) { + return false; + } + + if (null !== $this->host && !preg_match('{'.$this->host.'}i', $request->getHost())) { + return false; + } + + if (IpUtils::checkIp($request->getClientIp(), $this->ips)) { + return true; + } + + // Note to future implementors: add additional checks above the + // foreach above or else your check might not be run! + return count($this->ips) === 0; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/RequestMatcherInterface.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/RequestMatcherInterface.php new file mode 100644 index 0000000..066e7e8 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/RequestMatcherInterface.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation; + +/** + * RequestMatcherInterface is an interface for strategies to match a Request. + * + * @author Fabien Potencier + */ +interface RequestMatcherInterface +{ + /** + * Decides whether the rule(s) implemented by the strategy matches the supplied request. + * + * @param Request $request The request to check for a match + * + * @return bool true if the request matches, false otherwise + */ + public function matches(Request $request); +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/RequestStack.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/RequestStack.php new file mode 100644 index 0000000..3d9cfd0 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/RequestStack.php @@ -0,0 +1,103 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation; + +/** + * Request stack that controls the lifecycle of requests. + * + * @author Benjamin Eberlei + */ +class RequestStack +{ + /** + * @var Request[] + */ + private $requests = array(); + + /** + * Pushes a Request on the stack. + * + * This method should generally not be called directly as the stack + * management should be taken care of by the application itself. + */ + public function push(Request $request) + { + $this->requests[] = $request; + } + + /** + * Pops the current request from the stack. + * + * This operation lets the current request go out of scope. + * + * This method should generally not be called directly as the stack + * management should be taken care of by the application itself. + * + * @return Request|null + */ + public function pop() + { + if (!$this->requests) { + return; + } + + return array_pop($this->requests); + } + + /** + * @return Request|null + */ + public function getCurrentRequest() + { + return end($this->requests) ?: null; + } + + /** + * Gets the master Request. + * + * Be warned that making your code aware of the master request + * might make it un-compatible with other features of your framework + * like ESI support. + * + * @return Request|null + */ + public function getMasterRequest() + { + if (!$this->requests) { + return; + } + + return $this->requests[0]; + } + + /** + * Returns the parent request of the current. + * + * Be warned that making your code aware of the parent request + * might make it un-compatible with other features of your framework + * like ESI support. + * + * If current Request is the master request, it returns null. + * + * @return Request|null + */ + public function getParentRequest() + { + $pos = count($this->requests) - 2; + + if (!isset($this->requests[$pos])) { + return; + } + + return $this->requests[$pos]; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Resources/stubs/SessionHandlerInterface.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Resources/stubs/SessionHandlerInterface.php new file mode 100644 index 0000000..9baa7bc --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Resources/stubs/SessionHandlerInterface.php @@ -0,0 +1,102 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * SessionHandlerInterface for PHP < 5.4. + * + * The order in which these methods are invoked by PHP are: + * 1. open [session_start] + * 2. read + * 3. gc [optional depending on probability settings: gc_probability / gc_divisor] + * 4. destroy [optional when session_regenerate_id(true) is used] + * 5. write [session_write_close] or destroy [session_destroy] + * 6. close + * + * Extensive documentation can be found at php.net, see links: + * + * @see http://php.net/sessionhandlerinterface + * @see http://php.net/session.customhandler + * @see http://php.net/session-set-save-handler + * + * @author Drak + * @author Tobias Schultze + */ +interface SessionHandlerInterface +{ + /** + * Re-initializes existing session, or creates a new one. + * + * @see http://php.net/sessionhandlerinterface.open + * + * @param string $savePath Save path + * @param string $sessionName Session name, see http://php.net/function.session-name.php + * + * @return bool true on success, false on failure + */ + public function open($savePath, $sessionName); + + /** + * Closes the current session. + * + * @see http://php.net/sessionhandlerinterface.close + * + * @return bool true on success, false on failure + */ + public function close(); + + /** + * Reads the session data. + * + * @see http://php.net/sessionhandlerinterface.read + * + * @param string $sessionId Session ID, see http://php.net/function.session-id + * + * @return string Same session data as passed in write() or empty string when non-existent or on failure + */ + public function read($sessionId); + + /** + * Writes the session data to the storage. + * + * Care, the session ID passed to write() can be different from the one previously + * received in read() when the session ID changed due to session_regenerate_id(). + * + * @see http://php.net/sessionhandlerinterface.write + * + * @param string $sessionId Session ID , see http://php.net/function.session-id + * @param string $data Serialized session data to save + * + * @return bool true on success, false on failure + */ + public function write($sessionId, $data); + + /** + * Destroys a session. + * + * @see http://php.net/sessionhandlerinterface.destroy + * + * @param string $sessionId Session ID, see http://php.net/function.session-id + * + * @return bool true on success, false on failure + */ + public function destroy($sessionId); + + /** + * Cleans up expired sessions (garbage collection). + * + * @see http://php.net/sessionhandlerinterface.gc + * + * @param string|int $maxlifetime Sessions that have not updated for the last maxlifetime seconds will be removed + * + * @return bool true on success, false on failure + */ + public function gc($maxlifetime); +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Response.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Response.php new file mode 100644 index 0000000..9babc63 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Response.php @@ -0,0 +1,1176 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation; + +/** + * Response represents an HTTP response. + * + * @author Fabien Potencier + */ +class Response +{ + const HTTP_CONTINUE = 100; + const HTTP_SWITCHING_PROTOCOLS = 101; + const HTTP_PROCESSING = 102; // RFC2518 + const HTTP_OK = 200; + const HTTP_CREATED = 201; + const HTTP_ACCEPTED = 202; + const HTTP_NON_AUTHORITATIVE_INFORMATION = 203; + const HTTP_NO_CONTENT = 204; + const HTTP_RESET_CONTENT = 205; + const HTTP_PARTIAL_CONTENT = 206; + const HTTP_MULTI_STATUS = 207; // RFC4918 + const HTTP_ALREADY_REPORTED = 208; // RFC5842 + const HTTP_IM_USED = 226; // RFC3229 + const HTTP_MULTIPLE_CHOICES = 300; + const HTTP_MOVED_PERMANENTLY = 301; + const HTTP_FOUND = 302; + const HTTP_SEE_OTHER = 303; + const HTTP_NOT_MODIFIED = 304; + const HTTP_USE_PROXY = 305; + const HTTP_RESERVED = 306; + const HTTP_TEMPORARY_REDIRECT = 307; + const HTTP_PERMANENTLY_REDIRECT = 308; // RFC7238 + const HTTP_BAD_REQUEST = 400; + const HTTP_UNAUTHORIZED = 401; + const HTTP_PAYMENT_REQUIRED = 402; + const HTTP_FORBIDDEN = 403; + const HTTP_NOT_FOUND = 404; + const HTTP_METHOD_NOT_ALLOWED = 405; + const HTTP_NOT_ACCEPTABLE = 406; + const HTTP_PROXY_AUTHENTICATION_REQUIRED = 407; + const HTTP_REQUEST_TIMEOUT = 408; + const HTTP_CONFLICT = 409; + const HTTP_GONE = 410; + const HTTP_LENGTH_REQUIRED = 411; + const HTTP_PRECONDITION_FAILED = 412; + const HTTP_REQUEST_ENTITY_TOO_LARGE = 413; + const HTTP_REQUEST_URI_TOO_LONG = 414; + const HTTP_UNSUPPORTED_MEDIA_TYPE = 415; + const HTTP_REQUESTED_RANGE_NOT_SATISFIABLE = 416; + const HTTP_EXPECTATION_FAILED = 417; + const HTTP_I_AM_A_TEAPOT = 418; // RFC2324 + const HTTP_MISDIRECTED_REQUEST = 421; // RFC7540 + const HTTP_UNPROCESSABLE_ENTITY = 422; // RFC4918 + const HTTP_LOCKED = 423; // RFC4918 + const HTTP_FAILED_DEPENDENCY = 424; // RFC4918 + const HTTP_RESERVED_FOR_WEBDAV_ADVANCED_COLLECTIONS_EXPIRED_PROPOSAL = 425; // RFC2817 + const HTTP_UPGRADE_REQUIRED = 426; // RFC2817 + const HTTP_PRECONDITION_REQUIRED = 428; // RFC6585 + const HTTP_TOO_MANY_REQUESTS = 429; // RFC6585 + const HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE = 431; // RFC6585 + const HTTP_UNAVAILABLE_FOR_LEGAL_REASONS = 451; + const HTTP_INTERNAL_SERVER_ERROR = 500; + const HTTP_NOT_IMPLEMENTED = 501; + const HTTP_BAD_GATEWAY = 502; + const HTTP_SERVICE_UNAVAILABLE = 503; + const HTTP_GATEWAY_TIMEOUT = 504; + const HTTP_VERSION_NOT_SUPPORTED = 505; + const HTTP_VARIANT_ALSO_NEGOTIATES_EXPERIMENTAL = 506; // RFC2295 + const HTTP_INSUFFICIENT_STORAGE = 507; // RFC4918 + const HTTP_LOOP_DETECTED = 508; // RFC5842 + const HTTP_NOT_EXTENDED = 510; // RFC2774 + const HTTP_NETWORK_AUTHENTICATION_REQUIRED = 511; // RFC6585 + + /** + * @var \Symfony\Component\HttpFoundation\ResponseHeaderBag + */ + public $headers; + + /** + * @var string + */ + protected $content; + + /** + * @var string + */ + protected $version; + + /** + * @var int + */ + protected $statusCode; + + /** + * @var string + */ + protected $statusText; + + /** + * @var string + */ + protected $charset; + + /** + * Status codes translation table. + * + * The list of codes is complete according to the + * {@link http://www.iana.org/assignments/http-status-codes/ Hypertext Transfer Protocol (HTTP) Status Code Registry} + * (last updated 2016-03-01). + * + * Unless otherwise noted, the status code is defined in RFC2616. + * + * @var array + */ + public static $statusTexts = array( + 100 => 'Continue', + 101 => 'Switching Protocols', + 102 => 'Processing', // RFC2518 + 200 => 'OK', + 201 => 'Created', + 202 => 'Accepted', + 203 => 'Non-Authoritative Information', + 204 => 'No Content', + 205 => 'Reset Content', + 206 => 'Partial Content', + 207 => 'Multi-Status', // RFC4918 + 208 => 'Already Reported', // RFC5842 + 226 => 'IM Used', // RFC3229 + 300 => 'Multiple Choices', + 301 => 'Moved Permanently', + 302 => 'Found', + 303 => 'See Other', + 304 => 'Not Modified', + 305 => 'Use Proxy', + 306 => 'Reserved', + 307 => 'Temporary Redirect', + 308 => 'Permanent Redirect', // RFC7238 + 400 => 'Bad Request', + 401 => 'Unauthorized', + 402 => 'Payment Required', + 403 => 'Forbidden', + 404 => 'Not Found', + 405 => 'Method Not Allowed', + 406 => 'Not Acceptable', + 407 => 'Proxy Authentication Required', + 408 => 'Request Timeout', + 409 => 'Conflict', + 410 => 'Gone', + 411 => 'Length Required', + 412 => 'Precondition Failed', + 413 => 'Request Entity Too Large', + 414 => 'Request-URI Too Long', + 415 => 'Unsupported Media Type', + 416 => 'Requested Range Not Satisfiable', + 417 => 'Expectation Failed', + 418 => 'I\'m a teapot', // RFC2324 + 421 => 'Misdirected Request', // RFC7540 + 422 => 'Unprocessable Entity', // RFC4918 + 423 => 'Locked', // RFC4918 + 424 => 'Failed Dependency', // RFC4918 + 425 => 'Reserved for WebDAV advanced collections expired proposal', // RFC2817 + 426 => 'Upgrade Required', // RFC2817 + 428 => 'Precondition Required', // RFC6585 + 429 => 'Too Many Requests', // RFC6585 + 431 => 'Request Header Fields Too Large', // RFC6585 + 451 => 'Unavailable For Legal Reasons', // RFC7725 + 500 => 'Internal Server Error', + 501 => 'Not Implemented', + 502 => 'Bad Gateway', + 503 => 'Service Unavailable', + 504 => 'Gateway Timeout', + 505 => 'HTTP Version Not Supported', + 506 => 'Variant Also Negotiates (Experimental)', // RFC2295 + 507 => 'Insufficient Storage', // RFC4918 + 508 => 'Loop Detected', // RFC5842 + 510 => 'Not Extended', // RFC2774 + 511 => 'Network Authentication Required', // RFC6585 + ); + + /** + * Constructor. + * + * @param mixed $content The response content, see setContent() + * @param int $status The response status code + * @param array $headers An array of response headers + * + * @throws \InvalidArgumentException When the HTTP status code is not valid + */ + public function __construct($content = '', $status = 200, $headers = array()) + { + $this->headers = new ResponseHeaderBag($headers); + $this->setContent($content); + $this->setStatusCode($status); + $this->setProtocolVersion('1.0'); + if (!$this->headers->has('Date')) { + $this->setDate(\DateTime::createFromFormat('U', time(), new \DateTimeZone('UTC'))); + } + } + + /** + * Factory method for chainability. + * + * Example: + * + * return Response::create($body, 200) + * ->setSharedMaxAge(300); + * + * @param mixed $content The response content, see setContent() + * @param int $status The response status code + * @param array $headers An array of response headers + * + * @return Response + */ + public static function create($content = '', $status = 200, $headers = array()) + { + return new static($content, $status, $headers); + } + + /** + * Returns the Response as an HTTP string. + * + * The string representation of the Response is the same as the + * one that will be sent to the client only if the prepare() method + * has been called before. + * + * @return string The Response as an HTTP string + * + * @see prepare() + */ + public function __toString() + { + return + sprintf('HTTP/%s %s %s', $this->version, $this->statusCode, $this->statusText)."\r\n". + $this->headers."\r\n". + $this->getContent(); + } + + /** + * Clones the current Response instance. + */ + public function __clone() + { + $this->headers = clone $this->headers; + } + + /** + * Prepares the Response before it is sent to the client. + * + * This method tweaks the Response to ensure that it is + * compliant with RFC 2616. Most of the changes are based on + * the Request that is "associated" with this Response. + * + * @param Request $request A Request instance + * + * @return Response The current response + */ + public function prepare(Request $request) + { + $headers = $this->headers; + + if ($this->isInformational() || $this->isEmpty()) { + $this->setContent(null); + $headers->remove('Content-Type'); + $headers->remove('Content-Length'); + } else { + // Content-type based on the Request + if (!$headers->has('Content-Type')) { + $format = $request->getRequestFormat(); + if (null !== $format && $mimeType = $request->getMimeType($format)) { + $headers->set('Content-Type', $mimeType); + } + } + + // Fix Content-Type + $charset = $this->charset ?: 'UTF-8'; + if (!$headers->has('Content-Type')) { + $headers->set('Content-Type', 'text/html; charset='.$charset); + } elseif (0 === stripos($headers->get('Content-Type'), 'text/') && false === stripos($headers->get('Content-Type'), 'charset')) { + // add the charset + $headers->set('Content-Type', $headers->get('Content-Type').'; charset='.$charset); + } + + // Fix Content-Length + if ($headers->has('Transfer-Encoding')) { + $headers->remove('Content-Length'); + } + + if ($request->isMethod('HEAD')) { + // cf. RFC2616 14.13 + $length = $headers->get('Content-Length'); + $this->setContent(null); + if ($length) { + $headers->set('Content-Length', $length); + } + } + } + + // Fix protocol + if ('HTTP/1.0' != $request->server->get('SERVER_PROTOCOL')) { + $this->setProtocolVersion('1.1'); + } + + // Check if we need to send extra expire info headers + if ('1.0' == $this->getProtocolVersion() && 'no-cache' == $this->headers->get('Cache-Control')) { + $this->headers->set('pragma', 'no-cache'); + $this->headers->set('expires', -1); + } + + $this->ensureIEOverSSLCompatibility($request); + + return $this; + } + + /** + * Sends HTTP headers. + * + * @return Response + */ + public function sendHeaders() + { + // headers have already been sent by the developer + if (headers_sent()) { + return $this; + } + + // headers + foreach ($this->headers->allPreserveCase() as $name => $values) { + foreach ($values as $value) { + header($name.': '.$value, false); + } + } + + // status + header(sprintf('HTTP/%s %s %s', $this->version, $this->statusCode, $this->statusText), true, $this->statusCode); + + // cookies + foreach ($this->headers->getCookies() as $cookie) { + setcookie($cookie->getName(), $cookie->getValue(), $cookie->getExpiresTime(), $cookie->getPath(), $cookie->getDomain(), $cookie->isSecure(), $cookie->isHttpOnly()); + } + + return $this; + } + + /** + * Sends content for the current web response. + * + * @return Response + */ + public function sendContent() + { + echo $this->content; + + return $this; + } + + /** + * Sends HTTP headers and content. + * + * @return Response + */ + public function send() + { + $this->sendHeaders(); + $this->sendContent(); + + if (function_exists('fastcgi_finish_request')) { + fastcgi_finish_request(); + } elseif ('cli' !== PHP_SAPI) { + static::closeOutputBuffers(0, true); + } + + return $this; + } + + /** + * Sets the response content. + * + * Valid types are strings, numbers, null, and objects that implement a __toString() method. + * + * @param mixed $content Content that can be cast to string + * + * @return Response + * + * @throws \UnexpectedValueException + */ + public function setContent($content) + { + if (null !== $content && !is_string($content) && !is_numeric($content) && !is_callable(array($content, '__toString'))) { + throw new \UnexpectedValueException(sprintf('The Response content must be a string or object implementing __toString(), "%s" given.', gettype($content))); + } + + $this->content = (string) $content; + + return $this; + } + + /** + * Gets the current response content. + * + * @return string Content + */ + public function getContent() + { + return $this->content; + } + + /** + * Sets the HTTP protocol version (1.0 or 1.1). + * + * @param string $version The HTTP protocol version + * + * @return Response + */ + public function setProtocolVersion($version) + { + $this->version = $version; + + return $this; + } + + /** + * Gets the HTTP protocol version. + * + * @return string The HTTP protocol version + */ + public function getProtocolVersion() + { + return $this->version; + } + + /** + * Sets the response status code. + * + * @param int $code HTTP status code + * @param mixed $text HTTP status text + * + * If the status text is null it will be automatically populated for the known + * status codes and left empty otherwise. + * + * @return Response + * + * @throws \InvalidArgumentException When the HTTP status code is not valid + */ + public function setStatusCode($code, $text = null) + { + $this->statusCode = $code = (int) $code; + if ($this->isInvalid()) { + throw new \InvalidArgumentException(sprintf('The HTTP status code "%s" is not valid.', $code)); + } + + if (null === $text) { + $this->statusText = isset(self::$statusTexts[$code]) ? self::$statusTexts[$code] : 'unknown status'; + + return $this; + } + + if (false === $text) { + $this->statusText = ''; + + return $this; + } + + $this->statusText = $text; + + return $this; + } + + /** + * Retrieves the status code for the current web response. + * + * @return int Status code + */ + public function getStatusCode() + { + return $this->statusCode; + } + + /** + * Sets the response charset. + * + * @param string $charset Character set + * + * @return Response + */ + public function setCharset($charset) + { + $this->charset = $charset; + + return $this; + } + + /** + * Retrieves the response charset. + * + * @return string Character set + */ + public function getCharset() + { + return $this->charset; + } + + /** + * Returns true if the response is worth caching under any circumstance. + * + * Responses marked "private" with an explicit Cache-Control directive are + * considered uncacheable. + * + * Responses with neither a freshness lifetime (Expires, max-age) nor cache + * validator (Last-Modified, ETag) are considered uncacheable. + * + * @return bool true if the response is worth caching, false otherwise + */ + public function isCacheable() + { + if (!in_array($this->statusCode, array(200, 203, 300, 301, 302, 404, 410))) { + return false; + } + + if ($this->headers->hasCacheControlDirective('no-store') || $this->headers->getCacheControlDirective('private')) { + return false; + } + + return $this->isValidateable() || $this->isFresh(); + } + + /** + * Returns true if the response is "fresh". + * + * Fresh responses may be served from cache without any interaction with the + * origin. A response is considered fresh when it includes a Cache-Control/max-age + * indicator or Expires header and the calculated age is less than the freshness lifetime. + * + * @return bool true if the response is fresh, false otherwise + */ + public function isFresh() + { + return $this->getTtl() > 0; + } + + /** + * Returns true if the response includes headers that can be used to validate + * the response with the origin server using a conditional GET request. + * + * @return bool true if the response is validateable, false otherwise + */ + public function isValidateable() + { + return $this->headers->has('Last-Modified') || $this->headers->has('ETag'); + } + + /** + * Marks the response as "private". + * + * It makes the response ineligible for serving other clients. + * + * @return Response + */ + public function setPrivate() + { + $this->headers->removeCacheControlDirective('public'); + $this->headers->addCacheControlDirective('private'); + + return $this; + } + + /** + * Marks the response as "public". + * + * It makes the response eligible for serving other clients. + * + * @return Response + */ + public function setPublic() + { + $this->headers->addCacheControlDirective('public'); + $this->headers->removeCacheControlDirective('private'); + + return $this; + } + + /** + * Returns true if the response must be revalidated by caches. + * + * This method indicates that the response must not be served stale by a + * cache in any circumstance without first revalidating with the origin. + * When present, the TTL of the response should not be overridden to be + * greater than the value provided by the origin. + * + * @return bool true if the response must be revalidated by a cache, false otherwise + */ + public function mustRevalidate() + { + return $this->headers->hasCacheControlDirective('must-revalidate') || $this->headers->hasCacheControlDirective('proxy-revalidate'); + } + + /** + * Returns the Date header as a DateTime instance. + * + * @return \DateTime A \DateTime instance + * + * @throws \RuntimeException When the header is not parseable + */ + public function getDate() + { + return $this->headers->getDate('Date', new \DateTime()); + } + + /** + * Sets the Date header. + * + * @param \DateTime $date A \DateTime instance + * + * @return Response + */ + public function setDate(\DateTime $date) + { + $date->setTimezone(new \DateTimeZone('UTC')); + $this->headers->set('Date', $date->format('D, d M Y H:i:s').' GMT'); + + return $this; + } + + /** + * Returns the age of the response. + * + * @return int The age of the response in seconds + */ + public function getAge() + { + if (null !== $age = $this->headers->get('Age')) { + return (int) $age; + } + + return max(time() - $this->getDate()->format('U'), 0); + } + + /** + * Marks the response stale by setting the Age header to be equal to the maximum age of the response. + * + * @return Response + */ + public function expire() + { + if ($this->isFresh()) { + $this->headers->set('Age', $this->getMaxAge()); + } + + return $this; + } + + /** + * Returns the value of the Expires header as a DateTime instance. + * + * @return \DateTime|null A DateTime instance or null if the header does not exist + */ + public function getExpires() + { + try { + return $this->headers->getDate('Expires'); + } catch (\RuntimeException $e) { + // according to RFC 2616 invalid date formats (e.g. "0" and "-1") must be treated as in the past + return \DateTime::createFromFormat(DATE_RFC2822, 'Sat, 01 Jan 00 00:00:00 +0000'); + } + } + + /** + * Sets the Expires HTTP header with a DateTime instance. + * + * Passing null as value will remove the header. + * + * @param \DateTime|null $date A \DateTime instance or null to remove the header + * + * @return Response + */ + public function setExpires(\DateTime $date = null) + { + if (null === $date) { + $this->headers->remove('Expires'); + } else { + $date = clone $date; + $date->setTimezone(new \DateTimeZone('UTC')); + $this->headers->set('Expires', $date->format('D, d M Y H:i:s').' GMT'); + } + + return $this; + } + + /** + * Returns the number of seconds after the time specified in the response's Date + * header when the response should no longer be considered fresh. + * + * First, it checks for a s-maxage directive, then a max-age directive, and then it falls + * back on an expires header. It returns null when no maximum age can be established. + * + * @return int|null Number of seconds + */ + public function getMaxAge() + { + if ($this->headers->hasCacheControlDirective('s-maxage')) { + return (int) $this->headers->getCacheControlDirective('s-maxage'); + } + + if ($this->headers->hasCacheControlDirective('max-age')) { + return (int) $this->headers->getCacheControlDirective('max-age'); + } + + if (null !== $this->getExpires()) { + return $this->getExpires()->format('U') - $this->getDate()->format('U'); + } + } + + /** + * Sets the number of seconds after which the response should no longer be considered fresh. + * + * This methods sets the Cache-Control max-age directive. + * + * @param int $value Number of seconds + * + * @return Response + */ + public function setMaxAge($value) + { + $this->headers->addCacheControlDirective('max-age', $value); + + return $this; + } + + /** + * Sets the number of seconds after which the response should no longer be considered fresh by shared caches. + * + * This methods sets the Cache-Control s-maxage directive. + * + * @param int $value Number of seconds + * + * @return Response + */ + public function setSharedMaxAge($value) + { + $this->setPublic(); + $this->headers->addCacheControlDirective('s-maxage', $value); + + return $this; + } + + /** + * Returns the response's time-to-live in seconds. + * + * It returns null when no freshness information is present in the response. + * + * When the responses TTL is <= 0, the response may not be served from cache without first + * revalidating with the origin. + * + * @return int|null The TTL in seconds + */ + public function getTtl() + { + if (null !== $maxAge = $this->getMaxAge()) { + return $maxAge - $this->getAge(); + } + } + + /** + * Sets the response's time-to-live for shared caches. + * + * This method adjusts the Cache-Control/s-maxage directive. + * + * @param int $seconds Number of seconds + * + * @return Response + */ + public function setTtl($seconds) + { + $this->setSharedMaxAge($this->getAge() + $seconds); + + return $this; + } + + /** + * Sets the response's time-to-live for private/client caches. + * + * This method adjusts the Cache-Control/max-age directive. + * + * @param int $seconds Number of seconds + * + * @return Response + */ + public function setClientTtl($seconds) + { + $this->setMaxAge($this->getAge() + $seconds); + + return $this; + } + + /** + * Returns the Last-Modified HTTP header as a DateTime instance. + * + * @return \DateTime|null A DateTime instance or null if the header does not exist + * + * @throws \RuntimeException When the HTTP header is not parseable + */ + public function getLastModified() + { + return $this->headers->getDate('Last-Modified'); + } + + /** + * Sets the Last-Modified HTTP header with a DateTime instance. + * + * Passing null as value will remove the header. + * + * @param \DateTime|null $date A \DateTime instance or null to remove the header + * + * @return Response + */ + public function setLastModified(\DateTime $date = null) + { + if (null === $date) { + $this->headers->remove('Last-Modified'); + } else { + $date = clone $date; + $date->setTimezone(new \DateTimeZone('UTC')); + $this->headers->set('Last-Modified', $date->format('D, d M Y H:i:s').' GMT'); + } + + return $this; + } + + /** + * Returns the literal value of the ETag HTTP header. + * + * @return string|null The ETag HTTP header or null if it does not exist + */ + public function getEtag() + { + return $this->headers->get('ETag'); + } + + /** + * Sets the ETag value. + * + * @param string|null $etag The ETag unique identifier or null to remove the header + * @param bool $weak Whether you want a weak ETag or not + * + * @return Response + */ + public function setEtag($etag = null, $weak = false) + { + if (null === $etag) { + $this->headers->remove('Etag'); + } else { + if (0 !== strpos($etag, '"')) { + $etag = '"'.$etag.'"'; + } + + $this->headers->set('ETag', (true === $weak ? 'W/' : '').$etag); + } + + return $this; + } + + /** + * Sets the response's cache headers (validation and/or expiration). + * + * Available options are: etag, last_modified, max_age, s_maxage, private, and public. + * + * @param array $options An array of cache options + * + * @return Response + * + * @throws \InvalidArgumentException + */ + public function setCache(array $options) + { + if ($diff = array_diff(array_keys($options), array('etag', 'last_modified', 'max_age', 's_maxage', 'private', 'public'))) { + throw new \InvalidArgumentException(sprintf('Response does not support the following options: "%s".', implode('", "', array_values($diff)))); + } + + if (isset($options['etag'])) { + $this->setEtag($options['etag']); + } + + if (isset($options['last_modified'])) { + $this->setLastModified($options['last_modified']); + } + + if (isset($options['max_age'])) { + $this->setMaxAge($options['max_age']); + } + + if (isset($options['s_maxage'])) { + $this->setSharedMaxAge($options['s_maxage']); + } + + if (isset($options['public'])) { + if ($options['public']) { + $this->setPublic(); + } else { + $this->setPrivate(); + } + } + + if (isset($options['private'])) { + if ($options['private']) { + $this->setPrivate(); + } else { + $this->setPublic(); + } + } + + return $this; + } + + /** + * Modifies the response so that it conforms to the rules defined for a 304 status code. + * + * This sets the status, removes the body, and discards any headers + * that MUST NOT be included in 304 responses. + * + * @return Response + * + * @see http://tools.ietf.org/html/rfc2616#section-10.3.5 + */ + public function setNotModified() + { + $this->setStatusCode(304); + $this->setContent(null); + + // remove headers that MUST NOT be included with 304 Not Modified responses + foreach (array('Allow', 'Content-Encoding', 'Content-Language', 'Content-Length', 'Content-MD5', 'Content-Type', 'Last-Modified') as $header) { + $this->headers->remove($header); + } + + return $this; + } + + /** + * Returns true if the response includes a Vary header. + * + * @return bool true if the response includes a Vary header, false otherwise + */ + public function hasVary() + { + return null !== $this->headers->get('Vary'); + } + + /** + * Returns an array of header names given in the Vary header. + * + * @return array An array of Vary names + */ + public function getVary() + { + if (!$vary = $this->headers->get('Vary', null, false)) { + return array(); + } + + $ret = array(); + foreach ($vary as $item) { + $ret = array_merge($ret, preg_split('/[\s,]+/', $item)); + } + + return $ret; + } + + /** + * Sets the Vary header. + * + * @param string|array $headers + * @param bool $replace Whether to replace the actual value or not (true by default) + * + * @return Response + */ + public function setVary($headers, $replace = true) + { + $this->headers->set('Vary', $headers, $replace); + + return $this; + } + + /** + * Determines if the Response validators (ETag, Last-Modified) match + * a conditional value specified in the Request. + * + * If the Response is not modified, it sets the status code to 304 and + * removes the actual content by calling the setNotModified() method. + * + * @param Request $request A Request instance + * + * @return bool true if the Response validators match the Request, false otherwise + */ + public function isNotModified(Request $request) + { + if (!$request->isMethodSafe()) { + return false; + } + + $notModified = false; + $lastModified = $this->headers->get('Last-Modified'); + $modifiedSince = $request->headers->get('If-Modified-Since'); + + if ($etags = $request->getETags()) { + $notModified = in_array($this->getEtag(), $etags) || in_array('*', $etags); + } + + if ($modifiedSince && $lastModified) { + $notModified = strtotime($modifiedSince) >= strtotime($lastModified) && (!$etags || $notModified); + } + + if ($notModified) { + $this->setNotModified(); + } + + return $notModified; + } + + /** + * Is response invalid? + * + * @return bool + * + * @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html + */ + public function isInvalid() + { + return $this->statusCode < 100 || $this->statusCode >= 600; + } + + /** + * Is response informative? + * + * @return bool + */ + public function isInformational() + { + return $this->statusCode >= 100 && $this->statusCode < 200; + } + + /** + * Is response successful? + * + * @return bool + */ + public function isSuccessful() + { + return $this->statusCode >= 200 && $this->statusCode < 300; + } + + /** + * Is the response a redirect? + * + * @return bool + */ + public function isRedirection() + { + return $this->statusCode >= 300 && $this->statusCode < 400; + } + + /** + * Is there a client error? + * + * @return bool + */ + public function isClientError() + { + return $this->statusCode >= 400 && $this->statusCode < 500; + } + + /** + * Was there a server side error? + * + * @return bool + */ + public function isServerError() + { + return $this->statusCode >= 500 && $this->statusCode < 600; + } + + /** + * Is the response OK? + * + * @return bool + */ + public function isOk() + { + return 200 === $this->statusCode; + } + + /** + * Is the response forbidden? + * + * @return bool + */ + public function isForbidden() + { + return 403 === $this->statusCode; + } + + /** + * Is the response a not found error? + * + * @return bool + */ + public function isNotFound() + { + return 404 === $this->statusCode; + } + + /** + * Is the response a redirect of some form? + * + * @param string $location + * + * @return bool + */ + public function isRedirect($location = null) + { + return in_array($this->statusCode, array(201, 301, 302, 303, 307, 308)) && (null === $location ?: $location == $this->headers->get('Location')); + } + + /** + * Is the response empty? + * + * @return bool + */ + public function isEmpty() + { + return in_array($this->statusCode, array(204, 304)); + } + + /** + * Cleans or flushes output buffers up to target level. + * + * Resulting level can be greater than target level if a non-removable buffer has been encountered. + * + * @param int $targetLevel The target output buffering level + * @param bool $flush Whether to flush or clean the buffers + */ + public static function closeOutputBuffers($targetLevel, $flush) + { + $status = ob_get_status(true); + $level = count($status); + $flags = defined('PHP_OUTPUT_HANDLER_REMOVABLE') ? PHP_OUTPUT_HANDLER_REMOVABLE | ($flush ? PHP_OUTPUT_HANDLER_FLUSHABLE : PHP_OUTPUT_HANDLER_CLEANABLE) : -1; + + while ($level-- > $targetLevel && ($s = $status[$level]) && (!isset($s['del']) ? !isset($s['flags']) || $flags === ($s['flags'] & $flags) : $s['del'])) { + if ($flush) { + ob_end_flush(); + } else { + ob_end_clean(); + } + } + } + + /** + * Checks if we need to remove Cache-Control for SSL encrypted downloads when using IE < 9. + * + * @link http://support.microsoft.com/kb/323308 + */ + protected function ensureIEOverSSLCompatibility(Request $request) + { + if (false !== stripos($this->headers->get('Content-Disposition'), 'attachment') && preg_match('/MSIE (.*?);/i', $request->server->get('HTTP_USER_AGENT'), $match) == 1 && true === $request->isSecure()) { + if ((int) preg_replace('/(MSIE )(.*?);/', '$2', $match[0]) < 9) { + $this->headers->remove('Cache-Control'); + } + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/ResponseHeaderBag.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/ResponseHeaderBag.php new file mode 100644 index 0000000..3223691 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/ResponseHeaderBag.php @@ -0,0 +1,304 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation; + +/** + * ResponseHeaderBag is a container for Response HTTP headers. + * + * @author Fabien Potencier + */ +class ResponseHeaderBag extends HeaderBag +{ + const COOKIES_FLAT = 'flat'; + const COOKIES_ARRAY = 'array'; + + const DISPOSITION_ATTACHMENT = 'attachment'; + const DISPOSITION_INLINE = 'inline'; + + /** + * @var array + */ + protected $computedCacheControl = array(); + + /** + * @var array + */ + protected $cookies = array(); + + /** + * @var array + */ + protected $headerNames = array(); + + /** + * Constructor. + * + * @param array $headers An array of HTTP headers + */ + public function __construct(array $headers = array()) + { + parent::__construct($headers); + + if (!isset($this->headers['cache-control'])) { + $this->set('Cache-Control', ''); + } + } + + /** + * {@inheritdoc} + */ + public function __toString() + { + $cookies = ''; + foreach ($this->getCookies() as $cookie) { + $cookies .= 'Set-Cookie: '.$cookie."\r\n"; + } + + ksort($this->headerNames); + + return parent::__toString().$cookies; + } + + /** + * Returns the headers, with original capitalizations. + * + * @return array An array of headers + */ + public function allPreserveCase() + { + return array_combine($this->headerNames, $this->headers); + } + + /** + * {@inheritdoc} + */ + public function replace(array $headers = array()) + { + $this->headerNames = array(); + + parent::replace($headers); + + if (!isset($this->headers['cache-control'])) { + $this->set('Cache-Control', ''); + } + } + + /** + * {@inheritdoc} + */ + public function set($key, $values, $replace = true) + { + parent::set($key, $values, $replace); + + $uniqueKey = str_replace('_', '-', strtolower($key)); + $this->headerNames[$uniqueKey] = $key; + + // ensure the cache-control header has sensible defaults + if (in_array($uniqueKey, array('cache-control', 'etag', 'last-modified', 'expires'))) { + $computed = $this->computeCacheControlValue(); + $this->headers['cache-control'] = array($computed); + $this->headerNames['cache-control'] = 'Cache-Control'; + $this->computedCacheControl = $this->parseCacheControl($computed); + } + } + + /** + * {@inheritdoc} + */ + public function remove($key) + { + parent::remove($key); + + $uniqueKey = str_replace('_', '-', strtolower($key)); + unset($this->headerNames[$uniqueKey]); + + if ('cache-control' === $uniqueKey) { + $this->computedCacheControl = array(); + } + } + + /** + * {@inheritdoc} + */ + public function hasCacheControlDirective($key) + { + return array_key_exists($key, $this->computedCacheControl); + } + + /** + * {@inheritdoc} + */ + public function getCacheControlDirective($key) + { + return array_key_exists($key, $this->computedCacheControl) ? $this->computedCacheControl[$key] : null; + } + + /** + * Sets a cookie. + * + * @param Cookie $cookie + */ + public function setCookie(Cookie $cookie) + { + $this->cookies[$cookie->getDomain()][$cookie->getPath()][$cookie->getName()] = $cookie; + } + + /** + * Removes a cookie from the array, but does not unset it in the browser. + * + * @param string $name + * @param string $path + * @param string $domain + */ + public function removeCookie($name, $path = '/', $domain = null) + { + if (null === $path) { + $path = '/'; + } + + unset($this->cookies[$domain][$path][$name]); + + if (empty($this->cookies[$domain][$path])) { + unset($this->cookies[$domain][$path]); + + if (empty($this->cookies[$domain])) { + unset($this->cookies[$domain]); + } + } + } + + /** + * Returns an array with all cookies. + * + * @param string $format + * + * @return array + * + * @throws \InvalidArgumentException When the $format is invalid + */ + public function getCookies($format = self::COOKIES_FLAT) + { + if (!in_array($format, array(self::COOKIES_FLAT, self::COOKIES_ARRAY))) { + throw new \InvalidArgumentException(sprintf('Format "%s" invalid (%s).', $format, implode(', ', array(self::COOKIES_FLAT, self::COOKIES_ARRAY)))); + } + + if (self::COOKIES_ARRAY === $format) { + return $this->cookies; + } + + $flattenedCookies = array(); + foreach ($this->cookies as $path) { + foreach ($path as $cookies) { + foreach ($cookies as $cookie) { + $flattenedCookies[] = $cookie; + } + } + } + + return $flattenedCookies; + } + + /** + * Clears a cookie in the browser. + * + * @param string $name + * @param string $path + * @param string $domain + * @param bool $secure + * @param bool $httpOnly + */ + public function clearCookie($name, $path = '/', $domain = null, $secure = false, $httpOnly = true) + { + $this->setCookie(new Cookie($name, null, 1, $path, $domain, $secure, $httpOnly)); + } + + /** + * Generates a HTTP Content-Disposition field-value. + * + * @param string $disposition One of "inline" or "attachment" + * @param string $filename A unicode string + * @param string $filenameFallback A string containing only ASCII characters that + * is semantically equivalent to $filename. If the filename is already ASCII, + * it can be omitted, or just copied from $filename + * + * @return string A string suitable for use as a Content-Disposition field-value + * + * @throws \InvalidArgumentException + * + * @see RFC 6266 + */ + public function makeDisposition($disposition, $filename, $filenameFallback = '') + { + if (!in_array($disposition, array(self::DISPOSITION_ATTACHMENT, self::DISPOSITION_INLINE))) { + throw new \InvalidArgumentException(sprintf('The disposition must be either "%s" or "%s".', self::DISPOSITION_ATTACHMENT, self::DISPOSITION_INLINE)); + } + + if ('' == $filenameFallback) { + $filenameFallback = $filename; + } + + // filenameFallback is not ASCII. + if (!preg_match('/^[\x20-\x7e]*$/', $filenameFallback)) { + throw new \InvalidArgumentException('The filename fallback must only contain ASCII characters.'); + } + + // percent characters aren't safe in fallback. + if (false !== strpos($filenameFallback, '%')) { + throw new \InvalidArgumentException('The filename fallback cannot contain the "%" character.'); + } + + // path separators aren't allowed in either. + if (false !== strpos($filename, '/') || false !== strpos($filename, '\\') || false !== strpos($filenameFallback, '/') || false !== strpos($filenameFallback, '\\')) { + throw new \InvalidArgumentException('The filename and the fallback cannot contain the "/" and "\\" characters.'); + } + + $output = sprintf('%s; filename="%s"', $disposition, str_replace('"', '\\"', $filenameFallback)); + + if ($filename !== $filenameFallback) { + $output .= sprintf("; filename*=utf-8''%s", rawurlencode($filename)); + } + + return $output; + } + + /** + * Returns the calculated value of the cache-control header. + * + * This considers several other headers and calculates or modifies the + * cache-control header to a sensible, conservative value. + * + * @return string + */ + protected function computeCacheControlValue() + { + if (!$this->cacheControl && !$this->has('ETag') && !$this->has('Last-Modified') && !$this->has('Expires')) { + return 'no-cache'; + } + + if (!$this->cacheControl) { + // conservative by default + return 'private, must-revalidate'; + } + + $header = $this->getCacheControlHeader(); + if (isset($this->cacheControl['public']) || isset($this->cacheControl['private'])) { + return $header; + } + + // public if s-maxage is defined, private otherwise + if (!isset($this->cacheControl['s-maxage'])) { + return $header.', private'; + } + + return $header; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/ServerBag.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/ServerBag.php new file mode 100644 index 0000000..0d38c08 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/ServerBag.php @@ -0,0 +1,102 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation; + +/** + * ServerBag is a container for HTTP headers from the $_SERVER variable. + * + * @author Fabien Potencier + * @author Bulat Shakirzyanov + * @author Robert Kiss + */ +class ServerBag extends ParameterBag +{ + /** + * Gets the HTTP headers. + * + * @return array + */ + public function getHeaders() + { + $headers = array(); + $contentHeaders = array('CONTENT_LENGTH' => true, 'CONTENT_MD5' => true, 'CONTENT_TYPE' => true); + foreach ($this->parameters as $key => $value) { + if (0 === strpos($key, 'HTTP_')) { + $headers[substr($key, 5)] = $value; + } + // CONTENT_* are not prefixed with HTTP_ + elseif (isset($contentHeaders[$key])) { + $headers[$key] = $value; + } + } + + if (isset($this->parameters['PHP_AUTH_USER'])) { + $headers['PHP_AUTH_USER'] = $this->parameters['PHP_AUTH_USER']; + $headers['PHP_AUTH_PW'] = isset($this->parameters['PHP_AUTH_PW']) ? $this->parameters['PHP_AUTH_PW'] : ''; + } else { + /* + * php-cgi under Apache does not pass HTTP Basic user/pass to PHP by default + * For this workaround to work, add these lines to your .htaccess file: + * RewriteCond %{HTTP:Authorization} ^(.+)$ + * RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] + * + * A sample .htaccess file: + * RewriteEngine On + * RewriteCond %{HTTP:Authorization} ^(.+)$ + * RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] + * RewriteCond %{REQUEST_FILENAME} !-f + * RewriteRule ^(.*)$ app.php [QSA,L] + */ + + $authorizationHeader = null; + if (isset($this->parameters['HTTP_AUTHORIZATION'])) { + $authorizationHeader = $this->parameters['HTTP_AUTHORIZATION']; + } elseif (isset($this->parameters['REDIRECT_HTTP_AUTHORIZATION'])) { + $authorizationHeader = $this->parameters['REDIRECT_HTTP_AUTHORIZATION']; + } + + if (null !== $authorizationHeader) { + if (0 === stripos($authorizationHeader, 'basic ')) { + // Decode AUTHORIZATION header into PHP_AUTH_USER and PHP_AUTH_PW when authorization header is basic + $exploded = explode(':', base64_decode(substr($authorizationHeader, 6)), 2); + if (count($exploded) == 2) { + list($headers['PHP_AUTH_USER'], $headers['PHP_AUTH_PW']) = $exploded; + } + } elseif (empty($this->parameters['PHP_AUTH_DIGEST']) && (0 === stripos($authorizationHeader, 'digest '))) { + // In some circumstances PHP_AUTH_DIGEST needs to be set + $headers['PHP_AUTH_DIGEST'] = $authorizationHeader; + $this->parameters['PHP_AUTH_DIGEST'] = $authorizationHeader; + } elseif (0 === stripos($authorizationHeader, 'bearer ')) { + /* + * XXX: Since there is no PHP_AUTH_BEARER in PHP predefined variables, + * I'll just set $headers['AUTHORIZATION'] here. + * http://php.net/manual/en/reserved.variables.server.php + */ + $headers['AUTHORIZATION'] = $authorizationHeader; + } + } + } + + if (isset($headers['AUTHORIZATION'])) { + return $headers; + } + + // PHP_AUTH_USER/PHP_AUTH_PW + if (isset($headers['PHP_AUTH_USER'])) { + $headers['AUTHORIZATION'] = 'Basic '.base64_encode($headers['PHP_AUTH_USER'].':'.$headers['PHP_AUTH_PW']); + } elseif (isset($headers['PHP_AUTH_DIGEST'])) { + $headers['AUTHORIZATION'] = $headers['PHP_AUTH_DIGEST']; + } + + return $headers; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Attribute/AttributeBag.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Attribute/AttributeBag.php new file mode 100644 index 0000000..af292e3 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Attribute/AttributeBag.php @@ -0,0 +1,157 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Session\Attribute; + +/** + * This class relates to session attribute storage. + */ +class AttributeBag implements AttributeBagInterface, \IteratorAggregate, \Countable +{ + private $name = 'attributes'; + + /** + * @var string + */ + private $storageKey; + + /** + * @var array + */ + protected $attributes = array(); + + /** + * Constructor. + * + * @param string $storageKey The key used to store attributes in the session + */ + public function __construct($storageKey = '_sf2_attributes') + { + $this->storageKey = $storageKey; + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return $this->name; + } + + public function setName($name) + { + $this->name = $name; + } + + /** + * {@inheritdoc} + */ + public function initialize(array &$attributes) + { + $this->attributes = &$attributes; + } + + /** + * {@inheritdoc} + */ + public function getStorageKey() + { + return $this->storageKey; + } + + /** + * {@inheritdoc} + */ + public function has($name) + { + return array_key_exists($name, $this->attributes); + } + + /** + * {@inheritdoc} + */ + public function get($name, $default = null) + { + return array_key_exists($name, $this->attributes) ? $this->attributes[$name] : $default; + } + + /** + * {@inheritdoc} + */ + public function set($name, $value) + { + $this->attributes[$name] = $value; + } + + /** + * {@inheritdoc} + */ + public function all() + { + return $this->attributes; + } + + /** + * {@inheritdoc} + */ + public function replace(array $attributes) + { + $this->attributes = array(); + foreach ($attributes as $key => $value) { + $this->set($key, $value); + } + } + + /** + * {@inheritdoc} + */ + public function remove($name) + { + $retval = null; + if (array_key_exists($name, $this->attributes)) { + $retval = $this->attributes[$name]; + unset($this->attributes[$name]); + } + + return $retval; + } + + /** + * {@inheritdoc} + */ + public function clear() + { + $return = $this->attributes; + $this->attributes = array(); + + return $return; + } + + /** + * Returns an iterator for attributes. + * + * @return \ArrayIterator An \ArrayIterator instance + */ + public function getIterator() + { + return new \ArrayIterator($this->attributes); + } + + /** + * Returns the number of attributes. + * + * @return int The number of attributes + */ + public function count() + { + return count($this->attributes); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Attribute/AttributeBagInterface.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Attribute/AttributeBagInterface.php new file mode 100644 index 0000000..0d8d179 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Attribute/AttributeBagInterface.php @@ -0,0 +1,72 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Session\Attribute; + +use Symfony\Component\HttpFoundation\Session\SessionBagInterface; + +/** + * Attributes store. + * + * @author Drak + */ +interface AttributeBagInterface extends SessionBagInterface +{ + /** + * Checks if an attribute is defined. + * + * @param string $name The attribute name + * + * @return bool true if the attribute is defined, false otherwise + */ + public function has($name); + + /** + * Returns an attribute. + * + * @param string $name The attribute name + * @param mixed $default The default value if not found + * + * @return mixed + */ + public function get($name, $default = null); + + /** + * Sets an attribute. + * + * @param string $name + * @param mixed $value + */ + public function set($name, $value); + + /** + * Returns attributes. + * + * @return array Attributes + */ + public function all(); + + /** + * Sets attributes. + * + * @param array $attributes Attributes + */ + public function replace(array $attributes); + + /** + * Removes an attribute. + * + * @param string $name + * + * @return mixed The removed value or null when it does not exist + */ + public function remove($name); +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Attribute/NamespacedAttributeBag.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Attribute/NamespacedAttributeBag.php new file mode 100644 index 0000000..d797a6f --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Attribute/NamespacedAttributeBag.php @@ -0,0 +1,160 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Session\Attribute; + +/** + * This class provides structured storage of session attributes using + * a name spacing character in the key. + * + * @author Drak + */ +class NamespacedAttributeBag extends AttributeBag +{ + /** + * Namespace character. + * + * @var string + */ + private $namespaceCharacter; + + /** + * Constructor. + * + * @param string $storageKey Session storage key + * @param string $namespaceCharacter Namespace character to use in keys + */ + public function __construct($storageKey = '_sf2_attributes', $namespaceCharacter = '/') + { + $this->namespaceCharacter = $namespaceCharacter; + parent::__construct($storageKey); + } + + /** + * {@inheritdoc} + */ + public function has($name) + { + // reference mismatch: if fixed, re-introduced in array_key_exists; keep as it is + $attributes = $this->resolveAttributePath($name); + $name = $this->resolveKey($name); + + if (null === $attributes) { + return false; + } + + return array_key_exists($name, $attributes); + } + + /** + * {@inheritdoc} + */ + public function get($name, $default = null) + { + // reference mismatch: if fixed, re-introduced in array_key_exists; keep as it is + $attributes = $this->resolveAttributePath($name); + $name = $this->resolveKey($name); + + if (null === $attributes) { + return $default; + } + + return array_key_exists($name, $attributes) ? $attributes[$name] : $default; + } + + /** + * {@inheritdoc} + */ + public function set($name, $value) + { + $attributes = &$this->resolveAttributePath($name, true); + $name = $this->resolveKey($name); + $attributes[$name] = $value; + } + + /** + * {@inheritdoc} + */ + public function remove($name) + { + $retval = null; + $attributes = &$this->resolveAttributePath($name); + $name = $this->resolveKey($name); + if (null !== $attributes && array_key_exists($name, $attributes)) { + $retval = $attributes[$name]; + unset($attributes[$name]); + } + + return $retval; + } + + /** + * Resolves a path in attributes property and returns it as a reference. + * + * This method allows structured namespacing of session attributes. + * + * @param string $name Key name + * @param bool $writeContext Write context, default false + * + * @return array + */ + protected function &resolveAttributePath($name, $writeContext = false) + { + $array = &$this->attributes; + $name = (strpos($name, $this->namespaceCharacter) === 0) ? substr($name, 1) : $name; + + // Check if there is anything to do, else return + if (!$name) { + return $array; + } + + $parts = explode($this->namespaceCharacter, $name); + if (count($parts) < 2) { + if (!$writeContext) { + return $array; + } + + $array[$parts[0]] = array(); + + return $array; + } + + unset($parts[count($parts) - 1]); + + foreach ($parts as $part) { + if (null !== $array && !array_key_exists($part, $array)) { + $array[$part] = $writeContext ? array() : null; + } + + $array = &$array[$part]; + } + + return $array; + } + + /** + * Resolves the key from the name. + * + * This is the last part in a dot separated string. + * + * @param string $name + * + * @return string + */ + protected function resolveKey($name) + { + if (false !== $pos = strrpos($name, $this->namespaceCharacter)) { + $name = substr($name, $pos + 1); + } + + return $name; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Flash/AutoExpireFlashBag.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Flash/AutoExpireFlashBag.php new file mode 100644 index 0000000..ddd603f --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Flash/AutoExpireFlashBag.php @@ -0,0 +1,175 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Session\Flash; + +/** + * AutoExpireFlashBag flash message container. + * + * @author Drak + */ +class AutoExpireFlashBag implements FlashBagInterface +{ + private $name = 'flashes'; + + /** + * Flash messages. + * + * @var array + */ + private $flashes = array('display' => array(), 'new' => array()); + + /** + * The storage key for flashes in the session. + * + * @var string + */ + private $storageKey; + + /** + * Constructor. + * + * @param string $storageKey The key used to store flashes in the session + */ + public function __construct($storageKey = '_sf2_flashes') + { + $this->storageKey = $storageKey; + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return $this->name; + } + + public function setName($name) + { + $this->name = $name; + } + + /** + * {@inheritdoc} + */ + public function initialize(array &$flashes) + { + $this->flashes = &$flashes; + + // The logic: messages from the last request will be stored in new, so we move them to previous + // This request we will show what is in 'display'. What is placed into 'new' this time round will + // be moved to display next time round. + $this->flashes['display'] = array_key_exists('new', $this->flashes) ? $this->flashes['new'] : array(); + $this->flashes['new'] = array(); + } + + /** + * {@inheritdoc} + */ + public function add($type, $message) + { + $this->flashes['new'][$type][] = $message; + } + + /** + * {@inheritdoc} + */ + public function peek($type, array $default = array()) + { + return $this->has($type) ? $this->flashes['display'][$type] : $default; + } + + /** + * {@inheritdoc} + */ + public function peekAll() + { + return array_key_exists('display', $this->flashes) ? (array) $this->flashes['display'] : array(); + } + + /** + * {@inheritdoc} + */ + public function get($type, array $default = array()) + { + $return = $default; + + if (!$this->has($type)) { + return $return; + } + + if (isset($this->flashes['display'][$type])) { + $return = $this->flashes['display'][$type]; + unset($this->flashes['display'][$type]); + } + + return $return; + } + + /** + * {@inheritdoc} + */ + public function all() + { + $return = $this->flashes['display']; + $this->flashes = array('new' => array(), 'display' => array()); + + return $return; + } + + /** + * {@inheritdoc} + */ + public function setAll(array $messages) + { + $this->flashes['new'] = $messages; + } + + /** + * {@inheritdoc} + */ + public function set($type, $messages) + { + $this->flashes['new'][$type] = (array) $messages; + } + + /** + * {@inheritdoc} + */ + public function has($type) + { + return array_key_exists($type, $this->flashes['display']) && $this->flashes['display'][$type]; + } + + /** + * {@inheritdoc} + */ + public function keys() + { + return array_keys($this->flashes['display']); + } + + /** + * {@inheritdoc} + */ + public function getStorageKey() + { + return $this->storageKey; + } + + /** + * {@inheritdoc} + */ + public function clear() + { + return $this->all(); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Flash/FlashBag.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Flash/FlashBag.php new file mode 100644 index 0000000..1516de7 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Flash/FlashBag.php @@ -0,0 +1,182 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Session\Flash; + +/** + * FlashBag flash message container. + * + * \IteratorAggregate implementation is deprecated and will be removed in 3.0. + * + * @author Drak + */ +class FlashBag implements FlashBagInterface, \IteratorAggregate +{ + private $name = 'flashes'; + + /** + * Flash messages. + * + * @var array + */ + private $flashes = array(); + + /** + * The storage key for flashes in the session. + * + * @var string + */ + private $storageKey; + + /** + * Constructor. + * + * @param string $storageKey The key used to store flashes in the session + */ + public function __construct($storageKey = '_sf2_flashes') + { + $this->storageKey = $storageKey; + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return $this->name; + } + + public function setName($name) + { + $this->name = $name; + } + + /** + * {@inheritdoc} + */ + public function initialize(array &$flashes) + { + $this->flashes = &$flashes; + } + + /** + * {@inheritdoc} + */ + public function add($type, $message) + { + $this->flashes[$type][] = $message; + } + + /** + * {@inheritdoc} + */ + public function peek($type, array $default = array()) + { + return $this->has($type) ? $this->flashes[$type] : $default; + } + + /** + * {@inheritdoc} + */ + public function peekAll() + { + return $this->flashes; + } + + /** + * {@inheritdoc} + */ + public function get($type, array $default = array()) + { + if (!$this->has($type)) { + return $default; + } + + $return = $this->flashes[$type]; + + unset($this->flashes[$type]); + + return $return; + } + + /** + * {@inheritdoc} + */ + public function all() + { + $return = $this->peekAll(); + $this->flashes = array(); + + return $return; + } + + /** + * {@inheritdoc} + */ + public function set($type, $messages) + { + $this->flashes[$type] = (array) $messages; + } + + /** + * {@inheritdoc} + */ + public function setAll(array $messages) + { + $this->flashes = $messages; + } + + /** + * {@inheritdoc} + */ + public function has($type) + { + return array_key_exists($type, $this->flashes) && $this->flashes[$type]; + } + + /** + * {@inheritdoc} + */ + public function keys() + { + return array_keys($this->flashes); + } + + /** + * {@inheritdoc} + */ + public function getStorageKey() + { + return $this->storageKey; + } + + /** + * {@inheritdoc} + */ + public function clear() + { + return $this->all(); + } + + /** + * Returns an iterator for flashes. + * + * @deprecated since version 2.4, to be removed in 3.0. + * + * @return \ArrayIterator An \ArrayIterator instance + */ + public function getIterator() + { + @trigger_error('The '.__METHOD__.' method is deprecated since version 2.4 and will be removed in 3.0.', E_USER_DEPRECATED); + + return new \ArrayIterator($this->all()); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Flash/FlashBagInterface.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Flash/FlashBagInterface.php new file mode 100644 index 0000000..25f3d57 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Flash/FlashBagInterface.php @@ -0,0 +1,95 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Session\Flash; + +use Symfony\Component\HttpFoundation\Session\SessionBagInterface; + +/** + * FlashBagInterface. + * + * @author Drak + */ +interface FlashBagInterface extends SessionBagInterface +{ + /** + * Adds a flash message for type. + * + * @param string $type + * @param string $message + */ + public function add($type, $message); + + /** + * Registers a message for a given type. + * + * @param string $type + * @param string|array $message + */ + public function set($type, $message); + + /** + * Gets flash messages for a given type. + * + * @param string $type Message category type + * @param array $default Default value if $type does not exist + * + * @return array + */ + public function peek($type, array $default = array()); + + /** + * Gets all flash messages. + * + * @return array + */ + public function peekAll(); + + /** + * Gets and clears flash from the stack. + * + * @param string $type + * @param array $default Default value if $type does not exist + * + * @return array + */ + public function get($type, array $default = array()); + + /** + * Gets and clears flashes from the stack. + * + * @return array + */ + public function all(); + + /** + * Sets all flash messages. + * + * @param array $messages + */ + public function setAll(array $messages); + + /** + * Has flash messages for a given type? + * + * @param string $type + * + * @return bool + */ + public function has($type); + + /** + * Returns a list of all defined types. + * + * @return array + */ + public function keys(); +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Session.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Session.php new file mode 100644 index 0000000..cdd9737 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Session.php @@ -0,0 +1,249 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Session; + +use Symfony\Component\HttpFoundation\Session\Storage\SessionStorageInterface; +use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag; +use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBagInterface; +use Symfony\Component\HttpFoundation\Session\Flash\FlashBag; +use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface; +use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage; + +/** + * Session. + * + * @author Fabien Potencier + * @author Drak + */ +class Session implements SessionInterface, \IteratorAggregate, \Countable +{ + /** + * Storage driver. + * + * @var SessionStorageInterface + */ + protected $storage; + + /** + * @var string + */ + private $flashName; + + /** + * @var string + */ + private $attributeName; + + /** + * Constructor. + * + * @param SessionStorageInterface $storage A SessionStorageInterface instance + * @param AttributeBagInterface $attributes An AttributeBagInterface instance, (defaults null for default AttributeBag) + * @param FlashBagInterface $flashes A FlashBagInterface instance (defaults null for default FlashBag) + */ + public function __construct(SessionStorageInterface $storage = null, AttributeBagInterface $attributes = null, FlashBagInterface $flashes = null) + { + $this->storage = $storage ?: new NativeSessionStorage(); + + $attributes = $attributes ?: new AttributeBag(); + $this->attributeName = $attributes->getName(); + $this->registerBag($attributes); + + $flashes = $flashes ?: new FlashBag(); + $this->flashName = $flashes->getName(); + $this->registerBag($flashes); + } + + /** + * {@inheritdoc} + */ + public function start() + { + return $this->storage->start(); + } + + /** + * {@inheritdoc} + */ + public function has($name) + { + return $this->storage->getBag($this->attributeName)->has($name); + } + + /** + * {@inheritdoc} + */ + public function get($name, $default = null) + { + return $this->storage->getBag($this->attributeName)->get($name, $default); + } + + /** + * {@inheritdoc} + */ + public function set($name, $value) + { + $this->storage->getBag($this->attributeName)->set($name, $value); + } + + /** + * {@inheritdoc} + */ + public function all() + { + return $this->storage->getBag($this->attributeName)->all(); + } + + /** + * {@inheritdoc} + */ + public function replace(array $attributes) + { + $this->storage->getBag($this->attributeName)->replace($attributes); + } + + /** + * {@inheritdoc} + */ + public function remove($name) + { + return $this->storage->getBag($this->attributeName)->remove($name); + } + + /** + * {@inheritdoc} + */ + public function clear() + { + $this->storage->getBag($this->attributeName)->clear(); + } + + /** + * {@inheritdoc} + */ + public function isStarted() + { + return $this->storage->isStarted(); + } + + /** + * Returns an iterator for attributes. + * + * @return \ArrayIterator An \ArrayIterator instance + */ + public function getIterator() + { + return new \ArrayIterator($this->storage->getBag($this->attributeName)->all()); + } + + /** + * Returns the number of attributes. + * + * @return int The number of attributes + */ + public function count() + { + return count($this->storage->getBag($this->attributeName)->all()); + } + + /** + * {@inheritdoc} + */ + public function invalidate($lifetime = null) + { + $this->storage->clear(); + + return $this->migrate(true, $lifetime); + } + + /** + * {@inheritdoc} + */ + public function migrate($destroy = false, $lifetime = null) + { + return $this->storage->regenerate($destroy, $lifetime); + } + + /** + * {@inheritdoc} + */ + public function save() + { + $this->storage->save(); + } + + /** + * {@inheritdoc} + */ + public function getId() + { + return $this->storage->getId(); + } + + /** + * {@inheritdoc} + */ + public function setId($id) + { + $this->storage->setId($id); + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return $this->storage->getName(); + } + + /** + * {@inheritdoc} + */ + public function setName($name) + { + $this->storage->setName($name); + } + + /** + * {@inheritdoc} + */ + public function getMetadataBag() + { + return $this->storage->getMetadataBag(); + } + + /** + * {@inheritdoc} + */ + public function registerBag(SessionBagInterface $bag) + { + $this->storage->registerBag($bag); + } + + /** + * {@inheritdoc} + */ + public function getBag($name) + { + return $this->storage->getBag($name); + } + + /** + * Gets the flashbag interface. + * + * @return FlashBagInterface + */ + public function getFlashBag() + { + return $this->getBag($this->flashName); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/SessionBagInterface.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/SessionBagInterface.php new file mode 100644 index 0000000..aca18aa --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/SessionBagInterface.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Session; + +/** + * Session Bag store. + * + * @author Drak + */ +interface SessionBagInterface +{ + /** + * Gets this bag's name. + * + * @return string + */ + public function getName(); + + /** + * Initializes the Bag. + * + * @param array $array + */ + public function initialize(array &$array); + + /** + * Gets the storage key for this bag. + * + * @return string + */ + public function getStorageKey(); + + /** + * Clears out data from bag. + * + * @return mixed Whatever data was contained + */ + public function clear(); +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/SessionInterface.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/SessionInterface.php new file mode 100644 index 0000000..d3fcd2e --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/SessionInterface.php @@ -0,0 +1,182 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Session; + +use Symfony\Component\HttpFoundation\Session\Storage\MetadataBag; + +/** + * Interface for the session. + * + * @author Drak + */ +interface SessionInterface +{ + /** + * Starts the session storage. + * + * @return bool True if session started + * + * @throws \RuntimeException If session fails to start. + */ + public function start(); + + /** + * Returns the session ID. + * + * @return string The session ID + */ + public function getId(); + + /** + * Sets the session ID. + * + * @param string $id + */ + public function setId($id); + + /** + * Returns the session name. + * + * @return mixed The session name + */ + public function getName(); + + /** + * Sets the session name. + * + * @param string $name + */ + public function setName($name); + + /** + * Invalidates the current session. + * + * Clears all session attributes and flashes and regenerates the + * session and deletes the old session from persistence. + * + * @param int $lifetime Sets the cookie lifetime for the session cookie. A null value + * will leave the system settings unchanged, 0 sets the cookie + * to expire with browser session. Time is in seconds, and is + * not a Unix timestamp. + * + * @return bool True if session invalidated, false if error + */ + public function invalidate($lifetime = null); + + /** + * Migrates the current session to a new session id while maintaining all + * session attributes. + * + * @param bool $destroy Whether to delete the old session or leave it to garbage collection + * @param int $lifetime Sets the cookie lifetime for the session cookie. A null value + * will leave the system settings unchanged, 0 sets the cookie + * to expire with browser session. Time is in seconds, and is + * not a Unix timestamp. + * + * @return bool True if session migrated, false if error + */ + public function migrate($destroy = false, $lifetime = null); + + /** + * Force the session to be saved and closed. + * + * This method is generally not required for real sessions as + * the session will be automatically saved at the end of + * code execution. + */ + public function save(); + + /** + * Checks if an attribute is defined. + * + * @param string $name The attribute name + * + * @return bool true if the attribute is defined, false otherwise + */ + public function has($name); + + /** + * Returns an attribute. + * + * @param string $name The attribute name + * @param mixed $default The default value if not found + * + * @return mixed + */ + public function get($name, $default = null); + + /** + * Sets an attribute. + * + * @param string $name + * @param mixed $value + */ + public function set($name, $value); + + /** + * Returns attributes. + * + * @return array Attributes + */ + public function all(); + + /** + * Sets attributes. + * + * @param array $attributes Attributes + */ + public function replace(array $attributes); + + /** + * Removes an attribute. + * + * @param string $name + * + * @return mixed The removed value or null when it does not exist + */ + public function remove($name); + + /** + * Clears all attributes. + */ + public function clear(); + + /** + * Checks if the session was started. + * + * @return bool + */ + public function isStarted(); + + /** + * Registers a SessionBagInterface with the session. + * + * @param SessionBagInterface $bag + */ + public function registerBag(SessionBagInterface $bag); + + /** + * Gets a bag instance by name. + * + * @param string $name + * + * @return SessionBagInterface + */ + public function getBag($name); + + /** + * Gets session meta. + * + * @return MetadataBag + */ + public function getMetadataBag(); +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/Handler/LegacyPdoSessionHandler.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/Handler/LegacyPdoSessionHandler.php new file mode 100644 index 0000000..111541d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/Handler/LegacyPdoSessionHandler.php @@ -0,0 +1,271 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Session\Storage\Handler; + +@trigger_error('The '.__NAMESPACE__.'\LegacyPdoSessionHandler class is deprecated since version 2.6 and will be removed in 3.0. Use the Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler class instead.', E_USER_DEPRECATED); + +/** + * Session handler using a PDO connection to read and write data. + * + * Session data is a binary string that can contain non-printable characters like the null byte. + * For this reason this handler base64 encodes the data to be able to save it in a character column. + * + * This version of the PdoSessionHandler does NOT implement locking. So concurrent requests to the + * same session can result in data loss due to race conditions. + * + * @author Fabien Potencier + * @author Michael Williams + * @author Tobias Schultze + * + * @deprecated since version 2.6, to be removed in 3.0. Use + * {@link PdoSessionHandler} instead. + */ +class LegacyPdoSessionHandler implements \SessionHandlerInterface +{ + /** + * @var \PDO PDO instance + */ + private $pdo; + + /** + * @var string Table name + */ + private $table; + + /** + * @var string Column for session id + */ + private $idCol; + + /** + * @var string Column for session data + */ + private $dataCol; + + /** + * @var string Column for timestamp + */ + private $timeCol; + + /** + * Constructor. + * + * List of available options: + * * db_table: The name of the table [required] + * * db_id_col: The column where to store the session id [default: sess_id] + * * db_data_col: The column where to store the session data [default: sess_data] + * * db_time_col: The column where to store the timestamp [default: sess_time] + * + * @param \PDO $pdo A \PDO instance + * @param array $dbOptions An associative array of DB options + * + * @throws \InvalidArgumentException When "db_table" option is not provided + */ + public function __construct(\PDO $pdo, array $dbOptions = array()) + { + if (!array_key_exists('db_table', $dbOptions)) { + throw new \InvalidArgumentException('You must provide the "db_table" option for a PdoSessionStorage.'); + } + if (\PDO::ERRMODE_EXCEPTION !== $pdo->getAttribute(\PDO::ATTR_ERRMODE)) { + throw new \InvalidArgumentException(sprintf('"%s" requires PDO error mode attribute be set to throw Exceptions (i.e. $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION))', __CLASS__)); + } + + $this->pdo = $pdo; + $dbOptions = array_merge(array( + 'db_id_col' => 'sess_id', + 'db_data_col' => 'sess_data', + 'db_time_col' => 'sess_time', + ), $dbOptions); + + $this->table = $dbOptions['db_table']; + $this->idCol = $dbOptions['db_id_col']; + $this->dataCol = $dbOptions['db_data_col']; + $this->timeCol = $dbOptions['db_time_col']; + } + + /** + * {@inheritdoc} + */ + public function open($savePath, $sessionName) + { + return true; + } + + /** + * {@inheritdoc} + */ + public function close() + { + return true; + } + + /** + * {@inheritdoc} + */ + public function destroy($sessionId) + { + // delete the record associated with this id + $sql = "DELETE FROM $this->table WHERE $this->idCol = :id"; + + try { + $stmt = $this->pdo->prepare($sql); + $stmt->bindParam(':id', $sessionId, \PDO::PARAM_STR); + $stmt->execute(); + } catch (\PDOException $e) { + throw new \RuntimeException(sprintf('PDOException was thrown when trying to delete a session: %s', $e->getMessage()), 0, $e); + } + + return true; + } + + /** + * {@inheritdoc} + */ + public function gc($maxlifetime) + { + // delete the session records that have expired + $sql = "DELETE FROM $this->table WHERE $this->timeCol < :time"; + + try { + $stmt = $this->pdo->prepare($sql); + $stmt->bindValue(':time', time() - $maxlifetime, \PDO::PARAM_INT); + $stmt->execute(); + } catch (\PDOException $e) { + throw new \RuntimeException(sprintf('PDOException was thrown when trying to delete expired sessions: %s', $e->getMessage()), 0, $e); + } + + return true; + } + + /** + * {@inheritdoc} + */ + public function read($sessionId) + { + $sql = "SELECT $this->dataCol FROM $this->table WHERE $this->idCol = :id"; + + try { + $stmt = $this->pdo->prepare($sql); + $stmt->bindParam(':id', $sessionId, \PDO::PARAM_STR); + $stmt->execute(); + + // We use fetchAll instead of fetchColumn to make sure the DB cursor gets closed + $sessionRows = $stmt->fetchAll(\PDO::FETCH_NUM); + + if ($sessionRows) { + return base64_decode($sessionRows[0][0]); + } + + return ''; + } catch (\PDOException $e) { + throw new \RuntimeException(sprintf('PDOException was thrown when trying to read the session data: %s', $e->getMessage()), 0, $e); + } + } + + /** + * {@inheritdoc} + */ + public function write($sessionId, $data) + { + $encoded = base64_encode($data); + + try { + // We use a single MERGE SQL query when supported by the database. + $mergeSql = $this->getMergeSql(); + + if (null !== $mergeSql) { + $mergeStmt = $this->pdo->prepare($mergeSql); + $mergeStmt->bindParam(':id', $sessionId, \PDO::PARAM_STR); + $mergeStmt->bindParam(':data', $encoded, \PDO::PARAM_STR); + $mergeStmt->bindValue(':time', time(), \PDO::PARAM_INT); + $mergeStmt->execute(); + + return true; + } + + $updateStmt = $this->pdo->prepare( + "UPDATE $this->table SET $this->dataCol = :data, $this->timeCol = :time WHERE $this->idCol = :id" + ); + $updateStmt->bindParam(':id', $sessionId, \PDO::PARAM_STR); + $updateStmt->bindParam(':data', $encoded, \PDO::PARAM_STR); + $updateStmt->bindValue(':time', time(), \PDO::PARAM_INT); + $updateStmt->execute(); + + // When MERGE is not supported, like in Postgres, we have to use this approach that can result in + // duplicate key errors when the same session is written simultaneously. We can just catch such an + // error and re-execute the update. This is similar to a serializable transaction with retry logic + // on serialization failures but without the overhead and without possible false positives due to + // longer gap locking. + if (!$updateStmt->rowCount()) { + try { + $insertStmt = $this->pdo->prepare( + "INSERT INTO $this->table ($this->idCol, $this->dataCol, $this->timeCol) VALUES (:id, :data, :time)" + ); + $insertStmt->bindParam(':id', $sessionId, \PDO::PARAM_STR); + $insertStmt->bindParam(':data', $encoded, \PDO::PARAM_STR); + $insertStmt->bindValue(':time', time(), \PDO::PARAM_INT); + $insertStmt->execute(); + } catch (\PDOException $e) { + // Handle integrity violation SQLSTATE 23000 (or a subclass like 23505 in Postgres) for duplicate keys + if (0 === strpos($e->getCode(), '23')) { + $updateStmt->execute(); + } else { + throw $e; + } + } + } + } catch (\PDOException $e) { + throw new \RuntimeException(sprintf('PDOException was thrown when trying to write the session data: %s', $e->getMessage()), 0, $e); + } + + return true; + } + + /** + * Returns a merge/upsert (i.e. insert or update) SQL query when supported by the database. + * + * @return string|null The SQL string or null when not supported + */ + private function getMergeSql() + { + $driver = $this->pdo->getAttribute(\PDO::ATTR_DRIVER_NAME); + + switch ($driver) { + case 'mysql': + return "INSERT INTO $this->table ($this->idCol, $this->dataCol, $this->timeCol) VALUES (:id, :data, :time) ". + "ON DUPLICATE KEY UPDATE $this->dataCol = VALUES($this->dataCol), $this->timeCol = VALUES($this->timeCol)"; + case 'oci': + // DUAL is Oracle specific dummy table + return "MERGE INTO $this->table USING DUAL ON ($this->idCol = :id) ". + "WHEN NOT MATCHED THEN INSERT ($this->idCol, $this->dataCol, $this->timeCol) VALUES (:id, :data, :time) ". + "WHEN MATCHED THEN UPDATE SET $this->dataCol = :data, $this->timeCol = :time"; + case 'sqlsrv' === $driver && version_compare($this->pdo->getAttribute(\PDO::ATTR_SERVER_VERSION), '10', '>='): + // MERGE is only available since SQL Server 2008 and must be terminated by semicolon + // It also requires HOLDLOCK according to http://weblogs.sqlteam.com/dang/archive/2009/01/31/UPSERT-Race-Condition-With-MERGE.aspx + return "MERGE INTO $this->table WITH (HOLDLOCK) USING (SELECT 1 AS dummy) AS src ON ($this->idCol = :id) ". + "WHEN NOT MATCHED THEN INSERT ($this->idCol, $this->dataCol, $this->timeCol) VALUES (:id, :data, :time) ". + "WHEN MATCHED THEN UPDATE SET $this->dataCol = :data, $this->timeCol = :time;"; + case 'sqlite': + return "INSERT OR REPLACE INTO $this->table ($this->idCol, $this->dataCol, $this->timeCol) VALUES (:id, :data, :time)"; + } + } + + /** + * Return a PDO instance. + * + * @return \PDO + */ + protected function getConnection() + { + return $this->pdo; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/Handler/MemcacheSessionHandler.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/Handler/MemcacheSessionHandler.php new file mode 100644 index 0000000..a386bdd --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/Handler/MemcacheSessionHandler.php @@ -0,0 +1,119 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Session\Storage\Handler; + +/** + * MemcacheSessionHandler. + * + * @author Drak + */ +class MemcacheSessionHandler implements \SessionHandlerInterface +{ + /** + * @var \Memcache Memcache driver + */ + private $memcache; + + /** + * @var int Time to live in seconds + */ + private $ttl; + + /** + * @var string Key prefix for shared environments + */ + private $prefix; + + /** + * Constructor. + * + * List of available options: + * * prefix: The prefix to use for the memcache keys in order to avoid collision + * * expiretime: The time to live in seconds + * + * @param \Memcache $memcache A \Memcache instance + * @param array $options An associative array of Memcache options + * + * @throws \InvalidArgumentException When unsupported options are passed + */ + public function __construct(\Memcache $memcache, array $options = array()) + { + if ($diff = array_diff(array_keys($options), array('prefix', 'expiretime'))) { + throw new \InvalidArgumentException(sprintf( + 'The following options are not supported "%s"', implode(', ', $diff) + )); + } + + $this->memcache = $memcache; + $this->ttl = isset($options['expiretime']) ? (int) $options['expiretime'] : 86400; + $this->prefix = isset($options['prefix']) ? $options['prefix'] : 'sf2s'; + } + + /** + * {@inheritdoc} + */ + public function open($savePath, $sessionName) + { + return true; + } + + /** + * {@inheritdoc} + */ + public function close() + { + return $this->memcache->close(); + } + + /** + * {@inheritdoc} + */ + public function read($sessionId) + { + return $this->memcache->get($this->prefix.$sessionId) ?: ''; + } + + /** + * {@inheritdoc} + */ + public function write($sessionId, $data) + { + return $this->memcache->set($this->prefix.$sessionId, $data, 0, time() + $this->ttl); + } + + /** + * {@inheritdoc} + */ + public function destroy($sessionId) + { + return $this->memcache->delete($this->prefix.$sessionId); + } + + /** + * {@inheritdoc} + */ + public function gc($maxlifetime) + { + // not required here because memcache will auto expire the records anyhow. + return true; + } + + /** + * Return a Memcache instance. + * + * @return \Memcache + */ + protected function getMemcache() + { + return $this->memcache; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/Handler/MemcachedSessionHandler.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/Handler/MemcachedSessionHandler.php new file mode 100644 index 0000000..76b08e2 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/Handler/MemcachedSessionHandler.php @@ -0,0 +1,125 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Session\Storage\Handler; + +/** + * MemcachedSessionHandler. + * + * Memcached based session storage handler based on the Memcached class + * provided by the PHP memcached extension. + * + * @see http://php.net/memcached + * + * @author Drak + */ +class MemcachedSessionHandler implements \SessionHandlerInterface +{ + /** + * @var \Memcached Memcached driver + */ + private $memcached; + + /** + * @var int Time to live in seconds + */ + private $ttl; + + /** + * @var string Key prefix for shared environments + */ + private $prefix; + + /** + * Constructor. + * + * List of available options: + * * prefix: The prefix to use for the memcached keys in order to avoid collision + * * expiretime: The time to live in seconds + * + * @param \Memcached $memcached A \Memcached instance + * @param array $options An associative array of Memcached options + * + * @throws \InvalidArgumentException When unsupported options are passed + */ + public function __construct(\Memcached $memcached, array $options = array()) + { + $this->memcached = $memcached; + + if ($diff = array_diff(array_keys($options), array('prefix', 'expiretime'))) { + throw new \InvalidArgumentException(sprintf( + 'The following options are not supported "%s"', implode(', ', $diff) + )); + } + + $this->ttl = isset($options['expiretime']) ? (int) $options['expiretime'] : 86400; + $this->prefix = isset($options['prefix']) ? $options['prefix'] : 'sf2s'; + } + + /** + * {@inheritdoc} + */ + public function open($savePath, $sessionName) + { + return true; + } + + /** + * {@inheritdoc} + */ + public function close() + { + return true; + } + + /** + * {@inheritdoc} + */ + public function read($sessionId) + { + return $this->memcached->get($this->prefix.$sessionId) ?: ''; + } + + /** + * {@inheritdoc} + */ + public function write($sessionId, $data) + { + return $this->memcached->set($this->prefix.$sessionId, $data, time() + $this->ttl); + } + + /** + * {@inheritdoc} + */ + public function destroy($sessionId) + { + return $this->memcached->delete($this->prefix.$sessionId); + } + + /** + * {@inheritdoc} + */ + public function gc($maxlifetime) + { + // not required here because memcached will auto expire the records anyhow. + return true; + } + + /** + * Return a Memcached instance. + * + * @return \Memcached + */ + protected function getMemcached() + { + return $this->memcached; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/Handler/MongoDbSessionHandler.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/Handler/MongoDbSessionHandler.php new file mode 100644 index 0000000..8408f00 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/Handler/MongoDbSessionHandler.php @@ -0,0 +1,232 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Session\Storage\Handler; + +/** + * MongoDB session handler. + * + * @author Markus Bachmann + */ +class MongoDbSessionHandler implements \SessionHandlerInterface +{ + /** + * @var \Mongo|\MongoClient|\MongoDB\Client + */ + private $mongo; + + /** + * @var \MongoCollection + */ + private $collection; + + /** + * @var array + */ + private $options; + + /** + * Constructor. + * + * List of available options: + * * database: The name of the database [required] + * * collection: The name of the collection [required] + * * id_field: The field name for storing the session id [default: _id] + * * data_field: The field name for storing the session data [default: data] + * * time_field: The field name for storing the timestamp [default: time] + * * expiry_field: The field name for storing the expiry-timestamp [default: expires_at] + * + * It is strongly recommended to put an index on the `expiry_field` for + * garbage-collection. Alternatively it's possible to automatically expire + * the sessions in the database as described below: + * + * A TTL collections can be used on MongoDB 2.2+ to cleanup expired sessions + * automatically. Such an index can for example look like this: + * + * db..ensureIndex( + * { "": 1 }, + * { "expireAfterSeconds": 0 } + * ) + * + * More details on: http://docs.mongodb.org/manual/tutorial/expire-data/ + * + * If you use such an index, you can drop `gc_probability` to 0 since + * no garbage-collection is required. + * + * @param \Mongo|\MongoClient|\MongoDB\Client $mongo A MongoDB\Client, MongoClient or Mongo instance + * @param array $options An associative array of field options + * + * @throws \InvalidArgumentException When MongoClient or Mongo instance not provided + * @throws \InvalidArgumentException When "database" or "collection" not provided + */ + public function __construct($mongo, array $options) + { + if (!($mongo instanceof \MongoDB\Client || $mongo instanceof \MongoClient || $mongo instanceof \Mongo)) { + throw new \InvalidArgumentException('MongoClient or Mongo instance required'); + } + + if (!isset($options['database']) || !isset($options['collection'])) { + throw new \InvalidArgumentException('You must provide the "database" and "collection" option for MongoDBSessionHandler'); + } + + $this->mongo = $mongo; + + $this->options = array_merge(array( + 'id_field' => '_id', + 'data_field' => 'data', + 'time_field' => 'time', + 'expiry_field' => 'expires_at', + ), $options); + } + + /** + * {@inheritdoc} + */ + public function open($savePath, $sessionName) + { + return true; + } + + /** + * {@inheritdoc} + */ + public function close() + { + return true; + } + + /** + * {@inheritdoc} + */ + public function destroy($sessionId) + { + $methodName = $this->mongo instanceof \MongoDB\Client ? 'deleteOne' : 'remove'; + + $this->getCollection()->$methodName(array( + $this->options['id_field'] => $sessionId, + )); + + return true; + } + + /** + * {@inheritdoc} + */ + public function gc($maxlifetime) + { + $methodName = $this->mongo instanceof \MongoDB\Client ? 'deleteOne' : 'remove'; + + $this->getCollection()->$methodName(array( + $this->options['expiry_field'] => array('$lt' => $this->createDateTime()), + )); + + return true; + } + + /** + * {@inheritdoc} + */ + public function write($sessionId, $data) + { + $expiry = $this->createDateTime(time() + (int) ini_get('session.gc_maxlifetime')); + + $fields = array( + $this->options['time_field'] => $this->createDateTime(), + $this->options['expiry_field'] => $expiry, + ); + + $options = array('upsert' => true); + + if ($this->mongo instanceof \MongoDB\Client) { + $fields[$this->options['data_field']] = new \MongoDB\BSON\Binary($data, \MongoDB\BSON\Binary::TYPE_OLD_BINARY); + } else { + $fields[$this->options['data_field']] = new \MongoBinData($data, \MongoBinData::BYTE_ARRAY); + $options['multiple'] = false; + } + + $methodName = $this->mongo instanceof \MongoDB\Client ? 'updateOne' : 'update'; + + $this->getCollection()->$methodName( + array($this->options['id_field'] => $sessionId), + array('$set' => $fields), + $options + ); + + return true; + } + + /** + * {@inheritdoc} + */ + public function read($sessionId) + { + $dbData = $this->getCollection()->findOne(array( + $this->options['id_field'] => $sessionId, + $this->options['expiry_field'] => array('$gte' => $this->createDateTime()), + )); + + if (null === $dbData) { + return ''; + } + + if ($dbData[$this->options['data_field']] instanceof \MongoDB\BSON\Binary) { + return $dbData[$this->options['data_field']]->getData(); + } + + return $dbData[$this->options['data_field']]->bin; + } + + /** + * Return a "MongoCollection" instance. + * + * @return \MongoCollection + */ + private function getCollection() + { + if (null === $this->collection) { + $this->collection = $this->mongo->selectCollection($this->options['database'], $this->options['collection']); + } + + return $this->collection; + } + + /** + * Return a Mongo instance. + * + * @return \Mongo|\MongoClient|\MongoDB\Client + */ + protected function getMongo() + { + return $this->mongo; + } + + /** + * Create a date object using the class appropriate for the current mongo connection. + * + * Return an instance of a MongoDate or \MongoDB\BSON\UTCDateTime + * + * @param int $seconds An integer representing UTC seconds since Jan 1 1970. Defaults to now. + * + * @return \MongoDate|\MongoDB\BSON\UTCDateTime + */ + private function createDateTime($seconds = null) + { + if (null === $seconds) { + $seconds = time(); + } + + if ($this->mongo instanceof \MongoDB\Client) { + return new \MongoDB\BSON\UTCDateTime($seconds * 1000); + } + + return new \MongoDate($seconds); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/Handler/NativeFileSessionHandler.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/Handler/NativeFileSessionHandler.php new file mode 100644 index 0000000..1be0a39 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/Handler/NativeFileSessionHandler.php @@ -0,0 +1,58 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Session\Storage\Handler; + +/** + * NativeFileSessionHandler. + * + * Native session handler using PHP's built in file storage. + * + * @author Drak + */ +class NativeFileSessionHandler extends NativeSessionHandler +{ + /** + * Constructor. + * + * @param string $savePath Path of directory to save session files + * Default null will leave setting as defined by PHP. + * '/path', 'N;/path', or 'N;octal-mode;/path + * + * @see http://php.net/session.configuration.php#ini.session.save-path for further details. + * + * @throws \InvalidArgumentException On invalid $savePath + */ + public function __construct($savePath = null) + { + if (null === $savePath) { + $savePath = ini_get('session.save_path'); + } + + $baseDir = $savePath; + + if ($count = substr_count($savePath, ';')) { + if ($count > 2) { + throw new \InvalidArgumentException(sprintf('Invalid argument $savePath \'%s\'', $savePath)); + } + + // characters after last ';' are the path + $baseDir = ltrim(strrchr($savePath, ';'), ';'); + } + + if ($baseDir && !is_dir($baseDir) && !@mkdir($baseDir, 0777, true) && !is_dir($baseDir)) { + throw new \RuntimeException(sprintf('Session Storage was not able to create directory "%s"', $baseDir)); + } + + ini_set('session.save_path', $savePath); + ini_set('session.save_handler', 'files'); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/Handler/NativeSessionHandler.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/Handler/NativeSessionHandler.php new file mode 100644 index 0000000..95d5cdb --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/Handler/NativeSessionHandler.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Session\Storage\Handler; + +// Adds SessionHandler functionality if available. +// @see http://php.net/sessionhandler +if (PHP_VERSION_ID >= 50400) { + class NativeSessionHandler extends \SessionHandler + { + } +} else { + class NativeSessionHandler + { + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/Handler/NullSessionHandler.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/Handler/NullSessionHandler.php new file mode 100644 index 0000000..1516d43 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/Handler/NullSessionHandler.php @@ -0,0 +1,70 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Session\Storage\Handler; + +/** + * NullSessionHandler. + * + * Can be used in unit testing or in a situations where persisted sessions are not desired. + * + * @author Drak + */ +class NullSessionHandler implements \SessionHandlerInterface +{ + /** + * {@inheritdoc} + */ + public function open($savePath, $sessionName) + { + return true; + } + + /** + * {@inheritdoc} + */ + public function close() + { + return true; + } + + /** + * {@inheritdoc} + */ + public function read($sessionId) + { + return ''; + } + + /** + * {@inheritdoc} + */ + public function write($sessionId, $data) + { + return true; + } + + /** + * {@inheritdoc} + */ + public function destroy($sessionId) + { + return true; + } + + /** + * {@inheritdoc} + */ + public function gc($maxlifetime) + { + return true; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/Handler/PdoSessionHandler.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/Handler/PdoSessionHandler.php new file mode 100644 index 0000000..8909a5f --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/Handler/PdoSessionHandler.php @@ -0,0 +1,721 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Session\Storage\Handler; + +/** + * Session handler using a PDO connection to read and write data. + * + * It works with MySQL, PostgreSQL, Oracle, SQL Server and SQLite and implements + * different locking strategies to handle concurrent access to the same session. + * Locking is necessary to prevent loss of data due to race conditions and to keep + * the session data consistent between read() and write(). With locking, requests + * for the same session will wait until the other one finished writing. For this + * reason it's best practice to close a session as early as possible to improve + * concurrency. PHPs internal files session handler also implements locking. + * + * Attention: Since SQLite does not support row level locks but locks the whole database, + * it means only one session can be accessed at a time. Even different sessions would wait + * for another to finish. So saving session in SQLite should only be considered for + * development or prototypes. + * + * Session data is a binary string that can contain non-printable characters like the null byte. + * For this reason it must be saved in a binary column in the database like BLOB in MySQL. + * Saving it in a character column could corrupt the data. You can use createTable() + * to initialize a correctly defined table. + * + * @see http://php.net/sessionhandlerinterface + * + * @author Fabien Potencier + * @author Michael Williams + * @author Tobias Schultze + */ +class PdoSessionHandler implements \SessionHandlerInterface +{ + /** + * No locking is done. This means sessions are prone to loss of data due to + * race conditions of concurrent requests to the same session. The last session + * write will win in this case. It might be useful when you implement your own + * logic to deal with this like an optimistic approach. + */ + const LOCK_NONE = 0; + + /** + * Creates an application-level lock on a session. The disadvantage is that the + * lock is not enforced by the database and thus other, unaware parts of the + * application could still concurrently modify the session. The advantage is it + * does not require a transaction. + * This mode is not available for SQLite and not yet implemented for oci and sqlsrv. + */ + const LOCK_ADVISORY = 1; + + /** + * Issues a real row lock. Since it uses a transaction between opening and + * closing a session, you have to be careful when you use same database connection + * that you also use for your application logic. This mode is the default because + * it's the only reliable solution across DBMSs. + */ + const LOCK_TRANSACTIONAL = 2; + + /** + * @var \PDO|null PDO instance or null when not connected yet + */ + private $pdo; + + /** + * @var string|null|false DSN string or null for session.save_path or false when lazy connection disabled + */ + private $dsn = false; + + /** + * @var string Database driver + */ + private $driver; + + /** + * @var string Table name + */ + private $table = 'sessions'; + + /** + * @var string Column for session id + */ + private $idCol = 'sess_id'; + + /** + * @var string Column for session data + */ + private $dataCol = 'sess_data'; + + /** + * @var string Column for lifetime + */ + private $lifetimeCol = 'sess_lifetime'; + + /** + * @var string Column for timestamp + */ + private $timeCol = 'sess_time'; + + /** + * @var string Username when lazy-connect + */ + private $username = ''; + + /** + * @var string Password when lazy-connect + */ + private $password = ''; + + /** + * @var array Connection options when lazy-connect + */ + private $connectionOptions = array(); + + /** + * @var int The strategy for locking, see constants + */ + private $lockMode = self::LOCK_TRANSACTIONAL; + + /** + * It's an array to support multiple reads before closing which is manual, non-standard usage. + * + * @var \PDOStatement[] An array of statements to release advisory locks + */ + private $unlockStatements = array(); + + /** + * @var bool True when the current session exists but expired according to session.gc_maxlifetime + */ + private $sessionExpired = false; + + /** + * @var bool Whether a transaction is active + */ + private $inTransaction = false; + + /** + * @var bool Whether gc() has been called + */ + private $gcCalled = false; + + /** + * Constructor. + * + * You can either pass an existing database connection as PDO instance or + * pass a DSN string that will be used to lazy-connect to the database + * when the session is actually used. Furthermore it's possible to pass null + * which will then use the session.save_path ini setting as PDO DSN parameter. + * + * List of available options: + * * db_table: The name of the table [default: sessions] + * * db_id_col: The column where to store the session id [default: sess_id] + * * db_data_col: The column where to store the session data [default: sess_data] + * * db_lifetime_col: The column where to store the lifetime [default: sess_lifetime] + * * db_time_col: The column where to store the timestamp [default: sess_time] + * * db_username: The username when lazy-connect [default: ''] + * * db_password: The password when lazy-connect [default: ''] + * * db_connection_options: An array of driver-specific connection options [default: array()] + * * lock_mode: The strategy for locking, see constants [default: LOCK_TRANSACTIONAL] + * + * @param \PDO|string|null $pdoOrDsn A \PDO instance or DSN string or null + * @param array $options An associative array of options + * + * @throws \InvalidArgumentException When PDO error mode is not PDO::ERRMODE_EXCEPTION + */ + public function __construct($pdoOrDsn = null, array $options = array()) + { + if ($pdoOrDsn instanceof \PDO) { + if (\PDO::ERRMODE_EXCEPTION !== $pdoOrDsn->getAttribute(\PDO::ATTR_ERRMODE)) { + throw new \InvalidArgumentException(sprintf('"%s" requires PDO error mode attribute be set to throw Exceptions (i.e. $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION))', __CLASS__)); + } + + $this->pdo = $pdoOrDsn; + $this->driver = $this->pdo->getAttribute(\PDO::ATTR_DRIVER_NAME); + } else { + $this->dsn = $pdoOrDsn; + } + + $this->table = isset($options['db_table']) ? $options['db_table'] : $this->table; + $this->idCol = isset($options['db_id_col']) ? $options['db_id_col'] : $this->idCol; + $this->dataCol = isset($options['db_data_col']) ? $options['db_data_col'] : $this->dataCol; + $this->lifetimeCol = isset($options['db_lifetime_col']) ? $options['db_lifetime_col'] : $this->lifetimeCol; + $this->timeCol = isset($options['db_time_col']) ? $options['db_time_col'] : $this->timeCol; + $this->username = isset($options['db_username']) ? $options['db_username'] : $this->username; + $this->password = isset($options['db_password']) ? $options['db_password'] : $this->password; + $this->connectionOptions = isset($options['db_connection_options']) ? $options['db_connection_options'] : $this->connectionOptions; + $this->lockMode = isset($options['lock_mode']) ? $options['lock_mode'] : $this->lockMode; + } + + /** + * Creates the table to store sessions which can be called once for setup. + * + * Session ID is saved in a column of maximum length 128 because that is enough even + * for a 512 bit configured session.hash_function like Whirlpool. Session data is + * saved in a BLOB. One could also use a shorter inlined varbinary column + * if one was sure the data fits into it. + * + * @throws \PDOException When the table already exists + * @throws \DomainException When an unsupported PDO driver is used + */ + public function createTable() + { + // connect if we are not yet + $this->getConnection(); + + switch ($this->driver) { + case 'mysql': + // We use varbinary for the ID column because it prevents unwanted conversions: + // - character set conversions between server and client + // - trailing space removal + // - case-insensitivity + // - language processing like é == e + $sql = "CREATE TABLE $this->table ($this->idCol VARBINARY(128) NOT NULL PRIMARY KEY, $this->dataCol BLOB NOT NULL, $this->lifetimeCol MEDIUMINT NOT NULL, $this->timeCol INTEGER UNSIGNED NOT NULL) COLLATE utf8_bin, ENGINE = InnoDB"; + break; + case 'sqlite': + $sql = "CREATE TABLE $this->table ($this->idCol TEXT NOT NULL PRIMARY KEY, $this->dataCol BLOB NOT NULL, $this->lifetimeCol INTEGER NOT NULL, $this->timeCol INTEGER NOT NULL)"; + break; + case 'pgsql': + $sql = "CREATE TABLE $this->table ($this->idCol VARCHAR(128) NOT NULL PRIMARY KEY, $this->dataCol BYTEA NOT NULL, $this->lifetimeCol INTEGER NOT NULL, $this->timeCol INTEGER NOT NULL)"; + break; + case 'oci': + $sql = "CREATE TABLE $this->table ($this->idCol VARCHAR2(128) NOT NULL PRIMARY KEY, $this->dataCol BLOB NOT NULL, $this->lifetimeCol INTEGER NOT NULL, $this->timeCol INTEGER NOT NULL)"; + break; + case 'sqlsrv': + $sql = "CREATE TABLE $this->table ($this->idCol VARCHAR(128) NOT NULL PRIMARY KEY, $this->dataCol VARBINARY(MAX) NOT NULL, $this->lifetimeCol INTEGER NOT NULL, $this->timeCol INTEGER NOT NULL)"; + break; + default: + throw new \DomainException(sprintf('Creating the session table is currently not implemented for PDO driver "%s".', $this->driver)); + } + + try { + $this->pdo->exec($sql); + } catch (\PDOException $e) { + $this->rollback(); + + throw $e; + } + } + + /** + * Returns true when the current session exists but expired according to session.gc_maxlifetime. + * + * Can be used to distinguish between a new session and one that expired due to inactivity. + * + * @return bool Whether current session expired + */ + public function isSessionExpired() + { + return $this->sessionExpired; + } + + /** + * {@inheritdoc} + */ + public function open($savePath, $sessionName) + { + if (null === $this->pdo) { + $this->connect($this->dsn ?: $savePath); + } + + return true; + } + + /** + * {@inheritdoc} + */ + public function read($sessionId) + { + try { + return $this->doRead($sessionId); + } catch (\PDOException $e) { + $this->rollback(); + + throw $e; + } + } + + /** + * {@inheritdoc} + */ + public function gc($maxlifetime) + { + // We delay gc() to close() so that it is executed outside the transactional and blocking read-write process. + // This way, pruning expired sessions does not block them from being started while the current session is used. + $this->gcCalled = true; + + return true; + } + + /** + * {@inheritdoc} + */ + public function destroy($sessionId) + { + // delete the record associated with this id + $sql = "DELETE FROM $this->table WHERE $this->idCol = :id"; + + try { + $stmt = $this->pdo->prepare($sql); + $stmt->bindParam(':id', $sessionId, \PDO::PARAM_STR); + $stmt->execute(); + } catch (\PDOException $e) { + $this->rollback(); + + throw $e; + } + + return true; + } + + /** + * {@inheritdoc} + */ + public function write($sessionId, $data) + { + $maxlifetime = (int) ini_get('session.gc_maxlifetime'); + + try { + // We use a single MERGE SQL query when supported by the database. + $mergeStmt = $this->getMergeStatement($sessionId, $data, $maxlifetime); + if (null !== $mergeStmt) { + $mergeStmt->execute(); + + return true; + } + + $updateStmt = $this->pdo->prepare( + "UPDATE $this->table SET $this->dataCol = :data, $this->lifetimeCol = :lifetime, $this->timeCol = :time WHERE $this->idCol = :id" + ); + $updateStmt->bindParam(':id', $sessionId, \PDO::PARAM_STR); + $updateStmt->bindParam(':data', $data, \PDO::PARAM_LOB); + $updateStmt->bindParam(':lifetime', $maxlifetime, \PDO::PARAM_INT); + $updateStmt->bindValue(':time', time(), \PDO::PARAM_INT); + $updateStmt->execute(); + + // When MERGE is not supported, like in Postgres < 9.5, we have to use this approach that can result in + // duplicate key errors when the same session is written simultaneously (given the LOCK_NONE behavior). + // We can just catch such an error and re-execute the update. This is similar to a serializable + // transaction with retry logic on serialization failures but without the overhead and without possible + // false positives due to longer gap locking. + if (!$updateStmt->rowCount()) { + try { + $insertStmt = $this->pdo->prepare( + "INSERT INTO $this->table ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (:id, :data, :lifetime, :time)" + ); + $insertStmt->bindParam(':id', $sessionId, \PDO::PARAM_STR); + $insertStmt->bindParam(':data', $data, \PDO::PARAM_LOB); + $insertStmt->bindParam(':lifetime', $maxlifetime, \PDO::PARAM_INT); + $insertStmt->bindValue(':time', time(), \PDO::PARAM_INT); + $insertStmt->execute(); + } catch (\PDOException $e) { + // Handle integrity violation SQLSTATE 23000 (or a subclass like 23505 in Postgres) for duplicate keys + if (0 === strpos($e->getCode(), '23')) { + $updateStmt->execute(); + } else { + throw $e; + } + } + } + } catch (\PDOException $e) { + $this->rollback(); + + throw $e; + } + + return true; + } + + /** + * {@inheritdoc} + */ + public function close() + { + $this->commit(); + + while ($unlockStmt = array_shift($this->unlockStatements)) { + $unlockStmt->execute(); + } + + if ($this->gcCalled) { + $this->gcCalled = false; + + // delete the session records that have expired + $sql = "DELETE FROM $this->table WHERE $this->lifetimeCol + $this->timeCol < :time"; + + $stmt = $this->pdo->prepare($sql); + $stmt->bindValue(':time', time(), \PDO::PARAM_INT); + $stmt->execute(); + } + + if (false !== $this->dsn) { + $this->pdo = null; // only close lazy-connection + } + + return true; + } + + /** + * Lazy-connects to the database. + * + * @param string $dsn DSN string + */ + private function connect($dsn) + { + $this->pdo = new \PDO($dsn, $this->username, $this->password, $this->connectionOptions); + $this->pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); + $this->driver = $this->pdo->getAttribute(\PDO::ATTR_DRIVER_NAME); + } + + /** + * Helper method to begin a transaction. + * + * Since SQLite does not support row level locks, we have to acquire a reserved lock + * on the database immediately. Because of https://bugs.php.net/42766 we have to create + * such a transaction manually which also means we cannot use PDO::commit or + * PDO::rollback or PDO::inTransaction for SQLite. + * + * Also MySQLs default isolation, REPEATABLE READ, causes deadlock for different sessions + * due to http://www.mysqlperformanceblog.com/2013/12/12/one-more-innodb-gap-lock-to-avoid/ . + * So we change it to READ COMMITTED. + */ + private function beginTransaction() + { + if (!$this->inTransaction) { + if ('sqlite' === $this->driver) { + $this->pdo->exec('BEGIN IMMEDIATE TRANSACTION'); + } else { + if ('mysql' === $this->driver) { + $this->pdo->exec('SET TRANSACTION ISOLATION LEVEL READ COMMITTED'); + } + $this->pdo->beginTransaction(); + } + $this->inTransaction = true; + } + } + + /** + * Helper method to commit a transaction. + */ + private function commit() + { + if ($this->inTransaction) { + try { + // commit read-write transaction which also releases the lock + if ('sqlite' === $this->driver) { + $this->pdo->exec('COMMIT'); + } else { + $this->pdo->commit(); + } + $this->inTransaction = false; + } catch (\PDOException $e) { + $this->rollback(); + + throw $e; + } + } + } + + /** + * Helper method to rollback a transaction. + */ + private function rollback() + { + // We only need to rollback if we are in a transaction. Otherwise the resulting + // error would hide the real problem why rollback was called. We might not be + // in a transaction when not using the transactional locking behavior or when + // two callbacks (e.g. destroy and write) are invoked that both fail. + if ($this->inTransaction) { + if ('sqlite' === $this->driver) { + $this->pdo->exec('ROLLBACK'); + } else { + $this->pdo->rollBack(); + } + $this->inTransaction = false; + } + } + + /** + * Reads the session data in respect to the different locking strategies. + * + * We need to make sure we do not return session data that is already considered garbage according + * to the session.gc_maxlifetime setting because gc() is called after read() and only sometimes. + * + * @param string $sessionId Session ID + * + * @return string The session data + */ + private function doRead($sessionId) + { + $this->sessionExpired = false; + + if (self::LOCK_ADVISORY === $this->lockMode) { + $this->unlockStatements[] = $this->doAdvisoryLock($sessionId); + } + + $selectSql = $this->getSelectSql(); + $selectStmt = $this->pdo->prepare($selectSql); + $selectStmt->bindParam(':id', $sessionId, \PDO::PARAM_STR); + + do { + $selectStmt->execute(); + $sessionRows = $selectStmt->fetchAll(\PDO::FETCH_NUM); + + if ($sessionRows) { + if ($sessionRows[0][1] + $sessionRows[0][2] < time()) { + $this->sessionExpired = true; + + return ''; + } + + return is_resource($sessionRows[0][0]) ? stream_get_contents($sessionRows[0][0]) : $sessionRows[0][0]; + } + + if (self::LOCK_TRANSACTIONAL === $this->lockMode && 'sqlite' !== $this->driver) { + // Exclusive-reading of non-existent rows does not block, so we need to do an insert to block + // until other connections to the session are committed. + try { + $insertStmt = $this->pdo->prepare( + "INSERT INTO $this->table ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (:id, :data, :lifetime, :time)" + ); + $insertStmt->bindParam(':id', $sessionId, \PDO::PARAM_STR); + $insertStmt->bindValue(':data', '', \PDO::PARAM_LOB); + $insertStmt->bindValue(':lifetime', 0, \PDO::PARAM_INT); + $insertStmt->bindValue(':time', time(), \PDO::PARAM_INT); + $insertStmt->execute(); + } catch (\PDOException $e) { + // Catch duplicate key error because other connection created the session already. + // It would only not be the case when the other connection destroyed the session. + if (0 === strpos($e->getCode(), '23')) { + // Retrieve finished session data written by concurrent connection by restarting the loop. + // We have to start a new transaction as a failed query will mark the current transaction as + // aborted in PostgreSQL and disallow further queries within it. + $this->rollback(); + $this->beginTransaction(); + continue; + } + + throw $e; + } + } + + return ''; + } while (true); + } + + /** + * Executes an application-level lock on the database. + * + * @param string $sessionId Session ID + * + * @return \PDOStatement The statement that needs to be executed later to release the lock + * + * @throws \DomainException When an unsupported PDO driver is used + * + * @todo implement missing advisory locks + * - for oci using DBMS_LOCK.REQUEST + * - for sqlsrv using sp_getapplock with LockOwner = Session + */ + private function doAdvisoryLock($sessionId) + { + switch ($this->driver) { + case 'mysql': + // should we handle the return value? 0 on timeout, null on error + // we use a timeout of 50 seconds which is also the default for innodb_lock_wait_timeout + $stmt = $this->pdo->prepare('SELECT GET_LOCK(:key, 50)'); + $stmt->bindValue(':key', $sessionId, \PDO::PARAM_STR); + $stmt->execute(); + + $releaseStmt = $this->pdo->prepare('DO RELEASE_LOCK(:key)'); + $releaseStmt->bindValue(':key', $sessionId, \PDO::PARAM_STR); + + return $releaseStmt; + case 'pgsql': + // Obtaining an exclusive session level advisory lock requires an integer key. + // So we convert the HEX representation of the session id to an integer. + // Since integers are signed, we have to skip one hex char to fit in the range. + if (4 === PHP_INT_SIZE) { + $sessionInt1 = hexdec(substr($sessionId, 0, 7)); + $sessionInt2 = hexdec(substr($sessionId, 7, 7)); + + $stmt = $this->pdo->prepare('SELECT pg_advisory_lock(:key1, :key2)'); + $stmt->bindValue(':key1', $sessionInt1, \PDO::PARAM_INT); + $stmt->bindValue(':key2', $sessionInt2, \PDO::PARAM_INT); + $stmt->execute(); + + $releaseStmt = $this->pdo->prepare('SELECT pg_advisory_unlock(:key1, :key2)'); + $releaseStmt->bindValue(':key1', $sessionInt1, \PDO::PARAM_INT); + $releaseStmt->bindValue(':key2', $sessionInt2, \PDO::PARAM_INT); + } else { + $sessionBigInt = hexdec(substr($sessionId, 0, 15)); + + $stmt = $this->pdo->prepare('SELECT pg_advisory_lock(:key)'); + $stmt->bindValue(':key', $sessionBigInt, \PDO::PARAM_INT); + $stmt->execute(); + + $releaseStmt = $this->pdo->prepare('SELECT pg_advisory_unlock(:key)'); + $releaseStmt->bindValue(':key', $sessionBigInt, \PDO::PARAM_INT); + } + + return $releaseStmt; + case 'sqlite': + throw new \DomainException('SQLite does not support advisory locks.'); + default: + throw new \DomainException(sprintf('Advisory locks are currently not implemented for PDO driver "%s".', $this->driver)); + } + } + + /** + * Return a locking or nonlocking SQL query to read session information. + * + * @return string The SQL string + * + * @throws \DomainException When an unsupported PDO driver is used + */ + private function getSelectSql() + { + if (self::LOCK_TRANSACTIONAL === $this->lockMode) { + $this->beginTransaction(); + + switch ($this->driver) { + case 'mysql': + case 'oci': + case 'pgsql': + return "SELECT $this->dataCol, $this->lifetimeCol, $this->timeCol FROM $this->table WHERE $this->idCol = :id FOR UPDATE"; + case 'sqlsrv': + return "SELECT $this->dataCol, $this->lifetimeCol, $this->timeCol FROM $this->table WITH (UPDLOCK, ROWLOCK) WHERE $this->idCol = :id"; + case 'sqlite': + // we already locked when starting transaction + break; + default: + throw new \DomainException(sprintf('Transactional locks are currently not implemented for PDO driver "%s".', $this->driver)); + } + } + + return "SELECT $this->dataCol, $this->lifetimeCol, $this->timeCol FROM $this->table WHERE $this->idCol = :id"; + } + + /** + * Returns a merge/upsert (i.e. insert or update) statement when supported by the database for writing session data. + * + * @param string $sessionId Session ID + * @param string $data Encoded session data + * @param int $maxlifetime session.gc_maxlifetime + * + * @return \PDOStatement|null The merge statement or null when not supported + */ + private function getMergeStatement($sessionId, $data, $maxlifetime) + { + $mergeSql = null; + switch (true) { + case 'mysql' === $this->driver: + $mergeSql = "INSERT INTO $this->table ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (:id, :data, :lifetime, :time) ". + "ON DUPLICATE KEY UPDATE $this->dataCol = VALUES($this->dataCol), $this->lifetimeCol = VALUES($this->lifetimeCol), $this->timeCol = VALUES($this->timeCol)"; + break; + case 'oci' === $this->driver: + // DUAL is Oracle specific dummy table + $mergeSql = "MERGE INTO $this->table USING DUAL ON ($this->idCol = ?) ". + "WHEN NOT MATCHED THEN INSERT ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (?, ?, ?, ?) ". + "WHEN MATCHED THEN UPDATE SET $this->dataCol = ?, $this->lifetimeCol = ?, $this->timeCol = ?"; + break; + case 'sqlsrv' === $this->driver && version_compare($this->pdo->getAttribute(\PDO::ATTR_SERVER_VERSION), '10', '>='): + // MERGE is only available since SQL Server 2008 and must be terminated by semicolon + // It also requires HOLDLOCK according to http://weblogs.sqlteam.com/dang/archive/2009/01/31/UPSERT-Race-Condition-With-MERGE.aspx + $mergeSql = "MERGE INTO $this->table WITH (HOLDLOCK) USING (SELECT 1 AS dummy) AS src ON ($this->idCol = ?) ". + "WHEN NOT MATCHED THEN INSERT ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (?, ?, ?, ?) ". + "WHEN MATCHED THEN UPDATE SET $this->dataCol = ?, $this->lifetimeCol = ?, $this->timeCol = ?;"; + break; + case 'sqlite' === $this->driver: + $mergeSql = "INSERT OR REPLACE INTO $this->table ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (:id, :data, :lifetime, :time)"; + break; + case 'pgsql' === $this->driver && version_compare($this->pdo->getAttribute(\PDO::ATTR_SERVER_VERSION), '9.5', '>='): + $mergeSql = "INSERT INTO $this->table ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (:id, :data, :lifetime, :time) ". + "ON CONFLICT ($this->idCol) DO UPDATE SET ($this->dataCol, $this->lifetimeCol, $this->timeCol) = (EXCLUDED.$this->dataCol, EXCLUDED.$this->lifetimeCol, EXCLUDED.$this->timeCol)"; + break; + } + + if (null !== $mergeSql) { + $mergeStmt = $this->pdo->prepare($mergeSql); + + if ('sqlsrv' === $this->driver || 'oci' === $this->driver) { + $mergeStmt->bindParam(1, $sessionId, \PDO::PARAM_STR); + $mergeStmt->bindParam(2, $sessionId, \PDO::PARAM_STR); + $mergeStmt->bindParam(3, $data, \PDO::PARAM_LOB); + $mergeStmt->bindParam(4, $maxlifetime, \PDO::PARAM_INT); + $mergeStmt->bindValue(5, time(), \PDO::PARAM_INT); + $mergeStmt->bindParam(6, $data, \PDO::PARAM_LOB); + $mergeStmt->bindParam(7, $maxlifetime, \PDO::PARAM_INT); + $mergeStmt->bindValue(8, time(), \PDO::PARAM_INT); + } else { + $mergeStmt->bindParam(':id', $sessionId, \PDO::PARAM_STR); + $mergeStmt->bindParam(':data', $data, \PDO::PARAM_LOB); + $mergeStmt->bindParam(':lifetime', $maxlifetime, \PDO::PARAM_INT); + $mergeStmt->bindValue(':time', time(), \PDO::PARAM_INT); + } + + return $mergeStmt; + } + } + + /** + * Return a PDO instance. + * + * @return \PDO + */ + protected function getConnection() + { + if (null === $this->pdo) { + $this->connect($this->dsn ?: ini_get('session.save_path')); + } + + return $this->pdo; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/Handler/WriteCheckSessionHandler.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/Handler/WriteCheckSessionHandler.php new file mode 100644 index 0000000..d49c36c --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/Handler/WriteCheckSessionHandler.php @@ -0,0 +1,91 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Session\Storage\Handler; + +/** + * Wraps another SessionHandlerInterface to only write the session when it has been modified. + * + * @author Adrien Brault + */ +class WriteCheckSessionHandler implements \SessionHandlerInterface +{ + /** + * @var \SessionHandlerInterface + */ + private $wrappedSessionHandler; + + /** + * @var array sessionId => session + */ + private $readSessions; + + public function __construct(\SessionHandlerInterface $wrappedSessionHandler) + { + $this->wrappedSessionHandler = $wrappedSessionHandler; + } + + /** + * {@inheritdoc} + */ + public function close() + { + return $this->wrappedSessionHandler->close(); + } + + /** + * {@inheritdoc} + */ + public function destroy($sessionId) + { + return $this->wrappedSessionHandler->destroy($sessionId); + } + + /** + * {@inheritdoc} + */ + public function gc($maxlifetime) + { + return $this->wrappedSessionHandler->gc($maxlifetime); + } + + /** + * {@inheritdoc} + */ + public function open($savePath, $sessionName) + { + return $this->wrappedSessionHandler->open($savePath, $sessionName); + } + + /** + * {@inheritdoc} + */ + public function read($sessionId) + { + $session = $this->wrappedSessionHandler->read($sessionId); + + $this->readSessions[$sessionId] = $session; + + return $session; + } + + /** + * {@inheritdoc} + */ + public function write($sessionId, $data) + { + if (isset($this->readSessions[$sessionId]) && $data === $this->readSessions[$sessionId]) { + return true; + } + + return $this->wrappedSessionHandler->write($sessionId, $data); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/MetadataBag.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/MetadataBag.php new file mode 100644 index 0000000..322dd56 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/MetadataBag.php @@ -0,0 +1,170 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Session\Storage; + +use Symfony\Component\HttpFoundation\Session\SessionBagInterface; + +/** + * Metadata container. + * + * Adds metadata to the session. + * + * @author Drak + */ +class MetadataBag implements SessionBagInterface +{ + const CREATED = 'c'; + const UPDATED = 'u'; + const LIFETIME = 'l'; + + /** + * @var string + */ + private $name = '__metadata'; + + /** + * @var string + */ + private $storageKey; + + /** + * @var array + */ + protected $meta = array(self::CREATED => 0, self::UPDATED => 0, self::LIFETIME => 0); + + /** + * Unix timestamp. + * + * @var int + */ + private $lastUsed; + + /** + * @var int + */ + private $updateThreshold; + + /** + * Constructor. + * + * @param string $storageKey The key used to store bag in the session + * @param int $updateThreshold The time to wait between two UPDATED updates + */ + public function __construct($storageKey = '_sf2_meta', $updateThreshold = 0) + { + $this->storageKey = $storageKey; + $this->updateThreshold = $updateThreshold; + } + + /** + * {@inheritdoc} + */ + public function initialize(array &$array) + { + $this->meta = &$array; + + if (isset($array[self::CREATED])) { + $this->lastUsed = $this->meta[self::UPDATED]; + + $timeStamp = time(); + if ($timeStamp - $array[self::UPDATED] >= $this->updateThreshold) { + $this->meta[self::UPDATED] = $timeStamp; + } + } else { + $this->stampCreated(); + } + } + + /** + * Gets the lifetime that the session cookie was set with. + * + * @return int + */ + public function getLifetime() + { + return $this->meta[self::LIFETIME]; + } + + /** + * Stamps a new session's metadata. + * + * @param int $lifetime Sets the cookie lifetime for the session cookie. A null value + * will leave the system settings unchanged, 0 sets the cookie + * to expire with browser session. Time is in seconds, and is + * not a Unix timestamp. + */ + public function stampNew($lifetime = null) + { + $this->stampCreated($lifetime); + } + + /** + * {@inheritdoc} + */ + public function getStorageKey() + { + return $this->storageKey; + } + + /** + * Gets the created timestamp metadata. + * + * @return int Unix timestamp + */ + public function getCreated() + { + return $this->meta[self::CREATED]; + } + + /** + * Gets the last used metadata. + * + * @return int Unix timestamp + */ + public function getLastUsed() + { + return $this->lastUsed; + } + + /** + * {@inheritdoc} + */ + public function clear() + { + // nothing to do + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return $this->name; + } + + /** + * Sets name. + * + * @param string $name + */ + public function setName($name) + { + $this->name = $name; + } + + private function stampCreated($lifetime = null) + { + $timeStamp = time(); + $this->meta[self::CREATED] = $this->meta[self::UPDATED] = $this->lastUsed = $timeStamp; + $this->meta[self::LIFETIME] = (null === $lifetime) ? ini_get('session.cookie_lifetime') : $lifetime; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/MockArraySessionStorage.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/MockArraySessionStorage.php new file mode 100644 index 0000000..c26cc13 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/MockArraySessionStorage.php @@ -0,0 +1,268 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Session\Storage; + +use Symfony\Component\HttpFoundation\Session\SessionBagInterface; + +/** + * MockArraySessionStorage mocks the session for unit tests. + * + * No PHP session is actually started since a session can be initialized + * and shutdown only once per PHP execution cycle. + * + * When doing functional testing, you should use MockFileSessionStorage instead. + * + * @author Fabien Potencier + * @author Bulat Shakirzyanov + * @author Drak + */ +class MockArraySessionStorage implements SessionStorageInterface +{ + /** + * @var string + */ + protected $id = ''; + + /** + * @var string + */ + protected $name; + + /** + * @var bool + */ + protected $started = false; + + /** + * @var bool + */ + protected $closed = false; + + /** + * @var array + */ + protected $data = array(); + + /** + * @var MetadataBag + */ + protected $metadataBag; + + /** + * @var array + */ + protected $bags; + + /** + * Constructor. + * + * @param string $name Session name + * @param MetadataBag $metaBag MetadataBag instance + */ + public function __construct($name = 'MOCKSESSID', MetadataBag $metaBag = null) + { + $this->name = $name; + $this->setMetadataBag($metaBag); + } + + /** + * Sets the session data. + * + * @param array $array + */ + public function setSessionData(array $array) + { + $this->data = $array; + } + + /** + * {@inheritdoc} + */ + public function start() + { + if ($this->started) { + return true; + } + + if (empty($this->id)) { + $this->id = $this->generateId(); + } + + $this->loadSession(); + + return true; + } + + /** + * {@inheritdoc} + */ + public function regenerate($destroy = false, $lifetime = null) + { + if (!$this->started) { + $this->start(); + } + + $this->metadataBag->stampNew($lifetime); + $this->id = $this->generateId(); + + return true; + } + + /** + * {@inheritdoc} + */ + public function getId() + { + return $this->id; + } + + /** + * {@inheritdoc} + */ + public function setId($id) + { + if ($this->started) { + throw new \LogicException('Cannot set session ID after the session has started.'); + } + + $this->id = $id; + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return $this->name; + } + + /** + * {@inheritdoc} + */ + public function setName($name) + { + $this->name = $name; + } + + /** + * {@inheritdoc} + */ + public function save() + { + if (!$this->started || $this->closed) { + throw new \RuntimeException('Trying to save a session that was not started yet or was already closed'); + } + // nothing to do since we don't persist the session data + $this->closed = false; + $this->started = false; + } + + /** + * {@inheritdoc} + */ + public function clear() + { + // clear out the bags + foreach ($this->bags as $bag) { + $bag->clear(); + } + + // clear out the session + $this->data = array(); + + // reconnect the bags to the session + $this->loadSession(); + } + + /** + * {@inheritdoc} + */ + public function registerBag(SessionBagInterface $bag) + { + $this->bags[$bag->getName()] = $bag; + } + + /** + * {@inheritdoc} + */ + public function getBag($name) + { + if (!isset($this->bags[$name])) { + throw new \InvalidArgumentException(sprintf('The SessionBagInterface %s is not registered.', $name)); + } + + if (!$this->started) { + $this->start(); + } + + return $this->bags[$name]; + } + + /** + * {@inheritdoc} + */ + public function isStarted() + { + return $this->started; + } + + /** + * Sets the MetadataBag. + * + * @param MetadataBag $bag + */ + public function setMetadataBag(MetadataBag $bag = null) + { + if (null === $bag) { + $bag = new MetadataBag(); + } + + $this->metadataBag = $bag; + } + + /** + * Gets the MetadataBag. + * + * @return MetadataBag + */ + public function getMetadataBag() + { + return $this->metadataBag; + } + + /** + * Generates a session ID. + * + * This doesn't need to be particularly cryptographically secure since this is just + * a mock. + * + * @return string + */ + protected function generateId() + { + return hash('sha256', uniqid('ss_mock_', true)); + } + + protected function loadSession() + { + $bags = array_merge($this->bags, array($this->metadataBag)); + + foreach ($bags as $bag) { + $key = $bag->getStorageKey(); + $this->data[$key] = isset($this->data[$key]) ? $this->data[$key] : array(); + $bag->initialize($this->data[$key]); + } + + $this->started = true; + $this->closed = false; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/MockFileSessionStorage.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/MockFileSessionStorage.php new file mode 100644 index 0000000..71f9e55 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/MockFileSessionStorage.php @@ -0,0 +1,138 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Session\Storage; + +/** + * MockFileSessionStorage is used to mock sessions for + * functional testing when done in a single PHP process. + * + * No PHP session is actually started since a session can be initialized + * and shutdown only once per PHP execution cycle and this class does + * not pollute any session related globals, including session_*() functions + * or session.* PHP ini directives. + * + * @author Drak + */ +class MockFileSessionStorage extends MockArraySessionStorage +{ + /** + * @var string + */ + private $savePath; + + /** + * Constructor. + * + * @param string $savePath Path of directory to save session files + * @param string $name Session name + * @param MetadataBag $metaBag MetadataBag instance + */ + public function __construct($savePath = null, $name = 'MOCKSESSID', MetadataBag $metaBag = null) + { + if (null === $savePath) { + $savePath = sys_get_temp_dir(); + } + + if (!is_dir($savePath) && !@mkdir($savePath, 0777, true) && !is_dir($savePath)) { + throw new \RuntimeException(sprintf('Session Storage was not able to create directory "%s"', $savePath)); + } + + $this->savePath = $savePath; + + parent::__construct($name, $metaBag); + } + + /** + * {@inheritdoc} + */ + public function start() + { + if ($this->started) { + return true; + } + + if (!$this->id) { + $this->id = $this->generateId(); + } + + $this->read(); + + $this->started = true; + + return true; + } + + /** + * {@inheritdoc} + */ + public function regenerate($destroy = false, $lifetime = null) + { + if (!$this->started) { + $this->start(); + } + + if ($destroy) { + $this->destroy(); + } + + return parent::regenerate($destroy, $lifetime); + } + + /** + * {@inheritdoc} + */ + public function save() + { + if (!$this->started) { + throw new \RuntimeException('Trying to save a session that was not started yet or was already closed'); + } + + file_put_contents($this->getFilePath(), serialize($this->data)); + + // this is needed for Silex, where the session object is re-used across requests + // in functional tests. In Symfony, the container is rebooted, so we don't have + // this issue + $this->started = false; + } + + /** + * Deletes a session from persistent storage. + * Deliberately leaves session data in memory intact. + */ + private function destroy() + { + if (is_file($this->getFilePath())) { + unlink($this->getFilePath()); + } + } + + /** + * Calculate path to file. + * + * @return string File path + */ + private function getFilePath() + { + return $this->savePath.'/'.$this->id.'.mocksess'; + } + + /** + * Reads session from storage and loads session. + */ + private function read() + { + $filePath = $this->getFilePath(); + $this->data = is_readable($filePath) && is_file($filePath) ? unserialize(file_get_contents($filePath)) : array(); + + $this->loadSession(); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php new file mode 100644 index 0000000..32979e8 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php @@ -0,0 +1,434 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Session\Storage; + +use Symfony\Component\HttpFoundation\Session\SessionBagInterface; +use Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeSessionHandler; +use Symfony\Component\HttpFoundation\Session\Storage\Proxy\NativeProxy; +use Symfony\Component\HttpFoundation\Session\Storage\Proxy\AbstractProxy; +use Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy; + +/** + * This provides a base class for session attribute storage. + * + * @author Drak + */ +class NativeSessionStorage implements SessionStorageInterface +{ + /** + * Array of SessionBagInterface. + * + * @var SessionBagInterface[] + */ + protected $bags; + + /** + * @var bool + */ + protected $started = false; + + /** + * @var bool + */ + protected $closed = false; + + /** + * @var AbstractProxy + */ + protected $saveHandler; + + /** + * @var MetadataBag + */ + protected $metadataBag; + + /** + * Constructor. + * + * Depending on how you want the storage driver to behave you probably + * want to override this constructor entirely. + * + * List of options for $options array with their defaults. + * + * @see http://php.net/session.configuration for options + * but we omit 'session.' from the beginning of the keys for convenience. + * + * ("auto_start", is not supported as it tells PHP to start a session before + * PHP starts to execute user-land code. Setting during runtime has no effect). + * + * cache_limiter, "" (use "0" to prevent headers from being sent entirely). + * cookie_domain, "" + * cookie_httponly, "" + * cookie_lifetime, "0" + * cookie_path, "/" + * cookie_secure, "" + * entropy_file, "" + * entropy_length, "0" + * gc_divisor, "100" + * gc_maxlifetime, "1440" + * gc_probability, "1" + * hash_bits_per_character, "4" + * hash_function, "0" + * name, "PHPSESSID" + * referer_check, "" + * serialize_handler, "php" + * use_cookies, "1" + * use_only_cookies, "1" + * use_trans_sid, "0" + * upload_progress.enabled, "1" + * upload_progress.cleanup, "1" + * upload_progress.prefix, "upload_progress_" + * upload_progress.name, "PHP_SESSION_UPLOAD_PROGRESS" + * upload_progress.freq, "1%" + * upload_progress.min-freq, "1" + * url_rewriter.tags, "a=href,area=href,frame=src,form=,fieldset=" + * + * @param array $options Session configuration options + * @param AbstractProxy|NativeSessionHandler|\SessionHandlerInterface|null $handler + * @param MetadataBag $metaBag MetadataBag + */ + public function __construct(array $options = array(), $handler = null, MetadataBag $metaBag = null) + { + session_cache_limiter(''); // disable by default because it's managed by HeaderBag (if used) + ini_set('session.use_cookies', 1); + + if (PHP_VERSION_ID >= 50400) { + session_register_shutdown(); + } else { + register_shutdown_function('session_write_close'); + } + + $this->setMetadataBag($metaBag); + $this->setOptions($options); + $this->setSaveHandler($handler); + } + + /** + * Gets the save handler instance. + * + * @return AbstractProxy + */ + public function getSaveHandler() + { + return $this->saveHandler; + } + + /** + * {@inheritdoc} + */ + public function start() + { + if ($this->started) { + return true; + } + + if (PHP_VERSION_ID >= 50400 && \PHP_SESSION_ACTIVE === session_status()) { + throw new \RuntimeException('Failed to start the session: already started by PHP.'); + } + + if (PHP_VERSION_ID < 50400 && !$this->closed && isset($_SESSION) && session_id()) { + // not 100% fool-proof, but is the most reliable way to determine if a session is active in PHP 5.3 + throw new \RuntimeException('Failed to start the session: already started by PHP ($_SESSION is set).'); + } + + if (ini_get('session.use_cookies') && headers_sent($file, $line)) { + throw new \RuntimeException(sprintf('Failed to start the session because headers have already been sent by "%s" at line %d.', $file, $line)); + } + + // ok to try and start the session + if (!session_start()) { + throw new \RuntimeException('Failed to start the session'); + } + + $this->loadSession(); + if (!$this->saveHandler->isWrapper() && !$this->saveHandler->isSessionHandlerInterface()) { + // This condition matches only PHP 5.3 with internal save handlers + $this->saveHandler->setActive(true); + } + + return true; + } + + /** + * {@inheritdoc} + */ + public function getId() + { + return $this->saveHandler->getId(); + } + + /** + * {@inheritdoc} + */ + public function setId($id) + { + $this->saveHandler->setId($id); + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return $this->saveHandler->getName(); + } + + /** + * {@inheritdoc} + */ + public function setName($name) + { + $this->saveHandler->setName($name); + } + + /** + * {@inheritdoc} + */ + public function regenerate($destroy = false, $lifetime = null) + { + // Cannot regenerate the session ID for non-active sessions. + if (PHP_VERSION_ID >= 50400 && \PHP_SESSION_ACTIVE !== session_status()) { + return false; + } + + // Check if session ID exists in PHP 5.3 + if (PHP_VERSION_ID < 50400 && '' === session_id()) { + return false; + } + + if (null !== $lifetime) { + ini_set('session.cookie_lifetime', $lifetime); + } + + if ($destroy) { + $this->metadataBag->stampNew(); + } + + $isRegenerated = session_regenerate_id($destroy); + + // The reference to $_SESSION in session bags is lost in PHP7 and we need to re-create it. + // @see https://bugs.php.net/bug.php?id=70013 + $this->loadSession(); + + return $isRegenerated; + } + + /** + * {@inheritdoc} + */ + public function save() + { + session_write_close(); + + if (!$this->saveHandler->isWrapper() && !$this->saveHandler->isSessionHandlerInterface()) { + // This condition matches only PHP 5.3 with internal save handlers + $this->saveHandler->setActive(false); + } + + $this->closed = true; + $this->started = false; + } + + /** + * {@inheritdoc} + */ + public function clear() + { + // clear out the bags + foreach ($this->bags as $bag) { + $bag->clear(); + } + + // clear out the session + $_SESSION = array(); + + // reconnect the bags to the session + $this->loadSession(); + } + + /** + * {@inheritdoc} + */ + public function registerBag(SessionBagInterface $bag) + { + if ($this->started) { + throw new \LogicException('Cannot register a bag when the session is already started.'); + } + + $this->bags[$bag->getName()] = $bag; + } + + /** + * {@inheritdoc} + */ + public function getBag($name) + { + if (!isset($this->bags[$name])) { + throw new \InvalidArgumentException(sprintf('The SessionBagInterface %s is not registered.', $name)); + } + + if ($this->saveHandler->isActive() && !$this->started) { + $this->loadSession(); + } elseif (!$this->started) { + $this->start(); + } + + return $this->bags[$name]; + } + + /** + * Sets the MetadataBag. + * + * @param MetadataBag $metaBag + */ + public function setMetadataBag(MetadataBag $metaBag = null) + { + if (null === $metaBag) { + $metaBag = new MetadataBag(); + } + + $this->metadataBag = $metaBag; + } + + /** + * Gets the MetadataBag. + * + * @return MetadataBag + */ + public function getMetadataBag() + { + return $this->metadataBag; + } + + /** + * {@inheritdoc} + */ + public function isStarted() + { + return $this->started; + } + + /** + * Sets session.* ini variables. + * + * For convenience we omit 'session.' from the beginning of the keys. + * Explicitly ignores other ini keys. + * + * @param array $options Session ini directives array(key => value) + * + * @see http://php.net/session.configuration + */ + public function setOptions(array $options) + { + $validOptions = array_flip(array( + 'cache_limiter', 'cookie_domain', 'cookie_httponly', + 'cookie_lifetime', 'cookie_path', 'cookie_secure', + 'entropy_file', 'entropy_length', 'gc_divisor', + 'gc_maxlifetime', 'gc_probability', 'hash_bits_per_character', + 'hash_function', 'name', 'referer_check', + 'serialize_handler', 'use_cookies', + 'use_only_cookies', 'use_trans_sid', 'upload_progress.enabled', + 'upload_progress.cleanup', 'upload_progress.prefix', 'upload_progress.name', + 'upload_progress.freq', 'upload_progress.min-freq', 'url_rewriter.tags', + )); + + foreach ($options as $key => $value) { + if (isset($validOptions[$key])) { + ini_set('session.'.$key, $value); + } + } + } + + /** + * Registers session save handler as a PHP session handler. + * + * To use internal PHP session save handlers, override this method using ini_set with + * session.save_handler and session.save_path e.g. + * + * ini_set('session.save_handler', 'files'); + * ini_set('session.save_path', '/tmp'); + * + * or pass in a NativeSessionHandler instance which configures session.save_handler in the + * constructor, for a template see NativeFileSessionHandler or use handlers in + * composer package drak/native-session + * + * @see http://php.net/session-set-save-handler + * @see http://php.net/sessionhandlerinterface + * @see http://php.net/sessionhandler + * @see http://github.com/drak/NativeSession + * + * @param AbstractProxy|NativeSessionHandler|\SessionHandlerInterface|null $saveHandler + * + * @throws \InvalidArgumentException + */ + public function setSaveHandler($saveHandler = null) + { + if (!$saveHandler instanceof AbstractProxy && + !$saveHandler instanceof NativeSessionHandler && + !$saveHandler instanceof \SessionHandlerInterface && + null !== $saveHandler) { + throw new \InvalidArgumentException('Must be instance of AbstractProxy or NativeSessionHandler; implement \SessionHandlerInterface; or be null.'); + } + + // Wrap $saveHandler in proxy and prevent double wrapping of proxy + if (!$saveHandler instanceof AbstractProxy && $saveHandler instanceof \SessionHandlerInterface) { + $saveHandler = new SessionHandlerProxy($saveHandler); + } elseif (!$saveHandler instanceof AbstractProxy) { + $saveHandler = PHP_VERSION_ID >= 50400 ? + new SessionHandlerProxy(new \SessionHandler()) : new NativeProxy(); + } + $this->saveHandler = $saveHandler; + + if ($this->saveHandler instanceof \SessionHandlerInterface) { + if (PHP_VERSION_ID >= 50400) { + session_set_save_handler($this->saveHandler, false); + } else { + session_set_save_handler( + array($this->saveHandler, 'open'), + array($this->saveHandler, 'close'), + array($this->saveHandler, 'read'), + array($this->saveHandler, 'write'), + array($this->saveHandler, 'destroy'), + array($this->saveHandler, 'gc') + ); + } + } + } + + /** + * Load the session with attributes. + * + * After starting the session, PHP retrieves the session from whatever handlers + * are set to (either PHP's internal, or a custom save handler set with session_set_save_handler()). + * PHP takes the return value from the read() handler, unserializes it + * and populates $_SESSION with the result automatically. + * + * @param array|null $session + */ + protected function loadSession(array &$session = null) + { + if (null === $session) { + $session = &$_SESSION; + } + + $bags = array_merge($this->bags, array($this->metadataBag)); + + foreach ($bags as $bag) { + $key = $bag->getStorageKey(); + $session[$key] = isset($session[$key]) ? $session[$key] : array(); + $bag->initialize($session[$key]); + } + + $this->started = true; + $this->closed = false; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/PhpBridgeSessionStorage.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/PhpBridgeSessionStorage.php new file mode 100644 index 0000000..ced706f --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/PhpBridgeSessionStorage.php @@ -0,0 +1,68 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Session\Storage; + +use Symfony\Component\HttpFoundation\Session\Storage\Proxy\AbstractProxy; +use Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeSessionHandler; + +/** + * Allows session to be started by PHP and managed by Symfony. + * + * @author Drak + */ +class PhpBridgeSessionStorage extends NativeSessionStorage +{ + /** + * Constructor. + * + * @param AbstractProxy|NativeSessionHandler|\SessionHandlerInterface|null $handler + * @param MetadataBag $metaBag MetadataBag + */ + public function __construct($handler = null, MetadataBag $metaBag = null) + { + $this->setMetadataBag($metaBag); + $this->setSaveHandler($handler); + } + + /** + * {@inheritdoc} + */ + public function start() + { + if ($this->started) { + return true; + } + + $this->loadSession(); + if (!$this->saveHandler->isWrapper() && !$this->saveHandler->isSessionHandlerInterface()) { + // This condition matches only PHP 5.3 + internal save handlers + $this->saveHandler->setActive(true); + } + + return true; + } + + /** + * {@inheritdoc} + */ + public function clear() + { + // clear out the bags and nothing else that may be set + // since the purpose of this driver is to share a handler + foreach ($this->bags as $bag) { + $bag->clear(); + } + + // reconnect the bags to the session + $this->loadSession(); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/Proxy/AbstractProxy.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/Proxy/AbstractProxy.php new file mode 100644 index 0000000..463677b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/Proxy/AbstractProxy.php @@ -0,0 +1,154 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Session\Storage\Proxy; + +/** + * AbstractProxy. + * + * @author Drak + */ +abstract class AbstractProxy +{ + /** + * Flag if handler wraps an internal PHP session handler (using \SessionHandler). + * + * @var bool + */ + protected $wrapper = false; + + /** + * @var bool + */ + protected $active = false; + + /** + * @var string + */ + protected $saveHandlerName; + + /** + * Gets the session.save_handler name. + * + * @return string + */ + public function getSaveHandlerName() + { + return $this->saveHandlerName; + } + + /** + * Is this proxy handler and instance of \SessionHandlerInterface. + * + * @return bool + */ + public function isSessionHandlerInterface() + { + return $this instanceof \SessionHandlerInterface; + } + + /** + * Returns true if this handler wraps an internal PHP session save handler using \SessionHandler. + * + * @return bool + */ + public function isWrapper() + { + return $this->wrapper; + } + + /** + * Has a session started? + * + * @return bool + */ + public function isActive() + { + if (PHP_VERSION_ID >= 50400) { + return $this->active = \PHP_SESSION_ACTIVE === session_status(); + } + + return $this->active; + } + + /** + * Sets the active flag. + * + * Has no effect under PHP 5.4+ as status is detected + * automatically in isActive() + * + * @internal + * + * @param bool $flag + * + * @throws \LogicException + */ + public function setActive($flag) + { + if (PHP_VERSION_ID >= 50400) { + throw new \LogicException('This method is disabled in PHP 5.4.0+'); + } + + $this->active = (bool) $flag; + } + + /** + * Gets the session ID. + * + * @return string + */ + public function getId() + { + return session_id(); + } + + /** + * Sets the session ID. + * + * @param string $id + * + * @throws \LogicException + */ + public function setId($id) + { + if ($this->isActive()) { + throw new \LogicException('Cannot change the ID of an active session'); + } + + session_id($id); + } + + /** + * Gets the session name. + * + * @return string + */ + public function getName() + { + return session_name(); + } + + /** + * Sets the session name. + * + * @param string $name + * + * @throws \LogicException + */ + public function setName($name) + { + if ($this->isActive()) { + throw new \LogicException('Cannot change the name of an active session'); + } + + session_name($name); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/Proxy/NativeProxy.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/Proxy/NativeProxy.php new file mode 100644 index 0000000..0db34aa --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/Proxy/NativeProxy.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Session\Storage\Proxy; + +/** + * NativeProxy. + * + * This proxy is built-in session handlers in PHP 5.3.x + * + * @author Drak + */ +class NativeProxy extends AbstractProxy +{ + /** + * Constructor. + */ + public function __construct() + { + // this makes an educated guess as to what the handler is since it should already be set. + $this->saveHandlerName = ini_get('session.save_handler'); + } + + /** + * Returns true if this handler wraps an internal PHP session save handler using \SessionHandler. + * + * @return bool False + */ + public function isWrapper() + { + return false; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/Proxy/SessionHandlerProxy.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/Proxy/SessionHandlerProxy.php new file mode 100644 index 0000000..81643c7 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/Proxy/SessionHandlerProxy.php @@ -0,0 +1,95 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Session\Storage\Proxy; + +/** + * SessionHandler proxy. + * + * @author Drak + */ +class SessionHandlerProxy extends AbstractProxy implements \SessionHandlerInterface +{ + /** + * @var \SessionHandlerInterface + */ + protected $handler; + + /** + * Constructor. + * + * @param \SessionHandlerInterface $handler + */ + public function __construct(\SessionHandlerInterface $handler) + { + $this->handler = $handler; + $this->wrapper = ($handler instanceof \SessionHandler); + $this->saveHandlerName = $this->wrapper ? ini_get('session.save_handler') : 'user'; + } + + // \SessionHandlerInterface + + /** + * {@inheritdoc} + */ + public function open($savePath, $sessionName) + { + $return = (bool) $this->handler->open($savePath, $sessionName); + + if (true === $return) { + $this->active = true; + } + + return $return; + } + + /** + * {@inheritdoc} + */ + public function close() + { + $this->active = false; + + return (bool) $this->handler->close(); + } + + /** + * {@inheritdoc} + */ + public function read($sessionId) + { + return (string) $this->handler->read($sessionId); + } + + /** + * {@inheritdoc} + */ + public function write($sessionId, $data) + { + return (bool) $this->handler->write($sessionId, $data); + } + + /** + * {@inheritdoc} + */ + public function destroy($sessionId) + { + return (bool) $this->handler->destroy($sessionId); + } + + /** + * {@inheritdoc} + */ + public function gc($maxlifetime) + { + return (bool) $this->handler->gc($maxlifetime); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/SessionStorageInterface.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/SessionStorageInterface.php new file mode 100644 index 0000000..34f6c46 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/Session/Storage/SessionStorageInterface.php @@ -0,0 +1,139 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Session\Storage; + +use Symfony\Component\HttpFoundation\Session\SessionBagInterface; + +/** + * StorageInterface. + * + * @author Fabien Potencier + * @author Drak + */ +interface SessionStorageInterface +{ + /** + * Starts the session. + * + * @return bool True if started + * + * @throws \RuntimeException If something goes wrong starting the session. + */ + public function start(); + + /** + * Checks if the session is started. + * + * @return bool True if started, false otherwise + */ + public function isStarted(); + + /** + * Returns the session ID. + * + * @return string The session ID or empty + */ + public function getId(); + + /** + * Sets the session ID. + * + * @param string $id + */ + public function setId($id); + + /** + * Returns the session name. + * + * @return mixed The session name + */ + public function getName(); + + /** + * Sets the session name. + * + * @param string $name + */ + public function setName($name); + + /** + * Regenerates id that represents this storage. + * + * This method must invoke session_regenerate_id($destroy) unless + * this interface is used for a storage object designed for unit + * or functional testing where a real PHP session would interfere + * with testing. + * + * Note regenerate+destroy should not clear the session data in memory + * only delete the session data from persistent storage. + * + * Care: When regenerating the session ID no locking is involved in PHP's + * session design. See https://bugs.php.net/bug.php?id=61470 for a discussion. + * So you must make sure the regenerated session is saved BEFORE sending the + * headers with the new ID. Symfony's HttpKernel offers a listener for this. + * See Symfony\Component\HttpKernel\EventListener\SaveSessionListener. + * Otherwise session data could get lost again for concurrent requests with the + * new ID. One result could be that you get logged out after just logging in. + * + * @param bool $destroy Destroy session when regenerating? + * @param int $lifetime Sets the cookie lifetime for the session cookie. A null value + * will leave the system settings unchanged, 0 sets the cookie + * to expire with browser session. Time is in seconds, and is + * not a Unix timestamp. + * + * @return bool True if session regenerated, false if error + * + * @throws \RuntimeException If an error occurs while regenerating this storage + */ + public function regenerate($destroy = false, $lifetime = null); + + /** + * Force the session to be saved and closed. + * + * This method must invoke session_write_close() unless this interface is + * used for a storage object design for unit or functional testing where + * a real PHP session would interfere with testing, in which case + * it should actually persist the session data if required. + * + * @throws \RuntimeException If the session is saved without being started, or if the session + * is already closed. + */ + public function save(); + + /** + * Clear all session data in memory. + */ + public function clear(); + + /** + * Gets a SessionBagInterface by name. + * + * @param string $name + * + * @return SessionBagInterface + * + * @throws \InvalidArgumentException If the bag does not exist + */ + public function getBag($name); + + /** + * Registers a SessionBagInterface for use. + * + * @param SessionBagInterface $bag + */ + public function registerBag(SessionBagInterface $bag); + + /** + * @return MetadataBag + */ + public function getMetadataBag(); +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/StreamedResponse.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/StreamedResponse.php new file mode 100644 index 0000000..4b936a1 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-foundation/StreamedResponse.php @@ -0,0 +1,119 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation; + +/** + * StreamedResponse represents a streamed HTTP response. + * + * A StreamedResponse uses a callback for its content. + * + * The callback should use the standard PHP functions like echo + * to stream the response back to the client. The flush() method + * can also be used if needed. + * + * @see flush() + * + * @author Fabien Potencier + */ +class StreamedResponse extends Response +{ + protected $callback; + protected $streamed; + + /** + * Constructor. + * + * @param callable|null $callback A valid PHP callback or null to set it later + * @param int $status The response status code + * @param array $headers An array of response headers + */ + public function __construct($callback = null, $status = 200, $headers = array()) + { + parent::__construct(null, $status, $headers); + + if (null !== $callback) { + $this->setCallback($callback); + } + $this->streamed = false; + } + + /** + * Factory method for chainability. + * + * @param callable|null $callback A valid PHP callback or null to set it later + * @param int $status The response status code + * @param array $headers An array of response headers + * + * @return StreamedResponse + */ + public static function create($callback = null, $status = 200, $headers = array()) + { + return new static($callback, $status, $headers); + } + + /** + * Sets the PHP callback associated with this Response. + * + * @param callable $callback A valid PHP callback + * + * @throws \LogicException + */ + public function setCallback($callback) + { + if (!is_callable($callback)) { + throw new \LogicException('The Response callback must be a valid PHP callable.'); + } + $this->callback = $callback; + } + + /** + * {@inheritdoc} + * + * This method only sends the content once. + */ + public function sendContent() + { + if ($this->streamed) { + return; + } + + $this->streamed = true; + + if (null === $this->callback) { + throw new \LogicException('The Response callback must not be null.'); + } + + call_user_func($this->callback); + } + + /** + * {@inheritdoc} + * + * @throws \LogicException when the content is not null + */ + public function setContent($content) + { + if (null !== $content) { + throw new \LogicException('The content cannot be set on a StreamedResponse instance.'); + } + } + + /** + * {@inheritdoc} + * + * @return false + */ + public function getContent() + { + return false; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Bundle/Bundle.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Bundle/Bundle.php new file mode 100644 index 0000000..9c2466d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Bundle/Bundle.php @@ -0,0 +1,207 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Bundle; + +use Symfony\Component\DependencyInjection\ContainerAware; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Container; +use Symfony\Component\Console\Application; +use Symfony\Component\Finder\Finder; +use Symfony\Component\DependencyInjection\Extension\ExtensionInterface; + +/** + * An implementation of BundleInterface that adds a few conventions + * for DependencyInjection extensions and Console commands. + * + * @author Fabien Potencier + */ +abstract class Bundle extends ContainerAware implements BundleInterface +{ + protected $name; + protected $extension; + protected $path; + + /** + * Boots the Bundle. + */ + public function boot() + { + } + + /** + * Shutdowns the Bundle. + */ + public function shutdown() + { + } + + /** + * Builds the bundle. + * + * It is only ever called once when the cache is empty. + * + * This method can be overridden to register compilation passes, + * other extensions, ... + * + * @param ContainerBuilder $container A ContainerBuilder instance + */ + public function build(ContainerBuilder $container) + { + } + + /** + * Returns the bundle's container extension. + * + * @return ExtensionInterface|null The container extension + * + * @throws \LogicException + */ + public function getContainerExtension() + { + if (null === $this->extension) { + $class = $this->getContainerExtensionClass(); + if (class_exists($class)) { + $extension = new $class(); + + if (!$extension instanceof ExtensionInterface) { + throw new \LogicException(sprintf('Extension %s must implement Symfony\Component\DependencyInjection\Extension\ExtensionInterface.', $class)); + } + + // check naming convention + $basename = preg_replace('/Bundle$/', '', $this->getName()); + $expectedAlias = Container::underscore($basename); + if ($expectedAlias != $extension->getAlias()) { + throw new \LogicException(sprintf( + 'Users will expect the alias of the default extension of a bundle to be the underscored version of the bundle name ("%s"). You can override "Bundle::getContainerExtension()" if you want to use "%s" or another alias.', + $expectedAlias, $extension->getAlias() + )); + } + + $this->extension = $extension; + } else { + $this->extension = false; + } + } + + if ($this->extension) { + return $this->extension; + } + } + + /** + * Gets the Bundle namespace. + * + * @return string The Bundle namespace + */ + public function getNamespace() + { + $class = get_class($this); + + return substr($class, 0, strrpos($class, '\\')); + } + + /** + * Gets the Bundle directory path. + * + * @return string The Bundle absolute path + */ + public function getPath() + { + if (null === $this->path) { + $reflected = new \ReflectionObject($this); + $this->path = dirname($reflected->getFileName()); + } + + return $this->path; + } + + /** + * Returns the bundle parent name. + * + * @return string The Bundle parent name it overrides or null if no parent + */ + public function getParent() + { + } + + /** + * Returns the bundle name (the class short name). + * + * @return string The Bundle name + */ + final public function getName() + { + if (null !== $this->name) { + return $this->name; + } + + $name = get_class($this); + $pos = strrpos($name, '\\'); + + return $this->name = false === $pos ? $name : substr($name, $pos + 1); + } + + /** + * Finds and registers Commands. + * + * Override this method if your bundle commands do not follow the conventions: + * + * * Commands are in the 'Command' sub-directory + * * Commands extend Symfony\Component\Console\Command\Command + * + * @param Application $application An Application instance + */ + public function registerCommands(Application $application) + { + if (!is_dir($dir = $this->getPath().'/Command')) { + return; + } + + if (!class_exists('Symfony\Component\Finder\Finder')) { + throw new \RuntimeException('You need the symfony/finder component to register bundle commands.'); + } + + $finder = new Finder(); + $finder->files()->name('*Command.php')->in($dir); + + $prefix = $this->getNamespace().'\\Command'; + foreach ($finder as $file) { + $ns = $prefix; + if ($relativePath = $file->getRelativePath()) { + $ns .= '\\'.str_replace('/', '\\', $relativePath); + } + $class = $ns.'\\'.$file->getBasename('.php'); + if ($this->container) { + $alias = 'console.command.'.strtolower(str_replace('\\', '_', $class)); + if ($this->container->has($alias)) { + continue; + } + } + $r = new \ReflectionClass($class); + if ($r->isSubclassOf('Symfony\\Component\\Console\\Command\\Command') && !$r->isAbstract() && !$r->getConstructor()->getNumberOfRequiredParameters()) { + $application->add($r->newInstance()); + } + } + } + + /** + * Returns the bundle's container extension class. + * + * @return string + */ + protected function getContainerExtensionClass() + { + $basename = preg_replace('/Bundle$/', '', $this->getName()); + + return $this->getNamespace().'\\DependencyInjection\\'.$basename.'Extension'; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Bundle/BundleInterface.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Bundle/BundleInterface.php new file mode 100644 index 0000000..25eea1d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Bundle/BundleInterface.php @@ -0,0 +1,84 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Bundle; + +use Symfony\Component\DependencyInjection\ContainerAwareInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Extension\ExtensionInterface; + +/** + * BundleInterface. + * + * @author Fabien Potencier + */ +interface BundleInterface extends ContainerAwareInterface +{ + /** + * Boots the Bundle. + */ + public function boot(); + + /** + * Shutdowns the Bundle. + */ + public function shutdown(); + + /** + * Builds the bundle. + * + * It is only ever called once when the cache is empty. + * + * @param ContainerBuilder $container A ContainerBuilder instance + */ + public function build(ContainerBuilder $container); + + /** + * Returns the container extension that should be implicitly loaded. + * + * @return ExtensionInterface|null The default extension or null if there is none + */ + public function getContainerExtension(); + + /** + * Returns the bundle name that this bundle overrides. + * + * Despite its name, this method does not imply any parent/child relationship + * between the bundles, just a way to extend and override an existing + * bundle. + * + * @return string The Bundle name it overrides or null if no parent + */ + public function getParent(); + + /** + * Returns the bundle name (the class short name). + * + * @return string The Bundle name + */ + public function getName(); + + /** + * Gets the Bundle namespace. + * + * @return string The Bundle namespace + */ + public function getNamespace(); + + /** + * Gets the Bundle directory path. + * + * The path should always be returned as a Unix path (with /). + * + * @return string The Bundle absolute path + */ + public function getPath(); +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/CacheClearer/CacheClearerInterface.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/CacheClearer/CacheClearerInterface.php new file mode 100644 index 0000000..675c584 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/CacheClearer/CacheClearerInterface.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\CacheClearer; + +/** + * CacheClearerInterface. + * + * @author Dustin Dobervich + */ +interface CacheClearerInterface +{ + /** + * Clears any caches necessary. + * + * @param string $cacheDir The cache directory + */ + public function clear($cacheDir); +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/CacheClearer/ChainCacheClearer.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/CacheClearer/ChainCacheClearer.php new file mode 100644 index 0000000..c749c7c --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/CacheClearer/ChainCacheClearer.php @@ -0,0 +1,55 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\CacheClearer; + +/** + * ChainCacheClearer. + * + * @author Dustin Dobervich + */ +class ChainCacheClearer implements CacheClearerInterface +{ + /** + * @var array + */ + protected $clearers; + + /** + * Constructs a new instance of ChainCacheClearer. + * + * @param array $clearers The initial clearers + */ + public function __construct(array $clearers = array()) + { + $this->clearers = $clearers; + } + + /** + * {@inheritdoc} + */ + public function clear($cacheDir) + { + foreach ($this->clearers as $clearer) { + $clearer->clear($cacheDir); + } + } + + /** + * Adds a cache clearer to the aggregate. + * + * @param CacheClearerInterface $clearer + */ + public function add(CacheClearerInterface $clearer) + { + $this->clearers[] = $clearer; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/CacheWarmer/CacheWarmer.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/CacheWarmer/CacheWarmer.php new file mode 100644 index 0000000..dba35a6 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/CacheWarmer/CacheWarmer.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\CacheWarmer; + +/** + * Abstract cache warmer that knows how to write a file to the cache. + * + * @author Fabien Potencier + */ +abstract class CacheWarmer implements CacheWarmerInterface +{ + protected function writeCacheFile($file, $content) + { + $tmpFile = @tempnam(dirname($file), basename($file)); + if (false !== @file_put_contents($tmpFile, $content) && @rename($tmpFile, $file)) { + @chmod($file, 0666 & ~umask()); + + return; + } + + throw new \RuntimeException(sprintf('Failed to write cache file "%s".', $file)); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/CacheWarmer/CacheWarmerAggregate.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/CacheWarmer/CacheWarmerAggregate.php new file mode 100644 index 0000000..e5f4e4f --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/CacheWarmer/CacheWarmerAggregate.php @@ -0,0 +1,74 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\CacheWarmer; + +/** + * Aggregates several cache warmers into a single one. + * + * @author Fabien Potencier + */ +class CacheWarmerAggregate implements CacheWarmerInterface +{ + protected $warmers = array(); + protected $optionalsEnabled = false; + + public function __construct(array $warmers = array()) + { + foreach ($warmers as $warmer) { + $this->add($warmer); + } + } + + public function enableOptionalWarmers() + { + $this->optionalsEnabled = true; + } + + /** + * Warms up the cache. + * + * @param string $cacheDir The cache directory + */ + public function warmUp($cacheDir) + { + foreach ($this->warmers as $warmer) { + if (!$this->optionalsEnabled && $warmer->isOptional()) { + continue; + } + + $warmer->warmUp($cacheDir); + } + } + + /** + * Checks whether this warmer is optional or not. + * + * @return bool always false + */ + public function isOptional() + { + return false; + } + + public function setWarmers(array $warmers) + { + $this->warmers = array(); + foreach ($warmers as $warmer) { + $this->add($warmer); + } + } + + public function add(CacheWarmerInterface $warmer) + { + $this->warmers[] = $warmer; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/CacheWarmer/CacheWarmerInterface.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/CacheWarmer/CacheWarmerInterface.php new file mode 100644 index 0000000..8fece5e --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/CacheWarmer/CacheWarmerInterface.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\CacheWarmer; + +/** + * Interface for classes able to warm up the cache. + * + * @author Fabien Potencier + */ +interface CacheWarmerInterface extends WarmableInterface +{ + /** + * Checks whether this warmer is optional or not. + * + * Optional warmers can be ignored on certain conditions. + * + * A warmer should return true if the cache can be + * generated incrementally and on-demand. + * + * @return bool true if the warmer is optional, false otherwise + */ + public function isOptional(); +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/CacheWarmer/WarmableInterface.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/CacheWarmer/WarmableInterface.php new file mode 100644 index 0000000..25d8ee8 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/CacheWarmer/WarmableInterface.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\CacheWarmer; + +/** + * Interface for classes that support warming their cache. + * + * @author Fabien Potencier + */ +interface WarmableInterface +{ + /** + * Warms up the cache. + * + * @param string $cacheDir The cache directory + */ + public function warmUp($cacheDir); +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Client.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Client.php new file mode 100644 index 0000000..80b1bd6 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Client.php @@ -0,0 +1,226 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel; + +use Symfony\Component\BrowserKit\Client as BaseClient; +use Symfony\Component\BrowserKit\Request as DomRequest; +use Symfony\Component\BrowserKit\Response as DomResponse; +use Symfony\Component\BrowserKit\Cookie as DomCookie; +use Symfony\Component\BrowserKit\History; +use Symfony\Component\BrowserKit\CookieJar; +use Symfony\Component\HttpFoundation\File\UploadedFile; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; + +/** + * Client simulates a browser and makes requests to a Kernel object. + * + * @author Fabien Potencier + */ +class Client extends BaseClient +{ + protected $kernel; + + /** + * Constructor. + * + * @param HttpKernelInterface $kernel An HttpKernel instance + * @param array $server The server parameters (equivalent of $_SERVER) + * @param History $history A History instance to store the browser history + * @param CookieJar $cookieJar A CookieJar instance to store the cookies + */ + public function __construct(HttpKernelInterface $kernel, array $server = array(), History $history = null, CookieJar $cookieJar = null) + { + // These class properties must be set before calling the parent constructor, as it may depend on it. + $this->kernel = $kernel; + $this->followRedirects = false; + + parent::__construct($server, $history, $cookieJar); + } + + /** + * {@inheritdoc} + * + * @return Request|null A Request instance + */ + public function getRequest() + { + return parent::getRequest(); + } + + /** + * {@inheritdoc} + * + * @return Response|null A Response instance + */ + public function getResponse() + { + return parent::getResponse(); + } + + /** + * Makes a request. + * + * @param Request $request A Request instance + * + * @return Response A Response instance + */ + protected function doRequest($request) + { + $response = $this->kernel->handle($request); + + if ($this->kernel instanceof TerminableInterface) { + $this->kernel->terminate($request, $response); + } + + return $response; + } + + /** + * Returns the script to execute when the request must be insulated. + * + * @param Request $request A Request instance + * + * @return string + */ + protected function getScript($request) + { + $kernel = str_replace("'", "\\'", serialize($this->kernel)); + $request = str_replace("'", "\\'", serialize($request)); + + $r = new \ReflectionClass('\\Symfony\\Component\\ClassLoader\\ClassLoader'); + $requirePath = str_replace("'", "\\'", $r->getFileName()); + $symfonyPath = str_replace("'", "\\'", dirname(dirname(dirname(__DIR__)))); + $errorReporting = error_reporting(); + + $code = <<addPrefix('Symfony', '$symfonyPath'); +\$loader->register(); + +\$kernel = unserialize('$kernel'); +\$request = unserialize('$request'); +EOF; + + return $code.$this->getHandleScript(); + } + + protected function getHandleScript() + { + return <<<'EOF' +$response = $kernel->handle($request); + +if ($kernel instanceof Symfony\Component\HttpKernel\TerminableInterface) { + $kernel->terminate($request, $response); +} + +echo serialize($response); +EOF; + } + + /** + * Converts the BrowserKit request to a HttpKernel request. + * + * @param DomRequest $request A DomRequest instance + * + * @return Request A Request instance + */ + protected function filterRequest(DomRequest $request) + { + $httpRequest = Request::create($request->getUri(), $request->getMethod(), $request->getParameters(), $request->getCookies(), $request->getFiles(), $request->getServer(), $request->getContent()); + + foreach ($this->filterFiles($httpRequest->files->all()) as $key => $value) { + $httpRequest->files->set($key, $value); + } + + return $httpRequest; + } + + /** + * Filters an array of files. + * + * This method created test instances of UploadedFile so that the move() + * method can be called on those instances. + * + * If the size of a file is greater than the allowed size (from php.ini) then + * an invalid UploadedFile is returned with an error set to UPLOAD_ERR_INI_SIZE. + * + * @see UploadedFile + * + * @param array $files An array of files + * + * @return array An array with all uploaded files marked as already moved + */ + protected function filterFiles(array $files) + { + $filtered = array(); + foreach ($files as $key => $value) { + if (is_array($value)) { + $filtered[$key] = $this->filterFiles($value); + } elseif ($value instanceof UploadedFile) { + if ($value->isValid() && $value->getSize() > UploadedFile::getMaxFilesize()) { + $filtered[$key] = new UploadedFile( + '', + $value->getClientOriginalName(), + $value->getClientMimeType(), + 0, + UPLOAD_ERR_INI_SIZE, + true + ); + } else { + $filtered[$key] = new UploadedFile( + $value->getPathname(), + $value->getClientOriginalName(), + $value->getClientMimeType(), + $value->getClientSize(), + $value->getError(), + true + ); + } + } + } + + return $filtered; + } + + /** + * Converts the HttpKernel response to a BrowserKit response. + * + * @param Response $response A Response instance + * + * @return DomResponse A DomResponse instance + */ + protected function filterResponse($response) + { + $headers = $response->headers->all(); + if ($response->headers->getCookies()) { + $cookies = array(); + foreach ($response->headers->getCookies() as $cookie) { + $cookies[] = new DomCookie($cookie->getName(), $cookie->getValue(), $cookie->getExpiresTime(), $cookie->getPath(), $cookie->getDomain(), $cookie->isSecure(), $cookie->isHttpOnly()); + } + $headers['Set-Cookie'] = $cookies; + } + + // this is needed to support StreamedResponse + ob_start(); + $response->sendContent(); + $content = ob_get_clean(); + + return new DomResponse($content, $response->getStatusCode(), $headers); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Config/EnvParametersResource.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Config/EnvParametersResource.php new file mode 100644 index 0000000..5f54450 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Config/EnvParametersResource.php @@ -0,0 +1,95 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Config; + +use Symfony\Component\Config\Resource\ResourceInterface; + +/** + * EnvParametersResource represents resources stored in prefixed environment variables. + * + * @author Chris Wilkinson + */ +class EnvParametersResource implements ResourceInterface, \Serializable +{ + /** + * @var string + */ + private $prefix; + + /** + * @var string + */ + private $variables; + + /** + * Constructor. + * + * @param string $prefix + */ + public function __construct($prefix) + { + $this->prefix = $prefix; + $this->variables = $this->findVariables(); + } + + /** + * {@inheritdoc} + */ + public function __toString() + { + return serialize($this->getResource()); + } + + /** + * {@inheritdoc} + */ + public function getResource() + { + return array('prefix' => $this->prefix, 'variables' => $this->variables); + } + + /** + * {@inheritdoc} + */ + public function isFresh($timestamp) + { + return $this->findVariables() === $this->variables; + } + + public function serialize() + { + return serialize(array('prefix' => $this->prefix, 'variables' => $this->variables)); + } + + public function unserialize($serialized) + { + $unserialized = unserialize($serialized); + + $this->prefix = $unserialized['prefix']; + $this->variables = $unserialized['variables']; + } + + private function findVariables() + { + $variables = array(); + + foreach ($_SERVER as $key => $value) { + if (0 === strpos($key, $this->prefix)) { + $variables[$key] = $value; + } + } + + ksort($variables); + + return $variables; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Config/FileLocator.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Config/FileLocator.php new file mode 100644 index 0000000..169c9ad --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Config/FileLocator.php @@ -0,0 +1,56 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Config; + +use Symfony\Component\Config\FileLocator as BaseFileLocator; +use Symfony\Component\HttpKernel\KernelInterface; + +/** + * FileLocator uses the KernelInterface to locate resources in bundles. + * + * @author Fabien Potencier + */ +class FileLocator extends BaseFileLocator +{ + private $kernel; + private $path; + + /** + * Constructor. + * + * @param KernelInterface $kernel A KernelInterface instance + * @param null|string $path The path the global resource directory + * @param array $paths An array of paths where to look for resources + */ + public function __construct(KernelInterface $kernel, $path = null, array $paths = array()) + { + $this->kernel = $kernel; + if (null !== $path) { + $this->path = $path; + $paths[] = $path; + } + + parent::__construct($paths); + } + + /** + * {@inheritdoc} + */ + public function locate($file, $currentPath = null, $first = true) + { + if (isset($file[0]) && '@' === $file[0]) { + return $this->kernel->locateResource($file, $this->path, $first); + } + + return parent::locate($file, $currentPath, $first); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Controller/ControllerReference.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Controller/ControllerReference.php new file mode 100644 index 0000000..3d1592e --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Controller/ControllerReference.php @@ -0,0 +1,46 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Controller; + +use Symfony\Component\HttpKernel\Fragment\FragmentRendererInterface; + +/** + * Acts as a marker and a data holder for a Controller. + * + * Some methods in Symfony accept both a URI (as a string) or a controller as + * an argument. In the latter case, instead of passing an array representing + * the controller, you can use an instance of this class. + * + * @author Fabien Potencier + * + * @see FragmentRendererInterface + */ +class ControllerReference +{ + public $controller; + public $attributes = array(); + public $query = array(); + + /** + * Constructor. + * + * @param string $controller The controller name + * @param array $attributes An array of parameters to add to the Request attributes + * @param array $query An array of parameters to add to the Request query string + */ + public function __construct($controller, array $attributes = array(), array $query = array()) + { + $this->controller = $controller; + $this->attributes = $attributes; + $this->query = $query; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Controller/ControllerResolver.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Controller/ControllerResolver.php new file mode 100644 index 0000000..c76b57b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Controller/ControllerResolver.php @@ -0,0 +1,188 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Controller; + +use Psr\Log\LoggerInterface; +use Symfony\Component\HttpFoundation\Request; + +/** + * ControllerResolver. + * + * This implementation uses the '_controller' request attribute to determine + * the controller to execute and uses the request attributes to determine + * the controller method arguments. + * + * @author Fabien Potencier + */ +class ControllerResolver implements ControllerResolverInterface +{ + private $logger; + + /** + * If the ...$arg functionality is available. + * + * Requires at least PHP 5.6.0 or HHVM 3.9.1 + * + * @var bool + */ + private $supportsVariadic; + + /** + * Constructor. + * + * @param LoggerInterface $logger A LoggerInterface instance + */ + public function __construct(LoggerInterface $logger = null) + { + $this->logger = $logger; + + $this->supportsVariadic = method_exists('ReflectionParameter', 'isVariadic'); + } + + /** + * {@inheritdoc} + * + * This method looks for a '_controller' request attribute that represents + * the controller name (a string like ClassName::MethodName). + */ + public function getController(Request $request) + { + if (!$controller = $request->attributes->get('_controller')) { + if (null !== $this->logger) { + $this->logger->warning('Unable to look for the controller as the "_controller" parameter is missing.'); + } + + return false; + } + + if (is_array($controller)) { + return $controller; + } + + if (is_object($controller)) { + if (method_exists($controller, '__invoke')) { + return $controller; + } + + throw new \InvalidArgumentException(sprintf('Controller "%s" for URI "%s" is not callable.', get_class($controller), $request->getPathInfo())); + } + + if (false === strpos($controller, ':')) { + if (method_exists($controller, '__invoke')) { + return $this->instantiateController($controller); + } elseif (function_exists($controller)) { + return $controller; + } + } + + $callable = $this->createController($controller); + + if (!is_callable($callable)) { + throw new \InvalidArgumentException(sprintf('Controller "%s" for URI "%s" is not callable.', $controller, $request->getPathInfo())); + } + + return $callable; + } + + /** + * {@inheritdoc} + */ + public function getArguments(Request $request, $controller) + { + if (is_array($controller)) { + $r = new \ReflectionMethod($controller[0], $controller[1]); + } elseif (is_object($controller) && !$controller instanceof \Closure) { + $r = new \ReflectionObject($controller); + $r = $r->getMethod('__invoke'); + } else { + $r = new \ReflectionFunction($controller); + } + + return $this->doGetArguments($request, $controller, $r->getParameters()); + } + + /** + * @param Request $request + * @param callable $controller + * @param \ReflectionParameter[] $parameters + * + * @return array The arguments to use when calling the action + */ + protected function doGetArguments(Request $request, $controller, array $parameters) + { + $attributes = $request->attributes->all(); + $arguments = array(); + foreach ($parameters as $param) { + if (array_key_exists($param->name, $attributes)) { + if ($this->supportsVariadic && $param->isVariadic() && is_array($attributes[$param->name])) { + $arguments = array_merge($arguments, array_values($attributes[$param->name])); + } else { + $arguments[] = $attributes[$param->name]; + } + } elseif ($param->getClass() && $param->getClass()->isInstance($request)) { + $arguments[] = $request; + } elseif ($param->isDefaultValueAvailable()) { + $arguments[] = $param->getDefaultValue(); + } elseif ($param->allowsNull()) { + $arguments[] = null; + } else { + if (is_array($controller)) { + $repr = sprintf('%s::%s()', get_class($controller[0]), $controller[1]); + } elseif (is_object($controller)) { + $repr = get_class($controller); + } else { + $repr = $controller; + } + + throw new \RuntimeException(sprintf('Controller "%s" requires that you provide a value for the "$%s" argument (because there is no default value or because there is a non optional argument after this one).', $repr, $param->name)); + } + } + + return $arguments; + } + + /** + * Returns a callable for the given controller. + * + * @param string $controller A Controller string + * + * @return callable A PHP callable + * + * @throws \InvalidArgumentException + */ + protected function createController($controller) + { + if (false === strpos($controller, '::')) { + throw new \InvalidArgumentException(sprintf('Unable to find controller "%s".', $controller)); + } + + list($class, $method) = explode('::', $controller, 2); + + if (!class_exists($class)) { + throw new \InvalidArgumentException(sprintf('Class "%s" does not exist.', $class)); + } + + return array($this->instantiateController($class), $method); + } + + /** + * Returns an instantiated controller. + * + * @param string $class A class name + * + * @return object + */ + protected function instantiateController($class) + { + return new $class(); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Controller/ControllerResolverInterface.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Controller/ControllerResolverInterface.php new file mode 100644 index 0000000..f7b19ed --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Controller/ControllerResolverInterface.php @@ -0,0 +1,57 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Controller; + +use Symfony\Component\HttpFoundation\Request; + +/** + * A ControllerResolverInterface implementation knows how to determine the + * controller to execute based on a Request object. + * + * It can also determine the arguments to pass to the Controller. + * + * A Controller can be any valid PHP callable. + * + * @author Fabien Potencier + */ +interface ControllerResolverInterface +{ + /** + * Returns the Controller instance associated with a Request. + * + * As several resolvers can exist for a single application, a resolver must + * return false when it is not able to determine the controller. + * + * The resolver must only throw an exception when it should be able to load + * controller but cannot because of some errors made by the developer. + * + * @param Request $request A Request instance + * + * @return callable|false A PHP callable representing the Controller, + * or false if this resolver is not able to determine the controller + * + * @throws \LogicException If the controller can't be found + */ + public function getController(Request $request); + + /** + * Returns the arguments to pass to the controller. + * + * @param Request $request A Request instance + * @param callable $controller A PHP callable + * + * @return array An array of arguments to pass to the controller + * + * @throws \RuntimeException When value for argument given is not provided + */ + public function getArguments(Request $request, $controller); +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Controller/TraceableControllerResolver.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Controller/TraceableControllerResolver.php new file mode 100644 index 0000000..f8de31c --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Controller/TraceableControllerResolver.php @@ -0,0 +1,66 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Controller; + +use Symfony\Component\Stopwatch\Stopwatch; +use Symfony\Component\HttpFoundation\Request; + +/** + * TraceableControllerResolver. + * + * @author Fabien Potencier + */ +class TraceableControllerResolver implements ControllerResolverInterface +{ + private $resolver; + private $stopwatch; + + /** + * Constructor. + * + * @param ControllerResolverInterface $resolver A ControllerResolverInterface instance + * @param Stopwatch $stopwatch A Stopwatch instance + */ + public function __construct(ControllerResolverInterface $resolver, Stopwatch $stopwatch) + { + $this->resolver = $resolver; + $this->stopwatch = $stopwatch; + } + + /** + * {@inheritdoc} + */ + public function getController(Request $request) + { + $e = $this->stopwatch->start('controller.get_callable'); + + $ret = $this->resolver->getController($request); + + $e->stop(); + + return $ret; + } + + /** + * {@inheritdoc} + */ + public function getArguments(Request $request, $controller) + { + $e = $this->stopwatch->start('controller.get_arguments'); + + $ret = $this->resolver->getArguments($request, $controller); + + $e->stop(); + + return $ret; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DataCollector/ConfigDataCollector.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DataCollector/ConfigDataCollector.php new file mode 100644 index 0000000..395fee3 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DataCollector/ConfigDataCollector.php @@ -0,0 +1,291 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\DataCollector; + +use Symfony\Component\HttpKernel\KernelInterface; +use Symfony\Component\HttpKernel\Kernel; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; + +/** + * ConfigDataCollector. + * + * @author Fabien Potencier + */ +class ConfigDataCollector extends DataCollector +{ + /** + * @var KernelInterface + */ + private $kernel; + private $name; + private $version; + private $cacheVersionInfo = true; + + /** + * Constructor. + * + * @param string $name The name of the application using the web profiler + * @param string $version The version of the application using the web profiler + */ + public function __construct($name = null, $version = null) + { + $this->name = $name; + $this->version = $version; + } + + /** + * Sets the Kernel associated with this Request. + * + * @param KernelInterface $kernel A KernelInterface instance + */ + public function setKernel(KernelInterface $kernel = null) + { + $this->kernel = $kernel; + } + + /** + * {@inheritdoc} + */ + public function collect(Request $request, Response $response, \Exception $exception = null) + { + $this->data = array( + 'app_name' => $this->name, + 'app_version' => $this->version, + 'token' => $response->headers->get('X-Debug-Token'), + 'symfony_version' => Kernel::VERSION, + 'symfony_state' => 'unknown', + 'name' => isset($this->kernel) ? $this->kernel->getName() : 'n/a', + 'env' => isset($this->kernel) ? $this->kernel->getEnvironment() : 'n/a', + 'debug' => isset($this->kernel) ? $this->kernel->isDebug() : 'n/a', + 'php_version' => PHP_VERSION, + 'xdebug_enabled' => extension_loaded('xdebug'), + 'eaccel_enabled' => extension_loaded('eaccelerator') && ini_get('eaccelerator.enable'), + 'apc_enabled' => extension_loaded('apc') && ini_get('apc.enabled'), + 'xcache_enabled' => extension_loaded('xcache') && ini_get('xcache.cacher'), + 'wincache_enabled' => extension_loaded('wincache') && ini_get('wincache.ocenabled'), + 'zend_opcache_enabled' => extension_loaded('Zend OPcache') && ini_get('opcache.enable'), + 'bundles' => array(), + 'sapi_name' => PHP_SAPI, + ); + + if (isset($this->kernel)) { + foreach ($this->kernel->getBundles() as $name => $bundle) { + $this->data['bundles'][$name] = $bundle->getPath(); + } + + $this->data['symfony_state'] = $this->determineSymfonyState(); + } + } + + public function getApplicationName() + { + return $this->data['app_name']; + } + + public function getApplicationVersion() + { + return $this->data['app_version']; + } + + /** + * Gets the token. + * + * @return string The token + */ + public function getToken() + { + return $this->data['token']; + } + + /** + * Gets the Symfony version. + * + * @return string The Symfony version + */ + public function getSymfonyVersion() + { + return $this->data['symfony_version']; + } + + /** + * Returns the state of the current Symfony release. + * + * @return string One of: unknown, dev, stable, eom, eol + */ + public function getSymfonyState() + { + return $this->data['symfony_state']; + } + + public function setCacheVersionInfo($cacheVersionInfo) + { + $this->cacheVersionInfo = $cacheVersionInfo; + } + + /** + * Gets the PHP version. + * + * @return string The PHP version + */ + public function getPhpVersion() + { + return $this->data['php_version']; + } + + /** + * Gets the application name. + * + * @return string The application name + */ + public function getAppName() + { + return $this->data['name']; + } + + /** + * Gets the environment. + * + * @return string The environment + */ + public function getEnv() + { + return $this->data['env']; + } + + /** + * Returns true if the debug is enabled. + * + * @return bool true if debug is enabled, false otherwise + */ + public function isDebug() + { + return $this->data['debug']; + } + + /** + * Returns true if the XDebug is enabled. + * + * @return bool true if XDebug is enabled, false otherwise + */ + public function hasXDebug() + { + return $this->data['xdebug_enabled']; + } + + /** + * Returns true if EAccelerator is enabled. + * + * @return bool true if EAccelerator is enabled, false otherwise + */ + public function hasEAccelerator() + { + return $this->data['eaccel_enabled']; + } + + /** + * Returns true if APC is enabled. + * + * @return bool true if APC is enabled, false otherwise + */ + public function hasApc() + { + return $this->data['apc_enabled']; + } + + /** + * Returns true if Zend OPcache is enabled. + * + * @return bool true if Zend OPcache is enabled, false otherwise + */ + public function hasZendOpcache() + { + return $this->data['zend_opcache_enabled']; + } + + /** + * Returns true if XCache is enabled. + * + * @return bool true if XCache is enabled, false otherwise + */ + public function hasXCache() + { + return $this->data['xcache_enabled']; + } + + /** + * Returns true if WinCache is enabled. + * + * @return bool true if WinCache is enabled, false otherwise + */ + public function hasWinCache() + { + return $this->data['wincache_enabled']; + } + + /** + * Returns true if any accelerator is enabled. + * + * @return bool true if any accelerator is enabled, false otherwise + */ + public function hasAccelerator() + { + return $this->hasApc() || $this->hasZendOpcache() || $this->hasEAccelerator() || $this->hasXCache() || $this->hasWinCache(); + } + + public function getBundles() + { + return $this->data['bundles']; + } + + /** + * Gets the PHP SAPI name. + * + * @return string The environment + */ + public function getSapiName() + { + return $this->data['sapi_name']; + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'config'; + } + + /** + * Tries to retrieve information about the current Symfony version. + * + * @return string One of: dev, stable, eom, eol + */ + private function determineSymfonyState() + { + $now = new \DateTime(); + $eom = \DateTime::createFromFormat('m/Y', Kernel::END_OF_MAINTENANCE)->modify('last day of this month'); + $eol = \DateTime::createFromFormat('m/Y', Kernel::END_OF_LIFE)->modify('last day of this month'); + + if ($now > $eol) { + $versionState = 'eol'; + } elseif ($now > $eom) { + $versionState = 'eom'; + } elseif ('' !== Kernel::EXTRA_VERSION) { + $versionState = 'dev'; + } else { + $versionState = 'stable'; + } + + return $versionState; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DataCollector/DataCollector.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DataCollector/DataCollector.php new file mode 100644 index 0000000..5dca652 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DataCollector/DataCollector.php @@ -0,0 +1,58 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\DataCollector; + +use Symfony\Component\HttpKernel\DataCollector\Util\ValueExporter; + +/** + * DataCollector. + * + * Children of this class must store the collected data in the data property. + * + * @author Fabien Potencier + * @author Bernhard Schussek + */ +abstract class DataCollector implements DataCollectorInterface, \Serializable +{ + protected $data = array(); + + /** + * @var ValueExporter + */ + private $valueExporter; + + public function serialize() + { + return serialize($this->data); + } + + public function unserialize($data) + { + $this->data = unserialize($data); + } + + /** + * Converts a PHP variable to a string. + * + * @param mixed $var A PHP variable + * + * @return string The string representation of the variable + */ + protected function varToString($var) + { + if (null === $this->valueExporter) { + $this->valueExporter = new ValueExporter(); + } + + return $this->valueExporter->exportValue($var); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DataCollector/DataCollectorInterface.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DataCollector/DataCollectorInterface.php new file mode 100644 index 0000000..2820ad5 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DataCollector/DataCollectorInterface.php @@ -0,0 +1,39 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\DataCollector; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; + +/** + * DataCollectorInterface. + * + * @author Fabien Potencier + */ +interface DataCollectorInterface +{ + /** + * Collects data for the given Request and Response. + * + * @param Request $request A Request instance + * @param Response $response A Response instance + * @param \Exception $exception An Exception instance + */ + public function collect(Request $request, Response $response, \Exception $exception = null); + + /** + * Returns the name of the collector. + * + * @return string The collector name + */ + public function getName(); +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DataCollector/DumpDataCollector.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DataCollector/DumpDataCollector.php new file mode 100644 index 0000000..985db4b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DataCollector/DumpDataCollector.php @@ -0,0 +1,307 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\DataCollector; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\RequestStack; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\Stopwatch\Stopwatch; +use Symfony\Component\VarDumper\Cloner\Data; +use Symfony\Component\VarDumper\Cloner\VarCloner; +use Symfony\Component\VarDumper\Dumper\CliDumper; +use Symfony\Component\VarDumper\Dumper\HtmlDumper; +use Symfony\Component\VarDumper\Dumper\DataDumperInterface; + +/** + * @author Nicolas Grekas + */ +class DumpDataCollector extends DataCollector implements DataDumperInterface +{ + private $stopwatch; + private $fileLinkFormat; + private $dataCount = 0; + private $isCollected = true; + private $clonesCount = 0; + private $clonesIndex = 0; + private $rootRefs; + private $charset; + private $requestStack; + private $dumper; + private $dumperIsInjected; + + public function __construct(Stopwatch $stopwatch = null, $fileLinkFormat = null, $charset = null, RequestStack $requestStack = null, DataDumperInterface $dumper = null) + { + $this->stopwatch = $stopwatch; + $this->fileLinkFormat = $fileLinkFormat ?: ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format'); + $this->charset = $charset ?: ini_get('php.output_encoding') ?: ini_get('default_charset') ?: 'UTF-8'; + $this->requestStack = $requestStack; + $this->dumper = $dumper; + $this->dumperIsInjected = null !== $dumper; + + // All clones share these properties by reference: + $this->rootRefs = array( + &$this->data, + &$this->dataCount, + &$this->isCollected, + &$this->clonesCount, + ); + } + + public function __clone() + { + $this->clonesIndex = ++$this->clonesCount; + } + + public function dump(Data $data) + { + if ($this->stopwatch) { + $this->stopwatch->start('dump'); + } + if ($this->isCollected) { + $this->isCollected = false; + } + + $trace = DEBUG_BACKTRACE_PROVIDE_OBJECT | DEBUG_BACKTRACE_IGNORE_ARGS; + if (PHP_VERSION_ID >= 50400) { + $trace = debug_backtrace($trace, 7); + } else { + $trace = debug_backtrace($trace); + } + + $file = $trace[0]['file']; + $line = $trace[0]['line']; + $name = false; + $fileExcerpt = false; + + for ($i = 1; $i < 7; ++$i) { + if (isset($trace[$i]['class'], $trace[$i]['function']) + && 'dump' === $trace[$i]['function'] + && 'Symfony\Component\VarDumper\VarDumper' === $trace[$i]['class'] + ) { + $file = $trace[$i]['file']; + $line = $trace[$i]['line']; + + while (++$i < 7) { + if (isset($trace[$i]['function'], $trace[$i]['file']) && empty($trace[$i]['class']) && 0 !== strpos($trace[$i]['function'], 'call_user_func')) { + $file = $trace[$i]['file']; + $line = $trace[$i]['line']; + + break; + } elseif (isset($trace[$i]['object']) && $trace[$i]['object'] instanceof \Twig_Template) { + $info = $trace[$i]['object']; + $name = $info->getTemplateName(); + $src = method_exists($info, 'getSource') ? $info->getSource() : $info->getEnvironment()->getLoader()->getSource($name); + $info = $info->getDebugInfo(); + if (null !== $src && isset($info[$trace[$i - 1]['line']])) { + $file = false; + $line = $info[$trace[$i - 1]['line']]; + $src = explode("\n", $src); + $fileExcerpt = array(); + + for ($i = max($line - 3, 1), $max = min($line + 3, count($src)); $i <= $max; ++$i) { + $fileExcerpt[] = ''.$this->htmlEncode($src[$i - 1]).''; + } + + $fileExcerpt = '
      '.implode("\n", $fileExcerpt).'
    '; + } + break; + } + } + break; + } + } + + if (false === $name) { + $name = str_replace('\\', '/', $file); + $name = substr($name, strrpos($name, '/') + 1); + } + + if ($this->dumper) { + $this->doDump($data, $name, $file, $line); + } + + $this->data[] = compact('data', 'name', 'file', 'line', 'fileExcerpt'); + ++$this->dataCount; + + if ($this->stopwatch) { + $this->stopwatch->stop('dump'); + } + } + + public function collect(Request $request, Response $response, \Exception $exception = null) + { + // Sub-requests and programmatic calls stay in the collected profile. + if ($this->dumper || ($this->requestStack && $this->requestStack->getMasterRequest() !== $request) || $request->isXmlHttpRequest() || $request->headers->has('Origin')) { + return; + } + + // In all other conditions that remove the web debug toolbar, dumps are written on the output. + if (!$this->requestStack + || !$response->headers->has('X-Debug-Token') + || $response->isRedirection() + || ($response->headers->has('Content-Type') && false === strpos($response->headers->get('Content-Type'), 'html')) + || 'html' !== $request->getRequestFormat() + || false === strripos($response->getContent(), '') + ) { + if ($response->headers->has('Content-Type') && false !== strpos($response->headers->get('Content-Type'), 'html')) { + $this->dumper = new HtmlDumper('php://output', $this->charset); + } else { + $this->dumper = new CliDumper('php://output', $this->charset); + } + + foreach ($this->data as $dump) { + $this->doDump($dump['data'], $dump['name'], $dump['file'], $dump['line']); + } + } + } + + public function serialize() + { + if ($this->clonesCount !== $this->clonesIndex) { + return 'a:0:{}'; + } + + $this->data[] = $this->fileLinkFormat; + $this->data[] = $this->charset; + $ser = serialize($this->data); + $this->data = array(); + $this->dataCount = 0; + $this->isCollected = true; + if (!$this->dumperIsInjected) { + $this->dumper = null; + } + + return $ser; + } + + public function unserialize($data) + { + parent::unserialize($data); + $charset = array_pop($this->data); + $fileLinkFormat = array_pop($this->data); + $this->dataCount = count($this->data); + self::__construct($this->stopwatch, $fileLinkFormat, $charset); + } + + public function getDumpsCount() + { + return $this->dataCount; + } + + public function getDumps($format, $maxDepthLimit = -1, $maxItemsPerDepth = -1) + { + $data = fopen('php://memory', 'r+b'); + + if ('html' === $format) { + $dumper = new HtmlDumper($data, $this->charset); + } else { + throw new \InvalidArgumentException(sprintf('Invalid dump format: %s', $format)); + } + $dumps = array(); + + foreach ($this->data as $dump) { + if (method_exists($dump['data'], 'withMaxDepth')) { + $dumper->dump($dump['data']->withMaxDepth($maxDepthLimit)->withMaxItemsPerDepth($maxItemsPerDepth)); + } else { + // getLimitedClone is @deprecated, to be removed in 3.0 + $dumper->dump($dump['data']->getLimitedClone($maxDepthLimit, $maxItemsPerDepth)); + } + $dump['data'] = stream_get_contents($data, -1, 0); + ftruncate($data, 0); + rewind($data); + $dumps[] = $dump; + } + + return $dumps; + } + + public function getName() + { + return 'dump'; + } + + public function __destruct() + { + if (0 === $this->clonesCount-- && !$this->isCollected && $this->data) { + $this->clonesCount = 0; + $this->isCollected = true; + + $h = headers_list(); + $i = count($h); + array_unshift($h, 'Content-Type: '.ini_get('default_mimetype')); + while (0 !== stripos($h[$i], 'Content-Type:')) { + --$i; + } + + if ('cli' !== PHP_SAPI && stripos($h[$i], 'html')) { + $this->dumper = new HtmlDumper('php://output', $this->charset); + } else { + $this->dumper = new CliDumper('php://output', $this->charset); + } + + foreach ($this->data as $i => $dump) { + $this->data[$i] = null; + $this->doDump($dump['data'], $dump['name'], $dump['file'], $dump['line']); + } + + $this->data = array(); + $this->dataCount = 0; + } + } + + private function doDump($data, $name, $file, $line) + { + if (PHP_VERSION_ID >= 50400 && $this->dumper instanceof CliDumper) { + $contextDumper = function ($name, $file, $line, $fileLinkFormat) { + if ($this instanceof HtmlDumper) { + if ('' !== $file) { + $s = $this->style('meta', '%s'); + $name = strip_tags($this->style('', $name)); + $file = strip_tags($this->style('', $file)); + if ($fileLinkFormat) { + $link = strtr(strip_tags($this->style('', $fileLinkFormat)), array('%f' => $file, '%l' => (int) $line)); + $name = sprintf(''.$s.'', $link, $file, $name); + } else { + $name = sprintf(''.$s.'', $file, $name); + } + } else { + $name = $this->style('meta', $name); + } + $this->line = $name.' on line '.$this->style('meta', $line).':'; + } else { + $this->line = $this->style('meta', $name).' on line '.$this->style('meta', $line).':'; + } + $this->dumpLine(0); + }; + $contextDumper = $contextDumper->bindTo($this->dumper, $this->dumper); + $contextDumper($name, $file, $line, $this->fileLinkFormat); + } else { + $cloner = new VarCloner(); + $this->dumper->dump($cloner->cloneVar($name.' on line '.$line.':')); + } + $this->dumper->dump($data); + } + + private function htmlEncode($s) + { + $html = ''; + + $dumper = new HtmlDumper(function ($line) use (&$html) {$html .= $line;}, $this->charset); + $dumper->setDumpHeader(''); + $dumper->setDumpBoundaries('', ''); + + $cloner = new VarCloner(); + $dumper->dump($cloner->cloneVar($s)); + + return substr(strip_tags($html), 1, -1); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DataCollector/EventDataCollector.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DataCollector/EventDataCollector.php new file mode 100644 index 0000000..0a87bc3 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DataCollector/EventDataCollector.php @@ -0,0 +1,107 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\DataCollector; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcherInterface; + +/** + * EventDataCollector. + * + * @author Fabien Potencier + */ +class EventDataCollector extends DataCollector implements LateDataCollectorInterface +{ + protected $dispatcher; + + public function __construct(EventDispatcherInterface $dispatcher = null) + { + $this->dispatcher = $dispatcher; + } + + /** + * {@inheritdoc} + */ + public function collect(Request $request, Response $response, \Exception $exception = null) + { + $this->data = array( + 'called_listeners' => array(), + 'not_called_listeners' => array(), + ); + } + + public function lateCollect() + { + if ($this->dispatcher instanceof TraceableEventDispatcherInterface) { + $this->setCalledListeners($this->dispatcher->getCalledListeners()); + $this->setNotCalledListeners($this->dispatcher->getNotCalledListeners()); + } + } + + /** + * Sets the called listeners. + * + * @param array $listeners An array of called listeners + * + * @see TraceableEventDispatcherInterface + */ + public function setCalledListeners(array $listeners) + { + $this->data['called_listeners'] = $listeners; + } + + /** + * Gets the called listeners. + * + * @return array An array of called listeners + * + * @see TraceableEventDispatcherInterface + */ + public function getCalledListeners() + { + return $this->data['called_listeners']; + } + + /** + * Sets the not called listeners. + * + * @param array $listeners An array of not called listeners + * + * @see TraceableEventDispatcherInterface + */ + public function setNotCalledListeners(array $listeners) + { + $this->data['not_called_listeners'] = $listeners; + } + + /** + * Gets the not called listeners. + * + * @return array An array of not called listeners + * + * @see TraceableEventDispatcherInterface + */ + public function getNotCalledListeners() + { + return $this->data['not_called_listeners']; + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'events'; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DataCollector/ExceptionDataCollector.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DataCollector/ExceptionDataCollector.php new file mode 100644 index 0000000..9fe8264 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DataCollector/ExceptionDataCollector.php @@ -0,0 +1,104 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\DataCollector; + +use Symfony\Component\Debug\Exception\FlattenException; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; + +/** + * ExceptionDataCollector. + * + * @author Fabien Potencier + */ +class ExceptionDataCollector extends DataCollector +{ + /** + * {@inheritdoc} + */ + public function collect(Request $request, Response $response, \Exception $exception = null) + { + if (null !== $exception) { + $this->data = array( + 'exception' => FlattenException::create($exception), + ); + } + } + + /** + * Checks if the exception is not null. + * + * @return bool true if the exception is not null, false otherwise + */ + public function hasException() + { + return isset($this->data['exception']); + } + + /** + * Gets the exception. + * + * @return \Exception The exception + */ + public function getException() + { + return $this->data['exception']; + } + + /** + * Gets the exception message. + * + * @return string The exception message + */ + public function getMessage() + { + return $this->data['exception']->getMessage(); + } + + /** + * Gets the exception code. + * + * @return int The exception code + */ + public function getCode() + { + return $this->data['exception']->getCode(); + } + + /** + * Gets the status code. + * + * @return int The status code + */ + public function getStatusCode() + { + return $this->data['exception']->getStatusCode(); + } + + /** + * Gets the exception trace. + * + * @return array The exception trace + */ + public function getTrace() + { + return $this->data['exception']->getTrace(); + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'exception'; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DataCollector/LateDataCollectorInterface.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DataCollector/LateDataCollectorInterface.php new file mode 100644 index 0000000..012332d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DataCollector/LateDataCollectorInterface.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\DataCollector; + +/** + * LateDataCollectorInterface. + * + * @author Fabien Potencier + */ +interface LateDataCollectorInterface +{ + /** + * Collects data as late as possible. + */ + public function lateCollect(); +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DataCollector/LoggerDataCollector.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DataCollector/LoggerDataCollector.php new file mode 100644 index 0000000..6664a33 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DataCollector/LoggerDataCollector.php @@ -0,0 +1,188 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\DataCollector; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\Log\DebugLoggerInterface; + +/** + * LogDataCollector. + * + * @author Fabien Potencier + */ +class LoggerDataCollector extends DataCollector implements LateDataCollectorInterface +{ + private $logger; + + public function __construct($logger = null) + { + if (null !== $logger && $logger instanceof DebugLoggerInterface) { + $this->logger = $logger; + } + } + + /** + * {@inheritdoc} + */ + public function collect(Request $request, Response $response, \Exception $exception = null) + { + // everything is done as late as possible + } + + /** + * {@inheritdoc} + */ + public function lateCollect() + { + if (null !== $this->logger) { + $this->data = $this->computeErrorsCount(); + $this->data['logs'] = $this->sanitizeLogs($this->logger->getLogs()); + } + } + + /** + * Gets the logs. + * + * @return array An array of logs + */ + public function getLogs() + { + return isset($this->data['logs']) ? $this->data['logs'] : array(); + } + + public function getPriorities() + { + return isset($this->data['priorities']) ? $this->data['priorities'] : array(); + } + + public function countErrors() + { + return isset($this->data['error_count']) ? $this->data['error_count'] : 0; + } + + public function countDeprecations() + { + return isset($this->data['deprecation_count']) ? $this->data['deprecation_count'] : 0; + } + + public function countScreams() + { + return isset($this->data['scream_count']) ? $this->data['scream_count'] : 0; + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'logger'; + } + + private function sanitizeLogs($logs) + { + $errorContextById = array(); + $sanitizedLogs = array(); + + foreach ($logs as $log) { + $context = $this->sanitizeContext($log['context']); + + if (isset($context['type'], $context['file'], $context['line'], $context['level'])) { + $errorId = md5("{$context['type']}/{$context['line']}/{$context['file']}\x00{$log['message']}", true); + $silenced = !($context['type'] & $context['level']); + + if (isset($errorContextById[$errorId])) { + if (isset($errorContextById[$errorId]['errorCount'])) { + ++$errorContextById[$errorId]['errorCount']; + } else { + $errorContextById[$errorId]['errorCount'] = 2; + } + + if (!$silenced && isset($errorContextById[$errorId]['scream'])) { + unset($errorContextById[$errorId]['scream']); + $errorContextById[$errorId]['level'] = $context['level']; + } + + continue; + } + + $errorContextById[$errorId] = &$context; + if ($silenced) { + $context['scream'] = true; + } + + $log['context'] = &$context; + unset($context); + } else { + $log['context'] = $context; + } + + $sanitizedLogs[] = $log; + } + + return $sanitizedLogs; + } + + private function sanitizeContext($context) + { + if (is_array($context)) { + foreach ($context as $key => $value) { + $context[$key] = $this->sanitizeContext($value); + } + + return $context; + } + + if (is_resource($context)) { + return sprintf('Resource(%s)', get_resource_type($context)); + } + + if (is_object($context)) { + return sprintf('Object(%s)', get_class($context)); + } + + return $context; + } + + private function computeErrorsCount() + { + $count = array( + 'error_count' => $this->logger->countErrors(), + 'deprecation_count' => 0, + 'scream_count' => 0, + 'priorities' => array(), + ); + + foreach ($this->logger->getLogs() as $log) { + if (isset($count['priorities'][$log['priority']])) { + ++$count['priorities'][$log['priority']]['count']; + } else { + $count['priorities'][$log['priority']] = array( + 'count' => 1, + 'name' => $log['priorityName'], + ); + } + + if (isset($log['context']['type'], $log['context']['level'])) { + if (E_DEPRECATED === $log['context']['type'] || E_USER_DEPRECATED === $log['context']['type']) { + ++$count['deprecation_count']; + } elseif (!($log['context']['type'] & $log['context']['level'])) { + ++$count['scream_count']; + } + } + } + + ksort($count['priorities']); + + return $count; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DataCollector/MemoryDataCollector.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DataCollector/MemoryDataCollector.php new file mode 100644 index 0000000..9385010 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DataCollector/MemoryDataCollector.php @@ -0,0 +1,109 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\DataCollector; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; + +/** + * MemoryDataCollector. + * + * @author Fabien Potencier + */ +class MemoryDataCollector extends DataCollector implements LateDataCollectorInterface +{ + public function __construct() + { + $this->data = array( + 'memory' => 0, + 'memory_limit' => $this->convertToBytes(ini_get('memory_limit')), + ); + } + + /** + * {@inheritdoc} + */ + public function collect(Request $request, Response $response, \Exception $exception = null) + { + $this->updateMemoryUsage(); + } + + /** + * {@inheritdoc} + */ + public function lateCollect() + { + $this->updateMemoryUsage(); + } + + /** + * Gets the memory. + * + * @return int The memory + */ + public function getMemory() + { + return $this->data['memory']; + } + + /** + * Gets the PHP memory limit. + * + * @return int The memory limit + */ + public function getMemoryLimit() + { + return $this->data['memory_limit']; + } + + /** + * Updates the memory usage data. + */ + public function updateMemoryUsage() + { + $this->data['memory'] = memory_get_peak_usage(true); + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'memory'; + } + + private function convertToBytes($memoryLimit) + { + if ('-1' === $memoryLimit) { + return -1; + } + + $memoryLimit = strtolower($memoryLimit); + $max = strtolower(ltrim($memoryLimit, '+')); + if (0 === strpos($max, '0x')) { + $max = intval($max, 16); + } elseif (0 === strpos($max, '0')) { + $max = intval($max, 8); + } else { + $max = (int) $max; + } + + switch (substr($memoryLimit, -1)) { + case 't': $max *= 1024; + case 'g': $max *= 1024; + case 'm': $max *= 1024; + case 'k': $max *= 1024; + } + + return $max; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DataCollector/RequestDataCollector.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DataCollector/RequestDataCollector.php new file mode 100644 index 0000000..9a499a7 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DataCollector/RequestDataCollector.php @@ -0,0 +1,342 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\DataCollector; + +use Symfony\Component\HttpFoundation\ParameterBag; +use Symfony\Component\HttpFoundation\HeaderBag; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpFoundation\ResponseHeaderBag; +use Symfony\Component\HttpKernel\KernelEvents; +use Symfony\Component\HttpKernel\Event\FilterControllerEvent; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +/** + * RequestDataCollector. + * + * @author Fabien Potencier + */ +class RequestDataCollector extends DataCollector implements EventSubscriberInterface +{ + protected $controllers; + + public function __construct() + { + $this->controllers = new \SplObjectStorage(); + } + + /** + * {@inheritdoc} + */ + public function collect(Request $request, Response $response, \Exception $exception = null) + { + $responseHeaders = $response->headers->all(); + $cookies = array(); + foreach ($response->headers->getCookies() as $cookie) { + $cookies[] = $this->getCookieHeader($cookie->getName(), $cookie->getValue(), $cookie->getExpiresTime(), $cookie->getPath(), $cookie->getDomain(), $cookie->isSecure(), $cookie->isHttpOnly()); + } + if (count($cookies) > 0) { + $responseHeaders['Set-Cookie'] = $cookies; + } + + // attributes are serialized and as they can be anything, they need to be converted to strings. + $attributes = array(); + foreach ($request->attributes->all() as $key => $value) { + if ('_route' === $key && is_object($value)) { + $attributes[$key] = $this->varToString($value->getPath()); + } elseif ('_route_params' === $key) { + // we need to keep route params as an array (see getRouteParams()) + foreach ($value as $k => $v) { + $value[$k] = $this->varToString($v); + } + $attributes[$key] = $value; + } else { + $attributes[$key] = $this->varToString($value); + } + } + + $content = null; + try { + $content = $request->getContent(); + } catch (\LogicException $e) { + // the user already got the request content as a resource + $content = false; + } + + $sessionMetadata = array(); + $sessionAttributes = array(); + $flashes = array(); + if ($request->hasSession()) { + $session = $request->getSession(); + if ($session->isStarted()) { + $sessionMetadata['Created'] = date(DATE_RFC822, $session->getMetadataBag()->getCreated()); + $sessionMetadata['Last used'] = date(DATE_RFC822, $session->getMetadataBag()->getLastUsed()); + $sessionMetadata['Lifetime'] = $session->getMetadataBag()->getLifetime(); + $sessionAttributes = $session->all(); + $flashes = $session->getFlashBag()->peekAll(); + } + } + + $statusCode = $response->getStatusCode(); + + $this->data = array( + 'format' => $request->getRequestFormat(), + 'content' => $content, + 'content_type' => $response->headers->get('Content-Type', 'text/html'), + 'status_text' => isset(Response::$statusTexts[$statusCode]) ? Response::$statusTexts[$statusCode] : '', + 'status_code' => $statusCode, + 'request_query' => $request->query->all(), + 'request_request' => $request->request->all(), + 'request_headers' => $request->headers->all(), + 'request_server' => $request->server->all(), + 'request_cookies' => $request->cookies->all(), + 'request_attributes' => $attributes, + 'response_headers' => $responseHeaders, + 'session_metadata' => $sessionMetadata, + 'session_attributes' => $sessionAttributes, + 'flashes' => $flashes, + 'path_info' => $request->getPathInfo(), + 'controller' => 'n/a', + 'locale' => $request->getLocale(), + ); + + if (isset($this->data['request_headers']['php-auth-pw'])) { + $this->data['request_headers']['php-auth-pw'] = '******'; + } + + if (isset($this->data['request_server']['PHP_AUTH_PW'])) { + $this->data['request_server']['PHP_AUTH_PW'] = '******'; + } + + if (isset($this->data['request_request']['_password'])) { + $this->data['request_request']['_password'] = '******'; + } + + if (isset($this->controllers[$request])) { + $controller = $this->controllers[$request]; + if (is_array($controller)) { + try { + $r = new \ReflectionMethod($controller[0], $controller[1]); + $this->data['controller'] = array( + 'class' => is_object($controller[0]) ? get_class($controller[0]) : $controller[0], + 'method' => $controller[1], + 'file' => $r->getFileName(), + 'line' => $r->getStartLine(), + ); + } catch (\ReflectionException $e) { + if (is_callable($controller)) { + // using __call or __callStatic + $this->data['controller'] = array( + 'class' => is_object($controller[0]) ? get_class($controller[0]) : $controller[0], + 'method' => $controller[1], + 'file' => 'n/a', + 'line' => 'n/a', + ); + } + } + } elseif ($controller instanceof \Closure) { + $r = new \ReflectionFunction($controller); + $this->data['controller'] = array( + 'class' => $r->getName(), + 'method' => null, + 'file' => $r->getFileName(), + 'line' => $r->getStartLine(), + ); + } elseif (is_object($controller)) { + $r = new \ReflectionClass($controller); + $this->data['controller'] = array( + 'class' => $r->getName(), + 'method' => null, + 'file' => $r->getFileName(), + 'line' => $r->getStartLine(), + ); + } else { + $this->data['controller'] = (string) $controller ?: 'n/a'; + } + unset($this->controllers[$request]); + } + } + + public function getPathInfo() + { + return $this->data['path_info']; + } + + public function getRequestRequest() + { + return new ParameterBag($this->data['request_request']); + } + + public function getRequestQuery() + { + return new ParameterBag($this->data['request_query']); + } + + public function getRequestHeaders() + { + return new HeaderBag($this->data['request_headers']); + } + + public function getRequestServer() + { + return new ParameterBag($this->data['request_server']); + } + + public function getRequestCookies() + { + return new ParameterBag($this->data['request_cookies']); + } + + public function getRequestAttributes() + { + return new ParameterBag($this->data['request_attributes']); + } + + public function getResponseHeaders() + { + return new ResponseHeaderBag($this->data['response_headers']); + } + + public function getSessionMetadata() + { + return $this->data['session_metadata']; + } + + public function getSessionAttributes() + { + return $this->data['session_attributes']; + } + + public function getFlashes() + { + return $this->data['flashes']; + } + + public function getContent() + { + return $this->data['content']; + } + + public function getContentType() + { + return $this->data['content_type']; + } + + public function getStatusText() + { + return $this->data['status_text']; + } + + public function getStatusCode() + { + return $this->data['status_code']; + } + + public function getFormat() + { + return $this->data['format']; + } + + public function getLocale() + { + return $this->data['locale']; + } + + /** + * Gets the route name. + * + * The _route request attributes is automatically set by the Router Matcher. + * + * @return string The route + */ + public function getRoute() + { + return isset($this->data['request_attributes']['_route']) ? $this->data['request_attributes']['_route'] : ''; + } + + /** + * Gets the route parameters. + * + * The _route_params request attributes is automatically set by the RouterListener. + * + * @return array The parameters + */ + public function getRouteParams() + { + return isset($this->data['request_attributes']['_route_params']) ? $this->data['request_attributes']['_route_params'] : array(); + } + + /** + * Gets the controller. + * + * @return string The controller as a string + */ + public function getController() + { + return $this->data['controller']; + } + + public function onKernelController(FilterControllerEvent $event) + { + $this->controllers[$event->getRequest()] = $event->getController(); + } + + public static function getSubscribedEvents() + { + return array(KernelEvents::CONTROLLER => 'onKernelController'); + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'request'; + } + + private function getCookieHeader($name, $value, $expires, $path, $domain, $secure, $httponly) + { + $cookie = sprintf('%s=%s', $name, urlencode($value)); + + if (0 !== $expires) { + if (is_numeric($expires)) { + $expires = (int) $expires; + } elseif ($expires instanceof \DateTime) { + $expires = $expires->getTimestamp(); + } else { + $tmp = strtotime($expires); + if (false === $tmp || -1 == $tmp) { + throw new \InvalidArgumentException(sprintf('The "expires" cookie parameter is not valid (%s).', $expires)); + } + $expires = $tmp; + } + + $cookie .= '; expires='.str_replace('+0000', '', \DateTime::createFromFormat('U', $expires, new \DateTimeZone('GMT'))->format('D, d-M-Y H:i:s T')); + } + + if ($domain) { + $cookie .= '; domain='.$domain; + } + + $cookie .= '; path='.$path; + + if ($secure) { + $cookie .= '; secure'; + } + + if ($httponly) { + $cookie .= '; httponly'; + } + + return $cookie; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DataCollector/RouterDataCollector.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DataCollector/RouterDataCollector.php new file mode 100644 index 0000000..76d9623 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DataCollector/RouterDataCollector.php @@ -0,0 +1,102 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\DataCollector; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpFoundation\RedirectResponse; +use Symfony\Component\HttpKernel\Event\FilterControllerEvent; + +/** + * RouterDataCollector. + * + * @author Fabien Potencier + */ +class RouterDataCollector extends DataCollector +{ + protected $controllers; + + public function __construct() + { + $this->controllers = new \SplObjectStorage(); + + $this->data = array( + 'redirect' => false, + 'url' => null, + 'route' => null, + ); + } + + /** + * {@inheritdoc} + */ + public function collect(Request $request, Response $response, \Exception $exception = null) + { + if ($response instanceof RedirectResponse) { + $this->data['redirect'] = true; + $this->data['url'] = $response->getTargetUrl(); + + if ($this->controllers->contains($request)) { + $this->data['route'] = $this->guessRoute($request, $this->controllers[$request]); + } + } + + unset($this->controllers[$request]); + } + + protected function guessRoute(Request $request, $controller) + { + return 'n/a'; + } + + /** + * Remembers the controller associated to each request. + * + * @param FilterControllerEvent $event The filter controller event + */ + public function onKernelController(FilterControllerEvent $event) + { + $this->controllers[$event->getRequest()] = $event->getController(); + } + + /** + * @return bool Whether this request will result in a redirect + */ + public function getRedirect() + { + return $this->data['redirect']; + } + + /** + * @return string|null The target URL + */ + public function getTargetUrl() + { + return $this->data['url']; + } + + /** + * @return string|null The target route + */ + public function getTargetRoute() + { + return $this->data['route']; + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'router'; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DataCollector/TimeDataCollector.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DataCollector/TimeDataCollector.php new file mode 100644 index 0000000..4ccaafa --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DataCollector/TimeDataCollector.php @@ -0,0 +1,136 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\DataCollector; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\KernelInterface; + +/** + * TimeDataCollector. + * + * @author Fabien Potencier + */ +class TimeDataCollector extends DataCollector implements LateDataCollectorInterface +{ + protected $kernel; + protected $stopwatch; + + public function __construct(KernelInterface $kernel = null, $stopwatch = null) + { + $this->kernel = $kernel; + $this->stopwatch = $stopwatch; + } + + /** + * {@inheritdoc} + */ + public function collect(Request $request, Response $response, \Exception $exception = null) + { + if (null !== $this->kernel) { + $startTime = $this->kernel->getStartTime(); + } else { + $startTime = $request->server->get('REQUEST_TIME_FLOAT', $request->server->get('REQUEST_TIME')); + } + + $this->data = array( + 'token' => $response->headers->get('X-Debug-Token'), + 'start_time' => $startTime * 1000, + 'events' => array(), + ); + } + + /** + * {@inheritdoc} + */ + public function lateCollect() + { + if (null !== $this->stopwatch && isset($this->data['token'])) { + $this->setEvents($this->stopwatch->getSectionEvents($this->data['token'])); + } + unset($this->data['token']); + } + + /** + * Sets the request events. + * + * @param array $events The request events + */ + public function setEvents(array $events) + { + foreach ($events as $event) { + $event->ensureStopped(); + } + + $this->data['events'] = $events; + } + + /** + * Gets the request events. + * + * @return array The request events + */ + public function getEvents() + { + return $this->data['events']; + } + + /** + * Gets the request elapsed time. + * + * @return float The elapsed time + */ + public function getDuration() + { + if (!isset($this->data['events']['__section__'])) { + return 0; + } + + $lastEvent = $this->data['events']['__section__']; + + return $lastEvent->getOrigin() + $lastEvent->getDuration() - $this->getStartTime(); + } + + /** + * Gets the initialization time. + * + * This is the time spent until the beginning of the request handling. + * + * @return float The elapsed time + */ + public function getInitTime() + { + if (!isset($this->data['events']['__section__'])) { + return 0; + } + + return $this->data['events']['__section__']->getOrigin() - $this->getStartTime(); + } + + /** + * Gets the request time. + * + * @return int The time + */ + public function getStartTime() + { + return $this->data['start_time']; + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'time'; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DataCollector/Util/ValueExporter.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DataCollector/Util/ValueExporter.php new file mode 100644 index 0000000..09fe4e3 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DataCollector/Util/ValueExporter.php @@ -0,0 +1,89 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\DataCollector\Util; + +/** + * @author Bernhard Schussek + */ +class ValueExporter +{ + /** + * Converts a PHP value to a string. + * + * @param mixed $value The PHP value + * @param int $depth only for internal usage + * @param bool $deep only for internal usage + * + * @return string The string representation of the given value + */ + public function exportValue($value, $depth = 1, $deep = false) + { + if ($value instanceof \__PHP_Incomplete_Class) { + return sprintf('__PHP_Incomplete_Class(%s)', $this->getClassNameFromIncomplete($value)); + } + + if (is_object($value)) { + if ($value instanceof \DateTime || $value instanceof \DateTimeInterface) { + return sprintf('Object(%s) - %s', get_class($value), $value->format(\DateTime::ISO8601)); + } + + return sprintf('Object(%s)', get_class($value)); + } + + if (is_array($value)) { + if (empty($value)) { + return '[]'; + } + + $indent = str_repeat(' ', $depth); + + $a = array(); + foreach ($value as $k => $v) { + if (is_array($v)) { + $deep = true; + } + $a[] = sprintf('%s => %s', $k, $this->exportValue($v, $depth + 1, $deep)); + } + + if ($deep) { + return sprintf("[\n%s%s\n%s]", $indent, implode(sprintf(", \n%s", $indent), $a), str_repeat(' ', $depth - 1)); + } + + return sprintf('[%s]', implode(', ', $a)); + } + + if (is_resource($value)) { + return sprintf('Resource(%s#%d)', get_resource_type($value), $value); + } + + if (null === $value) { + return 'null'; + } + + if (false === $value) { + return 'false'; + } + + if (true === $value) { + return 'true'; + } + + return (string) $value; + } + + private function getClassNameFromIncomplete(\__PHP_Incomplete_Class $value) + { + $array = new \ArrayObject($value); + + return $array['__PHP_Incomplete_Class_Name']; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Debug/ErrorHandler.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Debug/ErrorHandler.php new file mode 100644 index 0000000..af714a3 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Debug/ErrorHandler.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Debug; + +@trigger_error('The '.__NAMESPACE__.'\ErrorHandler class is deprecated since version 2.3 and will be removed in 3.0. Use the Symfony\Component\Debug\ErrorHandler class instead.', E_USER_DEPRECATED); + +use Symfony\Component\Debug\ErrorHandler as DebugErrorHandler; + +/** + * ErrorHandler. + * + * @author Fabien Potencier + * + * @deprecated since version 2.3, to be removed in 3.0. Use the same class from the Debug component instead. + */ +class ErrorHandler extends DebugErrorHandler +{ +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Debug/ExceptionHandler.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Debug/ExceptionHandler.php new file mode 100644 index 0000000..50755d9 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Debug/ExceptionHandler.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Debug; + +@trigger_error('The '.__NAMESPACE__.'\ExceptionHandler class is deprecated since version 2.3 and will be removed in 3.0. Use the Symfony\Component\Debug\ExceptionHandler class instead.', E_USER_DEPRECATED); + +use Symfony\Component\Debug\ExceptionHandler as DebugExceptionHandler; + +/** + * ExceptionHandler converts an exception to a Response object. + * + * @author Fabien Potencier + * + * @deprecated since version 2.3, to be removed in 3.0. Use the same class from the Debug component instead. + */ +class ExceptionHandler extends DebugExceptionHandler +{ +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Debug/TraceableEventDispatcher.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Debug/TraceableEventDispatcher.php new file mode 100644 index 0000000..eb1d8a8 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Debug/TraceableEventDispatcher.php @@ -0,0 +1,99 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Debug; + +use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher as BaseTraceableEventDispatcher; +use Symfony\Component\HttpKernel\Profiler\Profiler; +use Symfony\Component\HttpKernel\KernelEvents; +use Symfony\Component\EventDispatcher\Event; + +/** + * Collects some data about event listeners. + * + * This event dispatcher delegates the dispatching to another one. + * + * @author Fabien Potencier + */ +class TraceableEventDispatcher extends BaseTraceableEventDispatcher +{ + /** + * Sets the profiler. + * + * The traceable event dispatcher does not use the profiler anymore. + * The job is now done directly by the Profiler listener and the + * data collectors themselves. + * + * @param Profiler|null $profiler A Profiler instance + * + * @deprecated since version 2.4, to be removed in 3.0. + */ + public function setProfiler(Profiler $profiler = null) + { + @trigger_error('The '.__METHOD__.' method is deprecated since version 2.4 and will be removed in 3.0.', E_USER_DEPRECATED); + } + + /** + * {@inheritdoc} + */ + protected function preDispatch($eventName, Event $event) + { + switch ($eventName) { + case KernelEvents::REQUEST: + $this->stopwatch->openSection(); + break; + case KernelEvents::VIEW: + case KernelEvents::RESPONSE: + // stop only if a controller has been executed + if ($this->stopwatch->isStarted('controller')) { + $this->stopwatch->stop('controller'); + } + break; + case KernelEvents::TERMINATE: + $token = $event->getResponse()->headers->get('X-Debug-Token'); + // There is a very special case when using built-in AppCache class as kernel wrapper, in the case + // of an ESI request leading to a `stale` response [B] inside a `fresh` cached response [A]. + // In this case, `$token` contains the [B] debug token, but the open `stopwatch` section ID + // is equal to the [A] debug token. Trying to reopen section with the [B] token throws an exception + // which must be caught. + try { + $this->stopwatch->openSection($token); + } catch (\LogicException $e) { + } + break; + } + } + + /** + * {@inheritdoc} + */ + protected function postDispatch($eventName, Event $event) + { + switch ($eventName) { + case KernelEvents::CONTROLLER: + $this->stopwatch->start('controller', 'section'); + break; + case KernelEvents::RESPONSE: + $token = $event->getResponse()->headers->get('X-Debug-Token'); + $this->stopwatch->stopSection($token); + break; + case KernelEvents::TERMINATE: + // In the special case described in the `preDispatch` method above, the `$token` section + // does not exist, then closing it throws an exception which must be caught. + $token = $event->getResponse()->headers->get('X-Debug-Token'); + try { + $this->stopwatch->stopSection($token); + } catch (\LogicException $e) { + } + break; + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DependencyInjection/AddClassesToCachePass.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DependencyInjection/AddClassesToCachePass.php new file mode 100644 index 0000000..09af6bd --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DependencyInjection/AddClassesToCachePass.php @@ -0,0 +1,46 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\DependencyInjection; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\HttpKernel\Kernel; + +/** + * Sets the classes to compile in the cache for the container. + * + * @author Fabien Potencier + */ +class AddClassesToCachePass implements CompilerPassInterface +{ + private $kernel; + + public function __construct(Kernel $kernel) + { + $this->kernel = $kernel; + } + + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + $classes = array(); + foreach ($container->getExtensions() as $extension) { + if ($extension instanceof Extension) { + $classes = array_merge($classes, $extension->getClassesToCompile()); + } + } + + $this->kernel->setClassCache(array_unique($container->getParameterBag()->resolveValue($classes))); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DependencyInjection/ConfigurableExtension.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DependencyInjection/ConfigurableExtension.php new file mode 100644 index 0000000..c7eca30 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DependencyInjection/ConfigurableExtension.php @@ -0,0 +1,45 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\DependencyInjection; + +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * This extension sub-class provides first-class integration with the + * Config/Definition Component. + * + * You can use this as base class if + * + * a) you use the Config/Definition component for configuration, + * b) your configuration class is named "Configuration", and + * c) the configuration class resides in the DependencyInjection sub-folder. + * + * @author Johannes M. Schmitt + */ +abstract class ConfigurableExtension extends Extension +{ + /** + * {@inheritdoc} + */ + final public function load(array $configs, ContainerBuilder $container) + { + $this->loadInternal($this->processConfiguration($this->getConfiguration($configs, $container), $configs), $container); + } + + /** + * Configures the passed container according to the merged configuration. + * + * @param array $mergedConfig + * @param ContainerBuilder $container + */ + abstract protected function loadInternal(array $mergedConfig, ContainerBuilder $container); +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DependencyInjection/ContainerAwareHttpKernel.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DependencyInjection/ContainerAwareHttpKernel.php new file mode 100644 index 0000000..4b3e218 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DependencyInjection/ContainerAwareHttpKernel.php @@ -0,0 +1,87 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\DependencyInjection; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\RequestStack; +use Symfony\Component\HttpKernel\HttpKernelInterface; +use Symfony\Component\HttpKernel\HttpKernel; +use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Scope; + +/** + * Adds a managed request scope. + * + * @author Fabien Potencier + * @author Johannes M. Schmitt + * + * @deprecated since version 2.7, to be removed in 3.0. + */ +class ContainerAwareHttpKernel extends HttpKernel +{ + protected $container; + + /** + * Constructor. + * + * @param EventDispatcherInterface $dispatcher An EventDispatcherInterface instance + * @param ContainerInterface $container A ContainerInterface instance + * @param ControllerResolverInterface $controllerResolver A ControllerResolverInterface instance + * @param RequestStack $requestStack A stack for master/sub requests + * @param bool $triggerDeprecation Whether or not to trigger the deprecation warning for the ContainerAwareHttpKernel + */ + public function __construct(EventDispatcherInterface $dispatcher, ContainerInterface $container, ControllerResolverInterface $controllerResolver, RequestStack $requestStack = null, $triggerDeprecation = true) + { + parent::__construct($dispatcher, $controllerResolver, $requestStack); + + if ($triggerDeprecation) { + @trigger_error('The '.__CLASS__.' class is deprecated since version 2.7 and will be removed in 3.0. Use the Symfony\Component\HttpKernel\HttpKernel class instead.', E_USER_DEPRECATED); + } + + $this->container = $container; + + // the request scope might have been created before (see FrameworkBundle) + if (!$container->hasScope('request')) { + $container->addScope(new Scope('request')); + } + } + + /** + * {@inheritdoc} + */ + public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true) + { + $this->container->enterScope('request'); + $this->container->set('request', $request, 'request'); + + try { + $response = parent::handle($request, $type, $catch); + } catch (\Exception $e) { + $this->container->set('request', null, 'request'); + $this->container->leaveScope('request'); + + throw $e; + } catch (\Throwable $e) { + $this->container->set('request', null, 'request'); + $this->container->leaveScope('request'); + + throw $e; + } + + $this->container->set('request', null, 'request'); + $this->container->leaveScope('request'); + + return $response; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DependencyInjection/Extension.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DependencyInjection/Extension.php new file mode 100644 index 0000000..2ca0f13 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DependencyInjection/Extension.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\DependencyInjection; + +use Symfony\Component\DependencyInjection\Extension\Extension as BaseExtension; + +/** + * Allow adding classes to the class cache. + * + * @author Fabien Potencier + */ +abstract class Extension extends BaseExtension +{ + private $classes = array(); + + /** + * Gets the classes to cache. + * + * @return array An array of classes + */ + public function getClassesToCompile() + { + return $this->classes; + } + + /** + * Adds classes to the class cache. + * + * @param array $classes An array of classes + */ + public function addClassesToCompile(array $classes) + { + $this->classes = array_merge($this->classes, $classes); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DependencyInjection/FragmentRendererPass.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DependencyInjection/FragmentRendererPass.php new file mode 100644 index 0000000..0c4cece --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DependencyInjection/FragmentRendererPass.php @@ -0,0 +1,78 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\DependencyInjection; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; + +/** + * Adds services tagged kernel.fragment_renderer as HTTP content rendering strategies. + * + * @author Fabien Potencier + */ +class FragmentRendererPass implements CompilerPassInterface +{ + private $handlerService; + private $rendererTag; + + /** + * @param string $handlerService Service name of the fragment handler in the container + * @param string $rendererTag Tag name used for fragments + */ + public function __construct($handlerService = 'fragment.handler', $rendererTag = 'kernel.fragment_renderer') + { + $this->handlerService = $handlerService; + $this->rendererTag = $rendererTag; + } + + public function process(ContainerBuilder $container) + { + if (!$container->hasDefinition($this->handlerService)) { + return; + } + + $definition = $container->getDefinition($this->handlerService); + foreach ($container->findTaggedServiceIds($this->rendererTag) as $id => $tags) { + $def = $container->getDefinition($id); + if (!$def->isPublic()) { + throw new \InvalidArgumentException(sprintf('The service "%s" must be public as fragment renderer are lazy-loaded.', $id)); + } + + if ($def->isAbstract()) { + throw new \InvalidArgumentException(sprintf('The service "%s" must not be abstract as fragment renderer are lazy-loaded.', $id)); + } + + $class = $container->getParameterBag()->resolveValue($def->getClass()); + $interface = 'Symfony\Component\HttpKernel\Fragment\FragmentRendererInterface'; + + if (!is_subclass_of($class, $interface)) { + if (!class_exists($class, false)) { + throw new \InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id)); + } + + throw new \InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $id, $interface)); + } + + foreach ($tags as $tag) { + if (!isset($tag['alias'])) { + @trigger_error(sprintf('Service "%s" will have to define the "alias" attribute on the "%s" tag as of Symfony 3.0.', $id, $this->rendererTag), E_USER_DEPRECATED); + + // register the handler as a non-lazy-loaded one + $definition->addMethodCall('addRenderer', array(new Reference($id))); + } else { + $definition->addMethodCall('addRendererService', array($tag['alias'], $id)); + } + } + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DependencyInjection/LazyLoadingFragmentHandler.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DependencyInjection/LazyLoadingFragmentHandler.php new file mode 100644 index 0000000..c611e9e --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DependencyInjection/LazyLoadingFragmentHandler.php @@ -0,0 +1,59 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\DependencyInjection; + +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\HttpFoundation\RequestStack; +use Symfony\Component\HttpKernel\Fragment\FragmentHandler; + +/** + * Lazily loads fragment renderers from the dependency injection container. + * + * @author Fabien Potencier + */ +class LazyLoadingFragmentHandler extends FragmentHandler +{ + private $container; + private $rendererIds = array(); + + public function __construct(ContainerInterface $container, $debug = false, RequestStack $requestStack = null) + { + $this->container = $container; + + parent::__construct(array(), $debug, $requestStack); + } + + /** + * Adds a service as a fragment renderer. + * + * @param string $name The service name + * @param string $renderer The render service id + */ + public function addRendererService($name, $renderer) + { + $this->rendererIds[$name] = $renderer; + } + + /** + * {@inheritdoc} + */ + public function render($uri, $renderer = 'inline', array $options = array()) + { + if (isset($this->rendererIds[$renderer])) { + $this->addRenderer($this->container->get($this->rendererIds[$renderer])); + + unset($this->rendererIds[$renderer]); + } + + return parent::render($uri, $renderer, $options); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DependencyInjection/MergeExtensionConfigurationPass.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DependencyInjection/MergeExtensionConfigurationPass.php new file mode 100644 index 0000000..dcd7382 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DependencyInjection/MergeExtensionConfigurationPass.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\DependencyInjection; + +use Symfony\Component\DependencyInjection\Compiler\MergeExtensionConfigurationPass as BaseMergeExtensionConfigurationPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * Ensures certain extensions are always loaded. + * + * @author Kris Wallsmith + */ +class MergeExtensionConfigurationPass extends BaseMergeExtensionConfigurationPass +{ + private $extensions; + + public function __construct(array $extensions) + { + $this->extensions = $extensions; + } + + public function process(ContainerBuilder $container) + { + foreach ($this->extensions as $extension) { + if (!count($container->getExtensionConfig($extension))) { + $container->loadFromExtension($extension, array()); + } + } + + parent::process($container); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DependencyInjection/RegisterListenersPass.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DependencyInjection/RegisterListenersPass.php new file mode 100644 index 0000000..f1c2247 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/DependencyInjection/RegisterListenersPass.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\DependencyInjection; + +@trigger_error('The '.__NAMESPACE__.'\RegisterListenersPass is deprecated since version 2.5 and will be removed in 3.0. Use the Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass class instead.', E_USER_DEPRECATED); + +use Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass as BaseRegisterListenersPass; + +/** + * Compiler pass to register tagged services for an event dispatcher. + * + * @deprecated since version 2.5, to be removed in 3.0. Use the Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass class instead. + */ +class RegisterListenersPass extends BaseRegisterListenersPass +{ +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Event/FilterControllerEvent.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Event/FilterControllerEvent.php new file mode 100644 index 0000000..77a5c1a --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Event/FilterControllerEvent.php @@ -0,0 +1,102 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Event; + +use Symfony\Component\HttpKernel\HttpKernelInterface; +use Symfony\Component\HttpFoundation\Request; + +/** + * Allows filtering of a controller callable. + * + * You can call getController() to retrieve the current controller. With + * setController() you can set a new controller that is used in the processing + * of the request. + * + * Controllers should be callables. + * + * @author Bernhard Schussek + */ +class FilterControllerEvent extends KernelEvent +{ + /** + * The current controller. + */ + private $controller; + + public function __construct(HttpKernelInterface $kernel, $controller, Request $request, $requestType) + { + parent::__construct($kernel, $request, $requestType); + + $this->setController($controller); + } + + /** + * Returns the current controller. + * + * @return callable + */ + public function getController() + { + return $this->controller; + } + + /** + * Sets a new controller. + * + * @param callable $controller + * + * @throws \LogicException + */ + public function setController($controller) + { + // controller must be a callable + if (!is_callable($controller)) { + throw new \LogicException(sprintf('The controller must be a callable (%s given).', $this->varToString($controller))); + } + + $this->controller = $controller; + } + + private function varToString($var) + { + if (is_object($var)) { + return sprintf('Object(%s)', get_class($var)); + } + + if (is_array($var)) { + $a = array(); + foreach ($var as $k => $v) { + $a[] = sprintf('%s => %s', $k, $this->varToString($v)); + } + + return sprintf('Array(%s)', implode(', ', $a)); + } + + if (is_resource($var)) { + return sprintf('Resource(%s)', get_resource_type($var)); + } + + if (null === $var) { + return 'null'; + } + + if (false === $var) { + return 'false'; + } + + if (true === $var) { + return 'true'; + } + + return (string) $var; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Event/FilterResponseEvent.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Event/FilterResponseEvent.php new file mode 100644 index 0000000..ed816a9 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Event/FilterResponseEvent.php @@ -0,0 +1,62 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Event; + +use Symfony\Component\HttpKernel\HttpKernelInterface; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; + +/** + * Allows to filter a Response object. + * + * You can call getResponse() to retrieve the current response. With + * setResponse() you can set a new response that will be returned to the + * browser. + * + * @author Bernhard Schussek + */ +class FilterResponseEvent extends KernelEvent +{ + /** + * The current response object. + * + * @var Response + */ + private $response; + + public function __construct(HttpKernelInterface $kernel, Request $request, $requestType, Response $response) + { + parent::__construct($kernel, $request, $requestType); + + $this->setResponse($response); + } + + /** + * Returns the current response object. + * + * @return Response + */ + public function getResponse() + { + return $this->response; + } + + /** + * Sets a new response object. + * + * @param Response $response + */ + public function setResponse(Response $response) + { + $this->response = $response; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Event/FinishRequestEvent.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Event/FinishRequestEvent.php new file mode 100644 index 0000000..ee72484 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Event/FinishRequestEvent.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Event; + +/** + * Triggered whenever a request is fully processed. + * + * @author Benjamin Eberlei + */ +class FinishRequestEvent extends KernelEvent +{ +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Event/GetResponseEvent.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Event/GetResponseEvent.php new file mode 100644 index 0000000..4c96a4b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Event/GetResponseEvent.php @@ -0,0 +1,65 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Event; + +use Symfony\Component\HttpFoundation\Response; + +/** + * Allows to create a response for a request. + * + * Call setResponse() to set the response that will be returned for the + * current request. The propagation of this event is stopped as soon as a + * response is set. + * + * @author Bernhard Schussek + */ +class GetResponseEvent extends KernelEvent +{ + /** + * The response object. + * + * @var Response + */ + private $response; + + /** + * Returns the response object. + * + * @return Response + */ + public function getResponse() + { + return $this->response; + } + + /** + * Sets a response and stops event propagation. + * + * @param Response $response + */ + public function setResponse(Response $response) + { + $this->response = $response; + + $this->stopPropagation(); + } + + /** + * Returns whether a response was set. + * + * @return bool Whether a response was set + */ + public function hasResponse() + { + return null !== $this->response; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Event/GetResponseForControllerResultEvent.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Event/GetResponseForControllerResultEvent.php new file mode 100644 index 0000000..f70ce09 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Event/GetResponseForControllerResultEvent.php @@ -0,0 +1,61 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Event; + +use Symfony\Component\HttpKernel\HttpKernelInterface; +use Symfony\Component\HttpFoundation\Request; + +/** + * Allows to create a response for the return value of a controller. + * + * Call setResponse() to set the response that will be returned for the + * current request. The propagation of this event is stopped as soon as a + * response is set. + * + * @author Bernhard Schussek + */ +class GetResponseForControllerResultEvent extends GetResponseEvent +{ + /** + * The return value of the controller. + * + * @var mixed + */ + private $controllerResult; + + public function __construct(HttpKernelInterface $kernel, Request $request, $requestType, $controllerResult) + { + parent::__construct($kernel, $request, $requestType); + + $this->controllerResult = $controllerResult; + } + + /** + * Returns the return value of the controller. + * + * @return mixed The controller return value + */ + public function getControllerResult() + { + return $this->controllerResult; + } + + /** + * Assigns the return value of the controller. + * + * @param mixed $controllerResult The controller return value + */ + public function setControllerResult($controllerResult) + { + $this->controllerResult = $controllerResult; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Event/GetResponseForExceptionEvent.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Event/GetResponseForExceptionEvent.php new file mode 100644 index 0000000..003953f --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Event/GetResponseForExceptionEvent.php @@ -0,0 +1,67 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Event; + +use Symfony\Component\HttpKernel\HttpKernelInterface; +use Symfony\Component\HttpFoundation\Request; + +/** + * Allows to create a response for a thrown exception. + * + * Call setResponse() to set the response that will be returned for the + * current request. The propagation of this event is stopped as soon as a + * response is set. + * + * You can also call setException() to replace the thrown exception. This + * exception will be thrown if no response is set during processing of this + * event. + * + * @author Bernhard Schussek + */ +class GetResponseForExceptionEvent extends GetResponseEvent +{ + /** + * The exception object. + * + * @var \Exception + */ + private $exception; + + public function __construct(HttpKernelInterface $kernel, Request $request, $requestType, \Exception $e) + { + parent::__construct($kernel, $request, $requestType); + + $this->setException($e); + } + + /** + * Returns the thrown exception. + * + * @return \Exception The thrown exception + */ + public function getException() + { + return $this->exception; + } + + /** + * Replaces the thrown exception. + * + * This exception will be thrown if no response is set in the event. + * + * @param \Exception $exception The thrown exception + */ + public function setException(\Exception $exception) + { + $this->exception = $exception; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Event/KernelEvent.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Event/KernelEvent.php new file mode 100644 index 0000000..2043a01 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Event/KernelEvent.php @@ -0,0 +1,94 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Event; + +use Symfony\Component\HttpKernel\HttpKernelInterface; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\EventDispatcher\Event; + +/** + * Base class for events thrown in the HttpKernel component. + * + * @author Bernhard Schussek + */ +class KernelEvent extends Event +{ + /** + * The kernel in which this event was thrown. + * + * @var HttpKernelInterface + */ + private $kernel; + + /** + * The request the kernel is currently processing. + * + * @var Request + */ + private $request; + + /** + * The request type the kernel is currently processing. One of + * HttpKernelInterface::MASTER_REQUEST and HttpKernelInterface::SUB_REQUEST. + * + * @var int + */ + private $requestType; + + public function __construct(HttpKernelInterface $kernel, Request $request, $requestType) + { + $this->kernel = $kernel; + $this->request = $request; + $this->requestType = $requestType; + } + + /** + * Returns the kernel in which this event was thrown. + * + * @return HttpKernelInterface + */ + public function getKernel() + { + return $this->kernel; + } + + /** + * Returns the request the kernel is currently processing. + * + * @return Request + */ + public function getRequest() + { + return $this->request; + } + + /** + * Returns the request type the kernel is currently processing. + * + * @return int One of HttpKernelInterface::MASTER_REQUEST and + * HttpKernelInterface::SUB_REQUEST + */ + public function getRequestType() + { + return $this->requestType; + } + + /** + * Checks if this is a master request. + * + * @return bool True if the request is a master request + */ + public function isMasterRequest() + { + return HttpKernelInterface::MASTER_REQUEST === $this->requestType; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Event/PostResponseEvent.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Event/PostResponseEvent.php new file mode 100644 index 0000000..5d4450b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Event/PostResponseEvent.php @@ -0,0 +1,73 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Event; + +use Symfony\Component\HttpKernel\HttpKernelInterface; +use Symfony\Component\EventDispatcher\Event; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; + +/** + * Allows to execute logic after a response was sent. + * + * @author Jordi Boggiano + */ +class PostResponseEvent extends Event +{ + /** + * The kernel in which this event was thrown. + * + * @var HttpKernelInterface + */ + private $kernel; + + private $request; + + private $response; + + public function __construct(HttpKernelInterface $kernel, Request $request, Response $response) + { + $this->kernel = $kernel; + $this->request = $request; + $this->response = $response; + } + + /** + * Returns the kernel in which this event was thrown. + * + * @return HttpKernelInterface + */ + public function getKernel() + { + return $this->kernel; + } + + /** + * Returns the request for which this event was thrown. + * + * @return Request + */ + public function getRequest() + { + return $this->request; + } + + /** + * Returns the response for which this event was thrown. + * + * @return Response + */ + public function getResponse() + { + return $this->response; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/AddRequestFormatsListener.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/AddRequestFormatsListener.php new file mode 100644 index 0000000..14a5d43 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/AddRequestFormatsListener.php @@ -0,0 +1,57 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\EventListener; + +use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\HttpKernel\KernelEvents; +use Symfony\Component\HttpKernel\Event\GetResponseEvent; + +/** + * Adds configured formats to each request. + * + * @author Gildas Quemener + */ +class AddRequestFormatsListener implements EventSubscriberInterface +{ + /** + * @var array + */ + protected $formats; + + /** + * @param array $formats + */ + public function __construct(array $formats) + { + $this->formats = $formats; + } + + /** + * Adds request formats. + * + * @param GetResponseEvent $event + */ + public function onKernelRequest(GetResponseEvent $event) + { + foreach ($this->formats as $format => $mimeTypes) { + $event->getRequest()->setFormat($format, $mimeTypes); + } + } + + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents() + { + return array(KernelEvents::REQUEST => 'onKernelRequest'); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/DebugHandlersListener.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/DebugHandlersListener.php new file mode 100644 index 0000000..2f523a5 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/DebugHandlersListener.php @@ -0,0 +1,138 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\EventListener; + +use Psr\Log\LoggerInterface; +use Symfony\Component\Debug\ErrorHandler; +use Symfony\Component\Debug\ExceptionHandler; +use Symfony\Component\EventDispatcher\Event; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\HttpKernel\Event\KernelEvent; +use Symfony\Component\HttpKernel\KernelEvents; +use Symfony\Component\Console\ConsoleEvents; +use Symfony\Component\Console\Event\ConsoleEvent; +use Symfony\Component\Console\Output\ConsoleOutputInterface; + +/** + * Configures errors and exceptions handlers. + * + * @author Nicolas Grekas + */ +class DebugHandlersListener implements EventSubscriberInterface +{ + private $exceptionHandler; + private $logger; + private $levels; + private $throwAt; + private $scream; + private $fileLinkFormat; + private $firstCall = true; + + /** + * @param callable|null $exceptionHandler A handler that will be called on Exception + * @param LoggerInterface|null $logger A PSR-3 logger + * @param array|int $levels An array map of E_* to LogLevel::* or an integer bit field of E_* constants + * @param int|null $throwAt Thrown errors in a bit field of E_* constants, or null to keep the current value + * @param bool $scream Enables/disables screaming mode, where even silenced errors are logged + * @param string $fileLinkFormat The format for links to source files + */ + public function __construct($exceptionHandler, LoggerInterface $logger = null, $levels = null, $throwAt = -1, $scream = true, $fileLinkFormat = null) + { + $this->exceptionHandler = $exceptionHandler; + $this->logger = $logger; + $this->levels = $levels; + $this->throwAt = is_numeric($throwAt) ? (int) $throwAt : (null === $throwAt ? null : ($throwAt ? -1 : null)); + $this->scream = (bool) $scream; + $this->fileLinkFormat = $fileLinkFormat ?: ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format'); + } + + /** + * Configures the error handler. + * + * @param Event|null $event The triggering event + */ + public function configure(Event $event = null) + { + if (!$this->firstCall) { + return; + } + $this->firstCall = false; + if ($this->logger || null !== $this->throwAt) { + $handler = set_error_handler('var_dump'); + $handler = is_array($handler) ? $handler[0] : null; + restore_error_handler(); + if ($handler instanceof ErrorHandler) { + if ($this->logger) { + $handler->setDefaultLogger($this->logger, $this->levels); + if (is_array($this->levels)) { + $scream = 0; + foreach ($this->levels as $type => $log) { + $scream |= $type; + } + } else { + $scream = null === $this->levels ? E_ALL | E_STRICT : $this->levels; + } + if ($this->scream) { + $handler->screamAt($scream); + } + $this->logger = $this->levels = null; + } + if (null !== $this->throwAt) { + $handler->throwAt($this->throwAt, true); + } + } + } + if (!$this->exceptionHandler) { + if ($event instanceof KernelEvent) { + if (method_exists($event->getKernel(), 'terminateWithException')) { + $this->exceptionHandler = array($event->getKernel(), 'terminateWithException'); + } + } elseif ($event instanceof ConsoleEvent && $app = $event->getCommand()->getApplication()) { + $output = $event->getOutput(); + if ($output instanceof ConsoleOutputInterface) { + $output = $output->getErrorOutput(); + } + $this->exceptionHandler = function ($e) use ($app, $output) { + $app->renderException($e, $output); + }; + } + } + if ($this->exceptionHandler) { + $handler = set_exception_handler('var_dump'); + $handler = is_array($handler) ? $handler[0] : null; + restore_exception_handler(); + if ($handler instanceof ErrorHandler) { + $h = $handler->setExceptionHandler('var_dump') ?: $this->exceptionHandler; + $handler->setExceptionHandler($h); + $handler = is_array($h) ? $h[0] : null; + } + if ($handler instanceof ExceptionHandler) { + $handler->setHandler($this->exceptionHandler); + if (null !== $this->fileLinkFormat) { + $handler->setFileLinkFormat($this->fileLinkFormat); + } + } + $this->exceptionHandler = null; + } + } + + public static function getSubscribedEvents() + { + $events = array(KernelEvents::REQUEST => array('configure', 2048)); + + if (defined('Symfony\Component\Console\ConsoleEvents::COMMAND')) { + $events[ConsoleEvents::COMMAND] = array('configure', 2048); + } + + return $events; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/DumpListener.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/DumpListener.php new file mode 100644 index 0000000..06b8a03 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/DumpListener.php @@ -0,0 +1,55 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\EventListener; + +use Symfony\Component\Console\ConsoleEvents; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\VarDumper\Cloner\ClonerInterface; +use Symfony\Component\VarDumper\Dumper\DataDumperInterface; +use Symfony\Component\VarDumper\VarDumper; + +/** + * Configures dump() handler. + * + * @author Nicolas Grekas + */ +class DumpListener implements EventSubscriberInterface +{ + private $cloner; + private $dumper; + + /** + * @param ClonerInterface $cloner Cloner service + * @param DataDumperInterface $dumper Dumper service + */ + public function __construct(ClonerInterface $cloner, DataDumperInterface $dumper) + { + $this->cloner = $cloner; + $this->dumper = $dumper; + } + + public function configure() + { + $cloner = $this->cloner; + $dumper = $this->dumper; + + VarDumper::setHandler(function ($var) use ($cloner, $dumper) { + $dumper->dump($cloner->cloneVar($var)); + }); + } + + public static function getSubscribedEvents() + { + // Register early to have a working dump() as early as possible + return array(ConsoleEvents::COMMAND => array('configure', 1024)); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/ErrorsLoggerListener.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/ErrorsLoggerListener.php new file mode 100644 index 0000000..80c3fe5 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/ErrorsLoggerListener.php @@ -0,0 +1,52 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\EventListener; + +@trigger_error('The '.__NAMESPACE__.'\ErrorsLoggerListener class is deprecated since version 2.6 and will be removed in 3.0. Use the Symfony\Component\HttpKernel\EventListener\DebugHandlersListener class instead.', E_USER_DEPRECATED); + +use Psr\Log\LoggerInterface; +use Symfony\Component\Debug\ErrorHandler; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\HttpKernel\KernelEvents; + +/** + * Injects the logger into the ErrorHandler, so that it can log various errors. + * + * @author Colin Frei + * @author Konstantin Myakshin + * + * @deprecated since version 2.6, to be removed in 3.0. Use the DebugHandlersListener class instead. + */ +class ErrorsLoggerListener implements EventSubscriberInterface +{ + private $channel; + private $logger; + + public function __construct($channel, LoggerInterface $logger = null) + { + $this->channel = $channel; + $this->logger = $logger; + } + + public function injectLogger() + { + if (null !== $this->logger) { + ErrorHandler::setLogger($this->logger, $this->channel); + $this->logger = null; + } + } + + public static function getSubscribedEvents() + { + return array(KernelEvents::REQUEST => array('injectLogger', 2048)); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/EsiListener.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/EsiListener.php new file mode 100644 index 0000000..bceb672 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/EsiListener.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\EventListener; + +@trigger_error('The '.__NAMESPACE__.'\EsiListener class is deprecated since version 2.6 and will be removed in 3.0. Use the Symfony\Component\HttpKernel\EventListener\SurrogateListener class instead.', E_USER_DEPRECATED); + +/** + * EsiListener adds a Surrogate-Control HTTP header when the Response needs to be parsed for ESI. + * + * @author Fabien Potencier + * + * @deprecated since version 2.6, to be removed in 3.0. Use SurrogateListener instead + */ +class EsiListener extends SurrogateListener +{ +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/ExceptionListener.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/ExceptionListener.php new file mode 100644 index 0000000..1c50ef4 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/ExceptionListener.php @@ -0,0 +1,120 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\EventListener; + +use Psr\Log\LoggerInterface; +use Symfony\Component\Debug\Exception\FlattenException; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpKernel\Log\DebugLoggerInterface; +use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; +use Symfony\Component\HttpKernel\KernelEvents; +use Symfony\Component\HttpKernel\HttpKernelInterface; +use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +/** + * ExceptionListener. + * + * @author Fabien Potencier + */ +class ExceptionListener implements EventSubscriberInterface +{ + protected $controller; + protected $logger; + + public function __construct($controller, LoggerInterface $logger = null) + { + $this->controller = $controller; + $this->logger = $logger; + } + + public function onKernelException(GetResponseForExceptionEvent $event) + { + $exception = $event->getException(); + $request = $event->getRequest(); + + $this->logException($exception, sprintf('Uncaught PHP Exception %s: "%s" at %s line %s', get_class($exception), $exception->getMessage(), $exception->getFile(), $exception->getLine())); + + $request = $this->duplicateRequest($exception, $request); + + try { + $response = $event->getKernel()->handle($request, HttpKernelInterface::SUB_REQUEST, false); + } catch (\Exception $e) { + $this->logException($e, sprintf('Exception thrown when handling an exception (%s: %s at %s line %s)', get_class($e), $e->getMessage(), $e->getFile(), $e->getLine())); + + $wrapper = $e; + + while ($prev = $wrapper->getPrevious()) { + if ($exception === $wrapper = $prev) { + throw $e; + } + } + + $prev = new \ReflectionProperty('Exception', 'previous'); + $prev->setAccessible(true); + $prev->setValue($wrapper, $exception); + + throw $e; + } + + $event->setResponse($response); + } + + public static function getSubscribedEvents() + { + return array( + KernelEvents::EXCEPTION => array('onKernelException', -128), + ); + } + + /** + * Logs an exception. + * + * @param \Exception $exception The \Exception instance + * @param string $message The error message to log + */ + protected function logException(\Exception $exception, $message) + { + if (null !== $this->logger) { + if (!$exception instanceof HttpExceptionInterface || $exception->getStatusCode() >= 500) { + $this->logger->critical($message, array('exception' => $exception)); + } else { + $this->logger->error($message, array('exception' => $exception)); + } + } + } + + /** + * Clones the request for the exception. + * + * @param \Exception $exception The thrown exception + * @param Request $request The original request + * + * @return Request $request The cloned request + */ + protected function duplicateRequest(\Exception $exception, Request $request) + { + $attributes = array( + '_controller' => $this->controller, + 'exception' => FlattenException::create($exception), + 'logger' => $this->logger instanceof DebugLoggerInterface ? $this->logger : null, + // keep for BC -- as $format can be an argument of the controller callable + // see src/Symfony/Bundle/TwigBundle/Controller/ExceptionController.php + // @deprecated since version 2.4, to be removed in 3.0 + 'format' => $request->getRequestFormat(), + ); + $request = $request->duplicate(null, null, $attributes); + $request->setMethod('GET'); + + return $request; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/FragmentListener.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/FragmentListener.php new file mode 100644 index 0000000..2ab6c85 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/FragmentListener.php @@ -0,0 +1,115 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\EventListener; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpKernel\Event\GetResponseEvent; +use Symfony\Component\HttpKernel\KernelEvents; +use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; +use Symfony\Component\HttpKernel\UriSigner; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +/** + * Handles content fragments represented by special URIs. + * + * All URL paths starting with /_fragment are handled as + * content fragments by this listener. + * + * If throws an AccessDeniedHttpException exception if the request + * is not signed or if it is not an internal sub-request. + * + * @author Fabien Potencier + */ +class FragmentListener implements EventSubscriberInterface +{ + private $signer; + private $fragmentPath; + + /** + * Constructor. + * + * @param UriSigner $signer A UriSigner instance + * @param string $fragmentPath The path that triggers this listener + */ + public function __construct(UriSigner $signer, $fragmentPath = '/_fragment') + { + $this->signer = $signer; + $this->fragmentPath = $fragmentPath; + } + + /** + * Fixes request attributes when the path is '/_fragment'. + * + * @param GetResponseEvent $event A GetResponseEvent instance + * + * @throws AccessDeniedHttpException if the request does not come from a trusted IP. + */ + public function onKernelRequest(GetResponseEvent $event) + { + $request = $event->getRequest(); + + if ($this->fragmentPath !== rawurldecode($request->getPathInfo())) { + return; + } + + if ($request->attributes->has('_controller')) { + // Is a sub-request: no need to parse _path but it should still be removed from query parameters as below. + $request->query->remove('_path'); + + return; + } + + if ($event->isMasterRequest()) { + $this->validateRequest($request); + } + + parse_str($request->query->get('_path', ''), $attributes); + $request->attributes->add($attributes); + $request->attributes->set('_route_params', array_replace($request->attributes->get('_route_params', array()), $attributes)); + $request->query->remove('_path'); + } + + protected function validateRequest(Request $request) + { + // is the Request safe? + if (!$request->isMethodSafe()) { + throw new AccessDeniedHttpException(); + } + + // is the Request signed? + // we cannot use $request->getUri() here as we want to work with the original URI (no query string reordering) + if ($this->signer->check($request->getSchemeAndHttpHost().$request->getBaseUrl().$request->getPathInfo().(null !== ($qs = $request->server->get('QUERY_STRING')) ? '?'.$qs : ''))) { + return; + } + + throw new AccessDeniedHttpException(); + } + + /** + * @deprecated since version 2.3.19, to be removed in 3.0. + * + * @return string[] + */ + protected function getLocalIpAddresses() + { + @trigger_error('The '.__METHOD__.' method is deprecated since version 2.3.19 and will be removed in 3.0.', E_USER_DEPRECATED); + + return array('127.0.0.1', 'fe80::1', '::1'); + } + + public static function getSubscribedEvents() + { + return array( + KernelEvents::REQUEST => array(array('onKernelRequest', 48)), + ); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/LocaleListener.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/LocaleListener.php new file mode 100644 index 0000000..564f6dc --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/LocaleListener.php @@ -0,0 +1,113 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\EventListener; + +use Symfony\Component\HttpKernel\Event\GetResponseEvent; +use Symfony\Component\HttpKernel\Event\FinishRequestEvent; +use Symfony\Component\HttpKernel\KernelEvents; +use Symfony\Component\HttpFoundation\RequestStack; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\Routing\RequestContextAwareInterface; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +/** + * Initializes the locale based on the current request. + * + * This listener works in 2 modes: + * + * * 2.3 compatibility mode where you must call setRequest whenever the Request changes. + * * 2.4+ mode where you must pass a RequestStack instance in the constructor. + * + * @author Fabien Potencier + */ +class LocaleListener implements EventSubscriberInterface +{ + private $router; + private $defaultLocale; + private $requestStack; + + /** + * RequestStack will become required in 3.0. + */ + public function __construct($defaultLocale = 'en', RequestContextAwareInterface $router = null, RequestStack $requestStack = null) + { + $this->defaultLocale = $defaultLocale; + $this->requestStack = $requestStack; + $this->router = $router; + } + + /** + * Sets the current Request. + * + * This method was used to synchronize the Request, but as the HttpKernel + * is doing that automatically now, you should never call it directly. + * It is kept public for BC with the 2.3 version. + * + * @param Request|null $request A Request instance + * + * @deprecated since version 2.4, to be removed in 3.0. + */ + public function setRequest(Request $request = null) + { + @trigger_error('The '.__METHOD__.' method is deprecated since version 2.4 and will be removed in 3.0.', E_USER_DEPRECATED); + + if (null === $request) { + return; + } + + $this->setLocale($request); + $this->setRouterContext($request); + } + + public function onKernelRequest(GetResponseEvent $event) + { + $request = $event->getRequest(); + $request->setDefaultLocale($this->defaultLocale); + + $this->setLocale($request); + $this->setRouterContext($request); + } + + public function onKernelFinishRequest(FinishRequestEvent $event) + { + if (null === $this->requestStack) { + return; // removed when requestStack is required + } + + if (null !== $parentRequest = $this->requestStack->getParentRequest()) { + $this->setRouterContext($parentRequest); + } + } + + private function setLocale(Request $request) + { + if ($locale = $request->attributes->get('_locale')) { + $request->setLocale($locale); + } + } + + private function setRouterContext(Request $request) + { + if (null !== $this->router) { + $this->router->getContext()->setParameter('_locale', $request->getLocale()); + } + } + + public static function getSubscribedEvents() + { + return array( + // must be registered after the Router to have access to the _locale + KernelEvents::REQUEST => array(array('onKernelRequest', 16)), + KernelEvents::FINISH_REQUEST => array(array('onKernelFinishRequest', 0)), + ); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/ProfilerListener.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/ProfilerListener.php new file mode 100644 index 0000000..06a5bbf --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/ProfilerListener.php @@ -0,0 +1,165 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\EventListener; + +use Symfony\Component\HttpKernel\Event\GetResponseEvent; +use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; +use Symfony\Component\HttpKernel\Event\FilterResponseEvent; +use Symfony\Component\HttpKernel\Event\PostResponseEvent; +use Symfony\Component\HttpKernel\KernelEvents; +use Symfony\Component\HttpKernel\Profiler\Profiler; +use Symfony\Component\HttpFoundation\RequestMatcherInterface; +use Symfony\Component\HttpFoundation\RequestStack; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +/** + * ProfilerListener collects data for the current request by listening to the kernel events. + * + * @author Fabien Potencier + */ +class ProfilerListener implements EventSubscriberInterface +{ + protected $profiler; + protected $matcher; + protected $onlyException; + protected $onlyMasterRequests; + protected $exception; + protected $requests = array(); + protected $profiles; + protected $requestStack; + protected $parents; + + /** + * Constructor. + * + * @param Profiler $profiler A Profiler instance + * @param RequestMatcherInterface|null $matcher A RequestMatcher instance + * @param bool $onlyException true if the profiler only collects data when an exception occurs, false otherwise + * @param bool $onlyMasterRequests true if the profiler only collects data when the request is a master request, false otherwise + * @param RequestStack|null $requestStack A RequestStack instance + */ + public function __construct(Profiler $profiler, RequestMatcherInterface $matcher = null, $onlyException = false, $onlyMasterRequests = false, RequestStack $requestStack = null) + { + if (null === $requestStack) { + // Prevent the deprecation notice to be triggered all the time. + // The onKernelRequest() method fires some logic only when the + // RequestStack instance is not provided as a dependency. + @trigger_error('Since version 2.4, the '.__METHOD__.' method must accept a RequestStack instance to get the request instead of using the '.__CLASS__.'::onKernelRequest method that will be removed in 3.0.', E_USER_DEPRECATED); + } + + $this->profiler = $profiler; + $this->matcher = $matcher; + $this->onlyException = (bool) $onlyException; + $this->onlyMasterRequests = (bool) $onlyMasterRequests; + $this->profiles = new \SplObjectStorage(); + $this->parents = new \SplObjectStorage(); + $this->requestStack = $requestStack; + } + + /** + * Handles the onKernelException event. + * + * @param GetResponseForExceptionEvent $event A GetResponseForExceptionEvent instance + */ + public function onKernelException(GetResponseForExceptionEvent $event) + { + if ($this->onlyMasterRequests && !$event->isMasterRequest()) { + return; + } + + $this->exception = $event->getException(); + } + + /** + * @deprecated since version 2.4, to be removed in 3.0. + */ + public function onKernelRequest(GetResponseEvent $event) + { + if (null === $this->requestStack) { + $this->requests[] = $event->getRequest(); + } + } + + /** + * Handles the onKernelResponse event. + * + * @param FilterResponseEvent $event A FilterResponseEvent instance + */ + public function onKernelResponse(FilterResponseEvent $event) + { + $master = $event->isMasterRequest(); + if ($this->onlyMasterRequests && !$master) { + return; + } + + if ($this->onlyException && null === $this->exception) { + return; + } + + $request = $event->getRequest(); + $exception = $this->exception; + $this->exception = null; + + if (null !== $this->matcher && !$this->matcher->matches($request)) { + return; + } + + if (!$profile = $this->profiler->collect($request, $event->getResponse(), $exception)) { + return; + } + + $this->profiles[$request] = $profile; + + if (null !== $this->requestStack) { + $this->parents[$request] = $this->requestStack->getParentRequest(); + } elseif (!$master) { + // to be removed when requestStack is required + array_pop($this->requests); + + $this->parents[$request] = end($this->requests); + } + } + + public function onKernelTerminate(PostResponseEvent $event) + { + // attach children to parents + foreach ($this->profiles as $request) { + // isset call should be removed when requestStack is required + if (isset($this->parents[$request]) && null !== $parentRequest = $this->parents[$request]) { + if (isset($this->profiles[$parentRequest])) { + $this->profiles[$parentRequest]->addChild($this->profiles[$request]); + } + } + } + + // save profiles + foreach ($this->profiles as $request) { + $this->profiler->saveProfile($this->profiles[$request]); + } + + $this->profiles = new \SplObjectStorage(); + $this->parents = new \SplObjectStorage(); + $this->requests = array(); + } + + public static function getSubscribedEvents() + { + return array( + // kernel.request must be registered as early as possible to not break + // when an exception is thrown in any other kernel.request listener + KernelEvents::REQUEST => array('onKernelRequest', 1024), + KernelEvents::RESPONSE => array('onKernelResponse', -100), + KernelEvents::EXCEPTION => 'onKernelException', + KernelEvents::TERMINATE => array('onKernelTerminate', -1024), + ); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/ResponseListener.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/ResponseListener.php new file mode 100644 index 0000000..eeb2b0f --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/ResponseListener.php @@ -0,0 +1,58 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\EventListener; + +use Symfony\Component\HttpKernel\Event\FilterResponseEvent; +use Symfony\Component\HttpKernel\KernelEvents; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +/** + * ResponseListener fixes the Response headers based on the Request. + * + * @author Fabien Potencier + */ +class ResponseListener implements EventSubscriberInterface +{ + private $charset; + + public function __construct($charset) + { + $this->charset = $charset; + } + + /** + * Filters the Response. + * + * @param FilterResponseEvent $event A FilterResponseEvent instance + */ + public function onKernelResponse(FilterResponseEvent $event) + { + if (!$event->isMasterRequest()) { + return; + } + + $response = $event->getResponse(); + + if (null === $response->getCharset()) { + $response->setCharset($this->charset); + } + + $response->prepare($event->getRequest()); + } + + public static function getSubscribedEvents() + { + return array( + KernelEvents::RESPONSE => 'onKernelResponse', + ); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/RouterListener.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/RouterListener.php new file mode 100644 index 0000000..297aab6 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/RouterListener.php @@ -0,0 +1,174 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\EventListener; + +use Psr\Log\LoggerInterface; +use Symfony\Component\HttpKernel\Event\GetResponseEvent; +use Symfony\Component\HttpKernel\Event\FinishRequestEvent; +use Symfony\Component\HttpKernel\KernelEvents; +use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; +use Symfony\Component\HttpFoundation\RequestStack; +use Symfony\Component\Routing\Exception\MethodNotAllowedException; +use Symfony\Component\Routing\Exception\ResourceNotFoundException; +use Symfony\Component\Routing\Matcher\UrlMatcherInterface; +use Symfony\Component\Routing\Matcher\RequestMatcherInterface; +use Symfony\Component\Routing\RequestContext; +use Symfony\Component\Routing\RequestContextAwareInterface; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\HttpFoundation\Request; + +/** + * Initializes the context from the request and sets request attributes based on a matching route. + * + * This listener works in 2 modes: + * + * * 2.3 compatibility mode where you must call setRequest whenever the Request changes. + * * 2.4+ mode where you must pass a RequestStack instance in the constructor. + * + * @author Fabien Potencier + */ +class RouterListener implements EventSubscriberInterface +{ + private $matcher; + private $context; + private $logger; + private $request; + private $requestStack; + + /** + * Constructor. + * + * RequestStack will become required in 3.0. + * + * @param UrlMatcherInterface|RequestMatcherInterface $matcher The Url or Request matcher + * @param RequestContext|null $context The RequestContext (can be null when $matcher implements RequestContextAwareInterface) + * @param LoggerInterface|null $logger The logger + * @param RequestStack|null $requestStack A RequestStack instance + * + * @throws \InvalidArgumentException + */ + public function __construct($matcher, RequestContext $context = null, LoggerInterface $logger = null, RequestStack $requestStack = null) + { + if (!$matcher instanceof UrlMatcherInterface && !$matcher instanceof RequestMatcherInterface) { + throw new \InvalidArgumentException('Matcher must either implement UrlMatcherInterface or RequestMatcherInterface.'); + } + + if (null === $context && !$matcher instanceof RequestContextAwareInterface) { + throw new \InvalidArgumentException('You must either pass a RequestContext or the matcher must implement RequestContextAwareInterface.'); + } + + if (!$requestStack instanceof RequestStack) { + @trigger_error('The '.__METHOD__.' method now requires a RequestStack instance as '.__CLASS__.'::setRequest method will not be supported anymore in 3.0.', E_USER_DEPRECATED); + } + + $this->matcher = $matcher; + $this->context = $context ?: $matcher->getContext(); + $this->requestStack = $requestStack; + $this->logger = $logger; + } + + /** + * Sets the current Request. + * + * This method was used to synchronize the Request, but as the HttpKernel + * is doing that automatically now, you should never call it directly. + * It is kept public for BC with the 2.3 version. + * + * @param Request|null $request A Request instance + * + * @deprecated since version 2.4, to be removed in 3.0. + */ + public function setRequest(Request $request = null) + { + @trigger_error('The '.__METHOD__.' method is deprecated since version 2.4 and will be made private in 3.0.', E_USER_DEPRECATED); + + $this->setCurrentRequest($request); + } + + private function setCurrentRequest(Request $request = null) + { + if (null !== $request && $this->request !== $request) { + $this->context->fromRequest($request); + } + + $this->request = $request; + } + + public function onKernelFinishRequest(FinishRequestEvent $event) + { + if (null === $this->requestStack) { + return; // removed when requestStack is required + } + + $this->setCurrentRequest($this->requestStack->getParentRequest()); + } + + public function onKernelRequest(GetResponseEvent $event) + { + $request = $event->getRequest(); + + // initialize the context that is also used by the generator (assuming matcher and generator share the same context instance) + // we call setCurrentRequest even if most of the time, it has already been done to keep compatibility + // with frameworks which do not use the Symfony service container + // when we have a RequestStack, no need to do it + if (null !== $this->requestStack) { + $this->setCurrentRequest($request); + } + + if ($request->attributes->has('_controller')) { + // routing is already done + return; + } + + // add attributes based on the request (routing) + try { + // matching a request is more powerful than matching a URL path + context, so try that first + if ($this->matcher instanceof RequestMatcherInterface) { + $parameters = $this->matcher->matchRequest($request); + } else { + $parameters = $this->matcher->match($request->getPathInfo()); + } + + if (null !== $this->logger) { + $this->logger->info(sprintf('Matched route "%s".', isset($parameters['_route']) ? $parameters['_route'] : 'n/a'), array( + 'route_parameters' => $parameters, + 'request_uri' => $request->getUri(), + )); + } + + $request->attributes->add($parameters); + unset($parameters['_route'], $parameters['_controller']); + $request->attributes->set('_route_params', $parameters); + } catch (ResourceNotFoundException $e) { + $message = sprintf('No route found for "%s %s"', $request->getMethod(), $request->getPathInfo()); + + if ($referer = $request->headers->get('referer')) { + $message .= sprintf(' (from "%s")', $referer); + } + + throw new NotFoundHttpException($message, $e); + } catch (MethodNotAllowedException $e) { + $message = sprintf('No route found for "%s %s": Method Not Allowed (Allow: %s)', $request->getMethod(), $request->getPathInfo(), implode(', ', $e->getAllowedMethods())); + + throw new MethodNotAllowedHttpException($e->getAllowedMethods(), $message, $e); + } + } + + public static function getSubscribedEvents() + { + return array( + KernelEvents::REQUEST => array(array('onKernelRequest', 32)), + KernelEvents::FINISH_REQUEST => array(array('onKernelFinishRequest', 0)), + ); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/SaveSessionListener.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/SaveSessionListener.php new file mode 100644 index 0000000..36809b5 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/SaveSessionListener.php @@ -0,0 +1,66 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\EventListener; + +use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\HttpKernel\Event\FilterResponseEvent; +use Symfony\Component\HttpKernel\KernelEvents; + +/** + * Saves the session, in case it is still open, before sending the response/headers. + * + * This ensures several things in case the developer did not save the session explicitly: + * + * * If a session save handler without locking is used, it ensures the data is available + * on the next request, e.g. after a redirect. PHPs auto-save at script end via + * session_register_shutdown is executed after fastcgi_finish_request. So in this case + * the data could be missing the next request because it might not be saved the moment + * the new request is processed. + * * A locking save handler (e.g. the native 'files') circumvents concurrency problems like + * the one above. But by saving the session before long-running things in the terminate event, + * we ensure the session is not blocked longer than needed. + * * When regenerating the session ID no locking is involved in PHPs session design. See + * https://bugs.php.net/bug.php?id=61470 for a discussion. So in this case, the session must + * be saved anyway before sending the headers with the new session ID. Otherwise session + * data could get lost again for concurrent requests with the new ID. One result could be + * that you get logged out after just logging in. + * + * This listener should be executed as one of the last listeners, so that previous listeners + * can still operate on the open session. This prevents the overhead of restarting it. + * Listeners after closing the session can still work with the session as usual because + * Symfonys session implementation starts the session on demand. So writing to it after + * it is saved will just restart it. + * + * @author Tobias Schultze + */ +class SaveSessionListener implements EventSubscriberInterface +{ + public function onKernelResponse(FilterResponseEvent $event) + { + if (!$event->isMasterRequest()) { + return; + } + + $session = $event->getRequest()->getSession(); + if ($session && $session->isStarted()) { + $session->save(); + } + } + + public static function getSubscribedEvents() + { + return array( + // low priority but higher than StreamedResponseListener + KernelEvents::RESPONSE => array(array('onKernelResponse', -1000)), + ); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/SessionListener.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/SessionListener.php new file mode 100644 index 0000000..ecf065f --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/SessionListener.php @@ -0,0 +1,53 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\EventListener; + +use Symfony\Component\HttpKernel\Event\GetResponseEvent; +use Symfony\Component\HttpKernel\KernelEvents; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +/** + * Sets the session in the request. + * + * @author Johannes M. Schmitt + */ +abstract class SessionListener implements EventSubscriberInterface +{ + public function onKernelRequest(GetResponseEvent $event) + { + if (!$event->isMasterRequest()) { + return; + } + + $request = $event->getRequest(); + $session = $this->getSession(); + if (null === $session || $request->hasSession()) { + return; + } + + $request->setSession($session); + } + + public static function getSubscribedEvents() + { + return array( + KernelEvents::REQUEST => array('onKernelRequest', 128), + ); + } + + /** + * Gets the session object. + * + * @return SessionInterface|null A SessionInterface instance or null if no session is available + */ + abstract protected function getSession(); +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/StreamedResponseListener.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/StreamedResponseListener.php new file mode 100644 index 0000000..571cd74 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/StreamedResponseListener.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\EventListener; + +use Symfony\Component\HttpFoundation\StreamedResponse; +use Symfony\Component\HttpKernel\Event\FilterResponseEvent; +use Symfony\Component\HttpKernel\KernelEvents; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +/** + * StreamedResponseListener is responsible for sending the Response + * to the client. + * + * @author Fabien Potencier + */ +class StreamedResponseListener implements EventSubscriberInterface +{ + /** + * Filters the Response. + * + * @param FilterResponseEvent $event A FilterResponseEvent instance + */ + public function onKernelResponse(FilterResponseEvent $event) + { + if (!$event->isMasterRequest()) { + return; + } + + $response = $event->getResponse(); + + if ($response instanceof StreamedResponse) { + $response->send(); + } + } + + public static function getSubscribedEvents() + { + return array( + KernelEvents::RESPONSE => array('onKernelResponse', -1024), + ); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/SurrogateListener.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/SurrogateListener.php new file mode 100644 index 0000000..dc815a2 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/SurrogateListener.php @@ -0,0 +1,58 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\EventListener; + +use Symfony\Component\HttpKernel\Event\FilterResponseEvent; +use Symfony\Component\HttpKernel\HttpCache\SurrogateInterface; +use Symfony\Component\HttpKernel\KernelEvents; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +/** + * SurrogateListener adds a Surrogate-Control HTTP header when the Response needs to be parsed for Surrogates. + * + * @author Fabien Potencier + */ +class SurrogateListener implements EventSubscriberInterface +{ + private $surrogate; + + /** + * Constructor. + * + * @param SurrogateInterface $surrogate An SurrogateInterface instance + */ + public function __construct(SurrogateInterface $surrogate = null) + { + $this->surrogate = $surrogate; + } + + /** + * Filters the Response. + * + * @param FilterResponseEvent $event A FilterResponseEvent instance + */ + public function onKernelResponse(FilterResponseEvent $event) + { + if (!$event->isMasterRequest() || null === $this->surrogate) { + return; + } + + $this->surrogate->addSurrogateControl($event->getResponse()); + } + + public static function getSubscribedEvents() + { + return array( + KernelEvents::RESPONSE => 'onKernelResponse', + ); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/TestSessionListener.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/TestSessionListener.php new file mode 100644 index 0000000..8fc8e57 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/TestSessionListener.php @@ -0,0 +1,83 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\EventListener; + +use Symfony\Component\HttpFoundation\Cookie; +use Symfony\Component\HttpKernel\KernelEvents; +use Symfony\Component\HttpKernel\Event\FilterResponseEvent; +use Symfony\Component\HttpKernel\Event\GetResponseEvent; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +/** + * TestSessionListener. + * + * Saves session in test environment. + * + * @author Bulat Shakirzyanov + * @author Fabien Potencier + */ +abstract class TestSessionListener implements EventSubscriberInterface +{ + public function onKernelRequest(GetResponseEvent $event) + { + if (!$event->isMasterRequest()) { + return; + } + + // bootstrap the session + $session = $this->getSession(); + if (!$session) { + return; + } + + $cookies = $event->getRequest()->cookies; + + if ($cookies->has($session->getName())) { + $session->setId($cookies->get($session->getName())); + } + } + + /** + * Checks if session was initialized and saves if current request is master + * Runs on 'kernel.response' in test environment. + * + * @param FilterResponseEvent $event + */ + public function onKernelResponse(FilterResponseEvent $event) + { + if (!$event->isMasterRequest()) { + return; + } + + $session = $event->getRequest()->getSession(); + if ($session && $session->isStarted()) { + $session->save(); + $params = session_get_cookie_params(); + $event->getResponse()->headers->setCookie(new Cookie($session->getName(), $session->getId(), 0 === $params['lifetime'] ? 0 : time() + $params['lifetime'], $params['path'], $params['domain'], $params['secure'], $params['httponly'])); + } + } + + public static function getSubscribedEvents() + { + return array( + KernelEvents::REQUEST => array('onKernelRequest', 192), + KernelEvents::RESPONSE => array('onKernelResponse', -128), + ); + } + + /** + * Gets the session object. + * + * @return SessionInterface|null A SessionInterface instance or null if no session is available + */ + abstract protected function getSession(); +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/TranslatorListener.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/TranslatorListener.php new file mode 100644 index 0000000..6967ad0 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/TranslatorListener.php @@ -0,0 +1,69 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\EventListener; + +use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpKernel\Event\GetResponseEvent; +use Symfony\Component\HttpKernel\Event\FinishRequestEvent; +use Symfony\Component\HttpKernel\KernelEvents; +use Symfony\Component\HttpFoundation\RequestStack; +use Symfony\Component\Translation\TranslatorInterface; + +/** + * Synchronizes the locale between the request and the translator. + * + * @author Fabien Potencier + */ +class TranslatorListener implements EventSubscriberInterface +{ + private $translator; + private $requestStack; + + public function __construct(TranslatorInterface $translator, RequestStack $requestStack) + { + $this->translator = $translator; + $this->requestStack = $requestStack; + } + + public function onKernelRequest(GetResponseEvent $event) + { + $this->setLocale($event->getRequest()); + } + + public function onKernelFinishRequest(FinishRequestEvent $event) + { + if (null === $parentRequest = $this->requestStack->getParentRequest()) { + return; + } + + $this->setLocale($parentRequest); + } + + public static function getSubscribedEvents() + { + return array( + // must be registered after the Locale listener + KernelEvents::REQUEST => array(array('onKernelRequest', 10)), + KernelEvents::FINISH_REQUEST => array(array('onKernelFinishRequest', 0)), + ); + } + + private function setLocale(Request $request) + { + try { + $this->translator->setLocale($request->getLocale()); + } catch (\InvalidArgumentException $e) { + $this->translator->setLocale($request->getDefaultLocale()); + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/ValidateRequestListener.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/ValidateRequestListener.php new file mode 100644 index 0000000..00096cc --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/EventListener/ValidateRequestListener.php @@ -0,0 +1,55 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\EventListener; + +use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\HttpKernel\Event\GetResponseEvent; +use Symfony\Component\HttpKernel\KernelEvents; + +/** + * Validates that the headers and other information indicating the + * client IP address of a request are consistent. + * + * @author Magnus Nordlander + */ +class ValidateRequestListener implements EventSubscriberInterface +{ + /** + * Performs the validation. + * + * @param GetResponseEvent $event + */ + public function onKernelRequest(GetResponseEvent $event) + { + if (!$event->isMasterRequest()) { + return; + } + $request = $event->getRequest(); + + if ($request::getTrustedProxies()) { + // This will throw an exception if the headers are inconsistent. + $request->getClientIps(); + } + } + + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents() + { + return array( + KernelEvents::REQUEST => array( + array('onKernelRequest', 256), + ), + ); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/AccessDeniedHttpException.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/AccessDeniedHttpException.php new file mode 100644 index 0000000..79d8639 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/AccessDeniedHttpException.php @@ -0,0 +1,33 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Exception; + +/** + * AccessDeniedHttpException. + * + * @author Fabien Potencier + * @author Christophe Coevoet + */ +class AccessDeniedHttpException extends HttpException +{ + /** + * Constructor. + * + * @param string $message The internal exception message + * @param \Exception $previous The previous exception + * @param int $code The internal exception code + */ + public function __construct($message = null, \Exception $previous = null, $code = 0) + { + parent::__construct(403, $message, $previous, array(), $code); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/BadRequestHttpException.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/BadRequestHttpException.php new file mode 100644 index 0000000..5f68172 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/BadRequestHttpException.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Exception; + +/** + * BadRequestHttpException. + * + * @author Ben Ramsey + */ +class BadRequestHttpException extends HttpException +{ + /** + * Constructor. + * + * @param string $message The internal exception message + * @param \Exception $previous The previous exception + * @param int $code The internal exception code + */ + public function __construct($message = null, \Exception $previous = null, $code = 0) + { + parent::__construct(400, $message, $previous, array(), $code); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/ConflictHttpException.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/ConflictHttpException.php new file mode 100644 index 0000000..34d738e --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/ConflictHttpException.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Exception; + +/** + * ConflictHttpException. + * + * @author Ben Ramsey + */ +class ConflictHttpException extends HttpException +{ + /** + * Constructor. + * + * @param string $message The internal exception message + * @param \Exception $previous The previous exception + * @param int $code The internal exception code + */ + public function __construct($message = null, \Exception $previous = null, $code = 0) + { + parent::__construct(409, $message, $previous, array(), $code); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/FatalErrorException.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/FatalErrorException.php new file mode 100644 index 0000000..0d2b4f9 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/FatalErrorException.php @@ -0,0 +1,23 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Exception; + +@trigger_error('The '.__NAMESPACE__.'\FatalErrorException class is deprecated since version 2.3 and will be removed in 3.0. Use the Symfony\Component\Debug\Exception\FatalErrorException class instead.', E_USER_DEPRECATED); + +/* + * Fatal Error Exception. + * + * @author Konstanton Myakshin + * + * @deprecated since version 2.3, to be removed in 3.0. Use the same class from the Debug component instead. + */ +class_exists('Symfony\Component\Debug\Exception\FatalErrorException'); diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/FlattenException.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/FlattenException.php new file mode 100644 index 0000000..599aa95 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/FlattenException.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Exception; + +@trigger_error('The '.__NAMESPACE__.'\FlattenException class is deprecated since version 2.3 and will be removed in 3.0. Use the Symfony\Component\Debug\Exception\FlattenException class instead.', E_USER_DEPRECATED); + +/* + * FlattenException wraps a PHP Exception to be able to serialize it. + * + * Basically, this class removes all objects from the trace. + * + * @author Fabien Potencier + * + * @deprecated since version 2.3, to be removed in 3.0. Use the same class from the Debug component instead. + */ +class_exists('Symfony\Component\Debug\Exception\FlattenException'); diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/GoneHttpException.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/GoneHttpException.php new file mode 100644 index 0000000..16ea223 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/GoneHttpException.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Exception; + +/** + * GoneHttpException. + * + * @author Ben Ramsey + */ +class GoneHttpException extends HttpException +{ + /** + * Constructor. + * + * @param string $message The internal exception message + * @param \Exception $previous The previous exception + * @param int $code The internal exception code + */ + public function __construct($message = null, \Exception $previous = null, $code = 0) + { + parent::__construct(410, $message, $previous, array(), $code); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/HttpException.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/HttpException.php new file mode 100644 index 0000000..4e1b526 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/HttpException.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Exception; + +/** + * HttpException. + * + * @author Kris Wallsmith + */ +class HttpException extends \RuntimeException implements HttpExceptionInterface +{ + private $statusCode; + private $headers; + + public function __construct($statusCode, $message = null, \Exception $previous = null, array $headers = array(), $code = 0) + { + $this->statusCode = $statusCode; + $this->headers = $headers; + + parent::__construct($message, $code, $previous); + } + + public function getStatusCode() + { + return $this->statusCode; + } + + public function getHeaders() + { + return $this->headers; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/HttpExceptionInterface.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/HttpExceptionInterface.php new file mode 100644 index 0000000..8aa50a9 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/HttpExceptionInterface.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Exception; + +/** + * Interface for HTTP error exceptions. + * + * @author Kris Wallsmith + */ +interface HttpExceptionInterface +{ + /** + * Returns the status code. + * + * @return int An HTTP response status code + */ + public function getStatusCode(); + + /** + * Returns response headers. + * + * @return array Response headers + */ + public function getHeaders(); +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/LengthRequiredHttpException.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/LengthRequiredHttpException.php new file mode 100644 index 0000000..0c4b943 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/LengthRequiredHttpException.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Exception; + +/** + * LengthRequiredHttpException. + * + * @author Ben Ramsey + */ +class LengthRequiredHttpException extends HttpException +{ + /** + * Constructor. + * + * @param string $message The internal exception message + * @param \Exception $previous The previous exception + * @param int $code The internal exception code + */ + public function __construct($message = null, \Exception $previous = null, $code = 0) + { + parent::__construct(411, $message, $previous, array(), $code); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/MethodNotAllowedHttpException.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/MethodNotAllowedHttpException.php new file mode 100644 index 0000000..78dd26b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/MethodNotAllowedHttpException.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Exception; + +/** + * MethodNotAllowedHttpException. + * + * @author Kris Wallsmith + */ +class MethodNotAllowedHttpException extends HttpException +{ + /** + * Constructor. + * + * @param array $allow An array of allowed methods + * @param string $message The internal exception message + * @param \Exception $previous The previous exception + * @param int $code The internal exception code + */ + public function __construct(array $allow, $message = null, \Exception $previous = null, $code = 0) + { + $headers = array('Allow' => strtoupper(implode(', ', $allow))); + + parent::__construct(405, $message, $previous, $headers, $code); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/NotAcceptableHttpException.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/NotAcceptableHttpException.php new file mode 100644 index 0000000..cc6be4b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/NotAcceptableHttpException.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Exception; + +/** + * NotAcceptableHttpException. + * + * @author Ben Ramsey + */ +class NotAcceptableHttpException extends HttpException +{ + /** + * Constructor. + * + * @param string $message The internal exception message + * @param \Exception $previous The previous exception + * @param int $code The internal exception code + */ + public function __construct($message = null, \Exception $previous = null, $code = 0) + { + parent::__construct(406, $message, $previous, array(), $code); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/NotFoundHttpException.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/NotFoundHttpException.php new file mode 100644 index 0000000..4639e37 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/NotFoundHttpException.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Exception; + +/** + * NotFoundHttpException. + * + * @author Fabien Potencier + */ +class NotFoundHttpException extends HttpException +{ + /** + * Constructor. + * + * @param string $message The internal exception message + * @param \Exception $previous The previous exception + * @param int $code The internal exception code + */ + public function __construct($message = null, \Exception $previous = null, $code = 0) + { + parent::__construct(404, $message, $previous, array(), $code); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/PreconditionFailedHttpException.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/PreconditionFailedHttpException.php new file mode 100644 index 0000000..9df0e7b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/PreconditionFailedHttpException.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Exception; + +/** + * PreconditionFailedHttpException. + * + * @author Ben Ramsey + */ +class PreconditionFailedHttpException extends HttpException +{ + /** + * Constructor. + * + * @param string $message The internal exception message + * @param \Exception $previous The previous exception + * @param int $code The internal exception code + */ + public function __construct($message = null, \Exception $previous = null, $code = 0) + { + parent::__construct(412, $message, $previous, array(), $code); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/PreconditionRequiredHttpException.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/PreconditionRequiredHttpException.php new file mode 100644 index 0000000..08ebca2 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/PreconditionRequiredHttpException.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Exception; + +/** + * PreconditionRequiredHttpException. + * + * @author Ben Ramsey + * + * @see http://tools.ietf.org/html/rfc6585 + */ +class PreconditionRequiredHttpException extends HttpException +{ + /** + * Constructor. + * + * @param string $message The internal exception message + * @param \Exception $previous The previous exception + * @param int $code The internal exception code + */ + public function __construct($message = null, \Exception $previous = null, $code = 0) + { + parent::__construct(428, $message, $previous, array(), $code); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/ServiceUnavailableHttpException.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/ServiceUnavailableHttpException.php new file mode 100644 index 0000000..32b9e2d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/ServiceUnavailableHttpException.php @@ -0,0 +1,38 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Exception; + +/** + * ServiceUnavailableHttpException. + * + * @author Ben Ramsey + */ +class ServiceUnavailableHttpException extends HttpException +{ + /** + * Constructor. + * + * @param int|string $retryAfter The number of seconds or HTTP-date after which the request may be retried + * @param string $message The internal exception message + * @param \Exception $previous The previous exception + * @param int $code The internal exception code + */ + public function __construct($retryAfter = null, $message = null, \Exception $previous = null, $code = 0) + { + $headers = array(); + if ($retryAfter) { + $headers = array('Retry-After' => $retryAfter); + } + + parent::__construct(503, $message, $previous, $headers, $code); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/TooManyRequestsHttpException.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/TooManyRequestsHttpException.php new file mode 100644 index 0000000..ab86e09 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/TooManyRequestsHttpException.php @@ -0,0 +1,40 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Exception; + +/** + * TooManyRequestsHttpException. + * + * @author Ben Ramsey + * + * @see http://tools.ietf.org/html/rfc6585 + */ +class TooManyRequestsHttpException extends HttpException +{ + /** + * Constructor. + * + * @param int|string $retryAfter The number of seconds or HTTP-date after which the request may be retried + * @param string $message The internal exception message + * @param \Exception $previous The previous exception + * @param int $code The internal exception code + */ + public function __construct($retryAfter = null, $message = null, \Exception $previous = null, $code = 0) + { + $headers = array(); + if ($retryAfter) { + $headers = array('Retry-After' => $retryAfter); + } + + parent::__construct(429, $message, $previous, $headers, $code); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/UnauthorizedHttpException.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/UnauthorizedHttpException.php new file mode 100644 index 0000000..0dfe42d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/UnauthorizedHttpException.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Exception; + +/** + * UnauthorizedHttpException. + * + * @author Ben Ramsey + */ +class UnauthorizedHttpException extends HttpException +{ + /** + * Constructor. + * + * @param string $challenge WWW-Authenticate challenge string + * @param string $message The internal exception message + * @param \Exception $previous The previous exception + * @param int $code The internal exception code + */ + public function __construct($challenge, $message = null, \Exception $previous = null, $code = 0) + { + $headers = array('WWW-Authenticate' => $challenge); + + parent::__construct(401, $message, $previous, $headers, $code); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/UnprocessableEntityHttpException.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/UnprocessableEntityHttpException.php new file mode 100644 index 0000000..eb13f56 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/UnprocessableEntityHttpException.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Exception; + +/** + * UnprocessableEntityHttpException. + * + * @author Steve Hutchins + */ +class UnprocessableEntityHttpException extends HttpException +{ + /** + * Constructor. + * + * @param string $message The internal exception message + * @param \Exception $previous The previous exception + * @param int $code The internal exception code + */ + public function __construct($message = null, \Exception $previous = null, $code = 0) + { + parent::__construct(422, $message, $previous, array(), $code); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/UnsupportedMediaTypeHttpException.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/UnsupportedMediaTypeHttpException.php new file mode 100644 index 0000000..a9d8fa0 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Exception/UnsupportedMediaTypeHttpException.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Exception; + +/** + * UnsupportedMediaTypeHttpException. + * + * @author Ben Ramsey + */ +class UnsupportedMediaTypeHttpException extends HttpException +{ + /** + * Constructor. + * + * @param string $message The internal exception message + * @param \Exception $previous The previous exception + * @param int $code The internal exception code + */ + public function __construct($message = null, \Exception $previous = null, $code = 0) + { + parent::__construct(415, $message, $previous, array(), $code); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Fragment/AbstractSurrogateFragmentRenderer.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Fragment/AbstractSurrogateFragmentRenderer.php new file mode 100644 index 0000000..1968001 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Fragment/AbstractSurrogateFragmentRenderer.php @@ -0,0 +1,95 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Fragment; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\Controller\ControllerReference; +use Symfony\Component\HttpKernel\HttpCache\SurrogateInterface; +use Symfony\Component\HttpKernel\UriSigner; + +/** + * Implements Surrogate rendering strategy. + * + * @author Fabien Potencier + */ +abstract class AbstractSurrogateFragmentRenderer extends RoutableFragmentRenderer +{ + private $surrogate; + private $inlineStrategy; + private $signer; + + /** + * Constructor. + * + * The "fallback" strategy when surrogate is not available should always be an + * instance of InlineFragmentRenderer. + * + * @param SurrogateInterface $surrogate An Surrogate instance + * @param FragmentRendererInterface $inlineStrategy The inline strategy to use when the surrogate is not supported + * @param UriSigner $signer + */ + public function __construct(SurrogateInterface $surrogate = null, FragmentRendererInterface $inlineStrategy, UriSigner $signer = null) + { + $this->surrogate = $surrogate; + $this->inlineStrategy = $inlineStrategy; + $this->signer = $signer; + } + + /** + * {@inheritdoc} + * + * Note that if the current Request has no surrogate capability, this method + * falls back to use the inline rendering strategy. + * + * Additional available options: + * + * * alt: an alternative URI to render in case of an error + * * comment: a comment to add when returning the surrogate tag + * + * Note, that not all surrogate strategies support all options. For now + * 'alt' and 'comment' are only supported by ESI. + * + * @see Symfony\Component\HttpKernel\HttpCache\SurrogateInterface + */ + public function render($uri, Request $request, array $options = array()) + { + if (!$this->surrogate || !$this->surrogate->hasSurrogateCapability($request)) { + return $this->inlineStrategy->render($uri, $request, $options); + } + + if ($uri instanceof ControllerReference) { + $uri = $this->generateSignedFragmentUri($uri, $request); + } + + $alt = isset($options['alt']) ? $options['alt'] : null; + if ($alt instanceof ControllerReference) { + $alt = $this->generateSignedFragmentUri($alt, $request); + } + + $tag = $this->surrogate->renderIncludeTag($uri, $alt, isset($options['ignore_errors']) ? $options['ignore_errors'] : false, isset($options['comment']) ? $options['comment'] : ''); + + return new Response($tag); + } + + private function generateSignedFragmentUri($uri, Request $request) + { + if (null === $this->signer) { + throw new \LogicException('You must use a URI when using the ESI rendering strategy or set a URL signer.'); + } + + // we need to sign the absolute URI, but want to return the path only. + $fragmentUri = $this->signer->sign($this->generateFragmentUri($uri, $request, true)); + + return substr($fragmentUri, strlen($request->getSchemeAndHttpHost())); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Fragment/EsiFragmentRenderer.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Fragment/EsiFragmentRenderer.php new file mode 100644 index 0000000..a4570e3 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Fragment/EsiFragmentRenderer.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Fragment; + +/** + * Implements the ESI rendering strategy. + * + * @author Fabien Potencier + */ +class EsiFragmentRenderer extends AbstractSurrogateFragmentRenderer +{ + /** + * {@inheritdoc} + */ + public function getName() + { + return 'esi'; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Fragment/FragmentHandler.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Fragment/FragmentHandler.php new file mode 100644 index 0000000..774870a --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Fragment/FragmentHandler.php @@ -0,0 +1,150 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Fragment; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpFoundation\StreamedResponse; +use Symfony\Component\HttpFoundation\RequestStack; +use Symfony\Component\HttpKernel\Controller\ControllerReference; + +/** + * Renders a URI that represents a resource fragment. + * + * This class handles the rendering of resource fragments that are included into + * a main resource. The handling of the rendering is managed by specialized renderers. + * + * This listener works in 2 modes: + * + * * 2.3 compatibility mode where you must call setRequest whenever the Request changes. + * * 2.4+ mode where you must pass a RequestStack instance in the constructor. + * + * @author Fabien Potencier + * + * @see FragmentRendererInterface + */ +class FragmentHandler +{ + private $debug; + private $renderers = array(); + private $request; + private $requestStack; + + /** + * Constructor. + * + * RequestStack will become required in 3.0. + * + * @param FragmentRendererInterface[] $renderers An array of FragmentRendererInterface instances + * @param bool $debug Whether the debug mode is enabled or not + * @param RequestStack|null $requestStack The Request stack that controls the lifecycle of requests + */ + public function __construct(array $renderers = array(), $debug = false, RequestStack $requestStack = null) + { + $this->requestStack = $requestStack; + foreach ($renderers as $renderer) { + $this->addRenderer($renderer); + } + $this->debug = $debug; + } + + /** + * Adds a renderer. + * + * @param FragmentRendererInterface $renderer A FragmentRendererInterface instance + */ + public function addRenderer(FragmentRendererInterface $renderer) + { + $this->renderers[$renderer->getName()] = $renderer; + } + + /** + * Sets the current Request. + * + * This method was used to synchronize the Request, but as the HttpKernel + * is doing that automatically now, you should never call it directly. + * It is kept public for BC with the 2.3 version. + * + * @param Request|null $request A Request instance + * + * @deprecated since version 2.4, to be removed in 3.0. + */ + public function setRequest(Request $request = null) + { + @trigger_error('The '.__METHOD__.' method is deprecated since version 2.4 and will be removed in 3.0.', E_USER_DEPRECATED); + + $this->request = $request; + } + + /** + * Renders a URI and returns the Response content. + * + * Available options: + * + * * ignore_errors: true to return an empty string in case of an error + * + * @param string|ControllerReference $uri A URI as a string or a ControllerReference instance + * @param string $renderer The renderer name + * @param array $options An array of options + * + * @return string|null The Response content or null when the Response is streamed + * + * @throws \InvalidArgumentException when the renderer does not exist + * @throws \LogicException when no master request is being handled + */ + public function render($uri, $renderer = 'inline', array $options = array()) + { + if (!isset($options['ignore_errors'])) { + $options['ignore_errors'] = !$this->debug; + } + + if (!isset($this->renderers[$renderer])) { + throw new \InvalidArgumentException(sprintf('The "%s" renderer does not exist.', $renderer)); + } + + if (!$request = $this->getRequest()) { + throw new \LogicException('Rendering a fragment can only be done when handling a Request.'); + } + + return $this->deliver($this->renderers[$renderer]->render($uri, $request, $options)); + } + + /** + * Delivers the Response as a string. + * + * When the Response is a StreamedResponse, the content is streamed immediately + * instead of being returned. + * + * @param Response $response A Response instance + * + * @return string|null The Response content or null when the Response is streamed + * + * @throws \RuntimeException when the Response is not successful + */ + protected function deliver(Response $response) + { + if (!$response->isSuccessful()) { + throw new \RuntimeException(sprintf('Error when rendering "%s" (Status code is %s).', $this->getRequest()->getUri(), $response->getStatusCode())); + } + + if (!$response instanceof StreamedResponse) { + return $response->getContent(); + } + + $response->sendContent(); + } + + private function getRequest() + { + return $this->requestStack ? $this->requestStack->getCurrentRequest() : $this->request; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Fragment/FragmentRendererInterface.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Fragment/FragmentRendererInterface.php new file mode 100644 index 0000000..b177c3a --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Fragment/FragmentRendererInterface.php @@ -0,0 +1,42 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Fragment; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpKernel\Controller\ControllerReference; +use Symfony\Component\HttpFoundation\Response; + +/** + * Interface implemented by all rendering strategies. + * + * @author Fabien Potencier + */ +interface FragmentRendererInterface +{ + /** + * Renders a URI and returns the Response content. + * + * @param string|ControllerReference $uri A URI as a string or a ControllerReference instance + * @param Request $request A Request instance + * @param array $options An array of options + * + * @return Response A Response instance + */ + public function render($uri, Request $request, array $options = array()); + + /** + * Gets the name of the strategy. + * + * @return string The strategy name + */ + public function getName(); +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Fragment/HIncludeFragmentRenderer.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Fragment/HIncludeFragmentRenderer.php new file mode 100644 index 0000000..56c96b3 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Fragment/HIncludeFragmentRenderer.php @@ -0,0 +1,164 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Fragment; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\Templating\EngineInterface; +use Symfony\Component\HttpKernel\Controller\ControllerReference; +use Symfony\Component\HttpKernel\UriSigner; + +/** + * Implements the Hinclude rendering strategy. + * + * @author Fabien Potencier + */ +class HIncludeFragmentRenderer extends RoutableFragmentRenderer +{ + private $globalDefaultTemplate; + private $signer; + private $templating; + private $charset; + + /** + * Constructor. + * + * @param EngineInterface|\Twig_Environment $templating An EngineInterface or a \Twig_Environment instance + * @param UriSigner $signer A UriSigner instance + * @param string $globalDefaultTemplate The global default content (it can be a template name or the content) + * @param string $charset + */ + public function __construct($templating = null, UriSigner $signer = null, $globalDefaultTemplate = null, $charset = 'utf-8') + { + $this->setTemplating($templating); + $this->globalDefaultTemplate = $globalDefaultTemplate; + $this->signer = $signer; + $this->charset = $charset; + } + + /** + * Sets the templating engine to use to render the default content. + * + * @param EngineInterface|\Twig_Environment|null $templating An EngineInterface or a \Twig_Environment instance + * + * @throws \InvalidArgumentException + */ + public function setTemplating($templating) + { + if (null !== $templating && !$templating instanceof EngineInterface && !$templating instanceof \Twig_Environment) { + throw new \InvalidArgumentException('The hinclude rendering strategy needs an instance of \Twig_Environment or Symfony\Component\Templating\EngineInterface'); + } + + $this->templating = $templating; + } + + /** + * Checks if a templating engine has been set. + * + * @return bool true if the templating engine has been set, false otherwise + */ + public function hasTemplating() + { + return null !== $this->templating; + } + + /** + * {@inheritdoc} + * + * Additional available options: + * + * * default: The default content (it can be a template name or the content) + * * id: An optional hx:include tag id attribute + * * attributes: An optional array of hx:include tag attributes + */ + public function render($uri, Request $request, array $options = array()) + { + if ($uri instanceof ControllerReference) { + if (null === $this->signer) { + throw new \LogicException('You must use a proper URI when using the Hinclude rendering strategy or set a URL signer.'); + } + + // we need to sign the absolute URI, but want to return the path only. + $uri = substr($this->signer->sign($this->generateFragmentUri($uri, $request, true)), strlen($request->getSchemeAndHttpHost())); + } + + // We need to replace ampersands in the URI with the encoded form in order to return valid html/xml content. + $uri = str_replace('&', '&', $uri); + + $template = isset($options['default']) ? $options['default'] : $this->globalDefaultTemplate; + if (null !== $this->templating && $template && $this->templateExists($template)) { + $content = $this->templating->render($template); + } else { + $content = $template; + } + + $attributes = isset($options['attributes']) && is_array($options['attributes']) ? $options['attributes'] : array(); + if (isset($options['id']) && $options['id']) { + $attributes['id'] = $options['id']; + } + $renderedAttributes = ''; + if (count($attributes) > 0) { + if (PHP_VERSION_ID >= 50400) { + $flags = ENT_QUOTES | ENT_SUBSTITUTE; + } else { + $flags = ENT_QUOTES; + } + foreach ($attributes as $attribute => $value) { + $renderedAttributes .= sprintf( + ' %s="%s"', + htmlspecialchars($attribute, $flags, $this->charset, false), + htmlspecialchars($value, $flags, $this->charset, false) + ); + } + } + + return new Response(sprintf('%s', $uri, $renderedAttributes, $content)); + } + + /** + * @param string $template + * + * @return bool + */ + private function templateExists($template) + { + if ($this->templating instanceof EngineInterface) { + try { + return $this->templating->exists($template); + } catch (\InvalidArgumentException $e) { + return false; + } + } + + $loader = $this->templating->getLoader(); + if ($loader instanceof \Twig_ExistsLoaderInterface) { + return $loader->exists($template); + } + + try { + $loader->getSource($template); + + return true; + } catch (\Twig_Error_Loader $e) { + } + + return false; + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'hinclude'; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Fragment/InlineFragmentRenderer.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Fragment/InlineFragmentRenderer.php new file mode 100644 index 0000000..a61b239 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Fragment/InlineFragmentRenderer.php @@ -0,0 +1,154 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Fragment; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\HttpKernelInterface; +use Symfony\Component\HttpKernel\Controller\ControllerReference; +use Symfony\Component\HttpKernel\KernelEvents; +use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; + +/** + * Implements the inline rendering strategy where the Request is rendered by the current HTTP kernel. + * + * @author Fabien Potencier + */ +class InlineFragmentRenderer extends RoutableFragmentRenderer +{ + private $kernel; + private $dispatcher; + + /** + * Constructor. + * + * @param HttpKernelInterface $kernel A HttpKernelInterface instance + * @param EventDispatcherInterface $dispatcher A EventDispatcherInterface instance + */ + public function __construct(HttpKernelInterface $kernel, EventDispatcherInterface $dispatcher = null) + { + $this->kernel = $kernel; + $this->dispatcher = $dispatcher; + } + + /** + * {@inheritdoc} + * + * Additional available options: + * + * * alt: an alternative URI to render in case of an error + */ + public function render($uri, Request $request, array $options = array()) + { + $reference = null; + if ($uri instanceof ControllerReference) { + $reference = $uri; + + // Remove attributes from the generated URI because if not, the Symfony + // routing system will use them to populate the Request attributes. We don't + // want that as we want to preserve objects (so we manually set Request attributes + // below instead) + $attributes = $reference->attributes; + $reference->attributes = array(); + + // The request format and locale might have been overridden by the user + foreach (array('_format', '_locale') as $key) { + if (isset($attributes[$key])) { + $reference->attributes[$key] = $attributes[$key]; + } + } + + $uri = $this->generateFragmentUri($uri, $request, false, false); + + $reference->attributes = array_merge($attributes, $reference->attributes); + } + + $subRequest = $this->createSubRequest($uri, $request); + + // override Request attributes as they can be objects (which are not supported by the generated URI) + if (null !== $reference) { + $subRequest->attributes->add($reference->attributes); + } + + $level = ob_get_level(); + try { + return $this->kernel->handle($subRequest, HttpKernelInterface::SUB_REQUEST, false); + } catch (\Exception $e) { + // we dispatch the exception event to trigger the logging + // the response that comes back is simply ignored + if (isset($options['ignore_errors']) && $options['ignore_errors'] && $this->dispatcher) { + $event = new GetResponseForExceptionEvent($this->kernel, $request, HttpKernelInterface::SUB_REQUEST, $e); + + $this->dispatcher->dispatch(KernelEvents::EXCEPTION, $event); + } + + // let's clean up the output buffers that were created by the sub-request + Response::closeOutputBuffers($level, false); + + if (isset($options['alt'])) { + $alt = $options['alt']; + unset($options['alt']); + + return $this->render($alt, $request, $options); + } + + if (!isset($options['ignore_errors']) || !$options['ignore_errors']) { + throw $e; + } + + return new Response(); + } + } + + protected function createSubRequest($uri, Request $request) + { + $cookies = $request->cookies->all(); + $server = $request->server->all(); + + // Override the arguments to emulate a sub-request. + // Sub-request object will point to localhost as client ip and real client ip + // will be included into trusted header for client ip + try { + if ($trustedHeaderName = Request::getTrustedHeaderName(Request::HEADER_CLIENT_IP)) { + $currentXForwardedFor = $request->headers->get($trustedHeaderName, ''); + + $server['HTTP_'.$trustedHeaderName] = ($currentXForwardedFor ? $currentXForwardedFor.', ' : '').$request->getClientIp(); + } + } catch (\InvalidArgumentException $e) { + // Do nothing + } + + $server['REMOTE_ADDR'] = '127.0.0.1'; + unset($server['HTTP_IF_MODIFIED_SINCE']); + unset($server['HTTP_IF_NONE_MATCH']); + + $subRequest = Request::create($uri, 'get', array(), $cookies, array(), $server); + if ($request->headers->has('Surrogate-Capability')) { + $subRequest->headers->set('Surrogate-Capability', $request->headers->get('Surrogate-Capability')); + } + + if ($session = $request->getSession()) { + $subRequest->setSession($session); + } + + return $subRequest; + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'inline'; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Fragment/RoutableFragmentRenderer.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Fragment/RoutableFragmentRenderer.php new file mode 100644 index 0000000..d7eeb89 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Fragment/RoutableFragmentRenderer.php @@ -0,0 +1,90 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Fragment; + +use Symfony\Component\HttpKernel\Controller\ControllerReference; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpKernel\EventListener\FragmentListener; + +/** + * Adds the possibility to generate a fragment URI for a given Controller. + * + * @author Fabien Potencier + */ +abstract class RoutableFragmentRenderer implements FragmentRendererInterface +{ + private $fragmentPath = '/_fragment'; + + /** + * Sets the fragment path that triggers the fragment listener. + * + * @param string $path The path + * + * @see FragmentListener + */ + public function setFragmentPath($path) + { + $this->fragmentPath = $path; + } + + /** + * Generates a fragment URI for a given controller. + * + * @param ControllerReference $reference A ControllerReference instance + * @param Request $request A Request instance + * @param bool $absolute Whether to generate an absolute URL or not + * @param bool $strict Whether to allow non-scalar attributes or not + * + * @return string A fragment URI + */ + protected function generateFragmentUri(ControllerReference $reference, Request $request, $absolute = false, $strict = true) + { + if ($strict) { + $this->checkNonScalar($reference->attributes); + } + + // We need to forward the current _format and _locale values as we don't have + // a proper routing pattern to do the job for us. + // This makes things inconsistent if you switch from rendering a controller + // to rendering a route if the route pattern does not contain the special + // _format and _locale placeholders. + if (!isset($reference->attributes['_format'])) { + $reference->attributes['_format'] = $request->getRequestFormat(); + } + if (!isset($reference->attributes['_locale'])) { + $reference->attributes['_locale'] = $request->getLocale(); + } + + $reference->attributes['_controller'] = $reference->controller; + + $reference->query['_path'] = http_build_query($reference->attributes, '', '&'); + + $path = $this->fragmentPath.'?'.http_build_query($reference->query, '', '&'); + + if ($absolute) { + return $request->getUriForPath($path); + } + + return $request->getBaseUrl().$path; + } + + private function checkNonScalar($values) + { + foreach ($values as $key => $value) { + if (is_array($value)) { + $this->checkNonScalar($value); + } elseif (!is_scalar($value) && null !== $value) { + throw new \LogicException(sprintf('Controller attributes cannot contain non-scalar/non-null values (value for key "%s" is not a scalar or null).', $key)); + } + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Fragment/SsiFragmentRenderer.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Fragment/SsiFragmentRenderer.php new file mode 100644 index 0000000..45e7122 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Fragment/SsiFragmentRenderer.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Fragment; + +/** + * Implements the SSI rendering strategy. + * + * @author Sebastian Krebs + */ +class SsiFragmentRenderer extends AbstractSurrogateFragmentRenderer +{ + /** + * {@inheritdoc} + */ + public function getName() + { + return 'ssi'; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/HttpCache/Esi.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/HttpCache/Esi.php new file mode 100644 index 0000000..4577939 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/HttpCache/Esi.php @@ -0,0 +1,295 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\HttpCache; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\HttpKernelInterface; + +/** + * Esi implements the ESI capabilities to Request and Response instances. + * + * For more information, read the following W3C notes: + * + * * ESI Language Specification 1.0 (http://www.w3.org/TR/esi-lang) + * + * * Edge Architecture Specification (http://www.w3.org/TR/edge-arch) + * + * @author Fabien Potencier + */ +class Esi implements SurrogateInterface +{ + private $contentTypes; + private $phpEscapeMap = array( + array('', '', '', ''), + ); + + /** + * Constructor. + * + * @param array $contentTypes An array of content-type that should be parsed for ESI information + * (default: text/html, text/xml, application/xhtml+xml, and application/xml) + */ + public function __construct(array $contentTypes = array('text/html', 'text/xml', 'application/xhtml+xml', 'application/xml')) + { + $this->contentTypes = $contentTypes; + } + + public function getName() + { + return 'esi'; + } + + /** + * Returns a new cache strategy instance. + * + * @return ResponseCacheStrategyInterface A ResponseCacheStrategyInterface instance + */ + public function createCacheStrategy() + { + return new ResponseCacheStrategy(); + } + + /** + * Checks that at least one surrogate has ESI/1.0 capability. + * + * @param Request $request A Request instance + * + * @return bool true if one surrogate has ESI/1.0 capability, false otherwise + */ + public function hasSurrogateCapability(Request $request) + { + if (null === $value = $request->headers->get('Surrogate-Capability')) { + return false; + } + + return false !== strpos($value, 'ESI/1.0'); + } + + /** + * Checks that at least one surrogate has ESI/1.0 capability. + * + * @param Request $request A Request instance + * + * @return bool true if one surrogate has ESI/1.0 capability, false otherwise + * + * @deprecated since version 2.6, to be removed in 3.0. Use hasSurrogateCapability() instead + */ + public function hasSurrogateEsiCapability(Request $request) + { + @trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the hasSurrogateCapability() method instead.', E_USER_DEPRECATED); + + return $this->hasSurrogateCapability($request); + } + + /** + * Adds ESI/1.0 capability to the given Request. + * + * @param Request $request A Request instance + */ + public function addSurrogateCapability(Request $request) + { + $current = $request->headers->get('Surrogate-Capability'); + $new = 'symfony2="ESI/1.0"'; + + $request->headers->set('Surrogate-Capability', $current ? $current.', '.$new : $new); + } + + /** + * Adds ESI/1.0 capability to the given Request. + * + * @param Request $request A Request instance + * + * @deprecated since version 2.6, to be removed in 3.0. Use addSurrogateCapability() instead + */ + public function addSurrogateEsiCapability(Request $request) + { + @trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the addSurrogateCapability() method instead.', E_USER_DEPRECATED); + + $this->addSurrogateCapability($request); + } + + /** + * Adds HTTP headers to specify that the Response needs to be parsed for ESI. + * + * This method only adds an ESI HTTP header if the Response has some ESI tags. + * + * @param Response $response A Response instance + */ + public function addSurrogateControl(Response $response) + { + if (false !== strpos($response->getContent(), 'headers->set('Surrogate-Control', 'content="ESI/1.0"'); + } + } + + /** + * Checks that the Response needs to be parsed for ESI tags. + * + * @param Response $response A Response instance + * + * @return bool true if the Response needs to be parsed, false otherwise + */ + public function needsParsing(Response $response) + { + if (!$control = $response->headers->get('Surrogate-Control')) { + return false; + } + + return (bool) preg_match('#content="[^"]*ESI/1.0[^"]*"#', $control); + } + + /** + * Checks that the Response needs to be parsed for ESI tags. + * + * @param Response $response A Response instance + * + * @return bool true if the Response needs to be parsed, false otherwise + * + * @deprecated since version 2.6, to be removed in 3.0. Use needsParsing() instead + */ + public function needsEsiParsing(Response $response) + { + @trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the needsParsing() method instead.', E_USER_DEPRECATED); + + return $this->needsParsing($response); + } + + /** + * Renders an ESI tag. + * + * @param string $uri A URI + * @param string $alt An alternate URI + * @param bool $ignoreErrors Whether to ignore errors or not + * @param string $comment A comment to add as an esi:include tag + * + * @return string + */ + public function renderIncludeTag($uri, $alt = null, $ignoreErrors = true, $comment = '') + { + $html = sprintf('', + $uri, + $ignoreErrors ? ' onerror="continue"' : '', + $alt ? sprintf(' alt="%s"', $alt) : '' + ); + + if (!empty($comment)) { + return sprintf("\n%s", $comment, $html); + } + + return $html; + } + + /** + * Replaces a Response ESI tags with the included resource content. + * + * @param Request $request A Request instance + * @param Response $response A Response instance + * + * @return Response + */ + public function process(Request $request, Response $response) + { + $type = $response->headers->get('Content-Type'); + if (empty($type)) { + $type = 'text/html'; + } + + $parts = explode(';', $type); + if (!in_array($parts[0], $this->contentTypes)) { + return $response; + } + + // we don't use a proper XML parser here as we can have ESI tags in a plain text response + $content = $response->getContent(); + $content = preg_replace('#.*?#s', '', $content); + $content = preg_replace('#]+>#s', '', $content); + + $chunks = preg_split('##', $content, -1, PREG_SPLIT_DELIM_CAPTURE); + $chunks[0] = str_replace($this->phpEscapeMap[0], $this->phpEscapeMap[1], $chunks[0]); + + $i = 1; + while (isset($chunks[$i])) { + $options = array(); + preg_match_all('/(src|onerror|alt)="([^"]*?)"/', $chunks[$i], $matches, PREG_SET_ORDER); + foreach ($matches as $set) { + $options[$set[1]] = $set[2]; + } + + if (!isset($options['src'])) { + throw new \RuntimeException('Unable to process an ESI tag without a "src" attribute.'); + } + + $chunks[$i] = sprintf('surrogate->handle($this, %s, %s, %s) ?>'."\n", + var_export($options['src'], true), + var_export(isset($options['alt']) ? $options['alt'] : '', true), + isset($options['onerror']) && 'continue' === $options['onerror'] ? 'true' : 'false' + ); + ++$i; + $chunks[$i] = str_replace($this->phpEscapeMap[0], $this->phpEscapeMap[1], $chunks[$i]); + ++$i; + } + $content = implode('', $chunks); + + $response->setContent($content); + $response->headers->set('X-Body-Eval', 'ESI'); + + // remove ESI/1.0 from the Surrogate-Control header + if ($response->headers->has('Surrogate-Control')) { + $value = $response->headers->get('Surrogate-Control'); + if ('content="ESI/1.0"' == $value) { + $response->headers->remove('Surrogate-Control'); + } elseif (preg_match('#,\s*content="ESI/1.0"#', $value)) { + $response->headers->set('Surrogate-Control', preg_replace('#,\s*content="ESI/1.0"#', '', $value)); + } elseif (preg_match('#content="ESI/1.0",\s*#', $value)) { + $response->headers->set('Surrogate-Control', preg_replace('#content="ESI/1.0",\s*#', '', $value)); + } + } + } + + /** + * Handles an ESI from the cache. + * + * @param HttpCache $cache An HttpCache instance + * @param string $uri The main URI + * @param string $alt An alternative URI + * @param bool $ignoreErrors Whether to ignore errors or not + * + * @return string + * + * @throws \RuntimeException + * @throws \Exception + */ + public function handle(HttpCache $cache, $uri, $alt, $ignoreErrors) + { + $subRequest = Request::create($uri, 'get', array(), $cache->getRequest()->cookies->all(), array(), $cache->getRequest()->server->all()); + + try { + $response = $cache->handle($subRequest, HttpKernelInterface::SUB_REQUEST, true); + + if (!$response->isSuccessful()) { + throw new \RuntimeException(sprintf('Error when rendering "%s" (Status code is %s).', $subRequest->getUri(), $response->getStatusCode())); + } + + return $response->getContent(); + } catch (\Exception $e) { + if ($alt) { + return $this->handle($cache, $alt, '', $ignoreErrors); + } + + if (!$ignoreErrors) { + throw $e; + } + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/HttpCache/EsiResponseCacheStrategy.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/HttpCache/EsiResponseCacheStrategy.php new file mode 100644 index 0000000..636f60e --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/HttpCache/EsiResponseCacheStrategy.php @@ -0,0 +1,33 @@ + + * + * This code is partially based on the Rack-Cache library by Ryan Tomayko, + * which is released under the MIT license. + * (based on commit 02d2b48d75bcb63cf1c0c7149c077ad256542801) + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\HttpCache; + +@trigger_error('The '.__NAMESPACE__.'\EsiResponseCacheStrategy class is deprecated since version 2.6 and will be removed in 3.0. Use the Symfony\Component\HttpKernel\HttpCache\ResponseCacheStrategy class instead.', E_USER_DEPRECATED); + +/** + * EsiResponseCacheStrategy knows how to compute the Response cache HTTP header + * based on the different ESI response cache headers. + * + * This implementation changes the master response TTL to the smallest TTL received + * or force validation if one of the ESI has validation cache strategy. + * + * @author Fabien Potencier + * + * @deprecated since version 2.6, to be removed in 3.0. Use ResponseCacheStrategy instead + */ +class EsiResponseCacheStrategy extends ResponseCacheStrategy implements EsiResponseCacheStrategyInterface +{ +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/HttpCache/EsiResponseCacheStrategyInterface.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/HttpCache/EsiResponseCacheStrategyInterface.php new file mode 100644 index 0000000..5388e99 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/HttpCache/EsiResponseCacheStrategyInterface.php @@ -0,0 +1,28 @@ + + * + * This code is partially based on the Rack-Cache library by Ryan Tomayko, + * which is released under the MIT license. + * (based on commit 02d2b48d75bcb63cf1c0c7149c077ad256542801) + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\HttpCache; + +/** + * ResponseCacheStrategyInterface implementations know how to compute the + * Response cache HTTP header based on the different response cache headers. + * + * @author Fabien Potencier + * + * @deprecated since version 2.6, to be removed in 3.0. Use ResponseCacheStrategyInterface instead. + */ +interface EsiResponseCacheStrategyInterface extends ResponseCacheStrategyInterface +{ +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/HttpCache/HttpCache.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/HttpCache/HttpCache.php new file mode 100644 index 0000000..253deb1 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/HttpCache/HttpCache.php @@ -0,0 +1,713 @@ + + * + * This code is partially based on the Rack-Cache library by Ryan Tomayko, + * which is released under the MIT license. + * (based on commit 02d2b48d75bcb63cf1c0c7149c077ad256542801) + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\HttpCache; + +use Symfony\Component\HttpKernel\HttpKernelInterface; +use Symfony\Component\HttpKernel\TerminableInterface; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; + +/** + * Cache provides HTTP caching. + * + * @author Fabien Potencier + */ +class HttpCache implements HttpKernelInterface, TerminableInterface +{ + private $kernel; + private $store; + private $request; + private $surrogate; + private $surrogateCacheStrategy; + private $options = array(); + private $traces = array(); + + /** + * Constructor. + * + * The available options are: + * + * * debug: If true, the traces are added as a HTTP header to ease debugging + * + * * default_ttl The number of seconds that a cache entry should be considered + * fresh when no explicit freshness information is provided in + * a response. Explicit Cache-Control or Expires headers + * override this value. (default: 0) + * + * * private_headers Set of request headers that trigger "private" cache-control behavior + * on responses that don't explicitly state whether the response is + * public or private via a Cache-Control directive. (default: Authorization and Cookie) + * + * * allow_reload Specifies whether the client can force a cache reload by including a + * Cache-Control "no-cache" directive in the request. Set it to ``true`` + * for compliance with RFC 2616. (default: false) + * + * * allow_revalidate Specifies whether the client can force a cache revalidate by including + * a Cache-Control "max-age=0" directive in the request. Set it to ``true`` + * for compliance with RFC 2616. (default: false) + * + * * stale_while_revalidate Specifies the default number of seconds (the granularity is the second as the + * Response TTL precision is a second) during which the cache can immediately return + * a stale response while it revalidates it in the background (default: 2). + * This setting is overridden by the stale-while-revalidate HTTP Cache-Control + * extension (see RFC 5861). + * + * * stale_if_error Specifies the default number of seconds (the granularity is the second) during which + * the cache can serve a stale response when an error is encountered (default: 60). + * This setting is overridden by the stale-if-error HTTP Cache-Control extension + * (see RFC 5861). + * + * @param HttpKernelInterface $kernel An HttpKernelInterface instance + * @param StoreInterface $store A Store instance + * @param SurrogateInterface $surrogate A SurrogateInterface instance + * @param array $options An array of options + */ + public function __construct(HttpKernelInterface $kernel, StoreInterface $store, SurrogateInterface $surrogate = null, array $options = array()) + { + $this->store = $store; + $this->kernel = $kernel; + $this->surrogate = $surrogate; + + // needed in case there is a fatal error because the backend is too slow to respond + register_shutdown_function(array($this->store, 'cleanup')); + + $this->options = array_merge(array( + 'debug' => false, + 'default_ttl' => 0, + 'private_headers' => array('Authorization', 'Cookie'), + 'allow_reload' => false, + 'allow_revalidate' => false, + 'stale_while_revalidate' => 2, + 'stale_if_error' => 60, + ), $options); + } + + /** + * Gets the current store. + * + * @return StoreInterface $store A StoreInterface instance + */ + public function getStore() + { + return $this->store; + } + + /** + * Returns an array of events that took place during processing of the last request. + * + * @return array An array of events + */ + public function getTraces() + { + return $this->traces; + } + + /** + * Returns a log message for the events of the last request processing. + * + * @return string A log message + */ + public function getLog() + { + $log = array(); + foreach ($this->traces as $request => $traces) { + $log[] = sprintf('%s: %s', $request, implode(', ', $traces)); + } + + return implode('; ', $log); + } + + /** + * Gets the Request instance associated with the master request. + * + * @return Request A Request instance + */ + public function getRequest() + { + return $this->request; + } + + /** + * Gets the Kernel instance. + * + * @return HttpKernelInterface An HttpKernelInterface instance + */ + public function getKernel() + { + return $this->kernel; + } + + /** + * Gets the Surrogate instance. + * + * @return SurrogateInterface A Surrogate instance + * + * @throws \LogicException + */ + public function getSurrogate() + { + if (!$this->surrogate instanceof Esi) { + throw new \LogicException('This instance of HttpCache was not set up to use ESI as surrogate handler. You must overwrite and use createSurrogate'); + } + + return $this->surrogate; + } + + /** + * Gets the Esi instance. + * + * @return Esi An Esi instance + * + * @throws \LogicException + * + * @deprecated since version 2.6, to be removed in 3.0. Use getSurrogate() instead + */ + public function getEsi() + { + @trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the getSurrogate() method instead.', E_USER_DEPRECATED); + + return $this->getSurrogate(); + } + + /** + * {@inheritdoc} + */ + public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true) + { + // FIXME: catch exceptions and implement a 500 error page here? -> in Varnish, there is a built-in error page mechanism + if (HttpKernelInterface::MASTER_REQUEST === $type) { + $this->traces = array(); + $this->request = $request; + if (null !== $this->surrogate) { + $this->surrogateCacheStrategy = $this->surrogate->createCacheStrategy(); + } + } + + $path = $request->getPathInfo(); + if ($qs = $request->getQueryString()) { + $path .= '?'.$qs; + } + $this->traces[$request->getMethod().' '.$path] = array(); + + if (!$request->isMethodSafe()) { + $response = $this->invalidate($request, $catch); + } elseif ($request->headers->has('expect')) { + $response = $this->pass($request, $catch); + } else { + $response = $this->lookup($request, $catch); + } + + $this->restoreResponseBody($request, $response); + + $response->setDate(\DateTime::createFromFormat('U', time(), new \DateTimeZone('UTC'))); + + if (HttpKernelInterface::MASTER_REQUEST === $type && $this->options['debug']) { + $response->headers->set('X-Symfony-Cache', $this->getLog()); + } + + if (null !== $this->surrogate) { + if (HttpKernelInterface::MASTER_REQUEST === $type) { + $this->surrogateCacheStrategy->update($response); + } else { + $this->surrogateCacheStrategy->add($response); + } + } + + $response->prepare($request); + + $response->isNotModified($request); + + return $response; + } + + /** + * {@inheritdoc} + */ + public function terminate(Request $request, Response $response) + { + if ($this->getKernel() instanceof TerminableInterface) { + $this->getKernel()->terminate($request, $response); + } + } + + /** + * Forwards the Request to the backend without storing the Response in the cache. + * + * @param Request $request A Request instance + * @param bool $catch Whether to process exceptions + * + * @return Response A Response instance + */ + protected function pass(Request $request, $catch = false) + { + $this->record($request, 'pass'); + + return $this->forward($request, $catch); + } + + /** + * Invalidates non-safe methods (like POST, PUT, and DELETE). + * + * @param Request $request A Request instance + * @param bool $catch Whether to process exceptions + * + * @return Response A Response instance + * + * @throws \Exception + * + * @see RFC2616 13.10 + */ + protected function invalidate(Request $request, $catch = false) + { + $response = $this->pass($request, $catch); + + // invalidate only when the response is successful + if ($response->isSuccessful() || $response->isRedirect()) { + try { + $this->store->invalidate($request); + + // As per the RFC, invalidate Location and Content-Location URLs if present + foreach (array('Location', 'Content-Location') as $header) { + if ($uri = $response->headers->get($header)) { + $subRequest = Request::create($uri, 'get', array(), array(), array(), $request->server->all()); + + $this->store->invalidate($subRequest); + } + } + + $this->record($request, 'invalidate'); + } catch (\Exception $e) { + $this->record($request, 'invalidate-failed'); + + if ($this->options['debug']) { + throw $e; + } + } + } + + return $response; + } + + /** + * Lookups a Response from the cache for the given Request. + * + * When a matching cache entry is found and is fresh, it uses it as the + * response without forwarding any request to the backend. When a matching + * cache entry is found but is stale, it attempts to "validate" the entry with + * the backend using conditional GET. When no matching cache entry is found, + * it triggers "miss" processing. + * + * @param Request $request A Request instance + * @param bool $catch whether to process exceptions + * + * @return Response A Response instance + * + * @throws \Exception + */ + protected function lookup(Request $request, $catch = false) + { + // if allow_reload and no-cache Cache-Control, allow a cache reload + if ($this->options['allow_reload'] && $request->isNoCache()) { + $this->record($request, 'reload'); + + return $this->fetch($request, $catch); + } + + try { + $entry = $this->store->lookup($request); + } catch (\Exception $e) { + $this->record($request, 'lookup-failed'); + + if ($this->options['debug']) { + throw $e; + } + + return $this->pass($request, $catch); + } + + if (null === $entry) { + $this->record($request, 'miss'); + + return $this->fetch($request, $catch); + } + + if (!$this->isFreshEnough($request, $entry)) { + $this->record($request, 'stale'); + + return $this->validate($request, $entry, $catch); + } + + $this->record($request, 'fresh'); + + $entry->headers->set('Age', $entry->getAge()); + + return $entry; + } + + /** + * Validates that a cache entry is fresh. + * + * The original request is used as a template for a conditional + * GET request with the backend. + * + * @param Request $request A Request instance + * @param Response $entry A Response instance to validate + * @param bool $catch Whether to process exceptions + * + * @return Response A Response instance + */ + protected function validate(Request $request, Response $entry, $catch = false) + { + $subRequest = clone $request; + + // send no head requests because we want content + if ('HEAD' === $request->getMethod()) { + $subRequest->setMethod('GET'); + } + + // add our cached last-modified validator + $subRequest->headers->set('if_modified_since', $entry->headers->get('Last-Modified')); + + // Add our cached etag validator to the environment. + // We keep the etags from the client to handle the case when the client + // has a different private valid entry which is not cached here. + $cachedEtags = $entry->getEtag() ? array($entry->getEtag()) : array(); + $requestEtags = $request->getETags(); + if ($etags = array_unique(array_merge($cachedEtags, $requestEtags))) { + $subRequest->headers->set('if_none_match', implode(', ', $etags)); + } + + $response = $this->forward($subRequest, $catch, $entry); + + if (304 == $response->getStatusCode()) { + $this->record($request, 'valid'); + + // return the response and not the cache entry if the response is valid but not cached + $etag = $response->getEtag(); + if ($etag && in_array($etag, $requestEtags) && !in_array($etag, $cachedEtags)) { + return $response; + } + + $entry = clone $entry; + $entry->headers->remove('Date'); + + foreach (array('Date', 'Expires', 'Cache-Control', 'ETag', 'Last-Modified') as $name) { + if ($response->headers->has($name)) { + $entry->headers->set($name, $response->headers->get($name)); + } + } + + $response = $entry; + } else { + $this->record($request, 'invalid'); + } + + if ($response->isCacheable()) { + $this->store($request, $response); + } + + return $response; + } + + /** + * Forwards the Request to the backend and determines whether the response should be stored. + * + * This methods is triggered when the cache missed or a reload is required. + * + * @param Request $request A Request instance + * @param bool $catch whether to process exceptions + * + * @return Response A Response instance + */ + protected function fetch(Request $request, $catch = false) + { + $subRequest = clone $request; + + // send no head requests because we want content + if ('HEAD' === $request->getMethod()) { + $subRequest->setMethod('GET'); + } + + // avoid that the backend sends no content + $subRequest->headers->remove('if_modified_since'); + $subRequest->headers->remove('if_none_match'); + + $response = $this->forward($subRequest, $catch); + + if ($response->isCacheable()) { + $this->store($request, $response); + } + + return $response; + } + + /** + * Forwards the Request to the backend and returns the Response. + * + * @param Request $request A Request instance + * @param bool $catch Whether to catch exceptions or not + * @param Response $entry A Response instance (the stale entry if present, null otherwise) + * + * @return Response A Response instance + */ + protected function forward(Request $request, $catch = false, Response $entry = null) + { + if ($this->surrogate) { + $this->surrogate->addSurrogateCapability($request); + } + + // modify the X-Forwarded-For header if needed + $forwardedFor = $request->headers->get('X-Forwarded-For'); + if ($forwardedFor) { + $request->headers->set('X-Forwarded-For', $forwardedFor.', '.$request->server->get('REMOTE_ADDR')); + } else { + $request->headers->set('X-Forwarded-For', $request->server->get('REMOTE_ADDR')); + } + + // fix the client IP address by setting it to 127.0.0.1 as HttpCache + // is always called from the same process as the backend. + $request->server->set('REMOTE_ADDR', '127.0.0.1'); + + // make sure HttpCache is a trusted proxy + if (!in_array('127.0.0.1', $trustedProxies = Request::getTrustedProxies())) { + $trustedProxies[] = '127.0.0.1'; + Request::setTrustedProxies($trustedProxies); + } + + // always a "master" request (as the real master request can be in cache) + $response = $this->kernel->handle($request, HttpKernelInterface::MASTER_REQUEST, $catch); + // FIXME: we probably need to also catch exceptions if raw === true + + // we don't implement the stale-if-error on Requests, which is nonetheless part of the RFC + if (null !== $entry && in_array($response->getStatusCode(), array(500, 502, 503, 504))) { + if (null === $age = $entry->headers->getCacheControlDirective('stale-if-error')) { + $age = $this->options['stale_if_error']; + } + + if (abs($entry->getTtl()) < $age) { + $this->record($request, 'stale-if-error'); + + return $entry; + } + } + + $this->processResponseBody($request, $response); + + if ($this->isPrivateRequest($request) && !$response->headers->hasCacheControlDirective('public')) { + $response->setPrivate(); + } elseif ($this->options['default_ttl'] > 0 && null === $response->getTtl() && !$response->headers->getCacheControlDirective('must-revalidate')) { + $response->setTtl($this->options['default_ttl']); + } + + return $response; + } + + /** + * Checks whether the cache entry is "fresh enough" to satisfy the Request. + * + * @param Request $request A Request instance + * @param Response $entry A Response instance + * + * @return bool true if the cache entry if fresh enough, false otherwise + */ + protected function isFreshEnough(Request $request, Response $entry) + { + if (!$entry->isFresh()) { + return $this->lock($request, $entry); + } + + if ($this->options['allow_revalidate'] && null !== $maxAge = $request->headers->getCacheControlDirective('max-age')) { + return $maxAge > 0 && $maxAge >= $entry->getAge(); + } + + return true; + } + + /** + * Locks a Request during the call to the backend. + * + * @param Request $request A Request instance + * @param Response $entry A Response instance + * + * @return bool true if the cache entry can be returned even if it is staled, false otherwise + */ + protected function lock(Request $request, Response $entry) + { + // try to acquire a lock to call the backend + $lock = $this->store->lock($request); + + // there is already another process calling the backend + if (true !== $lock) { + // check if we can serve the stale entry + if (null === $age = $entry->headers->getCacheControlDirective('stale-while-revalidate')) { + $age = $this->options['stale_while_revalidate']; + } + + if (abs($entry->getTtl()) < $age) { + $this->record($request, 'stale-while-revalidate'); + + // server the stale response while there is a revalidation + return true; + } + + // wait for the lock to be released + $wait = 0; + while ($this->store->isLocked($request) && $wait < 5000000) { + usleep(50000); + $wait += 50000; + } + + if ($wait < 5000000) { + // replace the current entry with the fresh one + $new = $this->lookup($request); + $entry->headers = $new->headers; + $entry->setContent($new->getContent()); + $entry->setStatusCode($new->getStatusCode()); + $entry->setProtocolVersion($new->getProtocolVersion()); + foreach ($new->headers->getCookies() as $cookie) { + $entry->headers->setCookie($cookie); + } + } else { + // backend is slow as hell, send a 503 response (to avoid the dog pile effect) + $entry->setStatusCode(503); + $entry->setContent('503 Service Unavailable'); + $entry->headers->set('Retry-After', 10); + } + + return true; + } + + // we have the lock, call the backend + return false; + } + + /** + * Writes the Response to the cache. + * + * @param Request $request A Request instance + * @param Response $response A Response instance + * + * @throws \Exception + */ + protected function store(Request $request, Response $response) + { + if (!$response->headers->has('Date')) { + $response->setDate(\DateTime::createFromFormat('U', time())); + } + try { + $this->store->write($request, $response); + + $this->record($request, 'store'); + + $response->headers->set('Age', $response->getAge()); + } catch (\Exception $e) { + $this->record($request, 'store-failed'); + + if ($this->options['debug']) { + throw $e; + } + } + + // now that the response is cached, release the lock + $this->store->unlock($request); + } + + /** + * Restores the Response body. + * + * @param Request $request A Request instance + * @param Response $response A Response instance + */ + private function restoreResponseBody(Request $request, Response $response) + { + if ($request->isMethod('HEAD') || 304 === $response->getStatusCode()) { + $response->setContent(null); + $response->headers->remove('X-Body-Eval'); + $response->headers->remove('X-Body-File'); + + return; + } + + if ($response->headers->has('X-Body-Eval')) { + ob_start(); + + if ($response->headers->has('X-Body-File')) { + include $response->headers->get('X-Body-File'); + } else { + eval('; ?>'.$response->getContent().'setContent(ob_get_clean()); + $response->headers->remove('X-Body-Eval'); + if (!$response->headers->has('Transfer-Encoding')) { + $response->headers->set('Content-Length', strlen($response->getContent())); + } + } elseif ($response->headers->has('X-Body-File')) { + $response->setContent(file_get_contents($response->headers->get('X-Body-File'))); + } else { + return; + } + + $response->headers->remove('X-Body-File'); + } + + protected function processResponseBody(Request $request, Response $response) + { + if (null !== $this->surrogate && $this->surrogate->needsParsing($response)) { + $this->surrogate->process($request, $response); + } + } + + /** + * Checks if the Request includes authorization or other sensitive information + * that should cause the Response to be considered private by default. + * + * @param Request $request A Request instance + * + * @return bool true if the Request is private, false otherwise + */ + private function isPrivateRequest(Request $request) + { + foreach ($this->options['private_headers'] as $key) { + $key = strtolower(str_replace('HTTP_', '', $key)); + + if ('cookie' === $key) { + if (count($request->cookies->all())) { + return true; + } + } elseif ($request->headers->has($key)) { + return true; + } + } + + return false; + } + + /** + * Records that an event took place. + * + * @param Request $request A Request instance + * @param string $event The event name + */ + private function record(Request $request, $event) + { + $path = $request->getPathInfo(); + if ($qs = $request->getQueryString()) { + $path .= '?'.$qs; + } + $this->traces[$request->getMethod().' '.$path][] = $event; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/HttpCache/ResponseCacheStrategy.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/HttpCache/ResponseCacheStrategy.php new file mode 100644 index 0000000..39a99e6 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/HttpCache/ResponseCacheStrategy.php @@ -0,0 +1,93 @@ + + * + * This code is partially based on the Rack-Cache library by Ryan Tomayko, + * which is released under the MIT license. + * (based on commit 02d2b48d75bcb63cf1c0c7149c077ad256542801) + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\HttpCache; + +use Symfony\Component\HttpFoundation\Response; + +/** + * ResponseCacheStrategy knows how to compute the Response cache HTTP header + * based on the different response cache headers. + * + * This implementation changes the master response TTL to the smallest TTL received + * or force validation if one of the surrogates has validation cache strategy. + * + * @author Fabien Potencier + */ +class ResponseCacheStrategy implements ResponseCacheStrategyInterface +{ + private $cacheable = true; + private $embeddedResponses = 0; + private $ttls = array(); + private $maxAges = array(); + private $isNotCacheableResponseEmbedded = false; + + /** + * {@inheritdoc} + */ + public function add(Response $response) + { + if ($response->isValidateable()) { + $this->cacheable = false; + } else { + $maxAge = $response->getMaxAge(); + $this->ttls[] = $response->getTtl(); + $this->maxAges[] = $maxAge; + + if (null === $maxAge) { + $this->isNotCacheableResponseEmbedded = true; + } + } + + ++$this->embeddedResponses; + } + + /** + * {@inheritdoc} + */ + public function update(Response $response) + { + // if we have no embedded Response, do nothing + if (0 === $this->embeddedResponses) { + return; + } + + // Remove validation related headers in order to avoid browsers using + // their own cache, because some of the response content comes from + // at least one embedded response (which likely has a different caching strategy). + if ($response->isValidateable()) { + $response->setEtag(null); + $response->setLastModified(null); + $this->cacheable = false; + } + + if (!$this->cacheable) { + $response->headers->set('Cache-Control', 'no-cache, must-revalidate'); + + return; + } + + $this->ttls[] = $response->getTtl(); + $this->maxAges[] = $response->getMaxAge(); + + if ($this->isNotCacheableResponseEmbedded) { + $response->headers->removeCacheControlDirective('s-maxage'); + } elseif (null !== $maxAge = min($this->maxAges)) { + $response->setSharedMaxAge($maxAge); + $response->headers->set('Age', $maxAge - min($this->ttls)); + } + $response->setMaxAge(0); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/HttpCache/ResponseCacheStrategyInterface.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/HttpCache/ResponseCacheStrategyInterface.php new file mode 100644 index 0000000..d70c2e0 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/HttpCache/ResponseCacheStrategyInterface.php @@ -0,0 +1,41 @@ + + * + * This code is partially based on the Rack-Cache library by Ryan Tomayko, + * which is released under the MIT license. + * (based on commit 02d2b48d75bcb63cf1c0c7149c077ad256542801) + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\HttpCache; + +use Symfony\Component\HttpFoundation\Response; + +/** + * ResponseCacheStrategyInterface implementations know how to compute the + * Response cache HTTP header based on the different response cache headers. + * + * @author Fabien Potencier + */ +interface ResponseCacheStrategyInterface +{ + /** + * Adds a Response. + * + * @param Response $response + */ + public function add(Response $response); + + /** + * Updates the Response HTTP headers based on the embedded Responses. + * + * @param Response $response + */ + public function update(Response $response); +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/HttpCache/Ssi.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/HttpCache/Ssi.php new file mode 100644 index 0000000..5f7ee10 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/HttpCache/Ssi.php @@ -0,0 +1,194 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\HttpCache; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\HttpKernelInterface; + +/** + * Ssi implements the SSI capabilities to Request and Response instances. + * + * @author Sebastian Krebs + */ +class Ssi implements SurrogateInterface +{ + private $contentTypes; + private $phpEscapeMap = array( + array('', '', '', ''), + ); + + /** + * Constructor. + * + * @param array $contentTypes An array of content-type that should be parsed for SSI information + * (default: text/html, text/xml, application/xhtml+xml, and application/xml) + */ + public function __construct(array $contentTypes = array('text/html', 'text/xml', 'application/xhtml+xml', 'application/xml')) + { + $this->contentTypes = $contentTypes; + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'ssi'; + } + + /** + * {@inheritdoc} + */ + public function createCacheStrategy() + { + return new ResponseCacheStrategy(); + } + + /** + * {@inheritdoc} + */ + public function hasSurrogateCapability(Request $request) + { + if (null === $value = $request->headers->get('Surrogate-Capability')) { + return false; + } + + return false !== strpos($value, 'SSI/1.0'); + } + + /** + * {@inheritdoc} + */ + public function addSurrogateCapability(Request $request) + { + $current = $request->headers->get('Surrogate-Capability'); + $new = 'symfony2="SSI/1.0"'; + + $request->headers->set('Surrogate-Capability', $current ? $current.', '.$new : $new); + } + + /** + * {@inheritdoc} + */ + public function addSurrogateControl(Response $response) + { + if (false !== strpos($response->getContent(), '', $uri); + } + + /** + * {@inheritdoc} + */ + public function process(Request $request, Response $response) + { + $type = $response->headers->get('Content-Type'); + if (empty($type)) { + $type = 'text/html'; + } + + $parts = explode(';', $type); + if (!in_array($parts[0], $this->contentTypes)) { + return $response; + } + + // we don't use a proper XML parser here as we can have SSI tags in a plain text response + $content = $response->getContent(); + + $chunks = preg_split('##', $content, -1, PREG_SPLIT_DELIM_CAPTURE); + $chunks[0] = str_replace($this->phpEscapeMap[0], $this->phpEscapeMap[1], $chunks[0]); + + $i = 1; + while (isset($chunks[$i])) { + $options = array(); + preg_match_all('/(virtual)="([^"]*?)"/', $chunks[$i], $matches, PREG_SET_ORDER); + foreach ($matches as $set) { + $options[$set[1]] = $set[2]; + } + + if (!isset($options['virtual'])) { + throw new \RuntimeException('Unable to process an SSI tag without a "virtual" attribute.'); + } + + $chunks[$i] = sprintf('surrogate->handle($this, %s, \'\', false) ?>'."\n", + var_export($options['virtual'], true) + ); + ++$i; + $chunks[$i] = str_replace($this->phpEscapeMap[0], $this->phpEscapeMap[1], $chunks[$i]); + ++$i; + } + $content = implode('', $chunks); + + $response->setContent($content); + $response->headers->set('X-Body-Eval', 'SSI'); + + // remove SSI/1.0 from the Surrogate-Control header + if ($response->headers->has('Surrogate-Control')) { + $value = $response->headers->get('Surrogate-Control'); + if ('content="SSI/1.0"' == $value) { + $response->headers->remove('Surrogate-Control'); + } elseif (preg_match('#,\s*content="SSI/1.0"#', $value)) { + $response->headers->set('Surrogate-Control', preg_replace('#,\s*content="SSI/1.0"#', '', $value)); + } elseif (preg_match('#content="SSI/1.0",\s*#', $value)) { + $response->headers->set('Surrogate-Control', preg_replace('#content="SSI/1.0",\s*#', '', $value)); + } + } + } + + /** + * {@inheritdoc} + */ + public function handle(HttpCache $cache, $uri, $alt, $ignoreErrors) + { + $subRequest = Request::create($uri, 'get', array(), $cache->getRequest()->cookies->all(), array(), $cache->getRequest()->server->all()); + + try { + $response = $cache->handle($subRequest, HttpKernelInterface::SUB_REQUEST, true); + + if (!$response->isSuccessful()) { + throw new \RuntimeException(sprintf('Error when rendering "%s" (Status code is %s).', $subRequest->getUri(), $response->getStatusCode())); + } + + return $response->getContent(); + } catch (\Exception $e) { + if ($alt) { + return $this->handle($cache, $alt, '', $ignoreErrors); + } + + if (!$ignoreErrors) { + throw $e; + } + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/HttpCache/Store.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/HttpCache/Store.php new file mode 100644 index 0000000..b57d4a7 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/HttpCache/Store.php @@ -0,0 +1,489 @@ + + * + * This code is partially based on the Rack-Cache library by Ryan Tomayko, + * which is released under the MIT license. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\HttpCache; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; + +/** + * Store implements all the logic for storing cache metadata (Request and Response headers). + * + * @author Fabien Potencier + */ +class Store implements StoreInterface +{ + protected $root; + private $keyCache; + private $locks; + + /** + * Constructor. + * + * @param string $root The path to the cache directory + * + * @throws \RuntimeException + */ + public function __construct($root) + { + $this->root = $root; + if (!file_exists($this->root) && !@mkdir($this->root, 0777, true) && !is_dir($this->root)) { + throw new \RuntimeException(sprintf('Unable to create the store directory (%s).', $this->root)); + } + $this->keyCache = new \SplObjectStorage(); + $this->locks = array(); + } + + /** + * Cleanups storage. + */ + public function cleanup() + { + // unlock everything + foreach ($this->locks as $lock) { + flock($lock, LOCK_UN); + fclose($lock); + } + + $this->locks = array(); + } + + /** + * Tries to lock the cache for a given Request, without blocking. + * + * @param Request $request A Request instance + * + * @return bool|string true if the lock is acquired, the path to the current lock otherwise + */ + public function lock(Request $request) + { + $key = $this->getCacheKey($request); + + if (!isset($this->locks[$key])) { + $path = $this->getPath($key); + if (!file_exists(dirname($path)) && false === @mkdir(dirname($path), 0777, true) && !is_dir(dirname($path))) { + return $path; + } + $h = fopen($path, 'cb'); + if (!flock($h, LOCK_EX | LOCK_NB)) { + fclose($h); + + return $path; + } + + $this->locks[$key] = $h; + } + + return true; + } + + /** + * Releases the lock for the given Request. + * + * @param Request $request A Request instance + * + * @return bool False if the lock file does not exist or cannot be unlocked, true otherwise + */ + public function unlock(Request $request) + { + $key = $this->getCacheKey($request); + + if (isset($this->locks[$key])) { + flock($this->locks[$key], LOCK_UN); + fclose($this->locks[$key]); + unset($this->locks[$key]); + + return true; + } + + return false; + } + + public function isLocked(Request $request) + { + $key = $this->getCacheKey($request); + + if (isset($this->locks[$key])) { + return true; // shortcut if lock held by this process + } + + if (!file_exists($path = $this->getPath($key))) { + return false; + } + + $h = fopen($path, 'rb'); + flock($h, LOCK_EX | LOCK_NB, $wouldBlock); + flock($h, LOCK_UN); // release the lock we just acquired + fclose($h); + + return (bool) $wouldBlock; + } + + /** + * Locates a cached Response for the Request provided. + * + * @param Request $request A Request instance + * + * @return Response|null A Response instance, or null if no cache entry was found + */ + public function lookup(Request $request) + { + $key = $this->getCacheKey($request); + + if (!$entries = $this->getMetadata($key)) { + return; + } + + // find a cached entry that matches the request. + $match = null; + foreach ($entries as $entry) { + if ($this->requestsMatch(isset($entry[1]['vary'][0]) ? implode(', ', $entry[1]['vary']) : '', $request->headers->all(), $entry[0])) { + $match = $entry; + + break; + } + } + + if (null === $match) { + return; + } + + list($req, $headers) = $match; + if (file_exists($body = $this->getPath($headers['x-content-digest'][0]))) { + return $this->restoreResponse($headers, $body); + } + + // TODO the metaStore referenced an entity that doesn't exist in + // the entityStore. We definitely want to return nil but we should + // also purge the entry from the meta-store when this is detected. + } + + /** + * Writes a cache entry to the store for the given Request and Response. + * + * Existing entries are read and any that match the response are removed. This + * method calls write with the new list of cache entries. + * + * @param Request $request A Request instance + * @param Response $response A Response instance + * + * @return string The key under which the response is stored + * + * @throws \RuntimeException + */ + public function write(Request $request, Response $response) + { + $key = $this->getCacheKey($request); + $storedEnv = $this->persistRequest($request); + + // write the response body to the entity store if this is the original response + if (!$response->headers->has('X-Content-Digest')) { + $digest = $this->generateContentDigest($response); + + if (false === $this->save($digest, $response->getContent())) { + throw new \RuntimeException('Unable to store the entity.'); + } + + $response->headers->set('X-Content-Digest', $digest); + + if (!$response->headers->has('Transfer-Encoding')) { + $response->headers->set('Content-Length', strlen($response->getContent())); + } + } + + // read existing cache entries, remove non-varying, and add this one to the list + $entries = array(); + $vary = $response->headers->get('vary'); + foreach ($this->getMetadata($key) as $entry) { + if (!isset($entry[1]['vary'][0])) { + $entry[1]['vary'] = array(''); + } + + if ($vary != $entry[1]['vary'][0] || !$this->requestsMatch($vary, $entry[0], $storedEnv)) { + $entries[] = $entry; + } + } + + $headers = $this->persistResponse($response); + unset($headers['age']); + + array_unshift($entries, array($storedEnv, $headers)); + + if (false === $this->save($key, serialize($entries))) { + throw new \RuntimeException('Unable to store the metadata.'); + } + + return $key; + } + + /** + * Returns content digest for $response. + * + * @param Response $response + * + * @return string + */ + protected function generateContentDigest(Response $response) + { + return 'en'.hash('sha256', $response->getContent()); + } + + /** + * Invalidates all cache entries that match the request. + * + * @param Request $request A Request instance + * + * @throws \RuntimeException + */ + public function invalidate(Request $request) + { + $modified = false; + $key = $this->getCacheKey($request); + + $entries = array(); + foreach ($this->getMetadata($key) as $entry) { + $response = $this->restoreResponse($entry[1]); + if ($response->isFresh()) { + $response->expire(); + $modified = true; + $entries[] = array($entry[0], $this->persistResponse($response)); + } else { + $entries[] = $entry; + } + } + + if ($modified && false === $this->save($key, serialize($entries))) { + throw new \RuntimeException('Unable to store the metadata.'); + } + } + + /** + * Determines whether two Request HTTP header sets are non-varying based on + * the vary response header value provided. + * + * @param string $vary A Response vary header + * @param array $env1 A Request HTTP header array + * @param array $env2 A Request HTTP header array + * + * @return bool true if the two environments match, false otherwise + */ + private function requestsMatch($vary, $env1, $env2) + { + if (empty($vary)) { + return true; + } + + foreach (preg_split('/[\s,]+/', $vary) as $header) { + $key = str_replace('_', '-', strtolower($header)); + $v1 = isset($env1[$key]) ? $env1[$key] : null; + $v2 = isset($env2[$key]) ? $env2[$key] : null; + if ($v1 !== $v2) { + return false; + } + } + + return true; + } + + /** + * Gets all data associated with the given key. + * + * Use this method only if you know what you are doing. + * + * @param string $key The store key + * + * @return array An array of data associated with the key + */ + private function getMetadata($key) + { + if (!$entries = $this->load($key)) { + return array(); + } + + return unserialize($entries); + } + + /** + * Purges data for the given URL. + * + * @param string $url A URL + * + * @return bool true if the URL exists and has been purged, false otherwise + */ + public function purge($url) + { + $key = $this->getCacheKey(Request::create($url)); + + if (isset($this->locks[$key])) { + flock($this->locks[$key], LOCK_UN); + fclose($this->locks[$key]); + unset($this->locks[$key]); + } + + if (file_exists($path = $this->getPath($key))) { + unlink($path); + + return true; + } + + return false; + } + + /** + * Loads data for the given key. + * + * @param string $key The store key + * + * @return string The data associated with the key + */ + private function load($key) + { + $path = $this->getPath($key); + + return file_exists($path) ? file_get_contents($path) : false; + } + + /** + * Save data for the given key. + * + * @param string $key The store key + * @param string $data The data to store + * + * @return bool + */ + private function save($key, $data) + { + $path = $this->getPath($key); + + if (isset($this->locks[$key])) { + $fp = $this->locks[$key]; + @ftruncate($fp, 0); + @fseek($fp, 0); + $len = @fwrite($fp, $data); + if (strlen($data) !== $len) { + @ftruncate($fp, 0); + + return false; + } + } else { + if (!file_exists(dirname($path)) && false === @mkdir(dirname($path), 0777, true) && !is_dir(dirname($path))) { + return false; + } + + $tmpFile = tempnam(dirname($path), basename($path)); + if (false === $fp = @fopen($tmpFile, 'wb')) { + return false; + } + @fwrite($fp, $data); + @fclose($fp); + + if ($data != file_get_contents($tmpFile)) { + return false; + } + + if (false === @rename($tmpFile, $path)) { + return false; + } + } + + @chmod($path, 0666 & ~umask()); + } + + public function getPath($key) + { + return $this->root.DIRECTORY_SEPARATOR.substr($key, 0, 2).DIRECTORY_SEPARATOR.substr($key, 2, 2).DIRECTORY_SEPARATOR.substr($key, 4, 2).DIRECTORY_SEPARATOR.substr($key, 6); + } + + /** + * Generates a cache key for the given Request. + * + * This method should return a key that must only depend on a + * normalized version of the request URI. + * + * If the same URI can have more than one representation, based on some + * headers, use a Vary header to indicate them, and each representation will + * be stored independently under the same cache key. + * + * @param Request $request A Request instance + * + * @return string A key for the given Request + */ + protected function generateCacheKey(Request $request) + { + return 'md'.hash('sha256', $request->getUri()); + } + + /** + * Returns a cache key for the given Request. + * + * @param Request $request A Request instance + * + * @return string A key for the given Request + */ + private function getCacheKey(Request $request) + { + if (isset($this->keyCache[$request])) { + return $this->keyCache[$request]; + } + + return $this->keyCache[$request] = $this->generateCacheKey($request); + } + + /** + * Persists the Request HTTP headers. + * + * @param Request $request A Request instance + * + * @return array An array of HTTP headers + */ + private function persistRequest(Request $request) + { + return $request->headers->all(); + } + + /** + * Persists the Response HTTP headers. + * + * @param Response $response A Response instance + * + * @return array An array of HTTP headers + */ + private function persistResponse(Response $response) + { + $headers = $response->headers->all(); + $headers['X-Status'] = array($response->getStatusCode()); + + return $headers; + } + + /** + * Restores a Response from the HTTP headers and body. + * + * @param array $headers An array of HTTP headers for the Response + * @param string $body The Response body + * + * @return Response + */ + private function restoreResponse($headers, $body = null) + { + $status = $headers['X-Status'][0]; + unset($headers['X-Status']); + + if (null !== $body) { + $headers['X-Body-File'] = array($body); + } + + return new Response($body, $status, $headers); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/HttpCache/StoreInterface.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/HttpCache/StoreInterface.php new file mode 100644 index 0000000..ddc0c04 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/HttpCache/StoreInterface.php @@ -0,0 +1,96 @@ + + * + * This code is partially based on the Rack-Cache library by Ryan Tomayko, + * which is released under the MIT license. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\HttpCache; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; + +/** + * Interface implemented by HTTP cache stores. + * + * @author Fabien Potencier + */ +interface StoreInterface +{ + /** + * Locates a cached Response for the Request provided. + * + * @param Request $request A Request instance + * + * @return Response|null A Response instance, or null if no cache entry was found + */ + public function lookup(Request $request); + + /** + * Writes a cache entry to the store for the given Request and Response. + * + * Existing entries are read and any that match the response are removed. This + * method calls write with the new list of cache entries. + * + * @param Request $request A Request instance + * @param Response $response A Response instance + * + * @return string The key under which the response is stored + */ + public function write(Request $request, Response $response); + + /** + * Invalidates all cache entries that match the request. + * + * @param Request $request A Request instance + */ + public function invalidate(Request $request); + + /** + * Locks the cache for a given Request. + * + * @param Request $request A Request instance + * + * @return bool|string true if the lock is acquired, the path to the current lock otherwise + */ + public function lock(Request $request); + + /** + * Releases the lock for the given Request. + * + * @param Request $request A Request instance + * + * @return bool False if the lock file does not exist or cannot be unlocked, true otherwise + */ + public function unlock(Request $request); + + /** + * Returns whether or not a lock exists. + * + * @param Request $request A Request instance + * + * @return bool true if lock exists, false otherwise + */ + public function isLocked(Request $request); + + /** + * Purges data for the given URL. + * + * @param string $url A URL + * + * @return bool true if the URL exists and has been purged, false otherwise + */ + public function purge($url); + + /** + * Cleanups storage. + */ + public function cleanup(); +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/HttpCache/SurrogateInterface.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/HttpCache/SurrogateInterface.php new file mode 100644 index 0000000..5d65fd6 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/HttpCache/SurrogateInterface.php @@ -0,0 +1,103 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\HttpCache; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; + +interface SurrogateInterface +{ + /** + * Returns surrogate name. + * + * @return string + */ + public function getName(); + + /** + * Returns a new cache strategy instance. + * + * @return ResponseCacheStrategyInterface A ResponseCacheStrategyInterface instance + */ + public function createCacheStrategy(); + + /** + * Checks that at least one surrogate has Surrogate capability. + * + * @param Request $request A Request instance + * + * @return bool true if one surrogate has Surrogate capability, false otherwise + */ + public function hasSurrogateCapability(Request $request); + + /** + * Adds Surrogate-capability to the given Request. + * + * @param Request $request A Request instance + */ + public function addSurrogateCapability(Request $request); + + /** + * Adds HTTP headers to specify that the Response needs to be parsed for Surrogate. + * + * This method only adds an Surrogate HTTP header if the Response has some Surrogate tags. + * + * @param Response $response A Response instance + */ + public function addSurrogateControl(Response $response); + + /** + * Checks that the Response needs to be parsed for Surrogate tags. + * + * @param Response $response A Response instance + * + * @return bool true if the Response needs to be parsed, false otherwise + */ + public function needsParsing(Response $response); + + /** + * Renders a Surrogate tag. + * + * @param string $uri A URI + * @param string $alt An alternate URI + * @param bool $ignoreErrors Whether to ignore errors or not + * @param string $comment A comment to add as an esi:include tag + * + * @return string + */ + public function renderIncludeTag($uri, $alt = null, $ignoreErrors = true, $comment = ''); + + /** + * Replaces a Response Surrogate tags with the included resource content. + * + * @param Request $request A Request instance + * @param Response $response A Response instance + * + * @return Response + */ + public function process(Request $request, Response $response); + + /** + * Handles a Surrogate from the cache. + * + * @param HttpCache $cache An HttpCache instance + * @param string $uri The main URI + * @param string $alt An alternative URI + * @param bool $ignoreErrors Whether to ignore errors or not + * + * @return string + * + * @throws \RuntimeException + * @throws \Exception + */ + public function handle(HttpCache $cache, $uri, $alt, $ignoreErrors); +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/HttpKernel.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/HttpKernel.php new file mode 100644 index 0000000..4e628a1 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/HttpKernel.php @@ -0,0 +1,290 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel; + +use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface; +use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; +use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; +use Symfony\Component\HttpKernel\Event\FilterControllerEvent; +use Symfony\Component\HttpKernel\Event\FilterResponseEvent; +use Symfony\Component\HttpKernel\Event\FinishRequestEvent; +use Symfony\Component\HttpKernel\Event\GetResponseEvent; +use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent; +use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; +use Symfony\Component\HttpKernel\Event\PostResponseEvent; +use Symfony\Component\HttpFoundation\Exception\ConflictingHeadersException; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\RequestStack; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; + +/** + * HttpKernel notifies events to convert a Request object to a Response one. + * + * @author Fabien Potencier + */ +class HttpKernel implements HttpKernelInterface, TerminableInterface +{ + protected $dispatcher; + protected $resolver; + protected $requestStack; + + /** + * Constructor. + * + * @param EventDispatcherInterface $dispatcher An EventDispatcherInterface instance + * @param ControllerResolverInterface $resolver A ControllerResolverInterface instance + * @param RequestStack $requestStack A stack for master/sub requests + */ + public function __construct(EventDispatcherInterface $dispatcher, ControllerResolverInterface $resolver, RequestStack $requestStack = null) + { + $this->dispatcher = $dispatcher; + $this->resolver = $resolver; + $this->requestStack = $requestStack ?: new RequestStack(); + } + + /** + * {@inheritdoc} + */ + public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true) + { + $request->headers->set('X-Php-Ob-Level', ob_get_level()); + + try { + return $this->handleRaw($request, $type); + } catch (\Exception $e) { + if ($e instanceof ConflictingHeadersException) { + $e = new BadRequestHttpException('The request headers contain conflicting information regarding the origin of this request.', $e); + } + if (false === $catch) { + $this->finishRequest($request, $type); + + throw $e; + } + + return $this->handleException($e, $request, $type); + } + } + + /** + * {@inheritdoc} + */ + public function terminate(Request $request, Response $response) + { + $this->dispatcher->dispatch(KernelEvents::TERMINATE, new PostResponseEvent($this, $request, $response)); + } + + /** + * @throws \LogicException If the request stack is empty + * + * @internal + */ + public function terminateWithException(\Exception $exception) + { + if (!$request = $this->requestStack->getMasterRequest()) { + throw new \LogicException('Request stack is empty', 0, $exception); + } + + $response = $this->handleException($exception, $request, self::MASTER_REQUEST); + + $response->sendHeaders(); + $response->sendContent(); + + $this->terminate($request, $response); + } + + /** + * Handles a request to convert it to a response. + * + * Exceptions are not caught. + * + * @param Request $request A Request instance + * @param int $type The type of the request (one of HttpKernelInterface::MASTER_REQUEST or HttpKernelInterface::SUB_REQUEST) + * + * @return Response A Response instance + * + * @throws \LogicException If one of the listener does not behave as expected + * @throws NotFoundHttpException When controller cannot be found + */ + private function handleRaw(Request $request, $type = self::MASTER_REQUEST) + { + $this->requestStack->push($request); + + // request + $event = new GetResponseEvent($this, $request, $type); + $this->dispatcher->dispatch(KernelEvents::REQUEST, $event); + + if ($event->hasResponse()) { + return $this->filterResponse($event->getResponse(), $request, $type); + } + + // load controller + if (false === $controller = $this->resolver->getController($request)) { + throw new NotFoundHttpException(sprintf('Unable to find the controller for path "%s". The route is wrongly configured.', $request->getPathInfo())); + } + + $event = new FilterControllerEvent($this, $controller, $request, $type); + $this->dispatcher->dispatch(KernelEvents::CONTROLLER, $event); + $controller = $event->getController(); + + // controller arguments + $arguments = $this->resolver->getArguments($request, $controller); + + // call controller + $response = call_user_func_array($controller, $arguments); + + // view + if (!$response instanceof Response) { + $event = new GetResponseForControllerResultEvent($this, $request, $type, $response); + $this->dispatcher->dispatch(KernelEvents::VIEW, $event); + + if ($event->hasResponse()) { + $response = $event->getResponse(); + } + + if (!$response instanceof Response) { + $msg = sprintf('The controller must return a response (%s given).', $this->varToString($response)); + + // the user may have forgotten to return something + if (null === $response) { + $msg .= ' Did you forget to add a return statement somewhere in your controller?'; + } + throw new \LogicException($msg); + } + } + + return $this->filterResponse($response, $request, $type); + } + + /** + * Filters a response object. + * + * @param Response $response A Response instance + * @param Request $request An error message in case the response is not a Response object + * @param int $type The type of the request (one of HttpKernelInterface::MASTER_REQUEST or HttpKernelInterface::SUB_REQUEST) + * + * @return Response The filtered Response instance + * + * @throws \RuntimeException if the passed object is not a Response instance + */ + private function filterResponse(Response $response, Request $request, $type) + { + $event = new FilterResponseEvent($this, $request, $type, $response); + + $this->dispatcher->dispatch(KernelEvents::RESPONSE, $event); + + $this->finishRequest($request, $type); + + return $event->getResponse(); + } + + /** + * Publishes the finish request event, then pop the request from the stack. + * + * Note that the order of the operations is important here, otherwise + * operations such as {@link RequestStack::getParentRequest()} can lead to + * weird results. + * + * @param Request $request + * @param int $type + */ + private function finishRequest(Request $request, $type) + { + $this->dispatcher->dispatch(KernelEvents::FINISH_REQUEST, new FinishRequestEvent($this, $request, $type)); + $this->requestStack->pop(); + } + + /** + * Handles an exception by trying to convert it to a Response. + * + * @param \Exception $e An \Exception instance + * @param Request $request A Request instance + * @param int $type The type of the request + * + * @return Response A Response instance + * + * @throws \Exception + */ + private function handleException(\Exception $e, $request, $type) + { + $event = new GetResponseForExceptionEvent($this, $request, $type, $e); + $this->dispatcher->dispatch(KernelEvents::EXCEPTION, $event); + + // a listener might have replaced the exception + $e = $event->getException(); + + if (!$event->hasResponse()) { + $this->finishRequest($request, $type); + + throw $e; + } + + $response = $event->getResponse(); + + // the developer asked for a specific status code + if ($response->headers->has('X-Status-Code')) { + $response->setStatusCode($response->headers->get('X-Status-Code')); + + $response->headers->remove('X-Status-Code'); + } elseif (!$response->isClientError() && !$response->isServerError() && !$response->isRedirect()) { + // ensure that we actually have an error response + if ($e instanceof HttpExceptionInterface) { + // keep the HTTP status code and headers + $response->setStatusCode($e->getStatusCode()); + $response->headers->add($e->getHeaders()); + } else { + $response->setStatusCode(500); + } + } + + try { + return $this->filterResponse($response, $request, $type); + } catch (\Exception $e) { + return $response; + } + } + + private function varToString($var) + { + if (is_object($var)) { + return sprintf('Object(%s)', get_class($var)); + } + + if (is_array($var)) { + $a = array(); + foreach ($var as $k => $v) { + $a[] = sprintf('%s => %s', $k, $this->varToString($v)); + } + + return sprintf('Array(%s)', implode(', ', $a)); + } + + if (is_resource($var)) { + return sprintf('Resource(%s)', get_resource_type($var)); + } + + if (null === $var) { + return 'null'; + } + + if (false === $var) { + return 'false'; + } + + if (true === $var) { + return 'true'; + } + + return (string) $var; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/HttpKernelInterface.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/HttpKernelInterface.php new file mode 100644 index 0000000..5050bfc --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/HttpKernelInterface.php @@ -0,0 +1,43 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; + +/** + * HttpKernelInterface handles a Request to convert it to a Response. + * + * @author Fabien Potencier + */ +interface HttpKernelInterface +{ + const MASTER_REQUEST = 1; + const SUB_REQUEST = 2; + + /** + * Handles a Request to convert it to a Response. + * + * When $catch is true, the implementation must catch all exceptions + * and do its best to convert them to a Response instance. + * + * @param Request $request A Request instance + * @param int $type The type of the request + * (one of HttpKernelInterface::MASTER_REQUEST or HttpKernelInterface::SUB_REQUEST) + * @param bool $catch Whether to catch exceptions or not + * + * @return Response A Response instance + * + * @throws \Exception When an Exception occurs during processing + */ + public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = true); +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Kernel.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Kernel.php new file mode 100644 index 0000000..c6586c0 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Kernel.php @@ -0,0 +1,765 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel; + +use Symfony\Bridge\ProxyManager\LazyProxy\Instantiator\RuntimeInstantiator; +use Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\ProxyDumper; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Dumper\PhpDumper; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; +use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; +use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; +use Symfony\Component\DependencyInjection\Loader\IniFileLoader; +use Symfony\Component\DependencyInjection\Loader\PhpFileLoader; +use Symfony\Component\DependencyInjection\Loader\ClosureLoader; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\Bundle\BundleInterface; +use Symfony\Component\HttpKernel\Config\EnvParametersResource; +use Symfony\Component\HttpKernel\Config\FileLocator; +use Symfony\Component\HttpKernel\DependencyInjection\MergeExtensionConfigurationPass; +use Symfony\Component\HttpKernel\DependencyInjection\AddClassesToCachePass; +use Symfony\Component\Config\Loader\LoaderResolver; +use Symfony\Component\Config\Loader\DelegatingLoader; +use Symfony\Component\Config\ConfigCache; +use Symfony\Component\ClassLoader\ClassCollectionLoader; + +/** + * The Kernel is the heart of the Symfony system. + * + * It manages an environment made of bundles. + * + * @author Fabien Potencier + */ +abstract class Kernel implements KernelInterface, TerminableInterface +{ + /** + * @var BundleInterface[] + */ + protected $bundles = array(); + + protected $bundleMap; + protected $container; + protected $rootDir; + protected $environment; + protected $debug; + protected $booted = false; + protected $name; + protected $startTime; + protected $loadClassCache; + + const VERSION = '2.7.19-DEV'; + const VERSION_ID = 20719; + const MAJOR_VERSION = 2; + const MINOR_VERSION = 7; + const RELEASE_VERSION = 19; + const EXTRA_VERSION = 'DEV'; + + const END_OF_MAINTENANCE = '05/2018'; + const END_OF_LIFE = '05/2019'; + + /** + * Constructor. + * + * @param string $environment The environment + * @param bool $debug Whether to enable debugging or not + */ + public function __construct($environment, $debug) + { + $this->environment = $environment; + $this->debug = (bool) $debug; + $this->rootDir = $this->getRootDir(); + $this->name = $this->getName(); + + if ($this->debug) { + $this->startTime = microtime(true); + } + + $defClass = new \ReflectionMethod($this, 'init'); + $defClass = $defClass->getDeclaringClass()->name; + + if (__CLASS__ !== $defClass) { + @trigger_error(sprintf('Calling the %s::init() method is deprecated since version 2.3 and will be removed in 3.0. Move your logic to the constructor method instead.', $defClass), E_USER_DEPRECATED); + $this->init(); + } + } + + /** + * @deprecated since version 2.3, to be removed in 3.0. Move your logic in the constructor instead. + */ + public function init() + { + @trigger_error('The '.__METHOD__.' method is deprecated since version 2.3 and will be removed in 3.0. Move your logic to the constructor method instead.', E_USER_DEPRECATED); + } + + public function __clone() + { + if ($this->debug) { + $this->startTime = microtime(true); + } + + $this->booted = false; + $this->container = null; + } + + /** + * Boots the current kernel. + */ + public function boot() + { + if (true === $this->booted) { + return; + } + + if ($this->loadClassCache) { + $this->doLoadClassCache($this->loadClassCache[0], $this->loadClassCache[1]); + } + + // init bundles + $this->initializeBundles(); + + // init container + $this->initializeContainer(); + + foreach ($this->getBundles() as $bundle) { + $bundle->setContainer($this->container); + $bundle->boot(); + } + + $this->booted = true; + } + + /** + * {@inheritdoc} + */ + public function terminate(Request $request, Response $response) + { + if (false === $this->booted) { + return; + } + + if ($this->getHttpKernel() instanceof TerminableInterface) { + $this->getHttpKernel()->terminate($request, $response); + } + } + + /** + * {@inheritdoc} + */ + public function shutdown() + { + if (false === $this->booted) { + return; + } + + $this->booted = false; + + foreach ($this->getBundles() as $bundle) { + $bundle->shutdown(); + $bundle->setContainer(null); + } + + $this->container = null; + } + + /** + * {@inheritdoc} + */ + public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true) + { + if (false === $this->booted) { + $this->boot(); + } + + return $this->getHttpKernel()->handle($request, $type, $catch); + } + + /** + * Gets a HTTP kernel from the container. + * + * @return HttpKernel + */ + protected function getHttpKernel() + { + return $this->container->get('http_kernel'); + } + + /** + * {@inheritdoc} + */ + public function getBundles() + { + return $this->bundles; + } + + /** + * {@inheritdoc} + * + * @deprecated since version 2.6, to be removed in 3.0. + */ + public function isClassInActiveBundle($class) + { + @trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in version 3.0.', E_USER_DEPRECATED); + + foreach ($this->getBundles() as $bundle) { + if (0 === strpos($class, $bundle->getNamespace())) { + return true; + } + } + + return false; + } + + /** + * {@inheritdoc} + */ + public function getBundle($name, $first = true) + { + if (!isset($this->bundleMap[$name])) { + throw new \InvalidArgumentException(sprintf('Bundle "%s" does not exist or it is not enabled. Maybe you forgot to add it in the registerBundles() method of your %s.php file?', $name, get_class($this))); + } + + if (true === $first) { + return $this->bundleMap[$name][0]; + } + + return $this->bundleMap[$name]; + } + + /** + * {@inheritdoc} + * + * @throws \RuntimeException if a custom resource is hidden by a resource in a derived bundle + */ + public function locateResource($name, $dir = null, $first = true) + { + if ('@' !== $name[0]) { + throw new \InvalidArgumentException(sprintf('A resource name must start with @ ("%s" given).', $name)); + } + + if (false !== strpos($name, '..')) { + throw new \RuntimeException(sprintf('File name "%s" contains invalid characters (..).', $name)); + } + + $bundleName = substr($name, 1); + $path = ''; + if (false !== strpos($bundleName, '/')) { + list($bundleName, $path) = explode('/', $bundleName, 2); + } + + $isResource = 0 === strpos($path, 'Resources') && null !== $dir; + $overridePath = substr($path, 9); + $resourceBundle = null; + $bundles = $this->getBundle($bundleName, false); + $files = array(); + + foreach ($bundles as $bundle) { + if ($isResource && file_exists($file = $dir.'/'.$bundle->getName().$overridePath)) { + if (null !== $resourceBundle) { + throw new \RuntimeException(sprintf('"%s" resource is hidden by a resource from the "%s" derived bundle. Create a "%s" file to override the bundle resource.', + $file, + $resourceBundle, + $dir.'/'.$bundles[0]->getName().$overridePath + )); + } + + if ($first) { + return $file; + } + $files[] = $file; + } + + if (file_exists($file = $bundle->getPath().'/'.$path)) { + if ($first && !$isResource) { + return $file; + } + $files[] = $file; + $resourceBundle = $bundle->getName(); + } + } + + if (count($files) > 0) { + return $first && $isResource ? $files[0] : $files; + } + + throw new \InvalidArgumentException(sprintf('Unable to find file "%s".', $name)); + } + + /** + * {@inheritdoc} + */ + public function getName() + { + if (null === $this->name) { + $this->name = preg_replace('/[^a-zA-Z0-9_]+/', '', basename($this->rootDir)); + } + + return $this->name; + } + + /** + * {@inheritdoc} + */ + public function getEnvironment() + { + return $this->environment; + } + + /** + * {@inheritdoc} + */ + public function isDebug() + { + return $this->debug; + } + + /** + * {@inheritdoc} + */ + public function getRootDir() + { + if (null === $this->rootDir) { + $r = new \ReflectionObject($this); + $this->rootDir = dirname($r->getFileName()); + } + + return $this->rootDir; + } + + /** + * {@inheritdoc} + */ + public function getContainer() + { + return $this->container; + } + + /** + * Loads the PHP class cache. + * + * This methods only registers the fact that you want to load the cache classes. + * The cache will actually only be loaded when the Kernel is booted. + * + * That optimization is mainly useful when using the HttpCache class in which + * case the class cache is not loaded if the Response is in the cache. + * + * @param string $name The cache name prefix + * @param string $extension File extension of the resulting file + */ + public function loadClassCache($name = 'classes', $extension = '.php') + { + $this->loadClassCache = array($name, $extension); + } + + /** + * Used internally. + */ + public function setClassCache(array $classes) + { + file_put_contents($this->getCacheDir().'/classes.map', sprintf('debug ? $this->startTime : -INF; + } + + /** + * {@inheritdoc} + */ + public function getCacheDir() + { + return $this->rootDir.'/cache/'.$this->environment; + } + + /** + * {@inheritdoc} + */ + public function getLogDir() + { + return $this->rootDir.'/logs'; + } + + /** + * {@inheritdoc} + */ + public function getCharset() + { + return 'UTF-8'; + } + + protected function doLoadClassCache($name, $extension) + { + if (!$this->booted && is_file($this->getCacheDir().'/classes.map')) { + ClassCollectionLoader::load(include($this->getCacheDir().'/classes.map'), $this->getCacheDir(), $name, $this->debug, false, $extension); + } + } + + /** + * Initializes the data structures related to the bundle management. + * + * - the bundles property maps a bundle name to the bundle instance, + * - the bundleMap property maps a bundle name to the bundle inheritance hierarchy (most derived bundle first). + * + * @throws \LogicException if two bundles share a common name + * @throws \LogicException if a bundle tries to extend a non-registered bundle + * @throws \LogicException if a bundle tries to extend itself + * @throws \LogicException if two bundles extend the same ancestor + */ + protected function initializeBundles() + { + // init bundles + $this->bundles = array(); + $topMostBundles = array(); + $directChildren = array(); + + foreach ($this->registerBundles() as $bundle) { + $name = $bundle->getName(); + if (isset($this->bundles[$name])) { + throw new \LogicException(sprintf('Trying to register two bundles with the same name "%s"', $name)); + } + $this->bundles[$name] = $bundle; + + if ($parentName = $bundle->getParent()) { + if (isset($directChildren[$parentName])) { + throw new \LogicException(sprintf('Bundle "%s" is directly extended by two bundles "%s" and "%s".', $parentName, $name, $directChildren[$parentName])); + } + if ($parentName == $name) { + throw new \LogicException(sprintf('Bundle "%s" can not extend itself.', $name)); + } + $directChildren[$parentName] = $name; + } else { + $topMostBundles[$name] = $bundle; + } + } + + // look for orphans + if (!empty($directChildren) && count($diff = array_diff_key($directChildren, $this->bundles))) { + $diff = array_keys($diff); + + throw new \LogicException(sprintf('Bundle "%s" extends bundle "%s", which is not registered.', $directChildren[$diff[0]], $diff[0])); + } + + // inheritance + $this->bundleMap = array(); + foreach ($topMostBundles as $name => $bundle) { + $bundleMap = array($bundle); + $hierarchy = array($name); + + while (isset($directChildren[$name])) { + $name = $directChildren[$name]; + array_unshift($bundleMap, $this->bundles[$name]); + $hierarchy[] = $name; + } + + foreach ($hierarchy as $hierarchyBundle) { + $this->bundleMap[$hierarchyBundle] = $bundleMap; + array_pop($bundleMap); + } + } + } + + /** + * Gets the container class. + * + * @return string The container class + */ + protected function getContainerClass() + { + return $this->name.ucfirst($this->environment).($this->debug ? 'Debug' : '').'ProjectContainer'; + } + + /** + * Gets the container's base class. + * + * All names except Container must be fully qualified. + * + * @return string + */ + protected function getContainerBaseClass() + { + return 'Container'; + } + + /** + * Initializes the service container. + * + * The cached version of the service container is used when fresh, otherwise the + * container is built. + */ + protected function initializeContainer() + { + $class = $this->getContainerClass(); + $cache = new ConfigCache($this->getCacheDir().'/'.$class.'.php', $this->debug); + $fresh = true; + if (!$cache->isFresh()) { + $container = $this->buildContainer(); + $container->compile(); + $this->dumpContainer($cache, $container, $class, $this->getContainerBaseClass()); + + $fresh = false; + } + + require_once $cache->getPath(); + + $this->container = new $class(); + $this->container->set('kernel', $this); + + if (!$fresh && $this->container->has('cache_warmer')) { + $this->container->get('cache_warmer')->warmUp($this->container->getParameter('kernel.cache_dir')); + } + } + + /** + * Returns the kernel parameters. + * + * @return array An array of kernel parameters + */ + protected function getKernelParameters() + { + $bundles = array(); + foreach ($this->bundles as $name => $bundle) { + $bundles[$name] = get_class($bundle); + } + + return array_merge( + array( + 'kernel.root_dir' => realpath($this->rootDir) ?: $this->rootDir, + 'kernel.environment' => $this->environment, + 'kernel.debug' => $this->debug, + 'kernel.name' => $this->name, + 'kernel.cache_dir' => realpath($this->getCacheDir()) ?: $this->getCacheDir(), + 'kernel.logs_dir' => realpath($this->getLogDir()) ?: $this->getLogDir(), + 'kernel.bundles' => $bundles, + 'kernel.charset' => $this->getCharset(), + 'kernel.container_class' => $this->getContainerClass(), + ), + $this->getEnvParameters() + ); + } + + /** + * Gets the environment parameters. + * + * Only the parameters starting with "SYMFONY__" are considered. + * + * @return array An array of parameters + */ + protected function getEnvParameters() + { + $parameters = array(); + foreach ($_SERVER as $key => $value) { + if (0 === strpos($key, 'SYMFONY__')) { + $parameters[strtolower(str_replace('__', '.', substr($key, 9)))] = $value; + } + } + + return $parameters; + } + + /** + * Builds the service container. + * + * @return ContainerBuilder The compiled service container + * + * @throws \RuntimeException + */ + protected function buildContainer() + { + foreach (array('cache' => $this->getCacheDir(), 'logs' => $this->getLogDir()) as $name => $dir) { + if (!is_dir($dir)) { + if (false === @mkdir($dir, 0777, true) && !is_dir($dir)) { + throw new \RuntimeException(sprintf("Unable to create the %s directory (%s)\n", $name, $dir)); + } + } elseif (!is_writable($dir)) { + throw new \RuntimeException(sprintf("Unable to write in the %s directory (%s)\n", $name, $dir)); + } + } + + $container = $this->getContainerBuilder(); + $container->addObjectResource($this); + $this->prepareContainer($container); + + if (null !== $cont = $this->registerContainerConfiguration($this->getContainerLoader($container))) { + $container->merge($cont); + } + + $container->addCompilerPass(new AddClassesToCachePass($this)); + $container->addResource(new EnvParametersResource('SYMFONY__')); + + return $container; + } + + /** + * Prepares the ContainerBuilder before it is compiled. + * + * @param ContainerBuilder $container A ContainerBuilder instance + */ + protected function prepareContainer(ContainerBuilder $container) + { + $extensions = array(); + foreach ($this->bundles as $bundle) { + if ($extension = $bundle->getContainerExtension()) { + $container->registerExtension($extension); + $extensions[] = $extension->getAlias(); + } + + if ($this->debug) { + $container->addObjectResource($bundle); + } + } + foreach ($this->bundles as $bundle) { + $bundle->build($container); + } + + // ensure these extensions are implicitly loaded + $container->getCompilerPassConfig()->setMergePass(new MergeExtensionConfigurationPass($extensions)); + } + + /** + * Gets a new ContainerBuilder instance used to build the service container. + * + * @return ContainerBuilder + */ + protected function getContainerBuilder() + { + $container = new ContainerBuilder(new ParameterBag($this->getKernelParameters())); + + if (class_exists('ProxyManager\Configuration') && class_exists('Symfony\Bridge\ProxyManager\LazyProxy\Instantiator\RuntimeInstantiator')) { + $container->setProxyInstantiator(new RuntimeInstantiator()); + } + + return $container; + } + + /** + * Dumps the service container to PHP code in the cache. + * + * @param ConfigCache $cache The config cache + * @param ContainerBuilder $container The service container + * @param string $class The name of the class to generate + * @param string $baseClass The name of the container's base class + */ + protected function dumpContainer(ConfigCache $cache, ContainerBuilder $container, $class, $baseClass) + { + // cache the container + $dumper = new PhpDumper($container); + + if (class_exists('ProxyManager\Configuration') && class_exists('Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\ProxyDumper')) { + $dumper->setProxyDumper(new ProxyDumper(md5($cache->getPath()))); + } + + $content = $dumper->dump(array('class' => $class, 'base_class' => $baseClass, 'file' => $cache->getPath(), 'debug' => $this->debug)); + + $cache->write($content, $container->getResources()); + } + + /** + * Returns a loader for the container. + * + * @param ContainerInterface $container The service container + * + * @return DelegatingLoader The loader + */ + protected function getContainerLoader(ContainerInterface $container) + { + $locator = new FileLocator($this); + $resolver = new LoaderResolver(array( + new XmlFileLoader($container, $locator), + new YamlFileLoader($container, $locator), + new IniFileLoader($container, $locator), + new PhpFileLoader($container, $locator), + new ClosureLoader($container), + )); + + return new DelegatingLoader($resolver); + } + + /** + * Removes comments from a PHP source string. + * + * We don't use the PHP php_strip_whitespace() function + * as we want the content to be readable and well-formatted. + * + * @param string $source A PHP string + * + * @return string The PHP string with the comments removed + */ + public static function stripComments($source) + { + if (!function_exists('token_get_all')) { + return $source; + } + + $rawChunk = ''; + $output = ''; + $tokens = token_get_all($source); + $ignoreSpace = false; + for ($i = 0; isset($tokens[$i]); ++$i) { + $token = $tokens[$i]; + if (!isset($token[1]) || 'b"' === $token) { + $rawChunk .= $token; + } elseif (T_START_HEREDOC === $token[0]) { + $output .= $rawChunk.$token[1]; + do { + $token = $tokens[++$i]; + $output .= isset($token[1]) && 'b"' !== $token ? $token[1] : $token; + } while ($token[0] !== T_END_HEREDOC); + $rawChunk = ''; + } elseif (T_WHITESPACE === $token[0]) { + if ($ignoreSpace) { + $ignoreSpace = false; + + continue; + } + + // replace multiple new lines with a single newline + $rawChunk .= preg_replace(array('/\n{2,}/S'), "\n", $token[1]); + } elseif (in_array($token[0], array(T_COMMENT, T_DOC_COMMENT))) { + $ignoreSpace = true; + } else { + $rawChunk .= $token[1]; + + // The PHP-open tag already has a new-line + if (T_OPEN_TAG === $token[0]) { + $ignoreSpace = true; + } + } + } + + $output .= $rawChunk; + + if (PHP_VERSION_ID >= 70000) { + // PHP 7 memory manager will not release after token_get_all(), see https://bugs.php.net/70098 + unset($tokens, $rawChunk); + gc_mem_caches(); + } + + return $output; + } + + public function serialize() + { + return serialize(array($this->environment, $this->debug)); + } + + public function unserialize($data) + { + list($environment, $debug) = unserialize($data); + + $this->__construct($environment, $debug); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/KernelEvents.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/KernelEvents.php new file mode 100644 index 0000000..abbbfcc --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/KernelEvents.php @@ -0,0 +1,119 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel; + +/** + * Contains all events thrown in the HttpKernel component. + * + * @author Bernhard Schussek + */ +final class KernelEvents +{ + /** + * The REQUEST event occurs at the very beginning of request + * dispatching. + * + * This event allows you to create a response for a request before any + * other code in the framework is executed. The event listener method + * receives a Symfony\Component\HttpKernel\Event\GetResponseEvent + * instance. + * + * @Event + * + * @var string + */ + const REQUEST = 'kernel.request'; + + /** + * The EXCEPTION event occurs when an uncaught exception appears. + * + * This event allows you to create a response for a thrown exception or + * to modify the thrown exception. The event listener method receives + * a Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent + * instance. + * + * @Event + * + * @var string + */ + const EXCEPTION = 'kernel.exception'; + + /** + * The VIEW event occurs when the return value of a controller + * is not a Response instance. + * + * This event allows you to create a response for the return value of the + * controller. The event listener method receives a + * Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent + * instance. + * + * @Event + * + * @var string + */ + const VIEW = 'kernel.view'; + + /** + * The CONTROLLER event occurs once a controller was found for + * handling a request. + * + * This event allows you to change the controller that will handle the + * request. The event listener method receives a + * Symfony\Component\HttpKernel\Event\FilterControllerEvent instance. + * + * @Event + * + * @var string + */ + const CONTROLLER = 'kernel.controller'; + + /** + * The RESPONSE event occurs once a response was created for + * replying to a request. + * + * This event allows you to modify or replace the response that will be + * replied. The event listener method receives a + * Symfony\Component\HttpKernel\Event\FilterResponseEvent instance. + * + * @Event + * + * @var string + */ + const RESPONSE = 'kernel.response'; + + /** + * The TERMINATE event occurs once a response was sent. + * + * This event allows you to run expensive post-response jobs. + * The event listener method receives a + * Symfony\Component\HttpKernel\Event\PostResponseEvent instance. + * + * @Event + * + * @var string + */ + const TERMINATE = 'kernel.terminate'; + + /** + * The FINISH_REQUEST event occurs when a response was generated for a request. + * + * This event allows you to reset the global and environmental state of + * the application, when it was changed during the request. + * The event listener method receives a + * Symfony\Component\HttpKernel\Event\FinishRequestEvent instance. + * + * @Event + * + * @var string + */ + const FINISH_REQUEST = 'kernel.finish_request'; +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/KernelInterface.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/KernelInterface.php new file mode 100644 index 0000000..37ac3af --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/KernelInterface.php @@ -0,0 +1,175 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel; + +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\HttpKernel\Bundle\BundleInterface; +use Symfony\Component\Config\Loader\LoaderInterface; + +/** + * The Kernel is the heart of the Symfony system. + * + * It manages an environment made of bundles. + * + * @author Fabien Potencier + */ +interface KernelInterface extends HttpKernelInterface, \Serializable +{ + /** + * Returns an array of bundles to register. + * + * @return BundleInterface[] An array of bundle instances + */ + public function registerBundles(); + + /** + * Loads the container configuration. + * + * @param LoaderInterface $loader A LoaderInterface instance + */ + public function registerContainerConfiguration(LoaderInterface $loader); + + /** + * Boots the current kernel. + */ + public function boot(); + + /** + * Shutdowns the kernel. + * + * This method is mainly useful when doing functional testing. + */ + public function shutdown(); + + /** + * Gets the registered bundle instances. + * + * @return BundleInterface[] An array of registered bundle instances + */ + public function getBundles(); + + /** + * Checks if a given class name belongs to an active bundle. + * + * @param string $class A class name + * + * @return bool true if the class belongs to an active bundle, false otherwise + * + * @deprecated since version 2.6, to be removed in 3.0. + */ + public function isClassInActiveBundle($class); + + /** + * Returns a bundle and optionally its descendants by its name. + * + * @param string $name Bundle name + * @param bool $first Whether to return the first bundle only or together with its descendants + * + * @return BundleInterface|BundleInterface[] A BundleInterface instance or an array of BundleInterface instances if $first is false + * + * @throws \InvalidArgumentException when the bundle is not enabled + */ + public function getBundle($name, $first = true); + + /** + * Returns the file path for a given resource. + * + * A Resource can be a file or a directory. + * + * The resource name must follow the following pattern: + * + * "@BundleName/path/to/a/file.something" + * + * where BundleName is the name of the bundle + * and the remaining part is the relative path in the bundle. + * + * If $dir is passed, and the first segment of the path is "Resources", + * this method will look for a file named: + * + * $dir//path/without/Resources + * + * before looking in the bundle resource folder. + * + * @param string $name A resource name to locate + * @param string $dir A directory where to look for the resource first + * @param bool $first Whether to return the first path or paths for all matching bundles + * + * @return string|array The absolute path of the resource or an array if $first is false + * + * @throws \InvalidArgumentException if the file cannot be found or the name is not valid + * @throws \RuntimeException if the name contains invalid/unsafe characters + */ + public function locateResource($name, $dir = null, $first = true); + + /** + * Gets the name of the kernel. + * + * @return string The kernel name + */ + public function getName(); + + /** + * Gets the environment. + * + * @return string The current environment + */ + public function getEnvironment(); + + /** + * Checks if debug mode is enabled. + * + * @return bool true if debug mode is enabled, false otherwise + */ + public function isDebug(); + + /** + * Gets the application root dir. + * + * @return string The application root dir + */ + public function getRootDir(); + + /** + * Gets the current container. + * + * @return ContainerInterface A ContainerInterface instance + */ + public function getContainer(); + + /** + * Gets the request start time (not available if debug is disabled). + * + * @return int The request start timestamp + */ + public function getStartTime(); + + /** + * Gets the cache directory. + * + * @return string The cache directory + */ + public function getCacheDir(); + + /** + * Gets the log directory. + * + * @return string The log directory + */ + public function getLogDir(); + + /** + * Gets the charset of the application. + * + * @return string The charset + */ + public function getCharset(); +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Log/DebugLoggerInterface.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Log/DebugLoggerInterface.php new file mode 100644 index 0000000..5635a21 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Log/DebugLoggerInterface.php @@ -0,0 +1,38 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Log; + +/** + * DebugLoggerInterface. + * + * @author Fabien Potencier + */ +interface DebugLoggerInterface +{ + /** + * Returns an array of logs. + * + * A log is an array with the following mandatory keys: + * timestamp, message, priority, and priorityName. + * It can also have an optional context key containing an array. + * + * @return array An array of logs + */ + public function getLogs(); + + /** + * Returns the number of errors. + * + * @return int The number of errors + */ + public function countErrors(); +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Log/LoggerInterface.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Log/LoggerInterface.php new file mode 100644 index 0000000..cad38e5 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Log/LoggerInterface.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Log; + +use Psr\Log\LoggerInterface as PsrLogger; + +/** + * LoggerInterface. + * + * @author Fabien Potencier + * + * @deprecated since version 2.2, to be removed in 3.0. Type-hint \Psr\Log\LoggerInterface instead. + */ +interface LoggerInterface extends PsrLogger +{ + /** + * @deprecated since version 2.2, to be removed in 3.0. Use emergency() which is PSR-3 compatible. + */ + public function emerg($message, array $context = array()); + + /** + * @deprecated since version 2.2, to be removed in 3.0. Use critical() which is PSR-3 compatible. + */ + public function crit($message, array $context = array()); + + /** + * @deprecated since version 2.2, to be removed in 3.0. Use error() which is PSR-3 compatible. + */ + public function err($message, array $context = array()); + + /** + * @deprecated since version 2.2, to be removed in 3.0. Use warning() which is PSR-3 compatible. + */ + public function warn($message, array $context = array()); +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Log/NullLogger.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Log/NullLogger.php new file mode 100644 index 0000000..36a857d --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Log/NullLogger.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Log; + +@trigger_error('The '.__NAMESPACE__.'\NullLogger class is deprecated since version 2.2 and will be removed in 3.0. Use the Psr\Log\NullLogger class instead from the psr/log Composer package.', E_USER_DEPRECATED); + +use Psr\Log\NullLogger as PsrNullLogger; + +/** + * NullLogger. + * + * @author Fabien Potencier + */ +class NullLogger extends PsrNullLogger implements LoggerInterface +{ + public function emerg($message, array $context = array()) + { + @trigger_error('The '.__METHOD__.' method is deprecated since version 2.2 and will be removed in 3.0. You should use the new emergency() method instead, which is PSR-3 compatible.', E_USER_DEPRECATED); + } + + public function crit($message, array $context = array()) + { + @trigger_error('The '.__METHOD__.' method is deprecated since version 2.2 and will be removed in 3.0. You should use the new critical() method instead, which is PSR-3 compatible.', E_USER_DEPRECATED); + } + + public function err($message, array $context = array()) + { + @trigger_error('The '.__METHOD__.' method is deprecated since version 2.2 and will be removed in 3.0. You should use the new error() method instead, which is PSR-3 compatible.', E_USER_DEPRECATED); + } + + public function warn($message, array $context = array()) + { + @trigger_error('The '.__METHOD__.' method is deprecated since version 2.2 and will be removed in 3.0. You should use the new warning() method instead, which is PSR-3 compatible.', E_USER_DEPRECATED); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Profiler/BaseMemcacheProfilerStorage.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Profiler/BaseMemcacheProfilerStorage.php new file mode 100644 index 0000000..c6395bd --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Profiler/BaseMemcacheProfilerStorage.php @@ -0,0 +1,310 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Profiler; + +/** + * Base Memcache storage for profiling information in a Memcache. + * + * @author Andrej Hudec + */ +abstract class BaseMemcacheProfilerStorage implements ProfilerStorageInterface +{ + const TOKEN_PREFIX = 'sf_profiler_'; + + protected $dsn; + protected $lifetime; + + /** + * Constructor. + * + * @param string $dsn A data source name + * @param string $username + * @param string $password + * @param int $lifetime The lifetime to use for the purge + */ + public function __construct($dsn, $username = '', $password = '', $lifetime = 86400) + { + $this->dsn = $dsn; + $this->lifetime = (int) $lifetime; + } + + /** + * {@inheritdoc} + */ + public function find($ip, $url, $limit, $method, $start = null, $end = null) + { + $indexName = $this->getIndexName(); + + $indexContent = $this->getValue($indexName); + if (!$indexContent) { + return array(); + } + + $profileList = explode("\n", $indexContent); + $result = array(); + + foreach ($profileList as $item) { + if ($limit === 0) { + break; + } + + if ($item == '') { + continue; + } + + $values = explode("\t", $item, 7); + list($itemToken, $itemIp, $itemMethod, $itemUrl, $itemTime, $itemParent) = $values; + $statusCode = isset($values[6]) ? $values[6] : null; + + $itemTime = (int) $itemTime; + + if ($ip && false === strpos($itemIp, $ip) || $url && false === strpos($itemUrl, $url) || $method && false === strpos($itemMethod, $method)) { + continue; + } + + if (!empty($start) && $itemTime < $start) { + continue; + } + + if (!empty($end) && $itemTime > $end) { + continue; + } + + $result[$itemToken] = array( + 'token' => $itemToken, + 'ip' => $itemIp, + 'method' => $itemMethod, + 'url' => $itemUrl, + 'time' => $itemTime, + 'parent' => $itemParent, + 'status_code' => $statusCode, + ); + --$limit; + } + + usort($result, function ($a, $b) { + if ($a['time'] === $b['time']) { + return 0; + } + + return $a['time'] > $b['time'] ? -1 : 1; + }); + + return $result; + } + + /** + * {@inheritdoc} + */ + public function purge() + { + // delete only items from index + $indexName = $this->getIndexName(); + + $indexContent = $this->getValue($indexName); + + if (!$indexContent) { + return false; + } + + $profileList = explode("\n", $indexContent); + + foreach ($profileList as $item) { + if ($item == '') { + continue; + } + + if (false !== $pos = strpos($item, "\t")) { + $this->delete($this->getItemName(substr($item, 0, $pos))); + } + } + + return $this->delete($indexName); + } + + /** + * {@inheritdoc} + */ + public function read($token) + { + if (empty($token)) { + return false; + } + + $profile = $this->getValue($this->getItemName($token)); + + if (false !== $profile) { + $profile = $this->createProfileFromData($token, $profile); + } + + return $profile; + } + + /** + * {@inheritdoc} + */ + public function write(Profile $profile) + { + $data = array( + 'token' => $profile->getToken(), + 'parent' => $profile->getParentToken(), + 'children' => array_map(function ($p) { return $p->getToken(); }, $profile->getChildren()), + 'data' => $profile->getCollectors(), + 'ip' => $profile->getIp(), + 'method' => $profile->getMethod(), + 'url' => $profile->getUrl(), + 'time' => $profile->getTime(), + ); + + $profileIndexed = false !== $this->getValue($this->getItemName($profile->getToken())); + + if ($this->setValue($this->getItemName($profile->getToken()), $data, $this->lifetime)) { + if (!$profileIndexed) { + // Add to index + $indexName = $this->getIndexName(); + + $indexRow = implode("\t", array( + $profile->getToken(), + $profile->getIp(), + $profile->getMethod(), + $profile->getUrl(), + $profile->getTime(), + $profile->getParentToken(), + $profile->getStatusCode(), + ))."\n"; + + return $this->appendValue($indexName, $indexRow, $this->lifetime); + } + + return true; + } + + return false; + } + + /** + * Retrieve item from the memcache server. + * + * @param string $key + * + * @return mixed + */ + abstract protected function getValue($key); + + /** + * Store an item on the memcache server under the specified key. + * + * @param string $key + * @param mixed $value + * @param int $expiration + * + * @return bool + */ + abstract protected function setValue($key, $value, $expiration = 0); + + /** + * Delete item from the memcache server. + * + * @param string $key + * + * @return bool + */ + abstract protected function delete($key); + + /** + * Append data to an existing item on the memcache server. + * + * @param string $key + * @param string $value + * @param int $expiration + * + * @return bool + */ + abstract protected function appendValue($key, $value, $expiration = 0); + + private function createProfileFromData($token, $data, $parent = null) + { + $profile = new Profile($token); + $profile->setIp($data['ip']); + $profile->setMethod($data['method']); + $profile->setUrl($data['url']); + $profile->setTime($data['time']); + $profile->setCollectors($data['data']); + + if (!$parent && $data['parent']) { + $parent = $this->read($data['parent']); + } + + if ($parent) { + $profile->setParent($parent); + } + + foreach ($data['children'] as $token) { + if (!$token) { + continue; + } + + if (!$childProfileData = $this->getValue($this->getItemName($token))) { + continue; + } + + $profile->addChild($this->createProfileFromData($token, $childProfileData, $profile)); + } + + return $profile; + } + + /** + * Get item name. + * + * @param string $token + * + * @return string + */ + private function getItemName($token) + { + $name = self::TOKEN_PREFIX.$token; + + if ($this->isItemNameValid($name)) { + return $name; + } + + return false; + } + + /** + * Get name of index. + * + * @return string + */ + private function getIndexName() + { + $name = self::TOKEN_PREFIX.'index'; + + if ($this->isItemNameValid($name)) { + return $name; + } + + return false; + } + + private function isItemNameValid($name) + { + $length = strlen($name); + + if ($length > 250) { + throw new \RuntimeException(sprintf('The memcache item key "%s" is too long (%s bytes). Allowed maximum size is 250 bytes.', $name, $length)); + } + + return true; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Profiler/FileProfilerStorage.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Profiler/FileProfilerStorage.php new file mode 100644 index 0000000..29da4ab --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Profiler/FileProfilerStorage.php @@ -0,0 +1,284 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Profiler; + +/** + * Storage for profiler using files. + * + * @author Alexandre Salomé + */ +class FileProfilerStorage implements ProfilerStorageInterface +{ + /** + * Folder where profiler data are stored. + * + * @var string + */ + private $folder; + + /** + * Constructs the file storage using a "dsn-like" path. + * + * Example : "file:/path/to/the/storage/folder" + * + * @param string $dsn The DSN + * + * @throws \RuntimeException + */ + public function __construct($dsn) + { + if (0 !== strpos($dsn, 'file:')) { + throw new \RuntimeException(sprintf('Please check your configuration. You are trying to use FileStorage with an invalid dsn "%s". The expected format is "file:/path/to/the/storage/folder".', $dsn)); + } + $this->folder = substr($dsn, 5); + + if (!is_dir($this->folder) && false === @mkdir($this->folder, 0777, true) && !is_dir($this->folder)) { + throw new \RuntimeException(sprintf('Unable to create the storage directory (%s).', $this->folder)); + } + } + + /** + * {@inheritdoc} + */ + public function find($ip, $url, $limit, $method, $start = null, $end = null) + { + $file = $this->getIndexFilename(); + + if (!file_exists($file)) { + return array(); + } + + $file = fopen($file, 'r'); + fseek($file, 0, SEEK_END); + + $result = array(); + while (count($result) < $limit && $line = $this->readLineFromFile($file)) { + $values = str_getcsv($line); + list($csvToken, $csvIp, $csvMethod, $csvUrl, $csvTime, $csvParent) = $values; + $csvStatusCode = isset($values[6]) ? $values[6] : null; + + $csvTime = (int) $csvTime; + + if ($ip && false === strpos($csvIp, $ip) || $url && false === strpos($csvUrl, $url) || $method && false === strpos($csvMethod, $method)) { + continue; + } + + if (!empty($start) && $csvTime < $start) { + continue; + } + + if (!empty($end) && $csvTime > $end) { + continue; + } + + $result[$csvToken] = array( + 'token' => $csvToken, + 'ip' => $csvIp, + 'method' => $csvMethod, + 'url' => $csvUrl, + 'time' => $csvTime, + 'parent' => $csvParent, + 'status_code' => $csvStatusCode, + ); + } + + fclose($file); + + return array_values($result); + } + + /** + * {@inheritdoc} + */ + public function purge() + { + $flags = \FilesystemIterator::SKIP_DOTS; + $iterator = new \RecursiveDirectoryIterator($this->folder, $flags); + $iterator = new \RecursiveIteratorIterator($iterator, \RecursiveIteratorIterator::CHILD_FIRST); + + foreach ($iterator as $file) { + if (is_file($file)) { + unlink($file); + } else { + rmdir($file); + } + } + } + + /** + * {@inheritdoc} + */ + public function read($token) + { + if (!$token || !file_exists($file = $this->getFilename($token))) { + return; + } + + return $this->createProfileFromData($token, unserialize(file_get_contents($file))); + } + + /** + * {@inheritdoc} + * + * @throws \RuntimeException + */ + public function write(Profile $profile) + { + $file = $this->getFilename($profile->getToken()); + + $profileIndexed = is_file($file); + if (!$profileIndexed) { + // Create directory + $dir = dirname($file); + if (!is_dir($dir) && false === @mkdir($dir, 0777, true) && !is_dir($dir)) { + throw new \RuntimeException(sprintf('Unable to create the storage directory (%s).', $dir)); + } + } + + // Store profile + $data = array( + 'token' => $profile->getToken(), + 'parent' => $profile->getParentToken(), + 'children' => array_map(function ($p) { return $p->getToken(); }, $profile->getChildren()), + 'data' => $profile->getCollectors(), + 'ip' => $profile->getIp(), + 'method' => $profile->getMethod(), + 'url' => $profile->getUrl(), + 'time' => $profile->getTime(), + ); + + if (false === file_put_contents($file, serialize($data))) { + return false; + } + + if (!$profileIndexed) { + // Add to index + if (false === $file = fopen($this->getIndexFilename(), 'a')) { + return false; + } + + fputcsv($file, array( + $profile->getToken(), + $profile->getIp(), + $profile->getMethod(), + $profile->getUrl(), + $profile->getTime(), + $profile->getParentToken(), + $profile->getStatusCode(), + )); + fclose($file); + } + + return true; + } + + /** + * Gets filename to store data, associated to the token. + * + * @param string $token + * + * @return string The profile filename + */ + protected function getFilename($token) + { + // Uses 4 last characters, because first are mostly the same. + $folderA = substr($token, -2, 2); + $folderB = substr($token, -4, 2); + + return $this->folder.'/'.$folderA.'/'.$folderB.'/'.$token; + } + + /** + * Gets the index filename. + * + * @return string The index filename + */ + protected function getIndexFilename() + { + return $this->folder.'/index.csv'; + } + + /** + * Reads a line in the file, backward. + * + * This function automatically skips the empty lines and do not include the line return in result value. + * + * @param resource $file The file resource, with the pointer placed at the end of the line to read + * + * @return mixed A string representing the line or null if beginning of file is reached + */ + protected function readLineFromFile($file) + { + $line = ''; + $position = ftell($file); + + if (0 === $position) { + return; + } + + while (true) { + $chunkSize = min($position, 1024); + $position -= $chunkSize; + fseek($file, $position); + + if (0 === $chunkSize) { + // bof reached + break; + } + + $buffer = fread($file, $chunkSize); + + if (false === ($upTo = strrpos($buffer, "\n"))) { + $line = $buffer.$line; + continue; + } + + $position += $upTo; + $line = substr($buffer, $upTo + 1).$line; + fseek($file, max(0, $position), SEEK_SET); + + if ('' !== $line) { + break; + } + } + + return '' === $line ? null : $line; + } + + protected function createProfileFromData($token, $data, $parent = null) + { + $profile = new Profile($token); + $profile->setIp($data['ip']); + $profile->setMethod($data['method']); + $profile->setUrl($data['url']); + $profile->setTime($data['time']); + $profile->setCollectors($data['data']); + + if (!$parent && $data['parent']) { + $parent = $this->read($data['parent']); + } + + if ($parent) { + $profile->setParent($parent); + } + + foreach ($data['children'] as $token) { + if (!$token || !file_exists($file = $this->getFilename($token))) { + continue; + } + + $profile->addChild($this->createProfileFromData($token, unserialize(file_get_contents($file)), $profile)); + } + + return $profile; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Profiler/MemcacheProfilerStorage.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Profiler/MemcacheProfilerStorage.php new file mode 100644 index 0000000..2727405 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Profiler/MemcacheProfilerStorage.php @@ -0,0 +1,107 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Profiler; + +/** + * Memcache Profiler Storage. + * + * @author Andrej Hudec + */ +class MemcacheProfilerStorage extends BaseMemcacheProfilerStorage +{ + /** + * @var \Memcache + */ + private $memcache; + + /** + * Internal convenience method that returns the instance of the Memcache. + * + * @return \Memcache + * + * @throws \RuntimeException + */ + protected function getMemcache() + { + if (null === $this->memcache) { + if (!preg_match('#^memcache://(?(?=\[.*\])\[(.*)\]|(.*)):(.*)$#', $this->dsn, $matches)) { + throw new \RuntimeException(sprintf('Please check your configuration. You are trying to use Memcache with an invalid dsn "%s". The expected format is "memcache://[host]:port".', $this->dsn)); + } + + $host = $matches[1] ?: $matches[2]; + $port = $matches[3]; + + $memcache = new \Memcache(); + $memcache->addserver($host, $port); + + $this->memcache = $memcache; + } + + return $this->memcache; + } + + /** + * Set instance of the Memcache. + * + * @param \Memcache $memcache + */ + public function setMemcache($memcache) + { + $this->memcache = $memcache; + } + + /** + * {@inheritdoc} + */ + protected function getValue($key) + { + return $this->getMemcache()->get($key); + } + + /** + * {@inheritdoc} + */ + protected function setValue($key, $value, $expiration = 0) + { + return $this->getMemcache()->set($key, $value, false, time() + $expiration); + } + + /** + * {@inheritdoc} + */ + protected function delete($key) + { + return $this->getMemcache()->delete($key); + } + + /** + * {@inheritdoc} + */ + protected function appendValue($key, $value, $expiration = 0) + { + $memcache = $this->getMemcache(); + + if (method_exists($memcache, 'append')) { + // Memcache v3.0 + if (!$result = $memcache->append($key, $value, false, $expiration)) { + return $memcache->set($key, $value, false, $expiration); + } + + return $result; + } + + // simulate append in Memcache <3.0 + $content = $memcache->get($key); + + return $memcache->set($key, $content.$value, false, $expiration); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Profiler/MemcachedProfilerStorage.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Profiler/MemcachedProfilerStorage.php new file mode 100644 index 0000000..0c57373 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Profiler/MemcachedProfilerStorage.php @@ -0,0 +1,103 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Profiler; + +/** + * Memcached Profiler Storage. + * + * @author Andrej Hudec + */ +class MemcachedProfilerStorage extends BaseMemcacheProfilerStorage +{ + /** + * @var \Memcached + */ + private $memcached; + + /** + * Internal convenience method that returns the instance of the Memcached. + * + * @return \Memcached + * + * @throws \RuntimeException + */ + protected function getMemcached() + { + if (null === $this->memcached) { + if (!preg_match('#^memcached://(?(?=\[.*\])\[(.*)\]|(.*)):(.*)$#', $this->dsn, $matches)) { + throw new \RuntimeException(sprintf('Please check your configuration. You are trying to use Memcached with an invalid dsn "%s". The expected format is "memcached://[host]:port".', $this->dsn)); + } + + $host = $matches[1] ?: $matches[2]; + $port = $matches[3]; + + $memcached = new \Memcached(); + + // disable compression to allow appending + $memcached->setOption(\Memcached::OPT_COMPRESSION, false); + + $memcached->addServer($host, $port); + + $this->memcached = $memcached; + } + + return $this->memcached; + } + + /** + * Set instance of the Memcached. + * + * @param \Memcached $memcached + */ + public function setMemcached($memcached) + { + $this->memcached = $memcached; + } + + /** + * {@inheritdoc} + */ + protected function getValue($key) + { + return $this->getMemcached()->get($key); + } + + /** + * {@inheritdoc} + */ + protected function setValue($key, $value, $expiration = 0) + { + return $this->getMemcached()->set($key, $value, time() + $expiration); + } + + /** + * {@inheritdoc} + */ + protected function delete($key) + { + return $this->getMemcached()->delete($key); + } + + /** + * {@inheritdoc} + */ + protected function appendValue($key, $value, $expiration = 0) + { + $memcached = $this->getMemcached(); + + if (!$result = $memcached->append($key, $value)) { + return $memcached->set($key, $value, $expiration); + } + + return $result; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Profiler/MongoDbProfilerStorage.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Profiler/MongoDbProfilerStorage.php new file mode 100644 index 0000000..f35a7f7 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Profiler/MongoDbProfilerStorage.php @@ -0,0 +1,259 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Profiler; + +class MongoDbProfilerStorage implements ProfilerStorageInterface +{ + protected $dsn; + protected $lifetime; + private $mongo; + + /** + * Constructor. + * + * @param string $dsn A data source name + * @param string $username Not used + * @param string $password Not used + * @param int $lifetime The lifetime to use for the purge + */ + public function __construct($dsn, $username = '', $password = '', $lifetime = 86400) + { + $this->dsn = $dsn; + $this->lifetime = (int) $lifetime; + } + + /** + * {@inheritdoc} + */ + public function find($ip, $url, $limit, $method, $start = null, $end = null) + { + $cursor = $this->getMongo()->find($this->buildQuery($ip, $url, $method, $start, $end), array('_id', 'parent', 'ip', 'method', 'url', 'time', 'status_code'))->sort(array('time' => -1))->limit($limit); + + $tokens = array(); + foreach ($cursor as $profile) { + $tokens[] = $this->getData($profile); + } + + return $tokens; + } + + /** + * {@inheritdoc} + */ + public function purge() + { + $this->getMongo()->remove(array()); + } + + /** + * {@inheritdoc} + */ + public function read($token) + { + $profile = $this->getMongo()->findOne(array('_id' => $token, 'data' => array('$exists' => true))); + + if (null !== $profile) { + $profile = $this->createProfileFromData($this->getData($profile)); + } + + return $profile; + } + + /** + * {@inheritdoc} + */ + public function write(Profile $profile) + { + $this->cleanup(); + + $record = array( + '_id' => $profile->getToken(), + 'parent' => $profile->getParentToken(), + 'data' => base64_encode(serialize($profile->getCollectors())), + 'ip' => $profile->getIp(), + 'method' => $profile->getMethod(), + 'url' => $profile->getUrl(), + 'time' => $profile->getTime(), + 'status_code' => $profile->getStatusCode(), + ); + + $result = $this->getMongo()->update(array('_id' => $profile->getToken()), array_filter($record, function ($v) { return !empty($v); }), array('upsert' => true)); + + return (bool) (isset($result['ok']) ? $result['ok'] : $result); + } + + /** + * Internal convenience method that returns the instance of the MongoDB Collection. + * + * @return \MongoCollection + * + * @throws \RuntimeException + */ + protected function getMongo() + { + if (null !== $this->mongo) { + return $this->mongo; + } + + if (!$parsedDsn = $this->parseDsn($this->dsn)) { + throw new \RuntimeException(sprintf('Please check your configuration. You are trying to use MongoDB with an invalid dsn "%s". The expected format is "mongodb://[user:pass@]host/database/collection"', $this->dsn)); + } + + list($server, $database, $collection) = $parsedDsn; + $mongoClass = version_compare(phpversion('mongo'), '1.3.0', '<') ? '\Mongo' : '\MongoClient'; + $mongo = new $mongoClass($server); + + return $this->mongo = $mongo->selectCollection($database, $collection); + } + + /** + * @param array $data + * + * @return Profile + */ + protected function createProfileFromData(array $data) + { + $profile = $this->getProfile($data); + + if ($data['parent']) { + $parent = $this->getMongo()->findOne(array('_id' => $data['parent'], 'data' => array('$exists' => true))); + if ($parent) { + $profile->setParent($this->getProfile($this->getData($parent))); + } + } + + $profile->setChildren($this->readChildren($data['token'])); + + return $profile; + } + + /** + * @param string $token + * + * @return Profile[] An array of Profile instances + */ + protected function readChildren($token) + { + $profiles = array(); + + $cursor = $this->getMongo()->find(array('parent' => $token, 'data' => array('$exists' => true))); + foreach ($cursor as $d) { + $profiles[] = $this->getProfile($this->getData($d)); + } + + return $profiles; + } + + protected function cleanup() + { + $this->getMongo()->remove(array('time' => array('$lt' => time() - $this->lifetime))); + } + + /** + * @param string $ip + * @param string $url + * @param string $method + * @param int $start + * @param int $end + * + * @return array + */ + private function buildQuery($ip, $url, $method, $start, $end) + { + $query = array(); + + if (!empty($ip)) { + $query['ip'] = $ip; + } + + if (!empty($url)) { + $query['url'] = $url; + } + + if (!empty($method)) { + $query['method'] = $method; + } + + if (!empty($start) || !empty($end)) { + $query['time'] = array(); + } + + if (!empty($start)) { + $query['time']['$gte'] = $start; + } + + if (!empty($end)) { + $query['time']['$lte'] = $end; + } + + return $query; + } + + /** + * @param array $data + * + * @return array + */ + private function getData(array $data) + { + return array( + 'token' => $data['_id'], + 'parent' => isset($data['parent']) ? $data['parent'] : null, + 'ip' => isset($data['ip']) ? $data['ip'] : null, + 'method' => isset($data['method']) ? $data['method'] : null, + 'url' => isset($data['url']) ? $data['url'] : null, + 'time' => isset($data['time']) ? $data['time'] : null, + 'data' => isset($data['data']) ? $data['data'] : null, + 'status_code' => isset($data['status_code']) ? $data['status_code'] : null, + ); + } + + /** + * @param array $data + * + * @return Profile + */ + private function getProfile(array $data) + { + $profile = new Profile($data['token']); + $profile->setIp($data['ip']); + $profile->setMethod($data['method']); + $profile->setUrl($data['url']); + $profile->setTime($data['time']); + $profile->setCollectors(unserialize(base64_decode($data['data']))); + + return $profile; + } + + /** + * @param string $dsn + * + * @return null|array Array($server, $database, $collection) + */ + private function parseDsn($dsn) + { + if (!preg_match('#^(mongodb://.*)/(.*)/(.*)$#', $dsn, $matches)) { + return; + } + + $server = $matches[1]; + $database = $matches[2]; + $collection = $matches[3]; + preg_match('#^mongodb://(([^:]+):?(.*)(?=@))?@?([^/]*)(.*)$#', $server, $matchesServer); + + if ('' == $matchesServer[5] && '' != $matches[2]) { + $server .= '/'.$matches[2]; + } + + return array($server, $database, $collection); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Profiler/MysqlProfilerStorage.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Profiler/MysqlProfilerStorage.php new file mode 100644 index 0000000..92e8a1b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Profiler/MysqlProfilerStorage.php @@ -0,0 +1,79 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Profiler; + +/** + * A ProfilerStorage for Mysql. + * + * @author Jan Schumann + */ +class MysqlProfilerStorage extends PdoProfilerStorage +{ + /** + * {@inheritdoc} + */ + protected function initDb() + { + if (null === $this->db) { + if (0 !== strpos($this->dsn, 'mysql')) { + throw new \RuntimeException(sprintf('Please check your configuration. You are trying to use Mysql with an invalid dsn "%s". The expected format is "mysql:dbname=database_name;host=host_name".', $this->dsn)); + } + + if (!class_exists('PDO') || !in_array('mysql', \PDO::getAvailableDrivers(), true)) { + throw new \RuntimeException('You need to enable PDO_Mysql extension for the profiler to run properly.'); + } + + $db = new \PDO($this->dsn, $this->username, $this->password); + $db->exec('CREATE TABLE IF NOT EXISTS sf_profiler_data (token VARCHAR(255) PRIMARY KEY, data LONGTEXT, ip VARCHAR(64), method VARCHAR(6), url VARCHAR(255), time INTEGER UNSIGNED, parent VARCHAR(255), created_at INTEGER UNSIGNED, status_code SMALLINT UNSIGNED, KEY (created_at), KEY (ip), KEY (method), KEY (url), KEY (parent))'); + + $this->db = $db; + } + + return $this->db; + } + + /** + * {@inheritdoc} + */ + protected function buildCriteria($ip, $url, $start, $end, $limit, $method) + { + $criteria = array(); + $args = array(); + + if ($ip = preg_replace('/[^\d\.]/', '', $ip)) { + $criteria[] = 'ip LIKE :ip'; + $args[':ip'] = '%'.$ip.'%'; + } + + if ($url) { + $criteria[] = 'url LIKE :url'; + $args[':url'] = '%'.addcslashes($url, '%_\\').'%'; + } + + if ($method) { + $criteria[] = 'method = :method'; + $args[':method'] = $method; + } + + if (!empty($start)) { + $criteria[] = 'time >= :start'; + $args[':start'] = $start; + } + + if (!empty($end)) { + $criteria[] = 'time <= :end'; + $args[':end'] = $end; + } + + return array($criteria, $args); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Profiler/PdoProfilerStorage.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Profiler/PdoProfilerStorage.php new file mode 100644 index 0000000..dc273dd --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Profiler/PdoProfilerStorage.php @@ -0,0 +1,262 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Profiler; + +/** + * Base PDO storage for profiling information in a PDO database. + * + * @author Fabien Potencier + * @author Jan Schumann + */ +abstract class PdoProfilerStorage implements ProfilerStorageInterface +{ + protected $dsn; + protected $username; + protected $password; + protected $lifetime; + protected $db; + + /** + * Constructor. + * + * @param string $dsn A data source name + * @param string $username The username for the database + * @param string $password The password for the database + * @param int $lifetime The lifetime to use for the purge + */ + public function __construct($dsn, $username = '', $password = '', $lifetime = 86400) + { + $this->dsn = $dsn; + $this->username = $username; + $this->password = $password; + $this->lifetime = (int) $lifetime; + } + + /** + * {@inheritdoc} + */ + public function find($ip, $url, $limit, $method, $start = null, $end = null) + { + if (null === $start) { + $start = 0; + } + + if (null === $end) { + $end = time(); + } + + list($criteria, $args) = $this->buildCriteria($ip, $url, $start, $end, $limit, $method); + + $criteria = $criteria ? 'WHERE '.implode(' AND ', $criteria) : ''; + + $db = $this->initDb(); + $tokens = $this->fetch($db, 'SELECT token, ip, method, url, time, parent, status_code FROM sf_profiler_data '.$criteria.' ORDER BY time DESC LIMIT '.((int) $limit), $args); + $this->close($db); + + return $tokens; + } + + /** + * {@inheritdoc} + */ + public function read($token) + { + $db = $this->initDb(); + $args = array(':token' => $token); + $data = $this->fetch($db, 'SELECT data, parent, ip, method, url, time FROM sf_profiler_data WHERE token = :token LIMIT 1', $args); + $this->close($db); + if (isset($data[0]['data'])) { + return $this->createProfileFromData($token, $data[0]); + } + } + + /** + * {@inheritdoc} + */ + public function write(Profile $profile) + { + $db = $this->initDb(); + $args = array( + ':token' => $profile->getToken(), + ':parent' => $profile->getParentToken(), + ':data' => base64_encode(serialize($profile->getCollectors())), + ':ip' => $profile->getIp(), + ':method' => $profile->getMethod(), + ':url' => $profile->getUrl(), + ':time' => $profile->getTime(), + ':created_at' => time(), + ':status_code' => $profile->getStatusCode(), + ); + + try { + if ($this->has($profile->getToken())) { + $this->exec($db, 'UPDATE sf_profiler_data SET parent = :parent, data = :data, ip = :ip, method = :method, url = :url, time = :time, created_at = :created_at, status_code = :status_code WHERE token = :token', $args); + } else { + $this->exec($db, 'INSERT INTO sf_profiler_data (token, parent, data, ip, method, url, time, created_at, status_code) VALUES (:token, :parent, :data, :ip, :method, :url, :time, :created_at, :status_code)', $args); + } + $this->cleanup(); + $status = true; + } catch (\Exception $e) { + $status = false; + } + + $this->close($db); + + return $status; + } + + /** + * {@inheritdoc} + */ + public function purge() + { + $db = $this->initDb(); + $this->exec($db, 'DELETE FROM sf_profiler_data'); + $this->close($db); + } + + /** + * Build SQL criteria to fetch records by ip and url. + * + * @param string $ip The IP + * @param string $url The URL + * @param string $start The start period to search from + * @param string $end The end period to search to + * @param string $limit The maximum number of tokens to return + * @param string $method The request method + * + * @return array An array with (criteria, args) + */ + abstract protected function buildCriteria($ip, $url, $start, $end, $limit, $method); + + /** + * Initializes the database. + * + * @throws \RuntimeException When the requested database driver is not installed + */ + abstract protected function initDb(); + + protected function cleanup() + { + $db = $this->initDb(); + $this->exec($db, 'DELETE FROM sf_profiler_data WHERE created_at < :time', array(':time' => time() - $this->lifetime)); + $this->close($db); + } + + protected function exec($db, $query, array $args = array()) + { + $stmt = $this->prepareStatement($db, $query); + + foreach ($args as $arg => $val) { + $stmt->bindValue($arg, $val, is_int($val) ? \PDO::PARAM_INT : \PDO::PARAM_STR); + } + $success = $stmt->execute(); + if (!$success) { + throw new \RuntimeException(sprintf('Error executing query "%s"', $query)); + } + } + + protected function prepareStatement($db, $query) + { + try { + $stmt = $db->prepare($query); + } catch (\Exception $e) { + $stmt = false; + } + + if (false === $stmt) { + throw new \RuntimeException('The database cannot successfully prepare the statement'); + } + + return $stmt; + } + + protected function fetch($db, $query, array $args = array()) + { + $stmt = $this->prepareStatement($db, $query); + + foreach ($args as $arg => $val) { + $stmt->bindValue($arg, $val, is_int($val) ? \PDO::PARAM_INT : \PDO::PARAM_STR); + } + $stmt->execute(); + + return $stmt->fetchAll(\PDO::FETCH_ASSOC); + } + + protected function close($db) + { + } + + protected function createProfileFromData($token, $data, $parent = null) + { + $profile = new Profile($token); + $profile->setIp($data['ip']); + $profile->setMethod($data['method']); + $profile->setUrl($data['url']); + $profile->setTime($data['time']); + $profile->setCollectors(unserialize(base64_decode($data['data']))); + + if (!$parent && !empty($data['parent'])) { + $parent = $this->read($data['parent']); + } + + if ($parent) { + $profile->setParent($parent); + } + + $profile->setChildren($this->readChildren($token, $profile)); + + return $profile; + } + + /** + * Reads the child profiles for the given token. + * + * @param string $token The parent token + * @param string $parent The parent instance + * + * @return Profile[] An array of Profile instance + */ + protected function readChildren($token, $parent) + { + $db = $this->initDb(); + $data = $this->fetch($db, 'SELECT token, data, ip, method, url, time FROM sf_profiler_data WHERE parent = :token', array(':token' => $token)); + $this->close($db); + + if (!$data) { + return array(); + } + + $profiles = array(); + foreach ($data as $d) { + $profiles[] = $this->createProfileFromData($d['token'], $d, $parent); + } + + return $profiles; + } + + /** + * Returns whether data for the given token already exists in storage. + * + * @param string $token The profile token + * + * @return string + */ + protected function has($token) + { + $db = $this->initDb(); + $tokenExists = $this->fetch($db, 'SELECT 1 FROM sf_profiler_data WHERE token = :token LIMIT 1', array(':token' => $token)); + $this->close($db); + + return !empty($tokenExists); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Profiler/Profile.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Profiler/Profile.php new file mode 100644 index 0000000..a4e4ba6 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Profiler/Profile.php @@ -0,0 +1,292 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Profiler; + +use Symfony\Component\HttpKernel\DataCollector\DataCollectorInterface; + +/** + * Profile. + * + * @author Fabien Potencier + */ +class Profile +{ + private $token; + + /** + * @var DataCollectorInterface[] + */ + private $collectors = array(); + + private $ip; + private $method; + private $url; + private $time; + private $statusCode; + + /** + * @var Profile + */ + private $parent; + + /** + * @var Profile[] + */ + private $children = array(); + + /** + * Constructor. + * + * @param string $token The token + */ + public function __construct($token) + { + $this->token = $token; + } + + /** + * Sets the token. + * + * @param string $token The token + */ + public function setToken($token) + { + $this->token = $token; + } + + /** + * Gets the token. + * + * @return string The token + */ + public function getToken() + { + return $this->token; + } + + /** + * Sets the parent token. + * + * @param Profile $parent The parent Profile + */ + public function setParent(Profile $parent) + { + $this->parent = $parent; + } + + /** + * Returns the parent profile. + * + * @return Profile The parent profile + */ + public function getParent() + { + return $this->parent; + } + + /** + * Returns the parent token. + * + * @return null|string The parent token + */ + public function getParentToken() + { + return $this->parent ? $this->parent->getToken() : null; + } + + /** + * Returns the IP. + * + * @return string The IP + */ + public function getIp() + { + return $this->ip; + } + + /** + * Sets the IP. + * + * @param string $ip + */ + public function setIp($ip) + { + $this->ip = $ip; + } + + /** + * Returns the request method. + * + * @return string The request method + */ + public function getMethod() + { + return $this->method; + } + + public function setMethod($method) + { + $this->method = $method; + } + + /** + * Returns the URL. + * + * @return string The URL + */ + public function getUrl() + { + return $this->url; + } + + public function setUrl($url) + { + $this->url = $url; + } + + /** + * Returns the time. + * + * @return string The time + */ + public function getTime() + { + if (null === $this->time) { + return 0; + } + + return $this->time; + } + + public function setTime($time) + { + $this->time = $time; + } + + /** + * @param int $statusCode + */ + public function setStatusCode($statusCode) + { + $this->statusCode = $statusCode; + } + + /** + * @return int + */ + public function getStatusCode() + { + return $this->statusCode; + } + + /** + * Finds children profilers. + * + * @return Profile[] An array of Profile + */ + public function getChildren() + { + return $this->children; + } + + /** + * Sets children profiler. + * + * @param Profile[] $children An array of Profile + */ + public function setChildren(array $children) + { + $this->children = array(); + foreach ($children as $child) { + $this->addChild($child); + } + } + + /** + * Adds the child token. + * + * @param Profile $child The child Profile + */ + public function addChild(Profile $child) + { + $this->children[] = $child; + $child->setParent($this); + } + + /** + * Gets a Collector by name. + * + * @param string $name A collector name + * + * @return DataCollectorInterface A DataCollectorInterface instance + * + * @throws \InvalidArgumentException if the collector does not exist + */ + public function getCollector($name) + { + if (!isset($this->collectors[$name])) { + throw new \InvalidArgumentException(sprintf('Collector "%s" does not exist.', $name)); + } + + return $this->collectors[$name]; + } + + /** + * Gets the Collectors associated with this profile. + * + * @return DataCollectorInterface[] + */ + public function getCollectors() + { + return $this->collectors; + } + + /** + * Sets the Collectors associated with this profile. + * + * @param DataCollectorInterface[] $collectors + */ + public function setCollectors(array $collectors) + { + $this->collectors = array(); + foreach ($collectors as $collector) { + $this->addCollector($collector); + } + } + + /** + * Adds a Collector. + * + * @param DataCollectorInterface $collector A DataCollectorInterface instance + */ + public function addCollector(DataCollectorInterface $collector) + { + $this->collectors[$collector->getName()] = $collector; + } + + /** + * Returns true if a Collector for the given name exists. + * + * @param string $name A collector name + * + * @return bool + */ + public function hasCollector($name) + { + return isset($this->collectors[$name]); + } + + public function __sleep() + { + return array('token', 'parent', 'children', 'collectors', 'ip', 'method', 'url', 'time'); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Profiler/Profiler.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Profiler/Profiler.php new file mode 100644 index 0000000..9bfc54e --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Profiler/Profiler.php @@ -0,0 +1,301 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Profiler; + +use Symfony\Component\HttpFoundation\Exception\ConflictingHeadersException; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\DataCollector\DataCollectorInterface; +use Symfony\Component\HttpKernel\DataCollector\LateDataCollectorInterface; +use Psr\Log\LoggerInterface; + +/** + * Profiler. + * + * @author Fabien Potencier + */ +class Profiler +{ + /** + * @var ProfilerStorageInterface + */ + private $storage; + + /** + * @var DataCollectorInterface[] + */ + private $collectors = array(); + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * @var bool + */ + private $enabled = true; + + /** + * Constructor. + * + * @param ProfilerStorageInterface $storage A ProfilerStorageInterface instance + * @param LoggerInterface $logger A LoggerInterface instance + */ + public function __construct(ProfilerStorageInterface $storage, LoggerInterface $logger = null) + { + $this->storage = $storage; + $this->logger = $logger; + } + + /** + * Disables the profiler. + */ + public function disable() + { + $this->enabled = false; + } + + /** + * Enables the profiler. + */ + public function enable() + { + $this->enabled = true; + } + + /** + * Loads the Profile for the given Response. + * + * @param Response $response A Response instance + * + * @return Profile|false A Profile instance + */ + public function loadProfileFromResponse(Response $response) + { + if (!$token = $response->headers->get('X-Debug-Token')) { + return false; + } + + return $this->loadProfile($token); + } + + /** + * Loads the Profile for the given token. + * + * @param string $token A token + * + * @return Profile A Profile instance + */ + public function loadProfile($token) + { + return $this->storage->read($token); + } + + /** + * Saves a Profile. + * + * @param Profile $profile A Profile instance + * + * @return bool + */ + public function saveProfile(Profile $profile) + { + // late collect + foreach ($profile->getCollectors() as $collector) { + if ($collector instanceof LateDataCollectorInterface) { + $collector->lateCollect(); + } + } + + if (!($ret = $this->storage->write($profile)) && null !== $this->logger) { + $this->logger->warning('Unable to store the profiler information.', array('configured_storage' => get_class($this->storage))); + } + + return $ret; + } + + /** + * Purges all data from the storage. + */ + public function purge() + { + $this->storage->purge(); + } + + /** + * Exports the current profiler data. + * + * @param Profile $profile A Profile instance + * + * @return string The exported data + */ + public function export(Profile $profile) + { + return base64_encode(serialize($profile)); + } + + /** + * Imports data into the profiler storage. + * + * @param string $data A data string as exported by the export() method + * + * @return Profile|false A Profile instance + */ + public function import($data) + { + $profile = unserialize(base64_decode($data)); + + if ($this->storage->read($profile->getToken())) { + return false; + } + + $this->saveProfile($profile); + + return $profile; + } + + /** + * Finds profiler tokens for the given criteria. + * + * @param string $ip The IP + * @param string $url The URL + * @param string $limit The maximum number of tokens to return + * @param string $method The request method + * @param string $start The start date to search from + * @param string $end The end date to search to + * + * @return array An array of tokens + * + * @see http://php.net/manual/en/datetime.formats.php for the supported date/time formats + */ + public function find($ip, $url, $limit, $method, $start, $end) + { + return $this->storage->find($ip, $url, $limit, $method, $this->getTimestamp($start), $this->getTimestamp($end)); + } + + /** + * Collects data for the given Response. + * + * @param Request $request A Request instance + * @param Response $response A Response instance + * @param \Exception $exception An exception instance if the request threw one + * + * @return Profile|null A Profile instance or null if the profiler is disabled + */ + public function collect(Request $request, Response $response, \Exception $exception = null) + { + if (false === $this->enabled) { + return; + } + + $profile = new Profile(substr(hash('sha256', uniqid(mt_rand(), true)), 0, 6)); + $profile->setTime(time()); + $profile->setUrl($request->getUri()); + $profile->setMethod($request->getMethod()); + $profile->setStatusCode($response->getStatusCode()); + try { + $profile->setIp($request->getClientIp()); + } catch (ConflictingHeadersException $e) { + $profile->setIp('Unknown'); + } + + $response->headers->set('X-Debug-Token', $profile->getToken()); + + foreach ($this->collectors as $collector) { + $collector->collect($request, $response, $exception); + + // we need to clone for sub-requests + $profile->addCollector(clone $collector); + } + + return $profile; + } + + /** + * Gets the Collectors associated with this profiler. + * + * @return array An array of collectors + */ + public function all() + { + return $this->collectors; + } + + /** + * Sets the Collectors associated with this profiler. + * + * @param DataCollectorInterface[] $collectors An array of collectors + */ + public function set(array $collectors = array()) + { + $this->collectors = array(); + foreach ($collectors as $collector) { + $this->add($collector); + } + } + + /** + * Adds a Collector. + * + * @param DataCollectorInterface $collector A DataCollectorInterface instance + */ + public function add(DataCollectorInterface $collector) + { + $this->collectors[$collector->getName()] = $collector; + } + + /** + * Returns true if a Collector for the given name exists. + * + * @param string $name A collector name + * + * @return bool + */ + public function has($name) + { + return isset($this->collectors[$name]); + } + + /** + * Gets a Collector by name. + * + * @param string $name A collector name + * + * @return DataCollectorInterface A DataCollectorInterface instance + * + * @throws \InvalidArgumentException if the collector does not exist + */ + public function get($name) + { + if (!isset($this->collectors[$name])) { + throw new \InvalidArgumentException(sprintf('Collector "%s" does not exist.', $name)); + } + + return $this->collectors[$name]; + } + + private function getTimestamp($value) + { + if (null === $value || '' == $value) { + return; + } + + try { + $value = new \DateTime(is_numeric($value) ? '@'.$value : $value); + } catch (\Exception $e) { + return; + } + + return $value->getTimestamp(); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Profiler/ProfilerStorageInterface.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Profiler/ProfilerStorageInterface.php new file mode 100644 index 0000000..ea72af2 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Profiler/ProfilerStorageInterface.php @@ -0,0 +1,59 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Profiler; + +/** + * ProfilerStorageInterface. + * + * @author Fabien Potencier + */ +interface ProfilerStorageInterface +{ + /** + * Finds profiler tokens for the given criteria. + * + * @param string $ip The IP + * @param string $url The URL + * @param string $limit The maximum number of tokens to return + * @param string $method The request method + * @param int|null $start The start date to search from + * @param int|null $end The end date to search to + * + * @return array An array of tokens + */ + public function find($ip, $url, $limit, $method, $start = null, $end = null); + + /** + * Reads data associated with the given token. + * + * The method returns false if the token does not exist in the storage. + * + * @param string $token A token + * + * @return Profile The profile associated with token + */ + public function read($token); + + /** + * Saves a Profile. + * + * @param Profile $profile A Profile instance + * + * @return bool Write operation successful + */ + public function write(Profile $profile); + + /** + * Purges all data from the database. + */ + public function purge(); +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Profiler/RedisProfilerStorage.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Profiler/RedisProfilerStorage.php new file mode 100644 index 0000000..b0e14ea --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Profiler/RedisProfilerStorage.php @@ -0,0 +1,394 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Profiler; + +/** + * RedisProfilerStorage stores profiling information in Redis. + * + * @author Andrej Hudec + * @author Stephane PY + */ +class RedisProfilerStorage implements ProfilerStorageInterface +{ + const TOKEN_PREFIX = 'sf_profiler_'; + + const REDIS_OPT_SERIALIZER = 1; + const REDIS_OPT_PREFIX = 2; + const REDIS_SERIALIZER_NONE = 0; + const REDIS_SERIALIZER_PHP = 1; + + protected $dsn; + protected $lifetime; + + /** + * @var \Redis + */ + private $redis; + + /** + * Constructor. + * + * @param string $dsn A data source name + * @param string $username Not used + * @param string $password Not used + * @param int $lifetime The lifetime to use for the purge + */ + public function __construct($dsn, $username = '', $password = '', $lifetime = 86400) + { + $this->dsn = $dsn; + $this->lifetime = (int) $lifetime; + } + + /** + * {@inheritdoc} + */ + public function find($ip, $url, $limit, $method, $start = null, $end = null) + { + $indexName = $this->getIndexName(); + + if (!$indexContent = $this->getValue($indexName, self::REDIS_SERIALIZER_NONE)) { + return array(); + } + + $profileList = array_reverse(explode("\n", $indexContent)); + $result = array(); + + foreach ($profileList as $item) { + if ($limit === 0) { + break; + } + + if ($item == '') { + continue; + } + + $values = explode("\t", $item, 7); + list($itemToken, $itemIp, $itemMethod, $itemUrl, $itemTime, $itemParent) = $values; + $statusCode = isset($values[6]) ? $values[6] : null; + + $itemTime = (int) $itemTime; + + if ($ip && false === strpos($itemIp, $ip) || $url && false === strpos($itemUrl, $url) || $method && false === strpos($itemMethod, $method)) { + continue; + } + + if (!empty($start) && $itemTime < $start) { + continue; + } + + if (!empty($end) && $itemTime > $end) { + continue; + } + + $result[] = array( + 'token' => $itemToken, + 'ip' => $itemIp, + 'method' => $itemMethod, + 'url' => $itemUrl, + 'time' => $itemTime, + 'parent' => $itemParent, + 'status_code' => $statusCode, + ); + --$limit; + } + + return $result; + } + + /** + * {@inheritdoc} + */ + public function purge() + { + // delete only items from index + $indexName = $this->getIndexName(); + + $indexContent = $this->getValue($indexName, self::REDIS_SERIALIZER_NONE); + + if (!$indexContent) { + return false; + } + + $profileList = explode("\n", $indexContent); + + $result = array(); + + foreach ($profileList as $item) { + if ($item == '') { + continue; + } + + if (false !== $pos = strpos($item, "\t")) { + $result[] = $this->getItemName(substr($item, 0, $pos)); + } + } + + $result[] = $indexName; + + return $this->delete($result); + } + + /** + * {@inheritdoc} + */ + public function read($token) + { + if (empty($token)) { + return false; + } + + $profile = $this->getValue($this->getItemName($token), self::REDIS_SERIALIZER_PHP); + + if (false !== $profile) { + $profile = $this->createProfileFromData($token, $profile); + } + + return $profile; + } + + /** + * {@inheritdoc} + */ + public function write(Profile $profile) + { + $data = array( + 'token' => $profile->getToken(), + 'parent' => $profile->getParentToken(), + 'children' => array_map(function ($p) { return $p->getToken(); }, $profile->getChildren()), + 'data' => $profile->getCollectors(), + 'ip' => $profile->getIp(), + 'method' => $profile->getMethod(), + 'url' => $profile->getUrl(), + 'time' => $profile->getTime(), + ); + + $profileIndexed = false !== $this->getValue($this->getItemName($profile->getToken())); + + if ($this->setValue($this->getItemName($profile->getToken()), $data, $this->lifetime, self::REDIS_SERIALIZER_PHP)) { + if (!$profileIndexed) { + // Add to index + $indexName = $this->getIndexName(); + + $indexRow = implode("\t", array( + $profile->getToken(), + $profile->getIp(), + $profile->getMethod(), + $profile->getUrl(), + $profile->getTime(), + $profile->getParentToken(), + $profile->getStatusCode(), + ))."\n"; + + return $this->appendValue($indexName, $indexRow, $this->lifetime); + } + + return true; + } + + return false; + } + + /** + * Internal convenience method that returns the instance of Redis. + * + * @return \Redis + * + * @throws \RuntimeException + */ + protected function getRedis() + { + if (null === $this->redis) { + $data = parse_url($this->dsn); + + if (false === $data || !isset($data['scheme']) || $data['scheme'] !== 'redis' || !isset($data['host']) || !isset($data['port'])) { + throw new \RuntimeException(sprintf('Please check your configuration. You are trying to use Redis with an invalid dsn "%s". The minimal expected format is "redis://[host]:port".', $this->dsn)); + } + + if (!extension_loaded('redis')) { + throw new \RuntimeException('RedisProfilerStorage requires that the redis extension is loaded.'); + } + + $redis = new \Redis(); + $redis->connect($data['host'], $data['port']); + + if (isset($data['path'])) { + $redis->select(substr($data['path'], 1)); + } + + if (isset($data['pass'])) { + $redis->auth($data['pass']); + } + + $redis->setOption(self::REDIS_OPT_PREFIX, self::TOKEN_PREFIX); + + $this->redis = $redis; + } + + return $this->redis; + } + + /** + * Set instance of the Redis. + * + * @param \Redis $redis + */ + public function setRedis($redis) + { + $this->redis = $redis; + } + + private function createProfileFromData($token, $data, $parent = null) + { + $profile = new Profile($token); + $profile->setIp($data['ip']); + $profile->setMethod($data['method']); + $profile->setUrl($data['url']); + $profile->setTime($data['time']); + $profile->setCollectors($data['data']); + + if (!$parent && $data['parent']) { + $parent = $this->read($data['parent']); + } + + if ($parent) { + $profile->setParent($parent); + } + + foreach ($data['children'] as $token) { + if (!$token) { + continue; + } + + if (!$childProfileData = $this->getValue($this->getItemName($token), self::REDIS_SERIALIZER_PHP)) { + continue; + } + + $profile->addChild($this->createProfileFromData($token, $childProfileData, $profile)); + } + + return $profile; + } + + /** + * Gets the item name. + * + * @param string $token + * + * @return string + */ + private function getItemName($token) + { + $name = $token; + + if ($this->isItemNameValid($name)) { + return $name; + } + + return false; + } + + /** + * Gets the name of the index. + * + * @return string + */ + private function getIndexName() + { + $name = 'index'; + + if ($this->isItemNameValid($name)) { + return $name; + } + + return false; + } + + private function isItemNameValid($name) + { + $length = strlen($name); + + if ($length > 2147483648) { + throw new \RuntimeException(sprintf('The Redis item key "%s" is too long (%s bytes). Allowed maximum size is 2^31 bytes.', $name, $length)); + } + + return true; + } + + /** + * Retrieves an item from the Redis server. + * + * @param string $key + * @param int $serializer + * + * @return mixed + */ + private function getValue($key, $serializer = self::REDIS_SERIALIZER_NONE) + { + $redis = $this->getRedis(); + $redis->setOption(self::REDIS_OPT_SERIALIZER, $serializer); + + return $redis->get($key); + } + + /** + * Stores an item on the Redis server under the specified key. + * + * @param string $key + * @param mixed $value + * @param int $expiration + * @param int $serializer + * + * @return bool + */ + private function setValue($key, $value, $expiration = 0, $serializer = self::REDIS_SERIALIZER_NONE) + { + $redis = $this->getRedis(); + $redis->setOption(self::REDIS_OPT_SERIALIZER, $serializer); + + return $redis->setex($key, $expiration, $value); + } + + /** + * Appends data to an existing item on the Redis server. + * + * @param string $key + * @param string $value + * @param int $expiration + * + * @return bool + */ + private function appendValue($key, $value, $expiration = 0) + { + $redis = $this->getRedis(); + $redis->setOption(self::REDIS_OPT_SERIALIZER, self::REDIS_SERIALIZER_NONE); + + if ($redis->exists($key)) { + $redis->append($key, $value); + + return $redis->setTimeout($key, $expiration); + } + + return $redis->setex($key, $expiration, $value); + } + + /** + * Removes the specified keys. + * + * @param array $keys + * + * @return bool + */ + private function delete(array $keys) + { + return (bool) $this->getRedis()->delete($keys); + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Profiler/SqliteProfilerStorage.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Profiler/SqliteProfilerStorage.php new file mode 100644 index 0000000..6e0a173 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/Profiler/SqliteProfilerStorage.php @@ -0,0 +1,139 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Profiler; + +/** + * SqliteProfilerStorage stores profiling information in a SQLite database. + * + * @author Fabien Potencier + */ +class SqliteProfilerStorage extends PdoProfilerStorage +{ + /** + * @throws \RuntimeException When neither of SQLite3 or PDO_SQLite extension is enabled + */ + protected function initDb() + { + if (null === $this->db || $this->db instanceof \SQLite3) { + if (0 !== strpos($this->dsn, 'sqlite')) { + throw new \RuntimeException(sprintf('Please check your configuration. You are trying to use Sqlite with an invalid dsn "%s". The expected format is "sqlite:/path/to/the/db/file".', $this->dsn)); + } + if (class_exists('SQLite3')) { + $db = new \SQLite3(substr($this->dsn, 7, strlen($this->dsn)), \SQLITE3_OPEN_READWRITE | \SQLITE3_OPEN_CREATE); + if (method_exists($db, 'busyTimeout')) { + // busyTimeout only exists for PHP >= 5.3.3 + $db->busyTimeout(1000); + } + } elseif (class_exists('PDO') && in_array('sqlite', \PDO::getAvailableDrivers(), true)) { + $db = new \PDO($this->dsn); + } else { + throw new \RuntimeException('You need to enable either the SQLite3 or PDO_SQLite extension for the profiler to run properly.'); + } + + $db->exec('PRAGMA temp_store=MEMORY; PRAGMA journal_mode=MEMORY;'); + $db->exec('CREATE TABLE IF NOT EXISTS sf_profiler_data (token STRING, data STRING, ip STRING, method STRING, url STRING, time INTEGER, parent STRING, created_at INTEGER, status_code INTEGER)'); + $db->exec('CREATE INDEX IF NOT EXISTS data_created_at ON sf_profiler_data (created_at)'); + $db->exec('CREATE INDEX IF NOT EXISTS data_ip ON sf_profiler_data (ip)'); + $db->exec('CREATE INDEX IF NOT EXISTS data_method ON sf_profiler_data (method)'); + $db->exec('CREATE INDEX IF NOT EXISTS data_url ON sf_profiler_data (url)'); + $db->exec('CREATE INDEX IF NOT EXISTS data_parent ON sf_profiler_data (parent)'); + $db->exec('CREATE UNIQUE INDEX IF NOT EXISTS data_token ON sf_profiler_data (token)'); + + $this->db = $db; + } + + return $this->db; + } + + protected function exec($db, $query, array $args = array()) + { + if ($db instanceof \SQLite3) { + $stmt = $this->prepareStatement($db, $query); + foreach ($args as $arg => $val) { + $stmt->bindValue($arg, $val, is_int($val) ? \SQLITE3_INTEGER : \SQLITE3_TEXT); + } + + $res = $stmt->execute(); + if (false === $res) { + throw new \RuntimeException(sprintf('Error executing SQLite query "%s"', $query)); + } + $res->finalize(); + } else { + parent::exec($db, $query, $args); + } + } + + protected function fetch($db, $query, array $args = array()) + { + $return = array(); + + if ($db instanceof \SQLite3) { + $stmt = $this->prepareStatement($db, $query); + foreach ($args as $arg => $val) { + $stmt->bindValue($arg, $val, is_int($val) ? \SQLITE3_INTEGER : \SQLITE3_TEXT); + } + $res = $stmt->execute(); + while ($row = $res->fetchArray(\SQLITE3_ASSOC)) { + $return[] = $row; + } + $res->finalize(); + $stmt->close(); + } else { + $return = parent::fetch($db, $query, $args); + } + + return $return; + } + + /** + * {@inheritdoc} + */ + protected function buildCriteria($ip, $url, $start, $end, $limit, $method) + { + $criteria = array(); + $args = array(); + + if ($ip = preg_replace('/[^\d\.]/', '', $ip)) { + $criteria[] = 'ip LIKE :ip'; + $args[':ip'] = '%'.$ip.'%'; + } + + if ($url) { + $criteria[] = 'url LIKE :url ESCAPE "\"'; + $args[':url'] = '%'.addcslashes($url, '%_\\').'%'; + } + + if ($method) { + $criteria[] = 'method = :method'; + $args[':method'] = $method; + } + + if (!empty($start)) { + $criteria[] = 'time >= :start'; + $args[':start'] = $start; + } + + if (!empty($end)) { + $criteria[] = 'time <= :end'; + $args[':end'] = $end; + } + + return array($criteria, $args); + } + + protected function close($db) + { + if ($db instanceof \SQLite3) { + $db->close(); + } + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/TerminableInterface.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/TerminableInterface.php new file mode 100644 index 0000000..d55a15b --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/TerminableInterface.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; + +/** + * Terminable extends the Kernel request/response cycle with dispatching a post + * response event after sending the response and before shutting down the kernel. + * + * @author Jordi Boggiano + * @author Pierre Minnieur + */ +interface TerminableInterface +{ + /** + * Terminates a request/response cycle. + * + * Should be called after sending the response and before shutting down the kernel. + * + * @param Request $request A Request instance + * @param Response $response A Response instance + */ + public function terminate(Request $request, Response $response); +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/UriSigner.php b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/UriSigner.php new file mode 100644 index 0000000..fa84899 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/http-kernel/UriSigner.php @@ -0,0 +1,109 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel; + +/** + * Signs URIs. + * + * @author Fabien Potencier + */ +class UriSigner +{ + private $secret; + + /** + * Constructor. + * + * @param string $secret A secret + */ + public function __construct($secret) + { + $this->secret = $secret; + } + + /** + * Signs a URI. + * + * The given URI is signed by adding a _hash query string parameter + * which value depends on the URI and the secret. + * + * @param string $uri A URI to sign + * + * @return string The signed URI + */ + public function sign($uri) + { + $url = parse_url($uri); + if (isset($url['query'])) { + parse_str($url['query'], $params); + } else { + $params = array(); + } + + $uri = $this->buildUrl($url, $params); + + return $uri.(false === strpos($uri, '?') ? '?' : '&').'_hash='.$this->computeHash($uri); + } + + /** + * Checks that a URI contains the correct hash. + * + * The _hash query string parameter must be the last one + * (as it is generated that way by the sign() method, it should + * never be a problem). + * + * @param string $uri A signed URI + * + * @return bool True if the URI is signed correctly, false otherwise + */ + public function check($uri) + { + $url = parse_url($uri); + if (isset($url['query'])) { + parse_str($url['query'], $params); + } else { + $params = array(); + } + + if (empty($params['_hash'])) { + return false; + } + + $hash = urlencode($params['_hash']); + unset($params['_hash']); + + return $this->computeHash($this->buildUrl($url, $params)) === $hash; + } + + private function computeHash($uri) + { + return urlencode(base64_encode(hash_hmac('sha256', $uri, $this->secret, true))); + } + + private function buildUrl(array $url, array $params = array()) + { + ksort($params, SORT_STRING); + $url['query'] = http_build_query($params, '', '&'); + + $scheme = isset($url['scheme']) ? $url['scheme'].'://' : ''; + $host = isset($url['host']) ? $url['host'] : ''; + $port = isset($url['port']) ? ':'.$url['port'] : ''; + $user = isset($url['user']) ? $url['user'] : ''; + $pass = isset($url['pass']) ? ':'.$url['pass'] : ''; + $pass = ($user || $pass) ? "$pass@" : ''; + $path = isset($url['path']) ? $url['path'] : ''; + $query = isset($url['query']) && $url['query'] ? '?'.$url['query'] : ''; + $fragment = isset($url['fragment']) ? '#'.$url['fragment'] : ''; + + return $scheme.$user.$pass.$host.$port.$path.$query.$fragment; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/polyfill-mbstring/Mbstring.php b/lib/ckfinder/core/connector/php/vendor/symfony/polyfill-mbstring/Mbstring.php new file mode 100644 index 0000000..934cfcf --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/polyfill-mbstring/Mbstring.php @@ -0,0 +1,650 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Polyfill\Mbstring; + +/** + * Partial mbstring implementation in PHP, iconv based, UTF-8 centric. + * + * Implemented: + * - mb_chr - Returns a specific character from its Unicode code point + * - mb_convert_encoding - Convert character encoding + * - mb_convert_variables - Convert character code in variable(s) + * - mb_decode_mimeheader - Decode string in MIME header field + * - mb_encode_mimeheader - Encode string for MIME header XXX NATIVE IMPLEMENTATION IS REALLY BUGGED + * - mb_convert_case - Perform case folding on a string + * - mb_get_info - Get internal settings of mbstring + * - mb_http_input - Detect HTTP input character encoding + * - mb_http_output - Set/Get HTTP output character encoding + * - mb_internal_encoding - Set/Get internal character encoding + * - mb_list_encodings - Returns an array of all supported encodings + * - mb_ord - Returns the Unicode code point of a character + * - mb_output_handler - Callback function converts character encoding in output buffer + * - mb_scrub - Replaces ill-formed byte sequences with substitute characters + * - mb_strlen - Get string length + * - mb_strpos - Find position of first occurrence of string in a string + * - mb_strrpos - Find position of last occurrence of a string in a string + * - mb_strtolower - Make a string lowercase + * - mb_strtoupper - Make a string uppercase + * - mb_substitute_character - Set/Get substitution character + * - mb_substr - Get part of string + * - mb_stripos - Finds position of first occurrence of a string within another, case insensitive + * - mb_stristr - Finds first occurrence of a string within another, case insensitive + * - mb_strrchr - Finds the last occurrence of a character in a string within another + * - mb_strrichr - Finds the last occurrence of a character in a string within another, case insensitive + * - mb_strripos - Finds position of last occurrence of a string within another, case insensitive + * - mb_strstr - Finds first occurrence of a string within anothers + * - mb_strwidth - Return width of string + * - mb_substr_count - Count the number of substring occurrences + * + * Not implemented: + * - mb_convert_kana - Convert "kana" one from another ("zen-kaku", "han-kaku" and more) + * - mb_decode_numericentity - Decode HTML numeric string reference to character + * - mb_encode_numericentity - Encode character to HTML numeric string reference + * - mb_ereg_* - Regular expression with multibyte support + * - mb_parse_str - Parse GET/POST/COOKIE data and set global variable + * - mb_preferred_mime_name - Get MIME charset string + * - mb_regex_encoding - Returns current encoding for multibyte regex as string + * - mb_regex_set_options - Set/Get the default options for mbregex functions + * - mb_send_mail - Send encoded mail + * - mb_split - Split multibyte string using regular expression + * - mb_strcut - Get part of string + * - mb_strimwidth - Get truncated string with specified width + * + * @author Nicolas Grekas + * + * @internal + */ +final class Mbstring +{ + const MB_CASE_FOLD = PHP_INT_MAX; + + private static $encodingList = array('ASCII', 'UTF-8'); + private static $language = 'neutral'; + private static $internalEncoding = 'UTF-8'; + private static $caseFold = array( + array('µ','ſ',"\xCD\x85",'ς',"\xCF\x90","\xCF\x91","\xCF\x95","\xCF\x96","\xCF\xB0","\xCF\xB1","\xCF\xB5","\xE1\xBA\x9B","\xE1\xBE\xBE"), + array('μ','s','ι', 'σ','β', 'θ', 'φ', 'π', 'κ', 'ρ', 'ε', "\xE1\xB9\xA1",'ι'), + ); + + public static function mb_convert_encoding($s, $toEncoding, $fromEncoding = null) + { + if (is_array($fromEncoding) || false !== strpos($fromEncoding, ',')) { + $fromEncoding = self::mb_detect_encoding($s, $fromEncoding); + } else { + $fromEncoding = self::getEncoding($fromEncoding); + } + + $toEncoding = self::getEncoding($toEncoding); + + if ('BASE64' === $fromEncoding) { + $s = base64_decode($s); + $fromEncoding = $toEncoding; + } + + if ('BASE64' === $toEncoding) { + return base64_encode($s); + } + + if ('HTML-ENTITIES' === $toEncoding || 'HTML' === $toEncoding) { + if ('HTML-ENTITIES' === $fromEncoding || 'HTML' === $fromEncoding) { + $fromEncoding = 'Windows-1252'; + } + if ('UTF-8' !== $fromEncoding) { + $s = iconv($fromEncoding, 'UTF-8//IGNORE', $s); + } + + return preg_replace_callback('/[\x80-\xFF]+/', array(__CLASS__, 'html_encoding_callback'), $s); + } + + if ('HTML-ENTITIES' === $fromEncoding) { + $s = html_entity_decode($s, ENT_COMPAT, 'UTF-8'); + $fromEncoding = 'UTF-8'; + } + + return iconv($fromEncoding, $toEncoding.'//IGNORE', $s); + } + + public static function mb_convert_variables($toEncoding, $fromEncoding, &$a = null, &$b = null, &$c = null, &$d = null, &$e = null, &$f = null) + { + $vars = array(&$a, &$b, &$c, &$d, &$e, &$f); + + $ok = true; + array_walk_recursive($vars, function (&$v) use (&$ok, $toEncoding, $fromEncoding) { + if (false === $v = Mbstring::mb_convert_encoding($v, $toEncoding, $fromEncoding)) { + $ok = false; + } + }); + + return $ok ? $fromEncoding : false; + } + + public static function mb_decode_mimeheader($s) + { + return iconv_mime_decode($s, 2, self::$internalEncoding); + } + + public static function mb_encode_mimeheader($s, $charset = null, $transferEncoding = null, $linefeed = null, $indent = null) + { + trigger_error('mb_encode_mimeheader() is bugged. Please use iconv_mime_encode() instead', E_USER_WARNING); + } + + public static function mb_convert_case($s, $mode, $encoding = null) + { + if ('' === $s .= '') { + return ''; + } + + $encoding = self::getEncoding($encoding); + + if ('UTF-8' === $encoding) { + $encoding = null; + } else { + $s = iconv($encoding, 'UTF-8//IGNORE', $s); + } + + if (MB_CASE_TITLE == $mode) { + $s = preg_replace_callback('/\b\p{Ll}/u', array(__CLASS__, 'title_case_upper'), $s); + $s = preg_replace_callback('/\B[\p{Lu}\p{Lt}]+/u', array(__CLASS__, 'title_case_lower'), $s); + } else { + if (MB_CASE_UPPER == $mode) { + static $upper = null; + if (null === $upper) { + $upper = self::getData('upperCase'); + } + $map = $upper; + } else { + if (self::MB_CASE_FOLD === $mode) { + $s = str_replace(self::$caseFold[0], self::$caseFold[1], $s); + } + + static $lower = null; + if (null === $lower) { + $lower = self::getData('lowerCase'); + } + $map = $lower; + } + + static $ulenMask = array("\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4); + + $i = 0; + $len = strlen($s); + + while ($i < $len) { + $ulen = $s[$i] < "\x80" ? 1 : $ulenMask[$s[$i] & "\xF0"]; + $uchr = substr($s, $i, $ulen); + $i += $ulen; + + if (isset($map[$uchr])) { + $uchr = $map[$uchr]; + $nlen = strlen($uchr); + + if ($nlen == $ulen) { + $nlen = $i; + do { + $s[--$nlen] = $uchr[--$ulen]; + } while ($ulen); + } else { + $s = substr_replace($s, $uchr, $i - $ulen, $ulen); + $len += $nlen - $ulen; + $i += $nlen - $ulen; + } + } + } + } + + if (null === $encoding) { + return $s; + } + + return iconv('UTF-8', $encoding.'//IGNORE', $s); + } + + public static function mb_internal_encoding($encoding = null) + { + if (null === $encoding) { + return self::$internalEncoding; + } + + $encoding = self::getEncoding($encoding); + + if ('UTF-8' === $encoding || false !== @iconv($encoding, $encoding, ' ')) { + self::$internalEncoding = $encoding; + + return true; + } + + return false; + } + + public static function mb_language($lang = null) + { + if (null === $lang) { + return self::$language; + } + + switch ($lang = strtolower($lang)) { + case 'uni': + case 'neutral': + self::$language = $lang; + + return true; + } + + return false; + } + + public static function mb_list_encodings() + { + return array('UTF-8'); + } + + public static function mb_encoding_aliases($encoding) + { + switch (strtoupper($encoding)) { + case 'UTF8': + case 'UTF-8': + return array('utf8'); + } + + return false; + } + + public static function mb_check_encoding($var = null, $encoding = null) + { + if (null === $encoding) { + if (null === $var) { + return false; + } + $encoding = self::$internalEncoding; + } + + return self::mb_detect_encoding($var, array($encoding)) || false !== @iconv($encoding, $encoding, $var); + } + + public static function mb_detect_encoding($str, $encodingList = null, $strict = false) + { + if (null === $encodingList) { + $encodingList = self::$encodingList; + } else { + if (!is_array($encodingList)) { + $encodingList = array_map('trim', explode(',', $encodingList)); + } + $encodingList = array_map('strtoupper', $encodingList); + } + + foreach ($encodingList as $enc) { + switch ($enc) { + case 'ASCII': + if (!preg_match('/[\x80-\xFF]/', $str)) { + return $enc; + } + break; + + case 'UTF8': + case 'UTF-8': + if (preg_match('//u', $str)) { + return 'UTF-8'; + } + break; + + default: + if (0 === strncmp($enc, 'ISO-8859-', 9)) { + return $enc; + } + } + } + + return false; + } + + public static function mb_detect_order($encodingList = null) + { + if (null === $encodingList) { + return self::$encodingList; + } + + if (!is_array($encodingList)) { + $encodingList = array_map('trim', explode(',', $encodingList)); + } + $encodingList = array_map('strtoupper', $encodingList); + + foreach ($encodingList as $enc) { + switch ($enc) { + default: + if (strncmp($enc, 'ISO-8859-', 9)) { + return false; + } + case 'ASCII': + case 'UTF8': + case 'UTF-8': + } + } + + self::$encodingList = $encodingList; + + return true; + } + + public static function mb_strlen($s, $encoding = null) + { + switch ($encoding = self::getEncoding($encoding)) { + case 'ASCII': + case 'CP850': + return strlen($s); + } + + return @iconv_strlen($s, $encoding); + } + + public static function mb_strpos($haystack, $needle, $offset = 0, $encoding = null) + { + $encoding = self::getEncoding($encoding); + + if ('' === $needle .= '') { + trigger_error(__METHOD__.': Empty delimiter', E_USER_WARNING); + + return false; + } + + return iconv_strpos($haystack, $needle, $offset, $encoding); + } + + public static function mb_strrpos($haystack, $needle, $offset = 0, $encoding = null) + { + $encoding = self::getEncoding($encoding); + + if ($offset != (int) $offset) { + $offset = 0; + } elseif ($offset = (int) $offset) { + if ($offset < 0) { + $haystack = self::mb_substr($haystack, 0, $offset, $encoding); + $offset = 0; + } else { + $haystack = self::mb_substr($haystack, $offset, 2147483647, $encoding); + } + } + + $pos = iconv_strrpos($haystack, $needle, $encoding); + + return false !== $pos ? $offset + $pos : false; + } + + public static function mb_strtolower($s, $encoding = null) + { + return self::mb_convert_case($s, MB_CASE_LOWER, $encoding); + } + + public static function mb_strtoupper($s, $encoding = null) + { + return self::mb_convert_case($s, MB_CASE_UPPER, $encoding); + } + + public static function mb_substitute_character($c = null) + { + if (0 === strcasecmp($c, 'none')) { + return true; + } + + return null !== $c ? false : 'none'; + } + + public static function mb_substr($s, $start, $length = null, $encoding = null) + { + $encoding = self::getEncoding($encoding); + + if ($start < 0) { + $start = iconv_strlen($s, $encoding) + $start; + if ($start < 0) { + $start = 0; + } + } + + if (null === $length) { + $length = 2147483647; + } elseif ($length < 0) { + $length = iconv_strlen($s, $encoding) + $length - $start; + if ($length < 0) { + return ''; + } + } + + return iconv_substr($s, $start, $length, $encoding).''; + } + + public static function mb_stripos($haystack, $needle, $offset = 0, $encoding = null) + { + $haystack = self::mb_convert_case($haystack, self::MB_CASE_FOLD, $encoding); + $needle = self::mb_convert_case($needle, self::MB_CASE_FOLD, $encoding); + + return self::mb_strpos($haystack, $needle, $offset, $encoding); + } + + public static function mb_stristr($haystack, $needle, $part = false, $encoding = null) + { + $pos = self::mb_stripos($haystack, $needle, 0, $encoding); + + return self::getSubpart($pos, $part, $haystack, $encoding); + } + + public static function mb_strrchr($haystack, $needle, $part = false, $encoding = null) + { + $encoding = self::getEncoding($encoding); + $needle = self::mb_substr($needle, 0, 1, $encoding); + $pos = iconv_strrpos($haystack, $needle, $encoding); + + return self::getSubpart($pos, $part, $haystack, $encoding); + } + + public static function mb_strrichr($haystack, $needle, $part = false, $encoding = null) + { + $needle = self::mb_substr($needle, 0, 1, $encoding); + $pos = self::mb_strripos($haystack, $needle, $encoding); + + return self::getSubpart($pos, $part, $haystack, $encoding); + } + + public static function mb_strripos($haystack, $needle, $offset = 0, $encoding = null) + { + $haystack = self::mb_convert_case($haystack, self::MB_CASE_FOLD, $encoding); + $needle = self::mb_convert_case($needle, self::MB_CASE_FOLD, $encoding); + + return self::mb_strrpos($haystack, $needle, $offset, $encoding); + } + + public static function mb_strstr($haystack, $needle, $part = false, $encoding = null) + { + $pos = strpos($haystack, $needle); + if (false === $pos) { + return false; + } + if ($part) { + return substr($haystack, 0, $pos); + } + + return substr($haystack, $pos); + } + + public static function mb_get_info($type = 'all') + { + $info = array( + 'internal_encoding' => self::$internalEncoding, + 'http_output' => 'pass', + 'http_output_conv_mimetypes' => '^(text/|application/xhtml\+xml)', + 'func_overload' => 0, + 'func_overload_list' => 'no overload', + 'mail_charset' => 'UTF-8', + 'mail_header_encoding' => 'BASE64', + 'mail_body_encoding' => 'BASE64', + 'illegal_chars' => 0, + 'encoding_translation' => 'Off', + 'language' => self::$language, + 'detect_order' => self::$encodingList, + 'substitute_character' => 'none', + 'strict_detection' => 'Off', + ); + + if ('all' === $type) { + return $info; + } + if (isset($info[$type])) { + return $info[$type]; + } + + return false; + } + + public static function mb_http_input($type = '') + { + return false; + } + + public static function mb_http_output($encoding = null) + { + return null !== $encoding ? 'pass' === $encoding : 'pass'; + } + + public static function mb_strwidth($s, $encoding = null) + { + $encoding = self::getEncoding($encoding); + + if ('UTF-8' !== $encoding) { + $s = iconv($encoding, 'UTF-8//IGNORE', $s); + } + + $s = preg_replace('/[\x{1100}-\x{115F}\x{2329}\x{232A}\x{2E80}-\x{303E}\x{3040}-\x{A4CF}\x{AC00}-\x{D7A3}\x{F900}-\x{FAFF}\x{FE10}-\x{FE19}\x{FE30}-\x{FE6F}\x{FF00}-\x{FF60}\x{FFE0}-\x{FFE6}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}]/u', '', $s, -1, $wide); + + return ($wide << 1) + iconv_strlen($s, 'UTF-8'); + } + + public static function mb_substr_count($haystack, $needle, $encoding = null) + { + return substr_count($haystack, $needle); + } + + public static function mb_output_handler($contents, $status) + { + return $contents; + } + + public static function mb_chr($code, $encoding = null) + { + if (0x80 > $code %= 0x200000) { + $s = chr($code); + } elseif (0x800 > $code) { + $s = chr(0xC0 | $code >> 6).chr(0x80 | $code & 0x3F); + } elseif (0x10000 > $code) { + $s = chr(0xE0 | $code >> 12).chr(0x80 | $code >> 6 & 0x3F).chr(0x80 | $code & 0x3F); + } else { + $s = chr(0xF0 | $code >> 18).chr(0x80 | $code >> 12 & 0x3F).chr(0x80 | $code >> 6 & 0x3F).chr(0x80 | $code & 0x3F); + } + + if ('UTF-8' !== $encoding = self::getEncoding($encoding)) { + $s = mb_convert_encoding($s, $encoding, 'UTF-8'); + } + + return $s; + } + + public static function mb_ord($s, $encoding = null) + { + if ('UTF-8' !== $encoding = self::getEncoding($encoding)) { + $s = mb_convert_encoding($s, 'UTF-8', $encoding); + } + + $code = ($s = unpack('C*', substr($s, 0, 4))) ? $s[1] : 0; + if (0xF0 <= $code) { + return (($code - 0xF0) << 18) + (($s[2] - 0x80) << 12) + (($s[3] - 0x80) << 6) + $s[4] - 0x80; + } + if (0xE0 <= $code) { + return (($code - 0xE0) << 12) + (($s[2] - 0x80) << 6) + $s[3] - 0x80; + } + if (0xC0 <= $code) { + return (($code - 0xC0) << 6) + $s[2] - 0x80; + } + + return $code; + } + + private static function getSubpart($pos, $part, $haystack, $encoding) + { + if (false === $pos) { + return false; + } + if ($part) { + return self::mb_substr($haystack, 0, $pos, $encoding); + } + + return self::mb_substr($haystack, $pos, null, $encoding); + } + + private static function html_encoding_callback($m) + { + $i = 1; + $entities = ''; + $m = unpack('C*', htmlentities($m[0], ENT_COMPAT, 'UTF-8')); + + while (isset($m[$i])) { + if (0x80 > $m[$i]) { + $entities .= chr($m[$i++]); + continue; + } + if (0xF0 <= $m[$i]) { + $c = (($m[$i++] - 0xF0) << 18) + (($m[$i++] - 0x80) << 12) + (($m[$i++] - 0x80) << 6) + $m[$i++] - 0x80; + } elseif (0xE0 <= $m[$i]) { + $c = (($m[$i++] - 0xE0) << 12) + (($m[$i++] - 0x80) << 6) + $m[$i++] - 0x80; + } else { + $c = (($m[$i++] - 0xC0) << 6) + $m[$i++] - 0x80; + } + + $entities .= '&#'.$c.';'; + } + + return $entities; + } + + private static function title_case_lower($s) + { + return self::mb_convert_case($s[0], MB_CASE_LOWER, 'UTF-8'); + } + + private static function title_case_upper($s) + { + return self::mb_convert_case($s[0], MB_CASE_UPPER, 'UTF-8'); + } + + private static function getData($file) + { + if (file_exists($file = __DIR__.'/Resources/unidata/'.$file.'.php')) { + return require $file; + } + + return false; + } + + private static function getEncoding($encoding) + { + if (null === $encoding) { + return self::$internalEncoding; + } + + $encoding = strtoupper($encoding); + + if ('8BIT' === $encoding || 'BINARY' === $encoding) { + return 'CP850'; + } + if ('UTF8' === $encoding) { + return 'UTF-8'; + } + + return $encoding; + } +} diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php b/lib/ckfinder/core/connector/php/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php new file mode 100644 index 0000000..3ca1641 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php @@ -0,0 +1,1101 @@ + 'a', + 'B' => 'b', + 'C' => 'c', + 'D' => 'd', + 'E' => 'e', + 'F' => 'f', + 'G' => 'g', + 'H' => 'h', + 'I' => 'i', + 'J' => 'j', + 'K' => 'k', + 'L' => 'l', + 'M' => 'm', + 'N' => 'n', + 'O' => 'o', + 'P' => 'p', + 'Q' => 'q', + 'R' => 'r', + 'S' => 's', + 'T' => 't', + 'U' => 'u', + 'V' => 'v', + 'W' => 'w', + 'X' => 'x', + 'Y' => 'y', + 'Z' => 'z', + 'À' => 'à', + 'Á' => 'á', + 'Â' => 'â', + 'Ã' => 'ã', + 'Ä' => 'ä', + 'Å' => 'å', + 'Æ' => 'æ', + 'Ç' => 'ç', + 'È' => 'è', + 'É' => 'é', + 'Ê' => 'ê', + 'Ë' => 'ë', + 'Ì' => 'ì', + 'Í' => 'í', + 'Î' => 'î', + 'Ï' => 'ï', + 'Ð' => 'ð', + 'Ñ' => 'ñ', + 'Ò' => 'ò', + 'Ó' => 'ó', + 'Ô' => 'ô', + 'Õ' => 'õ', + 'Ö' => 'ö', + 'Ø' => 'ø', + 'Ù' => 'ù', + 'Ú' => 'ú', + 'Û' => 'û', + 'Ü' => 'ü', + 'Ý' => 'ý', + 'Þ' => 'þ', + 'Ā' => 'ā', + 'Ă' => 'ă', + 'Ą' => 'ą', + 'Ć' => 'ć', + 'Ĉ' => 'ĉ', + 'Ċ' => 'ċ', + 'Č' => 'č', + 'Ď' => 'ď', + 'Đ' => 'đ', + 'Ē' => 'ē', + 'Ĕ' => 'ĕ', + 'Ė' => 'ė', + 'Ę' => 'ę', + 'Ě' => 'ě', + 'Ĝ' => 'ĝ', + 'Ğ' => 'ğ', + 'Ġ' => 'ġ', + 'Ģ' => 'ģ', + 'Ĥ' => 'ĥ', + 'Ħ' => 'ħ', + 'Ĩ' => 'ĩ', + 'Ī' => 'ī', + 'Ĭ' => 'ĭ', + 'Į' => 'į', + 'İ' => 'i', + 'IJ' => 'ij', + 'Ĵ' => 'ĵ', + 'Ķ' => 'ķ', + 'Ĺ' => 'ĺ', + 'Ļ' => 'ļ', + 'Ľ' => 'ľ', + 'Ŀ' => 'ŀ', + 'Ł' => 'ł', + 'Ń' => 'ń', + 'Ņ' => 'ņ', + 'Ň' => 'ň', + 'Ŋ' => 'ŋ', + 'Ō' => 'ō', + 'Ŏ' => 'ŏ', + 'Ő' => 'ő', + 'Œ' => 'œ', + 'Ŕ' => 'ŕ', + 'Ŗ' => 'ŗ', + 'Ř' => 'ř', + 'Ś' => 'ś', + 'Ŝ' => 'ŝ', + 'Ş' => 'ş', + 'Š' => 'š', + 'Ţ' => 'ţ', + 'Ť' => 'ť', + 'Ŧ' => 'ŧ', + 'Ũ' => 'ũ', + 'Ū' => 'ū', + 'Ŭ' => 'ŭ', + 'Ů' => 'ů', + 'Ű' => 'ű', + 'Ų' => 'ų', + 'Ŵ' => 'ŵ', + 'Ŷ' => 'ŷ', + 'Ÿ' => 'ÿ', + 'Ź' => 'ź', + 'Ż' => 'ż', + 'Ž' => 'ž', + 'Ɓ' => 'ɓ', + 'Ƃ' => 'ƃ', + 'Ƅ' => 'ƅ', + 'Ɔ' => 'ɔ', + 'Ƈ' => 'ƈ', + 'Ɖ' => 'ɖ', + 'Ɗ' => 'ɗ', + 'Ƌ' => 'ƌ', + 'Ǝ' => 'ǝ', + 'Ə' => 'ə', + 'Ɛ' => 'ɛ', + 'Ƒ' => 'ƒ', + 'Ɠ' => 'ɠ', + 'Ɣ' => 'ɣ', + 'Ɩ' => 'ɩ', + 'Ɨ' => 'ɨ', + 'Ƙ' => 'ƙ', + 'Ɯ' => 'ɯ', + 'Ɲ' => 'ɲ', + 'Ɵ' => 'ɵ', + 'Ơ' => 'ơ', + 'Ƣ' => 'ƣ', + 'Ƥ' => 'ƥ', + 'Ʀ' => 'ʀ', + 'Ƨ' => 'ƨ', + 'Ʃ' => 'ʃ', + 'Ƭ' => 'ƭ', + 'Ʈ' => 'ʈ', + 'Ư' => 'ư', + 'Ʊ' => 'ʊ', + 'Ʋ' => 'ʋ', + 'Ƴ' => 'ƴ', + 'Ƶ' => 'ƶ', + 'Ʒ' => 'ʒ', + 'Ƹ' => 'ƹ', + 'Ƽ' => 'ƽ', + 'DŽ' => 'dž', + 'Dž' => 'dž', + 'LJ' => 'lj', + 'Lj' => 'lj', + 'NJ' => 'nj', + 'Nj' => 'nj', + 'Ǎ' => 'ǎ', + 'Ǐ' => 'ǐ', + 'Ǒ' => 'ǒ', + 'Ǔ' => 'ǔ', + 'Ǖ' => 'ǖ', + 'Ǘ' => 'ǘ', + 'Ǚ' => 'ǚ', + 'Ǜ' => 'ǜ', + 'Ǟ' => 'ǟ', + 'Ǡ' => 'ǡ', + 'Ǣ' => 'ǣ', + 'Ǥ' => 'ǥ', + 'Ǧ' => 'ǧ', + 'Ǩ' => 'ǩ', + 'Ǫ' => 'ǫ', + 'Ǭ' => 'ǭ', + 'Ǯ' => 'ǯ', + 'DZ' => 'dz', + 'Dz' => 'dz', + 'Ǵ' => 'ǵ', + 'Ƕ' => 'ƕ', + 'Ƿ' => 'ƿ', + 'Ǹ' => 'ǹ', + 'Ǻ' => 'ǻ', + 'Ǽ' => 'ǽ', + 'Ǿ' => 'ǿ', + 'Ȁ' => 'ȁ', + 'Ȃ' => 'ȃ', + 'Ȅ' => 'ȅ', + 'Ȇ' => 'ȇ', + 'Ȉ' => 'ȉ', + 'Ȋ' => 'ȋ', + 'Ȍ' => 'ȍ', + 'Ȏ' => 'ȏ', + 'Ȑ' => 'ȑ', + 'Ȓ' => 'ȓ', + 'Ȕ' => 'ȕ', + 'Ȗ' => 'ȗ', + 'Ș' => 'ș', + 'Ț' => 'ț', + 'Ȝ' => 'ȝ', + 'Ȟ' => 'ȟ', + 'Ƞ' => 'ƞ', + 'Ȣ' => 'ȣ', + 'Ȥ' => 'ȥ', + 'Ȧ' => 'ȧ', + 'Ȩ' => 'ȩ', + 'Ȫ' => 'ȫ', + 'Ȭ' => 'ȭ', + 'Ȯ' => 'ȯ', + 'Ȱ' => 'ȱ', + 'Ȳ' => 'ȳ', + 'Ⱥ' => 'ⱥ', + 'Ȼ' => 'ȼ', + 'Ƚ' => 'ƚ', + 'Ⱦ' => 'ⱦ', + 'Ɂ' => 'ɂ', + 'Ƀ' => 'ƀ', + 'Ʉ' => 'ʉ', + 'Ʌ' => 'ʌ', + 'Ɇ' => 'ɇ', + 'Ɉ' => 'ɉ', + 'Ɋ' => 'ɋ', + 'Ɍ' => 'ɍ', + 'Ɏ' => 'ɏ', + 'Ͱ' => 'ͱ', + 'Ͳ' => 'ͳ', + 'Ͷ' => 'ͷ', + 'Ϳ' => 'ϳ', + 'Ά' => 'ά', + 'Έ' => 'έ', + 'Ή' => 'ή', + 'Ί' => 'ί', + 'Ό' => 'ό', + 'Ύ' => 'ύ', + 'Ώ' => 'ώ', + 'Α' => 'α', + 'Β' => 'β', + 'Γ' => 'γ', + 'Δ' => 'δ', + 'Ε' => 'ε', + 'Ζ' => 'ζ', + 'Η' => 'η', + 'Θ' => 'θ', + 'Ι' => 'ι', + 'Κ' => 'κ', + 'Λ' => 'λ', + 'Μ' => 'μ', + 'Ν' => 'ν', + 'Ξ' => 'ξ', + 'Ο' => 'ο', + 'Π' => 'π', + 'Ρ' => 'ρ', + 'Σ' => 'σ', + 'Τ' => 'τ', + 'Υ' => 'υ', + 'Φ' => 'φ', + 'Χ' => 'χ', + 'Ψ' => 'ψ', + 'Ω' => 'ω', + 'Ϊ' => 'ϊ', + 'Ϋ' => 'ϋ', + 'Ϗ' => 'ϗ', + 'Ϙ' => 'ϙ', + 'Ϛ' => 'ϛ', + 'Ϝ' => 'ϝ', + 'Ϟ' => 'ϟ', + 'Ϡ' => 'ϡ', + 'Ϣ' => 'ϣ', + 'Ϥ' => 'ϥ', + 'Ϧ' => 'ϧ', + 'Ϩ' => 'ϩ', + 'Ϫ' => 'ϫ', + 'Ϭ' => 'ϭ', + 'Ϯ' => 'ϯ', + 'ϴ' => 'θ', + 'Ϸ' => 'ϸ', + 'Ϲ' => 'ϲ', + 'Ϻ' => 'ϻ', + 'Ͻ' => 'ͻ', + 'Ͼ' => 'ͼ', + 'Ͽ' => 'ͽ', + 'Ѐ' => 'ѐ', + 'Ё' => 'ё', + 'Ђ' => 'ђ', + 'Ѓ' => 'ѓ', + 'Є' => 'є', + 'Ѕ' => 'ѕ', + 'І' => 'і', + 'Ї' => 'ї', + 'Ј' => 'ј', + 'Љ' => 'љ', + 'Њ' => 'њ', + 'Ћ' => 'ћ', + 'Ќ' => 'ќ', + 'Ѝ' => 'ѝ', + 'Ў' => 'ў', + 'Џ' => 'џ', + 'А' => 'а', + 'Б' => 'б', + 'В' => 'в', + 'Г' => 'г', + 'Д' => 'д', + 'Е' => 'е', + 'Ж' => 'ж', + 'З' => 'з', + 'И' => 'и', + 'Й' => 'й', + 'К' => 'к', + 'Л' => 'л', + 'М' => 'м', + 'Н' => 'н', + 'О' => 'о', + 'П' => 'п', + 'Р' => 'р', + 'С' => 'с', + 'Т' => 'т', + 'У' => 'у', + 'Ф' => 'ф', + 'Х' => 'х', + 'Ц' => 'ц', + 'Ч' => 'ч', + 'Ш' => 'ш', + 'Щ' => 'щ', + 'Ъ' => 'ъ', + 'Ы' => 'ы', + 'Ь' => 'ь', + 'Э' => 'э', + 'Ю' => 'ю', + 'Я' => 'я', + 'Ѡ' => 'ѡ', + 'Ѣ' => 'ѣ', + 'Ѥ' => 'ѥ', + 'Ѧ' => 'ѧ', + 'Ѩ' => 'ѩ', + 'Ѫ' => 'ѫ', + 'Ѭ' => 'ѭ', + 'Ѯ' => 'ѯ', + 'Ѱ' => 'ѱ', + 'Ѳ' => 'ѳ', + 'Ѵ' => 'ѵ', + 'Ѷ' => 'ѷ', + 'Ѹ' => 'ѹ', + 'Ѻ' => 'ѻ', + 'Ѽ' => 'ѽ', + 'Ѿ' => 'ѿ', + 'Ҁ' => 'ҁ', + 'Ҋ' => 'ҋ', + 'Ҍ' => 'ҍ', + 'Ҏ' => 'ҏ', + 'Ґ' => 'ґ', + 'Ғ' => 'ғ', + 'Ҕ' => 'ҕ', + 'Җ' => 'җ', + 'Ҙ' => 'ҙ', + 'Қ' => 'қ', + 'Ҝ' => 'ҝ', + 'Ҟ' => 'ҟ', + 'Ҡ' => 'ҡ', + 'Ң' => 'ң', + 'Ҥ' => 'ҥ', + 'Ҧ' => 'ҧ', + 'Ҩ' => 'ҩ', + 'Ҫ' => 'ҫ', + 'Ҭ' => 'ҭ', + 'Ү' => 'ү', + 'Ұ' => 'ұ', + 'Ҳ' => 'ҳ', + 'Ҵ' => 'ҵ', + 'Ҷ' => 'ҷ', + 'Ҹ' => 'ҹ', + 'Һ' => 'һ', + 'Ҽ' => 'ҽ', + 'Ҿ' => 'ҿ', + 'Ӏ' => 'ӏ', + 'Ӂ' => 'ӂ', + 'Ӄ' => 'ӄ', + 'Ӆ' => 'ӆ', + 'Ӈ' => 'ӈ', + 'Ӊ' => 'ӊ', + 'Ӌ' => 'ӌ', + 'Ӎ' => 'ӎ', + 'Ӑ' => 'ӑ', + 'Ӓ' => 'ӓ', + 'Ӕ' => 'ӕ', + 'Ӗ' => 'ӗ', + 'Ә' => 'ә', + 'Ӛ' => 'ӛ', + 'Ӝ' => 'ӝ', + 'Ӟ' => 'ӟ', + 'Ӡ' => 'ӡ', + 'Ӣ' => 'ӣ', + 'Ӥ' => 'ӥ', + 'Ӧ' => 'ӧ', + 'Ө' => 'ө', + 'Ӫ' => 'ӫ', + 'Ӭ' => 'ӭ', + 'Ӯ' => 'ӯ', + 'Ӱ' => 'ӱ', + 'Ӳ' => 'ӳ', + 'Ӵ' => 'ӵ', + 'Ӷ' => 'ӷ', + 'Ӹ' => 'ӹ', + 'Ӻ' => 'ӻ', + 'Ӽ' => 'ӽ', + 'Ӿ' => 'ӿ', + 'Ԁ' => 'ԁ', + 'Ԃ' => 'ԃ', + 'Ԅ' => 'ԅ', + 'Ԇ' => 'ԇ', + 'Ԉ' => 'ԉ', + 'Ԋ' => 'ԋ', + 'Ԍ' => 'ԍ', + 'Ԏ' => 'ԏ', + 'Ԑ' => 'ԑ', + 'Ԓ' => 'ԓ', + 'Ԕ' => 'ԕ', + 'Ԗ' => 'ԗ', + 'Ԙ' => 'ԙ', + 'Ԛ' => 'ԛ', + 'Ԝ' => 'ԝ', + 'Ԟ' => 'ԟ', + 'Ԡ' => 'ԡ', + 'Ԣ' => 'ԣ', + 'Ԥ' => 'ԥ', + 'Ԧ' => 'ԧ', + 'Ԩ' => 'ԩ', + 'Ԫ' => 'ԫ', + 'Ԭ' => 'ԭ', + 'Ԯ' => 'ԯ', + 'Ա' => 'ա', + 'Բ' => 'բ', + 'Գ' => 'գ', + 'Դ' => 'դ', + 'Ե' => 'ե', + 'Զ' => 'զ', + 'Է' => 'է', + 'Ը' => 'ը', + 'Թ' => 'թ', + 'Ժ' => 'ժ', + 'Ի' => 'ի', + 'Լ' => 'լ', + 'Խ' => 'խ', + 'Ծ' => 'ծ', + 'Կ' => 'կ', + 'Հ' => 'հ', + 'Ձ' => 'ձ', + 'Ղ' => 'ղ', + 'Ճ' => 'ճ', + 'Մ' => 'մ', + 'Յ' => 'յ', + 'Ն' => 'ն', + 'Շ' => 'շ', + 'Ո' => 'ո', + 'Չ' => 'չ', + 'Պ' => 'պ', + 'Ջ' => 'ջ', + 'Ռ' => 'ռ', + 'Ս' => 'ս', + 'Վ' => 'վ', + 'Տ' => 'տ', + 'Ր' => 'ր', + 'Ց' => 'ց', + 'Ւ' => 'ւ', + 'Փ' => 'փ', + 'Ք' => 'ք', + 'Օ' => 'օ', + 'Ֆ' => 'ֆ', + 'Ⴀ' => 'ⴀ', + 'Ⴁ' => 'ⴁ', + 'Ⴂ' => 'ⴂ', + 'Ⴃ' => 'ⴃ', + 'Ⴄ' => 'ⴄ', + 'Ⴅ' => 'ⴅ', + 'Ⴆ' => 'ⴆ', + 'Ⴇ' => 'ⴇ', + 'Ⴈ' => 'ⴈ', + 'Ⴉ' => 'ⴉ', + 'Ⴊ' => 'ⴊ', + 'Ⴋ' => 'ⴋ', + 'Ⴌ' => 'ⴌ', + 'Ⴍ' => 'ⴍ', + 'Ⴎ' => 'ⴎ', + 'Ⴏ' => 'ⴏ', + 'Ⴐ' => 'ⴐ', + 'Ⴑ' => 'ⴑ', + 'Ⴒ' => 'ⴒ', + 'Ⴓ' => 'ⴓ', + 'Ⴔ' => 'ⴔ', + 'Ⴕ' => 'ⴕ', + 'Ⴖ' => 'ⴖ', + 'Ⴗ' => 'ⴗ', + 'Ⴘ' => 'ⴘ', + 'Ⴙ' => 'ⴙ', + 'Ⴚ' => 'ⴚ', + 'Ⴛ' => 'ⴛ', + 'Ⴜ' => 'ⴜ', + 'Ⴝ' => 'ⴝ', + 'Ⴞ' => 'ⴞ', + 'Ⴟ' => 'ⴟ', + 'Ⴠ' => 'ⴠ', + 'Ⴡ' => 'ⴡ', + 'Ⴢ' => 'ⴢ', + 'Ⴣ' => 'ⴣ', + 'Ⴤ' => 'ⴤ', + 'Ⴥ' => 'ⴥ', + 'Ⴧ' => 'ⴧ', + 'Ⴭ' => 'ⴭ', + 'Ḁ' => 'ḁ', + 'Ḃ' => 'ḃ', + 'Ḅ' => 'ḅ', + 'Ḇ' => 'ḇ', + 'Ḉ' => 'ḉ', + 'Ḋ' => 'ḋ', + 'Ḍ' => 'ḍ', + 'Ḏ' => 'ḏ', + 'Ḑ' => 'ḑ', + 'Ḓ' => 'ḓ', + 'Ḕ' => 'ḕ', + 'Ḗ' => 'ḗ', + 'Ḙ' => 'ḙ', + 'Ḛ' => 'ḛ', + 'Ḝ' => 'ḝ', + 'Ḟ' => 'ḟ', + 'Ḡ' => 'ḡ', + 'Ḣ' => 'ḣ', + 'Ḥ' => 'ḥ', + 'Ḧ' => 'ḧ', + 'Ḩ' => 'ḩ', + 'Ḫ' => 'ḫ', + 'Ḭ' => 'ḭ', + 'Ḯ' => 'ḯ', + 'Ḱ' => 'ḱ', + 'Ḳ' => 'ḳ', + 'Ḵ' => 'ḵ', + 'Ḷ' => 'ḷ', + 'Ḹ' => 'ḹ', + 'Ḻ' => 'ḻ', + 'Ḽ' => 'ḽ', + 'Ḿ' => 'ḿ', + 'Ṁ' => 'ṁ', + 'Ṃ' => 'ṃ', + 'Ṅ' => 'ṅ', + 'Ṇ' => 'ṇ', + 'Ṉ' => 'ṉ', + 'Ṋ' => 'ṋ', + 'Ṍ' => 'ṍ', + 'Ṏ' => 'ṏ', + 'Ṑ' => 'ṑ', + 'Ṓ' => 'ṓ', + 'Ṕ' => 'ṕ', + 'Ṗ' => 'ṗ', + 'Ṙ' => 'ṙ', + 'Ṛ' => 'ṛ', + 'Ṝ' => 'ṝ', + 'Ṟ' => 'ṟ', + 'Ṡ' => 'ṡ', + 'Ṣ' => 'ṣ', + 'Ṥ' => 'ṥ', + 'Ṧ' => 'ṧ', + 'Ṩ' => 'ṩ', + 'Ṫ' => 'ṫ', + 'Ṭ' => 'ṭ', + 'Ṯ' => 'ṯ', + 'Ṱ' => 'ṱ', + 'Ṳ' => 'ṳ', + 'Ṵ' => 'ṵ', + 'Ṷ' => 'ṷ', + 'Ṹ' => 'ṹ', + 'Ṻ' => 'ṻ', + 'Ṽ' => 'ṽ', + 'Ṿ' => 'ṿ', + 'Ẁ' => 'ẁ', + 'Ẃ' => 'ẃ', + 'Ẅ' => 'ẅ', + 'Ẇ' => 'ẇ', + 'Ẉ' => 'ẉ', + 'Ẋ' => 'ẋ', + 'Ẍ' => 'ẍ', + 'Ẏ' => 'ẏ', + 'Ẑ' => 'ẑ', + 'Ẓ' => 'ẓ', + 'Ẕ' => 'ẕ', + 'ẞ' => 'ß', + 'Ạ' => 'ạ', + 'Ả' => 'ả', + 'Ấ' => 'ấ', + 'Ầ' => 'ầ', + 'Ẩ' => 'ẩ', + 'Ẫ' => 'ẫ', + 'Ậ' => 'ậ', + 'Ắ' => 'ắ', + 'Ằ' => 'ằ', + 'Ẳ' => 'ẳ', + 'Ẵ' => 'ẵ', + 'Ặ' => 'ặ', + 'Ẹ' => 'ẹ', + 'Ẻ' => 'ẻ', + 'Ẽ' => 'ẽ', + 'Ế' => 'ế', + 'Ề' => 'ề', + 'Ể' => 'ể', + 'Ễ' => 'ễ', + 'Ệ' => 'ệ', + 'Ỉ' => 'ỉ', + 'Ị' => 'ị', + 'Ọ' => 'ọ', + 'Ỏ' => 'ỏ', + 'Ố' => 'ố', + 'Ồ' => 'ồ', + 'Ổ' => 'ổ', + 'Ỗ' => 'ỗ', + 'Ộ' => 'ộ', + 'Ớ' => 'ớ', + 'Ờ' => 'ờ', + 'Ở' => 'ở', + 'Ỡ' => 'ỡ', + 'Ợ' => 'ợ', + 'Ụ' => 'ụ', + 'Ủ' => 'ủ', + 'Ứ' => 'ứ', + 'Ừ' => 'ừ', + 'Ử' => 'ử', + 'Ữ' => 'ữ', + 'Ự' => 'ự', + 'Ỳ' => 'ỳ', + 'Ỵ' => 'ỵ', + 'Ỷ' => 'ỷ', + 'Ỹ' => 'ỹ', + 'Ỻ' => 'ỻ', + 'Ỽ' => 'ỽ', + 'Ỿ' => 'ỿ', + 'Ἀ' => 'ἀ', + 'Ἁ' => 'ἁ', + 'Ἂ' => 'ἂ', + 'Ἃ' => 'ἃ', + 'Ἄ' => 'ἄ', + 'Ἅ' => 'ἅ', + 'Ἆ' => 'ἆ', + 'Ἇ' => 'ἇ', + 'Ἐ' => 'ἐ', + 'Ἑ' => 'ἑ', + 'Ἒ' => 'ἒ', + 'Ἓ' => 'ἓ', + 'Ἔ' => 'ἔ', + 'Ἕ' => 'ἕ', + 'Ἠ' => 'ἠ', + 'Ἡ' => 'ἡ', + 'Ἢ' => 'ἢ', + 'Ἣ' => 'ἣ', + 'Ἤ' => 'ἤ', + 'Ἥ' => 'ἥ', + 'Ἦ' => 'ἦ', + 'Ἧ' => 'ἧ', + 'Ἰ' => 'ἰ', + 'Ἱ' => 'ἱ', + 'Ἲ' => 'ἲ', + 'Ἳ' => 'ἳ', + 'Ἴ' => 'ἴ', + 'Ἵ' => 'ἵ', + 'Ἶ' => 'ἶ', + 'Ἷ' => 'ἷ', + 'Ὀ' => 'ὀ', + 'Ὁ' => 'ὁ', + 'Ὂ' => 'ὂ', + 'Ὃ' => 'ὃ', + 'Ὄ' => 'ὄ', + 'Ὅ' => 'ὅ', + 'Ὑ' => 'ὑ', + 'Ὓ' => 'ὓ', + 'Ὕ' => 'ὕ', + 'Ὗ' => 'ὗ', + 'Ὠ' => 'ὠ', + 'Ὡ' => 'ὡ', + 'Ὢ' => 'ὢ', + 'Ὣ' => 'ὣ', + 'Ὤ' => 'ὤ', + 'Ὥ' => 'ὥ', + 'Ὦ' => 'ὦ', + 'Ὧ' => 'ὧ', + 'ᾈ' => 'ᾀ', + 'ᾉ' => 'ᾁ', + 'ᾊ' => 'ᾂ', + 'ᾋ' => 'ᾃ', + 'ᾌ' => 'ᾄ', + 'ᾍ' => 'ᾅ', + 'ᾎ' => 'ᾆ', + 'ᾏ' => 'ᾇ', + 'ᾘ' => 'ᾐ', + 'ᾙ' => 'ᾑ', + 'ᾚ' => 'ᾒ', + 'ᾛ' => 'ᾓ', + 'ᾜ' => 'ᾔ', + 'ᾝ' => 'ᾕ', + 'ᾞ' => 'ᾖ', + 'ᾟ' => 'ᾗ', + 'ᾨ' => 'ᾠ', + 'ᾩ' => 'ᾡ', + 'ᾪ' => 'ᾢ', + 'ᾫ' => 'ᾣ', + 'ᾬ' => 'ᾤ', + 'ᾭ' => 'ᾥ', + 'ᾮ' => 'ᾦ', + 'ᾯ' => 'ᾧ', + 'Ᾰ' => 'ᾰ', + 'Ᾱ' => 'ᾱ', + 'Ὰ' => 'ὰ', + 'Ά' => 'ά', + 'ᾼ' => 'ᾳ', + 'Ὲ' => 'ὲ', + 'Έ' => 'έ', + 'Ὴ' => 'ὴ', + 'Ή' => 'ή', + 'ῌ' => 'ῃ', + 'Ῐ' => 'ῐ', + 'Ῑ' => 'ῑ', + 'Ὶ' => 'ὶ', + 'Ί' => 'ί', + 'Ῠ' => 'ῠ', + 'Ῡ' => 'ῡ', + 'Ὺ' => 'ὺ', + 'Ύ' => 'ύ', + 'Ῥ' => 'ῥ', + 'Ὸ' => 'ὸ', + 'Ό' => 'ό', + 'Ὼ' => 'ὼ', + 'Ώ' => 'ώ', + 'ῼ' => 'ῳ', + 'Ω' => 'ω', + 'K' => 'k', + 'Å' => 'å', + 'Ⅎ' => 'ⅎ', + 'Ⅰ' => 'ⅰ', + 'Ⅱ' => 'ⅱ', + 'Ⅲ' => 'ⅲ', + 'Ⅳ' => 'ⅳ', + 'Ⅴ' => 'ⅴ', + 'Ⅵ' => 'ⅵ', + 'Ⅶ' => 'ⅶ', + 'Ⅷ' => 'ⅷ', + 'Ⅸ' => 'ⅸ', + 'Ⅹ' => 'ⅹ', + 'Ⅺ' => 'ⅺ', + 'Ⅻ' => 'ⅻ', + 'Ⅼ' => 'ⅼ', + 'Ⅽ' => 'ⅽ', + 'Ⅾ' => 'ⅾ', + 'Ⅿ' => 'ⅿ', + 'Ↄ' => 'ↄ', + 'Ⓐ' => 'ⓐ', + 'Ⓑ' => 'ⓑ', + 'Ⓒ' => 'ⓒ', + 'Ⓓ' => 'ⓓ', + 'Ⓔ' => 'ⓔ', + 'Ⓕ' => 'ⓕ', + 'Ⓖ' => 'ⓖ', + 'Ⓗ' => 'ⓗ', + 'Ⓘ' => 'ⓘ', + 'Ⓙ' => 'ⓙ', + 'Ⓚ' => 'ⓚ', + 'Ⓛ' => 'ⓛ', + 'Ⓜ' => 'ⓜ', + 'Ⓝ' => 'ⓝ', + 'Ⓞ' => 'ⓞ', + 'Ⓟ' => 'ⓟ', + 'Ⓠ' => 'ⓠ', + 'Ⓡ' => 'ⓡ', + 'Ⓢ' => 'ⓢ', + 'Ⓣ' => 'ⓣ', + 'Ⓤ' => 'ⓤ', + 'Ⓥ' => 'ⓥ', + 'Ⓦ' => 'ⓦ', + 'Ⓧ' => 'ⓧ', + 'Ⓨ' => 'ⓨ', + 'Ⓩ' => 'ⓩ', + 'Ⰰ' => 'ⰰ', + 'Ⰱ' => 'ⰱ', + 'Ⰲ' => 'ⰲ', + 'Ⰳ' => 'ⰳ', + 'Ⰴ' => 'ⰴ', + 'Ⰵ' => 'ⰵ', + 'Ⰶ' => 'ⰶ', + 'Ⰷ' => 'ⰷ', + 'Ⰸ' => 'ⰸ', + 'Ⰹ' => 'ⰹ', + 'Ⰺ' => 'ⰺ', + 'Ⰻ' => 'ⰻ', + 'Ⰼ' => 'ⰼ', + 'Ⰽ' => 'ⰽ', + 'Ⰾ' => 'ⰾ', + 'Ⰿ' => 'ⰿ', + 'Ⱀ' => 'ⱀ', + 'Ⱁ' => 'ⱁ', + 'Ⱂ' => 'ⱂ', + 'Ⱃ' => 'ⱃ', + 'Ⱄ' => 'ⱄ', + 'Ⱅ' => 'ⱅ', + 'Ⱆ' => 'ⱆ', + 'Ⱇ' => 'ⱇ', + 'Ⱈ' => 'ⱈ', + 'Ⱉ' => 'ⱉ', + 'Ⱊ' => 'ⱊ', + 'Ⱋ' => 'ⱋ', + 'Ⱌ' => 'ⱌ', + 'Ⱍ' => 'ⱍ', + 'Ⱎ' => 'ⱎ', + 'Ⱏ' => 'ⱏ', + 'Ⱐ' => 'ⱐ', + 'Ⱑ' => 'ⱑ', + 'Ⱒ' => 'ⱒ', + 'Ⱓ' => 'ⱓ', + 'Ⱔ' => 'ⱔ', + 'Ⱕ' => 'ⱕ', + 'Ⱖ' => 'ⱖ', + 'Ⱗ' => 'ⱗ', + 'Ⱘ' => 'ⱘ', + 'Ⱙ' => 'ⱙ', + 'Ⱚ' => 'ⱚ', + 'Ⱛ' => 'ⱛ', + 'Ⱜ' => 'ⱜ', + 'Ⱝ' => 'ⱝ', + 'Ⱞ' => 'ⱞ', + 'Ⱡ' => 'ⱡ', + 'Ɫ' => 'ɫ', + 'Ᵽ' => 'ᵽ', + 'Ɽ' => 'ɽ', + 'Ⱨ' => 'ⱨ', + 'Ⱪ' => 'ⱪ', + 'Ⱬ' => 'ⱬ', + 'Ɑ' => 'ɑ', + 'Ɱ' => 'ɱ', + 'Ɐ' => 'ɐ', + 'Ɒ' => 'ɒ', + 'Ⱳ' => 'ⱳ', + 'Ⱶ' => 'ⱶ', + 'Ȿ' => 'ȿ', + 'Ɀ' => 'ɀ', + 'Ⲁ' => 'ⲁ', + 'Ⲃ' => 'ⲃ', + 'Ⲅ' => 'ⲅ', + 'Ⲇ' => 'ⲇ', + 'Ⲉ' => 'ⲉ', + 'Ⲋ' => 'ⲋ', + 'Ⲍ' => 'ⲍ', + 'Ⲏ' => 'ⲏ', + 'Ⲑ' => 'ⲑ', + 'Ⲓ' => 'ⲓ', + 'Ⲕ' => 'ⲕ', + 'Ⲗ' => 'ⲗ', + 'Ⲙ' => 'ⲙ', + 'Ⲛ' => 'ⲛ', + 'Ⲝ' => 'ⲝ', + 'Ⲟ' => 'ⲟ', + 'Ⲡ' => 'ⲡ', + 'Ⲣ' => 'ⲣ', + 'Ⲥ' => 'ⲥ', + 'Ⲧ' => 'ⲧ', + 'Ⲩ' => 'ⲩ', + 'Ⲫ' => 'ⲫ', + 'Ⲭ' => 'ⲭ', + 'Ⲯ' => 'ⲯ', + 'Ⲱ' => 'ⲱ', + 'Ⲳ' => 'ⲳ', + 'Ⲵ' => 'ⲵ', + 'Ⲷ' => 'ⲷ', + 'Ⲹ' => 'ⲹ', + 'Ⲻ' => 'ⲻ', + 'Ⲽ' => 'ⲽ', + 'Ⲿ' => 'ⲿ', + 'Ⳁ' => 'ⳁ', + 'Ⳃ' => 'ⳃ', + 'Ⳅ' => 'ⳅ', + 'Ⳇ' => 'ⳇ', + 'Ⳉ' => 'ⳉ', + 'Ⳋ' => 'ⳋ', + 'Ⳍ' => 'ⳍ', + 'Ⳏ' => 'ⳏ', + 'Ⳑ' => 'ⳑ', + 'Ⳓ' => 'ⳓ', + 'Ⳕ' => 'ⳕ', + 'Ⳗ' => 'ⳗ', + 'Ⳙ' => 'ⳙ', + 'Ⳛ' => 'ⳛ', + 'Ⳝ' => 'ⳝ', + 'Ⳟ' => 'ⳟ', + 'Ⳡ' => 'ⳡ', + 'Ⳣ' => 'ⳣ', + 'Ⳬ' => 'ⳬ', + 'Ⳮ' => 'ⳮ', + 'Ⳳ' => 'ⳳ', + 'Ꙁ' => 'ꙁ', + 'Ꙃ' => 'ꙃ', + 'Ꙅ' => 'ꙅ', + 'Ꙇ' => 'ꙇ', + 'Ꙉ' => 'ꙉ', + 'Ꙋ' => 'ꙋ', + 'Ꙍ' => 'ꙍ', + 'Ꙏ' => 'ꙏ', + 'Ꙑ' => 'ꙑ', + 'Ꙓ' => 'ꙓ', + 'Ꙕ' => 'ꙕ', + 'Ꙗ' => 'ꙗ', + 'Ꙙ' => 'ꙙ', + 'Ꙛ' => 'ꙛ', + 'Ꙝ' => 'ꙝ', + 'Ꙟ' => 'ꙟ', + 'Ꙡ' => 'ꙡ', + 'Ꙣ' => 'ꙣ', + 'Ꙥ' => 'ꙥ', + 'Ꙧ' => 'ꙧ', + 'Ꙩ' => 'ꙩ', + 'Ꙫ' => 'ꙫ', + 'Ꙭ' => 'ꙭ', + 'Ꚁ' => 'ꚁ', + 'Ꚃ' => 'ꚃ', + 'Ꚅ' => 'ꚅ', + 'Ꚇ' => 'ꚇ', + 'Ꚉ' => 'ꚉ', + 'Ꚋ' => 'ꚋ', + 'Ꚍ' => 'ꚍ', + 'Ꚏ' => 'ꚏ', + 'Ꚑ' => 'ꚑ', + 'Ꚓ' => 'ꚓ', + 'Ꚕ' => 'ꚕ', + 'Ꚗ' => 'ꚗ', + 'Ꚙ' => 'ꚙ', + 'Ꚛ' => 'ꚛ', + 'Ꜣ' => 'ꜣ', + 'Ꜥ' => 'ꜥ', + 'Ꜧ' => 'ꜧ', + 'Ꜩ' => 'ꜩ', + 'Ꜫ' => 'ꜫ', + 'Ꜭ' => 'ꜭ', + 'Ꜯ' => 'ꜯ', + 'Ꜳ' => 'ꜳ', + 'Ꜵ' => 'ꜵ', + 'Ꜷ' => 'ꜷ', + 'Ꜹ' => 'ꜹ', + 'Ꜻ' => 'ꜻ', + 'Ꜽ' => 'ꜽ', + 'Ꜿ' => 'ꜿ', + 'Ꝁ' => 'ꝁ', + 'Ꝃ' => 'ꝃ', + 'Ꝅ' => 'ꝅ', + 'Ꝇ' => 'ꝇ', + 'Ꝉ' => 'ꝉ', + 'Ꝋ' => 'ꝋ', + 'Ꝍ' => 'ꝍ', + 'Ꝏ' => 'ꝏ', + 'Ꝑ' => 'ꝑ', + 'Ꝓ' => 'ꝓ', + 'Ꝕ' => 'ꝕ', + 'Ꝗ' => 'ꝗ', + 'Ꝙ' => 'ꝙ', + 'Ꝛ' => 'ꝛ', + 'Ꝝ' => 'ꝝ', + 'Ꝟ' => 'ꝟ', + 'Ꝡ' => 'ꝡ', + 'Ꝣ' => 'ꝣ', + 'Ꝥ' => 'ꝥ', + 'Ꝧ' => 'ꝧ', + 'Ꝩ' => 'ꝩ', + 'Ꝫ' => 'ꝫ', + 'Ꝭ' => 'ꝭ', + 'Ꝯ' => 'ꝯ', + 'Ꝺ' => 'ꝺ', + 'Ꝼ' => 'ꝼ', + 'Ᵹ' => 'ᵹ', + 'Ꝿ' => 'ꝿ', + 'Ꞁ' => 'ꞁ', + 'Ꞃ' => 'ꞃ', + 'Ꞅ' => 'ꞅ', + 'Ꞇ' => 'ꞇ', + 'Ꞌ' => 'ꞌ', + 'Ɥ' => 'ɥ', + 'Ꞑ' => 'ꞑ', + 'Ꞓ' => 'ꞓ', + 'Ꞗ' => 'ꞗ', + 'Ꞙ' => 'ꞙ', + 'Ꞛ' => 'ꞛ', + 'Ꞝ' => 'ꞝ', + 'Ꞟ' => 'ꞟ', + 'Ꞡ' => 'ꞡ', + 'Ꞣ' => 'ꞣ', + 'Ꞥ' => 'ꞥ', + 'Ꞧ' => 'ꞧ', + 'Ꞩ' => 'ꞩ', + 'Ɦ' => 'ɦ', + 'Ɜ' => 'ɜ', + 'Ɡ' => 'ɡ', + 'Ɬ' => 'ɬ', + 'Ʞ' => 'ʞ', + 'Ʇ' => 'ʇ', + 'A' => 'a', + 'B' => 'b', + 'C' => 'c', + 'D' => 'd', + 'E' => 'e', + 'F' => 'f', + 'G' => 'g', + 'H' => 'h', + 'I' => 'i', + 'J' => 'j', + 'K' => 'k', + 'L' => 'l', + 'M' => 'm', + 'N' => 'n', + 'O' => 'o', + 'P' => 'p', + 'Q' => 'q', + 'R' => 'r', + 'S' => 's', + 'T' => 't', + 'U' => 'u', + 'V' => 'v', + 'W' => 'w', + 'X' => 'x', + 'Y' => 'y', + 'Z' => 'z', + '𐐀' => '𐐨', + '𐐁' => '𐐩', + '𐐂' => '𐐪', + '𐐃' => '𐐫', + '𐐄' => '𐐬', + '𐐅' => '𐐭', + '𐐆' => '𐐮', + '𐐇' => '𐐯', + '𐐈' => '𐐰', + '𐐉' => '𐐱', + '𐐊' => '𐐲', + '𐐋' => '𐐳', + '𐐌' => '𐐴', + '𐐍' => '𐐵', + '𐐎' => '𐐶', + '𐐏' => '𐐷', + '𐐐' => '𐐸', + '𐐑' => '𐐹', + '𐐒' => '𐐺', + '𐐓' => '𐐻', + '𐐔' => '𐐼', + '𐐕' => '𐐽', + '𐐖' => '𐐾', + '𐐗' => '𐐿', + '𐐘' => '𐑀', + '𐐙' => '𐑁', + '𐐚' => '𐑂', + '𐐛' => '𐑃', + '𐐜' => '𐑄', + '𐐝' => '𐑅', + '𐐞' => '𐑆', + '𐐟' => '𐑇', + '𐐠' => '𐑈', + '𐐡' => '𐑉', + '𐐢' => '𐑊', + '𐐣' => '𐑋', + '𐐤' => '𐑌', + '𐐥' => '𐑍', + '𐐦' => '𐑎', + '𐐧' => '𐑏', + '𑢠' => '𑣀', + '𑢡' => '𑣁', + '𑢢' => '𑣂', + '𑢣' => '𑣃', + '𑢤' => '𑣄', + '𑢥' => '𑣅', + '𑢦' => '𑣆', + '𑢧' => '𑣇', + '𑢨' => '𑣈', + '𑢩' => '𑣉', + '𑢪' => '𑣊', + '𑢫' => '𑣋', + '𑢬' => '𑣌', + '𑢭' => '𑣍', + '𑢮' => '𑣎', + '𑢯' => '𑣏', + '𑢰' => '𑣐', + '𑢱' => '𑣑', + '𑢲' => '𑣒', + '𑢳' => '𑣓', + '𑢴' => '𑣔', + '𑢵' => '𑣕', + '𑢶' => '𑣖', + '𑢷' => '𑣗', + '𑢸' => '𑣘', + '𑢹' => '𑣙', + '𑢺' => '𑣚', + '𑢻' => '𑣛', + '𑢼' => '𑣜', + '𑢽' => '𑣝', + '𑢾' => '𑣞', + '𑢿' => '𑣟', +); + +$result =& $data; +unset($data); + +return $result; diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/polyfill-mbstring/Resources/unidata/upperCase.php b/lib/ckfinder/core/connector/php/vendor/symfony/polyfill-mbstring/Resources/unidata/upperCase.php new file mode 100644 index 0000000..ec94221 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/polyfill-mbstring/Resources/unidata/upperCase.php @@ -0,0 +1,1109 @@ + 'A', + 'b' => 'B', + 'c' => 'C', + 'd' => 'D', + 'e' => 'E', + 'f' => 'F', + 'g' => 'G', + 'h' => 'H', + 'i' => 'I', + 'j' => 'J', + 'k' => 'K', + 'l' => 'L', + 'm' => 'M', + 'n' => 'N', + 'o' => 'O', + 'p' => 'P', + 'q' => 'Q', + 'r' => 'R', + 's' => 'S', + 't' => 'T', + 'u' => 'U', + 'v' => 'V', + 'w' => 'W', + 'x' => 'X', + 'y' => 'Y', + 'z' => 'Z', + 'µ' => 'Μ', + 'à' => 'À', + 'á' => 'Á', + 'â' => 'Â', + 'ã' => 'Ã', + 'ä' => 'Ä', + 'å' => 'Å', + 'æ' => 'Æ', + 'ç' => 'Ç', + 'è' => 'È', + 'é' => 'É', + 'ê' => 'Ê', + 'ë' => 'Ë', + 'ì' => 'Ì', + 'í' => 'Í', + 'î' => 'Î', + 'ï' => 'Ï', + 'ð' => 'Ð', + 'ñ' => 'Ñ', + 'ò' => 'Ò', + 'ó' => 'Ó', + 'ô' => 'Ô', + 'õ' => 'Õ', + 'ö' => 'Ö', + 'ø' => 'Ø', + 'ù' => 'Ù', + 'ú' => 'Ú', + 'û' => 'Û', + 'ü' => 'Ü', + 'ý' => 'Ý', + 'þ' => 'Þ', + 'ÿ' => 'Ÿ', + 'ā' => 'Ā', + 'ă' => 'Ă', + 'ą' => 'Ą', + 'ć' => 'Ć', + 'ĉ' => 'Ĉ', + 'ċ' => 'Ċ', + 'č' => 'Č', + 'ď' => 'Ď', + 'đ' => 'Đ', + 'ē' => 'Ē', + 'ĕ' => 'Ĕ', + 'ė' => 'Ė', + 'ę' => 'Ę', + 'ě' => 'Ě', + 'ĝ' => 'Ĝ', + 'ğ' => 'Ğ', + 'ġ' => 'Ġ', + 'ģ' => 'Ģ', + 'ĥ' => 'Ĥ', + 'ħ' => 'Ħ', + 'ĩ' => 'Ĩ', + 'ī' => 'Ī', + 'ĭ' => 'Ĭ', + 'į' => 'Į', + 'ı' => 'I', + 'ij' => 'IJ', + 'ĵ' => 'Ĵ', + 'ķ' => 'Ķ', + 'ĺ' => 'Ĺ', + 'ļ' => 'Ļ', + 'ľ' => 'Ľ', + 'ŀ' => 'Ŀ', + 'ł' => 'Ł', + 'ń' => 'Ń', + 'ņ' => 'Ņ', + 'ň' => 'Ň', + 'ŋ' => 'Ŋ', + 'ō' => 'Ō', + 'ŏ' => 'Ŏ', + 'ő' => 'Ő', + 'œ' => 'Œ', + 'ŕ' => 'Ŕ', + 'ŗ' => 'Ŗ', + 'ř' => 'Ř', + 'ś' => 'Ś', + 'ŝ' => 'Ŝ', + 'ş' => 'Ş', + 'š' => 'Š', + 'ţ' => 'Ţ', + 'ť' => 'Ť', + 'ŧ' => 'Ŧ', + 'ũ' => 'Ũ', + 'ū' => 'Ū', + 'ŭ' => 'Ŭ', + 'ů' => 'Ů', + 'ű' => 'Ű', + 'ų' => 'Ų', + 'ŵ' => 'Ŵ', + 'ŷ' => 'Ŷ', + 'ź' => 'Ź', + 'ż' => 'Ż', + 'ž' => 'Ž', + 'ſ' => 'S', + 'ƀ' => 'Ƀ', + 'ƃ' => 'Ƃ', + 'ƅ' => 'Ƅ', + 'ƈ' => 'Ƈ', + 'ƌ' => 'Ƌ', + 'ƒ' => 'Ƒ', + 'ƕ' => 'Ƕ', + 'ƙ' => 'Ƙ', + 'ƚ' => 'Ƚ', + 'ƞ' => 'Ƞ', + 'ơ' => 'Ơ', + 'ƣ' => 'Ƣ', + 'ƥ' => 'Ƥ', + 'ƨ' => 'Ƨ', + 'ƭ' => 'Ƭ', + 'ư' => 'Ư', + 'ƴ' => 'Ƴ', + 'ƶ' => 'Ƶ', + 'ƹ' => 'Ƹ', + 'ƽ' => 'Ƽ', + 'ƿ' => 'Ƿ', + 'Dž' => 'DŽ', + 'dž' => 'DŽ', + 'Lj' => 'LJ', + 'lj' => 'LJ', + 'Nj' => 'NJ', + 'nj' => 'NJ', + 'ǎ' => 'Ǎ', + 'ǐ' => 'Ǐ', + 'ǒ' => 'Ǒ', + 'ǔ' => 'Ǔ', + 'ǖ' => 'Ǖ', + 'ǘ' => 'Ǘ', + 'ǚ' => 'Ǚ', + 'ǜ' => 'Ǜ', + 'ǝ' => 'Ǝ', + 'ǟ' => 'Ǟ', + 'ǡ' => 'Ǡ', + 'ǣ' => 'Ǣ', + 'ǥ' => 'Ǥ', + 'ǧ' => 'Ǧ', + 'ǩ' => 'Ǩ', + 'ǫ' => 'Ǫ', + 'ǭ' => 'Ǭ', + 'ǯ' => 'Ǯ', + 'Dz' => 'DZ', + 'dz' => 'DZ', + 'ǵ' => 'Ǵ', + 'ǹ' => 'Ǹ', + 'ǻ' => 'Ǻ', + 'ǽ' => 'Ǽ', + 'ǿ' => 'Ǿ', + 'ȁ' => 'Ȁ', + 'ȃ' => 'Ȃ', + 'ȅ' => 'Ȅ', + 'ȇ' => 'Ȇ', + 'ȉ' => 'Ȉ', + 'ȋ' => 'Ȋ', + 'ȍ' => 'Ȍ', + 'ȏ' => 'Ȏ', + 'ȑ' => 'Ȑ', + 'ȓ' => 'Ȓ', + 'ȕ' => 'Ȕ', + 'ȗ' => 'Ȗ', + 'ș' => 'Ș', + 'ț' => 'Ț', + 'ȝ' => 'Ȝ', + 'ȟ' => 'Ȟ', + 'ȣ' => 'Ȣ', + 'ȥ' => 'Ȥ', + 'ȧ' => 'Ȧ', + 'ȩ' => 'Ȩ', + 'ȫ' => 'Ȫ', + 'ȭ' => 'Ȭ', + 'ȯ' => 'Ȯ', + 'ȱ' => 'Ȱ', + 'ȳ' => 'Ȳ', + 'ȼ' => 'Ȼ', + 'ȿ' => 'Ȿ', + 'ɀ' => 'Ɀ', + 'ɂ' => 'Ɂ', + 'ɇ' => 'Ɇ', + 'ɉ' => 'Ɉ', + 'ɋ' => 'Ɋ', + 'ɍ' => 'Ɍ', + 'ɏ' => 'Ɏ', + 'ɐ' => 'Ɐ', + 'ɑ' => 'Ɑ', + 'ɒ' => 'Ɒ', + 'ɓ' => 'Ɓ', + 'ɔ' => 'Ɔ', + 'ɖ' => 'Ɖ', + 'ɗ' => 'Ɗ', + 'ə' => 'Ə', + 'ɛ' => 'Ɛ', + 'ɜ' => 'Ɜ', + 'ɠ' => 'Ɠ', + 'ɡ' => 'Ɡ', + 'ɣ' => 'Ɣ', + 'ɥ' => 'Ɥ', + 'ɦ' => 'Ɦ', + 'ɨ' => 'Ɨ', + 'ɩ' => 'Ɩ', + 'ɫ' => 'Ɫ', + 'ɬ' => 'Ɬ', + 'ɯ' => 'Ɯ', + 'ɱ' => 'Ɱ', + 'ɲ' => 'Ɲ', + 'ɵ' => 'Ɵ', + 'ɽ' => 'Ɽ', + 'ʀ' => 'Ʀ', + 'ʃ' => 'Ʃ', + 'ʇ' => 'Ʇ', + 'ʈ' => 'Ʈ', + 'ʉ' => 'Ʉ', + 'ʊ' => 'Ʊ', + 'ʋ' => 'Ʋ', + 'ʌ' => 'Ʌ', + 'ʒ' => 'Ʒ', + 'ʞ' => 'Ʞ', + 'ͅ' => 'Ι', + 'ͱ' => 'Ͱ', + 'ͳ' => 'Ͳ', + 'ͷ' => 'Ͷ', + 'ͻ' => 'Ͻ', + 'ͼ' => 'Ͼ', + 'ͽ' => 'Ͽ', + 'ά' => 'Ά', + 'έ' => 'Έ', + 'ή' => 'Ή', + 'ί' => 'Ί', + 'α' => 'Α', + 'β' => 'Β', + 'γ' => 'Γ', + 'δ' => 'Δ', + 'ε' => 'Ε', + 'ζ' => 'Ζ', + 'η' => 'Η', + 'θ' => 'Θ', + 'ι' => 'Ι', + 'κ' => 'Κ', + 'λ' => 'Λ', + 'μ' => 'Μ', + 'ν' => 'Ν', + 'ξ' => 'Ξ', + 'ο' => 'Ο', + 'π' => 'Π', + 'ρ' => 'Ρ', + 'ς' => 'Σ', + 'σ' => 'Σ', + 'τ' => 'Τ', + 'υ' => 'Υ', + 'φ' => 'Φ', + 'χ' => 'Χ', + 'ψ' => 'Ψ', + 'ω' => 'Ω', + 'ϊ' => 'Ϊ', + 'ϋ' => 'Ϋ', + 'ό' => 'Ό', + 'ύ' => 'Ύ', + 'ώ' => 'Ώ', + 'ϐ' => 'Β', + 'ϑ' => 'Θ', + 'ϕ' => 'Φ', + 'ϖ' => 'Π', + 'ϗ' => 'Ϗ', + 'ϙ' => 'Ϙ', + 'ϛ' => 'Ϛ', + 'ϝ' => 'Ϝ', + 'ϟ' => 'Ϟ', + 'ϡ' => 'Ϡ', + 'ϣ' => 'Ϣ', + 'ϥ' => 'Ϥ', + 'ϧ' => 'Ϧ', + 'ϩ' => 'Ϩ', + 'ϫ' => 'Ϫ', + 'ϭ' => 'Ϭ', + 'ϯ' => 'Ϯ', + 'ϰ' => 'Κ', + 'ϱ' => 'Ρ', + 'ϲ' => 'Ϲ', + 'ϳ' => 'Ϳ', + 'ϵ' => 'Ε', + 'ϸ' => 'Ϸ', + 'ϻ' => 'Ϻ', + 'а' => 'А', + 'б' => 'Б', + 'в' => 'В', + 'г' => 'Г', + 'д' => 'Д', + 'е' => 'Е', + 'ж' => 'Ж', + 'з' => 'З', + 'и' => 'И', + 'й' => 'Й', + 'к' => 'К', + 'л' => 'Л', + 'м' => 'М', + 'н' => 'Н', + 'о' => 'О', + 'п' => 'П', + 'р' => 'Р', + 'с' => 'С', + 'т' => 'Т', + 'у' => 'У', + 'ф' => 'Ф', + 'х' => 'Х', + 'ц' => 'Ц', + 'ч' => 'Ч', + 'ш' => 'Ш', + 'щ' => 'Щ', + 'ъ' => 'Ъ', + 'ы' => 'Ы', + 'ь' => 'Ь', + 'э' => 'Э', + 'ю' => 'Ю', + 'я' => 'Я', + 'ѐ' => 'Ѐ', + 'ё' => 'Ё', + 'ђ' => 'Ђ', + 'ѓ' => 'Ѓ', + 'є' => 'Є', + 'ѕ' => 'Ѕ', + 'і' => 'І', + 'ї' => 'Ї', + 'ј' => 'Ј', + 'љ' => 'Љ', + 'њ' => 'Њ', + 'ћ' => 'Ћ', + 'ќ' => 'Ќ', + 'ѝ' => 'Ѝ', + 'ў' => 'Ў', + 'џ' => 'Џ', + 'ѡ' => 'Ѡ', + 'ѣ' => 'Ѣ', + 'ѥ' => 'Ѥ', + 'ѧ' => 'Ѧ', + 'ѩ' => 'Ѩ', + 'ѫ' => 'Ѫ', + 'ѭ' => 'Ѭ', + 'ѯ' => 'Ѯ', + 'ѱ' => 'Ѱ', + 'ѳ' => 'Ѳ', + 'ѵ' => 'Ѵ', + 'ѷ' => 'Ѷ', + 'ѹ' => 'Ѹ', + 'ѻ' => 'Ѻ', + 'ѽ' => 'Ѽ', + 'ѿ' => 'Ѿ', + 'ҁ' => 'Ҁ', + 'ҋ' => 'Ҋ', + 'ҍ' => 'Ҍ', + 'ҏ' => 'Ҏ', + 'ґ' => 'Ґ', + 'ғ' => 'Ғ', + 'ҕ' => 'Ҕ', + 'җ' => 'Җ', + 'ҙ' => 'Ҙ', + 'қ' => 'Қ', + 'ҝ' => 'Ҝ', + 'ҟ' => 'Ҟ', + 'ҡ' => 'Ҡ', + 'ң' => 'Ң', + 'ҥ' => 'Ҥ', + 'ҧ' => 'Ҧ', + 'ҩ' => 'Ҩ', + 'ҫ' => 'Ҫ', + 'ҭ' => 'Ҭ', + 'ү' => 'Ү', + 'ұ' => 'Ұ', + 'ҳ' => 'Ҳ', + 'ҵ' => 'Ҵ', + 'ҷ' => 'Ҷ', + 'ҹ' => 'Ҹ', + 'һ' => 'Һ', + 'ҽ' => 'Ҽ', + 'ҿ' => 'Ҿ', + 'ӂ' => 'Ӂ', + 'ӄ' => 'Ӄ', + 'ӆ' => 'Ӆ', + 'ӈ' => 'Ӈ', + 'ӊ' => 'Ӊ', + 'ӌ' => 'Ӌ', + 'ӎ' => 'Ӎ', + 'ӏ' => 'Ӏ', + 'ӑ' => 'Ӑ', + 'ӓ' => 'Ӓ', + 'ӕ' => 'Ӕ', + 'ӗ' => 'Ӗ', + 'ә' => 'Ә', + 'ӛ' => 'Ӛ', + 'ӝ' => 'Ӝ', + 'ӟ' => 'Ӟ', + 'ӡ' => 'Ӡ', + 'ӣ' => 'Ӣ', + 'ӥ' => 'Ӥ', + 'ӧ' => 'Ӧ', + 'ө' => 'Ө', + 'ӫ' => 'Ӫ', + 'ӭ' => 'Ӭ', + 'ӯ' => 'Ӯ', + 'ӱ' => 'Ӱ', + 'ӳ' => 'Ӳ', + 'ӵ' => 'Ӵ', + 'ӷ' => 'Ӷ', + 'ӹ' => 'Ӹ', + 'ӻ' => 'Ӻ', + 'ӽ' => 'Ӽ', + 'ӿ' => 'Ӿ', + 'ԁ' => 'Ԁ', + 'ԃ' => 'Ԃ', + 'ԅ' => 'Ԅ', + 'ԇ' => 'Ԇ', + 'ԉ' => 'Ԉ', + 'ԋ' => 'Ԋ', + 'ԍ' => 'Ԍ', + 'ԏ' => 'Ԏ', + 'ԑ' => 'Ԑ', + 'ԓ' => 'Ԓ', + 'ԕ' => 'Ԕ', + 'ԗ' => 'Ԗ', + 'ԙ' => 'Ԙ', + 'ԛ' => 'Ԛ', + 'ԝ' => 'Ԝ', + 'ԟ' => 'Ԟ', + 'ԡ' => 'Ԡ', + 'ԣ' => 'Ԣ', + 'ԥ' => 'Ԥ', + 'ԧ' => 'Ԧ', + 'ԩ' => 'Ԩ', + 'ԫ' => 'Ԫ', + 'ԭ' => 'Ԭ', + 'ԯ' => 'Ԯ', + 'ա' => 'Ա', + 'բ' => 'Բ', + 'գ' => 'Գ', + 'դ' => 'Դ', + 'ե' => 'Ե', + 'զ' => 'Զ', + 'է' => 'Է', + 'ը' => 'Ը', + 'թ' => 'Թ', + 'ժ' => 'Ժ', + 'ի' => 'Ի', + 'լ' => 'Լ', + 'խ' => 'Խ', + 'ծ' => 'Ծ', + 'կ' => 'Կ', + 'հ' => 'Հ', + 'ձ' => 'Ձ', + 'ղ' => 'Ղ', + 'ճ' => 'Ճ', + 'մ' => 'Մ', + 'յ' => 'Յ', + 'ն' => 'Ն', + 'շ' => 'Շ', + 'ո' => 'Ո', + 'չ' => 'Չ', + 'պ' => 'Պ', + 'ջ' => 'Ջ', + 'ռ' => 'Ռ', + 'ս' => 'Ս', + 'վ' => 'Վ', + 'տ' => 'Տ', + 'ր' => 'Ր', + 'ց' => 'Ց', + 'ւ' => 'Ւ', + 'փ' => 'Փ', + 'ք' => 'Ք', + 'օ' => 'Օ', + 'ֆ' => 'Ֆ', + 'ᵹ' => 'Ᵹ', + 'ᵽ' => 'Ᵽ', + 'ḁ' => 'Ḁ', + 'ḃ' => 'Ḃ', + 'ḅ' => 'Ḅ', + 'ḇ' => 'Ḇ', + 'ḉ' => 'Ḉ', + 'ḋ' => 'Ḋ', + 'ḍ' => 'Ḍ', + 'ḏ' => 'Ḏ', + 'ḑ' => 'Ḑ', + 'ḓ' => 'Ḓ', + 'ḕ' => 'Ḕ', + 'ḗ' => 'Ḗ', + 'ḙ' => 'Ḙ', + 'ḛ' => 'Ḛ', + 'ḝ' => 'Ḝ', + 'ḟ' => 'Ḟ', + 'ḡ' => 'Ḡ', + 'ḣ' => 'Ḣ', + 'ḥ' => 'Ḥ', + 'ḧ' => 'Ḧ', + 'ḩ' => 'Ḩ', + 'ḫ' => 'Ḫ', + 'ḭ' => 'Ḭ', + 'ḯ' => 'Ḯ', + 'ḱ' => 'Ḱ', + 'ḳ' => 'Ḳ', + 'ḵ' => 'Ḵ', + 'ḷ' => 'Ḷ', + 'ḹ' => 'Ḹ', + 'ḻ' => 'Ḻ', + 'ḽ' => 'Ḽ', + 'ḿ' => 'Ḿ', + 'ṁ' => 'Ṁ', + 'ṃ' => 'Ṃ', + 'ṅ' => 'Ṅ', + 'ṇ' => 'Ṇ', + 'ṉ' => 'Ṉ', + 'ṋ' => 'Ṋ', + 'ṍ' => 'Ṍ', + 'ṏ' => 'Ṏ', + 'ṑ' => 'Ṑ', + 'ṓ' => 'Ṓ', + 'ṕ' => 'Ṕ', + 'ṗ' => 'Ṗ', + 'ṙ' => 'Ṙ', + 'ṛ' => 'Ṛ', + 'ṝ' => 'Ṝ', + 'ṟ' => 'Ṟ', + 'ṡ' => 'Ṡ', + 'ṣ' => 'Ṣ', + 'ṥ' => 'Ṥ', + 'ṧ' => 'Ṧ', + 'ṩ' => 'Ṩ', + 'ṫ' => 'Ṫ', + 'ṭ' => 'Ṭ', + 'ṯ' => 'Ṯ', + 'ṱ' => 'Ṱ', + 'ṳ' => 'Ṳ', + 'ṵ' => 'Ṵ', + 'ṷ' => 'Ṷ', + 'ṹ' => 'Ṹ', + 'ṻ' => 'Ṻ', + 'ṽ' => 'Ṽ', + 'ṿ' => 'Ṿ', + 'ẁ' => 'Ẁ', + 'ẃ' => 'Ẃ', + 'ẅ' => 'Ẅ', + 'ẇ' => 'Ẇ', + 'ẉ' => 'Ẉ', + 'ẋ' => 'Ẋ', + 'ẍ' => 'Ẍ', + 'ẏ' => 'Ẏ', + 'ẑ' => 'Ẑ', + 'ẓ' => 'Ẓ', + 'ẕ' => 'Ẕ', + 'ẛ' => 'Ṡ', + 'ạ' => 'Ạ', + 'ả' => 'Ả', + 'ấ' => 'Ấ', + 'ầ' => 'Ầ', + 'ẩ' => 'Ẩ', + 'ẫ' => 'Ẫ', + 'ậ' => 'Ậ', + 'ắ' => 'Ắ', + 'ằ' => 'Ằ', + 'ẳ' => 'Ẳ', + 'ẵ' => 'Ẵ', + 'ặ' => 'Ặ', + 'ẹ' => 'Ẹ', + 'ẻ' => 'Ẻ', + 'ẽ' => 'Ẽ', + 'ế' => 'Ế', + 'ề' => 'Ề', + 'ể' => 'Ể', + 'ễ' => 'Ễ', + 'ệ' => 'Ệ', + 'ỉ' => 'Ỉ', + 'ị' => 'Ị', + 'ọ' => 'Ọ', + 'ỏ' => 'Ỏ', + 'ố' => 'Ố', + 'ồ' => 'Ồ', + 'ổ' => 'Ổ', + 'ỗ' => 'Ỗ', + 'ộ' => 'Ộ', + 'ớ' => 'Ớ', + 'ờ' => 'Ờ', + 'ở' => 'Ở', + 'ỡ' => 'Ỡ', + 'ợ' => 'Ợ', + 'ụ' => 'Ụ', + 'ủ' => 'Ủ', + 'ứ' => 'Ứ', + 'ừ' => 'Ừ', + 'ử' => 'Ử', + 'ữ' => 'Ữ', + 'ự' => 'Ự', + 'ỳ' => 'Ỳ', + 'ỵ' => 'Ỵ', + 'ỷ' => 'Ỷ', + 'ỹ' => 'Ỹ', + 'ỻ' => 'Ỻ', + 'ỽ' => 'Ỽ', + 'ỿ' => 'Ỿ', + 'ἀ' => 'Ἀ', + 'ἁ' => 'Ἁ', + 'ἂ' => 'Ἂ', + 'ἃ' => 'Ἃ', + 'ἄ' => 'Ἄ', + 'ἅ' => 'Ἅ', + 'ἆ' => 'Ἆ', + 'ἇ' => 'Ἇ', + 'ἐ' => 'Ἐ', + 'ἑ' => 'Ἑ', + 'ἒ' => 'Ἒ', + 'ἓ' => 'Ἓ', + 'ἔ' => 'Ἔ', + 'ἕ' => 'Ἕ', + 'ἠ' => 'Ἠ', + 'ἡ' => 'Ἡ', + 'ἢ' => 'Ἢ', + 'ἣ' => 'Ἣ', + 'ἤ' => 'Ἤ', + 'ἥ' => 'Ἥ', + 'ἦ' => 'Ἦ', + 'ἧ' => 'Ἧ', + 'ἰ' => 'Ἰ', + 'ἱ' => 'Ἱ', + 'ἲ' => 'Ἲ', + 'ἳ' => 'Ἳ', + 'ἴ' => 'Ἴ', + 'ἵ' => 'Ἵ', + 'ἶ' => 'Ἶ', + 'ἷ' => 'Ἷ', + 'ὀ' => 'Ὀ', + 'ὁ' => 'Ὁ', + 'ὂ' => 'Ὂ', + 'ὃ' => 'Ὃ', + 'ὄ' => 'Ὄ', + 'ὅ' => 'Ὅ', + 'ὑ' => 'Ὑ', + 'ὓ' => 'Ὓ', + 'ὕ' => 'Ὕ', + 'ὗ' => 'Ὗ', + 'ὠ' => 'Ὠ', + 'ὡ' => 'Ὡ', + 'ὢ' => 'Ὢ', + 'ὣ' => 'Ὣ', + 'ὤ' => 'Ὤ', + 'ὥ' => 'Ὥ', + 'ὦ' => 'Ὦ', + 'ὧ' => 'Ὧ', + 'ὰ' => 'Ὰ', + 'ά' => 'Ά', + 'ὲ' => 'Ὲ', + 'έ' => 'Έ', + 'ὴ' => 'Ὴ', + 'ή' => 'Ή', + 'ὶ' => 'Ὶ', + 'ί' => 'Ί', + 'ὸ' => 'Ὸ', + 'ό' => 'Ό', + 'ὺ' => 'Ὺ', + 'ύ' => 'Ύ', + 'ὼ' => 'Ὼ', + 'ώ' => 'Ώ', + 'ᾀ' => 'ᾈ', + 'ᾁ' => 'ᾉ', + 'ᾂ' => 'ᾊ', + 'ᾃ' => 'ᾋ', + 'ᾄ' => 'ᾌ', + 'ᾅ' => 'ᾍ', + 'ᾆ' => 'ᾎ', + 'ᾇ' => 'ᾏ', + 'ᾐ' => 'ᾘ', + 'ᾑ' => 'ᾙ', + 'ᾒ' => 'ᾚ', + 'ᾓ' => 'ᾛ', + 'ᾔ' => 'ᾜ', + 'ᾕ' => 'ᾝ', + 'ᾖ' => 'ᾞ', + 'ᾗ' => 'ᾟ', + 'ᾠ' => 'ᾨ', + 'ᾡ' => 'ᾩ', + 'ᾢ' => 'ᾪ', + 'ᾣ' => 'ᾫ', + 'ᾤ' => 'ᾬ', + 'ᾥ' => 'ᾭ', + 'ᾦ' => 'ᾮ', + 'ᾧ' => 'ᾯ', + 'ᾰ' => 'Ᾰ', + 'ᾱ' => 'Ᾱ', + 'ᾳ' => 'ᾼ', + 'ι' => 'Ι', + 'ῃ' => 'ῌ', + 'ῐ' => 'Ῐ', + 'ῑ' => 'Ῑ', + 'ῠ' => 'Ῠ', + 'ῡ' => 'Ῡ', + 'ῥ' => 'Ῥ', + 'ῳ' => 'ῼ', + 'ⅎ' => 'Ⅎ', + 'ⅰ' => 'Ⅰ', + 'ⅱ' => 'Ⅱ', + 'ⅲ' => 'Ⅲ', + 'ⅳ' => 'Ⅳ', + 'ⅴ' => 'Ⅴ', + 'ⅵ' => 'Ⅵ', + 'ⅶ' => 'Ⅶ', + 'ⅷ' => 'Ⅷ', + 'ⅸ' => 'Ⅸ', + 'ⅹ' => 'Ⅹ', + 'ⅺ' => 'Ⅺ', + 'ⅻ' => 'Ⅻ', + 'ⅼ' => 'Ⅼ', + 'ⅽ' => 'Ⅽ', + 'ⅾ' => 'Ⅾ', + 'ⅿ' => 'Ⅿ', + 'ↄ' => 'Ↄ', + 'ⓐ' => 'Ⓐ', + 'ⓑ' => 'Ⓑ', + 'ⓒ' => 'Ⓒ', + 'ⓓ' => 'Ⓓ', + 'ⓔ' => 'Ⓔ', + 'ⓕ' => 'Ⓕ', + 'ⓖ' => 'Ⓖ', + 'ⓗ' => 'Ⓗ', + 'ⓘ' => 'Ⓘ', + 'ⓙ' => 'Ⓙ', + 'ⓚ' => 'Ⓚ', + 'ⓛ' => 'Ⓛ', + 'ⓜ' => 'Ⓜ', + 'ⓝ' => 'Ⓝ', + 'ⓞ' => 'Ⓞ', + 'ⓟ' => 'Ⓟ', + 'ⓠ' => 'Ⓠ', + 'ⓡ' => 'Ⓡ', + 'ⓢ' => 'Ⓢ', + 'ⓣ' => 'Ⓣ', + 'ⓤ' => 'Ⓤ', + 'ⓥ' => 'Ⓥ', + 'ⓦ' => 'Ⓦ', + 'ⓧ' => 'Ⓧ', + 'ⓨ' => 'Ⓨ', + 'ⓩ' => 'Ⓩ', + 'ⰰ' => 'Ⰰ', + 'ⰱ' => 'Ⰱ', + 'ⰲ' => 'Ⰲ', + 'ⰳ' => 'Ⰳ', + 'ⰴ' => 'Ⰴ', + 'ⰵ' => 'Ⰵ', + 'ⰶ' => 'Ⰶ', + 'ⰷ' => 'Ⰷ', + 'ⰸ' => 'Ⰸ', + 'ⰹ' => 'Ⰹ', + 'ⰺ' => 'Ⰺ', + 'ⰻ' => 'Ⰻ', + 'ⰼ' => 'Ⰼ', + 'ⰽ' => 'Ⰽ', + 'ⰾ' => 'Ⰾ', + 'ⰿ' => 'Ⰿ', + 'ⱀ' => 'Ⱀ', + 'ⱁ' => 'Ⱁ', + 'ⱂ' => 'Ⱂ', + 'ⱃ' => 'Ⱃ', + 'ⱄ' => 'Ⱄ', + 'ⱅ' => 'Ⱅ', + 'ⱆ' => 'Ⱆ', + 'ⱇ' => 'Ⱇ', + 'ⱈ' => 'Ⱈ', + 'ⱉ' => 'Ⱉ', + 'ⱊ' => 'Ⱊ', + 'ⱋ' => 'Ⱋ', + 'ⱌ' => 'Ⱌ', + 'ⱍ' => 'Ⱍ', + 'ⱎ' => 'Ⱎ', + 'ⱏ' => 'Ⱏ', + 'ⱐ' => 'Ⱐ', + 'ⱑ' => 'Ⱑ', + 'ⱒ' => 'Ⱒ', + 'ⱓ' => 'Ⱓ', + 'ⱔ' => 'Ⱔ', + 'ⱕ' => 'Ⱕ', + 'ⱖ' => 'Ⱖ', + 'ⱗ' => 'Ⱗ', + 'ⱘ' => 'Ⱘ', + 'ⱙ' => 'Ⱙ', + 'ⱚ' => 'Ⱚ', + 'ⱛ' => 'Ⱛ', + 'ⱜ' => 'Ⱜ', + 'ⱝ' => 'Ⱝ', + 'ⱞ' => 'Ⱞ', + 'ⱡ' => 'Ⱡ', + 'ⱥ' => 'Ⱥ', + 'ⱦ' => 'Ⱦ', + 'ⱨ' => 'Ⱨ', + 'ⱪ' => 'Ⱪ', + 'ⱬ' => 'Ⱬ', + 'ⱳ' => 'Ⱳ', + 'ⱶ' => 'Ⱶ', + 'ⲁ' => 'Ⲁ', + 'ⲃ' => 'Ⲃ', + 'ⲅ' => 'Ⲅ', + 'ⲇ' => 'Ⲇ', + 'ⲉ' => 'Ⲉ', + 'ⲋ' => 'Ⲋ', + 'ⲍ' => 'Ⲍ', + 'ⲏ' => 'Ⲏ', + 'ⲑ' => 'Ⲑ', + 'ⲓ' => 'Ⲓ', + 'ⲕ' => 'Ⲕ', + 'ⲗ' => 'Ⲗ', + 'ⲙ' => 'Ⲙ', + 'ⲛ' => 'Ⲛ', + 'ⲝ' => 'Ⲝ', + 'ⲟ' => 'Ⲟ', + 'ⲡ' => 'Ⲡ', + 'ⲣ' => 'Ⲣ', + 'ⲥ' => 'Ⲥ', + 'ⲧ' => 'Ⲧ', + 'ⲩ' => 'Ⲩ', + 'ⲫ' => 'Ⲫ', + 'ⲭ' => 'Ⲭ', + 'ⲯ' => 'Ⲯ', + 'ⲱ' => 'Ⲱ', + 'ⲳ' => 'Ⲳ', + 'ⲵ' => 'Ⲵ', + 'ⲷ' => 'Ⲷ', + 'ⲹ' => 'Ⲹ', + 'ⲻ' => 'Ⲻ', + 'ⲽ' => 'Ⲽ', + 'ⲿ' => 'Ⲿ', + 'ⳁ' => 'Ⳁ', + 'ⳃ' => 'Ⳃ', + 'ⳅ' => 'Ⳅ', + 'ⳇ' => 'Ⳇ', + 'ⳉ' => 'Ⳉ', + 'ⳋ' => 'Ⳋ', + 'ⳍ' => 'Ⳍ', + 'ⳏ' => 'Ⳏ', + 'ⳑ' => 'Ⳑ', + 'ⳓ' => 'Ⳓ', + 'ⳕ' => 'Ⳕ', + 'ⳗ' => 'Ⳗ', + 'ⳙ' => 'Ⳙ', + 'ⳛ' => 'Ⳛ', + 'ⳝ' => 'Ⳝ', + 'ⳟ' => 'Ⳟ', + 'ⳡ' => 'Ⳡ', + 'ⳣ' => 'Ⳣ', + 'ⳬ' => 'Ⳬ', + 'ⳮ' => 'Ⳮ', + 'ⳳ' => 'Ⳳ', + 'ⴀ' => 'Ⴀ', + 'ⴁ' => 'Ⴁ', + 'ⴂ' => 'Ⴂ', + 'ⴃ' => 'Ⴃ', + 'ⴄ' => 'Ⴄ', + 'ⴅ' => 'Ⴅ', + 'ⴆ' => 'Ⴆ', + 'ⴇ' => 'Ⴇ', + 'ⴈ' => 'Ⴈ', + 'ⴉ' => 'Ⴉ', + 'ⴊ' => 'Ⴊ', + 'ⴋ' => 'Ⴋ', + 'ⴌ' => 'Ⴌ', + 'ⴍ' => 'Ⴍ', + 'ⴎ' => 'Ⴎ', + 'ⴏ' => 'Ⴏ', + 'ⴐ' => 'Ⴐ', + 'ⴑ' => 'Ⴑ', + 'ⴒ' => 'Ⴒ', + 'ⴓ' => 'Ⴓ', + 'ⴔ' => 'Ⴔ', + 'ⴕ' => 'Ⴕ', + 'ⴖ' => 'Ⴖ', + 'ⴗ' => 'Ⴗ', + 'ⴘ' => 'Ⴘ', + 'ⴙ' => 'Ⴙ', + 'ⴚ' => 'Ⴚ', + 'ⴛ' => 'Ⴛ', + 'ⴜ' => 'Ⴜ', + 'ⴝ' => 'Ⴝ', + 'ⴞ' => 'Ⴞ', + 'ⴟ' => 'Ⴟ', + 'ⴠ' => 'Ⴠ', + 'ⴡ' => 'Ⴡ', + 'ⴢ' => 'Ⴢ', + 'ⴣ' => 'Ⴣ', + 'ⴤ' => 'Ⴤ', + 'ⴥ' => 'Ⴥ', + 'ⴧ' => 'Ⴧ', + 'ⴭ' => 'Ⴭ', + 'ꙁ' => 'Ꙁ', + 'ꙃ' => 'Ꙃ', + 'ꙅ' => 'Ꙅ', + 'ꙇ' => 'Ꙇ', + 'ꙉ' => 'Ꙉ', + 'ꙋ' => 'Ꙋ', + 'ꙍ' => 'Ꙍ', + 'ꙏ' => 'Ꙏ', + 'ꙑ' => 'Ꙑ', + 'ꙓ' => 'Ꙓ', + 'ꙕ' => 'Ꙕ', + 'ꙗ' => 'Ꙗ', + 'ꙙ' => 'Ꙙ', + 'ꙛ' => 'Ꙛ', + 'ꙝ' => 'Ꙝ', + 'ꙟ' => 'Ꙟ', + 'ꙡ' => 'Ꙡ', + 'ꙣ' => 'Ꙣ', + 'ꙥ' => 'Ꙥ', + 'ꙧ' => 'Ꙧ', + 'ꙩ' => 'Ꙩ', + 'ꙫ' => 'Ꙫ', + 'ꙭ' => 'Ꙭ', + 'ꚁ' => 'Ꚁ', + 'ꚃ' => 'Ꚃ', + 'ꚅ' => 'Ꚅ', + 'ꚇ' => 'Ꚇ', + 'ꚉ' => 'Ꚉ', + 'ꚋ' => 'Ꚋ', + 'ꚍ' => 'Ꚍ', + 'ꚏ' => 'Ꚏ', + 'ꚑ' => 'Ꚑ', + 'ꚓ' => 'Ꚓ', + 'ꚕ' => 'Ꚕ', + 'ꚗ' => 'Ꚗ', + 'ꚙ' => 'Ꚙ', + 'ꚛ' => 'Ꚛ', + 'ꜣ' => 'Ꜣ', + 'ꜥ' => 'Ꜥ', + 'ꜧ' => 'Ꜧ', + 'ꜩ' => 'Ꜩ', + 'ꜫ' => 'Ꜫ', + 'ꜭ' => 'Ꜭ', + 'ꜯ' => 'Ꜯ', + 'ꜳ' => 'Ꜳ', + 'ꜵ' => 'Ꜵ', + 'ꜷ' => 'Ꜷ', + 'ꜹ' => 'Ꜹ', + 'ꜻ' => 'Ꜻ', + 'ꜽ' => 'Ꜽ', + 'ꜿ' => 'Ꜿ', + 'ꝁ' => 'Ꝁ', + 'ꝃ' => 'Ꝃ', + 'ꝅ' => 'Ꝅ', + 'ꝇ' => 'Ꝇ', + 'ꝉ' => 'Ꝉ', + 'ꝋ' => 'Ꝋ', + 'ꝍ' => 'Ꝍ', + 'ꝏ' => 'Ꝏ', + 'ꝑ' => 'Ꝑ', + 'ꝓ' => 'Ꝓ', + 'ꝕ' => 'Ꝕ', + 'ꝗ' => 'Ꝗ', + 'ꝙ' => 'Ꝙ', + 'ꝛ' => 'Ꝛ', + 'ꝝ' => 'Ꝝ', + 'ꝟ' => 'Ꝟ', + 'ꝡ' => 'Ꝡ', + 'ꝣ' => 'Ꝣ', + 'ꝥ' => 'Ꝥ', + 'ꝧ' => 'Ꝧ', + 'ꝩ' => 'Ꝩ', + 'ꝫ' => 'Ꝫ', + 'ꝭ' => 'Ꝭ', + 'ꝯ' => 'Ꝯ', + 'ꝺ' => 'Ꝺ', + 'ꝼ' => 'Ꝼ', + 'ꝿ' => 'Ꝿ', + 'ꞁ' => 'Ꞁ', + 'ꞃ' => 'Ꞃ', + 'ꞅ' => 'Ꞅ', + 'ꞇ' => 'Ꞇ', + 'ꞌ' => 'Ꞌ', + 'ꞑ' => 'Ꞑ', + 'ꞓ' => 'Ꞓ', + 'ꞗ' => 'Ꞗ', + 'ꞙ' => 'Ꞙ', + 'ꞛ' => 'Ꞛ', + 'ꞝ' => 'Ꞝ', + 'ꞟ' => 'Ꞟ', + 'ꞡ' => 'Ꞡ', + 'ꞣ' => 'Ꞣ', + 'ꞥ' => 'Ꞥ', + 'ꞧ' => 'Ꞧ', + 'ꞩ' => 'Ꞩ', + 'a' => 'A', + 'b' => 'B', + 'c' => 'C', + 'd' => 'D', + 'e' => 'E', + 'f' => 'F', + 'g' => 'G', + 'h' => 'H', + 'i' => 'I', + 'j' => 'J', + 'k' => 'K', + 'l' => 'L', + 'm' => 'M', + 'n' => 'N', + 'o' => 'O', + 'p' => 'P', + 'q' => 'Q', + 'r' => 'R', + 's' => 'S', + 't' => 'T', + 'u' => 'U', + 'v' => 'V', + 'w' => 'W', + 'x' => 'X', + 'y' => 'Y', + 'z' => 'Z', + '𐐨' => '𐐀', + '𐐩' => '𐐁', + '𐐪' => '𐐂', + '𐐫' => '𐐃', + '𐐬' => '𐐄', + '𐐭' => '𐐅', + '𐐮' => '𐐆', + '𐐯' => '𐐇', + '𐐰' => '𐐈', + '𐐱' => '𐐉', + '𐐲' => '𐐊', + '𐐳' => '𐐋', + '𐐴' => '𐐌', + '𐐵' => '𐐍', + '𐐶' => '𐐎', + '𐐷' => '𐐏', + '𐐸' => '𐐐', + '𐐹' => '𐐑', + '𐐺' => '𐐒', + '𐐻' => '𐐓', + '𐐼' => '𐐔', + '𐐽' => '𐐕', + '𐐾' => '𐐖', + '𐐿' => '𐐗', + '𐑀' => '𐐘', + '𐑁' => '𐐙', + '𐑂' => '𐐚', + '𐑃' => '𐐛', + '𐑄' => '𐐜', + '𐑅' => '𐐝', + '𐑆' => '𐐞', + '𐑇' => '𐐟', + '𐑈' => '𐐠', + '𐑉' => '𐐡', + '𐑊' => '𐐢', + '𐑋' => '𐐣', + '𐑌' => '𐐤', + '𐑍' => '𐐥', + '𐑎' => '𐐦', + '𐑏' => '𐐧', + '𑣀' => '𑢠', + '𑣁' => '𑢡', + '𑣂' => '𑢢', + '𑣃' => '𑢣', + '𑣄' => '𑢤', + '𑣅' => '𑢥', + '𑣆' => '𑢦', + '𑣇' => '𑢧', + '𑣈' => '𑢨', + '𑣉' => '𑢩', + '𑣊' => '𑢪', + '𑣋' => '𑢫', + '𑣌' => '𑢬', + '𑣍' => '𑢭', + '𑣎' => '𑢮', + '𑣏' => '𑢯', + '𑣐' => '𑢰', + '𑣑' => '𑢱', + '𑣒' => '𑢲', + '𑣓' => '𑢳', + '𑣔' => '𑢴', + '𑣕' => '𑢵', + '𑣖' => '𑢶', + '𑣗' => '𑢷', + '𑣘' => '𑢸', + '𑣙' => '𑢹', + '𑣚' => '𑢺', + '𑣛' => '𑢻', + '𑣜' => '𑢼', + '𑣝' => '𑢽', + '𑣞' => '𑢾', + '𑣟' => '𑢿', +); + +$result =& $data; +unset($data); + +return $result; diff --git a/lib/ckfinder/core/connector/php/vendor/symfony/polyfill-mbstring/bootstrap.php b/lib/ckfinder/core/connector/php/vendor/symfony/polyfill-mbstring/bootstrap.php new file mode 100644 index 0000000..3372291 --- /dev/null +++ b/lib/ckfinder/core/connector/php/vendor/symfony/polyfill-mbstring/bootstrap.php @@ -0,0 +1,56 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Polyfill\Mbstring as p; + +if (!function_exists('mb_strlen')) { + define('MB_CASE_UPPER', 0); + define('MB_CASE_LOWER', 1); + define('MB_CASE_TITLE', 2); + + function mb_convert_encoding($s, $to, $from = null) { return p\Mbstring::mb_convert_encoding($s, $to, $from); } + function mb_decode_mimeheader($s) { return p\Mbstring::mb_decode_mimeheader($s); } + function mb_encode_mimeheader($s, $charset = null, $transferEnc = null, $lf = null, $indent = null) { return p\Mbstring::mb_encode_mimeheader($s, $charset, $transferEnc, $lf, $indent); } + function mb_convert_case($s, $mode, $enc = null) { return p\Mbstring::mb_convert_case($s, $mode, $enc); } + function mb_internal_encoding($enc = null) { return p\Mbstring::mb_internal_encoding($enc); } + function mb_language($lang = null) { return p\Mbstring::mb_language($lang); } + function mb_list_encodings() { return p\Mbstring::mb_list_encodings(); } + function mb_encoding_aliases($encoding) { return p\Mbstring::mb_encoding_aliases($encoding); } + function mb_check_encoding($var = null, $encoding = null) { return p\Mbstring::mb_check_encoding($var, $encoding); } + function mb_detect_encoding($str, $encodingList = null, $strict = false) { return p\Mbstring::mb_detect_encoding($str, $encodingList, $strict); } + function mb_detect_order($encodingList = null) { return p\Mbstring::mb_detect_order($encodingList); } + function mb_parse_str($s, &$result = array()) { parse_str($s, $result); } + function mb_strlen($s, $enc = null) { return p\Mbstring::mb_strlen($s, $enc); } + function mb_strpos($s, $needle, $offset = 0, $enc = null) { return p\Mbstring::mb_strpos($s, $needle, $offset, $enc); } + function mb_strtolower($s, $enc = null) { return p\Mbstring::mb_strtolower($s, $enc); } + function mb_strtoupper($s, $enc = null) { return p\Mbstring::mb_strtoupper($s, $enc); } + function mb_substitute_character($char = null) { return p\Mbstring::mb_substitute_character($char); } + function mb_substr($s, $start, $length = 2147483647, $enc = null) { return p\Mbstring::mb_substr($s, $start, $length, $enc); } + function mb_stripos($s, $needle, $offset = 0, $enc = null) { return p\Mbstring::mb_stripos($s, $needle, $offset, $enc); } + function mb_stristr($s, $needle, $part = false, $enc = null) { return p\Mbstring::mb_stristr($s, $needle, $part, $enc); } + function mb_strrchr($s, $needle, $part = false, $enc = null) { return p\Mbstring::mb_strrchr($s, $needle, $part, $enc); } + function mb_strrichr($s, $needle, $part = false, $enc = null) { return p\Mbstring::mb_strrichr($s, $needle, $part, $enc); } + function mb_strripos($s, $needle, $offset = 0, $enc = null) { return p\Mbstring::mb_strripos($s, $needle, $offset, $enc); } + function mb_strrpos($s, $needle, $offset = 0, $enc = null) { return p\Mbstring::mb_strrpos($s, $needle, $offset, $enc); } + function mb_strstr($s, $needle, $part = false, $enc = null) { return p\Mbstring::mb_strstr($s, $needle, $part, $enc); } + function mb_get_info($type = 'all') { return p\Mbstring::mb_get_info($type); } + function mb_http_output($enc = null) { return p\Mbstring::mb_http_output($enc); } + function mb_strwidth($s, $enc = null) { return p\Mbstring::mb_strwidth($s, $enc); } + function mb_substr_count($haystack, $needle, $enc = null) { return p\Mbstring::mb_substr_count($haystack, $needle, $enc); } + function mb_output_handler($contents, $status) { return p\Mbstring::mb_output_handler($contents, $status); } + function mb_http_input($type = '') { return p\Mbstring::mb_http_input($type); } + function mb_convert_variables($toEncoding, $fromEncoding, &$a = null, &$b = null, &$c = null, &$d = null, &$e = null, &$f = null) { return p\Mbstring::mb_convert_variables($toEncoding, $fromEncoding, $a, $b, $c, $d, $e, $f); } +} +if (!function_exists('mb_chr')) { + function mb_ord($s, $enc = null) { return p\Mbstring::mb_ord($s, $enc); } + function mb_chr($code, $enc = null) { return p\Mbstring::mb_chr($code, $enc); } + function mb_scrub($s, $enc = null) { $enc = null === $enc ? mb_internal_encoding() : $enc; return mb_convert_encoding($s, $enc, $enc); } +} diff --git a/lib/ckfinder/lang/bg.json b/lib/ckfinder/lang/bg.json new file mode 100644 index 0000000..8214fd7 --- /dev/null +++ b/lib/ckfinder/lang/bg.json @@ -0,0 +1,288 @@ +{ + "appTitle": "CKFinder", + "dir": "ltr", + "langCode": "bg", + "common": { + "abort": "Abort", + "cancel": "Отказ", + "choose": "Choose", + "close": "Затвори", + "copy": "Copy", + "delete": "Изтриване", + "download": "Изтегли", + "edit": "Промяна", + "maximize": "Максимизиране", + "messageTitle": "Информация", + "minimize": "Минимизиране", + "move": "Move", + "newNameDialogTitle": "Ново име", + "ok": "ОК", + "pleaseWait": "Please wait.", + "rememberDecision": "Запомни ми избора", + "rename": "Преименуване", + "showMore": "Show more", + "skip": "Прескочи", + "upload": "Качване", + "view": "Виж" + }, + "units": { + "dateFormat": "d/m/yyyy h:MM aa", + "dateAmPm": [ + "AM", + "PM" + ], + "kb": "{size} KB", + "mb": "{size} MB", + "gb": "{size} GB", + "sizePerSecond": "{size}/s", + "pixelShort": "px" + }, + "files": { + "autoRename": "Авто-преименуване", + "countMany": "{count} файла", + "countOne": "1 файл", + "deleteConfirmation": "Are you sure you want to delete {count} files?", + "fileDeleteConfirmation": "Сигурни ли сте, че желаете да изтриете \"{name}\"?", + "fileRenameExtensionConfirmation": "Сигурни ли сте, че желаете да промените файловото разширение? Файлът може да стане неизползваем.", + "fileRenameLabel": "Моля въведете име на файл: ", + "filesPaneTitle": "Files pane", + "filesRefresh": "Refreshing files", + "filterPlaceholder": "Filter", + "gettingFileData": "Getting file data.", + "overwrite": "Препокриване", + "loadingFilesPane": { + "title": "Loading...", + "text": "The files are being loaded." + }, + "emptyFilesPane": { + "title": "The folder is empty.", + "text": "Use the Upload button or drag and drop your files here." + }, + "filterFilesEmpty": { + "title": "Nothing found.", + "text": "Please try using different search criteria." + } + }, + "folders": { + "deleteConfirmation": "Сигурни ли сте, че желаете да изтриете папката \"{name}\"?", + "destinationFolder": "Destination Folder", + "newNameLabel": "Моля въведете име на новата папка: ", + "newSubfolder": "Нов подпапка", + "renameDialogTitle": "Rename Folder", + "treeTitle": "Folders tree" + }, + "copy": { + "dropMenuItem": "Копиране тук", + "errorDialogTitle": "Files that cannot be copied:", + "manyFilesDialogTitle": "Copy {count} Files To...", + "manyFilesWait": "Copying {count} files.", + "oneFileDialogTitle": "Copy File To...", + "oneFileWait": "Copying file.", + "operationLabel": "Copying Files", + "operationSummary": "Number of files copied: {count}." + }, + "move": { + "dropMenuItem": "Местене тук", + "errorDialogTitle": "Files that cannot be moved:", + "manyFilesDialogTitle": "Move {count} Files To...", + "manyFilesWait": "Moving {count} files.", + "oneFileDialogTitle": "Move File To...", + "oneFileWait": "Moving file.", + "operationLabel": "Moving Files", + "operationSummary": "Number of files moved: {count}." + }, + "upload": { + "addFiles": "Добави файлове", + "bytesCountProgress": "({bytesUploaded} of {bytesTotal})", + "details": "Details", + "filesCountProgress": "{filesUploaded} of {filesTotal}", + "progressLabel": "Качва се в момента.", + "progressMessage": "Uploading...", + "selectFileLabel": "Изберете файл за качване", + "selectFiles": "Select files to upload", + "success": "Upload finished!", + "summary": "Uploaded files: {count}" + }, + "settings": { + "display": "Екран:", + "displayDate": "Дата", + "displayName": "Име на файл", + "displaySize": "Размер на файл", + "sortAscending": "Ascending", + "sortBy": "Sort by", + "sortByOrder": "Order", + "sortDescending": "Descending", + "thumbnailSize": "Thumbnail Size", + "title": "Настройки", + "viewType": "View", + "viewTypeCompact": "Compact", + "viewTypeList": "List", + "viewTypeThumbnails": "Thumbnails" + }, + "errors": { + "codes": { + "10": "Невалидна команда.", + "11": "Типът на ресурса не е определен в заявката.", + "12": "Заявеният тип на ресурса не е намерен.", + "13": "The connector configuration file is invalid.", + "14": "Invalid connector plugin: {pluginName}.", + "102": "Невалиден файл или име на папка.", + "103": "Не е възможно да се извърши действието заради проблем с идентификацията.", + "104": "Не е възможно да се извърши действието заради проблем с правата.", + "105": "Невалидно файлово разширение.", + "109": "Невалидна заявка.", + "110": "Неизвестна грешка.", + "111": "It was not possible to complete the request due to resulting file size.", + "115": "Файл или папка със същото име вече съществува.", + "116": "Папката не е намерена, опреснете и опитайте отново.", + "117": "Файлът не е намерен, опреснете и опитайте отново.", + "118": "Пътищата за цел и източник трябва да са еднакви.", + "201": "Файл с такова име съществува, каченият файл е преименуван на \"{name}\".", + "202": "Невалиден файл.", + "203": "Невалиден файл. Размерът е прекалено голям.", + "204": "Каченият файл е повреден.", + "205": "Няма временна папка за качените файлове.", + "206": "Качването е спряно заради проблеми със сигурността. Файлът съдържа HTML данни.", + "207": "Каченият файл е преименуван на \"{name}\".", + "300": "Преместването на файловете пропадна.", + "301": "Копирането на файловете пропадна.", + "302": "Deleting file(s) failed.", + "500": "Файловият браузър е изключен заради проблеми със сигурността. Моля свържете се с Вашия системен администратор и проверете конфигурацията.", + "501": "Поддръжката за миниатюри е изключена." + }, + "deleteFilePermissions": "Removing files is not allowed in this folder.", + "fileInvalidCharacters": "Името на файла не може да съдържа следните знаци: {disallowedCharacters}", + "fileNameNotEmpty": "The file name cannot be empty.", + "folderInvalidCharacters": "Името на папката не може да съдържа следните знаци: {disallowedCharacters}", + "incorrectExtension": "Файловото разширение не е позволено за тази папка.", + "missingFile": "The requested file is no longer available.", + "missingFolder": "The folder you are trying to reach is no longer available.", + "noUploadFolderSelected": "Моля изберете файл за качване.", + "operationCompleted": "Operation completed with errors.", + "renameFilePermissions": "Renaming files is not allowed in this folder.", + "unknown": "Не е възможно да се извърши заявката. (ГРЕШКА {number})", + "unknownUploadError": "Проблем с изпращането на файла.", + "uploadErrors": "Upload finished with errors.", + "uploadPermissions": "Качването на файлове не е позволено." + }, + "chooseResizedImage": { + "title": "Choose Resized", + "originalSize": "Original Size", + "sizes": { + "custom": "Custom", + "large": "Large", + "max": "Max", + "medium": "Medium", + "small": "Small" + } + }, + "editImage": { + "adjust": "Adjust", + "apply": "Apply", + "confirmExit": "Are you sure you want to close? You have unsaved changes to the image.", + "crop": "Crop", + "downloadAction": "Downloading original image.", + "keepAspectRatio": "Keep Aspect Ratio", + "loading": "Loading image", + "presets": "Presets", + "reset": "Reset", + "resize": "Resize", + "rotate": "Rotate", + "rotateAntiClockwise": "90° Left", + "rotateClockwise": "90° Right", + "save": "Save", + "saveDialogFileExists": "File with the same name already exists in folder.", + "saveDialogOverwrite": "Overwrite File", + "saveDialogSaveAs": "Save as:", + "saveDialogTitle": "Save Changes", + "title": "Edit Image", + "transformationAction": "Applying transformations.", + "uploadAction": "Uploading edited image.", + "filters": { + "brightness": "Brightness", + "clip": "Clip", + "contrast": "Contrast", + "exposure": "Exposure", + "gamma": "Gamma", + "hue": "Hue", + "noise": "Noise", + "saturation": "Saturation", + "sepia": "Sepia", + "sharpen": "Sharpen", + "stackBlur": "Blur", + "vibrance": "Vibrance" + }, + "preset": { + "clarity": "Clarity", + "concentrate": "Concentrate", + "crossProcess": "Cross Process", + "glowingSun": "Glowing Sun", + "grungy": "Grungy", + "hazyDays": "Hazy Days", + "hemingway": "Hemingway", + "herMajesty": "Her Majesty", + "jarques": "Jarques", + "lomo": "Lomo", + "love": "Love", + "nostalgia": "Nostalgia", + "oldBoot": "Old Boot", + "orangePeel": "Orange Peel", + "pinhole": "Pinhole", + "sinCity": "Sin City", + "sunrise": "Sunrise", + "vintage": "Vintage" + } + }, + "shortcuts": { + "title": "Keyboard Shortcuts", + "general": { + "action": "Execute default action", + "firstItem": "Go to first item", + "focusFilesPane": "Focus files pane", + "focusFoldersPane": "Focus folders pane or breadcrumbs", + "focusNext": "Focus next pane", + "focusToolbar": "Focus toolbar", + "lastItem": "Go to last item", + "listShortcuts": "Open this help dialog", + "nextItem": "Go to next item", + "previousItem": "Go to previous item", + "showContextMenu": "Open context menu", + "title": "General Interface" + }, + "files": { + "addToSelectionAbove": "Add or remove files above to selection", + "addToSelectionBelow": "Add or remove files below to selection", + "addToSelectionLeft": "Add or remove file on the left to selection", + "addToSelectionRight": "Add or remove file on the right to selection", + "delete": "Delete file(s)", + "refresh": "Refresh files", + "rename": "Rename file", + "selectAll": "Select all files", + "upload": "Upload file(s)" + }, + "folders": { + "collapseOrParent": "Collapse folder / Go to parent folder", + "delete": "Delete folder", + "expandOrSubfolder": "Expand folder / Go to first subfolder", + "title": "Folders Pane" + }, + "keys": { + "ctrl": "Control", + "delete": "Delete", + "downArrow": "Down arrow", + "escape": "Escape", + "leftArrow": "Left arrow", + "question": "Question mark", + "rightArrow": "Right arrow", + "upArrow": "Up arrow" + }, + "keysAbbreviations": { + "alt": "alt", + "ctrl": "ctrl", + "del": "del", + "end": "end", + "home": "home", + "shift": "shift" + } + } +} diff --git a/lib/ckfinder/lang/bs.json b/lib/ckfinder/lang/bs.json new file mode 100644 index 0000000..6c06120 --- /dev/null +++ b/lib/ckfinder/lang/bs.json @@ -0,0 +1,288 @@ +{ + "appTitle": "CKFinder", + "dir": "ltr", + "langCode": "bs", + "common": { + "abort": "Prekini", + "cancel": "Poništi", + "choose": "Odabir", + "close": "Zatvori", + "copy": "Kopiraj", + "delete": "Obriši", + "download": "Preuzimanje", + "edit": "Izmjena", + "maximize": "Povećaj", + "messageTitle": "Informacija", + "minimize": "Smanji", + "move": "Premjesti", + "newNameDialogTitle": "Novi naziv", + "ok": "Uredu", + "pleaseWait": "Molim, sačekajte.", + "rememberDecision": "Zapamti moj izbor", + "rename": "Promijeni naziv", + "showMore": "Prikaži više", + "skip": "Preskoči", + "upload": "Slanje", + "view": "Pregled" + }, + "units": { + "dateFormat": "dd.mm.yyyy. u HH:MM", + "dateAmPm": [ + "AM", + "PM" + ], + "kb": "{size} KB", + "mb": "{size} MB", + "gb": "{size} GB", + "sizePerSecond": "{size}/s", + "pixelShort": "px" + }, + "files": { + "autoRename": "Automatska promjena naziva", + "countMany": "{count} datoteka", + "countOne": "1 datoteka", + "deleteConfirmation": "Da li ste sigurni da želite obrisati datoteku \"{name}\"?", + "fileDeleteConfirmation": "Da li ste sigurni da želite obrisati {count} datoteke?", + "fileRenameExtensionConfirmation": "Da li ste sigurni da želite promijeniti tip datoteke? Datoteka može postati neupotrebljiva.", + "fileRenameLabel": "Unesite novo ime datoteke: ", + "filesPaneTitle": "Panel datoteka", + "filesRefresh": "Osvježavanje datoteka", + "filterPlaceholder": "Filter", + "gettingFileData": "Dobavljam podatke o datoteci. Molim, sačekajte.", + "overwrite": "Prepiši", + "loadingFilesPane": { + "title": "Učitavam...", + "text": "Molim, sačekajte. Datoteke se učitavaju." + }, + "emptyFilesPane": { + "title": "Direktorij je prazan.", + "text": "Koristite dugme Pošalji ili dovucite i ispustite vaše datoteke ovdje." + }, + "filterFilesEmpty": { + "title": "Ništa nije pronađeno.", + "text": "Pokušajte koristiti drugačiji kriterij pretraživanja." + } + }, + "folders": { + "deleteConfirmation": "Da li sigurno želite obrisati direktorij \"%1\"?", + "destinationFolder": "Odredišni direktorij", + "newNameLabel": "Unesite novo ime direktorija: ", + "newSubfolder": "New Subfolder", + "renameDialogTitle": "Promijeni naziv", + "treeTitle": "Struktura direktorija" + }, + "copy": { + "dropMenuItem": "Kopiraj ovdje", + "errorDialogTitle": "Datoteke koje nije moguće kopirati:", + "manyFilesDialogTitle": "Kopiraj {count} datoteke u...", + "manyFilesWait": "Kopiranje {count} datoteka.", + "oneFileDialogTitle": "Kopiraj datoteku u...", + "oneFileWait": "Kopiram datoteke.", + "operationLabel": "Kopiranje datoteka", + "operationSummary": "Broj kopiranih datoteka: {count}." + }, + "move": { + "dropMenuItem": "Premjesti ovdje", + "errorDialogTitle": "Datoteke koje nije moguće premjestiti:", + "manyFilesDialogTitle": "Premjesti {count} datoteke u...", + "manyFilesWait": "Premještanje {count} datoteka.", + "oneFileDialogTitle": "Premjesti datoteku u...", + "oneFileWait": "Premještam datoteke.", + "operationLabel": "Premještanje datoteka", + "operationSummary": "Broj premještenih datoteka: {count}." + }, + "upload": { + "addFiles": "dodaj datoteke", + "bytesCountProgress": "({bytesUploaded} od {bytesTotal})", + "details": "Detalji", + "filesCountProgress": "{filesUploaded} od {filesTotal}", + "progressLabel": "Slanje u toku. Molim, sačekajte...", + "progressMessage": "Uploading...", + "selectFileLabel": "Odaberite datoteku za slanje", + "selectFiles": "Odaberite datoteke za slanje", + "success": "Slanje završeno!", + "summary": "Poslanih datoteka: {count}" + }, + "settings": { + "display": "Prikaz", + "displayDate": "Datum", + "displayName": "Naziv datoteke", + "displaySize": "Veličina datoteke", + "sortAscending": "Padajući", + "sortBy": "Sortirtaj po", + "sortByOrder": "Redoslijed", + "sortDescending": "Rastući", + "thumbnailSize": "Veličina sličice", + "title": "Postavke", + "viewType": "Prikaz", + "viewTypeCompact": "Compact", + "viewTypeList": "Lista", + "viewTypeThumbnails": "Sličice" + }, + "errors": { + "codes": { + "10": "Nepoznata naredba.", + "11": "Nije navedena vrsta u zahtjevu.", + "12": "Tražena vrsta nije važeća.", + "13": "Connector konfiguracijska datoteka nije važeća.", + "14": "Nevažeći konektor plugin: {pluginName}.", + "102": "Neispravan naziv datoteke ili direktorija.", + "103": "Nije moguće izvršiti zahtjev zbog ograničenja ovlasti pristupa.", + "104": "Nije moguće izvršiti zahtjev zbog ograničenja ovlasti operativnog sistema.", + "105": "Nedozvoljena vrsta datoteke.", + "109": "Nedozvoljen zahtjev.", + "110": "Nepoznata greška.", + "111": "Nije moguće izvršiti zahtjev zbog veličine datoteke.", + "115": "Datoteka ili direktorij sa istim nazivom već postoji.", + "116": "Direktorij nije pronađen. Molim, osvježite stranicu i pokušajte ponovo.", + "117": "Datoteka nije pronađena. Molim, osvježite listu datoteka i pokušajte ponovo.", + "118": "Putanje izvora i odredišta su jednake.", + "201": "Datoteka sa istim nazivom već postoji. Naziv poslane datoteke je promijenjen u \"{name}\".", + "202": "Nevažeća datoteka.", + "203": "Nevažeća datoteka. Prevelika veličina datoteke.", + "204": "Poslana datoteka je oštećena.", + "205": "Privremeni direktorij za slanje na serveru nije dostupan.", + "206": "Slanje je poništeno zbog sigurnosnih postavki. Datoteka sadrži HTML sadržaj.", + "207": "Naziv poslane datoteke je promijenjen u \"{name}\".", + "300": "Premještanje datoteke(a) neuspješno.", + "301": "Kopiranje datoteke(a) neuspješno.", + "302": "Brisanje datoteke(a) neuspješno.", + "500": "Pretraživanje datoteka nije dozvoljeno iz sigurnosnih razloga. Molim, kontaktirajte administratora sistema i provjerite CKFinder konfiguracijsku datoteku.", + "501": "Podrška za sličice onemogućena." + }, + "deleteFilePermissions": "Removing files is not allowed in this folder.", + "fileInvalidCharacters": "Naziv datoteke ne smije sadržavati niti jedan od sljedećih znakova: {disallowedCharacters}", + "fileNameNotEmpty": "Naziv datoteke ne može biti prazan.", + "folderInvalidCharacters": "Naziv direktorija ne smije sadržavati niti jedan od sljedećih znakova: {disallowedCharacters}", + "incorrectExtension": "Vrsta datoteka nije dozvoljena u ovom direktoriju.", + "missingFile": "Tražena datoteka više nije dostupna.", + "missingFolder": "Traženi direktorij više nije dostupan.", + "noUploadFolderSelected": "Odaberite direktorije prije slanja.", + "operationCompleted": "Operacija je izvršena, ali sa greškama.", + "renameFilePermissions": "Renaming files is not allowed in this folder.", + "unknown": "Nije moguće završiti zahtjev. (Greška {number}})", + "unknownUploadError": "Greška pri slanju datoteke.", + "uploadErrors": "Slanje završeno sa greškama.", + "uploadPermissions": "Slanje datoteka nije dozvoljeno." + }, + "chooseResizedImage": { + "title": "Odaberi skalirano", + "originalSize": "Originalna veličina", + "sizes": { + "custom": "Zadano", + "large": "Velika", + "max": "Max", + "medium": "Srednja", + "small": "Mala" + } + }, + "editImage": { + "adjust": "Podešavanje", + "apply": "Prihvati izmjene", + "confirmExit": "Da li ste sigurni da želite zatvoriti? Postoje ne sačuvane izmjene na fotografiji.", + "crop": "Odsijecanje", + "downloadAction": "Preuzimanje originalne fotografije.", + "keepAspectRatio": "Zadrži omjer stranica", + "loading": "Učitavanje fotografije", + "presets": "Šabloni", + "reset": "Vrati/Poništi", + "resize": "Promjena veličine", + "rotate": "Rotacija", + "rotateAntiClockwise": "90° na lijevo", + "rotateClockwise": "90° na desno", + "save": "Sačuvaj", + "saveDialogFileExists": "Datoteka sa istim nazivom već postoji u direktoriju.", + "saveDialogOverwrite": "Prepiši datoteku", + "saveDialogSaveAs": "Sačuvaj kao:", + "saveDialogTitle": "Sačuvaj promjene", + "title": "Izmjena fotografije", + "transformationAction": "Transformacija u toku.", + "uploadAction": "Slanje uređene fotografije.", + "filters": { + "brightness": "Svjetlina", + "clip": "Clip", + "contrast": "Kontrast", + "exposure": "Ekspozicija", + "gamma": "Gamma", + "hue": "Nijansa", + "noise": "Šum", + "saturation": "Zasićenje", + "sepia": "Sepia", + "sharpen": "Oštrina", + "stackBlur": "Zamućenje", + "vibrance": "Živost" + }, + "preset": { + "clarity": "Clarity", + "concentrate": "Concentrate", + "crossProcess": "Cross Process", + "glowingSun": "Glowing Sun", + "grungy": "Grungy", + "hazyDays": "Hazy Days", + "hemingway": "Hemingway", + "herMajesty": "Her Majesty", + "jarques": "Jarques", + "lomo": "Lomo", + "love": "Love", + "nostalgia": "Nostalgia", + "oldBoot": "Old Boot", + "orangePeel": "Orange Peel", + "pinhole": "Pinhole", + "sinCity": "Sin City", + "sunrise": "Sunrise", + "vintage": "Vintage" + } + }, + "shortcuts": { + "title": "Prečice na tastaturi", + "general": { + "action": "Izvrši zadanu akciju", + "firstItem": "Idi na prvu stavku", + "focusFilesPane": "Fokusiraj panel datoteka", + "focusFoldersPane": "Fokusiraj panel direktorija", + "focusNext": "Fokusiraj naredni panel", + "focusToolbar": "Fokusiraj alatnu traku", + "lastItem": "Idi na zadnju stavku", + "listShortcuts": "Otvori dijalog za pomoć", + "nextItem": "Idi na sljedeću stavku", + "previousItem": "Idi na prošlu stavku", + "showContextMenu": "Otvori kontekst-meni", + "title": "Opšti interfejs" + }, + "files": { + "addToSelectionAbove": "Dodaj/ukloni datoteku (sa gornje strane) u odabir", + "addToSelectionBelow": "Dodaj/ukloni datoteku (sa donje strane) u odabir", + "addToSelectionLeft": "Dodaj/ukloni datoteku (sa lijeve strane) u odabir", + "addToSelectionRight": "Dodaj/ukloni datoteku (sa desne strane) u odabir", + "delete": "Obriši datoteku(e)", + "refresh": "Osvježi datoteke", + "rename": "Promijeni naziv datoteke", + "selectAll": "Odaberi sve datoteke", + "upload": "Pošalji datoteku(e)" + }, + "folders": { + "collapseOrParent": "Suzi direktorij / Idi na prethodni direktorij", + "delete": "Obriši direktorij", + "expandOrSubfolder": "Proširi direktorij / Idi na prvi poddirektorij", + "title": "Panel direktorija" + }, + "keys": { + "ctrl": "Control", + "delete": "Delete", + "downArrow": "Down arrow", + "escape": "Escape", + "leftArrow": "Left arrow", + "question": "Upitnik", + "rightArrow": "Right arrow", + "upArrow": "Up arrow" + }, + "keysAbbreviations": { + "alt": "alt", + "ctrl": "ctrl", + "del": "del", + "end": "end", + "home": "home", + "shift": "shift" + } + } +} diff --git a/lib/ckfinder/lang/ca.json b/lib/ckfinder/lang/ca.json new file mode 100644 index 0000000..9fb55f3 --- /dev/null +++ b/lib/ckfinder/lang/ca.json @@ -0,0 +1,288 @@ +{ + "appTitle": "CKFinder", + "dir": "ltr", + "langCode": "ca", + "common": { + "abort": "Abort", + "cancel": "Cancel·lar", + "choose": "Choose", + "close": "Tancar", + "copy": "Copy", + "delete": "Esborrar", + "download": "Descarregar", + "edit": "Editar", + "maximize": "Maximitzar", + "messageTitle": "Informació", + "minimize": "Minimitzar", + "move": "Move", + "newNameDialogTitle": "Nou nom", + "ok": "Acceptar", + "pleaseWait": "Please wait.", + "rememberDecision": "Recordar la meva decisió", + "rename": "Canviar el nom", + "showMore": "Show more", + "skip": "Ometre", + "upload": "Afegir", + "view": "Veure" + }, + "units": { + "dateFormat": "dd/mm/yyyy H:MM", + "dateAmPm": [ + "AM", + "PM" + ], + "kb": "{size} KB", + "mb": "{size} MB", + "gb": "{size} GB", + "sizePerSecond": "{size}/s", + "pixelShort": "px" + }, + "files": { + "autoRename": "Auto-renombrar", + "countMany": "{count} fitxers", + "countOne": "1 fitxer", + "deleteConfirmation": "Estàs segur d'esborrar els {count} fitxers?", + "fileDeleteConfirmation": "Estàs segur d'esborrar el fitxer \"{name}\"?", + "fileRenameExtensionConfirmation": "Estàs segur de canviar la extensió del fitxer? El fitxer pot quedar inservible.", + "fileRenameLabel": "Si us plau, escriu el nom del fitxer: ", + "filesPaneTitle": "Files pane", + "filesRefresh": "Refreshing files", + "filterPlaceholder": "Filter", + "gettingFileData": "Getting file data.", + "overwrite": "Sobreescriure", + "loadingFilesPane": { + "title": "Loading...", + "text": "The files are being loaded." + }, + "emptyFilesPane": { + "title": "The folder is empty.", + "text": "Use the Upload button or drag and drop your files here." + }, + "filterFilesEmpty": { + "title": "Nothing found.", + "text": "Please try using different search criteria." + } + }, + "folders": { + "deleteConfirmation": "Estàs segur que vols esborrar la carpeta \"{name}\"?", + "destinationFolder": "Carpeta de destinació", + "newNameLabel": "Si us plau, escriu el nom per la nova carpeta: ", + "newSubfolder": "Nova Subcarpeta", + "renameDialogTitle": "Rename Folder", + "treeTitle": "Folders tree" + }, + "copy": { + "dropMenuItem": "Copiar aquí", + "errorDialogTitle": "Files that cannot be copied:", + "manyFilesDialogTitle": "Copy {count} Files To...", + "manyFilesWait": "Copying {count} files.", + "oneFileDialogTitle": "Copy File To...", + "oneFileWait": "Copying file.", + "operationLabel": "Copying Files", + "operationSummary": "Número de fitxers copiats: {count}." + }, + "move": { + "dropMenuItem": "Moure aquí", + "errorDialogTitle": "Files that cannot be moved:", + "manyFilesDialogTitle": "Move {count} Files To...", + "manyFilesWait": "Moving {count} files.", + "oneFileDialogTitle": "Move File To...", + "oneFileWait": "Moving file.", + "operationLabel": "Moving Files", + "operationSummary": "Número de fitxers moguts: {count}." + }, + "upload": { + "addFiles": "Afegir fitxers", + "bytesCountProgress": "({bytesUploaded} of {bytesTotal})", + "details": "Details", + "filesCountProgress": "{filesUploaded} of {filesTotal}", + "progressLabel": "Pujada en progrés.", + "progressMessage": "Uploading...", + "selectFileLabel": "Triar el fitxer a pujar", + "selectFiles": "Select files to upload", + "success": "Upload finished!", + "summary": "Uploaded files: {count}" + }, + "settings": { + "display": "Mostrar:", + "displayDate": "Data", + "displayName": "Nom del fitxer", + "displaySize": "Grandària del fitxer", + "sortAscending": "Ascending", + "sortBy": "Sort by", + "sortByOrder": "Order", + "sortDescending": "Descending", + "thumbnailSize": "Thumbnail Size", + "title": "Configuració", + "viewType": "View", + "viewTypeCompact": "Compact", + "viewTypeList": "List", + "viewTypeThumbnails": "Thumbnails" + }, + "errors": { + "codes": { + "10": "Ordre incorrecte.", + "11": "El tipus de recurs no ha estat especificat a la solicitut.", + "12": "El tipus de recurs solicitat no és vàlid.", + "13": "The connector configuration file is invalid.", + "14": "Invalid connector plugin: {pluginName}.", + "102": "Nom de fitxer o carpeta no vàlids.", + "103": "No s'ha pogut completar la solicitut degut a les restriccions d'autorització.", + "104": "No s'ha pogut completar la solicitut degut a les restriccions en el sistema de fitxers.", + "105": "La extensió del fitxer no es vàlida.", + "109": "Petició invàlida.", + "110": "Error desconegut.", + "111": "No ha estat possible completar l'operació a causa de la grandària del fitxer resultant.", + "115": "Ja existeix un fitxer o carpeta amb aquest nom.", + "116": "No s'ha trobat la carpeta. Si us plau, actualitzi i torni-ho a provar.", + "117": "No s'ha trobat el fitxer. Si us plau, actualitzi i torni-ho a provar.", + "118": "Les rutes origen i destí són iguals.", + "201": "Ja existeix un fitxer amb aquest nom. El fitxer pujat ha estat renombrat com a \"{name}\".", + "202": "Fitxer invàlid.", + "203": "Fitxer invàlid. El pes és massa gran.", + "204": "El fitxer pujat està corrupte.", + "205": "La carpeta temporal no està disponible en el servidor per poder realitzar pujades.", + "206": "La pujada s'ha cancel·lat per raons de seguretat. El fitxer conté codi HTML.", + "207": "El fitxer pujat ha estat renombrat com a \"{name}\".", + "300": "Ha fallat el moure el(s) fitxer(s).", + "301": "Ha fallat el copiar el(s) fitxer(s).", + "302": "Deleting file(s) failed.", + "500": "El navegador de fitxers està deshabilitat per raons de seguretat. Si us plau, contacti amb l'administrador del sistema i comprovi el fitxer de configuració de CKFinder.", + "501": "El suport per a icones està deshabilitat." + }, + "deleteFilePermissions": "Removing files is not allowed in this folder.", + "fileInvalidCharacters": "El nom del fitxer no pot contenir cap dels caràcters següents: {disallowedCharacters}", + "fileNameNotEmpty": "The file name cannot be empty.", + "folderInvalidCharacters": "El nom de la carpeta no pot contenir cap dels caràcters següents: {disallowedCharacters}", + "incorrectExtension": "La extensió del fitxer no està permesa en aquesta carpeta.", + "missingFile": "The requested file is no longer available.", + "missingFolder": "The folder you are trying to reach is no longer available.", + "noUploadFolderSelected": "Si us plau, escull la carpeta abans d'iniciar la pujada.", + "operationCompleted": "Operació completada amb errors.", + "renameFilePermissions": "Renaming files is not allowed in this folder.", + "unknown": "No ha estat possible completar la solicitut. (Error {number})", + "unknownUploadError": "Error enviant el fitxer.", + "uploadErrors": "Upload finished with errors.", + "uploadPermissions": "No pot pujar fitxers." + }, + "chooseResizedImage": { + "title": "Choose Resized", + "originalSize": "Original Size", + "sizes": { + "custom": "Custom", + "large": "Large", + "max": "Max", + "medium": "Medium", + "small": "Small" + } + }, + "editImage": { + "adjust": "Adjust", + "apply": "Apply", + "confirmExit": "Are you sure you want to close? You have unsaved changes to the image.", + "crop": "Crop", + "downloadAction": "Downloading original image.", + "keepAspectRatio": "Keep Aspect Ratio", + "loading": "Loading image", + "presets": "Presets", + "reset": "Reset", + "resize": "Resize", + "rotate": "Rotate", + "rotateAntiClockwise": "90° Left", + "rotateClockwise": "90° Right", + "save": "Save", + "saveDialogFileExists": "File with the same name already exists in folder.", + "saveDialogOverwrite": "Overwrite File", + "saveDialogSaveAs": "Save as:", + "saveDialogTitle": "Save Changes", + "title": "Edit Image", + "transformationAction": "Applying transformations.", + "uploadAction": "Uploading edited image.", + "filters": { + "brightness": "Brightness", + "clip": "Clip", + "contrast": "Contrast", + "exposure": "Exposure", + "gamma": "Gamma", + "hue": "Hue", + "noise": "Noise", + "saturation": "Saturation", + "sepia": "Sepia", + "sharpen": "Sharpen", + "stackBlur": "Blur", + "vibrance": "Vibrance" + }, + "preset": { + "clarity": "Clarity", + "concentrate": "Concentrate", + "crossProcess": "Cross Process", + "glowingSun": "Glowing Sun", + "grungy": "Grungy", + "hazyDays": "Hazy Days", + "hemingway": "Hemingway", + "herMajesty": "Her Majesty", + "jarques": "Jarques", + "lomo": "Lomo", + "love": "Love", + "nostalgia": "Nostalgia", + "oldBoot": "Old Boot", + "orangePeel": "Orange Peel", + "pinhole": "Pinhole", + "sinCity": "Sin City", + "sunrise": "Sunrise", + "vintage": "Vintage" + } + }, + "shortcuts": { + "title": "Keyboard Shortcuts", + "general": { + "action": "Execute default action", + "firstItem": "Go to first item", + "focusFilesPane": "Focus files pane", + "focusFoldersPane": "Focus folders pane or breadcrumbs", + "focusNext": "Focus next pane", + "focusToolbar": "Focus toolbar", + "lastItem": "Go to last item", + "listShortcuts": "Open this help dialog", + "nextItem": "Go to next item", + "previousItem": "Go to previous item", + "showContextMenu": "Open context menu", + "title": "General Interface" + }, + "files": { + "addToSelectionAbove": "Add or remove files above to selection", + "addToSelectionBelow": "Add or remove files below to selection", + "addToSelectionLeft": "Add or remove file on the left to selection", + "addToSelectionRight": "Add or remove file on the right to selection", + "delete": "Delete file(s)", + "refresh": "Refresh files", + "rename": "Rename file", + "selectAll": "Select all files", + "upload": "Upload file(s)" + }, + "folders": { + "collapseOrParent": "Collapse folder / Go to parent folder", + "delete": "Delete folder", + "expandOrSubfolder": "Expand folder / Go to first subfolder", + "title": "Folders Pane" + }, + "keys": { + "ctrl": "Control", + "delete": "Delete", + "downArrow": "Down arrow", + "escape": "Escape", + "leftArrow": "Left arrow", + "question": "Question mark", + "rightArrow": "Right arrow", + "upArrow": "Up arrow" + }, + "keysAbbreviations": { + "alt": "alt", + "ctrl": "ctrl", + "del": "del", + "end": "end", + "home": "home", + "shift": "shift" + } + } +} diff --git a/lib/ckfinder/lang/cs.json b/lib/ckfinder/lang/cs.json new file mode 100644 index 0000000..455e9c8 --- /dev/null +++ b/lib/ckfinder/lang/cs.json @@ -0,0 +1,288 @@ +{ + "appTitle": "CKFinder", + "dir": "ltr", + "langCode": "cs", + "common": { + "abort": "Ukončit", + "cancel": "Zrušit", + "choose": "Zvolte", + "close": "Zavřít", + "copy": "Kopírovat", + "delete": "Smazat", + "download": "Uložit jako", + "edit": "Upravit", + "maximize": "Maximalizovat", + "messageTitle": "Informace", + "minimize": "Minimalizovat", + "move": "Přesunout", + "newNameDialogTitle": "Nový název", + "ok": "OK", + "pleaseWait": "Čekejte prosím.", + "rememberDecision": "Zapamatovat si mé rozhodnutí", + "rename": "Přejmenovat", + "showMore": "Zobrazit více", + "skip": "Přeskočit", + "upload": "Nahrát", + "view": "Zobrazit" + }, + "units": { + "dateFormat": "d/m/yyyy H:MM", + "dateAmPm": [ + "AM", + "PM" + ], + "kb": "{size} KB", + "mb": "{size} MB", + "gb": "{size} GB", + "sizePerSecond": "{size}/s", + "pixelShort": "px" + }, + "files": { + "autoRename": "Automaticky přejmenovat", + "countMany": "{count} souborů", + "countOne": "1 soubor", + "deleteConfirmation": "Opravdu chcete smazat {count} souborů?", + "fileDeleteConfirmation": "Opravdu chcete smazat soubor \"{name}\"?", + "fileRenameExtensionConfirmation": "Opravdu chcete změnit příponu souboru? Soubor se může stát nepoužitelným.", + "fileRenameLabel": "Zadejte nový název souboru: ", + "filesPaneTitle": "Panel souborů", + "filesRefresh": "Obnovování souborů", + "filterPlaceholder": "Filtrovat", + "gettingFileData": "Získávání dat souborů.", + "overwrite": "Přepsat", + "loadingFilesPane": { + "title": "Načítání...", + "text": "Probíhá načítání souborů." + }, + "emptyFilesPane": { + "title": "Složka je prázdná.", + "text": "Použijte tlačítko Nahrát nebo sem vaše soubory přetáhněte." + }, + "filterFilesEmpty": { + "title": "Nic nenalezeno.", + "text": "Zkuste prosím zadat jiné kritérium vyhledávání." + } + }, + "folders": { + "deleteConfirmation": "Opravdu chcete složku \"{name}\" smazat?", + "destinationFolder": "Cílová složka", + "newNameLabel": "Zadejte název nové složky: ", + "newSubfolder": "Nová podsložka", + "renameDialogTitle": "Přejmenovat složku", + "treeTitle": "Strom složek" + }, + "copy": { + "dropMenuItem": "Zkopírovat sem", + "errorDialogTitle": "Soubory, které nelze zkopírovat:", + "manyFilesDialogTitle": "Kopírovat {count} souborů do...", + "manyFilesWait": "Kopírování {count} souborů.", + "oneFileDialogTitle": "Kopírovat soubor do...", + "oneFileWait": "Kopírování souboru.", + "operationLabel": "Kopírování souborů", + "operationSummary": "Počet zkopírovaných souborů: {count}." + }, + "move": { + "dropMenuItem": "Přesunout sem", + "errorDialogTitle": "Soubory, které nelze přesunout:", + "manyFilesDialogTitle": "Přesunout {count} souborů do...", + "manyFilesWait": "Přesunování {count} souborů.", + "oneFileDialogTitle": "Přesunout soubor do...", + "oneFileWait": "Přesunování souboru.", + "operationLabel": "Přesunování souborů", + "operationSummary": "Počet přesunutých souborů: {count}." + }, + "upload": { + "addFiles": "Přidat soubory", + "bytesCountProgress": "({bytesUploaded} z {bytesTotal})", + "details": "Podrobnosti", + "filesCountProgress": "{filesUploaded} z {filesTotal}", + "progressLabel": "Probíhá nahrávání.", + "progressMessage": "Nahrávání...", + "selectFileLabel": "Zvolit soubor k nahrání", + "selectFiles": "Vyberte soubory k nahrání", + "success": "Nahrávání dokončeno!", + "summary": "Nahrané soubory: {count}" + }, + "settings": { + "display": "Zobrazit:", + "displayDate": "Datum", + "displayName": "Název", + "displaySize": "Velikost", + "sortAscending": "Vzestupně", + "sortBy": "Seřadit", + "sortByOrder": "Pořadí", + "sortDescending": "Sestupně", + "thumbnailSize": "Velikost miniatury", + "title": "Nastavení", + "viewType": "Zobrazení", + "viewTypeCompact": "Compact", + "viewTypeList": "Seznam", + "viewTypeThumbnails": "Miniatury" + }, + "errors": { + "codes": { + "10": "Neplatný příkaz.", + "11": "Typ zdroje nebyl v požadavku určen.", + "12": "Požadovaný typ zdroje není platný.", + "13": "Soubor s nastavením konektoru je neplatný.", + "14": "Neplatný zásuvný model konektoru: {pluginName}.", + "102": "Špatné název souboru, nebo složky.", + "103": "Nebylo možné příkaz dokončit kvůli omezení oprávnění.", + "104": "Nebylo možné příkaz dokončit kvůli omezení oprávnění souborového systému.", + "105": "Neplatná přípona souboru.", + "109": "Neplatný požadavek.", + "110": "Neznámá chyba.", + "111": "Požadavek nemohl být splněn kvůli výsledné velikosti souboru.", + "115": "Soubor nebo složka se stejným názvem již existuje.", + "116": "Složka nenalezena, prosím obnovte a zkuste znovu.", + "117": "Soubor nenalezen, prosím obnovte seznam souborů a zkuste znovu.", + "118": "Cesty zdroje a cíle jsou stejné.", + "201": "Soubor se stejným názvem je již dostupný, nahraný soubor byl přejmenován na \"{name}\".", + "202": "Neplatný soubor.", + "203": "Neplatný soubor. Velikost souboru je příliš velká.", + "204": "Nahraný soubor je poškozen.", + "205": "Na serveru není dostupná dočasná složka pro nahrávání.", + "206": "Nahrávání zrušeno z bezpečnostních důvodů. Soubor obsahuje data podobná HTML.", + "207": "Nahraný soubor byl přejmenován na \"{name}\".", + "300": "Přesunování souboru(ů) selhalo.", + "301": "Kopírování souboru(ů) selhalo.", + "302": "Mazání souborů selhalo.", + "500": "Průzkumník souborů je z bezpečnostních důvodů zakázán. Sdělte to prosím správci systému a zkontrolujte soubor nastavení CKFinder.", + "501": "Podpora náhledů je zakázána." + }, + "deleteFilePermissions": "Removing files is not allowed in this folder.", + "fileInvalidCharacters": "Název souboru nesmí obsahovat následující znaky: {disallowedCharacters}", + "fileNameNotEmpty": "Název souboru nemůže být prázdný.", + "folderInvalidCharacters": "Název složky nesmí obsahovat následující znaky: {disallowedCharacters}", + "incorrectExtension": "Přípona souboru není v této složce povolena.", + "missingFile": "Požadovaný soubor již není dostupný.", + "missingFolder": "Složka, kterou chcete zobrazit, již není dostupná.", + "noUploadFolderSelected": "Před nahráváním vyberte složku prosím.", + "operationCompleted": "Operace byla dokončena s chybami.", + "renameFilePermissions": "Renaming files is not allowed in this folder.", + "unknown": "Příkaz nebylo možné dokončit. (Chyba {number})", + "unknownUploadError": "Chyba při posílání souboru.", + "uploadErrors": "Nahrávání bylo dokončeno s chybami.", + "uploadPermissions": "Nahrávání souborů není povoleno." + }, + "chooseResizedImage": { + "title": "Zvolit velikost", + "originalSize": "Původní velikost", + "sizes": { + "custom": "Vlastní", + "large": "Velká", + "max": "Maximální", + "medium": "Střední", + "small": "Malá" + } + }, + "editImage": { + "adjust": "Přizpůsobit", + "apply": "Použít", + "confirmExit": "Opravdu chcete úpravu zavřít? V obrázku máte neuložené změny.", + "crop": "Oříznout", + "downloadAction": "Stahování původního obrázku.", + "keepAspectRatio": "Zachovat poměr stran", + "loading": "Načítání obrázku", + "presets": "Přednastavené", + "reset": "Resetovat", + "resize": "Změnit velikost", + "rotate": "Otočit", + "rotateAntiClockwise": "90° doleva", + "rotateClockwise": "90° doprava", + "save": "Uložit", + "saveDialogFileExists": "V této složce již existuje soubor s tímto názvem.", + "saveDialogOverwrite": "Přepsat soubor", + "saveDialogSaveAs": "Uložit jako:", + "saveDialogTitle": "Uložit změny", + "title": "Upravit obrázek", + "transformationAction": "Používání transformací.", + "uploadAction": "Nahrávání upraveného obrázku.", + "filters": { + "brightness": "Jas", + "clip": "Sestřihnout", + "contrast": "Kontrast", + "exposure": "Expozice", + "gamma": "Gama", + "hue": "Odstín", + "noise": "Šum", + "saturation": "Nasycení", + "sepia": "Sépie", + "sharpen": "Zostření", + "stackBlur": "Rozostření", + "vibrance": "Zářivost" + }, + "preset": { + "clarity": "Čistota", + "concentrate": "Koncentrace", + "crossProcess": "Cross Process", + "glowingSun": "Zářící slunce", + "grungy": "Výstřední", + "hazyDays": "Zamlžené", + "hemingway": "Hemingway", + "herMajesty": "Její Výsost", + "jarques": "Jarques", + "lomo": "Lomo", + "love": "Láska", + "nostalgia": "Nostalgie", + "oldBoot": "Stará bota", + "orangePeel": "Pomerančová slupka", + "pinhole": "Děrovaný papír", + "sinCity": "Město hříchu", + "sunrise": "Svítání", + "vintage": "Zastaralé" + } + }, + "shortcuts": { + "title": "Klávesové zkratky", + "general": { + "action": "Provést výchozí činnost", + "firstItem": "Přejít na první položku", + "focusFilesPane": "Zaměřit panel souborů", + "focusFoldersPane": "Zaměřit panel složek nebo navigační cestu", + "focusNext": "Zaměřit další panel", + "focusToolbar": "Zaměřit panel nástrojů", + "lastItem": "Přejít na poslední položku", + "listShortcuts": "Otevřít toto dialogové okno s nápovědou", + "nextItem": "Přejít na další položku", + "previousItem": "Přejít na předchozí položku", + "showContextMenu": "Otevřít kontextovou nabídku", + "title": "Obecné rozhraní" + }, + "files": { + "addToSelectionAbove": "Přidat nebo odebrat soubory výše z/do výběru", + "addToSelectionBelow": "Přidat nebo odebrat soubory níže z/do výběru", + "addToSelectionLeft": "Přidat nebo odebrat soubor nalevo z/do výběru", + "addToSelectionRight": "Přidat nebo odebrat soubor napravo z/do výběru", + "delete": "Smazat soubor(y)", + "refresh": "Obnovit soubory", + "rename": "Přejmenovat soubor", + "selectAll": "Vybrat všechny soubory", + "upload": "Nahrát soubor(y)" + }, + "folders": { + "collapseOrParent": "Sbalit složku / Přejít na nadřazenou složku", + "delete": "Smazat složku", + "expandOrSubfolder": "Rozbalit složku / Přejít na první podsložku", + "title": "Panel složek" + }, + "keys": { + "ctrl": "Control", + "delete": "Delete", + "downArrow": "Šipka dolů", + "escape": "Escape", + "leftArrow": "Šipka vlevo", + "question": "Otazník", + "rightArrow": "Šipka vpravo", + "upArrow": "Šipka nahoru" + }, + "keysAbbreviations": { + "alt": "alt", + "ctrl": "ctrl", + "del": "del", + "end": "end", + "home": "home", + "shift": "shift" + } + } +} diff --git a/lib/ckfinder/lang/cy.json b/lib/ckfinder/lang/cy.json new file mode 100644 index 0000000..c0c222a --- /dev/null +++ b/lib/ckfinder/lang/cy.json @@ -0,0 +1,288 @@ +{ + "appTitle": "CKFinder", + "dir": "ltr", + "langCode": "cy", + "common": { + "abort": "Abort", + "cancel": "Diddymu", + "choose": "Choose", + "close": "Cau", + "copy": "Copy", + "delete": "Dileu", + "download": "Lawrlwytho", + "edit": "Golygu", + "maximize": "Uchafu", + "messageTitle": "Gwybodaeth", + "minimize": "Isafu", + "move": "Move", + "newNameDialogTitle": "Enw Newydd", + "ok": "OK", + "pleaseWait": "Please wait.", + "rememberDecision": "Cofio fy mhenderfyniad", + "rename": "Ailenwi", + "showMore": "Show more", + "skip": "Neidio", + "upload": "Lanlwytho", + "view": "Dangos" + }, + "units": { + "dateFormat": "mm/dd/yyyy HH:MM", + "dateAmPm": [ + "yB", + "yH" + ], + "kb": "{size} KB", + "mb": "{size} MB", + "gb": "{size} GB", + "sizePerSecond": "{size}/s", + "pixelShort": "px" + }, + "files": { + "autoRename": "Awto-ailenwi", + "countMany": "{count} ffeil", + "countOne": "1 ffeil", + "deleteConfirmation": "Are you sure you want to delete {count} files?", + "fileDeleteConfirmation": "Ydych chi wir am ddileu'r ffeil \"{name}\"?", + "fileRenameExtensionConfirmation": "Ydych chi wir am newid estyniad y ffeil? Gall hwn atal y ffeil rhag gweithio.", + "fileRenameLabel": "Rhowch enw newydd y ffeil: ", + "filesPaneTitle": "Files pane", + "filesRefresh": "Refreshing files", + "filterPlaceholder": "Filter", + "gettingFileData": "Getting file data.", + "overwrite": "Trosysgrifo", + "loadingFilesPane": { + "title": "Loading...", + "text": "The files are being loaded." + }, + "emptyFilesPane": { + "title": "The folder is empty.", + "text": "Use the Upload button or drag and drop your files here." + }, + "filterFilesEmpty": { + "title": "Nothing found.", + "text": "Please try using different search criteria." + } + }, + "folders": { + "deleteConfirmation": "Ydych chi wir am ddileu'r ffolder \"{name}\"?", + "destinationFolder": "Destination Folder", + "newNameLabel": "Rhowch enw newydd y ffolder: ", + "newSubfolder": "Is-ffolder Newydd", + "renameDialogTitle": "Rename Folder", + "treeTitle": "Folders tree" + }, + "copy": { + "dropMenuItem": "Copïo Yma", + "errorDialogTitle": "Files that cannot be copied:", + "manyFilesDialogTitle": "Copy {count} Files To...", + "manyFilesWait": "Copying {count} files.", + "oneFileDialogTitle": "Copy File To...", + "oneFileWait": "Copying file.", + "operationLabel": "Copying Files", + "operationSummary": "Number of files copied: {count}." + }, + "move": { + "dropMenuItem": "Symud Yma", + "errorDialogTitle": "Files that cannot be moved:", + "manyFilesDialogTitle": "Move {count} Files To...", + "manyFilesWait": "Moving {count} files.", + "oneFileDialogTitle": "Move File To...", + "oneFileWait": "Moving file.", + "operationLabel": "Moving Files", + "operationSummary": "Number of files moved: {count}." + }, + "upload": { + "addFiles": "Ychwanegu Ffeiliau", + "bytesCountProgress": "({bytesUploaded} of {bytesTotal})", + "details": "Details", + "filesCountProgress": "{filesUploaded} of {filesTotal}", + "progressLabel": "Lanlwythiad ar y gweill.", + "progressMessage": "Uploading...", + "selectFileLabel": "Dewis ffeil i lanlwytho", + "selectFiles": "Select files to upload", + "success": "Upload finished!", + "summary": "Uploaded files: {count}" + }, + "settings": { + "display": "Arddangosiad:", + "displayDate": "Dyddiad", + "displayName": "Enw'r Ffeil", + "displaySize": "Maint y Ffeil", + "sortAscending": "Ascending", + "sortBy": "Sort by", + "sortByOrder": "Order", + "sortDescending": "Descending", + "thumbnailSize": "Thumbnail Size", + "title": "Gosodiadau", + "viewType": "View", + "viewTypeCompact": "Compact", + "viewTypeList": "List", + "viewTypeThumbnails": "Thumbnails" + }, + "errors": { + "codes": { + "10": "Gorchymyn annilys.", + "11": "Doedd math yr adnodd heb ei benodi yn y cais.", + "12": "Dyw math yr adnodd ddim yn ddilys.", + "13": "The connector configuration file is invalid.", + "14": "Invalid connector plugin: {pluginName}.", + "102": "Enw ffeil neu ffolder annilys.", + "103": "Doedd dim modd cwblhau'r cais oherwydd cyfyngiadau awdurdodi.", + "104": "Doedd dim modd cwblhau'r cais oherwydd cyfyngiadau i hawliau'r system ffeilio.", + "105": "Estyniad ffeil annilys.", + "109": "Cais annilys.", + "110": "Gwall anhysbys.", + "111": "It was not possible to complete the request due to resulting file size.", + "115": "Mae ffeil neu ffolder gyda'r un enw yn bodoli yn barod.", + "116": "Methu â darganfod y ffolder. Adfywiwch a cheisio eto.", + "117": "Methu â darganfod y ffeil. Adfywiwch y rhestr ffeiliau a cheisio eto.", + "118": "Mae'r llwybrau gwreiddiol a tharged yn unfath.", + "201": "Mae ffeil â'r enw hwnnw yn bodoli yn barod. Cafodd y ffeil a lanlwythwyd ei hailenwi i \"{name}\".", + "202": "Ffeil annilys.", + "203": "Ffeil annilys. Mae maint y ffeil yn rhy fawr.", + "204": "Mae'r ffeil a lanwythwyd wedi chwalu.", + "205": "Does dim ffolder dros dro ar gael er mwyn lanlwytho ffeiliau iddo ar y gweinydd hwn.", + "206": "Cafodd y lanlwythiad ei ddiddymu oherwydd rhesymau diogelwch. Mae'r ffeil yn cynnwys data yn debyg i HTML.", + "207": "Cafodd y ffeil a lanlwythwyd ei hailenwi i \"{name}\".", + "300": "Methodd symud y ffeil(iau).", + "301": "Methodd copïo'r ffeil(iau).", + "302": "Deleting file(s) failed.", + "500": "Cafodd y porwr ffeiliau ei anallogi oherwydd rhesymau diogelwch. Cysylltwch â'ch gweinyddwr system a gwirio'ch ffeil ffurfwedd CKFinder.", + "501": "Mae cynhaliaeth bawdluniau wedi'i hanalluogi." + }, + "deleteFilePermissions": "Removing files is not allowed in this folder.", + "fileInvalidCharacters": "Does dim hawl defnyddio'r nodau canlynol i enwi ffeil: {disallowedCharacters}", + "fileNameNotEmpty": "The file name cannot be empty.", + "folderInvalidCharacters": "Does dim hawl defnyddio'r nodau canlynol i enwi ffolder: {disallowedCharacters}", + "incorrectExtension": "Does dim hawl cadw'r ffeiliau â'r estyniad hwn yn y ffolder hwn.", + "missingFile": "The requested file is no longer available.", + "missingFolder": "The folder you are trying to reach is no longer available.", + "noUploadFolderSelected": "Dewiswch ffolder cyn lanlwytho.", + "operationCompleted": "Operation completed with errors.", + "renameFilePermissions": "Renaming files is not allowed in this folder.", + "unknown": "Does dim modd cwblhau'r cais. (Gwall {number})", + "unknownUploadError": "Gwall wrth anfon y ffeil.", + "uploadErrors": "Upload finished with errors.", + "uploadPermissions": "Does dim hawl lanlwytho ffeiliau." + }, + "chooseResizedImage": { + "title": "Choose Resized", + "originalSize": "Original Size", + "sizes": { + "custom": "Custom", + "large": "Large", + "max": "Max", + "medium": "Medium", + "small": "Small" + } + }, + "editImage": { + "adjust": "Adjust", + "apply": "Apply", + "confirmExit": "Are you sure you want to close? You have unsaved changes to the image.", + "crop": "Crop", + "downloadAction": "Downloading original image.", + "keepAspectRatio": "Keep Aspect Ratio", + "loading": "Loading image", + "presets": "Presets", + "reset": "Reset", + "resize": "Resize", + "rotate": "Rotate", + "rotateAntiClockwise": "90° Left", + "rotateClockwise": "90° Right", + "save": "Save", + "saveDialogFileExists": "File with the same name already exists in folder.", + "saveDialogOverwrite": "Overwrite File", + "saveDialogSaveAs": "Save as:", + "saveDialogTitle": "Save Changes", + "title": "Edit Image", + "transformationAction": "Applying transformations.", + "uploadAction": "Uploading edited image.", + "filters": { + "brightness": "Brightness", + "clip": "Clip", + "contrast": "Contrast", + "exposure": "Exposure", + "gamma": "Gamma", + "hue": "Hue", + "noise": "Noise", + "saturation": "Saturation", + "sepia": "Sepia", + "sharpen": "Sharpen", + "stackBlur": "Blur", + "vibrance": "Vibrance" + }, + "preset": { + "clarity": "Clarity", + "concentrate": "Concentrate", + "crossProcess": "Cross Process", + "glowingSun": "Glowing Sun", + "grungy": "Grungy", + "hazyDays": "Hazy Days", + "hemingway": "Hemingway", + "herMajesty": "Her Majesty", + "jarques": "Jarques", + "lomo": "Lomo", + "love": "Love", + "nostalgia": "Nostalgia", + "oldBoot": "Old Boot", + "orangePeel": "Orange Peel", + "pinhole": "Pinhole", + "sinCity": "Sin City", + "sunrise": "Sunrise", + "vintage": "Vintage" + } + }, + "shortcuts": { + "title": "Keyboard Shortcuts", + "general": { + "action": "Execute default action", + "firstItem": "Go to first item", + "focusFilesPane": "Focus files pane", + "focusFoldersPane": "Focus folders pane or breadcrumbs", + "focusNext": "Focus next pane", + "focusToolbar": "Focus toolbar", + "lastItem": "Go to last item", + "listShortcuts": "Open this help dialog", + "nextItem": "Go to next item", + "previousItem": "Go to previous item", + "showContextMenu": "Open context menu", + "title": "General Interface" + }, + "files": { + "addToSelectionAbove": "Add or remove files above to selection", + "addToSelectionBelow": "Add or remove files below to selection", + "addToSelectionLeft": "Add or remove file on the left to selection", + "addToSelectionRight": "Add or remove file on the right to selection", + "delete": "Delete file(s)", + "refresh": "Refresh files", + "rename": "Rename file", + "selectAll": "Select all files", + "upload": "Upload file(s)" + }, + "folders": { + "collapseOrParent": "Collapse folder / Go to parent folder", + "delete": "Delete folder", + "expandOrSubfolder": "Expand folder / Go to first subfolder", + "title": "Folders Pane" + }, + "keys": { + "ctrl": "Control", + "delete": "Delete", + "downArrow": "Down arrow", + "escape": "Escape", + "leftArrow": "Left arrow", + "question": "Question mark", + "rightArrow": "Right arrow", + "upArrow": "Up arrow" + }, + "keysAbbreviations": { + "alt": "alt", + "ctrl": "ctrl", + "del": "del", + "end": "end", + "home": "home", + "shift": "shift" + } + } +} diff --git a/lib/ckfinder/lang/da.json b/lib/ckfinder/lang/da.json new file mode 100644 index 0000000..55e1acd --- /dev/null +++ b/lib/ckfinder/lang/da.json @@ -0,0 +1,288 @@ +{ + "appTitle": "CKFinder", + "dir": "ltr", + "langCode": "da", + "common": { + "abort": "Abort", + "cancel": "Annullér", + "choose": "Vælg", + "close": "Luk", + "copy": "Kopier", + "delete": "Slet", + "download": "Download", + "edit": "Redigér", + "maximize": "Maksimér", + "messageTitle": "Information", + "minimize": "Minimér", + "move": "Flyt", + "newNameDialogTitle": "Nyt navn", + "ok": "OK", + "pleaseWait": "Vent venligst.", + "rememberDecision": "Husk denne indstilling", + "rename": "Omdøb", + "showMore": "Vis mere", + "skip": "Spring over", + "upload": "Upload", + "view": "Vis" + }, + "units": { + "dateFormat": "dd-mm-yyyy HH:MM", + "dateAmPm": [ + "AM", + "PM" + ], + "kb": "{size} KB", + "mb": "{size} MB", + "gb": "{size} GB", + "sizePerSecond": "{size}/s", + "pixelShort": "px" + }, + "files": { + "autoRename": "Automatisk-omdøbning", + "countMany": "{count} filer", + "countOne": "1 fil", + "deleteConfirmation": "Er du sikker på du vil slette {count} filer?", + "fileDeleteConfirmation": "Er du sikker på, at du vil slette filen \"{name}\"?", + "fileRenameExtensionConfirmation": "Er du sikker på, at du vil ændre filtypen? Filen kan muligvis ikke bruges bagefter.", + "fileRenameLabel": "Angiv navnet på den nye fil: ", + "filesPaneTitle": "Files pane", + "filesRefresh": "Refreshing files", + "filterPlaceholder": "Filter", + "gettingFileData": "Henter informationer om filen. , vent venligst.", + "overwrite": "Overskriv", + "loadingFilesPane": { + "title": "Loading...", + "text": "Filerne bliver hentet." + }, + "emptyFilesPane": { + "title": "Mappen er tom.", + "text": "Brug Upload knappen eller drag og drop filerne her." + }, + "filterFilesEmpty": { + "title": "Fandt ingenting.", + "text": "Venligst prøv at brug forskellige søgekriterier." + } + }, + "folders": { + "deleteConfirmation": "Er du sikker på, at du vil slette mappen \"{name}\"?", + "destinationFolder": "Destinations mappe", + "newNameLabel": "Angiv navnet på den nye mappe: ", + "newSubfolder": "Ny undermappe", + "renameDialogTitle": "Omdøb mappe", + "treeTitle": "Folders tree" + }, + "copy": { + "dropMenuItem": "Kopier hertil", + "errorDialogTitle": "Følgende filer kunne ikke kopieres:", + "manyFilesDialogTitle": "Kopier {count} filerne til...", + "manyFilesWait": "Kopierer {count} files.", + "oneFileDialogTitle": "Kopier filen til...", + "oneFileWait": "Kopierer fil.", + "operationLabel": "Kopiere filer", + "operationSummary": "Antal kopierede filer: {count}." + }, + "move": { + "dropMenuItem": "Flyt hertil", + "errorDialogTitle": "Følgende filer kunne ikke flyttes:", + "manyFilesDialogTitle": "Flyt {count} filerne til...", + "manyFilesWait": "Flytter {count} filer.", + "oneFileDialogTitle": "Flyt filen til...", + "oneFileWait": "Flytter fil.", + "operationLabel": "Flytter filer", + "operationSummary": "Antal flyttede filer: {count}." + }, + "upload": { + "addFiles": "Tilføj filer", + "bytesCountProgress": "({bytesUploaded} af {bytesTotal})", + "details": "Detaljer", + "filesCountProgress": "{filesUploaded} af {filesTotal}", + "progressLabel": "Uploader, vent venligst...", + "progressMessage": "Uploader...", + "selectFileLabel": "Vælg den fil, du vil uploade", + "selectFiles": "Vælg filer til upload", + "success": "Upload gennemført!", + "summary": "Uploadede filer: {count}" + }, + "settings": { + "display": "Thumbnails:", + "displayDate": "Dato", + "displayName": "Filnavn", + "displaySize": "Størrelse", + "sortAscending": "Ascending", + "sortBy": "Sort by", + "sortByOrder": "Order", + "sortDescending": "Descending", + "thumbnailSize": "Thumbnail størrelse", + "title": "Indstillingér", + "viewType": "View", + "viewTypeCompact": "Compact", + "viewTypeList": "List", + "viewTypeThumbnails": "Thumbnails" + }, + "errors": { + "codes": { + "10": "Ugyldig handling.", + "11": "Ressourcetypen blev ikke angivet i anmodningen.", + "12": "Ressourcetypen er ikke gyldig.", + "13": "Konfigurationsfilen er ikke gyldig.", + "14": "Ugyldig connector plugin: {pluginName}.", + "102": "Ugyldig fil eller mappenavn.", + "103": "Det var ikke muligt at fuldføre handlingen på grund af en begrænsning i rettigheder.", + "104": "Det var ikke muligt at fuldføre handlingen på grund af en begrænsning i filsystem rettigheder.", + "105": "Ugyldig filtype.", + "109": "Ugyldig anmodning.", + "110": "Ukendt fejl.", + "111": "Det var ikke muligt at fuldføre handlingent possible på grund af filstørrelsen.", + "115": "En fil eller mappe med det samme navn eksisterer allerede.", + "116": "Mappen blev ikke fundet. Opdatér listen eller prøv igen.", + "117": "Filen blev ikke fundet. Opdatér listen eller prøv igen.", + "118": "Originalplacering og destination er ens.", + "201": "En fil med det samme filnavn eksisterer allerede. Den uploadede fil er blevet omdøbt til \"{name}\".", + "202": "Ugyldig fil.", + "203": "Ugyldig fil. Filstørrelsen er for stor.", + "204": "Den uploadede fil er korrupt.", + "205": "Der er ikke en midlertidig mappe til upload til rådighed på serveren.", + "206": "Upload annulleret af sikkerhedsmæssige årsager. Filen indeholder HTML-lignende data.", + "207": "Den uploadede fil er blevet omdøbt til \"{name}\".", + "300": "Flytning af fil(er) fejlede.", + "301": "Kopiering af fil(er) fejlede.", + "302": "Sletning af file(s) fejlede.", + "500": "Filbrowseren er deaktiveret af sikkerhedsmæssige årsager. Kontakt systemadministratoren eller kontrollér CKFinders konfigurationsfil.", + "501": "Understøttelse af thumbnails er deaktiveret." + }, + "deleteFilePermissions": "Removing files is not allowed in this folder.", + "fileInvalidCharacters": "Filnavnet må ikke indeholde et af følgende tegn: {disallowedCharacters}", + "fileNameNotEmpty": "The file name cannot be empty.", + "folderInvalidCharacters": "Mappenavnet må ikke indeholde et af følgende tegn: {disallowedCharacters}", + "incorrectExtension": "Den valgte filtype kan ikke benyttes i denne mappe.", + "missingFile": "Filen eksistere ikke længere.", + "missingFolder": "Mappen eksistere ikke længere.", + "noUploadFolderSelected": "Venligst vælg en mappe før upload startes.", + "operationCompleted": "Opgaven blev fuldført med fejl.", + "renameFilePermissions": "Renaming files is not allowed in this folder.", + "unknown": "Det var ikke muligt at fuldføre handlingen. (Fejl: {number})", + "unknownUploadError": "Fejl ved upload.", + "uploadErrors": "Upload gennemført med fejl.", + "uploadPermissions": "Upload er ikke tilladt." + }, + "chooseResizedImage": { + "title": "Vælg skaleret", + "originalSize": "Original størrelse", + "sizes": { + "custom": "Brugerdefineret", + "large": "Stor", + "max": "Maksimal", + "medium": "Medium", + "small": "Lille" + } + }, + "editImage": { + "adjust": "Justér", + "apply": "Tilføj", + "confirmExit": "Er du sikker på du vil lukke? Der er ikke gemte ændringer til billedet.", + "crop": "Beskær", + "downloadAction": "Henter original billede.", + "keepAspectRatio": "Behold størrelseforhold", + "loading": "Henter billeder", + "presets": "Pre indstillinger", + "reset": "Nulstil", + "resize": "Reskalér", + "rotate": "Rotér", + "rotateAntiClockwise": "90° Venstre", + "rotateClockwise": "90° Højre", + "save": "Gem", + "saveDialogFileExists": "Der eksisterer allerede en fil med samme navn i mappen.", + "saveDialogOverwrite": "Overskriv fil", + "saveDialogSaveAs": "Gem som:", + "saveDialogTitle": "Gem ændringer", + "title": "Rediger billede", + "transformationAction": "Tilføj ændringer.", + "uploadAction": "Uploader det redigerede billede.", + "filters": { + "brightness": "Lysstyrke", + "clip": "Clip", + "contrast": "Kontrast", + "exposure": "Eksponering", + "gamma": "Gamma", + "hue": "Hue", + "noise": "Støj", + "saturation": "Farvemætning", + "sepia": "Sepia", + "sharpen": "Skarpere", + "stackBlur": "Blur", + "vibrance": "Vibrering" + }, + "preset": { + "clarity": "Clarity", + "concentrate": "Concentrate", + "crossProcess": "Cross Process", + "glowingSun": "Glødende sol", + "grungy": "Grungy", + "hazyDays": "Disede dage", + "hemingway": "Hemingway", + "herMajesty": "Hendes majestæt", + "jarques": "Jarques", + "lomo": "Lomo", + "love": "Kærlighed", + "nostalgia": "Nostalgi", + "oldBoot": "Gammel støvle", + "orangePeel": "Orange skal", + "pinhole": "Pinhole", + "sinCity": "Sin City", + "sunrise": "Solopgang", + "vintage": "Gammeldags" + } + }, + "shortcuts": { + "title": "Keyboard genvejstaster", + "general": { + "action": "Execute default action", + "firstItem": "Gå til første element", + "focusFilesPane": "Focus files pane", + "focusFoldersPane": "Focus folders pane or breadcrumbs", + "focusNext": "Focus next pane", + "focusToolbar": "Focus toolbar", + "lastItem": "Gå til sidste element", + "listShortcuts": "Open this help dialog", + "nextItem": "Gå til næste element", + "previousItem": "Gå til forrige element", + "showContextMenu": "Open context menu", + "title": "General Interface" + }, + "files": { + "addToSelectionAbove": "Tilføj eller fjern fil over makeringen", + "addToSelectionBelow": "Tilføj eller fjern fil under markeringen", + "addToSelectionLeft": "Tilføj eller fjern fil til venstre for markeringen", + "addToSelectionRight": "Tilføj eller fjern fil til højre for markeringen", + "delete": "Slet fil(er)", + "refresh": "Opdater filer", + "rename": "Omdøb fil", + "selectAll": "Vælg alle filer", + "upload": "Upload fil(er)" + }, + "folders": { + "collapseOrParent": "Sammenklap mappe / Gå til forrige mappe", + "delete": "Slet mappe", + "expandOrSubfolder": "Udvid mappe / Gå til første undermappe", + "title": "Folders Pane" + }, + "keys": { + "ctrl": "Control", + "delete": "Delete", + "downArrow": "Pil ned", + "escape": "Escape", + "leftArrow": "Venstre pil", + "question": "Spørgsmålstegn", + "rightArrow": "Højre pil", + "upArrow": "Pil op" + }, + "keysAbbreviations": { + "alt": "alt", + "ctrl": "ctrl", + "del": "del", + "end": "end", + "home": "home", + "shift": "shift" + } + } +} diff --git a/lib/ckfinder/lang/de-ch.json b/lib/ckfinder/lang/de-ch.json new file mode 100644 index 0000000..ad19700 --- /dev/null +++ b/lib/ckfinder/lang/de-ch.json @@ -0,0 +1,288 @@ +{ + "appTitle": "CKFinder", + "dir": "ltr", + "langCode": "de-ch", + "common": { + "abort": "Abbrechen", + "cancel": "Abbrechen", + "choose": "Auswählen", + "close": "Schliessen", + "copy": "Kopieren", + "delete": "Löschen", + "download": "Herunterladen", + "edit": "Bearbeitung", + "maximize": "Maximieren", + "messageTitle": "Information", + "minimize": "Minimieren", + "move": "Verschieben", + "newNameDialogTitle": "Neuer Name", + "ok": "OK", + "pleaseWait": "Bitte warten.", + "rememberDecision": "Entscheidung merken", + "rename": "Umbenennen", + "showMore": "Zeig mehr", + "skip": "Überspringen", + "upload": "Hochladen", + "view": "Ansehen" + }, + "units": { + "dateFormat": "d.m.yyyy H:MM", + "dateAmPm": [ + "AM", + "PM" + ], + "kb": "{size} KB", + "mb": "{size} MB", + "gb": "{size} GB", + "sizePerSecond": "{size}/s", + "pixelShort": "px" + }, + "files": { + "autoRename": "Automatisch umbenennen", + "countMany": "{count} Datei", + "countOne": "1 Datei", + "deleteConfirmation": "Wollen Sie wirklich {count} Dateien löschen?", + "fileDeleteConfirmation": "Wollen Sie wirklich die Datei \"{name}\" löschen?", + "fileRenameExtensionConfirmation": "Wollen Sie wirklich die Dateierweiterung ändern? Die Datei könnte unbrauchbar werden!", + "fileRenameLabel": "Bitte geben Sie den neuen Dateinamen an: ", + "filesPaneTitle": "Dateibereich", + "filesRefresh": "Aktualisiere Dateien", + "filterPlaceholder": "Filter", + "gettingFileData": "Rufe Informationen zu Datei auf.", + "overwrite": "Überschreiben", + "loadingFilesPane": { + "title": "Laden...", + "text": "Die Dateien werden geladen." + }, + "emptyFilesPane": { + "title": "Das Verzeichnis ist leer.", + "text": "Benutzen Sie den Hochladen Button oder ziehen und legen Sie Ihre Dateien hier ab." + }, + "filterFilesEmpty": { + "title": "Nichts gefunden.", + "text": "Bitte versuchen Sie es mit anderen Suchkriterien." + } + }, + "folders": { + "deleteConfirmation": "Wollen Sie wirklich den Ordner \"{name}\" löschen?", + "destinationFolder": "Zielverzeichnis", + "newNameLabel": "Bitte geben Sie den neuen Verzeichnisnamen an: ", + "newSubfolder": "Neues Unterverzeichnis", + "renameDialogTitle": "Ordner umbenennen", + "treeTitle": "Verzeichnisbaum" + }, + "copy": { + "dropMenuItem": "Hierher kopieren", + "errorDialogTitle": "Dateien, die nicht kopiert werden können:", + "manyFilesDialogTitle": "Kopieren {count} Dateien in...", + "manyFilesWait": "Kopieren {count} Dateien.", + "oneFileDialogTitle": "Kopieren die Datei in...", + "oneFileWait": "Kopieren einer Datei.", + "operationLabel": "Kopieren von Dateien", + "operationSummary": "Anzahl der kopierten Dateien: {count}." + }, + "move": { + "dropMenuItem": "Hierher verschieben", + "errorDialogTitle": "Dateien, die nicht verschoben werden können:", + "manyFilesDialogTitle": "Verschiebe {count} Dateien in...", + "manyFilesWait": "Verschiebe {count} Dateien.", + "oneFileDialogTitle": "Verschiebe die Datei in...", + "oneFileWait": "Verschieben einer Datei.", + "operationLabel": "Verschieben von Dateien", + "operationSummary": "Anzahl der Dateien verschoben: {count}." + }, + "upload": { + "addFiles": "Datei hinzufügen", + "bytesCountProgress": "({bytesUploaded} von {bytesTotal})", + "details": "Details", + "filesCountProgress": "{filesUploaded} von {filesTotal}", + "progressLabel": "Die Daten werden übertragen.", + "progressMessage": "Hochladen...", + "selectFileLabel": "Bitte wählen Sie die Datei aus", + "selectFiles": "Wählen Sie Dateien zum Hochladen", + "success": "Hochladen ist beendet!", + "summary": "Hochgeladene Dateien: {count}" + }, + "settings": { + "display": "Anzeige:", + "displayDate": "Datum", + "displayName": "Dateiname", + "displaySize": "Dateigrösse", + "sortAscending": "Aufsteigend", + "sortBy": "Sortiere nach", + "sortByOrder": "Reihenfolge", + "sortDescending": "Absteigend", + "thumbnailSize": "Miniaturgrösse", + "title": "Einstellungen", + "viewType": "Listenansicht", + "viewTypeCompact": "Compact", + "viewTypeList": "Liste", + "viewTypeThumbnails": "Miniaturansicht" + }, + "errors": { + "codes": { + "10": "Unbekannter Befehl.", + "11": "Der Ressourcentyp wurde nicht spezifiziert.", + "12": "Der Ressourcentyp ist nicht gültig.", + "13": "Der Connector-Konfigurationsdatei ist ungültig.", + "14": "Ungültige Connector-Plugin: {pluginName}.", + "102": "Ungültiger Datei oder Verzeichnisname.", + "103": "Ihre Anfrage konnte wegen Authorisierungseinschränkungen nicht durchgeführt werden.", + "104": "Ihre Anfrage konnte wegen Dateisystemeinschränkungen nicht durchgeführt werden.", + "105": "Ungültige Dateierweiterung.", + "109": "Unbekannte Anfrage.", + "110": "Unbekannter Fehler.", + "111": "Es war nicht möglich die Anforderung aufgrund resultierende Dateigrösse vervollständigen.", + "115": "Es existiert bereits eine Datei oder ein Ordner mit dem gleichen Namen.", + "116": "Verzeichnis nicht gefunden. Bitte aktualisieren Sie die Anzeige und versuchen es noch einmal.", + "117": "Datei nicht gefunden. Bitte aktualisieren Sie die Dateiliste und versuchen es noch einmal.", + "118": "Quell- und Zielpfad sind gleich.", + "201": "Es existiert bereits eine Datei unter gleichem Namen. Die hochgeladene Datei wurde unter \"{name}\" gespeichert.", + "202": "Ungültige Datei.", + "203": "ungültige Datei. Die Dateigrösse ist zu gross.", + "204": "Die hochgeladene Datei ist korrupt.", + "205": "Es existiert kein temp. Ordner für das Hochladen auf den Server.", + "206": "Das Hochladen wurde aus Sicherheitsgründen abgebrochen. Die Datei enthält HTML-Daten.", + "207": "Die hochgeladene Datei wurde unter \"{name}\" gespeichert.", + "300": "Verschieben der Dateien fehlgeschlagen.", + "301": "Kopieren der Dateien fehlgeschlagen.", + "302": "Löschen der Dateien fehlgeschlagen.", + "500": "Der Dateibrowser wurde aus Sicherheitsgründen deaktiviert. Bitte benachrichtigen Sie Ihren Systemadministrator und prüfen Sie die Konfigurationsdatei.", + "501": "Die Miniaturansicht wurde deaktivert." + }, + "deleteFilePermissions": "Removing files is not allowed in this folder.", + "fileInvalidCharacters": "Der Dateiname darf nicht eines der folgenden Zeichen enthalten: {disallowedCharacters}", + "fileNameNotEmpty": "Der Dateiname darf nicht leer sein.", + "folderInvalidCharacters": "Der Verzeichnisname darf nicht eines der folgenden Zeichen enthalten: {disallowedCharacters}", + "incorrectExtension": "Dateinamekürzel nicht in diesem Verzeichnis erlaubt.", + "missingFile": "Die angeforderte Datei ist nicht mehr verfügbar.", + "missingFolder": "Der Ordner, den Sie versuchen zu erreichen, ist nicht mehr verfügbar.", + "noUploadFolderSelected": "Bitte ein Verzeichnis vor dem Hochladen wählen.", + "operationCompleted": "Der Betrieb wurde mit Fehlern abgeschlossen.", + "renameFilePermissions": "Renaming files is not allowed in this folder.", + "unknown": "Ihre Anfrage konnte nicht bearbeitet werden. (Fehler {number})", + "unknownUploadError": "Fehler bei Dateitragung.", + "uploadErrors": "Hochladen mit Fehlern abgeschlossen.", + "uploadPermissions": "Datei hochladen nicht erlaubt." + }, + "chooseResizedImage": { + "title": "Wähle Skaliertes", + "originalSize": "Originalgrösse", + "sizes": { + "custom": "Benutzerdefiniert", + "large": "Gross", + "max": "Max", + "medium": "Mittel", + "small": "Klein" + } + }, + "editImage": { + "adjust": "Anpassen", + "apply": "Anwenden", + "confirmExit": "Sind Sie sicher, dass Sie schliessen möchten? Die Änderungen sind noch nicht gespeichert.", + "crop": "Zuschneiden", + "downloadAction": "Originalbild herunterladen.", + "keepAspectRatio": "Seitenverhältnis beibehalten", + "loading": "Bild wird geladen", + "presets": "Voreinstellungen", + "reset": "Rücksetzen", + "resize": "Grösse ändern", + "rotate": "Drehen", + "rotateAntiClockwise": "90° nach links", + "rotateClockwise": "90° nach rechts", + "save": "Speichern", + "saveDialogFileExists": "Eine Datei mit demselben Namen im Verzeichnis vorhanden ist.", + "saveDialogOverwrite": "Datei überschreiben", + "saveDialogSaveAs": "Speichern als:", + "saveDialogTitle": "Änderungen speichern", + "title": "Bild bearbeiten", + "transformationAction": "Wende Transformationen an.", + "uploadAction": "Hochladen bearbeitete Bild.", + "filters": { + "brightness": "Helligkeit", + "clip": "Zuschneiden", + "contrast": "Kontrast", + "exposure": "Belichtung", + "gamma": "Gamma", + "hue": "Farbton", + "noise": "Rauschen", + "saturation": "Sättigung", + "sepia": "Sepia", + "sharpen": "Schärfen", + "stackBlur": "Weichzeichnen", + "vibrance": "Vibrance" + }, + "preset": { + "clarity": "Klarheit", + "concentrate": "Konzentration", + "crossProcess": "Crossentwicklung", + "glowingSun": "Glühenden Sonne", + "grungy": "Grungy", + "hazyDays": "Dunstigen Tagen", + "hemingway": "Hemingway", + "herMajesty": "Ihre Majestät", + "jarques": "Jarques", + "lomo": "Lomo", + "love": "Liebe", + "nostalgia": "Nostalgie", + "oldBoot": "Alten Stiefel", + "orangePeel": "Orangenschale", + "pinhole": "Lochkamera", + "sinCity": "Sin City", + "sunrise": "Sonnenaufgang", + "vintage": "Vintage" + } + }, + "shortcuts": { + "title": "Tastenkombinationen", + "general": { + "action": "Standardaktion führen", + "firstItem": "Zum ersten Element", + "focusFilesPane": "Fokus auf den Dateibereich", + "focusFoldersPane": "Fokus auf den Ordnerbereich oder Ordnerpfad", + "focusNext": "Fokus auf das nächste Panel", + "focusToolbar": "Fokus auf die Werkzeugleiste", + "lastItem": "Zum letzten Element", + "listShortcuts": "Diese Hilfe-Dialog öffnen", + "nextItem": "Zum nächsten Element", + "previousItem": "Zum vorherigen Element", + "showContextMenu": "Kontextmenü öffnen", + "title": "Benutzerschnittstelle" + }, + "files": { + "addToSelectionAbove": "Dateien von oben zur Auswahl hinzufügen oder aus der Auswahl entfernen.", + "addToSelectionBelow": "Dateien von unten zur Auswahl hinzufügen oder aus der Auswahl entfernen.", + "addToSelectionLeft": "Dateien auf der linken Seite zur Auswahl hinzufügen oder aus der Auswahl entfernen.", + "addToSelectionRight": "Dateien auf der rechten Seite zur Auswahl hinzufügen oder aus der Auswahl entfernen.", + "delete": "Datei(en) löschen", + "refresh": "Dateien aktualisieren", + "rename": "Datei umbenennen", + "selectAll": "Alle Dateien auswählen", + "upload": "Datei(en) hochladen" + }, + "folders": { + "collapseOrParent": "Ordner reduzieren / Zum übergeordneten Ordner", + "delete": "Ordner löschen", + "expandOrSubfolder": "Ordner erweitern / Zum ersten Unterverzeichnis", + "title": "Ordnerbereich" + }, + "keys": { + "ctrl": "Control", + "delete": "Entfernen", + "downArrow": "Untere Pfeiltaste", + "escape": "Escape", + "leftArrow": "Linke Pfeiltaste", + "question": "Fragezeichen", + "rightArrow": "Rechte Pfeiltaste", + "upArrow": "Obere Pfeiltaste" + }, + "keysAbbreviations": { + "alt": "Alt", + "ctrl": "Ctrl", + "del": "Entf", + "end": "Ende", + "home": "Pos1", + "shift": "Shift" + } + } +} diff --git a/lib/ckfinder/lang/de.json b/lib/ckfinder/lang/de.json new file mode 100644 index 0000000..0d92bc6 --- /dev/null +++ b/lib/ckfinder/lang/de.json @@ -0,0 +1,288 @@ +{ + "appTitle": "CKFinder", + "dir": "ltr", + "langCode": "de", + "common": { + "abort": "Abbrechen", + "cancel": "Abbrechen", + "choose": "Auswählen", + "close": "Schließen", + "copy": "Kopieren", + "delete": "Löschen", + "download": "Herunterladen", + "edit": "Bearbeitung", + "maximize": "Maximieren", + "messageTitle": "Information", + "minimize": "Minimieren", + "move": "Verschieben", + "newNameDialogTitle": "Neuer Name", + "ok": "OK", + "pleaseWait": "Bitte warten.", + "rememberDecision": "Entscheidung merken", + "rename": "Umbenennen", + "showMore": "Zeig mehr", + "skip": "Überspringen", + "upload": "Hochladen", + "view": "Ansehen" + }, + "units": { + "dateFormat": "d.m.yyyy H:MM", + "dateAmPm": [ + "AM", + "PM" + ], + "kb": "{size} KB", + "mb": "{size} MB", + "gb": "{size} GB", + "sizePerSecond": "{size}/s", + "pixelShort": "px" + }, + "files": { + "autoRename": "Automatisch umbenennen", + "countMany": "{count} Datei", + "countOne": "1 Datei", + "deleteConfirmation": "Wollen Sie wirklich {count} Dateien löschen?", + "fileDeleteConfirmation": "Wollen Sie wirklich die Datei \"{name}\" löschen?", + "fileRenameExtensionConfirmation": "Wollen Sie wirklich die Dateierweiterung ändern? Die Datei könnte unbrauchbar werden!", + "fileRenameLabel": "Bitte geben Sie den neuen Dateinamen an: ", + "filesPaneTitle": "Dateibereich", + "filesRefresh": "Aktualisiere Dateien", + "filterPlaceholder": "Filter", + "gettingFileData": "Rufe Informationen zu Datei auf.", + "overwrite": "Überschreiben", + "loadingFilesPane": { + "title": "Laden...", + "text": "Die Dateien werden geladen." + }, + "emptyFilesPane": { + "title": "Das Verzeichnis ist leer.", + "text": "Benutzen Sie den Hochladen Button oder ziehen und legen Sie Ihre Dateien hier ab." + }, + "filterFilesEmpty": { + "title": "Nichts gefunden.", + "text": "Bitte versuchen Sie es mit anderen Suchkriterien." + } + }, + "folders": { + "deleteConfirmation": "Wollen Sie wirklich den Ordner \"{name}\" löschen?", + "destinationFolder": "Zielverzeichnis", + "newNameLabel": "Bitte geben Sie den neuen Verzeichnisnamen an: ", + "newSubfolder": "Neues Unterverzeichnis", + "renameDialogTitle": "Ordner umbenennen", + "treeTitle": "Verzeichnisbaum" + }, + "copy": { + "dropMenuItem": "Hierher kopieren", + "errorDialogTitle": "Dateien, die nicht kopiert werden können:", + "manyFilesDialogTitle": "Kopieren {count} Dateien in...", + "manyFilesWait": "Kopieren {count} Dateien.", + "oneFileDialogTitle": "Kopieren die Datei in...", + "oneFileWait": "Kopieren einer Datei.", + "operationLabel": "Kopieren von Dateien", + "operationSummary": "Anzahl der kopierten Dateien: {count}." + }, + "move": { + "dropMenuItem": "Hierher verschieben", + "errorDialogTitle": "Dateien, die nicht verschoben werden können:", + "manyFilesDialogTitle": "Verschiebe {count} Dateien in...", + "manyFilesWait": "Verschiebe {count} Dateien.", + "oneFileDialogTitle": "Verschiebe die Datei in...", + "oneFileWait": "Verschieben einer Datei.", + "operationLabel": "Verschieben von Dateien", + "operationSummary": "Anzahl der Dateien verschoben: {count}." + }, + "upload": { + "addFiles": "Datei hinzufügen", + "bytesCountProgress": "({bytesUploaded} von {bytesTotal})", + "details": "Details", + "filesCountProgress": "{filesUploaded} von {filesTotal}", + "progressLabel": "Die Daten werden übertragen.", + "progressMessage": "Hochladen...", + "selectFileLabel": "Bitte wählen Sie die Datei aus", + "selectFiles": "Wählen Sie Dateien zum Hochladen", + "success": "Hochladen ist beendet!", + "summary": "Hochgeladene Dateien: {count}" + }, + "settings": { + "display": "Anzeige:", + "displayDate": "Datum", + "displayName": "Dateiname", + "displaySize": "Dateigröße", + "sortAscending": "Aufsteigend", + "sortBy": "Sortiere nach", + "sortByOrder": "Reihenfolge", + "sortDescending": "Absteigend", + "thumbnailSize": "Miniaturgröße", + "title": "Einstellungen", + "viewType": "Listenansicht", + "viewTypeCompact": "Compact", + "viewTypeList": "Liste", + "viewTypeThumbnails": "Miniaturansicht" + }, + "errors": { + "codes": { + "10": "Unbekannter Befehl.", + "11": "Der Ressourcentyp wurde nicht spezifiziert.", + "12": "Der Ressourcentyp ist nicht gültig.", + "13": "Der Connector-Konfigurationsdatei ist ungültig.", + "14": "Ungültige Connector-Plugin: {pluginName}.", + "102": "Ungültiger Datei oder Verzeichnisname.", + "103": "Ihre Anfrage konnte wegen Authorisierungseinschränkungen nicht durchgeführt werden.", + "104": "Ihre Anfrage konnte wegen Dateisystemeinschränkungen nicht durchgeführt werden.", + "105": "Ungültige Dateierweiterung.", + "109": "Unbekannte Anfrage.", + "110": "Unbekannter Fehler.", + "111": "Es war nicht möglich die Anforderung aufgrund resultierende Dateigröße vervollständigen.", + "115": "Es existiert bereits eine Datei oder ein Ordner mit dem gleichen Namen.", + "116": "Verzeichnis nicht gefunden. Bitte aktualisieren Sie die Anzeige und versuchen es noch einmal.", + "117": "Datei nicht gefunden. Bitte aktualisieren Sie die Dateiliste und versuchen es noch einmal.", + "118": "Quell- und Zielpfad sind gleich.", + "201": "Es existiert bereits eine Datei unter gleichem Namen. Die hochgeladene Datei wurde unter \"{name}\" gespeichert.", + "202": "Ungültige Datei.", + "203": "ungültige Datei. Die Dateigröße ist zu groß.", + "204": "Die hochgeladene Datei ist korrupt.", + "205": "Es existiert kein temp. Ordner für das Hochladen auf den Server.", + "206": "Das Hochladen wurde aus Sicherheitsgründen abgebrochen. Die Datei enthält HTML-Daten.", + "207": "Die hochgeladene Datei wurde unter \"{name}\" gespeichert.", + "300": "Verschieben der Dateien fehlgeschlagen.", + "301": "Kopieren der Dateien fehlgeschlagen.", + "302": "Löschen der Dateien fehlgeschlagen.", + "500": "Der Dateibrowser wurde aus Sicherheitsgründen deaktiviert. Bitte benachrichtigen Sie Ihren Systemadministrator und prüfen Sie die Konfigurationsdatei.", + "501": "Die Miniaturansicht wurde deaktivert." + }, + "deleteFilePermissions": "Removing files is not allowed in this folder.", + "fileInvalidCharacters": "Der Dateiname darf nicht eines der folgenden Zeichen enthalten: {disallowedCharacters}", + "fileNameNotEmpty": "Der Dateiname darf nicht leer sein.", + "folderInvalidCharacters": "Der Verzeichnisname darf nicht eines der folgenden Zeichen enthalten: {disallowedCharacters}", + "incorrectExtension": "Dateinamekürzel nicht in diesem Verzeichnis erlaubt.", + "missingFile": "Die angeforderte Datei ist nicht mehr verfügbar.", + "missingFolder": "Der Ordner, den Sie versuchen zu erreichen, ist nicht mehr verfügbar.", + "noUploadFolderSelected": "Bitte ein Verzeichnis vor dem Hochladen wählen.", + "operationCompleted": "Der Betrieb wurde mit Fehlern abgeschlossen.", + "renameFilePermissions": "Renaming files is not allowed in this folder.", + "unknown": "Ihre Anfrage konnte nicht bearbeitet werden. (Fehler {number})", + "unknownUploadError": "Fehler bei Dateitragung.", + "uploadErrors": "Hochladen mit Fehlern abgeschlossen.", + "uploadPermissions": "Datei hochladen nicht erlaubt." + }, + "chooseResizedImage": { + "title": "Wähle Skaliertes", + "originalSize": "Originalgröße", + "sizes": { + "custom": "Benutzerdefiniert", + "large": "Groß", + "max": "Max", + "medium": "Mittel", + "small": "Klein" + } + }, + "editImage": { + "adjust": "Anpassen", + "apply": "Anwenden", + "confirmExit": "Sind Sie sicher, daß Sie schließen möchten? Die Änderungen sind noch nicht gespeichert.", + "crop": "Zuschneiden", + "downloadAction": "Originalbild herunterladen.", + "keepAspectRatio": "Seitenverhältnis beibehalten", + "loading": "Bild wird geladen", + "presets": "Voreinstellungen", + "reset": "Rücksetzen", + "resize": "Größe ändern", + "rotate": "Drehen", + "rotateAntiClockwise": "90° nach links", + "rotateClockwise": "90° nach rechts", + "save": "Speichern", + "saveDialogFileExists": "Eine Datei mit demselben Namen im Verzeichnis vorhanden ist.", + "saveDialogOverwrite": "Datei überschreiben", + "saveDialogSaveAs": "Speichern als:", + "saveDialogTitle": "Änderungen speichern", + "title": "Bild bearbeiten", + "transformationAction": "Wende Transformationen an.", + "uploadAction": "Hochladen bearbeitete Bild.", + "filters": { + "brightness": "Helligkeit", + "clip": "Zuschneiden", + "contrast": "Kontrast", + "exposure": "Belichtung", + "gamma": "Gamma", + "hue": "Farbton", + "noise": "Rauschen", + "saturation": "Sättigung", + "sepia": "Sepia", + "sharpen": "Schärfen", + "stackBlur": "Weichzeichnen", + "vibrance": "Vibrance" + }, + "preset": { + "clarity": "Klarheit", + "concentrate": "Konzentration", + "crossProcess": "Crossentwicklung", + "glowingSun": "Glühenden Sonne", + "grungy": "Grungy", + "hazyDays": "Dunstigen Tagen", + "hemingway": "Hemingway", + "herMajesty": "Ihre Majestät", + "jarques": "Jarques", + "lomo": "Lomo", + "love": "Liebe", + "nostalgia": "Nostalgie", + "oldBoot": "Alten Stiefel", + "orangePeel": "Orangenschale", + "pinhole": "Lochkamera", + "sinCity": "Sin City", + "sunrise": "Sonnenaufgang", + "vintage": "Vintage" + } + }, + "shortcuts": { + "title": "Tastenkombinationen", + "general": { + "action": "Standardaktion führen", + "firstItem": "Zum ersten Element", + "focusFilesPane": "Fokus auf den Dateibereich", + "focusFoldersPane": "Fokus auf den Ordnerbereich oder Ordnerpfad", + "focusNext": "Fokus auf das nächste Panel", + "focusToolbar": "Fokus auf die Werkzeugleiste", + "lastItem": "Zum letzten Element", + "listShortcuts": "Diese Hilfe-Dialog öffnen", + "nextItem": "Zum nächsten Element", + "previousItem": "Zum vorherigen Element", + "showContextMenu": "Kontextmenü öffnen", + "title": "Benutzerschnittstelle" + }, + "files": { + "addToSelectionAbove": "Dateien von oben zur Auswahl hinzufügen oder aus der Auswahl entfernen.", + "addToSelectionBelow": "Dateien von unten zur Auswahl hinzufügen oder aus der Auswahl entfernen.", + "addToSelectionLeft": "Dateien auf der linken Seite zur Auswahl hinzufügen oder aus der Auswahl entfernen.", + "addToSelectionRight": "Dateien auf der rechten Seite zur Auswahl hinzufügen oder aus der Auswahl entfernen.", + "delete": "Datei(en) löschen", + "refresh": "Dateien aktualisieren", + "rename": "Datei umbenennen", + "selectAll": "Alle Dateien auswählen", + "upload": "Datei(en) hochladen" + }, + "folders": { + "collapseOrParent": "Ordner reduzieren / Zum übergeordneten Ordner", + "delete": "Ordner löschen", + "expandOrSubfolder": "Ordner erweitern / Zum ersten Unterverzeichnis", + "title": "Ordnerbereich" + }, + "keys": { + "ctrl": "Steuerung", + "delete": "Entfernen", + "downArrow": "Untere Pfeiltaste", + "escape": "Escape", + "leftArrow": "Linke Pfeiltaste", + "question": "Fragezeichen", + "rightArrow": "Rechte Pfeiltaste", + "upArrow": "Obere Pfeiltaste" + }, + "keysAbbreviations": { + "alt": "Alt", + "ctrl": "Strg", + "del": "Entf", + "end": "Ende", + "home": "Pos1", + "shift": "Shift" + } + } +} diff --git a/lib/ckfinder/lang/el.json b/lib/ckfinder/lang/el.json new file mode 100644 index 0000000..28f2508 --- /dev/null +++ b/lib/ckfinder/lang/el.json @@ -0,0 +1,288 @@ +{ + "appTitle": "CKFinder", + "dir": "ltr", + "langCode": "el", + "common": { + "abort": "Ματαίωση", + "cancel": "Ακύρωση", + "choose": "Επιλογή", + "close": "Κλείσιμο", + "copy": "Αντιγραφή", + "delete": "Διαγραφή", + "download": "Λήψη αρχείου", + "edit": "Επεξεργασία", + "maximize": "Μεγιστοποίηση", + "messageTitle": "Πληροφορίες", + "minimize": "Ελαχιστοποίηση", + "move": "Μετακίνηση", + "newNameDialogTitle": "Νέα ονομασία", + "ok": "OK", + "pleaseWait": "Παρακαλώ περιμένετε.", + "rememberDecision": "Να θυμάσαι την απόφασή μου", + "rename": "Μετονομασία", + "showMore": "Εμφάνιση περισσοτέρων", + "skip": "Παράβλεψη", + "upload": "Μεταφόρτωση", + "view": "Προβολή" + }, + "units": { + "dateFormat": "dd/mm/yyyy HH:MM", + "dateAmPm": [ + "ΜΜ", + "ΠΜ" + ], + "kb": "{size} KB", + "mb": "{size} MB", + "gb": "{size} GB", + "sizePerSecond": "{size}/s", + "pixelShort": "px" + }, + "files": { + "autoRename": "Αυτόματη μετονομασία", + "countMany": "{count} αρχεία", + "countOne": "1 αρχείο", + "deleteConfirmation": "Είστε σίγουροι ότι θέλετε να διαγράψετε {count} αρχεία?", + "fileDeleteConfirmation": "Είστε σίγουροι ότι θέλετε να διαγράψετε το αρχείο \"{name}\"?", + "fileRenameExtensionConfirmation": "Είστε σίγουροι ότι θέλετε να αλλάξετε την επέκταση του αρχείου; Μετά από αυτή την ενέργεια το αρχείο είναι δυνατόν να μην μπορεί να χρησιμοποιηθεί", + "fileRenameLabel": "Παρακαλούμε πληκτρολογήστε την νέα ονομασία του αρχείου: ", + "filesPaneTitle": "Καρτέλα αρχείων", + "filesRefresh": "Ανανέωση αρχείων σε εξέλιξη", + "filterPlaceholder": "Φίλτρο", + "gettingFileData": "Λήψη δεδομένων αρχείου.", + "overwrite": "Αντικατάσταση αρχείου", + "loadingFilesPane": { + "title": "Φόρτωση...", + "text": "Φόρτωση αρχείων σε εξέλιξη." + }, + "emptyFilesPane": { + "title": "Ο φάκελος είναι άδειος.", + "text": "Χρησιμοποιήστε το κουμπί Μεταφόρτωση ή κάντε μεταφορά & απόθεση των αρχείων σας εδώ." + }, + "filterFilesEmpty": { + "title": "Δεν βρέθηκαν αρχεία με αυτά τα κριτήρια.", + "text": "Παρακαλούμε δοκιμάστε με άλλα κριτήρια αναζήτησης." + } + }, + "folders": { + "deleteConfirmation": "Είστε σίγουροι ότι θέλετε να διαγράψετε το φάκελο \"{name}\";", + "destinationFolder": "Φάκελος Προορισμού", + "newNameLabel": "Παρακαλούμε πληκτρολογήστε την ονομασία του νέου φακέλου: ", + "newSubfolder": "Νέος υποφάκελος", + "renameDialogTitle": "Μετονομασία φακέλου", + "treeTitle": "Δομή φακέλων" + }, + "copy": { + "dropMenuItem": "Αντέγραψε εδώ", + "errorDialogTitle": "Αρχεία που δεν είναι δυνατό να αντιγραφούν:", + "manyFilesDialogTitle": "Αντιγραφή {count} Αρχείων Σε...", + "manyFilesWait": "Αντιγραφή {count} αρχείων.", + "oneFileDialogTitle": "Αντιγραφή Αρχείου Σε...", + "oneFileWait": "Αντιγραφή αρχείου.", + "operationLabel": "Αντιγραφή Αρχείων", + "operationSummary": "Αριθμός αρχείων που αντιγράφηκαν: {count}." + }, + "move": { + "dropMenuItem": "Μετακίνησε εδώ", + "errorDialogTitle": "Αρχεία που δεν είναι δυνατό να μετακινηθούν:", + "manyFilesDialogTitle": "Μετακίνηση {count} Αρχείων Σε...", + "manyFilesWait": "Μετακίνηση {count} αρχείων.", + "oneFileDialogTitle": "Μετακίνηση Αρχείου Σε...", + "oneFileWait": "Μετακίνηση αρχείου.", + "operationLabel": "Μετακίνηση Αρχείων", + "operationSummary": "Αριθμός αρχείων που μετακινήθηκαν: {count}." + }, + "upload": { + "addFiles": "Προσθήκη αρχείων", + "bytesCountProgress": "({bytesUploaded} από {bytesTotal})", + "details": "Λεπτομέρειες", + "filesCountProgress": "{filesUploaded} από {filesTotal}", + "progressLabel": "Η μεταφόρτωση εκτελείται.", + "progressMessage": "Μεταφόρτωση...", + "selectFileLabel": "επιλέξτε το αρχείο που θέλετε να μεταφερθεί κάνοντας κλίκ στο κουμπί", + "selectFiles": "Επιλέξτε αρχεία για μεταφόρτωση", + "success": "Η μεταφόρτωση ολοκληρώθηκε!", + "summary": "Αρχεία που μεταφορτώθηκαν: {count}" + }, + "settings": { + "display": "Εμφάνιση:", + "displayDate": "Ημερομηνία", + "displayName": "Όνομα αρχείου", + "displaySize": "Μέγεθος αρχείου", + "sortAscending": "Αύξουσα", + "sortBy": "Ταξινόμηση κατά", + "sortByOrder": "Σειρά", + "sortDescending": "Φθίνουσα", + "thumbnailSize": "Μέγεθος μικρογραφιών", + "title": "Ρυθμίσεις", + "viewType": "Εμφάνιση", + "viewTypeCompact": "Σύντομη λίστα", + "viewTypeList": "Λίστα", + "viewTypeThumbnails": "Μικρογραφίες" + }, + "errors": { + "codes": { + "10": "Λανθασμένη Εντολή.", + "11": "Ο τύπος πόρου (resource type) δεν ήταν δυνατόν να προσδιοριστεί.", + "12": "Ο τύπος πόρου (resource type) δεν είναι έγκυρος.", + "13": "Το αρχείο ρυθμίσεων της λειτουργίας σύνδεσης είναι άκυρο.", + "14": "Άκυρο πρόσθετο (plugin) σύνδεσης: {pluginName}.", + "102": "Το όνομα αρχείου ή φακέλου δεν είναι έγκυρο.", + "103": "Δεν ήταν δυνατή η εκτέλεση της ενέργειας λόγω έλλειψης δικαιωμάτων ασφαλείας.", + "104": "Δεν ήταν δυνατή η εκτέλεση της ενέργειας λόγω περιορισμών του συστήματος αρχείων.", + "105": "Λανθασμένη επέκταση αρχείου.", + "109": "Λανθασμένη ενέργεια.", + "110": "Άγνωστο λάθος.", + "111": "Δεν ήταν δυνατή η ολοκλήρωση της ενέργειας λόγω του μεγέθους αρχείου που προκύπτει.", + "115": "Το αρχείο ή φάκελος υπάρχει ήδη.", + "116": "Ο φάκελος δεν βρέθηκε. Παρακαλούμε ανανεώστε τη σελίδα και προσπαθήστε ξανά.", + "117": "Το αρχείο δεν βρέθηκε. Παρακαλούμε ανανεώστε τη σελίδα και προσπαθήστε ξανά.", + "118": "Η αρχική και τελική διαδρομή είναι ίδιες.", + "201": "Ένα αρχείο με την ίδια ονομασία υπάρχει ήδη. Το μεταφορτωμένο αρχείο μετονομάστηκε σε \"{name}\".", + "202": "Λανθασμένο αρχείο.", + "203": "Λανθασμένο αρχείο. Το μέγεθος του αρχείου είναι πολύ μεγάλο.", + "204": "Το μεταφορτωμένο αρχείο είναι χαλασμένο.", + "205": "Δεν υπάρχει προσωρινός φάκελος για να χρησιμοποιηθεί για τις μεταφορτώσεις των αρχείων.", + "206": "Η μεταφόρτωση ακυρώθηκε για λόγους ασφαλείας. Το αρχείο περιέχει δεδομένα μορφής HTML.", + "207": "Το μεταφορτωμένο αρχείο μετονομάστηκε σε \"{name}\".", + "300": "Η μετακίνηση των αρχείων απέτυχε.", + "301": "Η αντιγραφή των αρχείων απέτυχε.", + "302": "Η διαγραφή αρχείων απέτυχε.", + "500": "Ο πλοηγός αρχείων έχει απενεργοποιηθεί για λόγους ασφαλείας. Παρακαλούμε επικοινωνήστε με τον διαχειριστή της ιστοσελίδας και ελέγξτε το αρχείο ρυθμίσεων του πλοηγού (CKFinder).", + "501": "Η υποστήριξη των μικρογραφιών έχει απενεργοποιηθεί." + }, + "deleteFilePermissions": "Δεν επιτρέπεται η διαγραφή αρχείων σε αυτόν τον φάκελο.", + "fileInvalidCharacters": "Η ονομασία του αρχείου δεν μπορεί να περιέχει τους ακόλουθους χαρακτήρες: {disallowedCharacters}", + "fileNameNotEmpty": "Η ονομασία του αρχείου δεν μπορεί να είναι κενή.", + "folderInvalidCharacters": "Η ονομασία του φακέλου δεν μπορεί να περιέχει τους ακόλουθους χαρακτήρες: {disallowedCharacters}", + "incorrectExtension": "Η επέκταση σε αρχείο δεν επιτρέπεται σε αυτόν τον φάκελο.", + "missingFile": "Το αρχείο που ζητήθηκε δεν είναι πλέον διαθέσιμο.", + "missingFolder": "Ο φάκελος που προσπαθείτε να ανοίξετε δεν είναι πλέον διαθέσιμος.", + "noUploadFolderSelected": "Παρακαλούμε επιλέξτε ένα φάκελο πριν εκκινήσετε την διαδικασία της μεταφόρτωσης.", + "operationCompleted": "Η διαδικασία ολοκληρώθηκε με σφάλματα.", + "renameFilePermissions": "Δεν επιτρέπεται η μετονομασία αρχείων σε αυτόν τον φάκελο.", + "unknown": "Η ενέργεια δεν ήταν δυνατόν να εκτελεστεί. (Σφάλμα {number})", + "unknownUploadError": "Παρουσιάστηκε σφάλμα κατά την αποστολή του αρχείου.", + "uploadErrors": "Η μεταφόρτωση ολοκληρώθηκε με σφάλματα.", + "uploadPermissions": "Η μεταφόρτωση των αρχείων δεν επιτρέπεται." + }, + "chooseResizedImage": { + "title": "Προσαρμογή Μεγέθους", + "originalSize": "Αρχικό μέγεθος", + "sizes": { + "custom": "Επιλεκτικά", + "large": "Μεγάλο", + "max": "Πολύ μεγάλο", + "medium": "Μεσαίο", + "small": "Μικρό" + } + }, + "editImage": { + "adjust": "Ρύθμιση", + "apply": "Εφαρμογή", + "confirmExit": "Είστε σίγουροι πως θέλετε να επιστρέψετε; Υπάρχουν αλλαγές στην εικόνα που δεν έχουν αποθηκευτεί.", + "crop": "Περικοπή", + "downloadAction": "Λήψη πρωτότυπης εικόνας.", + "keepAspectRatio": "Διατήρηση Λόγου Διαστάσεων", + "loading": "Φόρτωση εικόνας", + "presets": "Προεπιλογές", + "reset": "Επαναφορά", + "resize": "Αλλαγή μεγέθους", + "rotate": "Περιστροφή", + "rotateAntiClockwise": "90° Αριστερά", + "rotateClockwise": "90° Δεξιά", + "save": "Αποθήκευση", + "saveDialogFileExists": "Υπάρχει ήδη αρχείο με το ίδιο όνομα στον φάκελο.", + "saveDialogOverwrite": "Αντικατάσταση Αρχείου", + "saveDialogSaveAs": "Αποθήκευση ως:", + "saveDialogTitle": "Αποθήκευση Αλλαγών", + "title": "Επεξεργασία εικόνας", + "transformationAction": "Γίνεται εφαρμογή των μετασχηματισμών.", + "uploadAction": "Μεταφόρτωση επεξεργασμένης εικόνας.", + "filters": { + "brightness": "Φωτεινότητα", + "clip": "Υπερέκθεση (Clip)", + "contrast": "Αντίθεση", + "exposure": "Έκθεση", + "gamma": "Διόρθωση (Gamma)", + "hue": "Απόχρωση", + "noise": "Θόρυβος", + "saturation": "Κορεσμός", + "sepia": "Sepia", + "sharpen": "Όξυνση", + "stackBlur": "Θόλωση (Stack Blur)", + "vibrance": "Zωηρότητα (Vibrance)" + }, + "preset": { + "clarity": "Διαύγεια", + "concentrate": "Συγκέντρωση", + "crossProcess": "Ένταση", + "glowingSun": "Λαμπρός ήλιος", + "grungy": "Τραχύτητα", + "hazyDays": "Θολές ημέρες", + "hemingway": "Χέμινγουεϊ", + "herMajesty": "Αυτού εξοχότης", + "jarques": "Jarques", + "lomo": "Λομογραφία", + "love": "Αγάπη", + "nostalgia": "Νοσταλγία", + "oldBoot": "Ψυχρότητα", + "orangePeel": "Φλούδα πορτοκαλιού", + "pinhole": "Σκοτεινός θάλαμος", + "sinCity": "Sin City", + "sunrise": "Ανατολή ηλίου", + "vintage": "Εποχής" + } + }, + "shortcuts": { + "title": "Συντομεύσεις πληκτρολογίου", + "general": { + "action": "Εκτέλεση προεπιλεγμένης ενέργειας", + "firstItem": "Μεταφορά στο πρώτο αντικείμενο", + "focusFilesPane": "Εστίαση στην καρτέλα αρχείων", + "focusFoldersPane": "Εστίαση σε καρτέλα φακέλων ή στη διαδρομή (breadcrumbs)", + "focusNext": "Εστίαση επόμενης καρτέλας", + "focusToolbar": "Εστίαση σε γραμμή εργαλείων", + "lastItem": "Μεταφορά στο τελευταίο αντικείμενο", + "listShortcuts": "Άνοιγμα αυτού του παραθύρου βοηθείας", + "nextItem": "Μεταφορά στο επόμενο αντικείμενο", + "previousItem": "Μεταφορά στο προηγούμενο αντικείμενο", + "showContextMenu": "Άνοιγμα μενού επιλογών (context menu)", + "title": "Γενικό περιβάλλον διεπαφής" + }, + "files": { + "addToSelectionAbove": "Προσθήκη ή αφαίρεση αρχείου από επάνω στην επιλογή", + "addToSelectionBelow": "Προσθήκη ή αφαίρεση αρχείου από κάτω στην επιλογή", + "addToSelectionLeft": "Προσθήκη ή αφαίρεση αρχείου από αριστερά στην επιλογή", + "addToSelectionRight": "Προσθήκη ή αφαίρεση αρχείου από δεξιά στην επιλογή", + "delete": "Διαγραφή αρχείου(ων)", + "refresh": "Ανανέωση αρχείων", + "rename": "Μετονομασία αρχείου", + "selectAll": "Επιλογή όλων των αρχείων", + "upload": "Μεταφόρτωση αρχείου(ων)" + }, + "folders": { + "collapseOrParent": "Κλείσιμο φακέλου / Μεταφορά στον γονικό φάκελο", + "delete": "Διαγραφή φακέλου", + "expandOrSubfolder": "Άνοιγμα φακέλου / Μεταφορά στον πρώτο υποφάκελο", + "title": "Καρτέλα Φακέλων" + }, + "keys": { + "ctrl": "Control", + "delete": "Delete", + "downArrow": "Κάτω βέλος", + "escape": "Escape", + "leftArrow": "Αριστερό βέλος", + "question": "Ερωτηματικό", + "rightArrow": "Δεξί βέλος", + "upArrow": "Πάνω βέλος" + }, + "keysAbbreviations": { + "alt": "alt", + "ctrl": "ctrl", + "del": "del", + "end": "end", + "home": "home", + "shift": "shift" + } + } +} diff --git a/lib/ckfinder/lang/en.json b/lib/ckfinder/lang/en.json new file mode 100644 index 0000000..209ece6 --- /dev/null +++ b/lib/ckfinder/lang/en.json @@ -0,0 +1,288 @@ +{ + "appTitle": "CKFinder", + "dir": "ltr", + "langCode": "en", + "common": { + "abort": "Abort", + "cancel": "Cancel", + "choose": "Choose", + "close": "Close", + "copy": "Copy", + "delete": "Delete", + "download": "Download", + "edit": "Edit", + "maximize": "Maximize", + "messageTitle": "Information", + "minimize": "Minimize", + "move": "Move", + "newNameDialogTitle": "New Name", + "ok": "OK", + "pleaseWait": "Please wait.", + "rememberDecision": "Remember my decision", + "rename": "Rename", + "showMore": "Show more", + "skip": "Skip", + "upload": "Upload", + "view": "View" + }, + "units": { + "dateFormat": "m/d/yyyy h:MM aa", + "dateAmPm": [ + "AM", + "PM" + ], + "kb": "{size} KB", + "mb": "{size} MB", + "gb": "{size} GB", + "sizePerSecond": "{size}/s", + "pixelShort": "px" + }, + "files": { + "autoRename": "Auto-rename", + "countMany": "{count} files", + "countOne": "1 file", + "deleteConfirmation": "Are you sure you want to delete {count} files?", + "fileDeleteConfirmation": "Are you sure you want to delete the \"{name}\" file?", + "fileRenameExtensionConfirmation": "Are you sure you want to change the file extension? The file may become unusable.", + "fileRenameLabel": "Type the new file name: ", + "filesPaneTitle": "Files pane", + "filesRefresh": "Refreshing files", + "filterPlaceholder": "Filter", + "gettingFileData": "Getting file data.", + "overwrite": "Overwrite", + "loadingFilesPane": { + "title": "Loading...", + "text": "The files are being loaded." + }, + "emptyFilesPane": { + "title": "The folder is empty.", + "text": "Use the Upload button or drag and drop your files here." + }, + "filterFilesEmpty": { + "title": "Nothing found.", + "text": "Please try using different search criteria." + } + }, + "folders": { + "deleteConfirmation": "Are you sure you want to delete the \"{name}\" folder?", + "destinationFolder": "Destination Folder", + "newNameLabel": "Type the new folder name: ", + "newSubfolder": "New Subfolder", + "renameDialogTitle": "Rename Folder", + "treeTitle": "Folders tree" + }, + "copy": { + "dropMenuItem": "Copy Here", + "errorDialogTitle": "Files that cannot be copied:", + "manyFilesDialogTitle": "Copy {count} Files To...", + "manyFilesWait": "Copying {count} files.", + "oneFileDialogTitle": "Copy File To...", + "oneFileWait": "Copying file.", + "operationLabel": "Copying Files", + "operationSummary": "Number of files copied: {count}." + }, + "move": { + "dropMenuItem": "Move Here", + "errorDialogTitle": "Files that cannot be moved:", + "manyFilesDialogTitle": "Move {count} Files To...", + "manyFilesWait": "Moving {count} files.", + "oneFileDialogTitle": "Move File To...", + "oneFileWait": "Moving file.", + "operationLabel": "Moving Files", + "operationSummary": "Number of files moved: {count}." + }, + "upload": { + "addFiles": "Add Files", + "bytesCountProgress": "({bytesUploaded} of {bytesTotal})", + "details": "Details", + "filesCountProgress": "{filesUploaded} of {filesTotal}", + "progressLabel": "Upload in progress.", + "progressMessage": "Uploading...", + "selectFileLabel": "Select a file to upload", + "selectFiles": "Select files to upload", + "success": "Upload finished!", + "summary": "Uploaded files: {count}" + }, + "settings": { + "display": "Display", + "displayDate": "Date", + "displayName": "File Name", + "displaySize": "File Size", + "sortAscending": "Ascending", + "sortBy": "Sort by", + "sortByOrder": "Order", + "sortDescending": "Descending", + "thumbnailSize": "Thumbnail Size", + "title": "Settings", + "viewType": "View", + "viewTypeCompact": "Compact", + "viewTypeList": "List", + "viewTypeThumbnails": "Thumbnails" + }, + "errors": { + "codes": { + "10": "Invalid command.", + "11": "The resource type was not specified in the request.", + "12": "The requested resource type is invalid.", + "13": "The connector configuration file is invalid.", + "14": "Invalid connector plugin: {pluginName}.", + "102": "Invalid file or folder name.", + "103": "It was not possible to complete the request due to authorization restrictions.", + "104": "It was not possible to complete the request due to file system permission restrictions.", + "105": "Invalid file extension.", + "109": "Invalid request.", + "110": "Unknown error.", + "111": "It was not possible to complete the request due to resulting file size.", + "115": "A file or folder with the same name already exists.", + "116": "Folder not found. Please refresh and try again.", + "117": "File not found. Please refresh the files list and try again.", + "118": "Source and target paths are equal.", + "201": "A file with the same name already exists. The uploaded file was renamed to \"{name}\".", + "202": "Invalid file.", + "203": "Invalid file. The file size is too big.", + "204": "The uploaded file is corrupt.", + "205": "No temporary folder is available for upload on the server.", + "206": "Upload canceled due to security reasons. The file contains HTML-like data.", + "207": "The uploaded file was renamed to \"{name}\".", + "300": "Moving file(s) failed.", + "301": "Copying file(s) failed.", + "302": "Deleting file(s) failed.", + "500": "The file browser is disabled for security reasons. Please contact your system administrator and check the CKFinder configuration file.", + "501": "Thumbnail support is disabled." + }, + "deleteFilePermissions": "Removing files is not allowed in this folder.", + "fileInvalidCharacters": "The file name cannot contain any of the following characters: {disallowedCharacters}", + "fileNameNotEmpty": "The file name cannot be empty.", + "folderInvalidCharacters": "The folder name cannot contain any of the following characters: {disallowedCharacters}", + "incorrectExtension": "File extension is not allowed in this folder.", + "missingFile": "The requested file is no longer available.", + "missingFolder": "The folder you are trying to reach is no longer available.", + "noUploadFolderSelected": "Please select a folder before uploading.", + "operationCompleted": "Operation completed with errors.", + "renameFilePermissions": "Renaming files is not allowed in this folder.", + "unknown": "It was not possible to complete the request. (Error {number})", + "unknownUploadError": "Error sending the file.", + "uploadErrors": "Upload finished with errors.", + "uploadPermissions": "File upload is not allowed." + }, + "chooseResizedImage": { + "title": "Choose Resized", + "originalSize": "Original Size", + "sizes": { + "custom": "Custom", + "large": "Large", + "max": "Max", + "medium": "Medium", + "small": "Small" + } + }, + "editImage": { + "adjust": "Adjust", + "apply": "Apply", + "confirmExit": "Are you sure you want to close? You have unsaved changes to the image.", + "crop": "Crop", + "downloadAction": "Downloading original image.", + "keepAspectRatio": "Keep Aspect Ratio", + "loading": "Loading image", + "presets": "Presets", + "reset": "Reset", + "resize": "Resize", + "rotate": "Rotate", + "rotateAntiClockwise": "90° Left", + "rotateClockwise": "90° Right", + "save": "Save", + "saveDialogFileExists": "File with the same name already exists in folder.", + "saveDialogOverwrite": "Overwrite File", + "saveDialogSaveAs": "Save as:", + "saveDialogTitle": "Save Changes", + "title": "Edit Image", + "transformationAction": "Applying transformations.", + "uploadAction": "Uploading edited image.", + "filters": { + "brightness": "Brightness", + "clip": "Clip", + "contrast": "Contrast", + "exposure": "Exposure", + "gamma": "Gamma", + "hue": "Hue", + "noise": "Noise", + "saturation": "Saturation", + "sepia": "Sepia", + "sharpen": "Sharpen", + "stackBlur": "Blur", + "vibrance": "Vibrance" + }, + "preset": { + "clarity": "Clarity", + "concentrate": "Concentrate", + "crossProcess": "Cross Process", + "glowingSun": "Glowing Sun", + "grungy": "Grungy", + "hazyDays": "Hazy Days", + "hemingway": "Hemingway", + "herMajesty": "Her Majesty", + "jarques": "Jarques", + "lomo": "Lomo", + "love": "Love", + "nostalgia": "Nostalgia", + "oldBoot": "Old Boot", + "orangePeel": "Orange Peel", + "pinhole": "Pinhole", + "sinCity": "Sin City", + "sunrise": "Sunrise", + "vintage": "Vintage" + } + }, + "shortcuts": { + "title": "Keyboard Shortcuts", + "general": { + "action": "Execute default action", + "firstItem": "Go to first item", + "focusFilesPane": "Focus files pane", + "focusFoldersPane": "Focus folders pane or breadcrumbs", + "focusNext": "Focus next pane", + "focusToolbar": "Focus toolbar", + "lastItem": "Go to last item", + "listShortcuts": "Open this help dialog", + "nextItem": "Go to next item", + "previousItem": "Go to previous item", + "showContextMenu": "Open context menu", + "title": "General Interface" + }, + "files": { + "addToSelectionAbove": "Add or remove files above to selection", + "addToSelectionBelow": "Add or remove files below to selection", + "addToSelectionLeft": "Add or remove file on the left to selection", + "addToSelectionRight": "Add or remove file on the right to selection", + "delete": "Delete file(s)", + "refresh": "Refresh files", + "rename": "Rename file", + "selectAll": "Select all files", + "upload": "Upload file(s)" + }, + "folders": { + "collapseOrParent": "Collapse folder / Go to parent folder", + "delete": "Delete folder", + "expandOrSubfolder": "Expand folder / Go to first subfolder", + "title": "Folders Pane" + }, + "keys": { + "ctrl": "Control", + "delete": "Delete", + "downArrow": "Down arrow", + "escape": "Escape", + "leftArrow": "Left arrow", + "question": "Question mark", + "rightArrow": "Right arrow", + "upArrow": "Up arrow" + }, + "keysAbbreviations": { + "alt": "alt", + "ctrl": "ctrl", + "del": "del", + "end": "end", + "home": "home", + "shift": "shift" + } + } +} diff --git a/lib/ckfinder/lang/eo.json b/lib/ckfinder/lang/eo.json new file mode 100644 index 0000000..df55c46 --- /dev/null +++ b/lib/ckfinder/lang/eo.json @@ -0,0 +1,288 @@ +{ + "appTitle": "CKFinder", + "dir": "ltr", + "langCode": "eo", + "common": { + "abort": "Ĉesigu", + "cancel": "Rezignu", + "choose": "Elektu", + "close": "Fermi", + "copy": "Kopiu", + "delete": "Forigu", + "download": "Elŝutu", + "edit": "Redakti", + "maximize": "Pligrandigi", + "messageTitle": "Informo", + "minimize": "Malpligrandigi", + "move": "Movu", + "newNameDialogTitle": "Nova dosiero", + "ok": "OK", + "pleaseWait": "Bonvolu atendi.", + "rememberDecision": "Memoru la decidon", + "rename": "Renomu", + "showMore": "Montru pli", + "skip": "Transsaltu", + "upload": "Alŝutu", + "view": "Vidu" + }, + "units": { + "dateFormat": "dd/mm/yyyy H:MM", + "dateAmPm": [ + "AM", + "PM" + ], + "kb": "{size} KB", + "mb": "{size} MB", + "gb": "{size} GB", + "sizePerSecond": "{size}/s", + "pixelShort": "px" + }, + "files": { + "autoRename": "Aŭtomata renomo", + "countMany": "{count} dosieroj", + "countOne": "1 dosiero", + "deleteConfirmation": "Ĉu vi certas, ke vi volas forigi {count} dosierojn?", + "fileDeleteConfirmation": "Ĉu vi certas, ke vi volas forigi la dosieron \"{name}\"?", + "fileRenameExtensionConfirmation": "Ĉu vi certas, ke vi volas ŝanĝi la dosiernoman finaĵon? La dosiero povus fariĝi neuzebla.", + "fileRenameLabel": "Entajpu la novan nomon de la dosiero: ", + "filesPaneTitle": "Dosiera fenestro", + "filesRefresh": "Aktualigo de dosieroj", + "filterPlaceholder": "Filtro", + "gettingFileData": "Akiro de dosieraj datumoj.", + "overwrite": "Anstataŭigu", + "loadingFilesPane": { + "title": "Ŝargata...", + "text": "La dosieroj estas ŝargataj." + }, + "emptyFilesPane": { + "title": "La dosierujo estas malplena.", + "text": "Uzu la Alŝutan butonon aŭ ŝovu kaj demetu viajn dosierojn tien." + }, + "filterFilesEmpty": { + "title": "Nenio trovita.", + "text": "Bonvolu provi uzi malsamajn serĉkriteriojn." + } + }, + "folders": { + "deleteConfirmation": "Ĉu vi certas, ke vi volas forigi la \"{name}\"dosierujon?", + "destinationFolder": "Celdosierujo", + "newNameLabel": "Bonvolu entajpi la nomon de la nova dosierujo: ", + "newSubfolder": "Nova subdosierujo", + "renameDialogTitle": "Renomu dosierujon", + "treeTitle": "Dosieruja arbo" + }, + "copy": { + "dropMenuItem": "Kopiu tien", + "errorDialogTitle": "Dosieroj kiujn oni ne povas kopii:", + "manyFilesDialogTitle": "Kopiu {count} dosierojn al...", + "manyFilesWait": "{count} dosieroj kopiataj.", + "oneFileDialogTitle": "Kopiu dosieron al...", + "oneFileWait": "Dosiero kopiata.", + "operationLabel": "Dosieroj kopiataj", + "operationSummary": "Nombro de dosieroj kopiitaj: {count}." + }, + "move": { + "dropMenuItem": "Movu tien", + "errorDialogTitle": "Dosieroj kiujn oni ne povas movi:", + "manyFilesDialogTitle": "Movu {count} dosierojn al...", + "manyFilesWait": "{count} dosieroj movataj.", + "oneFileDialogTitle": "Movu dosieron al...", + "oneFileWait": "Dosiero movata.", + "operationLabel": "Dosieroj movataj", + "operationSummary": "Nombro de dosieroj movitaj: {count}." + }, + "upload": { + "addFiles": "Almetu dosierojn", + "bytesCountProgress": "({bytesUploaded} el {bytesTotal})", + "details": "Detaloj", + "filesCountProgress": "{filesUploaded} el {filesTotal}", + "progressLabel": "Estas alŝutata.", + "progressMessage": "Alŝuto okazanta...", + "selectFileLabel": "Selektu la alŝutotan dosieron", + "selectFiles": "Selektu dosierojn alŝutotajn", + "success": "Alŝuto finita!", + "summary": "Alŝutitaj dosieroj: {count}" + }, + "settings": { + "display": "Vidigo:", + "displayDate": "Dato", + "displayName": "Dosiernomo", + "displaySize": "Dosiergrando", + "sortAscending": "Kreska", + "sortBy": "Ordigu laŭ", + "sortByOrder": "Ordo", + "sortDescending": "Malkreska", + "thumbnailSize": "Miniaturgrando", + "title": "Agordo", + "viewType": "Vido", + "viewTypeCompact": "Compact", + "viewTypeList": "Listo", + "viewTypeThumbnails": "Miniaturoj" + }, + "errors": { + "codes": { + "10": "Nevalida komando.", + "11": "La risurctipo ne estas indikita en la komando.", + "12": "La risurctipo ne estas valida.", + "13": "La konektila agordodosiero estas ne valida.", + "14": "Nevalida konektilo: {pluginName}.", + "102": "La dosier- aŭ dosierujnomo ne estas valida.", + "103": "Ne eblis plenumi la peton pro rajtaj limigoj.", + "104": "Ne eblis plenumi la peton pro atingopermesaj limigoj.", + "105": "Nevalida dosiernoma finaĵo.", + "109": "Nevalida peto.", + "110": "Nekonata eraro.", + "111": "Ne eblis plenumi la peton pro dosiergrando.", + "115": "Dosiero aŭ dosierujo kun tiu nomo jam ekzistas.", + "116": "Tiu dosierujo ne ekzistas. Bonvolu aktualigi kaj reprovi.", + "117": "Tiu dosiero ne ekzistas. Bonvolu aktualigi kaj reprovi.", + "118": "La vojoj al la fonto kaj al la celo estas samaj.", + "201": "Dosiero kun la sama nomo jam ekzistas. La alŝutita dosiero estas renomita al \"{name}\".", + "202": "Nevalida dosiero.", + "203": "Nevalida dosiero. La grando estas tro alta.", + "204": "La alŝutita dosiero estas difektita.", + "205": "Neniu provizora dosierujo estas disponebla por alŝuto al la servilo.", + "206": "Alŝuto nuligita pro kialoj pri sekureco. La dosiero entenas datenojn de HTMLtipo.", + "207": "La alŝutita dosiero estas renomita al \"{name}\".", + "300": "La movo de la dosieroj malsukcesis.", + "301": "La kopio de la dosieroj malsukcesis.", + "302": "La forigo de la dosiero malsukcesis.", + "500": "La dosieradministra sistemo estas malvalidigita. Kontaktu vian administranton kaj kontrolu la agordodosieron de CKFinder.", + "501": "La eblo de miniaturoj estas malvalidigita." + }, + "deleteFilePermissions": "Removing files is not allowed in this folder.", + "fileInvalidCharacters": "La dosiernomo ne povas enhavi la sekvajn signojn : {disallowedCharacters}", + "fileNameNotEmpty": "La dosiernomo ne povas esti malplena.", + "folderInvalidCharacters": "La dosierujnomo ne povas enhavi la sekvajn signojn : {disallowedCharacters}", + "incorrectExtension": "La dosiernoma finaĵo ne estas permesita en tiu dosierujo.", + "missingFile": "La petita dosiero ne plu estas disponebla.", + "missingFolder": "La dosierujo, kiun vi provas atingi, ne plu estas disponebla.", + "noUploadFolderSelected": "Bonvolu selekti dosierujon antaŭ la alŝuto.", + "operationCompleted": "Operacio plenumita kun eraroj.", + "renameFilePermissions": "Renaming files is not allowed in this folder.", + "unknown": "Ne eblis plenumi la peton. (Eraro {number})", + "unknownUploadError": "Eraro dum la dosieralŝuto.", + "uploadErrors": "Alŝuto finita kun eraroj.", + "uploadPermissions": "La dosieralŝuto ne estas permesita." + }, + "chooseResizedImage": { + "title": "Elektu skalon", + "originalSize": "Origina grando", + "sizes": { + "custom": "Personigita", + "large": "Granda", + "max": "Plej granda", + "medium": "Mezgranda", + "small": "Malgranda" + } + }, + "editImage": { + "adjust": "Akomodu", + "apply": "Apliku", + "confirmExit": "Ĉu vi certas ke vi volas fermi ? Vi havas nekonservitajn ŝanĝojn en la bildo.", + "crop": "Pritondu", + "downloadAction": "Elŝuto de la origina bildo.", + "keepAspectRatio": "Konservu Aspektrejŝon", + "loading": "La bildo estas ŝargata", + "presets": "Antaŭagordo", + "reset": "Rekomencigo", + "resize": "Ŝanĝu grandon", + "rotate": "Turnu", + "rotateAntiClockwise": "90° Maldekstren", + "rotateClockwise": "90° Dekstren", + "save": "Konservu", + "saveDialogFileExists": "Dosiero kun la sama nomo jam ekzistas en dosierujo.", + "saveDialogOverwrite": "Anstataŭigu Dosieron", + "saveDialogSaveAs": "Konservu kiel:", + "saveDialogTitle": "Konservu ŝanĝojn", + "title": "Redaktu bildon", + "transformationAction": "Apliko de la transformoj.", + "uploadAction": "Alŝuto de la redaktita bildo.", + "filters": { + "brightness": "Brileco", + "clip": "Clip", + "contrast": "Kontrasto", + "exposure": "Ekspono", + "gamma": "Gamma", + "hue": "Kolortono", + "noise": "Bruo", + "saturation": "Satureco", + "sepia": "Sepia", + "sharpen": "Pliakrigo", + "stackBlur": "Malklareco", + "vibrance": "Vibranco" + }, + "preset": { + "clarity": "Klareco", + "concentrate": "Densigitaĵo", + "crossProcess": "Krucproceso", + "glowingSun": "Arda Suno", + "grungy": "Malpura", + "hazyDays": "Brumaj Tagoj", + "hemingway": "Hemingway", + "herMajesty": "Reĝina Moŝto", + "jarques": "Jarques", + "lomo": "Lomo", + "love": "Amo", + "nostalgia": "Nostalgio", + "oldBoot": "Malnova boto", + "orangePeel": "Oranĝŝelo", + "pinhole": "Stenopo", + "sinCity": "Pekurbo", + "sunrise": "Sunleviĝo", + "vintage": "Vinberrikolto" + } + }, + "shortcuts": { + "title": "Klavkombinaĵoj", + "general": { + "action": "Plenumu la defaŭltan agon", + "firstItem": "Iru al la unua elemento", + "focusFilesPane": "Fokuso al dosiera fenestro", + "focusFoldersPane": "Fokuso al dosieruja fenestro aŭ paĝnivela navigo", + "focusNext": "Fokuso al la sekva fenestro", + "focusToolbar": "Fokuso al ilbreto", + "lastItem": "Iru al la lasta elemento", + "listShortcuts": "Malfermu tiun helpdialogon", + "nextItem": "Iru al la sekva elemento", + "previousItem": "Iru al la antaŭa elemento", + "showContextMenu": "Malfermu la kuntekstan menuon ", + "title": "Ĝenerala interfaco" + }, + "files": { + "addToSelectionAbove": "Almetu al la selektaĵo aŭ forigu el ĝi suprajn dosierojn", + "addToSelectionBelow": "Almetu al la selektaĵo aŭ forigu el ĝi malsuprajn dosierojn", + "addToSelectionLeft": "Almetu al la selektaĵo aŭ forigu el ĝi dosierojn de la maldekstra flanko", + "addToSelectionRight": "Almetu al la selektaĵo aŭ forigu el ĝi dosierojn de la dekstra flanko", + "delete": "Forigu dosiero(j)n", + "refresh": "Aktualigu dosierojn", + "rename": "Renomu dosieron", + "selectAll": "Selektu ĉiujn dosierojn", + "upload": "Alŝutu dosiero(j)n" + }, + "folders": { + "collapseOrParent": "Maletendu dosierujon / Iru al la patra dosierujo", + "delete": "Forigi dosierujon", + "expandOrSubfolder": "Etendu dosierujon / Iru al la unua subdosierujo", + "title": "Dosieruja fenestro" + }, + "keys": { + "ctrl": "Stirklavo", + "delete": "Foriga klavo", + "downArrow": "Sago malsupren", + "escape": "Eskapa klavo", + "leftArrow": "Sago maldekstren", + "question": "Demandosigno", + "rightArrow": "Sago dekstren", + "upArrow": "Sago supren" + }, + "keysAbbreviations": { + "alt": "alt", + "ctrl": "ctrl", + "del": "del", + "end": "fino", + "home": "hejmo", + "shift": "maj" + } + } +} diff --git a/lib/ckfinder/lang/es-mx.json b/lib/ckfinder/lang/es-mx.json new file mode 100644 index 0000000..973762c --- /dev/null +++ b/lib/ckfinder/lang/es-mx.json @@ -0,0 +1,288 @@ +{ + "appTitle": "CKFinder", + "dir": "ltr", + "langCode": "es-mx", + "common": { + "abort": "Abort", + "cancel": "Cancelar", + "choose": "Choose", + "close": "Cerrar", + "copy": "Copy", + "delete": "Borrar", + "download": "Descargar", + "edit": "Editar", + "maximize": "Maximize", + "messageTitle": "Información", + "minimize": "Minimize", + "move": "Move", + "newNameDialogTitle": "Nuevo nombre", + "ok": "OK", + "pleaseWait": "Please wait.", + "rememberDecision": "Recordar mi decisión", + "rename": "Renombrar", + "showMore": "Show more", + "skip": "Omitir", + "upload": "Añadir", + "view": "Ver" + }, + "units": { + "dateFormat": "dd/mm/yyyy H:MM", + "dateAmPm": [ + "AM", + "PM" + ], + "kb": "{size} KB", + "mb": "{size} MB", + "gb": "{size} GB", + "sizePerSecond": "{size}/s", + "pixelShort": "px" + }, + "files": { + "autoRename": "Auto-renombrar", + "countMany": "{count} archivos", + "countOne": "1 archivo", + "deleteConfirmation": "Are you sure you want to delete {count} files?", + "fileDeleteConfirmation": "¿Está seguro de que quiere borrar el archivo \"{name}\".?", + "fileRenameExtensionConfirmation": "¿Está seguro de querer cambiar la extensión del archivo? El archivo puede dejar de ser usable.", + "fileRenameLabel": "Por favor, escriba el nuevo nombre del archivo: ", + "filesPaneTitle": "Files pane", + "filesRefresh": "Refreshing files", + "filterPlaceholder": "Filter", + "gettingFileData": "Getting file data.", + "overwrite": "Sobreescribir", + "loadingFilesPane": { + "title": "Loading...", + "text": "The files are being loaded." + }, + "emptyFilesPane": { + "title": "The folder is empty.", + "text": "Use the Upload button or drag and drop your files here." + }, + "filterFilesEmpty": { + "title": "Nothing found.", + "text": "Please try using different search criteria." + } + }, + "folders": { + "deleteConfirmation": "¿Está seguro de que quiere borrar la carpeta \"{name}\"?", + "destinationFolder": "Destination Folder", + "newNameLabel": "Por favor, escriba el nombre para la nueva carpeta: ", + "newSubfolder": "Nueva Subcarpeta", + "renameDialogTitle": "Rename Folder", + "treeTitle": "Folders tree" + }, + "copy": { + "dropMenuItem": "Copiar aquí", + "errorDialogTitle": "Files that cannot be copied:", + "manyFilesDialogTitle": "Copy {count} Files To...", + "manyFilesWait": "Copying {count} files.", + "oneFileDialogTitle": "Copy File To...", + "oneFileWait": "Copying file.", + "operationLabel": "Copying Files", + "operationSummary": "Number of files copied: {count}." + }, + "move": { + "dropMenuItem": "Mover aquí", + "errorDialogTitle": "Files that cannot be moved:", + "manyFilesDialogTitle": "Move {count} Files To...", + "manyFilesWait": "Moving {count} files.", + "oneFileDialogTitle": "Move File To...", + "oneFileWait": "Moving file.", + "operationLabel": "Moving Files", + "operationSummary": "Number of files moved: {count}." + }, + "upload": { + "addFiles": "Añadir archivos", + "bytesCountProgress": "({bytesUploaded} of {bytesTotal})", + "details": "Details", + "filesCountProgress": "{filesUploaded} of {filesTotal}", + "progressLabel": "Subida en progreso.", + "progressMessage": "Uploading...", + "selectFileLabel": "Elija el archivo a subir", + "selectFiles": "Select files to upload", + "success": "Upload finished!", + "summary": "Uploaded files: {count}" + }, + "settings": { + "display": "Mostrar:", + "displayDate": "Fecha", + "displayName": "Nombre de archivo", + "displaySize": "Tamaño del archivo", + "sortAscending": "Ascending", + "sortBy": "Sort by", + "sortByOrder": "Order", + "sortDescending": "Descending", + "thumbnailSize": "Thumbnail Size", + "title": "Configuración", + "viewType": "View", + "viewTypeCompact": "Compact", + "viewTypeList": "List", + "viewTypeThumbnails": "Thumbnails" + }, + "errors": { + "codes": { + "10": "Comando incorrecto.", + "11": "El tipo de recurso no ha sido especificado en la solicitud.", + "12": "El tipo de recurso solicitado no es válido.", + "13": "The connector configuration file is invalid.", + "14": "Invalid connector plugin: {pluginName}.", + "102": "Nombre de archivo o carpeta no válido.", + "103": "No se ha podido completar la solicitud debido a las restricciones de autorización.", + "104": "No ha sido posible completar la solicitud debido a restricciones en el sistema de archivos.", + "105": "La extensión del archivo no es válida.", + "109": "Petición inválida.", + "110": "Error desconocido.", + "111": "It was not possible to complete the request due to resulting file size.", + "115": "Ya existe un archivo o carpeta con ese nombre.", + "116": "No se ha encontrado la carpeta. Por favor, actualice y pruebe de nuevo.", + "117": "No se ha encontrado el archivo. Por favor, actualice la lista de archivos y pruebe de nuevo.", + "118": "Las rutas origen y destino son iguales.", + "201": "Ya existía un archivo con ese nombre. El archivo subido ha sido renombrado como \"{name}\".", + "202": "Archivo inválido.", + "203": "Archivo inválido. El tamaño es demasiado grande.", + "204": "El archivo subido está corrupto.", + "205": "La carpeta temporal no está disponible en el servidor para las subidas.", + "206": "La subida se ha cancelado por razones de seguridad. El archivo contenía código HTML.", + "207": "El archivo subido ha sido renombrado como \"{name}\".", + "300": "Ha fallado el mover el(los) archivo(s).", + "301": "Ha fallado el copiar el(los) archivo(s).", + "302": "Deleting file(s) failed.", + "500": "El navegador de archivos está deshabilitado por razones de seguridad. Por favor, contacte con el administrador de su sistema y compruebe el archivo de configuración de CKFinder.", + "501": "El soporte para iconos está deshabilitado." + }, + "deleteFilePermissions": "Removing files is not allowed in this folder.", + "fileInvalidCharacters": "El nombre del archivo no puede contener ninguno de los caracteres siguientes: {disallowedCharacters}", + "fileNameNotEmpty": "The file name cannot be empty.", + "folderInvalidCharacters": "El nombre de la carpeta no puede contener ninguno de los caracteres siguientes: {disallowedCharacters}", + "incorrectExtension": "La extensión del archivo no está permitida en esta carpeta.", + "missingFile": "The requested file is no longer available.", + "missingFolder": "The folder you are trying to reach is no longer available.", + "noUploadFolderSelected": "Por favor, escoja la carpeta antes de iniciar la subida.", + "operationCompleted": "Operation completed with errors.", + "renameFilePermissions": "Renaming files is not allowed in this folder.", + "unknown": "No ha sido posible completar la solicitud. (Error {number})", + "unknownUploadError": "Error enviando el archivo.", + "uploadErrors": "Upload finished with errors.", + "uploadPermissions": "No puede subir archivos." + }, + "chooseResizedImage": { + "title": "Choose Resized", + "originalSize": "Original Size", + "sizes": { + "custom": "Custom", + "large": "Large", + "max": "Max", + "medium": "Medium", + "small": "Small" + } + }, + "editImage": { + "adjust": "Adjust", + "apply": "Apply", + "confirmExit": "Are you sure you want to close? You have unsaved changes to the image.", + "crop": "Crop", + "downloadAction": "Downloading original image.", + "keepAspectRatio": "Keep Aspect Ratio", + "loading": "Loading image", + "presets": "Presets", + "reset": "Reset", + "resize": "Resize", + "rotate": "Rotate", + "rotateAntiClockwise": "90° Left", + "rotateClockwise": "90° Right", + "save": "Save", + "saveDialogFileExists": "File with the same name already exists in folder.", + "saveDialogOverwrite": "Overwrite File", + "saveDialogSaveAs": "Save as:", + "saveDialogTitle": "Save Changes", + "title": "Edit Image", + "transformationAction": "Applying transformations.", + "uploadAction": "Uploading edited image.", + "filters": { + "brightness": "Brightness", + "clip": "Clip", + "contrast": "Contrast", + "exposure": "Exposure", + "gamma": "Gamma", + "hue": "Hue", + "noise": "Noise", + "saturation": "Saturation", + "sepia": "Sepia", + "sharpen": "Sharpen", + "stackBlur": "Blur", + "vibrance": "Vibrance" + }, + "preset": { + "clarity": "Clarity", + "concentrate": "Concentrate", + "crossProcess": "Cross Process", + "glowingSun": "Glowing Sun", + "grungy": "Grungy", + "hazyDays": "Hazy Days", + "hemingway": "Hemingway", + "herMajesty": "Her Majesty", + "jarques": "Jarques", + "lomo": "Lomo", + "love": "Love", + "nostalgia": "Nostalgia", + "oldBoot": "Old Boot", + "orangePeel": "Orange Peel", + "pinhole": "Pinhole", + "sinCity": "Sin City", + "sunrise": "Sunrise", + "vintage": "Vintage" + } + }, + "shortcuts": { + "title": "Keyboard Shortcuts", + "general": { + "action": "Execute default action", + "firstItem": "Go to first item", + "focusFilesPane": "Focus files pane", + "focusFoldersPane": "Focus folders pane or breadcrumbs", + "focusNext": "Focus next pane", + "focusToolbar": "Focus toolbar", + "lastItem": "Go to last item", + "listShortcuts": "Open this help dialog", + "nextItem": "Go to next item", + "previousItem": "Go to previous item", + "showContextMenu": "Open context menu", + "title": "General Interface" + }, + "files": { + "addToSelectionAbove": "Add or remove files above to selection", + "addToSelectionBelow": "Add or remove files below to selection", + "addToSelectionLeft": "Add or remove file on the left to selection", + "addToSelectionRight": "Add or remove file on the right to selection", + "delete": "Delete file(s)", + "refresh": "Refresh files", + "rename": "Rename file", + "selectAll": "Select all files", + "upload": "Upload file(s)" + }, + "folders": { + "collapseOrParent": "Collapse folder / Go to parent folder", + "delete": "Delete folder", + "expandOrSubfolder": "Expand folder / Go to first subfolder", + "title": "Folders Pane" + }, + "keys": { + "ctrl": "Control", + "delete": "Delete", + "downArrow": "Down arrow", + "escape": "Escape", + "leftArrow": "Left arrow", + "question": "Question mark", + "rightArrow": "Right arrow", + "upArrow": "Up arrow" + }, + "keysAbbreviations": { + "alt": "alt", + "ctrl": "ctrl", + "del": "del", + "end": "end", + "home": "home", + "shift": "shift" + } + } +} diff --git a/lib/ckfinder/lang/es.json b/lib/ckfinder/lang/es.json new file mode 100644 index 0000000..c3c6bcb --- /dev/null +++ b/lib/ckfinder/lang/es.json @@ -0,0 +1,288 @@ +{ + "appTitle": "CKFinder", + "dir": "ltr", + "langCode": "es", + "common": { + "abort": "Abortar", + "cancel": "Cancelar", + "choose": "Seleccionar", + "close": "Cerrar", + "copy": "Copiar", + "delete": "Borrar", + "download": "Descargar", + "edit": "Editar", + "maximize": "Maximizar", + "messageTitle": "Información", + "minimize": "Minimizar", + "move": "Mover", + "newNameDialogTitle": "Nuevo nombre", + "ok": "Ok", + "pleaseWait": "Por favor espere.", + "rememberDecision": "Recordar mi decisión", + "rename": "Renombrar", + "showMore": "Mostrar más", + "skip": "Omitir", + "upload": "Añadir", + "view": "Ver" + }, + "units": { + "dateFormat": "dd/mm/yyyy H:MM", + "dateAmPm": [ + "AM", + "PM" + ], + "kb": "{size} KB", + "mb": "{size} MB", + "gb": "{size} GB", + "sizePerSecond": "{size}/s", + "pixelShort": "px" + }, + "files": { + "autoRename": "Auto-renombrar", + "countMany": "{count} ficheros", + "countOne": "1 fichero", + "deleteConfirmation": "¿Está seguro de que quiere borrar {count} ficheros?", + "fileDeleteConfirmation": "¿Está seguro de que quiere borrar el fichero \"{name}\"?", + "fileRenameExtensionConfirmation": "¿Está seguro de querer cambiar la extensión del fichero? El fichero puede dejar de ser usable.", + "fileRenameLabel": "Por favor, escriba el nuevo nombre del fichero: ", + "filesPaneTitle": "Panel de ficheros", + "filesRefresh": "Actualizando ficheros", + "filterPlaceholder": "Filtro", + "gettingFileData": "Obteniendo los datos del fichero. Por favor espere.", + "overwrite": "Sobreescribir", + "loadingFilesPane": { + "title": "Cargando...", + "text": "Por favor espere. Los ficheros están siendo cargados." + }, + "emptyFilesPane": { + "title": "La carpeta está vacía.", + "text": "Use el botón Subir o arrastre y suelte sus ficheros aquí." + }, + "filterFilesEmpty": { + "title": "No hay resultados.", + "text": "Por favor, pruebe usando otro criterio de búsqueda." + } + }, + "folders": { + "deleteConfirmation": "¿Está seguro de que quiere borrar la carpeta \"{name}\"?", + "destinationFolder": "Carpeta de destino", + "newNameLabel": "Por favor, escriba el nombre para la nueva carpeta: ", + "newSubfolder": "Nueva Subcarpeta", + "renameDialogTitle": "Renombrar carpeta", + "treeTitle": "Árbol de carpetas" + }, + "copy": { + "dropMenuItem": "Copiar aquí", + "errorDialogTitle": "Ficheros que no pueden ser copiados:", + "manyFilesDialogTitle": "Copiar {count} Archivos A...", + "manyFilesWait": "Copiando {count} ficheros. Por favor espere.", + "oneFileDialogTitle": "Copiar Fichero A...", + "oneFileWait": "Copiando fichero. Por favor espere.", + "operationLabel": "Copiando Ficheros", + "operationSummary": "Número de ficheros copiados: {count}." + }, + "move": { + "dropMenuItem": "Mover aquí", + "errorDialogTitle": "Ficheros que no pueden ser movidos:", + "manyFilesDialogTitle": "Mover {count} Ficheros A...", + "manyFilesWait": "Moviendo {count} ficheros. Por favor espere.", + "oneFileDialogTitle": "Mover Fichero A...", + "oneFileWait": "Moviendo fichero. Por favor espere.", + "operationLabel": "Moviendo Ficheros", + "operationSummary": "Número de ficheros movidos: {count}." + }, + "upload": { + "addFiles": "Añadir ficheros", + "bytesCountProgress": "({bytesUploaded} de {bytesTotal})", + "details": "Detalles", + "filesCountProgress": "{filesUploaded} de {filesTotal}", + "progressLabel": "Subida en progreso.", + "progressMessage": "Subiendo...", + "selectFileLabel": "Elija el fichero a subir", + "selectFiles": "Elije los ficheros para subir", + "success": "¡Subida terminada!", + "summary": "Ficheros añadidos: {count}" + }, + "settings": { + "display": "Mostrar:", + "displayDate": "Fecha", + "displayName": "Nombre de fichero", + "displaySize": "Tamaño del fichero", + "sortAscending": "Ascendente", + "sortBy": "Ordenar por", + "sortByOrder": "Orden", + "sortDescending": "Descendente", + "thumbnailSize": "Tamaño de miniatura", + "title": "Configuración", + "viewType": "Vista", + "viewTypeCompact": "Compact", + "viewTypeList": "Lista", + "viewTypeThumbnails": "Miniaturas" + }, + "errors": { + "codes": { + "10": "Comando incorrecto.", + "11": "El tipo de recurso no ha sido especificado en la solicitud.", + "12": "El tipo de recurso solicitado no es válido.", + "13": "El archivo de configuración del conector no es válido.", + "14": "Plugin del conector inválido: {pluginName}.", + "102": "Nombre de fichero o carpeta no válido.", + "103": "No se ha podido completar la solicitud debido a las restricciones de autorización.", + "104": "No ha sido posible completar la solicitud debido a restricciones en el sistema de ficheros.", + "105": "La extensión del archivo no es válida.", + "109": "Petición inválida.", + "110": "Error desconocido.", + "111": "No fué posible completar la petición debido al tamaño del fichero.", + "115": "Ya existe un fichero o carpeta con ese nombre.", + "116": "No se ha encontrado la carpeta. Por favor, actualice y pruebe de nuevo.", + "117": "No se ha encontrado el fichero. Por favor, actualice la lista de ficheros y pruebe de nuevo.", + "118": "Las rutas origen y destino son iguales.", + "201": "Ya existía un fichero con ese nombre. El fichero subido ha sido renombrado como \"{name}\".", + "202": "Fichero inválido.", + "203": "Fichero inválido. El tamaño es demasiado grande.", + "204": "El fichero subido está corrupto.", + "205": "La carpeta temporal no está disponible en el servidor para las subidas.", + "206": "La subida se ha cancelado por razones de seguridad. El fichero contenía código HTML.", + "207": "El fichero subido ha sido renombrado como \"{name}\".", + "300": "Ha fallado el mover el(los) fichero(s).", + "301": "Ha fallado el copiar el(los) fichero(s).", + "302": "Ha fallado la eliminación de el/los fichero(s).", + "500": "El navegador de archivos está deshabilitado por razones de seguridad. Por favor, contacte con el administrador de su sistema y compruebe el fichero de configuración de CKFinder.", + "501": "El soporte para iconos está deshabilitado." + }, + "deleteFilePermissions": "Removing files is not allowed in this folder.", + "fileInvalidCharacters": "El nombre del fichero no puede contener ninguno de los caracteres siguientes: {disallowedCharacters}", + "fileNameNotEmpty": "El fichero no puede estar vacío.", + "folderInvalidCharacters": "El nombre de la carpeta no puede contener ninguno de los caracteres siguientes: {disallowedCharacters}", + "incorrectExtension": "La extensión del fichero no está permitida en esta carpeta.", + "missingFile": "El fichero solicitado ya no está disponible.", + "missingFolder": "La carpeta a la que estás intentando acceder ya no está disponible.", + "noUploadFolderSelected": "Por favor, escoja la carpeta antes de iniciar la subida.", + "operationCompleted": "Operación completada con errores.", + "renameFilePermissions": "Renaming files is not allowed in this folder.", + "unknown": "No ha sido posible completar la solicitud. (Error {number})", + "unknownUploadError": "Error enviando el fichero.", + "uploadErrors": "Subida terminada con errores.", + "uploadPermissions": "No puede subir ficheros." + }, + "chooseResizedImage": { + "title": "Seleccionar Escalado", + "originalSize": "Tamaño original", + "sizes": { + "custom": "Personalizado", + "large": "Grande", + "max": "Max", + "medium": "Mediano", + "small": "Pequeño" + } + }, + "editImage": { + "adjust": "Ajustar", + "apply": "Aplicar", + "confirmExit": "¿Seguro que quieres cerrar? Tienes cambios sin guardar en la imagen.", + "crop": "Recortar", + "downloadAction": "Descargando imagen original.", + "keepAspectRatio": "Mantener el ratio de aspecto", + "loading": "Cargando imagen", + "presets": "Ajustes preestablecidos", + "reset": "Reset", + "resize": "Redimensionar", + "rotate": "Rotar", + "rotateAntiClockwise": "90° Izquierda", + "rotateClockwise": "90° Derecha", + "save": "Guardar", + "saveDialogFileExists": "Ya existe un archivo con el mismo nombre en la carpeta.", + "saveDialogOverwrite": "Sobreescribir archvio", + "saveDialogSaveAs": "Guardar como:", + "saveDialogTitle": "Guardar cambios", + "title": "Editar Imagen", + "transformationAction": "Aplicando transformaciones.", + "uploadAction": "Subiendo imagen editada.", + "filters": { + "brightness": "Brillo", + "clip": "Clip", + "contrast": "Contraste", + "exposure": "Exposición", + "gamma": "Gama", + "hue": "Matiz", + "noise": "Ruido", + "saturation": "Saturación", + "sepia": "Sepia", + "sharpen": "Enfocar", + "stackBlur": "Desenfocar", + "vibrance": "Vibrance" + }, + "preset": { + "clarity": "Claridad", + "concentrate": "Concentrado", + "crossProcess": "Proceso cruzado", + "glowingSun": "Soleado", + "grungy": "Sucio", + "hazyDays": "Nublado", + "hemingway": "Hemingway", + "herMajesty": "Su Majestad", + "jarques": "Jarques", + "lomo": "Lomo", + "love": "Amor", + "nostalgia": "Nostalgia", + "oldBoot": "Bota vieja", + "orangePeel": "Piel de naranja", + "pinhole": "Camara oscura", + "sinCity": "Sin City", + "sunrise": "Atarceder", + "vintage": "Vintage" + } + }, + "shortcuts": { + "title": "Atajos de teclado", + "general": { + "action": "Ejecutar acción por defecto", + "firstItem": "Ir al primer elemento", + "focusFilesPane": "Foco en panel de archivos", + "focusFoldersPane": "Foco en panel de carpetas", + "focusNext": "Foco en siguiente panel", + "focusToolbar": "Foco en barra de herramientas", + "lastItem": "Ir al último elemento", + "listShortcuts": "Abrir este dialogo de ayuda", + "nextItem": "Ir al elemento siguiente", + "previousItem": "Ir al elemento anterior", + "showContextMenu": "Abrir menú contextual", + "title": "Panel principal" + }, + "files": { + "addToSelectionAbove": "Añadir o eliminar ficheros encima de la selección", + "addToSelectionBelow": "Añadir o eliminar ficheros debajo de la selección", + "addToSelectionLeft": "Añadir o eliminar ficheros a la izquierda de la selección", + "addToSelectionRight": "Añadir o eliminar ficheros a la derecha de la selección", + "delete": "Eliminar fichero(s)", + "refresh": "Actualizar fichero", + "rename": "Renombrar fichero", + "selectAll": "Seleccionar todos los ficheros", + "upload": "Subir fichero(s)" + }, + "folders": { + "collapseOrParent": "Contraer carpeta / Ir a la carpeta superior", + "delete": "Eliminar carpeta", + "expandOrSubfolder": "Expandir carpeta / Ir a la primera subcarpeta", + "title": "Panel de carpetas" + }, + "keys": { + "ctrl": "Control", + "delete": "Suprimir", + "downArrow": "Flecha abajo", + "escape": "Escape", + "leftArrow": "Flecha Izquierda", + "question": "Signo de interrogación", + "rightArrow": "Flecha derecha", + "upArrow": "Flecha arriba" + }, + "keysAbbreviations": { + "alt": "alt", + "ctrl": "ctrl", + "del": "supr", + "end": "fin", + "home": "home", + "shift": "mayus." + } + } +} diff --git a/lib/ckfinder/lang/et.json b/lib/ckfinder/lang/et.json new file mode 100644 index 0000000..9cd5192 --- /dev/null +++ b/lib/ckfinder/lang/et.json @@ -0,0 +1,288 @@ +{ + "appTitle": "CKFinder", + "dir": "ltr", + "langCode": "et", + "common": { + "abort": "Abort", + "cancel": "Loobu", + "choose": "Vali", + "close": "Sulge", + "copy": "Kopeeri", + "delete": "Kustuta", + "download": "Laadi alla", + "edit": "Muuda", + "maximize": "Maximize", + "messageTitle": "Andmed", + "minimize": "Minimize", + "move": "Liiguta", + "newNameDialogTitle": "Uue nime andmine", + "ok": "OK", + "pleaseWait": "Palun oota.", + "rememberDecision": "Jäta valik meelde", + "rename": "Muuda nime", + "showMore": "Näita veel", + "skip": "Jäta vahele", + "upload": "Laadi üles", + "view": "Kuva" + }, + "units": { + "dateFormat": "yyyy-mm-dd H:MM", + "dateAmPm": [ + "eL", + "pL" + ], + "kb": "{size} KB", + "mb": "{size} MB", + "gb": "{size} GB", + "sizePerSecond": "{size}/s", + "pixelShort": "px" + }, + "files": { + "autoRename": "Muuda automaatselt nime", + "countMany": "{count} faili", + "countOne": "1 fail", + "deleteConfirmation": "Kas tahad kindlasti kustutada {count} faili?", + "fileDeleteConfirmation": "Kas tahad kindlasti kustutada faili \"{name}\"?", + "fileRenameExtensionConfirmation": "Kas tahad kindlasti faili laiendit muuta? Fail võib muutuda kasutamatuks.", + "fileRenameLabel": "Palun sisesta faili uus nimi: ", + "filesPaneTitle": "Failide paneel", + "filesRefresh": "Failide värskendamine", + "filterPlaceholder": "Filter", + "gettingFileData": "Faili andmete hankimine.", + "overwrite": "Kirjuta üle", + "loadingFilesPane": { + "title": "Laadimine...", + "text": "Faile laaditakse." + }, + "emptyFilesPane": { + "title": "Kaust on tühi.", + "text": "Kasuta Laadi üles nuppu või lohista oma failid siia." + }, + "filterFilesEmpty": { + "title": "Midagi ei leitud.", + "text": "Proovi kasutada mingit muud otsingusõna." + } + }, + "folders": { + "deleteConfirmation": "Kas tahad kindlasti kausta \"{name}\" kustutada?", + "destinationFolder": "Sihtkaust", + "newNameLabel": "Palun sisesta uue kataloogi nimi: ", + "newSubfolder": "Uus alamkaust", + "renameDialogTitle": "Nimeta kaust ümber", + "treeTitle": "Kaustade paneel" + }, + "copy": { + "dropMenuItem": "Kopeeri siia", + "errorDialogTitle": "Failid, mida ei saanud kopeerida:", + "manyFilesDialogTitle": "Kopeeri {count} faili kausta...", + "manyFilesWait": "{count} faili kopeerimine.", + "oneFileDialogTitle": "Kopeeri fail kausta...", + "oneFileWait": "Faili kopeerimine.", + "operationLabel": "Failide kopeerimine", + "operationSummary": "Kopeeritud failide arv: {count}." + }, + "move": { + "dropMenuItem": "Liiguta siia", + "errorDialogTitle": "Failid, mida ei saanud liigutada:", + "manyFilesDialogTitle": "Liiguta {count} faili kausta...", + "manyFilesWait": "{count} faili liigutamine.", + "oneFileDialogTitle": "Liiguta fail kausta...", + "oneFileWait": "Faili liigutamine.", + "operationLabel": "Failide liigutamine", + "operationSummary": "Liigutatud failide arv: {count}." + }, + "upload": { + "addFiles": "Lisa faile", + "bytesCountProgress": "({bytesUploaded} / {bytesTotal})", + "details": "Andmed", + "filesCountProgress": "{filesUploaded} / {filesTotal}", + "progressLabel": "Üleslaadimine.", + "progressMessage": "Üleslaadimine...", + "selectFileLabel": "Vali üleslaadimiseks fail", + "selectFiles": "Vali üleslaadimiseks failid", + "success": "Üleslaadimine lõpetati!", + "summary": "Üleslaaditud faile: {count}" + }, + "settings": { + "display": "Kuva:", + "displayDate": "Kuupäev", + "displayName": "Faili nimi", + "displaySize": "Faili suurus", + "sortAscending": "Ascending", + "sortBy": "Sort by", + "sortByOrder": "Order", + "sortDescending": "Descending", + "thumbnailSize": "Pisipildi suurus", + "title": "Sätted", + "viewType": "View", + "viewTypeCompact": "Compact", + "viewTypeList": "List", + "viewTypeThumbnails": "Thumbnails" + }, + "errors": { + "codes": { + "10": "Vigane käsk.", + "11": "Allika liik polnud päringus määratud.", + "12": "Päritud liik pole sobiv.", + "13": "Konnektori seadistusfail on vigane.", + "14": "Vigane konnektorplugin: {pluginName}.", + "102": "Sobimatu faili või kausta nimi.", + "103": "Piiratud õiguste tõttu polnud võimalik päringut lõpetada.", + "104": "Failisüsteemi piiratud õiguste tõttu polnud võimalik päringut lõpetada.", + "105": "Sobimatu faililaiend.", + "109": "Vigane päring.", + "110": "Tundmatu viga.", + "111": "Päringut polnud võimalik täita tekkiva faili suuruse tõttu.", + "115": "Sellenimeline fail või kaust on juba olemas.", + "116": "Kausta ei leitud. Palun värskenda lehte ja proovi uuesti.", + "117": "Faili ei leitud. Palun värskenda lehte ja proovi uuesti.", + "118": "Lähte- ja sihtasukoht on sama.", + "201": "Samanimeline fail on juba olemas. Üles laaditud faili nimeks pandi \"{name}\".", + "202": "Vigane fail.", + "203": "Vigane fail. Fail on liiga suur.", + "204": "Üleslaaditud fail on rikutud.", + "205": "Serverisse üleslaadimiseks pole ühtegi ajutiste failide kataloogi.", + "206": "Üleslaadimine katkestati turvakaalutlustel. Fail sisaldab HTMLi sarnaseid andmeid.", + "207": "Üleslaaditud faili nimeks pandi \"{name}\".", + "300": "Faili(de) liigutamine nurjus.", + "301": "Faili(de) kopeerimine nurjus.", + "302": "Faili(de) kustutamine nurjus.", + "500": "Failide sirvija on turvakaalutlustel keelatud. Palun võta ühendust oma süsteemi administraatoriga ja kontrolli CKFinderi seadistusfaili.", + "501": "Pisipiltide tugi on keelatud." + }, + "deleteFilePermissions": "Removing files is not allowed in this folder.", + "fileInvalidCharacters": "Faili nimi ei tohi sisaldada ühtegi järgnevatest märkidest: {disallowedCharacters}", + "fileNameNotEmpty": "The file name cannot be empty.", + "folderInvalidCharacters": "Faili nimi ei tohi sisaldada ühtegi järgnevatest märkidest: {disallowedCharacters}", + "incorrectExtension": "Selline faili laiend pole selles kaustas lubatud.", + "missingFile": "Faili, mida püüad avada, pole enam saadaval.", + "missingFolder": "Kausta, mida püüad avada, pole enam olemas.", + "noUploadFolderSelected": "Palun vali enne üleslaadimist kataloog.", + "operationCompleted": "Otsing lõpetati vigadega.", + "renameFilePermissions": "Renaming files is not allowed in this folder.", + "unknown": "Päringu täitmine polnud võimalik. (Viga {number})", + "unknownUploadError": "Viga faili saatmisel.", + "uploadErrors": "Üleslaadimine lõpetati vigadega.", + "uploadPermissions": "Failide üleslaadimine pole lubatud." + }, + "chooseResizedImage": { + "title": "Vali skaleerimine", + "originalSize": "Originaalsuurus", + "sizes": { + "custom": "Kohandatud", + "large": "Suur", + "max": "Maksimaalne", + "medium": "Keskmine", + "small": "Väike" + } + }, + "editImage": { + "adjust": "Värvid", + "apply": "Nõus", + "confirmExit": "Kas tahad ikka sulgeda? Kõik pildile tehtud salvestamata muudatused lähevad nii kaotsi.", + "crop": "Kärpimine", + "downloadAction": "Lähtepildi allalaadimine.", + "keepAspectRatio": "Külgede suhte säilitamine", + "loading": "Pildi laadimine", + "presets": "Mallid", + "reset": "Lähtesta", + "resize": "Suurus", + "rotate": "Pööramine", + "rotateAntiClockwise": "90° vasakule", + "rotateClockwise": "90° paremale", + "save": "Salvesta", + "saveDialogFileExists": "Samanimeline fail on kaustas juba olemas.", + "saveDialogOverwrite": "Faili ülekirjutamine", + "saveDialogSaveAs": "Salvesta kui:", + "saveDialogTitle": "Muudatuste salvestamine", + "title": "Pildi muutmine", + "transformationAction": "Muudatuste rakendamine.", + "uploadAction": "Muudetud pildi üleslaadimine.", + "filters": { + "brightness": "Heledus", + "clip": "Lõikamine", + "contrast": "Kontrastsus", + "exposure": "Säri", + "gamma": "Gamma", + "hue": "Värvitoon", + "noise": "Müra", + "saturation": "Küllastus", + "sepia": "Seepia", + "sharpen": "Teravus", + "stackBlur": "Udune", + "vibrance": "Värvilisus" + }, + "preset": { + "clarity": "Selgus", + "concentrate": "Kontsentraat", + "crossProcess": "Töötlus", + "glowingSun": "Hele päike", + "grungy": "Grunge", + "hazyDays": "Kerge udu", + "hemingway": "Hemingway", + "herMajesty": "Kuninganna", + "jarques": "Vana film", + "lomo": "Sünge", + "love": "Armas", + "nostalgia": "Nostalgia", + "oldBoot": "Vähevärviline", + "orangePeel": "Oranž film", + "pinhole": "Lukuauk", + "sinCity": "Julm", + "sunrise": "Päikesetõus", + "vintage": "Vana" + } + }, + "shortcuts": { + "title": "Keyboard Shortcuts", + "general": { + "action": "Vaikimisi tegevuse käivitamine", + "firstItem": "Esimesele liikumine", + "focusFilesPane": "Fookusesse failide paneel", + "focusFoldersPane": "Fookusesse kaustade paneel või asukohariba", + "focusNext": "Järgmise paneeli aktiveerimine", + "focusToolbar": "Fookusesse tööriistariba", + "lastItem": "Viimasele liikumine", + "listShortcuts": "Selle abidialoogi avamine", + "nextItem": "Järgmisele liikumine", + "previousItem": "Eelmisele liikumine", + "showContextMenu": "Kontekstimenüü avamine", + "title": "Üldine liides" + }, + "files": { + "addToSelectionAbove": "Lisa üleval olev fail valikusse või eemalda", + "addToSelectionBelow": "Lisa all olev fail valikusse või eemalda", + "addToSelectionLeft": "Lisa vasakul olev fail valikusse või eemalda", + "addToSelectionRight": "Lisa paremal olev fail valikusse või eemalda", + "delete": "Kustuta fail(id)", + "refresh": "Värskenda faile", + "rename": "Muuda faili nime", + "selectAll": "Vali kõik failid", + "upload": "Laadi fail(id) üles" + }, + "folders": { + "collapseOrParent": "Sulge / liigu ülemkausta", + "delete": "Kustuta kaust", + "expandOrSubfolder": "Laienda / liigu esimesse alamkausta", + "title": "Kaustade paneel" + }, + "keys": { + "ctrl": "Control", + "delete": "Delete", + "downArrow": "Allanool", + "escape": "Escape", + "leftArrow": "Vasakule nool", + "question": "Küsimärk", + "rightArrow": "Paremale nool", + "upArrow": "Ülesnool" + }, + "keysAbbreviations": { + "alt": "alt", + "ctrl": "ctrl", + "del": "del", + "end": "end", + "home": "home", + "shift": "shift" + } + } +} diff --git a/lib/ckfinder/lang/eu.json b/lib/ckfinder/lang/eu.json new file mode 100644 index 0000000..b054c67 --- /dev/null +++ b/lib/ckfinder/lang/eu.json @@ -0,0 +1,288 @@ +{ + "appTitle": "CKFinder", + "dir": "ltr", + "langCode": "eu", + "common": { + "abort": "Abortatu", + "cancel": "Utzi", + "choose": "Aukeratu", + "close": "Itxi", + "copy": "Kopiatu", + "delete": "Ezabatu", + "download": "Deskargatu", + "edit": "Editatu", + "maximize": "Maximize", + "messageTitle": "Informazioa", + "minimize": "Minimize", + "move": "Aldatu lekuz", + "newNameDialogTitle": "Izen berria", + "ok": "OK", + "pleaseWait": "Itxaron, mesedez.", + "rememberDecision": "Gogoratu nire erabakia", + "rename": "Aldatu izena", + "showMore": "Erakutsi gehiago", + "skip": "Saltatu", + "upload": "Kargatu", + "view": "Ikusi" + }, + "units": { + "dateFormat": "yyyy/m/d h:MM aa", + "dateAmPm": [ + "AM", + "PM" + ], + "kb": "{size} KB", + "mb": "{size} MB", + "gb": "{size} GB", + "sizePerSecond": "{size}/s", + "pixelShort": "px" + }, + "files": { + "autoRename": "Aldatu izena automatikoki", + "countMany": "{count} fitxategi", + "countOne": "Fitxategi bat", + "deleteConfirmation": "Ziur zaude {count} fitxategi ezabatu nahi dituzula?", + "fileDeleteConfirmation": "Ziur zaude \"{name}\" fitxategia ezabatu nahi duzula?", + "fileRenameExtensionConfirmation": "Ziur zaude fitxategi-luzapena aldatu nahi duzula? Fitxategia erabil ezinda gera daiteke.", + "fileRenameLabel": "Idatzi fitxategiaren izen berria: ", + "filesPaneTitle": "Fitxategiak panela", + "filesRefresh": "Fitxategiak freskatzen", + "filterPlaceholder": "Iragazi", + "gettingFileData": "Fitxategiaren datuak eskuratzen.", + "overwrite": "Gainidatzi", + "loadingFilesPane": { + "title": "Kargatzen...", + "text": "Fitxategiak kargatzen ari dira." + }, + "emptyFilesPane": { + "title": "Karpeta hutsik dago.", + "text": "Erabili Kargatu botoia edo arrastatu eta jaregin fitxategiak hemen." + }, + "filterFilesEmpty": { + "title": "Ez da ezer aurkitu.", + "text": "Mesedez saiatu beste bilaketa-irizpideak erabiltzen." + } + }, + "folders": { + "deleteConfirmation": "Ziur zaude \"{name}\" karpeta ezabatu nahi duzula?", + "destinationFolder": "Helburuko karpeta", + "newNameLabel": "Idatzi karpeta berriaren izena: ", + "newSubfolder": "New Subfolder", + "renameDialogTitle": "Aldatu izena karpetari", + "treeTitle": "Karpetak zuhaitza" + }, + "copy": { + "dropMenuItem": "Kopiatu hona", + "errorDialogTitle": "Kopiatu ezin diren fitxategiak:", + "manyFilesDialogTitle": "Kopiatu {count} fitxategi hona...", + "manyFilesWait": "{count} fitxategi kopiatzen.", + "oneFileDialogTitle": "Kopiatu fitxategia hona...", + "oneFileWait": "Fitxategia kopiatzen.", + "operationLabel": "Fitxategiak kopiatzen", + "operationSummary": "Kopiatutako fitxategi kopurua: {count}." + }, + "move": { + "dropMenuItem": "Aldatu lekuz hona", + "errorDialogTitle": "Lekuz aldatu ezin diren fitxategiak:", + "manyFilesDialogTitle": "Aldatu lekuz {count} fitxategi hona...", + "manyFilesWait": "{count} fitxategi lekuz aldatzen.", + "oneFileDialogTitle": "Aldatu lekuz fitxategia hona...", + "oneFileWait": "Fitxategia lekuz aldatzen.", + "operationLabel": "Fitxategiak lekuz aldatzen", + "operationSummary": "Lekuz aldatutako fitxategi kopurua: {count}." + }, + "upload": { + "addFiles": "Gehitu fitxategiak", + "bytesCountProgress": "({bytesUploaded} / {bytesTotal})", + "details": "Xehetasunak", + "filesCountProgress": "{filesUploaded} / {filesTotal}", + "progressLabel": "Kargatzen.", + "progressMessage": "Kargatzen...", + "selectFileLabel": "Hautatu fitxategia kargatzeko", + "selectFiles": "Hautatu fitxategiak kargatzeko", + "success": "Kargatzea amaituta!", + "summary": "Kargatutako fitxategiak: {count}" + }, + "settings": { + "display": "Bistaratu", + "displayDate": "Data", + "displayName": "Fitxategi-izena", + "displaySize": "Fitxategi-tamaina", + "sortAscending": "Ascending", + "sortBy": "Sort by", + "sortByOrder": "Order", + "sortDescending": "Descending", + "thumbnailSize": "Koadro txikiaren tamaina", + "title": "Ezarpenak", + "viewType": "View", + "viewTypeCompact": "Compact", + "viewTypeList": "List", + "viewTypeThumbnails": "Thumbnails" + }, + "errors": { + "codes": { + "10": "Komando baliogabea.", + "11": "Ez da baliabide mota zehaztu eskaeran.", + "12": "Eskatutako baliabide mota baliogabea da.", + "13": "Konektorearen konfigurazio-fitxategia baliogabea da.", + "14": "Konektorearen plugin baliogabea: {pluginName}.", + "102": "Fitxategi edo karpetaren izen baliogabea.", + "103": "Ezin izan da eskaera burutu autorizazio murrizketen ondorioz.", + "104": "Ezin izan da eskaera burutu fitxategi-sistemako baimen murrizketen ondorioz.", + "105": "Fitxategi-luzapen baliogabea.", + "109": "Eskaera baliogabea.", + "110": "Errore ezezaguna.", + "111": "Ezin izan da eskaera burutu lortzen den fitxategiaren tamainaren ondorioz.", + "115": "Izen bereko fitxategi edo karpeta bat existitzen da dagoeneko.", + "116": "Ez da karpeta aurkitu. Mesedez freskatu eta saiatu berriz.", + "117": "Ez da fitxategia aurkitu. Mesedez freskatu fitxategi-zerrenda eta saiatu berriz.", + "118": "Iturburu eta helburuko bideak berdinak dira.", + "201": "Izen bereko fitxategi bat existitzen da dagoeneko. Kargatutako fitxategia honela berrizendatu da: \"{name}\".", + "202": "Fitxategi baliogabea.", + "203": "Fitxategi baliogabea. Fitxategi-tamaina handiegia da.", + "204": "Kargatutako fitxategia hondatuta dago.", + "205": "Zerbitzarian ez dago fitxategiak kargatzeko aldi baterako karpetarik erabilgarri.", + "206": "Segurtasun-arrazoiak direla eta, karga bertan behera geratu da. Fitxategiak HTML bezalako datuak dauzka.", + "207": "Kargatutako fitxategia honela berrizendatu da: \"{name}\".", + "300": "Fitxategia(k) lekuz aldatzeak huts egin du.", + "301": "Fitxategia(k) kopiatzeak huts egin du.", + "302": "Fitxategia(k) ezabatzeak huts egin du.", + "500": "Segurtasun-arrazoiak direla eta, fitxategi-arakatzailea desgaituta dago. Jarri sistemaren administratzailearekin harremanetan eta egiaztatu CKFinder konfigurazio-fitxategia.", + "501": "Koadro txikien euskarria desgaituta dago." + }, + "deleteFilePermissions": "Removing files is not allowed in this folder.", + "fileInvalidCharacters": "Fitxategi-izenak ezin ditu ondorengo karaktereak eduki: {disallowedCharacters}", + "fileNameNotEmpty": "The file name cannot be empty.", + "folderInvalidCharacters": "Karpetaren izenak ezin ditu ondorengo karaktereak eduki: {disallowedCharacters}", + "incorrectExtension": "Fitxategi-luzapena ez da onartzen karpeta honetan.", + "missingFile": "Eskatutako fitxategia ez dago erabilgarri jada.", + "missingFolder": "Atzitu nahi duzun karpeta ez dago erabilgarri jada.", + "noUploadFolderSelected": "Mesedez hautatu karpeta kargatu aurretik.", + "operationCompleted": "Eragiketa erroreekin osatuta.", + "renameFilePermissions": "Renaming files is not allowed in this folder.", + "unknown": "Ezin izan da eskaera burutu. (Errorea {number})", + "unknownUploadError": "Errorea fitxategia bidaltzean.", + "uploadErrors": "Kargatzea erroreekin amaituta.", + "uploadPermissions": "Ez da onartzen fitxategia kargatzea." + }, + "chooseResizedImage": { + "title": "Aukeratu tamainaz aldatua", + "originalSize": "Jatorrizko tamaina", + "sizes": { + "custom": "Pertsonalizatua", + "large": "Handia", + "max": "Gehienezkoa", + "medium": "Ertaina", + "small": "Txikia" + } + }, + "editImage": { + "adjust": "Doitu", + "apply": "Aplikatu", + "confirmExit": "Ziur zaude itxi nahi duzula? Irudiari egindako gordeko gabeko aldaketak dauzkazu.", + "crop": "Moztu", + "downloadAction": "Jatorrizko irudia deskargatzen.", + "keepAspectRatio": "Mantendu aspektu-erlazioa", + "loading": "Irudia kargatzen", + "presets": "Aurrezarriak", + "reset": "Berrezarri", + "resize": "Aldatu tamaina", + "rotate": "Biratu", + "rotateAntiClockwise": "90° ezkerrera", + "rotateClockwise": "90° eskuinera", + "save": "Gorde", + "saveDialogFileExists": "Izen bereko fitxategi bat existitzen da karpetan jada.", + "saveDialogOverwrite": "Gainidatzi fitxategia", + "saveDialogSaveAs": "Gorde honela:", + "saveDialogTitle": "Gorde aldaketak", + "title": "Editatu irudia", + "transformationAction": "Eraldaketak aplikatzen.", + "uploadAction": "Editatutako irudia kargatzen.", + "filters": { + "brightness": "Distira", + "clip": "Clip-a", + "contrast": "Kontrastea", + "exposure": "Esposizioa", + "gamma": "Gamma", + "hue": "Ñabardura", + "noise": "Soinua", + "saturation": "Saturazioa", + "sepia": "Sepia", + "sharpen": "Araztu", + "stackBlur": "Lausotu", + "vibrance": "Bizitasuna" + }, + "preset": { + "clarity": "Argitasuna", + "concentrate": "Konzentratu", + "crossProcess": "Prozesu gurutzatua", + "glowingSun": "Eguzki distiratsua", + "grungy": "Grungy", + "hazyDays": "Egun lainotsuak", + "hemingway": "Hemingway", + "herMajesty": "Berorren maiestatea", + "jarques": "Jarques", + "lomo": "Lomo", + "love": "Maitasuna", + "nostalgia": "Nostalgia", + "oldBoot": "Bota zaharra", + "orangePeel": "Laranja-azala", + "pinhole": "Jostorratz-begia", + "sinCity": "Sin City", + "sunrise": "Egunsentia", + "vintage": "Vintage" + } + }, + "shortcuts": { + "title": "Laster-teklak", + "general": { + "action": "Exekutatu ekintza lehenetsia", + "firstItem": "Joan lehen elementura", + "focusFilesPane": "Fokuratu fitxategien panela", + "focusFoldersPane": "Fokuratu karpeten panela edo ogi apurrak", + "focusNext": "Fokuratu hurrengo panela", + "focusToolbar": "Fokuratu tresna-barra", + "lastItem": "Joan azken elementura", + "listShortcuts": "Ireki laguntzako elkarrizketa-koadro hau", + "nextItem": "Joan hurrengo elementura", + "previousItem": "Joan aurreko elementura", + "showContextMenu": "Ireki testuinguru-menua", + "title": "Interfaze orokorra" + }, + "files": { + "addToSelectionAbove": "Gehitu edo kendu hautapenaren gaineko fitxategiak", + "addToSelectionBelow": "Gehitu edo kendu hautapenaren azpiko fitxategiak", + "addToSelectionLeft": "Gehitu edo kendu hautapenaren ezkerreko fitxategia", + "addToSelectionRight": "Gehitu edo kendu hautapenaren eskuineko fitxategia", + "delete": "Ezabatu fitxategia(k)", + "refresh": "Freskatu fitxategiak", + "rename": "Aldatu izena fitxategiari", + "selectAll": "Hautatu fitxategi guztiak", + "upload": "Kargatu fitxategia(k)" + }, + "folders": { + "collapseOrParent": "Tolestu karpeta / Joan karpeta gurasora", + "delete": "Ezabatu karpeta", + "expandOrSubfolder": "Zabaldu karpeta / Joan lehen azpikarpetara", + "title": "Karpetak panela" + }, + "keys": { + "ctrl": "Kontrol", + "delete": "Ezabatu", + "downArrow": "Behera gezia", + "escape": "Ihes", + "leftArrow": "Ezker gezia", + "question": "Galdera-marka", + "rightArrow": "Eskuin-gezia", + "upArrow": "Gora gezia" + }, + "keysAbbreviations": { + "alt": "alt", + "ctrl": "ktrl", + "del": "ezab", + "end": "buka", + "home": "etxea", + "shift": "maius" + } + } +} diff --git a/lib/ckfinder/lang/fa.json b/lib/ckfinder/lang/fa.json new file mode 100644 index 0000000..faba360 --- /dev/null +++ b/lib/ckfinder/lang/fa.json @@ -0,0 +1,288 @@ +{ + "appTitle": "CKFinder", + "dir": "rtl", + "langCode": "fa", + "common": { + "abort": "توقف", + "cancel": "لغو", + "choose": "انتخاب", + "close": "بستن", + "copy": "رونوشت", + "delete": "حذف", + "download": "دانلود", + "edit": "ویرایش", + "maximize": "بیشینه", + "messageTitle": "اطلاعات", + "minimize": "کمینه", + "move": "انتقال", + "newNameDialogTitle": "نام جدید", + "ok": "لغو", + "pleaseWait": "لطفا صبر کنید.", + "rememberDecision": "انتخاب من را بیاد داشته باش", + "rename": "تغییر نام", + "showMore": "نمایش بیشتر", + "skip": "نادیده گرفتن", + "upload": "آپلود", + "view": "نمایش" + }, + "units": { + "dateFormat": "yyyy/mm/dd h:MM aa", + "dateAmPm": [ + "ق.ظ", + "ب.ظ" + ], + "kb": "{size}KB", + "mb": "{size}MB", + "gb": "{size}GB", + "sizePerSecond": "{size}/s", + "pixelShort": "px" + }, + "files": { + "autoRename": "تغییر نام خودکار", + "countMany": "{count} فایل", + "countOne": "یک فایل", + "deleteConfirmation": "آیا شما مطمئن هستید که می‌خواهید فایل‌های {count} را پاک کنید؟", + "fileDeleteConfirmation": "آیا اطمینان دارید که قصد حذف نمودن فایل \"{name}\" را دارید؟", + "fileRenameExtensionConfirmation": "آیا اطمینان دارید که قصد تغییر نام پسوند این فایل را دارید؟ ممکن است فایل غیر قابل استفاده شود", + "fileRenameLabel": "لطفا نام جدید فایل را درج کنید: ", + "filesPaneTitle": "چارچوب فایل‌ها", + "filesRefresh": "درحال تازه‌سازی فایل‌ها", + "filterPlaceholder": "صافی", + "gettingFileData": "درحال گرفتن اطلاعات فایل.", + "overwrite": "رونویسی", + "loadingFilesPane": { + "title": "درحال بارگیری...", + "text": "لطفا صبر کنید، فایل‌ها درحال بارگیری هستند." + }, + "emptyFilesPane": { + "title": "پوشه خالی است.", + "text": "از دکمه‌ی آپلود استفاده کنید یا فایل‌هایتان را بگیرید و اینجا بکشید." + }, + "filterFilesEmpty": { + "title": "چیزی پیدا نشد.", + "text": "لطفا با معیار دیگری تلاش به جستجو کنید." + } + }, + "folders": { + "deleteConfirmation": "آیا اطمینان دارید که قصد حذف کردن پوشه \"{name}\" را دارید؟", + "destinationFolder": "پوشه‌ی مقصد", + "newNameLabel": "لطفا نام پوشه جدید را وارد کنید: ", + "newSubfolder": "زیرپوشه جدید", + "renameDialogTitle": "تغییرنام پوشه", + "treeTitle": "درخت پوشه‌ها" + }, + "copy": { + "dropMenuItem": "کپی فایل به اینجا", + "errorDialogTitle": "فایل‌هایی که نمی‌توانند رونوشت‌گیری شوند:", + "manyFilesDialogTitle": "رونوشت {count} فایل به...", + "manyFilesWait": "درحال رونوشت‌گیری از {count} فایل.", + "oneFileDialogTitle": "رونوشت فایل به...", + "oneFileWait": "درحال رونوشت‌گیری از فایل،", + "operationLabel": "رونوشت‌گیری فایل‌ها", + "operationSummary": "تعداد فایل‌های رونوشت گرفته‌شده: {count}." + }, + "move": { + "dropMenuItem": "انتقال فایل به اینجا", + "errorDialogTitle": "فایل‌هایی که نمی‌توانند منتقل شوند:", + "manyFilesDialogTitle": "انتقال {count} فایل به...", + "manyFilesWait": "درحال انتقال {count} فایل.", + "oneFileDialogTitle": "انتقال فایل به...", + "oneFileWait": "درحال انتقال فایل.", + "operationLabel": "انتقال فایل‌ها", + "operationSummary": "تعداد فایل‌های منتقل شده: {count}." + }, + "upload": { + "addFiles": "افزودن فایلها", + "bytesCountProgress": "({bytesUploaded} از {bytesTotal})", + "details": "توضیحات", + "filesCountProgress": "{filesUploaded} از {filesTotal}", + "progressLabel": "درحال ارسال، لطفا صبر کنید...", + "progressMessage": "درحال آپلود...", + "selectFileLabel": "انتخاب فابل برای آپلود", + "selectFiles": "فایل‌ها را برای آپلود انتخاب کنید", + "success": "آپلود به پایان رسید!", + "summary": "فایل‌های آپلود شده: {count}" + }, + "settings": { + "display": "نمایش:", + "displayDate": "تاریخ", + "displayName": "نام فایل", + "displaySize": "اندازه فایل", + "sortAscending": "صعودی", + "sortBy": "مرتب‌سازی براساس", + "sortByOrder": "مرتب‌سازی", + "sortDescending": "نزولی", + "thumbnailSize": "اندازه تصویر بندانگشتی", + "title": "تنظیمات", + "viewType": "مشاهده", + "viewTypeCompact": "Compact", + "viewTypeList": "لیست", + "viewTypeThumbnails": "بند‌انگشتی‌ها" + }, + "errors": { + "codes": { + "10": "دستور نامعتبر.", + "11": "نوع منبع در درخواست تعریف نشده است.", + "12": "نوع منبع درخواست شده معتبر نیست.", + "13": "پیکربندی فایل اتصال نامعتبر است.", + "14": "افزونه‌ی اتصال نامعتبر: {pluginName}.", + "102": "نام فایل یا پوشه نامعتبر است.", + "103": "امکان کامل کردن این درخواست بخاطر محدودیت اختیارات وجود ندارد.", + "104": "امکان کامل کردن این درخواست بخاطر محدودیت دسترسی وجود ندارد.", + "105": "پسوند فایل نامعتبر است.", + "109": "درخواست نامعتبر است.", + "110": "خطای ناشناخته.", + "111": "انجام این عمل به دلیل اندازه‌ی فایل ممکن نیست.", + "115": "فایل یا پوشه ای با این نام وجود دارد", + "116": "پوشه یافت نشد. لطفا بروزرسانی کرده و مجددا تلاش کنید.", + "117": "فایل یافت نشد. لطفا فهرست فایلها را بروزرسانی کرده و مجددا تلاش کنید.", + "118": "منبع و مقصد مسیر یکی است.", + "201": "یک فایل با همان نام از قبل موجود است. فایل آپلود شده به \"{name}\" تغییر نام یافت.", + "202": "فایل نامعتبر", + "203": "فایل نامعتبر. اندازه فایل بیش از حد بزرگ است.", + "204": "فایل آپلود شده خراب است.", + "205": "هیچ پوشه موقتی برای آپلود فایل در سرور موجود نیست.", + "206": "آپلود به دلایل امنیتی متوقف شد. فایل محتوی اطلاعات HTML است.", + "207": "فایل آپلود شده به \"{name}\" تغییر نام یافت.", + "300": "انتقال فایل‌(ها) شکست خورد.", + "301": "کپی فایل‌(ها) شکست خورد.", + "302": "حذف فایل‌(ها) شکست خورد.", + "500": "مرورگر فایل به دلایل امنیتی غیر فعال است. لطفا با مدیر سامانه تماس بگیرید تا تنظیمات این بخش را بررسی نماید.", + "501": "پشتیبانی از تصاویر کوچک غیرفعال شده است" + }, + "deleteFilePermissions": "Removing files is not allowed in this folder.", + "fileInvalidCharacters": "نام فایل نباید شامل این کاراکترها باشد: {disallowedCharacters}", + "fileNameNotEmpty": "نام فایل نمی‌تواند خالی باشد.", + "folderInvalidCharacters": "نام پوشه نباید شامل این کاراکترها باشد: {disallowedCharacters}", + "incorrectExtension": "پسوند فایل برای این پوشه مجاز نیست.", + "missingFile": "فایل درخواست شده دیگر در دسترس نیست.", + "missingFolder": "پوشه‌ای که در حال تلاش برای دست‌یابی به آن هستید، دیگر در دسترس نیست.", + "noUploadFolderSelected": "لطفا پیش از آپلود، یک پوشه انتخاب کنید.", + "operationCompleted": "عملیات با خطاهایی به پایان رسید.", + "renameFilePermissions": "Renaming files is not allowed in this folder.", + "unknown": "امکان تکمیل درخواست فوق وجود ندارد (خطا: {number})", + "unknownUploadError": "خطا در ارسال", + "uploadErrors": "آپلود با خطاهایی به پایان رسید.", + "uploadPermissions": "اجازه ارسال فایل نداده شنده است" + }, + "chooseResizedImage": { + "title": "انتخاب مقیاس", + "originalSize": "اندازه‌ی اصلی", + "sizes": { + "custom": "سفارشی", + "large": "بزرگ", + "max": "بیشینه", + "medium": "متوسط", + "small": "کوچک" + } + }, + "editImage": { + "adjust": "تنظیم کردن", + "apply": "اعمال", + "confirmExit": "آیا شما مطمئن هستید که می‌خواهید این صفحه را ببندید؟ شما تغییرات ذخیره نشده‌ای بر تصویر دارید.", + "crop": "برش", + "downloadAction": "درحال دانلود تصویر اصلی.", + "keepAspectRatio": "حفظ نسبت ابعاد", + "loading": "درحال بارگیری تصویر", + "presets": "پیش تنظیم", + "reset": "بازنشانی", + "resize": "تغییر اندازه", + "rotate": "چرخش", + "rotateAntiClockwise": "90° به چپ", + "rotateClockwise": "90° به راست", + "save": "ذخیره", + "saveDialogFileExists": "فایلی با نام مشابه در این پوشه وجود دارد.", + "saveDialogOverwrite": "بازنویسی فایل", + "saveDialogSaveAs": "ذخیره به عنوان:", + "saveDialogTitle": "ذخیره تغییرات", + "title": "ویرایش تصویر", + "transformationAction": "درحال اعمال دگرگونی‌ها.", + "uploadAction": "درحال آپلود تصویر ویرایش‌شده.", + "filters": { + "brightness": "روشنایی", + "clip": "چیدن", + "contrast": "تضاد", + "exposure": "نوردهی", + "gamma": "گاما", + "hue": "رنگ", + "noise": "اختلال", + "saturation": "اشباع", + "sepia": "قهوه‌ای", + "sharpen": "واضح کردن", + "stackBlur": "تاری پشت", + "vibrance": "تحرک" + }, + "preset": { + "clarity": "Clarity", + "concentrate": "Concentrate", + "crossProcess": "Cross Process", + "glowingSun": "Glowing Sun", + "grungy": "Grungy", + "hazyDays": "Hazy Days", + "hemingway": "Hemingway", + "herMajesty": "Her Majesty", + "jarques": "Jarques", + "lomo": "Lomo", + "love": "Love", + "nostalgia": "Nostalgia", + "oldBoot": "Old Boot", + "orangePeel": "Orange Peel", + "pinhole": "Pinhole", + "sinCity": "Sin City", + "sunrise": "Sunrise", + "vintage": "Vintage" + } + }, + "shortcuts": { + "title": "میان‌برهای صفحه‌کلید", + "general": { + "action": "انجام کار پیش‌فرض", + "firstItem": "رفتن به نخستین مورد", + "focusFilesPane": "انتخاب چارچوپ فایل‌ها", + "focusFoldersPane": "انتخاب چارچوب پوشه‌ها یا نوار آدرس‌دهی", + "focusNext": "انتخاب چارچوپ بعدی", + "focusToolbar": "انتخاب نوار ابزار", + "lastItem": "رفتن به آخرین مورد", + "listShortcuts": "بازکردن پنجره‌ی راهنما", + "nextItem": "رفتن به مورد بعدی", + "previousItem": "رفتن به مورد قبلی", + "showContextMenu": "بازکردن منوی ابزار‌ها", + "title": "رابط عمومی" + }, + "files": { + "addToSelectionAbove": "اضافه یا حذف‌کردن فایل‌های بالا از انتخاب", + "addToSelectionBelow": "اضافه یا حذف‌کردن فایل‌های پایین از انتخاب", + "addToSelectionLeft": "اضافه یا حذف‌کردن فایل‌های سمت چپ از انتخاب", + "addToSelectionRight": "اضافه یا حذف‌کردن فایل‌های سمت راست از انتخاب", + "delete": "حذف فایل(ها)", + "refresh": "تازه‌سازی فایل‌ها", + "rename": "تغییرنام فایل", + "selectAll": "انتخاب همه‌ی فایل‌ها", + "upload": "آپلود فایل(ها)" + }, + "folders": { + "collapseOrParent": "بستن پوشه / رفتن به پوشه‌ی والد", + "delete": "حذف پوشه", + "expandOrSubfolder": "بازکردن پوشه / رفتن به اولین زیرپوشه", + "title": "چارچوب پوشه‌ها" + }, + "keys": { + "ctrl": "کنترل", + "delete": "حذف", + "downArrow": "جهت پایین", + "escape": "در رفتن", + "leftArrow": "جهت چپ", + "question": "علامت سوال", + "rightArrow": "جهت راست", + "upArrow": "جهت بالا" + }, + "keysAbbreviations": { + "alt": "آلت", + "ctrl": "کنترل", + "del": "حذف", + "end": "پایان", + "home": "خانه", + "shift": "شیفت" + } + } +} diff --git a/lib/ckfinder/lang/fi.json b/lib/ckfinder/lang/fi.json new file mode 100644 index 0000000..39edcce --- /dev/null +++ b/lib/ckfinder/lang/fi.json @@ -0,0 +1,288 @@ +{ + "appTitle": "CKFinder", + "dir": "ltr", + "langCode": "fi", + "common": { + "abort": "Abort", + "cancel": "Peru", + "choose": "Choose", + "close": "Sulje", + "copy": "Copy", + "delete": "Poista", + "download": "Lataa palvelimelta", + "edit": "Muokkaa", + "maximize": "Suurenna", + "messageTitle": "Ilmoitus", + "minimize": "Pienennä", + "move": "Move", + "newNameDialogTitle": "Uusi nimi", + "ok": "OK", + "pleaseWait": "Please wait.", + "rememberDecision": "Muista valintani", + "rename": "Uudelleennimeä ", + "showMore": "Show more", + "skip": "Ohita", + "upload": "Lataa palvelimelle", + "view": "Näytä" + }, + "units": { + "dateFormat": "yyyy-mm-dd HH:MM", + "dateAmPm": [ + "AM", + "PM" + ], + "kb": "{size} kt", + "mb": "{size} Mt", + "gb": "{size} Gt", + "sizePerSecond": "{size}/s", + "pixelShort": "px" + }, + "files": { + "autoRename": "Nimeä uudelleen automaattisesti", + "countMany": "{count} tiedostoa", + "countOne": "1 tiedosto", + "deleteConfirmation": "Are you sure you want to delete {count} files?", + "fileDeleteConfirmation": "Haluatko varmasti poistaa tiedoston \"{name}\"?", + "fileRenameExtensionConfirmation": "Haluatko varmasti muuttaa tiedostotarkennetta? Tiedosto voi muuttua käyttökelvottomaksi.", + "fileRenameLabel": "Kirjoita uusi tiedostonimi: ", + "filesPaneTitle": "Files pane", + "filesRefresh": "Refreshing files", + "filterPlaceholder": "Filter", + "gettingFileData": "Getting file data.", + "overwrite": "Ylikirjoita", + "loadingFilesPane": { + "title": "Loading...", + "text": "The files are being loaded." + }, + "emptyFilesPane": { + "title": "The folder is empty.", + "text": "Use the Upload button or drag and drop your files here." + }, + "filterFilesEmpty": { + "title": "Nothing found.", + "text": "Please try using different search criteria." + } + }, + "folders": { + "deleteConfirmation": "Haluatko varmasti poistaa kansion \"{name}\"?", + "destinationFolder": "Destination Folder", + "newNameLabel": "Kirjoita uuden kansion nimi: ", + "newSubfolder": "Uusi alikansio", + "renameDialogTitle": "Rename Folder", + "treeTitle": "Folders tree" + }, + "copy": { + "dropMenuItem": "Kopioi tähän", + "errorDialogTitle": "Files that cannot be copied:", + "manyFilesDialogTitle": "Copy {count} Files To...", + "manyFilesWait": "Copying {count} files.", + "oneFileDialogTitle": "Copy File To...", + "oneFileWait": "Copying file.", + "operationLabel": "Copying Files", + "operationSummary": "Number of files copied: {count}." + }, + "move": { + "dropMenuItem": "Siirrä tähän", + "errorDialogTitle": "Files that cannot be moved:", + "manyFilesDialogTitle": "Move {count} Files To...", + "manyFilesWait": "Moving {count} files.", + "oneFileDialogTitle": "Move File To...", + "oneFileWait": "Moving file.", + "operationLabel": "Moving Files", + "operationSummary": "Number of files moved: {count}." + }, + "upload": { + "addFiles": "Lisää tiedostoja", + "bytesCountProgress": "({bytesUploaded} of {bytesTotal})", + "details": "Details", + "filesCountProgress": "{filesUploaded} of {filesTotal}", + "progressLabel": "Lataaminen palvelimelle käynnissä...", + "progressMessage": "Uploading...", + "selectFileLabel": "Valitse ladattava tiedosto", + "selectFiles": "Select files to upload", + "success": "Upload finished!", + "summary": "Uploaded files: {count}" + }, + "settings": { + "display": "Näytä:", + "displayDate": "Päivämäärä", + "displayName": "Tiedostonimi", + "displaySize": "Tiedostokoko", + "sortAscending": "Ascending", + "sortBy": "Sort by", + "sortByOrder": "Order", + "sortDescending": "Descending", + "thumbnailSize": "Thumbnail Size", + "title": "Asetukset", + "viewType": "View", + "viewTypeCompact": "Compact", + "viewTypeList": "List", + "viewTypeThumbnails": "Thumbnails" + }, + "errors": { + "codes": { + "10": "Virheellinen komento.", + "11": "Pyynnön resurssityyppi on määrittelemättä.", + "12": "Pyynnön resurssityyppi on virheellinen.", + "13": "The connector configuration file is invalid.", + "14": "Invalid connector plugin: {pluginName}.", + "102": "Virheellinen tiedosto- tai kansionimi.", + "103": "Oikeutesi eivät riitä pyynnön suorittamiseen.", + "104": "Tiedosto-oikeudet eivät riitä pyynnön suorittamiseen.", + "105": "Virheellinen tiedostotarkenne.", + "109": "Virheellinen pyyntö.", + "110": "Tuntematon virhe.", + "111": "It was not possible to complete the request due to resulting file size.", + "115": "Samanniminen tiedosto tai kansio on jo olemassa.", + "116": "Kansiota ei löydy. Yritä uudelleen kansiopäivityksen jälkeen.", + "117": "Tiedostoa ei löydy. Yritä uudelleen kansiopäivityksen jälkeen.", + "118": "Lähde- ja kohdekansio on sama!", + "201": "Samanniminen tiedosto on jo olemassa. Palvelimelle ladattu tiedosto on nimetty: \"{name}\".", + "202": "Virheellinen tiedosto.", + "203": "Virheellinen tiedosto. Tiedostokoko on liian suuri.", + "204": "Palvelimelle ladattu tiedosto on vioittunut.", + "205": "Väliaikaishakemistoa ei ole määritetty palvelimelle lataamista varten.", + "206": "Palvelimelle lataaminen on peruttu turvallisuussyistä. Tiedosto sisältää HTML-tyylistä dataa.", + "207": "Palvelimelle ladattu tiedosto on nimetty: \"{name}\".", + "300": "Tiedostosiirto epäonnistui.", + "301": "Tiedostokopiointi epäonnistui.", + "302": "Deleting file(s) failed.", + "500": "Tiedostoselain on kytketty käytöstä turvallisuussyistä. Pyydä pääkäyttäjää tarkastamaan CKFinderin asetustiedosto.", + "501": "Esikatselukuvien tuki on kytketty toiminnasta." + }, + "deleteFilePermissions": "Removing files is not allowed in this folder.", + "fileInvalidCharacters": "Tiedostonimi ei voi sisältää seuraavia merkkejä: {disallowedCharacters}", + "fileNameNotEmpty": "The file name cannot be empty.", + "folderInvalidCharacters": "Kansionimi ei voi sisältää seuraavia merkkejä: {disallowedCharacters}", + "incorrectExtension": "Tiedostotarkenne ei ole sallittu valitussa kansiossa.", + "missingFile": "The requested file is no longer available.", + "missingFolder": "The folder you are trying to reach is no longer available.", + "noUploadFolderSelected": "Valitse kansio ennen palvelimelle lataamista.", + "operationCompleted": "Operation completed with errors.", + "renameFilePermissions": "Renaming files is not allowed in this folder.", + "unknown": "Pyyntöä ei voitu suorittaa. (Virhe {number})", + "unknownUploadError": "Tiedoston siirrossa tapahtui virhe.", + "uploadErrors": "Upload finished with errors.", + "uploadPermissions": "Tiedoston lataaminen palvelimelle evätty." + }, + "chooseResizedImage": { + "title": "Choose Resized", + "originalSize": "Original Size", + "sizes": { + "custom": "Custom", + "large": "Large", + "max": "Max", + "medium": "Medium", + "small": "Small" + } + }, + "editImage": { + "adjust": "Adjust", + "apply": "Apply", + "confirmExit": "Are you sure you want to close? You have unsaved changes to the image.", + "crop": "Crop", + "downloadAction": "Downloading original image.", + "keepAspectRatio": "Keep Aspect Ratio", + "loading": "Loading image", + "presets": "Presets", + "reset": "Reset", + "resize": "Resize", + "rotate": "Rotate", + "rotateAntiClockwise": "90° Left", + "rotateClockwise": "90° Right", + "save": "Save", + "saveDialogFileExists": "File with the same name already exists in folder.", + "saveDialogOverwrite": "Overwrite File", + "saveDialogSaveAs": "Save as:", + "saveDialogTitle": "Save Changes", + "title": "Edit Image", + "transformationAction": "Applying transformations.", + "uploadAction": "Uploading edited image.", + "filters": { + "brightness": "Brightness", + "clip": "Clip", + "contrast": "Contrast", + "exposure": "Exposure", + "gamma": "Gamma", + "hue": "Hue", + "noise": "Noise", + "saturation": "Saturation", + "sepia": "Sepia", + "sharpen": "Sharpen", + "stackBlur": "Blur", + "vibrance": "Vibrance" + }, + "preset": { + "clarity": "Clarity", + "concentrate": "Concentrate", + "crossProcess": "Cross Process", + "glowingSun": "Glowing Sun", + "grungy": "Grungy", + "hazyDays": "Hazy Days", + "hemingway": "Hemingway", + "herMajesty": "Her Majesty", + "jarques": "Jarques", + "lomo": "Lomo", + "love": "Love", + "nostalgia": "Nostalgia", + "oldBoot": "Old Boot", + "orangePeel": "Orange Peel", + "pinhole": "Pinhole", + "sinCity": "Sin City", + "sunrise": "Sunrise", + "vintage": "Vintage" + } + }, + "shortcuts": { + "title": "Keyboard Shortcuts", + "general": { + "action": "Execute default action", + "firstItem": "Go to first item", + "focusFilesPane": "Focus files pane", + "focusFoldersPane": "Focus folders pane or breadcrumbs", + "focusNext": "Focus next pane", + "focusToolbar": "Focus toolbar", + "lastItem": "Go to last item", + "listShortcuts": "Open this help dialog", + "nextItem": "Go to next item", + "previousItem": "Go to previous item", + "showContextMenu": "Open context menu", + "title": "General Interface" + }, + "files": { + "addToSelectionAbove": "Add or remove files above to selection", + "addToSelectionBelow": "Add or remove files below to selection", + "addToSelectionLeft": "Add or remove file on the left to selection", + "addToSelectionRight": "Add or remove file on the right to selection", + "delete": "Delete file(s)", + "refresh": "Refresh files", + "rename": "Rename file", + "selectAll": "Select all files", + "upload": "Upload file(s)" + }, + "folders": { + "collapseOrParent": "Collapse folder / Go to parent folder", + "delete": "Delete folder", + "expandOrSubfolder": "Expand folder / Go to first subfolder", + "title": "Folders Pane" + }, + "keys": { + "ctrl": "Control", + "delete": "Delete", + "downArrow": "Down arrow", + "escape": "Escape", + "leftArrow": "Left arrow", + "question": "Question mark", + "rightArrow": "Right arrow", + "upArrow": "Up arrow" + }, + "keysAbbreviations": { + "alt": "alt", + "ctrl": "ctrl", + "del": "del", + "end": "end", + "home": "home", + "shift": "shift" + } + } +} diff --git a/lib/ckfinder/lang/fr.json b/lib/ckfinder/lang/fr.json new file mode 100644 index 0000000..c24cd9f --- /dev/null +++ b/lib/ckfinder/lang/fr.json @@ -0,0 +1,288 @@ +{ + "appTitle": "CKFinder", + "dir": "ltr", + "langCode": "fr", + "common": { + "abort": "Abandonner", + "cancel": "Annuler", + "choose": "Choisir", + "close": "Fermer", + "copy": "Copier", + "delete": "Effacer", + "download": "Télécharger", + "edit": "Edition", + "maximize": "Agrandir", + "messageTitle": "Information", + "minimize": "Minimiser", + "move": "Déplacer", + "newNameDialogTitle": "Nouveau fichier", + "ok": "OK", + "pleaseWait": "Patientez.", + "rememberDecision": "Se rappeler de la décision", + "rename": "Renommer", + "showMore": "Montrer plus", + "skip": "Passer", + "upload": "Envoyer", + "view": "Voir" + }, + "units": { + "dateFormat": "dd/mm/yyyy H:MM", + "dateAmPm": [ + "AM", + "PM" + ], + "kb": "{size} Ko", + "mb": "{size} Mo", + "gb": "{size} Go", + "sizePerSecond": "{size}/s", + "pixelShort": "px" + }, + "files": { + "autoRename": "Re-nommage automatique", + "countMany": "{count} fichiers", + "countOne": "1 fichier", + "deleteConfirmation": "Êtes-vous sûr de vouloir supprimer {count} fichiers ?", + "fileDeleteConfirmation": "Êtes-vous sûr de vouloir effacer le fichier \"{name}\"?", + "fileRenameExtensionConfirmation": "Êtes-vous sûr de vouloir changer l'extension de ce fichier? Le fichier pourrait devenir inutilisable.", + "fileRenameLabel": "Entrez le nouveau nom du fichier: ", + "filesPaneTitle": "Fenêtre des fichiers", + "filesRefresh": "Actualisation des fichiers", + "filterPlaceholder": "Filtre", + "gettingFileData": "Données de fichier en cours d'acquisition.", + "overwrite": "Ré-écrire", + "loadingFilesPane": { + "title": "Chargement en cours...", + "text": "Les fichiers sont en cours de chargement." + }, + "emptyFilesPane": { + "title": "Le dossier est vide.", + "text": "Utiliser le bouton Envoyer ou glisser-déplacer vos fichiers ici." + }, + "filterFilesEmpty": { + "title": "Rien trouvé.", + "text": "Veuillez utiliser d'autres critères de recherche." + } + }, + "folders": { + "deleteConfirmation": "Êtes-vous sûr de vouloir effacer le dossier \"{name}\"?", + "destinationFolder": "Dossier de destination", + "newNameLabel": "Entrez le nom du nouveau dossier: ", + "newSubfolder": "Nouveau sous-dossier", + "renameDialogTitle": "Renommer le dossier", + "treeTitle": "Arborescence des dossiers" + }, + "copy": { + "dropMenuItem": "Copier ici", + "errorDialogTitle": "Fichiers qui ne peuvent pas être copiés:", + "manyFilesDialogTitle": "Copier {count} fichiers dans...", + "manyFilesWait": "{count} fichiers en cours de copie.", + "oneFileDialogTitle": "Copier le fichier dans...", + "oneFileWait": "Fichier en cours de copie.", + "operationLabel": "Fichiers en cours de copie", + "operationSummary": "Nombre de fichiers copiés: {count}." + }, + "move": { + "dropMenuItem": "Déplacer ici", + "errorDialogTitle": "Fichiers qui ne peuvent pas être déplacés:", + "manyFilesDialogTitle": "Déplacer {count} fichiers vers...", + "manyFilesWait": "{count} fichiers en cours de déplacement.", + "oneFileDialogTitle": "Déplacer le fichier vers...", + "oneFileWait": "Fichier en cours de déplacement.", + "operationLabel": "Fichiers en cours de déplacement", + "operationSummary": "Nombre de fichiers déplacés: {count}." + }, + "upload": { + "addFiles": "Ajouter des fichiers", + "bytesCountProgress": "({bytesUploaded} sur {bytesTotal})", + "details": "Détails", + "filesCountProgress": "{filesUploaded} sur {filesTotal}", + "progressLabel": "Envoi en cours.", + "progressMessage": "Envoi en cours...", + "selectFileLabel": "Sélectionner le fichier à télécharger", + "selectFiles": "Selectionner les fichiers à envoyer", + "success": "Envoi terminé!", + "summary": "Fichiers envoyés: {count}" + }, + "settings": { + "display": "Affichage:", + "displayDate": "Date", + "displayName": "Nom du fichier", + "displaySize": "Taille du fichier", + "sortAscending": "Croissant", + "sortBy": "Trier par", + "sortByOrder": "Ordre", + "sortDescending": "Décroissant", + "thumbnailSize": "Taille des miniatures", + "title": "Configuration", + "viewType": "Vue", + "viewTypeCompact": "Compact", + "viewTypeList": "Liste", + "viewTypeThumbnails": "Miniatures" + }, + "errors": { + "codes": { + "10": "Commande invalide.", + "11": "Le type de ressource n'a pas été spécifié dans la commande.", + "12": "Le type de ressource n'est pas valide.", + "13": "Le fichier de configuration du connecteur n'est pas valide.", + "14": "Connecteur plugin invalide: {pluginName}.", + "102": "Nom de fichier ou de dossier invalide.", + "103": "La demande n'a pas abouti: problème d'autorisations.", + "104": "La demande n'a pas abouti: problème de restrictions de permissions.", + "105": "Extension de fichier invalide.", + "109": "Demande invalide.", + "110": "Erreur inconnue.", + "111": "Il n'a pas été possible d'exécuter la requête à cause de la taille du fichier résultant.", + "115": "Un fichier ou un dossier avec ce nom existe déjà.", + "116": "Ce dossier n'existe pas. Veuillez rafraîchir la page et réessayer.", + "117": "Ce fichier n'existe pas. Veuillez rafraîchir la page et réessayer.", + "118": "Les chemins vers la source et la cible sont les mêmes.", + "201": "Un fichier avec ce nom existe déjà. Le fichier téléversé a été renommé en \"{name}\".", + "202": "Fichier invalide.", + "203": "Fichier invalide. La taille est trop grande.", + "204": "Le fichier téléversé est corrompu.", + "205": "Aucun dossier temporaire n'est disponible sur le serveur.", + "206": "Envoi interrompu pour raisons de sécurité. Le fichier contient des données de type HTML.", + "207": "Le fichier téléchargé a été renommé \"{name}\".", + "300": "Le déplacement des fichiers a échoué.", + "301": "La copie des fichiers a échoué.", + "302": "L'effacement des fichiers à échoué.", + "500": "L'interface de gestion des fichiers est désactivé. Contactez votre administrateur et vérifier le fichier de configuration de CKFinder.", + "501": "La fonction \"miniatures\" est désactivée." + }, + "deleteFilePermissions": "Removing files is not allowed in this folder.", + "fileInvalidCharacters": "Le nom du fichier ne peut pas contenir les charactères suivants: {disallowedCharacters}", + "fileNameNotEmpty": "Le nom de fichier ne peut pas être vide.", + "folderInvalidCharacters": "Le nom du dossier ne peut pas contenir les charactères suivants: {disallowedCharacters}", + "incorrectExtension": "L'extension du fichier n'est pas autorisée dans ce dossier.", + "missingFile": "Le fichier demandé n'est plus disponible.", + "missingFolder": "Le dossier auquel vous tentez d'accéder n'est plus disponible.", + "noUploadFolderSelected": "Merci de sélectionner un répertoire avant l'envoi.", + "operationCompleted": "Operation terminée avec des erreurs.", + "renameFilePermissions": "Renaming files is not allowed in this folder.", + "unknown": "La demande n'a pas abouti. (Erreur {number})", + "unknownUploadError": "Erreur pendant l'envoi du fichier.", + "uploadErrors": "Envoi terminé avec des erreurs.", + "uploadPermissions": "L'envoi de fichier n'est pas autorisé." + }, + "chooseResizedImage": { + "title": "Choisir l'échelle", + "originalSize": "Taille d'origine", + "sizes": { + "custom": "Personnalisé", + "large": "Grand", + "max": "Max", + "medium": "Moyen", + "small": "Petit" + } + }, + "editImage": { + "adjust": "Ajuster", + "apply": "Appliquer", + "confirmExit": "Etes-vous sûr que vous voulez fermer? Vous avez des modifications non enregistrées à l'image.", + "crop": "Rogner", + "downloadAction": "Téléchargement de l'image originale.", + "keepAspectRatio": "Consever les proportions", + "loading": "Chargement de l'image", + "presets": "Préconfigurer", + "reset": "Reset", + "resize": "Redimensionner", + "rotate": "Rotation", + "rotateAntiClockwise": "90° vers la gauche", + "rotateClockwise": "90° vers la droite", + "save": "Enregistrer", + "saveDialogFileExists": "Un fichier de même nom existe déjà dans le dossier.", + "saveDialogOverwrite": "Ecraser le fichier", + "saveDialogSaveAs": "Enregistrer comme:", + "saveDialogTitle": "Enregistrer les modifications", + "title": "Editer l'image", + "transformationAction": "Application des transformations.", + "uploadAction": "Envoi de l'image éditée.", + "filters": { + "brightness": "Brillance", + "clip": "Clip", + "contrast": "Contraste", + "exposure": "Exposition", + "gamma": "Gamma", + "hue": "Nuance", + "noise": "Bruit", + "saturation": "Saturation", + "sepia": "Sépia", + "sharpen": "Accentuation", + "stackBlur": "Flou", + "vibrance": "Vibrance" + }, + "preset": { + "clarity": "Clareté", + "concentrate": "Concentré", + "crossProcess": "Traitement croisé", + "glowingSun": "Soleil ardent", + "grungy": "Crasseux", + "hazyDays": "Jours de brume", + "hemingway": "Hemingway", + "herMajesty": "Sa Majesté", + "jarques": "Jarques", + "lomo": "Lomo", + "love": "Amour", + "nostalgia": "Nostalgie", + "oldBoot": "Vieille botte", + "orangePeel": "Peau d'orange", + "pinhole": "Sténopé", + "sinCity": "Ville du péché", + "sunrise": "Lever du soleil", + "vintage": "Vendanges" + } + }, + "shortcuts": { + "title": "Raccourcis clavier", + "general": { + "action": "Exécuter l'action par défaut", + "firstItem": "Aller au premier élément", + "focusFilesPane": "Se concentrer sur la fenêtre des fichiers", + "focusFoldersPane": "Se concentrer sur la fenêtre des dossiers ou le fil dAriane", + "focusNext": "Se concentrer sur la fenêtre suivante", + "focusToolbar": "Se concentrer sur la barre d'outils", + "lastItem": "Aller au dernier élément", + "listShortcuts": "Ouvrez cette boîte de dialogue d'aide", + "nextItem": "Aller à l'élément suivant", + "previousItem": "Aller à l'élément précédent", + "showContextMenu": "Ouvrir le menu contextuel", + "title": "Interface générale" + }, + "files": { + "addToSelectionAbove": "Ajouter à la sélection ou supprimer de celle ci les fichiers du haut", + "addToSelectionBelow": "Ajouter à la sélection ou supprimer de celle ci les fichiers du bas", + "addToSelectionLeft": "Ajouter à la sélection ou supprimer de celle ci les fichiers sur la gauche", + "addToSelectionRight": "Ajouter à la sélection ou supprimer de celle ci les fichiers sur la droite", + "delete": "Supprimer fichier(s)", + "refresh": "Actualiser les fichiers", + "rename": "Renommer le fichier", + "selectAll": "Sélectionnez tous les fichiers", + "upload": "Envoyer fichier(s)" + }, + "folders": { + "collapseOrParent": "Replier le dossier / Aller au dossier parent", + "delete": "Supprimer le dossier", + "expandOrSubfolder": "Déplier le dossier / Aller au premier sous-dossier", + "title": "Fenêtre des dossiers" + }, + "keys": { + "ctrl": "Contrôle", + "delete": "Supprimer", + "downArrow": "Flèche basse", + "escape": "Échap", + "leftArrow": "Flèche gauche", + "question": "Point d'interrogation", + "rightArrow": "Flèche droite", + "upArrow": "Flèche haute" + }, + "keysAbbreviations": { + "alt": "alt", + "ctrl": "ctrl", + "del": "suppr", + "end": "fin", + "home": "début", + "shift": "maj" + } + } +} diff --git a/lib/ckfinder/lang/gu.json b/lib/ckfinder/lang/gu.json new file mode 100644 index 0000000..f0b15f1 --- /dev/null +++ b/lib/ckfinder/lang/gu.json @@ -0,0 +1,288 @@ +{ + "appTitle": "CKFinder", + "dir": "ltr", + "langCode": "gu", + "common": { + "abort": "Abort", + "cancel": "રદ કરવું", + "choose": "Choose", + "close": "બંધ", + "copy": "Copy", + "delete": "કાઢી નાખવું", + "download": "ડાઊનલોડ", + "edit": "એડીટ", + "maximize": "મેક્ષિમાઈઝ", + "messageTitle": "માહિતી", + "minimize": "મિનીમાઈઝ", + "move": "Move", + "newNameDialogTitle": "નવું નામ", + "ok": "ઓકે", + "pleaseWait": "Please wait.", + "rememberDecision": "મારો વિકલ્પ યાદ રાખો", + "rename": "નવું નામ", + "showMore": "Show more", + "skip": "સ્કીપ", + "upload": "અપલોડ", + "view": "વ્યુ" + }, + "units": { + "dateFormat": "m/d/yyyy h:MM aa", + "dateAmPm": [ + "AM", + "PM" + ], + "kb": "{size} KB", + "mb": "{size} MB", + "gb": "{size} GB", + "sizePerSecond": "{size}/s", + "pixelShort": "px" + }, + "files": { + "autoRename": "આટો-નવું નામ", + "countMany": "{count} ફાઈલો", + "countOne": "1 ફાઈલ", + "deleteConfirmation": "Are you sure you want to delete {count} files?", + "fileDeleteConfirmation": "શું તમારે \"{name}\" ફાઈલ ડિલીટ કરવી છે?", + "fileRenameExtensionConfirmation": "છું તમારે ફાઈલ એક્ષ્તેન્શન્ બદલવું છે? તે ફાઈલ પછી નહી વપરાય.", + "fileRenameLabel": "નવી ફાઈલ નું નામ આપો: ", + "filesPaneTitle": "Files pane", + "filesRefresh": "Refreshing files", + "filterPlaceholder": "Filter", + "gettingFileData": "Getting file data.", + "overwrite": "ફાઈલ બદલવી છે", + "loadingFilesPane": { + "title": "Loading...", + "text": "The files are being loaded." + }, + "emptyFilesPane": { + "title": "The folder is empty.", + "text": "Use the Upload button or drag and drop your files here." + }, + "filterFilesEmpty": { + "title": "Nothing found.", + "text": "Please try using different search criteria." + } + }, + "folders": { + "deleteConfirmation": "શું તમારે \"{name}\" ફોલ્ડર ડિલીટ કરવું છે?", + "destinationFolder": "Destination Folder", + "newNameLabel": "નવું ફોલ્ડર નું નામ આપો: ", + "newSubfolder": "નવું સ્બફોલડર", + "renameDialogTitle": "Rename Folder", + "treeTitle": "Folders tree" + }, + "copy": { + "dropMenuItem": "અહિયાં ફાઈલ કોપી કરો", + "errorDialogTitle": "Files that cannot be copied:", + "manyFilesDialogTitle": "Copy {count} Files To...", + "manyFilesWait": "Copying {count} files.", + "oneFileDialogTitle": "Copy File To...", + "oneFileWait": "Copying file.", + "operationLabel": "Copying Files", + "operationSummary": "Number of files copied: {count}." + }, + "move": { + "dropMenuItem": "અહિયાં ફાઈલ મુવ કરો", + "errorDialogTitle": "Files that cannot be moved:", + "manyFilesDialogTitle": "Move {count} Files To...", + "manyFilesWait": "Moving {count} files.", + "oneFileDialogTitle": "Move File To...", + "oneFileWait": "Moving file.", + "operationLabel": "Moving Files", + "operationSummary": "Number of files moved: {count}." + }, + "upload": { + "addFiles": "ફાઈલ ઉમેરો", + "bytesCountProgress": "({bytesUploaded} of {bytesTotal})", + "details": "Details", + "filesCountProgress": "{filesUploaded} of {filesTotal}", + "progressLabel": "અપલોડ થાય છે.", + "progressMessage": "Uploading...", + "selectFileLabel": "અપલોડ માટે ફાઈલ પસંદ કરો", + "selectFiles": "Select files to upload", + "success": "Upload finished!", + "summary": "Uploaded files: {count}" + }, + "settings": { + "display": "ડિસ્પ્લે:", + "displayDate": "તારીખ", + "displayName": "ફાઈલનું નામ", + "displaySize": "ફાઈલ સાઈઝ", + "sortAscending": "Ascending", + "sortBy": "Sort by", + "sortByOrder": "Order", + "sortDescending": "Descending", + "thumbnailSize": "Thumbnail Size", + "title": "સેટીંગ્સ", + "viewType": "View", + "viewTypeCompact": "Compact", + "viewTypeList": "List", + "viewTypeThumbnails": "Thumbnails" + }, + "errors": { + "codes": { + "10": "કમાંડ માન્ય નથી.", + "11": "તમારી રીક્વેસ્ટ માન્ય નથી.", + "12": "તમારી રીક્વેસ્ટ રિસોર્સ માન્ય નથી.", + "13": "The connector configuration file is invalid.", + "14": "Invalid connector plugin: {pluginName}.", + "102": "ફાઈલ અથવા ફોલ્ડરનું નામ માન્ય નથી.", + "103": "ઓથોરીટી ન હોવાને કારણે, તમારી રીક્વેસ્ટ માન્ય નથી..", + "104": "સિસ્ટમ પરમીસન ન હોવાને કારણે, તમારી રીક્વેસ્ટ માન્ય નથી.", + "105": "ફાઈલ એક્ષટેનસન માન્ય નથી.", + "109": "ઇનવેલીડ રીક્વેસ્ટ.", + "110": "અન્નોન એરર.", + "111": "It was not possible to complete the request due to resulting file size.", + "115": "એજ નામ વાળું ફાઈલ અથવા ફોલ્ડર છે.", + "116": "ફોલ્ડર નથી. રીફ્રેશ દબાવી ફરી પ્રયત્ન કરો.", + "117": "ફાઈલ નથી. રીફ્રેશ દબાવી ફરી પ્રયત્ન કરો..", + "118": "સોર્સ અને ટાર્ગેટ ના પાથ સરખા નથી.", + "201": "એજ નામ વાળી ફાઈલ છે. અપલોડ કરેલી નવી ફાઈલનું નામ \"{name}\".", + "202": "ફાઈલ માન્ય નથી.", + "203": "ફાઈલ માન્ય નથી. ફાઈલની સાઈઝ ઘણી મોટી છે.", + "204": "અપલોડ કરેલી ફાઈલ કરપ્ટ છે.", + "205": "સર્વર પર અપલોડ કરવા માટે ટેમ્પરરી ફોલ્ડર નથી.", + "206": "સિક્યોરીટીના કારણે અપલોડ કેન્સલ કરેલ છે. ફાઈલમાં HTML જેવો ડેટા છે.", + "207": "અપલોડ ફાઈલનું નવું નામ \"{name}\".", + "300": "ફાઈલ મુવ શક્ય નથી.", + "301": "ફાઈલ કોપી શક્ય નથી.", + "302": "Deleting file(s) failed.", + "500": "સિક્યોરીટીના કારણે ફાઈલ બ્રાઉઝર બંધ કરેલ છે. તમારા સિક્યોરીટી એડ્મીનીસ્ટેટરની મદદથી CKFinder કોન્ફીગ્યુંરેષન ફાઈલ તપાસો.", + "501": "થમ્બનેલનો સપોર્ટ બંધ કરેલો છે." + }, + "deleteFilePermissions": "Removing files is not allowed in this folder.", + "fileInvalidCharacters": "ફાઈલના નામમાં એમના કોઈ પણ કેરેક્ટર ન ચાલે: {disallowedCharacters}", + "fileNameNotEmpty": "The file name cannot be empty.", + "folderInvalidCharacters": "ફોલ્ડરના નામમાં એમના કોઈ પણ કેરેક્ટર ન ચાલે: {disallowedCharacters}", + "incorrectExtension": "આ ફોલ્ડરમાં આ એક્ષટેનસન શક્ય નથી.", + "missingFile": "The requested file is no longer available.", + "missingFolder": "The folder you are trying to reach is no longer available.", + "noUploadFolderSelected": "અપલોડ કરતા પેહલાં ફોલ્ડર પસંદ કરો.", + "operationCompleted": "Operation completed with errors.", + "renameFilePermissions": "Renaming files is not allowed in this folder.", + "unknown": "તમારી રીક્વેસ્ટ માન્ય નથી. (એરર {number})", + "unknownUploadError": "ફાઈલ મોકલવામાં એરર છે.", + "uploadErrors": "Upload finished with errors.", + "uploadPermissions": "ફાઈલ અપલોડ શક્ય નથી." + }, + "chooseResizedImage": { + "title": "Choose Resized", + "originalSize": "Original Size", + "sizes": { + "custom": "Custom", + "large": "Large", + "max": "Max", + "medium": "Medium", + "small": "Small" + } + }, + "editImage": { + "adjust": "Adjust", + "apply": "Apply", + "confirmExit": "Are you sure you want to close? You have unsaved changes to the image.", + "crop": "Crop", + "downloadAction": "Downloading original image.", + "keepAspectRatio": "Keep Aspect Ratio", + "loading": "Loading image", + "presets": "Presets", + "reset": "Reset", + "resize": "Resize", + "rotate": "Rotate", + "rotateAntiClockwise": "90° Left", + "rotateClockwise": "90° Right", + "save": "Save", + "saveDialogFileExists": "File with the same name already exists in folder.", + "saveDialogOverwrite": "Overwrite File", + "saveDialogSaveAs": "Save as:", + "saveDialogTitle": "Save Changes", + "title": "Edit Image", + "transformationAction": "Applying transformations.", + "uploadAction": "Uploading edited image.", + "filters": { + "brightness": "Brightness", + "clip": "Clip", + "contrast": "Contrast", + "exposure": "Exposure", + "gamma": "Gamma", + "hue": "Hue", + "noise": "Noise", + "saturation": "Saturation", + "sepia": "Sepia", + "sharpen": "Sharpen", + "stackBlur": "Blur", + "vibrance": "Vibrance" + }, + "preset": { + "clarity": "Clarity", + "concentrate": "Concentrate", + "crossProcess": "Cross Process", + "glowingSun": "Glowing Sun", + "grungy": "Grungy", + "hazyDays": "Hazy Days", + "hemingway": "Hemingway", + "herMajesty": "Her Majesty", + "jarques": "Jarques", + "lomo": "Lomo", + "love": "Love", + "nostalgia": "Nostalgia", + "oldBoot": "Old Boot", + "orangePeel": "Orange Peel", + "pinhole": "Pinhole", + "sinCity": "Sin City", + "sunrise": "Sunrise", + "vintage": "Vintage" + } + }, + "shortcuts": { + "title": "Keyboard Shortcuts", + "general": { + "action": "Execute default action", + "firstItem": "Go to first item", + "focusFilesPane": "Focus files pane", + "focusFoldersPane": "Focus folders pane or breadcrumbs", + "focusNext": "Focus next pane", + "focusToolbar": "Focus toolbar", + "lastItem": "Go to last item", + "listShortcuts": "Open this help dialog", + "nextItem": "Go to next item", + "previousItem": "Go to previous item", + "showContextMenu": "Open context menu", + "title": "General Interface" + }, + "files": { + "addToSelectionAbove": "Add or remove files above to selection", + "addToSelectionBelow": "Add or remove files below to selection", + "addToSelectionLeft": "Add or remove file on the left to selection", + "addToSelectionRight": "Add or remove file on the right to selection", + "delete": "Delete file(s)", + "refresh": "Refresh files", + "rename": "Rename file", + "selectAll": "Select all files", + "upload": "Upload file(s)" + }, + "folders": { + "collapseOrParent": "Collapse folder / Go to parent folder", + "delete": "Delete folder", + "expandOrSubfolder": "Expand folder / Go to first subfolder", + "title": "Folders Pane" + }, + "keys": { + "ctrl": "Control", + "delete": "Delete", + "downArrow": "Down arrow", + "escape": "Escape", + "leftArrow": "Left arrow", + "question": "Question mark", + "rightArrow": "Right arrow", + "upArrow": "Up arrow" + }, + "keysAbbreviations": { + "alt": "alt", + "ctrl": "ctrl", + "del": "del", + "end": "end", + "home": "home", + "shift": "shift" + } + } +} diff --git a/lib/ckfinder/lang/he.json b/lib/ckfinder/lang/he.json new file mode 100644 index 0000000..7af2ce5 --- /dev/null +++ b/lib/ckfinder/lang/he.json @@ -0,0 +1,288 @@ +{ + "appTitle": "CKFinder", + "dir": "rtl", + "langCode": "he", + "common": { + "abort": "Abort", + "cancel": "ביטול", + "choose": "Choose", + "close": "סגור", + "copy": "Copy", + "delete": "מחיקה", + "download": "הורדה", + "edit": "עריכה", + "maximize": "הגדלה למקסימום", + "messageTitle": "הודעה", + "minimize": "הקטנה למינימום", + "move": "Move", + "newNameDialogTitle": "שם חדש", + "ok": "אישור", + "pleaseWait": "Please wait.", + "rememberDecision": "זכור החלטתי", + "rename": "שינוי שם", + "showMore": "Show more", + "skip": "דלג", + "upload": "העלאה", + "view": "צפיה" + }, + "units": { + "dateFormat": "d/m/yyyy HH:MM", + "dateAmPm": [ + "AM", + "PM" + ], + "kb": "{size}KB", + "mb": "{size}MB", + "gb": "{size}GB", + "sizePerSecond": "{size}/s", + "pixelShort": "px" + }, + "files": { + "autoRename": "שינוי שם אוטומטי", + "countMany": "{count} קבצים", + "countOne": "קובץ 1", + "deleteConfirmation": "האם למחוק {count} קבצים?", + "fileDeleteConfirmation": "האם למחוק את הקובץ \"{name}\"?", + "fileRenameExtensionConfirmation": "האם לשנות את הסיומת של הקובץ?", + "fileRenameLabel": "יש להקליד שם חדש לקובץ: ", + "filesPaneTitle": "Files pane", + "filesRefresh": "Refreshing files", + "filterPlaceholder": "Filter", + "gettingFileData": "Getting file data.", + "overwrite": "החלפה", + "loadingFilesPane": { + "title": "Loading...", + "text": "The files are being loaded." + }, + "emptyFilesPane": { + "title": "The folder is empty.", + "text": "Use the Upload button or drag and drop your files here." + }, + "filterFilesEmpty": { + "title": "Nothing found.", + "text": "Please try using different search criteria." + } + }, + "folders": { + "deleteConfirmation": "האם למחוק את התיקיה \"{name}\" ?", + "destinationFolder": "תיקיית יעד", + "newNameLabel": "יש להקליד שם חדש לתיקיה: ", + "newSubfolder": "תת-תיקיה חדשה", + "renameDialogTitle": "Rename Folder", + "treeTitle": "Folders tree" + }, + "copy": { + "dropMenuItem": "העתקת קבצים לכאן", + "errorDialogTitle": "Files that cannot be copied:", + "manyFilesDialogTitle": "Copy {count} Files To...", + "manyFilesWait": "Copying {count} files.", + "oneFileDialogTitle": "Copy File To...", + "oneFileWait": "Copying file.", + "operationLabel": "Copying Files", + "operationSummary": "מספר קבצים שהועתקו: {count}." + }, + "move": { + "dropMenuItem": "הזזת קבצים לכאן", + "errorDialogTitle": "Files that cannot be moved:", + "manyFilesDialogTitle": "Move {count} Files To...", + "manyFilesWait": "Moving {count} files.", + "oneFileDialogTitle": "Move File To...", + "oneFileWait": "Moving file.", + "operationLabel": "Moving Files", + "operationSummary": "מספר קבצים שהוזזו: {count}." + }, + "upload": { + "addFiles": "הוספת קבצים", + "bytesCountProgress": "({bytesUploaded} of {bytesTotal})", + "details": "Details", + "filesCountProgress": "{filesUploaded} of {filesTotal}", + "progressLabel": "העלאה מתבצעת, נא להמתין...", + "progressMessage": "Uploading...", + "selectFileLabel": "בחירת קובץ להעלאה", + "selectFiles": "Select files to upload", + "success": "Upload finished!", + "summary": "Uploaded files: {count}" + }, + "settings": { + "display": "תצוגה:", + "displayDate": "תאריך", + "displayName": "שם קובץ", + "displaySize": "גודל קובץ", + "sortAscending": "Ascending", + "sortBy": "Sort by", + "sortByOrder": "Order", + "sortDescending": "Descending", + "thumbnailSize": "Thumbnail Size", + "title": "הגדרות", + "viewType": "View", + "viewTypeCompact": "Compact", + "viewTypeList": "List", + "viewTypeThumbnails": "Thumbnails" + }, + "errors": { + "codes": { + "10": "הוראה לא תקינה.", + "11": "סוג המשאב לא צויין בבקשה לשרת.", + "12": "סוג המשאב המצויין לא תקין.", + "13": "The connector configuration file is invalid.", + "14": "Invalid connector plugin: {pluginName}.", + "102": "שם הקובץ או התיקיה לא תקין.", + "103": "לא היה ניתן להשלים את הבקשה בשל הרשאות מוגבלות.", + "104": "לא היה ניתן להשלים את הבקשה בשל הרשאות מערכת קבצים מוגבלות.", + "105": "סיומת הקובץ לא תקינה.", + "109": "בקשה לא תקינה.", + "110": "שגיאה לא ידועה.", + "111": "לא ניתן היה להשלים את הבקשה בשל הגודל החריג של הקובץ הנוצר.", + "115": "כבר קיים/ת קובץ או תיקיה באותו השם.", + "116": "התיקיה לא נמצאה. נא לרענן ולנסות שוב.", + "117": "הקובץ לא נמצא. נא לרענן ולנסות שוב.", + "118": "כתובות המקור והיעד זהות.", + "201": "קובץ עם אותו השם כבר קיים. שם הקובץ שהועלה שונה ל \"{name}\"", + "202": "הקובץ לא תקין.", + "203": "הקובץ לא תקין. גודל הקובץ גדול מדי.", + "204": "הקובץ המועלה לא תקין", + "205": "לא קיימת בשרת תיקיה זמנית להעלאת קבצים.", + "206": "ההעלאה בוטלה מסיבות אבטחה. הקובץ מכיל תוכן שדומה ל-HTML.", + "207": "שם הקובץ שהועלה שונה ל \"{name}\"", + "300": "העברת הקבצים נכשלה.", + "301": "העתקת הקבצים נכשלה.", + "302": "Deleting file(s) failed.", + "500": "דפדפן הקבצים מנוטרל מסיבות אבטחה. יש לפנות למנהל המערכת ולבדוק את קובץ התצורה של CKFinder.", + "501": "התמיכה בתמונות מוקטנות מבוטלת." + }, + "deleteFilePermissions": "Removing files is not allowed in this folder.", + "fileInvalidCharacters": "שם הקובץ לא יכול לכלול תווים הבאים: {disallowedCharacters}", + "fileNameNotEmpty": "The file name cannot be empty.", + "folderInvalidCharacters": "שם התיקיה לא יכול לכלול תווים הבאים: {disallowedCharacters}", + "incorrectExtension": "סוג קובץ זה לא מאושר בתיקיה זאת.", + "missingFile": "The requested file is no longer available.", + "missingFolder": "The folder you are trying to reach is no longer available.", + "noUploadFolderSelected": "יש לבחור תיקיה לפני ההעלאה.", + "operationCompleted": "הפעולה הושלמה עם שגיאות.", + "renameFilePermissions": "Renaming files is not allowed in this folder.", + "unknown": "לא היה ניתן להשלים את הבקשה. (שגיאה {number})", + "unknownUploadError": "שגיאה בשליחת הקובץ.", + "uploadErrors": "Upload finished with errors.", + "uploadPermissions": "העלאת קובץ אסורה." + }, + "chooseResizedImage": { + "title": "Choose Resized", + "originalSize": "Original Size", + "sizes": { + "custom": "Custom", + "large": "Large", + "max": "Max", + "medium": "Medium", + "small": "Small" + } + }, + "editImage": { + "adjust": "Adjust", + "apply": "Apply", + "confirmExit": "Are you sure you want to close? You have unsaved changes to the image.", + "crop": "Crop", + "downloadAction": "Downloading original image.", + "keepAspectRatio": "Keep Aspect Ratio", + "loading": "Loading image", + "presets": "Presets", + "reset": "Reset", + "resize": "Resize", + "rotate": "Rotate", + "rotateAntiClockwise": "90° Left", + "rotateClockwise": "90° Right", + "save": "Save", + "saveDialogFileExists": "File with the same name already exists in folder.", + "saveDialogOverwrite": "Overwrite File", + "saveDialogSaveAs": "Save as:", + "saveDialogTitle": "Save Changes", + "title": "Edit Image", + "transformationAction": "Applying transformations.", + "uploadAction": "Uploading edited image.", + "filters": { + "brightness": "Brightness", + "clip": "Clip", + "contrast": "Contrast", + "exposure": "Exposure", + "gamma": "Gamma", + "hue": "Hue", + "noise": "Noise", + "saturation": "Saturation", + "sepia": "Sepia", + "sharpen": "Sharpen", + "stackBlur": "Blur", + "vibrance": "Vibrance" + }, + "preset": { + "clarity": "Clarity", + "concentrate": "Concentrate", + "crossProcess": "Cross Process", + "glowingSun": "Glowing Sun", + "grungy": "Grungy", + "hazyDays": "Hazy Days", + "hemingway": "Hemingway", + "herMajesty": "Her Majesty", + "jarques": "Jarques", + "lomo": "Lomo", + "love": "Love", + "nostalgia": "Nostalgia", + "oldBoot": "Old Boot", + "orangePeel": "Orange Peel", + "pinhole": "Pinhole", + "sinCity": "Sin City", + "sunrise": "Sunrise", + "vintage": "Vintage" + } + }, + "shortcuts": { + "title": "Keyboard Shortcuts", + "general": { + "action": "Execute default action", + "firstItem": "Go to first item", + "focusFilesPane": "Focus files pane", + "focusFoldersPane": "Focus folders pane or breadcrumbs", + "focusNext": "Focus next pane", + "focusToolbar": "Focus toolbar", + "lastItem": "Go to last item", + "listShortcuts": "Open this help dialog", + "nextItem": "Go to next item", + "previousItem": "Go to previous item", + "showContextMenu": "Open context menu", + "title": "General Interface" + }, + "files": { + "addToSelectionAbove": "Add or remove files above to selection", + "addToSelectionBelow": "Add or remove files below to selection", + "addToSelectionLeft": "Add or remove file on the left to selection", + "addToSelectionRight": "Add or remove file on the right to selection", + "delete": "Delete file(s)", + "refresh": "Refresh files", + "rename": "Rename file", + "selectAll": "Select all files", + "upload": "Upload file(s)" + }, + "folders": { + "collapseOrParent": "Collapse folder / Go to parent folder", + "delete": "Delete folder", + "expandOrSubfolder": "Expand folder / Go to first subfolder", + "title": "Folders Pane" + }, + "keys": { + "ctrl": "Control", + "delete": "Delete", + "downArrow": "Down arrow", + "escape": "Escape", + "leftArrow": "Left arrow", + "question": "Question mark", + "rightArrow": "Right arrow", + "upArrow": "Up arrow" + }, + "keysAbbreviations": { + "alt": "alt", + "ctrl": "ctrl", + "del": "del", + "end": "end", + "home": "home", + "shift": "shift" + } + } +} diff --git a/lib/ckfinder/lang/hi.json b/lib/ckfinder/lang/hi.json new file mode 100644 index 0000000..9639676 --- /dev/null +++ b/lib/ckfinder/lang/hi.json @@ -0,0 +1,288 @@ +{ + "appTitle": "CKFinder", + "dir": "ltr", + "langCode": "hi", + "common": { + "abort": "Abort", + "cancel": "खारिज", + "choose": "Choose", + "close": "क्लोस", + "copy": "Copy", + "delete": "डिलिट", + "download": "डाउनलोड", + "edit": "एडिट", + "maximize": "मैक्सीमईज", + "messageTitle": "माहिती", + "minimize": "मिनीमाईज", + "move": "Move", + "newNameDialogTitle": "नया नाम", + "ok": "ओके", + "pleaseWait": "Please wait.", + "rememberDecision": "मेरा विकल्प याद रखो", + "rename": "रिनेम", + "showMore": "Show more", + "skip": "स्किप", + "upload": "अपलोड", + "view": "व्यू" + }, + "units": { + "dateFormat": "m/d/yyyy h:MM aa", + "dateAmPm": [ + "AM", + "PM" + ], + "kb": "{size} KB", + "mb": "{size} MB", + "gb": "{size} GB", + "sizePerSecond": "{size}/s", + "pixelShort": "px" + }, + "files": { + "autoRename": "ऑटो-रीनेम", + "countMany": "{count} फाएल", + "countOne": "1 फाएल", + "deleteConfirmation": "Are you sure you want to delete {count} files?", + "fileDeleteConfirmation": "क्या आपको फाएल डिलिट करना है \"{name}\"?", + "fileRenameExtensionConfirmation": "क्या आपको फाएल एक्सटेंसन बदलना है? फाएल का उपयोग नही कर सकोगे.", + "fileRenameLabel": "फाएलका नया नाम टाईप करो: ", + "filesPaneTitle": "Files pane", + "filesRefresh": "Refreshing files", + "filterPlaceholder": "Filter", + "gettingFileData": "Getting file data.", + "overwrite": "ओवरराईट", + "loadingFilesPane": { + "title": "Loading...", + "text": "The files are being loaded." + }, + "emptyFilesPane": { + "title": "The folder is empty.", + "text": "Use the Upload button or drag and drop your files here." + }, + "filterFilesEmpty": { + "title": "Nothing found.", + "text": "Please try using different search criteria." + } + }, + "folders": { + "deleteConfirmation": "क्या आपको \"{name}\" फोल्डर डीलिट करना है?", + "destinationFolder": "Destination Folder", + "newNameLabel": "फोल्डरका नया नाम टाईप करो: ", + "newSubfolder": "नया सबफोल्डर", + "renameDialogTitle": "Rename Folder", + "treeTitle": "Folders tree" + }, + "copy": { + "dropMenuItem": "यहाँ कोपी करें", + "errorDialogTitle": "Files that cannot be copied:", + "manyFilesDialogTitle": "Copy {count} Files To...", + "manyFilesWait": "Copying {count} files.", + "oneFileDialogTitle": "Copy File To...", + "oneFileWait": "Copying file.", + "operationLabel": "Copying Files", + "operationSummary": "Number of files copied: {count}." + }, + "move": { + "dropMenuItem": "यंहा मूव करें", + "errorDialogTitle": "Files that cannot be moved:", + "manyFilesDialogTitle": "Move {count} Files To...", + "manyFilesWait": "Moving {count} files.", + "oneFileDialogTitle": "Move File To...", + "oneFileWait": "Moving file.", + "operationLabel": "Moving Files", + "operationSummary": "Number of files moved: {count}." + }, + "upload": { + "addFiles": "फाएल एड करें", + "bytesCountProgress": "({bytesUploaded} of {bytesTotal})", + "details": "Details", + "filesCountProgress": "{filesUploaded} of {filesTotal}", + "progressLabel": "उपलोड जारी है.", + "progressMessage": "Uploading...", + "selectFileLabel": "उपलोड करने के लिये फाएल चुनो", + "selectFiles": "Select files to upload", + "success": "Upload finished!", + "summary": "Uploaded files: {count}" + }, + "settings": { + "display": "डिस्प्ले:", + "displayDate": "तारीख", + "displayName": "फाएलका नाम", + "displaySize": "फाएल साईज", + "sortAscending": "Ascending", + "sortBy": "Sort by", + "sortByOrder": "Order", + "sortDescending": "Descending", + "thumbnailSize": "Thumbnail Size", + "title": "सेटिंग्स", + "viewType": "View", + "viewTypeCompact": "Compact", + "viewTypeList": "List", + "viewTypeThumbnails": "Thumbnails" + }, + "errors": { + "codes": { + "10": "इन्वेलीड कमांड.", + "11": "यह रिसोर्स टाईप उपलब्ध नहीं है.", + "12": "यह रिसोर्स टाईप वेलिड नही हैं.", + "13": "The connector configuration file is invalid.", + "14": "Invalid connector plugin: {pluginName}.", + "102": "फाएल या फोल्डर का नाम वेलिड नहीं है.", + "103": "ओथोरिसेसंन रिस्त्रिक्सं की वजह से, आपकी रिक्वेस्ट पूरी नही कर सकते.", + "104": "सिस्टम परमिशन रिस्त्रिक्सं की वजह से, आपकी रिक्वेस्ट पूरी नही कर सकते..", + "105": "फाएल एक्स्त्न्सं गलत है.", + "109": "इन्वेलीड रिक्वेस्ट.", + "110": "अननोन एरर.", + "111": "It was not possible to complete the request due to resulting file size.", + "115": "सेम नाम का फाएल या फोल्डर मोजूद है.", + "116": "फोल्डर नही मिला. रिफ्रेस करके वापिस प्रयत्न करे.", + "117": "फाएल नही मिला. फाएल लिस्टको रिफ्रेस करके वापिस प्रयत्न करे.", + "118": "सोर्स और टारगेट के पाथ एक जैसे है.", + "201": "वहि नाम की फाएल मोजोद है. अपलोड फाएल का नया नाम \"{name}\".", + "202": "इन्वेलीड फाएल.", + "203": "इन्वेलीड फाएल. फाएल बहुत बड़ी है.", + "204": "अपलोडकी गयी फाएल करप्ट हो गयी है.", + "205": "फाएल अपलोड करनेके लिये, सर्वरपे टेम्पररी फोल्डर उपलब्थ नही है..", + "206": "सिक्योरिटी कारण वष, फाएल अपलोड केन्सल किया है. फाएलमें HTML-जैसे डेटा है.", + "207": "अपलोडेड फाएल का नया नाम \"{name}\".", + "300": "फाएल मूव नहीं कर सके.", + "301": "फाएल कोपी नहीं कर सके.", + "302": "Deleting file(s) failed.", + "500": "सिक्योरिटी कारण वष, फाएल ब्राउजर डिसेबल किया गया है. आपके सिस्टम एडमिनिस्ट्रेटर का सम्पर्क करे और CKFinder कोंफिग्युरेसन फाएल तपासे.", + "501": "थम्बनेल सपोर्ट डिसेबल किया है." + }, + "deleteFilePermissions": "Removing files is not allowed in this folder.", + "fileInvalidCharacters": "फाएलके नाममें यह केरेक्टर नही हो सकते: {disallowedCharacters}", + "fileNameNotEmpty": "The file name cannot be empty.", + "folderInvalidCharacters": "फोल्डरके नाममें यह केरेक्टर नही हो सकते: {disallowedCharacters}", + "incorrectExtension": "ये फोल्डरमें ये फाइल एक्सटेंसन अलाव नही है.", + "missingFile": "The requested file is no longer available.", + "missingFolder": "The folder you are trying to reach is no longer available.", + "noUploadFolderSelected": "फोल्डर चुनके अपलोडिग करिये.", + "operationCompleted": "Operation completed with errors.", + "renameFilePermissions": "Renaming files is not allowed in this folder.", + "unknown": "आपकी रिक्वेस्ट क्मप्लित नही कर सकते. (एरर {number})", + "unknownUploadError": "फाएल भेजने में मुश्केली हो रही है.", + "uploadErrors": "Upload finished with errors.", + "uploadPermissions": "फाएल उपलोड नही कर सकते." + }, + "chooseResizedImage": { + "title": "Choose Resized", + "originalSize": "Original Size", + "sizes": { + "custom": "Custom", + "large": "Large", + "max": "Max", + "medium": "Medium", + "small": "Small" + } + }, + "editImage": { + "adjust": "Adjust", + "apply": "Apply", + "confirmExit": "Are you sure you want to close? You have unsaved changes to the image.", + "crop": "Crop", + "downloadAction": "Downloading original image.", + "keepAspectRatio": "Keep Aspect Ratio", + "loading": "Loading image", + "presets": "Presets", + "reset": "Reset", + "resize": "Resize", + "rotate": "Rotate", + "rotateAntiClockwise": "90° Left", + "rotateClockwise": "90° Right", + "save": "Save", + "saveDialogFileExists": "File with the same name already exists in folder.", + "saveDialogOverwrite": "Overwrite File", + "saveDialogSaveAs": "Save as:", + "saveDialogTitle": "Save Changes", + "title": "Edit Image", + "transformationAction": "Applying transformations.", + "uploadAction": "Uploading edited image.", + "filters": { + "brightness": "Brightness", + "clip": "Clip", + "contrast": "Contrast", + "exposure": "Exposure", + "gamma": "Gamma", + "hue": "Hue", + "noise": "Noise", + "saturation": "Saturation", + "sepia": "Sepia", + "sharpen": "Sharpen", + "stackBlur": "Blur", + "vibrance": "Vibrance" + }, + "preset": { + "clarity": "Clarity", + "concentrate": "Concentrate", + "crossProcess": "Cross Process", + "glowingSun": "Glowing Sun", + "grungy": "Grungy", + "hazyDays": "Hazy Days", + "hemingway": "Hemingway", + "herMajesty": "Her Majesty", + "jarques": "Jarques", + "lomo": "Lomo", + "love": "Love", + "nostalgia": "Nostalgia", + "oldBoot": "Old Boot", + "orangePeel": "Orange Peel", + "pinhole": "Pinhole", + "sinCity": "Sin City", + "sunrise": "Sunrise", + "vintage": "Vintage" + } + }, + "shortcuts": { + "title": "Keyboard Shortcuts", + "general": { + "action": "Execute default action", + "firstItem": "Go to first item", + "focusFilesPane": "Focus files pane", + "focusFoldersPane": "Focus folders pane or breadcrumbs", + "focusNext": "Focus next pane", + "focusToolbar": "Focus toolbar", + "lastItem": "Go to last item", + "listShortcuts": "Open this help dialog", + "nextItem": "Go to next item", + "previousItem": "Go to previous item", + "showContextMenu": "Open context menu", + "title": "General Interface" + }, + "files": { + "addToSelectionAbove": "Add or remove files above to selection", + "addToSelectionBelow": "Add or remove files below to selection", + "addToSelectionLeft": "Add or remove file on the left to selection", + "addToSelectionRight": "Add or remove file on the right to selection", + "delete": "Delete file(s)", + "refresh": "Refresh files", + "rename": "Rename file", + "selectAll": "Select all files", + "upload": "Upload file(s)" + }, + "folders": { + "collapseOrParent": "Collapse folder / Go to parent folder", + "delete": "Delete folder", + "expandOrSubfolder": "Expand folder / Go to first subfolder", + "title": "Folders Pane" + }, + "keys": { + "ctrl": "Control", + "delete": "Delete", + "downArrow": "Down arrow", + "escape": "Escape", + "leftArrow": "Left arrow", + "question": "Question mark", + "rightArrow": "Right arrow", + "upArrow": "Up arrow" + }, + "keysAbbreviations": { + "alt": "alt", + "ctrl": "ctrl", + "del": "del", + "end": "end", + "home": "home", + "shift": "shift" + } + } +} diff --git a/lib/ckfinder/lang/hr.json b/lib/ckfinder/lang/hr.json new file mode 100644 index 0000000..0654d3f --- /dev/null +++ b/lib/ckfinder/lang/hr.json @@ -0,0 +1,288 @@ +{ + "appTitle": "CKFinder", + "dir": "ltr", + "langCode": "hr", + "common": { + "abort": "Prekini", + "cancel": "Poništi", + "choose": "Izaberi", + "close": "Zatvori", + "copy": "Kopiraj", + "delete": "Obriši", + "download": "Skini", + "edit": "Promijeni", + "maximize": "Povećaj", + "messageTitle": "Informacija", + "minimize": "Smanji", + "move": "Premjesti", + "newNameDialogTitle": "Novi naziv", + "ok": "U redu", + "pleaseWait": "Pričekajte.", + "rememberDecision": "Zapamti moj izbor", + "rename": "Promijeni naziv", + "showMore": "Pokaži više", + "skip": "Preskoči", + "upload": "Pošalji", + "view": "Pogledaj" + }, + "units": { + "dateFormat": "dd/mm/yyyy HH:MM", + "dateAmPm": [ + "AM", + "PM" + ], + "kb": "{size} KB", + "mb": "{size} MB", + "gb": "{size} GB", + "sizePerSecond": "{size}/s", + "pixelShort": "px" + }, + "files": { + "autoRename": "Automatska promjena naziva", + "countMany": "{count} datoteka", + "countOne": "1 datoteka", + "deleteConfirmation": "Jeste li sigurni da želite obrisati {count} datoteke?", + "fileDeleteConfirmation": "Sigurno želite obrisati datoteku \"{name}\"?", + "fileRenameExtensionConfirmation": "Sigurno želite promijeniti vrstu datoteke? Datoteka može postati neiskoristiva.", + "fileRenameLabel": "Unesite novo ime datoteke: ", + "filesPaneTitle": "Panel Datoteka", + "filesRefresh": "Osvježavanje datoteka", + "filterPlaceholder": "Filter", + "gettingFileData": "Dobavljam podatke o datoteci.", + "overwrite": "Prepiši", + "loadingFilesPane": { + "title": "Učitavam...", + "text": "Datoteke se učitavaju." + }, + "emptyFilesPane": { + "title": "Direktorij je prazan.", + "text": "Koristite Upload gumb ili dovucite i ispustite vaše datoteke ovdje." + }, + "filterFilesEmpty": { + "title": "Ništa nije nađeno.", + "text": "Pokušajte koristiti drugačiji kriterij pretraživanja." + } + }, + "folders": { + "deleteConfirmation": "Sigurno želite obrisati direktorij \"{name}\"?", + "destinationFolder": "Odredišni Folder", + "newNameLabel": "Unesite ime novog direktorija: ", + "newSubfolder": "Novi poddirektorij", + "renameDialogTitle": "Preimenuj Folder", + "treeTitle": "Drvo Foldera" + }, + "copy": { + "dropMenuItem": "Kopiraj ovdje", + "errorDialogTitle": "Datoteke koje ne mogu biti kopirane:", + "manyFilesDialogTitle": "Kopiraj {count} datoteke u...", + "manyFilesWait": "Kopiranje {count} datoteka.", + "oneFileDialogTitle": "Kopiraj datoteku u...", + "oneFileWait": "Kopiram datoteke.", + "operationLabel": "Kopiranje datoteka", + "operationSummary": "Broj kopiranih datoteka: {count}." + }, + "move": { + "dropMenuItem": "Premjesti ovdje", + "errorDialogTitle": "Datoteke koje ne mogu biti premještene:", + "manyFilesDialogTitle": "Premjesti {count} datoteke u...", + "manyFilesWait": "Premještanje {count} datoteka.", + "oneFileDialogTitle": "Premjesti datoteku u...", + "oneFileWait": "Premještam datoteke.", + "operationLabel": "Premještanje datoteka", + "operationSummary": "Broj premještenih datoteka: {count}." + }, + "upload": { + "addFiles": "Dodaj datoteke", + "bytesCountProgress": "({bytesUploaded} od {bytesTotal})", + "details": "Detalji", + "filesCountProgress": "{filesUploaded} od {filesTotal}", + "progressLabel": "Slanje u tijeku.", + "progressMessage": "Uploadanje...", + "selectFileLabel": "Odaberi datoteku za slanje", + "selectFiles": "Odaberite datoteke za upload", + "success": "Upload dovršen!", + "summary": "Uploadane datoteke: {count}" + }, + "settings": { + "display": "Prikaz:", + "displayDate": "Datum", + "displayName": "Naziv datoteke", + "displaySize": "Veličina datoteke", + "sortAscending": "Ascending", + "sortBy": "Sort by", + "sortByOrder": "Order", + "sortDescending": "Descending", + "thumbnailSize": "Veličina sličice", + "title": "Postavke", + "viewType": "View", + "viewTypeCompact": "Compact", + "viewTypeList": "List", + "viewTypeThumbnails": "Thumbnails" + }, + "errors": { + "codes": { + "10": "Nepoznata naredba.", + "11": "Nije navedena vrsta u zahtjevu.", + "12": "Zatražena vrsta nije važeća.", + "13": "Connector konfiguracijski fajl nije valjan.", + "14": "Connector plugin nije ispravan: {pluginName}.", + "102": "Neispravan naziv datoteke ili direktorija.", + "103": "Nije moguće izvršiti zahtjev zbog ograničenja pristupa.", + "104": "Nije moguće izvršiti zahtjev zbog ograničenja postavki sustava.", + "105": "Nedozvoljena vrsta datoteke.", + "109": "Nedozvoljen zahtjev.", + "110": "Nepoznata greška.", + "111": "Nije moguće izvršiti zahtjev zbog resulting veličine datoteke.", + "115": "Datoteka ili direktorij s istim nazivom već postoji.", + "116": "Direktorij nije pronađen. Osvježite stranicu i pokušajte ponovo.", + "117": "Datoteka nije pronađena. Osvježite listu datoteka i pokušajte ponovo.", + "118": "Putanje izvora i odredišta su jednake.", + "201": "Datoteka s istim nazivom već postoji. Poslana datoteka je promijenjena u \"{name}\".", + "202": "Neispravna datoteka.", + "203": "Neispravna datoteka. Veličina datoteke je prevelika.", + "204": "Poslana datoteka je neispravna.", + "205": "Ne postoji privremeni direktorij za slanje na server.", + "206": "Slanje je poništeno zbog sigurnosnih postavki. Naziv datoteke sadrži HTML podatke.", + "207": "Poslana datoteka je promjenjena u \"{name}\".", + "300": "Premještanje datoteke(a) nije uspjelo.", + "301": "Kopiranje datoteke(a) nije uspjelo.", + "302": "Brisanje datoteke(a) nije uspjelo.", + "500": "Pretraživanje datoteka nije dozvoljeno iz sigurnosnih razloga. Molimo kontaktirajte administratora sustava kako bi provjerili postavke CKFinder konfiguracijske datoteke.", + "501": "Podrška za sličice je onemogućena." + }, + "deleteFilePermissions": "Removing files is not allowed in this folder.", + "fileInvalidCharacters": "Naziv datoteke ne smije sadržavati niti jedan od sljedećih znakova: {disallowedCharacters}", + "fileNameNotEmpty": "The file name cannot be empty.", + "folderInvalidCharacters": "Naziv direktorija ne smije sadržavati niti jedan od sljedećih znakova: {disallowedCharacters}", + "incorrectExtension": "Vrsta datoteka nije dozvoljena.", + "missingFile": "Tražena datoteka više nije dostupna.", + "missingFolder": "Direktorij više nije dostupan.", + "noUploadFolderSelected": "Odaberite direktorije prije slanja.", + "operationCompleted": "Operacija je izvršena, ali sa greškama.", + "renameFilePermissions": "Renaming files is not allowed in this folder.", + "unknown": "Nije moguće završiti zahtjev. (Greška {number})", + "unknownUploadError": "Greška kod slanja datoteke.", + "uploadErrors": "Upload dovršen sa greškama.", + "uploadPermissions": "Slanje datoteka nije dozvoljeno." + }, + "chooseResizedImage": { + "title": "Izaberi Scaled", + "originalSize": "Originalna Veličina", + "sizes": { + "custom": "Odredi", + "large": "Velika", + "max": "Max", + "medium": "Srednja", + "small": "Mala" + } + }, + "editImage": { + "adjust": "Prilagodi", + "apply": "Primijeni", + "confirmExit": "Da li sigurno želiš zatvoriti? Imaš nesačuvane promjene na slici.", + "crop": "Izreži", + "downloadAction": "Preuzimanje originalne slike.", + "keepAspectRatio": "Zadrži Aspect Ratio", + "loading": "Učitavanje slike", + "presets": "Presets", + "reset": "Resetiraj", + "resize": "Resize", + "rotate": "Rotiraj", + "rotateAntiClockwise": "90° Lijevo", + "rotateClockwise": "90° Desno", + "save": "Sačuvaj", + "saveDialogFileExists": "Datoteka sa istim imenom već postoji u direktoriju.", + "saveDialogOverwrite": "Prepiši preko datoteke", + "saveDialogSaveAs": "Sačuvaj kao:", + "saveDialogTitle": "Sačuvaj Promjene", + "title": "Uredi Sliku", + "transformationAction": "Primjenjujem transformacije.", + "uploadAction": "Uploadanje uređene slike.", + "filters": { + "brightness": "Svjetlina", + "clip": "Clip", + "contrast": "Kontrast", + "exposure": "Expozicija", + "gamma": "Gamma", + "hue": "Nijansa", + "noise": "Noise", + "saturation": "Zasićenje", + "sepia": "Sepia", + "sharpen": "Izoštri", + "stackBlur": "Stack Blur", + "vibrance": "Vibrance" + }, + "preset": { + "clarity": "Jasnoća", + "concentrate": "Concentrate", + "crossProcess": "Cross Process", + "glowingSun": "Sjaj Sunca", + "grungy": "Grungy", + "hazyDays": "Hazy Days", + "hemingway": "Hemingway", + "herMajesty": "Njeno Visočanstvo", + "jarques": "Jarques", + "lomo": "Lomo", + "love": "Ljubav", + "nostalgia": "Nostalgia", + "oldBoot": "Stara Čizma", + "orangePeel": "Kora Naranče", + "pinhole": "Pinhole", + "sinCity": "Sin City", + "sunrise": "Izlazak sunca", + "vintage": "Vintage" + } + }, + "shortcuts": { + "title": "Prečaci na tipkovnici", + "general": { + "action": "Izvrši zadanu akciju", + "firstItem": "Idi na prvu stavku", + "focusFilesPane": "Fokusiraj panel datoteka", + "focusFoldersPane": "Fokusiraj panel foldera ili mrvice", + "focusNext": "Fokusiraj sljedeći panel", + "focusToolbar": "Fokusiraj alatnu traku", + "lastItem": "Idi na posljednju stavku", + "listShortcuts": "Otvori ovaj dijalog za pomoć", + "nextItem": "Idi na sljedeću stavku", + "previousItem": "Idi na prošlu stavku", + "showContextMenu": "Otvori kontextni menu", + "title": "Generalno Sučelje" + }, + "files": { + "addToSelectionAbove": "Dodaj ili makni datoteke u odabir", + "addToSelectionBelow": "Dodaj ili makni datoteke u odabir", + "addToSelectionLeft": "Dodaj ili makni datoteke u odabir", + "addToSelectionRight": "Dodaj ili makni datoteke u odabir", + "delete": "Obriši datoteku(e)", + "refresh": "Osvježi datoteke", + "rename": "Preimenuj datoteku", + "selectAll": "Odaberi sve datoteke", + "upload": "Prenesi datoteku(e)" + }, + "folders": { + "collapseOrParent": "Suzi folder / Pođi na roditeljski folder", + "delete": "Obriši folder", + "expandOrSubfolder": "Proširi folder / Pođi na prvi podfolder", + "title": "Panel Foldera" + }, + "keys": { + "ctrl": "Control", + "delete": "Obriši", + "downArrow": "Strelica dolje", + "escape": "Escape", + "leftArrow": "Strelica lijevo", + "question": "Upitnik", + "rightArrow": "Strelica desno", + "upArrow": "Strelica gore" + }, + "keysAbbreviations": { + "alt": "alt", + "ctrl": "ctrl", + "del": "del", + "end": "end", + "home": "home", + "shift": "shift" + } + } +} diff --git a/lib/ckfinder/lang/hu.json b/lib/ckfinder/lang/hu.json new file mode 100644 index 0000000..7b0339c --- /dev/null +++ b/lib/ckfinder/lang/hu.json @@ -0,0 +1,288 @@ +{ + "appTitle": "CKFinder", + "dir": "ltr", + "langCode": "hu", + "common": { + "abort": "Abort", + "cancel": "Mégsem", + "choose": "Válasszon", + "close": "Bezárás", + "copy": "Másolás", + "delete": "Törlés", + "download": "Letöltés", + "edit": "Szerkesztés", + "maximize": "Teljes méret", + "messageTitle": "Információ", + "minimize": "Kis méret", + "move": "Áthelyezés", + "newNameDialogTitle": "Új név", + "ok": "Rendben", + "pleaseWait": "Kérem várjon.", + "rememberDecision": "Jegyezze meg a választásomat", + "rename": "Átnevezés", + "showMore": "Mutass tübbet", + "skip": "Kihagy", + "upload": "Feltöltés", + "view": "Megtekintés" + }, + "units": { + "dateFormat": "yyyy.mm.dd. HH:MM", + "dateAmPm": [ + "de.", + "du." + ], + "kb": "{size} KB", + "mb": "{size} MB", + "gb": "{size} GB", + "sizePerSecond": "{size}/s", + "pixelShort": "px" + }, + "files": { + "autoRename": "Automatikus átnevezés", + "countMany": "{count} fájl", + "countOne": "1 fájl", + "deleteConfirmation": "Biztosan törli a kijelölt {count} fájlt?", + "fileDeleteConfirmation": "Biztosan törli a következő fájlt: \"{name}\"?", + "fileRenameExtensionConfirmation": "Biztosan szeretné módosítani a fájl kiterjesztését? A fájl használhatatlanná válhat.", + "fileRenameLabel": "Kérem adja meg a fájl új nevét: ", + "filesPaneTitle": "Files pane", + "filesRefresh": "Refreshing files", + "filterPlaceholder": "Szűrő", + "gettingFileData": "A fájl adatainak lekérdezése.", + "overwrite": "Felülír", + "loadingFilesPane": { + "title": "Betöltés...", + "text": "A fájlok betöltése megkezdődött." + }, + "emptyFilesPane": { + "title": "Ez a mappa üres.", + "text": "Használja a Feltöltés gombot, vagy húzzon ide a fájlokat." + }, + "filterFilesEmpty": { + "title": "Nincs találat.", + "text": "Kérem adjon meg más keresési feltételt." + } + }, + "folders": { + "deleteConfirmation": "Biztosan törölni szeretné a következő mappát: \"{name}\"?", + "destinationFolder": "Cél mappa", + "newNameLabel": "Kérem adja meg a mappa nevét: ", + "newSubfolder": "Új almappa", + "renameDialogTitle": "Mappa átnevezése", + "treeTitle": "Folders tree" + }, + "copy": { + "dropMenuItem": "Másolás ide", + "errorDialogTitle": "A következő fájlok nem másolhatóak:", + "manyFilesDialogTitle": "{count} fájl másolása ide...", + "manyFilesWait": "{count} fájl másolása.", + "oneFileDialogTitle": "Fájl másolása ide...", + "oneFileWait": "Fájl másolása.", + "operationLabel": "Fájlok másolása", + "operationSummary": "A másolt fájlok száma: {count}." + }, + "move": { + "dropMenuItem": "Áthelyezés ide", + "errorDialogTitle": "A következő fájlok nem helyezhetőek át:", + "manyFilesDialogTitle": "{count} fájl áthelyezése ide...", + "manyFilesWait": "{count} fájl áthelyezése.", + "oneFileDialogTitle": "Fájl áthelyezése ide...", + "oneFileWait": "Fájl áthelyezése.", + "operationLabel": "Fájlok áthelyezése", + "operationSummary": "Az áthelyezett fájlok száma: {count}." + }, + "upload": { + "addFiles": "Fájl hozzáadása", + "bytesCountProgress": "({bytesUploaded} / {bytesTotal})", + "details": "Részletek", + "filesCountProgress": "{filesUploaded} / {filesTotal}", + "progressLabel": "A feltöltés folyamatban.", + "progressMessage": "Feltöltés...", + "selectFileLabel": "Válassza ki a feltölteni kívánt fájlt", + "selectFiles": "Válassza ki a feltöltendő fájlokat", + "success": "A feltöltés befejeződött!", + "summary": "Feltöltött fájlok: {count}" + }, + "settings": { + "display": "Megjelenik:", + "displayDate": "dátum", + "displayName": "fájl neve", + "displaySize": "fájlméret", + "sortAscending": "Ascending", + "sortBy": "Sort by", + "sortByOrder": "Order", + "sortDescending": "Descending", + "thumbnailSize": "Bélyegkép méret", + "title": "Beállítások", + "viewType": "View", + "viewTypeCompact": "Compact", + "viewTypeList": "List", + "viewTypeThumbnails": "Thumbnails" + }, + "errors": { + "codes": { + "10": "Érvénytelen parancs.", + "11": "A fájl típusa nem lett a kérés során beállítva.", + "12": "A kívánt fájl típus érvénytelen.", + "13": "A kapcsolati konfiguráció érvénytelen.", + "14": "Érvénytelen kapcsolati plugin: {pluginName}.", + "102": "Érvénytelen fájl vagy könyvtárnév.", + "103": "Hitelesítési problémák miatt nem sikerült a kérést teljesíteni.", + "104": "Jogosultsági problémák miatt nem sikerült a kérést teljesíteni.", + "105": "Érvénytelen fájl kiterjesztés.", + "109": "Érvénytelen kérés.", + "110": "Ismeretlen hiba.", + "111": "A kérés nem teljesíthető a létrejövő fájl mérete miatt.", + "115": "A fálj vagy mappa már létezik ezen a néven.", + "116": "Mappa nem található. Kérem frissítsen és próbálja újra.", + "117": "Fájl nem található. Kérem frissítsen és próbálja újra.", + "118": "A forrás és a cél azonos.", + "201": "Ilyen nevű fájl már létezett. A feltöltött fájl a következőre lett átnevezve: \"{name}\".", + "202": "Érvénytelen fájl.", + "203": "Érvénytelen fájl. A fájl mérete túl nagy.", + "204": "A feltöltött fájl hibás.", + "205": "A szerveren nem található a feltöltéshez ideiglenes mappa.", + "206": "A fájl feltötése biztonsági okból megszakadt. A fájl HTML adatokat tartalmaz.", + "207": "El fichero subido ha sido renombrado como \"{name}\".", + "300": "A fájl(ok) áthelyezése sikertelen.", + "301": "A fájl(ok) másolása sikertelen.", + "302": "A fájl(ok) törlése sikertelen.", + "500": "A fájl-tallózó biztonsági okok miatt nincs engedélyezve. Kérem vegye fel a kapcsolatot a rendszer üzemeltetőjével és ellenőrizze a CKFinder konfigurációs fájlt.", + "501": "A bélyegkép támogatás nincs engedélyezve." + }, + "deleteFilePermissions": "Removing files is not allowed in this folder.", + "fileInvalidCharacters": "A fájl neve nem tartalmazhatja a következő karaktereket: {disallowedCharacters}", + "fileNameNotEmpty": "The file name cannot be empty.", + "folderInvalidCharacters": "A mappa neve nem tartalmazhatja a következő karaktereket: {disallowedCharacters}", + "incorrectExtension": "A fájl kiterjesztése nem engedélyezett ebben a mappában.", + "missingFile": "A fájl már nem létezik.", + "missingFolder": "A könyvtár már nem létezik.", + "noUploadFolderSelected": "A feltöltés előtt válasszon mappát.", + "operationCompleted": "A művelet közben hiba történt.", + "renameFilePermissions": "Renaming files is not allowed in this folder.", + "unknown": "A parancsot nem sikerült végrehajtani. (Hiba: {number})", + "unknownUploadError": "Hiba a fájl feltöltése közben.", + "uploadErrors": "A feltöltés befejeződött hibákkal.", + "uploadPermissions": "A fájlok feltöltése nem engedélyezett." + }, + "chooseResizedImage": { + "title": "Az átméretezett kiválasztása", + "originalSize": "Eredeti méret", + "sizes": { + "custom": "Egyedi", + "large": "Nagy", + "max": "Max", + "medium": "Közepes", + "small": "Kicsi" + } + }, + "editImage": { + "adjust": "Beállítások", + "apply": "Alkalmaz", + "confirmExit": "Biztosan bezárja? Még nem mentett változások fűződnek ehhez a képhez.", + "crop": "Kivágás", + "downloadAction": "Eredeti kép letöltése.", + "keepAspectRatio": "Képarány megtartása", + "loading": "Kép betöltése", + "presets": "Effektek", + "reset": "Visszaállít", + "resize": "Átméretezés", + "rotate": "Forgatás", + "rotateAntiClockwise": "90° balra", + "rotateClockwise": "90° jobbra", + "save": "Mentés", + "saveDialogFileExists": "Ilyen nevű fájl már létezik a könyvtárban.", + "saveDialogOverwrite": "Fájl felülírása", + "saveDialogSaveAs": "Mentés másként:", + "saveDialogTitle": "Módosítások mentése", + "title": "Kép szerkesztése", + "transformationAction": "Módosítások alkalmazása.", + "uploadAction": "Módosított kép feltöltése.", + "filters": { + "brightness": "Világosság", + "clip": "Kivág", + "contrast": "Kontraszt", + "exposure": "Expozíció", + "gamma": "Gamma", + "hue": "Hue", + "noise": "Zaj", + "saturation": "Telítettség", + "sepia": "Szépia", + "sharpen": "Élesség", + "stackBlur": "Homályosítás", + "vibrance": "Vibrance" + }, + "preset": { + "clarity": "Világosság", + "concentrate": "Koncentrált", + "crossProcess": "Cross Process", + "glowingSun": "Ragyogó nap", + "grungy": "Trutyis", + "hazyDays": "Ködös nap", + "hemingway": "Hemingway", + "herMajesty": "Őfelsége", + "jarques": "Jarques", + "lomo": "Lomo", + "love": "Szerelem", + "nostalgia": "Nosztalgia", + "oldBoot": "Öreg csizma", + "orangePeel": "Narancs héj", + "pinhole": "A tű foka", + "sinCity": "Sin City", + "sunrise": "Napkelte", + "vintage": "Klasszikus" + } + }, + "shortcuts": { + "title": "Billentyű-kombinációk", + "general": { + "action": "Első művelet futtatása", + "firstItem": "Ugrás az elsőhöz", + "focusFilesPane": "Összpontosítás a fájlokra", + "focusFoldersPane": "Összpontosítás a mappákra vagy útvonalra", + "focusNext": "Összpontosítás a következőre", + "focusToolbar": "Összpontosítás az eszköztárra", + "lastItem": "Ugrás az utolsóhoz", + "listShortcuts": "Súgó megnyitása", + "nextItem": "Ugrás a következőre", + "previousItem": "Ugrás az előzőre", + "showContextMenu": "Kontextus menü megnyitása", + "title": "Általános" + }, + "files": { + "addToSelectionAbove": "Add or remove files above to selection", + "addToSelectionBelow": "Add or remove files below to selection", + "addToSelectionLeft": "Add or remove file on the left to selection", + "addToSelectionRight": "Add or remove file on the right to selection", + "delete": "Fájlok törlése", + "refresh": "Frissítés", + "rename": "Fájl átnevezése", + "selectAll": "Minden kijelölése", + "upload": "Feltöltés" + }, + "folders": { + "collapseOrParent": "Mappa összetűzése / Ugrás a szülőkönyvtárba", + "delete": "Mappa törlése", + "expandOrSubfolder": "Mappa kibontása / Ugrás az első almappába", + "title": "Mappák" + }, + "keys": { + "ctrl": "Control", + "delete": "Delete", + "downArrow": "Le", + "escape": "Escape", + "leftArrow": "Bal", + "question": "Kérdőjel", + "rightArrow": "Jobb", + "upArrow": "Fel" + }, + "keysAbbreviations": { + "alt": "alt", + "ctrl": "ctrl", + "del": "del", + "end": "end", + "home": "home", + "shift": "shift" + } + } +} diff --git a/lib/ckfinder/lang/it.json b/lib/ckfinder/lang/it.json new file mode 100644 index 0000000..867701e --- /dev/null +++ b/lib/ckfinder/lang/it.json @@ -0,0 +1,288 @@ +{ + "appTitle": "CKFinder", + "dir": "ltr", + "langCode": "it", + "common": { + "abort": "Interrompi", + "cancel": "Annulla", + "choose": "Seleziona", + "close": "Chiudi", + "copy": "Copia", + "delete": "Elimina", + "download": "Scarica", + "edit": "Modifica", + "maximize": "Ingrandisci", + "messageTitle": "Informazione", + "minimize": "Riduci", + "move": "Sposta", + "newNameDialogTitle": "Nuovo nome", + "ok": "OK", + "pleaseWait": "Attendere.", + "rememberDecision": "Ricorda decisione", + "rename": "Rinomina", + "showMore": "Mostra altro", + "skip": "Salta", + "upload": "Carica", + "view": "Vedi" + }, + "units": { + "dateFormat": "dd/mm/yyyy HH:MM", + "dateAmPm": [ + "AM", + "PM" + ], + "kb": "{size} KB", + "mb": "{size} MB", + "gb": "{size} GB", + "sizePerSecond": "{size}/s", + "pixelShort": "px" + }, + "files": { + "autoRename": "Rinomina automaticamente", + "countMany": "{count} file", + "countOne": "1 file", + "deleteConfirmation": "Eliminare {count} file?", + "fileDeleteConfirmation": "Eliminare il file \"{name}\"?", + "fileRenameExtensionConfirmation": "Cambiare l'estensione del file? Il file può risultare inutilizzabile.", + "fileRenameLabel": "Nuovo nome del file: ", + "filesPaneTitle": "Pannello file", + "filesRefresh": "Aggiornamento dei file", + "filterPlaceholder": "Filtro", + "gettingFileData": "Recupero dei dati del file.", + "overwrite": "Sovrascrivi", + "loadingFilesPane": { + "title": "Caricamento...", + "text": "i file vengono caricati." + }, + "emptyFilesPane": { + "title": "La cartella è vuota.", + "text": "Usare il pulsante Carica oppure trascinare qui i propri file." + }, + "filterFilesEmpty": { + "title": "Non è stato trovato nulla.", + "text": "Riprovare con criteri di ricerca differenti." + } + }, + "folders": { + "deleteConfirmation": "Eliminare la cartella \"{name}\"?", + "destinationFolder": "Cartella di destinazione", + "newNameLabel": "Nome della cartella: ", + "newSubfolder": "Nuova sotto-cartella", + "renameDialogTitle": "Rinomina cartella", + "treeTitle": "Albero cartelle" + }, + "copy": { + "dropMenuItem": "Copia qui", + "errorDialogTitle": "File che non è possibile copiare:", + "manyFilesDialogTitle": "Copia {count} file in...", + "manyFilesWait": "Copia di {count} file in corso.", + "oneFileDialogTitle": "Copia il file in...", + "oneFileWait": "Copia del file in corso.", + "operationLabel": "Copia dei file", + "operationSummary": "Numero di file copiati: {count}." + }, + "move": { + "dropMenuItem": "Sposta qui", + "errorDialogTitle": "File che non è possibile spostare:", + "manyFilesDialogTitle": "Sposta {count} file in...", + "manyFilesWait": "Spostamento di {count} file in corso.", + "oneFileDialogTitle": "Sposta il file in...", + "oneFileWait": "Spostamento del file in corso.", + "operationLabel": "Spostamento dei file", + "operationSummary": "Numero di file spostati: {count}." + }, + "upload": { + "addFiles": "Aggiungi file", + "bytesCountProgress": "({bytesUploaded} di {bytesTotal})", + "details": "Dettagli", + "filesCountProgress": "{filesUploaded} di {filesTotal}", + "progressLabel": "caricamento in corso.", + "progressMessage": "Caricamento in corso...", + "selectFileLabel": "Selezionare un file da caricare", + "selectFiles": "Selezionare i file da caricare", + "success": "Caricamento completato!", + "summary": "File caricati: {count}" + }, + "settings": { + "display": "Informazioni:", + "displayDate": "Data", + "displayName": "Nome del file", + "displaySize": "Dimensioni", + "sortAscending": "Crescente", + "sortBy": "Ordina per", + "sortByOrder": "Ordine", + "sortDescending": "Decrescente", + "thumbnailSize": "Dimensioni miniatura", + "title": "Impostazioni", + "viewType": "Vista", + "viewTypeCompact": "Compact", + "viewTypeList": "Lista", + "viewTypeThumbnails": "Miniature" + }, + "errors": { + "codes": { + "10": "Comando non valido.", + "11": "Il tipo di risorsa non è stato specificato nella richiesta.", + "12": "Il tipo di risorsa richiesto non è valido.", + "13": "La configurazione del connettore non è valida.", + "14": "Estensione del connettore non valida: {pluginName}.", + "102": "Il nome del file o della cartella non è valido.", + "103": "Non è stato possibile completare la richiesta a causa di restrizioni di autorizzazione.", + "104": "Non è stato possibile completare la richiesta a causa di restrizioni nei permessi del file system.", + "105": "L'estensione del file non è valida.", + "109": "Richiesta non valida.", + "110": "Errore sconosciuto.", + "111": "Non è stato possibile completare la richiesta a causa della dimensione finale del file.", + "115": "Esiste già un file o una cartella con lo stesso nome.", + "116": "Cartella non trovata. Aggiornare e riprovare.", + "117": "File non trovato. Aggiornare la lista dei file e riprovare.", + "118": "Il percorso di origine e quello di destinazione sono uguali.", + "201": "Un file con lo stesso nome esiste già. Il file caricato è stato rinominato in \"{name}\".", + "202": "File non valido.", + "203": "File non valido. Il file è troppo grande.", + "204": "Il file caricato è corrotto.", + "205": "Non è disponibile alcuna cartella temporanea per il caricamento dei file sul server.", + "206": "Caricamento annullato per motivi di sicurezza. Il file contiene dati in formato HTML.", + "207": "Il file caricato è stato rinominato in \"{name}\".", + "300": "Non è stato possibile spostare i file.", + "301": "Non è stato possibile copiare i file.", + "302": "Non è stato possibile eliminare i file.", + "500": "Il gestore dei file è disabilitato per motivi di sicurezza. Contattare l'amministratore del sistema e verificare la configurazione di CKFinder.", + "501": "Il supporto alle miniature non è attivo." + }, + "deleteFilePermissions": "Removing files is not allowed in this folder.", + "fileInvalidCharacters": "I seguenti caratteri non possono essere usati per comporre il nome del file: {disallowedCharacters}", + "fileNameNotEmpty": "Il nome del file non può essere vuoto.", + "folderInvalidCharacters": "I seguenti caratteri non possono essere usati per comporre il nome della cartella: {disallowedCharacters}", + "incorrectExtension": "In questa cartella non sono permessi file con questa estensione.", + "missingFile": "Il file richiesto non è più disponibile.", + "missingFolder": "La cartella che si sta cercando di raggiungere non è più disponibile.", + "noUploadFolderSelected": "Selezionare la cartella prima di caricare i file.", + "operationCompleted": "L'operazione è stata completata con errori.", + "renameFilePermissions": "Renaming files is not allowed in this folder.", + "unknown": "Non è stato possibile completare la richiesta (errore {number}).", + "unknownUploadError": "Errore durante il caricamento del file.", + "uploadErrors": "Caricamento completato con errori.", + "uploadPermissions": "Il caricamento dei file non è permesso." + }, + "chooseResizedImage": { + "title": "Seleziona miniatura", + "originalSize": "Dimensioni originali", + "sizes": { + "custom": "Personalizzata", + "large": "Grande", + "max": "Max", + "medium": "Media", + "small": "Piccola" + } + }, + "editImage": { + "adjust": "Correggi", + "apply": "Applica", + "confirmExit": "Si è certi di voler chiudere? Sono state apportate delle modifiche all'immagine che non sono ancora state salvate.", + "crop": "Ritaglia", + "downloadAction": "Scaricamento dell'immagine originale.", + "keepAspectRatio": "Mantieni il rapporto di forma", + "loading": "Caricamento dell'immagine", + "presets": "Combinazioni", + "reset": "Reimposta", + "resize": "Ridimensiona", + "rotate": "Ruota", + "rotateAntiClockwise": "90° anti-orari", + "rotateClockwise": "90° orari", + "save": "Salva", + "saveDialogFileExists": "Un file con lo stesso nome esiste già nella cartella.", + "saveDialogOverwrite": "Sovrascrivi file", + "saveDialogSaveAs": "Salva con nome:", + "saveDialogTitle": "Salva modifiche", + "title": "Modifica immagine", + "transformationAction": "Applicazione delle trasformazioni.", + "uploadAction": "Caricamento dell'immagine modificata.", + "filters": { + "brightness": "Luminosità", + "clip": "Ritaglio", + "contrast": "Contrasto", + "exposure": "Esposizione", + "gamma": "Gamma", + "hue": "Tinta", + "noise": "Rumore", + "saturation": "Saturazione", + "sepia": "Seppia", + "sharpen": "Migliora contorni", + "stackBlur": "Sfocatura", + "vibrance": "Brillantezza" + }, + "preset": { + "clarity": "Limpidezza", + "concentrate": "Concentra", + "crossProcess": "Interprocesso", + "glowingSun": "Sole brillante", + "grungy": "Sporco", + "hazyDays": "Giorni sfocati", + "hemingway": "Hemingway", + "herMajesty": "Sua Maestà", + "jarques": "Jarques", + "lomo": "Lomo", + "love": "Amore", + "nostalgia": "Nostalgia", + "oldBoot": "Vecchio stivale", + "orangePeel": "Buccia d'arancia", + "pinhole": "Forellino", + "sinCity": "Sin City", + "sunrise": "Alba", + "vintage": "Vintage" + } + }, + "shortcuts": { + "title": "Tasti rapidi", + "general": { + "action": "Esegui azione predefinita", + "firstItem": "Vai al primo elemento", + "focusFilesPane": "Attiva pannello dei file", + "focusFoldersPane": "Attiva pannello delle cartelle o breadcrumb", + "focusNext": "Attiva pannello successivo", + "focusToolbar": "Attiva barra degli strumenti", + "lastItem": "Vai all'ultimo elemento", + "listShortcuts": "Apri questa finestra d'aiuto", + "nextItem": "Vai all'elemento successivo", + "previousItem": "Vai all'elemento precedente", + "showContextMenu": "Apri menù contestuale", + "title": "Interfaccia generale" + }, + "files": { + "addToSelectionAbove": "Aggiungi o rimuovi file sopra la selezione", + "addToSelectionBelow": "Aggiungi o rimuovi file sotto la selezione", + "addToSelectionLeft": "Aggiungi o rimuovi file a sinistra della selezione", + "addToSelectionRight": "Aggiungi o rimuovi file a destra della selezione", + "delete": "Elimina file", + "refresh": "Aggiorna file", + "rename": "Rinomina file", + "selectAll": "Seleziona tutti i file", + "upload": "Carica file" + }, + "folders": { + "collapseOrParent": "Comprimi cartella / Vai alla cartella padre", + "delete": "Elimina cartella", + "expandOrSubfolder": "Espandi cartella / Vai alla prima sotto-cartella", + "title": "Pannello delle cartelle" + }, + "keys": { + "ctrl": "Control", + "delete": "Canc", + "downArrow": "Freccia giù", + "escape": "Esc", + "leftArrow": "Freccia sinistra", + "question": "Punto di domanda", + "rightArrow": "Freccia destra", + "upArrow": "Freccia su" + }, + "keysAbbreviations": { + "alt": "alt", + "ctrl": "ctrl", + "del": "canc", + "end": "fine", + "home": "inizio", + "shift": "shift" + } + } +} diff --git a/lib/ckfinder/lang/ja.json b/lib/ckfinder/lang/ja.json new file mode 100644 index 0000000..d01ef46 --- /dev/null +++ b/lib/ckfinder/lang/ja.json @@ -0,0 +1,288 @@ +{ + "appTitle": "CKFinder", + "dir": "ltr", + "langCode": "ja", + "common": { + "abort": "Abort", + "cancel": "キャンセル", + "choose": "Choose", + "close": "閉じる", + "copy": "Copy", + "delete": "削除", + "download": "ダウンロード", + "edit": "編集", + "maximize": "最大化", + "messageTitle": "インフォメーション", + "minimize": "最小化", + "move": "Move", + "newNameDialogTitle": "新しい名前", + "ok": "OK", + "pleaseWait": "Please wait.", + "rememberDecision": "全てに適用する", + "rename": "ファイル名の変更", + "showMore": "Show more", + "skip": "スキップ", + "upload": "アップロード", + "view": "画像だけを表示" + }, + "units": { + "dateFormat": "m/d/yyyy h:MM aa", + "dateAmPm": [ + "AM", + "PM" + ], + "kb": "{size} KB", + "mb": "{size} MB", + "gb": "{size} GB", + "sizePerSecond": "{size}/s", + "pixelShort": "px" + }, + "files": { + "autoRename": "自動でリネーム", + "countMany": "{count}個のファイル", + "countOne": "1つのファイル", + "deleteConfirmation": "これらの {count} つのファイルを削除してもよろしいですか? ", + "fileDeleteConfirmation": "本当に「\"{name}\"」を削除してもよろしいですか?", + "fileRenameExtensionConfirmation": "ファイルが使えなくなる可能性がありますが、本当に拡張子を変更してもよろしいですか?", + "fileRenameLabel": "新しいファイル名を入力してください: ", + "filesPaneTitle": "Files pane", + "filesRefresh": "Refreshing files", + "filterPlaceholder": "Filter", + "gettingFileData": "Getting file data.", + "overwrite": "上書き", + "loadingFilesPane": { + "title": "Loading...", + "text": "The files are being loaded." + }, + "emptyFilesPane": { + "title": "The folder is empty.", + "text": "Use the Upload button or drag and drop your files here." + }, + "filterFilesEmpty": { + "title": "Nothing found.", + "text": "Please try using different search criteria." + } + }, + "folders": { + "deleteConfirmation": "本当にフォルダ「\"{name}\"」を削除してもよろしいですか?", + "destinationFolder": "適用するフォルダ", + "newNameLabel": "新しいフォルダ名を入力してください: ", + "newSubfolder": "新しいフォルダに入れる", + "renameDialogTitle": "Rename Folder", + "treeTitle": "Folders tree" + }, + "copy": { + "dropMenuItem": "コピーするファイルをここにドロップしてください", + "errorDialogTitle": "Files that cannot be copied:", + "manyFilesDialogTitle": "Copy {count} Files To...", + "manyFilesWait": "Copying {count} files.", + "oneFileDialogTitle": "Copy File To...", + "oneFileWait": "Copying file.", + "operationLabel": "Copying Files", + "operationSummary": "Number of files copied: {count}." + }, + "move": { + "dropMenuItem": "移動するファイルをここにドロップしてください", + "errorDialogTitle": "Files that cannot be moved:", + "manyFilesDialogTitle": "Move {count} Files To...", + "manyFilesWait": "Moving {count} files.", + "oneFileDialogTitle": "Move File To...", + "oneFileWait": "Moving file.", + "operationLabel": "Moving Files", + "operationSummary": "Number of files moved: {count}." + }, + "upload": { + "addFiles": "ファイルを追加", + "bytesCountProgress": "({bytesUploaded} of {bytesTotal})", + "details": "Details", + "filesCountProgress": "{filesUploaded} of {filesTotal}", + "progressLabel": "ファイルのアップロード中...", + "progressMessage": "Uploading...", + "selectFileLabel": "アップロードするファイルを選択してください", + "selectFiles": "Select files to upload", + "success": "Upload finished!", + "summary": "Uploaded files: {count}" + }, + "settings": { + "display": "表示する項目:", + "displayDate": "日時", + "displayName": "ファイル名", + "displaySize": "ファイルサイズ", + "sortAscending": "Ascending", + "sortBy": "Sort by", + "sortByOrder": "Order", + "sortDescending": "Descending", + "thumbnailSize": "Thumbnail Size", + "title": "カスタマイズ", + "viewType": "View", + "viewTypeCompact": "Compact", + "viewTypeList": "List", + "viewTypeThumbnails": "Thumbnails" + }, + "errors": { + "codes": { + "10": "不正なコマンドです。", + "11": "リソースタイプが特定できませんでした。", + "12": "要求されたリソースのタイプが正しくありません。", + "13": "The connector configuration file is invalid.", + "14": "Invalid connector plugin: {pluginName}.", + "102": "ファイル名/フォルダ名が正しくありません。", + "103": "リクエストを完了できませんでした。認証エラーです。", + "104": "リクエストを完了できませんでした。ファイルのパーミッションが許可されていません。", + "105": "拡張子が正しくありません。", + "109": "不正なリクエストです。", + "110": "不明なエラーが発生しました。", + "111": "It was not possible to complete the request due to resulting file size.", + "115": "同じ名前のファイル/フォルダがすでに存在しています。", + "116": "フォルダが見つかりませんでした。ページを更新して再度お試し下さい。", + "117": "ファイルが見つかりませんでした。ページを更新して再度お試し下さい。", + "118": "対象が移動元と同じ場所を指定されています。", + "201": "同じ名前のファイルがすでに存在しています。\"{name}\" にリネームして保存されました。", + "202": "不正なファイルです。", + "203": "ファイルのサイズが大きすぎます。", + "204": "アップロードされたファイルは壊れています。", + "205": "サーバ内の一時作業フォルダが利用できません。", + "206": "セキュリティ上の理由からアップロードが取り消されました。このファイルにはHTMLに似たデータが含まれています。", + "207": "ファイルは \"{name}\" にリネームして保存されました。", + "300": "ファイルの移動に失敗しました。", + "301": "ファイルのコピーに失敗しました。", + "302": "Deleting file(s) failed.", + "500": "ファイルブラウザはセキュリティ上の制限から無効になっています。システム担当者に連絡をして、CKFinderの設定をご確認下さい。", + "501": "サムネイル機能は無効になっています。" + }, + "deleteFilePermissions": "Removing files is not allowed in this folder.", + "fileInvalidCharacters": "ファイルに以下の文字は使えません: {disallowedCharacters}", + "fileNameNotEmpty": "The file name cannot be empty.", + "folderInvalidCharacters": "フォルダに以下の文字は使えません: {disallowedCharacters}", + "incorrectExtension": "選択されたファイルの拡張子は許可されていません。", + "missingFile": "The requested file is no longer available.", + "missingFolder": "The folder you are trying to reach is no longer available.", + "noUploadFolderSelected": "アップロードの前にフォルダを選択してください。", + "operationCompleted": "Operation completed with errors.", + "renameFilePermissions": "Renaming files is not allowed in this folder.", + "unknown": "リクエストの処理に失敗しました。 (Error {number})", + "unknownUploadError": "ファイルの送信に失敗しました。", + "uploadErrors": "Upload finished with errors.", + "uploadPermissions": "ファイルのアップロード権限がありません。" + }, + "chooseResizedImage": { + "title": "Choose Resized", + "originalSize": "Original Size", + "sizes": { + "custom": "Custom", + "large": "Large", + "max": "Max", + "medium": "Medium", + "small": "Small" + } + }, + "editImage": { + "adjust": "Adjust", + "apply": "Apply", + "confirmExit": "Are you sure you want to close? You have unsaved changes to the image.", + "crop": "Crop", + "downloadAction": "Downloading original image.", + "keepAspectRatio": "Keep Aspect Ratio", + "loading": "Loading image", + "presets": "Presets", + "reset": "Reset", + "resize": "Resize", + "rotate": "Rotate", + "rotateAntiClockwise": "90° Left", + "rotateClockwise": "90° Right", + "save": "Save", + "saveDialogFileExists": "File with the same name already exists in folder.", + "saveDialogOverwrite": "Overwrite File", + "saveDialogSaveAs": "Save as:", + "saveDialogTitle": "Save Changes", + "title": "Edit Image", + "transformationAction": "Applying transformations.", + "uploadAction": "Uploading edited image.", + "filters": { + "brightness": "Brightness", + "clip": "Clip", + "contrast": "Contrast", + "exposure": "Exposure", + "gamma": "Gamma", + "hue": "Hue", + "noise": "Noise", + "saturation": "Saturation", + "sepia": "Sepia", + "sharpen": "Sharpen", + "stackBlur": "Blur", + "vibrance": "Vibrance" + }, + "preset": { + "clarity": "Clarity", + "concentrate": "Concentrate", + "crossProcess": "Cross Process", + "glowingSun": "Glowing Sun", + "grungy": "Grungy", + "hazyDays": "Hazy Days", + "hemingway": "Hemingway", + "herMajesty": "Her Majesty", + "jarques": "Jarques", + "lomo": "Lomo", + "love": "Love", + "nostalgia": "Nostalgia", + "oldBoot": "Old Boot", + "orangePeel": "Orange Peel", + "pinhole": "Pinhole", + "sinCity": "Sin City", + "sunrise": "Sunrise", + "vintage": "Vintage" + } + }, + "shortcuts": { + "title": "Keyboard Shortcuts", + "general": { + "action": "Execute default action", + "firstItem": "Go to first item", + "focusFilesPane": "Focus files pane", + "focusFoldersPane": "Focus folders pane or breadcrumbs", + "focusNext": "Focus next pane", + "focusToolbar": "Focus toolbar", + "lastItem": "Go to last item", + "listShortcuts": "Open this help dialog", + "nextItem": "Go to next item", + "previousItem": "Go to previous item", + "showContextMenu": "Open context menu", + "title": "General Interface" + }, + "files": { + "addToSelectionAbove": "Add or remove files above to selection", + "addToSelectionBelow": "Add or remove files below to selection", + "addToSelectionLeft": "Add or remove file on the left to selection", + "addToSelectionRight": "Add or remove file on the right to selection", + "delete": "Delete file(s)", + "refresh": "Refresh files", + "rename": "Rename file", + "selectAll": "Select all files", + "upload": "Upload file(s)" + }, + "folders": { + "collapseOrParent": "Collapse folder / Go to parent folder", + "delete": "Delete folder", + "expandOrSubfolder": "Expand folder / Go to first subfolder", + "title": "Folders Pane" + }, + "keys": { + "ctrl": "Control", + "delete": "Delete", + "downArrow": "Down arrow", + "escape": "Escape", + "leftArrow": "Left arrow", + "question": "Question mark", + "rightArrow": "Right arrow", + "upArrow": "Up arrow" + }, + "keysAbbreviations": { + "alt": "alt", + "ctrl": "ctrl", + "del": "del", + "end": "end", + "home": "home", + "shift": "shift" + } + } +} diff --git a/lib/ckfinder/lang/ko.json b/lib/ckfinder/lang/ko.json new file mode 100644 index 0000000..f61fd47 --- /dev/null +++ b/lib/ckfinder/lang/ko.json @@ -0,0 +1,288 @@ +{ + "appTitle": "CKFinder", + "dir": "ltr", + "langCode": "ko", + "common": { + "abort": "중단", + "cancel": "취소", + "choose": "선택", + "close": "닫기", + "copy": "복사", + "delete": "삭제", + "download": "다운로드", + "edit": "수정", + "maximize": "최대화", + "messageTitle": "정보", + "minimize": "최소화", + "move": "이동", + "newNameDialogTitle": "새로운 이름", + "ok": "OK", + "pleaseWait": "잠시만 기다려주세요.", + "rememberDecision": "내 선택 기억", + "rename": "이름 바꾸기", + "showMore": "더보기", + "skip": "건너뛰기", + "upload": "업로드", + "view": "보기" + }, + "units": { + "dateFormat": "yyyy/m/d aa h:MM", + "dateAmPm": [ + "오전", + "오후" + ], + "kb": "{size} KB", + "mb": "{size} MB", + "gb": "{size} GB", + "sizePerSecond": "{size}/초", + "pixelShort": "px" + }, + "files": { + "autoRename": "자동 이름변경", + "countMany": "{count} 파일들", + "countOne": "1 파일", + "deleteConfirmation": "정말 {count} 파일들을 삭제하시겠습니까?", + "fileDeleteConfirmation": "정말 \"{name}\" 파일을 삭제하시겠습니까?", + "fileRenameExtensionConfirmation": "정말 파일 확장자를 변경하시겠습니까? 파일을 사용할 수 없게 될 수 있습니다.", + "fileRenameLabel": "새로운 파일 이름을 입력해 주십시오: ", + "filesPaneTitle": "파일 판", + "filesRefresh": "파일 새로고침", + "filterPlaceholder": "필터", + "gettingFileData": "파일을 가져오고 있습니다.", + "overwrite": "덮어쓰기", + "loadingFilesPane": { + "title": "불러오는 중...", + "text": "해당 파일들이 로딩 중입니다." + }, + "emptyFilesPane": { + "title": "폴더가 비어있습니다..", + "text": "업로드 버튼을 이용하거나 파일을 이곳에 드레그&드롭 하십시오." + }, + "filterFilesEmpty": { + "title": "아무것도 찾지 못하였습니다.", + "text": "다른 검색어를 사용해 주십시오." + } + }, + "folders": { + "deleteConfirmation": "정말 \"{name}\" 폴더를 삭제하시겠습니까?", + "destinationFolder": "목적지 폴더", + "newNameLabel": "새로운 폴더 이름을 입력해 주십시오: ", + "newSubfolder": "New Subfolder", + "renameDialogTitle": "폴더 이름 바꾸기", + "treeTitle": "폴더 트리" + }, + "copy": { + "dropMenuItem": "여기에 복사", + "errorDialogTitle": "복사에 실패한 파일들:", + "manyFilesDialogTitle": "다음으로 {count} 개 파일 복사...", + "manyFilesWait": "{count} 개 파일을 이동 중입니다.", + "oneFileDialogTitle": "다음으로 파일 복사...", + "oneFileWait": "파일을 복사 중입니다.", + "operationLabel": "파일 복사 중", + "operationSummary": "복사된 파일의 수: {count}." + }, + "move": { + "dropMenuItem": "여기로 이동", + "errorDialogTitle": "이동에 실패한 파일들:", + "manyFilesDialogTitle": "다음으로 {count} 개 파일 이동...", + "manyFilesWait": "{count} 개 파일을 이동 중입니다.", + "oneFileDialogTitle": "다음으로 파일 이동...", + "oneFileWait": "파일을 이동 중입니다.", + "operationLabel": "파일 이동 중", + "operationSummary": "이동된 파일의 수: {count}." + }, + "upload": { + "addFiles": "파일 추가", + "bytesCountProgress": "({bytesUploaded} / {bytesTotal})", + "details": "자세히", + "filesCountProgress": "{filesUploaded} / {filesTotal}", + "progressLabel": "업로드가 진행 중입니다.", + "progressMessage": "업로드 중...", + "selectFileLabel": "업로드할 파일을 선택해 주십시오", + "selectFiles": "업로드할 파일을 선택해 주십시오", + "success": "업로드 완료!", + "summary": "업로드된 파일: {count}" + }, + "settings": { + "display": "표시", + "displayDate": "날짜", + "displayName": "파일 이름", + "displaySize": "파일 크기", + "sortAscending": "Ascending", + "sortBy": "Sort by", + "sortByOrder": "Order", + "sortDescending": "Descending", + "thumbnailSize": "미리 보기 크기", + "title": "설정", + "viewType": "View", + "viewTypeCompact": "Compact", + "viewTypeList": "List", + "viewTypeThumbnails": "Thumbnails" + }, + "errors": { + "codes": { + "10": "올바르지 않은 명령.", + "11": "요청에서 리소스 유형이 특정되지 않았습니다.", + "12": "요청한 리소스 유형이 올바르지 않습니다.", + "13": "연결 설정 파일이 올바르지 않습니다.", + "14": "올바르지 않은 연결 플러그인: {pluginName}.", + "102": "올바르지 않은 파일 또는 폴더 이름.", + "103": "인증 제한 때문에 작업을 완료할 수 없었습니다.", + "104": "파일 시스템 권한 제한 때문에 작업을 완료할 수 없었습니다.", + "105": "올바르지 않은 파일 확장자.", + "109": "올바르지 않은 요청.", + "110": "알 수 없는 오류.", + "111": "파일 크기 때문에 요청을 완료할 수 없습니다.", + "115": "이미 같은 이름의 파일이나 폴더가 존재합니다.", + "116": "폴더를 찾지 못하였습니다. 새로고침을 해 보시고 다시 시도해 주십시오.", + "117": "파일을 찾지 못하였습니다. 새로고침을 해 보시고 다시 시도해 주십시오.", + "118": "원본 폴더와 대상 폴더가 동일합니다.", + "201": "이미 같은 이름의 파일이 존재합니다. 해당 업로드 파일의 이름이 \"{name}\" 로 변경되었습니다.", + "202": "올바르지 않은 파일.", + "203": "올바르지 않은 파일. 파일 용량이 너무 큽니다.", + "204": "업로드한 파일이 손상되어 있습니다.", + "205": "서버에 업로드를 위한 임시 폴더가 사용가능하지 않습니다.", + "206": "보안상의 이유로 업로드가 중단되었습니다. 해당 파일은 HTML 같은 데이터가 포함되어 있습니다.", + "207": "업로드한 파일의 이름이 \"{name}\" 로 변경되었습니다.", + "300": "파일 이동 실패.", + "301": "파일 복사 실패.", + "302": "파일 삭제 실패.", + "500": "파일 브라우저가 보안상의 이유로 비활성화 되어있습니다. 당신의 시스템 관리자에게 연락을 해 보시고 CKFinder의 설정 파일을 확인해 주십시오.", + "501": "미리 보기 지원이 비활성화 되어 있습니다." + }, + "deleteFilePermissions": "Removing files is not allowed in this folder.", + "fileInvalidCharacters": "파일 이름은 다음 글자중 어떠한것도 포함되지 않아야 됩니다: {disallowedCharacters}", + "fileNameNotEmpty": "The file name cannot be empty.", + "folderInvalidCharacters": "폴더 이름은 다음 글자중 어떠한것도 포함되지 않아야 됩니다: {disallowedCharacters}", + "incorrectExtension": "이 폴더에서는 해당 파일 확장자가 허용되지 않습니다.", + "missingFile": "요청한 파일에 더이상 접근할 수 없습니다.", + "missingFolder": "도달하려는 폴더에 더이상 접근할 수 없습니다.", + "noUploadFolderSelected": "업로드를 하기전에 폴더를 선택해 주십시오.", + "operationCompleted": "오류와 함께 작업을 마쳤습니다.", + "renameFilePermissions": "Renaming files is not allowed in this folder.", + "unknown": "요청을 완료할 수 없었습니다. (오류 {number})", + "unknownUploadError": "파일 전송 중 오류.", + "uploadErrors": "오류와 함께 업로드가 완료되었습니다.", + "uploadPermissions": "파일 업로드가 허용되지 않습니다." + }, + "chooseResizedImage": { + "title": "크기조절 및 선택", + "originalSize": "원본 크기", + "sizes": { + "custom": "사용자 정의", + "large": "큼", + "max": "최대", + "medium": "보통", + "small": "작음" + } + }, + "editImage": { + "adjust": "조절", + "apply": "적용", + "confirmExit": "정말 닫으시겠습니까? 저장되지 않은 이미지 수정 사항이 있습니다.", + "crop": "자르기", + "downloadAction": "원본 이미지 다운로드 중.", + "keepAspectRatio": "화면 비율 유지", + "loading": "이미지 로딩 중", + "presets": "사전값", + "reset": "초기화", + "resize": "크기변경", + "rotate": "회전", + "rotateAntiClockwise": "왼쪽으로 90°", + "rotateClockwise": "오른쪽으로 90°", + "save": "저장", + "saveDialogFileExists": "같은 이름의 파일이 폴더내에 존재합니다.", + "saveDialogOverwrite": "파일 덮어쓰기", + "saveDialogSaveAs": "다음으로 저장:", + "saveDialogTitle": "바뀐사항 저장", + "title": "이미지 수정", + "transformationAction": "변환 적용 중.", + "uploadAction": "수정된 이미지 업로드 중.", + "filters": { + "brightness": "밝기", + "clip": "클리핑", + "contrast": "명암", + "exposure": "노출", + "gamma": "감마", + "hue": "색조", + "noise": "노이즈", + "saturation": "채도", + "sepia": "세피아", + "sharpen": "선명도", + "stackBlur": "흐리게", + "vibrance": "활기" + }, + "preset": { + "clarity": "선명하게", + "concentrate": "정광", + "crossProcess": "크로스 프로세스", + "glowingSun": "은은한 햇살", + "grungy": "그런지", + "hazyDays": "흐린 날", + "hemingway": "헤밍웨이", + "herMajesty": "여왕 폐하", + "jarques": "쟈크 필터", + "lomo": "로모", + "love": "사랑", + "nostalgia": "향수", + "oldBoot": "낡은 장화", + "orangePeel": "오렌지 껍질", + "pinhole": "바늘구멍", + "sinCity": "씬시티", + "sunrise": "해돋이", + "vintage": "빈티지" + } + }, + "shortcuts": { + "title": "키보드 단축키", + "general": { + "action": "기본 동작 실행", + "firstItem": "첫 항목으로 이동", + "focusFilesPane": "파일 판 보기", + "focusFoldersPane": "폴더 판 또는 빵가루 보기", + "focusNext": "다음 판 보기", + "focusToolbar": "툴바 보기", + "lastItem": "마지막 항목으로 이동", + "listShortcuts": "이 도움말 상자 열기", + "nextItem": "다음 항목으로 이동", + "previousItem": "이전 항목으로 이동", + "showContextMenu": "대화 상자 열기", + "title": "일반 인터페이스" + }, + "files": { + "addToSelectionAbove": "위쪽 파일을 추가하거나 제거하여 선택", + "addToSelectionBelow": "아래쪽 파일을 추가하거나 제거하여 선택", + "addToSelectionLeft": "왼쪽에 파일을 추가하거나 제거하여 선택", + "addToSelectionRight": "오른쪽에 파일을 추가하거나 제거하여 선택", + "delete": "파일 삭제", + "refresh": "파일 새로고침", + "rename": "파일 이름 바꾸기", + "selectAll": "전체 파일 선택", + "upload": "파일 업로드" + }, + "folders": { + "collapseOrParent": "폴더 줄이기 / 상위 폴더로 이동", + "delete": "폴더 삭제", + "expandOrSubfolder": "폴더 펼치기 / 첫 하위 폴더로 이동", + "title": "폴더 판" + }, + "keys": { + "ctrl": "Ctrl 키", + "delete": "Delete 키", + "downArrow": "아래 화살표", + "escape": "Esc 키", + "leftArrow": "왼쪽 화살표", + "question": "물음표", + "rightArrow": "오른쪽 화살표", + "upArrow": "위쪽 화살표" + }, + "keysAbbreviations": { + "alt": "alt", + "ctrl": "ctrl", + "del": "del", + "end": "end", + "home": "home", + "shift": "shift" + } + } +} diff --git a/lib/ckfinder/lang/ku.json b/lib/ckfinder/lang/ku.json new file mode 100644 index 0000000..f815b95 --- /dev/null +++ b/lib/ckfinder/lang/ku.json @@ -0,0 +1,288 @@ +{ + "appTitle": "CKFinder دۆزەرەوەی", + "dir": "rtl", + "langCode": "ku", + "common": { + "abort": "لە باربردن", + "cancel": "هەڵوەشاندن", + "choose": "هەڵبژێرە", + "close": "دابخە", + "copy": "کۆپی", + "delete": "بیسڕەوە", + "download": "داگرتن", + "edit": "دەسکاری", + "maximize": "گەورەکردن", + "messageTitle": "زانیاری", + "minimize": "بچوکردن", + "move": "بگوازەوە", + "newNameDialogTitle": "ناوی نوێ", + "ok": "OK", + "pleaseWait": "تکایە چاوەڕوانبە.", + "rememberDecision": "بڕیارەکەم بیر بهێنەوە", + "rename": "دووبارەناوگۆڕین", + "showMore": "زیاتر پیشانبدە", + "skip": "تێپەڕاندن", + "upload": "بارکردن", + "view": "دیتن" + }, + "units": { + "dateFormat": "yyyy/mm/dd h:MM aa", + "dateAmPm": [ + "بەیانی", + "ئێوارە" + ], + "kb": "{size} KB", + "mb": "{size} MB", + "gb": "{size} GB", + "sizePerSecond": "{size}/s", + "pixelShort": "پیلس؛" + }, + "files": { + "autoRename": "دووبارەناوگۆڕینی خۆکارانە", + "countMany": "{count} پەڕگە", + "countOne": "1 پەڕگە", + "deleteConfirmation": "تۆ دڵنیای لە سڕینەوەی ئەم {count} پەڕگەیە؟?", + "fileDeleteConfirmation": "تۆ دڵنیای لە سڕینەوەی ئەم \"{name}\" پەڕگەیە؟?", + "fileRenameExtensionConfirmation": "تۆ دڵنیای لە گۆڕینی پێوەکاری ئەم پەڕگەیە؟ پەڕگەکە لەوانەیە نەتوانرێت بەکاربهێندرێت.", + "fileRenameLabel": "ناوی پەڕگەی نوێ بنووسە: ", + "filesPaneTitle": "بەشی پەڕگەکان", + "filesRefresh": "بووژاندنەوەی پەڕگەکان", + "filterPlaceholder": "فیلتەر", + "gettingFileData": "زانیاری پەڕگە دەهێندرێت.", + "overwrite": "سەرنوسینەوە", + "loadingFilesPane": { + "title": "ئامادەدەکرێت...", + "text": "پەرگەکە لە ئامادەکردن دایە." + }, + "emptyFilesPane": { + "title": "بوخچەکە خاڵیە.", + "text": "تکایە دوگمەی بارکردن کلیک بکە یان پەڕگەکە بهێنە بۆ ناو ئێرە." + }, + "filterFilesEmpty": { + "title": "هیچ نەدۆزراوە", + "text": "تکایە جۆری هەڵبژاردەی جیاواز هەڵبژێرە بۆ گەڕان." + } + }, + "folders": { + "deleteConfirmation": "تۆ دڵنیای لە سڕینەوەی ئەم \"{name}\" بوخچەیە؟", + "destinationFolder": "جێگای مەبەستی بوخچەی", + "newNameLabel": "ناوی بوخچەی نوێ بنووسە: ", + "newSubfolder": "ژێربوخچەی نوێ", + "renameDialogTitle": "ناوگۆڕینی بوخچە", + "treeTitle": "داری بوخچەکان" + }, + "copy": { + "dropMenuItem": "کۆپی ئێرە بکە", + "errorDialogTitle": "پەڕگانەی ناتوانرێت کۆپی بکرێت:", + "manyFilesDialogTitle": "کۆپیکردنی {count} پەرگە بۆ...", + "manyFilesWait": "کۆپیدەکرێت {count} پەڕگەکان.", + "oneFileDialogTitle": "پەڕگەکە کۆپی بکە بۆ...", + "oneFileWait": "کۆپی پەرگە.", + "operationLabel": "کۆپیکردنی پەڕگە", + "operationSummary": "ژمارەی ئەم پەڕگانەی کۆپیکراوە: {count}." + }, + "move": { + "dropMenuItem": "بیگوازەوە ئێرە", + "errorDialogTitle": "پەڕگانەی ناتوانرێت بگوازرێتەوە:", + "manyFilesDialogTitle": "گواستنەوەی {count} پەرگە بۆ...", + "manyFilesWait": "دەگوازرێتەوە {count} پەڕگەکان.", + "oneFileDialogTitle": "پەڕگەکە بگوازەوە بۆ...", + "oneFileWait": "گواستنەوەی پەرگە.", + "operationLabel": "گواستنەوەی پەڕگە", + "operationSummary": "ژمارەی ئەم پەڕگانەی گواستراوەتەوە: {count}." + }, + "upload": { + "addFiles": "خستنەسەری پەڕگە", + "bytesCountProgress": "({bytesUploaded} لە {bytesTotal})", + "details": "ووردەکاری", + "filesCountProgress": "{filesUploaded} لە {filesTotal}", + "progressLabel": "لە ژێر بارکردندایە.", + "progressMessage": "باردەکرێت...", + "selectFileLabel": "پەڕگەیەک هەڵبژێرە بۆ بارکردن", + "selectFiles": "پەڕگەیەک هەڵبژێرە بۆ بارکردن", + "success": "بارکردنەکە کۆتایی هات!", + "summary": "بارکردنی پەڕگە: {count}" + }, + "settings": { + "display": "پیشانبدە", + "displayDate": "ڕێکەوت", + "displayName": "ناوی پەرگە", + "displaySize": "قەبارەی پەرگە", + "sortAscending": "سەر بەرەو ژوور", + "sortBy": "ڕێزکردن بە", + "sortByOrder": "بەڕێکوپێکی", + "sortDescending": "سەر بەرەو خوار", + "thumbnailSize": "قەبارەی وێنۆچکە", + "title": "چاکسازیەکان", + "viewType": "ببینە", + "viewTypeCompact": "Compact", + "viewTypeList": "للیستە", + "viewTypeThumbnails": "وێنۆجکەکان" + }, + "errors": { + "codes": { + "10": "فەرمانێکی نادروست.", + "11": "جۆری کەرستەکە دەستنیشان نەکراوە لە داواکاریەکە.", + "12": "جۆری کەرستەی داواکراو نادرووستە.", + "13": "شێوەپێدانی لکێنەری پەرگەکە نادروستە.", + "14": "پێوەکاری لکێنەر نادرووستە: {pluginName}.", + "102": "ناوێکی نادروستی پەڕگە یان بوخچە.", + "103": "ئەستەم بوو لە جێبەجێکردنی داواکاریەکەت دەربارەی ڕێگەپێدانی سنووری.", + "104": "ئەستەم بوو لە جێبەجێکردنی داواکاریەکەت دەربارەی ڕێگەپێدانی سنووری سیستەم.", + "105": "پێوەکاری پەڕگە نادروستە.", + "109": "داوایەکی نادروست.", + "110": "هەڵەی نەناسراو.", + "111": "ئەستەم بوو لە جێبەجێکردنی داواکاریەکەت دەربارەی ئەنجامی قەبارەی پەڕگەکە.", + "115": "ئەم ناوە پێشوتر هەیە لە پەرگە یان لە بوخچە.", + "116": "بوخچەکە نەدرۆزراوە. تکایە دووبارە هەوڵبدەوە.", + "117": "پەرگە نەدرۆزراوە. تکایە لیستی پەڕگەکان نوێبکەوەو ئینجا دووبارە هەوڵبدەوە.", + "118": "سەرچاوەو ئامانجی ڕێڕەوە یەکسانن.", + "201": "پەڕگەیەک بەهەمان ناو هەیە. پەڕگەی بارکراو ناوەکەی خۆکارانە گۆڕدرا بۆ \"{name}\".", + "202": "پەڕگەی نادروست.", + "203": "پەڕگەی نادروست. قەبارەی پەڕگەکە زۆر گەورەیە.", + "204": "پەڕگەی بارکراو تێکدرا.", + "205": "کاتی بارکردنی بوخچە بەردەست نیە لەسەر ئەم سێرڤەرە.", + "206": "بارکردنەکە هەڵوەشیندراوە بۆهۆی پارێزگاری. پەڕگەکە زانیاری HTML لەخۆدەگرێت.", + "207": "پەڕگەی بارکراو ناوەکەی گۆڕدرا بۆ \"{name}\".", + "300": "گواستنەوەی پەرگە سەرکەوتونەبوو.", + "301": "کۆپیکردنی پەڕگەکە سەرکەوتونەبوو.", + "302": "سڕینەوەی پەرگەکە سەرکەوتونەبوو.", + "500": "گەڕۆککردنی پەڕگەکان ناچالاککراوە. بەهۆیی پارێزی. تکایە پەیوەندی بکە بە بەڕێوەبەری سیستمەکە بۆ پشکنینی شێوەپێدانی پەرگەی CKFinder.", + "501": "پشتیوانکردنی وێنۆچکە ناچالاککراوە." + }, + "deleteFilePermissions": "Removing files is not allowed in this folder.", + "fileInvalidCharacters": "ناوی پەڕگە نابێت پێکهاتبێت لەم پیتوو هێمایانە: {disallowedCharacters}", + "fileNameNotEmpty": "ناوی پەڕگە نابێت خاڵی بێت.", + "folderInvalidCharacters": "ناوی بوخچە نابێت پێکهاتبێت لەم پیتوو هێمایانە: {disallowedCharacters}", + "incorrectExtension": "پێوەکاری ئەم پەڕگەیە ڕێگەنەدراوە.", + "missingFile": "پەڕگەی داواکروا بەردەست نیە.", + "missingFolder": "ئەم بوخچەیەی تۆ هەوڵی گەیشتنی بۆ دەدەی، بەردەست نیە.", + "noUploadFolderSelected": "تکایە پێشتر بوخچەیەک هەڵبژێرە بۆ بارکردن.", + "operationCompleted": "کردارەکە تەواوکرا بە هەڵەوە.", + "renameFilePermissions": "Renaming files is not allowed in this folder.", + "unknown": "ئەستەم بوو داواکاریەکەت بە تەواوی جێبەجێبکرێت. (هەڵە {number})", + "unknownUploadError": "هەڵە لە ناردنی پەڕگەکە.", + "uploadErrors": "بارکردنەکە کۆتایی هات بە هەڵەوە.", + "uploadPermissions": "ڕێگەنەدراوە بە پەرگە بارکردن." + }, + "chooseResizedImage": { + "title": "هەڵبژاردنی قەبارەکراو", + "originalSize": "قەبارەی ڕەسەن", + "sizes": { + "custom": "درووستکراو", + "large": "گەورە", + "max": "ئەوپەڕی", + "medium": "مامناوەند", + "small": "بچووک" + } + }, + "editImage": { + "adjust": "ڕێککردن", + "apply": "داواکردن", + "confirmExit": "تۆ دڵنیایی لە داخستنی? تۆ هێشتا دەسکرایەکەی وێنەکەت پاشکەوتنەکردووە.", + "crop": "بڕین", + "downloadAction": "وێنەی ڕەسەن ئەسڵی دادەگیرێت.", + "keepAspectRatio": "هێشتنەوەی ڕووی ڕێژەیی", + "loading": "هێنانی وێنە", + "presets": "لەپێش", + "reset": "ڕێکخستنەوه", + "resize": "قەبارەکردن", + "rotate": "سووڕاندن", + "rotateAntiClockwise": "90° جەپ", + "rotateClockwise": "90° ڕاست", + "save": "پاشكەوت", + "saveDialogFileExists": "پەڕگە بەهەمان ناو هەیە لە بوخچەکە.", + "saveDialogOverwrite": "لەسەر پەڕگەکەی بنووسەوە", + "saveDialogSaveAs": "پاشکەوتکردنی وەک:", + "saveDialogTitle": "گۆڕانکاریەکان پاشکەوتبکە", + "title": "دەسکاری وێنە", + "transformationAction": "داواکردنی گۆرین.", + "uploadAction": "وێنەی دەسکاریکراو باردەکرێت.", + "filters": { + "brightness": "ڕووشاندن", + "clip": "گرتە", + "contrast": "جیاوازی", + "exposure": "خستنەڕوو", + "gamma": "گاما", + "hue": "ڕەنگ", + "noise": "خشەخش", + "saturation": "تێرایی - تێربوون", + "sepia": "قاوەیی", + "sharpen": "ڕوونکردن", + "stackBlur": "لێڵی پشت", + "vibrance": "لەرزاندن" + }, + "preset": { + "clarity": "ڕۆنکردن", + "concentrate": "چڕکردنەوە", + "crossProcess": "کاری تێکەڵ", + "glowingSun": "پەرۆشی خۆر", + "grungy": "گڕاونجی", + "hazyDays": "تەم و مژاوی", + "hemingway": "هێمینگوەی", + "herMajesty": "خاوەنشکۆ", + "jarques": "جاڕك", + "lomo": "سووری تاریک", + "love": "خۆشەویستی", + "nostalgia": "بەسۆز", + "oldBoot": "بۆتی کۆن", + "orangePeel": "توێکڵی پڕتەقاڵ", + "pinhole": "پینهۆڵ", + "sinCity": "تاوان", + "sunrise": "خۆرهەڵاتن", + "vintage": "وەرزی" + } + }, + "shortcuts": { + "title": "کلیلی قەدبڕەکان", + "general": { + "action": "بەجێهێنانی فەرمنای بنچینەیی", + "firstItem": "بچۆ بۆ بەرهەمی یەکەم", + "focusFilesPane": "سەرجندانی بەشی پەڕگەکان", + "focusFoldersPane": "سەرنجدانی بەشی بوخچەکان", + "focusNext": "سەرنجدانی بەشی داهاتوو", + "focusToolbar": "سەرنجدانی تووڵامراز", + "lastItem": "بچۆ بۆ بەرهەمی کۆتایی", + "listShortcuts": "ئەم دیالۆگی یارمەتیە بکەوە", + "nextItem": "بچٶ بۆ بەرهەمی داهاتوو", + "previousItem": "بچۆ بۆ بەرهەمی پێشوو", + "showContextMenu": "کردنەوەی شانەی لیستە", + "title": "ڕووکاری گشتی" + }, + "files": { + "addToSelectionAbove": "زیادکردن یان سڕینەوەی پەڕگە لە سەرەوە بۆ هەڵبژاردن", + "addToSelectionBelow": "زیادکردن یان سڕینەوەی پەڕگە لە ژێرەوە بۆ هەڵبژاردن", + "addToSelectionLeft": "زیادکردن یان سڕینەوەی پەڕگە لە لای چەپ بۆ هەڵبژاردن", + "addToSelectionRight": "زیادکردن یان سڕینەوەی پەڕگە لە لای ڕاست بۆ هەڵبژاردن", + "delete": "سڕینەوەی پەڕگە", + "refresh": "نوێکردنەوەی پەڕگەکان", + "rename": "ناوگۆڕینی پەڕگە", + "selectAll": "دیاریکردنی سەرجەم پەڕگەکان", + "upload": "بارکردنی پەڕگە" + }, + "folders": { + "collapseOrParent": "داخستنی بوخچە / بچۆ بۆ باوانی بوخچە", + "delete": "سڕینەوەی بوخچە", + "expandOrSubfolder": "پانکردنەوەی بوخچە / بچۆ بۆ ژێرلقە بوخچەی یەکەم", + "title": "بەشی بوخچەکان" + }, + "keys": { + "ctrl": "کۆنترۆل", + "delete": "بیسڕەوە", + "downArrow": "تیری خوارەوە", + "escape": "چوونە دەرەوە", + "leftArrow": "تیری چەپ", + "question": "نیشانەی پرسیار", + "rightArrow": "تیری ڕاست", + "upArrow": "تیری سەرەوە" + }, + "keysAbbreviations": { + "alt": "ئاڵت", + "ctrl": "کترل", + "del": "دێل", + "end": "ئێند", + "home": "هۆم", + "shift": "شیفت" + } + } +} diff --git a/lib/ckfinder/lang/lt.json b/lib/ckfinder/lang/lt.json new file mode 100644 index 0000000..560bfe4 --- /dev/null +++ b/lib/ckfinder/lang/lt.json @@ -0,0 +1,288 @@ +{ + "appTitle": "CKFinder", + "dir": "ltr", + "langCode": "lt", + "common": { + "abort": "Abort", + "cancel": "Atšaukti", + "choose": "Choose", + "close": "Uždaryti", + "copy": "Copy", + "delete": "Ištrinti", + "download": "Atsisiųsti", + "edit": "Redaguoti", + "maximize": "Padidinti", + "messageTitle": "Informacija", + "minimize": "Sumažinti", + "move": "Move", + "newNameDialogTitle": "Naujas pavadinimas", + "ok": "Gerai", + "pleaseWait": "Prašau palaukite.", + "rememberDecision": "Atsiminti mano pasirinkimą", + "rename": "Pervadinti", + "showMore": "Show more", + "skip": "Praleisti", + "upload": "Įkelti", + "view": "Peržiūrėti" + }, + "units": { + "dateFormat": "yyyy.mm.dd H:MM", + "dateAmPm": [ + "AM", + "PM" + ], + "kb": "{size} KB", + "mb": "{size} MB", + "gb": "{size} GB", + "sizePerSecond": "{size}/s", + "pixelShort": "px" + }, + "files": { + "autoRename": "Automatiškai pervadinti", + "countMany": "{count} failai", + "countOne": "1 failas", + "deleteConfirmation": "Are you sure you want to delete {count} files?", + "fileDeleteConfirmation": "Ar tikrai norite ištrinti failą \"{name}\"?", + "fileRenameExtensionConfirmation": "Ar tikrai norite pakeisti šio failo plėtinį? Failas gali būti nebepanaudojamas", + "fileRenameLabel": "Prašau įrašykite naujo failo pavadinimą: ", + "filesPaneTitle": "Files pane", + "filesRefresh": "Refreshing files", + "filterPlaceholder": "Filter", + "gettingFileData": "Getting file data.", + "overwrite": "Užrašyti ant viršaus", + "loadingFilesPane": { + "title": "Loading...", + "text": "The files are being loaded." + }, + "emptyFilesPane": { + "title": "The folder is empty.", + "text": "Use the Upload button or drag and drop your files here." + }, + "filterFilesEmpty": { + "title": "Nothing found.", + "text": "Please try using different search criteria." + } + }, + "folders": { + "deleteConfirmation": "Ar tikrai norite ištrinti \"{name}\" segtuvą?", + "destinationFolder": "Destination Folder", + "newNameLabel": "Prašau įrašykite naujo segtuvo pavadinimą: ", + "newSubfolder": "Naujas segtuvas", + "renameDialogTitle": "Rename Folder", + "treeTitle": "Folders tree" + }, + "copy": { + "dropMenuItem": "Nukopijuoti čia", + "errorDialogTitle": "Files that cannot be copied:", + "manyFilesDialogTitle": "Copy {count} Files To...", + "manyFilesWait": "Copying {count} files.", + "oneFileDialogTitle": "Copy File To...", + "oneFileWait": "Copying file.", + "operationLabel": "Copying Files", + "operationSummary": "Number of files copied: {count}." + }, + "move": { + "dropMenuItem": "Perkelti čia", + "errorDialogTitle": "Files that cannot be moved:", + "manyFilesDialogTitle": "Move {count} Files To...", + "manyFilesWait": "Moving {count} files.", + "oneFileDialogTitle": "Move File To...", + "oneFileWait": "Moving file.", + "operationLabel": "Moving Files", + "operationSummary": "Number of files moved: {count}." + }, + "upload": { + "addFiles": "Pridėti failus", + "bytesCountProgress": "({bytesUploaded} of {bytesTotal})", + "details": "Details", + "filesCountProgress": "{filesUploaded} of {filesTotal}", + "progressLabel": "Vykdomas įkėlimas.", + "progressMessage": "Uploading...", + "selectFileLabel": "Pasirinkite failą įkėlimui", + "selectFiles": "Select files to upload", + "success": "Upload finished!", + "summary": "Uploaded files: {count}" + }, + "settings": { + "display": "Rodymas:", + "displayDate": "Data", + "displayName": "Failo pavadinimas", + "displaySize": "Failo dydis", + "sortAscending": "Ascending", + "sortBy": "Sort by", + "sortByOrder": "Order", + "sortDescending": "Descending", + "thumbnailSize": "Thumbnail Size", + "title": "Nustatymai", + "viewType": "View", + "viewTypeCompact": "Compact", + "viewTypeList": "List", + "viewTypeThumbnails": "Thumbnails" + }, + "errors": { + "codes": { + "10": "Neteisinga komanda.", + "11": "Resurso rūšis nenurodyta užklausoje.", + "12": "Neteisinga resurso rūšis.", + "13": "The connector configuration file is invalid.", + "14": "Invalid connector plugin: {pluginName}.", + "102": "Netinkamas failas arba segtuvo pavadinimas.", + "103": "Nepavyko įvykdyti užklausos dėl autorizavimo apribojimų.", + "104": "Nepavyko įvykdyti užklausos dėl failų sistemos leidimų apribojimų.", + "105": "Netinkamas failo plėtinys.", + "109": "Netinkama užklausa.", + "110": "Nežinoma klaida.", + "111": "It was not possible to complete the request due to resulting file size.", + "115": "Failas arba segtuvas su tuo pačiu pavadinimu jau yra.", + "116": "Segtuvas nerastas. Pabandykite atnaujinti.", + "117": "Failas nerastas. Pabandykite atnaujinti failų sąrašą.", + "118": "Šaltinio ir nurodomos vietos nuorodos yra vienodos.", + "201": "Failas su tuo pačiu pavadinimu jau tra. Įkeltas failas buvo pervadintas į \"{name}\"", + "202": "Netinkamas failas", + "203": "Netinkamas failas. Failo apimtis yra per didelė.", + "204": "Įkeltas failas yra pažeistas.", + "205": "Nėra laikinojo segtuvo skirto failams įkelti.", + "206": "Įkėlimas bus nutrauktas dėl saugumo sumetimų. Šiame faile yra HTML duomenys.", + "207": "Įkeltas failas buvo pervadintas į \"{name}\"", + "300": "Failų perkėlimas nepavyko.", + "301": "Failų kopijavimas nepavyko.", + "302": "Deleting file(s) failed.", + "500": "Failų naršyklė yra išjungta dėl saugumo nustaymų. Prašau susisiekti su sistemų administratoriumi ir patikrinkite CKFinder konfigūracinį failą.", + "501": "Miniatiūrų palaikymas išjungtas." + }, + "deleteFilePermissions": "Removing files is not allowed in this folder.", + "fileInvalidCharacters": "Failo pavadinimas negali turėti bent vieno iš šių simbolių: {disallowedCharacters}", + "fileNameNotEmpty": "The file name cannot be empty.", + "folderInvalidCharacters": "Segtuvo pavadinimas negali turėti bent vieno iš šių simbolių: {disallowedCharacters}", + "incorrectExtension": "Šiame segtuve toks failų plėtinys yra uždraustas.", + "missingFile": "The requested file is no longer available.", + "missingFolder": "The folder you are trying to reach is no longer available.", + "noUploadFolderSelected": "Pasirinkite segtuvą prieš įkeliant.", + "operationCompleted": "Operation completed with errors.", + "renameFilePermissions": "Renaming files is not allowed in this folder.", + "unknown": "Užklausos įvykdyti nepavyko. (Klaida {number})", + "unknownUploadError": "Įvyko klaida siunčiant failą.", + "uploadErrors": "Upload finished with errors.", + "uploadPermissions": "Failų įkėlimas uždraustas." + }, + "chooseResizedImage": { + "title": "Choose Resized", + "originalSize": "Original Size", + "sizes": { + "custom": "Custom", + "large": "Large", + "max": "Max", + "medium": "Medium", + "small": "Small" + } + }, + "editImage": { + "adjust": "Adjust", + "apply": "Apply", + "confirmExit": "Are you sure you want to close? You have unsaved changes to the image.", + "crop": "Crop", + "downloadAction": "Downloading original image.", + "keepAspectRatio": "Keep Aspect Ratio", + "loading": "Loading image", + "presets": "Presets", + "reset": "Reset", + "resize": "Resize", + "rotate": "Rotate", + "rotateAntiClockwise": "90° Left", + "rotateClockwise": "90° Right", + "save": "Save", + "saveDialogFileExists": "File with the same name already exists in folder.", + "saveDialogOverwrite": "Overwrite File", + "saveDialogSaveAs": "Save as:", + "saveDialogTitle": "Save Changes", + "title": "Edit Image", + "transformationAction": "Applying transformations.", + "uploadAction": "Uploading edited image.", + "filters": { + "brightness": "Brightness", + "clip": "Clip", + "contrast": "Contrast", + "exposure": "Exposure", + "gamma": "Gamma", + "hue": "Hue", + "noise": "Noise", + "saturation": "Saturation", + "sepia": "Sepia", + "sharpen": "Sharpen", + "stackBlur": "Blur", + "vibrance": "Vibrance" + }, + "preset": { + "clarity": "Clarity", + "concentrate": "Concentrate", + "crossProcess": "Cross Process", + "glowingSun": "Glowing Sun", + "grungy": "Grungy", + "hazyDays": "Hazy Days", + "hemingway": "Hemingway", + "herMajesty": "Her Majesty", + "jarques": "Jarques", + "lomo": "Lomo", + "love": "Love", + "nostalgia": "Nostalgia", + "oldBoot": "Old Boot", + "orangePeel": "Orange Peel", + "pinhole": "Pinhole", + "sinCity": "Sin City", + "sunrise": "Sunrise", + "vintage": "Vintage" + } + }, + "shortcuts": { + "title": "Keyboard Shortcuts", + "general": { + "action": "Execute default action", + "firstItem": "Go to first item", + "focusFilesPane": "Focus files pane", + "focusFoldersPane": "Focus folders pane or breadcrumbs", + "focusNext": "Focus next pane", + "focusToolbar": "Focus toolbar", + "lastItem": "Go to last item", + "listShortcuts": "Open this help dialog", + "nextItem": "Go to next item", + "previousItem": "Go to previous item", + "showContextMenu": "Open context menu", + "title": "General Interface" + }, + "files": { + "addToSelectionAbove": "Add or remove files above to selection", + "addToSelectionBelow": "Add or remove files below to selection", + "addToSelectionLeft": "Add or remove file on the left to selection", + "addToSelectionRight": "Add or remove file on the right to selection", + "delete": "Delete file(s)", + "refresh": "Refresh files", + "rename": "Rename file", + "selectAll": "Select all files", + "upload": "Upload file(s)" + }, + "folders": { + "collapseOrParent": "Collapse folder / Go to parent folder", + "delete": "Delete folder", + "expandOrSubfolder": "Expand folder / Go to first subfolder", + "title": "Folders Pane" + }, + "keys": { + "ctrl": "Control", + "delete": "Delete", + "downArrow": "Down arrow", + "escape": "Escape", + "leftArrow": "Left arrow", + "question": "Question mark", + "rightArrow": "Right arrow", + "upArrow": "Up arrow" + }, + "keysAbbreviations": { + "alt": "alt", + "ctrl": "ctrl", + "del": "del", + "end": "end", + "home": "home", + "shift": "shift" + } + } +} diff --git a/lib/ckfinder/lang/lv.json b/lib/ckfinder/lang/lv.json new file mode 100644 index 0000000..06ec713 --- /dev/null +++ b/lib/ckfinder/lang/lv.json @@ -0,0 +1,288 @@ +{ + "appTitle": "CKFinder", + "dir": "ltr", + "langCode": "lv", + "common": { + "abort": "Atcelt", + "cancel": "Atcelt", + "choose": "Izvēlēties", + "close": "Aizvērt", + "copy": "Kopēt", + "delete": "Dzēst", + "download": "Lejupielādēt", + "edit": "Labot", + "maximize": "Maksimizēt", + "messageTitle": "Informācija", + "minimize": "Minimizēt", + "move": "Pārvietot", + "newNameDialogTitle": "Jauns nosaukums", + "ok": "Darīts!", + "pleaseWait": "Uzgaidiet.", + "rememberDecision": "Atcerēties izvēli", + "rename": "Pārsaukt", + "showMore": "Rādīt vairāk", + "skip": "Izlaist", + "upload": "Augšupielādēt", + "view": "Skatīt" + }, + "units": { + "dateFormat": "dd/mm/yyyy H:MM", + "dateAmPm": [ + "AM", + "PM" + ], + "kb": "{size} KB", + "mb": "{size} MB", + "gb": "{size} GB", + "sizePerSecond": "{size}/s", + "pixelShort": "px" + }, + "files": { + "autoRename": "Automātiski pārsaukt", + "countMany": "{count} faili", + "countOne": "1 fails", + "deleteConfirmation": "Vai tiešām vēlaties dzēst {count} failus?", + "fileDeleteConfirmation": "Vai tiešām vēlaties neatgriezeniski dzēst failu \"{name}\"?", + "fileRenameExtensionConfirmation": "Vai tiešām vēlaties mainīt faila paplašinājumu? Fails var palikt nelietojams.", + "fileRenameLabel": "Lūdzu ierakstiet jauno faila nosaukumu: ", + "filesPaneTitle": "Failu sadaļa", + "filesRefresh": "Atjaunot failus", + "filterPlaceholder": "Filtrs", + "gettingFileData": "Iegūst faila datus.", + "overwrite": "Pārrakstīt", + "loadingFilesPane": { + "title": "Notiek ielāde...", + "text": "Tiek ielādēti faili.." + }, + "emptyFilesPane": { + "title": "Mape ir tukša.", + "text": "Izmanto Augšupielādēt pogu vai velc un nomet savus failus šeit." + }, + "filterFilesEmpty": { + "title": "Nekas nav atrasts.", + "text": "Lūdzu mēģini citus meklēšanas nosacījumus." + } + }, + "folders": { + "deleteConfirmation": "Vai tiešām vēlaties neatgriezeniski dzēst mapi \"{name}\"?", + "destinationFolder": "Mērķa mape", + "newNameLabel": "Lūdzu ierakstiet mapes nosaukumu: ", + "newSubfolder": "Jauna apakšmape", + "renameDialogTitle": "Pārsaukt mapi", + "treeTitle": "Mapju koks" + }, + "copy": { + "dropMenuItem": "Kopēt šeit", + "errorDialogTitle": "Faili, kurus nevar pārkopēt:", + "manyFilesDialogTitle": "Kopēt {count} failus uz...", + "manyFilesWait": "{count} faili tiek kopēti.", + "oneFileDialogTitle": "Kopēt failu uz...", + "oneFileWait": "Fails tiek kopēts.", + "operationLabel": "Kopēju failus", + "operationSummary": "Kopā pārkopēti faili: {count}." + }, + "move": { + "dropMenuItem": "Pārvietot šeit", + "errorDialogTitle": "Faili, kurus nevar pārvietot:", + "manyFilesDialogTitle": "Pārvietot {count} failus uz...", + "manyFilesWait": "{count} faili tiek pārvietoti.", + "oneFileDialogTitle": "Pārvietot failu uz...", + "oneFileWait": "Fails tiek pārvietots.", + "operationLabel": "Pārvietoju failus", + "operationSummary": "Kopā pārvietoti faili: {count}." + }, + "upload": { + "addFiles": "Pievienot failus", + "bytesCountProgress": "({bytesUploaded} no {bytesTotal})", + "details": "Detaļas", + "filesCountProgress": "{filesUploaded} no {filesTotal}", + "progressLabel": "Augšupielādē.", + "progressMessage": "Notiek ielāde...", + "selectFileLabel": "Izvēlieties failu, ko augšupielādēt", + "selectFiles": "Izvēlieties failus ko augšupielādēt", + "success": "Augšupielādē pabeigta!", + "summary": "Augšupielādēti failu: {count}" + }, + "settings": { + "display": "Rādīt:", + "displayDate": "Datums", + "displayName": "Faila Nosaukums", + "displaySize": "Faila Izmērs", + "sortAscending": "Augoši", + "sortBy": "Kārtot pēc", + "sortByOrder": "Kārtot", + "sortDescending": "Dilstoši", + "thumbnailSize": "Sīktēla izmērs", + "title": "Uzstādījumi", + "viewType": "Skats", + "viewTypeCompact": "Compact", + "viewTypeList": "Saraksts", + "viewTypeThumbnails": "Sīktēli" + }, + "errors": { + "codes": { + "10": "Nederīga komanda.", + "11": "Resursa veids netika norādīts pieprasījumā.", + "12": "Pieprasītais resursa veids nav derīgs.", + "13": "Savienojuma konfigurācijas fails nav korekts.", + "14": "Nekorekts savienojuma spraudnis: {pluginName}.", + "102": "Nederīgs faila vai mapes nosaukums.", + "103": "Nav iespējams pabeigt pieprasījumu, autorizācijas aizliegumu dēļ.", + "104": "Nav iespējams pabeigt pieprasījumu, failu sistēmas atļauju ierobežojumu dēļ.", + "105": "Neatļauts faila paplašinājums.", + "109": "Nederīgs pieprasījums.", + "110": "Nezināma kļūda.", + "111": "Pieprasījums neizdevās, dēļ rezultāta faila izmēra.", + "115": "Fails vai mape ar šādu nosaukumu jau pastāv.", + "116": "Mape nav atrasta. Lūdzu pārlādējiet šo logu un mēģiniet vēlreiz.", + "117": "Fails nav atrasts. Lūdzu pārlādējiet failu sarakstu un mēģiniet vēlreiz.", + "118": "Abas mapes ir viena un tā pati.", + "201": "Fails ar šādu nosaukumu jau eksistē. Augšupielādētais fails tika pārsaukts par \"{name}\".", + "202": "Nederīgs fails.", + "203": "Nederīgs fails. Faila izmērs pārsniedz pieļaujamo.", + "204": "Augšupielādētais fails ir bojāts.", + "205": "Neviena pagaidu mape nav pieejama priekš augšupielādēšanas uz servera.", + "206": "Augšupielāde atcelta drošības apsvērumu dēļ. Fails satur HTML veida datus.", + "207": "Augšupielādētais fails tika pārsaukts par \"{name}\".", + "300": "Pārvietot failu(s) neizdevās.", + "301": "Pārkopēt failu(s) neizdevās.", + "302": "Dzēst failu(s) neizdevās.", + "500": "Failu pārlūks ir atslēgts drošības apsvērumu dēļ. Lūdzu sazinieties ar šīs sistēmas tehnisko administratoru vai pārbaudiet CKFinder konfigurācijas failu.", + "501": "Sīkbilžu atbalsts ir atslēgts." + }, + "deleteFilePermissions": "Removing files is not allowed in this folder.", + "fileInvalidCharacters": "Faila nosaukums nedrīkst saturēt nevienu no sekojošajām zīmēm: {disallowedCharacters}", + "fileNameNotEmpty": "Fails nevar būt tukšs", + "folderInvalidCharacters": "Mapes nosaukums nedrīkst saturēt nevienu no sekojošajām zīmēm: {disallowedCharacters}", + "incorrectExtension": "Faila paplašinājums nav atļauts šajā mapē.", + "missingFile": "Pieprasītais fails vairs nav pieejams.", + "missingFolder": "Mape, kuru mēģiniet atvērt, vairs neeksistē.", + "noUploadFolderSelected": "Lūdzu izvēlieties mapi pirms augšupielādes.", + "operationCompleted": "Darbība tika pabeigta ar kļūdām.", + "renameFilePermissions": "Renaming files is not allowed in this folder.", + "unknown": "Nebija iespējams pabeigt pieprasījumu. (Kļūda {number})", + "unknownUploadError": "Kļūda nosūtot failu.", + "uploadErrors": "Augšupielāde beidzās ar kļūdām.", + "uploadPermissions": "Failus augšupielāde nav atļauta." + }, + "chooseResizedImage": { + "title": "Izvēlēties mērogotu", + "originalSize": "Oriģinālais izmērs", + "sizes": { + "custom": "Norādīts", + "large": "Liels", + "max": "Maksimāls", + "medium": "Vidējs", + "small": "Mazs" + } + }, + "editImage": { + "adjust": "Pielāgot", + "apply": "Lietot", + "confirmExit": "Vai tiešām vēlaties azivērt? Jūsu attēlam ir nesaglabātas izmaiņas.", + "crop": "Apgriezt", + "downloadAction": "Ielādēju oriģinālo attēlu.", + "keepAspectRatio": "Saglabāt proporciju", + "loading": "Ielādē attēlu", + "presets": "Sagataves", + "reset": "Atcelt", + "resize": "Mērogot", + "rotate": "Rotēt", + "rotateAntiClockwise": "90° pa kreisi", + "rotateClockwise": "90° pa labi", + "save": "Saglabāt", + "saveDialogFileExists": "Fails ar šādu nosaukumu jau eksistē šajā mapē.", + "saveDialogOverwrite": "Pārrakstīt failam", + "saveDialogSaveAs": "Saglabāt kā:", + "saveDialogTitle": "Saglabāt izmaiņas", + "title": "Labot attēlu", + "transformationAction": "Pielietoju transformācijas.", + "uploadAction": "Augšupielādēju laboto attēlu.", + "filters": { + "brightness": "Gaišums", + "clip": "Klips", + "contrast": "Kontrasts", + "exposure": "Ekspozīcija", + "gamma": "Gamma", + "hue": "Nokrāsa", + "noise": "Troksnis", + "saturation": "Piesātinājums", + "sepia": "Sēpija", + "sharpen": "Asums", + "stackBlur": "Miglojums", + "vibrance": "Dzīvīgums" + }, + "preset": { + "clarity": "Skaidrums", + "concentrate": "Koncentrāts", + "crossProcess": "Krustu process", + "glowingSun": "Spīdoša saule", + "grungy": "Grungy", + "hazyDays": "Dūmakains dienas", + "hemingway": "Hemingvejs", + "herMajesty": "Jūsu augstība", + "jarques": "Jarques", + "lomo": "Lomo", + "love": "Mīlestība", + "nostalgia": "Nostaļģija", + "oldBoot": "Vecs zābaks", + "orangePeel": "Apelsīna miza", + "pinhole": "Adatas caurums", + "sinCity": "Grēku pilsēta", + "sunrise": "Saullēkts", + "vintage": "Vintāža" + } + }, + "shortcuts": { + "title": "Klaviatūras saīsinājumi", + "general": { + "action": "Izpildīt noklusēto darbību", + "firstItem": "Doties uz pirmo", + "focusFilesPane": "Aktivizēt failu sadaļu", + "focusFoldersPane": "Aktivizēt mapju sadaļu vai ceļu", + "focusNext": "Aktivizēt nākošo sadaļu", + "focusToolbar": "Aktivizēt rīkjoslu", + "lastItem": "Dotiez uz pēdējo", + "listShortcuts": "Atvērt šo palīdzības dialogu", + "nextItem": "Doties uz nākošo", + "previousItem": "Doties uz iepriekšējo", + "showContextMenu": "Atvērt satura izvēlni", + "title": "Galvenais interfeiss" + }, + "files": { + "addToSelectionAbove": "Pievienot vai dzēst failis virs atzīmes", + "addToSelectionBelow": "Pievienot vai dzēst failis zem atzīmes", + "addToSelectionLeft": "Pievienot vai dzēst failis pa kreisi no atzīmes", + "addToSelectionRight": "Pievienot vai dzēst failis pa labi no atzīmes", + "delete": "Dzēst failu(s)", + "refresh": "Atsvaidzināt failus", + "rename": "Pārsaukt failus", + "selectAll": "Atzīmēt visus failus", + "upload": "Augšupielādēt failu(s)" + }, + "folders": { + "collapseOrParent": "Aizvērt mapi / Doties uz augstāku mapi", + "delete": "Dzēst mapi", + "expandOrSubfolder": "Atvērt mapi / Doties uz pirmo apakšmapi", + "title": "Mapju sadaļa" + }, + "keys": { + "ctrl": "Control", + "delete": "Delete", + "downArrow": "Uz leju bultiņa", + "escape": "Escape", + "leftArrow": "Pa kreisi bultiņa", + "question": "Jautājumzīme", + "rightArrow": "Pa labi bultiņa", + "upArrow": "Uz augšu bultiņa" + }, + "keysAbbreviations": { + "alt": "alt", + "ctrl": "ctrl", + "del": "del", + "end": "end", + "home": "home", + "shift": "shift" + } + } +} diff --git a/lib/ckfinder/lang/nb.json b/lib/ckfinder/lang/nb.json new file mode 100644 index 0000000..e7ead67 --- /dev/null +++ b/lib/ckfinder/lang/nb.json @@ -0,0 +1,288 @@ +{ + "appTitle": "CKFinder", + "dir": "ltr", + "langCode": "nb", + "common": { + "abort": "Abort", + "cancel": "Avbryt", + "choose": "Velg", + "close": "Lukk", + "copy": "Kopier", + "delete": "Slett", + "download": "Last ned", + "edit": "Rediger", + "maximize": "Maksimer", + "messageTitle": "Informasjon", + "minimize": "Minimer", + "move": "Flytt", + "newNameDialogTitle": "Nytt navn", + "ok": "OK", + "pleaseWait": "Vennligst vent", + "rememberDecision": "Husk mitt valg", + "rename": "Endre navn", + "showMore": "Vis mer", + "skip": "Hopp over", + "upload": "Last opp", + "view": "Vis fullversjon" + }, + "units": { + "dateFormat": "dd/mm/yyyy HH:MM", + "dateAmPm": [ + "AM", + "PM" + ], + "kb": "{size} KB", + "mb": "{size} MB", + "gb": "{size} GB", + "sizePerSecond": "{size}/s", + "pixelShort": "px" + }, + "files": { + "autoRename": "Gi nytt navn automatisk", + "countMany": "{count} filer", + "countOne": "1 fil", + "deleteConfirmation": "Er du sikker på at du vil slette {count} filer?", + "fileDeleteConfirmation": "Er du sikker på at du vil slette denne filen \"{name}\"?", + "fileRenameExtensionConfirmation": "Er du sikker på at du vil endre filtypen? Filen kan bli ubrukelig.", + "fileRenameLabel": "Skriv inn det nye filnavnet: ", + "filesPaneTitle": "Files pane", + "filesRefresh": "Refreshing files", + "filterPlaceholder": "Filter", + "gettingFileData": "Henter fildata,", + "overwrite": "Overskriv", + "loadingFilesPane": { + "title": "Laster...", + "text": "Filene lastes." + }, + "emptyFilesPane": { + "title": "Mappen er tom.", + "text": "Bruk Last opp-knappen eller trekk filene dine hit." + }, + "filterFilesEmpty": { + "title": "Ingenting funnet.", + "text": "Prøv igjen med andre søkekriterier." + } + }, + "folders": { + "deleteConfirmation": "Er du sikker på at du vil slette mappen \"{name}\"?", + "destinationFolder": "Målmappe", + "newNameLabel": "Skriv inn det nye mappenavnet: ", + "newSubfolder": "Ny undermappe", + "renameDialogTitle": "Rename Folder", + "treeTitle": "Folders tree" + }, + "copy": { + "dropMenuItem": "Kopier hit", + "errorDialogTitle": "Filer som ikke kan kopieres:", + "manyFilesDialogTitle": "Kopier {count} filer til...", + "manyFilesWait": "Kopierer {count} filer,", + "oneFileDialogTitle": "Kopier filen til...", + "oneFileWait": "Kopierer filen,", + "operationLabel": "Kopierer filer", + "operationSummary": "Antall filer kopiert: {count}." + }, + "move": { + "dropMenuItem": "Flytt hit", + "errorDialogTitle": "Filer som ikke kan flyttes:", + "manyFilesDialogTitle": "Flytt {count} filer til...", + "manyFilesWait": "Flytter {count} filer,", + "oneFileDialogTitle": "Flytt filen til...", + "oneFileWait": "Flytter filen,", + "operationLabel": "Flytter filer", + "operationSummary": "Antall filer flyttet: {count}." + }, + "upload": { + "addFiles": "Legg til filer", + "bytesCountProgress": "({bytesUploaded} av {bytesTotal})", + "details": "Detaljer", + "filesCountProgress": "{filesUploaded} av {filesTotal}", + "progressLabel": "Laster opp filen.", + "progressMessage": "Laster opp...", + "selectFileLabel": "Velg filen du vil laste opp", + "selectFiles": "Velg filer for opplasting", + "success": "Opplasting fullført!", + "summary": "Opplastede filer: {count}" + }, + "settings": { + "display": "Vis:", + "displayDate": "Dato", + "displayName": "Filnavn", + "displaySize": "Filstørrelse", + "sortAscending": "Ascending", + "sortBy": "Sort by", + "sortByOrder": "Order", + "sortDescending": "Descending", + "thumbnailSize": "Miniatyrbildestørrelse", + "title": "Innstillinger", + "viewType": "View", + "viewTypeCompact": "Compact", + "viewTypeList": "List", + "viewTypeThumbnails": "Thumbnails" + }, + "errors": { + "codes": { + "10": "Ugyldig kommando.", + "11": "Ressurstypen ble ikke spesifisert i forespørselen.", + "12": "Ugyldig ressurstype.", + "13": "Konfigurasjonsfilen for forbindelsen er ugyldig.", + "14": "Ugyldig programvareutvidelse: {pluginName}.", + "102": "Ugyldig fil- eller mappenavn.", + "103": "Kunne ikke utføre forespørselen grunnet manglende tilgang.", + "104": "Kunne ikke utføre forespørselen grunnet manglende tilgang til filsystemet.", + "105": "Ugyldig filtype.", + "109": "Ugyldig forespørsel.", + "110": "Ukjent feil.", + "111": "Det var ikke mulig å fullføre handlingen på grunn av filstørrelsen.", + "115": "Det finnes allerede en fil eller mappe med dette navnet.", + "116": "Kunne ikke finne mappen. Last vinduet på nytt og prøv igjen.", + "117": "Kunne ikke finne filen. Last vinduet på nytt og prøv igjen.", + "118": "Kilde- og mål-bane er like.", + "201": "Det fantes allerede en fil med dette navnet. Den opplastede filens navn har blitt endret til \"{name}\".", + "202": "Ugyldig fil.", + "203": "Ugyldig fil. Filen er for stor.", + "204": "Den opplastede filen er korrupt.", + "205": "Det finnes ingen midlertidig mappe for filopplastinger.", + "206": "Opplastingen ble avbrutt av sikkerhetshensyn. Filen inneholder HTML-aktige data.", + "207": "Den opplastede filens navn har blitt endret til \"{name}\".", + "300": "Klarte ikke å flytte fil(er).", + "301": "Klarte ikke å kopiere fil(er).", + "302": "Sletting av fil(er) feilet.", + "500": "Filvelgeren ikke tilgjengelig av sikkerhetshensyn. Kontakt systemansvarlig og be ham sjekke CKFinders konfigurasjonsfil.", + "501": "Funksjon for miniatyrbilder er skrudd av." + }, + "deleteFilePermissions": "Removing files is not allowed in this folder.", + "fileInvalidCharacters": "Filnavnet kan ikke inneholde følgende tegn: {disallowedCharacters}", + "fileNameNotEmpty": "The file name cannot be empty.", + "folderInvalidCharacters": "Mappenavnet kan ikke inneholde følgende tegn: {disallowedCharacters}", + "incorrectExtension": "Filtypen er ikke tillatt i denne mappen.", + "missingFile": "Den forespurte filen finnes ikke lengre.", + "missingFolder": "Mappen du forsøker å nå er ikke lengre tilgjengelig.", + "noUploadFolderSelected": "Vennligst velg en mappe før du laster opp.", + "operationCompleted": "Handlingen ble utført med feil.", + "renameFilePermissions": "Renaming files is not allowed in this folder.", + "unknown": "Det var ikke mulig å utføre forespørselen. (Feil {number})", + "unknownUploadError": "Feil ved sending av fil.", + "uploadErrors": "Opplasting fullført med feil.", + "uploadPermissions": "Filopplastning er ikke tillatt." + }, + "chooseResizedImage": { + "title": "Velg skalert", + "originalSize": "Originalstørrelse", + "sizes": { + "custom": "Selvvalgt", + "large": "Stor", + "max": "Maks", + "medium": "Middels", + "small": "Liten" + } + }, + "editImage": { + "adjust": "Juster", + "apply": "Bruk", + "confirmExit": "Are you sure you want to close? You have unsaved changes to the image.", + "crop": "Utsnitt", + "downloadAction": "Laster ned originalbildet.", + "keepAspectRatio": "Behold sideforhold", + "loading": "Laster bilde", + "presets": "Forhåndsinnstillinger", + "reset": "Tilbakestill", + "resize": "Endre størrelse", + "rotate": "Roter", + "rotateAntiClockwise": "90° venstre", + "rotateClockwise": "90° høyre", + "save": "Lagre", + "saveDialogFileExists": "En fil med det samme navnet finnes allerede i mappen.", + "saveDialogOverwrite": "Overskriv fil", + "saveDialogSaveAs": "Lagre som:", + "saveDialogTitle": "Lagre endringene", + "title": "Rediger bilde", + "transformationAction": "Utfører forandringer.", + "uploadAction": "Laster opp endret bilde.", + "filters": { + "brightness": "Lysstyrke", + "clip": "Klipp", + "contrast": "Kontrast", + "exposure": "Eksponering", + "gamma": "Gamma", + "hue": "Fargetone", + "noise": "Støy", + "saturation": "Fargemetning", + "sepia": "Sepia", + "sharpen": "Skjerpe", + "stackBlur": "Stack Blur", + "vibrance": "Glød" + }, + "preset": { + "clarity": "Klarhet", + "concentrate": "Konsentrert", + "crossProcess": "Kryssprosesser", + "glowingSun": "Glødende sol", + "grungy": "Grungy", + "hazyDays": "Disige dager", + "hemingway": "Hemingway", + "herMajesty": "Hennes majestet", + "jarques": "Jarques", + "lomo": "Lomo", + "love": "Kjærlighet", + "nostalgia": "Nostalgi", + "oldBoot": "Old Boot", + "orangePeel": "Appelsinskall", + "pinhole": "Knappenålshull", + "sinCity": "Sin City", + "sunrise": "Soloppgang", + "vintage": "Vintage" + } + }, + "shortcuts": { + "title": "Keyboard Shortcuts", + "general": { + "action": "Execute default action", + "firstItem": "Go to first item", + "focusFilesPane": "Focus files pane", + "focusFoldersPane": "Focus folders pane or breadcrumbs", + "focusNext": "Focus next pane", + "focusToolbar": "Focus toolbar", + "lastItem": "Go to last item", + "listShortcuts": "Open this help dialog", + "nextItem": "Go to next item", + "previousItem": "Go to previous item", + "showContextMenu": "Open context menu", + "title": "General Interface" + }, + "files": { + "addToSelectionAbove": "Add or remove files above to selection", + "addToSelectionBelow": "Add or remove files below to selection", + "addToSelectionLeft": "Add or remove file on the left to selection", + "addToSelectionRight": "Add or remove file on the right to selection", + "delete": "Delete file(s)", + "refresh": "Refresh files", + "rename": "Rename file", + "selectAll": "Select all files", + "upload": "Upload file(s)" + }, + "folders": { + "collapseOrParent": "Collapse folder / Go to parent folder", + "delete": "Delete folder", + "expandOrSubfolder": "Expand folder / Go to first subfolder", + "title": "Folders Pane" + }, + "keys": { + "ctrl": "Control", + "delete": "Delete", + "downArrow": "Ned-piltast", + "escape": "Escape", + "leftArrow": "Venstre piltast", + "question": "Question mark", + "rightArrow": "Høyre piltast", + "upArrow": "Opp-piltast" + }, + "keysAbbreviations": { + "alt": "alt", + "ctrl": "ctrl", + "del": "del", + "end": "end", + "home": "home", + "shift": "shift" + } + } +} diff --git a/lib/ckfinder/lang/nl.json b/lib/ckfinder/lang/nl.json new file mode 100644 index 0000000..e2f485b --- /dev/null +++ b/lib/ckfinder/lang/nl.json @@ -0,0 +1,288 @@ +{ + "appTitle": "CKFinder", + "dir": "ltr", + "langCode": "nl", + "common": { + "abort": "Abort", + "cancel": "Annuleren", + "choose": "Choose", + "close": "Sluiten", + "copy": "Copy", + "delete": "Verwijderen", + "download": "Downloaden", + "edit": "Wijzigen", + "maximize": "Maximaliseren", + "messageTitle": "Informatie", + "minimize": "Minimaliseren", + "move": "Move", + "newNameDialogTitle": "Nieuwe naam", + "ok": "OK", + "pleaseWait": "Please wait.", + "rememberDecision": "Onthoud mijn keuze", + "rename": "Naam wijzigen", + "showMore": "Show more", + "skip": "Overslaan", + "upload": "Uploaden", + "view": "Bekijken" + }, + "units": { + "dateFormat": "d-m-yyyy H:MM", + "dateAmPm": [ + "AM", + "PM" + ], + "kb": "{size} KB", + "mb": "{size} MB", + "gb": "{size} GB", + "sizePerSecond": "{size}/s", + "pixelShort": "px" + }, + "files": { + "autoRename": "Automatisch hernoemen", + "countMany": "{count} bestanden", + "countOne": "1 bestand", + "deleteConfirmation": "Are you sure you want to delete {count} files?", + "fileDeleteConfirmation": "Weet je zeker dat je het bestand \"{name}\" wilt verwijderen?", + "fileRenameExtensionConfirmation": "Weet je zeker dat je de extensie wilt wijzigen? Het bestand kan onbruikbaar worden.", + "fileRenameLabel": "Vul de nieuwe bestandsnaam in: ", + "filesPaneTitle": "Files pane", + "filesRefresh": "Refreshing files", + "filterPlaceholder": "Filter", + "gettingFileData": "Getting file data.", + "overwrite": "Overschrijven", + "loadingFilesPane": { + "title": "Loading...", + "text": "The files are being loaded." + }, + "emptyFilesPane": { + "title": "The folder is empty.", + "text": "Use the Upload button or drag and drop your files here." + }, + "filterFilesEmpty": { + "title": "Nothing found.", + "text": "Please try using different search criteria." + } + }, + "folders": { + "deleteConfirmation": "Weet je het zeker dat je de map \"{name}\" wilt verwijderen?", + "destinationFolder": "Destination Folder", + "newNameLabel": "Vul de mapnaam in: ", + "newSubfolder": "Nieuwe onderliggende map", + "renameDialogTitle": "Rename Folder", + "treeTitle": "Folders tree" + }, + "copy": { + "dropMenuItem": "Hierheen kopiëren", + "errorDialogTitle": "Files that cannot be copied:", + "manyFilesDialogTitle": "Copy {count} Files To...", + "manyFilesWait": "Copying {count} files.", + "oneFileDialogTitle": "Copy File To...", + "oneFileWait": "Copying file.", + "operationLabel": "Copying Files", + "operationSummary": "Number of files copied: {count}." + }, + "move": { + "dropMenuItem": "Hierheen verplaatsen", + "errorDialogTitle": "Files that cannot be moved:", + "manyFilesDialogTitle": "Move {count} Files To...", + "manyFilesWait": "Moving {count} files.", + "oneFileDialogTitle": "Move File To...", + "oneFileWait": "Moving file.", + "operationLabel": "Moving Files", + "operationSummary": "Number of files moved: {count}." + }, + "upload": { + "addFiles": "Bestanden toevoegen", + "bytesCountProgress": "({bytesUploaded} of {bytesTotal})", + "details": "Details", + "filesCountProgress": "{filesUploaded} of {filesTotal}", + "progressLabel": "Bezig met uploaden.", + "progressMessage": "Uploading...", + "selectFileLabel": "Selecteer het bestand om te uploaden", + "selectFiles": "Select files to upload", + "success": "Upload finished!", + "summary": "Uploaded files: {count}" + }, + "settings": { + "display": "Weergave:", + "displayDate": "Datum", + "displayName": "Bestandsnaam", + "displaySize": "Bestandsgrootte", + "sortAscending": "Ascending", + "sortBy": "Sort by", + "sortByOrder": "Order", + "sortDescending": "Descending", + "thumbnailSize": "Thumbnail Size", + "title": "Instellingen", + "viewType": "View", + "viewTypeCompact": "Compact", + "viewTypeList": "List", + "viewTypeThumbnails": "Thumbnails" + }, + "errors": { + "codes": { + "10": "Ongeldig commando.", + "11": "Het bestandstype komt niet voor in de aanvraag.", + "12": "Het gevraagde brontype is niet geldig.", + "13": "The connector configuration file is invalid.", + "14": "Invalid connector plugin: {pluginName}.", + "102": "Ongeldige bestands- of mapnaam.", + "103": "Het verzoek kon niet worden voltooid vanwege autorisatie beperkingen.", + "104": "Het verzoek kon niet worden voltooid door beperkingen in de rechten op het bestandssysteem.", + "105": "Ongeldige bestandsextensie.", + "109": "Ongeldige aanvraag.", + "110": "Onbekende fout.", + "111": "It was not possible to complete the request due to resulting file size.", + "115": "Er bestaat al een bestand of map met deze naam.", + "116": "Map niet gevonden, vernieuw de mappenlijst of kies een andere map.", + "117": "Bestand niet gevonden, vernieuw de mappenlijst of kies een andere map.", + "118": "Bron- en doelmap zijn gelijk.", + "201": "Er bestaat al een bestand met dezelfde naam. Het geüploade bestand is hernoemd naar: \"{name}\".", + "202": "Ongeldige bestand.", + "203": "Ongeldige bestand. Het bestand is te groot.", + "204": "De geüploade file is kapot.", + "205": "Er is geen hoofdmap gevonden.", + "206": "Het uploaden van het bestand is om veiligheidsredenen afgebroken. Er is HTML code in het bestand aangetroffen.", + "207": "Het geüploade bestand is hernoemd naar: \"{name}\".", + "300": "Bestand(en) verplaatsen is mislukt.", + "301": "Bestand(en) kopiëren is mislukt.", + "302": "Deleting file(s) failed.", + "500": "Het uploaden van een bestand is momenteel niet mogelijk. Contacteer de beheerder en controleer het CKFinder configuratiebestand.", + "501": "De ondersteuning voor miniatuurafbeeldingen is uitgeschakeld." + }, + "deleteFilePermissions": "Removing files is not allowed in this folder.", + "fileInvalidCharacters": "De bestandsnaam mag de volgende tekens niet bevatten: {disallowedCharacters}", + "fileNameNotEmpty": "The file name cannot be empty.", + "folderInvalidCharacters": "De mapnaam mag de volgende tekens niet bevatten: {disallowedCharacters}", + "incorrectExtension": "Bestandsextensie is niet toegestaan in deze map.", + "missingFile": "The requested file is no longer available.", + "missingFolder": "The folder you are trying to reach is no longer available.", + "noUploadFolderSelected": "Selecteer a.u.b. een map voordat je gaat uploaden.", + "operationCompleted": "Operation completed with errors.", + "renameFilePermissions": "Renaming files is not allowed in this folder.", + "unknown": "Het was niet mogelijk om deze actie uit te voeren. (Fout {number})", + "unknownUploadError": "Fout bij het versturen van het bestand.", + "uploadErrors": "Upload finished with errors.", + "uploadPermissions": "Uploaden bestand niet toegestaan." + }, + "chooseResizedImage": { + "title": "Choose Resized", + "originalSize": "Original Size", + "sizes": { + "custom": "Custom", + "large": "Large", + "max": "Max", + "medium": "Medium", + "small": "Small" + } + }, + "editImage": { + "adjust": "Adjust", + "apply": "Apply", + "confirmExit": "Are you sure you want to close? You have unsaved changes to the image.", + "crop": "Crop", + "downloadAction": "Downloading original image.", + "keepAspectRatio": "Keep Aspect Ratio", + "loading": "Loading image", + "presets": "Presets", + "reset": "Reset", + "resize": "Resize", + "rotate": "Rotate", + "rotateAntiClockwise": "90° Left", + "rotateClockwise": "90° Right", + "save": "Save", + "saveDialogFileExists": "File with the same name already exists in folder.", + "saveDialogOverwrite": "Overwrite File", + "saveDialogSaveAs": "Save as:", + "saveDialogTitle": "Save Changes", + "title": "Edit Image", + "transformationAction": "Applying transformations.", + "uploadAction": "Uploading edited image.", + "filters": { + "brightness": "Brightness", + "clip": "Clip", + "contrast": "Contrast", + "exposure": "Exposure", + "gamma": "Gamma", + "hue": "Hue", + "noise": "Noise", + "saturation": "Saturation", + "sepia": "Sepia", + "sharpen": "Sharpen", + "stackBlur": "Blur", + "vibrance": "Vibrance" + }, + "preset": { + "clarity": "Clarity", + "concentrate": "Concentrate", + "crossProcess": "Cross Process", + "glowingSun": "Glowing Sun", + "grungy": "Grungy", + "hazyDays": "Hazy Days", + "hemingway": "Hemingway", + "herMajesty": "Her Majesty", + "jarques": "Jarques", + "lomo": "Lomo", + "love": "Love", + "nostalgia": "Nostalgia", + "oldBoot": "Old Boot", + "orangePeel": "Orange Peel", + "pinhole": "Pinhole", + "sinCity": "Sin City", + "sunrise": "Sunrise", + "vintage": "Vintage" + } + }, + "shortcuts": { + "title": "Keyboard Shortcuts", + "general": { + "action": "Execute default action", + "firstItem": "Go to first item", + "focusFilesPane": "Focus files pane", + "focusFoldersPane": "Focus folders pane or breadcrumbs", + "focusNext": "Focus next pane", + "focusToolbar": "Focus toolbar", + "lastItem": "Go to last item", + "listShortcuts": "Open this help dialog", + "nextItem": "Go to next item", + "previousItem": "Go to previous item", + "showContextMenu": "Open context menu", + "title": "General Interface" + }, + "files": { + "addToSelectionAbove": "Add or remove files above to selection", + "addToSelectionBelow": "Add or remove files below to selection", + "addToSelectionLeft": "Add or remove file on the left to selection", + "addToSelectionRight": "Add or remove file on the right to selection", + "delete": "Delete file(s)", + "refresh": "Refresh files", + "rename": "Rename file", + "selectAll": "Select all files", + "upload": "Upload file(s)" + }, + "folders": { + "collapseOrParent": "Collapse folder / Go to parent folder", + "delete": "Delete folder", + "expandOrSubfolder": "Expand folder / Go to first subfolder", + "title": "Folders Pane" + }, + "keys": { + "ctrl": "Control", + "delete": "Delete", + "downArrow": "Down arrow", + "escape": "Escape", + "leftArrow": "Left arrow", + "question": "Question mark", + "rightArrow": "Right arrow", + "upArrow": "Up arrow" + }, + "keysAbbreviations": { + "alt": "alt", + "ctrl": "ctrl", + "del": "del", + "end": "end", + "home": "home", + "shift": "shift" + } + } +} diff --git a/lib/ckfinder/lang/nn.json b/lib/ckfinder/lang/nn.json new file mode 100644 index 0000000..3bf5037 --- /dev/null +++ b/lib/ckfinder/lang/nn.json @@ -0,0 +1,288 @@ +{ + "appTitle": "CKFinder", + "dir": "ltr", + "langCode": "nn", + "common": { + "abort": "Abort", + "cancel": "Avbryt", + "choose": "Choose", + "close": "Lukk", + "copy": "Copy", + "delete": "Slett", + "download": "Last ned", + "edit": "Rediger", + "maximize": "Maksimer", + "messageTitle": "Informasjon", + "minimize": "Minimer", + "move": "Move", + "newNameDialogTitle": "Nytt navn", + "ok": "OK", + "pleaseWait": "vennligst vent.", + "rememberDecision": "Husk mitt valg", + "rename": "Endre navn", + "showMore": "Show more", + "skip": "Hopp over", + "upload": "Last opp", + "view": "Vis fullversjon" + }, + "units": { + "dateFormat": "dd/mm/yyyy HH:MM", + "dateAmPm": [ + "AM", + "PM" + ], + "kb": "{size} KB", + "mb": "{size} MB", + "gb": "{size} GB", + "sizePerSecond": "{size}/s", + "pixelShort": "px" + }, + "files": { + "autoRename": "Gi nytt navn automatisk", + "countMany": "{count} filer", + "countOne": "1 fil", + "deleteConfirmation": "Are you sure you want to delete {count} files?", + "fileDeleteConfirmation": "Er du sikker på at du vil slette denne filen \"{name}\"?", + "fileRenameExtensionConfirmation": "Er du sikker på at du vil endre filtypen? Filen kan bli ubrukelig.", + "fileRenameLabel": "Skriv inn det nye filnavnet: ", + "filesPaneTitle": "Files pane", + "filesRefresh": "Refreshing files", + "filterPlaceholder": "Filter", + "gettingFileData": "Getting file data.", + "overwrite": "Overskriv", + "loadingFilesPane": { + "title": "Loading...", + "text": "The files are being loaded." + }, + "emptyFilesPane": { + "title": "The folder is empty.", + "text": "Use the Upload button or drag and drop your files here." + }, + "filterFilesEmpty": { + "title": "Nothing found.", + "text": "Please try using different search criteria." + } + }, + "folders": { + "deleteConfirmation": "Er du sikker på at du vil slette mappen \"{name}\"?", + "destinationFolder": "Destination Folder", + "newNameLabel": "Skriv inn det nye mappenavnet: ", + "newSubfolder": "Ny undermappe", + "renameDialogTitle": "Rename Folder", + "treeTitle": "Folders tree" + }, + "copy": { + "dropMenuItem": "Kopier hit", + "errorDialogTitle": "Files that cannot be copied:", + "manyFilesDialogTitle": "Copy {count} Files To...", + "manyFilesWait": "Copying {count} files.", + "oneFileDialogTitle": "Copy File To...", + "oneFileWait": "Copying file.", + "operationLabel": "Copying Files", + "operationSummary": "Number of files copied: {count}." + }, + "move": { + "dropMenuItem": "Flytt hit", + "errorDialogTitle": "Files that cannot be moved:", + "manyFilesDialogTitle": "Move {count} Files To...", + "manyFilesWait": "Moving {count} files.", + "oneFileDialogTitle": "Move File To...", + "oneFileWait": "Moving file.", + "operationLabel": "Moving Files", + "operationSummary": "Number of files moved: {count}." + }, + "upload": { + "addFiles": "Legg til filer", + "bytesCountProgress": "({bytesUploaded} of {bytesTotal})", + "details": "Details", + "filesCountProgress": "{filesUploaded} of {filesTotal}", + "progressLabel": "Laster opp filen.", + "progressMessage": "Uploading...", + "selectFileLabel": "Velg filen du vil laste opp", + "selectFiles": "Select files to upload", + "success": "Upload finished!", + "summary": "Uploaded files: {count}" + }, + "settings": { + "display": "Vis:", + "displayDate": "Dato", + "displayName": "Filnavn", + "displaySize": "Filstørrelse", + "sortAscending": "Ascending", + "sortBy": "Sort by", + "sortByOrder": "Order", + "sortDescending": "Descending", + "thumbnailSize": "Thumbnail Size", + "title": "Innstillinger", + "viewType": "View", + "viewTypeCompact": "Compact", + "viewTypeList": "List", + "viewTypeThumbnails": "Thumbnails" + }, + "errors": { + "codes": { + "10": "Ugyldig kommando.", + "11": "Ressurstypen ble ikke spesifisert i forepørselen.", + "12": "Ugyldig ressurstype.", + "13": "The connector configuration file is invalid.", + "14": "Invalid connector plugin: {pluginName}.", + "102": "Ugyldig fil- eller mappenavn.", + "103": "Kunne ikke utføre forespørselen pga manglende autorisasjon.", + "104": "Kunne ikke utføre forespørselen pga manglende tilgang til filsystemet.", + "105": "Ugyldig filtype.", + "109": "Ugyldig forespørsel.", + "110": "Ukjent feil.", + "111": "It was not possible to complete the request due to resulting file size.", + "115": "Det finnes allerede en fil eller mappe med dette navnet.", + "116": "Kunne ikke finne mappen. Oppdater vinduet og prøv igjen.", + "117": "Kunne ikke finne filen. Oppdater vinduet og prøv igjen.", + "118": "Kilde- og mål-bane er like.", + "201": "Det fantes allerede en fil med dette navnet. Den opplastede filens navn har blitt endret til \"{name}\".", + "202": "Ugyldig fil.", + "203": "Ugyldig fil. Filen er for stor.", + "204": "Den opplastede filen er korrupt.", + "205": "Det finnes ingen midlertidig mappe for filopplastinger.", + "206": "Opplastingen ble avbrutt av sikkerhetshensyn. Filen inneholder HTML-aktig data.", + "207": "Den opplastede filens navn har blitt endret til \"{name}\".", + "300": "Klarte ikke å flytte fil(er).", + "301": "Klarte ikke å kopiere fil(er).", + "302": "Deleting file(s) failed.", + "500": "Filvelgeren ikke tilgjengelig av sikkerhetshensyn. Kontakt systemansvarlig og be han sjekke CKFinder's konfigurasjonsfil.", + "501": "Funksjon for minityrbilder er skrudd av." + }, + "deleteFilePermissions": "Removing files is not allowed in this folder.", + "fileInvalidCharacters": "Filnavnet kan ikke inneholde følgende tegn: {disallowedCharacters}", + "fileNameNotEmpty": "The file name cannot be empty.", + "folderInvalidCharacters": "Mappenavnet kan ikke inneholde følgende tegn: {disallowedCharacters}", + "incorrectExtension": "Filtypen er ikke tillatt i denne mappen.", + "missingFile": "The requested file is no longer available.", + "missingFolder": "The folder you are trying to reach is no longer available.", + "noUploadFolderSelected": "Vennligst velg en mappe før du laster opp.", + "operationCompleted": "Operation completed with errors.", + "renameFilePermissions": "Renaming files is not allowed in this folder.", + "unknown": "Det var ikke mulig å utføre forespørselen. (Feil {number})", + "unknownUploadError": "Feil ved sending av fil.", + "uploadErrors": "Upload finished with errors.", + "uploadPermissions": "Filopplastning er ikke tillatt." + }, + "chooseResizedImage": { + "title": "Choose Resized", + "originalSize": "Original Size", + "sizes": { + "custom": "Custom", + "large": "Large", + "max": "Max", + "medium": "Medium", + "small": "Small" + } + }, + "editImage": { + "adjust": "Adjust", + "apply": "Apply", + "confirmExit": "Are you sure you want to close? You have unsaved changes to the image.", + "crop": "Crop", + "downloadAction": "Downloading original image.", + "keepAspectRatio": "Keep Aspect Ratio", + "loading": "Loading image", + "presets": "Presets", + "reset": "Reset", + "resize": "Resize", + "rotate": "Rotate", + "rotateAntiClockwise": "90° Left", + "rotateClockwise": "90° Right", + "save": "Save", + "saveDialogFileExists": "File with the same name already exists in folder.", + "saveDialogOverwrite": "Overwrite File", + "saveDialogSaveAs": "Save as:", + "saveDialogTitle": "Save Changes", + "title": "Edit Image", + "transformationAction": "Applying transformations.", + "uploadAction": "Uploading edited image.", + "filters": { + "brightness": "Brightness", + "clip": "Clip", + "contrast": "Contrast", + "exposure": "Exposure", + "gamma": "Gamma", + "hue": "Hue", + "noise": "Noise", + "saturation": "Saturation", + "sepia": "Sepia", + "sharpen": "Sharpen", + "stackBlur": "Blur", + "vibrance": "Vibrance" + }, + "preset": { + "clarity": "Clarity", + "concentrate": "Concentrate", + "crossProcess": "Cross Process", + "glowingSun": "Glowing Sun", + "grungy": "Grungy", + "hazyDays": "Hazy Days", + "hemingway": "Hemingway", + "herMajesty": "Her Majesty", + "jarques": "Jarques", + "lomo": "Lomo", + "love": "Love", + "nostalgia": "Nostalgia", + "oldBoot": "Old Boot", + "orangePeel": "Orange Peel", + "pinhole": "Pinhole", + "sinCity": "Sin City", + "sunrise": "Sunrise", + "vintage": "Vintage" + } + }, + "shortcuts": { + "title": "Keyboard Shortcuts", + "general": { + "action": "Execute default action", + "firstItem": "Go to first item", + "focusFilesPane": "Focus files pane", + "focusFoldersPane": "Focus folders pane or breadcrumbs", + "focusNext": "Focus next pane", + "focusToolbar": "Focus toolbar", + "lastItem": "Go to last item", + "listShortcuts": "Open this help dialog", + "nextItem": "Go to next item", + "previousItem": "Go to previous item", + "showContextMenu": "Open context menu", + "title": "General Interface" + }, + "files": { + "addToSelectionAbove": "Add or remove files above to selection", + "addToSelectionBelow": "Add or remove files below to selection", + "addToSelectionLeft": "Add or remove file on the left to selection", + "addToSelectionRight": "Add or remove file on the right to selection", + "delete": "Delete file(s)", + "refresh": "Refresh files", + "rename": "Rename file", + "selectAll": "Select all files", + "upload": "Upload file(s)" + }, + "folders": { + "collapseOrParent": "Collapse folder / Go to parent folder", + "delete": "Delete folder", + "expandOrSubfolder": "Expand folder / Go to first subfolder", + "title": "Folders Pane" + }, + "keys": { + "ctrl": "Control", + "delete": "Delete", + "downArrow": "Down arrow", + "escape": "Escape", + "leftArrow": "Left arrow", + "question": "Question mark", + "rightArrow": "Right arrow", + "upArrow": "Up arrow" + }, + "keysAbbreviations": { + "alt": "alt", + "ctrl": "ctrl", + "del": "del", + "end": "end", + "home": "home", + "shift": "shift" + } + } +} diff --git a/lib/ckfinder/lang/no.json b/lib/ckfinder/lang/no.json new file mode 100644 index 0000000..e7ead67 --- /dev/null +++ b/lib/ckfinder/lang/no.json @@ -0,0 +1,288 @@ +{ + "appTitle": "CKFinder", + "dir": "ltr", + "langCode": "nb", + "common": { + "abort": "Abort", + "cancel": "Avbryt", + "choose": "Velg", + "close": "Lukk", + "copy": "Kopier", + "delete": "Slett", + "download": "Last ned", + "edit": "Rediger", + "maximize": "Maksimer", + "messageTitle": "Informasjon", + "minimize": "Minimer", + "move": "Flytt", + "newNameDialogTitle": "Nytt navn", + "ok": "OK", + "pleaseWait": "Vennligst vent", + "rememberDecision": "Husk mitt valg", + "rename": "Endre navn", + "showMore": "Vis mer", + "skip": "Hopp over", + "upload": "Last opp", + "view": "Vis fullversjon" + }, + "units": { + "dateFormat": "dd/mm/yyyy HH:MM", + "dateAmPm": [ + "AM", + "PM" + ], + "kb": "{size} KB", + "mb": "{size} MB", + "gb": "{size} GB", + "sizePerSecond": "{size}/s", + "pixelShort": "px" + }, + "files": { + "autoRename": "Gi nytt navn automatisk", + "countMany": "{count} filer", + "countOne": "1 fil", + "deleteConfirmation": "Er du sikker på at du vil slette {count} filer?", + "fileDeleteConfirmation": "Er du sikker på at du vil slette denne filen \"{name}\"?", + "fileRenameExtensionConfirmation": "Er du sikker på at du vil endre filtypen? Filen kan bli ubrukelig.", + "fileRenameLabel": "Skriv inn det nye filnavnet: ", + "filesPaneTitle": "Files pane", + "filesRefresh": "Refreshing files", + "filterPlaceholder": "Filter", + "gettingFileData": "Henter fildata,", + "overwrite": "Overskriv", + "loadingFilesPane": { + "title": "Laster...", + "text": "Filene lastes." + }, + "emptyFilesPane": { + "title": "Mappen er tom.", + "text": "Bruk Last opp-knappen eller trekk filene dine hit." + }, + "filterFilesEmpty": { + "title": "Ingenting funnet.", + "text": "Prøv igjen med andre søkekriterier." + } + }, + "folders": { + "deleteConfirmation": "Er du sikker på at du vil slette mappen \"{name}\"?", + "destinationFolder": "Målmappe", + "newNameLabel": "Skriv inn det nye mappenavnet: ", + "newSubfolder": "Ny undermappe", + "renameDialogTitle": "Rename Folder", + "treeTitle": "Folders tree" + }, + "copy": { + "dropMenuItem": "Kopier hit", + "errorDialogTitle": "Filer som ikke kan kopieres:", + "manyFilesDialogTitle": "Kopier {count} filer til...", + "manyFilesWait": "Kopierer {count} filer,", + "oneFileDialogTitle": "Kopier filen til...", + "oneFileWait": "Kopierer filen,", + "operationLabel": "Kopierer filer", + "operationSummary": "Antall filer kopiert: {count}." + }, + "move": { + "dropMenuItem": "Flytt hit", + "errorDialogTitle": "Filer som ikke kan flyttes:", + "manyFilesDialogTitle": "Flytt {count} filer til...", + "manyFilesWait": "Flytter {count} filer,", + "oneFileDialogTitle": "Flytt filen til...", + "oneFileWait": "Flytter filen,", + "operationLabel": "Flytter filer", + "operationSummary": "Antall filer flyttet: {count}." + }, + "upload": { + "addFiles": "Legg til filer", + "bytesCountProgress": "({bytesUploaded} av {bytesTotal})", + "details": "Detaljer", + "filesCountProgress": "{filesUploaded} av {filesTotal}", + "progressLabel": "Laster opp filen.", + "progressMessage": "Laster opp...", + "selectFileLabel": "Velg filen du vil laste opp", + "selectFiles": "Velg filer for opplasting", + "success": "Opplasting fullført!", + "summary": "Opplastede filer: {count}" + }, + "settings": { + "display": "Vis:", + "displayDate": "Dato", + "displayName": "Filnavn", + "displaySize": "Filstørrelse", + "sortAscending": "Ascending", + "sortBy": "Sort by", + "sortByOrder": "Order", + "sortDescending": "Descending", + "thumbnailSize": "Miniatyrbildestørrelse", + "title": "Innstillinger", + "viewType": "View", + "viewTypeCompact": "Compact", + "viewTypeList": "List", + "viewTypeThumbnails": "Thumbnails" + }, + "errors": { + "codes": { + "10": "Ugyldig kommando.", + "11": "Ressurstypen ble ikke spesifisert i forespørselen.", + "12": "Ugyldig ressurstype.", + "13": "Konfigurasjonsfilen for forbindelsen er ugyldig.", + "14": "Ugyldig programvareutvidelse: {pluginName}.", + "102": "Ugyldig fil- eller mappenavn.", + "103": "Kunne ikke utføre forespørselen grunnet manglende tilgang.", + "104": "Kunne ikke utføre forespørselen grunnet manglende tilgang til filsystemet.", + "105": "Ugyldig filtype.", + "109": "Ugyldig forespørsel.", + "110": "Ukjent feil.", + "111": "Det var ikke mulig å fullføre handlingen på grunn av filstørrelsen.", + "115": "Det finnes allerede en fil eller mappe med dette navnet.", + "116": "Kunne ikke finne mappen. Last vinduet på nytt og prøv igjen.", + "117": "Kunne ikke finne filen. Last vinduet på nytt og prøv igjen.", + "118": "Kilde- og mål-bane er like.", + "201": "Det fantes allerede en fil med dette navnet. Den opplastede filens navn har blitt endret til \"{name}\".", + "202": "Ugyldig fil.", + "203": "Ugyldig fil. Filen er for stor.", + "204": "Den opplastede filen er korrupt.", + "205": "Det finnes ingen midlertidig mappe for filopplastinger.", + "206": "Opplastingen ble avbrutt av sikkerhetshensyn. Filen inneholder HTML-aktige data.", + "207": "Den opplastede filens navn har blitt endret til \"{name}\".", + "300": "Klarte ikke å flytte fil(er).", + "301": "Klarte ikke å kopiere fil(er).", + "302": "Sletting av fil(er) feilet.", + "500": "Filvelgeren ikke tilgjengelig av sikkerhetshensyn. Kontakt systemansvarlig og be ham sjekke CKFinders konfigurasjonsfil.", + "501": "Funksjon for miniatyrbilder er skrudd av." + }, + "deleteFilePermissions": "Removing files is not allowed in this folder.", + "fileInvalidCharacters": "Filnavnet kan ikke inneholde følgende tegn: {disallowedCharacters}", + "fileNameNotEmpty": "The file name cannot be empty.", + "folderInvalidCharacters": "Mappenavnet kan ikke inneholde følgende tegn: {disallowedCharacters}", + "incorrectExtension": "Filtypen er ikke tillatt i denne mappen.", + "missingFile": "Den forespurte filen finnes ikke lengre.", + "missingFolder": "Mappen du forsøker å nå er ikke lengre tilgjengelig.", + "noUploadFolderSelected": "Vennligst velg en mappe før du laster opp.", + "operationCompleted": "Handlingen ble utført med feil.", + "renameFilePermissions": "Renaming files is not allowed in this folder.", + "unknown": "Det var ikke mulig å utføre forespørselen. (Feil {number})", + "unknownUploadError": "Feil ved sending av fil.", + "uploadErrors": "Opplasting fullført med feil.", + "uploadPermissions": "Filopplastning er ikke tillatt." + }, + "chooseResizedImage": { + "title": "Velg skalert", + "originalSize": "Originalstørrelse", + "sizes": { + "custom": "Selvvalgt", + "large": "Stor", + "max": "Maks", + "medium": "Middels", + "small": "Liten" + } + }, + "editImage": { + "adjust": "Juster", + "apply": "Bruk", + "confirmExit": "Are you sure you want to close? You have unsaved changes to the image.", + "crop": "Utsnitt", + "downloadAction": "Laster ned originalbildet.", + "keepAspectRatio": "Behold sideforhold", + "loading": "Laster bilde", + "presets": "Forhåndsinnstillinger", + "reset": "Tilbakestill", + "resize": "Endre størrelse", + "rotate": "Roter", + "rotateAntiClockwise": "90° venstre", + "rotateClockwise": "90° høyre", + "save": "Lagre", + "saveDialogFileExists": "En fil med det samme navnet finnes allerede i mappen.", + "saveDialogOverwrite": "Overskriv fil", + "saveDialogSaveAs": "Lagre som:", + "saveDialogTitle": "Lagre endringene", + "title": "Rediger bilde", + "transformationAction": "Utfører forandringer.", + "uploadAction": "Laster opp endret bilde.", + "filters": { + "brightness": "Lysstyrke", + "clip": "Klipp", + "contrast": "Kontrast", + "exposure": "Eksponering", + "gamma": "Gamma", + "hue": "Fargetone", + "noise": "Støy", + "saturation": "Fargemetning", + "sepia": "Sepia", + "sharpen": "Skjerpe", + "stackBlur": "Stack Blur", + "vibrance": "Glød" + }, + "preset": { + "clarity": "Klarhet", + "concentrate": "Konsentrert", + "crossProcess": "Kryssprosesser", + "glowingSun": "Glødende sol", + "grungy": "Grungy", + "hazyDays": "Disige dager", + "hemingway": "Hemingway", + "herMajesty": "Hennes majestet", + "jarques": "Jarques", + "lomo": "Lomo", + "love": "Kjærlighet", + "nostalgia": "Nostalgi", + "oldBoot": "Old Boot", + "orangePeel": "Appelsinskall", + "pinhole": "Knappenålshull", + "sinCity": "Sin City", + "sunrise": "Soloppgang", + "vintage": "Vintage" + } + }, + "shortcuts": { + "title": "Keyboard Shortcuts", + "general": { + "action": "Execute default action", + "firstItem": "Go to first item", + "focusFilesPane": "Focus files pane", + "focusFoldersPane": "Focus folders pane or breadcrumbs", + "focusNext": "Focus next pane", + "focusToolbar": "Focus toolbar", + "lastItem": "Go to last item", + "listShortcuts": "Open this help dialog", + "nextItem": "Go to next item", + "previousItem": "Go to previous item", + "showContextMenu": "Open context menu", + "title": "General Interface" + }, + "files": { + "addToSelectionAbove": "Add or remove files above to selection", + "addToSelectionBelow": "Add or remove files below to selection", + "addToSelectionLeft": "Add or remove file on the left to selection", + "addToSelectionRight": "Add or remove file on the right to selection", + "delete": "Delete file(s)", + "refresh": "Refresh files", + "rename": "Rename file", + "selectAll": "Select all files", + "upload": "Upload file(s)" + }, + "folders": { + "collapseOrParent": "Collapse folder / Go to parent folder", + "delete": "Delete folder", + "expandOrSubfolder": "Expand folder / Go to first subfolder", + "title": "Folders Pane" + }, + "keys": { + "ctrl": "Control", + "delete": "Delete", + "downArrow": "Ned-piltast", + "escape": "Escape", + "leftArrow": "Venstre piltast", + "question": "Question mark", + "rightArrow": "Høyre piltast", + "upArrow": "Opp-piltast" + }, + "keysAbbreviations": { + "alt": "alt", + "ctrl": "ctrl", + "del": "del", + "end": "end", + "home": "home", + "shift": "shift" + } + } +} diff --git a/lib/ckfinder/lang/pl.json b/lib/ckfinder/lang/pl.json new file mode 100644 index 0000000..ad526ad --- /dev/null +++ b/lib/ckfinder/lang/pl.json @@ -0,0 +1,288 @@ +{ + "appTitle": "CKFinder", + "dir": "ltr", + "langCode": "pl", + "common": { + "abort": "Przerwij", + "cancel": "Anuluj", + "choose": "Wybierz", + "close": "Zamknij", + "copy": "Skopiuj", + "delete": "Usuń", + "download": "Pobierz", + "edit": "Edytuj", + "maximize": "Maksymalizuj", + "messageTitle": "Informacja", + "minimize": "Minimalizuj", + "move": "Przenieś", + "newNameDialogTitle": "Nowa nazwa", + "ok": "OK", + "pleaseWait": "Proszę czekać.", + "rememberDecision": "Zapamiętaj mój wybór", + "rename": "Zmień nazwę", + "showMore": "Pokaż więcej", + "skip": "Pomiń", + "upload": "Wyślij", + "view": "Zobacz" + }, + "units": { + "dateFormat": "yyyy-mm-dd HH:MM", + "dateAmPm": [ + "AM", + "PM" + ], + "kb": "{size} KB", + "mb": "{size} MB", + "gb": "{size} GB", + "sizePerSecond": "{size}/s", + "pixelShort": "px" + }, + "files": { + "autoRename": "Zmień automatycznie nazwę", + "countMany": "Liczba plików: {count}", + "countOne": "1 plik", + "deleteConfirmation": "Czy na pewno chcesz usunąć pliki (razem: {count})?", + "fileDeleteConfirmation": "Czy na pewno chcesz usunąć plik \"{name}\"?", + "fileRenameExtensionConfirmation": "Czy na pewno chcesz zmienić rozszerzenie pliku? Może to spowodować problemy z otwieraniem pliku.", + "fileRenameLabel": "Podaj nową nazwę pliku: ", + "filesPaneTitle": "Panel plików", + "filesRefresh": "Odświeżanie plików", + "filterPlaceholder": "Filtruj", + "gettingFileData": "Pobieranie informacji o pliku.", + "overwrite": "Nadpisz", + "loadingFilesPane": { + "title": "Ładowanie...", + "text": "Trwa ładowanie plików." + }, + "emptyFilesPane": { + "title": "Folder jest pusty.", + "text": "Użyj przycisku Wyślij lub przeciągnij i upuść pliki wewnątrz aplikacji." + }, + "filterFilesEmpty": { + "title": "Nic nie znaleziono.", + "text": "Spróbuj podać inne parametry wyszukiwania." + } + }, + "folders": { + "deleteConfirmation": "Czy na pewno chcesz usunąć folder \"{name}\"?", + "destinationFolder": "Folder docelowy", + "newNameLabel": "Podaj nazwę nowego folderu: ", + "newSubfolder": "Nowy podfolder", + "renameDialogTitle": "Zmień nazwę folderu", + "treeTitle": "Drzewo folderów" + }, + "copy": { + "dropMenuItem": "Skopiuj tutaj", + "errorDialogTitle": "Następujące pliki nie mogą być skopiowane:", + "manyFilesDialogTitle": "Skopiuj pliki ({count}) do...", + "manyFilesWait": "Kopiowanie {count} plików.", + "oneFileDialogTitle": "Skopiuj plik do...", + "oneFileWait": "Kopiowanie pliku.", + "operationLabel": "Kopiowanie plików", + "operationSummary": "Liczba skopiowanych plików: {count}." + }, + "move": { + "dropMenuItem": "Przenieś tutaj", + "errorDialogTitle": "Następujące pliki nie mogą być przeniesione:", + "manyFilesDialogTitle": "Przenieś pliki ({count}) do...", + "manyFilesWait": "Przenoszenie {count} plików.", + "oneFileDialogTitle": "Przenieś plik do...", + "oneFileWait": "Przenoszenie pliku.", + "operationLabel": "Przenoszenie plików", + "operationSummary": "Liczba przeniesionych plików: {count}." + }, + "upload": { + "addFiles": "Dodaj pliki", + "bytesCountProgress": "({bytesUploaded} z {bytesTotal})", + "details": "Szczegóły", + "filesCountProgress": "{filesUploaded} z {filesTotal}", + "progressLabel": "Trwa wysyłanie pliku.", + "progressMessage": "Wysyłanie...", + "selectFileLabel": "Wybierz plik", + "selectFiles": "Wybierz pliki do wysłania", + "success": "Wysyłanie zakończone!", + "summary": "Wysłano plików: {count}" + }, + "settings": { + "display": "Wyświetlanie:", + "displayDate": "Data", + "displayName": "Nazwa pliku", + "displaySize": "Rozmiar pliku", + "sortAscending": "Rosnąco", + "sortBy": "Sortuj po", + "sortByOrder": "Kolejność", + "sortDescending": "Malejąco", + "thumbnailSize": "Rozmiar miniatur", + "title": "Ustawienia", + "viewType": "Widok", + "viewTypeCompact": "Compact", + "viewTypeList": "Lista", + "viewTypeThumbnails": "Miniatury" + }, + "errors": { + "codes": { + "10": "Nieprawidłowe polecenie (command).", + "11": "Brak wymaganego parametru: typ danych (resource type).", + "12": "Nieprawidłowy typ danych (resource type).", + "13": "Plik konfiguracyjny connectora jest nieprawidłowy.", + "14": "Nieprawidłowy plugin: {pluginName}.", + "102": "Nieprawidłowa nazwa pliku lub folderu.", + "103": "Wykonanie operacji nie jest możliwe: brak uprawnień.", + "104": "Wykonanie operacji nie powiodło się z powodu niewystarczających uprawnień do systemu plików.", + "105": "Nieprawidłowe rozszerzenie.", + "109": "Nieprawidłowe żądanie.", + "110": "Niezidentyfikowany błąd.", + "111": "Wykonanie operacji nie powiodło się z powodu zbyt dużego rozmiaru pliku wynikowego.", + "115": "Plik lub folder o podanej nazwie już istnieje.", + "116": "Nie znaleziono folderu. Odśwież panel i spróbuj ponownie.", + "117": "Nie znaleziono pliku. Odśwież listę plików i spróbuj ponownie.", + "118": "Ścieżki źródłowa i docelowa są jednakowe.", + "201": "Plik o podanej nazwie już istnieje. Nazwa przesłanego pliku została zmieniona na \"{name}\".", + "202": "Nieprawidłowy plik.", + "203": "Nieprawidłowy plik. Plik przekracza dozwolony rozmiar.", + "204": "Przesłany plik jest uszkodzony.", + "205": "Brak folderu tymczasowego na serwerze do przesyłania plików.", + "206": "Przesyłanie pliku zakończyło się niepowodzeniem z powodów bezpieczeństwa. Plik zawiera dane przypominające HTML.", + "207": "Nazwa przesłanego pliku została zmieniona na \"{name}\".", + "300": "Przenoszenie nie powiodło się.", + "301": "Kopiowanie nie powiodło się.", + "302": "Usuwanie nie powiodło się.", + "500": "Menedżer plików jest wyłączony z powodów bezpieczeństwa. Skontaktuj się z administratorem oraz sprawdź plik konfiguracyjny CKFindera.", + "501": "Tworzenie miniatur jest wyłączone." + }, + "deleteFilePermissions": "Removing files is not allowed in this folder.", + "fileInvalidCharacters": "Nazwa pliku nie może zawierać żadnego z podanych znaków: {disallowedCharacters}", + "fileNameNotEmpty": "Nazwa pliku nie może być pusta.", + "folderInvalidCharacters": "Nazwa folderu nie może zawierać żadnego z podanych znaków: {disallowedCharacters}", + "incorrectExtension": "Rozszerzenie pliku nie jest dozwolone w tym folderze.", + "missingFile": "Żądany plik jest już niedostępny.", + "missingFolder": "Folder, do którego dostęp próbujesz uzyskać, jest już niedostępny.", + "noUploadFolderSelected": "Wybierz folder przed wysłaniem pliku.", + "operationCompleted": "Operacja zakończyła się błędem.", + "renameFilePermissions": "Renaming files is not allowed in this folder.", + "unknown": "Wykonanie operacji zakończyło się niepowodzeniem. (Błąd {number})", + "unknownUploadError": "Błąd podczas wysyłania pliku.", + "uploadErrors": "Wysyłanie zakończone z błędami.", + "uploadPermissions": "Wysyłanie plików nie jest dozwolone." + }, + "chooseResizedImage": { + "title": "Wybierz przeskalowany", + "originalSize": "Oryginalny rozmiar", + "sizes": { + "custom": "Własny", + "large": "Duży", + "max": "Maksymalny", + "medium": "Średni", + "small": "Mały" + } + }, + "editImage": { + "adjust": "Dostosuj", + "apply": "Zastosuj", + "confirmExit": "Czy jesteś pewien, że chcesz zamknąć okno? Obrazek ma niezapisane zmiany.", + "crop": "Kadrowanie", + "downloadAction": "Pobierz oryginalny obrazek.", + "keepAspectRatio": "Zachowaj proporcje", + "loading": "Ładowanie obrazka", + "presets": "Predefiniowane opcje", + "reset": "Resetuj", + "resize": "Zmień rozmiar", + "rotate": "Obróć", + "rotateAntiClockwise": "90° w lewo", + "rotateClockwise": "90° w prawo", + "save": "Zapisz", + "saveDialogFileExists": "Plik o tej nazwie już istnieje w folderze.", + "saveDialogOverwrite": "Nadpisać plik?", + "saveDialogSaveAs": "Zapisz jako:", + "saveDialogTitle": "Zapisz zmiany", + "title": "Edytuj obrazek", + "transformationAction": "Aplikowanie transformacji.", + "uploadAction": "Wysyłanie zedytowanego obrazka.", + "filters": { + "brightness": "Jasność", + "clip": "Przytnij", + "contrast": "Kontrast", + "exposure": "Ekspozycja", + "gamma": "Gamma", + "hue": "Barwa", + "noise": "Szum", + "saturation": "Nasycenie", + "sepia": "Sepia", + "sharpen": "Wyostrz", + "stackBlur": "Rozmyj", + "vibrance": "Vibrance" + }, + "preset": { + "clarity": "Przejrzystość", + "concentrate": "Koncentracja", + "crossProcess": "Cross processing", + "glowingSun": "Promienne słońce", + "grungy": "Grungy", + "hazyDays": "Mgliste dni", + "hemingway": "Hemingway", + "herMajesty": "Jej Wysokość", + "jarques": "Jarques", + "lomo": "Lomo", + "love": "Miłość", + "nostalgia": "Nostalgia", + "oldBoot": "Stary but", + "orangePeel": "Skórka pomarańczowa", + "pinhole": "Kamera otworkowa", + "sinCity": "Sin City", + "sunrise": "Wschód słońca", + "vintage": "Vintage" + } + }, + "shortcuts": { + "title": "Skróty klawiaturowe", + "general": { + "action": "Wykonaj domyślne działanie", + "firstItem": "Przejdź do pierwszego elementu", + "focusFilesPane": "Wybierz panel plików", + "focusFoldersPane": "Wybierz panel folderów lub ścieżkę folderów", + "focusNext": "Wybierz następny panel", + "focusToolbar": "Wybierz pasek narzędzi", + "lastItem": "Przejdź do ostatniego elementu", + "listShortcuts": "Otwórz to okno pomocy", + "nextItem": "Przejdź do następnego elementu", + "previousItem": "Przejdź do poprzedniego elementu", + "showContextMenu": "Otwórz menu kontekstowe", + "title": "Interfejs użytkownika" + }, + "files": { + "addToSelectionAbove": "Dodaj lub usuń pliki wyżej do zaznaczenia", + "addToSelectionBelow": "Dodaj lub usuń pliki niżej do zaznaczenia", + "addToSelectionLeft": "Dodaj lub usuń plik po lewej do zaznaczenia", + "addToSelectionRight": "Dodaj lub usuń plik po prawej do zaznaczenia", + "delete": "Usuń plik(i)", + "refresh": "Odśwież pliki", + "rename": "Zmień nazwę pliku", + "selectAll": "Zaznacz wszystkie pliki", + "upload": "Prześlij plik(i)" + }, + "folders": { + "collapseOrParent": "Zwiń folder / Przejdź do podfolderu nadrzędnego", + "delete": "Usuń folder", + "expandOrSubfolder": "Rozwiń folder / Przejdź do pierwszego podfolderu", + "title": "Panel folderów" + }, + "keys": { + "ctrl": "Control", + "delete": "Delete", + "downArrow": "Strzałka w dół", + "escape": "Escape", + "leftArrow": "Strzałka w lewo", + "question": "Znak zapytania", + "rightArrow": "Strzałka w prawo", + "upArrow": "Strzałka w górę" + }, + "keysAbbreviations": { + "alt": "alt", + "ctrl": "ctrl", + "del": "del", + "end": "end", + "home": "home", + "shift": "shift" + } + } +} diff --git a/lib/ckfinder/lang/pt-br.json b/lib/ckfinder/lang/pt-br.json new file mode 100644 index 0000000..5ad5a40 --- /dev/null +++ b/lib/ckfinder/lang/pt-br.json @@ -0,0 +1,288 @@ +{ + "appTitle": "CKFinder", + "dir": "ltr", + "langCode": "pt-br", + "common": { + "abort": "Abortar", + "cancel": "Cancelar", + "choose": "Usar", + "close": "Fechar", + "copy": "Copiar", + "delete": "Apagar", + "download": "Download", + "edit": "Editar", + "maximize": "Maximizar", + "messageTitle": "Informação", + "minimize": "Minimizar", + "move": "Mover", + "newNameDialogTitle": "Novo Nome", + "ok": "OK", + "pleaseWait": "Por favor, aguarde.", + "rememberDecision": "Lembrar minha decisão", + "rename": "Renomear", + "showMore": "Mostrar Mais", + "skip": "Ignorar", + "upload": "Enviar Arquivo", + "view": "Visualizar" + }, + "units": { + "dateFormat": "dd/mm/yyyy HH:MM", + "dateAmPm": [ + "AM", + "PM" + ], + "kb": "{size} KB", + "mb": "{size} MB", + "gb": "{size} GB", + "sizePerSecond": "{size}/s", + "pixelShort": "px" + }, + "files": { + "autoRename": "Renomear automaticamente", + "countMany": "{count} arquivos", + "countOne": "1 arquivo", + "deleteConfirmation": "Tem certeza que deseja apagar os {count} arquivos?", + "fileDeleteConfirmation": "Tem certeza que deseja apagar o arquivo \"{name}\"?", + "fileRenameExtensionConfirmation": "Tem certeza que deseja alterar a extensão do arquivo? O arquivo pode ser danificado.", + "fileRenameLabel": "Novo nome do arquivo: ", + "filesPaneTitle": "Painel de arquivos", + "filesRefresh": "Atualizando arquivos", + "filterPlaceholder": "Filtro", + "gettingFileData": "Lendo informações do arquivo.", + "overwrite": "Sobrescrever", + "loadingFilesPane": { + "title": "Carregando...", + "text": "Carregando os arquivos." + }, + "emptyFilesPane": { + "title": "Esta pasta está vazia.", + "text": "Use o botão Enviar Arquivo ou arraste e solte seus arquivos aqui." + }, + "filterFilesEmpty": { + "title": "Nenhuma ocorrência encontrada.", + "text": "Tente outros termos de pesquisa." + } + }, + "folders": { + "deleteConfirmation": "Tem certeza que deseja apagar a pasta \"{name}\"?", + "destinationFolder": "Pasta Destino", + "newNameLabel": "Nome da nova pasta: ", + "newSubfolder": "Nova sub-pasta", + "renameDialogTitle": "Renomear Pasta", + "treeTitle": "Árvore de pastas" + }, + "copy": { + "dropMenuItem": "Copiar Aqui", + "errorDialogTitle": "Arquivos que não puderam ser copiados:", + "manyFilesDialogTitle": "Copiar {count} Arquivos Para...", + "manyFilesWait": "Copiando {count} arquivos.", + "oneFileDialogTitle": "Copiar Arquivo Para...", + "oneFileWait": "Copiando arquivo.", + "operationLabel": "Copiando Arquivos", + "operationSummary": "Número de arquivos copiados: {count}." + }, + "move": { + "dropMenuItem": "Mover Aqui", + "errorDialogTitle": "Arquivos que não puderam ser movidos:", + "manyFilesDialogTitle": "Mover {count} Arquivos Para...", + "manyFilesWait": "Movendo {count} arquivos.", + "oneFileDialogTitle": "Mover Arquivo Para...", + "oneFileWait": "Movendo arquivo.", + "operationLabel": "Movendo Arquivos", + "operationSummary": "Número de arquivos movidos: {count}." + }, + "upload": { + "addFiles": "Adicionar Arquivos", + "bytesCountProgress": "({bytesUploaded} de {bytesTotal})", + "details": "Detalhes", + "filesCountProgress": "{filesUploaded} de {filesTotal}", + "progressLabel": "Enviando arquivo.", + "progressMessage": "Enviando...", + "selectFileLabel": "Selecione o arquivo para enviar", + "selectFiles": "Selecione os arquivos para enviar", + "success": "Enviado com sucesso!", + "summary": "Arquivos enviados: {count}" + }, + "settings": { + "display": "Exibir", + "displayDate": "Data", + "displayName": "Arquivo", + "displaySize": "Tamanho", + "sortAscending": "Crescente", + "sortBy": "Ordernar por", + "sortByOrder": "Ordem", + "sortDescending": "Decrescente", + "thumbnailSize": "Tamanho da Miniatura", + "title": "Configurações", + "viewType": "Exibir", + "viewTypeCompact": "Compact", + "viewTypeList": "Lista", + "viewTypeThumbnails": "Miniaturas" + }, + "errors": { + "codes": { + "10": "Comando inválido.", + "11": "O tipo de recurso não foi especificado na solicitação.", + "12": "O tipo de recurso solicitado não é válido.", + "13": "O arquivo de configuração do conector não é válido.", + "14": "Plugin para o conector inválido: {pluginName}.", + "102": "Nome do arquivo ou pasta inválido.", + "103": "Não foi possível completar a solicitação por restrições de acesso.", + "104": "Não foi possível completar a solicitação por restrições de acesso do sistema de arquivos.", + "105": "Extensão de arquivo inválida.", + "109": "Solicitação inválida.", + "110": "Erro desconhecido.", + "111": "Impossível completar o pedido devido ao tamanho final do arquivo.", + "115": "Um arquivo ou pasta já existe com esse nome.", + "116": "Pasta não encontrada. Atualize e tente novamente.", + "117": "Arquivo não encontrado. Atualize a lista de arquivos e tente novamente.", + "118": "A origem e o destino são os mesmos.", + "201": "Um arquivo com o mesmo nome já está disponível. O arquivo enviado foi renomeado para \"{name}\".", + "202": "Arquivo inválido.", + "203": "Arquivo inválido. O tamanho é muito grande.", + "204": "O arquivo enviado está corrompido.", + "205": "Nenhuma pasta temporária para envio está disponível no servidor.", + "206": "Transmissão cancelada por razões de segurança. O arquivo contém dados HTML.", + "207": "O arquivo enviado foi renomeado para \"{name}\".", + "300": "Não foi possível mover o(s) arquivo(s).", + "301": "Não foi possível copiar o(s) arquivo(s).", + "302": "Não for possível apagar o(s) arquivo(s).", + "500": "A navegação de arquivos está desativada por razões de segurança. Contacte o administrador do sistema para controlar as configurações do CKFinder.", + "501": "O suporte a miniaturas está desabilitado." + }, + "deleteFilePermissions": "Removing files is not allowed in this folder.", + "fileInvalidCharacters": "O nome do arquivo não pode conter nenhum desses caracteres: {disallowedCharacters}", + "fileNameNotEmpty": "O nome do arquivo é obrigatório.", + "folderInvalidCharacters": "O nome da pasta não pode conter nenhum desses caracteres: {disallowedCharacters}", + "incorrectExtension": "A extensão deste arquivo não é permitida nesta pasta.", + "missingFile": "O arquivo solicitado não está mais disponível.", + "missingFolder": "A pasta que você está tentando abrir não está mais disponível.", + "noUploadFolderSelected": "Selecione a pasta antes the enviar o arquivo.", + "operationCompleted": "Operação completada com errors.", + "renameFilePermissions": "Renaming files is not allowed in this folder.", + "unknown": "Não foi possível completer o seu pedido. (Erro {number})", + "unknownUploadError": "Erro no envio do arquivo.", + "uploadErrors": "Envio terminado com errors.", + "uploadPermissions": "Não é permitido o envio de arquivos." + }, + "chooseResizedImage": { + "title": "Usar Redimensionada", + "originalSize": "Tamanho Original", + "sizes": { + "custom": "Personalizado", + "large": "Grande", + "max": "Máx", + "medium": "Médio", + "small": "Pequeno" + } + }, + "editImage": { + "adjust": "Ajustar", + "apply": "Aplicar", + "confirmExit": "Você tem certeza que quer encerrar? Algumas mudanças na imagem não foram registradas.", + "crop": "Cortar", + "downloadAction": "Carregando imagem original.", + "keepAspectRatio": "Manter as Proporções", + "loading": "Carregando Imagem...", + "presets": "Pre-Configurações", + "reset": "Restaurar", + "resize": "Redimensionar", + "rotate": "Girar", + "rotateAntiClockwise": "90° à Esquerda", + "rotateClockwise": "90° à Direita", + "save": "Salvar", + "saveDialogFileExists": "Já existe nesta pasta um arquivo com o mesmo nome.", + "saveDialogOverwrite": "Sobrescrever Arquivo", + "saveDialogSaveAs": "Salvar como:", + "saveDialogTitle": "Salvar Alterações", + "title": "Edição de Imagem", + "transformationAction": "Aplicando modificações.", + "uploadAction": "Enviando a imagem modificada.", + "filters": { + "brightness": "Brilho", + "clip": "Redução", + "contrast": "Contraste", + "exposure": "Exposição", + "gamma": "Gama", + "hue": "Matiz", + "noise": "Ruído", + "saturation": "Saturação", + "sepia": "Sépia", + "sharpen": "Nitidez", + "stackBlur": "Desfocagem", + "vibrance": "Vibração" + }, + "preset": { + "clarity": "Clareza", + "concentrate": "Concentrado", + "crossProcess": "Processo Cruzado", + "glowingSun": "Sol Crescente", + "grungy": "Enlameado", + "hazyDays": "Dia Nublado", + "hemingway": "Hemingway", + "herMajesty": "Sua Majestade", + "jarques": "Jarques", + "lomo": "Lomo", + "love": "Amor", + "nostalgia": "Saudades", + "oldBoot": "Old Boot", + "orangePeel": "Casca de Laranja", + "pinhole": "Câmera Obscura", + "sinCity": "Sin City", + "sunrise": "Nascer do Sol", + "vintage": "Antigo" + } + }, + "shortcuts": { + "title": "Teclas de Atalho", + "general": { + "action": "Executar a ação padrão", + "firstItem": "Ir para o primeiro item", + "focusFilesPane": "Foco no painel de arquivos", + "focusFoldersPane": "Foco na árvore de pastas ou no caminho de navegação", + "focusNext": "Foco no painel sucessivo", + "focusToolbar": "Foco na barra de ferramentas", + "lastItem": "Ir para o último item", + "listShortcuts": "Abrir esta janela de ajuda", + "nextItem": "Ir para o próximo item", + "previousItem": "Ir para o item anterior", + "showContextMenu": "Abrir o menu de contexto", + "title": "Interface Principal" + }, + "files": { + "addToSelectionAbove": "Adicionar ou remover o arquivo de cima à seleção", + "addToSelectionBelow": "Adicionar ou remover o arquivo de baixo à seleção", + "addToSelectionLeft": "Adicionar ou remover o arquivo da esquerda à seleção", + "addToSelectionRight": "Adicionar ou remover o arquivo da direita à seleção", + "delete": "Apagar arquivo(s)", + "refresh": "Atualizar arquivos", + "rename": "Renomear arquivo", + "selectAll": "Selecionar todos os arquivos", + "upload": "Enviar arquivo(s)" + }, + "folders": { + "collapseOrParent": "Fechar pasta / Ir para a pasta superior", + "delete": "Apagar pasta", + "expandOrSubfolder": "Expandir pasta / Ir para a primeira sub-pasta", + "title": "Painel de Pastas" + }, + "keys": { + "ctrl": "CTRL", + "delete": "Apagar", + "downArrow": "Seta para baixo", + "escape": "ESC", + "leftArrow": "Seta para a esquerda", + "question": "Interrogação", + "rightArrow": "Seta para a direita", + "upArrow": "Seta para cima" + }, + "keysAbbreviations": { + "alt": "alt", + "ctrl": "ctrl", + "del": "delete", + "end": "end", + "home": "home", + "shift": "shift" + } + } +} diff --git a/lib/ckfinder/lang/ro.json b/lib/ckfinder/lang/ro.json new file mode 100644 index 0000000..bb6f5c1 --- /dev/null +++ b/lib/ckfinder/lang/ro.json @@ -0,0 +1,288 @@ +{ + "appTitle": "CKFinder", + "dir": "ltr", + "langCode": "ro", + "common": { + "abort": "Abort", + "cancel": "Anulează", + "choose": "Choose", + "close": "Închide", + "copy": "Copy", + "delete": "Șterge", + "download": "Descarcă", + "edit": "Editează", + "maximize": "Maximizare", + "messageTitle": "Informații", + "minimize": "Minimizare", + "move": "Move", + "newNameDialogTitle": "Nume nou", + "ok": "OK", + "pleaseWait": "Te rog așteaptă.", + "rememberDecision": "Reține acțiunea pe viitor", + "rename": "Redenumește", + "showMore": "Show more", + "skip": "Sări", + "upload": "Încarcă", + "view": "Vizualizează" + }, + "units": { + "dateFormat": "dd/mm/yyyy HH:MM", + "dateAmPm": [ + "AM", + "PM" + ], + "kb": "{size} KB", + "mb": "{size} MB", + "gb": "{size} GB", + "sizePerSecond": "{size}/s", + "pixelShort": "px" + }, + "files": { + "autoRename": "Auto-redenumire", + "countMany": "{count} fișiere", + "countOne": "1 fișier", + "deleteConfirmation": "Are you sure you want to delete {count} files?", + "fileDeleteConfirmation": "Ești sigur că vrei să ștergi fișierul \"{name}\"?", + "fileRenameExtensionConfirmation": "Ești sigur că vrei să schimbi extensia fișierului? Fișierul poate deveni inutilizabil.", + "fileRenameLabel": "Te rugăm să introduci numele nou al fișierului: ", + "filesPaneTitle": "Files pane", + "filesRefresh": "Refreshing files", + "filterPlaceholder": "Filter", + "gettingFileData": "Getting file data.", + "overwrite": "Suprascriere", + "loadingFilesPane": { + "title": "Loading...", + "text": "The files are being loaded." + }, + "emptyFilesPane": { + "title": "The folder is empty.", + "text": "Use the Upload button or drag and drop your files here." + }, + "filterFilesEmpty": { + "title": "Nothing found.", + "text": "Please try using different search criteria." + } + }, + "folders": { + "deleteConfirmation": "Ești sigur că vrei să ștergi dosarul \"{name}\"?", + "destinationFolder": "Destination Folder", + "newNameLabel": "Te rugăm să introduci numele dosarului nou: ", + "newSubfolder": "Subdosar nou", + "renameDialogTitle": "Rename Folder", + "treeTitle": "Folders tree" + }, + "copy": { + "dropMenuItem": "Copiază aici", + "errorDialogTitle": "Files that cannot be copied:", + "manyFilesDialogTitle": "Copy {count} Files To...", + "manyFilesWait": "Copying {count} files.", + "oneFileDialogTitle": "Copy File To...", + "oneFileWait": "Copying file.", + "operationLabel": "Copying Files", + "operationSummary": "Number of files copied: {count}." + }, + "move": { + "dropMenuItem": "Mută aici", + "errorDialogTitle": "Files that cannot be moved:", + "manyFilesDialogTitle": "Move {count} Files To...", + "manyFilesWait": "Moving {count} files.", + "oneFileDialogTitle": "Move File To...", + "oneFileWait": "Moving file.", + "operationLabel": "Moving Files", + "operationSummary": "Number of files moved: {count}." + }, + "upload": { + "addFiles": "Adaugă fișiere", + "bytesCountProgress": "({bytesUploaded} of {bytesTotal})", + "details": "Details", + "filesCountProgress": "{filesUploaded} of {filesTotal}", + "progressLabel": "Încărcare în progres.", + "progressMessage": "Uploading...", + "selectFileLabel": "Selectează un fișier de încărcat", + "selectFiles": "Select files to upload", + "success": "Upload finished!", + "summary": "Uploaded files: {count}" + }, + "settings": { + "display": "Afișează:", + "displayDate": "Dată", + "displayName": "Nume fișier", + "displaySize": "Mărime fișier", + "sortAscending": "Ascending", + "sortBy": "Sort by", + "sortByOrder": "Order", + "sortDescending": "Descending", + "thumbnailSize": "Thumbnail Size", + "title": "Setări", + "viewType": "View", + "viewTypeCompact": "Compact", + "viewTypeList": "List", + "viewTypeThumbnails": "Thumbnails" + }, + "errors": { + "codes": { + "10": "Comandă invalidă.", + "11": "Tipul de resursă nu a fost specificat în cerere.", + "12": "Tipul de resursă cerut nu este valid.", + "13": "The connector configuration file is invalid.", + "14": "Invalid connector plugin: {pluginName}.", + "102": "Nume fișier sau nume dosar invalid.", + "103": "Nu a fost posibiliă finalizarea cererii din cauza restricțiilor de autorizare.", + "104": "Nu a fost posibiliă finalizarea cererii din cauza restricțiilor de permisiune la sistemul de fișiere.", + "105": "Extensie fișier invalidă.", + "109": "Cerere invalidă.", + "110": "Eroare necunoscută.", + "111": "It was not possible to complete the request due to resulting file size.", + "115": "Există deja un fișier sau un dosar cu același nume.", + "116": "Dosar negăsit. Te rog împrospătează și încearcă din nou.", + "117": "Fișier negăsit. Te rog împrospătează lista de fișiere și încearcă din nou.", + "118": "Calea sursei și a țintei sunt egale.", + "201": "Un fișier cu același nume este deja disponibil. Fișierul încărcat a fost redenumit cu \"{name}\".", + "202": "Fișier invalid.", + "203": "Fișier invalid. Mărimea fișierului este prea mare.", + "204": "Fișierul încărcat este corupt.", + "205": "Niciun dosar temporar nu este disponibil pentru încărcarea pe server.", + "206": "Încărcare anulată din motive de securitate. Fișierul conține date asemănătoare cu HTML.", + "207": "Fișierul încărcat a fost redenumit cu \"{name}\".", + "300": "Mutare fișier(e) eșuată.", + "301": "Copiere fișier(e) eșuată.", + "302": "Deleting file(s) failed.", + "500": "Browser-ul de fișiere este dezactivat din motive de securitate. Te rog contactează administratorul de sistem și verifică configurarea de fișiere CKFinder.", + "501": "Funcționalitatea de creat thumbnails este dezactivată." + }, + "deleteFilePermissions": "Removing files is not allowed in this folder.", + "fileInvalidCharacters": "Numele fișierului nu poate conține niciunul din următoarele caractere: {disallowedCharacters}", + "fileNameNotEmpty": "The file name cannot be empty.", + "folderInvalidCharacters": "Numele dosarului nu poate conține niciunul din următoarele caractere: {disallowedCharacters}", + "incorrectExtension": "Extensie fișier nepermisă în acest dosar.", + "missingFile": "The requested file is no longer available.", + "missingFolder": "The folder you are trying to reach is no longer available.", + "noUploadFolderSelected": "Te rugăm să selectezi un dosar înainte de a încărca.", + "operationCompleted": "Operation completed with errors.", + "renameFilePermissions": "Renaming files is not allowed in this folder.", + "unknown": "Nu a fost posibilă finalizarea cererii. (Eroare {number})", + "unknownUploadError": "Eroare la trimiterea fișierului.", + "uploadErrors": "Upload finished with errors.", + "uploadPermissions": "Încărcare fișier nepermisă." + }, + "chooseResizedImage": { + "title": "Choose Resized", + "originalSize": "Original Size", + "sizes": { + "custom": "Custom", + "large": "Large", + "max": "Max", + "medium": "Medium", + "small": "Small" + } + }, + "editImage": { + "adjust": "Adjust", + "apply": "Apply", + "confirmExit": "Are you sure you want to close? You have unsaved changes to the image.", + "crop": "Crop", + "downloadAction": "Downloading original image.", + "keepAspectRatio": "Keep Aspect Ratio", + "loading": "Loading image", + "presets": "Presets", + "reset": "Reset", + "resize": "Resize", + "rotate": "Rotate", + "rotateAntiClockwise": "90° Left", + "rotateClockwise": "90° Right", + "save": "Save", + "saveDialogFileExists": "File with the same name already exists in folder.", + "saveDialogOverwrite": "Overwrite File", + "saveDialogSaveAs": "Save as:", + "saveDialogTitle": "Save Changes", + "title": "Edit Image", + "transformationAction": "Applying transformations.", + "uploadAction": "Uploading edited image.", + "filters": { + "brightness": "Brightness", + "clip": "Clip", + "contrast": "Contrast", + "exposure": "Exposure", + "gamma": "Gamma", + "hue": "Hue", + "noise": "Noise", + "saturation": "Saturation", + "sepia": "Sepia", + "sharpen": "Sharpen", + "stackBlur": "Blur", + "vibrance": "Vibrance" + }, + "preset": { + "clarity": "Clarity", + "concentrate": "Concentrate", + "crossProcess": "Cross Process", + "glowingSun": "Glowing Sun", + "grungy": "Grungy", + "hazyDays": "Hazy Days", + "hemingway": "Hemingway", + "herMajesty": "Her Majesty", + "jarques": "Jarques", + "lomo": "Lomo", + "love": "Love", + "nostalgia": "Nostalgia", + "oldBoot": "Old Boot", + "orangePeel": "Orange Peel", + "pinhole": "Pinhole", + "sinCity": "Sin City", + "sunrise": "Sunrise", + "vintage": "Vintage" + } + }, + "shortcuts": { + "title": "Keyboard Shortcuts", + "general": { + "action": "Execute default action", + "firstItem": "Go to first item", + "focusFilesPane": "Focus files pane", + "focusFoldersPane": "Focus folders pane or breadcrumbs", + "focusNext": "Focus next pane", + "focusToolbar": "Focus toolbar", + "lastItem": "Go to last item", + "listShortcuts": "Open this help dialog", + "nextItem": "Go to next item", + "previousItem": "Go to previous item", + "showContextMenu": "Open context menu", + "title": "General Interface" + }, + "files": { + "addToSelectionAbove": "Add or remove files above to selection", + "addToSelectionBelow": "Add or remove files below to selection", + "addToSelectionLeft": "Add or remove file on the left to selection", + "addToSelectionRight": "Add or remove file on the right to selection", + "delete": "Delete file(s)", + "refresh": "Refresh files", + "rename": "Rename file", + "selectAll": "Select all files", + "upload": "Upload file(s)" + }, + "folders": { + "collapseOrParent": "Collapse folder / Go to parent folder", + "delete": "Delete folder", + "expandOrSubfolder": "Expand folder / Go to first subfolder", + "title": "Folders Pane" + }, + "keys": { + "ctrl": "Control", + "delete": "Delete", + "downArrow": "Down arrow", + "escape": "Escape", + "leftArrow": "Left arrow", + "question": "Question mark", + "rightArrow": "Right arrow", + "upArrow": "Up arrow" + }, + "keysAbbreviations": { + "alt": "alt", + "ctrl": "ctrl", + "del": "del", + "end": "end", + "home": "home", + "shift": "shift" + } + } +} diff --git a/lib/ckfinder/lang/ru.json b/lib/ckfinder/lang/ru.json new file mode 100644 index 0000000..398cbe8 --- /dev/null +++ b/lib/ckfinder/lang/ru.json @@ -0,0 +1,288 @@ +{ + "appTitle": "CKFinder", + "dir": "ltr", + "langCode": "ru", + "common": { + "abort": "Прервать", + "cancel": "Отмена", + "choose": "Выбрать", + "close": "Закрыть", + "copy": "Копировать", + "delete": "Удалить", + "download": "Сохранить", + "edit": "Редактировать", + "maximize": "Развернуть", + "messageTitle": "Информация", + "minimize": "Свернуть", + "move": "Переместить", + "newNameDialogTitle": "Новое имя", + "ok": "OK", + "pleaseWait": "Пожалуйста подождите.", + "rememberDecision": "Запомнить мой выбор", + "rename": "Переименовать", + "showMore": "Ещё", + "skip": "Пропустить", + "upload": "Загрузить файл", + "view": "Посмотреть" + }, + "units": { + "dateFormat": "dd.mm.yyyy H:MM", + "dateAmPm": [ + "AM", + "PM" + ], + "kb": "{size} KБ", + "mb": "{size} МБ", + "gb": "{size} ГБ", + "sizePerSecond": "{size}/с", + "pixelShort": "пикс" + }, + "files": { + "autoRename": "Автоматически переименовывать", + "countMany": "{count} файлов", + "countOne": "1 файл", + "deleteConfirmation": "Вы уверены, что хотите удалить {count} файла(ов)?", + "fileDeleteConfirmation": "Вы уверены, что хотите удалить файл \"{name}\"?", + "fileRenameExtensionConfirmation": "Вы уверены, что хотите изменить расширение файла? Файл может стать недоступным.", + "fileRenameLabel": "Пожалуйста, введите новое имя файла: ", + "filesPaneTitle": "Панель файлов", + "filesRefresh": "Обновление файлов", + "filterPlaceholder": "Фильтр", + "gettingFileData": "Чтение файла.", + "overwrite": "Заменить файл", + "loadingFilesPane": { + "title": "Загрузка...", + "text": "Файлы загружаются." + }, + "emptyFilesPane": { + "title": "Папка пуста.", + "text": "Используйте кнопку Загрузить или натащите ваши файлы сюда." + }, + "filterFilesEmpty": { + "title": "Ничего не найдено.", + "text": "Пожалуйста попробуйте другие критерии поиска." + } + }, + "folders": { + "deleteConfirmation": "Вы уверены, что хотите удалить папку \"{name}\"?", + "destinationFolder": "Конечная папка", + "newNameLabel": "Пожалуйста, введите новое имя папки: ", + "newSubfolder": "Новая папка", + "renameDialogTitle": "Переименовать папку", + "treeTitle": "Дерево каталогов" + }, + "copy": { + "dropMenuItem": "Копировать", + "errorDialogTitle": "Файлы, которые не могут быть скопированы:", + "manyFilesDialogTitle": "Копировать {count} файла(ов) в...", + "manyFilesWait": "Копирование {count} файлов.", + "oneFileDialogTitle": "Копировать файл в...", + "oneFileWait": "Копирование файла.", + "operationLabel": "Копирование файлов", + "operationSummary": "Скопировано файлов: {count}." + }, + "move": { + "dropMenuItem": "Переместить", + "errorDialogTitle": "Файлы, которые не могут быть перемещены:", + "manyFilesDialogTitle": "Переместить {count} файла(ов) в...", + "manyFilesWait": "Перемещение {count} файлов.", + "oneFileDialogTitle": "Переместить файл в...", + "oneFileWait": "Перемещение файла.", + "operationLabel": "Перемещение файлов", + "operationSummary": "Перемещено файлов: {count}." + }, + "upload": { + "addFiles": "Добавить файлы", + "bytesCountProgress": "({bytesUploaded} из {bytesTotal})", + "details": "Подробнее", + "filesCountProgress": "{filesUploaded} из {filesTotal}", + "progressLabel": "Загрузка в процессе.", + "progressMessage": "Загрузка...", + "selectFileLabel": "Выбрать файл для загрузки", + "selectFiles": "Выберите файлы для загрузки", + "success": "Загрузка завершена!", + "summary": "Загружено файлов: {count}" + }, + "settings": { + "display": "Показывать:", + "displayDate": "Дата", + "displayName": "Имя файла", + "displaySize": "Размер файла", + "sortAscending": "По возрастанию", + "sortBy": "Сортировать по", + "sortByOrder": "Порядок", + "sortDescending": "По убыванию", + "thumbnailSize": "Размер миниатюры", + "title": "Настройка", + "viewType": "Вид", + "viewTypeCompact": "Compact", + "viewTypeList": "Список", + "viewTypeThumbnails": "Миниатюры" + }, + "errors": { + "codes": { + "10": "Неверная команда.", + "11": "Тип ресурса не указан в запросе.", + "12": "Неверный запрошенный тип ресурса.", + "13": "Ошибка в конфигурационном файле.", + "14": "Ошибка в плагине: {pluginName}.", + "102": "Неверное имя файла или папки.", + "103": "Невозможно завершить запрос из-за ограничений авторизации.", + "104": "Невозможно завершить запрос из-за ограничения разрешений файловой системы.", + "105": "Неверное расширение файла.", + "109": "Неверный запрос.", + "110": "Неизвестная ошибка.", + "111": "Невозможно завершить запрос из-за размера конечного файла.", + "115": "Файл или папка с таким именем уже существует.", + "116": "Папка не найдена. Пожалуйста, обновите вид папок и попробуйте еще раз.", + "117": "Файл не найден. Пожалуйста, обновите список файлов и попробуйте еще раз.", + "118": "Исходное расположение файла совпадает с указанным.", + "201": "Файл с таким именем уже существует. Загруженный файл был переименован в \"{name}\".", + "202": "Неверный файл.", + "203": "Неверный файл. Размер файла слишком большой.", + "204": "Загруженный файл поврежден.", + "205": "Недоступна временная папка для загрузки файлов на сервер.", + "206": "Загрузка отменена из-за соображений безопасности. Файл содержит похожие на HTML данные.", + "207": "Загруженный файл был переименован в \"{name}\".", + "300": "Произошла ошибка при перемещении файла(ов).", + "301": "Произошла ошибка при копировании файла(ов).", + "302": "Произошла ошибка при удалении файла(ов).", + "500": "Браузер файлов отключен из-за соображений безопасности. Пожалуйста, сообщите вашему системному администратру и проверьте конфигурационный файл CKFinder.", + "501": "Поддержка миниатюр отключена." + }, + "deleteFilePermissions": "Removing files is not allowed in this folder.", + "fileInvalidCharacters": "Имя файла не может содержать любой из перечисленных символов: {disallowedCharacters}", + "fileNameNotEmpty": "Имя файла не может быть пустым.", + "folderInvalidCharacters": "Имя папки не может содержать любой из перечисленных символов: {disallowedCharacters}", + "incorrectExtension": "В эту папку нельзя загружать файлы с таким расширением.", + "missingFile": "Запрашиваемый файл более не доступен.", + "missingFolder": "Запрашиваемая папка более не доступен.", + "noUploadFolderSelected": "Пожалуйста, выберите папку, в которую вы хотите загрузить файл.", + "operationCompleted": "Операция завершилась с ошибками.", + "renameFilePermissions": "Renaming files is not allowed in this folder.", + "unknown": "Невозможно завершить запрос. (Ошибка {number})", + "unknownUploadError": "Ошибка при передаче файла.", + "uploadErrors": "Загрузка завершена с ошибками.", + "uploadPermissions": "Загрузка файлов запрещена." + }, + "chooseResizedImage": { + "title": "Выбрать уменьшенный", + "originalSize": "Оригинальный размер", + "sizes": { + "custom": "Пользовательский", + "large": "Большой", + "max": "Максимальный", + "medium": "Средний", + "small": "Маленький" + } + }, + "editImage": { + "adjust": "Цветокоррекция", + "apply": "Применить", + "confirmExit": "Вы действительно хотите закрыть? У вас имеются несохраненные изменения.", + "crop": "Обрезка", + "downloadAction": "Скачивание оригинального изображения.", + "keepAspectRatio": "Сохранять соотношение сторон", + "loading": "Загрузка изображения", + "presets": "Предустановки", + "reset": "Сбросить", + "resize": "Изменение размера", + "rotate": "Поворот", + "rotateAntiClockwise": "90° вправо", + "rotateClockwise": "90° влево", + "save": "Сохранить", + "saveDialogFileExists": "Файл с таким именем уже существует в папке.", + "saveDialogOverwrite": "Переписать файл", + "saveDialogSaveAs": "Сохранить как:", + "saveDialogTitle": "Сохранить изменения", + "title": "Редактирование изображения", + "transformationAction": "Применений трансформаций.", + "uploadAction": "Загрузка измененного изображения.", + "filters": { + "brightness": "Яркость", + "clip": "Clip", + "contrast": "Контраст", + "exposure": "Экспозиция", + "gamma": "Гамма", + "hue": "Тон", + "noise": "Шум", + "saturation": "Насыщенность", + "sepia": "Сепия", + "sharpen": "Резкость", + "stackBlur": "Размытие", + "vibrance": "Сощность" + }, + "preset": { + "clarity": "Четкость", + "concentrate": "Концентрат", + "crossProcess": "Кросспроцесс", + "glowingSun": "Солнечный свет", + "grungy": "Гранж", + "hazyDays": "Туман", + "hemingway": "Хемингуэй", + "herMajesty": "Ее величество", + "jarques": "Jarques", + "lomo": "Ломо", + "love": "Любовь", + "nostalgia": "Ностальгия", + "oldBoot": "Старый башмак", + "orangePeel": "Апельсин", + "pinhole": "Пинхол", + "sinCity": "Город Грехов", + "sunrise": "Восход солнца", + "vintage": "Винтаж" + } + }, + "shortcuts": { + "title": "Горячие клавиши", + "general": { + "action": "Выполнить действие по умолчанию", + "firstItem": "Перейти к первому элементу", + "focusFilesPane": "Перейти к панели файлов", + "focusFoldersPane": "Перейти к панели папок", + "focusNext": "Перейти к следующей панели", + "focusToolbar": "Перейти к панели инструментов", + "lastItem": "Перейти к последнему элементу", + "listShortcuts": "Открыть это справочное окно", + "nextItem": "Перейти к следующему элементу", + "previousItem": "Перейти к предыдущему элементу", + "showContextMenu": "Контекстное меню", + "title": "Общий интерфейс" + }, + "files": { + "addToSelectionAbove": "Выделить/исключить файл сверху от выделенного", + "addToSelectionBelow": "Выделить/исключить файл снизу от выделенного", + "addToSelectionLeft": "Выделить/исключить файл слева от выделенного", + "addToSelectionRight": "Выделить/исключить файл справа от выделенного", + "delete": "Удалить файл(ы)", + "refresh": "Обновить", + "rename": "Переименовать файл", + "selectAll": "Выделить все файлы", + "upload": "Загрузить файл(ы)" + }, + "folders": { + "collapseOrParent": "Свернуть папку / Перейти к родительской папке", + "delete": "Удалить папку", + "expandOrSubfolder": "Развернуть папку / Перейти к первой подпапке", + "title": "Панель папок" + }, + "keys": { + "ctrl": "Control", + "delete": "Delete", + "downArrow": "Стрелка вниз", + "escape": "Escape", + "leftArrow": "Стрелка влево", + "question": "Знак вопроса", + "rightArrow": "Стрелка вправо", + "upArrow": "Стрелка вверх" + }, + "keysAbbreviations": { + "alt": "alt", + "ctrl": "ctrl", + "del": "del", + "end": "end", + "home": "home", + "shift": "shift" + } + } +} diff --git a/lib/ckfinder/lang/sk.json b/lib/ckfinder/lang/sk.json new file mode 100644 index 0000000..b2902ad --- /dev/null +++ b/lib/ckfinder/lang/sk.json @@ -0,0 +1,288 @@ +{ + "appTitle": "CKFinder", + "dir": "ltr", + "langCode": "sk", + "common": { + "abort": "Odobrať", + "cancel": "Zrušiť", + "choose": "Vybrať", + "close": "Zatvoriť", + "copy": "Kopírovať", + "delete": "Zmazať", + "download": "Stiahnuť", + "edit": "Upraviť", + "maximize": "Maximalizovať", + "messageTitle": "Informácia", + "minimize": "Minimalizovať", + "move": "Presunúť", + "newNameDialogTitle": "Nové meno", + "ok": "OK", + "pleaseWait": "Čakajte prosím.", + "rememberDecision": "Pamätať si rozhodnutie", + "rename": "Premenovať", + "showMore": "Ukázať viac", + "skip": "Preskočiť", + "upload": "Prekopírovať na server (Upload)", + "view": "Náhľad" + }, + "units": { + "dateFormat": "mm/dd/yyyy HH:MM", + "dateAmPm": [ + "AM", + "PM" + ], + "kb": "{size} KB", + "mb": "{size} MB", + "gb": "{size} GB", + "sizePerSecond": "{size}/s", + "pixelShort": "px" + }, + "files": { + "autoRename": "Auto-premenovanie", + "countMany": "{count} súborov", + "countOne": "1 súbor", + "deleteConfirmation": "Naozaj chcete odstrániť {count} súborov?", + "fileDeleteConfirmation": "Skutočne chcete odstrániť súbor \"{name}\"?", + "fileRenameExtensionConfirmation": "Skutočne chcete zmeniť príponu súboru? Upozornenie: zmenou prípony sa súbor môže stať nepoužiteľným, pokiaľ prípona nie je podporovaná.", + "fileRenameLabel": "Zadajte prosím meno nového súboru: ", + "filesPaneTitle": "Názov súboru", + "filesRefresh": "Obnovujem súbory", + "filterPlaceholder": "Filter", + "gettingFileData": "Informácie o súbore.", + "overwrite": "Prepísať", + "loadingFilesPane": { + "title": "Načítam...", + "text": "Súbory sú načítané." + }, + "emptyFilesPane": { + "title": "Priečinok je prázdny.", + "text": "Použi Nahraj tlačidlo alebo označ a potiahni svoje súbory tu." + }, + "filterFilesEmpty": { + "title": "Nič sa nenašlo.", + "text": "Prosím, použi iné kritéria vyhľadávania." + } + }, + "folders": { + "deleteConfirmation": "Skutočne zmazať adresár \"{name}\"?", + "destinationFolder": "Adresa súborur", + "newNameLabel": "Zadajte prosím meno nového adresára: ", + "newSubfolder": "Nový podadresár", + "renameDialogTitle": "Premenovať priečinok", + "treeTitle": "Priečinky" + }, + "copy": { + "dropMenuItem": "Prekopírovať sem", + "errorDialogTitle": "Súbory, ktoré sa nedajú prekopírovať:", + "manyFilesDialogTitle": "Kopírovať {count} súborov do...", + "manyFilesWait": "Kopírovať {count} súbory.", + "oneFileDialogTitle": "Skopírovať súbory do...", + "oneFileWait": "Kopírujem súbory.", + "operationLabel": "Kopírujem súbory", + "operationSummary": "Počet skopírovaných súborov: {count}." + }, + "move": { + "dropMenuItem": "Presunúť sem", + "errorDialogTitle": "Súbory, ktoré sa nadajú presunúť:", + "manyFilesDialogTitle": "Presunúť {count} súbory do...", + "manyFilesWait": "Presúvam {count} súbory.", + "oneFileDialogTitle": "Presunúť súbor do...", + "oneFileWait": "Presúvam súbor.", + "operationLabel": "Presúvam súbory", + "operationSummary": "Počet presunutých súborov: {count}." + }, + "upload": { + "addFiles": "Pridať súbory", + "bytesCountProgress": "({bytesUploaded} z {bytesTotal})", + "details": "Detaily", + "filesCountProgress": "{filesUploaded} z {filesTotal}", + "progressLabel": "Prebieha kopírovanie.", + "progressMessage": "Nahrávam...", + "selectFileLabel": "Vyberte súbor, ktorý chcete prekopírovať na server", + "selectFiles": "Vybrať súbory na nahranie", + "success": "Nahrávanie dokončené!", + "summary": "Nahrané súbory: {count}" + }, + "settings": { + "display": "Zobraziť:", + "displayDate": "Dátum", + "displayName": "Názov súboru", + "displaySize": "Veľkosť súboru", + "sortAscending": "Vzostupne", + "sortBy": "Zoradiť podľa", + "sortByOrder": "Druh", + "sortDescending": "Zostupne", + "thumbnailSize": "Veĺkosť Thumbnail", + "title": "Nastavenia", + "viewType": "Ukážka", + "viewTypeCompact": "Compact", + "viewTypeList": "Zoznam", + "viewTypeThumbnails": "Thumbnails" + }, + "errors": { + "codes": { + "10": "Neplatný príkaz.", + "11": "V požiadavke nebol špecifikovaný typ súboru.", + "12": "Nepodporovaný typ súboru.", + "13": "Konfiguračný súbor konektoru programu CKFinder je neplatný.", + "14": "Neplatný plugin konektor: {pluginName}.", + "102": "Neplatný názov súboru alebo adresára.", + "103": "Nebolo možné dokončiť spracovanie požiadavky kvôli nepostačujúcej úrovni oprávnení.", + "104": "Nebolo možné dokončiť spracovanie požiadavky kvôli obmedzeniam v prístupových právach k súborom.", + "105": "Neplatná prípona súboru.", + "109": "Neplatná požiadavka.", + "110": "Neidentifikovaná chyba.", + "111": "Nebolo možné dokončiť príkaz na základe veľkosti súboru.", + "115": "Zadaný súbor alebo adresár už existuje.", + "116": "Adresár nebol nájdený. Aktualizujte obsah adresára (Znovunačítať) a skúste znovu.", + "117": "Súbor nebol nájdený. Aktualizujte obsah adresára (Znovunačítať) a skúste znovu.", + "118": "Zdrojové a cieľové cesty sú rovnaké.", + "201": "Súbor so zadaným názvom už existuje. Prekopírovaný súbor bol premenovaný na \"{name}\".", + "202": "Neplatný súbor.", + "203": "Neplatný súbor - súbor presahuje maximálnu povolenú veľkosť.", + "204": "Kopírovaný súbor je poškodený.", + "205": "Server nemá špecifikovaný dočasný adresár pre kopírované súbory.", + "206": "Kopírovanie prerušené kvôli nedostatočnému zabezpečeniu. Súbor obsahuje HTML data.", + "207": "Prekopírovaný súbor bol premenovaný na \"{name}\".", + "300": "Presunutie súborov zlyhalo.", + "301": "Kopírovanie súborov zlyhalo.", + "302": "Mazanie súborov zlyhalo.", + "500": "Prehliadanie súborov je zakázané kvôli bezpečnosti. Kontaktujte prosím administrátora a overte nastavenia v konfiguračnom súbore pre CKFinder.", + "501": "Momentálne nie je zapnutá podpora pre generáciu miniobrázkov." + }, + "deleteFilePermissions": "Removing files is not allowed in this folder.", + "fileInvalidCharacters": "Súbor nesmie obsahovať žiadny z nasledujúcich znakov: {disallowedCharacters}", + "fileNameNotEmpty": "Názov súboru nesmie byť bez znakov.", + "folderInvalidCharacters": "Adresár nesmie obsahovať žiadny z nasledujúcich znakov: {disallowedCharacters}", + "incorrectExtension": "V tomto adresári nie je povolený tento formát súboru.", + "missingFile": "Súbor už nie je k dispozícii.", + "missingFolder": "Priečinok už nie je k dispozícii.", + "noUploadFolderSelected": "Pred náhrávaním zvoľte adresár, prosím", + "operationCompleted": "Úloha dokončená s chybami.", + "renameFilePermissions": "Renaming files is not allowed in this folder.", + "unknown": "Server nemohol dokončiť spracovanie požiadavky. (Chyba {number})", + "unknownUploadError": "V priebehu posielania súboru sa vyskytla chyba.", + "uploadErrors": "Nahrávanie ukončené s chybami.", + "uploadPermissions": "Nahratie súboru nie je povolené." + }, + "chooseResizedImage": { + "title": "Vybrať upravený", + "originalSize": "Pôvodná veľkosť", + "sizes": { + "custom": "Vlastné", + "large": "Veĺké", + "max": "Maximum", + "medium": "Stredné", + "small": "Malé" + } + }, + "editImage": { + "adjust": "Prispôsobiť", + "apply": "Použiť", + "confirmExit": "Naozaj chcete ukončiť program? Vašé zmeny nebudú uložené.", + "crop": "Orezať", + "downloadAction": "Sťahujem originálny súbor.", + "keepAspectRatio": "Udržať polomer", + "loading": "Nahrávam obrázok", + "presets": "Predvoľby", + "reset": "Zmazať", + "resize": "Orezať", + "rotate": "Otočiť", + "rotateAntiClockwise": "90° Doľava", + "rotateClockwise": "90° Doprava", + "save": "UložiŤ", + "saveDialogFileExists": "Súbor s rovnakým menom už existuje v tomto súbore.", + "saveDialogOverwrite": "Prepísať súbor", + "saveDialogSaveAs": "Uložiť ako:", + "saveDialogTitle": "Uložiť zmeny", + "title": "Upraviť obrázok", + "transformationAction": "Použiť zmeny.", + "uploadAction": "Nahrávam upravené súbory.", + "filters": { + "brightness": "Jas", + "clip": "Strih", + "contrast": "Kontrast", + "exposure": "Expozícia", + "gamma": "Gamma", + "hue": "Odtieň", + "noise": "Sýtosť", + "saturation": "Saturícia", + "sepia": "Sépia", + "sharpen": "Ostrosť", + "stackBlur": "Zaostrenie", + "vibrance": "Citlivosť" + }, + "preset": { + "clarity": "Clarity", + "concentrate": "Concentrate", + "crossProcess": "Cross Process", + "glowingSun": "Glowing Sun", + "grungy": "Grungy", + "hazyDays": "Hazy Days", + "hemingway": "Hemingway", + "herMajesty": "Her Majesty", + "jarques": "Jarques", + "lomo": "Lomo", + "love": "Love", + "nostalgia": "Nostalgia", + "oldBoot": "Old Boot", + "orangePeel": "Orange Peel", + "pinhole": "Pinhole", + "sinCity": "Sin City", + "sunrise": "Sunrise", + "vintage": "Vintage" + } + }, + "shortcuts": { + "title": "Klávesové skratky", + "general": { + "action": "Pôvodné hodnoty", + "firstItem": "Vráť sa na začiatok", + "focusFilesPane": "Zaostriť na sekcie", + "focusFoldersPane": "Zaostriť na sekcie alebo breadcrumbs", + "focusNext": "Zaostriť ďalšiu sekciu", + "focusToolbar": "Označiť nástroje", + "lastItem": "Prejsť na posledný item", + "listShortcuts": "Otvoriť tento dialóg", + "nextItem": "Prejsť na ďalší item", + "previousItem": "Vrátiť sa na predchádzajúci item", + "showContextMenu": "Otvoriť kontextové menu", + "title": "General Interface" + }, + "files": { + "addToSelectionAbove": "Pridať alebo odstániť súbor vyššie do sekcie", + "addToSelectionBelow": "Pridať alebo odstrániť súbor nižšie do sekcie", + "addToSelectionLeft": "Pridať alebo odstrániť súbor vľavo do sekcie", + "addToSelectionRight": "Pridať alebo odstrániť súbor vpravo do sekcie", + "delete": "Zmazať súbory", + "refresh": "Obnoviť súbory", + "rename": "Premenovať súbor", + "selectAll": "Vybrať všetky súbory", + "upload": "Nahrať súbory" + }, + "folders": { + "collapseOrParent": "Zlyhanie priečinok / Choď do predošlého súboru", + "delete": "Zmazať priečinok", + "expandOrSubfolder": "Rozbaliť priečinok / Choď do prvého podsúboru", + "title": "Sekcia" + }, + "keys": { + "ctrl": "Control", + "delete": "Zmazať", + "downArrow": "Šípka dole", + "escape": "Escape", + "leftArrow": "Šípka vľavo", + "question": "Otáznik", + "rightArrow": "Šípka vpravo", + "upArrow": "Šípka hore" + }, + "keysAbbreviations": { + "alt": "alt", + "ctrl": "ctrl", + "del": "del", + "end": "end", + "home": "home", + "shift": "shift" + } + } +} diff --git a/lib/ckfinder/lang/sl.json b/lib/ckfinder/lang/sl.json new file mode 100644 index 0000000..96bf425 --- /dev/null +++ b/lib/ckfinder/lang/sl.json @@ -0,0 +1,288 @@ +{ + "appTitle": "CKFinder", + "dir": "ltr", + "langCode": "sl", + "common": { + "abort": "Abort", + "cancel": "Prekliči", + "choose": "Choose", + "close": "Zapri", + "copy": "Copy", + "delete": "Zbriši", + "download": "Prenesi na svoj računalnik", + "edit": "Uredi", + "maximize": "Maksimiraj", + "messageTitle": "Informacija", + "minimize": "Minimiraj", + "move": "Move", + "newNameDialogTitle": "Novo ime", + "ok": "Potrdi", + "pleaseWait": "Prosimo počakajte.", + "rememberDecision": "Zapomni si mojo izbiro", + "rename": "Preimenuj", + "showMore": "Show more", + "skip": "Preskoči", + "upload": "Naloži na strežnik", + "view": "Predogled" + }, + "units": { + "dateFormat": "d.m.yyyy H:MM", + "dateAmPm": [ + "AM", + "PM" + ], + "kb": "{size} KB", + "mb": "{size} MB", + "gb": "{size} GB", + "sizePerSecond": "{size}/s", + "pixelShort": "px" + }, + "files": { + "autoRename": "Avtomatsko preimenuj", + "countMany": "{count} datotek(e)", + "countOne": "1 datoteka", + "deleteConfirmation": "Are you sure you want to delete {count} files?", + "fileDeleteConfirmation": "Ali ste prepričani, da želite izbrisati datoteko \"{name}\"?", + "fileRenameExtensionConfirmation": "Ali ste prepričani, da želite spremeniti končnico datoteke? Možno je, da potem datoteka ne bo uporabna.", + "fileRenameLabel": "Vnesite novo ime datoteke: ", + "filesPaneTitle": "Files pane", + "filesRefresh": "Refreshing files", + "filterPlaceholder": "Filter", + "gettingFileData": "Getting file data.", + "overwrite": "Prepiši", + "loadingFilesPane": { + "title": "Loading...", + "text": "The files are being loaded." + }, + "emptyFilesPane": { + "title": "The folder is empty.", + "text": "Use the Upload button or drag and drop your files here." + }, + "filterFilesEmpty": { + "title": "Nothing found.", + "text": "Please try using different search criteria." + } + }, + "folders": { + "deleteConfirmation": "Ali ste prepričani, da želite zbrisati mapo \"{name}\"?", + "destinationFolder": "Destination Folder", + "newNameLabel": "Vnesite ime za novo mapo: ", + "newSubfolder": "Nova podmapa", + "renameDialogTitle": "Rename Folder", + "treeTitle": "Folders tree" + }, + "copy": { + "dropMenuItem": "Kopiraj", + "errorDialogTitle": "Files that cannot be copied:", + "manyFilesDialogTitle": "Copy {count} Files To...", + "manyFilesWait": "Copying {count} files.", + "oneFileDialogTitle": "Copy File To...", + "oneFileWait": "Copying file.", + "operationLabel": "Copying Files", + "operationSummary": "Number of files copied: {count}." + }, + "move": { + "dropMenuItem": "Premakni", + "errorDialogTitle": "Files that cannot be moved:", + "manyFilesDialogTitle": "Move {count} Files To...", + "manyFilesWait": "Moving {count} files.", + "oneFileDialogTitle": "Move File To...", + "oneFileWait": "Moving file.", + "operationLabel": "Moving Files", + "operationSummary": "Number of files moved: {count}." + }, + "upload": { + "addFiles": "Dodaj datoteke", + "bytesCountProgress": "({bytesUploaded} of {bytesTotal})", + "details": "Details", + "filesCountProgress": "{filesUploaded} of {filesTotal}", + "progressLabel": "Prenos na strežnik poteka.", + "progressMessage": "Uploading...", + "selectFileLabel": "Izberi datoteko za prenos na strežnik", + "selectFiles": "Select files to upload", + "success": "Upload finished!", + "summary": "Uploaded files: {count}" + }, + "settings": { + "display": "Prikaz:", + "displayDate": "datum", + "displayName": "ime datoteke", + "displaySize": "velikost datoteke", + "sortAscending": "Ascending", + "sortBy": "Sort by", + "sortByOrder": "Order", + "sortDescending": "Descending", + "thumbnailSize": "Thumbnail Size", + "title": "Nastavitve", + "viewType": "View", + "viewTypeCompact": "Compact", + "viewTypeList": "List", + "viewTypeThumbnails": "Thumbnails" + }, + "errors": { + "codes": { + "10": "Napačen ukaz.", + "11": "V poizvedbi ni bil jasen tip (resource type).", + "12": "Tip datoteke ni primeren.", + "13": "The connector configuration file is invalid.", + "14": "Invalid connector plugin: {pluginName}.", + "102": "Napačno ime mape ali datoteke.", + "103": "Vašega ukaza se ne da izvesti zaradi težav z avtorizacijo.", + "104": "Vašega ukaza se ne da izvesti zaradi težav z nastavitvami pravic v datotečnem sistemu.", + "105": "Napačna končnica datoteke.", + "109": "Napačna zahteva.", + "110": "Neznana napaka.", + "111": "It was not possible to complete the request due to resulting file size.", + "115": "Datoteka ali mapa s tem imenom že obstaja.", + "116": "Mapa ni najdena. Prosimo osvežite okno in poskusite znova.", + "117": "Datoteka ni najdena. Prosimo osvežite seznam datotek in poskusite znova.", + "118": "Začetna in končna pot je ista.", + "201": "Datoteka z istim imenom že obstaja. Naložena datoteka je bila preimenovana v \"{name}\".", + "202": "Neprimerna datoteka.", + "203": "Datoteka je prevelika in zasede preveč prostora.", + "204": "Naložena datoteka je okvarjena.", + "205": "Na strežniku ni na voljo začasna mapa za prenos datotek.", + "206": "Nalaganje je bilo prekinjeno zaradi varnostnih razlogov. Datoteka vsebuje podatke, ki spominjajo na HTML kodo.", + "207": "Naložena datoteka je bila preimenovana v \"{name}\".", + "300": "Premikanje datotek(e) ni uspelo.", + "301": "Kopiranje datotek(e) ni uspelo.", + "302": "Deleting file(s) failed.", + "500": "Brskalnik je onemogočen zaradi varnostnih razlogov. Prosimo kontaktirajte upravljalca spletnih strani.", + "501": "Ni podpore za majhne sličice (predogled)." + }, + "deleteFilePermissions": "Removing files is not allowed in this folder.", + "fileInvalidCharacters": "Ime datoteke ne sme vsebovati naslednjih znakov: {disallowedCharacters}", + "fileNameNotEmpty": "The file name cannot be empty.", + "folderInvalidCharacters": "Ime mape ne sme vsebovati naslednjih znakov: {disallowedCharacters}", + "incorrectExtension": "V tej mapi ta vrsta datoteke ni dovoljena.", + "missingFile": "The requested file is no longer available.", + "missingFolder": "The folder you are trying to reach is no longer available.", + "noUploadFolderSelected": "Izberite mapo v katero se bo naložilo datoteko!", + "operationCompleted": "Operation completed with errors.", + "renameFilePermissions": "Renaming files is not allowed in this folder.", + "unknown": "Prišlo je do napake. (Napaka {number})", + "unknownUploadError": "Napaka pri pošiljanju datoteke.", + "uploadErrors": "Upload finished with errors.", + "uploadPermissions": "Nalaganje datotek ni dovoljeno." + }, + "chooseResizedImage": { + "title": "Choose Resized", + "originalSize": "Original Size", + "sizes": { + "custom": "Custom", + "large": "Large", + "max": "Max", + "medium": "Medium", + "small": "Small" + } + }, + "editImage": { + "adjust": "Adjust", + "apply": "Apply", + "confirmExit": "Are you sure you want to close? You have unsaved changes to the image.", + "crop": "Crop", + "downloadAction": "Downloading original image.", + "keepAspectRatio": "Keep Aspect Ratio", + "loading": "Loading image", + "presets": "Presets", + "reset": "Reset", + "resize": "Resize", + "rotate": "Rotate", + "rotateAntiClockwise": "90° Left", + "rotateClockwise": "90° Right", + "save": "Save", + "saveDialogFileExists": "File with the same name already exists in folder.", + "saveDialogOverwrite": "Overwrite File", + "saveDialogSaveAs": "Save as:", + "saveDialogTitle": "Save Changes", + "title": "Edit Image", + "transformationAction": "Applying transformations.", + "uploadAction": "Uploading edited image.", + "filters": { + "brightness": "Brightness", + "clip": "Clip", + "contrast": "Contrast", + "exposure": "Exposure", + "gamma": "Gamma", + "hue": "Hue", + "noise": "Noise", + "saturation": "Saturation", + "sepia": "Sepia", + "sharpen": "Sharpen", + "stackBlur": "Blur", + "vibrance": "Vibrance" + }, + "preset": { + "clarity": "Clarity", + "concentrate": "Concentrate", + "crossProcess": "Cross Process", + "glowingSun": "Glowing Sun", + "grungy": "Grungy", + "hazyDays": "Hazy Days", + "hemingway": "Hemingway", + "herMajesty": "Her Majesty", + "jarques": "Jarques", + "lomo": "Lomo", + "love": "Love", + "nostalgia": "Nostalgia", + "oldBoot": "Old Boot", + "orangePeel": "Orange Peel", + "pinhole": "Pinhole", + "sinCity": "Sin City", + "sunrise": "Sunrise", + "vintage": "Vintage" + } + }, + "shortcuts": { + "title": "Keyboard Shortcuts", + "general": { + "action": "Execute default action", + "firstItem": "Go to first item", + "focusFilesPane": "Focus files pane", + "focusFoldersPane": "Focus folders pane or breadcrumbs", + "focusNext": "Focus next pane", + "focusToolbar": "Focus toolbar", + "lastItem": "Go to last item", + "listShortcuts": "Open this help dialog", + "nextItem": "Go to next item", + "previousItem": "Go to previous item", + "showContextMenu": "Open context menu", + "title": "General Interface" + }, + "files": { + "addToSelectionAbove": "Add or remove files above to selection", + "addToSelectionBelow": "Add or remove files below to selection", + "addToSelectionLeft": "Add or remove file on the left to selection", + "addToSelectionRight": "Add or remove file on the right to selection", + "delete": "Delete file(s)", + "refresh": "Refresh files", + "rename": "Rename file", + "selectAll": "Select all files", + "upload": "Upload file(s)" + }, + "folders": { + "collapseOrParent": "Collapse folder / Go to parent folder", + "delete": "Delete folder", + "expandOrSubfolder": "Expand folder / Go to first subfolder", + "title": "Folders Pane" + }, + "keys": { + "ctrl": "Control", + "delete": "Delete", + "downArrow": "Down arrow", + "escape": "Escape", + "leftArrow": "Left arrow", + "question": "Question mark", + "rightArrow": "Right arrow", + "upArrow": "Up arrow" + }, + "keysAbbreviations": { + "alt": "alt", + "ctrl": "ctrl", + "del": "del", + "end": "end", + "home": "home", + "shift": "shift" + } + } +} diff --git a/lib/ckfinder/lang/sr.json b/lib/ckfinder/lang/sr.json new file mode 100644 index 0000000..a1e8a36 --- /dev/null +++ b/lib/ckfinder/lang/sr.json @@ -0,0 +1,288 @@ +{ + "appTitle": "Датотеке", + "dir": "ltr", + "langCode": "sr", + "common": { + "abort": "Abort", + "cancel": "Поништи", + "choose": "Изабери", + "close": "Затвори", + "copy": "Копирај", + "delete": "Обриши", + "download": "Преузми", + "edit": "Промени", + "maximize": "Повећај", + "messageTitle": "Информација", + "minimize": "Смањи", + "move": "Премести", + "newNameDialogTitle": "Нови назив", + "ok": "У реду", + "pleaseWait": "Молимо сачекајте.", + "rememberDecision": "Запамти мој избор", + "rename": "Промени назив", + "showMore": "Прикажи више", + "skip": "Прескочи", + "upload": "Учитај", + "view": "Погледај" + }, + "units": { + "dateFormat": "dd/mm/yyyy HH:MM", + "dateAmPm": [ + "AM", + "PM" + ], + "kb": "{size} КБ", + "mb": "{size} МБ", + "gb": "{size} ГБ", + "sizePerSecond": "{size}/с", + "pixelShort": "px" + }, + "files": { + "autoRename": "Аутоматска промена назива", + "countMany": "{count} датотека(е)", + "countOne": "1 датотека", + "deleteConfirmation": "Да ли сте сигурни да желите да обришете {count} датотеке?", + "fileDeleteConfirmation": "Да ли сте сигурни да желите обрисати датотеку \"{name}\"?", + "fileRenameExtensionConfirmation": "Да ли сте сигурни да желите променити тип датотеке? Датотека може постати неискористива.", + "fileRenameLabel": "Унесите нови назив датотеке: ", + "filesPaneTitle": "Files pane", + "filesRefresh": "Refreshing files", + "filterPlaceholder": "Филтер", + "gettingFileData": "Преузимање информација о датотеци.", + "overwrite": "Препиши", + "loadingFilesPane": { + "title": "Учитавање...", + "text": "Датотеке се учитавају." + }, + "emptyFilesPane": { + "title": "Фасцикла је презна.", + "text": "Користи Upload дугме или додајте ваше датотеке овде." + }, + "filterFilesEmpty": { + "title": "Ништа није нађено.", + "text": "Молимо користите друге критеријуме за претраживање." + } + }, + "folders": { + "deleteConfirmation": "Да ли сте сигурни да желите обрисати фасциклу \"{name}\"?", + "destinationFolder": "Одредишна фасцикла", + "newNameLabel": "Унесите ново име фасцикле: ", + "newSubfolder": "Нова подфасцикла", + "renameDialogTitle": "Rename Folder", + "treeTitle": "Folders tree" + }, + "copy": { + "dropMenuItem": "Копирај датотеку овде", + "errorDialogTitle": "Датотека која не може бити копирана:", + "manyFilesDialogTitle": "Копирај {count} Датотеке у...", + "manyFilesWait": "Копирам {count} датотеке.", + "oneFileDialogTitle": "Копирај датотеке у...", + "oneFileWait": "Копирам датотеку.", + "operationLabel": "Копирам датотеке", + "operationSummary": "Број копираних датотека : {count}." + }, + "move": { + "dropMenuItem": "Премести датотеку овде", + "errorDialogTitle": "Датотека која не може бити премештена:", + "manyFilesDialogTitle": "Премести {count} Датотеке у...", + "manyFilesWait": "Премештам {count} датотеке.", + "oneFileDialogTitle": "Премести датотеке у...", + "oneFileWait": "Премештам датотеку.", + "operationLabel": "Премештам датотеке", + "operationSummary": "Број премештених датотека : {count}." + }, + "upload": { + "addFiles": "Додај датотеке", + "bytesCountProgress": "({bytesUploaded} od {bytesTotal})", + "details": "Детаљи", + "filesCountProgress": "{filesUploaded} od {filesTotal}", + "progressLabel": "Слање у току.", + "progressMessage": "Учитавање...", + "selectFileLabel": "Одабери датотеку за учитавање", + "selectFiles": "Изаберите датотеку за учитавање", + "success": "Учитавање завршено!", + "summary": "Учитај датотеке: {count}" + }, + "settings": { + "display": "Приказ:", + "displayDate": "Датум", + "displayName": "Назив датотеке", + "displaySize": "Величина датотеке", + "sortAscending": "Ascending", + "sortBy": "Sort by", + "sortByOrder": "Order", + "sortDescending": "Descending", + "thumbnailSize": "Величина приказа", + "title": "Подешавања", + "viewType": "View", + "viewTypeCompact": "Compact", + "viewTypeList": "List", + "viewTypeThumbnails": "Thumbnails" + }, + "errors": { + "codes": { + "10": "Непозната наредба.", + "11": "Није наведена врста у захтеву.", + "12": "Затражена врста није важећа.", + "13": "Неисправна датотека за конфигурацију конектора.", + "14": "Неисправан конектор за прикључење: {pluginName}.", + "102": "Неисправан назив датотеке или фасцикле.", + "103": "Није могуће извршити захтев због ограничења приступа.", + "104": "Није могуће извршити захтев због ограничења поставке система.", + "105": "Недозвољена врста датотеке.", + "109": "Недозвољен захтев.", + "110": "Непозната грешка.", + "111": "Није могуће извршити захтев због резултујуће величине датотеке.", + "115": "Датотека или фасцикла са истим називом већ постоји.", + "116": "Фасцикла није пронађена. Освежите страницу и покушајте поново.", + "117": "Датотека није пронађена. Освежите листу датотека и покушајте поново.", + "118": "Путања извора и одредишта су исте.", + "201": "Датотека са истим називом већ постоји. Учитана датотека је промењена у \"{name}\".", + "202": "Неисправна датотека.", + "203": "Неисправна датотека. Величина датотеке је превелика.", + "204": "Учитана датотека је неисправна.", + "205": "Не постоји привремена фасцикла за учитавање на серверe.", + "206": "Слање је поништено због сигурносних поставки. Назив датотеке садржи HTML податке.", + "207": "Учитана датотека је промењена у \"{name}\".", + "300": "Премештање датотеке(а) није успело.", + "301": "Копирање датотеке(а) није успело.", + "302": "Брисање датотеке(а) није успело.", + "500": "Претраживање датотека није дозвољено из сигурносних разлога. Молимо контактирајте администратора система како би проверили поставке CKFinder конфигурационе датотеке.", + "501": "Подршка за приказ није омогућена." + }, + "deleteFilePermissions": "Removing files is not allowed in this folder.", + "fileInvalidCharacters": "Назив датотеке не сме садржавати ни један од следећих знакова: {disallowedCharacters}", + "fileNameNotEmpty": "The file name cannot be empty.", + "folderInvalidCharacters": "Назив фасцикле не сме садржавати ни један од следећих знакова: {disallowedCharacters}", + "incorrectExtension": "Тип датотеке није дозвољен.", + "missingFile": "The requested file is no longer available.", + "missingFolder": "The folder you are trying to reach is no longer available.", + "noUploadFolderSelected": "Одаберите фасцикле прије учитавања.", + "operationCompleted": "Операција извршена са грешкама.", + "renameFilePermissions": "Renaming files is not allowed in this folder.", + "unknown": "Није могуће изавршити захтев. (Грешка {number})", + "unknownUploadError": "Грешка приликом учитавања датотеке.", + "uploadErrors": "Учитавање завршено са грешком.", + "uploadPermissions": "Учитавање датотеке није дозвољено." + }, + "chooseResizedImage": { + "title": "Изабери скалирано", + "originalSize": "Оригинална величина", + "sizes": { + "custom": "Прилагођена", + "large": "Велика", + "max": "Максимална", + "medium": "Средња", + "small": "Мала" + } + }, + "editImage": { + "adjust": "Прилагоди", + "apply": "Примени", + "confirmExit": "Are you sure you want to close? You have unsaved changes to the image.", + "crop": "Обрежи", + "downloadAction": "Преузимање оригиналне слике.", + "keepAspectRatio": "Задржи омер", + "loading": "Учитавање слике", + "presets": "Унапред постављен", + "reset": "Ресетуј", + "resize": "Промена величине", + "rotate": "Ротирај", + "rotateAntiClockwise": "90° степени; Лево", + "rotateClockwise": "90° степени; Десно", + "save": "Сачувај", + "saveDialogFileExists": "Датотека са истим именом већ постоји у фасцикли.", + "saveDialogOverwrite": "Препиши датотеку", + "saveDialogSaveAs": "Сачувај као:", + "saveDialogTitle": "Сачувај промене", + "title": "Уреди слику", + "transformationAction": "Примењујем трансформације.", + "uploadAction": "Учитавам уређену слику.", + "filters": { + "brightness": "Посветљење", + "clip": "Оквир", + "contrast": "Контраст", + "exposure": "Експозиција", + "gamma": "Гама", + "hue": "Нијанса", + "noise": "Шум", + "saturation": "Засићење", + "sepia": "Сепија", + "sharpen": "Изоштрити", + "stackBlur": "Замаглити", + "vibrance": "Живост боја" + }, + "preset": { + "clarity": "Јасноћа", + "concentrate": "Концентрисано", + "crossProcess": "Укрштено", + "glowingSun": "Јако сунце", + "grungy": "Грунги", + "hazyDays": "Магловит дан", + "hemingway": "Хемингвеј", + "herMajesty": "Њено височанство", + "jarques": "Јаркуес", + "lomo": "Ломо", + "love": "Љубав", + "nostalgia": "Носталгија", + "oldBoot": "Стара ципела", + "orangePeel": "Кора поморанџе", + "pinhole": "Пинхоле", + "sinCity": "Град греха", + "sunrise": "Излазак сунца", + "vintage": "Старо" + } + }, + "shortcuts": { + "title": "Keyboard Shortcuts", + "general": { + "action": "Execute default action", + "firstItem": "Go to first item", + "focusFilesPane": "Focus files pane", + "focusFoldersPane": "Focus folders pane or breadcrumbs", + "focusNext": "Focus next pane", + "focusToolbar": "Focus toolbar", + "lastItem": "Go to last item", + "listShortcuts": "Open this help dialog", + "nextItem": "Go to next item", + "previousItem": "Go to previous item", + "showContextMenu": "Open context menu", + "title": "General Interface" + }, + "files": { + "addToSelectionAbove": "Add or remove files above to selection", + "addToSelectionBelow": "Add or remove files below to selection", + "addToSelectionLeft": "Add or remove file on the left to selection", + "addToSelectionRight": "Add or remove file on the right to selection", + "delete": "Delete file(s)", + "refresh": "Refresh files", + "rename": "Rename file", + "selectAll": "Select all files", + "upload": "Upload file(s)" + }, + "folders": { + "collapseOrParent": "Collapse folder / Go to parent folder", + "delete": "Delete folder", + "expandOrSubfolder": "Expand folder / Go to first subfolder", + "title": "Folders Pane" + }, + "keys": { + "ctrl": "Control", + "delete": "Delete", + "downArrow": "Down arrow", + "escape": "Escape", + "leftArrow": "Left arrow", + "question": "Question mark", + "rightArrow": "Right arrow", + "upArrow": "Up arrow" + }, + "keysAbbreviations": { + "alt": "alt", + "ctrl": "ctrl", + "del": "del", + "end": "end", + "home": "home", + "shift": "shift" + } + } +} diff --git a/lib/ckfinder/lang/sv.json b/lib/ckfinder/lang/sv.json new file mode 100644 index 0000000..1fdca10 --- /dev/null +++ b/lib/ckfinder/lang/sv.json @@ -0,0 +1,288 @@ +{ + "appTitle": "CKFinder", + "dir": "ltr", + "langCode": "sv", + "common": { + "abort": "Avbryt", + "cancel": "Avbryt", + "choose": "Välj", + "close": "Stäng", + "copy": "Kopiera", + "delete": "Radera", + "download": "Ladda ner", + "edit": "Redigera", + "maximize": "Maximera", + "messageTitle": "Information", + "minimize": "Minimera", + "move": "Flytta", + "newNameDialogTitle": "Nytt namn", + "ok": "OK", + "pleaseWait": "Vänligen vänta.", + "rememberDecision": "Kom ihåg mitt val", + "rename": "Byt namn", + "showMore": "Visa mer", + "skip": "Hoppa över", + "upload": "Ladda upp", + "view": "Visa" + }, + "units": { + "dateFormat": "yyyy-mm-dd HH:MM", + "dateAmPm": [ + "AM", + "PM" + ], + "kb": "{size} KB", + "mb": "{size} MB", + "gb": "{size} GB", + "sizePerSecond": "{size}/s", + "pixelShort": "px" + }, + "files": { + "autoRename": "Auto-namnändring", + "countMany": "{count} filer", + "countOne": "1 fil", + "deleteConfirmation": "Är du säker på att du vill radera {count} filer?", + "fileDeleteConfirmation": "Är du säker på att du vill radera filen \"{name}\"?", + "fileRenameExtensionConfirmation": "Är du säker på att du vill ändra filändelsen? Filen kan bli oanvändbar.", + "fileRenameLabel": "Skriv det nya filnamnet: ", + "filesPaneTitle": "Files pane", + "filesRefresh": "Refreshing files", + "filterPlaceholder": "Filter", + "gettingFileData": "Hämtar fildata.", + "overwrite": "Skriv över", + "loadingFilesPane": { + "title": "Laddar...", + "text": "Filerna håller på att laddas." + }, + "emptyFilesPane": { + "title": "Mappen är tom.", + "text": "Använd Ladda upp-knappen eller dra och släpp dina filer här." + }, + "filterFilesEmpty": { + "title": "Hittade inget.", + "text": "Please try using different search criteria." + } + }, + "folders": { + "deleteConfirmation": "Är du säker på att du vill radera mappen \"{name}\"?", + "destinationFolder": "Målmapp", + "newNameLabel": "Skriv namnet på den nya mappen: ", + "newSubfolder": "Ny Undermappr", + "renameDialogTitle": "Byt namn på mapp", + "treeTitle": "Folders tree" + }, + "copy": { + "dropMenuItem": "Kopiera hit", + "errorDialogTitle": "Filer som inte kan kopieras:", + "manyFilesDialogTitle": "Kopiera {count} filer till...", + "manyFilesWait": "Kopierar {count} filer.", + "oneFileDialogTitle": "Kopiera fil till...", + "oneFileWait": "Kopierar fil.", + "operationLabel": "Kopierar filer", + "operationSummary": "Antal filer kopierade: {count}." + }, + "move": { + "dropMenuItem": "Flytta hit", + "errorDialogTitle": "Filer som inte kan flyttas:", + "manyFilesDialogTitle": "Flytta {count} filer till...", + "manyFilesWait": "Flyttar {count} filer.", + "oneFileDialogTitle": "Flytta fil till...", + "oneFileWait": "Flyttar fil.", + "operationLabel": "Flyttar filer", + "operationSummary": "Antal filer flyttade: {count}." + }, + "upload": { + "addFiles": "Lägg till filer", + "bytesCountProgress": "({bytesUploaded} av {bytesTotal})", + "details": "Detaljer", + "filesCountProgress": "{filesUploaded} av {filesTotal}", + "progressLabel": "Laddar upp filen.", + "progressMessage": "Laddar upp...", + "selectFileLabel": "Välj fil att ladda upp", + "selectFiles": "Välj filer att ladda upp", + "success": "Uppladdning klar!", + "summary": "Uppladdade filer: {count}" + }, + "settings": { + "display": "Visa:", + "displayDate": "Datum", + "displayName": "Filnamn", + "displaySize": "Storlek", + "sortAscending": "Stigande", + "sortBy": "Sortera efter", + "sortByOrder": "Order", + "sortDescending": "Fallande", + "thumbnailSize": "Thumbnail Size", + "title": "Inställningar", + "viewType": "View", + "viewTypeCompact": "Compact", + "viewTypeList": "List", + "viewTypeThumbnails": "Thumbnails" + }, + "errors": { + "codes": { + "10": "Ogiltig begäran.", + "11": "Resursens typ var inte specificerad i förfrågan.", + "12": "Den efterfrågade resurstypen är inte giltig.", + "13": "The connector configuration file is invalid.", + "14": "Invalid connector plugin: {pluginName}.", + "102": "Ogiltigt fil- eller mappnamn.", + "103": "Begäran kunde inte utföras p.g.a. restriktioner av rättigheterna.", + "104": "Begäran kunde inte utföras p.g.a. restriktioner av rättigheter i filsystemet.", + "105": "Ogiltig filändelse.", + "109": "Ogiltig begäran.", + "110": "Okänt fel.", + "111": "It was not possible to complete the request due to resulting file size.", + "115": "En fil eller mapp med aktuellt namn finns redan.", + "116": "Mappen kunde inte hittas. Var god uppdatera sidan och försök igen.", + "117": "Filen kunde inte hittas. Var god uppdatera sidan och försök igen.", + "118": "Sökväg till källa och mål är identisk.", + "201": "En fil med aktuellt namn fanns redan. Den uppladdade filen har döpts om till \"{name}\".", + "202": "Ogiltig fil.", + "203": "Ogiltig fil. Filen var för stor.", + "204": "Den uppladdade filen var korrupt.", + "205": "En tillfällig mapp för uppladdning är inte tillgänglig på servern.", + "206": "Uppladdningen stoppades av säkerhetsskäl. Filen innehåller HTML-liknande data.", + "207": "Den uppladdade filen har döpts om till \"{name}\".", + "300": "Flytt av fil(er) misslyckades.", + "301": "Kopiering av fil(er) misslyckades.", + "302": "Radering av fil(er) misslyckades.", + "500": "Filhanteraren har stoppats av säkerhetsskäl. Var god kontakta administratören för att kontrollera konfigurationsfilen för CKFinder.", + "501": "Stöd för tumnaglar har stängts av." + }, + "deleteFilePermissions": "Removing files is not allowed in this folder.", + "fileInvalidCharacters": "Filnamnet får inte innehålla något av följande tecken: {disallowedCharacters}", + "fileNameNotEmpty": "Filnamnet kan inte vara tomt.", + "folderInvalidCharacters": "Mappens namn får inte innehålla något av följande tecken: {disallowedCharacters}", + "incorrectExtension": "Filändelsen är inte tillåten i denna mapp.", + "missingFile": "Den begärda filen är inte längre tillgänglig.", + "missingFolder": "Mappen du försöker gå till finns inte längre.", + "noUploadFolderSelected": "Välj en mapp före uppladdning.", + "operationCompleted": "Operation completed with errors.", + "renameFilePermissions": "Renaming files is not allowed in this folder.", + "unknown": "Begäran kunde inte utföras eftersom ett fel uppstod. (Fel {number})", + "unknownUploadError": "Fel vid filuppladdning.", + "uploadErrors": "Uppladdning blev klar med fel.", + "uploadPermissions": "Filuppladdning ej tillåten." + }, + "chooseResizedImage": { + "title": "Choose Resized", + "originalSize": "Originalstorlek", + "sizes": { + "custom": "Eget val", + "large": "Stor", + "max": "Max", + "medium": "Medium", + "small": "Liten" + } + }, + "editImage": { + "adjust": "Justera", + "apply": "Tillämpa", + "confirmExit": "Are you sure you want to close? You have unsaved changes to the image.", + "crop": "Beskär", + "downloadAction": "Laddar ner originalbilden.", + "keepAspectRatio": "Behåll förhållande", + "loading": "Laddar bild", + "presets": "Förinställningar", + "reset": "Återställ", + "resize": "Ändra storlek", + "rotate": "Rotera", + "rotateAntiClockwise": "90° vänster", + "rotateClockwise": "90° höger", + "save": "Spara", + "saveDialogFileExists": "En fil med samma namn finns redan i mappen.", + "saveDialogOverwrite": "Skriv över fil", + "saveDialogSaveAs": "Spara som:", + "saveDialogTitle": "Spara ändringar", + "title": "Redigera bild", + "transformationAction": "Tillämpar transformationer", + "uploadAction": "Laddar upp redigerad bild.", + "filters": { + "brightness": "Ljus", + "clip": "Clip", + "contrast": "Kontrast", + "exposure": "Exposure", + "gamma": "Gamma", + "hue": "Hue", + "noise": "Noise", + "saturation": "Mättnad", + "sepia": "Sepia", + "sharpen": "Sharpen", + "stackBlur": "Blur", + "vibrance": "Vibrance" + }, + "preset": { + "clarity": "Clarity", + "concentrate": "Concentrate", + "crossProcess": "Cross Process", + "glowingSun": "Glowing Sun", + "grungy": "Grungy", + "hazyDays": "Hazy Days", + "hemingway": "Hemingway", + "herMajesty": "Her Majesty", + "jarques": "Jarques", + "lomo": "Lomo", + "love": "Love", + "nostalgia": "Nostalgia", + "oldBoot": "Old Boot", + "orangePeel": "Orange Peel", + "pinhole": "Pinhole", + "sinCity": "Sin City", + "sunrise": "Sunrise", + "vintage": "Vintage" + } + }, + "shortcuts": { + "title": "Keyboard Shortcuts", + "general": { + "action": "Execute default action", + "firstItem": "Go to first item", + "focusFilesPane": "Focus files pane", + "focusFoldersPane": "Focus folders pane or breadcrumbs", + "focusNext": "Focus next pane", + "focusToolbar": "Focus toolbar", + "lastItem": "Go to last item", + "listShortcuts": "Open this help dialog", + "nextItem": "Go to next item", + "previousItem": "Go to previous item", + "showContextMenu": "Open context menu", + "title": "General Interface" + }, + "files": { + "addToSelectionAbove": "Add or remove files above to selection", + "addToSelectionBelow": "Add or remove files below to selection", + "addToSelectionLeft": "Add or remove file on the left to selection", + "addToSelectionRight": "Add or remove file on the right to selection", + "delete": "Delete file(s)", + "refresh": "Refresh files", + "rename": "Byt namn på fil", + "selectAll": "files Välj alla filer", + "upload": "Ladda upp fil(er)" + }, + "folders": { + "collapseOrParent": "Collapse folder / Go to parent folder", + "delete": "Delete folder", + "expandOrSubfolder": "Expand folder / Go to first subfolder", + "title": "Folders Pane" + }, + "keys": { + "ctrl": "Control", + "delete": "Delete", + "downArrow": "Down arrow", + "escape": "Escape", + "leftArrow": "Left arrow", + "question": "Question mark", + "rightArrow": "Right arrow", + "upArrow": "Up arrow" + }, + "keysAbbreviations": { + "alt": "alt", + "ctrl": "ctrl", + "del": "del", + "end": "end", + "home": "home", + "shift": "shift" + } + } +} diff --git a/lib/ckfinder/lang/tr.json b/lib/ckfinder/lang/tr.json new file mode 100644 index 0000000..25f3d5b --- /dev/null +++ b/lib/ckfinder/lang/tr.json @@ -0,0 +1,288 @@ +{ + "appTitle": "CKFinder", + "dir": "ltr", + "langCode": "tr", + "common": { + "abort": "Vazgeç", + "cancel": "İptal", + "choose": "Seç", + "close": "Kapat", + "copy": "Kopyala", + "delete": "Sil", + "download": "İndir", + "edit": "Düzenle", + "maximize": "Tam Ekran", + "messageTitle": "Bilgilendirme", + "minimize": "Küçült", + "move": "Taşı", + "newNameDialogTitle": "Dizin Adı", + "ok": "Tamam", + "pleaseWait": "Lütfen bekleyin.", + "rememberDecision": "Seçimimi hatırla", + "rename": "Yeniden Adlandır", + "showMore": "Daha fazla", + "skip": "Atla", + "upload": "Karşıya Yükle", + "view": "İzle" + }, + "units": { + "dateFormat": "dd.mm.yyyy HH:MM", + "dateAmPm": [ + "ÖÖ", + "ÖS" + ], + "kb": "{size} KB", + "mb": "{size} MB", + "gb": "{size} GB", + "sizePerSecond": "{size}/sn.", + "pixelShort": "px" + }, + "files": { + "autoRename": "Otomatik yeniden adlandır", + "countMany": "{count} dosya", + "countOne": "1 dosya", + "deleteConfirmation": "{count} dosyayı silmek istediğinizden emin misiniz?", + "fileDeleteConfirmation": "\"{name}\" adlı dosyayı silmek istediğinizden emin misiniz?", + "fileRenameExtensionConfirmation": "Dosya uzantısını değiştirmek istediğinizden emin misiniz? Dosya kullanılamaz hale gelebilir.", + "fileRenameLabel": "Dosyanın yeni adını girin: ", + "filesPaneTitle": "Dosyalar bölmesi", + "filesRefresh": "Dosyalar yenileniyor", + "filterPlaceholder": "Filtrele", + "gettingFileData": "Dosya verisi alınıyor.", + "overwrite": "Üzerine yaz", + "loadingFilesPane": { + "title": "Yükleniyor...", + "text": "Dosyalar yükleniyor." + }, + "emptyFilesPane": { + "title": "Dizin boş.", + "text": "Karşıya Yükle düğmesini kullanın veya dosyalarınızı buraya sürükleyip bırakın." + }, + "filterFilesEmpty": { + "title": "Bir şey bulunamadı.", + "text": "Lütfen başka bir arama ölçütü ile tekrar deneyin." + } + }, + "folders": { + "deleteConfirmation": "\"{name}\" dizinini silmek istediğinizden emin misiniz?", + "destinationFolder": "Hedef Dizin", + "newNameLabel": "Yeni dizinin adını girin: ", + "newSubfolder": "Yeni Alt Dizin", + "renameDialogTitle": "Dizini Yeniden Adlandır", + "treeTitle": "Dizin ağacı" + }, + "copy": { + "dropMenuItem": "Buraya Kopyala", + "errorDialogTitle": "Kopyalanamayan dosyalar:", + "manyFilesDialogTitle": " {count} Dosyayı Kopyala...", + "manyFilesWait": "{count} dosya kopyalanıyor.", + "oneFileDialogTitle": "Dosyayı Kopyala...", + "oneFileWait": "Dosya kopyalanıyor.", + "operationLabel": "Dosyalar Kopyalanıyor", + "operationSummary": "{count} adet dosya kopyalandı." + }, + "move": { + "dropMenuItem": "Buraya Taşı", + "errorDialogTitle": "Taşınamayan dosyalar:", + "manyFilesDialogTitle": "{count} Dosyayı Taşı...", + "manyFilesWait": "{count} dosya taşınıyor.", + "oneFileDialogTitle": "Dosyayı Taşı...", + "oneFileWait": "Dosya taşınıyor.", + "operationLabel": "Dosyalar Taşınıyor", + "operationSummary": "{count} adet dosya taşındı." + }, + "upload": { + "addFiles": "Dosya Ekle", + "bytesCountProgress": "({bytesUploaded} / {bytesTotal})", + "details": "Ayrıntılar", + "filesCountProgress": "{filesUploaded} / {filesTotal}", + "progressLabel": "Karşıya yükleme işlemi devam ediyor.", + "progressMessage": "Karşıya Yükleniyor...", + "selectFileLabel": "Karşıya yüklenecek dosyayı seçin", + "selectFiles": "Karşıya yüklenecek dosyaları seçin", + "success": "Karşıya yükleme bitti!", + "summary": "Karşıya yüklenen dosyalar: {count}" + }, + "settings": { + "display": "Göster", + "displayDate": "Tarih", + "displayName": "Dosya Adı", + "displaySize": "Dosya Boyutu", + "sortAscending": "Artan", + "sortBy": "Sıralama Kaynağı", + "sortByOrder": "Sıralama Yönü", + "sortDescending": "Azalan", + "thumbnailSize": "Küçük Resim Boyutu", + "title": "Ayarlar", + "viewType": "Görünüm", + "viewTypeCompact": "Sıkıştırılmış", + "viewTypeList": "Liste", + "viewTypeThumbnails": "Küçük Resimler" + }, + "errors": { + "codes": { + "10": "Geçersiz komut.", + "11": "Kaynak türü istekte belirtilmedi.", + "12": "İstenen kaynak türü geçersiz.", + "13": "Bağlayıcı yapılandırma dosyası geçersiz", + "14": "Geçersiz bağlayıcı eklentisi: {pluginName}.", + "102": "Geçersiz dosya veya dizin adı.", + "103": "İstek yetkilendirme kısıtlamaları sebebiyle tamamlanamadı.", + "104": "İstek dosya sistemi kısıtlamaları sebebiyle tamamlanamadı.", + "105": "Geçersiz dosya uzantısı.", + "109": "Geçersiz istek.", + "110": "Bilinmeyen hata.", + "111": "İstek oluşan dosyanın boyutunun büyük olması sebebiyle tamamlanamadı.", + "115": "Aynı ada sahip bir dosya veya dizin zaten mevcut.", + "116": "Dizin bulunamadı. Lütfen yenileyerek tekrar deneyin.", + "117": "Dosya bulunamadı. Lütfen dosya listesini yenileyerek tekrar deneyin.", + "118": "Hedef ve kaynak yol aynı.", + "201": "Bu ada sahip bir dosya zaten mevcut. Karşıya yüklenen dosyanın adı \"{name}\" olarak değiştirildi.", + "202": "Geçersiz dosya.", + "203": "Geçersiz dosya. Dosya çok büyük.", + "204": "Karşıya yüklenen dosya bozuk.", + "205": "Sunucuda karşıya yükleme için kullanılabilir bir geçici dizin yok.", + "206": "Karşıya yükleme güvenlik sebebiyle iptal edildi. Dosya HTM benzeri veri içeriyor.", + "207": "Karşıya yüklenen dosyanın adı \"{name}\" olarak değiştirildi.", + "300": "Dosya taşıma başarısız oldu.", + "301": "Dosya kopyalama başarısız oldu.", + "302": "Dosya silme başarısız oldu.", + "500": "Dosya gezgini güvenlik sebebiyle devre dışı bırakıldı. Lütfen sistem yöneticinize başvurun ve CKFinder yapılandırma dosyasını denetleyin.", + "501": "Küçük resim desteği devre dışı bırakıldı." + }, + "deleteFilePermissions": "Bu dizinde dosya silmeye izin verilmiyor.", + "fileInvalidCharacters": "Dosya adı şu karakterlerden herhangi birini içeremez: {disallowedCharacters}", + "fileNameNotEmpty": "Dosya adı boş olamaz.", + "folderInvalidCharacters": "Dizin adı şu karakterlerden herhangi birini içeremez: {disallowedCharacters}", + "incorrectExtension": "Dosya uzantısına bu dizinde izin verilmiyor.", + "missingFile": "İstenen dosya artık mevcut değil.", + "missingFolder": "Ulaşmaya çalıştığınız dizin artık mevcut değil.", + "noUploadFolderSelected": "Lütfen karşıya yüklemeden önce bir dizin seçin.", + "operationCompleted": "İşlem hatalarla tamamlandı.", + "renameFilePermissions": "Bu dizinde dosya adı değiştirmeye izin verilmiyor.", + "unknown": "İstek tamamlanamadı. (Hata {number})", + "unknownUploadError": "Dosya gönderme hatası.", + "uploadErrors": "Karşıya yükleme hatalarla tamamlandı.", + "uploadPermissions": "Karşıya dosya yüklemeye izin verilmiyor." + }, + "chooseResizedImage": { + "title": "Yeniden Boyutlandırılmış Seç", + "originalSize": "Özgün Boyut", + "sizes": { + "custom": "Özel", + "large": "Büyük", + "max": "En Büyük", + "medium": "Orta", + "small": "Küçük" + } + }, + "editImage": { + "adjust": "Ayarla", + "apply": "Uygula", + "confirmExit": "Kapatmak istediğinizden emin misiniz? Resim üzerinde kaydedilmemiş değişiklikler yaptınız.", + "crop": "Kırp", + "downloadAction": "Özgün resim indiriliyor.", + "keepAspectRatio": "En-Boy Oranını Koru", + "loading": "Resim yükleniyor", + "presets": "Hazır Ayarlar", + "reset": "Sıfırla", + "resize": "Yeniden Boyutlandır", + "rotate": "Döndür", + "rotateAntiClockwise": "90° Sola", + "rotateClockwise": "90° Sağa", + "save": "Kaydet", + "saveDialogFileExists": "Aynı ada sahip bir dosya dizinde zaten mevcut.", + "saveDialogOverwrite": "Dosyanın Üzerine yaz", + "saveDialogSaveAs": "Farklı Kaydet:", + "saveDialogTitle": "Değişiklikleri Kaydet", + "title": "Resmi Düzenle", + "transformationAction": "Değişiklikler uygulanıyor.", + "uploadAction": "Düzenlenen resim karşıya yükleniyor.", + "filters": { + "brightness": "Aydınlık", + "clip": "İliştirme", + "contrast": "Karşıtlık", + "exposure": "Pozlama", + "gamma": "Gama", + "hue": "Renk", + "noise": "Parazit", + "saturation": "Doygunluk", + "sepia": "Sepya", + "sharpen": "Keskinlik", + "stackBlur": "Bulanıklık", + "vibrance": "Titreşim" + }, + "preset": { + "clarity": "Berrak", + "concentrate": "Yoğunlaşmış", + "crossProcess": "Cross Process", + "glowingSun": "Parlak Güneş", + "grungy": "Aşınma", + "hazyDays": "Puslu Günler", + "hemingway": "Hemingway", + "herMajesty": "Majesteleri", + "jarques": "Jarques", + "lomo": "Lomo", + "love": "Aşk", + "nostalgia": "Nostalji", + "oldBoot": "Eski Çizme", + "orangePeel": "Portakal Kabuğu", + "pinhole": "İğne Deliği", + "sinCity": "Sin City", + "sunrise": "Gündoğumu", + "vintage": "Eskilerden" + } + }, + "shortcuts": { + "title": "Kısayol Tuşları", + "general": { + "action": "Varsayılan eylemi çalıştır", + "firstItem": "İlk nesneye git", + "focusFilesPane": "Dosyalar bölmesine odaklan", + "focusFoldersPane": "Dizinler bölmesine veya menüye odaklan", + "focusNext": "Sonraki bölmeye odaklan", + "focusToolbar": "Araç çubuğuna odaklan", + "lastItem": "Son nesneye git", + "listShortcuts": "Bu yardım diyaloğunu aç", + "nextItem": "Sonraki nesneye git", + "previousItem": "Önceki nesneye git", + "showContextMenu": "Sağ tık menüsünü aç", + "title": "Genel Ara Yüz" + }, + "files": { + "addToSelectionAbove": "Yukarıdaki dosyaları seçime ekle veya çıkar.", + "addToSelectionBelow": "Aşağıdaki dosyaları seçime ekle veya çıkar.", + "addToSelectionLeft": "Soldaki dosyaları seçime ekle veya çıkar.", + "addToSelectionRight": "Sağdaki dosyaları seçime ekle veya çıkar.", + "delete": "Dosyaları sil", + "refresh": "Dosyaları yenile", + "rename": "Dosyayı yeniden adlandır", + "selectAll": "Tüm dosyaları seç", + "upload": "Karşıya Dosya Yükle" + }, + "folders": { + "collapseOrParent": "Dizini daralt / Üst dizine git", + "delete": "Dizini sil", + "expandOrSubfolder": "Dizini genişlet / İlk alt dizine git", + "title": "Dizinler Bölmesi" + }, + "keys": { + "ctrl": "Ctrl", + "delete": "Delete", + "downArrow": "Aşağı yön", + "escape": "Esc", + "leftArrow": "Sol yön", + "question": "Soru işareti", + "rightArrow": "Sağ yön", + "upArrow": "Yukarı yön" + }, + "keysAbbreviations": { + "alt": "alt", + "ctrl": "ctrl", + "del": "del", + "end": "end", + "home": "home", + "shift": "shift" + } + } +} diff --git a/lib/ckfinder/lang/uk.json b/lib/ckfinder/lang/uk.json new file mode 100644 index 0000000..cf4c694 --- /dev/null +++ b/lib/ckfinder/lang/uk.json @@ -0,0 +1,288 @@ +{ + "appTitle": "CKFinder", + "dir": "ltr", + "langCode": "uk", + "common": { + "abort": "Перервати", + "cancel": "Відміна", + "choose": "Вибрати", + "close": "Закрити", + "copy": "Копіювати", + "delete": "Видалити", + "download": "Зберегти", + "edit": "Редагувати", + "maximize": "Розгорнути", + "messageTitle": "Інформація", + "minimize": "Свернути", + "move": "Перемістити", + "newNameDialogTitle": "Нове ім'я", + "ok": "OK", + "pleaseWait": "Будьласка зачекайте.", + "rememberDecision": "Запам'ятати мій вибір", + "rename": "Змінити назву", + "showMore": "Ще", + "skip": "Пропустити", + "upload": "Завантижити файл", + "view": "Переглянути" + }, + "units": { + "dateFormat": "dd.mm.yyyy H:MM", + "dateAmPm": [ + "AM", + "PM" + ], + "kb": "{size} KБ", + "mb": "{size} МБ", + "gb": "{size} ГБ", + "sizePerSecond": "{size}/с", + "pixelShort": "пікс" + }, + "files": { + "autoRename": "Автоматично змінити назву", + "countMany": "{count} файлів", + "countOne": "1 файл", + "deleteConfirmation": "Ви впевнені, що хочете видалити {count} файла(лів)?", + "fileDeleteConfirmation": "Ви впевнені, що хочете видалити файл \"{name}\"?", + "fileRenameExtensionConfirmation": "Ви впевнені, що хочете змінити розширення файлу? Файл може стати недосяжним.", + "fileRenameLabel": "Будьласка, введіть новое ім'я файлу: ", + "filesPaneTitle": "Панель файлів", + "filesRefresh": "Оновлення файлів", + "filterPlaceholder": "Фільтр", + "gettingFileData": "Читання файлу.", + "overwrite": "Замінити файл", + "loadingFilesPane": { + "title": "Завантаження...", + "text": "Файли завантажуються." + }, + "emptyFilesPane": { + "title": "Папка пуста.", + "text": "Використовуйте кнопку Завантажити чи перетащіть ваші файлы сюди." + }, + "filterFilesEmpty": { + "title": "Нічого не знайдено.", + "text": "Будьласка спробуйте інші критерії пошуку." + } + }, + "folders": { + "deleteConfirmation": "Ви впевнені, що хочете видалити папку \"{name}\"?", + "destinationFolder": "Кінцева папка", + "newNameLabel": "Будьласка, введіть нове ім'я папки: ", + "newSubfolder": "Нова папка", + "renameDialogTitle": "Змінити назву папки", + "treeTitle": "Дерево каталогів" + }, + "copy": { + "dropMenuItem": "Копіювати", + "errorDialogTitle": "Файли, які не можуть бути скопійованими:", + "manyFilesDialogTitle": "Копіювати {count} файла(ів) в...", + "manyFilesWait": "Копіювання {count} файлів.", + "oneFileDialogTitle": "Копіювати файл в...", + "oneFileWait": "Копіювання файлу.", + "operationLabel": "Копіювання файлів", + "operationSummary": "Скопійовано файлів: {count}." + }, + "move": { + "dropMenuItem": "Перемістити", + "errorDialogTitle": "Файли, які не можуть бути переміщені:", + "manyFilesDialogTitle": "Переместить {count} файла(ов) в...", + "manyFilesWait": "Перемещение {count} файлов.", + "oneFileDialogTitle": "Переместить файл в...", + "oneFileWait": "Перемещение файла.", + "operationLabel": "Перемещение файлов", + "operationSummary": "Перемещено файлов: {count}." + }, + "upload": { + "addFiles": "Додати файли", + "bytesCountProgress": "({bytes Uploaded} з {bytesTotal})", + "details": "Детальніше", + "filesCountProgress": "{filesUploaded} з {filesTotal} ", + "progressLabel": "завантаження в процесі.", + "progressMessage": "завантаження...", + "selectFileLabel": "Вибрати файл для завантаження", + "selectFiles": "Виберіть файли для завантаження", + "success": "Завантаження завершено!", + "summary": "Завантажено файлів: {count}" + }, + "settings": { + "display": "Показувати:", + "displayDate": "Дата", + "displayName": "файл", + "displaySize": "Розмір файлу", + "sortAscending": "по зростанню", + "sortBy": "Сортувати по", + "sortByOrder": "Порядок", + "sortDescending": "за зменшенням", + "thumbnailSize": "Розмір мініатюри", + "title": "Налаштування", + "viewType": "Вид", + "viewTypeCompact": "Compact", + "viewTypeList": " Список", + "viewTypeThumbnails": "мініатюри" + }, + "errors": { + "codes": { + "10": "Невірна команда.", + "11": "Тип ресурсу не вказано в запиті.", + "12": "Неправильний запитаний тип ресурсу.", + "13": "Помилка в файлі конфігурації.", + "14": "Помилка в плагіні: {pluginName}.", + "102": "Неправильне ім'я файлу або папки.", + "103": "Неможливо завершити запит через обмеження авторизації.", + "104": "Неможливо завершити запит через обмеження дозволів файлової системи.", + "105": "Неправильне розширення файлу. ", + "109": "Невірний запит.", + "110": "Невідома помилка. ", + "111": "Неможливо завершити запит, не вірний розмір кінцевого файлу.", + "115": "файл або папка з таким ім'ям вже існує.", + "116": "папка не знайдено. Будь ласка, поновіть вид папок і спробуйте ще раз.", + "117": "Немає запису. Будь ласка, поновіть список файлів і спробуйте ще раз.", + "118": "Початкове розташування файлу співпадає з.", + "201": "Файл з такою назвою вже існує. Завантажений файл був перейменований в \"{name} \".", + "202": "Неправильний файл.", + "203": "Неправильний файл. Розмір файлу занадто великий.", + "204": "Завантажений файл пошкоджений.", + "205": "недоступна тимчасова папка для завантаження файлів на сервер.", + "206": "Завантаження скасовано з міркувань безпеки. Файл містить схожі на HTML дані.", + "207": "Завантажений файл був перейменований в \"{name} \".", + "300": "Сталася помилка при переміщенні файлу (ів).", + "301": "сталася помилка при копіюванні файлу (ів).", + "302": "сталася помилка при видаленні файлу (ів).", + "500": "Браузер файлів відключений з міркувань безпеки. Будь ласка, повідомте вашого системного адміністратру і перевірте конфігураційний файл CKFinder.", + "501": "Підтримка мініатюр відключена." + }, + "deleteFilePermissions": "Removing files is not allowed in this folder.", + "fileInvalidCharacters": "Ім'я файлу не може містити будь-який з перелічених символів: {disallowedCharacters}", + "fileNameNotEmpty": "файл не може бути порожнім.", + "folderInvalidCharacters": "Ім'я папки не може містити будь-який з перелічених символів: {disallowedCharacters}", + "incorrectExtension": "В цю папку можна завантажувати файли з таким розширенням.", + "missingFile": "Запитуваний файл більше не доступний.", + "missingFolder": "Запитувана папка більш не доступний.", + "noUploadFolderSelected": "Будь ласка, виберіть папку, в яку ви хочете завантажити файл.", + "operationCompleted": "Операція завершилася з помилками.", + "renameFilePermissions": "Renaming files is not allowed in this folder.", + "unknown": "Неможливо завершити запит. (Помилка {number})", + "unknownUploadError": "Помилка при передачі файлу.", + "uploadErrors": "Завантаження завершено з помилками.", + "uploadPermissions": "Завантаження відключена." + }, + "chooseResizedImage": { + "title": "Вибрати зменшений", + "originalSize": "Оригінальний розмір", + "sizes": { + "custom": "Призначений для користувача", + "large": "Великий", + "max": "Максимальний", + "medium": "Середній", + "small": "Маленький" + } + }, + "editImage": { + "adjust": "Корекція", + "apply": "Застосувати", + "confirmExit": "Ви дійсно хочете закрити? У вас є незбережені зміни.", + "crop": "Обрізання", + "downloadAction": "Завантаження оригінального зображення.", + "keepAspectRatio": "Зберігати співвідношення сторін", + "loading": "Завантаження зображення", + "presets": "Попередні", + "reset": "Скинути", + "resize": "Зміна розміру", + "rotate": "Поворот", + "rotateAntiClockwise": "90° вправо", + "rotateClockwise": "90° вліво", + "save": "Зберегти", + "saveDialogFileExists": "Файл з такою назвою вже існує в папці.", + "saveDialogOverwrite": "Переписати файл", + "saveDialogSaveAs": "Зберегти як:", + "saveDialogTitle": "Зберегти зміни", + "title": "Редагування зображення", + "transformationAction": "Застосувань трансформацій.", + "uploadAction": "Завантаження відредаговану фотографію.", + "filters": { + "brightness": "Яскравість", + "clip": "Clip", + "contrast": "Контраст", + "exposure": "Експозиція", + "gamma": "Гамма", + "hue": "Тон", + "noise": "Шум", + "saturation": "Насиченість", + "sepia": "Сепія", + "sharpen": "Різкість", + "stackBlur": "Розумієте", + "vibrance": "сощностью" + }, + "preset": { + "clarity": "Чіткість", + "concentrate": "Концентрат", + "crossProcess": "Кросспроцесс", + "glowingSun": "Сонячне світло", + "grungy": "Гранж", + "hazyDays": "Туман", + "hemingway": "Хемінгуей", + "herMajesty": "Її величність", + "jarques": "Jarques", + "lomo": "Ломо", + "love": "Любов", + "nostalgia": "Ностальгія", + "oldBoot": "Старий черевик", + "orangePeel": "Апельсин", + "pinhole": "Пінхол", + "sinCity": "Місто Гріхів", + "sunrise": "Схід сонця", + "vintage": "Вінтаж" + } + }, + "shortcuts": { + "title": "Швидкий доступ", + "general": { + "action": "Виконати дію за замовчуванням", + "firstItem": "Перейти до першого елементу", + "focusFilesPane": "Перейти до панелі файлів", + "focusFoldersPane": "Перейти до панелі папок", + "focusNext": "Перейти до наступної панелі", + "focusToolbar": "Перейти до панелі інструментів", + "lastItem": "Перейти до останнього елемента ", + "listShortcuts": "Відкрити це довідкове вікно ", + "nextItem": "Перейти до наступного елементу", + "previousItem": "Перейти до попереднього елемента", + "showContextMenu": "Контекстне меню", + "title": "Загальний інтерфейс" + }, + "files": { + "addToSelectionAbove": "Виділити / виключити файл зверху від виділеного", + "addToSelectionBelow": "Виділити / виключити файл знизу від виділеного", + "addToSelectionLeft": "Виділити / виключити файл зліва від виділеного", + "addToSelectionRight": "Виділити / виключити файл праворуч від виділеного", + "delete": "Видалити файл (и)", + "refresh": "Оновити", + "rename": "Перейменувати файл", + "selectAll": "Виділити всі файли", + "upload": "Завантажити файл (и )" + }, + "folders": { + "collapseOrParent": "Згорнути папку / Перейти до батьківської теки", + "delete": "Видалити папку", + "expandOrSubfolder": "Розгорнути папку / Перейти до першій папці", + "title": "Панель папок" + }, + "keys": { + "ctrl": "Control", + "delete": "Delete", + "downArrow": "Стрілка вниз", + "escape": "Escape", + "leftArrow": "Стрілка вліво", + "question": "Знак питання", + "rightArrow": "Стрілка вправо", + "upArrow": "Стрілка вгору" + }, + "keysAbbreviations": { + "alt": "alt", + "ctrl": "ctrl", + "del": "del", + "end": "end", + "home": "home", + "shift": "shift" + } + } +} diff --git a/lib/ckfinder/lang/vi.json b/lib/ckfinder/lang/vi.json new file mode 100644 index 0000000..fd2bd7a --- /dev/null +++ b/lib/ckfinder/lang/vi.json @@ -0,0 +1,288 @@ +{ + "appTitle": "CKFinder", + "dir": "ltr", + "langCode": "vi", + "common": { + "abort": "Abort", + "cancel": "Hủy", + "choose": "Choose", + "close": "Đóng", + "copy": "Copy", + "delete": "Xóa", + "download": "Tải về", + "edit": "Sửa", + "maximize": "Cực đại hóa", + "messageTitle": "Thông tin", + "minimize": "Cực tiểu hóa", + "move": "Move", + "newNameDialogTitle": "Tên mới", + "ok": "OK", + "pleaseWait": "Vui lòng chờ.", + "rememberDecision": "Ghi nhớ quyết định này", + "rename": "Đổi tên", + "showMore": "Show more", + "skip": "Bỏ qua", + "upload": "Tải lên", + "view": "Xem" + }, + "units": { + "dateFormat": "d/m/yyyy h:MM aa", + "dateAmPm": [ + "sA", + "cH" + ], + "kb": "{size} KB", + "mb": "{size} MB", + "gb": "{size} GB", + "sizePerSecond": "{size}/s", + "pixelShort": "px" + }, + "files": { + "autoRename": "Tự đổi tên", + "countMany": "{count} tập tin", + "countOne": "1 tập tin", + "deleteConfirmation": "Are you sure you want to delete {count} files?", + "fileDeleteConfirmation": "Bạn có chắc muốn xóa tập tin \"{name}\"?", + "fileRenameExtensionConfirmation": "Bạn có chắc muốn đổi phần mở rộng? Tập tin có thể sẽ không dùng được.", + "fileRenameLabel": "Xin nhập tên tập tin mới: ", + "filesPaneTitle": "Files pane", + "filesRefresh": "Refreshing files", + "filterPlaceholder": "Filter", + "gettingFileData": "Getting file data.", + "overwrite": "Ghi đè", + "loadingFilesPane": { + "title": "Loading...", + "text": "The files are being loaded." + }, + "emptyFilesPane": { + "title": "The folder is empty.", + "text": "Use the Upload button or drag and drop your files here." + }, + "filterFilesEmpty": { + "title": "Nothing found.", + "text": "Please try using different search criteria." + } + }, + "folders": { + "deleteConfirmation": "Bạn có chắc muốn xóa thư mục \"{name}\"?", + "destinationFolder": "Destination Folder", + "newNameLabel": "Xin chọn tên cho thư mục mới: ", + "newSubfolder": "Tạo thư mục con", + "renameDialogTitle": "Rename Folder", + "treeTitle": "Folders tree" + }, + "copy": { + "dropMenuItem": "Sao chép ở đây", + "errorDialogTitle": "Files that cannot be copied:", + "manyFilesDialogTitle": "Copy {count} Files To...", + "manyFilesWait": "Copying {count} files.", + "oneFileDialogTitle": "Copy File To...", + "oneFileWait": "Copying file.", + "operationLabel": "Copying Files", + "operationSummary": "Number of files copied: {count}." + }, + "move": { + "dropMenuItem": "Di chuyển ở đây", + "errorDialogTitle": "Files that cannot be moved:", + "manyFilesDialogTitle": "Move {count} Files To...", + "manyFilesWait": "Moving {count} files.", + "oneFileDialogTitle": "Move File To...", + "oneFileWait": "Moving file.", + "operationLabel": "Moving Files", + "operationSummary": "Number of files moved: {count}." + }, + "upload": { + "addFiles": "Thêm tập tin", + "bytesCountProgress": "({bytesUploaded} of {bytesTotal})", + "details": "Details", + "filesCountProgress": "{filesUploaded} of {filesTotal}", + "progressLabel": "Đang tải lên.", + "progressMessage": "Uploading...", + "selectFileLabel": "Chọn tập tin tải lên", + "selectFiles": "Select files to upload", + "success": "Upload finished!", + "summary": "Uploaded files: {count}" + }, + "settings": { + "display": "Hiển thị:", + "displayDate": "Ngày", + "displayName": "Tên tập tin", + "displaySize": "Dung lượng", + "sortAscending": "Ascending", + "sortBy": "Sort by", + "sortByOrder": "Order", + "sortDescending": "Descending", + "thumbnailSize": "Thumbnail Size", + "title": "Thiết lập", + "viewType": "View", + "viewTypeCompact": "Compact", + "viewTypeList": "List", + "viewTypeThumbnails": "Thumbnails" + }, + "errors": { + "codes": { + "10": "Lệnh không hợp lệ.", + "11": "Kiểu tài nguyên không được chỉ định trong yêu cầu.", + "12": "Kiểu tài nguyên yêu cầu không hợp lệ.", + "13": "The connector configuration file is invalid.", + "14": "Invalid connector plugin: {pluginName}.", + "102": "Tên tập tin hay thư mục không hợp lệ.", + "103": "Không thể hoàn tất yêu cầu vì giới hạn quyền.", + "104": "Không thể hoàn tất yêu cầu vì giới hạn quyền của hệ thống tập tin.", + "105": "Phần mở rộng tập tin không hợp lệ.", + "109": "Yêu cầu không hợp lệ.", + "110": "Lỗi không xác định.", + "111": "It was not possible to complete the request due to resulting file size.", + "115": "Tập tin hoặc thư mục cùng tên đã tồn tại.", + "116": "Không thấy thư mục. Hãy làm tươi và thử lại.", + "117": "Không thấy tập tin. Hãy làm tươi và thử lại.", + "118": "Đường dẫn nguồn và đích giống nhau.", + "201": "Tập tin cùng tên đã tồn tại. Tập tin vừa tải lên được đổi tên thành \"{name}\".", + "202": "Tập tin không hợp lệ.", + "203": "Tập tin không hợp lệ. Dung lượng quá lớn.", + "204": "Tập tin tải lên bị hỏng.", + "205": "Không có thư mục tạm để tải tập tin.", + "206": "Huỷ tải lên vì lí do bảo mật. Tập tin chứa dữ liệu giống HTML.", + "207": "Tập tin được đổi tên thành \"{name}\".", + "300": "Di chuyển tập tin thất bại.", + "301": "Chép tập tin thất bại.", + "302": "Deleting file(s) failed.", + "500": "Trình duyệt tập tin bị vô hiệu vì lí do bảo mật. Xin liên hệ quản trị hệ thống và kiểm tra tập tin cấu hình CKFinder.", + "501": "Chức năng hỗ trợ ảnh mẫu bị vô hiệu." + }, + "deleteFilePermissions": "Removing files is not allowed in this folder.", + "fileInvalidCharacters": "Tên tập tin không thể chưa các kí tự: {disallowedCharacters}", + "fileNameNotEmpty": "The file name cannot be empty.", + "folderInvalidCharacters": "Tên thư mục không thể chứa các kí tự: {disallowedCharacters}", + "incorrectExtension": "Kiểu tập tin không được chấp nhận trong thư mục này.", + "missingFile": "The requested file is no longer available.", + "missingFolder": "The folder you are trying to reach is no longer available.", + "noUploadFolderSelected": "Xin chọn thư mục trước khi tải lên.", + "operationCompleted": "Operation completed with errors.", + "renameFilePermissions": "Renaming files is not allowed in this folder.", + "unknown": "Không thể hoàn tất yêu cầu. (Lỗi {number})", + "unknownUploadError": "Lỗi khi tải tập tin.", + "uploadErrors": "Upload finished with errors.", + "uploadPermissions": "Không được phép tải lên." + }, + "chooseResizedImage": { + "title": "Choose Resized", + "originalSize": "Original Size", + "sizes": { + "custom": "Custom", + "large": "Large", + "max": "Max", + "medium": "Medium", + "small": "Small" + } + }, + "editImage": { + "adjust": "Adjust", + "apply": "Apply", + "confirmExit": "Are you sure you want to close? You have unsaved changes to the image.", + "crop": "Crop", + "downloadAction": "Downloading original image.", + "keepAspectRatio": "Keep Aspect Ratio", + "loading": "Loading image", + "presets": "Presets", + "reset": "Reset", + "resize": "Resize", + "rotate": "Rotate", + "rotateAntiClockwise": "90° Left", + "rotateClockwise": "90° Right", + "save": "Save", + "saveDialogFileExists": "File with the same name already exists in folder.", + "saveDialogOverwrite": "Overwrite File", + "saveDialogSaveAs": "Save as:", + "saveDialogTitle": "Save Changes", + "title": "Edit Image", + "transformationAction": "Applying transformations.", + "uploadAction": "Uploading edited image.", + "filters": { + "brightness": "Brightness", + "clip": "Clip", + "contrast": "Contrast", + "exposure": "Exposure", + "gamma": "Gamma", + "hue": "Hue", + "noise": "Noise", + "saturation": "Saturation", + "sepia": "Sepia", + "sharpen": "Sharpen", + "stackBlur": "Blur", + "vibrance": "Vibrance" + }, + "preset": { + "clarity": "Clarity", + "concentrate": "Concentrate", + "crossProcess": "Cross Process", + "glowingSun": "Glowing Sun", + "grungy": "Grungy", + "hazyDays": "Hazy Days", + "hemingway": "Hemingway", + "herMajesty": "Her Majesty", + "jarques": "Jarques", + "lomo": "Lomo", + "love": "Love", + "nostalgia": "Nostalgia", + "oldBoot": "Old Boot", + "orangePeel": "Orange Peel", + "pinhole": "Pinhole", + "sinCity": "Sin City", + "sunrise": "Sunrise", + "vintage": "Vintage" + } + }, + "shortcuts": { + "title": "Keyboard Shortcuts", + "general": { + "action": "Execute default action", + "firstItem": "Go to first item", + "focusFilesPane": "Focus files pane", + "focusFoldersPane": "Focus folders pane or breadcrumbs", + "focusNext": "Focus next pane", + "focusToolbar": "Focus toolbar", + "lastItem": "Go to last item", + "listShortcuts": "Open this help dialog", + "nextItem": "Go to next item", + "previousItem": "Go to previous item", + "showContextMenu": "Open context menu", + "title": "General Interface" + }, + "files": { + "addToSelectionAbove": "Add or remove files above to selection", + "addToSelectionBelow": "Add or remove files below to selection", + "addToSelectionLeft": "Add or remove file on the left to selection", + "addToSelectionRight": "Add or remove file on the right to selection", + "delete": "Delete file(s)", + "refresh": "Refresh files", + "rename": "Rename file", + "selectAll": "Select all files", + "upload": "Upload file(s)" + }, + "folders": { + "collapseOrParent": "Collapse folder / Go to parent folder", + "delete": "Delete folder", + "expandOrSubfolder": "Expand folder / Go to first subfolder", + "title": "Folders Pane" + }, + "keys": { + "ctrl": "Control", + "delete": "Delete", + "downArrow": "Down arrow", + "escape": "Escape", + "leftArrow": "Left arrow", + "question": "Question mark", + "rightArrow": "Right arrow", + "upArrow": "Up arrow" + }, + "keysAbbreviations": { + "alt": "alt", + "ctrl": "ctrl", + "del": "del", + "end": "end", + "home": "home", + "shift": "shift" + } + } +} diff --git a/lib/ckfinder/lang/zh-cn.json b/lib/ckfinder/lang/zh-cn.json new file mode 100644 index 0000000..77ed31e --- /dev/null +++ b/lib/ckfinder/lang/zh-cn.json @@ -0,0 +1,288 @@ +{ + "appTitle": "CKFinder", + "dir": "ltr", + "langCode": "zh-cn", + "common": { + "abort": "中止", + "cancel": "取消", + "choose": "选择", + "close": "关闭", + "copy": "复制", + "delete": "删除", + "download": "下载", + "edit": "编辑", + "maximize": "全屏", + "messageTitle": "提示", + "minimize": "最小化", + "move": "移动", + "newNameDialogTitle": "新文件名", + "ok": "确定", + "pleaseWait": "请稍候", + "rememberDecision": "下次不再询问", + "rename": "重命名", + "showMore": "更多", + "skip": "跳过", + "upload": "上传", + "view": "查看" + }, + "units": { + "dateFormat": "yyyy年m月d日 h:MM aa", + "dateAmPm": [ + "上午", + "下午" + ], + "kb": "{size} KB", + "mb": "{size} MB", + "gb": "{size} GB", + "sizePerSecond": "{size}/s", + "pixelShort": "像数" + }, + "files": { + "autoRename": "给重名文件自动命名", + "countMany": "{count} 个文件", + "countOne": "1 个文件", + "deleteConfirmation": "您确定要删除 {count} 个文件吗?", + "fileDeleteConfirmation": "您确定要删除文件 \"{name}\" 吗?", + "fileRenameExtensionConfirmation": "如果改变文件扩展名,可能会导致文件不可用。\r\n确定要更改吗?", + "fileRenameLabel": "请输入新文件名: ", + "filesPaneTitle": "文件窗口", + "filesRefresh": "正在刷新文件", + "filterPlaceholder": "过滤", + "gettingFileData": "正在获取文件数据,{pleaseWait}", + "overwrite": "自动覆盖重名文件", + "loadingFilesPane": { + "title": "正在加载...", + "text": "正在加载文件,{pleaseWait}" + }, + "emptyFilesPane": { + "title": "该文件夹是空的。", + "text": "使用 上传 按钮或 拖放 您的文件到这里来上传文件。" + }, + "filterFilesEmpty": { + "title": "没有找到。", + "text": "请尝试使用不同的搜索条件。" + } + }, + "folders": { + "deleteConfirmation": "您确定要删除文件夹 \"{name}\" 吗?", + "destinationFolder": "目标文件夹", + "newNameLabel": "请输入新文件夹名称: ", + "newSubfolder": "创建子文件夹", + "renameDialogTitle": "重命名文件夹", + "treeTitle": "文件夹目录" + }, + "copy": { + "dropMenuItem": "将文件复制至此", + "errorDialogTitle": "无法复制文件:", + "manyFilesDialogTitle": "复制 {count} 个文件到...", + "manyFilesWait": "正复制 {count} 个文件,{pleaseWait}", + "oneFileDialogTitle": "复制文件到...", + "oneFileWait": "正在复制文件,{pleaseWait}", + "operationLabel": "复制文件", + "operationSummary": "已复制的文件数: {count}。" + }, + "move": { + "dropMenuItem": "将文件移动至此", + "errorDialogTitle": "无法移动文件:", + "manyFilesDialogTitle": "移动 {count} 个文件到...", + "manyFilesWait": "正在移 {count} 个文件,{pleaseWait}", + "oneFileDialogTitle": "移动文件到...", + "oneFileWait": "正在移动文件,{pleaseWait}", + "operationLabel": "移动文件", + "operationSummary": "已移动的文件数: {count}。" + }, + "upload": { + "addFiles": "添加文件", + "bytesCountProgress": "({bytesTotal} / {bytesUploaded})", + "details": "详情", + "filesCountProgress": "{filesUploaded} / {filesTotal}", + "progressLabel": "正在上传文件,", + "progressMessage": "正在上传...", + "selectFileLabel": "选择要上传的文件", + "selectFiles": "选择要上传的文件", + "success": "上传完成!", + "summary": "已上传文件: {count}" + }, + "settings": { + "display": "显示:", + "displayDate": "日期", + "displayName": "文件名", + "displaySize": "大小", + "sortAscending": "升序", + "sortBy": "排序", + "sortByOrder": "排序顺序", + "sortDescending": "降序", + "thumbnailSize": "缩略图大小", + "title": "设置", + "viewType": "视图", + "viewTypeCompact": "Compact", + "viewTypeList": "列表", + "viewTypeThumbnails": "缩略图" + }, + "errors": { + "codes": { + "10": "无效的指令。", + "11": "文件类型不在许可范围之内。", + "12": "文件类型无效。", + "13": "无效的连接器设置文件。", + "14": "无效的连接器插件: {pluginName}。", + "102": "无效的文件名或文件夹名称。", + "103": "由于作者限制,该请求不能完成。", + "104": "由于文件系统的限制,该请求不能完成。", + "105": "无效的扩展名。", + "109": "无效请求。", + "110": "未知错误。", + "111": "由于文件大小原因,此请求无法完成。", + "115": "存在重名的文件或文件夹。", + "116": "文件夹不存在,请刷新后再试。", + "117": "文件不存在,请刷新列表后再试。", + "118": "目标位置与当前位置相同。", + "201": "文件与现有的重名,新上传的文件改名为 \"{name}\"。", + "202": "无效的文件。", + "203": "无效的文件,文件尺寸太大。", + "204": "上传文件已损失。", + "205": "服务器中的上传临时文件夹无效。", + "206": "因为安全原因,上传中断。上传文件包含不能 HTML 类型数据。", + "207": "新上传的文件改名为 \"{name}\"。", + "300": "移动文件失败。", + "301": "复制文件失败。", + "302": "删除文件失败。", + "500": "因为安全原因,文件不可浏览。请联系系统管理员并检查 CKFinder 配置文件。", + "501": "不支持缩略图方式。" + }, + "deleteFilePermissions": "Removing files is not allowed in this folder.", + "fileInvalidCharacters": "文件名不能包含以下字符:{disallowedCharacters}", + "fileNameNotEmpty": "文件名不能为空。", + "folderInvalidCharacters": "文件夹名称不能包含以下字符:{disallowedCharacters}", + "incorrectExtension": "此文件扩展名在当前文件夹中不可用。", + "missingFile": "请求的文件已不可用。", + "missingFolder": "您指定的文件夹已不可用。", + "noUploadFolderSelected": "需先选择一个文件。", + "operationCompleted": "操作完成,但有错误。", + "renameFilePermissions": "Renaming files is not allowed in this folder.", + "unknown": "请求的操作未能完成。(错误 {number})", + "unknownUploadError": "上传文件出错。", + "uploadErrors": "上传完成,但有错误。", + "uploadPermissions": "无文件上传权限。" + }, + "chooseResizedImage": { + "title": "选择调整大小", + "originalSize": "原始大小", + "sizes": { + "custom": "自定义", + "large": "大", + "max": "最大", + "medium": "中", + "small": "小" + } + }, + "editImage": { + "adjust": "调整", + "apply": "应用", + "confirmExit": "确定关闭?你会丢失未保存的图片。", + "crop": "裁剪", + "downloadAction": "正在下载原始图像...", + "keepAspectRatio": "保持纵横比", + "loading": "加载图像", + "presets": "预设", + "reset": "重置", + "resize": "缩放", + "rotate": "旋转", + "rotateAntiClockwise": "逆时针 90°", + "rotateClockwise": "顺时针 90°", + "save": "保存", + "saveDialogFileExists": "文件夹中已存在相同名称的文件。", + "saveDialogOverwrite": "覆盖文件", + "saveDialogSaveAs": "另存为:", + "saveDialogTitle": "保存更改", + "title": "编辑图像", + "transformationAction": "正在应用变换...", + "uploadAction": "正在上传编辑的图像...", + "filters": { + "brightness": "亮度", + "clip": "修剪", + "contrast": "对比度", + "exposure": "曝光度", + "gamma": "伽玛", + "hue": "色调", + "noise": "噪点", + "saturation": "饱和度", + "sepia": "怀旧", + "sharpen": "锐化", + "stackBlur": "模糊", + "vibrance": "鲜艳度" + }, + "preset": { + "clarity": "清晰", + "concentrate": "浓缩", + "crossProcess": "胶片", + "glowingSun": "光照", + "grungy": "油渍", + "hazyDays": "雨雾", + "hemingway": "海明威", + "herMajesty": "雄伟", + "jarques": "Jarques", + "lomo": "LOMO", + "love": "爱情", + "nostalgia": "怀旧", + "oldBoot": "旧靴子", + "orangePeel": "橘皮", + "pinhole": "针孔", + "sinCity": "罪恶之城", + "sunrise": "日出", + "vintage": "复古" + } + }, + "shortcuts": { + "title": "快捷键", + "general": { + "action": "执行默认操作", + "firstItem": "移动到第一项", + "focusFilesPane": "聚焦到文件窗", + "focusFoldersPane": "聚焦到文件夹窗或导航栏", + "focusNext": "聚焦到下个窗口", + "focusToolbar": "聚焦到工具栏", + "lastItem": "移动到最后一项", + "listShortcuts": "打开帮助框", + "nextItem": "移动到下一项", + "previousItem": "移动到前一项", + "showContextMenu": "打开上下文菜单", + "title": "通用界面" + }, + "files": { + "addToSelectionAbove": "添加或删除文件到选中项上面", + "addToSelectionBelow": "添加或删除文件到选中项下面", + "addToSelectionLeft": "添加或删除文件到选中项右边", + "addToSelectionRight": "Add or remove file on the right to selection", + "delete": "删除文件", + "refresh": "刷新文件", + "rename": "重命名文件", + "selectAll": "选中全部文件", + "upload": "上传文件" + }, + "folders": { + "collapseOrParent": "展开文件夹", + "delete": "删除文件夹", + "expandOrSubfolder": "折叠文件夹", + "title": "文件夹窗" + }, + "keys": { + "ctrl": "控制键", + "delete": "删除键", + "downArrow": "下箭头", + "escape": "退出", + "leftArrow": "左箭头", + "question": "问题标记", + "rightArrow": "右箭头", + "upArrow": "上箭头" + }, + "keysAbbreviations": { + "alt": "alt", + "ctrl": "ctrl", + "del": "del", + "end": "end", + "home": "home", + "shift": "shift" + } + } +} diff --git a/lib/ckfinder/lang/zh-tw.json b/lib/ckfinder/lang/zh-tw.json new file mode 100644 index 0000000..26209cf --- /dev/null +++ b/lib/ckfinder/lang/zh-tw.json @@ -0,0 +1,288 @@ +{ + "appTitle": "CKFinder", + "dir": "ltr", + "langCode": "zh-tw", + "common": { + "abort": "Abort", + "cancel": "Cancel", + "choose": "Choose", + "close": "關閉", + "copy": "Copy", + "delete": "刪除", + "download": "下載", + "edit": "Edit", + "maximize": "Maximize", + "messageTitle": "Information", + "minimize": "Minimize", + "move": "Move", + "newNameDialogTitle": "New Name", + "ok": "OK", + "pleaseWait": "Please wait.", + "rememberDecision": "Remember my decision", + "rename": "重新命名", + "showMore": "Show more", + "skip": "Skip", + "upload": "上傳檔案", + "view": "瀏覽" + }, + "units": { + "dateFormat": "mm/dd/yyyy HH:MM", + "dateAmPm": [ + "上午", + "下午" + ], + "kb": "{size} KB", + "mb": "{size} MB", + "gb": "{size} GB", + "sizePerSecond": "{size}/s", + "pixelShort": "px" + }, + "files": { + "autoRename": "Auto-rename", + "countMany": "{count} 個檔案", + "countOne": "1 個檔案", + "deleteConfirmation": "Are you sure you want to delete {count} files?", + "fileDeleteConfirmation": "確定要刪除這個檔案 \"{name}\"?", + "fileRenameExtensionConfirmation": "確定變更這個檔案的副檔名嗎? 變更後 , 此檔案可能會無法使用 !", + "fileRenameLabel": "請輸入新檔案名稱: ", + "filesPaneTitle": "Files pane", + "filesRefresh": "Refreshing files", + "filterPlaceholder": "Filter", + "gettingFileData": "Getting file data.", + "overwrite": "Overwrite", + "loadingFilesPane": { + "title": "Loading...", + "text": "The files are being loaded." + }, + "emptyFilesPane": { + "title": "The folder is empty.", + "text": "Use the Upload button or drag and drop your files here." + }, + "filterFilesEmpty": { + "title": "Nothing found.", + "text": "Please try using different search criteria." + } + }, + "folders": { + "deleteConfirmation": "確定刪除 \"{name}\" 這個目錄嗎?", + "destinationFolder": "Destination Folder", + "newNameLabel": "請輸入新目錄名稱: ", + "newSubfolder": "建立新子目錄", + "renameDialogTitle": "Rename Folder", + "treeTitle": "Folders tree" + }, + "copy": { + "dropMenuItem": "Copy Here", + "errorDialogTitle": "Files that cannot be copied:", + "manyFilesDialogTitle": "Copy {count} Files To...", + "manyFilesWait": "Copying {count} files.", + "oneFileDialogTitle": "Copy File To...", + "oneFileWait": "Copying file.", + "operationLabel": "Copying Files", + "operationSummary": "Number of files copied: {count}." + }, + "move": { + "dropMenuItem": "Move Here", + "errorDialogTitle": "Files that cannot be moved:", + "manyFilesDialogTitle": "Move {count} Files To...", + "manyFilesWait": "Moving {count} files.", + "oneFileDialogTitle": "Move File To...", + "oneFileWait": "Moving file.", + "operationLabel": "Moving Files", + "operationSummary": "Number of files moved: {count}." + }, + "upload": { + "addFiles": "Add Files", + "bytesCountProgress": "({bytesUploaded} of {bytesTotal})", + "details": "Details", + "filesCountProgress": "{filesUploaded} of {filesTotal}", + "progressLabel": "檔案上傳中 .", + "progressMessage": "Uploading...", + "selectFileLabel": "請選擇要上傳的檔案", + "selectFiles": "Select files to upload", + "success": "Upload finished!", + "summary": "Uploaded files: {count}" + }, + "settings": { + "display": "顯示欄位:", + "displayDate": "檔案日期", + "displayName": "檔案名稱", + "displaySize": "檔案大小", + "sortAscending": "Ascending", + "sortBy": "Sort by", + "sortByOrder": "Order", + "sortDescending": "Descending", + "thumbnailSize": "Thumbnail Size", + "title": "偏好設定", + "viewType": "View", + "viewTypeCompact": "Compact", + "viewTypeList": "List", + "viewTypeThumbnails": "Thumbnails" + }, + "errors": { + "codes": { + "10": "不合法的指令.", + "11": "連接過程中 , 未指定資源形態 !", + "12": "連接過程中出現不合法的資源形態 !", + "13": "The connector configuration file is invalid.", + "14": "Invalid connector plugin: {pluginName}.", + "102": "不合法的檔案或目錄名稱 !", + "103": "無法連接:可能是使用者權限設定錯誤 !", + "104": "無法連接:可能是伺服器檔案權限設定錯誤 !", + "105": "無法上傳:不合法的副檔名 !", + "109": "不合法的請求 !", + "110": "不明錯誤 !", + "111": "It was not possible to complete the request due to resulting file size.", + "115": "檔案或目錄名稱重複 !", + "116": "找不到目錄 ! 請先重新整理 , 然後再試一次 !", + "117": "找不到檔案 ! 請先重新整理 , 然後再試一次 !", + "118": "Source and target paths are equal.", + "201": "伺服器上已有相同的檔案名稱 ! 您上傳的檔案名稱將會自動更改為 \"{name}\".", + "202": "不合法的檔案 !", + "203": "不合法的檔案 ! 檔案大小超過預設值 !", + "204": "您上傳的檔案已經損毀 !", + "205": "伺服器上沒有預設的暫存目錄 !", + "206": "檔案上傳程序因為安全因素已被系統自動取消 ! 可能是上傳的檔案內容包含 HTML 碼 !", + "207": "您上傳的檔案名稱將會自動更改為 \"{name}\".", + "300": "Moving file(s) failed.", + "301": "Copying file(s) failed.", + "302": "Deleting file(s) failed.", + "500": "因為安全因素 , 檔案瀏覽器已被停用 ! 請聯絡您的系統管理者並檢查 CKFinder 的設定檔 config.php !", + "501": "縮圖預覽功能已被停用 !" + }, + "deleteFilePermissions": "Removing files is not allowed in this folder.", + "fileInvalidCharacters": "檔案名稱不能包含以下字元: {disallowedCharacters}", + "fileNameNotEmpty": "The file name cannot be empty.", + "folderInvalidCharacters": "目錄名稱不能包含以下字元: {disallowedCharacters}", + "incorrectExtension": "File extension is not allowed in this folder.", + "missingFile": "The requested file is no longer available.", + "missingFolder": "The folder you are trying to reach is no longer available.", + "noUploadFolderSelected": "Please select a folder before uploading.", + "operationCompleted": "Operation completed with errors.", + "renameFilePermissions": "Renaming files is not allowed in this folder.", + "unknown": "無法連接到伺服器 ! (錯誤代碼 {number})", + "unknownUploadError": "Error sending the file.", + "uploadErrors": "Upload finished with errors.", + "uploadPermissions": "File upload is not allowed." + }, + "chooseResizedImage": { + "title": "Choose Resized", + "originalSize": "Original Size", + "sizes": { + "custom": "Custom", + "large": "Large", + "max": "Max", + "medium": "Medium", + "small": "Small" + } + }, + "editImage": { + "adjust": "Adjust", + "apply": "Apply", + "confirmExit": "Are you sure you want to close? You have unsaved changes to the image.", + "crop": "Crop", + "downloadAction": "Downloading original image.", + "keepAspectRatio": "Keep Aspect Ratio", + "loading": "Loading image", + "presets": "Presets", + "reset": "Reset", + "resize": "Resize", + "rotate": "Rotate", + "rotateAntiClockwise": "90° Left", + "rotateClockwise": "90° Right", + "save": "Save", + "saveDialogFileExists": "File with the same name already exists in folder.", + "saveDialogOverwrite": "Overwrite File", + "saveDialogSaveAs": "Save as:", + "saveDialogTitle": "Save Changes", + "title": "Edit Image", + "transformationAction": "Applying transformations.", + "uploadAction": "Uploading edited image.", + "filters": { + "brightness": "Brightness", + "clip": "Clip", + "contrast": "Contrast", + "exposure": "Exposure", + "gamma": "Gamma", + "hue": "Hue", + "noise": "Noise", + "saturation": "Saturation", + "sepia": "Sepia", + "sharpen": "Sharpen", + "stackBlur": "Blur", + "vibrance": "Vibrance" + }, + "preset": { + "clarity": "Clarity", + "concentrate": "Concentrate", + "crossProcess": "Cross Process", + "glowingSun": "Glowing Sun", + "grungy": "Grungy", + "hazyDays": "Hazy Days", + "hemingway": "Hemingway", + "herMajesty": "Her Majesty", + "jarques": "Jarques", + "lomo": "Lomo", + "love": "Love", + "nostalgia": "Nostalgia", + "oldBoot": "Old Boot", + "orangePeel": "Orange Peel", + "pinhole": "Pinhole", + "sinCity": "Sin City", + "sunrise": "Sunrise", + "vintage": "Vintage" + } + }, + "shortcuts": { + "title": "Keyboard Shortcuts", + "general": { + "action": "Execute default action", + "firstItem": "Go to first item", + "focusFilesPane": "Focus files pane", + "focusFoldersPane": "Focus folders pane or breadcrumbs", + "focusNext": "Focus next pane", + "focusToolbar": "Focus toolbar", + "lastItem": "Go to last item", + "listShortcuts": "Open this help dialog", + "nextItem": "Go to next item", + "previousItem": "Go to previous item", + "showContextMenu": "Open context menu", + "title": "General Interface" + }, + "files": { + "addToSelectionAbove": "Add or remove files above to selection", + "addToSelectionBelow": "Add or remove files below to selection", + "addToSelectionLeft": "Add or remove file on the left to selection", + "addToSelectionRight": "Add or remove file on the right to selection", + "delete": "Delete file(s)", + "refresh": "Refresh files", + "rename": "Rename file", + "selectAll": "Select all files", + "upload": "Upload file(s)" + }, + "folders": { + "collapseOrParent": "Collapse folder / Go to parent folder", + "delete": "Delete folder", + "expandOrSubfolder": "Expand folder / Go to first subfolder", + "title": "Folders Pane" + }, + "keys": { + "ctrl": "Control", + "delete": "Delete", + "downArrow": "Down arrow", + "escape": "Escape", + "leftArrow": "Left arrow", + "question": "Question mark", + "rightArrow": "Right arrow", + "upArrow": "Up arrow" + }, + "keysAbbreviations": { + "alt": "alt", + "ctrl": "ctrl", + "del": "del", + "end": "end", + "home": "home", + "shift": "shift" + } + } +} diff --git a/lib/ckfinder/libs/caman.js b/lib/ckfinder/libs/caman.js new file mode 100644 index 0000000..33c9104 --- /dev/null +++ b/lib/ckfinder/libs/caman.js @@ -0,0 +1,252 @@ + +(function(){var $,Analyze,Blender,Calculate,Caman,CamanParser,Canvas,Convert,Event,Fiber,Filter,IO,Image,Layer,Log,Module,Pixel,Plugin,Renderer,Root,Store,Util,fs,http,moduleKeywords,slice,vignetteFilters,indexOf=[].indexOf||function(item){for(var i=0,l=this.length;i255){return 255;} +return val;};Util.copyAttributes=function(from,to,opts){var attr,len,o,ref,ref1,results;if(opts==null){opts={};} +ref=from.attributes;results=[];for(o=0,len=ref.length;o=0)){continue;} +results.push(to.setAttribute(attr.nodeName,attr.nodeValue));} +return results;};Util.dataArray=function(length){if(length==null){length=0;} +if(Caman.NodeJS||(window.Uint8Array!=null)){return new Uint8Array(length);} +return new Array(length);};return Util;})();if(typeof exports!=="undefined"&&exports!==null){Root=exports;Canvas=require('canvas');Image=Canvas.Image;Fiber=require('fibers');fs=require('fs');http=require('http');}else{Root=window;} +Caman=(function(superClass){extend(Caman,superClass);Caman.version={release:"4.1.2",date:"7/27/2013"};Caman.DEBUG=false;Caman.allowRevert=true;Caman.crossOrigin="anonymous";Caman.remoteProxy="";Caman.proxyParam="camanProxyUrl";Caman.NodeJS=typeof exports!=="undefined"&&exports!==null;Caman.autoload=!Caman.NodeJS;Caman.toString=function(){return"Version "+Caman.version.release+", Released "+Caman.version.date;};Caman.getAttrId=function(canvas){if(Caman.NodeJS){return true;} +if(typeof canvas==="string"){canvas=$(canvas);} +if(!((canvas!=null)&&(canvas.getAttribute!=null))){return null;} +return canvas.getAttribute('data-caman-id');};function Caman(){this.nodeFileReady=bind(this.nodeFileReady,this);var args,callback,id;if(arguments.length===0){throw"Invalid arguments";} +if(this instanceof Caman){this.finishInit=this.finishInit.bind(this);this.imageLoaded=this.imageLoaded.bind(this);args=arguments[0];if(!Caman.NodeJS){id=parseInt(Caman.getAttrId(args[0]),10);callback=typeof args[1]==="function"?args[1]:typeof args[2]==="function"?args[2]:function(){};if(!isNaN(id)&&Store.has(id)){return Store.execute(id,callback);}} +this.id=Util.uniqid.get();this.initializedPixelData=this.originalPixelData=null;this.cropCoordinates={x:0,y:0};this.cropped=false;this.resized=false;this.rotated=false;this.rotationAngle=0;this.pixelStack=[];this.layerStack=[];this.canvasQueue=[];this.currentLayer=null;this.scaled=false;this.analyze=new Analyze(this);this.renderer=new Renderer(this);this.domIsLoaded((function(_this){return function(){_this.parseArguments(args);return _this.setup();};})(this));return this;}else{return new Caman(arguments);}} +Caman.prototype.domIsLoaded=function(cb){var listener;if(Caman.NodeJS){return setTimeout((function(_this){return function(){return cb.call(_this);};})(this),0);}else{if(document.readyState==="complete"){Log.debug("DOM initialized");return setTimeout((function(_this){return function(){return cb.call(_this);};})(this),0);}else{listener=(function(_this){return function(){if(document.readyState==="complete"){Log.debug("DOM initialized");return cb.call(_this);}};})(this);return document.addEventListener("readystatechange",listener,false);}}};Caman.prototype.parseArguments=function(args){var key,ref,results,val;if(args.length===0){throw"Invalid arguments given";} +this.initObj=null;this.initType=null;this.imageUrl=null;this.callback=function(){};this.setInitObject(args[0]);if(args.length===1){return;} +switch(typeof args[1]){case"string":this.imageUrl=args[1];break;case"function":this.callback=args[1];} +if(args.length===2){return;} +this.callback=args[2];if(args.length===4){ref=args[4];results=[];for(key in ref){if(!hasProp.call(ref,key))continue;val=ref[key];results.push(this.options[key]=val);} +return results;}};Caman.prototype.setInitObject=function(obj){if(Caman.NodeJS){this.initObj=obj;this.initType='node';return;} +if(typeof obj==="object"){this.initObj=obj;}else{this.initObj=$(obj);} +if(this.initObj==null){throw"Could not find image or canvas for initialization.";} +return this.initType=this.initObj.nodeName.toLowerCase();};Caman.prototype.setup=function(){switch(this.initType){case"node":return this.initNode();case"img":return this.initImage();case"canvas":return this.initCanvas();}};Caman.prototype.initNode=function(){Log.debug("Initializing for NodeJS");if(typeof this.initObj==="string"&&this.initObj.match(/^https?:\/\//)){return this.readFromHttp(this.initObj,this.nodeFileReady);}else if(typeof this.initObj==="string"){return fs.readFile(this.initObj,this.nodeFileReady);}else{return this.nodeFileReady(null,this.initObj);}};Caman.prototype.readFromHttp=function(url,callback){var req;Log.debug("Fetching image from "+url);req=http.get(url,function(res){var buf;buf='';res.setEncoding('binary');res.on('data',function(chunk){return buf+=chunk;});return res.on('end',function(){return callback(null,new Buffer(buf,'binary'));});});return req.on('error',callback);};Caman.prototype.nodeFileReady=function(err,data){if(err){throw err;} +this.image=new Image();this.image.src=data;Log.debug("Image loaded. Width = "+(this.imageWidth())+", Height = "+(this.imageHeight()));this.canvas=new Canvas(this.imageWidth(),this.imageHeight());this.renderingCanvas=new Canvas(this.imageWidth(),this.imageHeight());return this.finishInit();};Caman.prototype.initImage=function(){this.image=this.initObj;this.canvas=document.createElement('canvas');this.context=this.canvas.getContext('2d');this.renderingCanvas=document.createElement('canvas');this.renderingContext=this.renderingCanvas.getContext('2d');Util.copyAttributes(this.image,this.canvas,{except:['src']});Util.copyAttributes(this.image,this.renderingCanvas,{except:['src']});if(this.image.parentNode!=null){this.image.parentNode.replaceChild(this.renderingCanvas,this.image);} +this.imageAdjustments();return this.waitForImageLoaded();};Caman.prototype.initCanvas=function(){this.canvas=document.createElement('canvas');this.context=this.canvas.getContext('2d');this.renderingCanvas=this.initObj;this.renderingContext=this.renderingCanvas.getContext('2d');this.canvas.width=this.renderingCanvas.width;this.canvas.height=this.renderingCanvas.height;if(this.imageUrl!=null){this.image=document.createElement('img');this.image.src=this.imageUrl;this.imageAdjustments();return this.waitForImageLoaded();}else{return this.finishInit();}};Caman.prototype.imageAdjustments=function(){if(this.needsHiDPISwap()){Log.debug(this.image.src,"->",this.hiDPIReplacement());this.swapped=true;this.image.src=this.hiDPIReplacement();} +if(IO.isRemote(this.image)){this.image.src=IO.proxyUrl(this.image.src);return Log.debug("Remote image detected, using URL = "+this.image.src);}};Caman.prototype.waitForImageLoaded=function(){if(this.isImageLoaded()){return this.imageLoaded();}else{return this.image.onload=this.imageLoaded;}};Caman.prototype.isImageLoaded=function(){if(!this.image.complete){return false;} +if((this.image.naturalWidth!=null)&&this.image.naturalWidth===0){return false;} +return true;};Caman.prototype.imageWidth=function(){return this.image.width||this.image.naturalWidth;};Caman.prototype.imageHeight=function(){return this.image.height||this.image.naturalHeight;};Caman.prototype.imageLoaded=function(){Log.debug("Image loaded. Width = "+(this.imageWidth())+", Height = "+(this.imageHeight()));if(this.swapped){this.canvas.width=this.imageWidth()/this.hiDPIRatio();this.canvas.height=this.imageHeight()/this.hiDPIRatio();this.renderingCanvas.width=this.imageWidth()/this.hiDPIRatio();this.renderingCanvas.height=this.imageHeight()/this.hiDPIRatio();}else{this.canvas.width=this.imageWidth();this.canvas.height=this.imageHeight();this.renderingCanvas.width=this.imageWidth();this.renderingCanvas.height=this.imageHeight();} +return this.finishInit();};Caman.prototype.finishInit=function(){var i,len,o,pixel,ref;if(this.context==null){this.context=this.canvas.getContext('2d');} +if(this.renderingContext==null){this.renderingContext=this.renderingCanvas.getContext('2d');} +this.originalWidth=this.preScaledWidth=this.width=this.canvas.width;this.originalHeight=this.preScaledHeight=this.height=this.canvas.height;this.hiDPIAdjustments();if(!this.hasId()){this.assignId();} +if(this.image!=null){this.context.drawImage(this.image,0,0,this.imageWidth(),this.imageHeight(),0,0,this.preScaledWidth,this.preScaledHeight);this.renderingContext.drawImage(this.image,0,0,this.imageWidth(),this.imageHeight(),0,0,this.preScaledWidth,this.preScaledHeight);} +this.imageData=this.context.getImageData(0,0,this.canvas.width,this.canvas.height);this.pixelData=this.imageData.data;if(Caman.allowRevert){this.initializedPixelData=Util.dataArray(this.pixelData.length);this.originalPixelData=Util.dataArray(this.pixelData.length);ref=this.pixelData;for(i=o=0,len=ref.length;oref;i=0<=ref?++o:--o){divisor+=adjust[i];}} +this.renderer.add({type:Filter.Type.Kernel,name:name,adjust:adjust,divisor:divisor,bias:bias});return this;};Caman.prototype.processPlugin=function(plugin,args){this.renderer.add({type:Filter.Type.Plugin,plugin:plugin,args:args});return this;};Caman.prototype.newLayer=function(callback){var layer;layer=new Layer(this);this.canvasQueue.push(layer);this.renderer.add({type:Filter.Type.LayerDequeue});callback.call(layer);this.renderer.add({type:Filter.Type.LayerFinished});return this;};Caman.prototype.executeLayer=function(layer){return this.pushContext(layer);};Caman.prototype.pushContext=function(layer){this.layerStack.push(this.currentLayer);this.pixelStack.push(this.pixelData);this.currentLayer=layer;return this.pixelData=layer.pixelData;};Caman.prototype.popContext=function(){this.pixelData=this.pixelStack.pop();return this.currentLayer=this.layerStack.pop();};Caman.prototype.applyCurrentLayer=function(){return this.currentLayer.applyToParent();};return Caman;})(Module);Root.Caman=Caman;Caman.Analyze=(function(){function Analyze(c1){this.c=c1;} +Analyze.prototype.calculateLevels=function(){var i,levels,numPixels,o,ref,u,w;levels={r:{},g:{},b:{}};for(i=o=0;o<=255;i=++o){levels.r[i]=0;levels.g[i]=0;levels.b[i]=0;} +for(i=u=0,ref=this.c.pixelData.length;u0)){return;} +results=[];for(o=0,len=imgs.length;o0)){return;} +r=new RegExp(INST_REGEX);results=[];for(o=0,len=unparsedInstructions.length;o1){next=[];for(j=u=0,ref=prev.length-2;0<=ref?u<=ref:u>=ref;j=0<=ref?++u:--u){next.push([lerp(prev[j][0],prev[j+1][0],t),lerp(prev[j][1],prev[j+1][1],t)]);} +prev=next;} +bezier[Math.round(prev[0][0])]=Math.round(clamp(prev[0][1],lowBound,highBound));} +endX=controlPoints[controlPoints.length-1][0];bezier=Caman.Calculate.missingValues(bezier,endX);if(bezier[endX]==null){bezier[endX]=bezier[endX-1];} +return bezier;};Calculate.hermite=function(controlPoints,lowBound,highBound){var add,clamp,count,endX,fac0,fac1,fac2,fac3,i,j,lerp,m0,m1,mul,o,p,p0,p1,pointsPerSegment,pointsPerStep,pos,ref,ref1,ret,sub,t,u;if(controlPoints.length<2){throw"Invalid number of arguments to hermite";} +ret={};lerp=function(a,b,t){return a*(1-t)+b*t;};add=(function(_this){return function(a,b,c,d){return[a[0]+b[0]+c[0]+d[0],a[1]+b[1]+c[1]+d[1]];};})(this);mul=(function(_this){return function(a,b){return[a[0]*b[0],a[1]*b[1]];};})(this);sub=(function(_this){return function(a,b){return[a[0]-b[0],a[1]-b[1]];};})(this);clamp=function(a,min,max){return Math.min(Math.max(a,min),max);};count=0;for(i=o=0,ref=controlPoints.length-2;0<=ref?o<=ref:o>=ref;i=0<=ref?++o:--o){p0=controlPoints[i];p1=controlPoints[i+1];pointsPerSegment=p1[0]-p0[0];pointsPerStep=1/pointsPerSegment;if(i===controlPoints.length-2){pointsPerStep=1/(pointsPerSegment-1);} +p=i>0?controlPoints[i-1]:p0;m0=mul(sub(p1,p),[0.5,0.5]);p=i=ref1;j=0<=ref1?++u:--u){t=j*pointsPerStep;fac0=2.0*t*t*t-3.0*t*t+1.0;fac1=t*t*t-2.0*t*t+t;fac2=-2.0*t*t*t+3.0*t*t;fac3=t*t*t-t*t;pos=add(mul(p0,[fac0,fac0]),mul(m0,[fac1,fac1]),mul(p1,[fac2,fac2]),mul(m1,[fac3,fac3]));ret[Math.round(pos[0])]=Math.round(clamp(pos[1],lowBound,highBound));count+=1;}} +endX=controlPoints[controlPoints.length-1][0];ret=Caman.Calculate.missingValues(ret,endX);return ret;};Calculate.missingValues=function(values,endX){var i,j,leftCoord,o,ref,ref1,ref2,ret,rightCoord,u;if(Object.keys(values).length=ref;i=0<=ref?++o:--o){if(values[i]!=null){ret[i]=values[i];}else{leftCoord=[i-1,ret[i-1]];for(j=u=ref1=i,ref2=endX;ref1<=ref2?u<=ref2:u>=ref2;j=ref1<=ref2?++u:--u){if(values[j]!=null){rightCoord=[j,values[j]];break;}} +if(rightCoord){ret[i]=leftCoord[1]+((rightCoord[1]-leftCoord[1])/(rightCoord[0]-leftCoord[0]))*(i-leftCoord[0]);}}} +return ret;} +return values;};return Calculate;})();Calculate=Caman.Calculate;Caman.Convert=(function(){function Convert(){} +Convert.hexToRGB=function(hex){var b,g,r;if(hex.charAt(0)==="#"){hex=hex.substr(1);} +r=parseInt(hex.substr(0,2),16);g=parseInt(hex.substr(2,2),16);b=parseInt(hex.substr(4,2),16);return{r:r,g:g,b:b};};Convert.rgbToHSL=function(r,g,b){var d,h,l,max,min,s;if(typeof r==="object"){g=r.g;b=r.b;r=r.r;} +r/=255;g/=255;b/=255;max=Math.max(r,g,b);min=Math.min(r,g,b);l=(max+min)/2;if(max===min){h=s=0;}else{d=max-min;s=l>0.5?d/(2-max-min):d/(max+min);h=(function(){switch(max){case r:return(g-b)/d+(g1){t-=1;} +if(t<1/6){return p+(q-p)*6*t;} +if(t<1/2){return q;} +if(t<2/3){return p+(q-p)*(2/3-t)*6;} +return p;};Convert.rgbToHSV=function(r,g,b){var d,h,max,min,s,v;r/=255;g/=255;b/=255;max=Math.max(r,g,b);min=Math.min(r,g,b);v=max;d=max-min;s=max===0?0:d/max;if(max===min){h=0;}else{h=(function(){switch(max){case r:return(g-b)/d+(g0.04045){r=Math.pow((r+0.055)/1.055,2.4);}else{r/=12.92;} +if(g>0.04045){g=Math.pow((g+0.055)/1.055,2.4);}else{g/=12.92;} +if(b>0.04045){b=Math.pow((b+0.055)/1.055,2.4);}else{b/=12.92;} +x=r*0.4124+g*0.3576+b*0.1805;y=r*0.2126+g*0.7152+b*0.0722;z=r*0.0193+g*0.1192+b*0.9505;return{x:x*100,y:y*100,z:z*100};};Convert.xyzToRGB=function(x,y,z){var b,g,r;x/=100;y/=100;z/=100;r=(3.2406*x)+(-1.5372*y)+(-0.4986*z);g=(-0.9689*x)+(1.8758*y)+(0.0415*z);b=(0.0557*x)+(-0.2040*y)+(1.0570*z);if(r>0.0031308){r=(1.055*Math.pow(r,0.4166666667))-0.055;}else{r*=12.92;} +if(g>0.0031308){g=(1.055*Math.pow(g,0.4166666667))-0.055;}else{g*=12.92;} +if(b>0.0031308){b=(1.055*Math.pow(b,0.4166666667))-0.055;}else{b*=12.92;} +return{r:r*255,g:g*255,b:b*255};};Convert.xyzToLab=function(x,y,z){var a,b,l,whiteX,whiteY,whiteZ;if(typeof x==="object"){y=x.y;z=x.z;x=x.x;} +whiteX=95.047;whiteY=100.0;whiteZ=108.883;x/=whiteX;y/=whiteY;z/=whiteZ;if(x>0.008856451679){x=Math.pow(x,0.3333333333);}else{x=(7.787037037*x)+0.1379310345;} +if(y>0.008856451679){y=Math.pow(y,0.3333333333);}else{y=(7.787037037*y)+0.1379310345;} +if(z>0.008856451679){z=Math.pow(z,0.3333333333);}else{z=(7.787037037*z)+0.1379310345;} +l=116*y-16;a=500*(x-y);b=200*(y-z);return{l:l,a:a,b:b};};Convert.labToXYZ=function(l,a,b){var x,y,z;if(typeof l==="object"){a=l.a;b=l.b;l=l.l;} +y=(l+16)/116;x=y+(a/500);z=y-(b/200);if(x>0.2068965517){x=x*x*x;}else{x=0.1284185493*(x-0.1379310345);} +if(y>0.2068965517){y=y*y*y;}else{y=0.1284185493*(y-0.1379310345);} +if(z>0.2068965517){z=z*z*z;}else{z=0.1284185493*(z-0.1379310345);} +return{x:x*95.047,y:y*100.0,z:z*108.883};};Convert.rgbToLab=function(r,g,b){var xyz;if(typeof r==="object"){g=r.g;b=r.b;r=r.r;} +xyz=this.rgbToXYZ(r,g,b);return this.xyzToLab(xyz);};Convert.labToRGB=function(l,a,b){};return Convert;})();Convert=Caman.Convert;Caman.Event=(function(){function Event(){} +Event.events={};Event.types=["processStart","processComplete","renderStart","renderFinished","blockStarted","blockFinished"];Event.trigger=function(target,type,data){var event,len,o,ref,results;if(data==null){data=null;} +if(this.events[type]&&this.events[type].length){ref=this.events[type];results=[];for(o=0,len=ref.length;othis.c.pixelData.length||newLoc<0){return new Pixel(0,0,0,255,this.c);} +return this.pixelAtLocation(newLoc);};Pixel.prototype.putPixelRelative=function(horiz,vert,rgba){var nowLoc;if(this.c==null){throw"Requires a CamanJS context";} +nowLoc=this.loc+(this.c.dimensions.width*4*(vert*-1))+(4*horiz);if(newLoc>this.c.pixelData.length||newLoc<0){return;} +this.c.pixelData[newLoc]=rgba.r;this.c.pixelData[newLoc+1]=rgba.g;this.c.pixelData[newLoc+2]=rgba.b;this.c.pixelData[newLoc+3]=rgba.a;return true;};Pixel.prototype.getPixel=function(x,y){var loc;if(this.c==null){throw"Requires a CamanJS context";} +loc=this.coordinatesToLocation(x,y,this.width);return this.pixelAtLocation(loc);};Pixel.prototype.putPixel=function(x,y,rgba){var loc;if(this.c==null){throw"Requires a CamanJS context";} +loc=this.coordinatesToLocation(x,y,this.width);this.c.pixelData[loc]=rgba.r;this.c.pixelData[loc+1]=rgba.g;this.c.pixelData[loc+2]=rgba.b;return this.c.pixelData[loc+3]=rgba.a;};Pixel.prototype.toString=function(){return this.toKey();};Pixel.prototype.toHex=function(includeAlpha){var hex;if(includeAlpha==null){includeAlpha=false;} +hex='#'+this.r.toString(16)+this.g.toString(16)+this.b.toString(16);if(includeAlpha){return hex+this.a.toString(16);}else{return hex;}};return Pixel;})();Pixel=Caman.Pixel;Caman.Plugin=(function(){function Plugin(){} +Plugin.plugins={};Plugin.register=function(name,plugin){return this.plugins[name]=plugin;};Plugin.execute=function(context,name,args){return this.plugins[name].apply(context,args);};return Plugin;})();Plugin=Caman.Plugin;Caman.Renderer=(function(){Renderer.Blocks=Caman.NodeJS?require('os').cpus().length:4;function Renderer(c1){this.c=c1;this.processNext=bind(this.processNext,this);this.renderQueue=[];this.modPixelData=null;} +Renderer.prototype.add=function(job){if(job==null){return;} +return this.renderQueue.push(job);};Renderer.prototype.processNext=function(){var layer;if(this.renderQueue.length===0){Event.trigger(this,"renderFinished");if(this.finishedFn!=null){this.finishedFn.call(this.c);} +return this;} +this.currentJob=this.renderQueue.shift();switch(this.currentJob.type){case Filter.Type.LayerDequeue:layer=this.c.canvasQueue.shift();this.c.executeLayer(layer);return this.processNext();case Filter.Type.LayerFinished:this.c.applyCurrentLayer();this.c.popContext();return this.processNext();case Filter.Type.LoadOverlay:return this.loadOverlay(this.currentJob.layer,this.currentJob.src);case Filter.Type.Plugin:return this.executePlugin();default:return this.executeFilter();}};Renderer.prototype.execute=function(callback){this.finishedFn=callback;this.modPixelData=Util.dataArray(this.c.pixelData.length);return this.processNext();};Renderer.prototype.eachBlock=function(fn){var blockN,blockPixelLength,bnum,end,f,i,lastBlockN,n,o,ref,results,start;this.blocksDone=0;n=this.c.pixelData.length;blockPixelLength=Math.floor((n/4)/Renderer.Blocks);blockN=blockPixelLength*4;lastBlockN=blockN+((n/4)%Renderer.Blocks)*4;results=[];for(i=o=0,ref=Renderer.Blocks;0<=ref?oref;i=0<=ref?++o:--o){start=i*blockN;end=start+(i===Renderer.Blocks-1?lastBlockN:blockN);if(Caman.NodeJS){f=Fiber((function(_this){return function(){return fn.call(_this,i,start,end);};})(this));bnum=f.run();results.push(this.blockFinished(bnum));}else{results.push(setTimeout((function(_this){return function(i,start,end){return function(){return fn.call(_this,i,start,end);};};})(this)(i,start,end),0));}} +return results;};Renderer.prototype.executeFilter=function(){Event.trigger(this.c,"processStart",this.currentJob);if(this.currentJob.type===Filter.Type.Single){return this.eachBlock(this.renderBlock);}else{return this.eachBlock(this.renderKernel);}};Renderer.prototype.executePlugin=function(){Log.debug("Executing plugin "+this.currentJob.plugin);Plugin.execute(this.c,this.currentJob.plugin,this.currentJob.args);Log.debug("Plugin "+this.currentJob.plugin+" finished!");return this.processNext();};Renderer.prototype.renderBlock=function(bnum,start,end){var i,o,pixel,ref,ref1;Log.debug("Block #"+bnum+" - Filter: "+this.currentJob.name+", Start: "+start+", End: "+end);Event.trigger(this.c,"blockStarted",{blockNum:bnum,totalBlocks:Renderer.Blocks,startPixel:start,endPixel:end});pixel=new Pixel();pixel.setContext(this.c);for(i=o=ref=start,ref1=end;o=ref3;j=ref2<=ref3?++u:--u){for(k=w=ref4=builder,ref5=-builder;ref4<=ref5?w<=ref5:w>=ref5;k=ref4<=ref5?++w:--w){p=pixel.getPixelRelative(j,k);kernel[builderIndex*3]=p.r;kernel[builderIndex*3+1]=p.g;kernel[builderIndex*3+2]=p.b;builderIndex++;}} +res=this.processKernel(adjust,kernel,divisor,bias);this.modPixelData[i]=Util.clampRGB(res.r);this.modPixelData[i+1]=Util.clampRGB(res.g);this.modPixelData[i+2]=Util.clampRGB(res.b);this.modPixelData[i+3]=this.c.pixelData[i+3];} +if(Caman.NodeJS){return Fiber["yield"](bnum);}else{return this.blockFinished(bnum);}};Renderer.prototype.blockFinished=function(bnum){var i,o,ref;if(bnum>=0){Log.debug("Block #"+bnum+" finished! Filter: "+this.currentJob.name);} +this.blocksDone++;Event.trigger(this.c,"blockFinished",{blockNum:bnum,blocksFinished:this.blocksDone,totalBlocks:Renderer.Blocks});if(this.blocksDone===Renderer.Blocks){if(this.currentJob.type===Filter.Type.Kernel){for(i=o=0,ref=this.c.pixelData.length;0<=ref?oref;i=0<=ref?++o:--o){this.c.pixelData[i]=this.modPixelData[i];}} +if(bnum>=0){Log.debug("Filter "+this.currentJob.name+" finished!");} +Event.trigger(this.c,"processComplete",this.currentJob);return this.processNext();}};Renderer.prototype.processKernel=function(adjust,kernel,divisor,bias){var i,o,ref,val;val={r:0,g:0,b:0};for(i=o=0,ref=adjust.length;0<=ref?oref;i=0<=ref?++o:--o){val.r+=adjust[i]*kernel[i*3];val.g+=adjust[i]*kernel[i*3+1];val.b+=adjust[i]*kernel[i*3+2];} +val.r=(val.r/divisor)+bias;val.g=(val.g/divisor)+bias;val.b=(val.b/divisor)+bias;return val;};Renderer.prototype.loadOverlay=function(layer,src){var img,proxyUrl;img=new Image();img.onload=(function(_this){return function(){layer.context.drawImage(img,0,0,_this.c.dimensions.width,_this.c.dimensions.height);layer.imageData=layer.context.getImageData(0,0,_this.c.dimensions.width,_this.c.dimensions.height);layer.pixelData=layer.imageData.data;_this.c.pixelData=layer.pixelData;return _this.processNext();};})(this);proxyUrl=IO.remoteCheck(src);return img.src=proxyUrl!=null?proxyUrl:src;};return Renderer;})();Renderer=Caman.Renderer;Caman.Store=(function(){function Store(){} +Store.items={};Store.has=function(search){return this.items[search]!=null;};Store.get=function(search){return this.items[search];};Store.put=function(name,obj){return this.items[name]=obj;};Store.execute=function(search,callback){setTimeout((function(_this){return function(){return callback.call(_this.get(search),_this.get(search));};})(this),0);return this.get(search);};Store.flush=function(name){if(name==null){name=false;} +if(name){return delete this.items[name];}else{return this.items={};}};return Store;})();Store=Caman.Store;Blender.register("normal",function(rgbaLayer,rgbaParent){return{r:rgbaLayer.r,g:rgbaLayer.g,b:rgbaLayer.b};});Blender.register("multiply",function(rgbaLayer,rgbaParent){return{r:(rgbaLayer.r*rgbaParent.r)/255,g:(rgbaLayer.g*rgbaParent.g)/255,b:(rgbaLayer.b*rgbaParent.b)/255};});Blender.register("screen",function(rgbaLayer,rgbaParent){return{r:255-(((255-rgbaLayer.r)*(255-rgbaParent.r))/255),g:255-(((255-rgbaLayer.g)*(255-rgbaParent.g))/255),b:255-(((255-rgbaLayer.b)*(255-rgbaParent.b))/255)};});Blender.register("overlay",function(rgbaLayer,rgbaParent){var result;result={};result.r=rgbaParent.r>128?255-2*(255-rgbaLayer.r)*(255-rgbaParent.r)/255:(rgbaParent.r*rgbaLayer.r*2)/255;result.g=rgbaParent.g>128?255-2*(255-rgbaLayer.g)*(255-rgbaParent.g)/255:(rgbaParent.g*rgbaLayer.g*2)/255;result.b=rgbaParent.b>128?255-2*(255-rgbaLayer.b)*(255-rgbaParent.b)/255:(rgbaParent.b*rgbaLayer.b*2)/255;return result;});Blender.register("difference",function(rgbaLayer,rgbaParent){return{r:rgbaLayer.r-rgbaParent.r,g:rgbaLayer.g-rgbaParent.g,b:rgbaLayer.b-rgbaParent.b};});Blender.register("addition",function(rgbaLayer,rgbaParent){return{r:rgbaParent.r+rgbaLayer.r,g:rgbaParent.g+rgbaLayer.g,b:rgbaParent.b+rgbaLayer.b};});Blender.register("exclusion",function(rgbaLayer,rgbaParent){return{r:128-2*(rgbaParent.r-128)*(rgbaLayer.r-128)/255,g:128-2*(rgbaParent.g-128)*(rgbaLayer.g-128)/255,b:128-2*(rgbaParent.b-128)*(rgbaLayer.b-128)/255};});Blender.register("softLight",function(rgbaLayer,rgbaParent){var result;result={};result.r=rgbaParent.r>128?255-((255-rgbaParent.r)*(255-(rgbaLayer.r-128)))/255:(rgbaParent.r*(rgbaLayer.r+128))/255;result.g=rgbaParent.g>128?255-((255-rgbaParent.g)*(255-(rgbaLayer.g-128)))/255:(rgbaParent.g*(rgbaLayer.g+128))/255;result.b=rgbaParent.b>128?255-((255-rgbaParent.b)*(255-(rgbaLayer.b-128)))/255:(rgbaParent.b*(rgbaLayer.b+128))/255;return result;});Blender.register("lighten",function(rgbaLayer,rgbaParent){return{r:rgbaParent.r>rgbaLayer.r?rgbaParent.r:rgbaLayer.r,g:rgbaParent.g>rgbaLayer.g?rgbaParent.g:rgbaLayer.g,b:rgbaParent.b>rgbaLayer.b?rgbaParent.b:rgbaLayer.b};});Blender.register("darken",function(rgbaLayer,rgbaParent){return{r:rgbaParent.r>rgbaLayer.r?rgbaLayer.r:rgbaParent.r,g:rgbaParent.g>rgbaLayer.g?rgbaLayer.g:rgbaParent.g,b:rgbaParent.b>rgbaLayer.b?rgbaLayer.b:rgbaParent.b};});Filter.register("fillColor",function(){var color;if(arguments.length===1){color=Convert.hexToRGB(arguments[0]);}else{color={r:arguments[0],g:arguments[1],b:arguments[2]};} +return this.process("fillColor",function(rgba){rgba.r=color.r;rgba.g=color.g;rgba.b=color.b;rgba.a=255;return rgba;});});Filter.register("brightness",function(adjust){adjust=Math.floor(255*(adjust/100));return this.process("brightness",function(rgba){rgba.r+=adjust;rgba.g+=adjust;rgba.b+=adjust;return rgba;});});Filter.register("saturation",function(adjust){adjust*=-0.01;return this.process("saturation",function(rgba){var max;max=Math.max(rgba.r,rgba.g,rgba.b);if(rgba.r!==max){rgba.r+=(max-rgba.r)*adjust;} +if(rgba.g!==max){rgba.g+=(max-rgba.g)*adjust;} +if(rgba.b!==max){rgba.b+=(max-rgba.b)*adjust;} +return rgba;});});Filter.register("vibrance",function(adjust){adjust*=-1;return this.process("vibrance",function(rgba){var amt,avg,max;max=Math.max(rgba.r,rgba.g,rgba.b);avg=(rgba.r+rgba.g+rgba.b)/3;amt=((Math.abs(max-avg)*2/255)*adjust)/100;if(rgba.r!==max){rgba.r+=(max-rgba.r)*amt;} +if(rgba.g!==max){rgba.g+=(max-rgba.g)*amt;} +if(rgba.b!==max){rgba.b+=(max-rgba.b)*amt;} +return rgba;});});Filter.register("greyscale",function(adjust){return this.process("greyscale",function(rgba){var avg;avg=Calculate.luminance(rgba);rgba.r=avg;rgba.g=avg;rgba.b=avg;return rgba;});});Filter.register("contrast",function(adjust){adjust=Math.pow((adjust+100)/100,2);return this.process("contrast",function(rgba){rgba.r/=255;rgba.r-=0.5;rgba.r*=adjust;rgba.r+=0.5;rgba.r*=255;rgba.g/=255;rgba.g-=0.5;rgba.g*=adjust;rgba.g+=0.5;rgba.g*=255;rgba.b/=255;rgba.b-=0.5;rgba.b*=adjust;rgba.b+=0.5;rgba.b*=255;return rgba;});});Filter.register("hue",function(adjust){return this.process("hue",function(rgba){var b,g,h,hsv,r,ref;hsv=Convert.rgbToHSV(rgba.r,rgba.g,rgba.b);h=hsv.h*100;h+=Math.abs(adjust);h=h%100;h/=100;hsv.h=h;ref=Convert.hsvToRGB(hsv.h,hsv.s,hsv.v),r=ref.r,g=ref.g,b=ref.b;rgba.r=r;rgba.g=g;rgba.b=b;return rgba;});});Filter.register("colorize",function(){var level,rgb;if(arguments.length===2){rgb=Convert.hexToRGB(arguments[0]);level=arguments[1];}else if(arguments.length===4){rgb={r:arguments[0],g:arguments[1],b:arguments[2]};level=arguments[3];} +return this.process("colorize",function(rgba){rgba.r-=(rgba.r-rgb.r)*(level/100);rgba.g-=(rgba.g-rgb.g)*(level/100);rgba.b-=(rgba.b-rgb.b)*(level/100);return rgba;});});Filter.register("invert",function(){return this.process("invert",function(rgba){rgba.r=255-rgba.r;rgba.g=255-rgba.g;rgba.b=255-rgba.b;return rgba;});});Filter.register("sepia",function(adjust){if(adjust==null){adjust=100;} +adjust/=100;return this.process("sepia",function(rgba){rgba.r=Math.min(255,(rgba.r*(1-(0.607*adjust)))+(rgba.g*(0.769*adjust))+(rgba.b*(0.189*adjust)));rgba.g=Math.min(255,(rgba.r*(0.349*adjust))+(rgba.g*(1-(0.314*adjust)))+(rgba.b*(0.168*adjust)));rgba.b=Math.min(255,(rgba.r*(0.272*adjust))+(rgba.g*(0.534*adjust))+(rgba.b*(1-(0.869*adjust))));return rgba;});});Filter.register("gamma",function(adjust){return this.process("gamma",function(rgba){rgba.r=Math.pow(rgba.r/255,adjust)*255;rgba.g=Math.pow(rgba.g/255,adjust)*255;rgba.b=Math.pow(rgba.b/255,adjust)*255;return rgba;});});Filter.register("noise",function(adjust){adjust=Math.abs(adjust)*2.55;return this.process("noise",function(rgba){var rand;rand=Calculate.randomRange(adjust*-1,adjust);rgba.r+=rand;rgba.g+=rand;rgba.b+=rand;return rgba;});});Filter.register("clip",function(adjust){adjust=Math.abs(adjust)*2.55;return this.process("clip",function(rgba){if(rgba.r>255-adjust){rgba.r=255;}else if(rgba.r255-adjust){rgba.g=255;}else if(rgba.g255-adjust){rgba.b=255;}else if(rgba.b0){rgba.r+=(255-rgba.r)*options.red;}else{rgba.r-=rgba.r*Math.abs(options.red);}} +if(options.green!=null){if(options.green>0){rgba.g+=(255-rgba.g)*options.green;}else{rgba.g-=rgba.g*Math.abs(options.green);}} +if(options.blue!=null){if(options.blue>0){rgba.b+=(255-rgba.b)*options.blue;}else{rgba.b-=rgba.b*Math.abs(options.blue);}} +return rgba;});});Filter.register("curves",function(){var algo,bezier,chans,cps,end,i,last,o,ref,ref1,start,u;chans=arguments[0],cps=2<=arguments.length?slice1.call(arguments,1):[];last=cps[cps.length-1];if(typeof last==="function"){algo=last;cps.pop();}else if(typeof last==="string"){algo=Calculate[last];cps.pop();}else{algo=Calculate.bezier;} +if(typeof chans==="string"){chans=chans.split("");} +if(chans[0]==="v"){chans=['r','g','b'];} +if(cps.length<2){throw"Invalid number of arguments to curves filter";} +bezier=algo(cps,0,255);start=cps[0];if(start[0]>0){for(i=o=0,ref=start[0];0<=ref?oref;i=0<=ref?++o:--o){bezier[i]=start[1];}} +end=cps[cps.length-1];if(end[0]<255){for(i=u=ref1=end[0];ref1<=255?u<=255:u>=255;i=ref1<=255?++u:--u){bezier[i]=end[1];}} +return this.process("curves",function(rgba){var ref2,w;for(i=w=0,ref2=chans.length;0<=ref2?wref2;i=0<=ref2?++w:--w){rgba[chans[i]]=bezier[rgba[chans[i]]];} +return rgba;});});Filter.register("exposure",function(adjust){var ctrl1,ctrl2,p;p=Math.abs(adjust)/100;ctrl1=[0,255*p];ctrl2=[255-(255*p),255];if(adjust<0){ctrl1=ctrl1.reverse();ctrl2=ctrl2.reverse();} +return this.curves('rgb',[0,0],ctrl1,ctrl2,[255,255]);});Caman.Plugin.register("crop",function(width,height,x,y){var canvas,ctx;if(x==null){x=0;} +if(y==null){y=0;} +if(typeof exports!=="undefined"&&exports!==null){canvas=new Canvas(width,height);}else{canvas=document.createElement('canvas');Util.copyAttributes(this.canvas,canvas);canvas.width=width;canvas.height=height;} +ctx=canvas.getContext('2d');ctx.drawImage(this.canvas,x,y,width,height,0,0,width,height);this.cropCoordinates={x:x,y:y};this.cropped=true;return this.replaceCanvas(canvas);});Caman.Plugin.register("resize",function(newDims){var canvas,ctx;if(newDims==null){newDims=null;} +if(newDims===null||((newDims.width==null)&&(newDims.height==null))){Log.error("Invalid or missing dimensions given for resize");return;} +if(newDims.width==null){newDims.width=this.canvas.width*newDims.height/this.canvas.height;}else if(newDims.height==null){newDims.height=this.canvas.height*newDims.width/this.canvas.width;} +if(typeof exports!=="undefined"&&exports!==null){canvas=new Canvas(newDims.width,newDims.height);}else{canvas=document.createElement('canvas');Util.copyAttributes(this.canvas,canvas);canvas.width=newDims.width;canvas.height=newDims.height;} +ctx=canvas.getContext('2d');ctx.drawImage(this.canvas,0,0,this.canvas.width,this.canvas.height,0,0,newDims.width,newDims.height);this.resized=true;return this.replaceCanvas(canvas);});Caman.Filter.register("crop",function(){return this.processPlugin("crop",Array.prototype.slice.call(arguments,0));});Caman.Filter.register("resize",function(){return this.processPlugin("resize",Array.prototype.slice.call(arguments,0));});Caman.Filter.register("boxBlur",function(){return this.processKernel("Box Blur",[1,1,1,1,1,1,1,1,1]);});Caman.Filter.register("heavyRadialBlur",function(){return this.processKernel("Heavy Radial Blur",[0,0,1,0,0,0,1,1,1,0,1,1,1,1,1,0,1,1,1,0,0,0,1,0,0]);});Caman.Filter.register("gaussianBlur",function(){return this.processKernel("Gaussian Blur",[1,4,6,4,1,4,16,24,16,4,6,24,36,24,6,4,16,24,16,4,1,4,6,4,1]);});Caman.Filter.register("motionBlur",function(degrees){var kernel;if(degrees===0||degrees===180){kernel=[0,0,1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,0,0];}else if((degrees>0&°rees<90)||(degrees>180&°rees<270)){kernel=[0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0];}else if(degrees===90||degrees===270){kernel=[0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0];}else{kernel=[1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1];} +return this.processKernel("Motion Blur",kernel);});Caman.Filter.register("sharpen",function(amt){if(amt==null){amt=100;} +amt/=100;return this.processKernel("Sharpen",[0,-amt,0,-amt,4*amt+1,-amt,0,-amt,0]);});vignetteFilters={brightness:function(rgba,amt,opts){rgba.r=rgba.r-(rgba.r*amt*opts.strength);rgba.g=rgba.g-(rgba.g*amt*opts.strength);rgba.b=rgba.b-(rgba.b*amt*opts.strength);return rgba;},gamma:function(rgba,amt,opts){rgba.r=Math.pow(rgba.r/255,Math.max(10*amt*opts.strength,1))*255;rgba.g=Math.pow(rgba.g/255,Math.max(10*amt*opts.strength,1))*255;rgba.b=Math.pow(rgba.b/255,Math.max(10*amt*opts.strength,1))*255;return rgba;},colorize:function(rgba,amt,opts){rgba.r-=(rgba.r-opts.color.r)*amt;rgba.g-=(rgba.g-opts.color.g)*amt;rgba.b-=(rgba.b-opts.color.b)*amt;return rgba;}};Filter.register("vignette",function(size,strength){var bezier,center,end,start;if(strength==null){strength=60;} +if(typeof size==="string"&&size.substr(-1)==="%"){if(this.dimensions.height>this.dimensions.width){size=this.dimensions.width*(parseInt(size.substr(0,size.length-1),10)/100);}else{size=this.dimensions.height*(parseInt(size.substr(0,size.length-1),10)/100);}} +strength/=100;center=[this.dimensions.width/2,this.dimensions.height/2];start=Math.sqrt(Math.pow(center[0],2)+Math.pow(center[1],2));end=start-size;bezier=Calculate.bezier([0,1],[30,30],[70,60],[100,80]);return this.process("vignette",function(rgba){var dist,div,loc;loc=rgba.locationXY();dist=Calculate.distance(loc.x,loc.y,center[0],center[1]);if(dist>end){div=Math.max(1,(bezier[Math.round(((dist-end)/size)*100)]/10)*strength);rgba.r=Math.pow(rgba.r/255,div)*255;rgba.g=Math.pow(rgba.g/255,div)*255;rgba.b=Math.pow(rgba.b/255,div)*255;} +return rgba;});});Filter.register("rectangularVignette",function(opts){var defaults,dim,len,o,percent,ref,size;defaults={strength:50,cornerRadius:0,method:'brightness',color:{r:0,g:0,b:0}};opts=Util.extend(defaults,opts);if(!opts.size){return this;}else if(typeof opts.size==="string"){percent=parseInt(opts.size,10)/100;opts.size={width:this.dimensions.width*percent,height:this.dimensions.height*percent};}else if(typeof opts.size==="object"){ref=["width","height"];for(o=0,len=ref.length;oopts.corners[0].x&&loc.xopts.coords.bottom&&loc.yopts.coords.left&&loc.xopts.corners[3].y&&loc.yopts.corners[0].x&&loc.xopts.coords.top){amt=(loc.y-opts.coords.top)/opts.maxDist;}else if(loc.y>opts.corners[2].y&&loc.yopts.coords.right){amt=(loc.x-opts.coords.right)/opts.maxDist;}else if(loc.x>opts.corners[0].x&&loc.xopts.corners[2].y&&loc.y=opts.corners[0].y){radialDist=Caman.distance(loc.x,loc.y,opts.corners[0].x,opts.corners[0].y);amt=(radialDist-opts.cornerRadius)/opts.maxDist;}else if(loc.x>=opts.corners[1].x&&loc.y>=opts.corners[1].y){radialDist=Caman.distance(loc.x,loc.y,opts.corners[1].x,opts.corners[1].y);amt=(radialDist-opts.cornerRadius)/opts.maxDist;}else if(loc.x>=opts.corners[2].x&&loc.y<=opts.corners[2].y){radialDist=Caman.distance(loc.x,loc.y,opts.corners[2].x,opts.corners[2].y);amt=(radialDist-opts.cornerRadius)/opts.maxDist;}else if(loc.x<=opts.corners[3].x&&loc.y<=opts.corners[3].y){radialDist=Caman.distance(loc.x,loc.y,opts.corners[3].x,opts.corners[3].y);amt=(radialDist-opts.cornerRadius)/opts.maxDist;} +if(amt<0){return rgba;} +return vignetteFilters[opts.method](rgba,amt,opts);});});(function(){var BlurStack,getLinearGradientMap,getRadialGradientMap,mul_table,shg_table;mul_table=[512,512,456,512,328,456,335,512,405,328,271,456,388,335,292,512,454,405,364,328,298,271,496,456,420,388,360,335,312,292,273,512,482,454,428,405,383,364,345,328,312,298,284,271,259,496,475,456,437,420,404,388,374,360,347,335,323,312,302,292,282,273,265,512,497,482,468,454,441,428,417,405,394,383,373,364,354,345,337,328,320,312,305,298,291,284,278,271,265,259,507,496,485,475,465,456,446,437,428,420,412,404,396,388,381,374,367,360,354,347,341,335,329,323,318,312,307,302,297,292,287,282,278,273,269,265,261,512,505,497,489,482,475,468,461,454,447,441,435,428,422,417,411,405,399,394,389,383,378,373,368,364,359,354,350,345,341,337,332,328,324,320,316,312,309,305,301,298,294,291,287,284,281,278,274,271,268,265,262,259,257,507,501,496,491,485,480,475,470,465,460,456,451,446,442,437,433,428,424,420,416,412,408,404,400,396,392,388,385,381,377,374,370,367,363,360,357,354,350,347,344,341,338,335,332,329,326,323,320,318,315,312,310,307,304,302,299,297,294,292,289,287,285,282,280,278,275,273,271,269,267,265,263,261,259];shg_table=[9,11,12,13,13,14,14,15,15,15,15,16,16,16,16,17,17,17,17,17,17,17,18,18,18,18,18,18,18,18,18,19,19,19,19,19,19,19,19,19,19,19,19,19,19,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24];getLinearGradientMap=function(width,height,centerX,centerY,angle,length,mirrored){var cnv,context,gradient,x1,x2,y1,y2;cnv=typeof exports!=="undefined"&&exports!==null?new Canvas():document.createElement('canvas');cnv.width=width;cnv.height=height;x1=centerX+Math.cos(angle)*length*0.5;y1=centerY+Math.sin(angle)*length*0.5;x2=centerX-Math.cos(angle)*length*0.5;y2=centerY-Math.sin(angle)*length*0.5;context=cnv.getContext("2d");gradient=context.createLinearGradient(x1,y1,x2,y2);if(!mirrored){gradient.addColorStop(0,"white");gradient.addColorStop(1,"black");}else{gradient.addColorStop(0,"white");gradient.addColorStop(0.5,"black");gradient.addColorStop(1,"white");} +context.fillStyle=gradient;context.fillRect(0,0,width,height);return context.getImageData(0,0,width,height);};getRadialGradientMap=function(width,height,centerX,centerY,radius1,radius2){var cnv,context,gradient;cnv=typeof exports!=="undefined"&&exports!==null?new Canvas():document.createElement('canvas');cnv.width=width;cnv.height=height;context=cnv.getContext("2d");gradient=context.createRadialGradient(centerX,centerY,radius1,centerX,centerY,radius2);gradient.addColorStop(1,"white");gradient.addColorStop(0,"black");context.fillStyle=gradient;context.fillRect(0,0,width,height);return context.getImageData(0,0,width,height);};BlurStack=function(){this.r=0;this.g=0;this.b=0;this.a=0;return this.next=null;};Caman.Plugin.register("compoundBlur",function(radiusData,radius,increaseFactor,blurLevels){var aa,ab,ac,ad,ae,af,ag,b_in_sum,b_out_sum,b_sum,blend,currentIndex,div,g_in_sum,g_out_sum,g_sum,height,heightMinus1,i,iblend,idx,imagePixels,index,iradius,lookupValue,mul_sum,o,p,pb,pg,pixels,pr,r_in_sum,r_out_sum,r_sum,radiusPixels,radiusPlus1,rbs,ref,ref1,ref2,ref3,ref4,ref5,ref6,ref7,ref8,ref9,shg_sum,stack,stackEnd,stackIn,stackOut,stackStart,steps,sumFactor,u,w,w4,wh,wh4,width,widthMinus1,x,y,yi,yp,yw;width=this.dimensions.width;height=this.dimensions.height;imagePixels=this.pixelData;radiusPixels=radiusData.data;wh=width*height;wh4=wh<<2;pixels=[];for(i=o=0,ref=wh4;0<=ref?oref;i=0<=ref?++o:--o){pixels[i]=imagePixels[i];} +currentIndex=0;steps=blurLevels;blurLevels-=1;while(steps-->=0){iradius=(radius+0.5)|0;if(iradius===0){continue;} +if(iradius>256){iradius=256;} +div=iradius+iradius+1;w4=width<<2;widthMinus1=width-1;heightMinus1=height-1;radiusPlus1=iradius+1;sumFactor=radiusPlus1*(radiusPlus1+1)/2;stackStart=new BlurStack();stackEnd=void 0;stack=stackStart;for(i=u=1,ref1=div;1<=ref1?uref1;i=1<=ref1?++u:--u){stack=stack.next=new BlurStack();if(i===radiusPlus1){stackEnd=stack;}} +stack.next=stackStart;stackIn=null;stackOut=null;yw=yi=0;mul_sum=mul_table[iradius];shg_sum=shg_table[iradius];for(y=w=0,ref2=height;0<=ref2?wref2;y=0<=ref2?++w:--w){r_in_sum=g_in_sum=b_in_sum=r_sum=g_sum=b_sum=0;r_out_sum=radiusPlus1*(pr=pixels[yi]);g_out_sum=radiusPlus1*(pg=pixels[yi+1]);b_out_sum=radiusPlus1*(pb=pixels[yi+2]);r_sum+=sumFactor*pr;g_sum+=sumFactor*pg;b_sum+=sumFactor*pb;stack=stackStart;for(i=aa=0,ref3=radiusPlus1;0<=ref3?aaref3;i=0<=ref3?++aa:--aa){stack.r=pr;stack.g=pg;stack.b=pb;stack=stack.next;} +for(i=ab=1,ref4=radiusPlus1;1<=ref4?abref4;i=1<=ref4?++ab:--ab){p=yi+((widthMinus1ref5;x=0<=ref5?++ac:--ac){pixels[yi]=(r_sum*mul_sum)>>shg_sum;pixels[yi+1]=(g_sum*mul_sum)>>shg_sum;pixels[yi+2]=(b_sum*mul_sum)>>shg_sum;r_sum-=r_out_sum;g_sum-=g_out_sum;b_sum-=b_out_sum;r_out_sum-=stackIn.r;g_out_sum-=stackIn.g;b_out_sum-=stackIn.b;p=(yw+((p=x+radiusPlus1)ref6;x=0<=ref6?++ad:--ad){g_in_sum=b_in_sum=r_in_sum=g_sum=b_sum=r_sum=0;yi=x<<2;r_out_sum=radiusPlus1*(pr=pixels[yi]);g_out_sum=radiusPlus1*(pg=pixels[yi+1]);b_out_sum=radiusPlus1*(pb=pixels[yi+2]);r_sum+=sumFactor*pr;g_sum+=sumFactor*pg;b_sum+=sumFactor*pb;stack=stackStart;for(i=ae=0,ref7=radiusPlus1;0<=ref7?aeref7;i=0<=ref7?++ae:--ae){stack.r=pr;stack.g=pg;stack.b=pb;stack=stack.next;} +yp=width;for(i=af=1,ref8=radiusPlus1;1<=ref8?afref8;i=1<=ref8?++af:--af){yi=(yp+x)<<2;r_sum+=(stack.r=(pr=pixels[yi]))*(rbs=radiusPlus1-i);g_sum+=(stack.g=(pg=pixels[yi+1]))*rbs;b_sum+=(stack.b=(pb=pixels[yi+2]))*rbs;r_in_sum+=pr;g_in_sum+=pg;b_in_sum+=pb;stack=stack.next;if(iref9;y=0<=ref9?++ag:--ag){p=yi<<2;pixels[p]=(r_sum*mul_sum)>>shg_sum;pixels[p+1]=(g_sum*mul_sum)>>shg_sum;pixels[p+2]=(b_sum*mul_sum)>>shg_sum;r_sum-=r_out_sum;g_sum-=g_out_sum;b_sum-=b_out_sum;r_out_sum-=stackIn.r;g_out_sum-=stackIn.g;b_out_sum-=stackIn.b;p=(x+(((p=y+radiusPlus1)-1){idx=i<<2;lookupValue=(radiusPixels[idx+2]&0xff)/255.0*blurLevels;index=lookupValue|0;if(index===currentIndex){blend=256.0*(lookupValue-(lookupValue|0));iblend=256-blend;imagePixels[idx]=(imagePixels[idx]*iblend+pixels[idx]*blend)>>8;imagePixels[idx+1]=(imagePixels[idx+1]*iblend+pixels[idx+1]*blend)>>8;imagePixels[idx+2]=(imagePixels[idx+2]*iblend+pixels[idx+2]*blend)>>8;}else if(index===currentIndex+1){imagePixels[idx]=pixels[idx];imagePixels[idx+1]=pixels[idx+1];imagePixels[idx+2]=pixels[idx+2];}} +currentIndex++;} +return this;});Caman.Filter.register("tiltShift",function(opts){var defaults,gradient;defaults={center:{x:this.dimensions.width/2,y:this.dimensions.height/2},angle:45,focusWidth:200,startRadius:3,radiusFactor:1.5,steps:3};opts=Util.extend(defaults,opts);opts.angle*=Math.PI/180;gradient=getLinearGradientMap(this.dimensions.width,this.dimensions.height,opts.center.x,opts.center.y,opts.angle,opts.focusWidth,true);return this.processPlugin("compoundBlur",[gradient,opts.startRadius,opts.radiusFactor,opts.steps]);});return Caman.Filter.register("radialBlur",function(opts){var defaults,gradient,radius1,radius2;defaults={size:50,center:{x:this.dimensions.width/2,y:this.dimensions.height/2},startRadius:3,radiusFactor:1.5,steps:3,radius:null};opts=Util.extend(defaults,opts);if(!opts.radius){opts.radius=this.dimensions.widthref;i=1<=ref?++o:--o){stack=stack.next=new BlurStack();if(i===radiusPlus1){stackEnd=stack;}} +stack.next=stackStart;stackIn=null;stackOut=null;yw=yi=0;mul_sum=mul_table[radius];shg_sum=shg_table[radius];for(y=u=0,ref1=height;0<=ref1?uref1;y=0<=ref1?++u:--u){r_in_sum=g_in_sum=b_in_sum=r_sum=g_sum=b_sum=0;r_out_sum=radiusPlus1*(pr=pixels[yi]);g_out_sum=radiusPlus1*(pg=pixels[yi+1]);b_out_sum=radiusPlus1*(pb=pixels[yi+2]);r_sum+=sumFactor*pr;g_sum+=sumFactor*pg;b_sum+=sumFactor*pb;stack=stackStart;for(i=w=0,ref2=radiusPlus1;0<=ref2?wref2;i=0<=ref2?++w:--w){stack.r=pr;stack.g=pg;stack.b=pb;stack=stack.next;} +for(i=aa=1,ref3=radiusPlus1;1<=ref3?aaref3;i=1<=ref3?++aa:--aa){p=yi+((widthMinus1ref4;x=0<=ref4?++ab:--ab){pixels[yi]=(r_sum*mul_sum)>>shg_sum;pixels[yi+1]=(g_sum*mul_sum)>>shg_sum;pixels[yi+2]=(b_sum*mul_sum)>>shg_sum;r_sum-=r_out_sum;g_sum-=g_out_sum;b_sum-=b_out_sum;r_out_sum-=stackIn.r;g_out_sum-=stackIn.g;b_out_sum-=stackIn.b;p=(yw+((p=x+radius+1)ref5;x=0<=ref5?++ac:--ac){g_in_sum=b_in_sum=r_in_sum=g_sum=b_sum=r_sum=0;yi=x<<2;r_out_sum=radiusPlus1*(pr=pixels[yi]);g_out_sum=radiusPlus1*(pg=pixels[yi+1]);b_out_sum=radiusPlus1*(pb=pixels[yi+2]);r_sum+=sumFactor*pr;g_sum+=sumFactor*pg;b_sum+=sumFactor*pb;stack=stackStart;for(i=ad=0,ref6=radiusPlus1;0<=ref6?adref6;i=0<=ref6?++ad:--ad){stack.r=pr;stack.g=pg;stack.b=pb;stack=stack.next;} +yp=width;for(i=ae=1,ref7=radius;1<=ref7?ae<=ref7:ae>=ref7;i=1<=ref7?++ae:--ae){yi=(yp+x)<<2;r_sum+=(stack.r=(pr=pixels[yi]))*(rbs=radiusPlus1-i);g_sum+=(stack.g=(pg=pixels[yi+1]))*rbs;b_sum+=(stack.b=(pb=pixels[yi+2]))*rbs;r_in_sum+=pr;g_in_sum+=pg;b_in_sum+=pb;stack=stack.next;if(iref8;y=0<=ref8?++af:--af){p=yi<<2;pixels[p]=(r_sum*mul_sum)>>shg_sum;pixels[p+1]=(g_sum*mul_sum)>>shg_sum;pixels[p+2]=(b_sum*mul_sum)>>shg_sum;r_sum-=r_out_sum;g_sum-=g_out_sum;b_sum-=b_out_sum;r_out_sum-=stackIn.r;g_out_sum-=stackIn.g;b_out_sum-=stackIn.b;p=(x+(((p=y+radiusPlus1)a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(n.isPlainObject(d)||(e=n.isArray(d)))?(e?(e=!1,f=c&&n.isArray(c)?c:[]):f=c&&n.isPlainObject(c)?c:{},g[b]=n.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){return!n.isArray(a)&&a-parseFloat(a)+1>=0},isPlainObject:function(a){return"object"!==n.type(a)||a.nodeType||n.isWindow(a)?!1:a.constructor&&!j.call(a.constructor.prototype,"isPrototypeOf")?!1:!0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=n.trim(a),a&&(1===a.indexOf("use strict")?(b=l.createElement("script"),b.text=a,l.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:g.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(c=a[b],b=a,a=c),n.isFunction(a)?(e=d.call(arguments,2),f=function(){return a.apply(b||this,e.concat(d.call(arguments)))},f.guid=a.guid=a.guid||n.guid++,f):void 0},now:Date.now,support:k}),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b="length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N=M.replace("w","w#"),O="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+N+"))|)"+L+"*\\]",P=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+O+")*)|.*)\\)|)",Q=new RegExp(L+"+","g"),R=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),S=new RegExp("^"+L+"*,"+L+"*"),T=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),U=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),V=new RegExp(P),W=new RegExp("^"+N+"$"),X={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+O),PSEUDO:new RegExp("^"+P),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,aa=/[+~]/,ba=/'|\\/g,ca=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),da=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ea=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(fa){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],k=b.nodeType,"string"!=typeof a||!a||1!==k&&9!==k&&11!==k)return d;if(!e&&p){if(11!==k&&(f=_.exec(a)))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return H.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName)return H.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=1!==k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(ba,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+ra(o[l]);w=aa.test(a)&&pa(b.parentNode)||b,x=o.join(",")}if(x)try{return H.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function pa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=g.documentElement,e=g.defaultView,e&&e!==e.top&&(e.addEventListener?e.addEventListener("unload",ea,!1):e.attachEvent&&e.attachEvent("onunload",ea)),p=!f(g),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(g.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(g.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!g.getElementsByName||!g.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(g.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){var b=g.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",P)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===g||a.ownerDocument===v&&t(v,a)?-1:b===g||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,h=[a],i=[b];if(!e||!f)return a===g?-1:b===g?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?la(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},g):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ca,da),a[3]=(a[3]||a[4]||a[5]||"").replace(ca,da),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ca,da).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(Q," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(ca,da),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return W.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(ca,da).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:oa(function(){return[0]}),last:oa(function(a,b){return[b-1]}),eq:oa(function(a,b,c){return[0>c?c+b:c]}),even:oa(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:oa(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:oa(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:oa(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function sa(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function ta(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ua(a,b,c){for(var d=0,e=b.length;e>d;d++)ga(a,b[d],c);return c}function va(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function wa(a,b,c,d,e,f){return d&&!d[u]&&(d=wa(d)),e&&!e[u]&&(e=wa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ua(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:va(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=va(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=va(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function xa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=sa(function(a){return a===b},h,!0),l=sa(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[sa(ta(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return wa(i>1&&ta(m),i>1&&ra(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&xa(a.slice(i,e)),f>e&&xa(a=a.slice(e)),f>e&&ra(a))}m.push(c)}return ta(m)}function ya(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=F.call(i));s=va(s)}H.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&ga.uniqueSort(i)}return k&&(w=v,j=t),r};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=xa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,ya(e,d)),f.selector=a}return f},i=ga.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ca,da),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ca,da),aa.test(j[0].type)&&pa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&ra(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,aa.test(a)&&pa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ja(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return g.call(b,a)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;c>b;b++)if(n.contains(e[b],this))return!0}));for(b=0;c>b;b++)n.find(a,e[b],d);return d=this.pushStack(c>1?n.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:l,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}return d=l.getElementById(c[2]),d&&d.parentNode&&(this.length=1,this[0]=d),this.context=l,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};A.prototype=n.fn,y=n(l);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b=n(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(n.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?"string"==typeof a?g.call(n(a),this[0]):g.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){while((a=a[b])&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return a.contentDocument||n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(C[a]||n.unique(e),B.test(a)&&e.reverse()),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return n.each(a.match(E)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(b=a.memory&&l,c=!0,g=e||0,e=0,f=h.length,d=!0;h&&f>g;g++)if(h[g].apply(l[0],l[1])===!1&&a.stopOnFalse){b=!1;break}d=!1,h&&(i?i.length&&j(i.shift()):b?h=[]:k.disable())},k={add:function(){if(h){var c=h.length;!function g(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this},remove:function(){return h&&n.each(arguments,function(a,b){var c;while((c=n.inArray(b,h,c))>-1)h.splice(c,1),d&&(f>=c&&f--,g>=c&&g--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],f=0,this},disable:function(){return h=i=b=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,b||k.disable(),this},locked:function(){return!i},fireWith:function(a,b){return!h||c&&!i||(b=b||[],b=[a,b.slice?b.slice():b],d?i.push(b):j(b)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!c}};return k},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(H.resolveWith(l,[n]),n.fn.triggerHandler&&(n(l).triggerHandler("ready"),n(l).off("ready"))))}});function I(){l.removeEventListener("DOMContentLoaded",I,!1),a.removeEventListener("load",I,!1),n.ready()}n.ready.promise=function(b){return H||(H=n.Deferred(),"complete"===l.readyState?setTimeout(n.ready):(l.addEventListener("DOMContentLoaded",I,!1),a.addEventListener("load",I,!1))),H.promise(b)},n.ready.promise();var J=n.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)n.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f};n.acceptData=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function K(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=n.expando+K.uid++}K.uid=1,K.accepts=n.acceptData,K.prototype={key:function(a){if(!K.accepts(a))return 0;var b={},c=a[this.expando];if(!c){c=K.uid++;try{b[this.expando]={value:c},Object.defineProperties(a,b)}catch(d){b[this.expando]=c,n.extend(a,b)}}return this.cache[c]||(this.cache[c]={}),c},set:function(a,b,c){var d,e=this.key(a),f=this.cache[e];if("string"==typeof b)f[b]=c;else if(n.isEmptyObject(f))n.extend(this.cache[e],b);else for(d in b)f[d]=b[d];return f},get:function(a,b){var c=this.cache[this.key(a)];return void 0===b?c:c[b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,n.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=this.key(a),g=this.cache[f];if(void 0===b)this.cache[f]={};else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in g?d=[b,e]:(d=e,d=d in g?[d]:d.match(E)||[])),c=d.length;while(c--)delete g[d[c]]}},hasData:function(a){return!n.isEmptyObject(this.cache[a[this.expando]]||{})},discard:function(a){a[this.expando]&&delete this.cache[a[this.expando]]}};var L=new K,M=new K,N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(O,"-$1").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}M.set(a,b,c)}else c=void 0;return c}n.extend({hasData:function(a){return M.hasData(a)||L.hasData(a)},data:function(a,b,c){ +return M.access(a,b,c)},removeData:function(a,b){M.remove(a,b)},_data:function(a,b,c){return L.access(a,b,c)},_removeData:function(a,b){L.remove(a,b)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=M.get(f),1===f.nodeType&&!L.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));L.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){M.set(this,a)}):J(this,function(b){var c,d=n.camelCase(a);if(f&&void 0===b){if(c=M.get(f,a),void 0!==c)return c;if(c=M.get(f,d),void 0!==c)return c;if(c=P(f,d,void 0),void 0!==c)return c}else this.each(function(){var c=M.get(this,d);M.set(this,d,b),-1!==a.indexOf("-")&&void 0!==c&&M.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){M.remove(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=L.get(a,b),c&&(!d||n.isArray(c)?d=L.access(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return L.get(a,c)||L.access(a,c,{empty:n.Callbacks("once memory").add(function(){L.remove(a,[b+"queue",c])})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthx",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var U="undefined";k.focusinBubbles="onfocusin"in a;var V=/^key/,W=/^(?:mouse|pointer|contextmenu)|click/,X=/^(?:focusinfocus|focusoutblur)$/,Y=/^([^.]*)(?:\.(.+)|)$/;function Z(){return!0}function $(){return!1}function _(){try{return l.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=n.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return typeof n!==U&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(E)||[""],j=b.length;while(j--)h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o&&(l=n.event.special[o]||{},o=(e?l.delegateType:l.bindType)||o,l=n.event.special[o]||{},k=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[o])||(m=i[o]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(o,g,!1)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),n.event.global[o]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.hasData(a)&&L.get(a);if(r&&(i=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=i[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete i[o])}else for(o in i)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(i)&&(delete r.handle,L.remove(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,m,o,p=[d||l],q=j.call(b,"type")?b.type:b,r=j.call(b,"namespace")?b.namespace.split("."):[];if(g=h=d=d||l,3!==d.nodeType&&8!==d.nodeType&&!X.test(q+n.event.triggered)&&(q.indexOf(".")>=0&&(r=q.split("."),q=r.shift(),r.sort()),k=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=r.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),o=n.event.special[q]||{},e||!o.trigger||o.trigger.apply(d,c)!==!1)){if(!e&&!o.noBubble&&!n.isWindow(d)){for(i=o.delegateType||q,X.test(i+q)||(g=g.parentNode);g;g=g.parentNode)p.push(g),h=g;h===(d.ownerDocument||l)&&p.push(h.defaultView||h.parentWindow||a)}f=0;while((g=p[f++])&&!b.isPropagationStopped())b.type=f>1?i:o.bindType||q,m=(L.get(g,"events")||{})[b.type]&&L.get(g,"handle"),m&&m.apply(g,c),m=k&&g[k],m&&m.apply&&n.acceptData(g)&&(b.result=m.apply(g,c),b.result===!1&&b.preventDefault());return b.type=q,e||b.isDefaultPrevented()||o._default&&o._default.apply(p.pop(),c)!==!1||!n.acceptData(d)||k&&n.isFunction(d[q])&&!n.isWindow(d)&&(h=d[k],h&&(d[k]=null),n.event.triggered=q,d[q](),n.event.triggered=void 0,h&&(d[k]=h)),b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(L.get(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(g.namespace))&&(a.handleObj=g,a.data=g.data,e=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(a.result=e)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!==this;i=i.parentNode||this)if(i.disabled!==!0||"click"!==a.type){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>=0:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h]*)\/>/gi,ba=/<([\w:]+)/,ca=/<|&#?\w+;/,da=/<(?:script|style|link)/i,ea=/checked\s*(?:[^=]|=\s*.checked.)/i,fa=/^$|\/(?:java|ecma)script/i,ga=/^true\/(.*)/,ha=/^\s*\s*$/g,ia={option:[1,""],thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};ia.optgroup=ia.option,ia.tbody=ia.tfoot=ia.colgroup=ia.caption=ia.thead,ia.th=ia.td;function ja(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function ka(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function la(a){var b=ga.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function ma(a,b){for(var c=0,d=a.length;d>c;c++)L.set(a[c],"globalEval",!b||L.get(b[c],"globalEval"))}function na(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(L.hasData(a)&&(f=L.access(a),g=L.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)n.event.add(b,e,j[e][c])}M.hasData(a)&&(h=M.access(a),i=n.extend({},h),M.set(b,i))}}function oa(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||"*"):a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function pa(a,b){var c=b.nodeName.toLowerCase();"input"===c&&T.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}n.extend({clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=oa(h),f=oa(a),d=0,e=f.length;e>d;d++)pa(f[d],g[d]);if(b)if(c)for(f=f||oa(a),g=g||oa(h),d=0,e=f.length;e>d;d++)na(f[d],g[d]);else na(a,h);return g=oa(h,"script"),g.length>0&&ma(g,!i&&oa(a,"script")),h},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k=b.createDocumentFragment(),l=[],m=0,o=a.length;o>m;m++)if(e=a[m],e||0===e)if("object"===n.type(e))n.merge(l,e.nodeType?[e]:e);else if(ca.test(e)){f=f||k.appendChild(b.createElement("div")),g=(ba.exec(e)||["",""])[1].toLowerCase(),h=ia[g]||ia._default,f.innerHTML=h[1]+e.replace(aa,"<$1>")+h[2],j=h[0];while(j--)f=f.lastChild;n.merge(l,f.childNodes),f=k.firstChild,f.textContent=""}else l.push(b.createTextNode(e));k.textContent="",m=0;while(e=l[m++])if((!d||-1===n.inArray(e,d))&&(i=n.contains(e.ownerDocument,e),f=oa(k.appendChild(e),"script"),i&&ma(f),c)){j=0;while(e=f[j++])fa.test(e.type||"")&&c.push(e)}return k},cleanData:function(a){for(var b,c,d,e,f=n.event.special,g=0;void 0!==(c=a[g]);g++){if(n.acceptData(c)&&(e=c[L.expando],e&&(b=L.cache[e]))){if(b.events)for(d in b.events)f[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);L.cache[e]&&delete L.cache[e]}delete M.cache[c[M.expando]]}}}),n.fn.extend({text:function(a){return J(this,function(a){return void 0===a?n.text(this):this.empty().each(function(){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&(this.textContent=a)})},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=ja(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=ja(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(oa(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&ma(oa(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(n.cleanData(oa(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return J(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!da.test(a)&&!ia[(ba.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(aa,"<$1>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(oa(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(oa(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,m=this,o=l-1,p=a[0],q=n.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&ea.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(c=n.buildFragment(a,this[0].ownerDocument,!1,this),d=c.firstChild,1===c.childNodes.length&&(c=d),d)){for(f=n.map(oa(c,"script"),ka),g=f.length;l>j;j++)h=c,j!==o&&(h=n.clone(h,!0,!0),g&&n.merge(f,oa(h,"script"))),b.call(this[j],h,j);if(g)for(i=f[f.length-1].ownerDocument,n.map(f,la),j=0;g>j;j++)h=f[j],fa.test(h.type||"")&&!L.access(h,"globalEval")&&n.contains(i,h)&&(h.src?n._evalUrl&&n._evalUrl(h.src):n.globalEval(h.textContent.replace(ha,"")))}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=[],e=n(a),g=e.length-1,h=0;g>=h;h++)c=h===g?this:this.clone(!0),n(e[h])[b](c),f.apply(d,c.get());return this.pushStack(d)}});var qa,ra={};function sa(b,c){var d,e=n(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:n.css(e[0],"display");return e.detach(),f}function ta(a){var b=l,c=ra[a];return c||(c=sa(a,b),"none"!==c&&c||(qa=(qa||n(""),g=["lang","theme","type","dir"];b.extend(true,h,d);c=h.url;c+=(c.indexOf("?")===-1)?"?":"&";for(f in g){f=g[f];if(h[f].length){c+=f+"="+encodeURIComponent(h[f])+"&"}}c=c.substr(0,c.length-1);j.css({margin:0,padding:0,width:b(e).innerWidth(),height:b(e).innerHeight(),border:"none"}).attr({src:c});b(e).html(j);if(b.isFunction(h.callback)||b.isFunction(h.callbackMultiple)){if(!window.KCFinder){window.KCFinder={}}if(b.isFunction(h.callback)){window.KCFinder.callBack=h.callback}else{if(window.KCFinder&&window.KCFinder.callback){delete window.KCFinder.callback}}if(b.isFunction(h.callbackMultiple)){window.KCFinder.callBackMultiple=h.callbackMultiple}else{if(window.KCFinder&&window.KCFinder.callbackMultiple){delete window.KCFinder.callbackMultiple}}}else{if(window.KCFinder){delete window.KCFinder}}}})(jQuery); \ No newline at end of file diff --git a/lib/kcfinder/adapters/jquery.js b/lib/kcfinder/adapters/jquery.js new file mode 100644 index 0000000..1fbd2f0 --- /dev/null +++ b/lib/kcfinder/adapters/jquery.js @@ -0,0 +1,82 @@ +/*! jQuery adapter for KCFinder + * http://kcfinder.sunhater.com + * Pavel Tzonkov + */ +/* BASE USAGE: + *
    + * + */ + +(function($) { + var defaultURL = "browse.php"; // Define here your default URL to KCFinder + + $.fn.kcfinder = function(options) { + + var url, i, + t = $(this).get(0), + + // Default options + o = { + url: defaultURL, + lang: "", + theme: "", + type: "", + dir: "", + callback: false, + callbackMultiple: false + }, + ifr = $(''), + + // GET parameters to parse URL + parse = ['lang', 'theme', 'type', 'dir']; + + $.extend(true, o, options); + + // Parse URL + url = o.url; + url += (url.indexOf('?') === -1) ? '?' : "&"; + for (i in parse) { + i = parse[i]; + if (o[i].length) + url += i + "=" + encodeURIComponent(o[i]) + "&"; + } + url = url.substr(0, url.length - 1); + + // Iframe setup + ifr.css({ + margin: 0, + padding: 0, + width: $(t).innerWidth(), + height: $(t).innerHeight(), + border: "none" + }).attr({ + src: url + }); + + $(t).html(ifr); + + // Callbacks + if ($.isFunction(o.callback) || $.isFunction(o.callbackMultiple)) { + if (!window.KCFinder) + window.KCFinder = {}; + + // Single file callback + if ($.isFunction(o.callback)) + window.KCFinder.callBack = o.callback; + else if (window.KCFinder && window.KCFinder.callback) + delete window.KCFinder.callback; + + // Multiple files callback + if ($.isFunction(o.callbackMultiple)) + window.KCFinder.callBackMultiple = o.callbackMultiple; + else if (window.KCFinder && window.KCFinder.callbackMultiple) + delete window.KCFinder.callbackMultiple; + + // No callbacks + } else if (window.KCFinder) + delete window.KCFinder; + } + +})(jQuery); \ No newline at end of file diff --git a/lib/kcfinder/browse.php b/lib/kcfinder/browse.php new file mode 100644 index 0000000..7f1f815 --- /dev/null +++ b/lib/kcfinder/browse.php @@ -0,0 +1,18 @@ + + * @copyright 2010-2014 KCFinder Project + * @license http://opensource.org/licenses/GPL-3.0 GPLv3 + * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3 + * @link http://kcfinder.sunhater.com + */ + +require "core/bootstrap.php"; +$browser = "kcfinder\\browser"; // To execute core/bootstrap.php on older +$browser = new $browser(); // PHP versions (even PHP 4) +$browser->action(); diff --git a/lib/kcfinder/cache/.htaccess b/lib/kcfinder/cache/.htaccess new file mode 100644 index 0000000..d61b264 --- /dev/null +++ b/lib/kcfinder/cache/.htaccess @@ -0,0 +1,4 @@ + +Order allow,deny +Deny from all + diff --git a/lib/kcfinder/cache/base.css b/lib/kcfinder/cache/base.css new file mode 100644 index 0000000..bcf481a --- /dev/null +++ b/lib/kcfinder/cache/base.css @@ -0,0 +1,300 @@ +html, body { + overflow: hidden; +} + +body, form, th, td { + margin: 0; + padding: 0; +} + +a { + cursor: pointer; +} + +* { + font-family: Tahoma, Verdana, Arial, sans-serif; + font-size: 11px; +} + +table { + border-collapse: collapse; +} + +#left { + float: left; + display: block; + width: 25%; +} + +#right { + float: left; + display: block; + width: 75%; +} + +#settings { + display: none; + padding: 0; + float: left; + width: 100%; +} + +#settings > div { + float: left; +} + +#folders { + padding: 5px; + overflow: auto; +} + +#toolbar { + padding: 5px; +} + +#files { + padding: 5px; + overflow: auto; +} + +#status { + padding: 5px; + float: left; + overflow: hidden; +} + +#fileinfo { + float: left; +} + +#clipboard div { + width: 16px; + height: 16px; +} + +.folders { + margin-left: 16px; +} + +div.file { + overflow-x: hidden; + float: left; + text-align: center; + cursor: default; + white-space: nowrap; +} + +div.file .thumb { + background: no-repeat center center; +} + +#files table { + width: 100%; +} + +tr.file { + cursor: default; +} + +tr.file > td { + white-space: nowrap; +} + +tr.file > td.name { + background-repeat: no-repeat; + background-position: left center; + padding-left: 20px; + width: 100%; +} + +tr.file > td.time, +tr.file > td.size { + text-align: right; +} + +#toolbar { + cursor: default; + white-space: nowrap; +} + +#toolbar a { + padding-left: 20px; + text-decoration: none; + background: no-repeat left center; +} + +#toolbar a:hover, a[href="#upload"].uploadHover { + color: #000; +} + +#upload { + position: absolute; + overflow: hidden; + opacity: 0; + filter: alpha(opacity=0); +} +#upload input, #upload input::-webkit-file-upload-button { + cursor: pointer; +} + +span.brace { + padding-left: 11px; + cursor: default; +} + +span.brace.opened, span.brace.closed { + cursor: pointer; +} + +#menu, #clipboard { + position: absolute; + display: none; + z-index: 101; + cursor: default; +} + +#menu .box, #alert { + max-width: 350px; +} + +#clipboard { + z-index: 99; +} + +#loading { + display: none; + float: right; +} + +.menu { + background: #888; + white-space: nowrap; +} + +.menu a { + display: block; +} + +.menu .list { + max-height: 0; + overflow-y: auto; + overflow-x: hidden; + white-space: nowrap; +} + +#uploadResponse, +.file .access, +.file .hasThumb { + display: none; +} + +#resizer { + position: absolute; + z-index: 98; + top: 0; + background: #000; + opacity: 0; + filter: alpha(opacity=0); +} + +#lang { + opacity: 0; + filter: alpha(opacity=0); +}.tf-select, .tf-multiple, .tf-file, .tf-radio, .tf-checkbox, .tf-button { + cursor: default; + overflow: auto; + display: -moz-inline-box; + display: inline-block; + zoom: 1; + vertical-align: middle; +} + +.tf-select .tf-selected { + float: left; + white-space: nowrap; +} + +.tf-select .tf-menu { + display: none; + position: absolute; + max-height: 173px; + overflow-x: hidden; + overflow-y: auto; +} + +.tf-select.tf-opened .tf-menu { + display: block; +} + +.tf-select .tf-button { + float: right; +} + +.tf-select select, +.tf-multiple select { + position: absolute; + left: -1000000px; + opacity: 0; + filter: alpha(opacity=0); +} + +.tf-select .tf-menu ul, +.tf-multiple ul { + padding: 0; + margin: 0; + list-style-type: none; +} + +.tf-select .tf-menu li, +.tf-multiple li { + padding: 0; + margin: 0; +} + +.tf-multiple span, +.tf-select .tf-button span { + white-space: nowrap; +} + +.tf-textarea { + resize: none; + overflow: auto; +} + +.tf-multiple { + max-height: 118px; +} +.tf-file input, +.tf-radio input, +.tf-checkbox input, +.tf-button input, +.tf-button button { + position: absolute; + opacity: 0; + filter: alpha(opacity=0); + outline: none; + margin: 0; + padding: 0; +} +.tf-file { + overflow: hidden; +} +.tf-file .tf-info { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + float: right; +} +.tf-file .tf-button { + float: right; +} +body.mobile { + -webkit-touch-callout: none; + -webkit-user-select: none; + -moz-user-select: none; +} + +body.firefox #files > div { + overflow: auto; + margin-bottom: 5px; +} \ No newline at end of file diff --git a/lib/kcfinder/cache/base.js b/lib/kcfinder/cache/base.js new file mode 100644 index 0000000..66aca17 --- /dev/null +++ b/lib/kcfinder/cache/base.js @@ -0,0 +1,4732 @@ +/*! jQuery v1.11.0 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */ +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k="".trim,l={},m="1.11.0",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(n.isPlainObject(c)||(b=n.isArray(c)))?(b?(b=!1,f=a&&n.isArray(a)?a:[]):f=a&&n.isPlainObject(a)?a:{},g[d]=n.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray||function(a){return"array"===n.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return a-parseFloat(a)>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(l.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&n.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:k&&!k.call("\ufeff\xa0")?function(a){return null==a?"":k.call(a)}:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),n.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||n.guid++,e):void 0},now:function(){return+new Date},support:l}),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s="sizzle"+-new Date,t=a.document,u=0,v=0,w=eb(),x=eb(),y=eb(),z=function(a,b){return a===b&&(j=!0),0},A="undefined",B=1<<31,C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=D.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",M=L.replace("w","w#"),N="\\["+K+"*("+L+")"+K+"*(?:([*^$|!~]?=)"+K+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+M+")|)|)"+K+"*\\]",O=":("+L+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+N.replace(3,8)+")*)|.*)\\)|)",P=new RegExp("^"+K+"+|((?:^|[^\\\\])(?:\\\\.)*)"+K+"+$","g"),Q=new RegExp("^"+K+"*,"+K+"*"),R=new RegExp("^"+K+"*([>+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(O),U=new RegExp("^"+M+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L.replace("w","w*")+")"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=/'|\\/g,ab=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),bb=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{G.apply(D=H.call(t.childNodes),t.childNodes),D[t.childNodes.length].nodeType}catch(cb){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function db(a,b,d,e){var f,g,h,i,j,m,p,q,u,v;if((b?b.ownerDocument||b:t)!==l&&k(b),b=b||l,d=d||[],!a||"string"!=typeof a)return d;if(1!==(i=b.nodeType)&&9!==i)return[];if(n&&!e){if(f=Z.exec(a))if(h=f[1]){if(9===i){if(g=b.getElementById(h),!g||!g.parentNode)return d;if(g.id===h)return d.push(g),d}else if(b.ownerDocument&&(g=b.ownerDocument.getElementById(h))&&r(b,g)&&g.id===h)return d.push(g),d}else{if(f[2])return G.apply(d,b.getElementsByTagName(a)),d;if((h=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(h)),d}if(c.qsa&&(!o||!o.test(a))){if(q=p=s,u=b,v=9===i&&a,1===i&&"object"!==b.nodeName.toLowerCase()){m=ob(a),(p=b.getAttribute("id"))?q=p.replace(_,"\\$&"):b.setAttribute("id",q),q="[id='"+q+"'] ",j=m.length;while(j--)m[j]=q+pb(m[j]);u=$.test(a)&&mb(b.parentNode)||b,v=m.join(",")}if(v)try{return G.apply(d,u.querySelectorAll(v)),d}catch(w){}finally{p||b.removeAttribute("id")}}}return xb(a.replace(P,"$1"),b,d,e)}function eb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function fb(a){return a[s]=!0,a}function gb(a){var b=l.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function hb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function ib(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||B)-(~a.sourceIndex||B);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function jb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function kb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function lb(a){return fb(function(b){return b=+b,fb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function mb(a){return a&&typeof a.getElementsByTagName!==A&&a}c=db.support={},f=db.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},k=db.setDocument=function(a){var b,e=a?a.ownerDocument||a:t,g=e.defaultView;return e!==l&&9===e.nodeType&&e.documentElement?(l=e,m=e.documentElement,n=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){k()},!1):g.attachEvent&&g.attachEvent("onunload",function(){k()})),c.attributes=gb(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=gb(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(e.getElementsByClassName)&&gb(function(a){return a.innerHTML="
    ",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=gb(function(a){return m.appendChild(a).id=s,!e.getElementsByName||!e.getElementsByName(s).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==A&&n){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ab,bb);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ab,bb);return function(a){var c=typeof a.getAttributeNode!==A&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==A?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==A&&n?b.getElementsByClassName(a):void 0},p=[],o=[],(c.qsa=Y.test(e.querySelectorAll))&&(gb(function(a){a.innerHTML="",a.querySelectorAll("[t^='']").length&&o.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||o.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll(":checked").length||o.push(":checked")}),gb(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&o.push("name"+K+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||o.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),o.push(",.*:")})),(c.matchesSelector=Y.test(q=m.webkitMatchesSelector||m.mozMatchesSelector||m.oMatchesSelector||m.msMatchesSelector))&&gb(function(a){c.disconnectedMatch=q.call(a,"div"),q.call(a,"[s!='']:x"),p.push("!=",O)}),o=o.length&&new RegExp(o.join("|")),p=p.length&&new RegExp(p.join("|")),b=Y.test(m.compareDocumentPosition),r=b||Y.test(m.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},z=b?function(a,b){if(a===b)return j=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===t&&r(t,a)?-1:b===e||b.ownerDocument===t&&r(t,b)?1:i?I.call(i,a)-I.call(i,b):0:4&d?-1:1)}:function(a,b){if(a===b)return j=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],k=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:i?I.call(i,a)-I.call(i,b):0;if(f===g)return ib(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)k.unshift(c);while(h[d]===k[d])d++;return d?ib(h[d],k[d]):h[d]===t?-1:k[d]===t?1:0},e):l},db.matches=function(a,b){return db(a,null,null,b)},db.matchesSelector=function(a,b){if((a.ownerDocument||a)!==l&&k(a),b=b.replace(S,"='$1']"),!(!c.matchesSelector||!n||p&&p.test(b)||o&&o.test(b)))try{var d=q.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return db(b,l,null,[a]).length>0},db.contains=function(a,b){return(a.ownerDocument||a)!==l&&k(a),r(a,b)},db.attr=function(a,b){(a.ownerDocument||a)!==l&&k(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!n):void 0;return void 0!==f?f:c.attributes||!n?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},db.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},db.uniqueSort=function(a){var b,d=[],e=0,f=0;if(j=!c.detectDuplicates,i=!c.sortStable&&a.slice(0),a.sort(z),j){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return i=null,a},e=db.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=db.selectors={cacheLength:50,createPseudo:fb,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ab,bb),a[3]=(a[4]||a[5]||"").replace(ab,bb),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||db.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&db.error(a[0]),a},PSEUDO:function(a){var b,c=!a[5]&&a[2];return V.CHILD.test(a[0])?null:(a[3]&&void 0!==a[4]?a[2]=a[4]:c&&T.test(c)&&(b=ob(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ab,bb).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=w[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&w(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==A&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=db.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),t=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&t){k=q[s]||(q[s]={}),j=k[a]||[],n=j[0]===u&&j[1],m=j[0]===u&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[u,n,m];break}}else if(t&&(j=(b[s]||(b[s]={}))[a])&&j[0]===u)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(t&&((l[s]||(l[s]={}))[a]=[u,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||db.error("unsupported pseudo: "+a);return e[s]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?fb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:fb(function(a){var b=[],c=[],d=g(a.replace(P,"$1"));return d[s]?fb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:fb(function(a){return function(b){return db(a,b).length>0}}),contains:fb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:fb(function(a){return U.test(a||"")||db.error("unsupported lang: "+a),a=a.replace(ab,bb).toLowerCase(),function(b){var c;do if(c=n?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===m},focus:function(a){return a===l.activeElement&&(!l.hasFocus||l.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:lb(function(){return[0]}),last:lb(function(a,b){return[b-1]}),eq:lb(function(a,b,c){return[0>c?c+b:c]}),even:lb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:lb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:lb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:lb(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function qb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=v++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[u,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[s]||(b[s]={}),(h=i[d])&&h[0]===u&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function rb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function sb(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function tb(a,b,c,d,e,f){return d&&!d[s]&&(d=tb(d)),e&&!e[s]&&(e=tb(e,f)),fb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||wb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:sb(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=sb(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?I.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=sb(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ub(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],i=g||d.relative[" "],j=g?1:0,k=qb(function(a){return a===b},i,!0),l=qb(function(a){return I.call(b,a)>-1},i,!0),m=[function(a,c,d){return!g&&(d||c!==h)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>j;j++)if(c=d.relative[a[j].type])m=[qb(rb(m),c)];else{if(c=d.filter[a[j].type].apply(null,a[j].matches),c[s]){for(e=++j;f>e;e++)if(d.relative[a[e].type])break;return tb(j>1&&rb(m),j>1&&pb(a.slice(0,j-1).concat({value:" "===a[j-2].type?"*":""})).replace(P,"$1"),c,e>j&&ub(a.slice(j,e)),f>e&&ub(a=a.slice(e)),f>e&&pb(a))}m.push(c)}return rb(m)}function vb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,i,j,k){var m,n,o,p=0,q="0",r=f&&[],s=[],t=h,v=f||e&&d.find.TAG("*",k),w=u+=null==t?1:Math.random()||.1,x=v.length;for(k&&(h=g!==l&&g);q!==x&&null!=(m=v[q]);q++){if(e&&m){n=0;while(o=a[n++])if(o(m,g,i)){j.push(m);break}k&&(u=w)}c&&((m=!o&&m)&&p--,f&&r.push(m))}if(p+=q,c&&q!==p){n=0;while(o=b[n++])o(r,s,g,i);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=E.call(j));s=sb(s)}G.apply(j,s),k&&!f&&s.length>0&&p+b.length>1&&db.uniqueSort(j)}return k&&(u=w,h=t),r};return c?fb(f):f}g=db.compile=function(a,b){var c,d=[],e=[],f=y[a+" "];if(!f){b||(b=ob(a)),c=b.length;while(c--)f=ub(b[c]),f[s]?d.push(f):e.push(f);f=y(a,vb(e,d))}return f};function wb(a,b,c){for(var d=0,e=b.length;e>d;d++)db(a,b[d],c);return c}function xb(a,b,e,f){var h,i,j,k,l,m=ob(a);if(!f&&1===m.length){if(i=m[0]=m[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&c.getById&&9===b.nodeType&&n&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(ab,bb),b)||[])[0],!b)return e;a=a.slice(i.shift().value.length)}h=V.needsContext.test(a)?0:i.length;while(h--){if(j=i[h],d.relative[k=j.type])break;if((l=d.find[k])&&(f=l(j.matches[0].replace(ab,bb),$.test(i[0].type)&&mb(b.parentNode)||b))){if(i.splice(h,1),a=f.length&&pb(i),!a)return G.apply(e,f),e;break}}}return g(a,m)(f,b,!n,e,$.test(a)&&mb(b.parentNode)||b),e}return c.sortStable=s.split("").sort(z).join("")===s,c.detectDuplicates=!!j,k(),c.sortDetached=gb(function(a){return 1&a.compareDocumentPosition(l.createElement("div"))}),gb(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||hb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&gb(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||hb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),gb(function(a){return null==a.getAttribute("disabled")})||hb(J,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),db}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return n.inArray(a,b)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;e>b;b++)if(n.contains(d[b],this))return!0}));for(b=0;e>b;b++)n.find(a,d[b],c);return c=this.pushStack(e>1?n.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=a.document,A=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,B=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:A.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:z,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=z.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return y.find(a);this.length=1,this[0]=d}return this.context=z,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};B.prototype=n.fn,y=n(z);var C=/^(?:parents|prev(?:Until|All))/,D={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!n(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b,c=n(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(n.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?"string"==typeof a?n.inArray(this[0],n(a)):n.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function E(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return E(a,"nextSibling")},prev:function(a){return E(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return n.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(D[a]||(e=n.unique(e)),C.test(a)&&(e=e.reverse())),this.pushStack(e)}});var F=/\S+/g,G={};function H(a){var b=G[a]={};return n.each(a.match(F)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?G[a]||H(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&n.each(arguments,function(a,c){var d;while((d=n.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){if(a===!0?!--n.readyWait:!n.isReady){if(!z.body)return setTimeout(n.ready);n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(z,[n]),n.fn.trigger&&n(z).trigger("ready").off("ready"))}}});function J(){z.addEventListener?(z.removeEventListener("DOMContentLoaded",K,!1),a.removeEventListener("load",K,!1)):(z.detachEvent("onreadystatechange",K),a.detachEvent("onload",K))}function K(){(z.addEventListener||"load"===event.type||"complete"===z.readyState)&&(J(),n.ready())}n.ready.promise=function(b){if(!I)if(I=n.Deferred(),"complete"===z.readyState)setTimeout(n.ready);else if(z.addEventListener)z.addEventListener("DOMContentLoaded",K,!1),a.addEventListener("load",K,!1);else{z.attachEvent("onreadystatechange",K),a.attachEvent("onload",K);var c=!1;try{c=null==a.frameElement&&z.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!n.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}J(),n.ready()}}()}return I.promise(b)};var L="undefined",M;for(M in n(l))break;l.ownLast="0"!==M,l.inlineBlockNeedsLayout=!1,n(function(){var a,b,c=z.getElementsByTagName("body")[0];c&&(a=z.createElement("div"),a.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",b=z.createElement("div"),c.appendChild(a).appendChild(b),typeof b.style.zoom!==L&&(b.style.cssText="border:0;margin:0;width:1px;padding:1px;display:inline;zoom:1",(l.inlineBlockNeedsLayout=3===b.offsetWidth)&&(c.style.zoom=1)),c.removeChild(a),a=b=null)}),function(){var a=z.createElement("div");if(null==l.deleteExpando){l.deleteExpando=!0;try{delete a.test}catch(b){l.deleteExpando=!1}}a=null}(),n.acceptData=function(a){var b=n.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(O,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}n.data(a,b,c)}else c=void 0}return c}function Q(a){var b;for(b in a)if(("data"!==b||!n.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function R(a,b,d,e){if(n.acceptData(a)){var f,g,h=n.expando,i=a.nodeType,j=i?n.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||n.guid++:h),j[k]||(j[k]=i?{}:{toJSON:n.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=n.extend(j[k],b):j[k].data=n.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[n.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[n.camelCase(b)])):f=g,f +}}function S(a,b,c){if(n.acceptData(a)){var d,e,f=a.nodeType,g=f?n.cache:a,h=f?a[n.expando]:n.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){n.isArray(b)?b=b.concat(n.map(b,n.camelCase)):b in d?b=[b]:(b=n.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!Q(d):!n.isEmptyObject(d))return}(c||(delete g[h].data,Q(g[h])))&&(f?n.cleanData([a],!0):l.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}n.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?n.cache[a[n.expando]]:a[n.expando],!!a&&!Q(a)},data:function(a,b,c){return R(a,b,c)},removeData:function(a,b){return S(a,b)},_data:function(a,b,c){return R(a,b,c,!0)},_removeData:function(a,b){return S(a,b,!0)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=n.data(f),1===f.nodeType&&!n._data(f,"parsedAttrs"))){c=g.length;while(c--)d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d]));n._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){n.data(this,a)}):arguments.length>1?this.each(function(){n.data(this,a,b)}):f?P(f,a,n.data(f,a)):void 0},removeData:function(a){return this.each(function(){n.removeData(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=n._data(a,b),c&&(!d||n.isArray(c)?d=n._data(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return n._data(a,c)||n._data(a,c,{empty:n.Callbacks("once memory").add(function(){n._removeData(a,b+"queue"),n._removeData(a,c)})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthh;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},X=/^(?:checkbox|radio)$/i;!function(){var a=z.createDocumentFragment(),b=z.createElement("div"),c=z.createElement("input");if(b.setAttribute("className","t"),b.innerHTML="
    a",l.leadingWhitespace=3===b.firstChild.nodeType,l.tbody=!b.getElementsByTagName("tbody").length,l.htmlSerialize=!!b.getElementsByTagName("link").length,l.html5Clone="<:nav>"!==z.createElement("nav").cloneNode(!0).outerHTML,c.type="checkbox",c.checked=!0,a.appendChild(c),l.appendChecked=c.checked,b.innerHTML="",l.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,a.appendChild(b),b.innerHTML="",l.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,l.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){l.noCloneEvent=!1}),b.cloneNode(!0).click()),null==l.deleteExpando){l.deleteExpando=!0;try{delete b.test}catch(d){l.deleteExpando=!1}}a=b=c=null}(),function(){var b,c,d=z.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(l[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),l[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var Y=/^(?:input|select|textarea)$/i,Z=/^key/,$=/^(?:mouse|contextmenu)|click/,_=/^(?:focusinfocus|focusoutblur)$/,ab=/^([^.]*)(?:\.(.+)|)$/;function bb(){return!0}function cb(){return!1}function db(){try{return z.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=n.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof n===L||a&&n.event.triggered===a.type?void 0:n.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(F)||[""],h=b.length;while(h--)f=ab.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=n.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=n.event.special[o]||{},l=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},i),(m=g[o])||(m=g[o]=[],m.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,l):m.push(l),n.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n.hasData(a)&&n._data(a);if(r&&(k=r.events)){b=(b||"").match(F)||[""],j=b.length;while(j--)if(h=ab.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=m.length;while(f--)g=m[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(m.splice(f,1),g.selector&&m.delegateCount--,l.remove&&l.remove.call(a,g));i&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(k)&&(delete r.handle,n._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,m,o=[d||z],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||z,3!==d.nodeType&&8!==d.nodeType&&!_.test(p+n.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[n.expando]?b:new n.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),k=n.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!n.isWindow(d)){for(i=k.delegateType||p,_.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||z)&&o.push(l.defaultView||l.parentWindow||a)}m=0;while((h=o[m++])&&!b.isPropagationStopped())b.type=m>1?i:k.bindType||p,f=(n._data(h,"events")||{})[b.type]&&n._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&n.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&n.acceptData(d)&&g&&d[p]&&!n.isWindow(d)){l=d[g],l&&(d[g]=null),n.event.triggered=p;try{d[p]()}catch(r){}n.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(n._data(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((n.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?n(c,this).index(i)>=0:n.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h]","i"),ib=/^\s+/,jb=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,kb=/<([\w:]+)/,lb=/\s*$/g,sb={option:[1,""],legend:[1,"
    ","
    "],area:[1,"",""],param:[1,"",""],thead:[1,"","
    "],tr:[2,"","
    "],col:[2,"","
    "],td:[3,"","
    "],_default:l.htmlSerialize?[0,"",""]:[1,"X
    ","
    "]},tb=eb(z),ub=tb.appendChild(z.createElement("div"));sb.optgroup=sb.option,sb.tbody=sb.tfoot=sb.colgroup=sb.caption=sb.thead,sb.th=sb.td;function vb(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==L?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==L?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||n.nodeName(d,b)?f.push(d):n.merge(f,vb(d,b));return void 0===b||b&&n.nodeName(a,b)?n.merge([a],f):f}function wb(a){X.test(a.type)&&(a.defaultChecked=a.checked)}function xb(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function yb(a){return a.type=(null!==n.find.attr(a,"type"))+"/"+a.type,a}function zb(a){var b=qb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Ab(a,b){for(var c,d=0;null!=(c=a[d]);d++)n._data(c,"globalEval",!b||n._data(b[d],"globalEval"))}function Bb(a,b){if(1===b.nodeType&&n.hasData(a)){var c,d,e,f=n._data(a),g=n._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)n.event.add(b,c,h[c][d])}g.data&&(g.data=n.extend({},g.data))}}function Cb(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!l.noCloneEvent&&b[n.expando]){e=n._data(b);for(d in e.events)n.removeEvent(b,d,e.handle);b.removeAttribute(n.expando)}"script"===c&&b.text!==a.text?(yb(b).text=a.text,zb(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),l.html5Clone&&a.innerHTML&&!n.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&X.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}n.extend({clone:function(a,b,c){var d,e,f,g,h,i=n.contains(a.ownerDocument,a);if(l.html5Clone||n.isXMLDoc(a)||!hb.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(ub.innerHTML=a.outerHTML,ub.removeChild(f=ub.firstChild)),!(l.noCloneEvent&&l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(d=vb(f),h=vb(a),g=0;null!=(e=h[g]);++g)d[g]&&Cb(e,d[g]);if(b)if(c)for(h=h||vb(a),d=d||vb(f),g=0;null!=(e=h[g]);g++)Bb(e,d[g]);else Bb(a,f);return d=vb(f,"script"),d.length>0&&Ab(d,!i&&vb(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k,m=a.length,o=eb(b),p=[],q=0;m>q;q++)if(f=a[q],f||0===f)if("object"===n.type(f))n.merge(p,f.nodeType?[f]:f);else if(mb.test(f)){h=h||o.appendChild(b.createElement("div")),i=(kb.exec(f)||["",""])[1].toLowerCase(),k=sb[i]||sb._default,h.innerHTML=k[1]+f.replace(jb,"<$1>")+k[2],e=k[0];while(e--)h=h.lastChild;if(!l.leadingWhitespace&&ib.test(f)&&p.push(b.createTextNode(ib.exec(f)[0])),!l.tbody){f="table"!==i||lb.test(f)?""!==k[1]||lb.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)n.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}n.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),l.appendChecked||n.grep(vb(p,"input"),wb),q=0;while(f=p[q++])if((!d||-1===n.inArray(f,d))&&(g=n.contains(f.ownerDocument,f),h=vb(o.appendChild(f),"script"),g&&Ab(h),c)){e=0;while(f=h[e++])pb.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=n.expando,j=n.cache,k=l.deleteExpando,m=n.event.special;null!=(d=a[h]);h++)if((b||n.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)m[e]?n.event.remove(d,e):n.removeEvent(d,e,g.handle);j[f]&&(delete j[f],k?delete d[i]:typeof d.removeAttribute!==L?d.removeAttribute(i):d[i]=null,c.push(f))}}}),n.fn.extend({text:function(a){return W(this,function(a){return void 0===a?n.text(this):this.empty().append((this[0]&&this[0].ownerDocument||z).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=xb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=xb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(vb(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&Ab(vb(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&n.cleanData(vb(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&n.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return W(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(gb,""):void 0;if(!("string"!=typeof a||nb.test(a)||!l.htmlSerialize&&hb.test(a)||!l.leadingWhitespace&&ib.test(a)||sb[(kb.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(jb,"<$1>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(vb(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(vb(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,k=this.length,m=this,o=k-1,p=a[0],q=n.isFunction(p);if(q||k>1&&"string"==typeof p&&!l.checkClone&&ob.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(k&&(i=n.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=n.map(vb(i,"script"),yb),f=g.length;k>j;j++)d=i,j!==o&&(d=n.clone(d,!0,!0),f&&n.merge(g,vb(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,n.map(g,zb),j=0;f>j;j++)d=g[j],pb.test(d.type||"")&&!n._data(d,"globalEval")&&n.contains(h,d)&&(d.src?n._evalUrl&&n._evalUrl(d.src):n.globalEval((d.text||d.textContent||d.innerHTML||"").replace(rb,"")));i=c=null}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=0,e=[],g=n(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),n(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Db,Eb={};function Fb(b,c){var d=n(c.createElement(b)).appendTo(c.body),e=a.getDefaultComputedStyle?a.getDefaultComputedStyle(d[0]).display:n.css(d[0],"display");return d.detach(),e}function Gb(a){var b=z,c=Eb[a];return c||(c=Fb(a,b),"none"!==c&&c||(Db=(Db||n("').prependTo(document.body); + $('#loading').html(_.label("Uploading file...")).show(); + form.submit(); + $('#uploadResponse').load(function() { + var response = $(this).contents().find('body').text(); + $('#loading').hide(); + response = response.split("\n"); + + var selected = [], errors = []; + $.each(response, function(i, row) { + if (row.substr(0, 1) == "/") + selected[selected.length] = row.substr(1, row.length - 1); + else + errors[errors.length] = row; + }); + if (errors.length) { + errors = errors.join("\n"); + if (errors.replace(/^\s+/g, "").replace(/\s+$/g, "").length) + _.alert(errors); + } + if (!selected.length) + selected = null; + _.refresh(selected); + $('#upload').detach(); + setTimeout(function() { + $('#uploadResponse').detach(); + }, 1); + _.initUploadButton(); + }); +}; + +_.maximize = function(button) { + + // TINYMCE 3 + if (_.opener.name == "tinymce") { + + var par = window.parent.document, + ifr = $('iframe[src*="browse.php?opener=tinymce&"]', par), + id = parseInt(ifr.attr('id').replace(/^mce_(\d+)_ifr$/, "$1")), + win = $('#mce_' + id, par); + + if ($(button).hasClass('selected')) { + $(button).removeClass('selected'); + win.css({ + left: _.maximizeMCE.left, + top: _.maximizeMCE.top, + width: _.maximizeMCE.width, + height: _.maximizeMCE.height + }); + ifr.css({ + width: _.maximizeMCE.width - _.maximizeMCE.Hspace, + height: _.maximizeMCE.height - _.maximizeMCE.Vspace + }); + + } else { + $(button).addClass('selected') + _.maximizeMCE = { + width: parseInt(win.css('width')), + height: parseInt(win.css('height')), + left: win.position().left, + top: win.position().top, + Hspace: parseInt(win.css('width')) - parseInt(ifr.css('width')), + Vspace: parseInt(win.css('height')) - parseInt(ifr.css('height')) + }; + var width = $(window.top).width(), + height = $(window.top).height(); + win.css({ + left: $(window.parent).scrollLeft(), + top: $(window.parent).scrollTop(), + width: width, + height: height + }); + ifr.css({ + width: width - _.maximizeMCE.Hspace, + height: height - _.maximizeMCE.Vspace + }); + } + + // TINYMCE 4 + } else if (_.opener.name == "tinymce4") { + + var par = window.parent.document, + ifr = $('iframe[src*="browse.php?opener=tinymce4&"]', par).parent(), + win = ifr.parent(); + + if ($(button).hasClass('selected')) { + $(button).removeClass('selected'); + + win.css({ + left: _.maximizeMCE4.left, + top: _.maximizeMCE4.top, + width: _.maximizeMCE4.width, + height: _.maximizeMCE4.height + }); + + ifr.css({ + width: _.maximizeMCE4.width, + height: _.maximizeMCE4.height - _.maximizeMCE4.Vspace + }); + + } else { + $(button).addClass('selected'); + + _.maximizeMCE4 = { + width: parseInt(win.css('width')), + height: parseInt(win.css('height')), + left: win.position().left, + top: win.position().top, + Vspace: win.outerHeight(true) - ifr.outerHeight(true) - 1 + }; + + var width = $(window.top).width(), + height = $(window.top).height(); + + win.css({ + left: 0, + top: 0, + width: width, + height: height + }); + + ifr.css({ + width: width, + height: height - _.maximizeMCE4.Vspace + }); + } + + // PUPUP WINDOW + } else if (window.opener) { + window.moveTo(0, 0); + width = screen.availWidth; + height = screen.availHeight; + if ($.agent.opera) + height -= 50; + window.resizeTo(width, height); + + } else { + if (window.parent) { + var el = null; + $(window.parent.document).find('iframe').each(function() { + if (this.src.replace('/?', '?') == window.location.href.replace('/?', '?')) { + el = this; + return false; + } + }); + + // IFRAME + if (el !== null) + $(el).toggleFullscreen(window.parent.document); + + // SELF WINDOW + else + $('body').toggleFullscreen(); + + } else + $('body').toggleFullscreen(); + } +}; + +_.refresh = function(selected) { + _.fadeFiles(); + $.ajax({ + type: "post", + dataType: "json", + url: _.getURL("chDir"), + data: {dir: _.dir}, + async: false, + success: function(data) { + if (_.check4errors(data)) { + $('#files > div').css({opacity: "", filter: ""}); + return; + } + _.dirWritable = data.dirWritable; + _.files = data.files ? data.files : []; + _.orderFiles(null, selected); + _.statusDir(); + }, + error: function() { + $('#files > div').css({opacity: "", filter: ""}); + $('#files').html(_.label("Unknown error.")); + } + }); +}; +/** This file is part of KCFinder project + * + * @desc Settings panel functionality + * @package KCFinder + * @version 3.12 + * @author Pavel Tzonkov + * @copyright 2010-2014 KCFinder Project + * @license http://opensource.org/licenses/GPL-3.0 GPLv3 + * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3 + * @link http://kcfinder.sunhater.com + */ + +_.initSettings = function() { + $('#settings fieldset').disableTextSelect(); + + if (!_.shows.length) + $('#show input[type="checkbox"]').each(function(i) { + _.shows[i] = this.name; + }); + + var shows = _.shows; + + if (!$.$.kuki.isSet('showname')) { + $.$.kuki.set('showname', "on"); + $.each(shows, function (i, val) { + if (val != "name") $.$.kuki.set('show' + val, "off"); + }); + } + + $('#show input[type="checkbox"]').click(function() { + $.$.kuki.set('show' + this.name, this.checked ? "on" : "off") + $('#files .file div.' + this.name).css('display', this.checked ? "block" : "none"); + }); + + $.each(shows, function(i, val) { + $('#show input[name="' + val + '"]').get(0).checked = ($.$.kuki.get('show' + val) == "on") ? "checked" : ""; + }); + + if (!_.orders.length) + $('#order input[type="radio"]').each(function(i) { + _.orders[i] = this.value; + }) + + var orders = _.orders; + + if (!$.$.kuki.isSet('order')) + $.$.kuki.set('order', "name"); + + if (!$.$.kuki.isSet('orderDesc')) + $.$.kuki.set('orderDesc', "off"); + + $('#order input[value="' + $.$.kuki.get('order') + '"]').get(0).checked = true; + $('#order input[name="desc"]').get(0).checked = ($.$.kuki.get('orderDesc') == "on"); + + $('#order input[type="radio"]').click(function() { + $.$.kuki.set('order', this.value); + _.orderFiles(); + }); + + $('#order input[name="desc"]').click(function() { + $.$.kuki.set('orderDesc', this.checked ? 'on' : "off"); + _.orderFiles(); + }); + + if (!$.$.kuki.isSet('view')) + $.$.kuki.set('view', "thumbs"); + + if ($.$.kuki.get('view') == "list") + $('#show').parent().hide(); + + $('#view input[value="' + $.$.kuki.get('view') + '"]').get(0).checked = true; + + $('#view input').click(function() { + var view = this.value; + if ($.$.kuki.get('view') != view) { + $.$.kuki.set('view', view); + if (view == "list") + $('#show').parent().hide(); + else + $('#show').parent().show(); + } + _.fixFilesHeight(); + _.refresh(); + }); + $('#settings fieldset, #settings input, #settings label').transForm(); + _.initLangs(); +}; + + +_.initLangs = function() { + $.each(_.langs, function(id, lng) { + var opt = $(''); + opt.val(id).text(lng); + if (id == _.lang) + opt.attr({selected: true}); + $('#lang').append(opt); + }); + $('#lang').change(function() { + window.location = _.getURL("browser", this.value) + "&theme=" + encodeURIComponent(_.theme); + }); +}/** This file is part of KCFinder project + * + * @desc File related functionality + * @package KCFinder + * @version 3.12 + * @author Pavel Tzonkov + * @copyright 2010-2014 KCFinder Project + * @license http://opensource.org/licenses/GPL-3.0 GPLv3 + * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3 + * @link http://kcfinder.sunhater.com + */ + +_.initFiles = function() { + $(document).unbind('keydown').keydown(function(e) { + return !_.selectAll(e); + }); + $('#files').unbind().scroll(function() { + _.menu.hide(); + }).disableTextSelect(); + + $('.file').unbind().click(function(e) { + _.selectFile($(this), e); + + }).rightClick(function(el, e) { + _.menuFile($(el), e); + }).dblclick(function() { + _.returnFile($(this)); + }); + + if ($.mobile) + $('.file').on('taphold', function() { + _.menuFile($(this), { + pageX: $(this).offset().left, + pageY: $(this).offset().top + $(this).outerHeight() + }); + }); + + $.each(_.shows, function(i, val) { + $('#files .file div.' + val).css('display', ($.$.kuki.get('show' + val) == "off") ? "none" : "block"); + }); + _.statusDir(); +}; + +_.showFiles = function(callBack, selected) { + _.fadeFiles(); + setTimeout(function() { + var c = $('
    '); + + $.each(_.files, function(i, file) { + var f, icon, + stamp = file.size + "|" + file.mtime; + + // List + if ($.$.kuki.get('view') == "list") { + if (!i) c.html('
    '); + + icon = $.$.getFileExtension(file.name); + if (file.thumb) + icon = ".image"; + else if (!icon.length || !file.smallIcon) + icon = "."; + icon = "themes/" + _.theme + "/img/files/small/" + icon + ".png"; + + f = $(''); + f.appendTo(c.find('table')); + + // Thumbnails + } else { + if (file.thumb) + icon = _.getURL('thumb') + "&file=" + encodeURIComponent(file.name) + "&dir=" + encodeURIComponent(_.dir) + "&stamp=" + stamp; + else if (file.smallThumb) { + icon = _.uploadURL + "/" + _.dir + "/" + encodeURIComponent(file.name); + icon = $.$.escapeDirs(icon).replace(/\'/g, "%27"); + } else { + icon = file.bigIcon ? $.$.getFileExtension(file.name) : "."; + if (!icon.length) icon = "."; + icon = "themes/" + _.theme + "/img/files/big/" + icon + ".png"; + } + f = $('
    '); + f.appendTo(c); + } + + f.find('.thumb').css({backgroundImage: 'url("' + icon + '")'}); + f.find('.name').text(file.name); + f.find('.time').html(file.date); + f.find('.size').html(_.humanSize(file.size)); + f.data(file); + + if ((file.name === selected) || $.$.inArray(file.name, selected)) + f.addClass('selected'); + }); + + c.css({opacity:'', filter:''}); + $('#files').html(c); + + if (callBack) callBack(); + _.initFiles(); + _.fixScrollRadius(); + }, 200); +}; + +_.selectFile = function(file, e) { + + // Click with Ctrl, Meta or Shift key + if (e.ctrlKey || e.metaKey || e.shiftKey) { + + // Click with Shift key + if (e.shiftKey && !file.hasClass('selected')) { + var f = file.prev(); + while (f.get(0) && !f.hasClass('selected')) { + f.addClass('selected'); + f = f.prev(); + } + } + + file.toggleClass('selected'); + + // Update statusbar + var files = $('.file.selected').get(), + size = 0, data; + if (!files.length) + _.statusDir(); + else { + $.each(files, function(i, cfile) { + size += $(cfile).data('size'); + }); + size = _.humanSize(size); + if (files.length > 1) + $('#fileinfo').html(files.length + " " + _.label("selected files") + " (" + size + ")"); + else { + data = $(files[0]).data(); + $('#fileinfo').text(data.name + " (" + _.humanSize(data.size) + ", " + data.date + ")"); + } + } + + // Normal click + } else { + data = file.data(); + $('.file').removeClass('selected'); + file.addClass('selected'); + $('#fileinfo').text(data.name + " (" + _.humanSize(data.size) + ", " + data.date + ")"); + } +}; + +_.selectAll = function(e) { + if ((!e.ctrlKey && !e.metaKey) || ((e.keyCode != 65) && (e.keyCode != 97))) // Ctrl-A + return false; + + var files = $('.file'), + size = 0; + + if (files.length) { + + files.addClass('selected').each(function() { + size += $(this).data('size'); + }); + + $('#fileinfo').html(files.length + " " + _.label("selected files") + " (" + _.humanSize(size) + ")"); + } + + return true; +}; + +_.returnFile = function(file) { + + var button, win, fileURL = file.substr + ? file : _.uploadURL + "/" + _.dir + "/" + file.data('name'); + fileURL = $.$.escapeDirs(fileURL); + + if (_.opener.name == "ckeditor") { + _.opener.CKEditor.object.tools.callFunction(_.opener.CKEditor.funcNum, fileURL, ""); + window.close(); + + } else if (_.opener.name == "fckeditor") { + window.opener.SetUrl(fileURL) ; + window.close() ; + + } else if (_.opener.name == "tinymce") { + win = tinyMCEPopup.getWindowArg('window'); + win.document.getElementById(tinyMCEPopup.getWindowArg('input')).value = fileURL; + if (win.getImageData) win.getImageData(); + if (typeof(win.ImageDialog) != "undefined") { + if (win.ImageDialog.getImageData) + win.ImageDialog.getImageData(); + if (win.ImageDialog.showPreviewImage) + win.ImageDialog.showPreviewImage(fileURL); + } + tinyMCEPopup.close(); + + } else if (_.opener.name == "tinymce4") { + win = (window.opener ? window.opener : window.parent); + $(win.document).find('#' + _.opener.TinyMCE.field).val(fileURL); + win.tinyMCE.activeEditor.windowManager.close(); + + } else if (_.opener.callBack) { + + if (window.opener && window.opener.KCFinder) { + _.opener.callBack(fileURL); + window.close(); + } + + if (window.parent && window.parent.KCFinder) { + button = $('#toolbar a[href="kcact:maximize"]'); + if (button.hasClass('selected')) + _.maximize(button); + _.opener.callBack(fileURL); + } + + } else if (_.opener.callBackMultiple) { + if (window.opener && window.opener.KCFinder) { + _.opener.callBackMultiple([fileURL]); + window.close(); + } + + if (window.parent && window.parent.KCFinder) { + button = $('#toolbar a[href="kcact:maximize"]'); + if (button.hasClass('selected')) + _.maximize(button); + _.opener.callBackMultiple([fileURL]); + } + + } +}; + +_.returnFiles = function(files) { + if (_.opener.callBackMultiple && files.length) { + var rfiles = []; + $.each(files, function(i, file) { + rfiles[i] = _.uploadURL + "/" + _.dir + "/" + $(file).data('name'); + rfiles[i] = $.$.escapeDirs(rfiles[i]); + }); + _.opener.callBackMultiple(rfiles); + if (window.opener) window.close() + } +}; + +_.returnThumbnails = function(files) { + if (_.opener.callBackMultiple) { + var rfiles = [], j = 0; + $.each(files, function(i, file) { + if ($(file).data('thumb')) { + rfiles[j] = _.thumbsURL + "/" + _.dir + "/" + $(file).data('name'); + rfiles[j] = $.$.escapeDirs(rfiles[j++]); + } + }); + _.opener.callBackMultiple(rfiles); + if (window.opener) window.close() + } +}; +/** This file is part of KCFinder project + * + * @desc Folder related functionality + * @package KCFinder + * @version 3.12 + * @author Pavel Tzonkov + * @copyright 2010-2014 KCFinder Project + * @license http://opensource.org/licenses/GPL-3.0 GPLv3 + * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3 + * @link http://kcfinder.sunhater.com + */ + +_.initFolders = function() { + $('#folders').scroll(function() { + _.menu.hide(); + }).disableTextSelect(); + $('div.folder > a').unbind().click(function() { + _.menu.hide(); + return false; + }); + $('div.folder > a > span.brace').unbind().click(function() { + if ($(this).hasClass('opened') || $(this).hasClass('closed')) + _.expandDir($(this).parent()); + }); + $('div.folder > a > span.folder').unbind().click(function() { + _.changeDir($(this).parent()); + }).rightClick(function(el, e) { + _.menuDir($(el).parent(), e); + }); + if ($.mobile) + $('div.folder > a > span.folder').on('taphold', function() { + _.menuDir($(this).parent(), { + pageX: $(this).offset().left + 1, + pageY: $(this).offset().top + $(this).outerHeight() + }); + }); + +}; + +_.setTreeData = function(data, path) { + if (!path) + path = ""; + else if (path.length && (path.substr(path.length - 1, 1) != '/')) + path += "/"; + path += data.name; + var selector = '#folders a[href="kcdir:/' + $.$.escapeDirs(path) + '"]'; + $(selector).data({ + name: data.name, + path: path, + readable: data.readable, + writable: data.writable, + removable: data.removable, + hasDirs: data.hasDirs + }); + $(selector + ' span.folder').addClass(data.current ? 'current' : 'regular'); + if (data.dirs && data.dirs.length) { + $(selector + ' span.brace').addClass('opened'); + $.each(data.dirs, function(i, cdir) { + _.setTreeData(cdir, path + "/"); + }); + } else if (data.hasDirs) + $(selector + ' span.brace').addClass('closed'); +}; + +_.buildTree = function(root, path) { + if (!path) path = ""; + path += root.name; + var cdir, html = '
     ' + $.$.htmlData(root.name) + ''; + if (root.dirs) { + html += '
    '; + for (var i = 0; i < root.dirs.length; i++) { + cdir = root.dirs[i]; + html += _.buildTree(cdir, path + "/"); + } + html += '
    '; + } + html += '
    '; + return html; +}; + +_.expandDir = function(dir) { + var path = dir.data('path'); + if (dir.children('.brace').hasClass('opened')) { + dir.parent().children('.folders').hide(500, function() { + if (path == _.dir.substr(0, path.length)) + _.changeDir(dir); + _.fixScrollRadius(); + }); + dir.children('.brace').removeClass('opened').addClass('closed'); + } else { + if (dir.parent().children('.folders').get(0)) { + dir.parent().children('.folders').show(500, function() { + _.fixScrollRadius(); + }); + dir.children('.brace').removeClass('closed').addClass('opened'); + } else if (!$('#loadingDirs').get(0)) { + dir.parent().append('
    ' + _.label("Loading folders...") + '
    '); + $('#loadingDirs').hide().show(200, function() { + $.ajax({ + type: "post", + dataType: "json", + url: _.getURL("expand"), + data: {dir: path}, + async: false, + success: function(data) { + $('#loadingDirs').hide(200, function() { + $('#loadingDirs').detach(); + }); + if (_.check4errors(data)) + return; + + var html = ""; + $.each(data.dirs, function(i, cdir) { + html += ''; + }); + if (html.length) { + dir.parent().append('
    ' + html + '
    '); + var folders = $(dir.parent().children('.folders').first()); + folders.hide(); + $(folders).show(500, function() { + _.fixScrollRadius(); + }); + $.each(data.dirs, function(i, cdir) { + _.setTreeData(cdir, path); + }); + } + if (data.dirs.length) + dir.children('.brace').removeClass('closed').addClass('opened'); + else + dir.children('.brace').removeClass('opened closed'); + _.initFolders(); + _.initDropUpload(); + _.fixScrollRadius(); + }, + error: function() { + $('#loadingDirs').detach(); + _.alert(_.label("Unknown error.")); + _.fixScrollRadius(); + } + }); + _.fixScrollRadius(); + }); + } + } +}; + +_.changeDir = function(dir) { + if (dir.children('span.folder').hasClass('regular')) { + $('div.folder > a > span.folder').removeClass('current regular').addClass('regular'); + dir.children('span.folder').removeClass('regular').addClass('current'); + $('#files').html(_.label("Loading files...")); + $.ajax({ + type: "post", + dataType: "json", + url: _.getURL("chDir"), + data: {dir: dir.data('path')}, + async: false, + success: function(data) { + if (_.check4errors(data)) + return; + _.files = data.files; + _.orderFiles(); + _.dir = dir.data('path'); + _.dirWritable = data.dirWritable; + _.setTitle("KCFinder: /" + _.dir); + _.statusDir(); + _.initDropUpload(); + }, + error: function() { + $('#files').html(_.label("Unknown error.")); + } + }); + } +}; + +_.statusDir = function() { + var i = 0, size = 0; + for (; i < _.files.length; i++) + size += _.files[i].size; + size = _.humanSize(size); + $('#fileinfo').html(_.files.length + " " + _.label("files") + " (" + size + ")"); +}; + +_.refreshDir = function(dir) { + var path = dir.data('path'); + if (dir.children('.brace').hasClass('opened') || dir.children('.brace').hasClass('closed')) + dir.children('.brace').removeClass('opened').addClass('closed'); + dir.parent().children('.folders').first().detach(); + if (path == _.dir.substr(0, path.length)) + _.changeDir(dir); + _.expandDir(dir); + return true; +}; +/** This file is part of KCFinder project + * + * @desc Context menus + * @package KCFinder + * @version 3.12 + * @author Pavel Tzonkov + * @copyright 2010-2014 KCFinder Project + * @license http://opensource.org/licenses/GPL-3.0 GPLv3 + * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3 + * @link http://kcfinder.sunhater.com + */ + +_.menu = { + + init: function() { + $('#menu').html("
      ").css('display', 'none'); + }, + + addItem: function(href, label, callback, denied) { + if (typeof denied == "undefined") + denied = false; + + $('#menu ul').append('
    • ' + label + '
    • '); + + if (!denied && $.isFunction(callback)) + $('#menu a[href="' + href + '"]').click(function() { + _.menu.hide(); + return callback(); + }); + }, + + addDivider: function() { + if ($('#menu ul').html().length) + $('#menu ul').append("
    • -
    • "); + }, + + show: function(e) { + var dlg = $('#menu'), + ul = $('#menu ul'); + if (ul.html().length) { + dlg.find('ul').first().menu(); + if (typeof e != "undefined") { + var left = e.pageX, + top = e.pageY, + win = $(window); + + if ((dlg.outerWidth() + left) > win.width()) + left = win.width() - dlg.outerWidth(); + + if ((dlg.outerHeight() + top) > win.height()) + top = win.height() - dlg.outerHeight(); + + dlg.hide().css({ + left: left, + top: top, + width: "" + }).fadeIn('fast'); + } else + dlg.fadeIn('fast'); + } else + ul.detach(); + }, + + hide: function() { + $('#clipboard').removeClass('selected'); + $('div.folder > a > span.folder').removeClass('context'); + $('#menu').hide().css('width', "").html("").data('title', null).unbind().click(function() { + return false; + }); + $(document).unbind('keydown').keydown(function(e) { + return !_.selectAll(e); + }); + } +}; + +// FILE CONTEXT MENU +_.menuFile = function(file, e) { + _.menu.init(); + + var data = file.data(), + files = $('.file.selected').get(); + + // MULTIPLE FILES MENU + if (file.hasClass('selected') && files.length && (files.length > 1)) { + var thumb = false, + notWritable = 0, + cdata; + + $.each(files, function(i, cfile) { + cdata = $(cfile).data(); + if (cdata.thumb) thumb = true; + if (!data.writable) notWritable++; + }); + + if (_.opener.callBackMultiple) { + + // SELECT FILES + _.menu.addItem("kcact:pick", _.label("Select"), function() { + _.returnFiles(files); + return false; + }); + + // SELECT THUMBNAILS + if (thumb) + _.menu.addItem("kcact:pick_thumb", _.label("Select Thumbnails"), function() { + _.returnThumbnails(files); + return false; + }); + } + + if (data.thumb || data.smallThumb || _.support.zip) { + + _.menu.addDivider(); + + // VIEW IMAGE + if (data.thumb || data.smallThumb) + _.menu.addItem("kcact:view", _.label("View"), function() { + _.viewImage(data); + }); + + // DOWNLOAD + if (_.support.zip) + _.menu.addItem("kcact:download", _.label("Download"), function() { + var pfiles = []; + $.each(files, function(i, cfile) { + pfiles[i] = $(cfile).data('name'); + }); + _.post(_.getURL('downloadSelected'), {dir:_.dir, files:pfiles}); + return false; + }); + } + + // ADD TO CLIPBOARD + if (_.access.files.copy || _.access.files.move) { + _.menu.addDivider(); + _.menu.addItem("kcact:clpbrdadd", _.label("Add to Clipboard"), function() { + var msg = ''; + $.each(files, function(i, cfile) { + var cdata = $(cfile).data(), + failed = false; + for (i = 0; i < _.clipboard.length; i++) + if ((_.clipboard[i].name == cdata.name) && + (_.clipboard[i].dir == _.dir) + ) { + failed = true; + msg += cdata.name + ": " + _.label("This file is already added to the Clipboard.") + "\n"; + break; + } + + if (!failed) { + cdata.dir = _.dir; + _.clipboard[_.clipboard.length] = cdata; + } + }); + _.initClipboard(); + if (msg.length) _.alert(msg.substr(0, msg.length - 1)); + return false; + }); + } + + // DELETE + if (_.access.files['delete']) { + _.menu.addDivider(); + _.menu.addItem("kcact:rm", _.label("Delete"), function() { + if ($(this).hasClass('denied')) return false; + var failed = 0, + dfiles = []; + $.each(files, function(i, cfile) { + var cdata = $(cfile).data(); + if (!cdata.writable) + failed++; + else + dfiles[dfiles.length] = _.dir + "/" + cdata.name; + }); + if (failed == files.length) { + _.alert(_.label("The selected files are not removable.")); + return false; + } + + var go = function(callBack) { + _.fadeFiles(); + $.ajax({ + type: "post", + dataType: "json", + url: _.getURL("rm_cbd"), + data: {files:dfiles}, + async: false, + success: function(data) { + if (callBack) callBack(); + _.check4errors(data); + _.refresh(); + }, + error: function() { + if (callBack) callBack(); + $('#files > div').css({ + opacity: "", + filter: "" + }); + _.alert(_.label("Unknown error.")); + } + }); + }; + + if (failed) + _.confirm( + _.label("{count} selected files are not removable. Do you want to delete the rest?", {count:failed}), + go + ); + + else + _.confirm( + _.label("Are you sure you want to delete all selected files?"), + go + ); + + return false; + }, (notWritable == files.length)); + } + + _.menu.show(e); + + // SINGLE FILE MENU + } else { + $('.file').removeClass('selected'); + file.addClass('selected'); + $('#fileinfo').text(data.name + " (" + _.humanSize(data.size) + ", " + data.date + ")"); + + if (_.opener.callBack || _.opener.callBackMultiple) { + + // SELECT FILE + _.menu.addItem("kcact:pick", _.label("Select"), function() { + _.returnFile(file); + return false; + }); + + // SELECT THUMBNAIL + if (data.thumb) + _.menu.addItem("kcact:pick_thumb", _.label("Select Thumbnail"), function() { + _.returnFile(_.thumbsURL + "/" + _.dir + "/" + data.name); + return false; + }); + + _.menu.addDivider(); + } + + // VIEW IMAGE + if (data.thumb || data.smallThumb) + _.menu.addItem("kcact:view", _.label("View"), function() { + _.viewImage(data); + }); + + // DOWNLOAD + _.menu.addItem("kcact:download", _.label("Download"), function() { + $('#menu').html('
      '); + $('#downloadForm input').get(0).value = _.dir; + $('#downloadForm input').get(1).value = data.name; + $('#downloadForm').submit(); + return false; + }); + + // ADD TO CLIPBOARD + if (_.access.files.copy || _.access.files.move) { + _.menu.addDivider(); + _.menu.addItem("kcact:clpbrdadd", _.label("Add to Clipboard"), function() { + for (i = 0; i < _.clipboard.length; i++) + if ((_.clipboard[i].name == data.name) && + (_.clipboard[i].dir == _.dir) + ) { + _.alert(_.label("This file is already added to the Clipboard.")); + return false; + } + var cdata = data; + cdata.dir = _.dir; + _.clipboard[_.clipboard.length] = cdata; + _.initClipboard(); + return false; + }); + } + + + if (_.access.files.rename || _.access.files['delete']) + _.menu.addDivider(); + + // RENAME + if (_.access.files.rename) + _.menu.addItem("kcact:mv", _.label("Rename..."), function() { + if (!data.writable) return false; + _.fileNameDialog( + {dir: _.dir, file: data.name}, + 'newName', data.name, _.getURL("rename"), { + title: "New file name:", + errEmpty: "Please enter new file name.", + errSlash: "Unallowable characters in file name.", + errDot: "File name shouldn't begins with '.'" + }, + _.refresh + ); + return false; + }, !data.writable); + + // DELETE + if (_.access.files['delete']) + _.menu.addItem("kcact:rm", _.label("Delete"), function() { + if (!data.writable) return false; + _.confirm(_.label("Are you sure you want to delete this file?"), + function(callBack) { + $.ajax({ + type: "post", + dataType: "json", + url: _.getURL("delete"), + data: {dir: _.dir, file: data.name}, + async: false, + success: function(data) { + if (callBack) callBack(); + _.clearClipboard(); + if (_.check4errors(data)) + return; + _.refresh(); + }, + error: function() { + if (callBack) callBack(); + _.alert(_.label("Unknown error.")); + } + }); + } + ); + return false; + }, !data.writable); + + _.menu.show(e); + } + +}; + +// FOLDER CONTEXT MENU +_.menuDir = function(dir, e) { + _.menu.init(); + + var data = dir.data(), + html = '
        '; + + if (_.clipboard && _.clipboard.length) { + + // COPY CLIPBOARD + if (_.access.files.copy) + _.menu.addItem("kcact:cpcbd", _.label("Copy {count} files", {count: _.clipboard.length}), function() { + _.copyClipboard(data.path); + return false; + }, !data.writable); + + // MOVE CLIPBOARD + if (_.access.files.move) + _.menu.addItem("kcact:mvcbd", _.label("Move {count} files", {count: _.clipboard.length}), function() { + _.moveClipboard(data.path); + return false; + }, !data.writable); + + if (_.access.files.copy || _.access.files.move) + _.menu.addDivider(); + } + + // REFRESH + _.menu.addItem("kcact:refresh", _.label("Refresh"), function() { + _.refreshDir(dir); + return false; + }); + + // DOWNLOAD + if (_.support.zip) { + _.menu.addDivider(); + _.menu.addItem("kcact:download", _.label("Download"), function() { + _.post(_.getURL("downloadDir"), {dir:data.path}); + return false; + }); + } + + if (_.access.dirs.create || _.access.dirs.rename || _.access.dirs['delete']) + _.menu.addDivider(); + + // NEW SUBFOLDER + if (_.access.dirs.create) + _.menu.addItem("kcact:mkdir", _.label("New Subfolder..."), function(e) { + if (!data.writable) return false; + _.fileNameDialog( + {dir: data.path}, + "newDir", "", _.getURL("newDir"), { + title: "New folder name:", + errEmpty: "Please enter new folder name.", + errSlash: "Unallowable characters in folder name.", + errDot: "Folder name shouldn't begins with '.'" + }, function() { + _.refreshDir(dir); + _.initDropUpload(); + if (!data.hasDirs) { + dir.data('hasDirs', true); + dir.children('span.brace').addClass('closed'); + } + } + ); + return false; + }, !data.writable); + + // RENAME + if (_.access.dirs.rename) + _.menu.addItem("kcact:mvdir", _.label("Rename..."), function(e) { + if (!data.removable) return false; + _.fileNameDialog( + {dir: data.path}, + "newName", data.name, _.getURL("renameDir"), { + title: "New folder name:", + errEmpty: "Please enter new folder name.", + errSlash: "Unallowable characters in folder name.", + errDot: "Folder name shouldn't begins with '.'" + }, function(dt) { + if (!dt.name) { + _.alert(_.label("Unknown error.")); + return; + } + var currentDir = (data.path == _.dir); + dir.children('span.folder').text(dt.name); + dir.data('name', dt.name); + dir.data('path', $.$.dirname(data.path) + '/' + dt.name); + if (currentDir) + _.dir = dir.data('path'); + _.initDropUpload(); + }, + true + ); + return false; + }, !data.removable); + + // DELETE + if (_.access.dirs['delete']) + _.menu.addItem("kcact:rmdir", _.label("Delete"), function() { + if (!data.removable) return false; + _.confirm( + _.label("Are you sure you want to delete this folder and all its content?"), + function(callBack) { + $.ajax({ + type: "post", + dataType: "json", + url: _.getURL("deleteDir"), + data: {dir: data.path}, + async: false, + success: function(data) { + if (callBack) callBack(); + if (_.check4errors(data)) + return; + dir.parent().hide(500, function() { + var folders = dir.parent().parent(); + var pDir = folders.parent().children('a').first(); + dir.parent().detach(); + if (!folders.children('div.folder').get(0)) { + pDir.children('span.brace').first().removeClass('opened closed'); + pDir.parent().children('.folders').detach(); + pDir.data('hasDirs', false); + } + if (pDir.data('path') == _.dir.substr(0, pDir.data('path').length)) + _.changeDir(pDir); + _.initDropUpload(); + }); + }, + error: function() { + if (callBack) callBack(); + _.alert(_.label("Unknown error.")); + } + }); + } + ); + return false; + }, !data.removable); + + _.menu.show(e); + + $('div.folder > a > span.folder').removeClass('context'); + if (dir.children('span.folder').hasClass('regular')) + dir.children('span.folder').addClass('context'); +}; + +// CLIPBOARD MENU +_.openClipboard = function() { + + if (!_.clipboard || !_.clipboard.length) return; + + // CLOSE MENU + if ($('#menu a[href="kcact:clrcbd"]').html()) { + $('#clipboard').removeClass('selected'); + _.menu.hide(); + return; + } + + setTimeout(function() { + _.menu.init(); + + var dlg = $('#menu'), + jStatus = $('#status'), + html = '
      • '; + + // CLIPBOARD FILES + $.each(_.clipboard, function(i, val) { + var icon = $.$.getFileExtension(val.name); + if (val.thumb) + icon = ".image"; + else if (!val.smallIcon || !icon.length) + icon = "."; + icon = "themes/" + _.theme + "/img/files/small/" + icon + ".png"; + html += '' + $.$.htmlData($.$.basename(val.name)) + ''; + }); + html += '
      • -
      • '; + $('#menu ul').append(html); + + // DOWNLOAD + if (_.support.zip) + _.menu.addItem("kcact:download", _.label("Download files"), function() { + _.downloadClipboard(); + return false; + }); + + if (_.access.files.copy || _.access.files.move || _.access.files['delete']) + _.menu.addDivider(); + + // COPY + if (_.access.files.copy) + _.menu.addItem("kcact:cpcbd", _.label("Copy files here"), function() { + if (!_.dirWritable) return false; + _.copyClipboard(_.dir); + return false; + }, !_.dirWritable); + + // MOVE + if (_.access.files.move) + _.menu.addItem("kcact:mvcbd", _.label("Move files here"), function() { + if (!_.dirWritable) return false; + _.moveClipboard(_.dir); + return false; + }, !_.dirWritable); + + // DELETE + if (_.access.files['delete']) + _.menu.addItem("kcact:rmcbd", _.label("Delete files"), function() { + _.confirm( + _.label("Are you sure you want to delete all files in the Clipboard?"), + function(callBack) { + if (callBack) callBack(); + _.deleteClipboard(); + } + ); + return false; + }); + + _.menu.addDivider(); + + // CLEAR CLIPBOARD + _.menu.addItem("kcact:clrcbd", _.label("Clear the Clipboard"), function() { + _.clearClipboard(); + return false; + }); + + $('#clipboard').addClass('selected'); + _.menu.show(); + + var left = $(window).width() - dlg.css({width: ""}).outerWidth(), + top = $(window).height() - dlg.outerHeight() - jStatus.outerHeight(), + lheight = top + dlg.outerTopSpace(); + + dlg.find('.list').css({ + 'max-height': lheight, + 'overflow-y': "auto", + 'overflow-x': "hidden", + width: "" + }); + + top = $(window).height() - dlg.outerHeight(true) - jStatus.outerHeight(true); + + dlg.css({ + left: left - 5, + top: top + }).fadeIn("fast"); + + var a = dlg.find('.list').outerHeight(), + b = dlg.find('.list div').outerHeight(); + + if (b - a > 10) { + dlg.css({ + left: parseInt(dlg.css('left')) - _.scrollbarWidth, + }).width(dlg.width() + _.scrollbarWidth); + } + }, 1); +};/** This file is part of KCFinder project + * + * @desc Image viewer + * @package KCFinder + * @version 3.12 + * @author Pavel Tzonkov + * @copyright 2010-2014 KCFinder Project + * @license http://opensource.org/licenses/GPL-3.0 GPLv3 + * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3 + * @link http://kcfinder.sunhater.com + */ + +_.viewImage = function(data) { + + var ts = new Date().getTime(), + dlg = false, + images = [], + min_h = 100, + w = $(window), + min_w, dd, dv, dh, + + showImage = function(data) { + _.lock = true; + + var url = $.$.escapeDirs(_.uploadURL + "/" + _.dir + "/" + data.name) + "?ts=" + ts, + img = new Image(), + i = $(img), + + onImgLoad = function() { + _.lock = false; + + $('#files .file').each(function() { + if ($(this).data('name') == data.name) { + _.ssImage = this; + return false; + } + }); + + i.hide().appendTo('body'); + + var w_w = w.width(), + w_h = w.height(), + o_w = i.width(), + o_h = i.height(), + i_w = o_w, + i_h = o_h, + openDlg = false, + t = $('
        '), + + goTo = function(i) { + if (!_.lock) { + var nimg = images[i]; + _.currImg = i; + showImage(nimg); + } + }, + + nextFunc = function() { + goTo((_.currImg >= images.length - 1) ? 0 : (_.currImg + 1)); + }, + + prevFunc = function() { + goTo((_.currImg ? _.currImg : images.length) - 1); + }, + + selectFunc = function(e) { + if (_.ssImage) + _.selectFile($(_.ssImage), e); + dlg.dialog('destroy').detach(); + }; + + i.detach().appendTo(t); + + if (!dlg) { + openDlg = true; + + var closeFunc = function() { + dlg.dialog('destroy').detach(); + }, + + focusFunc = function() { + setTimeout(function() { + dlg.find('input').get(0).focus(); + }, 100); + }; + + dlg = _.dialog(".", "", { + draggable: false, + nopadding: true, + close: closeFunc, + show: false, + hide: false, + buttons: [ + { + text: _.label("Previous"), + icons: {primary: "ui-icon-triangle-1-w"}, + click: prevFunc + + }, { + text: _.label("Next"), + icons: {secondary: "ui-icon-triangle-1-e"}, + click: nextFunc + + }, { + text: _.label("Select"), + icons: {primary: "ui-icon-check"}, + click: selectFunc + + }, { + text: _.label("Close"), + icons: {primary: "ui-icon-closethick"}, + click: closeFunc + } + ] + }); + + dlg.click(nextFunc).css({overflow: "hidden"}).parent().css({width: "auto", height: "auto"}); + + dd = dlg.parent().click(focusFunc).rightClick(focusFunc).disableTextSelect().addClass('kcfImageViewer'); + dv = dd.find('.ui-dialog-titlebar').outerHeight() + dd.find('.ui-dialog-buttonpane').outerHeight() + dd.outerVSpace('b'); + dh = dd.outerHSpace('b'); + min_w = dd.outerWidth() - dh; + } + + var max_w = w_w - dh, + max_h = w_h - dv + 1, + top = 0, + left = 0, + width = o_w, + height = o_h; + + // Too big + if ((o_w > max_w) || (o_h > max_h)) { + + if ((max_h / max_w) < (o_h / o_w)) { + height = max_h; + width = (o_w * height) / o_h; + + } else { + width = max_w; + height = (o_h * width) / o_w; + } + + i_w = width; + i_h = height; + + // Too small + } else if ((o_w < min_w) || (o_h < min_h)) { + width = (o_w < min_w) ? min_w : o_w; + height = (o_h < min_h) ? min_h : o_h; + left = (o_w < min_w) ? (min_w - o_w) / 2 : 0; + top = (o_h < min_h) ? (min_h - o_h) / 2 : 0; + } + + var show = function() { + dlg.animate({width: width, height: height}, 150); + dlg.parent().animate({top: (w_h - height - dv) / 2, left: (w_w - width - dh) / 2}, 150, function() { + dlg.html(t.get(0)).append(''); + dlg.find('input').keydown(function(e) { + if (!_.lock) { + if (e.metaKey || e.ctrlKey || e.altKey || e.shiftKey) + return; + var kc = e.keyCode; + if ((kc == 37)) prevFunc(); + if ((kc == 39)) nextFunc(); + if ((kc == 13) || (kc == 32)) selectFunc(e); + } + }).get(0).focus(); + i.css({padding: top + "px 0 0 " + left + "px", width: i_w, height: i_h}).show(); + dlg.children().first().css({width: width, height: height, display: "none"}).fadeIn(150, function() { + loadingStop(); + var title = data.name + " (" + o_w + " x " + o_h + ")"; + dlg.prev().find('.ui-dialog-title').css({width:width - dlg.prev().find('.ui-dialog-titlebar-close').outerWidth() - 20}).text(title).attr({title: title}).css({cursor: "default"}); + }); + }); + } + + if (openDlg) + show(); + else + dlg.children().first().fadeOut(150, show); + }, + + loadingStart = function() { + if (dlg) + dlg.prev().addClass("loading").find('.ui-dialog-title').text(_.label("Loading image...")).css({width: "auto"}); + else + $('#loading').text(_.label("Loading image...")).show(); + }, + + loadingStop = function() { + if (dlg) + dlg.prev().removeClass("loading"); + $('#loading').hide(); + }; + + loadingStart(); + img.src = url; + + if (img.complete) + onImgLoad(); + else { + img.onload = onImgLoad; + img.onerror = function() { + _.lock = false; + loadingStop(); + _.alert(_.label("Unknown error.")); + _.refresh(); + }; + } + }; + + $.each(_.files, function(i, file) { + i = images.length; + if (file.thumb || file.smallThumb) + images[i] = file; + if (file.name == data.name) + _.currImg = i; + }); + + showImage(data); + return false; +}; +/** This file is part of KCFinder project + * + * @desc Clipboard functionality + * @package KCFinder + * @version 3.12 + * @author Pavel Tzonkov + * @copyright 2010-2014 KCFinder Project + * @license http://opensource.org/licenses/GPL-3.0 GPLv3 + * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3 + * @link http://kcfinder.sunhater.com + */ + +_.initClipboard = function() { + if (!_.clipboard || !_.clipboard.length) return; + + var size = 0, + jClipboard = $('#clipboard'); + + $.each(_.clipboard, function(i, val) { + size += val.size; + }); + size = _.humanSize(size); + jClipboard.disableTextSelect().html('
        '); + var resize = function() { + jClipboard.css({ + left: $(window).width() - jClipboard.outerWidth(), + top: $(window).height() - jClipboard.outerHeight() + }); + }; + resize(); + jClipboard.show(); + $(window).unbind().resize(function() { + _.resize(); + resize(); + }); +}; + +_.removeFromClipboard = function(i) { + if (!_.clipboard || !_.clipboard[i]) return false; + if (_.clipboard.length == 1) { + _.clearClipboard(); + _.menu.hide(); + return; + } + + if (i < _.clipboard.length - 1) { + var last = _.clipboard.slice(i + 1); + _.clipboard = _.clipboard.slice(0, i); + _.clipboard = _.clipboard.concat(last); + } else + _.clipboard.pop(); + + _.initClipboard(); + _.menu.hide(); + _.openClipboard(); + return true; +}; + +_.copyClipboard = function(dir) { + if (!_.clipboard || !_.clipboard.length) return; + var files = [], + failed = 0; + for (i = 0; i < _.clipboard.length; i++) + if (_.clipboard[i].readable) + files[i] = _.clipboard[i].dir + "/" + _.clipboard[i].name; + else + failed++; + if (_.clipboard.length == failed) { + _.alert(_.label("The files in the Clipboard are not readable.")); + return; + } + var go = function(callBack) { + if (dir == _.dir) + _.fadeFiles(); + $.ajax({ + type: "post", + dataType: "json", + url: _.getURL("cp_cbd"), + data: {dir: dir, files: files}, + async: false, + success: function(data) { + if (callBack) callBack(); + _.check4errors(data); + _.clearClipboard(); + if (dir == _.dir) + _.refresh(); + }, + error: function() { + if (callBack) callBack(); + $('#files > div').css({ + opacity: "", + filter: "" + }); + _.alert(_.label("Unknown error.")); + } + }); + }; + + if (failed) + _.confirm( + _.label("{count} files in the Clipboard are not readable. Do you want to copy the rest?", {count:failed}), + go + ) + else + go(); + +}; + +_.moveClipboard = function(dir) { + if (!_.clipboard || !_.clipboard.length) return; + var files = [], + failed = 0; + for (i = 0; i < _.clipboard.length; i++) + if (_.clipboard[i].readable && _.clipboard[i].writable) + files[i] = _.clipboard[i].dir + "/" + _.clipboard[i].name; + else + failed++; + if (_.clipboard.length == failed) { + _.alert(_.label("The files in the Clipboard are not movable.")) + return; + } + + var go = function(callBack) { + _.fadeFiles(); + $.ajax({ + type: "post", + dataType: "json", + url: _.getURL("mv_cbd"), + data: {dir: dir, files: files}, + async: false, + success: function(data) { + if (callBack) callBack(); + _.check4errors(data); + _.clearClipboard(); + _.refresh(); + }, + error: function() { + if (callBack) callBack(); + $('#files > div').css({ + opacity: "", + filter: "" + }); + _.alert(_.label("Unknown error.")); + } + }); + }; + + if (failed) + _.confirm( + _.label("{count} files in the Clipboard are not movable. Do you want to move the rest?", {count: failed}), + go + ); + else + go(); +}; + +_.deleteClipboard = function() { + if (!_.clipboard || !_.clipboard.length) return; + var files = [], + failed = 0; + for (i = 0; i < _.clipboard.length; i++) + if (_.clipboard[i].readable && _.clipboard[i].writable) + files[i] = _.clipboard[i].dir + "/" + _.clipboard[i].name; + else + failed++; + if (_.clipboard.length == failed) { + _.alert(_.label("The files in the Clipboard are not removable.")) + return; + } + var go = function(callBack) { + _.fadeFiles(); + $.ajax({ + type: "post", + dataType: "json", + url: _.getURL("rm_cbd"), + data: {files:files}, + async: false, + success: function(data) { + if (callBack) callBack(); + _.check4errors(data); + _.clearClipboard(); + _.refresh(); + }, + error: function() { + if (callBack) callBack(); + $('#files > div').css({ + opacity: "", + filter: "" + }); + _.alert(_.label("Unknown error.")); + } + }); + }; + if (failed) + _.confirm( + _.label("{count} files in the Clipboard are not removable. Do you want to delete the rest?", {count: failed}), + go + ); + else + go(); +}; + +_.downloadClipboard = function() { + if (!_.clipboard || !_.clipboard.length) return; + var files = []; + for (i = 0; i < _.clipboard.length; i++) + if (_.clipboard[i].readable) + files[i] = _.clipboard[i].dir + "/" + _.clipboard[i].name; + if (files.length) + _.post(_.getURL('downloadClipboard'), {files:files}); +}; + +_.clearClipboard = function() { + $('#clipboard').html(""); + _.clipboard = []; +}; +/** This file is part of KCFinder project + * + * @desc Upload files using drag and drop + * @package KCFinder + * @version 3.12 + * @author Pavel Tzonkov + * @copyright 2010-2014 KCFinder Project + * @license http://opensource.org/licenses/GPL-3.0 GPLv3 + * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3 + * @link http://kcfinder.sunhater.com + */ + +_.initDropUpload = function() { + + if (!_.access.files.upload) + return; + + var files = $('#files'), + folders = $('#folders').find('div.folder > a'), + i, dlg, filesSize, uploaded, errors, + + precheck = function(e) { + filesSize = uploaded = 0; errors = []; + var fs = e.dataTransfer.files; + for (i = 0; i < fs.length; i++) + filesSize += fs[i].size; + + dlg = $('
         
         
         
        '); + + dlg.find('.bar.count').progressbar({max: fs.length, value: 0}); + dlg.find('.bar.size').progressbar({max: filesSize, value: 0}); + dlg.find('.info').css('padding', "5px 0").first().css('paddingTop', 0); + dlg.find('.info').last().css('paddingBottom', 0); + + dlg = _.dialog(_.label("Uploading files"), dlg, { + closeOnEscape: false, + buttons: [] + }); + + dlg.parent().css('paddingBottom', 0).find('.ui-dialog-titlebar button').css('visibility', 'hidden').get(0).disabled = true; + + return true; + }, + + localOptions = { + param: "upload[]", + maxFilesize: _.dropUploadMaxFilesize, + + begin: function(xhr, currentFile, count) { + + dlg.find('.info.count').html(_.label("Uploading file {current} of {count}", { + current: currentFile, + count: count + })); + + dlg.find('.info.size').html(_.label("Uploaded {uploaded} of {total}", { + uploaded: _.humanSize(uploaded), + total: _.humanSize(filesSize) + })); + + dlg.find('.info.errors').html(_.label("Errors:") + " " + errors.length); + dlg.find('.bar.count').progressbar({value: currentFile}); + dlg.find('.bar.size').progressbar({value: uploaded}); + }, + + success: function(xhr, currentFile, count) { + uploaded += xhr.file.size; + var response = xhr.responseText; + if (response.substr(0, 1) != "/") + errors.push($.$.htmlData(response)); + }, + + error: function(xhr, currentFile, count) { + uploaded += xhr.file.size; + errors.push($.$.htmlData(xhr.file.name + ": " + _.label("Failed to upload {filename}!", { + filename: xhr.file.name + }))); + }, + + abort: function(xhr, currentFile, filesCount) { + uploaded += xhr.file.size; + errors.push($.$.htmlData(xhr.file.name + ": " + _.label("Failed to upload {filename}!", { + filename: xhr.file.name + }))); + }, + + filesizeCallback: function(xhr, currentFile, filesCount) { + uploaded += xhr.file.size; + errors.push($.$.htmlData(xhr.file.name + ": " + _.label("The uploaded file exceeds {size} bytes.", { + size: _.dropUploadMaxFilesize + }))); + }, + + finish: function() { + _.refresh(); + dlg.find('.bar.size').progressbar({value: uploaded}); + dlg.find('.info.size').html(_.label("Uploaded: {uploaded} of {total}", { + uploaded: _.humanSize(uploaded), + total: _.humanSize(filesSize) + })); + dlg.find('.info.errors').html(_.label("Errors:") + " " + errors.length); + var err = errors; + setTimeout(function() { + dlg.dialog('destroy').detach(); + if (err.length) + _.alert(err.join('
        ')); + }, 500); + } + }, + + remoteOptions = { + ajax: { + success: function(data) { + _.refresh(); + if (data.error) { + _.alert(data.error) + return; + } + }, + error: function() { + _.refresh(); + _.alert(_.label("Unknown error.")); + }, + abort: function() { + _.refresh(); + } + } + }, + + url = "&dir=" + encodeURIComponent(_.dir); + + files.shDropUpload($.extend(localOptions, { + url: _.getURL('upload') + url, + precheck: function(e) { + if (!$('#folders span.current').first().parent().data('writable')) { + _.alert(_.label("Cannot write to upload folder.")); + return false; + } + return precheck(e); + } + }), $.extend(true, remoteOptions, { + ajax: { + url: _.getURL('dragUrl') + url + } + })); + + folders.each(function() { + var folder = this, + url = "&dir=" + encodeURIComponent($(folder).data('path')); + $(folder).shDropUpload($.extend(localOptions, { + url: _.getURL('upload') + url, + precheck: function(e) { + if (!$(folder).data('writable')) { + _.alert(_.label("Cannot write to upload folder.")); + return false; + } + return precheck(e); + } + }), $.extend(true, remoteOptions, { + ajax: { + url: _.getURL('dragUrl') + url + } + })); + }); +}; +/** This file is part of KCFinder project + * + * @desc Miscellaneous functionality + * @package KCFinder + * @version 3.12 + * @author Pavel Tzonkov + * @copyright 2010-2014 KCFinder Project + * @license http://opensource.org/licenses/GPL-3.0 GPLv3 + * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3 + * @link http://kcfinder.sunhater.com + */ + +_.orderFiles = function(callBack, selected) { + var order = $.$.kuki.get('order'), + desc = ($.$.kuki.get('orderDesc') == "on"), + a1, b1, arr; + + if (!_.files || !_.files.sort) + _.files = []; + + _.files = _.files.sort(function(a, b) { + if (!order) order = "name"; + + if (order == "date") { + a1 = a.mtime; + b1 = b.mtime; + } else if (order == "type") { + a1 = $.$.getFileExtension(a.name); + b1 = $.$.getFileExtension(b.name); + } else if (order == "size") { + a1 = a.size; + b1 = b.size; + } else { + a1 = a[order].toLowerCase(); + b1 = b[order].toLowerCase(); + } + + if ((order == "size") || (order == "date")) { + if (a1 < b1) return desc ? 1 : -1; + if (a1 > b1) return desc ? -1 : 1; + } + + if (a1 == b1) { + a1 = a.name.toLowerCase(); + b1 = b.name.toLowerCase(); + arr = [a1, b1]; + arr = arr.sort(); + return (arr[0] == a1) ? -1 : 1; + } + + arr = [a1, b1]; + arr = arr.sort(); + if (arr[0] == a1) return desc ? 1 : -1; + return desc ? -1 : 1; + }); + + _.showFiles(callBack, selected); + _.initFiles(); +}; + +_.humanSize = function(size) { + if (size < 1024) { + size = size.toString() + " B"; + } else if (size < 1048576) { + size /= 1024; + size = parseInt(size).toString() + " KB"; + } else if (size < 1073741824) { + size /= 1048576; + size = parseInt(size).toString() + " MB"; + } else if (size < 1099511627776) { + size /= 1073741824; + size = parseInt(size).toString() + " GB"; + } else { + size /= 1099511627776; + size = parseInt(size).toString() + " TB"; + } + return size; +}; + +_.getURL = function(act, lang) { + if (!lang) + lang = _.lang; + var url = "browse.php?type=" + encodeURIComponent(_.type) + "&lng=" + encodeURIComponent(lang); + if (_.opener.name) + url += "&opener=" + encodeURIComponent(_.opener.name); + if (act) + url += "&act=" + encodeURIComponent(act); + if (_.cms) + url += "&cms=" + encodeURIComponent(_.cms); + return url; +}; + +_.label = function(index, data) { + var label = _.labels[index] ? _.labels[index] : index; + if (data) + $.each(data, function(key, val) { + label = label.replace("{" + key + "}", val); + }); + return label; +}; + +_.check4errors = function(data) { + if (!data.error) + return false; + var msg = data.error.join + ? data.error.join("\n") + : data.error; + _.alert(msg); + return true; +}; + +_.post = function(url, data) { + var html = '
        '; + $.each(data, function(key, val) { + if ($.isArray(val)) + $.each(val, function(i, aval) { + html += ''; + }); + else + html += ''; + }); + html += '
        '; + $('#menu').html(html).show(); + $('#postForm').get(0).submit(); +}; + +_.fadeFiles = function() { + $('#files > div').css({ + opacity: "0.4", + filter: "alpha(opacity=40)" + }); +}; diff --git a/lib/kcfinder/cache/theme_dark.css b/lib/kcfinder/cache/theme_dark.css new file mode 100644 index 0000000..bde5f16 --- /dev/null +++ b/lib/kcfinder/cache/theme_dark.css @@ -0,0 +1 @@ +.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-clearfix{min-height:0}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:alpha(opacity=0)}.ui-front{z-index:100}.ui-widget .ui-widget,.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-size:1em}.ui-widget-content{border:1px solid #888;background:#000;color:#aaa}.ui-widget-content a{color:#aaa}.ui-widget-header{border:1px solid #4685b3;color:#fff;font-weight:bold;background:#184977;background:-webkit-linear-gradient(top,#184977,#4685b3);background:-moz-linear-gradient(top,#184977,#4685b3);background:-ms-linear-gradient(top,#184977,#4685b3);background:-o-linear-gradient(top,#184977,#4685b3);background:linear-gradient(to bottom,#184977,#4685b3)}.ui-widget-header a{color:#fff}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default,.ui-widget.ui-state-disabled{transition:.2s;border:1px solid #555;background:#333;background:-webkit-linear-gradient(top,#555,#111);background:-moz-linear-gradient(top,#555,#111);background:-ms-linear-gradient(top,#555,#111);background:-o-linear-gradient(top,#555,#111);background:linear-gradient(to bottom,#555,#111);font-weight:bold;color:#aaa}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus{transition:.2s;background:-webkit-linear-gradient(top,#111,#555);background:-moz-linear-gradient(top,#111,#555);background:-ms-linear-gradient(top,#111,#555);background:-o-linear-gradient(top,#111,#555);background:linear-gradient(to bottom,#111,#555)}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active,.ui-menu .ui-state-focus{transition:.2s;border:1px solid #184977;background:#4685b3;background:-webkit-linear-gradient(top,#184977,#4685b3);background:-moz-linear-gradient(top,#184977,#4685b3);background:-ms-linear-gradient(top,#184977,#4685b3);background:-o-linear-gradient(top,#184977,#4685b3);background:linear-gradient(to bottom,#184977,#4685b3);font-weight:bold;color:#fff}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited,.ui-state-hover a,.ui-state-hover a:hover,.ui-state-hover a:link,.ui-state-hover a:visited,.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{transition:.2s;color:#fff;text-decoration:none}.ui-menu .ui-state-active{transition:.2s;border-color:#6b6b6b;background:#6b6b6b;background:-webkit-linear-gradient(top,#6b6b6b,#ababab);background:-moz-linear-gradient(top,#6b6b6b,#ababab);background:-ms-linear-gradient(top,#6b6b6b,#ababab);background:-o-linear-gradient(top,#6b6b6b,#ababab);background:linear-gradient(to bottom,#6b6b6b,#ababab)}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #d5bc2c;box-shadow:inset 0 0 5px #d5bc2c;background:#fff6bf;color:#aaa}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #cf7f7f;box-shadow:inset 0 0 5px #cf7f7f;background:#fac4c4;color:#aaa}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a,.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a,.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#aaa}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:bold}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.5;filter:alpha(opacity=50);font-weight:normal}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.50;filter:alpha(opacity=50);background-image:none}.ui-state-disabled .ui-icon{filter:alpha(opacity=50)}.ui-state-disabled{cursor:default !important}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:.1px;display:block}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px}.ui-selectable-helper{position:absolute;z-index:100;border:1px dotted black}.ui-accordion .ui-accordion-header{display:block;cursor:pointer;position:relative;margin-top:2px;padding:6px;min-height:0}.ui-accordion .ui-accordion-icons,.ui-accordion .ui-accordion-icons .ui-accordion-icons{padding-left:24px}.ui-accordion .ui-accordion-noicons{padding-left:5px}.ui-accordion .ui-accordion-header .ui-accordion-header-icon{position:absolute;left:5px;top:50%;margin-top:-8px}.ui-accordion .ui-accordion-content{padding:1em;border-top:0;overflow:auto}.ui-autocomplete{position:absolute;top:0;left:0;cursor:pointer}.ui-button{display:inline-block;position:relative;padding:0;line-height:normal;cursor:pointer;vertical-align:middle;text-align:center;overflow:visible}.ui-button,.ui-button:link,.ui-button:visited,.ui-button:hover,.ui-button:active{text-decoration:none}.ui-button-icon-only{width:36px}.ui-button-icons-only{width:50px}.ui-button .ui-button-text{display:block;line-height:normal}.ui-button-text-only .ui-button-text{padding:6px 10px}.ui-button-icon-only .ui-button-text,.ui-button-icons-only .ui-button-text{padding:6px;text-indent:-9999999px}.ui-button-text-icon-primary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:6px 10px 6px 28px}.ui-button-text-icon-secondary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:6px 28px 6px 10px}.ui-button-text-icons .ui-button-text{padding-left:28px;padding-right:28px}input.ui-button{padding:6px 10px}.ui-button-icon-only .ui-icon,.ui-button-text-icon-primary .ui-icon,.ui-button-text-icon-secondary .ui-icon,.ui-button-text-icons .ui-icon,.ui-button-icons-only .ui-icon{position:absolute;top:50%;margin-top:-8px}.ui-button-icon-only .ui-icon{left:50%;margin-left:-8px}.ui-button-text-icon-primary .ui-button-icon-primary,.ui-button-text-icons .ui-button-icon-primary,.ui-button-icons-only .ui-button-icon-primary{left:7px}.ui-button-text-icon-secondary .ui-button-icon-secondary,.ui-button-text-icons .ui-button-icon-secondary,.ui-button-icons-only .ui-button-icon-secondary{right:7px}input.ui-button::-moz-focus-inner,button.ui-button::-moz-focus-inner{border:0;padding:0}.ui-buttonset{margin:0;overflow:auto}.ui-buttonset .ui-button{margin:0;float:left}.ui-datepicker{width:19em;display:none;padding:10px}.ui-datepicker .ui-datepicker-header{position:relative;padding:2px 0}.ui-datepicker .ui-datepicker-prev,.ui-datepicker .ui-datepicker-next{position:absolute;top:4px;width:20px;height:20px}.ui-datepicker .ui-datepicker-prev-hover,.ui-datepicker .ui-datepicker-next-hover{top:3px}.ui-datepicker .ui-datepicker-prev{left:4px}.ui-datepicker .ui-datepicker-next{right:4px}.ui-datepicker .ui-datepicker-prev-hover{left:3px}.ui-datepicker .ui-datepicker-next-hover{right:3px}.ui-datepicker .ui-datepicker-prev span,.ui-datepicker .ui-datepicker-next span{display:block;position:absolute;left:50%;margin-left:-8px;top:50%;margin-top:-8px}.ui-datepicker .ui-datepicker-title{margin:0 10px;padding:4px 0;text-align:center}.ui-datepicker .ui-datepicker-title select{font-size:1em;margin:-2px 2px;padding:0;outline:0}.ui-datepicker table{width:100%;border-collapse:collapse;margin:0;font-size:1em}.ui-datepicker th{padding:3px;text-align:center;font-weight:bold;border:0}.ui-datepicker td{border:0;padding:1px}.ui-datepicker td span,.ui-datepicker td a{display:block;padding:2px 3px;text-align:right;text-decoration:none}.ui-datepicker .ui-datepicker-buttonpane{background-image:none;margin:10px -11px -11px -11px;padding:10px;border:1px solid #184977;background:#e4f5ff;overflow:auto}.ui-datepicker .ui-datepicker-buttonpane button{float:right;cursor:pointer;width:auto;overflow:visible;margin:0;padding:6px 10px;font-weight:bold;opacity:1;filter:alpha(opacity=100)}.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current{float:left}.ui-datepicker.ui-datepicker-multi{width:auto;padding:10px}.ui-datepicker-multi .ui-datepicker-group{float:left}.ui-datepicker-multi .ui-datepicker-group .ui-datepicker-header{margin:0}.ui-datepicker-multi .ui-datepicker-group.ui-datepicker-group-last{margin-right:0}.ui-datepicker-multi .ui-datepicker-group table{width:95%;margin:0 auto .4em}.ui-datepicker-multi-2 .ui-datepicker-group{width:50%}.ui-datepicker-multi-3 .ui-datepicker-group{width:33.3%}.ui-datepicker-multi-4 .ui-datepicker-group{width:25%}.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header{border-left-width:0}.ui-datepicker-multi .ui-datepicker-buttonpane{clear:left}.ui-datepicker-row-break{clear:both;font-size:0;width:100px}th.ui-datepicker-week-col{color:#215b82}td.ui-datepicker-week-col{text-align:right;padding-right:7px;color:#215b82}td.ui-datepicker-other-month a.ui-state-default{font-weight:bold}th.ui-datepicker-week-end{color:#f44}.ui-datepicker-rtl{direction:rtl}.ui-datepicker-rtl .ui-datepicker-prev{right:2px;left:auto}.ui-datepicker-rtl .ui-datepicker-next{left:2px;right:auto}.ui-datepicker-rtl .ui-datepicker-prev:hover{right:1px;left:auto}.ui-datepicker-rtl .ui-datepicker-next:hover{left:1px;right:auto}.ui-datepicker-rtl .ui-datepicker-buttonpane{clear:right}.ui-datepicker-rtl .ui-datepicker-buttonpane button{float:left}.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,.ui-datepicker-rtl .ui-datepicker-group{float:right}.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header{border-right-width:0;border-left-width:1px}.ui-dialog{position:absolute;top:0;left:0;padding:4px;outline:0;box-shadow:0 0 10px #000}.ui-dialog .ui-dialog-titlebar{padding:5px 10px;position:relative}.ui-dialog .ui-dialog-title{float:left;margin:0;padding:1px 0;white-space:nowrap;width:90%;overflow:hidden;text-overflow:ellipsis}.ui-dialog .ui-dialog-titlebar-close{position:absolute;right:.3em;top:50%;width:21px;margin:-10px 0 0 0;padding:1px;height:20px}.ui-dialog .ui-dialog-content{position:relative;border:0;padding:1em;margin:0 -4px;background:0;overflow:auto}.ui-dialog .ui-dialog-buttonpane{text-align:left;border-width:1px 0 0 0;background-image:none;padding:10px}.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:right}.ui-dialog .ui-dialog-buttonpane button{margin:0 0 0 5px;cursor:pointer}.ui-dialog .ui-resizable-se{width:12px;height:12px;right:-5px;bottom:-5px;background-position:16px 16px}.ui-draggable .ui-dialog-titlebar{cursor:move}.ui-menu{list-style:none;padding:0;margin:0;display:block;outline:0}.ui-menu .ui-menu{margin-top:-3px;position:absolute}.ui-menu .ui-menu-item{margin:0;padding:0;width:100%;list-style-image:url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)}.ui-menu .ui-menu-divider{margin:1px 10px 1px 10px;height:0;font-size:0;line-height:0;border-width:1px 0 0 0;border-color:#777}.ui-menu .ui-menu-item a{text-decoration:none;display:block;padding:5px 10px;line-height:1.5;min-height:0;font-weight:normal;border-radius:0}.ui-menu .ui-menu-item a.ui-state-focus,.ui-menu .ui-menu-item a.ui-state-active{font-weight:normal;margin:-1px;transition:none}.ui-menu .ui-state-disabled{font-weight:normal;line-height:1.5}.ui-menu .ui-state-disabled a{cursor:default}.ui-menu.ui-corner-all.sh-menu{border-radius:4px}.ui-menu.ui-corner-all,.ui-menu.sh-menu.ui-autocomplete.ui-corner-all{border-radius:0}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item a{position:relative;padding-left:2em}.ui-menu .ui-icon{position:absolute;top:.2em;left:.2em}.ui-menu .ui-menu-icon{position:static;float:right}.ui-progressbar{height:2.1em;text-align:left;overflow:hidden}.ui-progressbar .ui-progressbar-value{margin:-1px;height:100%}.ui-progressbar .ui-progressbar-overlay{height:100%;filter:alpha(opacity=25);opacity:.25}.ui-progressbar-indeterminate .ui-progressbar-value{background-image:none}.ui-slider{position:relative;text-align:left;margin:0 13px;border-radius:15px}.ui-slider .ui-slider-handle{position:absolute;z-index:2;width:18px;height:18px;border-radius:9px;cursor:default;box-shadow:0 0 3px #aaa,inset 0 0 7px #fff,inset 0 0 3px #fff}.ui-slider .ui-slider-handle.ui-state-active{box-shadow:0 0 3px #4685b3,inset 0 0 7px #fff,inset 0 0 3px #fff}.ui-slider .ui-slider-range{position:absolute;z-index:1;display:block;border:0;background-position:0 0}.ui-slider.ui-state-disabled .ui-slider-handle,.ui-slider.ui-state-disabled .ui-slider-range{filter:inherit}.ui-slider-horizontal{height:10px}.ui-slider-horizontal .ui-slider-handle{top:-5px;margin-left:-9px}.ui-slider-horizontal .ui-slider-range{top:0;height:100%}.ui-slider-horizontal .ui-slider-range-min{left:0}.ui-slider-horizontal .ui-slider-range-max{right:0}.ui-slider-vertical{width:10px;height:150px}.ui-slider-vertical .ui-slider-handle{left:-5px;margin-left:0;margin-bottom:-9px}.ui-slider-vertical .ui-slider-range{left:-1px;width:100%}.ui-slider-vertical .ui-slider-range-min{bottom:0}.ui-slider-vertical .ui-slider-range-max{top:0}.ui-spinner.ui-widget{position:relative;display:inline-block;overflow:hidden;padding:0;vertical-align:middle;background:#fff;background:-webkit-linear-gradient(top,#f0f0f0,#fff);background:-moz-linear-gradient(top,#f0f0f0,#fff);background:-ms-linear-gradient(top,#f0f0f0,#fff);background:-o-linear-gradient(top,#f0f0f0,#fff);background:linear-gradient(to bottom,#f0f0f0,#fff)}.ui-spinner-input{border:0;color:inherit;padding:0;margin:6px 24px 6px 10px;vertical-align:middle;outline:0;background:transparent}.ui-spinner-input{color:#aaa}.ui-spinner-input:focus{color:#000}.ui-spinner-button{width:16px;height:50%;font-size:.5em;padding:0;margin:0;text-align:center;position:absolute;cursor:default;display:block;overflow:hidden;right:0}.ui-spinner a.ui-spinner-button{border-top:0;border-bottom:0;border-right:0}.ui-spinner .ui-icon{position:absolute;margin-top:-8px;top:50%;left:0}.ui-spinner-up{top:0}.ui-spinner-down{bottom:0}.ui-spinner .ui-icon-triangle-1-s{background-position:-65px -16px}.ui-tabs{position:relative}.ui-tabs .ui-tabs-nav{margin:0;padding:3px 3px 0 3px}.ui-tabs .ui-tabs-nav li{list-style:none;float:left;position:relative;top:0;margin:1px 3px 0 0;border-bottom-width:0;padding:0;white-space:nowrap}.ui-tabs .ui-tabs-nav li a{float:left;padding:6px 10px;text-decoration:none}.ui-tabs .ui-tabs-nav li.ui-tabs-active{margin-bottom:-1px;padding-bottom:1px}.ui-tabs .ui-tabs-nav li.ui-tabs-active a,.ui-tabs .ui-tabs-nav li.ui-state-disabled a,.ui-tabs .ui-tabs-nav li.ui-tabs-loading a{cursor:text}.ui-tabs .ui-tabs-nav li a,.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a{cursor:pointer}.ui-tabs .ui-tabs-panel{display:block;border-width:0;padding:1em;background:0}body .ui-tooltip{padding:6px 10px;position:absolute;z-index:9999;max-width:300px;color:gray;border-color:#a5a5a5;box-shadow:inset 0 0 4px #a5a5a5,0 0 4px #a5a5a5;background:-webkit-linear-gradient(top,#ddd,#fff);background:-moz-linear-gradient(top,#ddd,#fff);background:-ms-linear-gradient(top,#ddd,#fff);background:-o-linear-gradient(top,#ddd,#fff);background:linear-gradient(to bottom,#ddd,#fff)}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat;width:16px;height:16px}.ui-icon,.ui-button.ui-state-active .ui-icon,.ui-dialog .ui-dialog-titlebar-close .ui-icon{background-image:url(img/ui-icons_white.png)}.ui-button .ui-icon{background-image:url(img/ui-icons_grey.png)}.ui-icon-blank{background-position:16px 16px}.ui-icon-carat-1-n{background-position:0 0}.ui-icon-carat-1-ne{background-position:-16px 0}.ui-icon-carat-1-e{background-position:-32px 0}.ui-icon-carat-1-se{background-position:-48px 0}.ui-icon-carat-1-s{background-position:-64px 0}.ui-icon-carat-1-sw{background-position:-80px 0}.ui-icon-carat-1-w{background-position:-96px 0}.ui-icon-carat-1-nw{background-position:-112px 0}.ui-icon-carat-2-n-s{background-position:-128px 0}.ui-icon-carat-2-e-w{background-position:-144px 0}.ui-icon-triangle-1-n{background-position:0 -16px}.ui-icon-triangle-1-ne{background-position:-16px -16px}.ui-icon-triangle-1-e{background-position:-32px -16px}.ui-icon-triangle-1-se{background-position:-48px -16px}.ui-icon-triangle-1-s{background-position:-64px -16px}.ui-icon-triangle-1-sw{background-position:-80px -16px}.ui-icon-triangle-1-w{background-position:-96px -16px}.ui-icon-triangle-1-nw{background-position:-112px -16px}.ui-icon-triangle-2-n-s{background-position:-128px -16px}.ui-icon-triangle-2-e-w{background-position:-144px -16px}.ui-icon-arrow-1-n{background-position:0 -32px}.ui-icon-arrow-1-ne{background-position:-16px -32px}.ui-icon-arrow-1-e{background-position:-32px -32px}.ui-icon-arrow-1-se{background-position:-48px -32px}.ui-icon-arrow-1-s{background-position:-64px -32px}.ui-icon-arrow-1-sw{background-position:-80px -32px}.ui-icon-arrow-1-w{background-position:-96px -32px}.ui-icon-arrow-1-nw{background-position:-112px -32px}.ui-icon-arrow-2-n-s{background-position:-128px -32px}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px}.ui-icon-arrow-2-e-w{background-position:-160px -32px}.ui-icon-arrow-2-se-nw{background-position:-176px -32px}.ui-icon-arrowstop-1-n{background-position:-192px -32px}.ui-icon-arrowstop-1-e{background-position:-208px -32px}.ui-icon-arrowstop-1-s{background-position:-224px -32px}.ui-icon-arrowstop-1-w{background-position:-240px -32px}.ui-icon-arrowthick-1-n{background-position:0 -48px}.ui-icon-arrowthick-1-ne{background-position:-16px -48px}.ui-icon-arrowthick-1-e{background-position:-32px -48px}.ui-icon-arrowthick-1-se{background-position:-48px -48px}.ui-icon-arrowthick-1-s{background-position:-64px -48px}.ui-icon-arrowthick-1-sw{background-position:-80px -48px}.ui-icon-arrowthick-1-w{background-position:-96px -48px}.ui-icon-arrowthick-1-nw{background-position:-112px -48px}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px}.ui-icon-arrowreturn-1-w{background-position:-64px -64px}.ui-icon-arrowreturn-1-n{background-position:-80px -64px}.ui-icon-arrowreturn-1-e{background-position:-96px -64px}.ui-icon-arrowreturn-1-s{background-position:-112px -64px}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px}.ui-icon-arrow-4{background-position:0 -80px}.ui-icon-arrow-4-diag{background-position:-16px -80px}.ui-icon-extlink{background-position:-32px -80px}.ui-icon-newwin{background-position:-48px -80px}.ui-icon-refresh{background-position:-64px -80px}.ui-icon-shuffle{background-position:-80px -80px}.ui-icon-transfer-e-w{background-position:-96px -80px}.ui-icon-transferthick-e-w{background-position:-112px -80px}.ui-icon-folder-collapsed{background-position:0 -96px}.ui-icon-folder-open{background-position:-16px -96px}.ui-icon-document{background-position:-32px -96px}.ui-icon-document-b{background-position:-48px -96px}.ui-icon-note{background-position:-64px -96px}.ui-icon-mail-closed{background-position:-80px -96px}.ui-icon-mail-open{background-position:-96px -96px}.ui-icon-suitcase{background-position:-112px -96px}.ui-icon-comment{background-position:-128px -96px}.ui-icon-person{background-position:-144px -96px}.ui-icon-print{background-position:-160px -96px}.ui-icon-trash{background-position:-176px -96px}.ui-icon-locked{background-position:-192px -96px}.ui-icon-unlocked{background-position:-208px -96px}.ui-icon-bookmark{background-position:-224px -96px}.ui-icon-tag{background-position:-240px -96px}.ui-icon-home{background-position:0 -112px}.ui-icon-flag{background-position:-16px -112px}.ui-icon-calendar{background-position:-32px -112px}.ui-icon-cart{background-position:-48px -112px}.ui-icon-pencil{background-position:-64px -112px}.ui-icon-clock{background-position:-80px -112px}.ui-icon-disk{background-position:-96px -112px}.ui-icon-calculator{background-position:-112px -112px}.ui-icon-zoomin{background-position:-128px -112px}.ui-icon-zoomout{background-position:-144px -112px}.ui-icon-search{background-position:-160px -112px}.ui-icon-wrench{background-position:-176px -112px}.ui-icon-gear{background-position:-192px -112px}.ui-icon-heart{background-position:-208px -112px}.ui-icon-star{background-position:-224px -112px}.ui-icon-link{background-position:-240px -112px}.ui-icon-cancel{background-position:0 -128px}.ui-icon-plus{background-position:-16px -128px}.ui-icon-plusthick{background-position:-32px -128px}.ui-icon-minus{background-position:-48px -128px}.ui-icon-minusthick{background-position:-64px -128px}.ui-icon-close{background-position:-80px -128px}.ui-icon-closethick{background-position:-96px -128px}.ui-icon-key{background-position:-112px -128px}.ui-icon-lightbulb{background-position:-128px -128px}.ui-icon-scissors{background-position:-144px -128px}.ui-icon-clipboard{background-position:-160px -128px}.ui-icon-copy{background-position:-176px -128px}.ui-icon-contact{background-position:-192px -128px}.ui-icon-image{background-position:-208px -128px}.ui-icon-video{background-position:-224px -128px}.ui-icon-script{background-position:-240px -128px}.ui-icon-alert{background-position:0 -144px}.ui-icon-info{background-position:-16px -144px}.ui-icon-notice{background-position:-32px -144px}.ui-icon-help{background-position:-48px -144px}.ui-icon-check{background-position:-64px -144px}.ui-icon-bullet{background-position:-80px -144px}.ui-icon-radio-on{background-position:-96px -144px}.ui-icon-radio-off{background-position:-112px -144px}.ui-icon-pin-w{background-position:-128px -144px}.ui-icon-pin-s{background-position:-144px -144px}.ui-icon-play{background-position:0 -160px}.ui-icon-pause{background-position:-16px -160px}.ui-icon-seek-next{background-position:-32px -160px}.ui-icon-seek-prev{background-position:-48px -160px}.ui-icon-seek-end{background-position:-64px -160px}.ui-icon-seek-start{background-position:-80px -160px}.ui-icon-seek-first{background-position:-80px -160px}.ui-icon-stop{background-position:-96px -160px}.ui-icon-eject{background-position:-112px -160px}.ui-icon-volume-off{background-position:-128px -160px}.ui-icon-volume-on{background-position:-144px -160px}.ui-icon-power{background-position:0 -176px}.ui-icon-signal-diag{background-position:-16px -176px}.ui-icon-signal{background-position:-32px -176px}.ui-icon-battery-0{background-position:-48px -176px}.ui-icon-battery-1{background-position:-64px -176px}.ui-icon-battery-2{background-position:-80px -176px}.ui-icon-battery-3{background-position:-96px -176px}.ui-icon-circle-plus{background-position:0 -192px}.ui-icon-circle-minus{background-position:-16px -192px}.ui-icon-circle-close{background-position:-32px -192px}.ui-icon-circle-triangle-e{background-position:-48px -192px}.ui-icon-circle-triangle-s{background-position:-64px -192px}.ui-icon-circle-triangle-w{background-position:-80px -192px}.ui-icon-circle-triangle-n{background-position:-96px -192px}.ui-icon-circle-arrow-e{background-position:-112px -192px}.ui-icon-circle-arrow-s{background-position:-128px -192px}.ui-icon-circle-arrow-w{background-position:-144px -192px}.ui-icon-circle-arrow-n{background-position:-160px -192px}.ui-icon-circle-zoomin{background-position:-176px -192px}.ui-icon-circle-zoomout{background-position:-192px -192px}.ui-icon-circle-check{background-position:-208px -192px}.ui-icon-circlesmall-plus{background-position:0 -208px}.ui-icon-circlesmall-minus{background-position:-16px -208px}.ui-icon-circlesmall-close{background-position:-32px -208px}.ui-icon-squaresmall-plus{background-position:-48px -208px}.ui-icon-squaresmall-minus{background-position:-64px -208px}.ui-icon-squaresmall-close{background-position:-80px -208px}.ui-icon-grip-dotted-vertical{background-position:0 -224px}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px}.ui-icon-grip-solid-vertical{background-position:-32px -224px}.ui-icon-grip-solid-horizontal{background-position:-48px -224px}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px}.ui-icon-grip-diagonal-se{background-position:-80px -224px}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl,.ui-menu .ui-menu-item.ui-menu-item-first a{border-top-left-radius:4px}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr,.ui-menu .ui-menu-item.ui-menu-item-first a{border-top-right-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl,.ui-menu .ui-menu-item.ui-menu-item-last a,.ui-dialog-buttonpane,.ui-datepicker-multi .ui-datepicker-group-first .ui-datepicker-header,.ui-datepicker .ui-datepicker-buttonpane{border-bottom-left-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br,.ui-menu .ui-menu-item.ui-menu-item-last a,.ui-dialog-buttonpane,.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker .ui-datepicker-buttonpane{border-bottom-right-radius:4px}.ui-widget-overlay{background:rgba(255,255,255,.5)}.ui-widget-shadow{margin:-7px 0 0 -7px;padding:7px;background:rgba(0,0,0,.3);border-radius:8px}.ui-accordion-content-active,.ui-tabs,.ui-slider-range,.ui-datepicker,.ui-dialog{border-color:#4d637c}.ui-slider .ui-slider-range{border:1px solid #4685b3;top:-1px}.ui-progressbar{overflow:visible}.ui-progressbar-value{border:1px solid #4685b3;margin-top:-1px}.ui-button{box-shadow:inset 0 0 3px #555,inset 0 0 6px #555,0 0 3px #000,0 0 2px #000}.ui-button.ui-state-active{box-shadow:inset 0 0 3px #88b9da,0 0 3px #000,0 0 2px #000}.ui-widget-header,.ui-menu-item .ui-state-focus{box-shadow:inset 0 0 3px #88b9da}.ui-state-default,.ui-state-focus,.ui-state-active,.ui-widget-header,fieldset.sh-uniform label,fieldset.sh-uniform legend{text-shadow:1px 0 rgba(0,0,0,.2),-1px 0 rgba(0,0,0,.2),0 -1px rgba(0,0,0,.2),0 1px rgba(0,0,0,.2),1px 1px rgba(0,0,0,.2),-1px -1px rgba(0,0,0,.2),1px -1px rgba(0,0,0,.2),-1px 1px rgba(0,0,0,.2)}.ui-tabs .ui-state-active,.ui-datepicker .ui-state-highlight{text-shadow:none}.ui-datepicker .ui-state-highlight{color:#215b82;border-color:#4685b3;box-shadow:inset 0 0 4px #4685b3;background:#fff;background:-webkit-linear-gradient(top,#dfeef8,#fff);background:-moz-linear-gradient(top,#dfeef8,#fff);background:-ms-linear-gradient(top,#dfeef8,#fff);background:-o-linear-gradient(top,#dfeef8,#fff);background:linear-gradient(to bottom,#dfeef8,#fff)}.ui-progressbar,.ui-slider,.ui-menu{box-shadow:inset 0 0 4px #666,0 0 3px #000,0 0 6px #000;background:#000;background:-webkit-linear-gradient(top,#111,#444);background:-moz-linear-gradient(top,#111,#444);background:-ms-linear-gradient(top,#111,#444);background:-o-linear-gradient(top,#111,#444);background:linear-gradient(to bottom,#111,#444)}.ui-slider,.ui-spinner,.ui-progressbar,.ui-menu{border-color:#555}.ui-datepicker-calendar .ui-state-default{border-radius:3px}.ui-tabs .ui-tabs-nav{margin:-1px;border-bottom-right-radius:0;border-bottom-left-radius:0;padding-left:3px}.ui-tabs-active.ui-state-active{background:#fff;background:-webkit-linear-gradient(top,#ccc,#ddd,#eee,#fff,#fff,#fff);background:-moz-linear-gradient(top,#ccc,#ddd,#eee,#fff,#fff,#fff);background:-ms-linear-gradient(top,#ccc,#ddd,#eee,#fff,#fff,#fff);background:-o-linear-gradient(top,#ccc,#ddd,#eee,#fff,#fff,#fff);background:linear-gradient(to bottom,#ccc,#ddd,#eee,#fff,#fff,#fff);box-shadow:inset 0 0 5px #fff,inset 0 0 5px #fff,inset 0 0 5px #fff}.ui-tabs-active.ui-state-active a{color:#215b82}.ui-state-default,.ui-state-default a{outline:0}.ui-datepicker-header,.ui-dialog-titlebar{border-bottom-right-radius:0;border-bottom-left-radius:0;margin:-5px -5px 0 -5px}.ui-datepicker-header{margin:-11px -11px 5px -11px}.ui-datepicker-header a:hover{cursor:pointer}.ui-dialog-titlebar-close.ui-state-default{border-color:transparent;background:0;box-shadow:none}.ui-dialog-titlebar-close.ui-state-default.ui-state-hover{transition:.2s;border:1px solid #555;background:#333;background:-webkit-linear-gradient(top,#555,#111);background:-moz-linear-gradient(top,#555,#111);background:-ms-linear-gradient(top,#555,#111);background:-o-linear-gradient(top,#555,#111);background:linear-gradient(to bottom,#555,#111);box-shadow:inset 0 0 3px #555,inset 0 0 6px #555,0 0 3px #000,0 0 2px #000}.ui-dialog-buttonpane{background:#202d3e;box-shadow:inset 0 0 3px #000,inset 0 0 2px #000;border-top-color:#4d637c;margin:0 -4px -4px -4px;padding:0}.tf-select,.tf-input,.tf-textarea,.tf-multiple,.tf-label,.tf-fieldset legend,.tf-file,.tf-file input,.tf-radio,.tf-checkbox,.tf-button,.tf-input.tf-color,.tf-input.tf-range{font-size:13px;cursor:pointer}.tf-select .tf-selected,.tf-input,.tf-multiple,.tf-textarea,.tf-file .tf-info,.tf-radio,.tf-checkbox{background:#000;background:-webkit-linear-gradient(top,#111,#333);background:-moz-linear-gradient(top,#111,#333);background:-ms-linear-gradient(top,#111,#333);background:-o-linear-gradient(top,#111,#333);background:linear-gradient(to bottom,#111,#333);box-shadow:inset 0 0 4px #555;border:1px solid #666;color:#aaa;border-radius:4px;color:#6b6b6b;padding:6px 10px}.tf-select.tf-focused .tf-selected,.tf-select .tf-menu,.tf-multiple.tf-focused,.tf-input:focus,.tf-textarea:focus,.tf-file.tf-focused .tf-info,.tf-radio.tf-focused,.tf-checkbox.tf-focused{background:#202d3e;background:-webkit-linear-gradient(top,#131427,#273446);background:-moz-linear-gradient(top,#131427,#273446);background:-ms-linear-gradient(top,#131427,#273446);background:-o-linear-gradient(top,#131427,#273446);background:linear-gradient(to bottom,#131427,#273446);box-shadow:inset 0 0 4px #4d637c;border:1px solid #4d637c;color:#fff}.tf-button,.tf-file .tf-button{background:#333;background:-webkit-linear-gradient(top,#555,#111);background:-moz-linear-gradient(top,#555,#111);background:-ms-linear-gradient(top,#555,#111);background:-o-linear-gradient(top,#555,#111);background:linear-gradient(to bottom,#555,#111);box-shadow:inset 0 0 7px #555,inset 0 0 3px #555,0 0 3px #000,0 0 6px #000;border:1px solid #555;border-radius:4px;padding:6px 10px}.tf-file .tf-button,.tf-select .tf-button{box-shadow:inset 0 0 7px #555,inset 0 0 3px #555}.tf-file.tf-focused .tf-button,.tf-button.tf-focused,.tf-select.tf-focused .tf-button{background:#4685b3;background:-webkit-linear-gradient(top,#4685b3,#184977);background:-moz-linear-gradient(top,#4685b3,#184977);background:-ms-linear-gradient(top,#4685b3,#184977);background:-o-linear-gradient(top,#4685b3,#184977);background:linear-gradient(to bottom,#4685b3,#184977);box-shadow:inset 0 0 7px #4e9ed4,inset 0 0 3px #4e9ed4,0 0 3px #000,0 0 6px #000;border-color:#4685b3;color:#fff}.tf-file.tf-focused .tf-button,.tf-select.tf-focused .tf-button{box-shadow:inset 0 0 7px #4e9ed4,inset 0 0 3px #4e9ed4}.tf-select .tf-menu .tf-hover,.tf-multiple .tf-hover,.tf-multiple .tf-selected,.tf-button{color:#fff;text-shadow:1px 0 rgba(0,0,0,.2),-1px 0 rgba(0,0,0,.2),0 -1px rgba(0,0,0,.2),0 1px rgba(0,0,0,.2),1px 1px rgba(0,0,0,.2),-1px -1px rgba(0,0,0,.2),1px -1px rgba(0,0,0,.2),-1px 1px rgba(0,0,0,.2)}.tf-select .tf-selected{border-radius:4px 0 0 4px}.tf-select .tf-button{border-left:0;border-radius:0 4px 4px 0}.tf-select .tf-button span{display:block;background:url('img/ui-icons_grey.png') -64px -15px;width:16px;margin-left:4px;margin-right:5px}.tf-select.tf-focused .tf-button span{background-image:url('img/ui-icons_white.png')}.tf-select .tf-menu{border-radius:0 0 4px 4px}.tf-select .tf-menu div,.tf-multiple div{border:1px solid transparent;border-left-width:0;border-right-width:0;padding:6px 10px;margin-top:-1px}.tf-select .tf-menu .tf-hover,.tf-multiple.tf-focused .tf-hover,.tf-multiple.tf-focused .tf-selected,.tf-select.tf-opened.tf-focused .tf-button{border-color:#4685b3;background:#4685b3;background:-webkit-linear-gradient(top,#184977,#4685b3);background:-moz-linear-gradient(top,#184977,#4685b3);background:-ms-linear-gradient(top,#184977,#4685b3);background:-o-linear-gradient(top,#184977,#4685b3);background:linear-gradient(to bottom,#184977,#4685b3);box-shadow:inset 0 0 7px #4e9ed4,inset 0 0 3px #4e9ed4}.tf-select.tf-opened .tf-button{background:#111;background:-webkit-linear-gradient(top,#555,#111);background:-moz-linear-gradient(top,#555,#111);background:-ms-linear-gradient(top,#555,#111);background:-o-linear-gradient(top,#555,#111);background:linear-gradient(to bottom,#555,#111);box-shadow:inset 0 0 7px #555,inset 0 0 3px #555}.tf-select .tf-menu .tf-group-last,.tf-select .tf-menu div.tf-last{border-bottom-width:0}.tf-select .tf-menu ul{overflow:hidden}.tf-select .tf-menu li.tf-last{margin-bottom:-1px}.tf-select .tf-menu .tf-last{border-radius:0 0 4px 4px}.tf-select.tf-opened .tf-selected{border-radius:4px 0 0 0}.tf-select.tf-opened .tf-button{border-radius:0 4px 0 0}.tf-select .tf-menu li,.tf-multiple.tf-focused li{border-bottom:1px solid #54b0e0;border-top:1px solid #54b0e0;margin:-1px 0}.tf-select .tf-menu li>span,.tf-multiple li>span,.tf-multiple.tf-focused li>span{display:block;padding:6px 10px;text-align:center;font-weight:bold;color:#6b6b6b;background:#a7deff;border-bottom:1px solid #54b0e0;cursor:default;white-space:nowrap}.tf-multiple{padding:0}.tf-multiple li{border:1px solid #54b0e0;border-right:0;border-left:0;margin:-1px 0}.tf-multiple li>span{color:#70a5d1;border-color:#54b0e0;background:#c1ddf5}.tf-multiple .tf-hover,.tf-multiple .tf-selected,.tf-multiple.tf-focused .tf-hover{background:#4685b3;background:-webkit-linear-gradient(top,#184977,#4685b3);background:-moz-linear-gradient(top,#184977,#4685b3);background:-ms-linear-gradient(top,#184977,#4685b3);background:-o-linear-gradient(top,#184977,#4685b3);background:linear-gradient(to bottom,#184977,#4685b3);box-shadow:inset 0 0 7px #4e9ed4,inset 0 0 3px #4e9ed4;border-color:#4685b3}.tf-multiple .tf-hover,.tf-multiple .tf-selected{border:1px solid #54b0e0;border-left:0;border-right:0}.tf-multiple div.tf-first{border-top:0;border-radius:4px 4px 0 0;margin-top:0}.tf-multiple div.tf-last{border-bottom:0;border-radius:0 0 4px 4px}.tf-multiple .tf-group-first{border-top:0;margin-top:0}.tf-multiple li.tf-last,.tf-multiple .tf-group-last{border-bottom:0}.tf-file{width:200px;padding:0;overflow:auto}.tf-file .tf-info,.tf-file.tf-focused .tf-info{padding:6px 10px;border-radius:4px 0 0 4px;border-right:0}.tf-file .tf-button{border-radius:0 4px 4px 0;color:transparent;text-shadow:none;padding:6px 8px}.tf-file .tf-button span{margin:0 0 0 -4px;width:16px;height:16px;display:block;overflow:hidden;background:url('img/ui-icons_grey.png') -16px -96px}.tf-file .tf-button:after{content:"\00a0"}.tf-file input::-webkit-file-upload-button{cursor:pointer}.tf-radio{width:15px;height:15px;padding:0;border-radius:8px}.tf-radio input{width:17px;height:17px;margin:-1px 0 0 -1px;cursor:pointer}.tf-radio span{width:15px;height:15px;display:block;float:right}.tf-radio.tf-checked span{background:url('img/ui-icons_grey.png') -80px -145px}.tf-radio.tf-checked.tf-focused span{background-image:url('img/ui-icons_white.png')}.tf-checkbox{padding:0;width:15px;height:15px;border-radius:3px}.tf-checkbox input{width:17px;height:17px;margin:-1px 0 0 -1px;cursor:pointer}.tf-checkbox.tf-checked span{width:15px;height:15px;display:block;background:url('img/ui-icons_grey.png') -64px -145px;float:right}.tf-checkbox.tf-focused.tf-checked span{background-image:url('img/ui-icons_white.png')}.tf-button{overflow:hidden;padding:0}.tf-button span{margin:3px 7px;float:right}.tf-button input,.tf-button button{cursor:pointer}.tf-input,.tf-textarea{outline:0;cursor:text;margin:0}.tf-input::-webkit-input-placeholder,.tf-textarea::-webkit-input-placeholder{color:#aaa}.tf-input:-moz-placeholder,.tf-textarea:-moz-placeholder{color:#aaa}.tf-input::-moz-placeholder,.tf-textarea::-moz-placeholder{color:#aaa}.tf-input:-ms-input-placeholder,.tf-textarea:-ms-input-placeholder{color:#aaa}.tf-input:focus::-webkit-input-placeholder,.tf-textarea:focus::-webkit-input-placeholder{color:#184977}.tf-input:focus:-moz-placeholder,.tf-textarea:focus:-moz-placeholder{color:#184977}.tf-input:focus::-moz-placeholder,.tf-textarea:focus::-moz-placeholder{color:#184977}.tf-input:focus:-ms-input-placeholder,.tf-textarea:focus:-ms-input-placeholder{color:#184977}.tf-fieldset{color:#aaa;border:1px solid #425064;border-radius:4px;background:#202d3e;box-shadow:inset 0 0 3px #000,inset 0 0 6px #000,0 0 3px #425064,0 0 2px #425064;margin:0 10px 10px 0;padding:10px}.tf-fieldset legend{font-weight:bold;color:#aaa}.tf-label{color:#aaa}.tf-label.tf-focused{color:#fff}.tf-disabled{opacity:.5;filter:alpha(opacity=50)}.tf-disabled,.tf-disabled input,.tf-disabled button,.tf-disabled * *.tf-disabled{cursor:default}.tf-file.tf-disabled input::-webkit-file-upload-button{cursor:pointer}.tf-fieldset.tf-disabled,.tf-form.tf-disabled{opacity:1;filter:alpha(opacity=100)}.tf-input.tf-color{width:30px;padding:0;height:24px}.tf-input.tf-number{text-align:right}.tf-input.tf-range{height:9px;margin:8px 0 7px 0}.tf-input.tf-search,.tf-input.tf-search.tf-readOnly{border-radius:11px}.tf-input.tf-datetime,.tf-input.tf-datetime-local,.tf-input.tf-month,.tf-input.tf-time,.tf-input.tf-week,.tf-input.tf-datetime:focus,.tf-input.tf-datetime-local:focus,.tf-input.tf-month:focus,.tf-input.tf-time:focus,.tf-input.tf-week:focus{padding:1px 5px}*{font-size:13px}body{background:#000;color:#aaa}fieldset td{white-space:nowrap}#folders{margin:5px 5px 0 5px}#files{margin-right:5px}#toolbar a:hover,#toolbar a.hover,span.current,span.regular:hover,span.context,a.drag>span.folder,#clipboard div:hover,div.file:hover,#files div.selected,#files div.selected:hover,tr.selected>td,tr.selected:hover>td,#menu .list div a:hover,#toolbar a.selected{color:#fff;text-shadow:1px 0 rgba(0,0,0,.2),-1px 0 rgba(0,0,0,.2),0 -1px rgba(0,0,0,.2),0 1px rgba(0,0,0,.2),1px 1px rgba(0,0,0,.2),-1px -1px rgba(0,0,0,.2),1px -1px rgba(0,0,0,.2),-1px 1px rgba(0,0,0,.2)}#files div{text-shadow:1px 0 rgba(0,0,0,.2),-1px 0 rgba(0,0,0,.2),0 -1px rgba(0,0,0,.2),0 1px rgba(0,0,0,.2),1px 1px rgba(0,0,0,.2),-1px -1px rgba(0,0,0,.2),1px -1px rgba(0,0,0,.2),-1px 1px rgba(0,0,0,.2)}#files,#folders,#toolbar a.selected{color:#aaa;border:1px solid #425064;border-radius:4px;background:#202d3e;box-shadow:inset 0 0 3px #000,inset 0 0 6px #000,0 0 3px #425064,0 0 2px #425064}#toolbar{padding:5px 0}#toolbar a{color:#949494;margin-right:5px;border:1px solid transparent;outline:0;display:block;float:left;border-radius:4px;padding:0}#toolbar a>span{padding:6px 10px 6px 26px;diaplay:block;float:left;background:no-repeat 6px center}#toolbar a:hover,#toolbar a.hover{color:#fff;border-color:#184977;background:#4685b3;background:-webkit-linear-gradient(top,#4685b3,#184977);background:-moz-linear-gradient(top,#4685b3,#184977);background:-ms-linear-gradient(top,#4685b3,#184977);background:-o-linear-gradient(top,#4685b3,#184977);background:linear-gradient(to bottom,#4685b3,#184977);box-shadow:inset 0 0 3px #88b9da}#toolbar a[href="kcact:upload"] span{background-image:url(img/icons/upload.png)}#toolbar a[href="kcact:refresh"] span{background-image:url(img/icons/refresh.png)}#toolbar a[href="kcact:settings"] span{background-image:url(img/icons/settings.png)}#toolbar a[href="kcact:about"] span{background-image:url(img/icons/about.png)}#toolbar a[href="kcact:maximize"] span{background-image:url(img/icons/maximize.png)}#settings label{cursor:pointer}#settings fieldset{margin-right:5px;margin-bottom:6px;margin-top:-5px;padding:6px}div.folder{padding-top:2px;margin-top:5px;white-space:nowrap}div.folder a{text-decoration:none;cursor:default;outline:0;color:#aaa}span.folder{padding:2px 3px 2px 23px;outline:0;background:no-repeat 3px center;cursor:pointer;border-radius:3px;border:1px solid transparent}span.brace{width:16px;height:16px;outline:0}span.current{transition:.3s;background-image:url(img/tree/folder.png);background-color:#306999;border-color:#306999;box-shadow:inset 0 0 7px #8fd6ea,inset 0 0 3px #8fd6ea,0 0 2px #000,0 0 1px #000}span.regular{transition:.3s;background-image:url(img/tree/folder.png);background-color:transparent}span.regular:hover,span.context,a.drag>span.folder,#clipboard div:hover{transition:.3s;background-color:#333;border-color:#777;box-shadow:inset 0 0 7px #777,inset 0 0 3px #777,0 0 2px #000,0 0 1px #000}span.opened{background-image:url(img/tree/minus.png)}span.closed{background-image:url(img/tree/plus.png)}span.denied{background-image:url(img/tree/denied.png)}div.file{padding:4px;margin:3px;border:1px solid transparent;border-radius:4px}div.file:hover{box-shadow:inset 0 0 7px #555,inset 0 0 3px #555,0 0 3px #000,0 0 6px #000;background:#000;background:-webkit-linear-gradient(top,#111,#555);background:-moz-linear-gradient(top,#111,#555);background:-ms-linear-gradient(top,#111,#555);background:-o-linear-gradient(top,#111,#555);background:linear-gradient(to bottom,#111,#555);border-color:#555}div.file .name{margin-top:4px;font-weight:bold;height:16px;overflow:hidden;padding-bottom:2px}div.file .time{font-size:10px}div.file .size{font-size:10px}#files div.selected,#files div.selected:hover{border-color:#4685b3;background:#4685b3;background:-webkit-linear-gradient(top,#4685b3,#184977);background:-moz-linear-gradient(top,#4685b3,#184977);background:-ms-linear-gradient(top,#4685b3,#184977);background:-o-linear-gradient(top,#4685b3,#184977);background:linear-gradient(to bottom,#4685b3,#184977);box-shadow:inset 0 0 7px #4e9ed4,inset 0 0 3px #4e9ed4,0 0 3px #000,0 0 6px #000}tr.file>td{padding:3px 4px}tr.file:hover>td{background-color:#000;transition:none}tr.selected>td,tr.selected:hover>td{transition:.3s;background-color:#2d5277}tr.file td.name{background-position:2px center;padding-left:22px}a.denied{color:#666;opacity:.5;filter:alpha(opacity:50);cursor:default}a.denied:hover{background-color:#e4e3e2;border-color:transparent;box-shadow:none}#menu .ui-menu a span{background:left center no-repeat;padding-left:20px;white-space:nowrap}#menu a[href="kcact:refresh"] span{background-image:url(img/icons/refresh.png)}#menu a[href="kcact:mkdir"] span{background-image:url(img/icons/folder-new.png)}#menu a[href="kcact:mvdir"] span,#menu a[href="kcact:mv"] span{background-image:url(img/icons/rename.png)}#menu a[href="kcact:rmdir"] span,#menu a[href="kcact:rm"] span,#menu a[href="kcact:rmcbd"] span{background-image:url(img/icons/delete.png)}#menu a[href="kcact:clpbrdadd"] span{background-image:url(img/icons/clipboard-add.png)}#menu a[href="kcact:pick"] span,#menu a[href="kcact:pick_thumb"] span{background-image:url(img/icons/select.png)}#menu a[href="kcact:download"] span{background-image:url(img/icons/download.png)}#menu a[href="kcact:view"] span{background-image:url(img/icons/view.png)}#menu a[href="kcact:cpcbd"] span{background-image:url(img/icons/copy.png)}#menu a[href="kcact:mvcbd"] span{background-image:url(img/icons/move.png)}#menu a[href="kcact:clrcbd"] span{background-image:url(img/icons/clipboard-clear.png)}#clipboard{margin-left:-3px;padding:2px}#clipboard div{background:url(img/icons/clipboard.png) no-repeat center center;border:1px solid transparent;padding:2px;cursor:pointer;border-radius:4px}#clipboard.selected div,#clipboard.selected div:hover{background-color:#306999;border-color:#306999;box-shadow:inset 0 0 7px #8fd6ea,inset 0 0 3px #8fd6ea}#menu .list a,#menu .list a.ui-state-focus{margin:-1px 0 0 -1px;padding:6px 10px;border:1px solid transparent;background:0;border-radius:0;text-shadow:none;box-shadow:none}#menu .list a.first,#menu .list a.first.ui-state-focus{border-radius:4px 4px 0 0}#menu .list a:hover{border-color:#4685b3;background:#4685b3;background:-webkit-linear-gradient(top,#184977,#4685b3);background:-moz-linear-gradient(top,#184977,#4685b3);background:-ms-linear-gradient(top,#184977,#4685b3);background:-o-linear-gradient(top,#184977,#4685b3);background:linear-gradient(to bottom,#184977,#4685b3);box-shadow:inset 0 0 7px #4e9ed4,inset 0 0 3px #4e9ed4}#menu .list{overflow:hidden;max-height:1px;margin-bottom:-1px;padding-bottom:1px}#menu li.div-files{margin:0 0 1px 0}.about{text-align:center}.about div.head{font-weight:bold;font-size:12px;padding:3px 0 8px 0}.about div.head a{background:url(img/kcf_logo.png) no-repeat left center;padding:0 0 0 27px;font-size:17px;outline:0}.about a{text-decoration:none;color:#3665b4}.about a:hover{text-decoration:underline}#checkver{margin:5px 0 10px 0}#loading,#checkver>span.loading{background:url(img/loading.gif);border:1px solid #425064;box-shadow:inset 0 0 3px #000,inset 0 0 6px #000,0 0 3px #425064,0 0 2px #425064;padding:6px 10px;border-radius:4px;color:#aaa}#checkver a{font-weight:normal;padding:3px 3px 3px 20px;background:url(img/icons/download.png) no-repeat left center}.kcfImageViewer .ui-dialog-content{background:#000;cursor:pointer}.kcfImageViewer .img{background:url(img/bg_transparent.png)}.ui-dialog-titlebar.loading{background:url(img/loading.gif);box-shadow:inset 0 0 3px #000,inset 0 0 6px #000;border-color:#425064}.ui-dialog-titlebar.loading .ui-dialog-title{color:#aaa;font-weight:normal}.ui-dialog-titlebar.loading .ui-dialog-titlebar-close .ui-button-icon-primary.ui-icon.ui-icon-closethick{background-image:url(img/ui-icons_grey.png)}#settings .tf-select{margin:3px 5px 6px 0}#settings .tf-selected{padding-top:10px;padding-bottom:11px}#settings .tf-select .tf-button{padding-top:7px;padding-bottom:8px}#loading{margin-right:5px}#loadingDirs{padding:5px 0 1px 24px}#files.drag{background:#ddebf8}#resizer{background:#fff}div.selector#uniform-lang{margin:8px 6px 6px 0}body.msie fieldset,body.trident.rv fieldset{border-radius:0} \ No newline at end of file diff --git a/lib/kcfinder/cache/theme_dark.js b/lib/kcfinder/cache/theme_dark.js new file mode 100644 index 0000000..628d36f --- /dev/null +++ b/lib/kcfinder/cache/theme_dark.js @@ -0,0 +1 @@ +$.each(["loading.gif","ui-icons_black.png","ui-icons_grey.png","ui-icons_white.png"],function(b,a){new Image().src="themes/dark/img/"+a}); \ No newline at end of file diff --git a/lib/kcfinder/cache/theme_default.css b/lib/kcfinder/cache/theme_default.css new file mode 100644 index 0000000..27fdf53 --- /dev/null +++ b/lib/kcfinder/cache/theme_default.css @@ -0,0 +1,2494 @@ +/* + +This CSS code is generated from http://ui.sunhater.com +(c)2014 Pavel Tzonkov, sunhater.com. All rights reserved. + +*/ +/*** jQueryUI */ +/** Base */ + +.ui-helper-hidden { + display: none; +} +.ui-helper-hidden-accessible { + border: 0; + clip: rect(0 0 0 0); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; +} +.ui-helper-reset { + margin: 0; + padding: 0; + border: 0; + outline: 0; + line-height: 1.3; + text-decoration: none; + font-size: 100%; + list-style: none; +} +.ui-helper-clearfix:before, +.ui-helper-clearfix:after { + content: ""; + display: table; + border-collapse: collapse; +} +.ui-helper-clearfix:after { + clear: both; +} +.ui-helper-clearfix { + min-height: 0; /* support: IE7 */ +} +.ui-helper-zfix { + width: 100%; + height: 100%; + top: 0; + left: 0; + position: absolute; + opacity: 0; + filter:alpha(opacity=0); +} + +.ui-front { + z-index: 100; +} + +.ui-widget .ui-widget, +.ui-widget input, +.ui-widget select, +.ui-widget textarea, +.ui-widget button { + font-size: 1em; +} +.ui-widget-content { + border: 1px solid #888; + background: #fff; + color: #6B6B6B; +} +.ui-widget-content a { + color: #6B6B6B; +} +.ui-widget-header { + border: 1px solid #1b79b8; + color: #fff; + font-weight: bold; + background: #1b79b8; + background: -webkit-linear-gradient(top, #1b79b8, #59b5f2); + background: -moz-linear-gradient(top, #1b79b8, #59b5f2); + background: -ms-linear-gradient(top, #1b79b8, #59b5f2); + background: -o-linear-gradient(top, #1b79b8, #59b5f2); + background: linear-gradient(to bottom, #1b79b8, #59b5f2); +} +.ui-widget-header a { + color: #fff; +} + +/* Interaction states +----------------------------------*/ + +.ui-state-default, +.ui-widget-content .ui-state-default, +.ui-widget-header .ui-state-default, +.ui-widget.ui-state-disabled { + transition: .2s; + border: 1px solid #6b6b6b; + background: #6b6b6b; + background: -webkit-linear-gradient(top, #ababab, #6b6b6b); + background: -moz-linear-gradient(top, #ababab, #6b6b6b); + background: -ms-linear-gradient(top, #ababab, #6b6b6b); + background: -o-linear-gradient(top, #ababab, #6b6b6b); + background: linear-gradient(to bottom, #ababab, #6b6b6b); + font-weight: bold; + color: #fff; +} + +.ui-state-hover, +.ui-widget-content .ui-state-hover, +.ui-widget-header .ui-state-hover, +.ui-state-focus, +.ui-widget-content .ui-state-focus, +.ui-widget-header .ui-state-focus { + transition: .2s; + border: 1px solid #6b6b6b; + background: #6b6b6b; + background: -webkit-linear-gradient(top, #6b6b6b, #ababab); + background: -moz-linear-gradient(top, #6b6b6b, #ababab); + background: -ms-linear-gradient(top, #6b6b6b, #ababab); + background: -o-linear-gradient(top, #6b6b6b, #ababab); + background: linear-gradient(to bottom, #6b6b6b, #ababab); + font-weight: bold; + color: #fff; +} + +.ui-state-active, +.ui-widget-content .ui-state-active, +.ui-widget-header .ui-state-active, +.ui-menu .ui-state-focus { + transition: .2s; + border: 1px solid #1b79b8; + background: #1b79b8; + background: -webkit-linear-gradient(top, #1b79b8, #59b5f2); + background: -moz-linear-gradient(top, #1b79b8, #59b5f2); + background: -ms-linear-gradient(top, #1b79b8, #59b5f2); + background: -o-linear-gradient(top, #1b79b8, #59b5f2); + background: linear-gradient(to bottom, #1b79b8, #59b5f2); + font-weight: bold; + color: #fff; +} + +.ui-state-default a, +.ui-state-default a:link, +.ui-state-default a:visited, +.ui-state-hover a, +.ui-state-hover a:hover, +.ui-state-hover a:link, +.ui-state-hover a:visited, +.ui-state-active a, +.ui-state-active a:link, +.ui-state-active a:visited { + transition: .2s; + color: #fff; + text-decoration: none; +} + +.ui-menu .ui-state-active { + transition: .2s; + border-color: #6b6b6b; + background: #6b6b6b; + background: -webkit-linear-gradient(top, #6b6b6b, #ababab); + background: -moz-linear-gradient(top, #6b6b6b, #ababab); + background: -ms-linear-gradient(top, #6b6b6b, #ababab); + background: -o-linear-gradient(top, #6b6b6b, #ababab); + background: linear-gradient(to bottom, #6b6b6b, #ababab); +} + +/* Interaction Cues +----------------------------------*/ + +.ui-state-highlight, +.ui-widget-content .ui-state-highlight, +.ui-widget-header .ui-state-highlight { + border: 1px solid #d5bc2c; + box-shadow: inset 0 0 5px #d5bc2c; + background: #fff6bf; + color: #6b6b6b; +} +.ui-state-error, +.ui-widget-content .ui-state-error, +.ui-widget-header .ui-state-error { + border: 1px solid #cf7f7f; + box-shadow: inset 0 0 5px #cf7f7f; + background: #fac4c4; + color: #6b6b6b; +} +.ui-state-error a, +.ui-widget-content .ui-state-error a, +.ui-widget-header .ui-state-error a, +.ui-state-highlight a, +.ui-widget-content .ui-state-highlight a, +.ui-widget-header .ui-state-highlight a, +.ui-state-error-text, +.ui-widget-content .ui-state-error-text, +.ui-widget-header .ui-state-error-text { + color: #6b6b6b; +} +.ui-priority-primary, +.ui-widget-content .ui-priority-primary, +.ui-widget-header .ui-priority-primary { + font-weight: bold; +} +.ui-priority-secondary, +.ui-widget-content .ui-priority-secondary, +.ui-widget-header .ui-priority-secondary { + opacity: .5; + filter:alpha(opacity=50); + font-weight: normal; +} +.ui-state-disabled, +.ui-widget-content .ui-state-disabled, +.ui-widget-header .ui-state-disabled { + opacity: .50; + filter:alpha(opacity=50); + background-image: none; +} +.ui-state-disabled .ui-icon { + filter:alpha(opacity=50); /* For IE8 - See #6059 */ +} + +/* Interaction Cues +----------------------------------*/ +.ui-state-disabled { + cursor: default !important; +} + +/* Misc visuals +----------------------------------*/ + +/* Overlays */ +.ui-widget-overlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; +} +.ui-resizable { + position: relative; +} +.ui-resizable-handle { + position: absolute; + font-size: 0.1px; + display: block; +} +.ui-resizable-disabled .ui-resizable-handle, +.ui-resizable-autohide .ui-resizable-handle { + display: none; +} +.ui-resizable-n { + cursor: n-resize; + height: 7px; + width: 100%; + top: -5px; + left: 0; +} +.ui-resizable-s { + cursor: s-resize; + height: 7px; + width: 100%; + bottom: -5px; + left: 0; +} +.ui-resizable-e { + cursor: e-resize; + width: 7px; + right: -5px; + top: 0; + height: 100%; +} +.ui-resizable-w { + cursor: w-resize; + width: 7px; + left: -5px; + top: 0; + height: 100%; +} +.ui-resizable-se { + cursor: se-resize; + width: 12px; + height: 12px; + right: 1px; + bottom: 1px; +} +.ui-resizable-sw { + cursor: sw-resize; + width: 9px; + height: 9px; + left: -5px; + bottom: -5px; +} +.ui-resizable-nw { + cursor: nw-resize; + width: 9px; + height: 9px; + left: -5px; + top: -5px; +} +.ui-resizable-ne { + cursor: ne-resize; + width: 9px; + height: 9px; + right: -5px; + top: -5px; +} +.ui-selectable-helper { + position: absolute; + z-index: 100; + border: 1px dotted black; +} + + +/** Accordion */ + +.ui-accordion .ui-accordion-header { + display: block; + cursor: pointer; + position: relative; + margin-top: 2px; + padding: 6px; + min-height: 0; /* support: IE7 */ +} +.ui-accordion .ui-accordion-icons, +.ui-accordion .ui-accordion-icons .ui-accordion-icons { + padding-left: 24px; +} +.ui-accordion .ui-accordion-noicons { + padding-left: 5px; +} + +.ui-accordion .ui-accordion-header .ui-accordion-header-icon { + position: absolute; + left: 5px; + top: 50%; + margin-top: -8px; +} +.ui-accordion .ui-accordion-content { + padding: 1em; + border-top: 0; + overflow: auto; +} + + +/** Autocomplete */ + +.ui-autocomplete { + position: absolute; + top: 0; + left: 0; + cursor: pointer; +} + + +/** Button */ + +.ui-button { + display: inline-block; + position: relative; + padding: 0; + line-height: normal; + cursor: pointer; + vertical-align: middle; + text-align: center; + overflow: visible; /* removes extra width in IE */ +} +.ui-button, +.ui-button:link, +.ui-button:visited, +.ui-button:hover, +.ui-button:active { + text-decoration: none; +} +/* to make room for the icon, a width needs to be set here */ +.ui-button-icon-only { + width: 36px; +} +.ui-button-icons-only { + width: 50px; +} +/* button text element */ +.ui-button .ui-button-text { + display: block; + line-height: normal; +} +.ui-button-text-only .ui-button-text { + padding: 6px 10px; +} +.ui-button-icon-only .ui-button-text, +.ui-button-icons-only .ui-button-text { + padding: 6px; + text-indent: -9999999px; +} +.ui-button-text-icon-primary .ui-button-text, +.ui-button-text-icons .ui-button-text { + padding: 6px 10px 6px 28px; +} +.ui-button-text-icon-secondary .ui-button-text, +.ui-button-text-icons .ui-button-text { + padding: 6px 28px 6px 10px; +} +.ui-button-text-icons .ui-button-text { + padding-left: 28px; + padding-right: 28px; +} +/* no icon support for input elements, provide padding by default */ +input.ui-button { + padding: 6px 10px; +} + +/* button icon element(s) */ +.ui-button-icon-only .ui-icon, +.ui-button-text-icon-primary .ui-icon, +.ui-button-text-icon-secondary .ui-icon, +.ui-button-text-icons .ui-icon, +.ui-button-icons-only .ui-icon { + position: absolute; + top: 50%; + margin-top: -8px; +} +.ui-button-icon-only .ui-icon { + left: 50%; + margin-left: -8px; +} +.ui-button-text-icon-primary .ui-button-icon-primary, +.ui-button-text-icons .ui-button-icon-primary, +.ui-button-icons-only .ui-button-icon-primary { + left: 7px; +} +.ui-button-text-icon-secondary .ui-button-icon-secondary, +.ui-button-text-icons .ui-button-icon-secondary, +.ui-button-icons-only .ui-button-icon-secondary { + right: 7px; +} +/* workarounds */ +/* reset extra padding in Firefox, see h5bp.com/l */ +input.ui-button::-moz-focus-inner, +button.ui-button::-moz-focus-inner { + border: 0; + padding: 0; +} + + +/** Button set */ + +.ui-buttonset { + margin:0; + overflow:auto; +} +.ui-buttonset .ui-button { + margin: 0; + float:left; +} + + +/** Date picker */ + +.ui-datepicker { + width: 19em; + width: 19em; + display: none; + padding: 10px; +} +.ui-datepicker .ui-datepicker-header { + position: relative; + padding: 2px 0; +} +.ui-datepicker .ui-datepicker-prev, +.ui-datepicker .ui-datepicker-next { + position: absolute; + top: 4px; + width: 20px; + height: 20px; +} +.ui-datepicker .ui-datepicker-prev-hover, +.ui-datepicker .ui-datepicker-next-hover { + top: 3px; +} +.ui-datepicker .ui-datepicker-prev { + left: 4px; +} +.ui-datepicker .ui-datepicker-next { + right: 4px; +} +.ui-datepicker .ui-datepicker-prev-hover { + left: 3px; +} +.ui-datepicker .ui-datepicker-next-hover { + right: 3px; +} +.ui-datepicker .ui-datepicker-prev span, +.ui-datepicker .ui-datepicker-next span { + display: block; + position: absolute; + left: 50%; + margin-left: -8px; + top: 50%; + margin-top: -8px; +} +.ui-datepicker .ui-datepicker-title { + margin: 0 10px; + padding: 4px 0; + text-align: center; +} +.ui-datepicker .ui-datepicker-title select { + font-size: 1em; + margin:-2px 2px; + padding:0; + outline:0; +} +.ui-datepicker table { + width: 100%; + border-collapse: collapse; + margin: 0; + font-size: 1em; +} +.ui-datepicker th { + padding: 3px; + text-align: center; + font-weight: bold; + border: 0; +} +.ui-datepicker td { + border: 0; + padding: 1px; +} +.ui-datepicker td span, +.ui-datepicker td a { + display: block; + padding: 2px 3px; + text-align: right; + text-decoration: none; +} +.ui-datepicker .ui-datepicker-buttonpane { + background-image: none; + margin: 10px -11px -11px -11px; + padding: 10px; + border: 1px solid #1b79b8; + background: #e4f5ff; + overflow: auto; +} +.ui-datepicker .ui-datepicker-buttonpane button { + float: right; + cursor: pointer; + width: auto; + overflow: visible; + margin: 0; + padding: 6px 10px; + font-weight: bold; + opacity: 1; + filter: alpha(opacity=100); +} +.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { + float: left; +} + +/* with multiple calendars */ +.ui-datepicker.ui-datepicker-multi { + width: auto; + padding:10px; +} +.ui-datepicker-multi .ui-datepicker-group { + float: left; +} +.ui-datepicker-multi .ui-datepicker-group .ui-datepicker-header { + margin:0; +} +.ui-datepicker-multi .ui-datepicker-group.ui-datepicker-group-last { + margin-right:0; +} + +.ui-datepicker-multi .ui-datepicker-group table { + width: 95%; + margin: 0 auto .4em; +} +.ui-datepicker-multi-2 .ui-datepicker-group { + width: 50%; +} +.ui-datepicker-multi-3 .ui-datepicker-group { + width: 33.3%; +} +.ui-datepicker-multi-4 .ui-datepicker-group { + width: 25%; +} + +.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header, +.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { + border-left-width: 0; +} +.ui-datepicker-multi .ui-datepicker-buttonpane { + clear: left; +} +.ui-datepicker-row-break { + clear: both; + font-size: 0; + width: 100px; +} +th.ui-datepicker-week-col { + color: #215b82; +} +td.ui-datepicker-week-col { + text-align:right; + padding-right:7px; + color: #215b82; +} +td.ui-datepicker-other-month a.ui-state-default { + font-weight: bold; +} +th.ui-datepicker-week-end { + color: #f44; +} + +/* RTL support */ +.ui-datepicker-rtl { + direction: rtl; +} +.ui-datepicker-rtl .ui-datepicker-prev { + right: 2px; + left: auto; +} +.ui-datepicker-rtl .ui-datepicker-next { + left: 2px; + right: auto; +} +.ui-datepicker-rtl .ui-datepicker-prev:hover { + right: 1px; + left: auto; +} +.ui-datepicker-rtl .ui-datepicker-next:hover { + left: 1px; + right: auto; +} +.ui-datepicker-rtl .ui-datepicker-buttonpane { + clear: right; +} +.ui-datepicker-rtl .ui-datepicker-buttonpane button { + float: left; +} +.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current, +.ui-datepicker-rtl .ui-datepicker-group { + float: right; +} +.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header, +.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { + border-right-width: 0; + border-left-width: 1px; +} + + +/** Dialog */ + +.ui-dialog { + position: absolute; + top: 0; + left: 0; + padding: 4px; + outline: 0; + box-shadow: 0 0 10px #000; +} +.ui-dialog .ui-dialog-titlebar { + padding: 5px 10px; + position: relative; +} +.ui-dialog .ui-dialog-title { + float: left; + margin: 0; + padding: 1px 0; + white-space: nowrap; + width: 90%; + overflow: hidden; + text-overflow: ellipsis; +} +.ui-dialog .ui-dialog-titlebar-close { + position: absolute; + right: .3em; + top: 50%; + width: 21px; + margin: -10px 0 0 0; + padding: 1px; + height: 20px; +} +.ui-dialog .ui-dialog-content { + position: relative; + border: 0; + padding: 1em; + margin: 0 -4px; + background: none; + overflow: auto; +} +.ui-dialog .ui-dialog-buttonpane { + text-align: left; + border-width: 1px 0 0 0; + background-image: none; + padding: 10px; +} +.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { + float: right; +} +.ui-dialog .ui-dialog-buttonpane button { + margin: 0 0 0 5px; + cursor: pointer; +} +.ui-dialog .ui-resizable-se { + width: 12px; + height: 12px; + right: -5px; + bottom: -5px; + background-position: 16px 16px; +} +.ui-draggable .ui-dialog-titlebar { + cursor: move; +} + + +/** Menu */ + +.ui-menu { + list-style: none; + padding: 0; + margin: 0; + display: block; + outline: 0; +} +.ui-menu .ui-menu { + margin-top: -3px; + position: absolute; +} +.ui-menu .ui-menu-item { + margin: 0; + padding: 0; + width: 100%; + /* support: IE10, see #8844 */ + list-style-image: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7); +} +.ui-menu .ui-menu-divider { + margin: 1px 10px 1px 10px; + height: 0; + font-size: 0; + line-height: 0; + border-width: 1px 0 0 0; + border-color: #bbb; +} +.ui-menu .ui-menu-item a { + text-decoration: none; + display: block; + padding: 5px 10px; + line-height: 1.5; + min-height: 0; /* support: IE7 */ + font-weight: normal; + border-radius:0; +} +.ui-menu .ui-menu-item a.ui-state-focus, +.ui-menu .ui-menu-item a.ui-state-active { + font-weight: normal; + margin: -1px; + transition: none; +} +.ui-menu .ui-state-disabled { + font-weight: normal; + line-height: 1.5; +} +.ui-menu .ui-state-disabled a { + cursor: default; +} +.ui-menu.ui-corner-all.sh-menu { + border-radius: 4px; +} +.ui-menu.ui-corner-all, .ui-menu.sh-menu.ui-autocomplete.ui-corner-all { + border-radius: 0; +} + +/* icon support */ +.ui-menu-icons { + position: relative; +} +.ui-menu-icons .ui-menu-item a { + position: relative; + padding-left: 2em; +} + +/* left-aligned */ +.ui-menu .ui-icon { + position: absolute; + top: .2em; + left: .2em; +} + +/* right-aligned */ +.ui-menu .ui-menu-icon { + position: static; + float: right; +} + + +/** Progress bar */ + +.ui-progressbar { + height: 2.1em; + text-align: left; + overflow: hidden; +} +.ui-progressbar .ui-progressbar-value { + margin: -1px; + height: 100%; +} +.ui-progressbar .ui-progressbar-overlay { + height: 100%; + filter: alpha(opacity=25); + opacity: 0.25; +} +.ui-progressbar-indeterminate .ui-progressbar-value { + background-image: none; +} + + +/** Slider */ + +.ui-slider { + position: relative; + text-align: left; + margin: 0 13px; + border-radius:15px; +} +.ui-slider .ui-slider-handle { + position: absolute; + z-index: 2; + width: 18px; + height: 18px; + border-radius: 9px; + cursor: default; + box-shadow: 0 0 3px #6b6b6b, inset 0 0 7px #fff, inset 0 0 3px #fff; +} +.ui-slider .ui-slider-handle.ui-state-active { + box-shadow: 0 0 3px #1b79b8, inset 0 0 7px #fff, inset 0 0 3px #fff; +} +.ui-slider .ui-slider-range { + position: absolute; + z-index: 1; + display: block; + border: 0; + background-position: 0 0; +} + +/* For IE8 - See #6727 */ +.ui-slider.ui-state-disabled .ui-slider-handle, +.ui-slider.ui-state-disabled .ui-slider-range { + filter: inherit; +} + +.ui-slider-horizontal { + height: 10px; +} +.ui-slider-horizontal .ui-slider-handle { + top: -5px; + margin-left: -9px; +} +.ui-slider-horizontal .ui-slider-range { + top: 0; + height: 100%; +} +.ui-slider-horizontal .ui-slider-range-min { + left: 0; +} +.ui-slider-horizontal .ui-slider-range-max { + right: 0; +} + +.ui-slider-vertical { + width: 10px; + height: 150px; +} +.ui-slider-vertical .ui-slider-handle { + left: -5px; + margin-left: 0; + margin-bottom: -9px; +} +.ui-slider-vertical .ui-slider-range { + left: -1px; + width: 100%; +} +.ui-slider-vertical .ui-slider-range-min { + bottom: 0; +} +.ui-slider-vertical .ui-slider-range-max { + top: 0; +} + + +/** Spinner */ + +.ui-spinner.ui-widget { + position: relative; + display: inline-block; + overflow: hidden; + padding: 0; + vertical-align: middle; + background: #fff; + background: -webkit-linear-gradient(top, #f0f0f0, #fff); + background: -moz-linear-gradient(top, #f0f0f0, #fff); + background: -ms-linear-gradient(top, #f0f0f0, #fff); + background: -o-linear-gradient(top, #f0f0f0, #fff); + background: linear-gradient(to bottom, #f0f0f0, #fff); +} +.ui-spinner-input { + border: none; + color: inherit; + padding: 0; + margin: 6px 24px 6px 10px; + vertical-align: middle; + outline: 0; + background: transparent; +} +.ui-spinner-input { + color: #6b6b6b} +.ui-spinner-input:focus { + color: #000; +} +.ui-spinner-button { + width: 16px; + height: 50%; + font-size: .5em; + padding: 0; + margin: 0; + text-align: center; + position: absolute; + cursor: default; + display: block; + overflow: hidden; + right: 0; +} +/* more specificity required here to overide default borders */ +.ui-spinner a.ui-spinner-button { + border-top: none; + border-bottom: none; + border-right: none; +} +/* vertical centre icon */ +.ui-spinner .ui-icon { + position: absolute; + margin-top: -8px; + top: 50%; + left: 0; +} +.ui-spinner-up { + top: 0; +} +.ui-spinner-down { + bottom: 0; +} + +/* TR overrides */ +.ui-spinner .ui-icon-triangle-1-s { + /* need to fix icons sprite */ + background-position: -65px -16px; +} + + +/** Tabs */ + +.ui-tabs { + position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ +} +.ui-tabs .ui-tabs-nav { + margin: 0; + padding: 3px 3px 0 3px; +} +.ui-tabs .ui-tabs-nav li { + list-style: none; + float: left; + position: relative; + top: 0; + margin: 1px 3px 0 0; + border-bottom-width: 0; + padding: 0; + white-space: nowrap; +} +.ui-tabs .ui-tabs-nav li a { + float: left; + padding: 6px 10px; + text-decoration: none; +} +.ui-tabs .ui-tabs-nav li.ui-tabs-active { + margin-bottom: -1px; + padding-bottom: 1px; +} +.ui-tabs .ui-tabs-nav li.ui-tabs-active a, +.ui-tabs .ui-tabs-nav li.ui-state-disabled a, +.ui-tabs .ui-tabs-nav li.ui-tabs-loading a { + cursor: text; +} +.ui-tabs .ui-tabs-nav li a, /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */ +.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a { + cursor: pointer; +} +.ui-tabs .ui-tabs-panel { + display: block; + border-width: 0; + padding: 1em; + background: none; +} + +/** Tooltip */ + +body .ui-tooltip { + padding: 6px 10px; + position: absolute; + z-index: 9999; + max-width: 300px; + color: #808080; + border-color: #a5a5a5; + box-shadow: inset 0 0 4px #a5a5a5, 0 0 4px #a5a5a5; + background: -webkit-linear-gradient(top, #ddd, #fff); + background: -moz-linear-gradient(top, #ddd, #fff); + background: -ms-linear-gradient(top, #ddd, #fff); + background: -o-linear-gradient(top, #ddd, #fff); + background: linear-gradient(to bottom, #ddd, #fff); +} + +/** Icons */ + +/* states and images */ +.ui-icon { + display: block; + text-indent: -99999px; + overflow: hidden; + background-repeat: no-repeat; + width: 16px; + height: 16px; +} + +.ui-icon, +.ui-widget-content .ui-icon, +.ui-state-highlight .ui-icon, +.ui-state-error .ui-icon, +.ui-state-error-text .ui-icon, +.ui-icon.ui-icon-black { + background-image: url(img/ui-icons_black.png); +} + +.ui-widget-header .ui-icon, +.ui-state-default .ui-icon, +.ui-state-hover .ui-icon, +.ui-state-focus .ui-icon, +.ui-state-active .ui-icon, +.ui-icon.ui-icon-white { + background-image: url(img/ui-icons_white.png); +} + +/* positioning */ +.ui-icon-blank { background-position: 16px 16px; } +.ui-icon-carat-1-n { background-position: 0 0; } +.ui-icon-carat-1-ne { background-position: -16px 0; } +.ui-icon-carat-1-e { background-position: -32px 0; } +.ui-icon-carat-1-se { background-position: -48px 0; } +.ui-icon-carat-1-s { background-position: -64px 0; } +.ui-icon-carat-1-sw { background-position: -80px 0; } +.ui-icon-carat-1-w { background-position: -96px 0; } +.ui-icon-carat-1-nw { background-position: -112px 0; } +.ui-icon-carat-2-n-s { background-position: -128px 0; } +.ui-icon-carat-2-e-w { background-position: -144px 0; } +.ui-icon-triangle-1-n { background-position: 0 -16px; } +.ui-icon-triangle-1-ne { background-position: -16px -16px; } +.ui-icon-triangle-1-e { background-position: -32px -16px; } +.ui-icon-triangle-1-se { background-position: -48px -16px; } +.ui-icon-triangle-1-s { background-position: -64px -16px; } +.ui-icon-triangle-1-sw { background-position: -80px -16px; } +.ui-icon-triangle-1-w { background-position: -96px -16px; } +.ui-icon-triangle-1-nw { background-position: -112px -16px; } +.ui-icon-triangle-2-n-s { background-position: -128px -16px; } +.ui-icon-triangle-2-e-w { background-position: -144px -16px; } +.ui-icon-arrow-1-n { background-position: 0 -32px; } +.ui-icon-arrow-1-ne { background-position: -16px -32px; } +.ui-icon-arrow-1-e { background-position: -32px -32px; } +.ui-icon-arrow-1-se { background-position: -48px -32px; } +.ui-icon-arrow-1-s { background-position: -64px -32px; } +.ui-icon-arrow-1-sw { background-position: -80px -32px; } +.ui-icon-arrow-1-w { background-position: -96px -32px; } +.ui-icon-arrow-1-nw { background-position: -112px -32px; } +.ui-icon-arrow-2-n-s { background-position: -128px -32px; } +.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } +.ui-icon-arrow-2-e-w { background-position: -160px -32px; } +.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } +.ui-icon-arrowstop-1-n { background-position: -192px -32px; } +.ui-icon-arrowstop-1-e { background-position: -208px -32px; } +.ui-icon-arrowstop-1-s { background-position: -224px -32px; } +.ui-icon-arrowstop-1-w { background-position: -240px -32px; } +.ui-icon-arrowthick-1-n { background-position: 0 -48px; } +.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } +.ui-icon-arrowthick-1-e { background-position: -32px -48px; } +.ui-icon-arrowthick-1-se { background-position: -48px -48px; } +.ui-icon-arrowthick-1-s { background-position: -64px -48px; } +.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } +.ui-icon-arrowthick-1-w { background-position: -96px -48px; } +.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } +.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } +.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } +.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } +.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } +.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } +.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } +.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } +.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } +.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } +.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } +.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } +.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } +.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } +.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } +.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } +.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } +.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } +.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } +.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } +.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } +.ui-icon-arrow-4 { background-position: 0 -80px; } +.ui-icon-arrow-4-diag { background-position: -16px -80px; } +.ui-icon-extlink { background-position: -32px -80px; } +.ui-icon-newwin { background-position: -48px -80px; } +.ui-icon-refresh { background-position: -64px -80px; } +.ui-icon-shuffle { background-position: -80px -80px; } +.ui-icon-transfer-e-w { background-position: -96px -80px; } +.ui-icon-transferthick-e-w { background-position: -112px -80px; } +.ui-icon-folder-collapsed { background-position: 0 -96px; } +.ui-icon-folder-open { background-position: -16px -96px; } +.ui-icon-document { background-position: -32px -96px; } +.ui-icon-document-b { background-position: -48px -96px; } +.ui-icon-note { background-position: -64px -96px; } +.ui-icon-mail-closed { background-position: -80px -96px; } +.ui-icon-mail-open { background-position: -96px -96px; } +.ui-icon-suitcase { background-position: -112px -96px; } +.ui-icon-comment { background-position: -128px -96px; } +.ui-icon-person { background-position: -144px -96px; } +.ui-icon-print { background-position: -160px -96px; } +.ui-icon-trash { background-position: -176px -96px; } +.ui-icon-locked { background-position: -192px -96px; } +.ui-icon-unlocked { background-position: -208px -96px; } +.ui-icon-bookmark { background-position: -224px -96px; } +.ui-icon-tag { background-position: -240px -96px; } +.ui-icon-home { background-position: 0 -112px; } +.ui-icon-flag { background-position: -16px -112px; } +.ui-icon-calendar { background-position: -32px -112px; } +.ui-icon-cart { background-position: -48px -112px; } +.ui-icon-pencil { background-position: -64px -112px; } +.ui-icon-clock { background-position: -80px -112px; } +.ui-icon-disk { background-position: -96px -112px; } +.ui-icon-calculator { background-position: -112px -112px; } +.ui-icon-zoomin { background-position: -128px -112px; } +.ui-icon-zoomout { background-position: -144px -112px; } +.ui-icon-search { background-position: -160px -112px; } +.ui-icon-wrench { background-position: -176px -112px; } +.ui-icon-gear { background-position: -192px -112px; } +.ui-icon-heart { background-position: -208px -112px; } +.ui-icon-star { background-position: -224px -112px; } +.ui-icon-link { background-position: -240px -112px; } +.ui-icon-cancel { background-position: 0 -128px; } +.ui-icon-plus { background-position: -16px -128px; } +.ui-icon-plusthick { background-position: -32px -128px; } +.ui-icon-minus { background-position: -48px -128px; } +.ui-icon-minusthick { background-position: -64px -128px; } +.ui-icon-close { background-position: -80px -128px; } +.ui-icon-closethick { background-position: -96px -128px; } +.ui-icon-key { background-position: -112px -128px; } +.ui-icon-lightbulb { background-position: -128px -128px; } +.ui-icon-scissors { background-position: -144px -128px; } +.ui-icon-clipboard { background-position: -160px -128px; } +.ui-icon-copy { background-position: -176px -128px; } +.ui-icon-contact { background-position: -192px -128px; } +.ui-icon-image { background-position: -208px -128px; } +.ui-icon-video { background-position: -224px -128px; } +.ui-icon-script { background-position: -240px -128px; } +.ui-icon-alert { background-position: 0 -144px; } +.ui-icon-info { background-position: -16px -144px; } +.ui-icon-notice { background-position: -32px -144px; } +.ui-icon-help { background-position: -48px -144px; } +.ui-icon-check { background-position: -64px -144px; } +.ui-icon-bullet { background-position: -80px -144px; } +.ui-icon-radio-on { background-position: -96px -144px; } +.ui-icon-radio-off { background-position: -112px -144px; } +.ui-icon-pin-w { background-position: -128px -144px; } +.ui-icon-pin-s { background-position: -144px -144px; } +.ui-icon-play { background-position: 0 -160px; } +.ui-icon-pause { background-position: -16px -160px; } +.ui-icon-seek-next { background-position: -32px -160px; } +.ui-icon-seek-prev { background-position: -48px -160px; } +.ui-icon-seek-end { background-position: -64px -160px; } +.ui-icon-seek-start { background-position: -80px -160px; } +/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ +.ui-icon-seek-first { background-position: -80px -160px; } +.ui-icon-stop { background-position: -96px -160px; } +.ui-icon-eject { background-position: -112px -160px; } +.ui-icon-volume-off { background-position: -128px -160px; } +.ui-icon-volume-on { background-position: -144px -160px; } +.ui-icon-power { background-position: 0 -176px; } +.ui-icon-signal-diag { background-position: -16px -176px; } +.ui-icon-signal { background-position: -32px -176px; } +.ui-icon-battery-0 { background-position: -48px -176px; } +.ui-icon-battery-1 { background-position: -64px -176px; } +.ui-icon-battery-2 { background-position: -80px -176px; } +.ui-icon-battery-3 { background-position: -96px -176px; } +.ui-icon-circle-plus { background-position: 0 -192px; } +.ui-icon-circle-minus { background-position: -16px -192px; } +.ui-icon-circle-close { background-position: -32px -192px; } +.ui-icon-circle-triangle-e { background-position: -48px -192px; } +.ui-icon-circle-triangle-s { background-position: -64px -192px; } +.ui-icon-circle-triangle-w { background-position: -80px -192px; } +.ui-icon-circle-triangle-n { background-position: -96px -192px; } +.ui-icon-circle-arrow-e { background-position: -112px -192px; } +.ui-icon-circle-arrow-s { background-position: -128px -192px; } +.ui-icon-circle-arrow-w { background-position: -144px -192px; } +.ui-icon-circle-arrow-n { background-position: -160px -192px; } +.ui-icon-circle-zoomin { background-position: -176px -192px; } +.ui-icon-circle-zoomout { background-position: -192px -192px; } +.ui-icon-circle-check { background-position: -208px -192px; } +.ui-icon-circlesmall-plus { background-position: 0 -208px; } +.ui-icon-circlesmall-minus { background-position: -16px -208px; } +.ui-icon-circlesmall-close { background-position: -32px -208px; } +.ui-icon-squaresmall-plus { background-position: -48px -208px; } +.ui-icon-squaresmall-minus { background-position: -64px -208px; } +.ui-icon-squaresmall-close { background-position: -80px -208px; } +.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } +.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } +.ui-icon-grip-solid-vertical { background-position: -32px -224px; } +.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } +.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } +.ui-icon-grip-diagonal-se { background-position: -80px -224px; } + + +/** Misc */ + +/* Corner radius */ +.ui-corner-all, +.ui-corner-top, +.ui-corner-left, +.ui-corner-tl, +.ui-menu .ui-menu-item.ui-menu-item-first a { + border-top-left-radius: 4px; +} +.ui-corner-all, +.ui-corner-top, +.ui-corner-right, +.ui-corner-tr, +.ui-menu .ui-menu-item.ui-menu-item-first a { + border-top-right-radius:4px; +} +.ui-corner-all, +.ui-corner-bottom, +.ui-corner-left, +.ui-corner-bl, +.ui-menu .ui-menu-item.ui-menu-item-last a, +.ui-dialog-buttonpane, +.ui-datepicker-multi .ui-datepicker-group-first .ui-datepicker-header, +.ui-datepicker .ui-datepicker-buttonpane { + border-bottom-left-radius: 4px; +} +.ui-corner-all, +.ui-corner-bottom, +.ui-corner-right, +.ui-corner-br, +.ui-menu .ui-menu-item.ui-menu-item-last a, +.ui-dialog-buttonpane, +.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header, +.ui-datepicker .ui-datepicker-buttonpane { + border-bottom-right-radius: 4px; +} + +/* Overlays */ +.ui-widget-overlay { + background: rgba(255,255,255,.5); +} +.ui-widget-shadow { + margin: -7px 0 0 -7px; + padding: 7px; + background: rgba(0,0,0,.3); + border-radius: 8px; +} + +/* SunHater Fixes */ + +.ui-accordion-content-active, .ui-tabs, .ui-slider-range, .ui-datepicker, .ui-dialog { + border-color: #1b79b8; +} + +.ui-slider .ui-slider-range { + border: 1px solid #1b79b8; + top: -1px +} + +.ui-progressbar { + overflow:visible; +} +.ui-progressbar-value { + border: 1px solid #1b79b8; + margin-top: -1px +} + +.ui-accordion-header, +.ui-tabs-nav, +.ui-button, +.ui-tabs li, +.ui-slider-handle, +.ui-slider-range, +.ui-datepicker-header, +.ui-datepicker-header a:hover, +.ui-datepicker-calendar .ui-state-default, +.ui-progressbar-value, +.ui-menu .ui-menu-item a.ui-state-focus, +.ui-menu .ui-menu-item a.ui-state-active, +.ui-dialog-titlebar, +.ui-dialog-titlebar-close.ui-state-default.ui-state-hover, +.ui-datepicker .ui-datepicker-buttonpane button { + box-shadow: inset 0 0 7px #fff, inset 0 0 3px #fff; +} + +.ui-spinner, +.ui-menu { + box-shadow: inset 0 0 4px #6b6b6b; +} + +.ui-accordion-content, +.ui-tabs, +.ui-dialog-content, +.ui-dialog-buttonpane, +.ui-datepicker, +.ui-datepicker .ui-datepicker-buttonpane { + box-shadow: inset 0 0 4px #1b79b8; +} + +.ui-state-default, +.ui-state-focus, +.ui-state-active, +.ui-widget-header { + text-shadow: + 1px 0 rgba(0,0,0,.2), + -1px 0 rgba(0,0,0,.2), + 0 -1px rgba(0,0,0,.2), + 0 1px rgba(0,0,0,.2), + 1px 1px rgba(0,0,0,.2), + -1px -1px rgba(0,0,0,.2), + 1px -1px rgba(0,0,0,.2), + -1px 1px rgba(0,0,0,.2); +} + +.ui-tabs .ui-state-active, +.ui-datepicker .ui-state-highlight { + text-shadow: none; +} +.ui-datepicker .ui-state-highlight { + color: #215b82; + border-color: #1b79b8; + box-shadow: inset 0 0 4px #1b79b8; + background: #fff; + background: -webkit-linear-gradient(top, #dfeef8, #fff); + background: -moz-linear-gradient(top, #dfeef8, #fff); + background: -ms-linear-gradient(top, #dfeef8, #fff); + background: -o-linear-gradient(top, #dfeef8, #fff); + background: linear-gradient(to bottom, #dfeef8, #fff); +} + +.ui-progressbar, .ui-slider, .ui-menu { + box-shadow: inset 0 0 4px #6b6b6b; + background: #fff; + background: -webkit-linear-gradient(top, #f0f0f0, #fff); + background: -moz-linear-gradient(top, #f0f0f0, #fff); + background: -ms-linear-gradient(top, #f0f0f0, #fff); + background: -o-linear-gradient(top, #f0f0f0, #fff); + background: linear-gradient(to bottom, #f0f0f0, #fff); +} + +.ui-slider, .ui-spinner, .ui-progressbar, .ui-menu { + border-color: #6b6b6b; +} + +.ui-datepicker-calendar .ui-state-default { + border-radius: 3px; +} + +.ui-tabs .ui-tabs-nav { + margin: -1px; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; + padding-left:3px; +} + +.ui-tabs-active.ui-state-active { + background: #fff; + background: -webkit-linear-gradient(top, #ccc, #ddd, #eee, #fff, #fff, #fff); + background: -moz-linear-gradient(top, #ccc, #ddd, #eee, #fff, #fff, #fff); + background: -ms-linear-gradient(top, #ccc, #ddd, #eee, #fff, #fff, #fff); + background: -o-linear-gradient(top, #ccc, #ddd, #eee, #fff, #fff, #fff); + background: linear-gradient(to bottom, #ccc, #ddd, #eee, #fff, #fff, #fff); + box-shadow: inset 0 0 5px #fff, inset 0 0 5px #fff, inset 0 0 5px #fff; +} +.ui-tabs-active.ui-state-active a { + color: #215b82; +} +.ui-state-default, .ui-state-default a { + outline: 0; +} +.ui-datepicker-header, +.ui-dialog-titlebar { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; + margin: -5px -5px 0 -5px; +} +.ui-datepicker-header { + margin: -11px -11px 5px -11px; +} + +.ui-datepicker-header a:hover { + cursor: pointer; +} + +.ui-dialog-titlebar-close.ui-state-default { + border-color: transparent; + background: none; + box-shadow: none; +} + +.ui-dialog-titlebar-close.ui-state-default.ui-state-hover { + border-color: #6b6b6b; + background: #6b6b6b} + +.ui-dialog-buttonpane { + background: #e4f5ff; + border-top-color: #1b79b8; + margin: 0 -4px -4px -4px; + padding: 0; +} + + +/*** shCheckset */ +/* +.shcs { + margin: 0; +} +.shcs > div { + border: 1px solid; + border-top: 0; + padding: 5px; + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; +} +.shcs > input, .shcs > input:focus, .shcs > input:hover { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + margin:0; +} +.shcs label { + padding: 2px 5px 2px 2px; + border: 1px solid transparent; + border-radius: 4px; + color: #6b6b6b; +} +.shcs > div, .shcs label:hover { + border-color: #6b6b6b; + box-shadow: inset 0 0 4px #6b6b6b; + background: #fff; + background: -webkit-linear-gradient(top, #f0f0f0, #fff); + background: -moz-linear-gradient(top, #f0f0f0, #fff); + background: -ms-linear-gradient(top, #f0f0f0, #fff); + background: -o-linear-gradient(top, #f0f0f0, #fff); + background: linear-gradient(to bottom, #f0f0f0, #fff); +} +.shcs label:hover { + color: #6b6b6b; + cursor: pointer; +} +.shcs > div.focus, .shcs label.checked { + border-color: #1b79b8; + box-shadow: inset 0 0 4px #1b79b8; + color: #000; + background: #fff; + background: -webkit-linear-gradient(top, #dfeef8, #fff); + background: -moz-linear-gradient(top, #dfeef8, #fff); + background: -ms-linear-gradient(top, #dfeef8, #fff); + background: -o-linear-gradient(top, #dfeef8, #fff); + background: linear-gradient(to bottom, #dfeef8, #fff); +} +.shcs label.checked div.checker { + border-color: #1b79b8; + background: #1b79b8; + background: -webkit-linear-gradient(top, #59b5f2, #1b79b8); + background: -moz-linear-gradient(top, #59b5f2, #1b79b8); + background: -ms-linear-gradient(top, #59b5f2, #1b79b8); + background: -o-linear-gradient(top, #59b5f2, #1b79b8); + background: linear-gradient(to bottom, #59b5f2, #1b79b8); +} +.shcs label.checked div.checker.hover { + border-color: #1b79b8; + background: #1b79b8; + background: -webkit-linear-gradient(top, #1b79b8, #59b5f2); + background: -moz-linear-gradient(top, #1b79b8, #59b5f2); + background: -ms-linear-gradient(top, #1b79b8, #59b5f2); + background: -o-linear-gradient(top, #1b79b8, #59b5f2); + background: linear-gradient(to bottom, #1b79b8, #59b5f2); +} + +.shcs div.checker.focus { + border-color: #6b6b6b; + background: #6b6b6b; + background: -webkit-linear-gradient(top, #ababab, #6b6b6b); + background: -moz-linear-gradient(top, #ababab, #6b6b6b); + background: -ms-linear-gradient(top, #ababab, #6b6b6b); + background: -o-linear-gradient(top, #ababab, #6b6b6b); + background: linear-gradient(to bottom, #ababab, #6b6b6b); + box-shadow: inset 0 0 7px #fff, inset 0 0 3px #fff; +} + +.shcs div.checker.focus.hover { + border-color: #6b6b6b; + background: #6b6b6b; + background: -webkit-linear-gradient(top, #6b6b6b, #ababab); + background: -moz-linear-gradient(top, #6b6b6b, #ababab); + background: -ms-linear-gradient(top, #6b6b6b, #ababab); + background: -o-linear-gradient(top, #6b6b6b, #ababab); + background: linear-gradient(to bottom, #6b6b6b, #ababab); +} + +.shcs label > span { + position:relative; + margin-left:5px; + top:1px; +}*/ +/* COMMON - BEGIN */ + +/* FONT SETTINGS */ +.tf-select, +.tf-input, +.tf-textarea, +.tf-multiple, +.tf-label, +.tf-fieldset legend, +.tf-file, +.tf-file input, +.tf-radio, +.tf-checkbox, +.tf-button, +.tf-input.tf-color, +.tf-input.tf-range { + font-size: 13px; + cursor: pointer; +} + +/* FIELD - NORMAL */ +.tf-select .tf-selected, +.tf-input, +.tf-multiple, +.tf-textarea, +.tf-file .tf-info, +.tf-radio, +.tf-checkbox { + background: #f0f0f0; + background: -webkit-linear-gradient(top, #e3e3e3, #fff); + background: -moz-linear-gradient(top, #e3e3e3, #fff); + background: -ms-linear-gradient(top, #e3e3e3, #fff); + background: -o-linear-gradient(top, #e3e3e3, #fff); + background: linear-gradient(to bottom, #e3e3e3, #fff); + box-shadow: inset 0 0 2px #6b6b6b; + border: 1px solid #6b6b6b; + border-radius: 4px; + color: #6b6b6b; + padding: 6px 10px; +} + +/* FIELD - FOCUSED */ +.tf-select.tf-focused .tf-selected, +.tf-select .tf-menu, +.tf-multiple.tf-focused, +.tf-input:focus, .tf-textarea:focus, +.tf-file.tf-focused .tf-info, +.tf-radio.tf-focused, +.tf-checkbox.tf-focused { + background: #d2eaf6; + background: -webkit-linear-gradient(top, #d2eaf6, #fff); + background: -moz-linear-gradient(top, #d2eaf6, #fff); + background: -ms-linear-gradient(top, #d2eaf6, #fff); + background: -o-linear-gradient(top, #d2eaf6, #fff); + background: linear-gradient(to bottom, #d2eaf6, #fff); + box-shadow: inset 0 0 2px #1b79b8; + border: 1px solid #1b79b8; + color: #1b79b8; +} + +/* BUTTON - NORMAL */ +.tf-button, +.tf-file .tf-button { + background: #6b6b6b; + background: -webkit-linear-gradient(top, #ababab, #6b6b6b); + background: -moz-linear-gradient(top, #ababab, #6b6b6b); + background: -ms-linear-gradient(top, #ababab, #6b6b6b); + background: -o-linear-gradient(top, #ababab, #6b6b6b); + background: linear-gradient(to bottom, #ababab, #6b6b6b); + box-shadow: inset 0 0 7px #fff, inset 0 0 3px #fff; + border: 1px solid #6b6b6b; + border-radius: 4px; + padding: 6px 10px; +} + +/* BUTTON - FOCUSED */ +.tf-file.tf-focused .tf-button, +.tf-button.tf-focused, +.tf-select.tf-focused .tf-button{ + background: #1b79b8; + background: -webkit-linear-gradient(top, #59b5f2, #1b79b8); + background: -moz-linear-gradient(top, #59b5f2, #1b79b8); + background: -ms-linear-gradient(top, #59b5f2, #1b79b8); + background: -o-linear-gradient(top, #59b5f2, #1b79b8); + background: linear-gradient(to bottom, #59b5f2, #1b79b8); + border-color: #1b79b8; +} + +/* BLACK OUTLINE, WHITE TEXT */ +.tf-select .tf-menu .tf-hover, +.tf-multiple .tf-hover, +.tf-multiple .tf-selected, +.tf-button { + color: #fff; + text-shadow: + 1px 0 rgba(0,0,0,.2), + -1px 0 rgba(0,0,0,.2), + 0 -1px rgba(0,0,0,.2), + 0 1px rgba(0,0,0,.2), + 1px 1px rgba(0,0,0,.2), + -1px -1px rgba(0,0,0,.2), + 1px -1px rgba(0,0,0,.2), + -1px 1px rgba(0,0,0,.2); +} + +/* COMMON - END */ + +/* SELECT BOX - BEGIN */ + +.tf-select .tf-selected { + border-radius: 4px 0 0 4px; +} +.tf-select .tf-button { + border-left: none; + border-radius: 0 4px 4px 0; +} + +.tf-select .tf-button span { + display: block; + background: url('img/ui-icons_white.png') -64px -15px; + width: 16px; + margin-left: 4px; + margin-right: 5px; +} +.tf-select .tf-menu { + border-radius: 0 0 4px 4px; +} +.tf-select .tf-menu div, +.tf-multiple div { + border: 1px solid transparent; + border-left-width: 0; + border-right-width: 0; + padding: 6px 10px; + margin-top: -1px; +} +.tf-select .tf-menu .tf-hover, +.tf-multiple.tf-focused .tf-hover, +.tf-multiple.tf-focused .tf-selected, +.tf-select.tf-opened.tf-focused .tf-button { + border-color: #1b79b8; + background: #59b5f2; + background: -webkit-linear-gradient(top, #1b79b8, #59b5f2); + background: -moz-linear-gradient(top, #1b79b8, #59b5f2); + background: -ms-linear-gradient(top, #1b79b8, #59b5f2); + background: -o-linear-gradient(top, #1b79b8, #59b5f2); + background: linear-gradient(to bottom, #1b79b8, #59b5f2); + box-shadow: inset 0 0 7px #fff, inset 0 0 3px #fff; +} +.tf-select.tf-opened .tf-button { + background: #ababab; + background: -webkit-linear-gradient(top, #6b6b6b, #ababab); + background: -moz-linear-gradient(top, #6b6b6b, #ababab); + background: -ms-linear-gradient(top, #6b6b6b, #ababab); + background: -o-linear-gradient(top, #6b6b6b, #ababab); + background: linear-gradient(to bottom, #6b6b6b, #ababab); +} +.tf-select.tf-opened .tf-button { + +} +.tf-select .tf-menu .tf-group-last, +.tf-select .tf-menu div.tf-last { + border-bottom-width: 0; +} +.tf-select .tf-menu ul { + overflow: hidden; +} +.tf-select .tf-menu li.tf-last { + margin-bottom: -1px; +} +.tf-select .tf-menu .tf-last { + border-radius: 0 0 4px 4px; +} +.tf-select.tf-opened .tf-selected { + border-radius: 4px 0 0 0; +} +.tf-select.tf-opened .tf-button { + border-radius: 0 4px 0 0; +} +.tf-select .tf-menu li, +.tf-multiple.tf-focused li { + border-bottom: 1px solid #54b0e0; + border-top: 1px solid #54b0e0; + margin: -1px 0; +} +.tf-select .tf-menu li > span, +.tf-multiple li > span, +.tf-multiple.tf-focused li > span { + display: block; + padding: 6px 10px; + text-align: center; + font-weight: bold; + color: #6b6b6b; + background: #a7deff; + border-bottom: 1px solid #54b0e0; + cursor: default; + white-space: nowrap; +} + +/* SELECT BOX - END */ + +/* MULTIPLE SELECT BOX - BEGIN */ + +.tf-multiple { + padding: 0; +} +.tf-multiple li { + border: 1px solid #54b0e0; + border-right: none; + border-left: none; + margin: -1px 0; +} +.tf-multiple li > span { + color: #70a5d1; + border-color: #54b0e0; + background: #c1ddf5; +} +.tf-multiple .tf-hover, +.tf-multiple .tf-selected, +.tf-multiple.tf-focused .tf-hover { + background: #b7def2; + background: -webkit-linear-gradient(top, #54b0e0, #b7def2); + background: -moz-linear-gradient(top, #54b0e0, #b7def2); + background: -ms-linear-gradient(top, #54b0e0, #b7def2); + background: -o-linear-gradient(top, #54b0e0, #b7def2); + background: linear-gradient(to bottom, #54b0e0, #b7def2); + box-shadow: inset 0 0 2px #fff, inset 0 0 2px #fff; + border-color: #54b0e0; +} +.tf-multiple .tf-hover, +.tf-multiple .tf-selected { + border: 1px solid #54b0e0; + border-left: none; + border-right: none; +} +.tf-multiple div.tf-first { + border-top: none; + border-radius: 4px 4px 0 0; + margin-top: 0; +} +.tf-multiple div.tf-last { + border-bottom: none; + border-radius: 0 0 4px 4px; +} +.tf-multiple .tf-group-first { + border-top: none; + margin-top: 0; +} +.tf-multiple li.tf-last, +.tf-multiple .tf-group-last { + border-bottom: none; +} + +/* MULTIPLE SELECT BOX - END */ + +/* FILE UPLOAD BOX - BEGIN */ + +.tf-file { + width: 200px; + padding: 0; + overflow: auto; +} +.tf-file .tf-info, .tf-file.tf-focused .tf-info { + padding: 6px 10px; + border-radius: 4px 0 0 4px; + border-right: none; +} +.tf-file .tf-button { + border-radius: 0 4px 4px 0; + color: transparent; + text-shadow: none; + padding: 6px 8px; +} +.tf-file .tf-button span { + margin: 0 0 0 -4px; + width: 16px; + height: 16px; + display: block; + overflow: hidden; + background: url('img/ui-icons_white.png') -16px -96px; +} +.tf-file .tf-button:after { + content: "\00a0"; +} +.tf-file input::-webkit-file-upload-button { + cursor: pointer; +} + +/* FILE UPLOAD BOX - END */ + +/* RADIO BUTTON - BEGIN */ + +.tf-radio { + width: 15px; + height: 15px; + padding: 0; + border-radius: 8px; +} +.tf-radio input { + width: 17px; + height: 17px; + margin: -1px 0 0 -1px; + cursor: pointer; +} +.tf-radio span { + width: 15px; + height: 15px; + display: block; + float: right; +} +.tf-radio.tf-checked span { + background: url('img/ui-icons_black.png') -80px -145px; +} +.tf-radio.tf-checked.tf-focused span { + background-image: url('img/ui-icons_blue.png'); +} + +/* RADIO BUTTON - END */ + +/* CHECK BOX - BEGIN */ + +.tf-checkbox { + padding: 0; + width: 15px; + height: 15px; + border-radius: 3px; +} +.tf-checkbox input { + width: 17px; + height: 17px; + margin: -1px 0 0 -1px; + cursor: pointer; +} +.tf-checkbox.tf-checked span { + width: 15px; + height: 15px; + display: block; + background: url('img/ui-icons_black.png') -64px -145px; + float: right; +} +.tf-checkbox.tf-focused.tf-checked span { + background-image: url('img/ui-icons_blue.png'); +} + + +/* CHECK BX - END */ + +/* BUTTON */ +.tf-button { + overflow: hidden; + padding: 0; +} +.tf-button span { + margin: 3px 7px; + float: right; +} +.tf-button input, +.tf-button button { + cursor: pointer; +} + +/* TEXT & TEXTAREA - BEGIN */ + +.tf-input, .tf-textarea { + outline: none; + cursor: text; + margin: 0; +} +/*.tf-input.tf-readOnly, +.tf-textarea.tf-readOnly, +.tf-input.tf-readOnly:focus, +.tf-textarea.tf-readOnly:focus { + background: #e4e4e4; + background: -webkit-linear-gradient(top, #e4e4e4, #fff); + background: -moz-linear-gradient(top, #e4e4e4, #fff); + background: -ms-linear-gradient(top, #e4e4e4, #fff); + background: -o-linear-gradient(top, #e4e4e4, #fff); + background: linear-gradient(to bottom, #e4e4e4, #fff); + box-shadow: inset 0 0 2px #a2a2a2; + border: 1px solid #a2a2a2; + border-radius: 4px; + color: #888; + padding: 6px 10px; +}*/ + +/* PLACEHOLDER COLORS */ + +.tf-input::-webkit-input-placeholder, +.tf-textarea::-webkit-input-placeholder { + color: #bbb; +} +.tf-input:-moz-placeholder, +.tf-textarea:-moz-placeholder { + color: #aaa; +} +.tf-input::-moz-placeholder, +.tf-textarea::-moz-placeholder { + color: #aaa; +} +.tf-input:-ms-input-placeholder, +.tf-textarea:-ms-input-placeholder { + color: #bbb; +} +.tf-input:focus::-webkit-input-placeholder, +.tf-textarea:focus::-webkit-input-placeholder { + color: #abc7d6; +} +.tf-input:focus:-moz-placeholder, +.tf-textarea:focus:-moz-placeholder { + color: #54B0E0; +} +.tf-input:focus::-moz-placeholder, +.tf-textarea:focus::-moz-placeholder { + color: #54B0E0; +} +.tf-input:focus:-ms-input-placeholder, +.tf-textarea:focus:-ms-input-placeholder { + color: #abc7d6; +} + +/* READ-ONLY PLACEHOLDERS */ + +.tf-input.tf-readOnly::-webkit-input-placeholder, +.tf-textarea.tf-readOnly::-webkit-input-placeholder { + color: #d4d4d4; +} +.tf-input.tf-readOnly:-moz-placeholder, +.tf-textarea.tf-readOnly:-moz-placeholder { + color: #dedede; +} +.tf-input.tf-readOnly::-moz-placeholder, +.tf-textarea.tf-readOnly::-moz-placeholder { + color: #dedede; +} +.tf-input.tf-readOnly:-ms-input-placeholder, +.tf-textarea.tf-readOnly:-ms-input-placeholder { + color: #d4d4d4; +} +.tf-input.tf-readOnly:focus::-webkit-input-placeholder, +.tf-textarea.tf-readOnly:focus::-webkit-input-placeholder { + color: #d4d4d4; +} +.tf-input.tf-readOnly:focus:-moz-placeholder, +.tf-textarea.tf-readOnly:focus:-moz-placeholder { + color: #dedede; +} +.tf-input.tf-readOnly:focus::-moz-placeholder, +.tf-textarea.tf-readOnly:focus::-moz-placeholder { + color: #dedede; +} +.tf-input.tf-readOnly:focus:-ms-input-placeholder, +.tf-textarea.tf-readOnly:focus:-ms-input-placeholder { + color: #d4d4d4; +} + +/* TEXT & TEXTAREA - END */ + +/* FIELD SET */ +.tf-fieldset { +border: 1px solid #6B6B6B; + box-shadow: inset 0 0 4px #6B6B6B; + border-radius: 4px; + background: #fff; + background: -webkit-linear-gradient(top, #e3e3e3, #fff); + background: -moz-linear-gradient(top, #e3e3e3, #fff); + background: -ms-linear-gradient(top, #e3e3e3, #fff); + background: -o-linear-gradient(top, #e3e3e3, #fff); + background: linear-gradient(to bottom, #e3e3e3, #fff); + margin: 0 10px 10px 0; + padding: 10px; +} +.tf-fieldset legend { + font-weight: bold; + color: #6B6B6B; + text-shadow: + 1px 0 rgba(255,255,255,.5), + -1px 0 rgba(255,255,255,.5), + 0 -1px rgba(255,255,255,.5), + 0 1px rgba(255,255,255,.5), + 1px 1px rgba(255,255,255,.5), + -1px -1px rgba(255,255,255,.5), + 1px -1px rgba(255,255,255,.5), + -1px 1px rgba(255,255,255,.5), + 0 0 5px #fff; +} + +/* MISC */ + +.tf-label { + color: #6b6b6b; + margin: 0 3px; +} +.tf-label.tf-focused { + color: #1b79b8; +} +.tf-disabled { + opacity: .5; + filter: alpha(opacity=50); +} +.tf-disabled, +.tf-disabled input, +.tf-disabled button, +.tf-disabled * +*.tf-disabled { + cursor: default; +} +.tf-file.tf-disabled input::-webkit-file-upload-button { + cursor: pointer; +} +.tf-fieldset.tf-disabled, +.tf-form.tf-disabled { + opacity: 1; + filter: alpha(opacity=100); +} + +.tf-input.tf-color { + width: 30px; + padding: 0; + height: 24px; +} +.tf-input.tf-number { + text-align: right; +} +.tf-input.tf-range { + height: 9px; + margin: 8px 0 7px 0; +} +.tf-input.tf-search, +.tf-input.tf-search.tf-readOnly{ + border-radius: 11px; +} +.tf-input.tf-datetime, +.tf-input.tf-datetime-local, +.tf-input.tf-month, +.tf-input.tf-time, +.tf-input.tf-week, +.tf-input.tf-datetime:focus, +.tf-input.tf-datetime-local:focus, +.tf-input.tf-month:focus, +.tf-input.tf-time:focus, +.tf-input.tf-week:focus { + padding: 1px 5px; +}* { + font-size: 13px; +} +body { + background: #e0e0e0; + color: #6B6B6B; +} +fieldset td { + white-space: nowrap; +} +#folders { + margin: 5px 5px 0 5px; +} +#files { + margin-right: 5px; +} + + +/* SHARED DECLARATIONS */ + +#toolbar a:hover, +#toolbar a.hover, +span.current, +span.regular:hover, +span.context, +a.drag > span.folder, +#clipboard div:hover, +div.file:hover, +#files div.selected, +#files div.selected:hover, +tr.selected > td, +tr.selected:hover > td, +#menu .list div a:hover { + color: #fff; + text-shadow: + 1px 0 rgba(0,0,0,.2), + -1px 0 rgba(0,0,0,.2), + 0 -1px rgba(0,0,0,.2), + 0 1px rgba(0,0,0,.2), + 1px 1px rgba(0,0,0,.2), + -1px -1px rgba(0,0,0,.2), + 1px -1px rgba(0,0,0,.2), + -1px 1px rgba(0,0,0,.2); +} + +#files, +#folders, +#toolbar a.selected { + border: 1px solid #6B6B6B; + box-shadow: inset 0 0 4px #6B6B6B; + border-radius: 4px; + background: #fff; + background: -webkit-linear-gradient(top, #f0f0f0, #fff); + background: -moz-linear-gradient(top, #f0f0f0, #fff); + background: -ms-linear-gradient(top, #f0f0f0, #fff); + background: -o-linear-gradient(top, #f0f0f0, #fff); + background: linear-gradient(to bottom, #f0f0f0, #fff); +} + +/* TOOLBAR */ + +#toolbar { + padding: 5px 0; +} +#toolbar a { + color: #6b6b6b; + margin-right: 5px; + border: 1px solid transparent; + outline: none; + display: block; + float: left; + border-radius: 4px; + padding:0; + background: #E0E0E0; +} +#toolbar a > span { + padding: 6px 10px 6px 26px; + diaplay: block; + float:left; + background: no-repeat 6px center; +} +#toolbar a:hover, +#toolbar a.hover { + border-color: #1b79b8; + background: #1b79b8; + background: -webkit-linear-gradient(top, #59b5f2, #1b79b8); + background: -moz-linear-gradient(top, #59b5f2, #1b79b8); + background: -ms-linear-gradient(top, #59b5f2, #1b79b8); + background: -o-linear-gradient(top, #59b5f2, #1b79b8); + background: linear-gradient(to bottom, #59b5f2, #1b79b8); + box-shadow: inset 0 0 7px #fff, inset 0 0 3px #fff; +} +#toolbar a[href="kcact:upload"] span { + background-image: url(img/icons/upload.png); +} +#toolbar a[href="kcact:refresh"] span { + background-image: url(img/icons/refresh.png); +} +#toolbar a[href="kcact:settings"] span { + background-image: url(img/icons/settings.png); +} +#toolbar a[href="kcact:about"] span { + background-image: url(img/icons/about.png); +} +#toolbar a[href="kcact:maximize"] span { + background-image: url(img/icons/maximize.png); +} + + +/* SETTINGS BAR */ + +#settings label { + cursor: pointer; +} +#settings fieldset { + margin-right:5px; + margin-bottom: 6px; + margin-top:-5px; + padding:6px; +} + + +/* FOLDERS */ + +div.folder { + padding-top: 2px; + margin-top: 4px; + white-space: nowrap; +} +div.folder a { + text-decoration: none; + cursor: default; + outline: none; + color: #6b6b6b; +} +span.folder { + padding: 2px 3px 2px 23px; + outline: none; + background: no-repeat 3px center; + cursor: pointer; + border-radius: 3px; + border: 1px solid transparent; +} +span.brace { + width: 16px; + height: 16px; + outline: none; +} +span.current { + transition: .3s; + background-image: url(img/tree/folder.png); + background-color: #3b98d6; + border-color: #3b98d6; + box-shadow: inset 0 0 7px #fff, inset 0 0 3px #fff; +} +span.regular { + transition: .3s; + background-image: url(img/tree/folder.png); + background-color: transparent; +} +span.regular:hover, span.context, a.drag > span.folder, #clipboard div:hover { + transition: .3s; + background-color: #c6c6c6; + border-color: #c6c6c6; + box-shadow: inset 0 0 7px #fff, inset 0 0 3px #fff; +} +span.opened { + background-image: url(img/tree/minus.png); +} +span.closed { + background-image: url(img/tree/plus.png); +} +span.denied { + background-image: url(img/tree/denied.png); +} + + +/* FILES */ + +div.file { + padding: 4px; + margin: 3px; + border: 1px solid transparent; + border-radius: 4px; +} +div.file:hover { + border-color: #aaa; + box-shadow: inset 0 0 7px #fff, inset 0 0 3px #fff; + background: #c6c6c6; + background: -webkit-linear-gradient(top, #e7e7e7, #c6c6c6); + background: -moz-linear-gradient(top, #e7e7e7, #c6c6c6); + background: -ms-linear-gradient(top, #e7e7e7, #c6c6c6); + background: -o-linear-gradient(top, #e7e7e7, #c6c6c6); + background: linear-gradient(to bottom, #e7e7e7, #c6c6c6); +} +div.file .name { + margin-top: 4px; + font-weight: bold; + height: 16px; + overflow: hidden; + padding-bottom: 2px; +} +div.file .time { + font-size: 10px; +} +div.file .size { + font-size: 10px; +} +#files div.selected, +#files div.selected:hover { + border-color: #3b98d6; + background: #3b98d6; + background: -webkit-linear-gradient(top, #7dc2f2, #3b98d6); + background: -moz-linear-gradient(top, #7dc2f2, #3b98d6); + background: -ms-linear-gradient(top, #7dc2f2, #3b98d6); + background: -o-linear-gradient(top, #7dc2f2, #3b98d6); + background: linear-gradient(to bottom, #7dc2f2, #3b98d6); + box-shadow: inset 0 0 7px #fff, inset 0 0 3px #fff; +} +tr.file > td { + padding: 3px 4px; +} +tr.file:hover > td { + background-color: #ddebf8; + transition: none; +} +tr.selected > td, +tr.selected:hover > td { + transition: .3s; + background-color: #5b9bda; +} +tr.file td.name { + background-position: 2px center; + padding-left: 22px; +} +a.denied { + color: #666; + opacity: 0.5; + filter: alpha(opacity:50); + cursor: default; +} +a.denied:hover { + background-color: #e4e3e2; + border-color: transparent; + box-shadow: none; +} + +/* FILE MENU */ + +#menu .ui-menu a span { + background: left center no-repeat; + padding-left: 20px; + white-space: nowrap; +} +#menu a[href="kcact:refresh"] span { + background-image: url(img/icons/refresh.png); +} +#menu a[href="kcact:mkdir"] span { + background-image: url(img/icons/folder-new.png); +} +#menu a[href="kcact:mvdir"] span, #menu a[href="kcact:mv"] span { + background-image: url(img/icons/rename.png); +} +#menu a[href="kcact:rmdir"] span, #menu a[href="kcact:rm"] span, #menu a[href="kcact:rmcbd"] span { + background-image: url(img/icons/delete.png); +} +#menu a[href="kcact:clpbrdadd"] span { + background-image: url(img/icons/clipboard-add.png); +} +#menu a[href="kcact:pick"] span, #menu a[href="kcact:pick_thumb"] span { + background-image: url(img/icons/select.png); +} +#menu a[href="kcact:download"] span { + background-image: url(img/icons/download.png); +} +#menu a[href="kcact:view"] span { + background-image: url(img/icons/view.png); +} +#menu a[href="kcact:cpcbd"] span { + background-image: url(img/icons/copy.png); +} +#menu a[href="kcact:mvcbd"] span { + background-image: url(img/icons/move.png); +} +#menu a[href="kcact:clrcbd"] span { + background-image: url(img/icons/clipboard-clear.png); +} + +/* CLIPBOARD */ + +#clipboard { + margin-left:-3px; + padding: 2px; +} +#clipboard div { + background: url(img/icons/clipboard.png) no-repeat center center; + border: 1px solid transparent; + padding: 2px; + cursor: pointer; + border-radius: 4px; +} +#clipboard.selected div, #clipboard.selected div:hover { + background-color: #3b98d6; + border-color: #3b98d6; + box-shadow: inset 0 0 7px #fff, inset 0 0 3px #fff; +} +#menu .list a, #menu .list a.ui-state-focus { + margin: -1px 0 0 -1px; + padding: 6px 10px; + border: 1px solid transparent; + background: none; + border-radius: 0; + text-shadow: none; + box-shadow: none; + color: #6b6b6b; +} +#menu .list a.first, #menu .list a.first.ui-state-focus { + border-radius: 4px 4px 0 0; +} +#menu .list a:hover { + border-color: #1b79b8; + background: #1b79b8; + background: -webkit-linear-gradient(top, #1b79b8, #59b5f2); + background: -moz-linear-gradient(top, #1b79b8, #59b5f2); + background: -ms-linear-gradient(top, #1b79b8, #59b5f2); + background: -o-linear-gradient(top, #1b79b8, #59b5f2); + background: linear-gradient(to bottom, #1b79b8, #59b5f2); + box-shadow: inset 0 0 7px #fff, inset 0 0 3px #fff; +} +#menu .list { + overflow:hidden; + max-height: 1px; + margin-bottom: -1px; + padding-bottom:1px; +} +#menu li.div-files { + margin: 0 0 1px 0; +} + +/* ABOUT DIALOG */ + +.about { + text-align: center; +} +.about div.head { + font-weight: bold; + font-size: 12px; + padding: 3px 0 8px 0; +} +.about div.head a { + background: url(img/kcf_logo.png) no-repeat left center; + padding: 0 0 0 27px; + font-size: 17px; + outline: none; +} + +.about a { + text-decoration: none; + color: #0055ff; +} + +.about a:hover { + text-decoration: underline; +} +#checkver { + margin: 5px 0 10px 0; +} +#loading, #checkver > span.loading { + background: url(img/loading.gif); + border: 1px solid #3687e2; + box-shadow: 0 0 3px #3687e2, inset 0 0 4px #fff, inset 0 0 5px #fff; + padding: 6px 10px; + border-radius: 4px; +} +#checkver a { + font-weight: normal; + padding: 3px 3px 3px 20px; + background: url(img/icons/download.png) no-repeat left center; +} + +/* IMAGE VIEWER */ + +.kcfImageViewer .ui-dialog-content { + cursor: pointer; +} +.kcfImageViewer .img { + background: url(img/bg_transparent.png); +} +.ui-dialog-titlebar.loading { + background: url(img/loading.gif); +} + +.ui-dialog-titlebar.loading .ui-dialog-title { + color: #6b6b6b; + text-shadow:none; + font-weight: normal; +} +.ui-dialog-titlebar.loading .ui-dialog-titlebar-close .ui-button-icon-primary.ui-icon.ui-icon-closethick { + background-image: url(img/ui-icons_black.png); +} + + +/* MISC */ + +#loading { + margin-right: 5px; +} +#loadingDirs { + padding: 5px 0 1px 24px; +} +#files.drag { + background: #ddebf8; +} + +#settings .tf-select { + margin: 3px 5px 6px 0; +} +#settings .tf-selected { + padding-top: 10px; + padding-bottom: 11px; +} +#settings .tf-select .tf-button { + padding-top: 7px; + padding-bottom: 8px; +} + +/* FIX FIELDSET BORDER RADIUS BUG ON IE */ +body.msie fieldset, +body.trident.rv fieldset { + border-radius: 0; +} \ No newline at end of file diff --git a/lib/kcfinder/cache/theme_default.js b/lib/kcfinder/cache/theme_default.js new file mode 100644 index 0000000..5cc0b16 --- /dev/null +++ b/lib/kcfinder/cache/theme_default.js @@ -0,0 +1,9 @@ +// Preload some images +$.each([ + "loading.gif", + "ui-icons_black.png", + "ui-icons_blue.png", + "ui-icons_white.png" +], function(i, img) { + new Image().src = "themes/default/img/" + img; +}); diff --git a/lib/kcfinder/composer.json b/lib/kcfinder/composer.json new file mode 100644 index 0000000..da925e4 --- /dev/null +++ b/lib/kcfinder/composer.json @@ -0,0 +1,48 @@ +{ + "name": "sunhater/kcfinder", + "description": "KCFinder web file manager", + "version": "3.20-test2", + "type": "library", + "keywords": [ + "kcfinder", + "finder", + "file", + "manager", + "explorer", + "file manager", + "file explorer" + ], + "homepage": "http://kcfinder.sunhater.com", + "time": "2014-08-24", + "license": [ + "GPL-3.0+", + "LGPL-3.0+" + ], + "authors": [ + { + "name": "Pavel Tzonkov", + "email": "sunhater@sunhater.com", + "homepage": "http://sunhater.com", + "role": "Developer" + } + ], + "support": { + "email": "sunhater@sunhater.com", + "issues": "https://github.com/sunhater/kcfinder/issues", + "source": "https://github.com/sunhater/kcfinder" + }, + "require": { + "php": ">=5.3.0", + "ext-gd": "*" + }, + "suggest": { + "ext-fileinfo": "*", + "ext-exif": "*", + "ext-curl": "*", + "ext-http": "*", + "ext-sockets": "*", + "ext-imagick": "*", + "ext-gmagick": "*", + "ext-zip": "*" + } +} \ No newline at end of file diff --git a/lib/kcfinder/conf/.htaccess b/lib/kcfinder/conf/.htaccess new file mode 100644 index 0000000..d61b264 --- /dev/null +++ b/lib/kcfinder/conf/.htaccess @@ -0,0 +1,4 @@ + +Order allow,deny +Deny from all + diff --git a/lib/kcfinder/conf/config.php b/lib/kcfinder/conf/config.php new file mode 100644 index 0000000..98d4278 --- /dev/null +++ b/lib/kcfinder/conf/config.php @@ -0,0 +1,118 @@ + + * @copyright 2010-2014 KCFinder Project + * @license http://opensource.org/licenses/GPL-3.0 GPLv3 + * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3 + * @link http://kcfinder.sunhater.com + */ + +/* IMPORTANT!!! Do not comment or remove uncommented settings in this file + even if you are using session configuration. + See http://kcfinder.sunhater.com/install for setting descriptions */ + +return array( + + +// GENERAL SETTINGS + + 'disabled' => false, + 'uploadURL' => "http://prints.local/docs", + 'uploadDir' => "", + 'theme' => "default", + + 'types' => array( + + // (F)CKEditor types + 'files' => "", + 'flash' => "swf", + 'images' => "*img", + + // TinyMCE types + 'file' => "", + 'media' => "swf flv avi mpg mpeg qt mov wmv asf rm", + 'image' => "*img", + ), + + +// IMAGE SETTINGS + + 'imageDriversPriority' => "imagick gmagick gd", + 'jpegQuality' => 90, + 'thumbsDir' => ".thumbs", + + 'maxImageWidth' => 0, + 'maxImageHeight' => 0, + + 'thumbWidth' => 100, + 'thumbHeight' => 100, + + 'watermark' => "", + + +// DISABLE / ENABLE SETTINGS + + 'denyZipDownload' => false, + 'denyUpdateCheck' => false, + 'denyExtensionRename' => false, + + +// PERMISSION SETTINGS + + 'dirPerms' => 0755, + 'filePerms' => 0644, + + 'access' => array( + + 'files' => array( + 'upload' => true, + 'delete' => true, + 'copy' => true, + 'move' => true, + 'rename' => true + ), + + 'dirs' => array( + 'create' => true, + 'delete' => true, + 'rename' => true + ) + ), + + 'deniedExts' => "exe com msi bat cgi pl php phps phtml php3 php4 php5 php6 py pyc pyo pcgi pcgi3 pcgi4 pcgi5 pchi6", + + +// MISC SETTINGS + + 'filenameChangeChars' => array(/* + ' ' => "_", + ':' => "." + */), + + 'dirnameChangeChars' => array(/* + ' ' => "_", + ':' => "." + */), + + 'mime_magic' => "", + + 'cookieDomain' => "", + 'cookiePath' => "", + 'cookiePrefix' => 'KCFINDER_', + + +// THE FOLLOWING SETTINGS CANNOT BE OVERRIDED WITH SESSION SETTINGS + + '_sessionVar' => "KCFINDER", + '_check4htaccess' => true, + '_normalizeFilenames' => false, + '_dropUploadMaxFilesize' => 10485760, + //'_tinyMCEPath' => "/tiny_mce", + //'_cssMinCmd' => "java -jar /path/to/yuicompressor.jar --type css {file}", + //'_jsMinCmd' => "java -jar /path/to/yuicompressor.jar --type js {file}", + ); diff --git a/lib/kcfinder/conf/upload.htaccess b/lib/kcfinder/conf/upload.htaccess new file mode 100644 index 0000000..48dd490 --- /dev/null +++ b/lib/kcfinder/conf/upload.htaccess @@ -0,0 +1,21 @@ + + php_flag engine Off + + + php_flag engine Off + + + php_flag engine Off + + + Options -ExecCGI + + +RemoveHandler .cgi .pl .py .pyc .pyo .phtml .php .php3 .php4 .php5 .php6 .pcgi .pcgi3 .pcgi4 .pcgi5 .pchi6 .inc +RemoveType .cgi .pl .py .pyc .pyo .phtml .php .php3 .php4 .php5 .php6 .pcgi .pcgi3 .pcgi4 .pcgi5 .pchi6 .inc +SetHandler None +SetHandler default-handler + +# Remove both lines below if you want to render HTML files from the upload folder +AddType text/plain .html +AddType text/plain .htm diff --git a/lib/kcfinder/core/.htaccess b/lib/kcfinder/core/.htaccess new file mode 100644 index 0000000..d61b264 --- /dev/null +++ b/lib/kcfinder/core/.htaccess @@ -0,0 +1,4 @@ + +Order allow,deny +Deny from all + diff --git a/lib/kcfinder/core/autoload.php b/lib/kcfinder/core/autoload.php new file mode 100644 index 0000000..8d1fbcf --- /dev/null +++ b/lib/kcfinder/core/autoload.php @@ -0,0 +1,33 @@ + + * @copyright 2010-2014 KCFinder Project + * @license http://opensource.org/licenses/GPL-3.0 GPLv3 + * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3 + * @link http://kcfinder.sunhater.com + */ + +spl_autoload_register(function($path) { + $path = explode("\\", $path); + + if (count($path) == 1) + return; + + list($ns, $class) = $path; + + if ($ns == "kcfinder") { + if (in_array($class, array("uploader", "browser", "minifier", "session"))) + require "core/class/$class.php"; + elseif (file_exists("core/types/$class.php")) + require "core/types/$class.php"; + elseif (file_exists("lib/class_$class.php")) + require "lib/class_$class.php"; + elseif (file_exists("lib/helper_$class.php")) + require "lib/helper_$class.php"; + } +}); diff --git a/lib/kcfinder/core/bootstrap.php b/lib/kcfinder/core/bootstrap.php new file mode 100644 index 0000000..69b7fdf --- /dev/null +++ b/lib/kcfinder/core/bootstrap.php @@ -0,0 +1,179 @@ + + * @copyright 2010-2014 KCFinder Project + * @license http://opensource.org/licenses/GPL-3.0 GPLv3 + * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3 + * @link http://kcfinder.sunhater.com + * + * This file is the place you can put any code (at the end of the file), + * which will be executed before any other. Suitable for: + * 1. Set PHP ini settings using ini_set() + * 2. Custom session save handler with session_set_save_handler() + * 3. Any custom integration code. If you use any global variables + * here, they can be accessed in conf/config.php via $GLOBALS + * array. It's recommended to use constants instead. + */ + + +// PHP VERSION CHECK +if (!preg_match('/^(\d+\.\d+)/', PHP_VERSION, $ver) || ($ver[1] < 5.3)) + die("You are using PHP " . PHP_VERSION . " when KCFinder require at least version 5.3.0! Some systems has an option to change the active PHP version. Please refer to your hosting provider or upgrade your PHP distribution."); + + +// SAFE MODE CHECK +if (ini_get("safe_mode")) + die("The \"safe_mode\" PHP ini setting is turned on! You cannot run KCFinder in safe mode."); + + +// CMS INTEGRATION +if (isset($_GET['cms']) && + (basename($_GET['cms']) == $_GET['cms']) && + is_file("integration/{$_GET['cms']}.php") +) + require "integration/{$_GET['cms']}.php"; + + +// REGISTER AUTOLOAD FUNCTION +require "core/autoload.php"; + + +// json_encode() IMPLEMENTATION IF JSON EXTENSION IS MISSING +if (!function_exists("json_encode")) { + + function json_encode($data) { + + if (is_array($data)) { + $ret = array(); + + // OBJECT + if (array_keys($data) !== range(0, count($data) - 1)) { + foreach ($data as $key => $val) + $ret[] = json_encode((string) $key) . ':' . json_encode($val); + return "{" . implode(",", $ret) . "}"; + + // ARRAY + } else { + foreach ($data as $val) + $ret[] = json_encode($val); + return "[" . implode(",", $ret) . "]"; + } + + // BOOLEAN OR NULL + } elseif (is_bool($data) || ($data === null)) + return ($data === null) + ? "null" + : ($data ? "true" : "false"); + + // FLOAT + elseif (is_float($data)) + return rtrim(rtrim(number_format($data, 14, ".", ""), "0"), "."); + + // INTEGER + elseif (is_int($data)) + return $data; + + // STRING + return '"' . + str_replace('/', "\\/", + str_replace("\t", "\\t", + str_replace("\r", "\\r", + str_replace("\n", "\\n", + str_replace('"', "\\\"", + str_replace("\\", "\\\\", + $data)))))) . '"'; + } +} + + +// CUSTOM SESSION SAVE HANDLER CLASS EXAMPLE +// +// Uncomment & edit it if the application you want to integrate with, have +// its own session save handler. It's not even needed to save instances of +// this class in variables. Just add a row: +// new SessionSaveHandler(); +// and your handler will rule the sessions ;-) + +/* +class SessionSaveHandler { + protected $savePath; + protected $sessionName; + + public function __construct() { + session_set_save_handler( + array($this, "open"), + array($this, "close"), + array($this, "read"), + array($this, "write"), + array($this, "destroy"), + array($this, "gc") + ); + } + + // Open function, this works like a constructor in classes and is + // executed when the session is being opened. The open function expects + // two parameters, where the first is the save path and the second is the + // session name. + public function open($savePath, $sessionName) { + $this->savePath = $savePath; + $this->sessionName = $sessionName; + return true; + } + + // Close function, this works like a destructor in classes and is + // executed when the session operation is done. + public function close() { + return true; + } + + // Read function must return string value always to make save handler + // work as expected. Return empty string if there is no data to read. + // Return values from other handlers are converted to boolean expression. + // TRUE for success, FALSE for failure. + public function read($id) { + $file = $this->savePath . "/sess_$id"; + return (string) @file_get_contents($file); + } + + // Write function that is called when session data is to be saved. This + // function expects two parameters: an identifier and the data associated + // with it. + public function write($id, $data) { + $file = $this->savePath . "/sess_$id"; + if (false !== ($fp = @fopen($file, "w"))) { + $return = fwrite($fp, $data); + fclose($fp); + return $return; + } else + return false; + } + + // The destroy handler, this is executed when a session is destroyed with + // session_destroy() and takes the session id as its only parameter. + public function destroy($id) { + $file = $this->savePath . "/sess_$id"; + return @unlink($file); + } + + // The garbage collector, this is executed when the session garbage + // collector is executed and takes the max session lifetime as its only + // parameter. + public function gc($maxlifetime) { + foreach (glob($this->savePath . "/sess_*") as $file) + if (filemtime($file) + $maxlifetime < time()) + @unlink($file); + return true; + } +} + +new SessionSaveHandler(); + +*/ + + +// PUT YOUR ADDITIONAL CODE HERE diff --git a/lib/kcfinder/core/class/browser.php b/lib/kcfinder/core/class/browser.php new file mode 100644 index 0000000..0f648e4 --- /dev/null +++ b/lib/kcfinder/core/class/browser.php @@ -0,0 +1,938 @@ + + * @copyright 2010-2014 KCFinder Project + * @license http://opensource.org/licenses/GPL-3.0 GPLv3 + * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3 + * @link http://kcfinder.sunhater.com + */ + +namespace kcfinder; + +class browser extends uploader { + protected $action; + protected $thumbsDir; + protected $thumbsTypeDir; + + public function __construct() { + parent::__construct(); + + // SECURITY CHECK INPUT DIRECTORY + if (isset($_POST['dir'])) { + $dir = $this->checkInputDir($_POST['dir'], true, false); + if ($dir === false) unset($_POST['dir']); + $_POST['dir'] = $dir; + } + + if (isset($_GET['dir'])) { + $dir = $this->checkInputDir($_GET['dir'], true, false); + if ($dir === false) unset($_GET['dir']); + $_GET['dir'] = $dir; + } + + $thumbsDir = $this->config['uploadDir'] . "/" . $this->config['thumbsDir']; + if (!$this->config['disabled'] && + ( + ( + !is_dir($thumbsDir) && + !@mkdir($thumbsDir, $this->config['dirPerms']) + ) || + + !is_readable($thumbsDir) || + !dir::isWritable($thumbsDir) || + ( + !is_dir("$thumbsDir/{$this->type}") && + !@mkdir("$thumbsDir/{$this->type}", $this->config['dirPerms']) + ) + ) + ) + $this->errorMsg("Cannot access or create thumbnails folder."); + + $this->thumbsDir = $thumbsDir; + $this->thumbsTypeDir = "$thumbsDir/{$this->type}"; + + // Remove temporary zip downloads if exists + if (!$this->config['disabled']) { + $files = dir::content($this->config['uploadDir'], array( + 'types' => "file", + 'pattern' => '/^.*\.zip$/i' + )); + + if (is_array($files) && count($files)) { + $time = time(); + foreach ($files as $file) + if (is_file($file) && ($time - filemtime($file) > 3600)) + unlink($file); + } + } + + if (isset($_GET['theme']) && + $this->checkFilename($_GET['theme']) && + is_dir("themes/{$_GET['theme']}") + ) + $this->config['theme'] = $_GET['theme']; + } + + public function action() { + $act = isset($_GET['act']) ? $_GET['act'] : "browser"; + if (!method_exists($this, "act_$act")) + $act = "browser"; + $this->action = $act; + $method = "act_$act"; + + if ($this->config['disabled']) { + $message = $this->label("You don't have permissions to browse server."); + if (in_array($act, array("browser", "upload")) || + (substr($act, 0, 8) == "download") + ) + $this->backMsg($message); + else { + header("Content-Type: text/plain; charset={$this->charset}"); + die(json_encode(array('error' => $message))); + } + } + + if (!isset($this->session['dir'])) + $this->session['dir'] = $this->type; + else { + $type = $this->getTypeFromPath($this->session['dir']); + $dir = $this->config['uploadDir'] . "/" . $this->session['dir']; + if (($type != $this->type) || !is_dir($dir) || !is_readable($dir)) + $this->session['dir'] = $this->type; + } + $this->session['dir'] = path::normalize($this->session['dir']); + + // Render the browser + if ($act == "browser") { + header("X-UA-Compatible: chrome=1"); + header("Content-Type: text/html; charset={$this->charset}"); + + // Ajax requests + } elseif ( + (substr($act, 0, 8) != "download") && + !in_array($act, array("thumb", "upload")) + ) + header("Content-Type: text/plain; charset={$this->charset}"); + + $return = $this->$method(); + echo ($return === true) + ? '{}' + : $return; + } + + protected function act_browser() { + if (isset($_GET['dir'])) { + $dir = "{$this->typeDir}/{$_GET['dir']}"; + if ($this->checkFilePath($dir) && is_dir($dir) && is_readable($dir)) + $this->session['dir'] = path::normalize("{$this->type}/{$_GET['dir']}"); + } + return $this->output(); + } + + protected function act_init() { + $tree = $this->getDirInfo($this->typeDir); + $tree['dirs'] = $this->getTree($this->session['dir']); + if (!is_array($tree['dirs']) || !count($tree['dirs'])) + unset($tree['dirs']); + $files = $this->getFiles($this->session['dir']); + $dirWritable = dir::isWritable("{$this->config['uploadDir']}/{$this->session['dir']}"); + $data = array( + 'tree' => &$tree, + 'files' => &$files, + 'dirWritable' => $dirWritable + ); + return json_encode($data); + } + + protected function act_thumb() { + if (!isset($_GET['file']) || + !isset($_GET['dir']) || + !$this->checkFilename($_GET['file']) + ) + $this->sendDefaultThumb(); + + $dir = $this->getDir(); + $file = "{$this->thumbsTypeDir}/{$_GET['dir']}/${_GET['file']}"; + + // Create thumbnail + if (!is_file($file) || !is_readable($file)) { + $file = "$dir/{$_GET['file']}"; + if (!is_file($file) || !is_readable($file)) + $this->sendDefaultThumb($file); + $image = image::factory($this->imageDriver, $file); + if ($image->initError) + $this->sendDefaultThumb($file); + + $img = new fastImage($file); + $type = $img->getType(); + $img->close(); + + if (in_array($type, array("gif", "jpeg", "png")) && + ($image->width <= $this->config['thumbWidth']) && + ($image->height <= $this->config['thumbHeight']) + ) { + $mime = "image/$type"; + httpCache::file($file, $mime); + } else + $this->sendDefaultThumb($file); + + // Get type from already-existing thumbnail + } else { + $img = new fastImage($file); + $type = $img->getType(); + $img->close(); + } + httpCache::file($file, "image/$type"); + } + + protected function act_expand() { + return json_encode(array('dirs' => $this->getDirs($this->postDir()))); + } + + protected function act_chDir() { + $this->postDir(); // Just for existing check + $this->session['dir'] = "{$this->type}/{$_POST['dir']}"; + $dirWritable = dir::isWritable("{$this->config['uploadDir']}/{$this->session['dir']}"); + return json_encode(array( + 'files' => $this->getFiles($this->session['dir']), + 'dirWritable' => $dirWritable + )); + } + + protected function act_newDir() { + if (!$this->config['access']['dirs']['create'] || + !isset($_POST['dir']) || + !isset($_POST['newDir']) || + !$this->checkFilename($_POST['newDir']) + ) + $this->errorMsg("Unknown error."); + + $dir = $this->postDir(); + $newDir = $this->normalizeDirname(trim($_POST['newDir'])); + if (!strlen($newDir)) + $this->errorMsg("Please enter new folder name."); + if (preg_match('/[\/\\\\]/s', $newDir)) + $this->errorMsg("Unallowable characters in folder name."); + if (substr($newDir, 0, 1) == ".") + $this->errorMsg("Folder name shouldn't begins with '.'"); + if (file_exists("$dir/$newDir")) + $this->errorMsg("A file or folder with that name already exists."); + if (!@mkdir("$dir/$newDir", $this->config['dirPerms'])) + $this->errorMsg("Cannot create {dir} folder.", array('dir' => $this->htmlData($newDir))); + return true; + } + + protected function act_renameDir() { + if (!$this->config['access']['dirs']['rename'] || + !isset($_POST['dir']) || + !strlen(rtrim(rtrim(trim($_POST['dir']), "/"), "\\")) || + !isset($_POST['newName']) || + !$this->checkFilename($_POST['newName']) + ) + $this->errorMsg("Unknown error."); + + $dir = $this->postDir(); + $newName = $this->normalizeDirname(trim($_POST['newName'])); + if (!strlen($newName)) + $this->errorMsg("Please enter new folder name."); + if (preg_match('/[\/\\\\]/s', $newName)) + $this->errorMsg("Unallowable characters in folder name."); + if (substr($newName, 0, 1) == ".") + $this->errorMsg("Folder name shouldn't begins with '.'"); + if (!@rename($dir, dirname($dir) . "/$newName")) + $this->errorMsg("Cannot rename the folder."); + $thumbDir = "$this->thumbsTypeDir/{$_POST['dir']}"; + if (is_dir($thumbDir)) + @rename($thumbDir, dirname($thumbDir) . "/$newName"); + return json_encode(array('name' => $newName)); + } + + protected function act_deleteDir() { + if (!$this->config['access']['dirs']['delete'] || + !isset($_POST['dir']) || + !strlen(rtrim(rtrim(trim($_POST['dir']), "/"), "\\")) + ) + $this->errorMsg("Unknown error."); + + $dir = $this->postDir(); + + if (!dir::isWritable($dir)) + $this->errorMsg("Cannot delete the folder."); + $result = !dir::prune($dir, false); + if (is_array($result) && count($result)) + $this->errorMsg("Failed to delete {count} files/folders.", + array('count' => count($result))); + $thumbDir = "$this->thumbsTypeDir/{$_POST['dir']}"; + if (is_dir($thumbDir)) dir::prune($thumbDir); + return true; + } + + protected function act_upload() { + header("Content-Type: text/plain; charset={$this->charset}"); + + if (!$this->config['access']['files']['upload'] || + (!isset($_POST['dir']) && !isset($_GET['dir'])) + ) + $this->errorMsg("Unknown error."); + + $dir = isset($_GET['dir']) ? $this->getDir() : $this->postDir(); + + if (!dir::isWritable($dir)) + $this->errorMsg("Cannot access or write to upload folder."); + + if (is_array($this->file['name'])) { + $return = array(); + foreach ($this->file['name'] as $i => $name) { + $return[] = $this->moveUploadFile(array( + 'name' => $name, + 'tmp_name' => $this->file['tmp_name'][$i], + 'error' => $this->file['error'][$i] + ), $dir); + } + return implode("\n", $return); + } else + return $this->moveUploadFile($this->file, $dir); + } + + protected function act_dragUrl() { + if (!$this->config['access']['files']['upload'] || + !isset($_GET['dir']) || + !isset($_POST['url']) || + !isset($_POST['type']) + ) + $this->errorMsg("Unknown error."); + + $dir = $this->getDir(); + + if (!dir::isWritable($dir)) + $this->errorMsg("Cannot access or write to upload folder."); + + if (is_array($_POST['url'])) + foreach ($_POST['url'] as $url) + $this->downloadURL($url, $dir); + else + $this->downloadURL($_POST['url'], $dir); + + return true; + } + + protected function act_download() { + $dir = $this->postDir(); + if (!isset($_POST['dir']) || + !isset($_POST['file']) || + !$this->checkFilename($_POST['file']) || + (false === ($file = "$dir/{$_POST['file']}")) || + !file_exists($file) || !is_readable($file) + ) + $this->errorMsg("Unknown error."); + + header("Pragma: public"); + header("Expires: 0"); + header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); + header("Cache-Control: private", false); + header("Content-Type: application/octet-stream"); + header('Content-Disposition: attachment; filename="' . str_replace('"', "_", $_POST['file']) . '"'); + header("Content-Transfer-Encoding: binary"); + header("Content-Length: " . filesize($file)); + readfile($file); + die; + } + + protected function act_rename() { + $dir = $this->postDir(); + if (!$this->config['access']['files']['rename'] || + !isset($_POST['dir']) || + !isset($_POST['file']) || + !isset($_POST['newName']) || + !$this->checkFilename($_POST['file']) || + !$this->checkFilename($_POST['newName']) || + (false === ($file = "$dir/{$_POST['file']}")) || + !file_exists($file) || !is_readable($file) || !file::isWritable($file) + ) + $this->errorMsg("Unknown error."); + + if (isset($this->config['denyExtensionRename']) && + $this->config['denyExtensionRename'] && + (file::getExtension($_POST['file'], true) !== + file::getExtension($_POST['newName'], true) + ) + ) + $this->errorMsg("You cannot rename the extension of files!"); + + $newName = $this->normalizeFilename(trim($_POST['newName'])); + if (!strlen($newName)) + $this->errorMsg("Please enter new file name."); + if (preg_match('/[\/\\\\]/s', $newName)) + $this->errorMsg("Unallowable characters in file name."); + if (substr($newName, 0, 1) == ".") + $this->errorMsg("File name shouldn't begins with '.'"); + $newName = "$dir/$newName"; + if (file_exists($newName)) + $this->errorMsg("A file or folder with that name already exists."); + $ext = file::getExtension($newName); + if (!$this->validateExtension($ext, $this->type)) + $this->errorMsg("Denied file extension."); + if (!@rename($file, $newName)) + $this->errorMsg("Unknown error."); + + $thumbDir = "{$this->thumbsTypeDir}/{$_POST['dir']}"; + $thumbFile = "$thumbDir/{$_POST['file']}"; + + if (file_exists($thumbFile)) + @rename($thumbFile, "$thumbDir/" . basename($newName)); + return true; + } + + protected function act_delete() { + $dir = $this->postDir(); + if (!$this->config['access']['files']['delete'] || + !isset($_POST['dir']) || + !isset($_POST['file']) || + !$this->checkFilename($_POST['file']) || + (false === ($file = "$dir/{$_POST['file']}")) || + !file_exists($file) || !is_readable($file) || !file::isWritable($file) || + !@unlink($file) + ) + $this->errorMsg("Unknown error."); + + $thumb = "{$this->thumbsTypeDir}/{$_POST['dir']}/{$_POST['file']}"; + if (file_exists($thumb)) @unlink($thumb); + return true; + } + + protected function act_cp_cbd() { + $dir = $this->postDir(); + if (!$this->config['access']['files']['copy'] || + !isset($_POST['dir']) || + !is_dir($dir) || !is_readable($dir) || !dir::isWritable($dir) || + !isset($_POST['files']) || !is_array($_POST['files']) || + !count($_POST['files']) + ) + $this->errorMsg("Unknown error."); + + $error = array(); + foreach($_POST['files'] as $file) { + $file = path::normalize($file); + if (substr($file, 0, 1) == ".") continue; + $type = explode("/", $file); + $type = $type[0]; + if ($type != $this->type) continue; + $path = "{$this->config['uploadDir']}/$file"; + if (!$this->checkFilePath($path)) continue; + $base = basename($file); + $replace = array('file' => $this->htmlData($base)); + $ext = file::getExtension($base); + if (!file_exists($path)) + $error[] = $this->label("The file '{file}' does not exist.", $replace); + elseif (substr($base, 0, 1) == ".") + $error[] = $this->htmlData($base) . ": " . $this->label("File name shouldn't begins with '.'"); + elseif (!$this->validateExtension($ext, $type)) + $error[] = $this->htmlData($base) . ": " . $this->label("Denied file extension."); + elseif (file_exists("$dir/$base")) + $error[] = $this->htmlData($base) . ": " . $this->label("A file or folder with that name already exists."); + elseif (!is_readable($path) || !is_file($path)) + $error[] = $this->label("Cannot read '{file}'.", $replace); + elseif (!@copy($path, "$dir/$base")) + $error[] = $this->label("Cannot copy '{file}'.", $replace); + else { + if (function_exists("chmod")) + @chmod("$dir/$base", $this->config['filePerms']); + $fromThumb = "{$this->thumbsDir}/$file"; + if (is_file($fromThumb) && is_readable($fromThumb)) { + $toThumb = "{$this->thumbsTypeDir}/{$_POST['dir']}"; + if (!is_dir($toThumb)) + @mkdir($toThumb, $this->config['dirPerms'], true); + $toThumb .= "/$base"; + @copy($fromThumb, $toThumb); + } + } + } + if (count($error)) + return json_encode(array('error' => $error)); + return true; + } + + protected function act_mv_cbd() { + $dir = $this->postDir(); + if (!$this->config['access']['files']['move'] || + !isset($_POST['dir']) || + !is_dir($dir) || !is_readable($dir) || !dir::isWritable($dir) || + !isset($_POST['files']) || !is_array($_POST['files']) || + !count($_POST['files']) + ) + $this->errorMsg("Unknown error."); + + $error = array(); + foreach($_POST['files'] as $file) { + $file = path::normalize($file); + if (substr($file, 0, 1) == ".") continue; + $type = explode("/", $file); + $type = $type[0]; + if ($type != $this->type) continue; + $path = "{$this->config['uploadDir']}/$file"; + if (!$this->checkFilePath($path)) continue; + $base = basename($file); + $replace = array('file' => $this->htmlData($base)); + $ext = file::getExtension($base); + if (!file_exists($path)) + $error[] = $this->label("The file '{file}' does not exist.", $replace); + elseif (substr($base, 0, 1) == ".") + $error[] = $this->htmlData($base) . ": " . $this->label("File name shouldn't begins with '.'"); + elseif (!$this->validateExtension($ext, $type)) + $error[] = $this->htmlData($base) . ": " . $this->label("Denied file extension."); + elseif (file_exists("$dir/$base")) + $error[] = $this->htmlData($base) . ": " . $this->label("A file or folder with that name already exists."); + elseif (!is_readable($path) || !is_file($path)) + $error[] = $this->label("Cannot read '{file}'.", $replace); + elseif (!file::isWritable($path) || !@rename($path, "$dir/$base")) + $error[] = $this->label("Cannot move '{file}'.", $replace); + else { + if (function_exists("chmod")) + @chmod("$dir/$base", $this->config['filePerms']); + $fromThumb = "{$this->thumbsDir}/$file"; + if (is_file($fromThumb) && is_readable($fromThumb)) { + $toThumb = "{$this->thumbsTypeDir}/{$_POST['dir']}"; + if (!is_dir($toThumb)) + @mkdir($toThumb, $this->config['dirPerms'], true); + $toThumb .= "/$base"; + @rename($fromThumb, $toThumb); + } + } + } + if (count($error)) + return json_encode(array('error' => $error)); + return true; + } + + protected function act_rm_cbd() { + if (!$this->config['access']['files']['delete'] || + !isset($_POST['files']) || + !is_array($_POST['files']) || + !count($_POST['files']) + ) + $this->errorMsg("Unknown error."); + + $error = array(); + foreach($_POST['files'] as $file) { + $file = path::normalize($file); + if (substr($file, 0, 1) == ".") continue; + $type = explode("/", $file); + $type = $type[0]; + if ($type != $this->type) continue; + $path = "{$this->config['uploadDir']}/$file"; + if (!$this->checkFilePath($path)) continue; + $base = basename($file); + $replace = array('file' => $this->htmlData($base)); + if (!is_file($path)) + $error[] = $this->label("The file '{file}' does not exist.", $replace); + elseif (!@unlink($path)) + $error[] = $this->label("Cannot delete '{file}'.", $replace); + else { + $thumb = "{$this->thumbsDir}/$file"; + if (is_file($thumb)) @unlink($thumb); + } + } + if (count($error)) + return json_encode(array('error' => $error)); + return true; + } + + protected function act_downloadDir() { + $dir = $this->postDir(); + if (!isset($_POST['dir']) || $this->config['denyZipDownload']) + $this->errorMsg("Unknown error."); + $filename = basename($dir) . ".zip"; + do { + $file = md5(time() . session_id()); + $file = "{$this->config['uploadDir']}/$file.zip"; + } while (file_exists($file)); + new zipFolder($file, $dir); + header("Content-Type: application/x-zip"); + header('Content-Disposition: attachment; filename="' . str_replace('"', "_", $filename) . '"'); + header("Content-Length: " . filesize($file)); + readfile($file); + unlink($file); + die; + } + + protected function act_downloadSelected() { + $dir = $this->postDir(); + if (!isset($_POST['dir']) || + !isset($_POST['files']) || + !is_array($_POST['files']) || + $this->config['denyZipDownload'] + ) + $this->errorMsg("Unknown error."); + + $zipFiles = array(); + foreach ($_POST['files'] as $file) { + $file = path::normalize($file); + if ((substr($file, 0, 1) == ".") || (strpos($file, '/') !== false)) + continue; + $file = "$dir/$file"; + if (!is_file($file) || !is_readable($file) || !$this->checkFilePath($file)) + continue; + $zipFiles[] = $file; + } + + do { + $file = md5(time() . session_id()); + $file = "{$this->config['uploadDir']}/$file.zip"; + } while (file_exists($file)); + + $zip = new \ZipArchive(); + $res = $zip->open($file, \ZipArchive::CREATE); + if ($res === TRUE) { + foreach ($zipFiles as $cfile) + $zip->addFile($cfile, basename($cfile)); + $zip->close(); + } + header("Content-Type: application/x-zip"); + header('Content-Disposition: attachment; filename="selected_files_' . basename($file) . '"'); + header("Content-Length: " . filesize($file)); + readfile($file); + unlink($file); + die; + } + + protected function act_downloadClipboard() { + if (!isset($_POST['files']) || + !is_array($_POST['files']) || + $this->config['denyZipDownload'] + ) + $this->errorMsg("Unknown error."); + + $zipFiles = array(); + foreach ($_POST['files'] as $file) { + $file = path::normalize($file); + if ((substr($file, 0, 1) == ".")) + continue; + $type = explode("/", $file); + $type = $type[0]; + if ($type != $this->type) + continue; + $file = $this->config['uploadDir'] . "/$file"; + if (!is_file($file) || !is_readable($file) || !$this->checkFilePath($file)) + continue; + $zipFiles[] = $file; + } + + do { + $file = md5(time() . session_id()); + $file = "{$this->config['uploadDir']}/$file.zip"; + } while (file_exists($file)); + + $zip = new \ZipArchive(); + $res = $zip->open($file, \ZipArchive::CREATE); + if ($res === TRUE) { + foreach ($zipFiles as $cfile) + $zip->addFile($cfile, basename($cfile)); + $zip->close(); + } + header("Content-Type: application/x-zip"); + header('Content-Disposition: attachment; filename="clipboard_' . basename($file) . '"'); + header("Content-Length: " . filesize($file)); + readfile($file); + unlink($file); + die; + } + + protected function act_check4Update() { + if ($this->config['denyUpdateCheck']) + return json_encode(array('version' => false)); + + // Caching HTTP request for 6 hours + if (isset($this->session['checkVersion']) && + isset($this->session['checkVersionTime']) && + ((time() - $this->session['checkVersionTime']) < 21600) + ) + return json_encode(array('version' => $this->session['checkVersion'])); + + $ver = phpGet::get("http://kcfinder.sunhater.com/checkVersion.php"); + + if (isset($ver) && preg_match('/^\d+\.\d+$/', $ver)) { + $this->session['checkVersion'] = $ver; + $this->session['checkVersionTime'] = time(); + return json_encode(array('version' => $ver)); + } else + return json_encode(array('version' => false)); + } + + protected function moveUploadFile($file, $dir) { + $message = $this->checkUploadedFile($file); + + if ($message !== true) { + if (isset($file['tmp_name'])) + @unlink($file['tmp_name']); + return "{$file['name']}: $message"; + } + + $filename = $this->normalizeFilename($file['name']); + $target = "$dir/" . file::getInexistantFilename($filename, $dir); + + if (!@move_uploaded_file($file['tmp_name'], $target) && + !@rename($file['tmp_name'], $target) && + !@copy($file['tmp_name'], $target) + ) { + @unlink($file['tmp_name']); + return $this->htmlData($file['name']) . ": " . $this->label("Cannot move uploaded file to target folder."); + } elseif (function_exists('chmod')) + chmod($target, $this->config['filePerms']); + + $this->makeThumb($target); + return "/" . basename($target); + } + + protected function sendDefaultThumb($file=null) { + if ($file !== null) { + $ext = file::getExtension($file); + $thumb = "themes/{$this->config['theme']}/img/files/big/$ext.png"; + } + if (!isset($thumb) || !file_exists($thumb)) + $thumb = "themes/{$this->config['theme']}/img/files/big/..png"; + header("Content-Type: image/png"); + readfile($thumb); + die; + } + + protected function getFiles($dir) { + $thumbDir = "{$this->config['uploadDir']}/{$this->config['thumbsDir']}/$dir"; + $dir = "{$this->config['uploadDir']}/$dir"; + $return = array(); + $files = dir::content($dir, array('types' => "file")); + if ($files === false) + return $return; + + foreach ($files as $file) { + + $img = new fastImage($file); + $type = $img->getType(); + + if ($type !== false) { + $size = $img->getSize($file); + if (is_array($size) && count($size)) { + $thumb_file = "$thumbDir/" . basename($file); + if (!is_file($thumb_file)) + $this->makeThumb($file, false); + $smallThumb = + ($size[0] <= $this->config['thumbWidth']) && + ($size[1] <= $this->config['thumbHeight']) && + in_array($type, array("gif", "jpeg", "png")); + } else + $smallThumb = false; + } else + $smallThumb = false; + + $img->close(); + + $stat = stat($file); + if ($stat === false) continue; + $name = basename($file); + $ext = file::getExtension($file); + $bigIcon = file_exists("themes/{$this->config['theme']}/img/files/big/$ext.png"); + $smallIcon = file_exists("themes/{$this->config['theme']}/img/files/small/$ext.png"); + $thumb = file_exists("$thumbDir/$name"); + $return[] = array( + 'name' => stripcslashes($name), + 'size' => $stat['size'], + 'mtime' => $stat['mtime'], + 'date' => @strftime($this->dateTimeSmall, $stat['mtime']), + 'readable' => is_readable($file), + 'writable' => file::isWritable($file), + 'bigIcon' => $bigIcon, + 'smallIcon' => $smallIcon, + 'thumb' => $thumb, + 'smallThumb' => $smallThumb + ); + } + return $return; + } + + protected function getTree($dir, $index=0) { + $path = explode("/", $dir); + + $pdir = ""; + for ($i = 0; ($i <= $index && $i < count($path)); $i++) + $pdir .= "/{$path[$i]}"; + if (strlen($pdir)) + $pdir = substr($pdir, 1); + + $fdir = "{$this->config['uploadDir']}/$pdir"; + + $dirs = $this->getDirs($fdir); + + if (is_array($dirs) && count($dirs) && ($index <= count($path) - 1)) { + + foreach ($dirs as $i => $cdir) { + if ($cdir['hasDirs'] && + ( + ($index == count($path) - 1) || + ($cdir['name'] == $path[$index + 1]) + ) + ) { + $dirs[$i]['dirs'] = $this->getTree($dir, $index + 1); + if (!is_array($dirs[$i]['dirs']) || !count($dirs[$i]['dirs'])) { + unset($dirs[$i]['dirs']); + continue; + } + } + } + } else + return false; + + return $dirs; + } + + protected function postDir($existent=true) { + $dir = $this->typeDir; + if (isset($_POST['dir'])) + $dir .= "/" . $_POST['dir']; + if (!$this->checkFilePath($dir)) + $this->errorMsg("Unknown error."); + if ($existent && (!is_dir($dir) || !is_readable($dir))) + $this->errorMsg("Inexistant or inaccessible folder."); + return $dir; + } + + protected function getDir($existent=true) { + $dir = $this->typeDir; + if (isset($_GET['dir'])) + $dir .= "/" . $_GET['dir']; + if (!$this->checkFilePath($dir)) + $this->errorMsg("Unknown error."); + if ($existent && (!is_dir($dir) || !is_readable($dir))) + $this->errorMsg("Inexistant or inaccessible folder."); + return $dir; + } + + protected function getDirs($dir) { + $dirs = dir::content($dir, array('types' => "dir")); + $return = array(); + if (is_array($dirs)) { + $writable = dir::isWritable($dir); + foreach ($dirs as $cdir) { + $info = $this->getDirInfo($cdir); + if ($info === false) continue; + $info['removable'] = $writable && $info['writable']; + $return[] = $info; + } + } + return $return; + } + + protected function getDirInfo($dir, $removable=false) { + if ((substr(basename($dir), 0, 1) == ".") || !is_dir($dir) || !is_readable($dir)) + return false; + $dirs = dir::content($dir, array('types' => "dir")); + if (is_array($dirs)) { + foreach ($dirs as $key => $cdir) + if (substr(basename($cdir), 0, 1) == ".") + unset($dirs[$key]); + $hasDirs = count($dirs) ? true : false; + } else + $hasDirs = false; + + $writable = dir::isWritable($dir); + $info = array( + 'name' => stripslashes(basename($dir)), + 'readable' => is_readable($dir), + 'writable' => $writable, + 'removable' => $removable && $writable && dir::isWritable(dirname($dir)), + 'hasDirs' => $hasDirs + ); + + if ($dir == "{$this->config['uploadDir']}/{$this->session['dir']}") + $info['current'] = true; + + return $info; + } + + protected function output($data=null, $template=null) { + if (!is_array($data)) $data = array(); + if ($template === null) + $template = $this->action; + + if (file_exists("tpl/tpl_$template.php")) { + ob_start(); + $eval = "unset(\$data);unset(\$template);unset(\$eval);"; + $_ = $data; + foreach (array_keys($data) as $key) + if (preg_match('/^[a-z\d_]+$/i', $key)) + $eval .= "\$$key=\$_['$key'];"; + $eval .= "unset(\$_);require \"tpl/tpl_$template.php\";"; + eval($eval); + return ob_get_clean(); + } + + return ""; + } + + protected function errorMsg($message, array $data=null) { + if (in_array($this->action, array("thumb", "upload", "download", "downloadDir"))) + die($this->label($message, $data)); + if (($this->action === null) || ($this->action == "browser")) + $this->backMsg($message, $data); + else { + $message = $this->label($message, $data); + die(json_encode(array('error' => $message))); + } + } + + protected function htmlData($str) { + return htmlentities($str, null, strtoupper($this->charset)); + } + + protected function downloadURL($url, $dir) { + + if (!preg_match(phpGet::$urlExpr, $url, $match)) + return; + + if ((isset($match[7]) && strlen($match[7]))) + $furl = explode("&", $match[7]); + + $filename = isset($furl) + ? basename($furl[0]) + : "web_image.jpg"; + + $file = tempnam(sys_get_temp_dir(), $filename); + + if (phpGet::get($url, $file)) + $this->moveUploadFile(array( + 'name' => $filename, + 'tmp_name' => $file, + 'error' => UPLOAD_ERR_OK + ), $dir); + else + @unlink($file); + } + + protected function getLangs() { + if (isset($this->session['langs'])) + return $this->session['langs']; + + $files = dir::content("lang", array( + 'pattern' => '/^[a-z]{2,3}(\-[a-z]{2})?\.php$/', + 'types' => "file" + )); + + $langs = array(); + if (is_array($files)) + foreach ($files as $file) { + include $file; + $id = substr(basename($file), 0, -4); + $langs[$id] = isset($lang['_native']) + ? $lang['_native'] + : (isset($lang['_lang']) + ? $lang['_lang'] + : $id); + } + + $this->session['langs'] = $langs; + return $langs; + } +} diff --git a/lib/kcfinder/core/class/minifier.php b/lib/kcfinder/core/class/minifier.php new file mode 100644 index 0000000..bbe0db7 --- /dev/null +++ b/lib/kcfinder/core/class/minifier.php @@ -0,0 +1,111 @@ + + * @copyright 2010-2014 KCFinder Project + * @license http://opensource.org/licenses/GPL-3.0 GPLv3 + * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3 + * @link http://kcfinder.sunhater.com + */ + +namespace kcfinder; + +class minifier { + + protected $config; + protected $type = "js"; + protected $minCmd = ""; + protected $mime = array( + 'js' => "text/javascript", + 'css' => "text/css" + ); + + public function __construct($type=null) { + $this->config = require("conf/config.php"); + $type = strtolower($type); + if (isset($this->mime[$type])) + $this->type = $type; + if (isset($this->config["_{$this->type}MinCmd"])) + $this->minCmd = $this->config["_{$this->type}MinCmd"]; + } + + public function minify($cacheFile=null, $dir=null) { + if ($dir === null) + $dir = dirname($_SERVER['SCRIPT_FILENAME']); + + // MODIFICATION TIME FILES + $mtFiles = array( + __FILE__, + $_SERVER['SCRIPT_FILENAME'], + "conf/config.php" + ); + + // GET SOURCE CODE FILES + $files = dir::content($dir, array( + 'types' => "file", + 'pattern' => '/^.*\.' . $this->type . '$/' + )); + + // GET NEWEST MODIFICATION TIME + $mtime = 0; + foreach (array_merge($mtFiles, $files) as $file) { + $fmtime = filemtime($file); + if ($fmtime > $mtime) + $mtime = $fmtime; + } + + $header = "Content-Type: {$this->mime[$this->type]}"; + + // GET SOURCE CODE FROM CLIENT HTTP CACHE IF EXISTS + httpCache::checkMTime($mtime, $header); + + // OUTPUT SOURCE CODE + header($header); + + // GET SOURCE CODE FROM SERVER-SIDE CACHE + if (($cacheFile !== null) && + file_exists($cacheFile) && + ( + (filemtime($cacheFile) >= $mtime) || + !is_writable($cacheFile) // if cache file cannot be modified + ) // the script will output it always + ) { // with its distribution content + readfile($cacheFile); + die; + } + + // MINIFY AND JOIN SOURCE CODE + $source = ""; + foreach ($files as $file) { + + if (strlen($this->minCmd) && (substr($file, 4, 1) != "_")) { + $cmd = str_replace("{file}", $file, $this->minCmd); + $source .= `$cmd`; + + } else + $source .= file_get_contents($file); + } + + // UPDATE SERVER-SIDE CACHE + if (($cacheFile !== null) && + ( + is_writable($cacheFile) || + ( + !file_exists($cacheFile) && + dir::isWritable(dirname($cacheFile)) + ) + ) + ) { + file_put_contents($cacheFile, $source); + touch($cacheFile, $mtime); + } + + // OUTPUT SOURCE CODE + echo $source; + + } +} diff --git a/lib/kcfinder/core/class/session.php b/lib/kcfinder/core/class/session.php new file mode 100644 index 0000000..918a016 --- /dev/null +++ b/lib/kcfinder/core/class/session.php @@ -0,0 +1,76 @@ + + * @copyright 2010-2014 KCFinder Project + * @license http://opensource.org/licenses/GPL-3.0 GPLv3 + * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3 + * @link http://kcfinder.sunhater.com + */ + +namespace kcfinder; + +class session { + + const SESSION_VAR = "_sessionVar"; + public $values; + protected $config; + + public function __construct($configFile) { + + // Start session if it is not already started + if (!session_id()) + session_start(); + + $config = require($configFile); + + // _sessionVar option is set + if (isset($config[self::SESSION_VAR])) { + $session = &$config[self::SESSION_VAR]; + + // _sessionVar option is string + if (is_string($session)) + $session = &$_SESSION[$session]; + + if (!is_array($session)) + $session = array(); + + // Use global _SESSION array if _sessionVar option is not set + } else + $session = &$_SESSION; + + // Securing the session + $stamp = array( + 'ip' => $_SERVER['REMOTE_ADDR'], + 'agent' => md5($_SERVER['HTTP_USER_AGENT']) + ); + if (!isset($session['stamp'])) + $session['stamp'] = $stamp; + elseif (!is_array($session['stamp']) || ($session['stamp'] !== $stamp)) { + // Destroy session if user agent is different (e.g. after browser update) + if ($session['stamp']['ip'] === $stamp['ip']) + session_destroy(); + die; + } + + // Load session configuration + foreach ($config as $key => $val) + $this->config[$key] = ((substr($key, 0, 1) != "_") && isset($session[$key])) + ? $session[$key] + : $val; + + // Session data goes to 'self' element + if (!isset($session['self'])) + $session['self'] = array(); + $this->values = &$session['self']; + } + + public function getConfig() { + return $this->config; + } + +} diff --git a/lib/kcfinder/core/class/uploader.php b/lib/kcfinder/core/class/uploader.php new file mode 100644 index 0000000..447d0ff --- /dev/null +++ b/lib/kcfinder/core/class/uploader.php @@ -0,0 +1,766 @@ + + * @copyright 2010-2014 KCFinder Project + * @license http://opensource.org/licenses/GPL-3.0 GPLv3 + * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3 + * @link http://kcfinder.sunhater.com + */ + +namespace kcfinder; + +class uploader { + +/** Release version */ + const VERSION = "3.20-test2"; + +/** Config session-overrided settings + * @var array */ + protected $config = array(); + +/** Default image driver + * @var string */ + protected $imageDriver = "gd"; + +/** Opener applocation properties + * @var array */ + protected $opener = array(); + +/** Got from $_GET['type'] or first one $config['types'] array key, if inexistant + * @var string */ + protected $type; + +/** Helper property. Local filesystem path to the Type Directory + * Equivalent: $config['uploadDir'] . "/" . $type + * @var string */ + protected $typeDir; + +/** Helper property. Web URL to the Type Directory + * Equivalent: $config['uploadURL'] . "/" . $type + * @var string */ + protected $typeURL; + +/** Linked to $config['types'] + * @var array */ + protected $types = array(); + +/** Settings which can override default settings if exists as keys in $config['types'][$type] array + * @var array */ + protected $typeSettings = array('disabled', 'theme', 'dirPerms', 'filePerms', 'denyZipDownload', 'maxImageWidth', 'maxImageHeight', 'thumbWidth', 'thumbHeight', 'jpegQuality', 'access', 'filenameChangeChars', 'dirnameChangeChars', 'denyExtensionRename', 'deniedExts', 'watermark'); + +/** Got from language file + * @var string */ + protected $charset; + +/** The language got from $_GET['lng'] or $_GET['lang'] or... Please see next property + * @var string */ + protected $lang = "en"; + +/** Possible language $_GET keys + * @var array */ + protected $langInputNames = array('lang', 'langCode', 'lng', 'language', 'lang_code'); + +/** Uploaded file(s) info. Linked to first $_FILES element + * @var array */ + protected $file; + +/** Next three properties are got from the current language file + * @var string */ + protected $dateTimeFull; // Currently not used + protected $dateTimeMid; // Currently not used + protected $dateTimeSmall; + +/** Contain Specified language labels + * @var array */ + protected $labels = array(); + +/** Session array. Please use this property instead of $_SESSION + * @var array */ + protected $session; + +/** CMS integration property (got from $_GET['cms']) + * @var string */ + protected $cms = ""; + +/** Magic method which allows read-only access to protected or private class properties + * @param string $property + * @return mixed */ + public function __get($property) { + return property_exists($this, $property) ? $this->$property : null; + } + + public function __construct() { + + // SET CMS INTEGRATION PROPERTY + if (isset($_GET['cms']) && + $this->checkFilename($_GET['cms']) && + is_file("integration/{$_GET['cms']}.php") + ) + $this->cms = $_GET['cms']; + + // LINKING UPLOADED FILE + if (count($_FILES)) + $this->file = &$_FILES[key($_FILES)]; + + // CONFIG & SESSION SETUP + $session = new session("conf/config.php"); + $this->config = $session->getConfig(); + $this->session = &$session->values; + + // IMAGE DRIVER INIT + if (isset($this->config['imageDriversPriority'])) { + $this->config['imageDriversPriority'] = + text::clearWhitespaces($this->config['imageDriversPriority']); + $driver = image::getDriver(explode(' ', $this->config['imageDriversPriority'])); + if ($driver !== false) + $this->imageDriver = $driver; + } + if ((!isset($driver) || ($driver === false)) && + (image::getDriver(array($this->imageDriver)) === false) + ) + $this->backMsg("Cannot find any of the supported PHP image extensions!"); + + // WATERMARK INIT + if (isset($this->config['watermark']) && is_string($this->config['watermark'])) + $this->config['watermark'] = array('file' => $this->config['watermark']); + + // GET TYPE DIRECTORY + $this->types = &$this->config['types']; + $firstType = array_keys($this->types); + $firstType = $firstType[0]; + $this->type = ( + isset($_GET['type']) && + isset($this->types[$_GET['type']]) + ) + ? $_GET['type'] : $firstType; + + // LOAD TYPE DIRECTORY SPECIFIC CONFIGURATION IF EXISTS + if (is_array($this->types[$this->type])) { + foreach ($this->types[$this->type] as $key => $val) + if (in_array($key, $this->typeSettings)) + $this->config[$key] = $val; + $this->types[$this->type] = isset($this->types[$this->type]['type']) + ? $this->types[$this->type]['type'] : ""; + } + + // COOKIES INIT + $ip = '(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)'; + $ip = '/^' . implode('\.', array($ip, $ip, $ip, $ip)) . '$/'; + if (preg_match($ip, $_SERVER['HTTP_HOST']) || + preg_match('/^[^\.]+$/', $_SERVER['HTTP_HOST']) + ) + $this->config['cookieDomain'] = ""; + elseif (!strlen($this->config['cookieDomain'])) + $this->config['cookieDomain'] = $_SERVER['HTTP_HOST']; + if (!strlen($this->config['cookiePath'])) + $this->config['cookiePath'] = "/"; + + // UPLOAD FOLDER INIT + + // FULL URL + if (preg_match('/^([a-z]+)\:\/\/([^\/^\:]+)(\:(\d+))?\/(.+)\/?$/', + $this->config['uploadURL'], $patt) + ) { + list($unused, $protocol, $domain, $unused, $port, $path) = $patt; + $path = path::normalize($path); + $this->config['uploadURL'] = "$protocol://$domain" . (strlen($port) ? ":$port" : "") . "/$path"; + $this->config['uploadDir'] = strlen($this->config['uploadDir']) + ? path::normalize($this->config['uploadDir']) + : path::url2fullPath("/$path"); + $this->typeDir = "{$this->config['uploadDir']}/{$this->type}"; + $this->typeURL = "{$this->config['uploadURL']}/{$this->type}"; + + // SITE ROOT + } elseif ($this->config['uploadURL'] == "/") { + $this->config['uploadDir'] = strlen($this->config['uploadDir']) + ? path::normalize($this->config['uploadDir']) + : path::normalize(realpath($_SERVER['DOCUMENT_ROOT'])); + $this->typeDir = "{$this->config['uploadDir']}/{$this->type}"; + $this->typeURL = "/{$this->type}"; + + // ABSOLUTE & RELATIVE + } else { + $this->config['uploadURL'] = (substr($this->config['uploadURL'], 0, 1) === "/") + ? path::normalize($this->config['uploadURL']) + : path::rel2abs_url($this->config['uploadURL']); + $this->config['uploadDir'] = strlen($this->config['uploadDir']) + ? path::normalize($this->config['uploadDir']) + : path::url2fullPath($this->config['uploadURL']); + $this->typeDir = "{$this->config['uploadDir']}/{$this->type}"; + $this->typeURL = "{$this->config['uploadURL']}/{$this->type}"; + } + + // HOST APPLICATIONS INIT + if (isset($_GET['CKEditorFuncNum'])) { + $this->opener['name'] = "ckeditor"; + $this->opener['CKEditor'] = array('funcNum' => $_GET['CKEditorFuncNum']); + + } elseif (isset($_GET['opener'])) { + $this->opener['name'] = $_GET['opener']; + + if ($_GET['opener'] == "tinymce") { + if (!isset($this->config['_tinyMCEPath']) || !strlen($this->config['_tinyMCEPath'])) + $this->opener['name'] = false; + + } elseif ($_GET['opener'] == "tinymce4") { + if (!isset($_GET['field'])) + $this->opener['name'] = false; + else + $this->opener['TinyMCE'] = array('field' => $_GET['field']); + } + + } else + $this->opener['name'] = false; + + // LOCALIZATION + foreach ($this->langInputNames as $key) + if (isset($_GET[$key]) && + preg_match('/^[a-z][a-z\._\-]*$/i', $_GET[$key]) && + file_exists("lang/" . strtolower($_GET[$key]) . ".php") + ) { + $this->lang = $_GET[$key]; + break; + } + $this->localize($this->lang); + + // IF BROWSER IS ENABLED + if (!$this->config['disabled']) { + + // TRY TO CREATE UPLOAD DIRECTORY IF NOT EXISTS + if (!$this->config['disabled'] && !is_dir($this->config['uploadDir'])) + @mkdir($this->config['uploadDir'], $this->config['dirPerms']); + + // CHECK & MAKE DEFAULT .htaccess + if (isset($this->config['_check4htaccess']) && + $this->config['_check4htaccess'] + ) { + $htaccess = "{$this->config['uploadDir']}/.htaccess"; + $original = $this->get_htaccess(); + if (!file_exists($htaccess)) { + if (!@file_put_contents($htaccess, $original)) + $this->backMsg("Cannot write to upload folder. {$this->config['uploadDir']}"); + } else { + if (false === ($data = @file_get_contents($htaccess))) + $this->backMsg("Cannot read .htaccess"); + if (($data != $original) && !@file_put_contents($htaccess, $original)) + $this->backMsg("Incorrect .htaccess file. Cannot rewrite it!"); + } + } + + // CHECK & CREATE UPLOAD FOLDER + if (!is_dir($this->typeDir)) { + if (!mkdir($this->typeDir, $this->config['dirPerms'])) + $this->backMsg("Cannot create {dir} folder.", array('dir' => $this->type)); + } elseif (!is_readable($this->typeDir)) + $this->backMsg("Cannot read upload folder."); + } + } + + public function upload() { + $config = &$this->config; + $file = &$this->file; + $url = $message = ""; + + if ($config['disabled'] || !$config['access']['files']['upload']) { + if (isset($file['tmp_name'])) @unlink($file['tmp_name']); + $message = $this->label("You don't have permissions to upload files."); + + } elseif (true === ($message = $this->checkUploadedFile())) { + $message = ""; + + $dir = "{$this->typeDir}/"; + if (isset($_GET['dir']) && + (false !== ($gdir = $this->checkInputDir($_GET['dir']))) + ) { + $udir = path::normalize("$dir$gdir"); + if (substr($udir, 0, strlen($dir)) !== $dir) + $message = $this->label("Unknown error."); + else { + $l = strlen($dir); + $dir = "$udir/"; + $udir = substr($udir, $l); + } + } + + if (!strlen($message)) { + if (!is_dir(path::normalize($dir))) + @mkdir(path::normalize($dir), $this->config['dirPerms'], true); + + $filename = $this->normalizeFilename($file['name']); + $target = file::getInexistantFilename($dir . $filename); + + if (!@move_uploaded_file($file['tmp_name'], $target) && + !@rename($file['tmp_name'], $target) && + !@copy($file['tmp_name'], $target) + ) + $message = $this->label("Cannot move uploaded file to target folder."); + else { + if (function_exists('chmod')) + @chmod($target, $this->config['filePerms']); + $this->makeThumb($target); + $url = $this->typeURL; + if (isset($udir)) $url .= "/$udir"; + $url .= "/" . basename($target); + if (preg_match('/^([a-z]+)\:\/\/([^\/^\:]+)(\:(\d+))?\/(.+)$/', $url, $patt)) { + list($unused, $protocol, $domain, $unused, $port, $path) = $patt; + $base = "$protocol://$domain" . (strlen($port) ? ":$port" : "") . "/"; + $url = $base . path::urlPathEncode($path); + } else + $url = path::urlPathEncode($url); + } + } + } + + if (strlen($message) && + isset($this->file['tmp_name']) && + file_exists($this->file['tmp_name']) + ) + @unlink($this->file['tmp_name']); + + if (strlen($message) && method_exists($this, 'errorMsg')) + $this->errorMsg($message); + else + $this->callBack($url, $message); + } + + protected function normalizeFilename($filename) { + + if (isset($this->config['filenameChangeChars']) && + is_array($this->config['filenameChangeChars']) + ) + $filename = strtr($filename, $this->config['filenameChangeChars']); + + if (isset($this->config['_normalizeFilenames']) && $this->config['_normalizeFilenames']) + $filename = file::normalizeFilename($filename); + + return $filename; + } + + protected function normalizeDirname($dirname) { + + if (isset($this->config['dirnameChangeChars']) && + is_array($this->config['dirnameChangeChars']) + ) + $dirname = strtr($dirname, $this->config['dirnameChangeChars']); + + if (isset($this->config['_normalizeFilenames']) && $this->config['_normalizeFilenames']) + $dirname = file::normalizeFilename($dirname); + + return $dirname; + } + + protected function checkFilePath($file) { + $rPath = realpath($file); + if (strtoupper(substr(PHP_OS, 0, 3)) == "WIN") + $rPath = str_replace("\\", "/", $rPath); + return (substr($rPath, 0, strlen($this->typeDir)) === $this->typeDir); + } + + protected function checkFilename($file) { + + if ((basename($file) !== $file) || + ( + isset($this->config['_normalizeFilenames']) && + $this->config['_normalizeFilenames'] && + preg_match('/[^0-9a-z\.\- _]/si', $file) + ) + ) + return false; + + return true; + } + + protected function checkUploadedFile(array $aFile=null) { + $config = &$this->config; + $file = ($aFile === null) ? $this->file : $aFile; + + if (!is_array($file) || !isset($file['name'])) + return $this->label("Unknown error"); + + if (is_array($file['name'])) { + foreach ($file['name'] as $i => $name) { + $return = $this->checkUploadedFile(array( + 'name' => $name, + 'tmp_name' => $file['tmp_name'][$i], + 'error' => $file['error'][$i] + )); + if ($return !== true) + return "$name: $return"; + } + return true; + } + + $extension = file::getExtension($file['name']); + $typePatt = strtolower(text::clearWhitespaces($this->types[$this->type])); + + // CHECK FOR UPLOAD ERRORS + if ($file['error']) + return + ($file['error'] == UPLOAD_ERR_INI_SIZE) ? + $this->label("The uploaded file exceeds {size} bytes.", + array('size' => ini_get('upload_max_filesize'))) : ( + ($file['error'] == UPLOAD_ERR_FORM_SIZE) ? + $this->label("The uploaded file exceeds {size} bytes.", + array('size' => $_GET['MAX_FILE_SIZE'])) : ( + ($file['error'] == UPLOAD_ERR_PARTIAL) ? + $this->label("The uploaded file was only partially uploaded.") : ( + ($file['error'] == UPLOAD_ERR_NO_FILE) ? + $this->label("No file was uploaded.") : ( + ($file['error'] == UPLOAD_ERR_NO_TMP_DIR) ? + $this->label("Missing a temporary folder.") : ( + ($file['error'] == UPLOAD_ERR_CANT_WRITE) ? + $this->label("Failed to write file.") : + $this->label("Unknown error.") + ))))); + + // HIDDEN FILENAMES CHECK + elseif (substr($file['name'], 0, 1) == ".") + return $this->label("File name shouldn't begins with '.'"); + + // EXTENSION CHECK + elseif ( + (substr($file['name'], -1) == ".") || + !$this->validateExtension($extension, $this->type) + ) + return $this->label("Denied file extension."); + + // SPECIAL DIRECTORY TYPES CHECK (e.g. *img) + elseif (preg_match('/^\*([^ ]+)(.*)?$/s', $typePatt, $patt)) { + list($typePatt, $type, $params) = $patt; + $class = __NAMESPACE__ . "\\type_$type"; + if (class_exists($class)) { + $type = new $class(); + $cfg = $config; + $cfg['filename'] = $file['name']; + if (strlen($params)) + $cfg['params'] = trim($params); + $response = $type->checkFile($file['tmp_name'], $cfg); + if ($response !== true) + return $this->label($response); + } else + return $this->label("Non-existing directory type."); + } + + // IMAGE RESIZE + $img = image::factory($this->imageDriver, $file['tmp_name']); + if (!$img->initError && !$this->imageResize($img, $file['tmp_name'])) + return $this->label("The image is too big and/or cannot be resized."); + + return true; + } + + protected function checkInputDir($dir, $inclType=true, $existing=true) { + $dir = path::normalize($dir); + if (substr($dir, 0, 1) == "/") + $dir = substr($dir, 1); + + if ((substr($dir, 0, 1) == ".") || (substr(basename($dir), 0, 1) == ".")) + return false; + + if ($inclType) { + $first = explode("/", $dir); + $first = $first[0]; + if ($first != $this->type) + return false; + $return = $this->removeTypeFromPath($dir); + } else { + $return = $dir; + $dir = "{$this->type}/$dir"; + } + + if (!$existing) + return $return; + + $path = "{$this->config['uploadDir']}/$dir"; + return (is_dir($path) && is_readable($path)) ? $return : false; + } + + protected function validateExtension($ext, $type) { + $ext = trim(strtolower($ext)); + if (!isset($this->types[$type])) + return false; + + $exts = strtolower(text::clearWhitespaces($this->config['deniedExts'])); + if (strlen($exts)) { + $exts = explode(" ", $exts); + if (in_array($ext, $exts)) + return false; + } + + $exts = trim($this->types[$type]); + if (!strlen($exts) || substr($exts, 0, 1) == "*") + return true; + + if (substr($exts, 0, 1) == "!") { + $exts = explode(" ", trim(strtolower(substr($exts, 1)))); + return !in_array($ext, $exts); + } + + $exts = explode(" ", trim(strtolower($exts))); + return in_array($ext, $exts); + } + + protected function getTypeFromPath($path) { + return preg_match('/^([^\/]*)\/.*$/', $path, $patt) + ? $patt[1] : $path; + } + + protected function removeTypeFromPath($path) { + return preg_match('/^[^\/]*\/(.*)$/', $path, $patt) + ? $patt[1] : ""; + } + + protected function imageResize($image, $file=null) { + + if (!($image instanceof image)) { + $img = image::factory($this->imageDriver, $image); + if ($img->initError) return false; + $file = $image; + } elseif ($file === null) + return false; + else + $img = $image; + + $orientation = 1; + if (function_exists("exif_read_data")) { + $orientation = @exif_read_data($file); + $orientation = isset($orientation['Orientation']) ? $orientation['Orientation'] : 1; + } + + // IMAGE WILL NOT BE RESIZED WHEN NO WATERMARK AND SIZE IS ACCEPTABLE + if (( + !isset($this->config['watermark']['file']) || + (!strlen(trim($this->config['watermark']['file']))) + ) && ( + ( + !$this->config['maxImageWidth'] && + !$this->config['maxImageHeight'] + ) || ( + ($img->width <= $this->config['maxImageWidth']) && + ($img->height <= $this->config['maxImageHeight']) + ) + ) && + ($orientation == 1) + ) + return true; + + // PROPORTIONAL RESIZE + if ((!$this->config['maxImageWidth'] || !$this->config['maxImageHeight'])) { + + if ($this->config['maxImageWidth'] && + ($this->config['maxImageWidth'] < $img->width) + ) { + $width = $this->config['maxImageWidth']; + $height = $img->getPropHeight($width); + + } elseif ( + $this->config['maxImageHeight'] && + ($this->config['maxImageHeight'] < $img->height) + ) { + $height = $this->config['maxImageHeight']; + $width = $img->getPropWidth($height); + } + + if (isset($width) && isset($height) && !$img->resize($width, $height)) + return false; + + // RESIZE TO FIT + } elseif ( + $this->config['maxImageWidth'] && $this->config['maxImageHeight'] && + !$img->resizeFit($this->config['maxImageWidth'], $this->config['maxImageHeight']) + ) + return false; + + // AUTO FLIP AND ROTATE FROM EXIF + if ((($orientation == 2) && !$img->flipHorizontal()) || + (($orientation == 3) && !$img->rotate(180)) || + (($orientation == 4) && !$img->flipVertical()) || + (($orientation == 5) && (!$img->flipVertical() || !$img->rotate(90))) || + (($orientation == 6) && !$img->rotate(90)) || + (($orientation == 7) && (!$img->flipHorizontal() || !$img->rotate(90))) || + (($orientation == 8) && !$img->rotate(270)) + ) + return false; + if (($orientation >= 2) && ($orientation <= 8) && ($this->imageDriver == "imagick")) + try { + $img->image->setImageProperty('exif:Orientation', "1"); + } catch (\Exception $e) {} + + // WATERMARK + if (isset($this->config['watermark']['file']) && + is_file($this->config['watermark']['file']) + ) { + $left = isset($this->config['watermark']['left']) + ? $this->config['watermark']['left'] : false; + $top = isset($this->config['watermark']['top']) + ? $this->config['watermark']['top'] : false; + $img->watermark($this->config['watermark']['file'], $left, $top); + } + + // WRITE TO FILE + return $img->output("jpeg", array( + 'file' => $file, + 'quality' => $this->config['jpegQuality'] + )); + } + + protected function makeThumb($file, $overwrite=true) { + $img = image::factory($this->imageDriver, $file); + + // Drop files which are not images + if ($img->initError) + return true; + + $fimg = new fastImage($file); + $type = $fimg->getType(); + $fimg->close(); + + if ($type === false) + return true; + + $thumb = substr($file, strlen($this->config['uploadDir'])); + $thumb = $this->config['uploadDir'] . "/" . $this->config['thumbsDir'] . "/" . $thumb; + $thumb = path::normalize($thumb); + $thumbDir = dirname($thumb); + if (!is_dir($thumbDir) && !@mkdir($thumbDir, $this->config['dirPerms'], true)) + return false; + + if (!$overwrite && is_file($thumb)) + return true; + + // Images with smaller resolutions than thumbnails + if (($img->width <= $this->config['thumbWidth']) && + ($img->height <= $this->config['thumbHeight']) + ) { + // Drop only browsable types + if (in_array($type, array("gif", "jpeg", "png"))) + return true; + + // Resize image + } elseif (!$img->resizeFit($this->config['thumbWidth'], $this->config['thumbHeight'])) + return false; + + // Save thumbnail + $options = array('file' => $thumb); + if ($type == "gif") + $type = "jpeg"; + if ($type == "jpeg") + $options['quality'] = $this->config['jpegQuality']; + return $img->output($type, $options); + } + + protected function localize($langCode) { + require "lang/{$langCode}.php"; + setlocale(LC_ALL, $lang['_locale']); + $this->charset = $lang['_charset']; + $this->dateTimeFull = $lang['_dateTimeFull']; + $this->dateTimeMid = $lang['_dateTimeMid']; + $this->dateTimeSmall = $lang['_dateTimeSmall']; + unset($lang['_locale']); + unset($lang['_charset']); + unset($lang['_dateTimeFull']); + unset($lang['_dateTimeMid']); + unset($lang['_dateTimeSmall']); + $this->labels = $lang; + } + + protected function label($string, array $data=null) { + $return = isset($this->labels[$string]) ? $this->labels[$string] : $string; + if (is_array($data)) + foreach ($data as $key => $val) + $return = str_replace("{{$key}}", $val, $return); + return $return; + } + + protected function backMsg($message, array $data=null) { + $message = $this->label($message, $data); + $tmp_name = isset($this->file['tmp_name']) ? $this->file['tmp_name'] : false; + + if ($tmp_name) { + $tmp_name = (is_array($tmp_name) && isset($tmp_name[0])) + ? $tmp_name[0] + : $tmp_name; + + if (file_exists($tmp_name)) + @unlink($tmp_name); + } + $this->callBack("", $message); + die; + } + + protected function callBack($url, $message="") { + $message = text::jsValue($message); + + if ((get_class($this) == "kcfinder\\browser") && ($this->action != "browser")) + return; + + if (isset($this->opener['name'])) { + $method = "callBack_{$this->opener['name']}"; + if (method_exists($this, $method)) + $js = $this->$method($url, $message); + } + + if (!isset($js)) + $js = $this->callBack_default($url, $message); + + header("Content-Type: text/html; charset={$this->charset}"); + echo "$js"; + } + + protected function callBack_ckeditor($url, $message) { + $CKfuncNum = isset($this->opener['CKEditor']['funcNum']) ? $this->opener['CKEditor']['funcNum'] : 0; + if (!$CKfuncNum) $CKfuncNum = 0; + return ""; + } + + protected function callBack_fckeditor($url, $message) { + $n = strlen($message) ? 1 : 0; + return ""; + } + + protected function callBack_tinymce($url, $message) { + return $this->callBack_default($url, $message); + } + + protected function callBack_tinymce4($url, $message) { + return $this->callBack_default($url, $message); + } + + protected function callBack_default($url, $message) { + return ""; + } + + protected function get_htaccess() { + return file_get_contents("conf/upload.htaccess"); + } +} diff --git a/lib/kcfinder/core/types/type_img.php b/lib/kcfinder/core/types/type_img.php new file mode 100644 index 0000000..c03ca7d --- /dev/null +++ b/lib/kcfinder/core/types/type_img.php @@ -0,0 +1,31 @@ + + * @copyright 2010-2014 KCFinder Project + * @license http://opensource.org/licenses/GPL-3.0 GPLv3 + * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3 + * @link http://kcfinder.sunhater.com + */ + +namespace kcfinder; + +class type_img { + + public function checkFile($file, array $config) { + + $driver = isset($config['imageDriversPriority']) + ? image::getDriver(explode(" ", $config['imageDriversPriority'])) : "gd"; + + $img = image::factory($driver, $file); + + if ($img->initError) + return "Unknown image format/encoding."; + + return true; + } +} diff --git a/lib/kcfinder/core/types/type_mime.php b/lib/kcfinder/core/types/type_mime.php new file mode 100644 index 0000000..9fc734d --- /dev/null +++ b/lib/kcfinder/core/types/type_mime.php @@ -0,0 +1,47 @@ + + * @copyright 2010-2014 KCFinder Project + * @license http://opensource.org/licenses/GPL-3.0 GPLv3 + * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3 + * @link http://kcfinder.sunhater.com + */ + +namespace kcfinder; + +class type_mime { + + public function checkFile($file, array $config) { + if (!class_exists("finfo")) + return "Fileinfo PECL extension is missing."; + + if (!isset($config['params'])) + return "Undefined MIME types."; + + $finfo = strlen($config['mime_magic']) + ? new \finfo(FILEINFO_MIME, $config['mime_magic']) + : new \finfo(FILEINFO_MIME); + if (!$finfo) + return "Opening fileinfo database failed."; + + $type = $finfo->file($file); + $type = substr($type, 0, strrpos($type, ";")); + + $mimes = $config['params']; + if (substr($mimes, 0, 1) == "!") { + $mimes = trim(substr($mimes, 1)); + return in_array($type , explode(" ", $mimes)) + ? "You can't upload such files." + : true; + } + + return !in_array($type , explode(" ", $mimes)) + ? "You can't upload such files." + : true; + } +} diff --git a/lib/kcfinder/css/000.base.css b/lib/kcfinder/css/000.base.css new file mode 100644 index 0000000..7ff23cd --- /dev/null +++ b/lib/kcfinder/css/000.base.css @@ -0,0 +1,203 @@ +html, body { + overflow: hidden; +} + +body, form, th, td { + margin: 0; + padding: 0; +} + +a { + cursor: pointer; +} + +* { + font-family: Tahoma, Verdana, Arial, sans-serif; + font-size: 11px; +} + +table { + border-collapse: collapse; +} + +#left { + float: left; + display: block; + width: 25%; +} + +#right { + float: left; + display: block; + width: 75%; +} + +#settings { + display: none; + padding: 0; + float: left; + width: 100%; +} + +#settings > div { + float: left; +} + +#folders { + padding: 5px; + overflow: auto; +} + +#toolbar { + padding: 5px; +} + +#files { + padding: 5px; + overflow: auto; +} + +#status { + padding: 5px; + float: left; + overflow: hidden; +} + +#fileinfo { + float: left; +} + +#clipboard div { + width: 16px; + height: 16px; +} + +.folders { + margin-left: 16px; +} + +div.file { + overflow-x: hidden; + float: left; + text-align: center; + cursor: default; + white-space: nowrap; +} + +div.file .thumb { + background: no-repeat center center; +} + +#files table { + width: 100%; +} + +tr.file { + cursor: default; +} + +tr.file > td { + white-space: nowrap; +} + +tr.file > td.name { + background-repeat: no-repeat; + background-position: left center; + padding-left: 20px; + width: 100%; +} + +tr.file > td.time, +tr.file > td.size { + text-align: right; +} + +#toolbar { + cursor: default; + white-space: nowrap; +} + +#toolbar a { + padding-left: 20px; + text-decoration: none; + background: no-repeat left center; +} + +#toolbar a:hover, a[href="#upload"].uploadHover { + color: #000; +} + +#upload { + position: absolute; + overflow: hidden; + opacity: 0; + filter: alpha(opacity=0); +} +#upload input, #upload input::-webkit-file-upload-button { + cursor: pointer; +} + +span.brace { + padding-left: 11px; + cursor: default; +} + +span.brace.opened, span.brace.closed { + cursor: pointer; +} + +#menu, #clipboard { + position: absolute; + display: none; + z-index: 101; + cursor: default; +} + +#menu .box, #alert { + max-width: 350px; +} + +#clipboard { + z-index: 99; +} + +#loading { + display: none; + float: right; +} + +.menu { + background: #888; + white-space: nowrap; +} + +.menu a { + display: block; +} + +.menu .list { + max-height: 0; + overflow-y: auto; + overflow-x: hidden; + white-space: nowrap; +} + +#uploadResponse, +.file .access, +.file .hasThumb { + display: none; +} + +#resizer { + position: absolute; + z-index: 98; + top: 0; + background: #000; + opacity: 0; + filter: alpha(opacity=0); +} + +#lang { + opacity: 0; + filter: alpha(opacity=0); +} \ No newline at end of file diff --git a/lib/kcfinder/css/001.transForm.css b/lib/kcfinder/css/001.transForm.css new file mode 100644 index 0000000..e9dae28 --- /dev/null +++ b/lib/kcfinder/css/001.transForm.css @@ -0,0 +1,88 @@ +.tf-select, .tf-multiple, .tf-file, .tf-radio, .tf-checkbox, .tf-button { + cursor: default; + overflow: auto; + display: -moz-inline-box; + display: inline-block; + zoom: 1; + vertical-align: middle; +} + +.tf-select .tf-selected { + float: left; + white-space: nowrap; +} + +.tf-select .tf-menu { + display: none; + position: absolute; + max-height: 173px; + overflow-x: hidden; + overflow-y: auto; +} + +.tf-select.tf-opened .tf-menu { + display: block; +} + +.tf-select .tf-button { + float: right; +} + +.tf-select select, +.tf-multiple select { + position: absolute; + left: -1000000px; + opacity: 0; + filter: alpha(opacity=0); +} + +.tf-select .tf-menu ul, +.tf-multiple ul { + padding: 0; + margin: 0; + list-style-type: none; +} + +.tf-select .tf-menu li, +.tf-multiple li { + padding: 0; + margin: 0; +} + +.tf-multiple span, +.tf-select .tf-button span { + white-space: nowrap; +} + +.tf-textarea { + resize: none; + overflow: auto; +} + +.tf-multiple { + max-height: 118px; +} +.tf-file input, +.tf-radio input, +.tf-checkbox input, +.tf-button input, +.tf-button button { + position: absolute; + opacity: 0; + filter: alpha(opacity=0); + outline: none; + margin: 0; + padding: 0; +} +.tf-file { + overflow: hidden; +} +.tf-file .tf-info { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + float: right; +} +.tf-file .tf-button { + float: right; +} diff --git a/lib/kcfinder/css/999.agent.css b/lib/kcfinder/css/999.agent.css new file mode 100644 index 0000000..935a33d --- /dev/null +++ b/lib/kcfinder/css/999.agent.css @@ -0,0 +1,10 @@ +body.mobile { + -webkit-touch-callout: none; + -webkit-user-select: none; + -moz-user-select: none; +} + +body.firefox #files > div { + overflow: auto; + margin-bottom: 5px; +} \ No newline at end of file diff --git a/lib/kcfinder/css/index.php b/lib/kcfinder/css/index.php new file mode 100644 index 0000000..256a7b5 --- /dev/null +++ b/lib/kcfinder/css/index.php @@ -0,0 +1,20 @@ + + * @copyright 2010-2014 KCFinder Project + * @license http://opensource.org/licenses/GPL-3.0 GPLv3 + * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3 + * @link http://kcfinder.sunhater.com + */ + +namespace kcfinder; + +chdir(".."); +require "core/autoload.php"; +$min = new minifier("css"); +$min->minify("cache/base.css"); diff --git a/lib/kcfinder/docs/.htaccess b/lib/kcfinder/docs/.htaccess new file mode 100644 index 0000000..48dd490 --- /dev/null +++ b/lib/kcfinder/docs/.htaccess @@ -0,0 +1,21 @@ + + php_flag engine Off + + + php_flag engine Off + + + php_flag engine Off + + + Options -ExecCGI + + +RemoveHandler .cgi .pl .py .pyc .pyo .phtml .php .php3 .php4 .php5 .php6 .pcgi .pcgi3 .pcgi4 .pcgi5 .pchi6 .inc +RemoveType .cgi .pl .py .pyc .pyo .phtml .php .php3 .php4 .php5 .php6 .pcgi .pcgi3 .pcgi4 .pcgi5 .pchi6 .inc +SetHandler None +SetHandler default-handler + +# Remove both lines below if you want to render HTML files from the upload folder +AddType text/plain .html +AddType text/plain .htm diff --git a/lib/kcfinder/docs/2 (1).png b/lib/kcfinder/docs/2 (1).png new file mode 100644 index 0000000..bf341ba Binary files /dev/null and b/lib/kcfinder/docs/2 (1).png differ diff --git a/lib/kcfinder/favicon.ico b/lib/kcfinder/favicon.ico new file mode 100644 index 0000000..e40e047 Binary files /dev/null and b/lib/kcfinder/favicon.ico differ diff --git a/lib/kcfinder/index.php b/lib/kcfinder/index.php new file mode 100644 index 0000000..15a4b5e --- /dev/null +++ b/lib/kcfinder/index.php @@ -0,0 +1,2 @@ + +Order allow,deny +Deny from all + diff --git a/lib/kcfinder/integration/BolmerCMS.php b/lib/kcfinder/integration/BolmerCMS.php new file mode 100644 index 0000000..8281a96 --- /dev/null +++ b/lib/kcfinder/integration/BolmerCMS.php @@ -0,0 +1,43 @@ + + * @copyright 2010-2014 KCFinder Project + * @license http://opensource.org/licenses/GPL-3.0 GPLv3 + * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3 + * @link http://kcfinder.sunhater.com + */ +class BolmerCMS{ + protected static $authenticated = false; + static function checkAuth() { + $current_cwd = getcwd(); + if ( ! self::$authenticated) { + define('BOLMER_API_MODE', true); + define('IN_MANAGER_MODE', true); + $init = realpath(dirname(dirname(dirname(dirname(dirname(dirname(__FILE__))))))."/index.php"); + include_once($init); + $type = getService('user', true)->getLoginUserType(); + if($type=='manager'){ + self::$authenticated = true; + if (!isset($_SESSION['KCFINDER'])) { + $_SESSION['KCFINDER'] = array(); + } + if(!isset($_SESSION['KCFINDER']['disabled'])) { + $_SESSION['KCFINDER']['disabled'] = false; + } + $_SESSION['KCFINDER']['_check4htaccess'] = false; + $_SESSION['KCFINDER']['uploadURL'] = '/assets/'; + $_SESSION['KCFINDER']['uploadDir'] = BOLMER_BASE_PATH.'assets/'; + $_SESSION['KCFINDER']['theme'] = 'default'; + } + } + + chdir($current_cwd); + return self::$authenticated; + } +} +\kcfinder\cms\BolmerCMS::checkAuth(); \ No newline at end of file diff --git a/lib/kcfinder/integration/drupal.php b/lib/kcfinder/integration/drupal.php new file mode 100644 index 0000000..e5db5f9 --- /dev/null +++ b/lib/kcfinder/integration/drupal.php @@ -0,0 +1,111 @@ + + * @copyright 2010-2014 KCFinder Project + * @license http://opensource.org/licenses/GPL-3.0 GPLv3 + * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3 + * @link http://kcfinder.sunhater.com + */ + +// gets a valid drupal_path +function get_drupal_path() { + if (!empty($_SERVER['SCRIPT_FILENAME'])) { + $drupal_path = dirname(dirname(dirname(dirname($_SERVER['SCRIPT_FILENAME'])))); + if (!file_exists($drupal_path . '/includes/bootstrap.inc')) { + $drupal_path = dirname(dirname(dirname($_SERVER['SCRIPT_FILENAME']))); + $depth = 2; + do { + $drupal_path = dirname($drupal_path); + $depth++; + } while (!($bootstrap_file_found = file_exists($drupal_path . '/includes/bootstrap.inc')) && $depth < 10); + } + } + + if (!isset($bootstrap_file_found) || !$bootstrap_file_found) { + $drupal_path = '../../../../..'; + if (!file_exists($drupal_path . '/includes/bootstrap.inc')) { + $drupal_path = '../..'; + do { + $drupal_path .= '/..'; + $depth = substr_count($drupal_path, '..'); + } while (!($bootstrap_file_found = file_exists($drupal_path . '/includes/bootstrap.inc')) && $depth < 10); + } + } + return $drupal_path; +} + +function CheckAuthentication($drupal_path) { + + static $authenticated; + + if (!isset($authenticated)) { + + if (!isset($bootstrap_file_found) || $bootstrap_file_found) { + $current_cwd = getcwd(); + if (!defined('DRUPAL_ROOT')){ + define('DRUPAL_ROOT', $drupal_path); + } + + // Simulate being in the drupal root folder so we can share the session + chdir(DRUPAL_ROOT); + + global $base_url; + $base_root = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ? 'https' : 'http'; + $base_url = $base_root .= '://'. preg_replace('/[^a-z0-9-:._]/i', '', $_SERVER['HTTP_HOST']); + + if ($dir = trim(dirname($_SERVER['SCRIPT_NAME']), '\,/')) { + $base_path = "/$dir"; + $base_url .= $base_path; + } + + // correct base_url so it points to Drupal root + $pos = strpos($base_url, '/sites/'); + $base_url = substr($base_url, 0, $pos); // drupal root absolute url + + // If we aren't in a Drupal installation, or if Drupal path hasn't been properly found, die + if(!file_exists(DRUPAL_ROOT . '/includes/bootstrap.inc')) { + die("The CMS integration service for -drupal- requires KCFinder to be properly placed inside your Drupal installation."); + } + + + // bootstrap + require_once(DRUPAL_ROOT . '/includes/bootstrap.inc'); + drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); + + // if user has access permission... + if (user_access('access kcfinder')) { + if (!isset($_SESSION['KCFINDER'])) { + $_SESSION['KCFINDER'] = array(); + $_SESSION['KCFINDER']['disabled'] = false; + } + + // User has permission, so make sure KCFinder is not disabled! + if(!isset($_SESSION['KCFINDER']['disabled'])) { + $_SESSION['KCFINDER']['disabled'] = false; + } + + global $user; + $_SESSION['KCFINDER']['uploadURL'] = strtr(variable_get('kcfinder_upload_url', 'sites/default/files/kcfinder'), array('%u' => $user->uid, '%n' => $user->name)); + $_SESSION['KCFINDER']['uploadDir'] = strtr(variable_get('kcfinder_upload_dir', ''), array('%u' => $user->uid, '%n' => $user->name)); + $_SESSION['KCFINDER']['theme'] = variable_get('kcfinder_theme', 'default'); + + //echo '
        uploadURL: ' . $_SESSION['KCFINDER']['uploadURL']
        ; + //echo '
        uploadDir: ' . $_SESSION['KCFINDER']['uploadDir']
        ; + + chdir($current_cwd); + + return true; + } + + chdir($current_cwd); + return false; + } + } +} + +CheckAuthentication(get_drupal_path()); diff --git a/lib/kcfinder/integration/laraveladministrator.php b/lib/kcfinder/integration/laraveladministrator.php new file mode 100644 index 0000000..195aa5b --- /dev/null +++ b/lib/kcfinder/integration/laraveladministrator.php @@ -0,0 +1,136 @@ + + * @copyright 2010-2014 KCFinder Project + * @license http://opensource.org/licenses/GPL-3.0 GPLv3 + * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3 + * @link http://kcfinder.sunhater.com + */ + +class LaravelAdministrator { + protected static $authenticated = false; + protected static $bootstrapAutoload = '/bootstrap/autoload.php'; + protected static $bootstrapStart = '/bootstrap/start.php'; + + static function getLaravelPath() { + + //absolute path method + if (!empty($_SERVER['SCRIPT_FILENAME'])) { + $laravelPath = dirname(dirname(dirname(dirname(dirname(dirname(dirname(dirname($_SERVER['SCRIPT_FILENAME'])))))))); + if (!file_exists($laravelPath . self::$bootstrapAutoload)) { + $laravelPath = dirname(dirname(dirname(dirname($_SERVER['SCRIPT_FILENAME'])))); + $depth = 3; + do { + $laravelPath = dirname($laravelPath); + $depth++; + $autoloadFound = file_exists($laravelPath . self::$bootstrapAutoload); + } while (!$autoloadFound && $depth < 10); + } + else { + $autoloadFound = true; + } + } + + //relative path method + if (!isset($autoloadFound) || !$autoloadFound) { + $laravelPath = '../../../../../../..'; + if (!file_exists($laravelPath . self::$bootstrapAutoload)) { + $laravelPath = '../../..'; + $depth = 3; + do { + $laravelPath .= '/..'; + $depth++; + } while (!($autoloadFound = file_exists($laravelPath . self::$bootstrapAutoload)) && $depth < 10); + } + else { + $autoloadFound = true; + } + } + + return $laravelPath; + } + + static function runIntegration() { + + $laravelPath = self::getLaravelPath(); + + if(file_exists($laravelPath . '/bootstrap/autoload.php')) { + $currentCwd = getcwd(); + + // Simulate being in the laravel root folder so we can share the session (is this really needed?) + // chdir($laravelPath); + + // bootstrap + require $laravelPath.'/bootstrap/autoload.php'; + $app = require_once $laravelPath.'/bootstrap/start.php'; + $app->boot(); //Boot the application's service providers. + + //get the admin check closure that should be supplied in the admin config + $permission = \Illuminate\Support\Facades\Config::get('administrator::administrator.permission'); + $hasPermission = $permission(); + self::$authenticated = $hasPermission; + + //start session if not started already + if (session_id() == "") { + session_start(); + $iStartedTheSession = true; + } + + if (!isset($_SESSION['KCFINDER'])) { + $_SESSION['KCFINDER'] = array(); + } + + //if this is a simple true value, user is logged in + if ($hasPermission == true) { + + $configFactory = \Illuminate\Support\Facades\App::make('admin_config_factory'); + $modelName = \Illuminate\Support\Facades\Input::get('model'); + $fieldName = \Illuminate\Support\Facades\Input::get('field'); + + if(!empty($modelName) && !empty($fieldName)) { + + $modelConfig = $configFactory->make($modelName, true); + $modelConfigOptions = $modelConfig->getOption('edit_fields'); + $kcfinderOptions = $modelConfigOptions[$fieldName]["kcfinder"]; + + //allow users to use an option called 'enabled' instead of 'disabled' + if(isset($kcfinderOptions["enabled"])) { + $kcfinderOptions["disabled"] = !$kcfinderOptions["enabled"]; + } + + //save all options to the session + foreach ($kcfinderOptions as $optKey => $optValue) { + $_SESSION['KCFINDER'][$optKey] = $optValue; + } + + self::$authenticated = !$_SESSION['KCFINDER']['disabled']; + + } + } + else { + //clean and reset the session variable + $_SESSION['KCFINDER'] = array(); + } + + //close the session if I started it + if (isset($iStartedTheSession)) { + session_write_close(); + } + + // chdir($currentCwd); + return self::$authenticated; + } + else { + die("The integration service for 'Laravel Administrator' failed. Laravel root path not found!"); + } + + } + +} + +\kcfinder\integration\LaravelAdministrator::runIntegration(); diff --git a/lib/kcfinder/js/000._jquery.js b/lib/kcfinder/js/000._jquery.js new file mode 100644 index 0000000..046e93a --- /dev/null +++ b/lib/kcfinder/js/000._jquery.js @@ -0,0 +1,4 @@ +/*! jQuery v1.11.0 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */ +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k="".trim,l={},m="1.11.0",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(n.isPlainObject(c)||(b=n.isArray(c)))?(b?(b=!1,f=a&&n.isArray(a)?a:[]):f=a&&n.isPlainObject(a)?a:{},g[d]=n.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray||function(a){return"array"===n.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return a-parseFloat(a)>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(l.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&n.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:k&&!k.call("\ufeff\xa0")?function(a){return null==a?"":k.call(a)}:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),n.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||n.guid++,e):void 0},now:function(){return+new Date},support:l}),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s="sizzle"+-new Date,t=a.document,u=0,v=0,w=eb(),x=eb(),y=eb(),z=function(a,b){return a===b&&(j=!0),0},A="undefined",B=1<<31,C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=D.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",M=L.replace("w","w#"),N="\\["+K+"*("+L+")"+K+"*(?:([*^$|!~]?=)"+K+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+M+")|)|)"+K+"*\\]",O=":("+L+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+N.replace(3,8)+")*)|.*)\\)|)",P=new RegExp("^"+K+"+|((?:^|[^\\\\])(?:\\\\.)*)"+K+"+$","g"),Q=new RegExp("^"+K+"*,"+K+"*"),R=new RegExp("^"+K+"*([>+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(O),U=new RegExp("^"+M+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L.replace("w","w*")+")"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=/'|\\/g,ab=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),bb=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{G.apply(D=H.call(t.childNodes),t.childNodes),D[t.childNodes.length].nodeType}catch(cb){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function db(a,b,d,e){var f,g,h,i,j,m,p,q,u,v;if((b?b.ownerDocument||b:t)!==l&&k(b),b=b||l,d=d||[],!a||"string"!=typeof a)return d;if(1!==(i=b.nodeType)&&9!==i)return[];if(n&&!e){if(f=Z.exec(a))if(h=f[1]){if(9===i){if(g=b.getElementById(h),!g||!g.parentNode)return d;if(g.id===h)return d.push(g),d}else if(b.ownerDocument&&(g=b.ownerDocument.getElementById(h))&&r(b,g)&&g.id===h)return d.push(g),d}else{if(f[2])return G.apply(d,b.getElementsByTagName(a)),d;if((h=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(h)),d}if(c.qsa&&(!o||!o.test(a))){if(q=p=s,u=b,v=9===i&&a,1===i&&"object"!==b.nodeName.toLowerCase()){m=ob(a),(p=b.getAttribute("id"))?q=p.replace(_,"\\$&"):b.setAttribute("id",q),q="[id='"+q+"'] ",j=m.length;while(j--)m[j]=q+pb(m[j]);u=$.test(a)&&mb(b.parentNode)||b,v=m.join(",")}if(v)try{return G.apply(d,u.querySelectorAll(v)),d}catch(w){}finally{p||b.removeAttribute("id")}}}return xb(a.replace(P,"$1"),b,d,e)}function eb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function fb(a){return a[s]=!0,a}function gb(a){var b=l.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function hb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function ib(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||B)-(~a.sourceIndex||B);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function jb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function kb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function lb(a){return fb(function(b){return b=+b,fb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function mb(a){return a&&typeof a.getElementsByTagName!==A&&a}c=db.support={},f=db.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},k=db.setDocument=function(a){var b,e=a?a.ownerDocument||a:t,g=e.defaultView;return e!==l&&9===e.nodeType&&e.documentElement?(l=e,m=e.documentElement,n=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){k()},!1):g.attachEvent&&g.attachEvent("onunload",function(){k()})),c.attributes=gb(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=gb(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(e.getElementsByClassName)&&gb(function(a){return a.innerHTML="
        ",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=gb(function(a){return m.appendChild(a).id=s,!e.getElementsByName||!e.getElementsByName(s).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==A&&n){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ab,bb);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ab,bb);return function(a){var c=typeof a.getAttributeNode!==A&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==A?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==A&&n?b.getElementsByClassName(a):void 0},p=[],o=[],(c.qsa=Y.test(e.querySelectorAll))&&(gb(function(a){a.innerHTML="",a.querySelectorAll("[t^='']").length&&o.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||o.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll(":checked").length||o.push(":checked")}),gb(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&o.push("name"+K+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||o.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),o.push(",.*:")})),(c.matchesSelector=Y.test(q=m.webkitMatchesSelector||m.mozMatchesSelector||m.oMatchesSelector||m.msMatchesSelector))&&gb(function(a){c.disconnectedMatch=q.call(a,"div"),q.call(a,"[s!='']:x"),p.push("!=",O)}),o=o.length&&new RegExp(o.join("|")),p=p.length&&new RegExp(p.join("|")),b=Y.test(m.compareDocumentPosition),r=b||Y.test(m.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},z=b?function(a,b){if(a===b)return j=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===t&&r(t,a)?-1:b===e||b.ownerDocument===t&&r(t,b)?1:i?I.call(i,a)-I.call(i,b):0:4&d?-1:1)}:function(a,b){if(a===b)return j=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],k=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:i?I.call(i,a)-I.call(i,b):0;if(f===g)return ib(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)k.unshift(c);while(h[d]===k[d])d++;return d?ib(h[d],k[d]):h[d]===t?-1:k[d]===t?1:0},e):l},db.matches=function(a,b){return db(a,null,null,b)},db.matchesSelector=function(a,b){if((a.ownerDocument||a)!==l&&k(a),b=b.replace(S,"='$1']"),!(!c.matchesSelector||!n||p&&p.test(b)||o&&o.test(b)))try{var d=q.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return db(b,l,null,[a]).length>0},db.contains=function(a,b){return(a.ownerDocument||a)!==l&&k(a),r(a,b)},db.attr=function(a,b){(a.ownerDocument||a)!==l&&k(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!n):void 0;return void 0!==f?f:c.attributes||!n?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},db.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},db.uniqueSort=function(a){var b,d=[],e=0,f=0;if(j=!c.detectDuplicates,i=!c.sortStable&&a.slice(0),a.sort(z),j){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return i=null,a},e=db.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=db.selectors={cacheLength:50,createPseudo:fb,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ab,bb),a[3]=(a[4]||a[5]||"").replace(ab,bb),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||db.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&db.error(a[0]),a},PSEUDO:function(a){var b,c=!a[5]&&a[2];return V.CHILD.test(a[0])?null:(a[3]&&void 0!==a[4]?a[2]=a[4]:c&&T.test(c)&&(b=ob(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ab,bb).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=w[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&w(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==A&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=db.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),t=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&t){k=q[s]||(q[s]={}),j=k[a]||[],n=j[0]===u&&j[1],m=j[0]===u&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[u,n,m];break}}else if(t&&(j=(b[s]||(b[s]={}))[a])&&j[0]===u)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(t&&((l[s]||(l[s]={}))[a]=[u,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||db.error("unsupported pseudo: "+a);return e[s]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?fb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:fb(function(a){var b=[],c=[],d=g(a.replace(P,"$1"));return d[s]?fb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:fb(function(a){return function(b){return db(a,b).length>0}}),contains:fb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:fb(function(a){return U.test(a||"")||db.error("unsupported lang: "+a),a=a.replace(ab,bb).toLowerCase(),function(b){var c;do if(c=n?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===m},focus:function(a){return a===l.activeElement&&(!l.hasFocus||l.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:lb(function(){return[0]}),last:lb(function(a,b){return[b-1]}),eq:lb(function(a,b,c){return[0>c?c+b:c]}),even:lb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:lb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:lb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:lb(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function qb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=v++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[u,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[s]||(b[s]={}),(h=i[d])&&h[0]===u&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function rb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function sb(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function tb(a,b,c,d,e,f){return d&&!d[s]&&(d=tb(d)),e&&!e[s]&&(e=tb(e,f)),fb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||wb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:sb(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=sb(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?I.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=sb(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ub(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],i=g||d.relative[" "],j=g?1:0,k=qb(function(a){return a===b},i,!0),l=qb(function(a){return I.call(b,a)>-1},i,!0),m=[function(a,c,d){return!g&&(d||c!==h)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>j;j++)if(c=d.relative[a[j].type])m=[qb(rb(m),c)];else{if(c=d.filter[a[j].type].apply(null,a[j].matches),c[s]){for(e=++j;f>e;e++)if(d.relative[a[e].type])break;return tb(j>1&&rb(m),j>1&&pb(a.slice(0,j-1).concat({value:" "===a[j-2].type?"*":""})).replace(P,"$1"),c,e>j&&ub(a.slice(j,e)),f>e&&ub(a=a.slice(e)),f>e&&pb(a))}m.push(c)}return rb(m)}function vb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,i,j,k){var m,n,o,p=0,q="0",r=f&&[],s=[],t=h,v=f||e&&d.find.TAG("*",k),w=u+=null==t?1:Math.random()||.1,x=v.length;for(k&&(h=g!==l&&g);q!==x&&null!=(m=v[q]);q++){if(e&&m){n=0;while(o=a[n++])if(o(m,g,i)){j.push(m);break}k&&(u=w)}c&&((m=!o&&m)&&p--,f&&r.push(m))}if(p+=q,c&&q!==p){n=0;while(o=b[n++])o(r,s,g,i);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=E.call(j));s=sb(s)}G.apply(j,s),k&&!f&&s.length>0&&p+b.length>1&&db.uniqueSort(j)}return k&&(u=w,h=t),r};return c?fb(f):f}g=db.compile=function(a,b){var c,d=[],e=[],f=y[a+" "];if(!f){b||(b=ob(a)),c=b.length;while(c--)f=ub(b[c]),f[s]?d.push(f):e.push(f);f=y(a,vb(e,d))}return f};function wb(a,b,c){for(var d=0,e=b.length;e>d;d++)db(a,b[d],c);return c}function xb(a,b,e,f){var h,i,j,k,l,m=ob(a);if(!f&&1===m.length){if(i=m[0]=m[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&c.getById&&9===b.nodeType&&n&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(ab,bb),b)||[])[0],!b)return e;a=a.slice(i.shift().value.length)}h=V.needsContext.test(a)?0:i.length;while(h--){if(j=i[h],d.relative[k=j.type])break;if((l=d.find[k])&&(f=l(j.matches[0].replace(ab,bb),$.test(i[0].type)&&mb(b.parentNode)||b))){if(i.splice(h,1),a=f.length&&pb(i),!a)return G.apply(e,f),e;break}}}return g(a,m)(f,b,!n,e,$.test(a)&&mb(b.parentNode)||b),e}return c.sortStable=s.split("").sort(z).join("")===s,c.detectDuplicates=!!j,k(),c.sortDetached=gb(function(a){return 1&a.compareDocumentPosition(l.createElement("div"))}),gb(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||hb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&gb(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||hb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),gb(function(a){return null==a.getAttribute("disabled")})||hb(J,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),db}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return n.inArray(a,b)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;e>b;b++)if(n.contains(d[b],this))return!0}));for(b=0;e>b;b++)n.find(a,d[b],c);return c=this.pushStack(e>1?n.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=a.document,A=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,B=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:A.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:z,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=z.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return y.find(a);this.length=1,this[0]=d}return this.context=z,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};B.prototype=n.fn,y=n(z);var C=/^(?:parents|prev(?:Until|All))/,D={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!n(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b,c=n(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(n.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?"string"==typeof a?n.inArray(this[0],n(a)):n.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function E(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return E(a,"nextSibling")},prev:function(a){return E(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return n.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(D[a]||(e=n.unique(e)),C.test(a)&&(e=e.reverse())),this.pushStack(e)}});var F=/\S+/g,G={};function H(a){var b=G[a]={};return n.each(a.match(F)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?G[a]||H(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&n.each(arguments,function(a,c){var d;while((d=n.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){if(a===!0?!--n.readyWait:!n.isReady){if(!z.body)return setTimeout(n.ready);n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(z,[n]),n.fn.trigger&&n(z).trigger("ready").off("ready"))}}});function J(){z.addEventListener?(z.removeEventListener("DOMContentLoaded",K,!1),a.removeEventListener("load",K,!1)):(z.detachEvent("onreadystatechange",K),a.detachEvent("onload",K))}function K(){(z.addEventListener||"load"===event.type||"complete"===z.readyState)&&(J(),n.ready())}n.ready.promise=function(b){if(!I)if(I=n.Deferred(),"complete"===z.readyState)setTimeout(n.ready);else if(z.addEventListener)z.addEventListener("DOMContentLoaded",K,!1),a.addEventListener("load",K,!1);else{z.attachEvent("onreadystatechange",K),a.attachEvent("onload",K);var c=!1;try{c=null==a.frameElement&&z.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!n.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}J(),n.ready()}}()}return I.promise(b)};var L="undefined",M;for(M in n(l))break;l.ownLast="0"!==M,l.inlineBlockNeedsLayout=!1,n(function(){var a,b,c=z.getElementsByTagName("body")[0];c&&(a=z.createElement("div"),a.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",b=z.createElement("div"),c.appendChild(a).appendChild(b),typeof b.style.zoom!==L&&(b.style.cssText="border:0;margin:0;width:1px;padding:1px;display:inline;zoom:1",(l.inlineBlockNeedsLayout=3===b.offsetWidth)&&(c.style.zoom=1)),c.removeChild(a),a=b=null)}),function(){var a=z.createElement("div");if(null==l.deleteExpando){l.deleteExpando=!0;try{delete a.test}catch(b){l.deleteExpando=!1}}a=null}(),n.acceptData=function(a){var b=n.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(O,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}n.data(a,b,c)}else c=void 0}return c}function Q(a){var b;for(b in a)if(("data"!==b||!n.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function R(a,b,d,e){if(n.acceptData(a)){var f,g,h=n.expando,i=a.nodeType,j=i?n.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||n.guid++:h),j[k]||(j[k]=i?{}:{toJSON:n.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=n.extend(j[k],b):j[k].data=n.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[n.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[n.camelCase(b)])):f=g,f +}}function S(a,b,c){if(n.acceptData(a)){var d,e,f=a.nodeType,g=f?n.cache:a,h=f?a[n.expando]:n.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){n.isArray(b)?b=b.concat(n.map(b,n.camelCase)):b in d?b=[b]:(b=n.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!Q(d):!n.isEmptyObject(d))return}(c||(delete g[h].data,Q(g[h])))&&(f?n.cleanData([a],!0):l.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}n.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?n.cache[a[n.expando]]:a[n.expando],!!a&&!Q(a)},data:function(a,b,c){return R(a,b,c)},removeData:function(a,b){return S(a,b)},_data:function(a,b,c){return R(a,b,c,!0)},_removeData:function(a,b){return S(a,b,!0)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=n.data(f),1===f.nodeType&&!n._data(f,"parsedAttrs"))){c=g.length;while(c--)d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d]));n._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){n.data(this,a)}):arguments.length>1?this.each(function(){n.data(this,a,b)}):f?P(f,a,n.data(f,a)):void 0},removeData:function(a){return this.each(function(){n.removeData(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=n._data(a,b),c&&(!d||n.isArray(c)?d=n._data(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return n._data(a,c)||n._data(a,c,{empty:n.Callbacks("once memory").add(function(){n._removeData(a,b+"queue"),n._removeData(a,c)})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthh;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},X=/^(?:checkbox|radio)$/i;!function(){var a=z.createDocumentFragment(),b=z.createElement("div"),c=z.createElement("input");if(b.setAttribute("className","t"),b.innerHTML="
        a",l.leadingWhitespace=3===b.firstChild.nodeType,l.tbody=!b.getElementsByTagName("tbody").length,l.htmlSerialize=!!b.getElementsByTagName("link").length,l.html5Clone="<:nav>"!==z.createElement("nav").cloneNode(!0).outerHTML,c.type="checkbox",c.checked=!0,a.appendChild(c),l.appendChecked=c.checked,b.innerHTML="",l.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,a.appendChild(b),b.innerHTML="",l.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,l.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){l.noCloneEvent=!1}),b.cloneNode(!0).click()),null==l.deleteExpando){l.deleteExpando=!0;try{delete b.test}catch(d){l.deleteExpando=!1}}a=b=c=null}(),function(){var b,c,d=z.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(l[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),l[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var Y=/^(?:input|select|textarea)$/i,Z=/^key/,$=/^(?:mouse|contextmenu)|click/,_=/^(?:focusinfocus|focusoutblur)$/,ab=/^([^.]*)(?:\.(.+)|)$/;function bb(){return!0}function cb(){return!1}function db(){try{return z.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=n.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof n===L||a&&n.event.triggered===a.type?void 0:n.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(F)||[""],h=b.length;while(h--)f=ab.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=n.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=n.event.special[o]||{},l=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},i),(m=g[o])||(m=g[o]=[],m.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,l):m.push(l),n.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n.hasData(a)&&n._data(a);if(r&&(k=r.events)){b=(b||"").match(F)||[""],j=b.length;while(j--)if(h=ab.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=m.length;while(f--)g=m[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(m.splice(f,1),g.selector&&m.delegateCount--,l.remove&&l.remove.call(a,g));i&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(k)&&(delete r.handle,n._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,m,o=[d||z],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||z,3!==d.nodeType&&8!==d.nodeType&&!_.test(p+n.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[n.expando]?b:new n.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),k=n.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!n.isWindow(d)){for(i=k.delegateType||p,_.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||z)&&o.push(l.defaultView||l.parentWindow||a)}m=0;while((h=o[m++])&&!b.isPropagationStopped())b.type=m>1?i:k.bindType||p,f=(n._data(h,"events")||{})[b.type]&&n._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&n.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&n.acceptData(d)&&g&&d[p]&&!n.isWindow(d)){l=d[g],l&&(d[g]=null),n.event.triggered=p;try{d[p]()}catch(r){}n.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(n._data(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((n.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?n(c,this).index(i)>=0:n.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h]","i"),ib=/^\s+/,jb=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,kb=/<([\w:]+)/,lb=/\s*$/g,sb={option:[1,""],legend:[1,"
        ","
        "],area:[1,"",""],param:[1,"",""],thead:[1,"","
        "],tr:[2,"","
        "],col:[2,"","
        "],td:[3,"","
        "],_default:l.htmlSerialize?[0,"",""]:[1,"X
        ","
        "]},tb=eb(z),ub=tb.appendChild(z.createElement("div"));sb.optgroup=sb.option,sb.tbody=sb.tfoot=sb.colgroup=sb.caption=sb.thead,sb.th=sb.td;function vb(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==L?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==L?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||n.nodeName(d,b)?f.push(d):n.merge(f,vb(d,b));return void 0===b||b&&n.nodeName(a,b)?n.merge([a],f):f}function wb(a){X.test(a.type)&&(a.defaultChecked=a.checked)}function xb(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function yb(a){return a.type=(null!==n.find.attr(a,"type"))+"/"+a.type,a}function zb(a){var b=qb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Ab(a,b){for(var c,d=0;null!=(c=a[d]);d++)n._data(c,"globalEval",!b||n._data(b[d],"globalEval"))}function Bb(a,b){if(1===b.nodeType&&n.hasData(a)){var c,d,e,f=n._data(a),g=n._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)n.event.add(b,c,h[c][d])}g.data&&(g.data=n.extend({},g.data))}}function Cb(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!l.noCloneEvent&&b[n.expando]){e=n._data(b);for(d in e.events)n.removeEvent(b,d,e.handle);b.removeAttribute(n.expando)}"script"===c&&b.text!==a.text?(yb(b).text=a.text,zb(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),l.html5Clone&&a.innerHTML&&!n.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&X.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}n.extend({clone:function(a,b,c){var d,e,f,g,h,i=n.contains(a.ownerDocument,a);if(l.html5Clone||n.isXMLDoc(a)||!hb.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(ub.innerHTML=a.outerHTML,ub.removeChild(f=ub.firstChild)),!(l.noCloneEvent&&l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(d=vb(f),h=vb(a),g=0;null!=(e=h[g]);++g)d[g]&&Cb(e,d[g]);if(b)if(c)for(h=h||vb(a),d=d||vb(f),g=0;null!=(e=h[g]);g++)Bb(e,d[g]);else Bb(a,f);return d=vb(f,"script"),d.length>0&&Ab(d,!i&&vb(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k,m=a.length,o=eb(b),p=[],q=0;m>q;q++)if(f=a[q],f||0===f)if("object"===n.type(f))n.merge(p,f.nodeType?[f]:f);else if(mb.test(f)){h=h||o.appendChild(b.createElement("div")),i=(kb.exec(f)||["",""])[1].toLowerCase(),k=sb[i]||sb._default,h.innerHTML=k[1]+f.replace(jb,"<$1>")+k[2],e=k[0];while(e--)h=h.lastChild;if(!l.leadingWhitespace&&ib.test(f)&&p.push(b.createTextNode(ib.exec(f)[0])),!l.tbody){f="table"!==i||lb.test(f)?""!==k[1]||lb.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)n.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}n.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),l.appendChecked||n.grep(vb(p,"input"),wb),q=0;while(f=p[q++])if((!d||-1===n.inArray(f,d))&&(g=n.contains(f.ownerDocument,f),h=vb(o.appendChild(f),"script"),g&&Ab(h),c)){e=0;while(f=h[e++])pb.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=n.expando,j=n.cache,k=l.deleteExpando,m=n.event.special;null!=(d=a[h]);h++)if((b||n.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)m[e]?n.event.remove(d,e):n.removeEvent(d,e,g.handle);j[f]&&(delete j[f],k?delete d[i]:typeof d.removeAttribute!==L?d.removeAttribute(i):d[i]=null,c.push(f))}}}),n.fn.extend({text:function(a){return W(this,function(a){return void 0===a?n.text(this):this.empty().append((this[0]&&this[0].ownerDocument||z).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=xb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=xb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(vb(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&Ab(vb(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&n.cleanData(vb(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&n.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return W(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(gb,""):void 0;if(!("string"!=typeof a||nb.test(a)||!l.htmlSerialize&&hb.test(a)||!l.leadingWhitespace&&ib.test(a)||sb[(kb.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(jb,"<$1>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(vb(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(vb(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,k=this.length,m=this,o=k-1,p=a[0],q=n.isFunction(p);if(q||k>1&&"string"==typeof p&&!l.checkClone&&ob.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(k&&(i=n.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=n.map(vb(i,"script"),yb),f=g.length;k>j;j++)d=i,j!==o&&(d=n.clone(d,!0,!0),f&&n.merge(g,vb(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,n.map(g,zb),j=0;f>j;j++)d=g[j],pb.test(d.type||"")&&!n._data(d,"globalEval")&&n.contains(h,d)&&(d.src?n._evalUrl&&n._evalUrl(d.src):n.globalEval((d.text||d.textContent||d.innerHTML||"").replace(rb,"")));i=c=null}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=0,e=[],g=n(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),n(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Db,Eb={};function Fb(b,c){var d=n(c.createElement(b)).appendTo(c.body),e=a.getDefaultComputedStyle?a.getDefaultComputedStyle(d[0]).display:n.css(d[0],"display");return d.detach(),e}function Gb(a){var b=z,c=Eb[a];return c||(c=Fb(a,b),"none"!==c&&c||(Db=(Db||n("').prependTo(document.body); + $('#loading').html(_.label("Uploading file...")).show(); + form.submit(); + $('#uploadResponse').load(function() { + var response = $(this).contents().find('body').text(); + $('#loading').hide(); + response = response.split("\n"); + + var selected = [], errors = []; + $.each(response, function(i, row) { + if (row.substr(0, 1) == "/") + selected[selected.length] = row.substr(1, row.length - 1); + else + errors[errors.length] = row; + }); + if (errors.length) { + errors = errors.join("\n"); + if (errors.replace(/^\s+/g, "").replace(/\s+$/g, "").length) + _.alert(errors); + } + if (!selected.length) + selected = null; + _.refresh(selected); + $('#upload').detach(); + setTimeout(function() { + $('#uploadResponse').detach(); + }, 1); + _.initUploadButton(); + }); +}; + +_.maximize = function(button) { + + // TINYMCE 3 + if (_.opener.name == "tinymce") { + + var par = window.parent.document, + ifr = $('iframe[src*="browse.php?opener=tinymce&"]', par), + id = parseInt(ifr.attr('id').replace(/^mce_(\d+)_ifr$/, "$1")), + win = $('#mce_' + id, par); + + if ($(button).hasClass('selected')) { + $(button).removeClass('selected'); + win.css({ + left: _.maximizeMCE.left, + top: _.maximizeMCE.top, + width: _.maximizeMCE.width, + height: _.maximizeMCE.height + }); + ifr.css({ + width: _.maximizeMCE.width - _.maximizeMCE.Hspace, + height: _.maximizeMCE.height - _.maximizeMCE.Vspace + }); + + } else { + $(button).addClass('selected') + _.maximizeMCE = { + width: parseInt(win.css('width')), + height: parseInt(win.css('height')), + left: win.position().left, + top: win.position().top, + Hspace: parseInt(win.css('width')) - parseInt(ifr.css('width')), + Vspace: parseInt(win.css('height')) - parseInt(ifr.css('height')) + }; + var width = $(window.top).width(), + height = $(window.top).height(); + win.css({ + left: $(window.parent).scrollLeft(), + top: $(window.parent).scrollTop(), + width: width, + height: height + }); + ifr.css({ + width: width - _.maximizeMCE.Hspace, + height: height - _.maximizeMCE.Vspace + }); + } + + // TINYMCE 4 + } else if (_.opener.name == "tinymce4") { + + var par = window.parent.document, + ifr = $('iframe[src*="browse.php?opener=tinymce4&"]', par).parent(), + win = ifr.parent(); + + if ($(button).hasClass('selected')) { + $(button).removeClass('selected'); + + win.css({ + left: _.maximizeMCE4.left, + top: _.maximizeMCE4.top, + width: _.maximizeMCE4.width, + height: _.maximizeMCE4.height + }); + + ifr.css({ + width: _.maximizeMCE4.width, + height: _.maximizeMCE4.height - _.maximizeMCE4.Vspace + }); + + } else { + $(button).addClass('selected'); + + _.maximizeMCE4 = { + width: parseInt(win.css('width')), + height: parseInt(win.css('height')), + left: win.position().left, + top: win.position().top, + Vspace: win.outerHeight(true) - ifr.outerHeight(true) - 1 + }; + + var width = $(window.top).width(), + height = $(window.top).height(); + + win.css({ + left: 0, + top: 0, + width: width, + height: height + }); + + ifr.css({ + width: width, + height: height - _.maximizeMCE4.Vspace + }); + } + + // PUPUP WINDOW + } else if (window.opener) { + window.moveTo(0, 0); + width = screen.availWidth; + height = screen.availHeight; + if ($.agent.opera) + height -= 50; + window.resizeTo(width, height); + + } else { + if (window.parent) { + var el = null; + $(window.parent.document).find('iframe').each(function() { + if (this.src.replace('/?', '?') == window.location.href.replace('/?', '?')) { + el = this; + return false; + } + }); + + // IFRAME + if (el !== null) + $(el).toggleFullscreen(window.parent.document); + + // SELF WINDOW + else + $('body').toggleFullscreen(); + + } else + $('body').toggleFullscreen(); + } +}; + +_.refresh = function(selected) { + _.fadeFiles(); + $.ajax({ + type: "post", + dataType: "json", + url: _.getURL("chDir"), + data: {dir: _.dir}, + async: false, + success: function(data) { + if (_.check4errors(data)) { + $('#files > div').css({opacity: "", filter: ""}); + return; + } + _.dirWritable = data.dirWritable; + _.files = data.files ? data.files : []; + _.orderFiles(null, selected); + _.statusDir(); + }, + error: function() { + $('#files > div').css({opacity: "", filter: ""}); + $('#files').html(_.label("Unknown error.")); + } + }); +}; diff --git a/lib/kcfinder/js/070.settings.js b/lib/kcfinder/js/070.settings.js new file mode 100644 index 0000000..5d6886b --- /dev/null +++ b/lib/kcfinder/js/070.settings.js @@ -0,0 +1,101 @@ +/** This file is part of KCFinder project + * + * @desc Settings panel functionality + * @package KCFinder + * @version 3.12 + * @author Pavel Tzonkov + * @copyright 2010-2014 KCFinder Project + * @license http://opensource.org/licenses/GPL-3.0 GPLv3 + * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3 + * @link http://kcfinder.sunhater.com + */ + +_.initSettings = function() { + $('#settings fieldset').disableTextSelect(); + + if (!_.shows.length) + $('#show input[type="checkbox"]').each(function(i) { + _.shows[i] = this.name; + }); + + var shows = _.shows; + + if (!$.$.kuki.isSet('showname')) { + $.$.kuki.set('showname', "on"); + $.each(shows, function (i, val) { + if (val != "name") $.$.kuki.set('show' + val, "off"); + }); + } + + $('#show input[type="checkbox"]').click(function() { + $.$.kuki.set('show' + this.name, this.checked ? "on" : "off") + $('#files .file div.' + this.name).css('display', this.checked ? "block" : "none"); + }); + + $.each(shows, function(i, val) { + $('#show input[name="' + val + '"]').get(0).checked = ($.$.kuki.get('show' + val) == "on") ? "checked" : ""; + }); + + if (!_.orders.length) + $('#order input[type="radio"]').each(function(i) { + _.orders[i] = this.value; + }) + + var orders = _.orders; + + if (!$.$.kuki.isSet('order')) + $.$.kuki.set('order', "name"); + + if (!$.$.kuki.isSet('orderDesc')) + $.$.kuki.set('orderDesc', "off"); + + $('#order input[value="' + $.$.kuki.get('order') + '"]').get(0).checked = true; + $('#order input[name="desc"]').get(0).checked = ($.$.kuki.get('orderDesc') == "on"); + + $('#order input[type="radio"]').click(function() { + $.$.kuki.set('order', this.value); + _.orderFiles(); + }); + + $('#order input[name="desc"]').click(function() { + $.$.kuki.set('orderDesc', this.checked ? 'on' : "off"); + _.orderFiles(); + }); + + if (!$.$.kuki.isSet('view')) + $.$.kuki.set('view', "thumbs"); + + if ($.$.kuki.get('view') == "list") + $('#show').parent().hide(); + + $('#view input[value="' + $.$.kuki.get('view') + '"]').get(0).checked = true; + + $('#view input').click(function() { + var view = this.value; + if ($.$.kuki.get('view') != view) { + $.$.kuki.set('view', view); + if (view == "list") + $('#show').parent().hide(); + else + $('#show').parent().show(); + } + _.fixFilesHeight(); + _.refresh(); + }); + $('#settings fieldset, #settings input, #settings label').transForm(); + _.initLangs(); +}; + + +_.initLangs = function() { + $.each(_.langs, function(id, lng) { + var opt = $(''); + opt.val(id).text(lng); + if (id == _.lang) + opt.attr({selected: true}); + $('#lang').append(opt); + }); + $('#lang').change(function() { + window.location = _.getURL("browser", this.value) + "&theme=" + encodeURIComponent(_.theme); + }); +} \ No newline at end of file diff --git a/lib/kcfinder/js/080.files.js b/lib/kcfinder/js/080.files.js new file mode 100644 index 0000000..f3b5507 --- /dev/null +++ b/lib/kcfinder/js/080.files.js @@ -0,0 +1,249 @@ +/** This file is part of KCFinder project + * + * @desc File related functionality + * @package KCFinder + * @version 3.12 + * @author Pavel Tzonkov + * @copyright 2010-2014 KCFinder Project + * @license http://opensource.org/licenses/GPL-3.0 GPLv3 + * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3 + * @link http://kcfinder.sunhater.com + */ + +_.initFiles = function() { + $(document).unbind('keydown').keydown(function(e) { + return !_.selectAll(e); + }); + $('#files').unbind().scroll(function() { + _.menu.hide(); + }).disableTextSelect(); + + $('.file').unbind().click(function(e) { + _.selectFile($(this), e); + + }).rightClick(function(el, e) { + _.menuFile($(el), e); + }).dblclick(function() { + _.returnFile($(this)); + }); + + if ($.mobile) + $('.file').on('taphold', function() { + _.menuFile($(this), { + pageX: $(this).offset().left, + pageY: $(this).offset().top + $(this).outerHeight() + }); + }); + + $.each(_.shows, function(i, val) { + $('#files .file div.' + val).css('display', ($.$.kuki.get('show' + val) == "off") ? "none" : "block"); + }); + _.statusDir(); +}; + +_.showFiles = function(callBack, selected) { + _.fadeFiles(); + setTimeout(function() { + var c = $('
        '); + + $.each(_.files, function(i, file) { + var f, icon, + stamp = file.size + "|" + file.mtime; + + // List + if ($.$.kuki.get('view') == "list") { + if (!i) c.html('
        '); + + icon = $.$.getFileExtension(file.name); + if (file.thumb) + icon = ".image"; + else if (!icon.length || !file.smallIcon) + icon = "."; + icon = "themes/" + _.theme + "/img/files/small/" + icon + ".png"; + + f = $(''); + f.appendTo(c.find('table')); + + // Thumbnails + } else { + if (file.thumb) + icon = _.getURL('thumb') + "&file=" + encodeURIComponent(file.name) + "&dir=" + encodeURIComponent(_.dir) + "&stamp=" + stamp; + else if (file.smallThumb) { + icon = _.uploadURL + "/" + _.dir + "/" + encodeURIComponent(file.name); + icon = $.$.escapeDirs(icon).replace(/\'/g, "%27"); + } else { + icon = file.bigIcon ? $.$.getFileExtension(file.name) : "."; + if (!icon.length) icon = "."; + icon = "themes/" + _.theme + "/img/files/big/" + icon + ".png"; + } + f = $('
        '); + f.appendTo(c); + } + + f.find('.thumb').css({backgroundImage: 'url("' + icon + '")'}); + f.find('.name').text(file.name); + f.find('.time').html(file.date); + f.find('.size').html(_.humanSize(file.size)); + f.data(file); + + if ((file.name === selected) || $.$.inArray(file.name, selected)) + f.addClass('selected'); + }); + + c.css({opacity:'', filter:''}); + $('#files').html(c); + + if (callBack) callBack(); + _.initFiles(); + _.fixScrollRadius(); + }, 200); +}; + +_.selectFile = function(file, e) { + + // Click with Ctrl, Meta or Shift key + if (e.ctrlKey || e.metaKey || e.shiftKey) { + + // Click with Shift key + if (e.shiftKey && !file.hasClass('selected')) { + var f = file.prev(); + while (f.get(0) && !f.hasClass('selected')) { + f.addClass('selected'); + f = f.prev(); + } + } + + file.toggleClass('selected'); + + // Update statusbar + var files = $('.file.selected').get(), + size = 0, data; + if (!files.length) + _.statusDir(); + else { + $.each(files, function(i, cfile) { + size += $(cfile).data('size'); + }); + size = _.humanSize(size); + if (files.length > 1) + $('#fileinfo').html(files.length + " " + _.label("selected files") + " (" + size + ")"); + else { + data = $(files[0]).data(); + $('#fileinfo').text(data.name + " (" + _.humanSize(data.size) + ", " + data.date + ")"); + } + } + + // Normal click + } else { + data = file.data(); + $('.file').removeClass('selected'); + file.addClass('selected'); + $('#fileinfo').text(data.name + " (" + _.humanSize(data.size) + ", " + data.date + ")"); + } +}; + +_.selectAll = function(e) { + if ((!e.ctrlKey && !e.metaKey) || ((e.keyCode != 65) && (e.keyCode != 97))) // Ctrl-A + return false; + + var files = $('.file'), + size = 0; + + if (files.length) { + + files.addClass('selected').each(function() { + size += $(this).data('size'); + }); + + $('#fileinfo').html(files.length + " " + _.label("selected files") + " (" + _.humanSize(size) + ")"); + } + + return true; +}; + +_.returnFile = function(file) { + + var button, win, fileURL = file.substr + ? file : _.uploadURL + "/" + _.dir + "/" + file.data('name'); + fileURL = $.$.escapeDirs(fileURL); + + if (_.opener.name == "ckeditor") { + _.opener.CKEditor.object.tools.callFunction(_.opener.CKEditor.funcNum, fileURL, ""); + window.close(); + + } else if (_.opener.name == "fckeditor") { + window.opener.SetUrl(fileURL) ; + window.close() ; + + } else if (_.opener.name == "tinymce") { + win = tinyMCEPopup.getWindowArg('window'); + win.document.getElementById(tinyMCEPopup.getWindowArg('input')).value = fileURL; + if (win.getImageData) win.getImageData(); + if (typeof(win.ImageDialog) != "undefined") { + if (win.ImageDialog.getImageData) + win.ImageDialog.getImageData(); + if (win.ImageDialog.showPreviewImage) + win.ImageDialog.showPreviewImage(fileURL); + } + tinyMCEPopup.close(); + + } else if (_.opener.name == "tinymce4") { + win = (window.opener ? window.opener : window.parent); + $(win.document).find('#' + _.opener.TinyMCE.field).val(fileURL); + win.tinyMCE.activeEditor.windowManager.close(); + + } else if (_.opener.callBack) { + + if (window.opener && window.opener.KCFinder) { + _.opener.callBack(fileURL); + window.close(); + } + + if (window.parent && window.parent.KCFinder) { + button = $('#toolbar a[href="kcact:maximize"]'); + if (button.hasClass('selected')) + _.maximize(button); + _.opener.callBack(fileURL); + } + + } else if (_.opener.callBackMultiple) { + if (window.opener && window.opener.KCFinder) { + _.opener.callBackMultiple([fileURL]); + window.close(); + } + + if (window.parent && window.parent.KCFinder) { + button = $('#toolbar a[href="kcact:maximize"]'); + if (button.hasClass('selected')) + _.maximize(button); + _.opener.callBackMultiple([fileURL]); + } + + } +}; + +_.returnFiles = function(files) { + if (_.opener.callBackMultiple && files.length) { + var rfiles = []; + $.each(files, function(i, file) { + rfiles[i] = _.uploadURL + "/" + _.dir + "/" + $(file).data('name'); + rfiles[i] = $.$.escapeDirs(rfiles[i]); + }); + _.opener.callBackMultiple(rfiles); + if (window.opener) window.close() + } +}; + +_.returnThumbnails = function(files) { + if (_.opener.callBackMultiple) { + var rfiles = [], j = 0; + $.each(files, function(i, file) { + if ($(file).data('thumb')) { + rfiles[j] = _.thumbsURL + "/" + _.dir + "/" + $(file).data('name'); + rfiles[j] = $.$.escapeDirs(rfiles[j++]); + } + }); + _.opener.callBackMultiple(rfiles); + if (window.opener) window.close() + } +}; diff --git a/lib/kcfinder/js/090.folders.js b/lib/kcfinder/js/090.folders.js new file mode 100644 index 0000000..792113f --- /dev/null +++ b/lib/kcfinder/js/090.folders.js @@ -0,0 +1,193 @@ +/** This file is part of KCFinder project + * + * @desc Folder related functionality + * @package KCFinder + * @version 3.12 + * @author Pavel Tzonkov + * @copyright 2010-2014 KCFinder Project + * @license http://opensource.org/licenses/GPL-3.0 GPLv3 + * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3 + * @link http://kcfinder.sunhater.com + */ + +_.initFolders = function() { + $('#folders').scroll(function() { + _.menu.hide(); + }).disableTextSelect(); + $('div.folder > a').unbind().click(function() { + _.menu.hide(); + return false; + }); + $('div.folder > a > span.brace').unbind().click(function() { + if ($(this).hasClass('opened') || $(this).hasClass('closed')) + _.expandDir($(this).parent()); + }); + $('div.folder > a > span.folder').unbind().click(function() { + _.changeDir($(this).parent()); + }).rightClick(function(el, e) { + _.menuDir($(el).parent(), e); + }); + if ($.mobile) + $('div.folder > a > span.folder').on('taphold', function() { + _.menuDir($(this).parent(), { + pageX: $(this).offset().left + 1, + pageY: $(this).offset().top + $(this).outerHeight() + }); + }); + +}; + +_.setTreeData = function(data, path) { + if (!path) + path = ""; + else if (path.length && (path.substr(path.length - 1, 1) != '/')) + path += "/"; + path += data.name; + var selector = '#folders a[href="kcdir:/' + $.$.escapeDirs(path) + '"]'; + $(selector).data({ + name: data.name, + path: path, + readable: data.readable, + writable: data.writable, + removable: data.removable, + hasDirs: data.hasDirs + }); + $(selector + ' span.folder').addClass(data.current ? 'current' : 'regular'); + if (data.dirs && data.dirs.length) { + $(selector + ' span.brace').addClass('opened'); + $.each(data.dirs, function(i, cdir) { + _.setTreeData(cdir, path + "/"); + }); + } else if (data.hasDirs) + $(selector + ' span.brace').addClass('closed'); +}; + +_.buildTree = function(root, path) { + if (!path) path = ""; + path += root.name; + var cdir, html = '
         ' + $.$.htmlData(root.name) + ''; + if (root.dirs) { + html += '
        '; + for (var i = 0; i < root.dirs.length; i++) { + cdir = root.dirs[i]; + html += _.buildTree(cdir, path + "/"); + } + html += '
        '; + } + html += '
        '; + return html; +}; + +_.expandDir = function(dir) { + var path = dir.data('path'); + if (dir.children('.brace').hasClass('opened')) { + dir.parent().children('.folders').hide(500, function() { + if (path == _.dir.substr(0, path.length)) + _.changeDir(dir); + _.fixScrollRadius(); + }); + dir.children('.brace').removeClass('opened').addClass('closed'); + } else { + if (dir.parent().children('.folders').get(0)) { + dir.parent().children('.folders').show(500, function() { + _.fixScrollRadius(); + }); + dir.children('.brace').removeClass('closed').addClass('opened'); + } else if (!$('#loadingDirs').get(0)) { + dir.parent().append('
        ' + _.label("Loading folders...") + '
        '); + $('#loadingDirs').hide().show(200, function() { + $.ajax({ + type: "post", + dataType: "json", + url: _.getURL("expand"), + data: {dir: path}, + async: false, + success: function(data) { + $('#loadingDirs').hide(200, function() { + $('#loadingDirs').detach(); + }); + if (_.check4errors(data)) + return; + + var html = ""; + $.each(data.dirs, function(i, cdir) { + html += ''; + }); + if (html.length) { + dir.parent().append('
        ' + html + '
        '); + var folders = $(dir.parent().children('.folders').first()); + folders.hide(); + $(folders).show(500, function() { + _.fixScrollRadius(); + }); + $.each(data.dirs, function(i, cdir) { + _.setTreeData(cdir, path); + }); + } + if (data.dirs.length) + dir.children('.brace').removeClass('closed').addClass('opened'); + else + dir.children('.brace').removeClass('opened closed'); + _.initFolders(); + _.initDropUpload(); + _.fixScrollRadius(); + }, + error: function() { + $('#loadingDirs').detach(); + _.alert(_.label("Unknown error.")); + _.fixScrollRadius(); + } + }); + _.fixScrollRadius(); + }); + } + } +}; + +_.changeDir = function(dir) { + if (dir.children('span.folder').hasClass('regular')) { + $('div.folder > a > span.folder').removeClass('current regular').addClass('regular'); + dir.children('span.folder').removeClass('regular').addClass('current'); + $('#files').html(_.label("Loading files...")); + $.ajax({ + type: "post", + dataType: "json", + url: _.getURL("chDir"), + data: {dir: dir.data('path')}, + async: false, + success: function(data) { + if (_.check4errors(data)) + return; + _.files = data.files; + _.orderFiles(); + _.dir = dir.data('path'); + _.dirWritable = data.dirWritable; + _.setTitle("KCFinder: /" + _.dir); + _.statusDir(); + _.initDropUpload(); + }, + error: function() { + $('#files').html(_.label("Unknown error.")); + } + }); + } +}; + +_.statusDir = function() { + var i = 0, size = 0; + for (; i < _.files.length; i++) + size += _.files[i].size; + size = _.humanSize(size); + $('#fileinfo').html(_.files.length + " " + _.label("files") + " (" + size + ")"); +}; + +_.refreshDir = function(dir) { + var path = dir.data('path'); + if (dir.children('.brace').hasClass('opened') || dir.children('.brace').hasClass('closed')) + dir.children('.brace').removeClass('opened').addClass('closed'); + dir.parent().children('.folders').first().detach(); + if (path == _.dir.substr(0, path.length)) + _.changeDir(dir); + _.expandDir(dir); + return true; +}; diff --git a/lib/kcfinder/js/091.menus.js b/lib/kcfinder/js/091.menus.js new file mode 100644 index 0000000..b6f093d --- /dev/null +++ b/lib/kcfinder/js/091.menus.js @@ -0,0 +1,589 @@ +/** This file is part of KCFinder project + * + * @desc Context menus + * @package KCFinder + * @version 3.12 + * @author Pavel Tzonkov + * @copyright 2010-2014 KCFinder Project + * @license http://opensource.org/licenses/GPL-3.0 GPLv3 + * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3 + * @link http://kcfinder.sunhater.com + */ + +_.menu = { + + init: function() { + $('#menu').html("
          ").css('display', 'none'); + }, + + addItem: function(href, label, callback, denied) { + if (typeof denied == "undefined") + denied = false; + + $('#menu ul').append('
        • ' + label + '
        • '); + + if (!denied && $.isFunction(callback)) + $('#menu a[href="' + href + '"]').click(function() { + _.menu.hide(); + return callback(); + }); + }, + + addDivider: function() { + if ($('#menu ul').html().length) + $('#menu ul').append("
        • -
        • "); + }, + + show: function(e) { + var dlg = $('#menu'), + ul = $('#menu ul'); + if (ul.html().length) { + dlg.find('ul').first().menu(); + if (typeof e != "undefined") { + var left = e.pageX, + top = e.pageY, + win = $(window); + + if ((dlg.outerWidth() + left) > win.width()) + left = win.width() - dlg.outerWidth(); + + if ((dlg.outerHeight() + top) > win.height()) + top = win.height() - dlg.outerHeight(); + + dlg.hide().css({ + left: left, + top: top, + width: "" + }).fadeIn('fast'); + } else + dlg.fadeIn('fast'); + } else + ul.detach(); + }, + + hide: function() { + $('#clipboard').removeClass('selected'); + $('div.folder > a > span.folder').removeClass('context'); + $('#menu').hide().css('width', "").html("").data('title', null).unbind().click(function() { + return false; + }); + $(document).unbind('keydown').keydown(function(e) { + return !_.selectAll(e); + }); + } +}; + +// FILE CONTEXT MENU +_.menuFile = function(file, e) { + _.menu.init(); + + var data = file.data(), + files = $('.file.selected').get(); + + // MULTIPLE FILES MENU + if (file.hasClass('selected') && files.length && (files.length > 1)) { + var thumb = false, + notWritable = 0, + cdata; + + $.each(files, function(i, cfile) { + cdata = $(cfile).data(); + if (cdata.thumb) thumb = true; + if (!data.writable) notWritable++; + }); + + if (_.opener.callBackMultiple) { + + // SELECT FILES + _.menu.addItem("kcact:pick", _.label("Select"), function() { + _.returnFiles(files); + return false; + }); + + // SELECT THUMBNAILS + if (thumb) + _.menu.addItem("kcact:pick_thumb", _.label("Select Thumbnails"), function() { + _.returnThumbnails(files); + return false; + }); + } + + if (data.thumb || data.smallThumb || _.support.zip) { + + _.menu.addDivider(); + + // VIEW IMAGE + if (data.thumb || data.smallThumb) + _.menu.addItem("kcact:view", _.label("View"), function() { + _.viewImage(data); + }); + + // DOWNLOAD + if (_.support.zip) + _.menu.addItem("kcact:download", _.label("Download"), function() { + var pfiles = []; + $.each(files, function(i, cfile) { + pfiles[i] = $(cfile).data('name'); + }); + _.post(_.getURL('downloadSelected'), {dir:_.dir, files:pfiles}); + return false; + }); + } + + // ADD TO CLIPBOARD + if (_.access.files.copy || _.access.files.move) { + _.menu.addDivider(); + _.menu.addItem("kcact:clpbrdadd", _.label("Add to Clipboard"), function() { + var msg = ''; + $.each(files, function(i, cfile) { + var cdata = $(cfile).data(), + failed = false; + for (i = 0; i < _.clipboard.length; i++) + if ((_.clipboard[i].name == cdata.name) && + (_.clipboard[i].dir == _.dir) + ) { + failed = true; + msg += cdata.name + ": " + _.label("This file is already added to the Clipboard.") + "\n"; + break; + } + + if (!failed) { + cdata.dir = _.dir; + _.clipboard[_.clipboard.length] = cdata; + } + }); + _.initClipboard(); + if (msg.length) _.alert(msg.substr(0, msg.length - 1)); + return false; + }); + } + + // DELETE + if (_.access.files['delete']) { + _.menu.addDivider(); + _.menu.addItem("kcact:rm", _.label("Delete"), function() { + if ($(this).hasClass('denied')) return false; + var failed = 0, + dfiles = []; + $.each(files, function(i, cfile) { + var cdata = $(cfile).data(); + if (!cdata.writable) + failed++; + else + dfiles[dfiles.length] = _.dir + "/" + cdata.name; + }); + if (failed == files.length) { + _.alert(_.label("The selected files are not removable.")); + return false; + } + + var go = function(callBack) { + _.fadeFiles(); + $.ajax({ + type: "post", + dataType: "json", + url: _.getURL("rm_cbd"), + data: {files:dfiles}, + async: false, + success: function(data) { + if (callBack) callBack(); + _.check4errors(data); + _.refresh(); + }, + error: function() { + if (callBack) callBack(); + $('#files > div').css({ + opacity: "", + filter: "" + }); + _.alert(_.label("Unknown error.")); + } + }); + }; + + if (failed) + _.confirm( + _.label("{count} selected files are not removable. Do you want to delete the rest?", {count:failed}), + go + ); + + else + _.confirm( + _.label("Are you sure you want to delete all selected files?"), + go + ); + + return false; + }, (notWritable == files.length)); + } + + _.menu.show(e); + + // SINGLE FILE MENU + } else { + $('.file').removeClass('selected'); + file.addClass('selected'); + $('#fileinfo').text(data.name + " (" + _.humanSize(data.size) + ", " + data.date + ")"); + + if (_.opener.callBack || _.opener.callBackMultiple) { + + // SELECT FILE + _.menu.addItem("kcact:pick", _.label("Select"), function() { + _.returnFile(file); + return false; + }); + + // SELECT THUMBNAIL + if (data.thumb) + _.menu.addItem("kcact:pick_thumb", _.label("Select Thumbnail"), function() { + _.returnFile(_.thumbsURL + "/" + _.dir + "/" + data.name); + return false; + }); + + _.menu.addDivider(); + } + + // VIEW IMAGE + if (data.thumb || data.smallThumb) + _.menu.addItem("kcact:view", _.label("View"), function() { + _.viewImage(data); + }); + + // DOWNLOAD + _.menu.addItem("kcact:download", _.label("Download"), function() { + $('#menu').html('
          '); + $('#downloadForm input').get(0).value = _.dir; + $('#downloadForm input').get(1).value = data.name; + $('#downloadForm').submit(); + return false; + }); + + // ADD TO CLIPBOARD + if (_.access.files.copy || _.access.files.move) { + _.menu.addDivider(); + _.menu.addItem("kcact:clpbrdadd", _.label("Add to Clipboard"), function() { + for (i = 0; i < _.clipboard.length; i++) + if ((_.clipboard[i].name == data.name) && + (_.clipboard[i].dir == _.dir) + ) { + _.alert(_.label("This file is already added to the Clipboard.")); + return false; + } + var cdata = data; + cdata.dir = _.dir; + _.clipboard[_.clipboard.length] = cdata; + _.initClipboard(); + return false; + }); + } + + + if (_.access.files.rename || _.access.files['delete']) + _.menu.addDivider(); + + // RENAME + if (_.access.files.rename) + _.menu.addItem("kcact:mv", _.label("Rename..."), function() { + if (!data.writable) return false; + _.fileNameDialog( + {dir: _.dir, file: data.name}, + 'newName', data.name, _.getURL("rename"), { + title: "New file name:", + errEmpty: "Please enter new file name.", + errSlash: "Unallowable characters in file name.", + errDot: "File name shouldn't begins with '.'" + }, + _.refresh + ); + return false; + }, !data.writable); + + // DELETE + if (_.access.files['delete']) + _.menu.addItem("kcact:rm", _.label("Delete"), function() { + if (!data.writable) return false; + _.confirm(_.label("Are you sure you want to delete this file?"), + function(callBack) { + $.ajax({ + type: "post", + dataType: "json", + url: _.getURL("delete"), + data: {dir: _.dir, file: data.name}, + async: false, + success: function(data) { + if (callBack) callBack(); + _.clearClipboard(); + if (_.check4errors(data)) + return; + _.refresh(); + }, + error: function() { + if (callBack) callBack(); + _.alert(_.label("Unknown error.")); + } + }); + } + ); + return false; + }, !data.writable); + + _.menu.show(e); + } + +}; + +// FOLDER CONTEXT MENU +_.menuDir = function(dir, e) { + _.menu.init(); + + var data = dir.data(), + html = '
            '; + + if (_.clipboard && _.clipboard.length) { + + // COPY CLIPBOARD + if (_.access.files.copy) + _.menu.addItem("kcact:cpcbd", _.label("Copy {count} files", {count: _.clipboard.length}), function() { + _.copyClipboard(data.path); + return false; + }, !data.writable); + + // MOVE CLIPBOARD + if (_.access.files.move) + _.menu.addItem("kcact:mvcbd", _.label("Move {count} files", {count: _.clipboard.length}), function() { + _.moveClipboard(data.path); + return false; + }, !data.writable); + + if (_.access.files.copy || _.access.files.move) + _.menu.addDivider(); + } + + // REFRESH + _.menu.addItem("kcact:refresh", _.label("Refresh"), function() { + _.refreshDir(dir); + return false; + }); + + // DOWNLOAD + if (_.support.zip) { + _.menu.addDivider(); + _.menu.addItem("kcact:download", _.label("Download"), function() { + _.post(_.getURL("downloadDir"), {dir:data.path}); + return false; + }); + } + + if (_.access.dirs.create || _.access.dirs.rename || _.access.dirs['delete']) + _.menu.addDivider(); + + // NEW SUBFOLDER + if (_.access.dirs.create) + _.menu.addItem("kcact:mkdir", _.label("New Subfolder..."), function(e) { + if (!data.writable) return false; + _.fileNameDialog( + {dir: data.path}, + "newDir", "", _.getURL("newDir"), { + title: "New folder name:", + errEmpty: "Please enter new folder name.", + errSlash: "Unallowable characters in folder name.", + errDot: "Folder name shouldn't begins with '.'" + }, function() { + _.refreshDir(dir); + _.initDropUpload(); + if (!data.hasDirs) { + dir.data('hasDirs', true); + dir.children('span.brace').addClass('closed'); + } + } + ); + return false; + }, !data.writable); + + // RENAME + if (_.access.dirs.rename) + _.menu.addItem("kcact:mvdir", _.label("Rename..."), function(e) { + if (!data.removable) return false; + _.fileNameDialog( + {dir: data.path}, + "newName", data.name, _.getURL("renameDir"), { + title: "New folder name:", + errEmpty: "Please enter new folder name.", + errSlash: "Unallowable characters in folder name.", + errDot: "Folder name shouldn't begins with '.'" + }, function(dt) { + if (!dt.name) { + _.alert(_.label("Unknown error.")); + return; + } + var currentDir = (data.path == _.dir); + dir.children('span.folder').text(dt.name); + dir.data('name', dt.name); + dir.data('path', $.$.dirname(data.path) + '/' + dt.name); + if (currentDir) + _.dir = dir.data('path'); + _.initDropUpload(); + }, + true + ); + return false; + }, !data.removable); + + // DELETE + if (_.access.dirs['delete']) + _.menu.addItem("kcact:rmdir", _.label("Delete"), function() { + if (!data.removable) return false; + _.confirm( + _.label("Are you sure you want to delete this folder and all its content?"), + function(callBack) { + $.ajax({ + type: "post", + dataType: "json", + url: _.getURL("deleteDir"), + data: {dir: data.path}, + async: false, + success: function(data) { + if (callBack) callBack(); + if (_.check4errors(data)) + return; + dir.parent().hide(500, function() { + var folders = dir.parent().parent(); + var pDir = folders.parent().children('a').first(); + dir.parent().detach(); + if (!folders.children('div.folder').get(0)) { + pDir.children('span.brace').first().removeClass('opened closed'); + pDir.parent().children('.folders').detach(); + pDir.data('hasDirs', false); + } + if (pDir.data('path') == _.dir.substr(0, pDir.data('path').length)) + _.changeDir(pDir); + _.initDropUpload(); + }); + }, + error: function() { + if (callBack) callBack(); + _.alert(_.label("Unknown error.")); + } + }); + } + ); + return false; + }, !data.removable); + + _.menu.show(e); + + $('div.folder > a > span.folder').removeClass('context'); + if (dir.children('span.folder').hasClass('regular')) + dir.children('span.folder').addClass('context'); +}; + +// CLIPBOARD MENU +_.openClipboard = function() { + + if (!_.clipboard || !_.clipboard.length) return; + + // CLOSE MENU + if ($('#menu a[href="kcact:clrcbd"]').html()) { + $('#clipboard').removeClass('selected'); + _.menu.hide(); + return; + } + + setTimeout(function() { + _.menu.init(); + + var dlg = $('#menu'), + jStatus = $('#status'), + html = '
          • '; + + // CLIPBOARD FILES + $.each(_.clipboard, function(i, val) { + var icon = $.$.getFileExtension(val.name); + if (val.thumb) + icon = ".image"; + else if (!val.smallIcon || !icon.length) + icon = "."; + icon = "themes/" + _.theme + "/img/files/small/" + icon + ".png"; + html += '' + $.$.htmlData($.$.basename(val.name)) + ''; + }); + html += '
          • -
          • '; + $('#menu ul').append(html); + + // DOWNLOAD + if (_.support.zip) + _.menu.addItem("kcact:download", _.label("Download files"), function() { + _.downloadClipboard(); + return false; + }); + + if (_.access.files.copy || _.access.files.move || _.access.files['delete']) + _.menu.addDivider(); + + // COPY + if (_.access.files.copy) + _.menu.addItem("kcact:cpcbd", _.label("Copy files here"), function() { + if (!_.dirWritable) return false; + _.copyClipboard(_.dir); + return false; + }, !_.dirWritable); + + // MOVE + if (_.access.files.move) + _.menu.addItem("kcact:mvcbd", _.label("Move files here"), function() { + if (!_.dirWritable) return false; + _.moveClipboard(_.dir); + return false; + }, !_.dirWritable); + + // DELETE + if (_.access.files['delete']) + _.menu.addItem("kcact:rmcbd", _.label("Delete files"), function() { + _.confirm( + _.label("Are you sure you want to delete all files in the Clipboard?"), + function(callBack) { + if (callBack) callBack(); + _.deleteClipboard(); + } + ); + return false; + }); + + _.menu.addDivider(); + + // CLEAR CLIPBOARD + _.menu.addItem("kcact:clrcbd", _.label("Clear the Clipboard"), function() { + _.clearClipboard(); + return false; + }); + + $('#clipboard').addClass('selected'); + _.menu.show(); + + var left = $(window).width() - dlg.css({width: ""}).outerWidth(), + top = $(window).height() - dlg.outerHeight() - jStatus.outerHeight(), + lheight = top + dlg.outerTopSpace(); + + dlg.find('.list').css({ + 'max-height': lheight, + 'overflow-y': "auto", + 'overflow-x': "hidden", + width: "" + }); + + top = $(window).height() - dlg.outerHeight(true) - jStatus.outerHeight(true); + + dlg.css({ + left: left - 5, + top: top + }).fadeIn("fast"); + + var a = dlg.find('.list').outerHeight(), + b = dlg.find('.list div').outerHeight(); + + if (b - a > 10) { + dlg.css({ + left: parseInt(dlg.css('left')) - _.scrollbarWidth, + }).width(dlg.width() + _.scrollbarWidth); + } + }, 1); +}; \ No newline at end of file diff --git a/lib/kcfinder/js/091.viewImage.js b/lib/kcfinder/js/091.viewImage.js new file mode 100644 index 0000000..db4861d --- /dev/null +++ b/lib/kcfinder/js/091.viewImage.js @@ -0,0 +1,223 @@ +/** This file is part of KCFinder project + * + * @desc Image viewer + * @package KCFinder + * @version 3.12 + * @author Pavel Tzonkov + * @copyright 2010-2014 KCFinder Project + * @license http://opensource.org/licenses/GPL-3.0 GPLv3 + * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3 + * @link http://kcfinder.sunhater.com + */ + +_.viewImage = function(data) { + + var ts = new Date().getTime(), + dlg = false, + images = [], + min_h = 100, + w = $(window), + min_w, dd, dv, dh, + + showImage = function(data) { + _.lock = true; + + var url = $.$.escapeDirs(_.uploadURL + "/" + _.dir + "/" + data.name) + "?ts=" + ts, + img = new Image(), + i = $(img), + + onImgLoad = function() { + _.lock = false; + + $('#files .file').each(function() { + if ($(this).data('name') == data.name) { + _.ssImage = this; + return false; + } + }); + + i.hide().appendTo('body'); + + var w_w = w.width(), + w_h = w.height(), + o_w = i.width(), + o_h = i.height(), + i_w = o_w, + i_h = o_h, + openDlg = false, + t = $('
            '), + + goTo = function(i) { + if (!_.lock) { + var nimg = images[i]; + _.currImg = i; + showImage(nimg); + } + }, + + nextFunc = function() { + goTo((_.currImg >= images.length - 1) ? 0 : (_.currImg + 1)); + }, + + prevFunc = function() { + goTo((_.currImg ? _.currImg : images.length) - 1); + }, + + selectFunc = function(e) { + if (_.ssImage) + _.selectFile($(_.ssImage), e); + dlg.dialog('destroy').detach(); + }; + + i.detach().appendTo(t); + + if (!dlg) { + openDlg = true; + + var closeFunc = function() { + dlg.dialog('destroy').detach(); + }, + + focusFunc = function() { + setTimeout(function() { + dlg.find('input').get(0).focus(); + }, 100); + }; + + dlg = _.dialog(".", "", { + draggable: false, + nopadding: true, + close: closeFunc, + show: false, + hide: false, + buttons: [ + { + text: _.label("Previous"), + icons: {primary: "ui-icon-triangle-1-w"}, + click: prevFunc + + }, { + text: _.label("Next"), + icons: {secondary: "ui-icon-triangle-1-e"}, + click: nextFunc + + }, { + text: _.label("Select"), + icons: {primary: "ui-icon-check"}, + click: selectFunc + + }, { + text: _.label("Close"), + icons: {primary: "ui-icon-closethick"}, + click: closeFunc + } + ] + }); + + dlg.click(nextFunc).css({overflow: "hidden"}).parent().css({width: "auto", height: "auto"}); + + dd = dlg.parent().click(focusFunc).rightClick(focusFunc).disableTextSelect().addClass('kcfImageViewer'); + dv = dd.find('.ui-dialog-titlebar').outerHeight() + dd.find('.ui-dialog-buttonpane').outerHeight() + dd.outerVSpace('b'); + dh = dd.outerHSpace('b'); + min_w = dd.outerWidth() - dh; + } + + var max_w = w_w - dh, + max_h = w_h - dv + 1, + top = 0, + left = 0, + width = o_w, + height = o_h; + + // Too big + if ((o_w > max_w) || (o_h > max_h)) { + + if ((max_h / max_w) < (o_h / o_w)) { + height = max_h; + width = (o_w * height) / o_h; + + } else { + width = max_w; + height = (o_h * width) / o_w; + } + + i_w = width; + i_h = height; + + // Too small + } else if ((o_w < min_w) || (o_h < min_h)) { + width = (o_w < min_w) ? min_w : o_w; + height = (o_h < min_h) ? min_h : o_h; + left = (o_w < min_w) ? (min_w - o_w) / 2 : 0; + top = (o_h < min_h) ? (min_h - o_h) / 2 : 0; + } + + var show = function() { + dlg.animate({width: width, height: height}, 150); + dlg.parent().animate({top: (w_h - height - dv) / 2, left: (w_w - width - dh) / 2}, 150, function() { + dlg.html(t.get(0)).append(''); + dlg.find('input').keydown(function(e) { + if (!_.lock) { + if (e.metaKey || e.ctrlKey || e.altKey || e.shiftKey) + return; + var kc = e.keyCode; + if ((kc == 37)) prevFunc(); + if ((kc == 39)) nextFunc(); + if ((kc == 13) || (kc == 32)) selectFunc(e); + } + }).get(0).focus(); + i.css({padding: top + "px 0 0 " + left + "px", width: i_w, height: i_h}).show(); + dlg.children().first().css({width: width, height: height, display: "none"}).fadeIn(150, function() { + loadingStop(); + var title = data.name + " (" + o_w + " x " + o_h + ")"; + dlg.prev().find('.ui-dialog-title').css({width:width - dlg.prev().find('.ui-dialog-titlebar-close').outerWidth() - 20}).text(title).attr({title: title}).css({cursor: "default"}); + }); + }); + } + + if (openDlg) + show(); + else + dlg.children().first().fadeOut(150, show); + }, + + loadingStart = function() { + if (dlg) + dlg.prev().addClass("loading").find('.ui-dialog-title').text(_.label("Loading image...")).css({width: "auto"}); + else + $('#loading').text(_.label("Loading image...")).show(); + }, + + loadingStop = function() { + if (dlg) + dlg.prev().removeClass("loading"); + $('#loading').hide(); + }; + + loadingStart(); + img.src = url; + + if (img.complete) + onImgLoad(); + else { + img.onload = onImgLoad; + img.onerror = function() { + _.lock = false; + loadingStop(); + _.alert(_.label("Unknown error.")); + _.refresh(); + }; + } + }; + + $.each(_.files, function(i, file) { + i = images.length; + if (file.thumb || file.smallThumb) + images[i] = file; + if (file.name == data.name) + _.currImg = i; + }); + + showImage(data); + return false; +}; diff --git a/lib/kcfinder/js/100.clipboard.js b/lib/kcfinder/js/100.clipboard.js new file mode 100644 index 0000000..85f0b77 --- /dev/null +++ b/lib/kcfinder/js/100.clipboard.js @@ -0,0 +1,216 @@ +/** This file is part of KCFinder project + * + * @desc Clipboard functionality + * @package KCFinder + * @version 3.12 + * @author Pavel Tzonkov + * @copyright 2010-2014 KCFinder Project + * @license http://opensource.org/licenses/GPL-3.0 GPLv3 + * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3 + * @link http://kcfinder.sunhater.com + */ + +_.initClipboard = function() { + if (!_.clipboard || !_.clipboard.length) return; + + var size = 0, + jClipboard = $('#clipboard'); + + $.each(_.clipboard, function(i, val) { + size += val.size; + }); + size = _.humanSize(size); + jClipboard.disableTextSelect().html('
            '); + var resize = function() { + jClipboard.css({ + left: $(window).width() - jClipboard.outerWidth(), + top: $(window).height() - jClipboard.outerHeight() + }); + }; + resize(); + jClipboard.show(); + $(window).unbind().resize(function() { + _.resize(); + resize(); + }); +}; + +_.removeFromClipboard = function(i) { + if (!_.clipboard || !_.clipboard[i]) return false; + if (_.clipboard.length == 1) { + _.clearClipboard(); + _.menu.hide(); + return; + } + + if (i < _.clipboard.length - 1) { + var last = _.clipboard.slice(i + 1); + _.clipboard = _.clipboard.slice(0, i); + _.clipboard = _.clipboard.concat(last); + } else + _.clipboard.pop(); + + _.initClipboard(); + _.menu.hide(); + _.openClipboard(); + return true; +}; + +_.copyClipboard = function(dir) { + if (!_.clipboard || !_.clipboard.length) return; + var files = [], + failed = 0; + for (i = 0; i < _.clipboard.length; i++) + if (_.clipboard[i].readable) + files[i] = _.clipboard[i].dir + "/" + _.clipboard[i].name; + else + failed++; + if (_.clipboard.length == failed) { + _.alert(_.label("The files in the Clipboard are not readable.")); + return; + } + var go = function(callBack) { + if (dir == _.dir) + _.fadeFiles(); + $.ajax({ + type: "post", + dataType: "json", + url: _.getURL("cp_cbd"), + data: {dir: dir, files: files}, + async: false, + success: function(data) { + if (callBack) callBack(); + _.check4errors(data); + _.clearClipboard(); + if (dir == _.dir) + _.refresh(); + }, + error: function() { + if (callBack) callBack(); + $('#files > div').css({ + opacity: "", + filter: "" + }); + _.alert(_.label("Unknown error.")); + } + }); + }; + + if (failed) + _.confirm( + _.label("{count} files in the Clipboard are not readable. Do you want to copy the rest?", {count:failed}), + go + ) + else + go(); + +}; + +_.moveClipboard = function(dir) { + if (!_.clipboard || !_.clipboard.length) return; + var files = [], + failed = 0; + for (i = 0; i < _.clipboard.length; i++) + if (_.clipboard[i].readable && _.clipboard[i].writable) + files[i] = _.clipboard[i].dir + "/" + _.clipboard[i].name; + else + failed++; + if (_.clipboard.length == failed) { + _.alert(_.label("The files in the Clipboard are not movable.")) + return; + } + + var go = function(callBack) { + _.fadeFiles(); + $.ajax({ + type: "post", + dataType: "json", + url: _.getURL("mv_cbd"), + data: {dir: dir, files: files}, + async: false, + success: function(data) { + if (callBack) callBack(); + _.check4errors(data); + _.clearClipboard(); + _.refresh(); + }, + error: function() { + if (callBack) callBack(); + $('#files > div').css({ + opacity: "", + filter: "" + }); + _.alert(_.label("Unknown error.")); + } + }); + }; + + if (failed) + _.confirm( + _.label("{count} files in the Clipboard are not movable. Do you want to move the rest?", {count: failed}), + go + ); + else + go(); +}; + +_.deleteClipboard = function() { + if (!_.clipboard || !_.clipboard.length) return; + var files = [], + failed = 0; + for (i = 0; i < _.clipboard.length; i++) + if (_.clipboard[i].readable && _.clipboard[i].writable) + files[i] = _.clipboard[i].dir + "/" + _.clipboard[i].name; + else + failed++; + if (_.clipboard.length == failed) { + _.alert(_.label("The files in the Clipboard are not removable.")) + return; + } + var go = function(callBack) { + _.fadeFiles(); + $.ajax({ + type: "post", + dataType: "json", + url: _.getURL("rm_cbd"), + data: {files:files}, + async: false, + success: function(data) { + if (callBack) callBack(); + _.check4errors(data); + _.clearClipboard(); + _.refresh(); + }, + error: function() { + if (callBack) callBack(); + $('#files > div').css({ + opacity: "", + filter: "" + }); + _.alert(_.label("Unknown error.")); + } + }); + }; + if (failed) + _.confirm( + _.label("{count} files in the Clipboard are not removable. Do you want to delete the rest?", {count: failed}), + go + ); + else + go(); +}; + +_.downloadClipboard = function() { + if (!_.clipboard || !_.clipboard.length) return; + var files = []; + for (i = 0; i < _.clipboard.length; i++) + if (_.clipboard[i].readable) + files[i] = _.clipboard[i].dir + "/" + _.clipboard[i].name; + if (files.length) + _.post(_.getURL('downloadClipboard'), {files:files}); +}; + +_.clearClipboard = function() { + $('#clipboard').html(""); + _.clipboard = []; +}; diff --git a/lib/kcfinder/js/110.dropUpload.js b/lib/kcfinder/js/110.dropUpload.js new file mode 100644 index 0000000..f518c62 --- /dev/null +++ b/lib/kcfinder/js/110.dropUpload.js @@ -0,0 +1,165 @@ +/** This file is part of KCFinder project + * + * @desc Upload files using drag and drop + * @package KCFinder + * @version 3.12 + * @author Pavel Tzonkov + * @copyright 2010-2014 KCFinder Project + * @license http://opensource.org/licenses/GPL-3.0 GPLv3 + * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3 + * @link http://kcfinder.sunhater.com + */ + +_.initDropUpload = function() { + + if (!_.access.files.upload) + return; + + var files = $('#files'), + folders = $('#folders').find('div.folder > a'), + i, dlg, filesSize, uploaded, errors, + + precheck = function(e) { + filesSize = uploaded = 0; errors = []; + var fs = e.dataTransfer.files; + for (i = 0; i < fs.length; i++) + filesSize += fs[i].size; + + dlg = $('
             
             
             
            '); + + dlg.find('.bar.count').progressbar({max: fs.length, value: 0}); + dlg.find('.bar.size').progressbar({max: filesSize, value: 0}); + dlg.find('.info').css('padding', "5px 0").first().css('paddingTop', 0); + dlg.find('.info').last().css('paddingBottom', 0); + + dlg = _.dialog(_.label("Uploading files"), dlg, { + closeOnEscape: false, + buttons: [] + }); + + dlg.parent().css('paddingBottom', 0).find('.ui-dialog-titlebar button').css('visibility', 'hidden').get(0).disabled = true; + + return true; + }, + + localOptions = { + param: "upload[]", + maxFilesize: _.dropUploadMaxFilesize, + + begin: function(xhr, currentFile, count) { + + dlg.find('.info.count').html(_.label("Uploading file {current} of {count}", { + current: currentFile, + count: count + })); + + dlg.find('.info.size').html(_.label("Uploaded {uploaded} of {total}", { + uploaded: _.humanSize(uploaded), + total: _.humanSize(filesSize) + })); + + dlg.find('.info.errors').html(_.label("Errors:") + " " + errors.length); + dlg.find('.bar.count').progressbar({value: currentFile}); + dlg.find('.bar.size').progressbar({value: uploaded}); + }, + + success: function(xhr, currentFile, count) { + uploaded += xhr.file.size; + var response = xhr.responseText; + if (response.substr(0, 1) != "/") + errors.push($.$.htmlData(response)); + }, + + error: function(xhr, currentFile, count) { + uploaded += xhr.file.size; + errors.push($.$.htmlData(xhr.file.name + ": " + _.label("Failed to upload {filename}!", { + filename: xhr.file.name + }))); + }, + + abort: function(xhr, currentFile, filesCount) { + uploaded += xhr.file.size; + errors.push($.$.htmlData(xhr.file.name + ": " + _.label("Failed to upload {filename}!", { + filename: xhr.file.name + }))); + }, + + filesizeCallback: function(xhr, currentFile, filesCount) { + uploaded += xhr.file.size; + errors.push($.$.htmlData(xhr.file.name + ": " + _.label("The uploaded file exceeds {size} bytes.", { + size: _.dropUploadMaxFilesize + }))); + }, + + finish: function() { + _.refresh(); + dlg.find('.bar.size').progressbar({value: uploaded}); + dlg.find('.info.size').html(_.label("Uploaded: {uploaded} of {total}", { + uploaded: _.humanSize(uploaded), + total: _.humanSize(filesSize) + })); + dlg.find('.info.errors').html(_.label("Errors:") + " " + errors.length); + var err = errors; + setTimeout(function() { + dlg.dialog('destroy').detach(); + if (err.length) + _.alert(err.join('
            ')); + }, 500); + } + }, + + remoteOptions = { + ajax: { + success: function(data) { + _.refresh(); + if (data.error) { + _.alert(data.error) + return; + } + }, + error: function() { + _.refresh(); + _.alert(_.label("Unknown error.")); + }, + abort: function() { + _.refresh(); + } + } + }, + + url = "&dir=" + encodeURIComponent(_.dir); + + files.shDropUpload($.extend(localOptions, { + url: _.getURL('upload') + url, + precheck: function(e) { + if (!$('#folders span.current').first().parent().data('writable')) { + _.alert(_.label("Cannot write to upload folder.")); + return false; + } + return precheck(e); + } + }), $.extend(true, remoteOptions, { + ajax: { + url: _.getURL('dragUrl') + url + } + })); + + folders.each(function() { + var folder = this, + url = "&dir=" + encodeURIComponent($(folder).data('path')); + $(folder).shDropUpload($.extend(localOptions, { + url: _.getURL('upload') + url, + precheck: function(e) { + if (!$(folder).data('writable')) { + _.alert(_.label("Cannot write to upload folder.")); + return false; + } + return precheck(e); + } + }), $.extend(true, remoteOptions, { + ajax: { + url: _.getURL('dragUrl') + url + } + })); + }); +}; diff --git a/lib/kcfinder/js/120.misc.js b/lib/kcfinder/js/120.misc.js new file mode 100644 index 0000000..c3a2c48 --- /dev/null +++ b/lib/kcfinder/js/120.misc.js @@ -0,0 +1,132 @@ +/** This file is part of KCFinder project + * + * @desc Miscellaneous functionality + * @package KCFinder + * @version 3.12 + * @author Pavel Tzonkov + * @copyright 2010-2014 KCFinder Project + * @license http://opensource.org/licenses/GPL-3.0 GPLv3 + * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3 + * @link http://kcfinder.sunhater.com + */ + +_.orderFiles = function(callBack, selected) { + var order = $.$.kuki.get('order'), + desc = ($.$.kuki.get('orderDesc') == "on"), + a1, b1, arr; + + if (!_.files || !_.files.sort) + _.files = []; + + _.files = _.files.sort(function(a, b) { + if (!order) order = "name"; + + if (order == "date") { + a1 = a.mtime; + b1 = b.mtime; + } else if (order == "type") { + a1 = $.$.getFileExtension(a.name); + b1 = $.$.getFileExtension(b.name); + } else if (order == "size") { + a1 = a.size; + b1 = b.size; + } else { + a1 = a[order].toLowerCase(); + b1 = b[order].toLowerCase(); + } + + if ((order == "size") || (order == "date")) { + if (a1 < b1) return desc ? 1 : -1; + if (a1 > b1) return desc ? -1 : 1; + } + + if (a1 == b1) { + a1 = a.name.toLowerCase(); + b1 = b.name.toLowerCase(); + arr = [a1, b1]; + arr = arr.sort(); + return (arr[0] == a1) ? -1 : 1; + } + + arr = [a1, b1]; + arr = arr.sort(); + if (arr[0] == a1) return desc ? 1 : -1; + return desc ? -1 : 1; + }); + + _.showFiles(callBack, selected); + _.initFiles(); +}; + +_.humanSize = function(size) { + if (size < 1024) { + size = size.toString() + " B"; + } else if (size < 1048576) { + size /= 1024; + size = parseInt(size).toString() + " KB"; + } else if (size < 1073741824) { + size /= 1048576; + size = parseInt(size).toString() + " MB"; + } else if (size < 1099511627776) { + size /= 1073741824; + size = parseInt(size).toString() + " GB"; + } else { + size /= 1099511627776; + size = parseInt(size).toString() + " TB"; + } + return size; +}; + +_.getURL = function(act, lang) { + if (!lang) + lang = _.lang; + var url = "browse.php?type=" + encodeURIComponent(_.type) + "&lng=" + encodeURIComponent(lang); + if (_.opener.name) + url += "&opener=" + encodeURIComponent(_.opener.name); + if (act) + url += "&act=" + encodeURIComponent(act); + if (_.cms) + url += "&cms=" + encodeURIComponent(_.cms); + return url; +}; + +_.label = function(index, data) { + var label = _.labels[index] ? _.labels[index] : index; + if (data) + $.each(data, function(key, val) { + label = label.replace("{" + key + "}", val); + }); + return label; +}; + +_.check4errors = function(data) { + if (!data.error) + return false; + var msg = data.error.join + ? data.error.join("\n") + : data.error; + _.alert(msg); + return true; +}; + +_.post = function(url, data) { + var html = '
            '; + $.each(data, function(key, val) { + if ($.isArray(val)) + $.each(val, function(i, aval) { + html += ''; + }); + else + html += ''; + }); + html += '
            '; + $('#menu').html(html).show(); + $('#postForm').get(0).submit(); +}; + +_.fadeFiles = function() { + $('#files > div').css({ + opacity: "0.4", + filter: "alpha(opacity=40)" + }); +}; diff --git a/lib/kcfinder/js/index.php b/lib/kcfinder/js/index.php new file mode 100644 index 0000000..962e48e --- /dev/null +++ b/lib/kcfinder/js/index.php @@ -0,0 +1,20 @@ + + * @copyright 2010-2014 KCFinder Project + * @license http://opensource.org/licenses/GPL-3.0 GPLv3 + * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3 + * @link http://kcfinder.sunhater.com + */ + +namespace kcfinder; + +chdir(".."); +require "core/autoload.php"; +$min = new minifier("js"); +$min->minify("cache/base.js"); diff --git a/lib/kcfinder/js_localize.php b/lib/kcfinder/js_localize.php new file mode 100644 index 0000000..3ac3c76 --- /dev/null +++ b/lib/kcfinder/js_localize.php @@ -0,0 +1,46 @@ + + * @copyright 2010-2014 KCFinder Project + * @license http://opensource.org/licenses/GPL-3.0 GPLv3 + * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3 + * @link http://kcfinder.sunhater.com + */ + +namespace kcfinder; +require "core/autoload.php"; + +if (!isset($_GET['lng']) || ($_GET['lng'] == 'en') || + ($_GET['lng'] != basename($_GET['lng'])) || + !is_file("lang/" . $_GET['lng'] . ".php") +) { + header("Content-Type: text/javascript"); + die; +} + +$file = "lang/" . $_GET['lng'] . ".php"; +$mtime = @filemtime($file); + +if ($mtime) + httpCache::checkMTime($mtime, "Content-Type: text/javascript"); + +require $file; +header("Content-Type: text/javascript"); + +echo "_.labels={"; + +$i = 0; +foreach ($lang as $english => $native) { + if (substr($english, 0, 1) != "_") { + echo "'" . text::jsValue($english) . "':\"" . text::jsValue($native) . "\""; + if (++$i < count($lang)) + echo ","; + } +} + +echo "}"; diff --git a/lib/kcfinder/lang/.htaccess b/lib/kcfinder/lang/.htaccess new file mode 100644 index 0000000..d61b264 --- /dev/null +++ b/lib/kcfinder/lang/.htaccess @@ -0,0 +1,4 @@ + +Order allow,deny +Deny from all + diff --git a/lib/kcfinder/lang/af.php b/lib/kcfinder/lang/af.php new file mode 100644 index 0000000..86c2eb7 --- /dev/null +++ b/lib/kcfinder/lang/af.php @@ -0,0 +1,246 @@ + "Afrikaans", + '_native' => "Afrikaans", + '_locale' => "af-ZA.UTF-8", + '_charset' => "utf-8", + + // Date time formats. See http://www.php.net/manual/en/function.strftime.php + '_dateTimeFull' => "%d %B %Y %H:%M", + '_dateTimeMid' => "%d %b %Y %H:%M", + '_dateTimeSmall' => "%d %b %Y %H:%M", + + "You don't have permissions to upload files." => + "Jy het nie toestemming om lêers op te laai nie oplaai nie.", + + "You don't have permissions to browse server." => + "Jy het nie toestemming tot die bediener nie.", + + "Cannot move uploaded file to target folder." => + "Jy kannie die lêer beweeg na die gids toe nie.", + + "Unknown error." => + "Onbekende fout.", + + "The uploaded file exceeds {size} bytes." => + "Die foto's lêer oorskry {size} grepe.", + + "The uploaded file was only partially uploaded." => + "Die foto's lêer is slegs gedeeltelik opgelaai.", + + "No file was uploaded." => + "Geen lêer is opgelaai.", + + "Missing a temporary folder." => + "'N tydelike gids ontbreek.", + + "Failed to write file." => + "Misluk om lêer te kryf.", + + "Denied file extension." => + "Lêer uitbreiding verloën.", + + "Unknown image format/encoding." => + "Onbekende prentjie-formaat / kodering.", + + "The image is too big and/or cannot be resized." => + "Die beeld is te groot en / of kan nie verander word nie.", + + "Cannot create {dir} folder." => + "Kan nie {dir} gids skep nie.", + + "Cannot write to upload folder." => + "Kan nie skryf na die oplaai gids nie.", + + "Cannot read .htaccess" => + "Kan nie .htaccess lees nie.", + + "Incorrect .htaccess file. Cannot rewrite it!" => + "Verkeerde .htaccess lêer. Kan nie herskryf dit!", + + "Cannot fetch content of {dir} folder." => + "Kan nie haal inhoud van {dir} gids nie.", + + "Cannot read upload folder." => + "Kan nie oplaai gids lees nie.", + + "Cannot access or create thumbnails folder." => + "Kan nie toegang tot of duimnaels gids skep.", + + "Cannot access or write to upload folder." => + "Kan nie toegang tot of skryf na oplaai gids nie.", + + "Please enter new folder name." => + "Gee die nuwe gidsnaam.", + + "Unallowed characters in folder name." => + "Ongeoorloofd karakters in gidsnaam.", + + "Folder name shouldn't begins with '.'" => + "Gidsnaam moet nie begin met '.'", + + "Please enter new file name." => + "Gee nuwe lêernaam.", + + "Unallowed characters in file name." => + "Ongeoorloofd karakters in die lêernaam.", + + "File name shouldn't begins with '.'" => + "Lêer naam moet nie begin met '.'", + + "Are you sure you want to delete this file?" => + "Is jy seker jy wil hierdie lêer te verwyder ?", + + "Are you sure you want to delete this folder and all its content?" => + "Is jy seker jy wil hierdie gids en al die inhoud daarin te verwyder ?", + + "Unexisting directory type." => + "Nie Bestaande gids tipe.", + + "Undefined MIME types." => + "Ongedefinieerd MIME-tipes.", + + "Fileinfo PECL extension is missing." => + "Fileinfo PECL uitbreiding is weg.", + + "Opening fileinfo database failed." => + "Opening van fileinfo databasis het misluk.", + + "You can't upload such files." => + "Jy kan nie sulke lêers oplaai.", + + "The file '{file}' does not exist." => + "Die lêer '{file}' bestaan ​​nie.", + + "Cannot read '{file}'." => + "Kan nie '{file}' lees nie.", + + "Cannot copy '{file}'." => + "Kan nie '{file}' kopieer nie.", + + "Cannot move '{file}'." => + "Kan nie '{file}' beweeg nie.", + + "Cannot delete '{file}'." => + "Kan nie '{file}' verwyder .", + + "Click to remove from the Clipboard" => + "Klik om te verwyder van die Klembord", + + "This file is already added to the Clipboard." => + "Hierdie lêer is reeds aan die Klembord bygevoeg.", + + "Copy files here" => + "Kopieer lêers hier", + + "Move files here" => + "Skuif lêers hier", + + "Delete files" => + "Verwyder lêers ", + + "Clear the Clipboard" => // + "Vee Klembord Skoon", + + "Are you sure you want to delete all files in the Clipboard?" => + "Is jy seker jy wil al die lêers in die Klembord te verwyder?", + + "Copy {count} files" => + "Kopieer {count} lêers", + + "Move {count} files" => + "Beweeg {count} lêers", + + "Add to Clipboard" => + "Voeg na klembord", + "New folder name:" => "Nuwe gids naam:", + "New file name:" => "Nuwe lêer naam:", + "Folders" => "Gidse", + + "Upload" => "Oplaai", + "Refresh" => "Herlaai", + "Settings" => "Stellings", + "Maximize" => "Maksimaliseer", + "About" => "About", + "files" => "lêers", + "View:" => "Bekyk:", + "Show:" => "Wys:", + "Order by:" => "Sorteer volgens:", + "Thumbnails" => "Duimnaels", + "List" => "Lys", + "Name" => "Naam", + "Size" => "Grootte", + "Date" => "Datum", + "Descending" => "Aflopend", + "Uploading file..." => "Lêer Besig Met Oplaai...", + "Loading image..." => "Besig om beeld te laai...", + "Loading folders..." => "Besig om Gidse te laai...", + "Loading files..." => "Besig om Lêers te laai...", + "New Subfolder..." => "Nuwe subgids...", + "Rename..." => "Naam verander...", + "Delete" => "Verwyder", + "OK" => "REG", + "Cancel" => "Kanselleer", + "Select" => "Kies", + "Select Thumbnail" => "Kies Duimnaelskets", + "View" => "Bekyk", + "Download" => "Aflaai", + 'Clipboard' => "Klembord", + + // VERSION 2 NEW LABELS + + "Cannot rename the folder." => + "Kan nie die gids naam vernader nie.", + + "Non-existing directory type." => + "Nie-bestaande gids tipe.", + + "Cannot delete the folder." => + "Kan nie die gids verwyder nie.", + + "The files in the Clipboard are not readable." => + "Die lêers in die Klembord is nie leesbaar is.", + + "{count} files in the Clipboard are not readable. Do you want to copy the rest?" => + "{count} lêers in die Klembord is nie leesbaar is. Wil jy die res te kopieer ?", + + "The files in the Clipboard are not movable." => + "Die lêers in die Klembord kan verskuif word nie.", + + "{count} files in the Clipboard are not movable. Do you want to move the rest?" => + "{count} lêers in die Klembord kan nie verskuif word nie. Wil jy die res te beweeg ?", + + "The files in the Clipboard are not removable." => + "Die lêers in die Klembord kan nie verwyder word nie.", + + "{count} files in the Clipboard are not removable. Do you want to delete the rest?" => + "{count} lêers in die Klembord kan nie verwyder word nie. Wil jy die res te verwyder ?", + + "The selected files are not removable." => + "Die geselekteerde lêers kan nie verwyder word nie", + + "{count} selected files are not removable. Do you want to delete the rest?" => + "{count} geselekteerde lêers kan nie verwyder word nie. Wil jy die res te verwyder ?", + + "Are you sure you want to delete all selected files?" => + "Is jy seker jy wil all geselekteerde lêers te verwyder ?", + + "Failed to delete {count} files/folders." => + "Misluk {count} lêers/gidse te verwyder.", + + "A file or folder with that name already exists." => + "'N lêer of gids met daardie naam bestaan ​​reeds.", + + "Inexistant or inaccessible folder." => + "Nie-bestaande of ontoeganklik gids.", + + "selected files" => "geselekteerde lêers", + "Type" => "Tipe", + "Select Thumbnails" => "Kies duimnaels", + "Download files" => "Laai lêers af", +); diff --git a/lib/kcfinder/lang/bg.php b/lib/kcfinder/lang/bg.php new file mode 100644 index 0000000..2aa78a0 --- /dev/null +++ b/lib/kcfinder/lang/bg.php @@ -0,0 +1,278 @@ + + */ + +$lang = array( + + '_lang' => "Bulgarian", + '_native' => "Български", + '_locale' => "bg_BG.UTF-8", // UNIX localization code + '_charset' => "utf-8", // Browser charset + + // Date time formats. See http://www.php.net/manual/en/function.strftime.php + '_dateTimeFull' => "%A, %e %B, %Y %H:%M", + '_dateTimeMid' => "%a %e %b %Y %H:%M", + '_dateTimeSmall' => "%d.%m.%Y %H:%M", + + "You don't have permissions to upload files." => + "Нямате права за качване.", + + "You don't have permissions to browse server." => + "Нямате права за разглеждане на сървъра.", + + "Cannot move uploaded file to target folder." => + "Файлът не може да се премести в целевата папка.", + + "Unknown error." => + "Непозната грешка.", + + "The uploaded file exceeds {size} bytes." => + "Каченият файл надхвърля {size} байта.", + + "The uploaded file was only partially uploaded." => + "Каченият файл беше качен само частично.", + + "No file was uploaded." => + "Файлът не беше качен", + + "Missing a temporary folder." => + "Липсва временна папка.", + + "Failed to write file." => + "Грешка при записване на файла.", + + "Denied file extension." => + "Забранено файлово разширение.", + + "Unknown image format/encoding." => + "Файлът не може да бъде разпознат като изображение.", + + "The image is too big and/or cannot be resized." => + "Изображението е много голямо и/или не може да бъде преоразмерено.", + + "Cannot create {dir} folder." => + "Невъзможност да се създаде папка {dir}.", + + "Cannot rename the folder." => + "Папката не може да се преимеува.", + + "Cannot write to upload folder." => + "Не е възможно записването на файлове в папката за качване.", + + "Cannot read .htaccess" => + "Не е възможно прочитането на .htaccess", + + "Incorrect .htaccess file. Cannot rewrite it!" => + "Невалиден .htaccess файл. Не може да се презапише автоматично!", + + "Cannot read upload folder." => + "Не е възможно прочитането на папката за качване.", + + "Cannot access or create thumbnails folder." => + "Невъзможен достъп или невъзможно създаване на папката за thumbnails.", + + "Cannot access or write to upload folder." => + "Папката не може да се достъпи или не може да се записва в нея.", + + "Please enter new folder name." => + "Моля въведете име на папката.", + + "Unallowable characters in folder name." => + "Непозволени знаци в името на папката.", + + "Folder name shouldn't begins with '.'" => + "Името на папката не трябва да започва с '.'", + + "Please enter new file name." => + "Моля въведете ново име на файла", + + "Unallowable characters in file name." => + "Непозволени знаци в името на файла.", + + "File name shouldn't begins with '.'" => + "Името на файла не трябва да започва с '.'", + + "Are you sure you want to delete this file?" => + "Наистина ли искате да изтриете този файл?", + + + "Are you sure you want to delete this folder and all its content?" => + "Наистина ли искате да изтриете тази папка и цялото ѝ съдържание?", + + "Non-existing directory type." => + "Несъществуващ специален тип на папка.", + + "Undefined MIME types." => + "Не са дефинирани MIME типове.", + + "Fileinfo PECL extension is missing." => + "Липсва Fileinfo PECL разширение.", + + "Opening fileinfo database failed." => + "Грешка при отваряне на fileinfo дефиниции.", + + "You can't upload such files." => + "Не можете да качвате такива файлове.", + + "The file '{file}' does not exist." => + "Фаълът '{file}' не съществува.", + + "Cannot read '{file}'." => + "Файлът '{file}' не може да бъде прочетен.", + + "Cannot copy '{file}'." => + "Файлът '{file}' не може да бъде копиран.", + + "Cannot move '{file}'." => + "Файлът '{file}' не може да бъде преместен.", + + "Cannot delete '{file}'." => + "Файлът '{file}' не може да бъде изтрит.", + + "Cannot delete the folder." => + "Папката не може да бъде изтрита.", + + "Click to remove from the Clipboard" => + "Цъкнете за да премахнете файла от клипборда", + + "This file is already added to the Clipboard." => + "Този файл вече е добавен към клипборда.", + + "The files in the Clipboard are not readable." => + "Файловете в клипборда не могат да се прочетат.", + + "{count} files in the Clipboard are not readable. Do you want to copy the rest?" => + "{count} файла в клипборда не могат да се прочетат. Искате ли да копирате останалите?", + + "The files in the Clipboard are not movable." => + "Файловете в клипборда не могат да бъдат преместени.", + + "{count} files in the Clipboard are not movable. Do you want to move the rest?" => + "{count} файла в клипборда не могат да бъдат преместени. Искате ли да преместите останалите?", + + "The files in the Clipboard are not removable." => + "Файловете в клипборда не могат да бъдат изтрити.", + + "{count} files in the Clipboard are not removable. Do you want to delete the rest?" => + "{count} файла в клипборда не могат да бъдат изтрити. Искате ли да изтриете останалите?", + + "The selected files are not removable." => + "Избраните файлове не могат да бъдат изтрити.", + + "{count} selected files are not removable. Do you want to delete the rest?" => + "{count} от избраните файлове не могат да бъдат изтрити. Искате ли да изтриете останалите?", + + "Are you sure you want to delete all selected files?" => + "Наистина ли искате да изтриете всички избрани файлове?", + + "Failed to delete {count} files/folders." => + "{count} файла/папки не могат да бъдат изтрити.", + + "A file or folder with that name already exists." => + "Вече има файл или папка с такова име.", + + "Copy files here" => + "Копирай файловете тук", + + "Move files here" => + "Премести файловете тук", + + "Delete files" => + "Изтрий файловете", + + "Clear the Clipboard" => + "Изчисти клипборда", + + "Are you sure you want to delete all files in the Clipboard?" => + "Наистина ли искате да изтриете всички файлове от клипборда?", + + "Copy {count} files" => + "Копирай {count} файла", + + "Move {count} files" => + "Премести {count} файла", + + "Add to Clipboard" => + "Добави към клипборда", + + "Inexistant or inaccessible folder." => + "Несъществуваща или недостъпна папка.", + + "New folder name:" => "Име на папката:", + "New file name:" => "Ново име на файла:", + + "Upload" => "Качи", + "Refresh" => "Актуализирай", + "Settings" => "Настройки", + "Maximize" => "Разпъни", + "About" => "Информация", + "files" => "файла", + "selected files" => "избрани файла", + "View:" => "Изглед:", + "Show:" => "Покажи:", + "Order by:" => "Подреди по:", + "Thumbnails" => "Картинки", + "List" => "Списък", + "Name" => "Име", + "Type" => "Тип", + "Size" => "Размер", + "Date" => "Дата", + "Descending" => "Обратен ред", + "Uploading file..." => "Файлът се качва...", + "Loading image..." => "Изображението се зарежда...", + "Loading folders..." => "Зареждане на папките...", + "Loading files..." => "Зареждане на папката...", + "New Subfolder..." => "Нова подпапка...", + "Rename..." => "Преименуване...", + "Delete" => "Изтрий", + "OK" => "OK", + "Cancel" => "Отказ", + "Select" => "Избери", + "Select Thumbnail" => "Избери малък вариант", + "Select Thumbnails" => "Избери малки варианти", + "View" => "Преглед", + "Download" => "Свали", + "Download files" => "Свали файловете", + "Clipboard" => "Клипборд", + + // SINCE 2.4 + + "Checking for new version..." => "Проверка за нова версия...", + "Unable to connect!" => "Не може да се свърже!", + "Download version {version} now!" => "Свалете версия {version} сега!", + "KCFinder is up to date!" => "KCFinder е актуален!", + "Licenses:" => "Лицензи:", + "Attention" => "Внимание", + "Question" => "Въпрос", + "Yes" => "Да", + "No" => "Не", + + // SINCE 2.41 + + "You cannot rename the extension of files!" => + "Не можете да преименувате разширенията на файловете!", + + // SINCE 2.5 + + "Uploading file {number} of {count}... {progress}" => + "Качване на файл {number} от {count}... {progress}", + + "Failed to upload {filename}!" => "Несполучливо качване на {filename}!", + + // SINCE 3.0 + + "Close" => "Затвори", + "Previous" => "Предишно", + "Next" => "Следващо", + "Confirmation" => "Потвърждение", + "Warning" => "Внимание", + + // SINCE 3.20 + + "Uploading files" => "Качване на файлове", + "Uploading file {current} of {count}" => "Качване на файл {current} от общо {count}", + "Uploaded {uploaded} of {total}" => "Качено {uploaded} от общо {total}", + "Errors:" => "Грешки:" +); diff --git a/lib/kcfinder/lang/ca.php b/lib/kcfinder/lang/ca.php new file mode 100644 index 0000000..2cf49f3 --- /dev/null +++ b/lib/kcfinder/lang/ca.php @@ -0,0 +1,128 @@ + "Catalan", + '_native' => "Català", + '_locale' => "ca_ES.UTF-8", // UNIX localization code + '_charset' => "utf-8", // Browser charset + + // Date time formats. See http://www.php.net/manual/en/function.strftime.php + '_dateTimeFull' => "%A, %e %B, %Y %H:%M", + '_dateTimeMid' => "%a %e %b %Y %H:%M", + '_dateTimeSmall' => "%d.%m.%Y %H:%M", + + "You don't have permissions to upload files." => "No teniu permisos per pujar arxius.", + "You don't have permissions to browse server." => "No teniu permisos per visualitzar arxius.", + "Cannot move uploaded file to target folder." => "No es pot moure el fitxer pujat al directori destí", + "Unknown error." => "Error desconegut.", + "The uploaded file exceeds {size} bytes." => "El fitxer seleccionat excedeix el pes màxim permès ( {size} bytes ).", + "The uploaded file was only partially uploaded." => "El fitxer seleccionat només s'ha carregat parcialment.", + "No file was uploaded." => "No s'ha carregat cap fitxer.", + "Missing a temporary folder." => "Manca un directori temporal.", + "Failed to write file." => "No s'ha pogut escriure el fitxer.", + "Denied file extension." => "Extensió de fitxer no permesa.", + "Unknown image format/encoding." => "Format d'imatge desconegut.", + "The image is too big and/or cannot be resized." => "La imatge és massa gran i/o no es pot redimensionar.", + "Cannot create {dir} folder." => "No s'ha pogut crear el directori {dir}", + "Cannot rename the folder." => "No es pot reanomenar el directori.", + "Cannot write to upload folder." => "No es pot escriure al directori de càrrega de fitxers.", + "Cannot read .htaccess" => "No s'ha pogut llegir .htaccess.", + "Incorrect .htaccess file. Cannot rewrite it!" => "Fitxer .htaccess incorrecte. No es pot reescriure!", + "Cannot read upload folder." => "No s'ha pogut llegir la carpeta de càrrega de fitxers.", + "Cannot access or create thumbnails folder." => "No s'ha pogut accedir o crear la carpeta de miniatures.", + "Cannot access or write to upload folder." => "No s'ha pogut accedir o escriure la carpeta de càrrega de fitxers.", + "Please enter new folder name." => "Si us plau, introduïu el nom del nou directori.", + "Unallowable characters in folder name." => "Caràcters no permesos en el nom del directori.", + "Folder name shouldn't begins with '.'" => "El nom d'un directori no hauria de començar amb un punt '.'", + "Please enter new file name." => "Si us plau, introduïu el nom del nou fitxer.", + "Unallowable characters in file name." => "Caràcters no permesos en el nom del fitxer.", + "File name shouldn't begins with '.'" => "El nom d'un fitxer no hauria de començar amb un punt '.'", + "Are you sure you want to delete this file?" => "Esteu segur que voleu eliminar aquest fitxer?", + "Are you sure you want to delete this folder and all its content?" => "Esteu segur que voleu eliminar aquest directori i tot el seu contingut?", + "Non-existing directory type." => "Tipus de directori inexistent.", + "Undefined MIME types." => "Tipus MIME no definit.", + "Fileinfo PECL extension is missing." => "Manca arxiu d'informació de l'extensió PECL.", + "Opening fileinfo database failed." => "Error obrint el fitxer d'informació de la base de dades.", + "You can't upload such files." => "No podeu carregar tants fitxers.", + "The file '{file}' does not exist." => "El fitxer '{file}' no existeix.", + "Cannot read '{file}'." => "No s'ha pogut llegir '{file}'.", + "Cannot copy '{file}'." => "No s'ha pogut copiar '{file}'.", + "Cannot move '{file}'." => "No s'ha pogut moure '{file}'.", + "Cannot delete '{file}'." => "No s'ha pogut eliminar '{file}'.", + "Cannot delete the folder." => "No es pot eliminar el directori.", + "Click to remove from the Clipboard" => "Feu clic per eliminar del portapapers", + "This file is already added to the Clipboard." => "Aquest arxiu ja es troba al portapapers.", + "The files in the Clipboard are not readable." => "No es poden llegir els fitxers del portapapers.", + "{count} files in the Clipboard are not readable. Do you want to copy the rest?" => "{count} fitxers del portapapers no es poden llegir. Voleu copiar la resta?", + "The files in the Clipboard are not movable." => "No es poden moure els fitxers del portapapers.", + "{count} files in the Clipboard are not movable. Do you want to move the rest?" => "{count} fitxers del portapapers no es poden moure. Voleu moure la resta?", + "The files in the Clipboard are not removable." => "Els fitxers del portapapers no es poden eliminar.", + "{count} files in the Clipboard are not removable. Do you want to delete the rest?" => "{count} fitxers del portapapers no es poden eliminar. Voleu eliminar la resta?", + "The selected files are not removable." => "Els fitxers seleccionats no es poden eliminar.", + "{count} selected files are not removable. Do you want to delete the rest?" => "{count} fitxers dels seleccionats no es poden eliminar. Voleu eliminar la resta?", + "Are you sure you want to delete all selected files?" => "Esteu segur que voleu eliminar els fitxers seleccionats?", + "Failed to delete {count} files/folders." => "Error al eliminar {count} fitxers/directoris.", + "A file or folder with that name already exists." => "Ja existeix un directori o fitxer amb aquest nom.", + "Copy files here" => "Copia els fitxers aquí", + "Move files here" => "Mou els fitxers aquí", + "Delete files" => "Elimina els fitxers", + "Clear the Clipboard" => "Buida el portapapers", + "Are you sure you want to delete all files in the Clipboard?" => "Esteu segur que voleu eliminar tots els fitxers del portapapers?", + "Copy {count} files" => "Copia els {count} fitxers aquí", + "Move {count} files" => "Mou els {count} fitxers aquí", + "Add to Clipboard" => "Afegeix al portapapers", + "Inexistant or inaccessible folder." => "Directori inexistent o inaccessible.", + "New folder name:" => "Nom del nou directori:", + "New file name:" => "Nom del nou fitxer:", + "Upload" => "Carrega arxius", + "Refresh" => "Refresca", + "Settings" => "Opcions", + "Maximize" => "Maximitza", + "About" => "Sobre...", + "files" => "Fitxers", + "selected files" => "Fitxers seleccionats", + "View:" => "Veure:", + "Show:" => "Mostra:", + "Order by:" => "Ordena per:", + "Thumbnails" => "Miniatures", + "List" => "Llistat", + "Name" => "Nom", + "Type" => "Tipus", + "Size" => "Mida", + "Date" => "Data", + "Descending" => "Descendent", + "Uploading file..." => "Carregant fitxer...", + "Loading image..." => "Carregant imatge...", + "Loading folders..." => "Carregant directoris...", + "Loading files..." => "Carregant fitxers...", + "New Subfolder..." => "Nou subdirectori...", + "Rename..." => "Canvia el nom...", + "Delete" => "Elimina", + "OK" => "D'acord", + "Cancel" => "Cancel·la", + "Select" => "Selecciona", + "Select Thumbnail" => "Selecciona miniatura", + "Select Thumbnails" => "Selecciona miniatures", + "View" => "Veure", + "Download" => "Descarrega", + "Download files" => "Descarrega fitxers", + "Clipboard" => "Portapapers", + "Checking for new version..." => "Comprovant actualitzacions...", + "Unable to connect!" => "No es pot connectar!", + "Download version {version} now!" => "Descarregueu la versió {version}!", + "KCFinder is up to date!" => "KCFinder està actualitzat!", + "Licenses:" => "Llicències:", + "Attention" => "Atenció", + "Question" => "Pregunta", + "Yes" => "Sí", + "No" => "No", + "You cannot rename the extension of files!" => "No està permès canviar la extensió al fitxer.", + "Uploading file {number} of {count}... {progress}" => "Carregant arxiu {number} de {count}... {progress}", + "Failed to upload {filename}!" => "Error al carregar {filename}", +); diff --git a/lib/kcfinder/lang/cs.php b/lib/kcfinder/lang/cs.php new file mode 100644 index 0000000..a7efad2 --- /dev/null +++ b/lib/kcfinder/lang/cs.php @@ -0,0 +1,132 @@ + + */ + +$lang = array( + + '_lang' => "Czech", + '_native' => "Čeština", + '_locale' => "cs_CZ.UTF-8", // UNIX localization code + '_charset' => "utf-8", // Browser charset + + // Date time formats. See http://www.php.net/manual/en/function.strftime.php + '_dateTimeFull' => "%A, %e.%B.%Y %H:%M", + '_dateTimeMid' => "%a %e %b %Y %H:%M", + '_dateTimeSmall' => "%d.%m.%Y %H:%M", + + "You don't have permissions to upload files." => "Nemáte práva pro nahrávání souborů.", + "You don't have permissions to browse server." => "Nemáte práva pro prohlížení serveru.", + "Cannot move uploaded file to target folder." => "Nelze přesunout soubor do určeného adresáře.", + "Unknown error." => "Neznámá chyba.", + "The uploaded file exceeds {size} bytes." => "Nahraný soubor přesahuje {size} bytů.", + "The uploaded file was only partially uploaded." => "Nahraný soubor byl nahrán pouze částečně.", + "No file was uploaded." => "Žádný soubor nebyl nahrán na server.", + "Missing a temporary folder." => "Chybí dočasný adresář.", + "Failed to write file." => "Soubor se nepodařilo se uložit.", + "Denied file extension." => "Nepodporovaný typ souboru.", + "Unknown image format/encoding." => "Neznámý formát obrázku/encoding.", + "The image is too big and/or cannot be resized." => "Obrázek je příliš velký/nebo nemohl být zmenšen.", + "Cannot create {dir} folder." => "Adresář {dir} nelze vytvořit.", + "Cannot rename the folder." => "Adresář nelze přejmenovat.", + "Cannot write to upload folder." => "Nelze ukládat do adresáře pro nahrávání.", + "Cannot read .htaccess" => "Není možno číst soubor .htaccess", + "Incorrect .htaccess file. Cannot rewrite it!" => "Chybný soubor .htaccess. Soubor nelze přepsat!", + "Cannot read upload folder." => "Nelze číst z adresáře pro nahrávání souborů.", + "Cannot access or create thumbnails folder." => "Adresář pro náhledy nelze vytvořit nebo není přístupný.", + "Cannot access or write to upload folder." => "Nelze přistoupit, nebo zapisovat do adresáře pro nahrávání souborů.", + "Please enter new folder name." => "Vložte prosím nové jméno adresáře.", + "Unallowable characters in folder name." => "Nepovolené znaky v názvu adresáře.", + "Folder name shouldn't begins with '.'" => "Jméno adresáře nesmí začínat znakem '.'", + "Please enter new file name." => "Vložte prosím nové jméno souboru.", + "Unallowable characters in file name." => "Nepovolené znaky v názvu souboru.", + "File name shouldn't begins with '.'" => "Název soubor nesmí začínat znakem '.'", + "Are you sure you want to delete this file?" => "Jste si jistý že chcete smazat tento soubor?", + "Are you sure you want to delete this folder and all its content?" => "Jste si jistý že chcete smazat tento adresář a celý jeho obsah?", + "Non-existing directory type." => "Neexistující typ adresáře.", + "Undefined MIME types." => "Nedefinovaný MIME typ souboru.", + "Fileinfo PECL extension is missing." => "Rozříření PECL pro zjištění informací o souboru chybí.", + "Opening fileinfo database failed." => "Načtení informací o souboru selhalo.", + "You can't upload such files." => "Tyto soubory nemůžete nahrát na server.", + "The file '{file}' does not exist." => "Tento soubor '{file}' neexistuje.", + "Cannot read '{file}'." => "Nelze načíst '{file}'.", + "Cannot copy '{file}'." => "Nelze kopírovat '{file}'.", + "Cannot move '{file}'." => "Nelze přesunout '{file}'.", + "Cannot delete '{file}'." => "Nelze smazat '{file}'.", + "Cannot delete the folder." => "Adresář nelze smazat.", + "Click to remove from the Clipboard" => "Klikněte pro odstranění ze schránky", + "This file is already added to the Clipboard." => "Tento soubor je již ve schránce vložen.", + "The files in the Clipboard are not readable." => "Soubory ve schránce nelze načíst.", + "{count} files in the Clipboard are not readable. Do you want to copy the rest?" => "{count} souborů ve schránce nelze načíst. Chcete zkopírovat zbylé soubory?", + "The files in the Clipboard are not movable." => "Soubory ve schránce nelze přesunout.", + "{count} files in the Clipboard are not movable. Do you want to move the rest?" => "{count} souborů ve schránce nelze přesunout. Chcete přesunout zbylé soubory?", + "The files in the Clipboard are not removable." => "Soubory ve schránce nelze smazat.", + "{count} files in the Clipboard are not removable. Do you want to delete the rest?" => "{count} souborů ve schránce nelze smazat. Chcete smazat zbylé soubory?", + "The selected files are not removable." => "Označené soubory nelze smazat.", + "{count} selected files are not removable. Do you want to delete the rest?" => "{count} označených souborů nelze smazat. Chcete smazat zbylé soubory?", + "Are you sure you want to delete all selected files?" => "Jste si jistý že chcete smazat vybrané soubory?", + "Failed to delete {count} files/folders." => "Nebylo smazáno {count} souborů/adresářů.", + "A file or folder with that name already exists." => "Soubor nebo adresář s takovým jménem již existuje.", + "Copy files here" => "Kopírovat soubory na toto místo", + "Move files here" => "Přesunout soubory na toto místo", + "Delete files" => "Smazat soubory", + "Clear the Clipboard" => "Vyčistit schránku", + "Are you sure you want to delete all files in the Clipboard?" => "Jste si jistý že chcete vymazat všechny soubory ze schránky?", + "Copy {count} files" => "Kopírovat {count} souborů", + "Move {count} files" => "Přesunout {count} souborů", + "Add to Clipboard" => "Vložit do schránky", + "Inexistant or inaccessible folder." => "Neexistující nebo nepřístupný adresář.", + "New folder name:" => "Nový název adresáře:", + "New file name:" => "Nový název souboru:", + "Upload" => "Nahrát", + "Refresh" => "Obnovit", + "Settings" => "Nastavení", + "Maximize" => "Maximalizovat", + "About" => "O aplikaci", + "files" => "soubory", + "selected files" => "vybrané soubory", + "View:" => "Zobrazit:", + "Show:" => "Ukázat:", + "Order by:" => "Řadit podle:", + "Thumbnails" => "Náhledy", + "List" => "Seznam", + "Name" => "Jméno", + "Type" => "Typ", + "Size" => "Velikost", + "Date" => "Datum", + "Descending" => "Sestupně", + "Uploading file..." => "Nahrávání souboru...", + "Loading image..." => "Načítání obrázku...", + "Loading folders..." => "Načítání adresářů...", + "Loading files..." => "Načítání souborů...", + "New Subfolder..." => "Nový adresář...", + "Rename..." => "Přejmenovat...", + "Delete" => "Smazat", + "OK" => "OK", + "Cancel" => "Zrušit", + "Select" => "Vybrat", + "Select Thumbnail" => "Vybrat náhled", + "Select Thumbnails" => "Vybrat náhled", + "View" => "Zobrazit", + "Download" => "Stažení", + "Download files" => "Stáhnout soubory", + "Clipboard" => "Schránka", + "Checking for new version..." => "Zkontrolovat novou verzi...", + "Unable to connect!" => "Nelze připojit!", + "Download version {version} now!" => "Stáhnout verzi {version} nyní!", + "KCFinder is up to date!" => "KCFinder je aktuální!", + "Licenses:" => "Licence:", + "Attention" => "Upozornění", + "Question" => "Otázka", + "Yes" => "Ano", + "No" => "Ne", + "You cannot rename the extension of files!" => "Nemůžete přejmenovat příponu souborů!", + "Uploading file {number} of {count}... {progress}" => "Nahrávám soubor {number} z {count}... {progress}", + "Failed to upload {filename}!" => "Nepodařilo se nahrát soubor {filename}!", + "Close" => "Zavřít", + "Previous" => "Předchozí", + "Next" => "Další", + "Confirmation" => "Potvrzení", + "Warning" => "Varování", +); diff --git a/lib/kcfinder/lang/da.php b/lib/kcfinder/lang/da.php new file mode 100644 index 0000000..13759cc --- /dev/null +++ b/lib/kcfinder/lang/da.php @@ -0,0 +1,127 @@ + + * Danish corrections by Mikael Lyngvig + */ + +$lang = array( + + '_lang' => "Danish", + '_native' => "Dansk", + '_locale' => "da_DK.UTF-8", // UNIX localization code + '_charset' => "utf-8", // Browser charset + + // Date time formats. See http://www.php.net/manual/en/function.strftime.php + '_dateTimeFull' => "%A, %e.%B %Y %H:%M", + '_dateTimeMid' => "%a %e %b %Y %H:%M", + '_dateTimeSmall' => "%d/%m/%Y %H:%M", + + "You don't have permissions to upload files." => "Du har ikke tilladelser til at uploade filer.", + "You don't have permissions to browse server." => "Du har ikke tilladelser til at se filer.", + "Cannot move uploaded file to target folder." => "Kan ikke flytte fil til destinations mappe.", + "Unknown error." => "Ukendt fejl.", + "The uploaded file exceeds {size} bytes." => "Den uploadede fil overskrider {size} bytes.", + "The uploaded file was only partially uploaded." => "Den uploadede fil blev kun delvist uploadet.", + "No file was uploaded." => "Ingen fil blev uploadet.", + "Missing a temporary folder." => "Mangler en midlertidig mappe.", + "Failed to write file." => "Kunne ikke skrive fil.", + "Denied file extension." => "Nægtet filtypenavn.", + "Unknown image format/encoding." => "Ukendt billedformat / kodning.", + "The image is too big and/or cannot be resized." => "Billedet er for stort og / eller kan ikke ændres.", + "Cannot create {dir} folder." => "Kan ikke lave mappen {dir}.", + "Cannot rename the folder." => "Kan ikke omdøbe mappen.", + "Cannot write to upload folder." => "Kan ikke skrive til upload mappen.", + "Cannot read .htaccess" => "Ikke kan læse .htaccess", + "Incorrect .htaccess file. Cannot rewrite it!" => "Forkert .htaccess fil. Kan ikke omskrive den!", + "Cannot read upload folder." => "Kan ikke læse upload mappen.", + "Cannot access or create thumbnails folder." => "Kan ikke få adgang til eller oprette miniature mappe.", + "Cannot access or write to upload folder." => "Kan ikke få adgang til eller skrive til upload mappe.", + "Please enter new folder name." => "Indtast venligst nyt mappenavn.", + "Unallowable characters in folder name." => "Ugyldige tegn i mappens navn.", + "Folder name shouldn't begins with '.'" => "Mappenavne bør ikke begynde med '.'", + "Please enter new file name." => "Indtast venligst nyt filnavn.", + "Unallowable characters in file name." => "Ugyldige tegn i filens navn", + "File name shouldn't begins with '.'" => "Filnavn bør ikke begynde med '.'", + "Are you sure you want to delete this file?" => "Er du sikker på du vil slette denne fil?", + "Are you sure you want to delete this folder and all its content?" => "Er du sikker på du vil slette denne mappe og al dens indhold?", + "Non-existing directory type." => "Ikke-eksisterende mappe type.", + "Undefined MIME types." => "Udefinerede MIME typer.", + "Fileinfo PECL extension is missing." => "Filinfo PECL udvidelse mangler.", + "Opening fileinfo database failed." => "Åbning af filinfo database mislykkedes.", + "You can't upload such files." => "Du kan ikke uploade sådanne filer.", + "The file '{file}' does not exist." => "Filen '{file}' eksisterer ikke.", + "Cannot read '{file}'." => "Kan ikke læse '{file}'.", + "Cannot copy '{file}'." => "Kan ikke kopiere '{file}'.", + "Cannot move '{file}'." => "Kan ikke flytte '{file}'.", + "Cannot delete '{file}'." => "Kan ikke slette '{file}'.", + "Cannot delete the folder." => "Kan ikke slette mappen.", + "Click to remove from the Clipboard" => "Klik for at fjerne fra udklipsholderen.", + "This file is already added to the Clipboard." => "Denne fil er allerede føjet til udklipsholderen.", + "The files in the Clipboard are not readable." => "Filerne i udklipsholderen ikke kan læses.", + "{count} files in the Clipboard are not readable. Do you want to copy the rest?" => "{count} filer i udklipsholderen ikke kan læses. Ønsker du at kopiere resten?", + "The files in the Clipboard are not movable." => "Filerne i udklipsholderen kan ikke flyttes.", + "{count} files in the Clipboard are not movable. Do you want to move the rest?" => "{count} filer i udklipsholderen er ikke flytbare. Ønsker du at flytte resten?", + "The files in the Clipboard are not removable." => "Filerne i udklipsholderen kan ikke fjernes.", + "{count} files in the Clipboard are not removable. Do you want to delete the rest?" => "{count} filer i udklipsholderen kan ikke fjernes. Ønsker du at slette resten?", + "The selected files are not removable." => "De valgte filer er ikke flytbare.", + "{count} selected files are not removable. Do you want to delete the rest?" => "{count} valgte filer kan ikke fjernes. Ønsker du at slette resten?", + "Are you sure you want to delete all selected files?" => "Er du sikker på du vil slette alle markerede filer?", + "Failed to delete {count} files/folders." => "Kunne ikke slette {count} filer/mapper.", + "A file or folder with that name already exists." => "En fil eller mappe med det navn findes allerede.", + "Copy files here" => "Kopier filer her.", + "Move files here" => "Flyt filer her.", + "Delete files" => "Slet filer.", + "Clear the Clipboard" => "Tøm udklipsholderen", + "Are you sure you want to delete all files in the Clipboard?" => "Tøm udklipsholderen?", + "Copy {count} files" => "Kopier {count} filer", + "Move {count} files" => "Flyt {count} filer", + "Add to Clipboard" => "Tilføj til udklipsholderen", + "Inexistant or inaccessible folder." => "Manglende eller utilgængelig mappe.", + "New folder name:" => "Nyt mappenavn:", + "New file name:" => "Nyt filnavn:", + "Upload" => "Upload", + "Refresh" => "Genopfrisk", + "Settings" => "Indstillinger", + "Maximize" => "Maksimer", + "About" => "Om", + "files" => "filer", + "selected files" => "Valgte filer", + "View:" => "Åben:", + "Show:" => "Vis:", + "Order by:" => "Sorter efter:", + "Thumbnails" => "Miniaturer", + "List" => "Liste", + "Name" => "Navn", + "Type" => "Type", + "Size" => "Størrelse", + "Date" => "Dato", + "Descending" => "Aftagende", + "Uploading file..." => "Uploader fil...", + "Loading image..." => "Indlæser billede...", + "Loading folders..." => "Indlæser mapper...", + "Loading files..." => "Indlæser filer...", + "New Subfolder..." => "Ny undermappe...", + "Rename..." => "Omdøb...", + "Delete" => "Slet", + "OK" => "Ok", + "Cancel" => "Fortryd", + "Select" => "Vælg", + "Select Thumbnail" => "Vælg miniature", + "Select Thumbnails" => "Vælg miniaturer", + "View" => "Åben", + "Download" => "Download", + "Download files" => "Download filer", + "Clipboard" => "Udklipsholder", + "Checking for new version..." => "Søger efter ny version...", + "Unable to connect!" => "Kan ikke forbinde!", + "Download version {version} now!" => "Hent version {version} nu!", + "KCFinder is up to date!" => "KCFinder er opdateret!", + "Licenses:" => "Licenser:", + "Attention" => "Vigtigt", + "Question" => "Spørgsmål", + "Yes" => "Ja", + "No" => "Nej", + "You cannot rename the extension of files!" => "Du kan ikke ændre typen på filer!", + "Uploading file {number} of {count}... {progress}" => "Uploader fil {number} af {count} ... {progress}", + "Failed to upload {filename}!" => "Kunne ikke uploade {filename}!", +); diff --git a/lib/kcfinder/lang/de.php b/lib/kcfinder/lang/de.php new file mode 100644 index 0000000..9027bec --- /dev/null +++ b/lib/kcfinder/lang/de.php @@ -0,0 +1,132 @@ + + */ + +$lang = array( + + '_lang' => "German", + '_native' => "Deutsch", + '_locale' => "de_DE.UTF-8", // UNIX localization code + '_charset' => "utf-8", // Browser charset + + // Date time formats. See http://www.php.net/manual/en/function.strftime.php + '_dateTimeFull' => "%A, %e.%B.%Y %k:%M", + '_dateTimeMid' => "%a %e %b %Y %k:%M", + '_dateTimeSmall' => "%d.%m.%Y %k:%M", + + "You don't have permissions to upload files." => "Du hast keine Berechtigung Dateien hoch zu laden.", + "You don't have permissions to browse server." => "Fehlende Berechtigung.", + "Cannot move uploaded file to target folder." => "Kann hochgeladene Datei nicht in den Zielordner verschieben.", + "Unknown error." => "Unbekannter Fehler.", + "The uploaded file exceeds {size} bytes." => "Die hochgeladene Datei überschreitet die erlaubte Dateigröße von {size} bytes.", + "The uploaded file was only partially uploaded." => "Die Datei wurde nur teilweise hochgeladen.", + "No file was uploaded." => "Keine Datei hochgeladen.", + "Missing a temporary folder." => "Temporärer Ordner fehlt.", + "Failed to write file." => "Fehler beim schreiben der Datei.", + "Denied file extension." => "Die Dateiendung ist nicht erlaubt.", + "Unknown image format/encoding." => "Unbekanntes Bildformat/encoding.", + "The image is too big and/or cannot be resized." => "Das Bild ist zu groß und/oder kann nicht verkleinert werden.", + "Cannot create {dir} folder." => "Ordner {dir} kann nicht angelegt werden.", + "Cannot rename the folder." => "Der Ordner kann nicht umbenannt werden.", + "Cannot write to upload folder." => "Kann nicht in den upload Ordner schreiben.", + "Cannot read .htaccess" => "Kann .htaccess Datei nicht lesen", + "Incorrect .htaccess file. Cannot rewrite it!" => "Falsche .htaccess Datei. Die Datei kann nicht geschrieben werden", + "Cannot read upload folder." => "Ziel Ordner kann nicht gelesen werden.", + "Cannot access or create thumbnails folder." => "Kann thumbnails Ordner nicht erstellen oder darauf zugreifen.", + "Cannot access or write to upload folder." => "Kann nicht auf den upload Ordner zugreifen oder darin schreiben.", + "Please enter new folder name." => "Bitte einen neuen Ordnernamen angeben.", + "Unallowable characters in folder name." => "Der Ordnername enthält unerlaubte Zeichen.", + "Folder name shouldn't begins with '.'" => "Ordnernamen sollten nicht mit '.' beginnen.", + "Please enter new file name." => "Bitte gib einen neuen Dateinamen an.", + "Unallowable characters in file name." => "Der Dateiname enthält unerlaubte Zeichen", + "File name shouldn't begins with '.'" => "Dateinamen sollten nicht mit '.' beginnen.", + "Are you sure you want to delete this file?" => "Willst Du die Datei wirklich löschen?", + "Are you sure you want to delete this folder and all its content?" => "Willst Du wirklich diesen Ordner und seinen gesamten Inhalt löschen?", + "Non-existing directory type." => "Der Ordner Typ existiert nicht.", + "Undefined MIME types." => "Unbekannte MIME Typen.", + "Fileinfo PECL extension is missing." => "PECL extension für Dateiinformationen fehlt", + "Opening fileinfo database failed." => "√ñffnen der Dateiinfo Datenbank fehlgeschlagen.", + "You can't upload such files." => "Du kannst solche Dateien nicht hochladen.", + "The file '{file}' does not exist." => "Die Datei '{file}' existiert nicht.", + "Cannot read '{file}'." => "Kann Datei '{file}' nicht lesen.", + "Cannot copy '{file}'." => "Kann Datei '{file}' nicht kopieren.", + "Cannot move '{file}'." => "Kann Datei '{file}' nicht verschieben.", + "Cannot delete '{file}'." => "Kann Datei '{file}' nicht löschen.", + "Cannot delete the folder." => "Der Ordner kann nicht gelöscht werden.", + "Click to remove from the Clipboard" => "Zum entfernen aus der Zwischenablage, hier klicken.", + "This file is already added to the Clipboard." => "Diese Datei wurde bereits der Zwischenablage hinzugefügt.", + "The files in the Clipboard are not readable." => "Die Dateien in der Zwischenablage können nicht gelesen werden.", + "{count} files in the Clipboard are not readable. Do you want to copy the rest?" => "{count} Dateien in der Zwischenablage sind nicht lesbar. Möchtest Du die Übrigen trotzdem kopieren?", + "The files in the Clipboard are not movable." => "Die Dateien in der Zwischenablage können nicht verschoben werden.", + "{count} files in the Clipboard are not movable. Do you want to move the rest?" => "{count} Dateien in der Zwischenablage sind nicht verschiebbar. Möchtest Du die Übrigen trotzdem verschieben?", + "The files in the Clipboard are not removable." => "Die Dateien in der Zwischenablage können nicht gelöscht werden.", + "{count} files in the Clipboard are not removable. Do you want to delete the rest?" => "{count} Dateien in der Zwischenablage können nicht gelöscht werden. Möchtest Du die Übrigen trotzdem löschen?", + "The selected files are not removable." => "Die ausgewählten Dateien können nicht gelöscht werden.", + "{count} selected files are not removable. Do you want to delete the rest?" => "{count} der ausgewählten Dateien können nicht gelöscht werden. Möchtest Du die Übrigen trotzdem löschen?", + "Are you sure you want to delete all selected files?" => "Möchtest Du wirklich alle ausgewählten Dateien löschen?", + "Failed to delete {count} files/folders." => "Konnte {count} Dateien/Ordner nicht löschen.", + "A file or folder with that name already exists." => "Eine Datei oder ein Ordner mit dem Namen existiert bereits.", + "Copy files here" => "Kopiere Dateien hier hin.", + "Move files here" => "Verschiebe Dateien hier hin.", + "Delete files" => "Lösche Dateien.", + "Clear the Clipboard" => "Zwischenablage leeren", + "Are you sure you want to delete all files in the Clipboard?" => "Willst Du wirklich alle Dateien in der Zwischenablage löschen?", + "Copy {count} files" => "Kopiere {count} Dateien", + "Move {count} files" => "Verschiebe {count} Dateien", + "Add to Clipboard" => "Der Zwischenablage hinzufügen", + "Inexistant or inaccessible folder." => "Ordnertyp existiert nicht.", + "New folder name:" => "Neuer Ordnername:", + "New file name:" => "Neuer Dateiname:", + "Upload" => "Hochladen", + "Refresh" => "Aktualisieren", + "Settings" => "Einstellungen", + "Maximize" => "Maximieren", + "About" => "Über", + "files" => "Dateien", + "selected files" => "ausgewählte Dateien", + "View:" => "Ansicht:", + "Show:" => "Zeige:", + "Order by:" => "Ordnen nach:", + "Thumbnails" => "Miniaturansicht", + "List" => "Liste", + "Name" => "Name", + "Type" => "Typ", + "Size" => "Größe", + "Date" => "Datum", + "Descending" => "Absteigend", + "Uploading file..." => "Lade Datei hoch...", + "Loading image..." => "Lade Bild...", + "Loading folders..." => "Lade Ordner...", + "Loading files..." => "Lade Dateien...", + "New Subfolder..." => "Neuer Unterordner...", + "Rename..." => "Umbenennen...", + "Delete" => "Löschen", + "OK" => "OK", + "Cancel" => "Abbruch", + "Select" => "Auswählen", + "Select Thumbnail" => "Wähle Miniaturansicht", + "Select Thumbnails" => "Wähle Miniaturansicht", + "View" => "Ansicht", + "Download" => "Download", + "Download files" => "Dateien herunterladen", + "Clipboard" => "Zwischenablage", + "Checking for new version..." => "Nach neuer Version suchen", + "Unable to connect!" => "Kann keine Verbindung herstellen!", + "Download version {version} now!" => "Version {version} herunterladen!", + "KCFinder is up to date!" => "KCFinder ist aktuell!", + "Licenses:" => "Lizenz", + "Attention" => "Achtung", + "Question" => "Frage", + "Yes" => "Ja", + "No" => "Nein", + "You cannot rename the extension of files!" => "Die Umbenennung von Datei-Erweiterungen ist nicht möglich!", + "Uploading file {number} of {count}... {progress}" => "Lade Datei {number} von {count} hoch ... {progress}", + "Failed to upload {filename}!" => "Hochladen von {filename} fehlgeschlagen!", + "Close" => "Schließen", + "Previous" => "Vorherige", + "Next" => "Nächste", + "Confirmation" => "Bestätigung", + "Warning" => "Warnung" +); diff --git a/lib/kcfinder/lang/el.php b/lib/kcfinder/lang/el.php new file mode 100644 index 0000000..c550b8a --- /dev/null +++ b/lib/kcfinder/lang/el.php @@ -0,0 +1,132 @@ + "Greek", + '_native' => "Ελληνικά", + '_locale' => "el_GR.UTF-8", // UNIX localization code + '_charset' => "utf-8", // Browser charset + + // Date time formats. See http://www.php.net/manual/en/function.strftime.php + '_dateTimeFull' => "%A, %e %B, %Y %H:%M", + '_dateTimeMid' => "%a %e %b %Y %H:%M", + '_dateTimeSmall' => "%d.%m.%Y %H:%M", + + "You don't have permissions to upload files." => "Δεν έχετε δικαίωμα να ανεβάσετε αρχεία.", + "You don't have permissions to browse server." => "Δεν έχετε δικαίωμα να δείτε τα αρχεία στο διακομιστή.", + "Cannot move uploaded file to target folder." => "Το αρχείο δε μπορεί να μεταφερθεί στο φάκελο προορισμού.", + "Unknown error." => "Άγνωστο σφάλμα.", + "The uploaded file exceeds {size} bytes." => "Το αρχείο υπερβαίνει το μέγεθος των {size} bytes.", + "The uploaded file was only partially uploaded." => "Ένα μόνο μέρος του αρχείου ανέβηκε.", + "No file was uploaded." => "Κανένα αρχείο δεν ανέβηκε.", + "Missing a temporary folder." => "Λείπει ο φάκελος των προσωρινών αρχείων.", + "Failed to write file." => "Σφάλμα στη τροποποίηση του αρχείου.", + "Denied file extension." => "Δεν επιτρέπονται αυτού του είδους αρχεία.", + "Unknown image format/encoding." => "Αγνωστη κωδικοποίηση εικόνας.", + "The image is too big and/or cannot be resized." => "Η εικόνα είναι πάρα πολύ μεγάλη και/η δεν μπορεί να αλλάξει μέγεθος.", + "Cannot create {dir} folder." => "Αδύνατον να δημιουργηθεί ο φάκελος {dir}.", + "Cannot rename the folder." => "Αδύνατη η μετονομασία του φακέλου.", + "Cannot write to upload folder." => "Αδύνατη η εγγραφή στο φάκελο προορισμού.", + "Cannot read .htaccess" => "Αδύνατη η ανάγνωση του .htaccess", + "Incorrect .htaccess file. Cannot rewrite it!" => "Εσφαλμένο αρχείο .htaccess. Αδύνατη η τροποποίησή του!", + "Cannot read upload folder." => "Μη αναγνώσιμος φάκελος προορισμού.", + "Cannot access or create thumbnails folder." => "Αδύνατη η πρόσβαση και ανάγνωση του φακέλου με τις μικρογραφίες εικόνων.", + "Cannot access or write to upload folder." => "Αδύνατη η πρόσβαση και τροποποίηση του φακέλου προορισμού.", + "Please enter new folder name." => "Παρακαλούμε εισάγετε ένα νέο όνομα φακέλου. ", + "Unallowable characters in folder name." => "Μη επιτρεπτοί χαρακτήρες στο όνομα φακέλου.", + "Folder name shouldn't begins with '.'" => "Το όνομα του φακέλου δε πρέπει να αρχίζει με '.'", + "Please enter new file name." => "Παρακαλούμε εισάγετε ένα νέο όνομα αρχείου.", + "Unallowable characters in file name." => "Μη επιτρεπτοί χαρακτήρες στο όνομα αρχείου.", + "File name shouldn't begins with '.'" => "Το όνομα του αρχείου δεν πρέπει να αρχίζει με '.'", + "Are you sure you want to delete this file?" => "Σίγουρα θέλετε να διαγράψετε αυτό το αρχείο;", + "Are you sure you want to delete this folder and all its content?" => "Σίγουρα θέλετε να διαγράψετε αυτό το φάκελο μαζί με όλα τα περιεχόμενα;", + "Non-existing directory type." => "Ανύπαρκτος τύπος φακέλου.", + "Undefined MIME types." => "Απροσδιόριστοι τύποι MIME.", + "Fileinfo PECL extension is missing." => "Η επέκταση πληροφορίας αρχείου PECL δεν υπάρχει.", + "Opening fileinfo database failed." => "Η πρόσβαση στις πληροφορίες του αρχείου απέτυχε.", + "You can't upload such files." => "Δε μπορείτε να ανεβάσετε τέτοια αρχεία.", + "The file '{file}' does not exist." => "Το αρχείο '{file}' δεν υπάρχει.", + "Cannot read '{file}'." => "Αρχείο '{file}' μη αναγνώσιμο.", + "Cannot copy '{file}'." => "Αδύνατη η αντιγραφή του '{file}'.", + "Cannot move '{file}'." => "Αδύνατη η μετακίνηση του '{file}'.", + "Cannot delete '{file}'." => "Αδύνατη η διαγραφή του '{file}'.", + "Cannot delete the folder." => "Αδύνατη η διαγραφή του φακέλου.", + "Click to remove from the Clipboard" => "Πατήστε για διαγραφή από το Πρόχειρο.", + "This file is already added to the Clipboard." => "Αυτό το αρχείο βρίσκεται ήδη στο Πρόχειρο.", + "The files in the Clipboard are not readable." => "Τα αρχεία στο Πρόχειρο είναι μη αναγνώσιμα.", + "{count} files in the Clipboard are not readable. Do you want to copy the rest?" => "{count} αρχεία στο Πρόχειρο είναι μη αναγνώσιμα. Θέλετε να αντιγράψετε τα υπόλοιπα;", + "The files in the Clipboard are not movable." => "Τα αρχεία στο Πρόχειρο είναι αδύνατο να μετακινηθούν.", + "{count} files in the Clipboard are not movable. Do you want to move the rest?" => "{count} αρχεία στο Πρόχειρο δεν είναι δυνατό να μετακινηθούν. Θέλετε να μετακινήσετε τα υπόλοιπα;", + "The files in the Clipboard are not removable." => "Τα αρχεία στο Πρόχειρο είναι αδύνατο να αφαιρεθούν.", + "{count} files in the Clipboard are not removable. Do you want to delete the rest?" => "{count} αρχεία στο Πρόχειρο δεν είναι δυνατό να αφαιρεθούν. Θέλετε να αφαιρέσετε τα υπόλοιπα;", + "The selected files are not removable." => "Τα επιλεγμένα αρχεία δε μπορούν να αφαιρεθούν.", + "{count} selected files are not removable. Do you want to delete the rest?" => "{count} επιλεγμένα αρχεία δεν είναι δυνατό να αφαιρεθούν. Θέλετε να διαγράψετε τα υπόλοιπα;", + "Are you sure you want to delete all selected files?" => "Σίγουρα θέλετε να διαγράψετε όλα τα επιλεγμένα αρχεία;", + "Failed to delete {count} files/folders." => "Η διαγραφή {count} αρχείων/φακέλων απέτυχε.", + "A file or folder with that name already exists." => "Ένα αρχείο ή φάκελος με αυτό το όνομα υπάρχει ήδη.", + "Copy files here" => "Αντιγράψτε αρχεία εδώ.", + "Move files here" => "Μετακινήστε αρχεία εδώ.", + "Delete files" => "Διαγραφή αρχείων", + "Clear the Clipboard" => "Καθαρισμός Clipboard", + "Are you sure you want to delete all files in the Clipboard?" => "Σίγουρα θέλετε να διαγράψετε όλα τα αρχεία από το Πρόχειρο;", + "Copy {count} files" => "Αντιγραφή {count} αρχείων.", + "Move {count} files" => "Μετακίνηση {count} αρχείων.", + "Add to Clipboard" => "Προσθήκη στο Πρόχειρο", + "Inexistant or inaccessible folder." => "Ανύπαρκτος η μη προσβάσιμος φάκελος.", + "New folder name:" => "Νέο όνομα φακέλου:", + "New file name:" => "Νέο όνομα αρχείου:", + "Upload" => "Ανέβασμα", + "Refresh" => "Ανανέωση", + "Settings" => "Ρυθμίσεις", + "Maximize" => "Μεγιστοποίηση", + "About" => "Σχετικά", + "files" => "αρχεία", + "selected files" => "επιλεγμένα αρχεία", + "View:" => "Προβολή:", + "Show:" => "Εμφάνιση:", + "Order by:" => "Ταξινόμηση κατά:", + "Thumbnails" => "Μικρογραφίες", + "List" => "Λίστα", + "Name" => "Όνομα", + "Type" => "Τύπος", + "Size" => "Μέγεθος", + "Date" => "Ημερομηνία", + "Descending" => "Φθίνουσα", + "Uploading file..." => "Το αρχείο ανεβαίνει...", + "Loading image..." => "Η εικόνα φορτώνει...", + "Loading folders..." => "Οι φάκελοι φορτώνουν...", + "Loading files..." => "Τα αρχεία φορτώνουν...", + "New Subfolder..." => "Νέος υποφάκελος...", + "Rename..." => "Μετονομασία...", + "Delete" => "Διαγραφή", + "OK" => "OK", + "Cancel" => "Ακύρωση", + "Select" => "Επιλογή", + "Select Thumbnail" => "Επιλογή μικρογραφίας", + "Select Thumbnails" => "Επιλέξτε μικρογραφίες", + "View" => "Προβολή", + "Download" => "Κατέβασμα", + "Download files" => "Κατέβασμα αρχείων", + "Clipboard" => "Πρόχειρο", + "Checking for new version..." => "Ελεγχος για νέα έκδοση...", + "Unable to connect!" => "Αδύνατη η σύνδεση!", + "Download version {version} now!" => "Κατεβάστε την έκδοση {version} τώρα!", + "KCFinder is up to date!" => "Το KCFinder είναι ενημερωμένο με τη πιο πρόσφατη έκδοση!", + "Licenses:" => "Άδειες:", + "Attention" => "Προσοχή", + "Question" => "Ερώτηση", + "Yes" => "Ναι", + "No" => "Όχι", + "You cannot rename the extension of files!" => "Δεν έχετε δικαίωμα να αλλάζετε την κατάληξη των αρχείων!", + "Uploading file {number} of {count}... {progress}" => "Ανέβασμα αρχείου {number} από {count}... {progress}", + "Failed to upload {filename}!" => "Αποτυχία στο ανέβασμα του {filename}!", + "Close" => "Κλείσιμο", + "Previous" => "Προηγούμενη", + "Next" => "Επόμενη", + "Confirmation" => "Επιβεβαίωση", + "Warning" => "Προειδοποίηση", +); diff --git a/lib/kcfinder/lang/en.php b/lib/kcfinder/lang/en.php new file mode 100644 index 0000000..c66f2d3 --- /dev/null +++ b/lib/kcfinder/lang/en.php @@ -0,0 +1,25 @@ + + * @copyright 2010-2014 KCFinder Project + * @license http://opensource.org/licenses/GPL-3.0 GPLv3 + * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3 + * @link http://kcfinder.sunhater.com + */ + +$lang = array( + '_lang' => "English", + '_native' => "English", + '_locale' => "en_US.UTF-8", + '_charset' => "utf-8", + + // Date time formats. See http://www.php.net/manual/en/function.strftime.php + '_dateTimeFull' => "%A, %B %e, %Y %I:%M %p", + '_dateTimeMid' => "%a %b %e %Y %I:%M %p", + '_dateTimeSmall' => "%m/%d/%Y %I:%M %p", +); diff --git a/lib/kcfinder/lang/es.php b/lib/kcfinder/lang/es.php new file mode 100644 index 0000000..5ff6d06 --- /dev/null +++ b/lib/kcfinder/lang/es.php @@ -0,0 +1,127 @@ + "Spanish", + '_native' => "Español", + '_locale' => "es_ES.UTF-8", // UNIX localization code + '_charset' => "utf-8", // Browser charset + + // Date time formats. See http://www.php.net/manual/en/function.strftime.php + '_dateTimeFull' => "%A, %e %B, %Y %H:%M", + '_dateTimeMid' => "%a %e %b %Y %H:%M", + '_dateTimeSmall' => "%d.%m.%Y %H:%M", + + "You don't have permissions to upload files." => "No tiene permiso para subir archivos.", + "You don't have permissions to browse server." => "No tiene permiso para visualizar archivos.", + "Cannot move uploaded file to target folder." => "No puede mover archivos al directorio de destino.", + "Unknown error." => "Error desconocido.", + "The uploaded file exceeds {size} bytes." => "El archivo excede el tamaño permitido ({size} bytes).", + "The uploaded file was only partially uploaded." => "El archivo solo fué parcialmente cargado.", + "No file was uploaded." => "El archivo no fué cargado.", + "Missing a temporary folder." => "No se puede encontrar el directorio temporal.", + "Failed to write file." => "No se pudo crear el archivo.", + "Denied file extension." => "Extensión de archivo denegada.", + "Unknown image format/encoding." => "Formato / codificación de imagen desconocido.", + "The image is too big and/or cannot be resized." => "La imagen es muy grande o no se puede redimensionar.", + "Cannot create {dir} folder." => "No se puede crear la carpeta {dir}.", + "Cannot rename the folder." => "No se puede renombrar la carpeta.", + "Cannot write to upload folder." => "No se puede escribir en directorio de carga de archivos.", + "Cannot read .htaccess" => "No se puede leer el archivo .htaccess.", + "Incorrect .htaccess file. Cannot rewrite it!" => "Archivo .htaccess incorrecto. ¡No puede sobreescribirlo!", + "Cannot read upload folder." => "No se puede leer la carpeta de carga de archivos.", + "Cannot access or create thumbnails folder." => "No se puede leer o crear carpeta de miniaturas.", + "Cannot access or write to upload folder." => "No se puede leer o escribir en la carpeta de carga de archivos.", + "Please enter new folder name." => "Por favor introduzca el nombre de la nueva carpeta.", + "Unallowable characters in folder name." => "Caracteres inválidos en el nombre de carpeta.", + "Folder name shouldn't begins with '.'" => "El nombre de carpeta no puede comenzar con punto '.'", + "Please enter new file name." => "Por favor introduzca el nuevo nombre del archivo.", + "Unallowable characters in file name." => "Carácteres inválidos en el nombre de archivo.", + "File name shouldn't begins with '.'" => "El nombre de archivo no puede comenzar con punto '.'", + "Are you sure you want to delete this file?" => "Esta seguro de que desea borrar este archivo?", + "Are you sure you want to delete this folder and all its content?" => "Esta seguro de que desea borrar esta carpeta y todo su contenido?", + "Non-existing directory type." => "El tipo de directorio no existe.", + "Undefined MIME types." => "Tipo MIME no definido.", + "Fileinfo PECL extension is missing." => "Archivo PECL con estructura errónea.", + "Opening fileinfo database failed." => "Error abriendo el archivo de información de la base de datos.", + "You can't upload such files." => "No puede cargar tantos archivos.", + "The file '{file}' does not exist." => "El archivo '{file}' no existe.", + "Cannot read '{file}'." => "No se puede leer '{file}'.", + "Cannot copy '{file}'." => "No se puede copiar '{file}'.", + "Cannot move '{file}'." => "No se puede mover '{file}'.", + "Cannot delete '{file}'." => "No se puede borrar '{file}'.", + "Cannot delete the folder." => "No se puede borrrar la carpeta.", + "Click to remove from the Clipboard" => "Haga Click para borrar del portapapeles", + "This file is already added to the Clipboard." => "Este archivo ya fué agregado al portapapeles.", + "The files in the Clipboard are not readable." => "Los archivos en el portapapeles no son legibles.", + "{count} files in the Clipboard are not readable. Do you want to copy the rest?" => "{count} archivos en el portapapeles no son legibles. Desea copiar el resto?", + "The files in the Clipboard are not movable." => "Los archivos en el portapapeles no se pueden mover.", + "{count} files in the Clipboard are not movable. Do you want to move the rest?" => "{count} archivos en el portapapeles no se pueden mover. Desea mover el resto?", + "The files in the Clipboard are not removable." => "Los archivos en el portapapeles no se pueden remover.", + "{count} files in the Clipboard are not removable. Do you want to delete the rest?" => "{count} archivos en el portapapeles no se pueden remover. Desea borrar el resto?", + "The selected files are not removable." => "Los archivos seleccionados no son removibles.", + "{count} selected files are not removable. Do you want to delete the rest?" => "{count} archivos seleccionados no son removibles. Desea borrar el resto?", + "Are you sure you want to delete all selected files?" => "Esta seguro de que desea borrar todos los archivos seleccionados?", + "Failed to delete {count} files/folders." => "Falló al borrar {count} archivos/carpetas.", + "A file or folder with that name already exists." => "Existe una carpeta o archivo con el mismo nombre.", + "Copy files here" => "Copiar archivos aquí", + "Move files here" => "Mover archivos aquí", + "Delete files" => "Borrar archivos", + "Clear the Clipboard" => "Limpiar el portapapeles", + "Are you sure you want to delete all files in the Clipboard?" => "Esta seguro de que desea borrar todos los archivos del portapapeles?", + "Copy {count} files" => "Copiar {count} archivos", + "Move {count} files" => "Mover {count} archivos ", + "Add to Clipboard" => "Agregar al portapapeles", + "Inexistant or inaccessible folder." => "Carpeta inexistente o inaccesible.", + "New folder name:" => "Nuevo nombre de carpeta:", + "New file name:" => "Nuevo nombre de archivo:", + "Upload" => "Cargar", + "Refresh" => "Refrescar", + "Settings" => "Preferencias", + "Maximize" => "Maximizar", + "About" => "Acerca de", + "files" => "Archivos", + "selected files" => "Archivos seleccionados", + "View:" => "Ver:", + "Show:" => "Mostrar:", + "Order by:" => "Ordenar por:", + "Thumbnails" => "Miniaturas", + "List" => "Lista", + "Name" => "Nombre", + "Type" => "Tipo", + "Size" => "Tamaño", + "Date" => "Fecha", + "Descending" => "Decendente", + "Uploading file..." => "Cargando archivo...", + "Loading image..." => "Cargando imagen...", + "Loading folders..." => "Cargando carpetas...", + "Loading files..." => "Cargando archivos...", + "New Subfolder..." => "Nuevo subdirectorio...", + "Rename..." => "Renombrar...", + "Delete" => "Eliminar", + "OK" => "OK", + "Cancel" => "Cancelar", + "Select" => "Seleccionar", + "Select Thumbnail" => "Seleccionar miniatura", + "Select Thumbnails" => "Seleccionar miniaturas", + "View" => "Ver", + "Download" => "Descargar", + "Download files" => "Descargar archivos", + "Clipboard" => "Portapapeles", + "Checking for new version..." => "Verificando nuevas versiones...", + "Unable to connect!" => "¡No se pudo realizar la conexión!", + "Download version {version} now!" => "¡Descarga la versión {version} ahora!", + "KCFinder is up to date!" => "¡KCFinder está actualizado!", + "Licenses:" => "Licencias:", + "Attention" => "Atención", + "Question" => "Pregunta", + "Yes" => "Si", + "No" => "No", + "You cannot rename the extension of files!" => "¡Usted no puede renombrar la extensión de los archivos!", + "Uploading file {number} of {count}... {progress}" => "Cargando archivo {number} de {count}... {progress}", + "Failed to upload {filename}!" => "¡No se pudo cargar el archivo {filename}!", +); diff --git a/lib/kcfinder/lang/et.php b/lib/kcfinder/lang/et.php new file mode 100644 index 0000000..ba7e6e1 --- /dev/null +++ b/lib/kcfinder/lang/et.php @@ -0,0 +1,127 @@ + "Estonian", + '_native' => "Eesti", + '_locale' => "et_EE.UTF-8", // UNIX localization code + '_charset' => "utf-8", // Browser charset + + // Date time formats. See http://www.php.net/manual/en/function.strftime.php + '_dateTimeFull' => "%e. %B %Y %H:%M", + '_dateTimeMid' => "%e. %b %Y %H:%M", + '_dateTimeSmall' => "%d.%m.%Y %H:%M", + + "You don't have permissions to upload files." => "Sul pole failide üleslaadimiseks vajalikke õiguseid.", + "You don't have permissions to browse server." => "Sul ei ole serveri sirvimiseks vajalikke õiguseid.", + "Cannot move uploaded file to target folder." => "Üleslaetud faili liigutamine ebaõnnestus.", + "Unknown error." => "Tundmatu viga.", + "The uploaded file exceeds {size} bytes." => "Üleslaetud fail on suurem kui lubatud {size} baiti", + "The uploaded file was only partially uploaded." => "Fail laeti üles ainult osaliselt.", + "No file was uploaded." => "Faili ei õnnestunud üles laadida.", + "Missing a temporary folder." => "Failide ajutine kataloog on puudu.", + "Failed to write file." => "Faili loomine ebaõnnestus.", + "Denied file extension." => "Faili laiend ei ole lubatud.", + "Unknown image format/encoding." => "Tundmatu pildi formaat/kodeering.", + "The image is too big and/or cannot be resized." => "Pilt on liiga suur ja/või selle suurust ei saa muuta.", + "Cannot create {dir} folder." => "Kataloogi {dir} loomine ebaõnnestus.", + "Cannot rename the folder." => "Kataloogi ei saa ümber nimetada.", + "Cannot write to upload folder." => "Üleslaadimise kataloogi ei saa kirjutada.", + "Cannot read .htaccess" => ".htaccess faili ei saa lugeda.", + "Incorrect .htaccess file. Cannot rewrite it!" => "Vigane .htacess fail. Ümberkirjutamine ebaõnnestus.", + "Cannot read upload folder." => "Üleslaadimise kataloogi ei saa lugeda.", + "Cannot access or create thumbnails folder." => "Pisipiltide kataloogi ei saa lugeda või seda luua.", + "Cannot access or write to upload folder." => "Üleslaadimise kataloogi ei saa lugeda või seda luua.", + "Please enter new folder name." => "Sisesta uus kataloogi nimi.", + "Unallowable characters in folder name." => "Keelatud tähemärk kataloogi nimes.", + "Folder name shouldn't begins with '.'" => "Kataloogi nimi ei tohi alata punktiga.", + "Please enter new file name." => "Sisesta uus faili nimi.", + "Unallowable characters in file name." => "Keelatud tähemärgid faili nimes.", + "File name shouldn't begins with '.'" => "Failinimi ei tohi alata punktiga.", + "Are you sure you want to delete this file?" => "Oled sa kindel, et soovid selle faili kustutada?", + "Are you sure you want to delete this folder and all its content?" => "Oled sa kindel, et soovid selle kataloogi koos sisuga kustutada?", + "Non-existing directory type." => "Olematu kataloogi tüüp.", + "Undefined MIME types." => "Määramata MIME tüüp.", + "Fileinfo PECL extension is missing." => "Fileinfo PECL laiendus on puudu.", + "Opening fileinfo database failed." => "Failiinfo andmebaasi avamine ebaõnnestus.", + "You can't upload such files." => "Selliseid faile ei saa üles laadida.", + "The file '{file}' does not exist." => "Faili '{file}' ei ole olemas.", + "Cannot read '{file}'." => "Faili '{file}' ei õnnestunud lugeda.", + "Cannot copy '{file}'." => "Faili '{file}' ei õnnestunud kopeerida.", + "Cannot move '{file}'." => "Faili '{file}' ei õnnestunud liigutada.", + "Cannot delete '{file}'." => "Faili '{file}' ei õnnestunud kustutada.", + "Cannot delete the folder." => "Kataloogi ei saa kustutada.", + "Click to remove from the Clipboard" => "Kliki, et eemaldada lõikelaualt.", + "This file is already added to the Clipboard." => "Fail on juba lõikelauale lisatud.", + "The files in the Clipboard are not readable." => "Lõikelaual olevad failid ei ole loetavad.", + "{count} files in the Clipboard are not readable. Do you want to copy the rest?" => "{count} faili lõikelaual ei ole loetavad. Kas sa soovid ülejäänud kopeerida?", + "The files in the Clipboard are not movable." => "Lõikelaul olevad failid ei ole liigutatavad.", + "{count} files in the Clipboard are not movable. Do you want to move the rest?" => "{count} faili lõikelaual ei ole liigutatavad. Kas sa soovid ülejäänud liigutada?", + "The files in the Clipboard are not removable." => "Lõikelaul olevad failid ei ole kustutatavad.", + "{count} files in the Clipboard are not removable. Do you want to delete the rest?" => "{count} faili lõikelaual ei ole kustutatavad. Kas sa soovid ülejäänud kustutada?", + "The selected files are not removable." => "Valitud faile ei saa kustutada.", + "{count} selected files are not removable. Do you want to delete the rest?" => "{count} valitud faili ei saa kustutada. Kas sa soovid ülejäänud kustutada?", + "Are you sure you want to delete all selected files?" => "Oled sa kindel, et soovid kõik valitud failid kustutada?", + "Failed to delete {count} files/folders." => "{count} faili/kataloogi kustutamine ebaõnnestus.", + "A file or folder with that name already exists." => "Selle nimega fail/kataloog on juba olemas.", + "Copy files here" => "Kopeeri failid siia", + "Move files here" => "Liiguta failid siia", + "Delete files" => "Kustuta failid", + "Clear the Clipboard" => "Tühjenda lõikelaud", + "Are you sure you want to delete all files in the Clipboard?" => "Oled sa kindel, et soovid kustutada kõik lõikelaual olevad failid?", + "Copy {count} files" => "Kopeeri {count} faili", + "Move {count} files" => "Liiguta {count} faili", + "Add to Clipboard" => "Lisa lõikelauale", + "Inexistant or inaccessible folder." => "Olematu või ligipääsmatu kataloog.", + "New folder name:" => "Uus kataloogi nimi:", + "New file name:" => "Uus faili nimi:", + "Upload" => "Lae üles", + "Refresh" => "Värskenda", + "Settings" => "Seaded", + "Maximize" => "Täisekraan", + "About" => "Info", + "files" => "failid", + "selected files" => "valitud failid", + "View:" => "Vaade:", + "Show:" => "Näita:", + "Order by:" => "Sorteeri:", + "Thumbnails" => "Pisipildid", + "List" => "Nimekiri", + "Name" => "Nimi", + "Type" => "Tüüp", + "Size" => "Suurus", + "Date" => "Kuupäev", + "Descending" => "Kahanev", + "Uploading file..." => "Laen faili...", + "Loading image..." => "Laen pilti...", + "Loading folders..." => "Laen katalooge...", + "Loading files..." => "Laen faile...", + "New Subfolder..." => "Uus alamkataloog...", + "Rename..." => "Nimeta ümber...", + "Delete" => "Kustuta", + "OK" => "OK", + "Cancel" => "Loobu", + "Select" => "Vali", + "Select Thumbnail" => "Vali pisipilt", + "Select Thumbnails" => "Vali pisipildid", + "View" => "Vaata", + "Download" => "Lae alla", + "Download files" => "Lae failid alla", + "Clipboard" => "Lõikelaud", + "Checking for new version..." => "Kontrollin uut versiooni...", + "Unable to connect!" => "Ühendus ebaõnnestus!", + "Download version {version} now!" => "Lae versioon {version} alla!", + "KCFinder is up to date!" => "Uuendusi ei ole!", + "Licenses:" => "Litsentsid:", + "Attention" => "Tähelepanu", + "Question" => "Küsimus", + "Yes" => "Jah", + "No" => "Ei", + "You cannot rename the extension of files!" => "Failide laiendit ei saa muuta!", + "Uploading file {number} of {count}... {progress}" => "Laen üles faili {number} {count}-st... {progress}", + "Failed to upload {filename}!" => "{filename} üleslaadimine ebaõnnestus!", +); diff --git a/lib/kcfinder/lang/fa.php b/lib/kcfinder/lang/fa.php new file mode 100644 index 0000000..429749c --- /dev/null +++ b/lib/kcfinder/lang/fa.php @@ -0,0 +1,267 @@ + + * @copyright 2010 KCFinder Project + * @license http://opensource.org/licenses/GPL-3.0 GPLv3 + * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3 + * @link http://kcfinder.sunhater.com + */ + +$lang = array( + '_lang' => "Persian", + '_native' => "فارسى", + '_locale' => "fa_IR.UTF-8", + '_charset' => "utf-8", + + // Date time formats. See http://www.php.net/manual/en/function.strftime.php + '_dateTimeFull' => "%A, %B %e, %Y %H:%M", + '_dateTimeMid' => "%a %b %e %Y %H:%M", + '_dateTimeSmall' => "%Y/%m/%d %H:%M", + + "You don't have permissions to upload files." => + ".شما فاقد مجوز برای ارسال فایل ها هستید", + + "You don't have permissions to browse server." => + ".شما فاقد مجوز برای جستجو در سرور هستید", + + "Cannot move uploaded file to target folder." => + ".برنامه نمی تواند فایل بارگذاری شده را انتقال دهد به پوشه مورد نظر", + + "Unknown error." => + ".خطای نامشخص", + + "The uploaded file exceeds {size} bytes." => + ".بایت است {size} حجم فایل بارگذاری شده بیشتر از", + + "The uploaded file was only partially uploaded." => + ".فایل ناقص بارگذاری شد", + + "No file was uploaded." => + ".فایل ارسال نشد", + + "Missing a temporary folder." => + ".پوشه تمپ پیدا نشد", + + "Failed to write file." => + ".خطا در نوشتن فایل", + + "Denied file extension." => + ".پسوند فایل غیر مجاز است", + + "Unknown image format/encoding." => + ".عکس معتبر نیست format/encoding", + + "The image is too big and/or cannot be resized." => + ".عکس انتخابی یا بزرگ است یا تغییر اندازه داده نمی شود", + + "Cannot create {dir} folder." => + ".{dir}مشکل در ساخت پوشه", + + "Cannot write to upload folder." => + ".مشکل در نوشتن اطلاعات در پوشه بارگذاری", + + "Cannot read .htaccess" => + ".htaccess خطا در خواندن فایل", + + "Incorrect .htaccess file. Cannot rewrite it!" => + ".غیرقابل بازنویسی است .htaccess فایل", + + "Cannot read upload folder." => + ".مشکل در خواندن پوشه بارگذاری", + + "Cannot access or create thumbnails folder." => + ".مشکل در دسترسی یا ساخت پوشه تام", + + "Cannot access or write to upload folder." => + ".مشکل در دسترسی برای نوشتن اطلاعات در پوشه بارگذاری", + + "Please enter new folder name." => + ".لطفا نام پوشه جدید را وارد کنید", + + "Unallowable characters in folder name." => + ".نام پوشه دارای حروف غیر مجاز است", + + "Folder name shouldn't begins with '.'" => + ".نام پوشه نباید با '.' شروع شود", + + "Please enter new file name." => + ".لطفا نام فایل جدید را وارد کنید", + + "Unallowable characters in file name." => + ".نام فایل دارای حروف غیر مجاز است", + + "File name shouldn't begins with '.'" => + ".نام فایل نباید با '.' شروع شود", + + "Are you sure you want to delete this file?" => + "آیا از حذف این فایل اطمینان دارید؟", + + "Are you sure you want to delete this folder and all its content?" => + "آیا از حذف این پوشه و تمام محتویات داخل آن اطمینان دارید؟", + + "Inexistant or inaccessible folder." => + "Tipo di cartella non esistente.", + + "Undefined MIME types." => + ".تعریف نشده اند MIME پسوند های ", + + "Fileinfo PECL extension is missing." => + "Manca estensione PECL del file.", + + "Opening fileinfo database failed." => + ".خطا در بازکردن بانک اطلاعاتی مشخصات فایل", + + "You can't upload such files." => + ".شما امکان بارگذاری این فایل ها را ندارید", + + "The file '{file}' does not exist." => + ".موجود نیست '{file}' فایل", + + "Cannot read '{file}'." => + ".'{file}' مشکل در خواندن", + + "Cannot copy '{file}'." => + ".'{file}' نمی توانید کپی کنید", + + "Cannot move '{file}'." => + ".'{file}' نمی توانید انتقال دهید", + + "Cannot delete '{file}'." => + ".'{file}'نمی توانید حذف کنید", + + "Click to remove from the Clipboard" => + ".برای حذف از کلیپ برد کلیک کنید", + + "This file is already added to the Clipboard." => + ".این فایل قبلا در حافظه کلیپ برد افزوده شده است", + + "Copy files here" => + "کپی فایل ها به اینجا", + + "Move files here" => + "انتقال فایل ها به اینجا", + + "Delete files" => + "حذف فایل ها", + + "Clear the Clipboard" => + "پاک کردن حافظه کلیپ برد", + + "Are you sure you want to delete all files in the Clipboard?" => + "آیا از حذف فایل های موجود در کلیپ برد اطمینان دارید؟", + + "Copy {count} files" => + "...تعداد {count} فایل آماده کپی به", + + "Move {count} files" => + "...تعداد {count} فایل آماده انتقال به", + + "Add to Clipboard" => + "افزودن در کلیپ برد", + + "New folder name:" => "نام پوشه جدید:", + "New file name:" => "نام فایل جدید:", + + "Upload" => "ارسال فايل", + "Refresh" => "بارگذاری مجدد", + "Settings" => "تنظيمات", + "Maximize" => "تمام صفحه", + "About" => "درباره", + "files" => "فايل ها", + "View:" => ": نمایش", + "Show:" => ": نمايش", + "Order by:" => ": مرتب کردن بر مبناي", + "Thumbnails" => "نمايش کوچک عکسها", + "List" => "ليست", + "Name" => "نام", + "Size" => "حجم", + "Date" => "تاريخ", + "Type" => "پسوند", + "Descending" => "نزولي", + "Uploading file..." => "... درحال ارسال فایل", + "Loading image..." => "... درحال بارگذاری عکس", + "Loading folders..." => "... درحال بارگذاری پوشه ها", + "Loading files..." => "... درحال بارگذاری فایل ها", + "New Subfolder..." => "...ساخت زیرپوشه جدید", + "Rename..." => "... تغییر نام", + "Delete" => "حذف", + "OK" => "ادامه", + "Cancel" => "انصراف", + "Select" => "انتخاب", + "Select Thumbnail" => "انتخاب عکس با اندازه کوچک", + "View" => "نمایش", + "Download" => "دریافت فایل", + "Clipboard" => "حافضه کلیپ برد", + + // VERSION 2 NEW LABELS + + "Cannot rename the folder." => + ".نام وارد شده تکراری است. پوشه ای با این نام وجود دارد. لطفا نام جدیدی انتخاب کنید", + + "Non-existing directory type." => + ".نوع فهرست وجود ندارد", + + "Cannot delete the folder." => + ".نمی توانید این پوشه را حذف کنید", + + "The files in the Clipboard are not readable." => + ".فایل های موجود در کلیپ برد قابل خواندن نیستند", + + "{count} files in the Clipboard are not readable. Do you want to copy the rest?" => + "تعداد {count} فایل موجود در کلیپ برد قابل خواندن نیستند. آیا مایلید بقیه فایل ها کپی شوند؟", + + "The files in the Clipboard are not movable." => + ".فایل های موجود در کلیپ برد غیر قابل انتقال هستند. لطفا دسترسی فایل ها را چک کنید", + + "{count} files in the Clipboard are not movable. Do you want to move the rest?" => + "تعداد {count} فایل از فایل های موجود در کلیپ برد غیر قابل انتقال هستند. آیا مایلید بقیه فایل ها منتقل شوند؟", + + "The files in the Clipboard are not removable." => + ".فایل های موجود در کلیپ برد قابل پاک شدن نیستند. دسترسی فایل ها را چک کنید", + + "{count} files in the Clipboard are not removable. Do you want to delete the rest?" => + "تعداد {count} فایل از فایل های موجود در کلیپ برد غیر قابل حذف هستند. آیا مایلید بقیه فایل ها حذف شوند؟", + + "The selected files are not removable." => + ".فایل های انتخاب شده قابل برداشتن نیست", + + "{count} selected files are not removable. Do you want to delete the rest?" => + "تعداد {count} فایل از فایل های انتخابی غیر قابل حذف هستند.آیا مایلید بقیه فایل ها حذف شوند؟", + + "Are you sure you want to delete all selected files?" => + "آیا از حذف تمام فایل های انتخابی اطمینان دارید؟", + + "Failed to delete {count} files/folders." => + ".فایل/پوشه {count} خطا در پاک کردن", + + "A file or folder with that name already exists." => + ".یک پوشه یا فایل با این نام وجود دارد.لطفا نام دیگری انتخاب کنید", + + "selected files" => "فایل های انتخاب شده", + "Select Thumbnails" => "انتخاب عکس های کوچک", + "Download files" => "دریافت فایل ها", + + // SINCE 2.4 + + "Checking for new version..." => "...وجود نسخه جدید را بررسی کن", + "Unable to connect!" => "!مشکل در برقراری ارتباط", + "Download version {version} now!" => "!را دانلود کن {version} همسین حالا نسخه ", + "KCFinder is up to date!" => "!بروز است KCFinder", + "Licenses:" => "مجوز", + "Attention" => "توجه", + "Question" => "پرسش", + "Yes" => "بله", + "No" => "خیر", + + // SINCE 2.41 + + "You cannot rename the extension of files!" => "!شما نمی توانید پسوند فایلها را تغییر دهید", + "Uploading file {number} of {count}... {progress}" => "{progress} ...ارسال شد {count} فایل از {number}", + "Failed to upload {filename}!" => "! {filename} خطا در ارسال" + +); diff --git a/lib/kcfinder/lang/fi.php b/lib/kcfinder/lang/fi.php new file mode 100644 index 0000000..788f825 --- /dev/null +++ b/lib/kcfinder/lang/fi.php @@ -0,0 +1,127 @@ + "Finnish", + '_native' => "Suomi", + '_locale' => "fi_FI.UTF-8", // UNIX localization code + '_charset' => "utf-8", // Browser charset + + // Date time formats. See http://www.php.net/manual/en/function.strftime.php + '_dateTimeFull' => "%A, %e %B, %Y %H:%M", + '_dateTimeMid' => "%a %e %b %Y %H:%M", + '_dateTimeSmall' => "%d.%m.%Y %H:%M", + + "You don't have permissions to upload files." => "Sinulla ei ole oikeuksia ladata tiedostoja.", + "You don't have permissions to browse server." => "Sinulla ei ole riittäviä oikeuksia tiedostoselaimeen.", + "Cannot move uploaded file to target folder." => "Ladattua tiedostoa ei voi siirtää kohdekansioon. ", + "Unknown error." => "Tuntematon virhe.", + "The uploaded file exceeds {size} bytes." => "Tiedoston koko ylittää {size} tavua.", + "The uploaded file was only partially uploaded." => "Valitsemasi tiedosto latautui vain osittain.", + "No file was uploaded." => "Yhtään tiedostoja ei ladattu.", + "Missing a temporary folder." => "Puuttuu väliaikainen kansio.", + "Failed to write file." => "Tiedostoon kirjoitus epäonnistui.", + "Denied file extension." => "Kielletty tiedostopääte.", + "Unknown image format/encoding." => "Tuntematon kuvatiedosto/koodaus.", + "The image is too big and/or cannot be resized." => "Kuva on liian iso, koon muuttaminen ei onnistu.", + "Cannot create {dir} folder." => "Kansiota {dir} ei voi luoda.", + "Cannot rename the folder." => "Kansiota ei voi nimetä uudelleen.", + "Cannot write to upload folder." => "Latauskansioon ei voi kirjoittaa.", + "Cannot read .htaccess" => ".htaccess tiedostoa ei voi lukea.", + "Incorrect .htaccess file. Cannot rewrite it!" => "Virheellinen .htaccess tiedosto. Tiedostoon ei voi kirjoittaa.", + "Cannot read upload folder." => "Latauskansiota ei voi lukea.", + "Cannot access or create thumbnails folder." => "Esikatselukuvien kansiota ei voi lukea tai kirjoittaa.", + "Cannot access or write to upload folder." => "Latauskansiota ei voi lukea tai kirjoittaa.", + "Please enter new folder name." => "Kirjoita uuden kansion nimi.", + "Unallowable characters in folder name." => "Kiellettyjä merkkejä kansion nimessä.", + "Folder name shouldn't begins with '.'" => "Kansion nimi ei voi alkaa '.'", + "Please enter new file name." => "Kirjoita uusi tiedostonimi.", + "Unallowable characters in file name." => "Kiellettyjä merkkejä tiedoston nimessä.", + "File name shouldn't begins with '.'" => "Tiedoston nimi ei voi alkaa '.'", + "Are you sure you want to delete this file?" => "Haluatko varmasti poistaa tiedoston?", + "Are you sure you want to delete this folder and all its content?" => "Haluatko varmasti poistaa tiedoston sekä kaiken sen sisällön?", + "Non-existing directory type." => "Hakemisto tyyppi ei ole olemassa.", + "Undefined MIME types." => "Määrittämättömät MIME tyypit.", + "Fileinfo PECL extension is missing." => "Fileinfo PECL pääte puuttuu.", + "Opening fileinfo database failed." => "Opening fileinfo database failed.", + "You can't upload such files." => "Tiedostoja ei voi ladata.", + "The file '{file}' does not exist." => "Tiedostoa '{file}' ei ole luotu.", + "Cannot read '{file}'." => "Tiedostoa '{file}' ei voi lukea.", + "Cannot copy '{file}'." => "Tiedostoa '{file}' ei voi kopioda.", + "Cannot move '{file}'." => "Tiedostoa '{file}' ei voi siirtää.", + "Cannot delete '{file}'." => "Tiedostoa '{file}' ei voi poistaa.", + "Cannot delete the folder." => "Kansiota ei voi poistaa.", + "Click to remove from the Clipboard" => "Klikkaa poistaaksesi Leikepöydältä.", + "This file is already added to the Clipboard." => "Tiedosto on jo lisätty Leikepöydälle.", + "The files in the Clipboard are not readable." => "Leikepöydän tiedostot eivät ole luettavissa.", + "{count} files in the Clipboard are not readable. Do you want to copy the rest?" => "Leikepöydällä on {count} tiedostoa joita ei voi lukea. Haluatko kopioida loput?", + "The files in the Clipboard are not movable." => "Leikepöydän tiedostoja ei voi siirtää.", + "{count} files in the Clipboard are not movable. Do you want to move the rest?" => "Leikepöydällä on {count} tiedostoa joita ei voi siirtää. Haluatko siirtää loput?", + "The files in the Clipboard are not removable." => "Leikepöydän tiedostoja ei voi poistaa.", + "{count} files in the Clipboard are not removable. Do you want to delete the rest?" => "Leikepöydällä on {count} tiedostoa joita ei voi poistaa. Haluatko siirtää loput?", + "The selected files are not removable." => "Valittuja tiedostoja ei voi poistaa.", + "{count} selected files are not removable. Do you want to delete the rest?" => "Leikepöydällä on {count} tiedostoa joita ei voi poistaa. Haluatko poistaa loput?", + "Are you sure you want to delete all selected files?" => "Haluatko varmasti poistaa kaikki valitut tiedostot?", + "Failed to delete {count} files/folders." => "{count} tiedoston/kansion poistaminen epäonnistui.", + "A file or folder with that name already exists." => "Tiedosto tai kansio nimellä on jo luoto.", + "Copy files here" => "Kopio tähän", + "Move files here" => "Siirrä tähän", + "Delete files" => "Poista tiedostot", + "Clear the Clipboard" => "Pyyhi leikepöytä.", + "Are you sure you want to delete all files in the Clipboard?" => "Haluatko varmasti poistaa kaikki tiedostot Leikepöydältä?", + "Copy {count} files" => "Kopio {count} tiedostoa", + "Move {count} files" => "Siirrä {count} tiedostoa", + "Add to Clipboard" => "Lisää Leikepöydälle", + "Inexistant or inaccessible folder." => "Kansiota ei ole olemassa tai sitä ei voi avata.", + "New folder name:" => "Uusi kansion nimi:", + "New file name:" => "Uusi tiedostonimi:", + "Upload" => "Lataa", + "Refresh" => "Päivitä", + "Settings" => "Asetukset", + "Maximize" => "Koko ruutu", + "About" => "Lisätietoja", + "files" => "tiedostot", + "selected files" => "valitut tiedostot", + "View:" => "Näkymä:", + "Show:" => "Näytä:", + "Order by:" => "Järjestä:", + "Thumbnails" => "Esikatselukuvat", + "List" => "Lista", + "Name" => "Nimi", + "Type" => "Tyyppi", + "Size" => "Koko", + "Date" => "Päiväys", + "Descending" => "Laskeva", + "Uploading file..." => "Siirretään tiedostoa...", + "Loading image..." => "Ladataan tiedostoa...", + "Loading folders..." => "Ladataan kansioita...", + "Loading files..." => "Ladataan tiedostoja...", + "New Subfolder..." => "Uusi alikansio...", + "Rename..." => "Nimeä uudelleen...", + "Delete" => "Poista", + "OK" => "OK", + "Cancel" => "Peru", + "Select" => "Valitse", + "Select Thumbnail" => "Valitse esikatselukuva", + "Select Thumbnails" => "Valitse esikatselukuvat", + "View" => "Näytä", + "Download" => "Lataa", + "Download files" => "Lataa tiedostot", + "Clipboard" => "Leikepöytä", + "Checking for new version..." => "Tarkastetaan uusin versio...", + "Unable to connect!" => "Yhteys epäonnistui!", + "Download version {version} now!" => "Lataa versio {version} nyt!", + "KCFinder is up to date!" => "KCFinder uusin versio on käytössä!", + "Licenses:" => "Lisenssit:", + "Attention" => "Huomio", + "Question" => "Kysymys", + "Yes" => "Kyllä", + "No" => "Ei", + "You cannot rename the extension of files!" => "Et voi nimetä uudelleen tiedostopäätettä!", + "Uploading file {number} of {count}... {progress}" => "Siirretään tiedostoa {number}/{count} ... {progress}", + "Failed to upload {filename}!" => "Siirto epäonnistui {filename}!", +); diff --git a/lib/kcfinder/lang/fr.php b/lib/kcfinder/lang/fr.php new file mode 100644 index 0000000..82b5daf --- /dev/null +++ b/lib/kcfinder/lang/fr.php @@ -0,0 +1,133 @@ + "French", + '_native' => "Français", + '_locale' => "fr_FR.UTF-8", // UNIX localization code + '_charset' => "utf-8", // Browser charset + + // Date time formats. See http://www.php.net/manual/en/function.strftime.php + '_dateTimeFull' => "%A %e %B %Y %H:%M", + '_dateTimeMid' => "%a %e %b %Y %H:%M", + '_dateTimeSmall' => "%d/%m/%Y %H:%M", + + "You don't have permissions to upload files." => "Vous n'avez pas les droits nécessaires pour télécharger des fichiers.", + "You don't have permissions to browse server." => "Vous n'avez pas les droits nécessaires pour parcourir le serveur.", + "Cannot move uploaded file to target folder." => "Impossible de déplacer le fichier téléchargé vers le dossier de destination.", + "Unknown error." => "Erreur inconnue.", + "The uploaded file exceeds {size} bytes." => "Le fichier envoyé dépasse la taille maximale de {size} octects.", + "The uploaded file was only partially uploaded." => "Le fichier n'a été que partiellement téléchargé.", + "No file was uploaded." => "Aucun fichier n'a été téléchargé.", + "Missing a temporary folder." => "Dossier temporaire absent.", + "Failed to write file." => "Impossible de créer le fichier.", + "Denied file extension." => "Extension non autorisée.", + "Unknown image format/encoding." => "Format/encodage d'image inconnu.", + "The image is too big and/or cannot be resized." => "L'image est trop grande et/ou ne peut être redimensionnée.", + "Cannot create {dir} folder." => "Impossible de créer le dossier {dir}.", + "Cannot rename the folder." => "Impossible de renommer le dossier.", + "Cannot write to upload folder." => "Impossible d'écrire dans le dossier de destination.", + "Cannot read .htaccess" => "Impossible de lire le fichier .htaccess", + "Incorrect .htaccess file. Cannot rewrite it!" => "Fichier .htaccess incorrect. Réécriture du fichier impossible!", + "Cannot read upload folder." => "Impossible de lire le dossier de destination.", + "Cannot access or create thumbnails folder." => "Impossible d'accéder ou de créer le dossier des miniatures.", + "Cannot access or write to upload folder." => "Impossible d'accéder ou d'écrire dans le dossier de destination.", + "Please enter new folder name." => "Merci d'entrer le nouveau nom de dossier.", + "Unallowable characters in folder name." => "Caractères non autorisés dans le nom du dossier.", + "Folder name shouldn't begins with '.'" => "Le nom du dossier ne peut pas commencer par '.'", + "Please enter new file name." => "Merci d'entrer le nouveau nom de fichier", + "Unallowable characters in file name." => "Caractères non autorisés dans le nom du fichier.", + "File name shouldn't begins with '.'" => "Le nom du fichier ne peut pas commencer par '.'", + "Are you sure you want to delete this file?" => "Êtes vous sûr du vouloir supprimer ce fichier?", + "Are you sure you want to delete this folder and all its content?" => "Êtes vous sûr du vouloir supprimer ce dossier et tous les fichiers qu'il contient?", + "Non-existing directory type." => "Type de répertoire inexistant.", + "Undefined MIME types." => "Type MIME indéterminé.", + "Fileinfo PECL extension is missing." => "L'extension Fileinfo PECL est manquante.", + "Opening fileinfo database failed." => "Ouverture de la base de données fileinfo echouée.", + "You can't upload such files." => "Vous ne pouvez pas télécharger ce type de fichiers.", + "The file '{file}' does not exist." => "Le fichier '{file}' n'existe pas.", + "Cannot read '{file}'." => "Impossible de lire le fichier '{file}'.", + "Cannot copy '{file}'." => "Impossible de copier le fichier '{file}'.", + "Cannot move '{file}'." => "Impossible de déplacer le fichier '{file}'.", + "Cannot delete '{file}'." => "Impossible de supprimer le fichier '{file}'.", + "Cannot delete the folder." => "Impossible de supprimer le dossier.", + "Click to remove from the Clipboard" => "Cliquez pour enlever du presse-papier", + "This file is already added to the Clipboard." => "Ce fichier a déja été ajouté au presse-papier.", + "The files in the Clipboard are not readable." => "Les fichiers du presse-papier ne sont pas lisibles.", + "{count} files in the Clipboard are not readable. Do you want to copy the rest?" => "{count} fichiers dans le presse-papier ne sont pas lisibles. Voulez vous copier le reste?", + "The files in the Clipboard are not movable." => "Les fichiers du presse-papier ne peuvent pas être déplacés.", + "{count} files in the Clipboard are not movable. Do you want to move the rest?" => "{count} fichiers du presse-papier ne peuvent pas être déplacées. Voulez vous déplacer le reste?", + "The files in the Clipboard are not removable." => "Les fichiers du presse-papier ne peuvent pas être enlevés.", + "{count} files in the Clipboard are not removable. Do you want to delete the rest?" => "{count} fichiers du presse-papier ne peuvent pas être enlevés. Voulez vous supprimer le reste?", + "The selected files are not removable." => "Les fichiers sélectionnés ne peuvent pas être enlevés.", + "{count} selected files are not removable. Do you want to delete the rest?" => "{count} fichier sélectionnés ne peuvent pas être enlevés. Voulez vous supprimer le reste?", + "Are you sure you want to delete all selected files?" => "Êtes vous sûr de vouloir supprimer tous les fichiers sélectionnés?", + "Failed to delete {count} files/folders." => "Echec de la suppression de {count} fichiers/dossiers.", + "A file or folder with that name already exists." => "Un fichier/dossier du même nom existe déja.", + "Copy files here" => "Copier les fichiers ici", + "Move files here" => "Déplacer les fichiers ici", + "Delete files" => "Supprimer les fichiers", + "Clear the Clipboard" => "Vider le presse-papier", + "Are you sure you want to delete all files in the Clipboard?" => "Êtes vous sûr de vouloir supprimer tous les fichiers du presse-papier?", + "Copy {count} files" => "Copie de {count} fichiers", + "Move {count} files" => "Déplacement de {count} fichiers", + "Add to Clipboard" => "Ajouter au presse-papier", + "Inexistant or inaccessible folder." => "Dossier inexistant ou innacessible.", + "New folder name:" => "Nom du nouveau dossier:", + "New file name:" => "Nom du nouveau fichier:", + "Upload" => "Envoyer", + "Refresh" => "Actualiser", + "Settings" => "Paramètres", + "Maximize" => "Agrandir", + "About" => "A propos", + "files" => "fichiers", + "selected files" => "fichiers sélectionnés", + "View:" => "Voir:", + "Show:" => "Montrer:", + "Order by:" => "Trier par:", + "Thumbnails" => "Miniatures", + "List" => "Liste", + "Name" => "Nom", + "Type" => "Type", + "Size" => "Taille", + "Date" => "Date", + "Descending" => "Décroissant", + "Uploading file..." => "Téléchargement en cours...", + "Loading image..." => "Chargement de l'image...", + "Loading folders..." => "Chargement des dossiers...", + "Loading files..." => "Chargement des fichiers...", + "New Subfolder..." => "Nouveau sous-dossier...", + "Rename..." => "Renommer...", + "Delete" => "Supprimer", + "OK" => "OK", + "Cancel" => "Annuler", + "Select" => "Sélectionner", + "Select Thumbnail" => "Sélectionner la miniature", + "Select Thumbnails" => "Sélectionner les miniatures", + "View" => "Voir", + "Download" => "Télécharger", + "Download files" => "Télécharger les fichiers", + "Clipboard" => "Presse-papier", + "Checking for new version..." => "Vérifier les mises à jours...", + "Unable to connect!" => "Connexion impossible !", + "Download version {version} now!" => "Télécharger la version {version} maintenant !", + "KCFinder is up to date!" => "KCFinder est à jour !", + "Licenses:" => "Licences:", + "Attention" => "Alerte", + "Question" => "Question", + "Yes" => "Oui", + "No" => "Non", + "You cannot rename the extension of files!" => "Vous ne pouvez modifier l'extension des fichiers !", + "Uploading file {number} of {count}... {progress}" => "Envoi du fichier {number} sur {count}... {progress}", + "Failed to upload {filename}!" => "Échec du téléchargement du fichier {filename} !", + "Close" => "Fermer", + "Previous" => "Précédent", + "Next" => "Suivant", + "Confirmation" => "Confirmation", + "Warning" => "Avertissement", +); diff --git a/lib/kcfinder/lang/he.php b/lib/kcfinder/lang/he.php new file mode 100644 index 0000000..387b5f3 --- /dev/null +++ b/lib/kcfinder/lang/he.php @@ -0,0 +1,127 @@ + "Hebrew", + '_native' => "עברית", + '_locale' => "he_IL.UTF-8", // UNIX localization code + '_charset' => "utf-8", // Browser charset + + // Date time formats. See http://www.php.net/manual/en/function.strftime.php + '_dateTimeFull' => "%H:%M %Y %B %e %A", + '_dateTimeMid' => "%H:%M %d/%m/%Y", + '_dateTimeSmall' => "%H:%M %d/%m/%Y", + + "You don't have permissions to upload files." => "אין לך הרשאות להעלות קבצים.", + "You don't have permissions to browse server." => "איך לך הרשאות לצפות בקבצים.", + "Cannot move uploaded file to target folder." => "לא ניתן להעביר את הקבצים שהועלו לתקייה שנבחרה.", + "Unknown error." => "שגיאה לא ידועה.", + "The uploaded file exceeds {size} bytes." => "הקובץ המועלה עובר את הגודל המקסימלי. ({size} בתים).", + "The uploaded file was only partially uploaded." => "הקובץ הועלה חלקית.", + "No file was uploaded." => "לא הועלו קבצים.", + "Missing a temporary folder." => "חסר תקייה זמנית.", + "Failed to write file." => "כתיבת הקובץ נכשלה.", + "Denied file extension." => "סיומת קובץ לא מורשית.", + "Unknown image format/encoding." => "סוג תמונה לא מוכר.", + "The image is too big and/or cannot be resized." => "התמונה גדולה מדי או שלא ניתן למזערה.", + "Cannot create {dir} folder." => "לא יכול ליצור את '{dir}'.", + "Cannot rename the folder." => "לא ניתן לשנות את שם התקיה", + "Cannot write to upload folder." => "לא ניתן לכתובת לתקיית ההעלאה", + "Cannot read .htaccess" => "לא ניתן לקרא את .htaccess", + "Incorrect .htaccess file. Cannot rewrite it!" => "קובץ .htaccess לא חוקי, לא ניתן לשכתב קובץ \\זה.", + "Cannot read upload folder." => "לא ניתן לקרא מתקיית ההעלאות.", + "Cannot access or create thumbnails folder." => "לא ניתן לגשת לתקייה התמונות הממוזערות.", + "Cannot access or write to upload folder." => "לא ניתן לגשת לתקיית ההעלאה.", + "Please enter new folder name." => "אנא בחר בשם לתקייה החדשה.", + "Unallowable characters in folder name." => "אותיות לא מורשות בשם התקיה.", + "Folder name shouldn't begins with '.'" => "שם תקיה אינו יכול להתחיל בנקודה.", + "Please enter new file name." => "אנא הכנס שם לקובץ החדש", + "Unallowable characters in file name." => "אותיות לא מורשות בשם הקובץ.", + "File name shouldn't begins with '.'" => "שם קובץ אינו יכול להתחיל בנקודה.", + "Are you sure you want to delete this file?" => "הנך בטוח שברצונך למחוק קבצים אילו?", + "Are you sure you want to delete this folder and all its content?" => "האם ברצונך למחוק תקיה זו וכל תוכנה?", + "Non-existing directory type." => "סוג תקייה לא קיימת.", + "Undefined MIME types." => "סוג MIME לא מוגדר.", + "Fileinfo PECL extension is missing." => "פרטי PECL חסרים.", + "Opening fileinfo database failed." => "פתיחת מסד פרטי הקבצים נכשלה.", + "You can't upload such files." => "לא ניתן להעלות קבצים מסוג זה.", + "The file '{file}' does not exist." => "הקובץ '{file}' לא קיים.", + "Cannot read '{file}'." => "לא יכול לפתוח '{file}'.", + "Cannot copy '{file}'." => "לא יכול להעתיק '{file}'.", + "Cannot move '{file}'." => "לא יכול להעביר '{file}'.", + "Cannot delete '{file}'." => "לא יכול למחוק '{file}'.", + "Cannot delete the folder." => "לא ניתן למחוק את התקייה", + "Click to remove from the Clipboard" => "לחץ להסיר מהלוח", + "This file is already added to the Clipboard." => "קובץ זה קיים בלוח.", + "The files in the Clipboard are not readable." => "הקבצים בלוח אינם קריאים.", + "{count} files in the Clipboard are not readable. Do you want to copy the rest?" => "{count} קבצים בלוח אינם קריאים. להעתיק את השאר?", + "The files in the Clipboard are not movable." => "הקבצים בלוח אינם ניתן להעברה.", + "{count} files in the Clipboard are not movable. Do you want to move the rest?" => "{count} קבצים בלוח אינם ניתן להעברה. להעביר את השאר?", + "The files in the Clipboard are not removable." => "הקבצים בלוח אינם נתנים להסרה.", + "{count} files in the Clipboard are not removable. Do you want to delete the rest?" => "{count} קבצים בלוח אינם נתנים להסרה. להסיר את השאר?", + "The selected files are not removable." => "הקבצים הנבחרים אינם נתנים להסרה.", + "{count} selected files are not removable. Do you want to delete the rest?" => "{count} קבצים בלוח אינם נתנים להסרה. למחוק את השאר?", + "Are you sure you want to delete all selected files?" => "האם ברצונך למחוק את הקבצים בנבחרים?", + "Failed to delete {count} files/folders." => "מחיקת {count} קבצים נכשלה.", + "A file or folder with that name already exists." => "תקייה/קובץ בשם זה כבר קיימים.", + "Copy files here" => "העתק קבצים לכאן", + "Move files here" => "העבר קבצים לכאן", + "Delete files" => "מחק קובץ", + "Clear the Clipboard" => "נקה לוח", + "Are you sure you want to delete all files in the Clipboard?" => "האם ברצונך לרוקן את הלוח?", + "Copy {count} files" => "העתק {count} קבצים.", + "Move {count} files" => "העבר {count} קבצים.", + "Add to Clipboard" => "הוסף ללוח", + "Inexistant or inaccessible folder." => "תקיה או קובץ לא קיימים.", + "New folder name:" => "שם תקיה חדשה:", + "New file name:" => "שם קובץ חדש:", + "Upload" => "העלה", + "Refresh" => "רענן", + "Settings" => "הגדרות", + "Maximize" => "הגדל", + "About" => "אודות", + "files" => "קבצים", + "selected files" => "קבצים מסומנים", + "View:" => "צפה:", + "Show:" => "הראה:", + "Order by:" => "מיין ע\"פ:", + "Thumbnails" => "תמונות ממוזערות", + "List" => "רשימה", + "Name" => "שם", + "Type" => "סוג", + "Size" => "גודל", + "Date" => "תאריך", + "Descending" => "יורד", + "Uploading file..." => "מעלה קבצים...", + "Loading image..." => "טוען תמונות...", + "Loading folders..." => "טוען תקיות...", + "Loading files..." => "טוען קבצים...", + "New Subfolder..." => "תת תקיה חדשה...", + "Rename..." => "שנה שם...", + "Delete" => "מחק", + "OK" => "אישור", + "Cancel" => "ביטול", + "Select" => "סמן", + "Select Thumbnail" => "סמן תמונות ממוזערות", + "Select Thumbnails" => "סמן תמונות ממוזערות", + "View" => "צפה", + "Download" => "הורד", + "Download files" => "הורד קובץ/ים", + "Clipboard" => "לוח", + "Checking for new version..." => "בודק גרסא עדכנית...", + "Unable to connect!" => "שגיאת התחברות!", + "Download version {version} now!" => "הורד גרסא {version} עכשיו!", + "KCFinder is up to date!" => "המערכת עדכנית!", + "Licenses:" => "רשיון", + "Attention" => "לתשומת לב", + "Question" => "שאלה", + "Yes" => "כן", + "No" => "לא", + "You cannot rename the extension of files!" => "לא ניתו לערוך סיומות קבצים!", + "Uploading file {number} of {count}... {progress}" => "מעלה קובץ {number} מתוך {count}... {progress}", + "Failed to upload {filename}!" => "העלאת הקובץ נכשלה!", +); diff --git a/lib/kcfinder/lang/hu.php b/lib/kcfinder/lang/hu.php new file mode 100644 index 0000000..77973a6 --- /dev/null +++ b/lib/kcfinder/lang/hu.php @@ -0,0 +1,132 @@ + + */ + +$lang = array( + + '_lang' => "Hungarian", + '_native' => "Magyar", + '_locale' => "hu_HU.UTF-8", // UNIX localization code + '_charset' => "utf-8", // Browser charset + + // Date time formats. See http://www.php.net/manual/en/function.strftime.php + '_dateTimeFull' => "%A, %e.%B.%Y %H:%M", + '_dateTimeMid' => "%a %e %b %Y %H:%M", + '_dateTimeSmall' => "%d/%m/%Y %H:%M", + + "You don't have permissions to upload files." => "Nincs jogosultsága fájlokat feltölteni.", + "You don't have permissions to browse server." => "Nincs jogosultsága a kiszolgálón böngészni.", + "Cannot move uploaded file to target folder." => "Nem lehet áthelyezni a feltöltött fájlt a célkönyvtárba.", + "Unknown error." => "Ismeretlen hiba.", + "The uploaded file exceeds {size} bytes." => "A feltöltött fájl mérete meghaladja a {size} bájtot.", + "The uploaded file was only partially uploaded." => "A feltöltendő fájl csak részben sikerült feltölteni.", + "No file was uploaded." => "Nem történt fájlfeltöltés.", + "Missing a temporary folder." => "Hiányzik az ideiglenes könyvtár.", + "Failed to write file." => "Nem sikerült a fájl írása.", + "Denied file extension." => "Tiltott fájlkiterjesztés.", + "Unknown image format/encoding." => "Ismeretlen képformátum vagy kódolás.", + "The image is too big and/or cannot be resized." => "A kép mérete túl nagy és/vagy nem lehet átméretezni.", + "Cannot create {dir} folder." => "Nem lehet létrehozni a {dir} könyvtárat.", + "Cannot rename the folder." => "A könyvtárat nem lehet átnevezni.", + "Cannot write to upload folder." => "Nem lehet írni a feltöltési könyvtárba.", + "Cannot read .htaccess" => "Nem lehet olvasni a .htaccess fájlt", + "Incorrect .htaccess file. Cannot rewrite it!" => "Hibás .htaccess fájl. Nem lehet írni.", + "Cannot read upload folder." => "Nem lehet olvasni a feltöltési könyvtárat.", + "Cannot access or create thumbnails folder." => "Nem lehet elérni vagy létrehozni a bélyegképek könyvtárat.", + "Cannot access or write to upload folder." => "Nem lehet elérni vagy létrehozni a feltöltési könyvtárat.", + "Please enter new folder name." => "Kérem, adja meg az új könyvtár nevét.", + "Unallowable characters in folder name." => "Meg nem engedett karakter(ek) a könyvtár nevében.", + "Folder name shouldn't begins with '.'" => "Könyvtárnév nem kezdődhet '.'-tal", + "Please enter new file name." => "Kérem adja meg az új fájl nevét.", + "Unallowable characters in file name." => "Meg nem engedett karakter(ek) a fájl nevében.", + "File name shouldn't begins with '.'" => "Fájlnév nem kezdődhet '.'-tal", + "Are you sure you want to delete this file?" => "Biztos benne, hogy törölni kívánja ezt a fájlt?", + "Are you sure you want to delete this folder and all its content?" => "Biztos benne hogy törölni kívánja ezt a könyvtárat és minden tartalmát?", + "Non-existing directory type." => "Nem létező könyvtártípus.", + "Undefined MIME types." => "Meghatározatlan MIME típusok.", + "Fileinfo PECL extension is missing." => "Hiányzó PECL Fileinfo PHP kiegészítés.", + "Opening fileinfo database failed." => "Nem sikerült megnyitni a Fileinfo adatbázist.", + "You can't upload such files." => "Nem tölthet fel ilyen fájlokat.", + "The file '{file}' does not exist." => "A '{file}' fájl nem létezik.", + "Cannot read '{file}'." => "A '{file}' fájlt nem lehet olvasni.", + "Cannot copy '{file}'." => "A '{file}' fájlt nem lehet másolni.", + "Cannot move '{file}'." => "A '{file}' fájlt nem lehet áthelyezni.", + "Cannot delete '{file}'." => "A '{file}' fájlt nem lehet törölni.", + "Cannot delete the folder." => "Nem lehet törölni a könyvtárat.", + "Click to remove from the Clipboard" => "kattintson ide, hogy eltávolítsa a vágólapról", + "This file is already added to the Clipboard." => "Ezt a fájlt már hozzáadta a vágólaphoz.", + "The files in the Clipboard are not readable." => "A vágólapon lévő fájlok nem olvashatók.", + "{count} files in the Clipboard are not readable. Do you want to copy the rest?" => "{count} fájl a vágólapon nem olvasható. Akarja másolni a többit?", + "The files in the Clipboard are not movable." => "A vágólapon lévő fájlokat nem lehet áthelyezni.", + "{count} files in the Clipboard are not movable. Do you want to move the rest?" => "{count} fájlt a vágólapon nem lehet áthelyezni. Akarja áthelyezni a többit?", + "The files in the Clipboard are not removable." => "A vágólapon lévő fájlokat nem lehet eltávolítani.", + "{count} files in the Clipboard are not removable. Do you want to delete the rest?" => "{count} fájlt a vágólapon nem lehet eltávolítani. Akarja törölni a többit?", + "The selected files are not removable." => "A kiválasztott fájlokat nem lehet eltávolítani.", + "{count} selected files are not removable. Do you want to delete the rest?" => "{count} kiválasztott fájlt nem lehet eltávolítani. Akarja törölni a többit?", + "Are you sure you want to delete all selected files?" => "Biztosan törölni kíván minden kijelölt fájlt?", + "Failed to delete {count} files/folders." => "Nem sikerült törölni {count} fájlt.", + "A file or folder with that name already exists." => "Egy fájl vagy könyvtár már létezik ugyan ezzel a névvel.", + "Copy files here" => "Fájlok másolása ide", + "Move files here" => "Fájlok áthelyezése ide", + "Delete files" => "Fájlok törlése", + "Clear the Clipboard" => "Vágólap ürítése", + "Are you sure you want to delete all files in the Clipboard?" => "Biztosan törölni kívánja a vágólapon lévő összes fájlt?", + "Copy {count} files" => "{count} fájl másolása", + "Move {count} files" => "{count} fájl áthelyezése", + "Add to Clipboard" => "Hozzáadás vágólaphoz", + "Inexistant or inaccessible folder." => "Nem létező vagy elérhetetlen könyvtár.", + "New folder name:" => "Új könyvtár neve:", + "New file name:" => "Új fájl neve:", + "Upload" => "Feltöltés", + "Refresh" => "Frissítés", + "Settings" => "Beállítások", + "Maximize" => "Maximalizálás", + "About" => "Névjegy", + "files" => "fájlok", + "selected files" => "kiválasztott fájlok", + "View:" => "Nézet:", + "Show:" => "Mutat:", + "Order by:" => "Rendezés:", + "Thumbnails" => "Bélyegképek", + "List" => "Lista", + "Name" => "Név", + "Type" => "Típus", + "Size" => "Méret", + "Date" => "Datum", + "Descending" => "Csökkenő", + "Uploading file..." => "Fájl feltöltése...", + "Loading image..." => "Képek betöltése...", + "Loading folders..." => "Könyvtárak betöltése...", + "Loading files..." => "Fájlok betöltése...", + "New Subfolder..." => "Új alkönyvtár...", + "Rename..." => "Átnevezés...", + "Delete" => "Törlés", + "OK" => "OK", + "Cancel" => "Mégse", + "Select" => "Kiválaszt", + "Select Thumbnail" => "Bélyegkép kiválasztása", + "Select Thumbnails" => "Bélyegképek kiválasztása", + "View" => "Nézet", + "Download" => "Letöltés", + "Download files" => "Fájlok letöltése", + "Clipboard" => "Vágólap", + "Checking for new version..." => "Új verzió keresése ...", + "Unable to connect!" => "Nem lehet csatlakozni!", + "Download version {version} now!" => "Töltse le a {version} verziót most!", + "KCFinder is up to date!" => "Ez a KCFinder verzió a legfrissebb", + "Licenses:" => "Licenszek:", + "Attention" => "Figyelem", + "Question" => "Kérdés", + "Yes" => "Igen", + "No" => "Nem", + "You cannot rename the extension of files!" => "Nem változtathatja meg a fájlok kiterjezstését", + "Uploading file {number} of {count}... {progress}" => "A(z) {number}. fájl feltöltése (összesen {count}) ... {progress}", + "Failed to upload {filename}!" => "Nem sikerült feltölteni a '{filename}' fájlt.", + "Close" => "Bezár", + "Previous" => "Előző", + "Next" => "Következő", + "Confirmation" => "Megerősítés", + "Warning" => "Figyelem" +); diff --git a/lib/kcfinder/lang/id.php b/lib/kcfinder/lang/id.php new file mode 100644 index 0000000..24a8e7d --- /dev/null +++ b/lib/kcfinder/lang/id.php @@ -0,0 +1,127 @@ + "Indonesian", + '_native' => "Indonesia", + '_locale' => "id_ID.UTF-8", // UNIX localization code + '_charset' => "utf-8", // Browser charset + + // Date time formats. See http://www.php.net/manual/en/function.strftime.php + '_dateTimeFull' => "%A, %e %B, %Y %H:%M", + '_dateTimeMid' => "%a %e %b %Y %H:%M", + '_dateTimeSmall' => "%d.%m.%Y %H:%M", + + "You don't have permissions to upload files." => "Anda tidak punya izin untuk mengunggah file.", + "You don't have permissions to browse server." => "Anda tidak punya izin untuk menelusuri server.", + "Cannot move uploaded file to target folder." => "Gagal memindahkan file yang di unggah ke target folder.", + "Unknown error." => "Error yang tidak diketahui.", + "The uploaded file exceeds {size} bytes." => "File yang anda unggah melebihi {size} bytes.", + "The uploaded file was only partially uploaded." => "Hanya sebagian file yang anda unggah telah di upload.", + "No file was uploaded." => "Tidak ada file yang di unggah.", + "Missing a temporary folder." => "Temporary folder hilang.", + "Failed to write file." => "Gagal untuk menulis file.", + "Denied file extension." => "File extension ditolak.", + "Unknown image format/encoding." => "Format gambar/encoding tidak diketahui.", + "The image is too big and/or cannot be resized." => "Gambar terlalu besar dan/atau tidak bisa di ubah ukurannya.", + "Cannot create {dir} folder." => "Gagal membuat {dir} folder", + "Cannot rename the folder." => "Gagal mengganti nama folder.", + "Cannot write to upload folder." => "Gagal menulis ke server unggah.", + "Cannot read .htaccess" => "Gagal membaca .htaccess", + "Incorrect .htaccess file. Cannot rewrite it!" => "Salah .htaccess file. Tidak bisa menulis file itu kembali!", + "Cannot read upload folder." => "Gagal membaca folder unggah.", + "Cannot access or create thumbnails folder." => "Gagal mengakses atau membuat miniatur folder.", + "Cannot access or write to upload folder." => "Gagal mengakses atau menulis ke folder unggah.", + "Please enter new folder name." => "Tolong masukkan nama folder baru.", + "Unallowable characters in folder name." => "Ada karakter yang tidak di izinkan di nama folder.", + "Folder name shouldn't begins with '.'" => "Nama folder seharusnya tidak dimulai dengan '.'", + "Please enter new file name." => "Tolong masukkan nama file baru.", + "Unallowable characters in file name." => "Ada karakter yang tidak di izinkan di nama file.", + "File name shouldn't begins with '.'" => "Nama file seharusnya tidak dimulai dengan '.'", + "Are you sure you want to delete this file?" => "Yakin anda akan menghapus file ini?", + "Are you sure you want to delete this folder and all its content?" => "Yakin anda akan menghapus folder ini dan semua konten nya?", + "Non-existing directory type." => "Jenis direktory tidak ada.", + "Undefined MIME types." => "Jenis MIME tidak diketahui.", + "Fileinfo PECL extension is missing." => "extensi Fileinfo PECL hilang.", + "Opening fileinfo database failed." => "Membuka fileinfo database gagal.", + "You can't upload such files." => "Anda tidak bisa mengunggah file seperti ini.", + "The file '{file}' does not exist." => "File '{file}' tidak ada.", + "Cannot read '{file}'." => "Gagal membaca '{file}'", + "Cannot copy '{file}'." => "Gagal menyalin '{file}'", + "Cannot move '{file}'." => "Gagal pindahkan '{file}'", + "Cannot delete '{file}'." => "Gagal menghapus '{file}'", + "Cannot delete the folder." => "Gagal menghapus folder. ", + "Click to remove from the Clipboard" => "Klik untuk memusnahkan dari Clipboard.", + "This file is already added to the Clipboard." => "File ini memang sudah ditambahkan ke Clipboard.", + "The files in the Clipboard are not readable." => "File-File yang di Clipboard tidak bisa di baca.", + "{count} files in the Clipboard are not readable. Do you want to copy the rest?" => "{count} file-file di Clipboard tidak bisa di baca. Apakah anda mau menyalin sisa-nya?", + "The files in the Clipboard are not movable." => "File-file yang di clipboard tidak memungkinkan untuk di pindah.", + "{count} files in the Clipboard are not movable. Do you want to move the rest?" => "{count} file-file yang di Clipboard tidak bisa di pindah. Apakan anda mau memindahkan sisa-nya?", + "The files in the Clipboard are not removable." => "File file yang di Clipboard tidak memungkinkan untuk di hapus.", + "{count} files in the Clipboard are not removable. Do you want to delete the rest?" => "{count} file-file di Clipboard tidak memungkinkan untuk di hapus. Apakah anda mau menghapus sisa-nya?", + "The selected files are not removable." => "File-file yang anda pilih tidak memungkinkan untuk di hapus.", + "{count} selected files are not removable. Do you want to delete the rest?" => "{count} file-file yang terpilih tidak memungkinkan untuk di hapus. Apakah anda mau menghapus sisa-nya?", + "Are you sure you want to delete all selected files?" => "Yakin anda akan menghapus semua file-file yang di pilih?", + "Failed to delete {count} files/folders." => "Gagal menghapus {count} file/folder.", + "A file or folder with that name already exists." => "File atau folder dengan nama itu sudah ada.", + "Copy files here" => "Salin file-file kesini", + "Move files here" => "Pindah file-file kesini", + "Delete files" => "Hapus file", + "Clear the Clipboard" => "Bersihkan Clipboard", + "Are you sure you want to delete all files in the Clipboard?" => "Yakin anda akan menghapus semua file-file yang ada di Clipboard?", + "Copy {count} files" => "Salin {count} file-file", + "Move {count} files" => "Pindah {count} file-file", + "Add to Clipboard" => "Tambahkan ke Clipboard", + "Inexistant or inaccessible folder." => "Folder tidak ada atau tidak bisa di akses.", + "New folder name:" => "Nama folder baru:", + "New file name:" => "Nama file baru:", + "Upload" => "Unggah", + "Refresh" => "Refresh", + "Settings" => "Pengaturan", + "Maximize" => "Maksimalkan", + "About" => "Tentang", + "files" => "File", + "selected files" => "File-file yang di pilih", + "View:" => "Lihat:", + "Show:" => "Tampilkan:", + "Order by:" => "Sortir dengan:", + "Thumbnails" => "Miniatur", + "List" => "Daftar", + "Name" => "Nama", + "Type" => "Jenis", + "Size" => "Ukuran", + "Date" => "Tanggal", + "Descending" => "Menurun", + "Uploading file..." => "Mengunggah file...", + "Loading image..." => "Memuat gambar...", + "Loading folders..." => "Memuat folder...", + "Loading files..." => "Memuat file...", + "New Subfolder..." => "Subfolder baru...", + "Rename..." => "Ganti nama...", + "Delete" => "Hapus...", + "OK" => "OK", + "Cancel" => "Batalkan", + "Select" => "Pilih", + "Select Thumbnail" => "Pilih Thumbnail", + "Select Thumbnails" => "Pilih Thumbnails", + "View" => "Lihat", + "Download" => "Unggah", + "Download files" => "Unggah file", + "Clipboard" => "Clipboard", + "Checking for new version..." => "Mengecek untuk versi baru...", + "Unable to connect!" => "Gagal untuk mengkoneksi!", + "Download version {version} now!" => "Unduh versi {version} sekarang!", + "KCFinder is up to date!" => "KCFinder adalah versi terbaru!", + "Licenses:" => "Lisensi:", + "Attention" => "Perhatian", + "Question" => "Pertanyaan", + "Yes" => "Ya", + "No" => "Tidak", + "You cannot rename the extension of files!" => "Anda tidak bisa mengubah ekstensi file!", + "Uploading file {number} of {count}... {progress}" => "Mengunggah file {number} of {count}... {progress}", + "Failed to upload {filename}!" => "Gagal untuk mengunggah {filename}", +); diff --git a/lib/kcfinder/lang/it.php b/lib/kcfinder/lang/it.php new file mode 100644 index 0000000..377e56c --- /dev/null +++ b/lib/kcfinder/lang/it.php @@ -0,0 +1,132 @@ + "Italian", + '_native' => "Italiano", + '_locale' => "it_IT.UTF-8", // UNIX localization code + '_charset' => "utf-8", // Browser charset + + // Date time formats. See http://www.php.net/manual/en/function.strftime.php + '_dateTimeFull' => "%A, %e %B, %Y %H:%M", + '_dateTimeMid' => "%a %e %b %Y %H:%M", + '_dateTimeSmall' => "%d.%m.%Y %H:%M", + + "You don't have permissions to upload files." => "Non hai il permesso di caricare files.", + "You don't have permissions to browse server." => "Non hai il permesso di elencare i files.", + "Cannot move uploaded file to target folder." => "Non puoi spostare il file caricato nella cartella di destinazione.", + "Unknown error." => "Errore sconosciuto.", + "The uploaded file exceeds {size} bytes." => "Il file caricato eccede {size} bytes.", + "The uploaded file was only partially uploaded." => "Il file è stato caricato parzialmente.", + "No file was uploaded." => "Nessun file è stato caricato", + "Missing a temporary folder." => "Cartella temporanea non trovata.", + "Failed to write file." => "Scrittura del file fallita.", + "Denied file extension." => "Estensione del file non consentita.", + "Unknown image format/encoding." => "Il format/encoding dell'immagine è sconosciuto.", + "The image is too big and/or cannot be resized." => "L'immagine è troppo grande e/o non può essere rimpicciolita", + "Cannot create {dir} folder." => "La cartella {dir} non può essere creata.", + "Cannot rename the folder." => "Non è possibile rinominare la cartella.", + "Cannot write to upload folder." => "Cartella di destinazione protetta in scrittura.", + "Cannot read .htaccess" => "Impossibile leggere il file .htaccess.", + "Incorrect .htaccess file. Cannot rewrite it!" => "Il file .htaccess è corrotto. Impossibile riscriverlo!", + "Cannot read upload folder." => "Impossibile leggere il contenuto della cartella di destinazione.", + "Cannot access or create thumbnails folder." => "Impossibile creare o accedere alla cartella delle miniature.", + "Cannot access or write to upload folder." => "Impossibile accedere o scrivere nella cartella di destinazione.", + "Please enter new folder name." => "Scrivi il nome della nuova cartella.", + "Unallowable characters in folder name." => "Caratteri non permessi nel nome della cartella.", + "Folder name shouldn't begins with '.'" => "Il nome della cartella non può iniziare con'.'", + "Please enter new file name." => "Inserisci il nuovo nome del file", + "Unallowable characters in file name." => "Caratteri non permessi nel nome del file.", + "File name shouldn't begins with '.'" => "Il nome del file non può iniziare con '.'", + "Are you sure you want to delete this file?" => "Sei sicuro che vuoi cancellare questo file?", + "Are you sure you want to delete this folder and all its content?" => "Sei sicuro di voler cancellare questa cartella e il suo contenuto?", + "Non-existing directory type." => "Il tipo di cartella non esiste.", + "Undefined MIME types." => "Tipo MIME non definito.", + "Fileinfo PECL extension is missing." => "Manca estensione PECL del file.", + "Opening fileinfo database failed." => "Apertura del database delle informazioni del file fallita.", + "You can't upload such files." => "Non è possibile caricare questi files.", + "The file '{file}' does not exist." => "Il file '{file}' non esiste.", + "Cannot read '{file}'." => "Impossibile leggere il file '{file}'.", + "Cannot copy '{file}'." => "Impossibile copiare il file '{file}'.", + "Cannot move '{file}'." => "Impossibile spostare il file '{file}'.", + "Cannot delete '{file}'." => "Impossibile cancellare il file '{file}'.", + "Cannot delete the folder." => "Non è possibile cancellare la cartella.", + "Click to remove from the Clipboard" => "Click per rimuoverlo dalla Clipboard", + "This file is already added to the Clipboard." => "Questo file è già stato aggiunto alla Clipboard.", + "The files in the Clipboard are not readable." => "I files nella Clipboard non sono leggibili.", + "{count} files in the Clipboard are not readable. Do you want to copy the rest?" => "{count} files nella Clipboard non sono leggibili. Copiare il resto?", + "The files in the Clipboard are not movable." => "I files nella Clipboard non sono spostabili.", + "{count} files in the Clipboard are not movable. Do you want to move the rest?" => "{count} files nella Clipboard non sono spostabili. Spostare il resto?", + "The files in the Clipboard are not removable." => "I files nella Clipboard non si possono rimuovere.", + "{count} files in the Clipboard are not removable. Do you want to delete the rest?" => "{count} files nella Clipboard non si possono rimuovere. Cancellare il resto?", + "The selected files are not removable." => "Il file selezionato non è rimovibile.", + "{count} selected files are not removable. Do you want to delete the rest?" => "{count} files selezionati non sono rimovibili. Cancellare il resto?", + "Are you sure you want to delete all selected files?" => "Sei sicuro che vuoi cancellare tutti i files selezionati?", + "Failed to delete {count} files/folders." => "Cancellazione fallita {count} files/cartelle.", + "A file or folder with that name already exists." => "Un file o cartella con questo nome già esiste.", + "Copy files here" => "Copia i files qui", + "Move files here" => "Sposta i files qui", + "Delete files" => "Cancella i files", + "Clear the Clipboard" => "Pulisci la Clipboard", + "Are you sure you want to delete all files in the Clipboard?" => "Sei sicuro che vuoi cancellare tutti i files dalla Clipboard?", + "Copy {count} files" => "Copio {count} files", + "Move {count} files" => "Sposto {count} files", + "Add to Clipboard" => "Aggiungi alla Clipboard", + "Inexistant or inaccessible folder." => "La cartella non esiste o è inacessibile.", + "New folder name:" => "Nuovo nome della cartella:", + "New file name:" => "Nuovo nome del file:", + "Upload" => "Carica", + "Refresh" => "Aggiorna", + "Settings" => "Preferenze", + "Maximize" => "Massimizza", + "About" => "Chi siamo", + "files" => "files", + "selected files" => "files selezionati", + "View:" => "Vista:", + "Show:" => "Mostra:", + "Order by:" => "Ordina per:", + "Thumbnails" => "Miniature", + "List" => "Lista", + "Name" => "Nome", + "Type" => "Tipo", + "Size" => "Grandezza", + "Date" => "Data", + "Descending" => "Discendente", + "Uploading file..." => "Carico file...", + "Loading image..." => "Caricamento immagine...", + "Loading folders..." => "Caricamento cartella...", + "Loading files..." => "Caricamento files...", + "New Subfolder..." => "Nuova sottocartella...", + "Rename..." => "Rinomina...", + "Delete" => "Elimina", + "OK" => "OK", + "Cancel" => "Cancella", + "Select" => "Seleziona", + "Select Thumbnail" => "Seleziona miniatura", + "Select Thumbnails" => "Seleziona miniature", + "View" => "Vista", + "Download" => "Scarica", + "Download files" => "Scarica files", + "Clipboard" => "Clipboard", + "Checking for new version..." => "Controllo nuova versione...", + "Unable to connect!" => "Connessione impossibile", + "Download version {version} now!" => "Prelevo la versione {version} adesso!", + "KCFinder is up to date!" => "KCFinder è aggiornato!", + "Licenses:" => "Licenze:", + "Attention" => "Attenzione", + "Question" => "Domanda", + "Yes" => "Si", + "No" => "No", + "You cannot rename the extension of files!" => "Non puoi rinominare l'estensione del file!", + "Uploading file {number} of {count}... {progress}" => "Caricmento del file {number} di {count}... {progress}", + "Failed to upload {filename}!" => "Il caricamento del file {filename} è fallito ", + "Close" => "Chiudi", + "Previous" => "Precedente", + "Next" => "Successivo", + "Confirmation" => "Conferma", + "Warning" => "Attenzione", +); diff --git a/lib/kcfinder/lang/ja.php b/lib/kcfinder/lang/ja.php new file mode 100644 index 0000000..bde1a72 --- /dev/null +++ b/lib/kcfinder/lang/ja.php @@ -0,0 +1,133 @@ + "Japanese", + '_native' => "日本語", + '_locale' => "ja_JP.UTF-8", // UNIX localization code + '_charset' => "utf-8", // Browser charset + + // Date time formats. See http://www.php.net/manual/en/function.strftime.php + '_dateTimeFull' => "%Y/%m/%d %H:%M", + '_dateTimeMid' => "%Y/%m/%d %H:%M", + '_dateTimeSmall' => "%Y/%m/%d %H:%M", + + "You don't have permissions to upload files." => "アップロード権限がありません。", + "You don't have permissions to browse server." => "サーバーを閲覧する権限がありません", + "Cannot move uploaded file to target folder." => "ファイルを移動できません。", + "Unknown error." => "原因不明のエラーです。", + "The uploaded file exceeds {size} bytes." => "アップロードしたファイルは {size} バイトを越えました。", + "The uploaded file was only partially uploaded." => "アップロードしたファイルは、一部のみ処理されました。", + "No file was uploaded." => "ファイルはありません。", + "Missing a temporary folder." => "tempフォルダが見つかりません。", + "Failed to write file." => "ファイルの書き込みに失敗しました。", + "Denied file extension." => "このファイルは扱えません。", + "Unknown image format/encoding." => "この画像ファイルの種別を判定できません。", + "The image is too big and/or cannot be resized." => "画像ファイルのサイズが大き過ぎます。", + "Cannot create {dir} folder." => "「{dir}」フォルダを作成できません。", + "Cannot rename the folder." => "フォルダ名を変更できません", + "Cannot write to upload folder." => "アップロードフォルダに書き込みできません。", + "Cannot read .htaccess" => ".htaccessが読み込めません。", + "Incorrect .htaccess file. Cannot rewrite it!" => "不正な .htaccess ファイルです。再編集できません!", + "Cannot read upload folder." => "アップロードフォルダを読み取れません。", + "Cannot access or create thumbnails folder." => "サムネイルフォルダにアクセス、または作成できません。", + "Cannot access or write to upload folder." => "アップロードフォルダにアクセス、または書き込みできません。", + "Please enter new folder name." => "新しいフォルダ名を入力して下さい。", + "Unallowable characters in folder name." => "フォルダ名に使用できない文字が含まれています。", + "Folder name shouldn't begins with '.'" => "フォルダ名は、'.'で開始しないで下さい。", + "Please enter new file name." => "新しいファイル名を入力して下さい。", + "Unallowable characters in file name." => "ファイル名に使用できない文字が含まれています。", + "File name shouldn't begins with '.'" => "ファイル名は「. 」で始めることはできません。", + "Are you sure you want to delete this file?" => "このファイルを本当に削除してもよろしいですか?", + "Are you sure you want to delete this folder and all its content?" => "このフォルダとフォルダ内の全てのコンテンツを本当に削除してもよろしいですか?", + "Non-existing directory type." => "存在しないディレクトリの種類です。", + "Undefined MIME types." => "定義されていないMIMEタイプです。", + "Fileinfo PECL extension is missing." => "Fileinfo PECL 拡張モジュールが見付かりません。", + "Opening fileinfo database failed." => "fileinfo データベースを開くのに失敗しました。", + "You can't upload such files." => "このようなファイルをアップロードできません。", + "The file '{file}' does not exist." => "ファイル「{file}」は存在しません。", + "Cannot read '{file}'." => "「{file}」を読み取れません。", + "Cannot copy '{file}'." => "「{file}」をコピーできません。", + "Cannot move '{file}'." => "「{file}」を移動できません。", + "Cannot delete '{file}'." => "「{file}」を削除できません。", + "Cannot delete the folder." => "フォルダを削除できません", + "Click to remove from the Clipboard" => "クリップボードから削除する", + "This file is already added to the Clipboard." => "このファイルは既にクリップボードに追加されています。", + "The files in the Clipboard are not readable." => "クリップボードからファイルを読み取れません", + "{count} files in the Clipboard are not readable. Do you want to copy the rest?" => "クリップボード内の {count} 個のファイルが読み取れません。残りをコピーしてもよろしいですか?", + "The files in the Clipboard are not movable." => "クリップボードからファイルを移動できません", + "{count} files in the Clipboard are not movable. Do you want to move the rest?" => "クリップボード内の {count} 個のファイルが移動できません。残りを移動してもよろしいですか?", + "The files in the Clipboard are not removable." => "クリップボードを初期化できません", + "{count} files in the Clipboard are not removable. Do you want to delete the rest?" => "クリップボード内の {count} 個のファイルが削除出来ません。残りを削除してもよろしいですか?", + "The selected files are not removable." => "選択したファイルは削除できません。", + "{count} selected files are not removable. Do you want to delete the rest?" => "選択された {count} 個のファイルは削除できません。残りを削除してもよろしいですか?", + "Are you sure you want to delete all selected files?" => "選択された全てのファイルを本当に削除してもよろしいですか?", + "Failed to delete {count} files/folders." => "{count} 個のファイル / フォルダの削除に失敗しました。", + "A file or folder with that name already exists." => "その名前のファイル、またはフォルダは既に存在します。", + "Copy files here" => "ここにコピー", + "Move files here" => "ここに移動", + "Delete files" => "これらを全て削除", + "Clear the Clipboard" => "クリップボードを初期化", + "Are you sure you want to delete all files in the Clipboard?" => "クリップボードに記憶した全てのファイルを実際に削除します。", + "Copy {count} files" => "ファイル({count}個)をここに複写", + "Move {count} files" => "ファイル({count}個)をここに移動", + "Add to Clipboard" => "クリップボードに記憶", + "Inexistant or inaccessible folder." => "存在しない、またはアクセスできないフォルダです。", + "New folder name:" => "フォルダ名(半角英数):", + "New file name:" => "ファイル名(半角英数):", + "Upload" => "アップロード", + "Refresh" => "再表示", + "Settings" => "表示設定", + "Maximize" => "最大化", + "About" => "About", + "files" => "ファイル", + "selected files" => "選択したファイル", + "View:" => "表示スタイル:", + "Show:" => "表示項目:", + "Order by:" => "表示順:", + "Thumbnails" => "サムネイル", + "List" => "リスト", + "Name" => "ファイル名", + "Type" => "タイプ", + "Size" => "サイズ", + "Date" => "日付", + "Descending" => "順序を反転", + "Uploading file..." => "ファイルをアップロード中", + "Loading image..." => "画像を読み込み中", + "Loading folders..." => "フォルダを読み込み中", + "Loading files..." => "読み込み中", + "New Subfolder..." => "フォルダを作る", + "Rename..." => "名前の変更", + "Delete" => "削除", + "OK" => "OK", + "Cancel" => "キャンセル", + "Select" => "このファイルを選択", + "Select Thumbnail" => "サムネイルを選択", + "Select Thumbnails" => "サムネイルを選択", + "View" => "プレビュー", + "Download" => "ダウンロード", + "Download files" => "ファイルをダウンロードする", + "Clipboard" => "クリップボード", + "Checking for new version..." => "新しいバージョンを確認中", + "Unable to connect!" => "接続できません", + "Download version {version} now!" => "新しいバージョン({version})をダウンロードできます", + "KCFinder is up to date!" => "KCFinderは最新です。", + "Licenses:" => "ライセンス", + "Attention" => "注意", + "Question" => "確認", + "Yes" => "はい", + "No" => "いいえ", + "You cannot rename the extension of files!" => "ファイルの拡張子を変更できませんでした", + "Uploading file {number} of {count}... {progress}" => "ファイルをアップロード中({number}/{count})... {progress}", + "Failed to upload {filename}!" => "{filename}のアップロードに失敗しました", +); diff --git a/lib/kcfinder/lang/lt.php b/lib/kcfinder/lang/lt.php new file mode 100644 index 0000000..dfa92d6 --- /dev/null +++ b/lib/kcfinder/lang/lt.php @@ -0,0 +1,132 @@ + + */ + +$lang = array( + + '_lang' => "Lithuanian", + '_native' => "Lietuvių", + '_locale' => "lt_LT.UTF-8", // UNIX localization code + '_charset' => "utf-8", // Browser charset + + // Date time formats. See http://www.php.net/manual/en/function.strftime.php + '_dateTimeFull' => "%F %T", + '_dateTimeMid' => "%F %T", + '_dateTimeSmall' => "%F %T", + + "You don't have permissions to upload files." => "Jūs neturite teisių įkelti failus", + "You don't have permissions to browse server." => "Jūs neturite teisių naršyti po failus", + "Cannot move uploaded file to target folder." => "Nepavyko įkelti failo į reikiamą katalogą.", + "Unknown error." => "Nežinoma klaida.", + "The uploaded file exceeds {size} bytes." => "Įkeliamas failas viršija {size} baitų(-us).", + "The uploaded file was only partially uploaded." => "Failas buvo tik dalinai įkeltas.", + "No file was uploaded." => "Failas nebuvo įkeltas.", + "Missing a temporary folder." => "Nėra laikino katalogo.", + "Failed to write file." => "Nepavyko įrašyti failo.", + "Denied file extension." => "Draudžiama įkelti šio tipo failus.", + "Unknown image format/encoding." => "Nežinomas paveikslėlio formatas/kodavimas.", + "The image is too big and/or cannot be resized." => "Paveikslėlis yra per didelis ir/arba negali būti sumažintas.", + "Cannot create {dir} folder." => "Nepavyko sukurti {dir} katalogo.", + "Cannot rename the folder." => "Nepavyko pervadinti katalogo.", + "Cannot write to upload folder." => "Nepavyko įrašyti į įkeliamų failų katalogą.", + "Cannot read .htaccess" => "Nepavyko nuskaityti .htaccess failo", + "Incorrect .htaccess file. Cannot rewrite it!" => "Blogas .htaccess failas. Nepavyko jo perrašyti", + "Cannot read upload folder." => "Nepavyko atidaryti įkeliamų failų katalogo.", + "Cannot access or create thumbnails folder." => "Nepavyko atidaryti ar sukurti sumažintų paveikslėlių katalogo.", + "Cannot access or write to upload folder." => "Nepavyko atidaryti ar įrašyti į įkeliamų failų katalogą.", + "Please enter new folder name." => "Įveskite katalogo pavadinimą.", + "Unallowable characters in folder name." => "Katalogo pavadinime yra neleistinų simbolių.", + "Folder name shouldn't begins with '.'" => "Katalogo pavadinimas negali prasidėti '.'", + "Please enter new file name." => "Įveskite failo pavadinimą.", + "Unallowable characters in file name." => "Failo pavadinime yra neleistinų simbolių", + "File name shouldn't begins with '.'" => "Failo pavadinimas negali prasidėti '.'", + "Are you sure you want to delete this file?" => "Ar tikrai ištrinti šį failą?", + "Are you sure you want to delete this folder and all its content?" => "Ar tikrai ištrinti šį katalogą su visu jo turiniu?", + "Non-existing directory type." => "Neegzistuojantis katalogo tipas.", + "Undefined MIME types." => "Nenurodytas MIME tipas.", + "Fileinfo PECL extension is missing." => "Trūksa PECL plėtinio Fileinfo", + "Opening fileinfo database failed." => "Nepavyko atidaryti Fileinfo duomenų bazės.", + "You can't upload such files." => "Negalima įkelti tokių failų.", + "The file '{file}' does not exist." => "Failas '{file}' neegzistuoja.", + "Cannot read '{file}'." => "Nepavyko atidaryti '{file}' failo.", + "Cannot copy '{file}'." => "Nepavyko nukopijuoti '{file}' failo.", + "Cannot move '{file}'." => "Nepavyko perkelti '{file}' failo.", + "Cannot delete '{file}'." => "Nepavyko ištrinti '{file}' failo.", + "Cannot delete the folder." => "Nepavyko ištrinti katalogo.", + "Click to remove from the Clipboard" => "Zum entfernen aus der Zwischenablage, hier klicken.", + "This file is already added to the Clipboard." => "Šis failas jau įkeltas į laikinąją atmintį.", + "The files in the Clipboard are not readable." => "Nepavyko nuskaityti failų iš laikinosios atminties.", + "{count} files in the Clipboard are not readable. Do you want to copy the rest?" => "Nepavyko atidaryti {count} failų(-ai) iš laikinosios atminties. Ar kopijuoti likusius?", + "The files in the Clipboard are not movable." => "Nepavyko perkelti failų iš laikinosios atminties.", + "{count} files in the Clipboard are not movable. Do you want to move the rest?" => "Nepavyko perkelti {count} failų(-ai) iš laikinosios atminties. Ar perkelti likusius?", + "The files in the Clipboard are not removable." => "Nepavyko perkelti failų iš laikinosios atminties.", + "{count} files in the Clipboard are not removable. Do you want to delete the rest?" => "Nepavyko ištrinti {count} failų(-ai) iš laikinosios atminties. Ar ištrinti likusius?", + "The selected files are not removable." => "Nepavyko perkelti pažymėtų failų.", + "{count} selected files are not removable. Do you want to delete the rest?" => "Nepavyko ištrinti {count} failų(-ai) iš laikinosios atminties. Ar ištrinti likusius?", + "Are you sure you want to delete all selected files?" => "Ar tikrai ištrinti visus pažymėtus failus?", + "Failed to delete {count} files/folders." => "Nepavyko ištrinti {count} failų/katalogų.", + "A file or folder with that name already exists." => "Failas arba katalogas tokiu pavadinimu jau egzistuoja.", + "Copy files here" => "Kopijuoti failus čia.", + "Move files here" => "Perkelti failus čia.", + "Delete files" => "Ištrinti failus.", + "Clear the Clipboard" => "Išvalyti laikinąją atmintį", + "Are you sure you want to delete all files in the Clipboard?" => "Ar tikrai ištrinti visus failus, esančius laikinojoje atmintyje?", + "Copy {count} files" => "Kopijuoti {count} failų(-us)", + "Move {count} files" => "Perkelti {count} failų(-us)", + "Add to Clipboard" => "Įkelti į laikinąją atmintį", + "Inexistant or inaccessible folder." => "Katalogas neegzistuoja arba yra neprieinamas.", + "New folder name:" => "Naujo katalogo pavadinimas:", + "New file name:" => "Naujo failo pavadinimas:", + "Upload" => "Įkelti", + "Refresh" => "Atnaujinti", + "Settings" => "Nustatymai", + "Maximize" => "Padidinti", + "About" => "Apie", + "files" => "Failai", + "selected files" => "Pasirinkti failus", + "View:" => "Peržiūra:", + "Show:" => "Rodyti:", + "Order by:" => "Rikiuoti:", + "Thumbnails" => "Sumažintos iliustracijos", + "List" => "Sąrašas", + "Name" => "Pavadinimas", + "Type" => "Tipas", + "Size" => "Dydis", + "Date" => "Data", + "Descending" => "Mažejančia tvarka", + "Uploading file..." => "Įkeliamas failas...", + "Loading image..." => "Kraunami paveikslėliai...", + "Loading folders..." => "Kraunami katalogai...", + "Loading files..." => "Kraunami failai...", + "New Subfolder..." => "Naujas katalogas...", + "Rename..." => "Pervadinti...", + "Delete" => "Ištrinti", + "OK" => "OK", + "Cancel" => "Atšaukti", + "Select" => "Pažymėti", + "Select Thumbnail" => "Pasirinkti sumažintą paveikslėlį", + "Select Thumbnails" => "Pasirinkti sumažintus paveikslėlius", + "View" => "Peržiūra", + "Download" => "Atsisiųsti", + "Download files" => "Atsisiųsti failus", + "Clipboard" => "Laikinoji atmintis", + "Checking for new version..." => "Tikrinama nauja versija...", + "Unable to connect!" => "Nepavyko prisijungti!", + "Download version {version} now!" => "Siųsti versiją {version} dabar!", + "KCFinder is up to date!" => "KCFinder yra naujausios versijos!", + "Licenses:" => "Licenzijos:", + "Attention" => "Dėmesio", + "Question" => "Klausimas", + "Yes" => "Taip", + "No" => "Ne", + "You cannot rename the extension of files!" => "Negalima keisti failų plėtinių!", + "Uploading file {number} of {count}... {progress}" => "Įkeliamas {number} failas iš {count}... {progress}", + "Failed to upload {filename}!" => "Nepavyko įkelti {filename}!", + "Close" => "Uždaryti", + "Previous" => "Ankstesnis", + "Next" => "Kitas", + "Confirmation" => "Patvirtinimas", + "Warning" => "Įspėjimas", +); diff --git a/lib/kcfinder/lang/lv.php b/lib/kcfinder/lang/lv.php new file mode 100644 index 0000000..d3abaab --- /dev/null +++ b/lib/kcfinder/lang/lv.php @@ -0,0 +1,127 @@ + "Latvian", + '_native' => "Latviešu", + '_locale' => "lv_LV.UTF-8", // UNIX localization code + '_charset' => "utf-8", // Browser charset + + // Date time formats. See http://www.php.net/manual/en/function.strftime.php + '_dateTimeFull' => "%A, %Y. gada %e. %B", + '_dateTimeMid' => "%a, %Y. %e. %b", + '_dateTimeSmall' => "%Y.%m.%d %H:%M", + + "You don't have permissions to upload files." => "Jums nav atļaujas, lai augšupielādētu failu.", + "You don't have permissions to browse server." => "Jums nav atļaujas pārlūkot serverī.", + "Cannot move uploaded file to target folder." => "Nevar augšupielādēt failu uz mērķa mapi.", + "Unknown error." => "Nezināma kļūda.", + "The uploaded file exceeds {size} bytes." => "Augšupielādētais fails pārsniedz {size} baitus.", + "The uploaded file was only partially uploaded." => "Augšupielādētais fails tika augšupielādēts tikai daļēji.", + "No file was uploaded." => "Neviens fails netika augšupielādēts.", + "Missing a temporary folder." => "Trūkst pagaidu mapē.", + "Failed to write file." => "Neizdevās ierakstīt failā.", + "Denied file extension." => "Liegta piekļuve faila paplašinājums.", + "Unknown image format/encoding." => "Nezināms attēlu formāts / kodējumu.", + "The image is too big and/or cannot be resized." => "Attēls ir pārāk liels un / vai izmērus nevar mainīt.", + "Cannot create {dir} folder." => "Nevar izveidot {dir} mapē.", + "Cannot rename the folder." => "Nevar pārdēvēt mapi.", + "Cannot write to upload folder." => "Nevar ierakstīt augšupielādes mape.", + "Cannot read .htaccess" => "Nevar lasīt failu .htaccess", + "Incorrect .htaccess file. Cannot rewrite it!" => "Nepareizs fails .htaccess būs jānoņem. Nevar pārrakstīt!", + "Cannot read upload folder." => "Nevar lasīt failu augšupielāde mapē.", + "Cannot access or create thumbnails folder." => "Nevar piekļūt vai izveidot sīktēlu mapei.", + "Cannot access or write to upload folder." => "Nevar piekļūt vai rakstīt augšupielādēt mapes.", + "Please enter new folder name." => "Lūdzu, ievadiet jaunu mapes nosaukumu.", + "Unallowable characters in folder name." => "Nepieļaujamas mapes nosaukuma rakstzīmes.", + "Folder name shouldn't begins with '.'" => "Mapes nosaukums nedrīkst sāk ar '.'", + "Please enter new file name." => "Lūdzu, ievadiet jaunu faila nosaukumu.", + "Unallowable characters in file name." => "Nepieļaujami rakstzīmes faila nosaukumu.", + "File name shouldn't begins with '.'" => "Faila nosaukums nedrīkst sāk ar '.'", + "Are you sure you want to delete this file?" => "Vai tiešām vēlaties izdzēst šo failu?", + "Are you sure you want to delete this folder and all its content?" => "Vai tiešām vēlaties izdzēst šo mapi un visu tās saturu?", + "Non-existing directory type." => "Minimāla direktorija tips.", + "Undefined MIME types." => "Nedefinēts MIME tipu.", + "Fileinfo PECL extension is missing." => "Trūkst faila paplašinājuma Fileinfo PECL.", + "Opening fileinfo database failed." => "Atverot fileinfo datu bāzi neizdevās.", + "You can't upload such files." => "Nevar augšupielādēt šo failu.", + "The file '{file}' does not exist." => "Fails' {file} 'nepastāv.", + "Cannot read '{file}'." => "Nevar nolasīt '{file}'.", + "Cannot copy '{file}'." => "Nevar kopēt '{file}'.", + "Cannot move '{file}'." => "Nevar pārvietot '{file}'.", + "Cannot delete '{file}'." => "Nevar izdzēst '{file}'.", + "Cannot delete the folder." => "Nevar izdzēst mapi.", + "Click to remove from the Clipboard" => "Noklikšķiniet, lai noņemtu no starpliktuves", + "This file is already added to the Clipboard." => "Šis fails jau ir pievienots starpliktuvē.", + "The files in the Clipboard are not readable." => "Failu starpliktuvē nav lasāms.", + "{count} files in the Clipboard are not readable. Do you want to copy the rest?" => "{count} failu starpliktuvē nav lasāms. Vai vēlaties kopēt visu?", + "The files in the Clipboard are not movable." => "Failu starpliktuvē nav pārvietojams.", + "{count} files in the Clipboard are not movable. Do you want to move the rest?" => "{count} failu starpliktuvē nav pārvietojams. Vai vēlaties pārvietot citur?", + "The files in the Clipboard are not removable." => "Failu starpliktuvē nav noņemami.", + "{count} files in the Clipboard are not removable. Do you want to delete the rest?" => "{count} failu starpliktuvē nav noņemami. Vai vēlaties dzēst visu?", + "The selected files are not removable." => "Atlasītie faili nav noņemama.", + "{count} selected files are not removable. Do you want to delete the rest?" => "{count} atlasītie faili nav noņemama. Vai vēlaties dzēst visu?", + "Are you sure you want to delete all selected files?" => "Vai tiešām vēlaties izdzēst visus atlasītos failus?", + "Failed to delete {count} files/folders." => "Neizdevās izdzēst {count} failus / mapes.", + "A file or folder with that name already exists." => "Fails vai mape ar šādu nosaukumu jau pastāv.", + "Copy files here" => "Kopēt failus šeit", + "Move files here" => "Pārvietot failus šeit", + "Delete files" => "Dzēst failus", + "Clear the Clipboard" => "Notīrīt starpliktuvi", + "Are you sure you want to delete all files in the Clipboard?" => "Vai tiešām vēlaties dzēst visus failus no starpliktuves? ", + "Copy {count} files" => "Kopēt {count} faili ", + "Move {count} files" => "Pārvietot {count} faili ", + "Add to Clipboard" => "Pievienot starpliktuvei ", + "Inexistant or inaccessible folder." => "Inexistant vai piekļūt mapei.", + "New folder name:" => "Jaunās mapes nosaukums:", + "New file name:" => "Jauns faila nosaukums:", + "Upload" => "Augšupielādēt", + "Refresh" => "Atsvaidzināt", + "Settings" => "Iestatījumi", + "Maximize" => "Maksimizēt", + "About" => "Par", + "files" => "faili", + "selected files" => "atlasītie faili", + "View:" => "Skatīt:", + "Show:" => "Rādīt:", + "Order by:" => "Kārtot pēc: ", + "Thumbnails" => "Sīktēli ", + "List" => "Saraksts ", + "Name" => "Nosaukums ", + "Type" => "Tips ", + "Size" => "Izmērs ", + "Date" => "Datums", + "Descending" => "Dilstošā secībā", + "Uploading file..." => "... faila augšupielāde", + "Loading image..." => "Ielādē attēlu...", + "Loading folders..." => "Ielādē mapes...", + "Loading files..." => "... failu ielāde", + "New Subfolder..." => "Jauna apakšmape...", + "Rename..." => "Pārdēvēt...", + "Delete" => "Dzēst", + "OK" => "Labi", + "Cancel" => "Atcelt", + "Select" => "Izvēlieties", + "Select Thumbnail" => "Izvēlieties sīktēlu", + "Select Thumbnails" => "Atlasiet sīktēlus", + "View" => "Skats", + "Download" => "Lejupielādēt", + "Download files" => "Lejupielādēt failus", + "Clipboard" => "Starpliktuve", + "Checking for new version..." => "... jaunās versijas pārbaude", + "Unable to connect!" => "Nevar izveidot savienojumu.", + "Download version {version} now!" => "Lejupielādēt versiju {version} tagad!", + "KCFinder is up to date!" => "KCFinder ir aktuāla!", + "Licenses:" => "Licences:", + "Attention" => "Uzmanību", + "Question" => "Jautājums", + "Yes" => "Jā", + "No" => "Nr.", + "You cannot rename the extension of files!" => "Paplašinājums nevar pārdēvēt failu!", + "Uploading file {number} of {count}... {progress}" => "Augšupielādējot failu {number} no {count}... {progress}", + "Failed to upload {filename}!" => "Neizdevās augšupielādēt {filename}!", +); diff --git a/lib/kcfinder/lang/nl.php b/lib/kcfinder/lang/nl.php new file mode 100644 index 0000000..6d3e9a3 --- /dev/null +++ b/lib/kcfinder/lang/nl.php @@ -0,0 +1,133 @@ + + * update: Richard Leurs + */ + +$lang = array( + + '_lang' => "Dutch", + '_native' => "Nederlands", + '_locale' => "nl_NL.UTF-8", // UNIX localization code + '_charset' => "utf-8", // Browser charset + + // Date time formats. See http://www.php.net/manual/en/function.strftime.php + '_dateTimeFull' => "%A, %e.%B.%Y %H:%M", + '_dateTimeMid' => "%a %e %b %Y %H:%M", + '_dateTimeSmall' => "%d/%m/%Y %H:%M", + + "You don't have permissions to upload files." => "U heeft geen toestemming om bestanden te uploaden.", + "You don't have permissions to browse server." => "U heeft geen toegang tot de server.", + "Cannot move uploaded file to target folder." => "Het te uploaden bestand kon niet naar de doelmap verplaatst worden.", + "Unknown error." => "Onbekende foutmelding.", + "The uploaded file exceeds {size} bytes." => "De bestandsgrootte van het bestand overschrijdt de limiet {size} bytes.", + "The uploaded file was only partially uploaded." => "Het te uploaden bestand is slechts gedeeltelijk geupload.", + "No file was uploaded." => "Er is geen bestand geupload.", + "Missing a temporary folder." => "Een tijdelijke map ontbreekt.", + "Failed to write file." => "Poging tot schrijven van bestand is mislukt.", + "Denied file extension." => "De extensie van dit bestand is niet toegestaan.", + "Unknown image format/encoding." => "Onbekende afbeeldingsformaats/-codering.", + "The image is too big and/or cannot be resized." => "De afbeelding is te groot en/of de grootte kan niet aangepast worden.", + "Cannot create {dir} folder." => "Kan de map {dir} niet aanmaken.", + "Cannot rename the folder." => "De map kan niet hernoemd worden.", + "Cannot write to upload folder." => "Kan niet naar de uploadmap schrijven.", + "Cannot read .htaccess" => "Kan .htaccess niet lezen.", + "Incorrect .htaccess file. Cannot rewrite it!" => "Verkeerd .htaccess bestand. Bestand kan niet herschreven worden!", + "Cannot read upload folder." => "Uploadmap kan niet uitgelezen worden.", + "Cannot access or create thumbnails folder." => "Het is niet mogelijk om een miniatuurweergaven map aan te maken of te benaderen.", + "Cannot access or write to upload folder." => "Het is niet mogelijk om in de uploadmap te schrijven of deze te benaderen.", + "Please enter new folder name." => "Vul a.u.b. een nieuwe mapnaam in.", + "Unallowable characters in folder name." => "Er zijn niet toegestane karakters gebruikt in de mapnaam.", + "Folder name shouldn't begins with '.'" => "Een mapnaam mag niet met '.' beginnen.", + "Please enter new file name." => "Vul a.u.b. een nieuwe bestandsnaam in.", + "Unallowable characters in file name." => "Er zijn niet toegestane karakters gebruikt in de bestandsnaam.", + "File name shouldn't begins with '.'" => "Een bestandsnaam mag niet met '.' beginnen.", + "Are you sure you want to delete this file?" => "Weet u zeker dat u dit bestand wilt verwijderen?", + "Are you sure you want to delete this folder and all its content?" => "Weet u zeker dat u deze map en alle inhoud ervan wilt verwijderen?", + "Non-existing directory type." => "Het maptype bestaat niet.", + "Undefined MIME types." => "Onbekend MIME type.", + "Fileinfo PECL extension is missing." => "Bestandsinformatie PECL extensie ontbreekt.", + "Opening fileinfo database failed." => "Openen van bestandsinformatie database is mislukt.", + "You can't upload such files." => "Uploaden van dergelijke bestanden is niet mogelijk.", + "The file '{file}' does not exist." => "Het bestand '{file}' bestaat niet.", + "Cannot read '{file}'." => "Kan bestand '{file}' niet lezen.", + "Cannot copy '{file}'." => "Kan bestand '{file}' niet kopiëren.", + "Cannot move '{file}'." => "Kan bestand '{file}' niet verplaatsen.", + "Cannot delete '{file}'." => "Kan bestand '{file}' niet verwijderen.", + "Cannot delete the folder." => "De map kan niet verwijderd worden.", + "Click to remove from the Clipboard" => "Klik om te verwijderen van het klembord.", + "This file is already added to the Clipboard." => "Dit bestand was reeds toegevoegd aan het klembord.", + "The files in the Clipboard are not readable." => "De bestanden op het klembord kunnen niet gelezen worden.", + "{count} files in the Clipboard are not readable. Do you want to copy the rest?" => "{count} bestanden op het klembord zijn niet leesbaar. Wilt u de rest toch kopiëren?", + "The files in the Clipboard are not movable." => "De bestanden op het klembord kunnen niet verplaatst worden.", + "{count} files in the Clipboard are not movable. Do you want to move the rest?" => "{count} bestanden op het klembord kunnen niet verplaatst worden. Wilt u de rest toch verplaatsen?", + "The files in the Clipboard are not removable." => "De bestanden op het klembord kunnen niet verwijderd worden.", + "{count} files in the Clipboard are not removable. Do you want to delete the rest?" => "{count} bestanden op het klembord kunnen niet verwijderd worden. Wilt u de rest toch verwijderen?", + "The selected files are not removable." => "De geselecteerde bestanden kunnen niet verwijderd worden.", + "{count} selected files are not removable. Do you want to delete the rest?" => "{count} geselecteerde bestanden kunnen niet verwijderd worden. Wilt u de rest toch verwijderen?", + "Are you sure you want to delete all selected files?" => "Weet u zeker dat u alle geselcteerde bestanden wilt verwijderen?", + "Failed to delete {count} files/folders." => "{count} bestanden/mappen konden niet verwijderd worden.", + "A file or folder with that name already exists." => "Er bestaat reeds een bestand of map met die naam.", + "Copy files here" => "Kopieer bestanden hierheen", + "Move files here" => "Verplaats bestanden hierheen", + "Delete files" => "Verwijder bestanden", + "Clear the Clipboard" => "Klembord leegmaken", + "Are you sure you want to delete all files in the Clipboard?" => "Weet u zeker dat u alle bestanden op het klembord wilt verwijderen?", + "Copy {count} files" => "Kopieer {count} bestanden", + "Move {count} files" => "Verplaats {count} bestanden", + "Add to Clipboard" => "Voeg toe aan klembord", + "Inexistant or inaccessible folder." => "Map bestaat niet of kon niet worden benaderd.", + "New folder name:" => "Nieuwe mapnaam:", + "New file name:" => "Nieuwe bestandsnaam:", + "Upload" => "Upload", + "Refresh" => "Verversen", + "Settings" => "Instellingen", + "Maximize" => "Maximaliseren", + "About" => "Over", + "files" => "bestanden", + "selected files" => "geselecteerde bestanden", + "View:" => "Beeld:", + "Show:" => "Weergeven:", + "Order by:" => "Sorteren op:", + "Thumbnails" => "Miniatuurweergaven", + "List" => "Lijst", + "Name" => "Naam", + "Type" => "Type", + "Size" => "Grootte", + "Date" => "Datum", + "Descending" => "Aflopend", + "Uploading file..." => "Bestand uploaden...", + "Loading image..." => "Afbeelding wordt geladen...", + "Loading folders..." => "Mappen worden geladen...", + "Loading files..." => "Bestanden worden geladen ...", + "New Subfolder..." => "Nieuwe submap...", + "Rename..." => "Hernoemen...", + "Delete" => "Verwijderen", + "OK" => "OK", + "Cancel" => "Annuleren", + "Select" => "Selecteer", + "Select Thumbnail" => "Selecteer miniatuurweergave", + "Select Thumbnails" => "Kies miniatuurweergaven", + "View" => "Beeld", + "Download" => "Download", + "Download files" => "Bestanden downloaden", + "Clipboard" => "Klembord", + "Checking for new version..." => "Zoeken naar een nieuwere versie...", + "Unable to connect!" => "Kan geen verbinding maken!", + "Download version {version} now!" => "Download versie {version} nu!", + "KCFinder is up to date!" => "KCFinder is up to date!", + "Licenses:" => "Licenties:", + "Attention" => "Attentie", + "Question" => "Vraag", + "Yes" => "Ja", + "No" => "Nee", + "You cannot rename the extension of files!" => "U kan de extensie van bestanden niet hernoemen!", + "Uploading file {number} of {count}... {progress}" => "Bestand {number} van de {count} aan het uploaden... {progress}", + "Failed to upload {filename}!" => "Uploaden van {filename} mislukt!", + "Close" => "Vorige", + "Previous" => "Terug", + "Next" => "Volgende", + "Confirmation" => "Bevestiging", + "Warning" => "Waarschuwing", +); diff --git a/lib/kcfinder/lang/no.php b/lib/kcfinder/lang/no.php new file mode 100644 index 0000000..3482ef5 --- /dev/null +++ b/lib/kcfinder/lang/no.php @@ -0,0 +1,242 @@ + "Norwegian", + '_native' => "Norsk", + '_locale' => "nb_NO.UTF-8", // UNIX localization code + '_charset' => "utf-8", // Browser charset + + // Date time formats. See http://www.php.net/manual/en/function.strftime.php + '_dateTimeFull' => "%A, %e %B, %Y %H:%M", + '_dateTimeMid' => "%a %e %b %Y %H:%M", + '_dateTimeSmall' => "%d.%m.%Y %H:%M", + + "You don't have permissions to upload files." => + "Du har ikke tilgang til å laste opp filer", + + "You don't have permissions to browse server." => + "Du har ikke tilgang til å bla igjennom server", + + "Cannot move uploaded file to target folder." => + "Kan ikke flytte fil til denne mappen", + + "Unknown error." => + "Ukjent feil.", + + "The uploaded file exceeds {size} bytes." => + "Filen er for stor.", + + "The uploaded file was only partially uploaded." => + "Opplastning delvis fullført.", + + "No file was uploaded." => + "Ingen filer lastet opp", + + "Missing a temporary folder." => + "Mangler midlertidig mappe.", + + "Failed to write file." => + "Feil ved skriving til fil.", + + "Denied file extension." => + "Feil filformat", + + "Unknown image format/encoding." => + "Ukjent bildeformat.", + + "The image is too big and/or cannot be resized." => + "Bildet er for stort eller kan ikke skaleres ned.", + + "Cannot create {dir} folder." => + "Kan ikke opprette mappe.", + + "Cannot write to upload folder." => + "Ingen tilgang til å skrive til denne mappen.", + + "Cannot read .htaccess" => + "Kan ikke lese .htaccess.", + + "Incorrect .htaccess file. Cannot rewrite it!" => + "Feil! Kan ikke skrive til denne filen", + + "Cannot read upload folder." => + "Kan ikke lese denne mappen.", + + "Cannot access or create thumbnails folder." => + "Ikke tilgang til mappen for miniatyrbilder", + + "Cannot access or write to upload folder." => + "Ikke tilgang til opplastningsmappe.", + + "Please enter new folder name." => + "Skriv inn nytt navn til denne mappen.", + + "Unallowable characters in folder name." => + "Ulovlige tegn i mappenavn.", + + "Folder name shouldn't begins with '.'" => + "Mappenavnet kan ikke begynne med '.'", + + "Please enter new file name." => + "Skriv inn nytt filnavn ", + + "Unallowable characters in file name." => + "Ulovlige tegn i filnavn.", + + "File name shouldn't begins with '.'" => + "Filnavn kan ikke starte med '.'", + + "Are you sure you want to delete this file?" => + "Er du sikker på at du vil slette denne filen?", + + "Are you sure you want to delete this folder and all its content?" => + "Er du sikker på at du vil slette denne mappen og innholdet i den?", + + "Inexistant or inaccessible folder." => + "Kan ikke lese mappe.", + + "Undefined MIME types." => + "Undefined MIME types.", + + "Fileinfo PECL extension is missing." => + "Fileinfo PECL extension is missing.", + + "Opening fileinfo database failed." => + "Opening fileinfo database failed", + + "You can't upload such files." => + "Du kan ikke laste opp denne typen filer", + + "The file '{file}' does not exist." => + "Filen '{file}' finnes ikke.", + + "Cannot read '{file}'." => + "Kan ikke lese '{file}'.", + + "Cannot copy '{file}'." => + "Kan ikke kopiere '{file}'.", + + "Cannot move '{file}'." => + "Kan ikke flytte '{file}'.", + + "Cannot delete '{file}'." => + "Kan ikke slette '{file}'.", + + "Click to remove from the Clipboard" => + "Klikk for å fjerne fra utklippstavle", + + "This file is already added to the Clipboard." => + "Filen finnes allerede på utklippstavlen", + + "Copy files here" => + "Kopier filene til ;", + + "Move files here" => + "Flytt filene til ;", + + "Delete files" => + "Slett filer", + + "Clear the Clipboard" => + "Tøm utklippstavle", + + "Are you sure you want to delete all files in the Clipboard?" => + "Er du sikker på at du vil slette alle filene i utklippstavlen?", + + "Copy {count} files" => + "Kopier {count} filer", + + "Move {count} files" => + "Flytt {count} filer ", + + "Add to Clipboard" => + "Legg til i utklippstavle", + + "New folder name:" => "Nytt mappenavn:", + "New file name:" => "Nytt filnavn:", + + "Upload" => "Last opp", + "Refresh" => "Oppdater", + "Settings" => "Innstillinger", + "Maximize" => "Maksimer", + "About" => "Om/Hjelp", + "files" => "filer", + "View:" => "Vis:", + "Show:" => "Vis:", + "Order by:" => "Sorter etter:", + "Thumbnails" => "Miniatyrbilder", + "List" => "Liste", + "Name" => "Navn", + "Size" => "Størrelse", + "Date" => "Dato", + "Descending" => "Synkende", + "Uploading file..." => "Laster opp fil...", + "Loading image..." => "Laster bilde...", + "Loading folders..." => "Laster mapper...", + "Loading files..." => "Laster filer...", + "New Subfolder..." => "Ny undermappe...", + "Rename..." => "Endre navn...", + "Delete" => "Slett", + "OK" => "OK", + "Cancel" => "Avbryt", + "Select" => "Velg", + "Select Thumbnail" => "Velg miniatyrbilde", + "View" => "Vis", + "Download" => "Last ned", + "Clipboard" => "Utklippstavle", + + // VERSION 2 NEW LABELS + + "Cannot rename the folder." => + "Kan ikke endre navnet på mappen.", + + "Non-existing directory type." => + "Denne finnes ikke.", + + "Cannot delete the folder." => + "Kan ikke slette mappe.", + + "The files in the Clipboard are not readable." => + "Kan ikke lese filene i utklippstavlen.", + + "{count} files in the Clipboard are not readable. Do you want to copy the rest?" => + "{count} filer i utklippstavlen kan ikke leses, ønsker du kopiere resten av filene?", + + "The files in the Clipboard are not movable." => + "Filene i utklippstavlen kan ikke flyttes", + + "{count} files in the Clipboard are not movable. Do you want to move the rest?" => + "{count} filer i utklippstavlen kan ikke flyttes, ønsker du å flytte resten?", + + "The files in the Clipboard are not removable." => + "Filene i utklippstavlen kan ikke flyttes.", + + "{count} files in the Clipboard are not removable. Do you want to delete the rest?" => + "{count} filer i utklippstavlen kan ikke flyttes, ønsker du å flytte resten?", + + "The selected files are not removable." => + "Merkede filer kan ikke flyttes.", + + "{count} selected files are not removable. Do you want to delete the rest?" => + "{count} filer kan ikke flyttes, ønsker du å flytte resten?", + + "Are you sure you want to delete all selected files?" => + "Er du sikker på at du ønsker å slette alle merkede filer?", + + "Failed to delete {count} files/folders." => + "Feil ved sletting av {count} filer/mapper.", + + "A file or folder with that name already exists." => + "En fil eller mappe finnes allerede med dette navnet", + + "selected files" => "merkede filer", + "Type" => "Type", + "Select Thumbnails" => "Velg miniatyrbilde", + "Download files" => "Last ned filer", +); diff --git a/lib/kcfinder/lang/pl.php b/lib/kcfinder/lang/pl.php new file mode 100644 index 0000000..afbe644 --- /dev/null +++ b/lib/kcfinder/lang/pl.php @@ -0,0 +1,127 @@ + "Polish", + '_native' => "Polski", + '_locale' => "pl_PL.UTF-8", // UNIX localization code + '_charset' => "utf-8", // Browser charset + + // Date time formats. See http://www.php.net/manual/en/function.strftime.php + '_dateTimeFull' => "%A, %e %B, %Y %H:%M", + '_dateTimeMid' => "%a %e %b %Y %H:%M", + '_dateTimeSmall' => "%d.%m.%Y %H:%M", + + "You don't have permissions to upload files." => "Nie masz zezwolenia na wysyłanie plików.", + "You don't have permissions to browse server." => "Nie masz zezwolenia na przeglądanie serwera.", + "Cannot move uploaded file to target folder." => "Nie można przenieść wysłanego pliku do folderu plików wysłanych.", + "Unknown error." => "Nieokreślony błąd.", + "The uploaded file exceeds {size} bytes." => "Wysyłany plik przekroczył rozmiar {size} bajtów", + "The uploaded file was only partially uploaded." => "Wysyłany plik nie został przesłany w całości.", + "No file was uploaded." => "Żaden plik nie został przesłany", + "Missing a temporary folder." => "Brak katalogu domyślnego.", + "Failed to write file." => "Błąd zapisu pliku.", + "Denied file extension." => "Niedozwolone rozszerzenie pliku.", + "Unknown image format/encoding." => "Nie znany format/kodowanie pliku.", + "The image is too big and/or cannot be resized." => "Obraz jest zbyt duży i/lub nie może zostać zmieniony jego rozmiar.", + "Cannot create {dir} folder." => "Nie można utworzyć katalogu {dir}.", + "Cannot rename the folder." => "Nie można zmienić nazwy katalogu.", + "Cannot write to upload folder." => "Nie można zapisywać do katalogu plików wysłanych.", + "Cannot read .htaccess" => "Nie można odczytać pliku .htaccess", + "Incorrect .htaccess file. Cannot rewrite it!" => "Nie prawidłowy plik .htaccess. Nie można go zapisać!", + "Cannot read upload folder." => "Nie można odczytać katalogu plików wysłanych.", + "Cannot access or create thumbnails folder." => "Nie ma dostępu lub nie można utworzyć katalogu miniatur.", + "Cannot access or write to upload folder." => "Nie ma dostępu lub nie można zapisywać do katalogu plików wysłanych.", + "Please enter new folder name." => "Proszę podać nową nazwę katalogu.", + "Unallowable characters in folder name." => "Niedozwolony znak w nazwie folderu.", + "Folder name shouldn't begins with '.'" => "Nazwa katalogu nie może zaczynać się od '.'", + "Please enter new file name." => "Proszę podać nową nazwę pliku", + "Unallowable characters in file name." => "Nie dozwolony znak w nazwie pliku.", + "File name shouldn't begins with '.'" => "Nazwa pliku nie powinna zaczynać się od '.'", + "Are you sure you want to delete this file?" => "Czy jesteś pewien, że chcesz skasować ten plik?", + "Are you sure you want to delete this folder and all its content?" => "Czy jesteś pewien, że chcesz skasować ten katalog i jego zawartość?", + "Non-existing directory type." => "Nie istniejący katalog.", + "Undefined MIME types." => "Niezidentyfikowany typ MIME.", + "Fileinfo PECL extension is missing." => "Brak rozszerzenia Fileinfo PECL.", + "Opening fileinfo database failed." => "Otwieranie bazy danych fileinfo nie udane.", + "You can't upload such files." => "Nie możesz wysyłać plików tego typu.", + "The file '{file}' does not exist." => "Plik {file} nie istnieje.", + "Cannot read '{file}'." => "Nie można odczytać pliku '{file}'.", + "Cannot copy '{file}'." => "Nie można skopiować pliku '{file}'.", + "Cannot move '{file}'." => "Nie można przenieść pliku '{file}'.", + "Cannot delete '{file}'." => "Nie można usunąć pliku '{file}'.", + "Cannot delete the folder." => "Nie można usunąć katalogu.", + "Click to remove from the Clipboard" => "Kliknij aby usunąć ze Schowka", + "This file is already added to the Clipboard." => "Ten plik już został dodany do Schowka.", + "The files in the Clipboard are not readable." => "Pliki w Schowku nie mogą zostać odczytane.", + "{count} files in the Clipboard are not readable. Do you want to copy the rest?" => "{count} plik(i/ów) ze Schowka nie może zostać odczytanych. Czy chcesz skopiować pozostałe?", + "The files in the Clipboard are not movable." => "Pliki w Schowku nie mogą zostać przeniesione.", + "{count} files in the Clipboard are not movable. Do you want to move the rest?" => "{count} plik(i/ów) ze Schowka nie może zostać przeniesionych. Czy chcesz przenieść pozostałe?", + "The files in the Clipboard are not removable." => "Nie można usunąć plików ze Schowka.", + "{count} files in the Clipboard are not removable. Do you want to delete the rest?" => "{count} plik(i/ów) ze Schowka nie może zostać usunięty(ch). Czy usunąć pozostałe?", + "The selected files are not removable." => "Wybrane pliki nie mogą zostać usunięte.", + "{count} selected files are not removable. Do you want to delete the rest?" => "{count} wybrany(ch) plików nie może zostać usunięte. Czy usunąć pozostałe?", + "Are you sure you want to delete all selected files?" => "Czy jesteś pewien że, chcesz usunąć wszystkie wybrane pliki?", + "Failed to delete {count} files/folders." => "Nie udało się usunąć {count} plik(i/ów) / folder(u/ów).", + "A file or folder with that name already exists." => "Plik lub katalog o tej nazwie już istnieje.", + "Copy files here" => "Kopiuj pliki tutaj", + "Move files here" => "Przenieś pliki tutaj", + "Delete files" => "Usuń pliki", + "Clear the Clipboard" => "Wyczyść Schowek", + "Are you sure you want to delete all files in the Clipboard?" => "Czy jesteś pewien, że chcesz usunąć wszystkie pliki ze schowka?", + "Copy {count} files" => "Kopiowanie {count} plików", + "Move {count} files" => "Przenoszenie {count} plików", + "Add to Clipboard" => "Dodaj do Schowka", + "Inexistant or inaccessible folder." => "Nieistniejący lub niedostępny folder.", + "New folder name:" => "Nazwa nowego katalogu:", + "New file name:" => "Nowa nazwa pliku:", + "Upload" => "Wyślij", + "Refresh" => "Odśwież", + "Settings" => "Ustawienia", + "Maximize" => "Maksymalizuj", + "About" => "O...", + "files" => "pliki", + "selected files" => "wybrane pliki", + "View:" => "Widok:", + "Show:" => "Pokaż:", + "Order by:" => "Sortuj według:", + "Thumbnails" => "Miniatury", + "List" => "Lista", + "Name" => "Nazwa", + "Type" => "Typ", + "Size" => "Rozmiar", + "Date" => "Data", + "Descending" => "Malejąco", + "Uploading file..." => "Wysyłanie pliku...", + "Loading image..." => "Ładowanie obrazu...", + "Loading folders..." => "Ładowanie katalogów...", + "Loading files..." => "Ładowanie plików...", + "New Subfolder..." => "Nowy pod-katalog...", + "Rename..." => "Zmień nazwę...", + "Delete" => "Usuń", + "OK" => "OK", + "Cancel" => "Anuluj", + "Select" => "Wybierz", + "Select Thumbnail" => "Wybierz miniaturę", + "Select Thumbnails" => "Wybierz miniatury", + "View" => "Podgląd", + "Download" => "Pobierz", + "Download files" => "Pobierz pliki", + "Clipboard" => "Schowek", + "Checking for new version..." => "Sprawdzanie najnowszej dostępnej wersji ...", + "Unable to connect!" => "Nie udało się nawiązać połączenia!", + "Download version {version} now!" => "Pobierz wersję {version}.", + "KCFinder is up to date!" => "Korzystasz z najnowszej wersji KCFinder!", + "Licenses:" => "Licencja:", + "Attention" => "Uwaga", + "Question" => "Pytanie", + "Yes" => "Tak", + "No" => "Nie", + "You cannot rename the extension of files!" => "Nie możesz zmienić rozszerzeń plików!", + "Uploading file {number} of {count}... {progress}" => "Wysyłanie pliku nr {number} spośród {count} ... {progress}", + "Failed to upload {filename}!" => "Wysyłanie pliku {filename} nie powiodło się!", +); diff --git a/lib/kcfinder/lang/pt-br.php b/lib/kcfinder/lang/pt-br.php new file mode 100644 index 0000000..4acdec5 --- /dev/null +++ b/lib/kcfinder/lang/pt-br.php @@ -0,0 +1,130 @@ + "Brazilian Portuguese", + '_native' => "Português do Brasil", + '_locale' => "pt_BR.UTF-8", // UNIX localization code + '_charset' => "utf-8", // Browser charset + + // Date time formats. See http://www.php.net/manual/en/function.strftime.php + '_dateTimeFull' => "%A, %e %B, %Y %H:%M", + '_dateTimeMid' => "%a %e %b %Y %H:%M", + '_dateTimeSmall' => "%d.%m.%Y %H:%M", + + "You don't have permissions to upload files." => "Você não tem permissões para fazer upload de arquivos.", + "You don't have permissions to browse server." => "Você não tem permissões para procurar no servidor.", + "Cannot move uploaded file to target folder." => "Não é possível mover o arquivo enviado para a pasta de destino.", + "Unknown error." => "Erro desconhecido.", + "The uploaded file exceeds {size} bytes." => "O arquivo enviado excede {size} bytes.", + "The uploaded file was only partially uploaded." => "O arquivo enviado foi apenas parcialmente carregado.", + "No file was uploaded." => "Nenhum arquivo foi transferido.", + "Missing a temporary folder." => "Faltando uma pasta temporária.", + "Failed to write file." => "Falha ao gravar arquivo.", + "Denied file extension." => "Extensão de arquivo não permitida.", + "Unknown image format/encoding." => "Formato de imagem desconhecido/codificação.", + "The image is too big and/or cannot be resized." => "A imagem é muito grande e/ou não pode ser redimensionada.", + "Cannot create {dir} folder." => "Não é possível criar pasta em '{dir}'.", + "Cannot rename the folder." => "Não é possível renomear a pasta.", + "Cannot write to upload folder." => "Não é possível salvar na pasta.", + "Cannot read .htaccess" => "Não é possível ler '.htaccess'.", + "Incorrect .htaccess file. Cannot rewrite it!" => "Arquivo '.htaccess' incorreto. Não é possível alterar.", + "Cannot read upload folder." => "Não é possível ler a pasta de upload.", + "Cannot access or create thumbnails folder." => "Não é possível acessar ou criar pasta de miniaturas.", + "Cannot access or write to upload folder." => "Não é possível acessar ou salvar para a pasta.", + "Please enter new folder name." => "Por favor, digite o nome da nova pasta.", + "Unallowable characters in folder name." => "Caracteres no nome da pasta não Autorizado.", + "Folder name shouldn't begins with '.'" => "Nome da pasta não deve começar com '.'.", + "Please enter new file name." => "Por favor, digite o novo nome de arquivo.", + "Unallowable characters in file name." => "Caracteres no nome do arquivo não Autorizado.", + "File name shouldn't begins with '.'" => "O nome da pasta não deve começar por '.'.", + "Are you sure you want to delete this file?" => "Tem a certeza de que deseja excluir este arquivo?", + "Are you sure you want to delete this folder and all its content?" => "Tem a certeza de que deseja excluir esta pasta e todo o seu conte�do?", + "Non-existing directory type." => "Tipo de diretório não existente.", + "Undefined MIME types." => "Tipos MIME indefinidos.", + "Fileinfo PECL extension is missing." => "Está faltando Informações do arquivo extensão PECL.", + "Opening fileinfo database failed." => "Abrir banco de dados de fileinfo falhou.", + "You can't upload such files." => "Você não pode enviar esses arquivos.", + "The file '{file}' does not exist." => "O arquivo '{file}' não existe.", + "Cannot read '{file}'." => "Não é possível ler '{file}'.", + "Cannot copy '{file}'." => "Não é possível copiar '{file}'.", + "Cannot move '{file}'." => "Não é possível mover '{file}'.", + "Cannot delete '{file}'." => "Não é possível deletar '{file}'.", + "Cannot delete the folder." => "Não é possível excluir a pasta.", + "Click to remove from the Clipboard" => "Clique para remover da área de transferência", + "This file is already added to the Clipboard." => "Este arquivo já foi adicionado à área de transferência.", + "The files in the Clipboard are not readable." => "Os arquivos da área de transferência não podem ser lidos.", + "{count} files in the Clipboard are not readable. Do you want to copy the rest?" => "{count} arquivos da área de transferência não podem ser lidos. Você deseja copiar o resto?", + "The files in the Clipboard are not movable." => "Os arquivos da área de transferência não podem ser removidos.", + "{count} files in the Clipboard are not movable. Do you want to move the rest?" => "{count} arquivos da área de transferência não podem ser movidos. Você deseja mover o resto?", + "The files in the Clipboard are not removable." => "Os arquivos da área de transferência não podem ser removidos.", + "{count} files in the Clipboard are not removable. Do you want to delete the rest?" => "{count} arquivos da área de transferência não são removíveis. Você deseja excluir o restante?", + "The selected files are not removable." => "Os arquivos selecionados não são removíveis.", + "{count} selected files are not removable. Do you want to delete the rest?" => "{count} arquivos selecionados não são removíveis. Você deseja excluir o restante?", + "Are you sure you want to delete all selected files?" => "Tem a certeza de que deseja excluir todos os arquivos selecionados?", + "Failed to delete {count} files/folders." => "Não conseguiu excluir {count} arquivos/pastas.", + "A file or folder with that name already exists." => "Já existe um arquivo ou pasta com esse nome.", + "Copy files here" => "Copiar arquivos aqui", + "Move files here" => "Mover arquivos aqui", + "Delete files" => "Deletar arquivos", + "Clear the Clipboard" => "Limpar a área de transferência", + "Are you sure you want to delete all files in the Clipboard?" => "Tem a certeza de que deseja excluir todos os arquivos da área de transferência?", + "Copy {count} files" => "Copiar {count} arquivos", + "Move {count} files" => "Mover {count} arquivos", + "Add to Clipboard" => "Adicionar à área de transferência", + "Inexistant or inaccessible folder." => "Pasta inacessível ou inexistente.", + "New folder name:" => "Nome da nova pasta:", + "New file name:" => "Novo nome do arquivo:", + "Upload" => "Enviar arquivo", + "Refresh" => "Atualizar", + "Settings" => "Configurações", + "Maximize" => "Maximizar", + "About" => "Sobre", + "files" => "Arquivos", + "selected files" => "arquivos selecionados", + "View:" => "Exibir:", + "Show:" => "Mostrar:", + "Order by:" => "Ordenar por:", + "Thumbnails" => "Miniaturas", + "List" => "Lista", + "Name" => "Nome", + "Type" => "Tipo", + "Size" => "Tamanho", + "Date" => "Data", + "Descending" => "Descendente", + "Uploading file..." => "Carregando arquivo...", + "Loading image..." => "Carregando imagem...", + "Loading folders..." => "Carregando pastas...", + "Loading files..." => "Carregando arquivos...", + "New Subfolder..." => "Nova subpasta...", + "Rename..." => "Renomear...", + "Delete" => "Excluir", + "OK" => "OK", + "Cancel" => "Cancelar", + "Select" => "Selecionar", + "Select Thumbnail" => "Selecionar miniatura", + "Select Thumbnails" => "Selecionar miniaturas", + "View" => "Exibir", + "Download" => "Download", + "Download files" => "Baixar arquivos", + "Clipboard" => "área de transferência", + "Checking for new version..." => "Checando por nova versão...", + "Unable to connect!" => "Não foi possível conectar!", + "Download version {version} now!" => "Baixe a versão {version} agora!", + "KCFinder is up to date!" => "KCFinder está atualizado!", + "Licenses:" => "Licenças", + "Attention" => "Atenção", + "Question" => "Pergunta", + "Yes" => "Sim", + "No" => "Não", + "You cannot rename the extension of files!" => "Você não pode renomear a extensão de arquivos!", + "Uploading file {number} of {count}... {progress}" => "Enviando arquivo {number} de {count}... {progress}", + "Failed to upload {filename}!" => "Falha no envio do arquivo {filename}!", +); diff --git a/lib/kcfinder/lang/pt.php b/lib/kcfinder/lang/pt.php new file mode 100644 index 0000000..acd898a --- /dev/null +++ b/lib/kcfinder/lang/pt.php @@ -0,0 +1,243 @@ + "Portuguese", + '_native' => "Português", + '_locale' => "pt_PT.UTF-8", // UNIX localization code + '_charset' => "utf-8", // Browser charset + + // Date time formats. See http://www.php.net/manual/en/function.strftime.php + '_dateTimeFull' => "%A, %e %B, %Y %H:%M", + '_dateTimeMid' => "%a %e %b %Y %H:%M", + '_dateTimeSmall' => "%d.%m.%Y %H:%M", + + "You don't have permissions to upload files." => + "Não tem permissão para enviar ficheiros.", + + "You don't have permissions to browse server." => + "Não tem permissão para navegar no servidor.", + + "Cannot move uploaded file to target folder." => + "Não pode mover ficheiros enviados para a pasta definida.", + + "Unknown error." => + "Erro indefinido.", + + "The uploaded file exceeds {size} bytes." => + "O ficheiro enviado tem mais que {size} bytes.", + + "The uploaded file was only partially uploaded." => + "O ficheiro foi apenas enviado parcialmente.", + + "No file was uploaded." => + "Nenhum ficheiro enviado.", + + "Missing a temporary folder." => + "Falta a pasta temporária.", + + "Failed to write file." => + "Não foi possível guardar o ficheiro.", + + "Denied file extension." => + "Extensão do ficheiro inválida.", + + "Unknown image format/encoding." => + "Formato/codificação da imagem desconhecido.", + + "The image is too big and/or cannot be resized." => + "A imagem é muito grande e não pode ser redimensionada.", + + "Cannot create {dir} folder." => + "Não foi possível criar a pasta '{dir}'.", + + "Cannot write to upload folder." => + "Não foi possível guardar o ficheiro.", + + "Cannot read .htaccess" => + "Não foi possível ler o ficheiro .htaccess", + + "Incorrect .htaccess file. Cannot rewrite it!" => + "Ficheiro '.htaccess' incorrecto. Não foi possível altera-lo.", + + "Cannot read upload folder." => + "Não foi possível ler a pasta de upload.", + + "Cannot access or create thumbnails folder." => + "Não foi possível aceder ou criar a pasta de miniaturas.", + + "Cannot access or write to upload folder." => + "Não foi possível aceder ou criar a pasta de upload.", + + "Please enter new folder name." => + "Por favor insira o nome da pasta.", + + "Unallowable characters in folder name." => + "Caracteres não autorizados no nome da pasta.", + + "Folder name shouldn't begins with '.'" => + "O nome da pasta não deve começar por '.'", + + "Please enter new file name." => + "Por favor defina o nome do ficheiro.", + + "Unallowable characters in file name." => + "Caracteres não autorizados no nome do ficheiro.", + + "File name shouldn't begins with '.'" => + "O nome do ficheiro não deve começar por '.'", + + "Are you sure you want to delete this file?" => + "Tem a certeza que deseja apagar este ficheiro?", + + "Are you sure you want to delete this folder and all its content?" => + "Tem a certeza que deseja apagar esta pasta e todos os seus conteúdos?", + + "Inexistant or inaccessible folder." => + "Pasta inexistente ou inacessível.", + + "Undefined MIME types." => + "Tipos MIME indefinidos.", + + "Fileinfo PECL extension is missing." => + "Falta a extensão PECL nas informações do ficheiro.", + + "Opening fileinfo database failed." => + "Erro a abrir a informação do ficheiro.", + + "You can't upload such files." => + "Não pode enviar esse tipo de ficheiros.", + + "The file '{file}' does not exist." => + "O ficheiro '{file}' não existe.", + + "Cannot read '{file}'." => + "Não pode ler '{file}'.", + + "Cannot copy '{file}'." => + "Não pode copiar '{file}'.", + + "Cannot move '{file}'." => + "Não pode mover '{file}'.", + + "Cannot delete '{file}'." => + "Não pode apagar '{file}'.", + + "Click to remove from the Clipboard" => + "Clique aqui para remover do Clipboard", + + "This file is already added to the Clipboard." => + "Este ficheiros já foi adicionado ao Clipboard.", + + "Copy files here" => + "Copiar ficheiros para aqui", + + "Move files here" => + "Mover ficheiros para aqui", + + "Delete files" => + "Apagar ficheiros", + + "Clear the Clipboard" => + "Limpar Clipboard", + + "Are you sure you want to delete all files in the Clipboard?" => + "Tem a certeza que deseja apagar todos os ficheiros que estão no Clipboard?", + + "Copy {count} files" => + "Copiar {count} ficheiros", + + "Move {count} files" => + "Mover {count} ficheiros", + + "Add to Clipboard" => + "Adicionar ao Clipboard", + + "New folder name:" => "Nome da pasta:", + "New file name:" => "Nome do ficheiro:", + + "Upload" => "Enviar", + "Refresh" => "Actualizar", + "Settings" => "Preferências", + "Maximize" => "Maximizar", + "About" => "Acerca de", + "files" => "Ficheiros", + "View:" => "Ver:", + "Show:" => "Mostrar:", + "Order by:" => "Ordenar por:", + "Thumbnails" => "Miniatura", + "List" => "Lista", + "Name" => "Nome", + "Size" => "Tamanho", + "Date" => "Data", + "Descending" => "", + "Uploading file..." => "Carregando ficheiro...", + "Loading image..." => "Carregando imagens...", + "Loading folders..." => "Carregando pastas...", + "Loading files..." => "Carregando ficheiros...", + "New Subfolder..." => "Nova pasta...", + "Rename..." => "Alterar nome...", + "Delete" => "Eliminar", + "OK" => "OK", + "Cancel" => "Cancelar", + "Select" => "Seleccionar", + "Select Thumbnail" => "Seleccionar miniatura", + "View" => "Ver", + "Download" => "Sacar", + "Clipboard" => "Clipboard", + + // VERSION 2 NEW LABELS + + "Cannot rename the folder." => + "Não pode alterar o nome da pasta.", + + "Non-existing directory type." => + "Tipo de pasta inexistente.", + + "Cannot delete the folder." => + "Não pode apagar a pasta.", + + "The files in the Clipboard are not readable." => + "Os ficheiros que estão no Clipboard não podem ser copiados.", + + "{count} files in the Clipboard are not readable. Do you want to copy the rest?" => + "{count} ficheiros do Clipboard não podem ser copiados. Pretende copiar os restantes?", + + "The files in the Clipboard are not movable." => + "Os ficheiros que estão no Clipboard não podem ser movidos.", + + "{count} files in the Clipboard are not movable. Do you want to move the rest?" => + "{count} ficheiros do Clipboard não podem ser movidos. Pretende mover os restantes?", + + "The files in the Clipboard are not removable." => + "Os ficheiros que estão no Clipboard não podem ser removidos.", + + "{count} files in the Clipboard are not removable. Do you want to delete the rest?" => + "{count} ficheiros do Clipboard não podem ser removidos. Pretende apagar os restantes?", + + "The selected files are not removable." => + "Os ficheiros seleccionados não podem ser removidos.", + + "{count} selected files are not removable. Do you want to delete the rest?" => + "Não pode remover {count} ficheiros. Pretende apagar os restantes?", + + "Are you sure you want to delete all selected files?" => + "Tem a certeza que deseja apagar os ficheiros seleccionados?", + + "Failed to delete {count} files/folders." => + "Ocorreu um erro a apagar {count} ficheiros/pastas.", + + "A file or folder with that name already exists." => + "Já existe um ficheiro ou pasta com esse nome.", + + "selected files" => "Ficheiros seleccionados", + "Type" => "Tipo", + "Select Thumbnails" => "Seleccionar miniaturas", + "Download files" => "Sacar ficheiros", +); diff --git a/lib/kcfinder/lang/ro.php b/lib/kcfinder/lang/ro.php new file mode 100644 index 0000000..63f4955 --- /dev/null +++ b/lib/kcfinder/lang/ro.php @@ -0,0 +1,126 @@ + "Romanian", + '_native' => "Română", + '_locale' => "ro_RO.UTF-8", // UNIX localization code + '_charset' => "utf-8", // Browser charset + + // Date time formats. See http://www.php.net/manual/en/function.strftime.php + '_dateTimeFull' => "%A, %e %B, %Y %H:%M", + '_dateTimeMid' => "%a %e %b %Y %H:%M", + '_dateTimeSmall' => "%d.%m.%Y %H:%M", + + "You don't have permissions to upload files." => "Nu aveți permisiunea de a încărca fișiere.", + "You don't have permissions to browse server." => "Nu aveți permisiunea de a naviga pe server.", + "Cannot move uploaded file to target folder." => "Fișierul încărcat nu poate fi mutat în dosarul țintă.", + "Unknown error." => "Eroare necunoscută.", + "The uploaded file exceeds {size} bytes." => "Fișierul încărcat depășește {size} biți.", + "The uploaded file was only partially uploaded." => "Fișierul încărcat a fost încărcat doar parțial.", + "No file was uploaded." => "Nu a fost încărcat niciun fișier.", + "Missing a temporary folder." => "Nu există un dosar de fișiere temporare.", + "Failed to write file." => "Fișierul nu a fost scris.", + "Denied file extension." => "Extensie de fișier respinsă.", + "Unknown image format/encoding." => "Format/Codificare imagine necunoscut/ă.", + "The image is too big and/or cannot be resized." => "Imaginea este prea mare și/sau nu poate fi redimensionată.", + "Cannot create {dir} folder." => "Dosarul {dir} nu poate fi creat.", + "Cannot rename the folder." => "Dosarul nu poate fi numit din nou.", + "Cannot write to upload folder." => "Nu se poate scrie la dosarul de încărcare.", + "Cannot read .htaccess" => "Nu se poate citi .htacces", + "Incorrect .htaccess file. Cannot rewrite it!" => "Fișier .htacces incorect. Nu poate fi rescris!", + "Cannot read upload folder." => "Dosarul de încărcare nu poate fi citit.", + "Cannot access or create thumbnails folder." => "Dosarul de imagini în miniatură nu poate fi accesat sau creat.", + "Cannot access or write to upload folder." => "Dosarul de încărcare nu poate fi accesat sau creat.", + "Please enter new folder name." => "Vă rugăm să introduceți un nume de dosar nou.", + "Unallowable characters in folder name." => "Caractere nepermise în numele dosarului.", + "Folder name shouldn't begins with '.'" => "Numele dosarului nu trebuie să înceapă cu '.' ", + "Please enter new file name." => "Vă rugăm să introduceți un nou nume al fișierului.", + "Unallowable characters in file name." => "Caractere nepermise în numele fișierului.", + "File name shouldn't begins with '.'" => "Numele fișierului nu ar trebui să înceapă cu '.' ", + "Are you sure you want to delete this file?" => "Sigur doriți să ștergeți acest fișier?", + "Are you sure you want to delete this folder and all its content?" => "Sigur doriți să ștergeți acest dosar și toate conținuturile sale?", + "Non-existing directory type." => "Tip director non-existent.", + "Undefined MIME types." => "Tipuri MIME nefedinite.", + "Fileinfo PECL extension is missing." => "Extensia PECL lipsește.", + "Opening fileinfo database failed." => "Deschiderea bazei de date fileinfo a eșuat.", + "You can't upload such files." => "Nu puteți încărca asemenea fișiere.", + "The file '{file}' does not exist." => "Fișierul '{file}' nu există.", + "Cannot read '{file}'." => "Fișierul '{file}' nu poate fi citit.", + "Cannot copy '{file}'." => "Fișierul '{file}' nu poate fi copiat.", + "Cannot move '{file}'." => "Fișierul '{file}' nu poate fi mutat.", + "Cannot delete '{file}'." => "Fișierul '{file}' nu poate fi șters.", + "Cannot delete the folder." => "Dosarul nu poate fi șters.", + "Click to remove from the Clipboard" => "Faceți clic pentru a elimina de pe clipboard.", + "This file is already added to the Clipboard." => "Acest fișier este adăugat deja pe clipboard.", + "The files in the Clipboard are not readable." => "Fișierele de pe clipboard nu pot fi citite.", + "{count} files in the Clipboard are not readable. Do you want to copy the rest?" => "{count} fișiere de pe clipboard nu pot fi citite. Doriți să copiați restul fișierelor?", + "The files in the Clipboard are not movable." => "Fișierele de pe clipboard nu pot fi mutate.", + "{count} files in the Clipboard are not movable. Do you want to move the rest?" => "{count} fișiere de pe clipboard nu pot fi mutate. Doriți să mutați restul fișierelor?", + "The files in the Clipboard are not removable." => "Fișierele de pe clipboard nu pot fi fi mutate.", + "{count} files in the Clipboard are not removable. Do you want to delete the rest?" => "{count} fișiere de pe clipboard nu pot fi înlăturate. Doriți să înlăturați restul fișierelor?", + "The selected files are not removable." => "Fișierele selectate nu pot fi mutate.", + "{count} selected files are not removable. Do you want to delete the rest?" => "{count} fișiere selectate nu pot fi înlăturate. Doriți să ștergeți restul fișierelor?", + "Are you sure you want to delete all selected files?" => "Sigur doriți să ștergeți toate fișierele selectate?", + "Failed to delete {count} files/folders." => "{count} fișiere/dosare nu au putut fi șterse.", + "A file or folder with that name already exists." => "Există deja un fișier sau dosar cu acest nume.", + "Copy files here" => "Copiați fișierele aici", + "Move files here" => "Mutați fișierele aici", + "Delete files" => "Ștergeți fișierele", + "Clear the Clipboard" => "Eliberare clipboard", + "Are you sure you want to delete all files in the Clipboard?" => "Sigur doriți să ștergeți fișierele de pe clipboard?", + "Copy {count} files" => "Copiați {count} fișiere", + "Move {count} files" => "Mutați {count} fișiere", + "Add to Clipboard" => "Adăugați pe clipboard", + "Inexistant or inaccessible folder." => "Dosar inexistent sau inaccesibil.", + "New folder name:" => "Nume nou dosar:", + "New file name:" => "Nume nou fișier:", + "Upload" => "Încărcare", + "Refresh" => "Reîmprospătare", + "Settings" => "Setări", + "Maximize" => "Maximizare", + "About" => "Despre", + "files" => "fișiere", + "selected files" => "fișiere selectate", + "View:" => "Vizualizare:", + "Show:" => "Afișare:", + "Order by:" => "Ordonare după:", + "Thumbnails" => "Imagini în miniatură", + "List" => "Listă", + "Name" => "Nume", + "Type" => "Tip", + "Size" => "Mărime", + "Date" => "Dată", + "Descending" => "Ordine descrescătoare", + "Uploading file..." => "Încărcare fișier...", + "Loading image..." => "Încărcare imagine...", + "Loading folders..." => "Încărcare dosare...", + "Loading files..." => "Încărcare fișiere...", + "New Subfolder..." => "Sub-dosar nou...", + "Rename..." => "Redenumire...", + "Delete" => "Ștergere", + "OK" => "OK", + "Cancel" => "Anulare", + "Select" => "Selectare", + "Select Thumbnail" => "Selectare imagine în miniatură", + "Select Thumbnails" => "Selectare imagini în miniatură", + "View" => "Vizualizare", + "Download" => "Descărcare", + "Download files" => "Descărcare fișiere", + "Clipboard" => "Clipboard", + "Checking for new version..." => "Verificare versiune nouă...", + "Unable to connect!" => "Conectare imposibilă!", + "Download version {version} now!" => "Descărcați acum versiunea {version}!", + "KCFinder is up to date!" => "KCFinder este actualizat!", + "Licenses:" => "Licențe:", + "Attention" => "Atenție", + "Question" => "Întrebare", + "Yes" => "Da", + "No" => "Nu", + "You cannot rename the extension of files!" => "Nu puteți redenumi extensia fișierelor!", + "Uploading file {number} of {count}... {progress}" => "Încărcare fișier {number} din {count}... {progress}", + "Failed to upload {filename}!" => "Încărcare {filename} eșuată!", +); diff --git a/lib/kcfinder/lang/ru.php b/lib/kcfinder/lang/ru.php new file mode 100644 index 0000000..f9ada3c --- /dev/null +++ b/lib/kcfinder/lang/ru.php @@ -0,0 +1,133 @@ + "Russian", + '_native' => "Русский", + '_locale' => "ru_RU.UTF-8", // UNIX localization code + '_charset' => "utf-8", // Browser charset + + // Date time formats. See http://www.php.net/manual/en/function.strftime.php + '_dateTimeFull' => "%A, %e %B, %Y %H:%M", + '_dateTimeMid' => "%a %e %b %Y %H:%M", + '_dateTimeSmall' => "%d.%m.%Y %H:%M", + + "You don't have permissions to upload files." => "У вас нет прав для загрузки файлов.", + "You don't have permissions to browse server." => "У вас нет прав для просмотра содержимого на сервере.", + "Cannot move uploaded file to target folder." => "Невозможно переместить загруженный файл в папку назначения.", + "Unknown error." => "Неизвестная ошибка.", + "The uploaded file exceeds {size} bytes." => "Загруженный файл превышает размер {size} байт.", + "The uploaded file was only partially uploaded." => "Загруженный файл был загружен только частично.", + "No file was uploaded." => "Файл не был загружен", + "Missing a temporary folder." => "Временная папка не существует.", + "Failed to write file." => "Невозможно записать файл.", + "Denied file extension." => "Файлы этого типа запрещены для загрузки.", + "Unknown image format/encoding." => "Неизвестный формат изображения.", + "The image is too big and/or cannot be resized." => "Изображение слишком большое и/или не может быть уменьшено.", + "Cannot create {dir} folder." => "Невозможно создать папку {dir}.", + "Cannot rename the folder." => "Невозможно переименовать папку.", + "Cannot write to upload folder." => "Невозможно записать в папку загрузки.", + "Cannot read .htaccess" => "Невозможно прочитать файл .htaccess", + "Incorrect .htaccess file. Cannot rewrite it!" => "Неправильный файл .htaccess. Невозможно перезаписать!", + "Cannot read upload folder." => "Невозможно прочитать папку загрузки.", + "Cannot access or create thumbnails folder." => "Нет доступа или невозможно создать папку миниатюр.", + "Cannot access or write to upload folder." => "Нет доступа или невозможно записать в папку загрузки.", + "Please enter new folder name." => "Укажите имя новой папки.", + "Unallowable characters in folder name." => "Недопустимые символы в имени папки.", + "Folder name shouldn't begins with '.'" => "Имя папки не может начинаться с '.'", + "Please enter new file name." => "Укажите новое имя файла", + "Unallowable characters in file name." => "Недопустимые символны в имени файла.", + "File name shouldn't begins with '.'" => "Имя файла не может начинаться с '.'", + "Are you sure you want to delete this file?" => "Вы уверены, что хотите удалить этот файл?", + "Are you sure you want to delete this folder and all its content?" => "Вы уверены, что хотите удалить эту папку и всё её содержимое?", + "Non-existing directory type." => "Несуществующий тип папки.", + "Undefined MIME types." => "Неопределённые типы MIME.", + "Fileinfo PECL extension is missing." => "Расширение Fileinfo PECL отсутствует.", + "Opening fileinfo database failed." => "Невозможно открыть базу данных fileinfo.", + "You can't upload such files." => "Вы не можете загружать файлы этого типа.", + "The file '{file}' does not exist." => "Файл '{file}' не существует.", + "Cannot read '{file}'." => "Невозможно прочитать файл '{file}'.", + "Cannot copy '{file}'." => "Невозможно скопировать файл '{file}'.", + "Cannot move '{file}'." => "Невозможно переместить файл '{file}'.", + "Cannot delete '{file}'." => "Невозможно удалить файл '{file}'.", + "Cannot delete the folder." => "Невозможно удалить папку.", + "Click to remove from the Clipboard" => "Нажмите для удаления из буфера обмена", + "This file is already added to the Clipboard." => "Этот файл уже добавлен в буфер обмена.", + "The files in the Clipboard are not readable." => "Невозможно прочитать файлы в буфере обмена.", + "{count} files in the Clipboard are not readable. Do you want to copy the rest?" => "Невозможно прочитать {count} файл(ов) в буфере обмена. Вы хотите скопировать оставшиеся?", + "The files in the Clipboard are not movable." => "Невозможно переместить файлы в буфере обмена.", + "{count} files in the Clipboard are not movable. Do you want to move the rest?" => "Невозможно переместить {count} файл(ов) в буфере обмена. Вы хотите переместить оставшиеся?", + "The files in the Clipboard are not removable." => "Невозможно удалить файлы в буфере обмена.", + "{count} files in the Clipboard are not removable. Do you want to delete the rest?" => "Невозможно удалить {count} файл(ов) в буфере обмена. Вы хотите удалить оставшиеся?", + "The selected files are not removable." => "Невозможно удалить выбранные файлы.", + "{count} selected files are not removable. Do you want to delete the rest?" => "Невозможно удалить выбранный(е) {count} файл(ы). Вы хотите удалить оставшиеся?", + "Are you sure you want to delete all selected files?" => "Вы уверены, что хотите удалить все выбранные файлы?", + "Failed to delete {count} files/folders." => "Невозможно удалить {count} файлов/папок.", + "A file or folder with that name already exists." => "Файл или папка с таким именем уже существуют.", + "Copy files here" => "Скопировать файлы сюда", + "Move files here" => "Переместить файлы сюда", + "Delete files" => "Удалить файлы", + "Clear the Clipboard" => "Очистить буфер обмена", + "Are you sure you want to delete all files in the Clipboard?" => "Вы уверены, что хотите удалить все файлы в буфере обмена?", + "Copy {count} files" => "Скопировать {count} файл(ов)", + "Move {count} files" => "Переместить {count} файл(ов)", + "Add to Clipboard" => "Добавить в буфер обмена", + "Inexistant or inaccessible folder." => "Несуществующая или недоступная папка.", + "New folder name:" => "Новое имя папки:", + "New file name:" => "Новое имя файла:", + "Upload" => "Загрузить", + "Refresh" => "Обновить", + "Settings" => "Установки", + "Maximize" => "Развернуть", + "About" => "О скрипте", + "files" => "файлы", + "selected files" => "выбранные файлы", + "View:" => "Просмотр:", + "Show:" => "Показывать:", + "Order by:" => "Упорядочить по:", + "Thumbnails" => "Миниатюры", + "List" => "Список", + "Name" => "Имя", + "Type" => "Тип", + "Size" => "Размер", + "Date" => "Дата", + "Descending" => "По убыванию", + "Uploading file..." => "Загрузка файла...", + "Loading image..." => "Загрузка изображения...", + "Loading folders..." => "Загрузка папок...", + "Loading files..." => "Загрузка файлов...", + "New Subfolder..." => "Создать папку...", + "Rename..." => "Переименовать...", + "Delete" => "Удалить", + "OK" => "OK", + "Cancel" => "Отмена", + "Select" => "Выбрать", + "Select Thumbnail" => "Выбрать миниатюру", + "Select Thumbnails" => "Выбрать миниатюры", + "View" => "Просмотр", + "Download" => "Скачать", + "Download files" => "Скачать файлы", + "Clipboard" => "Буфер обмена", + "Checking for new version..." => "Проверяем наличие обновлений...", + "Unable to connect!" => "Невозможно подключиться!", + "Download version {version} now!" => "Скачать версию {version} сейчас!", + "KCFinder is up to date!" => "Вы используете последнюю версию KCFinder'а!", + "Licenses:" => "Лицензии:", + "Attention" => "Внимание", + "Question" => "Вопрос", + "Yes" => "Да", + "No" => "Нет", + "You cannot rename the extension of files!" => "Вы не можете изменять расширения файлов!", + "Uploading file {number} of {count}... {progress}" => "Загрузка {number} файла из {count}... {progress}", + "Failed to upload {filename}!" => "Неудачная попытка загрузки {filename}!", + "Close" => "Закрыть", + "Previous" => "Предыдущий", + "Next" => "Следующий", + "Confirmation" => "Подтверждение", + "Warning" => "Предупреждение", +); diff --git a/lib/kcfinder/lang/sk.php b/lib/kcfinder/lang/sk.php new file mode 100644 index 0000000..4262b02 --- /dev/null +++ b/lib/kcfinder/lang/sk.php @@ -0,0 +1,127 @@ + + */ + +$lang = array( + + '_lang' => "Slovak", + '_native' => "Slovenčina", + '_locale' => "sk_SK.UTF-8", // UNIX localization code + '_charset' => "utf-8", // Browser charset + + // Date time formats. See http://www.php.net/manual/en/function.strftime.php + '_dateTimeFull' => "%A, %e.%B.%Y %H:%M", + '_dateTimeMid' => "%a %e %b %Y %H:%M", + '_dateTimeSmall' => "%d.%m.%Y %H:%M", + + "You don't have permissions to upload files." => "Nemáte právo nahrávať súbory.", + "You don't have permissions to browse server." => "Nemáte právo prehliadať súbory na serveri.", + "Cannot move uploaded file to target folder." => "Nie je možné presunúť súbor do zvoleného adresára.", + "Unknown error." => "Neznáma chyba.", + "The uploaded file exceeds {size} bytes." => "Nahratý súbor presahuje {size} bytov.", + "The uploaded file was only partially uploaded." => "Nahratý súbor bol nahraný len čiastočne.", + "No file was uploaded." => "Žiadný súbor nebol nahraný na server.", + "Missing a temporary folder." => "Chyba dočasný adresár.", + "Failed to write file." => "Súbor sa nepodarilo uložiť.", + "Denied file extension." => "Nepodporovaný typ súboru.", + "Unknown image format/encoding." => "Neznamý formát obrázku/encoding.", + "The image is too big and/or cannot be resized." => "Obrázok je príliš veľký/alebo nemohol byť zmenšený.", + "Cannot create {dir} folder." => "Adresár {dir} nie je možné vytvoriť.", + "Cannot rename the folder." => "Adresár nie je možné premenovať.", + "Cannot write to upload folder." => "Nie je možné ukladať do adresára pre nahrávánie.", + "Cannot read .htaccess" => "Nie je možné čítať súbor .htaccess", + "Incorrect .htaccess file. Cannot rewrite it!" => "Chybný súbor .htaccess. Súbor nemožno prepísať!", + "Cannot read upload folder." => "Nie je možné čítať z adresára pre nahrávánie súborov.", + "Cannot access or create thumbnails folder." => "Adresár pre náhľady nie je možné vytvoriť alebo nie je prístupný.", + "Cannot access or write to upload folder." => "Nie je možné pristupovať alebo zapisovať do adresára pre nahrávanie súborov.", + "Please enter new folder name." => "Zadajte prosím nové meno adresára.", + "Unallowable characters in folder name." => "Nepovolené znaky v názve adresára.", + "Folder name shouldn't begins with '.'" => "Meno adresára nesmie začínať znakom '.'", + "Please enter new file name." => "Vložte prosím nové meno súboru.", + "Unallowable characters in file name." => "Nepovolené znaky v názve súboru.", + "File name shouldn't begins with '.'" => "Názov súboru nesmie začínať znakom '.'", + "Are you sure you want to delete this file?" => "Ste si istý že chcete vymazať tento súbor?", + "Are you sure you want to delete this folder and all its content?" => "Ste si istý že chcete vymazať tento adresár a celý jeho obsah?", + "Non-existing directory type." => "Neexistujúci typ adresára.", + "Undefined MIME types." => "Nedefinovaný MIME typ súboru.", + "Fileinfo PECL extension is missing." => "Rozšírenie PECL pre zistenie informácií o súbore chýba.", + "Opening fileinfo database failed." => "Načítanie informácií o súbore zlyhalo.", + "You can't upload such files." => "Tieto súbory nemôžete nahrať na server.", + "The file '{file}' does not exist." => "Tento súbor '{file}' neexistuje.", + "Cannot read '{file}'." => "Nie je možné načítať '{file}'.", + "Cannot copy '{file}'." => "Nie je možné kopírovať '{file}'.", + "Cannot move '{file}'." => "Nie je možné presunúť '{file}'.", + "Cannot delete '{file}'." => "Nie je možné vymazať '{file}'.", + "Cannot delete the folder." => "Adresár nie je možné vymazať.", + "Click to remove from the Clipboard" => "Kliknite pre odstránenie zo schránky", + "This file is already added to the Clipboard." => "Tento súbor je už v schránke uložený.", + "The files in the Clipboard are not readable." => "Súbory v schránke nie je možné načítať.", + "{count} files in the Clipboard are not readable. Do you want to copy the rest?" => "{count} súborov v schránke nie je možné načítať. Chcete skopírovať ostatné súbory?", + "The files in the Clipboard are not movable." => "Súbory v schránke nie je možné presunúť.", + "{count} files in the Clipboard are not movable. Do you want to move the rest?" => "{count} súborov v schránke nie je možné presunúť. Chcete presunúť ostatné súbory?", + "The files in the Clipboard are not removable." => "Súbory v schránke nie je možné vymazať.", + "{count} files in the Clipboard are not removable. Do you want to delete the rest?" => "{count} súborov v schránke nie je možné vymazať. Chcete vymazať ostatné súbory?", + "The selected files are not removable." => "Vybrané súbory nie je možné vymazať.", + "{count} selected files are not removable. Do you want to delete the rest?" => "{count} vybraných súborov nie je možné vymazať. Chcete vymazať ostatné súbory?", + "Are you sure you want to delete all selected files?" => "Ste si istý že chcete vymazať vybrané súbory?", + "Failed to delete {count} files/folders." => "Nebolo vymazaných {count} súborov/adresárov.", + "A file or folder with that name already exists." => "Soubor alebo adresár s takovým menom už existuje.", + "Copy files here" => "Kopírovať súbory na toto miesto", + "Move files here" => "Presunúť súbory na toto miesto", + "Delete files" => "Vymazať súbory", + "Clear the Clipboard" => "Vyčistiť schránku", + "Are you sure you want to delete all files in the Clipboard?" => "Ste si istý že chcete vymazať všetky súbory zo schránky?", + "Copy {count} files" => "Kopírovať {count} súborov", + "Move {count} files" => "Presunúť {count} súborov", + "Add to Clipboard" => "Vložiť do schránky", + "Inexistant or inaccessible folder." => "Neexistujúci alebo neprístupný adresár.", + "New folder name:" => "Nový názov adresára:", + "New file name:" => "Nový názov súboru:", + "Upload" => "Nahrať", + "Refresh" => "Obnoviť", + "Settings" => "Nastavenia", + "Maximize" => "Maxializovať", + "About" => "O aplikácii", + "files" => "súbory", + "selected files" => "vybrané súbory", + "View:" => "Zobraziť:", + "Show:" => "Ukázať:", + "Order by:" => "Zoradiť podľa:", + "Thumbnails" => "Náhľady", + "List" => "Zoznam", + "Name" => "Meno", + "Type" => "Typ", + "Size" => "Veľkosť", + "Date" => "Dátum", + "Descending" => "Zostupne", + "Uploading file..." => "Nahrávanie súborov...", + "Loading image..." => "Načítanie obrázkov...", + "Loading folders..." => "Načítanie adresárov...", + "Loading files..." => "Načítanie súborov...", + "New Subfolder..." => "Nový adresár...", + "Rename..." => "Premenovať...", + "Delete" => "Zmazať", + "OK" => "OK", + "Cancel" => "Zrušit", + "Select" => "Vybrať", + "Select Thumbnail" => "Vybrať náhľad", + "Select Thumbnails" => "Vybrať náhľad", + "View" => "Zobraziť", + "Download" => "Stahnuť", + "Download files" => "Stiahnuť súbory", + "Clipboard" => "Schránka", + "Checking for new version..." => "Kontrolujem novú verziu...", + "Unable to connect!" => "Pripojenie zlyhalo!", + "Download version {version} now!" => "Stiahnuť verziu {version} teraz!", + "KCFinder is up to date!" => "KCFinder je aktuálny!", + "Licenses:" => "Licencie:", + "Attention" => "Upozornenie", + "Question" => "Otázka", + "Yes" => "Áno", + "No" => "Nie", + "You cannot rename the extension of files!" => "Nemôžete premenovať príponu súborov", + "Uploading file {number} of {count}... {progress}" => "Nahrávam súbor {number} z {count}... {progress}", + "Failed to upload {filename}!" => "Nepodarilo sa nahrať súbor {filename}!", +); diff --git a/lib/kcfinder/lang/sv.php b/lib/kcfinder/lang/sv.php new file mode 100644 index 0000000..7241cea --- /dev/null +++ b/lib/kcfinder/lang/sv.php @@ -0,0 +1,127 @@ + "Swedish", + '_native' => "Svensk", + '_locale' => "sv_SE.UTF-8", // UNIX localization code + '_charset' => "utf-8", // Browser charset + + // Date time formats. See http://www.php.net/manual/en/function.strftime.php + '_dateTimeFull' => "den %e %B %Y", + '_dateTimeMid' => "%e %b %Y", + '_dateTimeSmall' => "%Y-%m-%d %H:%M", + + "You don't have permissions to upload files." => "Du har inte behörighet att ladda upp filer. Kontakta vår support.", + "You don't have permissions to browse server." => "Du har inte behörighet att bläddra server.", + "Cannot move uploaded file to target folder." => "Kan inte flytta upp filen till målmappen.", + "Unknown error." => "Okänt fel.", + "The uploaded file exceeds {size} bytes." => "Den uppladdade filen överstiger {size} byte.", + "The uploaded file was only partially uploaded." => "Den uppladdade filen var endast delvis uppladdat.", + "No file was uploaded." => "Inga filer laddades upp.", + "Missing a temporary folder." => "Saknade en temporär mapp.", + "Failed to write file." => "Misslyckades att skriva fil.", + "Denied file extension." => "Nekad filtillägg.", + "Unknown image format/encoding." => "Okänt bildformat / kodning.", + "The image is too big and/or cannot be resized." => "Bilden är för stor och / eller kan inte ändras.", + "Cannot create {dir} folder." => "Kan inte skapa {dir} mapp.", + "Cannot rename the folder." => "Kan inte byta namn på mappen.", + "Cannot write to upload folder." => "Kan inte laddaup till mappen.", + "Cannot read .htaccess" => "Fel läser inte htacess filen", + "Incorrect .htaccess file. Cannot rewrite it!" => "Fel . htaccess fil. Inte skrivvänlig", + "Cannot read upload folder." => "Kan inte läsa upp mappen.", + "Cannot access or create thumbnails folder." => "Kan inte komma åt eller skapa thumbnails mapp.", + "Cannot access or write to upload folder." => "Kan inte komma åt eller skriva för att ladda upp mappen.", + "Please enter new folder name." => "Vänligen skriv in ny mapp-namn", + "Unallowable characters in folder name." => "Otillåtna tecken i mappnamnet.", + "Folder name shouldn't begins with '.'" => "Mappnamn bör inte börjar med '. \"", + "Please enter new file name." => "Ange nytt filnamn.", + "Unallowable characters in file name." => "Otillåtna tecken i filnamnet.", + "File name shouldn't begins with '.'" => "Filnamn bör inte börjar med '. \"", + "Are you sure you want to delete this file?" => "Är du säker du vill radera filen?", + "Are you sure you want to delete this folder and all its content?" => "Är du säker du vill radera denna mappen ink innehåll?", + "Non-existing directory type." => "Icke-existerande katalog typ.", + "Undefined MIME types." => "Odefinierat MIME-typer.", + "Fileinfo PECL extension is missing." => "Fileinfo PECL förlängning saknas.", + "Opening fileinfo database failed." => "databas öppning misslyckad.", + "You can't upload such files." => "Kan inte ladda upp sådan fil.", + "The file '{file}' does not exist." => "Filen '{file}' finns inte.", + "Cannot read '{file}'." => "Ej läsbar fil : '{file}'. ", + "Cannot copy '{file}'." => "Kan inte kopiera '{file}'.", + "Cannot move '{file}'." => "Kan inte flytta '{file}'.", + "Cannot delete '{file}'." => "Kan inte radera'{file}'.", + "Cannot delete the folder." => "Kan inte radera mappen.", + "Click to remove from the Clipboard" => "Tryck för att radera från Urklipp", + "This file is already added to the Clipboard." => "Den här filen är redan lagts till i Urklipp.", + "The files in the Clipboard are not readable." => "Filerna i Urklipp är inte läsbar.", + "{count} files in the Clipboard are not readable. Do you want to copy the rest?" => "{count} filer i Urklipp är inte läsbar. Vill du kopiera resten?", + "The files in the Clipboard are not movable." => "Filerna i Urklipp är inte flyttbara.", + "{count} files in the Clipboard are not movable. Do you want to move the rest?" => "{count} filer i Urklipp är inte rörliga. Vill du flytta resten?", + "The files in the Clipboard are not removable." => "Filerna i Urklipp är inte avtagbara.", + "{count} files in the Clipboard are not removable. Do you want to delete the rest?" => "{count} filer i Urklipp är inte avtagbara. Vill du ta bort resten?", + "The selected files are not removable." => "De valda filerna inte tas bort.", + "{count} selected files are not removable. Do you want to delete the rest?" => "{count} valda filerna inte tas bort. Vill du ta bort resten?", + "Are you sure you want to delete all selected files?" => "Är du säker på att du vill ta bort alla markerade filer?", + "Failed to delete {count} files/folders." => "Misslyckades att radera {count} filer/mappar.", + "A file or folder with that name already exists." => "En fil eller mapp med det namnet finns redan.", + "Copy files here" => "Kopiera filerna här", + "Move files here" => "Flytta filerna här", + "Delete files" => "Radera filer", + "Clear the Clipboard" => "Rensa Urklipp", + "Are you sure you want to delete all files in the Clipboard?" => "Är du säker på att du vill ta bort alla filer i Urklipp?", + "Copy {count} files" => "Kopiera {count} filer", + "Move {count} files" => "Flytta {count} filer", + "Add to Clipboard" => "Lägg till i Urklipp", + "Inexistant or inaccessible folder." => "Inexistant eller otillgängliga mapp.", + "New folder name:" => "Ny mappnamn:", + "New file name:" => "Nytt filnamn:", + "Upload" => "Ladda upp", + "Refresh" => "Uppdatera", + "Settings" => "Inställningar", + "Maximize" => "Maximera", + "About" => "Om", + "files" => "Filer", + "selected files" => "Välj filer", + "View:" => "Se", + "Show:" => "Visa:", + "Order by:" => "Sortera efter:", + "Thumbnails" => "Miniatyr", + "List" => "Lista", + "Name" => "Namn", + "Type" => "Typ", + "Size" => "Storlek", + "Date" => "Datum", + "Descending" => "Fallande", + "Uploading file..." => "Laddar upp fil", + "Loading image..." => "Laddar bilder...", + "Loading folders..." => "Laddar mappar...", + "Loading files..." => "Laddar filer...", + "New Subfolder..." => "Ny undermapp...", + "Rename..." => "Byt namn", + "Delete" => "Radera", + "OK" => "Ok", + "Cancel" => "Avbryt", + "Select" => "Välj", + "Select Thumbnail" => "Välj miniatyr", + "Select Thumbnails" => "Välj miniatyrer", + "View" => "Se", + "Download" => "Ladda ner", + "Download files" => "Ladda ner fil", + "Clipboard" => "Urklipp", + "Checking for new version..." => "Söka efter ny version ...", + "Unable to connect!" => "Kunde inte ansluta! ", + "Download version {version} now!" => "Ladda ner version {version} nu!", + "KCFinder is up to date!" => "KCFinder är uppdaterad!", + "Licenses:" => "Licenser:", + "Attention" => "Uppmärksamhet", + "Question" => "Fråga", + "Yes" => "Ja", + "No" => "Nä", + "You cannot rename the extension of files!" => "Du kan inte byta namn på en förlängning av filer!", + "Uploading file {number} of {count}... {progress}" => "Ladda upp fil {number} av {count} ... {progress}", + "Failed to upload {filename}!" => "Uppladdning misslyckad {filename}!", +); diff --git a/lib/kcfinder/lang/tr.php b/lib/kcfinder/lang/tr.php new file mode 100644 index 0000000..645c476 --- /dev/null +++ b/lib/kcfinder/lang/tr.php @@ -0,0 +1,132 @@ + + */ + +$lang = array( + + '_lang' => "Turkish", + '_native' => "Türkçe", + '_locale' => "en_US.UTF-8", // UNIX localization code + '_charset' => "utf-8", // Browser charset + + // Date time formats. See http://www.php.net/manual/en/function.strftime.php + '_dateTimeFull' => "%A, %e.%B.%Y %H:%M", + '_dateTimeMid' => "%a %e %b %Y %H:%M", + '_dateTimeSmall' => "%d/%m/%Y %H:%M", + + "You don't have permissions to upload files." => "Dosya yüklemek için yetkiniz yok.", + "You don't have permissions to browse server." => "Sunucuyu gezmek için yetkiniz yok.", + "Cannot move uploaded file to target folder." => "Yüklenilen dosyalar hedef klasöre taşınamıyor.", + "Unknown error." => "Bilinmeyen hata.", + "The uploaded file exceeds {size} bytes." => "Gönderilen dosya boyutu, maksimum dosya boyutu limitini ({size} byte) aşıyor.", + "The uploaded file was only partially uploaded." => "Dosyanın sadece bir kısmı yüklendi. Yüklemeyi tekrar deneyin.", + "No file was uploaded." => "Dosya yüklenmedi.", + "Missing a temporary folder." => "Geçici dosya klasörü bulunamıyor. Klasörü kontrol edin.", + "Failed to write file." => "Dosya yazılamıyor. Klasör yetkilerini kontrol edin.", + "Denied file extension." => "Yasaklanmış dosya türü.", + "Unknown image format/encoding." => "Bilinmeyen resim formatı.", + "The image is too big and/or cannot be resized." => "Resim çok büyük ve/veya yeniden boyutlandırılamıyor.", + "Cannot create {dir} folder." => "{dir} klasörü oluşturulamıyor.", + "Cannot rename the folder." => "Klasör adı değiştirilemiyor.", + "Cannot write to upload folder." => "Dosya yükleme klasörüne yazılamıyor. Klasör yetkisini kontrol edin.", + "Cannot read .htaccess" => ".htaccess dosyası okunamıyor", + "Incorrect .htaccess file. Cannot rewrite it!" => "Hatalı .htaccess dosyası. Dosyaya yeniden yazılamıyor.", + "Cannot read upload folder." => "Dosya yükleme klasörü okunamıyor. Klasör yetkilerini kontrol edin.", + "Cannot access or create thumbnails folder." => "Önizleme dosyaları klasörüne erişilemiyor yada oluşturulamıyor.", + "Cannot access or write to upload folder." => "Dosya yükleme klasörüne ulaşılamıyor yada oluşturulamıyor.", + "Please enter new folder name." => "Lütfen yeni klasör adını girin.", + "Unallowable characters in folder name." => "Klasör adında izin verilmeyen karakter kullandınız.", + "Folder name shouldn't begins with '.'" => "Klasör adı '.' ile başlayamaz.", + "Please enter new file name." => "Lütfen yeni dosya adını girin.", + "Unallowable characters in file name." => "Dosya adında izin verilmeyen karakter kullandınız.", + "File name shouldn't begins with '.'" => "Dosya adı '.' ile başlayamaz.", + "Are you sure you want to delete this file?" => "Dosyayı silmek istediğinizden emin misiniz?", + "Are you sure you want to delete this folder and all its content?" => "Bu klasörü ve tüm içeriğini silmek istediğinizden emin misiniz?", + "Non-existing directory type." => "Geçersiz klasör türü.", + "Undefined MIME types." => "Tanımsız MIME türü.", + "Fileinfo PECL extension is missing." => "Dosya Bilgisi PECL uzantısı eksik.", + "Opening fileinfo database failed." => "Dosya Bilgisi veritabanı açılırken hata oluştu.", + "You can't upload such files." => "Bu tür dosyaları yükleyemezsiniz.", + "The file '{file}' does not exist." => "'{file}' dosyası yok.", + "Cannot read '{file}'." => "'{file}' dosyası okunamıyor.", + "Cannot copy '{file}'." => "'{file}' dosyası kopyalanamıyor.", + "Cannot move '{file}'." => "'{file}' dosyası taşınamıyor.", + "Cannot delete '{file}'." => "'{file}' dosyası silinemiyor.", + "Cannot delete the folder." => "Klasör silinemiyor.", + "Click to remove from the Clipboard" => "Panodan çıkarmak için tıklayın", + "This file is already added to the Clipboard." => "Bu dosya zaten panoya eklenmiş.", + "The files in the Clipboard are not readable." => "Panodaki dosyalar okunamıyor.", + "{count} files in the Clipboard are not readable. Do you want to copy the rest?" => "Panodaki {count} adet dosya okunamıyor. Geri kalanlarını kopyalamak istiyor musunuz?", + "The files in the Clipboard are not movable." => "Panodaki dosyalar taşınamıyor.", + "{count} files in the Clipboard are not movable. Do you want to move the rest?" => "Panodaki {count} adet dosya taşınamıyor. Geri kalanlarını taşımak istiyor musunuz?", + "The files in the Clipboard are not removable." => "Dosyalar panodan çıkartılamıyor.", + "{count} files in the Clipboard are not removable. Do you want to delete the rest?" => "{count} adet dosya panodan çıkartılamıyor. Geri kalanları silmek istiyor musunuz?", + "The selected files are not removable." => "Seçilen dosyalar panodan çıkartılamıyor.", + "{count} selected files are not removable. Do you want to delete the rest?" => "Seçilen dosyaların {count} adedi panodan çıkartılamıyor. Geri kalanları silmek istiyor musunuz?", + "Are you sure you want to delete all selected files?" => "Seçilen tüm dosyaları silmek istediğinizden emin misiniz?", + "Failed to delete {count} files/folders." => "{count} adet dosya/klasör silinemedi.", + "A file or folder with that name already exists." => "Bu isimde bir klasör yada dosya zaten var.", + "Copy files here" => "Dosyaları Buraya Kopyala", + "Move files here" => "Dosyaları Buraya Taşı", + "Delete files" => "Dosyaları Sil", + "Clear the Clipboard" => "Panoyu Temizle", + "Are you sure you want to delete all files in the Clipboard?" => "Panodaki tüm dosyaları silmek istediğinizden emin misiniz?", + "Copy {count} files" => "{count} adet dosyayı kopyala", + "Move {count} files" => "{count} adet dosyayı taşı", + "Add to Clipboard" => "Panoya Ekle", + "Inexistant or inaccessible folder." => "Klasör yok yada ulaşılamıyor.", + "New folder name:" => "Yeni Klasör Adı:", + "New file name:" => "Yeni Dosya Adı:", + "Upload" => "Yükle", + "Refresh" => "Yenile", + "Settings" => "Ayarlar", + "Maximize" => "Pencereyi Büyüt", + "About" => "Hakkında", + "files" => "dosya", + "selected files" => "dosya seçildi", + "View:" => "Görüntüleme:", + "Show:" => "Göster:", + "Order by:" => "Sıralama:", + "Thumbnails" => "Önizleme", + "List" => "Liste", + "Name" => "Ad", + "Type" => "Tür", + "Size" => "Boyut", + "Date" => "Tarih", + "Descending" => "Azalarak", + "Uploading file..." => "Dosya Gönderiliyor...", + "Loading image..." => "Resim Yükleniyor...", + "Loading folders..." => "Klasörler Yükleniyor...", + "Loading files..." => "Dosyalar Yükleniyor...", + "New Subfolder..." => "Yeni Alt Klasör...", + "Rename..." => "İsim Değiştir...", + "Delete" => "Sil", + "OK" => "Tamam", + "Cancel" => "İptal", + "Select" => "Seç", + "Select Thumbnail" => "Önizleme Resmini Seç", + "Select Thumbnails" => "Önizleme Resimlerini Seç", + "View" => "Göster", + "Download" => "İndir", + "Download files" => "Dosyaları İndir", + "Clipboard" => "Pano", + "Checking for new version..." => "Yeni versiyon kontrol ediliyor...", + "Unable to connect!" => "Bağlantı yapılamıyor!", + "Download version {version} now!" => " {version} versiyonunu hemen indir!", + "KCFinder is up to date!" => "KCFinder güncel durumda!", + "Licenses:" => "Lisanslar:", + "Attention" => "Dikkat", + "Question" => "Soru", + "Yes" => "Evet", + "No" => "Hayır", + "You cannot rename the extension of files!" => "Dosya uzantılarını değiştiremezsiniz!", + "Uploading file {number} of {count}... {progress}" => "{number} / {count} dosya yükleniyor... {progress}", + "Failed to upload {filename}!" => "{filename} dosyası yüklenemedi!", + "Close" => "Kapat", + "Previous" => "Önceki", + "Next" => "Sonraki", + "Confirmation" => "Onay", + "Warning" => "Uyarı", +); diff --git a/lib/kcfinder/lang/uk.php b/lib/kcfinder/lang/uk.php new file mode 100644 index 0000000..a619c06 --- /dev/null +++ b/lib/kcfinder/lang/uk.php @@ -0,0 +1,128 @@ + "Ukrainian", + '_native' => "Українська", + '_locale' => "uk_UA.UTF-8", // UNIX localization code + '_charset' => "utf-8", // Browser charset + + // Date time formats. See http://www.php.net/manual/en/function.strftime.php + '_dateTimeFull' => "%A, %e %B, %Y %H:%M", + '_dateTimeMid' => "%a %e %b %Y %H:%M", + '_dateTimeSmall' => "%d.%m.%Y %H:%M", + + "You don't have permissions to upload files." => "У вас нема прав для завантаження файлів.", + "You don't have permissions to browse server." => "У вас нема прав для перегляду вмісту на сервері.", + "Cannot move uploaded file to target folder." => "Неможливо перемістити завантажений файл в папку призначення.", + "Unknown error." => "Невідома помилка.", + "The uploaded file exceeds {size} bytes." => "Завантажений файл перевищує розмір {size} байтів.", + "The uploaded file was only partially uploaded." => "Завантажений файл було завантажено лише частково.", + "No file was uploaded." => "Файл не було завантажено", + "Missing a temporary folder." => "Тимчасова папка не існує.", + "Failed to write file." => "Неможливо записати файл.", + "Denied file extension." => "Файли цього типу заборонені для завантаження.", + "Unknown image format/encoding." => "Невідомий формат зображення.", + "The image is too big and/or cannot be resized." => "Зображення занадто велике і/або не може бути зменшене.", + "Cannot create {dir} folder." => "Неможливо створити папку {dir}.", + "Cannot rename the folder." => "Неможливо перейменувати папку.", + "Cannot write to upload folder." => "Неможливо записати в папку завантаження.", + "Cannot read .htaccess" => "Неможливо прочитати файл .htaccess", + "Incorrect .htaccess file. Cannot rewrite it!" => "Неправильний файл .htaccess. Неможливо перезаписати!", + "Cannot read upload folder." => "Неможливо прочитати папку завантаження.", + "Cannot access or create thumbnails folder." => "Нема доступу або неможливо створити папку мініатюр.", + "Cannot access or write to upload folder." => "Нма доступу або неможливо записати в папку завантаження.", + "Please enter new folder name." => "Вкажіть назву нової папки.", + "Unallowable characters in folder name." => "Недопустимі символи в назві папки.", + "Folder name shouldn't begins with '.'" => "Назва папки не может починатися з '.'", + "Please enter new file name." => "Вкажіть нову назву файла", + "Unallowable characters in file name." => "Недопустимі символи в назві файлу.", + "File name shouldn't begins with '.'" => "Назва файла не може починатися з '.'", + "Are you sure you want to delete this file?" => "Ви впевнені що хочете вилучити цей файл?", + "Are you sure you want to delete this folder and all its content?" => "Ви впевнені що хочете вилучити цю папку і весь її вміст?", + "Non-existing directory type." => "Неіснуючий тип папки.", + "Undefined MIME types." => "Невизначені MIME-типи.", + "Fileinfo PECL extension is missing." => "Розширення Fileinfo PECL відсутнє.", + "Opening fileinfo database failed." => "Неможливо відкрити базу даних fileinfo.", + "You can't upload such files." => "Ви не можете завантажувати файли цього типу.", + "The file '{file}' does not exist." => "Файл '{file}' не існує.", + "Cannot read '{file}'." => "Неможливо прочитати файл '{file}'.", + "Cannot copy '{file}'." => "Неможливо копіювати файл '{file}'.", + "Cannot move '{file}'." => "Неможливо перемістити файл '{file}'.", + "Cannot delete '{file}'." => "Неможливо вилучити файл '{file}'.", + "Cannot delete the folder." => "Неможливо вилучити папку.", + "Click to remove from the Clipboard" => "Натисніть для вилучення з буфера обміну", + "This file is already added to the Clipboard." => "Цей файл вже додано в буфер обміну.", + "The files in the Clipboard are not readable." => "Неможливо прочитати файли в буфері обміну.", + "{count} files in the Clipboard are not readable. Do you want to copy the rest?" => "Неможливо прочитати {count} файл(ів) в буфері обміну. Ви хочете копіювати ті які залишилися?", + "The files in the Clipboard are not movable." => "Неможливо перемістити файли в буфері обміну.", + "{count} files in the Clipboard are not movable. Do you want to move the rest?" => "Неможливо перемістити {count} файл(ів) в буфері обміну. Ви хчете перемістити ті які залишилися?", + "The files in the Clipboard are not removable." => "Неможливо вилучити файли в буфері обміну.", + "{count} files in the Clipboard are not removable. Do you want to delete the rest?" => "Неможливо вилучити {count} файл(ів) в буфері обміну. Ви хочете вилучити ті які залишилися?", + "The selected files are not removable." => "Неможливо вилучити вибрані файли.", + "{count} selected files are not removable. Do you want to delete the rest?" => "Неможливо вилучити вибраний(ні) {count} файл(и). Ви хочете вилучити ті які залишилися?", + "Are you sure you want to delete all selected files?" => "Ви впевнені що хочете вилучити всі вибрані файли?", + "Failed to delete {count} files/folders." => "Неможливо вилучити {count} файлів/папок.", + "A file or folder with that name already exists." => "Файл або папка з таким іменем вже існують.", + "Copy files here" => "Копіювати файли сюди", + "Move files here" => "Перемістити файли сюда", + "Delete files" => "Вилучити файли", + "Clear the Clipboard" => "Очистити буфер обміну", + "Are you sure you want to delete all files in the Clipboard?" => "Ви впевнені що хочете вилучити всі файли в буфері обміну?", + "Copy {count} files" => "Копіювати {count} файл(ів)", + "Move {count} files" => "Перемістити {count} файл(ів)", + "Add to Clipboard" => "Додати в буфер обміну", + "Inexistant or inaccessible folder." => "Неіснуюча або недоступна папка.", + "New folder name:" => "Нова назва папки:", + "New file name:" => "Нова назва файлу:", + "Upload" => "Завантажити", + "Refresh" => "Оновити", + "Settings" => "Налаштування", + "Maximize" => "Максимізувати", + "About" => "Про скрипт", + "files" => "файли", + "selected files" => "вибрані файли", + "View:" => "Перегляд:", + "Show:" => "Показувати:", + "Order by:" => "Впорядкувати за:", + "Thumbnails" => "Мініатюри", + "List" => "Список", + "Name" => "Назва", + "Type" => "Тип", + "Size" => "Розмір", + "Date" => "Дата", + "Descending" => "По спаданню", + "Uploading file..." => "Завантаження файлу...", + "Loading image..." => "Завантаження зображення...", + "Loading folders..." => "Завантаження папок...", + "Loading files..." => "Завантаження файлів...", + "New Subfolder..." => "Створити папку...", + "Rename..." => "Перейменувати...", + "Delete" => "Вилучити", + "OK" => "OK", + "Cancel" => "Скасувати", + "Select" => "Вибрати", + "Select Thumbnail" => "Вибрати мініатюру", + "Select Thumbnails" => "Вибрати мініатюри", + "View" => "Перегляд", + "Download" => "Зкачати", + "Download files" => "Зкачати файли", + "Clipboard" => "Буфер обміну", + "Checking for new version..." => "Перевіряємо наявність оновлень...", + "Unable to connect!" => "Неможливо підключитися!", + "Download version {version} now!" => "Скачати версію {version} зараз!", + "KCFinder is up to date!" => "Ви використовуєте останню версію KCFinder'а!", + "Licenses:" => "Ліцензії:", + "Attention" => "Увага", + "Question" => "Питання", + "Yes" => "Так", + "No" => "Ні", + "You cannot rename the extension of files!" => "Ви не можете змінювати розширення файлів!", + "Uploading file {number} of {count}... {progress}" => "Завантаження файлу {number} з {count}... {progress}", + "Failed to upload {filename}!" => "Помилка завантаження {filename}!", +); diff --git a/lib/kcfinder/lang/vi.php b/lib/kcfinder/lang/vi.php new file mode 100644 index 0000000..7974066 --- /dev/null +++ b/lib/kcfinder/lang/vi.php @@ -0,0 +1,132 @@ + "Vietnamese", + '_native' => "Việt", + '_locale' => "vi_VN.UTF-8", // UNIX localization code + '_charset' => "utf-8", // Browser charset + + // Date time formats. See http://www.php.net/manual/en/function.strftime.php + '_dateTimeFull' => "%A, %e %B, %Y %H:%M", + '_dateTimeMid' => "%a %e %b %Y %H:%M", + '_dateTimeSmall' => "%d.%m.%Y %H:%M", + + "You don't have permissions to upload files." => "Bạn không có quyền tải lên", + "You don't have permissions to browse server." => "Bạn không có quyền truy cập", + "Cannot move uploaded file to target folder." => "Không thể tải lên thư mục đích", + "Unknown error." => "Lỗi không xác định", + "The uploaded file exceeds {size} bytes." => "Tập tin tải lên lớn hơn {size}", + "The uploaded file was only partially uploaded." => "Các tập tin chỉ được tải lên một phần", + "No file was uploaded." => "Không có tập tin được tải lên", + "Missing a temporary folder." => "Không thấy thư mục tạm", + "Failed to write file." => "Không thể ghi", + "Denied file extension." => "Phần mở rộng không được phép", + "Unknown image format/encoding." => "Không biết định dạng ảnh/mã hóa này", + "The image is too big and/or cannot be resized." => "Hình ảnh quá lơn/hoặc không thể thay đổi kích thước", + "Cannot create {dir} folder." => "Không thể tạo thư mục {dir}", + "Cannot rename the folder." => "Không thể đổi tên thư mục", + "Cannot write to upload folder." => "Không thể ghi vào thư mục", + "Cannot read .htaccess" => "Không thể đọc tập tin .htaccess", + "Incorrect .htaccess file. Cannot rewrite it!" => "không thể ghi tập tin .htaccess", + "Cannot read upload folder." => "Không thể đọc thư mục để tải lên", + "Cannot access or create thumbnails folder." => "Không có quyền truy cập hoặc không thể tạo thư mục", + "Cannot access or write to upload folder." => "Không có quyền truy cập hoặc không thể ghi", + "Please enter new folder name." => "Vui lòng nhập tên thư mục", + "Unallowable characters in folder name." => "Tên thư mục có chứa những ký tự không được phép", + "Folder name shouldn't begins with '.'" => "Thư mục không thể bắt đầu bằng '.'", + "Please enter new file name." => "Vui lòng nhập tên tập tin", + "Unallowable characters in file name." => "Tên tập tin chứa những ký tự không được phép", + "File name shouldn't begins with '.'" => "Tập tin không thể bắt đầu bằng '.'", + "Are you sure you want to delete this file?" => "Bạn có chắc bạn muốn xóa tập tin này?", + "Are you sure you want to delete this folder and all its content?" => "Bạn có chắc bạn muốn xóa thư mục và tất cả nội dung bên trong?", + "Non-existing directory type." => "Không tồn tại thư mục", + "Undefined MIME types." => "Không biết kiểu MIME này", + "Fileinfo PECL extension is missing." => "Fileinfo PECL extension is missing", + "Opening fileinfo database failed." => "Opening fileinfo database failed", + "You can't upload such files." => "Bạn không thể tải các tập tin như vậy.", + "The file '{file}' does not exist." => "Tập tin '{file}' đã có", + "Cannot read '{file}'." => "Không thể đọc '{file}'.", + "Cannot copy '{file}'." => "Không thể sao chép '{file}'.", + "Cannot move '{file}'." => "Không thể di chuyển '{file}'.", + "Cannot delete '{file}'." => "Không thể xóa tập tin '{file}'.", + "Cannot delete the folder." => "Không thể xóa thư mục", + "Click to remove from the Clipboard" => "Không thể xóa từ Bộ nhớ", + "This file is already added to the Clipboard." => "Tập tin đã có trong bộ nhớ", + "The files in the Clipboard are not readable." => "Không thể đọc các tập tin trong Bộ nhớ", + "{count} files in the Clipboard are not readable. Do you want to copy the rest?" => "{count} tập tin trong Bộ nhớ không thể đọc. Bạn chắc chắn muốn sao chép phần còn lại?", + "The files in the Clipboard are not movable." => "Không thể di chuyển các tập tin trong Bộ nhớ", + "{count} files in the Clipboard are not movable. Do you want to move the rest?" => "{count} tập tin trong Bộ nhớ không thể di chuyển. Bạn chắc chắn muốn di chuyển phần còn lại?", + "The files in the Clipboard are not removable." => "Không thể xóa các tập tin trong Bộ nhớ", + "{count} files in the Clipboard are not removable. Do you want to delete the rest?" => "{count} tập tin trong Bộ nhớ không thể xóa. Bạn chắc chắn muốn xóa phần còn lại?", + "The selected files are not removable." => "Lựa chọn tập tin để xóa", + "{count} selected files are not removable. Do you want to delete the rest?" => "{count} tập tin không thể xóa. Bạn chắc chắn muốn xóa phần còn lại?", + "Are you sure you want to delete all selected files?" => "Bạn có chắc bạn muốn xóa tất cả tập tin đựoc chọn?", + "Failed to delete {count} files/folders." => "Không thể xóa {count} tập tin/thư mục", + "A file or folder with that name already exists." => "Đã tồn tại tập tin hoặc thư mục với tên này", + "Copy files here" => "Sao chép ở đây", + "Move files here" => "Di chuyển ở đây", + "Delete files" => "Xóa tập tin", + "Clear the Clipboard" => "Xóa bộ nhớ", + "Are you sure you want to delete all files in the Clipboard?" => "Bạn có chắc bạn muốn xóa tất cả tập tin trong Bộ nhớ?", + "Copy {count} files" => "Sao chep {count} tập tin", + "Move {count} files" => "Di chuyển {count} tập tin", + "Add to Clipboard" => "Thêm vào Bộ nhớ", + "Inexistant or inaccessible folder." => "Thư mục không tồn tại hoặc không thể truy cập", + "New folder name:" => "Tên mới của thư mục", + "New file name:" => "Tên mới của tập tin", + "Upload" => "Tải lên", + "Refresh" => "Làm mới", + "Settings" => "Cấu hình", + "Maximize" => "Tối đa", + "About" => "Giới thiệu", + "files" => "tập tin", + "selected files" => "chọn tập tin", + "View:" => "Xem", + "Show:" => "Hiện", + "Order by:" => "Thứ tự bởi", + "Thumbnails" => "Ảnh thu nhỏ", + "List" => "Danh sách", + "Name" => "Tên", + "Type" => "Kiểu", + "Size" => "Kích thước", + "Date" => "Ngày tháng", + "Descending" => "Giảm dần", + "Uploading file..." => "Đang tải lên", + "Loading image..." => "Đang đọc ảnh", + "Loading folders..." => "Đang đọc thư mục...", + "Loading files..." => "Đang đọc tập tin...", + "New Subfolder..." => "Thư mục con mới...", + "Rename..." => "Đổi tên...", + "Delete" => "Xóa", + "OK" => "Đồng Ý", + "Cancel" => "Hủy", + "Select" => "Chọn", + "Select Thumbnail" => "Chọn ảnh thu nhỏ", + "Select Thumbnails" => "Chọn nhiều ảnh thu nhỏ", + "View" => "Xem", + "Download" => "Tải xuống", + "Download files" => "Tải xuống tập tin", + "Clipboard" => "Bộ nhớ", + "Checking for new version..." => "Kiểm tra phiên bản mới", + "Unable to connect!" => "Không thể kết nối", + "Download version {version} now!" => "Có phiên bản mới {version}, tải về ngay!", + "KCFinder is up to date!" => "Không có cập nhật", + "Licenses:" => "Bản quyền", + "Attention" => "Cảnh báo", + "Question" => "Câu hỏi", + "Yes" => "Có", + "No" => "Không", + "You cannot rename the extension of files!" => "Bạn không thể đổi tên phần mở rộng của các tập tin!", + "Uploading file {number} of {count}... {progress}" => "Đang tải tập tin thứ {number} của {count}... {progress}", + "Failed to upload {filename}!" => "Tải lên thất bại {filename}!", + "Close" => "Đóng", + "Previous" => "Trước", + "Next" => "Sau", + "Confirmation" => "Xác nhận", + "Warning" => "Cảnh báo", +); diff --git a/lib/kcfinder/lang/zh-cn.php b/lib/kcfinder/lang/zh-cn.php new file mode 100644 index 0000000..1e53969 --- /dev/null +++ b/lib/kcfinder/lang/zh-cn.php @@ -0,0 +1,130 @@ + "Chinese Simplified", + '_native' => "中国简体", + '_locale' => "zh_CN.UTF-8", // UNIX localization code + '_charset' => "utf-8", // Browser charset + + // Date time formats. See http://www.php.net/manual/en/function.strftime.php + '_dateTimeFull' => "%A, %e %B, %Y %H:%M", + '_dateTimeMid' => "%a %e %b %Y %H:%M", + '_dateTimeSmall' => "%Y-%m-%d %H:%M", + + "You don't have permissions to upload files." => "您没有权限上传文件。", + "You don't have permissions to browse server." => "您没有权限查看服务器文件。", + "Cannot move uploaded file to target folder." => "无法移动上传文件到指定文件夹。", + "Unknown error." => "发生不可预知异常。", + "The uploaded file exceeds {size} bytes." => "文件大小超过{size}字节。", + "The uploaded file was only partially uploaded." => "文件未完全上传。", + "No file was uploaded." => "文件未上传。", + "Missing a temporary folder." => "临时文件夹不存在。", + "Failed to write file." => "写入文件失败。", + "Denied file extension." => "禁止的文件扩展名。", + "Unknown image format/encoding." => "无法确认图片格式。", + "The image is too big and/or cannot be resized." => "图片大太,且(或)无法更改大小。", + "Cannot create {dir} folder." => "无法创建{dir}文件夹。", + "Cannot rename the folder." => "无法重命名该文件夹。", + "Cannot write to upload folder." => "无法写入上传文件夹。", + "Cannot read .htaccess" => "文件.htaccess无法读取。", + "Incorrect .htaccess file. Cannot rewrite it!" => "文件.htaccess错误,无法重写。", + "Cannot read upload folder." => "无法读取上传目录。", + "Cannot access or create thumbnails folder." => "无法访问或创建缩略图文件夹。", + "Cannot access or write to upload folder." => "无法访问或写入上传文件夹。", + "Please enter new folder name." => "请输入文件夹名。", + "Unallowable characters in folder name." => "文件夹名含有禁止字符。", + "Folder name shouldn't begins with '.'" => "文件夹名不能以点(.)为首字符。", + "Please enter new file name." => "请输入新文件名。", + "Unallowable characters in file name." => "文件名含有禁止字符。", + "File name shouldn't begins with '.'" => "文件名不能以点(.)为首字符。", + "Are you sure you want to delete this file?" => "是否确认删除该文件?", + "Are you sure you want to delete this folder and all its content?" => "是否确认删除该文件夹以及其子文件和子目录?", + "Non-existing directory type." => "不存在的目录类型。", + "Undefined MIME types." => "未定义的MIME类型。", + "Fileinfo PECL extension is missing." => "文件PECL属性不存在。", + "Opening fileinfo database failed." => "打开文件属性数据库出错。", + "You can't upload such files." => "你无法上传该文件。", + "The file '{file}' does not exist." => "文件{file}不存在。", + "Cannot read '{file}'." => "无法读取文件{file}。", + "Cannot copy '{file}'." => "无法复制文件{file}。", + "Cannot move '{file}'." => "无法移动文件{file}。", + "Cannot delete '{file}'." => "无法删除文件{file}。", + "Cannot delete the folder." => "无法删除该文件夹。", + "Click to remove from the Clipboard" => "点击从剪贴板删除", + "This file is already added to the Clipboard." => "文件已复制到剪贴板。", + "The files in the Clipboard are not readable." => "剪贴板上该文件无法读取。", + "{count} files in the Clipboard are not readable. Do you want to copy the rest?" => "剪贴板{count}个文件无法读取。 是否复制静态文件?", + "The files in the Clipboard are not movable." => "剪贴板上该文件无法移动。", + "{count} files in the Clipboard are not movable. Do you want to move the rest?" => "剪贴板{count}个文件无法移动。 是否移动静态文件?", + "The files in the Clipboard are not removable." => "剪贴板上该文件无法删除。", + "{count} files in the Clipboard are not removable. Do you want to delete the rest?" => "剪贴板{count}个文件无法删除。 是否删除静态文件?", + "The selected files are not removable." => "选中文件未删除。", + "{count} selected files are not removable. Do you want to delete the rest?" => "选中的{count}个文件未删除。是否删除静态文件?", + "Are you sure you want to delete all selected files?" => "是否确认删除选中文件?", + "Failed to delete {count} files/folders." => "{count}个文件或文件夹无法删除。", + "A file or folder with that name already exists." => "文件或文件夹已存在。", + "Copy files here" => "复制到这里", + "Move files here" => "移动到这里", + "Delete files" => "删除这些文件", + "Clear the Clipboard" => "清除剪贴板", + "Are you sure you want to delete all files in the Clipboard?" => "是否确认删除所有在剪贴板的文件?", + "Copy {count} files" => "复制 {count} 个文件", + "Move {count} files" => "移动 {count} 个文件 ", + "Add to Clipboard" => "添加到剪贴板", + "Inexistant or inaccessible folder." => "不存在或不可访问的文件夹。", + "New folder name:" => "新文件夹名:", + "New file name:" => "新文件夹:", + "Upload" => "上传", + "Refresh" => "刷新", + "Settings" => "设置", + "Maximize" => "最大化", + "About" => "关于", + "files" => "文件", + "selected files" => "选中的文件", + "View:" => "视图:", + "Show:" => "显示:", + "Order by:" => "排序:", + "Thumbnails" => "图标", + "List" => "列表", + "Name" => "文件名", + "Type" => "种类", + "Size" => "大小", + "Date" => "日期", + "Descending" => "降序", + "Uploading file..." => "正在上传文件...", + "Loading image..." => "正在加载图片...", + "Loading folders..." => "正在加载文件夹...", + "Loading files..." => "正在加载文件...", + "New Subfolder..." => "新建文件夹...", + "Rename..." => "重命名...", + "Delete" => "删除", + "OK" => "OK", + "Cancel" => "取消", + "Select" => "选择", + "Select Thumbnail" => "选择缩略图", + "Select Thumbnails" => "选择缩略图", + "View" => "查看", + "Download" => "下载", + "Download files" => "下载文件", + "Clipboard" => "剪贴板", + "Checking for new version..." => "正在检查新版本...", + "Unable to connect!" => "无法链接!", + "Download version {version} now!" => "马上下载{version}版本!", + "KCFinder is up to date!" => "KCFinder已经是最新的!", + "Licenses:" => "许可证", + "Attention" => "注意", + "Question" => "问题", + "Yes" => "是", + "No" => "否", + "You cannot rename the extension of files!" => "禁止修改文件后缀", + "Uploading file {number} of {count}... {progress}" => "正在上传文件{number} / {count}... {progress}", + "Failed to upload {filename}!" => "上传失败{filename}!", +); diff --git a/lib/kcfinder/lib/.htaccess b/lib/kcfinder/lib/.htaccess new file mode 100644 index 0000000..d61b264 --- /dev/null +++ b/lib/kcfinder/lib/.htaccess @@ -0,0 +1,4 @@ + +Order allow,deny +Deny from all + diff --git a/lib/kcfinder/lib/class_fastImage.php b/lib/kcfinder/lib/class_fastImage.php new file mode 100644 index 0000000..bd4d5c2 --- /dev/null +++ b/lib/kcfinder/lib/class_fastImage.php @@ -0,0 +1,255 @@ +load($uri); + } + + public function load($uri) + { + if ($this->handle) $this->close(); + + $this->uri = $uri; + // Joy - this is a fix for URLs missing "http:" + if ($uri[0] == '/' && $uri[1] == '/') { + $uri = 'http:' . $uri; + } + + $this->handle = fopen( + $uri, + 'r', + false, + stream_context_create(array( + 'http'=> array('timeout' => 0.5), + )) + ); + } + + public function isValid() + { + return empty($this->handle) ? false : true; + } + + public function close() + { + if (is_resource($this->handle)) fclose($this->handle); + } + + + public function getSize() + { + $this->strpos = 0; + if ($this->getType()) + { + return array_values($this->parseSize()); + } + + return false; + } + + + public function getType() + { + $this->strpos = 0; + + if (!$this->type) + { + switch ($this->getChars(2)) + { + case "BM": + return $this->type = 'bmp'; + case "GI": + return $this->type = 'gif'; + case chr(0xFF).chr(0xd8): + return $this->type = 'jpeg'; + case chr(0x89).'P': + return $this->type = 'png'; + default: + return false; + } + } + + return $this->type; + } + + + private function parseSize() + { + $this->strpos = 0; + + switch ($this->type) + { + case 'png': + return $this->parseSizeForPNG(); + case 'gif': + return $this->parseSizeForGIF(); + case 'bmp': + return $this->parseSizeForBMP(); + case 'jpeg': + return $this->parseSizeForJPEG(); + } + + return null; + } + + + private function parseSizeForPNG() + { + $chars = $this->getChars(25); + + return unpack("N*", substr($chars, 16, 8)); + } + + + private function parseSizeForGIF() + { + $chars = $this->getChars(11); + + return unpack("S*", substr($chars, 6, 4)); + } + + + private function parseSizeForBMP() + { + $chars = $this->getChars(29); + $chars = substr($chars, 14, 14); + $type = unpack('C', $chars); + + return (reset($type) == 40) ? unpack('L*', substr($chars, 4)) : unpack('L*', substr($chars, 4, 8)); + } + + + private function parseSizeForJPEG() + { + $state = null; + $i = 0; + + while (true) + { + switch ($state) + { + default: + $this->getChars(2); + $state = 'started'; + break; + case 'started': + $b = $this->getByte(); + if ($b === false) return false; + + $state = $b == 0xFF ? 'sof' : 'started'; + break; + + case 'sof': + $b = $this->getByte(); + if (in_array($b, range(0xe0, 0xef))) + { + $state = 'skipframe'; + } + elseif (in_array($b, array_merge(range(0xC0,0xC3), range(0xC5,0xC7), range(0xC9,0xCB), range(0xCD,0xCF)))) + { + $state = 'readsize'; + } + elseif ($b == 0xFF) + { + $state = 'sof'; + } + else + { + $state = 'skipframe'; + } + break; + + case 'skipframe': + $skip = $this->readInt($this->getChars(2)) - 2; + $state = 'doskip'; + break; + + case 'doskip': + $this->getChars($skip); + $state = 'started'; + break; + + case 'readsize': + $c = $this->getChars(7); + + return array($this->readInt(substr($c, 5, 2)), $this->readInt(substr($c, 3, 2))); + } + } + } + + + private function getChars($n) + { + $response = null; + + // do we need more data? + if ($this->strpos + $n -1 >= strlen($this->str)) + { + $end = ($this->strpos + $n); + + while (strlen($this->str) < $end && $response !== false) + { + // read more from the file handle + $need = $end - ftell($this->handle); + + if ($response = fread($this->handle, $need)) + { + $this->str .= $response; + } + else + { + return false; + } + } + } + + $result = substr($this->str, $this->strpos, $n); + $this->strpos += $n; + + return $result; + } + + + private function getByte() + { + $c = $this->getChars(1); + $b = unpack("C", $c); + + return reset($b); + } + + + private function readInt($str) + { + $size = unpack("C*", $str); + + return ($size[1] << 8) + $size[2]; + } + + + public function __destruct() + { + $this->close(); + } +} \ No newline at end of file diff --git a/lib/kcfinder/lib/class_image.php b/lib/kcfinder/lib/class_image.php new file mode 100644 index 0000000..0e6666e --- /dev/null +++ b/lib/kcfinder/lib/class_image.php @@ -0,0 +1,241 @@ + + * @copyright 2010-2014 KCFinder Project + * @license http://opensource.org/licenses/GPL-3.0 GPLv3 + * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3 + * @link http://kcfinder.sunhater.com + */ + +namespace kcfinder; + +abstract class image { + const DEFAULT_JPEG_QUALITY = 75; + +/** Image resource or object + * @var mixed */ + protected $image; + +/** Image width in pixels + * @var integer */ + protected $width; + +/** Image height in pixels + * @var integer */ + protected $height; + +/** Init error + * @var bool */ + protected $initError = false; + +/** Driver specific options + * @var array */ + protected $options = array(); + + +/** Magic method which allows read-only access to all protected or private + * class properties + * @param string $property + * @return mixed */ + + final public function __get($property) { + return property_exists($this, $property) ? $this->$property : null; + } + + +/** Constructor. Parameter $image should be: + * 1. An instance of image driver class (copy instance). + * 2. An image represented by the type of the $image property + * (resource or object). + * 3. An array with two elements. First - width, second - height. + * Creates a blank image. + * 4. A filename string. Get image form file. + * Second paramaeter is used by pass some specific image driver options + * @param mixed $image + * @param array $options */ + + public function __construct($image, array $options=array()) { + $this->image = $this->width = $this->height = null; + $imageDetails = $this->buildImage($image); + + if ($imageDetails !== false) + list($this->image, $this->width, $this->height) = $imageDetails; + else + $this->initError = true; + $this->options = $options; + } + + +/** Factory pattern to load selected driver. $image and $options are passed + * to the constructor of the image driver + * @param string $driver + * @param mixed $image + * @return object */ + + final static function factory($driver, $image, array $options=array()) { + $class = __NAMESPACE__ . "\\image_$driver"; + return new $class($image, $options); + } + + +/** Checks if the drivers in the array parameter could be used. Returns first + * found one + * @param array $drivers + * @return string */ + + final static function getDriver(array $drivers=array('gd')) { + foreach ($drivers as $driver) { + if (!preg_match('/^[a-z0-9\_]+$/i', $driver)) + continue; + $class = __NAMESPACE__ . "\\image_$driver"; + if (class_exists($class) && method_exists($class, "available")) { + eval("\$avail = $class::available();"); + if ($avail) return $driver; + } + } + return false; + } + + +/** Returns an array. Element 0 - image resource. Element 1 - width. Element 2 - height. + * Returns FALSE on failure. + * @param mixed $image + * @return array */ + + final protected function buildImage($image) { + $class = get_class($this); + + if ($image instanceof $class) { + $width = $image->width; + $height = $image->height; + $img = $image->image; + + } elseif (is_array($image)) { + list($key, $width) = each($image); + list($key, $height) = each($image); + $img = $this->getBlankImage($width, $height); + + } else + $img = $this->getImage($image, $width, $height); + + return ($img !== false) + ? array($img, $width, $height) + : false; + } + + +/** Returns calculated proportional width from the given height + * @param integer $resizedHeight + * @return integer */ + + final public function getPropWidth($resizedHeight) { + $width = round(($this->width * $resizedHeight) / $this->height); + if (!$width) $width = 1; + return $width; + } + + +/** Returns calculated proportional height from the given width + * @param integer $resizedWidth + * @return integer */ + + final public function getPropHeight($resizedWidth) { + $height = round(($this->height * $resizedWidth) / $this->width); + if (!$height) $height = 1; + return $height; + } + + +/** Checks if PHP needs some extra extensions to use the image driver. This + * static method should be implemented into driver classes like abstract + * methods + * @return bool */ + static function available() { return false; } + +/** Checks if file is an image. This static method should be implemented into + * driver classes like abstract methods + * @param string $file + * @return bool */ + static function checkImage($file) { return false; } + +/** Resize image. Should return TRUE on success or FALSE on failure + * @param integer $width + * @param integer $height + * @return bool */ + abstract public function resize($width, $height); + +/** Resize image to fit in given resolution. Should returns TRUE on success + * or FALSE on failure. If $background is set, the image size will be + * $width x $height and the empty spaces (if any) will be filled with defined + * color. Background color examples: "#5f5", "#ff67ca", array(255, 255, 255) + * @param integer $width + * @param integer $height + * @param mixed $background + * @return bool */ + abstract public function resizeFit($width, $height, $background=false); + +/** Resize and crop the image to fit in given resolution. Returns TRUE on + * success or FALSE on failure + * @param mixed $src + * @param integer $offset + * @return bool */ + abstract public function resizeCrop($width, $height, $offset=false); + + +/** Rotate image + * @param integer $angle + * @param string $background + * @return bool */ + abstract public function rotate($angle, $background="#000000"); + + abstract public function flipHorizontal(); + + abstract public function flipVertical(); + +/** Apply a PNG or GIF watermark to the image. $top and $left parameters sets + * the offset of the watermark in pixels. Boolean and NULL values are possible + * too. In default case (FALSE, FALSE) the watermark should be applyed to + * the bottom right corner. NULL values means center aligning. If the + * watermark is bigger than the image or it's partialy or fully outside the + * image, it shoudn't be applied + * @param string $file + * @param mixed $top + * @param mixed $left + * @return bool */ + abstract public function watermark($file, $left=false, $top=false); + +/** Should output the image. Second parameter is used to pass some options like + * 'file' - if is set, the output will be written to a file + * 'quality' - compression quality + * It's possible to use extra specific options required by image type ($type) + * @param string $type + * @param array $options + * @return bool */ + abstract public function output($type='jpeg', array $options=array()); + +/** This method should create a blank image with selected size. Should returns + * resource or object related to the created image, which will be passed to + * $image property + * @param integer $width + * @param integer $height + * @return mixed */ + abstract protected function getBlankImage($width, $height); + +/** This method should create an image from source image. Only first parameter + * ($image) is input. Its type should be filename string or a type of the + * $image property. See the constructor reference for details. The + * parametters $width and $height are output only. Should returns resource or + * object related to the created image, which will be passed to $image + * property + * @param mixed $image + * @param integer $width + * @param integer $height + * @return mixed */ + abstract protected function getImage($image, &$width, &$height); + +} diff --git a/lib/kcfinder/lib/class_image_gd.php b/lib/kcfinder/lib/class_image_gd.php new file mode 100644 index 0000000..98f79be --- /dev/null +++ b/lib/kcfinder/lib/class_image_gd.php @@ -0,0 +1,352 @@ + + * @copyright 2010-2014 KCFinder Project + * @license http://opensource.org/licenses/GPL-3.0 GPLv3 + * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3 + * @link http://kcfinder.sunhater.com + */ + +namespace kcfinder; + +class image_gd extends image { + + + // ABSTRACT PUBLIC METHODS + + public function resize($width, $height) { + if (!$width) $width = 1; + if (!$height) $height = 1; + return ( + (false !== ($img = new image_gd(array($width, $height)))) && + $img->imageCopyResampled($this) && + (false !== ($this->image = $img->image)) && + (false !== ($this->width = $img->width)) && + (false !== ($this->height = $img->height)) + ); + } + + public function resizeFit($width, $height, $background=false) { + if ((!$width && !$height) || (($width == $this->width) && ($height == $this->height))) + return true; + if (!$width || (($height / $width) < ($this->height / $this->width))) { + $h = $height; + $w = round(($this->width * $h) / $this->height); + } elseif (!$height || (($width / $height) < ($this->width / $this->height))) { + $w = $width; + $h = round(($this->height * $w) / $this->width); + } else { + $w = $width; + $h = $height; + } + if (!$w) $w = 1; + if (!$h) $h = 1; + + if ($background === false) + return $this->resize($w, $h); + + else { + $img = new image_gd(array($width, $height)); + $x = round(($width - $w) / 2); + $y = round(($height - $h) / 2); + + if ((false === $this->resize($w, $h)) || + (false === $img->imageFilledRectangle(0, 0, $width, $height, $background)) || + (false === $img->imageCopyResampled($this->image, $x, $y, 0, 0, $w, $h)) + ) + return false; + + $this->image = $img->image; + $this->width = $width; + $this->height = $height; + + return true; + } + } + + public function resizeCrop($width, $height, $offset=false) { + + if (($this->width / $this->height) > ($width / $height)) { + $h = $height; + $w = ($this->width * $h) / $this->height; + $y = 0; + if ($offset !== false) { + if ($offset > 0) + $offset = -$offset; + if (($w + $offset) <= $width) + $offset = $width - $w; + $x = $offset; + } else + $x = ($width - $w) / 2; + + } else { + $w = $width; + $h = ($this->height * $w) / $this->width; + $x = 0; + if ($offset !== false) { + if ($offset > 0) + $offset = -$offset; + if (($h + $offset) <= $height) + $offset = $height - $h; + $y = $offset; + } else + $y = ($height - $h) / 2; + } + + $x = round($x); + $y = round($y); + $w = round($w); + $h = round($h); + if (!$w) $w = 1; + if (!$h) $h = 1; + + $return = ( + (false !== ($img = new image_gd(array($width, $height))))) && + (false !== ($img->imageCopyResampled($this->image, $x, $y, 0, 0, $w, $h)) + ); + + if ($return) { + $this->image = $img->image; + $this->width = $w; + $this->height = $h; + } + + return $return; + } + + public function rotate($angle, $background="#000000") { + $angle = -$angle; + $img = @imagerotate($this->image, $angle, $this->gdColor($background)); + if ($img === false) + return false; + $this->width = imagesx($img); + $this->height = imagesy($img); + $this->image = $img; + return true; + } + + public function flipHorizontal() { + $img = imagecreatetruecolor($this->width, $this->height); + if (imagecopyresampled($img, $this->image, 0, 0, ($this->width - 1), 0, $this->width, $this->height, -$this->width, $this->height)) + $this->image = $img; + else + return false; + return true; + } + + public function flipVertical() { + $img = imagecreatetruecolor($this->width, $this->height); + if (imagecopyresampled($img, $this->image, 0, 0, 0, ($this->height - 1), $this->width, $this->height, $this->width, -$this->height)) + $this->image = $img; + else + return false; + return true; + } + + public function watermark($file, $left=false, $top=false) { + $info = getimagesize($file); + list($w, $h, $t) = $info; + if (!in_array($t, array(IMAGETYPE_PNG, IMAGETYPE_GIF))) + return false; + $imagecreate = ($t == IMAGETYPE_PNG) ? "imagecreatefrompng" : "imagecreatefromgif"; + + if (!@imagealphablending($this->image, true) || + (false === ($wm = @$imagecreate($file))) + ) + return false; + + $w = imagesx($wm); + $h = imagesy($wm); + $x = + ($left === true) ? 0 : ( + ($left === null) ? round(($this->width - $w) / 2) : ( + (($left === false) || !preg_match('/^\d+$/', $left)) ? ($this->width - $w) : $left)); + $y = + ($top === true) ? 0 : ( + ($top === null) ? round(($this->height - $h) / 2) : ( + (($top === false) || !preg_match('/^\d+$/', $top)) ? ($this->height - $h) : $top)); + + if ((($x + $w) > $this->width) || + (($y + $h) > $this->height) || + ($x < 0) || ($y < 0) + ) + return false; + + if (($wm === false) || !@imagecopy($this->image, $wm, $x, $y, 0, 0, $w, $h)) + return false; + + @imagealphablending($this->image, false); + @imagesavealpha($this->image, true); + return true; + } + + public function output($type='jpeg', array $options=array()) { + $method = "output_$type"; + if (!method_exists($this, $method)) + return false; + return $this->$method($options); + } + + + // ABSTRACT PROTECTED METHODS + + protected function getBlankImage($width, $height) { + $image = imagecreatetruecolor($width, $height); + imagealphablending($image, false); + imagesavealpha($image, true); + return $image; + } + + protected function getImage($image, &$width, &$height) { + + if (is_resource($image) && (get_resource_type($image) == "gd")) { + $width = @imagesx($image); + $height = @imagesy($image); + imagealphablending($image, false); + imagesavealpha($image, true); + return $image; + + } elseif (is_string($image) && + (false !== (list($width, $height, $t) = @getimagesize($image))) + ) { + $image = + ($t == IMAGETYPE_GIF) ? @imagecreatefromgif($image) : ( + ($t == IMAGETYPE_WBMP) ? @imagecreatefromwbmp($image) : ( + ($t == IMAGETYPE_JPEG) ? @imagecreatefromjpeg($image) : ( + ($t == IMAGETYPE_PNG) ? @imagecreatefrompng($image) : ( + ($t == IMAGETYPE_XBM) ? @imagecreatefromxbm($image) : false + )))); + + if ($t == IMAGETYPE_PNG) { + imagealphablending($image, false); + imagesavealpha($image, true); + } + return $image; + + } else + return false; + } + + + // PSEUDO-ABSTRACT STATIC METHODS + + static function available() { + return function_exists("imagecreatefromjpeg"); + } + + static function checkImage($file) { + if (!is_string($file) || + ((false === (list($width, $height, $t) = @getimagesize($file)))) + ) + return false; + + $img = + ($t == IMAGETYPE_GIF) ? @imagecreatefromgif($file) : ( + ($t == IMAGETYPE_WBMP) ? @imagecreatefromwbmp($file) : ( + ($t == IMAGETYPE_JPEG) ? @imagecreatefromjpeg($file) : ( + ($t == IMAGETYPE_PNG) ? @imagecreatefrompng($file) : ( + ($t == IMAGETYPE_XBM) ? @imagecreatefromxbm($file) : false + )))); + + return ($img !== false); + } + + + // OWN METHODS + + protected function output_png(array $options=array()) { + $file = isset($options['file']) ? $options['file'] : null; + $quality = isset($options['quality']) ? $options['quality'] : null; + $filters = isset($options['filters']) ? $options['filters'] : null; + if (($file === null) && !headers_sent()) + header("Content-Type: image/png"); + return imagepng($this->image, $file, $quality, $filters); + } + + protected function output_jpeg(array $options=array()) { + $file = isset($options['file']) ? $options['file'] : null; + $quality = isset($options['quality']) + ? $options['quality'] + : self::DEFAULT_JPEG_QUALITY; + if (($file === null) && !headers_sent()) + header("Content-Type: image/jpeg"); + return imagejpeg($this->image, $file, $quality); + } + + protected function output_gif(array $options=array()) { + $file = isset($options['file']) ? $options['file'] : null; + if (isset($options['file']) && !headers_sent()) + header("Content-Type: image/gif"); + return imagegif($this->image, $file); + } + + protected function gdColor() { + $args = func_get_args(); + + $exprRGB = '/^rgb\(\s*(\d{1,3})\s*\,\s*(\d{1,3})\s*\,\s*(\d{1,3})\s*\)$/i'; + $exprHex1 = '/^\#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i'; + $exprHex2 = '/^\#?([0-9a-f])([0-9a-f])([0-9a-f])$/i'; + $exprByte = '/^([01]?\d?\d|2[0-4]\d|25[0-5])$/'; + + if (!isset($args[0])) + return false; + + if (count($args[0]) == 3) { + list($r, $g, $b) = $args[0]; + + } elseif (preg_match($exprRGB, $args[0], $match)) { + list($tmp, $r, $g, $b) = $match; + + } elseif (preg_match($exprHex1, $args[0], $match)) { + list($tmp, $r, $g, $b) = $match; + $r = hexdec($r); + $g = hexdec($g); + $b = hexdec($b); + + } elseif (preg_match($exprHex2, $args[0], $match)) { + list($tmp, $r, $g, $b) = $match; + $r = hexdec("$r$r"); + $g = hexdec("$g$g"); + $b = hexdec("$b$b"); + + } elseif ((count($args) == 3) && + preg_match($exprByte, $args[0]) && + preg_match($exprByte, $args[1]) && + preg_match($exprByte, $args[2]) + ) { + list($r, $g, $b) = $args; + + } else + return false; + + return imagecolorallocate($this->image, $r, $g, $b); + } + + protected function imageFilledRectangle($x1, $y1, $x2, $y2, $color) { + $color = $this->gdColor($color); + if ($color === false) return false; + return imageFilledRectangle($this->image, $x1, $y1, $x2, $y2, $color); + } + + protected function imageCopyResampled( + $src, $dstX=0, $dstY=0, $srcX=0, $srcY=0, $dstW=null, $dstH=null, $srcW=null, $srcH=null + ) { + $imageDetails = $this->buildImage($src); + + if ($imageDetails === false) + return false; + + list($src, $srcWidth, $srcHeight) = $imageDetails; + + if (is_null($dstW)) $dstW = $this->width - $dstW; + if (is_null($dstH)) $dstH = $this->height - $dstY; + if (is_null($srcW)) $srcW = $srcWidth - $srcX; + if (is_null($srcH)) $srcH = $srcHeight - $srcY; + return imageCopyResampled($this->image, $src, $dstX, $dstY, $srcX, $srcY, $dstW, $dstH, $srcW, $srcH); + } +} diff --git a/lib/kcfinder/lib/class_image_gmagick.php b/lib/kcfinder/lib/class_image_gmagick.php new file mode 100644 index 0000000..41ef437 --- /dev/null +++ b/lib/kcfinder/lib/class_image_gmagick.php @@ -0,0 +1,302 @@ + + * @copyright 2010-2014 KCFinder Project + * @license http://opensource.org/licenses/GPL-3.0 GPLv3 + * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3 + * @link http://kcfinder.sunhater.com + */ + +namespace kcfinder; + +class image_gmagick extends image { + + static $MIMES = array( + //'tif' => "image/tiff" + ); + + + // ABSTRACT PUBLIC METHODS + + public function resize($width, $height) {// + if (!$width) $width = 1; + if (!$height) $height = 1; + try { + $this->image->scaleImage($width, $height); + } catch (\Exception $e) { + return false; + } + $this->width = $width; + $this->height = $height; + return true; + } + + public function resizeFit($width, $height, $background=false) {// + if (!$width) $width = 1; + if (!$height) $height = 1; + + try { + $this->image->scaleImage($width, $height, true); + $w = $this->image->getImageWidth(); + $h = $this->image->getImageHeight(); + } catch (\Exception $e) { + return false; + } + + if ($background === false) { + $this->width = $w; + $this->height = $h; + return true; + + } else { + try { + $this->image->setImageBackgroundColor($background); + $x = round(($width - $w) / 2); + $y = round(($height - $h) / 2); + $img = new \Gmagick(); + $img->newImage($width, $height, $background); + $img->compositeImage($this->image, 1, $x, $y); + } catch (\Exception $e) { + return false; + } + $this->image = $img; + $this->width = $width; + $this->height = $height; + return true; + } + } + + public function resizeCrop($width, $height, $offset=false) { + if (!$width) $width = 1; + if (!$height) $height = 1; + + if (($this->width / $this->height) > ($width / $height)) { + $h = $height; + $w = ($this->width * $h) / $this->height; + $y = 0; + if ($offset !== false) { + if ($offset > 0) + $offset = -$offset; + if (($w + $offset) <= $width) + $offset = $width - $w; + $x = $offset; + } else + $x = ($width - $w) / 2; + + } else { + $w = $width; + $h = ($this->height * $w) / $this->width; + $x = 0; + if ($offset !== false) { + if ($offset > 0) + $offset = -$offset; + if (($h + $offset) <= $height) + $offset = $height - $h; + $y = $offset; + } else + $y = ($height - $h) / 2; + } + + $x = round($x); + $y = round($y); + $w = round($w); + $h = round($h); + if (!$w) $w = 1; + if (!$h) $h = 1; + + try { + $this->image->scaleImage($w, $h); + $this->image->cropImage($width, $height, -$x, -$y); + } catch (\Exception $e) { + return false; + } + + $this->width = $width; + $this->height = $height; + return true; + } + + public function rotate($angle, $background="#000000") { + try { + $this->image->rotateImage($background, $angle); + $w = $this->image->getImageWidth(); + $h = $this->image->getImageHeight(); + } catch (\Exception $e) { + return false; + } + $this->width = $w; + $this->height = $h; + return true; + } + + public function flipHorizontal() { + try { + $this->image->flopImage(); + } catch (\Exception $e) { + return false; + } + return true; + } + + public function flipVertical() { + try { + $this->image->flipImage(); + } catch (\Exception $e) { + return false; + } + return true; + } + + public function watermark($file, $left=false, $top=false) { + try { + $wm = new \Gmagick($file); + $w = $wm->getImageWidth(); + $h = $wm->getImageHeight(); + } catch (\Exception $e) { + return false; + } + + $x = + ($left === true) ? 0 : ( + ($left === null) ? round(($this->width - $w) / 2) : ( + (($left === false) || !preg_match('/^\d+$/', $left)) ? ($this->width - $w) : $left)); + $y = + ($top === true) ? 0 : ( + ($top === null) ? round(($this->height - $h) / 2) : ( + (($top === false) || !preg_match('/^\d+$/', $top)) ? ($this->height - $h) : $top)); + + if ((($x + $w) > $this->width) || + (($y + $h) > $this->height) || + ($x < 0) || ($y < 0) + ) + return false; + + try { + $this->image->compositeImage($wm, 1, $x, $y); + } catch (\Exception $e) { + return false; + } + return true; + } + + + // ABSTRACT PROTECTED METHODS + + protected function getBlankImage($width, $height) { + try { + $img = new \Gmagick(); + $img->newImage($width, $height, "none"); + } catch (\Exception $e) { + return false; + } + return $img; + } + + protected function getImage($image, &$width, &$height) { + + if (is_object($image) && ($image instanceof image_gmagick)) { + $width = $image->width; + $height = $image->height; + return $image->image; + + } elseif (is_object($image) && ($image instanceof \Gmagick)) { + try { + $w = $image->getImageWidth(); + $h = $image->getImageHeight(); + } catch (\Exception $e) { + return false; + } + $width = $w; + $height = $h; + return $image; + + } elseif (is_string($image)) { + try { + $image = new \Gmagick($image); + $w = $image->getImageWidth(); + $h = $image->getImageHeight(); + } catch (\Exception $e) { + return false; + } + $width = $w; + $height = $h; + return $image; + + } else + return false; + } + + + // PSEUDO-ABSTRACT STATIC METHODS + + static function available() { + return class_exists("Gmagick"); + } + + static function checkImage($file) { + try { + $img = new \Gmagick($file); + } catch (\Exception $e) { + return false; + } + return true; + } + + + // INHERIT METHODS + + public function output($type="jpeg", array $options=array()) { + $type = strtolower($type); + try { + $this->image->setImageFormat($type); + } catch (\Exception $e) { + return false; + } + $method = "optimize_$type"; + if (method_exists($this, $method) && !$this->$method($options)) + return false; + + if (!isset($options['file'])) { + if (!headers_sent()) { + $mime = isset(self::$MIMES[$type]) ? self::$MIMES[$type] : "image/$type"; + header("Content-Type: $mime"); + } + echo $this->image; + + } else { + $file = $options['file'] . ".$type"; + try { + $this->image->writeImage($file); + } catch (\Exception $e) { + @unlink($file); + return false; + } + + if (!@rename($file, $options['file'])) { + @unlink($file); + return false; + } + } + + return true; + } + + + // OWN METHODS + + protected function optimize_jpeg(array $options=array()) { + $quality = isset($options['quality']) ? $options['quality'] : self::DEFAULT_JPEG_QUALITY; + try { + $this->image->setCompressionQuality($quality); + } catch (\Exception $e) { + return false; + } + return true; + } + +} diff --git a/lib/kcfinder/lib/class_image_imagick.php b/lib/kcfinder/lib/class_image_imagick.php new file mode 100644 index 0000000..59bc39d --- /dev/null +++ b/lib/kcfinder/lib/class_image_imagick.php @@ -0,0 +1,305 @@ + + * @copyright 2010-2014 KCFinder Project + * @license http://opensource.org/licenses/GPL-3.0 GPLv3 + * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3 + * @link http://kcfinder.sunhater.com + */ + +namespace kcfinder; + +class image_imagick extends image { + + static $MIMES = array( + //'tif' => "image/tiff" + ); + + + // ABSTRACT PUBLIC METHODS + + public function resize($width, $height) {// + if (!$width) $width = 1; + if (!$height) $height = 1; + try { + $this->image->scaleImage($width, $height); + } catch (\Exception $e) { + return false; + } + $this->width = $width; + $this->height = $height; + return true; + } + + public function resizeFit($width, $height, $background=false) {// + if (!$width) $width = 1; + if (!$height) $height = 1; + + try { + $this->image->scaleImage($width, $height, true); + $size = $this->image->getImageGeometry(); + } catch (\Exception $e) { + return false; + } + + if ($background === false) { + $this->width = $size['width']; + $this->height = $size['height']; + return true; + + } else { + try { + $this->image->setImageBackgroundColor($background); + $x = -round(($width - $size['width']) / 2); + $y = -round(($height - $size['height']) / 2); + $this->image->extentImage($width, $height, $x, $y); + } catch (\Exception $e) { + return false; + } + $this->width = $width; + $this->height = $height; + return true; + } + } + + public function resizeCrop($width, $height, $offset=false) { + if (!$width) $width = 1; + if (!$height) $height = 1; + + if (($this->width / $this->height) > ($width / $height)) { + $h = $height; + $w = ($this->width * $h) / $this->height; + $y = 0; + if ($offset !== false) { + if ($offset > 0) + $offset = -$offset; + if (($w + $offset) <= $width) + $offset = $width - $w; + $x = $offset; + } else + $x = ($width - $w) / 2; + + } else { + $w = $width; + $h = ($this->height * $w) / $this->width; + $x = 0; + if ($offset !== false) { + if ($offset > 0) + $offset = -$offset; + if (($h + $offset) <= $height) + $offset = $height - $h; + $y = $offset; + } else + $y = ($height - $h) / 2; + } + + $x = round($x); + $y = round($y); + $w = round($w); + $h = round($h); + if (!$w) $w = 1; + if (!$h) $h = 1; + + try { + $this->image->scaleImage($w, $h); + $this->image->cropImage($width, $height, -$x, -$y); + } catch (\Exception $e) { + return false; + } + + $this->width = $width; + $this->height = $height; + return true; + } + + public function rotate($angle, $background="#000000") { + try { + $this->image->rotateImage(new \ImagickPixel($background), $angle); + $size = $this->image->getImageGeometry(); + } catch (\Exception $e) { + return false; + } + $this->width = $size['width']; + $this->height = $size['height']; + return true; + } + + public function flipHorizontal() { + try { + $this->image->flopImage(); + } catch (\Exception $e) { + return false; + } + return true; + } + + public function flipVertical() { + try { + $this->image->flipImage(); + } catch (\Exception $e) { + return false; + } + return true; + } + + public function watermark($file, $left=false, $top=false) { + try { + $wm = new \Imagick($file); + $size = $wm->getImageGeometry(); + } catch (\Exception $e) { + return false; + } + + $w = $size['width']; + $h = $size['height']; + $x = + ($left === true) ? 0 : ( + ($left === null) ? round(($this->width - $w) / 2) : ( + (($left === false) || !preg_match('/^\d+$/', $left)) ? ($this->width - $w) : $left)); + $y = + ($top === true) ? 0 : ( + ($top === null) ? round(($this->height - $h) / 2) : ( + (($top === false) || !preg_match('/^\d+$/', $top)) ? ($this->height - $h) : $top)); + + if ((($x + $w) > $this->width) || + (($y + $h) > $this->height) || + ($x < 0) || ($y < 0) + ) + return false; + + try { + $this->image->compositeImage($wm, \Imagick::COMPOSITE_DEFAULT, $x, $y); + } catch (\Exception $e) { + return false; + } + return true; + } + + + // ABSTRACT PROTECTED METHODS + + protected function getBlankImage($width, $height) { + try { + $img = new \Imagick(); + $img->newImage($width, $height, "none"); + $img->setImageCompressionQuality(100); + } catch (\Exception $e) { + return false; + } + return $img; + } + + protected function getImage($image, &$width, &$height) { + + if (is_object($image) && ($image instanceof image_imagick)) { + try { + $image->image->setImageCompressionQuality(100); + } catch (\Exception $e) { + return false; + } + $width = $image->width; + $height = $image->height; + return $image->image; + + } elseif (is_object($image) && ($image instanceof \Imagick)) { + try { + $image->setImageCompressionQuality(100); + $size = $image->getImageGeometry(); + } catch (\Exception $e) { + return false; + } + $width = $size['width']; + $height = $size['height']; + return $image; + + } elseif (is_string($image)) { + try { + $image = new \Imagick($image); + $image->setImageCompressionQuality(100); + $size = $image->getImageGeometry(); + } catch (\Exception $e) { + return false; + } + $width = $size['width']; + $height = $size['height']; + return $image; + + } else + return false; + } + + + // PSEUDO-ABSTRACT STATIC METHODS + + static function available() { + return class_exists("\\Imagick"); + } + + static function checkImage($file) { + try { + $img = new \Imagick($file); + } catch (\Exception $e) { + return false; + } + return true; + } + + + // INHERIT METHODS + + public function output($type="jpeg", array $options=array()) { + $type = strtolower($type); + try { + $this->image->setImageFormat($type); + } catch (\Exception $e) { + return false; + } + $method = "optimize_$type"; + if (method_exists($this, $method) && !$this->$method($options)) + return false; + + if (!isset($options['file'])) { + if (!headers_sent()) { + $mime = isset(self::$MIMES[$type]) ? self::$MIMES[$type] : "image/$type"; + header("Content-Type: $mime"); + } + echo $this->image; + + } else { + $file = $options['file'] . ".$type"; + try { + $this->image->writeImage($file); + } catch (\Exception $e) { + @unlink($file); + return false; + } + + if (!@rename($file, $options['file'])) { + @unlink($file); + return false; + } + } + + return true; + } + + + // OWN METHODS + + protected function optimize_jpeg(array $options=array()) { + $quality = isset($options['quality']) ? $options['quality'] : self::DEFAULT_JPEG_QUALITY; + try { + $this->image->setImageCompression(\Imagick::COMPRESSION_JPEG); + $this->image->setImageCompressionQuality($quality); + } catch (\Exception $e) { + return false; + } + return true; + } + +} diff --git a/lib/kcfinder/lib/class_zipFolder.php b/lib/kcfinder/lib/class_zipFolder.php new file mode 100644 index 0000000..64b446e --- /dev/null +++ b/lib/kcfinder/lib/class_zipFolder.php @@ -0,0 +1,60 @@ + + * @copyright 2010-2014 KCFinder Project + * @license http://opensource.org/licenses/GPL-3.0 GPLv3 + * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3 + * @link http://kcfinder.sunhater.com + */ + +namespace kcfinder; + +class zipFolder { + protected $zip; + protected $root; + protected $ignored; + + function __construct($file, $folder, $ignored=null) { + $this->zip = new \ZipArchive(); + + $this->ignored = is_array($ignored) + ? $ignored + : ($ignored ? array($ignored) : array()); + + if ($this->zip->open($file, \ZipArchive::CREATE) !== TRUE) + throw new \Exception("cannot open <$file>\n"); + + $folder = rtrim($folder, '/'); + + if (strstr($folder, '/')) { + $this->root = substr($folder, 0, strrpos($folder, '/') + 1); + $folder = substr($folder, strrpos($folder, '/') + 1); + } + + $this->zip($folder); + $this->zip->close(); + } + + function zip($folder, $parent=null) { + $full_path = "{$this->root}$parent$folder"; + $zip_path = "$parent$folder"; + $this->zip->addEmptyDir($zip_path); + $dir = new \DirectoryIterator($full_path); + foreach ($dir as $file) + if (!$file->isDot()) { + $filename = $file->getFilename(); + if (!in_array($filename, $this->ignored)) { + if ($file->isDir()) + $this->zip($filename, "$zip_path/"); + else + $this->zip->addFile("$full_path/$filename", "$zip_path/$filename"); + } + } + } +} diff --git a/lib/kcfinder/lib/helper_dir.php b/lib/kcfinder/lib/helper_dir.php new file mode 100644 index 0000000..a197a27 --- /dev/null +++ b/lib/kcfinder/lib/helper_dir.php @@ -0,0 +1,156 @@ + + * @copyright 2010-2014 KCFinder Project + * @license http://opensource.org/licenses/GPL-3.0 GPLv3 + * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3 + * @link http://kcfinder.sunhater.com + */ + +namespace kcfinder; + +class dir { + +/** Checks if the given directory is really writable. The standard PHP + * function is_writable() does not work properly on Windows servers + * @param string $dir + * @return bool */ + + static function isWritable($dir) { + $dir = path::normalize($dir); + if (!is_dir($dir)) + return false; + $i = 0; + do { + $file = "$dir/is_writable_" . md5($i++); + } while (file_exists($file)); + if (!@touch($file)) + return false; + unlink($file); + return true; + } + +/** Recursively delete the given directory. Returns TRUE on success. + * If $firstFailExit parameter is true (default), the method returns the + * path to the first failed file or directory which cannot be deleted. + * If $firstFailExit is false, the method returns an array with failed + * files and directories which cannot be deleted. The third parameter + * $failed is used for internal use only. + * @param string $dir + * @param bool $firstFailExit + * @param array $failed + * @return mixed */ + + static function prune($dir, $firstFailExit=true, array $failed=null) { + if ($failed === null) $failed = array(); + $files = self::content($dir); + if ($files === false) { + if ($firstFailExit) + return $dir; + $failed[] = $dir; + return $failed; + } + + foreach ($files as $file) { + if (is_dir($file)) { + $failed_in = self::prune($file, $firstFailExit, $failed); + if ($failed_in !== true) { + if ($firstFailExit) + return $failed_in; + if (is_array($failed_in)) + $failed = array_merge($failed, $failed_in); + else + $failed[] = $failed_in; + } + } elseif (!@unlink($file)) { + if ($firstFailExit) + return $file; + $failed[] = $file; + } + } + + if (!@rmdir($dir)) { + if ($firstFailExit) + return $dir; + $failed[] = $dir; + } + + return count($failed) ? $failed : true; + } + +/** Get the content of the given directory. Returns an array with filenames + * or FALSE on failure + * @param string $dir + * @param array $options + * @return mixed */ + + static function content($dir, array $options=null) { + + $defaultOptions = array( + 'types' => "all", // Allowed: "all" or possible return values + // of filetype(), or an array with them + 'addPath' => true, // Whether to add directory path to filenames + 'pattern' => '/./', // Regular expression pattern for filename + 'followLinks' => true + ); + + if (!is_dir($dir) || !is_readable($dir)) + return false; + + if (strtoupper(substr(PHP_OS, 0, 3)) == "WIN") + $dir = str_replace("\\", "/", $dir); + $dir = rtrim($dir, "/"); + + $dh = @opendir($dir); + if ($dh === false) + return false; + + if ($options === null) + $options = $defaultOptions; + + foreach ($defaultOptions as $key => $val) + if (!isset($options[$key])) + $options[$key] = $val; + + $files = array(); + while (($file = @readdir($dh)) !== false) { + + if (($file == '.') || ($file == '..') || + !preg_match($options['pattern'], $file) + ) + continue; + + $fullpath = "$dir/$file"; + $type = filetype($fullpath); + + // If file is a symlink, get the true type of its destination + if ($options['followLinks'] && ($type == "link")) + $type = filetype(realpath($fullpath)); + + if (($options['types'] === "all") || ($type === $options['types']) || + (is_array($options['types']) && in_array($type, $options['types'])) + ) + $files[] = $options['addPath'] ? $fullpath : $file; + } + closedir($dh); + usort($files, array(__NAMESPACE__ . "\\dir", "fileSort")); + return $files; + } + + static function fileSort($a, $b) { + if (function_exists("mb_strtolower")) { + $a = mb_strtolower($a); + $b = mb_strtolower($b); + } else { + $a = strtolower($a); + $b = strtolower($b); + } + if ($a == $b) return 0; + return ($a < $b) ? -1 : 1; + } +} diff --git a/lib/kcfinder/lib/helper_file.php b/lib/kcfinder/lib/helper_file.php new file mode 100644 index 0000000..5c3c34f --- /dev/null +++ b/lib/kcfinder/lib/helper_file.php @@ -0,0 +1,214 @@ + + * @copyright 2010-2014 KCFinder Project + * @license http://opensource.org/licenses/GPL-3.0 GPLv3 + * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3 + * @link http://kcfinder.sunhater.com + */ + +namespace kcfinder; + +class file { + + static $MIME = array( + 'ai' => 'application/postscript', + 'aif' => 'audio/x-aiff', + 'aifc' => 'audio/x-aiff', + 'aiff' => 'audio/x-aiff', + 'avi' => 'video/x-msvideo', + 'bin' => 'application/macbinary', + 'bmp' => 'image/bmp', + 'cpt' => 'application/mac-compactpro', + 'css' => 'text/css', + 'csv' => 'text/x-comma-separated-values', + 'dcr' => 'application/x-director', + 'dir' => 'application/x-director', + 'doc' => 'application/msword', + 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'dvi' => 'application/x-dvi', + 'dxr' => 'application/x-director', + 'eml' => 'message/rfc822', + 'eps' => 'application/postscript', + 'flv' => 'video/x-flv', + 'gif' => 'image/gif', + 'gtar' => 'application/x-gtar', + 'gz' => 'application/x-gzip', + 'hqx' => 'application/mac-binhex40', + 'htm' => 'text/html', + 'html' => 'text/html', + 'jpe' => 'image/jpeg', + 'jpeg' => 'image/jpeg', + 'jpg' => 'image/jpeg', + 'js' => 'application/x-javascript', + 'log' => 'text/plain', + 'mid' => 'audio/midi', + 'midi' => 'audio/midi', + 'mif' => 'application/vnd.mif', + 'mov' => 'video/quicktime', + 'movie' => 'video/x-sgi-movie', + 'mp2' => 'audio/mpeg', + 'mp3' => 'audio/mpeg', + 'mp4' => 'video/mpeg', + 'mpe' => 'video/mpeg', + 'mpeg' => 'video/mpeg', + 'mpg' => 'video/mpeg', + 'mpga' => 'audio/mpeg', + 'oda' => 'application/oda', + 'pdf' => 'application/pdf', + 'php' => 'application/x-httpd-php', + 'php3' => 'application/x-httpd-php', + 'php4' => 'application/x-httpd-php', + 'phps' => 'application/x-httpd-php-source', + 'phtml' => 'application/x-httpd-php', + 'png' => 'image/png', + 'ppt' => 'application/powerpoint', + 'ps' => 'application/postscript', + 'psd' => 'application/x-photoshop', + 'qt' => 'video/quicktime', + 'ra' => 'audio/x-realaudio', + 'ram' => 'audio/x-pn-realaudio', + 'rm' => 'audio/x-pn-realaudio', + 'rpm' => 'audio/x-pn-realaudio-plugin', + 'rtf' => 'text/rtf', + 'rtx' => 'text/richtext', + 'rv' => 'video/vnd.rn-realvideo', + 'shtml' => 'text/html', + 'sit' => 'application/x-stuffit', + 'smi' => 'application/smil', + 'smil' => 'application/smil', + 'swf' => 'application/x-shockwave-flash', + 'tar' => 'application/x-tar', + 'tgz' => 'application/x-tar', + 'text' => 'text/plain', + 'tif' => 'image/tiff', + 'tiff' => 'image/tiff', + 'txt' => 'text/plain', + 'wav' => 'audio/x-wav', + 'wbxml' => 'application/wbxml', + 'wmlc' => 'application/wmlc', + 'word' => 'application/msword', + 'xht' => 'application/xhtml+xml', + 'xhtml' => 'application/xhtml+xml', + 'xl' => 'application/excel', + 'xls' => 'application/excel', + 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'xml' => 'text/xml', + 'xsl' => 'text/xml', + 'zip' => 'application/x-zip' + ); + +/** Checks if the given file is really writable. The standard PHP function + * is_writable() does not work properly on Windows servers. + * @param string $filename + * @return bool */ + + static function isWritable($filename) { + $filename = path::normalize($filename); + if (!is_file($filename) || (false === ($fp = @fopen($filename, 'a+')))) + return false; + fclose($fp); + return true; + } + +/** Get the extension from filename + * @param string $filename + * @param bool $toLower + * @return string */ + + static function getExtension($filename, $toLower=true) { + return preg_match('/^.*\.([^\.]*)$/s', $filename, $patt) + ? ($toLower ? strtolower($patt[1]) : $patt[1]) : ""; + } + +/** Get MIME type of the given filename. If Fileinfo PHP extension is + * available the MIME type will be fetched by the file's content. The + * second parameter is optional and defines the magic file path. If you + * skip it, the default one will be loaded. + * If Fileinfo PHP extension is not available the MIME type will be fetched + * by filename extension regarding $MIME property. If the file extension + * does not exist there, returned type will be application/octet-stream + * @param string $filename + * @param string $magic + * @return string */ + + static function getMimeType($filename, $magic=null) { + if (class_exists("finfo")) { + $finfo = new \finfo(FILEINFO_MIME, $magic); + if ($finfo) { + $mime = $finfo->file($filename); + $mime = substr($mime, 0, strrpos($mime, ";")); + return $mime; + } + } + $ext = self::getExtension($filename, true); + return isset(self::$MIME[$ext]) ? self::$MIME[$ext] : "application/octet-stream"; + } + +/** Get inexistant filename based on the given filename. If you skip $dir + * parameter the directory will be fetched from $filename and returned + * value will be full filename path. The third parameter is optional and + * defines the template, the filename will be renamed to. Default template + * is {name}({sufix}){ext}. Examples: + * + * file::getInexistantFilename("/my/directory/myfile.txt"); + * If myfile.txt does not exist - returns the same path to the file + * otherwise returns "/my/directory/myfile(1).txt" + * + * file::getInexistantFilename("myfile.txt", "/my/directory"); + * returns "myfile.txt" or "myfile(1).txt" or "myfile(2).txt" etc... + * + * file::getInexistantFilename("myfile.txt", "/dir", "{name}[{sufix}]{ext}"); + * returns "myfile.txt" or "myfile[1].txt" or "myfile[2].txt" etc... + * + * @param string $filename + * @param string $dir + * @param string $tpl + * @return string */ + + static function getInexistantFilename($filename, $dir=null, $tpl=null) { + if ($tpl === null) $tpl = "{name}({sufix}){ext}"; + $fullPath = ($dir === null); + if ($fullPath) + $dir = path::normalize(dirname($filename)); + else { + $fdir = dirname($filename); + $dir = strlen($fdir) + ? path::normalize("$dir/$fdir") + : path::normalize($dir); + } + $filename = basename($filename); + $ext = self::getExtension($filename, false); + $name = strlen($ext) ? substr($filename, 0, -strlen($ext) - 1) : $filename; + $tpl = str_replace('{name}', $name, $tpl); + $tpl = str_replace('{ext}', (strlen($ext) ? ".$ext" : ""), $tpl); + $i = 1; $file = "$dir/$filename"; + while (file_exists($file)) + $file = "$dir/" . str_replace('{sufix}', $i++, $tpl); + + return $fullPath + ? $file + : (strlen($fdir) + ? "$fdir/" . basename($file) + : basename($file)); + } + +/** Normalize given filename. Accented characters becomes non-accented and + * removes any other special characters. Usable for non-unicode filesystems + * @param $filename + * @return string */ + + static function normalizeFilename($filename) { + $string = htmlentities($filename, ENT_QUOTES, 'UTF-8'); + if (strpos($string, '&') !== false) + $filename = html_entity_decode(preg_replace('~&([a-z]{1,2})(?:acute|cedil|circ|grave|lig|orn|ring|slash|tilde|uml);~i', '$1', $string), ENT_QUOTES, 'UTF-8'); + $filename = trim(preg_replace('~[^0-9a-z\.\- ]~i', "_", $filename)); + return $filename; + } + +} diff --git a/lib/kcfinder/lib/helper_httpCache.php b/lib/kcfinder/lib/helper_httpCache.php new file mode 100644 index 0000000..24e022a --- /dev/null +++ b/lib/kcfinder/lib/helper_httpCache.php @@ -0,0 +1,98 @@ + + * @copyright 2010-2014 KCFinder Project + * @license http://opensource.org/licenses/GPL-3.0 GPLv3 + * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3 + * @link http://kcfinder.sunhater.com + */ + +namespace kcfinder; + +class httpCache { + const DEFAULT_TYPE = "text/html"; + const DEFAULT_EXPIRE = 604800; // in seconds + +/** Cache a file. The $type parameter might define the MIME type of the file + * or path to magic file to autodetect the MIME type. If you skip $type + * parameter the method will try with the default magic file. Autodetection + * of MIME type requires Fileinfo PHP extension used in file::getMimeType() + * @param string $file + * @param string $type + * @param integer $expire + * @param array $headers */ + + static function file($file, $type=null, $expire=null, array $headers=null) { + $mtime = @filemtime($file); + if ($mtime !== false) self::checkMTime($mtime); + + if ($type === null) { + $magic = ((substr($type, 0, 1) == "/") || preg_match('/^[a-z]\:/i', $type)) + ? $type : null; + $type = file::getMimeType($file, $magic); + if (!$type) $type = null; + } + + self::content(@file_get_contents($file), $mtime, $type, $expire, $headers, false); + } + +/** Cache the given $content with $mtime modification time. + * @param binary $content + * @param integer $mtime + * @param string $type + * @param integer $expire + * @param array $headers + * @param bool $checkMTime */ + + static function content($content, $mtime, $type=null, $expire=null, array $headers=null, $checkMTime=true) { + if ($checkMTime) self::checkMTime($mtime); + if ($type === null) $type = self::DEFAULT_TYPE; + if ($expire === null) $expire = self::DEFAULT_EXPIRE; + $size = strlen($content); + $expires = gmdate("D, d M Y H:i:s", time() + $expire) . " GMT"; + header("Content-Type: $type"); + header("Expires: $expires"); + header("Cache-Control: max-age=$expire"); + header("Pragma: !invalid"); + header("Content-Length: $size"); + if ($headers !== null) foreach ($headers as $header) header($header); + echo $content; + } + +/** Check if given modification time is newer than client-side one. If not, + * the method will tell the client to get the content from its own cache. + * Afterwards the script process will be terminated. This feature requires + * the PHP to be configured as Apache module. + * @param integer $mtime + * @param mixed $sendHeaders */ + + static function checkMTime($mtime, $sendHeaders=null) { + header("Last-Modified: " . gmdate("D, d M Y H:i:s", $mtime) . " GMT"); + + $headers = function_exists("getallheaders") + ? getallheaders() + : (function_exists("apache_request_headers") + ? apache_request_headers() + : false); + + if (is_array($headers) && isset($headers['If-Modified-Since'])) { + $client_mtime = explode(';', $headers['If-Modified-Since']); + $client_mtime = @strtotime($client_mtime[0]); + if ($client_mtime >= $mtime) { + header('HTTP/1.1 304 Not Modified'); + if (is_array($sendHeaders) && count($sendHeaders)) + foreach ($sendHeaders as $header) + header($header); + elseif ($sendHeaders !== null) + header($sendHeaders); + die; + } + } + } + +} diff --git a/lib/kcfinder/lib/helper_path.php b/lib/kcfinder/lib/helper_path.php new file mode 100644 index 0000000..e2e085a --- /dev/null +++ b/lib/kcfinder/lib/helper_path.php @@ -0,0 +1,147 @@ + + * @copyright 2010-2014 KCFinder Project + * @license http://opensource.org/licenses/GPL-3.0 GPLv3 + * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3 + * @link http://kcfinder.sunhater.com + */ + +namespace kcfinder; + +class path { + +/** Get the absolute URL path of the given one. Returns FALSE if the URL + * is not valid or the current directory cannot be resolved (getcwd()) + * @param string $path + * @return string */ + + static function rel2abs_url($path) { + if (substr($path, 0, 1) == "/") return $path; + $dir = @getcwd(); + + if (!isset($_SERVER['DOCUMENT_ROOT']) || ($dir === false)) + return false; + + $dir = self::normalize($dir); + $doc_root = self::normalize(realpath($_SERVER['DOCUMENT_ROOT'])); + + if (substr($dir, 0, strlen($doc_root)) != $doc_root) + return false; + + $return = self::normalize(substr($dir, strlen($doc_root)) . "/$path"); + if (substr($return, 0, 1) !== "/") + $return = "/$return"; + + return $return; + } + +/** Resolve full filesystem path of given URL. Returns FALSE if the URL + * cannot be resolved + * @param string $url + * @return string */ + + static function url2fullPath($url) { + $url = self::normalize($url); + + $uri = isset($_SERVER['SCRIPT_NAME']) + ? $_SERVER['SCRIPT_NAME'] : (isset($_SERVER['PHP_SELF']) + ? $_SERVER['PHP_SELF'] + : false); + + $uri = self::normalize($uri); + + if (substr($url, 0, 1) !== "/") { + if ($uri === false) return false; + $url = dirname($uri) . "/$url"; + } + + if (isset($_SERVER['DOCUMENT_ROOT'])) { + return self::normalize(realpath($_SERVER['DOCUMENT_ROOT']) . "/$url"); + + } else { + if ($uri === false) return false; + + if (isset($_SERVER['SCRIPT_FILENAME'])) { + $scr_filename = self::normalize($_SERVER['SCRIPT_FILENAME']); + return self::normalize(substr($scr_filename, 0, -strlen($uri)) . "/$url"); + } + + $count = count(explode('/', $uri)) - 1; + for ($i = 0, $chdir = ""; $i < $count; $i++) + $chdir .= "../"; + $chdir = self::normalize($chdir); + + $dir = getcwd(); + if (($dir === false) || !@chdir($chdir)) + return false; + $rdir = getcwd(); + chdir($dir); + return ($rdir !== false) ? self::normalize($rdir . "/$url") : false; + } + } + +/** Normalize the given path. On Windows servers backslash will be replaced + * with slash. Removes unnecessary double slashes and double dots. Removes + * last slash if it exists. Examples: + * path::normalize("C:\\any\\path\\") returns "C:/any/path" + * path::normalize("/your/path/..//home/") returns "/your/home" + * @param string $path + * @return string */ + + static function normalize($path) { + + // Backslash to slash convert + if (strtoupper(substr(PHP_OS, 0, 3)) == "WIN") { + $path = preg_replace('/([^\\\])\\\+([^\\\])/s', "$1/$2", $path); + if (substr($path, -1) == "\\") $path = substr($path, 0, -1); + if (substr($path, 0, 1) == "\\") $path = "/" . substr($path, 1); + } + + $path = preg_replace('/\/+/s', "/", $path); + + $path = "/$path"; + if (substr($path, -1) != "/") + $path .= "/"; + + $expr = '/\/([^\/]{1}|[^\.\/]{2}|[^\/]{3,})\/\.\.\//s'; + while (preg_match($expr, $path)) + $path = preg_replace($expr, "/", $path); + + $path = substr($path, 0, -1); + $path = substr($path, 1); + return $path; + } + +/** Encode URL Path + * @param string $path + * @return string */ + + static function urlPathEncode($path) { + $path = self::normalize($path); + $encoded = ""; + foreach (explode("/", $path) as $dir) + $encoded .= rawurlencode($dir) . "/"; + $encoded = substr($encoded, 0, -1); + return $encoded; + } + +/** Decode URL Path + * @param string $path + * @return string */ + + static function urlPathDecode($path) { + $path = self::normalize($path); + $decoded = ""; + foreach (explode("/", $path) as $dir) + $decoded .= rawurldecode($dir) . "/"; + $decoded = substr($decoded, 0, -1); + return $decoded; + } + +} diff --git a/lib/kcfinder/lib/helper_phpGet.php b/lib/kcfinder/lib/helper_phpGet.php new file mode 100644 index 0000000..3b6c83b --- /dev/null +++ b/lib/kcfinder/lib/helper_phpGet.php @@ -0,0 +1,158 @@ + + * @copyright 2010-2014 KCFinder Project + * @license http://opensource.org/licenses/GPL-3.0 GPLv3 + * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3 + * @link http://kcfinder.sunhater.com + */ + +namespace kcfinder; + +class phpGet { + + static public $methods = array('curl', 'fopen', 'http', 'socket'); + static public $urlExpr = '/^([a-z]+):\/\/((([\p{L}\d\-]+\.)+[\p{L}]{1,4})(\:(\d{1,6}))?(\/.*)*)?$/u'; + static public $socketExpr = '/^[A-Z]+\/\d+(\.\d+)\s+\d+\s+OK\s*([a-zA-Z0-9\-]+\:\s*[^\n]*\n)*\s*([a-f0-9]+\r?\n)?(.*)$/s'; + + static public function get($url, $file=null, $method=null) { + if ($file === true) + $file = basename($url); + if ($file !== null) { + if (is_dir($file)) + $file = rtrim($file, '/') . '/' . basename($url); + $exists = file_exists($file); + if (!@touch($file)) + return false; + if (!$exists) + @unlink($file); + } + + if (in_array($method, self::$methods, true)) { + $check = "check_$method"; + $get = "get_$method"; + if (self::$check()) + $content = self::$get($url); + else + return false; + } else { + + foreach (self::$methods as $m) { + $check = "check_$m"; + $get = "get_$m"; + if (self::$check()) { + $content = self::$get($url); + if ((($method !== true) && (strtolower($method) != "all")) || + ($content !== false) + ) + break; + } + } + if (!isset($content)) + return false; + } + + return ($file !== null) + ? @file_put_contents($file, $content) + : $content; + } + + static public function get_fopen($url) { + return @file_get_contents($url); + } + + static public function get_curl($url) { + return ( + (false !== ( $curl = @curl_init($url) )) && + ( @ob_start() || (@curl_close($curl) && false)) && + ( @curl_exec($curl) || (@curl_close($curl) && false)) && + ((false !== ( $content = @ob_get_clean() )) || (@curl_close($curl) && false)) && + ( @curl_close($curl) || true) + ) + ? $content + : false; + } + + static public function get_http($url) { + return ( + (false !== ($content = @http_get($url))) && + ( + ( + preg_match(self::$socketExpr, $content, $match) && + false !== ($content = $match[4]) + ) || true + ) + ) + ? $content + : false; + } + + static public function get_socket($url) { + if (!preg_match(self::$urlExpr, $url, $match)) + return false; + + $protocol = $match[1]; + $host = $match[3]; + $port = strlen($match[6]) ? $match[6] : 80; + $path = strlen($match[7]) ? $match[7] : "/"; + + $cmd = + "GET $path " . strtoupper($protocol) . "/1.1\r\n" . + "Host: $host\r\n" . + "Connection: Close\r\n\r\n"; + + if ((false !== ( $socket = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP) )) && + (false !== @socket_connect($socket, $host, $port) ) && + (false !== @socket_write($socket, $cmd, strlen($cmd)) ) && + (false !== ( $content = @socket_read($socket, 2048) )) + ) { + do { + $piece = @socket_read($socket, 2048); + $content .= $piece; + } while ($piece); + + $content = preg_match(self::$socketExpr, $content, $match) + ? $match[4] : false; + } + + if (isset($socket) && is_resource($socket)) + @socket_close($socket); + else + return false; + + return isset($content) ? $content : false; + } + + static private function check_fopen() { + return + ini_get('allow_url_fopen') && + function_exists('file_get_contents'); + } + + static private function check_curl() { + return + function_exists('curl_init') && + function_exists('curl_exec') && + function_exists('curl_close') && + function_exists('ob_start') && + function_exists('ob_get_clean'); + } + + static private function check_http() { + return function_exists('http_get'); + } + + static private function check_socket() { + return + function_exists('socket_create') && + function_exists('socket_connect') && + function_exists('socket_write') && + function_exists('socket_read') && + function_exists('socket_close'); + } +} diff --git a/lib/kcfinder/lib/helper_text.php b/lib/kcfinder/lib/helper_text.php new file mode 100644 index 0000000..d750e5e --- /dev/null +++ b/lib/kcfinder/lib/helper_text.php @@ -0,0 +1,53 @@ + + * @copyright 2010-2014 KCFinder Project + * @license http://opensource.org/licenses/GPL-3.0 GPLv3 + * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3 + * @link http://kcfinder.sunhater.com + */ + +namespace kcfinder; + +class text { + +/** Replace repeated white spaces to single space + * @param string $string + * @return string */ + + static function clearWhitespaces($string) { + return trim(preg_replace('/\s+/s', " ", $string)); + } + +/** Normalize the string for HTML attribute value + * @param string $string + * @return string */ + + static function htmlValue($string) { + return + str_replace('"', """, + str_replace("'", ''', + str_replace('<', '<', + str_replace('&', "&", + $string)))); + } + +/** Normalize the string for JavaScript string value + * @param string $string + * @return string */ + + static function jsValue($string) { + return + preg_replace('/\r?\n/', "\\n", + str_replace('"', "\\\"", + str_replace("'", "\\'", + str_replace("\\", "\\\\", + $string)))); + } + +} diff --git a/lib/kcfinder/themes/dark/01.ui.css b/lib/kcfinder/themes/dark/01.ui.css new file mode 100644 index 0000000..ca54ed5 --- /dev/null +++ b/lib/kcfinder/themes/dark/01.ui.css @@ -0,0 +1,1499 @@ +/* + +This CSS code is generated from http://ui.sunhater.com +(c)2014 Pavel Tzonkov, sunhater.com. All rights reserved. + +*/ +/*** jQueryUI */ +/** Base */ + +.ui-helper-hidden { + display: none; +} +.ui-helper-hidden-accessible { + border: 0; + clip: rect(0 0 0 0); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; +} +.ui-helper-reset { + margin: 0; + padding: 0; + border: 0; + outline: 0; + line-height: 1.3; + text-decoration: none; + font-size: 100%; + list-style: none; +} +.ui-helper-clearfix:before, +.ui-helper-clearfix:after { + content: ""; + display: table; + border-collapse: collapse; +} +.ui-helper-clearfix:after { + clear: both; +} +.ui-helper-clearfix { + min-height: 0; /* support: IE7 */ +} +.ui-helper-zfix { + width: 100%; + height: 100%; + top: 0; + left: 0; + position: absolute; + opacity: 0; + filter:alpha(opacity=0); +} + +.ui-front { + z-index: 100; +} + +.ui-widget .ui-widget, +.ui-widget input, +.ui-widget select, +.ui-widget textarea, +.ui-widget button { + font-size: 1em; +} +.ui-widget-content { + border: 1px solid #888; + background: #000; + color: #aaa; +} +.ui-widget-content a { + color: #aaa; +} +.ui-widget-header { + border: 1px solid #4685b3; + color: #fff; + font-weight: bold; + background: #184977; + background: -webkit-linear-gradient(top, #184977, #4685b3); + background: -moz-linear-gradient(top, #184977, #4685b3); + background: -ms-linear-gradient(top, #184977, #4685b3); + background: -o-linear-gradient(top, #184977, #4685b3); + background: linear-gradient(to bottom, #184977, #4685b3); +} +.ui-widget-header a { + color: #fff; +} + +/* Interaction states +----------------------------------*/ + +.ui-state-default, +.ui-widget-content .ui-state-default, +.ui-widget-header .ui-state-default, +.ui-widget.ui-state-disabled { + transition: .2s; + border: 1px solid #555; + background: #333; + background: -webkit-linear-gradient(top, #555, #111); + background: -moz-linear-gradient(top, #555, #111); + background: -ms-linear-gradient(top, #555, #111); + background: -o-linear-gradient(top, #555, #111); + background: linear-gradient(to bottom, #555, #111); + font-weight: bold; + color: #aaa; +} + +.ui-state-hover, +.ui-widget-content .ui-state-hover, +.ui-widget-header .ui-state-hover, +.ui-state-focus, +.ui-widget-content .ui-state-focus, +.ui-widget-header .ui-state-focus { + transition: .2s; + background: -webkit-linear-gradient(top, #111, #555); + background: -moz-linear-gradient(top, #111, #555); + background: -ms-linear-gradient(top, #111, #555); + background: -o-linear-gradient(top, #111, #555); + background: linear-gradient(to bottom, #111, #555); +} + +.ui-state-active, +.ui-widget-content .ui-state-active, +.ui-widget-header .ui-state-active, +.ui-menu .ui-state-focus { + transition: .2s; + border: 1px solid #184977; + background: #4685b3; + background: -webkit-linear-gradient(top, #184977, #4685b3); + background: -moz-linear-gradient(top, #184977, #4685b3); + background: -ms-linear-gradient(top, #184977, #4685b3); + background: -o-linear-gradient(top, #184977, #4685b3); + background: linear-gradient(to bottom, #184977, #4685b3); + font-weight: bold; + color: #fff; +} + +.ui-state-default a, +.ui-state-default a:link, +.ui-state-default a:visited, +.ui-state-hover a, +.ui-state-hover a:hover, +.ui-state-hover a:link, +.ui-state-hover a:visited, +.ui-state-active a, +.ui-state-active a:link, +.ui-state-active a:visited { + transition: .2s; + color: #fff; + text-decoration: none; +} + +.ui-menu .ui-state-active { + transition: .2s; + border-color: #6b6b6b; + background: #6b6b6b; + background: -webkit-linear-gradient(top, #6b6b6b, #ababab); + background: -moz-linear-gradient(top, #6b6b6b, #ababab); + background: -ms-linear-gradient(top, #6b6b6b, #ababab); + background: -o-linear-gradient(top, #6b6b6b, #ababab); + background: linear-gradient(to bottom, #6b6b6b, #ababab); +} + +/* Interaction Cues +----------------------------------*/ + +.ui-state-highlight, +.ui-widget-content .ui-state-highlight, +.ui-widget-header .ui-state-highlight { + border: 1px solid #d5bc2c; + box-shadow: inset 0 0 5px #d5bc2c; + background: #fff6bf; + color: #aaa; +} +.ui-state-error, +.ui-widget-content .ui-state-error, +.ui-widget-header .ui-state-error { + border: 1px solid #cf7f7f; + box-shadow: inset 0 0 5px #cf7f7f; + background: #fac4c4; + color: #aaa; +} +.ui-state-error a, +.ui-widget-content .ui-state-error a, +.ui-widget-header .ui-state-error a, +.ui-state-highlight a, +.ui-widget-content .ui-state-highlight a, +.ui-widget-header .ui-state-highlight a, +.ui-state-error-text, +.ui-widget-content .ui-state-error-text, +.ui-widget-header .ui-state-error-text { + color: #aaa; +} +.ui-priority-primary, +.ui-widget-content .ui-priority-primary, +.ui-widget-header .ui-priority-primary { + font-weight: bold; +} +.ui-priority-secondary, +.ui-widget-content .ui-priority-secondary, +.ui-widget-header .ui-priority-secondary { + opacity: .5; + filter:alpha(opacity=50); + font-weight: normal; +} +.ui-state-disabled, +.ui-widget-content .ui-state-disabled, +.ui-widget-header .ui-state-disabled { + opacity: .50; + filter:alpha(opacity=50); + background-image: none; +} +.ui-state-disabled .ui-icon { + filter:alpha(opacity=50); /* For IE8 - See #6059 */ +} + +/* Interaction Cues +----------------------------------*/ +.ui-state-disabled { + cursor: default !important; +} + +/* Misc visuals +----------------------------------*/ + +/* Overlays */ +.ui-widget-overlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; +} +.ui-resizable { + position: relative; +} +.ui-resizable-handle { + position: absolute; + font-size: 0.1px; + display: block; +} +.ui-resizable-disabled .ui-resizable-handle, +.ui-resizable-autohide .ui-resizable-handle { + display: none; +} +.ui-resizable-n { + cursor: n-resize; + height: 7px; + width: 100%; + top: -5px; + left: 0; +} +.ui-resizable-s { + cursor: s-resize; + height: 7px; + width: 100%; + bottom: -5px; + left: 0; +} +.ui-resizable-e { + cursor: e-resize; + width: 7px; + right: -5px; + top: 0; + height: 100%; +} +.ui-resizable-w { + cursor: w-resize; + width: 7px; + left: -5px; + top: 0; + height: 100%; +} +.ui-resizable-se { + cursor: se-resize; + width: 12px; + height: 12px; + right: 1px; + bottom: 1px; +} +.ui-resizable-sw { + cursor: sw-resize; + width: 9px; + height: 9px; + left: -5px; + bottom: -5px; +} +.ui-resizable-nw { + cursor: nw-resize; + width: 9px; + height: 9px; + left: -5px; + top: -5px; +} +.ui-resizable-ne { + cursor: ne-resize; + width: 9px; + height: 9px; + right: -5px; + top: -5px; +} +.ui-selectable-helper { + position: absolute; + z-index: 100; + border: 1px dotted black; +} + + +/** Accordion */ + +.ui-accordion .ui-accordion-header { + display: block; + cursor: pointer; + position: relative; + margin-top: 2px; + padding: 6px; + min-height: 0; /* support: IE7 */ +} +.ui-accordion .ui-accordion-icons, +.ui-accordion .ui-accordion-icons .ui-accordion-icons { + padding-left: 24px; +} +.ui-accordion .ui-accordion-noicons { + padding-left: 5px; +} + +.ui-accordion .ui-accordion-header .ui-accordion-header-icon { + position: absolute; + left: 5px; + top: 50%; + margin-top: -8px; +} +.ui-accordion .ui-accordion-content { + padding: 1em; + border-top: 0; + overflow: auto; +} + + +/** Autocomplete */ + +.ui-autocomplete { + position: absolute; + top: 0; + left: 0; + cursor: pointer; +} + + +/** Button */ + +.ui-button { + display: inline-block; + position: relative; + padding: 0; + line-height: normal; + cursor: pointer; + vertical-align: middle; + text-align: center; + overflow: visible; /* removes extra width in IE */ +} +.ui-button, +.ui-button:link, +.ui-button:visited, +.ui-button:hover, +.ui-button:active { + text-decoration: none; +} +/* to make room for the icon, a width needs to be set here */ +.ui-button-icon-only { + width: 36px; +} +.ui-button-icons-only { + width: 50px; +} +/* button text element */ +.ui-button .ui-button-text { + display: block; + line-height: normal; +} +.ui-button-text-only .ui-button-text { + padding: 6px 10px; +} +.ui-button-icon-only .ui-button-text, +.ui-button-icons-only .ui-button-text { + padding: 6px; + text-indent: -9999999px; +} +.ui-button-text-icon-primary .ui-button-text, +.ui-button-text-icons .ui-button-text { + padding: 6px 10px 6px 28px; +} +.ui-button-text-icon-secondary .ui-button-text, +.ui-button-text-icons .ui-button-text { + padding: 6px 28px 6px 10px; +} +.ui-button-text-icons .ui-button-text { + padding-left: 28px; + padding-right: 28px; +} +/* no icon support for input elements, provide padding by default */ +input.ui-button { + padding: 6px 10px; +} + +/* button icon element(s) */ +.ui-button-icon-only .ui-icon, +.ui-button-text-icon-primary .ui-icon, +.ui-button-text-icon-secondary .ui-icon, +.ui-button-text-icons .ui-icon, +.ui-button-icons-only .ui-icon { + position: absolute; + top: 50%; + margin-top: -8px; +} +.ui-button-icon-only .ui-icon { + left: 50%; + margin-left: -8px; +} +.ui-button-text-icon-primary .ui-button-icon-primary, +.ui-button-text-icons .ui-button-icon-primary, +.ui-button-icons-only .ui-button-icon-primary { + left: 7px; +} +.ui-button-text-icon-secondary .ui-button-icon-secondary, +.ui-button-text-icons .ui-button-icon-secondary, +.ui-button-icons-only .ui-button-icon-secondary { + right: 7px; +} +/* workarounds */ +/* reset extra padding in Firefox, see h5bp.com/l */ +input.ui-button::-moz-focus-inner, +button.ui-button::-moz-focus-inner { + border: 0; + padding: 0; +} + + +/** Button set */ + +.ui-buttonset { + margin:0; + overflow:auto; +} +.ui-buttonset .ui-button { + margin: 0; + float:left; +} + + +/** Date picker */ + +.ui-datepicker { + width: 19em; + display: none; + padding: 10px; +} +.ui-datepicker .ui-datepicker-header { + position: relative; + padding: 2px 0; +} +.ui-datepicker .ui-datepicker-prev, +.ui-datepicker .ui-datepicker-next { + position: absolute; + top: 4px; + width: 20px; + height: 20px; +} +.ui-datepicker .ui-datepicker-prev-hover, +.ui-datepicker .ui-datepicker-next-hover { + top: 3px; +} +.ui-datepicker .ui-datepicker-prev { + left: 4px; +} +.ui-datepicker .ui-datepicker-next { + right: 4px; +} +.ui-datepicker .ui-datepicker-prev-hover { + left: 3px; +} +.ui-datepicker .ui-datepicker-next-hover { + right: 3px; +} +.ui-datepicker .ui-datepicker-prev span, +.ui-datepicker .ui-datepicker-next span { + display: block; + position: absolute; + left: 50%; + margin-left: -8px; + top: 50%; + margin-top: -8px; +} +.ui-datepicker .ui-datepicker-title { + margin: 0 10px; + padding: 4px 0; + text-align: center; +} +.ui-datepicker .ui-datepicker-title select { + font-size: 1em; + margin:-2px 2px; + padding:0; + outline:0; +} +.ui-datepicker table { + width: 100%; + border-collapse: collapse; + margin: 0; + font-size: 1em; +} +.ui-datepicker th { + padding: 3px; + text-align: center; + font-weight: bold; + border: 0; +} +.ui-datepicker td { + border: 0; + padding: 1px; +} +.ui-datepicker td span, +.ui-datepicker td a { + display: block; + padding: 2px 3px; + text-align: right; + text-decoration: none; +} +.ui-datepicker .ui-datepicker-buttonpane { + background-image: none; + margin: 10px -11px -11px -11px; + padding: 10px; + border: 1px solid #184977; + background: #e4f5ff; + overflow: auto; +} +.ui-datepicker .ui-datepicker-buttonpane button { + float: right; + cursor: pointer; + width: auto; + overflow: visible; + margin: 0; + padding: 6px 10px; + font-weight: bold; + opacity: 1; + filter: alpha(opacity=100); +} +.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { + float: left; +} + +/* with multiple calendars */ +.ui-datepicker.ui-datepicker-multi { + width: auto; + padding:10px; +} +.ui-datepicker-multi .ui-datepicker-group { + float: left; +} +.ui-datepicker-multi .ui-datepicker-group .ui-datepicker-header { + margin:0; +} +.ui-datepicker-multi .ui-datepicker-group.ui-datepicker-group-last { + margin-right:0; +} + +.ui-datepicker-multi .ui-datepicker-group table { + width: 95%; + margin: 0 auto .4em; +} +.ui-datepicker-multi-2 .ui-datepicker-group { + width: 50%; +} +.ui-datepicker-multi-3 .ui-datepicker-group { + width: 33.3%; +} +.ui-datepicker-multi-4 .ui-datepicker-group { + width: 25%; +} + +.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header, +.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { + border-left-width: 0; +} +.ui-datepicker-multi .ui-datepicker-buttonpane { + clear: left; +} +.ui-datepicker-row-break { + clear: both; + font-size: 0; + width: 100px; +} +th.ui-datepicker-week-col { + color: #215b82; +} +td.ui-datepicker-week-col { + text-align:right; + padding-right:7px; + color: #215b82; +} +td.ui-datepicker-other-month a.ui-state-default { + font-weight: bold; +} +th.ui-datepicker-week-end { + color: #f44; +} + +/* RTL support */ +.ui-datepicker-rtl { + direction: rtl; +} +.ui-datepicker-rtl .ui-datepicker-prev { + right: 2px; + left: auto; +} +.ui-datepicker-rtl .ui-datepicker-next { + left: 2px; + right: auto; +} +.ui-datepicker-rtl .ui-datepicker-prev:hover { + right: 1px; + left: auto; +} +.ui-datepicker-rtl .ui-datepicker-next:hover { + left: 1px; + right: auto; +} +.ui-datepicker-rtl .ui-datepicker-buttonpane { + clear: right; +} +.ui-datepicker-rtl .ui-datepicker-buttonpane button { + float: left; +} +.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current, +.ui-datepicker-rtl .ui-datepicker-group { + float: right; +} +.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header, +.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { + border-right-width: 0; + border-left-width: 1px; +} + + +/** Dialog */ + +.ui-dialog { + position: absolute; + top: 0; + left: 0; + padding: 4px; + outline: 0; + box-shadow: 0 0 10px #000; +} +.ui-dialog .ui-dialog-titlebar { + padding: 5px 10px; + position: relative; +} +.ui-dialog .ui-dialog-title { + float: left; + margin: 0; + padding: 1px 0; + white-space: nowrap; + width: 90%; + overflow: hidden; + text-overflow: ellipsis; +} +.ui-dialog .ui-dialog-titlebar-close { + position: absolute; + right: .3em; + top: 50%; + width: 21px; + margin: -10px 0 0 0; + padding: 1px; + height: 20px; +} +.ui-dialog .ui-dialog-content { + position: relative; + border: 0; + padding: 1em; + margin: 0 -4px; + background: none; + overflow: auto; +} +.ui-dialog .ui-dialog-buttonpane { + text-align: left; + border-width: 1px 0 0 0; + background-image: none; + padding: 10px; +} +.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { + float: right; +} +.ui-dialog .ui-dialog-buttonpane button { + margin: 0 0 0 5px; + cursor: pointer; +} +.ui-dialog .ui-resizable-se { + width: 12px; + height: 12px; + right: -5px; + bottom: -5px; + background-position: 16px 16px; +} +.ui-draggable .ui-dialog-titlebar { + cursor: move; +} + + +/** Menu */ + +.ui-menu { + list-style: none; + padding: 0; + margin: 0; + display: block; + outline: 0; +} +.ui-menu .ui-menu { + margin-top: -3px; + position: absolute; +} +.ui-menu .ui-menu-item { + margin: 0; + padding: 0; + width: 100%; + /* support: IE10, see #8844 */ + list-style-image: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7); +} +.ui-menu .ui-menu-divider { + margin: 1px 10px 1px 10px; + height: 0; + font-size: 0; + line-height: 0; + border-width: 1px 0 0 0; + border-color: #777; +} +.ui-menu .ui-menu-item a { + text-decoration: none; + display: block; + padding: 5px 10px; + line-height: 1.5; + min-height: 0; /* support: IE7 */ + font-weight: normal; + border-radius:0; +} +.ui-menu .ui-menu-item a.ui-state-focus, +.ui-menu .ui-menu-item a.ui-state-active { + font-weight: normal; + margin: -1px; + transition: none; +} +.ui-menu .ui-state-disabled { + font-weight: normal; + line-height: 1.5; +} +.ui-menu .ui-state-disabled a { + cursor: default; +} +.ui-menu.ui-corner-all.sh-menu { + border-radius: 4px; +} +.ui-menu.ui-corner-all, .ui-menu.sh-menu.ui-autocomplete.ui-corner-all { + border-radius: 0; +} + +/* icon support */ +.ui-menu-icons { + position: relative; +} +.ui-menu-icons .ui-menu-item a { + position: relative; + padding-left: 2em; +} + +/* left-aligned */ +.ui-menu .ui-icon { + position: absolute; + top: .2em; + left: .2em; +} + +/* right-aligned */ +.ui-menu .ui-menu-icon { + position: static; + float: right; +} + + +/** Progress bar */ + +.ui-progressbar { + height: 2.1em; + text-align: left; + overflow: hidden; +} +.ui-progressbar .ui-progressbar-value { + margin: -1px; + height: 100%; +} +.ui-progressbar .ui-progressbar-overlay { + height: 100%; + filter: alpha(opacity=25); + opacity: 0.25; +} +.ui-progressbar-indeterminate .ui-progressbar-value { + background-image: none; +} + + +/** Slider */ + +.ui-slider { + position: relative; + text-align: left; + margin: 0 13px; + border-radius:15px; +} +.ui-slider .ui-slider-handle { + position: absolute; + z-index: 2; + width: 18px; + height: 18px; + border-radius: 9px; + cursor: default; + box-shadow: 0 0 3px #aaa, inset 0 0 7px #fff, inset 0 0 3px #fff; +} +.ui-slider .ui-slider-handle.ui-state-active { + box-shadow: 0 0 3px #4685b3, inset 0 0 7px #fff, inset 0 0 3px #fff; +} +.ui-slider .ui-slider-range { + position: absolute; + z-index: 1; + display: block; + border: 0; + background-position: 0 0; +} + +/* For IE8 - See #6727 */ +.ui-slider.ui-state-disabled .ui-slider-handle, +.ui-slider.ui-state-disabled .ui-slider-range { + filter: inherit; +} + +.ui-slider-horizontal { + height: 10px; +} +.ui-slider-horizontal .ui-slider-handle { + top: -5px; + margin-left: -9px; +} +.ui-slider-horizontal .ui-slider-range { + top: 0; + height: 100%; +} +.ui-slider-horizontal .ui-slider-range-min { + left: 0; +} +.ui-slider-horizontal .ui-slider-range-max { + right: 0; +} + +.ui-slider-vertical { + width: 10px; + height: 150px; +} +.ui-slider-vertical .ui-slider-handle { + left: -5px; + margin-left: 0; + margin-bottom: -9px; +} +.ui-slider-vertical .ui-slider-range { + left: -1px; + width: 100%; +} +.ui-slider-vertical .ui-slider-range-min { + bottom: 0; +} +.ui-slider-vertical .ui-slider-range-max { + top: 0; +} + + +/** Spinner */ + +.ui-spinner.ui-widget { + position: relative; + display: inline-block; + overflow: hidden; + padding: 0; + vertical-align: middle; + background: #fff; + background: -webkit-linear-gradient(top, #f0f0f0, #fff); + background: -moz-linear-gradient(top, #f0f0f0, #fff); + background: -ms-linear-gradient(top, #f0f0f0, #fff); + background: -o-linear-gradient(top, #f0f0f0, #fff); + background: linear-gradient(to bottom, #f0f0f0, #fff); +} +.ui-spinner-input { + border: none; + color: inherit; + padding: 0; + margin: 6px 24px 6px 10px; + vertical-align: middle; + outline: 0; + background: transparent; +} +.ui-spinner-input { + color: #aaa} +.ui-spinner-input:focus { + color: #000; +} +.ui-spinner-button { + width: 16px; + height: 50%; + font-size: .5em; + padding: 0; + margin: 0; + text-align: center; + position: absolute; + cursor: default; + display: block; + overflow: hidden; + right: 0; +} +/* more specificity required here to overide default borders */ +.ui-spinner a.ui-spinner-button { + border-top: none; + border-bottom: none; + border-right: none; +} +/* vertical centre icon */ +.ui-spinner .ui-icon { + position: absolute; + margin-top: -8px; + top: 50%; + left: 0; +} +.ui-spinner-up { + top: 0; +} +.ui-spinner-down { + bottom: 0; +} + +/* TR overrides */ +.ui-spinner .ui-icon-triangle-1-s { + /* need to fix icons sprite */ + background-position: -65px -16px; +} + + +/** Tabs */ + +.ui-tabs { + position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ +} +.ui-tabs .ui-tabs-nav { + margin: 0; + padding: 3px 3px 0 3px; +} +.ui-tabs .ui-tabs-nav li { + list-style: none; + float: left; + position: relative; + top: 0; + margin: 1px 3px 0 0; + border-bottom-width: 0; + padding: 0; + white-space: nowrap; +} +.ui-tabs .ui-tabs-nav li a { + float: left; + padding: 6px 10px; + text-decoration: none; +} +.ui-tabs .ui-tabs-nav li.ui-tabs-active { + margin-bottom: -1px; + padding-bottom: 1px; +} +.ui-tabs .ui-tabs-nav li.ui-tabs-active a, +.ui-tabs .ui-tabs-nav li.ui-state-disabled a, +.ui-tabs .ui-tabs-nav li.ui-tabs-loading a { + cursor: text; +} +.ui-tabs .ui-tabs-nav li a, /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */ +.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a { + cursor: pointer; +} +.ui-tabs .ui-tabs-panel { + display: block; + border-width: 0; + padding: 1em; + background: none; +} + +/** Tooltip */ + +body .ui-tooltip { + padding: 6px 10px; + position: absolute; + z-index: 9999; + max-width: 300px; + color: #808080; + border-color: #a5a5a5; + box-shadow: inset 0 0 4px #a5a5a5, 0 0 4px #a5a5a5; + background: -webkit-linear-gradient(top, #ddd, #fff); + background: -moz-linear-gradient(top, #ddd, #fff); + background: -ms-linear-gradient(top, #ddd, #fff); + background: -o-linear-gradient(top, #ddd, #fff); + background: linear-gradient(to bottom, #ddd, #fff); +} + +/** Icons */ + +/* states and images */ +.ui-icon { + display: block; + text-indent: -99999px; + overflow: hidden; + background-repeat: no-repeat; + width: 16px; + height: 16px; +} + +.ui-icon, +.ui-button.ui-state-active .ui-icon, +.ui-dialog .ui-dialog-titlebar-close .ui-icon { + background-image: url(img/ui-icons_white.png); +} + +.ui-button .ui-icon { + background-image: url(img/ui-icons_grey.png); +} + +/* positioning */ +.ui-icon-blank { background-position: 16px 16px; } +.ui-icon-carat-1-n { background-position: 0 0; } +.ui-icon-carat-1-ne { background-position: -16px 0; } +.ui-icon-carat-1-e { background-position: -32px 0; } +.ui-icon-carat-1-se { background-position: -48px 0; } +.ui-icon-carat-1-s { background-position: -64px 0; } +.ui-icon-carat-1-sw { background-position: -80px 0; } +.ui-icon-carat-1-w { background-position: -96px 0; } +.ui-icon-carat-1-nw { background-position: -112px 0; } +.ui-icon-carat-2-n-s { background-position: -128px 0; } +.ui-icon-carat-2-e-w { background-position: -144px 0; } +.ui-icon-triangle-1-n { background-position: 0 -16px; } +.ui-icon-triangle-1-ne { background-position: -16px -16px; } +.ui-icon-triangle-1-e { background-position: -32px -16px; } +.ui-icon-triangle-1-se { background-position: -48px -16px; } +.ui-icon-triangle-1-s { background-position: -64px -16px; } +.ui-icon-triangle-1-sw { background-position: -80px -16px; } +.ui-icon-triangle-1-w { background-position: -96px -16px; } +.ui-icon-triangle-1-nw { background-position: -112px -16px; } +.ui-icon-triangle-2-n-s { background-position: -128px -16px; } +.ui-icon-triangle-2-e-w { background-position: -144px -16px; } +.ui-icon-arrow-1-n { background-position: 0 -32px; } +.ui-icon-arrow-1-ne { background-position: -16px -32px; } +.ui-icon-arrow-1-e { background-position: -32px -32px; } +.ui-icon-arrow-1-se { background-position: -48px -32px; } +.ui-icon-arrow-1-s { background-position: -64px -32px; } +.ui-icon-arrow-1-sw { background-position: -80px -32px; } +.ui-icon-arrow-1-w { background-position: -96px -32px; } +.ui-icon-arrow-1-nw { background-position: -112px -32px; } +.ui-icon-arrow-2-n-s { background-position: -128px -32px; } +.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } +.ui-icon-arrow-2-e-w { background-position: -160px -32px; } +.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } +.ui-icon-arrowstop-1-n { background-position: -192px -32px; } +.ui-icon-arrowstop-1-e { background-position: -208px -32px; } +.ui-icon-arrowstop-1-s { background-position: -224px -32px; } +.ui-icon-arrowstop-1-w { background-position: -240px -32px; } +.ui-icon-arrowthick-1-n { background-position: 0 -48px; } +.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } +.ui-icon-arrowthick-1-e { background-position: -32px -48px; } +.ui-icon-arrowthick-1-se { background-position: -48px -48px; } +.ui-icon-arrowthick-1-s { background-position: -64px -48px; } +.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } +.ui-icon-arrowthick-1-w { background-position: -96px -48px; } +.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } +.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } +.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } +.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } +.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } +.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } +.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } +.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } +.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } +.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } +.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } +.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } +.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } +.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } +.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } +.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } +.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } +.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } +.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } +.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } +.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } +.ui-icon-arrow-4 { background-position: 0 -80px; } +.ui-icon-arrow-4-diag { background-position: -16px -80px; } +.ui-icon-extlink { background-position: -32px -80px; } +.ui-icon-newwin { background-position: -48px -80px; } +.ui-icon-refresh { background-position: -64px -80px; } +.ui-icon-shuffle { background-position: -80px -80px; } +.ui-icon-transfer-e-w { background-position: -96px -80px; } +.ui-icon-transferthick-e-w { background-position: -112px -80px; } +.ui-icon-folder-collapsed { background-position: 0 -96px; } +.ui-icon-folder-open { background-position: -16px -96px; } +.ui-icon-document { background-position: -32px -96px; } +.ui-icon-document-b { background-position: -48px -96px; } +.ui-icon-note { background-position: -64px -96px; } +.ui-icon-mail-closed { background-position: -80px -96px; } +.ui-icon-mail-open { background-position: -96px -96px; } +.ui-icon-suitcase { background-position: -112px -96px; } +.ui-icon-comment { background-position: -128px -96px; } +.ui-icon-person { background-position: -144px -96px; } +.ui-icon-print { background-position: -160px -96px; } +.ui-icon-trash { background-position: -176px -96px; } +.ui-icon-locked { background-position: -192px -96px; } +.ui-icon-unlocked { background-position: -208px -96px; } +.ui-icon-bookmark { background-position: -224px -96px; } +.ui-icon-tag { background-position: -240px -96px; } +.ui-icon-home { background-position: 0 -112px; } +.ui-icon-flag { background-position: -16px -112px; } +.ui-icon-calendar { background-position: -32px -112px; } +.ui-icon-cart { background-position: -48px -112px; } +.ui-icon-pencil { background-position: -64px -112px; } +.ui-icon-clock { background-position: -80px -112px; } +.ui-icon-disk { background-position: -96px -112px; } +.ui-icon-calculator { background-position: -112px -112px; } +.ui-icon-zoomin { background-position: -128px -112px; } +.ui-icon-zoomout { background-position: -144px -112px; } +.ui-icon-search { background-position: -160px -112px; } +.ui-icon-wrench { background-position: -176px -112px; } +.ui-icon-gear { background-position: -192px -112px; } +.ui-icon-heart { background-position: -208px -112px; } +.ui-icon-star { background-position: -224px -112px; } +.ui-icon-link { background-position: -240px -112px; } +.ui-icon-cancel { background-position: 0 -128px; } +.ui-icon-plus { background-position: -16px -128px; } +.ui-icon-plusthick { background-position: -32px -128px; } +.ui-icon-minus { background-position: -48px -128px; } +.ui-icon-minusthick { background-position: -64px -128px; } +.ui-icon-close { background-position: -80px -128px; } +.ui-icon-closethick { background-position: -96px -128px; } +.ui-icon-key { background-position: -112px -128px; } +.ui-icon-lightbulb { background-position: -128px -128px; } +.ui-icon-scissors { background-position: -144px -128px; } +.ui-icon-clipboard { background-position: -160px -128px; } +.ui-icon-copy { background-position: -176px -128px; } +.ui-icon-contact { background-position: -192px -128px; } +.ui-icon-image { background-position: -208px -128px; } +.ui-icon-video { background-position: -224px -128px; } +.ui-icon-script { background-position: -240px -128px; } +.ui-icon-alert { background-position: 0 -144px; } +.ui-icon-info { background-position: -16px -144px; } +.ui-icon-notice { background-position: -32px -144px; } +.ui-icon-help { background-position: -48px -144px; } +.ui-icon-check { background-position: -64px -144px; } +.ui-icon-bullet { background-position: -80px -144px; } +.ui-icon-radio-on { background-position: -96px -144px; } +.ui-icon-radio-off { background-position: -112px -144px; } +.ui-icon-pin-w { background-position: -128px -144px; } +.ui-icon-pin-s { background-position: -144px -144px; } +.ui-icon-play { background-position: 0 -160px; } +.ui-icon-pause { background-position: -16px -160px; } +.ui-icon-seek-next { background-position: -32px -160px; } +.ui-icon-seek-prev { background-position: -48px -160px; } +.ui-icon-seek-end { background-position: -64px -160px; } +.ui-icon-seek-start { background-position: -80px -160px; } +/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ +.ui-icon-seek-first { background-position: -80px -160px; } +.ui-icon-stop { background-position: -96px -160px; } +.ui-icon-eject { background-position: -112px -160px; } +.ui-icon-volume-off { background-position: -128px -160px; } +.ui-icon-volume-on { background-position: -144px -160px; } +.ui-icon-power { background-position: 0 -176px; } +.ui-icon-signal-diag { background-position: -16px -176px; } +.ui-icon-signal { background-position: -32px -176px; } +.ui-icon-battery-0 { background-position: -48px -176px; } +.ui-icon-battery-1 { background-position: -64px -176px; } +.ui-icon-battery-2 { background-position: -80px -176px; } +.ui-icon-battery-3 { background-position: -96px -176px; } +.ui-icon-circle-plus { background-position: 0 -192px; } +.ui-icon-circle-minus { background-position: -16px -192px; } +.ui-icon-circle-close { background-position: -32px -192px; } +.ui-icon-circle-triangle-e { background-position: -48px -192px; } +.ui-icon-circle-triangle-s { background-position: -64px -192px; } +.ui-icon-circle-triangle-w { background-position: -80px -192px; } +.ui-icon-circle-triangle-n { background-position: -96px -192px; } +.ui-icon-circle-arrow-e { background-position: -112px -192px; } +.ui-icon-circle-arrow-s { background-position: -128px -192px; } +.ui-icon-circle-arrow-w { background-position: -144px -192px; } +.ui-icon-circle-arrow-n { background-position: -160px -192px; } +.ui-icon-circle-zoomin { background-position: -176px -192px; } +.ui-icon-circle-zoomout { background-position: -192px -192px; } +.ui-icon-circle-check { background-position: -208px -192px; } +.ui-icon-circlesmall-plus { background-position: 0 -208px; } +.ui-icon-circlesmall-minus { background-position: -16px -208px; } +.ui-icon-circlesmall-close { background-position: -32px -208px; } +.ui-icon-squaresmall-plus { background-position: -48px -208px; } +.ui-icon-squaresmall-minus { background-position: -64px -208px; } +.ui-icon-squaresmall-close { background-position: -80px -208px; } +.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } +.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } +.ui-icon-grip-solid-vertical { background-position: -32px -224px; } +.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } +.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } +.ui-icon-grip-diagonal-se { background-position: -80px -224px; } + + +/** Misc */ + +/* Corner radius */ +.ui-corner-all, +.ui-corner-top, +.ui-corner-left, +.ui-corner-tl, +.ui-menu .ui-menu-item.ui-menu-item-first a { + border-top-left-radius: 4px; +} +.ui-corner-all, +.ui-corner-top, +.ui-corner-right, +.ui-corner-tr, +.ui-menu .ui-menu-item.ui-menu-item-first a { + border-top-right-radius:4px; +} +.ui-corner-all, +.ui-corner-bottom, +.ui-corner-left, +.ui-corner-bl, +.ui-menu .ui-menu-item.ui-menu-item-last a, +.ui-dialog-buttonpane, +.ui-datepicker-multi .ui-datepicker-group-first .ui-datepicker-header, +.ui-datepicker .ui-datepicker-buttonpane { + border-bottom-left-radius: 4px; +} +.ui-corner-all, +.ui-corner-bottom, +.ui-corner-right, +.ui-corner-br, +.ui-menu .ui-menu-item.ui-menu-item-last a, +.ui-dialog-buttonpane, +.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header, +.ui-datepicker .ui-datepicker-buttonpane { + border-bottom-right-radius: 4px; +} + +/* Overlays */ +.ui-widget-overlay { + background: rgba(255,255,255,.5); +} +.ui-widget-shadow { + margin: -7px 0 0 -7px; + padding: 7px; + background: rgba(0,0,0,.3); + border-radius: 8px; +} + +/* SunHater Fixes */ + +.ui-accordion-content-active, .ui-tabs, .ui-slider-range, .ui-datepicker, .ui-dialog { + border-color: #4d637c; +} + +.ui-slider .ui-slider-range { + border: 1px solid #4685b3; + top: -1px +} + +.ui-progressbar { + overflow:visible; +} +.ui-progressbar-value { + border: 1px solid #4685b3; + margin-top: -1px +} + +.ui-button { + box-shadow: inset 0 0 3px #555, inset 0 0 6px #555, 0 0 3px #000, 0 0 2px #000; +} +.ui-button.ui-state-active { + box-shadow: inset 0 0 3px #88b9da, 0 0 3px #000, 0 0 2px #000; +} +.ui-widget-header, +.ui-menu-item .ui-state-focus { + box-shadow: inset 0 0 3px #88b9da; +} + +.ui-state-default, +.ui-state-focus, +.ui-state-active, +.ui-widget-header, +fieldset.sh-uniform label, +fieldset.sh-uniform legend { + text-shadow: + 1px 0 rgba(0,0,0,.2), + -1px 0 rgba(0,0,0,.2), + 0 -1px rgba(0,0,0,.2), + 0 1px rgba(0,0,0,.2), + 1px 1px rgba(0,0,0,.2), + -1px -1px rgba(0,0,0,.2), + 1px -1px rgba(0,0,0,.2), + -1px 1px rgba(0,0,0,.2); +} + +.ui-tabs .ui-state-active, +.ui-datepicker .ui-state-highlight { + text-shadow: none; +} +.ui-datepicker .ui-state-highlight { + color: #215b82; + border-color: #4685b3; + box-shadow: inset 0 0 4px #4685b3; + background: #fff; + background: -webkit-linear-gradient(top, #dfeef8, #fff); + background: -moz-linear-gradient(top, #dfeef8, #fff); + background: -ms-linear-gradient(top, #dfeef8, #fff); + background: -o-linear-gradient(top, #dfeef8, #fff); + background: linear-gradient(to bottom, #dfeef8, #fff); +} + +.ui-progressbar, .ui-slider, .ui-menu { + box-shadow: inset 0 0 4px #666, 0 0 3px #000, 0 0 6px #000; + background: #000; + background: -webkit-linear-gradient(top, #111, #444); + background: -moz-linear-gradient(top, #111, #444); + background: -ms-linear-gradient(top, #111, #444); + background: -o-linear-gradient(top, #111, #444); + background: linear-gradient(to bottom, #111, #444); +} + +.ui-slider, .ui-spinner, .ui-progressbar, .ui-menu { + border-color: #555; +} + +.ui-datepicker-calendar .ui-state-default { + border-radius: 3px; +} + +.ui-tabs .ui-tabs-nav { + margin: -1px; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; + padding-left:3px; +} + +.ui-tabs-active.ui-state-active { + background: #fff; + background: -webkit-linear-gradient(top, #ccc, #ddd, #eee, #fff, #fff, #fff); + background: -moz-linear-gradient(top, #ccc, #ddd, #eee, #fff, #fff, #fff); + background: -ms-linear-gradient(top, #ccc, #ddd, #eee, #fff, #fff, #fff); + background: -o-linear-gradient(top, #ccc, #ddd, #eee, #fff, #fff, #fff); + background: linear-gradient(to bottom, #ccc, #ddd, #eee, #fff, #fff, #fff); + box-shadow: inset 0 0 5px #fff, inset 0 0 5px #fff, inset 0 0 5px #fff; +} +.ui-tabs-active.ui-state-active a { + color: #215b82; +} +.ui-state-default, .ui-state-default a { + outline: 0; +} +.ui-datepicker-header, +.ui-dialog-titlebar { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; + margin: -5px -5px 0 -5px; +} +.ui-datepicker-header { + margin: -11px -11px 5px -11px; +} + +.ui-datepicker-header a:hover { + cursor: pointer; +} + +.ui-dialog-titlebar-close.ui-state-default { + border-color: transparent; + background: none; + box-shadow: none; +} + +.ui-dialog-titlebar-close.ui-state-default.ui-state-hover { + transition: .2s; + border: 1px solid #555; + background: #333; + background: -webkit-linear-gradient(top, #555, #111); + background: -moz-linear-gradient(top, #555, #111); + background: -ms-linear-gradient(top, #555, #111); + background: -o-linear-gradient(top, #555, #111); + background: linear-gradient(to bottom, #555, #111); + box-shadow: inset 0 0 3px #555, inset 0 0 6px #555, 0 0 3px #000, 0 0 2px #000; +} + +.ui-dialog-buttonpane { + background: #202D3E; + box-shadow: inset 0 0 3px #000, inset 0 0 2px #000; + border-top-color: #4d637c; + margin: 0 -4px -4px -4px; + padding: 0; +} + +/*** shCheckset */ +/* +.shcs { + margin: 0; +} +.shcs > div { + border: 1px solid; + border-top: 0; + padding: 5px; + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; +} +.shcs > input, .shcs > input:focus, .shcs > input:hover { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + margin:0; +} +.shcs label { + padding: 2px 5px 2px 2px; + border: 1px solid transparent; + border-radius: 4px; + color: #aaa; +} +.shcs > div, .shcs label:hover { + border-color: #aaa; + box-shadow: inset 0 0 4px #aaa; + background: #fff; + background: -webkit-linear-gradient(top, #f0f0f0, #fff); + background: -moz-linear-gradient(top, #f0f0f0, #fff); + background: -ms-linear-gradient(top, #f0f0f0, #fff); + background: -o-linear-gradient(top, #f0f0f0, #fff); + background: linear-gradient(to bottom, #f0f0f0, #fff); +} +.shcs label:hover { + color: #aaa; + cursor: pointer; +} +.shcs > div.focus, .shcs label.checked { + border-color: #184977; + box-shadow: inset 0 0 4px #4685b3; + color: #000; + background: #fff; + background: -webkit-linear-gradient(top, #dfeef8, #fff); + background: -moz-linear-gradient(top, #dfeef8, #fff); + background: -ms-linear-gradient(top, #dfeef8, #fff); + background: -o-linear-gradient(top, #dfeef8, #fff); + background: linear-gradient(to bottom, #dfeef8, #fff); +} +.shcs label.checked div.checker { + border-color: #4685b3; + background: #4685b3; + background: -webkit-linear-gradient(top, #4685b3, #184977); + background: -moz-linear-gradient(top, #4685b3, #184977); + background: -ms-linear-gradient(top, #4685b3, #184977); + background: -o-linear-gradient(top, #4685b3, #184977); + background: linear-gradient(to bottom, #4685b3, #184977); +} +.shcs label.checked div.checker.hover { + border-color: #4685b3; + background: #184977; + background: -webkit-linear-gradient(top, #184977, #4685b3); + background: -moz-linear-gradient(top, #184977, #4685b3); + background: -ms-linear-gradient(top, #184977, #4685b3); + background: -o-linear-gradient(top, #184977, #4685b3); + background: linear-gradient(to bottom, #184977, #4685b3); +} + +.shcs div.checker.focus { + border-color: #aaa; + background: #aaa; + background: -webkit-linear-gradient(top, #ababab, #aaa); + background: -moz-linear-gradient(top, #ababab, #aaa); + background: -ms-linear-gradient(top, #ababab, #aaa); + background: -o-linear-gradient(top, #ababab, #aaa); + background: linear-gradient(to bottom, #ababab, #aaa); + box-shadow: inset 0 0 7px #fff, inset 0 0 3px #fff; +} + +.shcs div.checker.focus.hover { + border-color: #aaa; + background: #aaa; + background: -webkit-linear-gradient(top, #aaa, #ababab); + background: -moz-linear-gradient(top, #aaa, #ababab); + background: -ms-linear-gradient(top, #aaa, #ababab); + background: -o-linear-gradient(top, #aaa, #ababab); + background: linear-gradient(to bottom, #aaa, #ababab); +} + +.shcs label > span { + position:relative; + margin-left:5px; + top:1px; +} +*/ \ No newline at end of file diff --git a/lib/kcfinder/themes/dark/02.transForm.css b/lib/kcfinder/themes/dark/02.transForm.css new file mode 100644 index 0000000..e07f37e --- /dev/null +++ b/lib/kcfinder/themes/dark/02.transForm.css @@ -0,0 +1,539 @@ +/* COMMON - BEGIN */ + +/* FONT SETTINGS */ +.tf-select, +.tf-input, +.tf-textarea, +.tf-multiple, +.tf-label, +.tf-fieldset legend, +.tf-file, +.tf-file input, +.tf-radio, +.tf-checkbox, +.tf-button, +.tf-input.tf-color, +.tf-input.tf-range { + font-size: 13px; + cursor: pointer; +} + +/* FIELD - NORMAL */ +.tf-select .tf-selected, +.tf-input, +.tf-multiple, +.tf-textarea, +.tf-file .tf-info, +.tf-radio, +.tf-checkbox { + background: #000; + background: -webkit-linear-gradient(top, #111, #333); + background: -moz-linear-gradient(top, #111, #333); + background: -ms-linear-gradient(top, #111, #333); + background: -o-linear-gradient(top, #111, #333); + background: linear-gradient(to bottom, #111, #333); + box-shadow: inset 0 0 4px #555; + border: 1px solid #666; + color: #aaa; + border-radius: 4px; + color: #6b6b6b; + padding: 6px 10px; +} + +/* FIELD - FOCUSED */ +.tf-select.tf-focused .tf-selected, +.tf-select .tf-menu, +.tf-multiple.tf-focused, +.tf-input:focus, .tf-textarea:focus, +.tf-file.tf-focused .tf-info, +.tf-radio.tf-focused, +.tf-checkbox.tf-focused { + background: #202D3E; + background: -webkit-linear-gradient(top, #131427, #273446); + background: -moz-linear-gradient(top, #131427, #273446); + background: -ms-linear-gradient(top, #131427, #273446); + background: -o-linear-gradient(top, #131427, #273446); + background: linear-gradient(to bottom, #131427, #273446); + box-shadow: inset 0 0 4px #4d637c; + border: 1px solid #4d637c; + color: #fff; +} + +/* BUTTON - NORMAL */ +.tf-button, +.tf-file .tf-button { + background: #333; + background: -webkit-linear-gradient(top, #555, #111); + background: -moz-linear-gradient(top, #555, #111); + background: -ms-linear-gradient(top, #555, #111); + background: -o-linear-gradient(top, #555, #111); + background: linear-gradient(to bottom, #555, #111); + box-shadow: inset 0 0 7px #555, inset 0 0 3px #555, 0 0 3px #000, 0 0 6px #000; + border: 1px solid #555; + border-radius: 4px; + padding: 6px 10px; +} +.tf-file .tf-button, +.tf-select .tf-button { + box-shadow: inset 0 0 7px #555, inset 0 0 3px #555; +} + +/* BUTTON - FOCUSED */ +.tf-file.tf-focused .tf-button, +.tf-button.tf-focused, +.tf-select.tf-focused .tf-button { + background: #4685b3; + background: -webkit-linear-gradient(top, #4685b3, #184977); + background: -moz-linear-gradient(top, #4685b3, #184977); + background: -ms-linear-gradient(top, #4685b3, #184977); + background: -o-linear-gradient(top, #4685b3, #184977); + background: linear-gradient(to bottom, #4685b3, #184977); + box-shadow: inset 0 0 7px #4e9ed4, inset 0 0 3px #4e9ed4, 0 0 3px #000, 0 0 6px #000; + border-color: #4685b3; + color: #fff; +} +.tf-file.tf-focused .tf-button, +.tf-select.tf-focused .tf-button { + box-shadow: inset 0 0 7px #4e9ed4, inset 0 0 3px #4e9ed4; +} + +/* BLACK OUTLINE, WHITE TEXT */ +.tf-select .tf-menu .tf-hover, +.tf-multiple .tf-hover, +.tf-multiple .tf-selected, +.tf-button { + color: #fff; + text-shadow: + 1px 0 rgba(0,0,0,.2), + -1px 0 rgba(0,0,0,.2), + 0 -1px rgba(0,0,0,.2), + 0 1px rgba(0,0,0,.2), + 1px 1px rgba(0,0,0,.2), + -1px -1px rgba(0,0,0,.2), + 1px -1px rgba(0,0,0,.2), + -1px 1px rgba(0,0,0,.2); +} + +/* COMMON - END */ + +/* SELECT BOX - BEGIN */ + +.tf-select .tf-selected { + border-radius: 4px 0 0 4px; +} +.tf-select .tf-button { + border-left: none; + border-radius: 0 4px 4px 0; +} + +.tf-select .tf-button span { + display: block; + background: url('img/ui-icons_grey.png') -64px -15px; + width: 16px; + margin-left: 4px; + margin-right: 5px; +} +.tf-select.tf-focused .tf-button span { + background-image: url('img/ui-icons_white.png'); +} +.tf-select .tf-menu { + border-radius: 0 0 4px 4px; +} +.tf-select .tf-menu div, +.tf-multiple div { + border: 1px solid transparent; + border-left-width: 0; + border-right-width: 0; + padding: 6px 10px; + margin-top: -1px; +} +.tf-select .tf-menu .tf-hover, +.tf-multiple.tf-focused .tf-hover, +.tf-multiple.tf-focused .tf-selected, +.tf-select.tf-opened.tf-focused .tf-button { + border-color: #4685b3; + background: #4685b3; + background: -webkit-linear-gradient(top, #184977, #4685b3); + background: -moz-linear-gradient(top, #184977, #4685b3); + background: -ms-linear-gradient(top, #184977, #4685b3); + background: -o-linear-gradient(top, #184977, #4685b3); + background: linear-gradient(to bottom, #184977, #4685b3); + box-shadow: inset 0 0 7px #4e9ed4, inset 0 0 3px #4e9ed4; +} +.tf-select.tf-opened .tf-button { + background: #111; + background: -webkit-linear-gradient(top, #555, #111); + background: -moz-linear-gradient(top, #555, #111); + background: -ms-linear-gradient(top, #555, #111); + background: -o-linear-gradient(top, #555, #111); + background: linear-gradient(to bottom, #555, #111); + box-shadow: inset 0 0 7px #555, inset 0 0 3px #555; +} +.tf-select .tf-menu .tf-group-last, +.tf-select .tf-menu div.tf-last { + border-bottom-width: 0; +} +.tf-select .tf-menu ul { + overflow: hidden; +} +.tf-select .tf-menu li.tf-last { + margin-bottom: -1px; +} +.tf-select .tf-menu .tf-last { + border-radius: 0 0 4px 4px; +} +.tf-select.tf-opened .tf-selected { + border-radius: 4px 0 0 0; +} +.tf-select.tf-opened .tf-button { + border-radius: 0 4px 0 0; +} +.tf-select .tf-menu li, +.tf-multiple.tf-focused li { + border-bottom: 1px solid #54b0e0; + border-top: 1px solid #54b0e0; + margin: -1px 0; +} +.tf-select .tf-menu li > span, +.tf-multiple li > span, +.tf-multiple.tf-focused li > span { + display: block; + padding: 6px 10px; + text-align: center; + font-weight: bold; + color: #6b6b6b; + background: #a7deff; + border-bottom: 1px solid #54b0e0; + cursor: default; + white-space: nowrap; +} + +/* SELECT BOX - END */ + +/* MULTIPLE SELECT BOX - BEGIN */ + +.tf-multiple { + padding: 0; +} +.tf-multiple li { + border: 1px solid #54b0e0; + border-right: none; + border-left: none; + margin: -1px 0; +} +.tf-multiple li > span { + color: #70a5d1; + border-color: #54b0e0; + background: #c1ddf5; +} +.tf-multiple .tf-hover, +.tf-multiple .tf-selected, +.tf-multiple.tf-focused .tf-hover { + background: #4685b3; + background: -webkit-linear-gradient(top, #184977, #4685b3); + background: -moz-linear-gradient(top, #184977, #4685b3); + background: -ms-linear-gradient(top, #184977, #4685b3); + background: -o-linear-gradient(top, #184977, #4685b3); + background: linear-gradient(to bottom, #184977, #4685b3); + box-shadow: inset 0 0 7px #4e9ed4, inset 0 0 3px #4e9ed4; + border-color: #4685b3; +} +.tf-multiple .tf-hover, +.tf-multiple .tf-selected { + border: 1px solid #54b0e0; + border-left: none; + border-right: none; +} +.tf-multiple div.tf-first { + border-top: none; + border-radius: 4px 4px 0 0; + margin-top: 0; +} +.tf-multiple div.tf-last { + border-bottom: none; + border-radius: 0 0 4px 4px; +} +.tf-multiple .tf-group-first { + border-top: none; + margin-top: 0; +} +.tf-multiple li.tf-last, +.tf-multiple .tf-group-last { + border-bottom: none; +} + +/* MULTIPLE SELECT BOX - END */ + +/* FILE UPLOAD BOX - BEGIN */ + +.tf-file { + width: 200px; + padding: 0; + overflow: auto; +} +.tf-file .tf-info, .tf-file.tf-focused .tf-info { + padding: 6px 10px; + border-radius: 4px 0 0 4px; + border-right: none; +} +.tf-file .tf-button { + border-radius: 0 4px 4px 0; + color: transparent; + text-shadow: none; + padding: 6px 8px; +} +.tf-file .tf-button span { + margin: 0 0 0 -4px; + width: 16px; + height: 16px; + display: block; + overflow: hidden; + background: url('img/ui-icons_grey.png') -16px -96px; +} +.tf-file .tf-button:after { + content: "\00a0"; +} +.tf-file input::-webkit-file-upload-button { + cursor: pointer; +} + +/* FILE UPLOAD BOX - END */ + +/* RADIO BUTTON - BEGIN */ + +.tf-radio { + width: 15px; + height: 15px; + padding: 0; + border-radius: 8px; +} +.tf-radio input { + width: 17px; + height: 17px; + margin: -1px 0 0 -1px; + cursor: pointer; +} +.tf-radio span { + width: 15px; + height: 15px; + display: block; + float: right; +} +.tf-radio.tf-checked span { + background: url('img/ui-icons_grey.png') -80px -145px; +} +.tf-radio.tf-checked.tf-focused span { + background-image: url('img/ui-icons_white.png'); +} + +/* RADIO BUTTON - END */ + +/* CHECK BOX - BEGIN */ + +.tf-checkbox { + padding: 0; + width: 15px; + height: 15px; + border-radius: 3px; +} +.tf-checkbox input { + width: 17px; + height: 17px; + margin: -1px 0 0 -1px; + cursor: pointer; +} +.tf-checkbox.tf-checked span { + width: 15px; + height: 15px; + display: block; + background: url('img/ui-icons_grey.png') -64px -145px; + float: right; +} +.tf-checkbox.tf-focused.tf-checked span { + background-image: url('img/ui-icons_white.png'); +} + + +/* CHECK BX - END */ + +/* BUTTON */ +.tf-button { + overflow: hidden; + padding: 0; +} +.tf-button span { + margin: 3px 7px; + float: right; +} +.tf-button input, +.tf-button button { + cursor: pointer; +} + +/* TEXT & TEXTAREA - BEGIN */ + +.tf-input, .tf-textarea { + outline: none; + cursor: text; + margin: 0; +} +/*.tf-input.tf-readOnly, +.tf-textarea.tf-readOnly, +.tf-input.tf-readOnly:focus, +.tf-textarea.tf-readOnly:focus { + background: #e4e4e4; + background: -webkit-linear-gradient(top, #e4e4e4, #fff); + background: -moz-linear-gradient(top, #e4e4e4, #fff); + background: -ms-linear-gradient(top, #e4e4e4, #fff); + background: -o-linear-gradient(top, #e4e4e4, #fff); + background: linear-gradient(to bottom, #e4e4e4, #fff); + box-shadow: inset 0 0 2px #a2a2a2; + border: 1px solid #a2a2a2; + border-radius: 4px; + color: #888; + padding: 6px 10px; +}*/ + +/* PLACEHOLDER COLORS */ + +.tf-input::-webkit-input-placeholder, +.tf-textarea::-webkit-input-placeholder { + color: #aaa; +} +.tf-input:-moz-placeholder, +.tf-textarea:-moz-placeholder { + color: #aaa; +} +.tf-input::-moz-placeholder, +.tf-textarea::-moz-placeholder { + color: #aaa; +} +.tf-input:-ms-input-placeholder, +.tf-textarea:-ms-input-placeholder { + color: #aaa; +} +.tf-input:focus::-webkit-input-placeholder, +.tf-textarea:focus::-webkit-input-placeholder { + color: #184977; +} +.tf-input:focus:-moz-placeholder, +.tf-textarea:focus:-moz-placeholder { + color: #184977; +} +.tf-input:focus::-moz-placeholder, +.tf-textarea:focus::-moz-placeholder { + color: #184977; +} +.tf-input:focus:-ms-input-placeholder, +.tf-textarea:focus:-ms-input-placeholder { + color: #184977; +} + +/* READ-ONLY PLACEHOLDERS */ +/* +.tf-input.tf-readOnly::-webkit-input-placeholder, +.tf-textarea.tf-readOnly::-webkit-input-placeholder { + color: #d4d4d4; +} +.tf-input.tf-readOnly:-moz-placeholder, +.tf-textarea.tf-readOnly:-moz-placeholder { + color: #dedede; +} +.tf-input.tf-readOnly::-moz-placeholder, +.tf-textarea.tf-readOnly::-moz-placeholder { + color: #dedede; +} +.tf-input.tf-readOnly:-ms-input-placeholder, +.tf-textarea.tf-readOnly:-ms-input-placeholder { + color: #d4d4d4; +} +.tf-input.tf-readOnly:focus::-webkit-input-placeholder, +.tf-textarea.tf-readOnly:focus::-webkit-input-placeholder { + color: #d4d4d4; +} +.tf-input.tf-readOnly:focus:-moz-placeholder, +.tf-textarea.tf-readOnly:focus:-moz-placeholder { + color: #dedede; +} +.tf-input.tf-readOnly:focus::-moz-placeholder, +.tf-textarea.tf-readOnly:focus::-moz-placeholder { + color: #dedede; +} +.tf-input.tf-readOnly:focus:-ms-input-placeholder, +.tf-textarea.tf-readOnly:focus:-ms-input-placeholder { + color: #d4d4d4; +} +*/ +/* TEXT & TEXTAREA - END */ + +/* FIELD SET */ +.tf-fieldset { + color: #aaa; + border: 1px solid #425064; + border-radius: 4px; + background: #202d3e; + box-shadow: inset 0 0 3px #000, inset 0 0 6px #000, 0 0 3px #425064, 0 0 2px #425064; + margin: 0 10px 10px 0; + padding: 10px; +} +.tf-fieldset legend { + font-weight: bold; + color: #aaa; +} +.tf-label { + color: #aaa; +} +.tf-label.tf-focused { + color: #fff; +} + +/* MISC */ + +.tf-disabled { + opacity: .5; + filter: alpha(opacity=50); +} +.tf-disabled, +.tf-disabled input, +.tf-disabled button, +.tf-disabled * +*.tf-disabled { + cursor: default; +} +.tf-file.tf-disabled input::-webkit-file-upload-button { + cursor: pointer; +} +.tf-fieldset.tf-disabled, +.tf-form.tf-disabled { + opacity: 1; + filter: alpha(opacity=100); +} + +.tf-input.tf-color { + width: 30px; + padding: 0; + height: 24px; +} +.tf-input.tf-number { + text-align: right; +} +.tf-input.tf-range { + height: 9px; + margin: 8px 0 7px 0; +} +.tf-input.tf-search, +.tf-input.tf-search.tf-readOnly{ + border-radius: 11px; +} +.tf-input.tf-datetime, +.tf-input.tf-datetime-local, +.tf-input.tf-month, +.tf-input.tf-time, +.tf-input.tf-week, +.tf-input.tf-datetime:focus, +.tf-input.tf-datetime-local:focus, +.tf-input.tf-month:focus, +.tf-input.tf-time:focus, +.tf-input.tf-week:focus { + padding: 1px 5px; +} \ No newline at end of file diff --git a/lib/kcfinder/themes/dark/03.misc.css b/lib/kcfinder/themes/dark/03.misc.css new file mode 100644 index 0000000..a2a77b3 --- /dev/null +++ b/lib/kcfinder/themes/dark/03.misc.css @@ -0,0 +1,446 @@ +* { + font-size: 13px; +} +body { + background: #000; + color: #aaa; +} +fieldset td { + white-space: nowrap; +} +#folders { + margin: 5px 5px 0 5px; +} +#files { + margin-right: 5px; +} + + +/* SHARED DECLARATIONS */ + +#toolbar a:hover, +#toolbar a.hover, +span.current, +span.regular:hover, +span.context, +a.drag > span.folder, +#clipboard div:hover, +div.file:hover, +#files div.selected, +#files div.selected:hover, +tr.selected > td, +tr.selected:hover > td, +#menu .list div a:hover, +#toolbar a.selected { + color: #fff; + text-shadow: + 1px 0 rgba(0,0,0,.2), + -1px 0 rgba(0,0,0,.2), + 0 -1px rgba(0,0,0,.2), + 0 1px rgba(0,0,0,.2), + 1px 1px rgba(0,0,0,.2), + -1px -1px rgba(0,0,0,.2), + 1px -1px rgba(0,0,0,.2), + -1px 1px rgba(0,0,0,.2); +} +#files div { + text-shadow: + 1px 0 rgba(0,0,0,.2), + -1px 0 rgba(0,0,0,.2), + 0 -1px rgba(0,0,0,.2), + 0 1px rgba(0,0,0,.2), + 1px 1px rgba(0,0,0,.2), + -1px -1px rgba(0,0,0,.2), + 1px -1px rgba(0,0,0,.2), + -1px 1px rgba(0,0,0,.2); +} + +#files, +#folders, +#toolbar a.selected { + color: #aaa; + border: 1px solid #425064; + border-radius: 4px; + background: #202d3e; + box-shadow: inset 0 0 3px #000, inset 0 0 6px #000, 0 0 3px #425064, 0 0 2px #425064; +} + +/* TOOLBAR */ +#toolbar { + padding: 5px 0; +} +#toolbar a { + color: #949494; + margin-right: 5px; + border: 1px solid transparent; + outline: none; + display: block; + float: left; + border-radius: 4px; + padding:0; +} +#toolbar a > span { + padding: 6px 10px 6px 26px; + diaplay: block; + float:left; + background: no-repeat 6px center; +} +#toolbar a:hover, +#toolbar a.hover { + color: #fff; + border-color: #184977; + background: #4685b3; + background: -webkit-linear-gradient(top, #4685b3, #184977); + background: -moz-linear-gradient(top, #4685b3, #184977); + background: -ms-linear-gradient(top, #4685b3, #184977); + background: -o-linear-gradient(top, #4685b3, #184977); + background: linear-gradient(to bottom, #4685b3, #184977); + box-shadow: inset 0 0 3px #88b9da; +} +#toolbar a[href="kcact:upload"] span { + background-image: url(img/icons/upload.png); +} +#toolbar a[href="kcact:refresh"] span { + background-image: url(img/icons/refresh.png); +} +#toolbar a[href="kcact:settings"] span { + background-image: url(img/icons/settings.png); +} +#toolbar a[href="kcact:about"] span { + background-image: url(img/icons/about.png); +} +#toolbar a[href="kcact:maximize"] span { + background-image: url(img/icons/maximize.png); +} + + +/* SETTINGS BAR */ + +#settings label { + cursor: pointer; +} +#settings fieldset { + margin-right:5px; + margin-bottom: 6px; + margin-top:-5px; + padding:6px; +} + + +/* FOLDERS */ + +div.folder { + padding-top: 2px; + margin-top: 5px; + white-space: nowrap; +} +div.folder a { + text-decoration: none; + cursor: default; + outline: none; + color: #aaa; +} +span.folder { + padding: 2px 3px 2px 23px; + outline: none; + background: no-repeat 3px center; + cursor: pointer; + border-radius: 3px; + border: 1px solid transparent; +} +span.brace { + width: 16px; + height: 16px; + outline: none; +} +span.current { + transition: .3s; + background-image: url(img/tree/folder.png); + background-color: #306999; + border-color: #306999; + box-shadow: inset 0 0 7px #8FD6EA, inset 0 0 3px #8FD6EA, 0 0 2px #000, 0 0 1px #000; +} +span.regular { + transition: .3s; + background-image: url(img/tree/folder.png); + background-color: transparent; +} +span.regular:hover, span.context, a.drag > span.folder, #clipboard div:hover { + transition: .3s; + background-color: #333; + border-color: #777; + box-shadow: inset 0 0 7px #777, inset 0 0 3px #777, 0 0 2px #000, 0 0 1px #000; +} +span.opened { + background-image: url(img/tree/minus.png); +} +span.closed { + background-image: url(img/tree/plus.png); +} +span.denied { + background-image: url(img/tree/denied.png); +} + + +/* FILES */ + +div.file { + padding: 4px; + margin: 3px; + border: 1px solid transparent; + border-radius: 4px; +} +div.file:hover { + box-shadow: inset 0 0 7px #555, inset 0 0 3px #555, 0 0 3px #000, 0 0 6px #000; + background: #000; + background: -webkit-linear-gradient(top, #111, #555); + background: -moz-linear-gradient(top, #111, #555); + background: -ms-linear-gradient(top, #111, #555); + background: -o-linear-gradient(top, #111, #555); + background: linear-gradient(to bottom, #111, #555); + border-color: #555; +} +div.file .name { + margin-top: 4px; + font-weight: bold; + height: 16px; + overflow: hidden; + padding-bottom:2px; +} +div.file .time { + font-size: 10px; +} +div.file .size { + font-size: 10px; +} +#files div.selected, +#files div.selected:hover { + border-color: #4685b3; + background: #4685b3; + background: -webkit-linear-gradient(top, #4685b3, #184977); + background: -moz-linear-gradient(top, #4685b3, #184977); + background: -ms-linear-gradient(top, #4685b3, #184977); + background: -o-linear-gradient(top, #4685b3, #184977); + background: linear-gradient(to bottom, #4685b3, #184977); + box-shadow: inset 0 0 7px #4e9ed4, inset 0 0 3px #4e9ed4, 0 0 3px #000, 0 0 6px #000; +} +tr.file > td { + padding: 3px 4px; +} +tr.file:hover > td { + background-color: #000; + transition: none; +} +tr.selected > td, +tr.selected:hover > td { + transition: .3s; + background-color: #2d5277; +} +tr.file td.name { + background-position: 2px center; + padding-left: 22px; +} +a.denied { + color: #666; + opacity: 0.5; + filter: alpha(opacity:50); + cursor: default; +} +a.denied:hover { + background-color: #e4e3e2; + border-color: transparent; + box-shadow: none; +} + +/* FILE MENU */ + +#menu .ui-menu a span { + background: left center no-repeat; + padding-left: 20px; + white-space: nowrap; +} +#menu a[href="kcact:refresh"] span { + background-image: url(img/icons/refresh.png); +} +#menu a[href="kcact:mkdir"] span { + background-image: url(img/icons/folder-new.png); +} +#menu a[href="kcact:mvdir"] span, #menu a[href="kcact:mv"] span { + background-image: url(img/icons/rename.png); +} +#menu a[href="kcact:rmdir"] span, #menu a[href="kcact:rm"] span, #menu a[href="kcact:rmcbd"] span { + background-image: url(img/icons/delete.png); +} +#menu a[href="kcact:clpbrdadd"] span { + background-image: url(img/icons/clipboard-add.png); +} +#menu a[href="kcact:pick"] span, #menu a[href="kcact:pick_thumb"] span { + background-image: url(img/icons/select.png); +} +#menu a[href="kcact:download"] span { + background-image: url(img/icons/download.png); +} +#menu a[href="kcact:view"] span { + background-image: url(img/icons/view.png); +} +#menu a[href="kcact:cpcbd"] span { + background-image: url(img/icons/copy.png); +} +#menu a[href="kcact:mvcbd"] span { + background-image: url(img/icons/move.png); +} +#menu a[href="kcact:clrcbd"] span { + background-image: url(img/icons/clipboard-clear.png); +} + +/* CLIPBOARD */ + +#clipboard { + margin-left:-3px; + padding: 2px; +} +#clipboard div { + background: url(img/icons/clipboard.png) no-repeat center center; + border: 1px solid transparent; + padding: 2px; + cursor: pointer; + border-radius: 4px; +} +#clipboard.selected div, #clipboard.selected div:hover { + background-color: #306999; + border-color: #306999; + box-shadow: inset 0 0 7px #8FD6EA, inset 0 0 3px #8FD6EA; +} +#menu .list a, #menu .list a.ui-state-focus { + margin: -1px 0 0 -1px; + padding: 6px 10px; + border: 1px solid transparent; + background: none; + border-radius: 0; + text-shadow: none; + box-shadow: none; +} +#menu .list a.first, #menu .list a.first.ui-state-focus { + border-radius: 4px 4px 0 0; +} +#menu .list a:hover { + border-color: #4685b3; + background: #4685b3; + background: -webkit-linear-gradient(top, #184977, #4685b3); + background: -moz-linear-gradient(top, #184977, #4685b3); + background: -ms-linear-gradient(top, #184977, #4685b3); + background: -o-linear-gradient(top, #184977, #4685b3); + background: linear-gradient(to bottom, #184977, #4685b3); + box-shadow: inset 0 0 7px #4e9ed4, inset 0 0 3px #4e9ed4; +} +#menu .list { + overflow:hidden; + max-height: 1px; + margin-bottom: -1px; + padding-bottom:1px; +} +#menu li.div-files { + margin: 0 0 1px 0; +} + +/* ABOUT DIALOG */ + +.about { + text-align: center; +} +.about div.head { + font-weight: bold; + font-size: 12px; + padding: 3px 0 8px 0; +} +.about div.head a { + background: url(img/kcf_logo.png) no-repeat left center; + padding: 0 0 0 27px; + font-size: 17px; + outline: none; +} + +.about a { + text-decoration: none; + color: #3665b4; +} + +.about a:hover { + text-decoration: underline; +} +#checkver { + margin: 5px 0 10px 0; +} +#loading, #checkver > span.loading { + background: url(img/loading.gif); + border: 1px solid #425064; + box-shadow: inset 0 0 3px #000, inset 0 0 6px #000, 0 0 3px #425064, 0 0 2px #425064; + padding: 6px 10px; + border-radius: 4px; + color: #aaa; +} +#checkver a { + font-weight: normal; + padding: 3px 3px 3px 20px; + background: url(img/icons/download.png) no-repeat left center; +} + +/* IMAGE VIEWER */ + +.kcfImageViewer .ui-dialog-content { + background: #000; + cursor: pointer; +} +.kcfImageViewer .img { + background: url(img/bg_transparent.png); +} +.ui-dialog-titlebar.loading { + background: url(img/loading.gif); + box-shadow: inset 0 0 3px #000, inset 0 0 6px #000; + border-color: #425064; +} + +.ui-dialog-titlebar.loading .ui-dialog-title { + color: #aaa; + font-weight: normal; +} + +.ui-dialog-titlebar.loading .ui-dialog-titlebar-close .ui-button-icon-primary.ui-icon.ui-icon-closethick { + background-image: url(img/ui-icons_grey.png); +} + +/* MISC */ +#settings .tf-select { + margin: 3px 5px 6px 0; +} +#settings .tf-selected { + padding-top: 10px; + padding-bottom: 11px; +} +#settings .tf-select .tf-button { + padding-top: 7px; + padding-bottom: 8px; +} + +#loading { + margin-right: 5px; +} +#loadingDirs { + padding: 5px 0 1px 24px; +} +#files.drag { + background: #ddebf8; +} +#resizer { + background: #fff; +} + +div.selector#uniform-lang { + margin: 8px 6px 6px 0; +} + +/* FIX FIELDSET BORDER RADIUS BUG ON IE */ +body.msie fieldset, +body.trident.rv fieldset { + border-radius: 0; +} \ No newline at end of file diff --git a/lib/kcfinder/themes/dark/README b/lib/kcfinder/themes/dark/README new file mode 100644 index 0000000..3d745ac --- /dev/null +++ b/lib/kcfinder/themes/dark/README @@ -0,0 +1,9 @@ +This folder contains files for designing default visual theme for KCFinder. +Some icons are taken from default KDE4 visual theme (http://www.kde.org) + +Theme Details: + +Version: 1.0 +Author: Pavel Tzonkov +Licenses: GPLv3 - http://opensource.org/licenses/GPL-3.0 + LGPLv3 - http://opensource.org/licenses/LGPL-3.0 diff --git a/lib/kcfinder/themes/dark/css.php b/lib/kcfinder/themes/dark/css.php new file mode 100644 index 0000000..247857b --- /dev/null +++ b/lib/kcfinder/themes/dark/css.php @@ -0,0 +1,10 @@ +minify("cache/theme_$theme.css"); diff --git a/lib/kcfinder/themes/dark/img/bg_transparent.png b/lib/kcfinder/themes/dark/img/bg_transparent.png new file mode 100644 index 0000000..08a9d43 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/bg_transparent.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/..png b/lib/kcfinder/themes/dark/img/files/big/..png new file mode 100644 index 0000000..aaff484 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/..png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/.image.png b/lib/kcfinder/themes/dark/img/files/big/.image.png new file mode 100644 index 0000000..bbe1180 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/.image.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/avi.png b/lib/kcfinder/themes/dark/img/files/big/avi.png new file mode 100644 index 0000000..28f9700 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/avi.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/bat.png b/lib/kcfinder/themes/dark/img/files/big/bat.png new file mode 100644 index 0000000..eaa3dc9 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/bat.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/bmp.png b/lib/kcfinder/themes/dark/img/files/big/bmp.png new file mode 100644 index 0000000..bbe1180 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/bmp.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/bz2.png b/lib/kcfinder/themes/dark/img/files/big/bz2.png new file mode 100644 index 0000000..84eaa19 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/bz2.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/ccd.png b/lib/kcfinder/themes/dark/img/files/big/ccd.png new file mode 100644 index 0000000..aa9f4a2 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/ccd.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/cgi.png b/lib/kcfinder/themes/dark/img/files/big/cgi.png new file mode 100644 index 0000000..eaa3dc9 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/cgi.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/com.png b/lib/kcfinder/themes/dark/img/files/big/com.png new file mode 100644 index 0000000..427a328 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/com.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/csh.png b/lib/kcfinder/themes/dark/img/files/big/csh.png new file mode 100644 index 0000000..eaa3dc9 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/csh.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/cue.png b/lib/kcfinder/themes/dark/img/files/big/cue.png new file mode 100644 index 0000000..aa9f4a2 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/cue.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/deb.png b/lib/kcfinder/themes/dark/img/files/big/deb.png new file mode 100644 index 0000000..14ce82f Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/deb.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/dll.png b/lib/kcfinder/themes/dark/img/files/big/dll.png new file mode 100644 index 0000000..9e03a48 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/dll.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/doc.png b/lib/kcfinder/themes/dark/img/files/big/doc.png new file mode 100644 index 0000000..b544dcc Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/doc.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/docx.png b/lib/kcfinder/themes/dark/img/files/big/docx.png new file mode 100644 index 0000000..b544dcc Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/docx.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/exe.png b/lib/kcfinder/themes/dark/img/files/big/exe.png new file mode 100644 index 0000000..427a328 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/exe.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/fla.png b/lib/kcfinder/themes/dark/img/files/big/fla.png new file mode 100644 index 0000000..5e7c751 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/fla.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/flv.png b/lib/kcfinder/themes/dark/img/files/big/flv.png new file mode 100644 index 0000000..28f9700 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/flv.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/fon.png b/lib/kcfinder/themes/dark/img/files/big/fon.png new file mode 100644 index 0000000..3815dac Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/fon.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/gif.png b/lib/kcfinder/themes/dark/img/files/big/gif.png new file mode 100644 index 0000000..bbe1180 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/gif.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/gz.png b/lib/kcfinder/themes/dark/img/files/big/gz.png new file mode 100644 index 0000000..84eaa19 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/gz.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/htm.png b/lib/kcfinder/themes/dark/img/files/big/htm.png new file mode 100644 index 0000000..4995b6b Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/htm.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/html.png b/lib/kcfinder/themes/dark/img/files/big/html.png new file mode 100644 index 0000000..4995b6b Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/html.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/ini.png b/lib/kcfinder/themes/dark/img/files/big/ini.png new file mode 100644 index 0000000..02489bd Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/ini.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/iso.png b/lib/kcfinder/themes/dark/img/files/big/iso.png new file mode 100644 index 0000000..aa9f4a2 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/iso.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/jar.png b/lib/kcfinder/themes/dark/img/files/big/jar.png new file mode 100644 index 0000000..cef54cd Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/jar.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/java.png b/lib/kcfinder/themes/dark/img/files/big/java.png new file mode 100644 index 0000000..351b5db Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/java.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/jpeg.png b/lib/kcfinder/themes/dark/img/files/big/jpeg.png new file mode 100644 index 0000000..bbe1180 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/jpeg.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/jpg.png b/lib/kcfinder/themes/dark/img/files/big/jpg.png new file mode 100644 index 0000000..bbe1180 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/jpg.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/js.png b/lib/kcfinder/themes/dark/img/files/big/js.png new file mode 100644 index 0000000..fcb1f8f Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/js.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/mds.png b/lib/kcfinder/themes/dark/img/files/big/mds.png new file mode 100644 index 0000000..aa9f4a2 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/mds.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/mdx.png b/lib/kcfinder/themes/dark/img/files/big/mdx.png new file mode 100644 index 0000000..aa9f4a2 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/mdx.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/mid.png b/lib/kcfinder/themes/dark/img/files/big/mid.png new file mode 100644 index 0000000..6187bc5 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/mid.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/midi.png b/lib/kcfinder/themes/dark/img/files/big/midi.png new file mode 100644 index 0000000..6187bc5 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/midi.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/mkv.png b/lib/kcfinder/themes/dark/img/files/big/mkv.png new file mode 100644 index 0000000..28f9700 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/mkv.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/mov.png b/lib/kcfinder/themes/dark/img/files/big/mov.png new file mode 100644 index 0000000..28f9700 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/mov.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/mp3.png b/lib/kcfinder/themes/dark/img/files/big/mp3.png new file mode 100644 index 0000000..5f4c206 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/mp3.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/mp4.png b/lib/kcfinder/themes/dark/img/files/big/mp4.png new file mode 100644 index 0000000..28f9700 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/mp4.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/mpeg.png b/lib/kcfinder/themes/dark/img/files/big/mpeg.png new file mode 100644 index 0000000..28f9700 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/mpeg.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/mpg.png b/lib/kcfinder/themes/dark/img/files/big/mpg.png new file mode 100644 index 0000000..28f9700 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/mpg.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/nfo.png b/lib/kcfinder/themes/dark/img/files/big/nfo.png new file mode 100644 index 0000000..02489bd Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/nfo.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/nrg.png b/lib/kcfinder/themes/dark/img/files/big/nrg.png new file mode 100644 index 0000000..aa9f4a2 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/nrg.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/ogg.png b/lib/kcfinder/themes/dark/img/files/big/ogg.png new file mode 100644 index 0000000..5f4c206 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/ogg.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/pdf.png b/lib/kcfinder/themes/dark/img/files/big/pdf.png new file mode 100644 index 0000000..49cf5e3 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/pdf.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/php.png b/lib/kcfinder/themes/dark/img/files/big/php.png new file mode 100644 index 0000000..588bef8 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/php.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/phps.png b/lib/kcfinder/themes/dark/img/files/big/phps.png new file mode 100644 index 0000000..588bef8 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/phps.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/pl.png b/lib/kcfinder/themes/dark/img/files/big/pl.png new file mode 100644 index 0000000..d3468a5 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/pl.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/pm.png b/lib/kcfinder/themes/dark/img/files/big/pm.png new file mode 100644 index 0000000..d3468a5 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/pm.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/png.png b/lib/kcfinder/themes/dark/img/files/big/png.png new file mode 100644 index 0000000..bbe1180 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/png.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/ppt.png b/lib/kcfinder/themes/dark/img/files/big/ppt.png new file mode 100644 index 0000000..ae13c8a Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/ppt.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/pptx.png b/lib/kcfinder/themes/dark/img/files/big/pptx.png new file mode 100644 index 0000000..ae13c8a Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/pptx.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/psd.png b/lib/kcfinder/themes/dark/img/files/big/psd.png new file mode 100644 index 0000000..bbe1180 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/psd.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/qt.png b/lib/kcfinder/themes/dark/img/files/big/qt.png new file mode 100644 index 0000000..28f9700 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/qt.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/rar.png b/lib/kcfinder/themes/dark/img/files/big/rar.png new file mode 100644 index 0000000..84eaa19 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/rar.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/rpm.png b/lib/kcfinder/themes/dark/img/files/big/rpm.png new file mode 100644 index 0000000..0708eef Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/rpm.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/rtf.png b/lib/kcfinder/themes/dark/img/files/big/rtf.png new file mode 100644 index 0000000..02489bd Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/rtf.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/sh.png b/lib/kcfinder/themes/dark/img/files/big/sh.png new file mode 100644 index 0000000..eaa3dc9 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/sh.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/sql.png b/lib/kcfinder/themes/dark/img/files/big/sql.png new file mode 100644 index 0000000..754b3dc Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/sql.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/srt.png b/lib/kcfinder/themes/dark/img/files/big/srt.png new file mode 100644 index 0000000..02489bd Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/srt.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/sub.png b/lib/kcfinder/themes/dark/img/files/big/sub.png new file mode 100644 index 0000000..02489bd Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/sub.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/swf.png b/lib/kcfinder/themes/dark/img/files/big/swf.png new file mode 100644 index 0000000..45a8208 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/swf.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/tgz.png b/lib/kcfinder/themes/dark/img/files/big/tgz.png new file mode 100644 index 0000000..d7e7b5b Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/tgz.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/tif.png b/lib/kcfinder/themes/dark/img/files/big/tif.png new file mode 100644 index 0000000..bbe1180 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/tif.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/tiff.png b/lib/kcfinder/themes/dark/img/files/big/tiff.png new file mode 100644 index 0000000..bbe1180 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/tiff.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/torrent.png b/lib/kcfinder/themes/dark/img/files/big/torrent.png new file mode 100644 index 0000000..0bffac4 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/torrent.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/ttf.png b/lib/kcfinder/themes/dark/img/files/big/ttf.png new file mode 100644 index 0000000..4f43e19 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/ttf.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/txt.png b/lib/kcfinder/themes/dark/img/files/big/txt.png new file mode 100644 index 0000000..02489bd Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/txt.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/wav.png b/lib/kcfinder/themes/dark/img/files/big/wav.png new file mode 100644 index 0000000..5f4c206 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/wav.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/wma.png b/lib/kcfinder/themes/dark/img/files/big/wma.png new file mode 100644 index 0000000..5f4c206 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/wma.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/xls.png b/lib/kcfinder/themes/dark/img/files/big/xls.png new file mode 100644 index 0000000..ddf069f Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/xls.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/xlsx.png b/lib/kcfinder/themes/dark/img/files/big/xlsx.png new file mode 100644 index 0000000..ddf069f Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/xlsx.png differ diff --git a/lib/kcfinder/themes/dark/img/files/big/zip.png b/lib/kcfinder/themes/dark/img/files/big/zip.png new file mode 100644 index 0000000..84eaa19 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/big/zip.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/..png b/lib/kcfinder/themes/dark/img/files/small/..png new file mode 100644 index 0000000..67f4c5f Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/..png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/.image.png b/lib/kcfinder/themes/dark/img/files/small/.image.png new file mode 100644 index 0000000..638dee6 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/.image.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/avi.png b/lib/kcfinder/themes/dark/img/files/small/avi.png new file mode 100644 index 0000000..bbff051 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/avi.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/bat.png b/lib/kcfinder/themes/dark/img/files/small/bat.png new file mode 100644 index 0000000..7b87884 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/bat.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/bmp.png b/lib/kcfinder/themes/dark/img/files/small/bmp.png new file mode 100644 index 0000000..638dee6 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/bmp.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/bz2.png b/lib/kcfinder/themes/dark/img/files/small/bz2.png new file mode 100644 index 0000000..305f01b Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/bz2.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/ccd.png b/lib/kcfinder/themes/dark/img/files/small/ccd.png new file mode 100644 index 0000000..4e8d91d Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/ccd.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/cgi.png b/lib/kcfinder/themes/dark/img/files/small/cgi.png new file mode 100644 index 0000000..7b87884 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/cgi.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/com.png b/lib/kcfinder/themes/dark/img/files/small/com.png new file mode 100644 index 0000000..2246f30 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/com.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/csh.png b/lib/kcfinder/themes/dark/img/files/small/csh.png new file mode 100644 index 0000000..7b87884 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/csh.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/cue.png b/lib/kcfinder/themes/dark/img/files/small/cue.png new file mode 100644 index 0000000..4e8d91d Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/cue.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/deb.png b/lib/kcfinder/themes/dark/img/files/small/deb.png new file mode 100644 index 0000000..305f01b Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/deb.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/dll.png b/lib/kcfinder/themes/dark/img/files/small/dll.png new file mode 100644 index 0000000..b1a2f1c Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/dll.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/doc.png b/lib/kcfinder/themes/dark/img/files/small/doc.png new file mode 100644 index 0000000..069059d Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/doc.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/docx.png b/lib/kcfinder/themes/dark/img/files/small/docx.png new file mode 100644 index 0000000..069059d Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/docx.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/exe.png b/lib/kcfinder/themes/dark/img/files/small/exe.png new file mode 100644 index 0000000..2246f30 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/exe.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/fla.png b/lib/kcfinder/themes/dark/img/files/small/fla.png new file mode 100644 index 0000000..c50ec52 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/fla.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/flv.png b/lib/kcfinder/themes/dark/img/files/small/flv.png new file mode 100644 index 0000000..bbff051 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/flv.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/fon.png b/lib/kcfinder/themes/dark/img/files/small/fon.png new file mode 100644 index 0000000..2303efe Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/fon.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/gif.png b/lib/kcfinder/themes/dark/img/files/small/gif.png new file mode 100644 index 0000000..638dee6 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/gif.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/gz.png b/lib/kcfinder/themes/dark/img/files/small/gz.png new file mode 100644 index 0000000..305f01b Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/gz.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/htm.png b/lib/kcfinder/themes/dark/img/files/small/htm.png new file mode 100644 index 0000000..cc2f1bf Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/htm.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/html.png b/lib/kcfinder/themes/dark/img/files/small/html.png new file mode 100644 index 0000000..cc2f1bf Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/html.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/ini.png b/lib/kcfinder/themes/dark/img/files/small/ini.png new file mode 100644 index 0000000..d904593 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/ini.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/iso.png b/lib/kcfinder/themes/dark/img/files/small/iso.png new file mode 100644 index 0000000..4e8d91d Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/iso.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/jar.png b/lib/kcfinder/themes/dark/img/files/small/jar.png new file mode 100644 index 0000000..305f01b Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/jar.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/java.png b/lib/kcfinder/themes/dark/img/files/small/java.png new file mode 100644 index 0000000..58fa8d0 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/java.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/jpeg.png b/lib/kcfinder/themes/dark/img/files/small/jpeg.png new file mode 100644 index 0000000..638dee6 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/jpeg.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/jpg.png b/lib/kcfinder/themes/dark/img/files/small/jpg.png new file mode 100644 index 0000000..638dee6 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/jpg.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/js.png b/lib/kcfinder/themes/dark/img/files/small/js.png new file mode 100644 index 0000000..db79975 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/js.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/mds.png b/lib/kcfinder/themes/dark/img/files/small/mds.png new file mode 100644 index 0000000..4e8d91d Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/mds.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/mdx.png b/lib/kcfinder/themes/dark/img/files/small/mdx.png new file mode 100644 index 0000000..4e8d91d Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/mdx.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/mid.png b/lib/kcfinder/themes/dark/img/files/small/mid.png new file mode 100644 index 0000000..e1ed4bd Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/mid.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/midi.png b/lib/kcfinder/themes/dark/img/files/small/midi.png new file mode 100644 index 0000000..e1ed4bd Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/midi.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/mkv.png b/lib/kcfinder/themes/dark/img/files/small/mkv.png new file mode 100644 index 0000000..bbff051 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/mkv.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/mov.png b/lib/kcfinder/themes/dark/img/files/small/mov.png new file mode 100644 index 0000000..bbff051 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/mov.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/mp3.png b/lib/kcfinder/themes/dark/img/files/small/mp3.png new file mode 100644 index 0000000..017b00d Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/mp3.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/mp4.png b/lib/kcfinder/themes/dark/img/files/small/mp4.png new file mode 100644 index 0000000..bbff051 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/mp4.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/mpeg.png b/lib/kcfinder/themes/dark/img/files/small/mpeg.png new file mode 100644 index 0000000..bbff051 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/mpeg.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/mpg.png b/lib/kcfinder/themes/dark/img/files/small/mpg.png new file mode 100644 index 0000000..bbff051 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/mpg.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/nfo.png b/lib/kcfinder/themes/dark/img/files/small/nfo.png new file mode 100644 index 0000000..d904593 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/nfo.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/nrg.png b/lib/kcfinder/themes/dark/img/files/small/nrg.png new file mode 100644 index 0000000..4e8d91d Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/nrg.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/ogg.png b/lib/kcfinder/themes/dark/img/files/small/ogg.png new file mode 100644 index 0000000..017b00d Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/ogg.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/pdf.png b/lib/kcfinder/themes/dark/img/files/small/pdf.png new file mode 100644 index 0000000..9498f0f Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/pdf.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/php.png b/lib/kcfinder/themes/dark/img/files/small/php.png new file mode 100644 index 0000000..d73934b Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/php.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/phps.png b/lib/kcfinder/themes/dark/img/files/small/phps.png new file mode 100644 index 0000000..d73934b Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/phps.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/pl.png b/lib/kcfinder/themes/dark/img/files/small/pl.png new file mode 100644 index 0000000..d904593 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/pl.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/pm.png b/lib/kcfinder/themes/dark/img/files/small/pm.png new file mode 100644 index 0000000..d904593 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/pm.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/png.png b/lib/kcfinder/themes/dark/img/files/small/png.png new file mode 100644 index 0000000..638dee6 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/png.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/ppt.png b/lib/kcfinder/themes/dark/img/files/small/ppt.png new file mode 100644 index 0000000..bdccbb6 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/ppt.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/pptx.png b/lib/kcfinder/themes/dark/img/files/small/pptx.png new file mode 100644 index 0000000..bdccbb6 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/pptx.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/psd.png b/lib/kcfinder/themes/dark/img/files/small/psd.png new file mode 100644 index 0000000..638dee6 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/psd.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/qt.png b/lib/kcfinder/themes/dark/img/files/small/qt.png new file mode 100644 index 0000000..bbff051 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/qt.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/rar.png b/lib/kcfinder/themes/dark/img/files/small/rar.png new file mode 100644 index 0000000..305f01b Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/rar.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/rpm.png b/lib/kcfinder/themes/dark/img/files/small/rpm.png new file mode 100644 index 0000000..305f01b Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/rpm.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/rtf.png b/lib/kcfinder/themes/dark/img/files/small/rtf.png new file mode 100644 index 0000000..d904593 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/rtf.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/sh.png b/lib/kcfinder/themes/dark/img/files/small/sh.png new file mode 100644 index 0000000..7b87884 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/sh.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/sql.png b/lib/kcfinder/themes/dark/img/files/small/sql.png new file mode 100644 index 0000000..5665b63 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/sql.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/srt.png b/lib/kcfinder/themes/dark/img/files/small/srt.png new file mode 100644 index 0000000..d904593 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/srt.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/sub.png b/lib/kcfinder/themes/dark/img/files/small/sub.png new file mode 100644 index 0000000..d904593 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/sub.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/swf.png b/lib/kcfinder/themes/dark/img/files/small/swf.png new file mode 100644 index 0000000..80e05a3 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/swf.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/tgz.png b/lib/kcfinder/themes/dark/img/files/small/tgz.png new file mode 100644 index 0000000..305f01b Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/tgz.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/tif.png b/lib/kcfinder/themes/dark/img/files/small/tif.png new file mode 100644 index 0000000..638dee6 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/tif.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/tiff.png b/lib/kcfinder/themes/dark/img/files/small/tiff.png new file mode 100644 index 0000000..638dee6 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/tiff.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/torrent.png b/lib/kcfinder/themes/dark/img/files/small/torrent.png new file mode 100644 index 0000000..55c04aa Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/torrent.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/ttf.png b/lib/kcfinder/themes/dark/img/files/small/ttf.png new file mode 100644 index 0000000..ed3e0f6 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/ttf.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/txt.png b/lib/kcfinder/themes/dark/img/files/small/txt.png new file mode 100644 index 0000000..d904593 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/txt.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/wav.png b/lib/kcfinder/themes/dark/img/files/small/wav.png new file mode 100644 index 0000000..017b00d Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/wav.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/wma.png b/lib/kcfinder/themes/dark/img/files/small/wma.png new file mode 100644 index 0000000..017b00d Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/wma.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/xls.png b/lib/kcfinder/themes/dark/img/files/small/xls.png new file mode 100644 index 0000000..573d141 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/xls.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/xlsx.png b/lib/kcfinder/themes/dark/img/files/small/xlsx.png new file mode 100644 index 0000000..573d141 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/xlsx.png differ diff --git a/lib/kcfinder/themes/dark/img/files/small/zip.png b/lib/kcfinder/themes/dark/img/files/small/zip.png new file mode 100644 index 0000000..305f01b Binary files /dev/null and b/lib/kcfinder/themes/dark/img/files/small/zip.png differ diff --git a/lib/kcfinder/themes/dark/img/icons/about.png b/lib/kcfinder/themes/dark/img/icons/about.png new file mode 100644 index 0000000..12cd1ae Binary files /dev/null and b/lib/kcfinder/themes/dark/img/icons/about.png differ diff --git a/lib/kcfinder/themes/dark/img/icons/clipboard-add.png b/lib/kcfinder/themes/dark/img/icons/clipboard-add.png new file mode 100644 index 0000000..d5eac9b Binary files /dev/null and b/lib/kcfinder/themes/dark/img/icons/clipboard-add.png differ diff --git a/lib/kcfinder/themes/dark/img/icons/clipboard-clear.png b/lib/kcfinder/themes/dark/img/icons/clipboard-clear.png new file mode 100644 index 0000000..dcce0b6 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/icons/clipboard-clear.png differ diff --git a/lib/kcfinder/themes/dark/img/icons/clipboard.png b/lib/kcfinder/themes/dark/img/icons/clipboard.png new file mode 100644 index 0000000..779ad58 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/icons/clipboard.png differ diff --git a/lib/kcfinder/themes/dark/img/icons/copy.png b/lib/kcfinder/themes/dark/img/icons/copy.png new file mode 100644 index 0000000..a9f31a2 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/icons/copy.png differ diff --git a/lib/kcfinder/themes/dark/img/icons/delete.png b/lib/kcfinder/themes/dark/img/icons/delete.png new file mode 100644 index 0000000..1514d51 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/icons/delete.png differ diff --git a/lib/kcfinder/themes/dark/img/icons/download.png b/lib/kcfinder/themes/dark/img/icons/download.png new file mode 100644 index 0000000..260ac88 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/icons/download.png differ diff --git a/lib/kcfinder/themes/dark/img/icons/folder-new.png b/lib/kcfinder/themes/dark/img/icons/folder-new.png new file mode 100644 index 0000000..529fe8f Binary files /dev/null and b/lib/kcfinder/themes/dark/img/icons/folder-new.png differ diff --git a/lib/kcfinder/themes/dark/img/icons/maximize.png b/lib/kcfinder/themes/dark/img/icons/maximize.png new file mode 100644 index 0000000..d41fc7e Binary files /dev/null and b/lib/kcfinder/themes/dark/img/icons/maximize.png differ diff --git a/lib/kcfinder/themes/dark/img/icons/move.png b/lib/kcfinder/themes/dark/img/icons/move.png new file mode 100644 index 0000000..7e62a92 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/icons/move.png differ diff --git a/lib/kcfinder/themes/dark/img/icons/refresh.png b/lib/kcfinder/themes/dark/img/icons/refresh.png new file mode 100644 index 0000000..aa65210 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/icons/refresh.png differ diff --git a/lib/kcfinder/themes/dark/img/icons/rename.png b/lib/kcfinder/themes/dark/img/icons/rename.png new file mode 100644 index 0000000..4e3688e Binary files /dev/null and b/lib/kcfinder/themes/dark/img/icons/rename.png differ diff --git a/lib/kcfinder/themes/dark/img/icons/select.png b/lib/kcfinder/themes/dark/img/icons/select.png new file mode 100644 index 0000000..a9925a0 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/icons/select.png differ diff --git a/lib/kcfinder/themes/dark/img/icons/settings.png b/lib/kcfinder/themes/dark/img/icons/settings.png new file mode 100644 index 0000000..5c8213f Binary files /dev/null and b/lib/kcfinder/themes/dark/img/icons/settings.png differ diff --git a/lib/kcfinder/themes/dark/img/icons/upload.png b/lib/kcfinder/themes/dark/img/icons/upload.png new file mode 100644 index 0000000..f4b6d51 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/icons/upload.png differ diff --git a/lib/kcfinder/themes/dark/img/icons/view.png b/lib/kcfinder/themes/dark/img/icons/view.png new file mode 100644 index 0000000..af4fe07 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/icons/view.png differ diff --git a/lib/kcfinder/themes/dark/img/kcf_logo.png b/lib/kcfinder/themes/dark/img/kcf_logo.png new file mode 100644 index 0000000..e829043 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/kcf_logo.png differ diff --git a/lib/kcfinder/themes/dark/img/loading.gif b/lib/kcfinder/themes/dark/img/loading.gif new file mode 100644 index 0000000..687e848 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/loading.gif differ diff --git a/lib/kcfinder/themes/dark/img/tree/denied.png b/lib/kcfinder/themes/dark/img/tree/denied.png new file mode 100644 index 0000000..07b93c1 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/tree/denied.png differ diff --git a/lib/kcfinder/themes/dark/img/tree/folder.png b/lib/kcfinder/themes/dark/img/tree/folder.png new file mode 100644 index 0000000..784e8fa Binary files /dev/null and b/lib/kcfinder/themes/dark/img/tree/folder.png differ diff --git a/lib/kcfinder/themes/dark/img/tree/minus.png b/lib/kcfinder/themes/dark/img/tree/minus.png new file mode 100644 index 0000000..af617bb Binary files /dev/null and b/lib/kcfinder/themes/dark/img/tree/minus.png differ diff --git a/lib/kcfinder/themes/dark/img/tree/plus.png b/lib/kcfinder/themes/dark/img/tree/plus.png new file mode 100644 index 0000000..897088b Binary files /dev/null and b/lib/kcfinder/themes/dark/img/tree/plus.png differ diff --git a/lib/kcfinder/themes/dark/img/ui-icons_black.png b/lib/kcfinder/themes/dark/img/ui-icons_black.png new file mode 100644 index 0000000..f07448d Binary files /dev/null and b/lib/kcfinder/themes/dark/img/ui-icons_black.png differ diff --git a/lib/kcfinder/themes/dark/img/ui-icons_grey.png b/lib/kcfinder/themes/dark/img/ui-icons_grey.png new file mode 100644 index 0000000..91c18a3 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/ui-icons_grey.png differ diff --git a/lib/kcfinder/themes/dark/img/ui-icons_white.png b/lib/kcfinder/themes/dark/img/ui-icons_white.png new file mode 100644 index 0000000..69ceaa4 Binary files /dev/null and b/lib/kcfinder/themes/dark/img/ui-icons_white.png differ diff --git a/lib/kcfinder/themes/dark/init.js b/lib/kcfinder/themes/dark/init.js new file mode 100644 index 0000000..e658eda --- /dev/null +++ b/lib/kcfinder/themes/dark/init.js @@ -0,0 +1,9 @@ +// Preload some images +$.each([ + "loading.gif", + "ui-icons_black.png", + "ui-icons_grey.png", + "ui-icons_white.png" +], function(i, img) { + new Image().src = "themes/dark/img/" + img; +}); diff --git a/lib/kcfinder/themes/dark/js.php b/lib/kcfinder/themes/dark/js.php new file mode 100644 index 0000000..b60b450 --- /dev/null +++ b/lib/kcfinder/themes/dark/js.php @@ -0,0 +1,10 @@ +minify("cache/theme_$theme.js"); diff --git a/lib/kcfinder/themes/default/01.ui.css b/lib/kcfinder/themes/default/01.ui.css new file mode 100644 index 0000000..0d08ed6 --- /dev/null +++ b/lib/kcfinder/themes/default/01.ui.css @@ -0,0 +1,1522 @@ +/* + +This CSS code is generated from http://ui.sunhater.com +(c)2014 Pavel Tzonkov, sunhater.com. All rights reserved. + +*/ +/*** jQueryUI */ +/** Base */ + +.ui-helper-hidden { + display: none; +} +.ui-helper-hidden-accessible { + border: 0; + clip: rect(0 0 0 0); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; +} +.ui-helper-reset { + margin: 0; + padding: 0; + border: 0; + outline: 0; + line-height: 1.3; + text-decoration: none; + font-size: 100%; + list-style: none; +} +.ui-helper-clearfix:before, +.ui-helper-clearfix:after { + content: ""; + display: table; + border-collapse: collapse; +} +.ui-helper-clearfix:after { + clear: both; +} +.ui-helper-clearfix { + min-height: 0; /* support: IE7 */ +} +.ui-helper-zfix { + width: 100%; + height: 100%; + top: 0; + left: 0; + position: absolute; + opacity: 0; + filter:alpha(opacity=0); +} + +.ui-front { + z-index: 100; +} + +.ui-widget .ui-widget, +.ui-widget input, +.ui-widget select, +.ui-widget textarea, +.ui-widget button { + font-size: 1em; +} +.ui-widget-content { + border: 1px solid #888; + background: #fff; + color: #6B6B6B; +} +.ui-widget-content a { + color: #6B6B6B; +} +.ui-widget-header { + border: 1px solid #1b79b8; + color: #fff; + font-weight: bold; + background: #1b79b8; + background: -webkit-linear-gradient(top, #1b79b8, #59b5f2); + background: -moz-linear-gradient(top, #1b79b8, #59b5f2); + background: -ms-linear-gradient(top, #1b79b8, #59b5f2); + background: -o-linear-gradient(top, #1b79b8, #59b5f2); + background: linear-gradient(to bottom, #1b79b8, #59b5f2); +} +.ui-widget-header a { + color: #fff; +} + +/* Interaction states +----------------------------------*/ + +.ui-state-default, +.ui-widget-content .ui-state-default, +.ui-widget-header .ui-state-default, +.ui-widget.ui-state-disabled { + transition: .2s; + border: 1px solid #6b6b6b; + background: #6b6b6b; + background: -webkit-linear-gradient(top, #ababab, #6b6b6b); + background: -moz-linear-gradient(top, #ababab, #6b6b6b); + background: -ms-linear-gradient(top, #ababab, #6b6b6b); + background: -o-linear-gradient(top, #ababab, #6b6b6b); + background: linear-gradient(to bottom, #ababab, #6b6b6b); + font-weight: bold; + color: #fff; +} + +.ui-state-hover, +.ui-widget-content .ui-state-hover, +.ui-widget-header .ui-state-hover, +.ui-state-focus, +.ui-widget-content .ui-state-focus, +.ui-widget-header .ui-state-focus { + transition: .2s; + border: 1px solid #6b6b6b; + background: #6b6b6b; + background: -webkit-linear-gradient(top, #6b6b6b, #ababab); + background: -moz-linear-gradient(top, #6b6b6b, #ababab); + background: -ms-linear-gradient(top, #6b6b6b, #ababab); + background: -o-linear-gradient(top, #6b6b6b, #ababab); + background: linear-gradient(to bottom, #6b6b6b, #ababab); + font-weight: bold; + color: #fff; +} + +.ui-state-active, +.ui-widget-content .ui-state-active, +.ui-widget-header .ui-state-active, +.ui-menu .ui-state-focus { + transition: .2s; + border: 1px solid #1b79b8; + background: #1b79b8; + background: -webkit-linear-gradient(top, #1b79b8, #59b5f2); + background: -moz-linear-gradient(top, #1b79b8, #59b5f2); + background: -ms-linear-gradient(top, #1b79b8, #59b5f2); + background: -o-linear-gradient(top, #1b79b8, #59b5f2); + background: linear-gradient(to bottom, #1b79b8, #59b5f2); + font-weight: bold; + color: #fff; +} + +.ui-state-default a, +.ui-state-default a:link, +.ui-state-default a:visited, +.ui-state-hover a, +.ui-state-hover a:hover, +.ui-state-hover a:link, +.ui-state-hover a:visited, +.ui-state-active a, +.ui-state-active a:link, +.ui-state-active a:visited { + transition: .2s; + color: #fff; + text-decoration: none; +} + +.ui-menu .ui-state-active { + transition: .2s; + border-color: #6b6b6b; + background: #6b6b6b; + background: -webkit-linear-gradient(top, #6b6b6b, #ababab); + background: -moz-linear-gradient(top, #6b6b6b, #ababab); + background: -ms-linear-gradient(top, #6b6b6b, #ababab); + background: -o-linear-gradient(top, #6b6b6b, #ababab); + background: linear-gradient(to bottom, #6b6b6b, #ababab); +} + +/* Interaction Cues +----------------------------------*/ + +.ui-state-highlight, +.ui-widget-content .ui-state-highlight, +.ui-widget-header .ui-state-highlight { + border: 1px solid #d5bc2c; + box-shadow: inset 0 0 5px #d5bc2c; + background: #fff6bf; + color: #6b6b6b; +} +.ui-state-error, +.ui-widget-content .ui-state-error, +.ui-widget-header .ui-state-error { + border: 1px solid #cf7f7f; + box-shadow: inset 0 0 5px #cf7f7f; + background: #fac4c4; + color: #6b6b6b; +} +.ui-state-error a, +.ui-widget-content .ui-state-error a, +.ui-widget-header .ui-state-error a, +.ui-state-highlight a, +.ui-widget-content .ui-state-highlight a, +.ui-widget-header .ui-state-highlight a, +.ui-state-error-text, +.ui-widget-content .ui-state-error-text, +.ui-widget-header .ui-state-error-text { + color: #6b6b6b; +} +.ui-priority-primary, +.ui-widget-content .ui-priority-primary, +.ui-widget-header .ui-priority-primary { + font-weight: bold; +} +.ui-priority-secondary, +.ui-widget-content .ui-priority-secondary, +.ui-widget-header .ui-priority-secondary { + opacity: .5; + filter:alpha(opacity=50); + font-weight: normal; +} +.ui-state-disabled, +.ui-widget-content .ui-state-disabled, +.ui-widget-header .ui-state-disabled { + opacity: .50; + filter:alpha(opacity=50); + background-image: none; +} +.ui-state-disabled .ui-icon { + filter:alpha(opacity=50); /* For IE8 - See #6059 */ +} + +/* Interaction Cues +----------------------------------*/ +.ui-state-disabled { + cursor: default !important; +} + +/* Misc visuals +----------------------------------*/ + +/* Overlays */ +.ui-widget-overlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; +} +.ui-resizable { + position: relative; +} +.ui-resizable-handle { + position: absolute; + font-size: 0.1px; + display: block; +} +.ui-resizable-disabled .ui-resizable-handle, +.ui-resizable-autohide .ui-resizable-handle { + display: none; +} +.ui-resizable-n { + cursor: n-resize; + height: 7px; + width: 100%; + top: -5px; + left: 0; +} +.ui-resizable-s { + cursor: s-resize; + height: 7px; + width: 100%; + bottom: -5px; + left: 0; +} +.ui-resizable-e { + cursor: e-resize; + width: 7px; + right: -5px; + top: 0; + height: 100%; +} +.ui-resizable-w { + cursor: w-resize; + width: 7px; + left: -5px; + top: 0; + height: 100%; +} +.ui-resizable-se { + cursor: se-resize; + width: 12px; + height: 12px; + right: 1px; + bottom: 1px; +} +.ui-resizable-sw { + cursor: sw-resize; + width: 9px; + height: 9px; + left: -5px; + bottom: -5px; +} +.ui-resizable-nw { + cursor: nw-resize; + width: 9px; + height: 9px; + left: -5px; + top: -5px; +} +.ui-resizable-ne { + cursor: ne-resize; + width: 9px; + height: 9px; + right: -5px; + top: -5px; +} +.ui-selectable-helper { + position: absolute; + z-index: 100; + border: 1px dotted black; +} + + +/** Accordion */ + +.ui-accordion .ui-accordion-header { + display: block; + cursor: pointer; + position: relative; + margin-top: 2px; + padding: 6px; + min-height: 0; /* support: IE7 */ +} +.ui-accordion .ui-accordion-icons, +.ui-accordion .ui-accordion-icons .ui-accordion-icons { + padding-left: 24px; +} +.ui-accordion .ui-accordion-noicons { + padding-left: 5px; +} + +.ui-accordion .ui-accordion-header .ui-accordion-header-icon { + position: absolute; + left: 5px; + top: 50%; + margin-top: -8px; +} +.ui-accordion .ui-accordion-content { + padding: 1em; + border-top: 0; + overflow: auto; +} + + +/** Autocomplete */ + +.ui-autocomplete { + position: absolute; + top: 0; + left: 0; + cursor: pointer; +} + + +/** Button */ + +.ui-button { + display: inline-block; + position: relative; + padding: 0; + line-height: normal; + cursor: pointer; + vertical-align: middle; + text-align: center; + overflow: visible; /* removes extra width in IE */ +} +.ui-button, +.ui-button:link, +.ui-button:visited, +.ui-button:hover, +.ui-button:active { + text-decoration: none; +} +/* to make room for the icon, a width needs to be set here */ +.ui-button-icon-only { + width: 36px; +} +.ui-button-icons-only { + width: 50px; +} +/* button text element */ +.ui-button .ui-button-text { + display: block; + line-height: normal; +} +.ui-button-text-only .ui-button-text { + padding: 6px 10px; +} +.ui-button-icon-only .ui-button-text, +.ui-button-icons-only .ui-button-text { + padding: 6px; + text-indent: -9999999px; +} +.ui-button-text-icon-primary .ui-button-text, +.ui-button-text-icons .ui-button-text { + padding: 6px 10px 6px 28px; +} +.ui-button-text-icon-secondary .ui-button-text, +.ui-button-text-icons .ui-button-text { + padding: 6px 28px 6px 10px; +} +.ui-button-text-icons .ui-button-text { + padding-left: 28px; + padding-right: 28px; +} +/* no icon support for input elements, provide padding by default */ +input.ui-button { + padding: 6px 10px; +} + +/* button icon element(s) */ +.ui-button-icon-only .ui-icon, +.ui-button-text-icon-primary .ui-icon, +.ui-button-text-icon-secondary .ui-icon, +.ui-button-text-icons .ui-icon, +.ui-button-icons-only .ui-icon { + position: absolute; + top: 50%; + margin-top: -8px; +} +.ui-button-icon-only .ui-icon { + left: 50%; + margin-left: -8px; +} +.ui-button-text-icon-primary .ui-button-icon-primary, +.ui-button-text-icons .ui-button-icon-primary, +.ui-button-icons-only .ui-button-icon-primary { + left: 7px; +} +.ui-button-text-icon-secondary .ui-button-icon-secondary, +.ui-button-text-icons .ui-button-icon-secondary, +.ui-button-icons-only .ui-button-icon-secondary { + right: 7px; +} +/* workarounds */ +/* reset extra padding in Firefox, see h5bp.com/l */ +input.ui-button::-moz-focus-inner, +button.ui-button::-moz-focus-inner { + border: 0; + padding: 0; +} + + +/** Button set */ + +.ui-buttonset { + margin:0; + overflow:auto; +} +.ui-buttonset .ui-button { + margin: 0; + float:left; +} + + +/** Date picker */ + +.ui-datepicker { + width: 19em; + width: 19em; + display: none; + padding: 10px; +} +.ui-datepicker .ui-datepicker-header { + position: relative; + padding: 2px 0; +} +.ui-datepicker .ui-datepicker-prev, +.ui-datepicker .ui-datepicker-next { + position: absolute; + top: 4px; + width: 20px; + height: 20px; +} +.ui-datepicker .ui-datepicker-prev-hover, +.ui-datepicker .ui-datepicker-next-hover { + top: 3px; +} +.ui-datepicker .ui-datepicker-prev { + left: 4px; +} +.ui-datepicker .ui-datepicker-next { + right: 4px; +} +.ui-datepicker .ui-datepicker-prev-hover { + left: 3px; +} +.ui-datepicker .ui-datepicker-next-hover { + right: 3px; +} +.ui-datepicker .ui-datepicker-prev span, +.ui-datepicker .ui-datepicker-next span { + display: block; + position: absolute; + left: 50%; + margin-left: -8px; + top: 50%; + margin-top: -8px; +} +.ui-datepicker .ui-datepicker-title { + margin: 0 10px; + padding: 4px 0; + text-align: center; +} +.ui-datepicker .ui-datepicker-title select { + font-size: 1em; + margin:-2px 2px; + padding:0; + outline:0; +} +.ui-datepicker table { + width: 100%; + border-collapse: collapse; + margin: 0; + font-size: 1em; +} +.ui-datepicker th { + padding: 3px; + text-align: center; + font-weight: bold; + border: 0; +} +.ui-datepicker td { + border: 0; + padding: 1px; +} +.ui-datepicker td span, +.ui-datepicker td a { + display: block; + padding: 2px 3px; + text-align: right; + text-decoration: none; +} +.ui-datepicker .ui-datepicker-buttonpane { + background-image: none; + margin: 10px -11px -11px -11px; + padding: 10px; + border: 1px solid #1b79b8; + background: #e4f5ff; + overflow: auto; +} +.ui-datepicker .ui-datepicker-buttonpane button { + float: right; + cursor: pointer; + width: auto; + overflow: visible; + margin: 0; + padding: 6px 10px; + font-weight: bold; + opacity: 1; + filter: alpha(opacity=100); +} +.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { + float: left; +} + +/* with multiple calendars */ +.ui-datepicker.ui-datepicker-multi { + width: auto; + padding:10px; +} +.ui-datepicker-multi .ui-datepicker-group { + float: left; +} +.ui-datepicker-multi .ui-datepicker-group .ui-datepicker-header { + margin:0; +} +.ui-datepicker-multi .ui-datepicker-group.ui-datepicker-group-last { + margin-right:0; +} + +.ui-datepicker-multi .ui-datepicker-group table { + width: 95%; + margin: 0 auto .4em; +} +.ui-datepicker-multi-2 .ui-datepicker-group { + width: 50%; +} +.ui-datepicker-multi-3 .ui-datepicker-group { + width: 33.3%; +} +.ui-datepicker-multi-4 .ui-datepicker-group { + width: 25%; +} + +.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header, +.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { + border-left-width: 0; +} +.ui-datepicker-multi .ui-datepicker-buttonpane { + clear: left; +} +.ui-datepicker-row-break { + clear: both; + font-size: 0; + width: 100px; +} +th.ui-datepicker-week-col { + color: #215b82; +} +td.ui-datepicker-week-col { + text-align:right; + padding-right:7px; + color: #215b82; +} +td.ui-datepicker-other-month a.ui-state-default { + font-weight: bold; +} +th.ui-datepicker-week-end { + color: #f44; +} + +/* RTL support */ +.ui-datepicker-rtl { + direction: rtl; +} +.ui-datepicker-rtl .ui-datepicker-prev { + right: 2px; + left: auto; +} +.ui-datepicker-rtl .ui-datepicker-next { + left: 2px; + right: auto; +} +.ui-datepicker-rtl .ui-datepicker-prev:hover { + right: 1px; + left: auto; +} +.ui-datepicker-rtl .ui-datepicker-next:hover { + left: 1px; + right: auto; +} +.ui-datepicker-rtl .ui-datepicker-buttonpane { + clear: right; +} +.ui-datepicker-rtl .ui-datepicker-buttonpane button { + float: left; +} +.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current, +.ui-datepicker-rtl .ui-datepicker-group { + float: right; +} +.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header, +.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { + border-right-width: 0; + border-left-width: 1px; +} + + +/** Dialog */ + +.ui-dialog { + position: absolute; + top: 0; + left: 0; + padding: 4px; + outline: 0; + box-shadow: 0 0 10px #000; +} +.ui-dialog .ui-dialog-titlebar { + padding: 5px 10px; + position: relative; +} +.ui-dialog .ui-dialog-title { + float: left; + margin: 0; + padding: 1px 0; + white-space: nowrap; + width: 90%; + overflow: hidden; + text-overflow: ellipsis; +} +.ui-dialog .ui-dialog-titlebar-close { + position: absolute; + right: .3em; + top: 50%; + width: 21px; + margin: -10px 0 0 0; + padding: 1px; + height: 20px; +} +.ui-dialog .ui-dialog-content { + position: relative; + border: 0; + padding: 1em; + margin: 0 -4px; + background: none; + overflow: auto; +} +.ui-dialog .ui-dialog-buttonpane { + text-align: left; + border-width: 1px 0 0 0; + background-image: none; + padding: 10px; +} +.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { + float: right; +} +.ui-dialog .ui-dialog-buttonpane button { + margin: 0 0 0 5px; + cursor: pointer; +} +.ui-dialog .ui-resizable-se { + width: 12px; + height: 12px; + right: -5px; + bottom: -5px; + background-position: 16px 16px; +} +.ui-draggable .ui-dialog-titlebar { + cursor: move; +} + + +/** Menu */ + +.ui-menu { + list-style: none; + padding: 0; + margin: 0; + display: block; + outline: 0; +} +.ui-menu .ui-menu { + margin-top: -3px; + position: absolute; +} +.ui-menu .ui-menu-item { + margin: 0; + padding: 0; + width: 100%; + /* support: IE10, see #8844 */ + list-style-image: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7); +} +.ui-menu .ui-menu-divider { + margin: 1px 10px 1px 10px; + height: 0; + font-size: 0; + line-height: 0; + border-width: 1px 0 0 0; + border-color: #bbb; +} +.ui-menu .ui-menu-item a { + text-decoration: none; + display: block; + padding: 5px 10px; + line-height: 1.5; + min-height: 0; /* support: IE7 */ + font-weight: normal; + border-radius:0; +} +.ui-menu .ui-menu-item a.ui-state-focus, +.ui-menu .ui-menu-item a.ui-state-active { + font-weight: normal; + margin: -1px; + transition: none; +} +.ui-menu .ui-state-disabled { + font-weight: normal; + line-height: 1.5; +} +.ui-menu .ui-state-disabled a { + cursor: default; +} +.ui-menu.ui-corner-all.sh-menu { + border-radius: 4px; +} +.ui-menu.ui-corner-all, .ui-menu.sh-menu.ui-autocomplete.ui-corner-all { + border-radius: 0; +} + +/* icon support */ +.ui-menu-icons { + position: relative; +} +.ui-menu-icons .ui-menu-item a { + position: relative; + padding-left: 2em; +} + +/* left-aligned */ +.ui-menu .ui-icon { + position: absolute; + top: .2em; + left: .2em; +} + +/* right-aligned */ +.ui-menu .ui-menu-icon { + position: static; + float: right; +} + + +/** Progress bar */ + +.ui-progressbar { + height: 2.1em; + text-align: left; + overflow: hidden; +} +.ui-progressbar .ui-progressbar-value { + margin: -1px; + height: 100%; +} +.ui-progressbar .ui-progressbar-overlay { + height: 100%; + filter: alpha(opacity=25); + opacity: 0.25; +} +.ui-progressbar-indeterminate .ui-progressbar-value { + background-image: none; +} + + +/** Slider */ + +.ui-slider { + position: relative; + text-align: left; + margin: 0 13px; + border-radius:15px; +} +.ui-slider .ui-slider-handle { + position: absolute; + z-index: 2; + width: 18px; + height: 18px; + border-radius: 9px; + cursor: default; + box-shadow: 0 0 3px #6b6b6b, inset 0 0 7px #fff, inset 0 0 3px #fff; +} +.ui-slider .ui-slider-handle.ui-state-active { + box-shadow: 0 0 3px #1b79b8, inset 0 0 7px #fff, inset 0 0 3px #fff; +} +.ui-slider .ui-slider-range { + position: absolute; + z-index: 1; + display: block; + border: 0; + background-position: 0 0; +} + +/* For IE8 - See #6727 */ +.ui-slider.ui-state-disabled .ui-slider-handle, +.ui-slider.ui-state-disabled .ui-slider-range { + filter: inherit; +} + +.ui-slider-horizontal { + height: 10px; +} +.ui-slider-horizontal .ui-slider-handle { + top: -5px; + margin-left: -9px; +} +.ui-slider-horizontal .ui-slider-range { + top: 0; + height: 100%; +} +.ui-slider-horizontal .ui-slider-range-min { + left: 0; +} +.ui-slider-horizontal .ui-slider-range-max { + right: 0; +} + +.ui-slider-vertical { + width: 10px; + height: 150px; +} +.ui-slider-vertical .ui-slider-handle { + left: -5px; + margin-left: 0; + margin-bottom: -9px; +} +.ui-slider-vertical .ui-slider-range { + left: -1px; + width: 100%; +} +.ui-slider-vertical .ui-slider-range-min { + bottom: 0; +} +.ui-slider-vertical .ui-slider-range-max { + top: 0; +} + + +/** Spinner */ + +.ui-spinner.ui-widget { + position: relative; + display: inline-block; + overflow: hidden; + padding: 0; + vertical-align: middle; + background: #fff; + background: -webkit-linear-gradient(top, #f0f0f0, #fff); + background: -moz-linear-gradient(top, #f0f0f0, #fff); + background: -ms-linear-gradient(top, #f0f0f0, #fff); + background: -o-linear-gradient(top, #f0f0f0, #fff); + background: linear-gradient(to bottom, #f0f0f0, #fff); +} +.ui-spinner-input { + border: none; + color: inherit; + padding: 0; + margin: 6px 24px 6px 10px; + vertical-align: middle; + outline: 0; + background: transparent; +} +.ui-spinner-input { + color: #6b6b6b} +.ui-spinner-input:focus { + color: #000; +} +.ui-spinner-button { + width: 16px; + height: 50%; + font-size: .5em; + padding: 0; + margin: 0; + text-align: center; + position: absolute; + cursor: default; + display: block; + overflow: hidden; + right: 0; +} +/* more specificity required here to overide default borders */ +.ui-spinner a.ui-spinner-button { + border-top: none; + border-bottom: none; + border-right: none; +} +/* vertical centre icon */ +.ui-spinner .ui-icon { + position: absolute; + margin-top: -8px; + top: 50%; + left: 0; +} +.ui-spinner-up { + top: 0; +} +.ui-spinner-down { + bottom: 0; +} + +/* TR overrides */ +.ui-spinner .ui-icon-triangle-1-s { + /* need to fix icons sprite */ + background-position: -65px -16px; +} + + +/** Tabs */ + +.ui-tabs { + position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ +} +.ui-tabs .ui-tabs-nav { + margin: 0; + padding: 3px 3px 0 3px; +} +.ui-tabs .ui-tabs-nav li { + list-style: none; + float: left; + position: relative; + top: 0; + margin: 1px 3px 0 0; + border-bottom-width: 0; + padding: 0; + white-space: nowrap; +} +.ui-tabs .ui-tabs-nav li a { + float: left; + padding: 6px 10px; + text-decoration: none; +} +.ui-tabs .ui-tabs-nav li.ui-tabs-active { + margin-bottom: -1px; + padding-bottom: 1px; +} +.ui-tabs .ui-tabs-nav li.ui-tabs-active a, +.ui-tabs .ui-tabs-nav li.ui-state-disabled a, +.ui-tabs .ui-tabs-nav li.ui-tabs-loading a { + cursor: text; +} +.ui-tabs .ui-tabs-nav li a, /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */ +.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a { + cursor: pointer; +} +.ui-tabs .ui-tabs-panel { + display: block; + border-width: 0; + padding: 1em; + background: none; +} + +/** Tooltip */ + +body .ui-tooltip { + padding: 6px 10px; + position: absolute; + z-index: 9999; + max-width: 300px; + color: #808080; + border-color: #a5a5a5; + box-shadow: inset 0 0 4px #a5a5a5, 0 0 4px #a5a5a5; + background: -webkit-linear-gradient(top, #ddd, #fff); + background: -moz-linear-gradient(top, #ddd, #fff); + background: -ms-linear-gradient(top, #ddd, #fff); + background: -o-linear-gradient(top, #ddd, #fff); + background: linear-gradient(to bottom, #ddd, #fff); +} + +/** Icons */ + +/* states and images */ +.ui-icon { + display: block; + text-indent: -99999px; + overflow: hidden; + background-repeat: no-repeat; + width: 16px; + height: 16px; +} + +.ui-icon, +.ui-widget-content .ui-icon, +.ui-state-highlight .ui-icon, +.ui-state-error .ui-icon, +.ui-state-error-text .ui-icon, +.ui-icon.ui-icon-black { + background-image: url(img/ui-icons_black.png); +} + +.ui-widget-header .ui-icon, +.ui-state-default .ui-icon, +.ui-state-hover .ui-icon, +.ui-state-focus .ui-icon, +.ui-state-active .ui-icon, +.ui-icon.ui-icon-white { + background-image: url(img/ui-icons_white.png); +} + +/* positioning */ +.ui-icon-blank { background-position: 16px 16px; } +.ui-icon-carat-1-n { background-position: 0 0; } +.ui-icon-carat-1-ne { background-position: -16px 0; } +.ui-icon-carat-1-e { background-position: -32px 0; } +.ui-icon-carat-1-se { background-position: -48px 0; } +.ui-icon-carat-1-s { background-position: -64px 0; } +.ui-icon-carat-1-sw { background-position: -80px 0; } +.ui-icon-carat-1-w { background-position: -96px 0; } +.ui-icon-carat-1-nw { background-position: -112px 0; } +.ui-icon-carat-2-n-s { background-position: -128px 0; } +.ui-icon-carat-2-e-w { background-position: -144px 0; } +.ui-icon-triangle-1-n { background-position: 0 -16px; } +.ui-icon-triangle-1-ne { background-position: -16px -16px; } +.ui-icon-triangle-1-e { background-position: -32px -16px; } +.ui-icon-triangle-1-se { background-position: -48px -16px; } +.ui-icon-triangle-1-s { background-position: -64px -16px; } +.ui-icon-triangle-1-sw { background-position: -80px -16px; } +.ui-icon-triangle-1-w { background-position: -96px -16px; } +.ui-icon-triangle-1-nw { background-position: -112px -16px; } +.ui-icon-triangle-2-n-s { background-position: -128px -16px; } +.ui-icon-triangle-2-e-w { background-position: -144px -16px; } +.ui-icon-arrow-1-n { background-position: 0 -32px; } +.ui-icon-arrow-1-ne { background-position: -16px -32px; } +.ui-icon-arrow-1-e { background-position: -32px -32px; } +.ui-icon-arrow-1-se { background-position: -48px -32px; } +.ui-icon-arrow-1-s { background-position: -64px -32px; } +.ui-icon-arrow-1-sw { background-position: -80px -32px; } +.ui-icon-arrow-1-w { background-position: -96px -32px; } +.ui-icon-arrow-1-nw { background-position: -112px -32px; } +.ui-icon-arrow-2-n-s { background-position: -128px -32px; } +.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } +.ui-icon-arrow-2-e-w { background-position: -160px -32px; } +.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } +.ui-icon-arrowstop-1-n { background-position: -192px -32px; } +.ui-icon-arrowstop-1-e { background-position: -208px -32px; } +.ui-icon-arrowstop-1-s { background-position: -224px -32px; } +.ui-icon-arrowstop-1-w { background-position: -240px -32px; } +.ui-icon-arrowthick-1-n { background-position: 0 -48px; } +.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } +.ui-icon-arrowthick-1-e { background-position: -32px -48px; } +.ui-icon-arrowthick-1-se { background-position: -48px -48px; } +.ui-icon-arrowthick-1-s { background-position: -64px -48px; } +.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } +.ui-icon-arrowthick-1-w { background-position: -96px -48px; } +.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } +.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } +.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } +.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } +.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } +.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } +.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } +.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } +.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } +.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } +.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } +.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } +.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } +.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } +.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } +.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } +.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } +.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } +.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } +.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } +.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } +.ui-icon-arrow-4 { background-position: 0 -80px; } +.ui-icon-arrow-4-diag { background-position: -16px -80px; } +.ui-icon-extlink { background-position: -32px -80px; } +.ui-icon-newwin { background-position: -48px -80px; } +.ui-icon-refresh { background-position: -64px -80px; } +.ui-icon-shuffle { background-position: -80px -80px; } +.ui-icon-transfer-e-w { background-position: -96px -80px; } +.ui-icon-transferthick-e-w { background-position: -112px -80px; } +.ui-icon-folder-collapsed { background-position: 0 -96px; } +.ui-icon-folder-open { background-position: -16px -96px; } +.ui-icon-document { background-position: -32px -96px; } +.ui-icon-document-b { background-position: -48px -96px; } +.ui-icon-note { background-position: -64px -96px; } +.ui-icon-mail-closed { background-position: -80px -96px; } +.ui-icon-mail-open { background-position: -96px -96px; } +.ui-icon-suitcase { background-position: -112px -96px; } +.ui-icon-comment { background-position: -128px -96px; } +.ui-icon-person { background-position: -144px -96px; } +.ui-icon-print { background-position: -160px -96px; } +.ui-icon-trash { background-position: -176px -96px; } +.ui-icon-locked { background-position: -192px -96px; } +.ui-icon-unlocked { background-position: -208px -96px; } +.ui-icon-bookmark { background-position: -224px -96px; } +.ui-icon-tag { background-position: -240px -96px; } +.ui-icon-home { background-position: 0 -112px; } +.ui-icon-flag { background-position: -16px -112px; } +.ui-icon-calendar { background-position: -32px -112px; } +.ui-icon-cart { background-position: -48px -112px; } +.ui-icon-pencil { background-position: -64px -112px; } +.ui-icon-clock { background-position: -80px -112px; } +.ui-icon-disk { background-position: -96px -112px; } +.ui-icon-calculator { background-position: -112px -112px; } +.ui-icon-zoomin { background-position: -128px -112px; } +.ui-icon-zoomout { background-position: -144px -112px; } +.ui-icon-search { background-position: -160px -112px; } +.ui-icon-wrench { background-position: -176px -112px; } +.ui-icon-gear { background-position: -192px -112px; } +.ui-icon-heart { background-position: -208px -112px; } +.ui-icon-star { background-position: -224px -112px; } +.ui-icon-link { background-position: -240px -112px; } +.ui-icon-cancel { background-position: 0 -128px; } +.ui-icon-plus { background-position: -16px -128px; } +.ui-icon-plusthick { background-position: -32px -128px; } +.ui-icon-minus { background-position: -48px -128px; } +.ui-icon-minusthick { background-position: -64px -128px; } +.ui-icon-close { background-position: -80px -128px; } +.ui-icon-closethick { background-position: -96px -128px; } +.ui-icon-key { background-position: -112px -128px; } +.ui-icon-lightbulb { background-position: -128px -128px; } +.ui-icon-scissors { background-position: -144px -128px; } +.ui-icon-clipboard { background-position: -160px -128px; } +.ui-icon-copy { background-position: -176px -128px; } +.ui-icon-contact { background-position: -192px -128px; } +.ui-icon-image { background-position: -208px -128px; } +.ui-icon-video { background-position: -224px -128px; } +.ui-icon-script { background-position: -240px -128px; } +.ui-icon-alert { background-position: 0 -144px; } +.ui-icon-info { background-position: -16px -144px; } +.ui-icon-notice { background-position: -32px -144px; } +.ui-icon-help { background-position: -48px -144px; } +.ui-icon-check { background-position: -64px -144px; } +.ui-icon-bullet { background-position: -80px -144px; } +.ui-icon-radio-on { background-position: -96px -144px; } +.ui-icon-radio-off { background-position: -112px -144px; } +.ui-icon-pin-w { background-position: -128px -144px; } +.ui-icon-pin-s { background-position: -144px -144px; } +.ui-icon-play { background-position: 0 -160px; } +.ui-icon-pause { background-position: -16px -160px; } +.ui-icon-seek-next { background-position: -32px -160px; } +.ui-icon-seek-prev { background-position: -48px -160px; } +.ui-icon-seek-end { background-position: -64px -160px; } +.ui-icon-seek-start { background-position: -80px -160px; } +/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ +.ui-icon-seek-first { background-position: -80px -160px; } +.ui-icon-stop { background-position: -96px -160px; } +.ui-icon-eject { background-position: -112px -160px; } +.ui-icon-volume-off { background-position: -128px -160px; } +.ui-icon-volume-on { background-position: -144px -160px; } +.ui-icon-power { background-position: 0 -176px; } +.ui-icon-signal-diag { background-position: -16px -176px; } +.ui-icon-signal { background-position: -32px -176px; } +.ui-icon-battery-0 { background-position: -48px -176px; } +.ui-icon-battery-1 { background-position: -64px -176px; } +.ui-icon-battery-2 { background-position: -80px -176px; } +.ui-icon-battery-3 { background-position: -96px -176px; } +.ui-icon-circle-plus { background-position: 0 -192px; } +.ui-icon-circle-minus { background-position: -16px -192px; } +.ui-icon-circle-close { background-position: -32px -192px; } +.ui-icon-circle-triangle-e { background-position: -48px -192px; } +.ui-icon-circle-triangle-s { background-position: -64px -192px; } +.ui-icon-circle-triangle-w { background-position: -80px -192px; } +.ui-icon-circle-triangle-n { background-position: -96px -192px; } +.ui-icon-circle-arrow-e { background-position: -112px -192px; } +.ui-icon-circle-arrow-s { background-position: -128px -192px; } +.ui-icon-circle-arrow-w { background-position: -144px -192px; } +.ui-icon-circle-arrow-n { background-position: -160px -192px; } +.ui-icon-circle-zoomin { background-position: -176px -192px; } +.ui-icon-circle-zoomout { background-position: -192px -192px; } +.ui-icon-circle-check { background-position: -208px -192px; } +.ui-icon-circlesmall-plus { background-position: 0 -208px; } +.ui-icon-circlesmall-minus { background-position: -16px -208px; } +.ui-icon-circlesmall-close { background-position: -32px -208px; } +.ui-icon-squaresmall-plus { background-position: -48px -208px; } +.ui-icon-squaresmall-minus { background-position: -64px -208px; } +.ui-icon-squaresmall-close { background-position: -80px -208px; } +.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } +.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } +.ui-icon-grip-solid-vertical { background-position: -32px -224px; } +.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } +.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } +.ui-icon-grip-diagonal-se { background-position: -80px -224px; } + + +/** Misc */ + +/* Corner radius */ +.ui-corner-all, +.ui-corner-top, +.ui-corner-left, +.ui-corner-tl, +.ui-menu .ui-menu-item.ui-menu-item-first a { + border-top-left-radius: 4px; +} +.ui-corner-all, +.ui-corner-top, +.ui-corner-right, +.ui-corner-tr, +.ui-menu .ui-menu-item.ui-menu-item-first a { + border-top-right-radius:4px; +} +.ui-corner-all, +.ui-corner-bottom, +.ui-corner-left, +.ui-corner-bl, +.ui-menu .ui-menu-item.ui-menu-item-last a, +.ui-dialog-buttonpane, +.ui-datepicker-multi .ui-datepicker-group-first .ui-datepicker-header, +.ui-datepicker .ui-datepicker-buttonpane { + border-bottom-left-radius: 4px; +} +.ui-corner-all, +.ui-corner-bottom, +.ui-corner-right, +.ui-corner-br, +.ui-menu .ui-menu-item.ui-menu-item-last a, +.ui-dialog-buttonpane, +.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header, +.ui-datepicker .ui-datepicker-buttonpane { + border-bottom-right-radius: 4px; +} + +/* Overlays */ +.ui-widget-overlay { + background: rgba(255,255,255,.5); +} +.ui-widget-shadow { + margin: -7px 0 0 -7px; + padding: 7px; + background: rgba(0,0,0,.3); + border-radius: 8px; +} + +/* SunHater Fixes */ + +.ui-accordion-content-active, .ui-tabs, .ui-slider-range, .ui-datepicker, .ui-dialog { + border-color: #1b79b8; +} + +.ui-slider .ui-slider-range { + border: 1px solid #1b79b8; + top: -1px +} + +.ui-progressbar { + overflow:visible; +} +.ui-progressbar-value { + border: 1px solid #1b79b8; + margin-top: -1px +} + +.ui-accordion-header, +.ui-tabs-nav, +.ui-button, +.ui-tabs li, +.ui-slider-handle, +.ui-slider-range, +.ui-datepicker-header, +.ui-datepicker-header a:hover, +.ui-datepicker-calendar .ui-state-default, +.ui-progressbar-value, +.ui-menu .ui-menu-item a.ui-state-focus, +.ui-menu .ui-menu-item a.ui-state-active, +.ui-dialog-titlebar, +.ui-dialog-titlebar-close.ui-state-default.ui-state-hover, +.ui-datepicker .ui-datepicker-buttonpane button { + box-shadow: inset 0 0 7px #fff, inset 0 0 3px #fff; +} + +.ui-spinner, +.ui-menu { + box-shadow: inset 0 0 4px #6b6b6b; +} + +.ui-accordion-content, +.ui-tabs, +.ui-dialog-content, +.ui-dialog-buttonpane, +.ui-datepicker, +.ui-datepicker .ui-datepicker-buttonpane { + box-shadow: inset 0 0 4px #1b79b8; +} + +.ui-state-default, +.ui-state-focus, +.ui-state-active, +.ui-widget-header { + text-shadow: + 1px 0 rgba(0,0,0,.2), + -1px 0 rgba(0,0,0,.2), + 0 -1px rgba(0,0,0,.2), + 0 1px rgba(0,0,0,.2), + 1px 1px rgba(0,0,0,.2), + -1px -1px rgba(0,0,0,.2), + 1px -1px rgba(0,0,0,.2), + -1px 1px rgba(0,0,0,.2); +} + +.ui-tabs .ui-state-active, +.ui-datepicker .ui-state-highlight { + text-shadow: none; +} +.ui-datepicker .ui-state-highlight { + color: #215b82; + border-color: #1b79b8; + box-shadow: inset 0 0 4px #1b79b8; + background: #fff; + background: -webkit-linear-gradient(top, #dfeef8, #fff); + background: -moz-linear-gradient(top, #dfeef8, #fff); + background: -ms-linear-gradient(top, #dfeef8, #fff); + background: -o-linear-gradient(top, #dfeef8, #fff); + background: linear-gradient(to bottom, #dfeef8, #fff); +} + +.ui-progressbar, .ui-slider, .ui-menu { + box-shadow: inset 0 0 4px #6b6b6b; + background: #fff; + background: -webkit-linear-gradient(top, #f0f0f0, #fff); + background: -moz-linear-gradient(top, #f0f0f0, #fff); + background: -ms-linear-gradient(top, #f0f0f0, #fff); + background: -o-linear-gradient(top, #f0f0f0, #fff); + background: linear-gradient(to bottom, #f0f0f0, #fff); +} + +.ui-slider, .ui-spinner, .ui-progressbar, .ui-menu { + border-color: #6b6b6b; +} + +.ui-datepicker-calendar .ui-state-default { + border-radius: 3px; +} + +.ui-tabs .ui-tabs-nav { + margin: -1px; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; + padding-left:3px; +} + +.ui-tabs-active.ui-state-active { + background: #fff; + background: -webkit-linear-gradient(top, #ccc, #ddd, #eee, #fff, #fff, #fff); + background: -moz-linear-gradient(top, #ccc, #ddd, #eee, #fff, #fff, #fff); + background: -ms-linear-gradient(top, #ccc, #ddd, #eee, #fff, #fff, #fff); + background: -o-linear-gradient(top, #ccc, #ddd, #eee, #fff, #fff, #fff); + background: linear-gradient(to bottom, #ccc, #ddd, #eee, #fff, #fff, #fff); + box-shadow: inset 0 0 5px #fff, inset 0 0 5px #fff, inset 0 0 5px #fff; +} +.ui-tabs-active.ui-state-active a { + color: #215b82; +} +.ui-state-default, .ui-state-default a { + outline: 0; +} +.ui-datepicker-header, +.ui-dialog-titlebar { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; + margin: -5px -5px 0 -5px; +} +.ui-datepicker-header { + margin: -11px -11px 5px -11px; +} + +.ui-datepicker-header a:hover { + cursor: pointer; +} + +.ui-dialog-titlebar-close.ui-state-default { + border-color: transparent; + background: none; + box-shadow: none; +} + +.ui-dialog-titlebar-close.ui-state-default.ui-state-hover { + border-color: #6b6b6b; + background: #6b6b6b} + +.ui-dialog-buttonpane { + background: #e4f5ff; + border-top-color: #1b79b8; + margin: 0 -4px -4px -4px; + padding: 0; +} + + +/*** shCheckset */ +/* +.shcs { + margin: 0; +} +.shcs > div { + border: 1px solid; + border-top: 0; + padding: 5px; + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; +} +.shcs > input, .shcs > input:focus, .shcs > input:hover { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + margin:0; +} +.shcs label { + padding: 2px 5px 2px 2px; + border: 1px solid transparent; + border-radius: 4px; + color: #6b6b6b; +} +.shcs > div, .shcs label:hover { + border-color: #6b6b6b; + box-shadow: inset 0 0 4px #6b6b6b; + background: #fff; + background: -webkit-linear-gradient(top, #f0f0f0, #fff); + background: -moz-linear-gradient(top, #f0f0f0, #fff); + background: -ms-linear-gradient(top, #f0f0f0, #fff); + background: -o-linear-gradient(top, #f0f0f0, #fff); + background: linear-gradient(to bottom, #f0f0f0, #fff); +} +.shcs label:hover { + color: #6b6b6b; + cursor: pointer; +} +.shcs > div.focus, .shcs label.checked { + border-color: #1b79b8; + box-shadow: inset 0 0 4px #1b79b8; + color: #000; + background: #fff; + background: -webkit-linear-gradient(top, #dfeef8, #fff); + background: -moz-linear-gradient(top, #dfeef8, #fff); + background: -ms-linear-gradient(top, #dfeef8, #fff); + background: -o-linear-gradient(top, #dfeef8, #fff); + background: linear-gradient(to bottom, #dfeef8, #fff); +} +.shcs label.checked div.checker { + border-color: #1b79b8; + background: #1b79b8; + background: -webkit-linear-gradient(top, #59b5f2, #1b79b8); + background: -moz-linear-gradient(top, #59b5f2, #1b79b8); + background: -ms-linear-gradient(top, #59b5f2, #1b79b8); + background: -o-linear-gradient(top, #59b5f2, #1b79b8); + background: linear-gradient(to bottom, #59b5f2, #1b79b8); +} +.shcs label.checked div.checker.hover { + border-color: #1b79b8; + background: #1b79b8; + background: -webkit-linear-gradient(top, #1b79b8, #59b5f2); + background: -moz-linear-gradient(top, #1b79b8, #59b5f2); + background: -ms-linear-gradient(top, #1b79b8, #59b5f2); + background: -o-linear-gradient(top, #1b79b8, #59b5f2); + background: linear-gradient(to bottom, #1b79b8, #59b5f2); +} + +.shcs div.checker.focus { + border-color: #6b6b6b; + background: #6b6b6b; + background: -webkit-linear-gradient(top, #ababab, #6b6b6b); + background: -moz-linear-gradient(top, #ababab, #6b6b6b); + background: -ms-linear-gradient(top, #ababab, #6b6b6b); + background: -o-linear-gradient(top, #ababab, #6b6b6b); + background: linear-gradient(to bottom, #ababab, #6b6b6b); + box-shadow: inset 0 0 7px #fff, inset 0 0 3px #fff; +} + +.shcs div.checker.focus.hover { + border-color: #6b6b6b; + background: #6b6b6b; + background: -webkit-linear-gradient(top, #6b6b6b, #ababab); + background: -moz-linear-gradient(top, #6b6b6b, #ababab); + background: -ms-linear-gradient(top, #6b6b6b, #ababab); + background: -o-linear-gradient(top, #6b6b6b, #ababab); + background: linear-gradient(to bottom, #6b6b6b, #ababab); +} + +.shcs label > span { + position:relative; + margin-left:5px; + top:1px; +}*/ \ No newline at end of file diff --git a/lib/kcfinder/themes/default/02.transForm.css b/lib/kcfinder/themes/default/02.transForm.css new file mode 100644 index 0000000..f3fb9c4 --- /dev/null +++ b/lib/kcfinder/themes/default/02.transForm.css @@ -0,0 +1,543 @@ + +/* COMMON - BEGIN */ + +/* FONT SETTINGS */ +.tf-select, +.tf-input, +.tf-textarea, +.tf-multiple, +.tf-label, +.tf-fieldset legend, +.tf-file, +.tf-file input, +.tf-radio, +.tf-checkbox, +.tf-button, +.tf-input.tf-color, +.tf-input.tf-range { + font-size: 13px; + cursor: pointer; +} + +/* FIELD - NORMAL */ +.tf-select .tf-selected, +.tf-input, +.tf-multiple, +.tf-textarea, +.tf-file .tf-info, +.tf-radio, +.tf-checkbox { + background: #f0f0f0; + background: -webkit-linear-gradient(top, #e3e3e3, #fff); + background: -moz-linear-gradient(top, #e3e3e3, #fff); + background: -ms-linear-gradient(top, #e3e3e3, #fff); + background: -o-linear-gradient(top, #e3e3e3, #fff); + background: linear-gradient(to bottom, #e3e3e3, #fff); + box-shadow: inset 0 0 2px #6b6b6b; + border: 1px solid #6b6b6b; + border-radius: 4px; + color: #6b6b6b; + padding: 6px 10px; +} + +/* FIELD - FOCUSED */ +.tf-select.tf-focused .tf-selected, +.tf-select .tf-menu, +.tf-multiple.tf-focused, +.tf-input:focus, .tf-textarea:focus, +.tf-file.tf-focused .tf-info, +.tf-radio.tf-focused, +.tf-checkbox.tf-focused { + background: #d2eaf6; + background: -webkit-linear-gradient(top, #d2eaf6, #fff); + background: -moz-linear-gradient(top, #d2eaf6, #fff); + background: -ms-linear-gradient(top, #d2eaf6, #fff); + background: -o-linear-gradient(top, #d2eaf6, #fff); + background: linear-gradient(to bottom, #d2eaf6, #fff); + box-shadow: inset 0 0 2px #1b79b8; + border: 1px solid #1b79b8; + color: #1b79b8; +} + +/* BUTTON - NORMAL */ +.tf-button, +.tf-file .tf-button { + background: #6b6b6b; + background: -webkit-linear-gradient(top, #ababab, #6b6b6b); + background: -moz-linear-gradient(top, #ababab, #6b6b6b); + background: -ms-linear-gradient(top, #ababab, #6b6b6b); + background: -o-linear-gradient(top, #ababab, #6b6b6b); + background: linear-gradient(to bottom, #ababab, #6b6b6b); + box-shadow: inset 0 0 7px #fff, inset 0 0 3px #fff; + border: 1px solid #6b6b6b; + border-radius: 4px; + padding: 6px 10px; +} + +/* BUTTON - FOCUSED */ +.tf-file.tf-focused .tf-button, +.tf-button.tf-focused, +.tf-select.tf-focused .tf-button{ + background: #1b79b8; + background: -webkit-linear-gradient(top, #59b5f2, #1b79b8); + background: -moz-linear-gradient(top, #59b5f2, #1b79b8); + background: -ms-linear-gradient(top, #59b5f2, #1b79b8); + background: -o-linear-gradient(top, #59b5f2, #1b79b8); + background: linear-gradient(to bottom, #59b5f2, #1b79b8); + border-color: #1b79b8; +} + +/* BLACK OUTLINE, WHITE TEXT */ +.tf-select .tf-menu .tf-hover, +.tf-multiple .tf-hover, +.tf-multiple .tf-selected, +.tf-button { + color: #fff; + text-shadow: + 1px 0 rgba(0,0,0,.2), + -1px 0 rgba(0,0,0,.2), + 0 -1px rgba(0,0,0,.2), + 0 1px rgba(0,0,0,.2), + 1px 1px rgba(0,0,0,.2), + -1px -1px rgba(0,0,0,.2), + 1px -1px rgba(0,0,0,.2), + -1px 1px rgba(0,0,0,.2); +} + +/* COMMON - END */ + +/* SELECT BOX - BEGIN */ + +.tf-select .tf-selected { + border-radius: 4px 0 0 4px; +} +.tf-select .tf-button { + border-left: none; + border-radius: 0 4px 4px 0; +} + +.tf-select .tf-button span { + display: block; + background: url('img/ui-icons_white.png') -64px -15px; + width: 16px; + margin-left: 4px; + margin-right: 5px; +} +.tf-select .tf-menu { + border-radius: 0 0 4px 4px; +} +.tf-select .tf-menu div, +.tf-multiple div { + border: 1px solid transparent; + border-left-width: 0; + border-right-width: 0; + padding: 6px 10px; + margin-top: -1px; +} +.tf-select .tf-menu .tf-hover, +.tf-multiple.tf-focused .tf-hover, +.tf-multiple.tf-focused .tf-selected, +.tf-select.tf-opened.tf-focused .tf-button { + border-color: #1b79b8; + background: #59b5f2; + background: -webkit-linear-gradient(top, #1b79b8, #59b5f2); + background: -moz-linear-gradient(top, #1b79b8, #59b5f2); + background: -ms-linear-gradient(top, #1b79b8, #59b5f2); + background: -o-linear-gradient(top, #1b79b8, #59b5f2); + background: linear-gradient(to bottom, #1b79b8, #59b5f2); + box-shadow: inset 0 0 7px #fff, inset 0 0 3px #fff; +} +.tf-select.tf-opened .tf-button { + background: #ababab; + background: -webkit-linear-gradient(top, #6b6b6b, #ababab); + background: -moz-linear-gradient(top, #6b6b6b, #ababab); + background: -ms-linear-gradient(top, #6b6b6b, #ababab); + background: -o-linear-gradient(top, #6b6b6b, #ababab); + background: linear-gradient(to bottom, #6b6b6b, #ababab); +} +.tf-select.tf-opened .tf-button { + +} +.tf-select .tf-menu .tf-group-last, +.tf-select .tf-menu div.tf-last { + border-bottom-width: 0; +} +.tf-select .tf-menu ul { + overflow: hidden; +} +.tf-select .tf-menu li.tf-last { + margin-bottom: -1px; +} +.tf-select .tf-menu .tf-last { + border-radius: 0 0 4px 4px; +} +.tf-select.tf-opened .tf-selected { + border-radius: 4px 0 0 0; +} +.tf-select.tf-opened .tf-button { + border-radius: 0 4px 0 0; +} +.tf-select .tf-menu li, +.tf-multiple.tf-focused li { + border-bottom: 1px solid #54b0e0; + border-top: 1px solid #54b0e0; + margin: -1px 0; +} +.tf-select .tf-menu li > span, +.tf-multiple li > span, +.tf-multiple.tf-focused li > span { + display: block; + padding: 6px 10px; + text-align: center; + font-weight: bold; + color: #6b6b6b; + background: #a7deff; + border-bottom: 1px solid #54b0e0; + cursor: default; + white-space: nowrap; +} + +/* SELECT BOX - END */ + +/* MULTIPLE SELECT BOX - BEGIN */ + +.tf-multiple { + padding: 0; +} +.tf-multiple li { + border: 1px solid #54b0e0; + border-right: none; + border-left: none; + margin: -1px 0; +} +.tf-multiple li > span { + color: #70a5d1; + border-color: #54b0e0; + background: #c1ddf5; +} +.tf-multiple .tf-hover, +.tf-multiple .tf-selected, +.tf-multiple.tf-focused .tf-hover { + background: #b7def2; + background: -webkit-linear-gradient(top, #54b0e0, #b7def2); + background: -moz-linear-gradient(top, #54b0e0, #b7def2); + background: -ms-linear-gradient(top, #54b0e0, #b7def2); + background: -o-linear-gradient(top, #54b0e0, #b7def2); + background: linear-gradient(to bottom, #54b0e0, #b7def2); + box-shadow: inset 0 0 2px #fff, inset 0 0 2px #fff; + border-color: #54b0e0; +} +.tf-multiple .tf-hover, +.tf-multiple .tf-selected { + border: 1px solid #54b0e0; + border-left: none; + border-right: none; +} +.tf-multiple div.tf-first { + border-top: none; + border-radius: 4px 4px 0 0; + margin-top: 0; +} +.tf-multiple div.tf-last { + border-bottom: none; + border-radius: 0 0 4px 4px; +} +.tf-multiple .tf-group-first { + border-top: none; + margin-top: 0; +} +.tf-multiple li.tf-last, +.tf-multiple .tf-group-last { + border-bottom: none; +} + +/* MULTIPLE SELECT BOX - END */ + +/* FILE UPLOAD BOX - BEGIN */ + +.tf-file { + width: 200px; + padding: 0; + overflow: auto; +} +.tf-file .tf-info, .tf-file.tf-focused .tf-info { + padding: 6px 10px; + border-radius: 4px 0 0 4px; + border-right: none; +} +.tf-file .tf-button { + border-radius: 0 4px 4px 0; + color: transparent; + text-shadow: none; + padding: 6px 8px; +} +.tf-file .tf-button span { + margin: 0 0 0 -4px; + width: 16px; + height: 16px; + display: block; + overflow: hidden; + background: url('img/ui-icons_white.png') -16px -96px; +} +.tf-file .tf-button:after { + content: "\00a0"; +} +.tf-file input::-webkit-file-upload-button { + cursor: pointer; +} + +/* FILE UPLOAD BOX - END */ + +/* RADIO BUTTON - BEGIN */ + +.tf-radio { + width: 15px; + height: 15px; + padding: 0; + border-radius: 8px; +} +.tf-radio input { + width: 17px; + height: 17px; + margin: -1px 0 0 -1px; + cursor: pointer; +} +.tf-radio span { + width: 15px; + height: 15px; + display: block; + float: right; +} +.tf-radio.tf-checked span { + background: url('img/ui-icons_black.png') -80px -145px; +} +.tf-radio.tf-checked.tf-focused span { + background-image: url('img/ui-icons_blue.png'); +} + +/* RADIO BUTTON - END */ + +/* CHECK BOX - BEGIN */ + +.tf-checkbox { + padding: 0; + width: 15px; + height: 15px; + border-radius: 3px; +} +.tf-checkbox input { + width: 17px; + height: 17px; + margin: -1px 0 0 -1px; + cursor: pointer; +} +.tf-checkbox.tf-checked span { + width: 15px; + height: 15px; + display: block; + background: url('img/ui-icons_black.png') -64px -145px; + float: right; +} +.tf-checkbox.tf-focused.tf-checked span { + background-image: url('img/ui-icons_blue.png'); +} + + +/* CHECK BX - END */ + +/* BUTTON */ +.tf-button { + overflow: hidden; + padding: 0; +} +.tf-button span { + margin: 3px 7px; + float: right; +} +.tf-button input, +.tf-button button { + cursor: pointer; +} + +/* TEXT & TEXTAREA - BEGIN */ + +.tf-input, .tf-textarea { + outline: none; + cursor: text; + margin: 0; +} +/*.tf-input.tf-readOnly, +.tf-textarea.tf-readOnly, +.tf-input.tf-readOnly:focus, +.tf-textarea.tf-readOnly:focus { + background: #e4e4e4; + background: -webkit-linear-gradient(top, #e4e4e4, #fff); + background: -moz-linear-gradient(top, #e4e4e4, #fff); + background: -ms-linear-gradient(top, #e4e4e4, #fff); + background: -o-linear-gradient(top, #e4e4e4, #fff); + background: linear-gradient(to bottom, #e4e4e4, #fff); + box-shadow: inset 0 0 2px #a2a2a2; + border: 1px solid #a2a2a2; + border-radius: 4px; + color: #888; + padding: 6px 10px; +}*/ + +/* PLACEHOLDER COLORS */ + +.tf-input::-webkit-input-placeholder, +.tf-textarea::-webkit-input-placeholder { + color: #bbb; +} +.tf-input:-moz-placeholder, +.tf-textarea:-moz-placeholder { + color: #aaa; +} +.tf-input::-moz-placeholder, +.tf-textarea::-moz-placeholder { + color: #aaa; +} +.tf-input:-ms-input-placeholder, +.tf-textarea:-ms-input-placeholder { + color: #bbb; +} +.tf-input:focus::-webkit-input-placeholder, +.tf-textarea:focus::-webkit-input-placeholder { + color: #abc7d6; +} +.tf-input:focus:-moz-placeholder, +.tf-textarea:focus:-moz-placeholder { + color: #54B0E0; +} +.tf-input:focus::-moz-placeholder, +.tf-textarea:focus::-moz-placeholder { + color: #54B0E0; +} +.tf-input:focus:-ms-input-placeholder, +.tf-textarea:focus:-ms-input-placeholder { + color: #abc7d6; +} + +/* READ-ONLY PLACEHOLDERS */ + +.tf-input.tf-readOnly::-webkit-input-placeholder, +.tf-textarea.tf-readOnly::-webkit-input-placeholder { + color: #d4d4d4; +} +.tf-input.tf-readOnly:-moz-placeholder, +.tf-textarea.tf-readOnly:-moz-placeholder { + color: #dedede; +} +.tf-input.tf-readOnly::-moz-placeholder, +.tf-textarea.tf-readOnly::-moz-placeholder { + color: #dedede; +} +.tf-input.tf-readOnly:-ms-input-placeholder, +.tf-textarea.tf-readOnly:-ms-input-placeholder { + color: #d4d4d4; +} +.tf-input.tf-readOnly:focus::-webkit-input-placeholder, +.tf-textarea.tf-readOnly:focus::-webkit-input-placeholder { + color: #d4d4d4; +} +.tf-input.tf-readOnly:focus:-moz-placeholder, +.tf-textarea.tf-readOnly:focus:-moz-placeholder { + color: #dedede; +} +.tf-input.tf-readOnly:focus::-moz-placeholder, +.tf-textarea.tf-readOnly:focus::-moz-placeholder { + color: #dedede; +} +.tf-input.tf-readOnly:focus:-ms-input-placeholder, +.tf-textarea.tf-readOnly:focus:-ms-input-placeholder { + color: #d4d4d4; +} + +/* TEXT & TEXTAREA - END */ + +/* FIELD SET */ +.tf-fieldset { +border: 1px solid #6B6B6B; + box-shadow: inset 0 0 4px #6B6B6B; + border-radius: 4px; + background: #fff; + background: -webkit-linear-gradient(top, #e3e3e3, #fff); + background: -moz-linear-gradient(top, #e3e3e3, #fff); + background: -ms-linear-gradient(top, #e3e3e3, #fff); + background: -o-linear-gradient(top, #e3e3e3, #fff); + background: linear-gradient(to bottom, #e3e3e3, #fff); + margin: 0 10px 10px 0; + padding: 10px; +} +.tf-fieldset legend { + font-weight: bold; + color: #6B6B6B; + text-shadow: + 1px 0 rgba(255,255,255,.5), + -1px 0 rgba(255,255,255,.5), + 0 -1px rgba(255,255,255,.5), + 0 1px rgba(255,255,255,.5), + 1px 1px rgba(255,255,255,.5), + -1px -1px rgba(255,255,255,.5), + 1px -1px rgba(255,255,255,.5), + -1px 1px rgba(255,255,255,.5), + 0 0 5px #fff; +} + +/* MISC */ + +.tf-label { + color: #6b6b6b; + margin: 0 3px; +} +.tf-label.tf-focused { + color: #1b79b8; +} +.tf-disabled { + opacity: .5; + filter: alpha(opacity=50); +} +.tf-disabled, +.tf-disabled input, +.tf-disabled button, +.tf-disabled * +*.tf-disabled { + cursor: default; +} +.tf-file.tf-disabled input::-webkit-file-upload-button { + cursor: pointer; +} +.tf-fieldset.tf-disabled, +.tf-form.tf-disabled { + opacity: 1; + filter: alpha(opacity=100); +} + +.tf-input.tf-color { + width: 30px; + padding: 0; + height: 24px; +} +.tf-input.tf-number { + text-align: right; +} +.tf-input.tf-range { + height: 9px; + margin: 8px 0 7px 0; +} +.tf-input.tf-search, +.tf-input.tf-search.tf-readOnly{ + border-radius: 11px; +} +.tf-input.tf-datetime, +.tf-input.tf-datetime-local, +.tf-input.tf-month, +.tf-input.tf-time, +.tf-input.tf-week, +.tf-input.tf-datetime:focus, +.tf-input.tf-datetime-local:focus, +.tf-input.tf-month:focus, +.tf-input.tf-time:focus, +.tf-input.tf-week:focus { + padding: 1px 5px; +} \ No newline at end of file diff --git a/lib/kcfinder/themes/default/03.misc.css b/lib/kcfinder/themes/default/03.misc.css new file mode 100644 index 0000000..550d0bc --- /dev/null +++ b/lib/kcfinder/themes/default/03.misc.css @@ -0,0 +1,431 @@ +* { + font-size: 13px; +} +body { + background: #e0e0e0; + color: #6B6B6B; +} +fieldset td { + white-space: nowrap; +} +#folders { + margin: 5px 5px 0 5px; +} +#files { + margin-right: 5px; +} + + +/* SHARED DECLARATIONS */ + +#toolbar a:hover, +#toolbar a.hover, +span.current, +span.regular:hover, +span.context, +a.drag > span.folder, +#clipboard div:hover, +div.file:hover, +#files div.selected, +#files div.selected:hover, +tr.selected > td, +tr.selected:hover > td, +#menu .list div a:hover { + color: #fff; + text-shadow: + 1px 0 rgba(0,0,0,.2), + -1px 0 rgba(0,0,0,.2), + 0 -1px rgba(0,0,0,.2), + 0 1px rgba(0,0,0,.2), + 1px 1px rgba(0,0,0,.2), + -1px -1px rgba(0,0,0,.2), + 1px -1px rgba(0,0,0,.2), + -1px 1px rgba(0,0,0,.2); +} + +#files, +#folders, +#toolbar a.selected { + border: 1px solid #6B6B6B; + box-shadow: inset 0 0 4px #6B6B6B; + border-radius: 4px; + background: #fff; + background: -webkit-linear-gradient(top, #f0f0f0, #fff); + background: -moz-linear-gradient(top, #f0f0f0, #fff); + background: -ms-linear-gradient(top, #f0f0f0, #fff); + background: -o-linear-gradient(top, #f0f0f0, #fff); + background: linear-gradient(to bottom, #f0f0f0, #fff); +} + +/* TOOLBAR */ + +#toolbar { + padding: 5px 0; +} +#toolbar a { + color: #6b6b6b; + margin-right: 5px; + border: 1px solid transparent; + outline: none; + display: block; + float: left; + border-radius: 4px; + padding:0; + background: #E0E0E0; +} +#toolbar a > span { + padding: 6px 10px 6px 26px; + diaplay: block; + float:left; + background: no-repeat 6px center; +} +#toolbar a:hover, +#toolbar a.hover { + border-color: #1b79b8; + background: #1b79b8; + background: -webkit-linear-gradient(top, #59b5f2, #1b79b8); + background: -moz-linear-gradient(top, #59b5f2, #1b79b8); + background: -ms-linear-gradient(top, #59b5f2, #1b79b8); + background: -o-linear-gradient(top, #59b5f2, #1b79b8); + background: linear-gradient(to bottom, #59b5f2, #1b79b8); + box-shadow: inset 0 0 7px #fff, inset 0 0 3px #fff; +} +#toolbar a[href="kcact:upload"] span { + background-image: url(img/icons/upload.png); +} +#toolbar a[href="kcact:refresh"] span { + background-image: url(img/icons/refresh.png); +} +#toolbar a[href="kcact:settings"] span { + background-image: url(img/icons/settings.png); +} +#toolbar a[href="kcact:about"] span { + background-image: url(img/icons/about.png); +} +#toolbar a[href="kcact:maximize"] span { + background-image: url(img/icons/maximize.png); +} + + +/* SETTINGS BAR */ + +#settings label { + cursor: pointer; +} +#settings fieldset { + margin-right:5px; + margin-bottom: 6px; + margin-top:-5px; + padding:6px; +} + + +/* FOLDERS */ + +div.folder { + padding-top: 2px; + margin-top: 4px; + white-space: nowrap; +} +div.folder a { + text-decoration: none; + cursor: default; + outline: none; + color: #6b6b6b; +} +span.folder { + padding: 2px 3px 2px 23px; + outline: none; + background: no-repeat 3px center; + cursor: pointer; + border-radius: 3px; + border: 1px solid transparent; +} +span.brace { + width: 16px; + height: 16px; + outline: none; +} +span.current { + transition: .3s; + background-image: url(img/tree/folder.png); + background-color: #3b98d6; + border-color: #3b98d6; + box-shadow: inset 0 0 7px #fff, inset 0 0 3px #fff; +} +span.regular { + transition: .3s; + background-image: url(img/tree/folder.png); + background-color: transparent; +} +span.regular:hover, span.context, a.drag > span.folder, #clipboard div:hover { + transition: .3s; + background-color: #c6c6c6; + border-color: #c6c6c6; + box-shadow: inset 0 0 7px #fff, inset 0 0 3px #fff; +} +span.opened { + background-image: url(img/tree/minus.png); +} +span.closed { + background-image: url(img/tree/plus.png); +} +span.denied { + background-image: url(img/tree/denied.png); +} + + +/* FILES */ + +div.file { + padding: 4px; + margin: 3px; + border: 1px solid transparent; + border-radius: 4px; +} +div.file:hover { + border-color: #aaa; + box-shadow: inset 0 0 7px #fff, inset 0 0 3px #fff; + background: #c6c6c6; + background: -webkit-linear-gradient(top, #e7e7e7, #c6c6c6); + background: -moz-linear-gradient(top, #e7e7e7, #c6c6c6); + background: -ms-linear-gradient(top, #e7e7e7, #c6c6c6); + background: -o-linear-gradient(top, #e7e7e7, #c6c6c6); + background: linear-gradient(to bottom, #e7e7e7, #c6c6c6); +} +div.file .name { + margin-top: 4px; + font-weight: bold; + height: 16px; + overflow: hidden; + padding-bottom: 2px; +} +div.file .time { + font-size: 10px; +} +div.file .size { + font-size: 10px; +} +#files div.selected, +#files div.selected:hover { + border-color: #3b98d6; + background: #3b98d6; + background: -webkit-linear-gradient(top, #7dc2f2, #3b98d6); + background: -moz-linear-gradient(top, #7dc2f2, #3b98d6); + background: -ms-linear-gradient(top, #7dc2f2, #3b98d6); + background: -o-linear-gradient(top, #7dc2f2, #3b98d6); + background: linear-gradient(to bottom, #7dc2f2, #3b98d6); + box-shadow: inset 0 0 7px #fff, inset 0 0 3px #fff; +} +tr.file > td { + padding: 3px 4px; +} +tr.file:hover > td { + background-color: #ddebf8; + transition: none; +} +tr.selected > td, +tr.selected:hover > td { + transition: .3s; + background-color: #5b9bda; +} +tr.file td.name { + background-position: 2px center; + padding-left: 22px; +} +a.denied { + color: #666; + opacity: 0.5; + filter: alpha(opacity:50); + cursor: default; +} +a.denied:hover { + background-color: #e4e3e2; + border-color: transparent; + box-shadow: none; +} + +/* FILE MENU */ + +#menu .ui-menu a span { + background: left center no-repeat; + padding-left: 20px; + white-space: nowrap; +} +#menu a[href="kcact:refresh"] span { + background-image: url(img/icons/refresh.png); +} +#menu a[href="kcact:mkdir"] span { + background-image: url(img/icons/folder-new.png); +} +#menu a[href="kcact:mvdir"] span, #menu a[href="kcact:mv"] span { + background-image: url(img/icons/rename.png); +} +#menu a[href="kcact:rmdir"] span, #menu a[href="kcact:rm"] span, #menu a[href="kcact:rmcbd"] span { + background-image: url(img/icons/delete.png); +} +#menu a[href="kcact:clpbrdadd"] span { + background-image: url(img/icons/clipboard-add.png); +} +#menu a[href="kcact:pick"] span, #menu a[href="kcact:pick_thumb"] span { + background-image: url(img/icons/select.png); +} +#menu a[href="kcact:download"] span { + background-image: url(img/icons/download.png); +} +#menu a[href="kcact:view"] span { + background-image: url(img/icons/view.png); +} +#menu a[href="kcact:cpcbd"] span { + background-image: url(img/icons/copy.png); +} +#menu a[href="kcact:mvcbd"] span { + background-image: url(img/icons/move.png); +} +#menu a[href="kcact:clrcbd"] span { + background-image: url(img/icons/clipboard-clear.png); +} + +/* CLIPBOARD */ + +#clipboard { + margin-left:-3px; + padding: 2px; +} +#clipboard div { + background: url(img/icons/clipboard.png) no-repeat center center; + border: 1px solid transparent; + padding: 2px; + cursor: pointer; + border-radius: 4px; +} +#clipboard.selected div, #clipboard.selected div:hover { + background-color: #3b98d6; + border-color: #3b98d6; + box-shadow: inset 0 0 7px #fff, inset 0 0 3px #fff; +} +#menu .list a, #menu .list a.ui-state-focus { + margin: -1px 0 0 -1px; + padding: 6px 10px; + border: 1px solid transparent; + background: none; + border-radius: 0; + text-shadow: none; + box-shadow: none; + color: #6b6b6b; +} +#menu .list a.first, #menu .list a.first.ui-state-focus { + border-radius: 4px 4px 0 0; +} +#menu .list a:hover { + border-color: #1b79b8; + background: #1b79b8; + background: -webkit-linear-gradient(top, #1b79b8, #59b5f2); + background: -moz-linear-gradient(top, #1b79b8, #59b5f2); + background: -ms-linear-gradient(top, #1b79b8, #59b5f2); + background: -o-linear-gradient(top, #1b79b8, #59b5f2); + background: linear-gradient(to bottom, #1b79b8, #59b5f2); + box-shadow: inset 0 0 7px #fff, inset 0 0 3px #fff; +} +#menu .list { + overflow:hidden; + max-height: 1px; + margin-bottom: -1px; + padding-bottom:1px; +} +#menu li.div-files { + margin: 0 0 1px 0; +} + +/* ABOUT DIALOG */ + +.about { + text-align: center; +} +.about div.head { + font-weight: bold; + font-size: 12px; + padding: 3px 0 8px 0; +} +.about div.head a { + background: url(img/kcf_logo.png) no-repeat left center; + padding: 0 0 0 27px; + font-size: 17px; + outline: none; +} + +.about a { + text-decoration: none; + color: #0055ff; +} + +.about a:hover { + text-decoration: underline; +} +#checkver { + margin: 5px 0 10px 0; +} +#loading, #checkver > span.loading { + background: url(img/loading.gif); + border: 1px solid #3687e2; + box-shadow: 0 0 3px #3687e2, inset 0 0 4px #fff, inset 0 0 5px #fff; + padding: 6px 10px; + border-radius: 4px; +} +#checkver a { + font-weight: normal; + padding: 3px 3px 3px 20px; + background: url(img/icons/download.png) no-repeat left center; +} + +/* IMAGE VIEWER */ + +.kcfImageViewer .ui-dialog-content { + cursor: pointer; +} +.kcfImageViewer .img { + background: url(img/bg_transparent.png); +} +.ui-dialog-titlebar.loading { + background: url(img/loading.gif); +} + +.ui-dialog-titlebar.loading .ui-dialog-title { + color: #6b6b6b; + text-shadow:none; + font-weight: normal; +} +.ui-dialog-titlebar.loading .ui-dialog-titlebar-close .ui-button-icon-primary.ui-icon.ui-icon-closethick { + background-image: url(img/ui-icons_black.png); +} + + +/* MISC */ + +#loading { + margin-right: 5px; +} +#loadingDirs { + padding: 5px 0 1px 24px; +} +#files.drag { + background: #ddebf8; +} + +#settings .tf-select { + margin: 3px 5px 6px 0; +} +#settings .tf-selected { + padding-top: 10px; + padding-bottom: 11px; +} +#settings .tf-select .tf-button { + padding-top: 7px; + padding-bottom: 8px; +} + +/* FIX FIELDSET BORDER RADIUS BUG ON IE */ +body.msie fieldset, +body.trident.rv fieldset { + border-radius: 0; +} \ No newline at end of file diff --git a/lib/kcfinder/themes/default/README b/lib/kcfinder/themes/default/README new file mode 100644 index 0000000..3d745ac --- /dev/null +++ b/lib/kcfinder/themes/default/README @@ -0,0 +1,9 @@ +This folder contains files for designing default visual theme for KCFinder. +Some icons are taken from default KDE4 visual theme (http://www.kde.org) + +Theme Details: + +Version: 1.0 +Author: Pavel Tzonkov +Licenses: GPLv3 - http://opensource.org/licenses/GPL-3.0 + LGPLv3 - http://opensource.org/licenses/LGPL-3.0 diff --git a/lib/kcfinder/themes/default/css.php b/lib/kcfinder/themes/default/css.php new file mode 100644 index 0000000..247857b --- /dev/null +++ b/lib/kcfinder/themes/default/css.php @@ -0,0 +1,10 @@ +minify("cache/theme_$theme.css"); diff --git a/lib/kcfinder/themes/default/img/bg_transparent.png b/lib/kcfinder/themes/default/img/bg_transparent.png new file mode 100644 index 0000000..3200632 Binary files /dev/null and b/lib/kcfinder/themes/default/img/bg_transparent.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/..png b/lib/kcfinder/themes/default/img/files/big/..png new file mode 100644 index 0000000..aaff484 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/..png differ diff --git a/lib/kcfinder/themes/default/img/files/big/.image.png b/lib/kcfinder/themes/default/img/files/big/.image.png new file mode 100644 index 0000000..bbe1180 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/.image.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/avi.png b/lib/kcfinder/themes/default/img/files/big/avi.png new file mode 100644 index 0000000..28f9700 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/avi.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/bat.png b/lib/kcfinder/themes/default/img/files/big/bat.png new file mode 100644 index 0000000..eaa3dc9 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/bat.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/bmp.png b/lib/kcfinder/themes/default/img/files/big/bmp.png new file mode 100644 index 0000000..bbe1180 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/bmp.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/bz2.png b/lib/kcfinder/themes/default/img/files/big/bz2.png new file mode 100644 index 0000000..84eaa19 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/bz2.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/ccd.png b/lib/kcfinder/themes/default/img/files/big/ccd.png new file mode 100644 index 0000000..aa9f4a2 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/ccd.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/cgi.png b/lib/kcfinder/themes/default/img/files/big/cgi.png new file mode 100644 index 0000000..eaa3dc9 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/cgi.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/com.png b/lib/kcfinder/themes/default/img/files/big/com.png new file mode 100644 index 0000000..427a328 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/com.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/csh.png b/lib/kcfinder/themes/default/img/files/big/csh.png new file mode 100644 index 0000000..eaa3dc9 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/csh.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/cue.png b/lib/kcfinder/themes/default/img/files/big/cue.png new file mode 100644 index 0000000..aa9f4a2 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/cue.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/deb.png b/lib/kcfinder/themes/default/img/files/big/deb.png new file mode 100644 index 0000000..14ce82f Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/deb.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/dll.png b/lib/kcfinder/themes/default/img/files/big/dll.png new file mode 100644 index 0000000..9e03a48 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/dll.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/doc.png b/lib/kcfinder/themes/default/img/files/big/doc.png new file mode 100644 index 0000000..b544dcc Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/doc.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/docx.png b/lib/kcfinder/themes/default/img/files/big/docx.png new file mode 100644 index 0000000..b544dcc Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/docx.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/exe.png b/lib/kcfinder/themes/default/img/files/big/exe.png new file mode 100644 index 0000000..427a328 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/exe.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/fla.png b/lib/kcfinder/themes/default/img/files/big/fla.png new file mode 100644 index 0000000..5e7c751 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/fla.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/flv.png b/lib/kcfinder/themes/default/img/files/big/flv.png new file mode 100644 index 0000000..28f9700 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/flv.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/fon.png b/lib/kcfinder/themes/default/img/files/big/fon.png new file mode 100644 index 0000000..3815dac Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/fon.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/gif.png b/lib/kcfinder/themes/default/img/files/big/gif.png new file mode 100644 index 0000000..bbe1180 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/gif.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/gz.png b/lib/kcfinder/themes/default/img/files/big/gz.png new file mode 100644 index 0000000..84eaa19 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/gz.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/htm.png b/lib/kcfinder/themes/default/img/files/big/htm.png new file mode 100644 index 0000000..4995b6b Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/htm.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/html.png b/lib/kcfinder/themes/default/img/files/big/html.png new file mode 100644 index 0000000..4995b6b Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/html.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/ini.png b/lib/kcfinder/themes/default/img/files/big/ini.png new file mode 100644 index 0000000..02489bd Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/ini.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/iso.png b/lib/kcfinder/themes/default/img/files/big/iso.png new file mode 100644 index 0000000..aa9f4a2 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/iso.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/jar.png b/lib/kcfinder/themes/default/img/files/big/jar.png new file mode 100644 index 0000000..cef54cd Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/jar.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/java.png b/lib/kcfinder/themes/default/img/files/big/java.png new file mode 100644 index 0000000..351b5db Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/java.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/jpeg.png b/lib/kcfinder/themes/default/img/files/big/jpeg.png new file mode 100644 index 0000000..bbe1180 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/jpeg.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/jpg.png b/lib/kcfinder/themes/default/img/files/big/jpg.png new file mode 100644 index 0000000..bbe1180 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/jpg.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/js.png b/lib/kcfinder/themes/default/img/files/big/js.png new file mode 100644 index 0000000..fcb1f8f Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/js.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/mds.png b/lib/kcfinder/themes/default/img/files/big/mds.png new file mode 100644 index 0000000..aa9f4a2 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/mds.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/mdx.png b/lib/kcfinder/themes/default/img/files/big/mdx.png new file mode 100644 index 0000000..aa9f4a2 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/mdx.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/mid.png b/lib/kcfinder/themes/default/img/files/big/mid.png new file mode 100644 index 0000000..6187bc5 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/mid.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/midi.png b/lib/kcfinder/themes/default/img/files/big/midi.png new file mode 100644 index 0000000..6187bc5 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/midi.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/mkv.png b/lib/kcfinder/themes/default/img/files/big/mkv.png new file mode 100644 index 0000000..28f9700 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/mkv.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/mov.png b/lib/kcfinder/themes/default/img/files/big/mov.png new file mode 100644 index 0000000..28f9700 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/mov.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/mp3.png b/lib/kcfinder/themes/default/img/files/big/mp3.png new file mode 100644 index 0000000..5f4c206 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/mp3.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/mp4.png b/lib/kcfinder/themes/default/img/files/big/mp4.png new file mode 100644 index 0000000..28f9700 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/mp4.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/mpeg.png b/lib/kcfinder/themes/default/img/files/big/mpeg.png new file mode 100644 index 0000000..28f9700 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/mpeg.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/mpg.png b/lib/kcfinder/themes/default/img/files/big/mpg.png new file mode 100644 index 0000000..28f9700 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/mpg.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/nfo.png b/lib/kcfinder/themes/default/img/files/big/nfo.png new file mode 100644 index 0000000..02489bd Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/nfo.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/nrg.png b/lib/kcfinder/themes/default/img/files/big/nrg.png new file mode 100644 index 0000000..aa9f4a2 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/nrg.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/ogg.png b/lib/kcfinder/themes/default/img/files/big/ogg.png new file mode 100644 index 0000000..5f4c206 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/ogg.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/pdf.png b/lib/kcfinder/themes/default/img/files/big/pdf.png new file mode 100644 index 0000000..49cf5e3 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/pdf.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/php.png b/lib/kcfinder/themes/default/img/files/big/php.png new file mode 100644 index 0000000..588bef8 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/php.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/phps.png b/lib/kcfinder/themes/default/img/files/big/phps.png new file mode 100644 index 0000000..588bef8 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/phps.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/pl.png b/lib/kcfinder/themes/default/img/files/big/pl.png new file mode 100644 index 0000000..d3468a5 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/pl.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/pm.png b/lib/kcfinder/themes/default/img/files/big/pm.png new file mode 100644 index 0000000..d3468a5 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/pm.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/png.png b/lib/kcfinder/themes/default/img/files/big/png.png new file mode 100644 index 0000000..bbe1180 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/png.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/ppt.png b/lib/kcfinder/themes/default/img/files/big/ppt.png new file mode 100644 index 0000000..ae13c8a Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/ppt.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/pptx.png b/lib/kcfinder/themes/default/img/files/big/pptx.png new file mode 100644 index 0000000..ae13c8a Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/pptx.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/psd.png b/lib/kcfinder/themes/default/img/files/big/psd.png new file mode 100644 index 0000000..bbe1180 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/psd.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/qt.png b/lib/kcfinder/themes/default/img/files/big/qt.png new file mode 100644 index 0000000..28f9700 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/qt.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/rar.png b/lib/kcfinder/themes/default/img/files/big/rar.png new file mode 100644 index 0000000..84eaa19 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/rar.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/rpm.png b/lib/kcfinder/themes/default/img/files/big/rpm.png new file mode 100644 index 0000000..0708eef Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/rpm.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/rtf.png b/lib/kcfinder/themes/default/img/files/big/rtf.png new file mode 100644 index 0000000..02489bd Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/rtf.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/sh.png b/lib/kcfinder/themes/default/img/files/big/sh.png new file mode 100644 index 0000000..eaa3dc9 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/sh.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/sql.png b/lib/kcfinder/themes/default/img/files/big/sql.png new file mode 100644 index 0000000..754b3dc Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/sql.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/srt.png b/lib/kcfinder/themes/default/img/files/big/srt.png new file mode 100644 index 0000000..02489bd Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/srt.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/sub.png b/lib/kcfinder/themes/default/img/files/big/sub.png new file mode 100644 index 0000000..02489bd Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/sub.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/swf.png b/lib/kcfinder/themes/default/img/files/big/swf.png new file mode 100644 index 0000000..45a8208 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/swf.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/tgz.png b/lib/kcfinder/themes/default/img/files/big/tgz.png new file mode 100644 index 0000000..d7e7b5b Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/tgz.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/tif.png b/lib/kcfinder/themes/default/img/files/big/tif.png new file mode 100644 index 0000000..bbe1180 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/tif.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/tiff.png b/lib/kcfinder/themes/default/img/files/big/tiff.png new file mode 100644 index 0000000..bbe1180 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/tiff.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/torrent.png b/lib/kcfinder/themes/default/img/files/big/torrent.png new file mode 100644 index 0000000..0bffac4 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/torrent.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/ttf.png b/lib/kcfinder/themes/default/img/files/big/ttf.png new file mode 100644 index 0000000..4f43e19 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/ttf.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/txt.png b/lib/kcfinder/themes/default/img/files/big/txt.png new file mode 100644 index 0000000..02489bd Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/txt.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/wav.png b/lib/kcfinder/themes/default/img/files/big/wav.png new file mode 100644 index 0000000..5f4c206 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/wav.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/wma.png b/lib/kcfinder/themes/default/img/files/big/wma.png new file mode 100644 index 0000000..5f4c206 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/wma.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/xls.png b/lib/kcfinder/themes/default/img/files/big/xls.png new file mode 100644 index 0000000..ddf069f Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/xls.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/xlsx.png b/lib/kcfinder/themes/default/img/files/big/xlsx.png new file mode 100644 index 0000000..ddf069f Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/xlsx.png differ diff --git a/lib/kcfinder/themes/default/img/files/big/zip.png b/lib/kcfinder/themes/default/img/files/big/zip.png new file mode 100644 index 0000000..84eaa19 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/big/zip.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/..png b/lib/kcfinder/themes/default/img/files/small/..png new file mode 100644 index 0000000..67f4c5f Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/..png differ diff --git a/lib/kcfinder/themes/default/img/files/small/.image.png b/lib/kcfinder/themes/default/img/files/small/.image.png new file mode 100644 index 0000000..638dee6 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/.image.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/avi.png b/lib/kcfinder/themes/default/img/files/small/avi.png new file mode 100644 index 0000000..bbff051 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/avi.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/bat.png b/lib/kcfinder/themes/default/img/files/small/bat.png new file mode 100644 index 0000000..7b87884 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/bat.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/bmp.png b/lib/kcfinder/themes/default/img/files/small/bmp.png new file mode 100644 index 0000000..638dee6 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/bmp.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/bz2.png b/lib/kcfinder/themes/default/img/files/small/bz2.png new file mode 100644 index 0000000..305f01b Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/bz2.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/ccd.png b/lib/kcfinder/themes/default/img/files/small/ccd.png new file mode 100644 index 0000000..4e8d91d Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/ccd.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/cgi.png b/lib/kcfinder/themes/default/img/files/small/cgi.png new file mode 100644 index 0000000..7b87884 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/cgi.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/com.png b/lib/kcfinder/themes/default/img/files/small/com.png new file mode 100644 index 0000000..2246f30 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/com.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/csh.png b/lib/kcfinder/themes/default/img/files/small/csh.png new file mode 100644 index 0000000..7b87884 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/csh.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/cue.png b/lib/kcfinder/themes/default/img/files/small/cue.png new file mode 100644 index 0000000..4e8d91d Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/cue.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/deb.png b/lib/kcfinder/themes/default/img/files/small/deb.png new file mode 100644 index 0000000..305f01b Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/deb.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/dll.png b/lib/kcfinder/themes/default/img/files/small/dll.png new file mode 100644 index 0000000..b1a2f1c Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/dll.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/doc.png b/lib/kcfinder/themes/default/img/files/small/doc.png new file mode 100644 index 0000000..069059d Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/doc.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/docx.png b/lib/kcfinder/themes/default/img/files/small/docx.png new file mode 100644 index 0000000..069059d Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/docx.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/exe.png b/lib/kcfinder/themes/default/img/files/small/exe.png new file mode 100644 index 0000000..2246f30 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/exe.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/fla.png b/lib/kcfinder/themes/default/img/files/small/fla.png new file mode 100644 index 0000000..c50ec52 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/fla.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/flv.png b/lib/kcfinder/themes/default/img/files/small/flv.png new file mode 100644 index 0000000..bbff051 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/flv.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/fon.png b/lib/kcfinder/themes/default/img/files/small/fon.png new file mode 100644 index 0000000..2303efe Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/fon.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/gif.png b/lib/kcfinder/themes/default/img/files/small/gif.png new file mode 100644 index 0000000..638dee6 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/gif.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/gz.png b/lib/kcfinder/themes/default/img/files/small/gz.png new file mode 100644 index 0000000..305f01b Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/gz.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/htm.png b/lib/kcfinder/themes/default/img/files/small/htm.png new file mode 100644 index 0000000..cc2f1bf Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/htm.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/html.png b/lib/kcfinder/themes/default/img/files/small/html.png new file mode 100644 index 0000000..cc2f1bf Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/html.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/ini.png b/lib/kcfinder/themes/default/img/files/small/ini.png new file mode 100644 index 0000000..d904593 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/ini.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/iso.png b/lib/kcfinder/themes/default/img/files/small/iso.png new file mode 100644 index 0000000..4e8d91d Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/iso.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/jar.png b/lib/kcfinder/themes/default/img/files/small/jar.png new file mode 100644 index 0000000..305f01b Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/jar.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/java.png b/lib/kcfinder/themes/default/img/files/small/java.png new file mode 100644 index 0000000..58fa8d0 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/java.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/jpeg.png b/lib/kcfinder/themes/default/img/files/small/jpeg.png new file mode 100644 index 0000000..638dee6 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/jpeg.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/jpg.png b/lib/kcfinder/themes/default/img/files/small/jpg.png new file mode 100644 index 0000000..638dee6 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/jpg.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/js.png b/lib/kcfinder/themes/default/img/files/small/js.png new file mode 100644 index 0000000..db79975 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/js.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/mds.png b/lib/kcfinder/themes/default/img/files/small/mds.png new file mode 100644 index 0000000..4e8d91d Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/mds.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/mdx.png b/lib/kcfinder/themes/default/img/files/small/mdx.png new file mode 100644 index 0000000..4e8d91d Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/mdx.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/mid.png b/lib/kcfinder/themes/default/img/files/small/mid.png new file mode 100644 index 0000000..e1ed4bd Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/mid.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/midi.png b/lib/kcfinder/themes/default/img/files/small/midi.png new file mode 100644 index 0000000..e1ed4bd Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/midi.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/mkv.png b/lib/kcfinder/themes/default/img/files/small/mkv.png new file mode 100644 index 0000000..bbff051 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/mkv.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/mov.png b/lib/kcfinder/themes/default/img/files/small/mov.png new file mode 100644 index 0000000..bbff051 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/mov.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/mp3.png b/lib/kcfinder/themes/default/img/files/small/mp3.png new file mode 100644 index 0000000..017b00d Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/mp3.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/mp4.png b/lib/kcfinder/themes/default/img/files/small/mp4.png new file mode 100644 index 0000000..bbff051 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/mp4.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/mpeg.png b/lib/kcfinder/themes/default/img/files/small/mpeg.png new file mode 100644 index 0000000..bbff051 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/mpeg.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/mpg.png b/lib/kcfinder/themes/default/img/files/small/mpg.png new file mode 100644 index 0000000..bbff051 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/mpg.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/nfo.png b/lib/kcfinder/themes/default/img/files/small/nfo.png new file mode 100644 index 0000000..d904593 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/nfo.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/nrg.png b/lib/kcfinder/themes/default/img/files/small/nrg.png new file mode 100644 index 0000000..4e8d91d Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/nrg.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/ogg.png b/lib/kcfinder/themes/default/img/files/small/ogg.png new file mode 100644 index 0000000..017b00d Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/ogg.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/pdf.png b/lib/kcfinder/themes/default/img/files/small/pdf.png new file mode 100644 index 0000000..9498f0f Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/pdf.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/php.png b/lib/kcfinder/themes/default/img/files/small/php.png new file mode 100644 index 0000000..d73934b Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/php.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/phps.png b/lib/kcfinder/themes/default/img/files/small/phps.png new file mode 100644 index 0000000..d73934b Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/phps.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/pl.png b/lib/kcfinder/themes/default/img/files/small/pl.png new file mode 100644 index 0000000..d904593 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/pl.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/pm.png b/lib/kcfinder/themes/default/img/files/small/pm.png new file mode 100644 index 0000000..d904593 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/pm.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/png.png b/lib/kcfinder/themes/default/img/files/small/png.png new file mode 100644 index 0000000..638dee6 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/png.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/ppt.png b/lib/kcfinder/themes/default/img/files/small/ppt.png new file mode 100644 index 0000000..bdccbb6 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/ppt.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/pptx.png b/lib/kcfinder/themes/default/img/files/small/pptx.png new file mode 100644 index 0000000..bdccbb6 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/pptx.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/psd.png b/lib/kcfinder/themes/default/img/files/small/psd.png new file mode 100644 index 0000000..638dee6 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/psd.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/qt.png b/lib/kcfinder/themes/default/img/files/small/qt.png new file mode 100644 index 0000000..bbff051 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/qt.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/rar.png b/lib/kcfinder/themes/default/img/files/small/rar.png new file mode 100644 index 0000000..305f01b Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/rar.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/rpm.png b/lib/kcfinder/themes/default/img/files/small/rpm.png new file mode 100644 index 0000000..305f01b Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/rpm.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/rtf.png b/lib/kcfinder/themes/default/img/files/small/rtf.png new file mode 100644 index 0000000..d904593 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/rtf.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/sh.png b/lib/kcfinder/themes/default/img/files/small/sh.png new file mode 100644 index 0000000..7b87884 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/sh.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/sql.png b/lib/kcfinder/themes/default/img/files/small/sql.png new file mode 100644 index 0000000..5665b63 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/sql.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/srt.png b/lib/kcfinder/themes/default/img/files/small/srt.png new file mode 100644 index 0000000..d904593 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/srt.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/sub.png b/lib/kcfinder/themes/default/img/files/small/sub.png new file mode 100644 index 0000000..d904593 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/sub.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/swf.png b/lib/kcfinder/themes/default/img/files/small/swf.png new file mode 100644 index 0000000..80e05a3 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/swf.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/tgz.png b/lib/kcfinder/themes/default/img/files/small/tgz.png new file mode 100644 index 0000000..305f01b Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/tgz.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/tif.png b/lib/kcfinder/themes/default/img/files/small/tif.png new file mode 100644 index 0000000..638dee6 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/tif.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/tiff.png b/lib/kcfinder/themes/default/img/files/small/tiff.png new file mode 100644 index 0000000..638dee6 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/tiff.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/torrent.png b/lib/kcfinder/themes/default/img/files/small/torrent.png new file mode 100644 index 0000000..55c04aa Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/torrent.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/ttf.png b/lib/kcfinder/themes/default/img/files/small/ttf.png new file mode 100644 index 0000000..ed3e0f6 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/ttf.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/txt.png b/lib/kcfinder/themes/default/img/files/small/txt.png new file mode 100644 index 0000000..d904593 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/txt.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/wav.png b/lib/kcfinder/themes/default/img/files/small/wav.png new file mode 100644 index 0000000..017b00d Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/wav.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/wma.png b/lib/kcfinder/themes/default/img/files/small/wma.png new file mode 100644 index 0000000..017b00d Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/wma.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/xls.png b/lib/kcfinder/themes/default/img/files/small/xls.png new file mode 100644 index 0000000..573d141 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/xls.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/xlsx.png b/lib/kcfinder/themes/default/img/files/small/xlsx.png new file mode 100644 index 0000000..573d141 Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/xlsx.png differ diff --git a/lib/kcfinder/themes/default/img/files/small/zip.png b/lib/kcfinder/themes/default/img/files/small/zip.png new file mode 100644 index 0000000..305f01b Binary files /dev/null and b/lib/kcfinder/themes/default/img/files/small/zip.png differ diff --git a/lib/kcfinder/themes/default/img/icons/about.png b/lib/kcfinder/themes/default/img/icons/about.png new file mode 100644 index 0000000..12cd1ae Binary files /dev/null and b/lib/kcfinder/themes/default/img/icons/about.png differ diff --git a/lib/kcfinder/themes/default/img/icons/clipboard-add.png b/lib/kcfinder/themes/default/img/icons/clipboard-add.png new file mode 100644 index 0000000..d5eac9b Binary files /dev/null and b/lib/kcfinder/themes/default/img/icons/clipboard-add.png differ diff --git a/lib/kcfinder/themes/default/img/icons/clipboard-clear.png b/lib/kcfinder/themes/default/img/icons/clipboard-clear.png new file mode 100644 index 0000000..dcce0b6 Binary files /dev/null and b/lib/kcfinder/themes/default/img/icons/clipboard-clear.png differ diff --git a/lib/kcfinder/themes/default/img/icons/clipboard.png b/lib/kcfinder/themes/default/img/icons/clipboard.png new file mode 100644 index 0000000..779ad58 Binary files /dev/null and b/lib/kcfinder/themes/default/img/icons/clipboard.png differ diff --git a/lib/kcfinder/themes/default/img/icons/copy.png b/lib/kcfinder/themes/default/img/icons/copy.png new file mode 100644 index 0000000..a9f31a2 Binary files /dev/null and b/lib/kcfinder/themes/default/img/icons/copy.png differ diff --git a/lib/kcfinder/themes/default/img/icons/delete.png b/lib/kcfinder/themes/default/img/icons/delete.png new file mode 100644 index 0000000..1514d51 Binary files /dev/null and b/lib/kcfinder/themes/default/img/icons/delete.png differ diff --git a/lib/kcfinder/themes/default/img/icons/download.png b/lib/kcfinder/themes/default/img/icons/download.png new file mode 100644 index 0000000..260ac88 Binary files /dev/null and b/lib/kcfinder/themes/default/img/icons/download.png differ diff --git a/lib/kcfinder/themes/default/img/icons/folder-new.png b/lib/kcfinder/themes/default/img/icons/folder-new.png new file mode 100644 index 0000000..529fe8f Binary files /dev/null and b/lib/kcfinder/themes/default/img/icons/folder-new.png differ diff --git a/lib/kcfinder/themes/default/img/icons/maximize.png b/lib/kcfinder/themes/default/img/icons/maximize.png new file mode 100644 index 0000000..d41fc7e Binary files /dev/null and b/lib/kcfinder/themes/default/img/icons/maximize.png differ diff --git a/lib/kcfinder/themes/default/img/icons/move.png b/lib/kcfinder/themes/default/img/icons/move.png new file mode 100644 index 0000000..7e62a92 Binary files /dev/null and b/lib/kcfinder/themes/default/img/icons/move.png differ diff --git a/lib/kcfinder/themes/default/img/icons/refresh.png b/lib/kcfinder/themes/default/img/icons/refresh.png new file mode 100644 index 0000000..aa65210 Binary files /dev/null and b/lib/kcfinder/themes/default/img/icons/refresh.png differ diff --git a/lib/kcfinder/themes/default/img/icons/rename.png b/lib/kcfinder/themes/default/img/icons/rename.png new file mode 100644 index 0000000..4e3688e Binary files /dev/null and b/lib/kcfinder/themes/default/img/icons/rename.png differ diff --git a/lib/kcfinder/themes/default/img/icons/select.png b/lib/kcfinder/themes/default/img/icons/select.png new file mode 100644 index 0000000..a9925a0 Binary files /dev/null and b/lib/kcfinder/themes/default/img/icons/select.png differ diff --git a/lib/kcfinder/themes/default/img/icons/settings.png b/lib/kcfinder/themes/default/img/icons/settings.png new file mode 100644 index 0000000..5c8213f Binary files /dev/null and b/lib/kcfinder/themes/default/img/icons/settings.png differ diff --git a/lib/kcfinder/themes/default/img/icons/upload.png b/lib/kcfinder/themes/default/img/icons/upload.png new file mode 100644 index 0000000..f4b6d51 Binary files /dev/null and b/lib/kcfinder/themes/default/img/icons/upload.png differ diff --git a/lib/kcfinder/themes/default/img/icons/view.png b/lib/kcfinder/themes/default/img/icons/view.png new file mode 100644 index 0000000..af4fe07 Binary files /dev/null and b/lib/kcfinder/themes/default/img/icons/view.png differ diff --git a/lib/kcfinder/themes/default/img/kcf_logo.png b/lib/kcfinder/themes/default/img/kcf_logo.png new file mode 100644 index 0000000..e829043 Binary files /dev/null and b/lib/kcfinder/themes/default/img/kcf_logo.png differ diff --git a/lib/kcfinder/themes/default/img/loading.gif b/lib/kcfinder/themes/default/img/loading.gif new file mode 100644 index 0000000..5f5cedc Binary files /dev/null and b/lib/kcfinder/themes/default/img/loading.gif differ diff --git a/lib/kcfinder/themes/default/img/tree/denied.png b/lib/kcfinder/themes/default/img/tree/denied.png new file mode 100644 index 0000000..07b93c1 Binary files /dev/null and b/lib/kcfinder/themes/default/img/tree/denied.png differ diff --git a/lib/kcfinder/themes/default/img/tree/folder.png b/lib/kcfinder/themes/default/img/tree/folder.png new file mode 100644 index 0000000..784e8fa Binary files /dev/null and b/lib/kcfinder/themes/default/img/tree/folder.png differ diff --git a/lib/kcfinder/themes/default/img/tree/minus.png b/lib/kcfinder/themes/default/img/tree/minus.png new file mode 100644 index 0000000..af617bb Binary files /dev/null and b/lib/kcfinder/themes/default/img/tree/minus.png differ diff --git a/lib/kcfinder/themes/default/img/tree/plus.png b/lib/kcfinder/themes/default/img/tree/plus.png new file mode 100644 index 0000000..897088b Binary files /dev/null and b/lib/kcfinder/themes/default/img/tree/plus.png differ diff --git a/lib/kcfinder/themes/default/img/ui-icons_black.png b/lib/kcfinder/themes/default/img/ui-icons_black.png new file mode 100644 index 0000000..d64e654 Binary files /dev/null and b/lib/kcfinder/themes/default/img/ui-icons_black.png differ diff --git a/lib/kcfinder/themes/default/img/ui-icons_blue.png b/lib/kcfinder/themes/default/img/ui-icons_blue.png new file mode 100644 index 0000000..33a3f3f Binary files /dev/null and b/lib/kcfinder/themes/default/img/ui-icons_blue.png differ diff --git a/lib/kcfinder/themes/default/img/ui-icons_white.png b/lib/kcfinder/themes/default/img/ui-icons_white.png new file mode 100644 index 0000000..cb9a9ae Binary files /dev/null and b/lib/kcfinder/themes/default/img/ui-icons_white.png differ diff --git a/lib/kcfinder/themes/default/init.js b/lib/kcfinder/themes/default/init.js new file mode 100644 index 0000000..5cc0b16 --- /dev/null +++ b/lib/kcfinder/themes/default/init.js @@ -0,0 +1,9 @@ +// Preload some images +$.each([ + "loading.gif", + "ui-icons_black.png", + "ui-icons_blue.png", + "ui-icons_white.png" +], function(i, img) { + new Image().src = "themes/default/img/" + img; +}); diff --git a/lib/kcfinder/themes/default/js.php b/lib/kcfinder/themes/default/js.php new file mode 100644 index 0000000..b60b450 --- /dev/null +++ b/lib/kcfinder/themes/default/js.php @@ -0,0 +1,10 @@ +minify("cache/theme_$theme.js"); diff --git a/lib/kcfinder/tpl/.htaccess b/lib/kcfinder/tpl/.htaccess new file mode 100644 index 0000000..7484f13 --- /dev/null +++ b/lib/kcfinder/tpl/.htaccess @@ -0,0 +1,4 @@ + +Order allow,deny +Deny from all + \ No newline at end of file diff --git a/lib/kcfinder/tpl/tpl_browser.php b/lib/kcfinder/tpl/tpl_browser.php new file mode 100644 index 0000000..536413b --- /dev/null +++ b/lib/kcfinder/tpl/tpl_browser.php @@ -0,0 +1,91 @@ + + + +KCFinder: /<?php echo $this->session['dir'] ?> + + + + + +
            + +
            +
            + +
            +
            +
            + + +
             
            +
            + + diff --git a/lib/kcfinder/tpl/tpl_css.php b/lib/kcfinder/tpl/tpl_css.php new file mode 100644 index 0000000..37df711 --- /dev/null +++ b/lib/kcfinder/tpl/tpl_css.php @@ -0,0 +1,6 @@ + + + diff --git a/lib/kcfinder/tpl/tpl_javascript.php b/lib/kcfinder/tpl/tpl_javascript.php new file mode 100644 index 0000000..208664f --- /dev/null +++ b/lib/kcfinder/tpl/tpl_javascript.php @@ -0,0 +1,39 @@ + + + +opener['name'] == "tinymce"): +?> + +config['theme']}/js.php")): +?> + + + diff --git a/lib/kcfinder/upload.php b/lib/kcfinder/upload.php new file mode 100644 index 0000000..5a86e60 --- /dev/null +++ b/lib/kcfinder/upload.php @@ -0,0 +1,18 @@ + + * @copyright 2010-2014 KCFinder Project + * @license http://opensource.org/licenses/GPL-3.0 GPLv3 + * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3 + * @link http://kcfinder.sunhater.com + */ + +require "core/bootstrap.php"; +$uploader = "kcfinder\\uploader"; // To execute core/bootstrap.php on older +$uploader = new $uploader(); // PHP versions (even PHP 4) +$uploader->upload(); diff --git a/lib/phpexcel/PHPExcel.php b/lib/phpexcel/PHPExcel.php new file mode 100644 index 0000000..bf6f60f --- /dev/null +++ b/lib/phpexcel/PHPExcel.php @@ -0,0 +1,1139 @@ +_hasMacros; + } + + /** + * Define if a workbook has macros + * + * @param true|false + */ + public function setHasMacros($hasMacros=false){ + $this->_hasMacros=(bool)$hasMacros; + } + + /** + * Set the macros code + * + * @param binary string|null + */ + public function setMacrosCode($MacrosCode){ + $this->_macrosCode=$MacrosCode; + $this->setHasMacros(!is_null($MacrosCode)); + } + + /** + * Return the macros code + * + * @return binary|null + */ + public function getMacrosCode(){ + return $this->_macrosCode; + } + + /** + * Set the macros certificate + * + * @param binary|null + */ + public function setMacrosCertificate($Certificate=NULL){ + $this->_macrosCertificate=$Certificate; + } + + /** + * Is the project signed ? + * + * @return true|false + */ + public function hasMacrosCertificate(){ + return !is_null($this->_macrosCertificate); + } + + /** + * Return the macros certificate + * + * @return binary|null + */ + public function getMacrosCertificate(){ + return $this->_macrosCertificate; + } + + /** + * Remove all macros, certificate from spreadsheet + * + * @param none + * @return void + */ + public function discardMacros(){ + $this->_hasMacros=false; + $this->_macrosCode=NULL; + $this->_macrosCertificate=NULL; + } + + /** + * set ribbon XML data + * + */ + public function setRibbonXMLData($Target=NULL, $XMLData=NULL){ + if(!is_null($Target) && !is_null($XMLData)){ + $this->_ribbonXMLData=array('target'=>$Target, 'data'=>$XMLData); + }else{ + $this->_ribbonXMLData=NULL; + } + } + + /** + * retrieve ribbon XML Data + * + * return string|null|array + */ + public function getRibbonXMLData($What='all'){//we need some constants here... + $ReturnData=NULL; + $What=strtolower($What); + switch($What){ + case 'all': + $ReturnData=$this->_ribbonXMLData; + break; + case 'target': + case 'data': + if(is_array($this->_ribbonXMLData) && array_key_exists($What,$this->_ribbonXMLData)){ + $ReturnData=$this->_ribbonXMLData[$What]; + }//else $ReturnData stay at null + break; + }//default: $ReturnData at null + return $ReturnData; + } + + /** + * store binaries ribbon objects (pictures) + * + */ + public function setRibbonBinObjects($BinObjectsNames=NULL, $BinObjectsData=NULL){ + if(!is_null($BinObjectsNames) && !is_null($BinObjectsData)){ + $this->_ribbonBinObjects=array('names'=>$BinObjectsNames, 'data'=>$BinObjectsData); + }else{ + $this->_ribbonBinObjects=NULL; + } + } + /** + * return the extension of a filename. Internal use for a array_map callback (php<5.3 don't like lambda function) + * + */ + private function _getExtensionOnly($ThePath){ + return pathinfo($ThePath, PATHINFO_EXTENSION); + } + + /** + * retrieve Binaries Ribbon Objects + * + */ + public function getRibbonBinObjects($What='all'){ + $ReturnData=NULL; + $What=strtolower($What); + switch($What){ + case 'all': + return $this->_ribbonBinObjects; + break; + case 'names': + case 'data': + if(is_array($this->_ribbonBinObjects) && array_key_exists($What, $this->_ribbonBinObjects)){ + $ReturnData=$this->_ribbonBinObjects[$What]; + } + break; + case 'types': + if(is_array($this->_ribbonBinObjects) && array_key_exists('data', $this->_ribbonBinObjects) && is_array($this->_ribbonBinObjects['data'])){ + $tmpTypes=array_keys($this->_ribbonBinObjects['data']); + $ReturnData=array_unique(array_map(array($this,'_getExtensionOnly'), $tmpTypes)); + }else + $ReturnData=array();//the caller want an array... not null if empty + break; + } + return $ReturnData; + } + + /** + * This workbook have a custom UI ? + * + * @return true|false + */ + public function hasRibbon(){ + return !is_null($this->_ribbonXMLData); + } + + /** + * This workbook have additionnal object for the ribbon ? + * + * @return true|false + */ + public function hasRibbonBinObjects(){ + return !is_null($this->_ribbonBinObjects); + } + + /** + * Check if a sheet with a specified code name already exists + * + * @param string $pSheetCodeName Name of the worksheet to check + * @return boolean + */ + public function sheetCodeNameExists($pSheetCodeName) + { + return ($this->getSheetByCodeName($pSheetCodeName) !== NULL); + } + + /** + * Get sheet by code name. Warning : sheet don't have always a code name ! + * + * @param string $pName Sheet name + * @return PHPExcel_Worksheet + */ + public function getSheetByCodeName($pName = '') + { + $worksheetCount = count($this->_workSheetCollection); + for ($i = 0; $i < $worksheetCount; ++$i) { + if ($this->_workSheetCollection[$i]->getCodeName() == $pName) { + return $this->_workSheetCollection[$i]; + } + } + + return null; + } + + /** + * Create a new PHPExcel with one Worksheet + */ + public function __construct() + { + $this->_uniqueID = uniqid(); + $this->_calculationEngine = PHPExcel_Calculation::getInstance($this); + + // Initialise worksheet collection and add one worksheet + $this->_workSheetCollection = array(); + $this->_workSheetCollection[] = new PHPExcel_Worksheet($this); + $this->_activeSheetIndex = 0; + + // Create document properties + $this->_properties = new PHPExcel_DocumentProperties(); + + // Create document security + $this->_security = new PHPExcel_DocumentSecurity(); + + // Set named ranges + $this->_namedRanges = array(); + + // Create the cellXf supervisor + $this->_cellXfSupervisor = new PHPExcel_Style(true); + $this->_cellXfSupervisor->bindParent($this); + + // Create the default style + $this->addCellXf(new PHPExcel_Style); + $this->addCellStyleXf(new PHPExcel_Style); + } + + /** + * Code to execute when this worksheet is unset() + * + */ + public function __destruct() { + PHPExcel_Calculation::unsetInstance($this); + $this->disconnectWorksheets(); + } // function __destruct() + + /** + * Disconnect all worksheets from this PHPExcel workbook object, + * typically so that the PHPExcel object can be unset + * + */ + public function disconnectWorksheets() + { + $worksheet = NULL; + foreach($this->_workSheetCollection as $k => &$worksheet) { + $worksheet->disconnectCells(); + $this->_workSheetCollection[$k] = null; + } + unset($worksheet); + $this->_workSheetCollection = array(); + } + + /** + * Return the calculation engine for this worksheet + * + * @return PHPExcel_Calculation + */ + public function getCalculationEngine() + { + return $this->_calculationEngine; + } // function getCellCacheController() + + /** + * Get properties + * + * @return PHPExcel_DocumentProperties + */ + public function getProperties() + { + return $this->_properties; + } + + /** + * Set properties + * + * @param PHPExcel_DocumentProperties $pValue + */ + public function setProperties(PHPExcel_DocumentProperties $pValue) + { + $this->_properties = $pValue; + } + + /** + * Get security + * + * @return PHPExcel_DocumentSecurity + */ + public function getSecurity() + { + return $this->_security; + } + + /** + * Set security + * + * @param PHPExcel_DocumentSecurity $pValue + */ + public function setSecurity(PHPExcel_DocumentSecurity $pValue) + { + $this->_security = $pValue; + } + + /** + * Get active sheet + * + * @return PHPExcel_Worksheet + */ + public function getActiveSheet() + { + return $this->_workSheetCollection[$this->_activeSheetIndex]; + } + + /** + * Create sheet and add it to this workbook + * + * @param int|null $iSheetIndex Index where sheet should go (0,1,..., or null for last) + * @return PHPExcel_Worksheet + * @throws PHPExcel_Exception + */ + public function createSheet($iSheetIndex = NULL) + { + $newSheet = new PHPExcel_Worksheet($this); + $this->addSheet($newSheet, $iSheetIndex); + return $newSheet; + } + + /** + * Check if a sheet with a specified name already exists + * + * @param string $pSheetName Name of the worksheet to check + * @return boolean + */ + public function sheetNameExists($pSheetName) + { + return ($this->getSheetByName($pSheetName) !== NULL); + } + + /** + * Add sheet + * + * @param PHPExcel_Worksheet $pSheet + * @param int|null $iSheetIndex Index where sheet should go (0,1,..., or null for last) + * @return PHPExcel_Worksheet + * @throws PHPExcel_Exception + */ + public function addSheet(PHPExcel_Worksheet $pSheet, $iSheetIndex = NULL) + { + if ($this->sheetNameExists($pSheet->getTitle())) { + throw new PHPExcel_Exception( + "Workbook already contains a worksheet named '{$pSheet->getTitle()}'. Rename this worksheet first." + ); + } + + if($iSheetIndex === NULL) { + if ($this->_activeSheetIndex < 0) { + $this->_activeSheetIndex = 0; + } + $this->_workSheetCollection[] = $pSheet; + } else { + // Insert the sheet at the requested index + array_splice( + $this->_workSheetCollection, + $iSheetIndex, + 0, + array($pSheet) + ); + + // Adjust active sheet index if necessary + if ($this->_activeSheetIndex >= $iSheetIndex) { + ++$this->_activeSheetIndex; + } + } + + if ($pSheet->getParent() === null) { + $pSheet->rebindParent($this); + } + + return $pSheet; + } + + /** + * Remove sheet by index + * + * @param int $pIndex Active sheet index + * @throws PHPExcel_Exception + */ + public function removeSheetByIndex($pIndex = 0) + { + + $numSheets = count($this->_workSheetCollection); + + if ($pIndex > $numSheets - 1) { + throw new PHPExcel_Exception( + "You tried to remove a sheet by the out of bounds index: {$pIndex}. The actual number of sheets is {$numSheets}." + ); + } else { + array_splice($this->_workSheetCollection, $pIndex, 1); + } + // Adjust active sheet index if necessary + if (($this->_activeSheetIndex >= $pIndex) && + ($pIndex > count($this->_workSheetCollection) - 1)) { + --$this->_activeSheetIndex; + } + + } + + /** + * Get sheet by index + * + * @param int $pIndex Sheet index + * @return PHPExcel_Worksheet + * @throws PHPExcel_Exception + */ + public function getSheet($pIndex = 0) + { + + $numSheets = count($this->_workSheetCollection); + + if ($pIndex > $numSheets - 1) { + throw new PHPExcel_Exception( + "Your requested sheet index: {$pIndex} is out of bounds. The actual number of sheets is {$numSheets}." + ); + } else { + return $this->_workSheetCollection[$pIndex]; + } + } + + /** + * Get all sheets + * + * @return PHPExcel_Worksheet[] + */ + public function getAllSheets() + { + return $this->_workSheetCollection; + } + + /** + * Get sheet by name + * + * @param string $pName Sheet name + * @return PHPExcel_Worksheet + */ + public function getSheetByName($pName = '') + { + $worksheetCount = count($this->_workSheetCollection); + for ($i = 0; $i < $worksheetCount; ++$i) { + if ($this->_workSheetCollection[$i]->getTitle() === $pName) { + return $this->_workSheetCollection[$i]; + } + } + + return NULL; + } + + /** + * Get index for sheet + * + * @param PHPExcel_Worksheet $pSheet + * @return Sheet index + * @throws PHPExcel_Exception + */ + public function getIndex(PHPExcel_Worksheet $pSheet) + { + foreach ($this->_workSheetCollection as $key => $value) { + if ($value->getHashCode() == $pSheet->getHashCode()) { + return $key; + } + } + + throw new PHPExcel_Exception("Sheet does not exist."); + } + + /** + * Set index for sheet by sheet name. + * + * @param string $sheetName Sheet name to modify index for + * @param int $newIndex New index for the sheet + * @return New sheet index + * @throws PHPExcel_Exception + */ + public function setIndexByName($sheetName, $newIndex) + { + $oldIndex = $this->getIndex($this->getSheetByName($sheetName)); + $pSheet = array_splice( + $this->_workSheetCollection, + $oldIndex, + 1 + ); + array_splice( + $this->_workSheetCollection, + $newIndex, + 0, + $pSheet + ); + return $newIndex; + } + + /** + * Get sheet count + * + * @return int + */ + public function getSheetCount() + { + return count($this->_workSheetCollection); + } + + /** + * Get active sheet index + * + * @return int Active sheet index + */ + public function getActiveSheetIndex() + { + return $this->_activeSheetIndex; + } + + /** + * Set active sheet index + * + * @param int $pIndex Active sheet index + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function setActiveSheetIndex($pIndex = 0) + { + $numSheets = count($this->_workSheetCollection); + + if ($pIndex > $numSheets - 1) { + throw new PHPExcel_Exception( + "You tried to set a sheet active by the out of bounds index: {$pIndex}. The actual number of sheets is {$numSheets}." + ); + } else { + $this->_activeSheetIndex = $pIndex; + } + return $this->getActiveSheet(); + } + + /** + * Set active sheet index by name + * + * @param string $pValue Sheet title + * @return PHPExcel_Worksheet + * @throws PHPExcel_Exception + */ + public function setActiveSheetIndexByName($pValue = '') + { + if (($worksheet = $this->getSheetByName($pValue)) instanceof PHPExcel_Worksheet) { + $this->setActiveSheetIndex($this->getIndex($worksheet)); + return $worksheet; + } + + throw new PHPExcel_Exception('Workbook does not contain sheet:' . $pValue); + } + + /** + * Get sheet names + * + * @return string[] + */ + public function getSheetNames() + { + $returnValue = array(); + $worksheetCount = $this->getSheetCount(); + for ($i = 0; $i < $worksheetCount; ++$i) { + $returnValue[] = $this->getSheet($i)->getTitle(); + } + + return $returnValue; + } + + /** + * Add external sheet + * + * @param PHPExcel_Worksheet $pSheet External sheet to add + * @param int|null $iSheetIndex Index where sheet should go (0,1,..., or null for last) + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function addExternalSheet(PHPExcel_Worksheet $pSheet, $iSheetIndex = null) { + if ($this->sheetNameExists($pSheet->getTitle())) { + throw new PHPExcel_Exception("Workbook already contains a worksheet named '{$pSheet->getTitle()}'. Rename the external sheet first."); + } + + // count how many cellXfs there are in this workbook currently, we will need this below + $countCellXfs = count($this->_cellXfCollection); + + // copy all the shared cellXfs from the external workbook and append them to the current + foreach ($pSheet->getParent()->getCellXfCollection() as $cellXf) { + $this->addCellXf(clone $cellXf); + } + + // move sheet to this workbook + $pSheet->rebindParent($this); + + // update the cellXfs + foreach ($pSheet->getCellCollection(false) as $cellID) { + $cell = $pSheet->getCell($cellID); + $cell->setXfIndex( $cell->getXfIndex() + $countCellXfs ); + } + + return $this->addSheet($pSheet, $iSheetIndex); + } + + /** + * Get named ranges + * + * @return PHPExcel_NamedRange[] + */ + public function getNamedRanges() { + return $this->_namedRanges; + } + + /** + * Add named range + * + * @param PHPExcel_NamedRange $namedRange + * @return PHPExcel + */ + public function addNamedRange(PHPExcel_NamedRange $namedRange) { + if ($namedRange->getScope() == null) { + // global scope + $this->_namedRanges[$namedRange->getName()] = $namedRange; + } else { + // local scope + $this->_namedRanges[$namedRange->getScope()->getTitle().'!'.$namedRange->getName()] = $namedRange; + } + return true; + } + + /** + * Get named range + * + * @param string $namedRange + * @param PHPExcel_Worksheet|null $pSheet Scope. Use null for global scope + * @return PHPExcel_NamedRange|null + */ + public function getNamedRange($namedRange, PHPExcel_Worksheet $pSheet = null) { + $returnValue = null; + + if ($namedRange != '' && ($namedRange !== NULL)) { + // first look for global defined name + if (isset($this->_namedRanges[$namedRange])) { + $returnValue = $this->_namedRanges[$namedRange]; + } + + // then look for local defined name (has priority over global defined name if both names exist) + if (($pSheet !== NULL) && isset($this->_namedRanges[$pSheet->getTitle() . '!' . $namedRange])) { + $returnValue = $this->_namedRanges[$pSheet->getTitle() . '!' . $namedRange]; + } + } + + return $returnValue; + } + + /** + * Remove named range + * + * @param string $namedRange + * @param PHPExcel_Worksheet|null $pSheet Scope: use null for global scope. + * @return PHPExcel + */ + public function removeNamedRange($namedRange, PHPExcel_Worksheet $pSheet = null) { + if ($pSheet === NULL) { + if (isset($this->_namedRanges[$namedRange])) { + unset($this->_namedRanges[$namedRange]); + } + } else { + if (isset($this->_namedRanges[$pSheet->getTitle() . '!' . $namedRange])) { + unset($this->_namedRanges[$pSheet->getTitle() . '!' . $namedRange]); + } + } + return $this; + } + + /** + * Get worksheet iterator + * + * @return PHPExcel_WorksheetIterator + */ + public function getWorksheetIterator() { + return new PHPExcel_WorksheetIterator($this); + } + + /** + * Copy workbook (!= clone!) + * + * @return PHPExcel + */ + public function copy() { + $copied = clone $this; + + $worksheetCount = count($this->_workSheetCollection); + for ($i = 0; $i < $worksheetCount; ++$i) { + $this->_workSheetCollection[$i] = $this->_workSheetCollection[$i]->copy(); + $this->_workSheetCollection[$i]->rebindParent($this); + } + + return $copied; + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + foreach($this as $key => $val) { + if (is_object($val) || (is_array($val))) { + $this->{$key} = unserialize(serialize($val)); + } + } + } + + /** + * Get the workbook collection of cellXfs + * + * @return PHPExcel_Style[] + */ + public function getCellXfCollection() + { + return $this->_cellXfCollection; + } + + /** + * Get cellXf by index + * + * @param int $pIndex + * @return PHPExcel_Style + */ + public function getCellXfByIndex($pIndex = 0) + { + return $this->_cellXfCollection[$pIndex]; + } + + /** + * Get cellXf by hash code + * + * @param string $pValue + * @return PHPExcel_Style|false + */ + public function getCellXfByHashCode($pValue = '') + { + foreach ($this->_cellXfCollection as $cellXf) { + if ($cellXf->getHashCode() == $pValue) { + return $cellXf; + } + } + return false; + } + + /** + * Check if style exists in style collection + * + * @param PHPExcel_Style $pCellStyle + * @return boolean + */ + public function cellXfExists($pCellStyle = null) + { + return in_array($pCellStyle, $this->_cellXfCollection, true); + } + + /** + * Get default style + * + * @return PHPExcel_Style + * @throws PHPExcel_Exception + */ + public function getDefaultStyle() + { + if (isset($this->_cellXfCollection[0])) { + return $this->_cellXfCollection[0]; + } + throw new PHPExcel_Exception('No default style found for this workbook'); + } + + /** + * Add a cellXf to the workbook + * + * @param PHPExcel_Style $style + */ + public function addCellXf(PHPExcel_Style $style) + { + $this->_cellXfCollection[] = $style; + $style->setIndex(count($this->_cellXfCollection) - 1); + } + + /** + * Remove cellXf by index. It is ensured that all cells get their xf index updated. + * + * @param int $pIndex Index to cellXf + * @throws PHPExcel_Exception + */ + public function removeCellXfByIndex($pIndex = 0) + { + if ($pIndex > count($this->_cellXfCollection) - 1) { + throw new PHPExcel_Exception("CellXf index is out of bounds."); + } else { + // first remove the cellXf + array_splice($this->_cellXfCollection, $pIndex, 1); + + // then update cellXf indexes for cells + foreach ($this->_workSheetCollection as $worksheet) { + foreach ($worksheet->getCellCollection(false) as $cellID) { + $cell = $worksheet->getCell($cellID); + $xfIndex = $cell->getXfIndex(); + if ($xfIndex > $pIndex ) { + // decrease xf index by 1 + $cell->setXfIndex($xfIndex - 1); + } else if ($xfIndex == $pIndex) { + // set to default xf index 0 + $cell->setXfIndex(0); + } + } + } + } + } + + /** + * Get the cellXf supervisor + * + * @return PHPExcel_Style + */ + public function getCellXfSupervisor() + { + return $this->_cellXfSupervisor; + } + + /** + * Get the workbook collection of cellStyleXfs + * + * @return PHPExcel_Style[] + */ + public function getCellStyleXfCollection() + { + return $this->_cellStyleXfCollection; + } + + /** + * Get cellStyleXf by index + * + * @param int $pIndex + * @return PHPExcel_Style + */ + public function getCellStyleXfByIndex($pIndex = 0) + { + return $this->_cellStyleXfCollection[$pIndex]; + } + + /** + * Get cellStyleXf by hash code + * + * @param string $pValue + * @return PHPExcel_Style|false + */ + public function getCellStyleXfByHashCode($pValue = '') + { + foreach ($this->_cellXfStyleCollection as $cellStyleXf) { + if ($cellStyleXf->getHashCode() == $pValue) { + return $cellStyleXf; + } + } + return false; + } + + /** + * Add a cellStyleXf to the workbook + * + * @param PHPExcel_Style $pStyle + */ + public function addCellStyleXf(PHPExcel_Style $pStyle) + { + $this->_cellStyleXfCollection[] = $pStyle; + $pStyle->setIndex(count($this->_cellStyleXfCollection) - 1); + } + + /** + * Remove cellStyleXf by index + * + * @param int $pIndex + * @throws PHPExcel_Exception + */ + public function removeCellStyleXfByIndex($pIndex = 0) + { + if ($pIndex > count($this->_cellStyleXfCollection) - 1) { + throw new PHPExcel_Exception("CellStyleXf index is out of bounds."); + } else { + array_splice($this->_cellStyleXfCollection, $pIndex, 1); + } + } + + /** + * Eliminate all unneeded cellXf and afterwards update the xfIndex for all cells + * and columns in the workbook + */ + public function garbageCollect() + { + // how many references are there to each cellXf ? + $countReferencesCellXf = array(); + foreach ($this->_cellXfCollection as $index => $cellXf) { + $countReferencesCellXf[$index] = 0; + } + + foreach ($this->getWorksheetIterator() as $sheet) { + + // from cells + foreach ($sheet->getCellCollection(false) as $cellID) { + $cell = $sheet->getCell($cellID); + ++$countReferencesCellXf[$cell->getXfIndex()]; + } + + // from row dimensions + foreach ($sheet->getRowDimensions() as $rowDimension) { + if ($rowDimension->getXfIndex() !== null) { + ++$countReferencesCellXf[$rowDimension->getXfIndex()]; + } + } + + // from column dimensions + foreach ($sheet->getColumnDimensions() as $columnDimension) { + ++$countReferencesCellXf[$columnDimension->getXfIndex()]; + } + } + + // remove cellXfs without references and create mapping so we can update xfIndex + // for all cells and columns + $countNeededCellXfs = 0; + foreach ($this->_cellXfCollection as $index => $cellXf) { + if ($countReferencesCellXf[$index] > 0 || $index == 0) { // we must never remove the first cellXf + ++$countNeededCellXfs; + } else { + unset($this->_cellXfCollection[$index]); + } + $map[$index] = $countNeededCellXfs - 1; + } + $this->_cellXfCollection = array_values($this->_cellXfCollection); + + // update the index for all cellXfs + foreach ($this->_cellXfCollection as $i => $cellXf) { + $cellXf->setIndex($i); + } + + // make sure there is always at least one cellXf (there should be) + if (empty($this->_cellXfCollection)) { + $this->_cellXfCollection[] = new PHPExcel_Style(); + } + + // update the xfIndex for all cells, row dimensions, column dimensions + foreach ($this->getWorksheetIterator() as $sheet) { + + // for all cells + foreach ($sheet->getCellCollection(false) as $cellID) { + $cell = $sheet->getCell($cellID); + $cell->setXfIndex( $map[$cell->getXfIndex()] ); + } + + // for all row dimensions + foreach ($sheet->getRowDimensions() as $rowDimension) { + if ($rowDimension->getXfIndex() !== null) { + $rowDimension->setXfIndex( $map[$rowDimension->getXfIndex()] ); + } + } + + // for all column dimensions + foreach ($sheet->getColumnDimensions() as $columnDimension) { + $columnDimension->setXfIndex( $map[$columnDimension->getXfIndex()] ); + } + + // also do garbage collection for all the sheets + $sheet->garbageCollect(); + } + } + + /** + * Return the unique ID value assigned to this spreadsheet workbook + * + * @return string + */ + public function getID() { + return $this->_uniqueID; + } + +} diff --git a/lib/phpexcel/PHPExcel/Autoloader.php b/lib/phpexcel/PHPExcel/Autoloader.php new file mode 100644 index 0000000..a36dfcc --- /dev/null +++ b/lib/phpexcel/PHPExcel/Autoloader.php @@ -0,0 +1,85 @@ +_currentCellIsDirty && !empty($this->_currentObjectID)) { + $this->_currentObject->detach(); + + if (!apc_store($this->_cachePrefix.$this->_currentObjectID.'.cache',serialize($this->_currentObject),$this->_cacheTime)) { + $this->__destruct(); + throw new PHPExcel_Exception('Failed to store cell '.$this->_currentObjectID.' in APC'); + } + $this->_currentCellIsDirty = false; + } + $this->_currentObjectID = $this->_currentObject = null; + } // function _storeData() + + + /** + * Add or Update a cell in cache identified by coordinate address + * + * @access public + * @param string $pCoord Coordinate address of the cell to update + * @param PHPExcel_Cell $cell Cell to update + * @return void + * @throws PHPExcel_Exception + */ + public function addCacheData($pCoord, PHPExcel_Cell $cell) { + if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) { + $this->_storeData(); + } + $this->_cellCache[$pCoord] = true; + + $this->_currentObjectID = $pCoord; + $this->_currentObject = $cell; + $this->_currentCellIsDirty = true; + + return $cell; + } // function addCacheData() + + + /** + * Is a value set in the current PHPExcel_CachedObjectStorage_ICache for an indexed cell? + * + * @access public + * @param string $pCoord Coordinate address of the cell to check + * @return void + * @return boolean + */ + public function isDataSet($pCoord) { + // Check if the requested entry is the current object, or exists in the cache + if (parent::isDataSet($pCoord)) { + if ($this->_currentObjectID == $pCoord) { + return true; + } + // Check if the requested entry still exists in apc + $success = apc_fetch($this->_cachePrefix.$pCoord.'.cache'); + if ($success === FALSE) { + // Entry no longer exists in APC, so clear it from the cache array + parent::deleteCacheData($pCoord); + throw new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in APC cache'); + } + return true; + } + return false; + } // function isDataSet() + + + /** + * Get cell at a specific coordinate + * + * @access public + * @param string $pCoord Coordinate of the cell + * @throws PHPExcel_Exception + * @return PHPExcel_Cell Cell that was found, or null if not found + */ + public function getCacheData($pCoord) { + if ($pCoord === $this->_currentObjectID) { + return $this->_currentObject; + } + $this->_storeData(); + + // Check if the entry that has been requested actually exists + if (parent::isDataSet($pCoord)) { + $obj = apc_fetch($this->_cachePrefix.$pCoord.'.cache'); + if ($obj === FALSE) { + // Entry no longer exists in APC, so clear it from the cache array + parent::deleteCacheData($pCoord); + throw new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in APC cache'); + } + } else { + // Return null if requested entry doesn't exist in cache + return null; + } + + // Set current entry to the requested entry + $this->_currentObjectID = $pCoord; + $this->_currentObject = unserialize($obj); + // Re-attach this as the cell's parent + $this->_currentObject->attach($this); + + // Return requested entry + return $this->_currentObject; + } // function getCacheData() + + + /** + * Get a list of all cell addresses currently held in cache + * + * @return array of string + */ + public function getCellList() { + if ($this->_currentObjectID !== null) { + $this->_storeData(); + } + + return parent::getCellList(); + } + + + /** + * Delete a cell in cache identified by coordinate address + * + * @access public + * @param string $pCoord Coordinate address of the cell to delete + * @throws PHPExcel_Exception + */ + public function deleteCacheData($pCoord) { + // Delete the entry from APC + apc_delete($this->_cachePrefix.$pCoord.'.cache'); + + // Delete the entry from our cell address array + parent::deleteCacheData($pCoord); + } // function deleteCacheData() + + + /** + * Clone the cell collection + * + * @access public + * @param PHPExcel_Worksheet $parent The new worksheet + * @throws PHPExcel_Exception + * @return void + */ + public function copyCellCollection(PHPExcel_Worksheet $parent) { + parent::copyCellCollection($parent); + // Get a new id for the new file name + $baseUnique = $this->_getUniqueID(); + $newCachePrefix = substr(md5($baseUnique),0,8).'.'; + $cacheList = $this->getCellList(); + foreach($cacheList as $cellID) { + if ($cellID != $this->_currentObjectID) { + $obj = apc_fetch($this->_cachePrefix.$cellID.'.cache'); + if ($obj === FALSE) { + // Entry no longer exists in APC, so clear it from the cache array + parent::deleteCacheData($cellID); + throw new PHPExcel_Exception('Cell entry '.$cellID.' no longer exists in APC'); + } + if (!apc_store($newCachePrefix.$cellID.'.cache',$obj,$this->_cacheTime)) { + $this->__destruct(); + throw new PHPExcel_Exception('Failed to store cell '.$cellID.' in APC'); + } + } + } + $this->_cachePrefix = $newCachePrefix; + } // function copyCellCollection() + + + /** + * Clear the cell collection and disconnect from our parent + * + * @return void + */ + public function unsetWorksheetCells() { + if ($this->_currentObject !== NULL) { + $this->_currentObject->detach(); + $this->_currentObject = $this->_currentObjectID = null; + } + + // Flush the APC cache + $this->__destruct(); + + $this->_cellCache = array(); + + // detach ourself from the worksheet, so that it can then delete this object successfully + $this->_parent = null; + } // function unsetWorksheetCells() + + + /** + * Initialise this new cell collection + * + * @param PHPExcel_Worksheet $parent The worksheet for this cell collection + * @param array of mixed $arguments Additional initialisation arguments + */ + public function __construct(PHPExcel_Worksheet $parent, $arguments) { + $cacheTime = (isset($arguments['cacheTime'])) ? $arguments['cacheTime'] : 600; + + if ($this->_cachePrefix === NULL) { + $baseUnique = $this->_getUniqueID(); + $this->_cachePrefix = substr(md5($baseUnique),0,8).'.'; + $this->_cacheTime = $cacheTime; + + parent::__construct($parent); + } + } // function __construct() + + + /** + * Destroy this cell collection + */ + public function __destruct() { + $cacheList = $this->getCellList(); + foreach($cacheList as $cellID) { + apc_delete($this->_cachePrefix.$cellID.'.cache'); + } + } // function __destruct() + + + /** + * Identify whether the caching method is currently available + * Some methods are dependent on the availability of certain extensions being enabled in the PHP build + * + * @return boolean + */ + public static function cacheMethodIsAvailable() { + if (!function_exists('apc_store')) { + return FALSE; + } + if (apc_sma_info() === FALSE) { + return FALSE; + } + + return TRUE; + } + +} diff --git a/lib/phpexcel/PHPExcel/CachedObjectStorage/CacheBase.php b/lib/phpexcel/PHPExcel/CachedObjectStorage/CacheBase.php new file mode 100644 index 0000000..db3a0d8 --- /dev/null +++ b/lib/phpexcel/PHPExcel/CachedObjectStorage/CacheBase.php @@ -0,0 +1,347 @@ +_parent = $parent; + } // function __construct() + + + /** + * Return the parent worksheet for this cell collection + * + * @return PHPExcel_Worksheet + */ + public function getParent() + { + return $this->_parent; + } + + /** + * Is a value set in the current PHPExcel_CachedObjectStorage_ICache for an indexed cell? + * + * @param string $pCoord Coordinate address of the cell to check + * @return boolean + */ + public function isDataSet($pCoord) { + if ($pCoord === $this->_currentObjectID) { + return true; + } + // Check if the requested entry exists in the cache + return isset($this->_cellCache[$pCoord]); + } // function isDataSet() + + + /** + * Move a cell object from one address to another + * + * @param string $fromAddress Current address of the cell to move + * @param string $toAddress Destination address of the cell to move + * @return boolean + */ + public function moveCell($fromAddress, $toAddress) { + if ($fromAddress === $this->_currentObjectID) { + $this->_currentObjectID = $toAddress; + } + $this->_currentCellIsDirty = true; + if (isset($this->_cellCache[$fromAddress])) { + $this->_cellCache[$toAddress] = &$this->_cellCache[$fromAddress]; + unset($this->_cellCache[$fromAddress]); + } + + return TRUE; + } // function moveCell() + + + /** + * Add or Update a cell in cache + * + * @param PHPExcel_Cell $cell Cell to update + * @return void + * @throws PHPExcel_Exception + */ + public function updateCacheData(PHPExcel_Cell $cell) { + return $this->addCacheData($cell->getCoordinate(),$cell); + } // function updateCacheData() + + + /** + * Delete a cell in cache identified by coordinate address + * + * @param string $pCoord Coordinate address of the cell to delete + * @throws PHPExcel_Exception + */ + public function deleteCacheData($pCoord) { + if ($pCoord === $this->_currentObjectID) { + $this->_currentObject->detach(); + $this->_currentObjectID = $this->_currentObject = null; + } + + if (is_object($this->_cellCache[$pCoord])) { + $this->_cellCache[$pCoord]->detach(); + unset($this->_cellCache[$pCoord]); + } + $this->_currentCellIsDirty = false; + } // function deleteCacheData() + + + /** + * Get a list of all cell addresses currently held in cache + * + * @return array of string + */ + public function getCellList() { + return array_keys($this->_cellCache); + } // function getCellList() + + + /** + * Sort the list of all cell addresses currently held in cache by row and column + * + * @return void + */ + public function getSortedCellList() { + $sortKeys = array(); + foreach ($this->getCellList() as $coord) { + sscanf($coord,'%[A-Z]%d', $column, $row); + $sortKeys[sprintf('%09d%3s',$row,$column)] = $coord; + } + ksort($sortKeys); + + return array_values($sortKeys); + } // function sortCellList() + + + + /** + * Get highest worksheet column and highest row that have cell records + * + * @return array Highest column name and highest row number + */ + public function getHighestRowAndColumn() + { + // Lookup highest column and highest row + $col = array('A' => '1A'); + $row = array(1); + foreach ($this->getCellList() as $coord) { + sscanf($coord,'%[A-Z]%d', $c, $r); + $row[$r] = $r; + $col[$c] = strlen($c).$c; + } + if (!empty($row)) { + // Determine highest column and row + $highestRow = max($row); + $highestColumn = substr(max($col),1); + } + + return array( 'row' => $highestRow, + 'column' => $highestColumn + ); + } + + + /** + * Return the cell address of the currently active cell object + * + * @return string + */ + public function getCurrentAddress() + { + return $this->_currentObjectID; + } + + /** + * Return the column address of the currently active cell object + * + * @return string + */ + public function getCurrentColumn() + { + sscanf($this->_currentObjectID, '%[A-Z]%d', $column, $row); + return $column; + } + + /** + * Return the row address of the currently active cell object + * + * @return string + */ + public function getCurrentRow() + { + sscanf($this->_currentObjectID, '%[A-Z]%d', $column, $row); + return $row; + } + + /** + * Get highest worksheet column + * + * @param string $row Return the highest column for the specified row, + * or the highest column of any row if no row number is passed + * @return string Highest column name + */ + public function getHighestColumn($row = null) + { + if ($row == null) { + $colRow = $this->getHighestRowAndColumn(); + return $colRow['column']; + } + + $columnList = array(1); + foreach ($this->getCellList() as $coord) { + sscanf($coord,'%[A-Z]%d', $c, $r); + if ($r != $row) { + continue; + } + $columnList[] = PHPExcel_Cell::columnIndexFromString($c); + } + return PHPExcel_Cell::stringFromColumnIndex(max($columnList) - 1); + } + + /** + * Get highest worksheet row + * + * @param string $column Return the highest row for the specified column, + * or the highest row of any column if no column letter is passed + * @return int Highest row number + */ + public function getHighestRow($column = null) + { + if ($column == null) { + $colRow = $this->getHighestRowAndColumn(); + return $colRow['row']; + } + + $rowList = array(0); + foreach ($this->getCellList() as $coord) { + sscanf($coord,'%[A-Z]%d', $c, $r); + if ($c != $column) { + continue; + } + $rowList[] = $r; + } + + return max($rowList); + } + + + /** + * Generate a unique ID for cache referencing + * + * @return string Unique Reference + */ + protected function _getUniqueID() { + if (function_exists('posix_getpid')) { + $baseUnique = posix_getpid(); + } else { + $baseUnique = mt_rand(); + } + return uniqid($baseUnique,true); + } + + /** + * Clone the cell collection + * + * @param PHPExcel_Worksheet $parent The new worksheet + * @return void + */ + public function copyCellCollection(PHPExcel_Worksheet $parent) { + $this->_currentCellIsDirty; + $this->_storeData(); + + $this->_parent = $parent; + if (($this->_currentObject !== NULL) && (is_object($this->_currentObject))) { + $this->_currentObject->attach($this); + } + } // function copyCellCollection() + + + /** + * Identify whether the caching method is currently available + * Some methods are dependent on the availability of certain extensions being enabled in the PHP build + * + * @return boolean + */ + public static function cacheMethodIsAvailable() { + return true; + } + +} diff --git a/lib/phpexcel/PHPExcel/CachedObjectStorage/DiscISAM.php b/lib/phpexcel/PHPExcel/CachedObjectStorage/DiscISAM.php new file mode 100644 index 0000000..5e9e382 --- /dev/null +++ b/lib/phpexcel/PHPExcel/CachedObjectStorage/DiscISAM.php @@ -0,0 +1,219 @@ +_currentCellIsDirty && !empty($this->_currentObjectID)) { + $this->_currentObject->detach(); + + fseek($this->_fileHandle,0,SEEK_END); + $offset = ftell($this->_fileHandle); + fwrite($this->_fileHandle, serialize($this->_currentObject)); + $this->_cellCache[$this->_currentObjectID] = array('ptr' => $offset, + 'sz' => ftell($this->_fileHandle) - $offset + ); + $this->_currentCellIsDirty = false; + } + $this->_currentObjectID = $this->_currentObject = null; + } // function _storeData() + + + /** + * Add or Update a cell in cache identified by coordinate address + * + * @param string $pCoord Coordinate address of the cell to update + * @param PHPExcel_Cell $cell Cell to update + * @return void + * @throws PHPExcel_Exception + */ + public function addCacheData($pCoord, PHPExcel_Cell $cell) { + if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) { + $this->_storeData(); + } + + $this->_currentObjectID = $pCoord; + $this->_currentObject = $cell; + $this->_currentCellIsDirty = true; + + return $cell; + } // function addCacheData() + + + /** + * Get cell at a specific coordinate + * + * @param string $pCoord Coordinate of the cell + * @throws PHPExcel_Exception + * @return PHPExcel_Cell Cell that was found, or null if not found + */ + public function getCacheData($pCoord) { + if ($pCoord === $this->_currentObjectID) { + return $this->_currentObject; + } + $this->_storeData(); + + // Check if the entry that has been requested actually exists + if (!isset($this->_cellCache[$pCoord])) { + // Return null if requested entry doesn't exist in cache + return null; + } + + // Set current entry to the requested entry + $this->_currentObjectID = $pCoord; + fseek($this->_fileHandle,$this->_cellCache[$pCoord]['ptr']); + $this->_currentObject = unserialize(fread($this->_fileHandle,$this->_cellCache[$pCoord]['sz'])); + // Re-attach this as the cell's parent + $this->_currentObject->attach($this); + + // Return requested entry + return $this->_currentObject; + } // function getCacheData() + + + /** + * Get a list of all cell addresses currently held in cache + * + * @return array of string + */ + public function getCellList() { + if ($this->_currentObjectID !== null) { + $this->_storeData(); + } + + return parent::getCellList(); + } + + + /** + * Clone the cell collection + * + * @param PHPExcel_Worksheet $parent The new worksheet + * @return void + */ + public function copyCellCollection(PHPExcel_Worksheet $parent) { + parent::copyCellCollection($parent); + // Get a new id for the new file name + $baseUnique = $this->_getUniqueID(); + $newFileName = $this->_cacheDirectory.'/PHPExcel.'.$baseUnique.'.cache'; + // Copy the existing cell cache file + copy ($this->_fileName,$newFileName); + $this->_fileName = $newFileName; + // Open the copied cell cache file + $this->_fileHandle = fopen($this->_fileName,'a+'); + } // function copyCellCollection() + + + /** + * Clear the cell collection and disconnect from our parent + * + * @return void + */ + public function unsetWorksheetCells() { + if(!is_null($this->_currentObject)) { + $this->_currentObject->detach(); + $this->_currentObject = $this->_currentObjectID = null; + } + $this->_cellCache = array(); + + // detach ourself from the worksheet, so that it can then delete this object successfully + $this->_parent = null; + + // Close down the temporary cache file + $this->__destruct(); + } // function unsetWorksheetCells() + + + /** + * Initialise this new cell collection + * + * @param PHPExcel_Worksheet $parent The worksheet for this cell collection + * @param array of mixed $arguments Additional initialisation arguments + */ + public function __construct(PHPExcel_Worksheet $parent, $arguments) { + $this->_cacheDirectory = ((isset($arguments['dir'])) && ($arguments['dir'] !== NULL)) + ? $arguments['dir'] + : PHPExcel_Shared_File::sys_get_temp_dir(); + + parent::__construct($parent); + if (is_null($this->_fileHandle)) { + $baseUnique = $this->_getUniqueID(); + $this->_fileName = $this->_cacheDirectory.'/PHPExcel.'.$baseUnique.'.cache'; + $this->_fileHandle = fopen($this->_fileName,'a+'); + } + } // function __construct() + + + /** + * Destroy this cell collection + */ + public function __destruct() { + if (!is_null($this->_fileHandle)) { + fclose($this->_fileHandle); + unlink($this->_fileName); + } + $this->_fileHandle = null; + } // function __destruct() + +} diff --git a/lib/phpexcel/PHPExcel/CachedObjectStorage/ICache.php b/lib/phpexcel/PHPExcel/CachedObjectStorage/ICache.php new file mode 100644 index 0000000..c3f2c14 --- /dev/null +++ b/lib/phpexcel/PHPExcel/CachedObjectStorage/ICache.php @@ -0,0 +1,112 @@ +_currentCellIsDirty && !empty($this->_currentObjectID)) { + $this->_currentObject->detach(); + + $this->_cellCache[$this->_currentObjectID] = igbinary_serialize($this->_currentObject); + $this->_currentCellIsDirty = false; + } + $this->_currentObjectID = $this->_currentObject = null; + } // function _storeData() + + + /** + * Add or Update a cell in cache identified by coordinate address + * + * @param string $pCoord Coordinate address of the cell to update + * @param PHPExcel_Cell $cell Cell to update + * @return void + * @throws PHPExcel_Exception + */ + public function addCacheData($pCoord, PHPExcel_Cell $cell) { + if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) { + $this->_storeData(); + } + + $this->_currentObjectID = $pCoord; + $this->_currentObject = $cell; + $this->_currentCellIsDirty = true; + + return $cell; + } // function addCacheData() + + + /** + * Get cell at a specific coordinate + * + * @param string $pCoord Coordinate of the cell + * @throws PHPExcel_Exception + * @return PHPExcel_Cell Cell that was found, or null if not found + */ + public function getCacheData($pCoord) { + if ($pCoord === $this->_currentObjectID) { + return $this->_currentObject; + } + $this->_storeData(); + + // Check if the entry that has been requested actually exists + if (!isset($this->_cellCache[$pCoord])) { + // Return null if requested entry doesn't exist in cache + return null; + } + + // Set current entry to the requested entry + $this->_currentObjectID = $pCoord; + $this->_currentObject = igbinary_unserialize($this->_cellCache[$pCoord]); + // Re-attach this as the cell's parent + $this->_currentObject->attach($this); + + // Return requested entry + return $this->_currentObject; + } // function getCacheData() + + + /** + * Get a list of all cell addresses currently held in cache + * + * @return array of string + */ + public function getCellList() { + if ($this->_currentObjectID !== null) { + $this->_storeData(); + } + + return parent::getCellList(); + } + + + /** + * Clear the cell collection and disconnect from our parent + * + * @return void + */ + public function unsetWorksheetCells() { + if(!is_null($this->_currentObject)) { + $this->_currentObject->detach(); + $this->_currentObject = $this->_currentObjectID = null; + } + $this->_cellCache = array(); + + // detach ourself from the worksheet, so that it can then delete this object successfully + $this->_parent = null; + } // function unsetWorksheetCells() + + + /** + * Identify whether the caching method is currently available + * Some methods are dependent on the availability of certain extensions being enabled in the PHP build + * + * @return boolean + */ + public static function cacheMethodIsAvailable() { + if (!function_exists('igbinary_serialize')) { + return false; + } + + return true; + } + +} diff --git a/lib/phpexcel/PHPExcel/CachedObjectStorage/Memcache.php b/lib/phpexcel/PHPExcel/CachedObjectStorage/Memcache.php new file mode 100644 index 0000000..1becd2b --- /dev/null +++ b/lib/phpexcel/PHPExcel/CachedObjectStorage/Memcache.php @@ -0,0 +1,312 @@ +_currentCellIsDirty && !empty($this->_currentObjectID)) { + $this->_currentObject->detach(); + + $obj = serialize($this->_currentObject); + if (!$this->_memcache->replace($this->_cachePrefix.$this->_currentObjectID.'.cache',$obj,NULL,$this->_cacheTime)) { + if (!$this->_memcache->add($this->_cachePrefix.$this->_currentObjectID.'.cache',$obj,NULL,$this->_cacheTime)) { + $this->__destruct(); + throw new PHPExcel_Exception('Failed to store cell '.$this->_currentObjectID.' in MemCache'); + } + } + $this->_currentCellIsDirty = false; + } + $this->_currentObjectID = $this->_currentObject = null; + } // function _storeData() + + + /** + * Add or Update a cell in cache identified by coordinate address + * + * @param string $pCoord Coordinate address of the cell to update + * @param PHPExcel_Cell $cell Cell to update + * @return void + * @throws PHPExcel_Exception + */ + public function addCacheData($pCoord, PHPExcel_Cell $cell) { + if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) { + $this->_storeData(); + } + $this->_cellCache[$pCoord] = true; + + $this->_currentObjectID = $pCoord; + $this->_currentObject = $cell; + $this->_currentCellIsDirty = true; + + return $cell; + } // function addCacheData() + + + /** + * Is a value set in the current PHPExcel_CachedObjectStorage_ICache for an indexed cell? + * + * @param string $pCoord Coordinate address of the cell to check + * @return void + * @return boolean + */ + public function isDataSet($pCoord) { + // Check if the requested entry is the current object, or exists in the cache + if (parent::isDataSet($pCoord)) { + if ($this->_currentObjectID == $pCoord) { + return true; + } + // Check if the requested entry still exists in Memcache + $success = $this->_memcache->get($this->_cachePrefix.$pCoord.'.cache'); + if ($success === false) { + // Entry no longer exists in Memcache, so clear it from the cache array + parent::deleteCacheData($pCoord); + throw new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in MemCache'); + } + return true; + } + return false; + } // function isDataSet() + + + /** + * Get cell at a specific coordinate + * + * @param string $pCoord Coordinate of the cell + * @throws PHPExcel_Exception + * @return PHPExcel_Cell Cell that was found, or null if not found + */ + public function getCacheData($pCoord) { + if ($pCoord === $this->_currentObjectID) { + return $this->_currentObject; + } + $this->_storeData(); + + // Check if the entry that has been requested actually exists + if (parent::isDataSet($pCoord)) { + $obj = $this->_memcache->get($this->_cachePrefix.$pCoord.'.cache'); + if ($obj === false) { + // Entry no longer exists in Memcache, so clear it from the cache array + parent::deleteCacheData($pCoord); + throw new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in MemCache'); + } + } else { + // Return null if requested entry doesn't exist in cache + return null; + } + + // Set current entry to the requested entry + $this->_currentObjectID = $pCoord; + $this->_currentObject = unserialize($obj); + // Re-attach this as the cell's parent + $this->_currentObject->attach($this); + + // Return requested entry + return $this->_currentObject; + } // function getCacheData() + + + /** + * Get a list of all cell addresses currently held in cache + * + * @return array of string + */ + public function getCellList() { + if ($this->_currentObjectID !== null) { + $this->_storeData(); + } + + return parent::getCellList(); + } + + + /** + * Delete a cell in cache identified by coordinate address + * + * @param string $pCoord Coordinate address of the cell to delete + * @throws PHPExcel_Exception + */ + public function deleteCacheData($pCoord) { + // Delete the entry from Memcache + $this->_memcache->delete($this->_cachePrefix.$pCoord.'.cache'); + + // Delete the entry from our cell address array + parent::deleteCacheData($pCoord); + } // function deleteCacheData() + + + /** + * Clone the cell collection + * + * @param PHPExcel_Worksheet $parent The new worksheet + * @return void + */ + public function copyCellCollection(PHPExcel_Worksheet $parent) { + parent::copyCellCollection($parent); + // Get a new id for the new file name + $baseUnique = $this->_getUniqueID(); + $newCachePrefix = substr(md5($baseUnique),0,8).'.'; + $cacheList = $this->getCellList(); + foreach($cacheList as $cellID) { + if ($cellID != $this->_currentObjectID) { + $obj = $this->_memcache->get($this->_cachePrefix.$cellID.'.cache'); + if ($obj === false) { + // Entry no longer exists in Memcache, so clear it from the cache array + parent::deleteCacheData($cellID); + throw new PHPExcel_Exception('Cell entry '.$cellID.' no longer exists in MemCache'); + } + if (!$this->_memcache->add($newCachePrefix.$cellID.'.cache',$obj,NULL,$this->_cacheTime)) { + $this->__destruct(); + throw new PHPExcel_Exception('Failed to store cell '.$cellID.' in MemCache'); + } + } + } + $this->_cachePrefix = $newCachePrefix; + } // function copyCellCollection() + + + /** + * Clear the cell collection and disconnect from our parent + * + * @return void + */ + public function unsetWorksheetCells() { + if(!is_null($this->_currentObject)) { + $this->_currentObject->detach(); + $this->_currentObject = $this->_currentObjectID = null; + } + + // Flush the Memcache cache + $this->__destruct(); + + $this->_cellCache = array(); + + // detach ourself from the worksheet, so that it can then delete this object successfully + $this->_parent = null; + } // function unsetWorksheetCells() + + + /** + * Initialise this new cell collection + * + * @param PHPExcel_Worksheet $parent The worksheet for this cell collection + * @param array of mixed $arguments Additional initialisation arguments + */ + public function __construct(PHPExcel_Worksheet $parent, $arguments) { + $memcacheServer = (isset($arguments['memcacheServer'])) ? $arguments['memcacheServer'] : 'localhost'; + $memcachePort = (isset($arguments['memcachePort'])) ? $arguments['memcachePort'] : 11211; + $cacheTime = (isset($arguments['cacheTime'])) ? $arguments['cacheTime'] : 600; + + if (is_null($this->_cachePrefix)) { + $baseUnique = $this->_getUniqueID(); + $this->_cachePrefix = substr(md5($baseUnique),0,8).'.'; + + // Set a new Memcache object and connect to the Memcache server + $this->_memcache = new Memcache(); + if (!$this->_memcache->addServer($memcacheServer, $memcachePort, false, 50, 5, 5, true, array($this, 'failureCallback'))) { + throw new PHPExcel_Exception('Could not connect to MemCache server at '.$memcacheServer.':'.$memcachePort); + } + $this->_cacheTime = $cacheTime; + + parent::__construct($parent); + } + } // function __construct() + + + /** + * Memcache error handler + * + * @param string $host Memcache server + * @param integer $port Memcache port + * @throws PHPExcel_Exception + */ + public function failureCallback($host, $port) { + throw new PHPExcel_Exception('memcache '.$host.':'.$port.' failed'); + } + + + /** + * Destroy this cell collection + */ + public function __destruct() { + $cacheList = $this->getCellList(); + foreach($cacheList as $cellID) { + $this->_memcache->delete($this->_cachePrefix.$cellID.'.cache'); + } + } // function __destruct() + + /** + * Identify whether the caching method is currently available + * Some methods are dependent on the availability of certain extensions being enabled in the PHP build + * + * @return boolean + */ + public static function cacheMethodIsAvailable() { + if (!function_exists('memcache_add')) { + return false; + } + + return true; + } + +} diff --git a/lib/phpexcel/PHPExcel/CachedObjectStorage/Memory.php b/lib/phpexcel/PHPExcel/CachedObjectStorage/Memory.php new file mode 100644 index 0000000..32b5c5a --- /dev/null +++ b/lib/phpexcel/PHPExcel/CachedObjectStorage/Memory.php @@ -0,0 +1,125 @@ +_cellCache[$pCoord] = $cell; + + // Set current entry to the new/updated entry + $this->_currentObjectID = $pCoord; + + return $cell; + } // function addCacheData() + + + /** + * Get cell at a specific coordinate + * + * @param string $pCoord Coordinate of the cell + * @throws PHPExcel_Exception + * @return PHPExcel_Cell Cell that was found, or null if not found + */ + public function getCacheData($pCoord) { + // Check if the entry that has been requested actually exists + if (!isset($this->_cellCache[$pCoord])) { + $this->_currentObjectID = NULL; + // Return null if requested entry doesn't exist in cache + return null; + } + + // Set current entry to the requested entry + $this->_currentObjectID = $pCoord; + + // Return requested entry + return $this->_cellCache[$pCoord]; + } // function getCacheData() + + + /** + * Clone the cell collection + * + * @param PHPExcel_Worksheet $parent The new worksheet + * @return void + */ + public function copyCellCollection(PHPExcel_Worksheet $parent) { + parent::copyCellCollection($parent); + + $newCollection = array(); + foreach($this->_cellCache as $k => &$cell) { + $newCollection[$k] = clone $cell; + $newCollection[$k]->attach($this); + } + + $this->_cellCache = $newCollection; + } + + + /** + * Clear the cell collection and disconnect from our parent + * + * @return void + */ + public function unsetWorksheetCells() { + // Because cells are all stored as intact objects in memory, we need to detach each one from the parent + foreach($this->_cellCache as $k => &$cell) { + $cell->detach(); + $this->_cellCache[$k] = null; + } + unset($cell); + + $this->_cellCache = array(); + + // detach ourself from the worksheet, so that it can then delete this object successfully + $this->_parent = null; + } // function unsetWorksheetCells() + +} diff --git a/lib/phpexcel/PHPExcel/CachedObjectStorage/MemoryGZip.php b/lib/phpexcel/PHPExcel/CachedObjectStorage/MemoryGZip.php new file mode 100644 index 0000000..6186be2 --- /dev/null +++ b/lib/phpexcel/PHPExcel/CachedObjectStorage/MemoryGZip.php @@ -0,0 +1,137 @@ +_currentCellIsDirty && !empty($this->_currentObjectID)) { + $this->_currentObject->detach(); + + $this->_cellCache[$this->_currentObjectID] = gzdeflate(serialize($this->_currentObject)); + $this->_currentCellIsDirty = false; + } + $this->_currentObjectID = $this->_currentObject = null; + } // function _storeData() + + + /** + * Add or Update a cell in cache identified by coordinate address + * + * @param string $pCoord Coordinate address of the cell to update + * @param PHPExcel_Cell $cell Cell to update + * @return void + * @throws PHPExcel_Exception + */ + public function addCacheData($pCoord, PHPExcel_Cell $cell) { + if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) { + $this->_storeData(); + } + + $this->_currentObjectID = $pCoord; + $this->_currentObject = $cell; + $this->_currentCellIsDirty = true; + + return $cell; + } // function addCacheData() + + + /** + * Get cell at a specific coordinate + * + * @param string $pCoord Coordinate of the cell + * @throws PHPExcel_Exception + * @return PHPExcel_Cell Cell that was found, or null if not found + */ + public function getCacheData($pCoord) { + if ($pCoord === $this->_currentObjectID) { + return $this->_currentObject; + } + $this->_storeData(); + + // Check if the entry that has been requested actually exists + if (!isset($this->_cellCache[$pCoord])) { + // Return null if requested entry doesn't exist in cache + return null; + } + + // Set current entry to the requested entry + $this->_currentObjectID = $pCoord; + $this->_currentObject = unserialize(gzinflate($this->_cellCache[$pCoord])); + // Re-attach this as the cell's parent + $this->_currentObject->attach($this); + + // Return requested entry + return $this->_currentObject; + } // function getCacheData() + + + /** + * Get a list of all cell addresses currently held in cache + * + * @return array of string + */ + public function getCellList() { + if ($this->_currentObjectID !== null) { + $this->_storeData(); + } + + return parent::getCellList(); + } + + + /** + * Clear the cell collection and disconnect from our parent + * + * @return void + */ + public function unsetWorksheetCells() { + if(!is_null($this->_currentObject)) { + $this->_currentObject->detach(); + $this->_currentObject = $this->_currentObjectID = null; + } + $this->_cellCache = array(); + + // detach ourself from the worksheet, so that it can then delete this object successfully + $this->_parent = null; + } // function unsetWorksheetCells() + +} diff --git a/lib/phpexcel/PHPExcel/CachedObjectStorage/MemorySerialized.php b/lib/phpexcel/PHPExcel/CachedObjectStorage/MemorySerialized.php new file mode 100644 index 0000000..1f2e864 --- /dev/null +++ b/lib/phpexcel/PHPExcel/CachedObjectStorage/MemorySerialized.php @@ -0,0 +1,137 @@ +_currentCellIsDirty && !empty($this->_currentObjectID)) { + $this->_currentObject->detach(); + + $this->_cellCache[$this->_currentObjectID] = serialize($this->_currentObject); + $this->_currentCellIsDirty = false; + } + $this->_currentObjectID = $this->_currentObject = null; + } // function _storeData() + + + /** + * Add or Update a cell in cache identified by coordinate address + * + * @param string $pCoord Coordinate address of the cell to update + * @param PHPExcel_Cell $cell Cell to update + * @return void + * @throws PHPExcel_Exception + */ + public function addCacheData($pCoord, PHPExcel_Cell $cell) { + if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) { + $this->_storeData(); + } + + $this->_currentObjectID = $pCoord; + $this->_currentObject = $cell; + $this->_currentCellIsDirty = true; + + return $cell; + } // function addCacheData() + + + /** + * Get cell at a specific coordinate + * + * @param string $pCoord Coordinate of the cell + * @throws PHPExcel_Exception + * @return PHPExcel_Cell Cell that was found, or null if not found + */ + public function getCacheData($pCoord) { + if ($pCoord === $this->_currentObjectID) { + return $this->_currentObject; + } + $this->_storeData(); + + // Check if the entry that has been requested actually exists + if (!isset($this->_cellCache[$pCoord])) { + // Return null if requested entry doesn't exist in cache + return null; + } + + // Set current entry to the requested entry + $this->_currentObjectID = $pCoord; + $this->_currentObject = unserialize($this->_cellCache[$pCoord]); + // Re-attach this as the cell's parent + $this->_currentObject->attach($this); + + // Return requested entry + return $this->_currentObject; + } // function getCacheData() + + + /** + * Get a list of all cell addresses currently held in cache + * + * @return array of string + */ + public function getCellList() { + if ($this->_currentObjectID !== null) { + $this->_storeData(); + } + + return parent::getCellList(); + } + + + /** + * Clear the cell collection and disconnect from our parent + * + * @return void + */ + public function unsetWorksheetCells() { + if(!is_null($this->_currentObject)) { + $this->_currentObject->detach(); + $this->_currentObject = $this->_currentObjectID = null; + } + $this->_cellCache = array(); + + // detach ourself from the worksheet, so that it can then delete this object successfully + $this->_parent = null; + } // function unsetWorksheetCells() + +} diff --git a/lib/phpexcel/PHPExcel/CachedObjectStorage/PHPTemp.php b/lib/phpexcel/PHPExcel/CachedObjectStorage/PHPTemp.php new file mode 100644 index 0000000..285c7ea --- /dev/null +++ b/lib/phpexcel/PHPExcel/CachedObjectStorage/PHPTemp.php @@ -0,0 +1,206 @@ +_currentCellIsDirty && !empty($this->_currentObjectID)) { + $this->_currentObject->detach(); + + fseek($this->_fileHandle,0,SEEK_END); + $offset = ftell($this->_fileHandle); + fwrite($this->_fileHandle, serialize($this->_currentObject)); + $this->_cellCache[$this->_currentObjectID] = array('ptr' => $offset, + 'sz' => ftell($this->_fileHandle) - $offset + ); + $this->_currentCellIsDirty = false; + } + $this->_currentObjectID = $this->_currentObject = null; + } // function _storeData() + + + /** + * Add or Update a cell in cache identified by coordinate address + * + * @param string $pCoord Coordinate address of the cell to update + * @param PHPExcel_Cell $cell Cell to update + * @return void + * @throws PHPExcel_Exception + */ + public function addCacheData($pCoord, PHPExcel_Cell $cell) { + if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) { + $this->_storeData(); + } + + $this->_currentObjectID = $pCoord; + $this->_currentObject = $cell; + $this->_currentCellIsDirty = true; + + return $cell; + } // function addCacheData() + + + /** + * Get cell at a specific coordinate + * + * @param string $pCoord Coordinate of the cell + * @throws PHPExcel_Exception + * @return PHPExcel_Cell Cell that was found, or null if not found + */ + public function getCacheData($pCoord) { + if ($pCoord === $this->_currentObjectID) { + return $this->_currentObject; + } + $this->_storeData(); + + // Check if the entry that has been requested actually exists + if (!isset($this->_cellCache[$pCoord])) { + // Return null if requested entry doesn't exist in cache + return null; + } + + // Set current entry to the requested entry + $this->_currentObjectID = $pCoord; + fseek($this->_fileHandle,$this->_cellCache[$pCoord]['ptr']); + $this->_currentObject = unserialize(fread($this->_fileHandle,$this->_cellCache[$pCoord]['sz'])); + // Re-attach this as the cell's parent + $this->_currentObject->attach($this); + + // Return requested entry + return $this->_currentObject; + } // function getCacheData() + + + /** + * Get a list of all cell addresses currently held in cache + * + * @return array of string + */ + public function getCellList() { + if ($this->_currentObjectID !== null) { + $this->_storeData(); + } + + return parent::getCellList(); + } + + + /** + * Clone the cell collection + * + * @param PHPExcel_Worksheet $parent The new worksheet + * @return void + */ + public function copyCellCollection(PHPExcel_Worksheet $parent) { + parent::copyCellCollection($parent); + // Open a new stream for the cell cache data + $newFileHandle = fopen('php://temp/maxmemory:'.$this->_memoryCacheSize,'a+'); + // Copy the existing cell cache data to the new stream + fseek($this->_fileHandle,0); + while (!feof($this->_fileHandle)) { + fwrite($newFileHandle,fread($this->_fileHandle, 1024)); + } + $this->_fileHandle = $newFileHandle; + } // function copyCellCollection() + + + /** + * Clear the cell collection and disconnect from our parent + * + * @return void + */ + public function unsetWorksheetCells() { + if(!is_null($this->_currentObject)) { + $this->_currentObject->detach(); + $this->_currentObject = $this->_currentObjectID = null; + } + $this->_cellCache = array(); + + // detach ourself from the worksheet, so that it can then delete this object successfully + $this->_parent = null; + + // Close down the php://temp file + $this->__destruct(); + } // function unsetWorksheetCells() + + + /** + * Initialise this new cell collection + * + * @param PHPExcel_Worksheet $parent The worksheet for this cell collection + * @param array of mixed $arguments Additional initialisation arguments + */ + public function __construct(PHPExcel_Worksheet $parent, $arguments) { + $this->_memoryCacheSize = (isset($arguments['memoryCacheSize'])) ? $arguments['memoryCacheSize'] : '1MB'; + + parent::__construct($parent); + if (is_null($this->_fileHandle)) { + $this->_fileHandle = fopen('php://temp/maxmemory:'.$this->_memoryCacheSize,'a+'); + } + } // function __construct() + + + /** + * Destroy this cell collection + */ + public function __destruct() { + if (!is_null($this->_fileHandle)) { + fclose($this->_fileHandle); + } + $this->_fileHandle = null; + } // function __destruct() + +} diff --git a/lib/phpexcel/PHPExcel/CachedObjectStorage/SQLite.php b/lib/phpexcel/PHPExcel/CachedObjectStorage/SQLite.php new file mode 100644 index 0000000..775a9f2 --- /dev/null +++ b/lib/phpexcel/PHPExcel/CachedObjectStorage/SQLite.php @@ -0,0 +1,306 @@ +_currentCellIsDirty && !empty($this->_currentObjectID)) { + $this->_currentObject->detach(); + + if (!$this->_DBHandle->queryExec("INSERT OR REPLACE INTO kvp_".$this->_TableName." VALUES('".$this->_currentObjectID."','".sqlite_escape_string(serialize($this->_currentObject))."')")) + throw new PHPExcel_Exception(sqlite_error_string($this->_DBHandle->lastError())); + $this->_currentCellIsDirty = false; + } + $this->_currentObjectID = $this->_currentObject = null; + } // function _storeData() + + + /** + * Add or Update a cell in cache identified by coordinate address + * + * @param string $pCoord Coordinate address of the cell to update + * @param PHPExcel_Cell $cell Cell to update + * @return void + * @throws PHPExcel_Exception + */ + public function addCacheData($pCoord, PHPExcel_Cell $cell) { + if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) { + $this->_storeData(); + } + + $this->_currentObjectID = $pCoord; + $this->_currentObject = $cell; + $this->_currentCellIsDirty = true; + + return $cell; + } // function addCacheData() + + + /** + * Get cell at a specific coordinate + * + * @param string $pCoord Coordinate of the cell + * @throws PHPExcel_Exception + * @return PHPExcel_Cell Cell that was found, or null if not found + */ + public function getCacheData($pCoord) { + if ($pCoord === $this->_currentObjectID) { + return $this->_currentObject; + } + $this->_storeData(); + + $query = "SELECT value FROM kvp_".$this->_TableName." WHERE id='".$pCoord."'"; + $cellResultSet = $this->_DBHandle->query($query,SQLITE_ASSOC); + if ($cellResultSet === false) { + throw new PHPExcel_Exception(sqlite_error_string($this->_DBHandle->lastError())); + } elseif ($cellResultSet->numRows() == 0) { + // Return null if requested entry doesn't exist in cache + return null; + } + + // Set current entry to the requested entry + $this->_currentObjectID = $pCoord; + + $cellResult = $cellResultSet->fetchSingle(); + $this->_currentObject = unserialize($cellResult); + // Re-attach this as the cell's parent + $this->_currentObject->attach($this); + + // Return requested entry + return $this->_currentObject; + } // function getCacheData() + + + /** + * Is a value set for an indexed cell? + * + * @param string $pCoord Coordinate address of the cell to check + * @return boolean + */ + public function isDataSet($pCoord) { + if ($pCoord === $this->_currentObjectID) { + return true; + } + + // Check if the requested entry exists in the cache + $query = "SELECT id FROM kvp_".$this->_TableName." WHERE id='".$pCoord."'"; + $cellResultSet = $this->_DBHandle->query($query,SQLITE_ASSOC); + if ($cellResultSet === false) { + throw new PHPExcel_Exception(sqlite_error_string($this->_DBHandle->lastError())); + } elseif ($cellResultSet->numRows() == 0) { + // Return null if requested entry doesn't exist in cache + return false; + } + return true; + } // function isDataSet() + + + /** + * Delete a cell in cache identified by coordinate address + * + * @param string $pCoord Coordinate address of the cell to delete + * @throws PHPExcel_Exception + */ + public function deleteCacheData($pCoord) { + if ($pCoord === $this->_currentObjectID) { + $this->_currentObject->detach(); + $this->_currentObjectID = $this->_currentObject = null; + } + + // Check if the requested entry exists in the cache + $query = "DELETE FROM kvp_".$this->_TableName." WHERE id='".$pCoord."'"; + if (!$this->_DBHandle->queryExec($query)) + throw new PHPExcel_Exception(sqlite_error_string($this->_DBHandle->lastError())); + + $this->_currentCellIsDirty = false; + } // function deleteCacheData() + + + /** + * Move a cell object from one address to another + * + * @param string $fromAddress Current address of the cell to move + * @param string $toAddress Destination address of the cell to move + * @return boolean + */ + public function moveCell($fromAddress, $toAddress) { + if ($fromAddress === $this->_currentObjectID) { + $this->_currentObjectID = $toAddress; + } + + $query = "DELETE FROM kvp_".$this->_TableName." WHERE id='".$toAddress."'"; + $result = $this->_DBHandle->exec($query); + if ($result === false) + throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); + + $query = "UPDATE kvp_".$this->_TableName." SET id='".$toAddress."' WHERE id='".$fromAddress."'"; + $result = $this->_DBHandle->exec($query); + if ($result === false) + throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); + + return TRUE; + } // function moveCell() + + + /** + * Get a list of all cell addresses currently held in cache + * + * @return array of string + */ + public function getCellList() { + if ($this->_currentObjectID !== null) { + $this->_storeData(); + } + + $query = "SELECT id FROM kvp_".$this->_TableName; + $cellIdsResult = $this->_DBHandle->unbufferedQuery($query,SQLITE_ASSOC); + if ($cellIdsResult === false) + throw new PHPExcel_Exception(sqlite_error_string($this->_DBHandle->lastError())); + + $cellKeys = array(); + foreach($cellIdsResult as $row) { + $cellKeys[] = $row['id']; + } + + return $cellKeys; + } // function getCellList() + + + /** + * Clone the cell collection + * + * @param PHPExcel_Worksheet $parent The new worksheet + * @return void + */ + public function copyCellCollection(PHPExcel_Worksheet $parent) { + $this->_currentCellIsDirty; + $this->_storeData(); + + // Get a new id for the new table name + $tableName = str_replace('.','_',$this->_getUniqueID()); + if (!$this->_DBHandle->queryExec('CREATE TABLE kvp_'.$tableName.' (id VARCHAR(12) PRIMARY KEY, value BLOB) + AS SELECT * FROM kvp_'.$this->_TableName)) + throw new PHPExcel_Exception(sqlite_error_string($this->_DBHandle->lastError())); + + // Copy the existing cell cache file + $this->_TableName = $tableName; + } // function copyCellCollection() + + + /** + * Clear the cell collection and disconnect from our parent + * + * @return void + */ + public function unsetWorksheetCells() { + if(!is_null($this->_currentObject)) { + $this->_currentObject->detach(); + $this->_currentObject = $this->_currentObjectID = null; + } + // detach ourself from the worksheet, so that it can then delete this object successfully + $this->_parent = null; + + // Close down the temporary cache file + $this->__destruct(); + } // function unsetWorksheetCells() + + + /** + * Initialise this new cell collection + * + * @param PHPExcel_Worksheet $parent The worksheet for this cell collection + */ + public function __construct(PHPExcel_Worksheet $parent) { + parent::__construct($parent); + if (is_null($this->_DBHandle)) { + $this->_TableName = str_replace('.','_',$this->_getUniqueID()); + $_DBName = ':memory:'; + + $this->_DBHandle = new SQLiteDatabase($_DBName); + if ($this->_DBHandle === false) + throw new PHPExcel_Exception(sqlite_error_string($this->_DBHandle->lastError())); + if (!$this->_DBHandle->queryExec('CREATE TABLE kvp_'.$this->_TableName.' (id VARCHAR(12) PRIMARY KEY, value BLOB)')) + throw new PHPExcel_Exception(sqlite_error_string($this->_DBHandle->lastError())); + } + } // function __construct() + + + /** + * Destroy this cell collection + */ + public function __destruct() { + if (!is_null($this->_DBHandle)) { + $this->_DBHandle->queryExec('DROP TABLE kvp_'.$this->_TableName); + } + $this->_DBHandle = null; + } // function __destruct() + + + /** + * Identify whether the caching method is currently available + * Some methods are dependent on the availability of certain extensions being enabled in the PHP build + * + * @return boolean + */ + public static function cacheMethodIsAvailable() { + if (!function_exists('sqlite_open')) { + return false; + } + + return true; + } + +} diff --git a/lib/phpexcel/PHPExcel/CachedObjectStorage/SQLite3.php b/lib/phpexcel/PHPExcel/CachedObjectStorage/SQLite3.php new file mode 100644 index 0000000..a2b8526 --- /dev/null +++ b/lib/phpexcel/PHPExcel/CachedObjectStorage/SQLite3.php @@ -0,0 +1,345 @@ +_currentCellIsDirty && !empty($this->_currentObjectID)) { + $this->_currentObject->detach(); + + $this->_insertQuery->bindValue('id',$this->_currentObjectID,SQLITE3_TEXT); + $this->_insertQuery->bindValue('data',serialize($this->_currentObject),SQLITE3_BLOB); + $result = $this->_insertQuery->execute(); + if ($result === false) + throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); + $this->_currentCellIsDirty = false; + } + $this->_currentObjectID = $this->_currentObject = null; + } // function _storeData() + + + /** + * Add or Update a cell in cache identified by coordinate address + * + * @param string $pCoord Coordinate address of the cell to update + * @param PHPExcel_Cell $cell Cell to update + * @return void + * @throws PHPExcel_Exception + */ + public function addCacheData($pCoord, PHPExcel_Cell $cell) { + if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) { + $this->_storeData(); + } + + $this->_currentObjectID = $pCoord; + $this->_currentObject = $cell; + $this->_currentCellIsDirty = true; + + return $cell; + } // function addCacheData() + + + /** + * Get cell at a specific coordinate + * + * @param string $pCoord Coordinate of the cell + * @throws PHPExcel_Exception + * @return PHPExcel_Cell Cell that was found, or null if not found + */ + public function getCacheData($pCoord) { + if ($pCoord === $this->_currentObjectID) { + return $this->_currentObject; + } + $this->_storeData(); + + $this->_selectQuery->bindValue('id',$pCoord,SQLITE3_TEXT); + $cellResult = $this->_selectQuery->execute(); + if ($cellResult === FALSE) { + throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); + } + $cellData = $cellResult->fetchArray(SQLITE3_ASSOC); + if ($cellData === FALSE) { + // Return null if requested entry doesn't exist in cache + return NULL; + } + + // Set current entry to the requested entry + $this->_currentObjectID = $pCoord; + + $this->_currentObject = unserialize($cellData['value']); + // Re-attach this as the cell's parent + $this->_currentObject->attach($this); + + // Return requested entry + return $this->_currentObject; + } // function getCacheData() + + + /** + * Is a value set for an indexed cell? + * + * @param string $pCoord Coordinate address of the cell to check + * @return boolean + */ + public function isDataSet($pCoord) { + if ($pCoord === $this->_currentObjectID) { + return TRUE; + } + + // Check if the requested entry exists in the cache + $this->_selectQuery->bindValue('id',$pCoord,SQLITE3_TEXT); + $cellResult = $this->_selectQuery->execute(); + if ($cellResult === FALSE) { + throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); + } + $cellData = $cellResult->fetchArray(SQLITE3_ASSOC); + + return ($cellData === FALSE) ? FALSE : TRUE; + } // function isDataSet() + + + /** + * Delete a cell in cache identified by coordinate address + * + * @param string $pCoord Coordinate address of the cell to delete + * @throws PHPExcel_Exception + */ + public function deleteCacheData($pCoord) { + if ($pCoord === $this->_currentObjectID) { + $this->_currentObject->detach(); + $this->_currentObjectID = $this->_currentObject = NULL; + } + + // Check if the requested entry exists in the cache + $this->_deleteQuery->bindValue('id',$pCoord,SQLITE3_TEXT); + $result = $this->_deleteQuery->execute(); + if ($result === FALSE) + throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); + + $this->_currentCellIsDirty = FALSE; + } // function deleteCacheData() + + + /** + * Move a cell object from one address to another + * + * @param string $fromAddress Current address of the cell to move + * @param string $toAddress Destination address of the cell to move + * @return boolean + */ + public function moveCell($fromAddress, $toAddress) { + if ($fromAddress === $this->_currentObjectID) { + $this->_currentObjectID = $toAddress; + } + + $this->_deleteQuery->bindValue('id',$toAddress,SQLITE3_TEXT); + $result = $this->_deleteQuery->execute(); + if ($result === false) + throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); + + $this->_updateQuery->bindValue('toid',$toAddress,SQLITE3_TEXT); + $this->_updateQuery->bindValue('fromid',$fromAddress,SQLITE3_TEXT); + $result = $this->_updateQuery->execute(); + if ($result === false) + throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); + + return TRUE; + } // function moveCell() + + + /** + * Get a list of all cell addresses currently held in cache + * + * @return array of string + */ + public function getCellList() { + if ($this->_currentObjectID !== null) { + $this->_storeData(); + } + + $query = "SELECT id FROM kvp_".$this->_TableName; + $cellIdsResult = $this->_DBHandle->query($query); + if ($cellIdsResult === false) + throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); + + $cellKeys = array(); + while ($row = $cellIdsResult->fetchArray(SQLITE3_ASSOC)) { + $cellKeys[] = $row['id']; + } + + return $cellKeys; + } // function getCellList() + + + /** + * Clone the cell collection + * + * @param PHPExcel_Worksheet $parent The new worksheet + * @return void + */ + public function copyCellCollection(PHPExcel_Worksheet $parent) { + $this->_currentCellIsDirty; + $this->_storeData(); + + // Get a new id for the new table name + $tableName = str_replace('.','_',$this->_getUniqueID()); + if (!$this->_DBHandle->exec('CREATE TABLE kvp_'.$tableName.' (id VARCHAR(12) PRIMARY KEY, value BLOB) + AS SELECT * FROM kvp_'.$this->_TableName)) + throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); + + // Copy the existing cell cache file + $this->_TableName = $tableName; + } // function copyCellCollection() + + + /** + * Clear the cell collection and disconnect from our parent + * + * @return void + */ + public function unsetWorksheetCells() { + if(!is_null($this->_currentObject)) { + $this->_currentObject->detach(); + $this->_currentObject = $this->_currentObjectID = null; + } + // detach ourself from the worksheet, so that it can then delete this object successfully + $this->_parent = null; + + // Close down the temporary cache file + $this->__destruct(); + } // function unsetWorksheetCells() + + + /** + * Initialise this new cell collection + * + * @param PHPExcel_Worksheet $parent The worksheet for this cell collection + */ + public function __construct(PHPExcel_Worksheet $parent) { + parent::__construct($parent); + if (is_null($this->_DBHandle)) { + $this->_TableName = str_replace('.','_',$this->_getUniqueID()); + $_DBName = ':memory:'; + + $this->_DBHandle = new SQLite3($_DBName); + if ($this->_DBHandle === false) + throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); + if (!$this->_DBHandle->exec('CREATE TABLE kvp_'.$this->_TableName.' (id VARCHAR(12) PRIMARY KEY, value BLOB)')) + throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); + } + + $this->_selectQuery = $this->_DBHandle->prepare("SELECT value FROM kvp_".$this->_TableName." WHERE id = :id"); + $this->_insertQuery = $this->_DBHandle->prepare("INSERT OR REPLACE INTO kvp_".$this->_TableName." VALUES(:id,:data)"); + $this->_updateQuery = $this->_DBHandle->prepare("UPDATE kvp_".$this->_TableName." SET id=:toId WHERE id=:fromId"); + $this->_deleteQuery = $this->_DBHandle->prepare("DELETE FROM kvp_".$this->_TableName." WHERE id = :id"); + } // function __construct() + + + /** + * Destroy this cell collection + */ + public function __destruct() { + if (!is_null($this->_DBHandle)) { + $this->_DBHandle->exec('DROP TABLE kvp_'.$this->_TableName); + $this->_DBHandle->close(); + } + $this->_DBHandle = null; + } // function __destruct() + + + /** + * Identify whether the caching method is currently available + * Some methods are dependent on the availability of certain extensions being enabled in the PHP build + * + * @return boolean + */ + public static function cacheMethodIsAvailable() { + if (!class_exists('SQLite3',FALSE)) { + return false; + } + + return true; + } + +} diff --git a/lib/phpexcel/PHPExcel/CachedObjectStorage/Wincache.php b/lib/phpexcel/PHPExcel/CachedObjectStorage/Wincache.php new file mode 100644 index 0000000..f7c55a7 --- /dev/null +++ b/lib/phpexcel/PHPExcel/CachedObjectStorage/Wincache.php @@ -0,0 +1,294 @@ +_currentCellIsDirty && !empty($this->_currentObjectID)) { + $this->_currentObject->detach(); + + $obj = serialize($this->_currentObject); + if (wincache_ucache_exists($this->_cachePrefix.$this->_currentObjectID.'.cache')) { + if (!wincache_ucache_set($this->_cachePrefix.$this->_currentObjectID.'.cache', $obj, $this->_cacheTime)) { + $this->__destruct(); + throw new PHPExcel_Exception('Failed to store cell '.$this->_currentObjectID.' in WinCache'); + } + } else { + if (!wincache_ucache_add($this->_cachePrefix.$this->_currentObjectID.'.cache', $obj, $this->_cacheTime)) { + $this->__destruct(); + throw new PHPExcel_Exception('Failed to store cell '.$this->_currentObjectID.' in WinCache'); + } + } + $this->_currentCellIsDirty = false; + } + + $this->_currentObjectID = $this->_currentObject = null; + } // function _storeData() + + + /** + * Add or Update a cell in cache identified by coordinate address + * + * @param string $pCoord Coordinate address of the cell to update + * @param PHPExcel_Cell $cell Cell to update + * @return void + * @throws PHPExcel_Exception + */ + public function addCacheData($pCoord, PHPExcel_Cell $cell) { + if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) { + $this->_storeData(); + } + $this->_cellCache[$pCoord] = true; + + $this->_currentObjectID = $pCoord; + $this->_currentObject = $cell; + $this->_currentCellIsDirty = true; + + return $cell; + } // function addCacheData() + + + /** + * Is a value set in the current PHPExcel_CachedObjectStorage_ICache for an indexed cell? + * + * @param string $pCoord Coordinate address of the cell to check + * @return boolean + */ + public function isDataSet($pCoord) { + // Check if the requested entry is the current object, or exists in the cache + if (parent::isDataSet($pCoord)) { + if ($this->_currentObjectID == $pCoord) { + return true; + } + // Check if the requested entry still exists in cache + $success = wincache_ucache_exists($this->_cachePrefix.$pCoord.'.cache'); + if ($success === false) { + // Entry no longer exists in Wincache, so clear it from the cache array + parent::deleteCacheData($pCoord); + throw new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in WinCache'); + } + return true; + } + return false; + } // function isDataSet() + + + /** + * Get cell at a specific coordinate + * + * @param string $pCoord Coordinate of the cell + * @throws PHPExcel_Exception + * @return PHPExcel_Cell Cell that was found, or null if not found + */ + public function getCacheData($pCoord) { + if ($pCoord === $this->_currentObjectID) { + return $this->_currentObject; + } + $this->_storeData(); + + // Check if the entry that has been requested actually exists + $obj = null; + if (parent::isDataSet($pCoord)) { + $success = false; + $obj = wincache_ucache_get($this->_cachePrefix.$pCoord.'.cache', $success); + if ($success === false) { + // Entry no longer exists in WinCache, so clear it from the cache array + parent::deleteCacheData($pCoord); + throw new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in WinCache'); + } + } else { + // Return null if requested entry doesn't exist in cache + return null; + } + + // Set current entry to the requested entry + $this->_currentObjectID = $pCoord; + $this->_currentObject = unserialize($obj); + // Re-attach this as the cell's parent + $this->_currentObject->attach($this); + + // Return requested entry + return $this->_currentObject; + } // function getCacheData() + + + /** + * Get a list of all cell addresses currently held in cache + * + * @return array of string + */ + public function getCellList() { + if ($this->_currentObjectID !== null) { + $this->_storeData(); + } + + return parent::getCellList(); + } + + + /** + * Delete a cell in cache identified by coordinate address + * + * @param string $pCoord Coordinate address of the cell to delete + * @throws PHPExcel_Exception + */ + public function deleteCacheData($pCoord) { + // Delete the entry from Wincache + wincache_ucache_delete($this->_cachePrefix.$pCoord.'.cache'); + + // Delete the entry from our cell address array + parent::deleteCacheData($pCoord); + } // function deleteCacheData() + + + /** + * Clone the cell collection + * + * @param PHPExcel_Worksheet $parent The new worksheet + * @return void + */ + public function copyCellCollection(PHPExcel_Worksheet $parent) { + parent::copyCellCollection($parent); + // Get a new id for the new file name + $baseUnique = $this->_getUniqueID(); + $newCachePrefix = substr(md5($baseUnique),0,8).'.'; + $cacheList = $this->getCellList(); + foreach($cacheList as $cellID) { + if ($cellID != $this->_currentObjectID) { + $success = false; + $obj = wincache_ucache_get($this->_cachePrefix.$cellID.'.cache', $success); + if ($success === false) { + // Entry no longer exists in WinCache, so clear it from the cache array + parent::deleteCacheData($cellID); + throw new PHPExcel_Exception('Cell entry '.$cellID.' no longer exists in Wincache'); + } + if (!wincache_ucache_add($newCachePrefix.$cellID.'.cache', $obj, $this->_cacheTime)) { + $this->__destruct(); + throw new PHPExcel_Exception('Failed to store cell '.$cellID.' in Wincache'); + } + } + } + $this->_cachePrefix = $newCachePrefix; + } // function copyCellCollection() + + + /** + * Clear the cell collection and disconnect from our parent + * + * @return void + */ + public function unsetWorksheetCells() { + if(!is_null($this->_currentObject)) { + $this->_currentObject->detach(); + $this->_currentObject = $this->_currentObjectID = null; + } + + // Flush the WinCache cache + $this->__destruct(); + + $this->_cellCache = array(); + + // detach ourself from the worksheet, so that it can then delete this object successfully + $this->_parent = null; + } // function unsetWorksheetCells() + + + /** + * Initialise this new cell collection + * + * @param PHPExcel_Worksheet $parent The worksheet for this cell collection + * @param array of mixed $arguments Additional initialisation arguments + */ + public function __construct(PHPExcel_Worksheet $parent, $arguments) { + $cacheTime = (isset($arguments['cacheTime'])) ? $arguments['cacheTime'] : 600; + + if (is_null($this->_cachePrefix)) { + $baseUnique = $this->_getUniqueID(); + $this->_cachePrefix = substr(md5($baseUnique),0,8).'.'; + $this->_cacheTime = $cacheTime; + + parent::__construct($parent); + } + } // function __construct() + + + /** + * Destroy this cell collection + */ + public function __destruct() { + $cacheList = $this->getCellList(); + foreach($cacheList as $cellID) { + wincache_ucache_delete($this->_cachePrefix.$cellID.'.cache'); + } + } // function __destruct() + + + /** + * Identify whether the caching method is currently available + * Some methods are dependent on the availability of certain extensions being enabled in the PHP build + * + * @return boolean + */ + public static function cacheMethodIsAvailable() { + if (!function_exists('wincache_ucache_add')) { + return false; + } + + return true; + } + +} diff --git a/lib/phpexcel/PHPExcel/CachedObjectStorageFactory.php b/lib/phpexcel/PHPExcel/CachedObjectStorageFactory.php new file mode 100644 index 0000000..6c3ec15 --- /dev/null +++ b/lib/phpexcel/PHPExcel/CachedObjectStorageFactory.php @@ -0,0 +1,251 @@ + array( + ), + self::cache_in_memory_gzip => array( + ), + self::cache_in_memory_serialized => array( + ), + self::cache_igbinary => array( + ), + self::cache_to_phpTemp => array( 'memoryCacheSize' => '1MB' + ), + self::cache_to_discISAM => array( 'dir' => NULL + ), + self::cache_to_apc => array( 'cacheTime' => 600 + ), + self::cache_to_memcache => array( 'memcacheServer' => 'localhost', + 'memcachePort' => 11211, + 'cacheTime' => 600 + ), + self::cache_to_wincache => array( 'cacheTime' => 600 + ), + self::cache_to_sqlite => array( + ), + self::cache_to_sqlite3 => array( + ), + ); + + + /** + * Arguments for the active cache storage method + * + * @var array of mixed array + */ + private static $_storageMethodParameters = array(); + + + /** + * Return the current cache storage method + * + * @return string|NULL + **/ + public static function getCacheStorageMethod() + { + return self::$_cacheStorageMethod; + } // function getCacheStorageMethod() + + + /** + * Return the current cache storage class + * + * @return PHPExcel_CachedObjectStorage_ICache|NULL + **/ + public static function getCacheStorageClass() + { + return self::$_cacheStorageClass; + } // function getCacheStorageClass() + + + /** + * Return the list of all possible cache storage methods + * + * @return string[] + **/ + public static function getAllCacheStorageMethods() + { + return self::$_storageMethods; + } // function getCacheStorageMethods() + + + /** + * Return the list of all available cache storage methods + * + * @return string[] + **/ + public static function getCacheStorageMethods() + { + $activeMethods = array(); + foreach(self::$_storageMethods as $storageMethod) { + $cacheStorageClass = 'PHPExcel_CachedObjectStorage_' . $storageMethod; + if (call_user_func(array($cacheStorageClass, 'cacheMethodIsAvailable'))) { + $activeMethods[] = $storageMethod; + } + } + return $activeMethods; + } // function getCacheStorageMethods() + + + /** + * Identify the cache storage method to use + * + * @param string $method Name of the method to use for cell cacheing + * @param array of mixed $arguments Additional arguments to pass to the cell caching class + * when instantiating + * @return boolean + **/ + public static function initialize($method = self::cache_in_memory, $arguments = array()) + { + if (!in_array($method,self::$_storageMethods)) { + return FALSE; + } + + $cacheStorageClass = 'PHPExcel_CachedObjectStorage_'.$method; + if (!call_user_func(array( $cacheStorageClass, + 'cacheMethodIsAvailable'))) { + return FALSE; + } + + self::$_storageMethodParameters[$method] = self::$_storageMethodDefaultParameters[$method]; + foreach($arguments as $k => $v) { + if (array_key_exists($k, self::$_storageMethodParameters[$method])) { + self::$_storageMethodParameters[$method][$k] = $v; + } + } + + if (self::$_cacheStorageMethod === NULL) { + self::$_cacheStorageClass = 'PHPExcel_CachedObjectStorage_' . $method; + self::$_cacheStorageMethod = $method; + } + return TRUE; + } // function initialize() + + + /** + * Initialise the cache storage + * + * @param PHPExcel_Worksheet $parent Enable cell caching for this worksheet + * @return PHPExcel_CachedObjectStorage_ICache + **/ + public static function getInstance(PHPExcel_Worksheet $parent) + { + $cacheMethodIsAvailable = TRUE; + if (self::$_cacheStorageMethod === NULL) { + $cacheMethodIsAvailable = self::initialize(); + } + + if ($cacheMethodIsAvailable) { + $instance = new self::$_cacheStorageClass( $parent, + self::$_storageMethodParameters[self::$_cacheStorageMethod] + ); + if ($instance !== NULL) { + return $instance; + } + } + + return FALSE; + } // function getInstance() + + + /** + * Clear the cache storage + * + **/ + public static function finalize() + { + self::$_cacheStorageMethod = NULL; + self::$_cacheStorageClass = NULL; + self::$_storageMethodParameters = array(); + } + +} diff --git a/lib/phpexcel/PHPExcel/CalcEngine/CyclicReferenceStack.php b/lib/phpexcel/PHPExcel/CalcEngine/CyclicReferenceStack.php new file mode 100644 index 0000000..0259193 --- /dev/null +++ b/lib/phpexcel/PHPExcel/CalcEngine/CyclicReferenceStack.php @@ -0,0 +1,98 @@ +_stack); + } + + /** + * Push a new entry onto the stack + * + * @param mixed $value + */ + public function push($value) { + $this->_stack[] = $value; + } // function push() + + /** + * Pop the last entry from the stack + * + * @return mixed + */ + public function pop() { + return array_pop($this->_stack); + } // function pop() + + /** + * Test to see if a specified entry exists on the stack + * + * @param mixed $value The value to test + */ + public function onStack($value) { + return in_array($value, $this->_stack); + } + + /** + * Clear the stack + */ + public function clear() { + $this->_stack = array(); + } // function push() + + /** + * Return an array of all entries on the stack + * + * @return mixed[] + */ + public function showStack() { + return $this->_stack; + } + +} // class PHPExcel_CalcEngine_CyclicReferenceStack diff --git a/lib/phpexcel/PHPExcel/CalcEngine/Logger.php b/lib/phpexcel/PHPExcel/CalcEngine/Logger.php new file mode 100644 index 0000000..2048df3 --- /dev/null +++ b/lib/phpexcel/PHPExcel/CalcEngine/Logger.php @@ -0,0 +1,153 @@ +_cellStack = $stack; + } + + /** + * Enable/Disable Calculation engine logging + * + * @param boolean $pValue + */ + public function setWriteDebugLog($pValue = FALSE) { + $this->_writeDebugLog = $pValue; + } + + /** + * Return whether calculation engine logging is enabled or disabled + * + * @return boolean + */ + public function getWriteDebugLog() { + return $this->_writeDebugLog; + } + + /** + * Enable/Disable echoing of debug log information + * + * @param boolean $pValue + */ + public function setEchoDebugLog($pValue = FALSE) { + $this->_echoDebugLog = $pValue; + } + + /** + * Return whether echoing of debug log information is enabled or disabled + * + * @return boolean + */ + public function getEchoDebugLog() { + return $this->_echoDebugLog; + } + + /** + * Write an entry to the calculation engine debug log + */ + public function writeDebugLog() { + // Only write the debug log if logging is enabled + if ($this->_writeDebugLog) { + $message = implode(func_get_args()); + $cellReference = implode(' -> ', $this->_cellStack->showStack()); + if ($this->_echoDebugLog) { + echo $cellReference, + ($this->_cellStack->count() > 0 ? ' => ' : ''), + $message, + PHP_EOL; + } + $this->_debugLog[] = $cellReference . + ($this->_cellStack->count() > 0 ? ' => ' : '') . + $message; + } + } // function _writeDebug() + + /** + * Clear the calculation engine debug log + */ + public function clearLog() { + $this->_debugLog = array(); + } // function flushLogger() + + /** + * Return the calculation engine debug log + * + * @return string[] + */ + public function getLog() { + return $this->_debugLog; + } // function flushLogger() + +} // class PHPExcel_CalcEngine_Logger + diff --git a/lib/phpexcel/PHPExcel/Calculation.php b/lib/phpexcel/PHPExcel/Calculation.php new file mode 100644 index 0000000..b609b0d --- /dev/null +++ b/lib/phpexcel/PHPExcel/Calculation.php @@ -0,0 +1,3933 @@ +=-]*)|(\'[^\']*\')|(\"[^\"]*\"))!)?\$?([a-z]{1,3})\$?(\d{1,7})'); + // Named Range of cells + define('CALCULATION_REGEXP_NAMEDRANGE','((([^\s,!&%^\/\*\+<>=-]*)|(\'[^\']*\')|(\"[^\"]*\"))!)?([_A-Z][_A-Z0-9\.]*)'); + } else { + // Cell reference (cell or range of cells, with or without a sheet reference) + define('CALCULATION_REGEXP_CELLREF','(((\w*)|(\'[^\']*\')|(\"[^\"]*\"))!)?\$?([a-z]{1,3})\$?(\d+)'); + // Named Range of cells + define('CALCULATION_REGEXP_NAMEDRANGE','(((\w*)|(\'.*\')|(\".*\"))!)?([_A-Z][_A-Z0-9\.]*)'); + } +} + + +/** + * PHPExcel_Calculation (Multiton) + * + * @category PHPExcel + * @package PHPExcel_Calculation + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Calculation { + + /** Constants */ + /** Regular Expressions */ + // Numeric operand + const CALCULATION_REGEXP_NUMBER = '[-+]?\d*\.?\d+(e[-+]?\d+)?'; + // String operand + const CALCULATION_REGEXP_STRING = '"(?:[^"]|"")*"'; + // Opening bracket + const CALCULATION_REGEXP_OPENBRACE = '\('; + // Function (allow for the old @ symbol that could be used to prefix a function, but we'll ignore it) + const CALCULATION_REGEXP_FUNCTION = '@?([A-Z][A-Z0-9\.]*)[\s]*\('; + // Cell reference (cell or range of cells, with or without a sheet reference) + const CALCULATION_REGEXP_CELLREF = CALCULATION_REGEXP_CELLREF; + // Named Range of cells + const CALCULATION_REGEXP_NAMEDRANGE = CALCULATION_REGEXP_NAMEDRANGE; + // Error + const CALCULATION_REGEXP_ERROR = '\#[A-Z][A-Z0_\/]*[!\?]?'; + + + /** constants */ + const RETURN_ARRAY_AS_ERROR = 'error'; + const RETURN_ARRAY_AS_VALUE = 'value'; + const RETURN_ARRAY_AS_ARRAY = 'array'; + + private static $returnArrayAsType = self::RETURN_ARRAY_AS_VALUE; + + + /** + * Instance of this class + * + * @access private + * @var PHPExcel_Calculation + */ + private static $_instance; + + + /** + * Instance of the workbook this Calculation Engine is using + * + * @access private + * @var PHPExcel + */ + private $_workbook; + + /** + * List of instances of the calculation engine that we've instantiated for individual workbooks + * + * @access private + * @var PHPExcel_Calculation[] + */ + private static $_workbookSets; + + /** + * Calculation cache + * + * @access private + * @var array + */ + private $_calculationCache = array (); + + + /** + * Calculation cache enabled + * + * @access private + * @var boolean + */ + private $_calculationCacheEnabled = TRUE; + + + /** + * List of operators that can be used within formulae + * The true/false value indicates whether it is a binary operator or a unary operator + * + * @access private + * @var array + */ + private static $_operators = array('+' => TRUE, '-' => TRUE, '*' => TRUE, '/' => TRUE, + '^' => TRUE, '&' => TRUE, '%' => FALSE, '~' => FALSE, + '>' => TRUE, '<' => TRUE, '=' => TRUE, '>=' => TRUE, + '<=' => TRUE, '<>' => TRUE, '|' => TRUE, ':' => TRUE + ); + + + /** + * List of binary operators (those that expect two operands) + * + * @access private + * @var array + */ + private static $_binaryOperators = array('+' => TRUE, '-' => TRUE, '*' => TRUE, '/' => TRUE, + '^' => TRUE, '&' => TRUE, '>' => TRUE, '<' => TRUE, + '=' => TRUE, '>=' => TRUE, '<=' => TRUE, '<>' => TRUE, + '|' => TRUE, ':' => TRUE + ); + + /** + * The debug log generated by the calculation engine + * + * @access private + * @var PHPExcel_CalcEngine_Logger + * + */ + private $debugLog; + + /** + * Flag to determine how formula errors should be handled + * If true, then a user error will be triggered + * If false, then an exception will be thrown + * + * @access public + * @var boolean + * + */ + public $suppressFormulaErrors = FALSE; + + /** + * Error message for any error that was raised/thrown by the calculation engine + * + * @access public + * @var string + * + */ + public $formulaError = NULL; + + /** + * An array of the nested cell references accessed by the calculation engine, used for the debug log + * + * @access private + * @var array of string + * + */ + private $_cyclicReferenceStack; + + /** + * Current iteration counter for cyclic formulae + * If the value is 0 (or less) then cyclic formulae will throw an exception, + * otherwise they will iterate to the limit defined here before returning a result + * + * @var integer + * + */ + private $_cyclicFormulaCount = 0; + + private $_cyclicFormulaCell = ''; + + /** + * Number of iterations for cyclic formulae + * + * @var integer + * + */ + public $cyclicFormulaCount = 0; + + /** + * Precision used for calculations + * + * @var integer + * + */ + private $_savedPrecision = 14; + + + /** + * The current locale setting + * + * @var string + * + */ + private static $_localeLanguage = 'en_us'; // US English (default locale) + + /** + * List of available locale settings + * Note that this is read for the locale subdirectory only when requested + * + * @var string[] + * + */ + private static $_validLocaleLanguages = array( 'en' // English (default language) + ); + /** + * Locale-specific argument separator for function arguments + * + * @var string + * + */ + private static $_localeArgumentSeparator = ','; + private static $_localeFunctions = array(); + + /** + * Locale-specific translations for Excel constants (True, False and Null) + * + * @var string[] + * + */ + public static $_localeBoolean = array( 'TRUE' => 'TRUE', + 'FALSE' => 'FALSE', + 'NULL' => 'NULL' + ); + + + /** + * Excel constant string translations to their PHP equivalents + * Constant conversion from text name/value to actual (datatyped) value + * + * @var string[] + * + */ + private static $_ExcelConstants = array('TRUE' => TRUE, + 'FALSE' => FALSE, + 'NULL' => NULL + ); + + // PHPExcel functions + private static $_PHPExcelFunctions = array( // PHPExcel functions + 'ABS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'abs', + 'argumentCount' => '1' + ), + 'ACCRINT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::ACCRINT', + 'argumentCount' => '4-7' + ), + 'ACCRINTM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::ACCRINTM', + 'argumentCount' => '3-5' + ), + 'ACOS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'acos', + 'argumentCount' => '1' + ), + 'ACOSH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'acosh', + 'argumentCount' => '1' + ), + 'ADDRESS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::CELL_ADDRESS', + 'argumentCount' => '2-5' + ), + 'AMORDEGRC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::AMORDEGRC', + 'argumentCount' => '6,7' + ), + 'AMORLINC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::AMORLINC', + 'argumentCount' => '6,7' + ), + 'AND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::LOGICAL_AND', + 'argumentCount' => '1+' + ), + 'AREAS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'ASC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'ASIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'asin', + 'argumentCount' => '1' + ), + 'ASINH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'asinh', + 'argumentCount' => '1' + ), + 'ATAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'atan', + 'argumentCount' => '1' + ), + 'ATAN2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::ATAN2', + 'argumentCount' => '2' + ), + 'ATANH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'atanh', + 'argumentCount' => '1' + ), + 'AVEDEV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::AVEDEV', + 'argumentCount' => '1+' + ), + 'AVERAGE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::AVERAGE', + 'argumentCount' => '1+' + ), + 'AVERAGEA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::AVERAGEA', + 'argumentCount' => '1+' + ), + 'AVERAGEIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::AVERAGEIF', + 'argumentCount' => '2,3' + ), + 'AVERAGEIFS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '3+' + ), + 'BAHTTEXT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'BESSELI' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELI', + 'argumentCount' => '2' + ), + 'BESSELJ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELJ', + 'argumentCount' => '2' + ), + 'BESSELK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELK', + 'argumentCount' => '2' + ), + 'BESSELY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELY', + 'argumentCount' => '2' + ), + 'BETADIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::BETADIST', + 'argumentCount' => '3-5' + ), + 'BETAINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::BETAINV', + 'argumentCount' => '3-5' + ), + 'BIN2DEC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BINTODEC', + 'argumentCount' => '1' + ), + 'BIN2HEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BINTOHEX', + 'argumentCount' => '1,2' + ), + 'BIN2OCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BINTOOCT', + 'argumentCount' => '1,2' + ), + 'BINOMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::BINOMDIST', + 'argumentCount' => '4' + ), + 'CEILING' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::CEILING', + 'argumentCount' => '2' + ), + 'CELL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1,2' + ), + 'CHAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::CHARACTER', + 'argumentCount' => '1' + ), + 'CHIDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::CHIDIST', + 'argumentCount' => '2' + ), + 'CHIINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::CHIINV', + 'argumentCount' => '2' + ), + 'CHITEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2' + ), + 'CHOOSE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::CHOOSE', + 'argumentCount' => '2+' + ), + 'CLEAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::TRIMNONPRINTABLE', + 'argumentCount' => '1' + ), + 'CODE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::ASCIICODE', + 'argumentCount' => '1' + ), + 'COLUMN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::COLUMN', + 'argumentCount' => '-1', + 'passByReference' => array(TRUE) + ), + 'COLUMNS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::COLUMNS', + 'argumentCount' => '1' + ), + 'COMBIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::COMBIN', + 'argumentCount' => '2' + ), + 'COMPLEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::COMPLEX', + 'argumentCount' => '2,3' + ), + 'CONCATENATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::CONCATENATE', + 'argumentCount' => '1+' + ), + 'CONFIDENCE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::CONFIDENCE', + 'argumentCount' => '3' + ), + 'CONVERT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::CONVERTUOM', + 'argumentCount' => '3' + ), + 'CORREL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::CORREL', + 'argumentCount' => '2' + ), + 'COS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'cos', + 'argumentCount' => '1' + ), + 'COSH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'cosh', + 'argumentCount' => '1' + ), + 'COUNT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNT', + 'argumentCount' => '1+' + ), + 'COUNTA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNTA', + 'argumentCount' => '1+' + ), + 'COUNTBLANK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNTBLANK', + 'argumentCount' => '1' + ), + 'COUNTIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNTIF', + 'argumentCount' => '2' + ), + 'COUNTIFS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2' + ), + 'COUPDAYBS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::COUPDAYBS', + 'argumentCount' => '3,4' + ), + 'COUPDAYS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::COUPDAYS', + 'argumentCount' => '3,4' + ), + 'COUPDAYSNC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::COUPDAYSNC', + 'argumentCount' => '3,4' + ), + 'COUPNCD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::COUPNCD', + 'argumentCount' => '3,4' + ), + 'COUPNUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::COUPNUM', + 'argumentCount' => '3,4' + ), + 'COUPPCD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::COUPPCD', + 'argumentCount' => '3,4' + ), + 'COVAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::COVAR', + 'argumentCount' => '2' + ), + 'CRITBINOM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::CRITBINOM', + 'argumentCount' => '3' + ), + 'CUBEKPIMEMBER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUBEMEMBER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUBEMEMBERPROPERTY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUBERANKEDMEMBER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUBESET' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUBESETCOUNT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUBEVALUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUMIPMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::CUMIPMT', + 'argumentCount' => '6' + ), + 'CUMPRINC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::CUMPRINC', + 'argumentCount' => '6' + ), + 'DATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DATE', + 'argumentCount' => '3' + ), + 'DATEDIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DATEDIF', + 'argumentCount' => '2,3' + ), + 'DATEVALUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DATEVALUE', + 'argumentCount' => '1' + ), + 'DAVERAGE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DAVERAGE', + 'argumentCount' => '3' + ), + 'DAY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DAYOFMONTH', + 'argumentCount' => '1' + ), + 'DAYS360' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DAYS360', + 'argumentCount' => '2,3' + ), + 'DB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::DB', + 'argumentCount' => '4,5' + ), + 'DCOUNT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DCOUNT', + 'argumentCount' => '3' + ), + 'DCOUNTA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DCOUNTA', + 'argumentCount' => '3' + ), + 'DDB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::DDB', + 'argumentCount' => '4,5' + ), + 'DEC2BIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::DECTOBIN', + 'argumentCount' => '1,2' + ), + 'DEC2HEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::DECTOHEX', + 'argumentCount' => '1,2' + ), + 'DEC2OCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::DECTOOCT', + 'argumentCount' => '1,2' + ), + 'DEGREES' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'rad2deg', + 'argumentCount' => '1' + ), + 'DELTA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::DELTA', + 'argumentCount' => '1,2' + ), + 'DEVSQ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::DEVSQ', + 'argumentCount' => '1+' + ), + 'DGET' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DGET', + 'argumentCount' => '3' + ), + 'DISC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::DISC', + 'argumentCount' => '4,5' + ), + 'DMAX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DMAX', + 'argumentCount' => '3' + ), + 'DMIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DMIN', + 'argumentCount' => '3' + ), + 'DOLLAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::DOLLAR', + 'argumentCount' => '1,2' + ), + 'DOLLARDE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::DOLLARDE', + 'argumentCount' => '2' + ), + 'DOLLARFR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::DOLLARFR', + 'argumentCount' => '2' + ), + 'DPRODUCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DPRODUCT', + 'argumentCount' => '3' + ), + 'DSTDEV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DSTDEV', + 'argumentCount' => '3' + ), + 'DSTDEVP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DSTDEVP', + 'argumentCount' => '3' + ), + 'DSUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DSUM', + 'argumentCount' => '3' + ), + 'DURATION' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '5,6' + ), + 'DVAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DVAR', + 'argumentCount' => '3' + ), + 'DVARP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DVARP', + 'argumentCount' => '3' + ), + 'EDATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::EDATE', + 'argumentCount' => '2' + ), + 'EFFECT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::EFFECT', + 'argumentCount' => '2' + ), + 'EOMONTH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::EOMONTH', + 'argumentCount' => '2' + ), + 'ERF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::ERF', + 'argumentCount' => '1,2' + ), + 'ERFC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::ERFC', + 'argumentCount' => '1' + ), + 'ERROR.TYPE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::ERROR_TYPE', + 'argumentCount' => '1' + ), + 'EVEN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::EVEN', + 'argumentCount' => '1' + ), + 'EXACT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2' + ), + 'EXP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'exp', + 'argumentCount' => '1' + ), + 'EXPONDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::EXPONDIST', + 'argumentCount' => '3' + ), + 'FACT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::FACT', + 'argumentCount' => '1' + ), + 'FACTDOUBLE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::FACTDOUBLE', + 'argumentCount' => '1' + ), + 'FALSE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::FALSE', + 'argumentCount' => '0' + ), + 'FDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '3' + ), + 'FIND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHSENSITIVE', + 'argumentCount' => '2,3' + ), + 'FINDB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHSENSITIVE', + 'argumentCount' => '2,3' + ), + 'FINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '3' + ), + 'FISHER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::FISHER', + 'argumentCount' => '1' + ), + 'FISHERINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::FISHERINV', + 'argumentCount' => '1' + ), + 'FIXED' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::FIXEDFORMAT', + 'argumentCount' => '1-3' + ), + 'FLOOR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::FLOOR', + 'argumentCount' => '2' + ), + 'FORECAST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::FORECAST', + 'argumentCount' => '3' + ), + 'FREQUENCY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2' + ), + 'FTEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2' + ), + 'FV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::FV', + 'argumentCount' => '3-5' + ), + 'FVSCHEDULE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::FVSCHEDULE', + 'argumentCount' => '2' + ), + 'GAMMADIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::GAMMADIST', + 'argumentCount' => '4' + ), + 'GAMMAINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::GAMMAINV', + 'argumentCount' => '3' + ), + 'GAMMALN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::GAMMALN', + 'argumentCount' => '1' + ), + 'GCD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::GCD', + 'argumentCount' => '1+' + ), + 'GEOMEAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::GEOMEAN', + 'argumentCount' => '1+' + ), + 'GESTEP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::GESTEP', + 'argumentCount' => '1,2' + ), + 'GETPIVOTDATA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2+' + ), + 'GROWTH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::GROWTH', + 'argumentCount' => '1-4' + ), + 'HARMEAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::HARMEAN', + 'argumentCount' => '1+' + ), + 'HEX2BIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::HEXTOBIN', + 'argumentCount' => '1,2' + ), + 'HEX2DEC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::HEXTODEC', + 'argumentCount' => '1' + ), + 'HEX2OCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::HEXTOOCT', + 'argumentCount' => '1,2' + ), + 'HLOOKUP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::HLOOKUP', + 'argumentCount' => '3,4' + ), + 'HOUR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::HOUROFDAY', + 'argumentCount' => '1' + ), + 'HYPERLINK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::HYPERLINK', + 'argumentCount' => '1,2', + 'passCellReference'=> TRUE + ), + 'HYPGEOMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::HYPGEOMDIST', + 'argumentCount' => '4' + ), + 'IF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::STATEMENT_IF', + 'argumentCount' => '1-3' + ), + 'IFERROR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::IFERROR', + 'argumentCount' => '2' + ), + 'IMABS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMABS', + 'argumentCount' => '1' + ), + 'IMAGINARY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMAGINARY', + 'argumentCount' => '1' + ), + 'IMARGUMENT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMARGUMENT', + 'argumentCount' => '1' + ), + 'IMCONJUGATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMCONJUGATE', + 'argumentCount' => '1' + ), + 'IMCOS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMCOS', + 'argumentCount' => '1' + ), + 'IMDIV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMDIV', + 'argumentCount' => '2' + ), + 'IMEXP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMEXP', + 'argumentCount' => '1' + ), + 'IMLN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMLN', + 'argumentCount' => '1' + ), + 'IMLOG10' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMLOG10', + 'argumentCount' => '1' + ), + 'IMLOG2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMLOG2', + 'argumentCount' => '1' + ), + 'IMPOWER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMPOWER', + 'argumentCount' => '2' + ), + 'IMPRODUCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMPRODUCT', + 'argumentCount' => '1+' + ), + 'IMREAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMREAL', + 'argumentCount' => '1' + ), + 'IMSIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSIN', + 'argumentCount' => '1' + ), + 'IMSQRT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSQRT', + 'argumentCount' => '1' + ), + 'IMSUB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSUB', + 'argumentCount' => '2' + ), + 'IMSUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSUM', + 'argumentCount' => '1+' + ), + 'INDEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::INDEX', + 'argumentCount' => '1-4' + ), + 'INDIRECT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::INDIRECT', + 'argumentCount' => '1,2', + 'passCellReference'=> TRUE + ), + 'INFO' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'INT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::INT', + 'argumentCount' => '1' + ), + 'INTERCEPT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::INTERCEPT', + 'argumentCount' => '2' + ), + 'INTRATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::INTRATE', + 'argumentCount' => '4,5' + ), + 'IPMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::IPMT', + 'argumentCount' => '4-6' + ), + 'IRR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::IRR', + 'argumentCount' => '1,2' + ), + 'ISBLANK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_BLANK', + 'argumentCount' => '1' + ), + 'ISERR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_ERR', + 'argumentCount' => '1' + ), + 'ISERROR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_ERROR', + 'argumentCount' => '1' + ), + 'ISEVEN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_EVEN', + 'argumentCount' => '1' + ), + 'ISLOGICAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_LOGICAL', + 'argumentCount' => '1' + ), + 'ISNA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_NA', + 'argumentCount' => '1' + ), + 'ISNONTEXT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_NONTEXT', + 'argumentCount' => '1' + ), + 'ISNUMBER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_NUMBER', + 'argumentCount' => '1' + ), + 'ISODD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_ODD', + 'argumentCount' => '1' + ), + 'ISPMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::ISPMT', + 'argumentCount' => '4' + ), + 'ISREF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'ISTEXT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_TEXT', + 'argumentCount' => '1' + ), + 'JIS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'KURT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::KURT', + 'argumentCount' => '1+' + ), + 'LARGE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::LARGE', + 'argumentCount' => '2' + ), + 'LCM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::LCM', + 'argumentCount' => '1+' + ), + 'LEFT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::LEFT', + 'argumentCount' => '1,2' + ), + 'LEFTB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::LEFT', + 'argumentCount' => '1,2' + ), + 'LEN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::STRINGLENGTH', + 'argumentCount' => '1' + ), + 'LENB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::STRINGLENGTH', + 'argumentCount' => '1' + ), + 'LINEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::LINEST', + 'argumentCount' => '1-4' + ), + 'LN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'log', + 'argumentCount' => '1' + ), + 'LOG' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::LOG_BASE', + 'argumentCount' => '1,2' + ), + 'LOG10' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'log10', + 'argumentCount' => '1' + ), + 'LOGEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::LOGEST', + 'argumentCount' => '1-4' + ), + 'LOGINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::LOGINV', + 'argumentCount' => '3' + ), + 'LOGNORMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::LOGNORMDIST', + 'argumentCount' => '3' + ), + 'LOOKUP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::LOOKUP', + 'argumentCount' => '2,3' + ), + 'LOWER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::LOWERCASE', + 'argumentCount' => '1' + ), + 'MATCH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::MATCH', + 'argumentCount' => '2,3' + ), + 'MAX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MAX', + 'argumentCount' => '1+' + ), + 'MAXA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MAXA', + 'argumentCount' => '1+' + ), + 'MAXIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MAXIF', + 'argumentCount' => '2+' + ), + 'MDETERM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::MDETERM', + 'argumentCount' => '1' + ), + 'MDURATION' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '5,6' + ), + 'MEDIAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MEDIAN', + 'argumentCount' => '1+' + ), + 'MEDIANIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2+' + ), + 'MID' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::MID', + 'argumentCount' => '3' + ), + 'MIDB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::MID', + 'argumentCount' => '3' + ), + 'MIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MIN', + 'argumentCount' => '1+' + ), + 'MINA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MINA', + 'argumentCount' => '1+' + ), + 'MINIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MINIF', + 'argumentCount' => '2+' + ), + 'MINUTE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::MINUTEOFHOUR', + 'argumentCount' => '1' + ), + 'MINVERSE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::MINVERSE', + 'argumentCount' => '1' + ), + 'MIRR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::MIRR', + 'argumentCount' => '3' + ), + 'MMULT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::MMULT', + 'argumentCount' => '2' + ), + 'MOD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::MOD', + 'argumentCount' => '2' + ), + 'MODE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MODE', + 'argumentCount' => '1+' + ), + 'MONTH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::MONTHOFYEAR', + 'argumentCount' => '1' + ), + 'MROUND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::MROUND', + 'argumentCount' => '2' + ), + 'MULTINOMIAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::MULTINOMIAL', + 'argumentCount' => '1+' + ), + 'N' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::N', + 'argumentCount' => '1' + ), + 'NA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::NA', + 'argumentCount' => '0' + ), + 'NEGBINOMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::NEGBINOMDIST', + 'argumentCount' => '3' + ), + 'NETWORKDAYS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::NETWORKDAYS', + 'argumentCount' => '2+' + ), + 'NOMINAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::NOMINAL', + 'argumentCount' => '2' + ), + 'NORMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMDIST', + 'argumentCount' => '4' + ), + 'NORMINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMINV', + 'argumentCount' => '3' + ), + 'NORMSDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMSDIST', + 'argumentCount' => '1' + ), + 'NORMSINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMSINV', + 'argumentCount' => '1' + ), + 'NOT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::NOT', + 'argumentCount' => '1' + ), + 'NOW' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DATETIMENOW', + 'argumentCount' => '0' + ), + 'NPER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::NPER', + 'argumentCount' => '3-5' + ), + 'NPV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::NPV', + 'argumentCount' => '2+' + ), + 'OCT2BIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::OCTTOBIN', + 'argumentCount' => '1,2' + ), + 'OCT2DEC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::OCTTODEC', + 'argumentCount' => '1' + ), + 'OCT2HEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::OCTTOHEX', + 'argumentCount' => '1,2' + ), + 'ODD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::ODD', + 'argumentCount' => '1' + ), + 'ODDFPRICE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '8,9' + ), + 'ODDFYIELD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '8,9' + ), + 'ODDLPRICE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '7,8' + ), + 'ODDLYIELD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '7,8' + ), + 'OFFSET' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::OFFSET', + 'argumentCount' => '3,5', + 'passCellReference'=> TRUE, + 'passByReference' => array(TRUE) + ), + 'OR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::LOGICAL_OR', + 'argumentCount' => '1+' + ), + 'PEARSON' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::CORREL', + 'argumentCount' => '2' + ), + 'PERCENTILE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::PERCENTILE', + 'argumentCount' => '2' + ), + 'PERCENTRANK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::PERCENTRANK', + 'argumentCount' => '2,3' + ), + 'PERMUT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::PERMUT', + 'argumentCount' => '2' + ), + 'PHONETIC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'PI' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'pi', + 'argumentCount' => '0' + ), + 'PMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::PMT', + 'argumentCount' => '3-5' + ), + 'POISSON' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::POISSON', + 'argumentCount' => '3' + ), + 'POWER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::POWER', + 'argumentCount' => '2' + ), + 'PPMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::PPMT', + 'argumentCount' => '4-6' + ), + 'PRICE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::PRICE', + 'argumentCount' => '6,7' + ), + 'PRICEDISC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::PRICEDISC', + 'argumentCount' => '4,5' + ), + 'PRICEMAT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::PRICEMAT', + 'argumentCount' => '5,6' + ), + 'PROB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '3,4' + ), + 'PRODUCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::PRODUCT', + 'argumentCount' => '1+' + ), + 'PROPER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::PROPERCASE', + 'argumentCount' => '1' + ), + 'PV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::PV', + 'argumentCount' => '3-5' + ), + 'QUARTILE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::QUARTILE', + 'argumentCount' => '2' + ), + 'QUOTIENT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::QUOTIENT', + 'argumentCount' => '2' + ), + 'RADIANS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'deg2rad', + 'argumentCount' => '1' + ), + 'RAND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::RAND', + 'argumentCount' => '0' + ), + 'RANDBETWEEN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::RAND', + 'argumentCount' => '2' + ), + 'RANK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::RANK', + 'argumentCount' => '2,3' + ), + 'RATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::RATE', + 'argumentCount' => '3-6' + ), + 'RECEIVED' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::RECEIVED', + 'argumentCount' => '4-5' + ), + 'REPLACE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::REPLACE', + 'argumentCount' => '4' + ), + 'REPLACEB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::REPLACE', + 'argumentCount' => '4' + ), + 'REPT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'str_repeat', + 'argumentCount' => '2' + ), + 'RIGHT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::RIGHT', + 'argumentCount' => '1,2' + ), + 'RIGHTB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::RIGHT', + 'argumentCount' => '1,2' + ), + 'ROMAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::ROMAN', + 'argumentCount' => '1,2' + ), + 'ROUND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'round', + 'argumentCount' => '2' + ), + 'ROUNDDOWN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::ROUNDDOWN', + 'argumentCount' => '2' + ), + 'ROUNDUP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::ROUNDUP', + 'argumentCount' => '2' + ), + 'ROW' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::ROW', + 'argumentCount' => '-1', + 'passByReference' => array(TRUE) + ), + 'ROWS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::ROWS', + 'argumentCount' => '1' + ), + 'RSQ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::RSQ', + 'argumentCount' => '2' + ), + 'RTD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1+' + ), + 'SEARCH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHINSENSITIVE', + 'argumentCount' => '2,3' + ), + 'SEARCHB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHINSENSITIVE', + 'argumentCount' => '2,3' + ), + 'SECOND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::SECONDOFMINUTE', + 'argumentCount' => '1' + ), + 'SERIESSUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SERIESSUM', + 'argumentCount' => '4' + ), + 'SIGN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SIGN', + 'argumentCount' => '1' + ), + 'SIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'sin', + 'argumentCount' => '1' + ), + 'SINH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'sinh', + 'argumentCount' => '1' + ), + 'SKEW' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::SKEW', + 'argumentCount' => '1+' + ), + 'SLN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::SLN', + 'argumentCount' => '3' + ), + 'SLOPE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::SLOPE', + 'argumentCount' => '2' + ), + 'SMALL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::SMALL', + 'argumentCount' => '2' + ), + 'SQRT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'sqrt', + 'argumentCount' => '1' + ), + 'SQRTPI' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SQRTPI', + 'argumentCount' => '1' + ), + 'STANDARDIZE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::STANDARDIZE', + 'argumentCount' => '3' + ), + 'STDEV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEV', + 'argumentCount' => '1+' + ), + 'STDEVA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEVA', + 'argumentCount' => '1+' + ), + 'STDEVP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEVP', + 'argumentCount' => '1+' + ), + 'STDEVPA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEVPA', + 'argumentCount' => '1+' + ), + 'STEYX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::STEYX', + 'argumentCount' => '2' + ), + 'SUBSTITUTE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::SUBSTITUTE', + 'argumentCount' => '3,4' + ), + 'SUBTOTAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUBTOTAL', + 'argumentCount' => '2+' + ), + 'SUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUM', + 'argumentCount' => '1+' + ), + 'SUMIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMIF', + 'argumentCount' => '2,3' + ), + 'SUMIFS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'SUMPRODUCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMPRODUCT', + 'argumentCount' => '1+' + ), + 'SUMSQ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMSQ', + 'argumentCount' => '1+' + ), + 'SUMX2MY2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMX2MY2', + 'argumentCount' => '2' + ), + 'SUMX2PY2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMX2PY2', + 'argumentCount' => '2' + ), + 'SUMXMY2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMXMY2', + 'argumentCount' => '2' + ), + 'SYD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::SYD', + 'argumentCount' => '4' + ), + 'T' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::RETURNSTRING', + 'argumentCount' => '1' + ), + 'TAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'tan', + 'argumentCount' => '1' + ), + 'TANH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'tanh', + 'argumentCount' => '1' + ), + 'TBILLEQ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::TBILLEQ', + 'argumentCount' => '3' + ), + 'TBILLPRICE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::TBILLPRICE', + 'argumentCount' => '3' + ), + 'TBILLYIELD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::TBILLYIELD', + 'argumentCount' => '3' + ), + 'TDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::TDIST', + 'argumentCount' => '3' + ), + 'TEXT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::TEXTFORMAT', + 'argumentCount' => '2' + ), + 'TIME' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::TIME', + 'argumentCount' => '3' + ), + 'TIMEVALUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::TIMEVALUE', + 'argumentCount' => '1' + ), + 'TINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::TINV', + 'argumentCount' => '2' + ), + 'TODAY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DATENOW', + 'argumentCount' => '0' + ), + 'TRANSPOSE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::TRANSPOSE', + 'argumentCount' => '1' + ), + 'TREND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::TREND', + 'argumentCount' => '1-4' + ), + 'TRIM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::TRIMSPACES', + 'argumentCount' => '1' + ), + 'TRIMMEAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::TRIMMEAN', + 'argumentCount' => '2' + ), + 'TRUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::TRUE', + 'argumentCount' => '0' + ), + 'TRUNC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::TRUNC', + 'argumentCount' => '1,2' + ), + 'TTEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '4' + ), + 'TYPE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::TYPE', + 'argumentCount' => '1' + ), + 'UPPER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::UPPERCASE', + 'argumentCount' => '1' + ), + 'USDOLLAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2' + ), + 'VALUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'VAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::VARFunc', + 'argumentCount' => '1+' + ), + 'VARA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::VARA', + 'argumentCount' => '1+' + ), + 'VARP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::VARP', + 'argumentCount' => '1+' + ), + 'VARPA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::VARPA', + 'argumentCount' => '1+' + ), + 'VDB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '5-7' + ), + 'VERSION' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::VERSION', + 'argumentCount' => '0' + ), + 'VLOOKUP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::VLOOKUP', + 'argumentCount' => '3,4' + ), + 'WEEKDAY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DAYOFWEEK', + 'argumentCount' => '1,2' + ), + 'WEEKNUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::WEEKOFYEAR', + 'argumentCount' => '1,2' + ), + 'WEIBULL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::WEIBULL', + 'argumentCount' => '4' + ), + 'WORKDAY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::WORKDAY', + 'argumentCount' => '2+' + ), + 'XIRR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::XIRR', + 'argumentCount' => '2,3' + ), + 'XNPV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::XNPV', + 'argumentCount' => '3' + ), + 'YEAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::YEAR', + 'argumentCount' => '1' + ), + 'YEARFRAC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::YEARFRAC', + 'argumentCount' => '2,3' + ), + 'YIELD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '6,7' + ), + 'YIELDDISC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::YIELDDISC', + 'argumentCount' => '4,5' + ), + 'YIELDMAT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::YIELDMAT', + 'argumentCount' => '5,6' + ), + 'ZTEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::ZTEST', + 'argumentCount' => '2-3' + ) + ); + + + // Internal functions used for special control purposes + private static $_controlFunctions = array( + 'MKMATRIX' => array('argumentCount' => '*', + 'functionCall' => 'self::_mkMatrix' + ) + ); + + + + + private function __construct(PHPExcel $workbook = NULL) { + $setPrecision = (PHP_INT_SIZE == 4) ? 14 : 16; + $this->_savedPrecision = ini_get('precision'); + if ($this->_savedPrecision < $setPrecision) { + ini_set('precision',$setPrecision); + } + + if ($workbook !== NULL) { + self::$_workbookSets[$workbook->getID()] = $this; + } + + $this->_workbook = $workbook; + $this->_cyclicReferenceStack = new PHPExcel_CalcEngine_CyclicReferenceStack(); + $this->_debugLog = new PHPExcel_CalcEngine_Logger($this->_cyclicReferenceStack); + } // function __construct() + + + public function __destruct() { + if ($this->_savedPrecision != ini_get('precision')) { + ini_set('precision',$this->_savedPrecision); + } + } + + private static function _loadLocales() { + $localeFileDirectory = PHPEXCEL_ROOT.'PHPExcel/locale/'; + foreach (glob($localeFileDirectory.'/*',GLOB_ONLYDIR) as $filename) { + $filename = substr($filename,strlen($localeFileDirectory)+1); + if ($filename != 'en') { + self::$_validLocaleLanguages[] = $filename; + } + } + } + + /** + * Get an instance of this class + * + * @access public + * @param PHPExcel $workbook Injected workbook for working with a PHPExcel object, + * or NULL to create a standalone claculation engine + * @return PHPExcel_Calculation + */ + public static function getInstance(PHPExcel $workbook = NULL) { + if ($workbook !== NULL) { + if (isset(self::$_workbookSets[$workbook->getID()])) { + return self::$_workbookSets[$workbook->getID()]; + } + return new PHPExcel_Calculation($workbook); + } + + if (!isset(self::$_instance) || (self::$_instance === NULL)) { + self::$_instance = new PHPExcel_Calculation(); + } + + return self::$_instance; + } // function getInstance() + + /** + * Unset an instance of this class + * + * @access public + * @param PHPExcel $workbook Injected workbook identifying the instance to unset + */ + public static function unsetInstance(PHPExcel $workbook = NULL) { + if ($workbook !== NULL) { + if (isset(self::$_workbookSets[$workbook->getID()])) { + unset(self::$_workbookSets[$workbook->getID()]); + } + } + } + + /** + * Flush the calculation cache for any existing instance of this class + * but only if a PHPExcel_Calculation instance exists + * + * @access public + * @return null + */ + public function flushInstance() { + $this->clearCalculationCache(); + } // function flushInstance() + + + /** + * Get the debuglog for this claculation engine instance + * + * @access public + * @return PHPExcel_CalcEngine_Logger + */ + public function getDebugLog() { + return $this->_debugLog; + } + + /** + * __clone implementation. Cloning should not be allowed in a Singleton! + * + * @access public + * @throws PHPExcel_Calculation_Exception + */ + public final function __clone() { + throw new PHPExcel_Calculation_Exception ('Cloning the calculation engine is not allowed!'); + } // function __clone() + + + /** + * Return the locale-specific translation of TRUE + * + * @access public + * @return string locale-specific translation of TRUE + */ + public static function getTRUE() { + return self::$_localeBoolean['TRUE']; + } + + /** + * Return the locale-specific translation of FALSE + * + * @access public + * @return string locale-specific translation of FALSE + */ + public static function getFALSE() { + return self::$_localeBoolean['FALSE']; + } + + /** + * Set the Array Return Type (Array or Value of first element in the array) + * + * @access public + * @param string $returnType Array return type + * @return boolean Success or failure + */ + public static function setArrayReturnType($returnType) { + if (($returnType == self::RETURN_ARRAY_AS_VALUE) || + ($returnType == self::RETURN_ARRAY_AS_ERROR) || + ($returnType == self::RETURN_ARRAY_AS_ARRAY)) { + self::$returnArrayAsType = $returnType; + return TRUE; + } + return FALSE; + } // function setArrayReturnType() + + + /** + * Return the Array Return Type (Array or Value of first element in the array) + * + * @access public + * @return string $returnType Array return type + */ + public static function getArrayReturnType() { + return self::$returnArrayAsType; + } // function getArrayReturnType() + + + /** + * Is calculation caching enabled? + * + * @access public + * @return boolean + */ + public function getCalculationCacheEnabled() { + return $this->_calculationCacheEnabled; + } // function getCalculationCacheEnabled() + + /** + * Enable/disable calculation cache + * + * @access public + * @param boolean $pValue + */ + public function setCalculationCacheEnabled($pValue = TRUE) { + $this->_calculationCacheEnabled = $pValue; + $this->clearCalculationCache(); + } // function setCalculationCacheEnabled() + + + /** + * Enable calculation cache + */ + public function enableCalculationCache() { + $this->setCalculationCacheEnabled(TRUE); + } // function enableCalculationCache() + + + /** + * Disable calculation cache + */ + public function disableCalculationCache() { + $this->setCalculationCacheEnabled(FALSE); + } // function disableCalculationCache() + + + /** + * Clear calculation cache + */ + public function clearCalculationCache() { + $this->_calculationCache = array(); + } // function clearCalculationCache() + + /** + * Clear calculation cache for a specified worksheet + * + * @param string $worksheetName + */ + public function clearCalculationCacheForWorksheet($worksheetName) { + if (isset($this->_calculationCache[$worksheetName])) { + unset($this->_calculationCache[$worksheetName]); + } + } // function clearCalculationCacheForWorksheet() + + /** + * Rename calculation cache for a specified worksheet + * + * @param string $fromWorksheetName + * @param string $toWorksheetName + */ + public function renameCalculationCacheForWorksheet($fromWorksheetName, $toWorksheetName) { + if (isset($this->_calculationCache[$fromWorksheetName])) { + $this->_calculationCache[$toWorksheetName] = &$this->_calculationCache[$fromWorksheetName]; + unset($this->_calculationCache[$fromWorksheetName]); + } + } // function renameCalculationCacheForWorksheet() + + + /** + * Get the currently defined locale code + * + * @return string + */ + public function getLocale() { + return self::$_localeLanguage; + } // function getLocale() + + + /** + * Set the locale code + * + * @param string $locale The locale to use for formula translation + * @return boolean + */ + public function setLocale($locale = 'en_us') { + // Identify our locale and language + $language = $locale = strtolower($locale); + if (strpos($locale,'_') !== FALSE) { + list($language) = explode('_',$locale); + } + + if (count(self::$_validLocaleLanguages) == 1) + self::_loadLocales(); + + // Test whether we have any language data for this language (any locale) + if (in_array($language,self::$_validLocaleLanguages)) { + // initialise language/locale settings + self::$_localeFunctions = array(); + self::$_localeArgumentSeparator = ','; + self::$_localeBoolean = array('TRUE' => 'TRUE', 'FALSE' => 'FALSE', 'NULL' => 'NULL'); + // Default is English, if user isn't requesting english, then read the necessary data from the locale files + if ($locale != 'en_us') { + // Search for a file with a list of function names for locale + $functionNamesFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.str_replace('_',DIRECTORY_SEPARATOR,$locale).DIRECTORY_SEPARATOR.'functions'; + if (!file_exists($functionNamesFile)) { + // If there isn't a locale specific function file, look for a language specific function file + $functionNamesFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.$language.DIRECTORY_SEPARATOR.'functions'; + if (!file_exists($functionNamesFile)) { + return FALSE; + } + } + // Retrieve the list of locale or language specific function names + $localeFunctions = file($functionNamesFile,FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); + foreach ($localeFunctions as $localeFunction) { + list($localeFunction) = explode('##',$localeFunction); // Strip out comments + if (strpos($localeFunction,'=') !== FALSE) { + list($fName,$lfName) = explode('=',$localeFunction); + $fName = trim($fName); + $lfName = trim($lfName); + if ((isset(self::$_PHPExcelFunctions[$fName])) && ($lfName != '') && ($fName != $lfName)) { + self::$_localeFunctions[$fName] = $lfName; + } + } + } + // Default the TRUE and FALSE constants to the locale names of the TRUE() and FALSE() functions + if (isset(self::$_localeFunctions['TRUE'])) { self::$_localeBoolean['TRUE'] = self::$_localeFunctions['TRUE']; } + if (isset(self::$_localeFunctions['FALSE'])) { self::$_localeBoolean['FALSE'] = self::$_localeFunctions['FALSE']; } + + $configFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.str_replace('_',DIRECTORY_SEPARATOR,$locale).DIRECTORY_SEPARATOR.'config'; + if (!file_exists($configFile)) { + $configFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.$language.DIRECTORY_SEPARATOR.'config'; + } + if (file_exists($configFile)) { + $localeSettings = file($configFile,FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); + foreach ($localeSettings as $localeSetting) { + list($localeSetting) = explode('##',$localeSetting); // Strip out comments + if (strpos($localeSetting,'=') !== FALSE) { + list($settingName,$settingValue) = explode('=',$localeSetting); + $settingName = strtoupper(trim($settingName)); + switch ($settingName) { + case 'ARGUMENTSEPARATOR' : + self::$_localeArgumentSeparator = trim($settingValue); + break; + } + } + } + } + } + + self::$functionReplaceFromExcel = self::$functionReplaceToExcel = + self::$functionReplaceFromLocale = self::$functionReplaceToLocale = NULL; + self::$_localeLanguage = $locale; + return TRUE; + } + return FALSE; + } // function setLocale() + + + + public static function _translateSeparator($fromSeparator,$toSeparator,$formula,&$inBraces) { + $strlen = mb_strlen($formula); + for ($i = 0; $i < $strlen; ++$i) { + $chr = mb_substr($formula,$i,1); + switch ($chr) { + case '{' : $inBraces = TRUE; + break; + case '}' : $inBraces = FALSE; + break; + case $fromSeparator : + if (!$inBraces) { + $formula = mb_substr($formula,0,$i).$toSeparator.mb_substr($formula,$i+1); + } + } + } + return $formula; + } + + private static function _translateFormula($from,$to,$formula,$fromSeparator,$toSeparator) { + // Convert any Excel function names to the required language + if (self::$_localeLanguage !== 'en_us') { + $inBraces = FALSE; + // If there is the possibility of braces within a quoted string, then we don't treat those as matrix indicators + if (strpos($formula,'"') !== FALSE) { + // So instead we skip replacing in any quoted strings by only replacing in every other array element after we've exploded + // the formula + $temp = explode('"',$formula); + $i = FALSE; + foreach($temp as &$value) { + // Only count/replace in alternating array entries + if ($i = !$i) { + $value = preg_replace($from,$to,$value); + $value = self::_translateSeparator($fromSeparator,$toSeparator,$value,$inBraces); + } + } + unset($value); + // Then rebuild the formula string + $formula = implode('"',$temp); + } else { + // If there's no quoted strings, then we do a simple count/replace + $formula = preg_replace($from,$to,$formula); + $formula = self::_translateSeparator($fromSeparator,$toSeparator,$formula,$inBraces); + } + } + + return $formula; + } + + private static $functionReplaceFromExcel = NULL; + private static $functionReplaceToLocale = NULL; + + public function _translateFormulaToLocale($formula) { + if (self::$functionReplaceFromExcel === NULL) { + self::$functionReplaceFromExcel = array(); + foreach(array_keys(self::$_localeFunctions) as $excelFunctionName) { + self::$functionReplaceFromExcel[] = '/(@?[^\w\.])'.preg_quote($excelFunctionName).'([\s]*\()/Ui'; + } + foreach(array_keys(self::$_localeBoolean) as $excelBoolean) { + self::$functionReplaceFromExcel[] = '/(@?[^\w\.])'.preg_quote($excelBoolean).'([^\w\.])/Ui'; + } + + } + + if (self::$functionReplaceToLocale === NULL) { + self::$functionReplaceToLocale = array(); + foreach(array_values(self::$_localeFunctions) as $localeFunctionName) { + self::$functionReplaceToLocale[] = '$1'.trim($localeFunctionName).'$2'; + } + foreach(array_values(self::$_localeBoolean) as $localeBoolean) { + self::$functionReplaceToLocale[] = '$1'.trim($localeBoolean).'$2'; + } + } + + return self::_translateFormula(self::$functionReplaceFromExcel,self::$functionReplaceToLocale,$formula,',',self::$_localeArgumentSeparator); + } // function _translateFormulaToLocale() + + + private static $functionReplaceFromLocale = NULL; + private static $functionReplaceToExcel = NULL; + + public function _translateFormulaToEnglish($formula) { + if (self::$functionReplaceFromLocale === NULL) { + self::$functionReplaceFromLocale = array(); + foreach(array_values(self::$_localeFunctions) as $localeFunctionName) { + self::$functionReplaceFromLocale[] = '/(@?[^\w\.])'.preg_quote($localeFunctionName).'([\s]*\()/Ui'; + } + foreach(array_values(self::$_localeBoolean) as $excelBoolean) { + self::$functionReplaceFromLocale[] = '/(@?[^\w\.])'.preg_quote($excelBoolean).'([^\w\.])/Ui'; + } + } + + if (self::$functionReplaceToExcel === NULL) { + self::$functionReplaceToExcel = array(); + foreach(array_keys(self::$_localeFunctions) as $excelFunctionName) { + self::$functionReplaceToExcel[] = '$1'.trim($excelFunctionName).'$2'; + } + foreach(array_keys(self::$_localeBoolean) as $excelBoolean) { + self::$functionReplaceToExcel[] = '$1'.trim($excelBoolean).'$2'; + } + } + + return self::_translateFormula(self::$functionReplaceFromLocale,self::$functionReplaceToExcel,$formula,self::$_localeArgumentSeparator,','); + } // function _translateFormulaToEnglish() + + + public static function _localeFunc($function) { + if (self::$_localeLanguage !== 'en_us') { + $functionName = trim($function,'('); + if (isset(self::$_localeFunctions[$functionName])) { + $brace = ($functionName != $function); + $function = self::$_localeFunctions[$functionName]; + if ($brace) { $function .= '('; } + } + } + return $function; + } + + + + + /** + * Wrap string values in quotes + * + * @param mixed $value + * @return mixed + */ + public static function _wrapResult($value) { + if (is_string($value)) { + // Error values cannot be "wrapped" + if (preg_match('/^'.self::CALCULATION_REGEXP_ERROR.'$/i', $value, $match)) { + // Return Excel errors "as is" + return $value; + } + // Return strings wrapped in quotes + return '"'.$value.'"'; + // Convert numeric errors to NaN error + } else if((is_float($value)) && ((is_nan($value)) || (is_infinite($value)))) { + return PHPExcel_Calculation_Functions::NaN(); + } + + return $value; + } // function _wrapResult() + + + /** + * Remove quotes used as a wrapper to identify string values + * + * @param mixed $value + * @return mixed + */ + public static function _unwrapResult($value) { + if (is_string($value)) { + if ((isset($value{0})) && ($value{0} == '"') && (substr($value,-1) == '"')) { + return substr($value,1,-1); + } + // Convert numeric errors to NaN error + } else if((is_float($value)) && ((is_nan($value)) || (is_infinite($value)))) { + return PHPExcel_Calculation_Functions::NaN(); + } + return $value; + } // function _unwrapResult() + + + + + /** + * Calculate cell value (using formula from a cell ID) + * Retained for backward compatibility + * + * @access public + * @param PHPExcel_Cell $pCell Cell to calculate + * @return mixed + * @throws PHPExcel_Calculation_Exception + */ + public function calculate(PHPExcel_Cell $pCell = NULL) { + try { + return $this->calculateCellValue($pCell); + } catch (PHPExcel_Exception $e) { + throw new PHPExcel_Calculation_Exception($e->getMessage()); + } + } // function calculate() + + + /** + * Calculate the value of a cell formula + * + * @access public + * @param PHPExcel_Cell $pCell Cell to calculate + * @param Boolean $resetLog Flag indicating whether the debug log should be reset or not + * @return mixed + * @throws PHPExcel_Calculation_Exception + */ + public function calculateCellValue(PHPExcel_Cell $pCell = NULL, $resetLog = TRUE) { + if ($pCell === NULL) { + return NULL; + } + + $returnArrayAsType = self::$returnArrayAsType; + if ($resetLog) { + // Initialise the logging settings if requested + $this->formulaError = null; + $this->_debugLog->clearLog(); + $this->_cyclicReferenceStack->clear(); + $this->_cyclicFormulaCount = 1; + + self::$returnArrayAsType = self::RETURN_ARRAY_AS_ARRAY; + } + + // Execute the calculation for the cell formula + try { + $result = self::_unwrapResult($this->_calculateFormulaValue($pCell->getValue(), $pCell->getCoordinate(), $pCell)); + } catch (PHPExcel_Exception $e) { + throw new PHPExcel_Calculation_Exception($e->getMessage()); + } + + if ((is_array($result)) && (self::$returnArrayAsType != self::RETURN_ARRAY_AS_ARRAY)) { + self::$returnArrayAsType = $returnArrayAsType; + $testResult = PHPExcel_Calculation_Functions::flattenArray($result); + if (self::$returnArrayAsType == self::RETURN_ARRAY_AS_ERROR) { + return PHPExcel_Calculation_Functions::VALUE(); + } + // If there's only a single cell in the array, then we allow it + if (count($testResult) != 1) { + // If keys are numeric, then it's a matrix result rather than a cell range result, so we permit it + $r = array_keys($result); + $r = array_shift($r); + if (!is_numeric($r)) { return PHPExcel_Calculation_Functions::VALUE(); } + if (is_array($result[$r])) { + $c = array_keys($result[$r]); + $c = array_shift($c); + if (!is_numeric($c)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + } + $result = array_shift($testResult); + } + self::$returnArrayAsType = $returnArrayAsType; + + + if ($result === NULL) { + return 0; + } elseif((is_float($result)) && ((is_nan($result)) || (is_infinite($result)))) { + return PHPExcel_Calculation_Functions::NaN(); + } + return $result; + } // function calculateCellValue( + + + /** + * Validate and parse a formula string + * + * @param string $formula Formula to parse + * @return array + * @throws PHPExcel_Calculation_Exception + */ + public function parseFormula($formula) { + // Basic validation that this is indeed a formula + // We return an empty array if not + $formula = trim($formula); + if ((!isset($formula{0})) || ($formula{0} != '=')) return array(); + $formula = ltrim(substr($formula,1)); + if (!isset($formula{0})) return array(); + + // Parse the formula and return the token stack + return $this->_parseFormula($formula); + } // function parseFormula() + + + /** + * Calculate the value of a formula + * + * @param string $formula Formula to parse + * @param string $cellID Address of the cell to calculate + * @param PHPExcel_Cell $pCell Cell to calculate + * @return mixed + * @throws PHPExcel_Calculation_Exception + */ + public function calculateFormula($formula, $cellID=NULL, PHPExcel_Cell $pCell = NULL) { + // Initialise the logging settings + $this->formulaError = null; + $this->_debugLog->clearLog(); + $this->_cyclicReferenceStack->clear(); + + // Disable calculation cacheing because it only applies to cell calculations, not straight formulae + // But don't actually flush any cache + $resetCache = $this->getCalculationCacheEnabled(); + $this->_calculationCacheEnabled = FALSE; + // Execute the calculation + try { + $result = self::_unwrapResult($this->_calculateFormulaValue($formula, $cellID, $pCell)); + } catch (PHPExcel_Exception $e) { + throw new PHPExcel_Calculation_Exception($e->getMessage()); + } + + // Reset calculation cacheing to its previous state + $this->_calculationCacheEnabled = $resetCache; + + return $result; + } // function calculateFormula() + + + public function getValueFromCache($worksheetName, $cellID, &$cellValue) { + // Is calculation cacheing enabled? + // Is the value present in calculation cache? +//echo 'Test cache for ',$worksheetName,'!',$cellID,PHP_EOL; + $this->_debugLog->writeDebugLog('Testing cache value for cell ', $worksheetName, '!', $cellID); + if (($this->_calculationCacheEnabled) && (isset($this->_calculationCache[$worksheetName][$cellID]))) { +//echo 'Retrieve from cache',PHP_EOL; + $this->_debugLog->writeDebugLog('Retrieving value for cell ', $worksheetName, '!', $cellID, ' from cache'); + // Return the cached result + $cellValue = $this->_calculationCache[$worksheetName][$cellID]; + return TRUE; + } + return FALSE; + } + + public function saveValueToCache($worksheetName, $cellID, $cellValue) { + if ($this->_calculationCacheEnabled) { + $this->_calculationCache[$worksheetName][$cellID] = $cellValue; + } + } + + /** + * Parse a cell formula and calculate its value + * + * @param string $formula The formula to parse and calculate + * @param string $cellID The ID (e.g. A3) of the cell that we are calculating + * @param PHPExcel_Cell $pCell Cell to calculate + * @return mixed + * @throws PHPExcel_Calculation_Exception + */ + public function _calculateFormulaValue($formula, $cellID=null, PHPExcel_Cell $pCell = null) { + $cellValue = ''; + + // Basic validation that this is indeed a formula + // We simply return the cell value if not + $formula = trim($formula); + if ($formula{0} != '=') return self::_wrapResult($formula); + $formula = ltrim(substr($formula,1)); + if (!isset($formula{0})) return self::_wrapResult($formula); + + $pCellParent = ($pCell !== NULL) ? $pCell->getWorksheet() : NULL; + $wsTitle = ($pCellParent !== NULL) ? $pCellParent->getTitle() : "\x00Wrk"; + + if (($cellID !== NULL) && ($this->getValueFromCache($wsTitle, $cellID, $cellValue))) { + return $cellValue; + } + + if (($wsTitle{0} !== "\x00") && ($this->_cyclicReferenceStack->onStack($wsTitle.'!'.$cellID))) { + if ($this->cyclicFormulaCount <= 0) { + return $this->_raiseFormulaError('Cyclic Reference in Formula'); + } elseif (($this->_cyclicFormulaCount >= $this->cyclicFormulaCount) && + ($this->_cyclicFormulaCell == $wsTitle.'!'.$cellID)) { + return $cellValue; + } elseif ($this->_cyclicFormulaCell == $wsTitle.'!'.$cellID) { + ++$this->_cyclicFormulaCount; + if ($this->_cyclicFormulaCount >= $this->cyclicFormulaCount) { + return $cellValue; + } + } elseif ($this->_cyclicFormulaCell == '') { + $this->_cyclicFormulaCell = $wsTitle.'!'.$cellID; + if ($this->_cyclicFormulaCount >= $this->cyclicFormulaCount) { + return $cellValue; + } + } + } + + // Parse the formula onto the token stack and calculate the value + $this->_cyclicReferenceStack->push($wsTitle.'!'.$cellID); + $cellValue = $this->_processTokenStack($this->_parseFormula($formula, $pCell), $cellID, $pCell); + $this->_cyclicReferenceStack->pop(); + + // Save to calculation cache + if ($cellID !== NULL) { + $this->saveValueToCache($wsTitle, $cellID, $cellValue); + } + + // Return the calculated value + return $cellValue; + } // function _calculateFormulaValue() + + + /** + * Ensure that paired matrix operands are both matrices and of the same size + * + * @param mixed &$operand1 First matrix operand + * @param mixed &$operand2 Second matrix operand + * @param integer $resize Flag indicating whether the matrices should be resized to match + * and (if so), whether the smaller dimension should grow or the + * larger should shrink. + * 0 = no resize + * 1 = shrink to fit + * 2 = extend to fit + */ + private static function _checkMatrixOperands(&$operand1,&$operand2,$resize = 1) { + // Examine each of the two operands, and turn them into an array if they aren't one already + // Note that this function should only be called if one or both of the operand is already an array + if (!is_array($operand1)) { + list($matrixRows,$matrixColumns) = self::_getMatrixDimensions($operand2); + $operand1 = array_fill(0,$matrixRows,array_fill(0,$matrixColumns,$operand1)); + $resize = 0; + } elseif (!is_array($operand2)) { + list($matrixRows,$matrixColumns) = self::_getMatrixDimensions($operand1); + $operand2 = array_fill(0,$matrixRows,array_fill(0,$matrixColumns,$operand2)); + $resize = 0; + } + + list($matrix1Rows,$matrix1Columns) = self::_getMatrixDimensions($operand1); + list($matrix2Rows,$matrix2Columns) = self::_getMatrixDimensions($operand2); + if (($matrix1Rows == $matrix2Columns) && ($matrix2Rows == $matrix1Columns)) { + $resize = 1; + } + + if ($resize == 2) { + // Given two matrices of (potentially) unequal size, convert the smaller in each dimension to match the larger + self::_resizeMatricesExtend($operand1,$operand2,$matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns); + } elseif ($resize == 1) { + // Given two matrices of (potentially) unequal size, convert the larger in each dimension to match the smaller + self::_resizeMatricesShrink($operand1,$operand2,$matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns); + } + return array( $matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns); + } // function _checkMatrixOperands() + + + /** + * Read the dimensions of a matrix, and re-index it with straight numeric keys starting from row 0, column 0 + * + * @param mixed &$matrix matrix operand + * @return array An array comprising the number of rows, and number of columns + */ + public static function _getMatrixDimensions(&$matrix) { + $matrixRows = count($matrix); + $matrixColumns = 0; + foreach($matrix as $rowKey => $rowValue) { + $matrixColumns = max(count($rowValue),$matrixColumns); + if (!is_array($rowValue)) { + $matrix[$rowKey] = array($rowValue); + } else { + $matrix[$rowKey] = array_values($rowValue); + } + } + $matrix = array_values($matrix); + return array($matrixRows,$matrixColumns); + } // function _getMatrixDimensions() + + + /** + * Ensure that paired matrix operands are both matrices of the same size + * + * @param mixed &$matrix1 First matrix operand + * @param mixed &$matrix2 Second matrix operand + * @param integer $matrix1Rows Row size of first matrix operand + * @param integer $matrix1Columns Column size of first matrix operand + * @param integer $matrix2Rows Row size of second matrix operand + * @param integer $matrix2Columns Column size of second matrix operand + */ + private static function _resizeMatricesShrink(&$matrix1,&$matrix2,$matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns) { + if (($matrix2Columns < $matrix1Columns) || ($matrix2Rows < $matrix1Rows)) { + if ($matrix2Rows < $matrix1Rows) { + for ($i = $matrix2Rows; $i < $matrix1Rows; ++$i) { + unset($matrix1[$i]); + } + } + if ($matrix2Columns < $matrix1Columns) { + for ($i = 0; $i < $matrix1Rows; ++$i) { + for ($j = $matrix2Columns; $j < $matrix1Columns; ++$j) { + unset($matrix1[$i][$j]); + } + } + } + } + + if (($matrix1Columns < $matrix2Columns) || ($matrix1Rows < $matrix2Rows)) { + if ($matrix1Rows < $matrix2Rows) { + for ($i = $matrix1Rows; $i < $matrix2Rows; ++$i) { + unset($matrix2[$i]); + } + } + if ($matrix1Columns < $matrix2Columns) { + for ($i = 0; $i < $matrix2Rows; ++$i) { + for ($j = $matrix1Columns; $j < $matrix2Columns; ++$j) { + unset($matrix2[$i][$j]); + } + } + } + } + } // function _resizeMatricesShrink() + + + /** + * Ensure that paired matrix operands are both matrices of the same size + * + * @param mixed &$matrix1 First matrix operand + * @param mixed &$matrix2 Second matrix operand + * @param integer $matrix1Rows Row size of first matrix operand + * @param integer $matrix1Columns Column size of first matrix operand + * @param integer $matrix2Rows Row size of second matrix operand + * @param integer $matrix2Columns Column size of second matrix operand + */ + private static function _resizeMatricesExtend(&$matrix1,&$matrix2,$matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns) { + if (($matrix2Columns < $matrix1Columns) || ($matrix2Rows < $matrix1Rows)) { + if ($matrix2Columns < $matrix1Columns) { + for ($i = 0; $i < $matrix2Rows; ++$i) { + $x = $matrix2[$i][$matrix2Columns-1]; + for ($j = $matrix2Columns; $j < $matrix1Columns; ++$j) { + $matrix2[$i][$j] = $x; + } + } + } + if ($matrix2Rows < $matrix1Rows) { + $x = $matrix2[$matrix2Rows-1]; + for ($i = 0; $i < $matrix1Rows; ++$i) { + $matrix2[$i] = $x; + } + } + } + + if (($matrix1Columns < $matrix2Columns) || ($matrix1Rows < $matrix2Rows)) { + if ($matrix1Columns < $matrix2Columns) { + for ($i = 0; $i < $matrix1Rows; ++$i) { + $x = $matrix1[$i][$matrix1Columns-1]; + for ($j = $matrix1Columns; $j < $matrix2Columns; ++$j) { + $matrix1[$i][$j] = $x; + } + } + } + if ($matrix1Rows < $matrix2Rows) { + $x = $matrix1[$matrix1Rows-1]; + for ($i = 0; $i < $matrix2Rows; ++$i) { + $matrix1[$i] = $x; + } + } + } + } // function _resizeMatricesExtend() + + + /** + * Format details of an operand for display in the log (based on operand type) + * + * @param mixed $value First matrix operand + * @return mixed + */ + private function _showValue($value) { + if ($this->_debugLog->getWriteDebugLog()) { + $testArray = PHPExcel_Calculation_Functions::flattenArray($value); + if (count($testArray) == 1) { + $value = array_pop($testArray); + } + + if (is_array($value)) { + $returnMatrix = array(); + $pad = $rpad = ', '; + foreach($value as $row) { + if (is_array($row)) { + $returnMatrix[] = implode($pad,array_map(array($this,'_showValue'),$row)); + $rpad = '; '; + } else { + $returnMatrix[] = $this->_showValue($row); + } + } + return '{ '.implode($rpad,$returnMatrix).' }'; + } elseif(is_string($value) && (trim($value,'"') == $value)) { + return '"'.$value.'"'; + } elseif(is_bool($value)) { + return ($value) ? self::$_localeBoolean['TRUE'] : self::$_localeBoolean['FALSE']; + } + } + return PHPExcel_Calculation_Functions::flattenSingleValue($value); + } // function _showValue() + + + /** + * Format type and details of an operand for display in the log (based on operand type) + * + * @param mixed $value First matrix operand + * @return mixed + */ + private function _showTypeDetails($value) { + if ($this->_debugLog->getWriteDebugLog()) { + $testArray = PHPExcel_Calculation_Functions::flattenArray($value); + if (count($testArray) == 1) { + $value = array_pop($testArray); + } + + if ($value === NULL) { + return 'a NULL value'; + } elseif (is_float($value)) { + $typeString = 'a floating point number'; + } elseif(is_int($value)) { + $typeString = 'an integer number'; + } elseif(is_bool($value)) { + $typeString = 'a boolean'; + } elseif(is_array($value)) { + $typeString = 'a matrix'; + } else { + if ($value == '') { + return 'an empty string'; + } elseif ($value{0} == '#') { + return 'a '.$value.' error'; + } else { + $typeString = 'a string'; + } + } + return $typeString.' with a value of '.$this->_showValue($value); + } + } // function _showTypeDetails() + + + private static function _convertMatrixReferences($formula) { + static $matrixReplaceFrom = array('{',';','}'); + static $matrixReplaceTo = array('MKMATRIX(MKMATRIX(','),MKMATRIX(','))'); + + // Convert any Excel matrix references to the MKMATRIX() function + if (strpos($formula,'{') !== FALSE) { + // If there is the possibility of braces within a quoted string, then we don't treat those as matrix indicators + if (strpos($formula,'"') !== FALSE) { + // So instead we skip replacing in any quoted strings by only replacing in every other array element after we've exploded + // the formula + $temp = explode('"',$formula); + // Open and Closed counts used for trapping mismatched braces in the formula + $openCount = $closeCount = 0; + $i = FALSE; + foreach($temp as &$value) { + // Only count/replace in alternating array entries + if ($i = !$i) { + $openCount += substr_count($value,'{'); + $closeCount += substr_count($value,'}'); + $value = str_replace($matrixReplaceFrom,$matrixReplaceTo,$value); + } + } + unset($value); + // Then rebuild the formula string + $formula = implode('"',$temp); + } else { + // If there's no quoted strings, then we do a simple count/replace + $openCount = substr_count($formula,'{'); + $closeCount = substr_count($formula,'}'); + $formula = str_replace($matrixReplaceFrom,$matrixReplaceTo,$formula); + } + // Trap for mismatched braces and trigger an appropriate error + if ($openCount < $closeCount) { + if ($openCount > 0) { + return $this->_raiseFormulaError("Formula Error: Mismatched matrix braces '}'"); + } else { + return $this->_raiseFormulaError("Formula Error: Unexpected '}' encountered"); + } + } elseif ($openCount > $closeCount) { + if ($closeCount > 0) { + return $this->_raiseFormulaError("Formula Error: Mismatched matrix braces '{'"); + } else { + return $this->_raiseFormulaError("Formula Error: Unexpected '{' encountered"); + } + } + } + + return $formula; + } // function _convertMatrixReferences() + + + private static function _mkMatrix() { + return func_get_args(); + } // function _mkMatrix() + + + // Binary Operators + // These operators always work on two values + // Array key is the operator, the value indicates whether this is a left or right associative operator + private static $_operatorAssociativity = array( + '^' => 0, // Exponentiation + '*' => 0, '/' => 0, // Multiplication and Division + '+' => 0, '-' => 0, // Addition and Subtraction + '&' => 0, // Concatenation + '|' => 0, ':' => 0, // Intersect and Range + '>' => 0, '<' => 0, '=' => 0, '>=' => 0, '<=' => 0, '<>' => 0 // Comparison + ); + + // Comparison (Boolean) Operators + // These operators work on two values, but always return a boolean result + private static $_comparisonOperators = array('>' => TRUE, '<' => TRUE, '=' => TRUE, '>=' => TRUE, '<=' => TRUE, '<>' => TRUE); + + // Operator Precedence + // This list includes all valid operators, whether binary (including boolean) or unary (such as %) + // Array key is the operator, the value is its precedence + private static $_operatorPrecedence = array( + ':' => 8, // Range + '|' => 7, // Intersect + '~' => 6, // Negation + '%' => 5, // Percentage + '^' => 4, // Exponentiation + '*' => 3, '/' => 3, // Multiplication and Division + '+' => 2, '-' => 2, // Addition and Subtraction + '&' => 1, // Concatenation + '>' => 0, '<' => 0, '=' => 0, '>=' => 0, '<=' => 0, '<>' => 0 // Comparison + ); + + // Convert infix to postfix notation + private function _parseFormula($formula, PHPExcel_Cell $pCell = NULL) { + if (($formula = self::_convertMatrixReferences(trim($formula))) === FALSE) { + return FALSE; + } + + // If we're using cell caching, then $pCell may well be flushed back to the cache (which detaches the parent worksheet), + // so we store the parent worksheet so that we can re-attach it when necessary + $pCellParent = ($pCell !== NULL) ? $pCell->getWorksheet() : NULL; + + $regexpMatchString = '/^('.self::CALCULATION_REGEXP_FUNCTION. + '|'.self::CALCULATION_REGEXP_CELLREF. + '|'.self::CALCULATION_REGEXP_NUMBER. + '|'.self::CALCULATION_REGEXP_STRING. + '|'.self::CALCULATION_REGEXP_OPENBRACE. + '|'.self::CALCULATION_REGEXP_NAMEDRANGE. + '|'.self::CALCULATION_REGEXP_ERROR. + ')/si'; + + // Start with initialisation + $index = 0; + $stack = new PHPExcel_Calculation_Token_Stack; + $output = array(); + $expectingOperator = FALSE; // We use this test in syntax-checking the expression to determine when a + // - is a negation or + is a positive operator rather than an operation + $expectingOperand = FALSE; // We use this test in syntax-checking the expression to determine whether an operand + // should be null in a function call + // The guts of the lexical parser + // Loop through the formula extracting each operator and operand in turn + while(TRUE) { +//echo 'Assessing Expression '.substr($formula, $index),PHP_EOL; + $opCharacter = $formula{$index}; // Get the first character of the value at the current index position +//echo 'Initial character of expression block is '.$opCharacter,PHP_EOL; + if ((isset(self::$_comparisonOperators[$opCharacter])) && (strlen($formula) > $index) && (isset(self::$_comparisonOperators[$formula{$index+1}]))) { + $opCharacter .= $formula{++$index}; +//echo 'Initial character of expression block is comparison operator '.$opCharacter.PHP_EOL; + } + + // Find out if we're currently at the beginning of a number, variable, cell reference, function, parenthesis or operand + $isOperandOrFunction = preg_match($regexpMatchString, substr($formula, $index), $match); +//echo '$isOperandOrFunction is '.(($isOperandOrFunction) ? 'True' : 'False').PHP_EOL; +//var_dump($match); + + if ($opCharacter == '-' && !$expectingOperator) { // Is it a negation instead of a minus? +//echo 'Element is a Negation operator',PHP_EOL; + $stack->push('Unary Operator','~'); // Put a negation on the stack + ++$index; // and drop the negation symbol + } elseif ($opCharacter == '%' && $expectingOperator) { +//echo 'Element is a Percentage operator',PHP_EOL; + $stack->push('Unary Operator','%'); // Put a percentage on the stack + ++$index; + } elseif ($opCharacter == '+' && !$expectingOperator) { // Positive (unary plus rather than binary operator plus) can be discarded? +//echo 'Element is a Positive number, not Plus operator',PHP_EOL; + ++$index; // Drop the redundant plus symbol + } elseif ((($opCharacter == '~') || ($opCharacter == '|')) && (!$isOperandOrFunction)) { // We have to explicitly deny a tilde or pipe, because they are legal + return $this->_raiseFormulaError("Formula Error: Illegal character '~'"); // on the stack but not in the input expression + + } elseif ((isset(self::$_operators[$opCharacter]) or $isOperandOrFunction) && $expectingOperator) { // Are we putting an operator on the stack? +//echo 'Element with value '.$opCharacter.' is an Operator',PHP_EOL; + while($stack->count() > 0 && + ($o2 = $stack->last()) && + isset(self::$_operators[$o2['value']]) && + @(self::$_operatorAssociativity[$opCharacter] ? self::$_operatorPrecedence[$opCharacter] < self::$_operatorPrecedence[$o2['value']] : self::$_operatorPrecedence[$opCharacter] <= self::$_operatorPrecedence[$o2['value']])) { + $output[] = $stack->pop(); // Swap operands and higher precedence operators from the stack to the output + } + $stack->push('Binary Operator',$opCharacter); // Finally put our current operator onto the stack + ++$index; + $expectingOperator = FALSE; + + } elseif ($opCharacter == ')' && $expectingOperator) { // Are we expecting to close a parenthesis? +//echo 'Element is a Closing bracket',PHP_EOL; + $expectingOperand = FALSE; + while (($o2 = $stack->pop()) && $o2['value'] != '(') { // Pop off the stack back to the last ( + if ($o2 === NULL) return $this->_raiseFormulaError('Formula Error: Unexpected closing brace ")"'); + else $output[] = $o2; + } + $d = $stack->last(2); + if (preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $d['value'], $matches)) { // Did this parenthesis just close a function? + $functionName = $matches[1]; // Get the function name +//echo 'Closed Function is '.$functionName,PHP_EOL; + $d = $stack->pop(); + $argumentCount = $d['value']; // See how many arguments there were (argument count is the next value stored on the stack) +//if ($argumentCount == 0) { +// echo 'With no arguments',PHP_EOL; +//} elseif ($argumentCount == 1) { +// echo 'With 1 argument',PHP_EOL; +//} else { +// echo 'With '.$argumentCount.' arguments',PHP_EOL; +//} + $output[] = $d; // Dump the argument count on the output + $output[] = $stack->pop(); // Pop the function and push onto the output + if (isset(self::$_controlFunctions[$functionName])) { +//echo 'Built-in function '.$functionName,PHP_EOL; + $expectedArgumentCount = self::$_controlFunctions[$functionName]['argumentCount']; + $functionCall = self::$_controlFunctions[$functionName]['functionCall']; + } elseif (isset(self::$_PHPExcelFunctions[$functionName])) { +//echo 'PHPExcel function '.$functionName,PHP_EOL; + $expectedArgumentCount = self::$_PHPExcelFunctions[$functionName]['argumentCount']; + $functionCall = self::$_PHPExcelFunctions[$functionName]['functionCall']; + } else { // did we somehow push a non-function on the stack? this should never happen + return $this->_raiseFormulaError("Formula Error: Internal error, non-function on stack"); + } + // Check the argument count + $argumentCountError = FALSE; + if (is_numeric($expectedArgumentCount)) { + if ($expectedArgumentCount < 0) { +//echo '$expectedArgumentCount is between 0 and '.abs($expectedArgumentCount),PHP_EOL; + if ($argumentCount > abs($expectedArgumentCount)) { + $argumentCountError = TRUE; + $expectedArgumentCountString = 'no more than '.abs($expectedArgumentCount); + } + } else { +//echo '$expectedArgumentCount is numeric '.$expectedArgumentCount,PHP_EOL; + if ($argumentCount != $expectedArgumentCount) { + $argumentCountError = TRUE; + $expectedArgumentCountString = $expectedArgumentCount; + } + } + } elseif ($expectedArgumentCount != '*') { + $isOperandOrFunction = preg_match('/(\d*)([-+,])(\d*)/',$expectedArgumentCount,$argMatch); +//print_r($argMatch); +//echo PHP_EOL; + switch ($argMatch[2]) { + case '+' : + if ($argumentCount < $argMatch[1]) { + $argumentCountError = TRUE; + $expectedArgumentCountString = $argMatch[1].' or more '; + } + break; + case '-' : + if (($argumentCount < $argMatch[1]) || ($argumentCount > $argMatch[3])) { + $argumentCountError = TRUE; + $expectedArgumentCountString = 'between '.$argMatch[1].' and '.$argMatch[3]; + } + break; + case ',' : + if (($argumentCount != $argMatch[1]) && ($argumentCount != $argMatch[3])) { + $argumentCountError = TRUE; + $expectedArgumentCountString = 'either '.$argMatch[1].' or '.$argMatch[3]; + } + break; + } + } + if ($argumentCountError) { + return $this->_raiseFormulaError("Formula Error: Wrong number of arguments for $functionName() function: $argumentCount given, ".$expectedArgumentCountString." expected"); + } + } + ++$index; + + } elseif ($opCharacter == ',') { // Is this the separator for function arguments? +//echo 'Element is a Function argument separator',PHP_EOL; + while (($o2 = $stack->pop()) && $o2['value'] != '(') { // Pop off the stack back to the last ( + if ($o2 === NULL) return $this->_raiseFormulaError("Formula Error: Unexpected ,"); + else $output[] = $o2; // pop the argument expression stuff and push onto the output + } + // If we've a comma when we're expecting an operand, then what we actually have is a null operand; + // so push a null onto the stack + if (($expectingOperand) || (!$expectingOperator)) { + $output[] = array('type' => 'NULL Value', 'value' => self::$_ExcelConstants['NULL'], 'reference' => NULL); + } + // make sure there was a function + $d = $stack->last(2); + if (!preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $d['value'], $matches)) + return $this->_raiseFormulaError("Formula Error: Unexpected ,"); + $d = $stack->pop(); + $stack->push($d['type'],++$d['value'],$d['reference']); // increment the argument count + $stack->push('Brace', '('); // put the ( back on, we'll need to pop back to it again + $expectingOperator = FALSE; + $expectingOperand = TRUE; + ++$index; + + } elseif ($opCharacter == '(' && !$expectingOperator) { +// echo 'Element is an Opening Bracket
            '; + $stack->push('Brace', '('); + ++$index; + + } elseif ($isOperandOrFunction && !$expectingOperator) { // do we now have a function/variable/number? + $expectingOperator = TRUE; + $expectingOperand = FALSE; + $val = $match[1]; + $length = strlen($val); +// echo 'Element with value '.$val.' is an Operand, Variable, Constant, String, Number, Cell Reference or Function
            '; + + if (preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $val, $matches)) { + $val = preg_replace('/\s/','',$val); +// echo 'Element '.$val.' is a Function
            '; + if (isset(self::$_PHPExcelFunctions[strtoupper($matches[1])]) || isset(self::$_controlFunctions[strtoupper($matches[1])])) { // it's a function + $stack->push('Function', strtoupper($val)); + $ax = preg_match('/^\s*(\s*\))/i', substr($formula, $index+$length), $amatch); + if ($ax) { + $stack->push('Operand Count for Function '.strtoupper($val).')', 0); + $expectingOperator = TRUE; + } else { + $stack->push('Operand Count for Function '.strtoupper($val).')', 1); + $expectingOperator = FALSE; + } + $stack->push('Brace', '('); + } else { // it's a var w/ implicit multiplication + $output[] = array('type' => 'Value', 'value' => $matches[1], 'reference' => NULL); + } + } elseif (preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'$/i', $val, $matches)) { +// echo 'Element '.$val.' is a Cell reference
            '; + // Watch for this case-change when modifying to allow cell references in different worksheets... + // Should only be applied to the actual cell column, not the worksheet name + + // If the last entry on the stack was a : operator, then we have a cell range reference + $testPrevOp = $stack->last(1); + if ($testPrevOp['value'] == ':') { + // If we have a worksheet reference, then we're playing with a 3D reference + if ($matches[2] == '') { + // Otherwise, we 'inherit' the worksheet reference from the start cell reference + // The start of the cell range reference should be the last entry in $output + $startCellRef = $output[count($output)-1]['value']; + preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'$/i', $startCellRef, $startMatches); + if ($startMatches[2] > '') { + $val = $startMatches[2].'!'.$val; + } + } else { + return $this->_raiseFormulaError("3D Range references are not yet supported"); + } + } + + $output[] = array('type' => 'Cell Reference', 'value' => $val, 'reference' => $val); +// $expectingOperator = FALSE; + } else { // it's a variable, constant, string, number or boolean +// echo 'Element is a Variable, Constant, String, Number or Boolean
            '; + // If the last entry on the stack was a : operator, then we may have a row or column range reference + $testPrevOp = $stack->last(1); + if ($testPrevOp['value'] == ':') { + $startRowColRef = $output[count($output)-1]['value']; + $rangeWS1 = ''; + if (strpos('!',$startRowColRef) !== FALSE) { + list($rangeWS1,$startRowColRef) = explode('!',$startRowColRef); + } + if ($rangeWS1 != '') $rangeWS1 .= '!'; + $rangeWS2 = $rangeWS1; + if (strpos('!',$val) !== FALSE) { + list($rangeWS2,$val) = explode('!',$val); + } + if ($rangeWS2 != '') $rangeWS2 .= '!'; + if ((is_integer($startRowColRef)) && (ctype_digit($val)) && + ($startRowColRef <= 1048576) && ($val <= 1048576)) { + // Row range + $endRowColRef = ($pCellParent !== NULL) ? $pCellParent->getHighestColumn() : 'XFD'; // Max 16,384 columns for Excel2007 + $output[count($output)-1]['value'] = $rangeWS1.'A'.$startRowColRef; + $val = $rangeWS2.$endRowColRef.$val; + } elseif ((ctype_alpha($startRowColRef)) && (ctype_alpha($val)) && + (strlen($startRowColRef) <= 3) && (strlen($val) <= 3)) { + // Column range + $endRowColRef = ($pCellParent !== NULL) ? $pCellParent->getHighestRow() : 1048576; // Max 1,048,576 rows for Excel2007 + $output[count($output)-1]['value'] = $rangeWS1.strtoupper($startRowColRef).'1'; + $val = $rangeWS2.$val.$endRowColRef; + } + } + + $localeConstant = FALSE; + if ($opCharacter == '"') { +// echo 'Element is a String
            '; + // UnEscape any quotes within the string + $val = self::_wrapResult(str_replace('""','"',self::_unwrapResult($val))); + } elseif (is_numeric($val)) { +// echo 'Element is a Number
            '; + if ((strpos($val,'.') !== FALSE) || (stripos($val,'e') !== FALSE) || ($val > PHP_INT_MAX) || ($val < -PHP_INT_MAX)) { +// echo 'Casting '.$val.' to float
            '; + $val = (float) $val; + } else { +// echo 'Casting '.$val.' to integer
            '; + $val = (integer) $val; + } + } elseif (isset(self::$_ExcelConstants[trim(strtoupper($val))])) { + $excelConstant = trim(strtoupper($val)); +// echo 'Element '.$excelConstant.' is an Excel Constant
            '; + $val = self::$_ExcelConstants[$excelConstant]; + } elseif (($localeConstant = array_search(trim(strtoupper($val)), self::$_localeBoolean)) !== FALSE) { +// echo 'Element '.$localeConstant.' is an Excel Constant
            '; + $val = self::$_ExcelConstants[$localeConstant]; + } + $details = array('type' => 'Value', 'value' => $val, 'reference' => NULL); + if ($localeConstant) { $details['localeValue'] = $localeConstant; } + $output[] = $details; + } + $index += $length; + + } elseif ($opCharacter == '$') { // absolute row or column range + ++$index; + } elseif ($opCharacter == ')') { // miscellaneous error checking + if ($expectingOperand) { + $output[] = array('type' => 'NULL Value', 'value' => self::$_ExcelConstants['NULL'], 'reference' => NULL); + $expectingOperand = FALSE; + $expectingOperator = TRUE; + } else { + return $this->_raiseFormulaError("Formula Error: Unexpected ')'"); + } + } elseif (isset(self::$_operators[$opCharacter]) && !$expectingOperator) { + return $this->_raiseFormulaError("Formula Error: Unexpected operator '$opCharacter'"); + } else { // I don't even want to know what you did to get here + return $this->_raiseFormulaError("Formula Error: An unexpected error occured"); + } + // Test for end of formula string + if ($index == strlen($formula)) { + // Did we end with an operator?. + // Only valid for the % unary operator + if ((isset(self::$_operators[$opCharacter])) && ($opCharacter != '%')) { + return $this->_raiseFormulaError("Formula Error: Operator '$opCharacter' has no operands"); + } else { + break; + } + } + // Ignore white space + while (($formula{$index} == "\n") || ($formula{$index} == "\r")) { + ++$index; + } + if ($formula{$index} == ' ') { + while ($formula{$index} == ' ') { + ++$index; + } + // If we're expecting an operator, but only have a space between the previous and next operands (and both are + // Cell References) then we have an INTERSECTION operator +// echo 'Possible Intersect Operator
            '; + if (($expectingOperator) && (preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'.*/Ui', substr($formula, $index), $match)) && + ($output[count($output)-1]['type'] == 'Cell Reference')) { +// echo 'Element is an Intersect Operator
            '; + while($stack->count() > 0 && + ($o2 = $stack->last()) && + isset(self::$_operators[$o2['value']]) && + @(self::$_operatorAssociativity[$opCharacter] ? self::$_operatorPrecedence[$opCharacter] < self::$_operatorPrecedence[$o2['value']] : self::$_operatorPrecedence[$opCharacter] <= self::$_operatorPrecedence[$o2['value']])) { + $output[] = $stack->pop(); // Swap operands and higher precedence operators from the stack to the output + } + $stack->push('Binary Operator','|'); // Put an Intersect Operator on the stack + $expectingOperator = FALSE; + } + } + } + + while (($op = $stack->pop()) !== NULL) { // pop everything off the stack and push onto output + if ((is_array($op) && $op['value'] == '(') || ($op === '(')) + return $this->_raiseFormulaError("Formula Error: Expecting ')'"); // if there are any opening braces on the stack, then braces were unbalanced + $output[] = $op; + } + return $output; + } // function _parseFormula() + + + private static function _dataTestReference(&$operandData) + { + $operand = $operandData['value']; + if (($operandData['reference'] === NULL) && (is_array($operand))) { + $rKeys = array_keys($operand); + $rowKey = array_shift($rKeys); + $cKeys = array_keys(array_keys($operand[$rowKey])); + $colKey = array_shift($cKeys); + if (ctype_upper($colKey)) { + $operandData['reference'] = $colKey.$rowKey; + } + } + return $operand; + } + + // evaluate postfix notation + private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCell = NULL) { + if ($tokens == FALSE) return FALSE; + + // If we're using cell caching, then $pCell may well be flushed back to the cache (which detaches the parent cell collection), + // so we store the parent cell collection so that we can re-attach it when necessary + $pCellWorksheet = ($pCell !== NULL) ? $pCell->getWorksheet() : NULL; + $pCellParent = ($pCell !== NULL) ? $pCell->getParent() : null; + $stack = new PHPExcel_Calculation_Token_Stack; + + // Loop through each token in turn + foreach ($tokens as $tokenData) { +// print_r($tokenData); +// echo '
            '; + $token = $tokenData['value']; +// echo 'Token is '.$token.'
            '; + // if the token is a binary operator, pop the top two values off the stack, do the operation, and push the result back on the stack + if (isset(self::$_binaryOperators[$token])) { +// echo 'Token is a binary operator
            '; + // We must have two operands, error if we don't + if (($operand2Data = $stack->pop()) === NULL) return $this->_raiseFormulaError('Internal error - Operand value missing from stack'); + if (($operand1Data = $stack->pop()) === NULL) return $this->_raiseFormulaError('Internal error - Operand value missing from stack'); + + $operand1 = self::_dataTestReference($operand1Data); + $operand2 = self::_dataTestReference($operand2Data); + + // Log what we're doing + if ($token == ':') { + $this->_debugLog->writeDebugLog('Evaluating Range ', $this->_showValue($operand1Data['reference']), ' ', $token, ' ', $this->_showValue($operand2Data['reference'])); + } else { + $this->_debugLog->writeDebugLog('Evaluating ', $this->_showValue($operand1), ' ', $token, ' ', $this->_showValue($operand2)); + } + + // Process the operation in the appropriate manner + switch ($token) { + // Comparison (Boolean) Operators + case '>' : // Greater than + case '<' : // Less than + case '>=' : // Greater than or Equal to + case '<=' : // Less than or Equal to + case '=' : // Equality + case '<>' : // Inequality + $this->_executeBinaryComparisonOperation($cellID,$operand1,$operand2,$token,$stack); + break; + // Binary Operators + case ':' : // Range + $sheet1 = $sheet2 = ''; + if (strpos($operand1Data['reference'],'!') !== FALSE) { + list($sheet1,$operand1Data['reference']) = explode('!',$operand1Data['reference']); + } else { + $sheet1 = ($pCellParent !== NULL) ? $pCellWorksheet->getTitle() : ''; + } + if (strpos($operand2Data['reference'],'!') !== FALSE) { + list($sheet2,$operand2Data['reference']) = explode('!',$operand2Data['reference']); + } else { + $sheet2 = $sheet1; + } + if ($sheet1 == $sheet2) { + if ($operand1Data['reference'] === NULL) { + if ((trim($operand1Data['value']) != '') && (is_numeric($operand1Data['value']))) { + $operand1Data['reference'] = $pCell->getColumn().$operand1Data['value']; + } elseif (trim($operand1Data['reference']) == '') { + $operand1Data['reference'] = $pCell->getCoordinate(); + } else { + $operand1Data['reference'] = $operand1Data['value'].$pCell->getRow(); + } + } + if ($operand2Data['reference'] === NULL) { + if ((trim($operand2Data['value']) != '') && (is_numeric($operand2Data['value']))) { + $operand2Data['reference'] = $pCell->getColumn().$operand2Data['value']; + } elseif (trim($operand2Data['reference']) == '') { + $operand2Data['reference'] = $pCell->getCoordinate(); + } else { + $operand2Data['reference'] = $operand2Data['value'].$pCell->getRow(); + } + } + + $oData = array_merge(explode(':',$operand1Data['reference']),explode(':',$operand2Data['reference'])); + $oCol = $oRow = array(); + foreach($oData as $oDatum) { + $oCR = PHPExcel_Cell::coordinateFromString($oDatum); + $oCol[] = PHPExcel_Cell::columnIndexFromString($oCR[0]) - 1; + $oRow[] = $oCR[1]; + } + $cellRef = PHPExcel_Cell::stringFromColumnIndex(min($oCol)).min($oRow).':'.PHPExcel_Cell::stringFromColumnIndex(max($oCol)).max($oRow); + if ($pCellParent !== NULL) { + $cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($sheet1), FALSE); + } else { + return $this->_raiseFormulaError('Unable to access Cell Reference'); + } + $stack->push('Cell Reference',$cellValue,$cellRef); + } else { + $stack->push('Error',PHPExcel_Calculation_Functions::REF(),NULL); + } + + break; + case '+' : // Addition + $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'plusEquals',$stack); + break; + case '-' : // Subtraction + $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'minusEquals',$stack); + break; + case '*' : // Multiplication + $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'arrayTimesEquals',$stack); + break; + case '/' : // Division + $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'arrayRightDivide',$stack); + break; + case '^' : // Exponential + $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'power',$stack); + break; + case '&' : // Concatenation + // If either of the operands is a matrix, we need to treat them both as matrices + // (converting the other operand to a matrix if need be); then perform the required + // matrix operation + if (is_bool($operand1)) { + $operand1 = ($operand1) ? self::$_localeBoolean['TRUE'] : self::$_localeBoolean['FALSE']; + } + if (is_bool($operand2)) { + $operand2 = ($operand2) ? self::$_localeBoolean['TRUE'] : self::$_localeBoolean['FALSE']; + } + if ((is_array($operand1)) || (is_array($operand2))) { + // Ensure that both operands are arrays/matrices + self::_checkMatrixOperands($operand1,$operand2,2); + try { + // Convert operand 1 from a PHP array to a matrix + $matrix = new PHPExcel_Shared_JAMA_Matrix($operand1); + // Perform the required operation against the operand 1 matrix, passing in operand 2 + $matrixResult = $matrix->concat($operand2); + $result = $matrixResult->getArray(); + } catch (PHPExcel_Exception $ex) { + $this->_debugLog->writeDebugLog('JAMA Matrix Exception: ', $ex->getMessage()); + $result = '#VALUE!'; + } + } else { + $result = '"'.str_replace('""','"',self::_unwrapResult($operand1,'"').self::_unwrapResult($operand2,'"')).'"'; + } + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result)); + $stack->push('Value',$result); + break; + case '|' : // Intersect + $rowIntersect = array_intersect_key($operand1,$operand2); + $cellIntersect = $oCol = $oRow = array(); + foreach(array_keys($rowIntersect) as $row) { + $oRow[] = $row; + foreach($rowIntersect[$row] as $col => $data) { + $oCol[] = PHPExcel_Cell::columnIndexFromString($col) - 1; + $cellIntersect[$row] = array_intersect_key($operand1[$row],$operand2[$row]); + } + } + $cellRef = PHPExcel_Cell::stringFromColumnIndex(min($oCol)).min($oRow).':'.PHPExcel_Cell::stringFromColumnIndex(max($oCol)).max($oRow); + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($cellIntersect)); + $stack->push('Value',$cellIntersect,$cellRef); + break; + } + + // if the token is a unary operator, pop one value off the stack, do the operation, and push it back on + } elseif (($token === '~') || ($token === '%')) { +// echo 'Token is a unary operator
            '; + if (($arg = $stack->pop()) === NULL) return $this->_raiseFormulaError('Internal error - Operand value missing from stack'); + $arg = $arg['value']; + if ($token === '~') { +// echo 'Token is a negation operator
            '; + $this->_debugLog->writeDebugLog('Evaluating Negation of ', $this->_showValue($arg)); + $multiplier = -1; + } else { +// echo 'Token is a percentile operator
            '; + $this->_debugLog->writeDebugLog('Evaluating Percentile of ', $this->_showValue($arg)); + $multiplier = 0.01; + } + if (is_array($arg)) { + self::_checkMatrixOperands($arg,$multiplier,2); + try { + $matrix1 = new PHPExcel_Shared_JAMA_Matrix($arg); + $matrixResult = $matrix1->arrayTimesEquals($multiplier); + $result = $matrixResult->getArray(); + } catch (PHPExcel_Exception $ex) { + $this->_debugLog->writeDebugLog('JAMA Matrix Exception: ', $ex->getMessage()); + $result = '#VALUE!'; + } + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result)); + $stack->push('Value',$result); + } else { + $this->_executeNumericBinaryOperation($cellID,$multiplier,$arg,'*','arrayTimesEquals',$stack); + } + + } elseif (preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'$/i', $token, $matches)) { + $cellRef = NULL; +// echo 'Element '.$token.' is a Cell reference
            '; + if (isset($matches[8])) { +// echo 'Reference is a Range of cells
            '; + if ($pCell === NULL) { +// We can't access the range, so return a REF error + $cellValue = PHPExcel_Calculation_Functions::REF(); + } else { + $cellRef = $matches[6].$matches[7].':'.$matches[9].$matches[10]; + if ($matches[2] > '') { + $matches[2] = trim($matches[2],"\"'"); + if ((strpos($matches[2],'[') !== FALSE) || (strpos($matches[2],']') !== FALSE)) { + // It's a Reference to an external workbook (not currently supported) + return $this->_raiseFormulaError('Unable to access External Workbook'); + } + $matches[2] = trim($matches[2],"\"'"); +// echo '$cellRef='.$cellRef.' in worksheet '.$matches[2].'
            '; + $this->_debugLog->writeDebugLog('Evaluating Cell Range ', $cellRef, ' in worksheet ', $matches[2]); + if ($pCellParent !== NULL) { + $cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($matches[2]), FALSE); + } else { + return $this->_raiseFormulaError('Unable to access Cell Reference'); + } + $this->_debugLog->writeDebugLog('Evaluation Result for cells ', $cellRef, ' in worksheet ', $matches[2], ' is ', $this->_showTypeDetails($cellValue)); +// $cellRef = $matches[2].'!'.$cellRef; + } else { +// echo '$cellRef='.$cellRef.' in current worksheet
            '; + $this->_debugLog->writeDebugLog('Evaluating Cell Range ', $cellRef, ' in current worksheet'); + if ($pCellParent !== NULL) { + $cellValue = $this->extractCellRange($cellRef, $pCellWorksheet, FALSE); + } else { + return $this->_raiseFormulaError('Unable to access Cell Reference'); + } + $this->_debugLog->writeDebugLog('Evaluation Result for cells ', $cellRef, ' is ', $this->_showTypeDetails($cellValue)); + } + } + } else { +// echo 'Reference is a single Cell
            '; + if ($pCell === NULL) { +// We can't access the cell, so return a REF error + $cellValue = PHPExcel_Calculation_Functions::REF(); + } else { + $cellRef = $matches[6].$matches[7]; + if ($matches[2] > '') { + $matches[2] = trim($matches[2],"\"'"); + if ((strpos($matches[2],'[') !== FALSE) || (strpos($matches[2],']') !== FALSE)) { + // It's a Reference to an external workbook (not currently supported) + return $this->_raiseFormulaError('Unable to access External Workbook'); + } +// echo '$cellRef='.$cellRef.' in worksheet '.$matches[2].'
            '; + $this->_debugLog->writeDebugLog('Evaluating Cell ', $cellRef, ' in worksheet ', $matches[2]); + if ($pCellParent !== NULL) { + $cellSheet = $this->_workbook->getSheetByName($matches[2]); + if ($cellSheet && $cellSheet->cellExists($cellRef)) { + $cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($matches[2]), FALSE); + $pCell->attach($pCellParent); + } else { + $cellValue = NULL; + } + } else { + return $this->_raiseFormulaError('Unable to access Cell Reference'); + } + $this->_debugLog->writeDebugLog('Evaluation Result for cell ', $cellRef, ' in worksheet ', $matches[2], ' is ', $this->_showTypeDetails($cellValue)); +// $cellRef = $matches[2].'!'.$cellRef; + } else { +// echo '$cellRef='.$cellRef.' in current worksheet
            '; + $this->_debugLog->writeDebugLog('Evaluating Cell ', $cellRef, ' in current worksheet'); + if ($pCellParent->isDataSet($cellRef)) { + $cellValue = $this->extractCellRange($cellRef, $pCellWorksheet, FALSE); + $pCell->attach($pCellParent); + } else { + $cellValue = NULL; + } + $this->_debugLog->writeDebugLog('Evaluation Result for cell ', $cellRef, ' is ', $this->_showTypeDetails($cellValue)); + } + } + } + $stack->push('Value',$cellValue,$cellRef); + + // if the token is a function, pop arguments off the stack, hand them to the function, and push the result back on + } elseif (preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $token, $matches)) { +// echo 'Token is a function
            '; + $functionName = $matches[1]; + $argCount = $stack->pop(); + $argCount = $argCount['value']; + if ($functionName != 'MKMATRIX') { + $this->_debugLog->writeDebugLog('Evaluating Function ', self::_localeFunc($functionName), '() with ', (($argCount == 0) ? 'no' : $argCount), ' argument', (($argCount == 1) ? '' : 's')); + } + if ((isset(self::$_PHPExcelFunctions[$functionName])) || (isset(self::$_controlFunctions[$functionName]))) { // function + if (isset(self::$_PHPExcelFunctions[$functionName])) { + $functionCall = self::$_PHPExcelFunctions[$functionName]['functionCall']; + $passByReference = isset(self::$_PHPExcelFunctions[$functionName]['passByReference']); + $passCellReference = isset(self::$_PHPExcelFunctions[$functionName]['passCellReference']); + } elseif (isset(self::$_controlFunctions[$functionName])) { + $functionCall = self::$_controlFunctions[$functionName]['functionCall']; + $passByReference = isset(self::$_controlFunctions[$functionName]['passByReference']); + $passCellReference = isset(self::$_controlFunctions[$functionName]['passCellReference']); + } + // get the arguments for this function +// echo 'Function '.$functionName.' expects '.$argCount.' arguments
            '; + $args = $argArrayVals = array(); + for ($i = 0; $i < $argCount; ++$i) { + $arg = $stack->pop(); + $a = $argCount - $i - 1; + if (($passByReference) && + (isset(self::$_PHPExcelFunctions[$functionName]['passByReference'][$a])) && + (self::$_PHPExcelFunctions[$functionName]['passByReference'][$a])) { + if ($arg['reference'] === NULL) { + $args[] = $cellID; + if ($functionName != 'MKMATRIX') { $argArrayVals[] = $this->_showValue($cellID); } + } else { + $args[] = $arg['reference']; + if ($functionName != 'MKMATRIX') { $argArrayVals[] = $this->_showValue($arg['reference']); } + } + } else { + $args[] = self::_unwrapResult($arg['value']); + if ($functionName != 'MKMATRIX') { $argArrayVals[] = $this->_showValue($arg['value']); } + } + } + // Reverse the order of the arguments + krsort($args); + if (($passByReference) && ($argCount == 0)) { + $args[] = $cellID; + $argArrayVals[] = $this->_showValue($cellID); + } +// echo 'Arguments are: '; +// print_r($args); +// echo '
            '; + if ($functionName != 'MKMATRIX') { + if ($this->_debugLog->getWriteDebugLog()) { + krsort($argArrayVals); + $this->_debugLog->writeDebugLog('Evaluating ', self::_localeFunc($functionName), '( ', implode(self::$_localeArgumentSeparator.' ',PHPExcel_Calculation_Functions::flattenArray($argArrayVals)), ' )'); + } + } + // Process each argument in turn, building the return value as an array +// if (($argCount == 1) && (is_array($args[1])) && ($functionName != 'MKMATRIX')) { +// $operand1 = $args[1]; +// $this->_debugLog->writeDebugLog('Argument is a matrix: ', $this->_showValue($operand1)); +// $result = array(); +// $row = 0; +// foreach($operand1 as $args) { +// if (is_array($args)) { +// foreach($args as $arg) { +// $this->_debugLog->writeDebugLog('Evaluating ', self::_localeFunc($functionName), '( ', $this->_showValue($arg), ' )'); +// $r = call_user_func_array($functionCall,$arg); +// $this->_debugLog->writeDebugLog('Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($r)); +// $result[$row][] = $r; +// } +// ++$row; +// } else { +// $this->_debugLog->writeDebugLog('Evaluating ', self::_localeFunc($functionName), '( ', $this->_showValue($args), ' )'); +// $r = call_user_func_array($functionCall,$args); +// $this->_debugLog->writeDebugLog('Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($r)); +// $result[] = $r; +// } +// } +// } else { + // Process the argument with the appropriate function call + if ($passCellReference) { + $args[] = $pCell; + } + if (strpos($functionCall,'::') !== FALSE) { + $result = call_user_func_array(explode('::',$functionCall),$args); + } else { + foreach($args as &$arg) { + $arg = PHPExcel_Calculation_Functions::flattenSingleValue($arg); + } + unset($arg); + $result = call_user_func_array($functionCall,$args); + } +// } + if ($functionName != 'MKMATRIX') { + $this->_debugLog->writeDebugLog('Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($result)); + } + $stack->push('Value',self::_wrapResult($result)); + } + + } else { + // if the token is a number, boolean, string or an Excel error, push it onto the stack + if (isset(self::$_ExcelConstants[strtoupper($token)])) { + $excelConstant = strtoupper($token); +// echo 'Token is a PHPExcel constant: '.$excelConstant.'
            '; + $stack->push('Constant Value',self::$_ExcelConstants[$excelConstant]); + $this->_debugLog->writeDebugLog('Evaluating Constant ', $excelConstant, ' as ', $this->_showTypeDetails(self::$_ExcelConstants[$excelConstant])); + } elseif ((is_numeric($token)) || ($token === NULL) || (is_bool($token)) || ($token == '') || ($token{0} == '"') || ($token{0} == '#')) { +// echo 'Token is a number, boolean, string, null or an Excel error
            '; + $stack->push('Value',$token); + // if the token is a named range, push the named range name onto the stack + } elseif (preg_match('/^'.self::CALCULATION_REGEXP_NAMEDRANGE.'$/i', $token, $matches)) { +// echo 'Token is a named range
            '; + $namedRange = $matches[6]; +// echo 'Named Range is '.$namedRange.'
            '; + $this->_debugLog->writeDebugLog('Evaluating Named Range ', $namedRange); + $cellValue = $this->extractNamedRange($namedRange, ((NULL !== $pCell) ? $pCellWorksheet : NULL), FALSE); + $pCell->attach($pCellParent); + $this->_debugLog->writeDebugLog('Evaluation Result for named range ', $namedRange, ' is ', $this->_showTypeDetails($cellValue)); + $stack->push('Named Range',$cellValue,$namedRange); + } else { + return $this->_raiseFormulaError("undefined variable '$token'"); + } + } + } + // when we're out of tokens, the stack should have a single element, the final result + if ($stack->count() != 1) return $this->_raiseFormulaError("internal error"); + $output = $stack->pop(); + $output = $output['value']; + +// if ((is_array($output)) && (self::$returnArrayAsType != self::RETURN_ARRAY_AS_ARRAY)) { +// return array_shift(PHPExcel_Calculation_Functions::flattenArray($output)); +// } + return $output; + } // function _processTokenStack() + + + private function _validateBinaryOperand($cellID, &$operand, &$stack) { + if (is_array($operand)) { + if ((count($operand, COUNT_RECURSIVE) - count($operand)) == 1) { + do { + $operand = array_pop($operand); + } while (is_array($operand)); + } + } + // Numbers, matrices and booleans can pass straight through, as they're already valid + if (is_string($operand)) { + // We only need special validations for the operand if it is a string + // Start by stripping off the quotation marks we use to identify true excel string values internally + if ($operand > '' && $operand{0} == '"') { $operand = self::_unwrapResult($operand); } + // If the string is a numeric value, we treat it as a numeric, so no further testing + if (!is_numeric($operand)) { + // If not a numeric, test to see if the value is an Excel error, and so can't be used in normal binary operations + if ($operand > '' && $operand{0} == '#') { + $stack->push('Value', $operand); + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($operand)); + return FALSE; + } elseif (!PHPExcel_Shared_String::convertToNumberIfFraction($operand)) { + // If not a numeric or a fraction, then it's a text string, and so can't be used in mathematical binary operations + $stack->push('Value', '#VALUE!'); + $this->_debugLog->writeDebugLog('Evaluation Result is a ', $this->_showTypeDetails('#VALUE!')); + return FALSE; + } + } + } + + // return a true if the value of the operand is one that we can use in normal binary operations + return TRUE; + } // function _validateBinaryOperand() + + + private function _executeBinaryComparisonOperation($cellID, $operand1, $operand2, $operation, &$stack, $recursingArrays=FALSE) { + // If we're dealing with matrix operations, we want a matrix result + if ((is_array($operand1)) || (is_array($operand2))) { + $result = array(); + if ((is_array($operand1)) && (!is_array($operand2))) { + foreach($operand1 as $x => $operandData) { + $this->_debugLog->writeDebugLog('Evaluating Comparison ', $this->_showValue($operandData), ' ', $operation, ' ', $this->_showValue($operand2)); + $this->_executeBinaryComparisonOperation($cellID,$operandData,$operand2,$operation,$stack); + $r = $stack->pop(); + $result[$x] = $r['value']; + } + } elseif ((!is_array($operand1)) && (is_array($operand2))) { + foreach($operand2 as $x => $operandData) { + $this->_debugLog->writeDebugLog('Evaluating Comparison ', $this->_showValue($operand1), ' ', $operation, ' ', $this->_showValue($operandData)); + $this->_executeBinaryComparisonOperation($cellID,$operand1,$operandData,$operation,$stack); + $r = $stack->pop(); + $result[$x] = $r['value']; + } + } else { + if (!$recursingArrays) { self::_checkMatrixOperands($operand1,$operand2,2); } + foreach($operand1 as $x => $operandData) { + $this->_debugLog->writeDebugLog('Evaluating Comparison ', $this->_showValue($operandData), ' ', $operation, ' ', $this->_showValue($operand2[$x])); + $this->_executeBinaryComparisonOperation($cellID,$operandData,$operand2[$x],$operation,$stack,TRUE); + $r = $stack->pop(); + $result[$x] = $r['value']; + } + } + // Log the result details + $this->_debugLog->writeDebugLog('Comparison Evaluation Result is ', $this->_showTypeDetails($result)); + // And push the result onto the stack + $stack->push('Array',$result); + return TRUE; + } + + // Simple validate the two operands if they are string values + if (is_string($operand1) && $operand1 > '' && $operand1{0} == '"') { $operand1 = self::_unwrapResult($operand1); } + if (is_string($operand2) && $operand2 > '' && $operand2{0} == '"') { $operand2 = self::_unwrapResult($operand2); } + + // Use case insensitive comparaison if not OpenOffice mode + if (PHPExcel_Calculation_Functions::getCompatibilityMode() != PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) + { + if (is_string($operand1)) { + $operand1 = strtoupper($operand1); + } + + if (is_string($operand2)) { + $operand2 = strtoupper($operand2); + } + } + + $useLowercaseFirstComparison = is_string($operand1) && is_string($operand2) && PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE; + + // execute the necessary operation + switch ($operation) { + // Greater than + case '>': + if ($useLowercaseFirstComparison) { + $result = $this->strcmpLowercaseFirst($operand1, $operand2) > 0; + } else { + $result = ($operand1 > $operand2); + } + break; + // Less than + case '<': + if ($useLowercaseFirstComparison) { + $result = $this->strcmpLowercaseFirst($operand1, $operand2) < 0; + } else { + $result = ($operand1 < $operand2); + } + break; + // Equality + case '=': + $result = ($operand1 == $operand2); + break; + // Greater than or equal + case '>=': + if ($useLowercaseFirstComparison) { + $result = $this->strcmpLowercaseFirst($operand1, $operand2) >= 0; + } else { + $result = ($operand1 >= $operand2); + } + break; + // Less than or equal + case '<=': + if ($useLowercaseFirstComparison) { + $result = $this->strcmpLowercaseFirst($operand1, $operand2) <= 0; + } else { + $result = ($operand1 <= $operand2); + } + break; + // Inequality + case '<>': + $result = ($operand1 != $operand2); + break; + } + + // Log the result details + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result)); + // And push the result onto the stack + $stack->push('Value',$result); + return TRUE; + } // function _executeBinaryComparisonOperation() + + /** + * Compare two strings in the same way as strcmp() except that lowercase come before uppercase letters + * @param string $str1 + * @param string $str2 + * @return integer + */ + private function strcmpLowercaseFirst($str1, $str2) + { + $from = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; + $to = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; + $inversedStr1 = strtr($str1, $from, $to); + $inversedStr2 = strtr($str2, $from, $to); + + return strcmp($inversedStr1, $inversedStr2); + } + + private function _executeNumericBinaryOperation($cellID,$operand1,$operand2,$operation,$matrixFunction,&$stack) { + // Validate the two operands + if (!$this->_validateBinaryOperand($cellID,$operand1,$stack)) return FALSE; + if (!$this->_validateBinaryOperand($cellID,$operand2,$stack)) return FALSE; + + // If either of the operands is a matrix, we need to treat them both as matrices + // (converting the other operand to a matrix if need be); then perform the required + // matrix operation + if ((is_array($operand1)) || (is_array($operand2))) { + // Ensure that both operands are arrays/matrices of the same size + self::_checkMatrixOperands($operand1, $operand2, 2); + + try { + // Convert operand 1 from a PHP array to a matrix + $matrix = new PHPExcel_Shared_JAMA_Matrix($operand1); + // Perform the required operation against the operand 1 matrix, passing in operand 2 + $matrixResult = $matrix->$matrixFunction($operand2); + $result = $matrixResult->getArray(); + } catch (PHPExcel_Exception $ex) { + $this->_debugLog->writeDebugLog('JAMA Matrix Exception: ', $ex->getMessage()); + $result = '#VALUE!'; + } + } else { + if ((PHPExcel_Calculation_Functions::getCompatibilityMode() != PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) && + ((is_string($operand1) && !is_numeric($operand1) && strlen($operand1)>0) || + (is_string($operand2) && !is_numeric($operand2) && strlen($operand2)>0))) { + $result = PHPExcel_Calculation_Functions::VALUE(); + } else { + // If we're dealing with non-matrix operations, execute the necessary operation + switch ($operation) { + // Addition + case '+': + $result = $operand1 + $operand2; + break; + // Subtraction + case '-': + $result = $operand1 - $operand2; + break; + // Multiplication + case '*': + $result = $operand1 * $operand2; + break; + // Division + case '/': + if ($operand2 == 0) { + // Trap for Divide by Zero error + $stack->push('Value','#DIV/0!'); + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails('#DIV/0!')); + return FALSE; + } else { + $result = $operand1 / $operand2; + } + break; + // Power + case '^': + $result = pow($operand1, $operand2); + break; + } + } + } + + // Log the result details + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result)); + // And push the result onto the stack + $stack->push('Value',$result); + return TRUE; + } // function _executeNumericBinaryOperation() + + + // trigger an error, but nicely, if need be + protected function _raiseFormulaError($errorMessage) { + $this->formulaError = $errorMessage; + $this->_cyclicReferenceStack->clear(); + if (!$this->suppressFormulaErrors) throw new PHPExcel_Calculation_Exception($errorMessage); + trigger_error($errorMessage, E_USER_ERROR); + } // function _raiseFormulaError() + + + /** + * Extract range values + * + * @param string &$pRange String based range representation + * @param PHPExcel_Worksheet $pSheet Worksheet + * @param boolean $resetLog Flag indicating whether calculation log should be reset or not + * @return mixed Array of values in range if range contains more than one element. Otherwise, a single value is returned. + * @throws PHPExcel_Calculation_Exception + */ + public function extractCellRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = NULL, $resetLog = TRUE) { + // Return value + $returnValue = array (); + +// echo 'extractCellRange('.$pRange.')',PHP_EOL; + if ($pSheet !== NULL) { + $pSheetName = $pSheet->getTitle(); +// echo 'Passed sheet name is '.$pSheetName.PHP_EOL; +// echo 'Range reference is '.$pRange.PHP_EOL; + if (strpos ($pRange, '!') !== false) { +// echo '$pRange reference includes sheet reference',PHP_EOL; + list($pSheetName,$pRange) = PHPExcel_Worksheet::extractSheetTitle($pRange, true); +// echo 'New sheet name is '.$pSheetName,PHP_EOL; +// echo 'Adjusted Range reference is '.$pRange,PHP_EOL; + $pSheet = $this->_workbook->getSheetByName($pSheetName); + } + + // Extract range + $aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($pRange); + $pRange = $pSheetName.'!'.$pRange; + if (!isset($aReferences[1])) { + // Single cell in range + sscanf($aReferences[0],'%[A-Z]%d', $currentCol, $currentRow); + $cellValue = NULL; + if ($pSheet->cellExists($aReferences[0])) { + $returnValue[$currentRow][$currentCol] = $pSheet->getCell($aReferences[0])->getCalculatedValue($resetLog); + } else { + $returnValue[$currentRow][$currentCol] = NULL; + } + } else { + // Extract cell data for all cells in the range + foreach ($aReferences as $reference) { + // Extract range + sscanf($reference,'%[A-Z]%d', $currentCol, $currentRow); + $cellValue = NULL; + if ($pSheet->cellExists($reference)) { + $returnValue[$currentRow][$currentCol] = $pSheet->getCell($reference)->getCalculatedValue($resetLog); + } else { + $returnValue[$currentRow][$currentCol] = NULL; + } + } + } + } + + // Return + return $returnValue; + } // function extractCellRange() + + + /** + * Extract range values + * + * @param string &$pRange String based range representation + * @param PHPExcel_Worksheet $pSheet Worksheet + * @return mixed Array of values in range if range contains more than one element. Otherwise, a single value is returned. + * @param boolean $resetLog Flag indicating whether calculation log should be reset or not + * @throws PHPExcel_Calculation_Exception + */ + public function extractNamedRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = NULL, $resetLog = TRUE) { + // Return value + $returnValue = array (); + +// echo 'extractNamedRange('.$pRange.')
            '; + if ($pSheet !== NULL) { + $pSheetName = $pSheet->getTitle(); +// echo 'Current sheet name is '.$pSheetName.'
            '; +// echo 'Range reference is '.$pRange.'
            '; + if (strpos ($pRange, '!') !== false) { +// echo '$pRange reference includes sheet reference',PHP_EOL; + list($pSheetName,$pRange) = PHPExcel_Worksheet::extractSheetTitle($pRange, true); +// echo 'New sheet name is '.$pSheetName,PHP_EOL; +// echo 'Adjusted Range reference is '.$pRange,PHP_EOL; + $pSheet = $this->_workbook->getSheetByName($pSheetName); + } + + // Named range? + $namedRange = PHPExcel_NamedRange::resolveRange($pRange, $pSheet); + if ($namedRange !== NULL) { + $pSheet = $namedRange->getWorksheet(); +// echo 'Named Range '.$pRange.' ('; + $pRange = $namedRange->getRange(); + $splitRange = PHPExcel_Cell::splitRange($pRange); + // Convert row and column references + if (ctype_alpha($splitRange[0][0])) { + $pRange = $splitRange[0][0] . '1:' . $splitRange[0][1] . $namedRange->getWorksheet()->getHighestRow(); + } elseif(ctype_digit($splitRange[0][0])) { + $pRange = 'A' . $splitRange[0][0] . ':' . $namedRange->getWorksheet()->getHighestColumn() . $splitRange[0][1]; + } +// echo $pRange.') is in sheet '.$namedRange->getWorksheet()->getTitle().'
            '; + +// if ($pSheet->getTitle() != $namedRange->getWorksheet()->getTitle()) { +// if (!$namedRange->getLocalOnly()) { +// $pSheet = $namedRange->getWorksheet(); +// } else { +// return $returnValue; +// } +// } + } else { + return PHPExcel_Calculation_Functions::REF(); + } + + // Extract range + $aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($pRange); +// var_dump($aReferences); + if (!isset($aReferences[1])) { + // Single cell (or single column or row) in range + list($currentCol,$currentRow) = PHPExcel_Cell::coordinateFromString($aReferences[0]); + $cellValue = NULL; + if ($pSheet->cellExists($aReferences[0])) { + $returnValue[$currentRow][$currentCol] = $pSheet->getCell($aReferences[0])->getCalculatedValue($resetLog); + } else { + $returnValue[$currentRow][$currentCol] = NULL; + } + } else { + // Extract cell data for all cells in the range + foreach ($aReferences as $reference) { + // Extract range + list($currentCol,$currentRow) = PHPExcel_Cell::coordinateFromString($reference); +// echo 'NAMED RANGE: $currentCol='.$currentCol.' $currentRow='.$currentRow.'
            '; + $cellValue = NULL; + if ($pSheet->cellExists($reference)) { + $returnValue[$currentRow][$currentCol] = $pSheet->getCell($reference)->getCalculatedValue($resetLog); + } else { + $returnValue[$currentRow][$currentCol] = NULL; + } + } + } +// print_r($returnValue); +// echo '
            '; + } + + // Return + return $returnValue; + } // function extractNamedRange() + + + /** + * Is a specific function implemented? + * + * @param string $pFunction Function Name + * @return boolean + */ + public function isImplemented($pFunction = '') { + $pFunction = strtoupper ($pFunction); + if (isset(self::$_PHPExcelFunctions[$pFunction])) { + return (self::$_PHPExcelFunctions[$pFunction]['functionCall'] != 'PHPExcel_Calculation_Functions::DUMMY'); + } else { + return FALSE; + } + } // function isImplemented() + + + /** + * Get a list of all implemented functions as an array of function objects + * + * @return array of PHPExcel_Calculation_Function + */ + public function listFunctions() { + // Return value + $returnValue = array(); + // Loop functions + foreach(self::$_PHPExcelFunctions as $functionName => $function) { + if ($function['functionCall'] != 'PHPExcel_Calculation_Functions::DUMMY') { + $returnValue[$functionName] = new PHPExcel_Calculation_Function($function['category'], + $functionName, + $function['functionCall'] + ); + } + } + + // Return + return $returnValue; + } // function listFunctions() + + + /** + * Get a list of all Excel function names + * + * @return array + */ + public function listAllFunctionNames() { + return array_keys(self::$_PHPExcelFunctions); + } // function listAllFunctionNames() + + /** + * Get a list of implemented Excel function names + * + * @return array + */ + public function listFunctionNames() { + // Return value + $returnValue = array(); + // Loop functions + foreach(self::$_PHPExcelFunctions as $functionName => $function) { + if ($function['functionCall'] != 'PHPExcel_Calculation_Functions::DUMMY') { + $returnValue[] = $functionName; + } + } + + // Return + return $returnValue; + } // function listFunctionNames() + +} // class PHPExcel_Calculation + diff --git a/lib/phpexcel/PHPExcel/Calculation/Database.php b/lib/phpexcel/PHPExcel/Calculation/Database.php new file mode 100644 index 0000000..c3e86d7 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Calculation/Database.php @@ -0,0 +1,725 @@ + $criteriaName) { + $testCondition = array(); + $testConditionCount = 0; + foreach($criteria as $row => $criterion) { + if ($criterion[$key] > '') { + $testCondition[] = '[:'.$criteriaName.']'.PHPExcel_Calculation_Functions::_ifCondition($criterion[$key]); + $testConditionCount++; + } + } + if ($testConditionCount > 1) { + $testConditions[] = 'OR('.implode(',',$testCondition).')'; + $testConditionsCount++; + } elseif($testConditionCount == 1) { + $testConditions[] = $testCondition[0]; + $testConditionsCount++; + } + } + + if ($testConditionsCount > 1) { + $testConditionSet = 'AND('.implode(',',$testConditions).')'; + } elseif($testConditionsCount == 1) { + $testConditionSet = $testConditions[0]; + } + + // Loop through each row of the database + foreach($database as $dataRow => $dataValues) { + // Substitute actual values from the database row for our [:placeholders] + $testConditionList = $testConditionSet; + foreach($criteriaNames as $key => $criteriaName) { + $k = array_search($criteriaName,$fieldNames); + if (isset($dataValues[$k])) { + $dataValue = $dataValues[$k]; + $dataValue = (is_string($dataValue)) ? PHPExcel_Calculation::_wrapResult(strtoupper($dataValue)) : $dataValue; + $testConditionList = str_replace('[:'.$criteriaName.']',$dataValue,$testConditionList); + } + } + // evaluate the criteria against the row data + $result = PHPExcel_Calculation::getInstance()->_calculateFormulaValue('='.$testConditionList); + // If the row failed to meet the criteria, remove it from the database + if (!$result) { + unset($database[$dataRow]); + } + } + + return $database; + } + + + /** + * DAVERAGE + * + * Averages the values in a column of a list or database that match conditions you specify. + * + * Excel Function: + * DAVERAGE(database,field,criteria) + * + * @access public + * @category Database Functions + * @param mixed[] $database The range of cells that makes up the list or database. + * A database is a list of related data in which rows of related + * information are records, and columns of data are fields. The + * first row of the list contains labels for each column. + * @param string|integer $field Indicates which column is used in the function. Enter the + * column label enclosed between double quotation marks, such as + * "Age" or "Yield," or a number (without quotation marks) that + * represents the position of the column within the list: 1 for + * the first column, 2 for the second column, and so on. + * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * You can use any range for the criteria argument, as long as it + * includes at least one column label and at least one cell below + * the column label in which you specify a condition for the + * column. + * @return float + * + */ + public static function DAVERAGE($database,$field,$criteria) { + $field = self::__fieldExtract($database,$field); + if (is_null($field)) { + return NULL; + } + // reduce the database to a set of rows that match all the criteria + $database = self::__filter($database,$criteria); + // extract an array of values for the requested column + $colData = array(); + foreach($database as $row) { + $colData[] = $row[$field]; + } + + // Return + return PHPExcel_Calculation_Statistical::AVERAGE($colData); + } // function DAVERAGE() + + + /** + * DCOUNT + * + * Counts the cells that contain numbers in a column of a list or database that match conditions + * that you specify. + * + * Excel Function: + * DCOUNT(database,[field],criteria) + * + * Excel Function: + * DAVERAGE(database,field,criteria) + * + * @access public + * @category Database Functions + * @param mixed[] $database The range of cells that makes up the list or database. + * A database is a list of related data in which rows of related + * information are records, and columns of data are fields. The + * first row of the list contains labels for each column. + * @param string|integer $field Indicates which column is used in the function. Enter the + * column label enclosed between double quotation marks, such as + * "Age" or "Yield," or a number (without quotation marks) that + * represents the position of the column within the list: 1 for + * the first column, 2 for the second column, and so on. + * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * You can use any range for the criteria argument, as long as it + * includes at least one column label and at least one cell below + * the column label in which you specify a condition for the + * column. + * @return integer + * + * @TODO The field argument is optional. If field is omitted, DCOUNT counts all records in the + * database that match the criteria. + * + */ + public static function DCOUNT($database,$field,$criteria) { + $field = self::__fieldExtract($database,$field); + if (is_null($field)) { + return NULL; + } + + // reduce the database to a set of rows that match all the criteria + $database = self::__filter($database,$criteria); + // extract an array of values for the requested column + $colData = array(); + foreach($database as $row) { + $colData[] = $row[$field]; + } + + // Return + return PHPExcel_Calculation_Statistical::COUNT($colData); + } // function DCOUNT() + + + /** + * DCOUNTA + * + * Counts the nonblank cells in a column of a list or database that match conditions that you specify. + * + * Excel Function: + * DCOUNTA(database,[field],criteria) + * + * @access public + * @category Database Functions + * @param mixed[] $database The range of cells that makes up the list or database. + * A database is a list of related data in which rows of related + * information are records, and columns of data are fields. The + * first row of the list contains labels for each column. + * @param string|integer $field Indicates which column is used in the function. Enter the + * column label enclosed between double quotation marks, such as + * "Age" or "Yield," or a number (without quotation marks) that + * represents the position of the column within the list: 1 for + * the first column, 2 for the second column, and so on. + * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * You can use any range for the criteria argument, as long as it + * includes at least one column label and at least one cell below + * the column label in which you specify a condition for the + * column. + * @return integer + * + * @TODO The field argument is optional. If field is omitted, DCOUNTA counts all records in the + * database that match the criteria. + * + */ + public static function DCOUNTA($database,$field,$criteria) { + $field = self::__fieldExtract($database,$field); + if (is_null($field)) { + return NULL; + } + + // reduce the database to a set of rows that match all the criteria + $database = self::__filter($database,$criteria); + // extract an array of values for the requested column + $colData = array(); + foreach($database as $row) { + $colData[] = $row[$field]; + } + + // Return + return PHPExcel_Calculation_Statistical::COUNTA($colData); + } // function DCOUNTA() + + + /** + * DGET + * + * Extracts a single value from a column of a list or database that matches conditions that you + * specify. + * + * Excel Function: + * DGET(database,field,criteria) + * + * @access public + * @category Database Functions + * @param mixed[] $database The range of cells that makes up the list or database. + * A database is a list of related data in which rows of related + * information are records, and columns of data are fields. The + * first row of the list contains labels for each column. + * @param string|integer $field Indicates which column is used in the function. Enter the + * column label enclosed between double quotation marks, such as + * "Age" or "Yield," or a number (without quotation marks) that + * represents the position of the column within the list: 1 for + * the first column, 2 for the second column, and so on. + * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * You can use any range for the criteria argument, as long as it + * includes at least one column label and at least one cell below + * the column label in which you specify a condition for the + * column. + * @return mixed + * + */ + public static function DGET($database,$field,$criteria) { + $field = self::__fieldExtract($database,$field); + if (is_null($field)) { + return NULL; + } + + // reduce the database to a set of rows that match all the criteria + $database = self::__filter($database,$criteria); + // extract an array of values for the requested column + $colData = array(); + foreach($database as $row) { + $colData[] = $row[$field]; + } + + // Return + if (count($colData) > 1) { + return PHPExcel_Calculation_Functions::NaN(); + } + + return $colData[0]; + } // function DGET() + + + /** + * DMAX + * + * Returns the largest number in a column of a list or database that matches conditions you that + * specify. + * + * Excel Function: + * DMAX(database,field,criteria) + * + * @access public + * @category Database Functions + * @param mixed[] $database The range of cells that makes up the list or database. + * A database is a list of related data in which rows of related + * information are records, and columns of data are fields. The + * first row of the list contains labels for each column. + * @param string|integer $field Indicates which column is used in the function. Enter the + * column label enclosed between double quotation marks, such as + * "Age" or "Yield," or a number (without quotation marks) that + * represents the position of the column within the list: 1 for + * the first column, 2 for the second column, and so on. + * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * You can use any range for the criteria argument, as long as it + * includes at least one column label and at least one cell below + * the column label in which you specify a condition for the + * column. + * @return float + * + */ + public static function DMAX($database,$field,$criteria) { + $field = self::__fieldExtract($database,$field); + if (is_null($field)) { + return NULL; + } + + // reduce the database to a set of rows that match all the criteria + $database = self::__filter($database,$criteria); + // extract an array of values for the requested column + $colData = array(); + foreach($database as $row) { + $colData[] = $row[$field]; + } + + // Return + return PHPExcel_Calculation_Statistical::MAX($colData); + } // function DMAX() + + + /** + * DMIN + * + * Returns the smallest number in a column of a list or database that matches conditions you that + * specify. + * + * Excel Function: + * DMIN(database,field,criteria) + * + * @access public + * @category Database Functions + * @param mixed[] $database The range of cells that makes up the list or database. + * A database is a list of related data in which rows of related + * information are records, and columns of data are fields. The + * first row of the list contains labels for each column. + * @param string|integer $field Indicates which column is used in the function. Enter the + * column label enclosed between double quotation marks, such as + * "Age" or "Yield," or a number (without quotation marks) that + * represents the position of the column within the list: 1 for + * the first column, 2 for the second column, and so on. + * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * You can use any range for the criteria argument, as long as it + * includes at least one column label and at least one cell below + * the column label in which you specify a condition for the + * column. + * @return float + * + */ + public static function DMIN($database,$field,$criteria) { + $field = self::__fieldExtract($database,$field); + if (is_null($field)) { + return NULL; + } + + // reduce the database to a set of rows that match all the criteria + $database = self::__filter($database,$criteria); + // extract an array of values for the requested column + $colData = array(); + foreach($database as $row) { + $colData[] = $row[$field]; + } + + // Return + return PHPExcel_Calculation_Statistical::MIN($colData); + } // function DMIN() + + + /** + * DPRODUCT + * + * Multiplies the values in a column of a list or database that match conditions that you specify. + * + * Excel Function: + * DPRODUCT(database,field,criteria) + * + * @access public + * @category Database Functions + * @param mixed[] $database The range of cells that makes up the list or database. + * A database is a list of related data in which rows of related + * information are records, and columns of data are fields. The + * first row of the list contains labels for each column. + * @param string|integer $field Indicates which column is used in the function. Enter the + * column label enclosed between double quotation marks, such as + * "Age" or "Yield," or a number (without quotation marks) that + * represents the position of the column within the list: 1 for + * the first column, 2 for the second column, and so on. + * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * You can use any range for the criteria argument, as long as it + * includes at least one column label and at least one cell below + * the column label in which you specify a condition for the + * column. + * @return float + * + */ + public static function DPRODUCT($database,$field,$criteria) { + $field = self::__fieldExtract($database,$field); + if (is_null($field)) { + return NULL; + } + + // reduce the database to a set of rows that match all the criteria + $database = self::__filter($database,$criteria); + // extract an array of values for the requested column + $colData = array(); + foreach($database as $row) { + $colData[] = $row[$field]; + } + + // Return + return PHPExcel_Calculation_MathTrig::PRODUCT($colData); + } // function DPRODUCT() + + + /** + * DSTDEV + * + * Estimates the standard deviation of a population based on a sample by using the numbers in a + * column of a list or database that match conditions that you specify. + * + * Excel Function: + * DSTDEV(database,field,criteria) + * + * @access public + * @category Database Functions + * @param mixed[] $database The range of cells that makes up the list or database. + * A database is a list of related data in which rows of related + * information are records, and columns of data are fields. The + * first row of the list contains labels for each column. + * @param string|integer $field Indicates which column is used in the function. Enter the + * column label enclosed between double quotation marks, such as + * "Age" or "Yield," or a number (without quotation marks) that + * represents the position of the column within the list: 1 for + * the first column, 2 for the second column, and so on. + * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * You can use any range for the criteria argument, as long as it + * includes at least one column label and at least one cell below + * the column label in which you specify a condition for the + * column. + * @return float + * + */ + public static function DSTDEV($database,$field,$criteria) { + $field = self::__fieldExtract($database,$field); + if (is_null($field)) { + return NULL; + } + + // reduce the database to a set of rows that match all the criteria + $database = self::__filter($database,$criteria); + // extract an array of values for the requested column + $colData = array(); + foreach($database as $row) { + $colData[] = $row[$field]; + } + + // Return + return PHPExcel_Calculation_Statistical::STDEV($colData); + } // function DSTDEV() + + + /** + * DSTDEVP + * + * Calculates the standard deviation of a population based on the entire population by using the + * numbers in a column of a list or database that match conditions that you specify. + * + * Excel Function: + * DSTDEVP(database,field,criteria) + * + * @access public + * @category Database Functions + * @param mixed[] $database The range of cells that makes up the list or database. + * A database is a list of related data in which rows of related + * information are records, and columns of data are fields. The + * first row of the list contains labels for each column. + * @param string|integer $field Indicates which column is used in the function. Enter the + * column label enclosed between double quotation marks, such as + * "Age" or "Yield," or a number (without quotation marks) that + * represents the position of the column within the list: 1 for + * the first column, 2 for the second column, and so on. + * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * You can use any range for the criteria argument, as long as it + * includes at least one column label and at least one cell below + * the column label in which you specify a condition for the + * column. + * @return float + * + */ + public static function DSTDEVP($database,$field,$criteria) { + $field = self::__fieldExtract($database,$field); + if (is_null($field)) { + return NULL; + } + + // reduce the database to a set of rows that match all the criteria + $database = self::__filter($database,$criteria); + // extract an array of values for the requested column + $colData = array(); + foreach($database as $row) { + $colData[] = $row[$field]; + } + + // Return + return PHPExcel_Calculation_Statistical::STDEVP($colData); + } // function DSTDEVP() + + + /** + * DSUM + * + * Adds the numbers in a column of a list or database that match conditions that you specify. + * + * Excel Function: + * DSUM(database,field,criteria) + * + * @access public + * @category Database Functions + * @param mixed[] $database The range of cells that makes up the list or database. + * A database is a list of related data in which rows of related + * information are records, and columns of data are fields. The + * first row of the list contains labels for each column. + * @param string|integer $field Indicates which column is used in the function. Enter the + * column label enclosed between double quotation marks, such as + * "Age" or "Yield," or a number (without quotation marks) that + * represents the position of the column within the list: 1 for + * the first column, 2 for the second column, and so on. + * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * You can use any range for the criteria argument, as long as it + * includes at least one column label and at least one cell below + * the column label in which you specify a condition for the + * column. + * @return float + * + */ + public static function DSUM($database,$field,$criteria) { + $field = self::__fieldExtract($database,$field); + if (is_null($field)) { + return NULL; + } + + // reduce the database to a set of rows that match all the criteria + $database = self::__filter($database,$criteria); + // extract an array of values for the requested column + $colData = array(); + foreach($database as $row) { + $colData[] = $row[$field]; + } + + // Return + return PHPExcel_Calculation_MathTrig::SUM($colData); + } // function DSUM() + + + /** + * DVAR + * + * Estimates the variance of a population based on a sample by using the numbers in a column + * of a list or database that match conditions that you specify. + * + * Excel Function: + * DVAR(database,field,criteria) + * + * @access public + * @category Database Functions + * @param mixed[] $database The range of cells that makes up the list or database. + * A database is a list of related data in which rows of related + * information are records, and columns of data are fields. The + * first row of the list contains labels for each column. + * @param string|integer $field Indicates which column is used in the function. Enter the + * column label enclosed between double quotation marks, such as + * "Age" or "Yield," or a number (without quotation marks) that + * represents the position of the column within the list: 1 for + * the first column, 2 for the second column, and so on. + * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * You can use any range for the criteria argument, as long as it + * includes at least one column label and at least one cell below + * the column label in which you specify a condition for the + * column. + * @return float + * + */ + public static function DVAR($database,$field,$criteria) { + $field = self::__fieldExtract($database,$field); + if (is_null($field)) { + return NULL; + } + + // reduce the database to a set of rows that match all the criteria + $database = self::__filter($database,$criteria); + // extract an array of values for the requested column + $colData = array(); + foreach($database as $row) { + $colData[] = $row[$field]; + } + + // Return + return PHPExcel_Calculation_Statistical::VARFunc($colData); + } // function DVAR() + + + /** + * DVARP + * + * Calculates the variance of a population based on the entire population by using the numbers + * in a column of a list or database that match conditions that you specify. + * + * Excel Function: + * DVARP(database,field,criteria) + * + * @access public + * @category Database Functions + * @param mixed[] $database The range of cells that makes up the list or database. + * A database is a list of related data in which rows of related + * information are records, and columns of data are fields. The + * first row of the list contains labels for each column. + * @param string|integer $field Indicates which column is used in the function. Enter the + * column label enclosed between double quotation marks, such as + * "Age" or "Yield," or a number (without quotation marks) that + * represents the position of the column within the list: 1 for + * the first column, 2 for the second column, and so on. + * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * You can use any range for the criteria argument, as long as it + * includes at least one column label and at least one cell below + * the column label in which you specify a condition for the + * column. + * @return float + * + */ + public static function DVARP($database,$field,$criteria) { + $field = self::__fieldExtract($database,$field); + if (is_null($field)) { + return NULL; + } + + // reduce the database to a set of rows that match all the criteria + $database = self::__filter($database,$criteria); + // extract an array of values for the requested column + $colData = array(); + foreach($database as $row) { + $colData[] = $row[$field]; + } + + // Return + return PHPExcel_Calculation_Statistical::VARP($colData); + } // function DVARP() + + +} // class PHPExcel_Calculation_Database diff --git a/lib/phpexcel/PHPExcel/Calculation/DateTime.php b/lib/phpexcel/PHPExcel/Calculation/DateTime.php new file mode 100644 index 0000000..debd131 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Calculation/DateTime.php @@ -0,0 +1,1475 @@ +format('m'); + $oYear = (int) $PHPDateObject->format('Y'); + + $adjustmentMonthsString = (string) $adjustmentMonths; + if ($adjustmentMonths > 0) { + $adjustmentMonthsString = '+'.$adjustmentMonths; + } + if ($adjustmentMonths != 0) { + $PHPDateObject->modify($adjustmentMonthsString.' months'); + } + $nMonth = (int) $PHPDateObject->format('m'); + $nYear = (int) $PHPDateObject->format('Y'); + + $monthDiff = ($nMonth - $oMonth) + (($nYear - $oYear) * 12); + if ($monthDiff != $adjustmentMonths) { + $adjustDays = (int) $PHPDateObject->format('d'); + $adjustDaysString = '-'.$adjustDays.' days'; + $PHPDateObject->modify($adjustDaysString); + } + return $PHPDateObject; + } // function _adjustDateByMonths() + + + /** + * DATETIMENOW + * + * Returns the current date and time. + * The NOW function is useful when you need to display the current date and time on a worksheet or + * calculate a value based on the current date and time, and have that value updated each time you + * open the worksheet. + * + * NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the date + * and time format of your regional settings. PHPExcel does not change cell formatting in this way. + * + * Excel Function: + * NOW() + * + * @access public + * @category Date/Time Functions + * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, + * depending on the value of the ReturnDateType flag + */ + public static function DATETIMENOW() { + $saveTimeZone = date_default_timezone_get(); + date_default_timezone_set('UTC'); + $retValue = False; + switch (PHPExcel_Calculation_Functions::getReturnDateType()) { + case PHPExcel_Calculation_Functions::RETURNDATE_EXCEL : + $retValue = (float) PHPExcel_Shared_Date::PHPToExcel(time()); + break; + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC : + $retValue = (integer) time(); + break; + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT : + $retValue = new DateTime(); + break; + } + date_default_timezone_set($saveTimeZone); + + return $retValue; + } // function DATETIMENOW() + + + /** + * DATENOW + * + * Returns the current date. + * The NOW function is useful when you need to display the current date and time on a worksheet or + * calculate a value based on the current date and time, and have that value updated each time you + * open the worksheet. + * + * NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the date + * and time format of your regional settings. PHPExcel does not change cell formatting in this way. + * + * Excel Function: + * TODAY() + * + * @access public + * @category Date/Time Functions + * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, + * depending on the value of the ReturnDateType flag + */ + public static function DATENOW() { + $saveTimeZone = date_default_timezone_get(); + date_default_timezone_set('UTC'); + $retValue = False; + $excelDateTime = floor(PHPExcel_Shared_Date::PHPToExcel(time())); + switch (PHPExcel_Calculation_Functions::getReturnDateType()) { + case PHPExcel_Calculation_Functions::RETURNDATE_EXCEL : + $retValue = (float) $excelDateTime; + break; + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC : + $retValue = (integer) PHPExcel_Shared_Date::ExcelToPHP($excelDateTime); + break; + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT : + $retValue = PHPExcel_Shared_Date::ExcelToPHPObject($excelDateTime); + break; + } + date_default_timezone_set($saveTimeZone); + + return $retValue; + } // function DATENOW() + + + /** + * DATE + * + * The DATE function returns a value that represents a particular date. + * + * NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the date + * format of your regional settings. PHPExcel does not change cell formatting in this way. + * + * Excel Function: + * DATE(year,month,day) + * + * PHPExcel is a lot more forgiving than MS Excel when passing non numeric values to this function. + * A Month name or abbreviation (English only at this point) such as 'January' or 'Jan' will still be accepted, + * as will a day value with a suffix (e.g. '21st' rather than simply 21); again only English language. + * + * @access public + * @category Date/Time Functions + * @param integer $year The value of the year argument can include one to four digits. + * Excel interprets the year argument according to the configured + * date system: 1900 or 1904. + * If year is between 0 (zero) and 1899 (inclusive), Excel adds that + * value to 1900 to calculate the year. For example, DATE(108,1,2) + * returns January 2, 2008 (1900+108). + * If year is between 1900 and 9999 (inclusive), Excel uses that + * value as the year. For example, DATE(2008,1,2) returns January 2, + * 2008. + * If year is less than 0 or is 10000 or greater, Excel returns the + * #NUM! error value. + * @param integer $month A positive or negative integer representing the month of the year + * from 1 to 12 (January to December). + * If month is greater than 12, month adds that number of months to + * the first month in the year specified. For example, DATE(2008,14,2) + * returns the serial number representing February 2, 2009. + * If month is less than 1, month subtracts the magnitude of that + * number of months, plus 1, from the first month in the year + * specified. For example, DATE(2008,-3,2) returns the serial number + * representing September 2, 2007. + * @param integer $day A positive or negative integer representing the day of the month + * from 1 to 31. + * If day is greater than the number of days in the month specified, + * day adds that number of days to the first day in the month. For + * example, DATE(2008,1,35) returns the serial number representing + * February 4, 2008. + * If day is less than 1, day subtracts the magnitude that number of + * days, plus one, from the first day of the month specified. For + * example, DATE(2008,1,-15) returns the serial number representing + * December 16, 2007. + * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, + * depending on the value of the ReturnDateType flag + */ + public static function DATE($year = 0, $month = 1, $day = 1) { + $year = PHPExcel_Calculation_Functions::flattenSingleValue($year); + $month = PHPExcel_Calculation_Functions::flattenSingleValue($month); + $day = PHPExcel_Calculation_Functions::flattenSingleValue($day); + + if (($month !== NULL) && (!is_numeric($month))) { + $month = PHPExcel_Shared_Date::monthStringToNumber($month); + } + + if (($day !== NULL) && (!is_numeric($day))) { + $day = PHPExcel_Shared_Date::dayStringToNumber($day); + } + + $year = ($year !== NULL) ? PHPExcel_Shared_String::testStringAsNumeric($year) : 0; + $month = ($month !== NULL) ? PHPExcel_Shared_String::testStringAsNumeric($month) : 0; + $day = ($day !== NULL) ? PHPExcel_Shared_String::testStringAsNumeric($day) : 0; + if ((!is_numeric($year)) || + (!is_numeric($month)) || + (!is_numeric($day))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $year = (integer) $year; + $month = (integer) $month; + $day = (integer) $day; + + $baseYear = PHPExcel_Shared_Date::getExcelCalendar(); + // Validate parameters + if ($year < ($baseYear-1900)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ((($baseYear-1900) != 0) && ($year < $baseYear) && ($year >= 1900)) { + return PHPExcel_Calculation_Functions::NaN(); + } + + if (($year < $baseYear) && ($year >= ($baseYear-1900))) { + $year += 1900; + } + + if ($month < 1) { + // Handle year/month adjustment if month < 1 + --$month; + $year += ceil($month / 12) - 1; + $month = 13 - abs($month % 12); + } elseif ($month > 12) { + // Handle year/month adjustment if month > 12 + $year += floor($month / 12); + $month = ($month % 12); + } + + // Re-validate the year parameter after adjustments + if (($year < $baseYear) || ($year >= 10000)) { + return PHPExcel_Calculation_Functions::NaN(); + } + + // Execute function + $excelDateValue = PHPExcel_Shared_Date::FormattedPHPToExcel($year, $month, $day); + switch (PHPExcel_Calculation_Functions::getReturnDateType()) { + case PHPExcel_Calculation_Functions::RETURNDATE_EXCEL : + return (float) $excelDateValue; + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC : + return (integer) PHPExcel_Shared_Date::ExcelToPHP($excelDateValue); + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT : + return PHPExcel_Shared_Date::ExcelToPHPObject($excelDateValue); + } + } // function DATE() + + + /** + * TIME + * + * The TIME function returns a value that represents a particular time. + * + * NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the time + * format of your regional settings. PHPExcel does not change cell formatting in this way. + * + * Excel Function: + * TIME(hour,minute,second) + * + * @access public + * @category Date/Time Functions + * @param integer $hour A number from 0 (zero) to 32767 representing the hour. + * Any value greater than 23 will be divided by 24 and the remainder + * will be treated as the hour value. For example, TIME(27,0,0) = + * TIME(3,0,0) = .125 or 3:00 AM. + * @param integer $minute A number from 0 to 32767 representing the minute. + * Any value greater than 59 will be converted to hours and minutes. + * For example, TIME(0,750,0) = TIME(12,30,0) = .520833 or 12:30 PM. + * @param integer $second A number from 0 to 32767 representing the second. + * Any value greater than 59 will be converted to hours, minutes, + * and seconds. For example, TIME(0,0,2000) = TIME(0,33,22) = .023148 + * or 12:33:20 AM + * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, + * depending on the value of the ReturnDateType flag + */ + public static function TIME($hour = 0, $minute = 0, $second = 0) { + $hour = PHPExcel_Calculation_Functions::flattenSingleValue($hour); + $minute = PHPExcel_Calculation_Functions::flattenSingleValue($minute); + $second = PHPExcel_Calculation_Functions::flattenSingleValue($second); + + if ($hour == '') { $hour = 0; } + if ($minute == '') { $minute = 0; } + if ($second == '') { $second = 0; } + + if ((!is_numeric($hour)) || (!is_numeric($minute)) || (!is_numeric($second))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $hour = (integer) $hour; + $minute = (integer) $minute; + $second = (integer) $second; + + if ($second < 0) { + $minute += floor($second / 60); + $second = 60 - abs($second % 60); + if ($second == 60) { $second = 0; } + } elseif ($second >= 60) { + $minute += floor($second / 60); + $second = $second % 60; + } + if ($minute < 0) { + $hour += floor($minute / 60); + $minute = 60 - abs($minute % 60); + if ($minute == 60) { $minute = 0; } + } elseif ($minute >= 60) { + $hour += floor($minute / 60); + $minute = $minute % 60; + } + + if ($hour > 23) { + $hour = $hour % 24; + } elseif ($hour < 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + + // Execute function + switch (PHPExcel_Calculation_Functions::getReturnDateType()) { + case PHPExcel_Calculation_Functions::RETURNDATE_EXCEL : + $date = 0; + $calendar = PHPExcel_Shared_Date::getExcelCalendar(); + if ($calendar != PHPExcel_Shared_Date::CALENDAR_WINDOWS_1900) { + $date = 1; + } + return (float) PHPExcel_Shared_Date::FormattedPHPToExcel($calendar, 1, $date, $hour, $minute, $second); + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC : + return (integer) PHPExcel_Shared_Date::ExcelToPHP(PHPExcel_Shared_Date::FormattedPHPToExcel(1970, 1, 1, $hour, $minute, $second)); // -2147468400; // -2147472000 + 3600 + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT : + $dayAdjust = 0; + if ($hour < 0) { + $dayAdjust = floor($hour / 24); + $hour = 24 - abs($hour % 24); + if ($hour == 24) { $hour = 0; } + } elseif ($hour >= 24) { + $dayAdjust = floor($hour / 24); + $hour = $hour % 24; + } + $phpDateObject = new DateTime('1900-01-01 '.$hour.':'.$minute.':'.$second); + if ($dayAdjust != 0) { + $phpDateObject->modify($dayAdjust.' days'); + } + return $phpDateObject; + } + } // function TIME() + + + /** + * DATEVALUE + * + * Returns a value that represents a particular date. + * Use DATEVALUE to convert a date represented by a text string to an Excel or PHP date/time stamp + * value. + * + * NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the date + * format of your regional settings. PHPExcel does not change cell formatting in this way. + * + * Excel Function: + * DATEVALUE(dateValue) + * + * @access public + * @category Date/Time Functions + * @param string $dateValue Text that represents a date in a Microsoft Excel date format. + * For example, "1/30/2008" or "30-Jan-2008" are text strings within + * quotation marks that represent dates. Using the default date + * system in Excel for Windows, date_text must represent a date from + * January 1, 1900, to December 31, 9999. Using the default date + * system in Excel for the Macintosh, date_text must represent a date + * from January 1, 1904, to December 31, 9999. DATEVALUE returns the + * #VALUE! error value if date_text is out of this range. + * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, + * depending on the value of the ReturnDateType flag + */ + public static function DATEVALUE($dateValue = 1) { + $dateValue = trim(PHPExcel_Calculation_Functions::flattenSingleValue($dateValue),'"'); + // Strip any ordinals because they're allowed in Excel (English only) + $dateValue = preg_replace('/(\d)(st|nd|rd|th)([ -\/])/Ui','$1$3',$dateValue); + // Convert separators (/ . or space) to hyphens (should also handle dot used for ordinals in some countries, e.g. Denmark, Germany) + $dateValue = str_replace(array('/','.','-',' '),array(' ',' ',' ',' '),$dateValue); + + $yearFound = false; + $t1 = explode(' ',$dateValue); + foreach($t1 as &$t) { + if ((is_numeric($t)) && ($t > 31)) { + if ($yearFound) { + return PHPExcel_Calculation_Functions::VALUE(); + } else { + if ($t < 100) { $t += 1900; } + $yearFound = true; + } + } + } + if ((count($t1) == 1) && (strpos($t,':') != false)) { + // We've been fed a time value without any date + return 0.0; + } elseif (count($t1) == 2) { + // We only have two parts of the date: either day/month or month/year + if ($yearFound) { + array_unshift($t1,1); + } else { + array_push($t1,date('Y')); + } + } + unset($t); + $dateValue = implode(' ',$t1); + + $PHPDateArray = date_parse($dateValue); + if (($PHPDateArray === False) || ($PHPDateArray['error_count'] > 0)) { + $testVal1 = strtok($dateValue,'- '); + if ($testVal1 !== False) { + $testVal2 = strtok('- '); + if ($testVal2 !== False) { + $testVal3 = strtok('- '); + if ($testVal3 === False) { + $testVal3 = strftime('%Y'); + } + } else { + return PHPExcel_Calculation_Functions::VALUE(); + } + } else { + return PHPExcel_Calculation_Functions::VALUE(); + } + $PHPDateArray = date_parse($testVal1.'-'.$testVal2.'-'.$testVal3); + if (($PHPDateArray === False) || ($PHPDateArray['error_count'] > 0)) { + $PHPDateArray = date_parse($testVal2.'-'.$testVal1.'-'.$testVal3); + if (($PHPDateArray === False) || ($PHPDateArray['error_count'] > 0)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + } + + if (($PHPDateArray !== False) && ($PHPDateArray['error_count'] == 0)) { + // Execute function + if ($PHPDateArray['year'] == '') { $PHPDateArray['year'] = strftime('%Y'); } + if ($PHPDateArray['year'] < 1900) + return PHPExcel_Calculation_Functions::VALUE(); + if ($PHPDateArray['month'] == '') { $PHPDateArray['month'] = strftime('%m'); } + if ($PHPDateArray['day'] == '') { $PHPDateArray['day'] = strftime('%d'); } + $excelDateValue = floor(PHPExcel_Shared_Date::FormattedPHPToExcel($PHPDateArray['year'],$PHPDateArray['month'],$PHPDateArray['day'],$PHPDateArray['hour'],$PHPDateArray['minute'],$PHPDateArray['second'])); + + switch (PHPExcel_Calculation_Functions::getReturnDateType()) { + case PHPExcel_Calculation_Functions::RETURNDATE_EXCEL : + return (float) $excelDateValue; + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC : + return (integer) PHPExcel_Shared_Date::ExcelToPHP($excelDateValue); + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT : + return new DateTime($PHPDateArray['year'].'-'.$PHPDateArray['month'].'-'.$PHPDateArray['day'].' 00:00:00'); + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function DATEVALUE() + + + /** + * TIMEVALUE + * + * Returns a value that represents a particular time. + * Use TIMEVALUE to convert a time represented by a text string to an Excel or PHP date/time stamp + * value. + * + * NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the time + * format of your regional settings. PHPExcel does not change cell formatting in this way. + * + * Excel Function: + * TIMEVALUE(timeValue) + * + * @access public + * @category Date/Time Functions + * @param string $timeValue A text string that represents a time in any one of the Microsoft + * Excel time formats; for example, "6:45 PM" and "18:45" text strings + * within quotation marks that represent time. + * Date information in time_text is ignored. + * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, + * depending on the value of the ReturnDateType flag + */ + public static function TIMEVALUE($timeValue) { + $timeValue = trim(PHPExcel_Calculation_Functions::flattenSingleValue($timeValue),'"'); + $timeValue = str_replace(array('/','.'),array('-','-'),$timeValue); + + $PHPDateArray = date_parse($timeValue); + if (($PHPDateArray !== False) && ($PHPDateArray['error_count'] == 0)) { + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { + $excelDateValue = PHPExcel_Shared_Date::FormattedPHPToExcel($PHPDateArray['year'],$PHPDateArray['month'],$PHPDateArray['day'],$PHPDateArray['hour'],$PHPDateArray['minute'],$PHPDateArray['second']); + } else { + $excelDateValue = PHPExcel_Shared_Date::FormattedPHPToExcel(1900,1,1,$PHPDateArray['hour'],$PHPDateArray['minute'],$PHPDateArray['second']) - 1; + } + + switch (PHPExcel_Calculation_Functions::getReturnDateType()) { + case PHPExcel_Calculation_Functions::RETURNDATE_EXCEL : + return (float) $excelDateValue; + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC : + return (integer) $phpDateValue = PHPExcel_Shared_Date::ExcelToPHP($excelDateValue+25569) - 3600;; + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT : + return new DateTime('1900-01-01 '.$PHPDateArray['hour'].':'.$PHPDateArray['minute'].':'.$PHPDateArray['second']); + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function TIMEVALUE() + + + /** + * DATEDIF + * + * @param mixed $startDate Excel date serial value, PHP date/time stamp, PHP DateTime object + * or a standard date string + * @param mixed $endDate Excel date serial value, PHP date/time stamp, PHP DateTime object + * or a standard date string + * @param string $unit + * @return integer Interval between the dates + */ + public static function DATEDIF($startDate = 0, $endDate = 0, $unit = 'D') { + $startDate = PHPExcel_Calculation_Functions::flattenSingleValue($startDate); + $endDate = PHPExcel_Calculation_Functions::flattenSingleValue($endDate); + $unit = strtoupper(PHPExcel_Calculation_Functions::flattenSingleValue($unit)); + + if (is_string($startDate = self::_getDateValue($startDate))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + if (is_string($endDate = self::_getDateValue($endDate))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + // Validate parameters + if ($startDate >= $endDate) { + return PHPExcel_Calculation_Functions::NaN(); + } + + // Execute function + $difference = $endDate - $startDate; + + $PHPStartDateObject = PHPExcel_Shared_Date::ExcelToPHPObject($startDate); + $startDays = $PHPStartDateObject->format('j'); + $startMonths = $PHPStartDateObject->format('n'); + $startYears = $PHPStartDateObject->format('Y'); + + $PHPEndDateObject = PHPExcel_Shared_Date::ExcelToPHPObject($endDate); + $endDays = $PHPEndDateObject->format('j'); + $endMonths = $PHPEndDateObject->format('n'); + $endYears = $PHPEndDateObject->format('Y'); + + $retVal = PHPExcel_Calculation_Functions::NaN(); + switch ($unit) { + case 'D': + $retVal = intval($difference); + break; + case 'M': + $retVal = intval($endMonths - $startMonths) + (intval($endYears - $startYears) * 12); + // We're only interested in full months + if ($endDays < $startDays) { + --$retVal; + } + break; + case 'Y': + $retVal = intval($endYears - $startYears); + // We're only interested in full months + if ($endMonths < $startMonths) { + --$retVal; + } elseif (($endMonths == $startMonths) && ($endDays < $startDays)) { + --$retVal; + } + break; + case 'MD': + if ($endDays < $startDays) { + $retVal = $endDays; + $PHPEndDateObject->modify('-'.$endDays.' days'); + $adjustDays = $PHPEndDateObject->format('j'); + if ($adjustDays > $startDays) { + $retVal += ($adjustDays - $startDays); + } + } else { + $retVal = $endDays - $startDays; + } + break; + case 'YM': + $retVal = intval($endMonths - $startMonths); + if ($retVal < 0) $retVal = 12 + $retVal; + // We're only interested in full months + if ($endDays < $startDays) { + --$retVal; + } + break; + case 'YD': + $retVal = intval($difference); + if ($endYears > $startYears) { + while ($endYears > $startYears) { + $PHPEndDateObject->modify('-1 year'); + $endYears = $PHPEndDateObject->format('Y'); + } + $retVal = $PHPEndDateObject->format('z') - $PHPStartDateObject->format('z'); + if ($retVal < 0) { $retVal += 365; } + } + break; + default: + $retVal = PHPExcel_Calculation_Functions::NaN(); + } + return $retVal; + } // function DATEDIF() + + + /** + * DAYS360 + * + * Returns the number of days between two dates based on a 360-day year (twelve 30-day months), + * which is used in some accounting calculations. Use this function to help compute payments if + * your accounting system is based on twelve 30-day months. + * + * Excel Function: + * DAYS360(startDate,endDate[,method]) + * + * @access public + * @category Date/Time Functions + * @param mixed $startDate Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard date string + * @param mixed $endDate Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard date string + * @param boolean $method US or European Method + * FALSE or omitted: U.S. (NASD) method. If the starting date is + * the last day of a month, it becomes equal to the 30th of the + * same month. If the ending date is the last day of a month and + * the starting date is earlier than the 30th of a month, the + * ending date becomes equal to the 1st of the next month; + * otherwise the ending date becomes equal to the 30th of the + * same month. + * TRUE: European method. Starting dates and ending dates that + * occur on the 31st of a month become equal to the 30th of the + * same month. + * @return integer Number of days between start date and end date + */ + public static function DAYS360($startDate = 0, $endDate = 0, $method = false) { + $startDate = PHPExcel_Calculation_Functions::flattenSingleValue($startDate); + $endDate = PHPExcel_Calculation_Functions::flattenSingleValue($endDate); + + if (is_string($startDate = self::_getDateValue($startDate))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + if (is_string($endDate = self::_getDateValue($endDate))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (!is_bool($method)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + // Execute function + $PHPStartDateObject = PHPExcel_Shared_Date::ExcelToPHPObject($startDate); + $startDay = $PHPStartDateObject->format('j'); + $startMonth = $PHPStartDateObject->format('n'); + $startYear = $PHPStartDateObject->format('Y'); + + $PHPEndDateObject = PHPExcel_Shared_Date::ExcelToPHPObject($endDate); + $endDay = $PHPEndDateObject->format('j'); + $endMonth = $PHPEndDateObject->format('n'); + $endYear = $PHPEndDateObject->format('Y'); + + return self::_dateDiff360($startDay, $startMonth, $startYear, $endDay, $endMonth, $endYear, !$method); + } // function DAYS360() + + + /** + * YEARFRAC + * + * Calculates the fraction of the year represented by the number of whole days between two dates + * (the start_date and the end_date). + * Use the YEARFRAC worksheet function to identify the proportion of a whole year's benefits or + * obligations to assign to a specific term. + * + * Excel Function: + * YEARFRAC(startDate,endDate[,method]) + * + * @access public + * @category Date/Time Functions + * @param mixed $startDate Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard date string + * @param mixed $endDate Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard date string + * @param integer $method Method used for the calculation + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return float fraction of the year + */ + public static function YEARFRAC($startDate = 0, $endDate = 0, $method = 0) { + $startDate = PHPExcel_Calculation_Functions::flattenSingleValue($startDate); + $endDate = PHPExcel_Calculation_Functions::flattenSingleValue($endDate); + $method = PHPExcel_Calculation_Functions::flattenSingleValue($method); + + if (is_string($startDate = self::_getDateValue($startDate))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + if (is_string($endDate = self::_getDateValue($endDate))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (((is_numeric($method)) && (!is_string($method))) || ($method == '')) { + switch($method) { + case 0 : + return self::DAYS360($startDate,$endDate) / 360; + case 1 : + $days = self::DATEDIF($startDate,$endDate); + $startYear = self::YEAR($startDate); + $endYear = self::YEAR($endDate); + $years = $endYear - $startYear + 1; + $leapDays = 0; + if ($years == 1) { + if (self::_isLeapYear($endYear)) { + $startMonth = self::MONTHOFYEAR($startDate); + $endMonth = self::MONTHOFYEAR($endDate); + $endDay = self::DAYOFMONTH($endDate); + if (($startMonth < 3) || + (($endMonth * 100 + $endDay) >= (2 * 100 + 29))) { + $leapDays += 1; + } + } + } else { + for($year = $startYear; $year <= $endYear; ++$year) { + if ($year == $startYear) { + $startMonth = self::MONTHOFYEAR($startDate); + $startDay = self::DAYOFMONTH($startDate); + if ($startMonth < 3) { + $leapDays += (self::_isLeapYear($year)) ? 1 : 0; + } + } elseif($year == $endYear) { + $endMonth = self::MONTHOFYEAR($endDate); + $endDay = self::DAYOFMONTH($endDate); + if (($endMonth * 100 + $endDay) >= (2 * 100 + 29)) { + $leapDays += (self::_isLeapYear($year)) ? 1 : 0; + } + } else { + $leapDays += (self::_isLeapYear($year)) ? 1 : 0; + } + } + if ($years == 2) { + if (($leapDays == 0) && (self::_isLeapYear($startYear)) && ($days > 365)) { + $leapDays = 1; + } elseif ($days < 366) { + $years = 1; + } + } + $leapDays /= $years; + } + return $days / (365 + $leapDays); + case 2 : + return self::DATEDIF($startDate,$endDate) / 360; + case 3 : + return self::DATEDIF($startDate,$endDate) / 365; + case 4 : + return self::DAYS360($startDate,$endDate,True) / 360; + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function YEARFRAC() + + + /** + * NETWORKDAYS + * + * Returns the number of whole working days between start_date and end_date. Working days + * exclude weekends and any dates identified in holidays. + * Use NETWORKDAYS to calculate employee benefits that accrue based on the number of days + * worked during a specific term. + * + * Excel Function: + * NETWORKDAYS(startDate,endDate[,holidays[,holiday[,...]]]) + * + * @access public + * @category Date/Time Functions + * @param mixed $startDate Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard date string + * @param mixed $endDate Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard date string + * @param mixed $holidays,... Optional series of Excel date serial value (float), PHP date + * timestamp (integer), PHP DateTime object, or a standard date + * strings that will be excluded from the working calendar, such + * as state and federal holidays and floating holidays. + * @return integer Interval between the dates + */ + public static function NETWORKDAYS($startDate,$endDate) { + // Retrieve the mandatory start and end date that are referenced in the function definition + $startDate = PHPExcel_Calculation_Functions::flattenSingleValue($startDate); + $endDate = PHPExcel_Calculation_Functions::flattenSingleValue($endDate); + // Flush the mandatory start and end date that are referenced in the function definition, and get the optional days + $dateArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + array_shift($dateArgs); + array_shift($dateArgs); + + // Validate the start and end dates + if (is_string($startDate = $sDate = self::_getDateValue($startDate))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $startDate = (float) floor($startDate); + if (is_string($endDate = $eDate = self::_getDateValue($endDate))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $endDate = (float) floor($endDate); + + if ($sDate > $eDate) { + $startDate = $eDate; + $endDate = $sDate; + } + + // Execute function + $startDoW = 6 - self::DAYOFWEEK($startDate,2); + if ($startDoW < 0) { $startDoW = 0; } + $endDoW = self::DAYOFWEEK($endDate,2); + if ($endDoW >= 6) { $endDoW = 0; } + + $wholeWeekDays = floor(($endDate - $startDate) / 7) * 5; + $partWeekDays = $endDoW + $startDoW; + if ($partWeekDays > 5) { + $partWeekDays -= 5; + } + + // Test any extra holiday parameters + $holidayCountedArray = array(); + foreach ($dateArgs as $holidayDate) { + if (is_string($holidayDate = self::_getDateValue($holidayDate))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + if (($holidayDate >= $startDate) && ($holidayDate <= $endDate)) { + if ((self::DAYOFWEEK($holidayDate,2) < 6) && (!in_array($holidayDate,$holidayCountedArray))) { + --$partWeekDays; + $holidayCountedArray[] = $holidayDate; + } + } + } + + if ($sDate > $eDate) { + return 0 - ($wholeWeekDays + $partWeekDays); + } + return $wholeWeekDays + $partWeekDays; + } // function NETWORKDAYS() + + + /** + * WORKDAY + * + * Returns the date that is the indicated number of working days before or after a date (the + * starting date). Working days exclude weekends and any dates identified as holidays. + * Use WORKDAY to exclude weekends or holidays when you calculate invoice due dates, expected + * delivery times, or the number of days of work performed. + * + * Excel Function: + * WORKDAY(startDate,endDays[,holidays[,holiday[,...]]]) + * + * @access public + * @category Date/Time Functions + * @param mixed $startDate Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard date string + * @param integer $endDays The number of nonweekend and nonholiday days before or after + * startDate. A positive value for days yields a future date; a + * negative value yields a past date. + * @param mixed $holidays,... Optional series of Excel date serial value (float), PHP date + * timestamp (integer), PHP DateTime object, or a standard date + * strings that will be excluded from the working calendar, such + * as state and federal holidays and floating holidays. + * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, + * depending on the value of the ReturnDateType flag + */ + public static function WORKDAY($startDate,$endDays) { + // Retrieve the mandatory start date and days that are referenced in the function definition + $startDate = PHPExcel_Calculation_Functions::flattenSingleValue($startDate); + $endDays = PHPExcel_Calculation_Functions::flattenSingleValue($endDays); + // Flush the mandatory start date and days that are referenced in the function definition, and get the optional days + $dateArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + array_shift($dateArgs); + array_shift($dateArgs); + + if ((is_string($startDate = self::_getDateValue($startDate))) || (!is_numeric($endDays))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $startDate = (float) floor($startDate); + $endDays = (int) floor($endDays); + // If endDays is 0, we always return startDate + if ($endDays == 0) { return $startDate; } + + $decrementing = ($endDays < 0) ? True : False; + + // Adjust the start date if it falls over a weekend + + $startDoW = self::DAYOFWEEK($startDate,3); + if (self::DAYOFWEEK($startDate,3) >= 5) { + $startDate += ($decrementing) ? -$startDoW + 4: 7 - $startDoW; + ($decrementing) ? $endDays++ : $endDays--; + } + + // Add endDays + $endDate = (float) $startDate + (intval($endDays / 5) * 7) + ($endDays % 5); + + // Adjust the calculated end date if it falls over a weekend + $endDoW = self::DAYOFWEEK($endDate,3); + if ($endDoW >= 5) { + $endDate += ($decrementing) ? -$endDoW + 4: 7 - $endDoW; + } + + // Test any extra holiday parameters + if (!empty($dateArgs)) { + $holidayCountedArray = $holidayDates = array(); + foreach ($dateArgs as $holidayDate) { + if (($holidayDate !== NULL) && (trim($holidayDate) > '')) { + if (is_string($holidayDate = self::_getDateValue($holidayDate))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + if (self::DAYOFWEEK($holidayDate,3) < 5) { + $holidayDates[] = $holidayDate; + } + } + } + if ($decrementing) { + rsort($holidayDates, SORT_NUMERIC); + } else { + sort($holidayDates, SORT_NUMERIC); + } + foreach ($holidayDates as $holidayDate) { + if ($decrementing) { + if (($holidayDate <= $startDate) && ($holidayDate >= $endDate)) { + if (!in_array($holidayDate,$holidayCountedArray)) { + --$endDate; + $holidayCountedArray[] = $holidayDate; + } + } + } else { + if (($holidayDate >= $startDate) && ($holidayDate <= $endDate)) { + if (!in_array($holidayDate,$holidayCountedArray)) { + ++$endDate; + $holidayCountedArray[] = $holidayDate; + } + } + } + // Adjust the calculated end date if it falls over a weekend + $endDoW = self::DAYOFWEEK($endDate,3); + if ($endDoW >= 5) { + $endDate += ($decrementing) ? -$endDoW + 4: 7 - $endDoW; + } + + } + } + + switch (PHPExcel_Calculation_Functions::getReturnDateType()) { + case PHPExcel_Calculation_Functions::RETURNDATE_EXCEL : + return (float) $endDate; + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC : + return (integer) PHPExcel_Shared_Date::ExcelToPHP($endDate); + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT : + return PHPExcel_Shared_Date::ExcelToPHPObject($endDate); + } + } // function WORKDAY() + + + /** + * DAYOFMONTH + * + * Returns the day of the month, for a specified date. The day is given as an integer + * ranging from 1 to 31. + * + * Excel Function: + * DAY(dateValue) + * + * @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard date string + * @return int Day of the month + */ + public static function DAYOFMONTH($dateValue = 1) { + $dateValue = PHPExcel_Calculation_Functions::flattenSingleValue($dateValue); + + if (is_string($dateValue = self::_getDateValue($dateValue))) { + return PHPExcel_Calculation_Functions::VALUE(); + } elseif ($dateValue == 0.0) { + return 0; + } elseif ($dateValue < 0.0) { + return PHPExcel_Calculation_Functions::NaN(); + } + + // Execute function + $PHPDateObject = PHPExcel_Shared_Date::ExcelToPHPObject($dateValue); + + return (int) $PHPDateObject->format('j'); + } // function DAYOFMONTH() + + + /** + * DAYOFWEEK + * + * Returns the day of the week for a specified date. The day is given as an integer + * ranging from 0 to 7 (dependent on the requested style). + * + * Excel Function: + * WEEKDAY(dateValue[,style]) + * + * @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard date string + * @param int $style A number that determines the type of return value + * 1 or omitted Numbers 1 (Sunday) through 7 (Saturday). + * 2 Numbers 1 (Monday) through 7 (Sunday). + * 3 Numbers 0 (Monday) through 6 (Sunday). + * @return int Day of the week value + */ + public static function DAYOFWEEK($dateValue = 1, $style = 1) { + $dateValue = PHPExcel_Calculation_Functions::flattenSingleValue($dateValue); + $style = PHPExcel_Calculation_Functions::flattenSingleValue($style); + + if (!is_numeric($style)) { + return PHPExcel_Calculation_Functions::VALUE(); + } elseif (($style < 1) || ($style > 3)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $style = floor($style); + + if (is_string($dateValue = self::_getDateValue($dateValue))) { + return PHPExcel_Calculation_Functions::VALUE(); + } elseif ($dateValue < 0.0) { + return PHPExcel_Calculation_Functions::NaN(); + } + + // Execute function + $PHPDateObject = PHPExcel_Shared_Date::ExcelToPHPObject($dateValue); + $DoW = $PHPDateObject->format('w'); + + $firstDay = 1; + switch ($style) { + case 1: ++$DoW; + break; + case 2: if ($DoW == 0) { $DoW = 7; } + break; + case 3: if ($DoW == 0) { $DoW = 7; } + $firstDay = 0; + --$DoW; + break; + } + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL) { + // Test for Excel's 1900 leap year, and introduce the error as required + if (($PHPDateObject->format('Y') == 1900) && ($PHPDateObject->format('n') <= 2)) { + --$DoW; + if ($DoW < $firstDay) { + $DoW += 7; + } + } + } + + return (int) $DoW; + } // function DAYOFWEEK() + + + /** + * WEEKOFYEAR + * + * Returns the week of the year for a specified date. + * The WEEKNUM function considers the week containing January 1 to be the first week of the year. + * However, there is a European standard that defines the first week as the one with the majority + * of days (four or more) falling in the new year. This means that for years in which there are + * three days or less in the first week of January, the WEEKNUM function returns week numbers + * that are incorrect according to the European standard. + * + * Excel Function: + * WEEKNUM(dateValue[,style]) + * + * @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard date string + * @param boolean $method Week begins on Sunday or Monday + * 1 or omitted Week begins on Sunday. + * 2 Week begins on Monday. + * @return int Week Number + */ + public static function WEEKOFYEAR($dateValue = 1, $method = 1) { + $dateValue = PHPExcel_Calculation_Functions::flattenSingleValue($dateValue); + $method = PHPExcel_Calculation_Functions::flattenSingleValue($method); + + if (!is_numeric($method)) { + return PHPExcel_Calculation_Functions::VALUE(); + } elseif (($method < 1) || ($method > 2)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $method = floor($method); + + if (is_string($dateValue = self::_getDateValue($dateValue))) { + return PHPExcel_Calculation_Functions::VALUE(); + } elseif ($dateValue < 0.0) { + return PHPExcel_Calculation_Functions::NaN(); + } + + // Execute function + $PHPDateObject = PHPExcel_Shared_Date::ExcelToPHPObject($dateValue); + $dayOfYear = $PHPDateObject->format('z'); + $dow = $PHPDateObject->format('w'); + $PHPDateObject->modify('-'.$dayOfYear.' days'); + $dow = $PHPDateObject->format('w'); + $daysInFirstWeek = 7 - (($dow + (2 - $method)) % 7); + $dayOfYear -= $daysInFirstWeek; + $weekOfYear = ceil($dayOfYear / 7) + 1; + + return (int) $weekOfYear; + } // function WEEKOFYEAR() + + + /** + * MONTHOFYEAR + * + * Returns the month of a date represented by a serial number. + * The month is given as an integer, ranging from 1 (January) to 12 (December). + * + * Excel Function: + * MONTH(dateValue) + * + * @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard date string + * @return int Month of the year + */ + public static function MONTHOFYEAR($dateValue = 1) { + $dateValue = PHPExcel_Calculation_Functions::flattenSingleValue($dateValue); + + if (is_string($dateValue = self::_getDateValue($dateValue))) { + return PHPExcel_Calculation_Functions::VALUE(); + } elseif ($dateValue < 0.0) { + return PHPExcel_Calculation_Functions::NaN(); + } + + // Execute function + $PHPDateObject = PHPExcel_Shared_Date::ExcelToPHPObject($dateValue); + + return (int) $PHPDateObject->format('n'); + } // function MONTHOFYEAR() + + + /** + * YEAR + * + * Returns the year corresponding to a date. + * The year is returned as an integer in the range 1900-9999. + * + * Excel Function: + * YEAR(dateValue) + * + * @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard date string + * @return int Year + */ + public static function YEAR($dateValue = 1) { + $dateValue = PHPExcel_Calculation_Functions::flattenSingleValue($dateValue); + + if (is_string($dateValue = self::_getDateValue($dateValue))) { + return PHPExcel_Calculation_Functions::VALUE(); + } elseif ($dateValue < 0.0) { + return PHPExcel_Calculation_Functions::NaN(); + } + + // Execute function + $PHPDateObject = PHPExcel_Shared_Date::ExcelToPHPObject($dateValue); + + return (int) $PHPDateObject->format('Y'); + } // function YEAR() + + + /** + * HOUROFDAY + * + * Returns the hour of a time value. + * The hour is given as an integer, ranging from 0 (12:00 A.M.) to 23 (11:00 P.M.). + * + * Excel Function: + * HOUR(timeValue) + * + * @param mixed $timeValue Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard time string + * @return int Hour + */ + public static function HOUROFDAY($timeValue = 0) { + $timeValue = PHPExcel_Calculation_Functions::flattenSingleValue($timeValue); + + if (!is_numeric($timeValue)) { + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) { + $testVal = strtok($timeValue,'/-: '); + if (strlen($testVal) < strlen($timeValue)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + $timeValue = self::_getTimeValue($timeValue); + if (is_string($timeValue)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + // Execute function + if ($timeValue >= 1) { + $timeValue = fmod($timeValue,1); + } elseif ($timeValue < 0.0) { + return PHPExcel_Calculation_Functions::NaN(); + } + $timeValue = PHPExcel_Shared_Date::ExcelToPHP($timeValue); + + return (int) gmdate('G',$timeValue); + } // function HOUROFDAY() + + + /** + * MINUTEOFHOUR + * + * Returns the minutes of a time value. + * The minute is given as an integer, ranging from 0 to 59. + * + * Excel Function: + * MINUTE(timeValue) + * + * @param mixed $timeValue Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard time string + * @return int Minute + */ + public static function MINUTEOFHOUR($timeValue = 0) { + $timeValue = $timeTester = PHPExcel_Calculation_Functions::flattenSingleValue($timeValue); + + if (!is_numeric($timeValue)) { + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) { + $testVal = strtok($timeValue,'/-: '); + if (strlen($testVal) < strlen($timeValue)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + $timeValue = self::_getTimeValue($timeValue); + if (is_string($timeValue)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + // Execute function + if ($timeValue >= 1) { + $timeValue = fmod($timeValue,1); + } elseif ($timeValue < 0.0) { + return PHPExcel_Calculation_Functions::NaN(); + } + $timeValue = PHPExcel_Shared_Date::ExcelToPHP($timeValue); + + return (int) gmdate('i',$timeValue); + } // function MINUTEOFHOUR() + + + /** + * SECONDOFMINUTE + * + * Returns the seconds of a time value. + * The second is given as an integer in the range 0 (zero) to 59. + * + * Excel Function: + * SECOND(timeValue) + * + * @param mixed $timeValue Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard time string + * @return int Second + */ + public static function SECONDOFMINUTE($timeValue = 0) { + $timeValue = PHPExcel_Calculation_Functions::flattenSingleValue($timeValue); + + if (!is_numeric($timeValue)) { + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) { + $testVal = strtok($timeValue,'/-: '); + if (strlen($testVal) < strlen($timeValue)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + $timeValue = self::_getTimeValue($timeValue); + if (is_string($timeValue)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + // Execute function + if ($timeValue >= 1) { + $timeValue = fmod($timeValue,1); + } elseif ($timeValue < 0.0) { + return PHPExcel_Calculation_Functions::NaN(); + } + $timeValue = PHPExcel_Shared_Date::ExcelToPHP($timeValue); + + return (int) gmdate('s',$timeValue); + } // function SECONDOFMINUTE() + + + /** + * EDATE + * + * Returns the serial number that represents the date that is the indicated number of months + * before or after a specified date (the start_date). + * Use EDATE to calculate maturity dates or due dates that fall on the same day of the month + * as the date of issue. + * + * Excel Function: + * EDATE(dateValue,adjustmentMonths) + * + * @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard date string + * @param int $adjustmentMonths The number of months before or after start_date. + * A positive value for months yields a future date; + * a negative value yields a past date. + * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, + * depending on the value of the ReturnDateType flag + */ + public static function EDATE($dateValue = 1, $adjustmentMonths = 0) { + $dateValue = PHPExcel_Calculation_Functions::flattenSingleValue($dateValue); + $adjustmentMonths = PHPExcel_Calculation_Functions::flattenSingleValue($adjustmentMonths); + + if (!is_numeric($adjustmentMonths)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $adjustmentMonths = floor($adjustmentMonths); + + if (is_string($dateValue = self::_getDateValue($dateValue))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + // Execute function + $PHPDateObject = self::_adjustDateByMonths($dateValue,$adjustmentMonths); + + switch (PHPExcel_Calculation_Functions::getReturnDateType()) { + case PHPExcel_Calculation_Functions::RETURNDATE_EXCEL : + return (float) PHPExcel_Shared_Date::PHPToExcel($PHPDateObject); + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC : + return (integer) PHPExcel_Shared_Date::ExcelToPHP(PHPExcel_Shared_Date::PHPToExcel($PHPDateObject)); + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT : + return $PHPDateObject; + } + } // function EDATE() + + + /** + * EOMONTH + * + * Returns the date value for the last day of the month that is the indicated number of months + * before or after start_date. + * Use EOMONTH to calculate maturity dates or due dates that fall on the last day of the month. + * + * Excel Function: + * EOMONTH(dateValue,adjustmentMonths) + * + * @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard date string + * @param int $adjustmentMonths The number of months before or after start_date. + * A positive value for months yields a future date; + * a negative value yields a past date. + * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, + * depending on the value of the ReturnDateType flag + */ + public static function EOMONTH($dateValue = 1, $adjustmentMonths = 0) { + $dateValue = PHPExcel_Calculation_Functions::flattenSingleValue($dateValue); + $adjustmentMonths = PHPExcel_Calculation_Functions::flattenSingleValue($adjustmentMonths); + + if (!is_numeric($adjustmentMonths)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $adjustmentMonths = floor($adjustmentMonths); + + if (is_string($dateValue = self::_getDateValue($dateValue))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + // Execute function + $PHPDateObject = self::_adjustDateByMonths($dateValue,$adjustmentMonths+1); + $adjustDays = (int) $PHPDateObject->format('d'); + $adjustDaysString = '-'.$adjustDays.' days'; + $PHPDateObject->modify($adjustDaysString); + + switch (PHPExcel_Calculation_Functions::getReturnDateType()) { + case PHPExcel_Calculation_Functions::RETURNDATE_EXCEL : + return (float) PHPExcel_Shared_Date::PHPToExcel($PHPDateObject); + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC : + return (integer) PHPExcel_Shared_Date::ExcelToPHP(PHPExcel_Shared_Date::PHPToExcel($PHPDateObject)); + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT : + return $PHPDateObject; + } + } // function EOMONTH() + +} // class PHPExcel_Calculation_DateTime + diff --git a/lib/phpexcel/PHPExcel/Calculation/Engineering.php b/lib/phpexcel/PHPExcel/Calculation/Engineering.php new file mode 100644 index 0000000..7e32aa8 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Calculation/Engineering.php @@ -0,0 +1,2505 @@ + array( 'Group' => 'Mass', 'Unit Name' => 'Gram', 'AllowPrefix' => True ), + 'sg' => array( 'Group' => 'Mass', 'Unit Name' => 'Slug', 'AllowPrefix' => False ), + 'lbm' => array( 'Group' => 'Mass', 'Unit Name' => 'Pound mass (avoirdupois)', 'AllowPrefix' => False ), + 'u' => array( 'Group' => 'Mass', 'Unit Name' => 'U (atomic mass unit)', 'AllowPrefix' => True ), + 'ozm' => array( 'Group' => 'Mass', 'Unit Name' => 'Ounce mass (avoirdupois)', 'AllowPrefix' => False ), + 'm' => array( 'Group' => 'Distance', 'Unit Name' => 'Meter', 'AllowPrefix' => True ), + 'mi' => array( 'Group' => 'Distance', 'Unit Name' => 'Statute mile', 'AllowPrefix' => False ), + 'Nmi' => array( 'Group' => 'Distance', 'Unit Name' => 'Nautical mile', 'AllowPrefix' => False ), + 'in' => array( 'Group' => 'Distance', 'Unit Name' => 'Inch', 'AllowPrefix' => False ), + 'ft' => array( 'Group' => 'Distance', 'Unit Name' => 'Foot', 'AllowPrefix' => False ), + 'yd' => array( 'Group' => 'Distance', 'Unit Name' => 'Yard', 'AllowPrefix' => False ), + 'ang' => array( 'Group' => 'Distance', 'Unit Name' => 'Angstrom', 'AllowPrefix' => True ), + 'Pica' => array( 'Group' => 'Distance', 'Unit Name' => 'Pica (1/72 in)', 'AllowPrefix' => False ), + 'yr' => array( 'Group' => 'Time', 'Unit Name' => 'Year', 'AllowPrefix' => False ), + 'day' => array( 'Group' => 'Time', 'Unit Name' => 'Day', 'AllowPrefix' => False ), + 'hr' => array( 'Group' => 'Time', 'Unit Name' => 'Hour', 'AllowPrefix' => False ), + 'mn' => array( 'Group' => 'Time', 'Unit Name' => 'Minute', 'AllowPrefix' => False ), + 'sec' => array( 'Group' => 'Time', 'Unit Name' => 'Second', 'AllowPrefix' => True ), + 'Pa' => array( 'Group' => 'Pressure', 'Unit Name' => 'Pascal', 'AllowPrefix' => True ), + 'p' => array( 'Group' => 'Pressure', 'Unit Name' => 'Pascal', 'AllowPrefix' => True ), + 'atm' => array( 'Group' => 'Pressure', 'Unit Name' => 'Atmosphere', 'AllowPrefix' => True ), + 'at' => array( 'Group' => 'Pressure', 'Unit Name' => 'Atmosphere', 'AllowPrefix' => True ), + 'mmHg' => array( 'Group' => 'Pressure', 'Unit Name' => 'mm of Mercury', 'AllowPrefix' => True ), + 'N' => array( 'Group' => 'Force', 'Unit Name' => 'Newton', 'AllowPrefix' => True ), + 'dyn' => array( 'Group' => 'Force', 'Unit Name' => 'Dyne', 'AllowPrefix' => True ), + 'dy' => array( 'Group' => 'Force', 'Unit Name' => 'Dyne', 'AllowPrefix' => True ), + 'lbf' => array( 'Group' => 'Force', 'Unit Name' => 'Pound force', 'AllowPrefix' => False ), + 'J' => array( 'Group' => 'Energy', 'Unit Name' => 'Joule', 'AllowPrefix' => True ), + 'e' => array( 'Group' => 'Energy', 'Unit Name' => 'Erg', 'AllowPrefix' => True ), + 'c' => array( 'Group' => 'Energy', 'Unit Name' => 'Thermodynamic calorie', 'AllowPrefix' => True ), + 'cal' => array( 'Group' => 'Energy', 'Unit Name' => 'IT calorie', 'AllowPrefix' => True ), + 'eV' => array( 'Group' => 'Energy', 'Unit Name' => 'Electron volt', 'AllowPrefix' => True ), + 'ev' => array( 'Group' => 'Energy', 'Unit Name' => 'Electron volt', 'AllowPrefix' => True ), + 'HPh' => array( 'Group' => 'Energy', 'Unit Name' => 'Horsepower-hour', 'AllowPrefix' => False ), + 'hh' => array( 'Group' => 'Energy', 'Unit Name' => 'Horsepower-hour', 'AllowPrefix' => False ), + 'Wh' => array( 'Group' => 'Energy', 'Unit Name' => 'Watt-hour', 'AllowPrefix' => True ), + 'wh' => array( 'Group' => 'Energy', 'Unit Name' => 'Watt-hour', 'AllowPrefix' => True ), + 'flb' => array( 'Group' => 'Energy', 'Unit Name' => 'Foot-pound', 'AllowPrefix' => False ), + 'BTU' => array( 'Group' => 'Energy', 'Unit Name' => 'BTU', 'AllowPrefix' => False ), + 'btu' => array( 'Group' => 'Energy', 'Unit Name' => 'BTU', 'AllowPrefix' => False ), + 'HP' => array( 'Group' => 'Power', 'Unit Name' => 'Horsepower', 'AllowPrefix' => False ), + 'h' => array( 'Group' => 'Power', 'Unit Name' => 'Horsepower', 'AllowPrefix' => False ), + 'W' => array( 'Group' => 'Power', 'Unit Name' => 'Watt', 'AllowPrefix' => True ), + 'w' => array( 'Group' => 'Power', 'Unit Name' => 'Watt', 'AllowPrefix' => True ), + 'T' => array( 'Group' => 'Magnetism', 'Unit Name' => 'Tesla', 'AllowPrefix' => True ), + 'ga' => array( 'Group' => 'Magnetism', 'Unit Name' => 'Gauss', 'AllowPrefix' => True ), + 'C' => array( 'Group' => 'Temperature', 'Unit Name' => 'Celsius', 'AllowPrefix' => False ), + 'cel' => array( 'Group' => 'Temperature', 'Unit Name' => 'Celsius', 'AllowPrefix' => False ), + 'F' => array( 'Group' => 'Temperature', 'Unit Name' => 'Fahrenheit', 'AllowPrefix' => False ), + 'fah' => array( 'Group' => 'Temperature', 'Unit Name' => 'Fahrenheit', 'AllowPrefix' => False ), + 'K' => array( 'Group' => 'Temperature', 'Unit Name' => 'Kelvin', 'AllowPrefix' => False ), + 'kel' => array( 'Group' => 'Temperature', 'Unit Name' => 'Kelvin', 'AllowPrefix' => False ), + 'tsp' => array( 'Group' => 'Liquid', 'Unit Name' => 'Teaspoon', 'AllowPrefix' => False ), + 'tbs' => array( 'Group' => 'Liquid', 'Unit Name' => 'Tablespoon', 'AllowPrefix' => False ), + 'oz' => array( 'Group' => 'Liquid', 'Unit Name' => 'Fluid Ounce', 'AllowPrefix' => False ), + 'cup' => array( 'Group' => 'Liquid', 'Unit Name' => 'Cup', 'AllowPrefix' => False ), + 'pt' => array( 'Group' => 'Liquid', 'Unit Name' => 'U.S. Pint', 'AllowPrefix' => False ), + 'us_pt' => array( 'Group' => 'Liquid', 'Unit Name' => 'U.S. Pint', 'AllowPrefix' => False ), + 'uk_pt' => array( 'Group' => 'Liquid', 'Unit Name' => 'U.K. Pint', 'AllowPrefix' => False ), + 'qt' => array( 'Group' => 'Liquid', 'Unit Name' => 'Quart', 'AllowPrefix' => False ), + 'gal' => array( 'Group' => 'Liquid', 'Unit Name' => 'Gallon', 'AllowPrefix' => False ), + 'l' => array( 'Group' => 'Liquid', 'Unit Name' => 'Litre', 'AllowPrefix' => True ), + 'lt' => array( 'Group' => 'Liquid', 'Unit Name' => 'Litre', 'AllowPrefix' => True ) + ); + + /** + * Details of the Multiplier prefixes that can be used with Units of Measure in CONVERTUOM() + * + * @var mixed[] + */ + private static $_conversionMultipliers = array( 'Y' => array( 'multiplier' => 1E24, 'name' => 'yotta' ), + 'Z' => array( 'multiplier' => 1E21, 'name' => 'zetta' ), + 'E' => array( 'multiplier' => 1E18, 'name' => 'exa' ), + 'P' => array( 'multiplier' => 1E15, 'name' => 'peta' ), + 'T' => array( 'multiplier' => 1E12, 'name' => 'tera' ), + 'G' => array( 'multiplier' => 1E9, 'name' => 'giga' ), + 'M' => array( 'multiplier' => 1E6, 'name' => 'mega' ), + 'k' => array( 'multiplier' => 1E3, 'name' => 'kilo' ), + 'h' => array( 'multiplier' => 1E2, 'name' => 'hecto' ), + 'e' => array( 'multiplier' => 1E1, 'name' => 'deka' ), + 'd' => array( 'multiplier' => 1E-1, 'name' => 'deci' ), + 'c' => array( 'multiplier' => 1E-2, 'name' => 'centi' ), + 'm' => array( 'multiplier' => 1E-3, 'name' => 'milli' ), + 'u' => array( 'multiplier' => 1E-6, 'name' => 'micro' ), + 'n' => array( 'multiplier' => 1E-9, 'name' => 'nano' ), + 'p' => array( 'multiplier' => 1E-12, 'name' => 'pico' ), + 'f' => array( 'multiplier' => 1E-15, 'name' => 'femto' ), + 'a' => array( 'multiplier' => 1E-18, 'name' => 'atto' ), + 'z' => array( 'multiplier' => 1E-21, 'name' => 'zepto' ), + 'y' => array( 'multiplier' => 1E-24, 'name' => 'yocto' ) + ); + + /** + * Details of the Units of measure conversion factors, organised by group + * + * @var mixed[] + */ + private static $_unitConversions = array( 'Mass' => array( 'g' => array( 'g' => 1.0, + 'sg' => 6.85220500053478E-05, + 'lbm' => 2.20462291469134E-03, + 'u' => 6.02217000000000E+23, + 'ozm' => 3.52739718003627E-02 + ), + 'sg' => array( 'g' => 1.45938424189287E+04, + 'sg' => 1.0, + 'lbm' => 3.21739194101647E+01, + 'u' => 8.78866000000000E+27, + 'ozm' => 5.14782785944229E+02 + ), + 'lbm' => array( 'g' => 4.5359230974881148E+02, + 'sg' => 3.10810749306493E-02, + 'lbm' => 1.0, + 'u' => 2.73161000000000E+26, + 'ozm' => 1.60000023429410E+01 + ), + 'u' => array( 'g' => 1.66053100460465E-24, + 'sg' => 1.13782988532950E-28, + 'lbm' => 3.66084470330684E-27, + 'u' => 1.0, + 'ozm' => 5.85735238300524E-26 + ), + 'ozm' => array( 'g' => 2.83495152079732E+01, + 'sg' => 1.94256689870811E-03, + 'lbm' => 6.24999908478882E-02, + 'u' => 1.70725600000000E+25, + 'ozm' => 1.0 + ) + ), + 'Distance' => array( 'm' => array( 'm' => 1.0, + 'mi' => 6.21371192237334E-04, + 'Nmi' => 5.39956803455724E-04, + 'in' => 3.93700787401575E+01, + 'ft' => 3.28083989501312E+00, + 'yd' => 1.09361329797891E+00, + 'ang' => 1.00000000000000E+10, + 'Pica' => 2.83464566929116E+03 + ), + 'mi' => array( 'm' => 1.60934400000000E+03, + 'mi' => 1.0, + 'Nmi' => 8.68976241900648E-01, + 'in' => 6.33600000000000E+04, + 'ft' => 5.28000000000000E+03, + 'yd' => 1.76000000000000E+03, + 'ang' => 1.60934400000000E+13, + 'Pica' => 4.56191999999971E+06 + ), + 'Nmi' => array( 'm' => 1.85200000000000E+03, + 'mi' => 1.15077944802354E+00, + 'Nmi' => 1.0, + 'in' => 7.29133858267717E+04, + 'ft' => 6.07611548556430E+03, + 'yd' => 2.02537182785694E+03, + 'ang' => 1.85200000000000E+13, + 'Pica' => 5.24976377952723E+06 + ), + 'in' => array( 'm' => 2.54000000000000E-02, + 'mi' => 1.57828282828283E-05, + 'Nmi' => 1.37149028077754E-05, + 'in' => 1.0, + 'ft' => 8.33333333333333E-02, + 'yd' => 2.77777777686643E-02, + 'ang' => 2.54000000000000E+08, + 'Pica' => 7.19999999999955E+01 + ), + 'ft' => array( 'm' => 3.04800000000000E-01, + 'mi' => 1.89393939393939E-04, + 'Nmi' => 1.64578833693305E-04, + 'in' => 1.20000000000000E+01, + 'ft' => 1.0, + 'yd' => 3.33333333223972E-01, + 'ang' => 3.04800000000000E+09, + 'Pica' => 8.63999999999946E+02 + ), + 'yd' => array( 'm' => 9.14400000300000E-01, + 'mi' => 5.68181818368230E-04, + 'Nmi' => 4.93736501241901E-04, + 'in' => 3.60000000118110E+01, + 'ft' => 3.00000000000000E+00, + 'yd' => 1.0, + 'ang' => 9.14400000300000E+09, + 'Pica' => 2.59200000085023E+03 + ), + 'ang' => array( 'm' => 1.00000000000000E-10, + 'mi' => 6.21371192237334E-14, + 'Nmi' => 5.39956803455724E-14, + 'in' => 3.93700787401575E-09, + 'ft' => 3.28083989501312E-10, + 'yd' => 1.09361329797891E-10, + 'ang' => 1.0, + 'Pica' => 2.83464566929116E-07 + ), + 'Pica' => array( 'm' => 3.52777777777800E-04, + 'mi' => 2.19205948372629E-07, + 'Nmi' => 1.90484761219114E-07, + 'in' => 1.38888888888898E-02, + 'ft' => 1.15740740740748E-03, + 'yd' => 3.85802469009251E-04, + 'ang' => 3.52777777777800E+06, + 'Pica' => 1.0 + ) + ), + 'Time' => array( 'yr' => array( 'yr' => 1.0, + 'day' => 365.25, + 'hr' => 8766.0, + 'mn' => 525960.0, + 'sec' => 31557600.0 + ), + 'day' => array( 'yr' => 2.73785078713210E-03, + 'day' => 1.0, + 'hr' => 24.0, + 'mn' => 1440.0, + 'sec' => 86400.0 + ), + 'hr' => array( 'yr' => 1.14077116130504E-04, + 'day' => 4.16666666666667E-02, + 'hr' => 1.0, + 'mn' => 60.0, + 'sec' => 3600.0 + ), + 'mn' => array( 'yr' => 1.90128526884174E-06, + 'day' => 6.94444444444444E-04, + 'hr' => 1.66666666666667E-02, + 'mn' => 1.0, + 'sec' => 60.0 + ), + 'sec' => array( 'yr' => 3.16880878140289E-08, + 'day' => 1.15740740740741E-05, + 'hr' => 2.77777777777778E-04, + 'mn' => 1.66666666666667E-02, + 'sec' => 1.0 + ) + ), + 'Pressure' => array( 'Pa' => array( 'Pa' => 1.0, + 'p' => 1.0, + 'atm' => 9.86923299998193E-06, + 'at' => 9.86923299998193E-06, + 'mmHg' => 7.50061707998627E-03 + ), + 'p' => array( 'Pa' => 1.0, + 'p' => 1.0, + 'atm' => 9.86923299998193E-06, + 'at' => 9.86923299998193E-06, + 'mmHg' => 7.50061707998627E-03 + ), + 'atm' => array( 'Pa' => 1.01324996583000E+05, + 'p' => 1.01324996583000E+05, + 'atm' => 1.0, + 'at' => 1.0, + 'mmHg' => 760.0 + ), + 'at' => array( 'Pa' => 1.01324996583000E+05, + 'p' => 1.01324996583000E+05, + 'atm' => 1.0, + 'at' => 1.0, + 'mmHg' => 760.0 + ), + 'mmHg' => array( 'Pa' => 1.33322363925000E+02, + 'p' => 1.33322363925000E+02, + 'atm' => 1.31578947368421E-03, + 'at' => 1.31578947368421E-03, + 'mmHg' => 1.0 + ) + ), + 'Force' => array( 'N' => array( 'N' => 1.0, + 'dyn' => 1.0E+5, + 'dy' => 1.0E+5, + 'lbf' => 2.24808923655339E-01 + ), + 'dyn' => array( 'N' => 1.0E-5, + 'dyn' => 1.0, + 'dy' => 1.0, + 'lbf' => 2.24808923655339E-06 + ), + 'dy' => array( 'N' => 1.0E-5, + 'dyn' => 1.0, + 'dy' => 1.0, + 'lbf' => 2.24808923655339E-06 + ), + 'lbf' => array( 'N' => 4.448222, + 'dyn' => 4.448222E+5, + 'dy' => 4.448222E+5, + 'lbf' => 1.0 + ) + ), + 'Energy' => array( 'J' => array( 'J' => 1.0, + 'e' => 9.99999519343231E+06, + 'c' => 2.39006249473467E-01, + 'cal' => 2.38846190642017E-01, + 'eV' => 6.24145700000000E+18, + 'ev' => 6.24145700000000E+18, + 'HPh' => 3.72506430801000E-07, + 'hh' => 3.72506430801000E-07, + 'Wh' => 2.77777916238711E-04, + 'wh' => 2.77777916238711E-04, + 'flb' => 2.37304222192651E+01, + 'BTU' => 9.47815067349015E-04, + 'btu' => 9.47815067349015E-04 + ), + 'e' => array( 'J' => 1.00000048065700E-07, + 'e' => 1.0, + 'c' => 2.39006364353494E-08, + 'cal' => 2.38846305445111E-08, + 'eV' => 6.24146000000000E+11, + 'ev' => 6.24146000000000E+11, + 'HPh' => 3.72506609848824E-14, + 'hh' => 3.72506609848824E-14, + 'Wh' => 2.77778049754611E-11, + 'wh' => 2.77778049754611E-11, + 'flb' => 2.37304336254586E-06, + 'BTU' => 9.47815522922962E-11, + 'btu' => 9.47815522922962E-11 + ), + 'c' => array( 'J' => 4.18399101363672E+00, + 'e' => 4.18398900257312E+07, + 'c' => 1.0, + 'cal' => 9.99330315287563E-01, + 'eV' => 2.61142000000000E+19, + 'ev' => 2.61142000000000E+19, + 'HPh' => 1.55856355899327E-06, + 'hh' => 1.55856355899327E-06, + 'Wh' => 1.16222030532950E-03, + 'wh' => 1.16222030532950E-03, + 'flb' => 9.92878733152102E+01, + 'BTU' => 3.96564972437776E-03, + 'btu' => 3.96564972437776E-03 + ), + 'cal' => array( 'J' => 4.18679484613929E+00, + 'e' => 4.18679283372801E+07, + 'c' => 1.00067013349059E+00, + 'cal' => 1.0, + 'eV' => 2.61317000000000E+19, + 'ev' => 2.61317000000000E+19, + 'HPh' => 1.55960800463137E-06, + 'hh' => 1.55960800463137E-06, + 'Wh' => 1.16299914807955E-03, + 'wh' => 1.16299914807955E-03, + 'flb' => 9.93544094443283E+01, + 'BTU' => 3.96830723907002E-03, + 'btu' => 3.96830723907002E-03 + ), + 'eV' => array( 'J' => 1.60219000146921E-19, + 'e' => 1.60218923136574E-12, + 'c' => 3.82933423195043E-20, + 'cal' => 3.82676978535648E-20, + 'eV' => 1.0, + 'ev' => 1.0, + 'HPh' => 5.96826078912344E-26, + 'hh' => 5.96826078912344E-26, + 'Wh' => 4.45053000026614E-23, + 'wh' => 4.45053000026614E-23, + 'flb' => 3.80206452103492E-18, + 'BTU' => 1.51857982414846E-22, + 'btu' => 1.51857982414846E-22 + ), + 'ev' => array( 'J' => 1.60219000146921E-19, + 'e' => 1.60218923136574E-12, + 'c' => 3.82933423195043E-20, + 'cal' => 3.82676978535648E-20, + 'eV' => 1.0, + 'ev' => 1.0, + 'HPh' => 5.96826078912344E-26, + 'hh' => 5.96826078912344E-26, + 'Wh' => 4.45053000026614E-23, + 'wh' => 4.45053000026614E-23, + 'flb' => 3.80206452103492E-18, + 'BTU' => 1.51857982414846E-22, + 'btu' => 1.51857982414846E-22 + ), + 'HPh' => array( 'J' => 2.68451741316170E+06, + 'e' => 2.68451612283024E+13, + 'c' => 6.41616438565991E+05, + 'cal' => 6.41186757845835E+05, + 'eV' => 1.67553000000000E+25, + 'ev' => 1.67553000000000E+25, + 'HPh' => 1.0, + 'hh' => 1.0, + 'Wh' => 7.45699653134593E+02, + 'wh' => 7.45699653134593E+02, + 'flb' => 6.37047316692964E+07, + 'BTU' => 2.54442605275546E+03, + 'btu' => 2.54442605275546E+03 + ), + 'hh' => array( 'J' => 2.68451741316170E+06, + 'e' => 2.68451612283024E+13, + 'c' => 6.41616438565991E+05, + 'cal' => 6.41186757845835E+05, + 'eV' => 1.67553000000000E+25, + 'ev' => 1.67553000000000E+25, + 'HPh' => 1.0, + 'hh' => 1.0, + 'Wh' => 7.45699653134593E+02, + 'wh' => 7.45699653134593E+02, + 'flb' => 6.37047316692964E+07, + 'BTU' => 2.54442605275546E+03, + 'btu' => 2.54442605275546E+03 + ), + 'Wh' => array( 'J' => 3.59999820554720E+03, + 'e' => 3.59999647518369E+10, + 'c' => 8.60422069219046E+02, + 'cal' => 8.59845857713046E+02, + 'eV' => 2.24692340000000E+22, + 'ev' => 2.24692340000000E+22, + 'HPh' => 1.34102248243839E-03, + 'hh' => 1.34102248243839E-03, + 'Wh' => 1.0, + 'wh' => 1.0, + 'flb' => 8.54294774062316E+04, + 'BTU' => 3.41213254164705E+00, + 'btu' => 3.41213254164705E+00 + ), + 'wh' => array( 'J' => 3.59999820554720E+03, + 'e' => 3.59999647518369E+10, + 'c' => 8.60422069219046E+02, + 'cal' => 8.59845857713046E+02, + 'eV' => 2.24692340000000E+22, + 'ev' => 2.24692340000000E+22, + 'HPh' => 1.34102248243839E-03, + 'hh' => 1.34102248243839E-03, + 'Wh' => 1.0, + 'wh' => 1.0, + 'flb' => 8.54294774062316E+04, + 'BTU' => 3.41213254164705E+00, + 'btu' => 3.41213254164705E+00 + ), + 'flb' => array( 'J' => 4.21400003236424E-02, + 'e' => 4.21399800687660E+05, + 'c' => 1.00717234301644E-02, + 'cal' => 1.00649785509554E-02, + 'eV' => 2.63015000000000E+17, + 'ev' => 2.63015000000000E+17, + 'HPh' => 1.56974211145130E-08, + 'hh' => 1.56974211145130E-08, + 'Wh' => 1.17055614802000E-05, + 'wh' => 1.17055614802000E-05, + 'flb' => 1.0, + 'BTU' => 3.99409272448406E-05, + 'btu' => 3.99409272448406E-05 + ), + 'BTU' => array( 'J' => 1.05505813786749E+03, + 'e' => 1.05505763074665E+10, + 'c' => 2.52165488508168E+02, + 'cal' => 2.51996617135510E+02, + 'eV' => 6.58510000000000E+21, + 'ev' => 6.58510000000000E+21, + 'HPh' => 3.93015941224568E-04, + 'hh' => 3.93015941224568E-04, + 'Wh' => 2.93071851047526E-01, + 'wh' => 2.93071851047526E-01, + 'flb' => 2.50369750774671E+04, + 'BTU' => 1.0, + 'btu' => 1.0, + ), + 'btu' => array( 'J' => 1.05505813786749E+03, + 'e' => 1.05505763074665E+10, + 'c' => 2.52165488508168E+02, + 'cal' => 2.51996617135510E+02, + 'eV' => 6.58510000000000E+21, + 'ev' => 6.58510000000000E+21, + 'HPh' => 3.93015941224568E-04, + 'hh' => 3.93015941224568E-04, + 'Wh' => 2.93071851047526E-01, + 'wh' => 2.93071851047526E-01, + 'flb' => 2.50369750774671E+04, + 'BTU' => 1.0, + 'btu' => 1.0, + ) + ), + 'Power' => array( 'HP' => array( 'HP' => 1.0, + 'h' => 1.0, + 'W' => 7.45701000000000E+02, + 'w' => 7.45701000000000E+02 + ), + 'h' => array( 'HP' => 1.0, + 'h' => 1.0, + 'W' => 7.45701000000000E+02, + 'w' => 7.45701000000000E+02 + ), + 'W' => array( 'HP' => 1.34102006031908E-03, + 'h' => 1.34102006031908E-03, + 'W' => 1.0, + 'w' => 1.0 + ), + 'w' => array( 'HP' => 1.34102006031908E-03, + 'h' => 1.34102006031908E-03, + 'W' => 1.0, + 'w' => 1.0 + ) + ), + 'Magnetism' => array( 'T' => array( 'T' => 1.0, + 'ga' => 10000.0 + ), + 'ga' => array( 'T' => 0.0001, + 'ga' => 1.0 + ) + ), + 'Liquid' => array( 'tsp' => array( 'tsp' => 1.0, + 'tbs' => 3.33333333333333E-01, + 'oz' => 1.66666666666667E-01, + 'cup' => 2.08333333333333E-02, + 'pt' => 1.04166666666667E-02, + 'us_pt' => 1.04166666666667E-02, + 'uk_pt' => 8.67558516821960E-03, + 'qt' => 5.20833333333333E-03, + 'gal' => 1.30208333333333E-03, + 'l' => 4.92999408400710E-03, + 'lt' => 4.92999408400710E-03 + ), + 'tbs' => array( 'tsp' => 3.00000000000000E+00, + 'tbs' => 1.0, + 'oz' => 5.00000000000000E-01, + 'cup' => 6.25000000000000E-02, + 'pt' => 3.12500000000000E-02, + 'us_pt' => 3.12500000000000E-02, + 'uk_pt' => 2.60267555046588E-02, + 'qt' => 1.56250000000000E-02, + 'gal' => 3.90625000000000E-03, + 'l' => 1.47899822520213E-02, + 'lt' => 1.47899822520213E-02 + ), + 'oz' => array( 'tsp' => 6.00000000000000E+00, + 'tbs' => 2.00000000000000E+00, + 'oz' => 1.0, + 'cup' => 1.25000000000000E-01, + 'pt' => 6.25000000000000E-02, + 'us_pt' => 6.25000000000000E-02, + 'uk_pt' => 5.20535110093176E-02, + 'qt' => 3.12500000000000E-02, + 'gal' => 7.81250000000000E-03, + 'l' => 2.95799645040426E-02, + 'lt' => 2.95799645040426E-02 + ), + 'cup' => array( 'tsp' => 4.80000000000000E+01, + 'tbs' => 1.60000000000000E+01, + 'oz' => 8.00000000000000E+00, + 'cup' => 1.0, + 'pt' => 5.00000000000000E-01, + 'us_pt' => 5.00000000000000E-01, + 'uk_pt' => 4.16428088074541E-01, + 'qt' => 2.50000000000000E-01, + 'gal' => 6.25000000000000E-02, + 'l' => 2.36639716032341E-01, + 'lt' => 2.36639716032341E-01 + ), + 'pt' => array( 'tsp' => 9.60000000000000E+01, + 'tbs' => 3.20000000000000E+01, + 'oz' => 1.60000000000000E+01, + 'cup' => 2.00000000000000E+00, + 'pt' => 1.0, + 'us_pt' => 1.0, + 'uk_pt' => 8.32856176149081E-01, + 'qt' => 5.00000000000000E-01, + 'gal' => 1.25000000000000E-01, + 'l' => 4.73279432064682E-01, + 'lt' => 4.73279432064682E-01 + ), + 'us_pt' => array( 'tsp' => 9.60000000000000E+01, + 'tbs' => 3.20000000000000E+01, + 'oz' => 1.60000000000000E+01, + 'cup' => 2.00000000000000E+00, + 'pt' => 1.0, + 'us_pt' => 1.0, + 'uk_pt' => 8.32856176149081E-01, + 'qt' => 5.00000000000000E-01, + 'gal' => 1.25000000000000E-01, + 'l' => 4.73279432064682E-01, + 'lt' => 4.73279432064682E-01 + ), + 'uk_pt' => array( 'tsp' => 1.15266000000000E+02, + 'tbs' => 3.84220000000000E+01, + 'oz' => 1.92110000000000E+01, + 'cup' => 2.40137500000000E+00, + 'pt' => 1.20068750000000E+00, + 'us_pt' => 1.20068750000000E+00, + 'uk_pt' => 1.0, + 'qt' => 6.00343750000000E-01, + 'gal' => 1.50085937500000E-01, + 'l' => 5.68260698087162E-01, + 'lt' => 5.68260698087162E-01 + ), + 'qt' => array( 'tsp' => 1.92000000000000E+02, + 'tbs' => 6.40000000000000E+01, + 'oz' => 3.20000000000000E+01, + 'cup' => 4.00000000000000E+00, + 'pt' => 2.00000000000000E+00, + 'us_pt' => 2.00000000000000E+00, + 'uk_pt' => 1.66571235229816E+00, + 'qt' => 1.0, + 'gal' => 2.50000000000000E-01, + 'l' => 9.46558864129363E-01, + 'lt' => 9.46558864129363E-01 + ), + 'gal' => array( 'tsp' => 7.68000000000000E+02, + 'tbs' => 2.56000000000000E+02, + 'oz' => 1.28000000000000E+02, + 'cup' => 1.60000000000000E+01, + 'pt' => 8.00000000000000E+00, + 'us_pt' => 8.00000000000000E+00, + 'uk_pt' => 6.66284940919265E+00, + 'qt' => 4.00000000000000E+00, + 'gal' => 1.0, + 'l' => 3.78623545651745E+00, + 'lt' => 3.78623545651745E+00 + ), + 'l' => array( 'tsp' => 2.02840000000000E+02, + 'tbs' => 6.76133333333333E+01, + 'oz' => 3.38066666666667E+01, + 'cup' => 4.22583333333333E+00, + 'pt' => 2.11291666666667E+00, + 'us_pt' => 2.11291666666667E+00, + 'uk_pt' => 1.75975569552166E+00, + 'qt' => 1.05645833333333E+00, + 'gal' => 2.64114583333333E-01, + 'l' => 1.0, + 'lt' => 1.0 + ), + 'lt' => array( 'tsp' => 2.02840000000000E+02, + 'tbs' => 6.76133333333333E+01, + 'oz' => 3.38066666666667E+01, + 'cup' => 4.22583333333333E+00, + 'pt' => 2.11291666666667E+00, + 'us_pt' => 2.11291666666667E+00, + 'uk_pt' => 1.75975569552166E+00, + 'qt' => 1.05645833333333E+00, + 'gal' => 2.64114583333333E-01, + 'l' => 1.0, + 'lt' => 1.0 + ) + ) + ); + + + /** + * _parseComplex + * + * Parses a complex number into its real and imaginary parts, and an I or J suffix + * + * @param string $complexNumber The complex number + * @return string[] Indexed on "real", "imaginary" and "suffix" + */ + public static function _parseComplex($complexNumber) { + $workString = (string) $complexNumber; + + $realNumber = $imaginary = 0; + // Extract the suffix, if there is one + $suffix = substr($workString,-1); + if (!is_numeric($suffix)) { + $workString = substr($workString,0,-1); + } else { + $suffix = ''; + } + + // Split the input into its Real and Imaginary components + $leadingSign = 0; + if (strlen($workString) > 0) { + $leadingSign = (($workString{0} == '+') || ($workString{0} == '-')) ? 1 : 0; + } + $power = ''; + $realNumber = strtok($workString, '+-'); + if (strtoupper(substr($realNumber,-1)) == 'E') { + $power = strtok('+-'); + ++$leadingSign; + } + + $realNumber = substr($workString,0,strlen($realNumber)+strlen($power)+$leadingSign); + + if ($suffix != '') { + $imaginary = substr($workString,strlen($realNumber)); + + if (($imaginary == '') && (($realNumber == '') || ($realNumber == '+') || ($realNumber == '-'))) { + $imaginary = $realNumber.'1'; + $realNumber = '0'; + } else if ($imaginary == '') { + $imaginary = $realNumber; + $realNumber = '0'; + } elseif (($imaginary == '+') || ($imaginary == '-')) { + $imaginary .= '1'; + } + } + + return array( 'real' => $realNumber, + 'imaginary' => $imaginary, + 'suffix' => $suffix + ); + } // function _parseComplex() + + + /** + * Cleans the leading characters in a complex number string + * + * @param string $complexNumber The complex number to clean + * @return string The "cleaned" complex number + */ + private static function _cleanComplex($complexNumber) { + if ($complexNumber{0} == '+') $complexNumber = substr($complexNumber,1); + if ($complexNumber{0} == '0') $complexNumber = substr($complexNumber,1); + if ($complexNumber{0} == '.') $complexNumber = '0'.$complexNumber; + if ($complexNumber{0} == '+') $complexNumber = substr($complexNumber,1); + return $complexNumber; + } + + /** + * Formats a number base string value with leading zeroes + * + * @param string $xVal The "number" to pad + * @param integer $places The length that we want to pad this value + * @return string The padded "number" + */ + private static function _nbrConversionFormat($xVal, $places) { + if (!is_null($places)) { + if (strlen($xVal) <= $places) { + return substr(str_pad($xVal, $places, '0', STR_PAD_LEFT), -10); + } else { + return PHPExcel_Calculation_Functions::NaN(); + } + } + + return substr($xVal, -10); + } // function _nbrConversionFormat() + + /** + * BESSELI + * + * Returns the modified Bessel function In(x), which is equivalent to the Bessel function evaluated + * for purely imaginary arguments + * + * Excel Function: + * BESSELI(x,ord) + * + * @access public + * @category Engineering Functions + * @param float $x The value at which to evaluate the function. + * If x is nonnumeric, BESSELI returns the #VALUE! error value. + * @param integer $ord The order of the Bessel function. + * If ord is not an integer, it is truncated. + * If $ord is nonnumeric, BESSELI returns the #VALUE! error value. + * If $ord < 0, BESSELI returns the #NUM! error value. + * @return float + * + */ + public static function BESSELI($x, $ord) { + $x = (is_null($x)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($x); + $ord = (is_null($ord)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($ord); + + if ((is_numeric($x)) && (is_numeric($ord))) { + $ord = floor($ord); + if ($ord < 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + + if (abs($x) <= 30) { + $fResult = $fTerm = pow($x / 2, $ord) / PHPExcel_Calculation_MathTrig::FACT($ord); + $ordK = 1; + $fSqrX = ($x * $x) / 4; + do { + $fTerm *= $fSqrX; + $fTerm /= ($ordK * ($ordK + $ord)); + $fResult += $fTerm; + } while ((abs($fTerm) > 1e-12) && (++$ordK < 100)); + } else { + $f_2_PI = 2 * M_PI; + + $fXAbs = abs($x); + $fResult = exp($fXAbs) / sqrt($f_2_PI * $fXAbs); + if (($ord & 1) && ($x < 0)) { + $fResult = -$fResult; + } + } + return (is_nan($fResult)) ? PHPExcel_Calculation_Functions::NaN() : $fResult; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function BESSELI() + + + /** + * BESSELJ + * + * Returns the Bessel function + * + * Excel Function: + * BESSELJ(x,ord) + * + * @access public + * @category Engineering Functions + * @param float $x The value at which to evaluate the function. + * If x is nonnumeric, BESSELJ returns the #VALUE! error value. + * @param integer $ord The order of the Bessel function. If n is not an integer, it is truncated. + * If $ord is nonnumeric, BESSELJ returns the #VALUE! error value. + * If $ord < 0, BESSELJ returns the #NUM! error value. + * @return float + * + */ + public static function BESSELJ($x, $ord) { + $x = (is_null($x)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($x); + $ord = (is_null($ord)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($ord); + + if ((is_numeric($x)) && (is_numeric($ord))) { + $ord = floor($ord); + if ($ord < 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + + $fResult = 0; + if (abs($x) <= 30) { + $fResult = $fTerm = pow($x / 2, $ord) / PHPExcel_Calculation_MathTrig::FACT($ord); + $ordK = 1; + $fSqrX = ($x * $x) / -4; + do { + $fTerm *= $fSqrX; + $fTerm /= ($ordK * ($ordK + $ord)); + $fResult += $fTerm; + } while ((abs($fTerm) > 1e-12) && (++$ordK < 100)); + } else { + $f_PI_DIV_2 = M_PI / 2; + $f_PI_DIV_4 = M_PI / 4; + + $fXAbs = abs($x); + $fResult = sqrt(M_2DIVPI / $fXAbs) * cos($fXAbs - $ord * $f_PI_DIV_2 - $f_PI_DIV_4); + if (($ord & 1) && ($x < 0)) { + $fResult = -$fResult; + } + } + return (is_nan($fResult)) ? PHPExcel_Calculation_Functions::NaN() : $fResult; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function BESSELJ() + + + private static function _Besselk0($fNum) { + if ($fNum <= 2) { + $fNum2 = $fNum * 0.5; + $y = ($fNum2 * $fNum2); + $fRet = -log($fNum2) * self::BESSELI($fNum, 0) + + (-0.57721566 + $y * (0.42278420 + $y * (0.23069756 + $y * (0.3488590e-1 + $y * (0.262698e-2 + $y * + (0.10750e-3 + $y * 0.74e-5)))))); + } else { + $y = 2 / $fNum; + $fRet = exp(-$fNum) / sqrt($fNum) * + (1.25331414 + $y * (-0.7832358e-1 + $y * (0.2189568e-1 + $y * (-0.1062446e-1 + $y * + (0.587872e-2 + $y * (-0.251540e-2 + $y * 0.53208e-3)))))); + } + return $fRet; + } // function _Besselk0() + + + private static function _Besselk1($fNum) { + if ($fNum <= 2) { + $fNum2 = $fNum * 0.5; + $y = ($fNum2 * $fNum2); + $fRet = log($fNum2) * self::BESSELI($fNum, 1) + + (1 + $y * (0.15443144 + $y * (-0.67278579 + $y * (-0.18156897 + $y * (-0.1919402e-1 + $y * + (-0.110404e-2 + $y * (-0.4686e-4))))))) / $fNum; + } else { + $y = 2 / $fNum; + $fRet = exp(-$fNum) / sqrt($fNum) * + (1.25331414 + $y * (0.23498619 + $y * (-0.3655620e-1 + $y * (0.1504268e-1 + $y * (-0.780353e-2 + $y * + (0.325614e-2 + $y * (-0.68245e-3))))))); + } + return $fRet; + } // function _Besselk1() + + + /** + * BESSELK + * + * Returns the modified Bessel function Kn(x), which is equivalent to the Bessel functions evaluated + * for purely imaginary arguments. + * + * Excel Function: + * BESSELK(x,ord) + * + * @access public + * @category Engineering Functions + * @param float $x The value at which to evaluate the function. + * If x is nonnumeric, BESSELK returns the #VALUE! error value. + * @param integer $ord The order of the Bessel function. If n is not an integer, it is truncated. + * If $ord is nonnumeric, BESSELK returns the #VALUE! error value. + * If $ord < 0, BESSELK returns the #NUM! error value. + * @return float + * + */ + public static function BESSELK($x, $ord) { + $x = (is_null($x)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($x); + $ord = (is_null($ord)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($ord); + + if ((is_numeric($x)) && (is_numeric($ord))) { + if (($ord < 0) || ($x == 0.0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + + switch(floor($ord)) { + case 0 : return self::_Besselk0($x); + break; + case 1 : return self::_Besselk1($x); + break; + default : $fTox = 2 / $x; + $fBkm = self::_Besselk0($x); + $fBk = self::_Besselk1($x); + for ($n = 1; $n < $ord; ++$n) { + $fBkp = $fBkm + $n * $fTox * $fBk; + $fBkm = $fBk; + $fBk = $fBkp; + } + } + return (is_nan($fBk)) ? PHPExcel_Calculation_Functions::NaN() : $fBk; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function BESSELK() + + + private static function _Bessely0($fNum) { + if ($fNum < 8.0) { + $y = ($fNum * $fNum); + $f1 = -2957821389.0 + $y * (7062834065.0 + $y * (-512359803.6 + $y * (10879881.29 + $y * (-86327.92757 + $y * 228.4622733)))); + $f2 = 40076544269.0 + $y * (745249964.8 + $y * (7189466.438 + $y * (47447.26470 + $y * (226.1030244 + $y)))); + $fRet = $f1 / $f2 + 0.636619772 * self::BESSELJ($fNum, 0) * log($fNum); + } else { + $z = 8.0 / $fNum; + $y = ($z * $z); + $xx = $fNum - 0.785398164; + $f1 = 1 + $y * (-0.1098628627e-2 + $y * (0.2734510407e-4 + $y * (-0.2073370639e-5 + $y * 0.2093887211e-6))); + $f2 = -0.1562499995e-1 + $y * (0.1430488765e-3 + $y * (-0.6911147651e-5 + $y * (0.7621095161e-6 + $y * (-0.934945152e-7)))); + $fRet = sqrt(0.636619772 / $fNum) * (sin($xx) * $f1 + $z * cos($xx) * $f2); + } + return $fRet; + } // function _Bessely0() + + + private static function _Bessely1($fNum) { + if ($fNum < 8.0) { + $y = ($fNum * $fNum); + $f1 = $fNum * (-0.4900604943e13 + $y * (0.1275274390e13 + $y * (-0.5153438139e11 + $y * (0.7349264551e9 + $y * + (-0.4237922726e7 + $y * 0.8511937935e4))))); + $f2 = 0.2499580570e14 + $y * (0.4244419664e12 + $y * (0.3733650367e10 + $y * (0.2245904002e8 + $y * + (0.1020426050e6 + $y * (0.3549632885e3 + $y))))); + $fRet = $f1 / $f2 + 0.636619772 * ( self::BESSELJ($fNum, 1) * log($fNum) - 1 / $fNum); + } else { + $fRet = sqrt(0.636619772 / $fNum) * sin($fNum - 2.356194491); + } + return $fRet; + } // function _Bessely1() + + + /** + * BESSELY + * + * Returns the Bessel function, which is also called the Weber function or the Neumann function. + * + * Excel Function: + * BESSELY(x,ord) + * + * @access public + * @category Engineering Functions + * @param float $x The value at which to evaluate the function. + * If x is nonnumeric, BESSELK returns the #VALUE! error value. + * @param integer $ord The order of the Bessel function. If n is not an integer, it is truncated. + * If $ord is nonnumeric, BESSELK returns the #VALUE! error value. + * If $ord < 0, BESSELK returns the #NUM! error value. + * + * @return float + */ + public static function BESSELY($x, $ord) { + $x = (is_null($x)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($x); + $ord = (is_null($ord)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($ord); + + if ((is_numeric($x)) && (is_numeric($ord))) { + if (($ord < 0) || ($x == 0.0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + + switch(floor($ord)) { + case 0 : return self::_Bessely0($x); + break; + case 1 : return self::_Bessely1($x); + break; + default: $fTox = 2 / $x; + $fBym = self::_Bessely0($x); + $fBy = self::_Bessely1($x); + for ($n = 1; $n < $ord; ++$n) { + $fByp = $n * $fTox * $fBy - $fBym; + $fBym = $fBy; + $fBy = $fByp; + } + } + return (is_nan($fBy)) ? PHPExcel_Calculation_Functions::NaN() : $fBy; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function BESSELY() + + + /** + * BINTODEC + * + * Return a binary value as decimal. + * + * Excel Function: + * BIN2DEC(x) + * + * @access public + * @category Engineering Functions + * @param string $x The binary number (as a string) that you want to convert. The number + * cannot contain more than 10 characters (10 bits). The most significant + * bit of number is the sign bit. The remaining 9 bits are magnitude bits. + * Negative numbers are represented using two's-complement notation. + * If number is not a valid binary number, or if number contains more than + * 10 characters (10 bits), BIN2DEC returns the #NUM! error value. + * @return string + */ + public static function BINTODEC($x) { + $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); + + if (is_bool($x)) { + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { + $x = (int) $x; + } else { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) { + $x = floor($x); + } + $x = (string) $x; + if (strlen($x) > preg_match_all('/[01]/',$x,$out)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if (strlen($x) > 10) { + return PHPExcel_Calculation_Functions::NaN(); + } elseif (strlen($x) == 10) { + // Two's Complement + $x = substr($x,-9); + return '-'.(512-bindec($x)); + } + return bindec($x); + } // function BINTODEC() + + + /** + * BINTOHEX + * + * Return a binary value as hex. + * + * Excel Function: + * BIN2HEX(x[,places]) + * + * @access public + * @category Engineering Functions + * @param string $x The binary number (as a string) that you want to convert. The number + * cannot contain more than 10 characters (10 bits). The most significant + * bit of number is the sign bit. The remaining 9 bits are magnitude bits. + * Negative numbers are represented using two's-complement notation. + * If number is not a valid binary number, or if number contains more than + * 10 characters (10 bits), BIN2HEX returns the #NUM! error value. + * @param integer $places The number of characters to use. If places is omitted, BIN2HEX uses the + * minimum number of characters necessary. Places is useful for padding the + * return value with leading 0s (zeros). + * If places is not an integer, it is truncated. + * If places is nonnumeric, BIN2HEX returns the #VALUE! error value. + * If places is negative, BIN2HEX returns the #NUM! error value. + * @return string + */ + public static function BINTOHEX($x, $places=NULL) { + $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); + $places = PHPExcel_Calculation_Functions::flattenSingleValue($places); + + if (is_bool($x)) { + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { + $x = (int) $x; + } else { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) { + $x = floor($x); + } + $x = (string) $x; + if (strlen($x) > preg_match_all('/[01]/',$x,$out)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if (strlen($x) > 10) { + return PHPExcel_Calculation_Functions::NaN(); + } elseif (strlen($x) == 10) { + // Two's Complement + return str_repeat('F',8).substr(strtoupper(dechex(bindec(substr($x,-9)))),-2); + } + $hexVal = (string) strtoupper(dechex(bindec($x))); + + return self::_nbrConversionFormat($hexVal,$places); + } // function BINTOHEX() + + + /** + * BINTOOCT + * + * Return a binary value as octal. + * + * Excel Function: + * BIN2OCT(x[,places]) + * + * @access public + * @category Engineering Functions + * @param string $x The binary number (as a string) that you want to convert. The number + * cannot contain more than 10 characters (10 bits). The most significant + * bit of number is the sign bit. The remaining 9 bits are magnitude bits. + * Negative numbers are represented using two's-complement notation. + * If number is not a valid binary number, or if number contains more than + * 10 characters (10 bits), BIN2OCT returns the #NUM! error value. + * @param integer $places The number of characters to use. If places is omitted, BIN2OCT uses the + * minimum number of characters necessary. Places is useful for padding the + * return value with leading 0s (zeros). + * If places is not an integer, it is truncated. + * If places is nonnumeric, BIN2OCT returns the #VALUE! error value. + * If places is negative, BIN2OCT returns the #NUM! error value. + * @return string + */ + public static function BINTOOCT($x, $places=NULL) { + $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); + $places = PHPExcel_Calculation_Functions::flattenSingleValue($places); + + if (is_bool($x)) { + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { + $x = (int) $x; + } else { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) { + $x = floor($x); + } + $x = (string) $x; + if (strlen($x) > preg_match_all('/[01]/',$x,$out)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if (strlen($x) > 10) { + return PHPExcel_Calculation_Functions::NaN(); + } elseif (strlen($x) == 10) { + // Two's Complement + return str_repeat('7',7).substr(strtoupper(decoct(bindec(substr($x,-9)))),-3); + } + $octVal = (string) decoct(bindec($x)); + + return self::_nbrConversionFormat($octVal,$places); + } // function BINTOOCT() + + + /** + * DECTOBIN + * + * Return a decimal value as binary. + * + * Excel Function: + * DEC2BIN(x[,places]) + * + * @access public + * @category Engineering Functions + * @param string $x The decimal integer you want to convert. If number is negative, + * valid place values are ignored and DEC2BIN returns a 10-character + * (10-bit) binary number in which the most significant bit is the sign + * bit. The remaining 9 bits are magnitude bits. Negative numbers are + * represented using two's-complement notation. + * If number < -512 or if number > 511, DEC2BIN returns the #NUM! error + * value. + * If number is nonnumeric, DEC2BIN returns the #VALUE! error value. + * If DEC2BIN requires more than places characters, it returns the #NUM! + * error value. + * @param integer $places The number of characters to use. If places is omitted, DEC2BIN uses + * the minimum number of characters necessary. Places is useful for + * padding the return value with leading 0s (zeros). + * If places is not an integer, it is truncated. + * If places is nonnumeric, DEC2BIN returns the #VALUE! error value. + * If places is zero or negative, DEC2BIN returns the #NUM! error value. + * @return string + */ + public static function DECTOBIN($x, $places=NULL) { + $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); + $places = PHPExcel_Calculation_Functions::flattenSingleValue($places); + + if (is_bool($x)) { + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { + $x = (int) $x; + } else { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + $x = (string) $x; + if (strlen($x) > preg_match_all('/[-0123456789.]/',$x,$out)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $x = (string) floor($x); + $r = decbin($x); + if (strlen($r) == 32) { + // Two's Complement + $r = substr($r,-10); + } elseif (strlen($r) > 11) { + return PHPExcel_Calculation_Functions::NaN(); + } + + return self::_nbrConversionFormat($r,$places); + } // function DECTOBIN() + + + /** + * DECTOHEX + * + * Return a decimal value as hex. + * + * Excel Function: + * DEC2HEX(x[,places]) + * + * @access public + * @category Engineering Functions + * @param string $x The decimal integer you want to convert. If number is negative, + * places is ignored and DEC2HEX returns a 10-character (40-bit) + * hexadecimal number in which the most significant bit is the sign + * bit. The remaining 39 bits are magnitude bits. Negative numbers + * are represented using two's-complement notation. + * If number < -549,755,813,888 or if number > 549,755,813,887, + * DEC2HEX returns the #NUM! error value. + * If number is nonnumeric, DEC2HEX returns the #VALUE! error value. + * If DEC2HEX requires more than places characters, it returns the + * #NUM! error value. + * @param integer $places The number of characters to use. If places is omitted, DEC2HEX uses + * the minimum number of characters necessary. Places is useful for + * padding the return value with leading 0s (zeros). + * If places is not an integer, it is truncated. + * If places is nonnumeric, DEC2HEX returns the #VALUE! error value. + * If places is zero or negative, DEC2HEX returns the #NUM! error value. + * @return string + */ + public static function DECTOHEX($x, $places=null) { + $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); + $places = PHPExcel_Calculation_Functions::flattenSingleValue($places); + + if (is_bool($x)) { + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { + $x = (int) $x; + } else { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + $x = (string) $x; + if (strlen($x) > preg_match_all('/[-0123456789.]/',$x,$out)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $x = (string) floor($x); + $r = strtoupper(dechex($x)); + if (strlen($r) == 8) { + // Two's Complement + $r = 'FF'.$r; + } + + return self::_nbrConversionFormat($r,$places); + } // function DECTOHEX() + + + /** + * DECTOOCT + * + * Return an decimal value as octal. + * + * Excel Function: + * DEC2OCT(x[,places]) + * + * @access public + * @category Engineering Functions + * @param string $x The decimal integer you want to convert. If number is negative, + * places is ignored and DEC2OCT returns a 10-character (30-bit) + * octal number in which the most significant bit is the sign bit. + * The remaining 29 bits are magnitude bits. Negative numbers are + * represented using two's-complement notation. + * If number < -536,870,912 or if number > 536,870,911, DEC2OCT + * returns the #NUM! error value. + * If number is nonnumeric, DEC2OCT returns the #VALUE! error value. + * If DEC2OCT requires more than places characters, it returns the + * #NUM! error value. + * @param integer $places The number of characters to use. If places is omitted, DEC2OCT uses + * the minimum number of characters necessary. Places is useful for + * padding the return value with leading 0s (zeros). + * If places is not an integer, it is truncated. + * If places is nonnumeric, DEC2OCT returns the #VALUE! error value. + * If places is zero or negative, DEC2OCT returns the #NUM! error value. + * @return string + */ + public static function DECTOOCT($x, $places=null) { + $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); + $places = PHPExcel_Calculation_Functions::flattenSingleValue($places); + + if (is_bool($x)) { + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { + $x = (int) $x; + } else { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + $x = (string) $x; + if (strlen($x) > preg_match_all('/[-0123456789.]/',$x,$out)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $x = (string) floor($x); + $r = decoct($x); + if (strlen($r) == 11) { + // Two's Complement + $r = substr($r,-10); + } + + return self::_nbrConversionFormat($r,$places); + } // function DECTOOCT() + + + /** + * HEXTOBIN + * + * Return a hex value as binary. + * + * Excel Function: + * HEX2BIN(x[,places]) + * + * @access public + * @category Engineering Functions + * @param string $x the hexadecimal number you want to convert. Number cannot + * contain more than 10 characters. The most significant bit of + * number is the sign bit (40th bit from the right). The remaining + * 9 bits are magnitude bits. Negative numbers are represented + * using two's-complement notation. + * If number is negative, HEX2BIN ignores places and returns a + * 10-character binary number. + * If number is negative, it cannot be less than FFFFFFFE00, and + * if number is positive, it cannot be greater than 1FF. + * If number is not a valid hexadecimal number, HEX2BIN returns + * the #NUM! error value. + * If HEX2BIN requires more than places characters, it returns + * the #NUM! error value. + * @param integer $places The number of characters to use. If places is omitted, + * HEX2BIN uses the minimum number of characters necessary. Places + * is useful for padding the return value with leading 0s (zeros). + * If places is not an integer, it is truncated. + * If places is nonnumeric, HEX2BIN returns the #VALUE! error value. + * If places is negative, HEX2BIN returns the #NUM! error value. + * @return string + */ + public static function HEXTOBIN($x, $places=null) { + $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); + $places = PHPExcel_Calculation_Functions::flattenSingleValue($places); + + if (is_bool($x)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $x = (string) $x; + if (strlen($x) > preg_match_all('/[0123456789ABCDEF]/',strtoupper($x),$out)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $binVal = decbin(hexdec($x)); + + return substr(self::_nbrConversionFormat($binVal,$places),-10); + } // function HEXTOBIN() + + + /** + * HEXTODEC + * + * Return a hex value as decimal. + * + * Excel Function: + * HEX2DEC(x) + * + * @access public + * @category Engineering Functions + * @param string $x The hexadecimal number you want to convert. This number cannot + * contain more than 10 characters (40 bits). The most significant + * bit of number is the sign bit. The remaining 39 bits are magnitude + * bits. Negative numbers are represented using two's-complement + * notation. + * If number is not a valid hexadecimal number, HEX2DEC returns the + * #NUM! error value. + * @return string + */ + public static function HEXTODEC($x) { + $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); + + if (is_bool($x)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $x = (string) $x; + if (strlen($x) > preg_match_all('/[0123456789ABCDEF]/',strtoupper($x),$out)) { + return PHPExcel_Calculation_Functions::NaN(); + } + return hexdec($x); + } // function HEXTODEC() + + + /** + * HEXTOOCT + * + * Return a hex value as octal. + * + * Excel Function: + * HEX2OCT(x[,places]) + * + * @access public + * @category Engineering Functions + * @param string $x The hexadecimal number you want to convert. Number cannot + * contain more than 10 characters. The most significant bit of + * number is the sign bit. The remaining 39 bits are magnitude + * bits. Negative numbers are represented using two's-complement + * notation. + * If number is negative, HEX2OCT ignores places and returns a + * 10-character octal number. + * If number is negative, it cannot be less than FFE0000000, and + * if number is positive, it cannot be greater than 1FFFFFFF. + * If number is not a valid hexadecimal number, HEX2OCT returns + * the #NUM! error value. + * If HEX2OCT requires more than places characters, it returns + * the #NUM! error value. + * @param integer $places The number of characters to use. If places is omitted, HEX2OCT + * uses the minimum number of characters necessary. Places is + * useful for padding the return value with leading 0s (zeros). + * If places is not an integer, it is truncated. + * If places is nonnumeric, HEX2OCT returns the #VALUE! error + * value. + * If places is negative, HEX2OCT returns the #NUM! error value. + * @return string + */ + public static function HEXTOOCT($x, $places=null) { + $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); + $places = PHPExcel_Calculation_Functions::flattenSingleValue($places); + + if (is_bool($x)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $x = (string) $x; + if (strlen($x) > preg_match_all('/[0123456789ABCDEF]/',strtoupper($x),$out)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $octVal = decoct(hexdec($x)); + + return self::_nbrConversionFormat($octVal,$places); + } // function HEXTOOCT() + + + /** + * OCTTOBIN + * + * Return an octal value as binary. + * + * Excel Function: + * OCT2BIN(x[,places]) + * + * @access public + * @category Engineering Functions + * @param string $x The octal number you want to convert. Number may not + * contain more than 10 characters. The most significant + * bit of number is the sign bit. The remaining 29 bits + * are magnitude bits. Negative numbers are represented + * using two's-complement notation. + * If number is negative, OCT2BIN ignores places and returns + * a 10-character binary number. + * If number is negative, it cannot be less than 7777777000, + * and if number is positive, it cannot be greater than 777. + * If number is not a valid octal number, OCT2BIN returns + * the #NUM! error value. + * If OCT2BIN requires more than places characters, it + * returns the #NUM! error value. + * @param integer $places The number of characters to use. If places is omitted, + * OCT2BIN uses the minimum number of characters necessary. + * Places is useful for padding the return value with + * leading 0s (zeros). + * If places is not an integer, it is truncated. + * If places is nonnumeric, OCT2BIN returns the #VALUE! + * error value. + * If places is negative, OCT2BIN returns the #NUM! error + * value. + * @return string + */ + public static function OCTTOBIN($x, $places=null) { + $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); + $places = PHPExcel_Calculation_Functions::flattenSingleValue($places); + + if (is_bool($x)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $x = (string) $x; + if (preg_match_all('/[01234567]/',$x,$out) != strlen($x)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $r = decbin(octdec($x)); + + return self::_nbrConversionFormat($r,$places); + } // function OCTTOBIN() + + + /** + * OCTTODEC + * + * Return an octal value as decimal. + * + * Excel Function: + * OCT2DEC(x) + * + * @access public + * @category Engineering Functions + * @param string $x The octal number you want to convert. Number may not contain + * more than 10 octal characters (30 bits). The most significant + * bit of number is the sign bit. The remaining 29 bits are + * magnitude bits. Negative numbers are represented using + * two's-complement notation. + * If number is not a valid octal number, OCT2DEC returns the + * #NUM! error value. + * @return string + */ + public static function OCTTODEC($x) { + $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); + + if (is_bool($x)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $x = (string) $x; + if (preg_match_all('/[01234567]/',$x,$out) != strlen($x)) { + return PHPExcel_Calculation_Functions::NaN(); + } + return octdec($x); + } // function OCTTODEC() + + + /** + * OCTTOHEX + * + * Return an octal value as hex. + * + * Excel Function: + * OCT2HEX(x[,places]) + * + * @access public + * @category Engineering Functions + * @param string $x The octal number you want to convert. Number may not contain + * more than 10 octal characters (30 bits). The most significant + * bit of number is the sign bit. The remaining 29 bits are + * magnitude bits. Negative numbers are represented using + * two's-complement notation. + * If number is negative, OCT2HEX ignores places and returns a + * 10-character hexadecimal number. + * If number is not a valid octal number, OCT2HEX returns the + * #NUM! error value. + * If OCT2HEX requires more than places characters, it returns + * the #NUM! error value. + * @param integer $places The number of characters to use. If places is omitted, OCT2HEX + * uses the minimum number of characters necessary. Places is useful + * for padding the return value with leading 0s (zeros). + * If places is not an integer, it is truncated. + * If places is nonnumeric, OCT2HEX returns the #VALUE! error value. + * If places is negative, OCT2HEX returns the #NUM! error value. + * @return string + */ + public static function OCTTOHEX($x, $places=null) { + $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); + $places = PHPExcel_Calculation_Functions::flattenSingleValue($places); + + if (is_bool($x)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $x = (string) $x; + if (preg_match_all('/[01234567]/',$x,$out) != strlen($x)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $hexVal = strtoupper(dechex(octdec($x))); + + return self::_nbrConversionFormat($hexVal,$places); + } // function OCTTOHEX() + + + /** + * COMPLEX + * + * Converts real and imaginary coefficients into a complex number of the form x + yi or x + yj. + * + * Excel Function: + * COMPLEX(realNumber,imaginary[,places]) + * + * @access public + * @category Engineering Functions + * @param float $realNumber The real coefficient of the complex number. + * @param float $imaginary The imaginary coefficient of the complex number. + * @param string $suffix The suffix for the imaginary component of the complex number. + * If omitted, the suffix is assumed to be "i". + * @return string + */ + public static function COMPLEX($realNumber=0.0, $imaginary=0.0, $suffix='i') { + $realNumber = (is_null($realNumber)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($realNumber); + $imaginary = (is_null($imaginary)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($imaginary); + $suffix = (is_null($suffix)) ? 'i' : PHPExcel_Calculation_Functions::flattenSingleValue($suffix); + + if (((is_numeric($realNumber)) && (is_numeric($imaginary))) && + (($suffix == 'i') || ($suffix == 'j') || ($suffix == ''))) { + $realNumber = (float) $realNumber; + $imaginary = (float) $imaginary; + + if ($suffix == '') $suffix = 'i'; + if ($realNumber == 0.0) { + if ($imaginary == 0.0) { + return (string) '0'; + } elseif ($imaginary == 1.0) { + return (string) $suffix; + } elseif ($imaginary == -1.0) { + return (string) '-'.$suffix; + } + return (string) $imaginary.$suffix; + } elseif ($imaginary == 0.0) { + return (string) $realNumber; + } elseif ($imaginary == 1.0) { + return (string) $realNumber.'+'.$suffix; + } elseif ($imaginary == -1.0) { + return (string) $realNumber.'-'.$suffix; + } + if ($imaginary > 0) { $imaginary = (string) '+'.$imaginary; } + return (string) $realNumber.$imaginary.$suffix; + } + + return PHPExcel_Calculation_Functions::VALUE(); + } // function COMPLEX() + + + /** + * IMAGINARY + * + * Returns the imaginary coefficient of a complex number in x + yi or x + yj text format. + * + * Excel Function: + * IMAGINARY(complexNumber) + * + * @access public + * @category Engineering Functions + * @param string $complexNumber The complex number for which you want the imaginary + * coefficient. + * @return float + */ + public static function IMAGINARY($complexNumber) { + $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); + + $parsedComplex = self::_parseComplex($complexNumber); + return $parsedComplex['imaginary']; + } // function IMAGINARY() + + + /** + * IMREAL + * + * Returns the real coefficient of a complex number in x + yi or x + yj text format. + * + * Excel Function: + * IMREAL(complexNumber) + * + * @access public + * @category Engineering Functions + * @param string $complexNumber The complex number for which you want the real coefficient. + * @return float + */ + public static function IMREAL($complexNumber) { + $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); + + $parsedComplex = self::_parseComplex($complexNumber); + return $parsedComplex['real']; + } // function IMREAL() + + + /** + * IMABS + * + * Returns the absolute value (modulus) of a complex number in x + yi or x + yj text format. + * + * Excel Function: + * IMABS(complexNumber) + * + * @param string $complexNumber The complex number for which you want the absolute value. + * @return float + */ + public static function IMABS($complexNumber) { + $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); + + $parsedComplex = self::_parseComplex($complexNumber); + + return sqrt(($parsedComplex['real'] * $parsedComplex['real']) + ($parsedComplex['imaginary'] * $parsedComplex['imaginary'])); + } // function IMABS() + + + /** + * IMARGUMENT + * + * Returns the argument theta of a complex number, i.e. the angle in radians from the real + * axis to the representation of the number in polar coordinates. + * + * Excel Function: + * IMARGUMENT(complexNumber) + * + * @param string $complexNumber The complex number for which you want the argument theta. + * @return float + */ + public static function IMARGUMENT($complexNumber) { + $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); + + $parsedComplex = self::_parseComplex($complexNumber); + + if ($parsedComplex['real'] == 0.0) { + if ($parsedComplex['imaginary'] == 0.0) { + return 0.0; + } elseif($parsedComplex['imaginary'] < 0.0) { + return M_PI / -2; + } else { + return M_PI / 2; + } + } elseif ($parsedComplex['real'] > 0.0) { + return atan($parsedComplex['imaginary'] / $parsedComplex['real']); + } elseif ($parsedComplex['imaginary'] < 0.0) { + return 0 - (M_PI - atan(abs($parsedComplex['imaginary']) / abs($parsedComplex['real']))); + } else { + return M_PI - atan($parsedComplex['imaginary'] / abs($parsedComplex['real'])); + } + } // function IMARGUMENT() + + + /** + * IMCONJUGATE + * + * Returns the complex conjugate of a complex number in x + yi or x + yj text format. + * + * Excel Function: + * IMCONJUGATE(complexNumber) + * + * @param string $complexNumber The complex number for which you want the conjugate. + * @return string + */ + public static function IMCONJUGATE($complexNumber) { + $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); + + $parsedComplex = self::_parseComplex($complexNumber); + + if ($parsedComplex['imaginary'] == 0.0) { + return $parsedComplex['real']; + } else { + return self::_cleanComplex( self::COMPLEX( $parsedComplex['real'], + 0 - $parsedComplex['imaginary'], + $parsedComplex['suffix'] + ) + ); + } + } // function IMCONJUGATE() + + + /** + * IMCOS + * + * Returns the cosine of a complex number in x + yi or x + yj text format. + * + * Excel Function: + * IMCOS(complexNumber) + * + * @param string $complexNumber The complex number for which you want the cosine. + * @return string|float + */ + public static function IMCOS($complexNumber) { + $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); + + $parsedComplex = self::_parseComplex($complexNumber); + + if ($parsedComplex['imaginary'] == 0.0) { + return cos($parsedComplex['real']); + } else { + return self::IMCONJUGATE(self::COMPLEX(cos($parsedComplex['real']) * cosh($parsedComplex['imaginary']),sin($parsedComplex['real']) * sinh($parsedComplex['imaginary']),$parsedComplex['suffix'])); + } + } // function IMCOS() + + + /** + * IMSIN + * + * Returns the sine of a complex number in x + yi or x + yj text format. + * + * Excel Function: + * IMSIN(complexNumber) + * + * @param string $complexNumber The complex number for which you want the sine. + * @return string|float + */ + public static function IMSIN($complexNumber) { + $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); + + $parsedComplex = self::_parseComplex($complexNumber); + + if ($parsedComplex['imaginary'] == 0.0) { + return sin($parsedComplex['real']); + } else { + return self::COMPLEX(sin($parsedComplex['real']) * cosh($parsedComplex['imaginary']),cos($parsedComplex['real']) * sinh($parsedComplex['imaginary']),$parsedComplex['suffix']); + } + } // function IMSIN() + + + /** + * IMSQRT + * + * Returns the square root of a complex number in x + yi or x + yj text format. + * + * Excel Function: + * IMSQRT(complexNumber) + * + * @param string $complexNumber The complex number for which you want the square root. + * @return string + */ + public static function IMSQRT($complexNumber) { + $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); + + $parsedComplex = self::_parseComplex($complexNumber); + + $theta = self::IMARGUMENT($complexNumber); + $d1 = cos($theta / 2); + $d2 = sin($theta / 2); + $r = sqrt(sqrt(($parsedComplex['real'] * $parsedComplex['real']) + ($parsedComplex['imaginary'] * $parsedComplex['imaginary']))); + + if ($parsedComplex['suffix'] == '') { + return self::COMPLEX($d1 * $r,$d2 * $r); + } else { + return self::COMPLEX($d1 * $r,$d2 * $r,$parsedComplex['suffix']); + } + } // function IMSQRT() + + + /** + * IMLN + * + * Returns the natural logarithm of a complex number in x + yi or x + yj text format. + * + * Excel Function: + * IMLN(complexNumber) + * + * @param string $complexNumber The complex number for which you want the natural logarithm. + * @return string + */ + public static function IMLN($complexNumber) { + $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); + + $parsedComplex = self::_parseComplex($complexNumber); + + if (($parsedComplex['real'] == 0.0) && ($parsedComplex['imaginary'] == 0.0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + + $logR = log(sqrt(($parsedComplex['real'] * $parsedComplex['real']) + ($parsedComplex['imaginary'] * $parsedComplex['imaginary']))); + $t = self::IMARGUMENT($complexNumber); + + if ($parsedComplex['suffix'] == '') { + return self::COMPLEX($logR,$t); + } else { + return self::COMPLEX($logR,$t,$parsedComplex['suffix']); + } + } // function IMLN() + + + /** + * IMLOG10 + * + * Returns the common logarithm (base 10) of a complex number in x + yi or x + yj text format. + * + * Excel Function: + * IMLOG10(complexNumber) + * + * @param string $complexNumber The complex number for which you want the common logarithm. + * @return string + */ + public static function IMLOG10($complexNumber) { + $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); + + $parsedComplex = self::_parseComplex($complexNumber); + + if (($parsedComplex['real'] == 0.0) && ($parsedComplex['imaginary'] == 0.0)) { + return PHPExcel_Calculation_Functions::NaN(); + } elseif (($parsedComplex['real'] > 0.0) && ($parsedComplex['imaginary'] == 0.0)) { + return log10($parsedComplex['real']); + } + + return self::IMPRODUCT(log10(EULER),self::IMLN($complexNumber)); + } // function IMLOG10() + + + /** + * IMLOG2 + * + * Returns the base-2 logarithm of a complex number in x + yi or x + yj text format. + * + * Excel Function: + * IMLOG2(complexNumber) + * + * @param string $complexNumber The complex number for which you want the base-2 logarithm. + * @return string + */ + public static function IMLOG2($complexNumber) { + $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); + + $parsedComplex = self::_parseComplex($complexNumber); + + if (($parsedComplex['real'] == 0.0) && ($parsedComplex['imaginary'] == 0.0)) { + return PHPExcel_Calculation_Functions::NaN(); + } elseif (($parsedComplex['real'] > 0.0) && ($parsedComplex['imaginary'] == 0.0)) { + return log($parsedComplex['real'],2); + } + + return self::IMPRODUCT(log(EULER,2),self::IMLN($complexNumber)); + } // function IMLOG2() + + + /** + * IMEXP + * + * Returns the exponential of a complex number in x + yi or x + yj text format. + * + * Excel Function: + * IMEXP(complexNumber) + * + * @param string $complexNumber The complex number for which you want the exponential. + * @return string + */ + public static function IMEXP($complexNumber) { + $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); + + $parsedComplex = self::_parseComplex($complexNumber); + + if (($parsedComplex['real'] == 0.0) && ($parsedComplex['imaginary'] == 0.0)) { + return '1'; + } + + $e = exp($parsedComplex['real']); + $eX = $e * cos($parsedComplex['imaginary']); + $eY = $e * sin($parsedComplex['imaginary']); + + if ($parsedComplex['suffix'] == '') { + return self::COMPLEX($eX,$eY); + } else { + return self::COMPLEX($eX,$eY,$parsedComplex['suffix']); + } + } // function IMEXP() + + + /** + * IMPOWER + * + * Returns a complex number in x + yi or x + yj text format raised to a power. + * + * Excel Function: + * IMPOWER(complexNumber,realNumber) + * + * @param string $complexNumber The complex number you want to raise to a power. + * @param float $realNumber The power to which you want to raise the complex number. + * @return string + */ + public static function IMPOWER($complexNumber,$realNumber) { + $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); + $realNumber = PHPExcel_Calculation_Functions::flattenSingleValue($realNumber); + + if (!is_numeric($realNumber)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + $parsedComplex = self::_parseComplex($complexNumber); + + $r = sqrt(($parsedComplex['real'] * $parsedComplex['real']) + ($parsedComplex['imaginary'] * $parsedComplex['imaginary'])); + $rPower = pow($r,$realNumber); + $theta = self::IMARGUMENT($complexNumber) * $realNumber; + if ($theta == 0) { + return 1; + } elseif ($parsedComplex['imaginary'] == 0.0) { + return self::COMPLEX($rPower * cos($theta),$rPower * sin($theta),$parsedComplex['suffix']); + } else { + return self::COMPLEX($rPower * cos($theta),$rPower * sin($theta),$parsedComplex['suffix']); + } + } // function IMPOWER() + + + /** + * IMDIV + * + * Returns the quotient of two complex numbers in x + yi or x + yj text format. + * + * Excel Function: + * IMDIV(complexDividend,complexDivisor) + * + * @param string $complexDividend The complex numerator or dividend. + * @param string $complexDivisor The complex denominator or divisor. + * @return string + */ + public static function IMDIV($complexDividend,$complexDivisor) { + $complexDividend = PHPExcel_Calculation_Functions::flattenSingleValue($complexDividend); + $complexDivisor = PHPExcel_Calculation_Functions::flattenSingleValue($complexDivisor); + + $parsedComplexDividend = self::_parseComplex($complexDividend); + $parsedComplexDivisor = self::_parseComplex($complexDivisor); + + if (($parsedComplexDividend['suffix'] != '') && ($parsedComplexDivisor['suffix'] != '') && + ($parsedComplexDividend['suffix'] != $parsedComplexDivisor['suffix'])) { + return PHPExcel_Calculation_Functions::NaN(); + } + if (($parsedComplexDividend['suffix'] != '') && ($parsedComplexDivisor['suffix'] == '')) { + $parsedComplexDivisor['suffix'] = $parsedComplexDividend['suffix']; + } + + $d1 = ($parsedComplexDividend['real'] * $parsedComplexDivisor['real']) + ($parsedComplexDividend['imaginary'] * $parsedComplexDivisor['imaginary']); + $d2 = ($parsedComplexDividend['imaginary'] * $parsedComplexDivisor['real']) - ($parsedComplexDividend['real'] * $parsedComplexDivisor['imaginary']); + $d3 = ($parsedComplexDivisor['real'] * $parsedComplexDivisor['real']) + ($parsedComplexDivisor['imaginary'] * $parsedComplexDivisor['imaginary']); + + $r = $d1/$d3; + $i = $d2/$d3; + + if ($i > 0.0) { + return self::_cleanComplex($r.'+'.$i.$parsedComplexDivisor['suffix']); + } elseif ($i < 0.0) { + return self::_cleanComplex($r.$i.$parsedComplexDivisor['suffix']); + } else { + return $r; + } + } // function IMDIV() + + + /** + * IMSUB + * + * Returns the difference of two complex numbers in x + yi or x + yj text format. + * + * Excel Function: + * IMSUB(complexNumber1,complexNumber2) + * + * @param string $complexNumber1 The complex number from which to subtract complexNumber2. + * @param string $complexNumber2 The complex number to subtract from complexNumber1. + * @return string + */ + public static function IMSUB($complexNumber1,$complexNumber2) { + $complexNumber1 = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber1); + $complexNumber2 = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber2); + + $parsedComplex1 = self::_parseComplex($complexNumber1); + $parsedComplex2 = self::_parseComplex($complexNumber2); + + if ((($parsedComplex1['suffix'] != '') && ($parsedComplex2['suffix'] != '')) && + ($parsedComplex1['suffix'] != $parsedComplex2['suffix'])) { + return PHPExcel_Calculation_Functions::NaN(); + } elseif (($parsedComplex1['suffix'] == '') && ($parsedComplex2['suffix'] != '')) { + $parsedComplex1['suffix'] = $parsedComplex2['suffix']; + } + + $d1 = $parsedComplex1['real'] - $parsedComplex2['real']; + $d2 = $parsedComplex1['imaginary'] - $parsedComplex2['imaginary']; + + return self::COMPLEX($d1,$d2,$parsedComplex1['suffix']); + } // function IMSUB() + + + /** + * IMSUM + * + * Returns the sum of two or more complex numbers in x + yi or x + yj text format. + * + * Excel Function: + * IMSUM(complexNumber[,complexNumber[,...]]) + * + * @param string $complexNumber,... Series of complex numbers to add + * @return string + */ + public static function IMSUM() { + // Return value + $returnValue = self::_parseComplex('0'); + $activeSuffix = ''; + + // Loop through the arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + foreach ($aArgs as $arg) { + $parsedComplex = self::_parseComplex($arg); + + if ($activeSuffix == '') { + $activeSuffix = $parsedComplex['suffix']; + } elseif (($parsedComplex['suffix'] != '') && ($activeSuffix != $parsedComplex['suffix'])) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + $returnValue['real'] += $parsedComplex['real']; + $returnValue['imaginary'] += $parsedComplex['imaginary']; + } + + if ($returnValue['imaginary'] == 0.0) { $activeSuffix = ''; } + return self::COMPLEX($returnValue['real'],$returnValue['imaginary'],$activeSuffix); + } // function IMSUM() + + + /** + * IMPRODUCT + * + * Returns the product of two or more complex numbers in x + yi or x + yj text format. + * + * Excel Function: + * IMPRODUCT(complexNumber[,complexNumber[,...]]) + * + * @param string $complexNumber,... Series of complex numbers to multiply + * @return string + */ + public static function IMPRODUCT() { + // Return value + $returnValue = self::_parseComplex('1'); + $activeSuffix = ''; + + // Loop through the arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + foreach ($aArgs as $arg) { + $parsedComplex = self::_parseComplex($arg); + + $workValue = $returnValue; + if (($parsedComplex['suffix'] != '') && ($activeSuffix == '')) { + $activeSuffix = $parsedComplex['suffix']; + } elseif (($parsedComplex['suffix'] != '') && ($activeSuffix != $parsedComplex['suffix'])) { + return PHPExcel_Calculation_Functions::NaN(); + } + $returnValue['real'] = ($workValue['real'] * $parsedComplex['real']) - ($workValue['imaginary'] * $parsedComplex['imaginary']); + $returnValue['imaginary'] = ($workValue['real'] * $parsedComplex['imaginary']) + ($workValue['imaginary'] * $parsedComplex['real']); + } + + if ($returnValue['imaginary'] == 0.0) { $activeSuffix = ''; } + return self::COMPLEX($returnValue['real'],$returnValue['imaginary'],$activeSuffix); + } // function IMPRODUCT() + + + /** + * DELTA + * + * Tests whether two values are equal. Returns 1 if number1 = number2; returns 0 otherwise. + * Use this function to filter a set of values. For example, by summing several DELTA + * functions you calculate the count of equal pairs. This function is also known as the + * Kronecker Delta function. + * + * Excel Function: + * DELTA(a[,b]) + * + * @param float $a The first number. + * @param float $b The second number. If omitted, b is assumed to be zero. + * @return int + */ + public static function DELTA($a, $b=0) { + $a = PHPExcel_Calculation_Functions::flattenSingleValue($a); + $b = PHPExcel_Calculation_Functions::flattenSingleValue($b); + + return (int) ($a == $b); + } // function DELTA() + + + /** + * GESTEP + * + * Excel Function: + * GESTEP(number[,step]) + * + * Returns 1 if number >= step; returns 0 (zero) otherwise + * Use this function to filter a set of values. For example, by summing several GESTEP + * functions you calculate the count of values that exceed a threshold. + * + * @param float $number The value to test against step. + * @param float $step The threshold value. + * If you omit a value for step, GESTEP uses zero. + * @return int + */ + public static function GESTEP($number, $step=0) { + $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); + $step = PHPExcel_Calculation_Functions::flattenSingleValue($step); + + return (int) ($number >= $step); + } // function GESTEP() + + + // + // Private method to calculate the erf value + // + private static $_two_sqrtpi = 1.128379167095512574; + + public static function _erfVal($x) { + if (abs($x) > 2.2) { + return 1 - self::_erfcVal($x); + } + $sum = $term = $x; + $xsqr = ($x * $x); + $j = 1; + do { + $term *= $xsqr / $j; + $sum -= $term / (2 * $j + 1); + ++$j; + $term *= $xsqr / $j; + $sum += $term / (2 * $j + 1); + ++$j; + if ($sum == 0.0) { + break; + } + } while (abs($term / $sum) > PRECISION); + return self::$_two_sqrtpi * $sum; + } // function _erfVal() + + + /** + * ERF + * + * Returns the error function integrated between the lower and upper bound arguments. + * + * Note: In Excel 2007 or earlier, if you input a negative value for the upper or lower bound arguments, + * the function would return a #NUM! error. However, in Excel 2010, the function algorithm was + * improved, so that it can now calculate the function for both positive and negative ranges. + * PHPExcel follows Excel 2010 behaviour, and accepts nagative arguments. + * + * Excel Function: + * ERF(lower[,upper]) + * + * @param float $lower lower bound for integrating ERF + * @param float $upper upper bound for integrating ERF. + * If omitted, ERF integrates between zero and lower_limit + * @return float + */ + public static function ERF($lower, $upper = NULL) { + $lower = PHPExcel_Calculation_Functions::flattenSingleValue($lower); + $upper = PHPExcel_Calculation_Functions::flattenSingleValue($upper); + + if (is_numeric($lower)) { + if (is_null($upper)) { + return self::_erfVal($lower); + } + if (is_numeric($upper)) { + return self::_erfVal($upper) - self::_erfVal($lower); + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function ERF() + + + // + // Private method to calculate the erfc value + // + private static $_one_sqrtpi = 0.564189583547756287; + + private static function _erfcVal($x) { + if (abs($x) < 2.2) { + return 1 - self::_erfVal($x); + } + if ($x < 0) { + return 2 - self::ERFC(-$x); + } + $a = $n = 1; + $b = $c = $x; + $d = ($x * $x) + 0.5; + $q1 = $q2 = $b / $d; + $t = 0; + do { + $t = $a * $n + $b * $x; + $a = $b; + $b = $t; + $t = $c * $n + $d * $x; + $c = $d; + $d = $t; + $n += 0.5; + $q1 = $q2; + $q2 = $b / $d; + } while ((abs($q1 - $q2) / $q2) > PRECISION); + return self::$_one_sqrtpi * exp(-$x * $x) * $q2; + } // function _erfcVal() + + + /** + * ERFC + * + * Returns the complementary ERF function integrated between x and infinity + * + * Note: In Excel 2007 or earlier, if you input a negative value for the lower bound argument, + * the function would return a #NUM! error. However, in Excel 2010, the function algorithm was + * improved, so that it can now calculate the function for both positive and negative x values. + * PHPExcel follows Excel 2010 behaviour, and accepts nagative arguments. + * + * Excel Function: + * ERFC(x) + * + * @param float $x The lower bound for integrating ERFC + * @return float + */ + public static function ERFC($x) { + $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); + + if (is_numeric($x)) { + return self::_erfcVal($x); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function ERFC() + + + /** + * getConversionGroups + * Returns a list of the different conversion groups for UOM conversions + * + * @return array + */ + public static function getConversionGroups() { + $conversionGroups = array(); + foreach(self::$_conversionUnits as $conversionUnit) { + $conversionGroups[] = $conversionUnit['Group']; + } + return array_merge(array_unique($conversionGroups)); + } // function getConversionGroups() + + + /** + * getConversionGroupUnits + * Returns an array of units of measure, for a specified conversion group, or for all groups + * + * @param string $group The group whose units of measure you want to retrieve + * @return array + */ + public static function getConversionGroupUnits($group = NULL) { + $conversionGroups = array(); + foreach(self::$_conversionUnits as $conversionUnit => $conversionGroup) { + if ((is_null($group)) || ($conversionGroup['Group'] == $group)) { + $conversionGroups[$conversionGroup['Group']][] = $conversionUnit; + } + } + return $conversionGroups; + } // function getConversionGroupUnits() + + + /** + * getConversionGroupUnitDetails + * + * @param string $group The group whose units of measure you want to retrieve + * @return array + */ + public static function getConversionGroupUnitDetails($group = NULL) { + $conversionGroups = array(); + foreach(self::$_conversionUnits as $conversionUnit => $conversionGroup) { + if ((is_null($group)) || ($conversionGroup['Group'] == $group)) { + $conversionGroups[$conversionGroup['Group']][] = array( 'unit' => $conversionUnit, + 'description' => $conversionGroup['Unit Name'] + ); + } + } + return $conversionGroups; + } // function getConversionGroupUnitDetails() + + + /** + * getConversionMultipliers + * Returns an array of the Multiplier prefixes that can be used with Units of Measure in CONVERTUOM() + * + * @return array of mixed + */ + public static function getConversionMultipliers() { + return self::$_conversionMultipliers; + } // function getConversionGroups() + + + /** + * CONVERTUOM + * + * Converts a number from one measurement system to another. + * For example, CONVERT can translate a table of distances in miles to a table of distances + * in kilometers. + * + * Excel Function: + * CONVERT(value,fromUOM,toUOM) + * + * @param float $value The value in fromUOM to convert. + * @param string $fromUOM The units for value. + * @param string $toUOM The units for the result. + * + * @return float + */ + public static function CONVERTUOM($value, $fromUOM, $toUOM) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $fromUOM = PHPExcel_Calculation_Functions::flattenSingleValue($fromUOM); + $toUOM = PHPExcel_Calculation_Functions::flattenSingleValue($toUOM); + + if (!is_numeric($value)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $fromMultiplier = 1.0; + if (isset(self::$_conversionUnits[$fromUOM])) { + $unitGroup1 = self::$_conversionUnits[$fromUOM]['Group']; + } else { + $fromMultiplier = substr($fromUOM,0,1); + $fromUOM = substr($fromUOM,1); + if (isset(self::$_conversionMultipliers[$fromMultiplier])) { + $fromMultiplier = self::$_conversionMultipliers[$fromMultiplier]['multiplier']; + } else { + return PHPExcel_Calculation_Functions::NA(); + } + if ((isset(self::$_conversionUnits[$fromUOM])) && (self::$_conversionUnits[$fromUOM]['AllowPrefix'])) { + $unitGroup1 = self::$_conversionUnits[$fromUOM]['Group']; + } else { + return PHPExcel_Calculation_Functions::NA(); + } + } + $value *= $fromMultiplier; + + $toMultiplier = 1.0; + if (isset(self::$_conversionUnits[$toUOM])) { + $unitGroup2 = self::$_conversionUnits[$toUOM]['Group']; + } else { + $toMultiplier = substr($toUOM,0,1); + $toUOM = substr($toUOM,1); + if (isset(self::$_conversionMultipliers[$toMultiplier])) { + $toMultiplier = self::$_conversionMultipliers[$toMultiplier]['multiplier']; + } else { + return PHPExcel_Calculation_Functions::NA(); + } + if ((isset(self::$_conversionUnits[$toUOM])) && (self::$_conversionUnits[$toUOM]['AllowPrefix'])) { + $unitGroup2 = self::$_conversionUnits[$toUOM]['Group']; + } else { + return PHPExcel_Calculation_Functions::NA(); + } + } + if ($unitGroup1 != $unitGroup2) { + return PHPExcel_Calculation_Functions::NA(); + } + + if (($fromUOM == $toUOM) && ($fromMultiplier == $toMultiplier)) { + // We've already factored $fromMultiplier into the value, so we need + // to reverse it again + return $value / $fromMultiplier; + } elseif ($unitGroup1 == 'Temperature') { + if (($fromUOM == 'F') || ($fromUOM == 'fah')) { + if (($toUOM == 'F') || ($toUOM == 'fah')) { + return $value; + } else { + $value = (($value - 32) / 1.8); + if (($toUOM == 'K') || ($toUOM == 'kel')) { + $value += 273.15; + } + return $value; + } + } elseif ((($fromUOM == 'K') || ($fromUOM == 'kel')) && + (($toUOM == 'K') || ($toUOM == 'kel'))) { + return $value; + } elseif ((($fromUOM == 'C') || ($fromUOM == 'cel')) && + (($toUOM == 'C') || ($toUOM == 'cel'))) { + return $value; + } + if (($toUOM == 'F') || ($toUOM == 'fah')) { + if (($fromUOM == 'K') || ($fromUOM == 'kel')) { + $value -= 273.15; + } + return ($value * 1.8) + 32; + } + if (($toUOM == 'C') || ($toUOM == 'cel')) { + return $value - 273.15; + } + return $value + 273.15; + } + return ($value * self::$_unitConversions[$unitGroup1][$fromUOM][$toUOM]) / $toMultiplier; + } // function CONVERTUOM() + +} // class PHPExcel_Calculation_Engineering diff --git a/lib/phpexcel/PHPExcel/Calculation/Exception.php b/lib/phpexcel/PHPExcel/Calculation/Exception.php new file mode 100644 index 0000000..037f788 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Calculation/Exception.php @@ -0,0 +1,52 @@ +line = $line; + $e->file = $file; + throw $e; + } +} diff --git a/lib/phpexcel/PHPExcel/Calculation/ExceptionHandler.php b/lib/phpexcel/PHPExcel/Calculation/ExceptionHandler.php new file mode 100644 index 0000000..389f647 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Calculation/ExceptionHandler.php @@ -0,0 +1,49 @@ +format('d') == $testDate->format('t')); + } // function _lastDayOfMonth() + + + /** + * _firstDayOfMonth + * + * Returns a boolean TRUE/FALSE indicating if this date is the first date of the month + * + * @param DateTime $testDate The date for testing + * @return boolean + */ + private static function _firstDayOfMonth($testDate) + { + return ($testDate->format('d') == 1); + } // function _firstDayOfMonth() + + + private static function _coupFirstPeriodDate($settlement, $maturity, $frequency, $next) + { + $months = 12 / $frequency; + + $result = PHPExcel_Shared_Date::ExcelToPHPObject($maturity); + $eom = self::_lastDayOfMonth($result); + + while ($settlement < PHPExcel_Shared_Date::PHPToExcel($result)) { + $result->modify('-'.$months.' months'); + } + if ($next) { + $result->modify('+'.$months.' months'); + } + + if ($eom) { + $result->modify('-1 day'); + } + + return PHPExcel_Shared_Date::PHPToExcel($result); + } // function _coupFirstPeriodDate() + + + private static function _validFrequency($frequency) + { + if (($frequency == 1) || ($frequency == 2) || ($frequency == 4)) { + return true; + } + if ((PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) && + (($frequency == 6) || ($frequency == 12))) { + return true; + } + return false; + } // function _validFrequency() + + + /** + * _daysPerYear + * + * Returns the number of days in a specified year, as defined by the "basis" value + * + * @param integer $year The year against which we're testing + * @param integer $basis The type of day count: + * 0 or omitted US (NASD) 360 + * 1 Actual (365 or 366 in a leap year) + * 2 360 + * 3 365 + * 4 European 360 + * @return integer + */ + private static function _daysPerYear($year, $basis=0) + { + switch ($basis) { + case 0 : + case 2 : + case 4 : + $daysPerYear = 360; + break; + case 3 : + $daysPerYear = 365; + break; + case 1 : + $daysPerYear = (PHPExcel_Calculation_DateTime::_isLeapYear($year)) ? 366 : 365; + break; + default : + return PHPExcel_Calculation_Functions::NaN(); + } + return $daysPerYear; + } // function _daysPerYear() + + + private static function _interestAndPrincipal($rate=0, $per=0, $nper=0, $pv=0, $fv=0, $type=0) + { + $pmt = self::PMT($rate, $nper, $pv, $fv, $type); + $capital = $pv; + for ($i = 1; $i<= $per; ++$i) { + $interest = ($type && $i == 1) ? 0 : -$capital * $rate; + $principal = $pmt - $interest; + $capital += $principal; + } + return array($interest, $principal); + } // function _interestAndPrincipal() + + + /** + * ACCRINT + * + * Returns the accrued interest for a security that pays periodic interest. + * + * Excel Function: + * ACCRINT(issue,firstinterest,settlement,rate,par,frequency[,basis]) + * + * @access public + * @category Financial Functions + * @param mixed $issue The security's issue date. + * @param mixed $firstinterest The security's first interest date. + * @param mixed $settlement The security's settlement date. + * The security settlement date is the date after the issue date + * when the security is traded to the buyer. + * @param float $rate The security's annual coupon rate. + * @param float $par The security's par value. + * If you omit par, ACCRINT uses $1,000. + * @param integer $frequency the number of coupon payments per year. + * Valid frequency values are: + * 1 Annual + * 2 Semi-Annual + * 4 Quarterly + * If working in Gnumeric Mode, the following frequency options are + * also available + * 6 Bimonthly + * 12 Monthly + * @param integer $basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return float + */ + public static function ACCRINT($issue, $firstinterest, $settlement, $rate, $par=1000, $frequency=1, $basis=0) + { + $issue = PHPExcel_Calculation_Functions::flattenSingleValue($issue); + $firstinterest = PHPExcel_Calculation_Functions::flattenSingleValue($firstinterest); + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); + $par = (is_null($par)) ? 1000 : PHPExcel_Calculation_Functions::flattenSingleValue($par); + $frequency = (is_null($frequency)) ? 1 : PHPExcel_Calculation_Functions::flattenSingleValue($frequency); + $basis = (is_null($basis)) ? 0 : PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + // Validate + if ((is_numeric($rate)) && (is_numeric($par))) { + $rate = (float) $rate; + $par = (float) $par; + if (($rate <= 0) || ($par <= 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $daysBetweenIssueAndSettlement = PHPExcel_Calculation_DateTime::YEARFRAC($issue, $settlement, $basis); + if (!is_numeric($daysBetweenIssueAndSettlement)) { + // return date error + return $daysBetweenIssueAndSettlement; + } + + return $par * $rate * $daysBetweenIssueAndSettlement; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function ACCRINT() + + + /** + * ACCRINTM + * + * Returns the accrued interest for a security that pays interest at maturity. + * + * Excel Function: + * ACCRINTM(issue,settlement,rate[,par[,basis]]) + * + * @access public + * @category Financial Functions + * @param mixed issue The security's issue date. + * @param mixed settlement The security's settlement (or maturity) date. + * @param float rate The security's annual coupon rate. + * @param float par The security's par value. + * If you omit par, ACCRINT uses $1,000. + * @param integer basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return float + */ + public static function ACCRINTM($issue, $settlement, $rate, $par=1000, $basis=0) { + $issue = PHPExcel_Calculation_Functions::flattenSingleValue($issue); + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); + $par = (is_null($par)) ? 1000 : PHPExcel_Calculation_Functions::flattenSingleValue($par); + $basis = (is_null($basis)) ? 0 : PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + // Validate + if ((is_numeric($rate)) && (is_numeric($par))) { + $rate = (float) $rate; + $par = (float) $par; + if (($rate <= 0) || ($par <= 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $daysBetweenIssueAndSettlement = PHPExcel_Calculation_DateTime::YEARFRAC($issue, $settlement, $basis); + if (!is_numeric($daysBetweenIssueAndSettlement)) { + // return date error + return $daysBetweenIssueAndSettlement; + } + return $par * $rate * $daysBetweenIssueAndSettlement; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function ACCRINTM() + + + /** + * AMORDEGRC + * + * Returns the depreciation for each accounting period. + * This function is provided for the French accounting system. If an asset is purchased in + * the middle of the accounting period, the prorated depreciation is taken into account. + * The function is similar to AMORLINC, except that a depreciation coefficient is applied in + * the calculation depending on the life of the assets. + * This function will return the depreciation until the last period of the life of the assets + * or until the cumulated value of depreciation is greater than the cost of the assets minus + * the salvage value. + * + * Excel Function: + * AMORDEGRC(cost,purchased,firstPeriod,salvage,period,rate[,basis]) + * + * @access public + * @category Financial Functions + * @param float cost The cost of the asset. + * @param mixed purchased Date of the purchase of the asset. + * @param mixed firstPeriod Date of the end of the first period. + * @param mixed salvage The salvage value at the end of the life of the asset. + * @param float period The period. + * @param float rate Rate of depreciation. + * @param integer basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return float + */ + public static function AMORDEGRC($cost, $purchased, $firstPeriod, $salvage, $period, $rate, $basis=0) { + $cost = PHPExcel_Calculation_Functions::flattenSingleValue($cost); + $purchased = PHPExcel_Calculation_Functions::flattenSingleValue($purchased); + $firstPeriod = PHPExcel_Calculation_Functions::flattenSingleValue($firstPeriod); + $salvage = PHPExcel_Calculation_Functions::flattenSingleValue($salvage); + $period = floor(PHPExcel_Calculation_Functions::flattenSingleValue($period)); + $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); + $basis = (is_null($basis)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + // The depreciation coefficients are: + // Life of assets (1/rate) Depreciation coefficient + // Less than 3 years 1 + // Between 3 and 4 years 1.5 + // Between 5 and 6 years 2 + // More than 6 years 2.5 + $fUsePer = 1.0 / $rate; + if ($fUsePer < 3.0) { + $amortiseCoeff = 1.0; + } elseif ($fUsePer < 5.0) { + $amortiseCoeff = 1.5; + } elseif ($fUsePer <= 6.0) { + $amortiseCoeff = 2.0; + } else { + $amortiseCoeff = 2.5; + } + + $rate *= $amortiseCoeff; + $fNRate = round(PHPExcel_Calculation_DateTime::YEARFRAC($purchased, $firstPeriod, $basis) * $rate * $cost,0); + $cost -= $fNRate; + $fRest = $cost - $salvage; + + for ($n = 0; $n < $period; ++$n) { + $fNRate = round($rate * $cost,0); + $fRest -= $fNRate; + + if ($fRest < 0.0) { + switch ($period - $n) { + case 0 : + case 1 : return round($cost * 0.5, 0); + break; + default : return 0.0; + break; + } + } + $cost -= $fNRate; + } + return $fNRate; + } // function AMORDEGRC() + + + /** + * AMORLINC + * + * Returns the depreciation for each accounting period. + * This function is provided for the French accounting system. If an asset is purchased in + * the middle of the accounting period, the prorated depreciation is taken into account. + * + * Excel Function: + * AMORLINC(cost,purchased,firstPeriod,salvage,period,rate[,basis]) + * + * @access public + * @category Financial Functions + * @param float cost The cost of the asset. + * @param mixed purchased Date of the purchase of the asset. + * @param mixed firstPeriod Date of the end of the first period. + * @param mixed salvage The salvage value at the end of the life of the asset. + * @param float period The period. + * @param float rate Rate of depreciation. + * @param integer basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return float + */ + public static function AMORLINC($cost, $purchased, $firstPeriod, $salvage, $period, $rate, $basis=0) { + $cost = PHPExcel_Calculation_Functions::flattenSingleValue($cost); + $purchased = PHPExcel_Calculation_Functions::flattenSingleValue($purchased); + $firstPeriod = PHPExcel_Calculation_Functions::flattenSingleValue($firstPeriod); + $salvage = PHPExcel_Calculation_Functions::flattenSingleValue($salvage); + $period = PHPExcel_Calculation_Functions::flattenSingleValue($period); + $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); + $basis = (is_null($basis)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + $fOneRate = $cost * $rate; + $fCostDelta = $cost - $salvage; + // Note, quirky variation for leap years on the YEARFRAC for this function + $purchasedYear = PHPExcel_Calculation_DateTime::YEAR($purchased); + $yearFrac = PHPExcel_Calculation_DateTime::YEARFRAC($purchased, $firstPeriod, $basis); + + if (($basis == 1) && ($yearFrac < 1) && (PHPExcel_Calculation_DateTime::_isLeapYear($purchasedYear))) { + $yearFrac *= 365 / 366; + } + + $f0Rate = $yearFrac * $rate * $cost; + $nNumOfFullPeriods = intval(($cost - $salvage - $f0Rate) / $fOneRate); + + if ($period == 0) { + return $f0Rate; + } elseif ($period <= $nNumOfFullPeriods) { + return $fOneRate; + } elseif ($period == ($nNumOfFullPeriods + 1)) { + return ($fCostDelta - $fOneRate * $nNumOfFullPeriods - $f0Rate); + } else { + return 0.0; + } + } // function AMORLINC() + + + /** + * COUPDAYBS + * + * Returns the number of days from the beginning of the coupon period to the settlement date. + * + * Excel Function: + * COUPDAYBS(settlement,maturity,frequency[,basis]) + * + * @access public + * @category Financial Functions + * @param mixed settlement The security's settlement date. + * The security settlement date is the date after the issue + * date when the security is traded to the buyer. + * @param mixed maturity The security's maturity date. + * The maturity date is the date when the security expires. + * @param mixed frequency the number of coupon payments per year. + * Valid frequency values are: + * 1 Annual + * 2 Semi-Annual + * 4 Quarterly + * If working in Gnumeric Mode, the following frequency options are + * also available + * 6 Bimonthly + * 12 Monthly + * @param integer basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return float + */ + public static function COUPDAYBS($settlement, $maturity, $frequency, $basis=0) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $frequency = (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency); + $basis = (is_null($basis)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + if (is_string($settlement = PHPExcel_Calculation_DateTime::_getDateValue($settlement))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + if (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (($settlement > $maturity) || + (!self::_validFrequency($frequency)) || + (($basis < 0) || ($basis > 4))) { + return PHPExcel_Calculation_Functions::NaN(); + } + + $daysPerYear = self::_daysPerYear(PHPExcel_Calculation_DateTime::YEAR($settlement),$basis); + $prev = self::_coupFirstPeriodDate($settlement, $maturity, $frequency, False); + + return PHPExcel_Calculation_DateTime::YEARFRAC($prev, $settlement, $basis) * $daysPerYear; + } // function COUPDAYBS() + + + /** + * COUPDAYS + * + * Returns the number of days in the coupon period that contains the settlement date. + * + * Excel Function: + * COUPDAYS(settlement,maturity,frequency[,basis]) + * + * @access public + * @category Financial Functions + * @param mixed settlement The security's settlement date. + * The security settlement date is the date after the issue + * date when the security is traded to the buyer. + * @param mixed maturity The security's maturity date. + * The maturity date is the date when the security expires. + * @param mixed frequency the number of coupon payments per year. + * Valid frequency values are: + * 1 Annual + * 2 Semi-Annual + * 4 Quarterly + * If working in Gnumeric Mode, the following frequency options are + * also available + * 6 Bimonthly + * 12 Monthly + * @param integer basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return float + */ + public static function COUPDAYS($settlement, $maturity, $frequency, $basis=0) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $frequency = (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency); + $basis = (is_null($basis)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + if (is_string($settlement = PHPExcel_Calculation_DateTime::_getDateValue($settlement))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + if (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (($settlement > $maturity) || + (!self::_validFrequency($frequency)) || + (($basis < 0) || ($basis > 4))) { + return PHPExcel_Calculation_Functions::NaN(); + } + + switch ($basis) { + case 3: // Actual/365 + return 365 / $frequency; + case 1: // Actual/actual + if ($frequency == 1) { + $daysPerYear = self::_daysPerYear(PHPExcel_Calculation_DateTime::YEAR($maturity),$basis); + return ($daysPerYear / $frequency); + } else { + $prev = self::_coupFirstPeriodDate($settlement, $maturity, $frequency, False); + $next = self::_coupFirstPeriodDate($settlement, $maturity, $frequency, True); + return ($next - $prev); + } + default: // US (NASD) 30/360, Actual/360 or European 30/360 + return 360 / $frequency; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function COUPDAYS() + + + /** + * COUPDAYSNC + * + * Returns the number of days from the settlement date to the next coupon date. + * + * Excel Function: + * COUPDAYSNC(settlement,maturity,frequency[,basis]) + * + * @access public + * @category Financial Functions + * @param mixed settlement The security's settlement date. + * The security settlement date is the date after the issue + * date when the security is traded to the buyer. + * @param mixed maturity The security's maturity date. + * The maturity date is the date when the security expires. + * @param mixed frequency the number of coupon payments per year. + * Valid frequency values are: + * 1 Annual + * 2 Semi-Annual + * 4 Quarterly + * If working in Gnumeric Mode, the following frequency options are + * also available + * 6 Bimonthly + * 12 Monthly + * @param integer basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return float + */ + public static function COUPDAYSNC($settlement, $maturity, $frequency, $basis=0) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $frequency = (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency); + $basis = (is_null($basis)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + if (is_string($settlement = PHPExcel_Calculation_DateTime::_getDateValue($settlement))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + if (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (($settlement > $maturity) || + (!self::_validFrequency($frequency)) || + (($basis < 0) || ($basis > 4))) { + return PHPExcel_Calculation_Functions::NaN(); + } + + $daysPerYear = self::_daysPerYear(PHPExcel_Calculation_DateTime::YEAR($settlement),$basis); + $next = self::_coupFirstPeriodDate($settlement, $maturity, $frequency, True); + + return PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $next, $basis) * $daysPerYear; + } // function COUPDAYSNC() + + + /** + * COUPNCD + * + * Returns the next coupon date after the settlement date. + * + * Excel Function: + * COUPNCD(settlement,maturity,frequency[,basis]) + * + * @access public + * @category Financial Functions + * @param mixed settlement The security's settlement date. + * The security settlement date is the date after the issue + * date when the security is traded to the buyer. + * @param mixed maturity The security's maturity date. + * The maturity date is the date when the security expires. + * @param mixed frequency the number of coupon payments per year. + * Valid frequency values are: + * 1 Annual + * 2 Semi-Annual + * 4 Quarterly + * If working in Gnumeric Mode, the following frequency options are + * also available + * 6 Bimonthly + * 12 Monthly + * @param integer basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, + * depending on the value of the ReturnDateType flag + */ + public static function COUPNCD($settlement, $maturity, $frequency, $basis=0) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $frequency = (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency); + $basis = (is_null($basis)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + if (is_string($settlement = PHPExcel_Calculation_DateTime::_getDateValue($settlement))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + if (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (($settlement > $maturity) || + (!self::_validFrequency($frequency)) || + (($basis < 0) || ($basis > 4))) { + return PHPExcel_Calculation_Functions::NaN(); + } + + return self::_coupFirstPeriodDate($settlement, $maturity, $frequency, True); + } // function COUPNCD() + + + /** + * COUPNUM + * + * Returns the number of coupons payable between the settlement date and maturity date, + * rounded up to the nearest whole coupon. + * + * Excel Function: + * COUPNUM(settlement,maturity,frequency[,basis]) + * + * @access public + * @category Financial Functions + * @param mixed settlement The security's settlement date. + * The security settlement date is the date after the issue + * date when the security is traded to the buyer. + * @param mixed maturity The security's maturity date. + * The maturity date is the date when the security expires. + * @param mixed frequency the number of coupon payments per year. + * Valid frequency values are: + * 1 Annual + * 2 Semi-Annual + * 4 Quarterly + * If working in Gnumeric Mode, the following frequency options are + * also available + * 6 Bimonthly + * 12 Monthly + * @param integer basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return integer + */ + public static function COUPNUM($settlement, $maturity, $frequency, $basis=0) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $frequency = (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency); + $basis = (is_null($basis)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + if (is_string($settlement = PHPExcel_Calculation_DateTime::_getDateValue($settlement))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + if (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (($settlement > $maturity) || + (!self::_validFrequency($frequency)) || + (($basis < 0) || ($basis > 4))) { + return PHPExcel_Calculation_Functions::NaN(); + } + + $settlement = self::_coupFirstPeriodDate($settlement, $maturity, $frequency, True); + $daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity, $basis) * 365; + + switch ($frequency) { + case 1: // annual payments + return ceil($daysBetweenSettlementAndMaturity / 360); + case 2: // half-yearly + return ceil($daysBetweenSettlementAndMaturity / 180); + case 4: // quarterly + return ceil($daysBetweenSettlementAndMaturity / 90); + case 6: // bimonthly + return ceil($daysBetweenSettlementAndMaturity / 60); + case 12: // monthly + return ceil($daysBetweenSettlementAndMaturity / 30); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function COUPNUM() + + + /** + * COUPPCD + * + * Returns the previous coupon date before the settlement date. + * + * Excel Function: + * COUPPCD(settlement,maturity,frequency[,basis]) + * + * @access public + * @category Financial Functions + * @param mixed settlement The security's settlement date. + * The security settlement date is the date after the issue + * date when the security is traded to the buyer. + * @param mixed maturity The security's maturity date. + * The maturity date is the date when the security expires. + * @param mixed frequency the number of coupon payments per year. + * Valid frequency values are: + * 1 Annual + * 2 Semi-Annual + * 4 Quarterly + * If working in Gnumeric Mode, the following frequency options are + * also available + * 6 Bimonthly + * 12 Monthly + * @param integer basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, + * depending on the value of the ReturnDateType flag + */ + public static function COUPPCD($settlement, $maturity, $frequency, $basis=0) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $frequency = (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency); + $basis = (is_null($basis)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + if (is_string($settlement = PHPExcel_Calculation_DateTime::_getDateValue($settlement))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + if (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (($settlement > $maturity) || + (!self::_validFrequency($frequency)) || + (($basis < 0) || ($basis > 4))) { + return PHPExcel_Calculation_Functions::NaN(); + } + + return self::_coupFirstPeriodDate($settlement, $maturity, $frequency, False); + } // function COUPPCD() + + + /** + * CUMIPMT + * + * Returns the cumulative interest paid on a loan between the start and end periods. + * + * Excel Function: + * CUMIPMT(rate,nper,pv,start,end[,type]) + * + * @access public + * @category Financial Functions + * @param float $rate The Interest rate + * @param integer $nper The total number of payment periods + * @param float $pv Present Value + * @param integer $start The first period in the calculation. + * Payment periods are numbered beginning with 1. + * @param integer $end The last period in the calculation. + * @param integer $type A number 0 or 1 and indicates when payments are due: + * 0 or omitted At the end of the period. + * 1 At the beginning of the period. + * @return float + */ + public static function CUMIPMT($rate, $nper, $pv, $start, $end, $type = 0) { + $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); + $nper = (int) PHPExcel_Calculation_Functions::flattenSingleValue($nper); + $pv = PHPExcel_Calculation_Functions::flattenSingleValue($pv); + $start = (int) PHPExcel_Calculation_Functions::flattenSingleValue($start); + $end = (int) PHPExcel_Calculation_Functions::flattenSingleValue($end); + $type = (int) PHPExcel_Calculation_Functions::flattenSingleValue($type); + + // Validate parameters + if ($type != 0 && $type != 1) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ($start < 1 || $start > $end) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + // Calculate + $interest = 0; + for ($per = $start; $per <= $end; ++$per) { + $interest += self::IPMT($rate, $per, $nper, $pv, 0, $type); + } + + return $interest; + } // function CUMIPMT() + + + /** + * CUMPRINC + * + * Returns the cumulative principal paid on a loan between the start and end periods. + * + * Excel Function: + * CUMPRINC(rate,nper,pv,start,end[,type]) + * + * @access public + * @category Financial Functions + * @param float $rate The Interest rate + * @param integer $nper The total number of payment periods + * @param float $pv Present Value + * @param integer $start The first period in the calculation. + * Payment periods are numbered beginning with 1. + * @param integer $end The last period in the calculation. + * @param integer $type A number 0 or 1 and indicates when payments are due: + * 0 or omitted At the end of the period. + * 1 At the beginning of the period. + * @return float + */ + public static function CUMPRINC($rate, $nper, $pv, $start, $end, $type = 0) { + $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); + $nper = (int) PHPExcel_Calculation_Functions::flattenSingleValue($nper); + $pv = PHPExcel_Calculation_Functions::flattenSingleValue($pv); + $start = (int) PHPExcel_Calculation_Functions::flattenSingleValue($start); + $end = (int) PHPExcel_Calculation_Functions::flattenSingleValue($end); + $type = (int) PHPExcel_Calculation_Functions::flattenSingleValue($type); + + // Validate parameters + if ($type != 0 && $type != 1) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ($start < 1 || $start > $end) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + // Calculate + $principal = 0; + for ($per = $start; $per <= $end; ++$per) { + $principal += self::PPMT($rate, $per, $nper, $pv, 0, $type); + } + + return $principal; + } // function CUMPRINC() + + + /** + * DB + * + * Returns the depreciation of an asset for a specified period using the + * fixed-declining balance method. + * This form of depreciation is used if you want to get a higher depreciation value + * at the beginning of the depreciation (as opposed to linear depreciation). The + * depreciation value is reduced with every depreciation period by the depreciation + * already deducted from the initial cost. + * + * Excel Function: + * DB(cost,salvage,life,period[,month]) + * + * @access public + * @category Financial Functions + * @param float cost Initial cost of the asset. + * @param float salvage Value at the end of the depreciation. + * (Sometimes called the salvage value of the asset) + * @param integer life Number of periods over which the asset is depreciated. + * (Sometimes called the useful life of the asset) + * @param integer period The period for which you want to calculate the + * depreciation. Period must use the same units as life. + * @param integer month Number of months in the first year. If month is omitted, + * it defaults to 12. + * @return float + */ + public static function DB($cost, $salvage, $life, $period, $month=12) { + $cost = PHPExcel_Calculation_Functions::flattenSingleValue($cost); + $salvage = PHPExcel_Calculation_Functions::flattenSingleValue($salvage); + $life = PHPExcel_Calculation_Functions::flattenSingleValue($life); + $period = PHPExcel_Calculation_Functions::flattenSingleValue($period); + $month = PHPExcel_Calculation_Functions::flattenSingleValue($month); + + // Validate + if ((is_numeric($cost)) && (is_numeric($salvage)) && (is_numeric($life)) && (is_numeric($period)) && (is_numeric($month))) { + $cost = (float) $cost; + $salvage = (float) $salvage; + $life = (int) $life; + $period = (int) $period; + $month = (int) $month; + if ($cost == 0) { + return 0.0; + } elseif (($cost < 0) || (($salvage / $cost) < 0) || ($life <= 0) || ($period < 1) || ($month < 1)) { + return PHPExcel_Calculation_Functions::NaN(); + } + // Set Fixed Depreciation Rate + $fixedDepreciationRate = 1 - pow(($salvage / $cost), (1 / $life)); + $fixedDepreciationRate = round($fixedDepreciationRate, 3); + + // Loop through each period calculating the depreciation + $previousDepreciation = 0; + for ($per = 1; $per <= $period; ++$per) { + if ($per == 1) { + $depreciation = $cost * $fixedDepreciationRate * $month / 12; + } elseif ($per == ($life + 1)) { + $depreciation = ($cost - $previousDepreciation) * $fixedDepreciationRate * (12 - $month) / 12; + } else { + $depreciation = ($cost - $previousDepreciation) * $fixedDepreciationRate; + } + $previousDepreciation += $depreciation; + } + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) { + $depreciation = round($depreciation,2); + } + return $depreciation; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function DB() + + + /** + * DDB + * + * Returns the depreciation of an asset for a specified period using the + * double-declining balance method or some other method you specify. + * + * Excel Function: + * DDB(cost,salvage,life,period[,factor]) + * + * @access public + * @category Financial Functions + * @param float cost Initial cost of the asset. + * @param float salvage Value at the end of the depreciation. + * (Sometimes called the salvage value of the asset) + * @param integer life Number of periods over which the asset is depreciated. + * (Sometimes called the useful life of the asset) + * @param integer period The period for which you want to calculate the + * depreciation. Period must use the same units as life. + * @param float factor The rate at which the balance declines. + * If factor is omitted, it is assumed to be 2 (the + * double-declining balance method). + * @return float + */ + public static function DDB($cost, $salvage, $life, $period, $factor=2.0) { + $cost = PHPExcel_Calculation_Functions::flattenSingleValue($cost); + $salvage = PHPExcel_Calculation_Functions::flattenSingleValue($salvage); + $life = PHPExcel_Calculation_Functions::flattenSingleValue($life); + $period = PHPExcel_Calculation_Functions::flattenSingleValue($period); + $factor = PHPExcel_Calculation_Functions::flattenSingleValue($factor); + + // Validate + if ((is_numeric($cost)) && (is_numeric($salvage)) && (is_numeric($life)) && (is_numeric($period)) && (is_numeric($factor))) { + $cost = (float) $cost; + $salvage = (float) $salvage; + $life = (int) $life; + $period = (int) $period; + $factor = (float) $factor; + if (($cost <= 0) || (($salvage / $cost) < 0) || ($life <= 0) || ($period < 1) || ($factor <= 0.0) || ($period > $life)) { + return PHPExcel_Calculation_Functions::NaN(); + } + // Set Fixed Depreciation Rate + $fixedDepreciationRate = 1 - pow(($salvage / $cost), (1 / $life)); + $fixedDepreciationRate = round($fixedDepreciationRate, 3); + + // Loop through each period calculating the depreciation + $previousDepreciation = 0; + for ($per = 1; $per <= $period; ++$per) { + $depreciation = min( ($cost - $previousDepreciation) * ($factor / $life), ($cost - $salvage - $previousDepreciation) ); + $previousDepreciation += $depreciation; + } + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) { + $depreciation = round($depreciation,2); + } + return $depreciation; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function DDB() + + + /** + * DISC + * + * Returns the discount rate for a security. + * + * Excel Function: + * DISC(settlement,maturity,price,redemption[,basis]) + * + * @access public + * @category Financial Functions + * @param mixed settlement The security's settlement date. + * The security settlement date is the date after the issue + * date when the security is traded to the buyer. + * @param mixed maturity The security's maturity date. + * The maturity date is the date when the security expires. + * @param integer price The security's price per $100 face value. + * @param integer redemption The security's redemption value per $100 face value. + * @param integer basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return float + */ + public static function DISC($settlement, $maturity, $price, $redemption, $basis=0) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $price = PHPExcel_Calculation_Functions::flattenSingleValue($price); + $redemption = PHPExcel_Calculation_Functions::flattenSingleValue($redemption); + $basis = PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + // Validate + if ((is_numeric($price)) && (is_numeric($redemption)) && (is_numeric($basis))) { + $price = (float) $price; + $redemption = (float) $redemption; + $basis = (int) $basis; + if (($price <= 0) || ($redemption <= 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity, $basis); + if (!is_numeric($daysBetweenSettlementAndMaturity)) { + // return date error + return $daysBetweenSettlementAndMaturity; + } + + return ((1 - $price / $redemption) / $daysBetweenSettlementAndMaturity); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function DISC() + + + /** + * DOLLARDE + * + * Converts a dollar price expressed as an integer part and a fraction + * part into a dollar price expressed as a decimal number. + * Fractional dollar numbers are sometimes used for security prices. + * + * Excel Function: + * DOLLARDE(fractional_dollar,fraction) + * + * @access public + * @category Financial Functions + * @param float $fractional_dollar Fractional Dollar + * @param integer $fraction Fraction + * @return float + */ + public static function DOLLARDE($fractional_dollar = Null, $fraction = 0) { + $fractional_dollar = PHPExcel_Calculation_Functions::flattenSingleValue($fractional_dollar); + $fraction = (int)PHPExcel_Calculation_Functions::flattenSingleValue($fraction); + + // Validate parameters + if (is_null($fractional_dollar) || $fraction < 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ($fraction == 0) { + return PHPExcel_Calculation_Functions::DIV0(); + } + + $dollars = floor($fractional_dollar); + $cents = fmod($fractional_dollar,1); + $cents /= $fraction; + $cents *= pow(10,ceil(log10($fraction))); + return $dollars + $cents; + } // function DOLLARDE() + + + /** + * DOLLARFR + * + * Converts a dollar price expressed as a decimal number into a dollar price + * expressed as a fraction. + * Fractional dollar numbers are sometimes used for security prices. + * + * Excel Function: + * DOLLARFR(decimal_dollar,fraction) + * + * @access public + * @category Financial Functions + * @param float $decimal_dollar Decimal Dollar + * @param integer $fraction Fraction + * @return float + */ + public static function DOLLARFR($decimal_dollar = Null, $fraction = 0) { + $decimal_dollar = PHPExcel_Calculation_Functions::flattenSingleValue($decimal_dollar); + $fraction = (int)PHPExcel_Calculation_Functions::flattenSingleValue($fraction); + + // Validate parameters + if (is_null($decimal_dollar) || $fraction < 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ($fraction == 0) { + return PHPExcel_Calculation_Functions::DIV0(); + } + + $dollars = floor($decimal_dollar); + $cents = fmod($decimal_dollar,1); + $cents *= $fraction; + $cents *= pow(10,-ceil(log10($fraction))); + return $dollars + $cents; + } // function DOLLARFR() + + + /** + * EFFECT + * + * Returns the effective interest rate given the nominal rate and the number of + * compounding payments per year. + * + * Excel Function: + * EFFECT(nominal_rate,npery) + * + * @access public + * @category Financial Functions + * @param float $nominal_rate Nominal interest rate + * @param integer $npery Number of compounding payments per year + * @return float + */ + public static function EFFECT($nominal_rate = 0, $npery = 0) { + $nominal_rate = PHPExcel_Calculation_Functions::flattenSingleValue($nominal_rate); + $npery = (int)PHPExcel_Calculation_Functions::flattenSingleValue($npery); + + // Validate parameters + if ($nominal_rate <= 0 || $npery < 1) { + return PHPExcel_Calculation_Functions::NaN(); + } + + return pow((1 + $nominal_rate / $npery), $npery) - 1; + } // function EFFECT() + + + /** + * FV + * + * Returns the Future Value of a cash flow with constant payments and interest rate (annuities). + * + * Excel Function: + * FV(rate,nper,pmt[,pv[,type]]) + * + * @access public + * @category Financial Functions + * @param float $rate The interest rate per period + * @param int $nper Total number of payment periods in an annuity + * @param float $pmt The payment made each period: it cannot change over the + * life of the annuity. Typically, pmt contains principal + * and interest but no other fees or taxes. + * @param float $pv Present Value, or the lump-sum amount that a series of + * future payments is worth right now. + * @param integer $type A number 0 or 1 and indicates when payments are due: + * 0 or omitted At the end of the period. + * 1 At the beginning of the period. + * @return float + */ + public static function FV($rate = 0, $nper = 0, $pmt = 0, $pv = 0, $type = 0) { + $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); + $nper = PHPExcel_Calculation_Functions::flattenSingleValue($nper); + $pmt = PHPExcel_Calculation_Functions::flattenSingleValue($pmt); + $pv = PHPExcel_Calculation_Functions::flattenSingleValue($pv); + $type = PHPExcel_Calculation_Functions::flattenSingleValue($type); + + // Validate parameters + if ($type != 0 && $type != 1) { + return PHPExcel_Calculation_Functions::NaN(); + } + + // Calculate + if (!is_null($rate) && $rate != 0) { + return -$pv * pow(1 + $rate, $nper) - $pmt * (1 + $rate * $type) * (pow(1 + $rate, $nper) - 1) / $rate; + } else { + return -$pv - $pmt * $nper; + } + } // function FV() + + + /** + * FVSCHEDULE + * + * Returns the future value of an initial principal after applying a series of compound interest rates. + * Use FVSCHEDULE to calculate the future value of an investment with a variable or adjustable rate. + * + * Excel Function: + * FVSCHEDULE(principal,schedule) + * + * @param float $principal The present value. + * @param float[] $schedule An array of interest rates to apply. + * @return float + */ + public static function FVSCHEDULE($principal, $schedule) { + $principal = PHPExcel_Calculation_Functions::flattenSingleValue($principal); + $schedule = PHPExcel_Calculation_Functions::flattenArray($schedule); + + foreach($schedule as $rate) { + $principal *= 1 + $rate; + } + + return $principal; + } // function FVSCHEDULE() + + + /** + * INTRATE + * + * Returns the interest rate for a fully invested security. + * + * Excel Function: + * INTRATE(settlement,maturity,investment,redemption[,basis]) + * + * @param mixed $settlement The security's settlement date. + * The security settlement date is the date after the issue date when the security is traded to the buyer. + * @param mixed $maturity The security's maturity date. + * The maturity date is the date when the security expires. + * @param integer $investment The amount invested in the security. + * @param integer $redemption The amount to be received at maturity. + * @param integer $basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return float + */ + public static function INTRATE($settlement, $maturity, $investment, $redemption, $basis=0) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $investment = PHPExcel_Calculation_Functions::flattenSingleValue($investment); + $redemption = PHPExcel_Calculation_Functions::flattenSingleValue($redemption); + $basis = PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + // Validate + if ((is_numeric($investment)) && (is_numeric($redemption)) && (is_numeric($basis))) { + $investment = (float) $investment; + $redemption = (float) $redemption; + $basis = (int) $basis; + if (($investment <= 0) || ($redemption <= 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity, $basis); + if (!is_numeric($daysBetweenSettlementAndMaturity)) { + // return date error + return $daysBetweenSettlementAndMaturity; + } + + return (($redemption / $investment) - 1) / ($daysBetweenSettlementAndMaturity); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function INTRATE() + + + /** + * IPMT + * + * Returns the interest payment for a given period for an investment based on periodic, constant payments and a constant interest rate. + * + * Excel Function: + * IPMT(rate,per,nper,pv[,fv][,type]) + * + * @param float $rate Interest rate per period + * @param int $per Period for which we want to find the interest + * @param int $nper Number of periods + * @param float $pv Present Value + * @param float $fv Future Value + * @param int $type Payment type: 0 = at the end of each period, 1 = at the beginning of each period + * @return float + */ + public static function IPMT($rate, $per, $nper, $pv, $fv = 0, $type = 0) { + $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); + $per = (int) PHPExcel_Calculation_Functions::flattenSingleValue($per); + $nper = (int) PHPExcel_Calculation_Functions::flattenSingleValue($nper); + $pv = PHPExcel_Calculation_Functions::flattenSingleValue($pv); + $fv = PHPExcel_Calculation_Functions::flattenSingleValue($fv); + $type = (int) PHPExcel_Calculation_Functions::flattenSingleValue($type); + + // Validate parameters + if ($type != 0 && $type != 1) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ($per <= 0 || $per > $nper) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + // Calculate + $interestAndPrincipal = self::_interestAndPrincipal($rate, $per, $nper, $pv, $fv, $type); + return $interestAndPrincipal[0]; + } // function IPMT() + + /** + * IRR + * + * Returns the internal rate of return for a series of cash flows represented by the numbers in values. + * These cash flows do not have to be even, as they would be for an annuity. However, the cash flows must occur + * at regular intervals, such as monthly or annually. The internal rate of return is the interest rate received + * for an investment consisting of payments (negative values) and income (positive values) that occur at regular + * periods. + * + * Excel Function: + * IRR(values[,guess]) + * + * @param float[] $values An array or a reference to cells that contain numbers for which you want + * to calculate the internal rate of return. + * Values must contain at least one positive value and one negative value to + * calculate the internal rate of return. + * @param float $guess A number that you guess is close to the result of IRR + * @return float + */ + public static function IRR($values, $guess = 0.1) { + if (!is_array($values)) return PHPExcel_Calculation_Functions::VALUE(); + $values = PHPExcel_Calculation_Functions::flattenArray($values); + $guess = PHPExcel_Calculation_Functions::flattenSingleValue($guess); + + // create an initial range, with a root somewhere between 0 and guess + $x1 = 0.0; + $x2 = $guess; + $f1 = self::NPV($x1, $values); + $f2 = self::NPV($x2, $values); + for ($i = 0; $i < FINANCIAL_MAX_ITERATIONS; ++$i) { + if (($f1 * $f2) < 0.0) break; + if (abs($f1) < abs($f2)) { + $f1 = self::NPV($x1 += 1.6 * ($x1 - $x2), $values); + } else { + $f2 = self::NPV($x2 += 1.6 * ($x2 - $x1), $values); + } + } + if (($f1 * $f2) > 0.0) return PHPExcel_Calculation_Functions::VALUE(); + + $f = self::NPV($x1, $values); + if ($f < 0.0) { + $rtb = $x1; + $dx = $x2 - $x1; + } else { + $rtb = $x2; + $dx = $x1 - $x2; + } + + for ($i = 0; $i < FINANCIAL_MAX_ITERATIONS; ++$i) { + $dx *= 0.5; + $x_mid = $rtb + $dx; + $f_mid = self::NPV($x_mid, $values); + if ($f_mid <= 0.0) + $rtb = $x_mid; + if ((abs($f_mid) < FINANCIAL_PRECISION) || (abs($dx) < FINANCIAL_PRECISION)) + return $x_mid; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function IRR() + + + /** + * ISPMT + * + * Returns the interest payment for an investment based on an interest rate and a constant payment schedule. + * + * Excel Function: + * =ISPMT(interest_rate, period, number_payments, PV) + * + * interest_rate is the interest rate for the investment + * + * period is the period to calculate the interest rate. It must be betweeen 1 and number_payments. + * + * number_payments is the number of payments for the annuity + * + * PV is the loan amount or present value of the payments + */ + public static function ISPMT() { + // Return value + $returnValue = 0; + + // Get the parameters + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + $interestRate = array_shift($aArgs); + $period = array_shift($aArgs); + $numberPeriods = array_shift($aArgs); + $principleRemaining = array_shift($aArgs); + + // Calculate + $principlePayment = ($principleRemaining * 1.0) / ($numberPeriods * 1.0); + for($i=0; $i <= $period; ++$i) { + $returnValue = $interestRate * $principleRemaining * -1; + $principleRemaining -= $principlePayment; + // principle needs to be 0 after the last payment, don't let floating point screw it up + if($i == $numberPeriods) { + $returnValue = 0; + } + } + return($returnValue); + } // function ISPMT() + + + /** + * MIRR + * + * Returns the modified internal rate of return for a series of periodic cash flows. MIRR considers both + * the cost of the investment and the interest received on reinvestment of cash. + * + * Excel Function: + * MIRR(values,finance_rate, reinvestment_rate) + * + * @param float[] $values An array or a reference to cells that contain a series of payments and + * income occurring at regular intervals. + * Payments are negative value, income is positive values. + * @param float $finance_rate The interest rate you pay on the money used in the cash flows + * @param float $reinvestment_rate The interest rate you receive on the cash flows as you reinvest them + * @return float + */ + public static function MIRR($values, $finance_rate, $reinvestment_rate) { + if (!is_array($values)) return PHPExcel_Calculation_Functions::VALUE(); + $values = PHPExcel_Calculation_Functions::flattenArray($values); + $finance_rate = PHPExcel_Calculation_Functions::flattenSingleValue($finance_rate); + $reinvestment_rate = PHPExcel_Calculation_Functions::flattenSingleValue($reinvestment_rate); + $n = count($values); + + $rr = 1.0 + $reinvestment_rate; + $fr = 1.0 + $finance_rate; + + $npv_pos = $npv_neg = 0.0; + foreach($values as $i => $v) { + if ($v >= 0) { + $npv_pos += $v / pow($rr, $i); + } else { + $npv_neg += $v / pow($fr, $i); + } + } + + if (($npv_neg == 0) || ($npv_pos == 0) || ($reinvestment_rate <= -1)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + $mirr = pow((-$npv_pos * pow($rr, $n)) + / ($npv_neg * ($rr)), (1.0 / ($n - 1))) - 1.0; + + return (is_finite($mirr) ? $mirr : PHPExcel_Calculation_Functions::VALUE()); + } // function MIRR() + + + /** + * NOMINAL + * + * Returns the nominal interest rate given the effective rate and the number of compounding payments per year. + * + * @param float $effect_rate Effective interest rate + * @param int $npery Number of compounding payments per year + * @return float + */ + public static function NOMINAL($effect_rate = 0, $npery = 0) { + $effect_rate = PHPExcel_Calculation_Functions::flattenSingleValue($effect_rate); + $npery = (int)PHPExcel_Calculation_Functions::flattenSingleValue($npery); + + // Validate parameters + if ($effect_rate <= 0 || $npery < 1) { + return PHPExcel_Calculation_Functions::NaN(); + } + + // Calculate + return $npery * (pow($effect_rate + 1, 1 / $npery) - 1); + } // function NOMINAL() + + + /** + * NPER + * + * Returns the number of periods for a cash flow with constant periodic payments (annuities), and interest rate. + * + * @param float $rate Interest rate per period + * @param int $pmt Periodic payment (annuity) + * @param float $pv Present Value + * @param float $fv Future Value + * @param int $type Payment type: 0 = at the end of each period, 1 = at the beginning of each period + * @return float + */ + public static function NPER($rate = 0, $pmt = 0, $pv = 0, $fv = 0, $type = 0) { + $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); + $pmt = PHPExcel_Calculation_Functions::flattenSingleValue($pmt); + $pv = PHPExcel_Calculation_Functions::flattenSingleValue($pv); + $fv = PHPExcel_Calculation_Functions::flattenSingleValue($fv); + $type = PHPExcel_Calculation_Functions::flattenSingleValue($type); + + // Validate parameters + if ($type != 0 && $type != 1) { + return PHPExcel_Calculation_Functions::NaN(); + } + + // Calculate + if (!is_null($rate) && $rate != 0) { + if ($pmt == 0 && $pv == 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + return log(($pmt * (1 + $rate * $type) / $rate - $fv) / ($pv + $pmt * (1 + $rate * $type) / $rate)) / log(1 + $rate); + } else { + if ($pmt == 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + return (-$pv -$fv) / $pmt; + } + } // function NPER() + + /** + * NPV + * + * Returns the Net Present Value of a cash flow series given a discount rate. + * + * @return float + */ + public static function NPV() { + // Return value + $returnValue = 0; + + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + + // Calculate + $rate = array_shift($aArgs); + for ($i = 1; $i <= count($aArgs); ++$i) { + // Is it a numeric value? + if (is_numeric($aArgs[$i - 1])) { + $returnValue += $aArgs[$i - 1] / pow(1 + $rate, $i); + } + } + + // Return + return $returnValue; + } // function NPV() + + /** + * PMT + * + * Returns the constant payment (annuity) for a cash flow with a constant interest rate. + * + * @param float $rate Interest rate per period + * @param int $nper Number of periods + * @param float $pv Present Value + * @param float $fv Future Value + * @param int $type Payment type: 0 = at the end of each period, 1 = at the beginning of each period + * @return float + */ + public static function PMT($rate = 0, $nper = 0, $pv = 0, $fv = 0, $type = 0) { + $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); + $nper = PHPExcel_Calculation_Functions::flattenSingleValue($nper); + $pv = PHPExcel_Calculation_Functions::flattenSingleValue($pv); + $fv = PHPExcel_Calculation_Functions::flattenSingleValue($fv); + $type = PHPExcel_Calculation_Functions::flattenSingleValue($type); + + // Validate parameters + if ($type != 0 && $type != 1) { + return PHPExcel_Calculation_Functions::NaN(); + } + + // Calculate + if (!is_null($rate) && $rate != 0) { + return (-$fv - $pv * pow(1 + $rate, $nper)) / (1 + $rate * $type) / ((pow(1 + $rate, $nper) - 1) / $rate); + } else { + return (-$pv - $fv) / $nper; + } + } // function PMT() + + + /** + * PPMT + * + * Returns the interest payment for a given period for an investment based on periodic, constant payments and a constant interest rate. + * + * @param float $rate Interest rate per period + * @param int $per Period for which we want to find the interest + * @param int $nper Number of periods + * @param float $pv Present Value + * @param float $fv Future Value + * @param int $type Payment type: 0 = at the end of each period, 1 = at the beginning of each period + * @return float + */ + public static function PPMT($rate, $per, $nper, $pv, $fv = 0, $type = 0) { + $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); + $per = (int) PHPExcel_Calculation_Functions::flattenSingleValue($per); + $nper = (int) PHPExcel_Calculation_Functions::flattenSingleValue($nper); + $pv = PHPExcel_Calculation_Functions::flattenSingleValue($pv); + $fv = PHPExcel_Calculation_Functions::flattenSingleValue($fv); + $type = (int) PHPExcel_Calculation_Functions::flattenSingleValue($type); + + // Validate parameters + if ($type != 0 && $type != 1) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ($per <= 0 || $per > $nper) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + // Calculate + $interestAndPrincipal = self::_interestAndPrincipal($rate, $per, $nper, $pv, $fv, $type); + return $interestAndPrincipal[1]; + } // function PPMT() + + + public static function PRICE($settlement, $maturity, $rate, $yield, $redemption, $frequency, $basis=0) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $rate = (float) PHPExcel_Calculation_Functions::flattenSingleValue($rate); + $yield = (float) PHPExcel_Calculation_Functions::flattenSingleValue($yield); + $redemption = (float) PHPExcel_Calculation_Functions::flattenSingleValue($redemption); + $frequency = (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency); + $basis = (is_null($basis)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + if (is_string($settlement = PHPExcel_Calculation_DateTime::_getDateValue($settlement))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + if (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (($settlement > $maturity) || + (!self::_validFrequency($frequency)) || + (($basis < 0) || ($basis > 4))) { + return PHPExcel_Calculation_Functions::NaN(); + } + + $dsc = self::COUPDAYSNC($settlement, $maturity, $frequency, $basis); + $e = self::COUPDAYS($settlement, $maturity, $frequency, $basis); + $n = self::COUPNUM($settlement, $maturity, $frequency, $basis); + $a = self::COUPDAYBS($settlement, $maturity, $frequency, $basis); + + $baseYF = 1.0 + ($yield / $frequency); + $rfp = 100 * ($rate / $frequency); + $de = $dsc / $e; + + $result = $redemption / pow($baseYF, (--$n + $de)); + for($k = 0; $k <= $n; ++$k) { + $result += $rfp / (pow($baseYF, ($k + $de))); + } + $result -= $rfp * ($a / $e); + + return $result; + } // function PRICE() + + + /** + * PRICEDISC + * + * Returns the price per $100 face value of a discounted security. + * + * @param mixed settlement The security's settlement date. + * The security settlement date is the date after the issue date when the security is traded to the buyer. + * @param mixed maturity The security's maturity date. + * The maturity date is the date when the security expires. + * @param int discount The security's discount rate. + * @param int redemption The security's redemption value per $100 face value. + * @param int basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return float + */ + public static function PRICEDISC($settlement, $maturity, $discount, $redemption, $basis=0) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $discount = (float) PHPExcel_Calculation_Functions::flattenSingleValue($discount); + $redemption = (float) PHPExcel_Calculation_Functions::flattenSingleValue($redemption); + $basis = (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + // Validate + if ((is_numeric($discount)) && (is_numeric($redemption)) && (is_numeric($basis))) { + if (($discount <= 0) || ($redemption <= 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity, $basis); + if (!is_numeric($daysBetweenSettlementAndMaturity)) { + // return date error + return $daysBetweenSettlementAndMaturity; + } + + return $redemption * (1 - $discount * $daysBetweenSettlementAndMaturity); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function PRICEDISC() + + + /** + * PRICEMAT + * + * Returns the price per $100 face value of a security that pays interest at maturity. + * + * @param mixed settlement The security's settlement date. + * The security's settlement date is the date after the issue date when the security is traded to the buyer. + * @param mixed maturity The security's maturity date. + * The maturity date is the date when the security expires. + * @param mixed issue The security's issue date. + * @param int rate The security's interest rate at date of issue. + * @param int yield The security's annual yield. + * @param int basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return float + */ + public static function PRICEMAT($settlement, $maturity, $issue, $rate, $yield, $basis=0) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $issue = PHPExcel_Calculation_Functions::flattenSingleValue($issue); + $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); + $yield = PHPExcel_Calculation_Functions::flattenSingleValue($yield); + $basis = (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + // Validate + if (is_numeric($rate) && is_numeric($yield)) { + if (($rate <= 0) || ($yield <= 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $daysPerYear = self::_daysPerYear(PHPExcel_Calculation_DateTime::YEAR($settlement),$basis); + if (!is_numeric($daysPerYear)) { + return $daysPerYear; + } + $daysBetweenIssueAndSettlement = PHPExcel_Calculation_DateTime::YEARFRAC($issue, $settlement, $basis); + if (!is_numeric($daysBetweenIssueAndSettlement)) { + // return date error + return $daysBetweenIssueAndSettlement; + } + $daysBetweenIssueAndSettlement *= $daysPerYear; + $daysBetweenIssueAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($issue, $maturity, $basis); + if (!is_numeric($daysBetweenIssueAndMaturity)) { + // return date error + return $daysBetweenIssueAndMaturity; + } + $daysBetweenIssueAndMaturity *= $daysPerYear; + $daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity, $basis); + if (!is_numeric($daysBetweenSettlementAndMaturity)) { + // return date error + return $daysBetweenSettlementAndMaturity; + } + $daysBetweenSettlementAndMaturity *= $daysPerYear; + + return ((100 + (($daysBetweenIssueAndMaturity / $daysPerYear) * $rate * 100)) / + (1 + (($daysBetweenSettlementAndMaturity / $daysPerYear) * $yield)) - + (($daysBetweenIssueAndSettlement / $daysPerYear) * $rate * 100)); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function PRICEMAT() + + + /** + * PV + * + * Returns the Present Value of a cash flow with constant payments and interest rate (annuities). + * + * @param float $rate Interest rate per period + * @param int $nper Number of periods + * @param float $pmt Periodic payment (annuity) + * @param float $fv Future Value + * @param int $type Payment type: 0 = at the end of each period, 1 = at the beginning of each period + * @return float + */ + public static function PV($rate = 0, $nper = 0, $pmt = 0, $fv = 0, $type = 0) { + $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); + $nper = PHPExcel_Calculation_Functions::flattenSingleValue($nper); + $pmt = PHPExcel_Calculation_Functions::flattenSingleValue($pmt); + $fv = PHPExcel_Calculation_Functions::flattenSingleValue($fv); + $type = PHPExcel_Calculation_Functions::flattenSingleValue($type); + + // Validate parameters + if ($type != 0 && $type != 1) { + return PHPExcel_Calculation_Functions::NaN(); + } + + // Calculate + if (!is_null($rate) && $rate != 0) { + return (-$pmt * (1 + $rate * $type) * ((pow(1 + $rate, $nper) - 1) / $rate) - $fv) / pow(1 + $rate, $nper); + } else { + return -$fv - $pmt * $nper; + } + } // function PV() + + + /** + * RATE + * + * Returns the interest rate per period of an annuity. + * RATE is calculated by iteration and can have zero or more solutions. + * If the successive results of RATE do not converge to within 0.0000001 after 20 iterations, + * RATE returns the #NUM! error value. + * + * Excel Function: + * RATE(nper,pmt,pv[,fv[,type[,guess]]]) + * + * @access public + * @category Financial Functions + * @param float nper The total number of payment periods in an annuity. + * @param float pmt The payment made each period and cannot change over the life + * of the annuity. + * Typically, pmt includes principal and interest but no other + * fees or taxes. + * @param float pv The present value - the total amount that a series of future + * payments is worth now. + * @param float fv The future value, or a cash balance you want to attain after + * the last payment is made. If fv is omitted, it is assumed + * to be 0 (the future value of a loan, for example, is 0). + * @param integer type A number 0 or 1 and indicates when payments are due: + * 0 or omitted At the end of the period. + * 1 At the beginning of the period. + * @param float guess Your guess for what the rate will be. + * If you omit guess, it is assumed to be 10 percent. + * @return float + **/ + public static function RATE($nper, $pmt, $pv, $fv = 0.0, $type = 0, $guess = 0.1) { + $nper = (int) PHPExcel_Calculation_Functions::flattenSingleValue($nper); + $pmt = PHPExcel_Calculation_Functions::flattenSingleValue($pmt); + $pv = PHPExcel_Calculation_Functions::flattenSingleValue($pv); + $fv = (is_null($fv)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($fv); + $type = (is_null($type)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($type); + $guess = (is_null($guess)) ? 0.1 : PHPExcel_Calculation_Functions::flattenSingleValue($guess); + + $rate = $guess; + if (abs($rate) < FINANCIAL_PRECISION) { + $y = $pv * (1 + $nper * $rate) + $pmt * (1 + $rate * $type) * $nper + $fv; + } else { + $f = exp($nper * log(1 + $rate)); + $y = $pv * $f + $pmt * (1 / $rate + $type) * ($f - 1) + $fv; + } + $y0 = $pv + $pmt * $nper + $fv; + $y1 = $pv * $f + $pmt * (1 / $rate + $type) * ($f - 1) + $fv; + + // find root by secant method + $i = $x0 = 0.0; + $x1 = $rate; + while ((abs($y0 - $y1) > FINANCIAL_PRECISION) && ($i < FINANCIAL_MAX_ITERATIONS)) { + $rate = ($y1 * $x0 - $y0 * $x1) / ($y1 - $y0); + $x0 = $x1; + $x1 = $rate; + if (($nper * abs($pmt)) > ($pv - $fv)) + $x1 = abs($x1); + + if (abs($rate) < FINANCIAL_PRECISION) { + $y = $pv * (1 + $nper * $rate) + $pmt * (1 + $rate * $type) * $nper + $fv; + } else { + $f = exp($nper * log(1 + $rate)); + $y = $pv * $f + $pmt * (1 / $rate + $type) * ($f - 1) + $fv; + } + + $y0 = $y1; + $y1 = $y; + ++$i; + } + return $rate; + } // function RATE() + + + /** + * RECEIVED + * + * Returns the price per $100 face value of a discounted security. + * + * @param mixed settlement The security's settlement date. + * The security settlement date is the date after the issue date when the security is traded to the buyer. + * @param mixed maturity The security's maturity date. + * The maturity date is the date when the security expires. + * @param int investment The amount invested in the security. + * @param int discount The security's discount rate. + * @param int basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return float + */ + public static function RECEIVED($settlement, $maturity, $investment, $discount, $basis=0) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $investment = (float) PHPExcel_Calculation_Functions::flattenSingleValue($investment); + $discount = (float) PHPExcel_Calculation_Functions::flattenSingleValue($discount); + $basis = (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + // Validate + if ((is_numeric($investment)) && (is_numeric($discount)) && (is_numeric($basis))) { + if (($investment <= 0) || ($discount <= 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity, $basis); + if (!is_numeric($daysBetweenSettlementAndMaturity)) { + // return date error + return $daysBetweenSettlementAndMaturity; + } + + return $investment / ( 1 - ($discount * $daysBetweenSettlementAndMaturity)); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function RECEIVED() + + + /** + * SLN + * + * Returns the straight-line depreciation of an asset for one period + * + * @param cost Initial cost of the asset + * @param salvage Value at the end of the depreciation + * @param life Number of periods over which the asset is depreciated + * @return float + */ + public static function SLN($cost, $salvage, $life) { + $cost = PHPExcel_Calculation_Functions::flattenSingleValue($cost); + $salvage = PHPExcel_Calculation_Functions::flattenSingleValue($salvage); + $life = PHPExcel_Calculation_Functions::flattenSingleValue($life); + + // Calculate + if ((is_numeric($cost)) && (is_numeric($salvage)) && (is_numeric($life))) { + if ($life < 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + return ($cost - $salvage) / $life; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function SLN() + + + /** + * SYD + * + * Returns the sum-of-years' digits depreciation of an asset for a specified period. + * + * @param cost Initial cost of the asset + * @param salvage Value at the end of the depreciation + * @param life Number of periods over which the asset is depreciated + * @param period Period + * @return float + */ + public static function SYD($cost, $salvage, $life, $period) { + $cost = PHPExcel_Calculation_Functions::flattenSingleValue($cost); + $salvage = PHPExcel_Calculation_Functions::flattenSingleValue($salvage); + $life = PHPExcel_Calculation_Functions::flattenSingleValue($life); + $period = PHPExcel_Calculation_Functions::flattenSingleValue($period); + + // Calculate + if ((is_numeric($cost)) && (is_numeric($salvage)) && (is_numeric($life)) && (is_numeric($period))) { + if (($life < 1) || ($period > $life)) { + return PHPExcel_Calculation_Functions::NaN(); + } + return (($cost - $salvage) * ($life - $period + 1) * 2) / ($life * ($life + 1)); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function SYD() + + + /** + * TBILLEQ + * + * Returns the bond-equivalent yield for a Treasury bill. + * + * @param mixed settlement The Treasury bill's settlement date. + * The Treasury bill's settlement date is the date after the issue date when the Treasury bill is traded to the buyer. + * @param mixed maturity The Treasury bill's maturity date. + * The maturity date is the date when the Treasury bill expires. + * @param int discount The Treasury bill's discount rate. + * @return float + */ + public static function TBILLEQ($settlement, $maturity, $discount) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $discount = PHPExcel_Calculation_Functions::flattenSingleValue($discount); + + // Use TBILLPRICE for validation + $testValue = self::TBILLPRICE($settlement, $maturity, $discount); + if (is_string($testValue)) { + return $testValue; + } + + if (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { + ++$maturity; + $daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity) * 360; + } else { + $daysBetweenSettlementAndMaturity = (PHPExcel_Calculation_DateTime::_getDateValue($maturity) - PHPExcel_Calculation_DateTime::_getDateValue($settlement)); + } + + return (365 * $discount) / (360 - $discount * $daysBetweenSettlementAndMaturity); + } // function TBILLEQ() + + + /** + * TBILLPRICE + * + * Returns the yield for a Treasury bill. + * + * @param mixed settlement The Treasury bill's settlement date. + * The Treasury bill's settlement date is the date after the issue date when the Treasury bill is traded to the buyer. + * @param mixed maturity The Treasury bill's maturity date. + * The maturity date is the date when the Treasury bill expires. + * @param int discount The Treasury bill's discount rate. + * @return float + */ + public static function TBILLPRICE($settlement, $maturity, $discount) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $discount = PHPExcel_Calculation_Functions::flattenSingleValue($discount); + + if (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + // Validate + if (is_numeric($discount)) { + if ($discount <= 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { + ++$maturity; + $daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity) * 360; + if (!is_numeric($daysBetweenSettlementAndMaturity)) { + // return date error + return $daysBetweenSettlementAndMaturity; + } + } else { + $daysBetweenSettlementAndMaturity = (PHPExcel_Calculation_DateTime::_getDateValue($maturity) - PHPExcel_Calculation_DateTime::_getDateValue($settlement)); + } + + if ($daysBetweenSettlementAndMaturity > 360) { + return PHPExcel_Calculation_Functions::NaN(); + } + + $price = 100 * (1 - (($discount * $daysBetweenSettlementAndMaturity) / 360)); + if ($price <= 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + return $price; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function TBILLPRICE() + + + /** + * TBILLYIELD + * + * Returns the yield for a Treasury bill. + * + * @param mixed settlement The Treasury bill's settlement date. + * The Treasury bill's settlement date is the date after the issue date when the Treasury bill is traded to the buyer. + * @param mixed maturity The Treasury bill's maturity date. + * The maturity date is the date when the Treasury bill expires. + * @param int price The Treasury bill's price per $100 face value. + * @return float + */ + public static function TBILLYIELD($settlement, $maturity, $price) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $price = PHPExcel_Calculation_Functions::flattenSingleValue($price); + + // Validate + if (is_numeric($price)) { + if ($price <= 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { + ++$maturity; + $daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity) * 360; + if (!is_numeric($daysBetweenSettlementAndMaturity)) { + // return date error + return $daysBetweenSettlementAndMaturity; + } + } else { + $daysBetweenSettlementAndMaturity = (PHPExcel_Calculation_DateTime::_getDateValue($maturity) - PHPExcel_Calculation_DateTime::_getDateValue($settlement)); + } + + if ($daysBetweenSettlementAndMaturity > 360) { + return PHPExcel_Calculation_Functions::NaN(); + } + + return ((100 - $price) / $price) * (360 / $daysBetweenSettlementAndMaturity); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function TBILLYIELD() + + + public static function XIRR($values, $dates, $guess = 0.1) { + if ((!is_array($values)) && (!is_array($dates))) return PHPExcel_Calculation_Functions::VALUE(); + $values = PHPExcel_Calculation_Functions::flattenArray($values); + $dates = PHPExcel_Calculation_Functions::flattenArray($dates); + $guess = PHPExcel_Calculation_Functions::flattenSingleValue($guess); + if (count($values) != count($dates)) return PHPExcel_Calculation_Functions::NaN(); + + // create an initial range, with a root somewhere between 0 and guess + $x1 = 0.0; + $x2 = $guess; + $f1 = self::XNPV($x1, $values, $dates); + $f2 = self::XNPV($x2, $values, $dates); + for ($i = 0; $i < FINANCIAL_MAX_ITERATIONS; ++$i) { + if (($f1 * $f2) < 0.0) break; + if (abs($f1) < abs($f2)) { + $f1 = self::XNPV($x1 += 1.6 * ($x1 - $x2), $values, $dates); + } else { + $f2 = self::XNPV($x2 += 1.6 * ($x2 - $x1), $values, $dates); + } + } + if (($f1 * $f2) > 0.0) return PHPExcel_Calculation_Functions::VALUE(); + + $f = self::XNPV($x1, $values, $dates); + if ($f < 0.0) { + $rtb = $x1; + $dx = $x2 - $x1; + } else { + $rtb = $x2; + $dx = $x1 - $x2; + } + + for ($i = 0; $i < FINANCIAL_MAX_ITERATIONS; ++$i) { + $dx *= 0.5; + $x_mid = $rtb + $dx; + $f_mid = self::XNPV($x_mid, $values, $dates); + if ($f_mid <= 0.0) $rtb = $x_mid; + if ((abs($f_mid) < FINANCIAL_PRECISION) || (abs($dx) < FINANCIAL_PRECISION)) return $x_mid; + } + return PHPExcel_Calculation_Functions::VALUE(); + } + + + /** + * XNPV + * + * Returns the net present value for a schedule of cash flows that is not necessarily periodic. + * To calculate the net present value for a series of cash flows that is periodic, use the NPV function. + * + * Excel Function: + * =XNPV(rate,values,dates) + * + * @param float $rate The discount rate to apply to the cash flows. + * @param array of float $values A series of cash flows that corresponds to a schedule of payments in dates. The first payment is optional and corresponds to a cost or payment that occurs at the beginning of the investment. If the first value is a cost or payment, it must be a negative value. All succeeding payments are discounted based on a 365-day year. The series of values must contain at least one positive value and one negative value. + * @param array of mixed $dates A schedule of payment dates that corresponds to the cash flow payments. The first payment date indicates the beginning of the schedule of payments. All other dates must be later than this date, but they may occur in any order. + * @return float + */ + public static function XNPV($rate, $values, $dates) { + $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); + if (!is_numeric($rate)) return PHPExcel_Calculation_Functions::VALUE(); + if ((!is_array($values)) || (!is_array($dates))) return PHPExcel_Calculation_Functions::VALUE(); + $values = PHPExcel_Calculation_Functions::flattenArray($values); + $dates = PHPExcel_Calculation_Functions::flattenArray($dates); + $valCount = count($values); + if ($valCount != count($dates)) return PHPExcel_Calculation_Functions::NaN(); + if ((min($values) > 0) || (max($values) < 0)) return PHPExcel_Calculation_Functions::VALUE(); + + $xnpv = 0.0; + for ($i = 0; $i < $valCount; ++$i) { + if (!is_numeric($values[$i])) return PHPExcel_Calculation_Functions::VALUE(); + $xnpv += $values[$i] / pow(1 + $rate, PHPExcel_Calculation_DateTime::DATEDIF($dates[0],$dates[$i],'d') / 365); + } + return (is_finite($xnpv)) ? $xnpv : PHPExcel_Calculation_Functions::VALUE(); + } // function XNPV() + + + /** + * YIELDDISC + * + * Returns the annual yield of a security that pays interest at maturity. + * + * @param mixed settlement The security's settlement date. + * The security's settlement date is the date after the issue date when the security is traded to the buyer. + * @param mixed maturity The security's maturity date. + * The maturity date is the date when the security expires. + * @param int price The security's price per $100 face value. + * @param int redemption The security's redemption value per $100 face value. + * @param int basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return float + */ + public static function YIELDDISC($settlement, $maturity, $price, $redemption, $basis=0) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $price = PHPExcel_Calculation_Functions::flattenSingleValue($price); + $redemption = PHPExcel_Calculation_Functions::flattenSingleValue($redemption); + $basis = (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + // Validate + if (is_numeric($price) && is_numeric($redemption)) { + if (($price <= 0) || ($redemption <= 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $daysPerYear = self::_daysPerYear(PHPExcel_Calculation_DateTime::YEAR($settlement),$basis); + if (!is_numeric($daysPerYear)) { + return $daysPerYear; + } + $daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity,$basis); + if (!is_numeric($daysBetweenSettlementAndMaturity)) { + // return date error + return $daysBetweenSettlementAndMaturity; + } + $daysBetweenSettlementAndMaturity *= $daysPerYear; + + return (($redemption - $price) / $price) * ($daysPerYear / $daysBetweenSettlementAndMaturity); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function YIELDDISC() + + + /** + * YIELDMAT + * + * Returns the annual yield of a security that pays interest at maturity. + * + * @param mixed settlement The security's settlement date. + * The security's settlement date is the date after the issue date when the security is traded to the buyer. + * @param mixed maturity The security's maturity date. + * The maturity date is the date when the security expires. + * @param mixed issue The security's issue date. + * @param int rate The security's interest rate at date of issue. + * @param int price The security's price per $100 face value. + * @param int basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return float + */ + public static function YIELDMAT($settlement, $maturity, $issue, $rate, $price, $basis=0) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $issue = PHPExcel_Calculation_Functions::flattenSingleValue($issue); + $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); + $price = PHPExcel_Calculation_Functions::flattenSingleValue($price); + $basis = (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + // Validate + if (is_numeric($rate) && is_numeric($price)) { + if (($rate <= 0) || ($price <= 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $daysPerYear = self::_daysPerYear(PHPExcel_Calculation_DateTime::YEAR($settlement),$basis); + if (!is_numeric($daysPerYear)) { + return $daysPerYear; + } + $daysBetweenIssueAndSettlement = PHPExcel_Calculation_DateTime::YEARFRAC($issue, $settlement, $basis); + if (!is_numeric($daysBetweenIssueAndSettlement)) { + // return date error + return $daysBetweenIssueAndSettlement; + } + $daysBetweenIssueAndSettlement *= $daysPerYear; + $daysBetweenIssueAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($issue, $maturity, $basis); + if (!is_numeric($daysBetweenIssueAndMaturity)) { + // return date error + return $daysBetweenIssueAndMaturity; + } + $daysBetweenIssueAndMaturity *= $daysPerYear; + $daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity, $basis); + if (!is_numeric($daysBetweenSettlementAndMaturity)) { + // return date error + return $daysBetweenSettlementAndMaturity; + } + $daysBetweenSettlementAndMaturity *= $daysPerYear; + + return ((1 + (($daysBetweenIssueAndMaturity / $daysPerYear) * $rate) - (($price / 100) + (($daysBetweenIssueAndSettlement / $daysPerYear) * $rate))) / + (($price / 100) + (($daysBetweenIssueAndSettlement / $daysPerYear) * $rate))) * + ($daysPerYear / $daysBetweenSettlementAndMaturity); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function YIELDMAT() + +} // class PHPExcel_Calculation_Financial diff --git a/lib/phpexcel/PHPExcel/Calculation/FormulaParser.php b/lib/phpexcel/PHPExcel/Calculation/FormulaParser.php new file mode 100644 index 0000000..754a638 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Calculation/FormulaParser.php @@ -0,0 +1,614 @@ +<"; + const OPERATORS_POSTFIX = "%"; + + /** + * Formula + * + * @var string + */ + private $_formula; + + /** + * Tokens + * + * @var PHPExcel_Calculation_FormulaToken[] + */ + private $_tokens = array(); + + /** + * Create a new PHPExcel_Calculation_FormulaParser + * + * @param string $pFormula Formula to parse + * @throws PHPExcel_Calculation_Exception + */ + public function __construct($pFormula = '') + { + // Check parameters + if (is_null($pFormula)) { + throw new PHPExcel_Calculation_Exception("Invalid parameter passed: formula"); + } + + // Initialise values + $this->_formula = trim($pFormula); + // Parse! + $this->_parseToTokens(); + } + + /** + * Get Formula + * + * @return string + */ + public function getFormula() { + return $this->_formula; + } + + /** + * Get Token + * + * @param int $pId Token id + * @return string + * @throws PHPExcel_Calculation_Exception + */ + public function getToken($pId = 0) { + if (isset($this->_tokens[$pId])) { + return $this->_tokens[$pId]; + } else { + throw new PHPExcel_Calculation_Exception("Token with id $pId does not exist."); + } + } + + /** + * Get Token count + * + * @return string + */ + public function getTokenCount() { + return count($this->_tokens); + } + + /** + * Get Tokens + * + * @return PHPExcel_Calculation_FormulaToken[] + */ + public function getTokens() { + return $this->_tokens; + } + + /** + * Parse to tokens + */ + private function _parseToTokens() { + // No attempt is made to verify formulas; assumes formulas are derived from Excel, where + // they can only exist if valid; stack overflows/underflows sunk as nulls without exceptions. + + // Check if the formula has a valid starting = + $formulaLength = strlen($this->_formula); + if ($formulaLength < 2 || $this->_formula{0} != '=') return; + + // Helper variables + $tokens1 = $tokens2 = $stack = array(); + $inString = $inPath = $inRange = $inError = false; + $token = $previousToken = $nextToken = null; + + $index = 1; + $value = ''; + + $ERRORS = array("#NULL!", "#DIV/0!", "#VALUE!", "#REF!", "#NAME?", "#NUM!", "#N/A"); + $COMPARATORS_MULTI = array(">=", "<=", "<>"); + + while ($index < $formulaLength) { + // state-dependent character evaluation (order is important) + + // double-quoted strings + // embeds are doubled + // end marks token + if ($inString) { + if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::QUOTE_DOUBLE) { + if ((($index + 2) <= $formulaLength) && ($this->_formula{$index + 1} == PHPExcel_Calculation_FormulaParser::QUOTE_DOUBLE)) { + $value .= PHPExcel_Calculation_FormulaParser::QUOTE_DOUBLE; + ++$index; + } else { + $inString = false; + $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_TEXT); + $value = ""; + } + } else { + $value .= $this->_formula{$index}; + } + ++$index; + continue; + } + + // single-quoted strings (links) + // embeds are double + // end does not mark a token + if ($inPath) { + if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::QUOTE_SINGLE) { + if ((($index + 2) <= $formulaLength) && ($this->_formula{$index + 1} == PHPExcel_Calculation_FormulaParser::QUOTE_SINGLE)) { + $value .= PHPExcel_Calculation_FormulaParser::QUOTE_SINGLE; + ++$index; + } else { + $inPath = false; + } + } else { + $value .= $this->_formula{$index}; + } + ++$index; + continue; + } + + // bracked strings (R1C1 range index or linked workbook name) + // no embeds (changed to "()" by Excel) + // end does not mark a token + if ($inRange) { + if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::BRACKET_CLOSE) { + $inRange = false; + } + $value .= $this->_formula{$index}; + ++$index; + continue; + } + + // error values + // end marks a token, determined from absolute list of values + if ($inError) { + $value .= $this->_formula{$index}; + ++$index; + if (in_array($value, $ERRORS)) { + $inError = false; + $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_ERROR); + $value = ""; + } + continue; + } + + // scientific notation check + if (strpos(PHPExcel_Calculation_FormulaParser::OPERATORS_SN, $this->_formula{$index}) !== false) { + if (strlen($value) > 1) { + if (preg_match("/^[1-9]{1}(\.[0-9]+)?E{1}$/", $this->_formula{$index}) != 0) { + $value .= $this->_formula{$index}; + ++$index; + continue; + } + } + } + + // independent character evaluation (order not important) + + // establish state-dependent character evaluations + if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::QUOTE_DOUBLE) { + if (strlen($value > 0)) { // unexpected + $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_UNKNOWN); + $value = ""; + } + $inString = true; + ++$index; + continue; + } + + if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::QUOTE_SINGLE) { + if (strlen($value) > 0) { // unexpected + $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_UNKNOWN); + $value = ""; + } + $inPath = true; + ++$index; + continue; + } + + if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::BRACKET_OPEN) { + $inRange = true; + $value .= PHPExcel_Calculation_FormulaParser::BRACKET_OPEN; + ++$index; + continue; + } + + if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::ERROR_START) { + if (strlen($value) > 0) { // unexpected + $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_UNKNOWN); + $value = ""; + } + $inError = true; + $value .= PHPExcel_Calculation_FormulaParser::ERROR_START; + ++$index; + continue; + } + + // mark start and end of arrays and array rows + if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::BRACE_OPEN) { + if (strlen($value) > 0) { // unexpected + $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_UNKNOWN); + $value = ""; + } + + $tmp = new PHPExcel_Calculation_FormulaToken("ARRAY", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START); + $tokens1[] = $tmp; + $stack[] = clone $tmp; + + $tmp = new PHPExcel_Calculation_FormulaToken("ARRAYROW", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START); + $tokens1[] = $tmp; + $stack[] = clone $tmp; + + ++$index; + continue; + } + + if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::SEMICOLON) { + if (strlen($value) > 0) { + $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); + $value = ""; + } + + $tmp = array_pop($stack); + $tmp->setValue(""); + $tmp->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP); + $tokens1[] = $tmp; + + $tmp = new PHPExcel_Calculation_FormulaToken(",", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_ARGUMENT); + $tokens1[] = $tmp; + + $tmp = new PHPExcel_Calculation_FormulaToken("ARRAYROW", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START); + $tokens1[] = $tmp; + $stack[] = clone $tmp; + + ++$index; + continue; + } + + if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::BRACE_CLOSE) { + if (strlen($value) > 0) { + $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); + $value = ""; + } + + $tmp = array_pop($stack); + $tmp->setValue(""); + $tmp->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP); + $tokens1[] = $tmp; + + $tmp = array_pop($stack); + $tmp->setValue(""); + $tmp->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP); + $tokens1[] = $tmp; + + ++$index; + continue; + } + + // trim white-space + if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::WHITESPACE) { + if (strlen($value) > 0) { + $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); + $value = ""; + } + $tokens1[] = new PHPExcel_Calculation_FormulaToken("", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_WHITESPACE); + ++$index; + while (($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::WHITESPACE) && ($index < $formulaLength)) { + ++$index; + } + continue; + } + + // multi-character comparators + if (($index + 2) <= $formulaLength) { + if (in_array(substr($this->_formula, $index, 2), $COMPARATORS_MULTI)) { + if (strlen($value) > 0) { + $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); + $value = ""; + } + $tokens1[] = new PHPExcel_Calculation_FormulaToken(substr($this->_formula, $index, 2), PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_LOGICAL); + $index += 2; + continue; + } + } + + // standard infix operators + if (strpos(PHPExcel_Calculation_FormulaParser::OPERATORS_INFIX, $this->_formula{$index}) !== false) { + if (strlen($value) > 0) { + $tokens1[] =new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); + $value = ""; + } + $tokens1[] = new PHPExcel_Calculation_FormulaToken($this->_formula{$index}, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX); + ++$index; + continue; + } + + // standard postfix operators (only one) + if (strpos(PHPExcel_Calculation_FormulaParser::OPERATORS_POSTFIX, $this->_formula{$index}) !== false) { + if (strlen($value) > 0) { + $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); + $value = ""; + } + $tokens1[] = new PHPExcel_Calculation_FormulaToken($this->_formula{$index}, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORPOSTFIX); + ++$index; + continue; + } + + // start subexpression or function + if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::PAREN_OPEN) { + if (strlen($value) > 0) { + $tmp = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START); + $tokens1[] = $tmp; + $stack[] = clone $tmp; + $value = ""; + } else { + $tmp = new PHPExcel_Calculation_FormulaToken("", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_SUBEXPRESSION, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START); + $tokens1[] = $tmp; + $stack[] = clone $tmp; + } + ++$index; + continue; + } + + // function, subexpression, or array parameters, or operand unions + if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::COMMA) { + if (strlen($value) > 0) { + $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); + $value = ""; + } + + $tmp = array_pop($stack); + $tmp->setValue(""); + $tmp->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP); + $stack[] = $tmp; + + if ($tmp->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) { + $tokens1[] = new PHPExcel_Calculation_FormulaToken(",", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_UNION); + } else { + $tokens1[] = new PHPExcel_Calculation_FormulaToken(",", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_ARGUMENT); + } + ++$index; + continue; + } + + // stop subexpression + if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::PAREN_CLOSE) { + if (strlen($value) > 0) { + $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); + $value = ""; + } + + $tmp = array_pop($stack); + $tmp->setValue(""); + $tmp->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP); + $tokens1[] = $tmp; + + ++$index; + continue; + } + + // token accumulation + $value .= $this->_formula{$index}; + ++$index; + } + + // dump remaining accumulation + if (strlen($value) > 0) { + $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); + } + + // move tokenList to new set, excluding unnecessary white-space tokens and converting necessary ones to intersections + $tokenCount = count($tokens1); + for ($i = 0; $i < $tokenCount; ++$i) { + $token = $tokens1[$i]; + if (isset($tokens1[$i - 1])) { + $previousToken = $tokens1[$i - 1]; + } else { + $previousToken = null; + } + if (isset($tokens1[$i + 1])) { + $nextToken = $tokens1[$i + 1]; + } else { + $nextToken = null; + } + + if (is_null($token)) { + continue; + } + + if ($token->getTokenType() != PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_WHITESPACE) { + $tokens2[] = $token; + continue; + } + + if (is_null($previousToken)) { + continue; + } + + if (! ( + (($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) && ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) || + (($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_SUBEXPRESSION) && ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) || + ($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND) + ) ) { + continue; + } + + if (is_null($nextToken)) { + continue; + } + + if (! ( + (($nextToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) && ($nextToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START)) || + (($nextToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_SUBEXPRESSION) && ($nextToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START)) || + ($nextToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND) + ) ) { + continue; + } + + $tokens2[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_INTERSECTION); + } + + // move tokens to final list, switching infix "-" operators to prefix when appropriate, switching infix "+" operators + // to noop when appropriate, identifying operand and infix-operator subtypes, and pulling "@" from function names + $this->_tokens = array(); + + $tokenCount = count($tokens2); + for ($i = 0; $i < $tokenCount; ++$i) { + $token = $tokens2[$i]; + if (isset($tokens2[$i - 1])) { + $previousToken = $tokens2[$i - 1]; + } else { + $previousToken = null; + } + if (isset($tokens2[$i + 1])) { + $nextToken = $tokens2[$i + 1]; + } else { + $nextToken = null; + } + + if (is_null($token)) { + continue; + } + + if ($token->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX && $token->getValue() == "-") { + if ($i == 0) { + $token->setTokenType(PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORPREFIX); + } else if ( + (($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) && ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) || + (($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_SUBEXPRESSION) && ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) || + ($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORPOSTFIX) || + ($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND) + ) { + $token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_MATH); + } else { + $token->setTokenType(PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORPREFIX); + } + + $this->_tokens[] = $token; + continue; + } + + if ($token->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX && $token->getValue() == "+") { + if ($i == 0) { + continue; + } else if ( + (($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) && ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) || + (($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_SUBEXPRESSION) && ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) || + ($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORPOSTFIX) || + ($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND) + ) { + $token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_MATH); + } else { + continue; + } + + $this->_tokens[] = $token; + continue; + } + + if ($token->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX && $token->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_NOTHING) { + if (strpos("<>=", substr($token->getValue(), 0, 1)) !== false) { + $token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_LOGICAL); + } else if ($token->getValue() == "&") { + $token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_CONCATENATION); + } else { + $token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_MATH); + } + + $this->_tokens[] = $token; + continue; + } + + if ($token->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND && $token->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_NOTHING) { + if (!is_numeric($token->getValue())) { + if (strtoupper($token->getValue()) == "TRUE" || strtoupper($token->getValue() == "FALSE")) { + $token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_LOGICAL); + } else { + $token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_RANGE); + } + } else { + $token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_NUMBER); + } + + $this->_tokens[] = $token; + continue; + } + + if ($token->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) { + if (strlen($token->getValue() > 0)) { + if (substr($token->getValue(), 0, 1) == "@") { + $token->setValue(substr($token->getValue(), 1)); + } + } + } + + $this->_tokens[] = $token; + } + } +} diff --git a/lib/phpexcel/PHPExcel/Calculation/FormulaToken.php b/lib/phpexcel/PHPExcel/Calculation/FormulaToken.php new file mode 100644 index 0000000..fd5e2e5 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Calculation/FormulaToken.php @@ -0,0 +1,176 @@ +_value = $pValue; + $this->_tokenType = $pTokenType; + $this->_tokenSubType = $pTokenSubType; + } + + /** + * Get Value + * + * @return string + */ + public function getValue() { + return $this->_value; + } + + /** + * Set Value + * + * @param string $value + */ + public function setValue($value) { + $this->_value = $value; + } + + /** + * Get Token Type (represented by TOKEN_TYPE_*) + * + * @return string + */ + public function getTokenType() { + return $this->_tokenType; + } + + /** + * Set Token Type + * + * @param string $value + */ + public function setTokenType($value = PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_UNKNOWN) { + $this->_tokenType = $value; + } + + /** + * Get Token SubType (represented by TOKEN_SUBTYPE_*) + * + * @return string + */ + public function getTokenSubType() { + return $this->_tokenSubType; + } + + /** + * Set Token SubType + * + * @param string $value + */ + public function setTokenSubType($value = PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_NOTHING) { + $this->_tokenSubType = $value; + } +} diff --git a/lib/phpexcel/PHPExcel/Calculation/Function.php b/lib/phpexcel/PHPExcel/Calculation/Function.php new file mode 100644 index 0000000..7299834 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Calculation/Function.php @@ -0,0 +1,149 @@ +_category = $pCategory; + $this->_excelName = $pExcelName; + $this->_phpExcelName = $pPHPExcelName; + } else { + throw new PHPExcel_Calculation_Exception("Invalid parameters passed."); + } + } + + /** + * Get Category (represented by CATEGORY_*) + * + * @return string + */ + public function getCategory() { + return $this->_category; + } + + /** + * Set Category (represented by CATEGORY_*) + * + * @param string $value + * @throws PHPExcel_Calculation_Exception + */ + public function setCategory($value = null) { + if (!is_null($value)) { + $this->_category = $value; + } else { + throw new PHPExcel_Calculation_Exception("Invalid parameter passed."); + } + } + + /** + * Get Excel name + * + * @return string + */ + public function getExcelName() { + return $this->_excelName; + } + + /** + * Set Excel name + * + * @param string $value + */ + public function setExcelName($value) { + $this->_excelName = $value; + } + + /** + * Get PHPExcel name + * + * @return string + */ + public function getPHPExcelName() { + return $this->_phpExcelName; + } + + /** + * Set PHPExcel name + * + * @param string $value + */ + public function setPHPExcelName($value) { + $this->_phpExcelName = $value; + } +} diff --git a/lib/phpexcel/PHPExcel/Calculation/Functions.php b/lib/phpexcel/PHPExcel/Calculation/Functions.php new file mode 100644 index 0000000..71bfa19 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Calculation/Functions.php @@ -0,0 +1,726 @@ + '#NULL!', + 'divisionbyzero' => '#DIV/0!', + 'value' => '#VALUE!', + 'reference' => '#REF!', + 'name' => '#NAME?', + 'num' => '#NUM!', + 'na' => '#N/A', + 'gettingdata' => '#GETTING_DATA' + ); + + + /** + * Set the Compatibility Mode + * + * @access public + * @category Function Configuration + * @param string $compatibilityMode Compatibility Mode + * Permitted values are: + * PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL 'Excel' + * PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC 'Gnumeric' + * PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE 'OpenOfficeCalc' + * @return boolean (Success or Failure) + */ + public static function setCompatibilityMode($compatibilityMode) { + if (($compatibilityMode == self::COMPATIBILITY_EXCEL) || + ($compatibilityMode == self::COMPATIBILITY_GNUMERIC) || + ($compatibilityMode == self::COMPATIBILITY_OPENOFFICE)) { + self::$compatibilityMode = $compatibilityMode; + return True; + } + return False; + } // function setCompatibilityMode() + + + /** + * Return the current Compatibility Mode + * + * @access public + * @category Function Configuration + * @return string Compatibility Mode + * Possible Return values are: + * PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL 'Excel' + * PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC 'Gnumeric' + * PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE 'OpenOfficeCalc' + */ + public static function getCompatibilityMode() { + return self::$compatibilityMode; + } // function getCompatibilityMode() + + + /** + * Set the Return Date Format used by functions that return a date/time (Excel, PHP Serialized Numeric or PHP Object) + * + * @access public + * @category Function Configuration + * @param string $returnDateType Return Date Format + * Permitted values are: + * PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC 'P' + * PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT 'O' + * PHPExcel_Calculation_Functions::RETURNDATE_EXCEL 'E' + * @return boolean Success or failure + */ + public static function setReturnDateType($returnDateType) { + if (($returnDateType == self::RETURNDATE_PHP_NUMERIC) || + ($returnDateType == self::RETURNDATE_PHP_OBJECT) || + ($returnDateType == self::RETURNDATE_EXCEL)) { + self::$ReturnDateType = $returnDateType; + return True; + } + return False; + } // function setReturnDateType() + + + /** + * Return the current Return Date Format for functions that return a date/time (Excel, PHP Serialized Numeric or PHP Object) + * + * @access public + * @category Function Configuration + * @return string Return Date Format + * Possible Return values are: + * PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC 'P' + * PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT 'O' + * PHPExcel_Calculation_Functions::RETURNDATE_EXCEL 'E' + */ + public static function getReturnDateType() { + return self::$ReturnDateType; + } // function getReturnDateType() + + + /** + * DUMMY + * + * @access public + * @category Error Returns + * @return string #Not Yet Implemented + */ + public static function DUMMY() { + return '#Not Yet Implemented'; + } // function DUMMY() + + + /** + * DIV0 + * + * @access public + * @category Error Returns + * @return string #Not Yet Implemented + */ + public static function DIV0() { + return self::$_errorCodes['divisionbyzero']; + } // function DIV0() + + + /** + * NA + * + * Excel Function: + * =NA() + * + * Returns the error value #N/A + * #N/A is the error value that means "no value is available." + * + * @access public + * @category Logical Functions + * @return string #N/A! + */ + public static function NA() { + return self::$_errorCodes['na']; + } // function NA() + + + /** + * NaN + * + * Returns the error value #NUM! + * + * @access public + * @category Error Returns + * @return string #NUM! + */ + public static function NaN() { + return self::$_errorCodes['num']; + } // function NaN() + + + /** + * NAME + * + * Returns the error value #NAME? + * + * @access public + * @category Error Returns + * @return string #NAME? + */ + public static function NAME() { + return self::$_errorCodes['name']; + } // function NAME() + + + /** + * REF + * + * Returns the error value #REF! + * + * @access public + * @category Error Returns + * @return string #REF! + */ + public static function REF() { + return self::$_errorCodes['reference']; + } // function REF() + + + /** + * NULL + * + * Returns the error value #NULL! + * + * @access public + * @category Error Returns + * @return string #NULL! + */ + public static function NULL() { + return self::$_errorCodes['null']; + } // function NULL() + + + /** + * VALUE + * + * Returns the error value #VALUE! + * + * @access public + * @category Error Returns + * @return string #VALUE! + */ + public static function VALUE() { + return self::$_errorCodes['value']; + } // function VALUE() + + + public static function isMatrixValue($idx) { + return ((substr_count($idx,'.') <= 1) || (preg_match('/\.[A-Z]/',$idx) > 0)); + } + + + public static function isValue($idx) { + return (substr_count($idx,'.') == 0); + } + + + public static function isCellValue($idx) { + return (substr_count($idx,'.') > 1); + } + + + public static function _ifCondition($condition) { + $condition = PHPExcel_Calculation_Functions::flattenSingleValue($condition); + if (!isset($condition{0})) + $condition = '=""'; + if (!in_array($condition{0},array('>', '<', '='))) { + if (!is_numeric($condition)) { $condition = PHPExcel_Calculation::_wrapResult(strtoupper($condition)); } + return '='.$condition; + } else { + preg_match('/([<>=]+)(.*)/',$condition,$matches); + list(,$operator,$operand) = $matches; + + if (!is_numeric($operand)) { + $operand = str_replace('"', '""', $operand); + $operand = PHPExcel_Calculation::_wrapResult(strtoupper($operand)); + } + + return $operator.$operand; + } + } // function _ifCondition() + + + /** + * ERROR_TYPE + * + * @param mixed $value Value to check + * @return boolean + */ + public static function ERROR_TYPE($value = '') { + $value = self::flattenSingleValue($value); + + $i = 1; + foreach(self::$_errorCodes as $errorCode) { + if ($value === $errorCode) { + return $i; + } + ++$i; + } + return self::NA(); + } // function ERROR_TYPE() + + + /** + * IS_BLANK + * + * @param mixed $value Value to check + * @return boolean + */ + public static function IS_BLANK($value = NULL) { + if (!is_null($value)) { + $value = self::flattenSingleValue($value); + } + + return is_null($value); + } // function IS_BLANK() + + + /** + * IS_ERR + * + * @param mixed $value Value to check + * @return boolean + */ + public static function IS_ERR($value = '') { + $value = self::flattenSingleValue($value); + + return self::IS_ERROR($value) && (!self::IS_NA($value)); + } // function IS_ERR() + + + /** + * IS_ERROR + * + * @param mixed $value Value to check + * @return boolean + */ + public static function IS_ERROR($value = '') { + $value = self::flattenSingleValue($value); + + if (!is_string($value)) + return false; + return in_array($value, array_values(self::$_errorCodes)); + } // function IS_ERROR() + + + /** + * IS_NA + * + * @param mixed $value Value to check + * @return boolean + */ + public static function IS_NA($value = '') { + $value = self::flattenSingleValue($value); + + return ($value === self::NA()); + } // function IS_NA() + + + /** + * IS_EVEN + * + * @param mixed $value Value to check + * @return boolean + */ + public static function IS_EVEN($value = NULL) { + $value = self::flattenSingleValue($value); + + if ($value === NULL) + return self::NAME(); + if ((is_bool($value)) || ((is_string($value)) && (!is_numeric($value)))) + return self::VALUE(); + return ($value % 2 == 0); + } // function IS_EVEN() + + + /** + * IS_ODD + * + * @param mixed $value Value to check + * @return boolean + */ + public static function IS_ODD($value = NULL) { + $value = self::flattenSingleValue($value); + + if ($value === NULL) + return self::NAME(); + if ((is_bool($value)) || ((is_string($value)) && (!is_numeric($value)))) + return self::VALUE(); + return (abs($value) % 2 == 1); + } // function IS_ODD() + + + /** + * IS_NUMBER + * + * @param mixed $value Value to check + * @return boolean + */ + public static function IS_NUMBER($value = NULL) { + $value = self::flattenSingleValue($value); + + if (is_string($value)) { + return False; + } + return is_numeric($value); + } // function IS_NUMBER() + + + /** + * IS_LOGICAL + * + * @param mixed $value Value to check + * @return boolean + */ + public static function IS_LOGICAL($value = NULL) { + $value = self::flattenSingleValue($value); + + return is_bool($value); + } // function IS_LOGICAL() + + + /** + * IS_TEXT + * + * @param mixed $value Value to check + * @return boolean + */ + public static function IS_TEXT($value = NULL) { + $value = self::flattenSingleValue($value); + + return (is_string($value) && !self::IS_ERROR($value)); + } // function IS_TEXT() + + + /** + * IS_NONTEXT + * + * @param mixed $value Value to check + * @return boolean + */ + public static function IS_NONTEXT($value = NULL) { + return !self::IS_TEXT($value); + } // function IS_NONTEXT() + + + /** + * VERSION + * + * @return string Version information + */ + public static function VERSION() { + return 'PHPExcel 1.8.0, 2014-03-02'; + } // function VERSION() + + + /** + * N + * + * Returns a value converted to a number + * + * @param value The value you want converted + * @return number N converts values listed in the following table + * If value is or refers to N returns + * A number That number + * A date The serial number of that date + * TRUE 1 + * FALSE 0 + * An error value The error value + * Anything else 0 + */ + public static function N($value = NULL) { + while (is_array($value)) { + $value = array_shift($value); + } + + switch (gettype($value)) { + case 'double' : + case 'float' : + case 'integer' : + return $value; + break; + case 'boolean' : + return (integer) $value; + break; + case 'string' : + // Errors + if ((strlen($value) > 0) && ($value{0} == '#')) { + return $value; + } + break; + } + return 0; + } // function N() + + + /** + * TYPE + * + * Returns a number that identifies the type of a value + * + * @param value The value you want tested + * @return number N converts values listed in the following table + * If value is or refers to N returns + * A number 1 + * Text 2 + * Logical Value 4 + * An error value 16 + * Array or Matrix 64 + */ + public static function TYPE($value = NULL) { + $value = self::flattenArrayIndexed($value); + if (is_array($value) && (count($value) > 1)) { + $a = array_keys($value); + $a = array_pop($a); + // Range of cells is an error + if (self::isCellValue($a)) { + return 16; + // Test for Matrix + } elseif (self::isMatrixValue($a)) { + return 64; + } + } elseif(empty($value)) { + // Empty Cell + return 1; + } + $value = self::flattenSingleValue($value); + + if (($value === NULL) || (is_float($value)) || (is_int($value))) { + return 1; + } elseif(is_bool($value)) { + return 4; + } elseif(is_array($value)) { + return 64; + break; + } elseif(is_string($value)) { + // Errors + if ((strlen($value) > 0) && ($value{0} == '#')) { + return 16; + } + return 2; + } + return 0; + } // function TYPE() + + + /** + * Convert a multi-dimensional array to a simple 1-dimensional array + * + * @param array $array Array to be flattened + * @return array Flattened array + */ + public static function flattenArray($array) { + if (!is_array($array)) { + return (array) $array; + } + + $arrayValues = array(); + foreach ($array as $value) { + if (is_array($value)) { + foreach ($value as $val) { + if (is_array($val)) { + foreach ($val as $v) { + $arrayValues[] = $v; + } + } else { + $arrayValues[] = $val; + } + } + } else { + $arrayValues[] = $value; + } + } + + return $arrayValues; + } // function flattenArray() + + + /** + * Convert a multi-dimensional array to a simple 1-dimensional array, but retain an element of indexing + * + * @param array $array Array to be flattened + * @return array Flattened array + */ + public static function flattenArrayIndexed($array) { + if (!is_array($array)) { + return (array) $array; + } + + $arrayValues = array(); + foreach ($array as $k1 => $value) { + if (is_array($value)) { + foreach ($value as $k2 => $val) { + if (is_array($val)) { + foreach ($val as $k3 => $v) { + $arrayValues[$k1.'.'.$k2.'.'.$k3] = $v; + } + } else { + $arrayValues[$k1.'.'.$k2] = $val; + } + } + } else { + $arrayValues[$k1] = $value; + } + } + + return $arrayValues; + } // function flattenArrayIndexed() + + + /** + * Convert an array to a single scalar value by extracting the first element + * + * @param mixed $value Array or scalar value + * @return mixed + */ + public static function flattenSingleValue($value = '') { + while (is_array($value)) { + $value = array_pop($value); + } + + return $value; + } // function flattenSingleValue() + +} // class PHPExcel_Calculation_Functions + + +// +// There are a few mathematical functions that aren't available on all versions of PHP for all platforms +// These functions aren't available in Windows implementations of PHP prior to version 5.3.0 +// So we test if they do exist for this version of PHP/operating platform; and if not we create them +// +if (!function_exists('acosh')) { + function acosh($x) { + return 2 * log(sqrt(($x + 1) / 2) + sqrt(($x - 1) / 2)); + } // function acosh() +} + +if (!function_exists('asinh')) { + function asinh($x) { + return log($x + sqrt(1 + $x * $x)); + } // function asinh() +} + +if (!function_exists('atanh')) { + function atanh($x) { + return (log(1 + $x) - log(1 - $x)) / 2; + } // function atanh() +} + + +// +// Strangely, PHP doesn't have a mb_str_replace multibyte function +// As we'll only ever use this function with UTF-8 characters, we can simply "hard-code" the character set +// +if ((!function_exists('mb_str_replace')) && + (function_exists('mb_substr')) && (function_exists('mb_strlen')) && (function_exists('mb_strpos'))) { + function mb_str_replace($search, $replace, $subject) { + if(is_array($subject)) { + $ret = array(); + foreach($subject as $key => $val) { + $ret[$key] = mb_str_replace($search, $replace, $val); + } + return $ret; + } + + foreach((array) $search as $key => $s) { + if($s == '') { + continue; + } + $r = !is_array($replace) ? $replace : (array_key_exists($key, $replace) ? $replace[$key] : ''); + $pos = mb_strpos($subject, $s, 0, 'UTF-8'); + while($pos !== false) { + $subject = mb_substr($subject, 0, $pos, 'UTF-8') . $r . mb_substr($subject, $pos + mb_strlen($s, 'UTF-8'), 65535, 'UTF-8'); + $pos = mb_strpos($subject, $s, $pos + mb_strlen($r, 'UTF-8'), 'UTF-8'); + } + } + return $subject; + } +} diff --git a/lib/phpexcel/PHPExcel/Calculation/Logical.php b/lib/phpexcel/PHPExcel/Calculation/Logical.php new file mode 100644 index 0000000..bb206a1 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Calculation/Logical.php @@ -0,0 +1,288 @@ + $arg) { + // Is it a boolean value? + if (is_bool($arg)) { + $returnValue = $returnValue && $arg; + } elseif ((is_numeric($arg)) && (!is_string($arg))) { + $returnValue = $returnValue && ($arg != 0); + } elseif (is_string($arg)) { + $arg = strtoupper($arg); + if (($arg == 'TRUE') || ($arg == PHPExcel_Calculation::getTRUE())) { + $arg = TRUE; + } elseif (($arg == 'FALSE') || ($arg == PHPExcel_Calculation::getFALSE())) { + $arg = FALSE; + } else { + return PHPExcel_Calculation_Functions::VALUE(); + } + $returnValue = $returnValue && ($arg != 0); + } + } + + // Return + if ($argCount < 0) { + return PHPExcel_Calculation_Functions::VALUE(); + } + return $returnValue; + } // function LOGICAL_AND() + + + /** + * LOGICAL_OR + * + * Returns boolean TRUE if any argument is TRUE; returns FALSE if all arguments are FALSE. + * + * Excel Function: + * =OR(logical1[,logical2[, ...]]) + * + * The arguments must evaluate to logical values such as TRUE or FALSE, or the arguments must be arrays + * or references that contain logical values. + * + * Boolean arguments are treated as True or False as appropriate + * Integer or floating point arguments are treated as True, except for 0 or 0.0 which are False + * If any argument value is a string, or a Null, the function returns a #VALUE! error, unless the string holds + * the value TRUE or FALSE, in which case it is evaluated as the corresponding boolean value + * + * @access public + * @category Logical Functions + * @param mixed $arg,... Data values + * @return boolean The logical OR of the arguments. + */ + public static function LOGICAL_OR() { + // Return value + $returnValue = FALSE; + + // Loop through the arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + $argCount = -1; + foreach ($aArgs as $argCount => $arg) { + // Is it a boolean value? + if (is_bool($arg)) { + $returnValue = $returnValue || $arg; + } elseif ((is_numeric($arg)) && (!is_string($arg))) { + $returnValue = $returnValue || ($arg != 0); + } elseif (is_string($arg)) { + $arg = strtoupper($arg); + if (($arg == 'TRUE') || ($arg == PHPExcel_Calculation::getTRUE())) { + $arg = TRUE; + } elseif (($arg == 'FALSE') || ($arg == PHPExcel_Calculation::getFALSE())) { + $arg = FALSE; + } else { + return PHPExcel_Calculation_Functions::VALUE(); + } + $returnValue = $returnValue || ($arg != 0); + } + } + + // Return + if ($argCount < 0) { + return PHPExcel_Calculation_Functions::VALUE(); + } + return $returnValue; + } // function LOGICAL_OR() + + + /** + * NOT + * + * Returns the boolean inverse of the argument. + * + * Excel Function: + * =NOT(logical) + * + * The argument must evaluate to a logical value such as TRUE or FALSE + * + * Boolean arguments are treated as True or False as appropriate + * Integer or floating point arguments are treated as True, except for 0 or 0.0 which are False + * If any argument value is a string, or a Null, the function returns a #VALUE! error, unless the string holds + * the value TRUE or FALSE, in which case it is evaluated as the corresponding boolean value + * + * @access public + * @category Logical Functions + * @param mixed $logical A value or expression that can be evaluated to TRUE or FALSE + * @return boolean The boolean inverse of the argument. + */ + public static function NOT($logical=FALSE) { + $logical = PHPExcel_Calculation_Functions::flattenSingleValue($logical); + if (is_string($logical)) { + $logical = strtoupper($logical); + if (($logical == 'TRUE') || ($logical == PHPExcel_Calculation::getTRUE())) { + return FALSE; + } elseif (($logical == 'FALSE') || ($logical == PHPExcel_Calculation::getFALSE())) { + return TRUE; + } else { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + + return !$logical; + } // function NOT() + + /** + * STATEMENT_IF + * + * Returns one value if a condition you specify evaluates to TRUE and another value if it evaluates to FALSE. + * + * Excel Function: + * =IF(condition[,returnIfTrue[,returnIfFalse]]) + * + * Condition is any value or expression that can be evaluated to TRUE or FALSE. + * For example, A10=100 is a logical expression; if the value in cell A10 is equal to 100, + * the expression evaluates to TRUE. Otherwise, the expression evaluates to FALSE. + * This argument can use any comparison calculation operator. + * ReturnIfTrue is the value that is returned if condition evaluates to TRUE. + * For example, if this argument is the text string "Within budget" and the condition argument evaluates to TRUE, + * then the IF function returns the text "Within budget" + * If condition is TRUE and ReturnIfTrue is blank, this argument returns 0 (zero). To display the word TRUE, use + * the logical value TRUE for this argument. + * ReturnIfTrue can be another formula. + * ReturnIfFalse is the value that is returned if condition evaluates to FALSE. + * For example, if this argument is the text string "Over budget" and the condition argument evaluates to FALSE, + * then the IF function returns the text "Over budget". + * If condition is FALSE and ReturnIfFalse is omitted, then the logical value FALSE is returned. + * If condition is FALSE and ReturnIfFalse is blank, then the value 0 (zero) is returned. + * ReturnIfFalse can be another formula. + * + * @access public + * @category Logical Functions + * @param mixed $condition Condition to evaluate + * @param mixed $returnIfTrue Value to return when condition is true + * @param mixed $returnIfFalse Optional value to return when condition is false + * @return mixed The value of returnIfTrue or returnIfFalse determined by condition + */ + public static function STATEMENT_IF($condition = TRUE, $returnIfTrue = 0, $returnIfFalse = FALSE) { + $condition = (is_null($condition)) ? TRUE : (boolean) PHPExcel_Calculation_Functions::flattenSingleValue($condition); + $returnIfTrue = (is_null($returnIfTrue)) ? 0 : PHPExcel_Calculation_Functions::flattenSingleValue($returnIfTrue); + $returnIfFalse = (is_null($returnIfFalse)) ? FALSE : PHPExcel_Calculation_Functions::flattenSingleValue($returnIfFalse); + + return ($condition) ? $returnIfTrue : $returnIfFalse; + } // function STATEMENT_IF() + + + /** + * IFERROR + * + * Excel Function: + * =IFERROR(testValue,errorpart) + * + * @access public + * @category Logical Functions + * @param mixed $testValue Value to check, is also the value returned when no error + * @param mixed $errorpart Value to return when testValue is an error condition + * @return mixed The value of errorpart or testValue determined by error condition + */ + public static function IFERROR($testValue = '', $errorpart = '') { + $testValue = (is_null($testValue)) ? '' : PHPExcel_Calculation_Functions::flattenSingleValue($testValue); + $errorpart = (is_null($errorpart)) ? '' : PHPExcel_Calculation_Functions::flattenSingleValue($errorpart); + + return self::STATEMENT_IF(PHPExcel_Calculation_Functions::IS_ERROR($testValue), $errorpart, $testValue); + } // function IFERROR() + +} // class PHPExcel_Calculation_Logical diff --git a/lib/phpexcel/PHPExcel/Calculation/LookupRef.php b/lib/phpexcel/PHPExcel/Calculation/LookupRef.php new file mode 100644 index 0000000..e1285d9 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Calculation/LookupRef.php @@ -0,0 +1,881 @@ + '') { + if (strpos($sheetText,' ') !== False) { $sheetText = "'".$sheetText."'"; } + $sheetText .='!'; + } + if ((!is_bool($referenceStyle)) || $referenceStyle) { + $rowRelative = $columnRelative = '$'; + $column = PHPExcel_Cell::stringFromColumnIndex($column-1); + if (($relativity == 2) || ($relativity == 4)) { $columnRelative = ''; } + if (($relativity == 3) || ($relativity == 4)) { $rowRelative = ''; } + return $sheetText.$columnRelative.$column.$rowRelative.$row; + } else { + if (($relativity == 2) || ($relativity == 4)) { $column = '['.$column.']'; } + if (($relativity == 3) || ($relativity == 4)) { $row = '['.$row.']'; } + return $sheetText.'R'.$row.'C'.$column; + } + } // function CELL_ADDRESS() + + + /** + * COLUMN + * + * Returns the column number of the given cell reference + * If the cell reference is a range of cells, COLUMN returns the column numbers of each column in the reference as a horizontal array. + * If cell reference is omitted, and the function is being called through the calculation engine, then it is assumed to be the + * reference of the cell in which the COLUMN function appears; otherwise this function returns 0. + * + * Excel Function: + * =COLUMN([cellAddress]) + * + * @param cellAddress A reference to a range of cells for which you want the column numbers + * @return integer or array of integer + */ + public static function COLUMN($cellAddress=Null) { + if (is_null($cellAddress) || trim($cellAddress) === '') { return 0; } + + if (is_array($cellAddress)) { + foreach($cellAddress as $columnKey => $value) { + $columnKey = preg_replace('/[^a-z]/i','',$columnKey); + return (integer) PHPExcel_Cell::columnIndexFromString($columnKey); + } + } else { + if (strpos($cellAddress,'!') !== false) { + list($sheet,$cellAddress) = explode('!',$cellAddress); + } + if (strpos($cellAddress,':') !== false) { + list($startAddress,$endAddress) = explode(':',$cellAddress); + $startAddress = preg_replace('/[^a-z]/i','',$startAddress); + $endAddress = preg_replace('/[^a-z]/i','',$endAddress); + $returnValue = array(); + do { + $returnValue[] = (integer) PHPExcel_Cell::columnIndexFromString($startAddress); + } while ($startAddress++ != $endAddress); + return $returnValue; + } else { + $cellAddress = preg_replace('/[^a-z]/i','',$cellAddress); + return (integer) PHPExcel_Cell::columnIndexFromString($cellAddress); + } + } + } // function COLUMN() + + + /** + * COLUMNS + * + * Returns the number of columns in an array or reference. + * + * Excel Function: + * =COLUMNS(cellAddress) + * + * @param cellAddress An array or array formula, or a reference to a range of cells for which you want the number of columns + * @return integer The number of columns in cellAddress + */ + public static function COLUMNS($cellAddress=Null) { + if (is_null($cellAddress) || $cellAddress === '') { + return 1; + } elseif (!is_array($cellAddress)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + $x = array_keys($cellAddress); + $x = array_shift($x); + $isMatrix = (is_numeric($x)); + list($columns,$rows) = PHPExcel_Calculation::_getMatrixDimensions($cellAddress); + + if ($isMatrix) { + return $rows; + } else { + return $columns; + } + } // function COLUMNS() + + + /** + * ROW + * + * Returns the row number of the given cell reference + * If the cell reference is a range of cells, ROW returns the row numbers of each row in the reference as a vertical array. + * If cell reference is omitted, and the function is being called through the calculation engine, then it is assumed to be the + * reference of the cell in which the ROW function appears; otherwise this function returns 0. + * + * Excel Function: + * =ROW([cellAddress]) + * + * @param cellAddress A reference to a range of cells for which you want the row numbers + * @return integer or array of integer + */ + public static function ROW($cellAddress=Null) { + if (is_null($cellAddress) || trim($cellAddress) === '') { return 0; } + + if (is_array($cellAddress)) { + foreach($cellAddress as $columnKey => $rowValue) { + foreach($rowValue as $rowKey => $cellValue) { + return (integer) preg_replace('/[^0-9]/i','',$rowKey); + } + } + } else { + if (strpos($cellAddress,'!') !== false) { + list($sheet,$cellAddress) = explode('!',$cellAddress); + } + if (strpos($cellAddress,':') !== false) { + list($startAddress,$endAddress) = explode(':',$cellAddress); + $startAddress = preg_replace('/[^0-9]/','',$startAddress); + $endAddress = preg_replace('/[^0-9]/','',$endAddress); + $returnValue = array(); + do { + $returnValue[][] = (integer) $startAddress; + } while ($startAddress++ != $endAddress); + return $returnValue; + } else { + list($cellAddress) = explode(':',$cellAddress); + return (integer) preg_replace('/[^0-9]/','',$cellAddress); + } + } + } // function ROW() + + + /** + * ROWS + * + * Returns the number of rows in an array or reference. + * + * Excel Function: + * =ROWS(cellAddress) + * + * @param cellAddress An array or array formula, or a reference to a range of cells for which you want the number of rows + * @return integer The number of rows in cellAddress + */ + public static function ROWS($cellAddress=Null) { + if (is_null($cellAddress) || $cellAddress === '') { + return 1; + } elseif (!is_array($cellAddress)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + $i = array_keys($cellAddress); + $isMatrix = (is_numeric(array_shift($i))); + list($columns,$rows) = PHPExcel_Calculation::_getMatrixDimensions($cellAddress); + + if ($isMatrix) { + return $columns; + } else { + return $rows; + } + } // function ROWS() + + + /** + * HYPERLINK + * + * Excel Function: + * =HYPERLINK(linkURL,displayName) + * + * @access public + * @category Logical Functions + * @param string $linkURL Value to check, is also the value returned when no error + * @param string $displayName Value to return when testValue is an error condition + * @param PHPExcel_Cell $pCell The cell to set the hyperlink in + * @return mixed The value of $displayName (or $linkURL if $displayName was blank) + */ + public static function HYPERLINK($linkURL = '', $displayName = null, PHPExcel_Cell $pCell = null) { + $args = func_get_args(); + $pCell = array_pop($args); + + $linkURL = (is_null($linkURL)) ? '' : PHPExcel_Calculation_Functions::flattenSingleValue($linkURL); + $displayName = (is_null($displayName)) ? '' : PHPExcel_Calculation_Functions::flattenSingleValue($displayName); + + if ((!is_object($pCell)) || (trim($linkURL) == '')) { + return PHPExcel_Calculation_Functions::REF(); + } + + if ((is_object($displayName)) || trim($displayName) == '') { + $displayName = $linkURL; + } + + $pCell->getHyperlink()->setUrl($linkURL); + + return $displayName; + } // function HYPERLINK() + + + /** + * INDIRECT + * + * Returns the reference specified by a text string. + * References are immediately evaluated to display their contents. + * + * Excel Function: + * =INDIRECT(cellAddress) + * + * NOTE - INDIRECT() does not yet support the optional a1 parameter introduced in Excel 2010 + * + * @param cellAddress $cellAddress The cell address of the current cell (containing this formula) + * @param PHPExcel_Cell $pCell The current cell (containing this formula) + * @return mixed The cells referenced by cellAddress + * + * @todo Support for the optional a1 parameter introduced in Excel 2010 + * + */ + public static function INDIRECT($cellAddress = NULL, PHPExcel_Cell $pCell = NULL) { + $cellAddress = PHPExcel_Calculation_Functions::flattenSingleValue($cellAddress); + if (is_null($cellAddress) || $cellAddress === '') { + return PHPExcel_Calculation_Functions::REF(); + } + + $cellAddress1 = $cellAddress; + $cellAddress2 = NULL; + if (strpos($cellAddress,':') !== false) { + list($cellAddress1,$cellAddress2) = explode(':',$cellAddress); + } + + if ((!preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_CELLREF.'$/i', $cellAddress1, $matches)) || + ((!is_null($cellAddress2)) && (!preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_CELLREF.'$/i', $cellAddress2, $matches)))) { + if (!preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_NAMEDRANGE.'$/i', $cellAddress1, $matches)) { + return PHPExcel_Calculation_Functions::REF(); + } + + if (strpos($cellAddress,'!') !== FALSE) { + list($sheetName, $cellAddress) = explode('!',$cellAddress); + $sheetName = trim($sheetName, "'"); + $pSheet = $pCell->getWorksheet()->getParent()->getSheetByName($sheetName); + } else { + $pSheet = $pCell->getWorksheet(); + } + + return PHPExcel_Calculation::getInstance()->extractNamedRange($cellAddress, $pSheet, FALSE); + } + + if (strpos($cellAddress,'!') !== FALSE) { + list($sheetName,$cellAddress) = explode('!',$cellAddress); + $sheetName = trim($sheetName, "'"); + $pSheet = $pCell->getWorksheet()->getParent()->getSheetByName($sheetName); + } else { + $pSheet = $pCell->getWorksheet(); + } + + return PHPExcel_Calculation::getInstance()->extractCellRange($cellAddress, $pSheet, FALSE); + } // function INDIRECT() + + + /** + * OFFSET + * + * Returns a reference to a range that is a specified number of rows and columns from a cell or range of cells. + * The reference that is returned can be a single cell or a range of cells. You can specify the number of rows and + * the number of columns to be returned. + * + * Excel Function: + * =OFFSET(cellAddress, rows, cols, [height], [width]) + * + * @param cellAddress The reference from which you want to base the offset. Reference must refer to a cell or + * range of adjacent cells; otherwise, OFFSET returns the #VALUE! error value. + * @param rows The number of rows, up or down, that you want the upper-left cell to refer to. + * Using 5 as the rows argument specifies that the upper-left cell in the reference is + * five rows below reference. Rows can be positive (which means below the starting reference) + * or negative (which means above the starting reference). + * @param cols The number of columns, to the left or right, that you want the upper-left cell of the result + * to refer to. Using 5 as the cols argument specifies that the upper-left cell in the + * reference is five columns to the right of reference. Cols can be positive (which means + * to the right of the starting reference) or negative (which means to the left of the + * starting reference). + * @param height The height, in number of rows, that you want the returned reference to be. Height must be a positive number. + * @param width The width, in number of columns, that you want the returned reference to be. Width must be a positive number. + * @return string A reference to a cell or range of cells + */ + public static function OFFSET($cellAddress=Null,$rows=0,$columns=0,$height=null,$width=null) { + $rows = PHPExcel_Calculation_Functions::flattenSingleValue($rows); + $columns = PHPExcel_Calculation_Functions::flattenSingleValue($columns); + $height = PHPExcel_Calculation_Functions::flattenSingleValue($height); + $width = PHPExcel_Calculation_Functions::flattenSingleValue($width); + if ($cellAddress == Null) { + return 0; + } + + $args = func_get_args(); + $pCell = array_pop($args); + if (!is_object($pCell)) { + return PHPExcel_Calculation_Functions::REF(); + } + + $sheetName = NULL; + if (strpos($cellAddress,"!")) { + list($sheetName,$cellAddress) = explode("!",$cellAddress); + $sheetName = trim($sheetName, "'"); + } + if (strpos($cellAddress,":")) { + list($startCell,$endCell) = explode(":",$cellAddress); + } else { + $startCell = $endCell = $cellAddress; + } + list($startCellColumn,$startCellRow) = PHPExcel_Cell::coordinateFromString($startCell); + list($endCellColumn,$endCellRow) = PHPExcel_Cell::coordinateFromString($endCell); + + $startCellRow += $rows; + $startCellColumn = PHPExcel_Cell::columnIndexFromString($startCellColumn) - 1; + $startCellColumn += $columns; + + if (($startCellRow <= 0) || ($startCellColumn < 0)) { + return PHPExcel_Calculation_Functions::REF(); + } + $endCellColumn = PHPExcel_Cell::columnIndexFromString($endCellColumn) - 1; + if (($width != null) && (!is_object($width))) { + $endCellColumn = $startCellColumn + $width - 1; + } else { + $endCellColumn += $columns; + } + $startCellColumn = PHPExcel_Cell::stringFromColumnIndex($startCellColumn); + + if (($height != null) && (!is_object($height))) { + $endCellRow = $startCellRow + $height - 1; + } else { + $endCellRow += $rows; + } + + if (($endCellRow <= 0) || ($endCellColumn < 0)) { + return PHPExcel_Calculation_Functions::REF(); + } + $endCellColumn = PHPExcel_Cell::stringFromColumnIndex($endCellColumn); + + $cellAddress = $startCellColumn.$startCellRow; + if (($startCellColumn != $endCellColumn) || ($startCellRow != $endCellRow)) { + $cellAddress .= ':'.$endCellColumn.$endCellRow; + } + + if ($sheetName !== NULL) { + $pSheet = $pCell->getWorksheet()->getParent()->getSheetByName($sheetName); + } else { + $pSheet = $pCell->getWorksheet(); + } + + return PHPExcel_Calculation::getInstance()->extractCellRange($cellAddress, $pSheet, False); + } // function OFFSET() + + + /** + * CHOOSE + * + * Uses lookup_value to return a value from the list of value arguments. + * Use CHOOSE to select one of up to 254 values based on the lookup_value. + * + * Excel Function: + * =CHOOSE(index_num, value1, [value2], ...) + * + * @param index_num Specifies which value argument is selected. + * Index_num must be a number between 1 and 254, or a formula or reference to a cell containing a number + * between 1 and 254. + * @param value1... Value1 is required, subsequent values are optional. + * Between 1 to 254 value arguments from which CHOOSE selects a value or an action to perform based on + * index_num. The arguments can be numbers, cell references, defined names, formulas, functions, or + * text. + * @return mixed The selected value + */ + public static function CHOOSE() { + $chooseArgs = func_get_args(); + $chosenEntry = PHPExcel_Calculation_Functions::flattenArray(array_shift($chooseArgs)); + $entryCount = count($chooseArgs) - 1; + + if(is_array($chosenEntry)) { + $chosenEntry = array_shift($chosenEntry); + } + if ((is_numeric($chosenEntry)) && (!is_bool($chosenEntry))) { + --$chosenEntry; + } else { + return PHPExcel_Calculation_Functions::VALUE(); + } + $chosenEntry = floor($chosenEntry); + if (($chosenEntry < 0) || ($chosenEntry > $entryCount)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (is_array($chooseArgs[$chosenEntry])) { + return PHPExcel_Calculation_Functions::flattenArray($chooseArgs[$chosenEntry]); + } else { + return $chooseArgs[$chosenEntry]; + } + } // function CHOOSE() + + + /** + * MATCH + * + * The MATCH function searches for a specified item in a range of cells + * + * Excel Function: + * =MATCH(lookup_value, lookup_array, [match_type]) + * + * @param lookup_value The value that you want to match in lookup_array + * @param lookup_array The range of cells being searched + * @param match_type The number -1, 0, or 1. -1 means above, 0 means exact match, 1 means below. If match_type is 1 or -1, the list has to be ordered. + * @return integer The relative position of the found item + */ + public static function MATCH($lookup_value, $lookup_array, $match_type=1) { + $lookup_array = PHPExcel_Calculation_Functions::flattenArray($lookup_array); + $lookup_value = PHPExcel_Calculation_Functions::flattenSingleValue($lookup_value); + $match_type = (is_null($match_type)) ? 1 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($match_type); + // MATCH is not case sensitive + $lookup_value = strtolower($lookup_value); + + // lookup_value type has to be number, text, or logical values + if ((!is_numeric($lookup_value)) && (!is_string($lookup_value)) && (!is_bool($lookup_value))) { + return PHPExcel_Calculation_Functions::NA(); + } + + // match_type is 0, 1 or -1 + if (($match_type !== 0) && ($match_type !== -1) && ($match_type !== 1)) { + return PHPExcel_Calculation_Functions::NA(); + } + + // lookup_array should not be empty + $lookupArraySize = count($lookup_array); + if ($lookupArraySize <= 0) { + return PHPExcel_Calculation_Functions::NA(); + } + + // lookup_array should contain only number, text, or logical values, or empty (null) cells + foreach($lookup_array as $i => $lookupArrayValue) { + // check the type of the value + if ((!is_numeric($lookupArrayValue)) && (!is_string($lookupArrayValue)) && + (!is_bool($lookupArrayValue)) && (!is_null($lookupArrayValue))) { + return PHPExcel_Calculation_Functions::NA(); + } + // convert strings to lowercase for case-insensitive testing + if (is_string($lookupArrayValue)) { + $lookup_array[$i] = strtolower($lookupArrayValue); + } + if ((is_null($lookupArrayValue)) && (($match_type == 1) || ($match_type == -1))) { + $lookup_array = array_slice($lookup_array,0,$i-1); + } + } + + // if match_type is 1 or -1, the list has to be ordered + if ($match_type == 1) { + asort($lookup_array); + $keySet = array_keys($lookup_array); + } elseif($match_type == -1) { + arsort($lookup_array); + $keySet = array_keys($lookup_array); + } + + // ** + // find the match + // ** + // loop on the cells +// var_dump($lookup_array); +// echo '
            '; + foreach($lookup_array as $i => $lookupArrayValue) { + if (($match_type == 0) && ($lookupArrayValue == $lookup_value)) { + // exact match + return ++$i; + } elseif (($match_type == -1) && ($lookupArrayValue <= $lookup_value)) { +// echo '$i = '.$i.' => '; +// var_dump($lookupArrayValue); +// echo '
            '; +// echo 'Keyset = '; +// var_dump($keySet); +// echo '
            '; + $i = array_search($i,$keySet); +// echo '$i='.$i.'
            '; + // if match_type is -1 <=> find the smallest value that is greater than or equal to lookup_value + if ($i < 1){ + // 1st cell was allready smaller than the lookup_value + break; + } else { + // the previous cell was the match + return $keySet[$i-1]+1; + } + } elseif (($match_type == 1) && ($lookupArrayValue >= $lookup_value)) { +// echo '$i = '.$i.' => '; +// var_dump($lookupArrayValue); +// echo '
            '; +// echo 'Keyset = '; +// var_dump($keySet); +// echo '
            '; + $i = array_search($i,$keySet); +// echo '$i='.$i.'
            '; + // if match_type is 1 <=> find the largest value that is less than or equal to lookup_value + if ($i < 1){ + // 1st cell was allready bigger than the lookup_value + break; + } else { + // the previous cell was the match + return $keySet[$i-1]+1; + } + } + } + + // unsuccessful in finding a match, return #N/A error value + return PHPExcel_Calculation_Functions::NA(); + } // function MATCH() + + + /** + * INDEX + * + * Uses an index to choose a value from a reference or array + * + * Excel Function: + * =INDEX(range_array, row_num, [column_num]) + * + * @param range_array A range of cells or an array constant + * @param row_num The row in array from which to return a value. If row_num is omitted, column_num is required. + * @param column_num The column in array from which to return a value. If column_num is omitted, row_num is required. + * @return mixed the value of a specified cell or array of cells + */ + public static function INDEX($arrayValues,$rowNum = 0,$columnNum = 0) { + + if (($rowNum < 0) || ($columnNum < 0)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (!is_array($arrayValues)) { + return PHPExcel_Calculation_Functions::REF(); + } + + $rowKeys = array_keys($arrayValues); + $columnKeys = @array_keys($arrayValues[$rowKeys[0]]); + + if ($columnNum > count($columnKeys)) { + return PHPExcel_Calculation_Functions::VALUE(); + } elseif ($columnNum == 0) { + if ($rowNum == 0) { + return $arrayValues; + } + $rowNum = $rowKeys[--$rowNum]; + $returnArray = array(); + foreach($arrayValues as $arrayColumn) { + if (is_array($arrayColumn)) { + if (isset($arrayColumn[$rowNum])) { + $returnArray[] = $arrayColumn[$rowNum]; + } else { + return $arrayValues[$rowNum]; + } + } else { + return $arrayValues[$rowNum]; + } + } + return $returnArray; + } + $columnNum = $columnKeys[--$columnNum]; + if ($rowNum > count($rowKeys)) { + return PHPExcel_Calculation_Functions::VALUE(); + } elseif ($rowNum == 0) { + return $arrayValues[$columnNum]; + } + $rowNum = $rowKeys[--$rowNum]; + + return $arrayValues[$rowNum][$columnNum]; + } // function INDEX() + + + /** + * TRANSPOSE + * + * @param array $matrixData A matrix of values + * @return array + * + * Unlike the Excel TRANSPOSE function, which will only work on a single row or column, this function will transpose a full matrix. + */ + public static function TRANSPOSE($matrixData) { + $returnMatrix = array(); + if (!is_array($matrixData)) { $matrixData = array(array($matrixData)); } + + $column = 0; + foreach($matrixData as $matrixRow) { + $row = 0; + foreach($matrixRow as $matrixCell) { + $returnMatrix[$row][$column] = $matrixCell; + ++$row; + } + ++$column; + } + return $returnMatrix; + } // function TRANSPOSE() + + + private static function _vlookupSort($a,$b) { + $f = array_keys($a); + $firstColumn = array_shift($f); + if (strtolower($a[$firstColumn]) == strtolower($b[$firstColumn])) { + return 0; + } + return (strtolower($a[$firstColumn]) < strtolower($b[$firstColumn])) ? -1 : 1; + } // function _vlookupSort() + + + /** + * VLOOKUP + * The VLOOKUP function searches for value in the left-most column of lookup_array and returns the value in the same row based on the index_number. + * @param lookup_value The value that you want to match in lookup_array + * @param lookup_array The range of cells being searched + * @param index_number The column number in table_array from which the matching value must be returned. The first column is 1. + * @param not_exact_match Determines if you are looking for an exact match based on lookup_value. + * @return mixed The value of the found cell + */ + public static function VLOOKUP($lookup_value, $lookup_array, $index_number, $not_exact_match=true) { + $lookup_value = PHPExcel_Calculation_Functions::flattenSingleValue($lookup_value); + $index_number = PHPExcel_Calculation_Functions::flattenSingleValue($index_number); + $not_exact_match = PHPExcel_Calculation_Functions::flattenSingleValue($not_exact_match); + + // index_number must be greater than or equal to 1 + if ($index_number < 1) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + // index_number must be less than or equal to the number of columns in lookup_array + if ((!is_array($lookup_array)) || (empty($lookup_array))) { + return PHPExcel_Calculation_Functions::REF(); + } else { + $f = array_keys($lookup_array); + $firstRow = array_pop($f); + if ((!is_array($lookup_array[$firstRow])) || ($index_number > count($lookup_array[$firstRow]))) { + return PHPExcel_Calculation_Functions::REF(); + } else { + $columnKeys = array_keys($lookup_array[$firstRow]); + $returnColumn = $columnKeys[--$index_number]; + $firstColumn = array_shift($columnKeys); + } + } + + if (!$not_exact_match) { + uasort($lookup_array,array('self','_vlookupSort')); + } + + $rowNumber = $rowValue = False; + foreach($lookup_array as $rowKey => $rowData) { + if ((is_numeric($lookup_value) && is_numeric($rowData[$firstColumn]) && ($rowData[$firstColumn] > $lookup_value)) || + (!is_numeric($lookup_value) && !is_numeric($rowData[$firstColumn]) && (strtolower($rowData[$firstColumn]) > strtolower($lookup_value)))) { + break; + } + $rowNumber = $rowKey; + $rowValue = $rowData[$firstColumn]; + } + + if ($rowNumber !== false) { + if ((!$not_exact_match) && ($rowValue != $lookup_value)) { + // if an exact match is required, we have what we need to return an appropriate response + return PHPExcel_Calculation_Functions::NA(); + } else { + // otherwise return the appropriate value + $result = $lookup_array[$rowNumber][$returnColumn]; + if ((is_numeric($lookup_value) && is_numeric($result)) || + (!is_numeric($lookup_value) && !is_numeric($result))) { + return $result; + } + } + } + + return PHPExcel_Calculation_Functions::NA(); + } // function VLOOKUP() + + +/** + * HLOOKUP + * The HLOOKUP function searches for value in the top-most row of lookup_array and returns the value in the same column based on the index_number. + * @param lookup_value The value that you want to match in lookup_array + * @param lookup_array The range of cells being searched + * @param index_number The row number in table_array from which the matching value must be returned. The first row is 1. + * @param not_exact_match Determines if you are looking for an exact match based on lookup_value. + * @return mixed The value of the found cell + */ + public static function HLOOKUP($lookup_value, $lookup_array, $index_number, $not_exact_match=true) { + $lookup_value = PHPExcel_Calculation_Functions::flattenSingleValue($lookup_value); + $index_number = PHPExcel_Calculation_Functions::flattenSingleValue($index_number); + $not_exact_match = PHPExcel_Calculation_Functions::flattenSingleValue($not_exact_match); + + // index_number must be greater than or equal to 1 + if ($index_number < 1) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + // index_number must be less than or equal to the number of columns in lookup_array + if ((!is_array($lookup_array)) || (empty($lookup_array))) { + return PHPExcel_Calculation_Functions::REF(); + } else { + $f = array_keys($lookup_array); + $firstRow = array_pop($f); + if ((!is_array($lookup_array[$firstRow])) || ($index_number > count($lookup_array[$firstRow]))) { + return PHPExcel_Calculation_Functions::REF(); + } else { + $columnKeys = array_keys($lookup_array[$firstRow]); + $firstkey = $f[0] - 1; + $returnColumn = $firstkey + $index_number; + $firstColumn = array_shift($f); + } + } + + if (!$not_exact_match) { + $firstRowH = asort($lookup_array[$firstColumn]); + } + + $rowNumber = $rowValue = False; + foreach($lookup_array[$firstColumn] as $rowKey => $rowData) { + if ((is_numeric($lookup_value) && is_numeric($rowData) && ($rowData > $lookup_value)) || + (!is_numeric($lookup_value) && !is_numeric($rowData) && (strtolower($rowData) > strtolower($lookup_value)))) { + break; + } + $rowNumber = $rowKey; + $rowValue = $rowData; + } + + if ($rowNumber !== false) { + if ((!$not_exact_match) && ($rowValue != $lookup_value)) { + // if an exact match is required, we have what we need to return an appropriate response + return PHPExcel_Calculation_Functions::NA(); + } else { + // otherwise return the appropriate value + $result = $lookup_array[$returnColumn][$rowNumber]; + return $result; + } + } + + return PHPExcel_Calculation_Functions::NA(); + } // function HLOOKUP() + + + /** + * LOOKUP + * The LOOKUP function searches for value either from a one-row or one-column range or from an array. + * @param lookup_value The value that you want to match in lookup_array + * @param lookup_vector The range of cells being searched + * @param result_vector The column from which the matching value must be returned + * @return mixed The value of the found cell + */ + public static function LOOKUP($lookup_value, $lookup_vector, $result_vector=null) { + $lookup_value = PHPExcel_Calculation_Functions::flattenSingleValue($lookup_value); + + if (!is_array($lookup_vector)) { + return PHPExcel_Calculation_Functions::NA(); + } + $lookupRows = count($lookup_vector); + $l = array_keys($lookup_vector); + $l = array_shift($l); + $lookupColumns = count($lookup_vector[$l]); + if ((($lookupRows == 1) && ($lookupColumns > 1)) || (($lookupRows == 2) && ($lookupColumns != 2))) { + $lookup_vector = self::TRANSPOSE($lookup_vector); + $lookupRows = count($lookup_vector); + $l = array_keys($lookup_vector); + $lookupColumns = count($lookup_vector[array_shift($l)]); + } + + if (is_null($result_vector)) { + $result_vector = $lookup_vector; + } + $resultRows = count($result_vector); + $l = array_keys($result_vector); + $l = array_shift($l); + $resultColumns = count($result_vector[$l]); + if ((($resultRows == 1) && ($resultColumns > 1)) || (($resultRows == 2) && ($resultColumns != 2))) { + $result_vector = self::TRANSPOSE($result_vector); + $resultRows = count($result_vector); + $r = array_keys($result_vector); + $resultColumns = count($result_vector[array_shift($r)]); + } + + if ($lookupRows == 2) { + $result_vector = array_pop($lookup_vector); + $lookup_vector = array_shift($lookup_vector); + } + if ($lookupColumns != 2) { + foreach($lookup_vector as &$value) { + if (is_array($value)) { + $k = array_keys($value); + $key1 = $key2 = array_shift($k); + $key2++; + $dataValue1 = $value[$key1]; + } else { + $key1 = 0; + $key2 = 1; + $dataValue1 = $value; + } + $dataValue2 = array_shift($result_vector); + if (is_array($dataValue2)) { + $dataValue2 = array_shift($dataValue2); + } + $value = array($key1 => $dataValue1, $key2 => $dataValue2); + } + unset($value); + } + + return self::VLOOKUP($lookup_value,$lookup_vector,2); + } // function LOOKUP() + +} // class PHPExcel_Calculation_LookupRef diff --git a/lib/phpexcel/PHPExcel/Calculation/MathTrig.php b/lib/phpexcel/PHPExcel/Calculation/MathTrig.php new file mode 100644 index 0000000..1093055 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Calculation/MathTrig.php @@ -0,0 +1,1373 @@ + 1; --$i) { + if (($value % $i) == 0) { + $factorArray = array_merge($factorArray,self::_factors($value / $i)); + $factorArray = array_merge($factorArray,self::_factors($i)); + if ($i <= sqrt($value)) { + break; + } + } + } + if (!empty($factorArray)) { + rsort($factorArray); + return $factorArray; + } else { + return array((integer) $value); + } + } // function _factors() + + + private static function _romanCut($num, $n) { + return ($num - ($num % $n ) ) / $n; + } // function _romanCut() + + + /** + * ATAN2 + * + * This function calculates the arc tangent of the two variables x and y. It is similar to + * calculating the arc tangent of y ÷ x, except that the signs of both arguments are used + * to determine the quadrant of the result. + * The arctangent is the angle from the x-axis to a line containing the origin (0, 0) and a + * point with coordinates (xCoordinate, yCoordinate). The angle is given in radians between + * -pi and pi, excluding -pi. + * + * Note that the Excel ATAN2() function accepts its arguments in the reverse order to the standard + * PHP atan2() function, so we need to reverse them here before calling the PHP atan() function. + * + * Excel Function: + * ATAN2(xCoordinate,yCoordinate) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param float $xCoordinate The x-coordinate of the point. + * @param float $yCoordinate The y-coordinate of the point. + * @return float The inverse tangent of the specified x- and y-coordinates. + */ + public static function ATAN2($xCoordinate = NULL, $yCoordinate = NULL) { + $xCoordinate = PHPExcel_Calculation_Functions::flattenSingleValue($xCoordinate); + $yCoordinate = PHPExcel_Calculation_Functions::flattenSingleValue($yCoordinate); + + $xCoordinate = ($xCoordinate !== NULL) ? $xCoordinate : 0.0; + $yCoordinate = ($yCoordinate !== NULL) ? $yCoordinate : 0.0; + + if (((is_numeric($xCoordinate)) || (is_bool($xCoordinate))) && + ((is_numeric($yCoordinate))) || (is_bool($yCoordinate))) { + $xCoordinate = (float) $xCoordinate; + $yCoordinate = (float) $yCoordinate; + + if (($xCoordinate == 0) && ($yCoordinate == 0)) { + return PHPExcel_Calculation_Functions::DIV0(); + } + + return atan2($yCoordinate, $xCoordinate); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function ATAN2() + + + /** + * CEILING + * + * Returns number rounded up, away from zero, to the nearest multiple of significance. + * For example, if you want to avoid using pennies in your prices and your product is + * priced at $4.42, use the formula =CEILING(4.42,0.05) to round prices up to the + * nearest nickel. + * + * Excel Function: + * CEILING(number[,significance]) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param float $number The number you want to round. + * @param float $significance The multiple to which you want to round. + * @return float Rounded Number + */ + public static function CEILING($number, $significance = NULL) { + $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); + $significance = PHPExcel_Calculation_Functions::flattenSingleValue($significance); + + if ((is_null($significance)) && + (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC)) { + $significance = $number/abs($number); + } + + if ((is_numeric($number)) && (is_numeric($significance))) { + if ($significance == 0.0) { + return 0.0; + } elseif (self::SIGN($number) == self::SIGN($significance)) { + return ceil($number / $significance) * $significance; + } else { + return PHPExcel_Calculation_Functions::NaN(); + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function CEILING() + + + /** + * COMBIN + * + * Returns the number of combinations for a given number of items. Use COMBIN to + * determine the total possible number of groups for a given number of items. + * + * Excel Function: + * COMBIN(numObjs,numInSet) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param int $numObjs Number of different objects + * @param int $numInSet Number of objects in each combination + * @return int Number of combinations + */ + public static function COMBIN($numObjs, $numInSet) { + $numObjs = PHPExcel_Calculation_Functions::flattenSingleValue($numObjs); + $numInSet = PHPExcel_Calculation_Functions::flattenSingleValue($numInSet); + + if ((is_numeric($numObjs)) && (is_numeric($numInSet))) { + if ($numObjs < $numInSet) { + return PHPExcel_Calculation_Functions::NaN(); + } elseif ($numInSet < 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + return round(self::FACT($numObjs) / self::FACT($numObjs - $numInSet)) / self::FACT($numInSet); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function COMBIN() + + + /** + * EVEN + * + * Returns number rounded up to the nearest even integer. + * You can use this function for processing items that come in twos. For example, + * a packing crate accepts rows of one or two items. The crate is full when + * the number of items, rounded up to the nearest two, matches the crate's + * capacity. + * + * Excel Function: + * EVEN(number) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param float $number Number to round + * @return int Rounded Number + */ + public static function EVEN($number) { + $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); + + if (is_null($number)) { + return 0; + } elseif (is_bool($number)) { + $number = (int) $number; + } + + if (is_numeric($number)) { + $significance = 2 * self::SIGN($number); + return (int) self::CEILING($number,$significance); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function EVEN() + + + /** + * FACT + * + * Returns the factorial of a number. + * The factorial of a number is equal to 1*2*3*...* number. + * + * Excel Function: + * FACT(factVal) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param float $factVal Factorial Value + * @return int Factorial + */ + public static function FACT($factVal) { + $factVal = PHPExcel_Calculation_Functions::flattenSingleValue($factVal); + + if (is_numeric($factVal)) { + if ($factVal < 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + $factLoop = floor($factVal); + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) { + if ($factVal > $factLoop) { + return PHPExcel_Calculation_Functions::NaN(); + } + } + + $factorial = 1; + while ($factLoop > 1) { + $factorial *= $factLoop--; + } + return $factorial ; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function FACT() + + + /** + * FACTDOUBLE + * + * Returns the double factorial of a number. + * + * Excel Function: + * FACTDOUBLE(factVal) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param float $factVal Factorial Value + * @return int Double Factorial + */ + public static function FACTDOUBLE($factVal) { + $factLoop = PHPExcel_Calculation_Functions::flattenSingleValue($factVal); + + if (is_numeric($factLoop)) { + $factLoop = floor($factLoop); + if ($factVal < 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + $factorial = 1; + while ($factLoop > 1) { + $factorial *= $factLoop--; + --$factLoop; + } + return $factorial ; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function FACTDOUBLE() + + + /** + * FLOOR + * + * Rounds number down, toward zero, to the nearest multiple of significance. + * + * Excel Function: + * FLOOR(number[,significance]) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param float $number Number to round + * @param float $significance Significance + * @return float Rounded Number + */ + public static function FLOOR($number, $significance = NULL) { + $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); + $significance = PHPExcel_Calculation_Functions::flattenSingleValue($significance); + + if ((is_null($significance)) && (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC)) { + $significance = $number/abs($number); + } + + if ((is_numeric($number)) && (is_numeric($significance))) { + if ((float) $significance == 0.0) { + return PHPExcel_Calculation_Functions::DIV0(); + } + if (self::SIGN($number) == self::SIGN($significance)) { + return floor($number / $significance) * $significance; + } else { + return PHPExcel_Calculation_Functions::NaN(); + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function FLOOR() + + + /** + * GCD + * + * Returns the greatest common divisor of a series of numbers. + * The greatest common divisor is the largest integer that divides both + * number1 and number2 without a remainder. + * + * Excel Function: + * GCD(number1[,number2[, ...]]) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param mixed $arg,... Data values + * @return integer Greatest Common Divisor + */ + public static function GCD() { + $returnValue = 1; + $allValuesFactors = array(); + // Loop through arguments + foreach(PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $value) { + if (!is_numeric($value)) { + return PHPExcel_Calculation_Functions::VALUE(); + } elseif ($value == 0) { + continue; + } elseif($value < 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + $myFactors = self::_factors($value); + $myCountedFactors = array_count_values($myFactors); + $allValuesFactors[] = $myCountedFactors; + } + $allValuesCount = count($allValuesFactors); + if ($allValuesCount == 0) { + return 0; + } + + $mergedArray = $allValuesFactors[0]; + for ($i=1;$i < $allValuesCount; ++$i) { + $mergedArray = array_intersect_key($mergedArray,$allValuesFactors[$i]); + } + $mergedArrayValues = count($mergedArray); + if ($mergedArrayValues == 0) { + return $returnValue; + } elseif ($mergedArrayValues > 1) { + foreach($mergedArray as $mergedKey => $mergedValue) { + foreach($allValuesFactors as $highestPowerTest) { + foreach($highestPowerTest as $testKey => $testValue) { + if (($testKey == $mergedKey) && ($testValue < $mergedValue)) { + $mergedArray[$mergedKey] = $testValue; + $mergedValue = $testValue; + } + } + } + } + + $returnValue = 1; + foreach($mergedArray as $key => $value) { + $returnValue *= pow($key,$value); + } + return $returnValue; + } else { + $keys = array_keys($mergedArray); + $key = $keys[0]; + $value = $mergedArray[$key]; + foreach($allValuesFactors as $testValue) { + foreach($testValue as $mergedKey => $mergedValue) { + if (($mergedKey == $key) && ($mergedValue < $value)) { + $value = $mergedValue; + } + } + } + return pow($key,$value); + } + } // function GCD() + + + /** + * INT + * + * Casts a floating point value to an integer + * + * Excel Function: + * INT(number) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param float $number Number to cast to an integer + * @return integer Integer value + */ + public static function INT($number) { + $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); + + if (is_null($number)) { + return 0; + } elseif (is_bool($number)) { + return (int) $number; + } + if (is_numeric($number)) { + return (int) floor($number); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function INT() + + + /** + * LCM + * + * Returns the lowest common multiplier of a series of numbers + * The least common multiple is the smallest positive integer that is a multiple + * of all integer arguments number1, number2, and so on. Use LCM to add fractions + * with different denominators. + * + * Excel Function: + * LCM(number1[,number2[, ...]]) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param mixed $arg,... Data values + * @return int Lowest Common Multiplier + */ + public static function LCM() { + $returnValue = 1; + $allPoweredFactors = array(); + // Loop through arguments + foreach(PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $value) { + if (!is_numeric($value)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + if ($value == 0) { + return 0; + } elseif ($value < 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + $myFactors = self::_factors(floor($value)); + $myCountedFactors = array_count_values($myFactors); + $myPoweredFactors = array(); + foreach($myCountedFactors as $myCountedFactor => $myCountedPower) { + $myPoweredFactors[$myCountedFactor] = pow($myCountedFactor,$myCountedPower); + } + foreach($myPoweredFactors as $myPoweredValue => $myPoweredFactor) { + if (array_key_exists($myPoweredValue,$allPoweredFactors)) { + if ($allPoweredFactors[$myPoweredValue] < $myPoweredFactor) { + $allPoweredFactors[$myPoweredValue] = $myPoweredFactor; + } + } else { + $allPoweredFactors[$myPoweredValue] = $myPoweredFactor; + } + } + } + foreach($allPoweredFactors as $allPoweredFactor) { + $returnValue *= (integer) $allPoweredFactor; + } + return $returnValue; + } // function LCM() + + + /** + * LOG_BASE + * + * Returns the logarithm of a number to a specified base. The default base is 10. + * + * Excel Function: + * LOG(number[,base]) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param float $number The positive real number for which you want the logarithm + * @param float $base The base of the logarithm. If base is omitted, it is assumed to be 10. + * @return float + */ + public static function LOG_BASE($number = NULL, $base = 10) { + $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); + $base = (is_null($base)) ? 10 : (float) PHPExcel_Calculation_Functions::flattenSingleValue($base); + + if ((!is_numeric($base)) || (!is_numeric($number))) + return PHPExcel_Calculation_Functions::VALUE(); + if (($base <= 0) || ($number <= 0)) + return PHPExcel_Calculation_Functions::NaN(); + return log($number, $base); + } // function LOG_BASE() + + + /** + * MDETERM + * + * Returns the matrix determinant of an array. + * + * Excel Function: + * MDETERM(array) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param array $matrixValues A matrix of values + * @return float + */ + public static function MDETERM($matrixValues) { + $matrixData = array(); + if (!is_array($matrixValues)) { $matrixValues = array(array($matrixValues)); } + + $row = $maxColumn = 0; + foreach($matrixValues as $matrixRow) { + if (!is_array($matrixRow)) { $matrixRow = array($matrixRow); } + $column = 0; + foreach($matrixRow as $matrixCell) { + if ((is_string($matrixCell)) || ($matrixCell === null)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $matrixData[$column][$row] = $matrixCell; + ++$column; + } + if ($column > $maxColumn) { $maxColumn = $column; } + ++$row; + } + if ($row != $maxColumn) { return PHPExcel_Calculation_Functions::VALUE(); } + + try { + $matrix = new PHPExcel_Shared_JAMA_Matrix($matrixData); + return $matrix->det(); + } catch (PHPExcel_Exception $ex) { + return PHPExcel_Calculation_Functions::VALUE(); + } + } // function MDETERM() + + + /** + * MINVERSE + * + * Returns the inverse matrix for the matrix stored in an array. + * + * Excel Function: + * MINVERSE(array) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param array $matrixValues A matrix of values + * @return array + */ + public static function MINVERSE($matrixValues) { + $matrixData = array(); + if (!is_array($matrixValues)) { $matrixValues = array(array($matrixValues)); } + + $row = $maxColumn = 0; + foreach($matrixValues as $matrixRow) { + if (!is_array($matrixRow)) { $matrixRow = array($matrixRow); } + $column = 0; + foreach($matrixRow as $matrixCell) { + if ((is_string($matrixCell)) || ($matrixCell === null)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $matrixData[$column][$row] = $matrixCell; + ++$column; + } + if ($column > $maxColumn) { $maxColumn = $column; } + ++$row; + } + if ($row != $maxColumn) { return PHPExcel_Calculation_Functions::VALUE(); } + + try { + $matrix = new PHPExcel_Shared_JAMA_Matrix($matrixData); + return $matrix->inverse()->getArray(); + } catch (PHPExcel_Exception $ex) { + return PHPExcel_Calculation_Functions::VALUE(); + } + } // function MINVERSE() + + + /** + * MMULT + * + * @param array $matrixData1 A matrix of values + * @param array $matrixData2 A matrix of values + * @return array + */ + public static function MMULT($matrixData1,$matrixData2) { + $matrixAData = $matrixBData = array(); + if (!is_array($matrixData1)) { $matrixData1 = array(array($matrixData1)); } + if (!is_array($matrixData2)) { $matrixData2 = array(array($matrixData2)); } + + $rowA = 0; + foreach($matrixData1 as $matrixRow) { + if (!is_array($matrixRow)) { $matrixRow = array($matrixRow); } + $columnA = 0; + foreach($matrixRow as $matrixCell) { + if ((is_string($matrixCell)) || ($matrixCell === null)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $matrixAData[$rowA][$columnA] = $matrixCell; + ++$columnA; + } + ++$rowA; + } + try { + $matrixA = new PHPExcel_Shared_JAMA_Matrix($matrixAData); + $rowB = 0; + foreach($matrixData2 as $matrixRow) { + if (!is_array($matrixRow)) { $matrixRow = array($matrixRow); } + $columnB = 0; + foreach($matrixRow as $matrixCell) { + if ((is_string($matrixCell)) || ($matrixCell === null)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $matrixBData[$rowB][$columnB] = $matrixCell; + ++$columnB; + } + ++$rowB; + } + $matrixB = new PHPExcel_Shared_JAMA_Matrix($matrixBData); + + if (($rowA != $columnB) || ($rowB != $columnA)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + return $matrixA->times($matrixB)->getArray(); + } catch (PHPExcel_Exception $ex) { + return PHPExcel_Calculation_Functions::VALUE(); + } + } // function MMULT() + + + /** + * MOD + * + * @param int $a Dividend + * @param int $b Divisor + * @return int Remainder + */ + public static function MOD($a = 1, $b = 1) { + $a = PHPExcel_Calculation_Functions::flattenSingleValue($a); + $b = PHPExcel_Calculation_Functions::flattenSingleValue($b); + + if ($b == 0.0) { + return PHPExcel_Calculation_Functions::DIV0(); + } elseif (($a < 0.0) && ($b > 0.0)) { + return $b - fmod(abs($a),$b); + } elseif (($a > 0.0) && ($b < 0.0)) { + return $b + fmod($a,abs($b)); + } + + return fmod($a,$b); + } // function MOD() + + + /** + * MROUND + * + * Rounds a number to the nearest multiple of a specified value + * + * @param float $number Number to round + * @param int $multiple Multiple to which you want to round $number + * @return float Rounded Number + */ + public static function MROUND($number,$multiple) { + $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); + $multiple = PHPExcel_Calculation_Functions::flattenSingleValue($multiple); + + if ((is_numeric($number)) && (is_numeric($multiple))) { + if ($multiple == 0) { + return 0; + } + if ((self::SIGN($number)) == (self::SIGN($multiple))) { + $multiplier = 1 / $multiple; + return round($number * $multiplier) / $multiplier; + } + return PHPExcel_Calculation_Functions::NaN(); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function MROUND() + + + /** + * MULTINOMIAL + * + * Returns the ratio of the factorial of a sum of values to the product of factorials. + * + * @param array of mixed Data Series + * @return float + */ + public static function MULTINOMIAL() { + $summer = 0; + $divisor = 1; + // Loop through arguments + foreach (PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $arg) { + // Is it a numeric value? + if (is_numeric($arg)) { + if ($arg < 1) { + return PHPExcel_Calculation_Functions::NaN(); + } + $summer += floor($arg); + $divisor *= self::FACT($arg); + } else { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + + // Return + if ($summer > 0) { + $summer = self::FACT($summer); + return $summer / $divisor; + } + return 0; + } // function MULTINOMIAL() + + + /** + * ODD + * + * Returns number rounded up to the nearest odd integer. + * + * @param float $number Number to round + * @return int Rounded Number + */ + public static function ODD($number) { + $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); + + if (is_null($number)) { + return 1; + } elseif (is_bool($number)) { + $number = (int) $number; + } + + if (is_numeric($number)) { + $significance = self::SIGN($number); + if ($significance == 0) { + return 1; + } + + $result = self::CEILING($number,$significance); + if ($result == self::EVEN($result)) { + $result += $significance; + } + + return (int) $result; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function ODD() + + + /** + * POWER + * + * Computes x raised to the power y. + * + * @param float $x + * @param float $y + * @return float + */ + public static function POWER($x = 0, $y = 2) { + $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); + $y = PHPExcel_Calculation_Functions::flattenSingleValue($y); + + // Validate parameters + if ($x == 0.0 && $y == 0.0) { + return PHPExcel_Calculation_Functions::NaN(); + } elseif ($x == 0.0 && $y < 0.0) { + return PHPExcel_Calculation_Functions::DIV0(); + } + + // Return + $result = pow($x, $y); + return (!is_nan($result) && !is_infinite($result)) ? $result : PHPExcel_Calculation_Functions::NaN(); + } // function POWER() + + + /** + * PRODUCT + * + * PRODUCT returns the product of all the values and cells referenced in the argument list. + * + * Excel Function: + * PRODUCT(value1[,value2[, ...]]) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function PRODUCT() { + // Return value + $returnValue = null; + + // Loop through arguments + foreach (PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $arg) { + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + if (is_null($returnValue)) { + $returnValue = $arg; + } else { + $returnValue *= $arg; + } + } + } + + // Return + if (is_null($returnValue)) { + return 0; + } + return $returnValue; + } // function PRODUCT() + + + /** + * QUOTIENT + * + * QUOTIENT function returns the integer portion of a division. Numerator is the divided number + * and denominator is the divisor. + * + * Excel Function: + * QUOTIENT(value1[,value2[, ...]]) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function QUOTIENT() { + // Return value + $returnValue = null; + + // Loop through arguments + foreach (PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $arg) { + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + if (is_null($returnValue)) { + $returnValue = ($arg == 0) ? 0 : $arg; + } else { + if (($returnValue == 0) || ($arg == 0)) { + $returnValue = 0; + } else { + $returnValue /= $arg; + } + } + } + } + + // Return + return intval($returnValue); + } // function QUOTIENT() + + + /** + * RAND + * + * @param int $min Minimal value + * @param int $max Maximal value + * @return int Random number + */ + public static function RAND($min = 0, $max = 0) { + $min = PHPExcel_Calculation_Functions::flattenSingleValue($min); + $max = PHPExcel_Calculation_Functions::flattenSingleValue($max); + + if ($min == 0 && $max == 0) { + return (rand(0,10000000)) / 10000000; + } else { + return rand($min, $max); + } + } // function RAND() + + + public static function ROMAN($aValue, $style=0) { + $aValue = PHPExcel_Calculation_Functions::flattenSingleValue($aValue); + $style = (is_null($style)) ? 0 : (integer) PHPExcel_Calculation_Functions::flattenSingleValue($style); + if ((!is_numeric($aValue)) || ($aValue < 0) || ($aValue >= 4000)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $aValue = (integer) $aValue; + if ($aValue == 0) { + return ''; + } + + $mill = Array('', 'M', 'MM', 'MMM', 'MMMM', 'MMMMM'); + $cent = Array('', 'C', 'CC', 'CCC', 'CD', 'D', 'DC', 'DCC', 'DCCC', 'CM'); + $tens = Array('', 'X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC'); + $ones = Array('', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX'); + + $roman = ''; + while ($aValue > 5999) { + $roman .= 'M'; + $aValue -= 1000; + } + $m = self::_romanCut($aValue, 1000); $aValue %= 1000; + $c = self::_romanCut($aValue, 100); $aValue %= 100; + $t = self::_romanCut($aValue, 10); $aValue %= 10; + + return $roman.$mill[$m].$cent[$c].$tens[$t].$ones[$aValue]; + } // function ROMAN() + + + /** + * ROUNDUP + * + * Rounds a number up to a specified number of decimal places + * + * @param float $number Number to round + * @param int $digits Number of digits to which you want to round $number + * @return float Rounded Number + */ + public static function ROUNDUP($number,$digits) { + $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); + $digits = PHPExcel_Calculation_Functions::flattenSingleValue($digits); + + if ((is_numeric($number)) && (is_numeric($digits))) { + $significance = pow(10,(int) $digits); + if ($number < 0.0) { + return floor($number * $significance) / $significance; + } else { + return ceil($number * $significance) / $significance; + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function ROUNDUP() + + + /** + * ROUNDDOWN + * + * Rounds a number down to a specified number of decimal places + * + * @param float $number Number to round + * @param int $digits Number of digits to which you want to round $number + * @return float Rounded Number + */ + public static function ROUNDDOWN($number,$digits) { + $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); + $digits = PHPExcel_Calculation_Functions::flattenSingleValue($digits); + + if ((is_numeric($number)) && (is_numeric($digits))) { + $significance = pow(10,(int) $digits); + if ($number < 0.0) { + return ceil($number * $significance) / $significance; + } else { + return floor($number * $significance) / $significance; + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function ROUNDDOWN() + + + /** + * SERIESSUM + * + * Returns the sum of a power series + * + * @param float $x Input value to the power series + * @param float $n Initial power to which you want to raise $x + * @param float $m Step by which to increase $n for each term in the series + * @param array of mixed Data Series + * @return float + */ + public static function SERIESSUM() { + // Return value + $returnValue = 0; + + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + + $x = array_shift($aArgs); + $n = array_shift($aArgs); + $m = array_shift($aArgs); + + if ((is_numeric($x)) && (is_numeric($n)) && (is_numeric($m))) { + // Calculate + $i = 0; + foreach($aArgs as $arg) { + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + $returnValue += $arg * pow($x,$n + ($m * $i++)); + } else { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + // Return + return $returnValue; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function SERIESSUM() + + + /** + * SIGN + * + * Determines the sign of a number. Returns 1 if the number is positive, zero (0) + * if the number is 0, and -1 if the number is negative. + * + * @param float $number Number to round + * @return int sign value + */ + public static function SIGN($number) { + $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); + + if (is_bool($number)) + return (int) $number; + if (is_numeric($number)) { + if ($number == 0.0) { + return 0; + } + return $number / abs($number); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function SIGN() + + + /** + * SQRTPI + * + * Returns the square root of (number * pi). + * + * @param float $number Number + * @return float Square Root of Number * Pi + */ + public static function SQRTPI($number) { + $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); + + if (is_numeric($number)) { + if ($number < 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + return sqrt($number * M_PI) ; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function SQRTPI() + + + /** + * SUBTOTAL + * + * Returns a subtotal in a list or database. + * + * @param int the number 1 to 11 that specifies which function to + * use in calculating subtotals within a list. + * @param array of mixed Data Series + * @return float + */ + public static function SUBTOTAL() { + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + + // Calculate + $subtotal = array_shift($aArgs); + + if ((is_numeric($subtotal)) && (!is_string($subtotal))) { + switch($subtotal) { + case 1 : + return PHPExcel_Calculation_Statistical::AVERAGE($aArgs); + break; + case 2 : + return PHPExcel_Calculation_Statistical::COUNT($aArgs); + break; + case 3 : + return PHPExcel_Calculation_Statistical::COUNTA($aArgs); + break; + case 4 : + return PHPExcel_Calculation_Statistical::MAX($aArgs); + break; + case 5 : + return PHPExcel_Calculation_Statistical::MIN($aArgs); + break; + case 6 : + return self::PRODUCT($aArgs); + break; + case 7 : + return PHPExcel_Calculation_Statistical::STDEV($aArgs); + break; + case 8 : + return PHPExcel_Calculation_Statistical::STDEVP($aArgs); + break; + case 9 : + return self::SUM($aArgs); + break; + case 10 : + return PHPExcel_Calculation_Statistical::VARFunc($aArgs); + break; + case 11 : + return PHPExcel_Calculation_Statistical::VARP($aArgs); + break; + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function SUBTOTAL() + + + /** + * SUM + * + * SUM computes the sum of all the values and cells referenced in the argument list. + * + * Excel Function: + * SUM(value1[,value2[, ...]]) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function SUM() { + // Return value + $returnValue = 0; + + // Loop through the arguments + foreach (PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $arg) { + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + $returnValue += $arg; + } + } + + // Return + return $returnValue; + } // function SUM() + + + /** + * SUMIF + * + * Counts the number of cells that contain numbers within the list of arguments + * + * Excel Function: + * SUMIF(value1[,value2[, ...]],condition) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param mixed $arg,... Data values + * @param string $condition The criteria that defines which cells will be summed. + * @return float + */ + public static function SUMIF($aArgs,$condition,$sumArgs = array()) { + // Return value + $returnValue = 0; + + $aArgs = PHPExcel_Calculation_Functions::flattenArray($aArgs); + $sumArgs = PHPExcel_Calculation_Functions::flattenArray($sumArgs); + if (empty($sumArgs)) { + $sumArgs = $aArgs; + } + $condition = PHPExcel_Calculation_Functions::_ifCondition($condition); + // Loop through arguments + foreach ($aArgs as $key => $arg) { + if (!is_numeric($arg)) { + $arg = str_replace('"', '""', $arg); + $arg = PHPExcel_Calculation::_wrapResult(strtoupper($arg)); + } + + $testCondition = '='.$arg.$condition; + if (PHPExcel_Calculation::getInstance()->_calculateFormulaValue($testCondition)) { + // Is it a value within our criteria + $returnValue += $sumArgs[$key]; + } + } + + // Return + return $returnValue; + } // function SUMIF() + + + /** + * SUMPRODUCT + * + * Excel Function: + * SUMPRODUCT(value1[,value2[, ...]]) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function SUMPRODUCT() { + $arrayList = func_get_args(); + + $wrkArray = PHPExcel_Calculation_Functions::flattenArray(array_shift($arrayList)); + $wrkCellCount = count($wrkArray); + + for ($i=0; $i< $wrkCellCount; ++$i) { + if ((!is_numeric($wrkArray[$i])) || (is_string($wrkArray[$i]))) { + $wrkArray[$i] = 0; + } + } + + foreach($arrayList as $matrixData) { + $array2 = PHPExcel_Calculation_Functions::flattenArray($matrixData); + $count = count($array2); + if ($wrkCellCount != $count) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + foreach ($array2 as $i => $val) { + if ((!is_numeric($val)) || (is_string($val))) { + $val = 0; + } + $wrkArray[$i] *= $val; + } + } + + return array_sum($wrkArray); + } // function SUMPRODUCT() + + + /** + * SUMSQ + * + * SUMSQ returns the sum of the squares of the arguments + * + * Excel Function: + * SUMSQ(value1[,value2[, ...]]) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function SUMSQ() { + // Return value + $returnValue = 0; + + // Loop through arguments + foreach (PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $arg) { + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + $returnValue += ($arg * $arg); + } + } + + // Return + return $returnValue; + } // function SUMSQ() + + + /** + * SUMX2MY2 + * + * @param mixed[] $matrixData1 Matrix #1 + * @param mixed[] $matrixData2 Matrix #2 + * @return float + */ + public static function SUMX2MY2($matrixData1,$matrixData2) { + $array1 = PHPExcel_Calculation_Functions::flattenArray($matrixData1); + $array2 = PHPExcel_Calculation_Functions::flattenArray($matrixData2); + $count1 = count($array1); + $count2 = count($array2); + if ($count1 < $count2) { + $count = $count1; + } else { + $count = $count2; + } + + $result = 0; + for ($i = 0; $i < $count; ++$i) { + if (((is_numeric($array1[$i])) && (!is_string($array1[$i]))) && + ((is_numeric($array2[$i])) && (!is_string($array2[$i])))) { + $result += ($array1[$i] * $array1[$i]) - ($array2[$i] * $array2[$i]); + } + } + + return $result; + } // function SUMX2MY2() + + + /** + * SUMX2PY2 + * + * @param mixed[] $matrixData1 Matrix #1 + * @param mixed[] $matrixData2 Matrix #2 + * @return float + */ + public static function SUMX2PY2($matrixData1,$matrixData2) { + $array1 = PHPExcel_Calculation_Functions::flattenArray($matrixData1); + $array2 = PHPExcel_Calculation_Functions::flattenArray($matrixData2); + $count1 = count($array1); + $count2 = count($array2); + if ($count1 < $count2) { + $count = $count1; + } else { + $count = $count2; + } + + $result = 0; + for ($i = 0; $i < $count; ++$i) { + if (((is_numeric($array1[$i])) && (!is_string($array1[$i]))) && + ((is_numeric($array2[$i])) && (!is_string($array2[$i])))) { + $result += ($array1[$i] * $array1[$i]) + ($array2[$i] * $array2[$i]); + } + } + + return $result; + } // function SUMX2PY2() + + + /** + * SUMXMY2 + * + * @param mixed[] $matrixData1 Matrix #1 + * @param mixed[] $matrixData2 Matrix #2 + * @return float + */ + public static function SUMXMY2($matrixData1,$matrixData2) { + $array1 = PHPExcel_Calculation_Functions::flattenArray($matrixData1); + $array2 = PHPExcel_Calculation_Functions::flattenArray($matrixData2); + $count1 = count($array1); + $count2 = count($array2); + if ($count1 < $count2) { + $count = $count1; + } else { + $count = $count2; + } + + $result = 0; + for ($i = 0; $i < $count; ++$i) { + if (((is_numeric($array1[$i])) && (!is_string($array1[$i]))) && + ((is_numeric($array2[$i])) && (!is_string($array2[$i])))) { + $result += ($array1[$i] - $array2[$i]) * ($array1[$i] - $array2[$i]); + } + } + + return $result; + } // function SUMXMY2() + + + /** + * TRUNC + * + * Truncates value to the number of fractional digits by number_digits. + * + * @param float $value + * @param int $digits + * @return float Truncated value + */ + public static function TRUNC($value = 0, $digits = 0) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $digits = PHPExcel_Calculation_Functions::flattenSingleValue($digits); + + // Validate parameters + if ((!is_numeric($value)) || (!is_numeric($digits))) + return PHPExcel_Calculation_Functions::VALUE(); + $digits = floor($digits); + + // Truncate + $adjust = pow(10, $digits); + + if (($digits > 0) && (rtrim(intval((abs($value) - abs(intval($value))) * $adjust),'0') < $adjust/10)) + return $value; + + return (intval($value * $adjust)) / $adjust; + } // function TRUNC() + +} // class PHPExcel_Calculation_MathTrig diff --git a/lib/phpexcel/PHPExcel/Calculation/Statistical.php b/lib/phpexcel/PHPExcel/Calculation/Statistical.php new file mode 100644 index 0000000..32b9c78 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Calculation/Statistical.php @@ -0,0 +1,3651 @@ + $value) { + if ((is_bool($value)) || (is_string($value)) || (is_null($value))) { + unset($array1[$key]); + unset($array2[$key]); + } + } + foreach($array2 as $key => $value) { + if ((is_bool($value)) || (is_string($value)) || (is_null($value))) { + unset($array1[$key]); + unset($array2[$key]); + } + } + $array1 = array_merge($array1); + $array2 = array_merge($array2); + + return True; + } // function _checkTrendArrays() + + + /** + * Beta function. + * + * @author Jaco van Kooten + * + * @param p require p>0 + * @param q require q>0 + * @return 0 if p<=0, q<=0 or p+q>2.55E305 to avoid errors and over/underflow + */ + private static function _beta($p, $q) { + if ($p <= 0.0 || $q <= 0.0 || ($p + $q) > LOG_GAMMA_X_MAX_VALUE) { + return 0.0; + } else { + return exp(self::_logBeta($p, $q)); + } + } // function _beta() + + + /** + * Incomplete beta function + * + * @author Jaco van Kooten + * @author Paul Meagher + * + * The computation is based on formulas from Numerical Recipes, Chapter 6.4 (W.H. Press et al, 1992). + * @param x require 0<=x<=1 + * @param p require p>0 + * @param q require q>0 + * @return 0 if x<0, p<=0, q<=0 or p+q>2.55E305 and 1 if x>1 to avoid errors and over/underflow + */ + private static function _incompleteBeta($x, $p, $q) { + if ($x <= 0.0) { + return 0.0; + } elseif ($x >= 1.0) { + return 1.0; + } elseif (($p <= 0.0) || ($q <= 0.0) || (($p + $q) > LOG_GAMMA_X_MAX_VALUE)) { + return 0.0; + } + $beta_gam = exp((0 - self::_logBeta($p, $q)) + $p * log($x) + $q * log(1.0 - $x)); + if ($x < ($p + 1.0) / ($p + $q + 2.0)) { + return $beta_gam * self::_betaFraction($x, $p, $q) / $p; + } else { + return 1.0 - ($beta_gam * self::_betaFraction(1 - $x, $q, $p) / $q); + } + } // function _incompleteBeta() + + + // Function cache for _logBeta function + private static $_logBetaCache_p = 0.0; + private static $_logBetaCache_q = 0.0; + private static $_logBetaCache_result = 0.0; + + /** + * The natural logarithm of the beta function. + * + * @param p require p>0 + * @param q require q>0 + * @return 0 if p<=0, q<=0 or p+q>2.55E305 to avoid errors and over/underflow + * @author Jaco van Kooten + */ + private static function _logBeta($p, $q) { + if ($p != self::$_logBetaCache_p || $q != self::$_logBetaCache_q) { + self::$_logBetaCache_p = $p; + self::$_logBetaCache_q = $q; + if (($p <= 0.0) || ($q <= 0.0) || (($p + $q) > LOG_GAMMA_X_MAX_VALUE)) { + self::$_logBetaCache_result = 0.0; + } else { + self::$_logBetaCache_result = self::_logGamma($p) + self::_logGamma($q) - self::_logGamma($p + $q); + } + } + return self::$_logBetaCache_result; + } // function _logBeta() + + + /** + * Evaluates of continued fraction part of incomplete beta function. + * Based on an idea from Numerical Recipes (W.H. Press et al, 1992). + * @author Jaco van Kooten + */ + private static function _betaFraction($x, $p, $q) { + $c = 1.0; + $sum_pq = $p + $q; + $p_plus = $p + 1.0; + $p_minus = $p - 1.0; + $h = 1.0 - $sum_pq * $x / $p_plus; + if (abs($h) < XMININ) { + $h = XMININ; + } + $h = 1.0 / $h; + $frac = $h; + $m = 1; + $delta = 0.0; + while ($m <= MAX_ITERATIONS && abs($delta-1.0) > PRECISION ) { + $m2 = 2 * $m; + // even index for d + $d = $m * ($q - $m) * $x / ( ($p_minus + $m2) * ($p + $m2)); + $h = 1.0 + $d * $h; + if (abs($h) < XMININ) { + $h = XMININ; + } + $h = 1.0 / $h; + $c = 1.0 + $d / $c; + if (abs($c) < XMININ) { + $c = XMININ; + } + $frac *= $h * $c; + // odd index for d + $d = -($p + $m) * ($sum_pq + $m) * $x / (($p + $m2) * ($p_plus + $m2)); + $h = 1.0 + $d * $h; + if (abs($h) < XMININ) { + $h = XMININ; + } + $h = 1.0 / $h; + $c = 1.0 + $d / $c; + if (abs($c) < XMININ) { + $c = XMININ; + } + $delta = $h * $c; + $frac *= $delta; + ++$m; + } + return $frac; + } // function _betaFraction() + + + /** + * logGamma function + * + * @version 1.1 + * @author Jaco van Kooten + * + * Original author was Jaco van Kooten. Ported to PHP by Paul Meagher. + * + * The natural logarithm of the gamma function.
            + * Based on public domain NETLIB (Fortran) code by W. J. Cody and L. Stoltz
            + * Applied Mathematics Division
            + * Argonne National Laboratory
            + * Argonne, IL 60439
            + *

            + * References: + *

              + *
            1. W. J. Cody and K. E. Hillstrom, 'Chebyshev Approximations for the Natural + * Logarithm of the Gamma Function,' Math. Comp. 21, 1967, pp. 198-203.
            2. + *
            3. K. E. Hillstrom, ANL/AMD Program ANLC366S, DGAMMA/DLGAMA, May, 1969.
            4. + *
            5. Hart, Et. Al., Computer Approximations, Wiley and sons, New York, 1968.
            6. + *
            + *

            + *

            + * From the original documentation: + *

            + *

            + * This routine calculates the LOG(GAMMA) function for a positive real argument X. + * Computation is based on an algorithm outlined in references 1 and 2. + * The program uses rational functions that theoretically approximate LOG(GAMMA) + * to at least 18 significant decimal digits. The approximation for X > 12 is from + * reference 3, while approximations for X < 12.0 are similar to those in reference + * 1, but are unpublished. The accuracy achieved depends on the arithmetic system, + * the compiler, the intrinsic functions, and proper selection of the + * machine-dependent constants. + *

            + *

            + * Error returns:
            + * The program returns the value XINF for X .LE. 0.0 or when overflow would occur. + * The computation is believed to be free of underflow and overflow. + *

            + * @return MAX_VALUE for x < 0.0 or when overflow would occur, i.e. x > 2.55E305 + */ + + // Function cache for logGamma + private static $_logGammaCache_result = 0.0; + private static $_logGammaCache_x = 0.0; + + private static function _logGamma($x) { + // Log Gamma related constants + static $lg_d1 = -0.5772156649015328605195174; + static $lg_d2 = 0.4227843350984671393993777; + static $lg_d4 = 1.791759469228055000094023; + + static $lg_p1 = array( 4.945235359296727046734888, + 201.8112620856775083915565, + 2290.838373831346393026739, + 11319.67205903380828685045, + 28557.24635671635335736389, + 38484.96228443793359990269, + 26377.48787624195437963534, + 7225.813979700288197698961 ); + static $lg_p2 = array( 4.974607845568932035012064, + 542.4138599891070494101986, + 15506.93864978364947665077, + 184793.2904445632425417223, + 1088204.76946882876749847, + 3338152.967987029735917223, + 5106661.678927352456275255, + 3074109.054850539556250927 ); + static $lg_p4 = array( 14745.02166059939948905062, + 2426813.369486704502836312, + 121475557.4045093227939592, + 2663432449.630976949898078, + 29403789566.34553899906876, + 170266573776.5398868392998, + 492612579337.743088758812, + 560625185622.3951465078242 ); + + static $lg_q1 = array( 67.48212550303777196073036, + 1113.332393857199323513008, + 7738.757056935398733233834, + 27639.87074403340708898585, + 54993.10206226157329794414, + 61611.22180066002127833352, + 36351.27591501940507276287, + 8785.536302431013170870835 ); + static $lg_q2 = array( 183.0328399370592604055942, + 7765.049321445005871323047, + 133190.3827966074194402448, + 1136705.821321969608938755, + 5267964.117437946917577538, + 13467014.54311101692290052, + 17827365.30353274213975932, + 9533095.591844353613395747 ); + static $lg_q4 = array( 2690.530175870899333379843, + 639388.5654300092398984238, + 41355999.30241388052042842, + 1120872109.61614794137657, + 14886137286.78813811542398, + 101680358627.2438228077304, + 341747634550.7377132798597, + 446315818741.9713286462081 ); + + static $lg_c = array( -0.001910444077728, + 8.4171387781295e-4, + -5.952379913043012e-4, + 7.93650793500350248e-4, + -0.002777777777777681622553, + 0.08333333333333333331554247, + 0.0057083835261 ); + + // Rough estimate of the fourth root of logGamma_xBig + static $lg_frtbig = 2.25e76; + static $pnt68 = 0.6796875; + + + if ($x == self::$_logGammaCache_x) { + return self::$_logGammaCache_result; + } + $y = $x; + if ($y > 0.0 && $y <= LOG_GAMMA_X_MAX_VALUE) { + if ($y <= EPS) { + $res = -log(y); + } elseif ($y <= 1.5) { + // --------------------- + // EPS .LT. X .LE. 1.5 + // --------------------- + if ($y < $pnt68) { + $corr = -log($y); + $xm1 = $y; + } else { + $corr = 0.0; + $xm1 = $y - 1.0; + } + if ($y <= 0.5 || $y >= $pnt68) { + $xden = 1.0; + $xnum = 0.0; + for ($i = 0; $i < 8; ++$i) { + $xnum = $xnum * $xm1 + $lg_p1[$i]; + $xden = $xden * $xm1 + $lg_q1[$i]; + } + $res = $corr + $xm1 * ($lg_d1 + $xm1 * ($xnum / $xden)); + } else { + $xm2 = $y - 1.0; + $xden = 1.0; + $xnum = 0.0; + for ($i = 0; $i < 8; ++$i) { + $xnum = $xnum * $xm2 + $lg_p2[$i]; + $xden = $xden * $xm2 + $lg_q2[$i]; + } + $res = $corr + $xm2 * ($lg_d2 + $xm2 * ($xnum / $xden)); + } + } elseif ($y <= 4.0) { + // --------------------- + // 1.5 .LT. X .LE. 4.0 + // --------------------- + $xm2 = $y - 2.0; + $xden = 1.0; + $xnum = 0.0; + for ($i = 0; $i < 8; ++$i) { + $xnum = $xnum * $xm2 + $lg_p2[$i]; + $xden = $xden * $xm2 + $lg_q2[$i]; + } + $res = $xm2 * ($lg_d2 + $xm2 * ($xnum / $xden)); + } elseif ($y <= 12.0) { + // ---------------------- + // 4.0 .LT. X .LE. 12.0 + // ---------------------- + $xm4 = $y - 4.0; + $xden = -1.0; + $xnum = 0.0; + for ($i = 0; $i < 8; ++$i) { + $xnum = $xnum * $xm4 + $lg_p4[$i]; + $xden = $xden * $xm4 + $lg_q4[$i]; + } + $res = $lg_d4 + $xm4 * ($xnum / $xden); + } else { + // --------------------------------- + // Evaluate for argument .GE. 12.0 + // --------------------------------- + $res = 0.0; + if ($y <= $lg_frtbig) { + $res = $lg_c[6]; + $ysq = $y * $y; + for ($i = 0; $i < 6; ++$i) + $res = $res / $ysq + $lg_c[$i]; + } + $res /= $y; + $corr = log($y); + $res = $res + log(SQRT2PI) - 0.5 * $corr; + $res += $y * ($corr - 1.0); + } + } else { + // -------------------------- + // Return for bad arguments + // -------------------------- + $res = MAX_VALUE; + } + // ------------------------------ + // Final adjustments and return + // ------------------------------ + self::$_logGammaCache_x = $x; + self::$_logGammaCache_result = $res; + return $res; + } // function _logGamma() + + + // + // Private implementation of the incomplete Gamma function + // + private static function _incompleteGamma($a,$x) { + static $max = 32; + $summer = 0; + for ($n=0; $n<=$max; ++$n) { + $divisor = $a; + for ($i=1; $i<=$n; ++$i) { + $divisor *= ($a + $i); + } + $summer += (pow($x,$n) / $divisor); + } + return pow($x,$a) * exp(0-$x) * $summer; + } // function _incompleteGamma() + + + // + // Private implementation of the Gamma function + // + private static function _gamma($data) { + if ($data == 0.0) return 0; + + static $p0 = 1.000000000190015; + static $p = array ( 1 => 76.18009172947146, + 2 => -86.50532032941677, + 3 => 24.01409824083091, + 4 => -1.231739572450155, + 5 => 1.208650973866179e-3, + 6 => -5.395239384953e-6 + ); + + $y = $x = $data; + $tmp = $x + 5.5; + $tmp -= ($x + 0.5) * log($tmp); + + $summer = $p0; + for ($j=1;$j<=6;++$j) { + $summer += ($p[$j] / ++$y); + } + return exp(0 - $tmp + log(SQRT2PI * $summer / $x)); + } // function _gamma() + + + /*************************************************************************** + * inverse_ncdf.php + * ------------------- + * begin : Friday, January 16, 2004 + * copyright : (C) 2004 Michael Nickerson + * email : nickersonm@yahoo.com + * + ***************************************************************************/ + private static function _inverse_ncdf($p) { + // Inverse ncdf approximation by Peter J. Acklam, implementation adapted to + // PHP by Michael Nickerson, using Dr. Thomas Ziegler's C implementation as + // a guide. http://home.online.no/~pjacklam/notes/invnorm/index.html + // I have not checked the accuracy of this implementation. Be aware that PHP + // will truncate the coeficcients to 14 digits. + + // You have permission to use and distribute this function freely for + // whatever purpose you want, but please show common courtesy and give credit + // where credit is due. + + // Input paramater is $p - probability - where 0 < p < 1. + + // Coefficients in rational approximations + static $a = array( 1 => -3.969683028665376e+01, + 2 => 2.209460984245205e+02, + 3 => -2.759285104469687e+02, + 4 => 1.383577518672690e+02, + 5 => -3.066479806614716e+01, + 6 => 2.506628277459239e+00 + ); + + static $b = array( 1 => -5.447609879822406e+01, + 2 => 1.615858368580409e+02, + 3 => -1.556989798598866e+02, + 4 => 6.680131188771972e+01, + 5 => -1.328068155288572e+01 + ); + + static $c = array( 1 => -7.784894002430293e-03, + 2 => -3.223964580411365e-01, + 3 => -2.400758277161838e+00, + 4 => -2.549732539343734e+00, + 5 => 4.374664141464968e+00, + 6 => 2.938163982698783e+00 + ); + + static $d = array( 1 => 7.784695709041462e-03, + 2 => 3.224671290700398e-01, + 3 => 2.445134137142996e+00, + 4 => 3.754408661907416e+00 + ); + + // Define lower and upper region break-points. + $p_low = 0.02425; //Use lower region approx. below this + $p_high = 1 - $p_low; //Use upper region approx. above this + + if (0 < $p && $p < $p_low) { + // Rational approximation for lower region. + $q = sqrt(-2 * log($p)); + return ((((($c[1] * $q + $c[2]) * $q + $c[3]) * $q + $c[4]) * $q + $c[5]) * $q + $c[6]) / + (((($d[1] * $q + $d[2]) * $q + $d[3]) * $q + $d[4]) * $q + 1); + } elseif ($p_low <= $p && $p <= $p_high) { + // Rational approximation for central region. + $q = $p - 0.5; + $r = $q * $q; + return ((((($a[1] * $r + $a[2]) * $r + $a[3]) * $r + $a[4]) * $r + $a[5]) * $r + $a[6]) * $q / + ((((($b[1] * $r + $b[2]) * $r + $b[3]) * $r + $b[4]) * $r + $b[5]) * $r + 1); + } elseif ($p_high < $p && $p < 1) { + // Rational approximation for upper region. + $q = sqrt(-2 * log(1 - $p)); + return -((((($c[1] * $q + $c[2]) * $q + $c[3]) * $q + $c[4]) * $q + $c[5]) * $q + $c[6]) / + (((($d[1] * $q + $d[2]) * $q + $d[3]) * $q + $d[4]) * $q + 1); + } + // If 0 < p < 1, return a null value + return PHPExcel_Calculation_Functions::NULL(); + } // function _inverse_ncdf() + + + private static function _inverse_ncdf2($prob) { + // Approximation of inverse standard normal CDF developed by + // B. Moro, "The Full Monte," Risk 8(2), Feb 1995, 57-58. + + $a1 = 2.50662823884; + $a2 = -18.61500062529; + $a3 = 41.39119773534; + $a4 = -25.44106049637; + + $b1 = -8.4735109309; + $b2 = 23.08336743743; + $b3 = -21.06224101826; + $b4 = 3.13082909833; + + $c1 = 0.337475482272615; + $c2 = 0.976169019091719; + $c3 = 0.160797971491821; + $c4 = 2.76438810333863E-02; + $c5 = 3.8405729373609E-03; + $c6 = 3.951896511919E-04; + $c7 = 3.21767881768E-05; + $c8 = 2.888167364E-07; + $c9 = 3.960315187E-07; + + $y = $prob - 0.5; + if (abs($y) < 0.42) { + $z = ($y * $y); + $z = $y * ((($a4 * $z + $a3) * $z + $a2) * $z + $a1) / (((($b4 * $z + $b3) * $z + $b2) * $z + $b1) * $z + 1); + } else { + if ($y > 0) { + $z = log(-log(1 - $prob)); + } else { + $z = log(-log($prob)); + } + $z = $c1 + $z * ($c2 + $z * ($c3 + $z * ($c4 + $z * ($c5 + $z * ($c6 + $z * ($c7 + $z * ($c8 + $z * $c9))))))); + if ($y < 0) { + $z = -$z; + } + } + return $z; + } // function _inverse_ncdf2() + + + private static function _inverse_ncdf3($p) { + // ALGORITHM AS241 APPL. STATIST. (1988) VOL. 37, NO. 3. + // Produces the normal deviate Z corresponding to a given lower + // tail area of P; Z is accurate to about 1 part in 10**16. + // + // This is a PHP version of the original FORTRAN code that can + // be found at http://lib.stat.cmu.edu/apstat/ + $split1 = 0.425; + $split2 = 5; + $const1 = 0.180625; + $const2 = 1.6; + + // coefficients for p close to 0.5 + $a0 = 3.3871328727963666080; + $a1 = 1.3314166789178437745E+2; + $a2 = 1.9715909503065514427E+3; + $a3 = 1.3731693765509461125E+4; + $a4 = 4.5921953931549871457E+4; + $a5 = 6.7265770927008700853E+4; + $a6 = 3.3430575583588128105E+4; + $a7 = 2.5090809287301226727E+3; + + $b1 = 4.2313330701600911252E+1; + $b2 = 6.8718700749205790830E+2; + $b3 = 5.3941960214247511077E+3; + $b4 = 2.1213794301586595867E+4; + $b5 = 3.9307895800092710610E+4; + $b6 = 2.8729085735721942674E+4; + $b7 = 5.2264952788528545610E+3; + + // coefficients for p not close to 0, 0.5 or 1. + $c0 = 1.42343711074968357734; + $c1 = 4.63033784615654529590; + $c2 = 5.76949722146069140550; + $c3 = 3.64784832476320460504; + $c4 = 1.27045825245236838258; + $c5 = 2.41780725177450611770E-1; + $c6 = 2.27238449892691845833E-2; + $c7 = 7.74545014278341407640E-4; + + $d1 = 2.05319162663775882187; + $d2 = 1.67638483018380384940; + $d3 = 6.89767334985100004550E-1; + $d4 = 1.48103976427480074590E-1; + $d5 = 1.51986665636164571966E-2; + $d6 = 5.47593808499534494600E-4; + $d7 = 1.05075007164441684324E-9; + + // coefficients for p near 0 or 1. + $e0 = 6.65790464350110377720; + $e1 = 5.46378491116411436990; + $e2 = 1.78482653991729133580; + $e3 = 2.96560571828504891230E-1; + $e4 = 2.65321895265761230930E-2; + $e5 = 1.24266094738807843860E-3; + $e6 = 2.71155556874348757815E-5; + $e7 = 2.01033439929228813265E-7; + + $f1 = 5.99832206555887937690E-1; + $f2 = 1.36929880922735805310E-1; + $f3 = 1.48753612908506148525E-2; + $f4 = 7.86869131145613259100E-4; + $f5 = 1.84631831751005468180E-5; + $f6 = 1.42151175831644588870E-7; + $f7 = 2.04426310338993978564E-15; + + $q = $p - 0.5; + + // computation for p close to 0.5 + if (abs($q) <= split1) { + $R = $const1 - $q * $q; + $z = $q * ((((((($a7 * $R + $a6) * $R + $a5) * $R + $a4) * $R + $a3) * $R + $a2) * $R + $a1) * $R + $a0) / + ((((((($b7 * $R + $b6) * $R + $b5) * $R + $b4) * $R + $b3) * $R + $b2) * $R + $b1) * $R + 1); + } else { + if ($q < 0) { + $R = $p; + } else { + $R = 1 - $p; + } + $R = pow(-log($R),2); + + // computation for p not close to 0, 0.5 or 1. + If ($R <= $split2) { + $R = $R - $const2; + $z = ((((((($c7 * $R + $c6) * $R + $c5) * $R + $c4) * $R + $c3) * $R + $c2) * $R + $c1) * $R + $c0) / + ((((((($d7 * $R + $d6) * $R + $d5) * $R + $d4) * $R + $d3) * $R + $d2) * $R + $d1) * $R + 1); + } else { + // computation for p near 0 or 1. + $R = $R - $split2; + $z = ((((((($e7 * $R + $e6) * $R + $e5) * $R + $e4) * $R + $e3) * $R + $e2) * $R + $e1) * $R + $e0) / + ((((((($f7 * $R + $f6) * $R + $f5) * $R + $f4) * $R + $f3) * $R + $f2) * $R + $f1) * $R + 1); + } + if ($q < 0) { + $z = -$z; + } + } + return $z; + } // function _inverse_ncdf3() + + + /** + * AVEDEV + * + * Returns the average of the absolute deviations of data points from their mean. + * AVEDEV is a measure of the variability in a data set. + * + * Excel Function: + * AVEDEV(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function AVEDEV() { + $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); + + // Return value + $returnValue = null; + + $aMean = self::AVERAGE($aArgs); + if ($aMean != PHPExcel_Calculation_Functions::DIV0()) { + $aCount = 0; + foreach ($aArgs as $k => $arg) { + if ((is_bool($arg)) && + ((!PHPExcel_Calculation_Functions::isCellValue($k)) || (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE))) { + $arg = (integer) $arg; + } + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + if (is_null($returnValue)) { + $returnValue = abs($arg - $aMean); + } else { + $returnValue += abs($arg - $aMean); + } + ++$aCount; + } + } + + // Return + if ($aCount == 0) { + return PHPExcel_Calculation_Functions::DIV0(); + } + return $returnValue / $aCount; + } + return PHPExcel_Calculation_Functions::NaN(); + } // function AVEDEV() + + + /** + * AVERAGE + * + * Returns the average (arithmetic mean) of the arguments + * + * Excel Function: + * AVERAGE(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function AVERAGE() { + $returnValue = $aCount = 0; + + // Loop through arguments + foreach (PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()) as $k => $arg) { + if ((is_bool($arg)) && + ((!PHPExcel_Calculation_Functions::isCellValue($k)) || (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE))) { + $arg = (integer) $arg; + } + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + if (is_null($returnValue)) { + $returnValue = $arg; + } else { + $returnValue += $arg; + } + ++$aCount; + } + } + + // Return + if ($aCount > 0) { + return $returnValue / $aCount; + } else { + return PHPExcel_Calculation_Functions::DIV0(); + } + } // function AVERAGE() + + + /** + * AVERAGEA + * + * Returns the average of its arguments, including numbers, text, and logical values + * + * Excel Function: + * AVERAGEA(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function AVERAGEA() { + // Return value + $returnValue = null; + + $aCount = 0; + // Loop through arguments + foreach (PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()) as $k => $arg) { + if ((is_bool($arg)) && + (!PHPExcel_Calculation_Functions::isMatrixValue($k))) { + } else { + if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) { + if (is_bool($arg)) { + $arg = (integer) $arg; + } elseif (is_string($arg)) { + $arg = 0; + } + if (is_null($returnValue)) { + $returnValue = $arg; + } else { + $returnValue += $arg; + } + ++$aCount; + } + } + } + + // Return + if ($aCount > 0) { + return $returnValue / $aCount; + } else { + return PHPExcel_Calculation_Functions::DIV0(); + } + } // function AVERAGEA() + + + /** + * AVERAGEIF + * + * Returns the average value from a range of cells that contain numbers within the list of arguments + * + * Excel Function: + * AVERAGEIF(value1[,value2[, ...]],condition) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param mixed $arg,... Data values + * @param string $condition The criteria that defines which cells will be checked. + * @param mixed[] $averageArgs Data values + * @return float + */ + public static function AVERAGEIF($aArgs,$condition,$averageArgs = array()) { + // Return value + $returnValue = 0; + + $aArgs = PHPExcel_Calculation_Functions::flattenArray($aArgs); + $averageArgs = PHPExcel_Calculation_Functions::flattenArray($averageArgs); + if (empty($averageArgs)) { + $averageArgs = $aArgs; + } + $condition = PHPExcel_Calculation_Functions::_ifCondition($condition); + // Loop through arguments + $aCount = 0; + foreach ($aArgs as $key => $arg) { + if (!is_numeric($arg)) { $arg = PHPExcel_Calculation::_wrapResult(strtoupper($arg)); } + $testCondition = '='.$arg.$condition; + if (PHPExcel_Calculation::getInstance()->_calculateFormulaValue($testCondition)) { + if ((is_null($returnValue)) || ($arg > $returnValue)) { + $returnValue += $arg; + ++$aCount; + } + } + } + + // Return + if ($aCount > 0) { + return $returnValue / $aCount; + } else { + return PHPExcel_Calculation_Functions::DIV0(); + } + } // function AVERAGEIF() + + + /** + * BETADIST + * + * Returns the beta distribution. + * + * @param float $value Value at which you want to evaluate the distribution + * @param float $alpha Parameter to the distribution + * @param float $beta Parameter to the distribution + * @param boolean $cumulative + * @return float + * + */ + public static function BETADIST($value,$alpha,$beta,$rMin=0,$rMax=1) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $alpha = PHPExcel_Calculation_Functions::flattenSingleValue($alpha); + $beta = PHPExcel_Calculation_Functions::flattenSingleValue($beta); + $rMin = PHPExcel_Calculation_Functions::flattenSingleValue($rMin); + $rMax = PHPExcel_Calculation_Functions::flattenSingleValue($rMax); + + if ((is_numeric($value)) && (is_numeric($alpha)) && (is_numeric($beta)) && (is_numeric($rMin)) && (is_numeric($rMax))) { + if (($value < $rMin) || ($value > $rMax) || ($alpha <= 0) || ($beta <= 0) || ($rMin == $rMax)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ($rMin > $rMax) { + $tmp = $rMin; + $rMin = $rMax; + $rMax = $tmp; + } + $value -= $rMin; + $value /= ($rMax - $rMin); + return self::_incompleteBeta($value,$alpha,$beta); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function BETADIST() + + + /** + * BETAINV + * + * Returns the inverse of the beta distribution. + * + * @param float $probability Probability at which you want to evaluate the distribution + * @param float $alpha Parameter to the distribution + * @param float $beta Parameter to the distribution + * @param float $rMin Minimum value + * @param float $rMax Maximum value + * @param boolean $cumulative + * @return float + * + */ + public static function BETAINV($probability,$alpha,$beta,$rMin=0,$rMax=1) { + $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); + $alpha = PHPExcel_Calculation_Functions::flattenSingleValue($alpha); + $beta = PHPExcel_Calculation_Functions::flattenSingleValue($beta); + $rMin = PHPExcel_Calculation_Functions::flattenSingleValue($rMin); + $rMax = PHPExcel_Calculation_Functions::flattenSingleValue($rMax); + + if ((is_numeric($probability)) && (is_numeric($alpha)) && (is_numeric($beta)) && (is_numeric($rMin)) && (is_numeric($rMax))) { + if (($alpha <= 0) || ($beta <= 0) || ($rMin == $rMax) || ($probability <= 0) || ($probability > 1)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ($rMin > $rMax) { + $tmp = $rMin; + $rMin = $rMax; + $rMax = $tmp; + } + $a = 0; + $b = 2; + + $i = 0; + while ((($b - $a) > PRECISION) && ($i++ < MAX_ITERATIONS)) { + $guess = ($a + $b) / 2; + $result = self::BETADIST($guess, $alpha, $beta); + if (($result == $probability) || ($result == 0)) { + $b = $a; + } elseif ($result > $probability) { + $b = $guess; + } else { + $a = $guess; + } + } + if ($i == MAX_ITERATIONS) { + return PHPExcel_Calculation_Functions::NA(); + } + return round($rMin + $guess * ($rMax - $rMin),12); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function BETAINV() + + + /** + * BINOMDIST + * + * Returns the individual term binomial distribution probability. Use BINOMDIST in problems with + * a fixed number of tests or trials, when the outcomes of any trial are only success or failure, + * when trials are independent, and when the probability of success is constant throughout the + * experiment. For example, BINOMDIST can calculate the probability that two of the next three + * babies born are male. + * + * @param float $value Number of successes in trials + * @param float $trials Number of trials + * @param float $probability Probability of success on each trial + * @param boolean $cumulative + * @return float + * + * @todo Cumulative distribution function + * + */ + public static function BINOMDIST($value, $trials, $probability, $cumulative) { + $value = floor(PHPExcel_Calculation_Functions::flattenSingleValue($value)); + $trials = floor(PHPExcel_Calculation_Functions::flattenSingleValue($trials)); + $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); + + if ((is_numeric($value)) && (is_numeric($trials)) && (is_numeric($probability))) { + if (($value < 0) || ($value > $trials)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if (($probability < 0) || ($probability > 1)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ((is_numeric($cumulative)) || (is_bool($cumulative))) { + if ($cumulative) { + $summer = 0; + for ($i = 0; $i <= $value; ++$i) { + $summer += PHPExcel_Calculation_MathTrig::COMBIN($trials,$i) * pow($probability,$i) * pow(1 - $probability,$trials - $i); + } + return $summer; + } else { + return PHPExcel_Calculation_MathTrig::COMBIN($trials,$value) * pow($probability,$value) * pow(1 - $probability,$trials - $value) ; + } + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function BINOMDIST() + + + /** + * CHIDIST + * + * Returns the one-tailed probability of the chi-squared distribution. + * + * @param float $value Value for the function + * @param float $degrees degrees of freedom + * @return float + */ + public static function CHIDIST($value, $degrees) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $degrees = floor(PHPExcel_Calculation_Functions::flattenSingleValue($degrees)); + + if ((is_numeric($value)) && (is_numeric($degrees))) { + if ($degrees < 1) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ($value < 0) { + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) { + return 1; + } + return PHPExcel_Calculation_Functions::NaN(); + } + return 1 - (self::_incompleteGamma($degrees/2,$value/2) / self::_gamma($degrees/2)); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function CHIDIST() + + + /** + * CHIINV + * + * Returns the one-tailed probability of the chi-squared distribution. + * + * @param float $probability Probability for the function + * @param float $degrees degrees of freedom + * @return float + */ + public static function CHIINV($probability, $degrees) { + $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); + $degrees = floor(PHPExcel_Calculation_Functions::flattenSingleValue($degrees)); + + if ((is_numeric($probability)) && (is_numeric($degrees))) { + + $xLo = 100; + $xHi = 0; + + $x = $xNew = 1; + $dx = 1; + $i = 0; + + while ((abs($dx) > PRECISION) && ($i++ < MAX_ITERATIONS)) { + // Apply Newton-Raphson step + $result = self::CHIDIST($x, $degrees); + $error = $result - $probability; + if ($error == 0.0) { + $dx = 0; + } elseif ($error < 0.0) { + $xLo = $x; + } else { + $xHi = $x; + } + // Avoid division by zero + if ($result != 0.0) { + $dx = $error / $result; + $xNew = $x - $dx; + } + // If the NR fails to converge (which for example may be the + // case if the initial guess is too rough) we apply a bisection + // step to determine a more narrow interval around the root. + if (($xNew < $xLo) || ($xNew > $xHi) || ($result == 0.0)) { + $xNew = ($xLo + $xHi) / 2; + $dx = $xNew - $x; + } + $x = $xNew; + } + if ($i == MAX_ITERATIONS) { + return PHPExcel_Calculation_Functions::NA(); + } + return round($x,12); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function CHIINV() + + + /** + * CONFIDENCE + * + * Returns the confidence interval for a population mean + * + * @param float $alpha + * @param float $stdDev Standard Deviation + * @param float $size + * @return float + * + */ + public static function CONFIDENCE($alpha,$stdDev,$size) { + $alpha = PHPExcel_Calculation_Functions::flattenSingleValue($alpha); + $stdDev = PHPExcel_Calculation_Functions::flattenSingleValue($stdDev); + $size = floor(PHPExcel_Calculation_Functions::flattenSingleValue($size)); + + if ((is_numeric($alpha)) && (is_numeric($stdDev)) && (is_numeric($size))) { + if (($alpha <= 0) || ($alpha >= 1)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if (($stdDev <= 0) || ($size < 1)) { + return PHPExcel_Calculation_Functions::NaN(); + } + return self::NORMSINV(1 - $alpha / 2) * $stdDev / sqrt($size); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function CONFIDENCE() + + + /** + * CORREL + * + * Returns covariance, the average of the products of deviations for each data point pair. + * + * @param array of mixed Data Series Y + * @param array of mixed Data Series X + * @return float + */ + public static function CORREL($yValues,$xValues=null) { + if ((is_null($xValues)) || (!is_array($yValues)) || (!is_array($xValues))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + if (!self::_checkTrendArrays($yValues,$xValues)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $yValueCount = count($yValues); + $xValueCount = count($xValues); + + if (($yValueCount == 0) || ($yValueCount != $xValueCount)) { + return PHPExcel_Calculation_Functions::NA(); + } elseif ($yValueCount == 1) { + return PHPExcel_Calculation_Functions::DIV0(); + } + + $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues); + return $bestFitLinear->getCorrelation(); + } // function CORREL() + + + /** + * COUNT + * + * Counts the number of cells that contain numbers within the list of arguments + * + * Excel Function: + * COUNT(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return int + */ + public static function COUNT() { + // Return value + $returnValue = 0; + + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); + foreach ($aArgs as $k => $arg) { + if ((is_bool($arg)) && + ((!PHPExcel_Calculation_Functions::isCellValue($k)) || (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE))) { + $arg = (integer) $arg; + } + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + ++$returnValue; + } + } + + // Return + return $returnValue; + } // function COUNT() + + + /** + * COUNTA + * + * Counts the number of cells that are not empty within the list of arguments + * + * Excel Function: + * COUNTA(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return int + */ + public static function COUNTA() { + // Return value + $returnValue = 0; + + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + foreach ($aArgs as $arg) { + // Is it a numeric, boolean or string value? + if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) { + ++$returnValue; + } + } + + // Return + return $returnValue; + } // function COUNTA() + + + /** + * COUNTBLANK + * + * Counts the number of empty cells within the list of arguments + * + * Excel Function: + * COUNTBLANK(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return int + */ + public static function COUNTBLANK() { + // Return value + $returnValue = 0; + + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + foreach ($aArgs as $arg) { + // Is it a blank cell? + if ((is_null($arg)) || ((is_string($arg)) && ($arg == ''))) { + ++$returnValue; + } + } + + // Return + return $returnValue; + } // function COUNTBLANK() + + + /** + * COUNTIF + * + * Counts the number of cells that contain numbers within the list of arguments + * + * Excel Function: + * COUNTIF(value1[,value2[, ...]],condition) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @param string $condition The criteria that defines which cells will be counted. + * @return int + */ + public static function COUNTIF($aArgs,$condition) { + // Return value + $returnValue = 0; + + $aArgs = PHPExcel_Calculation_Functions::flattenArray($aArgs); + $condition = PHPExcel_Calculation_Functions::_ifCondition($condition); + // Loop through arguments + foreach ($aArgs as $arg) { + if (!is_numeric($arg)) { $arg = PHPExcel_Calculation::_wrapResult(strtoupper($arg)); } + $testCondition = '='.$arg.$condition; + if (PHPExcel_Calculation::getInstance()->_calculateFormulaValue($testCondition)) { + // Is it a value within our criteria + ++$returnValue; + } + } + + // Return + return $returnValue; + } // function COUNTIF() + + + /** + * COVAR + * + * Returns covariance, the average of the products of deviations for each data point pair. + * + * @param array of mixed Data Series Y + * @param array of mixed Data Series X + * @return float + */ + public static function COVAR($yValues,$xValues) { + if (!self::_checkTrendArrays($yValues,$xValues)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $yValueCount = count($yValues); + $xValueCount = count($xValues); + + if (($yValueCount == 0) || ($yValueCount != $xValueCount)) { + return PHPExcel_Calculation_Functions::NA(); + } elseif ($yValueCount == 1) { + return PHPExcel_Calculation_Functions::DIV0(); + } + + $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues); + return $bestFitLinear->getCovariance(); + } // function COVAR() + + + /** + * CRITBINOM + * + * Returns the smallest value for which the cumulative binomial distribution is greater + * than or equal to a criterion value + * + * See http://support.microsoft.com/kb/828117/ for details of the algorithm used + * + * @param float $trials number of Bernoulli trials + * @param float $probability probability of a success on each trial + * @param float $alpha criterion value + * @return int + * + * @todo Warning. This implementation differs from the algorithm detailed on the MS + * web site in that $CumPGuessMinus1 = $CumPGuess - 1 rather than $CumPGuess - $PGuess + * This eliminates a potential endless loop error, but may have an adverse affect on the + * accuracy of the function (although all my tests have so far returned correct results). + * + */ + public static function CRITBINOM($trials, $probability, $alpha) { + $trials = floor(PHPExcel_Calculation_Functions::flattenSingleValue($trials)); + $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); + $alpha = PHPExcel_Calculation_Functions::flattenSingleValue($alpha); + + if ((is_numeric($trials)) && (is_numeric($probability)) && (is_numeric($alpha))) { + if ($trials < 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + if (($probability < 0) || ($probability > 1)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if (($alpha < 0) || ($alpha > 1)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ($alpha <= 0.5) { + $t = sqrt(log(1 / ($alpha * $alpha))); + $trialsApprox = 0 - ($t + (2.515517 + 0.802853 * $t + 0.010328 * $t * $t) / (1 + 1.432788 * $t + 0.189269 * $t * $t + 0.001308 * $t * $t * $t)); + } else { + $t = sqrt(log(1 / pow(1 - $alpha,2))); + $trialsApprox = $t - (2.515517 + 0.802853 * $t + 0.010328 * $t * $t) / (1 + 1.432788 * $t + 0.189269 * $t * $t + 0.001308 * $t * $t * $t); + } + $Guess = floor($trials * $probability + $trialsApprox * sqrt($trials * $probability * (1 - $probability))); + if ($Guess < 0) { + $Guess = 0; + } elseif ($Guess > $trials) { + $Guess = $trials; + } + + $TotalUnscaledProbability = $UnscaledPGuess = $UnscaledCumPGuess = 0.0; + $EssentiallyZero = 10e-12; + + $m = floor($trials * $probability); + ++$TotalUnscaledProbability; + if ($m == $Guess) { ++$UnscaledPGuess; } + if ($m <= $Guess) { ++$UnscaledCumPGuess; } + + $PreviousValue = 1; + $Done = False; + $k = $m + 1; + while ((!$Done) && ($k <= $trials)) { + $CurrentValue = $PreviousValue * ($trials - $k + 1) * $probability / ($k * (1 - $probability)); + $TotalUnscaledProbability += $CurrentValue; + if ($k == $Guess) { $UnscaledPGuess += $CurrentValue; } + if ($k <= $Guess) { $UnscaledCumPGuess += $CurrentValue; } + if ($CurrentValue <= $EssentiallyZero) { $Done = True; } + $PreviousValue = $CurrentValue; + ++$k; + } + + $PreviousValue = 1; + $Done = False; + $k = $m - 1; + while ((!$Done) && ($k >= 0)) { + $CurrentValue = $PreviousValue * $k + 1 * (1 - $probability) / (($trials - $k) * $probability); + $TotalUnscaledProbability += $CurrentValue; + if ($k == $Guess) { $UnscaledPGuess += $CurrentValue; } + if ($k <= $Guess) { $UnscaledCumPGuess += $CurrentValue; } + if ($CurrentValue <= $EssentiallyZero) { $Done = True; } + $PreviousValue = $CurrentValue; + --$k; + } + + $PGuess = $UnscaledPGuess / $TotalUnscaledProbability; + $CumPGuess = $UnscaledCumPGuess / $TotalUnscaledProbability; + +// $CumPGuessMinus1 = $CumPGuess - $PGuess; + $CumPGuessMinus1 = $CumPGuess - 1; + + while (True) { + if (($CumPGuessMinus1 < $alpha) && ($CumPGuess >= $alpha)) { + return $Guess; + } elseif (($CumPGuessMinus1 < $alpha) && ($CumPGuess < $alpha)) { + $PGuessPlus1 = $PGuess * ($trials - $Guess) * $probability / $Guess / (1 - $probability); + $CumPGuessMinus1 = $CumPGuess; + $CumPGuess = $CumPGuess + $PGuessPlus1; + $PGuess = $PGuessPlus1; + ++$Guess; + } elseif (($CumPGuessMinus1 >= $alpha) && ($CumPGuess >= $alpha)) { + $PGuessMinus1 = $PGuess * $Guess * (1 - $probability) / ($trials - $Guess + 1) / $probability; + $CumPGuess = $CumPGuessMinus1; + $CumPGuessMinus1 = $CumPGuessMinus1 - $PGuess; + $PGuess = $PGuessMinus1; + --$Guess; + } + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function CRITBINOM() + + + /** + * DEVSQ + * + * Returns the sum of squares of deviations of data points from their sample mean. + * + * Excel Function: + * DEVSQ(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function DEVSQ() { + $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); + + // Return value + $returnValue = null; + + $aMean = self::AVERAGE($aArgs); + if ($aMean != PHPExcel_Calculation_Functions::DIV0()) { + $aCount = -1; + foreach ($aArgs as $k => $arg) { + // Is it a numeric value? + if ((is_bool($arg)) && + ((!PHPExcel_Calculation_Functions::isCellValue($k)) || (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE))) { + $arg = (integer) $arg; + } + if ((is_numeric($arg)) && (!is_string($arg))) { + if (is_null($returnValue)) { + $returnValue = pow(($arg - $aMean),2); + } else { + $returnValue += pow(($arg - $aMean),2); + } + ++$aCount; + } + } + + // Return + if (is_null($returnValue)) { + return PHPExcel_Calculation_Functions::NaN(); + } else { + return $returnValue; + } + } + return self::NA(); + } // function DEVSQ() + + + /** + * EXPONDIST + * + * Returns the exponential distribution. Use EXPONDIST to model the time between events, + * such as how long an automated bank teller takes to deliver cash. For example, you can + * use EXPONDIST to determine the probability that the process takes at most 1 minute. + * + * @param float $value Value of the function + * @param float $lambda The parameter value + * @param boolean $cumulative + * @return float + */ + public static function EXPONDIST($value, $lambda, $cumulative) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $lambda = PHPExcel_Calculation_Functions::flattenSingleValue($lambda); + $cumulative = PHPExcel_Calculation_Functions::flattenSingleValue($cumulative); + + if ((is_numeric($value)) && (is_numeric($lambda))) { + if (($value < 0) || ($lambda < 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ((is_numeric($cumulative)) || (is_bool($cumulative))) { + if ($cumulative) { + return 1 - exp(0-$value*$lambda); + } else { + return $lambda * exp(0-$value*$lambda); + } + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function EXPONDIST() + + + /** + * FISHER + * + * Returns the Fisher transformation at x. This transformation produces a function that + * is normally distributed rather than skewed. Use this function to perform hypothesis + * testing on the correlation coefficient. + * + * @param float $value + * @return float + */ + public static function FISHER($value) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + + if (is_numeric($value)) { + if (($value <= -1) || ($value >= 1)) { + return PHPExcel_Calculation_Functions::NaN(); + } + return 0.5 * log((1+$value)/(1-$value)); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function FISHER() + + + /** + * FISHERINV + * + * Returns the inverse of the Fisher transformation. Use this transformation when + * analyzing correlations between ranges or arrays of data. If y = FISHER(x), then + * FISHERINV(y) = x. + * + * @param float $value + * @return float + */ + public static function FISHERINV($value) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + + if (is_numeric($value)) { + return (exp(2 * $value) - 1) / (exp(2 * $value) + 1); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function FISHERINV() + + + /** + * FORECAST + * + * Calculates, or predicts, a future value by using existing values. The predicted value is a y-value for a given x-value. + * + * @param float Value of X for which we want to find Y + * @param array of mixed Data Series Y + * @param array of mixed Data Series X + * @return float + */ + public static function FORECAST($xValue,$yValues,$xValues) { + $xValue = PHPExcel_Calculation_Functions::flattenSingleValue($xValue); + if (!is_numeric($xValue)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (!self::_checkTrendArrays($yValues,$xValues)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $yValueCount = count($yValues); + $xValueCount = count($xValues); + + if (($yValueCount == 0) || ($yValueCount != $xValueCount)) { + return PHPExcel_Calculation_Functions::NA(); + } elseif ($yValueCount == 1) { + return PHPExcel_Calculation_Functions::DIV0(); + } + + $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues); + return $bestFitLinear->getValueOfYForX($xValue); + } // function FORECAST() + + + /** + * GAMMADIST + * + * Returns the gamma distribution. + * + * @param float $value Value at which you want to evaluate the distribution + * @param float $a Parameter to the distribution + * @param float $b Parameter to the distribution + * @param boolean $cumulative + * @return float + * + */ + public static function GAMMADIST($value,$a,$b,$cumulative) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $a = PHPExcel_Calculation_Functions::flattenSingleValue($a); + $b = PHPExcel_Calculation_Functions::flattenSingleValue($b); + + if ((is_numeric($value)) && (is_numeric($a)) && (is_numeric($b))) { + if (($value < 0) || ($a <= 0) || ($b <= 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ((is_numeric($cumulative)) || (is_bool($cumulative))) { + if ($cumulative) { + return self::_incompleteGamma($a,$value / $b) / self::_gamma($a); + } else { + return (1 / (pow($b,$a) * self::_gamma($a))) * pow($value,$a-1) * exp(0-($value / $b)); + } + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function GAMMADIST() + + + /** + * GAMMAINV + * + * Returns the inverse of the beta distribution. + * + * @param float $probability Probability at which you want to evaluate the distribution + * @param float $alpha Parameter to the distribution + * @param float $beta Parameter to the distribution + * @return float + * + */ + public static function GAMMAINV($probability,$alpha,$beta) { + $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); + $alpha = PHPExcel_Calculation_Functions::flattenSingleValue($alpha); + $beta = PHPExcel_Calculation_Functions::flattenSingleValue($beta); + + if ((is_numeric($probability)) && (is_numeric($alpha)) && (is_numeric($beta))) { + if (($alpha <= 0) || ($beta <= 0) || ($probability < 0) || ($probability > 1)) { + return PHPExcel_Calculation_Functions::NaN(); + } + + $xLo = 0; + $xHi = $alpha * $beta * 5; + + $x = $xNew = 1; + $error = $pdf = 0; + $dx = 1024; + $i = 0; + + while ((abs($dx) > PRECISION) && ($i++ < MAX_ITERATIONS)) { + // Apply Newton-Raphson step + $error = self::GAMMADIST($x, $alpha, $beta, True) - $probability; + if ($error < 0.0) { + $xLo = $x; + } else { + $xHi = $x; + } + $pdf = self::GAMMADIST($x, $alpha, $beta, False); + // Avoid division by zero + if ($pdf != 0.0) { + $dx = $error / $pdf; + $xNew = $x - $dx; + } + // If the NR fails to converge (which for example may be the + // case if the initial guess is too rough) we apply a bisection + // step to determine a more narrow interval around the root. + if (($xNew < $xLo) || ($xNew > $xHi) || ($pdf == 0.0)) { + $xNew = ($xLo + $xHi) / 2; + $dx = $xNew - $x; + } + $x = $xNew; + } + if ($i == MAX_ITERATIONS) { + return PHPExcel_Calculation_Functions::NA(); + } + return $x; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function GAMMAINV() + + + /** + * GAMMALN + * + * Returns the natural logarithm of the gamma function. + * + * @param float $value + * @return float + */ + public static function GAMMALN($value) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + + if (is_numeric($value)) { + if ($value <= 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + return log(self::_gamma($value)); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function GAMMALN() + + + /** + * GEOMEAN + * + * Returns the geometric mean of an array or range of positive data. For example, you + * can use GEOMEAN to calculate average growth rate given compound interest with + * variable rates. + * + * Excel Function: + * GEOMEAN(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function GEOMEAN() { + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + + $aMean = PHPExcel_Calculation_MathTrig::PRODUCT($aArgs); + if (is_numeric($aMean) && ($aMean > 0)) { + $aCount = self::COUNT($aArgs) ; + if (self::MIN($aArgs) > 0) { + return pow($aMean, (1 / $aCount)); + } + } + return PHPExcel_Calculation_Functions::NaN(); + } // GEOMEAN() + + + /** + * GROWTH + * + * Returns values along a predicted emponential trend + * + * @param array of mixed Data Series Y + * @param array of mixed Data Series X + * @param array of mixed Values of X for which we want to find Y + * @param boolean A logical value specifying whether to force the intersect to equal 0. + * @return array of float + */ + public static function GROWTH($yValues,$xValues=array(),$newValues=array(),$const=True) { + $yValues = PHPExcel_Calculation_Functions::flattenArray($yValues); + $xValues = PHPExcel_Calculation_Functions::flattenArray($xValues); + $newValues = PHPExcel_Calculation_Functions::flattenArray($newValues); + $const = (is_null($const)) ? True : (boolean) PHPExcel_Calculation_Functions::flattenSingleValue($const); + + $bestFitExponential = trendClass::calculate(trendClass::TREND_EXPONENTIAL,$yValues,$xValues,$const); + if (empty($newValues)) { + $newValues = $bestFitExponential->getXValues(); + } + + $returnArray = array(); + foreach($newValues as $xValue) { + $returnArray[0][] = $bestFitExponential->getValueOfYForX($xValue); + } + + return $returnArray; + } // function GROWTH() + + + /** + * HARMEAN + * + * Returns the harmonic mean of a data set. The harmonic mean is the reciprocal of the + * arithmetic mean of reciprocals. + * + * Excel Function: + * HARMEAN(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function HARMEAN() { + // Return value + $returnValue = PHPExcel_Calculation_Functions::NA(); + + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + if (self::MIN($aArgs) < 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + $aCount = 0; + foreach ($aArgs as $arg) { + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + if ($arg <= 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + if (is_null($returnValue)) { + $returnValue = (1 / $arg); + } else { + $returnValue += (1 / $arg); + } + ++$aCount; + } + } + + // Return + if ($aCount > 0) { + return 1 / ($returnValue / $aCount); + } else { + return $returnValue; + } + } // function HARMEAN() + + + /** + * HYPGEOMDIST + * + * Returns the hypergeometric distribution. HYPGEOMDIST returns the probability of a given number of + * sample successes, given the sample size, population successes, and population size. + * + * @param float $sampleSuccesses Number of successes in the sample + * @param float $sampleNumber Size of the sample + * @param float $populationSuccesses Number of successes in the population + * @param float $populationNumber Population size + * @return float + * + */ + public static function HYPGEOMDIST($sampleSuccesses, $sampleNumber, $populationSuccesses, $populationNumber) { + $sampleSuccesses = floor(PHPExcel_Calculation_Functions::flattenSingleValue($sampleSuccesses)); + $sampleNumber = floor(PHPExcel_Calculation_Functions::flattenSingleValue($sampleNumber)); + $populationSuccesses = floor(PHPExcel_Calculation_Functions::flattenSingleValue($populationSuccesses)); + $populationNumber = floor(PHPExcel_Calculation_Functions::flattenSingleValue($populationNumber)); + + if ((is_numeric($sampleSuccesses)) && (is_numeric($sampleNumber)) && (is_numeric($populationSuccesses)) && (is_numeric($populationNumber))) { + if (($sampleSuccesses < 0) || ($sampleSuccesses > $sampleNumber) || ($sampleSuccesses > $populationSuccesses)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if (($sampleNumber <= 0) || ($sampleNumber > $populationNumber)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if (($populationSuccesses <= 0) || ($populationSuccesses > $populationNumber)) { + return PHPExcel_Calculation_Functions::NaN(); + } + return PHPExcel_Calculation_MathTrig::COMBIN($populationSuccesses,$sampleSuccesses) * + PHPExcel_Calculation_MathTrig::COMBIN($populationNumber - $populationSuccesses,$sampleNumber - $sampleSuccesses) / + PHPExcel_Calculation_MathTrig::COMBIN($populationNumber,$sampleNumber); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function HYPGEOMDIST() + + + /** + * INTERCEPT + * + * Calculates the point at which a line will intersect the y-axis by using existing x-values and y-values. + * + * @param array of mixed Data Series Y + * @param array of mixed Data Series X + * @return float + */ + public static function INTERCEPT($yValues,$xValues) { + if (!self::_checkTrendArrays($yValues,$xValues)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $yValueCount = count($yValues); + $xValueCount = count($xValues); + + if (($yValueCount == 0) || ($yValueCount != $xValueCount)) { + return PHPExcel_Calculation_Functions::NA(); + } elseif ($yValueCount == 1) { + return PHPExcel_Calculation_Functions::DIV0(); + } + + $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues); + return $bestFitLinear->getIntersect(); + } // function INTERCEPT() + + + /** + * KURT + * + * Returns the kurtosis of a data set. Kurtosis characterizes the relative peakedness + * or flatness of a distribution compared with the normal distribution. Positive + * kurtosis indicates a relatively peaked distribution. Negative kurtosis indicates a + * relatively flat distribution. + * + * @param array Data Series + * @return float + */ + public static function KURT() { + $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); + $mean = self::AVERAGE($aArgs); + $stdDev = self::STDEV($aArgs); + + if ($stdDev > 0) { + $count = $summer = 0; + // Loop through arguments + foreach ($aArgs as $k => $arg) { + if ((is_bool($arg)) && + (!PHPExcel_Calculation_Functions::isMatrixValue($k))) { + } else { + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + $summer += pow((($arg - $mean) / $stdDev),4) ; + ++$count; + } + } + } + + // Return + if ($count > 3) { + return $summer * ($count * ($count+1) / (($count-1) * ($count-2) * ($count-3))) - (3 * pow($count-1,2) / (($count-2) * ($count-3))); + } + } + return PHPExcel_Calculation_Functions::DIV0(); + } // function KURT() + + + /** + * LARGE + * + * Returns the nth largest value in a data set. You can use this function to + * select a value based on its relative standing. + * + * Excel Function: + * LARGE(value1[,value2[, ...]],entry) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @param int $entry Position (ordered from the largest) in the array or range of data to return + * @return float + * + */ + public static function LARGE() { + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + + // Calculate + $entry = floor(array_pop($aArgs)); + + if ((is_numeric($entry)) && (!is_string($entry))) { + $mArgs = array(); + foreach ($aArgs as $arg) { + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + $mArgs[] = $arg; + } + } + $count = self::COUNT($mArgs); + $entry = floor(--$entry); + if (($entry < 0) || ($entry >= $count) || ($count == 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + rsort($mArgs); + return $mArgs[$entry]; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function LARGE() + + + /** + * LINEST + * + * Calculates the statistics for a line by using the "least squares" method to calculate a straight line that best fits your data, + * and then returns an array that describes the line. + * + * @param array of mixed Data Series Y + * @param array of mixed Data Series X + * @param boolean A logical value specifying whether to force the intersect to equal 0. + * @param boolean A logical value specifying whether to return additional regression statistics. + * @return array + */ + public static function LINEST($yValues, $xValues = NULL, $const = TRUE, $stats = FALSE) { + $const = (is_null($const)) ? TRUE : (boolean) PHPExcel_Calculation_Functions::flattenSingleValue($const); + $stats = (is_null($stats)) ? FALSE : (boolean) PHPExcel_Calculation_Functions::flattenSingleValue($stats); + if (is_null($xValues)) $xValues = range(1,count(PHPExcel_Calculation_Functions::flattenArray($yValues))); + + if (!self::_checkTrendArrays($yValues,$xValues)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $yValueCount = count($yValues); + $xValueCount = count($xValues); + + + if (($yValueCount == 0) || ($yValueCount != $xValueCount)) { + return PHPExcel_Calculation_Functions::NA(); + } elseif ($yValueCount == 1) { + return 0; + } + + $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues,$const); + if ($stats) { + return array( array( $bestFitLinear->getSlope(), + $bestFitLinear->getSlopeSE(), + $bestFitLinear->getGoodnessOfFit(), + $bestFitLinear->getF(), + $bestFitLinear->getSSRegression(), + ), + array( $bestFitLinear->getIntersect(), + $bestFitLinear->getIntersectSE(), + $bestFitLinear->getStdevOfResiduals(), + $bestFitLinear->getDFResiduals(), + $bestFitLinear->getSSResiduals() + ) + ); + } else { + return array( $bestFitLinear->getSlope(), + $bestFitLinear->getIntersect() + ); + } + } // function LINEST() + + + /** + * LOGEST + * + * Calculates an exponential curve that best fits the X and Y data series, + * and then returns an array that describes the line. + * + * @param array of mixed Data Series Y + * @param array of mixed Data Series X + * @param boolean A logical value specifying whether to force the intersect to equal 0. + * @param boolean A logical value specifying whether to return additional regression statistics. + * @return array + */ + public static function LOGEST($yValues,$xValues=null,$const=True,$stats=False) { + $const = (is_null($const)) ? True : (boolean) PHPExcel_Calculation_Functions::flattenSingleValue($const); + $stats = (is_null($stats)) ? False : (boolean) PHPExcel_Calculation_Functions::flattenSingleValue($stats); + if (is_null($xValues)) $xValues = range(1,count(PHPExcel_Calculation_Functions::flattenArray($yValues))); + + if (!self::_checkTrendArrays($yValues,$xValues)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $yValueCount = count($yValues); + $xValueCount = count($xValues); + + foreach($yValues as $value) { + if ($value <= 0.0) { + return PHPExcel_Calculation_Functions::NaN(); + } + } + + + if (($yValueCount == 0) || ($yValueCount != $xValueCount)) { + return PHPExcel_Calculation_Functions::NA(); + } elseif ($yValueCount == 1) { + return 1; + } + + $bestFitExponential = trendClass::calculate(trendClass::TREND_EXPONENTIAL,$yValues,$xValues,$const); + if ($stats) { + return array( array( $bestFitExponential->getSlope(), + $bestFitExponential->getSlopeSE(), + $bestFitExponential->getGoodnessOfFit(), + $bestFitExponential->getF(), + $bestFitExponential->getSSRegression(), + ), + array( $bestFitExponential->getIntersect(), + $bestFitExponential->getIntersectSE(), + $bestFitExponential->getStdevOfResiduals(), + $bestFitExponential->getDFResiduals(), + $bestFitExponential->getSSResiduals() + ) + ); + } else { + return array( $bestFitExponential->getSlope(), + $bestFitExponential->getIntersect() + ); + } + } // function LOGEST() + + + /** + * LOGINV + * + * Returns the inverse of the normal cumulative distribution + * + * @param float $probability + * @param float $mean + * @param float $stdDev + * @return float + * + * @todo Try implementing P J Acklam's refinement algorithm for greater + * accuracy if I can get my head round the mathematics + * (as described at) http://home.online.no/~pjacklam/notes/invnorm/ + */ + public static function LOGINV($probability, $mean, $stdDev) { + $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); + $mean = PHPExcel_Calculation_Functions::flattenSingleValue($mean); + $stdDev = PHPExcel_Calculation_Functions::flattenSingleValue($stdDev); + + if ((is_numeric($probability)) && (is_numeric($mean)) && (is_numeric($stdDev))) { + if (($probability < 0) || ($probability > 1) || ($stdDev <= 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + return exp($mean + $stdDev * self::NORMSINV($probability)); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function LOGINV() + + + /** + * LOGNORMDIST + * + * Returns the cumulative lognormal distribution of x, where ln(x) is normally distributed + * with parameters mean and standard_dev. + * + * @param float $value + * @param float $mean + * @param float $stdDev + * @return float + */ + public static function LOGNORMDIST($value, $mean, $stdDev) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $mean = PHPExcel_Calculation_Functions::flattenSingleValue($mean); + $stdDev = PHPExcel_Calculation_Functions::flattenSingleValue($stdDev); + + if ((is_numeric($value)) && (is_numeric($mean)) && (is_numeric($stdDev))) { + if (($value <= 0) || ($stdDev <= 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + return self::NORMSDIST((log($value) - $mean) / $stdDev); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function LOGNORMDIST() + + + /** + * MAX + * + * MAX returns the value of the element of the values passed that has the highest value, + * with negative numbers considered smaller than positive numbers. + * + * Excel Function: + * MAX(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function MAX() { + // Return value + $returnValue = null; + + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + foreach ($aArgs as $arg) { + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + if ((is_null($returnValue)) || ($arg > $returnValue)) { + $returnValue = $arg; + } + } + } + + // Return + if(is_null($returnValue)) { + return 0; + } + return $returnValue; + } // function MAX() + + + /** + * MAXA + * + * Returns the greatest value in a list of arguments, including numbers, text, and logical values + * + * Excel Function: + * MAXA(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function MAXA() { + // Return value + $returnValue = null; + + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + foreach ($aArgs as $arg) { + // Is it a numeric value? + if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) { + if (is_bool($arg)) { + $arg = (integer) $arg; + } elseif (is_string($arg)) { + $arg = 0; + } + if ((is_null($returnValue)) || ($arg > $returnValue)) { + $returnValue = $arg; + } + } + } + + // Return + if(is_null($returnValue)) { + return 0; + } + return $returnValue; + } // function MAXA() + + + /** + * MAXIF + * + * Counts the maximum value within a range of cells that contain numbers within the list of arguments + * + * Excel Function: + * MAXIF(value1[,value2[, ...]],condition) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param mixed $arg,... Data values + * @param string $condition The criteria that defines which cells will be checked. + * @return float + */ + public static function MAXIF($aArgs,$condition,$sumArgs = array()) { + // Return value + $returnValue = null; + + $aArgs = PHPExcel_Calculation_Functions::flattenArray($aArgs); + $sumArgs = PHPExcel_Calculation_Functions::flattenArray($sumArgs); + if (empty($sumArgs)) { + $sumArgs = $aArgs; + } + $condition = PHPExcel_Calculation_Functions::_ifCondition($condition); + // Loop through arguments + foreach ($aArgs as $key => $arg) { + if (!is_numeric($arg)) { $arg = PHPExcel_Calculation::_wrapResult(strtoupper($arg)); } + $testCondition = '='.$arg.$condition; + if (PHPExcel_Calculation::getInstance()->_calculateFormulaValue($testCondition)) { + if ((is_null($returnValue)) || ($arg > $returnValue)) { + $returnValue = $arg; + } + } + } + + // Return + return $returnValue; + } // function MAXIF() + + + /** + * MEDIAN + * + * Returns the median of the given numbers. The median is the number in the middle of a set of numbers. + * + * Excel Function: + * MEDIAN(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function MEDIAN() { + // Return value + $returnValue = PHPExcel_Calculation_Functions::NaN(); + + $mArgs = array(); + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + foreach ($aArgs as $arg) { + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + $mArgs[] = $arg; + } + } + + $mValueCount = count($mArgs); + if ($mValueCount > 0) { + sort($mArgs,SORT_NUMERIC); + $mValueCount = $mValueCount / 2; + if ($mValueCount == floor($mValueCount)) { + $returnValue = ($mArgs[$mValueCount--] + $mArgs[$mValueCount]) / 2; + } else { + $mValueCount == floor($mValueCount); + $returnValue = $mArgs[$mValueCount]; + } + } + + // Return + return $returnValue; + } // function MEDIAN() + + + /** + * MIN + * + * MIN returns the value of the element of the values passed that has the smallest value, + * with negative numbers considered smaller than positive numbers. + * + * Excel Function: + * MIN(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function MIN() { + // Return value + $returnValue = null; + + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + foreach ($aArgs as $arg) { + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + if ((is_null($returnValue)) || ($arg < $returnValue)) { + $returnValue = $arg; + } + } + } + + // Return + if(is_null($returnValue)) { + return 0; + } + return $returnValue; + } // function MIN() + + + /** + * MINA + * + * Returns the smallest value in a list of arguments, including numbers, text, and logical values + * + * Excel Function: + * MINA(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function MINA() { + // Return value + $returnValue = null; + + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + foreach ($aArgs as $arg) { + // Is it a numeric value? + if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) { + if (is_bool($arg)) { + $arg = (integer) $arg; + } elseif (is_string($arg)) { + $arg = 0; + } + if ((is_null($returnValue)) || ($arg < $returnValue)) { + $returnValue = $arg; + } + } + } + + // Return + if(is_null($returnValue)) { + return 0; + } + return $returnValue; + } // function MINA() + + + /** + * MINIF + * + * Returns the minimum value within a range of cells that contain numbers within the list of arguments + * + * Excel Function: + * MINIF(value1[,value2[, ...]],condition) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param mixed $arg,... Data values + * @param string $condition The criteria that defines which cells will be checked. + * @return float + */ + public static function MINIF($aArgs,$condition,$sumArgs = array()) { + // Return value + $returnValue = null; + + $aArgs = PHPExcel_Calculation_Functions::flattenArray($aArgs); + $sumArgs = PHPExcel_Calculation_Functions::flattenArray($sumArgs); + if (empty($sumArgs)) { + $sumArgs = $aArgs; + } + $condition = PHPExcel_Calculation_Functions::_ifCondition($condition); + // Loop through arguments + foreach ($aArgs as $key => $arg) { + if (!is_numeric($arg)) { $arg = PHPExcel_Calculation::_wrapResult(strtoupper($arg)); } + $testCondition = '='.$arg.$condition; + if (PHPExcel_Calculation::getInstance()->_calculateFormulaValue($testCondition)) { + if ((is_null($returnValue)) || ($arg < $returnValue)) { + $returnValue = $arg; + } + } + } + + // Return + return $returnValue; + } // function MINIF() + + + // + // Special variant of array_count_values that isn't limited to strings and integers, + // but can work with floating point numbers as values + // + private static function _modeCalc($data) { + $frequencyArray = array(); + foreach($data as $datum) { + $found = False; + foreach($frequencyArray as $key => $value) { + if ((string) $value['value'] == (string) $datum) { + ++$frequencyArray[$key]['frequency']; + $found = True; + break; + } + } + if (!$found) { + $frequencyArray[] = array('value' => $datum, + 'frequency' => 1 ); + } + } + + foreach($frequencyArray as $key => $value) { + $frequencyList[$key] = $value['frequency']; + $valueList[$key] = $value['value']; + } + array_multisort($frequencyList, SORT_DESC, $valueList, SORT_ASC, SORT_NUMERIC, $frequencyArray); + + if ($frequencyArray[0]['frequency'] == 1) { + return PHPExcel_Calculation_Functions::NA(); + } + return $frequencyArray[0]['value']; + } // function _modeCalc() + + + /** + * MODE + * + * Returns the most frequently occurring, or repetitive, value in an array or range of data + * + * Excel Function: + * MODE(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function MODE() { + // Return value + $returnValue = PHPExcel_Calculation_Functions::NA(); + + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + + $mArgs = array(); + foreach ($aArgs as $arg) { + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + $mArgs[] = $arg; + } + } + + if (!empty($mArgs)) { + return self::_modeCalc($mArgs); + } + + // Return + return $returnValue; + } // function MODE() + + + /** + * NEGBINOMDIST + * + * Returns the negative binomial distribution. NEGBINOMDIST returns the probability that + * there will be number_f failures before the number_s-th success, when the constant + * probability of a success is probability_s. This function is similar to the binomial + * distribution, except that the number of successes is fixed, and the number of trials is + * variable. Like the binomial, trials are assumed to be independent. + * + * @param float $failures Number of Failures + * @param float $successes Threshold number of Successes + * @param float $probability Probability of success on each trial + * @return float + * + */ + public static function NEGBINOMDIST($failures, $successes, $probability) { + $failures = floor(PHPExcel_Calculation_Functions::flattenSingleValue($failures)); + $successes = floor(PHPExcel_Calculation_Functions::flattenSingleValue($successes)); + $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); + + if ((is_numeric($failures)) && (is_numeric($successes)) && (is_numeric($probability))) { + if (($failures < 0) || ($successes < 1)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if (($probability < 0) || ($probability > 1)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) { + if (($failures + $successes - 1) <= 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + } + return (PHPExcel_Calculation_MathTrig::COMBIN($failures + $successes - 1,$successes - 1)) * (pow($probability,$successes)) * (pow(1 - $probability,$failures)) ; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function NEGBINOMDIST() + + + /** + * NORMDIST + * + * Returns the normal distribution for the specified mean and standard deviation. This + * function has a very wide range of applications in statistics, including hypothesis + * testing. + * + * @param float $value + * @param float $mean Mean Value + * @param float $stdDev Standard Deviation + * @param boolean $cumulative + * @return float + * + */ + public static function NORMDIST($value, $mean, $stdDev, $cumulative) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $mean = PHPExcel_Calculation_Functions::flattenSingleValue($mean); + $stdDev = PHPExcel_Calculation_Functions::flattenSingleValue($stdDev); + + if ((is_numeric($value)) && (is_numeric($mean)) && (is_numeric($stdDev))) { + if ($stdDev < 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ((is_numeric($cumulative)) || (is_bool($cumulative))) { + if ($cumulative) { + return 0.5 * (1 + PHPExcel_Calculation_Engineering::_erfVal(($value - $mean) / ($stdDev * sqrt(2)))); + } else { + return (1 / (SQRT2PI * $stdDev)) * exp(0 - (pow($value - $mean,2) / (2 * ($stdDev * $stdDev)))); + } + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function NORMDIST() + + + /** + * NORMINV + * + * Returns the inverse of the normal cumulative distribution for the specified mean and standard deviation. + * + * @param float $value + * @param float $mean Mean Value + * @param float $stdDev Standard Deviation + * @return float + * + */ + public static function NORMINV($probability,$mean,$stdDev) { + $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); + $mean = PHPExcel_Calculation_Functions::flattenSingleValue($mean); + $stdDev = PHPExcel_Calculation_Functions::flattenSingleValue($stdDev); + + if ((is_numeric($probability)) && (is_numeric($mean)) && (is_numeric($stdDev))) { + if (($probability < 0) || ($probability > 1)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ($stdDev < 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + return (self::_inverse_ncdf($probability) * $stdDev) + $mean; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function NORMINV() + + + /** + * NORMSDIST + * + * Returns the standard normal cumulative distribution function. The distribution has + * a mean of 0 (zero) and a standard deviation of one. Use this function in place of a + * table of standard normal curve areas. + * + * @param float $value + * @return float + */ + public static function NORMSDIST($value) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + + return self::NORMDIST($value, 0, 1, True); + } // function NORMSDIST() + + + /** + * NORMSINV + * + * Returns the inverse of the standard normal cumulative distribution + * + * @param float $value + * @return float + */ + public static function NORMSINV($value) { + return self::NORMINV($value, 0, 1); + } // function NORMSINV() + + + /** + * PERCENTILE + * + * Returns the nth percentile of values in a range.. + * + * Excel Function: + * PERCENTILE(value1[,value2[, ...]],entry) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @param float $entry Percentile value in the range 0..1, inclusive. + * @return float + */ + public static function PERCENTILE() { + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + + // Calculate + $entry = array_pop($aArgs); + + if ((is_numeric($entry)) && (!is_string($entry))) { + if (($entry < 0) || ($entry > 1)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $mArgs = array(); + foreach ($aArgs as $arg) { + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + $mArgs[] = $arg; + } + } + $mValueCount = count($mArgs); + if ($mValueCount > 0) { + sort($mArgs); + $count = self::COUNT($mArgs); + $index = $entry * ($count-1); + $iBase = floor($index); + if ($index == $iBase) { + return $mArgs[$index]; + } else { + $iNext = $iBase + 1; + $iProportion = $index - $iBase; + return $mArgs[$iBase] + (($mArgs[$iNext] - $mArgs[$iBase]) * $iProportion) ; + } + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function PERCENTILE() + + + /** + * PERCENTRANK + * + * Returns the rank of a value in a data set as a percentage of the data set. + * + * @param array of number An array of, or a reference to, a list of numbers. + * @param number The number whose rank you want to find. + * @param number The number of significant digits for the returned percentage value. + * @return float + */ + public static function PERCENTRANK($valueSet,$value,$significance=3) { + $valueSet = PHPExcel_Calculation_Functions::flattenArray($valueSet); + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $significance = (is_null($significance)) ? 3 : (integer) PHPExcel_Calculation_Functions::flattenSingleValue($significance); + + foreach($valueSet as $key => $valueEntry) { + if (!is_numeric($valueEntry)) { + unset($valueSet[$key]); + } + } + sort($valueSet,SORT_NUMERIC); + $valueCount = count($valueSet); + if ($valueCount == 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + + $valueAdjustor = $valueCount - 1; + if (($value < $valueSet[0]) || ($value > $valueSet[$valueAdjustor])) { + return PHPExcel_Calculation_Functions::NA(); + } + + $pos = array_search($value,$valueSet); + if ($pos === False) { + $pos = 0; + $testValue = $valueSet[0]; + while ($testValue < $value) { + $testValue = $valueSet[++$pos]; + } + --$pos; + $pos += (($value - $valueSet[$pos]) / ($testValue - $valueSet[$pos])); + } + + return round($pos / $valueAdjustor,$significance); + } // function PERCENTRANK() + + + /** + * PERMUT + * + * Returns the number of permutations for a given number of objects that can be + * selected from number objects. A permutation is any set or subset of objects or + * events where internal order is significant. Permutations are different from + * combinations, for which the internal order is not significant. Use this function + * for lottery-style probability calculations. + * + * @param int $numObjs Number of different objects + * @param int $numInSet Number of objects in each permutation + * @return int Number of permutations + */ + public static function PERMUT($numObjs,$numInSet) { + $numObjs = PHPExcel_Calculation_Functions::flattenSingleValue($numObjs); + $numInSet = PHPExcel_Calculation_Functions::flattenSingleValue($numInSet); + + if ((is_numeric($numObjs)) && (is_numeric($numInSet))) { + $numInSet = floor($numInSet); + if ($numObjs < $numInSet) { + return PHPExcel_Calculation_Functions::NaN(); + } + return round(PHPExcel_Calculation_MathTrig::FACT($numObjs) / PHPExcel_Calculation_MathTrig::FACT($numObjs - $numInSet)); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function PERMUT() + + + /** + * POISSON + * + * Returns the Poisson distribution. A common application of the Poisson distribution + * is predicting the number of events over a specific time, such as the number of + * cars arriving at a toll plaza in 1 minute. + * + * @param float $value + * @param float $mean Mean Value + * @param boolean $cumulative + * @return float + * + */ + public static function POISSON($value, $mean, $cumulative) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $mean = PHPExcel_Calculation_Functions::flattenSingleValue($mean); + + if ((is_numeric($value)) && (is_numeric($mean))) { + if (($value <= 0) || ($mean <= 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ((is_numeric($cumulative)) || (is_bool($cumulative))) { + if ($cumulative) { + $summer = 0; + for ($i = 0; $i <= floor($value); ++$i) { + $summer += pow($mean,$i) / PHPExcel_Calculation_MathTrig::FACT($i); + } + return exp(0-$mean) * $summer; + } else { + return (exp(0-$mean) * pow($mean,$value)) / PHPExcel_Calculation_MathTrig::FACT($value); + } + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function POISSON() + + + /** + * QUARTILE + * + * Returns the quartile of a data set. + * + * Excel Function: + * QUARTILE(value1[,value2[, ...]],entry) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @param int $entry Quartile value in the range 1..3, inclusive. + * @return float + */ + public static function QUARTILE() { + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + + // Calculate + $entry = floor(array_pop($aArgs)); + + if ((is_numeric($entry)) && (!is_string($entry))) { + $entry /= 4; + if (($entry < 0) || ($entry > 1)) { + return PHPExcel_Calculation_Functions::NaN(); + } + return self::PERCENTILE($aArgs,$entry); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function QUARTILE() + + + /** + * RANK + * + * Returns the rank of a number in a list of numbers. + * + * @param number The number whose rank you want to find. + * @param array of number An array of, or a reference to, a list of numbers. + * @param mixed Order to sort the values in the value set + * @return float + */ + public static function RANK($value,$valueSet,$order=0) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $valueSet = PHPExcel_Calculation_Functions::flattenArray($valueSet); + $order = (is_null($order)) ? 0 : (integer) PHPExcel_Calculation_Functions::flattenSingleValue($order); + + foreach($valueSet as $key => $valueEntry) { + if (!is_numeric($valueEntry)) { + unset($valueSet[$key]); + } + } + + if ($order == 0) { + rsort($valueSet,SORT_NUMERIC); + } else { + sort($valueSet,SORT_NUMERIC); + } + $pos = array_search($value,$valueSet); + if ($pos === False) { + return PHPExcel_Calculation_Functions::NA(); + } + + return ++$pos; + } // function RANK() + + + /** + * RSQ + * + * Returns the square of the Pearson product moment correlation coefficient through data points in known_y's and known_x's. + * + * @param array of mixed Data Series Y + * @param array of mixed Data Series X + * @return float + */ + public static function RSQ($yValues,$xValues) { + if (!self::_checkTrendArrays($yValues,$xValues)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $yValueCount = count($yValues); + $xValueCount = count($xValues); + + if (($yValueCount == 0) || ($yValueCount != $xValueCount)) { + return PHPExcel_Calculation_Functions::NA(); + } elseif ($yValueCount == 1) { + return PHPExcel_Calculation_Functions::DIV0(); + } + + $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues); + return $bestFitLinear->getGoodnessOfFit(); + } // function RSQ() + + + /** + * SKEW + * + * Returns the skewness of a distribution. Skewness characterizes the degree of asymmetry + * of a distribution around its mean. Positive skewness indicates a distribution with an + * asymmetric tail extending toward more positive values. Negative skewness indicates a + * distribution with an asymmetric tail extending toward more negative values. + * + * @param array Data Series + * @return float + */ + public static function SKEW() { + $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); + $mean = self::AVERAGE($aArgs); + $stdDev = self::STDEV($aArgs); + + $count = $summer = 0; + // Loop through arguments + foreach ($aArgs as $k => $arg) { + if ((is_bool($arg)) && + (!PHPExcel_Calculation_Functions::isMatrixValue($k))) { + } else { + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + $summer += pow((($arg - $mean) / $stdDev),3) ; + ++$count; + } + } + } + + // Return + if ($count > 2) { + return $summer * ($count / (($count-1) * ($count-2))); + } + return PHPExcel_Calculation_Functions::DIV0(); + } // function SKEW() + + + /** + * SLOPE + * + * Returns the slope of the linear regression line through data points in known_y's and known_x's. + * + * @param array of mixed Data Series Y + * @param array of mixed Data Series X + * @return float + */ + public static function SLOPE($yValues,$xValues) { + if (!self::_checkTrendArrays($yValues,$xValues)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $yValueCount = count($yValues); + $xValueCount = count($xValues); + + if (($yValueCount == 0) || ($yValueCount != $xValueCount)) { + return PHPExcel_Calculation_Functions::NA(); + } elseif ($yValueCount == 1) { + return PHPExcel_Calculation_Functions::DIV0(); + } + + $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues); + return $bestFitLinear->getSlope(); + } // function SLOPE() + + + /** + * SMALL + * + * Returns the nth smallest value in a data set. You can use this function to + * select a value based on its relative standing. + * + * Excel Function: + * SMALL(value1[,value2[, ...]],entry) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @param int $entry Position (ordered from the smallest) in the array or range of data to return + * @return float + */ + public static function SMALL() { + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + + // Calculate + $entry = array_pop($aArgs); + + if ((is_numeric($entry)) && (!is_string($entry))) { + $mArgs = array(); + foreach ($aArgs as $arg) { + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + $mArgs[] = $arg; + } + } + $count = self::COUNT($mArgs); + $entry = floor(--$entry); + if (($entry < 0) || ($entry >= $count) || ($count == 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + sort($mArgs); + return $mArgs[$entry]; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function SMALL() + + + /** + * STANDARDIZE + * + * Returns a normalized value from a distribution characterized by mean and standard_dev. + * + * @param float $value Value to normalize + * @param float $mean Mean Value + * @param float $stdDev Standard Deviation + * @return float Standardized value + */ + public static function STANDARDIZE($value,$mean,$stdDev) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $mean = PHPExcel_Calculation_Functions::flattenSingleValue($mean); + $stdDev = PHPExcel_Calculation_Functions::flattenSingleValue($stdDev); + + if ((is_numeric($value)) && (is_numeric($mean)) && (is_numeric($stdDev))) { + if ($stdDev <= 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + return ($value - $mean) / $stdDev ; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function STANDARDIZE() + + + /** + * STDEV + * + * Estimates standard deviation based on a sample. The standard deviation is a measure of how + * widely values are dispersed from the average value (the mean). + * + * Excel Function: + * STDEV(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function STDEV() { + $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); + + // Return value + $returnValue = null; + + $aMean = self::AVERAGE($aArgs); + if (!is_null($aMean)) { + $aCount = -1; + foreach ($aArgs as $k => $arg) { + if ((is_bool($arg)) && + ((!PHPExcel_Calculation_Functions::isCellValue($k)) || (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE))) { + $arg = (integer) $arg; + } + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + if (is_null($returnValue)) { + $returnValue = pow(($arg - $aMean),2); + } else { + $returnValue += pow(($arg - $aMean),2); + } + ++$aCount; + } + } + + // Return + if (($aCount > 0) && ($returnValue >= 0)) { + return sqrt($returnValue / $aCount); + } + } + return PHPExcel_Calculation_Functions::DIV0(); + } // function STDEV() + + + /** + * STDEVA + * + * Estimates standard deviation based on a sample, including numbers, text, and logical values + * + * Excel Function: + * STDEVA(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function STDEVA() { + $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); + + // Return value + $returnValue = null; + + $aMean = self::AVERAGEA($aArgs); + if (!is_null($aMean)) { + $aCount = -1; + foreach ($aArgs as $k => $arg) { + if ((is_bool($arg)) && + (!PHPExcel_Calculation_Functions::isMatrixValue($k))) { + } else { + // Is it a numeric value? + if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) & ($arg != '')))) { + if (is_bool($arg)) { + $arg = (integer) $arg; + } elseif (is_string($arg)) { + $arg = 0; + } + if (is_null($returnValue)) { + $returnValue = pow(($arg - $aMean),2); + } else { + $returnValue += pow(($arg - $aMean),2); + } + ++$aCount; + } + } + } + + // Return + if (($aCount > 0) && ($returnValue >= 0)) { + return sqrt($returnValue / $aCount); + } + } + return PHPExcel_Calculation_Functions::DIV0(); + } // function STDEVA() + + + /** + * STDEVP + * + * Calculates standard deviation based on the entire population + * + * Excel Function: + * STDEVP(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function STDEVP() { + $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); + + // Return value + $returnValue = null; + + $aMean = self::AVERAGE($aArgs); + if (!is_null($aMean)) { + $aCount = 0; + foreach ($aArgs as $k => $arg) { + if ((is_bool($arg)) && + ((!PHPExcel_Calculation_Functions::isCellValue($k)) || (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE))) { + $arg = (integer) $arg; + } + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + if (is_null($returnValue)) { + $returnValue = pow(($arg - $aMean),2); + } else { + $returnValue += pow(($arg - $aMean),2); + } + ++$aCount; + } + } + + // Return + if (($aCount > 0) && ($returnValue >= 0)) { + return sqrt($returnValue / $aCount); + } + } + return PHPExcel_Calculation_Functions::DIV0(); + } // function STDEVP() + + + /** + * STDEVPA + * + * Calculates standard deviation based on the entire population, including numbers, text, and logical values + * + * Excel Function: + * STDEVPA(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function STDEVPA() { + $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); + + // Return value + $returnValue = null; + + $aMean = self::AVERAGEA($aArgs); + if (!is_null($aMean)) { + $aCount = 0; + foreach ($aArgs as $k => $arg) { + if ((is_bool($arg)) && + (!PHPExcel_Calculation_Functions::isMatrixValue($k))) { + } else { + // Is it a numeric value? + if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) & ($arg != '')))) { + if (is_bool($arg)) { + $arg = (integer) $arg; + } elseif (is_string($arg)) { + $arg = 0; + } + if (is_null($returnValue)) { + $returnValue = pow(($arg - $aMean),2); + } else { + $returnValue += pow(($arg - $aMean),2); + } + ++$aCount; + } + } + } + + // Return + if (($aCount > 0) && ($returnValue >= 0)) { + return sqrt($returnValue / $aCount); + } + } + return PHPExcel_Calculation_Functions::DIV0(); + } // function STDEVPA() + + + /** + * STEYX + * + * Returns the standard error of the predicted y-value for each x in the regression. + * + * @param array of mixed Data Series Y + * @param array of mixed Data Series X + * @return float + */ + public static function STEYX($yValues,$xValues) { + if (!self::_checkTrendArrays($yValues,$xValues)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $yValueCount = count($yValues); + $xValueCount = count($xValues); + + if (($yValueCount == 0) || ($yValueCount != $xValueCount)) { + return PHPExcel_Calculation_Functions::NA(); + } elseif ($yValueCount == 1) { + return PHPExcel_Calculation_Functions::DIV0(); + } + + $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues); + return $bestFitLinear->getStdevOfResiduals(); + } // function STEYX() + + + /** + * TDIST + * + * Returns the probability of Student's T distribution. + * + * @param float $value Value for the function + * @param float $degrees degrees of freedom + * @param float $tails number of tails (1 or 2) + * @return float + */ + public static function TDIST($value, $degrees, $tails) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $degrees = floor(PHPExcel_Calculation_Functions::flattenSingleValue($degrees)); + $tails = floor(PHPExcel_Calculation_Functions::flattenSingleValue($tails)); + + if ((is_numeric($value)) && (is_numeric($degrees)) && (is_numeric($tails))) { + if (($value < 0) || ($degrees < 1) || ($tails < 1) || ($tails > 2)) { + return PHPExcel_Calculation_Functions::NaN(); + } + // tdist, which finds the probability that corresponds to a given value + // of t with k degrees of freedom. This algorithm is translated from a + // pascal function on p81 of "Statistical Computing in Pascal" by D + // Cooke, A H Craven & G M Clark (1985: Edward Arnold (Pubs.) Ltd: + // London). The above Pascal algorithm is itself a translation of the + // fortran algoritm "AS 3" by B E Cooper of the Atlas Computer + // Laboratory as reported in (among other places) "Applied Statistics + // Algorithms", editied by P Griffiths and I D Hill (1985; Ellis + // Horwood Ltd.; W. Sussex, England). + $tterm = $degrees; + $ttheta = atan2($value,sqrt($tterm)); + $tc = cos($ttheta); + $ts = sin($ttheta); + $tsum = 0; + + if (($degrees % 2) == 1) { + $ti = 3; + $tterm = $tc; + } else { + $ti = 2; + $tterm = 1; + } + + $tsum = $tterm; + while ($ti < $degrees) { + $tterm *= $tc * $tc * ($ti - 1) / $ti; + $tsum += $tterm; + $ti += 2; + } + $tsum *= $ts; + if (($degrees % 2) == 1) { $tsum = M_2DIVPI * ($tsum + $ttheta); } + $tValue = 0.5 * (1 + $tsum); + if ($tails == 1) { + return 1 - abs($tValue); + } else { + return 1 - abs((1 - $tValue) - $tValue); + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function TDIST() + + + /** + * TINV + * + * Returns the one-tailed probability of the chi-squared distribution. + * + * @param float $probability Probability for the function + * @param float $degrees degrees of freedom + * @return float + */ + public static function TINV($probability, $degrees) { + $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); + $degrees = floor(PHPExcel_Calculation_Functions::flattenSingleValue($degrees)); + + if ((is_numeric($probability)) && (is_numeric($degrees))) { + $xLo = 100; + $xHi = 0; + + $x = $xNew = 1; + $dx = 1; + $i = 0; + + while ((abs($dx) > PRECISION) && ($i++ < MAX_ITERATIONS)) { + // Apply Newton-Raphson step + $result = self::TDIST($x, $degrees, 2); + $error = $result - $probability; + if ($error == 0.0) { + $dx = 0; + } elseif ($error < 0.0) { + $xLo = $x; + } else { + $xHi = $x; + } + // Avoid division by zero + if ($result != 0.0) { + $dx = $error / $result; + $xNew = $x - $dx; + } + // If the NR fails to converge (which for example may be the + // case if the initial guess is too rough) we apply a bisection + // step to determine a more narrow interval around the root. + if (($xNew < $xLo) || ($xNew > $xHi) || ($result == 0.0)) { + $xNew = ($xLo + $xHi) / 2; + $dx = $xNew - $x; + } + $x = $xNew; + } + if ($i == MAX_ITERATIONS) { + return PHPExcel_Calculation_Functions::NA(); + } + return round($x,12); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function TINV() + + + /** + * TREND + * + * Returns values along a linear trend + * + * @param array of mixed Data Series Y + * @param array of mixed Data Series X + * @param array of mixed Values of X for which we want to find Y + * @param boolean A logical value specifying whether to force the intersect to equal 0. + * @return array of float + */ + public static function TREND($yValues,$xValues=array(),$newValues=array(),$const=True) { + $yValues = PHPExcel_Calculation_Functions::flattenArray($yValues); + $xValues = PHPExcel_Calculation_Functions::flattenArray($xValues); + $newValues = PHPExcel_Calculation_Functions::flattenArray($newValues); + $const = (is_null($const)) ? True : (boolean) PHPExcel_Calculation_Functions::flattenSingleValue($const); + + $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues,$const); + if (empty($newValues)) { + $newValues = $bestFitLinear->getXValues(); + } + + $returnArray = array(); + foreach($newValues as $xValue) { + $returnArray[0][] = $bestFitLinear->getValueOfYForX($xValue); + } + + return $returnArray; + } // function TREND() + + + /** + * TRIMMEAN + * + * Returns the mean of the interior of a data set. TRIMMEAN calculates the mean + * taken by excluding a percentage of data points from the top and bottom tails + * of a data set. + * + * Excel Function: + * TRIMEAN(value1[,value2[, ...]],$discard) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @param float $discard Percentage to discard + * @return float + */ + public static function TRIMMEAN() { + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + + // Calculate + $percent = array_pop($aArgs); + + if ((is_numeric($percent)) && (!is_string($percent))) { + if (($percent < 0) || ($percent > 1)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $mArgs = array(); + foreach ($aArgs as $arg) { + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + $mArgs[] = $arg; + } + } + $discard = floor(self::COUNT($mArgs) * $percent / 2); + sort($mArgs); + for ($i=0; $i < $discard; ++$i) { + array_pop($mArgs); + array_shift($mArgs); + } + return self::AVERAGE($mArgs); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function TRIMMEAN() + + + /** + * VARFunc + * + * Estimates variance based on a sample. + * + * Excel Function: + * VAR(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function VARFunc() { + // Return value + $returnValue = PHPExcel_Calculation_Functions::DIV0(); + + $summerA = $summerB = 0; + + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + $aCount = 0; + foreach ($aArgs as $arg) { + if (is_bool($arg)) { $arg = (integer) $arg; } + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + $summerA += ($arg * $arg); + $summerB += $arg; + ++$aCount; + } + } + + // Return + if ($aCount > 1) { + $summerA *= $aCount; + $summerB *= $summerB; + $returnValue = ($summerA - $summerB) / ($aCount * ($aCount - 1)); + } + return $returnValue; + } // function VARFunc() + + + /** + * VARA + * + * Estimates variance based on a sample, including numbers, text, and logical values + * + * Excel Function: + * VARA(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function VARA() { + // Return value + $returnValue = PHPExcel_Calculation_Functions::DIV0(); + + $summerA = $summerB = 0; + + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); + $aCount = 0; + foreach ($aArgs as $k => $arg) { + if ((is_string($arg)) && + (PHPExcel_Calculation_Functions::isValue($k))) { + return PHPExcel_Calculation_Functions::VALUE(); + } elseif ((is_string($arg)) && + (!PHPExcel_Calculation_Functions::isMatrixValue($k))) { + } else { + // Is it a numeric value? + if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) & ($arg != '')))) { + if (is_bool($arg)) { + $arg = (integer) $arg; + } elseif (is_string($arg)) { + $arg = 0; + } + $summerA += ($arg * $arg); + $summerB += $arg; + ++$aCount; + } + } + } + + // Return + if ($aCount > 1) { + $summerA *= $aCount; + $summerB *= $summerB; + $returnValue = ($summerA - $summerB) / ($aCount * ($aCount - 1)); + } + return $returnValue; + } // function VARA() + + + /** + * VARP + * + * Calculates variance based on the entire population + * + * Excel Function: + * VARP(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function VARP() { + // Return value + $returnValue = PHPExcel_Calculation_Functions::DIV0(); + + $summerA = $summerB = 0; + + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + $aCount = 0; + foreach ($aArgs as $arg) { + if (is_bool($arg)) { $arg = (integer) $arg; } + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + $summerA += ($arg * $arg); + $summerB += $arg; + ++$aCount; + } + } + + // Return + if ($aCount > 0) { + $summerA *= $aCount; + $summerB *= $summerB; + $returnValue = ($summerA - $summerB) / ($aCount * $aCount); + } + return $returnValue; + } // function VARP() + + + /** + * VARPA + * + * Calculates variance based on the entire population, including numbers, text, and logical values + * + * Excel Function: + * VARPA(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function VARPA() { + // Return value + $returnValue = PHPExcel_Calculation_Functions::DIV0(); + + $summerA = $summerB = 0; + + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); + $aCount = 0; + foreach ($aArgs as $k => $arg) { + if ((is_string($arg)) && + (PHPExcel_Calculation_Functions::isValue($k))) { + return PHPExcel_Calculation_Functions::VALUE(); + } elseif ((is_string($arg)) && + (!PHPExcel_Calculation_Functions::isMatrixValue($k))) { + } else { + // Is it a numeric value? + if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) & ($arg != '')))) { + if (is_bool($arg)) { + $arg = (integer) $arg; + } elseif (is_string($arg)) { + $arg = 0; + } + $summerA += ($arg * $arg); + $summerB += $arg; + ++$aCount; + } + } + } + + // Return + if ($aCount > 0) { + $summerA *= $aCount; + $summerB *= $summerB; + $returnValue = ($summerA - $summerB) / ($aCount * $aCount); + } + return $returnValue; + } // function VARPA() + + + /** + * WEIBULL + * + * Returns the Weibull distribution. Use this distribution in reliability + * analysis, such as calculating a device's mean time to failure. + * + * @param float $value + * @param float $alpha Alpha Parameter + * @param float $beta Beta Parameter + * @param boolean $cumulative + * @return float + * + */ + public static function WEIBULL($value, $alpha, $beta, $cumulative) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $alpha = PHPExcel_Calculation_Functions::flattenSingleValue($alpha); + $beta = PHPExcel_Calculation_Functions::flattenSingleValue($beta); + + if ((is_numeric($value)) && (is_numeric($alpha)) && (is_numeric($beta))) { + if (($value < 0) || ($alpha <= 0) || ($beta <= 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ((is_numeric($cumulative)) || (is_bool($cumulative))) { + if ($cumulative) { + return 1 - exp(0 - pow($value / $beta,$alpha)); + } else { + return ($alpha / pow($beta,$alpha)) * pow($value,$alpha - 1) * exp(0 - pow($value / $beta,$alpha)); + } + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function WEIBULL() + + + /** + * ZTEST + * + * Returns the Weibull distribution. Use this distribution in reliability + * analysis, such as calculating a device's mean time to failure. + * + * @param float $dataSet + * @param float $m0 Alpha Parameter + * @param float $sigma Beta Parameter + * @param boolean $cumulative + * @return float + * + */ + public static function ZTEST($dataSet, $m0, $sigma = NULL) { + $dataSet = PHPExcel_Calculation_Functions::flattenArrayIndexed($dataSet); + $m0 = PHPExcel_Calculation_Functions::flattenSingleValue($m0); + $sigma = PHPExcel_Calculation_Functions::flattenSingleValue($sigma); + + if (is_null($sigma)) { + $sigma = self::STDEV($dataSet); + } + $n = count($dataSet); + + return 1 - self::NORMSDIST((self::AVERAGE($dataSet) - $m0)/($sigma/SQRT($n))); + } // function ZTEST() + +} // class PHPExcel_Calculation_Statistical diff --git a/lib/phpexcel/PHPExcel/Calculation/TextData.php b/lib/phpexcel/PHPExcel/Calculation/TextData.php new file mode 100644 index 0000000..d1ba272 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Calculation/TextData.php @@ -0,0 +1,590 @@ +=0 && ord($c{0}) <= 127) + return ord($c{0}); + if (ord($c{0}) >= 192 && ord($c{0}) <= 223) + return (ord($c{0})-192)*64 + (ord($c{1})-128); + if (ord($c{0}) >= 224 && ord($c{0}) <= 239) + return (ord($c{0})-224)*4096 + (ord($c{1})-128)*64 + (ord($c{2})-128); + if (ord($c{0}) >= 240 && ord($c{0}) <= 247) + return (ord($c{0})-240)*262144 + (ord($c{1})-128)*4096 + (ord($c{2})-128)*64 + (ord($c{3})-128); + if (ord($c{0}) >= 248 && ord($c{0}) <= 251) + return (ord($c{0})-248)*16777216 + (ord($c{1})-128)*262144 + (ord($c{2})-128)*4096 + (ord($c{3})-128)*64 + (ord($c{4})-128); + if (ord($c{0}) >= 252 && ord($c{0}) <= 253) + return (ord($c{0})-252)*1073741824 + (ord($c{1})-128)*16777216 + (ord($c{2})-128)*262144 + (ord($c{3})-128)*4096 + (ord($c{4})-128)*64 + (ord($c{5})-128); + if (ord($c{0}) >= 254 && ord($c{0}) <= 255) //error + return PHPExcel_Calculation_Functions::VALUE(); + return 0; + } // function _uniord() + + /** + * CHARACTER + * + * @param string $character Value + * @return int + */ + public static function CHARACTER($character) { + $character = PHPExcel_Calculation_Functions::flattenSingleValue($character); + + if ((!is_numeric($character)) || ($character < 0)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (function_exists('mb_convert_encoding')) { + return mb_convert_encoding('&#'.intval($character).';', 'UTF-8', 'HTML-ENTITIES'); + } else { + return chr(intval($character)); + } + } + + + /** + * TRIMNONPRINTABLE + * + * @param mixed $stringValue Value to check + * @return string + */ + public static function TRIMNONPRINTABLE($stringValue = '') { + $stringValue = PHPExcel_Calculation_Functions::flattenSingleValue($stringValue); + + if (is_bool($stringValue)) { + return ($stringValue) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); + } + + if (self::$_invalidChars == Null) { + self::$_invalidChars = range(chr(0),chr(31)); + } + + if (is_string($stringValue) || is_numeric($stringValue)) { + return str_replace(self::$_invalidChars,'',trim($stringValue,"\x00..\x1F")); + } + return NULL; + } // function TRIMNONPRINTABLE() + + + /** + * TRIMSPACES + * + * @param mixed $stringValue Value to check + * @return string + */ + public static function TRIMSPACES($stringValue = '') { + $stringValue = PHPExcel_Calculation_Functions::flattenSingleValue($stringValue); + + if (is_bool($stringValue)) { + return ($stringValue) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); + } + + if (is_string($stringValue) || is_numeric($stringValue)) { + return trim(preg_replace('/ +/',' ',trim($stringValue,' '))); + } + return NULL; + } // function TRIMSPACES() + + + /** + * ASCIICODE + * + * @param string $characters Value + * @return int + */ + public static function ASCIICODE($characters) { + if (($characters === NULL) || ($characters === '')) + return PHPExcel_Calculation_Functions::VALUE(); + $characters = PHPExcel_Calculation_Functions::flattenSingleValue($characters); + if (is_bool($characters)) { + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { + $characters = (int) $characters; + } else { + $characters = ($characters) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); + } + } + + $character = $characters; + if ((function_exists('mb_strlen')) && (function_exists('mb_substr'))) { + if (mb_strlen($characters, 'UTF-8') > 1) { $character = mb_substr($characters, 0, 1, 'UTF-8'); } + return self::_uniord($character); + } else { + if (strlen($characters) > 0) { $character = substr($characters, 0, 1); } + return ord($character); + } + } // function ASCIICODE() + + + /** + * CONCATENATE + * + * @return string + */ + public static function CONCATENATE() { + // Return value + $returnValue = ''; + + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + foreach ($aArgs as $arg) { + if (is_bool($arg)) { + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { + $arg = (int) $arg; + } else { + $arg = ($arg) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); + } + } + $returnValue .= $arg; + } + + // Return + return $returnValue; + } // function CONCATENATE() + + + /** + * DOLLAR + * + * This function converts a number to text using currency format, with the decimals rounded to the specified place. + * The format used is $#,##0.00_);($#,##0.00).. + * + * @param float $value The value to format + * @param int $decimals The number of digits to display to the right of the decimal point. + * If decimals is negative, number is rounded to the left of the decimal point. + * If you omit decimals, it is assumed to be 2 + * @return string + */ + public static function DOLLAR($value = 0, $decimals = 2) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $decimals = is_null($decimals) ? 0 : PHPExcel_Calculation_Functions::flattenSingleValue($decimals); + + // Validate parameters + if (!is_numeric($value) || !is_numeric($decimals)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $decimals = floor($decimals); + + $mask = '$#,##0'; + if ($decimals > 0) { + $mask .= '.' . str_repeat('0',$decimals); + } else { + $round = pow(10,abs($decimals)); + if ($value < 0) { $round = 0-$round; } + $value = PHPExcel_Calculation_MathTrig::MROUND($value, $round); + } + + return PHPExcel_Style_NumberFormat::toFormattedString($value, $mask); + + } // function DOLLAR() + + + /** + * SEARCHSENSITIVE + * + * @param string $needle The string to look for + * @param string $haystack The string in which to look + * @param int $offset Offset within $haystack + * @return string + */ + public static function SEARCHSENSITIVE($needle,$haystack,$offset=1) { + $needle = PHPExcel_Calculation_Functions::flattenSingleValue($needle); + $haystack = PHPExcel_Calculation_Functions::flattenSingleValue($haystack); + $offset = PHPExcel_Calculation_Functions::flattenSingleValue($offset); + + if (!is_bool($needle)) { + if (is_bool($haystack)) { + $haystack = ($haystack) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); + } + + if (($offset > 0) && (PHPExcel_Shared_String::CountCharacters($haystack) > $offset)) { + if (PHPExcel_Shared_String::CountCharacters($needle) == 0) { + return $offset; + } + if (function_exists('mb_strpos')) { + $pos = mb_strpos($haystack, $needle, --$offset, 'UTF-8'); + } else { + $pos = strpos($haystack, $needle, --$offset); + } + if ($pos !== false) { + return ++$pos; + } + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function SEARCHSENSITIVE() + + + /** + * SEARCHINSENSITIVE + * + * @param string $needle The string to look for + * @param string $haystack The string in which to look + * @param int $offset Offset within $haystack + * @return string + */ + public static function SEARCHINSENSITIVE($needle,$haystack,$offset=1) { + $needle = PHPExcel_Calculation_Functions::flattenSingleValue($needle); + $haystack = PHPExcel_Calculation_Functions::flattenSingleValue($haystack); + $offset = PHPExcel_Calculation_Functions::flattenSingleValue($offset); + + if (!is_bool($needle)) { + if (is_bool($haystack)) { + $haystack = ($haystack) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); + } + + if (($offset > 0) && (PHPExcel_Shared_String::CountCharacters($haystack) > $offset)) { + if (PHPExcel_Shared_String::CountCharacters($needle) == 0) { + return $offset; + } + if (function_exists('mb_stripos')) { + $pos = mb_stripos($haystack, $needle, --$offset,'UTF-8'); + } else { + $pos = stripos($haystack, $needle, --$offset); + } + if ($pos !== false) { + return ++$pos; + } + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function SEARCHINSENSITIVE() + + + /** + * FIXEDFORMAT + * + * @param mixed $value Value to check + * @param integer $decimals + * @param boolean $no_commas + * @return boolean + */ + public static function FIXEDFORMAT($value, $decimals = 2, $no_commas = FALSE) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $decimals = PHPExcel_Calculation_Functions::flattenSingleValue($decimals); + $no_commas = PHPExcel_Calculation_Functions::flattenSingleValue($no_commas); + + // Validate parameters + if (!is_numeric($value) || !is_numeric($decimals)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $decimals = floor($decimals); + + $valueResult = round($value,$decimals); + if ($decimals < 0) { $decimals = 0; } + if (!$no_commas) { + $valueResult = number_format($valueResult,$decimals); + } + + return (string) $valueResult; + } // function FIXEDFORMAT() + + + /** + * LEFT + * + * @param string $value Value + * @param int $chars Number of characters + * @return string + */ + public static function LEFT($value = '', $chars = 1) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $chars = PHPExcel_Calculation_Functions::flattenSingleValue($chars); + + if ($chars < 0) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (is_bool($value)) { + $value = ($value) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); + } + + if (function_exists('mb_substr')) { + return mb_substr($value, 0, $chars, 'UTF-8'); + } else { + return substr($value, 0, $chars); + } + } // function LEFT() + + + /** + * MID + * + * @param string $value Value + * @param int $start Start character + * @param int $chars Number of characters + * @return string + */ + public static function MID($value = '', $start = 1, $chars = null) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $start = PHPExcel_Calculation_Functions::flattenSingleValue($start); + $chars = PHPExcel_Calculation_Functions::flattenSingleValue($chars); + + if (($start < 1) || ($chars < 0)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (is_bool($value)) { + $value = ($value) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); + } + + if (function_exists('mb_substr')) { + return mb_substr($value, --$start, $chars, 'UTF-8'); + } else { + return substr($value, --$start, $chars); + } + } // function MID() + + + /** + * RIGHT + * + * @param string $value Value + * @param int $chars Number of characters + * @return string + */ + public static function RIGHT($value = '', $chars = 1) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $chars = PHPExcel_Calculation_Functions::flattenSingleValue($chars); + + if ($chars < 0) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (is_bool($value)) { + $value = ($value) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); + } + + if ((function_exists('mb_substr')) && (function_exists('mb_strlen'))) { + return mb_substr($value, mb_strlen($value, 'UTF-8') - $chars, $chars, 'UTF-8'); + } else { + return substr($value, strlen($value) - $chars); + } + } // function RIGHT() + + + /** + * STRINGLENGTH + * + * @param string $value Value + * @return string + */ + public static function STRINGLENGTH($value = '') { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + + if (is_bool($value)) { + $value = ($value) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); + } + + if (function_exists('mb_strlen')) { + return mb_strlen($value, 'UTF-8'); + } else { + return strlen($value); + } + } // function STRINGLENGTH() + + + /** + * LOWERCASE + * + * Converts a string value to upper case. + * + * @param string $mixedCaseString + * @return string + */ + public static function LOWERCASE($mixedCaseString) { + $mixedCaseString = PHPExcel_Calculation_Functions::flattenSingleValue($mixedCaseString); + + if (is_bool($mixedCaseString)) { + $mixedCaseString = ($mixedCaseString) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); + } + + return PHPExcel_Shared_String::StrToLower($mixedCaseString); + } // function LOWERCASE() + + + /** + * UPPERCASE + * + * Converts a string value to upper case. + * + * @param string $mixedCaseString + * @return string + */ + public static function UPPERCASE($mixedCaseString) { + $mixedCaseString = PHPExcel_Calculation_Functions::flattenSingleValue($mixedCaseString); + + if (is_bool($mixedCaseString)) { + $mixedCaseString = ($mixedCaseString) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); + } + + return PHPExcel_Shared_String::StrToUpper($mixedCaseString); + } // function UPPERCASE() + + + /** + * PROPERCASE + * + * Converts a string value to upper case. + * + * @param string $mixedCaseString + * @return string + */ + public static function PROPERCASE($mixedCaseString) { + $mixedCaseString = PHPExcel_Calculation_Functions::flattenSingleValue($mixedCaseString); + + if (is_bool($mixedCaseString)) { + $mixedCaseString = ($mixedCaseString) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); + } + + return PHPExcel_Shared_String::StrToTitle($mixedCaseString); + } // function PROPERCASE() + + + /** + * REPLACE + * + * @param string $oldText String to modify + * @param int $start Start character + * @param int $chars Number of characters + * @param string $newText String to replace in defined position + * @return string + */ + public static function REPLACE($oldText = '', $start = 1, $chars = null, $newText) { + $oldText = PHPExcel_Calculation_Functions::flattenSingleValue($oldText); + $start = PHPExcel_Calculation_Functions::flattenSingleValue($start); + $chars = PHPExcel_Calculation_Functions::flattenSingleValue($chars); + $newText = PHPExcel_Calculation_Functions::flattenSingleValue($newText); + + $left = self::LEFT($oldText,$start-1); + $right = self::RIGHT($oldText,self::STRINGLENGTH($oldText)-($start+$chars)+1); + + return $left.$newText.$right; + } // function REPLACE() + + + /** + * SUBSTITUTE + * + * @param string $text Value + * @param string $fromText From Value + * @param string $toText To Value + * @param integer $instance Instance Number + * @return string + */ + public static function SUBSTITUTE($text = '', $fromText = '', $toText = '', $instance = 0) { + $text = PHPExcel_Calculation_Functions::flattenSingleValue($text); + $fromText = PHPExcel_Calculation_Functions::flattenSingleValue($fromText); + $toText = PHPExcel_Calculation_Functions::flattenSingleValue($toText); + $instance = floor(PHPExcel_Calculation_Functions::flattenSingleValue($instance)); + + if ($instance == 0) { + if(function_exists('mb_str_replace')) { + return mb_str_replace($fromText,$toText,$text); + } else { + return str_replace($fromText,$toText,$text); + } + } else { + $pos = -1; + while($instance > 0) { + if (function_exists('mb_strpos')) { + $pos = mb_strpos($text, $fromText, $pos+1, 'UTF-8'); + } else { + $pos = strpos($text, $fromText, $pos+1); + } + if ($pos === false) { + break; + } + --$instance; + } + if ($pos !== false) { + if (function_exists('mb_strlen')) { + return self::REPLACE($text,++$pos,mb_strlen($fromText, 'UTF-8'),$toText); + } else { + return self::REPLACE($text,++$pos,strlen($fromText),$toText); + } + } + } + + return $text; + } // function SUBSTITUTE() + + + /** + * RETURNSTRING + * + * @param mixed $testValue Value to check + * @return boolean + */ + public static function RETURNSTRING($testValue = '') { + $testValue = PHPExcel_Calculation_Functions::flattenSingleValue($testValue); + + if (is_string($testValue)) { + return $testValue; + } + return Null; + } // function RETURNSTRING() + + + /** + * TEXTFORMAT + * + * @param mixed $value Value to check + * @param string $format Format mask to use + * @return boolean + */ + public static function TEXTFORMAT($value,$format) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $format = PHPExcel_Calculation_Functions::flattenSingleValue($format); + + if ((is_string($value)) && (!is_numeric($value)) && PHPExcel_Shared_Date::isDateTimeFormatCode($format)) { + $value = PHPExcel_Calculation_DateTime::DATEVALUE($value); + } + + return (string) PHPExcel_Style_NumberFormat::toFormattedString($value,$format); + } // function TEXTFORMAT() + +} // class PHPExcel_Calculation_TextData diff --git a/lib/phpexcel/PHPExcel/Calculation/Token/Stack.php b/lib/phpexcel/PHPExcel/Calculation/Token/Stack.php new file mode 100644 index 0000000..821f3bd --- /dev/null +++ b/lib/phpexcel/PHPExcel/Calculation/Token/Stack.php @@ -0,0 +1,115 @@ +_count; + } // function count() + + /** + * Push a new entry onto the stack + * + * @param mixed $type + * @param mixed $value + * @param mixed $reference + */ + public function push($type, $value, $reference = NULL) { + $this->_stack[$this->_count++] = array('type' => $type, + 'value' => $value, + 'reference' => $reference + ); + if ($type == 'Function') { + $localeFunction = PHPExcel_Calculation::_localeFunc($value); + if ($localeFunction != $value) { + $this->_stack[($this->_count - 1)]['localeValue'] = $localeFunction; + } + } + } // function push() + + /** + * Pop the last entry from the stack + * + * @return mixed + */ + public function pop() { + if ($this->_count > 0) { + return $this->_stack[--$this->_count]; + } + return NULL; + } // function pop() + + /** + * Return an entry from the stack without removing it + * + * @param integer $n number indicating how far back in the stack we want to look + * @return mixed + */ + public function last($n = 1) { + if ($this->_count - $n < 0) { + return NULL; + } + return $this->_stack[$this->_count - $n]; + } // function last() + + /** + * Clear the stack + */ + function clear() { + $this->_stack = array(); + $this->_count = 0; + } + +} // class PHPExcel_Calculation_Token_Stack diff --git a/lib/phpexcel/PHPExcel/Calculation/functionlist.txt b/lib/phpexcel/PHPExcel/Calculation/functionlist.txt new file mode 100644 index 0000000..67dbd49 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Calculation/functionlist.txt @@ -0,0 +1,351 @@ +ABS +ACCRINT +ACCRINTM +ACOS +ACOSH +ADDRESS +AMORDEGRC +AMORLINC +AND +AREAS +ASC +ASIN +ASINH +ATAN +ATAN2 +ATANH +AVEDEV +AVERAGE +AVERAGEA +AVERAGEIF +AVERAGEIFS +BAHTTEXT +BESSELI +BESSELJ +BESSELK +BESSELY +BETADIST +BETAINV +BIN2DEC +BIN2HEX +BIN2OCT +BINOMDIST +CEILING +CELL +CHAR +CHIDIST +CHIINV +CHITEST +CHOOSE +CLEAN +CODE +COLUMN +COLUMNS +COMBIN +COMPLEX +CONCATENATE +CONFIDENCE +CONVERT +CORREL +COS +COSH +COUNT +COUNTA +COUNTBLANK +COUNTIF +COUNTIFS +COUPDAYBS +COUPDAYBS +COUPDAYSNC +COUPNCD +COUPNUM +COUPPCD +COVAR +CRITBINOM +CUBEKPIMEMBER +CUBEMEMBER +CUBEMEMBERPROPERTY +CUBERANKEDMEMBER +CUBESET +CUBESETCOUNT +CUBEVALUE +CUMIPMT +CUMPRINC +DATE +DATEDIF +DATEVALUE +DAVERAGE +DAY +DAYS360 +DB +DCOUNT +DCOUNTA +DDB +DEC2BIN +DEC2HEX +DEC2OCT +DEGREES +DELTA +DEVSQ +DGET +DISC +DMAX +DMIN +DOLLAR +DOLLARDE +DOLLARFR +DPRODUCT +DSTDEV +DSTDEVP +DSUM +DURATION +DVAR +DVARP +EDATE +EFFECT +EOMONTH +ERF +ERFC +ERROR.TYPE +EVEN +EXACT +EXP +EXPONDIST +FACT +FACTDOUBLE +FALSE +FDIST +FIND +FINDB +FINV +FISHER +FISHERINV +FIXED +FLOOR +FORECAST +FREQUENCY +FTEST +FV +FVSCHEDULE +GAMAMDIST +GAMMAINV +GAMMALN +GCD +GEOMEAN +GESTEP +GETPIVOTDATA +GROWTH +HARMEAN +HEX2BIN +HEX2OCT +HLOOKUP +HOUR +HYPERLINK +HYPGEOMDIST +IF +IFERROR +IMABS +IMAGINARY +IMARGUMENT +IMCONJUGATE +IMCOS +IMEXP +IMLN +IMLOG10 +IMLOG2 +IMPOWER +IMPRODUCT +IMREAL +IMSIN +IMSQRT +IMSUB +IMSUM +INDEX +INDIRECT +INFO +INT +INTERCEPT +INTRATE +IPMT +IRR +ISBLANK +ISERR +ISERROR +ISEVEN +ISLOGICAL +ISNA +ISNONTEXT +ISNUMBER +ISODD +ISPMT +ISREF +ISTEXT +JIS +KURT +LARGE +LCM +LEFT +LEFTB +LEN +LENB +LINEST +LN +LOG +LOG10 +LOGEST +LOGINV +LOGNORMDIST +LOOKUP +LOWER +MATCH +MAX +MAXA +MDETERM +MDURATION +MEDIAN +MID +MIDB +MIN +MINA +MINUTE +MINVERSE +MIRR +MMULT +MOD +MODE +MONTH +MROUND +MULTINOMIAL +N +NA +NEGBINOMDIST +NETWORKDAYS +NOMINAL +NORMDIST +NORMINV +NORMSDIST +NORMSINV +NOT +NOW +NPER +NPV +OCT2BIN +OCT2DEC +OCT2HEX +ODD +ODDFPRICE +ODDFYIELD +ODDLPRICE +ODDLYIELD +OFFSET +OR +PEARSON +PERCENTILE +PERCENTRANK +PERMUT +PHONETIC +PI +PMT +POISSON +POWER +PPMT +PRICE +PRICEDISC +PRICEMAT +PROB +PRODUCT +PROPER +PV +QUARTILE +QUOTIENT +RADIANS +RAND +RANDBETWEEN +RANK +RATE +RECEIVED +REPLACE +REPLACEB +REPT +RIGHT +RIGHTB +ROMAN +ROUND +ROUNDDOWN +ROUNDUP +ROW +ROWS +RSQ +RTD +SEARCH +SEARCHB +SECOND +SERIESSUM +SIGN +SIN +SINH +SKEW +SLN +SLOPE +SMALL +SQRT +SQRTPI +STANDARDIZE +STDEV +STDEVA +STDEVP +STDEVPA +STEYX +SUBSTITUTE +SUBTOTAL +SUM +SUMIF +SUMIFS +SUMPRODUCT +SUMSQ +SUMX2MY2 +SUMX2PY2 +SUMXMY2 +SYD +T +TAN +TANH +TBILLEQ +TBILLPRICE +TBILLYIELD +TDIST +TEXT +TIME +TIMEVALUE +TINV +TODAY +TRANSPOSE +TREND +TRIM +TRIMMEAN +TRUE +TRUNC +TTEST +TYPE +UPPER +USDOLLAR +VALUE +VAR +VARA +VARP +VARPA +VDB +VERSION +VLOOKUP +WEEKDAY +WEEKNUM +WEIBULL +WORKDAY +XIRR +XNPV +YEAR +YEARFRAC +YIELD +YIELDDISC +YIELDMAT +ZTEST diff --git a/lib/phpexcel/PHPExcel/Cell.php b/lib/phpexcel/PHPExcel/Cell.php new file mode 100644 index 0000000..1788559 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Cell.php @@ -0,0 +1,990 @@ +_parent->updateCacheData($this); + + return $this; + } + + public function detach() { + $this->_parent = NULL; + } + + public function attach(PHPExcel_CachedObjectStorage_CacheBase $parent) { + + + $this->_parent = $parent; + } + + + /** + * Create a new Cell + * + * @param mixed $pValue + * @param string $pDataType + * @param PHPExcel_Worksheet $pSheet + * @throws PHPExcel_Exception + */ + public function __construct($pValue = NULL, $pDataType = NULL, PHPExcel_Worksheet $pSheet = NULL) + { + // Initialise cell value + $this->_value = $pValue; + + // Set worksheet cache + $this->_parent = $pSheet->getCellCacheController(); + + // Set datatype? + if ($pDataType !== NULL) { + if ($pDataType == PHPExcel_Cell_DataType::TYPE_STRING2) + $pDataType = PHPExcel_Cell_DataType::TYPE_STRING; + $this->_dataType = $pDataType; + } else { + if (!self::getValueBinder()->bindValue($this, $pValue)) { + throw new PHPExcel_Exception("Value could not be bound to cell."); + } + } + + // set default index to cellXf + $this->_xfIndex = 0; + } + + /** + * Get cell coordinate column + * + * @return string + */ + public function getColumn() + { + return $this->_parent->getCurrentColumn(); + } + + /** + * Get cell coordinate row + * + * @return int + */ + public function getRow() + { + return $this->_parent->getCurrentRow(); + } + + /** + * Get cell coordinate + * + * @return string + */ + public function getCoordinate() + { + return $this->_parent->getCurrentAddress(); + } + + /** + * Get cell value + * + * @return mixed + */ + public function getValue() + { + return $this->_value; + } + + /** + * Get cell value with formatting + * + * @return string + */ + public function getFormattedValue() + { + return (string) PHPExcel_Style_NumberFormat::toFormattedString( + $this->getCalculatedValue(), + $this->getWorksheet()->getParent()->getCellXfByIndex($this->getXfIndex()) + ->getNumberFormat()->getFormatCode() + ); + } + + /** + * Set cell value + * + * Sets the value for a cell, automatically determining the datatype using the value binder + * + * @param mixed $pValue Value + * @return PHPExcel_Cell + * @throws PHPExcel_Exception + */ + public function setValue($pValue = NULL) + { + if (!self::getValueBinder()->bindValue($this, $pValue)) { + throw new PHPExcel_Exception("Value could not be bound to cell."); + } + return $this; + } + + /** + * Set the value for a cell, with the explicit data type passed to the method (bypassing any use of the value binder) + * + * @param mixed $pValue Value + * @param string $pDataType Explicit data type + * @return PHPExcel_Cell + * @throws PHPExcel_Exception + */ + public function setValueExplicit($pValue = NULL, $pDataType = PHPExcel_Cell_DataType::TYPE_STRING) + { + // set the value according to data type + switch ($pDataType) { + case PHPExcel_Cell_DataType::TYPE_NULL: + $this->_value = $pValue; + break; + case PHPExcel_Cell_DataType::TYPE_STRING2: + $pDataType = PHPExcel_Cell_DataType::TYPE_STRING; + case PHPExcel_Cell_DataType::TYPE_STRING: + case PHPExcel_Cell_DataType::TYPE_INLINE: + $this->_value = PHPExcel_Cell_DataType::checkString($pValue); + break; + case PHPExcel_Cell_DataType::TYPE_NUMERIC: + $this->_value = (float)$pValue; + break; + case PHPExcel_Cell_DataType::TYPE_FORMULA: + $this->_value = (string)$pValue; + break; + case PHPExcel_Cell_DataType::TYPE_BOOL: + $this->_value = (bool)$pValue; + break; + case PHPExcel_Cell_DataType::TYPE_ERROR: + $this->_value = PHPExcel_Cell_DataType::checkErrorCode($pValue); + break; + default: + throw new PHPExcel_Exception('Invalid datatype: ' . $pDataType); + break; + } + + // set the datatype + $this->_dataType = $pDataType; + + return $this->notifyCacheController(); + } + + /** + * Get calculated cell value + * + * @deprecated Since version 1.7.8 for planned changes to cell for array formula handling + * + * @param boolean $resetLog Whether the calculation engine logger should be reset or not + * @return mixed + * @throws PHPExcel_Exception + */ + public function getCalculatedValue($resetLog = TRUE) + { +//echo 'Cell '.$this->getCoordinate().' value is a '.$this->_dataType.' with a value of '.$this->getValue().PHP_EOL; + if ($this->_dataType == PHPExcel_Cell_DataType::TYPE_FORMULA) { + try { +//echo 'Cell value for '.$this->getCoordinate().' is a formula: Calculating value'.PHP_EOL; + $result = PHPExcel_Calculation::getInstance( + $this->getWorksheet()->getParent() + )->calculateCellValue($this,$resetLog); +//echo $this->getCoordinate().' calculation result is '.$result.PHP_EOL; + // We don't yet handle array returns + if (is_array($result)) { + while (is_array($result)) { + $result = array_pop($result); + } + } + } catch ( PHPExcel_Exception $ex ) { + if (($ex->getMessage() === 'Unable to access External Workbook') && ($this->_calculatedValue !== NULL)) { +//echo 'Returning fallback value of '.$this->_calculatedValue.' for cell '.$this->getCoordinate().PHP_EOL; + return $this->_calculatedValue; // Fallback for calculations referencing external files. + } +//echo 'Calculation Exception: '.$ex->getMessage().PHP_EOL; + $result = '#N/A'; + throw new PHPExcel_Calculation_Exception( + $this->getWorksheet()->getTitle().'!'.$this->getCoordinate().' -> '.$ex->getMessage() + ); + } + + if ($result === '#Not Yet Implemented') { +//echo 'Returning fallback value of '.$this->_calculatedValue.' for cell '.$this->getCoordinate().PHP_EOL; + return $this->_calculatedValue; // Fallback if calculation engine does not support the formula. + } +//echo 'Returning calculated value of '.$result.' for cell '.$this->getCoordinate().PHP_EOL; + return $result; + } elseif($this->_value instanceof PHPExcel_RichText) { +// echo 'Cell value for '.$this->getCoordinate().' is rich text: Returning data value of '.$this->_value.'
            '; + return $this->_value->getPlainText(); + } +// echo 'Cell value for '.$this->getCoordinate().' is not a formula: Returning data value of '.$this->_value.'
            '; + return $this->_value; + } + + /** + * Set old calculated value (cached) + * + * @param mixed $pValue Value + * @return PHPExcel_Cell + */ + public function setCalculatedValue($pValue = NULL) + { + if ($pValue !== NULL) { + $this->_calculatedValue = (is_numeric($pValue)) ? (float) $pValue : $pValue; + } + + return $this->notifyCacheController(); + } + + /** + * Get old calculated value (cached) + * This returns the value last calculated by MS Excel or whichever spreadsheet program was used to + * create the original spreadsheet file. + * Note that this value is not guaranteed to refelect the actual calculated value because it is + * possible that auto-calculation was disabled in the original spreadsheet, and underlying data + * values used by the formula have changed since it was last calculated. + * + * @return mixed + */ + public function getOldCalculatedValue() + { + return $this->_calculatedValue; + } + + /** + * Get cell data type + * + * @return string + */ + public function getDataType() + { + return $this->_dataType; + } + + /** + * Set cell data type + * + * @param string $pDataType + * @return PHPExcel_Cell + */ + public function setDataType($pDataType = PHPExcel_Cell_DataType::TYPE_STRING) + { + if ($pDataType == PHPExcel_Cell_DataType::TYPE_STRING2) + $pDataType = PHPExcel_Cell_DataType::TYPE_STRING; + + $this->_dataType = $pDataType; + + return $this->notifyCacheController(); + } + + /** + * Identify if the cell contains a formula + * + * @return boolean + */ + public function isFormula() + { + return $this->_dataType == PHPExcel_Cell_DataType::TYPE_FORMULA; + } + + /** + * Does this cell contain Data validation rules? + * + * @return boolean + * @throws PHPExcel_Exception + */ + public function hasDataValidation() + { + if (!isset($this->_parent)) { + throw new PHPExcel_Exception('Cannot check for data validation when cell is not bound to a worksheet'); + } + + return $this->getWorksheet()->dataValidationExists($this->getCoordinate()); + } + + /** + * Get Data validation rules + * + * @return PHPExcel_Cell_DataValidation + * @throws PHPExcel_Exception + */ + public function getDataValidation() + { + if (!isset($this->_parent)) { + throw new PHPExcel_Exception('Cannot get data validation for cell that is not bound to a worksheet'); + } + + return $this->getWorksheet()->getDataValidation($this->getCoordinate()); + } + + /** + * Set Data validation rules + * + * @param PHPExcel_Cell_DataValidation $pDataValidation + * @return PHPExcel_Cell + * @throws PHPExcel_Exception + */ + public function setDataValidation(PHPExcel_Cell_DataValidation $pDataValidation = NULL) + { + if (!isset($this->_parent)) { + throw new PHPExcel_Exception('Cannot set data validation for cell that is not bound to a worksheet'); + } + + $this->getWorksheet()->setDataValidation($this->getCoordinate(), $pDataValidation); + + return $this->notifyCacheController(); + } + + /** + * Does this cell contain a Hyperlink? + * + * @return boolean + * @throws PHPExcel_Exception + */ + public function hasHyperlink() + { + if (!isset($this->_parent)) { + throw new PHPExcel_Exception('Cannot check for hyperlink when cell is not bound to a worksheet'); + } + + return $this->getWorksheet()->hyperlinkExists($this->getCoordinate()); + } + + /** + * Get Hyperlink + * + * @return PHPExcel_Cell_Hyperlink + * @throws PHPExcel_Exception + */ + public function getHyperlink() + { + if (!isset($this->_parent)) { + throw new PHPExcel_Exception('Cannot get hyperlink for cell that is not bound to a worksheet'); + } + + return $this->getWorksheet()->getHyperlink($this->getCoordinate()); + } + + /** + * Set Hyperlink + * + * @param PHPExcel_Cell_Hyperlink $pHyperlink + * @return PHPExcel_Cell + * @throws PHPExcel_Exception + */ + public function setHyperlink(PHPExcel_Cell_Hyperlink $pHyperlink = NULL) + { + if (!isset($this->_parent)) { + throw new PHPExcel_Exception('Cannot set hyperlink for cell that is not bound to a worksheet'); + } + + $this->getWorksheet()->setHyperlink($this->getCoordinate(), $pHyperlink); + + return $this->notifyCacheController(); + } + + /** + * Get parent worksheet + * + * @return PHPExcel_CachedObjectStorage_CacheBase + */ + public function getParent() { + return $this->_parent; + } + + /** + * Get parent worksheet + * + * @return PHPExcel_Worksheet + */ + public function getWorksheet() { + return $this->_parent->getParent(); + } + + /** + * Get cell style + * + * @return PHPExcel_Style + */ + public function getStyle() + { + return $this->getWorksheet()->getParent()->getCellXfByIndex($this->getXfIndex()); + } + + /** + * Re-bind parent + * + * @param PHPExcel_Worksheet $parent + * @return PHPExcel_Cell + */ + public function rebindParent(PHPExcel_Worksheet $parent) { + $this->_parent = $parent->getCellCacheController(); + + return $this->notifyCacheController(); + } + + /** + * Is cell in a specific range? + * + * @param string $pRange Cell range (e.g. A1:A1) + * @return boolean + */ + public function isInRange($pRange = 'A1:A1') + { + list($rangeStart,$rangeEnd) = self::rangeBoundaries($pRange); + + // Translate properties + $myColumn = self::columnIndexFromString($this->getColumn()); + $myRow = $this->getRow(); + + // Verify if cell is in range + return (($rangeStart[0] <= $myColumn) && ($rangeEnd[0] >= $myColumn) && + ($rangeStart[1] <= $myRow) && ($rangeEnd[1] >= $myRow) + ); + } + + /** + * Coordinate from string + * + * @param string $pCoordinateString + * @return array Array containing column and row (indexes 0 and 1) + * @throws PHPExcel_Exception + */ + public static function coordinateFromString($pCoordinateString = 'A1') + { + if (preg_match("/^([$]?[A-Z]{1,3})([$]?\d{1,7})$/", $pCoordinateString, $matches)) { + return array($matches[1],$matches[2]); + } elseif ((strpos($pCoordinateString,':') !== FALSE) || (strpos($pCoordinateString,',') !== FALSE)) { + throw new PHPExcel_Exception('Cell coordinate string can not be a range of cells'); + } elseif ($pCoordinateString == '') { + throw new PHPExcel_Exception('Cell coordinate can not be zero-length string'); + } + + throw new PHPExcel_Exception('Invalid cell coordinate '.$pCoordinateString); + } + + /** + * Make string row, column or cell coordinate absolute + * + * @param string $pCoordinateString e.g. 'A' or '1' or 'A1' + * Note that this value can be a row or column reference as well as a cell reference + * @return string Absolute coordinate e.g. '$A' or '$1' or '$A$1' + * @throws PHPExcel_Exception + */ + public static function absoluteReference($pCoordinateString = 'A1') + { + if (strpos($pCoordinateString,':') === FALSE && strpos($pCoordinateString,',') === FALSE) { + // Split out any worksheet name from the reference + $worksheet = ''; + $cellAddress = explode('!',$pCoordinateString); + if (count($cellAddress) > 1) { + list($worksheet,$pCoordinateString) = $cellAddress; + } + if ($worksheet > '') $worksheet .= '!'; + + // Create absolute coordinate + if (ctype_digit($pCoordinateString)) { + return $worksheet . '$' . $pCoordinateString; + } elseif (ctype_alpha($pCoordinateString)) { + return $worksheet . '$' . strtoupper($pCoordinateString); + } + return $worksheet . self::absoluteCoordinate($pCoordinateString); + } + + throw new PHPExcel_Exception('Cell coordinate string can not be a range of cells'); + } + + /** + * Make string coordinate absolute + * + * @param string $pCoordinateString e.g. 'A1' + * @return string Absolute coordinate e.g. '$A$1' + * @throws PHPExcel_Exception + */ + public static function absoluteCoordinate($pCoordinateString = 'A1') + { + if (strpos($pCoordinateString,':') === FALSE && strpos($pCoordinateString,',') === FALSE) { + // Split out any worksheet name from the coordinate + $worksheet = ''; + $cellAddress = explode('!',$pCoordinateString); + if (count($cellAddress) > 1) { + list($worksheet,$pCoordinateString) = $cellAddress; + } + if ($worksheet > '') $worksheet .= '!'; + + // Create absolute coordinate + list($column, $row) = self::coordinateFromString($pCoordinateString); + $column = ltrim($column,'$'); + $row = ltrim($row,'$'); + return $worksheet . '$' . $column . '$' . $row; + } + + throw new PHPExcel_Exception('Cell coordinate string can not be a range of cells'); + } + + /** + * Split range into coordinate strings + * + * @param string $pRange e.g. 'B4:D9' or 'B4:D9,H2:O11' or 'B4' + * @return array Array containg one or more arrays containing one or two coordinate strings + * e.g. array('B4','D9') or array(array('B4','D9'),array('H2','O11')) + * or array('B4') + */ + public static function splitRange($pRange = 'A1:A1') + { + // Ensure $pRange is a valid range + if(empty($pRange)) { + $pRange = self::DEFAULT_RANGE; + } + + $exploded = explode(',', $pRange); + $counter = count($exploded); + for ($i = 0; $i < $counter; ++$i) { + $exploded[$i] = explode(':', $exploded[$i]); + } + return $exploded; + } + + /** + * Build range from coordinate strings + * + * @param array $pRange Array containg one or more arrays containing one or two coordinate strings + * @return string String representation of $pRange + * @throws PHPExcel_Exception + */ + public static function buildRange($pRange) + { + // Verify range + if (!is_array($pRange) || empty($pRange) || !is_array($pRange[0])) { + throw new PHPExcel_Exception('Range does not contain any information'); + } + + // Build range + $imploded = array(); + $counter = count($pRange); + for ($i = 0; $i < $counter; ++$i) { + $pRange[$i] = implode(':', $pRange[$i]); + } + $imploded = implode(',', $pRange); + + return $imploded; + } + + /** + * Calculate range boundaries + * + * @param string $pRange Cell range (e.g. A1:A1) + * @return array Range coordinates array(Start Cell, End Cell) + * where Start Cell and End Cell are arrays (Column Number, Row Number) + */ + public static function rangeBoundaries($pRange = 'A1:A1') + { + // Ensure $pRange is a valid range + if(empty($pRange)) { + $pRange = self::DEFAULT_RANGE; + } + + // Uppercase coordinate + $pRange = strtoupper($pRange); + + // Extract range + if (strpos($pRange, ':') === FALSE) { + $rangeA = $rangeB = $pRange; + } else { + list($rangeA, $rangeB) = explode(':', $pRange); + } + + // Calculate range outer borders + $rangeStart = self::coordinateFromString($rangeA); + $rangeEnd = self::coordinateFromString($rangeB); + + // Translate column into index + $rangeStart[0] = self::columnIndexFromString($rangeStart[0]); + $rangeEnd[0] = self::columnIndexFromString($rangeEnd[0]); + + return array($rangeStart, $rangeEnd); + } + + /** + * Calculate range dimension + * + * @param string $pRange Cell range (e.g. A1:A1) + * @return array Range dimension (width, height) + */ + public static function rangeDimension($pRange = 'A1:A1') + { + // Calculate range outer borders + list($rangeStart,$rangeEnd) = self::rangeBoundaries($pRange); + + return array( ($rangeEnd[0] - $rangeStart[0] + 1), ($rangeEnd[1] - $rangeStart[1] + 1) ); + } + + /** + * Calculate range boundaries + * + * @param string $pRange Cell range (e.g. A1:A1) + * @return array Range coordinates array(Start Cell, End Cell) + * where Start Cell and End Cell are arrays (Column ID, Row Number) + */ + public static function getRangeBoundaries($pRange = 'A1:A1') + { + // Ensure $pRange is a valid range + if(empty($pRange)) { + $pRange = self::DEFAULT_RANGE; + } + + // Uppercase coordinate + $pRange = strtoupper($pRange); + + // Extract range + if (strpos($pRange, ':') === FALSE) { + $rangeA = $rangeB = $pRange; + } else { + list($rangeA, $rangeB) = explode(':', $pRange); + } + + return array( self::coordinateFromString($rangeA), self::coordinateFromString($rangeB)); + } + + /** + * Column index from string + * + * @param string $pString + * @return int Column index (base 1 !!!) + */ + public static function columnIndexFromString($pString = 'A') + { + // Using a lookup cache adds a slight memory overhead, but boosts speed + // caching using a static within the method is faster than a class static, + // though it's additional memory overhead + static $_indexCache = array(); + + if (isset($_indexCache[$pString])) + return $_indexCache[$pString]; + + // It's surprising how costly the strtoupper() and ord() calls actually are, so we use a lookup array rather than use ord() + // and make it case insensitive to get rid of the strtoupper() as well. Because it's a static, there's no significant + // memory overhead either + static $_columnLookup = array( + 'A' => 1, 'B' => 2, 'C' => 3, 'D' => 4, 'E' => 5, 'F' => 6, 'G' => 7, 'H' => 8, 'I' => 9, 'J' => 10, 'K' => 11, 'L' => 12, 'M' => 13, + 'N' => 14, 'O' => 15, 'P' => 16, 'Q' => 17, 'R' => 18, 'S' => 19, 'T' => 20, 'U' => 21, 'V' => 22, 'W' => 23, 'X' => 24, 'Y' => 25, 'Z' => 26, + 'a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5, 'f' => 6, 'g' => 7, 'h' => 8, 'i' => 9, 'j' => 10, 'k' => 11, 'l' => 12, 'm' => 13, + 'n' => 14, 'o' => 15, 'p' => 16, 'q' => 17, 'r' => 18, 's' => 19, 't' => 20, 'u' => 21, 'v' => 22, 'w' => 23, 'x' => 24, 'y' => 25, 'z' => 26 + ); + + // We also use the language construct isset() rather than the more costly strlen() function to match the length of $pString + // for improved performance + if (isset($pString{0})) { + if (!isset($pString{1})) { + $_indexCache[$pString] = $_columnLookup[$pString]; + return $_indexCache[$pString]; + } elseif(!isset($pString{2})) { + $_indexCache[$pString] = $_columnLookup[$pString{0}] * 26 + $_columnLookup[$pString{1}]; + return $_indexCache[$pString]; + } elseif(!isset($pString{3})) { + $_indexCache[$pString] = $_columnLookup[$pString{0}] * 676 + $_columnLookup[$pString{1}] * 26 + $_columnLookup[$pString{2}]; + return $_indexCache[$pString]; + } + } + throw new PHPExcel_Exception("Column string index can not be " . ((isset($pString{0})) ? "longer than 3 characters" : "empty")); + } + + /** + * String from columnindex + * + * @param int $pColumnIndex Column index (base 0 !!!) + * @return string + */ + public static function stringFromColumnIndex($pColumnIndex = 0) + { + // Using a lookup cache adds a slight memory overhead, but boosts speed + // caching using a static within the method is faster than a class static, + // though it's additional memory overhead + static $_indexCache = array(); + + if (!isset($_indexCache[$pColumnIndex])) { + // Determine column string + if ($pColumnIndex < 26) { + $_indexCache[$pColumnIndex] = chr(65 + $pColumnIndex); + } elseif ($pColumnIndex < 702) { + $_indexCache[$pColumnIndex] = chr(64 + ($pColumnIndex / 26)) . + chr(65 + $pColumnIndex % 26); + } else { + $_indexCache[$pColumnIndex] = chr(64 + (($pColumnIndex - 26) / 676)) . + chr(65 + ((($pColumnIndex - 26) % 676) / 26)) . + chr(65 + $pColumnIndex % 26); + } + } + return $_indexCache[$pColumnIndex]; + } + + /** + * Extract all cell references in range + * + * @param string $pRange Range (e.g. A1 or A1:C10 or A1:E10 A20:E25) + * @return array Array containing single cell references + */ + public static function extractAllCellReferencesInRange($pRange = 'A1') { + // Returnvalue + $returnValue = array(); + + // Explode spaces + $cellBlocks = explode(' ', str_replace('$', '', strtoupper($pRange))); + foreach ($cellBlocks as $cellBlock) { + // Single cell? + if (strpos($cellBlock,':') === FALSE && strpos($cellBlock,',') === FALSE) { + $returnValue[] = $cellBlock; + continue; + } + + // Range... + $ranges = self::splitRange($cellBlock); + foreach($ranges as $range) { + // Single cell? + if (!isset($range[1])) { + $returnValue[] = $range[0]; + continue; + } + + // Range... + list($rangeStart, $rangeEnd) = $range; + sscanf($rangeStart,'%[A-Z]%d', $startCol, $startRow); + sscanf($rangeEnd,'%[A-Z]%d', $endCol, $endRow); + $endCol++; + + // Current data + $currentCol = $startCol; + $currentRow = $startRow; + + // Loop cells + while ($currentCol != $endCol) { + while ($currentRow <= $endRow) { + $returnValue[] = $currentCol.$currentRow; + ++$currentRow; + } + ++$currentCol; + $currentRow = $startRow; + } + } + } + + // Sort the result by column and row + $sortKeys = array(); + foreach (array_unique($returnValue) as $coord) { + sscanf($coord,'%[A-Z]%d', $column, $row); + $sortKeys[sprintf('%3s%09d',$column,$row)] = $coord; + } + ksort($sortKeys); + + // Return value + return array_values($sortKeys); + } + + /** + * Compare 2 cells + * + * @param PHPExcel_Cell $a Cell a + * @param PHPExcel_Cell $b Cell b + * @return int Result of comparison (always -1 or 1, never zero!) + */ + public static function compareCells(PHPExcel_Cell $a, PHPExcel_Cell $b) + { + if ($a->getRow() < $b->getRow()) { + return -1; + } elseif ($a->getRow() > $b->getRow()) { + return 1; + } elseif (self::columnIndexFromString($a->getColumn()) < self::columnIndexFromString($b->getColumn())) { + return -1; + } else { + return 1; + } + } + + /** + * Get value binder to use + * + * @return PHPExcel_Cell_IValueBinder + */ + public static function getValueBinder() { + if (self::$_valueBinder === NULL) { + self::$_valueBinder = new PHPExcel_Cell_DefaultValueBinder(); + } + + return self::$_valueBinder; + } + + /** + * Set value binder to use + * + * @param PHPExcel_Cell_IValueBinder $binder + * @throws PHPExcel_Exception + */ + public static function setValueBinder(PHPExcel_Cell_IValueBinder $binder = NULL) { + if ($binder === NULL) { + throw new PHPExcel_Exception("A PHPExcel_Cell_IValueBinder is required for PHPExcel to function correctly."); + } + + self::$_valueBinder = $binder; + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if ((is_object($value)) && ($key != '_parent')) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } + + /** + * Get index to cellXf + * + * @return int + */ + public function getXfIndex() + { + return $this->_xfIndex; + } + + /** + * Set index to cellXf + * + * @param int $pValue + * @return PHPExcel_Cell + */ + public function setXfIndex($pValue = 0) + { + $this->_xfIndex = $pValue; + + return $this->notifyCacheController(); + } + + /** + * @deprecated Since version 1.7.8 for planned changes to cell for array formula handling + */ + public function setFormulaAttributes($pAttributes) + { + $this->_formulaAttributes = $pAttributes; + return $this; + } + + /** + * @deprecated Since version 1.7.8 for planned changes to cell for array formula handling + */ + public function getFormulaAttributes() + { + return $this->_formulaAttributes; + } + + /** + * Convert to string + * + * @return string + */ + public function __toString() + { + return (string) $this->getValue(); + } + +} + diff --git a/lib/phpexcel/PHPExcel/Cell/AdvancedValueBinder.php b/lib/phpexcel/PHPExcel/Cell/AdvancedValueBinder.php new file mode 100644 index 0000000..00a2b57 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Cell/AdvancedValueBinder.php @@ -0,0 +1,192 @@ +setValueExplicit( TRUE, PHPExcel_Cell_DataType::TYPE_BOOL); + return true; + } elseif($value == PHPExcel_Calculation::getFALSE()) { + $cell->setValueExplicit( FALSE, PHPExcel_Cell_DataType::TYPE_BOOL); + return true; + } + + // Check for number in scientific format + if (preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_NUMBER.'$/', $value)) { + $cell->setValueExplicit( (float) $value, PHPExcel_Cell_DataType::TYPE_NUMERIC); + return true; + } + + // Check for fraction + if (preg_match('/^([+-]?)\s*([0-9]+)\s?\/\s*([0-9]+)$/', $value, $matches)) { + // Convert value to number + $value = $matches[2] / $matches[3]; + if ($matches[1] == '-') $value = 0 - $value; + $cell->setValueExplicit( (float) $value, PHPExcel_Cell_DataType::TYPE_NUMERIC); + // Set style + $cell->getWorksheet()->getStyle( $cell->getCoordinate() ) + ->getNumberFormat()->setFormatCode( '??/??' ); + return true; + } elseif (preg_match('/^([+-]?)([0-9]*) +([0-9]*)\s?\/\s*([0-9]*)$/', $value, $matches)) { + // Convert value to number + $value = $matches[2] + ($matches[3] / $matches[4]); + if ($matches[1] == '-') $value = 0 - $value; + $cell->setValueExplicit( (float) $value, PHPExcel_Cell_DataType::TYPE_NUMERIC); + // Set style + $cell->getWorksheet()->getStyle( $cell->getCoordinate() ) + ->getNumberFormat()->setFormatCode( '# ??/??' ); + return true; + } + + // Check for percentage + if (preg_match('/^\-?[0-9]*\.?[0-9]*\s?\%$/', $value)) { + // Convert value to number + $value = (float) str_replace('%', '', $value) / 100; + $cell->setValueExplicit( $value, PHPExcel_Cell_DataType::TYPE_NUMERIC); + // Set style + $cell->getWorksheet()->getStyle( $cell->getCoordinate() ) + ->getNumberFormat()->setFormatCode( PHPExcel_Style_NumberFormat::FORMAT_PERCENTAGE_00 ); + return true; + } + + // Check for currency + $currencyCode = PHPExcel_Shared_String::getCurrencyCode(); + $decimalSeparator = PHPExcel_Shared_String::getDecimalSeparator(); + $thousandsSeparator = PHPExcel_Shared_String::getThousandsSeparator(); + if (preg_match('/^'.preg_quote($currencyCode).' *(\d{1,3}('.preg_quote($thousandsSeparator).'\d{3})*|(\d+))('.preg_quote($decimalSeparator).'\d{2})?$/', $value)) { + // Convert value to number + $value = (float) trim(str_replace(array($currencyCode, $thousandsSeparator, $decimalSeparator), array('', '', '.'), $value)); + $cell->setValueExplicit( $value, PHPExcel_Cell_DataType::TYPE_NUMERIC); + // Set style + $cell->getWorksheet()->getStyle( $cell->getCoordinate() ) + ->getNumberFormat()->setFormatCode( + str_replace('$', $currencyCode, PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_USD_SIMPLE ) + ); + return true; + } elseif (preg_match('/^\$ *(\d{1,3}(\,\d{3})*|(\d+))(\.\d{2})?$/', $value)) { + // Convert value to number + $value = (float) trim(str_replace(array('$',','), '', $value)); + $cell->setValueExplicit( $value, PHPExcel_Cell_DataType::TYPE_NUMERIC); + // Set style + $cell->getWorksheet()->getStyle( $cell->getCoordinate() ) + ->getNumberFormat()->setFormatCode( PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_USD_SIMPLE ); + return true; + } + + // Check for time without seconds e.g. '9:45', '09:45' + if (preg_match('/^(\d|[0-1]\d|2[0-3]):[0-5]\d$/', $value)) { + // Convert value to number + list($h, $m) = explode(':', $value); + $days = $h / 24 + $m / 1440; + $cell->setValueExplicit($days, PHPExcel_Cell_DataType::TYPE_NUMERIC); + // Set style + $cell->getWorksheet()->getStyle( $cell->getCoordinate() ) + ->getNumberFormat()->setFormatCode( PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME3 ); + return true; + } + + // Check for time with seconds '9:45:59', '09:45:59' + if (preg_match('/^(\d|[0-1]\d|2[0-3]):[0-5]\d:[0-5]\d$/', $value)) { + // Convert value to number + list($h, $m, $s) = explode(':', $value); + $days = $h / 24 + $m / 1440 + $s / 86400; + // Convert value to number + $cell->setValueExplicit($days, PHPExcel_Cell_DataType::TYPE_NUMERIC); + // Set style + $cell->getWorksheet()->getStyle( $cell->getCoordinate() ) + ->getNumberFormat()->setFormatCode( PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4 ); + return true; + } + + // Check for datetime, e.g. '2008-12-31', '2008-12-31 15:59', '2008-12-31 15:59:10' + if (($d = PHPExcel_Shared_Date::stringToExcel($value)) !== false) { + // Convert value to number + $cell->setValueExplicit($d, PHPExcel_Cell_DataType::TYPE_NUMERIC); + // Determine style. Either there is a time part or not. Look for ':' + if (strpos($value, ':') !== false) { + $formatCode = 'yyyy-mm-dd h:mm'; + } else { + $formatCode = 'yyyy-mm-dd'; + } + $cell->getWorksheet()->getStyle( $cell->getCoordinate() ) + ->getNumberFormat()->setFormatCode($formatCode); + return true; + } + + // Check for newline character "\n" + if (strpos($value, "\n") !== FALSE) { + $value = PHPExcel_Shared_String::SanitizeUTF8($value); + $cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_STRING); + // Set style + $cell->getWorksheet()->getStyle( $cell->getCoordinate() ) + ->getAlignment()->setWrapText(TRUE); + return true; + } + } + + // Not bound yet? Use parent... + return parent::bindValue($cell, $value); + } +} diff --git a/lib/phpexcel/PHPExcel/Cell/DataType.php b/lib/phpexcel/PHPExcel/Cell/DataType.php new file mode 100644 index 0000000..8576542 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Cell/DataType.php @@ -0,0 +1,122 @@ + 0, + '#DIV/0!' => 1, + '#VALUE!' => 2, + '#REF!' => 3, + '#NAME?' => 4, + '#NUM!' => 5, + '#N/A' => 6 + ); + + /** + * Get list of error codes + * + * @return array + */ + public static function getErrorCodes() { + return self::$_errorCodes; + } + + /** + * DataType for value + * + * @deprecated Replaced by PHPExcel_Cell_IValueBinder infrastructure, will be removed in version 1.8.0 + * @param mixed $pValue + * @return string + */ + public static function dataTypeForValue($pValue = null) { + return PHPExcel_Cell_DefaultValueBinder::dataTypeForValue($pValue); + } + + /** + * Check a string that it satisfies Excel requirements + * + * @param mixed Value to sanitize to an Excel string + * @return mixed Sanitized value + */ + public static function checkString($pValue = null) + { + if ($pValue instanceof PHPExcel_RichText) { + // TODO: Sanitize Rich-Text string (max. character count is 32,767) + return $pValue; + } + + // string must never be longer than 32,767 characters, truncate if necessary + $pValue = PHPExcel_Shared_String::Substring($pValue, 0, 32767); + + // we require that newline is represented as "\n" in core, not as "\r\n" or "\r" + $pValue = str_replace(array("\r\n", "\r"), "\n", $pValue); + + return $pValue; + } + + /** + * Check a value that it is a valid error code + * + * @param mixed Value to sanitize to an Excel error code + * @return string Sanitized value + */ + public static function checkErrorCode($pValue = null) + { + $pValue = (string) $pValue; + + if ( !array_key_exists($pValue, self::$_errorCodes) ) { + $pValue = '#NULL!'; + } + + return $pValue; + } + +} diff --git a/lib/phpexcel/PHPExcel/Cell/DataValidation.php b/lib/phpexcel/PHPExcel/Cell/DataValidation.php new file mode 100644 index 0000000..3174a3f --- /dev/null +++ b/lib/phpexcel/PHPExcel/Cell/DataValidation.php @@ -0,0 +1,472 @@ +_formula1 = ''; + $this->_formula2 = ''; + $this->_type = PHPExcel_Cell_DataValidation::TYPE_NONE; + $this->_errorStyle = PHPExcel_Cell_DataValidation::STYLE_STOP; + $this->_operator = ''; + $this->_allowBlank = FALSE; + $this->_showDropDown = FALSE; + $this->_showInputMessage = FALSE; + $this->_showErrorMessage = FALSE; + $this->_errorTitle = ''; + $this->_error = ''; + $this->_promptTitle = ''; + $this->_prompt = ''; + } + + /** + * Get Formula 1 + * + * @return string + */ + public function getFormula1() { + return $this->_formula1; + } + + /** + * Set Formula 1 + * + * @param string $value + * @return PHPExcel_Cell_DataValidation + */ + public function setFormula1($value = '') { + $this->_formula1 = $value; + return $this; + } + + /** + * Get Formula 2 + * + * @return string + */ + public function getFormula2() { + return $this->_formula2; + } + + /** + * Set Formula 2 + * + * @param string $value + * @return PHPExcel_Cell_DataValidation + */ + public function setFormula2($value = '') { + $this->_formula2 = $value; + return $this; + } + + /** + * Get Type + * + * @return string + */ + public function getType() { + return $this->_type; + } + + /** + * Set Type + * + * @param string $value + * @return PHPExcel_Cell_DataValidation + */ + public function setType($value = PHPExcel_Cell_DataValidation::TYPE_NONE) { + $this->_type = $value; + return $this; + } + + /** + * Get Error style + * + * @return string + */ + public function getErrorStyle() { + return $this->_errorStyle; + } + + /** + * Set Error style + * + * @param string $value + * @return PHPExcel_Cell_DataValidation + */ + public function setErrorStyle($value = PHPExcel_Cell_DataValidation::STYLE_STOP) { + $this->_errorStyle = $value; + return $this; + } + + /** + * Get Operator + * + * @return string + */ + public function getOperator() { + return $this->_operator; + } + + /** + * Set Operator + * + * @param string $value + * @return PHPExcel_Cell_DataValidation + */ + public function setOperator($value = '') { + $this->_operator = $value; + return $this; + } + + /** + * Get Allow Blank + * + * @return boolean + */ + public function getAllowBlank() { + return $this->_allowBlank; + } + + /** + * Set Allow Blank + * + * @param boolean $value + * @return PHPExcel_Cell_DataValidation + */ + public function setAllowBlank($value = false) { + $this->_allowBlank = $value; + return $this; + } + + /** + * Get Show DropDown + * + * @return boolean + */ + public function getShowDropDown() { + return $this->_showDropDown; + } + + /** + * Set Show DropDown + * + * @param boolean $value + * @return PHPExcel_Cell_DataValidation + */ + public function setShowDropDown($value = false) { + $this->_showDropDown = $value; + return $this; + } + + /** + * Get Show InputMessage + * + * @return boolean + */ + public function getShowInputMessage() { + return $this->_showInputMessage; + } + + /** + * Set Show InputMessage + * + * @param boolean $value + * @return PHPExcel_Cell_DataValidation + */ + public function setShowInputMessage($value = false) { + $this->_showInputMessage = $value; + return $this; + } + + /** + * Get Show ErrorMessage + * + * @return boolean + */ + public function getShowErrorMessage() { + return $this->_showErrorMessage; + } + + /** + * Set Show ErrorMessage + * + * @param boolean $value + * @return PHPExcel_Cell_DataValidation + */ + public function setShowErrorMessage($value = false) { + $this->_showErrorMessage = $value; + return $this; + } + + /** + * Get Error title + * + * @return string + */ + public function getErrorTitle() { + return $this->_errorTitle; + } + + /** + * Set Error title + * + * @param string $value + * @return PHPExcel_Cell_DataValidation + */ + public function setErrorTitle($value = '') { + $this->_errorTitle = $value; + return $this; + } + + /** + * Get Error + * + * @return string + */ + public function getError() { + return $this->_error; + } + + /** + * Set Error + * + * @param string $value + * @return PHPExcel_Cell_DataValidation + */ + public function setError($value = '') { + $this->_error = $value; + return $this; + } + + /** + * Get Prompt title + * + * @return string + */ + public function getPromptTitle() { + return $this->_promptTitle; + } + + /** + * Set Prompt title + * + * @param string $value + * @return PHPExcel_Cell_DataValidation + */ + public function setPromptTitle($value = '') { + $this->_promptTitle = $value; + return $this; + } + + /** + * Get Prompt + * + * @return string + */ + public function getPrompt() { + return $this->_prompt; + } + + /** + * Set Prompt + * + * @param string $value + * @return PHPExcel_Cell_DataValidation + */ + public function setPrompt($value = '') { + $this->_prompt = $value; + return $this; + } + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() { + return md5( + $this->_formula1 + . $this->_formula2 + . $this->_type = PHPExcel_Cell_DataValidation::TYPE_NONE + . $this->_errorStyle = PHPExcel_Cell_DataValidation::STYLE_STOP + . $this->_operator + . ($this->_allowBlank ? 't' : 'f') + . ($this->_showDropDown ? 't' : 'f') + . ($this->_showInputMessage ? 't' : 'f') + . ($this->_showErrorMessage ? 't' : 'f') + . $this->_errorTitle + . $this->_error + . $this->_promptTitle + . $this->_prompt + . __CLASS__ + ); + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } +} diff --git a/lib/phpexcel/PHPExcel/Cell/DefaultValueBinder.php b/lib/phpexcel/PHPExcel/Cell/DefaultValueBinder.php new file mode 100644 index 0000000..f1880fa --- /dev/null +++ b/lib/phpexcel/PHPExcel/Cell/DefaultValueBinder.php @@ -0,0 +1,106 @@ +setValueExplicit( $value, self::dataTypeForValue($value) ); + + // Done! + return TRUE; + } + + /** + * DataType for value + * + * @param mixed $pValue + * @return string + */ + public static function dataTypeForValue($pValue = null) { + // Match the value against a few data types + if (is_null($pValue)) { + return PHPExcel_Cell_DataType::TYPE_NULL; + + } elseif ($pValue === '') { + return PHPExcel_Cell_DataType::TYPE_STRING; + + } elseif ($pValue instanceof PHPExcel_RichText) { + return PHPExcel_Cell_DataType::TYPE_INLINE; + + } elseif ($pValue{0} === '=' && strlen($pValue) > 1) { + return PHPExcel_Cell_DataType::TYPE_FORMULA; + + } elseif (is_bool($pValue)) { + return PHPExcel_Cell_DataType::TYPE_BOOL; + + } elseif (is_float($pValue) || is_int($pValue)) { + return PHPExcel_Cell_DataType::TYPE_NUMERIC; + + } elseif (preg_match('/^\-?([0-9]+\\.?[0-9]*|[0-9]*\\.?[0-9]+)$/', $pValue)) { + return PHPExcel_Cell_DataType::TYPE_NUMERIC; + + } elseif (is_string($pValue) && array_key_exists($pValue, PHPExcel_Cell_DataType::getErrorCodes())) { + return PHPExcel_Cell_DataType::TYPE_ERROR; + + } else { + return PHPExcel_Cell_DataType::TYPE_STRING; + + } + } +} diff --git a/lib/phpexcel/PHPExcel/Cell/Hyperlink.php b/lib/phpexcel/PHPExcel/Cell/Hyperlink.php new file mode 100644 index 0000000..06edfad --- /dev/null +++ b/lib/phpexcel/PHPExcel/Cell/Hyperlink.php @@ -0,0 +1,126 @@ +_url = $pUrl; + $this->_tooltip = $pTooltip; + } + + /** + * Get URL + * + * @return string + */ + public function getUrl() { + return $this->_url; + } + + /** + * Set URL + * + * @param string $value + * @return PHPExcel_Cell_Hyperlink + */ + public function setUrl($value = '') { + $this->_url = $value; + return $this; + } + + /** + * Get tooltip + * + * @return string + */ + public function getTooltip() { + return $this->_tooltip; + } + + /** + * Set tooltip + * + * @param string $value + * @return PHPExcel_Cell_Hyperlink + */ + public function setTooltip($value = '') { + $this->_tooltip = $value; + return $this; + } + + /** + * Is this hyperlink internal? (to another worksheet) + * + * @return boolean + */ + public function isInternal() { + return strpos($this->_url, 'sheet://') !== false; + } + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() { + return md5( + $this->_url + . $this->_tooltip + . __CLASS__ + ); + } +} diff --git a/lib/phpexcel/PHPExcel/Cell/IValueBinder.php b/lib/phpexcel/PHPExcel/Cell/IValueBinder.php new file mode 100644 index 0000000..bc7b468 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Cell/IValueBinder.php @@ -0,0 +1,46 @@ +_name = $name; + $this->_title = $title; + $this->_legend = $legend; + $this->_xAxisLabel = $xAxisLabel; + $this->_yAxisLabel = $yAxisLabel; + $this->_plotArea = $plotArea; + $this->_plotVisibleOnly = $plotVisibleOnly; + $this->_displayBlanksAs = $displayBlanksAs; + } + + /** + * Get Name + * + * @return string + */ + public function getName() { + return $this->_name; + } + + /** + * Get Worksheet + * + * @return PHPExcel_Worksheet + */ + public function getWorksheet() { + return $this->_worksheet; + } + + /** + * Set Worksheet + * + * @param PHPExcel_Worksheet $pValue + * @throws PHPExcel_Chart_Exception + * @return PHPExcel_Chart + */ + public function setWorksheet(PHPExcel_Worksheet $pValue = null) { + $this->_worksheet = $pValue; + + return $this; + } + + /** + * Get Title + * + * @return PHPExcel_Chart_Title + */ + public function getTitle() { + return $this->_title; + } + + /** + * Set Title + * + * @param PHPExcel_Chart_Title $title + * @return PHPExcel_Chart + */ + public function setTitle(PHPExcel_Chart_Title $title) { + $this->_title = $title; + + return $this; + } + + /** + * Get Legend + * + * @return PHPExcel_Chart_Legend + */ + public function getLegend() { + return $this->_legend; + } + + /** + * Set Legend + * + * @param PHPExcel_Chart_Legend $legend + * @return PHPExcel_Chart + */ + public function setLegend(PHPExcel_Chart_Legend $legend) { + $this->_legend = $legend; + + return $this; + } + + /** + * Get X-Axis Label + * + * @return PHPExcel_Chart_Title + */ + public function getXAxisLabel() { + return $this->_xAxisLabel; + } + + /** + * Set X-Axis Label + * + * @param PHPExcel_Chart_Title $label + * @return PHPExcel_Chart + */ + public function setXAxisLabel(PHPExcel_Chart_Title $label) { + $this->_xAxisLabel = $label; + + return $this; + } + + /** + * Get Y-Axis Label + * + * @return PHPExcel_Chart_Title + */ + public function getYAxisLabel() { + return $this->_yAxisLabel; + } + + /** + * Set Y-Axis Label + * + * @param PHPExcel_Chart_Title $label + * @return PHPExcel_Chart + */ + public function setYAxisLabel(PHPExcel_Chart_Title $label) { + $this->_yAxisLabel = $label; + + return $this; + } + + /** + * Get Plot Area + * + * @return PHPExcel_Chart_PlotArea + */ + public function getPlotArea() { + return $this->_plotArea; + } + + /** + * Get Plot Visible Only + * + * @return boolean + */ + public function getPlotVisibleOnly() { + return $this->_plotVisibleOnly; + } + + /** + * Set Plot Visible Only + * + * @param boolean $plotVisibleOnly + * @return PHPExcel_Chart + */ + public function setPlotVisibleOnly($plotVisibleOnly = true) { + $this->_plotVisibleOnly = $plotVisibleOnly; + + return $this; + } + + /** + * Get Display Blanks as + * + * @return string + */ + public function getDisplayBlanksAs() { + return $this->_displayBlanksAs; + } + + /** + * Set Display Blanks as + * + * @param string $displayBlanksAs + * @return PHPExcel_Chart + */ + public function setDisplayBlanksAs($displayBlanksAs = '0') { + $this->_displayBlanksAs = $displayBlanksAs; + } + + + /** + * Set the Top Left position for the chart + * + * @param string $cell + * @param integer $xOffset + * @param integer $yOffset + * @return PHPExcel_Chart + */ + public function setTopLeftPosition($cell, $xOffset=null, $yOffset=null) { + $this->_topLeftCellRef = $cell; + if (!is_null($xOffset)) + $this->setTopLeftXOffset($xOffset); + if (!is_null($yOffset)) + $this->setTopLeftYOffset($yOffset); + + return $this; + } + + /** + * Get the top left position of the chart + * + * @return array an associative array containing the cell address, X-Offset and Y-Offset from the top left of that cell + */ + public function getTopLeftPosition() { + return array( 'cell' => $this->_topLeftCellRef, + 'xOffset' => $this->_topLeftXOffset, + 'yOffset' => $this->_topLeftYOffset + ); + } + + /** + * Get the cell address where the top left of the chart is fixed + * + * @return string + */ + public function getTopLeftCell() { + return $this->_topLeftCellRef; + } + + /** + * Set the Top Left cell position for the chart + * + * @param string $cell + * @return PHPExcel_Chart + */ + public function setTopLeftCell($cell) { + $this->_topLeftCellRef = $cell; + + return $this; + } + + /** + * Set the offset position within the Top Left cell for the chart + * + * @param integer $xOffset + * @param integer $yOffset + * @return PHPExcel_Chart + */ + public function setTopLeftOffset($xOffset=null,$yOffset=null) { + if (!is_null($xOffset)) + $this->setTopLeftXOffset($xOffset); + if (!is_null($yOffset)) + $this->setTopLeftYOffset($yOffset); + + return $this; + } + + /** + * Get the offset position within the Top Left cell for the chart + * + * @return integer[] + */ + public function getTopLeftOffset() { + return array( 'X' => $this->_topLeftXOffset, + 'Y' => $this->_topLeftYOffset + ); + } + + public function setTopLeftXOffset($xOffset) { + $this->_topLeftXOffset = $xOffset; + + return $this; + } + + public function getTopLeftXOffset() { + return $this->_topLeftXOffset; + } + + public function setTopLeftYOffset($yOffset) { + $this->_topLeftYOffset = $yOffset; + + return $this; + } + + public function getTopLeftYOffset() { + return $this->_topLeftYOffset; + } + + /** + * Set the Bottom Right position of the chart + * + * @param string $cell + * @param integer $xOffset + * @param integer $yOffset + * @return PHPExcel_Chart + */ + public function setBottomRightPosition($cell, $xOffset=null, $yOffset=null) { + $this->_bottomRightCellRef = $cell; + if (!is_null($xOffset)) + $this->setBottomRightXOffset($xOffset); + if (!is_null($yOffset)) + $this->setBottomRightYOffset($yOffset); + + return $this; + } + + /** + * Get the bottom right position of the chart + * + * @return array an associative array containing the cell address, X-Offset and Y-Offset from the top left of that cell + */ + public function getBottomRightPosition() { + return array( 'cell' => $this->_bottomRightCellRef, + 'xOffset' => $this->_bottomRightXOffset, + 'yOffset' => $this->_bottomRightYOffset + ); + } + + public function setBottomRightCell($cell) { + $this->_bottomRightCellRef = $cell; + + return $this; + } + + /** + * Get the cell address where the bottom right of the chart is fixed + * + * @return string + */ + public function getBottomRightCell() { + return $this->_bottomRightCellRef; + } + + /** + * Set the offset position within the Bottom Right cell for the chart + * + * @param integer $xOffset + * @param integer $yOffset + * @return PHPExcel_Chart + */ + public function setBottomRightOffset($xOffset=null,$yOffset=null) { + if (!is_null($xOffset)) + $this->setBottomRightXOffset($xOffset); + if (!is_null($yOffset)) + $this->setBottomRightYOffset($yOffset); + + return $this; + } + + /** + * Get the offset position within the Bottom Right cell for the chart + * + * @return integer[] + */ + public function getBottomRightOffset() { + return array( 'X' => $this->_bottomRightXOffset, + 'Y' => $this->_bottomRightYOffset + ); + } + + public function setBottomRightXOffset($xOffset) { + $this->_bottomRightXOffset = $xOffset; + + return $this; + } + + public function getBottomRightXOffset() { + return $this->_bottomRightXOffset; + } + + public function setBottomRightYOffset($yOffset) { + $this->_bottomRightYOffset = $yOffset; + + return $this; + } + + public function getBottomRightYOffset() { + return $this->_bottomRightYOffset; + } + + + public function refresh() { + if ($this->_worksheet !== NULL) { + $this->_plotArea->refresh($this->_worksheet); + } + } + + public function render($outputDestination = null) { + $libraryName = PHPExcel_Settings::getChartRendererName(); + if (is_null($libraryName)) { + return false; + } + // Ensure that data series values are up-to-date before we render + $this->refresh(); + + $libraryPath = PHPExcel_Settings::getChartRendererPath(); + $includePath = str_replace('\\','/',get_include_path()); + $rendererPath = str_replace('\\','/',$libraryPath); + if (strpos($rendererPath,$includePath) === false) { + set_include_path(get_include_path() . PATH_SEPARATOR . $libraryPath); + } + + $rendererName = 'PHPExcel_Chart_Renderer_'.$libraryName; + $renderer = new $rendererName($this); + + if ($outputDestination == 'php://output') { + $outputDestination = null; + } + return $renderer->render($outputDestination); + } + +} diff --git a/lib/phpexcel/PHPExcel/Chart/DataSeries.php b/lib/phpexcel/PHPExcel/Chart/DataSeries.php new file mode 100644 index 0000000..f5391aa --- /dev/null +++ b/lib/phpexcel/PHPExcel/Chart/DataSeries.php @@ -0,0 +1,365 @@ +_plotType = $plotType; + $this->_plotGrouping = $plotGrouping; + $this->_plotOrder = $plotOrder; + $keys = array_keys($plotValues); + $this->_plotValues = $plotValues; + if ((count($plotLabel) == 0) || (is_null($plotLabel[$keys[0]]))) { + $plotLabel[$keys[0]] = new PHPExcel_Chart_DataSeriesValues(); + } + + $this->_plotLabel = $plotLabel; + if ((count($plotCategory) == 0) || (is_null($plotCategory[$keys[0]]))) { + $plotCategory[$keys[0]] = new PHPExcel_Chart_DataSeriesValues(); + } + $this->_plotCategory = $plotCategory; + $this->_smoothLine = $smoothLine; + $this->_plotStyle = $plotStyle; + } + + /** + * Get Plot Type + * + * @return string + */ + public function getPlotType() { + return $this->_plotType; + } + + /** + * Set Plot Type + * + * @param string $plotType + * @return PHPExcel_Chart_DataSeries + */ + public function setPlotType($plotType = '') { + $this->_plotType = $plotType; + return $this; + } + + /** + * Get Plot Grouping Type + * + * @return string + */ + public function getPlotGrouping() { + return $this->_plotGrouping; + } + + /** + * Set Plot Grouping Type + * + * @param string $groupingType + * @return PHPExcel_Chart_DataSeries + */ + public function setPlotGrouping($groupingType = null) { + $this->_plotGrouping = $groupingType; + return $this; + } + + /** + * Get Plot Direction + * + * @return string + */ + public function getPlotDirection() { + return $this->_plotDirection; + } + + /** + * Set Plot Direction + * + * @param string $plotDirection + * @return PHPExcel_Chart_DataSeries + */ + public function setPlotDirection($plotDirection = null) { + $this->_plotDirection = $plotDirection; + return $this; + } + + /** + * Get Plot Order + * + * @return string + */ + public function getPlotOrder() { + return $this->_plotOrder; + } + + /** + * Get Plot Labels + * + * @return array of PHPExcel_Chart_DataSeriesValues + */ + public function getPlotLabels() { + return $this->_plotLabel; + } + + /** + * Get Plot Label by Index + * + * @return PHPExcel_Chart_DataSeriesValues + */ + public function getPlotLabelByIndex($index) { + $keys = array_keys($this->_plotLabel); + if (in_array($index,$keys)) { + return $this->_plotLabel[$index]; + } elseif(isset($keys[$index])) { + return $this->_plotLabel[$keys[$index]]; + } + return false; + } + + /** + * Get Plot Categories + * + * @return array of PHPExcel_Chart_DataSeriesValues + */ + public function getPlotCategories() { + return $this->_plotCategory; + } + + /** + * Get Plot Category by Index + * + * @return PHPExcel_Chart_DataSeriesValues + */ + public function getPlotCategoryByIndex($index) { + $keys = array_keys($this->_plotCategory); + if (in_array($index,$keys)) { + return $this->_plotCategory[$index]; + } elseif(isset($keys[$index])) { + return $this->_plotCategory[$keys[$index]]; + } + return false; + } + + /** + * Get Plot Style + * + * @return string + */ + public function getPlotStyle() { + return $this->_plotStyle; + } + + /** + * Set Plot Style + * + * @param string $plotStyle + * @return PHPExcel_Chart_DataSeries + */ + public function setPlotStyle($plotStyle = null) { + $this->_plotStyle = $plotStyle; + return $this; + } + + /** + * Get Plot Values + * + * @return array of PHPExcel_Chart_DataSeriesValues + */ + public function getPlotValues() { + return $this->_plotValues; + } + + /** + * Get Plot Values by Index + * + * @return PHPExcel_Chart_DataSeriesValues + */ + public function getPlotValuesByIndex($index) { + $keys = array_keys($this->_plotValues); + if (in_array($index,$keys)) { + return $this->_plotValues[$index]; + } elseif(isset($keys[$index])) { + return $this->_plotValues[$keys[$index]]; + } + return false; + } + + /** + * Get Number of Plot Series + * + * @return integer + */ + public function getPlotSeriesCount() { + return count($this->_plotValues); + } + + /** + * Get Smooth Line + * + * @return boolean + */ + public function getSmoothLine() { + return $this->_smoothLine; + } + + /** + * Set Smooth Line + * + * @param boolean $smoothLine + * @return PHPExcel_Chart_DataSeries + */ + public function setSmoothLine($smoothLine = TRUE) { + $this->_smoothLine = $smoothLine; + return $this; + } + + public function refresh(PHPExcel_Worksheet $worksheet) { + foreach($this->_plotValues as $plotValues) { + if ($plotValues !== NULL) + $plotValues->refresh($worksheet, TRUE); + } + foreach($this->_plotLabel as $plotValues) { + if ($plotValues !== NULL) + $plotValues->refresh($worksheet, TRUE); + } + foreach($this->_plotCategory as $plotValues) { + if ($plotValues !== NULL) + $plotValues->refresh($worksheet, FALSE); + } + } + +} diff --git a/lib/phpexcel/PHPExcel/Chart/DataSeriesValues.php b/lib/phpexcel/PHPExcel/Chart/DataSeriesValues.php new file mode 100644 index 0000000..930542b --- /dev/null +++ b/lib/phpexcel/PHPExcel/Chart/DataSeriesValues.php @@ -0,0 +1,327 @@ +setDataType($dataType); + $this->_dataSource = $dataSource; + $this->_formatCode = $formatCode; + $this->_pointCount = $pointCount; + $this->_dataValues = $dataValues; + $this->_marker = $marker; + } + + /** + * Get Series Data Type + * + * @return string + */ + public function getDataType() { + return $this->_dataType; + } + + /** + * Set Series Data Type + * + * @param string $dataType Datatype of this data series + * Typical values are: + * PHPExcel_Chart_DataSeriesValues::DATASERIES_TYPE_STRING + * Normally used for axis point values + * PHPExcel_Chart_DataSeriesValues::DATASERIES_TYPE_NUMBER + * Normally used for chart data values + * @return PHPExcel_Chart_DataSeriesValues + */ + public function setDataType($dataType = self::DATASERIES_TYPE_NUMBER) { + if (!in_array($dataType, self::$_dataTypeValues)) { + throw new PHPExcel_Chart_Exception('Invalid datatype for chart data series values'); + } + $this->_dataType = $dataType; + + return $this; + } + + /** + * Get Series Data Source (formula) + * + * @return string + */ + public function getDataSource() { + return $this->_dataSource; + } + + /** + * Set Series Data Source (formula) + * + * @param string $dataSource + * @return PHPExcel_Chart_DataSeriesValues + */ + public function setDataSource($dataSource = null, $refreshDataValues = true) { + $this->_dataSource = $dataSource; + + if ($refreshDataValues) { + // TO DO + } + + return $this; + } + + /** + * Get Point Marker + * + * @return string + */ + public function getPointMarker() { + return $this->_marker; + } + + /** + * Set Point Marker + * + * @param string $marker + * @return PHPExcel_Chart_DataSeriesValues + */ + public function setPointMarker($marker = null) { + $this->_marker = $marker; + + return $this; + } + + /** + * Get Series Format Code + * + * @return string + */ + public function getFormatCode() { + return $this->_formatCode; + } + + /** + * Set Series Format Code + * + * @param string $formatCode + * @return PHPExcel_Chart_DataSeriesValues + */ + public function setFormatCode($formatCode = null) { + $this->_formatCode = $formatCode; + + return $this; + } + + /** + * Get Series Point Count + * + * @return integer + */ + public function getPointCount() { + return $this->_pointCount; + } + + /** + * Identify if the Data Series is a multi-level or a simple series + * + * @return boolean + */ + public function isMultiLevelSeries() { + if (count($this->_dataValues) > 0) { + return is_array($this->_dataValues[0]); + } + return null; + } + + /** + * Return the level count of a multi-level Data Series + * + * @return boolean + */ + public function multiLevelCount() { + $levelCount = 0; + foreach($this->_dataValues as $dataValueSet) { + $levelCount = max($levelCount,count($dataValueSet)); + } + return $levelCount; + } + + /** + * Get Series Data Values + * + * @return array of mixed + */ + public function getDataValues() { + return $this->_dataValues; + } + + /** + * Get the first Series Data value + * + * @return mixed + */ + public function getDataValue() { + $count = count($this->_dataValues); + if ($count == 0) { + return null; + } elseif ($count == 1) { + return $this->_dataValues[0]; + } + return $this->_dataValues; + } + + /** + * Set Series Data Values + * + * @param array $dataValues + * @param boolean $refreshDataSource + * TRUE - refresh the value of _dataSource based on the values of $dataValues + * FALSE - don't change the value of _dataSource + * @return PHPExcel_Chart_DataSeriesValues + */ + public function setDataValues($dataValues = array(), $refreshDataSource = TRUE) { + $this->_dataValues = PHPExcel_Calculation_Functions::flattenArray($dataValues); + $this->_pointCount = count($dataValues); + + if ($refreshDataSource) { + // TO DO + } + + return $this; + } + + private function _stripNulls($var) { + return $var !== NULL; + } + + public function refresh(PHPExcel_Worksheet $worksheet, $flatten = TRUE) { + if ($this->_dataSource !== NULL) { + $calcEngine = PHPExcel_Calculation::getInstance($worksheet->getParent()); + $newDataValues = PHPExcel_Calculation::_unwrapResult( + $calcEngine->_calculateFormulaValue( + '='.$this->_dataSource, + NULL, + $worksheet->getCell('A1') + ) + ); + if ($flatten) { + $this->_dataValues = PHPExcel_Calculation_Functions::flattenArray($newDataValues); + foreach($this->_dataValues as &$dataValue) { + if ((!empty($dataValue)) && ($dataValue[0] == '#')) { + $dataValue = 0.0; + } + } + unset($dataValue); + } else { + $cellRange = explode('!',$this->_dataSource); + if (count($cellRange) > 1) { + list(,$cellRange) = $cellRange; + } + + $dimensions = PHPExcel_Cell::rangeDimension(str_replace('$','',$cellRange)); + if (($dimensions[0] == 1) || ($dimensions[1] == 1)) { + $this->_dataValues = PHPExcel_Calculation_Functions::flattenArray($newDataValues); + } else { + $newArray = array_values(array_shift($newDataValues)); + foreach($newArray as $i => $newDataSet) { + $newArray[$i] = array($newDataSet); + } + + foreach($newDataValues as $newDataSet) { + $i = 0; + foreach($newDataSet as $newDataVal) { + array_unshift($newArray[$i++],$newDataVal); + } + } + $this->_dataValues = $newArray; + } + } + $this->_pointCount = count($this->_dataValues); + } + + } + +} diff --git a/lib/phpexcel/PHPExcel/Chart/Exception.php b/lib/phpexcel/PHPExcel/Chart/Exception.php new file mode 100644 index 0000000..ecf3c43 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Chart/Exception.php @@ -0,0 +1,52 @@ +line = $line; + $e->file = $file; + throw $e; + } +} diff --git a/lib/phpexcel/PHPExcel/Chart/Layout.php b/lib/phpexcel/PHPExcel/Chart/Layout.php new file mode 100644 index 0000000..d749dfe --- /dev/null +++ b/lib/phpexcel/PHPExcel/Chart/Layout.php @@ -0,0 +1,445 @@ +_layoutTarget = $layout['layoutTarget']; } + if (isset($layout['xMode'])) { $this->_xMode = $layout['xMode']; } + if (isset($layout['yMode'])) { $this->_yMode = $layout['yMode']; } + if (isset($layout['x'])) { $this->_xPos = (float) $layout['x']; } + if (isset($layout['y'])) { $this->_yPos = (float) $layout['y']; } + if (isset($layout['w'])) { $this->_width = (float) $layout['w']; } + if (isset($layout['h'])) { $this->_height = (float) $layout['h']; } + } + + /** + * Get Layout Target + * + * @return string + */ + public function getLayoutTarget() { + return $this->_layoutTarget; + } + + /** + * Set Layout Target + * + * @param Layout Target $value + * @return PHPExcel_Chart_Layout + */ + public function setLayoutTarget($value) { + $this->_layoutTarget = $value; + return $this; + } + + /** + * Get X-Mode + * + * @return string + */ + public function getXMode() { + return $this->_xMode; + } + + /** + * Set X-Mode + * + * @param X-Mode $value + * @return PHPExcel_Chart_Layout + */ + public function setXMode($value) { + $this->_xMode = $value; + return $this; + } + + /** + * Get Y-Mode + * + * @return string + */ + public function getYMode() { + return $this->_yMode; + } + + /** + * Set Y-Mode + * + * @param Y-Mode $value + * @return PHPExcel_Chart_Layout + */ + public function setYMode($value) { + $this->_yMode = $value; + return $this; + } + + /** + * Get X-Position + * + * @return number + */ + public function getXPosition() { + return $this->_xPos; + } + + /** + * Set X-Position + * + * @param X-Position $value + * @return PHPExcel_Chart_Layout + */ + public function setXPosition($value) { + $this->_xPos = $value; + return $this; + } + + /** + * Get Y-Position + * + * @return number + */ + public function getYPosition() { + return $this->_yPos; + } + + /** + * Set Y-Position + * + * @param Y-Position $value + * @return PHPExcel_Chart_Layout + */ + public function setYPosition($value) { + $this->_yPos = $value; + return $this; + } + + /** + * Get Width + * + * @return number + */ + public function getWidth() { + return $this->_width; + } + + /** + * Set Width + * + * @param Width $value + * @return PHPExcel_Chart_Layout + */ + public function setWidth($value) { + $this->_width = $value; + return $this; + } + + /** + * Get Height + * + * @return number + */ + public function getHeight() { + return $this->_height; + } + + /** + * Set Height + * + * @param Height $value + * @return PHPExcel_Chart_Layout + */ + public function setHeight($value) { + $this->_height = $value; + return $this; + } + + + /** + * Get show legend key + * + * @return boolean + */ + public function getShowLegendKey() { + return $this->_showLegendKey; + } + + /** + * Set show legend key + * Specifies that legend keys should be shown in data labels. + * + * @param boolean $value Show legend key + * @return PHPExcel_Chart_Layout + */ + public function setShowLegendKey($value) { + $this->_showLegendKey = $value; + return $this; + } + + /** + * Get show value + * + * @return boolean + */ + public function getShowVal() { + return $this->_showVal; + } + + /** + * Set show val + * Specifies that the value should be shown in data labels. + * + * @param boolean $value Show val + * @return PHPExcel_Chart_Layout + */ + public function setShowVal($value) { + $this->_showVal = $value; + return $this; + } + + /** + * Get show category name + * + * @return boolean + */ + public function getShowCatName() { + return $this->_showCatName; + } + + /** + * Set show cat name + * Specifies that the category name should be shown in data labels. + * + * @param boolean $value Show cat name + * @return PHPExcel_Chart_Layout + */ + public function setShowCatName($value) { + $this->_showCatName = $value; + return $this; + } + + /** + * Get show data series name + * + * @return boolean + */ + public function getShowSerName() { + return $this->_showSerName; + } + + /** + * Set show ser name + * Specifies that the series name should be shown in data labels. + * + * @param boolean $value Show series name + * @return PHPExcel_Chart_Layout + */ + public function setShowSerName($value) { + $this->_showSerName = $value; + return $this; + } + + /** + * Get show percentage + * + * @return boolean + */ + public function getShowPercent() { + return $this->_showPercent; + } + + /** + * Set show percentage + * Specifies that the percentage should be shown in data labels. + * + * @param boolean $value Show percentage + * @return PHPExcel_Chart_Layout + */ + public function setShowPercent($value) { + $this->_showPercent = $value; + return $this; + } + + /** + * Get show bubble size + * + * @return boolean + */ + public function getShowBubbleSize() { + return $this->_showBubbleSize; + } + + /** + * Set show bubble size + * Specifies that the bubble size should be shown in data labels. + * + * @param boolean $value Show bubble size + * @return PHPExcel_Chart_Layout + */ + public function setShowBubbleSize($value) { + $this->_showBubbleSize = $value; + return $this; + } + + /** + * Get show leader lines + * + * @return boolean + */ + public function getShowLeaderLines() { + return $this->_showLeaderLines; + } + + /** + * Set show leader lines + * Specifies that leader lines should be shown in data labels. + * + * @param boolean $value Show leader lines + * @return PHPExcel_Chart_Layout + */ + public function setShowLeaderLines($value) { + $this->_showLeaderLines = $value; + return $this; + } + +} diff --git a/lib/phpexcel/PHPExcel/Chart/Legend.php b/lib/phpexcel/PHPExcel/Chart/Legend.php new file mode 100644 index 0000000..4b7c644 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Chart/Legend.php @@ -0,0 +1,171 @@ + self::POSITION_BOTTOM, + self::xlLegendPositionCorner => self::POSITION_TOPRIGHT, + self::xlLegendPositionCustom => '??', + self::xlLegendPositionLeft => self::POSITION_LEFT, + self::xlLegendPositionRight => self::POSITION_RIGHT, + self::xlLegendPositionTop => self::POSITION_TOP + ); + + /** + * Legend position + * + * @var string + */ + private $_position = self::POSITION_RIGHT; + + /** + * Allow overlay of other elements? + * + * @var boolean + */ + private $_overlay = TRUE; + + /** + * Legend Layout + * + * @var PHPExcel_Chart_Layout + */ + private $_layout = NULL; + + + /** + * Create a new PHPExcel_Chart_Legend + */ + public function __construct($position = self::POSITION_RIGHT, PHPExcel_Chart_Layout $layout = NULL, $overlay = FALSE) + { + $this->setPosition($position); + $this->_layout = $layout; + $this->setOverlay($overlay); + } + + /** + * Get legend position as an excel string value + * + * @return string + */ + public function getPosition() { + return $this->_position; + } + + /** + * Get legend position using an excel string value + * + * @param string $position + */ + public function setPosition($position = self::POSITION_RIGHT) { + if (!in_array($position,self::$_positionXLref)) { + return false; + } + + $this->_position = $position; + return true; + } + + /** + * Get legend position as an Excel internal numeric value + * + * @return number + */ + public function getPositionXL() { + return array_search($this->_position,self::$_positionXLref); + } + + /** + * Set legend position using an Excel internal numeric value + * + * @param number $positionXL + */ + public function setPositionXL($positionXL = self::xlLegendPositionRight) { + if (!array_key_exists($positionXL,self::$_positionXLref)) { + return false; + } + + $this->_position = self::$_positionXLref[$positionXL]; + return true; + } + + /** + * Get allow overlay of other elements? + * + * @return boolean + */ + public function getOverlay() { + return $this->_overlay; + } + + /** + * Set allow overlay of other elements? + * + * @param boolean $overlay + * @return boolean + */ + public function setOverlay($overlay = FALSE) { + if (!is_bool($overlay)) { + return false; + } + + $this->_overlay = $overlay; + return true; + } + + /** + * Get Layout + * + * @return PHPExcel_Chart_Layout + */ + public function getLayout() { + return $this->_layout; + } + +} diff --git a/lib/phpexcel/PHPExcel/Chart/PlotArea.php b/lib/phpexcel/PHPExcel/Chart/PlotArea.php new file mode 100644 index 0000000..237d29b --- /dev/null +++ b/lib/phpexcel/PHPExcel/Chart/PlotArea.php @@ -0,0 +1,128 @@ +_layout = $layout; + $this->_plotSeries = $plotSeries; + } + + /** + * Get Layout + * + * @return PHPExcel_Chart_Layout + */ + public function getLayout() { + return $this->_layout; + } + + /** + * Get Number of Plot Groups + * + * @return array of PHPExcel_Chart_DataSeries + */ + public function getPlotGroupCount() { + return count($this->_plotSeries); + } + + /** + * Get Number of Plot Series + * + * @return integer + */ + public function getPlotSeriesCount() { + $seriesCount = 0; + foreach($this->_plotSeries as $plot) { + $seriesCount += $plot->getPlotSeriesCount(); + } + return $seriesCount; + } + + /** + * Get Plot Series + * + * @return array of PHPExcel_Chart_DataSeries + */ + public function getPlotGroup() { + return $this->_plotSeries; + } + + /** + * Get Plot Series by Index + * + * @return PHPExcel_Chart_DataSeries + */ + public function getPlotGroupByIndex($index) { + return $this->_plotSeries[$index]; + } + + /** + * Set Plot Series + * + * @param [PHPExcel_Chart_DataSeries] + * @return PHPExcel_Chart_PlotArea + */ + public function setPlotSeries($plotSeries = array()) { + $this->_plotSeries = $plotSeries; + + return $this; + } + + public function refresh(PHPExcel_Worksheet $worksheet) { + foreach($this->_plotSeries as $plotSeries) { + $plotSeries->refresh($worksheet); + } + } + +} diff --git a/lib/phpexcel/PHPExcel/Chart/Renderer/PHP Charting Libraries.txt b/lib/phpexcel/PHPExcel/Chart/Renderer/PHP Charting Libraries.txt new file mode 100644 index 0000000..20a8258 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Chart/Renderer/PHP Charting Libraries.txt @@ -0,0 +1,17 @@ +ChartDirector + http://www.advsofteng.com/cdphp.html + +GraPHPite + http://graphpite.sourceforge.net/ + +JpGraph + http://www.aditus.nu/jpgraph/ + +LibChart + http://naku.dohcrew.com/libchart/pages/introduction/ + +pChart + http://pchart.sourceforge.net/ + +TeeChart + http://www.steema.com/products/teechart/overview.html diff --git a/lib/phpexcel/PHPExcel/Chart/Renderer/jpgraph.php b/lib/phpexcel/PHPExcel/Chart/Renderer/jpgraph.php new file mode 100644 index 0000000..ae88c62 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Chart/Renderer/jpgraph.php @@ -0,0 +1,855 @@ + MARK_DIAMOND, + 'square' => MARK_SQUARE, + 'triangle' => MARK_UTRIANGLE, + 'x' => MARK_X, + 'star' => MARK_STAR, + 'dot' => MARK_FILLEDCIRCLE, + 'dash' => MARK_DTRIANGLE, + 'circle' => MARK_CIRCLE, + 'plus' => MARK_CROSS + ); + + + private $_chart = null; + + private $_graph = null; + + private static $_plotColour = 0; + + private static $_plotMark = 0; + + + private function _formatPointMarker($seriesPlot,$markerID) { + $plotMarkKeys = array_keys(self::$_markSet); + if (is_null($markerID)) { + // Use default plot marker (next marker in the series) + self::$_plotMark %= count(self::$_markSet); + $seriesPlot->mark->SetType(self::$_markSet[$plotMarkKeys[self::$_plotMark++]]); + } elseif ($markerID !== 'none') { + // Use specified plot marker (if it exists) + if (isset(self::$_markSet[$markerID])) { + $seriesPlot->mark->SetType(self::$_markSet[$markerID]); + } else { + // If the specified plot marker doesn't exist, use default plot marker (next marker in the series) + self::$_plotMark %= count(self::$_markSet); + $seriesPlot->mark->SetType(self::$_markSet[$plotMarkKeys[self::$_plotMark++]]); + } + } else { + // Hide plot marker + $seriesPlot->mark->Hide(); + } + $seriesPlot->mark->SetColor(self::$_colourSet[self::$_plotColour]); + $seriesPlot->mark->SetFillColor(self::$_colourSet[self::$_plotColour]); + $seriesPlot->SetColor(self::$_colourSet[self::$_plotColour++]); + + return $seriesPlot; + } // function _formatPointMarker() + + + private function _formatDataSetLabels($groupID, $datasetLabels, $labelCount, $rotation = '') { + $datasetLabelFormatCode = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getFormatCode(); + if (!is_null($datasetLabelFormatCode)) { + // Retrieve any label formatting code + $datasetLabelFormatCode = stripslashes($datasetLabelFormatCode); + } + + $testCurrentIndex = 0; + foreach($datasetLabels as $i => $datasetLabel) { + if (is_array($datasetLabel)) { + if ($rotation == 'bar') { + $datasetLabels[$i] = implode(" ",$datasetLabel); + } else { + $datasetLabel = array_reverse($datasetLabel); + $datasetLabels[$i] = implode("\n",$datasetLabel); + } + } else { + // Format labels according to any formatting code + if (!is_null($datasetLabelFormatCode)) { + $datasetLabels[$i] = PHPExcel_Style_NumberFormat::toFormattedString($datasetLabel,$datasetLabelFormatCode); + } + } + ++$testCurrentIndex; + } + + return $datasetLabels; + } // function _formatDataSetLabels() + + + private function _percentageSumCalculation($groupID,$seriesCount) { + // Adjust our values to a percentage value across all series in the group + for($i = 0; $i < $seriesCount; ++$i) { + if ($i == 0) { + $sumValues = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); + } else { + $nextValues = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); + foreach($nextValues as $k => $value) { + if (isset($sumValues[$k])) { + $sumValues[$k] += $value; + } else { + $sumValues[$k] = $value; + } + } + } + } + + return $sumValues; + } // function _percentageSumCalculation() + + + private function _percentageAdjustValues($dataValues,$sumValues) { + foreach($dataValues as $k => $dataValue) { + $dataValues[$k] = $dataValue / $sumValues[$k] * 100; + } + + return $dataValues; + } // function _percentageAdjustValues() + + + private function _getCaption($captionElement) { + // Read any caption + $caption = (!is_null($captionElement)) ? $captionElement->getCaption() : NULL; + // Test if we have a title caption to display + if (!is_null($caption)) { + // If we do, it could be a plain string or an array + if (is_array($caption)) { + // Implode an array to a plain string + $caption = implode('',$caption); + } + } + return $caption; + } // function _getCaption() + + + private function _renderTitle() { + $title = $this->_getCaption($this->_chart->getTitle()); + if (!is_null($title)) { + $this->_graph->title->Set($title); + } + } // function _renderTitle() + + + private function _renderLegend() { + $legend = $this->_chart->getLegend(); + if (!is_null($legend)) { + $legendPosition = $legend->getPosition(); + $legendOverlay = $legend->getOverlay(); + switch ($legendPosition) { + case 'r' : + $this->_graph->legend->SetPos(0.01,0.5,'right','center'); // right + $this->_graph->legend->SetColumns(1); + break; + case 'l' : + $this->_graph->legend->SetPos(0.01,0.5,'left','center'); // left + $this->_graph->legend->SetColumns(1); + break; + case 't' : + $this->_graph->legend->SetPos(0.5,0.01,'center','top'); // top + break; + case 'b' : + $this->_graph->legend->SetPos(0.5,0.99,'center','bottom'); // bottom + break; + default : + $this->_graph->legend->SetPos(0.01,0.01,'right','top'); // top-right + $this->_graph->legend->SetColumns(1); + break; + } + } else { + $this->_graph->legend->Hide(); + } + } // function _renderLegend() + + + private function _renderCartesianPlotArea($type='textlin') { + $this->_graph = new Graph(self::$_width,self::$_height); + $this->_graph->SetScale($type); + + $this->_renderTitle(); + + // Rotate for bar rather than column chart + $rotation = $this->_chart->getPlotArea()->getPlotGroupByIndex(0)->getPlotDirection(); + $reverse = ($rotation == 'bar') ? true : false; + + $xAxisLabel = $this->_chart->getXAxisLabel(); + if (!is_null($xAxisLabel)) { + $title = $this->_getCaption($xAxisLabel); + if (!is_null($title)) { + $this->_graph->xaxis->SetTitle($title,'center'); + $this->_graph->xaxis->title->SetMargin(35); + if ($reverse) { + $this->_graph->xaxis->title->SetAngle(90); + $this->_graph->xaxis->title->SetMargin(90); + } + } + } + + $yAxisLabel = $this->_chart->getYAxisLabel(); + if (!is_null($yAxisLabel)) { + $title = $this->_getCaption($yAxisLabel); + if (!is_null($title)) { + $this->_graph->yaxis->SetTitle($title,'center'); + if ($reverse) { + $this->_graph->yaxis->title->SetAngle(0); + $this->_graph->yaxis->title->SetMargin(-55); + } + } + } + } // function _renderCartesianPlotArea() + + + private function _renderPiePlotArea($doughnut = False) { + $this->_graph = new PieGraph(self::$_width,self::$_height); + + $this->_renderTitle(); + } // function _renderPiePlotArea() + + + private function _renderRadarPlotArea() { + $this->_graph = new RadarGraph(self::$_width,self::$_height); + $this->_graph->SetScale('lin'); + + $this->_renderTitle(); + } // function _renderRadarPlotArea() + + + private function _renderPlotLine($groupID, $filled = false, $combination = false, $dimensions = '2d') { + $grouping = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); + + $labelCount = count($this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount()); + if ($labelCount > 0) { + $datasetLabels = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); + $datasetLabels = $this->_formatDataSetLabels($groupID, $datasetLabels, $labelCount); + $this->_graph->xaxis->SetTickLabels($datasetLabels); + } + + $seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); + $seriesPlots = array(); + if ($grouping == 'percentStacked') { + $sumValues = $this->_percentageSumCalculation($groupID,$seriesCount); + } + + // Loop through each data series in turn + for($i = 0; $i < $seriesCount; ++$i) { + $dataValues = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); + $marker = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getPointMarker(); + + if ($grouping == 'percentStacked') { + $dataValues = $this->_percentageAdjustValues($dataValues,$sumValues); + } + + // Fill in any missing values in the $dataValues array + $testCurrentIndex = 0; + foreach($dataValues as $k => $dataValue) { + while($k != $testCurrentIndex) { + $dataValues[$testCurrentIndex] = null; + ++$testCurrentIndex; + } + ++$testCurrentIndex; + } + + $seriesPlot = new LinePlot($dataValues); + if ($combination) { + $seriesPlot->SetBarCenter(); + } + + if ($filled) { + $seriesPlot->SetFilled(true); + $seriesPlot->SetColor('black'); + $seriesPlot->SetFillColor(self::$_colourSet[self::$_plotColour++]); + } else { + // Set the appropriate plot marker + $this->_formatPointMarker($seriesPlot,$marker); + } + $dataLabel = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($i)->getDataValue(); + $seriesPlot->SetLegend($dataLabel); + + $seriesPlots[] = $seriesPlot; + } + + if ($grouping == 'standard') { + $groupPlot = $seriesPlots; + } else { + $groupPlot = new AccLinePlot($seriesPlots); + } + $this->_graph->Add($groupPlot); + } // function _renderPlotLine() + + + private function _renderPlotBar($groupID, $dimensions = '2d') { + $rotation = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotDirection(); + // Rotate for bar rather than column chart + if (($groupID == 0) && ($rotation == 'bar')) { + $this->_graph->Set90AndMargin(); + } + $grouping = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); + + $labelCount = count($this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount()); + if ($labelCount > 0) { + $datasetLabels = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); + $datasetLabels = $this->_formatDataSetLabels($groupID, $datasetLabels, $labelCount, $rotation); + // Rotate for bar rather than column chart + if ($rotation == 'bar') { + $datasetLabels = array_reverse($datasetLabels); + $this->_graph->yaxis->SetPos('max'); + $this->_graph->yaxis->SetLabelAlign('center','top'); + $this->_graph->yaxis->SetLabelSide(SIDE_RIGHT); + } + $this->_graph->xaxis->SetTickLabels($datasetLabels); + } + + + $seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); + $seriesPlots = array(); + if ($grouping == 'percentStacked') { + $sumValues = $this->_percentageSumCalculation($groupID,$seriesCount); + } + + // Loop through each data series in turn + for($j = 0; $j < $seriesCount; ++$j) { + $dataValues = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($j)->getDataValues(); + if ($grouping == 'percentStacked') { + $dataValues = $this->_percentageAdjustValues($dataValues,$sumValues); + } + + // Fill in any missing values in the $dataValues array + $testCurrentIndex = 0; + foreach($dataValues as $k => $dataValue) { + while($k != $testCurrentIndex) { + $dataValues[$testCurrentIndex] = null; + ++$testCurrentIndex; + } + ++$testCurrentIndex; + } + + // Reverse the $dataValues order for bar rather than column chart + if ($rotation == 'bar') { + $dataValues = array_reverse($dataValues); + } + $seriesPlot = new BarPlot($dataValues); + $seriesPlot->SetColor('black'); + $seriesPlot->SetFillColor(self::$_colourSet[self::$_plotColour++]); + if ($dimensions == '3d') { + $seriesPlot->SetShadow(); + } + if (!$this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($j)) { + $dataLabel = ''; + } else { + $dataLabel = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($j)->getDataValue(); + } + $seriesPlot->SetLegend($dataLabel); + + $seriesPlots[] = $seriesPlot; + } + // Reverse the plot order for bar rather than column chart + if (($rotation == 'bar') && (!($grouping == 'percentStacked'))) { + $seriesPlots = array_reverse($seriesPlots); + } + + if ($grouping == 'clustered') { + $groupPlot = new GroupBarPlot($seriesPlots); + } elseif ($grouping == 'standard') { + $groupPlot = new GroupBarPlot($seriesPlots); + } else { + $groupPlot = new AccBarPlot($seriesPlots); + if ($dimensions == '3d') { + $groupPlot->SetShadow(); + } + } + + $this->_graph->Add($groupPlot); + } // function _renderPlotBar() + + + private function _renderPlotScatter($groupID,$bubble) { + $grouping = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); + $scatterStyle = $bubbleSize = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle(); + + $seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); + $seriesPlots = array(); + + // Loop through each data series in turn + for($i = 0; $i < $seriesCount; ++$i) { + $dataValuesY = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex($i)->getDataValues(); + $dataValuesX = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); + + foreach($dataValuesY as $k => $dataValueY) { + $dataValuesY[$k] = $k; + } + + $seriesPlot = new ScatterPlot($dataValuesX,$dataValuesY); + if ($scatterStyle == 'lineMarker') { + $seriesPlot->SetLinkPoints(); + $seriesPlot->link->SetColor(self::$_colourSet[self::$_plotColour]); + } elseif ($scatterStyle == 'smoothMarker') { + $spline = new Spline($dataValuesY,$dataValuesX); + list($splineDataY,$splineDataX) = $spline->Get(count($dataValuesX) * self::$_width / 20); + $lplot = new LinePlot($splineDataX,$splineDataY); + $lplot->SetColor(self::$_colourSet[self::$_plotColour]); + + $this->_graph->Add($lplot); + } + + if ($bubble) { + $this->_formatPointMarker($seriesPlot,'dot'); + $seriesPlot->mark->SetColor('black'); + $seriesPlot->mark->SetSize($bubbleSize); + } else { + $marker = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getPointMarker(); + $this->_formatPointMarker($seriesPlot,$marker); + } + $dataLabel = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($i)->getDataValue(); + $seriesPlot->SetLegend($dataLabel); + + $this->_graph->Add($seriesPlot); + } + } // function _renderPlotScatter() + + + private function _renderPlotRadar($groupID) { + $radarStyle = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle(); + + $seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); + $seriesPlots = array(); + + // Loop through each data series in turn + for($i = 0; $i < $seriesCount; ++$i) { + $dataValuesY = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex($i)->getDataValues(); + $dataValuesX = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); + $marker = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getPointMarker(); + + $dataValues = array(); + foreach($dataValuesY as $k => $dataValueY) { + $dataValues[$k] = implode(' ',array_reverse($dataValueY)); + } + $tmp = array_shift($dataValues); + $dataValues[] = $tmp; + $tmp = array_shift($dataValuesX); + $dataValuesX[] = $tmp; + + $this->_graph->SetTitles(array_reverse($dataValues)); + + $seriesPlot = new RadarPlot(array_reverse($dataValuesX)); + + $dataLabel = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($i)->getDataValue(); + $seriesPlot->SetColor(self::$_colourSet[self::$_plotColour++]); + if ($radarStyle == 'filled') { + $seriesPlot->SetFillColor(self::$_colourSet[self::$_plotColour]); + } + $this->_formatPointMarker($seriesPlot,$marker); + $seriesPlot->SetLegend($dataLabel); + + $this->_graph->Add($seriesPlot); + } + } // function _renderPlotRadar() + + + private function _renderPlotContour($groupID) { + $contourStyle = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle(); + + $seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); + $seriesPlots = array(); + + $dataValues = array(); + // Loop through each data series in turn + for($i = 0; $i < $seriesCount; ++$i) { + $dataValuesY = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex($i)->getDataValues(); + $dataValuesX = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); + + $dataValues[$i] = $dataValuesX; + } + $seriesPlot = new ContourPlot($dataValues); + + $this->_graph->Add($seriesPlot); + } // function _renderPlotContour() + + + private function _renderPlotStock($groupID) { + $seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); + $plotOrder = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotOrder(); + + $dataValues = array(); + // Loop through each data series in turn and build the plot arrays + foreach($plotOrder as $i => $v) { + $dataValuesX = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($v)->getDataValues(); + foreach($dataValuesX as $j => $dataValueX) { + $dataValues[$plotOrder[$i]][$j] = $dataValueX; + } + } + if(empty($dataValues)) { + return; + } + + $dataValuesPlot = array(); + // Flatten the plot arrays to a single dimensional array to work with jpgraph + for($j = 0; $j < count($dataValues[0]); $j++) { + for($i = 0; $i < $seriesCount; $i++) { + $dataValuesPlot[] = $dataValues[$i][$j]; + } + } + + // Set the x-axis labels + $labelCount = count($this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount()); + if ($labelCount > 0) { + $datasetLabels = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); + $datasetLabels = $this->_formatDataSetLabels($groupID, $datasetLabels, $labelCount); + $this->_graph->xaxis->SetTickLabels($datasetLabels); + } + + $seriesPlot = new StockPlot($dataValuesPlot); + $seriesPlot->SetWidth(20); + + $this->_graph->Add($seriesPlot); + } // function _renderPlotStock() + + + private function _renderAreaChart($groupCount, $dimensions = '2d') { + require_once('jpgraph_line.php'); + + $this->_renderCartesianPlotArea(); + + for($i = 0; $i < $groupCount; ++$i) { + $this->_renderPlotLine($i,True,False,$dimensions); + } + } // function _renderAreaChart() + + + private function _renderLineChart($groupCount, $dimensions = '2d') { + require_once('jpgraph_line.php'); + + $this->_renderCartesianPlotArea(); + + for($i = 0; $i < $groupCount; ++$i) { + $this->_renderPlotLine($i,False,False,$dimensions); + } + } // function _renderLineChart() + + + private function _renderBarChart($groupCount, $dimensions = '2d') { + require_once('jpgraph_bar.php'); + + $this->_renderCartesianPlotArea(); + + for($i = 0; $i < $groupCount; ++$i) { + $this->_renderPlotBar($i,$dimensions); + } + } // function _renderBarChart() + + + private function _renderScatterChart($groupCount) { + require_once('jpgraph_scatter.php'); + require_once('jpgraph_regstat.php'); + require_once('jpgraph_line.php'); + + $this->_renderCartesianPlotArea('linlin'); + + for($i = 0; $i < $groupCount; ++$i) { + $this->_renderPlotScatter($i,false); + } + } // function _renderScatterChart() + + + private function _renderBubbleChart($groupCount) { + require_once('jpgraph_scatter.php'); + + $this->_renderCartesianPlotArea('linlin'); + + for($i = 0; $i < $groupCount; ++$i) { + $this->_renderPlotScatter($i,true); + } + } // function _renderBubbleChart() + + + private function _renderPieChart($groupCount, $dimensions = '2d', $doughnut = False, $multiplePlots = False) { + require_once('jpgraph_pie.php'); + if ($dimensions == '3d') { + require_once('jpgraph_pie3d.php'); + } + + $this->_renderPiePlotArea($doughnut); + + $iLimit = ($multiplePlots) ? $groupCount : 1; + for($groupID = 0; $groupID < $iLimit; ++$groupID) { + $grouping = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); + $exploded = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle(); + if ($groupID == 0) { + $labelCount = count($this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount()); + if ($labelCount > 0) { + $datasetLabels = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); + $datasetLabels = $this->_formatDataSetLabels($groupID, $datasetLabels, $labelCount); + } + } + + $seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); + $seriesPlots = array(); + // For pie charts, we only display the first series: doughnut charts generally display all series + $jLimit = ($multiplePlots) ? $seriesCount : 1; + // Loop through each data series in turn + for($j = 0; $j < $jLimit; ++$j) { + $dataValues = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($j)->getDataValues(); + + // Fill in any missing values in the $dataValues array + $testCurrentIndex = 0; + foreach($dataValues as $k => $dataValue) { + while($k != $testCurrentIndex) { + $dataValues[$testCurrentIndex] = null; + ++$testCurrentIndex; + } + ++$testCurrentIndex; + } + + if ($dimensions == '3d') { + $seriesPlot = new PiePlot3D($dataValues); + } else { + if ($doughnut) { + $seriesPlot = new PiePlotC($dataValues); + } else { + $seriesPlot = new PiePlot($dataValues); + } + } + + if ($multiplePlots) { + $seriesPlot->SetSize(($jLimit-$j) / ($jLimit * 4)); + } + + if ($doughnut) { + $seriesPlot->SetMidColor('white'); + } + + $seriesPlot->SetColor(self::$_colourSet[self::$_plotColour++]); + if (count($datasetLabels) > 0) + $seriesPlot->SetLabels(array_fill(0,count($datasetLabels),'')); + if ($dimensions != '3d') { + $seriesPlot->SetGuideLines(false); + } + if ($j == 0) { + if ($exploded) { + $seriesPlot->ExplodeAll(); + } + $seriesPlot->SetLegends($datasetLabels); + } + + $this->_graph->Add($seriesPlot); + } + } + } // function _renderPieChart() + + + private function _renderRadarChart($groupCount) { + require_once('jpgraph_radar.php'); + + $this->_renderRadarPlotArea(); + + for($groupID = 0; $groupID < $groupCount; ++$groupID) { + $this->_renderPlotRadar($groupID); + } + } // function _renderRadarChart() + + + private function _renderStockChart($groupCount) { + require_once('jpgraph_stock.php'); + + $this->_renderCartesianPlotArea('intint'); + + for($groupID = 0; $groupID < $groupCount; ++$groupID) { + $this->_renderPlotStock($groupID); + } + } // function _renderStockChart() + + + private function _renderContourChart($groupCount,$dimensions) { + require_once('jpgraph_contour.php'); + + $this->_renderCartesianPlotArea('intint'); + + for($i = 0; $i < $groupCount; ++$i) { + $this->_renderPlotContour($i); + } + } // function _renderContourChart() + + + private function _renderCombinationChart($groupCount,$dimensions,$outputDestination) { + require_once('jpgraph_line.php'); + require_once('jpgraph_bar.php'); + require_once('jpgraph_scatter.php'); + require_once('jpgraph_regstat.php'); + require_once('jpgraph_line.php'); + + $this->_renderCartesianPlotArea(); + + for($i = 0; $i < $groupCount; ++$i) { + $dimensions = null; + $chartType = $this->_chart->getPlotArea()->getPlotGroupByIndex($i)->getPlotType(); + switch ($chartType) { + case 'area3DChart' : + $dimensions = '3d'; + case 'areaChart' : + $this->_renderPlotLine($i,True,True,$dimensions); + break; + case 'bar3DChart' : + $dimensions = '3d'; + case 'barChart' : + $this->_renderPlotBar($i,$dimensions); + break; + case 'line3DChart' : + $dimensions = '3d'; + case 'lineChart' : + $this->_renderPlotLine($i,False,True,$dimensions); + break; + case 'scatterChart' : + $this->_renderPlotScatter($i,false); + break; + case 'bubbleChart' : + $this->_renderPlotScatter($i,true); + break; + default : + $this->_graph = null; + return false; + } + } + + $this->_renderLegend(); + + $this->_graph->Stroke($outputDestination); + return true; + } // function _renderCombinationChart() + + + public function render($outputDestination) { + self::$_plotColour = 0; + + $groupCount = $this->_chart->getPlotArea()->getPlotGroupCount(); + + $dimensions = null; + if ($groupCount == 1) { + $chartType = $this->_chart->getPlotArea()->getPlotGroupByIndex(0)->getPlotType(); + } else { + $chartTypes = array(); + for($i = 0; $i < $groupCount; ++$i) { + $chartTypes[] = $this->_chart->getPlotArea()->getPlotGroupByIndex($i)->getPlotType(); + } + $chartTypes = array_unique($chartTypes); + if (count($chartTypes) == 1) { + $chartType = array_pop($chartTypes); + } elseif (count($chartTypes) == 0) { + echo 'Chart is not yet implemented
            '; + return false; + } else { + return $this->_renderCombinationChart($groupCount,$dimensions,$outputDestination); + } + } + + switch ($chartType) { + case 'area3DChart' : + $dimensions = '3d'; + case 'areaChart' : + $this->_renderAreaChart($groupCount,$dimensions); + break; + case 'bar3DChart' : + $dimensions = '3d'; + case 'barChart' : + $this->_renderBarChart($groupCount,$dimensions); + break; + case 'line3DChart' : + $dimensions = '3d'; + case 'lineChart' : + $this->_renderLineChart($groupCount,$dimensions); + break; + case 'pie3DChart' : + $dimensions = '3d'; + case 'pieChart' : + $this->_renderPieChart($groupCount,$dimensions,False,False); + break; + case 'doughnut3DChart' : + $dimensions = '3d'; + case 'doughnutChart' : + $this->_renderPieChart($groupCount,$dimensions,True,True); + break; + case 'scatterChart' : + $this->_renderScatterChart($groupCount); + break; + case 'bubbleChart' : + $this->_renderBubbleChart($groupCount); + break; + case 'radarChart' : + $this->_renderRadarChart($groupCount); + break; + case 'surface3DChart' : + $dimensions = '3d'; + case 'surfaceChart' : + $this->_renderContourChart($groupCount,$dimensions); + break; + case 'stockChart' : + $this->_renderStockChart($groupCount,$dimensions); + break; + default : + echo $chartType.' is not yet implemented
            '; + return false; + } + $this->_renderLegend(); + + $this->_graph->Stroke($outputDestination); + return true; + } // function render() + + + /** + * Create a new PHPExcel_Chart_Renderer_jpgraph + */ + public function __construct(PHPExcel_Chart $chart) + { + $this->_graph = null; + $this->_chart = $chart; + } // function __construct() + +} // PHPExcel_Chart_Renderer_jpgraph diff --git a/lib/phpexcel/PHPExcel/Chart/Title.php b/lib/phpexcel/PHPExcel/Chart/Title.php new file mode 100644 index 0000000..415551b --- /dev/null +++ b/lib/phpexcel/PHPExcel/Chart/Title.php @@ -0,0 +1,92 @@ +_caption = $caption; + $this->_layout = $layout; + } + + /** + * Get caption + * + * @return string + */ + public function getCaption() { + return $this->_caption; + } + + /** + * Set caption + * + * @param string $caption + * @return PHPExcel_Chart_Title + */ + public function setCaption($caption = null) { + $this->_caption = $caption; + + return $this; + } + + /** + * Get Layout + * + * @return PHPExcel_Chart_Layout + */ + public function getLayout() { + return $this->_layout; + } + +} diff --git a/lib/phpexcel/PHPExcel/Comment.php b/lib/phpexcel/PHPExcel/Comment.php new file mode 100644 index 0000000..a2422c6 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Comment.php @@ -0,0 +1,327 @@ +_author = 'Author'; + $this->_text = new PHPExcel_RichText(); + $this->_fillColor = new PHPExcel_Style_Color('FFFFFFE1'); + $this->_alignment = PHPExcel_Style_Alignment::HORIZONTAL_GENERAL; + } + + /** + * Get Author + * + * @return string + */ + public function getAuthor() { + return $this->_author; + } + + /** + * Set Author + * + * @param string $pValue + * @return PHPExcel_Comment + */ + public function setAuthor($pValue = '') { + $this->_author = $pValue; + return $this; + } + + /** + * Get Rich text comment + * + * @return PHPExcel_RichText + */ + public function getText() { + return $this->_text; + } + + /** + * Set Rich text comment + * + * @param PHPExcel_RichText $pValue + * @return PHPExcel_Comment + */ + public function setText(PHPExcel_RichText $pValue) { + $this->_text = $pValue; + return $this; + } + + /** + * Get comment width (CSS style, i.e. XXpx or YYpt) + * + * @return string + */ + public function getWidth() { + return $this->_width; + } + + /** + * Set comment width (CSS style, i.e. XXpx or YYpt) + * + * @param string $value + * @return PHPExcel_Comment + */ + public function setWidth($value = '96pt') { + $this->_width = $value; + return $this; + } + + /** + * Get comment height (CSS style, i.e. XXpx or YYpt) + * + * @return string + */ + public function getHeight() { + return $this->_height; + } + + /** + * Set comment height (CSS style, i.e. XXpx or YYpt) + * + * @param string $value + * @return PHPExcel_Comment + */ + public function setHeight($value = '55.5pt') { + $this->_height = $value; + return $this; + } + + /** + * Get left margin (CSS style, i.e. XXpx or YYpt) + * + * @return string + */ + public function getMarginLeft() { + return $this->_marginLeft; + } + + /** + * Set left margin (CSS style, i.e. XXpx or YYpt) + * + * @param string $value + * @return PHPExcel_Comment + */ + public function setMarginLeft($value = '59.25pt') { + $this->_marginLeft = $value; + return $this; + } + + /** + * Get top margin (CSS style, i.e. XXpx or YYpt) + * + * @return string + */ + public function getMarginTop() { + return $this->_marginTop; + } + + /** + * Set top margin (CSS style, i.e. XXpx or YYpt) + * + * @param string $value + * @return PHPExcel_Comment + */ + public function setMarginTop($value = '1.5pt') { + $this->_marginTop = $value; + return $this; + } + + /** + * Is the comment visible by default? + * + * @return boolean + */ + public function getVisible() { + return $this->_visible; + } + + /** + * Set comment default visibility + * + * @param boolean $value + * @return PHPExcel_Comment + */ + public function setVisible($value = false) { + $this->_visible = $value; + return $this; + } + + /** + * Get fill color + * + * @return PHPExcel_Style_Color + */ + public function getFillColor() { + return $this->_fillColor; + } + + /** + * Set Alignment + * + * @param string $pValue + * @return PHPExcel_Comment + */ + public function setAlignment($pValue = PHPExcel_Style_Alignment::HORIZONTAL_GENERAL) { + $this->_alignment = $pValue; + return $this; + } + + /** + * Get Alignment + * + * @return string + */ + public function getAlignment() { + return $this->_alignment; + } + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() { + return md5( + $this->_author + . $this->_text->getHashCode() + . $this->_width + . $this->_height + . $this->_marginLeft + . $this->_marginTop + . ($this->_visible ? 1 : 0) + . $this->_fillColor->getHashCode() + . $this->_alignment + . __CLASS__ + ); + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } + + /** + * Convert to string + * + * @return string + */ + public function __toString() { + return $this->_text->getPlainText(); + } + +} diff --git a/lib/phpexcel/PHPExcel/DocumentProperties.php b/lib/phpexcel/PHPExcel/DocumentProperties.php new file mode 100644 index 0000000..2f1fa1e --- /dev/null +++ b/lib/phpexcel/PHPExcel/DocumentProperties.php @@ -0,0 +1,587 @@ +_lastModifiedBy = $this->_creator; + $this->_created = time(); + $this->_modified = time(); + } + + /** + * Get Creator + * + * @return string + */ + public function getCreator() { + return $this->_creator; + } + + /** + * Set Creator + * + * @param string $pValue + * @return PHPExcel_DocumentProperties + */ + public function setCreator($pValue = '') { + $this->_creator = $pValue; + return $this; + } + + /** + * Get Last Modified By + * + * @return string + */ + public function getLastModifiedBy() { + return $this->_lastModifiedBy; + } + + /** + * Set Last Modified By + * + * @param string $pValue + * @return PHPExcel_DocumentProperties + */ + public function setLastModifiedBy($pValue = '') { + $this->_lastModifiedBy = $pValue; + return $this; + } + + /** + * Get Created + * + * @return datetime + */ + public function getCreated() { + return $this->_created; + } + + /** + * Set Created + * + * @param datetime $pValue + * @return PHPExcel_DocumentProperties + */ + public function setCreated($pValue = null) { + if ($pValue === NULL) { + $pValue = time(); + } elseif (is_string($pValue)) { + if (is_numeric($pValue)) { + $pValue = intval($pValue); + } else { + $pValue = strtotime($pValue); + } + } + + $this->_created = $pValue; + return $this; + } + + /** + * Get Modified + * + * @return datetime + */ + public function getModified() { + return $this->_modified; + } + + /** + * Set Modified + * + * @param datetime $pValue + * @return PHPExcel_DocumentProperties + */ + public function setModified($pValue = null) { + if ($pValue === NULL) { + $pValue = time(); + } elseif (is_string($pValue)) { + if (is_numeric($pValue)) { + $pValue = intval($pValue); + } else { + $pValue = strtotime($pValue); + } + } + + $this->_modified = $pValue; + return $this; + } + + /** + * Get Title + * + * @return string + */ + public function getTitle() { + return $this->_title; + } + + /** + * Set Title + * + * @param string $pValue + * @return PHPExcel_DocumentProperties + */ + public function setTitle($pValue = '') { + $this->_title = $pValue; + return $this; + } + + /** + * Get Description + * + * @return string + */ + public function getDescription() { + return $this->_description; + } + + /** + * Set Description + * + * @param string $pValue + * @return PHPExcel_DocumentProperties + */ + public function setDescription($pValue = '') { + $this->_description = $pValue; + return $this; + } + + /** + * Get Subject + * + * @return string + */ + public function getSubject() { + return $this->_subject; + } + + /** + * Set Subject + * + * @param string $pValue + * @return PHPExcel_DocumentProperties + */ + public function setSubject($pValue = '') { + $this->_subject = $pValue; + return $this; + } + + /** + * Get Keywords + * + * @return string + */ + public function getKeywords() { + return $this->_keywords; + } + + /** + * Set Keywords + * + * @param string $pValue + * @return PHPExcel_DocumentProperties + */ + public function setKeywords($pValue = '') { + $this->_keywords = $pValue; + return $this; + } + + /** + * Get Category + * + * @return string + */ + public function getCategory() { + return $this->_category; + } + + /** + * Set Category + * + * @param string $pValue + * @return PHPExcel_DocumentProperties + */ + public function setCategory($pValue = '') { + $this->_category = $pValue; + return $this; + } + + /** + * Get Company + * + * @return string + */ + public function getCompany() { + return $this->_company; + } + + /** + * Set Company + * + * @param string $pValue + * @return PHPExcel_DocumentProperties + */ + public function setCompany($pValue = '') { + $this->_company = $pValue; + return $this; + } + + /** + * Get Manager + * + * @return string + */ + public function getManager() { + return $this->_manager; + } + + /** + * Set Manager + * + * @param string $pValue + * @return PHPExcel_DocumentProperties + */ + public function setManager($pValue = '') { + $this->_manager = $pValue; + return $this; + } + + /** + * Get a List of Custom Property Names + * + * @return array of string + */ + public function getCustomProperties() { + return array_keys($this->_customProperties); + } + + /** + * Check if a Custom Property is defined + * + * @param string $propertyName + * @return boolean + */ + public function isCustomPropertySet($propertyName) { + return isset($this->_customProperties[$propertyName]); + } + + /** + * Get a Custom Property Value + * + * @param string $propertyName + * @return string + */ + public function getCustomPropertyValue($propertyName) { + if (isset($this->_customProperties[$propertyName])) { + return $this->_customProperties[$propertyName]['value']; + } + + } + + /** + * Get a Custom Property Type + * + * @param string $propertyName + * @return string + */ + public function getCustomPropertyType($propertyName) { + if (isset($this->_customProperties[$propertyName])) { + return $this->_customProperties[$propertyName]['type']; + } + + } + + /** + * Set a Custom Property + * + * @param string $propertyName + * @param mixed $propertyValue + * @param string $propertyType + * 'i' : Integer + * 'f' : Floating Point + * 's' : String + * 'd' : Date/Time + * 'b' : Boolean + * @return PHPExcel_DocumentProperties + */ + public function setCustomProperty($propertyName,$propertyValue='',$propertyType=NULL) { + if (($propertyType === NULL) || (!in_array($propertyType,array(self::PROPERTY_TYPE_INTEGER, + self::PROPERTY_TYPE_FLOAT, + self::PROPERTY_TYPE_STRING, + self::PROPERTY_TYPE_DATE, + self::PROPERTY_TYPE_BOOLEAN)))) { + if ($propertyValue === NULL) { + $propertyType = self::PROPERTY_TYPE_STRING; + } elseif (is_float($propertyValue)) { + $propertyType = self::PROPERTY_TYPE_FLOAT; + } elseif(is_int($propertyValue)) { + $propertyType = self::PROPERTY_TYPE_INTEGER; + } elseif (is_bool($propertyValue)) { + $propertyType = self::PROPERTY_TYPE_BOOLEAN; + } else { + $propertyType = self::PROPERTY_TYPE_STRING; + } + } + + $this->_customProperties[$propertyName] = array('value' => $propertyValue, 'type' => $propertyType); + return $this; + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } + + public static function convertProperty($propertyValue,$propertyType) { + switch ($propertyType) { + case 'empty' : // Empty + return ''; + break; + case 'null' : // Null + return NULL; + break; + case 'i1' : // 1-Byte Signed Integer + case 'i2' : // 2-Byte Signed Integer + case 'i4' : // 4-Byte Signed Integer + case 'i8' : // 8-Byte Signed Integer + case 'int' : // Integer + return (int) $propertyValue; + break; + case 'ui1' : // 1-Byte Unsigned Integer + case 'ui2' : // 2-Byte Unsigned Integer + case 'ui4' : // 4-Byte Unsigned Integer + case 'ui8' : // 8-Byte Unsigned Integer + case 'uint' : // Unsigned Integer + return abs((int) $propertyValue); + break; + case 'r4' : // 4-Byte Real Number + case 'r8' : // 8-Byte Real Number + case 'decimal' : // Decimal + return (float) $propertyValue; + break; + case 'lpstr' : // LPSTR + case 'lpwstr' : // LPWSTR + case 'bstr' : // Basic String + return $propertyValue; + break; + case 'date' : // Date and Time + case 'filetime' : // File Time + return strtotime($propertyValue); + break; + case 'bool' : // Boolean + return ($propertyValue == 'true') ? True : False; + break; + case 'cy' : // Currency + case 'error' : // Error Status Code + case 'vector' : // Vector + case 'array' : // Array + case 'blob' : // Binary Blob + case 'oblob' : // Binary Blob Object + case 'stream' : // Binary Stream + case 'ostream' : // Binary Stream Object + case 'storage' : // Binary Storage + case 'ostorage' : // Binary Storage Object + case 'vstream' : // Binary Versioned Stream + case 'clsid' : // Class ID + case 'cf' : // Clipboard Data + return $propertyValue; + break; + } + return $propertyValue; + } + + public static function convertPropertyType($propertyType) { + switch ($propertyType) { + case 'i1' : // 1-Byte Signed Integer + case 'i2' : // 2-Byte Signed Integer + case 'i4' : // 4-Byte Signed Integer + case 'i8' : // 8-Byte Signed Integer + case 'int' : // Integer + case 'ui1' : // 1-Byte Unsigned Integer + case 'ui2' : // 2-Byte Unsigned Integer + case 'ui4' : // 4-Byte Unsigned Integer + case 'ui8' : // 8-Byte Unsigned Integer + case 'uint' : // Unsigned Integer + return self::PROPERTY_TYPE_INTEGER; + break; + case 'r4' : // 4-Byte Real Number + case 'r8' : // 8-Byte Real Number + case 'decimal' : // Decimal + return self::PROPERTY_TYPE_FLOAT; + break; + case 'empty' : // Empty + case 'null' : // Null + case 'lpstr' : // LPSTR + case 'lpwstr' : // LPWSTR + case 'bstr' : // Basic String + return self::PROPERTY_TYPE_STRING; + break; + case 'date' : // Date and Time + case 'filetime' : // File Time + return self::PROPERTY_TYPE_DATE; + break; + case 'bool' : // Boolean + return self::PROPERTY_TYPE_BOOLEAN; + break; + case 'cy' : // Currency + case 'error' : // Error Status Code + case 'vector' : // Vector + case 'array' : // Array + case 'blob' : // Binary Blob + case 'oblob' : // Binary Blob Object + case 'stream' : // Binary Stream + case 'ostream' : // Binary Stream Object + case 'storage' : // Binary Storage + case 'ostorage' : // Binary Storage Object + case 'vstream' : // Binary Versioned Stream + case 'clsid' : // Class ID + case 'cf' : // Clipboard Data + return self::PROPERTY_TYPE_UNKNOWN; + break; + } + return self::PROPERTY_TYPE_UNKNOWN; + } + +} diff --git a/lib/phpexcel/PHPExcel/DocumentSecurity.php b/lib/phpexcel/PHPExcel/DocumentSecurity.php new file mode 100644 index 0000000..340504e --- /dev/null +++ b/lib/phpexcel/PHPExcel/DocumentSecurity.php @@ -0,0 +1,218 @@ +_lockRevision = false; + $this->_lockStructure = false; + $this->_lockWindows = false; + $this->_revisionsPassword = ''; + $this->_workbookPassword = ''; + } + + /** + * Is some sort of dcument security enabled? + * + * @return boolean + */ + function isSecurityEnabled() { + return $this->_lockRevision || + $this->_lockStructure || + $this->_lockWindows; + } + + /** + * Get LockRevision + * + * @return boolean + */ + function getLockRevision() { + return $this->_lockRevision; + } + + /** + * Set LockRevision + * + * @param boolean $pValue + * @return PHPExcel_DocumentSecurity + */ + function setLockRevision($pValue = false) { + $this->_lockRevision = $pValue; + return $this; + } + + /** + * Get LockStructure + * + * @return boolean + */ + function getLockStructure() { + return $this->_lockStructure; + } + + /** + * Set LockStructure + * + * @param boolean $pValue + * @return PHPExcel_DocumentSecurity + */ + function setLockStructure($pValue = false) { + $this->_lockStructure = $pValue; + return $this; + } + + /** + * Get LockWindows + * + * @return boolean + */ + function getLockWindows() { + return $this->_lockWindows; + } + + /** + * Set LockWindows + * + * @param boolean $pValue + * @return PHPExcel_DocumentSecurity + */ + function setLockWindows($pValue = false) { + $this->_lockWindows = $pValue; + return $this; + } + + /** + * Get RevisionsPassword (hashed) + * + * @return string + */ + function getRevisionsPassword() { + return $this->_revisionsPassword; + } + + /** + * Set RevisionsPassword + * + * @param string $pValue + * @param boolean $pAlreadyHashed If the password has already been hashed, set this to true + * @return PHPExcel_DocumentSecurity + */ + function setRevisionsPassword($pValue = '', $pAlreadyHashed = false) { + if (!$pAlreadyHashed) { + $pValue = PHPExcel_Shared_PasswordHasher::hashPassword($pValue); + } + $this->_revisionsPassword = $pValue; + return $this; + } + + /** + * Get WorkbookPassword (hashed) + * + * @return string + */ + function getWorkbookPassword() { + return $this->_workbookPassword; + } + + /** + * Set WorkbookPassword + * + * @param string $pValue + * @param boolean $pAlreadyHashed If the password has already been hashed, set this to true + * @return PHPExcel_DocumentSecurity + */ + function setWorkbookPassword($pValue = '', $pAlreadyHashed = false) { + if (!$pAlreadyHashed) { + $pValue = PHPExcel_Shared_PasswordHasher::hashPassword($pValue); + } + $this->_workbookPassword = $pValue; + return $this; + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } +} diff --git a/lib/phpexcel/PHPExcel/Exception.php b/lib/phpexcel/PHPExcel/Exception.php new file mode 100644 index 0000000..683e909 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Exception.php @@ -0,0 +1,52 @@ +line = $line; + $e->file = $file; + throw $e; + } +} diff --git a/lib/phpexcel/PHPExcel/HashTable.php b/lib/phpexcel/PHPExcel/HashTable.php new file mode 100644 index 0000000..7a9205e --- /dev/null +++ b/lib/phpexcel/PHPExcel/HashTable.php @@ -0,0 +1,202 @@ +addFromSource($pSource); + } + } + + /** + * Add HashTable items from source + * + * @param PHPExcel_IComparable[] $pSource Source array to create HashTable from + * @throws PHPExcel_Exception + */ + public function addFromSource($pSource = null) { + // Check if an array was passed + if ($pSource == null) { + return; + } else if (!is_array($pSource)) { + throw new PHPExcel_Exception('Invalid array parameter passed.'); + } + + foreach ($pSource as $item) { + $this->add($item); + } + } + + /** + * Add HashTable item + * + * @param PHPExcel_IComparable $pSource Item to add + * @throws PHPExcel_Exception + */ + public function add(PHPExcel_IComparable $pSource = null) { + $hash = $pSource->getHashCode(); + if (!isset($this->_items[$hash])) { + $this->_items[$hash] = $pSource; + $this->_keyMap[count($this->_items) - 1] = $hash; + } + } + + /** + * Remove HashTable item + * + * @param PHPExcel_IComparable $pSource Item to remove + * @throws PHPExcel_Exception + */ + public function remove(PHPExcel_IComparable $pSource = null) { + $hash = $pSource->getHashCode(); + if (isset($this->_items[$hash])) { + unset($this->_items[$hash]); + + $deleteKey = -1; + foreach ($this->_keyMap as $key => $value) { + if ($deleteKey >= 0) { + $this->_keyMap[$key - 1] = $value; + } + + if ($value == $hash) { + $deleteKey = $key; + } + } + unset($this->_keyMap[count($this->_keyMap) - 1]); + } + } + + /** + * Clear HashTable + * + */ + public function clear() { + $this->_items = array(); + $this->_keyMap = array(); + } + + /** + * Count + * + * @return int + */ + public function count() { + return count($this->_items); + } + + /** + * Get index for hash code + * + * @param string $pHashCode + * @return int Index + */ + public function getIndexForHashCode($pHashCode = '') { + return array_search($pHashCode, $this->_keyMap); + } + + /** + * Get by index + * + * @param int $pIndex + * @return PHPExcel_IComparable + * + */ + public function getByIndex($pIndex = 0) { + if (isset($this->_keyMap[$pIndex])) { + return $this->getByHashCode( $this->_keyMap[$pIndex] ); + } + + return null; + } + + /** + * Get by hashcode + * + * @param string $pHashCode + * @return PHPExcel_IComparable + * + */ + public function getByHashCode($pHashCode = '') { + if (isset($this->_items[$pHashCode])) { + return $this->_items[$pHashCode]; + } + + return null; + } + + /** + * HashTable to array + * + * @return PHPExcel_IComparable[] + */ + public function toArray() { + return $this->_items; + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } + } + } +} diff --git a/lib/phpexcel/PHPExcel/IComparable.php b/lib/phpexcel/PHPExcel/IComparable.php new file mode 100644 index 0000000..6b1e18a --- /dev/null +++ b/lib/phpexcel/PHPExcel/IComparable.php @@ -0,0 +1,43 @@ + 'IWriter', 'path' => 'PHPExcel/Writer/{0}.php', 'class' => 'PHPExcel_Writer_{0}' ), + array( 'type' => 'IReader', 'path' => 'PHPExcel/Reader/{0}.php', 'class' => 'PHPExcel_Reader_{0}' ) + ); + + /** + * Autoresolve classes + * + * @var array + * @access private + * @static + */ + private static $_autoResolveClasses = array( + 'Excel2007', + 'Excel5', + 'Excel2003XML', + 'OOCalc', + 'SYLK', + 'Gnumeric', + 'HTML', + 'CSV', + ); + + /** + * Private constructor for PHPExcel_IOFactory + */ + private function __construct() { } + + /** + * Get search locations + * + * @static + * @access public + * @return array + */ + public static function getSearchLocations() { + return self::$_searchLocations; + } // function getSearchLocations() + + /** + * Set search locations + * + * @static + * @access public + * @param array $value + * @throws PHPExcel_Reader_Exception + */ + public static function setSearchLocations($value) { + if (is_array($value)) { + self::$_searchLocations = $value; + } else { + throw new PHPExcel_Reader_Exception('Invalid parameter passed.'); + } + } // function setSearchLocations() + + /** + * Add search location + * + * @static + * @access public + * @param string $type Example: IWriter + * @param string $location Example: PHPExcel/Writer/{0}.php + * @param string $classname Example: PHPExcel_Writer_{0} + */ + public static function addSearchLocation($type = '', $location = '', $classname = '') { + self::$_searchLocations[] = array( 'type' => $type, 'path' => $location, 'class' => $classname ); + } // function addSearchLocation() + + /** + * Create PHPExcel_Writer_IWriter + * + * @static + * @access public + * @param PHPExcel $phpExcel + * @param string $writerType Example: Excel2007 + * @return PHPExcel_Writer_IWriter + * @throws PHPExcel_Reader_Exception + */ + public static function createWriter(PHPExcel $phpExcel, $writerType = '') { + // Search type + $searchType = 'IWriter'; + + // Include class + foreach (self::$_searchLocations as $searchLocation) { + if ($searchLocation['type'] == $searchType) { + $className = str_replace('{0}', $writerType, $searchLocation['class']); + + $instance = new $className($phpExcel); + if ($instance !== NULL) { + return $instance; + } + } + } + + // Nothing found... + throw new PHPExcel_Reader_Exception("No $searchType found for type $writerType"); + } // function createWriter() + + /** + * Create PHPExcel_Reader_IReader + * + * @static + * @access public + * @param string $readerType Example: Excel2007 + * @return PHPExcel_Reader_IReader + * @throws PHPExcel_Reader_Exception + */ + public static function createReader($readerType = '') { + // Search type + $searchType = 'IReader'; + + // Include class + foreach (self::$_searchLocations as $searchLocation) { + if ($searchLocation['type'] == $searchType) { + $className = str_replace('{0}', $readerType, $searchLocation['class']); + + $instance = new $className(); + if ($instance !== NULL) { + return $instance; + } + } + } + + // Nothing found... + throw new PHPExcel_Reader_Exception("No $searchType found for type $readerType"); + } // function createReader() + + /** + * Loads PHPExcel from file using automatic PHPExcel_Reader_IReader resolution + * + * @static + * @access public + * @param string $pFilename The name of the spreadsheet file + * @return PHPExcel + * @throws PHPExcel_Reader_Exception + */ + public static function load($pFilename) { + $reader = self::createReaderForFile($pFilename); + return $reader->load($pFilename); + } // function load() + + /** + * Identify file type using automatic PHPExcel_Reader_IReader resolution + * + * @static + * @access public + * @param string $pFilename The name of the spreadsheet file to identify + * @return string + * @throws PHPExcel_Reader_Exception + */ + public static function identify($pFilename) { + $reader = self::createReaderForFile($pFilename); + $className = get_class($reader); + $classType = explode('_',$className); + unset($reader); + return array_pop($classType); + } // function identify() + + /** + * Create PHPExcel_Reader_IReader for file using automatic PHPExcel_Reader_IReader resolution + * + * @static + * @access public + * @param string $pFilename The name of the spreadsheet file + * @return PHPExcel_Reader_IReader + * @throws PHPExcel_Reader_Exception + */ + public static function createReaderForFile($pFilename) { + + // First, lucky guess by inspecting file extension + $pathinfo = pathinfo($pFilename); + + $extensionType = NULL; + if (isset($pathinfo['extension'])) { + switch (strtolower($pathinfo['extension'])) { + case 'xlsx': // Excel (OfficeOpenXML) Spreadsheet + case 'xlsm': // Excel (OfficeOpenXML) Macro Spreadsheet (macros will be discarded) + case 'xltx': // Excel (OfficeOpenXML) Template + case 'xltm': // Excel (OfficeOpenXML) Macro Template (macros will be discarded) + $extensionType = 'Excel2007'; + break; + case 'xls': // Excel (BIFF) Spreadsheet + case 'xlt': // Excel (BIFF) Template + $extensionType = 'Excel5'; + break; + case 'ods': // Open/Libre Offic Calc + case 'ots': // Open/Libre Offic Calc Template + $extensionType = 'OOCalc'; + break; + case 'slk': + $extensionType = 'SYLK'; + break; + case 'xml': // Excel 2003 SpreadSheetML + $extensionType = 'Excel2003XML'; + break; + case 'gnumeric': + $extensionType = 'Gnumeric'; + break; + case 'htm': + case 'html': + $extensionType = 'HTML'; + break; + case 'csv': + // Do nothing + // We must not try to use CSV reader since it loads + // all files including Excel files etc. + break; + default: + break; + } + + if ($extensionType !== NULL) { + $reader = self::createReader($extensionType); + // Let's see if we are lucky + if (isset($reader) && $reader->canRead($pFilename)) { + return $reader; + } + } + } + + // If we reach here then "lucky guess" didn't give any result + // Try walking through all the options in self::$_autoResolveClasses + foreach (self::$_autoResolveClasses as $autoResolveClass) { + // Ignore our original guess, we know that won't work + if ($autoResolveClass !== $extensionType) { + $reader = self::createReader($autoResolveClass); + if ($reader->canRead($pFilename)) { + return $reader; + } + } + } + + throw new PHPExcel_Reader_Exception('Unable to identify a reader for this file'); + } // function createReaderForFile() +} diff --git a/lib/phpexcel/PHPExcel/NamedRange.php b/lib/phpexcel/PHPExcel/NamedRange.php new file mode 100644 index 0000000..3ad5caa --- /dev/null +++ b/lib/phpexcel/PHPExcel/NamedRange.php @@ -0,0 +1,246 @@ +_worksheet) + * + * @var bool + */ + private $_localOnly; + + /** + * Scope + * + * @var PHPExcel_Worksheet + */ + private $_scope; + + /** + * Create a new NamedRange + * + * @param string $pName + * @param PHPExcel_Worksheet $pWorksheet + * @param string $pRange + * @param bool $pLocalOnly + * @param PHPExcel_Worksheet|null $pScope Scope. Only applies when $pLocalOnly = true. Null for global scope. + * @throws PHPExcel_Exception + */ + public function __construct($pName = null, PHPExcel_Worksheet $pWorksheet, $pRange = 'A1', $pLocalOnly = false, $pScope = null) + { + // Validate data + if (($pName === NULL) || ($pWorksheet === NULL) || ($pRange === NULL)) { + throw new PHPExcel_Exception('Parameters can not be null.'); + } + + // Set local members + $this->_name = $pName; + $this->_worksheet = $pWorksheet; + $this->_range = $pRange; + $this->_localOnly = $pLocalOnly; + $this->_scope = ($pLocalOnly == true) ? + (($pScope == null) ? $pWorksheet : $pScope) : null; + } + + /** + * Get name + * + * @return string + */ + public function getName() { + return $this->_name; + } + + /** + * Set name + * + * @param string $value + * @return PHPExcel_NamedRange + */ + public function setName($value = null) { + if ($value !== NULL) { + // Old title + $oldTitle = $this->_name; + + // Re-attach + if ($this->_worksheet !== NULL) { + $this->_worksheet->getParent()->removeNamedRange($this->_name,$this->_worksheet); + } + $this->_name = $value; + + if ($this->_worksheet !== NULL) { + $this->_worksheet->getParent()->addNamedRange($this); + } + + // New title + $newTitle = $this->_name; + PHPExcel_ReferenceHelper::getInstance()->updateNamedFormulas($this->_worksheet->getParent(), $oldTitle, $newTitle); + } + return $this; + } + + /** + * Get worksheet + * + * @return PHPExcel_Worksheet + */ + public function getWorksheet() { + return $this->_worksheet; + } + + /** + * Set worksheet + * + * @param PHPExcel_Worksheet $value + * @return PHPExcel_NamedRange + */ + public function setWorksheet(PHPExcel_Worksheet $value = null) { + if ($value !== NULL) { + $this->_worksheet = $value; + } + return $this; + } + + /** + * Get range + * + * @return string + */ + public function getRange() { + return $this->_range; + } + + /** + * Set range + * + * @param string $value + * @return PHPExcel_NamedRange + */ + public function setRange($value = null) { + if ($value !== NULL) { + $this->_range = $value; + } + return $this; + } + + /** + * Get localOnly + * + * @return bool + */ + public function getLocalOnly() { + return $this->_localOnly; + } + + /** + * Set localOnly + * + * @param bool $value + * @return PHPExcel_NamedRange + */ + public function setLocalOnly($value = false) { + $this->_localOnly = $value; + $this->_scope = $value ? $this->_worksheet : null; + return $this; + } + + /** + * Get scope + * + * @return PHPExcel_Worksheet|null + */ + public function getScope() { + return $this->_scope; + } + + /** + * Set scope + * + * @param PHPExcel_Worksheet|null $value + * @return PHPExcel_NamedRange + */ + public function setScope(PHPExcel_Worksheet $value = null) { + $this->_scope = $value; + $this->_localOnly = ($value == null) ? false : true; + return $this; + } + + /** + * Resolve a named range to a regular cell range + * + * @param string $pNamedRange Named range + * @param PHPExcel_Worksheet|null $pSheet Scope. Use null for global scope + * @return PHPExcel_NamedRange + */ + public static function resolveRange($pNamedRange = '', PHPExcel_Worksheet $pSheet) { + return $pSheet->getParent()->getNamedRange($pNamedRange, $pSheet); + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } +} diff --git a/lib/phpexcel/PHPExcel/Reader/Abstract.php b/lib/phpexcel/PHPExcel/Reader/Abstract.php new file mode 100644 index 0000000..0d5180c --- /dev/null +++ b/lib/phpexcel/PHPExcel/Reader/Abstract.php @@ -0,0 +1,227 @@ +_readDataOnly; + } + + /** + * Set read data only + * Set to true, to advise the Reader only to read data values for cells, and to ignore any formatting information. + * Set to false (the default) to advise the Reader to read both data and formatting for cells. + * + * @param boolean $pValue + * + * @return PHPExcel_Reader_IReader + */ + public function setReadDataOnly($pValue = FALSE) { + $this->_readDataOnly = $pValue; + return $this; + } + + /** + * Read charts in workbook? + * If this is true, then the Reader will include any charts that exist in the workbook. + * Note that a ReadDataOnly value of false overrides, and charts won't be read regardless of the IncludeCharts value. + * If false (the default) it will ignore any charts defined in the workbook file. + * + * @return boolean + */ + public function getIncludeCharts() { + return $this->_includeCharts; + } + + /** + * Set read charts in workbook + * Set to true, to advise the Reader to include any charts that exist in the workbook. + * Note that a ReadDataOnly value of false overrides, and charts won't be read regardless of the IncludeCharts value. + * Set to false (the default) to discard charts. + * + * @param boolean $pValue + * + * @return PHPExcel_Reader_IReader + */ + public function setIncludeCharts($pValue = FALSE) { + $this->_includeCharts = (boolean) $pValue; + return $this; + } + + /** + * Get which sheets to load + * Returns either an array of worksheet names (the list of worksheets that should be loaded), or a null + * indicating that all worksheets in the workbook should be loaded. + * + * @return mixed + */ + public function getLoadSheetsOnly() + { + return $this->_loadSheetsOnly; + } + + /** + * Set which sheets to load + * + * @param mixed $value + * This should be either an array of worksheet names to be loaded, or a string containing a single worksheet name. + * If NULL, then it tells the Reader to read all worksheets in the workbook + * + * @return PHPExcel_Reader_IReader + */ + public function setLoadSheetsOnly($value = NULL) + { + $this->_loadSheetsOnly = is_array($value) ? + $value : array($value); + return $this; + } + + /** + * Set all sheets to load + * Tells the Reader to load all worksheets from the workbook. + * + * @return PHPExcel_Reader_IReader + */ + public function setLoadAllSheets() + { + $this->_loadSheetsOnly = NULL; + return $this; + } + + /** + * Read filter + * + * @return PHPExcel_Reader_IReadFilter + */ + public function getReadFilter() { + return $this->_readFilter; + } + + /** + * Set read filter + * + * @param PHPExcel_Reader_IReadFilter $pValue + * @return PHPExcel_Reader_IReader + */ + public function setReadFilter(PHPExcel_Reader_IReadFilter $pValue) { + $this->_readFilter = $pValue; + return $this; + } + + /** + * Open file for reading + * + * @param string $pFilename + * @throws PHPExcel_Reader_Exception + * @return resource + */ + protected function _openFile($pFilename) + { + // Check if file exists + if (!file_exists($pFilename) || !is_readable($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + // Open file + $this->_fileHandle = fopen($pFilename, 'r'); + if ($this->_fileHandle === FALSE) { + throw new PHPExcel_Reader_Exception("Could not open file " . $pFilename . " for reading."); + } + } + + /** + * Can the current PHPExcel_Reader_IReader read the file? + * + * @param string $pFilename + * @return boolean + * @throws PHPExcel_Reader_Exception + */ + public function canRead($pFilename) + { + // Check if file exists + try { + $this->_openFile($pFilename); + } catch (Exception $e) { + return FALSE; + } + + $readable = $this->_isValidFormat(); + fclose ($this->_fileHandle); + return $readable; + } + +} diff --git a/lib/phpexcel/PHPExcel/Reader/CSV.php b/lib/phpexcel/PHPExcel/Reader/CSV.php new file mode 100644 index 0000000..8bf7b84 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Reader/CSV.php @@ -0,0 +1,415 @@ +_readFilter = new PHPExcel_Reader_DefaultReadFilter(); + } + + /** + * Validate that the current file is a CSV file + * + * @return boolean + */ + protected function _isValidFormat() + { + return TRUE; + } + + /** + * Set input encoding + * + * @param string $pValue Input encoding + */ + public function setInputEncoding($pValue = 'UTF-8') + { + $this->_inputEncoding = $pValue; + return $this; + } + + /** + * Get input encoding + * + * @return string + */ + public function getInputEncoding() + { + return $this->_inputEncoding; + } + + /** + * Move filepointer past any BOM marker + * + */ + protected function _skipBOM() + { + rewind($this->_fileHandle); + + switch ($this->_inputEncoding) { + case 'UTF-8': + fgets($this->_fileHandle, 4) == "\xEF\xBB\xBF" ? + fseek($this->_fileHandle, 3) : fseek($this->_fileHandle, 0); + break; + case 'UTF-16LE': + fgets($this->_fileHandle, 3) == "\xFF\xFE" ? + fseek($this->_fileHandle, 2) : fseek($this->_fileHandle, 0); + break; + case 'UTF-16BE': + fgets($this->_fileHandle, 3) == "\xFE\xFF" ? + fseek($this->_fileHandle, 2) : fseek($this->_fileHandle, 0); + break; + case 'UTF-32LE': + fgets($this->_fileHandle, 5) == "\xFF\xFE\x00\x00" ? + fseek($this->_fileHandle, 4) : fseek($this->_fileHandle, 0); + break; + case 'UTF-32BE': + fgets($this->_fileHandle, 5) == "\x00\x00\xFE\xFF" ? + fseek($this->_fileHandle, 4) : fseek($this->_fileHandle, 0); + break; + default: + break; + } + } + + /** + * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns) + * + * @param string $pFilename + * @throws PHPExcel_Reader_Exception + */ + public function listWorksheetInfo($pFilename) + { + // Open file + $this->_openFile($pFilename); + if (!$this->_isValidFormat()) { + fclose ($this->_fileHandle); + throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file."); + } + $fileHandle = $this->_fileHandle; + + // Skip BOM, if any + $this->_skipBOM(); + + $escapeEnclosures = array( "\\" . $this->_enclosure, $this->_enclosure . $this->_enclosure ); + + $worksheetInfo = array(); + $worksheetInfo[0]['worksheetName'] = 'Worksheet'; + $worksheetInfo[0]['lastColumnLetter'] = 'A'; + $worksheetInfo[0]['lastColumnIndex'] = 0; + $worksheetInfo[0]['totalRows'] = 0; + $worksheetInfo[0]['totalColumns'] = 0; + + // Loop through each line of the file in turn + while (($rowData = fgetcsv($fileHandle, 0, $this->_delimiter, $this->_enclosure)) !== FALSE) { + $worksheetInfo[0]['totalRows']++; + $worksheetInfo[0]['lastColumnIndex'] = max($worksheetInfo[0]['lastColumnIndex'], count($rowData) - 1); + } + + $worksheetInfo[0]['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($worksheetInfo[0]['lastColumnIndex']); + $worksheetInfo[0]['totalColumns'] = $worksheetInfo[0]['lastColumnIndex'] + 1; + + // Close file + fclose($fileHandle); + + return $worksheetInfo; + } + + /** + * Loads PHPExcel from file + * + * @param string $pFilename + * @return PHPExcel + * @throws PHPExcel_Reader_Exception + */ + public function load($pFilename) + { + // Create new PHPExcel + $objPHPExcel = new PHPExcel(); + + // Load into this instance + return $this->loadIntoExisting($pFilename, $objPHPExcel); + } + + /** + * Loads PHPExcel from file into PHPExcel instance + * + * @param string $pFilename + * @param PHPExcel $objPHPExcel + * @return PHPExcel + * @throws PHPExcel_Reader_Exception + */ + public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) + { + $lineEnding = ini_get('auto_detect_line_endings'); + ini_set('auto_detect_line_endings', true); + + // Open file + $this->_openFile($pFilename); + if (!$this->_isValidFormat()) { + fclose ($this->_fileHandle); + throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file."); + } + $fileHandle = $this->_fileHandle; + + // Skip BOM, if any + $this->_skipBOM(); + + // Create new PHPExcel object + while ($objPHPExcel->getSheetCount() <= $this->_sheetIndex) { + $objPHPExcel->createSheet(); + } + $sheet = $objPHPExcel->setActiveSheetIndex($this->_sheetIndex); + + $escapeEnclosures = array( "\\" . $this->_enclosure, + $this->_enclosure . $this->_enclosure + ); + + // Set our starting row based on whether we're in contiguous mode or not + $currentRow = 1; + if ($this->_contiguous) { + $currentRow = ($this->_contiguousRow == -1) ? $sheet->getHighestRow(): $this->_contiguousRow; + } + + // Loop through each line of the file in turn + while (($rowData = fgetcsv($fileHandle, 0, $this->_delimiter, $this->_enclosure)) !== FALSE) { + $columnLetter = 'A'; + foreach($rowData as $rowDatum) { + if ($rowDatum != '' && $this->_readFilter->readCell($columnLetter, $currentRow)) { + // Unescape enclosures + $rowDatum = str_replace($escapeEnclosures, $this->_enclosure, $rowDatum); + + // Convert encoding if necessary + if ($this->_inputEncoding !== 'UTF-8') { + $rowDatum = PHPExcel_Shared_String::ConvertEncoding($rowDatum, 'UTF-8', $this->_inputEncoding); + } + + // Set cell value + $sheet->getCell($columnLetter . $currentRow)->setValue($rowDatum); + } + ++$columnLetter; + } + ++$currentRow; + } + + // Close file + fclose($fileHandle); + + if ($this->_contiguous) { + $this->_contiguousRow = $currentRow; + } + + ini_set('auto_detect_line_endings', $lineEnding); + + // Return + return $objPHPExcel; + } + + /** + * Get delimiter + * + * @return string + */ + public function getDelimiter() { + return $this->_delimiter; + } + + /** + * Set delimiter + * + * @param string $pValue Delimiter, defaults to , + * @return PHPExcel_Reader_CSV + */ + public function setDelimiter($pValue = ',') { + $this->_delimiter = $pValue; + return $this; + } + + /** + * Get enclosure + * + * @return string + */ + public function getEnclosure() { + return $this->_enclosure; + } + + /** + * Set enclosure + * + * @param string $pValue Enclosure, defaults to " + * @return PHPExcel_Reader_CSV + */ + public function setEnclosure($pValue = '"') { + if ($pValue == '') { + $pValue = '"'; + } + $this->_enclosure = $pValue; + return $this; + } + + /** + * Get line ending + * + * @return string + */ + public function getLineEnding() { + return $this->_lineEnding; + } + + /** + * Set line ending + * + * @param string $pValue Line ending, defaults to OS line ending (PHP_EOL) + * @return PHPExcel_Reader_CSV + */ + public function setLineEnding($pValue = PHP_EOL) { + $this->_lineEnding = $pValue; + return $this; + } + + /** + * Get sheet index + * + * @return integer + */ + public function getSheetIndex() { + return $this->_sheetIndex; + } + + /** + * Set sheet index + * + * @param integer $pValue Sheet index + * @return PHPExcel_Reader_CSV + */ + public function setSheetIndex($pValue = 0) { + $this->_sheetIndex = $pValue; + return $this; + } + + /** + * Set Contiguous + * + * @param boolean $contiguous + */ + public function setContiguous($contiguous = FALSE) + { + $this->_contiguous = (bool) $contiguous; + if (!$contiguous) { + $this->_contiguousRow = -1; + } + + return $this; + } + + /** + * Get Contiguous + * + * @return boolean + */ + public function getContiguous() { + return $this->_contiguous; + } + +} diff --git a/lib/phpexcel/PHPExcel/Reader/DefaultReadFilter.php b/lib/phpexcel/PHPExcel/Reader/DefaultReadFilter.php new file mode 100644 index 0000000..228ed10 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Reader/DefaultReadFilter.php @@ -0,0 +1,58 @@ +_readFilter = new PHPExcel_Reader_DefaultReadFilter(); + } + + + /** + * Can the current PHPExcel_Reader_IReader read the file? + * + * @param string $pFilename + * @return boolean + * @throws PHPExcel_Reader_Exception + */ + public function canRead($pFilename) + { + + // Office xmlns:o="urn:schemas-microsoft-com:office:office" + // Excel xmlns:x="urn:schemas-microsoft-com:office:excel" + // XML Spreadsheet xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" + // Spreadsheet component xmlns:c="urn:schemas-microsoft-com:office:component:spreadsheet" + // XML schema xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882" + // XML data type xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" + // MS-persist recordset xmlns:rs="urn:schemas-microsoft-com:rowset" + // Rowset xmlns:z="#RowsetSchema" + // + + $signature = array( + '' + ); + + // Open file + $this->_openFile($pFilename); + $fileHandle = $this->_fileHandle; + + // Read sample data (first 2 KB will do) + $data = fread($fileHandle, 2048); + fclose($fileHandle); + + $valid = true; + foreach($signature as $match) { + // every part of the signature must be present + if (strpos($data, $match) === false) { + $valid = false; + break; + } + } + + // Retrieve charset encoding + if(preg_match('//um',$data,$matches)) { + $this->_charSet = strtoupper($matches[1]); + } +// echo 'Character Set is ',$this->_charSet,'
            '; + + return $valid; + } + + + /** + * Reads names of the worksheets from a file, without parsing the whole file to a PHPExcel object + * + * @param string $pFilename + * @throws PHPExcel_Reader_Exception + */ + public function listWorksheetNames($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + if (!$this->canRead($pFilename)) { + throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file."); + } + + $worksheetNames = array(); + + $xml = simplexml_load_file($pFilename, 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $namespaces = $xml->getNamespaces(true); + + $xml_ss = $xml->children($namespaces['ss']); + foreach($xml_ss->Worksheet as $worksheet) { + $worksheet_ss = $worksheet->attributes($namespaces['ss']); + $worksheetNames[] = self::_convertStringEncoding((string) $worksheet_ss['Name'],$this->_charSet); + } + + return $worksheetNames; + } + + + /** + * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns) + * + * @param string $pFilename + * @throws PHPExcel_Reader_Exception + */ + public function listWorksheetInfo($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + $worksheetInfo = array(); + + $xml = simplexml_load_file($pFilename, 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $namespaces = $xml->getNamespaces(true); + + $worksheetID = 1; + $xml_ss = $xml->children($namespaces['ss']); + foreach($xml_ss->Worksheet as $worksheet) { + $worksheet_ss = $worksheet->attributes($namespaces['ss']); + + $tmpInfo = array(); + $tmpInfo['worksheetName'] = ''; + $tmpInfo['lastColumnLetter'] = 'A'; + $tmpInfo['lastColumnIndex'] = 0; + $tmpInfo['totalRows'] = 0; + $tmpInfo['totalColumns'] = 0; + + if (isset($worksheet_ss['Name'])) { + $tmpInfo['worksheetName'] = (string) $worksheet_ss['Name']; + } else { + $tmpInfo['worksheetName'] = "Worksheet_{$worksheetID}"; + } + + if (isset($worksheet->Table->Row)) { + $rowIndex = 0; + + foreach($worksheet->Table->Row as $rowData) { + $columnIndex = 0; + $rowHasData = false; + + foreach($rowData->Cell as $cell) { + if (isset($cell->Data)) { + $tmpInfo['lastColumnIndex'] = max($tmpInfo['lastColumnIndex'], $columnIndex); + $rowHasData = true; + } + + ++$columnIndex; + } + + ++$rowIndex; + + if ($rowHasData) { + $tmpInfo['totalRows'] = max($tmpInfo['totalRows'], $rowIndex); + } + } + } + + $tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']); + $tmpInfo['totalColumns'] = $tmpInfo['lastColumnIndex'] + 1; + + $worksheetInfo[] = $tmpInfo; + ++$worksheetID; + } + + return $worksheetInfo; + } + + + /** + * Loads PHPExcel from file + * + * @param string $pFilename + * @return PHPExcel + * @throws PHPExcel_Reader_Exception + */ + public function load($pFilename) + { + // Create new PHPExcel + $objPHPExcel = new PHPExcel(); + + // Load into this instance + return $this->loadIntoExisting($pFilename, $objPHPExcel); + } + + + private static function identifyFixedStyleValue($styleList,&$styleAttributeValue) { + $styleAttributeValue = strtolower($styleAttributeValue); + foreach($styleList as $style) { + if ($styleAttributeValue == strtolower($style)) { + $styleAttributeValue = $style; + return true; + } + } + return false; + } + + + /** + * pixel units to excel width units(units of 1/256th of a character width) + * @param pxs + * @return + */ + private static function _pixel2WidthUnits($pxs) { + $UNIT_OFFSET_MAP = array(0, 36, 73, 109, 146, 182, 219); + + $widthUnits = 256 * ($pxs / 7); + $widthUnits += $UNIT_OFFSET_MAP[($pxs % 7)]; + return $widthUnits; + } + + + /** + * excel width units(units of 1/256th of a character width) to pixel units + * @param widthUnits + * @return + */ + private static function _widthUnits2Pixel($widthUnits) { + $pixels = ($widthUnits / 256) * 7; + $offsetWidthUnits = $widthUnits % 256; + $pixels += round($offsetWidthUnits / (256 / 7)); + return $pixels; + } + + + private static function _hex2str($hex) { + return chr(hexdec($hex[1])); + } + + + /** + * Loads PHPExcel from file into PHPExcel instance + * + * @param string $pFilename + * @param PHPExcel $objPHPExcel + * @return PHPExcel + * @throws PHPExcel_Reader_Exception + */ + public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) + { + $fromFormats = array('\-', '\ '); + $toFormats = array('-', ' '); + + $underlineStyles = array ( + PHPExcel_Style_Font::UNDERLINE_NONE, + PHPExcel_Style_Font::UNDERLINE_DOUBLE, + PHPExcel_Style_Font::UNDERLINE_DOUBLEACCOUNTING, + PHPExcel_Style_Font::UNDERLINE_SINGLE, + PHPExcel_Style_Font::UNDERLINE_SINGLEACCOUNTING + ); + $verticalAlignmentStyles = array ( + PHPExcel_Style_Alignment::VERTICAL_BOTTOM, + PHPExcel_Style_Alignment::VERTICAL_TOP, + PHPExcel_Style_Alignment::VERTICAL_CENTER, + PHPExcel_Style_Alignment::VERTICAL_JUSTIFY + ); + $horizontalAlignmentStyles = array ( + PHPExcel_Style_Alignment::HORIZONTAL_GENERAL, + PHPExcel_Style_Alignment::HORIZONTAL_LEFT, + PHPExcel_Style_Alignment::HORIZONTAL_RIGHT, + PHPExcel_Style_Alignment::HORIZONTAL_CENTER, + PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS, + PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY + ); + + $timezoneObj = new DateTimeZone('Europe/London'); + $GMT = new DateTimeZone('UTC'); + + + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + if (!$this->canRead($pFilename)) { + throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file."); + } + + $xml = simplexml_load_file($pFilename, 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $namespaces = $xml->getNamespaces(true); + + $docProps = $objPHPExcel->getProperties(); + if (isset($xml->DocumentProperties[0])) { + foreach($xml->DocumentProperties[0] as $propertyName => $propertyValue) { + switch ($propertyName) { + case 'Title' : + $docProps->setTitle(self::_convertStringEncoding($propertyValue,$this->_charSet)); + break; + case 'Subject' : + $docProps->setSubject(self::_convertStringEncoding($propertyValue,$this->_charSet)); + break; + case 'Author' : + $docProps->setCreator(self::_convertStringEncoding($propertyValue,$this->_charSet)); + break; + case 'Created' : + $creationDate = strtotime($propertyValue); + $docProps->setCreated($creationDate); + break; + case 'LastAuthor' : + $docProps->setLastModifiedBy(self::_convertStringEncoding($propertyValue,$this->_charSet)); + break; + case 'LastSaved' : + $lastSaveDate = strtotime($propertyValue); + $docProps->setModified($lastSaveDate); + break; + case 'Company' : + $docProps->setCompany(self::_convertStringEncoding($propertyValue,$this->_charSet)); + break; + case 'Category' : + $docProps->setCategory(self::_convertStringEncoding($propertyValue,$this->_charSet)); + break; + case 'Manager' : + $docProps->setManager(self::_convertStringEncoding($propertyValue,$this->_charSet)); + break; + case 'Keywords' : + $docProps->setKeywords(self::_convertStringEncoding($propertyValue,$this->_charSet)); + break; + case 'Description' : + $docProps->setDescription(self::_convertStringEncoding($propertyValue,$this->_charSet)); + break; + } + } + } + if (isset($xml->CustomDocumentProperties)) { + foreach($xml->CustomDocumentProperties[0] as $propertyName => $propertyValue) { + $propertyAttributes = $propertyValue->attributes($namespaces['dt']); + $propertyName = preg_replace_callback('/_x([0-9a-z]{4})_/','PHPExcel_Reader_Excel2003XML::_hex2str',$propertyName); + $propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_UNKNOWN; + switch((string) $propertyAttributes) { + case 'string' : + $propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_STRING; + $propertyValue = trim($propertyValue); + break; + case 'boolean' : + $propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_BOOLEAN; + $propertyValue = (bool) $propertyValue; + break; + case 'integer' : + $propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_INTEGER; + $propertyValue = intval($propertyValue); + break; + case 'float' : + $propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_FLOAT; + $propertyValue = floatval($propertyValue); + break; + case 'dateTime.tz' : + $propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_DATE; + $propertyValue = strtotime(trim($propertyValue)); + break; + } + $docProps->setCustomProperty($propertyName,$propertyValue,$propertyType); + } + } + + foreach($xml->Styles[0] as $style) { + $style_ss = $style->attributes($namespaces['ss']); + $styleID = (string) $style_ss['ID']; +// echo 'Style ID = '.$styleID.'
            '; + if ($styleID == 'Default') { + $this->_styles['Default'] = array(); + } else { + $this->_styles[$styleID] = $this->_styles['Default']; + } + foreach ($style as $styleType => $styleData) { + $styleAttributes = $styleData->attributes($namespaces['ss']); +// echo $styleType.'
            '; + switch ($styleType) { + case 'Alignment' : + foreach($styleAttributes as $styleAttributeKey => $styleAttributeValue) { +// echo $styleAttributeKey.' = '.$styleAttributeValue.'
            '; + $styleAttributeValue = (string) $styleAttributeValue; + switch ($styleAttributeKey) { + case 'Vertical' : + if (self::identifyFixedStyleValue($verticalAlignmentStyles,$styleAttributeValue)) { + $this->_styles[$styleID]['alignment']['vertical'] = $styleAttributeValue; + } + break; + case 'Horizontal' : + if (self::identifyFixedStyleValue($horizontalAlignmentStyles,$styleAttributeValue)) { + $this->_styles[$styleID]['alignment']['horizontal'] = $styleAttributeValue; + } + break; + case 'WrapText' : + $this->_styles[$styleID]['alignment']['wrap'] = true; + break; + } + } + break; + case 'Borders' : + foreach($styleData->Border as $borderStyle) { + $borderAttributes = $borderStyle->attributes($namespaces['ss']); + $thisBorder = array(); + foreach($borderAttributes as $borderStyleKey => $borderStyleValue) { +// echo $borderStyleKey.' = '.$borderStyleValue.'
            '; + switch ($borderStyleKey) { + case 'LineStyle' : + $thisBorder['style'] = PHPExcel_Style_Border::BORDER_MEDIUM; +// $thisBorder['style'] = $borderStyleValue; + break; + case 'Weight' : +// $thisBorder['style'] = $borderStyleValue; + break; + case 'Position' : + $borderPosition = strtolower($borderStyleValue); + break; + case 'Color' : + $borderColour = substr($borderStyleValue,1); + $thisBorder['color']['rgb'] = $borderColour; + break; + } + } + if (!empty($thisBorder)) { + if (($borderPosition == 'left') || ($borderPosition == 'right') || ($borderPosition == 'top') || ($borderPosition == 'bottom')) { + $this->_styles[$styleID]['borders'][$borderPosition] = $thisBorder; + } + } + } + break; + case 'Font' : + foreach($styleAttributes as $styleAttributeKey => $styleAttributeValue) { +// echo $styleAttributeKey.' = '.$styleAttributeValue.'
            '; + $styleAttributeValue = (string) $styleAttributeValue; + switch ($styleAttributeKey) { + case 'FontName' : + $this->_styles[$styleID]['font']['name'] = $styleAttributeValue; + break; + case 'Size' : + $this->_styles[$styleID]['font']['size'] = $styleAttributeValue; + break; + case 'Color' : + $this->_styles[$styleID]['font']['color']['rgb'] = substr($styleAttributeValue,1); + break; + case 'Bold' : + $this->_styles[$styleID]['font']['bold'] = true; + break; + case 'Italic' : + $this->_styles[$styleID]['font']['italic'] = true; + break; + case 'Underline' : + if (self::identifyFixedStyleValue($underlineStyles,$styleAttributeValue)) { + $this->_styles[$styleID]['font']['underline'] = $styleAttributeValue; + } + break; + } + } + break; + case 'Interior' : + foreach($styleAttributes as $styleAttributeKey => $styleAttributeValue) { +// echo $styleAttributeKey.' = '.$styleAttributeValue.'
            '; + switch ($styleAttributeKey) { + case 'Color' : + $this->_styles[$styleID]['fill']['color']['rgb'] = substr($styleAttributeValue,1); + break; + } + } + break; + case 'NumberFormat' : + foreach($styleAttributes as $styleAttributeKey => $styleAttributeValue) { +// echo $styleAttributeKey.' = '.$styleAttributeValue.'
            '; + $styleAttributeValue = str_replace($fromFormats,$toFormats,$styleAttributeValue); + switch ($styleAttributeValue) { + case 'Short Date' : + $styleAttributeValue = 'dd/mm/yyyy'; + break; + } + if ($styleAttributeValue > '') { + $this->_styles[$styleID]['numberformat']['code'] = $styleAttributeValue; + } + } + break; + case 'Protection' : + foreach($styleAttributes as $styleAttributeKey => $styleAttributeValue) { +// echo $styleAttributeKey.' = '.$styleAttributeValue.'
            '; + } + break; + } + } +// print_r($this->_styles[$styleID]); +// echo '
            '; + } +// echo '
            '; + + $worksheetID = 0; + $xml_ss = $xml->children($namespaces['ss']); + + foreach($xml_ss->Worksheet as $worksheet) { + $worksheet_ss = $worksheet->attributes($namespaces['ss']); + + if ((isset($this->_loadSheetsOnly)) && (isset($worksheet_ss['Name'])) && + (!in_array($worksheet_ss['Name'], $this->_loadSheetsOnly))) { + continue; + } + +// echo '

            Worksheet: ',$worksheet_ss['Name'],'

            '; +// + // Create new Worksheet + $objPHPExcel->createSheet(); + $objPHPExcel->setActiveSheetIndex($worksheetID); + if (isset($worksheet_ss['Name'])) { + $worksheetName = self::_convertStringEncoding((string) $worksheet_ss['Name'],$this->_charSet); + // Use false for $updateFormulaCellReferences to prevent adjustment of worksheet references in + // formula cells... during the load, all formulae should be correct, and we're simply bringing + // the worksheet name in line with the formula, not the reverse + $objPHPExcel->getActiveSheet()->setTitle($worksheetName,false); + } + + $columnID = 'A'; + if (isset($worksheet->Table->Column)) { + foreach($worksheet->Table->Column as $columnData) { + $columnData_ss = $columnData->attributes($namespaces['ss']); + if (isset($columnData_ss['Index'])) { + $columnID = PHPExcel_Cell::stringFromColumnIndex($columnData_ss['Index']-1); + } + if (isset($columnData_ss['Width'])) { + $columnWidth = $columnData_ss['Width']; +// echo 'Setting column width for '.$columnID.' to '.$columnWidth.'
            '; + $objPHPExcel->getActiveSheet()->getColumnDimension($columnID)->setWidth($columnWidth / 5.4); + } + ++$columnID; + } + } + + $rowID = 1; + if (isset($worksheet->Table->Row)) { + foreach($worksheet->Table->Row as $rowData) { + $rowHasData = false; + $row_ss = $rowData->attributes($namespaces['ss']); + if (isset($row_ss['Index'])) { + $rowID = (integer) $row_ss['Index']; + } +// echo 'Row '.$rowID.'
            '; + + $columnID = 'A'; + foreach($rowData->Cell as $cell) { + + $cell_ss = $cell->attributes($namespaces['ss']); + if (isset($cell_ss['Index'])) { + $columnID = PHPExcel_Cell::stringFromColumnIndex($cell_ss['Index']-1); + } + $cellRange = $columnID.$rowID; + + if ($this->getReadFilter() !== NULL) { + if (!$this->getReadFilter()->readCell($columnID, $rowID, $worksheetName)) { + continue; + } + } + + if ((isset($cell_ss['MergeAcross'])) || (isset($cell_ss['MergeDown']))) { + $columnTo = $columnID; + if (isset($cell_ss['MergeAcross'])) { + $columnTo = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::columnIndexFromString($columnID) + $cell_ss['MergeAcross'] -1); + } + $rowTo = $rowID; + if (isset($cell_ss['MergeDown'])) { + $rowTo = $rowTo + $cell_ss['MergeDown']; + } + $cellRange .= ':'.$columnTo.$rowTo; + $objPHPExcel->getActiveSheet()->mergeCells($cellRange); + } + + $cellIsSet = $hasCalculatedValue = false; + $cellDataFormula = ''; + if (isset($cell_ss['Formula'])) { + $cellDataFormula = $cell_ss['Formula']; + // added this as a check for array formulas + if (isset($cell_ss['ArrayRange'])) { + $cellDataCSEFormula = $cell_ss['ArrayRange']; +// echo "found an array formula at ".$columnID.$rowID."
            "; + } + $hasCalculatedValue = true; + } + if (isset($cell->Data)) { + $cellValue = $cellData = $cell->Data; + $type = PHPExcel_Cell_DataType::TYPE_NULL; + $cellData_ss = $cellData->attributes($namespaces['ss']); + if (isset($cellData_ss['Type'])) { + $cellDataType = $cellData_ss['Type']; + switch ($cellDataType) { + /* + const TYPE_STRING = 's'; + const TYPE_FORMULA = 'f'; + const TYPE_NUMERIC = 'n'; + const TYPE_BOOL = 'b'; + const TYPE_NULL = 'null'; + const TYPE_INLINE = 'inlineStr'; + const TYPE_ERROR = 'e'; + */ + case 'String' : + $cellValue = self::_convertStringEncoding($cellValue,$this->_charSet); + $type = PHPExcel_Cell_DataType::TYPE_STRING; + break; + case 'Number' : + $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; + $cellValue = (float) $cellValue; + if (floor($cellValue) == $cellValue) { + $cellValue = (integer) $cellValue; + } + break; + case 'Boolean' : + $type = PHPExcel_Cell_DataType::TYPE_BOOL; + $cellValue = ($cellValue != 0); + break; + case 'DateTime' : + $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; + $cellValue = PHPExcel_Shared_Date::PHPToExcel(strtotime($cellValue)); + break; + case 'Error' : + $type = PHPExcel_Cell_DataType::TYPE_ERROR; + break; + } + } + + if ($hasCalculatedValue) { +// echo 'FORMULA
            '; + $type = PHPExcel_Cell_DataType::TYPE_FORMULA; + $columnNumber = PHPExcel_Cell::columnIndexFromString($columnID); + if (substr($cellDataFormula,0,3) == 'of:') { + $cellDataFormula = substr($cellDataFormula,3); +// echo 'Before: ',$cellDataFormula,'
            '; + $temp = explode('"',$cellDataFormula); + $key = false; + foreach($temp as &$value) { + // Only replace in alternate array entries (i.e. non-quoted blocks) + if ($key = !$key) { + $value = str_replace(array('[.','.',']'),'',$value); + } + } + } else { + // Convert R1C1 style references to A1 style references (but only when not quoted) +// echo 'Before: ',$cellDataFormula,'
            '; + $temp = explode('"',$cellDataFormula); + $key = false; + foreach($temp as &$value) { + // Only replace in alternate array entries (i.e. non-quoted blocks) + if ($key = !$key) { + preg_match_all('/(R(\[?-?\d*\]?))(C(\[?-?\d*\]?))/',$value, $cellReferences,PREG_SET_ORDER+PREG_OFFSET_CAPTURE); + // Reverse the matches array, otherwise all our offsets will become incorrect if we modify our way + // through the formula from left to right. Reversing means that we work right to left.through + // the formula + $cellReferences = array_reverse($cellReferences); + // Loop through each R1C1 style reference in turn, converting it to its A1 style equivalent, + // then modify the formula to use that new reference + foreach($cellReferences as $cellReference) { + $rowReference = $cellReference[2][0]; + // Empty R reference is the current row + if ($rowReference == '') $rowReference = $rowID; + // Bracketed R references are relative to the current row + if ($rowReference{0} == '[') $rowReference = $rowID + trim($rowReference,'[]'); + $columnReference = $cellReference[4][0]; + // Empty C reference is the current column + if ($columnReference == '') $columnReference = $columnNumber; + // Bracketed C references are relative to the current column + if ($columnReference{0} == '[') $columnReference = $columnNumber + trim($columnReference,'[]'); + $A1CellReference = PHPExcel_Cell::stringFromColumnIndex($columnReference-1).$rowReference; + $value = substr_replace($value,$A1CellReference,$cellReference[0][1],strlen($cellReference[0][0])); + } + } + } + } + unset($value); + // Then rebuild the formula string + $cellDataFormula = implode('"',$temp); +// echo 'After: ',$cellDataFormula,'
            '; + } + +// echo 'Cell '.$columnID.$rowID.' is a '.$type.' with a value of '.(($hasCalculatedValue) ? $cellDataFormula : $cellValue).'
            '; +// + $objPHPExcel->getActiveSheet()->getCell($columnID.$rowID)->setValueExplicit((($hasCalculatedValue) ? $cellDataFormula : $cellValue),$type); + if ($hasCalculatedValue) { +// echo 'Formula result is '.$cellValue.'
            '; + $objPHPExcel->getActiveSheet()->getCell($columnID.$rowID)->setCalculatedValue($cellValue); + } + $cellIsSet = $rowHasData = true; + } + + if (isset($cell->Comment)) { +// echo 'comment found
            '; + $commentAttributes = $cell->Comment->attributes($namespaces['ss']); + $author = 'unknown'; + if (isset($commentAttributes->Author)) { + $author = (string)$commentAttributes->Author; +// echo 'Author: ',$author,'
            '; + } + $node = $cell->Comment->Data->asXML(); +// $annotation = str_replace('html:','',substr($node,49,-10)); +// echo $annotation,'
            '; + $annotation = strip_tags($node); +// echo 'Annotation: ',$annotation,'
            '; + $objPHPExcel->getActiveSheet()->getComment( $columnID.$rowID ) + ->setAuthor(self::_convertStringEncoding($author ,$this->_charSet)) + ->setText($this->_parseRichText($annotation) ); + } + + if (($cellIsSet) && (isset($cell_ss['StyleID']))) { + $style = (string) $cell_ss['StyleID']; +// echo 'Cell style for '.$columnID.$rowID.' is '.$style.'
            '; + if ((isset($this->_styles[$style])) && (!empty($this->_styles[$style]))) { +// echo 'Cell '.$columnID.$rowID.'
            '; +// print_r($this->_styles[$style]); +// echo '
            '; + if (!$objPHPExcel->getActiveSheet()->cellExists($columnID.$rowID)) { + $objPHPExcel->getActiveSheet()->getCell($columnID.$rowID)->setValue(NULL); + } + $objPHPExcel->getActiveSheet()->getStyle($cellRange)->applyFromArray($this->_styles[$style]); + } + } + ++$columnID; + } + + if ($rowHasData) { + if (isset($row_ss['StyleID'])) { + $rowStyle = $row_ss['StyleID']; + } + if (isset($row_ss['Height'])) { + $rowHeight = $row_ss['Height']; +// echo 'Setting row height to '.$rowHeight.'
            '; + $objPHPExcel->getActiveSheet()->getRowDimension($rowID)->setRowHeight($rowHeight); + } + } + + ++$rowID; + } + } + ++$worksheetID; + } + + // Return + return $objPHPExcel; + } + + + private static function _convertStringEncoding($string,$charset) { + if ($charset != 'UTF-8') { + return PHPExcel_Shared_String::ConvertEncoding($string,'UTF-8',$charset); + } + return $string; + } + + + private function _parseRichText($is = '') { + $value = new PHPExcel_RichText(); + + $value->createText(self::_convertStringEncoding($is,$this->_charSet)); + + return $value; + } + +} diff --git a/lib/phpexcel/PHPExcel/Reader/Excel2007.php b/lib/phpexcel/PHPExcel/Reader/Excel2007.php new file mode 100644 index 0000000..d8344ac --- /dev/null +++ b/lib/phpexcel/PHPExcel/Reader/Excel2007.php @@ -0,0 +1,2069 @@ +_readFilter = new PHPExcel_Reader_DefaultReadFilter(); + $this->_referenceHelper = PHPExcel_ReferenceHelper::getInstance(); + } + + + /** + * Can the current PHPExcel_Reader_IReader read the file? + * + * @param string $pFilename + * @return boolean + * @throws PHPExcel_Reader_Exception + */ + public function canRead($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + $zipClass = PHPExcel_Settings::getZipClass(); + + // Check if zip class exists +// if (!class_exists($zipClass, FALSE)) { +// throw new PHPExcel_Reader_Exception($zipClass . " library is not enabled"); +// } + + $xl = false; + // Load file + $zip = new $zipClass; + if ($zip->open($pFilename) === true) { + // check if it is an OOXML archive + $rels = simplexml_load_string($this->_getFromZipArchive($zip, "_rels/.rels"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + if ($rels !== false) { + foreach ($rels->Relationship as $rel) { + switch ($rel["Type"]) { + case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument": + if (basename($rel["Target"]) == 'workbook.xml') { + $xl = true; + } + break; + + } + } + } + $zip->close(); + } + + return $xl; + } + + + /** + * Reads names of the worksheets from a file, without parsing the whole file to a PHPExcel object + * + * @param string $pFilename + * @throws PHPExcel_Reader_Exception + */ + public function listWorksheetNames($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + $worksheetNames = array(); + + $zipClass = PHPExcel_Settings::getZipClass(); + + $zip = new $zipClass; + $zip->open($pFilename); + + // The files we're looking at here are small enough that simpleXML is more efficient than XMLReader + $rels = simplexml_load_string( + $this->_getFromZipArchive($zip, "_rels/.rels", 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()) + ); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + foreach ($rels->Relationship as $rel) { + switch ($rel["Type"]) { + case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument": + $xmlWorkbook = simplexml_load_string( + $this->_getFromZipArchive($zip, "{$rel['Target']}", 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()) + ); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); + + if ($xmlWorkbook->sheets) { + foreach ($xmlWorkbook->sheets->sheet as $eleSheet) { + // Check if sheet should be skipped + $worksheetNames[] = (string) $eleSheet["name"]; + } + } + } + } + + $zip->close(); + + return $worksheetNames; + } + + + /** + * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns) + * + * @param string $pFilename + * @throws PHPExcel_Reader_Exception + */ + public function listWorksheetInfo($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + $worksheetInfo = array(); + + $zipClass = PHPExcel_Settings::getZipClass(); + + $zip = new $zipClass; + $zip->open($pFilename); + + $rels = simplexml_load_string($this->_getFromZipArchive($zip, "_rels/.rels"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + foreach ($rels->Relationship as $rel) { + if ($rel["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument") { + $dir = dirname($rel["Target"]); + $relsWorkbook = simplexml_load_string($this->_getFromZipArchive($zip, "$dir/_rels/" . basename($rel["Target"]) . ".rels"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $relsWorkbook->registerXPathNamespace("rel", "http://schemas.openxmlformats.org/package/2006/relationships"); + + $worksheets = array(); + foreach ($relsWorkbook->Relationship as $ele) { + if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet") { + $worksheets[(string) $ele["Id"]] = $ele["Target"]; + } + } + + $xmlWorkbook = simplexml_load_string($this->_getFromZipArchive($zip, "{$rel['Target']}"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); + if ($xmlWorkbook->sheets) { + $dir = dirname($rel["Target"]); + foreach ($xmlWorkbook->sheets->sheet as $eleSheet) { + $tmpInfo = array( + 'worksheetName' => (string) $eleSheet["name"], + 'lastColumnLetter' => 'A', + 'lastColumnIndex' => 0, + 'totalRows' => 0, + 'totalColumns' => 0, + ); + + $fileWorksheet = $worksheets[(string) self::array_item($eleSheet->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "id")]; + + $xml = new XMLReader(); + $res = $xml->open('zip://'.PHPExcel_Shared_File::realpath($pFilename).'#'."$dir/$fileWorksheet", null, PHPExcel_Settings::getLibXmlLoaderOptions()); + $xml->setParserProperty(2,true); + + $currCells = 0; + while ($xml->read()) { + if ($xml->name == 'row' && $xml->nodeType == XMLReader::ELEMENT) { + $row = $xml->getAttribute('r'); + $tmpInfo['totalRows'] = $row; + $tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'],$currCells); + $currCells = 0; + } elseif ($xml->name == 'c' && $xml->nodeType == XMLReader::ELEMENT) { + $currCells++; + } + } + $tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'],$currCells); + $xml->close(); + + $tmpInfo['lastColumnIndex'] = $tmpInfo['totalColumns'] - 1; + $tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']); + + $worksheetInfo[] = $tmpInfo; + } + } + } + } + + $zip->close(); + + return $worksheetInfo; + } + + + private static function _castToBool($c) { +// echo 'Initial Cast to Boolean', PHP_EOL; + $value = isset($c->v) ? (string) $c->v : NULL; + if ($value == '0') { + return FALSE; + } elseif ($value == '1') { + return TRUE; + } else { + return (bool)$c->v; + } + return $value; + } // function _castToBool() + + + private static function _castToError($c) { +// echo 'Initial Cast to Error', PHP_EOL; + return isset($c->v) ? (string) $c->v : NULL; + } // function _castToError() + + + private static function _castToString($c) { +// echo 'Initial Cast to String, PHP_EOL; + return isset($c->v) ? (string) $c->v : NULL; + } // function _castToString() + + + private function _castToFormula($c,$r,&$cellDataType,&$value,&$calculatedValue,&$sharedFormulas,$castBaseType) { +// echo 'Formula', PHP_EOL; +// echo '$c->f is ', $c->f, PHP_EOL; + $cellDataType = 'f'; + $value = "={$c->f}"; + $calculatedValue = self::$castBaseType($c); + + // Shared formula? + if (isset($c->f['t']) && strtolower((string)$c->f['t']) == 'shared') { +// echo 'SHARED FORMULA', PHP_EOL; + $instance = (string)$c->f['si']; + +// echo 'Instance ID = ', $instance, PHP_EOL; +// +// echo 'Shared Formula Array:', PHP_EOL; +// print_r($sharedFormulas); + if (!isset($sharedFormulas[(string)$c->f['si']])) { +// echo 'SETTING NEW SHARED FORMULA', PHP_EOL; +// echo 'Master is ', $r, PHP_EOL; +// echo 'Formula is ', $value, PHP_EOL; + $sharedFormulas[$instance] = array( 'master' => $r, + 'formula' => $value + ); +// echo 'New Shared Formula Array:', PHP_EOL; +// print_r($sharedFormulas); + } else { +// echo 'GETTING SHARED FORMULA', PHP_EOL; +// echo 'Master is ', $sharedFormulas[$instance]['master'], PHP_EOL; +// echo 'Formula is ', $sharedFormulas[$instance]['formula'], PHP_EOL; + $master = PHPExcel_Cell::coordinateFromString($sharedFormulas[$instance]['master']); + $current = PHPExcel_Cell::coordinateFromString($r); + + $difference = array(0, 0); + $difference[0] = PHPExcel_Cell::columnIndexFromString($current[0]) - PHPExcel_Cell::columnIndexFromString($master[0]); + $difference[1] = $current[1] - $master[1]; + + $value = $this->_referenceHelper->updateFormulaReferences( $sharedFormulas[$instance]['formula'], + 'A1', + $difference[0], + $difference[1] + ); +// echo 'Adjusted Formula is ', $value, PHP_EOL; + } + } + } + + + public function _getFromZipArchive($archive, $fileName = '') + { + // Root-relative paths + if (strpos($fileName, '//') !== false) + { + $fileName = substr($fileName, strpos($fileName, '//') + 1); + } + $fileName = PHPExcel_Shared_File::realpath($fileName); + + // Apache POI fixes + $contents = $archive->getFromName($fileName); + if ($contents === false) + { + $contents = $archive->getFromName(substr($fileName, 1)); + } + + return $contents; + } + + + /** + * Loads PHPExcel from file + * + * @param string $pFilename + * @throws PHPExcel_Reader_Exception + */ + public function load($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + // Initialisations + $excel = new PHPExcel; + $excel->removeSheetByIndex(0); + if (!$this->_readDataOnly) { + $excel->removeCellStyleXfByIndex(0); // remove the default style + $excel->removeCellXfByIndex(0); // remove the default style + } + + $zipClass = PHPExcel_Settings::getZipClass(); + + $zip = new $zipClass; + $zip->open($pFilename); + + // Read the theme first, because we need the colour scheme when reading the styles + $wbRels = simplexml_load_string($this->_getFromZipArchive($zip, "xl/_rels/workbook.xml.rels"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + foreach ($wbRels->Relationship as $rel) { + switch ($rel["Type"]) { + case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme": + $themeOrderArray = array('lt1','dk1','lt2','dk2'); + $themeOrderAdditional = count($themeOrderArray); + + $xmlTheme = simplexml_load_string($this->_getFromZipArchive($zip, "xl/{$rel['Target']}"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + if (is_object($xmlTheme)) { + $xmlThemeName = $xmlTheme->attributes(); + $xmlTheme = $xmlTheme->children("http://schemas.openxmlformats.org/drawingml/2006/main"); + $themeName = (string)$xmlThemeName['name']; + + $colourScheme = $xmlTheme->themeElements->clrScheme->attributes(); + $colourSchemeName = (string)$colourScheme['name']; + $colourScheme = $xmlTheme->themeElements->clrScheme->children("http://schemas.openxmlformats.org/drawingml/2006/main"); + + $themeColours = array(); + foreach ($colourScheme as $k => $xmlColour) { + $themePos = array_search($k,$themeOrderArray); + if ($themePos === false) { + $themePos = $themeOrderAdditional++; + } + if (isset($xmlColour->sysClr)) { + $xmlColourData = $xmlColour->sysClr->attributes(); + $themeColours[$themePos] = $xmlColourData['lastClr']; + } elseif (isset($xmlColour->srgbClr)) { + $xmlColourData = $xmlColour->srgbClr->attributes(); + $themeColours[$themePos] = $xmlColourData['val']; + } + } + self::$_theme = new PHPExcel_Reader_Excel2007_Theme($themeName,$colourSchemeName,$themeColours); + } + break; + } + } + + $rels = simplexml_load_string($this->_getFromZipArchive($zip, "_rels/.rels"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + foreach ($rels->Relationship as $rel) { + switch ($rel["Type"]) { + case "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties": + $xmlCore = simplexml_load_string($this->_getFromZipArchive($zip, "{$rel['Target']}"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + if (is_object($xmlCore)) { + $xmlCore->registerXPathNamespace("dc", "http://purl.org/dc/elements/1.1/"); + $xmlCore->registerXPathNamespace("dcterms", "http://purl.org/dc/terms/"); + $xmlCore->registerXPathNamespace("cp", "http://schemas.openxmlformats.org/package/2006/metadata/core-properties"); + $docProps = $excel->getProperties(); + $docProps->setCreator((string) self::array_item($xmlCore->xpath("dc:creator"))); + $docProps->setLastModifiedBy((string) self::array_item($xmlCore->xpath("cp:lastModifiedBy"))); + $docProps->setCreated(strtotime(self::array_item($xmlCore->xpath("dcterms:created")))); //! respect xsi:type + $docProps->setModified(strtotime(self::array_item($xmlCore->xpath("dcterms:modified")))); //! respect xsi:type + $docProps->setTitle((string) self::array_item($xmlCore->xpath("dc:title"))); + $docProps->setDescription((string) self::array_item($xmlCore->xpath("dc:description"))); + $docProps->setSubject((string) self::array_item($xmlCore->xpath("dc:subject"))); + $docProps->setKeywords((string) self::array_item($xmlCore->xpath("cp:keywords"))); + $docProps->setCategory((string) self::array_item($xmlCore->xpath("cp:category"))); + } + break; + + case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties": + $xmlCore = simplexml_load_string($this->_getFromZipArchive($zip, "{$rel['Target']}"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + if (is_object($xmlCore)) { + $docProps = $excel->getProperties(); + if (isset($xmlCore->Company)) + $docProps->setCompany((string) $xmlCore->Company); + if (isset($xmlCore->Manager)) + $docProps->setManager((string) $xmlCore->Manager); + } + break; + + case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties": + $xmlCore = simplexml_load_string($this->_getFromZipArchive($zip, "{$rel['Target']}"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + if (is_object($xmlCore)) { + $docProps = $excel->getProperties(); + foreach ($xmlCore as $xmlProperty) { + $cellDataOfficeAttributes = $xmlProperty->attributes(); + if (isset($cellDataOfficeAttributes['name'])) { + $propertyName = (string) $cellDataOfficeAttributes['name']; + $cellDataOfficeChildren = $xmlProperty->children('http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes'); + $attributeType = $cellDataOfficeChildren->getName(); + $attributeValue = (string) $cellDataOfficeChildren->{$attributeType}; + $attributeValue = PHPExcel_DocumentProperties::convertProperty($attributeValue,$attributeType); + $attributeType = PHPExcel_DocumentProperties::convertPropertyType($attributeType); + $docProps->setCustomProperty($propertyName,$attributeValue,$attributeType); + } + } + } + break; + //Ribbon + case "http://schemas.microsoft.com/office/2006/relationships/ui/extensibility": + $customUI = $rel['Target']; + if(!is_null($customUI)){ + $this->_readRibbon($excel, $customUI, $zip); + } + break; + case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument": + $dir = dirname($rel["Target"]); + $relsWorkbook = simplexml_load_string($this->_getFromZipArchive($zip, "$dir/_rels/" . basename($rel["Target"]) . ".rels"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $relsWorkbook->registerXPathNamespace("rel", "http://schemas.openxmlformats.org/package/2006/relationships"); + + $sharedStrings = array(); + $xpath = self::array_item($relsWorkbook->xpath("rel:Relationship[@Type='http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings']")); + $xmlStrings = simplexml_load_string($this->_getFromZipArchive($zip, "$dir/$xpath[Target]"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); + if (isset($xmlStrings) && isset($xmlStrings->si)) { + foreach ($xmlStrings->si as $val) { + if (isset($val->t)) { + $sharedStrings[] = PHPExcel_Shared_String::ControlCharacterOOXML2PHP( (string) $val->t ); + } elseif (isset($val->r)) { + $sharedStrings[] = $this->_parseRichText($val); + } + } + } + + $worksheets = array(); + $macros = $customUI = NULL; + foreach ($relsWorkbook->Relationship as $ele) { + switch($ele['Type']){ + case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet": + $worksheets[(string) $ele["Id"]] = $ele["Target"]; + break; + // a vbaProject ? (: some macros) + case "http://schemas.microsoft.com/office/2006/relationships/vbaProject": + $macros = $ele["Target"]; + break; + } + } + + if(!is_null($macros)){ + $macrosCode = $this->_getFromZipArchive($zip, 'xl/vbaProject.bin');//vbaProject.bin always in 'xl' dir and always named vbaProject.bin + if($macrosCode !== false){ + $excel->setMacrosCode($macrosCode); + $excel->setHasMacros(true); + //short-circuit : not reading vbaProject.bin.rel to get Signature =>allways vbaProjectSignature.bin in 'xl' dir + $Certificate = $this->_getFromZipArchive($zip, 'xl/vbaProjectSignature.bin'); + if($Certificate !== false) + $excel->setMacrosCertificate($Certificate); + } + } + $styles = array(); + $cellStyles = array(); + $xpath = self::array_item($relsWorkbook->xpath("rel:Relationship[@Type='http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles']")); + $xmlStyles = simplexml_load_string($this->_getFromZipArchive($zip, "$dir/$xpath[Target]"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); + $numFmts = null; + if ($xmlStyles && $xmlStyles->numFmts[0]) { + $numFmts = $xmlStyles->numFmts[0]; + } + if (isset($numFmts) && ($numFmts !== NULL)) { + $numFmts->registerXPathNamespace("sml", "http://schemas.openxmlformats.org/spreadsheetml/2006/main"); + } + if (!$this->_readDataOnly && $xmlStyles) { + foreach ($xmlStyles->cellXfs->xf as $xf) { + $numFmt = PHPExcel_Style_NumberFormat::FORMAT_GENERAL; + + if ($xf["numFmtId"]) { + if (isset($numFmts)) { + $tmpNumFmt = self::array_item($numFmts->xpath("sml:numFmt[@numFmtId=$xf[numFmtId]]")); + + if (isset($tmpNumFmt["formatCode"])) { + $numFmt = (string) $tmpNumFmt["formatCode"]; + } + } + + if ((int)$xf["numFmtId"] < 164) { + $numFmt = PHPExcel_Style_NumberFormat::builtInFormatCode((int)$xf["numFmtId"]); + } + } + $quotePrefix = false; + if (isset($xf["quotePrefix"])) { + $quotePrefix = (boolean) $xf["quotePrefix"]; + } + //$numFmt = str_replace('mm', 'i', $numFmt); + //$numFmt = str_replace('h', 'H', $numFmt); + + $style = (object) array( + "numFmt" => $numFmt, + "font" => $xmlStyles->fonts->font[intval($xf["fontId"])], + "fill" => $xmlStyles->fills->fill[intval($xf["fillId"])], + "border" => $xmlStyles->borders->border[intval($xf["borderId"])], + "alignment" => $xf->alignment, + "protection" => $xf->protection, + "quotePrefix" => $quotePrefix, + ); + $styles[] = $style; + + // add style to cellXf collection + $objStyle = new PHPExcel_Style; + self::_readStyle($objStyle, $style); + $excel->addCellXf($objStyle); + } + + foreach ($xmlStyles->cellStyleXfs->xf as $xf) { + $numFmt = PHPExcel_Style_NumberFormat::FORMAT_GENERAL; + if ($numFmts && $xf["numFmtId"]) { + $tmpNumFmt = self::array_item($numFmts->xpath("sml:numFmt[@numFmtId=$xf[numFmtId]]")); + if (isset($tmpNumFmt["formatCode"])) { + $numFmt = (string) $tmpNumFmt["formatCode"]; + } else if ((int)$xf["numFmtId"] < 165) { + $numFmt = PHPExcel_Style_NumberFormat::builtInFormatCode((int)$xf["numFmtId"]); + } + } + + $cellStyle = (object) array( + "numFmt" => $numFmt, + "font" => $xmlStyles->fonts->font[intval($xf["fontId"])], + "fill" => $xmlStyles->fills->fill[intval($xf["fillId"])], + "border" => $xmlStyles->borders->border[intval($xf["borderId"])], + "alignment" => $xf->alignment, + "protection" => $xf->protection, + "quotePrefix" => $quotePrefix, + ); + $cellStyles[] = $cellStyle; + + // add style to cellStyleXf collection + $objStyle = new PHPExcel_Style; + self::_readStyle($objStyle, $cellStyle); + $excel->addCellStyleXf($objStyle); + } + } + + $dxfs = array(); + if (!$this->_readDataOnly && $xmlStyles) { + // Conditional Styles + if ($xmlStyles->dxfs) { + foreach ($xmlStyles->dxfs->dxf as $dxf) { + $style = new PHPExcel_Style(FALSE, TRUE); + self::_readStyle($style, $dxf); + $dxfs[] = $style; + } + } + // Cell Styles + if ($xmlStyles->cellStyles) { + foreach ($xmlStyles->cellStyles->cellStyle as $cellStyle) { + if (intval($cellStyle['builtinId']) == 0) { + if (isset($cellStyles[intval($cellStyle['xfId'])])) { + // Set default style + $style = new PHPExcel_Style; + self::_readStyle($style, $cellStyles[intval($cellStyle['xfId'])]); + + // normal style, currently not using it for anything + } + } + } + } + } + + $xmlWorkbook = simplexml_load_string($this->_getFromZipArchive($zip, "{$rel['Target']}"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); + + // Set base date + if ($xmlWorkbook->workbookPr) { + PHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_WINDOWS_1900); + if (isset($xmlWorkbook->workbookPr['date1904'])) { + if (self::boolean((string) $xmlWorkbook->workbookPr['date1904'])) { + PHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_MAC_1904); + } + } + } + + $sheetId = 0; // keep track of new sheet id in final workbook + $oldSheetId = -1; // keep track of old sheet id in final workbook + $countSkippedSheets = 0; // keep track of number of skipped sheets + $mapSheetId = array(); // mapping of sheet ids from old to new + + + $charts = $chartDetails = array(); + + if ($xmlWorkbook->sheets) { + foreach ($xmlWorkbook->sheets->sheet as $eleSheet) { + ++$oldSheetId; + + // Check if sheet should be skipped + if (isset($this->_loadSheetsOnly) && !in_array((string) $eleSheet["name"], $this->_loadSheetsOnly)) { + ++$countSkippedSheets; + $mapSheetId[$oldSheetId] = null; + continue; + } + + // Map old sheet id in original workbook to new sheet id. + // They will differ if loadSheetsOnly() is being used + $mapSheetId[$oldSheetId] = $oldSheetId - $countSkippedSheets; + + // Load sheet + $docSheet = $excel->createSheet(); + // Use false for $updateFormulaCellReferences to prevent adjustment of worksheet + // references in formula cells... during the load, all formulae should be correct, + // and we're simply bringing the worksheet name in line with the formula, not the + // reverse + $docSheet->setTitle((string) $eleSheet["name"],false); + $fileWorksheet = $worksheets[(string) self::array_item($eleSheet->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "id")]; + $xmlSheet = simplexml_load_string($this->_getFromZipArchive($zip, "$dir/$fileWorksheet"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); + + $sharedFormulas = array(); + + if (isset($eleSheet["state"]) && (string) $eleSheet["state"] != '') { + $docSheet->setSheetState( (string) $eleSheet["state"] ); + } + + if (isset($xmlSheet->sheetViews) && isset($xmlSheet->sheetViews->sheetView)) { + if (isset($xmlSheet->sheetViews->sheetView['zoomScale'])) { + $docSheet->getSheetView()->setZoomScale( intval($xmlSheet->sheetViews->sheetView['zoomScale']) ); + } + + if (isset($xmlSheet->sheetViews->sheetView['zoomScaleNormal'])) { + $docSheet->getSheetView()->setZoomScaleNormal( intval($xmlSheet->sheetViews->sheetView['zoomScaleNormal']) ); + } + + if (isset($xmlSheet->sheetViews->sheetView['view'])) { + $docSheet->getSheetView()->setView((string) $xmlSheet->sheetViews->sheetView['view']); + } + + if (isset($xmlSheet->sheetViews->sheetView['showGridLines'])) { + $docSheet->setShowGridLines(self::boolean((string)$xmlSheet->sheetViews->sheetView['showGridLines'])); + } + + if (isset($xmlSheet->sheetViews->sheetView['showRowColHeaders'])) { + $docSheet->setShowRowColHeaders(self::boolean((string)$xmlSheet->sheetViews->sheetView['showRowColHeaders'])); + } + + if (isset($xmlSheet->sheetViews->sheetView['rightToLeft'])) { + $docSheet->setRightToLeft(self::boolean((string)$xmlSheet->sheetViews->sheetView['rightToLeft'])); + } + + if (isset($xmlSheet->sheetViews->sheetView->pane)) { + if (isset($xmlSheet->sheetViews->sheetView->pane['topLeftCell'])) { + $docSheet->freezePane( (string)$xmlSheet->sheetViews->sheetView->pane['topLeftCell'] ); + } else { + $xSplit = 0; + $ySplit = 0; + + if (isset($xmlSheet->sheetViews->sheetView->pane['xSplit'])) { + $xSplit = 1 + intval($xmlSheet->sheetViews->sheetView->pane['xSplit']); + } + + if (isset($xmlSheet->sheetViews->sheetView->pane['ySplit'])) { + $ySplit = 1 + intval($xmlSheet->sheetViews->sheetView->pane['ySplit']); + } + + $docSheet->freezePaneByColumnAndRow($xSplit, $ySplit); + } + } + + if (isset($xmlSheet->sheetViews->sheetView->selection)) { + if (isset($xmlSheet->sheetViews->sheetView->selection['sqref'])) { + $sqref = (string)$xmlSheet->sheetViews->sheetView->selection['sqref']; + $sqref = explode(' ', $sqref); + $sqref = $sqref[0]; + $docSheet->setSelectedCells($sqref); + } + } + + } + + if (isset($xmlSheet->sheetPr) && isset($xmlSheet->sheetPr->tabColor)) { + if (isset($xmlSheet->sheetPr->tabColor['rgb'])) { + $docSheet->getTabColor()->setARGB( (string)$xmlSheet->sheetPr->tabColor['rgb'] ); + } + } + if (isset($xmlSheet->sheetPr) && isset($xmlSheet->sheetPr['codeName'])) { + $docSheet->setCodeName((string) $xmlSheet->sheetPr['codeName']); + } + if (isset($xmlSheet->sheetPr) && isset($xmlSheet->sheetPr->outlinePr)) { + if (isset($xmlSheet->sheetPr->outlinePr['summaryRight']) && + !self::boolean((string) $xmlSheet->sheetPr->outlinePr['summaryRight'])) { + $docSheet->setShowSummaryRight(FALSE); + } else { + $docSheet->setShowSummaryRight(TRUE); + } + + if (isset($xmlSheet->sheetPr->outlinePr['summaryBelow']) && + !self::boolean((string) $xmlSheet->sheetPr->outlinePr['summaryBelow'])) { + $docSheet->setShowSummaryBelow(FALSE); + } else { + $docSheet->setShowSummaryBelow(TRUE); + } + } + + if (isset($xmlSheet->sheetPr) && isset($xmlSheet->sheetPr->pageSetUpPr)) { + if (isset($xmlSheet->sheetPr->pageSetUpPr['fitToPage']) && + !self::boolean((string) $xmlSheet->sheetPr->pageSetUpPr['fitToPage'])) { + $docSheet->getPageSetup()->setFitToPage(FALSE); + } else { + $docSheet->getPageSetup()->setFitToPage(TRUE); + } + } + + if (isset($xmlSheet->sheetFormatPr)) { + if (isset($xmlSheet->sheetFormatPr['customHeight']) && + self::boolean((string) $xmlSheet->sheetFormatPr['customHeight']) && + isset($xmlSheet->sheetFormatPr['defaultRowHeight'])) { + $docSheet->getDefaultRowDimension()->setRowHeight( (float)$xmlSheet->sheetFormatPr['defaultRowHeight'] ); + } + if (isset($xmlSheet->sheetFormatPr['defaultColWidth'])) { + $docSheet->getDefaultColumnDimension()->setWidth( (float)$xmlSheet->sheetFormatPr['defaultColWidth'] ); + } + if (isset($xmlSheet->sheetFormatPr['zeroHeight']) && + ((string)$xmlSheet->sheetFormatPr['zeroHeight'] == '1')) { + $docSheet->getDefaultRowDimension()->setzeroHeight(true); + } + } + + if (isset($xmlSheet->cols) && !$this->_readDataOnly) { + foreach ($xmlSheet->cols->col as $col) { + for ($i = intval($col["min"]) - 1; $i < intval($col["max"]); ++$i) { + if ($col["style"] && !$this->_readDataOnly) { + $docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setXfIndex(intval($col["style"])); + } + if (self::boolean($col["bestFit"])) { + //$docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setAutoSize(TRUE); + } + if (self::boolean($col["hidden"])) { + // echo PHPExcel_Cell::stringFromColumnIndex($i),': HIDDEN COLUMN',PHP_EOL; + $docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setVisible(FALSE); + } + if (self::boolean($col["collapsed"])) { + $docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setCollapsed(TRUE); + } + if ($col["outlineLevel"] > 0) { + $docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setOutlineLevel(intval($col["outlineLevel"])); + } + $docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setWidth(floatval($col["width"])); + + if (intval($col["max"]) == 16384) { + break; + } + } + } + } + + if (isset($xmlSheet->printOptions) && !$this->_readDataOnly) { + if (self::boolean((string) $xmlSheet->printOptions['gridLinesSet'])) { + $docSheet->setShowGridlines(TRUE); + } + + if (self::boolean((string) $xmlSheet->printOptions['gridLines'])) { + $docSheet->setPrintGridlines(TRUE); + } + + if (self::boolean((string) $xmlSheet->printOptions['horizontalCentered'])) { + $docSheet->getPageSetup()->setHorizontalCentered(TRUE); + } + if (self::boolean((string) $xmlSheet->printOptions['verticalCentered'])) { + $docSheet->getPageSetup()->setVerticalCentered(TRUE); + } + } + + if ($xmlSheet && $xmlSheet->sheetData && $xmlSheet->sheetData->row) { + foreach ($xmlSheet->sheetData->row as $row) { + if ($row["ht"] && !$this->_readDataOnly) { + $docSheet->getRowDimension(intval($row["r"]))->setRowHeight(floatval($row["ht"])); + } + if (self::boolean($row["hidden"]) && !$this->_readDataOnly) { + $docSheet->getRowDimension(intval($row["r"]))->setVisible(FALSE); + } + if (self::boolean($row["collapsed"])) { + $docSheet->getRowDimension(intval($row["r"]))->setCollapsed(TRUE); + } + if ($row["outlineLevel"] > 0) { + $docSheet->getRowDimension(intval($row["r"]))->setOutlineLevel(intval($row["outlineLevel"])); + } + if ($row["s"] && !$this->_readDataOnly) { + $docSheet->getRowDimension(intval($row["r"]))->setXfIndex(intval($row["s"])); + } + + foreach ($row->c as $c) { + $r = (string) $c["r"]; + $cellDataType = (string) $c["t"]; + $value = null; + $calculatedValue = null; + + // Read cell? + if ($this->getReadFilter() !== NULL) { + $coordinates = PHPExcel_Cell::coordinateFromString($r); + + if (!$this->getReadFilter()->readCell($coordinates[0], $coordinates[1], $docSheet->getTitle())) { + continue; + } + } + + // echo 'Reading cell ', $coordinates[0], $coordinates[1], PHP_EOL; + // print_r($c); + // echo PHP_EOL; + // echo 'Cell Data Type is ', $cellDataType, ': '; + // + // Read cell! + switch ($cellDataType) { + case "s": + // echo 'String', PHP_EOL; + if ((string)$c->v != '') { + $value = $sharedStrings[intval($c->v)]; + + if ($value instanceof PHPExcel_RichText) { + $value = clone $value; + } + } else { + $value = ''; + } + + break; + case "b": + // echo 'Boolean', PHP_EOL; + if (!isset($c->f)) { + $value = self::_castToBool($c); + } else { + // Formula + $this->_castToFormula($c,$r,$cellDataType,$value,$calculatedValue,$sharedFormulas,'_castToBool'); + if (isset($c->f['t'])) { + $att = array(); + $att = $c->f; + $docSheet->getCell($r)->setFormulaAttributes($att); + } + // echo '$calculatedValue = ', $calculatedValue, PHP_EOL; + } + break; + case "inlineStr": + // echo 'Inline String', PHP_EOL; + $value = $this->_parseRichText($c->is); + + break; + case "e": + // echo 'Error', PHP_EOL; + if (!isset($c->f)) { + $value = self::_castToError($c); + } else { + // Formula + $this->_castToFormula($c,$r,$cellDataType,$value,$calculatedValue,$sharedFormulas,'_castToError'); + // echo '$calculatedValue = ', $calculatedValue, PHP_EOL; + } + + break; + + default: + // echo 'Default', PHP_EOL; + if (!isset($c->f)) { + // echo 'Not a Formula', PHP_EOL; + $value = self::_castToString($c); + } else { + // echo 'Treat as Formula', PHP_EOL; + // Formula + $this->_castToFormula($c,$r,$cellDataType,$value,$calculatedValue,$sharedFormulas,'_castToString'); + // echo '$calculatedValue = ', $calculatedValue, PHP_EOL; + } + + break; + } + // echo 'Value is ', $value, PHP_EOL; + + // Check for numeric values + if (is_numeric($value) && $cellDataType != 's') { + if ($value == (int)$value) $value = (int)$value; + elseif ($value == (float)$value) $value = (float)$value; + elseif ($value == (double)$value) $value = (double)$value; + } + + // Rich text? + if ($value instanceof PHPExcel_RichText && $this->_readDataOnly) { + $value = $value->getPlainText(); + } + + $cell = $docSheet->getCell($r); + // Assign value + if ($cellDataType != '') { + $cell->setValueExplicit($value, $cellDataType); + } else { + $cell->setValue($value); + } + if ($calculatedValue !== NULL) { + $cell->setCalculatedValue($calculatedValue); + } + + // Style information? + if ($c["s"] && !$this->_readDataOnly) { + // no style index means 0, it seems + $cell->setXfIndex(isset($styles[intval($c["s"])]) ? + intval($c["s"]) : 0); + } + } + } + } + + $conditionals = array(); + if (!$this->_readDataOnly && $xmlSheet && $xmlSheet->conditionalFormatting) { + foreach ($xmlSheet->conditionalFormatting as $conditional) { + foreach ($conditional->cfRule as $cfRule) { + if ( + ( + (string)$cfRule["type"] == PHPExcel_Style_Conditional::CONDITION_NONE || + (string)$cfRule["type"] == PHPExcel_Style_Conditional::CONDITION_CELLIS || + (string)$cfRule["type"] == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT || + (string)$cfRule["type"] == PHPExcel_Style_Conditional::CONDITION_EXPRESSION + ) && isset($dxfs[intval($cfRule["dxfId"])]) + ) { + $conditionals[(string) $conditional["sqref"]][intval($cfRule["priority"])] = $cfRule; + } + } + } + + foreach ($conditionals as $ref => $cfRules) { + ksort($cfRules); + $conditionalStyles = array(); + foreach ($cfRules as $cfRule) { + $objConditional = new PHPExcel_Style_Conditional(); + $objConditional->setConditionType((string)$cfRule["type"]); + $objConditional->setOperatorType((string)$cfRule["operator"]); + + if ((string)$cfRule["text"] != '') { + $objConditional->setText((string)$cfRule["text"]); + } + + if (count($cfRule->formula) > 1) { + foreach ($cfRule->formula as $formula) { + $objConditional->addCondition((string)$formula); + } + } else { + $objConditional->addCondition((string)$cfRule->formula); + } + $objConditional->setStyle(clone $dxfs[intval($cfRule["dxfId"])]); + $conditionalStyles[] = $objConditional; + } + + // Extract all cell references in $ref + $aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($ref); + foreach ($aReferences as $reference) { + $docSheet->getStyle($reference)->setConditionalStyles($conditionalStyles); + } + } + } + + $aKeys = array("sheet", "objects", "scenarios", "formatCells", "formatColumns", "formatRows", "insertColumns", "insertRows", "insertHyperlinks", "deleteColumns", "deleteRows", "selectLockedCells", "sort", "autoFilter", "pivotTables", "selectUnlockedCells"); + if (!$this->_readDataOnly && $xmlSheet && $xmlSheet->sheetProtection) { + foreach ($aKeys as $key) { + $method = "set" . ucfirst($key); + $docSheet->getProtection()->$method(self::boolean((string) $xmlSheet->sheetProtection[$key])); + } + } + + if (!$this->_readDataOnly && $xmlSheet && $xmlSheet->sheetProtection) { + $docSheet->getProtection()->setPassword((string) $xmlSheet->sheetProtection["password"], TRUE); + if ($xmlSheet->protectedRanges->protectedRange) { + foreach ($xmlSheet->protectedRanges->protectedRange as $protectedRange) { + $docSheet->protectCells((string) $protectedRange["sqref"], (string) $protectedRange["password"], true); + } + } + } + + if ($xmlSheet && $xmlSheet->autoFilter && !$this->_readDataOnly) { + $autoFilter = $docSheet->getAutoFilter(); + $autoFilter->setRange((string) $xmlSheet->autoFilter["ref"]); + foreach ($xmlSheet->autoFilter->filterColumn as $filterColumn) { + $column = $autoFilter->getColumnByOffset((integer) $filterColumn["colId"]); + // Check for standard filters + if ($filterColumn->filters) { + $column->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER); + $filters = $filterColumn->filters; + if ((isset($filters["blank"])) && ($filters["blank"] == 1)) { + $column->createRule()->setRule( + NULL, // Operator is undefined, but always treated as EQUAL + '' + ) + ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_FILTER); + } + // Standard filters are always an OR join, so no join rule needs to be set + // Entries can be either filter elements + foreach ($filters->filter as $filterRule) { + $column->createRule()->setRule( + NULL, // Operator is undefined, but always treated as EQUAL + (string) $filterRule["val"] + ) + ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_FILTER); + } + // Or Date Group elements + foreach ($filters->dateGroupItem as $dateGroupItem) { + $column->createRule()->setRule( + NULL, // Operator is undefined, but always treated as EQUAL + array( + 'year' => (string) $dateGroupItem["year"], + 'month' => (string) $dateGroupItem["month"], + 'day' => (string) $dateGroupItem["day"], + 'hour' => (string) $dateGroupItem["hour"], + 'minute' => (string) $dateGroupItem["minute"], + 'second' => (string) $dateGroupItem["second"], + ), + (string) $dateGroupItem["dateTimeGrouping"] + ) + ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP); + } + } + // Check for custom filters + if ($filterColumn->customFilters) { + $column->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_CUSTOMFILTER); + $customFilters = $filterColumn->customFilters; + // Custom filters can an AND or an OR join; + // and there should only ever be one or two entries + if ((isset($customFilters["and"])) && ($customFilters["and"] == 1)) { + $column->setJoin(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND); + } + foreach ($customFilters->customFilter as $filterRule) { + $column->createRule()->setRule( + (string) $filterRule["operator"], + (string) $filterRule["val"] + ) + ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_CUSTOMFILTER); + } + } + // Check for dynamic filters + if ($filterColumn->dynamicFilter) { + $column->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER); + // We should only ever have one dynamic filter + foreach ($filterColumn->dynamicFilter as $filterRule) { + $column->createRule()->setRule( + NULL, // Operator is undefined, but always treated as EQUAL + (string) $filterRule["val"], + (string) $filterRule["type"] + ) + ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMICFILTER); + if (isset($filterRule["val"])) { + $column->setAttribute('val',(string) $filterRule["val"]); + } + if (isset($filterRule["maxVal"])) { + $column->setAttribute('maxVal',(string) $filterRule["maxVal"]); + } + } + } + // Check for dynamic filters + if ($filterColumn->top10) { + $column->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_TOPTENFILTER); + // We should only ever have one top10 filter + foreach ($filterColumn->top10 as $filterRule) { + $column->createRule()->setRule( + (((isset($filterRule["percent"])) && ($filterRule["percent"] == 1)) + ? PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT + : PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_BY_VALUE + ), + (string) $filterRule["val"], + (((isset($filterRule["top"])) && ($filterRule["top"] == 1)) + ? PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP + : PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_BOTTOM + ) + ) + ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_TOPTENFILTER); + } + } + } + } + + if ($xmlSheet && $xmlSheet->mergeCells && $xmlSheet->mergeCells->mergeCell && !$this->_readDataOnly) { + foreach ($xmlSheet->mergeCells->mergeCell as $mergeCell) { + $mergeRef = (string) $mergeCell["ref"]; + if (strpos($mergeRef,':') !== FALSE) { + $docSheet->mergeCells((string) $mergeCell["ref"]); + } + } + } + + if ($xmlSheet && $xmlSheet->pageMargins && !$this->_readDataOnly) { + $docPageMargins = $docSheet->getPageMargins(); + $docPageMargins->setLeft(floatval($xmlSheet->pageMargins["left"])); + $docPageMargins->setRight(floatval($xmlSheet->pageMargins["right"])); + $docPageMargins->setTop(floatval($xmlSheet->pageMargins["top"])); + $docPageMargins->setBottom(floatval($xmlSheet->pageMargins["bottom"])); + $docPageMargins->setHeader(floatval($xmlSheet->pageMargins["header"])); + $docPageMargins->setFooter(floatval($xmlSheet->pageMargins["footer"])); + } + + if ($xmlSheet && $xmlSheet->pageSetup && !$this->_readDataOnly) { + $docPageSetup = $docSheet->getPageSetup(); + + if (isset($xmlSheet->pageSetup["orientation"])) { + $docPageSetup->setOrientation((string) $xmlSheet->pageSetup["orientation"]); + } + if (isset($xmlSheet->pageSetup["paperSize"])) { + $docPageSetup->setPaperSize(intval($xmlSheet->pageSetup["paperSize"])); + } + if (isset($xmlSheet->pageSetup["scale"])) { + $docPageSetup->setScale(intval($xmlSheet->pageSetup["scale"]), FALSE); + } + if (isset($xmlSheet->pageSetup["fitToHeight"]) && intval($xmlSheet->pageSetup["fitToHeight"]) >= 0) { + $docPageSetup->setFitToHeight(intval($xmlSheet->pageSetup["fitToHeight"]), FALSE); + } + if (isset($xmlSheet->pageSetup["fitToWidth"]) && intval($xmlSheet->pageSetup["fitToWidth"]) >= 0) { + $docPageSetup->setFitToWidth(intval($xmlSheet->pageSetup["fitToWidth"]), FALSE); + } + if (isset($xmlSheet->pageSetup["firstPageNumber"]) && isset($xmlSheet->pageSetup["useFirstPageNumber"]) && + self::boolean((string) $xmlSheet->pageSetup["useFirstPageNumber"])) { + $docPageSetup->setFirstPageNumber(intval($xmlSheet->pageSetup["firstPageNumber"])); + } + } + + if ($xmlSheet && $xmlSheet->headerFooter && !$this->_readDataOnly) { + $docHeaderFooter = $docSheet->getHeaderFooter(); + + if (isset($xmlSheet->headerFooter["differentOddEven"]) && + self::boolean((string)$xmlSheet->headerFooter["differentOddEven"])) { + $docHeaderFooter->setDifferentOddEven(TRUE); + } else { + $docHeaderFooter->setDifferentOddEven(FALSE); + } + if (isset($xmlSheet->headerFooter["differentFirst"]) && + self::boolean((string)$xmlSheet->headerFooter["differentFirst"])) { + $docHeaderFooter->setDifferentFirst(TRUE); + } else { + $docHeaderFooter->setDifferentFirst(FALSE); + } + if (isset($xmlSheet->headerFooter["scaleWithDoc"]) && + !self::boolean((string)$xmlSheet->headerFooter["scaleWithDoc"])) { + $docHeaderFooter->setScaleWithDocument(FALSE); + } else { + $docHeaderFooter->setScaleWithDocument(TRUE); + } + if (isset($xmlSheet->headerFooter["alignWithMargins"]) && + !self::boolean((string)$xmlSheet->headerFooter["alignWithMargins"])) { + $docHeaderFooter->setAlignWithMargins(FALSE); + } else { + $docHeaderFooter->setAlignWithMargins(TRUE); + } + + $docHeaderFooter->setOddHeader((string) $xmlSheet->headerFooter->oddHeader); + $docHeaderFooter->setOddFooter((string) $xmlSheet->headerFooter->oddFooter); + $docHeaderFooter->setEvenHeader((string) $xmlSheet->headerFooter->evenHeader); + $docHeaderFooter->setEvenFooter((string) $xmlSheet->headerFooter->evenFooter); + $docHeaderFooter->setFirstHeader((string) $xmlSheet->headerFooter->firstHeader); + $docHeaderFooter->setFirstFooter((string) $xmlSheet->headerFooter->firstFooter); + } + + if ($xmlSheet && $xmlSheet->rowBreaks && $xmlSheet->rowBreaks->brk && !$this->_readDataOnly) { + foreach ($xmlSheet->rowBreaks->brk as $brk) { + if ($brk["man"]) { + $docSheet->setBreak("A$brk[id]", PHPExcel_Worksheet::BREAK_ROW); + } + } + } + if ($xmlSheet && $xmlSheet->colBreaks && $xmlSheet->colBreaks->brk && !$this->_readDataOnly) { + foreach ($xmlSheet->colBreaks->brk as $brk) { + if ($brk["man"]) { + $docSheet->setBreak(PHPExcel_Cell::stringFromColumnIndex((string) $brk["id"]) . "1", PHPExcel_Worksheet::BREAK_COLUMN); + } + } + } + + if ($xmlSheet && $xmlSheet->dataValidations && !$this->_readDataOnly) { + foreach ($xmlSheet->dataValidations->dataValidation as $dataValidation) { + // Uppercase coordinate + $range = strtoupper($dataValidation["sqref"]); + $rangeSet = explode(' ',$range); + foreach($rangeSet as $range) { + $stRange = $docSheet->shrinkRangeToFit($range); + + // Extract all cell references in $range + $aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($stRange); + foreach ($aReferences as $reference) { + // Create validation + $docValidation = $docSheet->getCell($reference)->getDataValidation(); + $docValidation->setType((string) $dataValidation["type"]); + $docValidation->setErrorStyle((string) $dataValidation["errorStyle"]); + $docValidation->setOperator((string) $dataValidation["operator"]); + $docValidation->setAllowBlank($dataValidation["allowBlank"] != 0); + $docValidation->setShowDropDown($dataValidation["showDropDown"] == 0); + $docValidation->setShowInputMessage($dataValidation["showInputMessage"] != 0); + $docValidation->setShowErrorMessage($dataValidation["showErrorMessage"] != 0); + $docValidation->setErrorTitle((string) $dataValidation["errorTitle"]); + $docValidation->setError((string) $dataValidation["error"]); + $docValidation->setPromptTitle((string) $dataValidation["promptTitle"]); + $docValidation->setPrompt((string) $dataValidation["prompt"]); + $docValidation->setFormula1((string) $dataValidation->formula1); + $docValidation->setFormula2((string) $dataValidation->formula2); + } + } + } + } + + // Add hyperlinks + $hyperlinks = array(); + if (!$this->_readDataOnly) { + // Locate hyperlink relations + if ($zip->locateName(dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")) { + $relsWorksheet = simplexml_load_string($this->_getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels") , 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + foreach ($relsWorksheet->Relationship as $ele) { + if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink") { + $hyperlinks[(string)$ele["Id"]] = (string)$ele["Target"]; + } + } + } + + // Loop through hyperlinks + if ($xmlSheet && $xmlSheet->hyperlinks) { + foreach ($xmlSheet->hyperlinks->hyperlink as $hyperlink) { + // Link url + $linkRel = $hyperlink->attributes('http://schemas.openxmlformats.org/officeDocument/2006/relationships'); + + foreach (PHPExcel_Cell::extractAllCellReferencesInRange($hyperlink['ref']) as $cellReference) { + $cell = $docSheet->getCell( $cellReference ); + if (isset($linkRel['id'])) { + $hyperlinkUrl = $hyperlinks[ (string)$linkRel['id'] ]; + if (isset($hyperlink['location'])) { + $hyperlinkUrl .= '#' . (string) $hyperlink['location']; + } + $cell->getHyperlink()->setUrl($hyperlinkUrl); + } elseif (isset($hyperlink['location'])) { + $cell->getHyperlink()->setUrl( 'sheet://' . (string)$hyperlink['location'] ); + } + + // Tooltip + if (isset($hyperlink['tooltip'])) { + $cell->getHyperlink()->setTooltip( (string)$hyperlink['tooltip'] ); + } + } + } + } + } + + // Add comments + $comments = array(); + $vmlComments = array(); + if (!$this->_readDataOnly) { + // Locate comment relations + if ($zip->locateName(dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")) { + $relsWorksheet = simplexml_load_string($this->_getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels") , 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + foreach ($relsWorksheet->Relationship as $ele) { + if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments") { + $comments[(string)$ele["Id"]] = (string)$ele["Target"]; + } + if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing") { + $vmlComments[(string)$ele["Id"]] = (string)$ele["Target"]; + } + } + } + + // Loop through comments + foreach ($comments as $relName => $relPath) { + // Load comments file + $relPath = PHPExcel_Shared_File::realpath(dirname("$dir/$fileWorksheet") . "/" . $relPath); + $commentsFile = simplexml_load_string($this->_getFromZipArchive($zip, $relPath) , 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + + // Utility variables + $authors = array(); + + // Loop through authors + foreach ($commentsFile->authors->author as $author) { + $authors[] = (string)$author; + } + + // Loop through contents + foreach ($commentsFile->commentList->comment as $comment) { + $docSheet->getComment( (string)$comment['ref'] )->setAuthor( $authors[(string)$comment['authorId']] ); + $docSheet->getComment( (string)$comment['ref'] )->setText( $this->_parseRichText($comment->text) ); + } + } + + // Loop through VML comments + foreach ($vmlComments as $relName => $relPath) { + // Load VML comments file + $relPath = PHPExcel_Shared_File::realpath(dirname("$dir/$fileWorksheet") . "/" . $relPath); + $vmlCommentsFile = simplexml_load_string( $this->_getFromZipArchive($zip, $relPath) , 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $vmlCommentsFile->registerXPathNamespace('v', 'urn:schemas-microsoft-com:vml'); + + $shapes = $vmlCommentsFile->xpath('//v:shape'); + foreach ($shapes as $shape) { + $shape->registerXPathNamespace('v', 'urn:schemas-microsoft-com:vml'); + + if (isset($shape['style'])) { + $style = (string)$shape['style']; + $fillColor = strtoupper( substr( (string)$shape['fillcolor'], 1 ) ); + $column = null; + $row = null; + + $clientData = $shape->xpath('.//x:ClientData'); + if (is_array($clientData) && !empty($clientData)) { + $clientData = $clientData[0]; + + if ( isset($clientData['ObjectType']) && (string)$clientData['ObjectType'] == 'Note' ) { + $temp = $clientData->xpath('.//x:Row'); + if (is_array($temp)) $row = $temp[0]; + + $temp = $clientData->xpath('.//x:Column'); + if (is_array($temp)) $column = $temp[0]; + } + } + + if (($column !== NULL) && ($row !== NULL)) { + // Set comment properties + $comment = $docSheet->getCommentByColumnAndRow((string) $column, $row + 1); + $comment->getFillColor()->setRGB( $fillColor ); + + // Parse style + $styleArray = explode(';', str_replace(' ', '', $style)); + foreach ($styleArray as $stylePair) { + $stylePair = explode(':', $stylePair); + + if ($stylePair[0] == 'margin-left') $comment->setMarginLeft($stylePair[1]); + if ($stylePair[0] == 'margin-top') $comment->setMarginTop($stylePair[1]); + if ($stylePair[0] == 'width') $comment->setWidth($stylePair[1]); + if ($stylePair[0] == 'height') $comment->setHeight($stylePair[1]); + if ($stylePair[0] == 'visibility') $comment->setVisible( $stylePair[1] == 'visible' ); + + } + } + } + } + } + + // Header/footer images + if ($xmlSheet && $xmlSheet->legacyDrawingHF && !$this->_readDataOnly) { + if ($zip->locateName(dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")) { + $relsWorksheet = simplexml_load_string($this->_getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels") , 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $vmlRelationship = ''; + + foreach ($relsWorksheet->Relationship as $ele) { + if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing") { + $vmlRelationship = self::dir_add("$dir/$fileWorksheet", $ele["Target"]); + } + } + + if ($vmlRelationship != '') { + // Fetch linked images + $relsVML = simplexml_load_string($this->_getFromZipArchive($zip, dirname($vmlRelationship) . '/_rels/' . basename($vmlRelationship) . '.rels' ), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $drawings = array(); + foreach ($relsVML->Relationship as $ele) { + if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image") { + $drawings[(string) $ele["Id"]] = self::dir_add($vmlRelationship, $ele["Target"]); + } + } + + // Fetch VML document + $vmlDrawing = simplexml_load_string($this->_getFromZipArchive($zip, $vmlRelationship), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $vmlDrawing->registerXPathNamespace('v', 'urn:schemas-microsoft-com:vml'); + + $hfImages = array(); + + $shapes = $vmlDrawing->xpath('//v:shape'); + foreach ($shapes as $idx => $shape) { + $shape->registerXPathNamespace('v', 'urn:schemas-microsoft-com:vml'); + $imageData = $shape->xpath('//v:imagedata'); + $imageData = $imageData[$idx]; + + $imageData = $imageData->attributes('urn:schemas-microsoft-com:office:office'); + $style = self::toCSSArray( (string)$shape['style'] ); + + $hfImages[ (string)$shape['id'] ] = new PHPExcel_Worksheet_HeaderFooterDrawing(); + if (isset($imageData['title'])) { + $hfImages[ (string)$shape['id'] ]->setName( (string)$imageData['title'] ); + } + + $hfImages[ (string)$shape['id'] ]->setPath("zip://".PHPExcel_Shared_File::realpath($pFilename)."#" . $drawings[(string)$imageData['relid']], false); + $hfImages[ (string)$shape['id'] ]->setResizeProportional(false); + $hfImages[ (string)$shape['id'] ]->setWidth($style['width']); + $hfImages[ (string)$shape['id'] ]->setHeight($style['height']); + if (isset($style['margin-left'])) { + $hfImages[ (string)$shape['id'] ]->setOffsetX($style['margin-left']); + } + $hfImages[ (string)$shape['id'] ]->setOffsetY($style['margin-top']); + $hfImages[ (string)$shape['id'] ]->setResizeProportional(true); + } + + $docSheet->getHeaderFooter()->setImages($hfImages); + } + } + } + + } + + // TODO: Autoshapes from twoCellAnchors! + if ($zip->locateName(dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")) { + $relsWorksheet = simplexml_load_string($this->_getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels") , 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $drawings = array(); + foreach ($relsWorksheet->Relationship as $ele) { + if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing") { + $drawings[(string) $ele["Id"]] = self::dir_add("$dir/$fileWorksheet", $ele["Target"]); + } + } + if ($xmlSheet->drawing && !$this->_readDataOnly) { + foreach ($xmlSheet->drawing as $drawing) { + $fileDrawing = $drawings[(string) self::array_item($drawing->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "id")]; + $relsDrawing = simplexml_load_string($this->_getFromZipArchive($zip, dirname($fileDrawing) . "/_rels/" . basename($fileDrawing) . ".rels") , 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $images = array(); + + if ($relsDrawing && $relsDrawing->Relationship) { + foreach ($relsDrawing->Relationship as $ele) { + if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image") { + $images[(string) $ele["Id"]] = self::dir_add($fileDrawing, $ele["Target"]); + } elseif ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart") { + if ($this->_includeCharts) { + $charts[self::dir_add($fileDrawing, $ele["Target"])] = array('id' => (string) $ele["Id"], + 'sheet' => $docSheet->getTitle() + ); + } + } + } + } + $xmlDrawing = simplexml_load_string($this->_getFromZipArchive($zip, $fileDrawing), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions())->children("http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing"); + + if ($xmlDrawing->oneCellAnchor) { + foreach ($xmlDrawing->oneCellAnchor as $oneCellAnchor) { + if ($oneCellAnchor->pic->blipFill) { + $blip = $oneCellAnchor->pic->blipFill->children("http://schemas.openxmlformats.org/drawingml/2006/main")->blip; + $xfrm = $oneCellAnchor->pic->spPr->children("http://schemas.openxmlformats.org/drawingml/2006/main")->xfrm; + $outerShdw = $oneCellAnchor->pic->spPr->children("http://schemas.openxmlformats.org/drawingml/2006/main")->effectLst->outerShdw; + $objDrawing = new PHPExcel_Worksheet_Drawing; + $objDrawing->setName((string) self::array_item($oneCellAnchor->pic->nvPicPr->cNvPr->attributes(), "name")); + $objDrawing->setDescription((string) self::array_item($oneCellAnchor->pic->nvPicPr->cNvPr->attributes(), "descr")); + $objDrawing->setPath("zip://".PHPExcel_Shared_File::realpath($pFilename)."#" . $images[(string) self::array_item($blip->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "embed")], false); + $objDrawing->setCoordinates(PHPExcel_Cell::stringFromColumnIndex((string) $oneCellAnchor->from->col) . ($oneCellAnchor->from->row + 1)); + $objDrawing->setOffsetX(PHPExcel_Shared_Drawing::EMUToPixels($oneCellAnchor->from->colOff)); + $objDrawing->setOffsetY(PHPExcel_Shared_Drawing::EMUToPixels($oneCellAnchor->from->rowOff)); + $objDrawing->setResizeProportional(false); + $objDrawing->setWidth(PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($oneCellAnchor->ext->attributes(), "cx"))); + $objDrawing->setHeight(PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($oneCellAnchor->ext->attributes(), "cy"))); + if ($xfrm) { + $objDrawing->setRotation(PHPExcel_Shared_Drawing::angleToDegrees(self::array_item($xfrm->attributes(), "rot"))); + } + if ($outerShdw) { + $shadow = $objDrawing->getShadow(); + $shadow->setVisible(true); + $shadow->setBlurRadius(PHPExcel_Shared_Drawing::EMUTopixels(self::array_item($outerShdw->attributes(), "blurRad"))); + $shadow->setDistance(PHPExcel_Shared_Drawing::EMUTopixels(self::array_item($outerShdw->attributes(), "dist"))); + $shadow->setDirection(PHPExcel_Shared_Drawing::angleToDegrees(self::array_item($outerShdw->attributes(), "dir"))); + $shadow->setAlignment((string) self::array_item($outerShdw->attributes(), "algn")); + $shadow->getColor()->setRGB(self::array_item($outerShdw->srgbClr->attributes(), "val")); + $shadow->setAlpha(self::array_item($outerShdw->srgbClr->alpha->attributes(), "val") / 1000); + } + $objDrawing->setWorksheet($docSheet); + } else { + // ? Can charts be positioned with a oneCellAnchor ? + $coordinates = PHPExcel_Cell::stringFromColumnIndex((string) $oneCellAnchor->from->col) . ($oneCellAnchor->from->row + 1); + $offsetX = PHPExcel_Shared_Drawing::EMUToPixels($oneCellAnchor->from->colOff); + $offsetY = PHPExcel_Shared_Drawing::EMUToPixels($oneCellAnchor->from->rowOff); + $width = PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($oneCellAnchor->ext->attributes(), "cx")); + $height = PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($oneCellAnchor->ext->attributes(), "cy")); + } + } + } + if ($xmlDrawing->twoCellAnchor) { + foreach ($xmlDrawing->twoCellAnchor as $twoCellAnchor) { + if ($twoCellAnchor->pic->blipFill) { + $blip = $twoCellAnchor->pic->blipFill->children("http://schemas.openxmlformats.org/drawingml/2006/main")->blip; + $xfrm = $twoCellAnchor->pic->spPr->children("http://schemas.openxmlformats.org/drawingml/2006/main")->xfrm; + $outerShdw = $twoCellAnchor->pic->spPr->children("http://schemas.openxmlformats.org/drawingml/2006/main")->effectLst->outerShdw; + $objDrawing = new PHPExcel_Worksheet_Drawing; + $objDrawing->setName((string) self::array_item($twoCellAnchor->pic->nvPicPr->cNvPr->attributes(), "name")); + $objDrawing->setDescription((string) self::array_item($twoCellAnchor->pic->nvPicPr->cNvPr->attributes(), "descr")); + $objDrawing->setPath("zip://".PHPExcel_Shared_File::realpath($pFilename)."#" . $images[(string) self::array_item($blip->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "embed")], false); + $objDrawing->setCoordinates(PHPExcel_Cell::stringFromColumnIndex((string) $twoCellAnchor->from->col) . ($twoCellAnchor->from->row + 1)); + $objDrawing->setOffsetX(PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->from->colOff)); + $objDrawing->setOffsetY(PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->from->rowOff)); + $objDrawing->setResizeProportional(false); + + $objDrawing->setWidth(PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($xfrm->ext->attributes(), "cx"))); + $objDrawing->setHeight(PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($xfrm->ext->attributes(), "cy"))); + + if ($xfrm) { + $objDrawing->setRotation(PHPExcel_Shared_Drawing::angleToDegrees(self::array_item($xfrm->attributes(), "rot"))); + } + if ($outerShdw) { + $shadow = $objDrawing->getShadow(); + $shadow->setVisible(true); + $shadow->setBlurRadius(PHPExcel_Shared_Drawing::EMUTopixels(self::array_item($outerShdw->attributes(), "blurRad"))); + $shadow->setDistance(PHPExcel_Shared_Drawing::EMUTopixels(self::array_item($outerShdw->attributes(), "dist"))); + $shadow->setDirection(PHPExcel_Shared_Drawing::angleToDegrees(self::array_item($outerShdw->attributes(), "dir"))); + $shadow->setAlignment((string) self::array_item($outerShdw->attributes(), "algn")); + $shadow->getColor()->setRGB(self::array_item($outerShdw->srgbClr->attributes(), "val")); + $shadow->setAlpha(self::array_item($outerShdw->srgbClr->alpha->attributes(), "val") / 1000); + } + $objDrawing->setWorksheet($docSheet); + } elseif(($this->_includeCharts) && ($twoCellAnchor->graphicFrame)) { + $fromCoordinate = PHPExcel_Cell::stringFromColumnIndex((string) $twoCellAnchor->from->col) . ($twoCellAnchor->from->row + 1); + $fromOffsetX = PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->from->colOff); + $fromOffsetY = PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->from->rowOff); + $toCoordinate = PHPExcel_Cell::stringFromColumnIndex((string) $twoCellAnchor->to->col) . ($twoCellAnchor->to->row + 1); + $toOffsetX = PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->to->colOff); + $toOffsetY = PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->to->rowOff); + $graphic = $twoCellAnchor->graphicFrame->children("http://schemas.openxmlformats.org/drawingml/2006/main")->graphic; + $chartRef = $graphic->graphicData->children("http://schemas.openxmlformats.org/drawingml/2006/chart")->chart; + $thisChart = (string) $chartRef->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"); + + $chartDetails[$docSheet->getTitle().'!'.$thisChart] = + array( 'fromCoordinate' => $fromCoordinate, + 'fromOffsetX' => $fromOffsetX, + 'fromOffsetY' => $fromOffsetY, + 'toCoordinate' => $toCoordinate, + 'toOffsetX' => $toOffsetX, + 'toOffsetY' => $toOffsetY, + 'worksheetTitle' => $docSheet->getTitle() + ); + } + } + } + + } + } + } + + // Loop through definedNames + if ($xmlWorkbook->definedNames) { + foreach ($xmlWorkbook->definedNames->definedName as $definedName) { + // Extract range + $extractedRange = (string)$definedName; + $extractedRange = preg_replace('/\'(\w+)\'\!/', '', $extractedRange); + if (($spos = strpos($extractedRange,'!')) !== false) { + $extractedRange = substr($extractedRange,0,$spos).str_replace('$', '', substr($extractedRange,$spos)); + } else { + $extractedRange = str_replace('$', '', $extractedRange); + } + + // Valid range? + if (stripos((string)$definedName, '#REF!') !== FALSE || $extractedRange == '') { + continue; + } + + // Some definedNames are only applicable if we are on the same sheet... + if ((string)$definedName['localSheetId'] != '' && (string)$definedName['localSheetId'] == $sheetId) { + // Switch on type + switch ((string)$definedName['name']) { + + case '_xlnm._FilterDatabase': + if ((string)$definedName['hidden'] !== '1') { + $docSheet->getAutoFilter()->setRange($extractedRange); + } + break; + + case '_xlnm.Print_Titles': + // Split $extractedRange + $extractedRange = explode(',', $extractedRange); + + // Set print titles + foreach ($extractedRange as $range) { + $matches = array(); + $range = str_replace('$', '', $range); + + // check for repeating columns, e g. 'A:A' or 'A:D' + if (preg_match('/!?([A-Z]+)\:([A-Z]+)$/', $range, $matches)) { + $docSheet->getPageSetup()->setColumnsToRepeatAtLeft(array($matches[1], $matches[2])); + } + // check for repeating rows, e.g. '1:1' or '1:5' + elseif (preg_match('/!?(\d+)\:(\d+)$/', $range, $matches)) { + $docSheet->getPageSetup()->setRowsToRepeatAtTop(array($matches[1], $matches[2])); + } + } + break; + + case '_xlnm.Print_Area': + $rangeSets = explode(',', $extractedRange); // FIXME: what if sheetname contains comma? + $newRangeSets = array(); + foreach($rangeSets as $rangeSet) { + $range = explode('!', $rangeSet); // FIXME: what if sheetname contains exclamation mark? + $rangeSet = isset($range[1]) ? $range[1] : $range[0]; + if (strpos($rangeSet, ':') === FALSE) { + $rangeSet = $rangeSet . ':' . $rangeSet; + } + $newRangeSets[] = str_replace('$', '', $rangeSet); + } + $docSheet->getPageSetup()->setPrintArea(implode(',',$newRangeSets)); + break; + + default: + break; + } + } + } + } + + // Next sheet id + ++$sheetId; + } + + // Loop through definedNames + if ($xmlWorkbook->definedNames) { + foreach ($xmlWorkbook->definedNames->definedName as $definedName) { + // Extract range + $extractedRange = (string)$definedName; + $extractedRange = preg_replace('/\'(\w+)\'\!/', '', $extractedRange); + if (($spos = strpos($extractedRange,'!')) !== false) { + $extractedRange = substr($extractedRange,0,$spos).str_replace('$', '', substr($extractedRange,$spos)); + } else { + $extractedRange = str_replace('$', '', $extractedRange); + } + + // Valid range? + if (stripos((string)$definedName, '#REF!') !== false || $extractedRange == '') { + continue; + } + + // Some definedNames are only applicable if we are on the same sheet... + if ((string)$definedName['localSheetId'] != '') { + // Local defined name + // Switch on type + switch ((string)$definedName['name']) { + + case '_xlnm._FilterDatabase': + case '_xlnm.Print_Titles': + case '_xlnm.Print_Area': + break; + + default: + if ($mapSheetId[(integer) $definedName['localSheetId']] !== null) { + $range = explode('!', (string)$definedName); + if (count($range) == 2) { + $range[0] = str_replace("''", "'", $range[0]); + $range[0] = str_replace("'", "", $range[0]); + if ($worksheet = $docSheet->getParent()->getSheetByName($range[0])) { + $extractedRange = str_replace('$', '', $range[1]); + $scope = $docSheet->getParent()->getSheet($mapSheetId[(integer) $definedName['localSheetId']]); + $excel->addNamedRange( new PHPExcel_NamedRange((string)$definedName['name'], $worksheet, $extractedRange, true, $scope) ); + } + } + } + break; + } + } else if (!isset($definedName['localSheetId'])) { + // "Global" definedNames + $locatedSheet = null; + $extractedSheetName = ''; + if (strpos( (string)$definedName, '!' ) !== false) { + // Extract sheet name + $extractedSheetName = PHPExcel_Worksheet::extractSheetTitle( (string)$definedName, true ); + $extractedSheetName = $extractedSheetName[0]; + + // Locate sheet + $locatedSheet = $excel->getSheetByName($extractedSheetName); + + // Modify range + $range = explode('!', $extractedRange); + $extractedRange = isset($range[1]) ? $range[1] : $range[0]; + } + + if ($locatedSheet !== NULL) { + $excel->addNamedRange( new PHPExcel_NamedRange((string)$definedName['name'], $locatedSheet, $extractedRange, false) ); + } + } + } + } + } + + if ((!$this->_readDataOnly) || (!empty($this->_loadSheetsOnly))) { + // active sheet index + $activeTab = intval($xmlWorkbook->bookViews->workbookView["activeTab"]); // refers to old sheet index + + // keep active sheet index if sheet is still loaded, else first sheet is set as the active + if (isset($mapSheetId[$activeTab]) && $mapSheetId[$activeTab] !== null) { + $excel->setActiveSheetIndex($mapSheetId[$activeTab]); + } else { + if ($excel->getSheetCount() == 0) { + $excel->createSheet(); + } + $excel->setActiveSheetIndex(0); + } + } + break; + } + + } + + + if (!$this->_readDataOnly) { + $contentTypes = simplexml_load_string($this->_getFromZipArchive($zip, "[Content_Types].xml"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + foreach ($contentTypes->Override as $contentType) { + switch ($contentType["ContentType"]) { + case "application/vnd.openxmlformats-officedocument.drawingml.chart+xml": + if ($this->_includeCharts) { + $chartEntryRef = ltrim($contentType['PartName'],'/'); + $chartElements = simplexml_load_string($this->_getFromZipArchive($zip, $chartEntryRef), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $objChart = PHPExcel_Reader_Excel2007_Chart::readChart($chartElements,basename($chartEntryRef,'.xml')); + +// echo 'Chart ',$chartEntryRef,'
            '; +// var_dump($charts[$chartEntryRef]); +// + if (isset($charts[$chartEntryRef])) { + $chartPositionRef = $charts[$chartEntryRef]['sheet'].'!'.$charts[$chartEntryRef]['id']; +// echo 'Position Ref ',$chartPositionRef,'
            '; + if (isset($chartDetails[$chartPositionRef])) { +// var_dump($chartDetails[$chartPositionRef]); + + $excel->getSheetByName($charts[$chartEntryRef]['sheet'])->addChart($objChart); + $objChart->setWorksheet($excel->getSheetByName($charts[$chartEntryRef]['sheet'])); + $objChart->setTopLeftPosition( $chartDetails[$chartPositionRef]['fromCoordinate'], + $chartDetails[$chartPositionRef]['fromOffsetX'], + $chartDetails[$chartPositionRef]['fromOffsetY'] + ); + $objChart->setBottomRightPosition( $chartDetails[$chartPositionRef]['toCoordinate'], + $chartDetails[$chartPositionRef]['toOffsetX'], + $chartDetails[$chartPositionRef]['toOffsetY'] + ); + } + } + } + } + } + } + + $zip->close(); + + return $excel; + } + + + private static function _readColor($color, $background=FALSE) { + if (isset($color["rgb"])) { + return (string)$color["rgb"]; + } else if (isset($color["indexed"])) { + return PHPExcel_Style_Color::indexedColor($color["indexed"]-7,$background)->getARGB(); + } else if (isset($color["theme"])) { + if (self::$_theme !== NULL) { + $returnColour = self::$_theme->getColourByIndex((int)$color["theme"]); + if (isset($color["tint"])) { + $tintAdjust = (float) $color["tint"]; + $returnColour = PHPExcel_Style_Color::changeBrightness($returnColour, $tintAdjust); + } + return 'FF'.$returnColour; + } + } + + if ($background) { + return 'FFFFFFFF'; + } + return 'FF000000'; + } + + + private static function _readStyle($docStyle, $style) { + // format code +// if (isset($style->numFmt)) { +// if (isset($style->numFmt['formatCode'])) { +// $docStyle->getNumberFormat()->setFormatCode((string) $style->numFmt['formatCode']); +// } else { + $docStyle->getNumberFormat()->setFormatCode($style->numFmt); +// } +// } + + // font + if (isset($style->font)) { + $docStyle->getFont()->setName((string) $style->font->name["val"]); + $docStyle->getFont()->setSize((string) $style->font->sz["val"]); + if (isset($style->font->b)) { + $docStyle->getFont()->setBold(!isset($style->font->b["val"]) || self::boolean((string) $style->font->b["val"])); + } + if (isset($style->font->i)) { + $docStyle->getFont()->setItalic(!isset($style->font->i["val"]) || self::boolean((string) $style->font->i["val"])); + } + if (isset($style->font->strike)) { + $docStyle->getFont()->setStrikethrough(!isset($style->font->strike["val"]) || self::boolean((string) $style->font->strike["val"])); + } + $docStyle->getFont()->getColor()->setARGB(self::_readColor($style->font->color)); + + if (isset($style->font->u) && !isset($style->font->u["val"])) { + $docStyle->getFont()->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLE); + } else if (isset($style->font->u) && isset($style->font->u["val"])) { + $docStyle->getFont()->setUnderline((string)$style->font->u["val"]); + } + + if (isset($style->font->vertAlign) && isset($style->font->vertAlign["val"])) { + $vertAlign = strtolower((string)$style->font->vertAlign["val"]); + if ($vertAlign == 'superscript') { + $docStyle->getFont()->setSuperScript(true); + } + if ($vertAlign == 'subscript') { + $docStyle->getFont()->setSubScript(true); + } + } + } + + // fill + if (isset($style->fill)) { + if ($style->fill->gradientFill) { + $gradientFill = $style->fill->gradientFill[0]; + if(!empty($gradientFill["type"])) { + $docStyle->getFill()->setFillType((string) $gradientFill["type"]); + } + $docStyle->getFill()->setRotation(floatval($gradientFill["degree"])); + $gradientFill->registerXPathNamespace("sml", "http://schemas.openxmlformats.org/spreadsheetml/2006/main"); + $docStyle->getFill()->getStartColor()->setARGB(self::_readColor( self::array_item($gradientFill->xpath("sml:stop[@position=0]"))->color) ); + $docStyle->getFill()->getEndColor()->setARGB(self::_readColor( self::array_item($gradientFill->xpath("sml:stop[@position=1]"))->color) ); + } elseif ($style->fill->patternFill) { + $patternType = (string)$style->fill->patternFill["patternType"] != '' ? (string)$style->fill->patternFill["patternType"] : 'solid'; + $docStyle->getFill()->setFillType($patternType); + if ($style->fill->patternFill->fgColor) { + $docStyle->getFill()->getStartColor()->setARGB(self::_readColor($style->fill->patternFill->fgColor,true)); + } else { + $docStyle->getFill()->getStartColor()->setARGB('FF000000'); + } + if ($style->fill->patternFill->bgColor) { + $docStyle->getFill()->getEndColor()->setARGB(self::_readColor($style->fill->patternFill->bgColor,true)); + } + } + } + + // border + if (isset($style->border)) { + $diagonalUp = self::boolean((string) $style->border["diagonalUp"]); + $diagonalDown = self::boolean((string) $style->border["diagonalDown"]); + if (!$diagonalUp && !$diagonalDown) { + $docStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_NONE); + } elseif ($diagonalUp && !$diagonalDown) { + $docStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_UP); + } elseif (!$diagonalUp && $diagonalDown) { + $docStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_DOWN); + } else { + $docStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_BOTH); + } + self::_readBorder($docStyle->getBorders()->getLeft(), $style->border->left); + self::_readBorder($docStyle->getBorders()->getRight(), $style->border->right); + self::_readBorder($docStyle->getBorders()->getTop(), $style->border->top); + self::_readBorder($docStyle->getBorders()->getBottom(), $style->border->bottom); + self::_readBorder($docStyle->getBorders()->getDiagonal(), $style->border->diagonal); + } + + // alignment + if (isset($style->alignment)) { + $docStyle->getAlignment()->setHorizontal((string) $style->alignment["horizontal"]); + $docStyle->getAlignment()->setVertical((string) $style->alignment["vertical"]); + + $textRotation = 0; + if ((int)$style->alignment["textRotation"] <= 90) { + $textRotation = (int)$style->alignment["textRotation"]; + } else if ((int)$style->alignment["textRotation"] > 90) { + $textRotation = 90 - (int)$style->alignment["textRotation"]; + } + + $docStyle->getAlignment()->setTextRotation(intval($textRotation)); + $docStyle->getAlignment()->setWrapText(self::boolean((string) $style->alignment["wrapText"])); + $docStyle->getAlignment()->setShrinkToFit(self::boolean((string) $style->alignment["shrinkToFit"])); + $docStyle->getAlignment()->setIndent( intval((string)$style->alignment["indent"]) > 0 ? intval((string)$style->alignment["indent"]) : 0 ); + } + + // protection + if (isset($style->protection)) { + if (isset($style->protection['locked'])) { + if (self::boolean((string) $style->protection['locked'])) { + $docStyle->getProtection()->setLocked(PHPExcel_Style_Protection::PROTECTION_PROTECTED); + } else { + $docStyle->getProtection()->setLocked(PHPExcel_Style_Protection::PROTECTION_UNPROTECTED); + } + } + + if (isset($style->protection['hidden'])) { + if (self::boolean((string) $style->protection['hidden'])) { + $docStyle->getProtection()->setHidden(PHPExcel_Style_Protection::PROTECTION_PROTECTED); + } else { + $docStyle->getProtection()->setHidden(PHPExcel_Style_Protection::PROTECTION_UNPROTECTED); + } + } + } + + // top-level style settings + if (isset($style->quotePrefix)) { + $docStyle->setQuotePrefix($style->quotePrefix); + } + } + + + private static function _readBorder($docBorder, $eleBorder) { + if (isset($eleBorder["style"])) { + $docBorder->setBorderStyle((string) $eleBorder["style"]); + } + if (isset($eleBorder->color)) { + $docBorder->getColor()->setARGB(self::_readColor($eleBorder->color)); + } + } + + + private function _parseRichText($is = null) { + $value = new PHPExcel_RichText(); + + if (isset($is->t)) { + $value->createText( PHPExcel_Shared_String::ControlCharacterOOXML2PHP( (string) $is->t ) ); + } else { + foreach ($is->r as $run) { + if (!isset($run->rPr)) { + $objText = $value->createText( PHPExcel_Shared_String::ControlCharacterOOXML2PHP( (string) $run->t ) ); + + } else { + $objText = $value->createTextRun( PHPExcel_Shared_String::ControlCharacterOOXML2PHP( (string) $run->t ) ); + + if (isset($run->rPr->rFont["val"])) { + $objText->getFont()->setName((string) $run->rPr->rFont["val"]); + } + + if (isset($run->rPr->sz["val"])) { + $objText->getFont()->setSize((string) $run->rPr->sz["val"]); + } + + if (isset($run->rPr->color)) { + $objText->getFont()->setColor( new PHPExcel_Style_Color( self::_readColor($run->rPr->color) ) ); + } + + if ((isset($run->rPr->b["val"]) && self::boolean((string) $run->rPr->b["val"])) || + (isset($run->rPr->b) && !isset($run->rPr->b["val"]))) { + $objText->getFont()->setBold(TRUE); + } + + if ((isset($run->rPr->i["val"]) && self::boolean((string) $run->rPr->i["val"])) || + (isset($run->rPr->i) && !isset($run->rPr->i["val"]))) { + $objText->getFont()->setItalic(TRUE); + } + + if (isset($run->rPr->vertAlign) && isset($run->rPr->vertAlign["val"])) { + $vertAlign = strtolower((string)$run->rPr->vertAlign["val"]); + if ($vertAlign == 'superscript') { + $objText->getFont()->setSuperScript(TRUE); + } + if ($vertAlign == 'subscript') { + $objText->getFont()->setSubScript(TRUE); + } + } + + if (isset($run->rPr->u) && !isset($run->rPr->u["val"])) { + $objText->getFont()->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLE); + } else if (isset($run->rPr->u) && isset($run->rPr->u["val"])) { + $objText->getFont()->setUnderline((string)$run->rPr->u["val"]); + } + + if ((isset($run->rPr->strike["val"]) && self::boolean((string) $run->rPr->strike["val"])) || + (isset($run->rPr->strike) && !isset($run->rPr->strike["val"]))) { + $objText->getFont()->setStrikethrough(TRUE); + } + } + } + } + + return $value; + } + + private function _readRibbon($excel, $customUITarget, $zip) + { + $baseDir = dirname($customUITarget); + $nameCustomUI = basename($customUITarget); + // get the xml file (ribbon) + $localRibbon = $this->_getFromZipArchive($zip, $customUITarget); + $customUIImagesNames = array(); + $customUIImagesBinaries = array(); + // something like customUI/_rels/customUI.xml.rels + $pathRels = $baseDir . '/_rels/' . $nameCustomUI . '.rels'; + $dataRels = $this->_getFromZipArchive($zip, $pathRels); + if ($dataRels) { + // exists and not empty if the ribbon have some pictures (other than internal MSO) + $UIRels = simplexml_load_string($dataRels, 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + if ($UIRels) { + // we need to save id and target to avoid parsing customUI.xml and "guess" if it's a pseudo callback who load the image + foreach ($UIRels->Relationship as $ele) { + if ($ele["Type"] == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image') { + // an image ? + $customUIImagesNames[(string) $ele['Id']] = (string)$ele['Target']; + $customUIImagesBinaries[(string)$ele['Target']] = $this->_getFromZipArchive($zip, $baseDir . '/' . (string) $ele['Target']); + } + } + } + } + if ($localRibbon) { + $excel->setRibbonXMLData($customUITarget, $localRibbon); + if (count($customUIImagesNames) > 0 && count($customUIImagesBinaries) > 0) { + $excel->setRibbonBinObjects($customUIImagesNames, $customUIImagesBinaries); + } else { + $excel->setRibbonBinObjects(NULL); + } + } else { + $excel->setRibbonXMLData(NULL); + $excel->setRibbonBinObjects(NULL); + } + } + + private static function array_item($array, $key = 0) { + return (isset($array[$key]) ? $array[$key] : null); + } + + + private static function dir_add($base, $add) { + return preg_replace('~[^/]+/\.\./~', '', dirname($base) . "/$add"); + } + + + private static function toCSSArray($style) { + $style = str_replace(array("\r","\n"), "", $style); + + $temp = explode(';', $style); + $style = array(); + foreach ($temp as $item) { + $item = explode(':', $item); + + if (strpos($item[1], 'px') !== false) { + $item[1] = str_replace('px', '', $item[1]); + } + if (strpos($item[1], 'pt') !== false) { + $item[1] = str_replace('pt', '', $item[1]); + $item[1] = PHPExcel_Shared_Font::fontSizeToPixels($item[1]); + } + if (strpos($item[1], 'in') !== false) { + $item[1] = str_replace('in', '', $item[1]); + $item[1] = PHPExcel_Shared_Font::inchSizeToPixels($item[1]); + } + if (strpos($item[1], 'cm') !== false) { + $item[1] = str_replace('cm', '', $item[1]); + $item[1] = PHPExcel_Shared_Font::centimeterSizeToPixels($item[1]); + } + + $style[$item[0]] = $item[1]; + } + + return $style; + } + + private static function boolean($value = NULL) + { + if (is_object($value)) { + $value = (string) $value; + } + if (is_numeric($value)) { + return (bool) $value; + } + return ($value === 'true' || $value === 'TRUE'); + } +} diff --git a/lib/phpexcel/PHPExcel/Reader/Excel2007/Chart.php b/lib/phpexcel/PHPExcel/Reader/Excel2007/Chart.php new file mode 100644 index 0000000..0de88ac --- /dev/null +++ b/lib/phpexcel/PHPExcel/Reader/Excel2007/Chart.php @@ -0,0 +1,517 @@ +attributes(); + if (isset($attributes[$name])) { + if ($format == 'string') { + return (string) $attributes[$name]; + } elseif ($format == 'integer') { + return (integer) $attributes[$name]; + } elseif ($format == 'boolean') { + return (boolean) ($attributes[$name] === '0' || $attributes[$name] !== 'true') ? false : true; + } else { + return (float) $attributes[$name]; + } + } + return null; + } // function _getAttribute() + + + private static function _readColor($color,$background=false) { + if (isset($color["rgb"])) { + return (string)$color["rgb"]; + } else if (isset($color["indexed"])) { + return PHPExcel_Style_Color::indexedColor($color["indexed"]-7,$background)->getARGB(); + } + } + + + public static function readChart($chartElements,$chartName) { + $namespacesChartMeta = $chartElements->getNamespaces(true); + $chartElementsC = $chartElements->children($namespacesChartMeta['c']); + + $XaxisLabel = $YaxisLabel = $legend = $title = NULL; + $dispBlanksAs = $plotVisOnly = NULL; + + foreach($chartElementsC as $chartElementKey => $chartElement) { + switch ($chartElementKey) { + case "chart": + foreach($chartElement as $chartDetailsKey => $chartDetails) { + $chartDetailsC = $chartDetails->children($namespacesChartMeta['c']); + switch ($chartDetailsKey) { + case "plotArea": + $plotAreaLayout = $XaxisLable = $YaxisLable = null; + $plotSeries = $plotAttributes = array(); + foreach($chartDetails as $chartDetailKey => $chartDetail) { + switch ($chartDetailKey) { + case "layout": + $plotAreaLayout = self::_chartLayoutDetails($chartDetail,$namespacesChartMeta,'plotArea'); + break; + case "catAx": + if (isset($chartDetail->title)) { + $XaxisLabel = self::_chartTitle($chartDetail->title->children($namespacesChartMeta['c']),$namespacesChartMeta,'cat'); + } + break; + case "dateAx": + if (isset($chartDetail->title)) { + $XaxisLabel = self::_chartTitle($chartDetail->title->children($namespacesChartMeta['c']),$namespacesChartMeta,'cat'); + } + break; + case "valAx": + if (isset($chartDetail->title)) { + $YaxisLabel = self::_chartTitle($chartDetail->title->children($namespacesChartMeta['c']),$namespacesChartMeta,'cat'); + } + break; + case "barChart": + case "bar3DChart": + $barDirection = self::_getAttribute($chartDetail->barDir, 'val', 'string'); + $plotSer = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey); + $plotSer->setPlotDirection($barDirection); + $plotSeries[] = $plotSer; + $plotAttributes = self::_readChartAttributes($chartDetail); + break; + case "lineChart": + case "line3DChart": + $plotSeries[] = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey); + $plotAttributes = self::_readChartAttributes($chartDetail); + break; + case "areaChart": + case "area3DChart": + $plotSeries[] = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey); + $plotAttributes = self::_readChartAttributes($chartDetail); + break; + case "doughnutChart": + case "pieChart": + case "pie3DChart": + $explosion = isset($chartDetail->ser->explosion); + $plotSer = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey); + $plotSer->setPlotStyle($explosion); + $plotSeries[] = $plotSer; + $plotAttributes = self::_readChartAttributes($chartDetail); + break; + case "scatterChart": + $scatterStyle = self::_getAttribute($chartDetail->scatterStyle, 'val', 'string'); + $plotSer = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey); + $plotSer->setPlotStyle($scatterStyle); + $plotSeries[] = $plotSer; + $plotAttributes = self::_readChartAttributes($chartDetail); + break; + case "bubbleChart": + $bubbleScale = self::_getAttribute($chartDetail->bubbleScale, 'val', 'integer'); + $plotSer = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey); + $plotSer->setPlotStyle($bubbleScale); + $plotSeries[] = $plotSer; + $plotAttributes = self::_readChartAttributes($chartDetail); + break; + case "radarChart": + $radarStyle = self::_getAttribute($chartDetail->radarStyle, 'val', 'string'); + $plotSer = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey); + $plotSer->setPlotStyle($radarStyle); + $plotSeries[] = $plotSer; + $plotAttributes = self::_readChartAttributes($chartDetail); + break; + case "surfaceChart": + case "surface3DChart": + $wireFrame = self::_getAttribute($chartDetail->wireframe, 'val', 'boolean'); + $plotSer = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey); + $plotSer->setPlotStyle($wireFrame); + $plotSeries[] = $plotSer; + $plotAttributes = self::_readChartAttributes($chartDetail); + break; + case "stockChart": + $plotSeries[] = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey); + $plotAttributes = self::_readChartAttributes($plotAreaLayout); + break; + } + } + if ($plotAreaLayout == NULL) { + $plotAreaLayout = new PHPExcel_Chart_Layout(); + } + $plotArea = new PHPExcel_Chart_PlotArea($plotAreaLayout,$plotSeries); + self::_setChartAttributes($plotAreaLayout,$plotAttributes); + break; + case "plotVisOnly": + $plotVisOnly = self::_getAttribute($chartDetails, 'val', 'string'); + break; + case "dispBlanksAs": + $dispBlanksAs = self::_getAttribute($chartDetails, 'val', 'string'); + break; + case "title": + $title = self::_chartTitle($chartDetails,$namespacesChartMeta,'title'); + break; + case "legend": + $legendPos = 'r'; + $legendLayout = null; + $legendOverlay = false; + foreach($chartDetails as $chartDetailKey => $chartDetail) { + switch ($chartDetailKey) { + case "legendPos": + $legendPos = self::_getAttribute($chartDetail, 'val', 'string'); + break; + case "overlay": + $legendOverlay = self::_getAttribute($chartDetail, 'val', 'boolean'); + break; + case "layout": + $legendLayout = self::_chartLayoutDetails($chartDetail,$namespacesChartMeta,'legend'); + break; + } + } + $legend = new PHPExcel_Chart_Legend($legendPos, $legendLayout, $legendOverlay); + break; + } + } + } + } + $chart = new PHPExcel_Chart($chartName,$title,$legend,$plotArea,$plotVisOnly,$dispBlanksAs,$XaxisLabel,$YaxisLabel); + + return $chart; + } // function readChart() + + + private static function _chartTitle($titleDetails,$namespacesChartMeta,$type) { + $caption = array(); + $titleLayout = null; + foreach($titleDetails as $titleDetailKey => $chartDetail) { + switch ($titleDetailKey) { + case "tx": + $titleDetails = $chartDetail->rich->children($namespacesChartMeta['a']); + foreach($titleDetails as $titleKey => $titleDetail) { + switch ($titleKey) { + case "p": + $titleDetailPart = $titleDetail->children($namespacesChartMeta['a']); + $caption[] = self::_parseRichText($titleDetailPart); + } + } + break; + case "layout": + $titleLayout = self::_chartLayoutDetails($chartDetail,$namespacesChartMeta); + break; + } + } + + return new PHPExcel_Chart_Title($caption, $titleLayout); + } // function _chartTitle() + + + private static function _chartLayoutDetails($chartDetail,$namespacesChartMeta) { + if (!isset($chartDetail->manualLayout)) { + return null; + } + $details = $chartDetail->manualLayout->children($namespacesChartMeta['c']); + if (is_null($details)) { + return null; + } + $layout = array(); + foreach($details as $detailKey => $detail) { +// echo $detailKey,' => ',self::_getAttribute($detail, 'val', 'string'),PHP_EOL; + $layout[$detailKey] = self::_getAttribute($detail, 'val', 'string'); + } + return new PHPExcel_Chart_Layout($layout); + } // function _chartLayoutDetails() + + + private static function _chartDataSeries($chartDetail,$namespacesChartMeta,$plotType) { + $multiSeriesType = NULL; + $smoothLine = false; + $seriesLabel = $seriesCategory = $seriesValues = $plotOrder = array(); + + $seriesDetailSet = $chartDetail->children($namespacesChartMeta['c']); + foreach($seriesDetailSet as $seriesDetailKey => $seriesDetails) { + switch ($seriesDetailKey) { + case "grouping": + $multiSeriesType = self::_getAttribute($chartDetail->grouping, 'val', 'string'); + break; + case "ser": + $marker = NULL; + foreach($seriesDetails as $seriesKey => $seriesDetail) { + switch ($seriesKey) { + case "idx": + $seriesIndex = self::_getAttribute($seriesDetail, 'val', 'integer'); + break; + case "order": + $seriesOrder = self::_getAttribute($seriesDetail, 'val', 'integer'); + $plotOrder[$seriesIndex] = $seriesOrder; + break; + case "tx": + $seriesLabel[$seriesIndex] = self::_chartDataSeriesValueSet($seriesDetail,$namespacesChartMeta); + break; + case "marker": + $marker = self::_getAttribute($seriesDetail->symbol, 'val', 'string'); + break; + case "smooth": + $smoothLine = self::_getAttribute($seriesDetail, 'val', 'boolean'); + break; + case "cat": + $seriesCategory[$seriesIndex] = self::_chartDataSeriesValueSet($seriesDetail,$namespacesChartMeta); + break; + case "val": + $seriesValues[$seriesIndex] = self::_chartDataSeriesValueSet($seriesDetail,$namespacesChartMeta,$marker); + break; + case "xVal": + $seriesCategory[$seriesIndex] = self::_chartDataSeriesValueSet($seriesDetail,$namespacesChartMeta,$marker); + break; + case "yVal": + $seriesValues[$seriesIndex] = self::_chartDataSeriesValueSet($seriesDetail,$namespacesChartMeta,$marker); + break; + } + } + } + } + return new PHPExcel_Chart_DataSeries($plotType,$multiSeriesType,$plotOrder,$seriesLabel,$seriesCategory,$seriesValues,$smoothLine); + } // function _chartDataSeries() + + + private static function _chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta, $marker = null, $smoothLine = false) { + if (isset($seriesDetail->strRef)) { + $seriesSource = (string) $seriesDetail->strRef->f; + $seriesData = self::_chartDataSeriesValues($seriesDetail->strRef->strCache->children($namespacesChartMeta['c']),'s'); + + return new PHPExcel_Chart_DataSeriesValues('String',$seriesSource,$seriesData['formatCode'],$seriesData['pointCount'],$seriesData['dataValues'],$marker,$smoothLine); + } elseif (isset($seriesDetail->numRef)) { + $seriesSource = (string) $seriesDetail->numRef->f; + $seriesData = self::_chartDataSeriesValues($seriesDetail->numRef->numCache->children($namespacesChartMeta['c'])); + + return new PHPExcel_Chart_DataSeriesValues('Number',$seriesSource,$seriesData['formatCode'],$seriesData['pointCount'],$seriesData['dataValues'],$marker,$smoothLine); + } elseif (isset($seriesDetail->multiLvlStrRef)) { + $seriesSource = (string) $seriesDetail->multiLvlStrRef->f; + $seriesData = self::_chartDataSeriesValuesMultiLevel($seriesDetail->multiLvlStrRef->multiLvlStrCache->children($namespacesChartMeta['c']),'s'); + $seriesData['pointCount'] = count($seriesData['dataValues']); + + return new PHPExcel_Chart_DataSeriesValues('String',$seriesSource,$seriesData['formatCode'],$seriesData['pointCount'],$seriesData['dataValues'],$marker,$smoothLine); + } elseif (isset($seriesDetail->multiLvlNumRef)) { + $seriesSource = (string) $seriesDetail->multiLvlNumRef->f; + $seriesData = self::_chartDataSeriesValuesMultiLevel($seriesDetail->multiLvlNumRef->multiLvlNumCache->children($namespacesChartMeta['c']),'s'); + $seriesData['pointCount'] = count($seriesData['dataValues']); + + return new PHPExcel_Chart_DataSeriesValues('String',$seriesSource,$seriesData['formatCode'],$seriesData['pointCount'],$seriesData['dataValues'],$marker,$smoothLine); + } + return null; + } // function _chartDataSeriesValueSet() + + + private static function _chartDataSeriesValues($seriesValueSet,$dataType='n') { + $seriesVal = array(); + $formatCode = ''; + $pointCount = 0; + + foreach($seriesValueSet as $seriesValueIdx => $seriesValue) { + switch ($seriesValueIdx) { + case 'ptCount': + $pointCount = self::_getAttribute($seriesValue, 'val', 'integer'); + break; + case 'formatCode': + $formatCode = (string) $seriesValue; + break; + case 'pt': + $pointVal = self::_getAttribute($seriesValue, 'idx', 'integer'); + if ($dataType == 's') { + $seriesVal[$pointVal] = (string) $seriesValue->v; + } else { + $seriesVal[$pointVal] = (float) $seriesValue->v; + } + break; + } + } + + if (empty($seriesVal)) { + $seriesVal = NULL; + } + + return array( 'formatCode' => $formatCode, + 'pointCount' => $pointCount, + 'dataValues' => $seriesVal + ); + } // function _chartDataSeriesValues() + + + private static function _chartDataSeriesValuesMultiLevel($seriesValueSet,$dataType='n') { + $seriesVal = array(); + $formatCode = ''; + $pointCount = 0; + + foreach($seriesValueSet->lvl as $seriesLevelIdx => $seriesLevel) { + foreach($seriesLevel as $seriesValueIdx => $seriesValue) { + switch ($seriesValueIdx) { + case 'ptCount': + $pointCount = self::_getAttribute($seriesValue, 'val', 'integer'); + break; + case 'formatCode': + $formatCode = (string) $seriesValue; + break; + case 'pt': + $pointVal = self::_getAttribute($seriesValue, 'idx', 'integer'); + if ($dataType == 's') { + $seriesVal[$pointVal][] = (string) $seriesValue->v; + } else { + $seriesVal[$pointVal][] = (float) $seriesValue->v; + } + break; + } + } + } + + return array( 'formatCode' => $formatCode, + 'pointCount' => $pointCount, + 'dataValues' => $seriesVal + ); + } // function _chartDataSeriesValuesMultiLevel() + + private static function _parseRichText($titleDetailPart = null) { + $value = new PHPExcel_RichText(); + + foreach($titleDetailPart as $titleDetailElementKey => $titleDetailElement) { + if (isset($titleDetailElement->t)) { + $objText = $value->createTextRun( (string) $titleDetailElement->t ); + } + if (isset($titleDetailElement->rPr)) { + if (isset($titleDetailElement->rPr->rFont["val"])) { + $objText->getFont()->setName((string) $titleDetailElement->rPr->rFont["val"]); + } + + $fontSize = (self::_getAttribute($titleDetailElement->rPr, 'sz', 'integer')); + if (!is_null($fontSize)) { + $objText->getFont()->setSize(floor($fontSize / 100)); + } + + $fontColor = (self::_getAttribute($titleDetailElement->rPr, 'color', 'string')); + if (!is_null($fontColor)) { + $objText->getFont()->setColor( new PHPExcel_Style_Color( self::_readColor($fontColor) ) ); + } + + $bold = self::_getAttribute($titleDetailElement->rPr, 'b', 'boolean'); + if (!is_null($bold)) { + $objText->getFont()->setBold($bold); + } + + $italic = self::_getAttribute($titleDetailElement->rPr, 'i', 'boolean'); + if (!is_null($italic)) { + $objText->getFont()->setItalic($italic); + } + + $baseline = self::_getAttribute($titleDetailElement->rPr, 'baseline', 'integer'); + if (!is_null($baseline)) { + if ($baseline > 0) { + $objText->getFont()->setSuperScript(true); + } elseif($baseline < 0) { + $objText->getFont()->setSubScript(true); + } + } + + $underscore = (self::_getAttribute($titleDetailElement->rPr, 'u', 'string')); + if (!is_null($underscore)) { + if ($underscore == 'sng') { + $objText->getFont()->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLE); + } elseif($underscore == 'dbl') { + $objText->getFont()->setUnderline(PHPExcel_Style_Font::UNDERLINE_DOUBLE); + } else { + $objText->getFont()->setUnderline(PHPExcel_Style_Font::UNDERLINE_NONE); + } + } + + $strikethrough = (self::_getAttribute($titleDetailElement->rPr, 's', 'string')); + if (!is_null($strikethrough)) { + if ($strikethrough == 'noStrike') { + $objText->getFont()->setStrikethrough(false); + } else { + $objText->getFont()->setStrikethrough(true); + } + } + } + } + + return $value; + } + + private static function _readChartAttributes($chartDetail) { + $plotAttributes = array(); + if (isset($chartDetail->dLbls)) { + if (isset($chartDetail->dLbls->howLegendKey)) { + $plotAttributes['showLegendKey'] = self::_getAttribute($chartDetail->dLbls->showLegendKey, 'val', 'string'); + } + if (isset($chartDetail->dLbls->showVal)) { + $plotAttributes['showVal'] = self::_getAttribute($chartDetail->dLbls->showVal, 'val', 'string'); + } + if (isset($chartDetail->dLbls->showCatName)) { + $plotAttributes['showCatName'] = self::_getAttribute($chartDetail->dLbls->showCatName, 'val', 'string'); + } + if (isset($chartDetail->dLbls->showSerName)) { + $plotAttributes['showSerName'] = self::_getAttribute($chartDetail->dLbls->showSerName, 'val', 'string'); + } + if (isset($chartDetail->dLbls->showPercent)) { + $plotAttributes['showPercent'] = self::_getAttribute($chartDetail->dLbls->showPercent, 'val', 'string'); + } + if (isset($chartDetail->dLbls->showBubbleSize)) { + $plotAttributes['showBubbleSize'] = self::_getAttribute($chartDetail->dLbls->showBubbleSize, 'val', 'string'); + } + if (isset($chartDetail->dLbls->showLeaderLines)) { + $plotAttributes['showLeaderLines'] = self::_getAttribute($chartDetail->dLbls->showLeaderLines, 'val', 'string'); + } + } + + return $plotAttributes; + } + + private static function _setChartAttributes($plotArea,$plotAttributes) + { + foreach($plotAttributes as $plotAttributeKey => $plotAttributeValue) { + switch($plotAttributeKey) { + case 'showLegendKey' : + $plotArea->setShowLegendKey($plotAttributeValue); + break; + case 'showVal' : + $plotArea->setShowVal($plotAttributeValue); + break; + case 'showCatName' : + $plotArea->setShowCatName($plotAttributeValue); + break; + case 'showSerName' : + $plotArea->setShowSerName($plotAttributeValue); + break; + case 'showPercent' : + $plotArea->setShowPercent($plotAttributeValue); + break; + case 'showBubbleSize' : + $plotArea->setShowBubbleSize($plotAttributeValue); + break; + case 'showLeaderLines' : + $plotArea->setShowLeaderLines($plotAttributeValue); + break; + } + } + } + +} diff --git a/lib/phpexcel/PHPExcel/Reader/Excel2007/Theme.php b/lib/phpexcel/PHPExcel/Reader/Excel2007/Theme.php new file mode 100644 index 0000000..820fa96 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Reader/Excel2007/Theme.php @@ -0,0 +1,124 @@ +_themeName = $themeName; + $this->_colourSchemeName = $colourSchemeName; + $this->_colourMap = $colourMap; + } + + /** + * Get Theme Name + * + * @return string + */ + public function getThemeName() + { + return $this->_themeName; + } + + /** + * Get colour Scheme Name + * + * @return string + */ + public function getColourSchemeName() { + return $this->_colourSchemeName; + } + + /** + * Get colour Map Value by Position + * + * @return string + */ + public function getColourByIndex($index=0) { + if (isset($this->_colourMap[$index])) { + return $this->_colourMap[$index]; + } + return null; + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if ((is_object($value)) && ($key != '_parent')) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } +} diff --git a/lib/phpexcel/PHPExcel/Reader/Excel5.php b/lib/phpexcel/PHPExcel/Reader/Excel5.php new file mode 100644 index 0000000..b43b315 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Reader/Excel5.php @@ -0,0 +1,7084 @@ +_data + * + * @var int + */ + private $_dataSize; + + /** + * Current position in stream + * + * @var integer + */ + private $_pos; + + /** + * Workbook to be returned by the reader. + * + * @var PHPExcel + */ + private $_phpExcel; + + /** + * Worksheet that is currently being built by the reader. + * + * @var PHPExcel_Worksheet + */ + private $_phpSheet; + + /** + * BIFF version + * + * @var int + */ + private $_version; + + /** + * Codepage set in the Excel file being read. Only important for BIFF5 (Excel 5.0 - Excel 95) + * For BIFF8 (Excel 97 - Excel 2003) this will always have the value 'UTF-16LE' + * + * @var string + */ + private $_codepage; + + /** + * Shared formats + * + * @var array + */ + private $_formats; + + /** + * Shared fonts + * + * @var array + */ + private $_objFonts; + + /** + * Color palette + * + * @var array + */ + private $_palette; + + /** + * Worksheets + * + * @var array + */ + private $_sheets; + + /** + * External books + * + * @var array + */ + private $_externalBooks; + + /** + * REF structures. Only applies to BIFF8. + * + * @var array + */ + private $_ref; + + /** + * External names + * + * @var array + */ + private $_externalNames; + + /** + * Defined names + * + * @var array + */ + private $_definedname; + + /** + * Shared strings. Only applies to BIFF8. + * + * @var array + */ + private $_sst; + + /** + * Panes are frozen? (in sheet currently being read). See WINDOW2 record. + * + * @var boolean + */ + private $_frozen; + + /** + * Fit printout to number of pages? (in sheet currently being read). See SHEETPR record. + * + * @var boolean + */ + private $_isFitToPages; + + /** + * Objects. One OBJ record contributes with one entry. + * + * @var array + */ + private $_objs; + + /** + * Text Objects. One TXO record corresponds with one entry. + * + * @var array + */ + private $_textObjects; + + /** + * Cell Annotations (BIFF8) + * + * @var array + */ + private $_cellNotes; + + /** + * The combined MSODRAWINGGROUP data + * + * @var string + */ + private $_drawingGroupData; + + /** + * The combined MSODRAWING data (per sheet) + * + * @var string + */ + private $_drawingData; + + /** + * Keep track of XF index + * + * @var int + */ + private $_xfIndex; + + /** + * Mapping of XF index (that is a cell XF) to final index in cellXf collection + * + * @var array + */ + private $_mapCellXfIndex; + + /** + * Mapping of XF index (that is a style XF) to final index in cellStyleXf collection + * + * @var array + */ + private $_mapCellStyleXfIndex; + + /** + * The shared formulas in a sheet. One SHAREDFMLA record contributes with one value. + * + * @var array + */ + private $_sharedFormulas; + + /** + * The shared formula parts in a sheet. One FORMULA record contributes with one value if it + * refers to a shared formula. + * + * @var array + */ + private $_sharedFormulaParts; + + /** + * The type of encryption in use + * + * @var int + */ + private $_encryption = 0; + + /** + * The position in the stream after which contents are encrypted + * + * @var int + */ + private $_encryptionStartPos = false; + + /** + * The current RC4 decryption object + * + * @var PHPExcel_Reader_Excel5_RC4 + */ + private $_rc4Key = null; + + /** + * The position in the stream that the RC4 decryption object was left at + * + * @var int + */ + private $_rc4Pos = 0; + + /** + * The current MD5 context state + * + * @var string + */ + private $_md5Ctxt = null; + + /** + * Create a new PHPExcel_Reader_Excel5 instance + */ + public function __construct() { + $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); + } + + + /** + * Can the current PHPExcel_Reader_IReader read the file? + * + * @param string $pFilename + * @return boolean + * @throws PHPExcel_Reader_Exception + */ + public function canRead($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + try { + // Use ParseXL for the hard work. + $ole = new PHPExcel_Shared_OLERead(); + + // get excel data + $res = $ole->read($pFilename); + return true; + } catch (PHPExcel_Exception $e) { + return false; + } + } + + + /** + * Reads names of the worksheets from a file, without parsing the whole file to a PHPExcel object + * + * @param string $pFilename + * @throws PHPExcel_Reader_Exception + */ + public function listWorksheetNames($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + $worksheetNames = array(); + + // Read the OLE file + $this->_loadOLE($pFilename); + + // total byte size of Excel data (workbook global substream + sheet substreams) + $this->_dataSize = strlen($this->_data); + + $this->_pos = 0; + $this->_sheets = array(); + + // Parse Workbook Global Substream + while ($this->_pos < $this->_dataSize) { + $code = self::_GetInt2d($this->_data, $this->_pos); + + switch ($code) { + case self::XLS_Type_BOF: $this->_readBof(); break; + case self::XLS_Type_SHEET: $this->_readSheet(); break; + case self::XLS_Type_EOF: $this->_readDefault(); break 2; + default: $this->_readDefault(); break; + } + } + + foreach ($this->_sheets as $sheet) { + if ($sheet['sheetType'] != 0x00) { + // 0x00: Worksheet, 0x02: Chart, 0x06: Visual Basic module + continue; + } + + $worksheetNames[] = $sheet['name']; + } + + return $worksheetNames; + } + + + /** + * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns) + * + * @param string $pFilename + * @throws PHPExcel_Reader_Exception + */ + public function listWorksheetInfo($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + $worksheetInfo = array(); + + // Read the OLE file + $this->_loadOLE($pFilename); + + // total byte size of Excel data (workbook global substream + sheet substreams) + $this->_dataSize = strlen($this->_data); + + // initialize + $this->_pos = 0; + $this->_sheets = array(); + + // Parse Workbook Global Substream + while ($this->_pos < $this->_dataSize) { + $code = self::_GetInt2d($this->_data, $this->_pos); + + switch ($code) { + case self::XLS_Type_BOF: $this->_readBof(); break; + case self::XLS_Type_SHEET: $this->_readSheet(); break; + case self::XLS_Type_EOF: $this->_readDefault(); break 2; + default: $this->_readDefault(); break; + } + } + + // Parse the individual sheets + foreach ($this->_sheets as $sheet) { + + if ($sheet['sheetType'] != 0x00) { + // 0x00: Worksheet + // 0x02: Chart + // 0x06: Visual Basic module + continue; + } + + $tmpInfo = array(); + $tmpInfo['worksheetName'] = $sheet['name']; + $tmpInfo['lastColumnLetter'] = 'A'; + $tmpInfo['lastColumnIndex'] = 0; + $tmpInfo['totalRows'] = 0; + $tmpInfo['totalColumns'] = 0; + + $this->_pos = $sheet['offset']; + + while ($this->_pos <= $this->_dataSize - 4) { + $code = self::_GetInt2d($this->_data, $this->_pos); + + switch ($code) { + case self::XLS_Type_RK: + case self::XLS_Type_LABELSST: + case self::XLS_Type_NUMBER: + case self::XLS_Type_FORMULA: + case self::XLS_Type_BOOLERR: + case self::XLS_Type_LABEL: + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + $rowIndex = self::_GetInt2d($recordData, 0) + 1; + $columnIndex = self::_GetInt2d($recordData, 2); + + $tmpInfo['totalRows'] = max($tmpInfo['totalRows'], $rowIndex); + $tmpInfo['lastColumnIndex'] = max($tmpInfo['lastColumnIndex'], $columnIndex); + break; + case self::XLS_Type_BOF: $this->_readBof(); break; + case self::XLS_Type_EOF: $this->_readDefault(); break 2; + default: $this->_readDefault(); break; + } + } + + $tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']); + $tmpInfo['totalColumns'] = $tmpInfo['lastColumnIndex'] + 1; + + $worksheetInfo[] = $tmpInfo; + } + + return $worksheetInfo; + } + + + /** + * Loads PHPExcel from file + * + * @param string $pFilename + * @return PHPExcel + * @throws PHPExcel_Reader_Exception + */ + public function load($pFilename) + { + // Read the OLE file + $this->_loadOLE($pFilename); + + // Initialisations + $this->_phpExcel = new PHPExcel; + $this->_phpExcel->removeSheetByIndex(0); // remove 1st sheet + if (!$this->_readDataOnly) { + $this->_phpExcel->removeCellStyleXfByIndex(0); // remove the default style + $this->_phpExcel->removeCellXfByIndex(0); // remove the default style + } + + // Read the summary information stream (containing meta data) + $this->_readSummaryInformation(); + + // Read the Additional document summary information stream (containing application-specific meta data) + $this->_readDocumentSummaryInformation(); + + // total byte size of Excel data (workbook global substream + sheet substreams) + $this->_dataSize = strlen($this->_data); + + // initialize + $this->_pos = 0; + $this->_codepage = 'CP1252'; + $this->_formats = array(); + $this->_objFonts = array(); + $this->_palette = array(); + $this->_sheets = array(); + $this->_externalBooks = array(); + $this->_ref = array(); + $this->_definedname = array(); + $this->_sst = array(); + $this->_drawingGroupData = ''; + $this->_xfIndex = ''; + $this->_mapCellXfIndex = array(); + $this->_mapCellStyleXfIndex = array(); + + // Parse Workbook Global Substream + while ($this->_pos < $this->_dataSize) { + $code = self::_GetInt2d($this->_data, $this->_pos); + + switch ($code) { + case self::XLS_Type_BOF: $this->_readBof(); break; + case self::XLS_Type_FILEPASS: $this->_readFilepass(); break; + case self::XLS_Type_CODEPAGE: $this->_readCodepage(); break; + case self::XLS_Type_DATEMODE: $this->_readDateMode(); break; + case self::XLS_Type_FONT: $this->_readFont(); break; + case self::XLS_Type_FORMAT: $this->_readFormat(); break; + case self::XLS_Type_XF: $this->_readXf(); break; + case self::XLS_Type_XFEXT: $this->_readXfExt(); break; + case self::XLS_Type_STYLE: $this->_readStyle(); break; + case self::XLS_Type_PALETTE: $this->_readPalette(); break; + case self::XLS_Type_SHEET: $this->_readSheet(); break; + case self::XLS_Type_EXTERNALBOOK: $this->_readExternalBook(); break; + case self::XLS_Type_EXTERNNAME: $this->_readExternName(); break; + case self::XLS_Type_EXTERNSHEET: $this->_readExternSheet(); break; + case self::XLS_Type_DEFINEDNAME: $this->_readDefinedName(); break; + case self::XLS_Type_MSODRAWINGGROUP: $this->_readMsoDrawingGroup(); break; + case self::XLS_Type_SST: $this->_readSst(); break; + case self::XLS_Type_EOF: $this->_readDefault(); break 2; + default: $this->_readDefault(); break; + } + } + + // Resolve indexed colors for font, fill, and border colors + // Cannot be resolved already in XF record, because PALETTE record comes afterwards + if (!$this->_readDataOnly) { + foreach ($this->_objFonts as $objFont) { + if (isset($objFont->colorIndex)) { + $color = self::_readColor($objFont->colorIndex,$this->_palette,$this->_version); + $objFont->getColor()->setRGB($color['rgb']); + } + } + + foreach ($this->_phpExcel->getCellXfCollection() as $objStyle) { + // fill start and end color + $fill = $objStyle->getFill(); + + if (isset($fill->startcolorIndex)) { + $startColor = self::_readColor($fill->startcolorIndex,$this->_palette,$this->_version); + $fill->getStartColor()->setRGB($startColor['rgb']); + } + + if (isset($fill->endcolorIndex)) { + $endColor = self::_readColor($fill->endcolorIndex,$this->_palette,$this->_version); + $fill->getEndColor()->setRGB($endColor['rgb']); + } + + // border colors + $top = $objStyle->getBorders()->getTop(); + $right = $objStyle->getBorders()->getRight(); + $bottom = $objStyle->getBorders()->getBottom(); + $left = $objStyle->getBorders()->getLeft(); + $diagonal = $objStyle->getBorders()->getDiagonal(); + + if (isset($top->colorIndex)) { + $borderTopColor = self::_readColor($top->colorIndex,$this->_palette,$this->_version); + $top->getColor()->setRGB($borderTopColor['rgb']); + } + + if (isset($right->colorIndex)) { + $borderRightColor = self::_readColor($right->colorIndex,$this->_palette,$this->_version); + $right->getColor()->setRGB($borderRightColor['rgb']); + } + + if (isset($bottom->colorIndex)) { + $borderBottomColor = self::_readColor($bottom->colorIndex,$this->_palette,$this->_version); + $bottom->getColor()->setRGB($borderBottomColor['rgb']); + } + + if (isset($left->colorIndex)) { + $borderLeftColor = self::_readColor($left->colorIndex,$this->_palette,$this->_version); + $left->getColor()->setRGB($borderLeftColor['rgb']); + } + + if (isset($diagonal->colorIndex)) { + $borderDiagonalColor = self::_readColor($diagonal->colorIndex,$this->_palette,$this->_version); + $diagonal->getColor()->setRGB($borderDiagonalColor['rgb']); + } + } + } + + // treat MSODRAWINGGROUP records, workbook-level Escher + if (!$this->_readDataOnly && $this->_drawingGroupData) { + $escherWorkbook = new PHPExcel_Shared_Escher(); + $reader = new PHPExcel_Reader_Excel5_Escher($escherWorkbook); + $escherWorkbook = $reader->load($this->_drawingGroupData); + + // debug Escher stream + //$debug = new Debug_Escher(new PHPExcel_Shared_Escher()); + //$debug->load($this->_drawingGroupData); + } + + // Parse the individual sheets + foreach ($this->_sheets as $sheet) { + + if ($sheet['sheetType'] != 0x00) { + // 0x00: Worksheet, 0x02: Chart, 0x06: Visual Basic module + continue; + } + + // check if sheet should be skipped + if (isset($this->_loadSheetsOnly) && !in_array($sheet['name'], $this->_loadSheetsOnly)) { + continue; + } + + // add sheet to PHPExcel object + $this->_phpSheet = $this->_phpExcel->createSheet(); + // Use false for $updateFormulaCellReferences to prevent adjustment of worksheet references in formula + // cells... during the load, all formulae should be correct, and we're simply bringing the worksheet + // name in line with the formula, not the reverse + $this->_phpSheet->setTitle($sheet['name'],false); + $this->_phpSheet->setSheetState($sheet['sheetState']); + + $this->_pos = $sheet['offset']; + + // Initialize isFitToPages. May change after reading SHEETPR record. + $this->_isFitToPages = false; + + // Initialize drawingData + $this->_drawingData = ''; + + // Initialize objs + $this->_objs = array(); + + // Initialize shared formula parts + $this->_sharedFormulaParts = array(); + + // Initialize shared formulas + $this->_sharedFormulas = array(); + + // Initialize text objs + $this->_textObjects = array(); + + // Initialize cell annotations + $this->_cellNotes = array(); + $this->textObjRef = -1; + + while ($this->_pos <= $this->_dataSize - 4) { + $code = self::_GetInt2d($this->_data, $this->_pos); + + switch ($code) { + case self::XLS_Type_BOF: $this->_readBof(); break; + case self::XLS_Type_PRINTGRIDLINES: $this->_readPrintGridlines(); break; + case self::XLS_Type_DEFAULTROWHEIGHT: $this->_readDefaultRowHeight(); break; + case self::XLS_Type_SHEETPR: $this->_readSheetPr(); break; + case self::XLS_Type_HORIZONTALPAGEBREAKS: $this->_readHorizontalPageBreaks(); break; + case self::XLS_Type_VERTICALPAGEBREAKS: $this->_readVerticalPageBreaks(); break; + case self::XLS_Type_HEADER: $this->_readHeader(); break; + case self::XLS_Type_FOOTER: $this->_readFooter(); break; + case self::XLS_Type_HCENTER: $this->_readHcenter(); break; + case self::XLS_Type_VCENTER: $this->_readVcenter(); break; + case self::XLS_Type_LEFTMARGIN: $this->_readLeftMargin(); break; + case self::XLS_Type_RIGHTMARGIN: $this->_readRightMargin(); break; + case self::XLS_Type_TOPMARGIN: $this->_readTopMargin(); break; + case self::XLS_Type_BOTTOMMARGIN: $this->_readBottomMargin(); break; + case self::XLS_Type_PAGESETUP: $this->_readPageSetup(); break; + case self::XLS_Type_PROTECT: $this->_readProtect(); break; + case self::XLS_Type_SCENPROTECT: $this->_readScenProtect(); break; + case self::XLS_Type_OBJECTPROTECT: $this->_readObjectProtect(); break; + case self::XLS_Type_PASSWORD: $this->_readPassword(); break; + case self::XLS_Type_DEFCOLWIDTH: $this->_readDefColWidth(); break; + case self::XLS_Type_COLINFO: $this->_readColInfo(); break; + case self::XLS_Type_DIMENSION: $this->_readDefault(); break; + case self::XLS_Type_ROW: $this->_readRow(); break; + case self::XLS_Type_DBCELL: $this->_readDefault(); break; + case self::XLS_Type_RK: $this->_readRk(); break; + case self::XLS_Type_LABELSST: $this->_readLabelSst(); break; + case self::XLS_Type_MULRK: $this->_readMulRk(); break; + case self::XLS_Type_NUMBER: $this->_readNumber(); break; + case self::XLS_Type_FORMULA: $this->_readFormula(); break; + case self::XLS_Type_SHAREDFMLA: $this->_readSharedFmla(); break; + case self::XLS_Type_BOOLERR: $this->_readBoolErr(); break; + case self::XLS_Type_MULBLANK: $this->_readMulBlank(); break; + case self::XLS_Type_LABEL: $this->_readLabel(); break; + case self::XLS_Type_BLANK: $this->_readBlank(); break; + case self::XLS_Type_MSODRAWING: $this->_readMsoDrawing(); break; + case self::XLS_Type_OBJ: $this->_readObj(); break; + case self::XLS_Type_WINDOW2: $this->_readWindow2(); break; + case self::XLS_Type_PAGELAYOUTVIEW: $this->_readPageLayoutView(); break; + case self::XLS_Type_SCL: $this->_readScl(); break; + case self::XLS_Type_PANE: $this->_readPane(); break; + case self::XLS_Type_SELECTION: $this->_readSelection(); break; + case self::XLS_Type_MERGEDCELLS: $this->_readMergedCells(); break; + case self::XLS_Type_HYPERLINK: $this->_readHyperLink(); break; + case self::XLS_Type_DATAVALIDATIONS: $this->_readDataValidations(); break; + case self::XLS_Type_DATAVALIDATION: $this->_readDataValidation(); break; + case self::XLS_Type_SHEETLAYOUT: $this->_readSheetLayout(); break; + case self::XLS_Type_SHEETPROTECTION: $this->_readSheetProtection(); break; + case self::XLS_Type_RANGEPROTECTION: $this->_readRangeProtection(); break; + case self::XLS_Type_NOTE: $this->_readNote(); break; + //case self::XLS_Type_IMDATA: $this->_readImData(); break; + case self::XLS_Type_TXO: $this->_readTextObject(); break; + case self::XLS_Type_CONTINUE: $this->_readContinue(); break; + case self::XLS_Type_EOF: $this->_readDefault(); break 2; + default: $this->_readDefault(); break; + } + + } + + // treat MSODRAWING records, sheet-level Escher + if (!$this->_readDataOnly && $this->_drawingData) { + $escherWorksheet = new PHPExcel_Shared_Escher(); + $reader = new PHPExcel_Reader_Excel5_Escher($escherWorksheet); + $escherWorksheet = $reader->load($this->_drawingData); + + // debug Escher stream + //$debug = new Debug_Escher(new PHPExcel_Shared_Escher()); + //$debug->load($this->_drawingData); + + // get all spContainers in one long array, so they can be mapped to OBJ records + $allSpContainers = $escherWorksheet->getDgContainer()->getSpgrContainer()->getAllSpContainers(); + } + + // treat OBJ records + foreach ($this->_objs as $n => $obj) { +// echo '
            Object reference is ',$n,'
            '; +// var_dump($obj); +// echo '
            '; + + // the first shape container never has a corresponding OBJ record, hence $n + 1 + if (isset($allSpContainers[$n + 1]) && is_object($allSpContainers[$n + 1])) { + $spContainer = $allSpContainers[$n + 1]; + + // we skip all spContainers that are a part of a group shape since we cannot yet handle those + if ($spContainer->getNestingLevel() > 1) { + continue; + } + + // calculate the width and height of the shape + list($startColumn, $startRow) = PHPExcel_Cell::coordinateFromString($spContainer->getStartCoordinates()); + list($endColumn, $endRow) = PHPExcel_Cell::coordinateFromString($spContainer->getEndCoordinates()); + + $startOffsetX = $spContainer->getStartOffsetX(); + $startOffsetY = $spContainer->getStartOffsetY(); + $endOffsetX = $spContainer->getEndOffsetX(); + $endOffsetY = $spContainer->getEndOffsetY(); + + $width = PHPExcel_Shared_Excel5::getDistanceX($this->_phpSheet, $startColumn, $startOffsetX, $endColumn, $endOffsetX); + $height = PHPExcel_Shared_Excel5::getDistanceY($this->_phpSheet, $startRow, $startOffsetY, $endRow, $endOffsetY); + + // calculate offsetX and offsetY of the shape + $offsetX = $startOffsetX * PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, $startColumn) / 1024; + $offsetY = $startOffsetY * PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $startRow) / 256; + + switch ($obj['otObjType']) { + case 0x19: + // Note +// echo 'Cell Annotation Object
            '; +// echo 'Object ID is ',$obj['idObjID'],'
            '; +// + if (isset($this->_cellNotes[$obj['idObjID']])) { + $cellNote = $this->_cellNotes[$obj['idObjID']]; + + if (isset($this->_textObjects[$obj['idObjID']])) { + $textObject = $this->_textObjects[$obj['idObjID']]; + $this->_cellNotes[$obj['idObjID']]['objTextData'] = $textObject; + } + } + break; + + case 0x08: +// echo 'Picture Object
            '; + // picture + + // get index to BSE entry (1-based) + $BSEindex = $spContainer->getOPT(0x0104); + $BSECollection = $escherWorkbook->getDggContainer()->getBstoreContainer()->getBSECollection(); + $BSE = $BSECollection[$BSEindex - 1]; + $blipType = $BSE->getBlipType(); + + // need check because some blip types are not supported by Escher reader such as EMF + if ($blip = $BSE->getBlip()) { + $ih = imagecreatefromstring($blip->getData()); + $drawing = new PHPExcel_Worksheet_MemoryDrawing(); + $drawing->setImageResource($ih); + + // width, height, offsetX, offsetY + $drawing->setResizeProportional(false); + $drawing->setWidth($width); + $drawing->setHeight($height); + $drawing->setOffsetX($offsetX); + $drawing->setOffsetY($offsetY); + + switch ($blipType) { + case PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_JPEG: + $drawing->setRenderingFunction(PHPExcel_Worksheet_MemoryDrawing::RENDERING_JPEG); + $drawing->setMimeType(PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_JPEG); + break; + + case PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG: + $drawing->setRenderingFunction(PHPExcel_Worksheet_MemoryDrawing::RENDERING_PNG); + $drawing->setMimeType(PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_PNG); + break; + } + + $drawing->setWorksheet($this->_phpSheet); + $drawing->setCoordinates($spContainer->getStartCoordinates()); + } + + break; + + default: + // other object type + break; + + } + } + } + + // treat SHAREDFMLA records + if ($this->_version == self::XLS_BIFF8) { + foreach ($this->_sharedFormulaParts as $cell => $baseCell) { + list($column, $row) = PHPExcel_Cell::coordinateFromString($cell); + if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($column, $row, $this->_phpSheet->getTitle()) ) { + $formula = $this->_getFormulaFromStructure($this->_sharedFormulas[$baseCell], $cell); + $this->_phpSheet->getCell($cell)->setValueExplicit('=' . $formula, PHPExcel_Cell_DataType::TYPE_FORMULA); + } + } + } + + if (!empty($this->_cellNotes)) { + foreach($this->_cellNotes as $note => $noteDetails) { + if (!isset($noteDetails['objTextData'])) { + if (isset($this->_textObjects[$note])) { + $textObject = $this->_textObjects[$note]; + $noteDetails['objTextData'] = $textObject; + } else { + $noteDetails['objTextData']['text'] = ''; + } + } +// echo 'Cell annotation ',$note,'
            '; +// var_dump($noteDetails); +// echo '
            '; + $cellAddress = str_replace('$','',$noteDetails['cellRef']); + $this->_phpSheet->getComment( $cellAddress ) + ->setAuthor( $noteDetails['author'] ) + ->setText($this->_parseRichText($noteDetails['objTextData']['text']) ); + } + } + } + + // add the named ranges (defined names) + foreach ($this->_definedname as $definedName) { + if ($definedName['isBuiltInName']) { + switch ($definedName['name']) { + + case pack('C', 0x06): + // print area + // in general, formula looks like this: Foo!$C$7:$J$66,Bar!$A$1:$IV$2 + $ranges = explode(',', $definedName['formula']); // FIXME: what if sheetname contains comma? + + $extractedRanges = array(); + foreach ($ranges as $range) { + // $range should look like one of these + // Foo!$C$7:$J$66 + // Bar!$A$1:$IV$2 + + $explodes = explode('!', $range); // FIXME: what if sheetname contains exclamation mark? + $sheetName = trim($explodes[0], "'"); + + if (count($explodes) == 2) { + if (strpos($explodes[1], ':') === FALSE) { + $explodes[1] = $explodes[1] . ':' . $explodes[1]; + } + $extractedRanges[] = str_replace('$', '', $explodes[1]); // C7:J66 + } + } + if ($docSheet = $this->_phpExcel->getSheetByName($sheetName)) { + $docSheet->getPageSetup()->setPrintArea(implode(',', $extractedRanges)); // C7:J66,A1:IV2 + } + break; + + case pack('C', 0x07): + // print titles (repeating rows) + // Assuming BIFF8, there are 3 cases + // 1. repeating rows + // formula looks like this: Sheet!$A$1:$IV$2 + // rows 1-2 repeat + // 2. repeating columns + // formula looks like this: Sheet!$A$1:$B$65536 + // columns A-B repeat + // 3. both repeating rows and repeating columns + // formula looks like this: Sheet!$A$1:$B$65536,Sheet!$A$1:$IV$2 + + $ranges = explode(',', $definedName['formula']); // FIXME: what if sheetname contains comma? + + foreach ($ranges as $range) { + // $range should look like this one of these + // Sheet!$A$1:$B$65536 + // Sheet!$A$1:$IV$2 + + $explodes = explode('!', $range); + + if (count($explodes) == 2) { + if ($docSheet = $this->_phpExcel->getSheetByName($explodes[0])) { + + $extractedRange = $explodes[1]; + $extractedRange = str_replace('$', '', $extractedRange); + + $coordinateStrings = explode(':', $extractedRange); + if (count($coordinateStrings) == 2) { + list($firstColumn, $firstRow) = PHPExcel_Cell::coordinateFromString($coordinateStrings[0]); + list($lastColumn, $lastRow) = PHPExcel_Cell::coordinateFromString($coordinateStrings[1]); + + if ($firstColumn == 'A' and $lastColumn == 'IV') { + // then we have repeating rows + $docSheet->getPageSetup()->setRowsToRepeatAtTop(array($firstRow, $lastRow)); + } elseif ($firstRow == 1 and $lastRow == 65536) { + // then we have repeating columns + $docSheet->getPageSetup()->setColumnsToRepeatAtLeft(array($firstColumn, $lastColumn)); + } + } + } + } + } + break; + + } + } else { + // Extract range + $explodes = explode('!', $definedName['formula']); + + if (count($explodes) == 2) { + if (($docSheet = $this->_phpExcel->getSheetByName($explodes[0])) || + ($docSheet = $this->_phpExcel->getSheetByName(trim($explodes[0],"'")))) { + $extractedRange = $explodes[1]; + $extractedRange = str_replace('$', '', $extractedRange); + + $localOnly = ($definedName['scope'] == 0) ? false : true; + + $scope = ($definedName['scope'] == 0) ? + null : $this->_phpExcel->getSheetByName($this->_sheets[$definedName['scope'] - 1]['name']); + + $this->_phpExcel->addNamedRange( new PHPExcel_NamedRange((string)$definedName['name'], $docSheet, $extractedRange, $localOnly, $scope) ); + } + } else { + // Named Value + // TODO Provide support for named values + } + } + } + + return $this->_phpExcel; + } + + /** + * Read record data from stream, decrypting as required + * + * @param string $data Data stream to read from + * @param int $pos Position to start reading from + * @param int $length Record data length + * + * @return string Record data + */ + private function _readRecordData($data, $pos, $len) + { + $data = substr($data, $pos, $len); + + // File not encrypted, or record before encryption start point + if ($this->_encryption == self::MS_BIFF_CRYPTO_NONE || $pos < $this->_encryptionStartPos) { + return $data; + } + + $recordData = ''; + if ($this->_encryption == self::MS_BIFF_CRYPTO_RC4) { + + $oldBlock = floor($this->_rc4Pos / self::REKEY_BLOCK); + $block = floor($pos / self::REKEY_BLOCK); + $endBlock = floor(($pos + $len) / self::REKEY_BLOCK); + + // Spin an RC4 decryptor to the right spot. If we have a decryptor sitting + // at a point earlier in the current block, re-use it as we can save some time. + if ($block != $oldBlock || $pos < $this->_rc4Pos || !$this->_rc4Key) { + $this->_rc4Key = $this->_makeKey($block, $this->_md5Ctxt); + $step = $pos % self::REKEY_BLOCK; + } else { + $step = $pos - $this->_rc4Pos; + } + $this->_rc4Key->RC4(str_repeat("\0", $step)); + + // Decrypt record data (re-keying at the end of every block) + while ($block != $endBlock) { + $step = self::REKEY_BLOCK - ($pos % self::REKEY_BLOCK); + $recordData .= $this->_rc4Key->RC4(substr($data, 0, $step)); + $data = substr($data, $step); + $pos += $step; + $len -= $step; + $block++; + $this->_rc4Key = $this->_makeKey($block, $this->_md5Ctxt); + } + $recordData .= $this->_rc4Key->RC4(substr($data, 0, $len)); + + // Keep track of the position of this decryptor. + // We'll try and re-use it later if we can to speed things up + $this->_rc4Pos = $pos + $len; + + } elseif ($this->_encryption == self::MS_BIFF_CRYPTO_XOR) { + throw new PHPExcel_Reader_Exception('XOr encryption not supported'); + } + return $recordData; + } + + /** + * Use OLE reader to extract the relevant data streams from the OLE file + * + * @param string $pFilename + */ + private function _loadOLE($pFilename) + { + // OLE reader + $ole = new PHPExcel_Shared_OLERead(); + + // get excel data, + $res = $ole->read($pFilename); + // Get workbook data: workbook stream + sheet streams + $this->_data = $ole->getStream($ole->wrkbook); + + // Get summary information data + $this->_summaryInformation = $ole->getStream($ole->summaryInformation); + + // Get additional document summary information data + $this->_documentSummaryInformation = $ole->getStream($ole->documentSummaryInformation); + + // Get user-defined property data +// $this->_userDefinedProperties = $ole->getUserDefinedProperties(); + } + + + /** + * Read summary information + */ + private function _readSummaryInformation() + { + if (!isset($this->_summaryInformation)) { + return; + } + + // offset: 0; size: 2; must be 0xFE 0xFF (UTF-16 LE byte order mark) + // offset: 2; size: 2; + // offset: 4; size: 2; OS version + // offset: 6; size: 2; OS indicator + // offset: 8; size: 16 + // offset: 24; size: 4; section count + $secCount = self::_GetInt4d($this->_summaryInformation, 24); + + // offset: 28; size: 16; first section's class id: e0 85 9f f2 f9 4f 68 10 ab 91 08 00 2b 27 b3 d9 + // offset: 44; size: 4 + $secOffset = self::_GetInt4d($this->_summaryInformation, 44); + + // section header + // offset: $secOffset; size: 4; section length + $secLength = self::_GetInt4d($this->_summaryInformation, $secOffset); + + // offset: $secOffset+4; size: 4; property count + $countProperties = self::_GetInt4d($this->_summaryInformation, $secOffset+4); + + // initialize code page (used to resolve string values) + $codePage = 'CP1252'; + + // offset: ($secOffset+8); size: var + // loop through property decarations and properties + for ($i = 0; $i < $countProperties; ++$i) { + + // offset: ($secOffset+8) + (8 * $i); size: 4; property ID + $id = self::_GetInt4d($this->_summaryInformation, ($secOffset+8) + (8 * $i)); + + // Use value of property id as appropriate + // offset: ($secOffset+12) + (8 * $i); size: 4; offset from beginning of section (48) + $offset = self::_GetInt4d($this->_summaryInformation, ($secOffset+12) + (8 * $i)); + + $type = self::_GetInt4d($this->_summaryInformation, $secOffset + $offset); + + // initialize property value + $value = null; + + // extract property value based on property type + switch ($type) { + case 0x02: // 2 byte signed integer + $value = self::_GetInt2d($this->_summaryInformation, $secOffset + 4 + $offset); + break; + + case 0x03: // 4 byte signed integer + $value = self::_GetInt4d($this->_summaryInformation, $secOffset + 4 + $offset); + break; + + case 0x13: // 4 byte unsigned integer + // not needed yet, fix later if necessary + break; + + case 0x1E: // null-terminated string prepended by dword string length + $byteLength = self::_GetInt4d($this->_summaryInformation, $secOffset + 4 + $offset); + $value = substr($this->_summaryInformation, $secOffset + 8 + $offset, $byteLength); + $value = PHPExcel_Shared_String::ConvertEncoding($value, 'UTF-8', $codePage); + $value = rtrim($value); + break; + + case 0x40: // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) + // PHP-time + $value = PHPExcel_Shared_OLE::OLE2LocalDate(substr($this->_summaryInformation, $secOffset + 4 + $offset, 8)); + break; + + case 0x47: // Clipboard format + // not needed yet, fix later if necessary + break; + } + + switch ($id) { + case 0x01: // Code Page + $codePage = PHPExcel_Shared_CodePage::NumberToName($value); + break; + + case 0x02: // Title + $this->_phpExcel->getProperties()->setTitle($value); + break; + + case 0x03: // Subject + $this->_phpExcel->getProperties()->setSubject($value); + break; + + case 0x04: // Author (Creator) + $this->_phpExcel->getProperties()->setCreator($value); + break; + + case 0x05: // Keywords + $this->_phpExcel->getProperties()->setKeywords($value); + break; + + case 0x06: // Comments (Description) + $this->_phpExcel->getProperties()->setDescription($value); + break; + + case 0x07: // Template + // Not supported by PHPExcel + break; + + case 0x08: // Last Saved By (LastModifiedBy) + $this->_phpExcel->getProperties()->setLastModifiedBy($value); + break; + + case 0x09: // Revision + // Not supported by PHPExcel + break; + + case 0x0A: // Total Editing Time + // Not supported by PHPExcel + break; + + case 0x0B: // Last Printed + // Not supported by PHPExcel + break; + + case 0x0C: // Created Date/Time + $this->_phpExcel->getProperties()->setCreated($value); + break; + + case 0x0D: // Modified Date/Time + $this->_phpExcel->getProperties()->setModified($value); + break; + + case 0x0E: // Number of Pages + // Not supported by PHPExcel + break; + + case 0x0F: // Number of Words + // Not supported by PHPExcel + break; + + case 0x10: // Number of Characters + // Not supported by PHPExcel + break; + + case 0x11: // Thumbnail + // Not supported by PHPExcel + break; + + case 0x12: // Name of creating application + // Not supported by PHPExcel + break; + + case 0x13: // Security + // Not supported by PHPExcel + break; + + } + } + } + + + /** + * Read additional document summary information + */ + private function _readDocumentSummaryInformation() + { + if (!isset($this->_documentSummaryInformation)) { + return; + } + + // offset: 0; size: 2; must be 0xFE 0xFF (UTF-16 LE byte order mark) + // offset: 2; size: 2; + // offset: 4; size: 2; OS version + // offset: 6; size: 2; OS indicator + // offset: 8; size: 16 + // offset: 24; size: 4; section count + $secCount = self::_GetInt4d($this->_documentSummaryInformation, 24); +// echo '$secCount = ',$secCount,'
            '; + + // offset: 28; size: 16; first section's class id: 02 d5 cd d5 9c 2e 1b 10 93 97 08 00 2b 2c f9 ae + // offset: 44; size: 4; first section offset + $secOffset = self::_GetInt4d($this->_documentSummaryInformation, 44); +// echo '$secOffset = ',$secOffset,'
            '; + + // section header + // offset: $secOffset; size: 4; section length + $secLength = self::_GetInt4d($this->_documentSummaryInformation, $secOffset); +// echo '$secLength = ',$secLength,'
            '; + + // offset: $secOffset+4; size: 4; property count + $countProperties = self::_GetInt4d($this->_documentSummaryInformation, $secOffset+4); +// echo '$countProperties = ',$countProperties,'
            '; + + // initialize code page (used to resolve string values) + $codePage = 'CP1252'; + + // offset: ($secOffset+8); size: var + // loop through property decarations and properties + for ($i = 0; $i < $countProperties; ++$i) { +// echo 'Property ',$i,'
            '; + // offset: ($secOffset+8) + (8 * $i); size: 4; property ID + $id = self::_GetInt4d($this->_documentSummaryInformation, ($secOffset+8) + (8 * $i)); +// echo 'ID is ',$id,'
            '; + + // Use value of property id as appropriate + // offset: 60 + 8 * $i; size: 4; offset from beginning of section (48) + $offset = self::_GetInt4d($this->_documentSummaryInformation, ($secOffset+12) + (8 * $i)); + + $type = self::_GetInt4d($this->_documentSummaryInformation, $secOffset + $offset); +// echo 'Type is ',$type,', '; + + // initialize property value + $value = null; + + // extract property value based on property type + switch ($type) { + case 0x02: // 2 byte signed integer + $value = self::_GetInt2d($this->_documentSummaryInformation, $secOffset + 4 + $offset); + break; + + case 0x03: // 4 byte signed integer + $value = self::_GetInt4d($this->_documentSummaryInformation, $secOffset + 4 + $offset); + break; + + case 0x0B: // Boolean + $value = self::_GetInt2d($this->_documentSummaryInformation, $secOffset + 4 + $offset); + $value = ($value == 0 ? false : true); + break; + + case 0x13: // 4 byte unsigned integer + // not needed yet, fix later if necessary + break; + + case 0x1E: // null-terminated string prepended by dword string length + $byteLength = self::_GetInt4d($this->_documentSummaryInformation, $secOffset + 4 + $offset); + $value = substr($this->_documentSummaryInformation, $secOffset + 8 + $offset, $byteLength); + $value = PHPExcel_Shared_String::ConvertEncoding($value, 'UTF-8', $codePage); + $value = rtrim($value); + break; + + case 0x40: // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) + // PHP-Time + $value = PHPExcel_Shared_OLE::OLE2LocalDate(substr($this->_documentSummaryInformation, $secOffset + 4 + $offset, 8)); + break; + + case 0x47: // Clipboard format + // not needed yet, fix later if necessary + break; + } + + switch ($id) { + case 0x01: // Code Page + $codePage = PHPExcel_Shared_CodePage::NumberToName($value); + break; + + case 0x02: // Category + $this->_phpExcel->getProperties()->setCategory($value); + break; + + case 0x03: // Presentation Target + // Not supported by PHPExcel + break; + + case 0x04: // Bytes + // Not supported by PHPExcel + break; + + case 0x05: // Lines + // Not supported by PHPExcel + break; + + case 0x06: // Paragraphs + // Not supported by PHPExcel + break; + + case 0x07: // Slides + // Not supported by PHPExcel + break; + + case 0x08: // Notes + // Not supported by PHPExcel + break; + + case 0x09: // Hidden Slides + // Not supported by PHPExcel + break; + + case 0x0A: // MM Clips + // Not supported by PHPExcel + break; + + case 0x0B: // Scale Crop + // Not supported by PHPExcel + break; + + case 0x0C: // Heading Pairs + // Not supported by PHPExcel + break; + + case 0x0D: // Titles of Parts + // Not supported by PHPExcel + break; + + case 0x0E: // Manager + $this->_phpExcel->getProperties()->setManager($value); + break; + + case 0x0F: // Company + $this->_phpExcel->getProperties()->setCompany($value); + break; + + case 0x10: // Links up-to-date + // Not supported by PHPExcel + break; + + } + } + } + + + /** + * Reads a general type of BIFF record. Does nothing except for moving stream pointer forward to next record. + */ + private function _readDefault() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); +// $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + } + + + /** + * The NOTE record specifies a comment associated with a particular cell. In Excel 95 (BIFF7) and earlier versions, + * this record stores a note (cell note). This feature was significantly enhanced in Excel 97. + */ + private function _readNote() + { +// echo 'Read Cell Annotation
            '; + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_readDataOnly) { + return; + } + + $cellAddress = $this->_readBIFF8CellAddress(substr($recordData, 0, 4)); + if ($this->_version == self::XLS_BIFF8) { + $noteObjID = self::_GetInt2d($recordData, 6); + $noteAuthor = self::_readUnicodeStringLong(substr($recordData, 8)); + $noteAuthor = $noteAuthor['value']; +// echo 'Note Address=',$cellAddress,'
            '; +// echo 'Note Object ID=',$noteObjID,'
            '; +// echo 'Note Author=',$noteAuthor,'
            '; +// + $this->_cellNotes[$noteObjID] = array('cellRef' => $cellAddress, + 'objectID' => $noteObjID, + 'author' => $noteAuthor + ); + } else { + $extension = false; + if ($cellAddress == '$B$65536') { + // If the address row is -1 and the column is 0, (which translates as $B$65536) then this is a continuation + // note from the previous cell annotation. We're not yet handling this, so annotations longer than the + // max 2048 bytes will probably throw a wobbly. + $row = self::_GetInt2d($recordData, 0); + $extension = true; + $cellAddress = array_pop(array_keys($this->_phpSheet->getComments())); + } +// echo 'Note Address=',$cellAddress,'
            '; + + $cellAddress = str_replace('$','',$cellAddress); + $noteLength = self::_GetInt2d($recordData, 4); + $noteText = trim(substr($recordData, 6)); +// echo 'Note Length=',$noteLength,'
            '; +// echo 'Note Text=',$noteText,'
            '; + + if ($extension) { + // Concatenate this extension with the currently set comment for the cell + $comment = $this->_phpSheet->getComment( $cellAddress ); + $commentText = $comment->getText()->getPlainText(); + $comment->setText($this->_parseRichText($commentText.$noteText) ); + } else { + // Set comment for the cell + $this->_phpSheet->getComment( $cellAddress ) +// ->setAuthor( $author ) + ->setText($this->_parseRichText($noteText) ); + } + } + + } + + + /** + * The TEXT Object record contains the text associated with a cell annotation. + */ + private function _readTextObject() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_readDataOnly) { + return; + } + + // recordData consists of an array of subrecords looking like this: + // grbit: 2 bytes; Option Flags + // rot: 2 bytes; rotation + // cchText: 2 bytes; length of the text (in the first continue record) + // cbRuns: 2 bytes; length of the formatting (in the second continue record) + // followed by the continuation records containing the actual text and formatting + $grbitOpts = self::_GetInt2d($recordData, 0); + $rot = self::_GetInt2d($recordData, 2); + $cchText = self::_GetInt2d($recordData, 10); + $cbRuns = self::_GetInt2d($recordData, 12); + $text = $this->_getSplicedRecordData(); + + $this->_textObjects[$this->textObjRef] = array( + 'text' => substr($text["recordData"],$text["spliceOffsets"][0]+1,$cchText), + 'format' => substr($text["recordData"],$text["spliceOffsets"][1],$cbRuns), + 'alignment' => $grbitOpts, + 'rotation' => $rot + ); + +// echo '_readTextObject()
            '; +// var_dump($this->_textObjects[$this->textObjRef]); +// echo '
            '; + } + + + /** + * Read BOF + */ + private function _readBof() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = substr($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 2; size: 2; type of the following data + $substreamType = self::_GetInt2d($recordData, 2); + + switch ($substreamType) { + case self::XLS_WorkbookGlobals: + $version = self::_GetInt2d($recordData, 0); + if (($version != self::XLS_BIFF8) && ($version != self::XLS_BIFF7)) { + throw new PHPExcel_Reader_Exception('Cannot read this Excel file. Version is too old.'); + } + $this->_version = $version; + break; + + case self::XLS_Worksheet: + // do not use this version information for anything + // it is unreliable (OpenOffice doc, 5.8), use only version information from the global stream + break; + + default: + // substream, e.g. chart + // just skip the entire substream + do { + $code = self::_GetInt2d($this->_data, $this->_pos); + $this->_readDefault(); + } while ($code != self::XLS_Type_EOF && $this->_pos < $this->_dataSize); + break; + } + } + + + /** + * FILEPASS + * + * This record is part of the File Protection Block. It + * contains information about the read/write password of the + * file. All record contents following this record will be + * encrypted. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + * + * The decryption functions and objects used from here on in + * are based on the source of Spreadsheet-ParseExcel: + * http://search.cpan.org/~jmcnamara/Spreadsheet-ParseExcel/ + */ + private function _readFilepass() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + + if ($length != 54) { + throw new PHPExcel_Reader_Exception('Unexpected file pass record length'); + } + + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_verifyPassword( + 'VelvetSweatshop', + substr($recordData, 6, 16), + substr($recordData, 22, 16), + substr($recordData, 38, 16), + $this->_md5Ctxt + )) { + throw new PHPExcel_Reader_Exception('Decryption password incorrect'); + } + + $this->_encryption = self::MS_BIFF_CRYPTO_RC4; + + // Decryption required from the record after next onwards + $this->_encryptionStartPos = $this->_pos + self::_GetInt2d($this->_data, $this->_pos + 2); + } + + /** + * Make an RC4 decryptor for the given block + * + * @var int $block Block for which to create decrypto + * @var string $valContext MD5 context state + * + * @return PHPExcel_Reader_Excel5_RC4 + */ + private function _makeKey($block, $valContext) + { + $pwarray = str_repeat("\0", 64); + + for ($i = 0; $i < 5; $i++) { + $pwarray[$i] = $valContext[$i]; + } + + $pwarray[5] = chr($block & 0xff); + $pwarray[6] = chr(($block >> 8) & 0xff); + $pwarray[7] = chr(($block >> 16) & 0xff); + $pwarray[8] = chr(($block >> 24) & 0xff); + + $pwarray[9] = "\x80"; + $pwarray[56] = "\x48"; + + $md5 = new PHPExcel_Reader_Excel5_MD5(); + $md5->add($pwarray); + + $s = $md5->getContext(); + return new PHPExcel_Reader_Excel5_RC4($s); + } + + /** + * Verify RC4 file password + * + * @var string $password Password to check + * @var string $docid Document id + * @var string $salt_data Salt data + * @var string $hashedsalt_data Hashed salt data + * @var string &$valContext Set to the MD5 context of the value + * + * @return bool Success + */ + private function _verifyPassword($password, $docid, $salt_data, $hashedsalt_data, &$valContext) + { + $pwarray = str_repeat("\0", 64); + + for ($i = 0; $i < strlen($password); $i++) { + $o = ord(substr($password, $i, 1)); + $pwarray[2 * $i] = chr($o & 0xff); + $pwarray[2 * $i + 1] = chr(($o >> 8) & 0xff); + } + $pwarray[2 * $i] = chr(0x80); + $pwarray[56] = chr(($i << 4) & 0xff); + + $md5 = new PHPExcel_Reader_Excel5_MD5(); + $md5->add($pwarray); + + $mdContext1 = $md5->getContext(); + + $offset = 0; + $keyoffset = 0; + $tocopy = 5; + + $md5->reset(); + + while ($offset != 16) { + if ((64 - $offset) < 5) { + $tocopy = 64 - $offset; + } + + for ($i = 0; $i <= $tocopy; $i++) { + $pwarray[$offset + $i] = $mdContext1[$keyoffset + $i]; + } + + $offset += $tocopy; + + if ($offset == 64) { + $md5->add($pwarray); + $keyoffset = $tocopy; + $tocopy = 5 - $tocopy; + $offset = 0; + continue; + } + + $keyoffset = 0; + $tocopy = 5; + for ($i = 0; $i < 16; $i++) { + $pwarray[$offset + $i] = $docid[$i]; + } + $offset += 16; + } + + $pwarray[16] = "\x80"; + for ($i = 0; $i < 47; $i++) { + $pwarray[17 + $i] = "\0"; + } + $pwarray[56] = "\x80"; + $pwarray[57] = "\x0a"; + + $md5->add($pwarray); + $valContext = $md5->getContext(); + + $key = $this->_makeKey(0, $valContext); + + $salt = $key->RC4($salt_data); + $hashedsalt = $key->RC4($hashedsalt_data); + + $salt .= "\x80" . str_repeat("\0", 47); + $salt[56] = "\x80"; + + $md5->reset(); + $md5->add($salt); + $mdContext2 = $md5->getContext(); + + return $mdContext2 == $hashedsalt; + } + + /** + * CODEPAGE + * + * This record stores the text encoding used to write byte + * strings, stored as MS Windows code page identifier. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readCodepage() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; code page identifier + $codepage = self::_GetInt2d($recordData, 0); + + $this->_codepage = PHPExcel_Shared_CodePage::NumberToName($codepage); + } + + + /** + * DATEMODE + * + * This record specifies the base date for displaying date + * values. All dates are stored as count of days past this + * base date. In BIFF2-BIFF4 this record is part of the + * Calculation Settings Block. In BIFF5-BIFF8 it is + * stored in the Workbook Globals Substream. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readDateMode() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; 0 = base 1900, 1 = base 1904 + PHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_WINDOWS_1900); + if (ord($recordData{0}) == 1) { + PHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_MAC_1904); + } + } + + + /** + * Read a FONT record + */ + private function _readFont() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + $objFont = new PHPExcel_Style_Font(); + + // offset: 0; size: 2; height of the font (in twips = 1/20 of a point) + $size = self::_GetInt2d($recordData, 0); + $objFont->setSize($size / 20); + + // offset: 2; size: 2; option flags + // bit: 0; mask 0x0001; bold (redundant in BIFF5-BIFF8) + // bit: 1; mask 0x0002; italic + $isItalic = (0x0002 & self::_GetInt2d($recordData, 2)) >> 1; + if ($isItalic) $objFont->setItalic(true); + + // bit: 2; mask 0x0004; underlined (redundant in BIFF5-BIFF8) + // bit: 3; mask 0x0008; strike + $isStrike = (0x0008 & self::_GetInt2d($recordData, 2)) >> 3; + if ($isStrike) $objFont->setStrikethrough(true); + + // offset: 4; size: 2; colour index + $colorIndex = self::_GetInt2d($recordData, 4); + $objFont->colorIndex = $colorIndex; + + // offset: 6; size: 2; font weight + $weight = self::_GetInt2d($recordData, 6); + switch ($weight) { + case 0x02BC: + $objFont->setBold(true); + break; + } + + // offset: 8; size: 2; escapement type + $escapement = self::_GetInt2d($recordData, 8); + switch ($escapement) { + case 0x0001: + $objFont->setSuperScript(true); + break; + case 0x0002: + $objFont->setSubScript(true); + break; + } + + // offset: 10; size: 1; underline type + $underlineType = ord($recordData{10}); + switch ($underlineType) { + case 0x00: + break; // no underline + case 0x01: + $objFont->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLE); + break; + case 0x02: + $objFont->setUnderline(PHPExcel_Style_Font::UNDERLINE_DOUBLE); + break; + case 0x21: + $objFont->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLEACCOUNTING); + break; + case 0x22: + $objFont->setUnderline(PHPExcel_Style_Font::UNDERLINE_DOUBLEACCOUNTING); + break; + } + + // offset: 11; size: 1; font family + // offset: 12; size: 1; character set + // offset: 13; size: 1; not used + // offset: 14; size: var; font name + if ($this->_version == self::XLS_BIFF8) { + $string = self::_readUnicodeStringShort(substr($recordData, 14)); + } else { + $string = $this->_readByteStringShort(substr($recordData, 14)); + } + $objFont->setName($string['value']); + + $this->_objFonts[] = $objFont; + } + } + + + /** + * FORMAT + * + * This record contains information about a number format. + * All FORMAT records occur together in a sequential list. + * + * In BIFF2-BIFF4 other records referencing a FORMAT record + * contain a zero-based index into this list. From BIFF5 on + * the FORMAT record contains the index itself that will be + * used by other records. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readFormat() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + $indexCode = self::_GetInt2d($recordData, 0); + + if ($this->_version == self::XLS_BIFF8) { + $string = self::_readUnicodeStringLong(substr($recordData, 2)); + } else { + // BIFF7 + $string = $this->_readByteStringShort(substr($recordData, 2)); + } + + $formatString = $string['value']; + $this->_formats[$indexCode] = $formatString; + } + } + + + /** + * XF - Extended Format + * + * This record contains formatting information for cells, rows, columns or styles. + * According to http://support.microsoft.com/kb/147732 there are always at least 15 cell style XF + * and 1 cell XF. + * Inspection of Excel files generated by MS Office Excel shows that XF records 0-14 are cell style XF + * and XF record 15 is a cell XF + * We only read the first cell style XF and skip the remaining cell style XF records + * We read all cell XF records. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readXf() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + $objStyle = new PHPExcel_Style(); + + if (!$this->_readDataOnly) { + // offset: 0; size: 2; Index to FONT record + if (self::_GetInt2d($recordData, 0) < 4) { + $fontIndex = self::_GetInt2d($recordData, 0); + } else { + // this has to do with that index 4 is omitted in all BIFF versions for some strange reason + // check the OpenOffice documentation of the FONT record + $fontIndex = self::_GetInt2d($recordData, 0) - 1; + } + $objStyle->setFont($this->_objFonts[$fontIndex]); + + // offset: 2; size: 2; Index to FORMAT record + $numberFormatIndex = self::_GetInt2d($recordData, 2); + if (isset($this->_formats[$numberFormatIndex])) { + // then we have user-defined format code + $numberformat = array('code' => $this->_formats[$numberFormatIndex]); + } elseif (($code = PHPExcel_Style_NumberFormat::builtInFormatCode($numberFormatIndex)) !== '') { + // then we have built-in format code + $numberformat = array('code' => $code); + } else { + // we set the general format code + $numberformat = array('code' => 'General'); + } + $objStyle->getNumberFormat()->setFormatCode($numberformat['code']); + + // offset: 4; size: 2; XF type, cell protection, and parent style XF + // bit 2-0; mask 0x0007; XF_TYPE_PROT + $xfTypeProt = self::_GetInt2d($recordData, 4); + // bit 0; mask 0x01; 1 = cell is locked + $isLocked = (0x01 & $xfTypeProt) >> 0; + $objStyle->getProtection()->setLocked($isLocked ? + PHPExcel_Style_Protection::PROTECTION_INHERIT : PHPExcel_Style_Protection::PROTECTION_UNPROTECTED); + + // bit 1; mask 0x02; 1 = Formula is hidden + $isHidden = (0x02 & $xfTypeProt) >> 1; + $objStyle->getProtection()->setHidden($isHidden ? + PHPExcel_Style_Protection::PROTECTION_PROTECTED : PHPExcel_Style_Protection::PROTECTION_UNPROTECTED); + + // bit 2; mask 0x04; 0 = Cell XF, 1 = Cell Style XF + $isCellStyleXf = (0x04 & $xfTypeProt) >> 2; + + // offset: 6; size: 1; Alignment and text break + // bit 2-0, mask 0x07; horizontal alignment + $horAlign = (0x07 & ord($recordData{6})) >> 0; + switch ($horAlign) { + case 0: + $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_GENERAL); + break; + case 1: + $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_LEFT); + break; + case 2: + $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_CENTER); + break; + case 3: + $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT); + break; + case 4: + $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_FILL); + break; + case 5: + $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY); + break; + case 6: + $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS); + break; + } + // bit 3, mask 0x08; wrap text + $wrapText = (0x08 & ord($recordData{6})) >> 3; + switch ($wrapText) { + case 0: + $objStyle->getAlignment()->setWrapText(false); + break; + case 1: + $objStyle->getAlignment()->setWrapText(true); + break; + } + // bit 6-4, mask 0x70; vertical alignment + $vertAlign = (0x70 & ord($recordData{6})) >> 4; + switch ($vertAlign) { + case 0: + $objStyle->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_TOP); + break; + case 1: + $objStyle->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_CENTER); + break; + case 2: + $objStyle->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_BOTTOM); + break; + case 3: + $objStyle->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_JUSTIFY); + break; + } + + if ($this->_version == self::XLS_BIFF8) { + // offset: 7; size: 1; XF_ROTATION: Text rotation angle + $angle = ord($recordData{7}); + $rotation = 0; + if ($angle <= 90) { + $rotation = $angle; + } else if ($angle <= 180) { + $rotation = 90 - $angle; + } else if ($angle == 255) { + $rotation = -165; + } + $objStyle->getAlignment()->setTextRotation($rotation); + + // offset: 8; size: 1; Indentation, shrink to cell size, and text direction + // bit: 3-0; mask: 0x0F; indent level + $indent = (0x0F & ord($recordData{8})) >> 0; + $objStyle->getAlignment()->setIndent($indent); + + // bit: 4; mask: 0x10; 1 = shrink content to fit into cell + $shrinkToFit = (0x10 & ord($recordData{8})) >> 4; + switch ($shrinkToFit) { + case 0: + $objStyle->getAlignment()->setShrinkToFit(false); + break; + case 1: + $objStyle->getAlignment()->setShrinkToFit(true); + break; + } + + // offset: 9; size: 1; Flags used for attribute groups + + // offset: 10; size: 4; Cell border lines and background area + // bit: 3-0; mask: 0x0000000F; left style + if ($bordersLeftStyle = self::_mapBorderStyle((0x0000000F & self::_GetInt4d($recordData, 10)) >> 0)) { + $objStyle->getBorders()->getLeft()->setBorderStyle($bordersLeftStyle); + } + // bit: 7-4; mask: 0x000000F0; right style + if ($bordersRightStyle = self::_mapBorderStyle((0x000000F0 & self::_GetInt4d($recordData, 10)) >> 4)) { + $objStyle->getBorders()->getRight()->setBorderStyle($bordersRightStyle); + } + // bit: 11-8; mask: 0x00000F00; top style + if ($bordersTopStyle = self::_mapBorderStyle((0x00000F00 & self::_GetInt4d($recordData, 10)) >> 8)) { + $objStyle->getBorders()->getTop()->setBorderStyle($bordersTopStyle); + } + // bit: 15-12; mask: 0x0000F000; bottom style + if ($bordersBottomStyle = self::_mapBorderStyle((0x0000F000 & self::_GetInt4d($recordData, 10)) >> 12)) { + $objStyle->getBorders()->getBottom()->setBorderStyle($bordersBottomStyle); + } + // bit: 22-16; mask: 0x007F0000; left color + $objStyle->getBorders()->getLeft()->colorIndex = (0x007F0000 & self::_GetInt4d($recordData, 10)) >> 16; + + // bit: 29-23; mask: 0x3F800000; right color + $objStyle->getBorders()->getRight()->colorIndex = (0x3F800000 & self::_GetInt4d($recordData, 10)) >> 23; + + // bit: 30; mask: 0x40000000; 1 = diagonal line from top left to right bottom + $diagonalDown = (0x40000000 & self::_GetInt4d($recordData, 10)) >> 30 ? + true : false; + + // bit: 31; mask: 0x80000000; 1 = diagonal line from bottom left to top right + $diagonalUp = (0x80000000 & self::_GetInt4d($recordData, 10)) >> 31 ? + true : false; + + if ($diagonalUp == false && $diagonalDown == false) { + $objStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_NONE); + } elseif ($diagonalUp == true && $diagonalDown == false) { + $objStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_UP); + } elseif ($diagonalUp == false && $diagonalDown == true) { + $objStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_DOWN); + } elseif ($diagonalUp == true && $diagonalDown == true) { + $objStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_BOTH); + } + + // offset: 14; size: 4; + // bit: 6-0; mask: 0x0000007F; top color + $objStyle->getBorders()->getTop()->colorIndex = (0x0000007F & self::_GetInt4d($recordData, 14)) >> 0; + + // bit: 13-7; mask: 0x00003F80; bottom color + $objStyle->getBorders()->getBottom()->colorIndex = (0x00003F80 & self::_GetInt4d($recordData, 14)) >> 7; + + // bit: 20-14; mask: 0x001FC000; diagonal color + $objStyle->getBorders()->getDiagonal()->colorIndex = (0x001FC000 & self::_GetInt4d($recordData, 14)) >> 14; + + // bit: 24-21; mask: 0x01E00000; diagonal style + if ($bordersDiagonalStyle = self::_mapBorderStyle((0x01E00000 & self::_GetInt4d($recordData, 14)) >> 21)) { + $objStyle->getBorders()->getDiagonal()->setBorderStyle($bordersDiagonalStyle); + } + + // bit: 31-26; mask: 0xFC000000 fill pattern + if ($fillType = self::_mapFillPattern((0xFC000000 & self::_GetInt4d($recordData, 14)) >> 26)) { + $objStyle->getFill()->setFillType($fillType); + } + // offset: 18; size: 2; pattern and background colour + // bit: 6-0; mask: 0x007F; color index for pattern color + $objStyle->getFill()->startcolorIndex = (0x007F & self::_GetInt2d($recordData, 18)) >> 0; + + // bit: 13-7; mask: 0x3F80; color index for pattern background + $objStyle->getFill()->endcolorIndex = (0x3F80 & self::_GetInt2d($recordData, 18)) >> 7; + } else { + // BIFF5 + + // offset: 7; size: 1; Text orientation and flags + $orientationAndFlags = ord($recordData{7}); + + // bit: 1-0; mask: 0x03; XF_ORIENTATION: Text orientation + $xfOrientation = (0x03 & $orientationAndFlags) >> 0; + switch ($xfOrientation) { + case 0: + $objStyle->getAlignment()->setTextRotation(0); + break; + case 1: + $objStyle->getAlignment()->setTextRotation(-165); + break; + case 2: + $objStyle->getAlignment()->setTextRotation(90); + break; + case 3: + $objStyle->getAlignment()->setTextRotation(-90); + break; + } + + // offset: 8; size: 4; cell border lines and background area + $borderAndBackground = self::_GetInt4d($recordData, 8); + + // bit: 6-0; mask: 0x0000007F; color index for pattern color + $objStyle->getFill()->startcolorIndex = (0x0000007F & $borderAndBackground) >> 0; + + // bit: 13-7; mask: 0x00003F80; color index for pattern background + $objStyle->getFill()->endcolorIndex = (0x00003F80 & $borderAndBackground) >> 7; + + // bit: 21-16; mask: 0x003F0000; fill pattern + $objStyle->getFill()->setFillType(self::_mapFillPattern((0x003F0000 & $borderAndBackground) >> 16)); + + // bit: 24-22; mask: 0x01C00000; bottom line style + $objStyle->getBorders()->getBottom()->setBorderStyle(self::_mapBorderStyle((0x01C00000 & $borderAndBackground) >> 22)); + + // bit: 31-25; mask: 0xFE000000; bottom line color + $objStyle->getBorders()->getBottom()->colorIndex = (0xFE000000 & $borderAndBackground) >> 25; + + // offset: 12; size: 4; cell border lines + $borderLines = self::_GetInt4d($recordData, 12); + + // bit: 2-0; mask: 0x00000007; top line style + $objStyle->getBorders()->getTop()->setBorderStyle(self::_mapBorderStyle((0x00000007 & $borderLines) >> 0)); + + // bit: 5-3; mask: 0x00000038; left line style + $objStyle->getBorders()->getLeft()->setBorderStyle(self::_mapBorderStyle((0x00000038 & $borderLines) >> 3)); + + // bit: 8-6; mask: 0x000001C0; right line style + $objStyle->getBorders()->getRight()->setBorderStyle(self::_mapBorderStyle((0x000001C0 & $borderLines) >> 6)); + + // bit: 15-9; mask: 0x0000FE00; top line color index + $objStyle->getBorders()->getTop()->colorIndex = (0x0000FE00 & $borderLines) >> 9; + + // bit: 22-16; mask: 0x007F0000; left line color index + $objStyle->getBorders()->getLeft()->colorIndex = (0x007F0000 & $borderLines) >> 16; + + // bit: 29-23; mask: 0x3F800000; right line color index + $objStyle->getBorders()->getRight()->colorIndex = (0x3F800000 & $borderLines) >> 23; + } + + // add cellStyleXf or cellXf and update mapping + if ($isCellStyleXf) { + // we only read one style XF record which is always the first + if ($this->_xfIndex == 0) { + $this->_phpExcel->addCellStyleXf($objStyle); + $this->_mapCellStyleXfIndex[$this->_xfIndex] = 0; + } + } else { + // we read all cell XF records + $this->_phpExcel->addCellXf($objStyle); + $this->_mapCellXfIndex[$this->_xfIndex] = count($this->_phpExcel->getCellXfCollection()) - 1; + } + + // update XF index for when we read next record + ++$this->_xfIndex; + } + } + + + /** + * + */ + private function _readXfExt() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 2; 0x087D = repeated header + + // offset: 2; size: 2 + + // offset: 4; size: 8; not used + + // offset: 12; size: 2; record version + + // offset: 14; size: 2; index to XF record which this record modifies + $ixfe = self::_GetInt2d($recordData, 14); + + // offset: 16; size: 2; not used + + // offset: 18; size: 2; number of extension properties that follow + $cexts = self::_GetInt2d($recordData, 18); + + // start reading the actual extension data + $offset = 20; + while ($offset < $length) { + // extension type + $extType = self::_GetInt2d($recordData, $offset); + + // extension length + $cb = self::_GetInt2d($recordData, $offset + 2); + + // extension data + $extData = substr($recordData, $offset + 4, $cb); + + switch ($extType) { + case 4: // fill start color + $xclfType = self::_GetInt2d($extData, 0); // color type + $xclrValue = substr($extData, 4, 4); // color value (value based on color type) + + if ($xclfType == 2) { + $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); + + // modify the relevant style property + if ( isset($this->_mapCellXfIndex[$ixfe]) ) { + $fill = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getFill(); + $fill->getStartColor()->setRGB($rgb); + unset($fill->startcolorIndex); // normal color index does not apply, discard + } + } + break; + + case 5: // fill end color + $xclfType = self::_GetInt2d($extData, 0); // color type + $xclrValue = substr($extData, 4, 4); // color value (value based on color type) + + if ($xclfType == 2) { + $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); + + // modify the relevant style property + if ( isset($this->_mapCellXfIndex[$ixfe]) ) { + $fill = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getFill(); + $fill->getEndColor()->setRGB($rgb); + unset($fill->endcolorIndex); // normal color index does not apply, discard + } + } + break; + + case 7: // border color top + $xclfType = self::_GetInt2d($extData, 0); // color type + $xclrValue = substr($extData, 4, 4); // color value (value based on color type) + + if ($xclfType == 2) { + $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); + + // modify the relevant style property + if ( isset($this->_mapCellXfIndex[$ixfe]) ) { + $top = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getTop(); + $top->getColor()->setRGB($rgb); + unset($top->colorIndex); // normal color index does not apply, discard + } + } + break; + + case 8: // border color bottom + $xclfType = self::_GetInt2d($extData, 0); // color type + $xclrValue = substr($extData, 4, 4); // color value (value based on color type) + + if ($xclfType == 2) { + $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); + + // modify the relevant style property + if ( isset($this->_mapCellXfIndex[$ixfe]) ) { + $bottom = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getBottom(); + $bottom->getColor()->setRGB($rgb); + unset($bottom->colorIndex); // normal color index does not apply, discard + } + } + break; + + case 9: // border color left + $xclfType = self::_GetInt2d($extData, 0); // color type + $xclrValue = substr($extData, 4, 4); // color value (value based on color type) + + if ($xclfType == 2) { + $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); + + // modify the relevant style property + if ( isset($this->_mapCellXfIndex[$ixfe]) ) { + $left = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getLeft(); + $left->getColor()->setRGB($rgb); + unset($left->colorIndex); // normal color index does not apply, discard + } + } + break; + + case 10: // border color right + $xclfType = self::_GetInt2d($extData, 0); // color type + $xclrValue = substr($extData, 4, 4); // color value (value based on color type) + + if ($xclfType == 2) { + $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); + + // modify the relevant style property + if ( isset($this->_mapCellXfIndex[$ixfe]) ) { + $right = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getRight(); + $right->getColor()->setRGB($rgb); + unset($right->colorIndex); // normal color index does not apply, discard + } + } + break; + + case 11: // border color diagonal + $xclfType = self::_GetInt2d($extData, 0); // color type + $xclrValue = substr($extData, 4, 4); // color value (value based on color type) + + if ($xclfType == 2) { + $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); + + // modify the relevant style property + if ( isset($this->_mapCellXfIndex[$ixfe]) ) { + $diagonal = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getDiagonal(); + $diagonal->getColor()->setRGB($rgb); + unset($diagonal->colorIndex); // normal color index does not apply, discard + } + } + break; + + case 13: // font color + $xclfType = self::_GetInt2d($extData, 0); // color type + $xclrValue = substr($extData, 4, 4); // color value (value based on color type) + + if ($xclfType == 2) { + $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); + + // modify the relevant style property + if ( isset($this->_mapCellXfIndex[$ixfe]) ) { + $font = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getFont(); + $font->getColor()->setRGB($rgb); + unset($font->colorIndex); // normal color index does not apply, discard + } + } + break; + } + + $offset += $cb; + } + } + + } + + + /** + * Read STYLE record + */ + private function _readStyle() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 2; index to XF record and flag for built-in style + $ixfe = self::_GetInt2d($recordData, 0); + + // bit: 11-0; mask 0x0FFF; index to XF record + $xfIndex = (0x0FFF & $ixfe) >> 0; + + // bit: 15; mask 0x8000; 0 = user-defined style, 1 = built-in style + $isBuiltIn = (bool) ((0x8000 & $ixfe) >> 15); + + if ($isBuiltIn) { + // offset: 2; size: 1; identifier for built-in style + $builtInId = ord($recordData{2}); + + switch ($builtInId) { + case 0x00: + // currently, we are not using this for anything + break; + + default: + break; + } + + } else { + // user-defined; not supported by PHPExcel + } + } + } + + + /** + * Read PALETTE record + */ + private function _readPalette() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 2; number of following colors + $nm = self::_GetInt2d($recordData, 0); + + // list of RGB colors + for ($i = 0; $i < $nm; ++$i) { + $rgb = substr($recordData, 2 + 4 * $i, 4); + $this->_palette[] = self::_readRGB($rgb); + } + } + } + + + /** + * SHEET + * + * This record is located in the Workbook Globals + * Substream and represents a sheet inside the workbook. + * One SHEET record is written for each sheet. It stores the + * sheet name and a stream offset to the BOF record of the + * respective Sheet Substream within the Workbook Stream. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readSheet() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // offset: 0; size: 4; absolute stream position of the BOF record of the sheet + // NOTE: not encrypted + $rec_offset = self::_GetInt4d($this->_data, $this->_pos + 4); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 4; size: 1; sheet state + switch (ord($recordData{4})) { + case 0x00: $sheetState = PHPExcel_Worksheet::SHEETSTATE_VISIBLE; break; + case 0x01: $sheetState = PHPExcel_Worksheet::SHEETSTATE_HIDDEN; break; + case 0x02: $sheetState = PHPExcel_Worksheet::SHEETSTATE_VERYHIDDEN; break; + default: $sheetState = PHPExcel_Worksheet::SHEETSTATE_VISIBLE; break; + } + + // offset: 5; size: 1; sheet type + $sheetType = ord($recordData{5}); + + // offset: 6; size: var; sheet name + if ($this->_version == self::XLS_BIFF8) { + $string = self::_readUnicodeStringShort(substr($recordData, 6)); + $rec_name = $string['value']; + } elseif ($this->_version == self::XLS_BIFF7) { + $string = $this->_readByteStringShort(substr($recordData, 6)); + $rec_name = $string['value']; + } + + $this->_sheets[] = array( + 'name' => $rec_name, + 'offset' => $rec_offset, + 'sheetState' => $sheetState, + 'sheetType' => $sheetType, + ); + } + + + /** + * Read EXTERNALBOOK record + */ + private function _readExternalBook() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset within record data + $offset = 0; + + // there are 4 types of records + if (strlen($recordData) > 4) { + // external reference + // offset: 0; size: 2; number of sheet names ($nm) + $nm = self::_GetInt2d($recordData, 0); + $offset += 2; + + // offset: 2; size: var; encoded URL without sheet name (Unicode string, 16-bit length) + $encodedUrlString = self::_readUnicodeStringLong(substr($recordData, 2)); + $offset += $encodedUrlString['size']; + + // offset: var; size: var; list of $nm sheet names (Unicode strings, 16-bit length) + $externalSheetNames = array(); + for ($i = 0; $i < $nm; ++$i) { + $externalSheetNameString = self::_readUnicodeStringLong(substr($recordData, $offset)); + $externalSheetNames[] = $externalSheetNameString['value']; + $offset += $externalSheetNameString['size']; + } + + // store the record data + $this->_externalBooks[] = array( + 'type' => 'external', + 'encodedUrl' => $encodedUrlString['value'], + 'externalSheetNames' => $externalSheetNames, + ); + + } elseif (substr($recordData, 2, 2) == pack('CC', 0x01, 0x04)) { + // internal reference + // offset: 0; size: 2; number of sheet in this document + // offset: 2; size: 2; 0x01 0x04 + $this->_externalBooks[] = array( + 'type' => 'internal', + ); + } elseif (substr($recordData, 0, 4) == pack('vCC', 0x0001, 0x01, 0x3A)) { + // add-in function + // offset: 0; size: 2; 0x0001 + $this->_externalBooks[] = array( + 'type' => 'addInFunction', + ); + } elseif (substr($recordData, 0, 2) == pack('v', 0x0000)) { + // DDE links, OLE links + // offset: 0; size: 2; 0x0000 + // offset: 2; size: var; encoded source document name + $this->_externalBooks[] = array( + 'type' => 'DDEorOLE', + ); + } + } + + + /** + * Read EXTERNNAME record. + */ + private function _readExternName() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // external sheet references provided for named cells + if ($this->_version == self::XLS_BIFF8) { + // offset: 0; size: 2; options + $options = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; + + // offset: 4; size: 2; not used + + // offset: 6; size: var + $nameString = self::_readUnicodeStringShort(substr($recordData, 6)); + + // offset: var; size: var; formula data + $offset = 6 + $nameString['size']; + $formula = $this->_getFormulaFromStructure(substr($recordData, $offset)); + + $this->_externalNames[] = array( + 'name' => $nameString['value'], + 'formula' => $formula, + ); + } + } + + + /** + * Read EXTERNSHEET record + */ + private function _readExternSheet() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // external sheet references provided for named cells + if ($this->_version == self::XLS_BIFF8) { + // offset: 0; size: 2; number of following ref structures + $nm = self::_GetInt2d($recordData, 0); + for ($i = 0; $i < $nm; ++$i) { + $this->_ref[] = array( + // offset: 2 + 6 * $i; index to EXTERNALBOOK record + 'externalBookIndex' => self::_GetInt2d($recordData, 2 + 6 * $i), + // offset: 4 + 6 * $i; index to first sheet in EXTERNALBOOK record + 'firstSheetIndex' => self::_GetInt2d($recordData, 4 + 6 * $i), + // offset: 6 + 6 * $i; index to last sheet in EXTERNALBOOK record + 'lastSheetIndex' => self::_GetInt2d($recordData, 6 + 6 * $i), + ); + } + } + } + + + /** + * DEFINEDNAME + * + * This record is part of a Link Table. It contains the name + * and the token array of an internal defined name. Token + * arrays of defined names contain tokens with aberrant + * token classes. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readDefinedName() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_version == self::XLS_BIFF8) { + // retrieves named cells + + // offset: 0; size: 2; option flags + $opts = self::_GetInt2d($recordData, 0); + + // bit: 5; mask: 0x0020; 0 = user-defined name, 1 = built-in-name + $isBuiltInName = (0x0020 & $opts) >> 5; + + // offset: 2; size: 1; keyboard shortcut + + // offset: 3; size: 1; length of the name (character count) + $nlen = ord($recordData{3}); + + // offset: 4; size: 2; size of the formula data (it can happen that this is zero) + // note: there can also be additional data, this is not included in $flen + $flen = self::_GetInt2d($recordData, 4); + + // offset: 8; size: 2; 0=Global name, otherwise index to sheet (1-based) + $scope = self::_GetInt2d($recordData, 8); + + // offset: 14; size: var; Name (Unicode string without length field) + $string = self::_readUnicodeString(substr($recordData, 14), $nlen); + + // offset: var; size: $flen; formula data + $offset = 14 + $string['size']; + $formulaStructure = pack('v', $flen) . substr($recordData, $offset); + + try { + $formula = $this->_getFormulaFromStructure($formulaStructure); + } catch (PHPExcel_Exception $e) { + $formula = ''; + } + + $this->_definedname[] = array( + 'isBuiltInName' => $isBuiltInName, + 'name' => $string['value'], + 'formula' => $formula, + 'scope' => $scope, + ); + } + } + + + /** + * Read MSODRAWINGGROUP record + */ + private function _readMsoDrawingGroup() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + + // get spliced record data + $splicedRecordData = $this->_getSplicedRecordData(); + $recordData = $splicedRecordData['recordData']; + + $this->_drawingGroupData .= $recordData; + } + + + /** + * SST - Shared String Table + * + * This record contains a list of all strings used anywhere + * in the workbook. Each string occurs only once. The + * workbook uses indexes into the list to reference the + * strings. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + **/ + private function _readSst() + { + // offset within (spliced) record data + $pos = 0; + + // get spliced record data + $splicedRecordData = $this->_getSplicedRecordData(); + + $recordData = $splicedRecordData['recordData']; + $spliceOffsets = $splicedRecordData['spliceOffsets']; + + // offset: 0; size: 4; total number of strings in the workbook + $pos += 4; + + // offset: 4; size: 4; number of following strings ($nm) + $nm = self::_GetInt4d($recordData, 4); + $pos += 4; + + // loop through the Unicode strings (16-bit length) + for ($i = 0; $i < $nm; ++$i) { + + // number of characters in the Unicode string + $numChars = self::_GetInt2d($recordData, $pos); + $pos += 2; + + // option flags + $optionFlags = ord($recordData{$pos}); + ++$pos; + + // bit: 0; mask: 0x01; 0 = compressed; 1 = uncompressed + $isCompressed = (($optionFlags & 0x01) == 0) ; + + // bit: 2; mask: 0x02; 0 = ordinary; 1 = Asian phonetic + $hasAsian = (($optionFlags & 0x04) != 0); + + // bit: 3; mask: 0x03; 0 = ordinary; 1 = Rich-Text + $hasRichText = (($optionFlags & 0x08) != 0); + + if ($hasRichText) { + // number of Rich-Text formatting runs + $formattingRuns = self::_GetInt2d($recordData, $pos); + $pos += 2; + } + + if ($hasAsian) { + // size of Asian phonetic setting + $extendedRunLength = self::_GetInt4d($recordData, $pos); + $pos += 4; + } + + // expected byte length of character array if not split + $len = ($isCompressed) ? $numChars : $numChars * 2; + + // look up limit position + foreach ($spliceOffsets as $spliceOffset) { + // it can happen that the string is empty, therefore we need + // <= and not just < + if ($pos <= $spliceOffset) { + $limitpos = $spliceOffset; + break; + } + } + + if ($pos + $len <= $limitpos) { + // character array is not split between records + + $retstr = substr($recordData, $pos, $len); + $pos += $len; + + } else { + // character array is split between records + + // first part of character array + $retstr = substr($recordData, $pos, $limitpos - $pos); + + $bytesRead = $limitpos - $pos; + + // remaining characters in Unicode string + $charsLeft = $numChars - (($isCompressed) ? $bytesRead : ($bytesRead / 2)); + + $pos = $limitpos; + + // keep reading the characters + while ($charsLeft > 0) { + + // look up next limit position, in case the string span more than one continue record + foreach ($spliceOffsets as $spliceOffset) { + if ($pos < $spliceOffset) { + $limitpos = $spliceOffset; + break; + } + } + + // repeated option flags + // OpenOffice.org documentation 5.21 + $option = ord($recordData{$pos}); + ++$pos; + + if ($isCompressed && ($option == 0)) { + // 1st fragment compressed + // this fragment compressed + $len = min($charsLeft, $limitpos - $pos); + $retstr .= substr($recordData, $pos, $len); + $charsLeft -= $len; + $isCompressed = true; + + } elseif (!$isCompressed && ($option != 0)) { + // 1st fragment uncompressed + // this fragment uncompressed + $len = min($charsLeft * 2, $limitpos - $pos); + $retstr .= substr($recordData, $pos, $len); + $charsLeft -= $len / 2; + $isCompressed = false; + + } elseif (!$isCompressed && ($option == 0)) { + // 1st fragment uncompressed + // this fragment compressed + $len = min($charsLeft, $limitpos - $pos); + for ($j = 0; $j < $len; ++$j) { + $retstr .= $recordData{$pos + $j} . chr(0); + } + $charsLeft -= $len; + $isCompressed = false; + + } else { + // 1st fragment compressed + // this fragment uncompressed + $newstr = ''; + for ($j = 0; $j < strlen($retstr); ++$j) { + $newstr .= $retstr[$j] . chr(0); + } + $retstr = $newstr; + $len = min($charsLeft * 2, $limitpos - $pos); + $retstr .= substr($recordData, $pos, $len); + $charsLeft -= $len / 2; + $isCompressed = false; + } + + $pos += $len; + } + } + + // convert to UTF-8 + $retstr = self::_encodeUTF16($retstr, $isCompressed); + + // read additional Rich-Text information, if any + $fmtRuns = array(); + if ($hasRichText) { + // list of formatting runs + for ($j = 0; $j < $formattingRuns; ++$j) { + // first formatted character; zero-based + $charPos = self::_GetInt2d($recordData, $pos + $j * 4); + + // index to font record + $fontIndex = self::_GetInt2d($recordData, $pos + 2 + $j * 4); + + $fmtRuns[] = array( + 'charPos' => $charPos, + 'fontIndex' => $fontIndex, + ); + } + $pos += 4 * $formattingRuns; + } + + // read additional Asian phonetics information, if any + if ($hasAsian) { + // For Asian phonetic settings, we skip the extended string data + $pos += $extendedRunLength; + } + + // store the shared sting + $this->_sst[] = array( + 'value' => $retstr, + 'fmtRuns' => $fmtRuns, + ); + } + + // _getSplicedRecordData() takes care of moving current position in data stream + } + + + /** + * Read PRINTGRIDLINES record + */ + private function _readPrintGridlines() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_version == self::XLS_BIFF8 && !$this->_readDataOnly) { + // offset: 0; size: 2; 0 = do not print sheet grid lines; 1 = print sheet gridlines + $printGridlines = (bool) self::_GetInt2d($recordData, 0); + $this->_phpSheet->setPrintGridlines($printGridlines); + } + } + + + /** + * Read DEFAULTROWHEIGHT record + */ + private function _readDefaultRowHeight() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; option flags + // offset: 2; size: 2; default height for unused rows, (twips 1/20 point) + $height = self::_GetInt2d($recordData, 2); + $this->_phpSheet->getDefaultRowDimension()->setRowHeight($height / 20); + } + + + /** + * Read SHEETPR record + */ + private function _readSheetPr() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2 + + // bit: 6; mask: 0x0040; 0 = outline buttons above outline group + $isSummaryBelow = (0x0040 & self::_GetInt2d($recordData, 0)) >> 6; + $this->_phpSheet->setShowSummaryBelow($isSummaryBelow); + + // bit: 7; mask: 0x0080; 0 = outline buttons left of outline group + $isSummaryRight = (0x0080 & self::_GetInt2d($recordData, 0)) >> 7; + $this->_phpSheet->setShowSummaryRight($isSummaryRight); + + // bit: 8; mask: 0x100; 0 = scale printout in percent, 1 = fit printout to number of pages + // this corresponds to radio button setting in page setup dialog in Excel + $this->_isFitToPages = (bool) ((0x0100 & self::_GetInt2d($recordData, 0)) >> 8); + } + + + /** + * Read HORIZONTALPAGEBREAKS record + */ + private function _readHorizontalPageBreaks() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_version == self::XLS_BIFF8 && !$this->_readDataOnly) { + + // offset: 0; size: 2; number of the following row index structures + $nm = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 6 * $nm; list of $nm row index structures + for ($i = 0; $i < $nm; ++$i) { + $r = self::_GetInt2d($recordData, 2 + 6 * $i); + $cf = self::_GetInt2d($recordData, 2 + 6 * $i + 2); + $cl = self::_GetInt2d($recordData, 2 + 6 * $i + 4); + + // not sure why two column indexes are necessary? + $this->_phpSheet->setBreakByColumnAndRow($cf, $r, PHPExcel_Worksheet::BREAK_ROW); + } + } + } + + + /** + * Read VERTICALPAGEBREAKS record + */ + private function _readVerticalPageBreaks() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_version == self::XLS_BIFF8 && !$this->_readDataOnly) { + // offset: 0; size: 2; number of the following column index structures + $nm = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 6 * $nm; list of $nm row index structures + for ($i = 0; $i < $nm; ++$i) { + $c = self::_GetInt2d($recordData, 2 + 6 * $i); + $rf = self::_GetInt2d($recordData, 2 + 6 * $i + 2); + $rl = self::_GetInt2d($recordData, 2 + 6 * $i + 4); + + // not sure why two row indexes are necessary? + $this->_phpSheet->setBreakByColumnAndRow($c, $rf, PHPExcel_Worksheet::BREAK_COLUMN); + } + } + } + + + /** + * Read HEADER record + */ + private function _readHeader() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: var + // realized that $recordData can be empty even when record exists + if ($recordData) { + if ($this->_version == self::XLS_BIFF8) { + $string = self::_readUnicodeStringLong($recordData); + } else { + $string = $this->_readByteStringShort($recordData); + } + + $this->_phpSheet->getHeaderFooter()->setOddHeader($string['value']); + $this->_phpSheet->getHeaderFooter()->setEvenHeader($string['value']); + } + } + } + + + /** + * Read FOOTER record + */ + private function _readFooter() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: var + // realized that $recordData can be empty even when record exists + if ($recordData) { + if ($this->_version == self::XLS_BIFF8) { + $string = self::_readUnicodeStringLong($recordData); + } else { + $string = $this->_readByteStringShort($recordData); + } + $this->_phpSheet->getHeaderFooter()->setOddFooter($string['value']); + $this->_phpSheet->getHeaderFooter()->setEvenFooter($string['value']); + } + } + } + + + /** + * Read HCENTER record + */ + private function _readHcenter() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 2; 0 = print sheet left aligned, 1 = print sheet centered horizontally + $isHorizontalCentered = (bool) self::_GetInt2d($recordData, 0); + + $this->_phpSheet->getPageSetup()->setHorizontalCentered($isHorizontalCentered); + } + } + + + /** + * Read VCENTER record + */ + private function _readVcenter() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 2; 0 = print sheet aligned at top page border, 1 = print sheet vertically centered + $isVerticalCentered = (bool) self::_GetInt2d($recordData, 0); + + $this->_phpSheet->getPageSetup()->setVerticalCentered($isVerticalCentered); + } + } + + + /** + * Read LEFTMARGIN record + */ + private function _readLeftMargin() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 8 + $this->_phpSheet->getPageMargins()->setLeft(self::_extractNumber($recordData)); + } + } + + + /** + * Read RIGHTMARGIN record + */ + private function _readRightMargin() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 8 + $this->_phpSheet->getPageMargins()->setRight(self::_extractNumber($recordData)); + } + } + + + /** + * Read TOPMARGIN record + */ + private function _readTopMargin() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 8 + $this->_phpSheet->getPageMargins()->setTop(self::_extractNumber($recordData)); + } + } + + + /** + * Read BOTTOMMARGIN record + */ + private function _readBottomMargin() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 8 + $this->_phpSheet->getPageMargins()->setBottom(self::_extractNumber($recordData)); + } + } + + + /** + * Read PAGESETUP record + */ + private function _readPageSetup() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 2; paper size + $paperSize = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; scaling factor + $scale = self::_GetInt2d($recordData, 2); + + // offset: 6; size: 2; fit worksheet width to this number of pages, 0 = use as many as needed + $fitToWidth = self::_GetInt2d($recordData, 6); + + // offset: 8; size: 2; fit worksheet height to this number of pages, 0 = use as many as needed + $fitToHeight = self::_GetInt2d($recordData, 8); + + // offset: 10; size: 2; option flags + + // bit: 1; mask: 0x0002; 0=landscape, 1=portrait + $isPortrait = (0x0002 & self::_GetInt2d($recordData, 10)) >> 1; + + // bit: 2; mask: 0x0004; 1= paper size, scaling factor, paper orient. not init + // when this bit is set, do not use flags for those properties + $isNotInit = (0x0004 & self::_GetInt2d($recordData, 10)) >> 2; + + if (!$isNotInit) { + $this->_phpSheet->getPageSetup()->setPaperSize($paperSize); + switch ($isPortrait) { + case 0: $this->_phpSheet->getPageSetup()->setOrientation(PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE); break; + case 1: $this->_phpSheet->getPageSetup()->setOrientation(PHPExcel_Worksheet_PageSetup::ORIENTATION_PORTRAIT); break; + } + + $this->_phpSheet->getPageSetup()->setScale($scale, false); + $this->_phpSheet->getPageSetup()->setFitToPage((bool) $this->_isFitToPages); + $this->_phpSheet->getPageSetup()->setFitToWidth($fitToWidth, false); + $this->_phpSheet->getPageSetup()->setFitToHeight($fitToHeight, false); + } + + // offset: 16; size: 8; header margin (IEEE 754 floating-point value) + $marginHeader = self::_extractNumber(substr($recordData, 16, 8)); + $this->_phpSheet->getPageMargins()->setHeader($marginHeader); + + // offset: 24; size: 8; footer margin (IEEE 754 floating-point value) + $marginFooter = self::_extractNumber(substr($recordData, 24, 8)); + $this->_phpSheet->getPageMargins()->setFooter($marginFooter); + } + } + + + /** + * PROTECT - Sheet protection (BIFF2 through BIFF8) + * if this record is omitted, then it also means no sheet protection + */ + private function _readProtect() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_readDataOnly) { + return; + } + + // offset: 0; size: 2; + + // bit 0, mask 0x01; 1 = sheet is protected + $bool = (0x01 & self::_GetInt2d($recordData, 0)) >> 0; + $this->_phpSheet->getProtection()->setSheet((bool)$bool); + } + + + /** + * SCENPROTECT + */ + private function _readScenProtect() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_readDataOnly) { + return; + } + + // offset: 0; size: 2; + + // bit: 0, mask 0x01; 1 = scenarios are protected + $bool = (0x01 & self::_GetInt2d($recordData, 0)) >> 0; + + $this->_phpSheet->getProtection()->setScenarios((bool)$bool); + } + + + /** + * OBJECTPROTECT + */ + private function _readObjectProtect() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_readDataOnly) { + return; + } + + // offset: 0; size: 2; + + // bit: 0, mask 0x01; 1 = objects are protected + $bool = (0x01 & self::_GetInt2d($recordData, 0)) >> 0; + + $this->_phpSheet->getProtection()->setObjects((bool)$bool); + } + + + /** + * PASSWORD - Sheet protection (hashed) password (BIFF2 through BIFF8) + */ + private function _readPassword() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 2; 16-bit hash value of password + $password = strtoupper(dechex(self::_GetInt2d($recordData, 0))); // the hashed password + $this->_phpSheet->getProtection()->setPassword($password, true); + } + } + + + /** + * Read DEFCOLWIDTH record + */ + private function _readDefColWidth() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; default column width + $width = self::_GetInt2d($recordData, 0); + if ($width != 8) { + $this->_phpSheet->getDefaultColumnDimension()->setWidth($width); + } + } + + + /** + * Read COLINFO record + */ + private function _readColInfo() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 2; index to first column in range + $fc = self::_GetInt2d($recordData, 0); // first column index + + // offset: 2; size: 2; index to last column in range + $lc = self::_GetInt2d($recordData, 2); // first column index + + // offset: 4; size: 2; width of the column in 1/256 of the width of the zero character + $width = self::_GetInt2d($recordData, 4); + + // offset: 6; size: 2; index to XF record for default column formatting + $xfIndex = self::_GetInt2d($recordData, 6); + + // offset: 8; size: 2; option flags + + // bit: 0; mask: 0x0001; 1= columns are hidden + $isHidden = (0x0001 & self::_GetInt2d($recordData, 8)) >> 0; + + // bit: 10-8; mask: 0x0700; outline level of the columns (0 = no outline) + $level = (0x0700 & self::_GetInt2d($recordData, 8)) >> 8; + + // bit: 12; mask: 0x1000; 1 = collapsed + $isCollapsed = (0x1000 & self::_GetInt2d($recordData, 8)) >> 12; + + // offset: 10; size: 2; not used + + for ($i = $fc; $i <= $lc; ++$i) { + if ($lc == 255 || $lc == 256) { + $this->_phpSheet->getDefaultColumnDimension()->setWidth($width / 256); + break; + } + $this->_phpSheet->getColumnDimensionByColumn($i)->setWidth($width / 256); + $this->_phpSheet->getColumnDimensionByColumn($i)->setVisible(!$isHidden); + $this->_phpSheet->getColumnDimensionByColumn($i)->setOutlineLevel($level); + $this->_phpSheet->getColumnDimensionByColumn($i)->setCollapsed($isCollapsed); + $this->_phpSheet->getColumnDimensionByColumn($i)->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + } + } + } + + + /** + * ROW + * + * This record contains the properties of a single row in a + * sheet. Rows and cells in a sheet are divided into blocks + * of 32 rows. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readRow() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 2; index of this row + $r = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; index to column of the first cell which is described by a cell record + + // offset: 4; size: 2; index to column of the last cell which is described by a cell record, increased by 1 + + // offset: 6; size: 2; + + // bit: 14-0; mask: 0x7FFF; height of the row, in twips = 1/20 of a point + $height = (0x7FFF & self::_GetInt2d($recordData, 6)) >> 0; + + // bit: 15: mask: 0x8000; 0 = row has custom height; 1= row has default height + $useDefaultHeight = (0x8000 & self::_GetInt2d($recordData, 6)) >> 15; + + if (!$useDefaultHeight) { + $this->_phpSheet->getRowDimension($r + 1)->setRowHeight($height / 20); + } + + // offset: 8; size: 2; not used + + // offset: 10; size: 2; not used in BIFF5-BIFF8 + + // offset: 12; size: 4; option flags and default row formatting + + // bit: 2-0: mask: 0x00000007; outline level of the row + $level = (0x00000007 & self::_GetInt4d($recordData, 12)) >> 0; + $this->_phpSheet->getRowDimension($r + 1)->setOutlineLevel($level); + + // bit: 4; mask: 0x00000010; 1 = outline group start or ends here... and is collapsed + $isCollapsed = (0x00000010 & self::_GetInt4d($recordData, 12)) >> 4; + $this->_phpSheet->getRowDimension($r + 1)->setCollapsed($isCollapsed); + + // bit: 5; mask: 0x00000020; 1 = row is hidden + $isHidden = (0x00000020 & self::_GetInt4d($recordData, 12)) >> 5; + $this->_phpSheet->getRowDimension($r + 1)->setVisible(!$isHidden); + + // bit: 7; mask: 0x00000080; 1 = row has explicit format + $hasExplicitFormat = (0x00000080 & self::_GetInt4d($recordData, 12)) >> 7; + + // bit: 27-16; mask: 0x0FFF0000; only applies when hasExplicitFormat = 1; index to XF record + $xfIndex = (0x0FFF0000 & self::_GetInt4d($recordData, 12)) >> 16; + + if ($hasExplicitFormat) { + $this->_phpSheet->getRowDimension($r + 1)->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + } + } + } + + + /** + * Read RK record + * This record represents a cell that contains an RK value + * (encoded integer or floating-point value). If a + * floating-point value cannot be encoded to an RK value, + * a NUMBER record will be written. This record replaces the + * record INTEGER written in BIFF2. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readRk() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; index to row + $row = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; index to column + $column = self::_GetInt2d($recordData, 2); + $columnString = PHPExcel_Cell::stringFromColumnIndex($column); + + // Read cell? + if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) { + // offset: 4; size: 2; index to XF record + $xfIndex = self::_GetInt2d($recordData, 4); + + // offset: 6; size: 4; RK value + $rknum = self::_GetInt4d($recordData, 6); + $numValue = self::_GetIEEE754($rknum); + + $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); + if (!$this->_readDataOnly) { + // add style information + $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + } + + // add cell + $cell->setValueExplicit($numValue, PHPExcel_Cell_DataType::TYPE_NUMERIC); + } + } + + + /** + * Read LABELSST record + * This record represents a cell that contains a string. It + * replaces the LABEL record and RSTRING record used in + * BIFF2-BIFF5. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readLabelSst() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; index to row + $row = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; index to column + $column = self::_GetInt2d($recordData, 2); + $columnString = PHPExcel_Cell::stringFromColumnIndex($column); + + // Read cell? + if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) { + // offset: 4; size: 2; index to XF record + $xfIndex = self::_GetInt2d($recordData, 4); + + // offset: 6; size: 4; index to SST record + $index = self::_GetInt4d($recordData, 6); + + // add cell + if (($fmtRuns = $this->_sst[$index]['fmtRuns']) && !$this->_readDataOnly) { + // then we should treat as rich text + $richText = new PHPExcel_RichText(); + $charPos = 0; + $sstCount = count($this->_sst[$index]['fmtRuns']); + for ($i = 0; $i <= $sstCount; ++$i) { + if (isset($fmtRuns[$i])) { + $text = PHPExcel_Shared_String::Substring($this->_sst[$index]['value'], $charPos, $fmtRuns[$i]['charPos'] - $charPos); + $charPos = $fmtRuns[$i]['charPos']; + } else { + $text = PHPExcel_Shared_String::Substring($this->_sst[$index]['value'], $charPos, PHPExcel_Shared_String::CountCharacters($this->_sst[$index]['value'])); + } + + if (PHPExcel_Shared_String::CountCharacters($text) > 0) { + if ($i == 0) { // first text run, no style + $richText->createText($text); + } else { + $textRun = $richText->createTextRun($text); + if (isset($fmtRuns[$i - 1])) { + if ($fmtRuns[$i - 1]['fontIndex'] < 4) { + $fontIndex = $fmtRuns[$i - 1]['fontIndex']; + } else { + // this has to do with that index 4 is omitted in all BIFF versions for some strange reason + // check the OpenOffice documentation of the FONT record + $fontIndex = $fmtRuns[$i - 1]['fontIndex'] - 1; + } + $textRun->setFont(clone $this->_objFonts[$fontIndex]); + } + } + } + } + $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); + $cell->setValueExplicit($richText, PHPExcel_Cell_DataType::TYPE_STRING); + } else { + $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); + $cell->setValueExplicit($this->_sst[$index]['value'], PHPExcel_Cell_DataType::TYPE_STRING); + } + + if (!$this->_readDataOnly) { + // add style information + $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + } + } + } + + + /** + * Read MULRK record + * This record represents a cell range containing RK value + * cells. All cells are located in the same row. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readMulRk() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; index to row + $row = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; index to first column + $colFirst = self::_GetInt2d($recordData, 2); + + // offset: var; size: 2; index to last column + $colLast = self::_GetInt2d($recordData, $length - 2); + $columns = $colLast - $colFirst + 1; + + // offset within record data + $offset = 4; + + for ($i = 0; $i < $columns; ++$i) { + $columnString = PHPExcel_Cell::stringFromColumnIndex($colFirst + $i); + + // Read cell? + if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) { + + // offset: var; size: 2; index to XF record + $xfIndex = self::_GetInt2d($recordData, $offset); + + // offset: var; size: 4; RK value + $numValue = self::_GetIEEE754(self::_GetInt4d($recordData, $offset + 2)); + $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); + if (!$this->_readDataOnly) { + // add style + $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + } + + // add cell value + $cell->setValueExplicit($numValue, PHPExcel_Cell_DataType::TYPE_NUMERIC); + } + + $offset += 6; + } + } + + + /** + * Read NUMBER record + * This record represents a cell that contains a + * floating-point value. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readNumber() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; index to row + $row = self::_GetInt2d($recordData, 0); + + // offset: 2; size 2; index to column + $column = self::_GetInt2d($recordData, 2); + $columnString = PHPExcel_Cell::stringFromColumnIndex($column); + + // Read cell? + if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) { + // offset 4; size: 2; index to XF record + $xfIndex = self::_GetInt2d($recordData, 4); + + $numValue = self::_extractNumber(substr($recordData, 6, 8)); + + $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); + if (!$this->_readDataOnly) { + // add cell style + $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + } + + // add cell value + $cell->setValueExplicit($numValue, PHPExcel_Cell_DataType::TYPE_NUMERIC); + } + } + + + /** + * Read FORMULA record + perhaps a following STRING record if formula result is a string + * This record contains the token array and the result of a + * formula cell. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readFormula() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; row index + $row = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; col index + $column = self::_GetInt2d($recordData, 2); + $columnString = PHPExcel_Cell::stringFromColumnIndex($column); + + // offset: 20: size: variable; formula structure + $formulaStructure = substr($recordData, 20); + + // offset: 14: size: 2; option flags, recalculate always, recalculate on open etc. + $options = self::_GetInt2d($recordData, 14); + + // bit: 0; mask: 0x0001; 1 = recalculate always + // bit: 1; mask: 0x0002; 1 = calculate on open + // bit: 2; mask: 0x0008; 1 = part of a shared formula + $isPartOfSharedFormula = (bool) (0x0008 & $options); + + // WARNING: + // We can apparently not rely on $isPartOfSharedFormula. Even when $isPartOfSharedFormula = true + // the formula data may be ordinary formula data, therefore we need to check + // explicitly for the tExp token (0x01) + $isPartOfSharedFormula = $isPartOfSharedFormula && ord($formulaStructure{2}) == 0x01; + + if ($isPartOfSharedFormula) { + // part of shared formula which means there will be a formula with a tExp token and nothing else + // get the base cell, grab tExp token + $baseRow = self::_GetInt2d($formulaStructure, 3); + $baseCol = self::_GetInt2d($formulaStructure, 5); + $this->_baseCell = PHPExcel_Cell::stringFromColumnIndex($baseCol). ($baseRow + 1); + } + + // Read cell? + if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) { + + if ($isPartOfSharedFormula) { + // formula is added to this cell after the sheet has been read + $this->_sharedFormulaParts[$columnString . ($row + 1)] = $this->_baseCell; + } + + // offset: 16: size: 4; not used + + // offset: 4; size: 2; XF index + $xfIndex = self::_GetInt2d($recordData, 4); + + // offset: 6; size: 8; result of the formula + if ( (ord($recordData{6}) == 0) + && (ord($recordData{12}) == 255) + && (ord($recordData{13}) == 255) ) { + + // String formula. Result follows in appended STRING record + $dataType = PHPExcel_Cell_DataType::TYPE_STRING; + + // read possible SHAREDFMLA record + $code = self::_GetInt2d($this->_data, $this->_pos); + if ($code == self::XLS_Type_SHAREDFMLA) { + $this->_readSharedFmla(); + } + + // read STRING record + $value = $this->_readString(); + + } elseif ((ord($recordData{6}) == 1) + && (ord($recordData{12}) == 255) + && (ord($recordData{13}) == 255)) { + + // Boolean formula. Result is in +2; 0=false, 1=true + $dataType = PHPExcel_Cell_DataType::TYPE_BOOL; + $value = (bool) ord($recordData{8}); + + } elseif ((ord($recordData{6}) == 2) + && (ord($recordData{12}) == 255) + && (ord($recordData{13}) == 255)) { + + // Error formula. Error code is in +2 + $dataType = PHPExcel_Cell_DataType::TYPE_ERROR; + $value = self::_mapErrorCode(ord($recordData{8})); + + } elseif ((ord($recordData{6}) == 3) + && (ord($recordData{12}) == 255) + && (ord($recordData{13}) == 255)) { + + // Formula result is a null string + $dataType = PHPExcel_Cell_DataType::TYPE_NULL; + $value = ''; + + } else { + + // forumla result is a number, first 14 bytes like _NUMBER record + $dataType = PHPExcel_Cell_DataType::TYPE_NUMERIC; + $value = self::_extractNumber(substr($recordData, 6, 8)); + + } + + $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); + if (!$this->_readDataOnly) { + // add cell style + $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + } + + // store the formula + if (!$isPartOfSharedFormula) { + // not part of shared formula + // add cell value. If we can read formula, populate with formula, otherwise just used cached value + try { + if ($this->_version != self::XLS_BIFF8) { + throw new PHPExcel_Reader_Exception('Not BIFF8. Can only read BIFF8 formulas'); + } + $formula = $this->_getFormulaFromStructure($formulaStructure); // get formula in human language + $cell->setValueExplicit('=' . $formula, PHPExcel_Cell_DataType::TYPE_FORMULA); + + } catch (PHPExcel_Exception $e) { + $cell->setValueExplicit($value, $dataType); + } + } else { + if ($this->_version == self::XLS_BIFF8) { + // do nothing at this point, formula id added later in the code + } else { + $cell->setValueExplicit($value, $dataType); + } + } + + // store the cached calculated value + $cell->setCalculatedValue($value); + } + } + + + /** + * Read a SHAREDFMLA record. This function just stores the binary shared formula in the reader, + * which usually contains relative references. + * These will be used to construct the formula in each shared formula part after the sheet is read. + */ + private function _readSharedFmla() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0, size: 6; cell range address of the area used by the shared formula, not used for anything + $cellRange = substr($recordData, 0, 6); + $cellRange = $this->_readBIFF5CellRangeAddressFixed($cellRange); // note: even BIFF8 uses BIFF5 syntax + + // offset: 6, size: 1; not used + + // offset: 7, size: 1; number of existing FORMULA records for this shared formula + $no = ord($recordData{7}); + + // offset: 8, size: var; Binary token array of the shared formula + $formula = substr($recordData, 8); + + // at this point we only store the shared formula for later use + $this->_sharedFormulas[$this->_baseCell] = $formula; + + } + + + /** + * Read a STRING record from current stream position and advance the stream pointer to next record + * This record is used for storing result from FORMULA record when it is a string, and + * it occurs directly after the FORMULA record + * + * @return string The string contents as UTF-8 + */ + private function _readString() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_version == self::XLS_BIFF8) { + $string = self::_readUnicodeStringLong($recordData); + $value = $string['value']; + } else { + $string = $this->_readByteStringLong($recordData); + $value = $string['value']; + } + + return $value; + } + + + /** + * Read BOOLERR record + * This record represents a Boolean value or error value + * cell. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readBoolErr() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; row index + $row = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; column index + $column = self::_GetInt2d($recordData, 2); + $columnString = PHPExcel_Cell::stringFromColumnIndex($column); + + // Read cell? + if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) { + // offset: 4; size: 2; index to XF record + $xfIndex = self::_GetInt2d($recordData, 4); + + // offset: 6; size: 1; the boolean value or error value + $boolErr = ord($recordData{6}); + + // offset: 7; size: 1; 0=boolean; 1=error + $isError = ord($recordData{7}); + + $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); + switch ($isError) { + case 0: // boolean + $value = (bool) $boolErr; + + // add cell value + $cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_BOOL); + break; + + case 1: // error type + $value = self::_mapErrorCode($boolErr); + + // add cell value + $cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_ERROR); + break; + } + + if (!$this->_readDataOnly) { + // add cell style + $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + } + } + } + + + /** + * Read MULBLANK record + * This record represents a cell range of empty cells. All + * cells are located in the same row + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readMulBlank() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; index to row + $row = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; index to first column + $fc = self::_GetInt2d($recordData, 2); + + // offset: 4; size: 2 x nc; list of indexes to XF records + // add style information + if (!$this->_readDataOnly) { + for ($i = 0; $i < $length / 2 - 3; ++$i) { + $columnString = PHPExcel_Cell::stringFromColumnIndex($fc + $i); + + // Read cell? + if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) { + $xfIndex = self::_GetInt2d($recordData, 4 + 2 * $i); + $this->_phpSheet->getCell($columnString . ($row + 1))->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + } + } + } + + // offset: 6; size 2; index to last column (not needed) + } + + + /** + * Read LABEL record + * This record represents a cell that contains a string. In + * BIFF8 it is usually replaced by the LABELSST record. + * Excel still uses this record, if it copies unformatted + * text cells to the clipboard. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readLabel() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; index to row + $row = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; index to column + $column = self::_GetInt2d($recordData, 2); + $columnString = PHPExcel_Cell::stringFromColumnIndex($column); + + // Read cell? + if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) { + // offset: 4; size: 2; XF index + $xfIndex = self::_GetInt2d($recordData, 4); + + // add cell value + // todo: what if string is very long? continue record + if ($this->_version == self::XLS_BIFF8) { + $string = self::_readUnicodeStringLong(substr($recordData, 6)); + $value = $string['value']; + } else { + $string = $this->_readByteStringLong(substr($recordData, 6)); + $value = $string['value']; + } + $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); + $cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_STRING); + + if (!$this->_readDataOnly) { + // add cell style + $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + } + } + } + + + /** + * Read BLANK record + */ + private function _readBlank() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; row index + $row = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; col index + $col = self::_GetInt2d($recordData, 2); + $columnString = PHPExcel_Cell::stringFromColumnIndex($col); + + // Read cell? + if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) { + // offset: 4; size: 2; XF index + $xfIndex = self::_GetInt2d($recordData, 4); + + // add style information + if (!$this->_readDataOnly) { + $this->_phpSheet->getCell($columnString . ($row + 1))->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + } + } + + } + + + /** + * Read MSODRAWING record + */ + private function _readMsoDrawing() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + + // get spliced record data + $splicedRecordData = $this->_getSplicedRecordData(); + $recordData = $splicedRecordData['recordData']; + + $this->_drawingData .= $recordData; + } + + + /** + * Read OBJ record + */ + private function _readObj() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_readDataOnly || $this->_version != self::XLS_BIFF8) { + return; + } + + // recordData consists of an array of subrecords looking like this: + // ft: 2 bytes; ftCmo type (0x15) + // cb: 2 bytes; size in bytes of ftCmo data + // ot: 2 bytes; Object Type + // id: 2 bytes; Object id number + // grbit: 2 bytes; Option Flags + // data: var; subrecord data + + // for now, we are just interested in the second subrecord containing the object type + $ftCmoType = self::_GetInt2d($recordData, 0); + $cbCmoSize = self::_GetInt2d($recordData, 2); + $otObjType = self::_GetInt2d($recordData, 4); + $idObjID = self::_GetInt2d($recordData, 6); + $grbitOpts = self::_GetInt2d($recordData, 6); + + $this->_objs[] = array( + 'ftCmoType' => $ftCmoType, + 'cbCmoSize' => $cbCmoSize, + 'otObjType' => $otObjType, + 'idObjID' => $idObjID, + 'grbitOpts' => $grbitOpts + ); + $this->textObjRef = $idObjID; + +// echo '_readObj()
            '; +// var_dump(end($this->_objs)); +// echo '
            '; + } + + + /** + * Read WINDOW2 record + */ + private function _readWindow2() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; option flags + $options = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; index to first visible row + $firstVisibleRow = self::_GetInt2d($recordData, 2); + + // offset: 4; size: 2; index to first visible colum + $firstVisibleColumn = self::_GetInt2d($recordData, 4); + if ($this->_version === self::XLS_BIFF8) { + // offset: 8; size: 2; not used + // offset: 10; size: 2; cached magnification factor in page break preview (in percent); 0 = Default (60%) + // offset: 12; size: 2; cached magnification factor in normal view (in percent); 0 = Default (100%) + // offset: 14; size: 4; not used + $zoomscaleInPageBreakPreview = self::_GetInt2d($recordData, 10); + if ($zoomscaleInPageBreakPreview === 0) $zoomscaleInPageBreakPreview = 60; + $zoomscaleInNormalView = self::_GetInt2d($recordData, 12); + if ($zoomscaleInNormalView === 0) $zoomscaleInNormalView = 100; + } + + // bit: 1; mask: 0x0002; 0 = do not show gridlines, 1 = show gridlines + $showGridlines = (bool) ((0x0002 & $options) >> 1); + $this->_phpSheet->setShowGridlines($showGridlines); + + // bit: 2; mask: 0x0004; 0 = do not show headers, 1 = show headers + $showRowColHeaders = (bool) ((0x0004 & $options) >> 2); + $this->_phpSheet->setShowRowColHeaders($showRowColHeaders); + + // bit: 3; mask: 0x0008; 0 = panes are not frozen, 1 = panes are frozen + $this->_frozen = (bool) ((0x0008 & $options) >> 3); + + // bit: 6; mask: 0x0040; 0 = columns from left to right, 1 = columns from right to left + $this->_phpSheet->setRightToLeft((bool)((0x0040 & $options) >> 6)); + + // bit: 10; mask: 0x0400; 0 = sheet not active, 1 = sheet active + $isActive = (bool) ((0x0400 & $options) >> 10); + if ($isActive) { + $this->_phpExcel->setActiveSheetIndex($this->_phpExcel->getIndex($this->_phpSheet)); + } + + // bit: 11; mask: 0x0800; 0 = normal view, 1 = page break view + $isPageBreakPreview = (bool) ((0x0800 & $options) >> 11); + + //FIXME: set $firstVisibleRow and $firstVisibleColumn + + if ($this->_phpSheet->getSheetView()->getView() !== PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_LAYOUT) { + //NOTE: this setting is inferior to page layout view(Excel2007-) + $view = $isPageBreakPreview? PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_BREAK_PREVIEW : + PHPExcel_Worksheet_SheetView::SHEETVIEW_NORMAL; + $this->_phpSheet->getSheetView()->setView($view); + if ($this->_version === self::XLS_BIFF8) { + $zoomScale = $isPageBreakPreview? $zoomscaleInPageBreakPreview : $zoomscaleInNormalView; + $this->_phpSheet->getSheetView()->setZoomScale($zoomScale); + $this->_phpSheet->getSheetView()->setZoomScaleNormal($zoomscaleInNormalView); + } + } + } + + /** + * Read PLV Record(Created by Excel2007 or upper) + */ + private function _readPageLayoutView(){ + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + //var_dump(unpack("vrt/vgrbitFrt/V2reserved/vwScalePLV/vgrbit", $recordData)); + + // offset: 0; size: 2; rt + //->ignore + $rt = self::_GetInt2d($recordData, 0); + // offset: 2; size: 2; grbitfr + //->ignore + $grbitFrt = self::_GetInt2d($recordData, 2); + // offset: 4; size: 8; reserved + //->ignore + + // offset: 12; size 2; zoom scale + $wScalePLV = self::_GetInt2d($recordData, 12); + // offset: 14; size 2; grbit + $grbit = self::_GetInt2d($recordData, 14); + + // decomprise grbit + $fPageLayoutView = $grbit & 0x01; + $fRulerVisible = ($grbit >> 1) & 0x01; //no support + $fWhitespaceHidden = ($grbit >> 3) & 0x01; //no support + + if ($fPageLayoutView === 1) { + $this->_phpSheet->getSheetView()->setView(PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_LAYOUT); + $this->_phpSheet->getSheetView()->setZoomScale($wScalePLV); //set by Excel2007 only if SHEETVIEW_PAGE_LAYOUT + } + //otherwise, we cannot know whether SHEETVIEW_PAGE_LAYOUT or SHEETVIEW_PAGE_BREAK_PREVIEW. + } + + /** + * Read SCL record + */ + private function _readScl() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; numerator of the view magnification + $numerator = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; numerator of the view magnification + $denumerator = self::_GetInt2d($recordData, 2); + + // set the zoom scale (in percent) + $this->_phpSheet->getSheetView()->setZoomScale($numerator * 100 / $denumerator); + } + + + /** + * Read PANE record + */ + private function _readPane() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 2; position of vertical split + $px = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; position of horizontal split + $py = self::_GetInt2d($recordData, 2); + + if ($this->_frozen) { + // frozen panes + $this->_phpSheet->freezePane(PHPExcel_Cell::stringFromColumnIndex($px) . ($py + 1)); + } else { + // unfrozen panes; split windows; not supported by PHPExcel core + } + } + } + + + /** + * Read SELECTION record. There is one such record for each pane in the sheet. + */ + private function _readSelection() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 1; pane identifier + $paneId = ord($recordData{0}); + + // offset: 1; size: 2; index to row of the active cell + $r = self::_GetInt2d($recordData, 1); + + // offset: 3; size: 2; index to column of the active cell + $c = self::_GetInt2d($recordData, 3); + + // offset: 5; size: 2; index into the following cell range list to the + // entry that contains the active cell + $index = self::_GetInt2d($recordData, 5); + + // offset: 7; size: var; cell range address list containing all selected cell ranges + $data = substr($recordData, 7); + $cellRangeAddressList = $this->_readBIFF5CellRangeAddressList($data); // note: also BIFF8 uses BIFF5 syntax + + $selectedCells = $cellRangeAddressList['cellRangeAddresses'][0]; + + // first row '1' + last row '16384' indicates that full column is selected (apparently also in BIFF8!) + if (preg_match('/^([A-Z]+1\:[A-Z]+)16384$/', $selectedCells)) { + $selectedCells = preg_replace('/^([A-Z]+1\:[A-Z]+)16384$/', '${1}1048576', $selectedCells); + } + + // first row '1' + last row '65536' indicates that full column is selected + if (preg_match('/^([A-Z]+1\:[A-Z]+)65536$/', $selectedCells)) { + $selectedCells = preg_replace('/^([A-Z]+1\:[A-Z]+)65536$/', '${1}1048576', $selectedCells); + } + + // first column 'A' + last column 'IV' indicates that full row is selected + if (preg_match('/^(A[0-9]+\:)IV([0-9]+)$/', $selectedCells)) { + $selectedCells = preg_replace('/^(A[0-9]+\:)IV([0-9]+)$/', '${1}XFD${2}', $selectedCells); + } + + $this->_phpSheet->setSelectedCells($selectedCells); + } + } + + + private function _includeCellRangeFiltered($cellRangeAddress) + { + $includeCellRange = true; + if ($this->getReadFilter() !== NULL) { + $includeCellRange = false; + $rangeBoundaries = PHPExcel_Cell::getRangeBoundaries($cellRangeAddress); + $rangeBoundaries[1][0]++; + for ($row = $rangeBoundaries[0][1]; $row <= $rangeBoundaries[1][1]; $row++) { + for ($column = $rangeBoundaries[0][0]; $column != $rangeBoundaries[1][0]; $column++) { + if ($this->getReadFilter()->readCell($column, $row, $this->_phpSheet->getTitle())) { + $includeCellRange = true; + break 2; + } + } + } + } + return $includeCellRange; + } + + + /** + * MERGEDCELLS + * + * This record contains the addresses of merged cell ranges + * in the current sheet. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readMergedCells() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_version == self::XLS_BIFF8 && !$this->_readDataOnly) { + $cellRangeAddressList = $this->_readBIFF8CellRangeAddressList($recordData); + foreach ($cellRangeAddressList['cellRangeAddresses'] as $cellRangeAddress) { + if ((strpos($cellRangeAddress,':') !== FALSE) && + ($this->_includeCellRangeFiltered($cellRangeAddress))) { + $this->_phpSheet->mergeCells($cellRangeAddress); + } + } + } + } + + + /** + * Read HYPERLINK record + */ + private function _readHyperLink() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer forward to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 8; cell range address of all cells containing this hyperlink + try { + $cellRange = $this->_readBIFF8CellRangeAddressFixed($recordData, 0, 8); + } catch (PHPExcel_Exception $e) { + return; + } + + // offset: 8, size: 16; GUID of StdLink + + // offset: 24, size: 4; unknown value + + // offset: 28, size: 4; option flags + + // bit: 0; mask: 0x00000001; 0 = no link or extant, 1 = file link or URL + $isFileLinkOrUrl = (0x00000001 & self::_GetInt2d($recordData, 28)) >> 0; + + // bit: 1; mask: 0x00000002; 0 = relative path, 1 = absolute path or URL + $isAbsPathOrUrl = (0x00000001 & self::_GetInt2d($recordData, 28)) >> 1; + + // bit: 2 (and 4); mask: 0x00000014; 0 = no description + $hasDesc = (0x00000014 & self::_GetInt2d($recordData, 28)) >> 2; + + // bit: 3; mask: 0x00000008; 0 = no text, 1 = has text + $hasText = (0x00000008 & self::_GetInt2d($recordData, 28)) >> 3; + + // bit: 7; mask: 0x00000080; 0 = no target frame, 1 = has target frame + $hasFrame = (0x00000080 & self::_GetInt2d($recordData, 28)) >> 7; + + // bit: 8; mask: 0x00000100; 0 = file link or URL, 1 = UNC path (inc. server name) + $isUNC = (0x00000100 & self::_GetInt2d($recordData, 28)) >> 8; + + // offset within record data + $offset = 32; + + if ($hasDesc) { + // offset: 32; size: var; character count of description text + $dl = self::_GetInt4d($recordData, 32); + // offset: 36; size: var; character array of description text, no Unicode string header, always 16-bit characters, zero terminated + $desc = self::_encodeUTF16(substr($recordData, 36, 2 * ($dl - 1)), false); + $offset += 4 + 2 * $dl; + } + if ($hasFrame) { + $fl = self::_GetInt4d($recordData, $offset); + $offset += 4 + 2 * $fl; + } + + // detect type of hyperlink (there are 4 types) + $hyperlinkType = null; + + if ($isUNC) { + $hyperlinkType = 'UNC'; + } else if (!$isFileLinkOrUrl) { + $hyperlinkType = 'workbook'; + } else if (ord($recordData{$offset}) == 0x03) { + $hyperlinkType = 'local'; + } else if (ord($recordData{$offset}) == 0xE0) { + $hyperlinkType = 'URL'; + } + + switch ($hyperlinkType) { + case 'URL': + // section 5.58.2: Hyperlink containing a URL + // e.g. http://example.org/index.php + + // offset: var; size: 16; GUID of URL Moniker + $offset += 16; + // offset: var; size: 4; size (in bytes) of character array of the URL including trailing zero word + $us = self::_GetInt4d($recordData, $offset); + $offset += 4; + // offset: var; size: $us; character array of the URL, no Unicode string header, always 16-bit characters, zero-terminated + $url = self::_encodeUTF16(substr($recordData, $offset, $us - 2), false); + $url .= $hasText ? '#' : ''; + $offset += $us; + break; + + case 'local': + // section 5.58.3: Hyperlink to local file + // examples: + // mydoc.txt + // ../../somedoc.xls#Sheet!A1 + + // offset: var; size: 16; GUI of File Moniker + $offset += 16; + + // offset: var; size: 2; directory up-level count. + $upLevelCount = self::_GetInt2d($recordData, $offset); + $offset += 2; + + // offset: var; size: 4; character count of the shortened file path and name, including trailing zero word + $sl = self::_GetInt4d($recordData, $offset); + $offset += 4; + + // offset: var; size: sl; character array of the shortened file path and name in 8.3-DOS-format (compressed Unicode string) + $shortenedFilePath = substr($recordData, $offset, $sl); + $shortenedFilePath = self::_encodeUTF16($shortenedFilePath, true); + $shortenedFilePath = substr($shortenedFilePath, 0, -1); // remove trailing zero + + $offset += $sl; + + // offset: var; size: 24; unknown sequence + $offset += 24; + + // extended file path + // offset: var; size: 4; size of the following file link field including string lenth mark + $sz = self::_GetInt4d($recordData, $offset); + $offset += 4; + + // only present if $sz > 0 + if ($sz > 0) { + // offset: var; size: 4; size of the character array of the extended file path and name + $xl = self::_GetInt4d($recordData, $offset); + $offset += 4; + + // offset: var; size 2; unknown + $offset += 2; + + // offset: var; size $xl; character array of the extended file path and name. + $extendedFilePath = substr($recordData, $offset, $xl); + $extendedFilePath = self::_encodeUTF16($extendedFilePath, false); + $offset += $xl; + } + + // construct the path + $url = str_repeat('..\\', $upLevelCount); + $url .= ($sz > 0) ? + $extendedFilePath : $shortenedFilePath; // use extended path if available + $url .= $hasText ? '#' : ''; + + break; + + + case 'UNC': + // section 5.58.4: Hyperlink to a File with UNC (Universal Naming Convention) Path + // todo: implement + return; + + case 'workbook': + // section 5.58.5: Hyperlink to the Current Workbook + // e.g. Sheet2!B1:C2, stored in text mark field + $url = 'sheet://'; + break; + + default: + return; + + } + + if ($hasText) { + // offset: var; size: 4; character count of text mark including trailing zero word + $tl = self::_GetInt4d($recordData, $offset); + $offset += 4; + // offset: var; size: var; character array of the text mark without the # sign, no Unicode header, always 16-bit characters, zero-terminated + $text = self::_encodeUTF16(substr($recordData, $offset, 2 * ($tl - 1)), false); + $url .= $text; + } + + // apply the hyperlink to all the relevant cells + foreach (PHPExcel_Cell::extractAllCellReferencesInRange($cellRange) as $coordinate) { + $this->_phpSheet->getCell($coordinate)->getHyperLink()->setUrl($url); + } + } + } + + + /** + * Read DATAVALIDATIONS record + */ + private function _readDataValidations() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer forward to next record + $this->_pos += 4 + $length; + } + + + /** + * Read DATAVALIDATION record + */ + private function _readDataValidation() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer forward to next record + $this->_pos += 4 + $length; + + if ($this->_readDataOnly) { + return; + } + + // offset: 0; size: 4; Options + $options = self::_GetInt4d($recordData, 0); + + // bit: 0-3; mask: 0x0000000F; type + $type = (0x0000000F & $options) >> 0; + switch ($type) { + case 0x00: $type = PHPExcel_Cell_DataValidation::TYPE_NONE; break; + case 0x01: $type = PHPExcel_Cell_DataValidation::TYPE_WHOLE; break; + case 0x02: $type = PHPExcel_Cell_DataValidation::TYPE_DECIMAL; break; + case 0x03: $type = PHPExcel_Cell_DataValidation::TYPE_LIST; break; + case 0x04: $type = PHPExcel_Cell_DataValidation::TYPE_DATE; break; + case 0x05: $type = PHPExcel_Cell_DataValidation::TYPE_TIME; break; + case 0x06: $type = PHPExcel_Cell_DataValidation::TYPE_TEXTLENGTH; break; + case 0x07: $type = PHPExcel_Cell_DataValidation::TYPE_CUSTOM; break; + } + + // bit: 4-6; mask: 0x00000070; error type + $errorStyle = (0x00000070 & $options) >> 4; + switch ($errorStyle) { + case 0x00: $errorStyle = PHPExcel_Cell_DataValidation::STYLE_STOP; break; + case 0x01: $errorStyle = PHPExcel_Cell_DataValidation::STYLE_WARNING; break; + case 0x02: $errorStyle = PHPExcel_Cell_DataValidation::STYLE_INFORMATION; break; + } + + // bit: 7; mask: 0x00000080; 1= formula is explicit (only applies to list) + // I have only seen cases where this is 1 + $explicitFormula = (0x00000080 & $options) >> 7; + + // bit: 8; mask: 0x00000100; 1= empty cells allowed + $allowBlank = (0x00000100 & $options) >> 8; + + // bit: 9; mask: 0x00000200; 1= suppress drop down arrow in list type validity + $suppressDropDown = (0x00000200 & $options) >> 9; + + // bit: 18; mask: 0x00040000; 1= show prompt box if cell selected + $showInputMessage = (0x00040000 & $options) >> 18; + + // bit: 19; mask: 0x00080000; 1= show error box if invalid values entered + $showErrorMessage = (0x00080000 & $options) >> 19; + + // bit: 20-23; mask: 0x00F00000; condition operator + $operator = (0x00F00000 & $options) >> 20; + switch ($operator) { + case 0x00: $operator = PHPExcel_Cell_DataValidation::OPERATOR_BETWEEN ; break; + case 0x01: $operator = PHPExcel_Cell_DataValidation::OPERATOR_NOTBETWEEN ; break; + case 0x02: $operator = PHPExcel_Cell_DataValidation::OPERATOR_EQUAL ; break; + case 0x03: $operator = PHPExcel_Cell_DataValidation::OPERATOR_NOTEQUAL ; break; + case 0x04: $operator = PHPExcel_Cell_DataValidation::OPERATOR_GREATERTHAN ; break; + case 0x05: $operator = PHPExcel_Cell_DataValidation::OPERATOR_LESSTHAN ; break; + case 0x06: $operator = PHPExcel_Cell_DataValidation::OPERATOR_GREATERTHANOREQUAL; break; + case 0x07: $operator = PHPExcel_Cell_DataValidation::OPERATOR_LESSTHANOREQUAL ; break; + } + + // offset: 4; size: var; title of the prompt box + $offset = 4; + $string = self::_readUnicodeStringLong(substr($recordData, $offset)); + $promptTitle = $string['value'] !== chr(0) ? + $string['value'] : ''; + $offset += $string['size']; + + // offset: var; size: var; title of the error box + $string = self::_readUnicodeStringLong(substr($recordData, $offset)); + $errorTitle = $string['value'] !== chr(0) ? + $string['value'] : ''; + $offset += $string['size']; + + // offset: var; size: var; text of the prompt box + $string = self::_readUnicodeStringLong(substr($recordData, $offset)); + $prompt = $string['value'] !== chr(0) ? + $string['value'] : ''; + $offset += $string['size']; + + // offset: var; size: var; text of the error box + $string = self::_readUnicodeStringLong(substr($recordData, $offset)); + $error = $string['value'] !== chr(0) ? + $string['value'] : ''; + $offset += $string['size']; + + // offset: var; size: 2; size of the formula data for the first condition + $sz1 = self::_GetInt2d($recordData, $offset); + $offset += 2; + + // offset: var; size: 2; not used + $offset += 2; + + // offset: var; size: $sz1; formula data for first condition (without size field) + $formula1 = substr($recordData, $offset, $sz1); + $formula1 = pack('v', $sz1) . $formula1; // prepend the length + try { + $formula1 = $this->_getFormulaFromStructure($formula1); + + // in list type validity, null characters are used as item separators + if ($type == PHPExcel_Cell_DataValidation::TYPE_LIST) { + $formula1 = str_replace(chr(0), ',', $formula1); + } + } catch (PHPExcel_Exception $e) { + return; + } + $offset += $sz1; + + // offset: var; size: 2; size of the formula data for the first condition + $sz2 = self::_GetInt2d($recordData, $offset); + $offset += 2; + + // offset: var; size: 2; not used + $offset += 2; + + // offset: var; size: $sz2; formula data for second condition (without size field) + $formula2 = substr($recordData, $offset, $sz2); + $formula2 = pack('v', $sz2) . $formula2; // prepend the length + try { + $formula2 = $this->_getFormulaFromStructure($formula2); + } catch (PHPExcel_Exception $e) { + return; + } + $offset += $sz2; + + // offset: var; size: var; cell range address list with + $cellRangeAddressList = $this->_readBIFF8CellRangeAddressList(substr($recordData, $offset)); + $cellRangeAddresses = $cellRangeAddressList['cellRangeAddresses']; + + foreach ($cellRangeAddresses as $cellRange) { + $stRange = $this->_phpSheet->shrinkRangeToFit($cellRange); + $stRange = PHPExcel_Cell::extractAllCellReferencesInRange($stRange); + foreach ($stRange as $coordinate) { + $objValidation = $this->_phpSheet->getCell($coordinate)->getDataValidation(); + $objValidation->setType($type); + $objValidation->setErrorStyle($errorStyle); + $objValidation->setAllowBlank((bool)$allowBlank); + $objValidation->setShowInputMessage((bool)$showInputMessage); + $objValidation->setShowErrorMessage((bool)$showErrorMessage); + $objValidation->setShowDropDown(!$suppressDropDown); + $objValidation->setOperator($operator); + $objValidation->setErrorTitle($errorTitle); + $objValidation->setError($error); + $objValidation->setPromptTitle($promptTitle); + $objValidation->setPrompt($prompt); + $objValidation->setFormula1($formula1); + $objValidation->setFormula2($formula2); + } + } + + } + + + /** + * Read SHEETLAYOUT record. Stores sheet tab color information. + */ + private function _readSheetLayout() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // local pointer in record data + $offset = 0; + + if (!$this->_readDataOnly) { + // offset: 0; size: 2; repeated record identifier 0x0862 + + // offset: 2; size: 10; not used + + // offset: 12; size: 4; size of record data + // Excel 2003 uses size of 0x14 (documented), Excel 2007 uses size of 0x28 (not documented?) + $sz = self::_GetInt4d($recordData, 12); + + switch ($sz) { + case 0x14: + // offset: 16; size: 2; color index for sheet tab + $colorIndex = self::_GetInt2d($recordData, 16); + $color = self::_readColor($colorIndex,$this->_palette,$this->_version); + $this->_phpSheet->getTabColor()->setRGB($color['rgb']); + break; + + case 0x28: + // TODO: Investigate structure for .xls SHEETLAYOUT record as saved by MS Office Excel 2007 + return; + break; + } + } + } + + + /** + * Read SHEETPROTECTION record (FEATHEADR) + */ + private function _readSheetProtection() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_readDataOnly) { + return; + } + + // offset: 0; size: 2; repeated record header + + // offset: 2; size: 2; FRT cell reference flag (=0 currently) + + // offset: 4; size: 8; Currently not used and set to 0 + + // offset: 12; size: 2; Shared feature type index (2=Enhanced Protetion, 4=SmartTag) + $isf = self::_GetInt2d($recordData, 12); + if ($isf != 2) { + return; + } + + // offset: 14; size: 1; =1 since this is a feat header + + // offset: 15; size: 4; size of rgbHdrSData + + // rgbHdrSData, assume "Enhanced Protection" + // offset: 19; size: 2; option flags + $options = self::_GetInt2d($recordData, 19); + + // bit: 0; mask 0x0001; 1 = user may edit objects, 0 = users must not edit objects + $bool = (0x0001 & $options) >> 0; + $this->_phpSheet->getProtection()->setObjects(!$bool); + + // bit: 1; mask 0x0002; edit scenarios + $bool = (0x0002 & $options) >> 1; + $this->_phpSheet->getProtection()->setScenarios(!$bool); + + // bit: 2; mask 0x0004; format cells + $bool = (0x0004 & $options) >> 2; + $this->_phpSheet->getProtection()->setFormatCells(!$bool); + + // bit: 3; mask 0x0008; format columns + $bool = (0x0008 & $options) >> 3; + $this->_phpSheet->getProtection()->setFormatColumns(!$bool); + + // bit: 4; mask 0x0010; format rows + $bool = (0x0010 & $options) >> 4; + $this->_phpSheet->getProtection()->setFormatRows(!$bool); + + // bit: 5; mask 0x0020; insert columns + $bool = (0x0020 & $options) >> 5; + $this->_phpSheet->getProtection()->setInsertColumns(!$bool); + + // bit: 6; mask 0x0040; insert rows + $bool = (0x0040 & $options) >> 6; + $this->_phpSheet->getProtection()->setInsertRows(!$bool); + + // bit: 7; mask 0x0080; insert hyperlinks + $bool = (0x0080 & $options) >> 7; + $this->_phpSheet->getProtection()->setInsertHyperlinks(!$bool); + + // bit: 8; mask 0x0100; delete columns + $bool = (0x0100 & $options) >> 8; + $this->_phpSheet->getProtection()->setDeleteColumns(!$bool); + + // bit: 9; mask 0x0200; delete rows + $bool = (0x0200 & $options) >> 9; + $this->_phpSheet->getProtection()->setDeleteRows(!$bool); + + // bit: 10; mask 0x0400; select locked cells + $bool = (0x0400 & $options) >> 10; + $this->_phpSheet->getProtection()->setSelectLockedCells(!$bool); + + // bit: 11; mask 0x0800; sort cell range + $bool = (0x0800 & $options) >> 11; + $this->_phpSheet->getProtection()->setSort(!$bool); + + // bit: 12; mask 0x1000; auto filter + $bool = (0x1000 & $options) >> 12; + $this->_phpSheet->getProtection()->setAutoFilter(!$bool); + + // bit: 13; mask 0x2000; pivot tables + $bool = (0x2000 & $options) >> 13; + $this->_phpSheet->getProtection()->setPivotTables(!$bool); + + // bit: 14; mask 0x4000; select unlocked cells + $bool = (0x4000 & $options) >> 14; + $this->_phpSheet->getProtection()->setSelectUnlockedCells(!$bool); + + // offset: 21; size: 2; not used + } + + + /** + * Read RANGEPROTECTION record + * Reading of this record is based on Microsoft Office Excel 97-2000 Binary File Format Specification, + * where it is referred to as FEAT record + */ + private function _readRangeProtection() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // local pointer in record data + $offset = 0; + + if (!$this->_readDataOnly) { + $offset += 12; + + // offset: 12; size: 2; shared feature type, 2 = enhanced protection, 4 = smart tag + $isf = self::_GetInt2d($recordData, 12); + if ($isf != 2) { + // we only read FEAT records of type 2 + return; + } + $offset += 2; + + $offset += 5; + + // offset: 19; size: 2; count of ref ranges this feature is on + $cref = self::_GetInt2d($recordData, 19); + $offset += 2; + + $offset += 6; + + // offset: 27; size: 8 * $cref; list of cell ranges (like in hyperlink record) + $cellRanges = array(); + for ($i = 0; $i < $cref; ++$i) { + try { + $cellRange = $this->_readBIFF8CellRangeAddressFixed(substr($recordData, 27 + 8 * $i, 8)); + } catch (PHPExcel_Exception $e) { + return; + } + $cellRanges[] = $cellRange; + $offset += 8; + } + + // offset: var; size: var; variable length of feature specific data + $rgbFeat = substr($recordData, $offset); + $offset += 4; + + // offset: var; size: 4; the encrypted password (only 16-bit although field is 32-bit) + $wPassword = self::_GetInt4d($recordData, $offset); + $offset += 4; + + // Apply range protection to sheet + if ($cellRanges) { + $this->_phpSheet->protectCells(implode(' ', $cellRanges), strtoupper(dechex($wPassword)), true); + } + } + } + + + /** + * Read IMDATA record + */ + private function _readImData() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + + // get spliced record data + $splicedRecordData = $this->_getSplicedRecordData(); + $recordData = $splicedRecordData['recordData']; + + // UNDER CONSTRUCTION + + // offset: 0; size: 2; image format + $cf = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; environment from which the file was written + $env = self::_GetInt2d($recordData, 2); + + // offset: 4; size: 4; length of the image data + $lcb = self::_GetInt4d($recordData, 4); + + // offset: 8; size: var; image data + $iData = substr($recordData, 8); + + switch ($cf) { + case 0x09: // Windows bitmap format + // BITMAPCOREINFO + // 1. BITMAPCOREHEADER + // offset: 0; size: 4; bcSize, Specifies the number of bytes required by the structure + $bcSize = self::_GetInt4d($iData, 0); +// var_dump($bcSize); + + // offset: 4; size: 2; bcWidth, specifies the width of the bitmap, in pixels + $bcWidth = self::_GetInt2d($iData, 4); +// var_dump($bcWidth); + + // offset: 6; size: 2; bcHeight, specifies the height of the bitmap, in pixels. + $bcHeight = self::_GetInt2d($iData, 6); +// var_dump($bcHeight); + $ih = imagecreatetruecolor($bcWidth, $bcHeight); + + // offset: 8; size: 2; bcPlanes, specifies the number of planes for the target device. This value must be 1 + + // offset: 10; size: 2; bcBitCount specifies the number of bits-per-pixel. This value must be 1, 4, 8, or 24 + $bcBitCount = self::_GetInt2d($iData, 10); +// var_dump($bcBitCount); + + $rgbString = substr($iData, 12); + $rgbTriples = array(); + while (strlen($rgbString) > 0) { + $rgbTriples[] = unpack('Cb/Cg/Cr', $rgbString); + $rgbString = substr($rgbString, 3); + } + $x = 0; + $y = 0; + foreach ($rgbTriples as $i => $rgbTriple) { + $color = imagecolorallocate($ih, $rgbTriple['r'], $rgbTriple['g'], $rgbTriple['b']); + imagesetpixel($ih, $x, $bcHeight - 1 - $y, $color); + $x = ($x + 1) % $bcWidth; + $y = $y + floor(($x + 1) / $bcWidth); + } + //imagepng($ih, 'image.png'); + + $drawing = new PHPExcel_Worksheet_Drawing(); + $drawing->setPath($filename); + $drawing->setWorksheet($this->_phpSheet); + + break; + + case 0x02: // Windows metafile or Macintosh PICT format + case 0x0e: // native format + default; + break; + + } + + // _getSplicedRecordData() takes care of moving current position in data stream + } + + + /** + * Read a free CONTINUE record. Free CONTINUE record may be a camouflaged MSODRAWING record + * When MSODRAWING data on a sheet exceeds 8224 bytes, CONTINUE records are used instead. Undocumented. + * In this case, we must treat the CONTINUE record as a MSODRAWING record + */ + private function _readContinue() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // check if we are reading drawing data + // this is in case a free CONTINUE record occurs in other circumstances we are unaware of + if ($this->_drawingData == '') { + // move stream pointer to next record + $this->_pos += 4 + $length; + + return; + } + + // check if record data is at least 4 bytes long, otherwise there is no chance this is MSODRAWING data + if ($length < 4) { + // move stream pointer to next record + $this->_pos += 4 + $length; + + return; + } + + // dirty check to see if CONTINUE record could be a camouflaged MSODRAWING record + // look inside CONTINUE record to see if it looks like a part of an Escher stream + // we know that Escher stream may be split at least at + // 0xF003 MsofbtSpgrContainer + // 0xF004 MsofbtSpContainer + // 0xF00D MsofbtClientTextbox + $validSplitPoints = array(0xF003, 0xF004, 0xF00D); // add identifiers if we find more + + $splitPoint = self::_GetInt2d($recordData, 2); + if (in_array($splitPoint, $validSplitPoints)) { + // get spliced record data (and move pointer to next record) + $splicedRecordData = $this->_getSplicedRecordData(); + $this->_drawingData .= $splicedRecordData['recordData']; + + return; + } + + // move stream pointer to next record + $this->_pos += 4 + $length; + + } + + + /** + * Reads a record from current position in data stream and continues reading data as long as CONTINUE + * records are found. Splices the record data pieces and returns the combined string as if record data + * is in one piece. + * Moves to next current position in data stream to start of next record different from a CONtINUE record + * + * @return array + */ + private function _getSplicedRecordData() + { + $data = ''; + $spliceOffsets = array(); + + $i = 0; + $spliceOffsets[0] = 0; + + do { + ++$i; + + // offset: 0; size: 2; identifier + $identifier = self::_GetInt2d($this->_data, $this->_pos); + // offset: 2; size: 2; length + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $data .= $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + $spliceOffsets[$i] = $spliceOffsets[$i - 1] + $length; + + $this->_pos += 4 + $length; + $nextIdentifier = self::_GetInt2d($this->_data, $this->_pos); + } + while ($nextIdentifier == self::XLS_Type_CONTINUE); + + $splicedData = array( + 'recordData' => $data, + 'spliceOffsets' => $spliceOffsets, + ); + + return $splicedData; + + } + + + /** + * Convert formula structure into human readable Excel formula like 'A3+A5*5' + * + * @param string $formulaStructure The complete binary data for the formula + * @param string $baseCell Base cell, only needed when formula contains tRefN tokens, e.g. with shared formulas + * @return string Human readable formula + */ + private function _getFormulaFromStructure($formulaStructure, $baseCell = 'A1') + { + // offset: 0; size: 2; size of the following formula data + $sz = self::_GetInt2d($formulaStructure, 0); + + // offset: 2; size: sz + $formulaData = substr($formulaStructure, 2, $sz); + + // for debug: dump the formula data + //echo ''; + //echo 'size: ' . $sz . "\n"; + //echo 'the entire formula data: '; + //Debug::dump($formulaData); + //echo "\n----\n"; + + // offset: 2 + sz; size: variable (optional) + if (strlen($formulaStructure) > 2 + $sz) { + $additionalData = substr($formulaStructure, 2 + $sz); + + // for debug: dump the additional data + //echo 'the entire additional data: '; + //Debug::dump($additionalData); + //echo "\n----\n"; + + } else { + $additionalData = ''; + } + + return $this->_getFormulaFromData($formulaData, $additionalData, $baseCell); + } + + + /** + * Take formula data and additional data for formula and return human readable formula + * + * @param string $formulaData The binary data for the formula itself + * @param string $additionalData Additional binary data going with the formula + * @param string $baseCell Base cell, only needed when formula contains tRefN tokens, e.g. with shared formulas + * @return string Human readable formula + */ + private function _getFormulaFromData($formulaData, $additionalData = '', $baseCell = 'A1') + { + // start parsing the formula data + $tokens = array(); + + while (strlen($formulaData) > 0 and $token = $this->_getNextToken($formulaData, $baseCell)) { + $tokens[] = $token; + $formulaData = substr($formulaData, $token['size']); + + // for debug: dump the token + //var_dump($token); + } + + $formulaString = $this->_createFormulaFromTokens($tokens, $additionalData); + + return $formulaString; + } + + + /** + * Take array of tokens together with additional data for formula and return human readable formula + * + * @param array $tokens + * @param array $additionalData Additional binary data going with the formula + * @param string $baseCell Base cell, only needed when formula contains tRefN tokens, e.g. with shared formulas + * @return string Human readable formula + */ + private function _createFormulaFromTokens($tokens, $additionalData) + { + // empty formula? + if (empty($tokens)) { + return ''; + } + + $formulaStrings = array(); + foreach ($tokens as $token) { + // initialize spaces + $space0 = isset($space0) ? $space0 : ''; // spaces before next token, not tParen + $space1 = isset($space1) ? $space1 : ''; // carriage returns before next token, not tParen + $space2 = isset($space2) ? $space2 : ''; // spaces before opening parenthesis + $space3 = isset($space3) ? $space3 : ''; // carriage returns before opening parenthesis + $space4 = isset($space4) ? $space4 : ''; // spaces before closing parenthesis + $space5 = isset($space5) ? $space5 : ''; // carriage returns before closing parenthesis + + switch ($token['name']) { + case 'tAdd': // addition + case 'tConcat': // addition + case 'tDiv': // division + case 'tEQ': // equality + case 'tGE': // greater than or equal + case 'tGT': // greater than + case 'tIsect': // intersection + case 'tLE': // less than or equal + case 'tList': // less than or equal + case 'tLT': // less than + case 'tMul': // multiplication + case 'tNE': // multiplication + case 'tPower': // power + case 'tRange': // range + case 'tSub': // subtraction + $op2 = array_pop($formulaStrings); + $op1 = array_pop($formulaStrings); + $formulaStrings[] = "$op1$space1$space0{$token['data']}$op2"; + unset($space0, $space1); + break; + case 'tUplus': // unary plus + case 'tUminus': // unary minus + $op = array_pop($formulaStrings); + $formulaStrings[] = "$space1$space0{$token['data']}$op"; + unset($space0, $space1); + break; + case 'tPercent': // percent sign + $op = array_pop($formulaStrings); + $formulaStrings[] = "$op$space1$space0{$token['data']}"; + unset($space0, $space1); + break; + case 'tAttrVolatile': // indicates volatile function + case 'tAttrIf': + case 'tAttrSkip': + case 'tAttrChoose': + // token is only important for Excel formula evaluator + // do nothing + break; + case 'tAttrSpace': // space / carriage return + // space will be used when next token arrives, do not alter formulaString stack + switch ($token['data']['spacetype']) { + case 'type0': + $space0 = str_repeat(' ', $token['data']['spacecount']); + break; + case 'type1': + $space1 = str_repeat("\n", $token['data']['spacecount']); + break; + case 'type2': + $space2 = str_repeat(' ', $token['data']['spacecount']); + break; + case 'type3': + $space3 = str_repeat("\n", $token['data']['spacecount']); + break; + case 'type4': + $space4 = str_repeat(' ', $token['data']['spacecount']); + break; + case 'type5': + $space5 = str_repeat("\n", $token['data']['spacecount']); + break; + } + break; + case 'tAttrSum': // SUM function with one parameter + $op = array_pop($formulaStrings); + $formulaStrings[] = "{$space1}{$space0}SUM($op)"; + unset($space0, $space1); + break; + case 'tFunc': // function with fixed number of arguments + case 'tFuncV': // function with variable number of arguments + if ($token['data']['function'] != '') { + // normal function + $ops = array(); // array of operators + for ($i = 0; $i < $token['data']['args']; ++$i) { + $ops[] = array_pop($formulaStrings); + } + $ops = array_reverse($ops); + $formulaStrings[] = "$space1$space0{$token['data']['function']}(" . implode(',', $ops) . ")"; + unset($space0, $space1); + } else { + // add-in function + $ops = array(); // array of operators + for ($i = 0; $i < $token['data']['args'] - 1; ++$i) { + $ops[] = array_pop($formulaStrings); + } + $ops = array_reverse($ops); + $function = array_pop($formulaStrings); + $formulaStrings[] = "$space1$space0$function(" . implode(',', $ops) . ")"; + unset($space0, $space1); + } + break; + case 'tParen': // parenthesis + $expression = array_pop($formulaStrings); + $formulaStrings[] = "$space3$space2($expression$space5$space4)"; + unset($space2, $space3, $space4, $space5); + break; + case 'tArray': // array constant + $constantArray = self::_readBIFF8ConstantArray($additionalData); + $formulaStrings[] = $space1 . $space0 . $constantArray['value']; + $additionalData = substr($additionalData, $constantArray['size']); // bite of chunk of additional data + unset($space0, $space1); + break; + case 'tMemArea': + // bite off chunk of additional data + $cellRangeAddressList = $this->_readBIFF8CellRangeAddressList($additionalData); + $additionalData = substr($additionalData, $cellRangeAddressList['size']); + $formulaStrings[] = "$space1$space0{$token['data']}"; + unset($space0, $space1); + break; + case 'tArea': // cell range address + case 'tBool': // boolean + case 'tErr': // error code + case 'tInt': // integer + case 'tMemErr': + case 'tMemFunc': + case 'tMissArg': + case 'tName': + case 'tNameX': + case 'tNum': // number + case 'tRef': // single cell reference + case 'tRef3d': // 3d cell reference + case 'tArea3d': // 3d cell range reference + case 'tRefN': + case 'tAreaN': + case 'tStr': // string + $formulaStrings[] = "$space1$space0{$token['data']}"; + unset($space0, $space1); + break; + } + } + $formulaString = $formulaStrings[0]; + + // for debug: dump the human readable formula + //echo '----' . "\n"; + //echo 'Formula: ' . $formulaString; + + return $formulaString; + } + + + /** + * Fetch next token from binary formula data + * + * @param string Formula data + * @param string $baseCell Base cell, only needed when formula contains tRefN tokens, e.g. with shared formulas + * @return array + * @throws PHPExcel_Reader_Exception + */ + private function _getNextToken($formulaData, $baseCell = 'A1') + { + // offset: 0; size: 1; token id + $id = ord($formulaData[0]); // token id + $name = false; // initialize token name + + switch ($id) { + case 0x03: $name = 'tAdd'; $size = 1; $data = '+'; break; + case 0x04: $name = 'tSub'; $size = 1; $data = '-'; break; + case 0x05: $name = 'tMul'; $size = 1; $data = '*'; break; + case 0x06: $name = 'tDiv'; $size = 1; $data = '/'; break; + case 0x07: $name = 'tPower'; $size = 1; $data = '^'; break; + case 0x08: $name = 'tConcat'; $size = 1; $data = '&'; break; + case 0x09: $name = 'tLT'; $size = 1; $data = '<'; break; + case 0x0A: $name = 'tLE'; $size = 1; $data = '<='; break; + case 0x0B: $name = 'tEQ'; $size = 1; $data = '='; break; + case 0x0C: $name = 'tGE'; $size = 1; $data = '>='; break; + case 0x0D: $name = 'tGT'; $size = 1; $data = '>'; break; + case 0x0E: $name = 'tNE'; $size = 1; $data = '<>'; break; + case 0x0F: $name = 'tIsect'; $size = 1; $data = ' '; break; + case 0x10: $name = 'tList'; $size = 1; $data = ','; break; + case 0x11: $name = 'tRange'; $size = 1; $data = ':'; break; + case 0x12: $name = 'tUplus'; $size = 1; $data = '+'; break; + case 0x13: $name = 'tUminus'; $size = 1; $data = '-'; break; + case 0x14: $name = 'tPercent'; $size = 1; $data = '%'; break; + case 0x15: // parenthesis + $name = 'tParen'; + $size = 1; + $data = null; + break; + case 0x16: // missing argument + $name = 'tMissArg'; + $size = 1; + $data = ''; + break; + case 0x17: // string + $name = 'tStr'; + // offset: 1; size: var; Unicode string, 8-bit string length + $string = self::_readUnicodeStringShort(substr($formulaData, 1)); + $size = 1 + $string['size']; + $data = self::_UTF8toExcelDoubleQuoted($string['value']); + break; + case 0x19: // Special attribute + // offset: 1; size: 1; attribute type flags: + switch (ord($formulaData[1])) { + case 0x01: + $name = 'tAttrVolatile'; + $size = 4; + $data = null; + break; + case 0x02: + $name = 'tAttrIf'; + $size = 4; + $data = null; + break; + case 0x04: + $name = 'tAttrChoose'; + // offset: 2; size: 2; number of choices in the CHOOSE function ($nc, number of parameters decreased by 1) + $nc = self::_GetInt2d($formulaData, 2); + // offset: 4; size: 2 * $nc + // offset: 4 + 2 * $nc; size: 2 + $size = 2 * $nc + 6; + $data = null; + break; + case 0x08: + $name = 'tAttrSkip'; + $size = 4; + $data = null; + break; + case 0x10: + $name = 'tAttrSum'; + $size = 4; + $data = null; + break; + case 0x40: + case 0x41: + $name = 'tAttrSpace'; + $size = 4; + // offset: 2; size: 2; space type and position + switch (ord($formulaData[2])) { + case 0x00: + $spacetype = 'type0'; + break; + case 0x01: + $spacetype = 'type1'; + break; + case 0x02: + $spacetype = 'type2'; + break; + case 0x03: + $spacetype = 'type3'; + break; + case 0x04: + $spacetype = 'type4'; + break; + case 0x05: + $spacetype = 'type5'; + break; + default: + throw new PHPExcel_Reader_Exception('Unrecognized space type in tAttrSpace token'); + break; + } + // offset: 3; size: 1; number of inserted spaces/carriage returns + $spacecount = ord($formulaData[3]); + + $data = array('spacetype' => $spacetype, 'spacecount' => $spacecount); + break; + default: + throw new PHPExcel_Reader_Exception('Unrecognized attribute flag in tAttr token'); + break; + } + break; + case 0x1C: // error code + // offset: 1; size: 1; error code + $name = 'tErr'; + $size = 2; + $data = self::_mapErrorCode(ord($formulaData[1])); + break; + case 0x1D: // boolean + // offset: 1; size: 1; 0 = false, 1 = true; + $name = 'tBool'; + $size = 2; + $data = ord($formulaData[1]) ? 'TRUE' : 'FALSE'; + break; + case 0x1E: // integer + // offset: 1; size: 2; unsigned 16-bit integer + $name = 'tInt'; + $size = 3; + $data = self::_GetInt2d($formulaData, 1); + break; + case 0x1F: // number + // offset: 1; size: 8; + $name = 'tNum'; + $size = 9; + $data = self::_extractNumber(substr($formulaData, 1)); + $data = str_replace(',', '.', (string)$data); // in case non-English locale + break; + case 0x20: // array constant + case 0x40: + case 0x60: + // offset: 1; size: 7; not used + $name = 'tArray'; + $size = 8; + $data = null; + break; + case 0x21: // function with fixed number of arguments + case 0x41: + case 0x61: + $name = 'tFunc'; + $size = 3; + // offset: 1; size: 2; index to built-in sheet function + switch (self::_GetInt2d($formulaData, 1)) { + case 2: $function = 'ISNA'; $args = 1; break; + case 3: $function = 'ISERROR'; $args = 1; break; + case 10: $function = 'NA'; $args = 0; break; + case 15: $function = 'SIN'; $args = 1; break; + case 16: $function = 'COS'; $args = 1; break; + case 17: $function = 'TAN'; $args = 1; break; + case 18: $function = 'ATAN'; $args = 1; break; + case 19: $function = 'PI'; $args = 0; break; + case 20: $function = 'SQRT'; $args = 1; break; + case 21: $function = 'EXP'; $args = 1; break; + case 22: $function = 'LN'; $args = 1; break; + case 23: $function = 'LOG10'; $args = 1; break; + case 24: $function = 'ABS'; $args = 1; break; + case 25: $function = 'INT'; $args = 1; break; + case 26: $function = 'SIGN'; $args = 1; break; + case 27: $function = 'ROUND'; $args = 2; break; + case 30: $function = 'REPT'; $args = 2; break; + case 31: $function = 'MID'; $args = 3; break; + case 32: $function = 'LEN'; $args = 1; break; + case 33: $function = 'VALUE'; $args = 1; break; + case 34: $function = 'TRUE'; $args = 0; break; + case 35: $function = 'FALSE'; $args = 0; break; + case 38: $function = 'NOT'; $args = 1; break; + case 39: $function = 'MOD'; $args = 2; break; + case 40: $function = 'DCOUNT'; $args = 3; break; + case 41: $function = 'DSUM'; $args = 3; break; + case 42: $function = 'DAVERAGE'; $args = 3; break; + case 43: $function = 'DMIN'; $args = 3; break; + case 44: $function = 'DMAX'; $args = 3; break; + case 45: $function = 'DSTDEV'; $args = 3; break; + case 48: $function = 'TEXT'; $args = 2; break; + case 61: $function = 'MIRR'; $args = 3; break; + case 63: $function = 'RAND'; $args = 0; break; + case 65: $function = 'DATE'; $args = 3; break; + case 66: $function = 'TIME'; $args = 3; break; + case 67: $function = 'DAY'; $args = 1; break; + case 68: $function = 'MONTH'; $args = 1; break; + case 69: $function = 'YEAR'; $args = 1; break; + case 71: $function = 'HOUR'; $args = 1; break; + case 72: $function = 'MINUTE'; $args = 1; break; + case 73: $function = 'SECOND'; $args = 1; break; + case 74: $function = 'NOW'; $args = 0; break; + case 75: $function = 'AREAS'; $args = 1; break; + case 76: $function = 'ROWS'; $args = 1; break; + case 77: $function = 'COLUMNS'; $args = 1; break; + case 83: $function = 'TRANSPOSE'; $args = 1; break; + case 86: $function = 'TYPE'; $args = 1; break; + case 97: $function = 'ATAN2'; $args = 2; break; + case 98: $function = 'ASIN'; $args = 1; break; + case 99: $function = 'ACOS'; $args = 1; break; + case 105: $function = 'ISREF'; $args = 1; break; + case 111: $function = 'CHAR'; $args = 1; break; + case 112: $function = 'LOWER'; $args = 1; break; + case 113: $function = 'UPPER'; $args = 1; break; + case 114: $function = 'PROPER'; $args = 1; break; + case 117: $function = 'EXACT'; $args = 2; break; + case 118: $function = 'TRIM'; $args = 1; break; + case 119: $function = 'REPLACE'; $args = 4; break; + case 121: $function = 'CODE'; $args = 1; break; + case 126: $function = 'ISERR'; $args = 1; break; + case 127: $function = 'ISTEXT'; $args = 1; break; + case 128: $function = 'ISNUMBER'; $args = 1; break; + case 129: $function = 'ISBLANK'; $args = 1; break; + case 130: $function = 'T'; $args = 1; break; + case 131: $function = 'N'; $args = 1; break; + case 140: $function = 'DATEVALUE'; $args = 1; break; + case 141: $function = 'TIMEVALUE'; $args = 1; break; + case 142: $function = 'SLN'; $args = 3; break; + case 143: $function = 'SYD'; $args = 4; break; + case 162: $function = 'CLEAN'; $args = 1; break; + case 163: $function = 'MDETERM'; $args = 1; break; + case 164: $function = 'MINVERSE'; $args = 1; break; + case 165: $function = 'MMULT'; $args = 2; break; + case 184: $function = 'FACT'; $args = 1; break; + case 189: $function = 'DPRODUCT'; $args = 3; break; + case 190: $function = 'ISNONTEXT'; $args = 1; break; + case 195: $function = 'DSTDEVP'; $args = 3; break; + case 196: $function = 'DVARP'; $args = 3; break; + case 198: $function = 'ISLOGICAL'; $args = 1; break; + case 199: $function = 'DCOUNTA'; $args = 3; break; + case 207: $function = 'REPLACEB'; $args = 4; break; + case 210: $function = 'MIDB'; $args = 3; break; + case 211: $function = 'LENB'; $args = 1; break; + case 212: $function = 'ROUNDUP'; $args = 2; break; + case 213: $function = 'ROUNDDOWN'; $args = 2; break; + case 214: $function = 'ASC'; $args = 1; break; + case 215: $function = 'DBCS'; $args = 1; break; + case 221: $function = 'TODAY'; $args = 0; break; + case 229: $function = 'SINH'; $args = 1; break; + case 230: $function = 'COSH'; $args = 1; break; + case 231: $function = 'TANH'; $args = 1; break; + case 232: $function = 'ASINH'; $args = 1; break; + case 233: $function = 'ACOSH'; $args = 1; break; + case 234: $function = 'ATANH'; $args = 1; break; + case 235: $function = 'DGET'; $args = 3; break; + case 244: $function = 'INFO'; $args = 1; break; + case 252: $function = 'FREQUENCY'; $args = 2; break; + case 261: $function = 'ERROR.TYPE'; $args = 1; break; + case 271: $function = 'GAMMALN'; $args = 1; break; + case 273: $function = 'BINOMDIST'; $args = 4; break; + case 274: $function = 'CHIDIST'; $args = 2; break; + case 275: $function = 'CHIINV'; $args = 2; break; + case 276: $function = 'COMBIN'; $args = 2; break; + case 277: $function = 'CONFIDENCE'; $args = 3; break; + case 278: $function = 'CRITBINOM'; $args = 3; break; + case 279: $function = 'EVEN'; $args = 1; break; + case 280: $function = 'EXPONDIST'; $args = 3; break; + case 281: $function = 'FDIST'; $args = 3; break; + case 282: $function = 'FINV'; $args = 3; break; + case 283: $function = 'FISHER'; $args = 1; break; + case 284: $function = 'FISHERINV'; $args = 1; break; + case 285: $function = 'FLOOR'; $args = 2; break; + case 286: $function = 'GAMMADIST'; $args = 4; break; + case 287: $function = 'GAMMAINV'; $args = 3; break; + case 288: $function = 'CEILING'; $args = 2; break; + case 289: $function = 'HYPGEOMDIST'; $args = 4; break; + case 290: $function = 'LOGNORMDIST'; $args = 3; break; + case 291: $function = 'LOGINV'; $args = 3; break; + case 292: $function = 'NEGBINOMDIST'; $args = 3; break; + case 293: $function = 'NORMDIST'; $args = 4; break; + case 294: $function = 'NORMSDIST'; $args = 1; break; + case 295: $function = 'NORMINV'; $args = 3; break; + case 296: $function = 'NORMSINV'; $args = 1; break; + case 297: $function = 'STANDARDIZE'; $args = 3; break; + case 298: $function = 'ODD'; $args = 1; break; + case 299: $function = 'PERMUT'; $args = 2; break; + case 300: $function = 'POISSON'; $args = 3; break; + case 301: $function = 'TDIST'; $args = 3; break; + case 302: $function = 'WEIBULL'; $args = 4; break; + case 303: $function = 'SUMXMY2'; $args = 2; break; + case 304: $function = 'SUMX2MY2'; $args = 2; break; + case 305: $function = 'SUMX2PY2'; $args = 2; break; + case 306: $function = 'CHITEST'; $args = 2; break; + case 307: $function = 'CORREL'; $args = 2; break; + case 308: $function = 'COVAR'; $args = 2; break; + case 309: $function = 'FORECAST'; $args = 3; break; + case 310: $function = 'FTEST'; $args = 2; break; + case 311: $function = 'INTERCEPT'; $args = 2; break; + case 312: $function = 'PEARSON'; $args = 2; break; + case 313: $function = 'RSQ'; $args = 2; break; + case 314: $function = 'STEYX'; $args = 2; break; + case 315: $function = 'SLOPE'; $args = 2; break; + case 316: $function = 'TTEST'; $args = 4; break; + case 325: $function = 'LARGE'; $args = 2; break; + case 326: $function = 'SMALL'; $args = 2; break; + case 327: $function = 'QUARTILE'; $args = 2; break; + case 328: $function = 'PERCENTILE'; $args = 2; break; + case 331: $function = 'TRIMMEAN'; $args = 2; break; + case 332: $function = 'TINV'; $args = 2; break; + case 337: $function = 'POWER'; $args = 2; break; + case 342: $function = 'RADIANS'; $args = 1; break; + case 343: $function = 'DEGREES'; $args = 1; break; + case 346: $function = 'COUNTIF'; $args = 2; break; + case 347: $function = 'COUNTBLANK'; $args = 1; break; + case 350: $function = 'ISPMT'; $args = 4; break; + case 351: $function = 'DATEDIF'; $args = 3; break; + case 352: $function = 'DATESTRING'; $args = 1; break; + case 353: $function = 'NUMBERSTRING'; $args = 2; break; + case 360: $function = 'PHONETIC'; $args = 1; break; + case 368: $function = 'BAHTTEXT'; $args = 1; break; + default: + throw new PHPExcel_Reader_Exception('Unrecognized function in formula'); + break; + } + $data = array('function' => $function, 'args' => $args); + break; + case 0x22: // function with variable number of arguments + case 0x42: + case 0x62: + $name = 'tFuncV'; + $size = 4; + // offset: 1; size: 1; number of arguments + $args = ord($formulaData[1]); + // offset: 2: size: 2; index to built-in sheet function + $index = self::_GetInt2d($formulaData, 2); + switch ($index) { + case 0: $function = 'COUNT'; break; + case 1: $function = 'IF'; break; + case 4: $function = 'SUM'; break; + case 5: $function = 'AVERAGE'; break; + case 6: $function = 'MIN'; break; + case 7: $function = 'MAX'; break; + case 8: $function = 'ROW'; break; + case 9: $function = 'COLUMN'; break; + case 11: $function = 'NPV'; break; + case 12: $function = 'STDEV'; break; + case 13: $function = 'DOLLAR'; break; + case 14: $function = 'FIXED'; break; + case 28: $function = 'LOOKUP'; break; + case 29: $function = 'INDEX'; break; + case 36: $function = 'AND'; break; + case 37: $function = 'OR'; break; + case 46: $function = 'VAR'; break; + case 49: $function = 'LINEST'; break; + case 50: $function = 'TREND'; break; + case 51: $function = 'LOGEST'; break; + case 52: $function = 'GROWTH'; break; + case 56: $function = 'PV'; break; + case 57: $function = 'FV'; break; + case 58: $function = 'NPER'; break; + case 59: $function = 'PMT'; break; + case 60: $function = 'RATE'; break; + case 62: $function = 'IRR'; break; + case 64: $function = 'MATCH'; break; + case 70: $function = 'WEEKDAY'; break; + case 78: $function = 'OFFSET'; break; + case 82: $function = 'SEARCH'; break; + case 100: $function = 'CHOOSE'; break; + case 101: $function = 'HLOOKUP'; break; + case 102: $function = 'VLOOKUP'; break; + case 109: $function = 'LOG'; break; + case 115: $function = 'LEFT'; break; + case 116: $function = 'RIGHT'; break; + case 120: $function = 'SUBSTITUTE'; break; + case 124: $function = 'FIND'; break; + case 125: $function = 'CELL'; break; + case 144: $function = 'DDB'; break; + case 148: $function = 'INDIRECT'; break; + case 167: $function = 'IPMT'; break; + case 168: $function = 'PPMT'; break; + case 169: $function = 'COUNTA'; break; + case 183: $function = 'PRODUCT'; break; + case 193: $function = 'STDEVP'; break; + case 194: $function = 'VARP'; break; + case 197: $function = 'TRUNC'; break; + case 204: $function = 'USDOLLAR'; break; + case 205: $function = 'FINDB'; break; + case 206: $function = 'SEARCHB'; break; + case 208: $function = 'LEFTB'; break; + case 209: $function = 'RIGHTB'; break; + case 216: $function = 'RANK'; break; + case 219: $function = 'ADDRESS'; break; + case 220: $function = 'DAYS360'; break; + case 222: $function = 'VDB'; break; + case 227: $function = 'MEDIAN'; break; + case 228: $function = 'SUMPRODUCT'; break; + case 247: $function = 'DB'; break; + case 255: $function = ''; break; + case 269: $function = 'AVEDEV'; break; + case 270: $function = 'BETADIST'; break; + case 272: $function = 'BETAINV'; break; + case 317: $function = 'PROB'; break; + case 318: $function = 'DEVSQ'; break; + case 319: $function = 'GEOMEAN'; break; + case 320: $function = 'HARMEAN'; break; + case 321: $function = 'SUMSQ'; break; + case 322: $function = 'KURT'; break; + case 323: $function = 'SKEW'; break; + case 324: $function = 'ZTEST'; break; + case 329: $function = 'PERCENTRANK'; break; + case 330: $function = 'MODE'; break; + case 336: $function = 'CONCATENATE'; break; + case 344: $function = 'SUBTOTAL'; break; + case 345: $function = 'SUMIF'; break; + case 354: $function = 'ROMAN'; break; + case 358: $function = 'GETPIVOTDATA'; break; + case 359: $function = 'HYPERLINK'; break; + case 361: $function = 'AVERAGEA'; break; + case 362: $function = 'MAXA'; break; + case 363: $function = 'MINA'; break; + case 364: $function = 'STDEVPA'; break; + case 365: $function = 'VARPA'; break; + case 366: $function = 'STDEVA'; break; + case 367: $function = 'VARA'; break; + default: + throw new PHPExcel_Reader_Exception('Unrecognized function in formula'); + break; + } + $data = array('function' => $function, 'args' => $args); + break; + case 0x23: // index to defined name + case 0x43: + case 0x63: + $name = 'tName'; + $size = 5; + // offset: 1; size: 2; one-based index to definedname record + $definedNameIndex = self::_GetInt2d($formulaData, 1) - 1; + // offset: 2; size: 2; not used + $data = $this->_definedname[$definedNameIndex]['name']; + break; + case 0x24: // single cell reference e.g. A5 + case 0x44: + case 0x64: + $name = 'tRef'; + $size = 5; + $data = $this->_readBIFF8CellAddress(substr($formulaData, 1, 4)); + break; + case 0x25: // cell range reference to cells in the same sheet (2d) + case 0x45: + case 0x65: + $name = 'tArea'; + $size = 9; + $data = $this->_readBIFF8CellRangeAddress(substr($formulaData, 1, 8)); + break; + case 0x26: // Constant reference sub-expression + case 0x46: + case 0x66: + $name = 'tMemArea'; + // offset: 1; size: 4; not used + // offset: 5; size: 2; size of the following subexpression + $subSize = self::_GetInt2d($formulaData, 5); + $size = 7 + $subSize; + $data = $this->_getFormulaFromData(substr($formulaData, 7, $subSize)); + break; + case 0x27: // Deleted constant reference sub-expression + case 0x47: + case 0x67: + $name = 'tMemErr'; + // offset: 1; size: 4; not used + // offset: 5; size: 2; size of the following subexpression + $subSize = self::_GetInt2d($formulaData, 5); + $size = 7 + $subSize; + $data = $this->_getFormulaFromData(substr($formulaData, 7, $subSize)); + break; + case 0x29: // Variable reference sub-expression + case 0x49: + case 0x69: + $name = 'tMemFunc'; + // offset: 1; size: 2; size of the following sub-expression + $subSize = self::_GetInt2d($formulaData, 1); + $size = 3 + $subSize; + $data = $this->_getFormulaFromData(substr($formulaData, 3, $subSize)); + break; + + case 0x2C: // Relative 2d cell reference reference, used in shared formulas and some other places + case 0x4C: + case 0x6C: + $name = 'tRefN'; + $size = 5; + $data = $this->_readBIFF8CellAddressB(substr($formulaData, 1, 4), $baseCell); + break; + + case 0x2D: // Relative 2d range reference + case 0x4D: + case 0x6D: + $name = 'tAreaN'; + $size = 9; + $data = $this->_readBIFF8CellRangeAddressB(substr($formulaData, 1, 8), $baseCell); + break; + + case 0x39: // External name + case 0x59: + case 0x79: + $name = 'tNameX'; + $size = 7; + // offset: 1; size: 2; index to REF entry in EXTERNSHEET record + // offset: 3; size: 2; one-based index to DEFINEDNAME or EXTERNNAME record + $index = self::_GetInt2d($formulaData, 3); + // assume index is to EXTERNNAME record + $data = $this->_externalNames[$index - 1]['name']; + // offset: 5; size: 2; not used + break; + + case 0x3A: // 3d reference to cell + case 0x5A: + case 0x7A: + $name = 'tRef3d'; + $size = 7; + + try { + // offset: 1; size: 2; index to REF entry + $sheetRange = $this->_readSheetRangeByRefIndex(self::_GetInt2d($formulaData, 1)); + // offset: 3; size: 4; cell address + $cellAddress = $this->_readBIFF8CellAddress(substr($formulaData, 3, 4)); + + $data = "$sheetRange!$cellAddress"; + } catch (PHPExcel_Exception $e) { + // deleted sheet reference + $data = '#REF!'; + } + + break; + case 0x3B: // 3d reference to cell range + case 0x5B: + case 0x7B: + $name = 'tArea3d'; + $size = 11; + + try { + // offset: 1; size: 2; index to REF entry + $sheetRange = $this->_readSheetRangeByRefIndex(self::_GetInt2d($formulaData, 1)); + // offset: 3; size: 8; cell address + $cellRangeAddress = $this->_readBIFF8CellRangeAddress(substr($formulaData, 3, 8)); + + $data = "$sheetRange!$cellRangeAddress"; + } catch (PHPExcel_Exception $e) { + // deleted sheet reference + $data = '#REF!'; + } + + break; + // Unknown cases // don't know how to deal with + default: + throw new PHPExcel_Reader_Exception('Unrecognized token ' . sprintf('%02X', $id) . ' in formula'); + break; + } + + return array( + 'id' => $id, + 'name' => $name, + 'size' => $size, + 'data' => $data, + ); + } + + + /** + * Reads a cell address in BIFF8 e.g. 'A2' or '$A$2' + * section 3.3.4 + * + * @param string $cellAddressStructure + * @return string + */ + private function _readBIFF8CellAddress($cellAddressStructure) + { + // offset: 0; size: 2; index to row (0... 65535) (or offset (-32768... 32767)) + $row = self::_GetInt2d($cellAddressStructure, 0) + 1; + + // offset: 2; size: 2; index to column or column offset + relative flags + + // bit: 7-0; mask 0x00FF; column index + $column = PHPExcel_Cell::stringFromColumnIndex(0x00FF & self::_GetInt2d($cellAddressStructure, 2)); + + // bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index) + if (!(0x4000 & self::_GetInt2d($cellAddressStructure, 2))) { + $column = '$' . $column; + } + // bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index) + if (!(0x8000 & self::_GetInt2d($cellAddressStructure, 2))) { + $row = '$' . $row; + } + + return $column . $row; + } + + + /** + * Reads a cell address in BIFF8 for shared formulas. Uses positive and negative values for row and column + * to indicate offsets from a base cell + * section 3.3.4 + * + * @param string $cellAddressStructure + * @param string $baseCell Base cell, only needed when formula contains tRefN tokens, e.g. with shared formulas + * @return string + */ + private function _readBIFF8CellAddressB($cellAddressStructure, $baseCell = 'A1') + { + list($baseCol, $baseRow) = PHPExcel_Cell::coordinateFromString($baseCell); + $baseCol = PHPExcel_Cell::columnIndexFromString($baseCol) - 1; + + // offset: 0; size: 2; index to row (0... 65535) (or offset (-32768... 32767)) + $rowIndex = self::_GetInt2d($cellAddressStructure, 0); + $row = self::_GetInt2d($cellAddressStructure, 0) + 1; + + // offset: 2; size: 2; index to column or column offset + relative flags + + // bit: 7-0; mask 0x00FF; column index + $colIndex = 0x00FF & self::_GetInt2d($cellAddressStructure, 2); + + // bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index) + if (!(0x4000 & self::_GetInt2d($cellAddressStructure, 2))) { + $column = PHPExcel_Cell::stringFromColumnIndex($colIndex); + $column = '$' . $column; + } else { + $colIndex = ($colIndex <= 127) ? $colIndex : $colIndex - 256; + $column = PHPExcel_Cell::stringFromColumnIndex($baseCol + $colIndex); + } + + // bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index) + if (!(0x8000 & self::_GetInt2d($cellAddressStructure, 2))) { + $row = '$' . $row; + } else { + $rowIndex = ($rowIndex <= 32767) ? $rowIndex : $rowIndex - 65536; + $row = $baseRow + $rowIndex; + } + + return $column . $row; + } + + + /** + * Reads a cell range address in BIFF5 e.g. 'A2:B6' or 'A1' + * always fixed range + * section 2.5.14 + * + * @param string $subData + * @return string + * @throws PHPExcel_Reader_Exception + */ + private function _readBIFF5CellRangeAddressFixed($subData) + { + // offset: 0; size: 2; index to first row + $fr = self::_GetInt2d($subData, 0) + 1; + + // offset: 2; size: 2; index to last row + $lr = self::_GetInt2d($subData, 2) + 1; + + // offset: 4; size: 1; index to first column + $fc = ord($subData{4}); + + // offset: 5; size: 1; index to last column + $lc = ord($subData{5}); + + // check values + if ($fr > $lr || $fc > $lc) { + throw new PHPExcel_Reader_Exception('Not a cell range address'); + } + + // column index to letter + $fc = PHPExcel_Cell::stringFromColumnIndex($fc); + $lc = PHPExcel_Cell::stringFromColumnIndex($lc); + + if ($fr == $lr and $fc == $lc) { + return "$fc$fr"; + } + return "$fc$fr:$lc$lr"; + } + + + /** + * Reads a cell range address in BIFF8 e.g. 'A2:B6' or 'A1' + * always fixed range + * section 2.5.14 + * + * @param string $subData + * @return string + * @throws PHPExcel_Reader_Exception + */ + private function _readBIFF8CellRangeAddressFixed($subData) + { + // offset: 0; size: 2; index to first row + $fr = self::_GetInt2d($subData, 0) + 1; + + // offset: 2; size: 2; index to last row + $lr = self::_GetInt2d($subData, 2) + 1; + + // offset: 4; size: 2; index to first column + $fc = self::_GetInt2d($subData, 4); + + // offset: 6; size: 2; index to last column + $lc = self::_GetInt2d($subData, 6); + + // check values + if ($fr > $lr || $fc > $lc) { + throw new PHPExcel_Reader_Exception('Not a cell range address'); + } + + // column index to letter + $fc = PHPExcel_Cell::stringFromColumnIndex($fc); + $lc = PHPExcel_Cell::stringFromColumnIndex($lc); + + if ($fr == $lr and $fc == $lc) { + return "$fc$fr"; + } + return "$fc$fr:$lc$lr"; + } + + + /** + * Reads a cell range address in BIFF8 e.g. 'A2:B6' or '$A$2:$B$6' + * there are flags indicating whether column/row index is relative + * section 3.3.4 + * + * @param string $subData + * @return string + */ + private function _readBIFF8CellRangeAddress($subData) + { + // todo: if cell range is just a single cell, should this funciton + // not just return e.g. 'A1' and not 'A1:A1' ? + + // offset: 0; size: 2; index to first row (0... 65535) (or offset (-32768... 32767)) + $fr = self::_GetInt2d($subData, 0) + 1; + + // offset: 2; size: 2; index to last row (0... 65535) (or offset (-32768... 32767)) + $lr = self::_GetInt2d($subData, 2) + 1; + + // offset: 4; size: 2; index to first column or column offset + relative flags + + // bit: 7-0; mask 0x00FF; column index + $fc = PHPExcel_Cell::stringFromColumnIndex(0x00FF & self::_GetInt2d($subData, 4)); + + // bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index) + if (!(0x4000 & self::_GetInt2d($subData, 4))) { + $fc = '$' . $fc; + } + + // bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index) + if (!(0x8000 & self::_GetInt2d($subData, 4))) { + $fr = '$' . $fr; + } + + // offset: 6; size: 2; index to last column or column offset + relative flags + + // bit: 7-0; mask 0x00FF; column index + $lc = PHPExcel_Cell::stringFromColumnIndex(0x00FF & self::_GetInt2d($subData, 6)); + + // bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index) + if (!(0x4000 & self::_GetInt2d($subData, 6))) { + $lc = '$' . $lc; + } + + // bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index) + if (!(0x8000 & self::_GetInt2d($subData, 6))) { + $lr = '$' . $lr; + } + + return "$fc$fr:$lc$lr"; + } + + + /** + * Reads a cell range address in BIFF8 for shared formulas. Uses positive and negative values for row and column + * to indicate offsets from a base cell + * section 3.3.4 + * + * @param string $subData + * @param string $baseCell Base cell + * @return string Cell range address + */ + private function _readBIFF8CellRangeAddressB($subData, $baseCell = 'A1') + { + list($baseCol, $baseRow) = PHPExcel_Cell::coordinateFromString($baseCell); + $baseCol = PHPExcel_Cell::columnIndexFromString($baseCol) - 1; + + // TODO: if cell range is just a single cell, should this funciton + // not just return e.g. 'A1' and not 'A1:A1' ? + + // offset: 0; size: 2; first row + $frIndex = self::_GetInt2d($subData, 0); // adjust below + + // offset: 2; size: 2; relative index to first row (0... 65535) should be treated as offset (-32768... 32767) + $lrIndex = self::_GetInt2d($subData, 2); // adjust below + + // offset: 4; size: 2; first column with relative/absolute flags + + // bit: 7-0; mask 0x00FF; column index + $fcIndex = 0x00FF & self::_GetInt2d($subData, 4); + + // bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index) + if (!(0x4000 & self::_GetInt2d($subData, 4))) { + // absolute column index + $fc = PHPExcel_Cell::stringFromColumnIndex($fcIndex); + $fc = '$' . $fc; + } else { + // column offset + $fcIndex = ($fcIndex <= 127) ? $fcIndex : $fcIndex - 256; + $fc = PHPExcel_Cell::stringFromColumnIndex($baseCol + $fcIndex); + } + + // bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index) + if (!(0x8000 & self::_GetInt2d($subData, 4))) { + // absolute row index + $fr = $frIndex + 1; + $fr = '$' . $fr; + } else { + // row offset + $frIndex = ($frIndex <= 32767) ? $frIndex : $frIndex - 65536; + $fr = $baseRow + $frIndex; + } + + // offset: 6; size: 2; last column with relative/absolute flags + + // bit: 7-0; mask 0x00FF; column index + $lcIndex = 0x00FF & self::_GetInt2d($subData, 6); + $lcIndex = ($lcIndex <= 127) ? $lcIndex : $lcIndex - 256; + $lc = PHPExcel_Cell::stringFromColumnIndex($baseCol + $lcIndex); + + // bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index) + if (!(0x4000 & self::_GetInt2d($subData, 6))) { + // absolute column index + $lc = PHPExcel_Cell::stringFromColumnIndex($lcIndex); + $lc = '$' . $lc; + } else { + // column offset + $lcIndex = ($lcIndex <= 127) ? $lcIndex : $lcIndex - 256; + $lc = PHPExcel_Cell::stringFromColumnIndex($baseCol + $lcIndex); + } + + // bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index) + if (!(0x8000 & self::_GetInt2d($subData, 6))) { + // absolute row index + $lr = $lrIndex + 1; + $lr = '$' . $lr; + } else { + // row offset + $lrIndex = ($lrIndex <= 32767) ? $lrIndex : $lrIndex - 65536; + $lr = $baseRow + $lrIndex; + } + + return "$fc$fr:$lc$lr"; + } + + + /** + * Read BIFF8 cell range address list + * section 2.5.15 + * + * @param string $subData + * @return array + */ + private function _readBIFF8CellRangeAddressList($subData) + { + $cellRangeAddresses = array(); + + // offset: 0; size: 2; number of the following cell range addresses + $nm = self::_GetInt2d($subData, 0); + + $offset = 2; + // offset: 2; size: 8 * $nm; list of $nm (fixed) cell range addresses + for ($i = 0; $i < $nm; ++$i) { + $cellRangeAddresses[] = $this->_readBIFF8CellRangeAddressFixed(substr($subData, $offset, 8)); + $offset += 8; + } + + return array( + 'size' => 2 + 8 * $nm, + 'cellRangeAddresses' => $cellRangeAddresses, + ); + } + + + /** + * Read BIFF5 cell range address list + * section 2.5.15 + * + * @param string $subData + * @return array + */ + private function _readBIFF5CellRangeAddressList($subData) + { + $cellRangeAddresses = array(); + + // offset: 0; size: 2; number of the following cell range addresses + $nm = self::_GetInt2d($subData, 0); + + $offset = 2; + // offset: 2; size: 6 * $nm; list of $nm (fixed) cell range addresses + for ($i = 0; $i < $nm; ++$i) { + $cellRangeAddresses[] = $this->_readBIFF5CellRangeAddressFixed(substr($subData, $offset, 6)); + $offset += 6; + } + + return array( + 'size' => 2 + 6 * $nm, + 'cellRangeAddresses' => $cellRangeAddresses, + ); + } + + + /** + * Get a sheet range like Sheet1:Sheet3 from REF index + * Note: If there is only one sheet in the range, one gets e.g Sheet1 + * It can also happen that the REF structure uses the -1 (FFFF) code to indicate deleted sheets, + * in which case an PHPExcel_Reader_Exception is thrown + * + * @param int $index + * @return string|false + * @throws PHPExcel_Reader_Exception + */ + private function _readSheetRangeByRefIndex($index) + { + if (isset($this->_ref[$index])) { + + $type = $this->_externalBooks[$this->_ref[$index]['externalBookIndex']]['type']; + + switch ($type) { + case 'internal': + // check if we have a deleted 3d reference + if ($this->_ref[$index]['firstSheetIndex'] == 0xFFFF or $this->_ref[$index]['lastSheetIndex'] == 0xFFFF) { + throw new PHPExcel_Reader_Exception('Deleted sheet reference'); + } + + // we have normal sheet range (collapsed or uncollapsed) + $firstSheetName = $this->_sheets[$this->_ref[$index]['firstSheetIndex']]['name']; + $lastSheetName = $this->_sheets[$this->_ref[$index]['lastSheetIndex']]['name']; + + if ($firstSheetName == $lastSheetName) { + // collapsed sheet range + $sheetRange = $firstSheetName; + } else { + $sheetRange = "$firstSheetName:$lastSheetName"; + } + + // escape the single-quotes + $sheetRange = str_replace("'", "''", $sheetRange); + + // if there are special characters, we need to enclose the range in single-quotes + // todo: check if we have identified the whole set of special characters + // it seems that the following characters are not accepted for sheet names + // and we may assume that they are not present: []*/:\? + if (preg_match("/[ !\"@#£$%&{()}<>=+'|^,;-]/", $sheetRange)) { + $sheetRange = "'$sheetRange'"; + } + + return $sheetRange; + break; + + default: + // TODO: external sheet support + throw new PHPExcel_Reader_Exception('Excel5 reader only supports internal sheets in fomulas'); + break; + } + } + return false; + } + + + /** + * read BIFF8 constant value array from array data + * returns e.g. array('value' => '{1,2;3,4}', 'size' => 40} + * section 2.5.8 + * + * @param string $arrayData + * @return array + */ + private static function _readBIFF8ConstantArray($arrayData) + { + // offset: 0; size: 1; number of columns decreased by 1 + $nc = ord($arrayData[0]); + + // offset: 1; size: 2; number of rows decreased by 1 + $nr = self::_GetInt2d($arrayData, 1); + $size = 3; // initialize + $arrayData = substr($arrayData, 3); + + // offset: 3; size: var; list of ($nc + 1) * ($nr + 1) constant values + $matrixChunks = array(); + for ($r = 1; $r <= $nr + 1; ++$r) { + $items = array(); + for ($c = 1; $c <= $nc + 1; ++$c) { + $constant = self::_readBIFF8Constant($arrayData); + $items[] = $constant['value']; + $arrayData = substr($arrayData, $constant['size']); + $size += $constant['size']; + } + $matrixChunks[] = implode(',', $items); // looks like e.g. '1,"hello"' + } + $matrix = '{' . implode(';', $matrixChunks) . '}'; + + return array( + 'value' => $matrix, + 'size' => $size, + ); + } + + + /** + * read BIFF8 constant value which may be 'Empty Value', 'Number', 'String Value', 'Boolean Value', 'Error Value' + * section 2.5.7 + * returns e.g. array('value' => '5', 'size' => 9) + * + * @param string $valueData + * @return array + */ + private static function _readBIFF8Constant($valueData) + { + // offset: 0; size: 1; identifier for type of constant + $identifier = ord($valueData[0]); + + switch ($identifier) { + case 0x00: // empty constant (what is this?) + $value = ''; + $size = 9; + break; + case 0x01: // number + // offset: 1; size: 8; IEEE 754 floating-point value + $value = self::_extractNumber(substr($valueData, 1, 8)); + $size = 9; + break; + case 0x02: // string value + // offset: 1; size: var; Unicode string, 16-bit string length + $string = self::_readUnicodeStringLong(substr($valueData, 1)); + $value = '"' . $string['value'] . '"'; + $size = 1 + $string['size']; + break; + case 0x04: // boolean + // offset: 1; size: 1; 0 = FALSE, 1 = TRUE + if (ord($valueData[1])) { + $value = 'TRUE'; + } else { + $value = 'FALSE'; + } + $size = 9; + break; + case 0x10: // error code + // offset: 1; size: 1; error code + $value = self::_mapErrorCode(ord($valueData[1])); + $size = 9; + break; + } + return array( + 'value' => $value, + 'size' => $size, + ); + } + + + /** + * Extract RGB color + * OpenOffice.org's Documentation of the Microsoft Excel File Format, section 2.5.4 + * + * @param string $rgb Encoded RGB value (4 bytes) + * @return array + */ + private static function _readRGB($rgb) + { + // offset: 0; size 1; Red component + $r = ord($rgb{0}); + + // offset: 1; size: 1; Green component + $g = ord($rgb{1}); + + // offset: 2; size: 1; Blue component + $b = ord($rgb{2}); + + // HEX notation, e.g. 'FF00FC' + $rgb = sprintf('%02X%02X%02X', $r, $g, $b); + + return array('rgb' => $rgb); + } + + + /** + * Read byte string (8-bit string length) + * OpenOffice documentation: 2.5.2 + * + * @param string $subData + * @return array + */ + private function _readByteStringShort($subData) + { + // offset: 0; size: 1; length of the string (character count) + $ln = ord($subData[0]); + + // offset: 1: size: var; character array (8-bit characters) + $value = $this->_decodeCodepage(substr($subData, 1, $ln)); + + return array( + 'value' => $value, + 'size' => 1 + $ln, // size in bytes of data structure + ); + } + + + /** + * Read byte string (16-bit string length) + * OpenOffice documentation: 2.5.2 + * + * @param string $subData + * @return array + */ + private function _readByteStringLong($subData) + { + // offset: 0; size: 2; length of the string (character count) + $ln = self::_GetInt2d($subData, 0); + + // offset: 2: size: var; character array (8-bit characters) + $value = $this->_decodeCodepage(substr($subData, 2)); + + //return $string; + return array( + 'value' => $value, + 'size' => 2 + $ln, // size in bytes of data structure + ); + } + + + /** + * Extracts an Excel Unicode short string (8-bit string length) + * OpenOffice documentation: 2.5.3 + * function will automatically find out where the Unicode string ends. + * + * @param string $subData + * @return array + */ + private static function _readUnicodeStringShort($subData) + { + $value = ''; + + // offset: 0: size: 1; length of the string (character count) + $characterCount = ord($subData[0]); + + $string = self::_readUnicodeString(substr($subData, 1), $characterCount); + + // add 1 for the string length + $string['size'] += 1; + + return $string; + } + + + /** + * Extracts an Excel Unicode long string (16-bit string length) + * OpenOffice documentation: 2.5.3 + * this function is under construction, needs to support rich text, and Asian phonetic settings + * + * @param string $subData + * @return array + */ + private static function _readUnicodeStringLong($subData) + { + $value = ''; + + // offset: 0: size: 2; length of the string (character count) + $characterCount = self::_GetInt2d($subData, 0); + + $string = self::_readUnicodeString(substr($subData, 2), $characterCount); + + // add 2 for the string length + $string['size'] += 2; + + return $string; + } + + + /** + * Read Unicode string with no string length field, but with known character count + * this function is under construction, needs to support rich text, and Asian phonetic settings + * OpenOffice.org's Documentation of the Microsoft Excel File Format, section 2.5.3 + * + * @param string $subData + * @param int $characterCount + * @return array + */ + private static function _readUnicodeString($subData, $characterCount) + { + $value = ''; + + // offset: 0: size: 1; option flags + + // bit: 0; mask: 0x01; character compression (0 = compressed 8-bit, 1 = uncompressed 16-bit) + $isCompressed = !((0x01 & ord($subData[0])) >> 0); + + // bit: 2; mask: 0x04; Asian phonetic settings + $hasAsian = (0x04) & ord($subData[0]) >> 2; + + // bit: 3; mask: 0x08; Rich-Text settings + $hasRichText = (0x08) & ord($subData[0]) >> 3; + + // offset: 1: size: var; character array + // this offset assumes richtext and Asian phonetic settings are off which is generally wrong + // needs to be fixed + $value = self::_encodeUTF16(substr($subData, 1, $isCompressed ? $characterCount : 2 * $characterCount), $isCompressed); + + return array( + 'value' => $value, + 'size' => $isCompressed ? 1 + $characterCount : 1 + 2 * $characterCount, // the size in bytes including the option flags + ); + } + + + /** + * Convert UTF-8 string to string surounded by double quotes. Used for explicit string tokens in formulas. + * Example: hello"world --> "hello""world" + * + * @param string $value UTF-8 encoded string + * @return string + */ + private static function _UTF8toExcelDoubleQuoted($value) + { + return '"' . str_replace('"', '""', $value) . '"'; + } + + + /** + * Reads first 8 bytes of a string and return IEEE 754 float + * + * @param string $data Binary string that is at least 8 bytes long + * @return float + */ + private static function _extractNumber($data) + { + $rknumhigh = self::_GetInt4d($data, 4); + $rknumlow = self::_GetInt4d($data, 0); + $sign = ($rknumhigh & 0x80000000) >> 31; + $exp = (($rknumhigh & 0x7ff00000) >> 20) - 1023; + $mantissa = (0x100000 | ($rknumhigh & 0x000fffff)); + $mantissalow1 = ($rknumlow & 0x80000000) >> 31; + $mantissalow2 = ($rknumlow & 0x7fffffff); + $value = $mantissa / pow( 2 , (20 - $exp)); + + if ($mantissalow1 != 0) { + $value += 1 / pow (2 , (21 - $exp)); + } + + $value += $mantissalow2 / pow (2 , (52 - $exp)); + if ($sign) { + $value *= -1; + } + + return $value; + } + + + private static function _GetIEEE754($rknum) + { + if (($rknum & 0x02) != 0) { + $value = $rknum >> 2; + } else { + // changes by mmp, info on IEEE754 encoding from + // research.microsoft.com/~hollasch/cgindex/coding/ieeefloat.html + // The RK format calls for using only the most significant 30 bits + // of the 64 bit floating point value. The other 34 bits are assumed + // to be 0 so we use the upper 30 bits of $rknum as follows... + $sign = ($rknum & 0x80000000) >> 31; + $exp = ($rknum & 0x7ff00000) >> 20; + $mantissa = (0x100000 | ($rknum & 0x000ffffc)); + $value = $mantissa / pow( 2 , (20- ($exp - 1023))); + if ($sign) { + $value = -1 * $value; + } + //end of changes by mmp + } + if (($rknum & 0x01) != 0) { + $value /= 100; + } + return $value; + } + + + /** + * Get UTF-8 string from (compressed or uncompressed) UTF-16 string + * + * @param string $string + * @param bool $compressed + * @return string + */ + private static function _encodeUTF16($string, $compressed = '') + { + if ($compressed) { + $string = self::_uncompressByteString($string); + } + + return PHPExcel_Shared_String::ConvertEncoding($string, 'UTF-8', 'UTF-16LE'); + } + + + /** + * Convert UTF-16 string in compressed notation to uncompressed form. Only used for BIFF8. + * + * @param string $string + * @return string + */ + private static function _uncompressByteString($string) + { + $uncompressedString = ''; + $strLen = strlen($string); + for ($i = 0; $i < $strLen; ++$i) { + $uncompressedString .= $string[$i] . "\0"; + } + + return $uncompressedString; + } + + + /** + * Convert string to UTF-8. Only used for BIFF5. + * + * @param string $string + * @return string + */ + private function _decodeCodepage($string) + { + return PHPExcel_Shared_String::ConvertEncoding($string, 'UTF-8', $this->_codepage); + } + + + /** + * Read 16-bit unsigned integer + * + * @param string $data + * @param int $pos + * @return int + */ + public static function _GetInt2d($data, $pos) + { + return ord($data[$pos]) | (ord($data[$pos+1]) << 8); + } + + + /** + * Read 32-bit signed integer + * + * @param string $data + * @param int $pos + * @return int + */ + public static function _GetInt4d($data, $pos) + { + // FIX: represent numbers correctly on 64-bit system + // http://sourceforge.net/tracker/index.php?func=detail&aid=1487372&group_id=99160&atid=623334 + // Hacked by Andreas Rehm 2006 to ensure correct result of the <<24 block on 32 and 64bit systems + $_or_24 = ord($data[$pos + 3]); + if ($_or_24 >= 128) { + // negative number + $_ord_24 = -abs((256 - $_or_24) << 24); + } else { + $_ord_24 = ($_or_24 & 127) << 24; + } + return ord($data[$pos]) | (ord($data[$pos+1]) << 8) | (ord($data[$pos+2]) << 16) | $_ord_24; + } + + + /** + * Read color + * + * @param int $color Indexed color + * @param array $palette Color palette + * @return array RGB color value, example: array('rgb' => 'FF0000') + */ + private static function _readColor($color,$palette,$version) + { + if ($color <= 0x07 || $color >= 0x40) { + // special built-in color + return self::_mapBuiltInColor($color); + } elseif (isset($palette) && isset($palette[$color - 8])) { + // palette color, color index 0x08 maps to pallete index 0 + return $palette[$color - 8]; + } else { + // default color table + if ($version == self::XLS_BIFF8) { + return self::_mapColor($color); + } else { + // BIFF5 + return self::_mapColorBIFF5($color); + } + } + + return $color; + } + + + /** + * Map border style + * OpenOffice documentation: 2.5.11 + * + * @param int $index + * @return string + */ + private static function _mapBorderStyle($index) + { + switch ($index) { + case 0x00: return PHPExcel_Style_Border::BORDER_NONE; + case 0x01: return PHPExcel_Style_Border::BORDER_THIN; + case 0x02: return PHPExcel_Style_Border::BORDER_MEDIUM; + case 0x03: return PHPExcel_Style_Border::BORDER_DASHED; + case 0x04: return PHPExcel_Style_Border::BORDER_DOTTED; + case 0x05: return PHPExcel_Style_Border::BORDER_THICK; + case 0x06: return PHPExcel_Style_Border::BORDER_DOUBLE; + case 0x07: return PHPExcel_Style_Border::BORDER_HAIR; + case 0x08: return PHPExcel_Style_Border::BORDER_MEDIUMDASHED; + case 0x09: return PHPExcel_Style_Border::BORDER_DASHDOT; + case 0x0A: return PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT; + case 0x0B: return PHPExcel_Style_Border::BORDER_DASHDOTDOT; + case 0x0C: return PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT; + case 0x0D: return PHPExcel_Style_Border::BORDER_SLANTDASHDOT; + default: return PHPExcel_Style_Border::BORDER_NONE; + } + } + + + /** + * Get fill pattern from index + * OpenOffice documentation: 2.5.12 + * + * @param int $index + * @return string + */ + private static function _mapFillPattern($index) + { + switch ($index) { + case 0x00: return PHPExcel_Style_Fill::FILL_NONE; + case 0x01: return PHPExcel_Style_Fill::FILL_SOLID; + case 0x02: return PHPExcel_Style_Fill::FILL_PATTERN_MEDIUMGRAY; + case 0x03: return PHPExcel_Style_Fill::FILL_PATTERN_DARKGRAY; + case 0x04: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRAY; + case 0x05: return PHPExcel_Style_Fill::FILL_PATTERN_DARKHORIZONTAL; + case 0x06: return PHPExcel_Style_Fill::FILL_PATTERN_DARKVERTICAL; + case 0x07: return PHPExcel_Style_Fill::FILL_PATTERN_DARKDOWN; + case 0x08: return PHPExcel_Style_Fill::FILL_PATTERN_DARKUP; + case 0x09: return PHPExcel_Style_Fill::FILL_PATTERN_DARKGRID; + case 0x0A: return PHPExcel_Style_Fill::FILL_PATTERN_DARKTRELLIS; + case 0x0B: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTHORIZONTAL; + case 0x0C: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTVERTICAL; + case 0x0D: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTDOWN; + case 0x0E: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTUP; + case 0x0F: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRID; + case 0x10: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTTRELLIS; + case 0x11: return PHPExcel_Style_Fill::FILL_PATTERN_GRAY125; + case 0x12: return PHPExcel_Style_Fill::FILL_PATTERN_GRAY0625; + default: return PHPExcel_Style_Fill::FILL_NONE; + } + } + + + /** + * Map error code, e.g. '#N/A' + * + * @param int $subData + * @return string + */ + private static function _mapErrorCode($subData) + { + switch ($subData) { + case 0x00: return '#NULL!'; break; + case 0x07: return '#DIV/0!'; break; + case 0x0F: return '#VALUE!'; break; + case 0x17: return '#REF!'; break; + case 0x1D: return '#NAME?'; break; + case 0x24: return '#NUM!'; break; + case 0x2A: return '#N/A'; break; + default: return false; + } + } + + + /** + * Map built-in color to RGB value + * + * @param int $color Indexed color + * @return array + */ + private static function _mapBuiltInColor($color) + { + switch ($color) { + case 0x00: return array('rgb' => '000000'); + case 0x01: return array('rgb' => 'FFFFFF'); + case 0x02: return array('rgb' => 'FF0000'); + case 0x03: return array('rgb' => '00FF00'); + case 0x04: return array('rgb' => '0000FF'); + case 0x05: return array('rgb' => 'FFFF00'); + case 0x06: return array('rgb' => 'FF00FF'); + case 0x07: return array('rgb' => '00FFFF'); + case 0x40: return array('rgb' => '000000'); // system window text color + case 0x41: return array('rgb' => 'FFFFFF'); // system window background color + default: return array('rgb' => '000000'); + } + } + + + /** + * Map color array from BIFF5 built-in color index + * + * @param int $subData + * @return array + */ + private static function _mapColorBIFF5($subData) + { + switch ($subData) { + case 0x08: return array('rgb' => '000000'); + case 0x09: return array('rgb' => 'FFFFFF'); + case 0x0A: return array('rgb' => 'FF0000'); + case 0x0B: return array('rgb' => '00FF00'); + case 0x0C: return array('rgb' => '0000FF'); + case 0x0D: return array('rgb' => 'FFFF00'); + case 0x0E: return array('rgb' => 'FF00FF'); + case 0x0F: return array('rgb' => '00FFFF'); + case 0x10: return array('rgb' => '800000'); + case 0x11: return array('rgb' => '008000'); + case 0x12: return array('rgb' => '000080'); + case 0x13: return array('rgb' => '808000'); + case 0x14: return array('rgb' => '800080'); + case 0x15: return array('rgb' => '008080'); + case 0x16: return array('rgb' => 'C0C0C0'); + case 0x17: return array('rgb' => '808080'); + case 0x18: return array('rgb' => '8080FF'); + case 0x19: return array('rgb' => '802060'); + case 0x1A: return array('rgb' => 'FFFFC0'); + case 0x1B: return array('rgb' => 'A0E0F0'); + case 0x1C: return array('rgb' => '600080'); + case 0x1D: return array('rgb' => 'FF8080'); + case 0x1E: return array('rgb' => '0080C0'); + case 0x1F: return array('rgb' => 'C0C0FF'); + case 0x20: return array('rgb' => '000080'); + case 0x21: return array('rgb' => 'FF00FF'); + case 0x22: return array('rgb' => 'FFFF00'); + case 0x23: return array('rgb' => '00FFFF'); + case 0x24: return array('rgb' => '800080'); + case 0x25: return array('rgb' => '800000'); + case 0x26: return array('rgb' => '008080'); + case 0x27: return array('rgb' => '0000FF'); + case 0x28: return array('rgb' => '00CFFF'); + case 0x29: return array('rgb' => '69FFFF'); + case 0x2A: return array('rgb' => 'E0FFE0'); + case 0x2B: return array('rgb' => 'FFFF80'); + case 0x2C: return array('rgb' => 'A6CAF0'); + case 0x2D: return array('rgb' => 'DD9CB3'); + case 0x2E: return array('rgb' => 'B38FEE'); + case 0x2F: return array('rgb' => 'E3E3E3'); + case 0x30: return array('rgb' => '2A6FF9'); + case 0x31: return array('rgb' => '3FB8CD'); + case 0x32: return array('rgb' => '488436'); + case 0x33: return array('rgb' => '958C41'); + case 0x34: return array('rgb' => '8E5E42'); + case 0x35: return array('rgb' => 'A0627A'); + case 0x36: return array('rgb' => '624FAC'); + case 0x37: return array('rgb' => '969696'); + case 0x38: return array('rgb' => '1D2FBE'); + case 0x39: return array('rgb' => '286676'); + case 0x3A: return array('rgb' => '004500'); + case 0x3B: return array('rgb' => '453E01'); + case 0x3C: return array('rgb' => '6A2813'); + case 0x3D: return array('rgb' => '85396A'); + case 0x3E: return array('rgb' => '4A3285'); + case 0x3F: return array('rgb' => '424242'); + default: return array('rgb' => '000000'); + } + } + + + /** + * Map color array from BIFF8 built-in color index + * + * @param int $subData + * @return array + */ + private static function _mapColor($subData) + { + switch ($subData) { + case 0x08: return array('rgb' => '000000'); + case 0x09: return array('rgb' => 'FFFFFF'); + case 0x0A: return array('rgb' => 'FF0000'); + case 0x0B: return array('rgb' => '00FF00'); + case 0x0C: return array('rgb' => '0000FF'); + case 0x0D: return array('rgb' => 'FFFF00'); + case 0x0E: return array('rgb' => 'FF00FF'); + case 0x0F: return array('rgb' => '00FFFF'); + case 0x10: return array('rgb' => '800000'); + case 0x11: return array('rgb' => '008000'); + case 0x12: return array('rgb' => '000080'); + case 0x13: return array('rgb' => '808000'); + case 0x14: return array('rgb' => '800080'); + case 0x15: return array('rgb' => '008080'); + case 0x16: return array('rgb' => 'C0C0C0'); + case 0x17: return array('rgb' => '808080'); + case 0x18: return array('rgb' => '9999FF'); + case 0x19: return array('rgb' => '993366'); + case 0x1A: return array('rgb' => 'FFFFCC'); + case 0x1B: return array('rgb' => 'CCFFFF'); + case 0x1C: return array('rgb' => '660066'); + case 0x1D: return array('rgb' => 'FF8080'); + case 0x1E: return array('rgb' => '0066CC'); + case 0x1F: return array('rgb' => 'CCCCFF'); + case 0x20: return array('rgb' => '000080'); + case 0x21: return array('rgb' => 'FF00FF'); + case 0x22: return array('rgb' => 'FFFF00'); + case 0x23: return array('rgb' => '00FFFF'); + case 0x24: return array('rgb' => '800080'); + case 0x25: return array('rgb' => '800000'); + case 0x26: return array('rgb' => '008080'); + case 0x27: return array('rgb' => '0000FF'); + case 0x28: return array('rgb' => '00CCFF'); + case 0x29: return array('rgb' => 'CCFFFF'); + case 0x2A: return array('rgb' => 'CCFFCC'); + case 0x2B: return array('rgb' => 'FFFF99'); + case 0x2C: return array('rgb' => '99CCFF'); + case 0x2D: return array('rgb' => 'FF99CC'); + case 0x2E: return array('rgb' => 'CC99FF'); + case 0x2F: return array('rgb' => 'FFCC99'); + case 0x30: return array('rgb' => '3366FF'); + case 0x31: return array('rgb' => '33CCCC'); + case 0x32: return array('rgb' => '99CC00'); + case 0x33: return array('rgb' => 'FFCC00'); + case 0x34: return array('rgb' => 'FF9900'); + case 0x35: return array('rgb' => 'FF6600'); + case 0x36: return array('rgb' => '666699'); + case 0x37: return array('rgb' => '969696'); + case 0x38: return array('rgb' => '003366'); + case 0x39: return array('rgb' => '339966'); + case 0x3A: return array('rgb' => '003300'); + case 0x3B: return array('rgb' => '333300'); + case 0x3C: return array('rgb' => '993300'); + case 0x3D: return array('rgb' => '993366'); + case 0x3E: return array('rgb' => '333399'); + case 0x3F: return array('rgb' => '333333'); + default: return array('rgb' => '000000'); + } + } + + + private function _parseRichText($is = '') { + $value = new PHPExcel_RichText(); + + $value->createText($is); + + return $value; + } + +} diff --git a/lib/phpexcel/PHPExcel/Reader/Excel5/Escher.php b/lib/phpexcel/PHPExcel/Reader/Excel5/Escher.php new file mode 100644 index 0000000..3ed82c6 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Reader/Excel5/Escher.php @@ -0,0 +1,640 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Reader_Excel5 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + +/** + * PHPExcel_Reader_Excel5_Escher + * + * @category PHPExcel + * @package PHPExcel_Reader_Excel5 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Reader_Excel5_Escher +{ + const DGGCONTAINER = 0xF000; + const BSTORECONTAINER = 0xF001; + const DGCONTAINER = 0xF002; + const SPGRCONTAINER = 0xF003; + const SPCONTAINER = 0xF004; + const DGG = 0xF006; + const BSE = 0xF007; + const DG = 0xF008; + const SPGR = 0xF009; + const SP = 0xF00A; + const OPT = 0xF00B; + const CLIENTTEXTBOX = 0xF00D; + const CLIENTANCHOR = 0xF010; + const CLIENTDATA = 0xF011; + const BLIPJPEG = 0xF01D; + const BLIPPNG = 0xF01E; + const SPLITMENUCOLORS = 0xF11E; + const TERTIARYOPT = 0xF122; + + /** + * Escher stream data (binary) + * + * @var string + */ + private $_data; + + /** + * Size in bytes of the Escher stream data + * + * @var int + */ + private $_dataSize; + + /** + * Current position of stream pointer in Escher stream data + * + * @var int + */ + private $_pos; + + /** + * The object to be returned by the reader. Modified during load. + * + * @var mixed + */ + private $_object; + + /** + * Create a new PHPExcel_Reader_Excel5_Escher instance + * + * @param mixed $object + */ + public function __construct($object) + { + $this->_object = $object; + } + + /** + * Load Escher stream data. May be a partial Escher stream. + * + * @param string $data + */ + public function load($data) + { + $this->_data = $data; + + // total byte size of Excel data (workbook global substream + sheet substreams) + $this->_dataSize = strlen($this->_data); + + $this->_pos = 0; + + // Parse Escher stream + while ($this->_pos < $this->_dataSize) { + + // offset: 2; size: 2: Record Type + $fbt = PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos + 2); + + switch ($fbt) { + case self::DGGCONTAINER: $this->_readDggContainer(); break; + case self::DGG: $this->_readDgg(); break; + case self::BSTORECONTAINER: $this->_readBstoreContainer(); break; + case self::BSE: $this->_readBSE(); break; + case self::BLIPJPEG: $this->_readBlipJPEG(); break; + case self::BLIPPNG: $this->_readBlipPNG(); break; + case self::OPT: $this->_readOPT(); break; + case self::TERTIARYOPT: $this->_readTertiaryOPT(); break; + case self::SPLITMENUCOLORS: $this->_readSplitMenuColors(); break; + case self::DGCONTAINER: $this->_readDgContainer(); break; + case self::DG: $this->_readDg(); break; + case self::SPGRCONTAINER: $this->_readSpgrContainer(); break; + case self::SPCONTAINER: $this->_readSpContainer(); break; + case self::SPGR: $this->_readSpgr(); break; + case self::SP: $this->_readSp(); break; + case self::CLIENTTEXTBOX: $this->_readClientTextbox(); break; + case self::CLIENTANCHOR: $this->_readClientAnchor(); break; + case self::CLIENTDATA: $this->_readClientData(); break; + default: $this->_readDefault(); break; + } + } + + return $this->_object; + } + + /** + * Read a generic record + */ + private function _readDefault() + { + // offset 0; size: 2; recVer and recInstance + $verInstance = PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos); + + // offset: 2; size: 2: Record Type + $fbt = PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos + 2); + + // bit: 0-3; mask: 0x000F; recVer + $recVer = (0x000F & $verInstance) >> 0; + + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + } + + /** + * Read DggContainer record (Drawing Group Container) + */ + private function _readDggContainer() + { + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + + // record is a container, read contents + $dggContainer = new PHPExcel_Shared_Escher_DggContainer(); + $this->_object->setDggContainer($dggContainer); + $reader = new PHPExcel_Reader_Excel5_Escher($dggContainer); + $reader->load($recordData); + } + + /** + * Read Dgg record (Drawing Group) + */ + private function _readDgg() + { + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + } + + /** + * Read BstoreContainer record (Blip Store Container) + */ + private function _readBstoreContainer() + { + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + + // record is a container, read contents + $bstoreContainer = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer(); + $this->_object->setBstoreContainer($bstoreContainer); + $reader = new PHPExcel_Reader_Excel5_Escher($bstoreContainer); + $reader->load($recordData); + } + + /** + * Read BSE record + */ + private function _readBSE() + { + // offset: 0; size: 2; recVer and recInstance + + // bit: 4-15; mask: 0xFFF0; recInstance + $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4; + + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + + // add BSE to BstoreContainer + $BSE = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE(); + $this->_object->addBSE($BSE); + + $BSE->setBLIPType($recInstance); + + // offset: 0; size: 1; btWin32 (MSOBLIPTYPE) + $btWin32 = ord($recordData[0]); + + // offset: 1; size: 1; btWin32 (MSOBLIPTYPE) + $btMacOS = ord($recordData[1]); + + // offset: 2; size: 16; MD4 digest + $rgbUid = substr($recordData, 2, 16); + + // offset: 18; size: 2; tag + $tag = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 18); + + // offset: 20; size: 4; size of BLIP in bytes + $size = PHPExcel_Reader_Excel5::_GetInt4d($recordData, 20); + + // offset: 24; size: 4; number of references to this BLIP + $cRef = PHPExcel_Reader_Excel5::_GetInt4d($recordData, 24); + + // offset: 28; size: 4; MSOFO file offset + $foDelay = PHPExcel_Reader_Excel5::_GetInt4d($recordData, 28); + + // offset: 32; size: 1; unused1 + $unused1 = ord($recordData{32}); + + // offset: 33; size: 1; size of nameData in bytes (including null terminator) + $cbName = ord($recordData{33}); + + // offset: 34; size: 1; unused2 + $unused2 = ord($recordData{34}); + + // offset: 35; size: 1; unused3 + $unused3 = ord($recordData{35}); + + // offset: 36; size: $cbName; nameData + $nameData = substr($recordData, 36, $cbName); + + // offset: 36 + $cbName, size: var; the BLIP data + $blipData = substr($recordData, 36 + $cbName); + + // record is a container, read contents + $reader = new PHPExcel_Reader_Excel5_Escher($BSE); + $reader->load($blipData); + } + + /** + * Read BlipJPEG record. Holds raw JPEG image data + */ + private function _readBlipJPEG() + { + // offset: 0; size: 2; recVer and recInstance + + // bit: 4-15; mask: 0xFFF0; recInstance + $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4; + + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + + $pos = 0; + + // offset: 0; size: 16; rgbUid1 (MD4 digest of) + $rgbUid1 = substr($recordData, 0, 16); + $pos += 16; + + // offset: 16; size: 16; rgbUid2 (MD4 digest), only if $recInstance = 0x46B or 0x6E3 + if (in_array($recInstance, array(0x046B, 0x06E3))) { + $rgbUid2 = substr($recordData, 16, 16); + $pos += 16; + } + + // offset: var; size: 1; tag + $tag = ord($recordData{$pos}); + $pos += 1; + + // offset: var; size: var; the raw image data + $data = substr($recordData, $pos); + + $blip = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip(); + $blip->setData($data); + + $this->_object->setBlip($blip); + } + + /** + * Read BlipPNG record. Holds raw PNG image data + */ + private function _readBlipPNG() + { + // offset: 0; size: 2; recVer and recInstance + + // bit: 4-15; mask: 0xFFF0; recInstance + $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4; + + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + + $pos = 0; + + // offset: 0; size: 16; rgbUid1 (MD4 digest of) + $rgbUid1 = substr($recordData, 0, 16); + $pos += 16; + + // offset: 16; size: 16; rgbUid2 (MD4 digest), only if $recInstance = 0x46B or 0x6E3 + if ($recInstance == 0x06E1) { + $rgbUid2 = substr($recordData, 16, 16); + $pos += 16; + } + + // offset: var; size: 1; tag + $tag = ord($recordData{$pos}); + $pos += 1; + + // offset: var; size: var; the raw image data + $data = substr($recordData, $pos); + + $blip = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip(); + $blip->setData($data); + + $this->_object->setBlip($blip); + } + + /** + * Read OPT record. This record may occur within DggContainer record or SpContainer + */ + private function _readOPT() + { + // offset: 0; size: 2; recVer and recInstance + + // bit: 4-15; mask: 0xFFF0; recInstance + $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4; + + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + + $this->_readOfficeArtRGFOPTE($recordData, $recInstance); + } + + /** + * Read TertiaryOPT record + */ + private function _readTertiaryOPT() + { + // offset: 0; size: 2; recVer and recInstance + + // bit: 4-15; mask: 0xFFF0; recInstance + $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4; + + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + } + + /** + * Read SplitMenuColors record + */ + private function _readSplitMenuColors() + { + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + } + + /** + * Read DgContainer record (Drawing Container) + */ + private function _readDgContainer() + { + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + + // record is a container, read contents + $dgContainer = new PHPExcel_Shared_Escher_DgContainer(); + $this->_object->setDgContainer($dgContainer); + $reader = new PHPExcel_Reader_Excel5_Escher($dgContainer); + $escher = $reader->load($recordData); + } + + /** + * Read Dg record (Drawing) + */ + private function _readDg() + { + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + } + + /** + * Read SpgrContainer record (Shape Group Container) + */ + private function _readSpgrContainer() + { + // context is either context DgContainer or SpgrContainer + + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + + // record is a container, read contents + $spgrContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer(); + + if ($this->_object instanceof PHPExcel_Shared_Escher_DgContainer) { + // DgContainer + $this->_object->setSpgrContainer($spgrContainer); + } else { + // SpgrContainer + $this->_object->addChild($spgrContainer); + } + + $reader = new PHPExcel_Reader_Excel5_Escher($spgrContainer); + $escher = $reader->load($recordData); + } + + /** + * Read SpContainer record (Shape Container) + */ + private function _readSpContainer() + { + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // add spContainer to spgrContainer + $spContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer(); + $this->_object->addChild($spContainer); + + // move stream pointer to next record + $this->_pos += 8 + $length; + + // record is a container, read contents + $reader = new PHPExcel_Reader_Excel5_Escher($spContainer); + $escher = $reader->load($recordData); + } + + /** + * Read Spgr record (Shape Group) + */ + private function _readSpgr() + { + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + } + + /** + * Read Sp record (Shape) + */ + private function _readSp() + { + // offset: 0; size: 2; recVer and recInstance + + // bit: 4-15; mask: 0xFFF0; recInstance + $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4; + + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + } + + /** + * Read ClientTextbox record + */ + private function _readClientTextbox() + { + // offset: 0; size: 2; recVer and recInstance + + // bit: 4-15; mask: 0xFFF0; recInstance + $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4; + + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + } + + /** + * Read ClientAnchor record. This record holds information about where the shape is anchored in worksheet + */ + private function _readClientAnchor() + { + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + + // offset: 2; size: 2; upper-left corner column index (0-based) + $c1 = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 2); + + // offset: 4; size: 2; upper-left corner horizontal offset in 1/1024 of column width + $startOffsetX = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 4); + + // offset: 6; size: 2; upper-left corner row index (0-based) + $r1 = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 6); + + // offset: 8; size: 2; upper-left corner vertical offset in 1/256 of row height + $startOffsetY = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 8); + + // offset: 10; size: 2; bottom-right corner column index (0-based) + $c2 = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 10); + + // offset: 12; size: 2; bottom-right corner horizontal offset in 1/1024 of column width + $endOffsetX = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 12); + + // offset: 14; size: 2; bottom-right corner row index (0-based) + $r2 = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 14); + + // offset: 16; size: 2; bottom-right corner vertical offset in 1/256 of row height + $endOffsetY = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 16); + + // set the start coordinates + $this->_object->setStartCoordinates(PHPExcel_Cell::stringFromColumnIndex($c1) . ($r1 + 1)); + + // set the start offsetX + $this->_object->setStartOffsetX($startOffsetX); + + // set the start offsetY + $this->_object->setStartOffsetY($startOffsetY); + + // set the end coordinates + $this->_object->setEndCoordinates(PHPExcel_Cell::stringFromColumnIndex($c2) . ($r2 + 1)); + + // set the end offsetX + $this->_object->setEndOffsetX($endOffsetX); + + // set the end offsetY + $this->_object->setEndOffsetY($endOffsetY); + } + + /** + * Read ClientData record + */ + private function _readClientData() + { + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + } + + /** + * Read OfficeArtRGFOPTE table of property-value pairs + * + * @param string $data Binary data + * @param int $n Number of properties + */ + private function _readOfficeArtRGFOPTE($data, $n) { + + $splicedComplexData = substr($data, 6 * $n); + + // loop through property-value pairs + for ($i = 0; $i < $n; ++$i) { + // read 6 bytes at a time + $fopte = substr($data, 6 * $i, 6); + + // offset: 0; size: 2; opid + $opid = PHPExcel_Reader_Excel5::_GetInt2d($fopte, 0); + + // bit: 0-13; mask: 0x3FFF; opid.opid + $opidOpid = (0x3FFF & $opid) >> 0; + + // bit: 14; mask 0x4000; 1 = value in op field is BLIP identifier + $opidFBid = (0x4000 & $opid) >> 14; + + // bit: 15; mask 0x8000; 1 = this is a complex property, op field specifies size of complex data + $opidFComplex = (0x8000 & $opid) >> 15; + + // offset: 2; size: 4; the value for this property + $op = PHPExcel_Reader_Excel5::_GetInt4d($fopte, 2); + + if ($opidFComplex) { + $complexData = substr($splicedComplexData, 0, $op); + $splicedComplexData = substr($splicedComplexData, $op); + + // we store string value with complex data + $value = $complexData; + } else { + // we store integer value + $value = $op; + } + + $this->_object->setOPT($opidOpid, $value); + } + } + +} diff --git a/lib/phpexcel/PHPExcel/Reader/Excel5/MD5.php b/lib/phpexcel/PHPExcel/Reader/Excel5/MD5.php new file mode 100644 index 0000000..946d5a0 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Reader/Excel5/MD5.php @@ -0,0 +1,221 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Reader_Excel5 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Reader_Excel5_MD5 + * + * @category PHPExcel + * @package PHPExcel_Reader_Excel5 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Reader_Excel5_MD5 +{ + // Context + private $a; + private $b; + private $c; + private $d; + + + /** + * MD5 stream constructor + */ + public function __construct() + { + $this->reset(); + } + + + /** + * Reset the MD5 stream context + */ + public function reset() + { + $this->a = 0x67452301; + $this->b = 0xEFCDAB89; + $this->c = 0x98BADCFE; + $this->d = 0x10325476; + } + + + /** + * Get MD5 stream context + * + * @return string + */ + public function getContext() + { + $s = ''; + foreach (array('a', 'b', 'c', 'd') as $i) { + $v = $this->{$i}; + $s .= chr($v & 0xff); + $s .= chr(($v >> 8) & 0xff); + $s .= chr(($v >> 16) & 0xff); + $s .= chr(($v >> 24) & 0xff); + } + + return $s; + } + + + /** + * Add data to context + * + * @param string $data Data to add + */ + public function add($data) + { + $words = array_values(unpack('V16', $data)); + + $A = $this->a; + $B = $this->b; + $C = $this->c; + $D = $this->d; + + $F = array('PHPExcel_Reader_Excel5_MD5','F'); + $G = array('PHPExcel_Reader_Excel5_MD5','G'); + $H = array('PHPExcel_Reader_Excel5_MD5','H'); + $I = array('PHPExcel_Reader_Excel5_MD5','I'); + + /* ROUND 1 */ + self::step($F, $A, $B, $C, $D, $words[0], 7, 0xd76aa478); + self::step($F, $D, $A, $B, $C, $words[1], 12, 0xe8c7b756); + self::step($F, $C, $D, $A, $B, $words[2], 17, 0x242070db); + self::step($F, $B, $C, $D, $A, $words[3], 22, 0xc1bdceee); + self::step($F, $A, $B, $C, $D, $words[4], 7, 0xf57c0faf); + self::step($F, $D, $A, $B, $C, $words[5], 12, 0x4787c62a); + self::step($F, $C, $D, $A, $B, $words[6], 17, 0xa8304613); + self::step($F, $B, $C, $D, $A, $words[7], 22, 0xfd469501); + self::step($F, $A, $B, $C, $D, $words[8], 7, 0x698098d8); + self::step($F, $D, $A, $B, $C, $words[9], 12, 0x8b44f7af); + self::step($F, $C, $D, $A, $B, $words[10], 17, 0xffff5bb1); + self::step($F, $B, $C, $D, $A, $words[11], 22, 0x895cd7be); + self::step($F, $A, $B, $C, $D, $words[12], 7, 0x6b901122); + self::step($F, $D, $A, $B, $C, $words[13], 12, 0xfd987193); + self::step($F, $C, $D, $A, $B, $words[14], 17, 0xa679438e); + self::step($F, $B, $C, $D, $A, $words[15], 22, 0x49b40821); + + /* ROUND 2 */ + self::step($G, $A, $B, $C, $D, $words[1], 5, 0xf61e2562); + self::step($G, $D, $A, $B, $C, $words[6], 9, 0xc040b340); + self::step($G, $C, $D, $A, $B, $words[11], 14, 0x265e5a51); + self::step($G, $B, $C, $D, $A, $words[0], 20, 0xe9b6c7aa); + self::step($G, $A, $B, $C, $D, $words[5], 5, 0xd62f105d); + self::step($G, $D, $A, $B, $C, $words[10], 9, 0x02441453); + self::step($G, $C, $D, $A, $B, $words[15], 14, 0xd8a1e681); + self::step($G, $B, $C, $D, $A, $words[4], 20, 0xe7d3fbc8); + self::step($G, $A, $B, $C, $D, $words[9], 5, 0x21e1cde6); + self::step($G, $D, $A, $B, $C, $words[14], 9, 0xc33707d6); + self::step($G, $C, $D, $A, $B, $words[3], 14, 0xf4d50d87); + self::step($G, $B, $C, $D, $A, $words[8], 20, 0x455a14ed); + self::step($G, $A, $B, $C, $D, $words[13], 5, 0xa9e3e905); + self::step($G, $D, $A, $B, $C, $words[2], 9, 0xfcefa3f8); + self::step($G, $C, $D, $A, $B, $words[7], 14, 0x676f02d9); + self::step($G, $B, $C, $D, $A, $words[12], 20, 0x8d2a4c8a); + + /* ROUND 3 */ + self::step($H, $A, $B, $C, $D, $words[5], 4, 0xfffa3942); + self::step($H, $D, $A, $B, $C, $words[8], 11, 0x8771f681); + self::step($H, $C, $D, $A, $B, $words[11], 16, 0x6d9d6122); + self::step($H, $B, $C, $D, $A, $words[14], 23, 0xfde5380c); + self::step($H, $A, $B, $C, $D, $words[1], 4, 0xa4beea44); + self::step($H, $D, $A, $B, $C, $words[4], 11, 0x4bdecfa9); + self::step($H, $C, $D, $A, $B, $words[7], 16, 0xf6bb4b60); + self::step($H, $B, $C, $D, $A, $words[10], 23, 0xbebfbc70); + self::step($H, $A, $B, $C, $D, $words[13], 4, 0x289b7ec6); + self::step($H, $D, $A, $B, $C, $words[0], 11, 0xeaa127fa); + self::step($H, $C, $D, $A, $B, $words[3], 16, 0xd4ef3085); + self::step($H, $B, $C, $D, $A, $words[6], 23, 0x04881d05); + self::step($H, $A, $B, $C, $D, $words[9], 4, 0xd9d4d039); + self::step($H, $D, $A, $B, $C, $words[12], 11, 0xe6db99e5); + self::step($H, $C, $D, $A, $B, $words[15], 16, 0x1fa27cf8); + self::step($H, $B, $C, $D, $A, $words[2], 23, 0xc4ac5665); + + /* ROUND 4 */ + self::step($I, $A, $B, $C, $D, $words[0], 6, 0xf4292244); + self::step($I, $D, $A, $B, $C, $words[7], 10, 0x432aff97); + self::step($I, $C, $D, $A, $B, $words[14], 15, 0xab9423a7); + self::step($I, $B, $C, $D, $A, $words[5], 21, 0xfc93a039); + self::step($I, $A, $B, $C, $D, $words[12], 6, 0x655b59c3); + self::step($I, $D, $A, $B, $C, $words[3], 10, 0x8f0ccc92); + self::step($I, $C, $D, $A, $B, $words[10], 15, 0xffeff47d); + self::step($I, $B, $C, $D, $A, $words[1], 21, 0x85845dd1); + self::step($I, $A, $B, $C, $D, $words[8], 6, 0x6fa87e4f); + self::step($I, $D, $A, $B, $C, $words[15], 10, 0xfe2ce6e0); + self::step($I, $C, $D, $A, $B, $words[6], 15, 0xa3014314); + self::step($I, $B, $C, $D, $A, $words[13], 21, 0x4e0811a1); + self::step($I, $A, $B, $C, $D, $words[4], 6, 0xf7537e82); + self::step($I, $D, $A, $B, $C, $words[11], 10, 0xbd3af235); + self::step($I, $C, $D, $A, $B, $words[2], 15, 0x2ad7d2bb); + self::step($I, $B, $C, $D, $A, $words[9], 21, 0xeb86d391); + + $this->a = ($this->a + $A) & 0xffffffff; + $this->b = ($this->b + $B) & 0xffffffff; + $this->c = ($this->c + $C) & 0xffffffff; + $this->d = ($this->d + $D) & 0xffffffff; + } + + + private static function F($X, $Y, $Z) + { + return (($X & $Y) | ((~ $X) & $Z)); // X AND Y OR NOT X AND Z + } + + + private static function G($X, $Y, $Z) + { + return (($X & $Z) | ($Y & (~ $Z))); // X AND Z OR Y AND NOT Z + } + + + private static function H($X, $Y, $Z) + { + return ($X ^ $Y ^ $Z); // X XOR Y XOR Z + } + + + private static function I($X, $Y, $Z) + { + return ($Y ^ ($X | (~ $Z))) ; // Y XOR (X OR NOT Z) + } + + + private static function step($func, &$A, $B, $C, $D, $M, $s, $t) + { + $A = ($A + call_user_func($func, $B, $C, $D) + $M + $t) & 0xffffffff; + $A = self::rotate($A, $s); + $A = ($B + $A) & 0xffffffff; + } + + + private static function rotate($decimal, $bits) + { + $binary = str_pad(decbin($decimal), 32, "0", STR_PAD_LEFT); + return bindec(substr($binary, $bits).substr($binary, 0, $bits)); + } +} \ No newline at end of file diff --git a/lib/phpexcel/PHPExcel/Reader/Excel5/RC4.php b/lib/phpexcel/PHPExcel/Reader/Excel5/RC4.php new file mode 100644 index 0000000..dc6327c --- /dev/null +++ b/lib/phpexcel/PHPExcel/Reader/Excel5/RC4.php @@ -0,0 +1,88 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Reader_Excel5 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + +/** + * PHPExcel_Reader_Excel5_RC4 + * + * @category PHPExcel + * @package PHPExcel_Reader_Excel5 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Reader_Excel5_RC4 +{ + // Context + var $s = array(); + var $i = 0; + var $j = 0; + + /** + * RC4 stream decryption/encryption constrcutor + * + * @param string $key Encryption key/passphrase + */ + public function __construct($key) + { + $len = strlen($key); + + for ($this->i = 0; $this->i < 256; $this->i++) { + $this->s[$this->i] = $this->i; + } + + $this->j = 0; + for ($this->i = 0; $this->i < 256; $this->i++) { + $this->j = ($this->j + $this->s[$this->i] + ord($key[$this->i % $len])) % 256; + $t = $this->s[$this->i]; + $this->s[$this->i] = $this->s[$this->j]; + $this->s[$this->j] = $t; + } + $this->i = $this->j = 0; + } + + /** + * Symmetric decryption/encryption function + * + * @param string $data Data to encrypt/decrypt + * + * @return string + */ + public function RC4($data) + { + $len = strlen($data); + for ($c = 0; $c < $len; $c++) { + $this->i = ($this->i + 1) % 256; + $this->j = ($this->j + $this->s[$this->i]) % 256; + $t = $this->s[$this->i]; + $this->s[$this->i] = $this->s[$this->j]; + $this->s[$this->j] = $t; + + $t = ($this->s[$this->i] + $this->s[$this->j]) % 256; + + $data[$c] = chr(ord($data[$c]) ^ $this->s[$t]); + } + return $data; + } +} diff --git a/lib/phpexcel/PHPExcel/Reader/Exception.php b/lib/phpexcel/PHPExcel/Reader/Exception.php new file mode 100644 index 0000000..f42a1aa --- /dev/null +++ b/lib/phpexcel/PHPExcel/Reader/Exception.php @@ -0,0 +1,52 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Reader + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Reader_Exception + * + * @category PHPExcel + * @package PHPExcel_Reader + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Reader_Exception extends PHPExcel_Exception { + /** + * Error handler callback + * + * @param mixed $code + * @param mixed $string + * @param mixed $file + * @param mixed $line + * @param mixed $context + */ + public static function errorHandlerCallback($code, $string, $file, $line, $context) { + $e = new self($string, $code); + $e->line = $line; + $e->file = $file; + throw $e; + } +} diff --git a/lib/phpexcel/PHPExcel/Reader/Gnumeric.php b/lib/phpexcel/PHPExcel/Reader/Gnumeric.php new file mode 100644 index 0000000..6db7c49 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Reader/Gnumeric.php @@ -0,0 +1,873 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Reader + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** PHPExcel root directory */ +if (!defined('PHPEXCEL_ROOT')) { + /** + * @ignore + */ + define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); + require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); +} + +/** + * PHPExcel_Reader_Gnumeric + * + * @category PHPExcel + * @package PHPExcel_Reader + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Reader_Gnumeric extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader +{ + /** + * Formats + * + * @var array + */ + private $_styles = array(); + + /** + * Shared Expressions + * + * @var array + */ + private $_expressions = array(); + + private $_referenceHelper = null; + + + /** + * Create a new PHPExcel_Reader_Gnumeric + */ + public function __construct() { + $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); + $this->_referenceHelper = PHPExcel_ReferenceHelper::getInstance(); + } + + + /** + * Can the current PHPExcel_Reader_IReader read the file? + * + * @param string $pFilename + * @return boolean + * @throws PHPExcel_Reader_Exception + */ + public function canRead($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + // Check if gzlib functions are available + if (!function_exists('gzread')) { + throw new PHPExcel_Reader_Exception("gzlib library is not enabled"); + } + + // Read signature data (first 3 bytes) + $fh = fopen($pFilename, 'r'); + $data = fread($fh, 2); + fclose($fh); + + if ($data != chr(0x1F).chr(0x8B)) { + return false; + } + + return true; + } + + + /** + * Reads names of the worksheets from a file, without parsing the whole file to a PHPExcel object + * + * @param string $pFilename + * @throws PHPExcel_Reader_Exception + */ + public function listWorksheetNames($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + $xml = new XMLReader(); + $xml->open( + 'compress.zlib://'.realpath($pFilename), null, PHPExcel_Settings::getLibXmlLoaderOptions() + ); + $xml->setParserProperty(2,true); + + $worksheetNames = array(); + while ($xml->read()) { + if ($xml->name == 'gnm:SheetName' && $xml->nodeType == XMLReader::ELEMENT) { + $xml->read(); // Move onto the value node + $worksheetNames[] = (string) $xml->value; + } elseif ($xml->name == 'gnm:Sheets') { + // break out of the loop once we've got our sheet names rather than parse the entire file + break; + } + } + + return $worksheetNames; + } + + + /** + * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns) + * + * @param string $pFilename + * @throws PHPExcel_Reader_Exception + */ + public function listWorksheetInfo($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + $xml = new XMLReader(); + $xml->open( + 'compress.zlib://'.realpath($pFilename), null, PHPExcel_Settings::getLibXmlLoaderOptions() + ); + $xml->setParserProperty(2,true); + + $worksheetInfo = array(); + while ($xml->read()) { + if ($xml->name == 'gnm:Sheet' && $xml->nodeType == XMLReader::ELEMENT) { + $tmpInfo = array( + 'worksheetName' => '', + 'lastColumnLetter' => 'A', + 'lastColumnIndex' => 0, + 'totalRows' => 0, + 'totalColumns' => 0, + ); + + while ($xml->read()) { + if ($xml->name == 'gnm:Name' && $xml->nodeType == XMLReader::ELEMENT) { + $xml->read(); // Move onto the value node + $tmpInfo['worksheetName'] = (string) $xml->value; + } elseif ($xml->name == 'gnm:MaxCol' && $xml->nodeType == XMLReader::ELEMENT) { + $xml->read(); // Move onto the value node + $tmpInfo['lastColumnIndex'] = (int) $xml->value; + $tmpInfo['totalColumns'] = (int) $xml->value + 1; + } elseif ($xml->name == 'gnm:MaxRow' && $xml->nodeType == XMLReader::ELEMENT) { + $xml->read(); // Move onto the value node + $tmpInfo['totalRows'] = (int) $xml->value + 1; + break; + } + } + $tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']); + $worksheetInfo[] = $tmpInfo; + } + } + + return $worksheetInfo; + } + + + private function _gzfileGetContents($filename) { + $file = @gzopen($filename, 'rb'); + if ($file !== false) { + $data = ''; + while (!gzeof($file)) { + $data .= gzread($file, 1024); + } + gzclose($file); + } + return $data; + } + + + /** + * Loads PHPExcel from file + * + * @param string $pFilename + * @return PHPExcel + * @throws PHPExcel_Reader_Exception + */ + public function load($pFilename) + { + // Create new PHPExcel + $objPHPExcel = new PHPExcel(); + + // Load into this instance + return $this->loadIntoExisting($pFilename, $objPHPExcel); + } + + + /** + * Loads PHPExcel from file into PHPExcel instance + * + * @param string $pFilename + * @param PHPExcel $objPHPExcel + * @return PHPExcel + * @throws PHPExcel_Reader_Exception + */ + public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + $timezoneObj = new DateTimeZone('Europe/London'); + $GMT = new DateTimeZone('UTC'); + + $gFileData = $this->_gzfileGetContents($pFilename); + +// echo '<pre>'; +// echo htmlentities($gFileData,ENT_QUOTES,'UTF-8'); +// echo '</pre><hr />'; +// + $xml = simplexml_load_string($gFileData, 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $namespacesMeta = $xml->getNamespaces(true); + +// var_dump($namespacesMeta); +// + $gnmXML = $xml->children($namespacesMeta['gnm']); + + $docProps = $objPHPExcel->getProperties(); + // Document Properties are held differently, depending on the version of Gnumeric + if (isset($namespacesMeta['office'])) { + $officeXML = $xml->children($namespacesMeta['office']); + $officeDocXML = $officeXML->{'document-meta'}; + $officeDocMetaXML = $officeDocXML->meta; + + foreach($officeDocMetaXML as $officePropertyData) { + + $officePropertyDC = array(); + if (isset($namespacesMeta['dc'])) { + $officePropertyDC = $officePropertyData->children($namespacesMeta['dc']); + } + foreach($officePropertyDC as $propertyName => $propertyValue) { + $propertyValue = (string) $propertyValue; + switch ($propertyName) { + case 'title' : + $docProps->setTitle(trim($propertyValue)); + break; + case 'subject' : + $docProps->setSubject(trim($propertyValue)); + break; + case 'creator' : + $docProps->setCreator(trim($propertyValue)); + $docProps->setLastModifiedBy(trim($propertyValue)); + break; + case 'date' : + $creationDate = strtotime(trim($propertyValue)); + $docProps->setCreated($creationDate); + $docProps->setModified($creationDate); + break; + case 'description' : + $docProps->setDescription(trim($propertyValue)); + break; + } + } + $officePropertyMeta = array(); + if (isset($namespacesMeta['meta'])) { + $officePropertyMeta = $officePropertyData->children($namespacesMeta['meta']); + } + foreach($officePropertyMeta as $propertyName => $propertyValue) { + $attributes = $propertyValue->attributes($namespacesMeta['meta']); + $propertyValue = (string) $propertyValue; + switch ($propertyName) { + case 'keyword' : + $docProps->setKeywords(trim($propertyValue)); + break; + case 'initial-creator' : + $docProps->setCreator(trim($propertyValue)); + $docProps->setLastModifiedBy(trim($propertyValue)); + break; + case 'creation-date' : + $creationDate = strtotime(trim($propertyValue)); + $docProps->setCreated($creationDate); + $docProps->setModified($creationDate); + break; + case 'user-defined' : + list(,$attrName) = explode(':',$attributes['name']); + switch ($attrName) { + case 'publisher' : + $docProps->setCompany(trim($propertyValue)); + break; + case 'category' : + $docProps->setCategory(trim($propertyValue)); + break; + case 'manager' : + $docProps->setManager(trim($propertyValue)); + break; + } + break; + } + } + } + } elseif (isset($gnmXML->Summary)) { + foreach($gnmXML->Summary->Item as $summaryItem) { + $propertyName = $summaryItem->name; + $propertyValue = $summaryItem->{'val-string'}; + switch ($propertyName) { + case 'title' : + $docProps->setTitle(trim($propertyValue)); + break; + case 'comments' : + $docProps->setDescription(trim($propertyValue)); + break; + case 'keywords' : + $docProps->setKeywords(trim($propertyValue)); + break; + case 'category' : + $docProps->setCategory(trim($propertyValue)); + break; + case 'manager' : + $docProps->setManager(trim($propertyValue)); + break; + case 'author' : + $docProps->setCreator(trim($propertyValue)); + $docProps->setLastModifiedBy(trim($propertyValue)); + break; + case 'company' : + $docProps->setCompany(trim($propertyValue)); + break; + } + } + } + + $worksheetID = 0; + foreach($gnmXML->Sheets->Sheet as $sheet) { + $worksheetName = (string) $sheet->Name; +// echo '<b>Worksheet: ',$worksheetName,'</b><br />'; + if ((isset($this->_loadSheetsOnly)) && (!in_array($worksheetName, $this->_loadSheetsOnly))) { + continue; + } + + $maxRow = $maxCol = 0; + + // Create new Worksheet + $objPHPExcel->createSheet(); + $objPHPExcel->setActiveSheetIndex($worksheetID); + // Use false for $updateFormulaCellReferences to prevent adjustment of worksheet references in formula + // cells... during the load, all formulae should be correct, and we're simply bringing the worksheet + // name in line with the formula, not the reverse + $objPHPExcel->getActiveSheet()->setTitle($worksheetName,false); + + if ((!$this->_readDataOnly) && (isset($sheet->PrintInformation))) { + if (isset($sheet->PrintInformation->Margins)) { + foreach($sheet->PrintInformation->Margins->children('gnm',TRUE) as $key => $margin) { + $marginAttributes = $margin->attributes(); + $marginSize = 72 / 100; // Default + switch($marginAttributes['PrefUnit']) { + case 'mm' : + $marginSize = intval($marginAttributes['Points']) / 100; + break; + } + switch($key) { + case 'top' : + $objPHPExcel->getActiveSheet()->getPageMargins()->setTop($marginSize); + break; + case 'bottom' : + $objPHPExcel->getActiveSheet()->getPageMargins()->setBottom($marginSize); + break; + case 'left' : + $objPHPExcel->getActiveSheet()->getPageMargins()->setLeft($marginSize); + break; + case 'right' : + $objPHPExcel->getActiveSheet()->getPageMargins()->setRight($marginSize); + break; + case 'header' : + $objPHPExcel->getActiveSheet()->getPageMargins()->setHeader($marginSize); + break; + case 'footer' : + $objPHPExcel->getActiveSheet()->getPageMargins()->setFooter($marginSize); + break; + } + } + } + } + + foreach($sheet->Cells->Cell as $cell) { + $cellAttributes = $cell->attributes(); + $row = (int) $cellAttributes->Row + 1; + $column = (int) $cellAttributes->Col; + + if ($row > $maxRow) $maxRow = $row; + if ($column > $maxCol) $maxCol = $column; + + $column = PHPExcel_Cell::stringFromColumnIndex($column); + + // Read cell? + if ($this->getReadFilter() !== NULL) { + if (!$this->getReadFilter()->readCell($column, $row, $worksheetName)) { + continue; + } + } + + $ValueType = $cellAttributes->ValueType; + $ExprID = (string) $cellAttributes->ExprID; +// echo 'Cell ',$column,$row,'<br />'; +// echo 'Type is ',$ValueType,'<br />'; +// echo 'Value is ',$cell,'<br />'; + $type = PHPExcel_Cell_DataType::TYPE_FORMULA; + if ($ExprID > '') { + if (((string) $cell) > '') { + + $this->_expressions[$ExprID] = array( 'column' => $cellAttributes->Col, + 'row' => $cellAttributes->Row, + 'formula' => (string) $cell + ); +// echo 'NEW EXPRESSION ',$ExprID,'<br />'; + } else { + $expression = $this->_expressions[$ExprID]; + + $cell = $this->_referenceHelper->updateFormulaReferences( $expression['formula'], + 'A1', + $cellAttributes->Col - $expression['column'], + $cellAttributes->Row - $expression['row'], + $worksheetName + ); +// echo 'SHARED EXPRESSION ',$ExprID,'<br />'; +// echo 'New Value is ',$cell,'<br />'; + } + $type = PHPExcel_Cell_DataType::TYPE_FORMULA; + } else { + switch($ValueType) { + case '10' : // NULL + $type = PHPExcel_Cell_DataType::TYPE_NULL; + break; + case '20' : // Boolean + $type = PHPExcel_Cell_DataType::TYPE_BOOL; + $cell = ($cell == 'TRUE') ? True : False; + break; + case '30' : // Integer + $cell = intval($cell); + case '40' : // Float + $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; + break; + case '50' : // Error + $type = PHPExcel_Cell_DataType::TYPE_ERROR; + break; + case '60' : // String + $type = PHPExcel_Cell_DataType::TYPE_STRING; + break; + case '70' : // Cell Range + case '80' : // Array + } + } + $objPHPExcel->getActiveSheet()->getCell($column.$row)->setValueExplicit($cell,$type); + } + + if ((!$this->_readDataOnly) && (isset($sheet->Objects))) { + foreach($sheet->Objects->children('gnm',TRUE) as $key => $comment) { + $commentAttributes = $comment->attributes(); + // Only comment objects are handled at the moment + if ($commentAttributes->Text) { + $objPHPExcel->getActiveSheet()->getComment( (string)$commentAttributes->ObjectBound ) + ->setAuthor( (string)$commentAttributes->Author ) + ->setText($this->_parseRichText((string)$commentAttributes->Text) ); + } + } + } +// echo '$maxCol=',$maxCol,'; $maxRow=',$maxRow,'<br />'; +// + foreach($sheet->Styles->StyleRegion as $styleRegion) { + $styleAttributes = $styleRegion->attributes(); + if (($styleAttributes['startRow'] <= $maxRow) && + ($styleAttributes['startCol'] <= $maxCol)) { + + $startColumn = PHPExcel_Cell::stringFromColumnIndex((int) $styleAttributes['startCol']); + $startRow = $styleAttributes['startRow'] + 1; + + $endColumn = ($styleAttributes['endCol'] > $maxCol) ? $maxCol : (int) $styleAttributes['endCol']; + $endColumn = PHPExcel_Cell::stringFromColumnIndex($endColumn); + $endRow = ($styleAttributes['endRow'] > $maxRow) ? $maxRow : $styleAttributes['endRow']; + $endRow += 1; + $cellRange = $startColumn.$startRow.':'.$endColumn.$endRow; +// echo $cellRange,'<br />'; + + $styleAttributes = $styleRegion->Style->attributes(); +// var_dump($styleAttributes); +// echo '<br />'; + + // We still set the number format mask for date/time values, even if _readDataOnly is true + if ((!$this->_readDataOnly) || + (PHPExcel_Shared_Date::isDateTimeFormatCode((string) $styleAttributes['Format']))) { + $styleArray = array(); + $styleArray['numberformat']['code'] = (string) $styleAttributes['Format']; + // If _readDataOnly is false, we set all formatting information + if (!$this->_readDataOnly) { + switch($styleAttributes['HAlign']) { + case '1' : + $styleArray['alignment']['horizontal'] = PHPExcel_Style_Alignment::HORIZONTAL_GENERAL; + break; + case '2' : + $styleArray['alignment']['horizontal'] = PHPExcel_Style_Alignment::HORIZONTAL_LEFT; + break; + case '4' : + $styleArray['alignment']['horizontal'] = PHPExcel_Style_Alignment::HORIZONTAL_RIGHT; + break; + case '8' : + $styleArray['alignment']['horizontal'] = PHPExcel_Style_Alignment::HORIZONTAL_CENTER; + break; + case '16' : + case '64' : + $styleArray['alignment']['horizontal'] = PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS; + break; + case '32' : + $styleArray['alignment']['horizontal'] = PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY; + break; + } + + switch($styleAttributes['VAlign']) { + case '1' : + $styleArray['alignment']['vertical'] = PHPExcel_Style_Alignment::VERTICAL_TOP; + break; + case '2' : + $styleArray['alignment']['vertical'] = PHPExcel_Style_Alignment::VERTICAL_BOTTOM; + break; + case '4' : + $styleArray['alignment']['vertical'] = PHPExcel_Style_Alignment::VERTICAL_CENTER; + break; + case '8' : + $styleArray['alignment']['vertical'] = PHPExcel_Style_Alignment::VERTICAL_JUSTIFY; + break; + } + + $styleArray['alignment']['wrap'] = ($styleAttributes['WrapText'] == '1') ? True : False; + $styleArray['alignment']['shrinkToFit'] = ($styleAttributes['ShrinkToFit'] == '1') ? True : False; + $styleArray['alignment']['indent'] = (intval($styleAttributes["Indent"]) > 0) ? $styleAttributes["indent"] : 0; + + $RGB = self::_parseGnumericColour($styleAttributes["Fore"]); + $styleArray['font']['color']['rgb'] = $RGB; + $RGB = self::_parseGnumericColour($styleAttributes["Back"]); + $shade = $styleAttributes["Shade"]; + if (($RGB != '000000') || ($shade != '0')) { + $styleArray['fill']['color']['rgb'] = $styleArray['fill']['startcolor']['rgb'] = $RGB; + $RGB2 = self::_parseGnumericColour($styleAttributes["PatternColor"]); + $styleArray['fill']['endcolor']['rgb'] = $RGB2; + switch($shade) { + case '1' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_SOLID; + break; + case '2' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_GRADIENT_LINEAR; + break; + case '3' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_GRADIENT_PATH; + break; + case '4' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKDOWN; + break; + case '5' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKGRAY; + break; + case '6' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKGRID; + break; + case '7' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKHORIZONTAL; + break; + case '8' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKTRELLIS; + break; + case '9' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKUP; + break; + case '10' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKVERTICAL; + break; + case '11' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_GRAY0625; + break; + case '12' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_GRAY125; + break; + case '13' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTDOWN; + break; + case '14' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRAY; + break; + case '15' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRID; + break; + case '16' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTHORIZONTAL; + break; + case '17' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTTRELLIS; + break; + case '18' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTUP; + break; + case '19' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTVERTICAL; + break; + case '20' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_MEDIUMGRAY; + break; + } + } + + $fontAttributes = $styleRegion->Style->Font->attributes(); +// var_dump($fontAttributes); +// echo '<br />'; + $styleArray['font']['name'] = (string) $styleRegion->Style->Font; + $styleArray['font']['size'] = intval($fontAttributes['Unit']); + $styleArray['font']['bold'] = ($fontAttributes['Bold'] == '1') ? True : False; + $styleArray['font']['italic'] = ($fontAttributes['Italic'] == '1') ? True : False; + $styleArray['font']['strike'] = ($fontAttributes['StrikeThrough'] == '1') ? True : False; + switch($fontAttributes['Underline']) { + case '1' : + $styleArray['font']['underline'] = PHPExcel_Style_Font::UNDERLINE_SINGLE; + break; + case '2' : + $styleArray['font']['underline'] = PHPExcel_Style_Font::UNDERLINE_DOUBLE; + break; + case '3' : + $styleArray['font']['underline'] = PHPExcel_Style_Font::UNDERLINE_SINGLEACCOUNTING; + break; + case '4' : + $styleArray['font']['underline'] = PHPExcel_Style_Font::UNDERLINE_DOUBLEACCOUNTING; + break; + default : + $styleArray['font']['underline'] = PHPExcel_Style_Font::UNDERLINE_NONE; + break; + } + switch($fontAttributes['Script']) { + case '1' : + $styleArray['font']['superScript'] = True; + break; + case '-1' : + $styleArray['font']['subScript'] = True; + break; + } + + if (isset($styleRegion->Style->StyleBorder)) { + if (isset($styleRegion->Style->StyleBorder->Top)) { + $styleArray['borders']['top'] = self::_parseBorderAttributes($styleRegion->Style->StyleBorder->Top->attributes()); + } + if (isset($styleRegion->Style->StyleBorder->Bottom)) { + $styleArray['borders']['bottom'] = self::_parseBorderAttributes($styleRegion->Style->StyleBorder->Bottom->attributes()); + } + if (isset($styleRegion->Style->StyleBorder->Left)) { + $styleArray['borders']['left'] = self::_parseBorderAttributes($styleRegion->Style->StyleBorder->Left->attributes()); + } + if (isset($styleRegion->Style->StyleBorder->Right)) { + $styleArray['borders']['right'] = self::_parseBorderAttributes($styleRegion->Style->StyleBorder->Right->attributes()); + } + if ((isset($styleRegion->Style->StyleBorder->Diagonal)) && (isset($styleRegion->Style->StyleBorder->{'Rev-Diagonal'}))) { + $styleArray['borders']['diagonal'] = self::_parseBorderAttributes($styleRegion->Style->StyleBorder->Diagonal->attributes()); + $styleArray['borders']['diagonaldirection'] = PHPExcel_Style_Borders::DIAGONAL_BOTH; + } elseif (isset($styleRegion->Style->StyleBorder->Diagonal)) { + $styleArray['borders']['diagonal'] = self::_parseBorderAttributes($styleRegion->Style->StyleBorder->Diagonal->attributes()); + $styleArray['borders']['diagonaldirection'] = PHPExcel_Style_Borders::DIAGONAL_UP; + } elseif (isset($styleRegion->Style->StyleBorder->{'Rev-Diagonal'})) { + $styleArray['borders']['diagonal'] = self::_parseBorderAttributes($styleRegion->Style->StyleBorder->{'Rev-Diagonal'}->attributes()); + $styleArray['borders']['diagonaldirection'] = PHPExcel_Style_Borders::DIAGONAL_DOWN; + } + } + if (isset($styleRegion->Style->HyperLink)) { + // TO DO + $hyperlink = $styleRegion->Style->HyperLink->attributes(); + } + } +// var_dump($styleArray); +// echo '<br />'; + $objPHPExcel->getActiveSheet()->getStyle($cellRange)->applyFromArray($styleArray); + } + } + } + + if ((!$this->_readDataOnly) && (isset($sheet->Cols))) { + // Column Widths + $columnAttributes = $sheet->Cols->attributes(); + $defaultWidth = $columnAttributes['DefaultSizePts'] / 5.4; + $c = 0; + foreach($sheet->Cols->ColInfo as $columnOverride) { + $columnAttributes = $columnOverride->attributes(); + $column = $columnAttributes['No']; + $columnWidth = $columnAttributes['Unit'] / 5.4; + $hidden = ((isset($columnAttributes['Hidden'])) && ($columnAttributes['Hidden'] == '1')) ? true : false; + $columnCount = (isset($columnAttributes['Count'])) ? $columnAttributes['Count'] : 1; + while ($c < $column) { + $objPHPExcel->getActiveSheet()->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($c))->setWidth($defaultWidth); + ++$c; + } + while (($c < ($column+$columnCount)) && ($c <= $maxCol)) { + $objPHPExcel->getActiveSheet()->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($c))->setWidth($columnWidth); + if ($hidden) { + $objPHPExcel->getActiveSheet()->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($c))->setVisible(false); + } + ++$c; + } + } + while ($c <= $maxCol) { + $objPHPExcel->getActiveSheet()->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($c))->setWidth($defaultWidth); + ++$c; + } + } + + if ((!$this->_readDataOnly) && (isset($sheet->Rows))) { + // Row Heights + $rowAttributes = $sheet->Rows->attributes(); + $defaultHeight = $rowAttributes['DefaultSizePts']; + $r = 0; + + foreach($sheet->Rows->RowInfo as $rowOverride) { + $rowAttributes = $rowOverride->attributes(); + $row = $rowAttributes['No']; + $rowHeight = $rowAttributes['Unit']; + $hidden = ((isset($rowAttributes['Hidden'])) && ($rowAttributes['Hidden'] == '1')) ? true : false; + $rowCount = (isset($rowAttributes['Count'])) ? $rowAttributes['Count'] : 1; + while ($r < $row) { + ++$r; + $objPHPExcel->getActiveSheet()->getRowDimension($r)->setRowHeight($defaultHeight); + } + while (($r < ($row+$rowCount)) && ($r < $maxRow)) { + ++$r; + $objPHPExcel->getActiveSheet()->getRowDimension($r)->setRowHeight($rowHeight); + if ($hidden) { + $objPHPExcel->getActiveSheet()->getRowDimension($r)->setVisible(false); + } + } + } + while ($r < $maxRow) { + ++$r; + $objPHPExcel->getActiveSheet()->getRowDimension($r)->setRowHeight($defaultHeight); + } + } + + // Handle Merged Cells in this worksheet + if (isset($sheet->MergedRegions)) { + foreach($sheet->MergedRegions->Merge as $mergeCells) { + if (strpos($mergeCells,':') !== FALSE) { + $objPHPExcel->getActiveSheet()->mergeCells($mergeCells); + } + } + } + + $worksheetID++; + } + + // Loop through definedNames (global named ranges) + if (isset($gnmXML->Names)) { + foreach($gnmXML->Names->Name as $namedRange) { + $name = (string) $namedRange->name; + $range = (string) $namedRange->value; + if (stripos($range, '#REF!') !== false) { + continue; + } + + $range = explode('!',$range); + $range[0] = trim($range[0],"'");; + if ($worksheet = $objPHPExcel->getSheetByName($range[0])) { + $extractedRange = str_replace('$', '', $range[1]); + $objPHPExcel->addNamedRange( new PHPExcel_NamedRange($name, $worksheet, $extractedRange) ); + } + } + } + + + // Return + return $objPHPExcel; + } + + + private static function _parseBorderAttributes($borderAttributes) + { + $styleArray = array(); + + if (isset($borderAttributes["Color"])) { + $RGB = self::_parseGnumericColour($borderAttributes["Color"]); + $styleArray['color']['rgb'] = $RGB; + } + + switch ($borderAttributes["Style"]) { + case '0' : + $styleArray['style'] = PHPExcel_Style_Border::BORDER_NONE; + break; + case '1' : + $styleArray['style'] = PHPExcel_Style_Border::BORDER_THIN; + break; + case '2' : + $styleArray['style'] = PHPExcel_Style_Border::BORDER_MEDIUM; + break; + case '4' : + $styleArray['style'] = PHPExcel_Style_Border::BORDER_DASHED; + break; + case '5' : + $styleArray['style'] = PHPExcel_Style_Border::BORDER_THICK; + break; + case '6' : + $styleArray['style'] = PHPExcel_Style_Border::BORDER_DOUBLE; + break; + case '7' : + $styleArray['style'] = PHPExcel_Style_Border::BORDER_DOTTED; + break; + case '9' : + $styleArray['style'] = PHPExcel_Style_Border::BORDER_DASHDOT; + break; + case '10' : + $styleArray['style'] = PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT; + break; + case '11' : + $styleArray['style'] = PHPExcel_Style_Border::BORDER_DASHDOTDOT; + break; + case '12' : + $styleArray['style'] = PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT; + break; + case '13' : + $styleArray['style'] = PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT; + break; + case '3' : + $styleArray['style'] = PHPExcel_Style_Border::BORDER_SLANTDASHDOT; + break; + case '8' : + $styleArray['style'] = PHPExcel_Style_Border::BORDER_MEDIUMDASHED; + break; + } + return $styleArray; + } + + + private function _parseRichText($is = '') { + $value = new PHPExcel_RichText(); + + $value->createText($is); + + return $value; + } + + + private static function _parseGnumericColour($gnmColour) { + list($gnmR,$gnmG,$gnmB) = explode(':',$gnmColour); + $gnmR = substr(str_pad($gnmR,4,'0',STR_PAD_RIGHT),0,2); + $gnmG = substr(str_pad($gnmG,4,'0',STR_PAD_RIGHT),0,2); + $gnmB = substr(str_pad($gnmB,4,'0',STR_PAD_RIGHT),0,2); + $RGB = $gnmR.$gnmG.$gnmB; +// echo 'Excel Colour: ',$RGB,'<br />'; + return $RGB; + } + +} diff --git a/lib/phpexcel/PHPExcel/Reader/HTML.php b/lib/phpexcel/PHPExcel/Reader/HTML.php new file mode 100644 index 0000000..1696471 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Reader/HTML.php @@ -0,0 +1,468 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Reader + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** PHPExcel root directory */ +if (!defined('PHPEXCEL_ROOT')) { + /** + * @ignore + */ + define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); + require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); +} + +/** + * PHPExcel_Reader_HTML + * + * @category PHPExcel + * @package PHPExcel_Reader + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Reader_HTML extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader +{ + /** + * Input encoding + * + * @var string + */ + private $_inputEncoding = 'ANSI'; + + /** + * Sheet index to read + * + * @var int + */ + private $_sheetIndex = 0; + + /** + * Formats + * + * @var array + */ + private $_formats = array( 'h1' => array( 'font' => array( 'bold' => true, + 'size' => 24, + ), + ), // Bold, 24pt + 'h2' => array( 'font' => array( 'bold' => true, + 'size' => 18, + ), + ), // Bold, 18pt + 'h3' => array( 'font' => array( 'bold' => true, + 'size' => 13.5, + ), + ), // Bold, 13.5pt + 'h4' => array( 'font' => array( 'bold' => true, + 'size' => 12, + ), + ), // Bold, 12pt + 'h5' => array( 'font' => array( 'bold' => true, + 'size' => 10, + ), + ), // Bold, 10pt + 'h6' => array( 'font' => array( 'bold' => true, + 'size' => 7.5, + ), + ), // Bold, 7.5pt + 'a' => array( 'font' => array( 'underline' => true, + 'color' => array( 'argb' => PHPExcel_Style_Color::COLOR_BLUE, + ), + ), + ), // Blue underlined + 'hr' => array( 'borders' => array( 'bottom' => array( 'style' => PHPExcel_Style_Border::BORDER_THIN, + 'color' => array( PHPExcel_Style_Color::COLOR_BLACK, + ), + ), + ), + ), // Bottom border + ); + + + /** + * Create a new PHPExcel_Reader_HTML + */ + public function __construct() { + $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); + } + + /** + * Validate that the current file is an HTML file + * + * @return boolean + */ + protected function _isValidFormat() + { + // Reading 2048 bytes should be enough to validate that the format is HTML + $data = fread($this->_fileHandle, 2048); + if ((strpos($data, '<') !== FALSE) && + (strlen($data) !== strlen(strip_tags($data)))) { + return TRUE; + } + + return FALSE; + } + + /** + * Loads PHPExcel from file + * + * @param string $pFilename + * @return PHPExcel + * @throws PHPExcel_Reader_Exception + */ + public function load($pFilename) + { + // Create new PHPExcel + $objPHPExcel = new PHPExcel(); + + // Load into this instance + return $this->loadIntoExisting($pFilename, $objPHPExcel); + } + + /** + * Set input encoding + * + * @param string $pValue Input encoding + */ + public function setInputEncoding($pValue = 'ANSI') + { + $this->_inputEncoding = $pValue; + return $this; + } + + /** + * Get input encoding + * + * @return string + */ + public function getInputEncoding() + { + return $this->_inputEncoding; + } + + // Data Array used for testing only, should write to PHPExcel object on completion of tests + private $_dataArray = array(); + + private $_tableLevel = 0; + private $_nestedColumn = array('A'); + + private function _setTableStartColumn($column) { + if ($this->_tableLevel == 0) + $column = 'A'; + ++$this->_tableLevel; + $this->_nestedColumn[$this->_tableLevel] = $column; + + return $this->_nestedColumn[$this->_tableLevel]; + } + + private function _getTableStartColumn() { + return $this->_nestedColumn[$this->_tableLevel]; + } + + private function _releaseTableStartColumn() { + --$this->_tableLevel; + return array_pop($this->_nestedColumn); + } + + private function _flushCell($sheet,$column,$row,&$cellContent) { + if (is_string($cellContent)) { + // Simple String content + if (trim($cellContent) > '') { + // Only actually write it if there's content in the string +// echo 'FLUSH CELL: ' , $column , $row , ' => ' , $cellContent , '<br />'; + // Write to worksheet to be done here... + // ... we return the cell so we can mess about with styles more easily + $cell = $sheet->setCellValue($column.$row,$cellContent,true); + $this->_dataArray[$row][$column] = $cellContent; + } + } else { + // We have a Rich Text run + // TODO + $this->_dataArray[$row][$column] = 'RICH TEXT: ' . $cellContent; + } + $cellContent = (string) ''; + } + + private function _processDomElement(DOMNode $element, $sheet, &$row, &$column, &$cellContent){ + foreach($element->childNodes as $child){ + if ($child instanceof DOMText) { + $domText = preg_replace('/\s+/',' ',trim($child->nodeValue)); + if (is_string($cellContent)) { + // simply append the text if the cell content is a plain text string + $cellContent .= $domText; + } else { + // but if we have a rich text run instead, we need to append it correctly + // TODO + } + } elseif($child instanceof DOMElement) { +// echo '<b>DOM ELEMENT: </b>' , strtoupper($child->nodeName) , '<br />'; + + $attributeArray = array(); + foreach($child->attributes as $attribute) { +// echo '<b>ATTRIBUTE: </b>' , $attribute->name , ' => ' , $attribute->value , '<br />'; + $attributeArray[$attribute->name] = $attribute->value; + } + + switch($child->nodeName) { + case 'meta' : + foreach($attributeArray as $attributeName => $attributeValue) { + switch($attributeName) { + case 'content': + // TODO + // Extract character set, so we can convert to UTF-8 if required + break; + } + } + $this->_processDomElement($child,$sheet,$row,$column,$cellContent); + break; + case 'title' : + $this->_processDomElement($child,$sheet,$row,$column,$cellContent); + $sheet->setTitle($cellContent); + $cellContent = ''; + break; + case 'span' : + case 'div' : + case 'font' : + case 'i' : + case 'em' : + case 'strong': + case 'b' : +// echo 'STYLING, SPAN OR DIV<br />'; + if ($cellContent > '') + $cellContent .= ' '; + $this->_processDomElement($child,$sheet,$row,$column,$cellContent); + if ($cellContent > '') + $cellContent .= ' '; +// echo 'END OF STYLING, SPAN OR DIV<br />'; + break; + case 'hr' : + $this->_flushCell($sheet,$column,$row,$cellContent); + ++$row; + if (isset($this->_formats[$child->nodeName])) { + $sheet->getStyle($column.$row)->applyFromArray($this->_formats[$child->nodeName]); + } else { + $cellContent = '----------'; + $this->_flushCell($sheet,$column,$row,$cellContent); + } + ++$row; + case 'br' : + if ($this->_tableLevel > 0) { + // If we're inside a table, replace with a \n + $cellContent .= "\n"; + } else { + // Otherwise flush our existing content and move the row cursor on + $this->_flushCell($sheet,$column,$row,$cellContent); + ++$row; + } +// echo 'HARD LINE BREAK: ' , '<br />'; + break; + case 'a' : +// echo 'START OF HYPERLINK: ' , '<br />'; + foreach($attributeArray as $attributeName => $attributeValue) { + switch($attributeName) { + case 'href': +// echo 'Link to ' , $attributeValue , '<br />'; + $sheet->getCell($column.$row)->getHyperlink()->setUrl($attributeValue); + if (isset($this->_formats[$child->nodeName])) { + $sheet->getStyle($column.$row)->applyFromArray($this->_formats[$child->nodeName]); + } + break; + } + } + $cellContent .= ' '; + $this->_processDomElement($child,$sheet,$row,$column,$cellContent); +// echo 'END OF HYPERLINK:' , '<br />'; + break; + case 'h1' : + case 'h2' : + case 'h3' : + case 'h4' : + case 'h5' : + case 'h6' : + case 'ol' : + case 'ul' : + case 'p' : + if ($this->_tableLevel > 0) { + // If we're inside a table, replace with a \n + $cellContent .= "\n"; +// echo 'LIST ENTRY: ' , '<br />'; + $this->_processDomElement($child,$sheet,$row,$column,$cellContent); +// echo 'END OF LIST ENTRY:' , '<br />'; + } else { + if ($cellContent > '') { + $this->_flushCell($sheet,$column,$row,$cellContent); + $row += 2; + } +// echo 'START OF PARAGRAPH: ' , '<br />'; + $this->_processDomElement($child,$sheet,$row,$column,$cellContent); +// echo 'END OF PARAGRAPH:' , '<br />'; + $this->_flushCell($sheet,$column,$row,$cellContent); + + if (isset($this->_formats[$child->nodeName])) { + $sheet->getStyle($column.$row)->applyFromArray($this->_formats[$child->nodeName]); + } + + $row += 2; + $column = 'A'; + } + break; + case 'li' : + if ($this->_tableLevel > 0) { + // If we're inside a table, replace with a \n + $cellContent .= "\n"; +// echo 'LIST ENTRY: ' , '<br />'; + $this->_processDomElement($child,$sheet,$row,$column,$cellContent); +// echo 'END OF LIST ENTRY:' , '<br />'; + } else { + if ($cellContent > '') { + $this->_flushCell($sheet,$column,$row,$cellContent); + } + ++$row; +// echo 'LIST ENTRY: ' , '<br />'; + $this->_processDomElement($child,$sheet,$row,$column,$cellContent); +// echo 'END OF LIST ENTRY:' , '<br />'; + $this->_flushCell($sheet,$column,$row,$cellContent); + $column = 'A'; + } + break; + case 'table' : + $this->_flushCell($sheet,$column,$row,$cellContent); + $column = $this->_setTableStartColumn($column); +// echo 'START OF TABLE LEVEL ' , $this->_tableLevel , '<br />'; + if ($this->_tableLevel > 1) + --$row; + $this->_processDomElement($child,$sheet,$row,$column,$cellContent); +// echo 'END OF TABLE LEVEL ' , $this->_tableLevel , '<br />'; + $column = $this->_releaseTableStartColumn(); + if ($this->_tableLevel > 1) { + ++$column; + } else { + ++$row; + } + break; + case 'thead' : + case 'tbody' : + $this->_processDomElement($child,$sheet,$row,$column,$cellContent); + break; + case 'tr' : + ++$row; + $column = $this->_getTableStartColumn(); + $cellContent = ''; +// echo 'START OF TABLE ' , $this->_tableLevel , ' ROW<br />'; + $this->_processDomElement($child,$sheet,$row,$column,$cellContent); +// echo 'END OF TABLE ' , $this->_tableLevel , ' ROW<br />'; + break; + case 'th' : + case 'td' : +// echo 'START OF TABLE ' , $this->_tableLevel , ' CELL<br />'; + $this->_processDomElement($child,$sheet,$row,$column,$cellContent); +// echo 'END OF TABLE ' , $this->_tableLevel , ' CELL<br />'; + $this->_flushCell($sheet,$column,$row,$cellContent); + ++$column; + break; + case 'body' : + $row = 1; + $column = 'A'; + $content = ''; + $this->_tableLevel = 0; + $this->_processDomElement($child,$sheet,$row,$column,$cellContent); + break; + default: + $this->_processDomElement($child,$sheet,$row,$column,$cellContent); + } + } + } + } + + /** + * Loads PHPExcel from file into PHPExcel instance + * + * @param string $pFilename + * @param PHPExcel $objPHPExcel + * @return PHPExcel + * @throws PHPExcel_Reader_Exception + */ + public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) + { + // Open file to validate + $this->_openFile($pFilename); + if (!$this->_isValidFormat()) { + fclose ($this->_fileHandle); + throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid HTML file."); + } + // Close after validating + fclose ($this->_fileHandle); + + // Create new PHPExcel + while ($objPHPExcel->getSheetCount() <= $this->_sheetIndex) { + $objPHPExcel->createSheet(); + } + $objPHPExcel->setActiveSheetIndex( $this->_sheetIndex ); + + // Create a new DOM object + $dom = new domDocument; + // Reload the HTML file into the DOM object + $loaded = $dom->loadHTMLFile($pFilename, PHPExcel_Settings::getLibXmlLoaderOptions()); + if ($loaded === FALSE) { + throw new PHPExcel_Reader_Exception('Failed to load ',$pFilename,' as a DOM Document'); + } + + // Discard white space + $dom->preserveWhiteSpace = false; + + + $row = 0; + $column = 'A'; + $content = ''; + $this->_processDomElement($dom,$objPHPExcel->getActiveSheet(),$row,$column,$content); + +// echo '<hr />'; +// var_dump($this->_dataArray); + + // Return + return $objPHPExcel; + } + + /** + * Get sheet index + * + * @return int + */ + public function getSheetIndex() { + return $this->_sheetIndex; + } + + /** + * Set sheet index + * + * @param int $pValue Sheet index + * @return PHPExcel_Reader_HTML + */ + public function setSheetIndex($pValue = 0) { + $this->_sheetIndex = $pValue; + return $this; + } + +} diff --git a/lib/phpexcel/PHPExcel/Reader/IReadFilter.php b/lib/phpexcel/PHPExcel/Reader/IReadFilter.php new file mode 100644 index 0000000..5a691a5 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Reader/IReadFilter.php @@ -0,0 +1,47 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Reader + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Reader_IReadFilter + * + * @category PHPExcel + * @package PHPExcel_Reader + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +interface PHPExcel_Reader_IReadFilter +{ + /** + * Should this cell be read? + * + * @param $column String column index + * @param $row Row index + * @param $worksheetName Optional worksheet name + * @return boolean + */ + public function readCell($column, $row, $worksheetName = ''); +} diff --git a/lib/phpexcel/PHPExcel/Reader/IReader.php b/lib/phpexcel/PHPExcel/Reader/IReader.php new file mode 100644 index 0000000..6c3e878 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Reader/IReader.php @@ -0,0 +1,53 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Reader + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Reader_IReader + * + * @category PHPExcel + * @package PHPExcel_Reader + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +interface PHPExcel_Reader_IReader +{ + /** + * Can the current PHPExcel_Reader_IReader read the file? + * + * @param string $pFilename + * @return boolean + */ + public function canRead($pFilename); + + /** + * Loads PHPExcel from file + * + * @param string $pFilename + * @throws PHPExcel_Reader_Exception + */ + public function load($pFilename); +} diff --git a/lib/phpexcel/PHPExcel/Reader/OOCalc.php b/lib/phpexcel/PHPExcel/Reader/OOCalc.php new file mode 100644 index 0000000..8ad7061 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Reader/OOCalc.php @@ -0,0 +1,707 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Reader + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** PHPExcel root directory */ +if (!defined('PHPEXCEL_ROOT')) { + /** + * @ignore + */ + define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); + require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); +} + +/** + * PHPExcel_Reader_OOCalc + * + * @category PHPExcel + * @package PHPExcel_Reader + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Reader_OOCalc extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader +{ + /** + * Formats + * + * @var array + */ + private $_styles = array(); + + + /** + * Create a new PHPExcel_Reader_OOCalc + */ + public function __construct() { + $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); + } + + + /** + * Can the current PHPExcel_Reader_IReader read the file? + * + * @param string $pFilename + * @return boolean + * @throws PHPExcel_Reader_Exception + */ + public function canRead($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + $zipClass = PHPExcel_Settings::getZipClass(); + + // Check if zip class exists +// if (!class_exists($zipClass, FALSE)) { +// throw new PHPExcel_Reader_Exception($zipClass . " library is not enabled"); +// } + + $mimeType = 'UNKNOWN'; + // Load file + $zip = new $zipClass; + if ($zip->open($pFilename) === true) { + // check if it is an OOXML archive + $stat = $zip->statName('mimetype'); + if ($stat && ($stat['size'] <= 255)) { + $mimeType = $zip->getFromName($stat['name']); + } elseif($stat = $zip->statName('META-INF/manifest.xml')) { + $xml = simplexml_load_string($zip->getFromName('META-INF/manifest.xml'), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $namespacesContent = $xml->getNamespaces(true); + if (isset($namespacesContent['manifest'])) { + $manifest = $xml->children($namespacesContent['manifest']); + foreach($manifest as $manifestDataSet) { + $manifestAttributes = $manifestDataSet->attributes($namespacesContent['manifest']); + if ($manifestAttributes->{'full-path'} == '/') { + $mimeType = (string) $manifestAttributes->{'media-type'}; + break; + } + } + } + } + + $zip->close(); + + return ($mimeType === 'application/vnd.oasis.opendocument.spreadsheet'); + } + + return FALSE; + } + + + /** + * Reads names of the worksheets from a file, without parsing the whole file to a PHPExcel object + * + * @param string $pFilename + * @throws PHPExcel_Reader_Exception + */ + public function listWorksheetNames($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + $zipClass = PHPExcel_Settings::getZipClass(); + + $zip = new $zipClass; + if (!$zip->open($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! Error opening file."); + } + + $worksheetNames = array(); + + $xml = new XMLReader(); + $res = $xml->open('zip://'.realpath($pFilename).'#content.xml', null, PHPExcel_Settings::getLibXmlLoaderOptions()); + $xml->setParserProperty(2,true); + + // Step into the first level of content of the XML + $xml->read(); + while ($xml->read()) { + // Quickly jump through to the office:body node + while ($xml->name !== 'office:body') { + if ($xml->isEmptyElement) + $xml->read(); + else + $xml->next(); + } + // Now read each node until we find our first table:table node + while ($xml->read()) { + if ($xml->name == 'table:table' && $xml->nodeType == XMLReader::ELEMENT) { + // Loop through each table:table node reading the table:name attribute for each worksheet name + do { + $worksheetNames[] = $xml->getAttribute('table:name'); + $xml->next(); + } while ($xml->name == 'table:table' && $xml->nodeType == XMLReader::ELEMENT); + } + } + } + + return $worksheetNames; + } + + + /** + * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns) + * + * @param string $pFilename + * @throws PHPExcel_Reader_Exception + */ + public function listWorksheetInfo($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + $worksheetInfo = array(); + + $zipClass = PHPExcel_Settings::getZipClass(); + + $zip = new $zipClass; + if (!$zip->open($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! Error opening file."); + } + + $xml = new XMLReader(); + $res = $xml->open('zip://'.realpath($pFilename).'#content.xml', null, PHPExcel_Settings::getLibXmlLoaderOptions()); + $xml->setParserProperty(2,true); + + // Step into the first level of content of the XML + $xml->read(); + while ($xml->read()) { + // Quickly jump through to the office:body node + while ($xml->name !== 'office:body') { + if ($xml->isEmptyElement) + $xml->read(); + else + $xml->next(); + } + // Now read each node until we find our first table:table node + while ($xml->read()) { + if ($xml->name == 'table:table' && $xml->nodeType == XMLReader::ELEMENT) { + $worksheetNames[] = $xml->getAttribute('table:name'); + + $tmpInfo = array( + 'worksheetName' => $xml->getAttribute('table:name'), + 'lastColumnLetter' => 'A', + 'lastColumnIndex' => 0, + 'totalRows' => 0, + 'totalColumns' => 0, + ); + + // Loop through each child node of the table:table element reading + $currCells = 0; + do { + $xml->read(); + if ($xml->name == 'table:table-row' && $xml->nodeType == XMLReader::ELEMENT) { + $rowspan = $xml->getAttribute('table:number-rows-repeated'); + $rowspan = empty($rowspan) ? 1 : $rowspan; + $tmpInfo['totalRows'] += $rowspan; + $tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'],$currCells); + $currCells = 0; + // Step into the row + $xml->read(); + do { + if ($xml->name == 'table:table-cell' && $xml->nodeType == XMLReader::ELEMENT) { + if (!$xml->isEmptyElement) { + $currCells++; + $xml->next(); + } else { + $xml->read(); + } + } elseif ($xml->name == 'table:covered-table-cell' && $xml->nodeType == XMLReader::ELEMENT) { + $mergeSize = $xml->getAttribute('table:number-columns-repeated'); + $currCells += $mergeSize; + $xml->read(); + } + } while ($xml->name != 'table:table-row'); + } + } while ($xml->name != 'table:table'); + + $tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'],$currCells); + $tmpInfo['lastColumnIndex'] = $tmpInfo['totalColumns'] - 1; + $tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']); + $worksheetInfo[] = $tmpInfo; + } + } + +// foreach($workbookData->table as $worksheetDataSet) { +// $worksheetData = $worksheetDataSet->children($namespacesContent['table']); +// $worksheetDataAttributes = $worksheetDataSet->attributes($namespacesContent['table']); +// +// $rowIndex = 0; +// foreach ($worksheetData as $key => $rowData) { +// switch ($key) { +// case 'table-row' : +// $rowDataTableAttributes = $rowData->attributes($namespacesContent['table']); +// $rowRepeats = (isset($rowDataTableAttributes['number-rows-repeated'])) ? +// $rowDataTableAttributes['number-rows-repeated'] : 1; +// $columnIndex = 0; +// +// foreach ($rowData as $key => $cellData) { +// $cellDataTableAttributes = $cellData->attributes($namespacesContent['table']); +// $colRepeats = (isset($cellDataTableAttributes['number-columns-repeated'])) ? +// $cellDataTableAttributes['number-columns-repeated'] : 1; +// $cellDataOfficeAttributes = $cellData->attributes($namespacesContent['office']); +// if (isset($cellDataOfficeAttributes['value-type'])) { +// $tmpInfo['lastColumnIndex'] = max($tmpInfo['lastColumnIndex'], $columnIndex + $colRepeats - 1); +// $tmpInfo['totalRows'] = max($tmpInfo['totalRows'], $rowIndex + $rowRepeats); +// } +// $columnIndex += $colRepeats; +// } +// $rowIndex += $rowRepeats; +// break; +// } +// } +// +// $tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']); +// $tmpInfo['totalColumns'] = $tmpInfo['lastColumnIndex'] + 1; +// +// } +// } + } + + return $worksheetInfo; + } + + + /** + * Loads PHPExcel from file + * + * @param string $pFilename + * @return PHPExcel + * @throws PHPExcel_Reader_Exception + */ + public function load($pFilename) + { + // Create new PHPExcel + $objPHPExcel = new PHPExcel(); + + // Load into this instance + return $this->loadIntoExisting($pFilename, $objPHPExcel); + } + + + private static function identifyFixedStyleValue($styleList,&$styleAttributeValue) { + $styleAttributeValue = strtolower($styleAttributeValue); + foreach($styleList as $style) { + if ($styleAttributeValue == strtolower($style)) { + $styleAttributeValue = $style; + return true; + } + } + return false; + } + + + /** + * Loads PHPExcel from file into PHPExcel instance + * + * @param string $pFilename + * @param PHPExcel $objPHPExcel + * @return PHPExcel + * @throws PHPExcel_Reader_Exception + */ + public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + $timezoneObj = new DateTimeZone('Europe/London'); + $GMT = new DateTimeZone('UTC'); + + $zipClass = PHPExcel_Settings::getZipClass(); + + $zip = new $zipClass; + if (!$zip->open($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! Error opening file."); + } + +// echo '<h1>Meta Information</h1>'; + $xml = simplexml_load_string($zip->getFromName("meta.xml"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $namespacesMeta = $xml->getNamespaces(true); +// echo '<pre>'; +// print_r($namespacesMeta); +// echo '</pre><hr />'; + + $docProps = $objPHPExcel->getProperties(); + $officeProperty = $xml->children($namespacesMeta['office']); + foreach($officeProperty as $officePropertyData) { + $officePropertyDC = array(); + if (isset($namespacesMeta['dc'])) { + $officePropertyDC = $officePropertyData->children($namespacesMeta['dc']); + } + foreach($officePropertyDC as $propertyName => $propertyValue) { + $propertyValue = (string) $propertyValue; + switch ($propertyName) { + case 'title' : + $docProps->setTitle($propertyValue); + break; + case 'subject' : + $docProps->setSubject($propertyValue); + break; + case 'creator' : + $docProps->setCreator($propertyValue); + $docProps->setLastModifiedBy($propertyValue); + break; + case 'date' : + $creationDate = strtotime($propertyValue); + $docProps->setCreated($creationDate); + $docProps->setModified($creationDate); + break; + case 'description' : + $docProps->setDescription($propertyValue); + break; + } + } + $officePropertyMeta = array(); + if (isset($namespacesMeta['dc'])) { + $officePropertyMeta = $officePropertyData->children($namespacesMeta['meta']); + } + foreach($officePropertyMeta as $propertyName => $propertyValue) { + $propertyValueAttributes = $propertyValue->attributes($namespacesMeta['meta']); + $propertyValue = (string) $propertyValue; + switch ($propertyName) { + case 'initial-creator' : + $docProps->setCreator($propertyValue); + break; + case 'keyword' : + $docProps->setKeywords($propertyValue); + break; + case 'creation-date' : + $creationDate = strtotime($propertyValue); + $docProps->setCreated($creationDate); + break; + case 'user-defined' : + $propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_STRING; + foreach ($propertyValueAttributes as $key => $value) { + if ($key == 'name') { + $propertyValueName = (string) $value; + } elseif($key == 'value-type') { + switch ($value) { + case 'date' : + $propertyValue = PHPExcel_DocumentProperties::convertProperty($propertyValue,'date'); + $propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_DATE; + break; + case 'boolean' : + $propertyValue = PHPExcel_DocumentProperties::convertProperty($propertyValue,'bool'); + $propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_BOOLEAN; + break; + case 'float' : + $propertyValue = PHPExcel_DocumentProperties::convertProperty($propertyValue,'r4'); + $propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_FLOAT; + break; + default : + $propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_STRING; + } + } + } + $docProps->setCustomProperty($propertyValueName,$propertyValue,$propertyValueType); + break; + } + } + } + + +// echo '<h1>Workbook Content</h1>'; + $xml = simplexml_load_string($zip->getFromName("content.xml"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $namespacesContent = $xml->getNamespaces(true); +// echo '<pre>'; +// print_r($namespacesContent); +// echo '</pre><hr />'; + + $workbook = $xml->children($namespacesContent['office']); + foreach($workbook->body->spreadsheet as $workbookData) { + $workbookData = $workbookData->children($namespacesContent['table']); + $worksheetID = 0; + foreach($workbookData->table as $worksheetDataSet) { + $worksheetData = $worksheetDataSet->children($namespacesContent['table']); +// print_r($worksheetData); +// echo '<br />'; + $worksheetDataAttributes = $worksheetDataSet->attributes($namespacesContent['table']); +// print_r($worksheetDataAttributes); +// echo '<br />'; + if ((isset($this->_loadSheetsOnly)) && (isset($worksheetDataAttributes['name'])) && + (!in_array($worksheetDataAttributes['name'], $this->_loadSheetsOnly))) { + continue; + } + +// echo '<h2>Worksheet '.$worksheetDataAttributes['name'].'</h2>'; + // Create new Worksheet + $objPHPExcel->createSheet(); + $objPHPExcel->setActiveSheetIndex($worksheetID); + if (isset($worksheetDataAttributes['name'])) { + $worksheetName = (string) $worksheetDataAttributes['name']; + // Use false for $updateFormulaCellReferences to prevent adjustment of worksheet references in + // formula cells... during the load, all formulae should be correct, and we're simply + // bringing the worksheet name in line with the formula, not the reverse + $objPHPExcel->getActiveSheet()->setTitle($worksheetName,false); + } + + $rowID = 1; + foreach($worksheetData as $key => $rowData) { +// echo '<b>'.$key.'</b><br />'; + switch ($key) { + case 'table-header-rows': + foreach ($rowData as $key=>$cellData) { + $rowData = $cellData; + break; + } + case 'table-row' : + $rowDataTableAttributes = $rowData->attributes($namespacesContent['table']); + $rowRepeats = (isset($rowDataTableAttributes['number-rows-repeated'])) ? + $rowDataTableAttributes['number-rows-repeated'] : 1; + $columnID = 'A'; + foreach($rowData as $key => $cellData) { + if ($this->getReadFilter() !== NULL) { + if (!$this->getReadFilter()->readCell($columnID, $rowID, $worksheetName)) { + continue; + } + } + +// echo '<b>'.$columnID.$rowID.'</b><br />'; + $cellDataText = (isset($namespacesContent['text'])) ? + $cellData->children($namespacesContent['text']) : + ''; + $cellDataOffice = $cellData->children($namespacesContent['office']); + $cellDataOfficeAttributes = $cellData->attributes($namespacesContent['office']); + $cellDataTableAttributes = $cellData->attributes($namespacesContent['table']); + +// echo 'Office Attributes: '; +// print_r($cellDataOfficeAttributes); +// echo '<br />Table Attributes: '; +// print_r($cellDataTableAttributes); +// echo '<br />Cell Data Text'; +// print_r($cellDataText); +// echo '<br />'; +// + $type = $formatting = $hyperlink = null; + $hasCalculatedValue = false; + $cellDataFormula = ''; + if (isset($cellDataTableAttributes['formula'])) { + $cellDataFormula = $cellDataTableAttributes['formula']; + $hasCalculatedValue = true; + } + + if (isset($cellDataOffice->annotation)) { +// echo 'Cell has comment<br />'; + $annotationText = $cellDataOffice->annotation->children($namespacesContent['text']); + $textArray = array(); + foreach($annotationText as $t) { + foreach($t->span as $text) { + $textArray[] = (string)$text; + } + } + $text = implode("\n",$textArray); +// echo $text,'<br />'; + $objPHPExcel->getActiveSheet()->getComment( $columnID.$rowID ) +// ->setAuthor( $author ) + ->setText($this->_parseRichText($text) ); + } + + if (isset($cellDataText->p)) { + // Consolidate if there are multiple p records (maybe with spans as well) + $dataArray = array(); + // Text can have multiple text:p and within those, multiple text:span. + // text:p newlines, but text:span does not. + // Also, here we assume there is no text data is span fields are specified, since + // we have no way of knowing proper positioning anyway. + foreach ($cellDataText->p as $pData) { + if (isset($pData->span)) { + // span sections do not newline, so we just create one large string here + $spanSection = ""; + foreach ($pData->span as $spanData) { + $spanSection .= $spanData; + } + array_push($dataArray, $spanSection); + } else { + array_push($dataArray, $pData); + } + } + $allCellDataText = implode($dataArray, "\n"); + +// echo 'Value Type is '.$cellDataOfficeAttributes['value-type'].'<br />'; + switch ($cellDataOfficeAttributes['value-type']) { + case 'string' : + $type = PHPExcel_Cell_DataType::TYPE_STRING; + $dataValue = $allCellDataText; + if (isset($dataValue->a)) { + $dataValue = $dataValue->a; + $cellXLinkAttributes = $dataValue->attributes($namespacesContent['xlink']); + $hyperlink = $cellXLinkAttributes['href']; + } + break; + case 'boolean' : + $type = PHPExcel_Cell_DataType::TYPE_BOOL; + $dataValue = ($allCellDataText == 'TRUE') ? True : False; + break; + case 'percentage' : + $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; + $dataValue = (float) $cellDataOfficeAttributes['value']; + if (floor($dataValue) == $dataValue) { + $dataValue = (integer) $dataValue; + } + $formatting = PHPExcel_Style_NumberFormat::FORMAT_PERCENTAGE_00; + break; + case 'currency' : + $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; + $dataValue = (float) $cellDataOfficeAttributes['value']; + if (floor($dataValue) == $dataValue) { + $dataValue = (integer) $dataValue; + } + $formatting = PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_USD_SIMPLE; + break; + case 'float' : + $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; + $dataValue = (float) $cellDataOfficeAttributes['value']; + if (floor($dataValue) == $dataValue) { + if ($dataValue == (integer) $dataValue) + $dataValue = (integer) $dataValue; + else + $dataValue = (float) $dataValue; + } + break; + case 'date' : + $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; + $dateObj = new DateTime($cellDataOfficeAttributes['date-value'], $GMT); + $dateObj->setTimeZone($timezoneObj); + list($year,$month,$day,$hour,$minute,$second) = explode(' ',$dateObj->format('Y m d H i s')); + $dataValue = PHPExcel_Shared_Date::FormattedPHPToExcel($year,$month,$day,$hour,$minute,$second); + if ($dataValue != floor($dataValue)) { + $formatting = PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX15.' '.PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4; + } else { + $formatting = PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX15; + } + break; + case 'time' : + $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; + $dataValue = PHPExcel_Shared_Date::PHPToExcel(strtotime('01-01-1970 '.implode(':',sscanf($cellDataOfficeAttributes['time-value'],'PT%dH%dM%dS')))); + $formatting = PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4; + break; + } +// echo 'Data value is '.$dataValue.'<br />'; +// if ($hyperlink !== NULL) { +// echo 'Hyperlink is '.$hyperlink.'<br />'; +// } + } else { + $type = PHPExcel_Cell_DataType::TYPE_NULL; + $dataValue = NULL; + } + + if ($hasCalculatedValue) { + $type = PHPExcel_Cell_DataType::TYPE_FORMULA; +// echo 'Formula: ', $cellDataFormula, PHP_EOL; + $cellDataFormula = substr($cellDataFormula,strpos($cellDataFormula,':=')+1); + $temp = explode('"',$cellDataFormula); + $tKey = false; + foreach($temp as &$value) { + // Only replace in alternate array entries (i.e. non-quoted blocks) + if ($tKey = !$tKey) { + $value = preg_replace('/\[([^\.]+)\.([^\.]+):\.([^\.]+)\]/Ui','$1!$2:$3',$value); // Cell range reference in another sheet + $value = preg_replace('/\[([^\.]+)\.([^\.]+)\]/Ui','$1!$2',$value); // Cell reference in another sheet + $value = preg_replace('/\[\.([^\.]+):\.([^\.]+)\]/Ui','$1:$2',$value); // Cell range reference + $value = preg_replace('/\[\.([^\.]+)\]/Ui','$1',$value); // Simple cell reference + $value = PHPExcel_Calculation::_translateSeparator(';',',',$value,$inBraces); + } + } + unset($value); + // Then rebuild the formula string + $cellDataFormula = implode('"',$temp); +// echo 'Adjusted Formula: ', $cellDataFormula, PHP_EOL; + } + + $colRepeats = (isset($cellDataTableAttributes['number-columns-repeated'])) ? + $cellDataTableAttributes['number-columns-repeated'] : 1; + if ($type !== NULL) { + for ($i = 0; $i < $colRepeats; ++$i) { + if ($i > 0) { + ++$columnID; + } + if ($type !== PHPExcel_Cell_DataType::TYPE_NULL) { + for ($rowAdjust = 0; $rowAdjust < $rowRepeats; ++$rowAdjust) { + $rID = $rowID + $rowAdjust; + $objPHPExcel->getActiveSheet()->getCell($columnID.$rID)->setValueExplicit((($hasCalculatedValue) ? $cellDataFormula : $dataValue),$type); + if ($hasCalculatedValue) { +// echo 'Forumla result is '.$dataValue.'<br />'; + $objPHPExcel->getActiveSheet()->getCell($columnID.$rID)->setCalculatedValue($dataValue); + } + if ($formatting !== NULL) { + $objPHPExcel->getActiveSheet()->getStyle($columnID.$rID)->getNumberFormat()->setFormatCode($formatting); + } else { + $objPHPExcel->getActiveSheet()->getStyle($columnID.$rID)->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_GENERAL); + } + if ($hyperlink !== NULL) { + $objPHPExcel->getActiveSheet()->getCell($columnID.$rID)->getHyperlink()->setUrl($hyperlink); + } + } + } + } + } + + // Merged cells + if ((isset($cellDataTableAttributes['number-columns-spanned'])) || (isset($cellDataTableAttributes['number-rows-spanned']))) { + if (($type !== PHPExcel_Cell_DataType::TYPE_NULL) || (!$this->_readDataOnly)) { + $columnTo = $columnID; + if (isset($cellDataTableAttributes['number-columns-spanned'])) { + $columnTo = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::columnIndexFromString($columnID) + $cellDataTableAttributes['number-columns-spanned'] -2); + } + $rowTo = $rowID; + if (isset($cellDataTableAttributes['number-rows-spanned'])) { + $rowTo = $rowTo + $cellDataTableAttributes['number-rows-spanned'] - 1; + } + $cellRange = $columnID.$rowID.':'.$columnTo.$rowTo; + $objPHPExcel->getActiveSheet()->mergeCells($cellRange); + } + } + + ++$columnID; + } + $rowID += $rowRepeats; + break; + } + } + ++$worksheetID; + } + } + + // Return + return $objPHPExcel; + } + + + private function _parseRichText($is = '') { + $value = new PHPExcel_RichText(); + + $value->createText($is); + + return $value; + } + +} diff --git a/lib/phpexcel/PHPExcel/Reader/SYLK.php b/lib/phpexcel/PHPExcel/Reader/SYLK.php new file mode 100644 index 0000000..cd87ce5 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Reader/SYLK.php @@ -0,0 +1,450 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Reader + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** PHPExcel root directory */ +if (!defined('PHPEXCEL_ROOT')) { + /** + * @ignore + */ + define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); + require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); +} + +/** + * PHPExcel_Reader_SYLK + * + * @category PHPExcel + * @package PHPExcel_Reader + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Reader_SYLK extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader +{ + /** + * Input encoding + * + * @var string + */ + private $_inputEncoding = 'ANSI'; + + /** + * Sheet index to read + * + * @var int + */ + private $_sheetIndex = 0; + + /** + * Formats + * + * @var array + */ + private $_formats = array(); + + /** + * Format Count + * + * @var int + */ + private $_format = 0; + + /** + * Create a new PHPExcel_Reader_SYLK + */ + public function __construct() { + $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); + } + + /** + * Validate that the current file is a SYLK file + * + * @return boolean + */ + protected function _isValidFormat() + { + // Read sample data (first 2 KB will do) + $data = fread($this->_fileHandle, 2048); + + // Count delimiters in file + $delimiterCount = substr_count($data, ';'); + if ($delimiterCount < 1) { + return FALSE; + } + + // Analyze first line looking for ID; signature + $lines = explode("\n", $data); + if (substr($lines[0],0,4) != 'ID;P') { + return FALSE; + } + + return TRUE; + } + + /** + * Set input encoding + * + * @param string $pValue Input encoding + */ + public function setInputEncoding($pValue = 'ANSI') + { + $this->_inputEncoding = $pValue; + return $this; + } + + /** + * Get input encoding + * + * @return string + */ + public function getInputEncoding() + { + return $this->_inputEncoding; + } + + /** + * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns) + * + * @param string $pFilename + * @throws PHPExcel_Reader_Exception + */ + public function listWorksheetInfo($pFilename) + { + // Open file + $this->_openFile($pFilename); + if (!$this->_isValidFormat()) { + fclose ($this->_fileHandle); + throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file."); + } + $fileHandle = $this->_fileHandle; + rewind($fileHandle); + + $worksheetInfo = array(); + $worksheetInfo[0]['worksheetName'] = 'Worksheet'; + $worksheetInfo[0]['lastColumnLetter'] = 'A'; + $worksheetInfo[0]['lastColumnIndex'] = 0; + $worksheetInfo[0]['totalRows'] = 0; + $worksheetInfo[0]['totalColumns'] = 0; + + // Loop through file + $rowData = array(); + + // loop through one row (line) at a time in the file + $rowIndex = 0; + while (($rowData = fgets($fileHandle)) !== FALSE) { + $columnIndex = 0; + + // convert SYLK encoded $rowData to UTF-8 + $rowData = PHPExcel_Shared_String::SYLKtoUTF8($rowData); + + // explode each row at semicolons while taking into account that literal semicolon (;) + // is escaped like this (;;) + $rowData = explode("\t",str_replace('¤',';',str_replace(';',"\t",str_replace(';;','¤',rtrim($rowData))))); + + $dataType = array_shift($rowData); + if ($dataType == 'C') { + // Read cell value data + foreach($rowData as $rowDatum) { + switch($rowDatum{0}) { + case 'C' : + case 'X' : + $columnIndex = substr($rowDatum,1) - 1; + break; + case 'R' : + case 'Y' : + $rowIndex = substr($rowDatum,1); + break; + } + + $worksheetInfo[0]['totalRows'] = max($worksheetInfo[0]['totalRows'], $rowIndex); + $worksheetInfo[0]['lastColumnIndex'] = max($worksheetInfo[0]['lastColumnIndex'], $columnIndex); + } + } + } + + $worksheetInfo[0]['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($worksheetInfo[0]['lastColumnIndex']); + $worksheetInfo[0]['totalColumns'] = $worksheetInfo[0]['lastColumnIndex'] + 1; + + // Close file + fclose($fileHandle); + + return $worksheetInfo; + } + + /** + * Loads PHPExcel from file + * + * @param string $pFilename + * @return PHPExcel + * @throws PHPExcel_Reader_Exception + */ + public function load($pFilename) + { + // Create new PHPExcel + $objPHPExcel = new PHPExcel(); + + // Load into this instance + return $this->loadIntoExisting($pFilename, $objPHPExcel); + } + + /** + * Loads PHPExcel from file into PHPExcel instance + * + * @param string $pFilename + * @param PHPExcel $objPHPExcel + * @return PHPExcel + * @throws PHPExcel_Reader_Exception + */ + public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) + { + // Open file + $this->_openFile($pFilename); + if (!$this->_isValidFormat()) { + fclose ($this->_fileHandle); + throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file."); + } + $fileHandle = $this->_fileHandle; + rewind($fileHandle); + + // Create new PHPExcel + while ($objPHPExcel->getSheetCount() <= $this->_sheetIndex) { + $objPHPExcel->createSheet(); + } + $objPHPExcel->setActiveSheetIndex( $this->_sheetIndex ); + + $fromFormats = array('\-', '\ '); + $toFormats = array('-', ' '); + + // Loop through file + $rowData = array(); + $column = $row = ''; + + // loop through one row (line) at a time in the file + while (($rowData = fgets($fileHandle)) !== FALSE) { + + // convert SYLK encoded $rowData to UTF-8 + $rowData = PHPExcel_Shared_String::SYLKtoUTF8($rowData); + + // explode each row at semicolons while taking into account that literal semicolon (;) + // is escaped like this (;;) + $rowData = explode("\t",str_replace('¤',';',str_replace(';',"\t",str_replace(';;','¤',rtrim($rowData))))); + + $dataType = array_shift($rowData); + // Read shared styles + if ($dataType == 'P') { + $formatArray = array(); + foreach($rowData as $rowDatum) { + switch($rowDatum{0}) { + case 'P' : $formatArray['numberformat']['code'] = str_replace($fromFormats,$toFormats,substr($rowDatum,1)); + break; + case 'E' : + case 'F' : $formatArray['font']['name'] = substr($rowDatum,1); + break; + case 'L' : $formatArray['font']['size'] = substr($rowDatum,1); + break; + case 'S' : $styleSettings = substr($rowDatum,1); + for ($i=0;$i<strlen($styleSettings);++$i) { + switch ($styleSettings{$i}) { + case 'I' : $formatArray['font']['italic'] = true; + break; + case 'D' : $formatArray['font']['bold'] = true; + break; + case 'T' : $formatArray['borders']['top']['style'] = PHPExcel_Style_Border::BORDER_THIN; + break; + case 'B' : $formatArray['borders']['bottom']['style'] = PHPExcel_Style_Border::BORDER_THIN; + break; + case 'L' : $formatArray['borders']['left']['style'] = PHPExcel_Style_Border::BORDER_THIN; + break; + case 'R' : $formatArray['borders']['right']['style'] = PHPExcel_Style_Border::BORDER_THIN; + break; + } + } + break; + } + } + $this->_formats['P'.$this->_format++] = $formatArray; + // Read cell value data + } elseif ($dataType == 'C') { + $hasCalculatedValue = false; + $cellData = $cellDataFormula = ''; + foreach($rowData as $rowDatum) { + switch($rowDatum{0}) { + case 'C' : + case 'X' : $column = substr($rowDatum,1); + break; + case 'R' : + case 'Y' : $row = substr($rowDatum,1); + break; + case 'K' : $cellData = substr($rowDatum,1); + break; + case 'E' : $cellDataFormula = '='.substr($rowDatum,1); + // Convert R1C1 style references to A1 style references (but only when not quoted) + $temp = explode('"',$cellDataFormula); + $key = false; + foreach($temp as &$value) { + // Only count/replace in alternate array entries + if ($key = !$key) { + preg_match_all('/(R(\[?-?\d*\]?))(C(\[?-?\d*\]?))/',$value, $cellReferences,PREG_SET_ORDER+PREG_OFFSET_CAPTURE); + // Reverse the matches array, otherwise all our offsets will become incorrect if we modify our way + // through the formula from left to right. Reversing means that we work right to left.through + // the formula + $cellReferences = array_reverse($cellReferences); + // Loop through each R1C1 style reference in turn, converting it to its A1 style equivalent, + // then modify the formula to use that new reference + foreach($cellReferences as $cellReference) { + $rowReference = $cellReference[2][0]; + // Empty R reference is the current row + if ($rowReference == '') $rowReference = $row; + // Bracketed R references are relative to the current row + if ($rowReference{0} == '[') $rowReference = $row + trim($rowReference,'[]'); + $columnReference = $cellReference[4][0]; + // Empty C reference is the current column + if ($columnReference == '') $columnReference = $column; + // Bracketed C references are relative to the current column + if ($columnReference{0} == '[') $columnReference = $column + trim($columnReference,'[]'); + $A1CellReference = PHPExcel_Cell::stringFromColumnIndex($columnReference-1).$rowReference; + + $value = substr_replace($value,$A1CellReference,$cellReference[0][1],strlen($cellReference[0][0])); + } + } + } + unset($value); + // Then rebuild the formula string + $cellDataFormula = implode('"',$temp); + $hasCalculatedValue = true; + break; + } + } + $columnLetter = PHPExcel_Cell::stringFromColumnIndex($column-1); + $cellData = PHPExcel_Calculation::_unwrapResult($cellData); + + // Set cell value + $objPHPExcel->getActiveSheet()->getCell($columnLetter.$row)->setValue(($hasCalculatedValue) ? $cellDataFormula : $cellData); + if ($hasCalculatedValue) { + $cellData = PHPExcel_Calculation::_unwrapResult($cellData); + $objPHPExcel->getActiveSheet()->getCell($columnLetter.$row)->setCalculatedValue($cellData); + } + // Read cell formatting + } elseif ($dataType == 'F') { + $formatStyle = $columnWidth = $styleSettings = ''; + $styleData = array(); + foreach($rowData as $rowDatum) { + switch($rowDatum{0}) { + case 'C' : + case 'X' : $column = substr($rowDatum,1); + break; + case 'R' : + case 'Y' : $row = substr($rowDatum,1); + break; + case 'P' : $formatStyle = $rowDatum; + break; + case 'W' : list($startCol,$endCol,$columnWidth) = explode(' ',substr($rowDatum,1)); + break; + case 'S' : $styleSettings = substr($rowDatum,1); + for ($i=0;$i<strlen($styleSettings);++$i) { + switch ($styleSettings{$i}) { + case 'I' : $styleData['font']['italic'] = true; + break; + case 'D' : $styleData['font']['bold'] = true; + break; + case 'T' : $styleData['borders']['top']['style'] = PHPExcel_Style_Border::BORDER_THIN; + break; + case 'B' : $styleData['borders']['bottom']['style'] = PHPExcel_Style_Border::BORDER_THIN; + break; + case 'L' : $styleData['borders']['left']['style'] = PHPExcel_Style_Border::BORDER_THIN; + break; + case 'R' : $styleData['borders']['right']['style'] = PHPExcel_Style_Border::BORDER_THIN; + break; + } + } + break; + } + } + if (($formatStyle > '') && ($column > '') && ($row > '')) { + $columnLetter = PHPExcel_Cell::stringFromColumnIndex($column-1); + if (isset($this->_formats[$formatStyle])) { + $objPHPExcel->getActiveSheet()->getStyle($columnLetter.$row)->applyFromArray($this->_formats[$formatStyle]); + } + } + if ((!empty($styleData)) && ($column > '') && ($row > '')) { + $columnLetter = PHPExcel_Cell::stringFromColumnIndex($column-1); + $objPHPExcel->getActiveSheet()->getStyle($columnLetter.$row)->applyFromArray($styleData); + } + if ($columnWidth > '') { + if ($startCol == $endCol) { + $startCol = PHPExcel_Cell::stringFromColumnIndex($startCol-1); + $objPHPExcel->getActiveSheet()->getColumnDimension($startCol)->setWidth($columnWidth); + } else { + $startCol = PHPExcel_Cell::stringFromColumnIndex($startCol-1); + $endCol = PHPExcel_Cell::stringFromColumnIndex($endCol-1); + $objPHPExcel->getActiveSheet()->getColumnDimension($startCol)->setWidth($columnWidth); + do { + $objPHPExcel->getActiveSheet()->getColumnDimension(++$startCol)->setWidth($columnWidth); + } while ($startCol != $endCol); + } + } + } else { + foreach($rowData as $rowDatum) { + switch($rowDatum{0}) { + case 'C' : + case 'X' : $column = substr($rowDatum,1); + break; + case 'R' : + case 'Y' : $row = substr($rowDatum,1); + break; + } + } + } + } + + // Close file + fclose($fileHandle); + + // Return + return $objPHPExcel; + } + + /** + * Get sheet index + * + * @return int + */ + public function getSheetIndex() { + return $this->_sheetIndex; + } + + /** + * Set sheet index + * + * @param int $pValue Sheet index + * @return PHPExcel_Reader_SYLK + */ + public function setSheetIndex($pValue = 0) { + $this->_sheetIndex = $pValue; + return $this; + } + +} diff --git a/lib/phpexcel/PHPExcel/ReferenceHelper.php b/lib/phpexcel/PHPExcel/ReferenceHelper.php new file mode 100644 index 0000000..402f2b4 --- /dev/null +++ b/lib/phpexcel/PHPExcel/ReferenceHelper.php @@ -0,0 +1,922 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_ReferenceHelper (Singleton) + * + * @category PHPExcel + * @package PHPExcel + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_ReferenceHelper +{ + /** Constants */ + /** Regular Expressions */ + const REFHELPER_REGEXP_CELLREF = '((\w*|\'[^!]*\')!)?(?<![:a-z\$])(\$?[a-z]{1,3}\$?\d+)(?=[^:!\d\'])'; + const REFHELPER_REGEXP_CELLRANGE = '((\w*|\'[^!]*\')!)?(\$?[a-z]{1,3}\$?\d+):(\$?[a-z]{1,3}\$?\d+)'; + const REFHELPER_REGEXP_ROWRANGE = '((\w*|\'[^!]*\')!)?(\$?\d+):(\$?\d+)'; + const REFHELPER_REGEXP_COLRANGE = '((\w*|\'[^!]*\')!)?(\$?[a-z]{1,3}):(\$?[a-z]{1,3})'; + + /** + * Instance of this class + * + * @var PHPExcel_ReferenceHelper + */ + private static $_instance; + + /** + * Get an instance of this class + * + * @return PHPExcel_ReferenceHelper + */ + public static function getInstance() { + if (!isset(self::$_instance) || (self::$_instance === NULL)) { + self::$_instance = new PHPExcel_ReferenceHelper(); + } + + return self::$_instance; + } + + /** + * Create a new PHPExcel_ReferenceHelper + */ + protected function __construct() { + } + + /** + * Compare two column addresses + * Intended for use as a Callback function for sorting column addresses by column + * + * @param string $a First column to test (e.g. 'AA') + * @param string $b Second column to test (e.g. 'Z') + * @return integer + */ + public static function columnSort($a, $b) { + return strcasecmp(strlen($a) . $a, strlen($b) . $b); + } + + /** + * Compare two column addresses + * Intended for use as a Callback function for reverse sorting column addresses by column + * + * @param string $a First column to test (e.g. 'AA') + * @param string $b Second column to test (e.g. 'Z') + * @return integer + */ + public static function columnReverseSort($a, $b) { + return 1 - strcasecmp(strlen($a) . $a, strlen($b) . $b); + } + + /** + * Compare two cell addresses + * Intended for use as a Callback function for sorting cell addresses by column and row + * + * @param string $a First cell to test (e.g. 'AA1') + * @param string $b Second cell to test (e.g. 'Z1') + * @return integer + */ + public static function cellSort($a, $b) { + sscanf($a,'%[A-Z]%d', $ac, $ar); + sscanf($b,'%[A-Z]%d', $bc, $br); + + if ($ar == $br) { + return strcasecmp(strlen($ac) . $ac, strlen($bc) . $bc); + } + return ($ar < $br) ? -1 : 1; + } + + /** + * Compare two cell addresses + * Intended for use as a Callback function for sorting cell addresses by column and row + * + * @param string $a First cell to test (e.g. 'AA1') + * @param string $b Second cell to test (e.g. 'Z1') + * @return integer + */ + public static function cellReverseSort($a, $b) { + sscanf($a,'%[A-Z]%d', $ac, $ar); + sscanf($b,'%[A-Z]%d', $bc, $br); + + if ($ar == $br) { + return 1 - strcasecmp(strlen($ac) . $ac, strlen($bc) . $bc); + } + return ($ar < $br) ? 1 : -1; + } + + /** + * Test whether a cell address falls within a defined range of cells + * + * @param string $cellAddress Address of the cell we're testing + * @param integer $beforeRow Number of the row we're inserting/deleting before + * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) + * @param integer $beforeColumnIndex Index number of the column we're inserting/deleting before + * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) + * @return boolean + */ + private static function cellAddressInDeleteRange($cellAddress, $beforeRow, $pNumRows, $beforeColumnIndex, $pNumCols) { + list($cellColumn, $cellRow) = PHPExcel_Cell::coordinateFromString($cellAddress); + $cellColumnIndex = PHPExcel_Cell::columnIndexFromString($cellColumn); + // Is cell within the range of rows/columns if we're deleting + if ($pNumRows < 0 && + ($cellRow >= ($beforeRow + $pNumRows)) && + ($cellRow < $beforeRow)) { + return TRUE; + } elseif ($pNumCols < 0 && + ($cellColumnIndex >= ($beforeColumnIndex + $pNumCols)) && + ($cellColumnIndex < $beforeColumnIndex)) { + return TRUE; + } + return FALSE; + } + + /** + * Update page breaks when inserting/deleting rows/columns + * + * @param PHPExcel_Worksheet $pSheet The worksheet that we're editing + * @param string $pBefore Insert/Delete before this cell address (e.g. 'A1') + * @param integer $beforeColumnIndex Index number of the column we're inserting/deleting before + * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) + * @param integer $beforeRow Number of the row we're inserting/deleting before + * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) + */ + protected function _adjustPageBreaks(PHPExcel_Worksheet $pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) + { + $aBreaks = $pSheet->getBreaks(); + ($pNumCols > 0 || $pNumRows > 0) ? + uksort($aBreaks, array('PHPExcel_ReferenceHelper','cellReverseSort')) : + uksort($aBreaks, array('PHPExcel_ReferenceHelper','cellSort')); + + foreach ($aBreaks as $key => $value) { + if (self::cellAddressInDeleteRange($key, $beforeRow, $pNumRows, $beforeColumnIndex, $pNumCols)) { + // If we're deleting, then clear any defined breaks that are within the range + // of rows/columns that we're deleting + $pSheet->setBreak($key, PHPExcel_Worksheet::BREAK_NONE); + } else { + // Otherwise update any affected breaks by inserting a new break at the appropriate point + // and removing the old affected break + $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); + if ($key != $newReference) { + $pSheet->setBreak($newReference, $value) + ->setBreak($key, PHPExcel_Worksheet::BREAK_NONE); + } + } + } + } + + /** + * Update cell comments when inserting/deleting rows/columns + * + * @param PHPExcel_Worksheet $pSheet The worksheet that we're editing + * @param string $pBefore Insert/Delete before this cell address (e.g. 'A1') + * @param integer $beforeColumnIndex Index number of the column we're inserting/deleting before + * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) + * @param integer $beforeRow Number of the row we're inserting/deleting before + * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) + */ + protected function _adjustComments($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) + { + $aComments = $pSheet->getComments(); + $aNewComments = array(); // the new array of all comments + + foreach ($aComments as $key => &$value) { + // Any comments inside a deleted range will be ignored + if (!self::cellAddressInDeleteRange($key, $beforeRow, $pNumRows, $beforeColumnIndex, $pNumCols)) { + // Otherwise build a new array of comments indexed by the adjusted cell reference + $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); + $aNewComments[$newReference] = $value; + } + } + // Replace the comments array with the new set of comments + $pSheet->setComments($aNewComments); + } + + /** + * Update hyperlinks when inserting/deleting rows/columns + * + * @param PHPExcel_Worksheet $pSheet The worksheet that we're editing + * @param string $pBefore Insert/Delete before this cell address (e.g. 'A1') + * @param integer $beforeColumnIndex Index number of the column we're inserting/deleting before + * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) + * @param integer $beforeRow Number of the row we're inserting/deleting before + * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) + */ + protected function _adjustHyperlinks($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) + { + $aHyperlinkCollection = $pSheet->getHyperlinkCollection(); + ($pNumCols > 0 || $pNumRows > 0) ? + uksort($aHyperlinkCollection, array('PHPExcel_ReferenceHelper','cellReverseSort')) : + uksort($aHyperlinkCollection, array('PHPExcel_ReferenceHelper','cellSort')); + + foreach ($aHyperlinkCollection as $key => $value) { + $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); + if ($key != $newReference) { + $pSheet->setHyperlink( $newReference, $value ); + $pSheet->setHyperlink( $key, null ); + } + } + } + + /** + * Update data validations when inserting/deleting rows/columns + * + * @param PHPExcel_Worksheet $pSheet The worksheet that we're editing + * @param string $pBefore Insert/Delete before this cell address (e.g. 'A1') + * @param integer $beforeColumnIndex Index number of the column we're inserting/deleting before + * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) + * @param integer $beforeRow Number of the row we're inserting/deleting before + * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) + */ + protected function _adjustDataValidations($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) + { + $aDataValidationCollection = $pSheet->getDataValidationCollection(); + ($pNumCols > 0 || $pNumRows > 0) ? + uksort($aDataValidationCollection, array('PHPExcel_ReferenceHelper','cellReverseSort')) : + uksort($aDataValidationCollection, array('PHPExcel_ReferenceHelper','cellSort')); + foreach ($aDataValidationCollection as $key => $value) { + $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); + if ($key != $newReference) { + $pSheet->setDataValidation( $newReference, $value ); + $pSheet->setDataValidation( $key, null ); + } + } + } + + /** + * Update merged cells when inserting/deleting rows/columns + * + * @param PHPExcel_Worksheet $pSheet The worksheet that we're editing + * @param string $pBefore Insert/Delete before this cell address (e.g. 'A1') + * @param integer $beforeColumnIndex Index number of the column we're inserting/deleting before + * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) + * @param integer $beforeRow Number of the row we're inserting/deleting before + * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) + */ + protected function _adjustMergeCells($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) + { + $aMergeCells = $pSheet->getMergeCells(); + $aNewMergeCells = array(); // the new array of all merge cells + foreach ($aMergeCells as $key => &$value) { + $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); + $aNewMergeCells[$newReference] = $newReference; + } + $pSheet->setMergeCells($aNewMergeCells); // replace the merge cells array + } + + /** + * Update protected cells when inserting/deleting rows/columns + * + * @param PHPExcel_Worksheet $pSheet The worksheet that we're editing + * @param string $pBefore Insert/Delete before this cell address (e.g. 'A1') + * @param integer $beforeColumnIndex Index number of the column we're inserting/deleting before + * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) + * @param integer $beforeRow Number of the row we're inserting/deleting before + * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) + */ + protected function _adjustProtectedCells($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) + { + $aProtectedCells = $pSheet->getProtectedCells(); + ($pNumCols > 0 || $pNumRows > 0) ? + uksort($aProtectedCells, array('PHPExcel_ReferenceHelper','cellReverseSort')) : + uksort($aProtectedCells, array('PHPExcel_ReferenceHelper','cellSort')); + foreach ($aProtectedCells as $key => $value) { + $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); + if ($key != $newReference) { + $pSheet->protectCells( $newReference, $value, true ); + $pSheet->unprotectCells( $key ); + } + } + } + + /** + * Update column dimensions when inserting/deleting rows/columns + * + * @param PHPExcel_Worksheet $pSheet The worksheet that we're editing + * @param string $pBefore Insert/Delete before this cell address (e.g. 'A1') + * @param integer $beforeColumnIndex Index number of the column we're inserting/deleting before + * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) + * @param integer $beforeRow Number of the row we're inserting/deleting before + * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) + */ + protected function _adjustColumnDimensions($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) + { + $aColumnDimensions = array_reverse($pSheet->getColumnDimensions(), true); + if (!empty($aColumnDimensions)) { + foreach ($aColumnDimensions as $objColumnDimension) { + $newReference = $this->updateCellReference($objColumnDimension->getColumnIndex() . '1', $pBefore, $pNumCols, $pNumRows); + list($newReference) = PHPExcel_Cell::coordinateFromString($newReference); + if ($objColumnDimension->getColumnIndex() != $newReference) { + $objColumnDimension->setColumnIndex($newReference); + } + } + $pSheet->refreshColumnDimensions(); + } + } + + /** + * Update row dimensions when inserting/deleting rows/columns + * + * @param PHPExcel_Worksheet $pSheet The worksheet that we're editing + * @param string $pBefore Insert/Delete before this cell address (e.g. 'A1') + * @param integer $beforeColumnIndex Index number of the column we're inserting/deleting before + * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) + * @param integer $beforeRow Number of the row we're inserting/deleting before + * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) + */ + protected function _adjustRowDimensions($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) + { + $aRowDimensions = array_reverse($pSheet->getRowDimensions(), true); + if (!empty($aRowDimensions)) { + foreach ($aRowDimensions as $objRowDimension) { + $newReference = $this->updateCellReference('A' . $objRowDimension->getRowIndex(), $pBefore, $pNumCols, $pNumRows); + list(, $newReference) = PHPExcel_Cell::coordinateFromString($newReference); + if ($objRowDimension->getRowIndex() != $newReference) { + $objRowDimension->setRowIndex($newReference); + } + } + $pSheet->refreshRowDimensions(); + + $copyDimension = $pSheet->getRowDimension($beforeRow - 1); + for ($i = $beforeRow; $i <= $beforeRow - 1 + $pNumRows; ++$i) { + $newDimension = $pSheet->getRowDimension($i); + $newDimension->setRowHeight($copyDimension->getRowHeight()); + $newDimension->setVisible($copyDimension->getVisible()); + $newDimension->setOutlineLevel($copyDimension->getOutlineLevel()); + $newDimension->setCollapsed($copyDimension->getCollapsed()); + } + } + } + + /** + * Insert a new column or row, updating all possible related data + * + * @param string $pBefore Insert before this cell address (e.g. 'A1') + * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) + * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) + * @param PHPExcel_Worksheet $pSheet The worksheet that we're editing + * @throws PHPExcel_Exception + */ + public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, PHPExcel_Worksheet $pSheet = NULL) + { + $remove = ($pNumCols < 0 || $pNumRows < 0); + $aCellCollection = $pSheet->getCellCollection(); + + // Get coordinates of $pBefore + $beforeColumn = 'A'; + $beforeRow = 1; + list($beforeColumn, $beforeRow) = PHPExcel_Cell::coordinateFromString($pBefore); + $beforeColumnIndex = PHPExcel_Cell::columnIndexFromString($beforeColumn); + + // Clear cells if we are removing columns or rows + $highestColumn = $pSheet->getHighestColumn(); + $highestRow = $pSheet->getHighestRow(); + + // 1. Clear column strips if we are removing columns + if ($pNumCols < 0 && $beforeColumnIndex - 2 + $pNumCols > 0) { + for ($i = 1; $i <= $highestRow - 1; ++$i) { + for ($j = $beforeColumnIndex - 1 + $pNumCols; $j <= $beforeColumnIndex - 2; ++$j) { + $coordinate = PHPExcel_Cell::stringFromColumnIndex($j) . $i; + $pSheet->removeConditionalStyles($coordinate); + if ($pSheet->cellExists($coordinate)) { + $pSheet->getCell($coordinate)->setValueExplicit('', PHPExcel_Cell_DataType::TYPE_NULL); + $pSheet->getCell($coordinate)->setXfIndex(0); + } + } + } + } + + // 2. Clear row strips if we are removing rows + if ($pNumRows < 0 && $beforeRow - 1 + $pNumRows > 0) { + for ($i = $beforeColumnIndex - 1; $i <= PHPExcel_Cell::columnIndexFromString($highestColumn) - 1; ++$i) { + for ($j = $beforeRow + $pNumRows; $j <= $beforeRow - 1; ++$j) { + $coordinate = PHPExcel_Cell::stringFromColumnIndex($i) . $j; + $pSheet->removeConditionalStyles($coordinate); + if ($pSheet->cellExists($coordinate)) { + $pSheet->getCell($coordinate)->setValueExplicit('', PHPExcel_Cell_DataType::TYPE_NULL); + $pSheet->getCell($coordinate)->setXfIndex(0); + } + } + } + } + + // Loop through cells, bottom-up, and change cell coordinates + if($remove) { + // It's faster to reverse and pop than to use unshift, especially with large cell collections + $aCellCollection = array_reverse($aCellCollection); + } + while ($cellID = array_pop($aCellCollection)) { + $cell = $pSheet->getCell($cellID); + $cellIndex = PHPExcel_Cell::columnIndexFromString($cell->getColumn()); + + if ($cellIndex-1 + $pNumCols < 0) { + continue; + } + + // New coordinates + $newCoordinates = PHPExcel_Cell::stringFromColumnIndex($cellIndex-1 + $pNumCols) . ($cell->getRow() + $pNumRows); + + // Should the cell be updated? Move value and cellXf index from one cell to another. + if (($cellIndex >= $beforeColumnIndex) && + ($cell->getRow() >= $beforeRow)) { + + // Update cell styles + $pSheet->getCell($newCoordinates)->setXfIndex($cell->getXfIndex()); + + // Insert this cell at its new location + if ($cell->getDataType() == PHPExcel_Cell_DataType::TYPE_FORMULA) { + // Formula should be adjusted + $pSheet->getCell($newCoordinates) + ->setValue($this->updateFormulaReferences($cell->getValue(), + $pBefore, $pNumCols, $pNumRows, $pSheet->getTitle())); + } else { + // Formula should not be adjusted + $pSheet->getCell($newCoordinates)->setValue($cell->getValue()); + } + + // Clear the original cell + $pSheet->getCellCacheController()->deleteCacheData($cellID); + + } else { + /* We don't need to update styles for rows/columns before our insertion position, + but we do still need to adjust any formulae in those cells */ + if ($cell->getDataType() == PHPExcel_Cell_DataType::TYPE_FORMULA) { + // Formula should be adjusted + $cell->setValue($this->updateFormulaReferences($cell->getValue(), + $pBefore, $pNumCols, $pNumRows, $pSheet->getTitle())); + } + + } + } + + // Duplicate styles for the newly inserted cells + $highestColumn = $pSheet->getHighestColumn(); + $highestRow = $pSheet->getHighestRow(); + + if ($pNumCols > 0 && $beforeColumnIndex - 2 > 0) { + for ($i = $beforeRow; $i <= $highestRow - 1; ++$i) { + + // Style + $coordinate = PHPExcel_Cell::stringFromColumnIndex( $beforeColumnIndex - 2 ) . $i; + if ($pSheet->cellExists($coordinate)) { + $xfIndex = $pSheet->getCell($coordinate)->getXfIndex(); + $conditionalStyles = $pSheet->conditionalStylesExists($coordinate) ? + $pSheet->getConditionalStyles($coordinate) : false; + for ($j = $beforeColumnIndex - 1; $j <= $beforeColumnIndex - 2 + $pNumCols; ++$j) { + $pSheet->getCellByColumnAndRow($j, $i)->setXfIndex($xfIndex); + if ($conditionalStyles) { + $cloned = array(); + foreach ($conditionalStyles as $conditionalStyle) { + $cloned[] = clone $conditionalStyle; + } + $pSheet->setConditionalStyles(PHPExcel_Cell::stringFromColumnIndex($j) . $i, $cloned); + } + } + } + + } + } + + if ($pNumRows > 0 && $beforeRow - 1 > 0) { + for ($i = $beforeColumnIndex - 1; $i <= PHPExcel_Cell::columnIndexFromString($highestColumn) - 1; ++$i) { + + // Style + $coordinate = PHPExcel_Cell::stringFromColumnIndex($i) . ($beforeRow - 1); + if ($pSheet->cellExists($coordinate)) { + $xfIndex = $pSheet->getCell($coordinate)->getXfIndex(); + $conditionalStyles = $pSheet->conditionalStylesExists($coordinate) ? + $pSheet->getConditionalStyles($coordinate) : false; + for ($j = $beforeRow; $j <= $beforeRow - 1 + $pNumRows; ++$j) { + $pSheet->getCell(PHPExcel_Cell::stringFromColumnIndex($i) . $j)->setXfIndex($xfIndex); + if ($conditionalStyles) { + $cloned = array(); + foreach ($conditionalStyles as $conditionalStyle) { + $cloned[] = clone $conditionalStyle; + } + $pSheet->setConditionalStyles(PHPExcel_Cell::stringFromColumnIndex($i) . $j, $cloned); + } + } + } + } + } + + // Update worksheet: column dimensions + $this->_adjustColumnDimensions($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); + + // Update worksheet: row dimensions + $this->_adjustRowDimensions($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); + + // Update worksheet: page breaks + $this->_adjustPageBreaks($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); + + // Update worksheet: comments + $this->_adjustComments($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); + + // Update worksheet: hyperlinks + $this->_adjustHyperlinks($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); + + // Update worksheet: data validations + $this->_adjustDataValidations($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); + + // Update worksheet: merge cells + $this->_adjustMergeCells($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); + + // Update worksheet: protected cells + $this->_adjustProtectedCells($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); + + // Update worksheet: autofilter + $autoFilter = $pSheet->getAutoFilter(); + $autoFilterRange = $autoFilter->getRange(); + if (!empty($autoFilterRange)) { + if ($pNumCols != 0) { + $autoFilterColumns = array_keys($autoFilter->getColumns()); + if (count($autoFilterColumns) > 0) { + sscanf($pBefore,'%[A-Z]%d', $column, $row); + $columnIndex = PHPExcel_Cell::columnIndexFromString($column); + list($rangeStart,$rangeEnd) = PHPExcel_Cell::rangeBoundaries($autoFilterRange); + if ($columnIndex <= $rangeEnd[0]) { + if ($pNumCols < 0) { + // If we're actually deleting any columns that fall within the autofilter range, + // then we delete any rules for those columns + $deleteColumn = $columnIndex + $pNumCols - 1; + $deleteCount = abs($pNumCols); + for ($i = 1; $i <= $deleteCount; ++$i) { + if (in_array(PHPExcel_Cell::stringFromColumnIndex($deleteColumn),$autoFilterColumns)) { + $autoFilter->clearColumn(PHPExcel_Cell::stringFromColumnIndex($deleteColumn)); + } + ++$deleteColumn; + } + } + $startCol = ($columnIndex > $rangeStart[0]) ? $columnIndex : $rangeStart[0]; + + // Shuffle columns in autofilter range + if ($pNumCols > 0) { + // For insert, we shuffle from end to beginning to avoid overwriting + $startColID = PHPExcel_Cell::stringFromColumnIndex($startCol-1); + $toColID = PHPExcel_Cell::stringFromColumnIndex($startCol+$pNumCols-1); + $endColID = PHPExcel_Cell::stringFromColumnIndex($rangeEnd[0]); + + $startColRef = $startCol; + $endColRef = $rangeEnd[0]; + $toColRef = $rangeEnd[0]+$pNumCols; + + do { + $autoFilter->shiftColumn(PHPExcel_Cell::stringFromColumnIndex($endColRef-1),PHPExcel_Cell::stringFromColumnIndex($toColRef-1)); + --$endColRef; + --$toColRef; + } while ($startColRef <= $endColRef); + } else { + // For delete, we shuffle from beginning to end to avoid overwriting + $startColID = PHPExcel_Cell::stringFromColumnIndex($startCol-1); + $toColID = PHPExcel_Cell::stringFromColumnIndex($startCol+$pNumCols-1); + $endColID = PHPExcel_Cell::stringFromColumnIndex($rangeEnd[0]); + do { + $autoFilter->shiftColumn($startColID,$toColID); + ++$startColID; + ++$toColID; + } while ($startColID != $endColID); + } + } + } + } + $pSheet->setAutoFilter( $this->updateCellReference($autoFilterRange, $pBefore, $pNumCols, $pNumRows) ); + } + + // Update worksheet: freeze pane + if ($pSheet->getFreezePane() != '') { + $pSheet->freezePane( $this->updateCellReference($pSheet->getFreezePane(), $pBefore, $pNumCols, $pNumRows) ); + } + + // Page setup + if ($pSheet->getPageSetup()->isPrintAreaSet()) { + $pSheet->getPageSetup()->setPrintArea( $this->updateCellReference($pSheet->getPageSetup()->getPrintArea(), $pBefore, $pNumCols, $pNumRows) ); + } + + // Update worksheet: drawings + $aDrawings = $pSheet->getDrawingCollection(); + foreach ($aDrawings as $objDrawing) { + $newReference = $this->updateCellReference($objDrawing->getCoordinates(), $pBefore, $pNumCols, $pNumRows); + if ($objDrawing->getCoordinates() != $newReference) { + $objDrawing->setCoordinates($newReference); + } + } + + // Update workbook: named ranges + if (count($pSheet->getParent()->getNamedRanges()) > 0) { + foreach ($pSheet->getParent()->getNamedRanges() as $namedRange) { + if ($namedRange->getWorksheet()->getHashCode() == $pSheet->getHashCode()) { + $namedRange->setRange( + $this->updateCellReference($namedRange->getRange(), $pBefore, $pNumCols, $pNumRows) + ); + } + } + } + + // Garbage collect + $pSheet->garbageCollect(); + } + + /** + * Update references within formulas + * + * @param string $pFormula Formula to update + * @param int $pBefore Insert before this one + * @param int $pNumCols Number of columns to insert + * @param int $pNumRows Number of rows to insert + * @param string $sheetName Worksheet name/title + * @return string Updated formula + * @throws PHPExcel_Exception + */ + public function updateFormulaReferences($pFormula = '', $pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, $sheetName = '') { + // Update cell references in the formula + $formulaBlocks = explode('"',$pFormula); + $i = false; + foreach($formulaBlocks as &$formulaBlock) { + // Ignore blocks that were enclosed in quotes (alternating entries in the $formulaBlocks array after the explode) + if ($i = !$i) { + $adjustCount = 0; + $newCellTokens = $cellTokens = array(); + // Search for row ranges (e.g. 'Sheet1'!3:5 or 3:5) with or without $ absolutes (e.g. $3:5) + $matchCount = preg_match_all('/'.self::REFHELPER_REGEXP_ROWRANGE.'/i', ' '.$formulaBlock.' ', $matches, PREG_SET_ORDER); + if ($matchCount > 0) { + foreach($matches as $match) { + $fromString = ($match[2] > '') ? $match[2].'!' : ''; + $fromString .= $match[3].':'.$match[4]; + $modified3 = substr($this->updateCellReference('$A'.$match[3],$pBefore,$pNumCols,$pNumRows),2); + $modified4 = substr($this->updateCellReference('$A'.$match[4],$pBefore,$pNumCols,$pNumRows),2); + + if ($match[3].':'.$match[4] !== $modified3.':'.$modified4) { + if (($match[2] == '') || (trim($match[2],"'") == $sheetName)) { + $toString = ($match[2] > '') ? $match[2].'!' : ''; + $toString .= $modified3.':'.$modified4; + // Max worksheet size is 1,048,576 rows by 16,384 columns in Excel 2007, so our adjustments need to be at least one digit more + $column = 100000; + $row = 10000000+trim($match[3],'$'); + $cellIndex = $column.$row; + + $newCellTokens[$cellIndex] = preg_quote($toString); + $cellTokens[$cellIndex] = '/(?<!\d\$\!)'.preg_quote($fromString).'(?!\d)/i'; + ++$adjustCount; + } + } + } + } + // Search for column ranges (e.g. 'Sheet1'!C:E or C:E) with or without $ absolutes (e.g. $C:E) + $matchCount = preg_match_all('/'.self::REFHELPER_REGEXP_COLRANGE.'/i', ' '.$formulaBlock.' ', $matches, PREG_SET_ORDER); + if ($matchCount > 0) { + foreach($matches as $match) { + $fromString = ($match[2] > '') ? $match[2].'!' : ''; + $fromString .= $match[3].':'.$match[4]; + $modified3 = substr($this->updateCellReference($match[3].'$1',$pBefore,$pNumCols,$pNumRows),0,-2); + $modified4 = substr($this->updateCellReference($match[4].'$1',$pBefore,$pNumCols,$pNumRows),0,-2); + + if ($match[3].':'.$match[4] !== $modified3.':'.$modified4) { + if (($match[2] == '') || (trim($match[2],"'") == $sheetName)) { + $toString = ($match[2] > '') ? $match[2].'!' : ''; + $toString .= $modified3.':'.$modified4; + // Max worksheet size is 1,048,576 rows by 16,384 columns in Excel 2007, so our adjustments need to be at least one digit more + $column = PHPExcel_Cell::columnIndexFromString(trim($match[3],'$')) + 100000; + $row = 10000000; + $cellIndex = $column.$row; + + $newCellTokens[$cellIndex] = preg_quote($toString); + $cellTokens[$cellIndex] = '/(?<![A-Z\$\!])'.preg_quote($fromString).'(?![A-Z])/i'; + ++$adjustCount; + } + } + } + } + // Search for cell ranges (e.g. 'Sheet1'!A3:C5 or A3:C5) with or without $ absolutes (e.g. $A1:C$5) + $matchCount = preg_match_all('/'.self::REFHELPER_REGEXP_CELLRANGE.'/i', ' '.$formulaBlock.' ', $matches, PREG_SET_ORDER); + if ($matchCount > 0) { + foreach($matches as $match) { + $fromString = ($match[2] > '') ? $match[2].'!' : ''; + $fromString .= $match[3].':'.$match[4]; + $modified3 = $this->updateCellReference($match[3],$pBefore,$pNumCols,$pNumRows); + $modified4 = $this->updateCellReference($match[4],$pBefore,$pNumCols,$pNumRows); + + if ($match[3].$match[4] !== $modified3.$modified4) { + if (($match[2] == '') || (trim($match[2],"'") == $sheetName)) { + $toString = ($match[2] > '') ? $match[2].'!' : ''; + $toString .= $modified3.':'.$modified4; + list($column,$row) = PHPExcel_Cell::coordinateFromString($match[3]); + // Max worksheet size is 1,048,576 rows by 16,384 columns in Excel 2007, so our adjustments need to be at least one digit more + $column = PHPExcel_Cell::columnIndexFromString(trim($column,'$')) + 100000; + $row = trim($row,'$') + 10000000; + $cellIndex = $column.$row; + + $newCellTokens[$cellIndex] = preg_quote($toString); + $cellTokens[$cellIndex] = '/(?<![A-Z]\$\!)'.preg_quote($fromString).'(?!\d)/i'; + ++$adjustCount; + } + } + } + } + // Search for cell references (e.g. 'Sheet1'!A3 or C5) with or without $ absolutes (e.g. $A1 or C$5) + $matchCount = preg_match_all('/'.self::REFHELPER_REGEXP_CELLREF.'/i', ' '.$formulaBlock.' ', $matches, PREG_SET_ORDER); + + if ($matchCount > 0) { + foreach($matches as $match) { + $fromString = ($match[2] > '') ? $match[2].'!' : ''; + $fromString .= $match[3]; + + $modified3 = $this->updateCellReference($match[3],$pBefore,$pNumCols,$pNumRows); + if ($match[3] !== $modified3) { + if (($match[2] == '') || (trim($match[2],"'") == $sheetName)) { + $toString = ($match[2] > '') ? $match[2].'!' : ''; + $toString .= $modified3; + list($column,$row) = PHPExcel_Cell::coordinateFromString($match[3]); + // Max worksheet size is 1,048,576 rows by 16,384 columns in Excel 2007, so our adjustments need to be at least one digit more + $column = PHPExcel_Cell::columnIndexFromString(trim($column,'$')) + 100000; + $row = trim($row,'$') + 10000000; + $cellIndex = $row . $column; + + $newCellTokens[$cellIndex] = preg_quote($toString); + $cellTokens[$cellIndex] = '/(?<![A-Z\$\!])'.preg_quote($fromString).'(?!\d)/i'; + ++$adjustCount; + } + } + } + } + if ($adjustCount > 0) { + if ($pNumCols > 0 || $pNumRows > 0) { + krsort($cellTokens); + krsort($newCellTokens); + } else { + ksort($cellTokens); + ksort($newCellTokens); + } // Update cell references in the formula + $formulaBlock = str_replace('\\','',preg_replace($cellTokens,$newCellTokens,$formulaBlock)); + } + } + } + unset($formulaBlock); + + // Then rebuild the formula string + return implode('"',$formulaBlocks); + } + + /** + * Update cell reference + * + * @param string $pCellRange Cell range + * @param int $pBefore Insert before this one + * @param int $pNumCols Number of columns to increment + * @param int $pNumRows Number of rows to increment + * @return string Updated cell range + * @throws PHPExcel_Exception + */ + public function updateCellReference($pCellRange = 'A1', $pBefore = 'A1', $pNumCols = 0, $pNumRows = 0) { + // Is it in another worksheet? Will not have to update anything. + if (strpos($pCellRange, "!") !== false) { + return $pCellRange; + // Is it a range or a single cell? + } elseif (strpos($pCellRange, ':') === false && strpos($pCellRange, ',') === false) { + // Single cell + return $this->_updateSingleCellReference($pCellRange, $pBefore, $pNumCols, $pNumRows); + } elseif (strpos($pCellRange, ':') !== false || strpos($pCellRange, ',') !== false) { + // Range + return $this->_updateCellRange($pCellRange, $pBefore, $pNumCols, $pNumRows); + } else { + // Return original + return $pCellRange; + } + } + + /** + * Update named formulas (i.e. containing worksheet references / named ranges) + * + * @param PHPExcel $pPhpExcel Object to update + * @param string $oldName Old name (name to replace) + * @param string $newName New name + */ + public function updateNamedFormulas(PHPExcel $pPhpExcel, $oldName = '', $newName = '') { + if ($oldName == '') { + return; + } + + foreach ($pPhpExcel->getWorksheetIterator() as $sheet) { + foreach ($sheet->getCellCollection(false) as $cellID) { + $cell = $sheet->getCell($cellID); + if (($cell !== NULL) && ($cell->getDataType() == PHPExcel_Cell_DataType::TYPE_FORMULA)) { + $formula = $cell->getValue(); + if (strpos($formula, $oldName) !== false) { + $formula = str_replace("'" . $oldName . "'!", "'" . $newName . "'!", $formula); + $formula = str_replace($oldName . "!", $newName . "!", $formula); + $cell->setValueExplicit($formula, PHPExcel_Cell_DataType::TYPE_FORMULA); + } + } + } + } + } + + /** + * Update cell range + * + * @param string $pCellRange Cell range (e.g. 'B2:D4', 'B:C' or '2:3') + * @param int $pBefore Insert before this one + * @param int $pNumCols Number of columns to increment + * @param int $pNumRows Number of rows to increment + * @return string Updated cell range + * @throws PHPExcel_Exception + */ + private function _updateCellRange($pCellRange = 'A1:A1', $pBefore = 'A1', $pNumCols = 0, $pNumRows = 0) { + if (strpos($pCellRange,':') !== false || strpos($pCellRange, ',') !== false) { + // Update range + $range = PHPExcel_Cell::splitRange($pCellRange); + $ic = count($range); + for ($i = 0; $i < $ic; ++$i) { + $jc = count($range[$i]); + for ($j = 0; $j < $jc; ++$j) { + if (ctype_alpha($range[$i][$j])) { + $r = PHPExcel_Cell::coordinateFromString($this->_updateSingleCellReference($range[$i][$j].'1', $pBefore, $pNumCols, $pNumRows)); + $range[$i][$j] = $r[0]; + } elseif(ctype_digit($range[$i][$j])) { + $r = PHPExcel_Cell::coordinateFromString($this->_updateSingleCellReference('A'.$range[$i][$j], $pBefore, $pNumCols, $pNumRows)); + $range[$i][$j] = $r[1]; + } else { + $range[$i][$j] = $this->_updateSingleCellReference($range[$i][$j], $pBefore, $pNumCols, $pNumRows); + } + } + } + + // Recreate range string + return PHPExcel_Cell::buildRange($range); + } else { + throw new PHPExcel_Exception("Only cell ranges may be passed to this method."); + } + } + + /** + * Update single cell reference + * + * @param string $pCellReference Single cell reference + * @param int $pBefore Insert before this one + * @param int $pNumCols Number of columns to increment + * @param int $pNumRows Number of rows to increment + * @return string Updated cell reference + * @throws PHPExcel_Exception + */ + private function _updateSingleCellReference($pCellReference = 'A1', $pBefore = 'A1', $pNumCols = 0, $pNumRows = 0) { + if (strpos($pCellReference, ':') === false && strpos($pCellReference, ',') === false) { + // Get coordinates of $pBefore + list($beforeColumn, $beforeRow) = PHPExcel_Cell::coordinateFromString( $pBefore ); + + // Get coordinates of $pCellReference + list($newColumn, $newRow) = PHPExcel_Cell::coordinateFromString( $pCellReference ); + + // Verify which parts should be updated + $updateColumn = (($newColumn{0} != '$') && ($beforeColumn{0} != '$') && + PHPExcel_Cell::columnIndexFromString($newColumn) >= PHPExcel_Cell::columnIndexFromString($beforeColumn)); + $updateRow = (($newRow{0} != '$') && ($beforeRow{0} != '$') && + $newRow >= $beforeRow); + + // Create new column reference + if ($updateColumn) { + $newColumn = PHPExcel_Cell::stringFromColumnIndex( PHPExcel_Cell::columnIndexFromString($newColumn) - 1 + $pNumCols ); + } + + // Create new row reference + if ($updateRow) { + $newRow = $newRow + $pNumRows; + } + + // Return new reference + return $newColumn . $newRow; + } else { + throw new PHPExcel_Exception("Only single cell references may be passed to this method."); + } + } + + /** + * __clone implementation. Cloning should not be allowed in a Singleton! + * + * @throws PHPExcel_Exception + */ + public final function __clone() { + throw new PHPExcel_Exception("Cloning a Singleton is not allowed!"); + } +} diff --git a/lib/phpexcel/PHPExcel/RichText.php b/lib/phpexcel/PHPExcel/RichText.php new file mode 100644 index 0000000..2f172a0 --- /dev/null +++ b/lib/phpexcel/PHPExcel/RichText.php @@ -0,0 +1,199 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_RichText + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_RichText + * + * @category PHPExcel + * @package PHPExcel_RichText + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_RichText implements PHPExcel_IComparable +{ + /** + * Rich text elements + * + * @var PHPExcel_RichText_ITextElement[] + */ + private $_richTextElements; + + /** + * Create a new PHPExcel_RichText instance + * + * @param PHPExcel_Cell $pCell + * @throws PHPExcel_Exception + */ + public function __construct(PHPExcel_Cell $pCell = null) + { + // Initialise variables + $this->_richTextElements = array(); + + // Rich-Text string attached to cell? + if ($pCell !== NULL) { + // Add cell text and style + if ($pCell->getValue() != "") { + $objRun = new PHPExcel_RichText_Run($pCell->getValue()); + $objRun->setFont(clone $pCell->getParent()->getStyle($pCell->getCoordinate())->getFont()); + $this->addText($objRun); + } + + // Set parent value + $pCell->setValueExplicit($this, PHPExcel_Cell_DataType::TYPE_STRING); + } + } + + /** + * Add text + * + * @param PHPExcel_RichText_ITextElement $pText Rich text element + * @throws PHPExcel_Exception + * @return PHPExcel_RichText + */ + public function addText(PHPExcel_RichText_ITextElement $pText = null) + { + $this->_richTextElements[] = $pText; + return $this; + } + + /** + * Create text + * + * @param string $pText Text + * @return PHPExcel_RichText_TextElement + * @throws PHPExcel_Exception + */ + public function createText($pText = '') + { + $objText = new PHPExcel_RichText_TextElement($pText); + $this->addText($objText); + return $objText; + } + + /** + * Create text run + * + * @param string $pText Text + * @return PHPExcel_RichText_Run + * @throws PHPExcel_Exception + */ + public function createTextRun($pText = '') + { + $objText = new PHPExcel_RichText_Run($pText); + $this->addText($objText); + return $objText; + } + + /** + * Get plain text + * + * @return string + */ + public function getPlainText() + { + // Return value + $returnValue = ''; + + // Loop through all PHPExcel_RichText_ITextElement + foreach ($this->_richTextElements as $text) { + $returnValue .= $text->getText(); + } + + // Return + return $returnValue; + } + + /** + * Convert to string + * + * @return string + */ + public function __toString() + { + return $this->getPlainText(); + } + + /** + * Get Rich Text elements + * + * @return PHPExcel_RichText_ITextElement[] + */ + public function getRichTextElements() + { + return $this->_richTextElements; + } + + /** + * Set Rich Text elements + * + * @param PHPExcel_RichText_ITextElement[] $pElements Array of elements + * @throws PHPExcel_Exception + * @return PHPExcel_RichText + */ + public function setRichTextElements($pElements = null) + { + if (is_array($pElements)) { + $this->_richTextElements = $pElements; + } else { + throw new PHPExcel_Exception("Invalid PHPExcel_RichText_ITextElement[] array passed."); + } + return $this; + } + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() + { + $hashElements = ''; + foreach ($this->_richTextElements as $element) { + $hashElements .= $element->getHashCode(); + } + + return md5( + $hashElements + . __CLASS__ + ); + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() + { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } +} diff --git a/lib/phpexcel/PHPExcel/RichText/ITextElement.php b/lib/phpexcel/PHPExcel/RichText/ITextElement.php new file mode 100644 index 0000000..ec19498 --- /dev/null +++ b/lib/phpexcel/PHPExcel/RichText/ITextElement.php @@ -0,0 +1,64 @@ +<?php +/** + * PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_RichText + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_RichText_ITextElement + * + * @category PHPExcel + * @package PHPExcel_RichText + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +interface PHPExcel_RichText_ITextElement +{ + /** + * Get text + * + * @return string Text + */ + public function getText(); + + /** + * Set text + * + * @param $pText string Text + * @return PHPExcel_RichText_ITextElement + */ + public function setText($pText = ''); + + /** + * Get font + * + * @return PHPExcel_Style_Font + */ + public function getFont(); + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode(); +} diff --git a/lib/phpexcel/PHPExcel/RichText/Run.php b/lib/phpexcel/PHPExcel/RichText/Run.php new file mode 100644 index 0000000..71545fc --- /dev/null +++ b/lib/phpexcel/PHPExcel/RichText/Run.php @@ -0,0 +1,102 @@ +<?php +/** + * PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_RichText + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_RichText_Run + * + * @category PHPExcel + * @package PHPExcel_RichText + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_RichText_Run extends PHPExcel_RichText_TextElement implements PHPExcel_RichText_ITextElement +{ + /** + * Font + * + * @var PHPExcel_Style_Font + */ + private $_font; + + /** + * Create a new PHPExcel_RichText_Run instance + * + * @param string $pText Text + */ + public function __construct($pText = '') + { + // Initialise variables + $this->setText($pText); + $this->_font = new PHPExcel_Style_Font(); + } + + /** + * Get font + * + * @return PHPExcel_Style_Font + */ + public function getFont() { + return $this->_font; + } + + /** + * Set font + * + * @param PHPExcel_Style_Font $pFont Font + * @throws PHPExcel_Exception + * @return PHPExcel_RichText_ITextElement + */ + public function setFont(PHPExcel_Style_Font $pFont = null) { + $this->_font = $pFont; + return $this; + } + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() { + return md5( + $this->getText() + . $this->_font->getHashCode() + . __CLASS__ + ); + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } +} diff --git a/lib/phpexcel/PHPExcel/RichText/TextElement.php b/lib/phpexcel/PHPExcel/RichText/TextElement.php new file mode 100644 index 0000000..3593c6e --- /dev/null +++ b/lib/phpexcel/PHPExcel/RichText/TextElement.php @@ -0,0 +1,108 @@ +<?php +/** + * PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_RichText + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_RichText_TextElement + * + * @category PHPExcel + * @package PHPExcel_RichText + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_RichText_TextElement implements PHPExcel_RichText_ITextElement +{ + /** + * Text + * + * @var string + */ + private $_text; + + /** + * Create a new PHPExcel_RichText_TextElement instance + * + * @param string $pText Text + */ + public function __construct($pText = '') + { + // Initialise variables + $this->_text = $pText; + } + + /** + * Get text + * + * @return string Text + */ + public function getText() { + return $this->_text; + } + + /** + * Set text + * + * @param $pText string Text + * @return PHPExcel_RichText_ITextElement + */ + public function setText($pText = '') { + $this->_text = $pText; + return $this; + } + + /** + * Get font + * + * @return PHPExcel_Style_Font + */ + public function getFont() { + return null; + } + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() { + return md5( + $this->_text + . __CLASS__ + ); + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } +} diff --git a/lib/phpexcel/PHPExcel/Settings.php b/lib/phpexcel/PHPExcel/Settings.php new file mode 100644 index 0000000..b899613 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Settings.php @@ -0,0 +1,387 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Settings + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + +/** PHPExcel root directory */ +if (!defined('PHPEXCEL_ROOT')) { + /** + * @ignore + */ + define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../'); + require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); +} + + +class PHPExcel_Settings +{ + /** constants */ + /** Available Zip library classes */ + const PCLZIP = 'PHPExcel_Shared_ZipArchive'; + const ZIPARCHIVE = 'ZipArchive'; + + /** Optional Chart Rendering libraries */ + const CHART_RENDERER_JPGRAPH = 'jpgraph'; + + /** Optional PDF Rendering libraries */ + const PDF_RENDERER_TCPDF = 'tcPDF'; + const PDF_RENDERER_DOMPDF = 'DomPDF'; + const PDF_RENDERER_MPDF = 'mPDF'; + + + private static $_chartRenderers = array( + self::CHART_RENDERER_JPGRAPH, + ); + + private static $_pdfRenderers = array( + self::PDF_RENDERER_TCPDF, + self::PDF_RENDERER_DOMPDF, + self::PDF_RENDERER_MPDF, + ); + + + /** + * Name of the class used for Zip file management + * e.g. + * ZipArchive + * + * @var string + */ + private static $_zipClass = self::ZIPARCHIVE; + + + /** + * Name of the external Library used for rendering charts + * e.g. + * jpgraph + * + * @var string + */ + private static $_chartRendererName = NULL; + + /** + * Directory Path to the external Library used for rendering charts + * + * @var string + */ + private static $_chartRendererPath = NULL; + + + /** + * Name of the external Library used for rendering PDF files + * e.g. + * mPDF + * + * @var string + */ + private static $_pdfRendererName = NULL; + + /** + * Directory Path to the external Library used for rendering PDF files + * + * @var string + */ + private static $_pdfRendererPath = NULL; + + /** + * Default options for libxml loader + * + * @var int + */ + private static $_libXmlLoaderOptions = null; + + /** + * Set the Zip handler Class that PHPExcel should use for Zip file management (PCLZip or ZipArchive) + * + * @param string $zipClass The Zip handler class that PHPExcel should use for Zip file management + * e.g. PHPExcel_Settings::PCLZip or PHPExcel_Settings::ZipArchive + * @return boolean Success or failure + */ + public static function setZipClass($zipClass) + { + if (($zipClass === self::PCLZIP) || + ($zipClass === self::ZIPARCHIVE)) { + self::$_zipClass = $zipClass; + return TRUE; + } + return FALSE; + } // function setZipClass() + + + /** + * Return the name of the Zip handler Class that PHPExcel is configured to use (PCLZip or ZipArchive) + * or Zip file management + * + * @return string Name of the Zip handler Class that PHPExcel is configured to use + * for Zip file management + * e.g. PHPExcel_Settings::PCLZip or PHPExcel_Settings::ZipArchive + */ + public static function getZipClass() + { + return self::$_zipClass; + } // function getZipClass() + + + /** + * Return the name of the method that is currently configured for cell cacheing + * + * @return string Name of the cacheing method + */ + public static function getCacheStorageMethod() + { + return PHPExcel_CachedObjectStorageFactory::getCacheStorageMethod(); + } // function getCacheStorageMethod() + + + /** + * Return the name of the class that is currently being used for cell cacheing + * + * @return string Name of the class currently being used for cacheing + */ + public static function getCacheStorageClass() + { + return PHPExcel_CachedObjectStorageFactory::getCacheStorageClass(); + } // function getCacheStorageClass() + + + /** + * Set the method that should be used for cell cacheing + * + * @param string $method Name of the cacheing method + * @param array $arguments Optional configuration arguments for the cacheing method + * @return boolean Success or failure + */ + public static function setCacheStorageMethod( + $method = PHPExcel_CachedObjectStorageFactory::cache_in_memory, + $arguments = array() + ) + { + return PHPExcel_CachedObjectStorageFactory::initialize($method, $arguments); + } // function setCacheStorageMethod() + + + /** + * Set the locale code to use for formula translations and any special formatting + * + * @param string $locale The locale code to use (e.g. "fr" or "pt_br" or "en_uk") + * @return boolean Success or failure + */ + public static function setLocale($locale='en_us') + { + return PHPExcel_Calculation::getInstance()->setLocale($locale); + } // function setLocale() + + + /** + * Set details of the external library that PHPExcel should use for rendering charts + * + * @param string $libraryName Internal reference name of the library + * e.g. PHPExcel_Settings::CHART_RENDERER_JPGRAPH + * @param string $libraryBaseDir Directory path to the library's base folder + * + * @return boolean Success or failure + */ + public static function setChartRenderer($libraryName, $libraryBaseDir) + { + if (!self::setChartRendererName($libraryName)) + return FALSE; + return self::setChartRendererPath($libraryBaseDir); + } // function setChartRenderer() + + + /** + * Identify to PHPExcel the external library to use for rendering charts + * + * @param string $libraryName Internal reference name of the library + * e.g. PHPExcel_Settings::CHART_RENDERER_JPGRAPH + * + * @return boolean Success or failure + */ + public static function setChartRendererName($libraryName) + { + if (!in_array($libraryName,self::$_chartRenderers)) { + return FALSE; + } + + self::$_chartRendererName = $libraryName; + + return TRUE; + } // function setChartRendererName() + + + /** + * Tell PHPExcel where to find the external library to use for rendering charts + * + * @param string $libraryBaseDir Directory path to the library's base folder + * @return boolean Success or failure + */ + public static function setChartRendererPath($libraryBaseDir) + { + if ((file_exists($libraryBaseDir) === false) || (is_readable($libraryBaseDir) === false)) { + return FALSE; + } + self::$_chartRendererPath = $libraryBaseDir; + + return TRUE; + } // function setChartRendererPath() + + + /** + * Return the Chart Rendering Library that PHPExcel is currently configured to use (e.g. jpgraph) + * + * @return string|NULL Internal reference name of the Chart Rendering Library that PHPExcel is + * currently configured to use + * e.g. PHPExcel_Settings::CHART_RENDERER_JPGRAPH + */ + public static function getChartRendererName() + { + return self::$_chartRendererName; + } // function getChartRendererName() + + + /** + * Return the directory path to the Chart Rendering Library that PHPExcel is currently configured to use + * + * @return string|NULL Directory Path to the Chart Rendering Library that PHPExcel is + * currently configured to use + */ + public static function getChartRendererPath() + { + return self::$_chartRendererPath; + } // function getChartRendererPath() + + + /** + * Set details of the external library that PHPExcel should use for rendering PDF files + * + * @param string $libraryName Internal reference name of the library + * e.g. PHPExcel_Settings::PDF_RENDERER_TCPDF, + * PHPExcel_Settings::PDF_RENDERER_DOMPDF + * or PHPExcel_Settings::PDF_RENDERER_MPDF + * @param string $libraryBaseDir Directory path to the library's base folder + * + * @return boolean Success or failure + */ + public static function setPdfRenderer($libraryName, $libraryBaseDir) + { + if (!self::setPdfRendererName($libraryName)) + return FALSE; + return self::setPdfRendererPath($libraryBaseDir); + } // function setPdfRenderer() + + + /** + * Identify to PHPExcel the external library to use for rendering PDF files + * + * @param string $libraryName Internal reference name of the library + * e.g. PHPExcel_Settings::PDF_RENDERER_TCPDF, + * PHPExcel_Settings::PDF_RENDERER_DOMPDF + * or PHPExcel_Settings::PDF_RENDERER_MPDF + * + * @return boolean Success or failure + */ + public static function setPdfRendererName($libraryName) + { + if (!in_array($libraryName,self::$_pdfRenderers)) { + return FALSE; + } + + self::$_pdfRendererName = $libraryName; + + return TRUE; + } // function setPdfRendererName() + + + /** + * Tell PHPExcel where to find the external library to use for rendering PDF files + * + * @param string $libraryBaseDir Directory path to the library's base folder + * @return boolean Success or failure + */ + public static function setPdfRendererPath($libraryBaseDir) + { + if ((file_exists($libraryBaseDir) === false) || (is_readable($libraryBaseDir) === false)) { + return FALSE; + } + self::$_pdfRendererPath = $libraryBaseDir; + + return TRUE; + } // function setPdfRendererPath() + + + /** + * Return the PDF Rendering Library that PHPExcel is currently configured to use (e.g. dompdf) + * + * @return string|NULL Internal reference name of the PDF Rendering Library that PHPExcel is + * currently configured to use + * e.g. PHPExcel_Settings::PDF_RENDERER_TCPDF, + * PHPExcel_Settings::PDF_RENDERER_DOMPDF + * or PHPExcel_Settings::PDF_RENDERER_MPDF + */ + public static function getPdfRendererName() + { + return self::$_pdfRendererName; + } // function getPdfRendererName() + + /** + * Return the directory path to the PDF Rendering Library that PHPExcel is currently configured to use + * + * @return string|NULL Directory Path to the PDF Rendering Library that PHPExcel is + * currently configured to use + */ + public static function getPdfRendererPath() + { + return self::$_pdfRendererPath; + } // function getPdfRendererPath() + + /** + * Set default options for libxml loader + * + * @param int $options Default options for libxml loader + */ + public static function setLibXmlLoaderOptions($options = null) + { + if (is_null($options)) { + $options = LIBXML_DTDLOAD | LIBXML_DTDATTR; + } + @libxml_disable_entity_loader($options == (LIBXML_DTDLOAD | LIBXML_DTDATTR)); + self::$_libXmlLoaderOptions = $options; + } // function setLibXmlLoaderOptions + + /** + * Get default options for libxml loader. + * Defaults to LIBXML_DTDLOAD | LIBXML_DTDATTR when not set explicitly. + * + * @return int Default options for libxml loader + */ + public static function getLibXmlLoaderOptions() + { + if (is_null(self::$_libXmlLoaderOptions)) { + self::setLibXmlLoaderOptions(LIBXML_DTDLOAD | LIBXML_DTDATTR); + } + @libxml_disable_entity_loader($options == (LIBXML_DTDLOAD | LIBXML_DTDATTR)); + return self::$_libXmlLoaderOptions; + } // function getLibXmlLoaderOptions +} diff --git a/lib/phpexcel/PHPExcel/Shared/CodePage.php b/lib/phpexcel/PHPExcel/Shared/CodePage.php new file mode 100644 index 0000000..2807ab3 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Shared/CodePage.php @@ -0,0 +1,102 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Shared_CodePage + * + * @category PHPExcel + * @package PHPExcel_Shared + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Shared_CodePage +{ + /** + * Convert Microsoft Code Page Identifier to Code Page Name which iconv + * and mbstring understands + * + * @param integer $codePage Microsoft Code Page Indentifier + * @return string Code Page Name + * @throws PHPExcel_Exception + */ + public static function NumberToName($codePage = 1252) + { + switch ($codePage) { + case 367: return 'ASCII'; break; // ASCII + case 437: return 'CP437'; break; // OEM US + case 720: throw new PHPExcel_Exception('Code page 720 not supported.'); + break; // OEM Arabic + case 737: return 'CP737'; break; // OEM Greek + case 775: return 'CP775'; break; // OEM Baltic + case 850: return 'CP850'; break; // OEM Latin I + case 852: return 'CP852'; break; // OEM Latin II (Central European) + case 855: return 'CP855'; break; // OEM Cyrillic + case 857: return 'CP857'; break; // OEM Turkish + case 858: return 'CP858'; break; // OEM Multilingual Latin I with Euro + case 860: return 'CP860'; break; // OEM Portugese + case 861: return 'CP861'; break; // OEM Icelandic + case 862: return 'CP862'; break; // OEM Hebrew + case 863: return 'CP863'; break; // OEM Canadian (French) + case 864: return 'CP864'; break; // OEM Arabic + case 865: return 'CP865'; break; // OEM Nordic + case 866: return 'CP866'; break; // OEM Cyrillic (Russian) + case 869: return 'CP869'; break; // OEM Greek (Modern) + case 874: return 'CP874'; break; // ANSI Thai + case 932: return 'CP932'; break; // ANSI Japanese Shift-JIS + case 936: return 'CP936'; break; // ANSI Chinese Simplified GBK + case 949: return 'CP949'; break; // ANSI Korean (Wansung) + case 950: return 'CP950'; break; // ANSI Chinese Traditional BIG5 + case 1200: return 'UTF-16LE'; break; // UTF-16 (BIFF8) + case 1250: return 'CP1250'; break; // ANSI Latin II (Central European) + case 1251: return 'CP1251'; break; // ANSI Cyrillic + case 0: // CodePage is not always correctly set when the xls file was saved by Apple's Numbers program + case 1252: return 'CP1252'; break; // ANSI Latin I (BIFF4-BIFF7) + case 1253: return 'CP1253'; break; // ANSI Greek + case 1254: return 'CP1254'; break; // ANSI Turkish + case 1255: return 'CP1255'; break; // ANSI Hebrew + case 1256: return 'CP1256'; break; // ANSI Arabic + case 1257: return 'CP1257'; break; // ANSI Baltic + case 1258: return 'CP1258'; break; // ANSI Vietnamese + case 1361: return 'CP1361'; break; // ANSI Korean (Johab) + case 10000: return 'MAC'; break; // Apple Roman + case 10006: return 'MACGREEK'; break; // Macintosh Greek + case 10007: return 'MACCYRILLIC'; break; // Macintosh Cyrillic + case 10008: return 'CP936'; break; // Macintosh - Simplified Chinese (GB 2312) + case 10029: return 'MACCENTRALEUROPE'; break; // Macintosh Central Europe + case 10079: return 'MACICELAND'; break; // Macintosh Icelandic + case 10081: return 'MACTURKISH'; break; // Macintosh Turkish + case 32768: return 'MAC'; break; // Apple Roman + case 32769: throw new PHPExcel_Exception('Code page 32769 not supported.'); + break; // ANSI Latin I (BIFF2-BIFF3) + case 65000: return 'UTF-7'; break; // Unicode (UTF-7) + case 65001: return 'UTF-8'; break; // Unicode (UTF-8) + } + + throw new PHPExcel_Exception('Unknown codepage: ' . $codePage); + } + +} diff --git a/lib/phpexcel/PHPExcel/Shared/Date.php b/lib/phpexcel/PHPExcel/Shared/Date.php new file mode 100644 index 0000000..7fe4f42 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Shared/Date.php @@ -0,0 +1,393 @@ +<?php + +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Shared_Date + * + * @category PHPExcel + * @package PHPExcel_Shared + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Shared_Date +{ + /** constants */ + const CALENDAR_WINDOWS_1900 = 1900; // Base date of 1st Jan 1900 = 1.0 + const CALENDAR_MAC_1904 = 1904; // Base date of 2nd Jan 1904 = 1.0 + + /* + * Names of the months of the year, indexed by shortname + * Planned usage for locale settings + * + * @public + * @var string[] + */ + public static $_monthNames = array( 'Jan' => 'January', + 'Feb' => 'February', + 'Mar' => 'March', + 'Apr' => 'April', + 'May' => 'May', + 'Jun' => 'June', + 'Jul' => 'July', + 'Aug' => 'August', + 'Sep' => 'September', + 'Oct' => 'October', + 'Nov' => 'November', + 'Dec' => 'December', + ); + + /* + * Names of the months of the year, indexed by shortname + * Planned usage for locale settings + * + * @public + * @var string[] + */ + public static $_numberSuffixes = array( 'st', + 'nd', + 'rd', + 'th', + ); + + /* + * Base calendar year to use for calculations + * + * @private + * @var int + */ + protected static $_excelBaseDate = self::CALENDAR_WINDOWS_1900; + + /** + * Set the Excel calendar (Windows 1900 or Mac 1904) + * + * @param integer $baseDate Excel base date (1900 or 1904) + * @return boolean Success or failure + */ + public static function setExcelCalendar($baseDate) { + if (($baseDate == self::CALENDAR_WINDOWS_1900) || + ($baseDate == self::CALENDAR_MAC_1904)) { + self::$_excelBaseDate = $baseDate; + return TRUE; + } + return FALSE; + } // function setExcelCalendar() + + + /** + * Return the Excel calendar (Windows 1900 or Mac 1904) + * + * @return integer Excel base date (1900 or 1904) + */ + public static function getExcelCalendar() { + return self::$_excelBaseDate; + } // function getExcelCalendar() + + + /** + * Convert a date from Excel to PHP + * + * @param long $dateValue Excel date/time value + * @param boolean $adjustToTimezone Flag indicating whether $dateValue should be treated as + * a UST timestamp, or adjusted to UST + * @param string $timezone The timezone for finding the adjustment from UST + * @return long PHP serialized date/time + */ + public static function ExcelToPHP($dateValue = 0, $adjustToTimezone = FALSE, $timezone = NULL) { + if (self::$_excelBaseDate == self::CALENDAR_WINDOWS_1900) { + $my_excelBaseDate = 25569; + // Adjust for the spurious 29-Feb-1900 (Day 60) + if ($dateValue < 60) { + --$my_excelBaseDate; + } + } else { + $my_excelBaseDate = 24107; + } + + // Perform conversion + if ($dateValue >= 1) { + $utcDays = $dateValue - $my_excelBaseDate; + $returnValue = round($utcDays * 86400); + if (($returnValue <= PHP_INT_MAX) && ($returnValue >= -PHP_INT_MAX)) { + $returnValue = (integer) $returnValue; + } + } else { + $hours = round($dateValue * 24); + $mins = round($dateValue * 1440) - round($hours * 60); + $secs = round($dateValue * 86400) - round($hours * 3600) - round($mins * 60); + $returnValue = (integer) gmmktime($hours, $mins, $secs); + } + + $timezoneAdjustment = ($adjustToTimezone) ? + PHPExcel_Shared_TimeZone::getTimezoneAdjustment($timezone, $returnValue) : + 0; + + // Return + return $returnValue + $timezoneAdjustment; + } // function ExcelToPHP() + + + /** + * Convert a date from Excel to a PHP Date/Time object + * + * @param integer $dateValue Excel date/time value + * @return integer PHP date/time object + */ + public static function ExcelToPHPObject($dateValue = 0) { + $dateTime = self::ExcelToPHP($dateValue); + $days = floor($dateTime / 86400); + $time = round((($dateTime / 86400) - $days) * 86400); + $hours = round($time / 3600); + $minutes = round($time / 60) - ($hours * 60); + $seconds = round($time) - ($hours * 3600) - ($minutes * 60); + + $dateObj = date_create('1-Jan-1970+'.$days.' days'); + $dateObj->setTime($hours,$minutes,$seconds); + + return $dateObj; + } // function ExcelToPHPObject() + + + /** + * Convert a date from PHP to Excel + * + * @param mixed $dateValue PHP serialized date/time or date object + * @param boolean $adjustToTimezone Flag indicating whether $dateValue should be treated as + * a UST timestamp, or adjusted to UST + * @param string $timezone The timezone for finding the adjustment from UST + * @return mixed Excel date/time value + * or boolean FALSE on failure + */ + public static function PHPToExcel($dateValue = 0, $adjustToTimezone = FALSE, $timezone = NULL) { + $saveTimeZone = date_default_timezone_get(); + date_default_timezone_set('UTC'); + $retValue = FALSE; + if ((is_object($dateValue)) && ($dateValue instanceof DateTime)) { + $retValue = self::FormattedPHPToExcel( $dateValue->format('Y'), $dateValue->format('m'), $dateValue->format('d'), + $dateValue->format('H'), $dateValue->format('i'), $dateValue->format('s') + ); + } elseif (is_numeric($dateValue)) { + $retValue = self::FormattedPHPToExcel( date('Y',$dateValue), date('m',$dateValue), date('d',$dateValue), + date('H',$dateValue), date('i',$dateValue), date('s',$dateValue) + ); + } + date_default_timezone_set($saveTimeZone); + + return $retValue; + } // function PHPToExcel() + + + /** + * FormattedPHPToExcel + * + * @param long $year + * @param long $month + * @param long $day + * @param long $hours + * @param long $minutes + * @param long $seconds + * @return long Excel date/time value + */ + public static function FormattedPHPToExcel($year, $month, $day, $hours=0, $minutes=0, $seconds=0) { + if (self::$_excelBaseDate == self::CALENDAR_WINDOWS_1900) { + // + // Fudge factor for the erroneous fact that the year 1900 is treated as a Leap Year in MS Excel + // This affects every date following 28th February 1900 + // + $excel1900isLeapYear = TRUE; + if (($year == 1900) && ($month <= 2)) { $excel1900isLeapYear = FALSE; } + $my_excelBaseDate = 2415020; + } else { + $my_excelBaseDate = 2416481; + $excel1900isLeapYear = FALSE; + } + + // Julian base date Adjustment + if ($month > 2) { + $month -= 3; + } else { + $month += 9; + --$year; + } + + // Calculate the Julian Date, then subtract the Excel base date (JD 2415020 = 31-Dec-1899 Giving Excel Date of 0) + $century = substr($year,0,2); + $decade = substr($year,2,2); + $excelDate = floor((146097 * $century) / 4) + floor((1461 * $decade) / 4) + floor((153 * $month + 2) / 5) + $day + 1721119 - $my_excelBaseDate + $excel1900isLeapYear; + + $excelTime = (($hours * 3600) + ($minutes * 60) + $seconds) / 86400; + + return (float) $excelDate + $excelTime; + } // function FormattedPHPToExcel() + + + /** + * Is a given cell a date/time? + * + * @param PHPExcel_Cell $pCell + * @return boolean + */ + public static function isDateTime(PHPExcel_Cell $pCell) { + return self::isDateTimeFormat( + $pCell->getWorksheet()->getStyle( + $pCell->getCoordinate() + )->getNumberFormat() + ); + } // function isDateTime() + + + /** + * Is a given number format a date/time? + * + * @param PHPExcel_Style_NumberFormat $pFormat + * @return boolean + */ + public static function isDateTimeFormat(PHPExcel_Style_NumberFormat $pFormat) { + return self::isDateTimeFormatCode($pFormat->getFormatCode()); + } // function isDateTimeFormat() + + + private static $possibleDateFormatCharacters = 'eymdHs'; + + /** + * Is a given number format code a date/time? + * + * @param string $pFormatCode + * @return boolean + */ + public static function isDateTimeFormatCode($pFormatCode = '') { + if (strtolower($pFormatCode) === strtolower(PHPExcel_Style_NumberFormat::FORMAT_GENERAL)) + // "General" contains an epoch letter 'e', so we trap for it explicitly here (case-insensitive check) + return FALSE; + if (preg_match('/[0#]E[+-]0/i', $pFormatCode)) + // Scientific format + return FALSE; + // Switch on formatcode + switch ($pFormatCode) { + // Explicitly defined date formats + case PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDD: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDD2: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_DDMMYYYY: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_DMYSLASH: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_DMYMINUS: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_DMMINUS: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_MYMINUS: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_DATETIME: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME1: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME2: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME3: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME5: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME6: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME7: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME8: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDDSLASH: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX14: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX15: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX16: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX17: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX22: + return TRUE; + } + + // Typically number, currency or accounting (or occasionally fraction) formats + if ((substr($pFormatCode,0,1) == '_') || (substr($pFormatCode,0,2) == '0 ')) { + return FALSE; + } + // Try checking for any of the date formatting characters that don't appear within square braces + if (preg_match('/(^|\])[^\[]*['.self::$possibleDateFormatCharacters.']/i',$pFormatCode)) { + // We might also have a format mask containing quoted strings... + // we don't want to test for any of our characters within the quoted blocks + if (strpos($pFormatCode,'"') !== FALSE) { + $segMatcher = FALSE; + foreach(explode('"',$pFormatCode) as $subVal) { + // Only test in alternate array entries (the non-quoted blocks) + if (($segMatcher = !$segMatcher) && + (preg_match('/(^|\])[^\[]*['.self::$possibleDateFormatCharacters.']/i',$subVal))) { + return TRUE; + } + } + return FALSE; + } + return TRUE; + } + + // No date... + return FALSE; + } // function isDateTimeFormatCode() + + + /** + * Convert a date/time string to Excel time + * + * @param string $dateValue Examples: '2009-12-31', '2009-12-31 15:59', '2009-12-31 15:59:10' + * @return float|FALSE Excel date/time serial value + */ + public static function stringToExcel($dateValue = '') { + if (strlen($dateValue) < 2) + return FALSE; + if (!preg_match('/^(\d{1,4}[ \.\/\-][A-Z]{3,9}([ \.\/\-]\d{1,4})?|[A-Z]{3,9}[ \.\/\-]\d{1,4}([ \.\/\-]\d{1,4})?|\d{1,4}[ \.\/\-]\d{1,4}([ \.\/\-]\d{1,4})?)( \d{1,2}:\d{1,2}(:\d{1,2})?)?$/iu', $dateValue)) + return FALSE; + + $dateValueNew = PHPExcel_Calculation_DateTime::DATEVALUE($dateValue); + + if ($dateValueNew === PHPExcel_Calculation_Functions::VALUE()) { + return FALSE; + } else { + if (strpos($dateValue, ':') !== FALSE) { + $timeValue = PHPExcel_Calculation_DateTime::TIMEVALUE($dateValue); + if ($timeValue === PHPExcel_Calculation_Functions::VALUE()) { + return FALSE; + } + $dateValueNew += $timeValue; + } + return $dateValueNew; + } + + + } + + public static function monthStringToNumber($month) { + $monthIndex = 1; + foreach(self::$_monthNames as $shortMonthName => $longMonthName) { + if (($month === $longMonthName) || ($month === $shortMonthName)) { + return $monthIndex; + } + ++$monthIndex; + } + return $month; + } + + public static function dayStringToNumber($day) { + $strippedDayValue = (str_replace(self::$_numberSuffixes,'',$day)); + if (is_numeric($strippedDayValue)) { + return $strippedDayValue; + } + return $day; + } + +} diff --git a/lib/phpexcel/PHPExcel/Shared/Drawing.php b/lib/phpexcel/PHPExcel/Shared/Drawing.php new file mode 100644 index 0000000..1d7af16 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Shared/Drawing.php @@ -0,0 +1,272 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Shared_Drawing + * + * @category PHPExcel + * @package PHPExcel_Shared + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Shared_Drawing +{ + /** + * Convert pixels to EMU + * + * @param int $pValue Value in pixels + * @return int Value in EMU + */ + public static function pixelsToEMU($pValue = 0) { + return round($pValue * 9525); + } + + /** + * Convert EMU to pixels + * + * @param int $pValue Value in EMU + * @return int Value in pixels + */ + public static function EMUToPixels($pValue = 0) { + if ($pValue != 0) { + return round($pValue / 9525); + } else { + return 0; + } + } + + /** + * Convert pixels to column width. Exact algorithm not known. + * By inspection of a real Excel file using Calibri 11, one finds 1000px ~ 142.85546875 + * This gives a conversion factor of 7. Also, we assume that pixels and font size are proportional. + * + * @param int $pValue Value in pixels + * @param PHPExcel_Style_Font $pDefaultFont Default font of the workbook + * @return int Value in cell dimension + */ + public static function pixelsToCellDimension($pValue = 0, PHPExcel_Style_Font $pDefaultFont) { + // Font name and size + $name = $pDefaultFont->getName(); + $size = $pDefaultFont->getSize(); + + if (isset(PHPExcel_Shared_Font::$defaultColumnWidths[$name][$size])) { + // Exact width can be determined + $colWidth = $pValue + * PHPExcel_Shared_Font::$defaultColumnWidths[$name][$size]['width'] + / PHPExcel_Shared_Font::$defaultColumnWidths[$name][$size]['px']; + } else { + // We don't have data for this particular font and size, use approximation by + // extrapolating from Calibri 11 + $colWidth = $pValue * 11 + * PHPExcel_Shared_Font::$defaultColumnWidths['Calibri'][11]['width'] + / PHPExcel_Shared_Font::$defaultColumnWidths['Calibri'][11]['px'] / $size; + } + + return $colWidth; + } + + /** + * Convert column width from (intrinsic) Excel units to pixels + * + * @param float $pValue Value in cell dimension + * @param PHPExcel_Style_Font $pDefaultFont Default font of the workbook + * @return int Value in pixels + */ + public static function cellDimensionToPixels($pValue = 0, PHPExcel_Style_Font $pDefaultFont) { + // Font name and size + $name = $pDefaultFont->getName(); + $size = $pDefaultFont->getSize(); + + if (isset(PHPExcel_Shared_Font::$defaultColumnWidths[$name][$size])) { + // Exact width can be determined + $colWidth = $pValue + * PHPExcel_Shared_Font::$defaultColumnWidths[$name][$size]['px'] + / PHPExcel_Shared_Font::$defaultColumnWidths[$name][$size]['width']; + + } else { + // We don't have data for this particular font and size, use approximation by + // extrapolating from Calibri 11 + $colWidth = $pValue * $size + * PHPExcel_Shared_Font::$defaultColumnWidths['Calibri'][11]['px'] + / PHPExcel_Shared_Font::$defaultColumnWidths['Calibri'][11]['width'] / 11; + } + + // Round pixels to closest integer + $colWidth = (int) round($colWidth); + + return $colWidth; + } + + /** + * Convert pixels to points + * + * @param int $pValue Value in pixels + * @return int Value in points + */ + public static function pixelsToPoints($pValue = 0) { + return $pValue * 0.67777777; + } + + /** + * Convert points to pixels + * + * @param int $pValue Value in points + * @return int Value in pixels + */ + public static function pointsToPixels($pValue = 0) { + if ($pValue != 0) { + return (int) ceil($pValue * 1.333333333); + } else { + return 0; + } + } + + /** + * Convert degrees to angle + * + * @param int $pValue Degrees + * @return int Angle + */ + public static function degreesToAngle($pValue = 0) { + return (int)round($pValue * 60000); + } + + /** + * Convert angle to degrees + * + * @param int $pValue Angle + * @return int Degrees + */ + public static function angleToDegrees($pValue = 0) { + if ($pValue != 0) { + return round($pValue / 60000); + } else { + return 0; + } + } + + /** + * Create a new image from file. By alexander at alexauto dot nl + * + * @link http://www.php.net/manual/en/function.imagecreatefromwbmp.php#86214 + * @param string $filename Path to Windows DIB (BMP) image + * @return resource + */ + public static function imagecreatefrombmp($p_sFile) + { + // Load the image into a string + $file = fopen($p_sFile,"rb"); + $read = fread($file,10); + while(!feof($file)&&($read<>"")) + $read .= fread($file,1024); + + $temp = unpack("H*",$read); + $hex = $temp[1]; + $header = substr($hex,0,108); + + // Process the header + // Structure: http://www.fastgraph.com/help/bmp_header_format.html + if (substr($header,0,4)=="424d") + { + // Cut it in parts of 2 bytes + $header_parts = str_split($header,2); + + // Get the width 4 bytes + $width = hexdec($header_parts[19].$header_parts[18]); + + // Get the height 4 bytes + $height = hexdec($header_parts[23].$header_parts[22]); + + // Unset the header params + unset($header_parts); + } + + // Define starting X and Y + $x = 0; + $y = 1; + + // Create newimage + $image = imagecreatetruecolor($width,$height); + + // Grab the body from the image + $body = substr($hex,108); + + // Calculate if padding at the end-line is needed + // Divided by two to keep overview. + // 1 byte = 2 HEX-chars + $body_size = (strlen($body)/2); + $header_size = ($width*$height); + + // Use end-line padding? Only when needed + $usePadding = ($body_size>($header_size*3)+4); + + // Using a for-loop with index-calculation instaid of str_split to avoid large memory consumption + // Calculate the next DWORD-position in the body + for ($i=0;$i<$body_size;$i+=3) + { + // Calculate line-ending and padding + if ($x>=$width) + { + // If padding needed, ignore image-padding + // Shift i to the ending of the current 32-bit-block + if ($usePadding) + $i += $width%4; + + // Reset horizontal position + $x = 0; + + // Raise the height-position (bottom-up) + $y++; + + // Reached the image-height? Break the for-loop + if ($y>$height) + break; + } + + // Calculation of the RGB-pixel (defined as BGR in image-data) + // Define $i_pos as absolute position in the body + $i_pos = $i*2; + $r = hexdec($body[$i_pos+4].$body[$i_pos+5]); + $g = hexdec($body[$i_pos+2].$body[$i_pos+3]); + $b = hexdec($body[$i_pos].$body[$i_pos+1]); + + // Calculate and draw the pixel + $color = imagecolorallocate($image,$r,$g,$b); + imagesetpixel($image,$x,$height-$y,$color); + + // Raise the horizontal position + $x++; + } + + // Unset the body / free the memory + unset($body); + + // Return image-object + return $image; + } + +} diff --git a/lib/phpexcel/PHPExcel/Shared/Escher.php b/lib/phpexcel/PHPExcel/Shared/Escher.php new file mode 100644 index 0000000..983cbda --- /dev/null +++ b/lib/phpexcel/PHPExcel/Shared/Escher.php @@ -0,0 +1,91 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared_Escher + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + +/** + * PHPExcel_Shared_Escher + * + * @category PHPExcel + * @package PHPExcel_Shared_Escher + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Shared_Escher +{ + /** + * Drawing Group Container + * + * @var PHPExcel_Shared_Escher_DggContainer + */ + private $_dggContainer; + + /** + * Drawing Container + * + * @var PHPExcel_Shared_Escher_DgContainer + */ + private $_dgContainer; + + /** + * Get Drawing Group Container + * + * @return PHPExcel_Shared_Escher_DgContainer + */ + public function getDggContainer() + { + return $this->_dggContainer; + } + + /** + * Set Drawing Group Container + * + * @param PHPExcel_Shared_Escher_DggContainer $dggContainer + */ + public function setDggContainer($dggContainer) + { + return $this->_dggContainer = $dggContainer; + } + + /** + * Get Drawing Container + * + * @return PHPExcel_Shared_Escher_DgContainer + */ + public function getDgContainer() + { + return $this->_dgContainer; + } + + /** + * Set Drawing Container + * + * @param PHPExcel_Shared_Escher_DgContainer $dgContainer + */ + public function setDgContainer($dgContainer) + { + return $this->_dgContainer = $dgContainer; + } + +} diff --git a/lib/phpexcel/PHPExcel/Shared/Escher/DgContainer.php b/lib/phpexcel/PHPExcel/Shared/Escher/DgContainer.php new file mode 100644 index 0000000..3ec564c --- /dev/null +++ b/lib/phpexcel/PHPExcel/Shared/Escher/DgContainer.php @@ -0,0 +1,83 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared_Escher + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + +/** + * PHPExcel_Shared_Escher_DgContainer + * + * @category PHPExcel + * @package PHPExcel_Shared_Escher + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Shared_Escher_DgContainer +{ + /** + * Drawing index, 1-based. + * + * @var int + */ + private $_dgId; + + /** + * Last shape index in this drawing + * + * @var int + */ + private $_lastSpId; + + private $_spgrContainer = null; + + public function getDgId() + { + return $this->_dgId; + } + + public function setDgId($value) + { + $this->_dgId = $value; + } + + public function getLastSpId() + { + return $this->_lastSpId; + } + + public function setLastSpId($value) + { + $this->_lastSpId = $value; + } + + public function getSpgrContainer() + { + return $this->_spgrContainer; + } + + public function setSpgrContainer($spgrContainer) + { + return $this->_spgrContainer = $spgrContainer; + } + +} diff --git a/lib/phpexcel/PHPExcel/Shared/Escher/DgContainer/SpgrContainer.php b/lib/phpexcel/PHPExcel/Shared/Escher/DgContainer/SpgrContainer.php new file mode 100644 index 0000000..651eaf0 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Shared/Escher/DgContainer/SpgrContainer.php @@ -0,0 +1,109 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared_Escher + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + +/** + * PHPExcel_Shared_Escher_DgContainer_SpgrContainer + * + * @category PHPExcel + * @package PHPExcel_Shared_Escher + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Shared_Escher_DgContainer_SpgrContainer +{ + /** + * Parent Shape Group Container + * + * @var PHPExcel_Shared_Escher_DgContainer_SpgrContainer + */ + private $_parent; + + /** + * Shape Container collection + * + * @var array + */ + private $_children = array(); + + /** + * Set parent Shape Group Container + * + * @param PHPExcel_Shared_Escher_DgContainer_SpgrContainer $parent + */ + public function setParent($parent) + { + $this->_parent = $parent; + } + + /** + * Get the parent Shape Group Container if any + * + * @return PHPExcel_Shared_Escher_DgContainer_SpgrContainer|null + */ + public function getParent() + { + return $this->_parent; + } + + /** + * Add a child. This will be either spgrContainer or spContainer + * + * @param mixed $child + */ + public function addChild($child) + { + $this->_children[] = $child; + $child->setParent($this); + } + + /** + * Get collection of Shape Containers + */ + public function getChildren() + { + return $this->_children; + } + + /** + * Recursively get all spContainers within this spgrContainer + * + * @return PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer[] + */ + public function getAllSpContainers() + { + $allSpContainers = array(); + + foreach ($this->_children as $child) { + if ($child instanceof PHPExcel_Shared_Escher_DgContainer_SpgrContainer) { + $allSpContainers = array_merge($allSpContainers, $child->getAllSpContainers()); + } else { + $allSpContainers[] = $child; + } + } + + return $allSpContainers; + } +} diff --git a/lib/phpexcel/PHPExcel/Shared/Escher/DgContainer/SpgrContainer/SpContainer.php b/lib/phpexcel/PHPExcel/Shared/Escher/DgContainer/SpgrContainer/SpContainer.php new file mode 100644 index 0000000..dde1154 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Shared/Escher/DgContainer/SpgrContainer/SpContainer.php @@ -0,0 +1,395 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared_Escher + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + +/** + * PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer + * + * @category PHPExcel + * @package PHPExcel_Shared_Escher + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer +{ + /** + * Parent Shape Group Container + * + * @var PHPExcel_Shared_Escher_DgContainer_SpgrContainer + */ + private $_parent; + + /** + * Is this a group shape? + * + * @var boolean + */ + private $_spgr = false; + + /** + * Shape type + * + * @var int + */ + private $_spType; + + /** + * Shape flag + * + * @var int + */ + private $_spFlag; + + /** + * Shape index (usually group shape has index 0, and the rest: 1,2,3...) + * + * @var boolean + */ + private $_spId; + + /** + * Array of options + * + * @var array + */ + private $_OPT; + + /** + * Cell coordinates of upper-left corner of shape, e.g. 'A1' + * + * @var string + */ + private $_startCoordinates; + + /** + * Horizontal offset of upper-left corner of shape measured in 1/1024 of column width + * + * @var int + */ + private $_startOffsetX; + + /** + * Vertical offset of upper-left corner of shape measured in 1/256 of row height + * + * @var int + */ + private $_startOffsetY; + + /** + * Cell coordinates of bottom-right corner of shape, e.g. 'B2' + * + * @var string + */ + private $_endCoordinates; + + /** + * Horizontal offset of bottom-right corner of shape measured in 1/1024 of column width + * + * @var int + */ + private $_endOffsetX; + + /** + * Vertical offset of bottom-right corner of shape measured in 1/256 of row height + * + * @var int + */ + private $_endOffsetY; + + /** + * Set parent Shape Group Container + * + * @param PHPExcel_Shared_Escher_DgContainer_SpgrContainer $parent + */ + public function setParent($parent) + { + $this->_parent = $parent; + } + + /** + * Get the parent Shape Group Container + * + * @return PHPExcel_Shared_Escher_DgContainer_SpgrContainer + */ + public function getParent() + { + return $this->_parent; + } + + /** + * Set whether this is a group shape + * + * @param boolean $value + */ + public function setSpgr($value = false) + { + $this->_spgr = $value; + } + + /** + * Get whether this is a group shape + * + * @return boolean + */ + public function getSpgr() + { + return $this->_spgr; + } + + /** + * Set the shape type + * + * @param int $value + */ + public function setSpType($value) + { + $this->_spType = $value; + } + + /** + * Get the shape type + * + * @return int + */ + public function getSpType() + { + return $this->_spType; + } + + /** + * Set the shape flag + * + * @param int $value + */ + public function setSpFlag($value) + { + $this->_spFlag = $value; + } + + /** + * Get the shape flag + * + * @return int + */ + public function getSpFlag() + { + return $this->_spFlag; + } + + /** + * Set the shape index + * + * @param int $value + */ + public function setSpId($value) + { + $this->_spId = $value; + } + + /** + * Get the shape index + * + * @return int + */ + public function getSpId() + { + return $this->_spId; + } + + /** + * Set an option for the Shape Group Container + * + * @param int $property The number specifies the option + * @param mixed $value + */ + public function setOPT($property, $value) + { + $this->_OPT[$property] = $value; + } + + /** + * Get an option for the Shape Group Container + * + * @param int $property The number specifies the option + * @return mixed + */ + public function getOPT($property) + { + if (isset($this->_OPT[$property])) { + return $this->_OPT[$property]; + } + return null; + } + + /** + * Get the collection of options + * + * @return array + */ + public function getOPTCollection() + { + return $this->_OPT; + } + + /** + * Set cell coordinates of upper-left corner of shape + * + * @param string $value + */ + public function setStartCoordinates($value = 'A1') + { + $this->_startCoordinates = $value; + } + + /** + * Get cell coordinates of upper-left corner of shape + * + * @return string + */ + public function getStartCoordinates() + { + return $this->_startCoordinates; + } + + /** + * Set offset in x-direction of upper-left corner of shape measured in 1/1024 of column width + * + * @param int $startOffsetX + */ + public function setStartOffsetX($startOffsetX = 0) + { + $this->_startOffsetX = $startOffsetX; + } + + /** + * Get offset in x-direction of upper-left corner of shape measured in 1/1024 of column width + * + * @return int + */ + public function getStartOffsetX() + { + return $this->_startOffsetX; + } + + /** + * Set offset in y-direction of upper-left corner of shape measured in 1/256 of row height + * + * @param int $startOffsetY + */ + public function setStartOffsetY($startOffsetY = 0) + { + $this->_startOffsetY = $startOffsetY; + } + + /** + * Get offset in y-direction of upper-left corner of shape measured in 1/256 of row height + * + * @return int + */ + public function getStartOffsetY() + { + return $this->_startOffsetY; + } + + /** + * Set cell coordinates of bottom-right corner of shape + * + * @param string $value + */ + public function setEndCoordinates($value = 'A1') + { + $this->_endCoordinates = $value; + } + + /** + * Get cell coordinates of bottom-right corner of shape + * + * @return string + */ + public function getEndCoordinates() + { + return $this->_endCoordinates; + } + + /** + * Set offset in x-direction of bottom-right corner of shape measured in 1/1024 of column width + * + * @param int $startOffsetX + */ + public function setEndOffsetX($endOffsetX = 0) + { + $this->_endOffsetX = $endOffsetX; + } + + /** + * Get offset in x-direction of bottom-right corner of shape measured in 1/1024 of column width + * + * @return int + */ + public function getEndOffsetX() + { + return $this->_endOffsetX; + } + + /** + * Set offset in y-direction of bottom-right corner of shape measured in 1/256 of row height + * + * @param int $endOffsetY + */ + public function setEndOffsetY($endOffsetY = 0) + { + $this->_endOffsetY = $endOffsetY; + } + + /** + * Get offset in y-direction of bottom-right corner of shape measured in 1/256 of row height + * + * @return int + */ + public function getEndOffsetY() + { + return $this->_endOffsetY; + } + + /** + * Get the nesting level of this spContainer. This is the number of spgrContainers between this spContainer and + * the dgContainer. A value of 1 = immediately within first spgrContainer + * Higher nesting level occurs if and only if spContainer is part of a shape group + * + * @return int Nesting level + */ + public function getNestingLevel() + { + $nestingLevel = 0; + + $parent = $this->getParent(); + while ($parent instanceof PHPExcel_Shared_Escher_DgContainer_SpgrContainer) { + ++$nestingLevel; + $parent = $parent->getParent(); + } + + return $nestingLevel; + } +} diff --git a/lib/phpexcel/PHPExcel/Shared/Escher/DggContainer.php b/lib/phpexcel/PHPExcel/Shared/Escher/DggContainer.php new file mode 100644 index 0000000..bf5f61f --- /dev/null +++ b/lib/phpexcel/PHPExcel/Shared/Escher/DggContainer.php @@ -0,0 +1,203 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared_Escher + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + +/** + * PHPExcel_Shared_Escher_DggContainer + * + * @category PHPExcel + * @package PHPExcel_Shared_Escher + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Shared_Escher_DggContainer +{ + /** + * Maximum shape index of all shapes in all drawings increased by one + * + * @var int + */ + private $_spIdMax; + + /** + * Total number of drawings saved + * + * @var int + */ + private $_cDgSaved; + + /** + * Total number of shapes saved (including group shapes) + * + * @var int + */ + private $_cSpSaved; + + /** + * BLIP Store Container + * + * @var PHPExcel_Shared_Escher_DggContainer_BstoreContainer + */ + private $_bstoreContainer; + + /** + * Array of options for the drawing group + * + * @var array + */ + private $_OPT = array(); + + /** + * Array of identifier clusters containg information about the maximum shape identifiers + * + * @var array + */ + private $_IDCLs = array(); + + /** + * Get maximum shape index of all shapes in all drawings (plus one) + * + * @return int + */ + public function getSpIdMax() + { + return $this->_spIdMax; + } + + /** + * Set maximum shape index of all shapes in all drawings (plus one) + * + * @param int + */ + public function setSpIdMax($value) + { + $this->_spIdMax = $value; + } + + /** + * Get total number of drawings saved + * + * @return int + */ + public function getCDgSaved() + { + return $this->_cDgSaved; + } + + /** + * Set total number of drawings saved + * + * @param int + */ + public function setCDgSaved($value) + { + $this->_cDgSaved = $value; + } + + /** + * Get total number of shapes saved (including group shapes) + * + * @return int + */ + public function getCSpSaved() + { + return $this->_cSpSaved; + } + + /** + * Set total number of shapes saved (including group shapes) + * + * @param int + */ + public function setCSpSaved($value) + { + $this->_cSpSaved = $value; + } + + /** + * Get BLIP Store Container + * + * @return PHPExcel_Shared_Escher_DggContainer_BstoreContainer + */ + public function getBstoreContainer() + { + return $this->_bstoreContainer; + } + + /** + * Set BLIP Store Container + * + * @param PHPExcel_Shared_Escher_DggContainer_BstoreContainer $bstoreContainer + */ + public function setBstoreContainer($bstoreContainer) + { + $this->_bstoreContainer = $bstoreContainer; + } + + /** + * Set an option for the drawing group + * + * @param int $property The number specifies the option + * @param mixed $value + */ + public function setOPT($property, $value) + { + $this->_OPT[$property] = $value; + } + + /** + * Get an option for the drawing group + * + * @param int $property The number specifies the option + * @return mixed + */ + public function getOPT($property) + { + if (isset($this->_OPT[$property])) { + return $this->_OPT[$property]; + } + return null; + } + + /** + * Get identifier clusters + * + * @return array + */ + public function getIDCLs() + { + return $this->_IDCLs; + } + + /** + * Set identifier clusters. array(<drawingId> => <max shape id>, ...) + * + * @param array $pValue + */ + public function setIDCLs($pValue) + { + $this->_IDCLs = $pValue; + } +} diff --git a/lib/phpexcel/PHPExcel/Shared/Escher/DggContainer/BstoreContainer.php b/lib/phpexcel/PHPExcel/Shared/Escher/DggContainer/BstoreContainer.php new file mode 100644 index 0000000..d16bfc7 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Shared/Escher/DggContainer/BstoreContainer.php @@ -0,0 +1,65 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared_Escher + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + +/** + * PHPExcel_Shared_Escher_DggContainer_BstoreContainer + * + * @category PHPExcel + * @package PHPExcel_Shared_Escher + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Shared_Escher_DggContainer_BstoreContainer +{ + /** + * BLIP Store Entries. Each of them holds one BLIP (Big Large Image or Picture) + * + * @var array + */ + private $_BSECollection = array(); + + /** + * Add a BLIP Store Entry + * + * @param PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE $BSE + */ + public function addBSE($BSE) + { + $this->_BSECollection[] = $BSE; + $BSE->setParent($this); + } + + /** + * Get the collection of BLIP Store Entries + * + * @return PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE[] + */ + public function getBSECollection() + { + return $this->_BSECollection; + } + +} diff --git a/lib/phpexcel/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE.php b/lib/phpexcel/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE.php new file mode 100644 index 0000000..ea3c52a --- /dev/null +++ b/lib/phpexcel/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE.php @@ -0,0 +1,120 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared_Escher + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + +/** + * PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE + * + * @category PHPExcel + * @package PHPExcel_Shared_Escher + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE +{ + const BLIPTYPE_ERROR = 0x00; + const BLIPTYPE_UNKNOWN = 0x01; + const BLIPTYPE_EMF = 0x02; + const BLIPTYPE_WMF = 0x03; + const BLIPTYPE_PICT = 0x04; + const BLIPTYPE_JPEG = 0x05; + const BLIPTYPE_PNG = 0x06; + const BLIPTYPE_DIB = 0x07; + const BLIPTYPE_TIFF = 0x11; + const BLIPTYPE_CMYKJPEG = 0x12; + + /** + * The parent BLIP Store Entry Container + * + * @var PHPExcel_Shared_Escher_DggContainer_BstoreContainer + */ + private $_parent; + + /** + * The BLIP (Big Large Image or Picture) + * + * @var PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip + */ + private $_blip; + + /** + * The BLIP type + * + * @var int + */ + private $_blipType; + + /** + * Set parent BLIP Store Entry Container + * + * @param PHPExcel_Shared_Escher_DggContainer_BstoreContainer $parent + */ + public function setParent($parent) + { + $this->_parent = $parent; + } + + /** + * Get the BLIP + * + * @return PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip + */ + public function getBlip() + { + return $this->_blip; + } + + /** + * Set the BLIP + * + * @param PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip $blip + */ + public function setBlip($blip) + { + $this->_blip = $blip; + $blip->setParent($this); + } + + /** + * Get the BLIP type + * + * @return int + */ + public function getBlipType() + { + return $this->_blipType; + } + + /** + * Set the BLIP type + * + * @param int + */ + public function setBlipType($blipType) + { + $this->_blipType = $blipType; + } + +} diff --git a/lib/phpexcel/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE/Blip.php b/lib/phpexcel/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE/Blip.php new file mode 100644 index 0000000..802ce6d --- /dev/null +++ b/lib/phpexcel/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE/Blip.php @@ -0,0 +1,91 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared_Escher + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + +/** + * PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip + * + * @category PHPExcel + * @package PHPExcel_Shared_Escher + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip +{ + /** + * The parent BSE + * + * @var PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE + */ + private $_parent; + + /** + * Raw image data + * + * @var string + */ + private $_data; + + /** + * Get the raw image data + * + * @return string + */ + public function getData() + { + return $this->_data; + } + + /** + * Set the raw image data + * + * @param string + */ + public function setData($data) + { + $this->_data = $data; + } + + /** + * Set parent BSE + * + * @param PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE $parent + */ + public function setParent($parent) + { + $this->_parent = $parent; + } + + /** + * Get parent BSE + * + * @return PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE $parent + */ + public function getParent() + { + return $this->_parent; + } + +} diff --git a/lib/phpexcel/PHPExcel/Shared/Excel5.php b/lib/phpexcel/PHPExcel/Shared/Excel5.php new file mode 100644 index 0000000..927dace --- /dev/null +++ b/lib/phpexcel/PHPExcel/Shared/Excel5.php @@ -0,0 +1,317 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + +/** + * PHPExcel_Shared_Excel5 + * + * @category PHPExcel + * @package PHPExcel_Shared + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Shared_Excel5 +{ + /** + * Get the width of a column in pixels. We use the relationship y = ceil(7x) where + * x is the width in intrinsic Excel units (measuring width in number of normal characters) + * This holds for Arial 10 + * + * @param PHPExcel_Worksheet $sheet The sheet + * @param string $col The column + * @return integer The width in pixels + */ + public static function sizeCol($sheet, $col = 'A') + { + // default font of the workbook + $font = $sheet->getParent()->getDefaultStyle()->getFont(); + + $columnDimensions = $sheet->getColumnDimensions(); + + // first find the true column width in pixels (uncollapsed and unhidden) + if ( isset($columnDimensions[$col]) and $columnDimensions[$col]->getWidth() != -1 ) { + + // then we have column dimension with explicit width + $columnDimension = $columnDimensions[$col]; + $width = $columnDimension->getWidth(); + $pixelWidth = PHPExcel_Shared_Drawing::cellDimensionToPixels($width, $font); + + } else if ($sheet->getDefaultColumnDimension()->getWidth() != -1) { + + // then we have default column dimension with explicit width + $defaultColumnDimension = $sheet->getDefaultColumnDimension(); + $width = $defaultColumnDimension->getWidth(); + $pixelWidth = PHPExcel_Shared_Drawing::cellDimensionToPixels($width, $font); + + } else { + + // we don't even have any default column dimension. Width depends on default font + $pixelWidth = PHPExcel_Shared_Font::getDefaultColumnWidthByFont($font, true); + } + + // now find the effective column width in pixels + if (isset($columnDimensions[$col]) and !$columnDimensions[$col]->getVisible()) { + $effectivePixelWidth = 0; + } else { + $effectivePixelWidth = $pixelWidth; + } + + return $effectivePixelWidth; + } + + /** + * Convert the height of a cell from user's units to pixels. By interpolation + * the relationship is: y = 4/3x. If the height hasn't been set by the user we + * use the default value. If the row is hidden we use a value of zero. + * + * @param PHPExcel_Worksheet $sheet The sheet + * @param integer $row The row index (1-based) + * @return integer The width in pixels + */ + public static function sizeRow($sheet, $row = 1) + { + // default font of the workbook + $font = $sheet->getParent()->getDefaultStyle()->getFont(); + + $rowDimensions = $sheet->getRowDimensions(); + + // first find the true row height in pixels (uncollapsed and unhidden) + if ( isset($rowDimensions[$row]) and $rowDimensions[$row]->getRowHeight() != -1) { + + // then we have a row dimension + $rowDimension = $rowDimensions[$row]; + $rowHeight = $rowDimension->getRowHeight(); + $pixelRowHeight = (int) ceil(4 * $rowHeight / 3); // here we assume Arial 10 + + } else if ($sheet->getDefaultRowDimension()->getRowHeight() != -1) { + + // then we have a default row dimension with explicit height + $defaultRowDimension = $sheet->getDefaultRowDimension(); + $rowHeight = $defaultRowDimension->getRowHeight(); + $pixelRowHeight = PHPExcel_Shared_Drawing::pointsToPixels($rowHeight); + + } else { + + // we don't even have any default row dimension. Height depends on default font + $pointRowHeight = PHPExcel_Shared_Font::getDefaultRowHeightByFont($font); + $pixelRowHeight = PHPExcel_Shared_Font::fontSizeToPixels($pointRowHeight); + + } + + // now find the effective row height in pixels + if ( isset($rowDimensions[$row]) and !$rowDimensions[$row]->getVisible() ) { + $effectivePixelRowHeight = 0; + } else { + $effectivePixelRowHeight = $pixelRowHeight; + } + + return $effectivePixelRowHeight; + } + + /** + * Get the horizontal distance in pixels between two anchors + * The distanceX is found as sum of all the spanning columns widths minus correction for the two offsets + * + * @param PHPExcel_Worksheet $sheet + * @param string $startColumn + * @param integer $startOffsetX Offset within start cell measured in 1/1024 of the cell width + * @param string $endColumn + * @param integer $endOffsetX Offset within end cell measured in 1/1024 of the cell width + * @return integer Horizontal measured in pixels + */ + public static function getDistanceX(PHPExcel_Worksheet $sheet, $startColumn = 'A', $startOffsetX = 0, $endColumn = 'A', $endOffsetX = 0) + { + $distanceX = 0; + + // add the widths of the spanning columns + $startColumnIndex = PHPExcel_Cell::columnIndexFromString($startColumn) - 1; // 1-based + $endColumnIndex = PHPExcel_Cell::columnIndexFromString($endColumn) - 1; // 1-based + for ($i = $startColumnIndex; $i <= $endColumnIndex; ++$i) { + $distanceX += self::sizeCol($sheet, PHPExcel_Cell::stringFromColumnIndex($i)); + } + + // correct for offsetX in startcell + $distanceX -= (int) floor(self::sizeCol($sheet, $startColumn) * $startOffsetX / 1024); + + // correct for offsetX in endcell + $distanceX -= (int) floor(self::sizeCol($sheet, $endColumn) * (1 - $endOffsetX / 1024)); + + return $distanceX; + } + + /** + * Get the vertical distance in pixels between two anchors + * The distanceY is found as sum of all the spanning rows minus two offsets + * + * @param PHPExcel_Worksheet $sheet + * @param integer $startRow (1-based) + * @param integer $startOffsetY Offset within start cell measured in 1/256 of the cell height + * @param integer $endRow (1-based) + * @param integer $endOffsetY Offset within end cell measured in 1/256 of the cell height + * @return integer Vertical distance measured in pixels + */ + public static function getDistanceY(PHPExcel_Worksheet $sheet, $startRow = 1, $startOffsetY = 0, $endRow = 1, $endOffsetY = 0) + { + $distanceY = 0; + + // add the widths of the spanning rows + for ($row = $startRow; $row <= $endRow; ++$row) { + $distanceY += self::sizeRow($sheet, $row); + } + + // correct for offsetX in startcell + $distanceY -= (int) floor(self::sizeRow($sheet, $startRow) * $startOffsetY / 256); + + // correct for offsetX in endcell + $distanceY -= (int) floor(self::sizeRow($sheet, $endRow) * (1 - $endOffsetY / 256)); + + return $distanceY; + } + + /** + * Convert 1-cell anchor coordinates to 2-cell anchor coordinates + * This function is ported from PEAR Spreadsheet_Writer_Excel with small modifications + * + * Calculate the vertices that define the position of the image as required by + * the OBJ record. + * + * +------------+------------+ + * | A | B | + * +-----+------------+------------+ + * | |(x1,y1) | | + * | 1 |(A1)._______|______ | + * | | | | | + * | | | | | + * +-----+----| BITMAP |-----+ + * | | | | | + * | 2 | |______________. | + * | | | (B2)| + * | | | (x2,y2)| + * +---- +------------+------------+ + * + * Example of a bitmap that covers some of the area from cell A1 to cell B2. + * + * Based on the width and height of the bitmap we need to calculate 8 vars: + * $col_start, $row_start, $col_end, $row_end, $x1, $y1, $x2, $y2. + * The width and height of the cells are also variable and have to be taken into + * account. + * The values of $col_start and $row_start are passed in from the calling + * function. The values of $col_end and $row_end are calculated by subtracting + * the width and height of the bitmap from the width and height of the + * underlying cells. + * The vertices are expressed as a percentage of the underlying cell width as + * follows (rhs values are in pixels): + * + * x1 = X / W *1024 + * y1 = Y / H *256 + * x2 = (X-1) / W *1024 + * y2 = (Y-1) / H *256 + * + * Where: X is distance from the left side of the underlying cell + * Y is distance from the top of the underlying cell + * W is the width of the cell + * H is the height of the cell + * + * @param PHPExcel_Worksheet $sheet + * @param string $coordinates E.g. 'A1' + * @param integer $offsetX Horizontal offset in pixels + * @param integer $offsetY Vertical offset in pixels + * @param integer $width Width in pixels + * @param integer $height Height in pixels + * @return array + */ + public static function oneAnchor2twoAnchor($sheet, $coordinates, $offsetX, $offsetY, $width, $height) + { + list($column, $row) = PHPExcel_Cell::coordinateFromString($coordinates); + $col_start = PHPExcel_Cell::columnIndexFromString($column) - 1; + $row_start = $row - 1; + + $x1 = $offsetX; + $y1 = $offsetY; + + // Initialise end cell to the same as the start cell + $col_end = $col_start; // Col containing lower right corner of object + $row_end = $row_start; // Row containing bottom right corner of object + + // Zero the specified offset if greater than the cell dimensions + if ($x1 >= self::sizeCol($sheet, PHPExcel_Cell::stringFromColumnIndex($col_start))) { + $x1 = 0; + } + if ($y1 >= self::sizeRow($sheet, $row_start + 1)) { + $y1 = 0; + } + + $width = $width + $x1 -1; + $height = $height + $y1 -1; + + // Subtract the underlying cell widths to find the end cell of the image + while ($width >= self::sizeCol($sheet, PHPExcel_Cell::stringFromColumnIndex($col_end))) { + $width -= self::sizeCol($sheet, PHPExcel_Cell::stringFromColumnIndex($col_end)); + ++$col_end; + } + + // Subtract the underlying cell heights to find the end cell of the image + while ($height >= self::sizeRow($sheet, $row_end + 1)) { + $height -= self::sizeRow($sheet, $row_end + 1); + ++$row_end; + } + + // Bitmap isn't allowed to start or finish in a hidden cell, i.e. a cell + // with zero height or width. + if (self::sizeCol($sheet, PHPExcel_Cell::stringFromColumnIndex($col_start)) == 0) { + return; + } + if (self::sizeCol($sheet, PHPExcel_Cell::stringFromColumnIndex($col_end)) == 0) { + return; + } + if (self::sizeRow($sheet, $row_start + 1) == 0) { + return; + } + if (self::sizeRow($sheet, $row_end + 1) == 0) { + return; + } + + // Convert the pixel values to the percentage value expected by Excel + $x1 = $x1 / self::sizeCol($sheet, PHPExcel_Cell::stringFromColumnIndex($col_start)) * 1024; + $y1 = $y1 / self::sizeRow($sheet, $row_start + 1) * 256; + $x2 = ($width + 1) / self::sizeCol($sheet, PHPExcel_Cell::stringFromColumnIndex($col_end)) * 1024; // Distance to right side of object + $y2 = ($height + 1) / self::sizeRow($sheet, $row_end + 1) * 256; // Distance to bottom of object + + $startCoordinates = PHPExcel_Cell::stringFromColumnIndex($col_start) . ($row_start + 1); + $endCoordinates = PHPExcel_Cell::stringFromColumnIndex($col_end) . ($row_end + 1); + + $twoAnchor = array( + 'startCoordinates' => $startCoordinates, + 'startOffsetX' => $x1, + 'startOffsetY' => $y1, + 'endCoordinates' => $endCoordinates, + 'endOffsetX' => $x2, + 'endOffsetY' => $y2, + ); + + return $twoAnchor; + } + +} diff --git a/lib/phpexcel/PHPExcel/Shared/File.php b/lib/phpexcel/PHPExcel/Shared/File.php new file mode 100644 index 0000000..70756a0 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Shared/File.php @@ -0,0 +1,178 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Shared_File + * + * @category PHPExcel + * @package PHPExcel_Shared + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Shared_File +{ + /* + * Use Temp or File Upload Temp for temporary files + * + * @protected + * @var boolean + */ + protected static $_useUploadTempDirectory = FALSE; + + + /** + * Set the flag indicating whether the File Upload Temp directory should be used for temporary files + * + * @param boolean $useUploadTempDir Use File Upload Temporary directory (true or false) + */ + public static function setUseUploadTempDirectory($useUploadTempDir = FALSE) { + self::$_useUploadTempDirectory = (boolean) $useUploadTempDir; + } // function setUseUploadTempDirectory() + + + /** + * Get the flag indicating whether the File Upload Temp directory should be used for temporary files + * + * @return boolean Use File Upload Temporary directory (true or false) + */ + public static function getUseUploadTempDirectory() { + return self::$_useUploadTempDirectory; + } // function getUseUploadTempDirectory() + + + /** + * Verify if a file exists + * + * @param string $pFilename Filename + * @return bool + */ + public static function file_exists($pFilename) { + // Sick construction, but it seems that + // file_exists returns strange values when + // doing the original file_exists on ZIP archives... + if ( strtolower(substr($pFilename, 0, 3)) == 'zip' ) { + // Open ZIP file and verify if the file exists + $zipFile = substr($pFilename, 6, strpos($pFilename, '#') - 6); + $archiveFile = substr($pFilename, strpos($pFilename, '#') + 1); + + $zip = new ZipArchive(); + if ($zip->open($zipFile) === true) { + $returnValue = ($zip->getFromName($archiveFile) !== false); + $zip->close(); + return $returnValue; + } else { + return false; + } + } else { + // Regular file_exists + return file_exists($pFilename); + } + } + + /** + * Returns canonicalized absolute pathname, also for ZIP archives + * + * @param string $pFilename + * @return string + */ + public static function realpath($pFilename) { + // Returnvalue + $returnValue = ''; + + // Try using realpath() + if (file_exists($pFilename)) { + $returnValue = realpath($pFilename); + } + + // Found something? + if ($returnValue == '' || ($returnValue === NULL)) { + $pathArray = explode('/' , $pFilename); + while(in_array('..', $pathArray) && $pathArray[0] != '..') { + for ($i = 0; $i < count($pathArray); ++$i) { + if ($pathArray[$i] == '..' && $i > 0) { + unset($pathArray[$i]); + unset($pathArray[$i - 1]); + break; + } + } + } + $returnValue = implode('/', $pathArray); + } + + // Return + return $returnValue; + } + + /** + * Get the systems temporary directory. + * + * @return string + */ + public static function sys_get_temp_dir() + { + if (self::$_useUploadTempDirectory) { + // use upload-directory when defined to allow running on environments having very restricted + // open_basedir configs + if (ini_get('upload_tmp_dir') !== FALSE) { + if ($temp = ini_get('upload_tmp_dir')) { + if (file_exists($temp)) + return realpath($temp); + } + } + } + + // sys_get_temp_dir is only available since PHP 5.2.1 + // http://php.net/manual/en/function.sys-get-temp-dir.php#94119 + if ( !function_exists('sys_get_temp_dir')) { + if ($temp = getenv('TMP') ) { + if ((!empty($temp)) && (file_exists($temp))) { return realpath($temp); } + } + if ($temp = getenv('TEMP') ) { + if ((!empty($temp)) && (file_exists($temp))) { return realpath($temp); } + } + if ($temp = getenv('TMPDIR') ) { + if ((!empty($temp)) && (file_exists($temp))) { return realpath($temp); } + } + + // trick for creating a file in system's temporary dir + // without knowing the path of the system's temporary dir + $temp = tempnam(__FILE__, ''); + if (file_exists($temp)) { + unlink($temp); + return realpath(dirname($temp)); + } + + return null; + } + + // use ordinary built-in PHP function + // There should be no problem with the 5.2.4 Suhosin realpath() bug, because this line should only + // be called if we're running 5.2.1 or earlier + return realpath(sys_get_temp_dir()); + } + +} diff --git a/lib/phpexcel/PHPExcel/Shared/Font.php b/lib/phpexcel/PHPExcel/Shared/Font.php new file mode 100644 index 0000000..203d4ec --- /dev/null +++ b/lib/phpexcel/PHPExcel/Shared/Font.php @@ -0,0 +1,775 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Shared_Font + * + * @category PHPExcel + * @package PHPExcel_Shared + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Shared_Font +{ + /* Methods for resolving autosize value */ + const AUTOSIZE_METHOD_APPROX = 'approx'; + const AUTOSIZE_METHOD_EXACT = 'exact'; + + private static $_autoSizeMethods = array( + self::AUTOSIZE_METHOD_APPROX, + self::AUTOSIZE_METHOD_EXACT, + ); + + /** Character set codes used by BIFF5-8 in Font records */ + const CHARSET_ANSI_LATIN = 0x00; + const CHARSET_SYSTEM_DEFAULT = 0x01; + const CHARSET_SYMBOL = 0x02; + const CHARSET_APPLE_ROMAN = 0x4D; + const CHARSET_ANSI_JAPANESE_SHIFTJIS = 0x80; + const CHARSET_ANSI_KOREAN_HANGUL = 0x81; + const CHARSET_ANSI_KOREAN_JOHAB = 0x82; + const CHARSET_ANSI_CHINESE_SIMIPLIFIED = 0x86; // gb2312 + const CHARSET_ANSI_CHINESE_TRADITIONAL = 0x88; // big5 + const CHARSET_ANSI_GREEK = 0xA1; + const CHARSET_ANSI_TURKISH = 0xA2; + const CHARSET_ANSI_VIETNAMESE = 0xA3; + const CHARSET_ANSI_HEBREW = 0xB1; + const CHARSET_ANSI_ARABIC = 0xB2; + const CHARSET_ANSI_BALTIC = 0xBA; + const CHARSET_ANSI_CYRILLIC = 0xCC; + const CHARSET_ANSI_THAI = 0xDD; + const CHARSET_ANSI_LATIN_II = 0xEE; + const CHARSET_OEM_LATIN_I = 0xFF; + + // XXX: Constants created! + /** Font filenames */ + const ARIAL = 'arial.ttf'; + const ARIAL_BOLD = 'arialbd.ttf'; + const ARIAL_ITALIC = 'ariali.ttf'; + const ARIAL_BOLD_ITALIC = 'arialbi.ttf'; + + const CALIBRI = 'CALIBRI.TTF'; + const CALIBRI_BOLD = 'CALIBRIB.TTF'; + const CALIBRI_ITALIC = 'CALIBRII.TTF'; + const CALIBRI_BOLD_ITALIC = 'CALIBRIZ.TTF'; + + const COMIC_SANS_MS = 'comic.ttf'; + const COMIC_SANS_MS_BOLD = 'comicbd.ttf'; + + const COURIER_NEW = 'cour.ttf'; + const COURIER_NEW_BOLD = 'courbd.ttf'; + const COURIER_NEW_ITALIC = 'couri.ttf'; + const COURIER_NEW_BOLD_ITALIC = 'courbi.ttf'; + + const GEORGIA = 'georgia.ttf'; + const GEORGIA_BOLD = 'georgiab.ttf'; + const GEORGIA_ITALIC = 'georgiai.ttf'; + const GEORGIA_BOLD_ITALIC = 'georgiaz.ttf'; + + const IMPACT = 'impact.ttf'; + + const LIBERATION_SANS = 'LiberationSans-Regular.ttf'; + const LIBERATION_SANS_BOLD = 'LiberationSans-Bold.ttf'; + const LIBERATION_SANS_ITALIC = 'LiberationSans-Italic.ttf'; + const LIBERATION_SANS_BOLD_ITALIC = 'LiberationSans-BoldItalic.ttf'; + + const LUCIDA_CONSOLE = 'lucon.ttf'; + const LUCIDA_SANS_UNICODE = 'l_10646.ttf'; + + const MICROSOFT_SANS_SERIF = 'micross.ttf'; + + const PALATINO_LINOTYPE = 'pala.ttf'; + const PALATINO_LINOTYPE_BOLD = 'palab.ttf'; + const PALATINO_LINOTYPE_ITALIC = 'palai.ttf'; + const PALATINO_LINOTYPE_BOLD_ITALIC = 'palabi.ttf'; + + const SYMBOL = 'symbol.ttf'; + + const TAHOMA = 'tahoma.ttf'; + const TAHOMA_BOLD = 'tahomabd.ttf'; + + const TIMES_NEW_ROMAN = 'times.ttf'; + const TIMES_NEW_ROMAN_BOLD = 'timesbd.ttf'; + const TIMES_NEW_ROMAN_ITALIC = 'timesi.ttf'; + const TIMES_NEW_ROMAN_BOLD_ITALIC = 'timesbi.ttf'; + + const TREBUCHET_MS = 'trebuc.ttf'; + const TREBUCHET_MS_BOLD = 'trebucbd.ttf'; + const TREBUCHET_MS_ITALIC = 'trebucit.ttf'; + const TREBUCHET_MS_BOLD_ITALIC = 'trebucbi.ttf'; + + const VERDANA = 'verdana.ttf'; + const VERDANA_BOLD = 'verdanab.ttf'; + const VERDANA_ITALIC = 'verdanai.ttf'; + const VERDANA_BOLD_ITALIC = 'verdanaz.ttf'; + + /** + * AutoSize method + * + * @var string + */ + private static $autoSizeMethod = self::AUTOSIZE_METHOD_APPROX; + + /** + * Path to folder containing TrueType font .ttf files + * + * @var string + */ + private static $trueTypeFontPath = null; + + /** + * How wide is a default column for a given default font and size? + * Empirical data found by inspecting real Excel files and reading off the pixel width + * in Microsoft Office Excel 2007. + * + * @var array + */ + public static $defaultColumnWidths = array( + 'Arial' => array( + 1 => array('px' => 24, 'width' => 12.00000000), + 2 => array('px' => 24, 'width' => 12.00000000), + 3 => array('px' => 32, 'width' => 10.66406250), + 4 => array('px' => 32, 'width' => 10.66406250), + 5 => array('px' => 40, 'width' => 10.00000000), + 6 => array('px' => 48, 'width' => 9.59765625), + 7 => array('px' => 48, 'width' => 9.59765625), + 8 => array('px' => 56, 'width' => 9.33203125), + 9 => array('px' => 64, 'width' => 9.14062500), + 10 => array('px' => 64, 'width' => 9.14062500), + ), + 'Calibri' => array( + 1 => array('px' => 24, 'width' => 12.00000000), + 2 => array('px' => 24, 'width' => 12.00000000), + 3 => array('px' => 32, 'width' => 10.66406250), + 4 => array('px' => 32, 'width' => 10.66406250), + 5 => array('px' => 40, 'width' => 10.00000000), + 6 => array('px' => 48, 'width' => 9.59765625), + 7 => array('px' => 48, 'width' => 9.59765625), + 8 => array('px' => 56, 'width' => 9.33203125), + 9 => array('px' => 56, 'width' => 9.33203125), + 10 => array('px' => 64, 'width' => 9.14062500), + 11 => array('px' => 64, 'width' => 9.14062500), + ), + 'Verdana' => array( + 1 => array('px' => 24, 'width' => 12.00000000), + 2 => array('px' => 24, 'width' => 12.00000000), + 3 => array('px' => 32, 'width' => 10.66406250), + 4 => array('px' => 32, 'width' => 10.66406250), + 5 => array('px' => 40, 'width' => 10.00000000), + 6 => array('px' => 48, 'width' => 9.59765625), + 7 => array('px' => 48, 'width' => 9.59765625), + 8 => array('px' => 64, 'width' => 9.14062500), + 9 => array('px' => 72, 'width' => 9.00000000), + 10 => array('px' => 72, 'width' => 9.00000000), + ), + ); + + /** + * Set autoSize method + * + * @param string $pValue + * @return boolean Success or failure + */ + public static function setAutoSizeMethod($pValue = self::AUTOSIZE_METHOD_APPROX) + { + if (!in_array($pValue,self::$_autoSizeMethods)) { + return FALSE; + } + + self::$autoSizeMethod = $pValue; + + return TRUE; + } + + /** + * Get autoSize method + * + * @return string + */ + public static function getAutoSizeMethod() + { + return self::$autoSizeMethod; + } + + /** + * Set the path to the folder containing .ttf files. There should be a trailing slash. + * Typical locations on variout some platforms: + * <ul> + * <li>C:/Windows/Fonts/</li> + * <li>/usr/share/fonts/truetype/</li> + * <li>~/.fonts/</li> + * </ul> + * + * @param string $pValue + */ + public static function setTrueTypeFontPath($pValue = '') + { + self::$trueTypeFontPath = $pValue; + } + + /** + * Get the path to the folder containing .ttf files. + * + * @return string + */ + public static function getTrueTypeFontPath() + { + return self::$trueTypeFontPath; + } + + /** + * Calculate an (approximate) OpenXML column width, based on font size and text contained + * + * @param PHPExcel_Style_Font $font Font object + * @param PHPExcel_RichText|string $cellText Text to calculate width + * @param integer $rotation Rotation angle + * @param PHPExcel_Style_Font|NULL $defaultFont Font object + * @return integer Column width + */ + public static function calculateColumnWidth(PHPExcel_Style_Font $font, $cellText = '', $rotation = 0, PHPExcel_Style_Font $defaultFont = null) { + + // If it is rich text, use plain text + if ($cellText instanceof PHPExcel_RichText) { + $cellText = $cellText->getPlainText(); + } + + // Special case if there are one or more newline characters ("\n") + if (strpos($cellText, "\n") !== false) { + $lineTexts = explode("\n", $cellText); + $lineWitdhs = array(); + foreach ($lineTexts as $lineText) { + $lineWidths[] = self::calculateColumnWidth($font, $lineText, $rotation = 0, $defaultFont); + } + return max($lineWidths); // width of longest line in cell + } + + // Try to get the exact text width in pixels + try { + // If autosize method is set to 'approx', use approximation + if (self::$autoSizeMethod == self::AUTOSIZE_METHOD_APPROX) { + throw new PHPExcel_Exception('AutoSize method is set to approx'); + } + + // Width of text in pixels excl. padding + $columnWidth = self::getTextWidthPixelsExact($cellText, $font, $rotation); + + // Excel adds some padding, use 1.07 of the width of an 'n' glyph + $columnWidth += ceil(self::getTextWidthPixelsExact('0', $font, 0) * 1.07); // pixels incl. padding + + } catch (PHPExcel_Exception $e) { + // Width of text in pixels excl. padding, approximation + $columnWidth = self::getTextWidthPixelsApprox($cellText, $font, $rotation); + + // Excel adds some padding, just use approx width of 'n' glyph + $columnWidth += self::getTextWidthPixelsApprox('n', $font, 0); + } + + // Convert from pixel width to column width + $columnWidth = PHPExcel_Shared_Drawing::pixelsToCellDimension($columnWidth, $defaultFont); + + // Return + return round($columnWidth, 6); + } + + /** + * Get GD text width in pixels for a string of text in a certain font at a certain rotation angle + * + * @param string $text + * @param PHPExcel_Style_Font + * @param int $rotation + * @return int + * @throws PHPExcel_Exception + */ + public static function getTextWidthPixelsExact($text, PHPExcel_Style_Font $font, $rotation = 0) { + if (!function_exists('imagettfbbox')) { + throw new PHPExcel_Exception('GD library needs to be enabled'); + } + + // font size should really be supplied in pixels in GD2, + // but since GD2 seems to assume 72dpi, pixels and points are the same + $fontFile = self::getTrueTypeFontFileFromFont($font); + $textBox = imagettfbbox($font->getSize(), $rotation, $fontFile, $text); + + // Get corners positions + $lowerLeftCornerX = $textBox[0]; + $lowerLeftCornerY = $textBox[1]; + $lowerRightCornerX = $textBox[2]; + $lowerRightCornerY = $textBox[3]; + $upperRightCornerX = $textBox[4]; + $upperRightCornerY = $textBox[5]; + $upperLeftCornerX = $textBox[6]; + $upperLeftCornerY = $textBox[7]; + + // Consider the rotation when calculating the width + $textWidth = max($lowerRightCornerX - $upperLeftCornerX, $upperRightCornerX - $lowerLeftCornerX); + + return $textWidth; + } + + /** + * Get approximate width in pixels for a string of text in a certain font at a certain rotation angle + * + * @param string $columnText + * @param PHPExcel_Style_Font $font + * @param int $rotation + * @return int Text width in pixels (no padding added) + */ + public static function getTextWidthPixelsApprox($columnText, PHPExcel_Style_Font $font = null, $rotation = 0) + { + $fontName = $font->getName(); + $fontSize = $font->getSize(); + + // Calculate column width in pixels. We assume fixed glyph width. Result varies with font name and size. + switch ($fontName) { + case 'Calibri': + // value 8.26 was found via interpolation by inspecting real Excel files with Calibri 11 font. + $columnWidth = (int) (8.26 * PHPExcel_Shared_String::CountCharacters($columnText)); + $columnWidth = $columnWidth * $fontSize / 11; // extrapolate from font size + break; + + case 'Arial': + // value 7 was found via interpolation by inspecting real Excel files with Arial 10 font. + $columnWidth = (int) (7 * PHPExcel_Shared_String::CountCharacters($columnText)); + $columnWidth = $columnWidth * $fontSize / 10; // extrapolate from font size + break; + + case 'Verdana': + // value 8 was found via interpolation by inspecting real Excel files with Verdana 10 font. + $columnWidth = (int) (8 * PHPExcel_Shared_String::CountCharacters($columnText)); + $columnWidth = $columnWidth * $fontSize / 10; // extrapolate from font size + break; + + default: + // just assume Calibri + $columnWidth = (int) (8.26 * PHPExcel_Shared_String::CountCharacters($columnText)); + $columnWidth = $columnWidth * $fontSize / 11; // extrapolate from font size + break; + } + + // Calculate approximate rotated column width + if ($rotation !== 0) { + if ($rotation == -165) { + // stacked text + $columnWidth = 4; // approximation + } else { + // rotated text + $columnWidth = $columnWidth * cos(deg2rad($rotation)) + + $fontSize * abs(sin(deg2rad($rotation))) / 5; // approximation + } + } + + // pixel width is an integer + $columnWidth = (int) $columnWidth; + return $columnWidth; + } + + /** + * Calculate an (approximate) pixel size, based on a font points size + * + * @param int $fontSizeInPoints Font size (in points) + * @return int Font size (in pixels) + */ + public static function fontSizeToPixels($fontSizeInPoints = 11) { + return (int) ((4 / 3) * $fontSizeInPoints); + } + + /** + * Calculate an (approximate) pixel size, based on inch size + * + * @param int $sizeInInch Font size (in inch) + * @return int Size (in pixels) + */ + public static function inchSizeToPixels($sizeInInch = 1) { + return ($sizeInInch * 96); + } + + /** + * Calculate an (approximate) pixel size, based on centimeter size + * + * @param int $sizeInCm Font size (in centimeters) + * @return int Size (in pixels) + */ + public static function centimeterSizeToPixels($sizeInCm = 1) { + return ($sizeInCm * 37.795275591); + } + + /** + * Returns the font path given the font + * + * @param PHPExcel_Style_Font + * @return string Path to TrueType font file + */ + public static function getTrueTypeFontFileFromFont($font) { + if (!file_exists(self::$trueTypeFontPath) || !is_dir(self::$trueTypeFontPath)) { + throw new PHPExcel_Exception('Valid directory to TrueType Font files not specified'); + } + + $name = $font->getName(); + $bold = $font->getBold(); + $italic = $font->getItalic(); + + // Check if we can map font to true type font file + switch ($name) { + case 'Arial': + $fontFile = ( + $bold ? ($italic ? self::ARIAL_BOLD_ITALIC : self::ARIAL_BOLD) + : ($italic ? self::ARIAL_ITALIC : self::ARIAL) + ); + break; + + case 'Calibri': + $fontFile = ( + $bold ? ($italic ? self::CALIBRI_BOLD_ITALIC : self::CALIBRI_BOLD) + : ($italic ? self::CALIBRI_ITALIC : self::CALIBRI) + ); + break; + + case 'Courier New': + $fontFile = ( + $bold ? ($italic ? self::COURIER_NEW_BOLD_ITALIC : self::COURIER_NEW_BOLD) + : ($italic ? self::COURIER_NEW_ITALIC : self::COURIER_NEW) + ); + break; + + case 'Comic Sans MS': + $fontFile = ( + $bold ? self::COMIC_SANS_MS_BOLD : self::COMIC_SANS_MS + ); + break; + + case 'Georgia': + $fontFile = ( + $bold ? ($italic ? self::GEORGIA_BOLD_ITALIC : self::GEORGIA_BOLD) + : ($italic ? self::GEORGIA_ITALIC : self::GEORGIA) + ); + break; + + case 'Impact': + $fontFile = self::IMPACT; + break; + + case 'Liberation Sans': + $fontFile = ( + $bold ? ($italic ? self::LIBERATION_SANS_BOLD_ITALIC : self::LIBERATION_SANS_BOLD) + : ($italic ? self::LIBERATION_SANS_ITALIC : self::LIBERATION_SANS) + ); + break; + + case 'Lucida Console': + $fontFile = self::LUCIDA_CONSOLE; + break; + + case 'Lucida Sans Unicode': + $fontFile = self::LUCIDA_SANS_UNICODE; + break; + + case 'Microsoft Sans Serif': + $fontFile = self::MICROSOFT_SANS_SERIF; + break; + + case 'Palatino Linotype': + $fontFile = ( + $bold ? ($italic ? self::PALATINO_LINOTYPE_BOLD_ITALIC : self::PALATINO_LINOTYPE_BOLD) + : ($italic ? self::PALATINO_LINOTYPE_ITALIC : self::PALATINO_LINOTYPE) + ); + break; + + case 'Symbol': + $fontFile = self::SYMBOL; + break; + + case 'Tahoma': + $fontFile = ( + $bold ? self::TAHOMA_BOLD : self::TAHOMA + ); + break; + + case 'Times New Roman': + $fontFile = ( + $bold ? ($italic ? self::TIMES_NEW_ROMAN_BOLD_ITALIC : self::TIMES_NEW_ROMAN_BOLD) + : ($italic ? self::TIMES_NEW_ROMAN_ITALIC : self::TIMES_NEW_ROMAN) + ); + break; + + case 'Trebuchet MS': + $fontFile = ( + $bold ? ($italic ? self::TREBUCHET_MS_BOLD_ITALIC : self::TREBUCHET_MS_BOLD) + : ($italic ? self::TREBUCHET_MS_ITALIC : self::TREBUCHET_MS) + ); + break; + + case 'Verdana': + $fontFile = ( + $bold ? ($italic ? self::VERDANA_BOLD_ITALIC : self::VERDANA_BOLD) + : ($italic ? self::VERDANA_ITALIC : self::VERDANA) + ); + break; + + default: + throw new PHPExcel_Exception('Unknown font name "'. $name .'". Cannot map to TrueType font file'); + break; + } + + $fontFile = self::$trueTypeFontPath . $fontFile; + + // Check if file actually exists + if (!file_exists($fontFile)) { + throw New PHPExcel_Exception('TrueType Font file not found'); + } + + return $fontFile; + } + + /** + * Returns the associated charset for the font name. + * + * @param string $name Font name + * @return int Character set code + */ + public static function getCharsetFromFontName($name) + { + switch ($name) { + // Add more cases. Check FONT records in real Excel files. + case 'EucrosiaUPC': return self::CHARSET_ANSI_THAI; + case 'Wingdings': return self::CHARSET_SYMBOL; + case 'Wingdings 2': return self::CHARSET_SYMBOL; + case 'Wingdings 3': return self::CHARSET_SYMBOL; + default: return self::CHARSET_ANSI_LATIN; + } + } + + /** + * Get the effective column width for columns without a column dimension or column with width -1 + * For example, for Calibri 11 this is 9.140625 (64 px) + * + * @param PHPExcel_Style_Font $font The workbooks default font + * @param boolean $pPixels true = return column width in pixels, false = return in OOXML units + * @return mixed Column width + */ + public static function getDefaultColumnWidthByFont(PHPExcel_Style_Font $font, $pPixels = false) + { + if (isset(self::$defaultColumnWidths[$font->getName()][$font->getSize()])) { + // Exact width can be determined + $columnWidth = $pPixels ? + self::$defaultColumnWidths[$font->getName()][$font->getSize()]['px'] + : self::$defaultColumnWidths[$font->getName()][$font->getSize()]['width']; + + } else { + // We don't have data for this particular font and size, use approximation by + // extrapolating from Calibri 11 + $columnWidth = $pPixels ? + self::$defaultColumnWidths['Calibri'][11]['px'] + : self::$defaultColumnWidths['Calibri'][11]['width']; + $columnWidth = $columnWidth * $font->getSize() / 11; + + // Round pixels to closest integer + if ($pPixels) { + $columnWidth = (int) round($columnWidth); + } + } + + return $columnWidth; + } + + /** + * Get the effective row height for rows without a row dimension or rows with height -1 + * For example, for Calibri 11 this is 15 points + * + * @param PHPExcel_Style_Font $font The workbooks default font + * @return float Row height in points + */ + public static function getDefaultRowHeightByFont(PHPExcel_Style_Font $font) + { + switch ($font->getName()) { + case 'Arial': + switch ($font->getSize()) { + case 10: + // inspection of Arial 10 workbook says 12.75pt ~17px + $rowHeight = 12.75; + break; + + case 9: + // inspection of Arial 9 workbook says 12.00pt ~16px + $rowHeight = 12; + break; + + case 8: + // inspection of Arial 8 workbook says 11.25pt ~15px + $rowHeight = 11.25; + break; + + case 7: + // inspection of Arial 7 workbook says 9.00pt ~12px + $rowHeight = 9; + break; + + case 6: + case 5: + // inspection of Arial 5,6 workbook says 8.25pt ~11px + $rowHeight = 8.25; + break; + + case 4: + // inspection of Arial 4 workbook says 6.75pt ~9px + $rowHeight = 6.75; + break; + + case 3: + // inspection of Arial 3 workbook says 6.00pt ~8px + $rowHeight = 6; + break; + + case 2: + case 1: + // inspection of Arial 1,2 workbook says 5.25pt ~7px + $rowHeight = 5.25; + break; + + default: + // use Arial 10 workbook as an approximation, extrapolation + $rowHeight = 12.75 * $font->getSize() / 10; + break; + } + break; + + case 'Calibri': + switch ($font->getSize()) { + case 11: + // inspection of Calibri 11 workbook says 15.00pt ~20px + $rowHeight = 15; + break; + + case 10: + // inspection of Calibri 10 workbook says 12.75pt ~17px + $rowHeight = 12.75; + break; + + case 9: + // inspection of Calibri 9 workbook says 12.00pt ~16px + $rowHeight = 12; + break; + + case 8: + // inspection of Calibri 8 workbook says 11.25pt ~15px + $rowHeight = 11.25; + break; + + case 7: + // inspection of Calibri 7 workbook says 9.00pt ~12px + $rowHeight = 9; + break; + + case 6: + case 5: + // inspection of Calibri 5,6 workbook says 8.25pt ~11px + $rowHeight = 8.25; + break; + + case 4: + // inspection of Calibri 4 workbook says 6.75pt ~9px + $rowHeight = 6.75; + break; + + case 3: + // inspection of Calibri 3 workbook says 6.00pt ~8px + $rowHeight = 6.00; + break; + + case 2: + case 1: + // inspection of Calibri 1,2 workbook says 5.25pt ~7px + $rowHeight = 5.25; + break; + + default: + // use Calibri 11 workbook as an approximation, extrapolation + $rowHeight = 15 * $font->getSize() / 11; + break; + } + break; + + case 'Verdana': + switch ($font->getSize()) { + case 10: + // inspection of Verdana 10 workbook says 12.75pt ~17px + $rowHeight = 12.75; + break; + + case 9: + // inspection of Verdana 9 workbook says 11.25pt ~15px + $rowHeight = 11.25; + break; + + case 8: + // inspection of Verdana 8 workbook says 10.50pt ~14px + $rowHeight = 10.50; + break; + + case 7: + // inspection of Verdana 7 workbook says 9.00pt ~12px + $rowHeight = 9.00; + break; + + case 6: + case 5: + // inspection of Verdana 5,6 workbook says 8.25pt ~11px + $rowHeight = 8.25; + break; + + case 4: + // inspection of Verdana 4 workbook says 6.75pt ~9px + $rowHeight = 6.75; + break; + + case 3: + // inspection of Verdana 3 workbook says 6.00pt ~8px + $rowHeight = 6; + break; + + case 2: + case 1: + // inspection of Verdana 1,2 workbook says 5.25pt ~7px + $rowHeight = 5.25; + break; + + default: + // use Verdana 10 workbook as an approximation, extrapolation + $rowHeight = 12.75 * $font->getSize() / 10; + break; + } + break; + + default: + // just use Calibri as an approximation + $rowHeight = 15 * $font->getSize() / 11; + break; + } + + return $rowHeight; + } + +} diff --git a/lib/phpexcel/PHPExcel/Shared/JAMA/CHANGELOG.TXT b/lib/phpexcel/PHPExcel/Shared/JAMA/CHANGELOG.TXT new file mode 100644 index 0000000..1c18a5d --- /dev/null +++ b/lib/phpexcel/PHPExcel/Shared/JAMA/CHANGELOG.TXT @@ -0,0 +1,16 @@ +Mar 1, 2005 11:15 AST by PM + ++ For consistency, renamed Math.php to Maths.java, utils to util, + tests to test, docs to doc - + ++ Removed conditional logic from top of Matrix class. + ++ Switched to using hypo function in Maths.php for all php-hypot calls. + NOTE TO SELF: Need to make sure that all decompositions have been + switched over to using the bundled hypo. + +Feb 25, 2005 at 10:00 AST by PM + ++ Recommend using simpler Error.php instead of JAMA_Error.php but + can be persuaded otherwise. + diff --git a/lib/phpexcel/PHPExcel/Shared/JAMA/CholeskyDecomposition.php b/lib/phpexcel/PHPExcel/Shared/JAMA/CholeskyDecomposition.php new file mode 100644 index 0000000..cfbaa53 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Shared/JAMA/CholeskyDecomposition.php @@ -0,0 +1,149 @@ +<?php +/** + * @package JAMA + * + * Cholesky decomposition class + * + * For a symmetric, positive definite matrix A, the Cholesky decomposition + * is an lower triangular matrix L so that A = L*L'. + * + * If the matrix is not symmetric or positive definite, the constructor + * returns a partial decomposition and sets an internal flag that may + * be queried by the isSPD() method. + * + * @author Paul Meagher + * @author Michael Bommarito + * @version 1.2 + */ +class CholeskyDecomposition { + + /** + * Decomposition storage + * @var array + * @access private + */ + private $L = array(); + + /** + * Matrix row and column dimension + * @var int + * @access private + */ + private $m; + + /** + * Symmetric positive definite flag + * @var boolean + * @access private + */ + private $isspd = true; + + + /** + * CholeskyDecomposition + * + * Class constructor - decomposes symmetric positive definite matrix + * @param mixed Matrix square symmetric positive definite matrix + */ + public function __construct($A = null) { + if ($A instanceof Matrix) { + $this->L = $A->getArray(); + $this->m = $A->getRowDimension(); + + for($i = 0; $i < $this->m; ++$i) { + for($j = $i; $j < $this->m; ++$j) { + for($sum = $this->L[$i][$j], $k = $i - 1; $k >= 0; --$k) { + $sum -= $this->L[$i][$k] * $this->L[$j][$k]; + } + if ($i == $j) { + if ($sum >= 0) { + $this->L[$i][$i] = sqrt($sum); + } else { + $this->isspd = false; + } + } else { + if ($this->L[$i][$i] != 0) { + $this->L[$j][$i] = $sum / $this->L[$i][$i]; + } + } + } + + for ($k = $i+1; $k < $this->m; ++$k) { + $this->L[$i][$k] = 0.0; + } + } + } else { + throw new PHPExcel_Calculation_Exception(JAMAError(ArgumentTypeException)); + } + } // function __construct() + + + /** + * Is the matrix symmetric and positive definite? + * + * @return boolean + */ + public function isSPD() { + return $this->isspd; + } // function isSPD() + + + /** + * getL + * + * Return triangular factor. + * @return Matrix Lower triangular matrix + */ + public function getL() { + return new Matrix($this->L); + } // function getL() + + + /** + * Solve A*X = B + * + * @param $B Row-equal matrix + * @return Matrix L * L' * X = B + */ + public function solve($B = null) { + if ($B instanceof Matrix) { + if ($B->getRowDimension() == $this->m) { + if ($this->isspd) { + $X = $B->getArrayCopy(); + $nx = $B->getColumnDimension(); + + for ($k = 0; $k < $this->m; ++$k) { + for ($i = $k + 1; $i < $this->m; ++$i) { + for ($j = 0; $j < $nx; ++$j) { + $X[$i][$j] -= $X[$k][$j] * $this->L[$i][$k]; + } + } + for ($j = 0; $j < $nx; ++$j) { + $X[$k][$j] /= $this->L[$k][$k]; + } + } + + for ($k = $this->m - 1; $k >= 0; --$k) { + for ($j = 0; $j < $nx; ++$j) { + $X[$k][$j] /= $this->L[$k][$k]; + } + for ($i = 0; $i < $k; ++$i) { + for ($j = 0; $j < $nx; ++$j) { + $X[$i][$j] -= $X[$k][$j] * $this->L[$k][$i]; + } + } + } + + return new Matrix($X, $this->m, $nx); + } else { + throw new PHPExcel_Calculation_Exception(JAMAError(MatrixSPDException)); + } + } else { + throw new PHPExcel_Calculation_Exception(JAMAError(MatrixDimensionException)); + } + } else { + throw new PHPExcel_Calculation_Exception(JAMAError(ArgumentTypeException)); + } + } // function solve() + +} // class CholeskyDecomposition diff --git a/lib/phpexcel/PHPExcel/Shared/JAMA/EigenvalueDecomposition.php b/lib/phpexcel/PHPExcel/Shared/JAMA/EigenvalueDecomposition.php new file mode 100644 index 0000000..2a696d0 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Shared/JAMA/EigenvalueDecomposition.php @@ -0,0 +1,862 @@ +<?php +/** + * @package JAMA + * + * Class to obtain eigenvalues and eigenvectors of a real matrix. + * + * If A is symmetric, then A = V*D*V' where the eigenvalue matrix D + * is diagonal and the eigenvector matrix V is orthogonal (i.e. + * A = V.times(D.times(V.transpose())) and V.times(V.transpose()) + * equals the identity matrix). + * + * If A is not symmetric, then the eigenvalue matrix D is block diagonal + * with the real eigenvalues in 1-by-1 blocks and any complex eigenvalues, + * lambda + i*mu, in 2-by-2 blocks, [lambda, mu; -mu, lambda]. The + * columns of V represent the eigenvectors in the sense that A*V = V*D, + * i.e. A.times(V) equals V.times(D). The matrix V may be badly + * conditioned, or even singular, so the validity of the equation + * A = V*D*inverse(V) depends upon V.cond(). + * + * @author Paul Meagher + * @license PHP v3.0 + * @version 1.1 + */ +class EigenvalueDecomposition { + + /** + * Row and column dimension (square matrix). + * @var int + */ + private $n; + + /** + * Internal symmetry flag. + * @var int + */ + private $issymmetric; + + /** + * Arrays for internal storage of eigenvalues. + * @var array + */ + private $d = array(); + private $e = array(); + + /** + * Array for internal storage of eigenvectors. + * @var array + */ + private $V = array(); + + /** + * Array for internal storage of nonsymmetric Hessenberg form. + * @var array + */ + private $H = array(); + + /** + * Working storage for nonsymmetric algorithm. + * @var array + */ + private $ort; + + /** + * Used for complex scalar division. + * @var float + */ + private $cdivr; + private $cdivi; + + + /** + * Symmetric Householder reduction to tridiagonal form. + * + * @access private + */ + private function tred2 () { + // This is derived from the Algol procedures tred2 by + // Bowdler, Martin, Reinsch, and Wilkinson, Handbook for + // Auto. Comp., Vol.ii-Linear Algebra, and the corresponding + // Fortran subroutine in EISPACK. + $this->d = $this->V[$this->n-1]; + // Householder reduction to tridiagonal form. + for ($i = $this->n-1; $i > 0; --$i) { + $i_ = $i -1; + // Scale to avoid under/overflow. + $h = $scale = 0.0; + $scale += array_sum(array_map(abs, $this->d)); + if ($scale == 0.0) { + $this->e[$i] = $this->d[$i_]; + $this->d = array_slice($this->V[$i_], 0, $i_); + for ($j = 0; $j < $i; ++$j) { + $this->V[$j][$i] = $this->V[$i][$j] = 0.0; + } + } else { + // Generate Householder vector. + for ($k = 0; $k < $i; ++$k) { + $this->d[$k] /= $scale; + $h += pow($this->d[$k], 2); + } + $f = $this->d[$i_]; + $g = sqrt($h); + if ($f > 0) { + $g = -$g; + } + $this->e[$i] = $scale * $g; + $h = $h - $f * $g; + $this->d[$i_] = $f - $g; + for ($j = 0; $j < $i; ++$j) { + $this->e[$j] = 0.0; + } + // Apply similarity transformation to remaining columns. + for ($j = 0; $j < $i; ++$j) { + $f = $this->d[$j]; + $this->V[$j][$i] = $f; + $g = $this->e[$j] + $this->V[$j][$j] * $f; + for ($k = $j+1; $k <= $i_; ++$k) { + $g += $this->V[$k][$j] * $this->d[$k]; + $this->e[$k] += $this->V[$k][$j] * $f; + } + $this->e[$j] = $g; + } + $f = 0.0; + for ($j = 0; $j < $i; ++$j) { + $this->e[$j] /= $h; + $f += $this->e[$j] * $this->d[$j]; + } + $hh = $f / (2 * $h); + for ($j=0; $j < $i; ++$j) { + $this->e[$j] -= $hh * $this->d[$j]; + } + for ($j = 0; $j < $i; ++$j) { + $f = $this->d[$j]; + $g = $this->e[$j]; + for ($k = $j; $k <= $i_; ++$k) { + $this->V[$k][$j] -= ($f * $this->e[$k] + $g * $this->d[$k]); + } + $this->d[$j] = $this->V[$i-1][$j]; + $this->V[$i][$j] = 0.0; + } + } + $this->d[$i] = $h; + } + + // Accumulate transformations. + for ($i = 0; $i < $this->n-1; ++$i) { + $this->V[$this->n-1][$i] = $this->V[$i][$i]; + $this->V[$i][$i] = 1.0; + $h = $this->d[$i+1]; + if ($h != 0.0) { + for ($k = 0; $k <= $i; ++$k) { + $this->d[$k] = $this->V[$k][$i+1] / $h; + } + for ($j = 0; $j <= $i; ++$j) { + $g = 0.0; + for ($k = 0; $k <= $i; ++$k) { + $g += $this->V[$k][$i+1] * $this->V[$k][$j]; + } + for ($k = 0; $k <= $i; ++$k) { + $this->V[$k][$j] -= $g * $this->d[$k]; + } + } + } + for ($k = 0; $k <= $i; ++$k) { + $this->V[$k][$i+1] = 0.0; + } + } + + $this->d = $this->V[$this->n-1]; + $this->V[$this->n-1] = array_fill(0, $j, 0.0); + $this->V[$this->n-1][$this->n-1] = 1.0; + $this->e[0] = 0.0; + } + + + /** + * Symmetric tridiagonal QL algorithm. + * + * This is derived from the Algol procedures tql2, by + * Bowdler, Martin, Reinsch, and Wilkinson, Handbook for + * Auto. Comp., Vol.ii-Linear Algebra, and the corresponding + * Fortran subroutine in EISPACK. + * + * @access private + */ + private function tql2() { + for ($i = 1; $i < $this->n; ++$i) { + $this->e[$i-1] = $this->e[$i]; + } + $this->e[$this->n-1] = 0.0; + $f = 0.0; + $tst1 = 0.0; + $eps = pow(2.0,-52.0); + + for ($l = 0; $l < $this->n; ++$l) { + // Find small subdiagonal element + $tst1 = max($tst1, abs($this->d[$l]) + abs($this->e[$l])); + $m = $l; + while ($m < $this->n) { + if (abs($this->e[$m]) <= $eps * $tst1) + break; + ++$m; + } + // If m == l, $this->d[l] is an eigenvalue, + // otherwise, iterate. + if ($m > $l) { + $iter = 0; + do { + // Could check iteration count here. + $iter += 1; + // Compute implicit shift + $g = $this->d[$l]; + $p = ($this->d[$l+1] - $g) / (2.0 * $this->e[$l]); + $r = hypo($p, 1.0); + if ($p < 0) + $r *= -1; + $this->d[$l] = $this->e[$l] / ($p + $r); + $this->d[$l+1] = $this->e[$l] * ($p + $r); + $dl1 = $this->d[$l+1]; + $h = $g - $this->d[$l]; + for ($i = $l + 2; $i < $this->n; ++$i) + $this->d[$i] -= $h; + $f += $h; + // Implicit QL transformation. + $p = $this->d[$m]; + $c = 1.0; + $c2 = $c3 = $c; + $el1 = $this->e[$l + 1]; + $s = $s2 = 0.0; + for ($i = $m-1; $i >= $l; --$i) { + $c3 = $c2; + $c2 = $c; + $s2 = $s; + $g = $c * $this->e[$i]; + $h = $c * $p; + $r = hypo($p, $this->e[$i]); + $this->e[$i+1] = $s * $r; + $s = $this->e[$i] / $r; + $c = $p / $r; + $p = $c * $this->d[$i] - $s * $g; + $this->d[$i+1] = $h + $s * ($c * $g + $s * $this->d[$i]); + // Accumulate transformation. + for ($k = 0; $k < $this->n; ++$k) { + $h = $this->V[$k][$i+1]; + $this->V[$k][$i+1] = $s * $this->V[$k][$i] + $c * $h; + $this->V[$k][$i] = $c * $this->V[$k][$i] - $s * $h; + } + } + $p = -$s * $s2 * $c3 * $el1 * $this->e[$l] / $dl1; + $this->e[$l] = $s * $p; + $this->d[$l] = $c * $p; + // Check for convergence. + } while (abs($this->e[$l]) > $eps * $tst1); + } + $this->d[$l] = $this->d[$l] + $f; + $this->e[$l] = 0.0; + } + + // Sort eigenvalues and corresponding vectors. + for ($i = 0; $i < $this->n - 1; ++$i) { + $k = $i; + $p = $this->d[$i]; + for ($j = $i+1; $j < $this->n; ++$j) { + if ($this->d[$j] < $p) { + $k = $j; + $p = $this->d[$j]; + } + } + if ($k != $i) { + $this->d[$k] = $this->d[$i]; + $this->d[$i] = $p; + for ($j = 0; $j < $this->n; ++$j) { + $p = $this->V[$j][$i]; + $this->V[$j][$i] = $this->V[$j][$k]; + $this->V[$j][$k] = $p; + } + } + } + } + + + /** + * Nonsymmetric reduction to Hessenberg form. + * + * This is derived from the Algol procedures orthes and ortran, + * by Martin and Wilkinson, Handbook for Auto. Comp., + * Vol.ii-Linear Algebra, and the corresponding + * Fortran subroutines in EISPACK. + * + * @access private + */ + private function orthes () { + $low = 0; + $high = $this->n-1; + + for ($m = $low+1; $m <= $high-1; ++$m) { + // Scale column. + $scale = 0.0; + for ($i = $m; $i <= $high; ++$i) { + $scale = $scale + abs($this->H[$i][$m-1]); + } + if ($scale != 0.0) { + // Compute Householder transformation. + $h = 0.0; + for ($i = $high; $i >= $m; --$i) { + $this->ort[$i] = $this->H[$i][$m-1] / $scale; + $h += $this->ort[$i] * $this->ort[$i]; + } + $g = sqrt($h); + if ($this->ort[$m] > 0) { + $g *= -1; + } + $h -= $this->ort[$m] * $g; + $this->ort[$m] -= $g; + // Apply Householder similarity transformation + // H = (I -u * u' / h) * H * (I -u * u') / h) + for ($j = $m; $j < $this->n; ++$j) { + $f = 0.0; + for ($i = $high; $i >= $m; --$i) { + $f += $this->ort[$i] * $this->H[$i][$j]; + } + $f /= $h; + for ($i = $m; $i <= $high; ++$i) { + $this->H[$i][$j] -= $f * $this->ort[$i]; + } + } + for ($i = 0; $i <= $high; ++$i) { + $f = 0.0; + for ($j = $high; $j >= $m; --$j) { + $f += $this->ort[$j] * $this->H[$i][$j]; + } + $f = $f / $h; + for ($j = $m; $j <= $high; ++$j) { + $this->H[$i][$j] -= $f * $this->ort[$j]; + } + } + $this->ort[$m] = $scale * $this->ort[$m]; + $this->H[$m][$m-1] = $scale * $g; + } + } + + // Accumulate transformations (Algol's ortran). + for ($i = 0; $i < $this->n; ++$i) { + for ($j = 0; $j < $this->n; ++$j) { + $this->V[$i][$j] = ($i == $j ? 1.0 : 0.0); + } + } + for ($m = $high-1; $m >= $low+1; --$m) { + if ($this->H[$m][$m-1] != 0.0) { + for ($i = $m+1; $i <= $high; ++$i) { + $this->ort[$i] = $this->H[$i][$m-1]; + } + for ($j = $m; $j <= $high; ++$j) { + $g = 0.0; + for ($i = $m; $i <= $high; ++$i) { + $g += $this->ort[$i] * $this->V[$i][$j]; + } + // Double division avoids possible underflow + $g = ($g / $this->ort[$m]) / $this->H[$m][$m-1]; + for ($i = $m; $i <= $high; ++$i) { + $this->V[$i][$j] += $g * $this->ort[$i]; + } + } + } + } + } + + + /** + * Performs complex division. + * + * @access private + */ + private function cdiv($xr, $xi, $yr, $yi) { + if (abs($yr) > abs($yi)) { + $r = $yi / $yr; + $d = $yr + $r * $yi; + $this->cdivr = ($xr + $r * $xi) / $d; + $this->cdivi = ($xi - $r * $xr) / $d; + } else { + $r = $yr / $yi; + $d = $yi + $r * $yr; + $this->cdivr = ($r * $xr + $xi) / $d; + $this->cdivi = ($r * $xi - $xr) / $d; + } + } + + + /** + * Nonsymmetric reduction from Hessenberg to real Schur form. + * + * Code is derived from the Algol procedure hqr2, + * by Martin and Wilkinson, Handbook for Auto. Comp., + * Vol.ii-Linear Algebra, and the corresponding + * Fortran subroutine in EISPACK. + * + * @access private + */ + private function hqr2 () { + // Initialize + $nn = $this->n; + $n = $nn - 1; + $low = 0; + $high = $nn - 1; + $eps = pow(2.0, -52.0); + $exshift = 0.0; + $p = $q = $r = $s = $z = 0; + // Store roots isolated by balanc and compute matrix norm + $norm = 0.0; + + for ($i = 0; $i < $nn; ++$i) { + if (($i < $low) OR ($i > $high)) { + $this->d[$i] = $this->H[$i][$i]; + $this->e[$i] = 0.0; + } + for ($j = max($i-1, 0); $j < $nn; ++$j) { + $norm = $norm + abs($this->H[$i][$j]); + } + } + + // Outer loop over eigenvalue index + $iter = 0; + while ($n >= $low) { + // Look for single small sub-diagonal element + $l = $n; + while ($l > $low) { + $s = abs($this->H[$l-1][$l-1]) + abs($this->H[$l][$l]); + if ($s == 0.0) { + $s = $norm; + } + if (abs($this->H[$l][$l-1]) < $eps * $s) { + break; + } + --$l; + } + // Check for convergence + // One root found + if ($l == $n) { + $this->H[$n][$n] = $this->H[$n][$n] + $exshift; + $this->d[$n] = $this->H[$n][$n]; + $this->e[$n] = 0.0; + --$n; + $iter = 0; + // Two roots found + } else if ($l == $n-1) { + $w = $this->H[$n][$n-1] * $this->H[$n-1][$n]; + $p = ($this->H[$n-1][$n-1] - $this->H[$n][$n]) / 2.0; + $q = $p * $p + $w; + $z = sqrt(abs($q)); + $this->H[$n][$n] = $this->H[$n][$n] + $exshift; + $this->H[$n-1][$n-1] = $this->H[$n-1][$n-1] + $exshift; + $x = $this->H[$n][$n]; + // Real pair + if ($q >= 0) { + if ($p >= 0) { + $z = $p + $z; + } else { + $z = $p - $z; + } + $this->d[$n-1] = $x + $z; + $this->d[$n] = $this->d[$n-1]; + if ($z != 0.0) { + $this->d[$n] = $x - $w / $z; + } + $this->e[$n-1] = 0.0; + $this->e[$n] = 0.0; + $x = $this->H[$n][$n-1]; + $s = abs($x) + abs($z); + $p = $x / $s; + $q = $z / $s; + $r = sqrt($p * $p + $q * $q); + $p = $p / $r; + $q = $q / $r; + // Row modification + for ($j = $n-1; $j < $nn; ++$j) { + $z = $this->H[$n-1][$j]; + $this->H[$n-1][$j] = $q * $z + $p * $this->H[$n][$j]; + $this->H[$n][$j] = $q * $this->H[$n][$j] - $p * $z; + } + // Column modification + for ($i = 0; $i <= n; ++$i) { + $z = $this->H[$i][$n-1]; + $this->H[$i][$n-1] = $q * $z + $p * $this->H[$i][$n]; + $this->H[$i][$n] = $q * $this->H[$i][$n] - $p * $z; + } + // Accumulate transformations + for ($i = $low; $i <= $high; ++$i) { + $z = $this->V[$i][$n-1]; + $this->V[$i][$n-1] = $q * $z + $p * $this->V[$i][$n]; + $this->V[$i][$n] = $q * $this->V[$i][$n] - $p * $z; + } + // Complex pair + } else { + $this->d[$n-1] = $x + $p; + $this->d[$n] = $x + $p; + $this->e[$n-1] = $z; + $this->e[$n] = -$z; + } + $n = $n - 2; + $iter = 0; + // No convergence yet + } else { + // Form shift + $x = $this->H[$n][$n]; + $y = 0.0; + $w = 0.0; + if ($l < $n) { + $y = $this->H[$n-1][$n-1]; + $w = $this->H[$n][$n-1] * $this->H[$n-1][$n]; + } + // Wilkinson's original ad hoc shift + if ($iter == 10) { + $exshift += $x; + for ($i = $low; $i <= $n; ++$i) { + $this->H[$i][$i] -= $x; + } + $s = abs($this->H[$n][$n-1]) + abs($this->H[$n-1][$n-2]); + $x = $y = 0.75 * $s; + $w = -0.4375 * $s * $s; + } + // MATLAB's new ad hoc shift + if ($iter == 30) { + $s = ($y - $x) / 2.0; + $s = $s * $s + $w; + if ($s > 0) { + $s = sqrt($s); + if ($y < $x) { + $s = -$s; + } + $s = $x - $w / (($y - $x) / 2.0 + $s); + for ($i = $low; $i <= $n; ++$i) { + $this->H[$i][$i] -= $s; + } + $exshift += $s; + $x = $y = $w = 0.964; + } + } + // Could check iteration count here. + $iter = $iter + 1; + // Look for two consecutive small sub-diagonal elements + $m = $n - 2; + while ($m >= $l) { + $z = $this->H[$m][$m]; + $r = $x - $z; + $s = $y - $z; + $p = ($r * $s - $w) / $this->H[$m+1][$m] + $this->H[$m][$m+1]; + $q = $this->H[$m+1][$m+1] - $z - $r - $s; + $r = $this->H[$m+2][$m+1]; + $s = abs($p) + abs($q) + abs($r); + $p = $p / $s; + $q = $q / $s; + $r = $r / $s; + if ($m == $l) { + break; + } + if (abs($this->H[$m][$m-1]) * (abs($q) + abs($r)) < + $eps * (abs($p) * (abs($this->H[$m-1][$m-1]) + abs($z) + abs($this->H[$m+1][$m+1])))) { + break; + } + --$m; + } + for ($i = $m + 2; $i <= $n; ++$i) { + $this->H[$i][$i-2] = 0.0; + if ($i > $m+2) { + $this->H[$i][$i-3] = 0.0; + } + } + // Double QR step involving rows l:n and columns m:n + for ($k = $m; $k <= $n-1; ++$k) { + $notlast = ($k != $n-1); + if ($k != $m) { + $p = $this->H[$k][$k-1]; + $q = $this->H[$k+1][$k-1]; + $r = ($notlast ? $this->H[$k+2][$k-1] : 0.0); + $x = abs($p) + abs($q) + abs($r); + if ($x != 0.0) { + $p = $p / $x; + $q = $q / $x; + $r = $r / $x; + } + } + if ($x == 0.0) { + break; + } + $s = sqrt($p * $p + $q * $q + $r * $r); + if ($p < 0) { + $s = -$s; + } + if ($s != 0) { + if ($k != $m) { + $this->H[$k][$k-1] = -$s * $x; + } elseif ($l != $m) { + $this->H[$k][$k-1] = -$this->H[$k][$k-1]; + } + $p = $p + $s; + $x = $p / $s; + $y = $q / $s; + $z = $r / $s; + $q = $q / $p; + $r = $r / $p; + // Row modification + for ($j = $k; $j < $nn; ++$j) { + $p = $this->H[$k][$j] + $q * $this->H[$k+1][$j]; + if ($notlast) { + $p = $p + $r * $this->H[$k+2][$j]; + $this->H[$k+2][$j] = $this->H[$k+2][$j] - $p * $z; + } + $this->H[$k][$j] = $this->H[$k][$j] - $p * $x; + $this->H[$k+1][$j] = $this->H[$k+1][$j] - $p * $y; + } + // Column modification + for ($i = 0; $i <= min($n, $k+3); ++$i) { + $p = $x * $this->H[$i][$k] + $y * $this->H[$i][$k+1]; + if ($notlast) { + $p = $p + $z * $this->H[$i][$k+2]; + $this->H[$i][$k+2] = $this->H[$i][$k+2] - $p * $r; + } + $this->H[$i][$k] = $this->H[$i][$k] - $p; + $this->H[$i][$k+1] = $this->H[$i][$k+1] - $p * $q; + } + // Accumulate transformations + for ($i = $low; $i <= $high; ++$i) { + $p = $x * $this->V[$i][$k] + $y * $this->V[$i][$k+1]; + if ($notlast) { + $p = $p + $z * $this->V[$i][$k+2]; + $this->V[$i][$k+2] = $this->V[$i][$k+2] - $p * $r; + } + $this->V[$i][$k] = $this->V[$i][$k] - $p; + $this->V[$i][$k+1] = $this->V[$i][$k+1] - $p * $q; + } + } // ($s != 0) + } // k loop + } // check convergence + } // while ($n >= $low) + + // Backsubstitute to find vectors of upper triangular form + if ($norm == 0.0) { + return; + } + + for ($n = $nn-1; $n >= 0; --$n) { + $p = $this->d[$n]; + $q = $this->e[$n]; + // Real vector + if ($q == 0) { + $l = $n; + $this->H[$n][$n] = 1.0; + for ($i = $n-1; $i >= 0; --$i) { + $w = $this->H[$i][$i] - $p; + $r = 0.0; + for ($j = $l; $j <= $n; ++$j) { + $r = $r + $this->H[$i][$j] * $this->H[$j][$n]; + } + if ($this->e[$i] < 0.0) { + $z = $w; + $s = $r; + } else { + $l = $i; + if ($this->e[$i] == 0.0) { + if ($w != 0.0) { + $this->H[$i][$n] = -$r / $w; + } else { + $this->H[$i][$n] = -$r / ($eps * $norm); + } + // Solve real equations + } else { + $x = $this->H[$i][$i+1]; + $y = $this->H[$i+1][$i]; + $q = ($this->d[$i] - $p) * ($this->d[$i] - $p) + $this->e[$i] * $this->e[$i]; + $t = ($x * $s - $z * $r) / $q; + $this->H[$i][$n] = $t; + if (abs($x) > abs($z)) { + $this->H[$i+1][$n] = (-$r - $w * $t) / $x; + } else { + $this->H[$i+1][$n] = (-$s - $y * $t) / $z; + } + } + // Overflow control + $t = abs($this->H[$i][$n]); + if (($eps * $t) * $t > 1) { + for ($j = $i; $j <= $n; ++$j) { + $this->H[$j][$n] = $this->H[$j][$n] / $t; + } + } + } + } + // Complex vector + } else if ($q < 0) { + $l = $n-1; + // Last vector component imaginary so matrix is triangular + if (abs($this->H[$n][$n-1]) > abs($this->H[$n-1][$n])) { + $this->H[$n-1][$n-1] = $q / $this->H[$n][$n-1]; + $this->H[$n-1][$n] = -($this->H[$n][$n] - $p) / $this->H[$n][$n-1]; + } else { + $this->cdiv(0.0, -$this->H[$n-1][$n], $this->H[$n-1][$n-1] - $p, $q); + $this->H[$n-1][$n-1] = $this->cdivr; + $this->H[$n-1][$n] = $this->cdivi; + } + $this->H[$n][$n-1] = 0.0; + $this->H[$n][$n] = 1.0; + for ($i = $n-2; $i >= 0; --$i) { + // double ra,sa,vr,vi; + $ra = 0.0; + $sa = 0.0; + for ($j = $l; $j <= $n; ++$j) { + $ra = $ra + $this->H[$i][$j] * $this->H[$j][$n-1]; + $sa = $sa + $this->H[$i][$j] * $this->H[$j][$n]; + } + $w = $this->H[$i][$i] - $p; + if ($this->e[$i] < 0.0) { + $z = $w; + $r = $ra; + $s = $sa; + } else { + $l = $i; + if ($this->e[$i] == 0) { + $this->cdiv(-$ra, -$sa, $w, $q); + $this->H[$i][$n-1] = $this->cdivr; + $this->H[$i][$n] = $this->cdivi; + } else { + // Solve complex equations + $x = $this->H[$i][$i+1]; + $y = $this->H[$i+1][$i]; + $vr = ($this->d[$i] - $p) * ($this->d[$i] - $p) + $this->e[$i] * $this->e[$i] - $q * $q; + $vi = ($this->d[$i] - $p) * 2.0 * $q; + if ($vr == 0.0 & $vi == 0.0) { + $vr = $eps * $norm * (abs($w) + abs($q) + abs($x) + abs($y) + abs($z)); + } + $this->cdiv($x * $r - $z * $ra + $q * $sa, $x * $s - $z * $sa - $q * $ra, $vr, $vi); + $this->H[$i][$n-1] = $this->cdivr; + $this->H[$i][$n] = $this->cdivi; + if (abs($x) > (abs($z) + abs($q))) { + $this->H[$i+1][$n-1] = (-$ra - $w * $this->H[$i][$n-1] + $q * $this->H[$i][$n]) / $x; + $this->H[$i+1][$n] = (-$sa - $w * $this->H[$i][$n] - $q * $this->H[$i][$n-1]) / $x; + } else { + $this->cdiv(-$r - $y * $this->H[$i][$n-1], -$s - $y * $this->H[$i][$n], $z, $q); + $this->H[$i+1][$n-1] = $this->cdivr; + $this->H[$i+1][$n] = $this->cdivi; + } + } + // Overflow control + $t = max(abs($this->H[$i][$n-1]),abs($this->H[$i][$n])); + if (($eps * $t) * $t > 1) { + for ($j = $i; $j <= $n; ++$j) { + $this->H[$j][$n-1] = $this->H[$j][$n-1] / $t; + $this->H[$j][$n] = $this->H[$j][$n] / $t; + } + } + } // end else + } // end for + } // end else for complex case + } // end for + + // Vectors of isolated roots + for ($i = 0; $i < $nn; ++$i) { + if ($i < $low | $i > $high) { + for ($j = $i; $j < $nn; ++$j) { + $this->V[$i][$j] = $this->H[$i][$j]; + } + } + } + + // Back transformation to get eigenvectors of original matrix + for ($j = $nn-1; $j >= $low; --$j) { + for ($i = $low; $i <= $high; ++$i) { + $z = 0.0; + for ($k = $low; $k <= min($j,$high); ++$k) { + $z = $z + $this->V[$i][$k] * $this->H[$k][$j]; + } + $this->V[$i][$j] = $z; + } + } + } // end hqr2 + + + /** + * Constructor: Check for symmetry, then construct the eigenvalue decomposition + * + * @access public + * @param A Square matrix + * @return Structure to access D and V. + */ + public function __construct($Arg) { + $this->A = $Arg->getArray(); + $this->n = $Arg->getColumnDimension(); + + $issymmetric = true; + for ($j = 0; ($j < $this->n) & $issymmetric; ++$j) { + for ($i = 0; ($i < $this->n) & $issymmetric; ++$i) { + $issymmetric = ($this->A[$i][$j] == $this->A[$j][$i]); + } + } + + if ($issymmetric) { + $this->V = $this->A; + // Tridiagonalize. + $this->tred2(); + // Diagonalize. + $this->tql2(); + } else { + $this->H = $this->A; + $this->ort = array(); + // Reduce to Hessenberg form. + $this->orthes(); + // Reduce Hessenberg to real Schur form. + $this->hqr2(); + } + } + + + /** + * Return the eigenvector matrix + * + * @access public + * @return V + */ + public function getV() { + return new Matrix($this->V, $this->n, $this->n); + } + + + /** + * Return the real parts of the eigenvalues + * + * @access public + * @return real(diag(D)) + */ + public function getRealEigenvalues() { + return $this->d; + } + + + /** + * Return the imaginary parts of the eigenvalues + * + * @access public + * @return imag(diag(D)) + */ + public function getImagEigenvalues() { + return $this->e; + } + + + /** + * Return the block diagonal eigenvalue matrix + * + * @access public + * @return D + */ + public function getD() { + for ($i = 0; $i < $this->n; ++$i) { + $D[$i] = array_fill(0, $this->n, 0.0); + $D[$i][$i] = $this->d[$i]; + if ($this->e[$i] == 0) { + continue; + } + $o = ($this->e[$i] > 0) ? $i + 1 : $i - 1; + $D[$i][$o] = $this->e[$i]; + } + return new Matrix($D); + } + +} // class EigenvalueDecomposition diff --git a/lib/phpexcel/PHPExcel/Shared/JAMA/LUDecomposition.php b/lib/phpexcel/PHPExcel/Shared/JAMA/LUDecomposition.php new file mode 100644 index 0000000..08e500c --- /dev/null +++ b/lib/phpexcel/PHPExcel/Shared/JAMA/LUDecomposition.php @@ -0,0 +1,258 @@ +<?php +/** + * @package JAMA + * + * For an m-by-n matrix A with m >= n, the LU decomposition is an m-by-n + * unit lower triangular matrix L, an n-by-n upper triangular matrix U, + * and a permutation vector piv of length m so that A(piv,:) = L*U. + * If m < n, then L is m-by-m and U is m-by-n. + * + * The LU decompostion with pivoting always exists, even if the matrix is + * singular, so the constructor will never fail. The primary use of the + * LU decomposition is in the solution of square systems of simultaneous + * linear equations. This will fail if isNonsingular() returns false. + * + * @author Paul Meagher + * @author Bartosz Matosiuk + * @author Michael Bommarito + * @version 1.1 + * @license PHP v3.0 + */ +class PHPExcel_Shared_JAMA_LUDecomposition { + + const MatrixSingularException = "Can only perform operation on singular matrix."; + const MatrixSquareException = "Mismatched Row dimension"; + + /** + * Decomposition storage + * @var array + */ + private $LU = array(); + + /** + * Row dimension. + * @var int + */ + private $m; + + /** + * Column dimension. + * @var int + */ + private $n; + + /** + * Pivot sign. + * @var int + */ + private $pivsign; + + /** + * Internal storage of pivot vector. + * @var array + */ + private $piv = array(); + + + /** + * LU Decomposition constructor. + * + * @param $A Rectangular matrix + * @return Structure to access L, U and piv. + */ + public function __construct($A) { + if ($A instanceof PHPExcel_Shared_JAMA_Matrix) { + // Use a "left-looking", dot-product, Crout/Doolittle algorithm. + $this->LU = $A->getArray(); + $this->m = $A->getRowDimension(); + $this->n = $A->getColumnDimension(); + for ($i = 0; $i < $this->m; ++$i) { + $this->piv[$i] = $i; + } + $this->pivsign = 1; + $LUrowi = $LUcolj = array(); + + // Outer loop. + for ($j = 0; $j < $this->n; ++$j) { + // Make a copy of the j-th column to localize references. + for ($i = 0; $i < $this->m; ++$i) { + $LUcolj[$i] = &$this->LU[$i][$j]; + } + // Apply previous transformations. + for ($i = 0; $i < $this->m; ++$i) { + $LUrowi = $this->LU[$i]; + // Most of the time is spent in the following dot product. + $kmax = min($i,$j); + $s = 0.0; + for ($k = 0; $k < $kmax; ++$k) { + $s += $LUrowi[$k] * $LUcolj[$k]; + } + $LUrowi[$j] = $LUcolj[$i] -= $s; + } + // Find pivot and exchange if necessary. + $p = $j; + for ($i = $j+1; $i < $this->m; ++$i) { + if (abs($LUcolj[$i]) > abs($LUcolj[$p])) { + $p = $i; + } + } + if ($p != $j) { + for ($k = 0; $k < $this->n; ++$k) { + $t = $this->LU[$p][$k]; + $this->LU[$p][$k] = $this->LU[$j][$k]; + $this->LU[$j][$k] = $t; + } + $k = $this->piv[$p]; + $this->piv[$p] = $this->piv[$j]; + $this->piv[$j] = $k; + $this->pivsign = $this->pivsign * -1; + } + // Compute multipliers. + if (($j < $this->m) && ($this->LU[$j][$j] != 0.0)) { + for ($i = $j+1; $i < $this->m; ++$i) { + $this->LU[$i][$j] /= $this->LU[$j][$j]; + } + } + } + } else { + throw new PHPExcel_Calculation_Exception(PHPExcel_Shared_JAMA_Matrix::ArgumentTypeException); + } + } // function __construct() + + + /** + * Get lower triangular factor. + * + * @return array Lower triangular factor + */ + public function getL() { + for ($i = 0; $i < $this->m; ++$i) { + for ($j = 0; $j < $this->n; ++$j) { + if ($i > $j) { + $L[$i][$j] = $this->LU[$i][$j]; + } elseif ($i == $j) { + $L[$i][$j] = 1.0; + } else { + $L[$i][$j] = 0.0; + } + } + } + return new PHPExcel_Shared_JAMA_Matrix($L); + } // function getL() + + + /** + * Get upper triangular factor. + * + * @return array Upper triangular factor + */ + public function getU() { + for ($i = 0; $i < $this->n; ++$i) { + for ($j = 0; $j < $this->n; ++$j) { + if ($i <= $j) { + $U[$i][$j] = $this->LU[$i][$j]; + } else { + $U[$i][$j] = 0.0; + } + } + } + return new PHPExcel_Shared_JAMA_Matrix($U); + } // function getU() + + + /** + * Return pivot permutation vector. + * + * @return array Pivot vector + */ + public function getPivot() { + return $this->piv; + } // function getPivot() + + + /** + * Alias for getPivot + * + * @see getPivot + */ + public function getDoublePivot() { + return $this->getPivot(); + } // function getDoublePivot() + + + /** + * Is the matrix nonsingular? + * + * @return true if U, and hence A, is nonsingular. + */ + public function isNonsingular() { + for ($j = 0; $j < $this->n; ++$j) { + if ($this->LU[$j][$j] == 0) { + return false; + } + } + return true; + } // function isNonsingular() + + + /** + * Count determinants + * + * @return array d matrix deterninat + */ + public function det() { + if ($this->m == $this->n) { + $d = $this->pivsign; + for ($j = 0; $j < $this->n; ++$j) { + $d *= $this->LU[$j][$j]; + } + return $d; + } else { + throw new PHPExcel_Calculation_Exception(PHPExcel_Shared_JAMA_Matrix::MatrixDimensionException); + } + } // function det() + + + /** + * Solve A*X = B + * + * @param $B A Matrix with as many rows as A and any number of columns. + * @return X so that L*U*X = B(piv,:) + * @PHPExcel_Calculation_Exception IllegalArgumentException Matrix row dimensions must agree. + * @PHPExcel_Calculation_Exception RuntimeException Matrix is singular. + */ + public function solve($B) { + if ($B->getRowDimension() == $this->m) { + if ($this->isNonsingular()) { + // Copy right hand side with pivoting + $nx = $B->getColumnDimension(); + $X = $B->getMatrix($this->piv, 0, $nx-1); + // Solve L*Y = B(piv,:) + for ($k = 0; $k < $this->n; ++$k) { + for ($i = $k+1; $i < $this->n; ++$i) { + for ($j = 0; $j < $nx; ++$j) { + $X->A[$i][$j] -= $X->A[$k][$j] * $this->LU[$i][$k]; + } + } + } + // Solve U*X = Y; + for ($k = $this->n-1; $k >= 0; --$k) { + for ($j = 0; $j < $nx; ++$j) { + $X->A[$k][$j] /= $this->LU[$k][$k]; + } + for ($i = 0; $i < $k; ++$i) { + for ($j = 0; $j < $nx; ++$j) { + $X->A[$i][$j] -= $X->A[$k][$j] * $this->LU[$i][$k]; + } + } + } + return $X; + } else { + throw new PHPExcel_Calculation_Exception(self::MatrixSingularException); + } + } else { + throw new PHPExcel_Calculation_Exception(self::MatrixSquareException); + } + } // function solve() + +} // class PHPExcel_Shared_JAMA_LUDecomposition diff --git a/lib/phpexcel/PHPExcel/Shared/JAMA/Matrix.php b/lib/phpexcel/PHPExcel/Shared/JAMA/Matrix.php new file mode 100644 index 0000000..b893a44 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Shared/JAMA/Matrix.php @@ -0,0 +1,1059 @@ +<?php +/** + * @package JAMA + */ + +/** PHPExcel root directory */ +if (!defined('PHPEXCEL_ROOT')) { + /** + * @ignore + */ + define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../../'); + require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); +} + + +/* + * Matrix class + * + * @author Paul Meagher + * @author Michael Bommarito + * @author Lukasz Karapuda + * @author Bartek Matosiuk + * @version 1.8 + * @license PHP v3.0 + * @see http://math.nist.gov/javanumerics/jama/ + */ +class PHPExcel_Shared_JAMA_Matrix { + + + const PolymorphicArgumentException = "Invalid argument pattern for polymorphic function."; + const ArgumentTypeException = "Invalid argument type."; + const ArgumentBoundsException = "Invalid argument range."; + const MatrixDimensionException = "Matrix dimensions are not equal."; + const ArrayLengthException = "Array length must be a multiple of m."; + + /** + * Matrix storage + * + * @var array + * @access public + */ + public $A = array(); + + /** + * Matrix row dimension + * + * @var int + * @access private + */ + private $m; + + /** + * Matrix column dimension + * + * @var int + * @access private + */ + private $n; + + + /** + * Polymorphic constructor + * + * As PHP has no support for polymorphic constructors, we hack our own sort of polymorphism using func_num_args, func_get_arg, and gettype. In essence, we're just implementing a simple RTTI filter and calling the appropriate constructor. + */ + public function __construct() { + if (func_num_args() > 0) { + $args = func_get_args(); + $match = implode(",", array_map('gettype', $args)); + + switch($match) { + //Rectangular matrix - m x n initialized from 2D array + case 'array': + $this->m = count($args[0]); + $this->n = count($args[0][0]); + $this->A = $args[0]; + break; + //Square matrix - n x n + case 'integer': + $this->m = $args[0]; + $this->n = $args[0]; + $this->A = array_fill(0, $this->m, array_fill(0, $this->n, 0)); + break; + //Rectangular matrix - m x n + case 'integer,integer': + $this->m = $args[0]; + $this->n = $args[1]; + $this->A = array_fill(0, $this->m, array_fill(0, $this->n, 0)); + break; + //Rectangular matrix - m x n initialized from packed array + case 'array,integer': + $this->m = $args[1]; + if ($this->m != 0) { + $this->n = count($args[0]) / $this->m; + } else { + $this->n = 0; + } + if (($this->m * $this->n) == count($args[0])) { + for($i = 0; $i < $this->m; ++$i) { + for($j = 0; $j < $this->n; ++$j) { + $this->A[$i][$j] = $args[0][$i + $j * $this->m]; + } + } + } else { + throw new PHPExcel_Calculation_Exception(self::ArrayLengthException); + } + break; + default: + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; + } + } else { + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + } + } // function __construct() + + + /** + * getArray + * + * @return array Matrix array + */ + public function getArray() { + return $this->A; + } // function getArray() + + + /** + * getRowDimension + * + * @return int Row dimension + */ + public function getRowDimension() { + return $this->m; + } // function getRowDimension() + + + /** + * getColumnDimension + * + * @return int Column dimension + */ + public function getColumnDimension() { + return $this->n; + } // function getColumnDimension() + + + /** + * get + * + * Get the i,j-th element of the matrix. + * @param int $i Row position + * @param int $j Column position + * @return mixed Element (int/float/double) + */ + public function get($i = null, $j = null) { + return $this->A[$i][$j]; + } // function get() + + + /** + * getMatrix + * + * Get a submatrix + * @param int $i0 Initial row index + * @param int $iF Final row index + * @param int $j0 Initial column index + * @param int $jF Final column index + * @return Matrix Submatrix + */ + public function getMatrix() { + if (func_num_args() > 0) { + $args = func_get_args(); + $match = implode(",", array_map('gettype', $args)); + + switch($match) { + //A($i0...; $j0...) + case 'integer,integer': + list($i0, $j0) = $args; + if ($i0 >= 0) { $m = $this->m - $i0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + if ($j0 >= 0) { $n = $this->n - $j0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + $R = new PHPExcel_Shared_JAMA_Matrix($m, $n); + for($i = $i0; $i < $this->m; ++$i) { + for($j = $j0; $j < $this->n; ++$j) { + $R->set($i, $j, $this->A[$i][$j]); + } + } + return $R; + break; + //A($i0...$iF; $j0...$jF) + case 'integer,integer,integer,integer': + list($i0, $iF, $j0, $jF) = $args; + if (($iF > $i0) && ($this->m >= $iF) && ($i0 >= 0)) { $m = $iF - $i0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + if (($jF > $j0) && ($this->n >= $jF) && ($j0 >= 0)) { $n = $jF - $j0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + $R = new PHPExcel_Shared_JAMA_Matrix($m+1, $n+1); + for($i = $i0; $i <= $iF; ++$i) { + for($j = $j0; $j <= $jF; ++$j) { + $R->set($i - $i0, $j - $j0, $this->A[$i][$j]); + } + } + return $R; + break; + //$R = array of row indices; $C = array of column indices + case 'array,array': + list($RL, $CL) = $args; + if (count($RL) > 0) { $m = count($RL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + if (count($CL) > 0) { $n = count($CL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + $R = new PHPExcel_Shared_JAMA_Matrix($m, $n); + for($i = 0; $i < $m; ++$i) { + for($j = 0; $j < $n; ++$j) { + $R->set($i - $i0, $j - $j0, $this->A[$RL[$i]][$CL[$j]]); + } + } + return $R; + break; + //$RL = array of row indices; $CL = array of column indices + case 'array,array': + list($RL, $CL) = $args; + if (count($RL) > 0) { $m = count($RL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + if (count($CL) > 0) { $n = count($CL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + $R = new PHPExcel_Shared_JAMA_Matrix($m, $n); + for($i = 0; $i < $m; ++$i) { + for($j = 0; $j < $n; ++$j) { + $R->set($i, $j, $this->A[$RL[$i]][$CL[$j]]); + } + } + return $R; + break; + //A($i0...$iF); $CL = array of column indices + case 'integer,integer,array': + list($i0, $iF, $CL) = $args; + if (($iF > $i0) && ($this->m >= $iF) && ($i0 >= 0)) { $m = $iF - $i0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + if (count($CL) > 0) { $n = count($CL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + $R = new PHPExcel_Shared_JAMA_Matrix($m, $n); + for($i = $i0; $i < $iF; ++$i) { + for($j = 0; $j < $n; ++$j) { + $R->set($i - $i0, $j, $this->A[$RL[$i]][$j]); + } + } + return $R; + break; + //$RL = array of row indices + case 'array,integer,integer': + list($RL, $j0, $jF) = $args; + if (count($RL) > 0) { $m = count($RL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + if (($jF >= $j0) && ($this->n >= $jF) && ($j0 >= 0)) { $n = $jF - $j0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + $R = new PHPExcel_Shared_JAMA_Matrix($m, $n+1); + for($i = 0; $i < $m; ++$i) { + for($j = $j0; $j <= $jF; ++$j) { + $R->set($i, $j - $j0, $this->A[$RL[$i]][$j]); + } + } + return $R; + break; + default: + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; + } + } else { + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + } + } // function getMatrix() + + + /** + * checkMatrixDimensions + * + * Is matrix B the same size? + * @param Matrix $B Matrix B + * @return boolean + */ + public function checkMatrixDimensions($B = null) { + if ($B instanceof PHPExcel_Shared_JAMA_Matrix) { + if (($this->m == $B->getRowDimension()) && ($this->n == $B->getColumnDimension())) { + return true; + } else { + throw new PHPExcel_Calculation_Exception(self::MatrixDimensionException); + } + } else { + throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); + } + } // function checkMatrixDimensions() + + + + /** + * set + * + * Set the i,j-th element of the matrix. + * @param int $i Row position + * @param int $j Column position + * @param mixed $c Int/float/double value + * @return mixed Element (int/float/double) + */ + public function set($i = null, $j = null, $c = null) { + // Optimized set version just has this + $this->A[$i][$j] = $c; + } // function set() + + + /** + * identity + * + * Generate an identity matrix. + * @param int $m Row dimension + * @param int $n Column dimension + * @return Matrix Identity matrix + */ + public function identity($m = null, $n = null) { + return $this->diagonal($m, $n, 1); + } // function identity() + + + /** + * diagonal + * + * Generate a diagonal matrix + * @param int $m Row dimension + * @param int $n Column dimension + * @param mixed $c Diagonal value + * @return Matrix Diagonal matrix + */ + public function diagonal($m = null, $n = null, $c = 1) { + $R = new PHPExcel_Shared_JAMA_Matrix($m, $n); + for($i = 0; $i < $m; ++$i) { + $R->set($i, $i, $c); + } + return $R; + } // function diagonal() + + + /** + * getMatrixByRow + * + * Get a submatrix by row index/range + * @param int $i0 Initial row index + * @param int $iF Final row index + * @return Matrix Submatrix + */ + public function getMatrixByRow($i0 = null, $iF = null) { + if (is_int($i0)) { + if (is_int($iF)) { + return $this->getMatrix($i0, 0, $iF + 1, $this->n); + } else { + return $this->getMatrix($i0, 0, $i0 + 1, $this->n); + } + } else { + throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); + } + } // function getMatrixByRow() + + + /** + * getMatrixByCol + * + * Get a submatrix by column index/range + * @param int $i0 Initial column index + * @param int $iF Final column index + * @return Matrix Submatrix + */ + public function getMatrixByCol($j0 = null, $jF = null) { + if (is_int($j0)) { + if (is_int($jF)) { + return $this->getMatrix(0, $j0, $this->m, $jF + 1); + } else { + return $this->getMatrix(0, $j0, $this->m, $j0 + 1); + } + } else { + throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); + } + } // function getMatrixByCol() + + + /** + * transpose + * + * Tranpose matrix + * @return Matrix Transposed matrix + */ + public function transpose() { + $R = new PHPExcel_Shared_JAMA_Matrix($this->n, $this->m); + for($i = 0; $i < $this->m; ++$i) { + for($j = 0; $j < $this->n; ++$j) { + $R->set($j, $i, $this->A[$i][$j]); + } + } + return $R; + } // function transpose() + + + /** + * trace + * + * Sum of diagonal elements + * @return float Sum of diagonal elements + */ + public function trace() { + $s = 0; + $n = min($this->m, $this->n); + for($i = 0; $i < $n; ++$i) { + $s += $this->A[$i][$i]; + } + return $s; + } // function trace() + + + /** + * uminus + * + * Unary minus matrix -A + * @return Matrix Unary minus matrix + */ + public function uminus() { + } // function uminus() + + + /** + * plus + * + * A + B + * @param mixed $B Matrix/Array + * @return Matrix Sum + */ + public function plus() { + if (func_num_args() > 0) { + $args = func_get_args(); + $match = implode(",", array_map('gettype', $args)); + + switch($match) { + case 'object': + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } + break; + case 'array': + $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); + break; + default: + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; + } + $this->checkMatrixDimensions($M); + for($i = 0; $i < $this->m; ++$i) { + for($j = 0; $j < $this->n; ++$j) { + $M->set($i, $j, $M->get($i, $j) + $this->A[$i][$j]); + } + } + return $M; + } else { + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + } + } // function plus() + + + /** + * plusEquals + * + * A = A + B + * @param mixed $B Matrix/Array + * @return Matrix Sum + */ + public function plusEquals() { + if (func_num_args() > 0) { + $args = func_get_args(); + $match = implode(",", array_map('gettype', $args)); + + switch($match) { + case 'object': + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } + break; + case 'array': + $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); + break; + default: + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; + } + $this->checkMatrixDimensions($M); + for($i = 0; $i < $this->m; ++$i) { + for($j = 0; $j < $this->n; ++$j) { + $validValues = True; + $value = $M->get($i, $j); + if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) { + $this->A[$i][$j] = trim($this->A[$i][$j],'"'); + $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($this->A[$i][$j]); + } + if ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) { + $value = trim($value,'"'); + $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($value); + } + if ($validValues) { + $this->A[$i][$j] += $value; + } else { + $this->A[$i][$j] = PHPExcel_Calculation_Functions::NaN(); + } + } + } + return $this; + } else { + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + } + } // function plusEquals() + + + /** + * minus + * + * A - B + * @param mixed $B Matrix/Array + * @return Matrix Sum + */ + public function minus() { + if (func_num_args() > 0) { + $args = func_get_args(); + $match = implode(",", array_map('gettype', $args)); + + switch($match) { + case 'object': + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } + break; + case 'array': + $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); + break; + default: + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; + } + $this->checkMatrixDimensions($M); + for($i = 0; $i < $this->m; ++$i) { + for($j = 0; $j < $this->n; ++$j) { + $M->set($i, $j, $M->get($i, $j) - $this->A[$i][$j]); + } + } + return $M; + } else { + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + } + } // function minus() + + + /** + * minusEquals + * + * A = A - B + * @param mixed $B Matrix/Array + * @return Matrix Sum + */ + public function minusEquals() { + if (func_num_args() > 0) { + $args = func_get_args(); + $match = implode(",", array_map('gettype', $args)); + + switch($match) { + case 'object': + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } + break; + case 'array': + $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); + break; + default: + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; + } + $this->checkMatrixDimensions($M); + for($i = 0; $i < $this->m; ++$i) { + for($j = 0; $j < $this->n; ++$j) { + $validValues = True; + $value = $M->get($i, $j); + if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) { + $this->A[$i][$j] = trim($this->A[$i][$j],'"'); + $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($this->A[$i][$j]); + } + if ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) { + $value = trim($value,'"'); + $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($value); + } + if ($validValues) { + $this->A[$i][$j] -= $value; + } else { + $this->A[$i][$j] = PHPExcel_Calculation_Functions::NaN(); + } + } + } + return $this; + } else { + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + } + } // function minusEquals() + + + /** + * arrayTimes + * + * Element-by-element multiplication + * Cij = Aij * Bij + * @param mixed $B Matrix/Array + * @return Matrix Matrix Cij + */ + public function arrayTimes() { + if (func_num_args() > 0) { + $args = func_get_args(); + $match = implode(",", array_map('gettype', $args)); + + switch($match) { + case 'object': + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } + break; + case 'array': + $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); + break; + default: + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; + } + $this->checkMatrixDimensions($M); + for($i = 0; $i < $this->m; ++$i) { + for($j = 0; $j < $this->n; ++$j) { + $M->set($i, $j, $M->get($i, $j) * $this->A[$i][$j]); + } + } + return $M; + } else { + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + } + } // function arrayTimes() + + + /** + * arrayTimesEquals + * + * Element-by-element multiplication + * Aij = Aij * Bij + * @param mixed $B Matrix/Array + * @return Matrix Matrix Aij + */ + public function arrayTimesEquals() { + if (func_num_args() > 0) { + $args = func_get_args(); + $match = implode(",", array_map('gettype', $args)); + + switch($match) { + case 'object': + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } + break; + case 'array': + $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); + break; + default: + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; + } + $this->checkMatrixDimensions($M); + for($i = 0; $i < $this->m; ++$i) { + for($j = 0; $j < $this->n; ++$j) { + $validValues = True; + $value = $M->get($i, $j); + if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) { + $this->A[$i][$j] = trim($this->A[$i][$j],'"'); + $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($this->A[$i][$j]); + } + if ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) { + $value = trim($value,'"'); + $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($value); + } + if ($validValues) { + $this->A[$i][$j] *= $value; + } else { + $this->A[$i][$j] = PHPExcel_Calculation_Functions::NaN(); + } + } + } + return $this; + } else { + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + } + } // function arrayTimesEquals() + + + /** + * arrayRightDivide + * + * Element-by-element right division + * A / B + * @param Matrix $B Matrix B + * @return Matrix Division result + */ + public function arrayRightDivide() { + if (func_num_args() > 0) { + $args = func_get_args(); + $match = implode(",", array_map('gettype', $args)); + + switch($match) { + case 'object': + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } + break; + case 'array': + $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); + break; + default: + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; + } + $this->checkMatrixDimensions($M); + for($i = 0; $i < $this->m; ++$i) { + for($j = 0; $j < $this->n; ++$j) { + $validValues = True; + $value = $M->get($i, $j); + if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) { + $this->A[$i][$j] = trim($this->A[$i][$j],'"'); + $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($this->A[$i][$j]); + } + if ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) { + $value = trim($value,'"'); + $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($value); + } + if ($validValues) { + if ($value == 0) { + // Trap for Divide by Zero error + $M->set($i, $j, '#DIV/0!'); + } else { + $M->set($i, $j, $this->A[$i][$j] / $value); + } + } else { + $M->set($i, $j, PHPExcel_Calculation_Functions::NaN()); + } + } + } + return $M; + } else { + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + } + } // function arrayRightDivide() + + + /** + * arrayRightDivideEquals + * + * Element-by-element right division + * Aij = Aij / Bij + * @param mixed $B Matrix/Array + * @return Matrix Matrix Aij + */ + public function arrayRightDivideEquals() { + if (func_num_args() > 0) { + $args = func_get_args(); + $match = implode(",", array_map('gettype', $args)); + + switch($match) { + case 'object': + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } + break; + case 'array': + $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); + break; + default: + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; + } + $this->checkMatrixDimensions($M); + for($i = 0; $i < $this->m; ++$i) { + for($j = 0; $j < $this->n; ++$j) { + $this->A[$i][$j] = $this->A[$i][$j] / $M->get($i, $j); + } + } + return $M; + } else { + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + } + } // function arrayRightDivideEquals() + + + /** + * arrayLeftDivide + * + * Element-by-element Left division + * A / B + * @param Matrix $B Matrix B + * @return Matrix Division result + */ + public function arrayLeftDivide() { + if (func_num_args() > 0) { + $args = func_get_args(); + $match = implode(",", array_map('gettype', $args)); + + switch($match) { + case 'object': + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } + break; + case 'array': + $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); + break; + default: + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; + } + $this->checkMatrixDimensions($M); + for($i = 0; $i < $this->m; ++$i) { + for($j = 0; $j < $this->n; ++$j) { + $M->set($i, $j, $M->get($i, $j) / $this->A[$i][$j]); + } + } + return $M; + } else { + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + } + } // function arrayLeftDivide() + + + /** + * arrayLeftDivideEquals + * + * Element-by-element Left division + * Aij = Aij / Bij + * @param mixed $B Matrix/Array + * @return Matrix Matrix Aij + */ + public function arrayLeftDivideEquals() { + if (func_num_args() > 0) { + $args = func_get_args(); + $match = implode(",", array_map('gettype', $args)); + + switch($match) { + case 'object': + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } + break; + case 'array': + $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); + break; + default: + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; + } + $this->checkMatrixDimensions($M); + for($i = 0; $i < $this->m; ++$i) { + for($j = 0; $j < $this->n; ++$j) { + $this->A[$i][$j] = $M->get($i, $j) / $this->A[$i][$j]; + } + } + return $M; + } else { + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + } + } // function arrayLeftDivideEquals() + + + /** + * times + * + * Matrix multiplication + * @param mixed $n Matrix/Array/Scalar + * @return Matrix Product + */ + public function times() { + if (func_num_args() > 0) { + $args = func_get_args(); + $match = implode(",", array_map('gettype', $args)); + + switch($match) { + case 'object': + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $B = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } + if ($this->n == $B->m) { + $C = new PHPExcel_Shared_JAMA_Matrix($this->m, $B->n); + for($j = 0; $j < $B->n; ++$j) { + for ($k = 0; $k < $this->n; ++$k) { + $Bcolj[$k] = $B->A[$k][$j]; + } + for($i = 0; $i < $this->m; ++$i) { + $Arowi = $this->A[$i]; + $s = 0; + for($k = 0; $k < $this->n; ++$k) { + $s += $Arowi[$k] * $Bcolj[$k]; + } + $C->A[$i][$j] = $s; + } + } + return $C; + } else { + throw new PHPExcel_Calculation_Exception(JAMAError(MatrixDimensionMismatch)); + } + break; + case 'array': + $B = new PHPExcel_Shared_JAMA_Matrix($args[0]); + if ($this->n == $B->m) { + $C = new PHPExcel_Shared_JAMA_Matrix($this->m, $B->n); + for($i = 0; $i < $C->m; ++$i) { + for($j = 0; $j < $C->n; ++$j) { + $s = "0"; + for($k = 0; $k < $C->n; ++$k) { + $s += $this->A[$i][$k] * $B->A[$k][$j]; + } + $C->A[$i][$j] = $s; + } + } + return $C; + } else { + throw new PHPExcel_Calculation_Exception(JAMAError(MatrixDimensionMismatch)); + } + return $M; + break; + case 'integer': + $C = new PHPExcel_Shared_JAMA_Matrix($this->A); + for($i = 0; $i < $C->m; ++$i) { + for($j = 0; $j < $C->n; ++$j) { + $C->A[$i][$j] *= $args[0]; + } + } + return $C; + break; + case 'double': + $C = new PHPExcel_Shared_JAMA_Matrix($this->m, $this->n); + for($i = 0; $i < $C->m; ++$i) { + for($j = 0; $j < $C->n; ++$j) { + $C->A[$i][$j] = $args[0] * $this->A[$i][$j]; + } + } + return $C; + break; + case 'float': + $C = new PHPExcel_Shared_JAMA_Matrix($this->A); + for($i = 0; $i < $C->m; ++$i) { + for($j = 0; $j < $C->n; ++$j) { + $C->A[$i][$j] *= $args[0]; + } + } + return $C; + break; + default: + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; + } + } else { + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + } + } // function times() + + + /** + * power + * + * A = A ^ B + * @param mixed $B Matrix/Array + * @return Matrix Sum + */ + public function power() { + if (func_num_args() > 0) { + $args = func_get_args(); + $match = implode(",", array_map('gettype', $args)); + + switch($match) { + case 'object': + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } + break; + case 'array': + $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); + break; + default: + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; + } + $this->checkMatrixDimensions($M); + for($i = 0; $i < $this->m; ++$i) { + for($j = 0; $j < $this->n; ++$j) { + $validValues = True; + $value = $M->get($i, $j); + if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) { + $this->A[$i][$j] = trim($this->A[$i][$j],'"'); + $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($this->A[$i][$j]); + } + if ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) { + $value = trim($value,'"'); + $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($value); + } + if ($validValues) { + $this->A[$i][$j] = pow($this->A[$i][$j],$value); + } else { + $this->A[$i][$j] = PHPExcel_Calculation_Functions::NaN(); + } + } + } + return $this; + } else { + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + } + } // function power() + + + /** + * concat + * + * A = A & B + * @param mixed $B Matrix/Array + * @return Matrix Sum + */ + public function concat() { + if (func_num_args() > 0) { + $args = func_get_args(); + $match = implode(",", array_map('gettype', $args)); + + switch($match) { + case 'object': + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } + case 'array': + $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); + break; + default: + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; + } + $this->checkMatrixDimensions($M); + for($i = 0; $i < $this->m; ++$i) { + for($j = 0; $j < $this->n; ++$j) { + $this->A[$i][$j] = trim($this->A[$i][$j],'"').trim($M->get($i, $j),'"'); + } + } + return $this; + } else { + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + } + } // function concat() + + + /** + * Solve A*X = B. + * + * @param Matrix $B Right hand side + * @return Matrix ... Solution if A is square, least squares solution otherwise + */ + public function solve($B) { + if ($this->m == $this->n) { + $LU = new PHPExcel_Shared_JAMA_LUDecomposition($this); + return $LU->solve($B); + } else { + $QR = new QRDecomposition($this); + return $QR->solve($B); + } + } // function solve() + + + /** + * Matrix inverse or pseudoinverse. + * + * @return Matrix ... Inverse(A) if A is square, pseudoinverse otherwise. + */ + public function inverse() { + return $this->solve($this->identity($this->m, $this->m)); + } // function inverse() + + + /** + * det + * + * Calculate determinant + * @return float Determinant + */ + public function det() { + $L = new PHPExcel_Shared_JAMA_LUDecomposition($this); + return $L->det(); + } // function det() + + +} // class PHPExcel_Shared_JAMA_Matrix diff --git a/lib/phpexcel/PHPExcel/Shared/JAMA/QRDecomposition.php b/lib/phpexcel/PHPExcel/Shared/JAMA/QRDecomposition.php new file mode 100644 index 0000000..7538462 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Shared/JAMA/QRDecomposition.php @@ -0,0 +1,234 @@ +<?php +/** + * @package JAMA + * + * For an m-by-n matrix A with m >= n, the QR decomposition is an m-by-n + * orthogonal matrix Q and an n-by-n upper triangular matrix R so that + * A = Q*R. + * + * The QR decompostion always exists, even if the matrix does not have + * full rank, so the constructor will never fail. The primary use of the + * QR decomposition is in the least squares solution of nonsquare systems + * of simultaneous linear equations. This will fail if isFullRank() + * returns false. + * + * @author Paul Meagher + * @license PHP v3.0 + * @version 1.1 + */ +class PHPExcel_Shared_JAMA_QRDecomposition { + + const MatrixRankException = "Can only perform operation on full-rank matrix."; + + /** + * Array for internal storage of decomposition. + * @var array + */ + private $QR = array(); + + /** + * Row dimension. + * @var integer + */ + private $m; + + /** + * Column dimension. + * @var integer + */ + private $n; + + /** + * Array for internal storage of diagonal of R. + * @var array + */ + private $Rdiag = array(); + + + /** + * QR Decomposition computed by Householder reflections. + * + * @param matrix $A Rectangular matrix + * @return Structure to access R and the Householder vectors and compute Q. + */ + public function __construct($A) { + if($A instanceof PHPExcel_Shared_JAMA_Matrix) { + // Initialize. + $this->QR = $A->getArrayCopy(); + $this->m = $A->getRowDimension(); + $this->n = $A->getColumnDimension(); + // Main loop. + for ($k = 0; $k < $this->n; ++$k) { + // Compute 2-norm of k-th column without under/overflow. + $nrm = 0.0; + for ($i = $k; $i < $this->m; ++$i) { + $nrm = hypo($nrm, $this->QR[$i][$k]); + } + if ($nrm != 0.0) { + // Form k-th Householder vector. + if ($this->QR[$k][$k] < 0) { + $nrm = -$nrm; + } + for ($i = $k; $i < $this->m; ++$i) { + $this->QR[$i][$k] /= $nrm; + } + $this->QR[$k][$k] += 1.0; + // Apply transformation to remaining columns. + for ($j = $k+1; $j < $this->n; ++$j) { + $s = 0.0; + for ($i = $k; $i < $this->m; ++$i) { + $s += $this->QR[$i][$k] * $this->QR[$i][$j]; + } + $s = -$s/$this->QR[$k][$k]; + for ($i = $k; $i < $this->m; ++$i) { + $this->QR[$i][$j] += $s * $this->QR[$i][$k]; + } + } + } + $this->Rdiag[$k] = -$nrm; + } + } else { + throw new PHPExcel_Calculation_Exception(PHPExcel_Shared_JAMA_Matrix::ArgumentTypeException); + } + } // function __construct() + + + /** + * Is the matrix full rank? + * + * @return boolean true if R, and hence A, has full rank, else false. + */ + public function isFullRank() { + for ($j = 0; $j < $this->n; ++$j) { + if ($this->Rdiag[$j] == 0) { + return false; + } + } + return true; + } // function isFullRank() + + + /** + * Return the Householder vectors + * + * @return Matrix Lower trapezoidal matrix whose columns define the reflections + */ + public function getH() { + for ($i = 0; $i < $this->m; ++$i) { + for ($j = 0; $j < $this->n; ++$j) { + if ($i >= $j) { + $H[$i][$j] = $this->QR[$i][$j]; + } else { + $H[$i][$j] = 0.0; + } + } + } + return new PHPExcel_Shared_JAMA_Matrix($H); + } // function getH() + + + /** + * Return the upper triangular factor + * + * @return Matrix upper triangular factor + */ + public function getR() { + for ($i = 0; $i < $this->n; ++$i) { + for ($j = 0; $j < $this->n; ++$j) { + if ($i < $j) { + $R[$i][$j] = $this->QR[$i][$j]; + } elseif ($i == $j) { + $R[$i][$j] = $this->Rdiag[$i]; + } else { + $R[$i][$j] = 0.0; + } + } + } + return new PHPExcel_Shared_JAMA_Matrix($R); + } // function getR() + + + /** + * Generate and return the (economy-sized) orthogonal factor + * + * @return Matrix orthogonal factor + */ + public function getQ() { + for ($k = $this->n-1; $k >= 0; --$k) { + for ($i = 0; $i < $this->m; ++$i) { + $Q[$i][$k] = 0.0; + } + $Q[$k][$k] = 1.0; + for ($j = $k; $j < $this->n; ++$j) { + if ($this->QR[$k][$k] != 0) { + $s = 0.0; + for ($i = $k; $i < $this->m; ++$i) { + $s += $this->QR[$i][$k] * $Q[$i][$j]; + } + $s = -$s/$this->QR[$k][$k]; + for ($i = $k; $i < $this->m; ++$i) { + $Q[$i][$j] += $s * $this->QR[$i][$k]; + } + } + } + } + /* + for($i = 0; $i < count($Q); ++$i) { + for($j = 0; $j < count($Q); ++$j) { + if(! isset($Q[$i][$j]) ) { + $Q[$i][$j] = 0; + } + } + } + */ + return new PHPExcel_Shared_JAMA_Matrix($Q); + } // function getQ() + + + /** + * Least squares solution of A*X = B + * + * @param Matrix $B A Matrix with as many rows as A and any number of columns. + * @return Matrix Matrix that minimizes the two norm of Q*R*X-B. + */ + public function solve($B) { + if ($B->getRowDimension() == $this->m) { + if ($this->isFullRank()) { + // Copy right hand side + $nx = $B->getColumnDimension(); + $X = $B->getArrayCopy(); + // Compute Y = transpose(Q)*B + for ($k = 0; $k < $this->n; ++$k) { + for ($j = 0; $j < $nx; ++$j) { + $s = 0.0; + for ($i = $k; $i < $this->m; ++$i) { + $s += $this->QR[$i][$k] * $X[$i][$j]; + } + $s = -$s/$this->QR[$k][$k]; + for ($i = $k; $i < $this->m; ++$i) { + $X[$i][$j] += $s * $this->QR[$i][$k]; + } + } + } + // Solve R*X = Y; + for ($k = $this->n-1; $k >= 0; --$k) { + for ($j = 0; $j < $nx; ++$j) { + $X[$k][$j] /= $this->Rdiag[$k]; + } + for ($i = 0; $i < $k; ++$i) { + for ($j = 0; $j < $nx; ++$j) { + $X[$i][$j] -= $X[$k][$j]* $this->QR[$i][$k]; + } + } + } + $X = new PHPExcel_Shared_JAMA_Matrix($X); + return ($X->getMatrix(0, $this->n-1, 0, $nx)); + } else { + throw new PHPExcel_Calculation_Exception(self::MatrixRankException); + } + } else { + throw new PHPExcel_Calculation_Exception(PHPExcel_Shared_JAMA_Matrix::MatrixDimensionException); + } + } // function solve() + +} // PHPExcel_Shared_JAMA_class QRDecomposition diff --git a/lib/phpexcel/PHPExcel/Shared/JAMA/SingularValueDecomposition.php b/lib/phpexcel/PHPExcel/Shared/JAMA/SingularValueDecomposition.php new file mode 100644 index 0000000..a4b096c --- /dev/null +++ b/lib/phpexcel/PHPExcel/Shared/JAMA/SingularValueDecomposition.php @@ -0,0 +1,526 @@ +<?php +/** + * @package JAMA + * + * For an m-by-n matrix A with m >= n, the singular value decomposition is + * an m-by-n orthogonal matrix U, an n-by-n diagonal matrix S, and + * an n-by-n orthogonal matrix V so that A = U*S*V'. + * + * The singular values, sigma[$k] = S[$k][$k], are ordered so that + * sigma[0] >= sigma[1] >= ... >= sigma[n-1]. + * + * The singular value decompostion always exists, so the constructor will + * never fail. The matrix condition number and the effective numerical + * rank can be computed from this decomposition. + * + * @author Paul Meagher + * @license PHP v3.0 + * @version 1.1 + */ +class SingularValueDecomposition { + + /** + * Internal storage of U. + * @var array + */ + private $U = array(); + + /** + * Internal storage of V. + * @var array + */ + private $V = array(); + + /** + * Internal storage of singular values. + * @var array + */ + private $s = array(); + + /** + * Row dimension. + * @var int + */ + private $m; + + /** + * Column dimension. + * @var int + */ + private $n; + + + /** + * Construct the singular value decomposition + * + * Derived from LINPACK code. + * + * @param $A Rectangular matrix + * @return Structure to access U, S and V. + */ + public function __construct($Arg) { + + // Initialize. + $A = $Arg->getArrayCopy(); + $this->m = $Arg->getRowDimension(); + $this->n = $Arg->getColumnDimension(); + $nu = min($this->m, $this->n); + $e = array(); + $work = array(); + $wantu = true; + $wantv = true; + $nct = min($this->m - 1, $this->n); + $nrt = max(0, min($this->n - 2, $this->m)); + + // Reduce A to bidiagonal form, storing the diagonal elements + // in s and the super-diagonal elements in e. + for ($k = 0; $k < max($nct,$nrt); ++$k) { + + if ($k < $nct) { + // Compute the transformation for the k-th column and + // place the k-th diagonal in s[$k]. + // Compute 2-norm of k-th column without under/overflow. + $this->s[$k] = 0; + for ($i = $k; $i < $this->m; ++$i) { + $this->s[$k] = hypo($this->s[$k], $A[$i][$k]); + } + if ($this->s[$k] != 0.0) { + if ($A[$k][$k] < 0.0) { + $this->s[$k] = -$this->s[$k]; + } + for ($i = $k; $i < $this->m; ++$i) { + $A[$i][$k] /= $this->s[$k]; + } + $A[$k][$k] += 1.0; + } + $this->s[$k] = -$this->s[$k]; + } + + for ($j = $k + 1; $j < $this->n; ++$j) { + if (($k < $nct) & ($this->s[$k] != 0.0)) { + // Apply the transformation. + $t = 0; + for ($i = $k; $i < $this->m; ++$i) { + $t += $A[$i][$k] * $A[$i][$j]; + } + $t = -$t / $A[$k][$k]; + for ($i = $k; $i < $this->m; ++$i) { + $A[$i][$j] += $t * $A[$i][$k]; + } + // Place the k-th row of A into e for the + // subsequent calculation of the row transformation. + $e[$j] = $A[$k][$j]; + } + } + + if ($wantu AND ($k < $nct)) { + // Place the transformation in U for subsequent back + // multiplication. + for ($i = $k; $i < $this->m; ++$i) { + $this->U[$i][$k] = $A[$i][$k]; + } + } + + if ($k < $nrt) { + // Compute the k-th row transformation and place the + // k-th super-diagonal in e[$k]. + // Compute 2-norm without under/overflow. + $e[$k] = 0; + for ($i = $k + 1; $i < $this->n; ++$i) { + $e[$k] = hypo($e[$k], $e[$i]); + } + if ($e[$k] != 0.0) { + if ($e[$k+1] < 0.0) { + $e[$k] = -$e[$k]; + } + for ($i = $k + 1; $i < $this->n; ++$i) { + $e[$i] /= $e[$k]; + } + $e[$k+1] += 1.0; + } + $e[$k] = -$e[$k]; + if (($k+1 < $this->m) AND ($e[$k] != 0.0)) { + // Apply the transformation. + for ($i = $k+1; $i < $this->m; ++$i) { + $work[$i] = 0.0; + } + for ($j = $k+1; $j < $this->n; ++$j) { + for ($i = $k+1; $i < $this->m; ++$i) { + $work[$i] += $e[$j] * $A[$i][$j]; + } + } + for ($j = $k + 1; $j < $this->n; ++$j) { + $t = -$e[$j] / $e[$k+1]; + for ($i = $k + 1; $i < $this->m; ++$i) { + $A[$i][$j] += $t * $work[$i]; + } + } + } + if ($wantv) { + // Place the transformation in V for subsequent + // back multiplication. + for ($i = $k + 1; $i < $this->n; ++$i) { + $this->V[$i][$k] = $e[$i]; + } + } + } + } + + // Set up the final bidiagonal matrix or order p. + $p = min($this->n, $this->m + 1); + if ($nct < $this->n) { + $this->s[$nct] = $A[$nct][$nct]; + } + if ($this->m < $p) { + $this->s[$p-1] = 0.0; + } + if ($nrt + 1 < $p) { + $e[$nrt] = $A[$nrt][$p-1]; + } + $e[$p-1] = 0.0; + // If required, generate U. + if ($wantu) { + for ($j = $nct; $j < $nu; ++$j) { + for ($i = 0; $i < $this->m; ++$i) { + $this->U[$i][$j] = 0.0; + } + $this->U[$j][$j] = 1.0; + } + for ($k = $nct - 1; $k >= 0; --$k) { + if ($this->s[$k] != 0.0) { + for ($j = $k + 1; $j < $nu; ++$j) { + $t = 0; + for ($i = $k; $i < $this->m; ++$i) { + $t += $this->U[$i][$k] * $this->U[$i][$j]; + } + $t = -$t / $this->U[$k][$k]; + for ($i = $k; $i < $this->m; ++$i) { + $this->U[$i][$j] += $t * $this->U[$i][$k]; + } + } + for ($i = $k; $i < $this->m; ++$i ) { + $this->U[$i][$k] = -$this->U[$i][$k]; + } + $this->U[$k][$k] = 1.0 + $this->U[$k][$k]; + for ($i = 0; $i < $k - 1; ++$i) { + $this->U[$i][$k] = 0.0; + } + } else { + for ($i = 0; $i < $this->m; ++$i) { + $this->U[$i][$k] = 0.0; + } + $this->U[$k][$k] = 1.0; + } + } + } + + // If required, generate V. + if ($wantv) { + for ($k = $this->n - 1; $k >= 0; --$k) { + if (($k < $nrt) AND ($e[$k] != 0.0)) { + for ($j = $k + 1; $j < $nu; ++$j) { + $t = 0; + for ($i = $k + 1; $i < $this->n; ++$i) { + $t += $this->V[$i][$k]* $this->V[$i][$j]; + } + $t = -$t / $this->V[$k+1][$k]; + for ($i = $k + 1; $i < $this->n; ++$i) { + $this->V[$i][$j] += $t * $this->V[$i][$k]; + } + } + } + for ($i = 0; $i < $this->n; ++$i) { + $this->V[$i][$k] = 0.0; + } + $this->V[$k][$k] = 1.0; + } + } + + // Main iteration loop for the singular values. + $pp = $p - 1; + $iter = 0; + $eps = pow(2.0, -52.0); + + while ($p > 0) { + // Here is where a test for too many iterations would go. + // This section of the program inspects for negligible + // elements in the s and e arrays. On completion the + // variables kase and k are set as follows: + // kase = 1 if s(p) and e[k-1] are negligible and k<p + // kase = 2 if s(k) is negligible and k<p + // kase = 3 if e[k-1] is negligible, k<p, and + // s(k), ..., s(p) are not negligible (qr step). + // kase = 4 if e(p-1) is negligible (convergence). + for ($k = $p - 2; $k >= -1; --$k) { + if ($k == -1) { + break; + } + if (abs($e[$k]) <= $eps * (abs($this->s[$k]) + abs($this->s[$k+1]))) { + $e[$k] = 0.0; + break; + } + } + if ($k == $p - 2) { + $kase = 4; + } else { + for ($ks = $p - 1; $ks >= $k; --$ks) { + if ($ks == $k) { + break; + } + $t = ($ks != $p ? abs($e[$ks]) : 0.) + ($ks != $k + 1 ? abs($e[$ks-1]) : 0.); + if (abs($this->s[$ks]) <= $eps * $t) { + $this->s[$ks] = 0.0; + break; + } + } + if ($ks == $k) { + $kase = 3; + } else if ($ks == $p-1) { + $kase = 1; + } else { + $kase = 2; + $k = $ks; + } + } + ++$k; + + // Perform the task indicated by kase. + switch ($kase) { + // Deflate negligible s(p). + case 1: + $f = $e[$p-2]; + $e[$p-2] = 0.0; + for ($j = $p - 2; $j >= $k; --$j) { + $t = hypo($this->s[$j],$f); + $cs = $this->s[$j] / $t; + $sn = $f / $t; + $this->s[$j] = $t; + if ($j != $k) { + $f = -$sn * $e[$j-1]; + $e[$j-1] = $cs * $e[$j-1]; + } + if ($wantv) { + for ($i = 0; $i < $this->n; ++$i) { + $t = $cs * $this->V[$i][$j] + $sn * $this->V[$i][$p-1]; + $this->V[$i][$p-1] = -$sn * $this->V[$i][$j] + $cs * $this->V[$i][$p-1]; + $this->V[$i][$j] = $t; + } + } + } + break; + // Split at negligible s(k). + case 2: + $f = $e[$k-1]; + $e[$k-1] = 0.0; + for ($j = $k; $j < $p; ++$j) { + $t = hypo($this->s[$j], $f); + $cs = $this->s[$j] / $t; + $sn = $f / $t; + $this->s[$j] = $t; + $f = -$sn * $e[$j]; + $e[$j] = $cs * $e[$j]; + if ($wantu) { + for ($i = 0; $i < $this->m; ++$i) { + $t = $cs * $this->U[$i][$j] + $sn * $this->U[$i][$k-1]; + $this->U[$i][$k-1] = -$sn * $this->U[$i][$j] + $cs * $this->U[$i][$k-1]; + $this->U[$i][$j] = $t; + } + } + } + break; + // Perform one qr step. + case 3: + // Calculate the shift. + $scale = max(max(max(max( + abs($this->s[$p-1]),abs($this->s[$p-2])),abs($e[$p-2])), + abs($this->s[$k])), abs($e[$k])); + $sp = $this->s[$p-1] / $scale; + $spm1 = $this->s[$p-2] / $scale; + $epm1 = $e[$p-2] / $scale; + $sk = $this->s[$k] / $scale; + $ek = $e[$k] / $scale; + $b = (($spm1 + $sp) * ($spm1 - $sp) + $epm1 * $epm1) / 2.0; + $c = ($sp * $epm1) * ($sp * $epm1); + $shift = 0.0; + if (($b != 0.0) || ($c != 0.0)) { + $shift = sqrt($b * $b + $c); + if ($b < 0.0) { + $shift = -$shift; + } + $shift = $c / ($b + $shift); + } + $f = ($sk + $sp) * ($sk - $sp) + $shift; + $g = $sk * $ek; + // Chase zeros. + for ($j = $k; $j < $p-1; ++$j) { + $t = hypo($f,$g); + $cs = $f/$t; + $sn = $g/$t; + if ($j != $k) { + $e[$j-1] = $t; + } + $f = $cs * $this->s[$j] + $sn * $e[$j]; + $e[$j] = $cs * $e[$j] - $sn * $this->s[$j]; + $g = $sn * $this->s[$j+1]; + $this->s[$j+1] = $cs * $this->s[$j+1]; + if ($wantv) { + for ($i = 0; $i < $this->n; ++$i) { + $t = $cs * $this->V[$i][$j] + $sn * $this->V[$i][$j+1]; + $this->V[$i][$j+1] = -$sn * $this->V[$i][$j] + $cs * $this->V[$i][$j+1]; + $this->V[$i][$j] = $t; + } + } + $t = hypo($f,$g); + $cs = $f/$t; + $sn = $g/$t; + $this->s[$j] = $t; + $f = $cs * $e[$j] + $sn * $this->s[$j+1]; + $this->s[$j+1] = -$sn * $e[$j] + $cs * $this->s[$j+1]; + $g = $sn * $e[$j+1]; + $e[$j+1] = $cs * $e[$j+1]; + if ($wantu && ($j < $this->m - 1)) { + for ($i = 0; $i < $this->m; ++$i) { + $t = $cs * $this->U[$i][$j] + $sn * $this->U[$i][$j+1]; + $this->U[$i][$j+1] = -$sn * $this->U[$i][$j] + $cs * $this->U[$i][$j+1]; + $this->U[$i][$j] = $t; + } + } + } + $e[$p-2] = $f; + $iter = $iter + 1; + break; + // Convergence. + case 4: + // Make the singular values positive. + if ($this->s[$k] <= 0.0) { + $this->s[$k] = ($this->s[$k] < 0.0 ? -$this->s[$k] : 0.0); + if ($wantv) { + for ($i = 0; $i <= $pp; ++$i) { + $this->V[$i][$k] = -$this->V[$i][$k]; + } + } + } + // Order the singular values. + while ($k < $pp) { + if ($this->s[$k] >= $this->s[$k+1]) { + break; + } + $t = $this->s[$k]; + $this->s[$k] = $this->s[$k+1]; + $this->s[$k+1] = $t; + if ($wantv AND ($k < $this->n - 1)) { + for ($i = 0; $i < $this->n; ++$i) { + $t = $this->V[$i][$k+1]; + $this->V[$i][$k+1] = $this->V[$i][$k]; + $this->V[$i][$k] = $t; + } + } + if ($wantu AND ($k < $this->m-1)) { + for ($i = 0; $i < $this->m; ++$i) { + $t = $this->U[$i][$k+1]; + $this->U[$i][$k+1] = $this->U[$i][$k]; + $this->U[$i][$k] = $t; + } + } + ++$k; + } + $iter = 0; + --$p; + break; + } // end switch + } // end while + + } // end constructor + + + /** + * Return the left singular vectors + * + * @access public + * @return U + */ + public function getU() { + return new Matrix($this->U, $this->m, min($this->m + 1, $this->n)); + } + + + /** + * Return the right singular vectors + * + * @access public + * @return V + */ + public function getV() { + return new Matrix($this->V); + } + + + /** + * Return the one-dimensional array of singular values + * + * @access public + * @return diagonal of S. + */ + public function getSingularValues() { + return $this->s; + } + + + /** + * Return the diagonal matrix of singular values + * + * @access public + * @return S + */ + public function getS() { + for ($i = 0; $i < $this->n; ++$i) { + for ($j = 0; $j < $this->n; ++$j) { + $S[$i][$j] = 0.0; + } + $S[$i][$i] = $this->s[$i]; + } + return new Matrix($S); + } + + + /** + * Two norm + * + * @access public + * @return max(S) + */ + public function norm2() { + return $this->s[0]; + } + + + /** + * Two norm condition number + * + * @access public + * @return max(S)/min(S) + */ + public function cond() { + return $this->s[0] / $this->s[min($this->m, $this->n) - 1]; + } + + + /** + * Effective numerical matrix rank + * + * @access public + * @return Number of nonnegligible singular values. + */ + public function rank() { + $eps = pow(2.0, -52.0); + $tol = max($this->m, $this->n) * $this->s[0] * $eps; + $r = 0; + for ($i = 0; $i < count($this->s); ++$i) { + if ($this->s[$i] > $tol) { + ++$r; + } + } + return $r; + } + +} // class SingularValueDecomposition diff --git a/lib/phpexcel/PHPExcel/Shared/JAMA/utils/Error.php b/lib/phpexcel/PHPExcel/Shared/JAMA/utils/Error.php new file mode 100644 index 0000000..e73252b --- /dev/null +++ b/lib/phpexcel/PHPExcel/Shared/JAMA/utils/Error.php @@ -0,0 +1,82 @@ +<?php +/** + * @package JAMA + * + * Error handling + * @author Michael Bommarito + * @version 01292005 + */ + +//Language constant +define('JAMALANG', 'EN'); + + +//All errors may be defined by the following format: +//define('ExceptionName', N); +//$error['lang'][ExceptionName] = 'Error message'; +$error = array(); + +/* +I've used Babelfish and a little poor knowledge of Romance/Germanic languages for the translations here. +Feel free to correct anything that looks amiss to you. +*/ + +define('PolymorphicArgumentException', -1); +$error['EN'][PolymorphicArgumentException] = "Invalid argument pattern for polymorphic function."; +$error['FR'][PolymorphicArgumentException] = "Modèle inadmissible d'argument pour la fonction polymorphe.". +$error['DE'][PolymorphicArgumentException] = "Unzulässiges Argumentmuster für polymorphe Funktion."; + +define('ArgumentTypeException', -2); +$error['EN'][ArgumentTypeException] = "Invalid argument type."; +$error['FR'][ArgumentTypeException] = "Type inadmissible d'argument."; +$error['DE'][ArgumentTypeException] = "Unzulässige Argumentart."; + +define('ArgumentBoundsException', -3); +$error['EN'][ArgumentBoundsException] = "Invalid argument range."; +$error['FR'][ArgumentBoundsException] = "Gamme inadmissible d'argument."; +$error['DE'][ArgumentBoundsException] = "Unzulässige Argumentstrecke."; + +define('MatrixDimensionException', -4); +$error['EN'][MatrixDimensionException] = "Matrix dimensions are not equal."; +$error['FR'][MatrixDimensionException] = "Les dimensions de Matrix ne sont pas égales."; +$error['DE'][MatrixDimensionException] = "Matrixmaße sind nicht gleich."; + +define('PrecisionLossException', -5); +$error['EN'][PrecisionLossException] = "Significant precision loss detected."; +$error['FR'][PrecisionLossException] = "Perte significative de précision détectée."; +$error['DE'][PrecisionLossException] = "Bedeutender Präzision Verlust ermittelte."; + +define('MatrixSPDException', -6); +$error['EN'][MatrixSPDException] = "Can only perform operation on symmetric positive definite matrix."; +$error['FR'][MatrixSPDException] = "Perte significative de précision détectée."; +$error['DE'][MatrixSPDException] = "Bedeutender Präzision Verlust ermittelte."; + +define('MatrixSingularException', -7); +$error['EN'][MatrixSingularException] = "Can only perform operation on singular matrix."; + +define('MatrixRankException', -8); +$error['EN'][MatrixRankException] = "Can only perform operation on full-rank matrix."; + +define('ArrayLengthException', -9); +$error['EN'][ArrayLengthException] = "Array length must be a multiple of m."; + +define('RowLengthException', -10); +$error['EN'][RowLengthException] = "All rows must have the same length."; + +/** + * Custom error handler + * @param int $num Error number + */ +function JAMAError($errorNumber = null) { + global $error; + + if (isset($errorNumber)) { + if (isset($error[JAMALANG][$errorNumber])) { + return $error[JAMALANG][$errorNumber]; + } else { + return $error['EN'][$errorNumber]; + } + } else { + return ("Invalid argument to JAMAError()"); + } +} diff --git a/lib/phpexcel/PHPExcel/Shared/JAMA/utils/Maths.php b/lib/phpexcel/PHPExcel/Shared/JAMA/utils/Maths.php new file mode 100644 index 0000000..aa09a8b --- /dev/null +++ b/lib/phpexcel/PHPExcel/Shared/JAMA/utils/Maths.php @@ -0,0 +1,43 @@ +<?php +/** + * @package JAMA + * + * Pythagorean Theorem: + * + * a = 3 + * b = 4 + * r = sqrt(square(a) + square(b)) + * r = 5 + * + * r = sqrt(a^2 + b^2) without under/overflow. + */ +function hypo($a, $b) { + if (abs($a) > abs($b)) { + $r = $b / $a; + $r = abs($a) * sqrt(1 + $r * $r); + } elseif ($b != 0) { + $r = $a / $b; + $r = abs($b) * sqrt(1 + $r * $r); + } else { + $r = 0.0; + } + return $r; +} // function hypo() + + +/** + * Mike Bommarito's version. + * Compute n-dimensional hyotheneuse. + * +function hypot() { + $s = 0; + foreach (func_get_args() as $d) { + if (is_numeric($d)) { + $s += pow($d, 2); + } else { + throw new PHPExcel_Calculation_Exception(JAMAError(ArgumentTypeException)); + } + } + return sqrt($s); +} +*/ diff --git a/lib/phpexcel/PHPExcel/Shared/OLE.php b/lib/phpexcel/PHPExcel/Shared/OLE.php new file mode 100644 index 0000000..9796282 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Shared/OLE.php @@ -0,0 +1,531 @@ +<?php +/* vim: set expandtab tabstop=4 shiftwidth=4: */ +// +----------------------------------------------------------------------+ +// | PHP Version 4 | +// +----------------------------------------------------------------------+ +// | Copyright (c) 1997-2002 The PHP Group | +// +----------------------------------------------------------------------+ +// | This source file is subject to version 2.02 of the PHP license, | +// | that is bundled with this package in the file LICENSE, and is | +// | available at through the world-wide-web at | +// | http://www.php.net/license/2_02.txt. | +// | If you did not receive a copy of the PHP license and are unable to | +// | obtain it through the world-wide-web, please send a note to | +// | license@php.net so we can mail you a copy immediately. | +// +----------------------------------------------------------------------+ +// | Author: Xavier Noguer <xnoguer@php.net> | +// | Based on OLE::Storage_Lite by Kawai, Takanori | +// +----------------------------------------------------------------------+ +// +// $Id: OLE.php,v 1.13 2007/03/07 14:38:25 schmidt Exp $ + + +/** +* Array for storing OLE instances that are accessed from +* OLE_ChainedBlockStream::stream_open(). +* @var array +*/ +$GLOBALS['_OLE_INSTANCES'] = array(); + +/** +* OLE package base class. +* +* @author Xavier Noguer <xnoguer@php.net> +* @author Christian Schmidt <schmidt@php.net> +* @category PHPExcel +* @package PHPExcel_Shared_OLE +*/ +class PHPExcel_Shared_OLE +{ + const OLE_PPS_TYPE_ROOT = 5; + const OLE_PPS_TYPE_DIR = 1; + const OLE_PPS_TYPE_FILE = 2; + const OLE_DATA_SIZE_SMALL = 0x1000; + const OLE_LONG_INT_SIZE = 4; + const OLE_PPS_SIZE = 0x80; + + /** + * The file handle for reading an OLE container + * @var resource + */ + public $_file_handle; + + /** + * Array of PPS's found on the OLE container + * @var array + */ + public $_list = array(); + + /** + * Root directory of OLE container + * @var OLE_PPS_Root + */ + public $root; + + /** + * Big Block Allocation Table + * @var array (blockId => nextBlockId) + */ + public $bbat; + + /** + * Short Block Allocation Table + * @var array (blockId => nextBlockId) + */ + public $sbat; + + /** + * Size of big blocks. This is usually 512. + * @var int number of octets per block. + */ + public $bigBlockSize; + + /** + * Size of small blocks. This is usually 64. + * @var int number of octets per block + */ + public $smallBlockSize; + + /** + * Reads an OLE container from the contents of the file given. + * + * @acces public + * @param string $file + * @return mixed true on success, PEAR_Error on failure + */ + public function read($file) + { + $fh = fopen($file, "r"); + if (!$fh) { + throw new PHPExcel_Reader_Exception("Can't open file $file"); + } + $this->_file_handle = $fh; + + $signature = fread($fh, 8); + if ("\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1" != $signature) { + throw new PHPExcel_Reader_Exception("File doesn't seem to be an OLE container."); + } + fseek($fh, 28); + if (fread($fh, 2) != "\xFE\xFF") { + // This shouldn't be a problem in practice + throw new PHPExcel_Reader_Exception("Only Little-Endian encoding is supported."); + } + // Size of blocks and short blocks in bytes + $this->bigBlockSize = pow(2, self::_readInt2($fh)); + $this->smallBlockSize = pow(2, self::_readInt2($fh)); + + // Skip UID, revision number and version number + fseek($fh, 44); + // Number of blocks in Big Block Allocation Table + $bbatBlockCount = self::_readInt4($fh); + + // Root chain 1st block + $directoryFirstBlockId = self::_readInt4($fh); + + // Skip unused bytes + fseek($fh, 56); + // Streams shorter than this are stored using small blocks + $this->bigBlockThreshold = self::_readInt4($fh); + // Block id of first sector in Short Block Allocation Table + $sbatFirstBlockId = self::_readInt4($fh); + // Number of blocks in Short Block Allocation Table + $sbbatBlockCount = self::_readInt4($fh); + // Block id of first sector in Master Block Allocation Table + $mbatFirstBlockId = self::_readInt4($fh); + // Number of blocks in Master Block Allocation Table + $mbbatBlockCount = self::_readInt4($fh); + $this->bbat = array(); + + // Remaining 4 * 109 bytes of current block is beginning of Master + // Block Allocation Table + $mbatBlocks = array(); + for ($i = 0; $i < 109; ++$i) { + $mbatBlocks[] = self::_readInt4($fh); + } + + // Read rest of Master Block Allocation Table (if any is left) + $pos = $this->_getBlockOffset($mbatFirstBlockId); + for ($i = 0; $i < $mbbatBlockCount; ++$i) { + fseek($fh, $pos); + for ($j = 0; $j < $this->bigBlockSize / 4 - 1; ++$j) { + $mbatBlocks[] = self::_readInt4($fh); + } + // Last block id in each block points to next block + $pos = $this->_getBlockOffset(self::_readInt4($fh)); + } + + // Read Big Block Allocation Table according to chain specified by + // $mbatBlocks + for ($i = 0; $i < $bbatBlockCount; ++$i) { + $pos = $this->_getBlockOffset($mbatBlocks[$i]); + fseek($fh, $pos); + for ($j = 0 ; $j < $this->bigBlockSize / 4; ++$j) { + $this->bbat[] = self::_readInt4($fh); + } + } + + // Read short block allocation table (SBAT) + $this->sbat = array(); + $shortBlockCount = $sbbatBlockCount * $this->bigBlockSize / 4; + $sbatFh = $this->getStream($sbatFirstBlockId); + for ($blockId = 0; $blockId < $shortBlockCount; ++$blockId) { + $this->sbat[$blockId] = self::_readInt4($sbatFh); + } + fclose($sbatFh); + + $this->_readPpsWks($directoryFirstBlockId); + + return true; + } + + /** + * @param int block id + * @param int byte offset from beginning of file + * @access public + */ + public function _getBlockOffset($blockId) + { + return 512 + $blockId * $this->bigBlockSize; + } + + /** + * Returns a stream for use with fread() etc. External callers should + * use PHPExcel_Shared_OLE_PPS_File::getStream(). + * @param int|PPS block id or PPS + * @return resource read-only stream + */ + public function getStream($blockIdOrPps) + { + static $isRegistered = false; + if (!$isRegistered) { + stream_wrapper_register('ole-chainedblockstream', + 'PHPExcel_Shared_OLE_ChainedBlockStream'); + $isRegistered = true; + } + + // Store current instance in global array, so that it can be accessed + // in OLE_ChainedBlockStream::stream_open(). + // Object is removed from self::$instances in OLE_Stream::close(). + $GLOBALS['_OLE_INSTANCES'][] = $this; + $instanceId = end(array_keys($GLOBALS['_OLE_INSTANCES'])); + + $path = 'ole-chainedblockstream://oleInstanceId=' . $instanceId; + if ($blockIdOrPps instanceof PHPExcel_Shared_OLE_PPS) { + $path .= '&blockId=' . $blockIdOrPps->_StartBlock; + $path .= '&size=' . $blockIdOrPps->Size; + } else { + $path .= '&blockId=' . $blockIdOrPps; + } + return fopen($path, 'r'); + } + + /** + * Reads a signed char. + * @param resource file handle + * @return int + * @access public + */ + private static function _readInt1($fh) + { + list(, $tmp) = unpack("c", fread($fh, 1)); + return $tmp; + } + + /** + * Reads an unsigned short (2 octets). + * @param resource file handle + * @return int + * @access public + */ + private static function _readInt2($fh) + { + list(, $tmp) = unpack("v", fread($fh, 2)); + return $tmp; + } + + /** + * Reads an unsigned long (4 octets). + * @param resource file handle + * @return int + * @access public + */ + private static function _readInt4($fh) + { + list(, $tmp) = unpack("V", fread($fh, 4)); + return $tmp; + } + + /** + * Gets information about all PPS's on the OLE container from the PPS WK's + * creates an OLE_PPS object for each one. + * + * @access public + * @param integer the block id of the first block + * @return mixed true on success, PEAR_Error on failure + */ + public function _readPpsWks($blockId) + { + $fh = $this->getStream($blockId); + for ($pos = 0; ; $pos += 128) { + fseek($fh, $pos, SEEK_SET); + $nameUtf16 = fread($fh, 64); + $nameLength = self::_readInt2($fh); + $nameUtf16 = substr($nameUtf16, 0, $nameLength - 2); + // Simple conversion from UTF-16LE to ISO-8859-1 + $name = str_replace("\x00", "", $nameUtf16); + $type = self::_readInt1($fh); + switch ($type) { + case self::OLE_PPS_TYPE_ROOT: + $pps = new PHPExcel_Shared_OLE_PPS_Root(null, null, array()); + $this->root = $pps; + break; + case self::OLE_PPS_TYPE_DIR: + $pps = new PHPExcel_Shared_OLE_PPS(null, null, null, null, null, + null, null, null, null, array()); + break; + case self::OLE_PPS_TYPE_FILE: + $pps = new PHPExcel_Shared_OLE_PPS_File($name); + break; + default: + continue; + } + fseek($fh, 1, SEEK_CUR); + $pps->Type = $type; + $pps->Name = $name; + $pps->PrevPps = self::_readInt4($fh); + $pps->NextPps = self::_readInt4($fh); + $pps->DirPps = self::_readInt4($fh); + fseek($fh, 20, SEEK_CUR); + $pps->Time1st = self::OLE2LocalDate(fread($fh, 8)); + $pps->Time2nd = self::OLE2LocalDate(fread($fh, 8)); + $pps->_StartBlock = self::_readInt4($fh); + $pps->Size = self::_readInt4($fh); + $pps->No = count($this->_list); + $this->_list[] = $pps; + + // check if the PPS tree (starting from root) is complete + if (isset($this->root) && + $this->_ppsTreeComplete($this->root->No)) { + + break; + } + } + fclose($fh); + + // Initialize $pps->children on directories + foreach ($this->_list as $pps) { + if ($pps->Type == self::OLE_PPS_TYPE_DIR || $pps->Type == self::OLE_PPS_TYPE_ROOT) { + $nos = array($pps->DirPps); + $pps->children = array(); + while ($nos) { + $no = array_pop($nos); + if ($no != -1) { + $childPps = $this->_list[$no]; + $nos[] = $childPps->PrevPps; + $nos[] = $childPps->NextPps; + $pps->children[] = $childPps; + } + } + } + } + + return true; + } + + /** + * It checks whether the PPS tree is complete (all PPS's read) + * starting with the given PPS (not necessarily root) + * + * @access public + * @param integer $index The index of the PPS from which we are checking + * @return boolean Whether the PPS tree for the given PPS is complete + */ + public function _ppsTreeComplete($index) + { + return isset($this->_list[$index]) && + ($pps = $this->_list[$index]) && + ($pps->PrevPps == -1 || + $this->_ppsTreeComplete($pps->PrevPps)) && + ($pps->NextPps == -1 || + $this->_ppsTreeComplete($pps->NextPps)) && + ($pps->DirPps == -1 || + $this->_ppsTreeComplete($pps->DirPps)); + } + + /** + * Checks whether a PPS is a File PPS or not. + * If there is no PPS for the index given, it will return false. + * + * @access public + * @param integer $index The index for the PPS + * @return bool true if it's a File PPS, false otherwise + */ + public function isFile($index) + { + if (isset($this->_list[$index])) { + return ($this->_list[$index]->Type == self::OLE_PPS_TYPE_FILE); + } + return false; + } + + /** + * Checks whether a PPS is a Root PPS or not. + * If there is no PPS for the index given, it will return false. + * + * @access public + * @param integer $index The index for the PPS. + * @return bool true if it's a Root PPS, false otherwise + */ + public function isRoot($index) + { + if (isset($this->_list[$index])) { + return ($this->_list[$index]->Type == self::OLE_PPS_TYPE_ROOT); + } + return false; + } + + /** + * Gives the total number of PPS's found in the OLE container. + * + * @access public + * @return integer The total number of PPS's found in the OLE container + */ + public function ppsTotal() + { + return count($this->_list); + } + + /** + * Gets data from a PPS + * If there is no PPS for the index given, it will return an empty string. + * + * @access public + * @param integer $index The index for the PPS + * @param integer $position The position from which to start reading + * (relative to the PPS) + * @param integer $length The amount of bytes to read (at most) + * @return string The binary string containing the data requested + * @see OLE_PPS_File::getStream() + */ + public function getData($index, $position, $length) + { + // if position is not valid return empty string + if (!isset($this->_list[$index]) || ($position >= $this->_list[$index]->Size) || ($position < 0)) { + return ''; + } + $fh = $this->getStream($this->_list[$index]); + $data = stream_get_contents($fh, $length, $position); + fclose($fh); + return $data; + } + + /** + * Gets the data length from a PPS + * If there is no PPS for the index given, it will return 0. + * + * @access public + * @param integer $index The index for the PPS + * @return integer The amount of bytes in data the PPS has + */ + public function getDataLength($index) + { + if (isset($this->_list[$index])) { + return $this->_list[$index]->Size; + } + return 0; + } + + /** + * Utility function to transform ASCII text to Unicode + * + * @access public + * @static + * @param string $ascii The ASCII string to transform + * @return string The string in Unicode + */ + public static function Asc2Ucs($ascii) + { + $rawname = ''; + for ($i = 0; $i < strlen($ascii); ++$i) { + $rawname .= $ascii{$i} . "\x00"; + } + return $rawname; + } + + /** + * Utility function + * Returns a string for the OLE container with the date given + * + * @access public + * @static + * @param integer $date A timestamp + * @return string The string for the OLE container + */ + public static function LocalDate2OLE($date = null) + { + if (!isset($date)) { + return "\x00\x00\x00\x00\x00\x00\x00\x00"; + } + + // factor used for separating numbers into 4 bytes parts + $factor = pow(2, 32); + + // days from 1-1-1601 until the beggining of UNIX era + $days = 134774; + // calculate seconds + $big_date = $days*24*3600 + gmmktime(date("H",$date),date("i",$date),date("s",$date), + date("m",$date),date("d",$date),date("Y",$date)); + // multiply just to make MS happy + $big_date *= 10000000; + + $high_part = floor($big_date / $factor); + // lower 4 bytes + $low_part = floor((($big_date / $factor) - $high_part) * $factor); + + // Make HEX string + $res = ''; + + for ($i = 0; $i < 4; ++$i) { + $hex = $low_part % 0x100; + $res .= pack('c', $hex); + $low_part /= 0x100; + } + for ($i = 0; $i < 4; ++$i) { + $hex = $high_part % 0x100; + $res .= pack('c', $hex); + $high_part /= 0x100; + } + return $res; + } + + /** + * Returns a timestamp from an OLE container's date + * + * @access public + * @static + * @param integer $string A binary string with the encoded date + * @return string The timestamp corresponding to the string + */ + public static function OLE2LocalDate($string) + { + if (strlen($string) != 8) { + return new PEAR_Error("Expecting 8 byte string"); + } + + // factor used for separating numbers into 4 bytes parts + $factor = pow(2,32); + list(, $high_part) = unpack('V', substr($string, 4, 4)); + list(, $low_part) = unpack('V', substr($string, 0, 4)); + + $big_date = ($high_part * $factor) + $low_part; + // translate to seconds + $big_date /= 10000000; + + // days from 1-1-1601 until the beggining of UNIX era + $days = 134774; + + // translate to seconds from beggining of UNIX era + $big_date -= $days * 24 * 3600; + return floor($big_date); + } +} diff --git a/lib/phpexcel/PHPExcel/Shared/OLE/ChainedBlockStream.php b/lib/phpexcel/PHPExcel/Shared/OLE/ChainedBlockStream.php new file mode 100644 index 0000000..3dcd7e1 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Shared/OLE/ChainedBlockStream.php @@ -0,0 +1,230 @@ +<?php +/** + * PHPExcel + * + * Copyright (C) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared_OLE + * @copyright Copyright (c) 2006 - 2007 Christian Schmidt + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + +/** + * PHPExcel_Shared_OLE_ChainedBlockStream + * + * Stream wrapper for reading data stored in an OLE file. Implements methods + * for PHP's stream_wrapper_register(). For creating streams using this + * wrapper, use PHPExcel_Shared_OLE_PPS_File::getStream(). + * + * @category PHPExcel + * @package PHPExcel_Shared_OLE + */ +class PHPExcel_Shared_OLE_ChainedBlockStream +{ + /** + * The OLE container of the file that is being read. + * @var OLE + */ + public $ole; + + /** + * Parameters specified by fopen(). + * @var array + */ + public $params; + + /** + * The binary data of the file. + * @var string + */ + public $data; + + /** + * The file pointer. + * @var int byte offset + */ + public $pos; + + /** + * Implements support for fopen(). + * For creating streams using this wrapper, use OLE_PPS_File::getStream(). + * + * @param string $path resource name including scheme, e.g. + * ole-chainedblockstream://oleInstanceId=1 + * @param string $mode only "r" is supported + * @param int $options mask of STREAM_REPORT_ERRORS and STREAM_USE_PATH + * @param string &$openedPath absolute path of the opened stream (out parameter) + * @return bool true on success + */ + public function stream_open($path, $mode, $options, &$openedPath) + { + if ($mode != 'r') { + if ($options & STREAM_REPORT_ERRORS) { + trigger_error('Only reading is supported', E_USER_WARNING); + } + return false; + } + + // 25 is length of "ole-chainedblockstream://" + parse_str(substr($path, 25), $this->params); + if (!isset($this->params['oleInstanceId'], + $this->params['blockId'], + $GLOBALS['_OLE_INSTANCES'][$this->params['oleInstanceId']])) { + + if ($options & STREAM_REPORT_ERRORS) { + trigger_error('OLE stream not found', E_USER_WARNING); + } + return false; + } + $this->ole = $GLOBALS['_OLE_INSTANCES'][$this->params['oleInstanceId']]; + + $blockId = $this->params['blockId']; + $this->data = ''; + if (isset($this->params['size']) && + $this->params['size'] < $this->ole->bigBlockThreshold && + $blockId != $this->ole->root->_StartBlock) { + + // Block id refers to small blocks + $rootPos = $this->ole->_getBlockOffset($this->ole->root->_StartBlock); + while ($blockId != -2) { + $pos = $rootPos + $blockId * $this->ole->bigBlockSize; + $blockId = $this->ole->sbat[$blockId]; + fseek($this->ole->_file_handle, $pos); + $this->data .= fread($this->ole->_file_handle, $this->ole->bigBlockSize); + } + } else { + // Block id refers to big blocks + while ($blockId != -2) { + $pos = $this->ole->_getBlockOffset($blockId); + fseek($this->ole->_file_handle, $pos); + $this->data .= fread($this->ole->_file_handle, $this->ole->bigBlockSize); + $blockId = $this->ole->bbat[$blockId]; + } + } + if (isset($this->params['size'])) { + $this->data = substr($this->data, 0, $this->params['size']); + } + + if ($options & STREAM_USE_PATH) { + $openedPath = $path; + } + + return true; + } + + /** + * Implements support for fclose(). + * + */ + public function stream_close() + { + $this->ole = null; + unset($GLOBALS['_OLE_INSTANCES']); + } + + /** + * Implements support for fread(), fgets() etc. + * + * @param int $count maximum number of bytes to read + * @return string + */ + public function stream_read($count) + { + if ($this->stream_eof()) { + return false; + } + $s = substr($this->data, $this->pos, $count); + $this->pos += $count; + return $s; + } + + /** + * Implements support for feof(). + * + * @return bool TRUE if the file pointer is at EOF; otherwise FALSE + */ + public function stream_eof() + { +// As we don't support below 5.2 anymore, this is simply redundancy and overhead +// $eof = $this->pos >= strlen($this->data); +// // Workaround for bug in PHP 5.0.x: http://bugs.php.net/27508 +// if (version_compare(PHP_VERSION, '5.0', '>=') && +// version_compare(PHP_VERSION, '5.1', '<')) { +// $eof = !$eof; +// } +// return $eof; + return $this->pos >= strlen($this->data); + } + + /** + * Returns the position of the file pointer, i.e. its offset into the file + * stream. Implements support for ftell(). + * + * @return int + */ + public function stream_tell() + { + return $this->pos; + } + + /** + * Implements support for fseek(). + * + * @param int $offset byte offset + * @param int $whence SEEK_SET, SEEK_CUR or SEEK_END + * @return bool + */ + public function stream_seek($offset, $whence) + { + if ($whence == SEEK_SET && $offset >= 0) { + $this->pos = $offset; + } elseif ($whence == SEEK_CUR && -$offset <= $this->pos) { + $this->pos += $offset; + } elseif ($whence == SEEK_END && -$offset <= sizeof($this->data)) { + $this->pos = strlen($this->data) + $offset; + } else { + return false; + } + return true; + } + + /** + * Implements support for fstat(). Currently the only supported field is + * "size". + * @return array + */ + public function stream_stat() + { + return array( + 'size' => strlen($this->data), + ); + } + + // Methods used by stream_wrapper_register() that are not implemented: + // bool stream_flush ( void ) + // int stream_write ( string data ) + // bool rename ( string path_from, string path_to ) + // bool mkdir ( string path, int mode, int options ) + // bool rmdir ( string path, int options ) + // bool dir_opendir ( string path, int options ) + // array url_stat ( string path, int flags ) + // string dir_readdir ( void ) + // bool dir_rewinddir ( void ) + // bool dir_closedir ( void ) +} diff --git a/lib/phpexcel/PHPExcel/Shared/OLE/PPS.php b/lib/phpexcel/PHPExcel/Shared/OLE/PPS.php new file mode 100644 index 0000000..4db0ae4 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Shared/OLE/PPS.php @@ -0,0 +1,230 @@ +<?php +/* vim: set expandtab tabstop=4 shiftwidth=4: */ +// +----------------------------------------------------------------------+ +// | PHP Version 4 | +// +----------------------------------------------------------------------+ +// | Copyright (c) 1997-2002 The PHP Group | +// +----------------------------------------------------------------------+ +// | This source file is subject to version 2.02 of the PHP license, | +// | that is bundled with this package in the file LICENSE, and is | +// | available at through the world-wide-web at | +// | http://www.php.net/license/2_02.txt. | +// | If you did not receive a copy of the PHP license and are unable to | +// | obtain it through the world-wide-web, please send a note to | +// | license@php.net so we can mail you a copy immediately. | +// +----------------------------------------------------------------------+ +// | Author: Xavier Noguer <xnoguer@php.net> | +// | Based on OLE::Storage_Lite by Kawai, Takanori | +// +----------------------------------------------------------------------+ +// +// $Id: PPS.php,v 1.7 2007/02/13 21:00:42 schmidt Exp $ + + +/** +* Class for creating PPS's for OLE containers +* +* @author Xavier Noguer <xnoguer@php.net> +* @category PHPExcel +* @package PHPExcel_Shared_OLE +*/ +class PHPExcel_Shared_OLE_PPS +{ + /** + * The PPS index + * @var integer + */ + public $No; + + /** + * The PPS name (in Unicode) + * @var string + */ + public $Name; + + /** + * The PPS type. Dir, Root or File + * @var integer + */ + public $Type; + + /** + * The index of the previous PPS + * @var integer + */ + public $PrevPps; + + /** + * The index of the next PPS + * @var integer + */ + public $NextPps; + + /** + * The index of it's first child if this is a Dir or Root PPS + * @var integer + */ + public $DirPps; + + /** + * A timestamp + * @var integer + */ + public $Time1st; + + /** + * A timestamp + * @var integer + */ + public $Time2nd; + + /** + * Starting block (small or big) for this PPS's data inside the container + * @var integer + */ + public $_StartBlock; + + /** + * The size of the PPS's data (in bytes) + * @var integer + */ + public $Size; + + /** + * The PPS's data (only used if it's not using a temporary file) + * @var string + */ + public $_data; + + /** + * Array of child PPS's (only used by Root and Dir PPS's) + * @var array + */ + public $children = array(); + + /** + * Pointer to OLE container + * @var OLE + */ + public $ole; + + /** + * The constructor + * + * @access public + * @param integer $No The PPS index + * @param string $name The PPS name + * @param integer $type The PPS type. Dir, Root or File + * @param integer $prev The index of the previous PPS + * @param integer $next The index of the next PPS + * @param integer $dir The index of it's first child if this is a Dir or Root PPS + * @param integer $time_1st A timestamp + * @param integer $time_2nd A timestamp + * @param string $data The (usually binary) source data of the PPS + * @param array $children Array containing children PPS for this PPS + */ + public function __construct($No, $name, $type, $prev, $next, $dir, $time_1st, $time_2nd, $data, $children) + { + $this->No = $No; + $this->Name = $name; + $this->Type = $type; + $this->PrevPps = $prev; + $this->NextPps = $next; + $this->DirPps = $dir; + $this->Time1st = $time_1st; + $this->Time2nd = $time_2nd; + $this->_data = $data; + $this->children = $children; + if ($data != '') { + $this->Size = strlen($data); + } else { + $this->Size = 0; + } + } + + /** + * Returns the amount of data saved for this PPS + * + * @access public + * @return integer The amount of data (in bytes) + */ + public function _DataLen() + { + if (!isset($this->_data)) { + return 0; + } + //if (isset($this->_PPS_FILE)) { + // fseek($this->_PPS_FILE, 0); + // $stats = fstat($this->_PPS_FILE); + // return $stats[7]; + //} else { + return strlen($this->_data); + //} + } + + /** + * Returns a string with the PPS's WK (What is a WK?) + * + * @access public + * @return string The binary string + */ + public function _getPpsWk() + { + $ret = str_pad($this->Name,64,"\x00"); + + $ret .= pack("v", strlen($this->Name) + 2) // 66 + . pack("c", $this->Type) // 67 + . pack("c", 0x00) //UK // 68 + . pack("V", $this->PrevPps) //Prev // 72 + . pack("V", $this->NextPps) //Next // 76 + . pack("V", $this->DirPps) //Dir // 80 + . "\x00\x09\x02\x00" // 84 + . "\x00\x00\x00\x00" // 88 + . "\xc0\x00\x00\x00" // 92 + . "\x00\x00\x00\x46" // 96 // Seems to be ok only for Root + . "\x00\x00\x00\x00" // 100 + . PHPExcel_Shared_OLE::LocalDate2OLE($this->Time1st) // 108 + . PHPExcel_Shared_OLE::LocalDate2OLE($this->Time2nd) // 116 + . pack("V", isset($this->_StartBlock)? + $this->_StartBlock:0) // 120 + . pack("V", $this->Size) // 124 + . pack("V", 0); // 128 + return $ret; + } + + /** + * Updates index and pointers to previous, next and children PPS's for this + * PPS. I don't think it'll work with Dir PPS's. + * + * @access public + * @param array &$raList Reference to the array of PPS's for the whole OLE + * container + * @return integer The index for this PPS + */ + public static function _savePpsSetPnt(&$raList, $to_save, $depth = 0) + { + if ( !is_array($to_save) || (empty($to_save)) ) { + return 0xFFFFFFFF; + } elseif( count($to_save) == 1 ) { + $cnt = count($raList); + // If the first entry, it's the root... Don't clone it! + $raList[$cnt] = ( $depth == 0 ) ? $to_save[0] : clone $to_save[0]; + $raList[$cnt]->No = $cnt; + $raList[$cnt]->PrevPps = 0xFFFFFFFF; + $raList[$cnt]->NextPps = 0xFFFFFFFF; + $raList[$cnt]->DirPps = self::_savePpsSetPnt($raList, @$raList[$cnt]->children, $depth++); + } else { + $iPos = floor(count($to_save) / 2); + $aPrev = array_slice($to_save, 0, $iPos); + $aNext = array_slice($to_save, $iPos + 1); + $cnt = count($raList); + // If the first entry, it's the root... Don't clone it! + $raList[$cnt] = ( $depth == 0 ) ? $to_save[$iPos] : clone $to_save[$iPos]; + $raList[$cnt]->No = $cnt; + $raList[$cnt]->PrevPps = self::_savePpsSetPnt($raList, $aPrev, $depth++); + $raList[$cnt]->NextPps = self::_savePpsSetPnt($raList, $aNext, $depth++); + $raList[$cnt]->DirPps = self::_savePpsSetPnt($raList, @$raList[$cnt]->children, $depth++); + + } + return $cnt; + } +} diff --git a/lib/phpexcel/PHPExcel/Shared/OLE/PPS/File.php b/lib/phpexcel/PHPExcel/Shared/OLE/PPS/File.php new file mode 100644 index 0000000..f061f56 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Shared/OLE/PPS/File.php @@ -0,0 +1,84 @@ +<?php +/* vim: set expandtab tabstop=4 shiftwidth=4: */ +// +----------------------------------------------------------------------+ +// | PHP Version 4 | +// +----------------------------------------------------------------------+ +// | Copyright (c) 1997-2002 The PHP Group | +// +----------------------------------------------------------------------+ +// | This source file is subject to version 2.02 of the PHP license, | +// | that is bundled with this package in the file LICENSE, and is | +// | available at through the world-wide-web at | +// | http://www.php.net/license/2_02.txt. | +// | If you did not receive a copy of the PHP license and are unable to | +// | obtain it through the world-wide-web, please send a note to | +// | license@php.net so we can mail you a copy immediately. | +// +----------------------------------------------------------------------+ +// | Author: Xavier Noguer <xnoguer@php.net> | +// | Based on OLE::Storage_Lite by Kawai, Takanori | +// +----------------------------------------------------------------------+ +// +// $Id: File.php,v 1.11 2007/02/13 21:00:42 schmidt Exp $ + + +/** +* Class for creating File PPS's for OLE containers +* +* @author Xavier Noguer <xnoguer@php.net> +* @category PHPExcel +* @package PHPExcel_Shared_OLE +*/ +class PHPExcel_Shared_OLE_PPS_File extends PHPExcel_Shared_OLE_PPS + { + /** + * The constructor + * + * @access public + * @param string $name The name of the file (in Unicode) + * @see OLE::Asc2Ucs() + */ + public function __construct($name) + { + parent::__construct( + null, + $name, + PHPExcel_Shared_OLE::OLE_PPS_TYPE_FILE, + null, + null, + null, + null, + null, + '', + array()); + } + + /** + * Initialization method. Has to be called right after OLE_PPS_File(). + * + * @access public + * @return mixed true on success + */ + public function init() + { + return true; + } + + /** + * Append data to PPS + * + * @access public + * @param string $data The data to append + */ + public function append($data) + { + $this->_data .= $data; + } + + /** + * Returns a stream for reading this file using fread() etc. + * @return resource a read-only stream + */ + public function getStream() + { + $this->ole->getStream($this); + } +} diff --git a/lib/phpexcel/PHPExcel/Shared/OLE/PPS/Root.php b/lib/phpexcel/PHPExcel/Shared/OLE/PPS/Root.php new file mode 100644 index 0000000..eb929d2 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Shared/OLE/PPS/Root.php @@ -0,0 +1,467 @@ +<?php +/* vim: set expandtab tabstop=4 shiftwidth=4: */ +// +----------------------------------------------------------------------+ +// | PHP Version 4 | +// +----------------------------------------------------------------------+ +// | Copyright (c) 1997-2002 The PHP Group | +// +----------------------------------------------------------------------+ +// | This source file is subject to version 2.02 of the PHP license, | +// | that is bundled with this package in the file LICENSE, and is | +// | available at through the world-wide-web at | +// | http://www.php.net/license/2_02.txt. | +// | If you did not receive a copy of the PHP license and are unable to | +// | obtain it through the world-wide-web, please send a note to | +// | license@php.net so we can mail you a copy immediately. | +// +----------------------------------------------------------------------+ +// | Author: Xavier Noguer <xnoguer@php.net> | +// | Based on OLE::Storage_Lite by Kawai, Takanori | +// +----------------------------------------------------------------------+ +// +// $Id: Root.php,v 1.9 2005/04/23 21:53:49 dufuz Exp $ + + +/** +* Class for creating Root PPS's for OLE containers +* +* @author Xavier Noguer <xnoguer@php.net> +* @category PHPExcel +* @package PHPExcel_Shared_OLE +*/ +class PHPExcel_Shared_OLE_PPS_Root extends PHPExcel_Shared_OLE_PPS + { + + /** + * Directory for temporary files + * @var string + */ + protected $_tmp_dir = NULL; + + /** + * @param integer $time_1st A timestamp + * @param integer $time_2nd A timestamp + */ + public function __construct($time_1st, $time_2nd, $raChild) + { + $this->_tempDir = PHPExcel_Shared_File::sys_get_temp_dir(); + + parent::__construct( + null, + PHPExcel_Shared_OLE::Asc2Ucs('Root Entry'), + PHPExcel_Shared_OLE::OLE_PPS_TYPE_ROOT, + null, + null, + null, + $time_1st, + $time_2nd, + null, + $raChild); + } + + /** + * Method for saving the whole OLE container (including files). + * In fact, if called with an empty argument (or '-'), it saves to a + * temporary file and then outputs it's contents to stdout. + * If a resource pointer to a stream created by fopen() is passed + * it will be used, but you have to close such stream by yourself. + * + * @param string|resource $filename The name of the file or stream where to save the OLE container. + * @access public + * @return mixed true on success + */ + public function save($filename) + { + // Initial Setting for saving + $this->_BIG_BLOCK_SIZE = pow(2, + ((isset($this->_BIG_BLOCK_SIZE))? self::_adjust2($this->_BIG_BLOCK_SIZE) : 9)); + $this->_SMALL_BLOCK_SIZE= pow(2, + ((isset($this->_SMALL_BLOCK_SIZE))? self::_adjust2($this->_SMALL_BLOCK_SIZE): 6)); + + if (is_resource($filename)) { + $this->_FILEH_ = $filename; + } else if ($filename == '-' || $filename == '') { + if ($this->_tmp_dir === NULL) + $this->_tmp_dir = PHPExcel_Shared_File::sys_get_temp_dir(); + $this->_tmp_filename = tempnam($this->_tmp_dir, "OLE_PPS_Root"); + $this->_FILEH_ = fopen($this->_tmp_filename,"w+b"); + if ($this->_FILEH_ == false) { + throw new PHPExcel_Writer_Exception("Can't create temporary file."); + } + } else { + $this->_FILEH_ = fopen($filename, "wb"); + } + if ($this->_FILEH_ == false) { + throw new PHPExcel_Writer_Exception("Can't open $filename. It may be in use or protected."); + } + // Make an array of PPS's (for Save) + $aList = array(); + PHPExcel_Shared_OLE_PPS::_savePpsSetPnt($aList, array($this)); + // calculate values for header + list($iSBDcnt, $iBBcnt, $iPPScnt) = $this->_calcSize($aList); //, $rhInfo); + // Save Header + $this->_saveHeader($iSBDcnt, $iBBcnt, $iPPScnt); + + // Make Small Data string (write SBD) + $this->_data = $this->_makeSmallData($aList); + + // Write BB + $this->_saveBigData($iSBDcnt, $aList); + // Write PPS + $this->_savePps($aList); + // Write Big Block Depot and BDList and Adding Header informations + $this->_saveBbd($iSBDcnt, $iBBcnt, $iPPScnt); + + if (!is_resource($filename)) { + fclose($this->_FILEH_); + } + + return true; + } + + /** + * Calculate some numbers + * + * @access public + * @param array $raList Reference to an array of PPS's + * @return array The array of numbers + */ + public function _calcSize(&$raList) + { + // Calculate Basic Setting + list($iSBDcnt, $iBBcnt, $iPPScnt) = array(0,0,0); + $iSmallLen = 0; + $iSBcnt = 0; + $iCount = count($raList); + for ($i = 0; $i < $iCount; ++$i) { + if ($raList[$i]->Type == PHPExcel_Shared_OLE::OLE_PPS_TYPE_FILE) { + $raList[$i]->Size = $raList[$i]->_DataLen(); + if ($raList[$i]->Size < PHPExcel_Shared_OLE::OLE_DATA_SIZE_SMALL) { + $iSBcnt += floor($raList[$i]->Size / $this->_SMALL_BLOCK_SIZE) + + (($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE)? 1: 0); + } else { + $iBBcnt += (floor($raList[$i]->Size / $this->_BIG_BLOCK_SIZE) + + (($raList[$i]->Size % $this->_BIG_BLOCK_SIZE)? 1: 0)); + } + } + } + $iSmallLen = $iSBcnt * $this->_SMALL_BLOCK_SIZE; + $iSlCnt = floor($this->_BIG_BLOCK_SIZE / PHPExcel_Shared_OLE::OLE_LONG_INT_SIZE); + $iSBDcnt = floor($iSBcnt / $iSlCnt) + (($iSBcnt % $iSlCnt)? 1:0); + $iBBcnt += (floor($iSmallLen / $this->_BIG_BLOCK_SIZE) + + (( $iSmallLen % $this->_BIG_BLOCK_SIZE)? 1: 0)); + $iCnt = count($raList); + $iBdCnt = $this->_BIG_BLOCK_SIZE / PHPExcel_Shared_OLE::OLE_PPS_SIZE; + $iPPScnt = (floor($iCnt/$iBdCnt) + (($iCnt % $iBdCnt)? 1: 0)); + + return array($iSBDcnt, $iBBcnt, $iPPScnt); + } + + /** + * Helper function for caculating a magic value for block sizes + * + * @access public + * @param integer $i2 The argument + * @see save() + * @return integer + */ + private static function _adjust2($i2) + { + $iWk = log($i2)/log(2); + return ($iWk > floor($iWk))? floor($iWk)+1:$iWk; + } + + /** + * Save OLE header + * + * @access public + * @param integer $iSBDcnt + * @param integer $iBBcnt + * @param integer $iPPScnt + */ + public function _saveHeader($iSBDcnt, $iBBcnt, $iPPScnt) + { + $FILE = $this->_FILEH_; + + // Calculate Basic Setting + $iBlCnt = $this->_BIG_BLOCK_SIZE / PHPExcel_Shared_OLE::OLE_LONG_INT_SIZE; + $i1stBdL = ($this->_BIG_BLOCK_SIZE - 0x4C) / PHPExcel_Shared_OLE::OLE_LONG_INT_SIZE; + + $iBdExL = 0; + $iAll = $iBBcnt + $iPPScnt + $iSBDcnt; + $iAllW = $iAll; + $iBdCntW = floor($iAllW / $iBlCnt) + (($iAllW % $iBlCnt)? 1: 0); + $iBdCnt = floor(($iAll + $iBdCntW) / $iBlCnt) + ((($iAllW+$iBdCntW) % $iBlCnt)? 1: 0); + + // Calculate BD count + if ($iBdCnt > $i1stBdL) { + while (1) { + ++$iBdExL; + ++$iAllW; + $iBdCntW = floor($iAllW / $iBlCnt) + (($iAllW % $iBlCnt)? 1: 0); + $iBdCnt = floor(($iAllW + $iBdCntW) / $iBlCnt) + ((($iAllW+$iBdCntW) % $iBlCnt)? 1: 0); + if ($iBdCnt <= ($iBdExL*$iBlCnt+ $i1stBdL)) { + break; + } + } + } + + // Save Header + fwrite($FILE, + "\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1" + . "\x00\x00\x00\x00" + . "\x00\x00\x00\x00" + . "\x00\x00\x00\x00" + . "\x00\x00\x00\x00" + . pack("v", 0x3b) + . pack("v", 0x03) + . pack("v", -2) + . pack("v", 9) + . pack("v", 6) + . pack("v", 0) + . "\x00\x00\x00\x00" + . "\x00\x00\x00\x00" + . pack("V", $iBdCnt) + . pack("V", $iBBcnt+$iSBDcnt) //ROOT START + . pack("V", 0) + . pack("V", 0x1000) + . pack("V", $iSBDcnt ? 0 : -2) //Small Block Depot + . pack("V", $iSBDcnt) + ); + // Extra BDList Start, Count + if ($iBdCnt < $i1stBdL) { + fwrite($FILE, + pack("V", -2) // Extra BDList Start + . pack("V", 0) // Extra BDList Count + ); + } else { + fwrite($FILE, pack("V", $iAll+$iBdCnt) . pack("V", $iBdExL)); + } + + // BDList + for ($i = 0; $i < $i1stBdL && $i < $iBdCnt; ++$i) { + fwrite($FILE, pack("V", $iAll+$i)); + } + if ($i < $i1stBdL) { + $jB = $i1stBdL - $i; + for ($j = 0; $j < $jB; ++$j) { + fwrite($FILE, (pack("V", -1))); + } + } + } + + /** + * Saving big data (PPS's with data bigger than PHPExcel_Shared_OLE::OLE_DATA_SIZE_SMALL) + * + * @access public + * @param integer $iStBlk + * @param array &$raList Reference to array of PPS's + */ + public function _saveBigData($iStBlk, &$raList) + { + $FILE = $this->_FILEH_; + + // cycle through PPS's + $iCount = count($raList); + for ($i = 0; $i < $iCount; ++$i) { + if ($raList[$i]->Type != PHPExcel_Shared_OLE::OLE_PPS_TYPE_DIR) { + $raList[$i]->Size = $raList[$i]->_DataLen(); + if (($raList[$i]->Size >= PHPExcel_Shared_OLE::OLE_DATA_SIZE_SMALL) || + (($raList[$i]->Type == PHPExcel_Shared_OLE::OLE_PPS_TYPE_ROOT) && isset($raList[$i]->_data))) + { + // Write Data + //if (isset($raList[$i]->_PPS_FILE)) { + // $iLen = 0; + // fseek($raList[$i]->_PPS_FILE, 0); // To The Top + // while($sBuff = fread($raList[$i]->_PPS_FILE, 4096)) { + // $iLen += strlen($sBuff); + // fwrite($FILE, $sBuff); + // } + //} else { + fwrite($FILE, $raList[$i]->_data); + //} + + if ($raList[$i]->Size % $this->_BIG_BLOCK_SIZE) { + fwrite($FILE, str_repeat("\x00", $this->_BIG_BLOCK_SIZE - ($raList[$i]->Size % $this->_BIG_BLOCK_SIZE))); + } + // Set For PPS + $raList[$i]->_StartBlock = $iStBlk; + $iStBlk += + (floor($raList[$i]->Size / $this->_BIG_BLOCK_SIZE) + + (($raList[$i]->Size % $this->_BIG_BLOCK_SIZE)? 1: 0)); + } + // Close file for each PPS, and unlink it + //if (isset($raList[$i]->_PPS_FILE)) { + // fclose($raList[$i]->_PPS_FILE); + // $raList[$i]->_PPS_FILE = null; + // unlink($raList[$i]->_tmp_filename); + //} + } + } + } + + /** + * get small data (PPS's with data smaller than PHPExcel_Shared_OLE::OLE_DATA_SIZE_SMALL) + * + * @access public + * @param array &$raList Reference to array of PPS's + */ + public function _makeSmallData(&$raList) + { + $sRes = ''; + $FILE = $this->_FILEH_; + $iSmBlk = 0; + + $iCount = count($raList); + for ($i = 0; $i < $iCount; ++$i) { + // Make SBD, small data string + if ($raList[$i]->Type == PHPExcel_Shared_OLE::OLE_PPS_TYPE_FILE) { + if ($raList[$i]->Size <= 0) { + continue; + } + if ($raList[$i]->Size < PHPExcel_Shared_OLE::OLE_DATA_SIZE_SMALL) { + $iSmbCnt = floor($raList[$i]->Size / $this->_SMALL_BLOCK_SIZE) + + (($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE)? 1: 0); + // Add to SBD + $jB = $iSmbCnt - 1; + for ($j = 0; $j < $jB; ++$j) { + fwrite($FILE, pack("V", $j+$iSmBlk+1)); + } + fwrite($FILE, pack("V", -2)); + + //// Add to Data String(this will be written for RootEntry) + //if ($raList[$i]->_PPS_FILE) { + // fseek($raList[$i]->_PPS_FILE, 0); // To The Top + // while ($sBuff = fread($raList[$i]->_PPS_FILE, 4096)) { + // $sRes .= $sBuff; + // } + //} else { + $sRes .= $raList[$i]->_data; + //} + if ($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE) { + $sRes .= str_repeat("\x00",$this->_SMALL_BLOCK_SIZE - ($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE)); + } + // Set for PPS + $raList[$i]->_StartBlock = $iSmBlk; + $iSmBlk += $iSmbCnt; + } + } + } + $iSbCnt = floor($this->_BIG_BLOCK_SIZE / PHPExcel_Shared_OLE::OLE_LONG_INT_SIZE); + if ($iSmBlk % $iSbCnt) { + $iB = $iSbCnt - ($iSmBlk % $iSbCnt); + for ($i = 0; $i < $iB; ++$i) { + fwrite($FILE, pack("V", -1)); + } + } + return $sRes; + } + + /** + * Saves all the PPS's WKs + * + * @access public + * @param array $raList Reference to an array with all PPS's + */ + public function _savePps(&$raList) + { + // Save each PPS WK + $iC = count($raList); + for ($i = 0; $i < $iC; ++$i) { + fwrite($this->_FILEH_, $raList[$i]->_getPpsWk()); + } + // Adjust for Block + $iCnt = count($raList); + $iBCnt = $this->_BIG_BLOCK_SIZE / PHPExcel_Shared_OLE::OLE_PPS_SIZE; + if ($iCnt % $iBCnt) { + fwrite($this->_FILEH_, str_repeat("\x00",($iBCnt - ($iCnt % $iBCnt)) * PHPExcel_Shared_OLE::OLE_PPS_SIZE)); + } + } + + /** + * Saving Big Block Depot + * + * @access public + * @param integer $iSbdSize + * @param integer $iBsize + * @param integer $iPpsCnt + */ + public function _saveBbd($iSbdSize, $iBsize, $iPpsCnt) + { + $FILE = $this->_FILEH_; + // Calculate Basic Setting + $iBbCnt = $this->_BIG_BLOCK_SIZE / PHPExcel_Shared_OLE::OLE_LONG_INT_SIZE; + $i1stBdL = ($this->_BIG_BLOCK_SIZE - 0x4C) / PHPExcel_Shared_OLE::OLE_LONG_INT_SIZE; + + $iBdExL = 0; + $iAll = $iBsize + $iPpsCnt + $iSbdSize; + $iAllW = $iAll; + $iBdCntW = floor($iAllW / $iBbCnt) + (($iAllW % $iBbCnt)? 1: 0); + $iBdCnt = floor(($iAll + $iBdCntW) / $iBbCnt) + ((($iAllW+$iBdCntW) % $iBbCnt)? 1: 0); + // Calculate BD count + if ($iBdCnt >$i1stBdL) { + while (1) { + ++$iBdExL; + ++$iAllW; + $iBdCntW = floor($iAllW / $iBbCnt) + (($iAllW % $iBbCnt)? 1: 0); + $iBdCnt = floor(($iAllW + $iBdCntW) / $iBbCnt) + ((($iAllW+$iBdCntW) % $iBbCnt)? 1: 0); + if ($iBdCnt <= ($iBdExL*$iBbCnt+ $i1stBdL)) { + break; + } + } + } + + // Making BD + // Set for SBD + if ($iSbdSize > 0) { + for ($i = 0; $i < ($iSbdSize - 1); ++$i) { + fwrite($FILE, pack("V", $i+1)); + } + fwrite($FILE, pack("V", -2)); + } + // Set for B + for ($i = 0; $i < ($iBsize - 1); ++$i) { + fwrite($FILE, pack("V", $i+$iSbdSize+1)); + } + fwrite($FILE, pack("V", -2)); + + // Set for PPS + for ($i = 0; $i < ($iPpsCnt - 1); ++$i) { + fwrite($FILE, pack("V", $i+$iSbdSize+$iBsize+1)); + } + fwrite($FILE, pack("V", -2)); + // Set for BBD itself ( 0xFFFFFFFD : BBD) + for ($i = 0; $i < $iBdCnt; ++$i) { + fwrite($FILE, pack("V", 0xFFFFFFFD)); + } + // Set for ExtraBDList + for ($i = 0; $i < $iBdExL; ++$i) { + fwrite($FILE, pack("V", 0xFFFFFFFC)); + } + // Adjust for Block + if (($iAllW + $iBdCnt) % $iBbCnt) { + $iBlock = ($iBbCnt - (($iAllW + $iBdCnt) % $iBbCnt)); + for ($i = 0; $i < $iBlock; ++$i) { + fwrite($FILE, pack("V", -1)); + } + } + // Extra BDList + if ($iBdCnt > $i1stBdL) { + $iN=0; + $iNb=0; + for ($i = $i1stBdL;$i < $iBdCnt; $i++, ++$iN) { + if ($iN >= ($iBbCnt - 1)) { + $iN = 0; + ++$iNb; + fwrite($FILE, pack("V", $iAll+$iBdCnt+$iNb)); + } + fwrite($FILE, pack("V", $iBsize+$iSbdSize+$iPpsCnt+$i)); + } + if (($iBdCnt-$i1stBdL) % ($iBbCnt-1)) { + $iB = ($iBbCnt - 1) - (($iBdCnt - $i1stBdL) % ($iBbCnt - 1)); + for ($i = 0; $i < $iB; ++$i) { + fwrite($FILE, pack("V", -1)); + } + } + fwrite($FILE, pack("V", -2)); + } + } +} diff --git a/lib/phpexcel/PHPExcel/Shared/OLERead.php b/lib/phpexcel/PHPExcel/Shared/OLERead.php new file mode 100644 index 0000000..c4cb7da --- /dev/null +++ b/lib/phpexcel/PHPExcel/Shared/OLERead.php @@ -0,0 +1,317 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + +defined('IDENTIFIER_OLE') || + define('IDENTIFIER_OLE', pack('CCCCCCCC', 0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1)); + +class PHPExcel_Shared_OLERead { + private $data = ''; + + // OLE identifier + const IDENTIFIER_OLE = IDENTIFIER_OLE; + + // Size of a sector = 512 bytes + const BIG_BLOCK_SIZE = 0x200; + + // Size of a short sector = 64 bytes + const SMALL_BLOCK_SIZE = 0x40; + + // Size of a directory entry always = 128 bytes + const PROPERTY_STORAGE_BLOCK_SIZE = 0x80; + + // Minimum size of a standard stream = 4096 bytes, streams smaller than this are stored as short streams + const SMALL_BLOCK_THRESHOLD = 0x1000; + + // header offsets + const NUM_BIG_BLOCK_DEPOT_BLOCKS_POS = 0x2c; + const ROOT_START_BLOCK_POS = 0x30; + const SMALL_BLOCK_DEPOT_BLOCK_POS = 0x3c; + const EXTENSION_BLOCK_POS = 0x44; + const NUM_EXTENSION_BLOCK_POS = 0x48; + const BIG_BLOCK_DEPOT_BLOCKS_POS = 0x4c; + + // property storage offsets (directory offsets) + const SIZE_OF_NAME_POS = 0x40; + const TYPE_POS = 0x42; + const START_BLOCK_POS = 0x74; + const SIZE_POS = 0x78; + + + + public $wrkbook = null; + public $summaryInformation = null; + public $documentSummaryInformation = null; + + + /** + * Read the file + * + * @param $sFileName string Filename + * @throws PHPExcel_Reader_Exception + */ + public function read($sFileName) + { + // Check if file exists and is readable + if(!is_readable($sFileName)) { + throw new PHPExcel_Reader_Exception("Could not open " . $sFileName . " for reading! File does not exist, or it is not readable."); + } + + // Get the file identifier + // Don't bother reading the whole file until we know it's a valid OLE file + $this->data = file_get_contents($sFileName, FALSE, NULL, 0, 8); + + // Check OLE identifier + if ($this->data != self::IDENTIFIER_OLE) { + throw new PHPExcel_Reader_Exception('The filename ' . $sFileName . ' is not recognised as an OLE file'); + } + + // Get the file data + $this->data = file_get_contents($sFileName); + + // Total number of sectors used for the SAT + $this->numBigBlockDepotBlocks = self::_GetInt4d($this->data, self::NUM_BIG_BLOCK_DEPOT_BLOCKS_POS); + + // SecID of the first sector of the directory stream + $this->rootStartBlock = self::_GetInt4d($this->data, self::ROOT_START_BLOCK_POS); + + // SecID of the first sector of the SSAT (or -2 if not extant) + $this->sbdStartBlock = self::_GetInt4d($this->data, self::SMALL_BLOCK_DEPOT_BLOCK_POS); + + // SecID of the first sector of the MSAT (or -2 if no additional sectors are used) + $this->extensionBlock = self::_GetInt4d($this->data, self::EXTENSION_BLOCK_POS); + + // Total number of sectors used by MSAT + $this->numExtensionBlocks = self::_GetInt4d($this->data, self::NUM_EXTENSION_BLOCK_POS); + + $bigBlockDepotBlocks = array(); + $pos = self::BIG_BLOCK_DEPOT_BLOCKS_POS; + + $bbdBlocks = $this->numBigBlockDepotBlocks; + + if ($this->numExtensionBlocks != 0) { + $bbdBlocks = (self::BIG_BLOCK_SIZE - self::BIG_BLOCK_DEPOT_BLOCKS_POS)/4; + } + + for ($i = 0; $i < $bbdBlocks; ++$i) { + $bigBlockDepotBlocks[$i] = self::_GetInt4d($this->data, $pos); + $pos += 4; + } + + for ($j = 0; $j < $this->numExtensionBlocks; ++$j) { + $pos = ($this->extensionBlock + 1) * self::BIG_BLOCK_SIZE; + $blocksToRead = min($this->numBigBlockDepotBlocks - $bbdBlocks, self::BIG_BLOCK_SIZE / 4 - 1); + + for ($i = $bbdBlocks; $i < $bbdBlocks + $blocksToRead; ++$i) { + $bigBlockDepotBlocks[$i] = self::_GetInt4d($this->data, $pos); + $pos += 4; + } + + $bbdBlocks += $blocksToRead; + if ($bbdBlocks < $this->numBigBlockDepotBlocks) { + $this->extensionBlock = self::_GetInt4d($this->data, $pos); + } + } + + $pos = 0; + $this->bigBlockChain = ''; + $bbs = self::BIG_BLOCK_SIZE / 4; + for ($i = 0; $i < $this->numBigBlockDepotBlocks; ++$i) { + $pos = ($bigBlockDepotBlocks[$i] + 1) * self::BIG_BLOCK_SIZE; + + $this->bigBlockChain .= substr($this->data, $pos, 4*$bbs); + $pos += 4*$bbs; + } + + $pos = 0; + $sbdBlock = $this->sbdStartBlock; + $this->smallBlockChain = ''; + while ($sbdBlock != -2) { + $pos = ($sbdBlock + 1) * self::BIG_BLOCK_SIZE; + + $this->smallBlockChain .= substr($this->data, $pos, 4*$bbs); + $pos += 4*$bbs; + + $sbdBlock = self::_GetInt4d($this->bigBlockChain, $sbdBlock*4); + } + + // read the directory stream + $block = $this->rootStartBlock; + $this->entry = $this->_readData($block); + + $this->_readPropertySets(); + } + + /** + * Extract binary stream data + * + * @return string + */ + public function getStream($stream) + { + if ($stream === NULL) { + return null; + } + + $streamData = ''; + + if ($this->props[$stream]['size'] < self::SMALL_BLOCK_THRESHOLD) { + $rootdata = $this->_readData($this->props[$this->rootentry]['startBlock']); + + $block = $this->props[$stream]['startBlock']; + + while ($block != -2) { + $pos = $block * self::SMALL_BLOCK_SIZE; + $streamData .= substr($rootdata, $pos, self::SMALL_BLOCK_SIZE); + + $block = self::_GetInt4d($this->smallBlockChain, $block*4); + } + + return $streamData; + } else { + $numBlocks = $this->props[$stream]['size'] / self::BIG_BLOCK_SIZE; + if ($this->props[$stream]['size'] % self::BIG_BLOCK_SIZE != 0) { + ++$numBlocks; + } + + if ($numBlocks == 0) return ''; + + $block = $this->props[$stream]['startBlock']; + + while ($block != -2) { + $pos = ($block + 1) * self::BIG_BLOCK_SIZE; + $streamData .= substr($this->data, $pos, self::BIG_BLOCK_SIZE); + $block = self::_GetInt4d($this->bigBlockChain, $block*4); + } + + return $streamData; + } + } + + /** + * Read a standard stream (by joining sectors using information from SAT) + * + * @param int $bl Sector ID where the stream starts + * @return string Data for standard stream + */ + private function _readData($bl) + { + $block = $bl; + $data = ''; + + while ($block != -2) { + $pos = ($block + 1) * self::BIG_BLOCK_SIZE; + $data .= substr($this->data, $pos, self::BIG_BLOCK_SIZE); + $block = self::_GetInt4d($this->bigBlockChain, $block*4); + } + return $data; + } + + /** + * Read entries in the directory stream. + */ + private function _readPropertySets() { + $offset = 0; + + // loop through entires, each entry is 128 bytes + $entryLen = strlen($this->entry); + while ($offset < $entryLen) { + // entry data (128 bytes) + $d = substr($this->entry, $offset, self::PROPERTY_STORAGE_BLOCK_SIZE); + + // size in bytes of name + $nameSize = ord($d[self::SIZE_OF_NAME_POS]) | (ord($d[self::SIZE_OF_NAME_POS+1]) << 8); + + // type of entry + $type = ord($d[self::TYPE_POS]); + + // sectorID of first sector or short sector, if this entry refers to a stream (the case with workbook) + // sectorID of first sector of the short-stream container stream, if this entry is root entry + $startBlock = self::_GetInt4d($d, self::START_BLOCK_POS); + + $size = self::_GetInt4d($d, self::SIZE_POS); + + $name = str_replace("\x00", "", substr($d,0,$nameSize)); + + + $this->props[] = array ( + 'name' => $name, + 'type' => $type, + 'startBlock' => $startBlock, + 'size' => $size); + + // tmp helper to simplify checks + $upName = strtoupper($name); + + // Workbook directory entry (BIFF5 uses Book, BIFF8 uses Workbook) + if (($upName === 'WORKBOOK') || ($upName === 'BOOK')) { + $this->wrkbook = count($this->props) - 1; + } + else if ( $upName === 'ROOT ENTRY' || $upName === 'R') { + // Root entry + $this->rootentry = count($this->props) - 1; + } + + // Summary information + if ($name == chr(5) . 'SummaryInformation') { +// echo 'Summary Information<br />'; + $this->summaryInformation = count($this->props) - 1; + } + + // Additional Document Summary information + if ($name == chr(5) . 'DocumentSummaryInformation') { +// echo 'Document Summary Information<br />'; + $this->documentSummaryInformation = count($this->props) - 1; + } + + $offset += self::PROPERTY_STORAGE_BLOCK_SIZE; + } + + } + + /** + * Read 4 bytes of data at specified position + * + * @param string $data + * @param int $pos + * @return int + */ + private static function _GetInt4d($data, $pos) + { + // FIX: represent numbers correctly on 64-bit system + // http://sourceforge.net/tracker/index.php?func=detail&aid=1487372&group_id=99160&atid=623334 + // Hacked by Andreas Rehm 2006 to ensure correct result of the <<24 block on 32 and 64bit systems + $_or_24 = ord($data[$pos + 3]); + if ($_or_24 >= 128) { + // negative number + $_ord_24 = -abs((256 - $_or_24) << 24); + } else { + $_ord_24 = ($_or_24 & 127) << 24; + } + return ord($data[$pos]) | (ord($data[$pos + 1]) << 8) | (ord($data[$pos + 2]) << 16) | $_ord_24; + } + +} diff --git a/lib/phpexcel/PHPExcel/Shared/PCLZip/gnu-lgpl.txt b/lib/phpexcel/PHPExcel/Shared/PCLZip/gnu-lgpl.txt new file mode 100644 index 0000000..cbee875 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Shared/PCLZip/gnu-lgpl.txt @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + <one line to give the library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/lib/phpexcel/PHPExcel/Shared/PCLZip/pclzip.lib.php b/lib/phpexcel/PHPExcel/Shared/PCLZip/pclzip.lib.php new file mode 100644 index 0000000..4bf05a5 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Shared/PCLZip/pclzip.lib.php @@ -0,0 +1,5694 @@ +<?php +// -------------------------------------------------------------------------------- +// PhpConcept Library - Zip Module 2.8.2 +// -------------------------------------------------------------------------------- +// License GNU/LGPL - Vincent Blavet - August 2009 +// http://www.phpconcept.net +// -------------------------------------------------------------------------------- +// +// Presentation : +// PclZip is a PHP library that manage ZIP archives. +// So far tests show that archives generated by PclZip are readable by +// WinZip application and other tools. +// +// Description : +// See readme.txt and http://www.phpconcept.net +// +// Warning : +// This library and the associated files are non commercial, non professional +// work. +// It should not have unexpected results. However if any damage is caused by +// this software the author can not be responsible. +// The use of this software is at the risk of the user. +// +// -------------------------------------------------------------------------------- +// $Id: pclzip.lib.php,v 1.60 2009/09/30 21:01:04 vblavet Exp $ +// -------------------------------------------------------------------------------- + + // ----- Constants + if (!defined('PCLZIP_READ_BLOCK_SIZE')) { + define( 'PCLZIP_READ_BLOCK_SIZE', 2048 ); + } + + // ----- File list separator + // In version 1.x of PclZip, the separator for file list is a space + // (which is not a very smart choice, specifically for windows paths !). + // A better separator should be a comma (,). This constant gives you the + // abilty to change that. + // However notice that changing this value, may have impact on existing + // scripts, using space separated filenames. + // Recommanded values for compatibility with older versions : + //define( 'PCLZIP_SEPARATOR', ' ' ); + // Recommanded values for smart separation of filenames. + if (!defined('PCLZIP_SEPARATOR')) { + define( 'PCLZIP_SEPARATOR', ',' ); + } + + // ----- Error configuration + // 0 : PclZip Class integrated error handling + // 1 : PclError external library error handling. By enabling this + // you must ensure that you have included PclError library. + // [2,...] : reserved for futur use + if (!defined('PCLZIP_ERROR_EXTERNAL')) { + define( 'PCLZIP_ERROR_EXTERNAL', 0 ); + } + + // ----- Optional static temporary directory + // By default temporary files are generated in the script current + // path. + // If defined : + // - MUST BE terminated by a '/'. + // - MUST be a valid, already created directory + // Samples : + // define( 'PCLZIP_TEMPORARY_DIR', '/temp/' ); + // define( 'PCLZIP_TEMPORARY_DIR', 'C:/Temp/' ); + if (!defined('PCLZIP_TEMPORARY_DIR')) { + define( 'PCLZIP_TEMPORARY_DIR', '' ); + } + + // ----- Optional threshold ratio for use of temporary files + // Pclzip sense the size of the file to add/extract and decide to + // use or not temporary file. The algorythm is looking for + // memory_limit of PHP and apply a ratio. + // threshold = memory_limit * ratio. + // Recommended values are under 0.5. Default 0.47. + // Samples : + // define( 'PCLZIP_TEMPORARY_FILE_RATIO', 0.5 ); + if (!defined('PCLZIP_TEMPORARY_FILE_RATIO')) { + define( 'PCLZIP_TEMPORARY_FILE_RATIO', 0.47 ); + } + +// -------------------------------------------------------------------------------- +// ***** UNDER THIS LINE NOTHING NEEDS TO BE MODIFIED ***** +// -------------------------------------------------------------------------------- + + // ----- Global variables + $g_pclzip_version = "2.8.2"; + + // ----- Error codes + // -1 : Unable to open file in binary write mode + // -2 : Unable to open file in binary read mode + // -3 : Invalid parameters + // -4 : File does not exist + // -5 : Filename is too long (max. 255) + // -6 : Not a valid zip file + // -7 : Invalid extracted file size + // -8 : Unable to create directory + // -9 : Invalid archive extension + // -10 : Invalid archive format + // -11 : Unable to delete file (unlink) + // -12 : Unable to rename file (rename) + // -13 : Invalid header checksum + // -14 : Invalid archive size + define( 'PCLZIP_ERR_USER_ABORTED', 2 ); + define( 'PCLZIP_ERR_NO_ERROR', 0 ); + define( 'PCLZIP_ERR_WRITE_OPEN_FAIL', -1 ); + define( 'PCLZIP_ERR_READ_OPEN_FAIL', -2 ); + define( 'PCLZIP_ERR_INVALID_PARAMETER', -3 ); + define( 'PCLZIP_ERR_MISSING_FILE', -4 ); + define( 'PCLZIP_ERR_FILENAME_TOO_LONG', -5 ); + define( 'PCLZIP_ERR_INVALID_ZIP', -6 ); + define( 'PCLZIP_ERR_BAD_EXTRACTED_FILE', -7 ); + define( 'PCLZIP_ERR_DIR_CREATE_FAIL', -8 ); + define( 'PCLZIP_ERR_BAD_EXTENSION', -9 ); + define( 'PCLZIP_ERR_BAD_FORMAT', -10 ); + define( 'PCLZIP_ERR_DELETE_FILE_FAIL', -11 ); + define( 'PCLZIP_ERR_RENAME_FILE_FAIL', -12 ); + define( 'PCLZIP_ERR_BAD_CHECKSUM', -13 ); + define( 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', -14 ); + define( 'PCLZIP_ERR_MISSING_OPTION_VALUE', -15 ); + define( 'PCLZIP_ERR_INVALID_OPTION_VALUE', -16 ); + define( 'PCLZIP_ERR_ALREADY_A_DIRECTORY', -17 ); + define( 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', -18 ); + define( 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION', -19 ); + define( 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE', -20 ); + define( 'PCLZIP_ERR_DIRECTORY_RESTRICTION', -21 ); + + // ----- Options values + define( 'PCLZIP_OPT_PATH', 77001 ); + define( 'PCLZIP_OPT_ADD_PATH', 77002 ); + define( 'PCLZIP_OPT_REMOVE_PATH', 77003 ); + define( 'PCLZIP_OPT_REMOVE_ALL_PATH', 77004 ); + define( 'PCLZIP_OPT_SET_CHMOD', 77005 ); + define( 'PCLZIP_OPT_EXTRACT_AS_STRING', 77006 ); + define( 'PCLZIP_OPT_NO_COMPRESSION', 77007 ); + define( 'PCLZIP_OPT_BY_NAME', 77008 ); + define( 'PCLZIP_OPT_BY_INDEX', 77009 ); + define( 'PCLZIP_OPT_BY_EREG', 77010 ); + define( 'PCLZIP_OPT_BY_PREG', 77011 ); + define( 'PCLZIP_OPT_COMMENT', 77012 ); + define( 'PCLZIP_OPT_ADD_COMMENT', 77013 ); + define( 'PCLZIP_OPT_PREPEND_COMMENT', 77014 ); + define( 'PCLZIP_OPT_EXTRACT_IN_OUTPUT', 77015 ); + define( 'PCLZIP_OPT_REPLACE_NEWER', 77016 ); + define( 'PCLZIP_OPT_STOP_ON_ERROR', 77017 ); + // Having big trouble with crypt. Need to multiply 2 long int + // which is not correctly supported by PHP ... + //define( 'PCLZIP_OPT_CRYPT', 77018 ); + define( 'PCLZIP_OPT_EXTRACT_DIR_RESTRICTION', 77019 ); + define( 'PCLZIP_OPT_TEMP_FILE_THRESHOLD', 77020 ); + define( 'PCLZIP_OPT_ADD_TEMP_FILE_THRESHOLD', 77020 ); // alias + define( 'PCLZIP_OPT_TEMP_FILE_ON', 77021 ); + define( 'PCLZIP_OPT_ADD_TEMP_FILE_ON', 77021 ); // alias + define( 'PCLZIP_OPT_TEMP_FILE_OFF', 77022 ); + define( 'PCLZIP_OPT_ADD_TEMP_FILE_OFF', 77022 ); // alias + + // ----- File description attributes + define( 'PCLZIP_ATT_FILE_NAME', 79001 ); + define( 'PCLZIP_ATT_FILE_NEW_SHORT_NAME', 79002 ); + define( 'PCLZIP_ATT_FILE_NEW_FULL_NAME', 79003 ); + define( 'PCLZIP_ATT_FILE_MTIME', 79004 ); + define( 'PCLZIP_ATT_FILE_CONTENT', 79005 ); + define( 'PCLZIP_ATT_FILE_COMMENT', 79006 ); + + // ----- Call backs values + define( 'PCLZIP_CB_PRE_EXTRACT', 78001 ); + define( 'PCLZIP_CB_POST_EXTRACT', 78002 ); + define( 'PCLZIP_CB_PRE_ADD', 78003 ); + define( 'PCLZIP_CB_POST_ADD', 78004 ); + /* For futur use + define( 'PCLZIP_CB_PRE_LIST', 78005 ); + define( 'PCLZIP_CB_POST_LIST', 78006 ); + define( 'PCLZIP_CB_PRE_DELETE', 78007 ); + define( 'PCLZIP_CB_POST_DELETE', 78008 ); + */ + + // -------------------------------------------------------------------------------- + // Class : PclZip + // Description : + // PclZip is the class that represent a Zip archive. + // The public methods allow the manipulation of the archive. + // Attributes : + // Attributes must not be accessed directly. + // Methods : + // PclZip() : Object creator + // create() : Creates the Zip archive + // listContent() : List the content of the Zip archive + // extract() : Extract the content of the archive + // properties() : List the properties of the archive + // -------------------------------------------------------------------------------- + class PclZip + { + // ----- Filename of the zip file + var $zipname = ''; + + // ----- File descriptor of the zip file + var $zip_fd = 0; + + // ----- Internal error handling + var $error_code = 1; + var $error_string = ''; + + // ----- Current status of the magic_quotes_runtime + // This value store the php configuration for magic_quotes + // The class can then disable the magic_quotes and reset it after + var $magic_quotes_status; + + // -------------------------------------------------------------------------------- + // Function : PclZip() + // Description : + // Creates a PclZip object and set the name of the associated Zip archive + // filename. + // Note that no real action is taken, if the archive does not exist it is not + // created. Use create() for that. + // -------------------------------------------------------------------------------- + function PclZip($p_zipname) + { + + // ----- Tests the zlib + if (!function_exists('gzopen')) + { + die('Abort '.basename(__FILE__).' : Missing zlib extensions'); + } + + // ----- Set the attributes + $this->zipname = $p_zipname; + $this->zip_fd = 0; + $this->magic_quotes_status = -1; + + // ----- Return + return; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : + // create($p_filelist, $p_add_dir="", $p_remove_dir="") + // create($p_filelist, $p_option, $p_option_value, ...) + // Description : + // This method supports two different synopsis. The first one is historical. + // This method creates a Zip Archive. The Zip file is created in the + // filesystem. The files and directories indicated in $p_filelist + // are added in the archive. See the parameters description for the + // supported format of $p_filelist. + // When a directory is in the list, the directory and its content is added + // in the archive. + // In this synopsis, the function takes an optional variable list of + // options. See bellow the supported options. + // Parameters : + // $p_filelist : An array containing file or directory names, or + // a string containing one filename or one directory name, or + // a string containing a list of filenames and/or directory + // names separated by spaces. + // $p_add_dir : A path to add before the real path of the archived file, + // in order to have it memorized in the archive. + // $p_remove_dir : A path to remove from the real path of the file to archive, + // in order to have a shorter path memorized in the archive. + // When $p_add_dir and $p_remove_dir are set, $p_remove_dir + // is removed first, before $p_add_dir is added. + // Options : + // PCLZIP_OPT_ADD_PATH : + // PCLZIP_OPT_REMOVE_PATH : + // PCLZIP_OPT_REMOVE_ALL_PATH : + // PCLZIP_OPT_COMMENT : + // PCLZIP_CB_PRE_ADD : + // PCLZIP_CB_POST_ADD : + // Return Values : + // 0 on failure, + // The list of the added files, with a status of the add action. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + function create($p_filelist) + { + $v_result=1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Set default values + $v_options = array(); + $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE; + + // ----- Look for variable options arguments + $v_size = func_num_args(); + + // ----- Look for arguments + if ($v_size > 1) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Remove from the options list the first argument + array_shift($v_arg_list); + $v_size--; + + // ----- Look for first arg + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { + + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, + array (PCLZIP_OPT_REMOVE_PATH => 'optional', + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', + PCLZIP_OPT_ADD_PATH => 'optional', + PCLZIP_CB_PRE_ADD => 'optional', + PCLZIP_CB_POST_ADD => 'optional', + PCLZIP_OPT_NO_COMPRESSION => 'optional', + PCLZIP_OPT_COMMENT => 'optional', + PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', + PCLZIP_OPT_TEMP_FILE_ON => 'optional', + PCLZIP_OPT_TEMP_FILE_OFF => 'optional' + //, PCLZIP_OPT_CRYPT => 'optional' + )); + if ($v_result != 1) { + return 0; + } + } + + // ----- Look for 2 args + // Here we need to support the first historic synopsis of the + // method. + else { + + // ----- Get the first argument + $v_options[PCLZIP_OPT_ADD_PATH] = $v_arg_list[0]; + + // ----- Look for the optional second argument + if ($v_size == 2) { + $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1]; + } + else if ($v_size > 2) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, + "Invalid number / type of arguments"); + return 0; + } + } + } + + // ----- Look for default option values + $this->privOptionDefaultThreshold($v_options); + + // ----- Init + $v_string_list = array(); + $v_att_list = array(); + $v_filedescr_list = array(); + $p_result_list = array(); + + // ----- Look if the $p_filelist is really an array + if (is_array($p_filelist)) { + + // ----- Look if the first element is also an array + // This will mean that this is a file description entry + if (isset($p_filelist[0]) && is_array($p_filelist[0])) { + $v_att_list = $p_filelist; + } + + // ----- The list is a list of string names + else { + $v_string_list = $p_filelist; + } + } + + // ----- Look if the $p_filelist is a string + else if (is_string($p_filelist)) { + // ----- Create a list from the string + $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist); + } + + // ----- Invalid variable type for $p_filelist + else { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist"); + return 0; + } + + // ----- Reformat the string list + if (sizeof($v_string_list) != 0) { + foreach ($v_string_list as $v_string) { + if ($v_string != '') { + $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string; + } + else { + } + } + } + + // ----- For each file in the list check the attributes + $v_supported_attributes + = array ( PCLZIP_ATT_FILE_NAME => 'mandatory' + ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional' + ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional' + ,PCLZIP_ATT_FILE_MTIME => 'optional' + ,PCLZIP_ATT_FILE_CONTENT => 'optional' + ,PCLZIP_ATT_FILE_COMMENT => 'optional' + ); + foreach ($v_att_list as $v_entry) { + $v_result = $this->privFileDescrParseAtt($v_entry, + $v_filedescr_list[], + $v_options, + $v_supported_attributes); + if ($v_result != 1) { + return 0; + } + } + + // ----- Expand the filelist (expand directories) + $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options); + if ($v_result != 1) { + return 0; + } + + // ----- Call the create fct + $v_result = $this->privCreate($v_filedescr_list, $p_result_list, $v_options); + if ($v_result != 1) { + return 0; + } + + // ----- Return + return $p_result_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : + // add($p_filelist, $p_add_dir="", $p_remove_dir="") + // add($p_filelist, $p_option, $p_option_value, ...) + // Description : + // This method supports two synopsis. The first one is historical. + // This methods add the list of files in an existing archive. + // If a file with the same name already exists, it is added at the end of the + // archive, the first one is still present. + // If the archive does not exist, it is created. + // Parameters : + // $p_filelist : An array containing file or directory names, or + // a string containing one filename or one directory name, or + // a string containing a list of filenames and/or directory + // names separated by spaces. + // $p_add_dir : A path to add before the real path of the archived file, + // in order to have it memorized in the archive. + // $p_remove_dir : A path to remove from the real path of the file to archive, + // in order to have a shorter path memorized in the archive. + // When $p_add_dir and $p_remove_dir are set, $p_remove_dir + // is removed first, before $p_add_dir is added. + // Options : + // PCLZIP_OPT_ADD_PATH : + // PCLZIP_OPT_REMOVE_PATH : + // PCLZIP_OPT_REMOVE_ALL_PATH : + // PCLZIP_OPT_COMMENT : + // PCLZIP_OPT_ADD_COMMENT : + // PCLZIP_OPT_PREPEND_COMMENT : + // PCLZIP_CB_PRE_ADD : + // PCLZIP_CB_POST_ADD : + // Return Values : + // 0 on failure, + // The list of the added files, with a status of the add action. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + function add($p_filelist) + { + $v_result=1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Set default values + $v_options = array(); + $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE; + + // ----- Look for variable options arguments + $v_size = func_num_args(); + + // ----- Look for arguments + if ($v_size > 1) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Remove form the options list the first argument + array_shift($v_arg_list); + $v_size--; + + // ----- Look for first arg + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { + + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, + array (PCLZIP_OPT_REMOVE_PATH => 'optional', + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', + PCLZIP_OPT_ADD_PATH => 'optional', + PCLZIP_CB_PRE_ADD => 'optional', + PCLZIP_CB_POST_ADD => 'optional', + PCLZIP_OPT_NO_COMPRESSION => 'optional', + PCLZIP_OPT_COMMENT => 'optional', + PCLZIP_OPT_ADD_COMMENT => 'optional', + PCLZIP_OPT_PREPEND_COMMENT => 'optional', + PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', + PCLZIP_OPT_TEMP_FILE_ON => 'optional', + PCLZIP_OPT_TEMP_FILE_OFF => 'optional' + //, PCLZIP_OPT_CRYPT => 'optional' + )); + if ($v_result != 1) { + return 0; + } + } + + // ----- Look for 2 args + // Here we need to support the first historic synopsis of the + // method. + else { + + // ----- Get the first argument + $v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0]; + + // ----- Look for the optional second argument + if ($v_size == 2) { + $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1]; + } + else if ($v_size > 2) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); + + // ----- Return + return 0; + } + } + } + + // ----- Look for default option values + $this->privOptionDefaultThreshold($v_options); + + // ----- Init + $v_string_list = array(); + $v_att_list = array(); + $v_filedescr_list = array(); + $p_result_list = array(); + + // ----- Look if the $p_filelist is really an array + if (is_array($p_filelist)) { + + // ----- Look if the first element is also an array + // This will mean that this is a file description entry + if (isset($p_filelist[0]) && is_array($p_filelist[0])) { + $v_att_list = $p_filelist; + } + + // ----- The list is a list of string names + else { + $v_string_list = $p_filelist; + } + } + + // ----- Look if the $p_filelist is a string + else if (is_string($p_filelist)) { + // ----- Create a list from the string + $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist); + } + + // ----- Invalid variable type for $p_filelist + else { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type '".gettype($p_filelist)."' for p_filelist"); + return 0; + } + + // ----- Reformat the string list + if (sizeof($v_string_list) != 0) { + foreach ($v_string_list as $v_string) { + $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string; + } + } + + // ----- For each file in the list check the attributes + $v_supported_attributes + = array ( PCLZIP_ATT_FILE_NAME => 'mandatory' + ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional' + ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional' + ,PCLZIP_ATT_FILE_MTIME => 'optional' + ,PCLZIP_ATT_FILE_CONTENT => 'optional' + ,PCLZIP_ATT_FILE_COMMENT => 'optional' + ); + foreach ($v_att_list as $v_entry) { + $v_result = $this->privFileDescrParseAtt($v_entry, + $v_filedescr_list[], + $v_options, + $v_supported_attributes); + if ($v_result != 1) { + return 0; + } + } + + // ----- Expand the filelist (expand directories) + $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options); + if ($v_result != 1) { + return 0; + } + + // ----- Call the create fct + $v_result = $this->privAdd($v_filedescr_list, $p_result_list, $v_options); + if ($v_result != 1) { + return 0; + } + + // ----- Return + return $p_result_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : listContent() + // Description : + // This public method, gives the list of the files and directories, with their + // properties. + // The properties of each entries in the list are (used also in other functions) : + // filename : Name of the file. For a create or add action it is the filename + // given by the user. For an extract function it is the filename + // of the extracted file. + // stored_filename : Name of the file / directory stored in the archive. + // size : Size of the stored file. + // compressed_size : Size of the file's data compressed in the archive + // (without the headers overhead) + // mtime : Last known modification date of the file (UNIX timestamp) + // comment : Comment associated with the file + // folder : true | false + // index : index of the file in the archive + // status : status of the action (depending of the action) : + // Values are : + // ok : OK ! + // filtered : the file / dir is not extracted (filtered by user) + // already_a_directory : the file can not be extracted because a + // directory with the same name already exists + // write_protected : the file can not be extracted because a file + // with the same name already exists and is + // write protected + // newer_exist : the file was not extracted because a newer file exists + // path_creation_fail : the file is not extracted because the folder + // does not exist and can not be created + // write_error : the file was not extracted because there was a + // error while writing the file + // read_error : the file was not extracted because there was a error + // while reading the file + // invalid_header : the file was not extracted because of an archive + // format error (bad file header) + // Note that each time a method can continue operating when there + // is an action error on a file, the error is only logged in the file status. + // Return Values : + // 0 on an unrecoverable failure, + // The list of the files in the archive. + // -------------------------------------------------------------------------------- + function listContent() + { + $v_result=1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Check archive + if (!$this->privCheckFormat()) { + return(0); + } + + // ----- Call the extracting fct + $p_list = array(); + if (($v_result = $this->privList($p_list)) != 1) + { + unset($p_list); + return(0); + } + + // ----- Return + return $p_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : + // extract($p_path="./", $p_remove_path="") + // extract([$p_option, $p_option_value, ...]) + // Description : + // This method supports two synopsis. The first one is historical. + // This method extract all the files / directories from the archive to the + // folder indicated in $p_path. + // If you want to ignore the 'root' part of path of the memorized files + // you can indicate this in the optional $p_remove_path parameter. + // By default, if a newer file with the same name already exists, the + // file is not extracted. + // + // If both PCLZIP_OPT_PATH and PCLZIP_OPT_ADD_PATH aoptions + // are used, the path indicated in PCLZIP_OPT_ADD_PATH is append + // at the end of the path value of PCLZIP_OPT_PATH. + // Parameters : + // $p_path : Path where the files and directories are to be extracted + // $p_remove_path : First part ('root' part) of the memorized path + // (if any similar) to remove while extracting. + // Options : + // PCLZIP_OPT_PATH : + // PCLZIP_OPT_ADD_PATH : + // PCLZIP_OPT_REMOVE_PATH : + // PCLZIP_OPT_REMOVE_ALL_PATH : + // PCLZIP_CB_PRE_EXTRACT : + // PCLZIP_CB_POST_EXTRACT : + // Return Values : + // 0 or a negative value on failure, + // The list of the extracted files, with a status of the action. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + function extract() + { + $v_result=1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Check archive + if (!$this->privCheckFormat()) { + return(0); + } + + // ----- Set default values + $v_options = array(); +// $v_path = "./"; + $v_path = ''; + $v_remove_path = ""; + $v_remove_all_path = false; + + // ----- Look for variable options arguments + $v_size = func_num_args(); + + // ----- Default values for option + $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; + + // ----- Look for arguments + if ($v_size > 0) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Look for first arg + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { + + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, + array (PCLZIP_OPT_PATH => 'optional', + PCLZIP_OPT_REMOVE_PATH => 'optional', + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', + PCLZIP_OPT_ADD_PATH => 'optional', + PCLZIP_CB_PRE_EXTRACT => 'optional', + PCLZIP_CB_POST_EXTRACT => 'optional', + PCLZIP_OPT_SET_CHMOD => 'optional', + PCLZIP_OPT_BY_NAME => 'optional', + PCLZIP_OPT_BY_EREG => 'optional', + PCLZIP_OPT_BY_PREG => 'optional', + PCLZIP_OPT_BY_INDEX => 'optional', + PCLZIP_OPT_EXTRACT_AS_STRING => 'optional', + PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional', + PCLZIP_OPT_REPLACE_NEWER => 'optional' + ,PCLZIP_OPT_STOP_ON_ERROR => 'optional' + ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional', + PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', + PCLZIP_OPT_TEMP_FILE_ON => 'optional', + PCLZIP_OPT_TEMP_FILE_OFF => 'optional' + )); + if ($v_result != 1) { + return 0; + } + + // ----- Set the arguments + if (isset($v_options[PCLZIP_OPT_PATH])) { + $v_path = $v_options[PCLZIP_OPT_PATH]; + } + if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) { + $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH]; + } + if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { + $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH]; + } + if (isset($v_options[PCLZIP_OPT_ADD_PATH])) { + // ----- Check for '/' in last path char + if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) { + $v_path .= '/'; + } + $v_path .= $v_options[PCLZIP_OPT_ADD_PATH]; + } + } + + // ----- Look for 2 args + // Here we need to support the first historic synopsis of the + // method. + else { + + // ----- Get the first argument + $v_path = $v_arg_list[0]; + + // ----- Look for the optional second argument + if ($v_size == 2) { + $v_remove_path = $v_arg_list[1]; + } + else if ($v_size > 2) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); + + // ----- Return + return 0; + } + } + } + + // ----- Look for default option values + $this->privOptionDefaultThreshold($v_options); + + // ----- Trace + + // ----- Call the extracting fct + $p_list = array(); + $v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, + $v_remove_all_path, $v_options); + if ($v_result < 1) { + unset($p_list); + return(0); + } + + // ----- Return + return $p_list; + } + // -------------------------------------------------------------------------------- + + + // -------------------------------------------------------------------------------- + // Function : + // extractByIndex($p_index, $p_path="./", $p_remove_path="") + // extractByIndex($p_index, [$p_option, $p_option_value, ...]) + // Description : + // This method supports two synopsis. The first one is historical. + // This method is doing a partial extract of the archive. + // The extracted files or folders are identified by their index in the + // archive (from 0 to n). + // Note that if the index identify a folder, only the folder entry is + // extracted, not all the files included in the archive. + // Parameters : + // $p_index : A single index (integer) or a string of indexes of files to + // extract. The form of the string is "0,4-6,8-12" with only numbers + // and '-' for range or ',' to separate ranges. No spaces or ';' + // are allowed. + // $p_path : Path where the files and directories are to be extracted + // $p_remove_path : First part ('root' part) of the memorized path + // (if any similar) to remove while extracting. + // Options : + // PCLZIP_OPT_PATH : + // PCLZIP_OPT_ADD_PATH : + // PCLZIP_OPT_REMOVE_PATH : + // PCLZIP_OPT_REMOVE_ALL_PATH : + // PCLZIP_OPT_EXTRACT_AS_STRING : The files are extracted as strings and + // not as files. + // The resulting content is in a new field 'content' in the file + // structure. + // This option must be used alone (any other options are ignored). + // PCLZIP_CB_PRE_EXTRACT : + // PCLZIP_CB_POST_EXTRACT : + // Return Values : + // 0 on failure, + // The list of the extracted files, with a status of the action. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + //function extractByIndex($p_index, options...) + function extractByIndex($p_index) + { + $v_result=1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Check archive + if (!$this->privCheckFormat()) { + return(0); + } + + // ----- Set default values + $v_options = array(); +// $v_path = "./"; + $v_path = ''; + $v_remove_path = ""; + $v_remove_all_path = false; + + // ----- Look for variable options arguments + $v_size = func_num_args(); + + // ----- Default values for option + $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; + + // ----- Look for arguments + if ($v_size > 1) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Remove form the options list the first argument + array_shift($v_arg_list); + $v_size--; + + // ----- Look for first arg + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { + + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, + array (PCLZIP_OPT_PATH => 'optional', + PCLZIP_OPT_REMOVE_PATH => 'optional', + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', + PCLZIP_OPT_EXTRACT_AS_STRING => 'optional', + PCLZIP_OPT_ADD_PATH => 'optional', + PCLZIP_CB_PRE_EXTRACT => 'optional', + PCLZIP_CB_POST_EXTRACT => 'optional', + PCLZIP_OPT_SET_CHMOD => 'optional', + PCLZIP_OPT_REPLACE_NEWER => 'optional' + ,PCLZIP_OPT_STOP_ON_ERROR => 'optional' + ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional', + PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', + PCLZIP_OPT_TEMP_FILE_ON => 'optional', + PCLZIP_OPT_TEMP_FILE_OFF => 'optional' + )); + if ($v_result != 1) { + return 0; + } + + // ----- Set the arguments + if (isset($v_options[PCLZIP_OPT_PATH])) { + $v_path = $v_options[PCLZIP_OPT_PATH]; + } + if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) { + $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH]; + } + if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { + $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH]; + } + if (isset($v_options[PCLZIP_OPT_ADD_PATH])) { + // ----- Check for '/' in last path char + if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) { + $v_path .= '/'; + } + $v_path .= $v_options[PCLZIP_OPT_ADD_PATH]; + } + if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) { + $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; + } + else { + } + } + + // ----- Look for 2 args + // Here we need to support the first historic synopsis of the + // method. + else { + + // ----- Get the first argument + $v_path = $v_arg_list[0]; + + // ----- Look for the optional second argument + if ($v_size == 2) { + $v_remove_path = $v_arg_list[1]; + } + else if ($v_size > 2) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); + + // ----- Return + return 0; + } + } + } + + // ----- Trace + + // ----- Trick + // Here I want to reuse extractByRule(), so I need to parse the $p_index + // with privParseOptions() + $v_arg_trick = array (PCLZIP_OPT_BY_INDEX, $p_index); + $v_options_trick = array(); + $v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick, + array (PCLZIP_OPT_BY_INDEX => 'optional' )); + if ($v_result != 1) { + return 0; + } + $v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX]; + + // ----- Look for default option values + $this->privOptionDefaultThreshold($v_options); + + // ----- Call the extracting fct + if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) { + return(0); + } + + // ----- Return + return $p_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : + // delete([$p_option, $p_option_value, ...]) + // Description : + // This method removes files from the archive. + // If no parameters are given, then all the archive is emptied. + // Parameters : + // None or optional arguments. + // Options : + // PCLZIP_OPT_BY_INDEX : + // PCLZIP_OPT_BY_NAME : + // PCLZIP_OPT_BY_EREG : + // PCLZIP_OPT_BY_PREG : + // Return Values : + // 0 on failure, + // The list of the files which are still present in the archive. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + function delete() + { + $v_result=1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Check archive + if (!$this->privCheckFormat()) { + return(0); + } + + // ----- Set default values + $v_options = array(); + + // ----- Look for variable options arguments + $v_size = func_num_args(); + + // ----- Look for arguments + if ($v_size > 0) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, + array (PCLZIP_OPT_BY_NAME => 'optional', + PCLZIP_OPT_BY_EREG => 'optional', + PCLZIP_OPT_BY_PREG => 'optional', + PCLZIP_OPT_BY_INDEX => 'optional' )); + if ($v_result != 1) { + return 0; + } + } + + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); + + // ----- Call the delete fct + $v_list = array(); + if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) { + $this->privSwapBackMagicQuotes(); + unset($v_list); + return(0); + } + + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : deleteByIndex() + // Description : + // ***** Deprecated ***** + // delete(PCLZIP_OPT_BY_INDEX, $p_index) should be prefered. + // -------------------------------------------------------------------------------- + function deleteByIndex($p_index) + { + + $p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index); + + // ----- Return + return $p_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : properties() + // Description : + // This method gives the properties of the archive. + // The properties are : + // nb : Number of files in the archive + // comment : Comment associated with the archive file + // status : not_exist, ok + // Parameters : + // None + // Return Values : + // 0 on failure, + // An array with the archive properties. + // -------------------------------------------------------------------------------- + function properties() + { + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); + + // ----- Check archive + if (!$this->privCheckFormat()) { + $this->privSwapBackMagicQuotes(); + return(0); + } + + // ----- Default properties + $v_prop = array(); + $v_prop['comment'] = ''; + $v_prop['nb'] = 0; + $v_prop['status'] = 'not_exist'; + + // ----- Look if file exists + if (@is_file($this->zipname)) + { + // ----- Open the zip file + if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0) + { + $this->privSwapBackMagicQuotes(); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode'); + + // ----- Return + return 0; + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) + { + $this->privSwapBackMagicQuotes(); + return 0; + } + + // ----- Close the zip file + $this->privCloseFd(); + + // ----- Set the user attributes + $v_prop['comment'] = $v_central_dir['comment']; + $v_prop['nb'] = $v_central_dir['entries']; + $v_prop['status'] = 'ok'; + } + + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_prop; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : duplicate() + // Description : + // This method creates an archive by copying the content of an other one. If + // the archive already exist, it is replaced by the new one without any warning. + // Parameters : + // $p_archive : The filename of a valid archive, or + // a valid PclZip object. + // Return Values : + // 1 on success. + // 0 or a negative value on error (error code). + // -------------------------------------------------------------------------------- + function duplicate($p_archive) + { + $v_result = 1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Look if the $p_archive is a PclZip object + if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip')) + { + + // ----- Duplicate the archive + $v_result = $this->privDuplicate($p_archive->zipname); + } + + // ----- Look if the $p_archive is a string (so a filename) + else if (is_string($p_archive)) + { + + // ----- Check that $p_archive is a valid zip file + // TBC : Should also check the archive format + if (!is_file($p_archive)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '".$p_archive."'"); + $v_result = PCLZIP_ERR_MISSING_FILE; + } + else { + // ----- Duplicate the archive + $v_result = $this->privDuplicate($p_archive); + } + } + + // ----- Invalid variable + else + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add"); + $v_result = PCLZIP_ERR_INVALID_PARAMETER; + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : merge() + // Description : + // This method merge the $p_archive_to_add archive at the end of the current + // one ($this). + // If the archive ($this) does not exist, the merge becomes a duplicate. + // If the $p_archive_to_add archive does not exist, the merge is a success. + // Parameters : + // $p_archive_to_add : It can be directly the filename of a valid zip archive, + // or a PclZip object archive. + // Return Values : + // 1 on success, + // 0 or negative values on error (see below). + // -------------------------------------------------------------------------------- + function merge($p_archive_to_add) + { + $v_result = 1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Check archive + if (!$this->privCheckFormat()) { + return(0); + } + + // ----- Look if the $p_archive_to_add is a PclZip object + if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip')) + { + + // ----- Merge the archive + $v_result = $this->privMerge($p_archive_to_add); + } + + // ----- Look if the $p_archive_to_add is a string (so a filename) + else if (is_string($p_archive_to_add)) + { + + // ----- Create a temporary archive + $v_object_archive = new PclZip($p_archive_to_add); + + // ----- Merge the archive + $v_result = $this->privMerge($v_object_archive); + } + + // ----- Invalid variable + else + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add"); + $v_result = PCLZIP_ERR_INVALID_PARAMETER; + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + + + // -------------------------------------------------------------------------------- + // Function : errorCode() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function errorCode() + { + if (PCLZIP_ERROR_EXTERNAL == 1) { + return(PclErrorCode()); + } + else { + return($this->error_code); + } + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : errorName() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function errorName($p_with_code=false) + { + $v_name = array ( PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR', + PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL', + PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL', + PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER', + PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE', + PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG', + PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP', + PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE', + PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL', + PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION', + PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT', + PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL', + PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL', + PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM', + PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', + PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE', + PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE', + PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', + PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION' + ,PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE => 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE' + ,PCLZIP_ERR_DIRECTORY_RESTRICTION => 'PCLZIP_ERR_DIRECTORY_RESTRICTION' + ); + + if (isset($v_name[$this->error_code])) { + $v_value = $v_name[$this->error_code]; + } + else { + $v_value = 'NoName'; + } + + if ($p_with_code) { + return($v_value.' ('.$this->error_code.')'); + } + else { + return($v_value); + } + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : errorInfo() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function errorInfo($p_full=false) + { + if (PCLZIP_ERROR_EXTERNAL == 1) { + return(PclErrorString()); + } + else { + if ($p_full) { + return($this->errorName(true)." : ".$this->error_string); + } + else { + return($this->error_string." [code ".$this->error_code."]"); + } + } + } + // -------------------------------------------------------------------------------- + + +// -------------------------------------------------------------------------------- +// ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS ***** +// ***** ***** +// ***** THESES FUNCTIONS MUST NOT BE USED DIRECTLY ***** +// -------------------------------------------------------------------------------- + + + + // -------------------------------------------------------------------------------- + // Function : privCheckFormat() + // Description : + // This method check that the archive exists and is a valid zip archive. + // Several level of check exists. (futur) + // Parameters : + // $p_level : Level of check. Default 0. + // 0 : Check the first bytes (magic codes) (default value)) + // 1 : 0 + Check the central directory (futur) + // 2 : 1 + Check each file header (futur) + // Return Values : + // true on success, + // false on error, the error code is set. + // -------------------------------------------------------------------------------- + function privCheckFormat($p_level=0) + { + $v_result = true; + + // ----- Reset the file system cache + clearstatcache(); + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Look if the file exits + if (!is_file($this->zipname)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '".$this->zipname."'"); + return(false); + } + + // ----- Check that the file is readeable + if (!is_readable($this->zipname)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '".$this->zipname."'"); + return(false); + } + + // ----- Check the magic code + // TBC + + // ----- Check the central header + // TBC + + // ----- Check each file header + // TBC + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privParseOptions() + // Description : + // This internal methods reads the variable list of arguments ($p_options_list, + // $p_size) and generate an array with the options and values ($v_result_list). + // $v_requested_options contains the options that can be present and those that + // must be present. + // $v_requested_options is an array, with the option value as key, and 'optional', + // or 'mandatory' as value. + // Parameters : + // See above. + // Return Values : + // 1 on success. + // 0 on failure. + // -------------------------------------------------------------------------------- + function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options=false) + { + $v_result=1; + + // ----- Read the options + $i=0; + while ($i<$p_size) { + + // ----- Check if the option is supported + if (!isset($v_requested_options[$p_options_list[$i]])) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid optional parameter '".$p_options_list[$i]."' for this method"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Look for next option + switch ($p_options_list[$i]) { + // ----- Look for options that request a path value + case PCLZIP_OPT_PATH : + case PCLZIP_OPT_REMOVE_PATH : + case PCLZIP_OPT_ADD_PATH : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE); + $i++; + break; + + case PCLZIP_OPT_TEMP_FILE_THRESHOLD : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + return PclZip::errorCode(); + } + + // ----- Check for incompatible options + if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'"); + return PclZip::errorCode(); + } + + // ----- Check the value + $v_value = $p_options_list[$i+1]; + if ((!is_integer($v_value)) || ($v_value<0)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Integer expected for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + return PclZip::errorCode(); + } + + // ----- Get the value (and convert it in bytes) + $v_result_list[$p_options_list[$i]] = $v_value*1048576; + $i++; + break; + + case PCLZIP_OPT_TEMP_FILE_ON : + // ----- Check for incompatible options + if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'"); + return PclZip::errorCode(); + } + + $v_result_list[$p_options_list[$i]] = true; + break; + + case PCLZIP_OPT_TEMP_FILE_OFF : + // ----- Check for incompatible options + if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_ON])) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_ON'"); + return PclZip::errorCode(); + } + // ----- Check for incompatible options + if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_THRESHOLD'"); + return PclZip::errorCode(); + } + + $v_result_list[$p_options_list[$i]] = true; + break; + + case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + if ( is_string($p_options_list[$i+1]) + && ($p_options_list[$i+1] != '')) { + $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE); + $i++; + } + else { + } + break; + + // ----- Look for options that request an array of string for value + case PCLZIP_OPT_BY_NAME : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + if (is_string($p_options_list[$i+1])) { + $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i+1]; + } + else if (is_array($p_options_list[$i+1])) { + $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; + } + else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + $i++; + break; + + // ----- Look for options that request an EREG or PREG expression + case PCLZIP_OPT_BY_EREG : + // ereg() is deprecated starting with PHP 5.3. Move PCLZIP_OPT_BY_EREG + // to PCLZIP_OPT_BY_PREG + $p_options_list[$i] = PCLZIP_OPT_BY_PREG; + case PCLZIP_OPT_BY_PREG : + //case PCLZIP_OPT_CRYPT : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + if (is_string($p_options_list[$i+1])) { + $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; + } + else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + $i++; + break; + + // ----- Look for options that takes a string + case PCLZIP_OPT_COMMENT : + case PCLZIP_OPT_ADD_COMMENT : + case PCLZIP_OPT_PREPEND_COMMENT : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, + "Missing parameter value for option '" + .PclZipUtilOptionText($p_options_list[$i]) + ."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + if (is_string($p_options_list[$i+1])) { + $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; + } + else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, + "Wrong parameter value for option '" + .PclZipUtilOptionText($p_options_list[$i]) + ."'"); + + // ----- Return + return PclZip::errorCode(); + } + $i++; + break; + + // ----- Look for options that request an array of index + case PCLZIP_OPT_BY_INDEX : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + $v_work_list = array(); + if (is_string($p_options_list[$i+1])) { + + // ----- Remove spaces + $p_options_list[$i+1] = strtr($p_options_list[$i+1], ' ', ''); + + // ----- Parse items + $v_work_list = explode(",", $p_options_list[$i+1]); + } + else if (is_integer($p_options_list[$i+1])) { + $v_work_list[0] = $p_options_list[$i+1].'-'.$p_options_list[$i+1]; + } + else if (is_array($p_options_list[$i+1])) { + $v_work_list = $p_options_list[$i+1]; + } + else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Value must be integer, string or array for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Reduce the index list + // each index item in the list must be a couple with a start and + // an end value : [0,3], [5-5], [8-10], ... + // ----- Check the format of each item + $v_sort_flag=false; + $v_sort_value=0; + for ($j=0; $j<sizeof($v_work_list); $j++) { + // ----- Explode the item + $v_item_list = explode("-", $v_work_list[$j]); + $v_size_item_list = sizeof($v_item_list); + + // ----- TBC : Here we might check that each item is a + // real integer ... + + // ----- Look for single value + if ($v_size_item_list == 1) { + // ----- Set the option value + $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0]; + $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[0]; + } + elseif ($v_size_item_list == 2) { + // ----- Set the option value + $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0]; + $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[1]; + } + else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Too many values in index range for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + + // ----- Look for list sort + if ($v_result_list[$p_options_list[$i]][$j]['start'] < $v_sort_value) { + $v_sort_flag=true; + + // ----- TBC : An automatic sort should be writen ... + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Invalid order of index range for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + $v_sort_value = $v_result_list[$p_options_list[$i]][$j]['start']; + } + + // ----- Sort the items + if ($v_sort_flag) { + // TBC : To Be Completed + } + + // ----- Next option + $i++; + break; + + // ----- Look for options that request no value + case PCLZIP_OPT_REMOVE_ALL_PATH : + case PCLZIP_OPT_EXTRACT_AS_STRING : + case PCLZIP_OPT_NO_COMPRESSION : + case PCLZIP_OPT_EXTRACT_IN_OUTPUT : + case PCLZIP_OPT_REPLACE_NEWER : + case PCLZIP_OPT_STOP_ON_ERROR : + $v_result_list[$p_options_list[$i]] = true; + break; + + // ----- Look for options that request an octal value + case PCLZIP_OPT_SET_CHMOD : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; + $i++; + break; + + // ----- Look for options that request a call-back + case PCLZIP_CB_PRE_EXTRACT : + case PCLZIP_CB_POST_EXTRACT : + case PCLZIP_CB_PRE_ADD : + case PCLZIP_CB_POST_ADD : + /* for futur use + case PCLZIP_CB_PRE_DELETE : + case PCLZIP_CB_POST_DELETE : + case PCLZIP_CB_PRE_LIST : + case PCLZIP_CB_POST_LIST : + */ + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + $v_function_name = $p_options_list[$i+1]; + + // ----- Check that the value is a valid existing function + if (!function_exists($v_function_name)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Function '".$v_function_name."()' is not an existing function for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Set the attribute + $v_result_list[$p_options_list[$i]] = $v_function_name; + $i++; + break; + + default : + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, + "Unknown parameter '" + .$p_options_list[$i]."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Next options + $i++; + } + + // ----- Look for mandatory options + if ($v_requested_options !== false) { + for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) { + // ----- Look for mandatory option + if ($v_requested_options[$key] == 'mandatory') { + // ----- Look if present + if (!isset($v_result_list[$key])) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")"); + + // ----- Return + return PclZip::errorCode(); + } + } + } + } + + // ----- Look for default values + if (!isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) { + + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privOptionDefaultThreshold() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privOptionDefaultThreshold(&$p_options) + { + $v_result=1; + + if (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) + || isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) { + return $v_result; + } + + // ----- Get 'memory_limit' configuration value + $v_memory_limit = ini_get('memory_limit'); + $v_memory_limit = trim($v_memory_limit); + $last = strtolower(substr($v_memory_limit, -1)); + + if($last == 'g') + //$v_memory_limit = $v_memory_limit*1024*1024*1024; + $v_memory_limit = $v_memory_limit*1073741824; + if($last == 'm') + //$v_memory_limit = $v_memory_limit*1024*1024; + $v_memory_limit = $v_memory_limit*1048576; + if($last == 'k') + $v_memory_limit = $v_memory_limit*1024; + + $p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] = floor($v_memory_limit*PCLZIP_TEMPORARY_FILE_RATIO); + + + // ----- Sanity check : No threshold if value lower than 1M + if ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] < 1048576) { + unset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privFileDescrParseAtt() + // Description : + // Parameters : + // Return Values : + // 1 on success. + // 0 on failure. + // -------------------------------------------------------------------------------- + function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requested_options=false) + { + $v_result=1; + + // ----- For each file in the list check the attributes + foreach ($p_file_list as $v_key => $v_value) { + + // ----- Check if the option is supported + if (!isset($v_requested_options[$v_key])) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file attribute '".$v_key."' for this file"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Look for attribute + switch ($v_key) { + case PCLZIP_ATT_FILE_NAME : + if (!is_string($v_value)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + + $p_filedescr['filename'] = PclZipUtilPathReduction($v_value); + + if ($p_filedescr['filename'] == '') { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty filename for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + + break; + + case PCLZIP_ATT_FILE_NEW_SHORT_NAME : + if (!is_string($v_value)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + + $p_filedescr['new_short_name'] = PclZipUtilPathReduction($v_value); + + if ($p_filedescr['new_short_name'] == '') { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty short filename for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + break; + + case PCLZIP_ATT_FILE_NEW_FULL_NAME : + if (!is_string($v_value)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + + $p_filedescr['new_full_name'] = PclZipUtilPathReduction($v_value); + + if ($p_filedescr['new_full_name'] == '') { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty full filename for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + break; + + // ----- Look for options that takes a string + case PCLZIP_ATT_FILE_COMMENT : + if (!is_string($v_value)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + + $p_filedescr['comment'] = $v_value; + break; + + case PCLZIP_ATT_FILE_MTIME : + if (!is_integer($v_value)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". Integer expected for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + + $p_filedescr['mtime'] = $v_value; + break; + + case PCLZIP_ATT_FILE_CONTENT : + $p_filedescr['content'] = $v_value; + break; + + default : + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, + "Unknown parameter '".$v_key."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Look for mandatory options + if ($v_requested_options !== false) { + for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) { + // ----- Look for mandatory option + if ($v_requested_options[$key] == 'mandatory') { + // ----- Look if present + if (!isset($p_file_list[$key])) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")"); + return PclZip::errorCode(); + } + } + } + } + + // end foreach + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privFileDescrExpand() + // Description : + // This method look for each item of the list to see if its a file, a folder + // or a string to be added as file. For any other type of files (link, other) + // just ignore the item. + // Then prepare the information that will be stored for that file. + // When its a folder, expand the folder with all the files that are in that + // folder (recursively). + // Parameters : + // Return Values : + // 1 on success. + // 0 on failure. + // -------------------------------------------------------------------------------- + function privFileDescrExpand(&$p_filedescr_list, &$p_options) + { + $v_result=1; + + // ----- Create a result list + $v_result_list = array(); + + // ----- Look each entry + for ($i=0; $i<sizeof($p_filedescr_list); $i++) { + + // ----- Get filedescr + $v_descr = $p_filedescr_list[$i]; + + // ----- Reduce the filename + $v_descr['filename'] = PclZipUtilTranslateWinPath($v_descr['filename'], false); + $v_descr['filename'] = PclZipUtilPathReduction($v_descr['filename']); + + // ----- Look for real file or folder + if (file_exists($v_descr['filename'])) { + if (@is_file($v_descr['filename'])) { + $v_descr['type'] = 'file'; + } + else if (@is_dir($v_descr['filename'])) { + $v_descr['type'] = 'folder'; + } + else if (@is_link($v_descr['filename'])) { + // skip + continue; + } + else { + // skip + continue; + } + } + + // ----- Look for string added as file + else if (isset($v_descr['content'])) { + $v_descr['type'] = 'virtual_file'; + } + + // ----- Missing file + else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$v_descr['filename']."' does not exist"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Calculate the stored filename + $this->privCalculateStoredFilename($v_descr, $p_options); + + // ----- Add the descriptor in result list + $v_result_list[sizeof($v_result_list)] = $v_descr; + + // ----- Look for folder + if ($v_descr['type'] == 'folder') { + // ----- List of items in folder + $v_dirlist_descr = array(); + $v_dirlist_nb = 0; + if ($v_folder_handler = @opendir($v_descr['filename'])) { + while (($v_item_handler = @readdir($v_folder_handler)) !== false) { + + // ----- Skip '.' and '..' + if (($v_item_handler == '.') || ($v_item_handler == '..')) { + continue; + } + + // ----- Compose the full filename + $v_dirlist_descr[$v_dirlist_nb]['filename'] = $v_descr['filename'].'/'.$v_item_handler; + + // ----- Look for different stored filename + // Because the name of the folder was changed, the name of the + // files/sub-folders also change + if (($v_descr['stored_filename'] != $v_descr['filename']) + && (!isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))) { + if ($v_descr['stored_filename'] != '') { + $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_descr['stored_filename'].'/'.$v_item_handler; + } + else { + $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_item_handler; + } + } + + $v_dirlist_nb++; + } + + @closedir($v_folder_handler); + } + else { + // TBC : unable to open folder in read mode + } + + // ----- Expand each element of the list + if ($v_dirlist_nb != 0) { + // ----- Expand + if (($v_result = $this->privFileDescrExpand($v_dirlist_descr, $p_options)) != 1) { + return $v_result; + } + + // ----- Concat the resulting list + $v_result_list = array_merge($v_result_list, $v_dirlist_descr); + } + else { + } + + // ----- Free local array + unset($v_dirlist_descr); + } + } + + // ----- Get the result list + $p_filedescr_list = $v_result_list; + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privCreate() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privCreate($p_filedescr_list, &$p_result_list, &$p_options) + { + $v_result=1; + $v_list_detail = array(); + + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); + + // ----- Open the file in write mode + if (($v_result = $this->privOpenFd('wb')) != 1) + { + // ----- Return + return $v_result; + } + + // ----- Add the list of files + $v_result = $this->privAddList($p_filedescr_list, $p_result_list, $p_options); + + // ----- Close + $this->privCloseFd(); + + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privAdd() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privAdd($p_filedescr_list, &$p_result_list, &$p_options) + { + $v_result=1; + $v_list_detail = array(); + + // ----- Look if the archive exists or is empty + if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0)) + { + + // ----- Do a create + $v_result = $this->privCreate($p_filedescr_list, $p_result_list, $p_options); + + // ----- Return + return $v_result; + } + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); + + // ----- Open the zip file + if (($v_result=$this->privOpenFd('rb')) != 1) + { + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_result; + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) + { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result; + } + + // ----- Go to beginning of File + @rewind($this->zip_fd); + + // ----- Creates a temporay file + $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; + + // ----- Open the temporary file in write mode + if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0) + { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Copy the files from the archive to the temporary file + // TBC : Here I should better append the file and go back to erase the central dir + $v_size = $v_central_dir['offset']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = fread($this->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Swap the file descriptor + // Here is a trick : I swap the temporary fd with the zip fd, in order to use + // the following methods on the temporary fil and not the real archive + $v_swap = $this->zip_fd; + $this->zip_fd = $v_zip_temp_fd; + $v_zip_temp_fd = $v_swap; + + // ----- Add the files + $v_header_list = array(); + if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1) + { + fclose($v_zip_temp_fd); + $this->privCloseFd(); + @unlink($v_zip_temp_name); + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_result; + } + + // ----- Store the offset of the central dir + $v_offset = @ftell($this->zip_fd); + + // ----- Copy the block of file headers from the old archive + $v_size = $v_central_dir['size']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($v_zip_temp_fd, $v_read_size); + @fwrite($this->zip_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Create the Central Dir files header + for ($i=0, $v_count=0; $i<sizeof($v_header_list); $i++) + { + // ----- Create the file header + if ($v_header_list[$i]['status'] == 'ok') { + if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) { + fclose($v_zip_temp_fd); + $this->privCloseFd(); + @unlink($v_zip_temp_name); + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_result; + } + $v_count++; + } + + // ----- Transform the header to a 'usable' info + $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); + } + + // ----- Zip file comment + $v_comment = $v_central_dir['comment']; + if (isset($p_options[PCLZIP_OPT_COMMENT])) { + $v_comment = $p_options[PCLZIP_OPT_COMMENT]; + } + if (isset($p_options[PCLZIP_OPT_ADD_COMMENT])) { + $v_comment = $v_comment.$p_options[PCLZIP_OPT_ADD_COMMENT]; + } + if (isset($p_options[PCLZIP_OPT_PREPEND_COMMENT])) { + $v_comment = $p_options[PCLZIP_OPT_PREPEND_COMMENT].$v_comment; + } + + // ----- Calculate the size of the central header + $v_size = @ftell($this->zip_fd)-$v_offset; + + // ----- Create the central dir footer + if (($v_result = $this->privWriteCentralHeader($v_count+$v_central_dir['entries'], $v_size, $v_offset, $v_comment)) != 1) + { + // ----- Reset the file list + unset($v_header_list); + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_result; + } + + // ----- Swap back the file descriptor + $v_swap = $this->zip_fd; + $this->zip_fd = $v_zip_temp_fd; + $v_zip_temp_fd = $v_swap; + + // ----- Close + $this->privCloseFd(); + + // ----- Close the temporary file + @fclose($v_zip_temp_fd); + + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); + + // ----- Delete the zip file + // TBC : I should test the result ... + @unlink($this->zipname); + + // ----- Rename the temporary file + // TBC : I should test the result ... + //@rename($v_zip_temp_name, $this->zipname); + PclZipUtilRename($v_zip_temp_name, $this->zipname); + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privOpenFd() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function privOpenFd($p_mode) + { + $v_result=1; + + // ----- Look if already open + if ($this->zip_fd != 0) + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Zip file \''.$this->zipname.'\' already open'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Open the zip file + if (($this->zip_fd = @fopen($this->zipname, $p_mode)) == 0) + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in '.$p_mode.' mode'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privCloseFd() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function privCloseFd() + { + $v_result=1; + + if ($this->zip_fd != 0) + @fclose($this->zip_fd); + $this->zip_fd = 0; + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privAddList() + // Description : + // $p_add_dir and $p_remove_dir will give the ability to memorize a path which is + // different from the real path of the file. This is usefull if you want to have PclTar + // running in any directory, and memorize relative path from an other directory. + // Parameters : + // $p_list : An array containing the file or directory names to add in the tar + // $p_result_list : list of added files with their properties (specially the status field) + // $p_add_dir : Path to add in the filename path archived + // $p_remove_dir : Path to remove in the filename path archived + // Return Values : + // -------------------------------------------------------------------------------- +// function privAddList($p_list, &$p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options) + function privAddList($p_filedescr_list, &$p_result_list, &$p_options) + { + $v_result=1; + + // ----- Add the files + $v_header_list = array(); + if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1) + { + // ----- Return + return $v_result; + } + + // ----- Store the offset of the central dir + $v_offset = @ftell($this->zip_fd); + + // ----- Create the Central Dir files header + for ($i=0,$v_count=0; $i<sizeof($v_header_list); $i++) + { + // ----- Create the file header + if ($v_header_list[$i]['status'] == 'ok') { + if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) { + // ----- Return + return $v_result; + } + $v_count++; + } + + // ----- Transform the header to a 'usable' info + $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); + } + + // ----- Zip file comment + $v_comment = ''; + if (isset($p_options[PCLZIP_OPT_COMMENT])) { + $v_comment = $p_options[PCLZIP_OPT_COMMENT]; + } + + // ----- Calculate the size of the central header + $v_size = @ftell($this->zip_fd)-$v_offset; + + // ----- Create the central dir footer + if (($v_result = $this->privWriteCentralHeader($v_count, $v_size, $v_offset, $v_comment)) != 1) + { + // ----- Reset the file list + unset($v_header_list); + + // ----- Return + return $v_result; + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privAddFileList() + // Description : + // Parameters : + // $p_filedescr_list : An array containing the file description + // or directory names to add in the zip + // $p_result_list : list of added files with their properties (specially the status field) + // Return Values : + // -------------------------------------------------------------------------------- + function privAddFileList($p_filedescr_list, &$p_result_list, &$p_options) + { + $v_result=1; + $v_header = array(); + + // ----- Recuperate the current number of elt in list + $v_nb = sizeof($p_result_list); + + // ----- Loop on the files + for ($j=0; ($j<sizeof($p_filedescr_list)) && ($v_result==1); $j++) { + // ----- Format the filename + $p_filedescr_list[$j]['filename'] + = PclZipUtilTranslateWinPath($p_filedescr_list[$j]['filename'], false); + + + // ----- Skip empty file names + // TBC : Can this be possible ? not checked in DescrParseAtt ? + if ($p_filedescr_list[$j]['filename'] == "") { + continue; + } + + // ----- Check the filename + if ( ($p_filedescr_list[$j]['type'] != 'virtual_file') + && (!file_exists($p_filedescr_list[$j]['filename']))) { + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$p_filedescr_list[$j]['filename']."' does not exist"); + return PclZip::errorCode(); + } + + // ----- Look if it is a file or a dir with no all path remove option + // or a dir with all its path removed +// if ( (is_file($p_filedescr_list[$j]['filename'])) +// || ( is_dir($p_filedescr_list[$j]['filename']) + if ( ($p_filedescr_list[$j]['type'] == 'file') + || ($p_filedescr_list[$j]['type'] == 'virtual_file') + || ( ($p_filedescr_list[$j]['type'] == 'folder') + && ( !isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]) + || !$p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) + ) { + + // ----- Add the file + $v_result = $this->privAddFile($p_filedescr_list[$j], $v_header, + $p_options); + if ($v_result != 1) { + return $v_result; + } + + // ----- Store the file infos + $p_result_list[$v_nb++] = $v_header; + } + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privAddFile() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privAddFile($p_filedescr, &$p_header, &$p_options) + { + $v_result=1; + + // ----- Working variable + $p_filename = $p_filedescr['filename']; + + // TBC : Already done in the fileAtt check ... ? + if ($p_filename == "") { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Look for a stored different filename + /* TBC : Removed + if (isset($p_filedescr['stored_filename'])) { + $v_stored_filename = $p_filedescr['stored_filename']; + } + else { + $v_stored_filename = $p_filedescr['stored_filename']; + } + */ + + // ----- Set the file properties + clearstatcache(); + $p_header['version'] = 20; + $p_header['version_extracted'] = 10; + $p_header['flag'] = 0; + $p_header['compression'] = 0; + $p_header['crc'] = 0; + $p_header['compressed_size'] = 0; + $p_header['filename_len'] = strlen($p_filename); + $p_header['extra_len'] = 0; + $p_header['disk'] = 0; + $p_header['internal'] = 0; + $p_header['offset'] = 0; + $p_header['filename'] = $p_filename; +// TBC : Removed $p_header['stored_filename'] = $v_stored_filename; + $p_header['stored_filename'] = $p_filedescr['stored_filename']; + $p_header['extra'] = ''; + $p_header['status'] = 'ok'; + $p_header['index'] = -1; + + // ----- Look for regular file + if ($p_filedescr['type']=='file') { + $p_header['external'] = 0x00000000; + $p_header['size'] = filesize($p_filename); + } + + // ----- Look for regular folder + else if ($p_filedescr['type']=='folder') { + $p_header['external'] = 0x00000010; + $p_header['mtime'] = filemtime($p_filename); + $p_header['size'] = filesize($p_filename); + } + + // ----- Look for virtual file + else if ($p_filedescr['type'] == 'virtual_file') { + $p_header['external'] = 0x00000000; + $p_header['size'] = strlen($p_filedescr['content']); + } + + + // ----- Look for filetime + if (isset($p_filedescr['mtime'])) { + $p_header['mtime'] = $p_filedescr['mtime']; + } + else if ($p_filedescr['type'] == 'virtual_file') { + $p_header['mtime'] = time(); + } + else { + $p_header['mtime'] = filemtime($p_filename); + } + + // ------ Look for file comment + if (isset($p_filedescr['comment'])) { + $p_header['comment_len'] = strlen($p_filedescr['comment']); + $p_header['comment'] = $p_filedescr['comment']; + } + else { + $p_header['comment_len'] = 0; + $p_header['comment'] = ''; + } + + // ----- Look for pre-add callback + if (isset($p_options[PCLZIP_CB_PRE_ADD])) { + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_header, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. +// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_ADD].'(PCLZIP_CB_PRE_ADD, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_PRE_ADD](PCLZIP_CB_PRE_ADD, $v_local_header); + if ($v_result == 0) { + // ----- Change the file status + $p_header['status'] = "skipped"; + $v_result = 1; + } + + // ----- Update the informations + // Only some fields can be modified + if ($p_header['stored_filename'] != $v_local_header['stored_filename']) { + $p_header['stored_filename'] = PclZipUtilPathReduction($v_local_header['stored_filename']); + } + } + + // ----- Look for empty stored filename + if ($p_header['stored_filename'] == "") { + $p_header['status'] = "filtered"; + } + + // ----- Check the path length + if (strlen($p_header['stored_filename']) > 0xFF) { + $p_header['status'] = 'filename_too_long'; + } + + // ----- Look if no error, or file not skipped + if ($p_header['status'] == 'ok') { + + // ----- Look for a file + if ($p_filedescr['type'] == 'file') { + // ----- Look for using temporary file to zip + if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) + && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON]) + || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) + && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_header['size'])) ) ) { + $v_result = $this->privAddFileUsingTempFile($p_filedescr, $p_header, $p_options); + if ($v_result < PCLZIP_ERR_NO_ERROR) { + return $v_result; + } + } + + // ----- Use "in memory" zip algo + else { + + // ----- Open the source file + if (($v_file = @fopen($p_filename, "rb")) == 0) { + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode"); + return PclZip::errorCode(); + } + + // ----- Read the file content + $v_content = @fread($v_file, $p_header['size']); + + // ----- Close the file + @fclose($v_file); + + // ----- Calculate the CRC + $p_header['crc'] = @crc32($v_content); + + // ----- Look for no compression + if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) { + // ----- Set header parameters + $p_header['compressed_size'] = $p_header['size']; + $p_header['compression'] = 0; + } + + // ----- Look for normal compression + else { + // ----- Compress the content + $v_content = @gzdeflate($v_content); + + // ----- Set header parameters + $p_header['compressed_size'] = strlen($v_content); + $p_header['compression'] = 8; + } + + // ----- Call the header generation + if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { + @fclose($v_file); + return $v_result; + } + + // ----- Write the compressed (or not) content + @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']); + + } + + } + + // ----- Look for a virtual file (a file from string) + else if ($p_filedescr['type'] == 'virtual_file') { + + $v_content = $p_filedescr['content']; + + // ----- Calculate the CRC + $p_header['crc'] = @crc32($v_content); + + // ----- Look for no compression + if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) { + // ----- Set header parameters + $p_header['compressed_size'] = $p_header['size']; + $p_header['compression'] = 0; + } + + // ----- Look for normal compression + else { + // ----- Compress the content + $v_content = @gzdeflate($v_content); + + // ----- Set header parameters + $p_header['compressed_size'] = strlen($v_content); + $p_header['compression'] = 8; + } + + // ----- Call the header generation + if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { + @fclose($v_file); + return $v_result; + } + + // ----- Write the compressed (or not) content + @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']); + } + + // ----- Look for a directory + else if ($p_filedescr['type'] == 'folder') { + // ----- Look for directory last '/' + if (@substr($p_header['stored_filename'], -1) != '/') { + $p_header['stored_filename'] .= '/'; + } + + // ----- Set the file properties + $p_header['size'] = 0; + //$p_header['external'] = 0x41FF0010; // Value for a folder : to be checked + $p_header['external'] = 0x00000010; // Value for a folder : to be checked + + // ----- Call the header generation + if (($v_result = $this->privWriteFileHeader($p_header)) != 1) + { + return $v_result; + } + } + } + + // ----- Look for post-add callback + if (isset($p_options[PCLZIP_CB_POST_ADD])) { + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_header, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. +// eval('$v_result = '.$p_options[PCLZIP_CB_POST_ADD].'(PCLZIP_CB_POST_ADD, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_POST_ADD](PCLZIP_CB_POST_ADD, $v_local_header); + if ($v_result == 0) { + // ----- Ignored + $v_result = 1; + } + + // ----- Update the informations + // Nothing can be modified + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privAddFileUsingTempFile() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privAddFileUsingTempFile($p_filedescr, &$p_header, &$p_options) + { + $v_result=PCLZIP_ERR_NO_ERROR; + + // ----- Working variable + $p_filename = $p_filedescr['filename']; + + + // ----- Open the source file + if (($v_file = @fopen($p_filename, "rb")) == 0) { + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode"); + return PclZip::errorCode(); + } + + // ----- Creates a compressed temporary file + $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz'; + if (($v_file_compressed = @gzopen($v_gzip_temp_name, "wb")) == 0) { + fclose($v_file); + PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode'); + return PclZip::errorCode(); + } + + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks + $v_size = filesize($p_filename); + while ($v_size != 0) { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($v_file, $v_read_size); + //$v_binary_data = pack('a'.$v_read_size, $v_buffer); + @gzputs($v_file_compressed, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Close the file + @fclose($v_file); + @gzclose($v_file_compressed); + + // ----- Check the minimum file size + if (filesize($v_gzip_temp_name) < 18) { + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'gzip temporary file \''.$v_gzip_temp_name.'\' has invalid filesize - should be minimum 18 bytes'); + return PclZip::errorCode(); + } + + // ----- Extract the compressed attributes + if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) { + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode'); + return PclZip::errorCode(); + } + + // ----- Read the gzip file header + $v_binary_data = @fread($v_file_compressed, 10); + $v_data_header = unpack('a1id1/a1id2/a1cm/a1flag/Vmtime/a1xfl/a1os', $v_binary_data); + + // ----- Check some parameters + $v_data_header['os'] = bin2hex($v_data_header['os']); + + // ----- Read the gzip file footer + @fseek($v_file_compressed, filesize($v_gzip_temp_name)-8); + $v_binary_data = @fread($v_file_compressed, 8); + $v_data_footer = unpack('Vcrc/Vcompressed_size', $v_binary_data); + + // ----- Set the attributes + $p_header['compression'] = ord($v_data_header['cm']); + //$p_header['mtime'] = $v_data_header['mtime']; + $p_header['crc'] = $v_data_footer['crc']; + $p_header['compressed_size'] = filesize($v_gzip_temp_name)-18; + + // ----- Close the file + @fclose($v_file_compressed); + + // ----- Call the header generation + if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { + return $v_result; + } + + // ----- Add the compressed data + if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) + { + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode'); + return PclZip::errorCode(); + } + + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks + fseek($v_file_compressed, 10); + $v_size = $p_header['compressed_size']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($v_file_compressed, $v_read_size); + //$v_binary_data = pack('a'.$v_read_size, $v_buffer); + @fwrite($this->zip_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Close the file + @fclose($v_file_compressed); + + // ----- Unlink the temporary file + @unlink($v_gzip_temp_name); + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privCalculateStoredFilename() + // Description : + // Based on file descriptor properties and global options, this method + // calculate the filename that will be stored in the archive. + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privCalculateStoredFilename(&$p_filedescr, &$p_options) + { + $v_result=1; + + // ----- Working variables + $p_filename = $p_filedescr['filename']; + if (isset($p_options[PCLZIP_OPT_ADD_PATH])) { + $p_add_dir = $p_options[PCLZIP_OPT_ADD_PATH]; + } + else { + $p_add_dir = ''; + } + if (isset($p_options[PCLZIP_OPT_REMOVE_PATH])) { + $p_remove_dir = $p_options[PCLZIP_OPT_REMOVE_PATH]; + } + else { + $p_remove_dir = ''; + } + if (isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { + $p_remove_all_dir = $p_options[PCLZIP_OPT_REMOVE_ALL_PATH]; + } + else { + $p_remove_all_dir = 0; + } + + + // ----- Look for full name change + if (isset($p_filedescr['new_full_name'])) { + // ----- Remove drive letter if any + $v_stored_filename = PclZipUtilTranslateWinPath($p_filedescr['new_full_name']); + } + + // ----- Look for path and/or short name change + else { + + // ----- Look for short name change + // Its when we cahnge just the filename but not the path + if (isset($p_filedescr['new_short_name'])) { + $v_path_info = pathinfo($p_filename); + $v_dir = ''; + if ($v_path_info['dirname'] != '') { + $v_dir = $v_path_info['dirname'].'/'; + } + $v_stored_filename = $v_dir.$p_filedescr['new_short_name']; + } + else { + // ----- Calculate the stored filename + $v_stored_filename = $p_filename; + } + + // ----- Look for all path to remove + if ($p_remove_all_dir) { + $v_stored_filename = basename($p_filename); + } + // ----- Look for partial path remove + else if ($p_remove_dir != "") { + if (substr($p_remove_dir, -1) != '/') + $p_remove_dir .= "/"; + + if ( (substr($p_filename, 0, 2) == "./") + || (substr($p_remove_dir, 0, 2) == "./")) { + + if ( (substr($p_filename, 0, 2) == "./") + && (substr($p_remove_dir, 0, 2) != "./")) { + $p_remove_dir = "./".$p_remove_dir; + } + if ( (substr($p_filename, 0, 2) != "./") + && (substr($p_remove_dir, 0, 2) == "./")) { + $p_remove_dir = substr($p_remove_dir, 2); + } + } + + $v_compare = PclZipUtilPathInclusion($p_remove_dir, + $v_stored_filename); + if ($v_compare > 0) { + if ($v_compare == 2) { + $v_stored_filename = ""; + } + else { + $v_stored_filename = substr($v_stored_filename, + strlen($p_remove_dir)); + } + } + } + + // ----- Remove drive letter if any + $v_stored_filename = PclZipUtilTranslateWinPath($v_stored_filename); + + // ----- Look for path to add + if ($p_add_dir != "") { + if (substr($p_add_dir, -1) == "/") + $v_stored_filename = $p_add_dir.$v_stored_filename; + else + $v_stored_filename = $p_add_dir."/".$v_stored_filename; + } + } + + // ----- Filename (reduce the path of stored name) + $v_stored_filename = PclZipUtilPathReduction($v_stored_filename); + $p_filedescr['stored_filename'] = $v_stored_filename; + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privWriteFileHeader() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privWriteFileHeader(&$p_header) + { + $v_result=1; + + // ----- Store the offset position of the file + $p_header['offset'] = ftell($this->zip_fd); + + // ----- Transform UNIX mtime to DOS format mdate/mtime + $v_date = getdate($p_header['mtime']); + $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2; + $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday']; + + // ----- Packed data + $v_binary_data = pack("VvvvvvVVVvv", 0x04034b50, + $p_header['version_extracted'], $p_header['flag'], + $p_header['compression'], $v_mtime, $v_mdate, + $p_header['crc'], $p_header['compressed_size'], + $p_header['size'], + strlen($p_header['stored_filename']), + $p_header['extra_len']); + + // ----- Write the first 148 bytes of the header in the archive + fputs($this->zip_fd, $v_binary_data, 30); + + // ----- Write the variable fields + if (strlen($p_header['stored_filename']) != 0) + { + fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename'])); + } + if ($p_header['extra_len'] != 0) + { + fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privWriteCentralFileHeader() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privWriteCentralFileHeader(&$p_header) + { + $v_result=1; + + // TBC + //for(reset($p_header); $key = key($p_header); next($p_header)) { + //} + + // ----- Transform UNIX mtime to DOS format mdate/mtime + $v_date = getdate($p_header['mtime']); + $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2; + $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday']; + + + // ----- Packed data + $v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50, + $p_header['version'], $p_header['version_extracted'], + $p_header['flag'], $p_header['compression'], + $v_mtime, $v_mdate, $p_header['crc'], + $p_header['compressed_size'], $p_header['size'], + strlen($p_header['stored_filename']), + $p_header['extra_len'], $p_header['comment_len'], + $p_header['disk'], $p_header['internal'], + $p_header['external'], $p_header['offset']); + + // ----- Write the 42 bytes of the header in the zip file + fputs($this->zip_fd, $v_binary_data, 46); + + // ----- Write the variable fields + if (strlen($p_header['stored_filename']) != 0) + { + fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename'])); + } + if ($p_header['extra_len'] != 0) + { + fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']); + } + if ($p_header['comment_len'] != 0) + { + fputs($this->zip_fd, $p_header['comment'], $p_header['comment_len']); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privWriteCentralHeader() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment) + { + $v_result=1; + + // ----- Packed data + $v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries, + $p_nb_entries, $p_size, + $p_offset, strlen($p_comment)); + + // ----- Write the 22 bytes of the header in the zip file + fputs($this->zip_fd, $v_binary_data, 22); + + // ----- Write the variable fields + if (strlen($p_comment) != 0) + { + fputs($this->zip_fd, $p_comment, strlen($p_comment)); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privList() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privList(&$p_list) + { + $v_result=1; + + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); + + // ----- Open the zip file + if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0) + { + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) + { + $this->privSwapBackMagicQuotes(); + return $v_result; + } + + // ----- Go to beginning of Central Dir + @rewind($this->zip_fd); + if (@fseek($this->zip_fd, $v_central_dir['offset'])) + { + $this->privSwapBackMagicQuotes(); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Read each entry + for ($i=0; $i<$v_central_dir['entries']; $i++) + { + // ----- Read the file header + if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1) + { + $this->privSwapBackMagicQuotes(); + return $v_result; + } + $v_header['index'] = $i; + + // ----- Get the only interesting attributes + $this->privConvertHeader2FileInfo($v_header, $p_list[$i]); + unset($v_header); + } + + // ----- Close the zip file + $this->privCloseFd(); + + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privConvertHeader2FileInfo() + // Description : + // This function takes the file informations from the central directory + // entries and extract the interesting parameters that will be given back. + // The resulting file infos are set in the array $p_info + // $p_info['filename'] : Filename with full path. Given by user (add), + // extracted in the filesystem (extract). + // $p_info['stored_filename'] : Stored filename in the archive. + // $p_info['size'] = Size of the file. + // $p_info['compressed_size'] = Compressed size of the file. + // $p_info['mtime'] = Last modification date of the file. + // $p_info['comment'] = Comment associated with the file. + // $p_info['folder'] = true/false : indicates if the entry is a folder or not. + // $p_info['status'] = status of the action on the file. + // $p_info['crc'] = CRC of the file content. + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privConvertHeader2FileInfo($p_header, &$p_info) + { + $v_result=1; + + // ----- Get the interesting attributes + $v_temp_path = PclZipUtilPathReduction($p_header['filename']); + $p_info['filename'] = $v_temp_path; + $v_temp_path = PclZipUtilPathReduction($p_header['stored_filename']); + $p_info['stored_filename'] = $v_temp_path; + $p_info['size'] = $p_header['size']; + $p_info['compressed_size'] = $p_header['compressed_size']; + $p_info['mtime'] = $p_header['mtime']; + $p_info['comment'] = $p_header['comment']; + $p_info['folder'] = (($p_header['external']&0x00000010)==0x00000010); + $p_info['index'] = $p_header['index']; + $p_info['status'] = $p_header['status']; + $p_info['crc'] = $p_header['crc']; + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privExtractByRule() + // Description : + // Extract a file or directory depending of rules (by index, by name, ...) + // Parameters : + // $p_file_list : An array where will be placed the properties of each + // extracted file + // $p_path : Path to add while writing the extracted files + // $p_remove_path : Path to remove (from the file memorized path) while writing the + // extracted files. If the path does not match the file path, + // the file is extracted with its memorized path. + // $p_remove_path does not apply to 'list' mode. + // $p_path and $p_remove_path are commulative. + // Return Values : + // 1 on success,0 or less on error (see error code list) + // -------------------------------------------------------------------------------- + function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options) + { + $v_result=1; + + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); + + // ----- Check the path + if ( ($p_path == "") + || ( (substr($p_path, 0, 1) != "/") + && (substr($p_path, 0, 3) != "../") + && (substr($p_path,1,2)!=":/"))) + $p_path = "./".$p_path; + + // ----- Reduce the path last (and duplicated) '/' + if (($p_path != "./") && ($p_path != "/")) + { + // ----- Look for the path end '/' + while (substr($p_path, -1) == "/") + { + $p_path = substr($p_path, 0, strlen($p_path)-1); + } + } + + // ----- Look for path to remove format (should end by /) + if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/')) + { + $p_remove_path .= '/'; + } + $p_remove_path_size = strlen($p_remove_path); + + // ----- Open the zip file + if (($v_result = $this->privOpenFd('rb')) != 1) + { + $this->privSwapBackMagicQuotes(); + return $v_result; + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) + { + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + + return $v_result; + } + + // ----- Start at beginning of Central Dir + $v_pos_entry = $v_central_dir['offset']; + + // ----- Read each entry + $j_start = 0; + for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++) + { + + // ----- Read next Central dir entry + @rewind($this->zip_fd); + if (@fseek($this->zip_fd, $v_pos_entry)) + { + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Read the file header + $v_header = array(); + if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1) + { + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + + return $v_result; + } + + // ----- Store the index + $v_header['index'] = $i; + + // ----- Store the file position + $v_pos_entry = ftell($this->zip_fd); + + // ----- Look for the specific extract rules + $v_extract = false; + + // ----- Look for extract by name rule + if ( (isset($p_options[PCLZIP_OPT_BY_NAME])) + && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) { + + // ----- Look if the filename is in the list + for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_extract); $j++) { + + // ----- Look for a directory + if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") { + + // ----- Look if the directory is in the filename path + if ( (strlen($v_header['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) + && (substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) { + $v_extract = true; + } + } + // ----- Look for a filename + elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) { + $v_extract = true; + } + } + } + + // ----- Look for extract by ereg rule + // ereg() is deprecated with PHP 5.3 + /* + else if ( (isset($p_options[PCLZIP_OPT_BY_EREG])) + && ($p_options[PCLZIP_OPT_BY_EREG] != "")) { + + if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header['stored_filename'])) { + $v_extract = true; + } + } + */ + + // ----- Look for extract by preg rule + else if ( (isset($p_options[PCLZIP_OPT_BY_PREG])) + && ($p_options[PCLZIP_OPT_BY_PREG] != "")) { + + if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) { + $v_extract = true; + } + } + + // ----- Look for extract by index rule + else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX])) + && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) { + + // ----- Look if the index is in the list + for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_extract); $j++) { + + if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) { + $v_extract = true; + } + if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) { + $j_start = $j+1; + } + + if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) { + break; + } + } + } + + // ----- Look for no rule, which means extract all the archive + else { + $v_extract = true; + } + + // ----- Check compression method + if ( ($v_extract) + && ( ($v_header['compression'] != 8) + && ($v_header['compression'] != 0))) { + $v_header['status'] = 'unsupported_compression'; + + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { + + $this->privSwapBackMagicQuotes(); + + PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_COMPRESSION, + "Filename '".$v_header['stored_filename']."' is " + ."compressed by an unsupported compression " + ."method (".$v_header['compression'].") "); + + return PclZip::errorCode(); + } + } + + // ----- Check encrypted files + if (($v_extract) && (($v_header['flag'] & 1) == 1)) { + $v_header['status'] = 'unsupported_encryption'; + + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { + + $this->privSwapBackMagicQuotes(); + + PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, + "Unsupported encryption for " + ." filename '".$v_header['stored_filename'] + ."'"); + + return PclZip::errorCode(); + } + } + + // ----- Look for real extraction + if (($v_extract) && ($v_header['status'] != 'ok')) { + $v_result = $this->privConvertHeader2FileInfo($v_header, + $p_file_list[$v_nb_extracted++]); + if ($v_result != 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result; + } + + $v_extract = false; + } + + // ----- Look for real extraction + if ($v_extract) + { + + // ----- Go to the file position + @rewind($this->zip_fd); + if (@fseek($this->zip_fd, $v_header['offset'])) + { + // ----- Close the zip file + $this->privCloseFd(); + + $this->privSwapBackMagicQuotes(); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Look for extraction as string + if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) { + + $v_string = ''; + + // ----- Extracting the file + $v_result1 = $this->privExtractFileAsString($v_header, $v_string, $p_options); + if ($v_result1 < 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result1; + } + + // ----- Get the only interesting attributes + if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1) + { + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + + return $v_result; + } + + // ----- Set the file content + $p_file_list[$v_nb_extracted]['content'] = $v_string; + + // ----- Next extracted file + $v_nb_extracted++; + + // ----- Look for user callback abort + if ($v_result1 == 2) { + break; + } + } + // ----- Look for extraction in standard output + elseif ( (isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) + && ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) { + // ----- Extracting the file in standard output + $v_result1 = $this->privExtractFileInOutput($v_header, $p_options); + if ($v_result1 < 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result1; + } + + // ----- Get the only interesting attributes + if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result; + } + + // ----- Look for user callback abort + if ($v_result1 == 2) { + break; + } + } + // ----- Look for normal extraction + else { + // ----- Extracting the file + $v_result1 = $this->privExtractFile($v_header, + $p_path, $p_remove_path, + $p_remove_all_path, + $p_options); + if ($v_result1 < 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result1; + } + + // ----- Get the only interesting attributes + if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) + { + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + + return $v_result; + } + + // ----- Look for user callback abort + if ($v_result1 == 2) { + break; + } + } + } + } + + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privExtractFile() + // Description : + // Parameters : + // Return Values : + // + // 1 : ... ? + // PCLZIP_ERR_USER_ABORTED(2) : User ask for extraction stop in callback + // -------------------------------------------------------------------------------- + function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options) + { + $v_result=1; + + // ----- Read the file header + if (($v_result = $this->privReadFileHeader($v_header)) != 1) + { + // ----- Return + return $v_result; + } + + + // ----- Check that the file header is coherent with $p_entry info + if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { + // TBC + } + + // ----- Look for all path to remove + if ($p_remove_all_path == true) { + // ----- Look for folder entry that not need to be extracted + if (($p_entry['external']&0x00000010)==0x00000010) { + + $p_entry['status'] = "filtered"; + + return $v_result; + } + + // ----- Get the basename of the path + $p_entry['filename'] = basename($p_entry['filename']); + } + + // ----- Look for path to remove + else if ($p_remove_path != "") + { + if (PclZipUtilPathInclusion($p_remove_path, $p_entry['filename']) == 2) + { + + // ----- Change the file status + $p_entry['status'] = "filtered"; + + // ----- Return + return $v_result; + } + + $p_remove_path_size = strlen($p_remove_path); + if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path) + { + + // ----- Remove the path + $p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size); + + } + } + + // ----- Add the path + if ($p_path != '') { + $p_entry['filename'] = $p_path."/".$p_entry['filename']; + } + + // ----- Check a base_dir_restriction + if (isset($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION])) { + $v_inclusion + = PclZipUtilPathInclusion($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION], + $p_entry['filename']); + if ($v_inclusion == 0) { + + PclZip::privErrorLog(PCLZIP_ERR_DIRECTORY_RESTRICTION, + "Filename '".$p_entry['filename']."' is " + ."outside PCLZIP_OPT_EXTRACT_DIR_RESTRICTION"); + + return PclZip::errorCode(); + } + } + + // ----- Look for pre-extract callback + if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. +// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header); + if ($v_result == 0) { + // ----- Change the file status + $p_entry['status'] = "skipped"; + $v_result = 1; + } + + // ----- Look for abort result + if ($v_result == 2) { + // ----- This status is internal and will be changed in 'skipped' + $p_entry['status'] = "aborted"; + $v_result = PCLZIP_ERR_USER_ABORTED; + } + + // ----- Update the informations + // Only some fields can be modified + $p_entry['filename'] = $v_local_header['filename']; + } + + + // ----- Look if extraction should be done + if ($p_entry['status'] == 'ok') { + + // ----- Look for specific actions while the file exist + if (file_exists($p_entry['filename'])) + { + + // ----- Look if file is a directory + if (is_dir($p_entry['filename'])) + { + + // ----- Change the file status + $p_entry['status'] = "already_a_directory"; + + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + // For historical reason first PclZip implementation does not stop + // when this kind of error occurs. + if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { + + PclZip::privErrorLog(PCLZIP_ERR_ALREADY_A_DIRECTORY, + "Filename '".$p_entry['filename']."' is " + ."already used by an existing directory"); + + return PclZip::errorCode(); + } + } + // ----- Look if file is write protected + else if (!is_writeable($p_entry['filename'])) + { + + // ----- Change the file status + $p_entry['status'] = "write_protected"; + + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + // For historical reason first PclZip implementation does not stop + // when this kind of error occurs. + if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { + + PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, + "Filename '".$p_entry['filename']."' exists " + ."and is write protected"); + + return PclZip::errorCode(); + } + } + + // ----- Look if the extracted file is older + else if (filemtime($p_entry['filename']) > $p_entry['mtime']) + { + // ----- Change the file status + if ( (isset($p_options[PCLZIP_OPT_REPLACE_NEWER])) + && ($p_options[PCLZIP_OPT_REPLACE_NEWER]===true)) { + } + else { + $p_entry['status'] = "newer_exist"; + + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + // For historical reason first PclZip implementation does not stop + // when this kind of error occurs. + if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { + + PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, + "Newer version of '".$p_entry['filename']."' exists " + ."and option PCLZIP_OPT_REPLACE_NEWER is not selected"); + + return PclZip::errorCode(); + } + } + } + else { + } + } + + // ----- Check the directory availability and create it if necessary + else { + if ((($p_entry['external']&0x00000010)==0x00000010) || (substr($p_entry['filename'], -1) == '/')) + $v_dir_to_check = $p_entry['filename']; + else if (!strstr($p_entry['filename'], "/")) + $v_dir_to_check = ""; + else + $v_dir_to_check = dirname($p_entry['filename']); + + if (($v_result = $this->privDirCheck($v_dir_to_check, (($p_entry['external']&0x00000010)==0x00000010))) != 1) { + + // ----- Change the file status + $p_entry['status'] = "path_creation_fail"; + + // ----- Return + //return $v_result; + $v_result = 1; + } + } + } + + // ----- Look if extraction should be done + if ($p_entry['status'] == 'ok') { + + // ----- Do the extraction (if not a folder) + if (!(($p_entry['external']&0x00000010)==0x00000010)) + { + // ----- Look for not compressed file + if ($p_entry['compression'] == 0) { + + // ----- Opening destination file + if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) + { + + // ----- Change the file status + $p_entry['status'] = "write_error"; + + // ----- Return + return $v_result; + } + + + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks + $v_size = $p_entry['compressed_size']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($this->zip_fd, $v_read_size); + /* Try to speed up the code + $v_binary_data = pack('a'.$v_read_size, $v_buffer); + @fwrite($v_dest_file, $v_binary_data, $v_read_size); + */ + @fwrite($v_dest_file, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Closing the destination file + fclose($v_dest_file); + + // ----- Change the file mtime + touch($p_entry['filename'], $p_entry['mtime']); + + + } + else { + // ----- TBC + // Need to be finished + if (($p_entry['flag'] & 1) == 1) { + PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, 'File \''.$p_entry['filename'].'\' is encrypted. Encrypted files are not supported.'); + return PclZip::errorCode(); + } + + + // ----- Look for using temporary file to unzip + if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) + && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON]) + || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) + && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_entry['size'])) ) ) { + $v_result = $this->privExtractFileUsingTempFile($p_entry, $p_options); + if ($v_result < PCLZIP_ERR_NO_ERROR) { + return $v_result; + } + } + + // ----- Look for extract in memory + else { + + + // ----- Read the compressed file in a buffer (one shot) + $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); + + // ----- Decompress the file + $v_file_content = @gzinflate($v_buffer); + unset($v_buffer); + if ($v_file_content === FALSE) { + + // ----- Change the file status + // TBC + $p_entry['status'] = "error"; + + return $v_result; + } + + // ----- Opening destination file + if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) { + + // ----- Change the file status + $p_entry['status'] = "write_error"; + + return $v_result; + } + + // ----- Write the uncompressed data + @fwrite($v_dest_file, $v_file_content, $p_entry['size']); + unset($v_file_content); + + // ----- Closing the destination file + @fclose($v_dest_file); + + } + + // ----- Change the file mtime + @touch($p_entry['filename'], $p_entry['mtime']); + } + + // ----- Look for chmod option + if (isset($p_options[PCLZIP_OPT_SET_CHMOD])) { + + // ----- Change the mode of the file + @chmod($p_entry['filename'], $p_options[PCLZIP_OPT_SET_CHMOD]); + } + + } + } + + // ----- Change abort status + if ($p_entry['status'] == "aborted") { + $p_entry['status'] = "skipped"; + } + + // ----- Look for post-extract callback + elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. +// eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header); + + // ----- Look for abort result + if ($v_result == 2) { + $v_result = PCLZIP_ERR_USER_ABORTED; + } + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privExtractFileUsingTempFile() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privExtractFileUsingTempFile(&$p_entry, &$p_options) + { + $v_result=1; + + // ----- Creates a temporary file + $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz'; + if (($v_dest_file = @fopen($v_gzip_temp_name, "wb")) == 0) { + fclose($v_file); + PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode'); + return PclZip::errorCode(); + } + + + // ----- Write gz file format header + $v_binary_data = pack('va1a1Va1a1', 0x8b1f, Chr($p_entry['compression']), Chr(0x00), time(), Chr(0x00), Chr(3)); + @fwrite($v_dest_file, $v_binary_data, 10); + + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks + $v_size = $p_entry['compressed_size']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($this->zip_fd, $v_read_size); + //$v_binary_data = pack('a'.$v_read_size, $v_buffer); + @fwrite($v_dest_file, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Write gz file format footer + $v_binary_data = pack('VV', $p_entry['crc'], $p_entry['size']); + @fwrite($v_dest_file, $v_binary_data, 8); + + // ----- Close the temporary file + @fclose($v_dest_file); + + // ----- Opening destination file + if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) { + $p_entry['status'] = "write_error"; + return $v_result; + } + + // ----- Open the temporary gz file + if (($v_src_file = @gzopen($v_gzip_temp_name, 'rb')) == 0) { + @fclose($v_dest_file); + $p_entry['status'] = "read_error"; + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode'); + return PclZip::errorCode(); + } + + + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks + $v_size = $p_entry['size']; + while ($v_size != 0) { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @gzread($v_src_file, $v_read_size); + //$v_binary_data = pack('a'.$v_read_size, $v_buffer); + @fwrite($v_dest_file, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + @fclose($v_dest_file); + @gzclose($v_src_file); + + // ----- Delete the temporary file + @unlink($v_gzip_temp_name); + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privExtractFileInOutput() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privExtractFileInOutput(&$p_entry, &$p_options) + { + $v_result=1; + + // ----- Read the file header + if (($v_result = $this->privReadFileHeader($v_header)) != 1) { + return $v_result; + } + + + // ----- Check that the file header is coherent with $p_entry info + if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { + // TBC + } + + // ----- Look for pre-extract callback + if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. +// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header); + if ($v_result == 0) { + // ----- Change the file status + $p_entry['status'] = "skipped"; + $v_result = 1; + } + + // ----- Look for abort result + if ($v_result == 2) { + // ----- This status is internal and will be changed in 'skipped' + $p_entry['status'] = "aborted"; + $v_result = PCLZIP_ERR_USER_ABORTED; + } + + // ----- Update the informations + // Only some fields can be modified + $p_entry['filename'] = $v_local_header['filename']; + } + + // ----- Trace + + // ----- Look if extraction should be done + if ($p_entry['status'] == 'ok') { + + // ----- Do the extraction (if not a folder) + if (!(($p_entry['external']&0x00000010)==0x00000010)) { + // ----- Look for not compressed file + if ($p_entry['compressed_size'] == $p_entry['size']) { + + // ----- Read the file in a buffer (one shot) + $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); + + // ----- Send the file to the output + echo $v_buffer; + unset($v_buffer); + } + else { + + // ----- Read the compressed file in a buffer (one shot) + $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); + + // ----- Decompress the file + $v_file_content = gzinflate($v_buffer); + unset($v_buffer); + + // ----- Send the file to the output + echo $v_file_content; + unset($v_file_content); + } + } + } + + // ----- Change abort status + if ($p_entry['status'] == "aborted") { + $p_entry['status'] = "skipped"; + } + + // ----- Look for post-extract callback + elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. +// eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header); + + // ----- Look for abort result + if ($v_result == 2) { + $v_result = PCLZIP_ERR_USER_ABORTED; + } + } + + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privExtractFileAsString() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privExtractFileAsString(&$p_entry, &$p_string, &$p_options) + { + $v_result=1; + + // ----- Read the file header + $v_header = array(); + if (($v_result = $this->privReadFileHeader($v_header)) != 1) + { + // ----- Return + return $v_result; + } + + + // ----- Check that the file header is coherent with $p_entry info + if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { + // TBC + } + + // ----- Look for pre-extract callback + if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. +// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header); + if ($v_result == 0) { + // ----- Change the file status + $p_entry['status'] = "skipped"; + $v_result = 1; + } + + // ----- Look for abort result + if ($v_result == 2) { + // ----- This status is internal and will be changed in 'skipped' + $p_entry['status'] = "aborted"; + $v_result = PCLZIP_ERR_USER_ABORTED; + } + + // ----- Update the informations + // Only some fields can be modified + $p_entry['filename'] = $v_local_header['filename']; + } + + + // ----- Look if extraction should be done + if ($p_entry['status'] == 'ok') { + + // ----- Do the extraction (if not a folder) + if (!(($p_entry['external']&0x00000010)==0x00000010)) { + // ----- Look for not compressed file + // if ($p_entry['compressed_size'] == $p_entry['size']) + if ($p_entry['compression'] == 0) { + + // ----- Reading the file + $p_string = @fread($this->zip_fd, $p_entry['compressed_size']); + } + else { + + // ----- Reading the file + $v_data = @fread($this->zip_fd, $p_entry['compressed_size']); + + // ----- Decompress the file + if (($p_string = @gzinflate($v_data)) === FALSE) { + // TBC + } + } + + // ----- Trace + } + else { + // TBC : error : can not extract a folder in a string + } + + } + + // ----- Change abort status + if ($p_entry['status'] == "aborted") { + $p_entry['status'] = "skipped"; + } + + // ----- Look for post-extract callback + elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Swap the content to header + $v_local_header['content'] = $p_string; + $p_string = ''; + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. +// eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header); + + // ----- Swap back the content to header + $p_string = $v_local_header['content']; + unset($v_local_header['content']); + + // ----- Look for abort result + if ($v_result == 2) { + $v_result = PCLZIP_ERR_USER_ABORTED; + } + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privReadFileHeader() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privReadFileHeader(&$p_header) + { + $v_result=1; + + // ----- Read the 4 bytes signature + $v_binary_data = @fread($this->zip_fd, 4); + $v_data = unpack('Vid', $v_binary_data); + + // ----- Check signature + if ($v_data['id'] != 0x04034b50) + { + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Read the first 42 bytes of the header + $v_binary_data = fread($this->zip_fd, 26); + + // ----- Look for invalid block size + if (strlen($v_binary_data) != 26) + { + $p_header['filename'] = ""; + $p_header['status'] = "invalid_header"; + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data)); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Extract the values + $v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $v_binary_data); + + // ----- Get filename + $p_header['filename'] = fread($this->zip_fd, $v_data['filename_len']); + + // ----- Get extra_fields + if ($v_data['extra_len'] != 0) { + $p_header['extra'] = fread($this->zip_fd, $v_data['extra_len']); + } + else { + $p_header['extra'] = ''; + } + + // ----- Extract properties + $p_header['version_extracted'] = $v_data['version']; + $p_header['compression'] = $v_data['compression']; + $p_header['size'] = $v_data['size']; + $p_header['compressed_size'] = $v_data['compressed_size']; + $p_header['crc'] = $v_data['crc']; + $p_header['flag'] = $v_data['flag']; + $p_header['filename_len'] = $v_data['filename_len']; + + // ----- Recuperate date in UNIX format + $p_header['mdate'] = $v_data['mdate']; + $p_header['mtime'] = $v_data['mtime']; + if ($p_header['mdate'] && $p_header['mtime']) + { + // ----- Extract time + $v_hour = ($p_header['mtime'] & 0xF800) >> 11; + $v_minute = ($p_header['mtime'] & 0x07E0) >> 5; + $v_seconde = ($p_header['mtime'] & 0x001F)*2; + + // ----- Extract date + $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980; + $v_month = ($p_header['mdate'] & 0x01E0) >> 5; + $v_day = $p_header['mdate'] & 0x001F; + + // ----- Get UNIX date format + $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); + + } + else + { + $p_header['mtime'] = time(); + } + + // TBC + //for(reset($v_data); $key = key($v_data); next($v_data)) { + //} + + // ----- Set the stored filename + $p_header['stored_filename'] = $p_header['filename']; + + // ----- Set the status field + $p_header['status'] = "ok"; + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privReadCentralFileHeader() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privReadCentralFileHeader(&$p_header) + { + $v_result=1; + + // ----- Read the 4 bytes signature + $v_binary_data = @fread($this->zip_fd, 4); + $v_data = unpack('Vid', $v_binary_data); + + // ----- Check signature + if ($v_data['id'] != 0x02014b50) + { + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Read the first 42 bytes of the header + $v_binary_data = fread($this->zip_fd, 42); + + // ----- Look for invalid block size + if (strlen($v_binary_data) != 42) + { + $p_header['filename'] = ""; + $p_header['status'] = "invalid_header"; + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data)); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Extract the values + $p_header = unpack('vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', $v_binary_data); + + // ----- Get filename + if ($p_header['filename_len'] != 0) + $p_header['filename'] = fread($this->zip_fd, $p_header['filename_len']); + else + $p_header['filename'] = ''; + + // ----- Get extra + if ($p_header['extra_len'] != 0) + $p_header['extra'] = fread($this->zip_fd, $p_header['extra_len']); + else + $p_header['extra'] = ''; + + // ----- Get comment + if ($p_header['comment_len'] != 0) + $p_header['comment'] = fread($this->zip_fd, $p_header['comment_len']); + else + $p_header['comment'] = ''; + + // ----- Extract properties + + // ----- Recuperate date in UNIX format + //if ($p_header['mdate'] && $p_header['mtime']) + // TBC : bug : this was ignoring time with 0/0/0 + if (1) + { + // ----- Extract time + $v_hour = ($p_header['mtime'] & 0xF800) >> 11; + $v_minute = ($p_header['mtime'] & 0x07E0) >> 5; + $v_seconde = ($p_header['mtime'] & 0x001F)*2; + + // ----- Extract date + $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980; + $v_month = ($p_header['mdate'] & 0x01E0) >> 5; + $v_day = $p_header['mdate'] & 0x001F; + + // ----- Get UNIX date format + $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); + + } + else + { + $p_header['mtime'] = time(); + } + + // ----- Set the stored filename + $p_header['stored_filename'] = $p_header['filename']; + + // ----- Set default status to ok + $p_header['status'] = 'ok'; + + // ----- Look if it is a directory + if (substr($p_header['filename'], -1) == '/') { + //$p_header['external'] = 0x41FF0010; + $p_header['external'] = 0x00000010; + } + + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privCheckFileHeaders() + // Description : + // Parameters : + // Return Values : + // 1 on success, + // 0 on error; + // -------------------------------------------------------------------------------- + function privCheckFileHeaders(&$p_local_header, &$p_central_header) + { + $v_result=1; + + // ----- Check the static values + // TBC + if ($p_local_header['filename'] != $p_central_header['filename']) { + } + if ($p_local_header['version_extracted'] != $p_central_header['version_extracted']) { + } + if ($p_local_header['flag'] != $p_central_header['flag']) { + } + if ($p_local_header['compression'] != $p_central_header['compression']) { + } + if ($p_local_header['mtime'] != $p_central_header['mtime']) { + } + if ($p_local_header['filename_len'] != $p_central_header['filename_len']) { + } + + // ----- Look for flag bit 3 + if (($p_local_header['flag'] & 8) == 8) { + $p_local_header['size'] = $p_central_header['size']; + $p_local_header['compressed_size'] = $p_central_header['compressed_size']; + $p_local_header['crc'] = $p_central_header['crc']; + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privReadEndCentralDir() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privReadEndCentralDir(&$p_central_dir) + { + $v_result=1; + + // ----- Go to the end of the zip file + $v_size = filesize($this->zipname); + @fseek($this->zip_fd, $v_size); + if (@ftell($this->zip_fd) != $v_size) + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to go to the end of the archive \''.$this->zipname.'\''); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- First try : look if this is an archive with no commentaries (most of the time) + // in this case the end of central dir is at 22 bytes of the file end + $v_found = 0; + if ($v_size > 26) { + @fseek($this->zip_fd, $v_size-22); + if (($v_pos = @ftell($this->zip_fd)) != ($v_size-22)) + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\''); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Read for bytes + $v_binary_data = @fread($this->zip_fd, 4); + $v_data = @unpack('Vid', $v_binary_data); + + // ----- Check signature + if ($v_data['id'] == 0x06054b50) { + $v_found = 1; + } + + $v_pos = ftell($this->zip_fd); + } + + // ----- Go back to the maximum possible size of the Central Dir End Record + if (!$v_found) { + $v_maximum_size = 65557; // 0xFFFF + 22; + if ($v_maximum_size > $v_size) + $v_maximum_size = $v_size; + @fseek($this->zip_fd, $v_size-$v_maximum_size); + if (@ftell($this->zip_fd) != ($v_size-$v_maximum_size)) + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\''); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Read byte per byte in order to find the signature + $v_pos = ftell($this->zip_fd); + $v_bytes = 0x00000000; + while ($v_pos < $v_size) + { + // ----- Read a byte + $v_byte = @fread($this->zip_fd, 1); + + // ----- Add the byte + //$v_bytes = ($v_bytes << 8) | Ord($v_byte); + // Note we mask the old value down such that once shifted we can never end up with more than a 32bit number + // Otherwise on systems where we have 64bit integers the check below for the magic number will fail. + $v_bytes = ( ($v_bytes & 0xFFFFFF) << 8) | Ord($v_byte); + + // ----- Compare the bytes + if ($v_bytes == 0x504b0506) + { + $v_pos++; + break; + } + + $v_pos++; + } + + // ----- Look if not found end of central dir + if ($v_pos == $v_size) + { + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Unable to find End of Central Dir Record signature"); + + // ----- Return + return PclZip::errorCode(); + } + } + + // ----- Read the first 18 bytes of the header + $v_binary_data = fread($this->zip_fd, 18); + + // ----- Look for invalid block size + if (strlen($v_binary_data) != 18) + { + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid End of Central Dir Record size : ".strlen($v_binary_data)); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Extract the values + $v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data); + + // ----- Check the global size + if (($v_pos + $v_data['comment_size'] + 18) != $v_size) { + + // ----- Removed in release 2.2 see readme file + // The check of the file size is a little too strict. + // Some bugs where found when a zip is encrypted/decrypted with 'crypt'. + // While decrypted, zip has training 0 bytes + if (0) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, + 'The central dir is not at the end of the archive.' + .' Some trailing bytes exists after the archive.'); + + // ----- Return + return PclZip::errorCode(); + } + } + + // ----- Get comment + if ($v_data['comment_size'] != 0) { + $p_central_dir['comment'] = fread($this->zip_fd, $v_data['comment_size']); + } + else + $p_central_dir['comment'] = ''; + + $p_central_dir['entries'] = $v_data['entries']; + $p_central_dir['disk_entries'] = $v_data['disk_entries']; + $p_central_dir['offset'] = $v_data['offset']; + $p_central_dir['size'] = $v_data['size']; + $p_central_dir['disk'] = $v_data['disk']; + $p_central_dir['disk_start'] = $v_data['disk_start']; + + // TBC + //for(reset($p_central_dir); $key = key($p_central_dir); next($p_central_dir)) { + //} + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privDeleteByRule() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privDeleteByRule(&$p_result_list, &$p_options) + { + $v_result=1; + $v_list_detail = array(); + + // ----- Open the zip file + if (($v_result=$this->privOpenFd('rb')) != 1) + { + // ----- Return + return $v_result; + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) + { + $this->privCloseFd(); + return $v_result; + } + + // ----- Go to beginning of File + @rewind($this->zip_fd); + + // ----- Scan all the files + // ----- Start at beginning of Central Dir + $v_pos_entry = $v_central_dir['offset']; + @rewind($this->zip_fd); + if (@fseek($this->zip_fd, $v_pos_entry)) + { + // ----- Close the zip file + $this->privCloseFd(); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Read each entry + $v_header_list = array(); + $j_start = 0; + for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++) + { + + // ----- Read the file header + $v_header_list[$v_nb_extracted] = array(); + if (($v_result = $this->privReadCentralFileHeader($v_header_list[$v_nb_extracted])) != 1) + { + // ----- Close the zip file + $this->privCloseFd(); + + return $v_result; + } + + + // ----- Store the index + $v_header_list[$v_nb_extracted]['index'] = $i; + + // ----- Look for the specific extract rules + $v_found = false; + + // ----- Look for extract by name rule + if ( (isset($p_options[PCLZIP_OPT_BY_NAME])) + && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) { + + // ----- Look if the filename is in the list + for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_found); $j++) { + + // ----- Look for a directory + if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") { + + // ----- Look if the directory is in the filename path + if ( (strlen($v_header_list[$v_nb_extracted]['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) + && (substr($v_header_list[$v_nb_extracted]['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) { + $v_found = true; + } + elseif ( (($v_header_list[$v_nb_extracted]['external']&0x00000010)==0x00000010) /* Indicates a folder */ + && ($v_header_list[$v_nb_extracted]['stored_filename'].'/' == $p_options[PCLZIP_OPT_BY_NAME][$j])) { + $v_found = true; + } + } + // ----- Look for a filename + elseif ($v_header_list[$v_nb_extracted]['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) { + $v_found = true; + } + } + } + + // ----- Look for extract by ereg rule + // ereg() is deprecated with PHP 5.3 + /* + else if ( (isset($p_options[PCLZIP_OPT_BY_EREG])) + && ($p_options[PCLZIP_OPT_BY_EREG] != "")) { + + if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header_list[$v_nb_extracted]['stored_filename'])) { + $v_found = true; + } + } + */ + + // ----- Look for extract by preg rule + else if ( (isset($p_options[PCLZIP_OPT_BY_PREG])) + && ($p_options[PCLZIP_OPT_BY_PREG] != "")) { + + if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header_list[$v_nb_extracted]['stored_filename'])) { + $v_found = true; + } + } + + // ----- Look for extract by index rule + else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX])) + && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) { + + // ----- Look if the index is in the list + for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_found); $j++) { + + if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) { + $v_found = true; + } + if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) { + $j_start = $j+1; + } + + if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) { + break; + } + } + } + else { + $v_found = true; + } + + // ----- Look for deletion + if ($v_found) + { + unset($v_header_list[$v_nb_extracted]); + } + else + { + $v_nb_extracted++; + } + } + + // ----- Look if something need to be deleted + if ($v_nb_extracted > 0) { + + // ----- Creates a temporay file + $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; + + // ----- Creates a temporary zip archive + $v_temp_zip = new PclZip($v_zip_temp_name); + + // ----- Open the temporary zip file in write mode + if (($v_result = $v_temp_zip->privOpenFd('wb')) != 1) { + $this->privCloseFd(); + + // ----- Return + return $v_result; + } + + // ----- Look which file need to be kept + for ($i=0; $i<sizeof($v_header_list); $i++) { + + // ----- Calculate the position of the header + @rewind($this->zip_fd); + if (@fseek($this->zip_fd, $v_header_list[$i]['offset'])) { + // ----- Close the zip file + $this->privCloseFd(); + $v_temp_zip->privCloseFd(); + @unlink($v_zip_temp_name); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Read the file header + $v_local_header = array(); + if (($v_result = $this->privReadFileHeader($v_local_header)) != 1) { + // ----- Close the zip file + $this->privCloseFd(); + $v_temp_zip->privCloseFd(); + @unlink($v_zip_temp_name); + + // ----- Return + return $v_result; + } + + // ----- Check that local file header is same as central file header + if ($this->privCheckFileHeaders($v_local_header, + $v_header_list[$i]) != 1) { + // TBC + } + unset($v_local_header); + + // ----- Write the file header + if (($v_result = $v_temp_zip->privWriteFileHeader($v_header_list[$i])) != 1) { + // ----- Close the zip file + $this->privCloseFd(); + $v_temp_zip->privCloseFd(); + @unlink($v_zip_temp_name); + + // ----- Return + return $v_result; + } + + // ----- Read/write the data block + if (($v_result = PclZipUtilCopyBlock($this->zip_fd, $v_temp_zip->zip_fd, $v_header_list[$i]['compressed_size'])) != 1) { + // ----- Close the zip file + $this->privCloseFd(); + $v_temp_zip->privCloseFd(); + @unlink($v_zip_temp_name); + + // ----- Return + return $v_result; + } + } + + // ----- Store the offset of the central dir + $v_offset = @ftell($v_temp_zip->zip_fd); + + // ----- Re-Create the Central Dir files header + for ($i=0; $i<sizeof($v_header_list); $i++) { + // ----- Create the file header + if (($v_result = $v_temp_zip->privWriteCentralFileHeader($v_header_list[$i])) != 1) { + $v_temp_zip->privCloseFd(); + $this->privCloseFd(); + @unlink($v_zip_temp_name); + + // ----- Return + return $v_result; + } + + // ----- Transform the header to a 'usable' info + $v_temp_zip->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); + } + + + // ----- Zip file comment + $v_comment = ''; + if (isset($p_options[PCLZIP_OPT_COMMENT])) { + $v_comment = $p_options[PCLZIP_OPT_COMMENT]; + } + + // ----- Calculate the size of the central header + $v_size = @ftell($v_temp_zip->zip_fd)-$v_offset; + + // ----- Create the central dir footer + if (($v_result = $v_temp_zip->privWriteCentralHeader(sizeof($v_header_list), $v_size, $v_offset, $v_comment)) != 1) { + // ----- Reset the file list + unset($v_header_list); + $v_temp_zip->privCloseFd(); + $this->privCloseFd(); + @unlink($v_zip_temp_name); + + // ----- Return + return $v_result; + } + + // ----- Close + $v_temp_zip->privCloseFd(); + $this->privCloseFd(); + + // ----- Delete the zip file + // TBC : I should test the result ... + @unlink($this->zipname); + + // ----- Rename the temporary file + // TBC : I should test the result ... + //@rename($v_zip_temp_name, $this->zipname); + PclZipUtilRename($v_zip_temp_name, $this->zipname); + + // ----- Destroy the temporary archive + unset($v_temp_zip); + } + + // ----- Remove every files : reset the file + else if ($v_central_dir['entries'] != 0) { + $this->privCloseFd(); + + if (($v_result = $this->privOpenFd('wb')) != 1) { + return $v_result; + } + + if (($v_result = $this->privWriteCentralHeader(0, 0, 0, '')) != 1) { + return $v_result; + } + + $this->privCloseFd(); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privDirCheck() + // Description : + // Check if a directory exists, if not it creates it and all the parents directory + // which may be useful. + // Parameters : + // $p_dir : Directory path to check. + // Return Values : + // 1 : OK + // -1 : Unable to create directory + // -------------------------------------------------------------------------------- + function privDirCheck($p_dir, $p_is_dir=false) + { + $v_result = 1; + + + // ----- Remove the final '/' + if (($p_is_dir) && (substr($p_dir, -1)=='/')) + { + $p_dir = substr($p_dir, 0, strlen($p_dir)-1); + } + + // ----- Check the directory availability + if ((is_dir($p_dir)) || ($p_dir == "")) + { + return 1; + } + + // ----- Extract parent directory + $p_parent_dir = dirname($p_dir); + + // ----- Just a check + if ($p_parent_dir != $p_dir) + { + // ----- Look for parent directory + if ($p_parent_dir != "") + { + if (($v_result = $this->privDirCheck($p_parent_dir)) != 1) + { + return $v_result; + } + } + } + + // ----- Create the directory + if (!@mkdir($p_dir, 0777)) + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_DIR_CREATE_FAIL, "Unable to create directory '$p_dir'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privMerge() + // Description : + // If $p_archive_to_add does not exist, the function exit with a success result. + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privMerge(&$p_archive_to_add) + { + $v_result=1; + + // ----- Look if the archive_to_add exists + if (!is_file($p_archive_to_add->zipname)) + { + + // ----- Nothing to merge, so merge is a success + $v_result = 1; + + // ----- Return + return $v_result; + } + + // ----- Look if the archive exists + if (!is_file($this->zipname)) + { + + // ----- Do a duplicate + $v_result = $this->privDuplicate($p_archive_to_add->zipname); + + // ----- Return + return $v_result; + } + + // ----- Open the zip file + if (($v_result=$this->privOpenFd('rb')) != 1) + { + // ----- Return + return $v_result; + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) + { + $this->privCloseFd(); + return $v_result; + } + + // ----- Go to beginning of File + @rewind($this->zip_fd); + + // ----- Open the archive_to_add file + if (($v_result=$p_archive_to_add->privOpenFd('rb')) != 1) + { + $this->privCloseFd(); + + // ----- Return + return $v_result; + } + + // ----- Read the central directory informations + $v_central_dir_to_add = array(); + if (($v_result = $p_archive_to_add->privReadEndCentralDir($v_central_dir_to_add)) != 1) + { + $this->privCloseFd(); + $p_archive_to_add->privCloseFd(); + + return $v_result; + } + + // ----- Go to beginning of File + @rewind($p_archive_to_add->zip_fd); + + // ----- Creates a temporay file + $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; + + // ----- Open the temporary file in write mode + if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0) + { + $this->privCloseFd(); + $p_archive_to_add->privCloseFd(); + + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Copy the files from the archive to the temporary file + // TBC : Here I should better append the file and go back to erase the central dir + $v_size = $v_central_dir['offset']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = fread($this->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Copy the files from the archive_to_add into the temporary file + $v_size = $v_central_dir_to_add['offset']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = fread($p_archive_to_add->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Store the offset of the central dir + $v_offset = @ftell($v_zip_temp_fd); + + // ----- Copy the block of file headers from the old archive + $v_size = $v_central_dir['size']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($this->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Copy the block of file headers from the archive_to_add + $v_size = $v_central_dir_to_add['size']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($p_archive_to_add->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Merge the file comments + $v_comment = $v_central_dir['comment'].' '.$v_central_dir_to_add['comment']; + + // ----- Calculate the size of the (new) central header + $v_size = @ftell($v_zip_temp_fd)-$v_offset; + + // ----- Swap the file descriptor + // Here is a trick : I swap the temporary fd with the zip fd, in order to use + // the following methods on the temporary fil and not the real archive fd + $v_swap = $this->zip_fd; + $this->zip_fd = $v_zip_temp_fd; + $v_zip_temp_fd = $v_swap; + + // ----- Create the central dir footer + if (($v_result = $this->privWriteCentralHeader($v_central_dir['entries']+$v_central_dir_to_add['entries'], $v_size, $v_offset, $v_comment)) != 1) + { + $this->privCloseFd(); + $p_archive_to_add->privCloseFd(); + @fclose($v_zip_temp_fd); + $this->zip_fd = null; + + // ----- Reset the file list + unset($v_header_list); + + // ----- Return + return $v_result; + } + + // ----- Swap back the file descriptor + $v_swap = $this->zip_fd; + $this->zip_fd = $v_zip_temp_fd; + $v_zip_temp_fd = $v_swap; + + // ----- Close + $this->privCloseFd(); + $p_archive_to_add->privCloseFd(); + + // ----- Close the temporary file + @fclose($v_zip_temp_fd); + + // ----- Delete the zip file + // TBC : I should test the result ... + @unlink($this->zipname); + + // ----- Rename the temporary file + // TBC : I should test the result ... + //@rename($v_zip_temp_name, $this->zipname); + PclZipUtilRename($v_zip_temp_name, $this->zipname); + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privDuplicate() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privDuplicate($p_archive_filename) + { + $v_result=1; + + // ----- Look if the $p_archive_filename exists + if (!is_file($p_archive_filename)) + { + + // ----- Nothing to duplicate, so duplicate is a success. + $v_result = 1; + + // ----- Return + return $v_result; + } + + // ----- Open the zip file + if (($v_result=$this->privOpenFd('wb')) != 1) + { + // ----- Return + return $v_result; + } + + // ----- Open the temporary file in write mode + if (($v_zip_temp_fd = @fopen($p_archive_filename, 'rb')) == 0) + { + $this->privCloseFd(); + + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive file \''.$p_archive_filename.'\' in binary write mode'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Copy the files from the archive to the temporary file + // TBC : Here I should better append the file and go back to erase the central dir + $v_size = filesize($p_archive_filename); + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = fread($v_zip_temp_fd, $v_read_size); + @fwrite($this->zip_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Close + $this->privCloseFd(); + + // ----- Close the temporary file + @fclose($v_zip_temp_fd); + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privErrorLog() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function privErrorLog($p_error_code=0, $p_error_string='') + { + if (PCLZIP_ERROR_EXTERNAL == 1) { + PclError($p_error_code, $p_error_string); + } + else { + $this->error_code = $p_error_code; + $this->error_string = $p_error_string; + } + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privErrorReset() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function privErrorReset() + { + if (PCLZIP_ERROR_EXTERNAL == 1) { + PclErrorReset(); + } + else { + $this->error_code = 0; + $this->error_string = ''; + } + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privDisableMagicQuotes() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privDisableMagicQuotes() + { + $v_result=1; + + // ----- Look if function exists + if ( (!function_exists("get_magic_quotes_runtime")) + || (!function_exists("set_magic_quotes_runtime"))) { + return $v_result; + } + + // ----- Look if already done + if ($this->magic_quotes_status != -1) { + return $v_result; + } + + // ----- Get and memorize the magic_quote value + $this->magic_quotes_status = @get_magic_quotes_runtime(); + + // ----- Disable magic_quotes + if ($this->magic_quotes_status == 1) { + @set_magic_quotes_runtime(0); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privSwapBackMagicQuotes() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privSwapBackMagicQuotes() + { + $v_result=1; + + // ----- Look if function exists + if ( (!function_exists("get_magic_quotes_runtime")) + || (!function_exists("set_magic_quotes_runtime"))) { + return $v_result; + } + + // ----- Look if something to do + if ($this->magic_quotes_status != -1) { + return $v_result; + } + + // ----- Swap back magic_quotes + if ($this->magic_quotes_status == 1) { + @set_magic_quotes_runtime($this->magic_quotes_status); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + } + // End of class + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : PclZipUtilPathReduction() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function PclZipUtilPathReduction($p_dir) + { + $v_result = ""; + + // ----- Look for not empty path + if ($p_dir != "") { + // ----- Explode path by directory names + $v_list = explode("/", $p_dir); + + // ----- Study directories from last to first + $v_skip = 0; + for ($i=sizeof($v_list)-1; $i>=0; $i--) { + // ----- Look for current path + if ($v_list[$i] == ".") { + // ----- Ignore this directory + // Should be the first $i=0, but no check is done + } + else if ($v_list[$i] == "..") { + $v_skip++; + } + else if ($v_list[$i] == "") { + // ----- First '/' i.e. root slash + if ($i == 0) { + $v_result = "/".$v_result; + if ($v_skip > 0) { + // ----- It is an invalid path, so the path is not modified + // TBC + $v_result = $p_dir; + $v_skip = 0; + } + } + // ----- Last '/' i.e. indicates a directory + else if ($i == (sizeof($v_list)-1)) { + $v_result = $v_list[$i]; + } + // ----- Double '/' inside the path + else { + // ----- Ignore only the double '//' in path, + // but not the first and last '/' + } + } + else { + // ----- Look for item to skip + if ($v_skip > 0) { + $v_skip--; + } + else { + $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?"/".$v_result:""); + } + } + } + + // ----- Look for skip + if ($v_skip > 0) { + while ($v_skip > 0) { + $v_result = '../'.$v_result; + $v_skip--; + } + } + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : PclZipUtilPathInclusion() + // Description : + // This function indicates if the path $p_path is under the $p_dir tree. Or, + // said in an other way, if the file or sub-dir $p_path is inside the dir + // $p_dir. + // The function indicates also if the path is exactly the same as the dir. + // This function supports path with duplicated '/' like '//', but does not + // support '.' or '..' statements. + // Parameters : + // Return Values : + // 0 if $p_path is not inside directory $p_dir + // 1 if $p_path is inside directory $p_dir + // 2 if $p_path is exactly the same as $p_dir + // -------------------------------------------------------------------------------- + function PclZipUtilPathInclusion($p_dir, $p_path) + { + $v_result = 1; + + // ----- Look for path beginning by ./ + if ( ($p_dir == '.') + || ((strlen($p_dir) >=2) && (substr($p_dir, 0, 2) == './'))) { + $p_dir = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_dir, 1); + } + if ( ($p_path == '.') + || ((strlen($p_path) >=2) && (substr($p_path, 0, 2) == './'))) { + $p_path = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_path, 1); + } + + // ----- Explode dir and path by directory separator + $v_list_dir = explode("/", $p_dir); + $v_list_dir_size = sizeof($v_list_dir); + $v_list_path = explode("/", $p_path); + $v_list_path_size = sizeof($v_list_path); + + // ----- Study directories paths + $i = 0; + $j = 0; + while (($i < $v_list_dir_size) && ($j < $v_list_path_size) && ($v_result)) { + + // ----- Look for empty dir (path reduction) + if ($v_list_dir[$i] == '') { + $i++; + continue; + } + if ($v_list_path[$j] == '') { + $j++; + continue; + } + + // ----- Compare the items + if (($v_list_dir[$i] != $v_list_path[$j]) && ($v_list_dir[$i] != '') && ( $v_list_path[$j] != '')) { + $v_result = 0; + } + + // ----- Next items + $i++; + $j++; + } + + // ----- Look if everything seems to be the same + if ($v_result) { + // ----- Skip all the empty items + while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) $j++; + while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) $i++; + + if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) { + // ----- There are exactly the same + $v_result = 2; + } + else if ($i < $v_list_dir_size) { + // ----- The path is shorter than the dir + $v_result = 0; + } + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : PclZipUtilCopyBlock() + // Description : + // Parameters : + // $p_mode : read/write compression mode + // 0 : src & dest normal + // 1 : src gzip, dest normal + // 2 : src normal, dest gzip + // 3 : src & dest gzip + // Return Values : + // -------------------------------------------------------------------------------- + function PclZipUtilCopyBlock($p_src, $p_dest, $p_size, $p_mode=0) + { + $v_result = 1; + + if ($p_mode==0) + { + while ($p_size != 0) + { + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($p_src, $v_read_size); + @fwrite($p_dest, $v_buffer, $v_read_size); + $p_size -= $v_read_size; + } + } + else if ($p_mode==1) + { + while ($p_size != 0) + { + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @gzread($p_src, $v_read_size); + @fwrite($p_dest, $v_buffer, $v_read_size); + $p_size -= $v_read_size; + } + } + else if ($p_mode==2) + { + while ($p_size != 0) + { + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($p_src, $v_read_size); + @gzwrite($p_dest, $v_buffer, $v_read_size); + $p_size -= $v_read_size; + } + } + else if ($p_mode==3) + { + while ($p_size != 0) + { + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @gzread($p_src, $v_read_size); + @gzwrite($p_dest, $v_buffer, $v_read_size); + $p_size -= $v_read_size; + } + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : PclZipUtilRename() + // Description : + // This function tries to do a simple rename() function. If it fails, it + // tries to copy the $p_src file in a new $p_dest file and then unlink the + // first one. + // Parameters : + // $p_src : Old filename + // $p_dest : New filename + // Return Values : + // 1 on success, 0 on failure. + // -------------------------------------------------------------------------------- + function PclZipUtilRename($p_src, $p_dest) + { + $v_result = 1; + + // ----- Try to rename the files + if (!@rename($p_src, $p_dest)) { + + // ----- Try to copy & unlink the src + if (!@copy($p_src, $p_dest)) { + $v_result = 0; + } + else if (!@unlink($p_src)) { + $v_result = 0; + } + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : PclZipUtilOptionText() + // Description : + // Translate option value in text. Mainly for debug purpose. + // Parameters : + // $p_option : the option value. + // Return Values : + // The option text value. + // -------------------------------------------------------------------------------- + function PclZipUtilOptionText($p_option) + { + + $v_list = get_defined_constants(); + for (reset($v_list); $v_key = key($v_list); next($v_list)) { + $v_prefix = substr($v_key, 0, 10); + if (( ($v_prefix == 'PCLZIP_OPT') + || ($v_prefix == 'PCLZIP_CB_') + || ($v_prefix == 'PCLZIP_ATT')) + && ($v_list[$v_key] == $p_option)) { + return $v_key; + } + } + + $v_result = 'Unknown'; + + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : PclZipUtilTranslateWinPath() + // Description : + // Translate windows path by replacing '\' by '/' and optionally removing + // drive letter. + // Parameters : + // $p_path : path to translate. + // $p_remove_disk_letter : true | false + // Return Values : + // The path translated. + // -------------------------------------------------------------------------------- + function PclZipUtilTranslateWinPath($p_path, $p_remove_disk_letter=true) + { + if (stristr(php_uname(), 'windows')) { + // ----- Look for potential disk letter + if (($p_remove_disk_letter) && (($v_position = strpos($p_path, ':')) != false)) { + $p_path = substr($p_path, $v_position+1); + } + // ----- Change potential windows directory separator + if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0,1) == '\\')) { + $p_path = strtr($p_path, '\\', '/'); + } + } + return $p_path; + } + // -------------------------------------------------------------------------------- + + +?> diff --git a/lib/phpexcel/PHPExcel/Shared/PCLZip/readme.txt b/lib/phpexcel/PHPExcel/Shared/PCLZip/readme.txt new file mode 100644 index 0000000..6ed8839 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Shared/PCLZip/readme.txt @@ -0,0 +1,421 @@ +// -------------------------------------------------------------------------------- +// PclZip 2.8.2 - readme.txt +// -------------------------------------------------------------------------------- +// License GNU/LGPL - August 2009 +// Vincent Blavet - vincent@phpconcept.net +// http://www.phpconcept.net +// -------------------------------------------------------------------------------- +// $Id: readme.txt,v 1.60 2009/09/30 20:35:21 vblavet Exp $ +// -------------------------------------------------------------------------------- + + + +0 - Sommaire +============ + 1 - Introduction + 2 - What's new + 3 - Corrected bugs + 4 - Known bugs or limitations + 5 - License + 6 - Warning + 7 - Documentation + 8 - Author + 9 - Contribute + +1 - Introduction +================ + + PclZip is a library that allow you to manage a Zip archive. + + Full documentation about PclZip can be found here : http://www.phpconcept.net/pclzip + +2 - What's new +============== + + Version 2.8.2 : + - PCLZIP_CB_PRE_EXTRACT and PCLZIP_CB_POST_EXTRACT are now supported with + extraction as a string (PCLZIP_OPT_EXTRACT_AS_STRING). The string + can also be modified in the post-extract call back. + **Bugs correction : + - PCLZIP_OPT_REMOVE_ALL_PATH was not working correctly + - Remove use of eval() and do direct call to callback functions + - Correct support of 64bits systems (Thanks to WordPress team) + + Version 2.8.1 : + - Move option PCLZIP_OPT_BY_EREG to PCLZIP_OPT_BY_PREG because ereg() is + deprecated in PHP 5.3. When using option PCLZIP_OPT_BY_EREG, PclZip will + automatically replace it by PCLZIP_OPT_BY_PREG. + + Version 2.8 : + - Improve extraction of zip archive for large files by using temporary files + This feature is working like the one defined in r2.7. + Options are renamed : PCLZIP_OPT_TEMP_FILE_ON, PCLZIP_OPT_TEMP_FILE_OFF, + PCLZIP_OPT_TEMP_FILE_THRESHOLD + - Add a ratio constant PCLZIP_TEMPORARY_FILE_RATIO to configure the auto + sense of temporary file use. + - Bug correction : Reduce filepath in returned file list to remove ennoying + './/' preambule in file path. + + Version 2.7 : + - Improve creation of zip archive for large files : + PclZip will now autosense the configured memory and use temporary files + when large file is suspected. + This feature can also ne triggered by manual options in create() and add() + methods. 'PCLZIP_OPT_ADD_TEMP_FILE_ON' force the use of temporary files, + 'PCLZIP_OPT_ADD_TEMP_FILE_OFF' disable the autosense technic, + 'PCLZIP_OPT_ADD_TEMP_FILE_THRESHOLD' allow for configuration of a size + threshold to use temporary files. + Using "temporary files" rather than "memory" might take more time, but + might give the ability to zip very large files : + Tested on my win laptop with a 88Mo file : + Zip "in-memory" : 18sec (max_execution_time=30, memory_limit=180Mo) + Zip "tmporary-files" : 23sec (max_execution_time=30, memory_limit=30Mo) + - Replace use of mktime() by time() to limit the E_STRICT error messages. + - Bug correction : When adding files with full windows path (drive letter) + PclZip is now working. Before, if the drive letter is not the default + path, PclZip was not able to add the file. + + Version 2.6 : + - Code optimisation + - New attributes PCLZIP_ATT_FILE_COMMENT gives the ability to + add a comment for a specific file. (Don't really know if this is usefull) + - New attribute PCLZIP_ATT_FILE_CONTENT gives the ability to add a string + as a file. + - New attribute PCLZIP_ATT_FILE_MTIME modify the timestamp associated with + a file. + - Correct a bug. Files archived with a timestamp with 0h0m0s were extracted + with current time + - Add CRC value in the informations returned back for each file after an + action. + - Add missing closedir() statement. + - When adding a folder, and removing the path of this folder, files were + incorrectly added with a '/' at the beginning. Which means files are + related to root in unix systems. Corrected. + - Add conditional if before constant definition. This will allow users + to redefine constants without changing the file, and then improve + upgrade of pclzip code for new versions. + + Version 2.5 : + - Introduce the ability to add file/folder with individual properties (file descriptor). + This gives for example the ability to change the filename of a zipped file. + . Able to add files individually + . Able to change full name + . Able to change short name + . Compatible with global options + - New attributes : PCLZIP_ATT_FILE_NAME, PCLZIP_ATT_FILE_NEW_SHORT_NAME, PCLZIP_ATT_FILE_NEW_FULL_NAME + - New error code : PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE + - Add a security control feature. PclZip can extract any file in any folder + of a system. People may use this to upload a zip file and try to override + a system file. The PCLZIP_OPT_EXTRACT_DIR_RESTRICTION will give the + ability to forgive any directory transversal behavior. + - New PCLZIP_OPT_EXTRACT_DIR_RESTRICTION : check extraction path + - New error code : PCLZIP_ERR_DIRECTORY_RESTRICTION + - Modification in PclZipUtilPathInclusion() : dir and path beginning with ./ will be prepend + by current path (getcwd()) + + Version 2.4 : + - Code improvment : try to speed up the code by removing unusefull call to pack() + - Correct bug in delete() : delete() should be called with no argument. This was not + the case in 2.3. This is corrected in 2.4. + - Correct a bug in path_inclusion function. When the path has several '../../', the + result was bad. + - Add a check for magic_quotes_runtime configuration. If enabled, PclZip will + disable it while working and det it back to its original value. + This resolve a lots of bad formated archive errors. + - Bug correction : PclZip now correctly unzip file in some specific situation, + when compressed content has same size as uncompressed content. + - Bug correction : When selecting option 'PCLZIP_OPT_REMOVE_ALL_PATH', + directories are not any more created. + - Code improvment : correct unclosed opendir(), better handling of . and .. in + loops. + + + Version 2.3 : + - Correct a bug with PHP5 : affecting the value 0xFE49FFE0 to a variable does not + give the same result in PHP4 and PHP5 .... + + Version 2.2 : + - Try development of PCLZIP_OPT_CRYPT ..... + However this becomes to a stop. To crypt/decrypt I need to multiply 2 long integers, + the result (greater than a long) is not supported by PHP. Even the use of bcmath + functions does not help. I did not find yet a solution ...; + - Add missing '/' at end of directory entries + - Check is a file is encrypted or not. Returns status 'unsupported_encryption' and/or + error code PCLZIP_ERR_UNSUPPORTED_ENCRYPTION. + - Corrected : Bad "version need to extract" field in local file header + - Add private method privCheckFileHeaders() in order to check local and central + file headers. PclZip is now supporting purpose bit flag bit 3. Purpose bit flag bit 3 gives + the ability to have a local file header without size, compressed size and crc filled. + - Add a generic status 'error' for file status + - Add control of compression type. PclZip only support deflate compression method. + Before v2.2, PclZip does not check the compression method used in an archive while + extracting. With v2.2 PclZip returns a new error status for a file using an unsupported + compression method. New status is "unsupported_compression". New error code is + PCLZIP_ERR_UNSUPPORTED_COMPRESSION. + - Add optional attribute PCLZIP_OPT_STOP_ON_ERROR. This will stop the extract of files + when errors like 'a folder with same name exists' or 'a newer file exists' or + 'a write protected file' exists, rather than set a status for the concerning file + and resume the extract of the zip. + - Add optional attribute PCLZIP_OPT_REPLACE_NEWER. This will force, during an extract' the + replacement of the file, even if a newer version of the file exists. + Note that today if a file with the same name already exists but is older it will be + replaced by the extracted one. + - Improve PclZipUtilOption() + - Support of zip archive with trailing bytes. Before 2.2, PclZip checks that the central + directory structure is the last data in the archive. Crypt encryption/decryption of + zip archive put trailing 0 bytes after decryption. PclZip is now supporting this. + + Version 2.1 : + - Add the ability to abort the extraction by using a user callback function. + The user can now return the value '2' in its callback which indicates to stop the + extraction. For a pre call-back extract is stopped before the extration of the current + file. For a post call back, the extraction is stopped after. + - Add the ability to extract a file (or several files) directly in the standard output. + This is done by the new parameter PCLZIP_OPT_EXTRACT_IN_OUTPUT with method extract(). + - Add support for parameters PCLZIP_OPT_COMMENT, PCLZIP_OPT_ADD_COMMENT, + PCLZIP_OPT_PREPEND_COMMENT. This will create, replace, add, or prepend comments + in the zip archive. + - When merging two archives, the comments are not any more lost, but merged, with a + blank space separator. + - Corrected bug : Files are not deleted when all files are asked to be deleted. + - Corrected bug : Folders with name '0' made PclZip to abort the create or add feature. + + + Version 2.0 : + ***** Warning : Some new features may break the backward compatibility for your scripts. + Please carefully read the readme file. + - Add the ability to delete by Index, name and regular expression. This feature is + performed by the method delete(), which uses the optional parameters + PCLZIP_OPT_BY_INDEX, PCLZIP_OPT_BY_NAME, PCLZIP_OPT_BY_EREG or PCLZIP_OPT_BY_PREG. + - Add the ability to extract by regular expression. To extract by regexp you must use the method + extract(), with the option PCLZIP_OPT_BY_EREG or PCLZIP_OPT_BY_PREG + (depending if you want to use ereg() or preg_match() syntax) followed by the + regular expression pattern. + - Add the ability to extract by index, directly with the extract() method. This is a + code improvment of the extractByIndex() method. + - Add the ability to extract by name. To extract by name you must use the method + extract(), with the option PCLZIP_OPT_BY_NAME followed by the filename to + extract or an array of filenames to extract. To extract all a folder, use the folder + name rather than the filename with a '/' at the end. + - Add the ability to add files without compression. This is done with a new attribute + which is PCLZIP_OPT_NO_COMPRESSION. + - Add the attribute PCLZIP_OPT_EXTRACT_AS_STRING, which allow to extract a file directly + in a string without using any file (or temporary file). + - Add constant PCLZIP_SEPARATOR for static configuration of filename separators in a single string. + The default separator is now a comma (,) and not any more a blank space. + THIS BREAK THE BACKWARD COMPATIBILITY : Please check if this may have an impact with + your script. + - Improve algorythm performance by removing the use of temporary files when adding or + extracting files in an archive. + - Add (correct) detection of empty filename zipping. This can occurs when the removed + path is the same + as a zipped dir. The dir is not zipped (['status'] = filtered), only its content. + - Add better support for windows paths (thanks for help from manus@manusfreedom.com). + - Corrected bug : When the archive file already exists with size=0, the add() method + fails. Corrected in 2.0. + - Remove the use of OS_WINDOWS constant. Use php_uname() function rather. + - Control the order of index ranges in extract by index feature. + - Change the internal management of folders (better handling of internal flag). + + + Version 1.3 : + - Removing the double include check. This is now done by include_once() and require_once() + PHP directives. + - Changing the error handling mecanism : Remove the use of an external error library. + The former PclError...() functions are replaced by internal equivalent methods. + By changing the environment variable PCLZIP_ERROR_EXTERNAL you can still use the former library. + Introducing the use of constants for error codes rather than integer values. This will help + in futur improvment. + Introduction of error handling functions like errorCode(), errorName() and errorInfo(). + - Remove the deprecated use of calling function with arguments passed by reference. + - Add the calling of extract(), extractByIndex(), create() and add() functions + with variable options rather than fixed arguments. + - Add the ability to remove all the file path while extracting or adding, + without any need to specify the path to remove. + This is available for extract(), extractByIndex(), create() and add() functionS by using + the new variable options parameters : + - PCLZIP_OPT_REMOVE_ALL_PATH : by indicating this option while calling the fct. + - Ability to change the mode of a file after the extraction (chmod()). + This is available for extract() and extractByIndex() functionS by using + the new variable options parameters. + - PCLZIP_OPT_SET_CHMOD : by setting the value of this option. + - Ability to definition call-back options. These call-back will be called during the adding, + or the extracting of file (extract(), extractByIndex(), create() and add() functions) : + - PCLZIP_CB_PRE_EXTRACT : will be called before each extraction of a file. The user + can trigerred the change the filename of the extracted file. The user can triggered the + skip of the extraction. This is adding a 'skipped' status in the file list result value. + - PCLZIP_CB_POST_EXTRACT : will be called after each extraction of a file. + Nothing can be triggered from that point. + - PCLZIP_CB_PRE_ADD : will be called before each add of a file. The user + can trigerred the change the stored filename of the added file. The user can triggered the + skip of the add. This is adding a 'skipped' status in the file list result value. + - PCLZIP_CB_POST_ADD : will be called after each add of a file. + Nothing can be triggered from that point. + - Two status are added in the file list returned as function result : skipped & filename_too_long + 'skipped' is used when a call-back function ask for skipping the file. + 'filename_too_long' is used while adding a file with a too long filename to archive (the file is + not added) + - Adding the function PclZipUtilPathInclusion(), that check the inclusion of a path into + a directory. + - Add a check of the presence of the archive file before some actions (like list, ...) + - Add the initialisation of field "index" in header array. This means that by + default index will be -1 when not explicitly set by the methods. + + Version 1.2 : + - Adding a duplicate function. + - Adding a merge function. The merge function is a "quick merge" function, + it just append the content of an archive at the end of the first one. There + is no check for duplicate files or more recent files. + - Improve the search of the central directory end. + + Version 1.1.2 : + + - Changing the license of PclZip. PclZip is now released under the GNU / LGPL license + (see License section). + - Adding the optional support of a static temporary directory. You will need to configure + the constant PCLZIP_TEMPORARY_DIR if you want to use this feature. + - Improving the rename() function. In some cases rename() does not work (different + Filesystems), so it will be replaced by a copy() + unlink() functions. + + Version 1.1.1 : + + - Maintenance release, no new feature. + + Version 1.1 : + + - New method Add() : adding files in the archive + - New method ExtractByIndex() : partial extract of the archive, files are identified by + their index in the archive + - New method DeleteByIndex() : delete some files/folder entries from the archive, + files are identified by their index in the archive. + - Adding a test of the zlib extension presence. If not present abort the script. + + Version 1.0.1 : + + - No new feature + + +3 - Corrected bugs +================== + + Corrected in Version 2.0 : + - Corrected : During an extraction, if a call-back fucntion is used and try to skip + a file, all the extraction process is stopped. + + Corrected in Version 1.3 : + - Corrected : Support of static synopsis for method extract() is broken. + - Corrected : invalid size of archive content field (0xFF) should be (0xFFFF). + - Corrected : When an extract is done with a remove_path parameter, the entry for + the directory with exactly the same path is not skipped/filtered. + - Corrected : extractByIndex() and deleteByIndex() were not managing index in the + right way. For example indexes '1,3-5,11' will only extract files 1 and 11. This + is due to a sort of the index resulting table that puts 11 before 3-5 (sort on + string and not interger). The sort is temporarilly removed, this means that + you must provide a sorted list of index ranges. + + Corrected in Version 1.2 : + + - Nothing. + + Corrected in Version 1.1.2 : + + - Corrected : Winzip is unable to delete or add new files in a PclZip created archives. + + Corrected in Version 1.1.1 : + + - Corrected : When archived file is not compressed (0% compression), the + extract method fails. + + Corrected in Version 1.1 : + + - Corrected : Adding a complete tree of folder may result in a bad archive + creation. + + Corrected in Version 1.0.1 : + + - Corrected : Error while compressing files greater than PCLZIP_READ_BLOCK_SIZE (default=1024). + + +4 - Known bugs or limitations +============================= + + Please publish bugs reports in SourceForge : + http://sourceforge.net/tracker/?group_id=40254&atid=427564 + + In Version 2.x : + - PclZip does only support file uncompressed or compressed with deflate (compression method 8) + - PclZip does not support password protected zip archive + - Some concern were seen when changing mtime of a file while archiving. + Seems to be linked to Daylight Saving Time (PclTest_changing_mtime). + + In Version 1.2 : + + - merge() methods does not check for duplicate files or last date of modifications. + + In Version 1.1 : + + - Limitation : Using 'extract' fields in the file header in the zip archive is not supported. + - WinZip is unable to delete a single file in a PclZip created archive. It is also unable to + add a file in a PclZip created archive. (Corrected in v.1.2) + + In Version 1.0.1 : + + - Adding a complete tree of folder may result in a bad archive + creation. (Corrected in V.1.1). + - Path given to methods must be in the unix format (/) and not the Windows format (\). + Workaround : Use only / directory separators. + - PclZip is using temporary files that are sometime the name of the file with a .tmp or .gz + added suffix. Files with these names may already exist and may be overwritten. + Workaround : none. + - PclZip does not check if the zlib extension is present. If it is absent, the zip + file is not created and the lib abort without warning. + Workaround : enable the zlib extension on the php install + + In Version 1.0 : + + - Error while compressing files greater than PCLZIP_READ_BLOCK_SIZE (default=1024). + (Corrected in v.1.0.1) + - Limitation : Multi-disk zip archive are not supported. + + +5 - License +=========== + + Since version 1.1.2, PclZip Library is released under GNU/LGPL license. + This library is free, so you can use it at no cost. + + HOWEVER, if you release a script, an application, a library or any kind of + code using PclZip library (or a part of it), YOU MUST : + - Indicate in the documentation (or a readme file), that your work + uses PclZip Library, and make a reference to the author and the web site + http://www.phpconcept.net + - Gives the ability to the final user to update the PclZip libary. + + I will also appreciate that you send me a mail (vincent@phpconcept.net), just to + be aware that someone is using PclZip. + + For more information about GNU/LGPL license : http://www.gnu.org + +6 - Warning +================= + + This library and the associated files are non commercial, non professional work. + It should not have unexpected results. However if any damage is caused by this software + the author can not be responsible. + The use of this software is at the risk of the user. + +7 - Documentation +================= + PclZip User Manuel is available in English on PhpConcept : http://www.phpconcept.net/pclzip/man/en/index.php + A Russian translation was done by Feskov Kuzma : http://php.russofile.ru/ru/authors/unsort/zip/ + +8 - Author +========== + + This software was written by Vincent Blavet (vincent@phpconcept.net) on its leasure time. + +9 - Contribute +============== + If you want to contribute to the development of PclZip, please contact vincent@phpconcept.net. + If you can help in financing PhpConcept hosting service, please go to + http://www.phpconcept.net/soutien.php diff --git a/lib/phpexcel/PHPExcel/Shared/PasswordHasher.php b/lib/phpexcel/PHPExcel/Shared/PasswordHasher.php new file mode 100644 index 0000000..4f505a2 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Shared/PasswordHasher.php @@ -0,0 +1,66 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Shared_PasswordHasher + * + * @category PHPExcel + * @package PHPExcel_Shared + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Shared_PasswordHasher +{ + /** + * Create a password hash from a given string. + * + * This method is based on the algorithm provided by + * Daniel Rentz of OpenOffice and the PEAR package + * Spreadsheet_Excel_Writer by Xavier Noguer <xnoguer@rezebra.com>. + * + * @param string $pPassword Password to hash + * @return string Hashed password + */ + public static function hashPassword($pPassword = '') { + $password = 0x0000; + $charPos = 1; // char position + + // split the plain text password in its component characters + $chars = preg_split('//', $pPassword, -1, PREG_SPLIT_NO_EMPTY); + foreach ($chars as $char) { + $value = ord($char) << $charPos++; // shifted ASCII value + $rotated_bits = $value >> 15; // rotated bits beyond bit 15 + $value &= 0x7fff; // first 15 bits + $password ^= ($value | $rotated_bits); + } + + $password ^= strlen($pPassword); + $password ^= 0xCE4B; + + return(strtoupper(dechex($password))); + } +} diff --git a/lib/phpexcel/PHPExcel/Shared/String.php b/lib/phpexcel/PHPExcel/Shared/String.php new file mode 100644 index 0000000..49d217a --- /dev/null +++ b/lib/phpexcel/PHPExcel/Shared/String.php @@ -0,0 +1,776 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Shared_String + * + * @category PHPExcel + * @package PHPExcel_Shared + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Shared_String +{ + /** Constants */ + /** Regular Expressions */ + // Fraction + const STRING_REGEXP_FRACTION = '(-?)(\d+)\s+(\d+\/\d+)'; + + + /** + * Control characters array + * + * @var string[] + */ + private static $_controlCharacters = array(); + + /** + * SYLK Characters array + * + * $var array + */ + private static $_SYLKCharacters = array(); + + /** + * Decimal separator + * + * @var string + */ + private static $_decimalSeparator; + + /** + * Thousands separator + * + * @var string + */ + private static $_thousandsSeparator; + + /** + * Currency code + * + * @var string + */ + private static $_currencyCode; + + /** + * Is mbstring extension avalable? + * + * @var boolean + */ + private static $_isMbstringEnabled; + + /** + * Is iconv extension avalable? + * + * @var boolean + */ + private static $_isIconvEnabled; + + /** + * Build control characters array + */ + private static function _buildControlCharacters() { + for ($i = 0; $i <= 31; ++$i) { + if ($i != 9 && $i != 10 && $i != 13) { + $find = '_x' . sprintf('%04s' , strtoupper(dechex($i))) . '_'; + $replace = chr($i); + self::$_controlCharacters[$find] = $replace; + } + } + } + + /** + * Build SYLK characters array + */ + private static function _buildSYLKCharacters() + { + self::$_SYLKCharacters = array( + "\x1B 0" => chr(0), + "\x1B 1" => chr(1), + "\x1B 2" => chr(2), + "\x1B 3" => chr(3), + "\x1B 4" => chr(4), + "\x1B 5" => chr(5), + "\x1B 6" => chr(6), + "\x1B 7" => chr(7), + "\x1B 8" => chr(8), + "\x1B 9" => chr(9), + "\x1B :" => chr(10), + "\x1B ;" => chr(11), + "\x1B <" => chr(12), + "\x1B :" => chr(13), + "\x1B >" => chr(14), + "\x1B ?" => chr(15), + "\x1B!0" => chr(16), + "\x1B!1" => chr(17), + "\x1B!2" => chr(18), + "\x1B!3" => chr(19), + "\x1B!4" => chr(20), + "\x1B!5" => chr(21), + "\x1B!6" => chr(22), + "\x1B!7" => chr(23), + "\x1B!8" => chr(24), + "\x1B!9" => chr(25), + "\x1B!:" => chr(26), + "\x1B!;" => chr(27), + "\x1B!<" => chr(28), + "\x1B!=" => chr(29), + "\x1B!>" => chr(30), + "\x1B!?" => chr(31), + "\x1B'?" => chr(127), + "\x1B(0" => '€', // 128 in CP1252 + "\x1B(2" => '‚', // 130 in CP1252 + "\x1B(3" => 'ƒ', // 131 in CP1252 + "\x1B(4" => '„', // 132 in CP1252 + "\x1B(5" => '…', // 133 in CP1252 + "\x1B(6" => '†', // 134 in CP1252 + "\x1B(7" => '‡', // 135 in CP1252 + "\x1B(8" => 'ˆ', // 136 in CP1252 + "\x1B(9" => '‰', // 137 in CP1252 + "\x1B(:" => 'Š', // 138 in CP1252 + "\x1B(;" => '‹', // 139 in CP1252 + "\x1BNj" => 'Œ', // 140 in CP1252 + "\x1B(>" => 'Ž', // 142 in CP1252 + "\x1B)1" => '‘', // 145 in CP1252 + "\x1B)2" => '’', // 146 in CP1252 + "\x1B)3" => '“', // 147 in CP1252 + "\x1B)4" => '”', // 148 in CP1252 + "\x1B)5" => '•', // 149 in CP1252 + "\x1B)6" => '–', // 150 in CP1252 + "\x1B)7" => '—', // 151 in CP1252 + "\x1B)8" => '˜', // 152 in CP1252 + "\x1B)9" => '™', // 153 in CP1252 + "\x1B):" => 'š', // 154 in CP1252 + "\x1B);" => '›', // 155 in CP1252 + "\x1BNz" => 'œ', // 156 in CP1252 + "\x1B)>" => 'ž', // 158 in CP1252 + "\x1B)?" => 'Ÿ', // 159 in CP1252 + "\x1B*0" => ' ', // 160 in CP1252 + "\x1BN!" => '¡', // 161 in CP1252 + "\x1BN\"" => '¢', // 162 in CP1252 + "\x1BN#" => '£', // 163 in CP1252 + "\x1BN(" => '¤', // 164 in CP1252 + "\x1BN%" => '¥', // 165 in CP1252 + "\x1B*6" => '¦', // 166 in CP1252 + "\x1BN'" => '§', // 167 in CP1252 + "\x1BNH " => '¨', // 168 in CP1252 + "\x1BNS" => '©', // 169 in CP1252 + "\x1BNc" => 'ª', // 170 in CP1252 + "\x1BN+" => '«', // 171 in CP1252 + "\x1B*<" => '¬', // 172 in CP1252 + "\x1B*=" => '­', // 173 in CP1252 + "\x1BNR" => '®', // 174 in CP1252 + "\x1B*?" => '¯', // 175 in CP1252 + "\x1BN0" => '°', // 176 in CP1252 + "\x1BN1" => '±', // 177 in CP1252 + "\x1BN2" => '²', // 178 in CP1252 + "\x1BN3" => '³', // 179 in CP1252 + "\x1BNB " => '´', // 180 in CP1252 + "\x1BN5" => 'µ', // 181 in CP1252 + "\x1BN6" => '¶', // 182 in CP1252 + "\x1BN7" => '·', // 183 in CP1252 + "\x1B+8" => '¸', // 184 in CP1252 + "\x1BNQ" => '¹', // 185 in CP1252 + "\x1BNk" => 'º', // 186 in CP1252 + "\x1BN;" => '»', // 187 in CP1252 + "\x1BN<" => '¼', // 188 in CP1252 + "\x1BN=" => '½', // 189 in CP1252 + "\x1BN>" => '¾', // 190 in CP1252 + "\x1BN?" => '¿', // 191 in CP1252 + "\x1BNAA" => 'À', // 192 in CP1252 + "\x1BNBA" => 'Á', // 193 in CP1252 + "\x1BNCA" => 'Â', // 194 in CP1252 + "\x1BNDA" => 'Ã', // 195 in CP1252 + "\x1BNHA" => 'Ä', // 196 in CP1252 + "\x1BNJA" => 'Å', // 197 in CP1252 + "\x1BNa" => 'Æ', // 198 in CP1252 + "\x1BNKC" => 'Ç', // 199 in CP1252 + "\x1BNAE" => 'È', // 200 in CP1252 + "\x1BNBE" => 'É', // 201 in CP1252 + "\x1BNCE" => 'Ê', // 202 in CP1252 + "\x1BNHE" => 'Ë', // 203 in CP1252 + "\x1BNAI" => 'Ì', // 204 in CP1252 + "\x1BNBI" => 'Í', // 205 in CP1252 + "\x1BNCI" => 'Î', // 206 in CP1252 + "\x1BNHI" => 'Ï', // 207 in CP1252 + "\x1BNb" => 'Ð', // 208 in CP1252 + "\x1BNDN" => 'Ñ', // 209 in CP1252 + "\x1BNAO" => 'Ò', // 210 in CP1252 + "\x1BNBO" => 'Ó', // 211 in CP1252 + "\x1BNCO" => 'Ô', // 212 in CP1252 + "\x1BNDO" => 'Õ', // 213 in CP1252 + "\x1BNHO" => 'Ö', // 214 in CP1252 + "\x1B-7" => '×', // 215 in CP1252 + "\x1BNi" => 'Ø', // 216 in CP1252 + "\x1BNAU" => 'Ù', // 217 in CP1252 + "\x1BNBU" => 'Ú', // 218 in CP1252 + "\x1BNCU" => 'Û', // 219 in CP1252 + "\x1BNHU" => 'Ü', // 220 in CP1252 + "\x1B-=" => 'Ý', // 221 in CP1252 + "\x1BNl" => 'Þ', // 222 in CP1252 + "\x1BN{" => 'ß', // 223 in CP1252 + "\x1BNAa" => 'à', // 224 in CP1252 + "\x1BNBa" => 'á', // 225 in CP1252 + "\x1BNCa" => 'â', // 226 in CP1252 + "\x1BNDa" => 'ã', // 227 in CP1252 + "\x1BNHa" => 'ä', // 228 in CP1252 + "\x1BNJa" => 'å', // 229 in CP1252 + "\x1BNq" => 'æ', // 230 in CP1252 + "\x1BNKc" => 'ç', // 231 in CP1252 + "\x1BNAe" => 'è', // 232 in CP1252 + "\x1BNBe" => 'é', // 233 in CP1252 + "\x1BNCe" => 'ê', // 234 in CP1252 + "\x1BNHe" => 'ë', // 235 in CP1252 + "\x1BNAi" => 'ì', // 236 in CP1252 + "\x1BNBi" => 'í', // 237 in CP1252 + "\x1BNCi" => 'î', // 238 in CP1252 + "\x1BNHi" => 'ï', // 239 in CP1252 + "\x1BNs" => 'ð', // 240 in CP1252 + "\x1BNDn" => 'ñ', // 241 in CP1252 + "\x1BNAo" => 'ò', // 242 in CP1252 + "\x1BNBo" => 'ó', // 243 in CP1252 + "\x1BNCo" => 'ô', // 244 in CP1252 + "\x1BNDo" => 'õ', // 245 in CP1252 + "\x1BNHo" => 'ö', // 246 in CP1252 + "\x1B/7" => '÷', // 247 in CP1252 + "\x1BNy" => 'ø', // 248 in CP1252 + "\x1BNAu" => 'ù', // 249 in CP1252 + "\x1BNBu" => 'ú', // 250 in CP1252 + "\x1BNCu" => 'û', // 251 in CP1252 + "\x1BNHu" => 'ü', // 252 in CP1252 + "\x1B/=" => 'ý', // 253 in CP1252 + "\x1BN|" => 'þ', // 254 in CP1252 + "\x1BNHy" => 'ÿ', // 255 in CP1252 + ); + } + + /** + * Get whether mbstring extension is available + * + * @return boolean + */ + public static function getIsMbstringEnabled() + { + if (isset(self::$_isMbstringEnabled)) { + return self::$_isMbstringEnabled; + } + + self::$_isMbstringEnabled = function_exists('mb_convert_encoding') ? + true : false; + + return self::$_isMbstringEnabled; + } + + /** + * Get whether iconv extension is available + * + * @return boolean + */ + public static function getIsIconvEnabled() + { + if (isset(self::$_isIconvEnabled)) { + return self::$_isIconvEnabled; + } + + // Fail if iconv doesn't exist + if (!function_exists('iconv')) { + self::$_isIconvEnabled = false; + return false; + } + + // Sometimes iconv is not working, and e.g. iconv('UTF-8', 'UTF-16LE', 'x') just returns false, + if (!@iconv('UTF-8', 'UTF-16LE', 'x')) { + self::$_isIconvEnabled = false; + return false; + } + + // Sometimes iconv_substr('A', 0, 1, 'UTF-8') just returns false in PHP 5.2.0 + // we cannot use iconv in that case either (http://bugs.php.net/bug.php?id=37773) + if (!@iconv_substr('A', 0, 1, 'UTF-8')) { + self::$_isIconvEnabled = false; + return false; + } + + // CUSTOM: IBM AIX iconv() does not work + if ( defined('PHP_OS') && @stristr(PHP_OS, 'AIX') + && defined('ICONV_IMPL') && (@strcasecmp(ICONV_IMPL, 'unknown') == 0) + && defined('ICONV_VERSION') && (@strcasecmp(ICONV_VERSION, 'unknown') == 0) ) + { + self::$_isIconvEnabled = false; + return false; + } + + // If we reach here no problems were detected with iconv + self::$_isIconvEnabled = true; + return true; + } + + public static function buildCharacterSets() { + if(empty(self::$_controlCharacters)) { + self::_buildControlCharacters(); + } + if(empty(self::$_SYLKCharacters)) { + self::_buildSYLKCharacters(); + } + } + + /** + * Convert from OpenXML escaped control character to PHP control character + * + * Excel 2007 team: + * ---------------- + * That's correct, control characters are stored directly in the shared-strings table. + * We do encode characters that cannot be represented in XML using the following escape sequence: + * _xHHHH_ where H represents a hexadecimal character in the character's value... + * So you could end up with something like _x0008_ in a string (either in a cell value (<v>) + * element or in the shared string <t> element. + * + * @param string $value Value to unescape + * @return string + */ + public static function ControlCharacterOOXML2PHP($value = '') { + return str_replace( array_keys(self::$_controlCharacters), array_values(self::$_controlCharacters), $value ); + } + + /** + * Convert from PHP control character to OpenXML escaped control character + * + * Excel 2007 team: + * ---------------- + * That's correct, control characters are stored directly in the shared-strings table. + * We do encode characters that cannot be represented in XML using the following escape sequence: + * _xHHHH_ where H represents a hexadecimal character in the character's value... + * So you could end up with something like _x0008_ in a string (either in a cell value (<v>) + * element or in the shared string <t> element. + * + * @param string $value Value to escape + * @return string + */ + public static function ControlCharacterPHP2OOXML($value = '') { + return str_replace( array_values(self::$_controlCharacters), array_keys(self::$_controlCharacters), $value ); + } + + /** + * Try to sanitize UTF8, stripping invalid byte sequences. Not perfect. Does not surrogate characters. + * + * @param string $value + * @return string + */ + public static function SanitizeUTF8($value) + { + if (self::getIsIconvEnabled()) { + $value = @iconv('UTF-8', 'UTF-8', $value); + return $value; + } + + if (self::getIsMbstringEnabled()) { + $value = mb_convert_encoding($value, 'UTF-8', 'UTF-8'); + return $value; + } + + // else, no conversion + return $value; + } + + /** + * Check if a string contains UTF8 data + * + * @param string $value + * @return boolean + */ + public static function IsUTF8($value = '') { + return $string === '' || preg_match('/^./su', $string) === 1; + } + + /** + * Formats a numeric value as a string for output in various output writers forcing + * point as decimal separator in case locale is other than English. + * + * @param mixed $value + * @return string + */ + public static function FormatNumber($value) { + if (is_float($value)) { + return str_replace(',', '.', $value); + } + return (string) $value; + } + + /** + * Converts a UTF-8 string into BIFF8 Unicode string data (8-bit string length) + * Writes the string using uncompressed notation, no rich text, no Asian phonetics + * If mbstring extension is not available, ASCII is assumed, and compressed notation is used + * although this will give wrong results for non-ASCII strings + * see OpenOffice.org's Documentation of the Microsoft Excel File Format, sect. 2.5.3 + * + * @param string $value UTF-8 encoded string + * @param mixed[] $arrcRuns Details of rich text runs in $value + * @return string + */ + public static function UTF8toBIFF8UnicodeShort($value, $arrcRuns = array()) + { + // character count + $ln = self::CountCharacters($value, 'UTF-8'); + // option flags + if(empty($arrcRuns)){ + $opt = (self::getIsIconvEnabled() || self::getIsMbstringEnabled()) ? + 0x0001 : 0x0000; + $data = pack('CC', $ln, $opt); + // characters + $data .= self::ConvertEncoding($value, 'UTF-16LE', 'UTF-8'); + } + else { + $data = pack('vC', $ln, 0x09); + $data .= pack('v', count($arrcRuns)); + // characters + $data .= self::ConvertEncoding($value, 'UTF-16LE', 'UTF-8'); + foreach ($arrcRuns as $cRun){ + $data .= pack('v', $cRun['strlen']); + $data .= pack('v', $cRun['fontidx']); + } + } + return $data; + } + + /** + * Converts a UTF-8 string into BIFF8 Unicode string data (16-bit string length) + * Writes the string using uncompressed notation, no rich text, no Asian phonetics + * If mbstring extension is not available, ASCII is assumed, and compressed notation is used + * although this will give wrong results for non-ASCII strings + * see OpenOffice.org's Documentation of the Microsoft Excel File Format, sect. 2.5.3 + * + * @param string $value UTF-8 encoded string + * @return string + */ + public static function UTF8toBIFF8UnicodeLong($value) + { + // character count + $ln = self::CountCharacters($value, 'UTF-8'); + + // option flags + $opt = (self::getIsIconvEnabled() || self::getIsMbstringEnabled()) ? + 0x0001 : 0x0000; + + // characters + $chars = self::ConvertEncoding($value, 'UTF-16LE', 'UTF-8'); + + $data = pack('vC', $ln, $opt) . $chars; + return $data; + } + + /** + * Convert string from one encoding to another. First try mbstring, then iconv, finally strlen + * + * @param string $value + * @param string $to Encoding to convert to, e.g. 'UTF-8' + * @param string $from Encoding to convert from, e.g. 'UTF-16LE' + * @return string + */ + public static function ConvertEncoding($value, $to, $from) + { + if (self::getIsIconvEnabled()) { + return iconv($from, $to, $value); + } + + if (self::getIsMbstringEnabled()) { + return mb_convert_encoding($value, $to, $from); + } + + if($from == 'UTF-16LE'){ + return self::utf16_decode($value, false); + }else if($from == 'UTF-16BE'){ + return self::utf16_decode($value); + } + // else, no conversion + return $value; + } + + /** + * Decode UTF-16 encoded strings. + * + * Can handle both BOM'ed data and un-BOM'ed data. + * Assumes Big-Endian byte order if no BOM is available. + * This function was taken from http://php.net/manual/en/function.utf8-decode.php + * and $bom_be parameter added. + * + * @param string $str UTF-16 encoded data to decode. + * @return string UTF-8 / ISO encoded data. + * @access public + * @version 0.2 / 2010-05-13 + * @author Rasmus Andersson {@link http://rasmusandersson.se/} + * @author vadik56 + */ + public static function utf16_decode($str, $bom_be = TRUE) { + if( strlen($str) < 2 ) return $str; + $c0 = ord($str{0}); + $c1 = ord($str{1}); + if( $c0 == 0xfe && $c1 == 0xff ) { $str = substr($str,2); } + elseif( $c0 == 0xff && $c1 == 0xfe ) { $str = substr($str,2); $bom_be = false; } + $len = strlen($str); + $newstr = ''; + for($i=0;$i<$len;$i+=2) { + if( $bom_be ) { $val = ord($str{$i}) << 4; $val += ord($str{$i+1}); } + else { $val = ord($str{$i+1}) << 4; $val += ord($str{$i}); } + $newstr .= ($val == 0x228) ? "\n" : chr($val); + } + return $newstr; + } + + /** + * Get character count. First try mbstring, then iconv, finally strlen + * + * @param string $value + * @param string $enc Encoding + * @return int Character count + */ + public static function CountCharacters($value, $enc = 'UTF-8') + { + if (self::getIsMbstringEnabled()) { + return mb_strlen($value, $enc); + } + + if (self::getIsIconvEnabled()) { + return iconv_strlen($value, $enc); + } + + // else strlen + return strlen($value); + } + + /** + * Get a substring of a UTF-8 encoded string. First try mbstring, then iconv, finally strlen + * + * @param string $pValue UTF-8 encoded string + * @param int $pStart Start offset + * @param int $pLength Maximum number of characters in substring + * @return string + */ + public static function Substring($pValue = '', $pStart = 0, $pLength = 0) + { + if (self::getIsMbstringEnabled()) { + return mb_substr($pValue, $pStart, $pLength, 'UTF-8'); + } + + if (self::getIsIconvEnabled()) { + return iconv_substr($pValue, $pStart, $pLength, 'UTF-8'); + } + + // else substr + return substr($pValue, $pStart, $pLength); + } + + /** + * Convert a UTF-8 encoded string to upper case + * + * @param string $pValue UTF-8 encoded string + * @return string + */ + public static function StrToUpper($pValue = '') + { + if (function_exists('mb_convert_case')) { + return mb_convert_case($pValue, MB_CASE_UPPER, "UTF-8"); + } + return strtoupper($pValue); + } + + /** + * Convert a UTF-8 encoded string to lower case + * + * @param string $pValue UTF-8 encoded string + * @return string + */ + public static function StrToLower($pValue = '') + { + if (function_exists('mb_convert_case')) { + return mb_convert_case($pValue, MB_CASE_LOWER, "UTF-8"); + } + return strtolower($pValue); + } + + /** + * Convert a UTF-8 encoded string to title/proper case + * (uppercase every first character in each word, lower case all other characters) + * + * @param string $pValue UTF-8 encoded string + * @return string + */ + public static function StrToTitle($pValue = '') + { + if (function_exists('mb_convert_case')) { + return mb_convert_case($pValue, MB_CASE_TITLE, "UTF-8"); + } + return ucwords($pValue); + } + + /** + * Identify whether a string contains a fractional numeric value, + * and convert it to a numeric if it is + * + * @param string &$operand string value to test + * @return boolean + */ + public static function convertToNumberIfFraction(&$operand) { + if (preg_match('/^'.self::STRING_REGEXP_FRACTION.'$/i', $operand, $match)) { + $sign = ($match[1] == '-') ? '-' : '+'; + $fractionFormula = '='.$sign.$match[2].$sign.$match[3]; + $operand = PHPExcel_Calculation::getInstance()->_calculateFormulaValue($fractionFormula); + return true; + } + return false; + } // function convertToNumberIfFraction() + + /** + * Get the decimal separator. If it has not yet been set explicitly, try to obtain number + * formatting information from locale. + * + * @return string + */ + public static function getDecimalSeparator() + { + if (!isset(self::$_decimalSeparator)) { + $localeconv = localeconv(); + self::$_decimalSeparator = ($localeconv['decimal_point'] != '') + ? $localeconv['decimal_point'] : $localeconv['mon_decimal_point']; + + if (self::$_decimalSeparator == '') { + // Default to . + self::$_decimalSeparator = '.'; + } + } + return self::$_decimalSeparator; + } + + /** + * Set the decimal separator. Only used by PHPExcel_Style_NumberFormat::toFormattedString() + * to format output by PHPExcel_Writer_HTML and PHPExcel_Writer_PDF + * + * @param string $pValue Character for decimal separator + */ + public static function setDecimalSeparator($pValue = '.') + { + self::$_decimalSeparator = $pValue; + } + + /** + * Get the thousands separator. If it has not yet been set explicitly, try to obtain number + * formatting information from locale. + * + * @return string + */ + public static function getThousandsSeparator() + { + if (!isset(self::$_thousandsSeparator)) { + $localeconv = localeconv(); + self::$_thousandsSeparator = ($localeconv['thousands_sep'] != '') + ? $localeconv['thousands_sep'] : $localeconv['mon_thousands_sep']; + + if (self::$_thousandsSeparator == '') { + // Default to . + self::$_thousandsSeparator = ','; + } + } + return self::$_thousandsSeparator; + } + + /** + * Set the thousands separator. Only used by PHPExcel_Style_NumberFormat::toFormattedString() + * to format output by PHPExcel_Writer_HTML and PHPExcel_Writer_PDF + * + * @param string $pValue Character for thousands separator + */ + public static function setThousandsSeparator($pValue = ',') + { + self::$_thousandsSeparator = $pValue; + } + + /** + * Get the currency code. If it has not yet been set explicitly, try to obtain the + * symbol information from locale. + * + * @return string + */ + public static function getCurrencyCode() + { + if (!isset(self::$_currencyCode)) { + $localeconv = localeconv(); + self::$_currencyCode = ($localeconv['currency_symbol'] != '') + ? $localeconv['currency_symbol'] : $localeconv['int_curr_symbol']; + + if (self::$_currencyCode == '') { + // Default to $ + self::$_currencyCode = '$'; + } + } + return self::$_currencyCode; + } + + /** + * Set the currency code. Only used by PHPExcel_Style_NumberFormat::toFormattedString() + * to format output by PHPExcel_Writer_HTML and PHPExcel_Writer_PDF + * + * @param string $pValue Character for currency code + */ + public static function setCurrencyCode($pValue = '$') + { + self::$_currencyCode = $pValue; + } + + /** + * Convert SYLK encoded string to UTF-8 + * + * @param string $pValue + * @return string UTF-8 encoded string + */ + public static function SYLKtoUTF8($pValue = '') + { + // If there is no escape character in the string there is nothing to do + if (strpos($pValue, '') === false) { + return $pValue; + } + + foreach (self::$_SYLKCharacters as $k => $v) { + $pValue = str_replace($k, $v, $pValue); + } + + return $pValue; + } + + /** + * Retrieve any leading numeric part of a string, or return the full string if no leading numeric + * (handles basic integer or float, but not exponent or non decimal) + * + * @param string $value + * @return mixed string or only the leading numeric part of the string + */ + public static function testStringAsNumeric($value) + { + if (is_numeric($value)) + return $value; + $v = floatval($value); + return (is_numeric(substr($value,0,strlen($v)))) ? $v : $value; + } +} diff --git a/lib/phpexcel/PHPExcel/Shared/TimeZone.php b/lib/phpexcel/PHPExcel/Shared/TimeZone.php new file mode 100644 index 0000000..d5fa2ad --- /dev/null +++ b/lib/phpexcel/PHPExcel/Shared/TimeZone.php @@ -0,0 +1,140 @@ +<?php + +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Shared_TimeZone + * + * @category PHPExcel + * @package PHPExcel_Shared + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Shared_TimeZone +{ + /* + * Default Timezone used for date/time conversions + * + * @private + * @var string + */ + protected static $_timezone = 'UTC'; + + /** + * Validate a Timezone name + * + * @param string $timezone Time zone (e.g. 'Europe/London') + * @return boolean Success or failure + */ + public static function _validateTimeZone($timezone) { + if (in_array($timezone, DateTimeZone::listIdentifiers())) { + return TRUE; + } + return FALSE; + } + + /** + * Set the Default Timezone used for date/time conversions + * + * @param string $timezone Time zone (e.g. 'Europe/London') + * @return boolean Success or failure + */ + public static function setTimeZone($timezone) { + if (self::_validateTimezone($timezone)) { + self::$_timezone = $timezone; + return TRUE; + } + return FALSE; + } // function setTimezone() + + + /** + * Return the Default Timezone used for date/time conversions + * + * @return string Timezone (e.g. 'Europe/London') + */ + public static function getTimeZone() { + return self::$_timezone; + } // function getTimezone() + + + /** + * Return the Timezone transition for the specified timezone and timestamp + * + * @param DateTimeZone $objTimezone The timezone for finding the transitions + * @param integer $timestamp PHP date/time value for finding the current transition + * @return array The current transition details + */ + private static function _getTimezoneTransitions($objTimezone, $timestamp) { + $allTransitions = $objTimezone->getTransitions(); + $transitions = array(); + foreach($allTransitions as $key => $transition) { + if ($transition['ts'] > $timestamp) { + $transitions[] = ($key > 0) ? $allTransitions[$key - 1] : $transition; + break; + } + if (empty($transitions)) { + $transitions[] = end($allTransitions); + } + } + + return $transitions; + } + + /** + * Return the Timezone offset used for date/time conversions to/from UST + * This requires both the timezone and the calculated date/time to allow for local DST + * + * @param string $timezone The timezone for finding the adjustment to UST + * @param integer $timestamp PHP date/time value + * @return integer Number of seconds for timezone adjustment + * @throws PHPExcel_Exception + */ + public static function getTimeZoneAdjustment($timezone, $timestamp) { + if ($timezone !== NULL) { + if (!self::_validateTimezone($timezone)) { + throw new PHPExcel_Exception("Invalid timezone " . $timezone); + } + } else { + $timezone = self::$_timezone; + } + + if ($timezone == 'UST') { + return 0; + } + + $objTimezone = new DateTimeZone($timezone); + if (version_compare(PHP_VERSION, '5.3.0') >= 0) { + $transitions = $objTimezone->getTransitions($timestamp,$timestamp); + } else { + $transitions = self::_getTimezoneTransitions($objTimezone, $timestamp); + } + + return (count($transitions) > 0) ? $transitions[0]['offset'] : 0; + } + +} diff --git a/lib/phpexcel/PHPExcel/Shared/XMLWriter.php b/lib/phpexcel/PHPExcel/Shared/XMLWriter.php new file mode 100644 index 0000000..0b0b553 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Shared/XMLWriter.php @@ -0,0 +1,127 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + +if (!defined('DATE_W3C')) { + define('DATE_W3C', 'Y-m-d\TH:i:sP'); +} + +if (!defined('DEBUGMODE_ENABLED')) { + define('DEBUGMODE_ENABLED', false); +} + + +/** + * PHPExcel_Shared_XMLWriter + * + * @category PHPExcel + * @package PHPExcel_Shared + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Shared_XMLWriter extends XMLWriter { + /** Temporary storage method */ + const STORAGE_MEMORY = 1; + const STORAGE_DISK = 2; + + /** + * Temporary filename + * + * @var string + */ + private $_tempFileName = ''; + + /** + * Create a new PHPExcel_Shared_XMLWriter instance + * + * @param int $pTemporaryStorage Temporary storage location + * @param string $pTemporaryStorageFolder Temporary storage folder + */ + public function __construct($pTemporaryStorage = self::STORAGE_MEMORY, $pTemporaryStorageFolder = NULL) { + // Open temporary storage + if ($pTemporaryStorage == self::STORAGE_MEMORY) { + $this->openMemory(); + } else { + // Create temporary filename + if ($pTemporaryStorageFolder === NULL) + $pTemporaryStorageFolder = PHPExcel_Shared_File::sys_get_temp_dir(); + $this->_tempFileName = @tempnam($pTemporaryStorageFolder, 'xml'); + + // Open storage + if ($this->openUri($this->_tempFileName) === false) { + // Fallback to memory... + $this->openMemory(); + } + } + + // Set default values + if (DEBUGMODE_ENABLED) { + $this->setIndent(true); + } + } + + /** + * Destructor + */ + public function __destruct() { + // Unlink temporary files + if ($this->_tempFileName != '') { + @unlink($this->_tempFileName); + } + } + + /** + * Get written data + * + * @return $data + */ + public function getData() { + if ($this->_tempFileName == '') { + return $this->outputMemory(true); + } else { + $this->flush(); + return file_get_contents($this->_tempFileName); + } + } + + /** + * Fallback method for writeRaw, introduced in PHP 5.2 + * + * @param string $text + * @return string + */ + public function writeRawData($text) + { + if (is_array($text)) { + $text = implode("\n",$text); + } + + if (method_exists($this, 'writeRaw')) { + return $this->writeRaw(htmlspecialchars($text)); + } + + return $this->text($text); + } +} diff --git a/lib/phpexcel/PHPExcel/Shared/ZipArchive.php b/lib/phpexcel/PHPExcel/Shared/ZipArchive.php new file mode 100644 index 0000000..ab551af --- /dev/null +++ b/lib/phpexcel/PHPExcel/Shared/ZipArchive.php @@ -0,0 +1,175 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared_ZipArchive + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + +if (!defined('PCLZIP_TEMPORARY_DIR')) { + define('PCLZIP_TEMPORARY_DIR', PHPExcel_Shared_File::sys_get_temp_dir()); +} +require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/PCLZip/pclzip.lib.php'; + + +/** + * PHPExcel_Shared_ZipArchive + * + * @category PHPExcel + * @package PHPExcel_Shared_ZipArchive + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Shared_ZipArchive +{ + + /** constants */ + const OVERWRITE = 'OVERWRITE'; + const CREATE = 'CREATE'; + + + /** + * Temporary storage directory + * + * @var string + */ + private $_tempDir; + + /** + * Zip Archive Stream Handle + * + * @var string + */ + private $_zip; + + + /** + * Open a new zip archive + * + * @param string $fileName Filename for the zip archive + * @return boolean + */ + public function open($fileName) + { + $this->_tempDir = PHPExcel_Shared_File::sys_get_temp_dir(); + + $this->_zip = new PclZip($fileName); + + return true; + } + + + /** + * Close this zip archive + * + */ + public function close() + { + } + + + /** + * Add a new file to the zip archive from a string of raw data. + * + * @param string $localname Directory/Name of the file to add to the zip archive + * @param string $contents String of data to add to the zip archive + */ + public function addFromString($localname, $contents) + { + $filenameParts = pathinfo($localname); + + $handle = fopen($this->_tempDir.'/'.$filenameParts["basename"], "wb"); + fwrite($handle, $contents); + fclose($handle); + + $res = $this->_zip->add($this->_tempDir.'/'.$filenameParts["basename"], + PCLZIP_OPT_REMOVE_PATH, $this->_tempDir, + PCLZIP_OPT_ADD_PATH, $filenameParts["dirname"] + ); + if ($res == 0) { + throw new PHPExcel_Writer_Exception("Error zipping files : " . $this->_zip->errorInfo(true)); + } + + unlink($this->_tempDir.'/'.$filenameParts["basename"]); + } + + /** + * Find if given fileName exist in archive (Emulate ZipArchive locateName()) + * + * @param string $fileName Filename for the file in zip archive + * @return boolean + */ + public function locateName($fileName) + { + $list = $this->_zip->listContent(); + $listCount = count($list); + $list_index = -1; + for ($i = 0; $i < $listCount; ++$i) { + if (strtolower($list[$i]["filename"]) == strtolower($fileName) || + strtolower($list[$i]["stored_filename"]) == strtolower($fileName)) { + $list_index = $i; + break; + } + } + return ($list_index > -1); + } + + /** + * Extract file from archive by given fileName (Emulate ZipArchive getFromName()) + * + * @param string $fileName Filename for the file in zip archive + * @return string $contents File string contents + */ + public function getFromName($fileName) + { + $list = $this->_zip->listContent(); + $listCount = count($list); + $list_index = -1; + for ($i = 0; $i < $listCount; ++$i) { + if (strtolower($list[$i]["filename"]) == strtolower($fileName) || + strtolower($list[$i]["stored_filename"]) == strtolower($fileName)) { + $list_index = $i; + break; + } + } + + $extracted = ""; + if ($list_index != -1) { + $extracted = $this->_zip->extractByIndex($list_index, PCLZIP_OPT_EXTRACT_AS_STRING); + } else { + $filename = substr($fileName, 1); + $list_index = -1; + for ($i = 0; $i < $listCount; ++$i) { + if (strtolower($list[$i]["filename"]) == strtolower($fileName) || + strtolower($list[$i]["stored_filename"]) == strtolower($fileName)) { + $list_index = $i; + break; + } + } + $extracted = $this->_zip->extractByIndex($list_index, PCLZIP_OPT_EXTRACT_AS_STRING); + } + if ((is_array($extracted)) && ($extracted != 0)) { + $contents = $extracted[0]["content"]; + } + + return $contents; + } +} diff --git a/lib/phpexcel/PHPExcel/Shared/ZipStreamWrapper.php b/lib/phpexcel/PHPExcel/Shared/ZipStreamWrapper.php new file mode 100644 index 0000000..696072b --- /dev/null +++ b/lib/phpexcel/PHPExcel/Shared/ZipStreamWrapper.php @@ -0,0 +1,201 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Shared_ZipStreamWrapper + * + * @category PHPExcel + * @package PHPExcel_Shared + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Shared_ZipStreamWrapper { + /** + * Internal ZipAcrhive + * + * @var ZipAcrhive + */ + private $_archive; + + /** + * Filename in ZipAcrhive + * + * @var string + */ + private $_fileNameInArchive = ''; + + /** + * Position in file + * + * @var int + */ + private $_position = 0; + + /** + * Data + * + * @var mixed + */ + private $_data = ''; + + /** + * Register wrapper + */ + public static function register() { + @stream_wrapper_unregister("zip"); + @stream_wrapper_register("zip", __CLASS__); + } + + /** + * Implements support for fopen(). + * + * @param string $path resource name including scheme, e.g. + * @param string $mode only "r" is supported + * @param int $options mask of STREAM_REPORT_ERRORS and STREAM_USE_PATH + * @param string &$openedPath absolute path of the opened stream (out parameter) + * @return bool true on success + */ + public function stream_open($path, $mode, $options, &$opened_path) { + // Check for mode + if ($mode{0} != 'r') { + throw new PHPExcel_Reader_Exception('Mode ' . $mode . ' is not supported. Only read mode is supported.'); + } + + $pos = strrpos($path, '#'); + $url['host'] = substr($path, 6, $pos - 6); // 6: strlen('zip://') + $url['fragment'] = substr($path, $pos + 1); + + // Open archive + $this->_archive = new ZipArchive(); + $this->_archive->open($url['host']); + + $this->_fileNameInArchive = $url['fragment']; + $this->_position = 0; + $this->_data = $this->_archive->getFromName( $this->_fileNameInArchive ); + + return true; + } + + /** + * Implements support for fstat(). + * + * @return boolean + */ + public function statName() { + return $this->_fileNameInArchive; + } + + /** + * Implements support for fstat(). + * + * @return boolean + */ + public function url_stat() { + return $this->statName( $this->_fileNameInArchive ); + } + + /** + * Implements support for fstat(). + * + * @return boolean + */ + public function stream_stat() { + return $this->_archive->statName( $this->_fileNameInArchive ); + } + + /** + * Implements support for fread(), fgets() etc. + * + * @param int $count maximum number of bytes to read + * @return string + */ + function stream_read($count) { + $ret = substr($this->_data, $this->_position, $count); + $this->_position += strlen($ret); + return $ret; + } + + /** + * Returns the position of the file pointer, i.e. its offset into the file + * stream. Implements support for ftell(). + * + * @return int + */ + public function stream_tell() { + return $this->_position; + } + + /** + * EOF stream + * + * @return bool + */ + public function stream_eof() { + return $this->_position >= strlen($this->_data); + } + + /** + * Seek stream + * + * @param int $offset byte offset + * @param int $whence SEEK_SET, SEEK_CUR or SEEK_END + * @return bool + */ + public function stream_seek($offset, $whence) { + switch ($whence) { + case SEEK_SET: + if ($offset < strlen($this->_data) && $offset >= 0) { + $this->_position = $offset; + return true; + } else { + return false; + } + break; + + case SEEK_CUR: + if ($offset >= 0) { + $this->_position += $offset; + return true; + } else { + return false; + } + break; + + case SEEK_END: + if (strlen($this->_data) + $offset >= 0) { + $this->_position = strlen($this->_data) + $offset; + return true; + } else { + return false; + } + break; + + default: + return false; + } + } +} diff --git a/lib/phpexcel/PHPExcel/Shared/trend/bestFitClass.php b/lib/phpexcel/PHPExcel/Shared/trend/bestFitClass.php new file mode 100644 index 0000000..088ce06 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Shared/trend/bestFitClass.php @@ -0,0 +1,432 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared_Trend + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Best_Fit + * + * @category PHPExcel + * @package PHPExcel_Shared_Trend + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Best_Fit +{ + /** + * Indicator flag for a calculation error + * + * @var boolean + **/ + protected $_error = False; + + /** + * Algorithm type to use for best-fit + * + * @var string + **/ + protected $_bestFitType = 'undetermined'; + + /** + * Number of entries in the sets of x- and y-value arrays + * + * @var int + **/ + protected $_valueCount = 0; + + /** + * X-value dataseries of values + * + * @var float[] + **/ + protected $_xValues = array(); + + /** + * Y-value dataseries of values + * + * @var float[] + **/ + protected $_yValues = array(); + + /** + * Flag indicating whether values should be adjusted to Y=0 + * + * @var boolean + **/ + protected $_adjustToZero = False; + + /** + * Y-value series of best-fit values + * + * @var float[] + **/ + protected $_yBestFitValues = array(); + + protected $_goodnessOfFit = 1; + + protected $_stdevOfResiduals = 0; + + protected $_covariance = 0; + + protected $_correlation = 0; + + protected $_SSRegression = 0; + + protected $_SSResiduals = 0; + + protected $_DFResiduals = 0; + + protected $_F = 0; + + protected $_slope = 0; + + protected $_slopeSE = 0; + + protected $_intersect = 0; + + protected $_intersectSE = 0; + + protected $_Xoffset = 0; + + protected $_Yoffset = 0; + + + public function getError() { + return $this->_error; + } // function getBestFitType() + + + public function getBestFitType() { + return $this->_bestFitType; + } // function getBestFitType() + + + /** + * Return the Y-Value for a specified value of X + * + * @param float $xValue X-Value + * @return float Y-Value + */ + public function getValueOfYForX($xValue) { + return False; + } // function getValueOfYForX() + + + /** + * Return the X-Value for a specified value of Y + * + * @param float $yValue Y-Value + * @return float X-Value + */ + public function getValueOfXForY($yValue) { + return False; + } // function getValueOfXForY() + + + /** + * Return the original set of X-Values + * + * @return float[] X-Values + */ + public function getXValues() { + return $this->_xValues; + } // function getValueOfXForY() + + + /** + * Return the Equation of the best-fit line + * + * @param int $dp Number of places of decimal precision to display + * @return string + */ + public function getEquation($dp=0) { + return False; + } // function getEquation() + + + /** + * Return the Slope of the line + * + * @param int $dp Number of places of decimal precision to display + * @return string + */ + public function getSlope($dp=0) { + if ($dp != 0) { + return round($this->_slope,$dp); + } + return $this->_slope; + } // function getSlope() + + + /** + * Return the standard error of the Slope + * + * @param int $dp Number of places of decimal precision to display + * @return string + */ + public function getSlopeSE($dp=0) { + if ($dp != 0) { + return round($this->_slopeSE,$dp); + } + return $this->_slopeSE; + } // function getSlopeSE() + + + /** + * Return the Value of X where it intersects Y = 0 + * + * @param int $dp Number of places of decimal precision to display + * @return string + */ + public function getIntersect($dp=0) { + if ($dp != 0) { + return round($this->_intersect,$dp); + } + return $this->_intersect; + } // function getIntersect() + + + /** + * Return the standard error of the Intersect + * + * @param int $dp Number of places of decimal precision to display + * @return string + */ + public function getIntersectSE($dp=0) { + if ($dp != 0) { + return round($this->_intersectSE,$dp); + } + return $this->_intersectSE; + } // function getIntersectSE() + + + /** + * Return the goodness of fit for this regression + * + * @param int $dp Number of places of decimal precision to return + * @return float + */ + public function getGoodnessOfFit($dp=0) { + if ($dp != 0) { + return round($this->_goodnessOfFit,$dp); + } + return $this->_goodnessOfFit; + } // function getGoodnessOfFit() + + + public function getGoodnessOfFitPercent($dp=0) { + if ($dp != 0) { + return round($this->_goodnessOfFit * 100,$dp); + } + return $this->_goodnessOfFit * 100; + } // function getGoodnessOfFitPercent() + + + /** + * Return the standard deviation of the residuals for this regression + * + * @param int $dp Number of places of decimal precision to return + * @return float + */ + public function getStdevOfResiduals($dp=0) { + if ($dp != 0) { + return round($this->_stdevOfResiduals,$dp); + } + return $this->_stdevOfResiduals; + } // function getStdevOfResiduals() + + + public function getSSRegression($dp=0) { + if ($dp != 0) { + return round($this->_SSRegression,$dp); + } + return $this->_SSRegression; + } // function getSSRegression() + + + public function getSSResiduals($dp=0) { + if ($dp != 0) { + return round($this->_SSResiduals,$dp); + } + return $this->_SSResiduals; + } // function getSSResiduals() + + + public function getDFResiduals($dp=0) { + if ($dp != 0) { + return round($this->_DFResiduals,$dp); + } + return $this->_DFResiduals; + } // function getDFResiduals() + + + public function getF($dp=0) { + if ($dp != 0) { + return round($this->_F,$dp); + } + return $this->_F; + } // function getF() + + + public function getCovariance($dp=0) { + if ($dp != 0) { + return round($this->_covariance,$dp); + } + return $this->_covariance; + } // function getCovariance() + + + public function getCorrelation($dp=0) { + if ($dp != 0) { + return round($this->_correlation,$dp); + } + return $this->_correlation; + } // function getCorrelation() + + + public function getYBestFitValues() { + return $this->_yBestFitValues; + } // function getYBestFitValues() + + + protected function _calculateGoodnessOfFit($sumX,$sumY,$sumX2,$sumY2,$sumXY,$meanX,$meanY, $const) { + $SSres = $SScov = $SScor = $SStot = $SSsex = 0.0; + foreach($this->_xValues as $xKey => $xValue) { + $bestFitY = $this->_yBestFitValues[$xKey] = $this->getValueOfYForX($xValue); + + $SSres += ($this->_yValues[$xKey] - $bestFitY) * ($this->_yValues[$xKey] - $bestFitY); + if ($const) { + $SStot += ($this->_yValues[$xKey] - $meanY) * ($this->_yValues[$xKey] - $meanY); + } else { + $SStot += $this->_yValues[$xKey] * $this->_yValues[$xKey]; + } + $SScov += ($this->_xValues[$xKey] - $meanX) * ($this->_yValues[$xKey] - $meanY); + if ($const) { + $SSsex += ($this->_xValues[$xKey] - $meanX) * ($this->_xValues[$xKey] - $meanX); + } else { + $SSsex += $this->_xValues[$xKey] * $this->_xValues[$xKey]; + } + } + + $this->_SSResiduals = $SSres; + $this->_DFResiduals = $this->_valueCount - 1 - $const; + + if ($this->_DFResiduals == 0.0) { + $this->_stdevOfResiduals = 0.0; + } else { + $this->_stdevOfResiduals = sqrt($SSres / $this->_DFResiduals); + } + if (($SStot == 0.0) || ($SSres == $SStot)) { + $this->_goodnessOfFit = 1; + } else { + $this->_goodnessOfFit = 1 - ($SSres / $SStot); + } + + $this->_SSRegression = $this->_goodnessOfFit * $SStot; + $this->_covariance = $SScov / $this->_valueCount; + $this->_correlation = ($this->_valueCount * $sumXY - $sumX * $sumY) / sqrt(($this->_valueCount * $sumX2 - pow($sumX,2)) * ($this->_valueCount * $sumY2 - pow($sumY,2))); + $this->_slopeSE = $this->_stdevOfResiduals / sqrt($SSsex); + $this->_intersectSE = $this->_stdevOfResiduals * sqrt(1 / ($this->_valueCount - ($sumX * $sumX) / $sumX2)); + if ($this->_SSResiduals != 0.0) { + if ($this->_DFResiduals == 0.0) { + $this->_F = 0.0; + } else { + $this->_F = $this->_SSRegression / ($this->_SSResiduals / $this->_DFResiduals); + } + } else { + if ($this->_DFResiduals == 0.0) { + $this->_F = 0.0; + } else { + $this->_F = $this->_SSRegression / $this->_DFResiduals; + } + } + } // function _calculateGoodnessOfFit() + + + protected function _leastSquareFit($yValues, $xValues, $const) { + // calculate sums + $x_sum = array_sum($xValues); + $y_sum = array_sum($yValues); + $meanX = $x_sum / $this->_valueCount; + $meanY = $y_sum / $this->_valueCount; + $mBase = $mDivisor = $xx_sum = $xy_sum = $yy_sum = 0.0; + for($i = 0; $i < $this->_valueCount; ++$i) { + $xy_sum += $xValues[$i] * $yValues[$i]; + $xx_sum += $xValues[$i] * $xValues[$i]; + $yy_sum += $yValues[$i] * $yValues[$i]; + + if ($const) { + $mBase += ($xValues[$i] - $meanX) * ($yValues[$i] - $meanY); + $mDivisor += ($xValues[$i] - $meanX) * ($xValues[$i] - $meanX); + } else { + $mBase += $xValues[$i] * $yValues[$i]; + $mDivisor += $xValues[$i] * $xValues[$i]; + } + } + + // calculate slope +// $this->_slope = (($this->_valueCount * $xy_sum) - ($x_sum * $y_sum)) / (($this->_valueCount * $xx_sum) - ($x_sum * $x_sum)); + $this->_slope = $mBase / $mDivisor; + + // calculate intersect +// $this->_intersect = ($y_sum - ($this->_slope * $x_sum)) / $this->_valueCount; + if ($const) { + $this->_intersect = $meanY - ($this->_slope * $meanX); + } else { + $this->_intersect = 0; + } + + $this->_calculateGoodnessOfFit($x_sum,$y_sum,$xx_sum,$yy_sum,$xy_sum,$meanX,$meanY,$const); + } // function _leastSquareFit() + + + /** + * Define the regression + * + * @param float[] $yValues The set of Y-values for this regression + * @param float[] $xValues The set of X-values for this regression + * @param boolean $const + */ + function __construct($yValues, $xValues=array(), $const=True) { + // Calculate number of points + $nY = count($yValues); + $nX = count($xValues); + + // Define X Values if necessary + if ($nX == 0) { + $xValues = range(1,$nY); + $nX = $nY; + } elseif ($nY != $nX) { + // Ensure both arrays of points are the same size + $this->_error = True; + return False; + } + + $this->_valueCount = $nY; + $this->_xValues = $xValues; + $this->_yValues = $yValues; + } // function __construct() + +} // class bestFit diff --git a/lib/phpexcel/PHPExcel/Shared/trend/exponentialBestFitClass.php b/lib/phpexcel/PHPExcel/Shared/trend/exponentialBestFitClass.php new file mode 100644 index 0000000..44c7aee --- /dev/null +++ b/lib/phpexcel/PHPExcel/Shared/trend/exponentialBestFitClass.php @@ -0,0 +1,148 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared_Trend + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +require_once(PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/bestFitClass.php'); + + +/** + * PHPExcel_Exponential_Best_Fit + * + * @category PHPExcel + * @package PHPExcel_Shared_Trend + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Exponential_Best_Fit extends PHPExcel_Best_Fit +{ + /** + * Algorithm type to use for best-fit + * (Name of this trend class) + * + * @var string + **/ + protected $_bestFitType = 'exponential'; + + + /** + * Return the Y-Value for a specified value of X + * + * @param float $xValue X-Value + * @return float Y-Value + **/ + public function getValueOfYForX($xValue) { + return $this->getIntersect() * pow($this->getSlope(),($xValue - $this->_Xoffset)); + } // function getValueOfYForX() + + + /** + * Return the X-Value for a specified value of Y + * + * @param float $yValue Y-Value + * @return float X-Value + **/ + public function getValueOfXForY($yValue) { + return log(($yValue + $this->_Yoffset) / $this->getIntersect()) / log($this->getSlope()); + } // function getValueOfXForY() + + + /** + * Return the Equation of the best-fit line + * + * @param int $dp Number of places of decimal precision to display + * @return string + **/ + public function getEquation($dp=0) { + $slope = $this->getSlope($dp); + $intersect = $this->getIntersect($dp); + + return 'Y = '.$intersect.' * '.$slope.'^X'; + } // function getEquation() + + + /** + * Return the Slope of the line + * + * @param int $dp Number of places of decimal precision to display + * @return string + **/ + public function getSlope($dp=0) { + if ($dp != 0) { + return round(exp($this->_slope),$dp); + } + return exp($this->_slope); + } // function getSlope() + + + /** + * Return the Value of X where it intersects Y = 0 + * + * @param int $dp Number of places of decimal precision to display + * @return string + **/ + public function getIntersect($dp=0) { + if ($dp != 0) { + return round(exp($this->_intersect),$dp); + } + return exp($this->_intersect); + } // function getIntersect() + + + /** + * Execute the regression and calculate the goodness of fit for a set of X and Y data values + * + * @param float[] $yValues The set of Y-values for this regression + * @param float[] $xValues The set of X-values for this regression + * @param boolean $const + */ + private function _exponential_regression($yValues, $xValues, $const) { + foreach($yValues as &$value) { + if ($value < 0.0) { + $value = 0 - log(abs($value)); + } elseif ($value > 0.0) { + $value = log($value); + } + } + unset($value); + + $this->_leastSquareFit($yValues, $xValues, $const); + } // function _exponential_regression() + + + /** + * Define the regression and calculate the goodness of fit for a set of X and Y data values + * + * @param float[] $yValues The set of Y-values for this regression + * @param float[] $xValues The set of X-values for this regression + * @param boolean $const + */ + function __construct($yValues, $xValues=array(), $const=True) { + if (parent::__construct($yValues, $xValues) !== False) { + $this->_exponential_regression($yValues, $xValues, $const); + } + } // function __construct() + +} // class exponentialBestFit \ No newline at end of file diff --git a/lib/phpexcel/PHPExcel/Shared/trend/linearBestFitClass.php b/lib/phpexcel/PHPExcel/Shared/trend/linearBestFitClass.php new file mode 100644 index 0000000..00da841 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Shared/trend/linearBestFitClass.php @@ -0,0 +1,111 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared_Trend + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +require_once(PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/bestFitClass.php'); + + +/** + * PHPExcel_Linear_Best_Fit + * + * @category PHPExcel + * @package PHPExcel_Shared_Trend + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Linear_Best_Fit extends PHPExcel_Best_Fit +{ + /** + * Algorithm type to use for best-fit + * (Name of this trend class) + * + * @var string + **/ + protected $_bestFitType = 'linear'; + + + /** + * Return the Y-Value for a specified value of X + * + * @param float $xValue X-Value + * @return float Y-Value + **/ + public function getValueOfYForX($xValue) { + return $this->getIntersect() + $this->getSlope() * $xValue; + } // function getValueOfYForX() + + + /** + * Return the X-Value for a specified value of Y + * + * @param float $yValue Y-Value + * @return float X-Value + **/ + public function getValueOfXForY($yValue) { + return ($yValue - $this->getIntersect()) / $this->getSlope(); + } // function getValueOfXForY() + + + /** + * Return the Equation of the best-fit line + * + * @param int $dp Number of places of decimal precision to display + * @return string + **/ + public function getEquation($dp=0) { + $slope = $this->getSlope($dp); + $intersect = $this->getIntersect($dp); + + return 'Y = '.$intersect.' + '.$slope.' * X'; + } // function getEquation() + + + /** + * Execute the regression and calculate the goodness of fit for a set of X and Y data values + * + * @param float[] $yValues The set of Y-values for this regression + * @param float[] $xValues The set of X-values for this regression + * @param boolean $const + */ + private function _linear_regression($yValues, $xValues, $const) { + $this->_leastSquareFit($yValues, $xValues,$const); + } // function _linear_regression() + + + /** + * Define the regression and calculate the goodness of fit for a set of X and Y data values + * + * @param float[] $yValues The set of Y-values for this regression + * @param float[] $xValues The set of X-values for this regression + * @param boolean $const + */ + function __construct($yValues, $xValues=array(), $const=True) { + if (parent::__construct($yValues, $xValues) !== False) { + $this->_linear_regression($yValues, $xValues, $const); + } + } // function __construct() + +} // class linearBestFit \ No newline at end of file diff --git a/lib/phpexcel/PHPExcel/Shared/trend/logarithmicBestFitClass.php b/lib/phpexcel/PHPExcel/Shared/trend/logarithmicBestFitClass.php new file mode 100644 index 0000000..ac9c1e2 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Shared/trend/logarithmicBestFitClass.php @@ -0,0 +1,120 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared_Trend + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +require_once(PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/bestFitClass.php'); + + +/** + * PHPExcel_Logarithmic_Best_Fit + * + * @category PHPExcel + * @package PHPExcel_Shared_Trend + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Logarithmic_Best_Fit extends PHPExcel_Best_Fit +{ + /** + * Algorithm type to use for best-fit + * (Name of this trend class) + * + * @var string + **/ + protected $_bestFitType = 'logarithmic'; + + + /** + * Return the Y-Value for a specified value of X + * + * @param float $xValue X-Value + * @return float Y-Value + **/ + public function getValueOfYForX($xValue) { + return $this->getIntersect() + $this->getSlope() * log($xValue - $this->_Xoffset); + } // function getValueOfYForX() + + + /** + * Return the X-Value for a specified value of Y + * + * @param float $yValue Y-Value + * @return float X-Value + **/ + public function getValueOfXForY($yValue) { + return exp(($yValue - $this->getIntersect()) / $this->getSlope()); + } // function getValueOfXForY() + + + /** + * Return the Equation of the best-fit line + * + * @param int $dp Number of places of decimal precision to display + * @return string + **/ + public function getEquation($dp=0) { + $slope = $this->getSlope($dp); + $intersect = $this->getIntersect($dp); + + return 'Y = '.$intersect.' + '.$slope.' * log(X)'; + } // function getEquation() + + + /** + * Execute the regression and calculate the goodness of fit for a set of X and Y data values + * + * @param float[] $yValues The set of Y-values for this regression + * @param float[] $xValues The set of X-values for this regression + * @param boolean $const + */ + private function _logarithmic_regression($yValues, $xValues, $const) { + foreach($xValues as &$value) { + if ($value < 0.0) { + $value = 0 - log(abs($value)); + } elseif ($value > 0.0) { + $value = log($value); + } + } + unset($value); + + $this->_leastSquareFit($yValues, $xValues, $const); + } // function _logarithmic_regression() + + + /** + * Define the regression and calculate the goodness of fit for a set of X and Y data values + * + * @param float[] $yValues The set of Y-values for this regression + * @param float[] $xValues The set of X-values for this regression + * @param boolean $const + */ + function __construct($yValues, $xValues=array(), $const=True) { + if (parent::__construct($yValues, $xValues) !== False) { + $this->_logarithmic_regression($yValues, $xValues, $const); + } + } // function __construct() + +} // class logarithmicBestFit \ No newline at end of file diff --git a/lib/phpexcel/PHPExcel/Shared/trend/polynomialBestFitClass.php b/lib/phpexcel/PHPExcel/Shared/trend/polynomialBestFitClass.php new file mode 100644 index 0000000..a507975 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Shared/trend/polynomialBestFitClass.php @@ -0,0 +1,224 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared_Trend + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/bestFitClass.php'; +require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/JAMA/Matrix.php'; + + +/** + * PHPExcel_Polynomial_Best_Fit + * + * @category PHPExcel + * @package PHPExcel_Shared_Trend + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Polynomial_Best_Fit extends PHPExcel_Best_Fit +{ + /** + * Algorithm type to use for best-fit + * (Name of this trend class) + * + * @var string + **/ + protected $_bestFitType = 'polynomial'; + + /** + * Polynomial order + * + * @protected + * @var int + **/ + protected $_order = 0; + + + /** + * Return the order of this polynomial + * + * @return int + **/ + public function getOrder() { + return $this->_order; + } // function getOrder() + + + /** + * Return the Y-Value for a specified value of X + * + * @param float $xValue X-Value + * @return float Y-Value + **/ + public function getValueOfYForX($xValue) { + $retVal = $this->getIntersect(); + $slope = $this->getSlope(); + foreach($slope as $key => $value) { + if ($value != 0.0) { + $retVal += $value * pow($xValue, $key + 1); + } + } + return $retVal; + } // function getValueOfYForX() + + + /** + * Return the X-Value for a specified value of Y + * + * @param float $yValue Y-Value + * @return float X-Value + **/ + public function getValueOfXForY($yValue) { + return ($yValue - $this->getIntersect()) / $this->getSlope(); + } // function getValueOfXForY() + + + /** + * Return the Equation of the best-fit line + * + * @param int $dp Number of places of decimal precision to display + * @return string + **/ + public function getEquation($dp=0) { + $slope = $this->getSlope($dp); + $intersect = $this->getIntersect($dp); + + $equation = 'Y = '.$intersect; + foreach($slope as $key => $value) { + if ($value != 0.0) { + $equation .= ' + '.$value.' * X'; + if ($key > 0) { + $equation .= '^'.($key + 1); + } + } + } + return $equation; + } // function getEquation() + + + /** + * Return the Slope of the line + * + * @param int $dp Number of places of decimal precision to display + * @return string + **/ + public function getSlope($dp=0) { + if ($dp != 0) { + $coefficients = array(); + foreach($this->_slope as $coefficient) { + $coefficients[] = round($coefficient,$dp); + } + return $coefficients; + } + return $this->_slope; + } // function getSlope() + + + public function getCoefficients($dp=0) { + return array_merge(array($this->getIntersect($dp)),$this->getSlope($dp)); + } // function getCoefficients() + + + /** + * Execute the regression and calculate the goodness of fit for a set of X and Y data values + * + * @param int $order Order of Polynomial for this regression + * @param float[] $yValues The set of Y-values for this regression + * @param float[] $xValues The set of X-values for this regression + * @param boolean $const + */ + private function _polynomial_regression($order, $yValues, $xValues, $const) { + // calculate sums + $x_sum = array_sum($xValues); + $y_sum = array_sum($yValues); + $xx_sum = $xy_sum = 0; + for($i = 0; $i < $this->_valueCount; ++$i) { + $xy_sum += $xValues[$i] * $yValues[$i]; + $xx_sum += $xValues[$i] * $xValues[$i]; + $yy_sum += $yValues[$i] * $yValues[$i]; + } + /* + * This routine uses logic from the PHP port of polyfit version 0.1 + * written by Michael Bommarito and Paul Meagher + * + * The function fits a polynomial function of order $order through + * a series of x-y data points using least squares. + * + */ + for ($i = 0; $i < $this->_valueCount; ++$i) { + for ($j = 0; $j <= $order; ++$j) { + $A[$i][$j] = pow($xValues[$i], $j); + } + } + for ($i=0; $i < $this->_valueCount; ++$i) { + $B[$i] = array($yValues[$i]); + } + $matrixA = new Matrix($A); + $matrixB = new Matrix($B); + $C = $matrixA->solve($matrixB); + + $coefficients = array(); + for($i = 0; $i < $C->m; ++$i) { + $r = $C->get($i, 0); + if (abs($r) <= pow(10, -9)) { + $r = 0; + } + $coefficients[] = $r; + } + + $this->_intersect = array_shift($coefficients); + $this->_slope = $coefficients; + + $this->_calculateGoodnessOfFit($x_sum,$y_sum,$xx_sum,$yy_sum,$xy_sum); + foreach($this->_xValues as $xKey => $xValue) { + $this->_yBestFitValues[$xKey] = $this->getValueOfYForX($xValue); + } + } // function _polynomial_regression() + + + /** + * Define the regression and calculate the goodness of fit for a set of X and Y data values + * + * @param int $order Order of Polynomial for this regression + * @param float[] $yValues The set of Y-values for this regression + * @param float[] $xValues The set of X-values for this regression + * @param boolean $const + */ + function __construct($order, $yValues, $xValues=array(), $const=True) { + if (parent::__construct($yValues, $xValues) !== False) { + if ($order < $this->_valueCount) { + $this->_bestFitType .= '_'.$order; + $this->_order = $order; + $this->_polynomial_regression($order, $yValues, $xValues, $const); + if (($this->getGoodnessOfFit() < 0.0) || ($this->getGoodnessOfFit() > 1.0)) { + $this->_error = True; + } + } else { + $this->_error = True; + } + } + } // function __construct() + +} // class polynomialBestFit \ No newline at end of file diff --git a/lib/phpexcel/PHPExcel/Shared/trend/powerBestFitClass.php b/lib/phpexcel/PHPExcel/Shared/trend/powerBestFitClass.php new file mode 100644 index 0000000..158e0c4 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Shared/trend/powerBestFitClass.php @@ -0,0 +1,142 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared_Trend + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/bestFitClass.php'; + + +/** + * PHPExcel_Power_Best_Fit + * + * @category PHPExcel + * @package PHPExcel_Shared_Trend + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Power_Best_Fit extends PHPExcel_Best_Fit +{ + /** + * Algorithm type to use for best-fit + * (Name of this trend class) + * + * @var string + **/ + protected $_bestFitType = 'power'; + + + /** + * Return the Y-Value for a specified value of X + * + * @param float $xValue X-Value + * @return float Y-Value + **/ + public function getValueOfYForX($xValue) { + return $this->getIntersect() * pow(($xValue - $this->_Xoffset),$this->getSlope()); + } // function getValueOfYForX() + + + /** + * Return the X-Value for a specified value of Y + * + * @param float $yValue Y-Value + * @return float X-Value + **/ + public function getValueOfXForY($yValue) { + return pow((($yValue + $this->_Yoffset) / $this->getIntersect()),(1 / $this->getSlope())); + } // function getValueOfXForY() + + + /** + * Return the Equation of the best-fit line + * + * @param int $dp Number of places of decimal precision to display + * @return string + **/ + public function getEquation($dp=0) { + $slope = $this->getSlope($dp); + $intersect = $this->getIntersect($dp); + + return 'Y = '.$intersect.' * X^'.$slope; + } // function getEquation() + + + /** + * Return the Value of X where it intersects Y = 0 + * + * @param int $dp Number of places of decimal precision to display + * @return string + **/ + public function getIntersect($dp=0) { + if ($dp != 0) { + return round(exp($this->_intersect),$dp); + } + return exp($this->_intersect); + } // function getIntersect() + + + /** + * Execute the regression and calculate the goodness of fit for a set of X and Y data values + * + * @param float[] $yValues The set of Y-values for this regression + * @param float[] $xValues The set of X-values for this regression + * @param boolean $const + */ + private function _power_regression($yValues, $xValues, $const) { + foreach($xValues as &$value) { + if ($value < 0.0) { + $value = 0 - log(abs($value)); + } elseif ($value > 0.0) { + $value = log($value); + } + } + unset($value); + foreach($yValues as &$value) { + if ($value < 0.0) { + $value = 0 - log(abs($value)); + } elseif ($value > 0.0) { + $value = log($value); + } + } + unset($value); + + $this->_leastSquareFit($yValues, $xValues, $const); + } // function _power_regression() + + + /** + * Define the regression and calculate the goodness of fit for a set of X and Y data values + * + * @param float[] $yValues The set of Y-values for this regression + * @param float[] $xValues The set of X-values for this regression + * @param boolean $const + */ + function __construct($yValues, $xValues=array(), $const=True) { + if (parent::__construct($yValues, $xValues) !== False) { + $this->_power_regression($yValues, $xValues, $const); + } + } // function __construct() + +} // class powerBestFit \ No newline at end of file diff --git a/lib/phpexcel/PHPExcel/Shared/trend/trendClass.php b/lib/phpexcel/PHPExcel/Shared/trend/trendClass.php new file mode 100644 index 0000000..d891a7d --- /dev/null +++ b/lib/phpexcel/PHPExcel/Shared/trend/trendClass.php @@ -0,0 +1,156 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared_Trend + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/linearBestFitClass.php'; +require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/logarithmicBestFitClass.php'; +require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/exponentialBestFitClass.php'; +require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/powerBestFitClass.php'; +require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/polynomialBestFitClass.php'; + + +/** + * PHPExcel_trendClass + * + * @category PHPExcel + * @package PHPExcel_Shared_Trend + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class trendClass +{ + const TREND_LINEAR = 'Linear'; + const TREND_LOGARITHMIC = 'Logarithmic'; + const TREND_EXPONENTIAL = 'Exponential'; + const TREND_POWER = 'Power'; + const TREND_POLYNOMIAL_2 = 'Polynomial_2'; + const TREND_POLYNOMIAL_3 = 'Polynomial_3'; + const TREND_POLYNOMIAL_4 = 'Polynomial_4'; + const TREND_POLYNOMIAL_5 = 'Polynomial_5'; + const TREND_POLYNOMIAL_6 = 'Polynomial_6'; + const TREND_BEST_FIT = 'Bestfit'; + const TREND_BEST_FIT_NO_POLY = 'Bestfit_no_Polynomials'; + + /** + * Names of the best-fit trend analysis methods + * + * @var string[] + **/ + private static $_trendTypes = array( self::TREND_LINEAR, + self::TREND_LOGARITHMIC, + self::TREND_EXPONENTIAL, + self::TREND_POWER + ); + /** + * Names of the best-fit trend polynomial orders + * + * @var string[] + **/ + private static $_trendTypePolyOrders = array( self::TREND_POLYNOMIAL_2, + self::TREND_POLYNOMIAL_3, + self::TREND_POLYNOMIAL_4, + self::TREND_POLYNOMIAL_5, + self::TREND_POLYNOMIAL_6 + ); + + /** + * Cached results for each method when trying to identify which provides the best fit + * + * @var PHPExcel_Best_Fit[] + **/ + private static $_trendCache = array(); + + + public static function calculate($trendType=self::TREND_BEST_FIT, $yValues, $xValues=array(), $const=True) { + // Calculate number of points in each dataset + $nY = count($yValues); + $nX = count($xValues); + + // Define X Values if necessary + if ($nX == 0) { + $xValues = range(1,$nY); + $nX = $nY; + } elseif ($nY != $nX) { + // Ensure both arrays of points are the same size + trigger_error("trend(): Number of elements in coordinate arrays do not match.", E_USER_ERROR); + } + + $key = md5($trendType.$const.serialize($yValues).serialize($xValues)); + // Determine which trend method has been requested + switch ($trendType) { + // Instantiate and return the class for the requested trend method + case self::TREND_LINEAR : + case self::TREND_LOGARITHMIC : + case self::TREND_EXPONENTIAL : + case self::TREND_POWER : + if (!isset(self::$_trendCache[$key])) { + $className = 'PHPExcel_'.$trendType.'_Best_Fit'; + self::$_trendCache[$key] = new $className($yValues,$xValues,$const); + } + return self::$_trendCache[$key]; + break; + case self::TREND_POLYNOMIAL_2 : + case self::TREND_POLYNOMIAL_3 : + case self::TREND_POLYNOMIAL_4 : + case self::TREND_POLYNOMIAL_5 : + case self::TREND_POLYNOMIAL_6 : + if (!isset(self::$_trendCache[$key])) { + $order = substr($trendType,-1); + self::$_trendCache[$key] = new PHPExcel_Polynomial_Best_Fit($order,$yValues,$xValues,$const); + } + return self::$_trendCache[$key]; + break; + case self::TREND_BEST_FIT : + case self::TREND_BEST_FIT_NO_POLY : + // If the request is to determine the best fit regression, then we test each trend line in turn + // Start by generating an instance of each available trend method + foreach(self::$_trendTypes as $trendMethod) { + $className = 'PHPExcel_'.$trendMethod.'BestFit'; + $bestFit[$trendMethod] = new $className($yValues,$xValues,$const); + $bestFitValue[$trendMethod] = $bestFit[$trendMethod]->getGoodnessOfFit(); + } + if ($trendType != self::TREND_BEST_FIT_NO_POLY) { + foreach(self::$_trendTypePolyOrders as $trendMethod) { + $order = substr($trendMethod,-1); + $bestFit[$trendMethod] = new PHPExcel_Polynomial_Best_Fit($order,$yValues,$xValues,$const); + if ($bestFit[$trendMethod]->getError()) { + unset($bestFit[$trendMethod]); + } else { + $bestFitValue[$trendMethod] = $bestFit[$trendMethod]->getGoodnessOfFit(); + } + } + } + // Determine which of our trend lines is the best fit, and then we return the instance of that trend class + arsort($bestFitValue); + $bestFitType = key($bestFitValue); + return $bestFit[$bestFitType]; + break; + default : + return false; + } + } // function calculate() + +} // class trendClass \ No newline at end of file diff --git a/lib/phpexcel/PHPExcel/Style.php b/lib/phpexcel/PHPExcel/Style.php new file mode 100644 index 0000000..715ae11 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Style.php @@ -0,0 +1,668 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Style + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Style + * + * @category PHPExcel + * @package PHPExcel_Style + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Style extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable +{ + /** + * Font + * + * @var PHPExcel_Style_Font + */ + protected $_font; + + /** + * Fill + * + * @var PHPExcel_Style_Fill + */ + protected $_fill; + + /** + * Borders + * + * @var PHPExcel_Style_Borders + */ + protected $_borders; + + /** + * Alignment + * + * @var PHPExcel_Style_Alignment + */ + protected $_alignment; + + /** + * Number Format + * + * @var PHPExcel_Style_NumberFormat + */ + protected $_numberFormat; + + /** + * Conditional styles + * + * @var PHPExcel_Style_Conditional[] + */ + protected $_conditionalStyles; + + /** + * Protection + * + * @var PHPExcel_Style_Protection + */ + protected $_protection; + + /** + * Index of style in collection. Only used for real style. + * + * @var int + */ + protected $_index; + + /** + * Use Quote Prefix when displaying in cell editor. Only used for real style. + * + * @var boolean + */ + protected $_quotePrefix = false; + + /** + * Create a new PHPExcel_Style + * + * @param boolean $isSupervisor Flag indicating if this is a supervisor or not + * Leave this value at default unless you understand exactly what + * its ramifications are + * @param boolean $isConditional Flag indicating if this is a conditional style or not + * Leave this value at default unless you understand exactly what + * its ramifications are + */ + public function __construct($isSupervisor = false, $isConditional = false) + { + // Supervisor? + $this->_isSupervisor = $isSupervisor; + + // Initialise values + $this->_conditionalStyles = array(); + $this->_font = new PHPExcel_Style_Font($isSupervisor, $isConditional); + $this->_fill = new PHPExcel_Style_Fill($isSupervisor, $isConditional); + $this->_borders = new PHPExcel_Style_Borders($isSupervisor, $isConditional); + $this->_alignment = new PHPExcel_Style_Alignment($isSupervisor, $isConditional); + $this->_numberFormat = new PHPExcel_Style_NumberFormat($isSupervisor, $isConditional); + $this->_protection = new PHPExcel_Style_Protection($isSupervisor, $isConditional); + + // bind parent if we are a supervisor + if ($isSupervisor) { + $this->_font->bindParent($this); + $this->_fill->bindParent($this); + $this->_borders->bindParent($this); + $this->_alignment->bindParent($this); + $this->_numberFormat->bindParent($this); + $this->_protection->bindParent($this); + } + } + + /** + * Get the shared style component for the currently active cell in currently active sheet. + * Only used for style supervisor + * + * @return PHPExcel_Style + */ + public function getSharedComponent() + { + $activeSheet = $this->getActiveSheet(); + $selectedCell = $this->getActiveCell(); // e.g. 'A1' + + if ($activeSheet->cellExists($selectedCell)) { + $xfIndex = $activeSheet->getCell($selectedCell)->getXfIndex(); + } else { + $xfIndex = 0; + } + + return $this->_parent->getCellXfByIndex($xfIndex); + } + + /** + * Get parent. Only used for style supervisor + * + * @return PHPExcel + */ + public function getParent() + { + return $this->_parent; + } + + /** + * Build style array from subcomponents + * + * @param array $array + * @return array + */ + public function getStyleArray($array) + { + return array('quotePrefix' => $array); + } + + /** + * Apply styles from array + * + * <code> + * $objPHPExcel->getActiveSheet()->getStyle('B2')->applyFromArray( + * array( + * 'font' => array( + * 'name' => 'Arial', + * 'bold' => true, + * 'italic' => false, + * 'underline' => PHPExcel_Style_Font::UNDERLINE_DOUBLE, + * 'strike' => false, + * 'color' => array( + * 'rgb' => '808080' + * ) + * ), + * 'borders' => array( + * 'bottom' => array( + * 'style' => PHPExcel_Style_Border::BORDER_DASHDOT, + * 'color' => array( + * 'rgb' => '808080' + * ) + * ), + * 'top' => array( + * 'style' => PHPExcel_Style_Border::BORDER_DASHDOT, + * 'color' => array( + * 'rgb' => '808080' + * ) + * ) + * ), + * 'quotePrefix' => true + * ) + * ); + * </code> + * + * @param array $pStyles Array containing style information + * @param boolean $pAdvanced Advanced mode for setting borders. + * @throws PHPExcel_Exception + * @return PHPExcel_Style + */ + public function applyFromArray($pStyles = null, $pAdvanced = true) + { + if (is_array($pStyles)) { + if ($this->_isSupervisor) { + + $pRange = $this->getSelectedCells(); + + // Uppercase coordinate + $pRange = strtoupper($pRange); + + // Is it a cell range or a single cell? + if (strpos($pRange, ':') === false) { + $rangeA = $pRange; + $rangeB = $pRange; + } else { + list($rangeA, $rangeB) = explode(':', $pRange); + } + + // Calculate range outer borders + $rangeStart = PHPExcel_Cell::coordinateFromString($rangeA); + $rangeEnd = PHPExcel_Cell::coordinateFromString($rangeB); + + // Translate column into index + $rangeStart[0] = PHPExcel_Cell::columnIndexFromString($rangeStart[0]) - 1; + $rangeEnd[0] = PHPExcel_Cell::columnIndexFromString($rangeEnd[0]) - 1; + + // Make sure we can loop upwards on rows and columns + if ($rangeStart[0] > $rangeEnd[0] && $rangeStart[1] > $rangeEnd[1]) { + $tmp = $rangeStart; + $rangeStart = $rangeEnd; + $rangeEnd = $tmp; + } + + // ADVANCED MODE: + + if ($pAdvanced && isset($pStyles['borders'])) { + + // 'allborders' is a shorthand property for 'outline' and 'inside' and + // it applies to components that have not been set explicitly + if (isset($pStyles['borders']['allborders'])) { + foreach (array('outline', 'inside') as $component) { + if (!isset($pStyles['borders'][$component])) { + $pStyles['borders'][$component] = $pStyles['borders']['allborders']; + } + } + unset($pStyles['borders']['allborders']); // not needed any more + } + + // 'outline' is a shorthand property for 'top', 'right', 'bottom', 'left' + // it applies to components that have not been set explicitly + if (isset($pStyles['borders']['outline'])) { + foreach (array('top', 'right', 'bottom', 'left') as $component) { + if (!isset($pStyles['borders'][$component])) { + $pStyles['borders'][$component] = $pStyles['borders']['outline']; + } + } + unset($pStyles['borders']['outline']); // not needed any more + } + + // 'inside' is a shorthand property for 'vertical' and 'horizontal' + // it applies to components that have not been set explicitly + if (isset($pStyles['borders']['inside'])) { + foreach (array('vertical', 'horizontal') as $component) { + if (!isset($pStyles['borders'][$component])) { + $pStyles['borders'][$component] = $pStyles['borders']['inside']; + } + } + unset($pStyles['borders']['inside']); // not needed any more + } + + // width and height characteristics of selection, 1, 2, or 3 (for 3 or more) + $xMax = min($rangeEnd[0] - $rangeStart[0] + 1, 3); + $yMax = min($rangeEnd[1] - $rangeStart[1] + 1, 3); + + // loop through up to 3 x 3 = 9 regions + for ($x = 1; $x <= $xMax; ++$x) { + // start column index for region + $colStart = ($x == 3) ? + PHPExcel_Cell::stringFromColumnIndex($rangeEnd[0]) + : PHPExcel_Cell::stringFromColumnIndex($rangeStart[0] + $x - 1); + + // end column index for region + $colEnd = ($x == 1) ? + PHPExcel_Cell::stringFromColumnIndex($rangeStart[0]) + : PHPExcel_Cell::stringFromColumnIndex($rangeEnd[0] - $xMax + $x); + + for ($y = 1; $y <= $yMax; ++$y) { + + // which edges are touching the region + $edges = array(); + + // are we at left edge + if ($x == 1) { + $edges[] = 'left'; + } + + // are we at right edge + if ($x == $xMax) { + $edges[] = 'right'; + } + + // are we at top edge? + if ($y == 1) { + $edges[] = 'top'; + } + + // are we at bottom edge? + if ($y == $yMax) { + $edges[] = 'bottom'; + } + + // start row index for region + $rowStart = ($y == 3) ? + $rangeEnd[1] : $rangeStart[1] + $y - 1; + + // end row index for region + $rowEnd = ($y == 1) ? + $rangeStart[1] : $rangeEnd[1] - $yMax + $y; + + // build range for region + $range = $colStart . $rowStart . ':' . $colEnd . $rowEnd; + + // retrieve relevant style array for region + $regionStyles = $pStyles; + unset($regionStyles['borders']['inside']); + + // what are the inner edges of the region when looking at the selection + $innerEdges = array_diff( array('top', 'right', 'bottom', 'left'), $edges ); + + // inner edges that are not touching the region should take the 'inside' border properties if they have been set + foreach ($innerEdges as $innerEdge) { + switch ($innerEdge) { + case 'top': + case 'bottom': + // should pick up 'horizontal' border property if set + if (isset($pStyles['borders']['horizontal'])) { + $regionStyles['borders'][$innerEdge] = $pStyles['borders']['horizontal']; + } else { + unset($regionStyles['borders'][$innerEdge]); + } + break; + case 'left': + case 'right': + // should pick up 'vertical' border property if set + if (isset($pStyles['borders']['vertical'])) { + $regionStyles['borders'][$innerEdge] = $pStyles['borders']['vertical']; + } else { + unset($regionStyles['borders'][$innerEdge]); + } + break; + } + } + + // apply region style to region by calling applyFromArray() in simple mode + $this->getActiveSheet()->getStyle($range)->applyFromArray($regionStyles, false); + } + } + return $this; + } + + // SIMPLE MODE: + + // Selection type, inspect + if (preg_match('/^[A-Z]+1:[A-Z]+1048576$/', $pRange)) { + $selectionType = 'COLUMN'; + } else if (preg_match('/^A[0-9]+:XFD[0-9]+$/', $pRange)) { + $selectionType = 'ROW'; + } else { + $selectionType = 'CELL'; + } + + // First loop through columns, rows, or cells to find out which styles are affected by this operation + switch ($selectionType) { + case 'COLUMN': + $oldXfIndexes = array(); + for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) { + $oldXfIndexes[$this->getActiveSheet()->getColumnDimensionByColumn($col)->getXfIndex()] = true; + } + break; + + case 'ROW': + $oldXfIndexes = array(); + for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) { + if ($this->getActiveSheet()->getRowDimension($row)->getXfIndex() == null) { + $oldXfIndexes[0] = true; // row without explicit style should be formatted based on default style + } else { + $oldXfIndexes[$this->getActiveSheet()->getRowDimension($row)->getXfIndex()] = true; + } + } + break; + + case 'CELL': + $oldXfIndexes = array(); + for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) { + for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) { + $oldXfIndexes[$this->getActiveSheet()->getCellByColumnAndRow($col, $row)->getXfIndex()] = true; + } + } + break; + } + + // clone each of the affected styles, apply the style array, and add the new styles to the workbook + $workbook = $this->getActiveSheet()->getParent(); + foreach ($oldXfIndexes as $oldXfIndex => $dummy) { + $style = $workbook->getCellXfByIndex($oldXfIndex); + $newStyle = clone $style; + $newStyle->applyFromArray($pStyles); + + if ($existingStyle = $workbook->getCellXfByHashCode($newStyle->getHashCode())) { + // there is already such cell Xf in our collection + $newXfIndexes[$oldXfIndex] = $existingStyle->getIndex(); + } else { + // we don't have such a cell Xf, need to add + $workbook->addCellXf($newStyle); + $newXfIndexes[$oldXfIndex] = $newStyle->getIndex(); + } + } + + // Loop through columns, rows, or cells again and update the XF index + switch ($selectionType) { + case 'COLUMN': + for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) { + $columnDimension = $this->getActiveSheet()->getColumnDimensionByColumn($col); + $oldXfIndex = $columnDimension->getXfIndex(); + $columnDimension->setXfIndex($newXfIndexes[$oldXfIndex]); + } + break; + + case 'ROW': + for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) { + $rowDimension = $this->getActiveSheet()->getRowDimension($row); + $oldXfIndex = $rowDimension->getXfIndex() === null ? + 0 : $rowDimension->getXfIndex(); // row without explicit style should be formatted based on default style + $rowDimension->setXfIndex($newXfIndexes[$oldXfIndex]); + } + break; + + case 'CELL': + for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) { + for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) { + $cell = $this->getActiveSheet()->getCellByColumnAndRow($col, $row); + $oldXfIndex = $cell->getXfIndex(); + $cell->setXfIndex($newXfIndexes[$oldXfIndex]); + } + } + break; + } + + } else { + // not a supervisor, just apply the style array directly on style object + if (array_key_exists('fill', $pStyles)) { + $this->getFill()->applyFromArray($pStyles['fill']); + } + if (array_key_exists('font', $pStyles)) { + $this->getFont()->applyFromArray($pStyles['font']); + } + if (array_key_exists('borders', $pStyles)) { + $this->getBorders()->applyFromArray($pStyles['borders']); + } + if (array_key_exists('alignment', $pStyles)) { + $this->getAlignment()->applyFromArray($pStyles['alignment']); + } + if (array_key_exists('numberformat', $pStyles)) { + $this->getNumberFormat()->applyFromArray($pStyles['numberformat']); + } + if (array_key_exists('protection', $pStyles)) { + $this->getProtection()->applyFromArray($pStyles['protection']); + } + if (array_key_exists('quotePrefix', $pStyles)) { + $this->_quotePrefix = $pStyles['quotePrefix']; + } + } + } else { + throw new PHPExcel_Exception("Invalid style array passed."); + } + return $this; + } + + /** + * Get Fill + * + * @return PHPExcel_Style_Fill + */ + public function getFill() + { + return $this->_fill; + } + + /** + * Get Font + * + * @return PHPExcel_Style_Font + */ + public function getFont() + { + return $this->_font; + } + + /** + * Set font + * + * @param PHPExcel_Style_Font $font + * @return PHPExcel_Style + */ + public function setFont(PHPExcel_Style_Font $font) + { + $this->_font = $font; + return $this; + } + + /** + * Get Borders + * + * @return PHPExcel_Style_Borders + */ + public function getBorders() + { + return $this->_borders; + } + + /** + * Get Alignment + * + * @return PHPExcel_Style_Alignment + */ + public function getAlignment() + { + return $this->_alignment; + } + + /** + * Get Number Format + * + * @return PHPExcel_Style_NumberFormat + */ + public function getNumberFormat() + { + return $this->_numberFormat; + } + + /** + * Get Conditional Styles. Only used on supervisor. + * + * @return PHPExcel_Style_Conditional[] + */ + public function getConditionalStyles() + { + return $this->getActiveSheet()->getConditionalStyles($this->getActiveCell()); + } + + /** + * Set Conditional Styles. Only used on supervisor. + * + * @param PHPExcel_Style_Conditional[] $pValue Array of condtional styles + * @return PHPExcel_Style + */ + public function setConditionalStyles($pValue = null) + { + if (is_array($pValue)) { + $this->getActiveSheet()->setConditionalStyles($this->getSelectedCells(), $pValue); + } + return $this; + } + + /** + * Get Protection + * + * @return PHPExcel_Style_Protection + */ + public function getProtection() + { + return $this->_protection; + } + + /** + * Get quote prefix + * + * @return boolean + */ + public function getQuotePrefix() + { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getQuotePrefix(); + } + return $this->_quotePrefix; + } + + /** + * Set quote prefix + * + * @param boolean $pValue + */ + public function setQuotePrefix($pValue) + { + if ($pValue == '') { + $pValue = false; + } + if ($this->_isSupervisor) { + $styleArray = array('quotePrefix' => $pValue); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_quotePrefix = (boolean) $pValue; + } + return $this; + } + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() + { + $hashConditionals = ''; + foreach ($this->_conditionalStyles as $conditional) { + $hashConditionals .= $conditional->getHashCode(); + } + + return md5( + $this->_fill->getHashCode() + . $this->_font->getHashCode() + . $this->_borders->getHashCode() + . $this->_alignment->getHashCode() + . $this->_numberFormat->getHashCode() + . $hashConditionals + . $this->_protection->getHashCode() + . ($this->_quotePrefix ? 't' : 'f') + . __CLASS__ + ); + } + + /** + * Get own index in style collection + * + * @return int + */ + public function getIndex() + { + return $this->_index; + } + + /** + * Set own index in style collection + * + * @param int $pValue + */ + public function setIndex($pValue) + { + $this->_index = $pValue; + } + +} diff --git a/lib/phpexcel/PHPExcel/Style/Alignment.php b/lib/phpexcel/PHPExcel/Style/Alignment.php new file mode 100644 index 0000000..0d9e076 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Style/Alignment.php @@ -0,0 +1,412 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Style + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Style_Alignment + * + * @category PHPExcel + * @package PHPExcel_Style + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Style_Alignment extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable +{ + /* Horizontal alignment styles */ + const HORIZONTAL_GENERAL = 'general'; + const HORIZONTAL_LEFT = 'left'; + const HORIZONTAL_RIGHT = 'right'; + const HORIZONTAL_CENTER = 'center'; + const HORIZONTAL_CENTER_CONTINUOUS = 'centerContinuous'; + const HORIZONTAL_JUSTIFY = 'justify'; + const HORIZONTAL_FILL = 'fill'; + const HORIZONTAL_DISTRIBUTED = 'distributed'; // Excel2007 only + + /* Vertical alignment styles */ + const VERTICAL_BOTTOM = 'bottom'; + const VERTICAL_TOP = 'top'; + const VERTICAL_CENTER = 'center'; + const VERTICAL_JUSTIFY = 'justify'; + const VERTICAL_DISTRIBUTED = 'distributed'; // Excel2007 only + + /** + * Horizontal + * + * @var string + */ + protected $_horizontal = PHPExcel_Style_Alignment::HORIZONTAL_GENERAL; + + /** + * Vertical + * + * @var string + */ + protected $_vertical = PHPExcel_Style_Alignment::VERTICAL_BOTTOM; + + /** + * Text rotation + * + * @var int + */ + protected $_textRotation = 0; + + /** + * Wrap text + * + * @var boolean + */ + protected $_wrapText = FALSE; + + /** + * Shrink to fit + * + * @var boolean + */ + protected $_shrinkToFit = FALSE; + + /** + * Indent - only possible with horizontal alignment left and right + * + * @var int + */ + protected $_indent = 0; + + /** + * Create a new PHPExcel_Style_Alignment + * + * @param boolean $isSupervisor Flag indicating if this is a supervisor or not + * Leave this value at default unless you understand exactly what + * its ramifications are + * @param boolean $isConditional Flag indicating if this is a conditional style or not + * Leave this value at default unless you understand exactly what + * its ramifications are + */ + public function __construct($isSupervisor = FALSE, $isConditional = FALSE) + { + // Supervisor? + parent::__construct($isSupervisor); + + if ($isConditional) { + $this->_horizontal = NULL; + $this->_vertical = NULL; + $this->_textRotation = NULL; + } + } + + /** + * Get the shared style component for the currently active cell in currently active sheet. + * Only used for style supervisor + * + * @return PHPExcel_Style_Alignment + */ + public function getSharedComponent() + { + return $this->_parent->getSharedComponent()->getAlignment(); + } + + /** + * Build style array from subcomponents + * + * @param array $array + * @return array + */ + public function getStyleArray($array) + { + return array('alignment' => $array); + } + + /** + * Apply styles from array + * + * <code> + * $objPHPExcel->getActiveSheet()->getStyle('B2')->getAlignment()->applyFromArray( + * array( + * 'horizontal' => PHPExcel_Style_Alignment::HORIZONTAL_CENTER, + * 'vertical' => PHPExcel_Style_Alignment::VERTICAL_CENTER, + * 'rotation' => 0, + * 'wrap' => TRUE + * ) + * ); + * </code> + * + * @param array $pStyles Array containing style information + * @throws PHPExcel_Exception + * @return PHPExcel_Style_Alignment + */ + public function applyFromArray($pStyles = NULL) { + if (is_array($pStyles)) { + if ($this->_isSupervisor) { + $this->getActiveSheet()->getStyle($this->getSelectedCells()) + ->applyFromArray($this->getStyleArray($pStyles)); + } else { + if (isset($pStyles['horizontal'])) { + $this->setHorizontal($pStyles['horizontal']); + } + if (isset($pStyles['vertical'])) { + $this->setVertical($pStyles['vertical']); + } + if (isset($pStyles['rotation'])) { + $this->setTextRotation($pStyles['rotation']); + } + if (isset($pStyles['wrap'])) { + $this->setWrapText($pStyles['wrap']); + } + if (isset($pStyles['shrinkToFit'])) { + $this->setShrinkToFit($pStyles['shrinkToFit']); + } + if (isset($pStyles['indent'])) { + $this->setIndent($pStyles['indent']); + } + } + } else { + throw new PHPExcel_Exception("Invalid style array passed."); + } + return $this; + } + + /** + * Get Horizontal + * + * @return string + */ + public function getHorizontal() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getHorizontal(); + } + return $this->_horizontal; + } + + /** + * Set Horizontal + * + * @param string $pValue + * @return PHPExcel_Style_Alignment + */ + public function setHorizontal($pValue = PHPExcel_Style_Alignment::HORIZONTAL_GENERAL) { + if ($pValue == '') { + $pValue = PHPExcel_Style_Alignment::HORIZONTAL_GENERAL; + } + + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('horizontal' => $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } + else { + $this->_horizontal = $pValue; + } + return $this; + } + + /** + * Get Vertical + * + * @return string + */ + public function getVertical() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getVertical(); + } + return $this->_vertical; + } + + /** + * Set Vertical + * + * @param string $pValue + * @return PHPExcel_Style_Alignment + */ + public function setVertical($pValue = PHPExcel_Style_Alignment::VERTICAL_BOTTOM) { + if ($pValue == '') { + $pValue = PHPExcel_Style_Alignment::VERTICAL_BOTTOM; + } + + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('vertical' => $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_vertical = $pValue; + } + return $this; + } + + /** + * Get TextRotation + * + * @return int + */ + public function getTextRotation() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getTextRotation(); + } + return $this->_textRotation; + } + + /** + * Set TextRotation + * + * @param int $pValue + * @throws PHPExcel_Exception + * @return PHPExcel_Style_Alignment + */ + public function setTextRotation($pValue = 0) { + // Excel2007 value 255 => PHPExcel value -165 + if ($pValue == 255) { + $pValue = -165; + } + + // Set rotation + if ( ($pValue >= -90 && $pValue <= 90) || $pValue == -165 ) { + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('rotation' => $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_textRotation = $pValue; + } + } else { + throw new PHPExcel_Exception("Text rotation should be a value between -90 and 90."); + } + + return $this; + } + + /** + * Get Wrap Text + * + * @return boolean + */ + public function getWrapText() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getWrapText(); + } + return $this->_wrapText; + } + + /** + * Set Wrap Text + * + * @param boolean $pValue + * @return PHPExcel_Style_Alignment + */ + public function setWrapText($pValue = FALSE) { + if ($pValue == '') { + $pValue = FALSE; + } + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('wrap' => $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_wrapText = $pValue; + } + return $this; + } + + /** + * Get Shrink to fit + * + * @return boolean + */ + public function getShrinkToFit() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getShrinkToFit(); + } + return $this->_shrinkToFit; + } + + /** + * Set Shrink to fit + * + * @param boolean $pValue + * @return PHPExcel_Style_Alignment + */ + public function setShrinkToFit($pValue = FALSE) { + if ($pValue == '') { + $pValue = FALSE; + } + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('shrinkToFit' => $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_shrinkToFit = $pValue; + } + return $this; + } + + /** + * Get indent + * + * @return int + */ + public function getIndent() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getIndent(); + } + return $this->_indent; + } + + /** + * Set indent + * + * @param int $pValue + * @return PHPExcel_Style_Alignment + */ + public function setIndent($pValue = 0) { + if ($pValue > 0) { + if ($this->getHorizontal() != self::HORIZONTAL_GENERAL && + $this->getHorizontal() != self::HORIZONTAL_LEFT && + $this->getHorizontal() != self::HORIZONTAL_RIGHT) { + $pValue = 0; // indent not supported + } + } + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('indent' => $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_indent = $pValue; + } + return $this; + } + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getHashCode(); + } + return md5( + $this->_horizontal + . $this->_vertical + . $this->_textRotation + . ($this->_wrapText ? 't' : 'f') + . ($this->_shrinkToFit ? 't' : 'f') + . $this->_indent + . __CLASS__ + ); + } + +} diff --git a/lib/phpexcel/PHPExcel/Style/Border.php b/lib/phpexcel/PHPExcel/Style/Border.php new file mode 100644 index 0000000..3b7eba9 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Style/Border.php @@ -0,0 +1,294 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Style + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Style_Border + * + * @category PHPExcel + * @package PHPExcel_Style + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Style_Border extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable +{ + /* Border style */ + const BORDER_NONE = 'none'; + const BORDER_DASHDOT = 'dashDot'; + const BORDER_DASHDOTDOT = 'dashDotDot'; + const BORDER_DASHED = 'dashed'; + const BORDER_DOTTED = 'dotted'; + const BORDER_DOUBLE = 'double'; + const BORDER_HAIR = 'hair'; + const BORDER_MEDIUM = 'medium'; + const BORDER_MEDIUMDASHDOT = 'mediumDashDot'; + const BORDER_MEDIUMDASHDOTDOT = 'mediumDashDotDot'; + const BORDER_MEDIUMDASHED = 'mediumDashed'; + const BORDER_SLANTDASHDOT = 'slantDashDot'; + const BORDER_THICK = 'thick'; + const BORDER_THIN = 'thin'; + + /** + * Border style + * + * @var string + */ + protected $_borderStyle = PHPExcel_Style_Border::BORDER_NONE; + + /** + * Border color + * + * @var PHPExcel_Style_Color + */ + protected $_color; + + /** + * Parent property name + * + * @var string + */ + protected $_parentPropertyName; + + /** + * Create a new PHPExcel_Style_Border + * + * @param boolean $isSupervisor Flag indicating if this is a supervisor or not + * Leave this value at default unless you understand exactly what + * its ramifications are + * @param boolean $isConditional Flag indicating if this is a conditional style or not + * Leave this value at default unless you understand exactly what + * its ramifications are + */ + public function __construct($isSupervisor = FALSE, $isConditional = FALSE) + { + // Supervisor? + parent::__construct($isSupervisor); + + // Initialise values + $this->_color = new PHPExcel_Style_Color(PHPExcel_Style_Color::COLOR_BLACK, $isSupervisor); + + // bind parent if we are a supervisor + if ($isSupervisor) { + $this->_color->bindParent($this, '_color'); + } + } + + /** + * Bind parent. Only used for supervisor + * + * @param PHPExcel_Style_Borders $parent + * @param string $parentPropertyName + * @return PHPExcel_Style_Border + */ + public function bindParent($parent, $parentPropertyName=NULL) + { + $this->_parent = $parent; + $this->_parentPropertyName = $parentPropertyName; + return $this; + } + + /** + * Get the shared style component for the currently active cell in currently active sheet. + * Only used for style supervisor + * + * @return PHPExcel_Style_Border + * @throws PHPExcel_Exception + */ + public function getSharedComponent() + { + switch ($this->_parentPropertyName) { + case '_allBorders': + case '_horizontal': + case '_inside': + case '_outline': + case '_vertical': + throw new PHPExcel_Exception('Cannot get shared component for a pseudo-border.'); + break; + case '_bottom': + return $this->_parent->getSharedComponent()->getBottom(); break; + case '_diagonal': + return $this->_parent->getSharedComponent()->getDiagonal(); break; + case '_left': + return $this->_parent->getSharedComponent()->getLeft(); break; + case '_right': + return $this->_parent->getSharedComponent()->getRight(); break; + case '_top': + return $this->_parent->getSharedComponent()->getTop(); break; + + } + } + + /** + * Build style array from subcomponents + * + * @param array $array + * @return array + */ + public function getStyleArray($array) + { + switch ($this->_parentPropertyName) { + case '_allBorders': + $key = 'allborders'; break; + case '_bottom': + $key = 'bottom'; break; + case '_diagonal': + $key = 'diagonal'; break; + case '_horizontal': + $key = 'horizontal'; break; + case '_inside': + $key = 'inside'; break; + case '_left': + $key = 'left'; break; + case '_outline': + $key = 'outline'; break; + case '_right': + $key = 'right'; break; + case '_top': + $key = 'top'; break; + case '_vertical': + $key = 'vertical'; break; + } + return $this->_parent->getStyleArray(array($key => $array)); + } + + /** + * Apply styles from array + * + * <code> + * $objPHPExcel->getActiveSheet()->getStyle('B2')->getBorders()->getTop()->applyFromArray( + * array( + * 'style' => PHPExcel_Style_Border::BORDER_DASHDOT, + * 'color' => array( + * 'rgb' => '808080' + * ) + * ) + * ); + * </code> + * + * @param array $pStyles Array containing style information + * @throws PHPExcel_Exception + * @return PHPExcel_Style_Border + */ + public function applyFromArray($pStyles = null) { + if (is_array($pStyles)) { + if ($this->_isSupervisor) { + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles)); + } else { + if (isset($pStyles['style'])) { + $this->setBorderStyle($pStyles['style']); + } + if (isset($pStyles['color'])) { + $this->getColor()->applyFromArray($pStyles['color']); + } + } + } else { + throw new PHPExcel_Exception("Invalid style array passed."); + } + return $this; + } + + /** + * Get Border style + * + * @return string + */ + public function getBorderStyle() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getBorderStyle(); + } + return $this->_borderStyle; + } + + /** + * Set Border style + * + * @param string|boolean $pValue + * When passing a boolean, FALSE equates PHPExcel_Style_Border::BORDER_NONE + * and TRUE to PHPExcel_Style_Border::BORDER_MEDIUM + * @return PHPExcel_Style_Border + */ + public function setBorderStyle($pValue = PHPExcel_Style_Border::BORDER_NONE) { + + if (empty($pValue)) { + $pValue = PHPExcel_Style_Border::BORDER_NONE; + } elseif(is_bool($pValue) && $pValue) { + $pValue = PHPExcel_Style_Border::BORDER_MEDIUM; + } + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('style' => $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_borderStyle = $pValue; + } + return $this; + } + + /** + * Get Border Color + * + * @return PHPExcel_Style_Color + */ + public function getColor() { + return $this->_color; + } + + /** + * Set Border Color + * + * @param PHPExcel_Style_Color $pValue + * @throws PHPExcel_Exception + * @return PHPExcel_Style_Border + */ + public function setColor(PHPExcel_Style_Color $pValue = null) { + // make sure parameter is a real color and not a supervisor + $color = $pValue->getIsSupervisor() ? $pValue->getSharedComponent() : $pValue; + + if ($this->_isSupervisor) { + $styleArray = $this->getColor()->getStyleArray(array('argb' => $color->getARGB())); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_color = $color; + } + return $this; + } + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getHashCode(); + } + return md5( + $this->_borderStyle + . $this->_color->getHashCode() + . __CLASS__ + ); + } + +} diff --git a/lib/phpexcel/PHPExcel/Style/Borders.php b/lib/phpexcel/PHPExcel/Style/Borders.php new file mode 100644 index 0000000..b90838a --- /dev/null +++ b/lib/phpexcel/PHPExcel/Style/Borders.php @@ -0,0 +1,424 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Style + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Style_Borders + * + * @category PHPExcel + * @package PHPExcel_Style + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Style_Borders extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable +{ + /* Diagonal directions */ + const DIAGONAL_NONE = 0; + const DIAGONAL_UP = 1; + const DIAGONAL_DOWN = 2; + const DIAGONAL_BOTH = 3; + + /** + * Left + * + * @var PHPExcel_Style_Border + */ + protected $_left; + + /** + * Right + * + * @var PHPExcel_Style_Border + */ + protected $_right; + + /** + * Top + * + * @var PHPExcel_Style_Border + */ + protected $_top; + + /** + * Bottom + * + * @var PHPExcel_Style_Border + */ + protected $_bottom; + + /** + * Diagonal + * + * @var PHPExcel_Style_Border + */ + protected $_diagonal; + + /** + * DiagonalDirection + * + * @var int + */ + protected $_diagonalDirection; + + /** + * All borders psedo-border. Only applies to supervisor. + * + * @var PHPExcel_Style_Border + */ + protected $_allBorders; + + /** + * Outline psedo-border. Only applies to supervisor. + * + * @var PHPExcel_Style_Border + */ + protected $_outline; + + /** + * Inside psedo-border. Only applies to supervisor. + * + * @var PHPExcel_Style_Border + */ + protected $_inside; + + /** + * Vertical pseudo-border. Only applies to supervisor. + * + * @var PHPExcel_Style_Border + */ + protected $_vertical; + + /** + * Horizontal pseudo-border. Only applies to supervisor. + * + * @var PHPExcel_Style_Border + */ + protected $_horizontal; + + /** + * Create a new PHPExcel_Style_Borders + * + * @param boolean $isSupervisor Flag indicating if this is a supervisor or not + * Leave this value at default unless you understand exactly what + * its ramifications are + * @param boolean $isConditional Flag indicating if this is a conditional style or not + * Leave this value at default unless you understand exactly what + * its ramifications are + */ + public function __construct($isSupervisor = FALSE, $isConditional = FALSE) + { + // Supervisor? + parent::__construct($isSupervisor); + + // Initialise values + $this->_left = new PHPExcel_Style_Border($isSupervisor, $isConditional); + $this->_right = new PHPExcel_Style_Border($isSupervisor, $isConditional); + $this->_top = new PHPExcel_Style_Border($isSupervisor, $isConditional); + $this->_bottom = new PHPExcel_Style_Border($isSupervisor, $isConditional); + $this->_diagonal = new PHPExcel_Style_Border($isSupervisor, $isConditional); + $this->_diagonalDirection = PHPExcel_Style_Borders::DIAGONAL_NONE; + + // Specially for supervisor + if ($isSupervisor) { + // Initialize pseudo-borders + $this->_allBorders = new PHPExcel_Style_Border(TRUE); + $this->_outline = new PHPExcel_Style_Border(TRUE); + $this->_inside = new PHPExcel_Style_Border(TRUE); + $this->_vertical = new PHPExcel_Style_Border(TRUE); + $this->_horizontal = new PHPExcel_Style_Border(TRUE); + + // bind parent if we are a supervisor + $this->_left->bindParent($this, '_left'); + $this->_right->bindParent($this, '_right'); + $this->_top->bindParent($this, '_top'); + $this->_bottom->bindParent($this, '_bottom'); + $this->_diagonal->bindParent($this, '_diagonal'); + $this->_allBorders->bindParent($this, '_allBorders'); + $this->_outline->bindParent($this, '_outline'); + $this->_inside->bindParent($this, '_inside'); + $this->_vertical->bindParent($this, '_vertical'); + $this->_horizontal->bindParent($this, '_horizontal'); + } + } + + /** + * Get the shared style component for the currently active cell in currently active sheet. + * Only used for style supervisor + * + * @return PHPExcel_Style_Borders + */ + public function getSharedComponent() + { + return $this->_parent->getSharedComponent()->getBorders(); + } + + /** + * Build style array from subcomponents + * + * @param array $array + * @return array + */ + public function getStyleArray($array) + { + return array('borders' => $array); + } + + /** + * Apply styles from array + * + * <code> + * $objPHPExcel->getActiveSheet()->getStyle('B2')->getBorders()->applyFromArray( + * array( + * 'bottom' => array( + * 'style' => PHPExcel_Style_Border::BORDER_DASHDOT, + * 'color' => array( + * 'rgb' => '808080' + * ) + * ), + * 'top' => array( + * 'style' => PHPExcel_Style_Border::BORDER_DASHDOT, + * 'color' => array( + * 'rgb' => '808080' + * ) + * ) + * ) + * ); + * </code> + * <code> + * $objPHPExcel->getActiveSheet()->getStyle('B2')->getBorders()->applyFromArray( + * array( + * 'allborders' => array( + * 'style' => PHPExcel_Style_Border::BORDER_DASHDOT, + * 'color' => array( + * 'rgb' => '808080' + * ) + * ) + * ) + * ); + * </code> + * + * @param array $pStyles Array containing style information + * @throws PHPExcel_Exception + * @return PHPExcel_Style_Borders + */ + public function applyFromArray($pStyles = null) { + if (is_array($pStyles)) { + if ($this->_isSupervisor) { + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles)); + } else { + if (array_key_exists('left', $pStyles)) { + $this->getLeft()->applyFromArray($pStyles['left']); + } + if (array_key_exists('right', $pStyles)) { + $this->getRight()->applyFromArray($pStyles['right']); + } + if (array_key_exists('top', $pStyles)) { + $this->getTop()->applyFromArray($pStyles['top']); + } + if (array_key_exists('bottom', $pStyles)) { + $this->getBottom()->applyFromArray($pStyles['bottom']); + } + if (array_key_exists('diagonal', $pStyles)) { + $this->getDiagonal()->applyFromArray($pStyles['diagonal']); + } + if (array_key_exists('diagonaldirection', $pStyles)) { + $this->setDiagonalDirection($pStyles['diagonaldirection']); + } + if (array_key_exists('allborders', $pStyles)) { + $this->getLeft()->applyFromArray($pStyles['allborders']); + $this->getRight()->applyFromArray($pStyles['allborders']); + $this->getTop()->applyFromArray($pStyles['allborders']); + $this->getBottom()->applyFromArray($pStyles['allborders']); + } + } + } else { + throw new PHPExcel_Exception("Invalid style array passed."); + } + return $this; + } + + /** + * Get Left + * + * @return PHPExcel_Style_Border + */ + public function getLeft() { + return $this->_left; + } + + /** + * Get Right + * + * @return PHPExcel_Style_Border + */ + public function getRight() { + return $this->_right; + } + + /** + * Get Top + * + * @return PHPExcel_Style_Border + */ + public function getTop() { + return $this->_top; + } + + /** + * Get Bottom + * + * @return PHPExcel_Style_Border + */ + public function getBottom() { + return $this->_bottom; + } + + /** + * Get Diagonal + * + * @return PHPExcel_Style_Border + */ + public function getDiagonal() { + return $this->_diagonal; + } + + /** + * Get AllBorders (pseudo-border). Only applies to supervisor. + * + * @return PHPExcel_Style_Border + * @throws PHPExcel_Exception + */ + public function getAllBorders() { + if (!$this->_isSupervisor) { + throw new PHPExcel_Exception('Can only get pseudo-border for supervisor.'); + } + return $this->_allBorders; + } + + /** + * Get Outline (pseudo-border). Only applies to supervisor. + * + * @return boolean + * @throws PHPExcel_Exception + */ + public function getOutline() { + if (!$this->_isSupervisor) { + throw new PHPExcel_Exception('Can only get pseudo-border for supervisor.'); + } + return $this->_outline; + } + + /** + * Get Inside (pseudo-border). Only applies to supervisor. + * + * @return boolean + * @throws PHPExcel_Exception + */ + public function getInside() { + if (!$this->_isSupervisor) { + throw new PHPExcel_Exception('Can only get pseudo-border for supervisor.'); + } + return $this->_inside; + } + + /** + * Get Vertical (pseudo-border). Only applies to supervisor. + * + * @return PHPExcel_Style_Border + * @throws PHPExcel_Exception + */ + public function getVertical() { + if (!$this->_isSupervisor) { + throw new PHPExcel_Exception('Can only get pseudo-border for supervisor.'); + } + return $this->_vertical; + } + + /** + * Get Horizontal (pseudo-border). Only applies to supervisor. + * + * @return PHPExcel_Style_Border + * @throws PHPExcel_Exception + */ + public function getHorizontal() { + if (!$this->_isSupervisor) { + throw new PHPExcel_Exception('Can only get pseudo-border for supervisor.'); + } + return $this->_horizontal; + } + + /** + * Get DiagonalDirection + * + * @return int + */ + public function getDiagonalDirection() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getDiagonalDirection(); + } + return $this->_diagonalDirection; + } + + /** + * Set DiagonalDirection + * + * @param int $pValue + * @return PHPExcel_Style_Borders + */ + public function setDiagonalDirection($pValue = PHPExcel_Style_Borders::DIAGONAL_NONE) { + if ($pValue == '') { + $pValue = PHPExcel_Style_Borders::DIAGONAL_NONE; + } + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('diagonaldirection' => $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_diagonalDirection = $pValue; + } + return $this; + } + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getHashcode(); + } + return md5( + $this->getLeft()->getHashCode() + . $this->getRight()->getHashCode() + . $this->getTop()->getHashCode() + . $this->getBottom()->getHashCode() + . $this->getDiagonal()->getHashCode() + . $this->getDiagonalDirection() + . __CLASS__ + ); + } + +} diff --git a/lib/phpexcel/PHPExcel/Style/Color.php b/lib/phpexcel/PHPExcel/Style/Color.php new file mode 100644 index 0000000..4d34504 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Style/Color.php @@ -0,0 +1,429 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Style + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Style_Color + * + * @category PHPExcel + * @package PHPExcel_Style + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Style_Color extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable +{ + /* Colors */ + const COLOR_BLACK = 'FF000000'; + const COLOR_WHITE = 'FFFFFFFF'; + const COLOR_RED = 'FFFF0000'; + const COLOR_DARKRED = 'FF800000'; + const COLOR_BLUE = 'FF0000FF'; + const COLOR_DARKBLUE = 'FF000080'; + const COLOR_GREEN = 'FF00FF00'; + const COLOR_DARKGREEN = 'FF008000'; + const COLOR_YELLOW = 'FFFFFF00'; + const COLOR_DARKYELLOW = 'FF808000'; + + /** + * Indexed colors array + * + * @var array + */ + protected static $_indexedColors; + + /** + * ARGB - Alpha RGB + * + * @var string + */ + protected $_argb = NULL; + + /** + * Parent property name + * + * @var string + */ + protected $_parentPropertyName; + + + /** + * Create a new PHPExcel_Style_Color + * + * @param string $pARGB ARGB value for the colour + * @param boolean $isSupervisor Flag indicating if this is a supervisor or not + * Leave this value at default unless you understand exactly what + * its ramifications are + * @param boolean $isConditional Flag indicating if this is a conditional style or not + * Leave this value at default unless you understand exactly what + * its ramifications are + */ + public function __construct($pARGB = PHPExcel_Style_Color::COLOR_BLACK, $isSupervisor = FALSE, $isConditional = FALSE) + { + // Supervisor? + parent::__construct($isSupervisor); + + // Initialise values + if (!$isConditional) { + $this->_argb = $pARGB; + } + } + + /** + * Bind parent. Only used for supervisor + * + * @param mixed $parent + * @param string $parentPropertyName + * @return PHPExcel_Style_Color + */ + public function bindParent($parent, $parentPropertyName=NULL) + { + $this->_parent = $parent; + $this->_parentPropertyName = $parentPropertyName; + return $this; + } + + /** + * Get the shared style component for the currently active cell in currently active sheet. + * Only used for style supervisor + * + * @return PHPExcel_Style_Color + */ + public function getSharedComponent() + { + switch ($this->_parentPropertyName) { + case '_endColor': + return $this->_parent->getSharedComponent()->getEndColor(); break; + case '_color': + return $this->_parent->getSharedComponent()->getColor(); break; + case '_startColor': + return $this->_parent->getSharedComponent()->getStartColor(); break; + } + } + + /** + * Build style array from subcomponents + * + * @param array $array + * @return array + */ + public function getStyleArray($array) + { + switch ($this->_parentPropertyName) { + case '_endColor': + $key = 'endcolor'; + break; + case '_color': + $key = 'color'; + break; + case '_startColor': + $key = 'startcolor'; + break; + + } + return $this->_parent->getStyleArray(array($key => $array)); + } + + /** + * Apply styles from array + * + * <code> + * $objPHPExcel->getActiveSheet()->getStyle('B2')->getFont()->getColor()->applyFromArray( array('rgb' => '808080') ); + * </code> + * + * @param array $pStyles Array containing style information + * @throws PHPExcel_Exception + * @return PHPExcel_Style_Color + */ + public function applyFromArray($pStyles = NULL) { + if (is_array($pStyles)) { + if ($this->_isSupervisor) { + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles)); + } else { + if (array_key_exists('rgb', $pStyles)) { + $this->setRGB($pStyles['rgb']); + } + if (array_key_exists('argb', $pStyles)) { + $this->setARGB($pStyles['argb']); + } + } + } else { + throw new PHPExcel_Exception("Invalid style array passed."); + } + return $this; + } + + /** + * Get ARGB + * + * @return string + */ + public function getARGB() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getARGB(); + } + return $this->_argb; + } + + /** + * Set ARGB + * + * @param string $pValue + * @return PHPExcel_Style_Color + */ + public function setARGB($pValue = PHPExcel_Style_Color::COLOR_BLACK) { + if ($pValue == '') { + $pValue = PHPExcel_Style_Color::COLOR_BLACK; + } + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('argb' => $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_argb = $pValue; + } + return $this; + } + + /** + * Get RGB + * + * @return string + */ + public function getRGB() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getRGB(); + } + return substr($this->_argb, 2); + } + + /** + * Set RGB + * + * @param string $pValue RGB value + * @return PHPExcel_Style_Color + */ + public function setRGB($pValue = '000000') { + if ($pValue == '') { + $pValue = '000000'; + } + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('argb' => 'FF' . $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_argb = 'FF' . $pValue; + } + return $this; + } + + /** + * Get a specified colour component of an RGB value + * + * @private + * @param string $RGB The colour as an RGB value (e.g. FF00CCCC or CCDDEE + * @param int $offset Position within the RGB value to extract + * @param boolean $hex Flag indicating whether the component should be returned as a hex or a + * decimal value + * @return string The extracted colour component + */ + private static function _getColourComponent($RGB,$offset,$hex=TRUE) { + $colour = substr($RGB, $offset, 2); + if (!$hex) + $colour = hexdec($colour); + return $colour; + } + + /** + * Get the red colour component of an RGB value + * + * @param string $RGB The colour as an RGB value (e.g. FF00CCCC or CCDDEE + * @param boolean $hex Flag indicating whether the component should be returned as a hex or a + * decimal value + * @return string The red colour component + */ + public static function getRed($RGB,$hex=TRUE) { + return self::_getColourComponent($RGB, strlen($RGB) - 6, $hex); + } + + /** + * Get the green colour component of an RGB value + * + * @param string $RGB The colour as an RGB value (e.g. FF00CCCC or CCDDEE + * @param boolean $hex Flag indicating whether the component should be returned as a hex or a + * decimal value + * @return string The green colour component + */ + public static function getGreen($RGB,$hex=TRUE) { + return self::_getColourComponent($RGB, strlen($RGB) - 4, $hex); + } + + /** + * Get the blue colour component of an RGB value + * + * @param string $RGB The colour as an RGB value (e.g. FF00CCCC or CCDDEE + * @param boolean $hex Flag indicating whether the component should be returned as a hex or a + * decimal value + * @return string The blue colour component + */ + public static function getBlue($RGB,$hex=TRUE) { + return self::_getColourComponent($RGB, strlen($RGB) - 2, $hex); + } + + /** + * Adjust the brightness of a color + * + * @param string $hex The colour as an RGBA or RGB value (e.g. FF00CCCC or CCDDEE) + * @param float $adjustPercentage The percentage by which to adjust the colour as a float from -1 to 1 + * @return string The adjusted colour as an RGBA or RGB value (e.g. FF00CCCC or CCDDEE) + */ + public static function changeBrightness($hex, $adjustPercentage) { + $rgba = (strlen($hex) == 8); + + $red = self::getRed($hex, FALSE); + $green = self::getGreen($hex, FALSE); + $blue = self::getBlue($hex, FALSE); + if ($adjustPercentage > 0) { + $red += (255 - $red) * $adjustPercentage; + $green += (255 - $green) * $adjustPercentage; + $blue += (255 - $blue) * $adjustPercentage; + } else { + $red += $red * $adjustPercentage; + $green += $green * $adjustPercentage; + $blue += $blue * $adjustPercentage; + } + + if ($red < 0) $red = 0; + elseif ($red > 255) $red = 255; + if ($green < 0) $green = 0; + elseif ($green > 255) $green = 255; + if ($blue < 0) $blue = 0; + elseif ($blue > 255) $blue = 255; + + $rgb = strtoupper( str_pad(dechex($red), 2, '0', 0) . + str_pad(dechex($green), 2, '0', 0) . + str_pad(dechex($blue), 2, '0', 0) + ); + return (($rgba) ? 'FF' : '') . $rgb; + } + + /** + * Get indexed color + * + * @param int $pIndex Index entry point into the colour array + * @param boolean $background Flag to indicate whether default background or foreground colour + * should be returned if the indexed colour doesn't exist + * @return PHPExcel_Style_Color + */ + public static function indexedColor($pIndex, $background=FALSE) { + // Clean parameter + $pIndex = intval($pIndex); + + // Indexed colors + if (is_null(self::$_indexedColors)) { + self::$_indexedColors = array( + 1 => 'FF000000', // System Colour #1 - Black + 2 => 'FFFFFFFF', // System Colour #2 - White + 3 => 'FFFF0000', // System Colour #3 - Red + 4 => 'FF00FF00', // System Colour #4 - Green + 5 => 'FF0000FF', // System Colour #5 - Blue + 6 => 'FFFFFF00', // System Colour #6 - Yellow + 7 => 'FFFF00FF', // System Colour #7- Magenta + 8 => 'FF00FFFF', // System Colour #8- Cyan + 9 => 'FF800000', // Standard Colour #9 + 10 => 'FF008000', // Standard Colour #10 + 11 => 'FF000080', // Standard Colour #11 + 12 => 'FF808000', // Standard Colour #12 + 13 => 'FF800080', // Standard Colour #13 + 14 => 'FF008080', // Standard Colour #14 + 15 => 'FFC0C0C0', // Standard Colour #15 + 16 => 'FF808080', // Standard Colour #16 + 17 => 'FF9999FF', // Chart Fill Colour #17 + 18 => 'FF993366', // Chart Fill Colour #18 + 19 => 'FFFFFFCC', // Chart Fill Colour #19 + 20 => 'FFCCFFFF', // Chart Fill Colour #20 + 21 => 'FF660066', // Chart Fill Colour #21 + 22 => 'FFFF8080', // Chart Fill Colour #22 + 23 => 'FF0066CC', // Chart Fill Colour #23 + 24 => 'FFCCCCFF', // Chart Fill Colour #24 + 25 => 'FF000080', // Chart Line Colour #25 + 26 => 'FFFF00FF', // Chart Line Colour #26 + 27 => 'FFFFFF00', // Chart Line Colour #27 + 28 => 'FF00FFFF', // Chart Line Colour #28 + 29 => 'FF800080', // Chart Line Colour #29 + 30 => 'FF800000', // Chart Line Colour #30 + 31 => 'FF008080', // Chart Line Colour #31 + 32 => 'FF0000FF', // Chart Line Colour #32 + 33 => 'FF00CCFF', // Standard Colour #33 + 34 => 'FFCCFFFF', // Standard Colour #34 + 35 => 'FFCCFFCC', // Standard Colour #35 + 36 => 'FFFFFF99', // Standard Colour #36 + 37 => 'FF99CCFF', // Standard Colour #37 + 38 => 'FFFF99CC', // Standard Colour #38 + 39 => 'FFCC99FF', // Standard Colour #39 + 40 => 'FFFFCC99', // Standard Colour #40 + 41 => 'FF3366FF', // Standard Colour #41 + 42 => 'FF33CCCC', // Standard Colour #42 + 43 => 'FF99CC00', // Standard Colour #43 + 44 => 'FFFFCC00', // Standard Colour #44 + 45 => 'FFFF9900', // Standard Colour #45 + 46 => 'FFFF6600', // Standard Colour #46 + 47 => 'FF666699', // Standard Colour #47 + 48 => 'FF969696', // Standard Colour #48 + 49 => 'FF003366', // Standard Colour #49 + 50 => 'FF339966', // Standard Colour #50 + 51 => 'FF003300', // Standard Colour #51 + 52 => 'FF333300', // Standard Colour #52 + 53 => 'FF993300', // Standard Colour #53 + 54 => 'FF993366', // Standard Colour #54 + 55 => 'FF333399', // Standard Colour #55 + 56 => 'FF333333' // Standard Colour #56 + ); + } + + if (array_key_exists($pIndex, self::$_indexedColors)) { + return new PHPExcel_Style_Color(self::$_indexedColors[$pIndex]); + } + + if ($background) { + return new PHPExcel_Style_Color('FFFFFFFF'); + } + return new PHPExcel_Style_Color('FF000000'); + } + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getHashCode(); + } + return md5( + $this->_argb + . __CLASS__ + ); + } + +} diff --git a/lib/phpexcel/PHPExcel/Style/Conditional.php b/lib/phpexcel/PHPExcel/Style/Conditional.php new file mode 100644 index 0000000..ffd7a9f --- /dev/null +++ b/lib/phpexcel/PHPExcel/Style/Conditional.php @@ -0,0 +1,277 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Style + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Style_Conditional + * + * @category PHPExcel + * @package PHPExcel_Style + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Style_Conditional implements PHPExcel_IComparable +{ + /* Condition types */ + const CONDITION_NONE = 'none'; + const CONDITION_CELLIS = 'cellIs'; + const CONDITION_CONTAINSTEXT = 'containsText'; + const CONDITION_EXPRESSION = 'expression'; + + /* Operator types */ + const OPERATOR_NONE = ''; + const OPERATOR_BEGINSWITH = 'beginsWith'; + const OPERATOR_ENDSWITH = 'endsWith'; + const OPERATOR_EQUAL = 'equal'; + const OPERATOR_GREATERTHAN = 'greaterThan'; + const OPERATOR_GREATERTHANOREQUAL = 'greaterThanOrEqual'; + const OPERATOR_LESSTHAN = 'lessThan'; + const OPERATOR_LESSTHANOREQUAL = 'lessThanOrEqual'; + const OPERATOR_NOTEQUAL = 'notEqual'; + const OPERATOR_CONTAINSTEXT = 'containsText'; + const OPERATOR_NOTCONTAINS = 'notContains'; + const OPERATOR_BETWEEN = 'between'; + + /** + * Condition type + * + * @var int + */ + private $_conditionType; + + /** + * Operator type + * + * @var int + */ + private $_operatorType; + + /** + * Text + * + * @var string + */ + private $_text; + + /** + * Condition + * + * @var string[] + */ + private $_condition = array(); + + /** + * Style + * + * @var PHPExcel_Style + */ + private $_style; + + /** + * Create a new PHPExcel_Style_Conditional + */ + public function __construct() + { + // Initialise values + $this->_conditionType = PHPExcel_Style_Conditional::CONDITION_NONE; + $this->_operatorType = PHPExcel_Style_Conditional::OPERATOR_NONE; + $this->_text = null; + $this->_condition = array(); + $this->_style = new PHPExcel_Style(FALSE, TRUE); + } + + /** + * Get Condition type + * + * @return string + */ + public function getConditionType() { + return $this->_conditionType; + } + + /** + * Set Condition type + * + * @param string $pValue PHPExcel_Style_Conditional condition type + * @return PHPExcel_Style_Conditional + */ + public function setConditionType($pValue = PHPExcel_Style_Conditional::CONDITION_NONE) { + $this->_conditionType = $pValue; + return $this; + } + + /** + * Get Operator type + * + * @return string + */ + public function getOperatorType() { + return $this->_operatorType; + } + + /** + * Set Operator type + * + * @param string $pValue PHPExcel_Style_Conditional operator type + * @return PHPExcel_Style_Conditional + */ + public function setOperatorType($pValue = PHPExcel_Style_Conditional::OPERATOR_NONE) { + $this->_operatorType = $pValue; + return $this; + } + + /** + * Get text + * + * @return string + */ + public function getText() { + return $this->_text; + } + + /** + * Set text + * + * @param string $value + * @return PHPExcel_Style_Conditional + */ + public function setText($value = null) { + $this->_text = $value; + return $this; + } + + /** + * Get Condition + * + * @deprecated Deprecated, use getConditions instead + * @return string + */ + public function getCondition() { + if (isset($this->_condition[0])) { + return $this->_condition[0]; + } + + return ''; + } + + /** + * Set Condition + * + * @deprecated Deprecated, use setConditions instead + * @param string $pValue Condition + * @return PHPExcel_Style_Conditional + */ + public function setCondition($pValue = '') { + if (!is_array($pValue)) + $pValue = array($pValue); + + return $this->setConditions($pValue); + } + + /** + * Get Conditions + * + * @return string[] + */ + public function getConditions() { + return $this->_condition; + } + + /** + * Set Conditions + * + * @param string[] $pValue Condition + * @return PHPExcel_Style_Conditional + */ + public function setConditions($pValue) { + if (!is_array($pValue)) + $pValue = array($pValue); + + $this->_condition = $pValue; + return $this; + } + + /** + * Add Condition + * + * @param string $pValue Condition + * @return PHPExcel_Style_Conditional + */ + public function addCondition($pValue = '') { + $this->_condition[] = $pValue; + return $this; + } + + /** + * Get Style + * + * @return PHPExcel_Style + */ + public function getStyle() { + return $this->_style; + } + + /** + * Set Style + * + * @param PHPExcel_Style $pValue + * @throws PHPExcel_Exception + * @return PHPExcel_Style_Conditional + */ + public function setStyle(PHPExcel_Style $pValue = null) { + $this->_style = $pValue; + return $this; + } + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() { + return md5( + $this->_conditionType + . $this->_operatorType + . implode(';', $this->_condition) + . $this->_style->getHashCode() + . __CLASS__ + ); + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } +} diff --git a/lib/phpexcel/PHPExcel/Style/Fill.php b/lib/phpexcel/PHPExcel/Style/Fill.php new file mode 100644 index 0000000..1b4d0ad --- /dev/null +++ b/lib/phpexcel/PHPExcel/Style/Fill.php @@ -0,0 +1,321 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Style + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Style_Fill + * + * @category PHPExcel + * @package PHPExcel_Style + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Style_Fill extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable +{ + /* Fill types */ + const FILL_NONE = 'none'; + const FILL_SOLID = 'solid'; + const FILL_GRADIENT_LINEAR = 'linear'; + const FILL_GRADIENT_PATH = 'path'; + const FILL_PATTERN_DARKDOWN = 'darkDown'; + const FILL_PATTERN_DARKGRAY = 'darkGray'; + const FILL_PATTERN_DARKGRID = 'darkGrid'; + const FILL_PATTERN_DARKHORIZONTAL = 'darkHorizontal'; + const FILL_PATTERN_DARKTRELLIS = 'darkTrellis'; + const FILL_PATTERN_DARKUP = 'darkUp'; + const FILL_PATTERN_DARKVERTICAL = 'darkVertical'; + const FILL_PATTERN_GRAY0625 = 'gray0625'; + const FILL_PATTERN_GRAY125 = 'gray125'; + const FILL_PATTERN_LIGHTDOWN = 'lightDown'; + const FILL_PATTERN_LIGHTGRAY = 'lightGray'; + const FILL_PATTERN_LIGHTGRID = 'lightGrid'; + const FILL_PATTERN_LIGHTHORIZONTAL = 'lightHorizontal'; + const FILL_PATTERN_LIGHTTRELLIS = 'lightTrellis'; + const FILL_PATTERN_LIGHTUP = 'lightUp'; + const FILL_PATTERN_LIGHTVERTICAL = 'lightVertical'; + const FILL_PATTERN_MEDIUMGRAY = 'mediumGray'; + + /** + * Fill type + * + * @var string + */ + protected $_fillType = PHPExcel_Style_Fill::FILL_NONE; + + /** + * Rotation + * + * @var double + */ + protected $_rotation = 0; + + /** + * Start color + * + * @var PHPExcel_Style_Color + */ + protected $_startColor; + + /** + * End color + * + * @var PHPExcel_Style_Color + */ + protected $_endColor; + + /** + * Create a new PHPExcel_Style_Fill + * + * @param boolean $isSupervisor Flag indicating if this is a supervisor or not + * Leave this value at default unless you understand exactly what + * its ramifications are + * @param boolean $isConditional Flag indicating if this is a conditional style or not + * Leave this value at default unless you understand exactly what + * its ramifications are + */ + public function __construct($isSupervisor = FALSE, $isConditional = FALSE) + { + // Supervisor? + parent::__construct($isSupervisor); + + // Initialise values + if ($isConditional) { + $this->_fillType = NULL; + } + $this->_startColor = new PHPExcel_Style_Color(PHPExcel_Style_Color::COLOR_WHITE, $isSupervisor, $isConditional); + $this->_endColor = new PHPExcel_Style_Color(PHPExcel_Style_Color::COLOR_BLACK, $isSupervisor, $isConditional); + + // bind parent if we are a supervisor + if ($isSupervisor) { + $this->_startColor->bindParent($this, '_startColor'); + $this->_endColor->bindParent($this, '_endColor'); + } + } + + /** + * Get the shared style component for the currently active cell in currently active sheet. + * Only used for style supervisor + * + * @return PHPExcel_Style_Fill + */ + public function getSharedComponent() + { + return $this->_parent->getSharedComponent()->getFill(); + } + + /** + * Build style array from subcomponents + * + * @param array $array + * @return array + */ + public function getStyleArray($array) + { + return array('fill' => $array); + } + + /** + * Apply styles from array + * + * <code> + * $objPHPExcel->getActiveSheet()->getStyle('B2')->getFill()->applyFromArray( + * array( + * 'type' => PHPExcel_Style_Fill::FILL_GRADIENT_LINEAR, + * 'rotation' => 0, + * 'startcolor' => array( + * 'rgb' => '000000' + * ), + * 'endcolor' => array( + * 'argb' => 'FFFFFFFF' + * ) + * ) + * ); + * </code> + * + * @param array $pStyles Array containing style information + * @throws PHPExcel_Exception + * @return PHPExcel_Style_Fill + */ + public function applyFromArray($pStyles = null) { + if (is_array($pStyles)) { + if ($this->_isSupervisor) { + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles)); + } else { + if (array_key_exists('type', $pStyles)) { + $this->setFillType($pStyles['type']); + } + if (array_key_exists('rotation', $pStyles)) { + $this->setRotation($pStyles['rotation']); + } + if (array_key_exists('startcolor', $pStyles)) { + $this->getStartColor()->applyFromArray($pStyles['startcolor']); + } + if (array_key_exists('endcolor', $pStyles)) { + $this->getEndColor()->applyFromArray($pStyles['endcolor']); + } + if (array_key_exists('color', $pStyles)) { + $this->getStartColor()->applyFromArray($pStyles['color']); + } + } + } else { + throw new PHPExcel_Exception("Invalid style array passed."); + } + return $this; + } + + /** + * Get Fill Type + * + * @return string + */ + public function getFillType() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getFillType(); + } + return $this->_fillType; + } + + /** + * Set Fill Type + * + * @param string $pValue PHPExcel_Style_Fill fill type + * @return PHPExcel_Style_Fill + */ + public function setFillType($pValue = PHPExcel_Style_Fill::FILL_NONE) { + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('type' => $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_fillType = $pValue; + } + return $this; + } + + /** + * Get Rotation + * + * @return double + */ + public function getRotation() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getRotation(); + } + return $this->_rotation; + } + + /** + * Set Rotation + * + * @param double $pValue + * @return PHPExcel_Style_Fill + */ + public function setRotation($pValue = 0) { + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('rotation' => $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_rotation = $pValue; + } + return $this; + } + + /** + * Get Start Color + * + * @return PHPExcel_Style_Color + */ + public function getStartColor() { + return $this->_startColor; + } + + /** + * Set Start Color + * + * @param PHPExcel_Style_Color $pValue + * @throws PHPExcel_Exception + * @return PHPExcel_Style_Fill + */ + public function setStartColor(PHPExcel_Style_Color $pValue = null) { + // make sure parameter is a real color and not a supervisor + $color = $pValue->getIsSupervisor() ? $pValue->getSharedComponent() : $pValue; + + if ($this->_isSupervisor) { + $styleArray = $this->getStartColor()->getStyleArray(array('argb' => $color->getARGB())); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_startColor = $color; + } + return $this; + } + + /** + * Get End Color + * + * @return PHPExcel_Style_Color + */ + public function getEndColor() { + return $this->_endColor; + } + + /** + * Set End Color + * + * @param PHPExcel_Style_Color $pValue + * @throws PHPExcel_Exception + * @return PHPExcel_Style_Fill + */ + public function setEndColor(PHPExcel_Style_Color $pValue = null) { + // make sure parameter is a real color and not a supervisor + $color = $pValue->getIsSupervisor() ? $pValue->getSharedComponent() : $pValue; + + if ($this->_isSupervisor) { + $styleArray = $this->getEndColor()->getStyleArray(array('argb' => $color->getARGB())); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_endColor = $color; + } + return $this; + } + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getHashCode(); + } + return md5( + $this->getFillType() + . $this->getRotation() + . $this->getStartColor()->getHashCode() + . $this->getEndColor()->getHashCode() + . __CLASS__ + ); + } + +} diff --git a/lib/phpexcel/PHPExcel/Style/Font.php b/lib/phpexcel/PHPExcel/Style/Font.php new file mode 100644 index 0000000..e89488c --- /dev/null +++ b/lib/phpexcel/PHPExcel/Style/Font.php @@ -0,0 +1,532 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Style + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Style_Font + * + * @category PHPExcel + * @package PHPExcel_Style + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Style_Font extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable +{ + /* Underline types */ + const UNDERLINE_NONE = 'none'; + const UNDERLINE_DOUBLE = 'double'; + const UNDERLINE_DOUBLEACCOUNTING = 'doubleAccounting'; + const UNDERLINE_SINGLE = 'single'; + const UNDERLINE_SINGLEACCOUNTING = 'singleAccounting'; + + /** + * Font Name + * + * @var string + */ + protected $_name = 'Calibri'; + + /** + * Font Size + * + * @var float + */ + protected $_size = 11; + + /** + * Bold + * + * @var boolean + */ + protected $_bold = FALSE; + + /** + * Italic + * + * @var boolean + */ + protected $_italic = FALSE; + + /** + * Superscript + * + * @var boolean + */ + protected $_superScript = FALSE; + + /** + * Subscript + * + * @var boolean + */ + protected $_subScript = FALSE; + + /** + * Underline + * + * @var string + */ + protected $_underline = self::UNDERLINE_NONE; + + /** + * Strikethrough + * + * @var boolean + */ + protected $_strikethrough = FALSE; + + /** + * Foreground color + * + * @var PHPExcel_Style_Color + */ + protected $_color; + + /** + * Create a new PHPExcel_Style_Font + * + * @param boolean $isSupervisor Flag indicating if this is a supervisor or not + * Leave this value at default unless you understand exactly what + * its ramifications are + * @param boolean $isConditional Flag indicating if this is a conditional style or not + * Leave this value at default unless you understand exactly what + * its ramifications are + */ + public function __construct($isSupervisor = FALSE, $isConditional = FALSE) + { + // Supervisor? + parent::__construct($isSupervisor); + + // Initialise values + if ($isConditional) { + $this->_name = NULL; + $this->_size = NULL; + $this->_bold = NULL; + $this->_italic = NULL; + $this->_superScript = NULL; + $this->_subScript = NULL; + $this->_underline = NULL; + $this->_strikethrough = NULL; + $this->_color = new PHPExcel_Style_Color(PHPExcel_Style_Color::COLOR_BLACK, $isSupervisor, $isConditional); + } else { + $this->_color = new PHPExcel_Style_Color(PHPExcel_Style_Color::COLOR_BLACK, $isSupervisor); + } + // bind parent if we are a supervisor + if ($isSupervisor) { + $this->_color->bindParent($this, '_color'); + } + } + + /** + * Get the shared style component for the currently active cell in currently active sheet. + * Only used for style supervisor + * + * @return PHPExcel_Style_Font + */ + public function getSharedComponent() + { + return $this->_parent->getSharedComponent()->getFont(); + } + + /** + * Build style array from subcomponents + * + * @param array $array + * @return array + */ + public function getStyleArray($array) + { + return array('font' => $array); + } + + /** + * Apply styles from array + * + * <code> + * $objPHPExcel->getActiveSheet()->getStyle('B2')->getFont()->applyFromArray( + * array( + * 'name' => 'Arial', + * 'bold' => TRUE, + * 'italic' => FALSE, + * 'underline' => PHPExcel_Style_Font::UNDERLINE_DOUBLE, + * 'strike' => FALSE, + * 'color' => array( + * 'rgb' => '808080' + * ) + * ) + * ); + * </code> + * + * @param array $pStyles Array containing style information + * @throws PHPExcel_Exception + * @return PHPExcel_Style_Font + */ + public function applyFromArray($pStyles = null) { + if (is_array($pStyles)) { + if ($this->_isSupervisor) { + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles)); + } else { + if (array_key_exists('name', $pStyles)) { + $this->setName($pStyles['name']); + } + if (array_key_exists('bold', $pStyles)) { + $this->setBold($pStyles['bold']); + } + if (array_key_exists('italic', $pStyles)) { + $this->setItalic($pStyles['italic']); + } + if (array_key_exists('superScript', $pStyles)) { + $this->setSuperScript($pStyles['superScript']); + } + if (array_key_exists('subScript', $pStyles)) { + $this->setSubScript($pStyles['subScript']); + } + if (array_key_exists('underline', $pStyles)) { + $this->setUnderline($pStyles['underline']); + } + if (array_key_exists('strike', $pStyles)) { + $this->setStrikethrough($pStyles['strike']); + } + if (array_key_exists('color', $pStyles)) { + $this->getColor()->applyFromArray($pStyles['color']); + } + if (array_key_exists('size', $pStyles)) { + $this->setSize($pStyles['size']); + } + } + } else { + throw new PHPExcel_Exception("Invalid style array passed."); + } + return $this; + } + + /** + * Get Name + * + * @return string + */ + public function getName() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getName(); + } + return $this->_name; + } + + /** + * Set Name + * + * @param string $pValue + * @return PHPExcel_Style_Font + */ + public function setName($pValue = 'Calibri') { + if ($pValue == '') { + $pValue = 'Calibri'; + } + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('name' => $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_name = $pValue; + } + return $this; + } + + /** + * Get Size + * + * @return double + */ + public function getSize() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getSize(); + } + return $this->_size; + } + + /** + * Set Size + * + * @param double $pValue + * @return PHPExcel_Style_Font + */ + public function setSize($pValue = 10) { + if ($pValue == '') { + $pValue = 10; + } + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('size' => $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_size = $pValue; + } + return $this; + } + + /** + * Get Bold + * + * @return boolean + */ + public function getBold() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getBold(); + } + return $this->_bold; + } + + /** + * Set Bold + * + * @param boolean $pValue + * @return PHPExcel_Style_Font + */ + public function setBold($pValue = false) { + if ($pValue == '') { + $pValue = false; + } + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('bold' => $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_bold = $pValue; + } + return $this; + } + + /** + * Get Italic + * + * @return boolean + */ + public function getItalic() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getItalic(); + } + return $this->_italic; + } + + /** + * Set Italic + * + * @param boolean $pValue + * @return PHPExcel_Style_Font + */ + public function setItalic($pValue = false) { + if ($pValue == '') { + $pValue = false; + } + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('italic' => $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_italic = $pValue; + } + return $this; + } + + /** + * Get SuperScript + * + * @return boolean + */ + public function getSuperScript() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getSuperScript(); + } + return $this->_superScript; + } + + /** + * Set SuperScript + * + * @param boolean $pValue + * @return PHPExcel_Style_Font + */ + public function setSuperScript($pValue = false) { + if ($pValue == '') { + $pValue = false; + } + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('superScript' => $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_superScript = $pValue; + $this->_subScript = !$pValue; + } + return $this; + } + + /** + * Get SubScript + * + * @return boolean + */ + public function getSubScript() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getSubScript(); + } + return $this->_subScript; + } + + /** + * Set SubScript + * + * @param boolean $pValue + * @return PHPExcel_Style_Font + */ + public function setSubScript($pValue = false) { + if ($pValue == '') { + $pValue = false; + } + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('subScript' => $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_subScript = $pValue; + $this->_superScript = !$pValue; + } + return $this; + } + + /** + * Get Underline + * + * @return string + */ + public function getUnderline() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getUnderline(); + } + return $this->_underline; + } + + /** + * Set Underline + * + * @param string|boolean $pValue PHPExcel_Style_Font underline type + * If a boolean is passed, then TRUE equates to UNDERLINE_SINGLE, + * false equates to UNDERLINE_NONE + * @return PHPExcel_Style_Font + */ + public function setUnderline($pValue = self::UNDERLINE_NONE) { + if (is_bool($pValue)) { + $pValue = ($pValue) ? self::UNDERLINE_SINGLE : self::UNDERLINE_NONE; + } elseif ($pValue == '') { + $pValue = self::UNDERLINE_NONE; + } + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('underline' => $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_underline = $pValue; + } + return $this; + } + + /** + * Get Strikethrough + * + * @return boolean + */ + public function getStrikethrough() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getStrikethrough(); + } + return $this->_strikethrough; + } + + /** + * Set Strikethrough + * + * @param boolean $pValue + * @return PHPExcel_Style_Font + */ + public function setStrikethrough($pValue = false) { + if ($pValue == '') { + $pValue = false; + } + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('strike' => $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_strikethrough = $pValue; + } + return $this; + } + + /** + * Get Color + * + * @return PHPExcel_Style_Color + */ + public function getColor() { + return $this->_color; + } + + /** + * Set Color + * + * @param PHPExcel_Style_Color $pValue + * @throws PHPExcel_Exception + * @return PHPExcel_Style_Font + */ + public function setColor(PHPExcel_Style_Color $pValue = null) { + // make sure parameter is a real color and not a supervisor + $color = $pValue->getIsSupervisor() ? $pValue->getSharedComponent() : $pValue; + + if ($this->_isSupervisor) { + $styleArray = $this->getColor()->getStyleArray(array('argb' => $color->getARGB())); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_color = $color; + } + return $this; + } + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getHashCode(); + } + return md5( + $this->_name + . $this->_size + . ($this->_bold ? 't' : 'f') + . ($this->_italic ? 't' : 'f') + . ($this->_superScript ? 't' : 'f') + . ($this->_subScript ? 't' : 'f') + . $this->_underline + . ($this->_strikethrough ? 't' : 'f') + . $this->_color->getHashCode() + . __CLASS__ + ); + } + +} diff --git a/lib/phpexcel/PHPExcel/Style/NumberFormat.php b/lib/phpexcel/PHPExcel/Style/NumberFormat.php new file mode 100644 index 0000000..e8a978f --- /dev/null +++ b/lib/phpexcel/PHPExcel/Style/NumberFormat.php @@ -0,0 +1,711 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Style + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Style_NumberFormat + * + * @category PHPExcel + * @package PHPExcel_Style + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Style_NumberFormat extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable +{ + /* Pre-defined formats */ + const FORMAT_GENERAL = 'General'; + + const FORMAT_TEXT = '@'; + + const FORMAT_NUMBER = '0'; + const FORMAT_NUMBER_00 = '0.00'; + const FORMAT_NUMBER_COMMA_SEPARATED1 = '#,##0.00'; + const FORMAT_NUMBER_COMMA_SEPARATED2 = '#,##0.00_-'; + + const FORMAT_PERCENTAGE = '0%'; + const FORMAT_PERCENTAGE_00 = '0.00%'; + + const FORMAT_DATE_YYYYMMDD2 = 'yyyy-mm-dd'; + const FORMAT_DATE_YYYYMMDD = 'yy-mm-dd'; + const FORMAT_DATE_DDMMYYYY = 'dd/mm/yy'; + const FORMAT_DATE_DMYSLASH = 'd/m/y'; + const FORMAT_DATE_DMYMINUS = 'd-m-y'; + const FORMAT_DATE_DMMINUS = 'd-m'; + const FORMAT_DATE_MYMINUS = 'm-y'; + const FORMAT_DATE_XLSX14 = 'mm-dd-yy'; + const FORMAT_DATE_XLSX15 = 'd-mmm-yy'; + const FORMAT_DATE_XLSX16 = 'd-mmm'; + const FORMAT_DATE_XLSX17 = 'mmm-yy'; + const FORMAT_DATE_XLSX22 = 'm/d/yy h:mm'; + const FORMAT_DATE_DATETIME = 'd/m/y h:mm'; + const FORMAT_DATE_TIME1 = 'h:mm AM/PM'; + const FORMAT_DATE_TIME2 = 'h:mm:ss AM/PM'; + const FORMAT_DATE_TIME3 = 'h:mm'; + const FORMAT_DATE_TIME4 = 'h:mm:ss'; + const FORMAT_DATE_TIME5 = 'mm:ss'; + const FORMAT_DATE_TIME6 = 'h:mm:ss'; + const FORMAT_DATE_TIME7 = 'i:s.S'; + const FORMAT_DATE_TIME8 = 'h:mm:ss;@'; + const FORMAT_DATE_YYYYMMDDSLASH = 'yy/mm/dd;@'; + + const FORMAT_CURRENCY_USD_SIMPLE = '"$"#,##0.00_-'; + const FORMAT_CURRENCY_USD = '$#,##0_-'; + const FORMAT_CURRENCY_EUR_SIMPLE = '[$EUR ]#,##0.00_-'; + + /** + * Excel built-in number formats + * + * @var array + */ + protected static $_builtInFormats; + + /** + * Excel built-in number formats (flipped, for faster lookups) + * + * @var array + */ + protected static $_flippedBuiltInFormats; + + /** + * Format Code + * + * @var string + */ + protected $_formatCode = PHPExcel_Style_NumberFormat::FORMAT_GENERAL; + + /** + * Built-in format Code + * + * @var string + */ + protected $_builtInFormatCode = 0; + + /** + * Create a new PHPExcel_Style_NumberFormat + * + * @param boolean $isSupervisor Flag indicating if this is a supervisor or not + * Leave this value at default unless you understand exactly what + * its ramifications are + * @param boolean $isConditional Flag indicating if this is a conditional style or not + * Leave this value at default unless you understand exactly what + * its ramifications are + */ + public function __construct($isSupervisor = FALSE, $isConditional = FALSE) + { + // Supervisor? + parent::__construct($isSupervisor); + + if ($isConditional) { + $this->_formatCode = NULL; + } + } + + /** + * Get the shared style component for the currently active cell in currently active sheet. + * Only used for style supervisor + * + * @return PHPExcel_Style_NumberFormat + */ + public function getSharedComponent() + { + return $this->_parent->getSharedComponent()->getNumberFormat(); + } + + /** + * Build style array from subcomponents + * + * @param array $array + * @return array + */ + public function getStyleArray($array) + { + return array('numberformat' => $array); + } + + /** + * Apply styles from array + * + * <code> + * $objPHPExcel->getActiveSheet()->getStyle('B2')->getNumberFormat()->applyFromArray( + * array( + * 'code' => PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_EUR_SIMPLE + * ) + * ); + * </code> + * + * @param array $pStyles Array containing style information + * @throws PHPExcel_Exception + * @return PHPExcel_Style_NumberFormat + */ + public function applyFromArray($pStyles = null) + { + if (is_array($pStyles)) { + if ($this->_isSupervisor) { + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles)); + } else { + if (array_key_exists('code', $pStyles)) { + $this->setFormatCode($pStyles['code']); + } + } + } else { + throw new PHPExcel_Exception("Invalid style array passed."); + } + return $this; + } + + /** + * Get Format Code + * + * @return string + */ + public function getFormatCode() + { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getFormatCode(); + } + if ($this->_builtInFormatCode !== false) + { + return self::builtInFormatCode($this->_builtInFormatCode); + } + return $this->_formatCode; + } + + /** + * Set Format Code + * + * @param string $pValue + * @return PHPExcel_Style_NumberFormat + */ + public function setFormatCode($pValue = PHPExcel_Style_NumberFormat::FORMAT_GENERAL) + { + if ($pValue == '') { + $pValue = PHPExcel_Style_NumberFormat::FORMAT_GENERAL; + } + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('code' => $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_formatCode = $pValue; + $this->_builtInFormatCode = self::builtInFormatCodeIndex($pValue); + } + return $this; + } + + /** + * Get Built-In Format Code + * + * @return int + */ + public function getBuiltInFormatCode() + { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getBuiltInFormatCode(); + } + return $this->_builtInFormatCode; + } + + /** + * Set Built-In Format Code + * + * @param int $pValue + * @return PHPExcel_Style_NumberFormat + */ + public function setBuiltInFormatCode($pValue = 0) + { + + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('code' => self::builtInFormatCode($pValue))); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_builtInFormatCode = $pValue; + $this->_formatCode = self::builtInFormatCode($pValue); + } + return $this; + } + + /** + * Fill built-in format codes + */ + private static function fillBuiltInFormatCodes() + { + // Built-in format codes + if (is_null(self::$_builtInFormats)) { + self::$_builtInFormats = array(); + + // General + self::$_builtInFormats[0] = PHPExcel_Style_NumberFormat::FORMAT_GENERAL; + self::$_builtInFormats[1] = '0'; + self::$_builtInFormats[2] = '0.00'; + self::$_builtInFormats[3] = '#,##0'; + self::$_builtInFormats[4] = '#,##0.00'; + + self::$_builtInFormats[9] = '0%'; + self::$_builtInFormats[10] = '0.00%'; + self::$_builtInFormats[11] = '0.00E+00'; + self::$_builtInFormats[12] = '# ?/?'; + self::$_builtInFormats[13] = '# ??/??'; + self::$_builtInFormats[14] = 'mm-dd-yy'; + self::$_builtInFormats[15] = 'd-mmm-yy'; + self::$_builtInFormats[16] = 'd-mmm'; + self::$_builtInFormats[17] = 'mmm-yy'; + self::$_builtInFormats[18] = 'h:mm AM/PM'; + self::$_builtInFormats[19] = 'h:mm:ss AM/PM'; + self::$_builtInFormats[20] = 'h:mm'; + self::$_builtInFormats[21] = 'h:mm:ss'; + self::$_builtInFormats[22] = 'm/d/yy h:mm'; + + self::$_builtInFormats[37] = '#,##0 ;(#,##0)'; + self::$_builtInFormats[38] = '#,##0 ;[Red](#,##0)'; + self::$_builtInFormats[39] = '#,##0.00;(#,##0.00)'; + self::$_builtInFormats[40] = '#,##0.00;[Red](#,##0.00)'; + + self::$_builtInFormats[44] = '_("$"* #,##0.00_);_("$"* \(#,##0.00\);_("$"* "-"??_);_(@_)'; + self::$_builtInFormats[45] = 'mm:ss'; + self::$_builtInFormats[46] = '[h]:mm:ss'; + self::$_builtInFormats[47] = 'mmss.0'; + self::$_builtInFormats[48] = '##0.0E+0'; + self::$_builtInFormats[49] = '@'; + + // CHT + self::$_builtInFormats[27] = '[$-404]e/m/d'; + self::$_builtInFormats[30] = 'm/d/yy'; + self::$_builtInFormats[36] = '[$-404]e/m/d'; + self::$_builtInFormats[50] = '[$-404]e/m/d'; + self::$_builtInFormats[57] = '[$-404]e/m/d'; + + // THA + self::$_builtInFormats[59] = 't0'; + self::$_builtInFormats[60] = 't0.00'; + self::$_builtInFormats[61] = 't#,##0'; + self::$_builtInFormats[62] = 't#,##0.00'; + self::$_builtInFormats[67] = 't0%'; + self::$_builtInFormats[68] = 't0.00%'; + self::$_builtInFormats[69] = 't# ?/?'; + self::$_builtInFormats[70] = 't# ??/??'; + + // Flip array (for faster lookups) + self::$_flippedBuiltInFormats = array_flip(self::$_builtInFormats); + } + } + + /** + * Get built-in format code + * + * @param int $pIndex + * @return string + */ + public static function builtInFormatCode($pIndex) + { + // Clean parameter + $pIndex = intval($pIndex); + + // Ensure built-in format codes are available + self::fillBuiltInFormatCodes(); + + // Lookup format code + if (isset(self::$_builtInFormats[$pIndex])) { + return self::$_builtInFormats[$pIndex]; + } + + return ''; + } + + /** + * Get built-in format code index + * + * @param string $formatCode + * @return int|boolean + */ + public static function builtInFormatCodeIndex($formatCode) + { + // Ensure built-in format codes are available + self::fillBuiltInFormatCodes(); + + // Lookup format code + if (isset(self::$_flippedBuiltInFormats[$formatCode])) { + return self::$_flippedBuiltInFormats[$formatCode]; + } + + return false; + } + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() + { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getHashCode(); + } + return md5( + $this->_formatCode + . $this->_builtInFormatCode + . __CLASS__ + ); + } + + /** + * Search/replace values to convert Excel date/time format masks to PHP format masks + * + * @var array + */ + private static $_dateFormatReplacements = array( + // first remove escapes related to non-format characters + '\\' => '', + // 12-hour suffix + 'am/pm' => 'A', + // 4-digit year + 'e' => 'Y', + 'yyyy' => 'Y', + // 2-digit year + 'yy' => 'y', + // first letter of month - no php equivalent + 'mmmmm' => 'M', + // full month name + 'mmmm' => 'F', + // short month name + 'mmm' => 'M', + // mm is minutes if time, but can also be month w/leading zero + // so we try to identify times be the inclusion of a : separator in the mask + // It isn't perfect, but the best way I know how + ':mm' => ':i', + 'mm:' => 'i:', + // month leading zero + 'mm' => 'm', + // month no leading zero + 'm' => 'n', + // full day of week name + 'dddd' => 'l', + // short day of week name + 'ddd' => 'D', + // days leading zero + 'dd' => 'd', + // days no leading zero + 'd' => 'j', + // seconds + 'ss' => 's', + // fractional seconds - no php equivalent + '.s' => '' + ); + /** + * Search/replace values to convert Excel date/time format masks hours to PHP format masks (24 hr clock) + * + * @var array + */ + private static $_dateFormatReplacements24 = array( + 'hh' => 'H', + 'h' => 'G' + ); + /** + * Search/replace values to convert Excel date/time format masks hours to PHP format masks (12 hr clock) + * + * @var array + */ + private static $_dateFormatReplacements12 = array( + 'hh' => 'h', + 'h' => 'g' + ); + + private static function _formatAsDate(&$value, &$format) + { + // dvc: convert Excel formats to PHP date formats + + // strip off first part containing e.g. [$-F800] or [$USD-409] + // general syntax: [$<Currency string>-<language info>] + // language info is in hexadecimal + $format = preg_replace('/^(\[\$[A-Z]*-[0-9A-F]*\])/i', '', $format); + + // OpenOffice.org uses upper-case number formats, e.g. 'YYYY', convert to lower-case + $format = strtolower($format); + + $format = strtr($format,self::$_dateFormatReplacements); + if (!strpos($format,'A')) { // 24-hour time format + $format = strtr($format,self::$_dateFormatReplacements24); + } else { // 12-hour time format + $format = strtr($format,self::$_dateFormatReplacements12); + } + + $dateObj = PHPExcel_Shared_Date::ExcelToPHPObject($value); + $value = $dateObj->format($format); + } + + private static function _formatAsPercentage(&$value, &$format) + { + if ($format === self::FORMAT_PERCENTAGE) { + $value = round( (100 * $value), 0) . '%'; + } else { + if (preg_match('/\.[#0]+/i', $format, $m)) { + $s = substr($m[0], 0, 1) . (strlen($m[0]) - 1); + $format = str_replace($m[0], $s, $format); + } + if (preg_match('/^[#0]+/', $format, $m)) { + $format = str_replace($m[0], strlen($m[0]), $format); + } + $format = '%' . str_replace('%', 'f%%', $format); + + $value = sprintf($format, 100 * $value); + } + } + + private static function _formatAsFraction(&$value, &$format) + { + $sign = ($value < 0) ? '-' : ''; + + $integerPart = floor(abs($value)); + $decimalPart = trim(fmod(abs($value),1),'0.'); + $decimalLength = strlen($decimalPart); + $decimalDivisor = pow(10,$decimalLength); + + $GCD = PHPExcel_Calculation_MathTrig::GCD($decimalPart,$decimalDivisor); + + $adjustedDecimalPart = $decimalPart/$GCD; + $adjustedDecimalDivisor = $decimalDivisor/$GCD; + + if ((strpos($format,'0') !== false) || (strpos($format,'#') !== false) || (substr($format,0,3) == '? ?')) { + if ($integerPart == 0) { + $integerPart = ''; + } + $value = "$sign$integerPart $adjustedDecimalPart/$adjustedDecimalDivisor"; + } else { + $adjustedDecimalPart += $integerPart * $adjustedDecimalDivisor; + $value = "$sign$adjustedDecimalPart/$adjustedDecimalDivisor"; + } + } + + private static function _complexNumberFormatMask($number, $mask) { + if (strpos($mask,'.') !== false) { + $numbers = explode('.', $number . '.0'); + $masks = explode('.', $mask . '.0'); + $result1 = self::_complexNumberFormatMask($numbers[0], $masks[0]); + $result2 = strrev(self::_complexNumberFormatMask(strrev($numbers[1]), strrev($masks[1]))); + return $result1 . '.' . $result2; + } + + $r = preg_match_all('/0+/', $mask, $result, PREG_OFFSET_CAPTURE); + if ($r > 1) { + $result = array_reverse($result[0]); + + foreach($result as $block) { + $divisor = 1 . $block[0]; + $size = strlen($block[0]); + $offset = $block[1]; + + $blockValue = sprintf( + '%0' . $size . 'd', + fmod($number, $divisor) + ); + $number = floor($number / $divisor); + $mask = substr_replace($mask,$blockValue, $offset, $size); + } + if ($number > 0) { + $mask = substr_replace($mask, $number, $offset, 0); + } + $result = $mask; + } else { + $result = $number; + } + + return $result; + } + + /** + * Convert a value in a pre-defined format to a PHP string + * + * @param mixed $value Value to format + * @param string $format Format code + * @param array $callBack Callback function for additional formatting of string + * @return string Formatted string + */ + public static function toFormattedString($value = '0', $format = PHPExcel_Style_NumberFormat::FORMAT_GENERAL, $callBack = null) + { + // For now we do not treat strings although section 4 of a format code affects strings + if (!is_numeric($value)) return $value; + + // For 'General' format code, we just pass the value although this is not entirely the way Excel does it, + // it seems to round numbers to a total of 10 digits. + if (($format === PHPExcel_Style_NumberFormat::FORMAT_GENERAL) || ($format === PHPExcel_Style_NumberFormat::FORMAT_TEXT)) { + return $value; + } + + // Get the sections, there can be up to four sections + $sections = explode(';', $format); + + // Fetch the relevant section depending on whether number is positive, negative, or zero? + // Text not supported yet. + // Here is how the sections apply to various values in Excel: + // 1 section: [POSITIVE/NEGATIVE/ZERO/TEXT] + // 2 sections: [POSITIVE/ZERO/TEXT] [NEGATIVE] + // 3 sections: [POSITIVE/TEXT] [NEGATIVE] [ZERO] + // 4 sections: [POSITIVE] [NEGATIVE] [ZERO] [TEXT] + switch (count($sections)) { + case 1: + $format = $sections[0]; + break; + + case 2: + $format = ($value >= 0) ? $sections[0] : $sections[1]; + $value = abs($value); // Use the absolute value + break; + + case 3: + $format = ($value > 0) ? + $sections[0] : ( ($value < 0) ? + $sections[1] : $sections[2]); + $value = abs($value); // Use the absolute value + break; + + case 4: + $format = ($value > 0) ? + $sections[0] : ( ($value < 0) ? + $sections[1] : $sections[2]); + $value = abs($value); // Use the absolute value + break; + + default: + // something is wrong, just use first section + $format = $sections[0]; + break; + } + + // Save format with color information for later use below + $formatColor = $format; + + // Strip color information + $color_regex = '/^\\[[a-zA-Z]+\\]/'; + $format = preg_replace($color_regex, '', $format); + + // Let's begin inspecting the format and converting the value to a formatted string + if (preg_match('/^(\[\$[A-Z]*-[0-9A-F]*\])*[hmsdy]/i', $format)) { // datetime format + self::_formatAsDate($value, $format); + } else if (preg_match('/%$/', $format)) { // % number format + self::_formatAsPercentage($value, $format); + } else { + if ($format === self::FORMAT_CURRENCY_EUR_SIMPLE) { + $value = 'EUR ' . sprintf('%1.2f', $value); + } else { + // In Excel formats, "_" is used to add spacing, which we can't do in HTML + $format = preg_replace('/_./', '', $format); + + // Some non-number characters are escaped with \, which we don't need + $format = preg_replace("/\\\\/", '', $format); + + // Some non-number strings are quoted, so we'll get rid of the quotes, likewise any positional * symbols + $format = str_replace(array('"','*'), '', $format); + + // Find out if we need thousands separator + // This is indicated by a comma enclosed by a digit placeholder: + // #,# or 0,0 + $useThousands = preg_match('/(#,#|0,0)/', $format); + if ($useThousands) { + $format = preg_replace('/0,0/', '00', $format); + $format = preg_replace('/#,#/', '##', $format); + } + + // Scale thousands, millions,... + // This is indicated by a number of commas after a digit placeholder: + // #, or 0.0,, + $scale = 1; // same as no scale + $matches = array(); + if (preg_match('/(#|0)(,+)/', $format, $matches)) { + $scale = pow(1000, strlen($matches[2])); + + // strip the commas + $format = preg_replace('/0,+/', '0', $format); + $format = preg_replace('/#,+/', '#', $format); + } + + if (preg_match('/#?.*\?\/\?/', $format, $m)) { + //echo 'Format mask is fractional '.$format.' <br />'; + if ($value != (int)$value) { + self::_formatAsFraction($value, $format); + } + + } else { + // Handle the number itself + + // scale number + $value = $value / $scale; + + // Strip # + $format = preg_replace('/\\#/', '0', $format); + + $n = "/\[[^\]]+\]/"; + $m = preg_replace($n, '', $format); + $number_regex = "/(0+)(\.?)(0*)/"; + if (preg_match($number_regex, $m, $matches)) { + $left = $matches[1]; + $dec = $matches[2]; + $right = $matches[3]; + + // minimun width of formatted number (including dot) + $minWidth = strlen($left) + strlen($dec) + strlen($right); + if ($useThousands) { + $value = number_format( + $value + , strlen($right) + , PHPExcel_Shared_String::getDecimalSeparator() + , PHPExcel_Shared_String::getThousandsSeparator() + ); + $value = preg_replace($number_regex, $value, $format); + } else { + if (preg_match('/[0#]E[+-]0/i', $format)) { + // Scientific format + $value = sprintf('%5.2E', $value); + } elseif (preg_match('/0([^\d\.]+)0/', $format)) { + $value = self::_complexNumberFormatMask($value, $format); + } else { + $sprintf_pattern = "%0$minWidth." . strlen($right) . "f"; + $value = sprintf($sprintf_pattern, $value); + $value = preg_replace($number_regex, $value, $format); + } + } + } + } + if (preg_match('/\[\$(.*)\]/u', $format, $m)) { + // Currency or Accounting + $currencyFormat = $m[0]; + $currencyCode = $m[1]; + list($currencyCode) = explode('-',$currencyCode); + if ($currencyCode == '') { + $currencyCode = PHPExcel_Shared_String::getCurrencyCode(); + } + $value = preg_replace('/\[\$([^\]]*)\]/u',$currencyCode,$value); + } + } + } + + // Additional formatting provided by callback function + if ($callBack !== null) { + list($writerInstance, $function) = $callBack; + $value = $writerInstance->$function($value, $formatColor); + } + + return $value; + } + +} diff --git a/lib/phpexcel/PHPExcel/Style/Protection.php b/lib/phpexcel/PHPExcel/Style/Protection.php new file mode 100644 index 0000000..8dc1f31 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Style/Protection.php @@ -0,0 +1,207 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Style + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.4.5, 2007-08-23 + */ + + +/** + * PHPExcel_Style_Protection + * + * @category PHPExcel + * @package PHPExcel_Style + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Style_Protection extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable +{ + /** Protection styles */ + const PROTECTION_INHERIT = 'inherit'; + const PROTECTION_PROTECTED = 'protected'; + const PROTECTION_UNPROTECTED = 'unprotected'; + + /** + * Locked + * + * @var string + */ + protected $_locked; + + /** + * Hidden + * + * @var string + */ + protected $_hidden; + + /** + * Create a new PHPExcel_Style_Protection + * + * @param boolean $isSupervisor Flag indicating if this is a supervisor or not + * Leave this value at default unless you understand exactly what + * its ramifications are + * @param boolean $isConditional Flag indicating if this is a conditional style or not + * Leave this value at default unless you understand exactly what + * its ramifications are + */ + public function __construct($isSupervisor = FALSE, $isConditional = FALSE) + { + // Supervisor? + parent::__construct($isSupervisor); + + // Initialise values + if (!$isConditional) { + $this->_locked = self::PROTECTION_INHERIT; + $this->_hidden = self::PROTECTION_INHERIT; + } + } + + /** + * Get the shared style component for the currently active cell in currently active sheet. + * Only used for style supervisor + * + * @return PHPExcel_Style_Protection + */ + public function getSharedComponent() + { + return $this->_parent->getSharedComponent()->getProtection(); + } + + /** + * Build style array from subcomponents + * + * @param array $array + * @return array + */ + public function getStyleArray($array) + { + return array('protection' => $array); + } + + /** + * Apply styles from array + * + * <code> + * $objPHPExcel->getActiveSheet()->getStyle('B2')->getLocked()->applyFromArray( + * array( + * 'locked' => TRUE, + * 'hidden' => FALSE + * ) + * ); + * </code> + * + * @param array $pStyles Array containing style information + * @throws PHPExcel_Exception + * @return PHPExcel_Style_Protection + */ + public function applyFromArray($pStyles = NULL) { + if (is_array($pStyles)) { + if ($this->_isSupervisor) { + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles)); + } else { + if (isset($pStyles['locked'])) { + $this->setLocked($pStyles['locked']); + } + if (isset($pStyles['hidden'])) { + $this->setHidden($pStyles['hidden']); + } + } + } else { + throw new PHPExcel_Exception("Invalid style array passed."); + } + return $this; + } + + /** + * Get locked + * + * @return string + */ + public function getLocked() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getLocked(); + } + return $this->_locked; + } + + /** + * Set locked + * + * @param string $pValue + * @return PHPExcel_Style_Protection + */ + public function setLocked($pValue = self::PROTECTION_INHERIT) { + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('locked' => $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_locked = $pValue; + } + return $this; + } + + /** + * Get hidden + * + * @return string + */ + public function getHidden() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getHidden(); + } + return $this->_hidden; + } + + /** + * Set hidden + * + * @param string $pValue + * @return PHPExcel_Style_Protection + */ + public function setHidden($pValue = self::PROTECTION_INHERIT) { + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('hidden' => $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_hidden = $pValue; + } + return $this; + } + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getHashCode(); + } + return md5( + $this->_locked + . $this->_hidden + . __CLASS__ + ); + } + +} diff --git a/lib/phpexcel/PHPExcel/Style/Supervisor.php b/lib/phpexcel/PHPExcel/Style/Supervisor.php new file mode 100644 index 0000000..c2ce9c0 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Style/Supervisor.php @@ -0,0 +1,132 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Style + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Style_Supervisor + * + * @category PHPExcel + * @package PHPExcel_Style + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +abstract class PHPExcel_Style_Supervisor +{ + /** + * Supervisor? + * + * @var boolean + */ + protected $_isSupervisor; + + /** + * Parent. Only used for supervisor + * + * @var PHPExcel_Style + */ + protected $_parent; + + /** + * Create a new PHPExcel_Style_Alignment + * + * @param boolean $isSupervisor Flag indicating if this is a supervisor or not + * Leave this value at default unless you understand exactly what + * its ramifications are + */ + public function __construct($isSupervisor = FALSE) + { + // Supervisor? + $this->_isSupervisor = $isSupervisor; + } + + /** + * Bind parent. Only used for supervisor + * + * @param PHPExcel $parent + * @return PHPExcel_Style_Supervisor + */ + public function bindParent($parent, $parentPropertyName=NULL) + { + $this->_parent = $parent; + return $this; + } + + /** + * Is this a supervisor or a cell style component? + * + * @return boolean + */ + public function getIsSupervisor() + { + return $this->_isSupervisor; + } + + /** + * Get the currently active sheet. Only used for supervisor + * + * @return PHPExcel_Worksheet + */ + public function getActiveSheet() + { + return $this->_parent->getActiveSheet(); + } + + /** + * Get the currently active cell coordinate in currently active sheet. + * Only used for supervisor + * + * @return string E.g. 'A1' + */ + public function getSelectedCells() + { + return $this->getActiveSheet()->getSelectedCells(); + } + + /** + * Get the currently active cell coordinate in currently active sheet. + * Only used for supervisor + * + * @return string E.g. 'A1' + */ + public function getActiveCell() + { + return $this->getActiveSheet()->getActiveCell(); + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if ((is_object($value)) && ($key != '_parent')) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } +} diff --git a/lib/phpexcel/PHPExcel/Worksheet.php b/lib/phpexcel/PHPExcel/Worksheet.php new file mode 100644 index 0000000..682ad98 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Worksheet.php @@ -0,0 +1,2909 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Worksheet + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Worksheet implements PHPExcel_IComparable +{ + /* Break types */ + const BREAK_NONE = 0; + const BREAK_ROW = 1; + const BREAK_COLUMN = 2; + + /* Sheet state */ + const SHEETSTATE_VISIBLE = 'visible'; + const SHEETSTATE_HIDDEN = 'hidden'; + const SHEETSTATE_VERYHIDDEN = 'veryHidden'; + + /** + * Invalid characters in sheet title + * + * @var array + */ + private static $_invalidCharacters = array('*', ':', '/', '\\', '?', '[', ']'); + + /** + * Parent spreadsheet + * + * @var PHPExcel + */ + private $_parent; + + /** + * Cacheable collection of cells + * + * @var PHPExcel_CachedObjectStorage_xxx + */ + private $_cellCollection = null; + + /** + * Collection of row dimensions + * + * @var PHPExcel_Worksheet_RowDimension[] + */ + private $_rowDimensions = array(); + + /** + * Default row dimension + * + * @var PHPExcel_Worksheet_RowDimension + */ + private $_defaultRowDimension = null; + + /** + * Collection of column dimensions + * + * @var PHPExcel_Worksheet_ColumnDimension[] + */ + private $_columnDimensions = array(); + + /** + * Default column dimension + * + * @var PHPExcel_Worksheet_ColumnDimension + */ + private $_defaultColumnDimension = null; + + /** + * Collection of drawings + * + * @var PHPExcel_Worksheet_BaseDrawing[] + */ + private $_drawingCollection = null; + + /** + * Collection of Chart objects + * + * @var PHPExcel_Chart[] + */ + private $_chartCollection = array(); + + /** + * Worksheet title + * + * @var string + */ + private $_title; + + /** + * Sheet state + * + * @var string + */ + private $_sheetState; + + /** + * Page setup + * + * @var PHPExcel_Worksheet_PageSetup + */ + private $_pageSetup; + + /** + * Page margins + * + * @var PHPExcel_Worksheet_PageMargins + */ + private $_pageMargins; + + /** + * Page header/footer + * + * @var PHPExcel_Worksheet_HeaderFooter + */ + private $_headerFooter; + + /** + * Sheet view + * + * @var PHPExcel_Worksheet_SheetView + */ + private $_sheetView; + + /** + * Protection + * + * @var PHPExcel_Worksheet_Protection + */ + private $_protection; + + /** + * Collection of styles + * + * @var PHPExcel_Style[] + */ + private $_styles = array(); + + /** + * Conditional styles. Indexed by cell coordinate, e.g. 'A1' + * + * @var array + */ + private $_conditionalStylesCollection = array(); + + /** + * Is the current cell collection sorted already? + * + * @var boolean + */ + private $_cellCollectionIsSorted = false; + + /** + * Collection of breaks + * + * @var array + */ + private $_breaks = array(); + + /** + * Collection of merged cell ranges + * + * @var array + */ + private $_mergeCells = array(); + + /** + * Collection of protected cell ranges + * + * @var array + */ + private $_protectedCells = array(); + + /** + * Autofilter Range and selection + * + * @var PHPExcel_Worksheet_AutoFilter + */ + private $_autoFilter = NULL; + + /** + * Freeze pane + * + * @var string + */ + private $_freezePane = ''; + + /** + * Show gridlines? + * + * @var boolean + */ + private $_showGridlines = true; + + /** + * Print gridlines? + * + * @var boolean + */ + private $_printGridlines = false; + + /** + * Show row and column headers? + * + * @var boolean + */ + private $_showRowColHeaders = true; + + /** + * Show summary below? (Row/Column outline) + * + * @var boolean + */ + private $_showSummaryBelow = true; + + /** + * Show summary right? (Row/Column outline) + * + * @var boolean + */ + private $_showSummaryRight = true; + + /** + * Collection of comments + * + * @var PHPExcel_Comment[] + */ + private $_comments = array(); + + /** + * Active cell. (Only one!) + * + * @var string + */ + private $_activeCell = 'A1'; + + /** + * Selected cells + * + * @var string + */ + private $_selectedCells = 'A1'; + + /** + * Cached highest column + * + * @var string + */ + private $_cachedHighestColumn = 'A'; + + /** + * Cached highest row + * + * @var int + */ + private $_cachedHighestRow = 1; + + /** + * Right-to-left? + * + * @var boolean + */ + private $_rightToLeft = false; + + /** + * Hyperlinks. Indexed by cell coordinate, e.g. 'A1' + * + * @var array + */ + private $_hyperlinkCollection = array(); + + /** + * Data validation objects. Indexed by cell coordinate, e.g. 'A1' + * + * @var array + */ + private $_dataValidationCollection = array(); + + /** + * Tab color + * + * @var PHPExcel_Style_Color + */ + private $_tabColor; + + /** + * Dirty flag + * + * @var boolean + */ + private $_dirty = true; + + /** + * Hash + * + * @var string + */ + private $_hash = null; + + /** + * CodeName + * + * @var string + */ + private $_codeName = null; + + /** + * Create a new worksheet + * + * @param PHPExcel $pParent + * @param string $pTitle + */ + public function __construct(PHPExcel $pParent = null, $pTitle = 'Worksheet') + { + // Set parent and title + $this->_parent = $pParent; + $this->setTitle($pTitle, FALSE); + // setTitle can change $pTitle + $this->setCodeName($this->getTitle()); + $this->setSheetState(PHPExcel_Worksheet::SHEETSTATE_VISIBLE); + + $this->_cellCollection = PHPExcel_CachedObjectStorageFactory::getInstance($this); + + // Set page setup + $this->_pageSetup = new PHPExcel_Worksheet_PageSetup(); + + // Set page margins + $this->_pageMargins = new PHPExcel_Worksheet_PageMargins(); + + // Set page header/footer + $this->_headerFooter = new PHPExcel_Worksheet_HeaderFooter(); + + // Set sheet view + $this->_sheetView = new PHPExcel_Worksheet_SheetView(); + + // Drawing collection + $this->_drawingCollection = new ArrayObject(); + + // Chart collection + $this->_chartCollection = new ArrayObject(); + + // Protection + $this->_protection = new PHPExcel_Worksheet_Protection(); + + // Default row dimension + $this->_defaultRowDimension = new PHPExcel_Worksheet_RowDimension(NULL); + + // Default column dimension + $this->_defaultColumnDimension = new PHPExcel_Worksheet_ColumnDimension(NULL); + + $this->_autoFilter = new PHPExcel_Worksheet_AutoFilter(NULL, $this); + } + + + /** + * Disconnect all cells from this PHPExcel_Worksheet object, + * typically so that the worksheet object can be unset + * + */ + public function disconnectCells() { + if ( $this->_cellCollection !== NULL){ + $this->_cellCollection->unsetWorksheetCells(); + $this->_cellCollection = NULL; + } + // detach ourself from the workbook, so that it can then delete this worksheet successfully + $this->_parent = null; + } + + /** + * Code to execute when this worksheet is unset() + * + */ + function __destruct() { + PHPExcel_Calculation::getInstance($this->_parent) + ->clearCalculationCacheForWorksheet($this->_title); + + $this->disconnectCells(); + } + + /** + * Return the cache controller for the cell collection + * + * @return PHPExcel_CachedObjectStorage_xxx + */ + public function getCellCacheController() { + return $this->_cellCollection; + } // function getCellCacheController() + + + /** + * Get array of invalid characters for sheet title + * + * @return array + */ + public static function getInvalidCharacters() + { + return self::$_invalidCharacters; + } + + /** + * Check sheet code name for valid Excel syntax + * + * @param string $pValue The string to check + * @return string The valid string + * @throws Exception + */ + private static function _checkSheetCodeName($pValue) + { + $CharCount = PHPExcel_Shared_String::CountCharacters($pValue); + if ($CharCount == 0) { + throw new PHPExcel_Exception('Sheet code name cannot be empty.'); + } + // Some of the printable ASCII characters are invalid: * : / \ ? [ ] and first and last characters cannot be a "'" + if ((str_replace(self::$_invalidCharacters, '', $pValue) !== $pValue) || + (PHPExcel_Shared_String::Substring($pValue,-1,1)=='\'') || + (PHPExcel_Shared_String::Substring($pValue,0,1)=='\'')) { + throw new PHPExcel_Exception('Invalid character found in sheet code name'); + } + + // Maximum 31 characters allowed for sheet title + if ($CharCount > 31) { + throw new PHPExcel_Exception('Maximum 31 characters allowed in sheet code name.'); + } + + return $pValue; + } + + /** + * Check sheet title for valid Excel syntax + * + * @param string $pValue The string to check + * @return string The valid string + * @throws PHPExcel_Exception + */ + private static function _checkSheetTitle($pValue) + { + // Some of the printable ASCII characters are invalid: * : / \ ? [ ] + if (str_replace(self::$_invalidCharacters, '', $pValue) !== $pValue) { + throw new PHPExcel_Exception('Invalid character found in sheet title'); + } + + // Maximum 31 characters allowed for sheet title + if (PHPExcel_Shared_String::CountCharacters($pValue) > 31) { + throw new PHPExcel_Exception('Maximum 31 characters allowed in sheet title.'); + } + + return $pValue; + } + + /** + * Get collection of cells + * + * @param boolean $pSorted Also sort the cell collection? + * @return PHPExcel_Cell[] + */ + public function getCellCollection($pSorted = true) + { + if ($pSorted) { + // Re-order cell collection + return $this->sortCellCollection(); + } + if ($this->_cellCollection !== NULL) { + return $this->_cellCollection->getCellList(); + } + return array(); + } + + /** + * Sort collection of cells + * + * @return PHPExcel_Worksheet + */ + public function sortCellCollection() + { + if ($this->_cellCollection !== NULL) { + return $this->_cellCollection->getSortedCellList(); + } + return array(); + } + + /** + * Get collection of row dimensions + * + * @return PHPExcel_Worksheet_RowDimension[] + */ + public function getRowDimensions() + { + return $this->_rowDimensions; + } + + /** + * Get default row dimension + * + * @return PHPExcel_Worksheet_RowDimension + */ + public function getDefaultRowDimension() + { + return $this->_defaultRowDimension; + } + + /** + * Get collection of column dimensions + * + * @return PHPExcel_Worksheet_ColumnDimension[] + */ + public function getColumnDimensions() + { + return $this->_columnDimensions; + } + + /** + * Get default column dimension + * + * @return PHPExcel_Worksheet_ColumnDimension + */ + public function getDefaultColumnDimension() + { + return $this->_defaultColumnDimension; + } + + /** + * Get collection of drawings + * + * @return PHPExcel_Worksheet_BaseDrawing[] + */ + public function getDrawingCollection() + { + return $this->_drawingCollection; + } + + /** + * Get collection of charts + * + * @return PHPExcel_Chart[] + */ + public function getChartCollection() + { + return $this->_chartCollection; + } + + /** + * Add chart + * + * @param PHPExcel_Chart $pChart + * @param int|null $iChartIndex Index where chart should go (0,1,..., or null for last) + * @return PHPExcel_Chart + */ + public function addChart(PHPExcel_Chart $pChart = null, $iChartIndex = null) + { + $pChart->setWorksheet($this); + if (is_null($iChartIndex)) { + $this->_chartCollection[] = $pChart; + } else { + // Insert the chart at the requested index + array_splice($this->_chartCollection, $iChartIndex, 0, array($pChart)); + } + + return $pChart; + } + + /** + * Return the count of charts on this worksheet + * + * @return int The number of charts + */ + public function getChartCount() + { + return count($this->_chartCollection); + } + + /** + * Get a chart by its index position + * + * @param string $index Chart index position + * @return false|PHPExcel_Chart + * @throws PHPExcel_Exception + */ + public function getChartByIndex($index = null) + { + $chartCount = count($this->_chartCollection); + if ($chartCount == 0) { + return false; + } + if (is_null($index)) { + $index = --$chartCount; + } + if (!isset($this->_chartCollection[$index])) { + return false; + } + + return $this->_chartCollection[$index]; + } + + /** + * Return an array of the names of charts on this worksheet + * + * @return string[] The names of charts + * @throws PHPExcel_Exception + */ + public function getChartNames() + { + $chartNames = array(); + foreach($this->_chartCollection as $chart) { + $chartNames[] = $chart->getName(); + } + return $chartNames; + } + + /** + * Get a chart by name + * + * @param string $chartName Chart name + * @return false|PHPExcel_Chart + * @throws PHPExcel_Exception + */ + public function getChartByName($chartName = '') + { + $chartCount = count($this->_chartCollection); + if ($chartCount == 0) { + return false; + } + foreach($this->_chartCollection as $index => $chart) { + if ($chart->getName() == $chartName) { + return $this->_chartCollection[$index]; + } + } + return false; + } + + /** + * Refresh column dimensions + * + * @return PHPExcel_Worksheet + */ + public function refreshColumnDimensions() + { + $currentColumnDimensions = $this->getColumnDimensions(); + $newColumnDimensions = array(); + + foreach ($currentColumnDimensions as $objColumnDimension) { + $newColumnDimensions[$objColumnDimension->getColumnIndex()] = $objColumnDimension; + } + + $this->_columnDimensions = $newColumnDimensions; + + return $this; + } + + /** + * Refresh row dimensions + * + * @return PHPExcel_Worksheet + */ + public function refreshRowDimensions() + { + $currentRowDimensions = $this->getRowDimensions(); + $newRowDimensions = array(); + + foreach ($currentRowDimensions as $objRowDimension) { + $newRowDimensions[$objRowDimension->getRowIndex()] = $objRowDimension; + } + + $this->_rowDimensions = $newRowDimensions; + + return $this; + } + + /** + * Calculate worksheet dimension + * + * @return string String containing the dimension of this worksheet + */ + public function calculateWorksheetDimension() + { + // Return + return 'A1' . ':' . $this->getHighestColumn() . $this->getHighestRow(); + } + + /** + * Calculate worksheet data dimension + * + * @return string String containing the dimension of this worksheet that actually contain data + */ + public function calculateWorksheetDataDimension() + { + // Return + return 'A1' . ':' . $this->getHighestDataColumn() . $this->getHighestDataRow(); + } + + /** + * Calculate widths for auto-size columns + * + * @param boolean $calculateMergeCells Calculate merge cell width + * @return PHPExcel_Worksheet; + */ + public function calculateColumnWidths($calculateMergeCells = false) + { + // initialize $autoSizes array + $autoSizes = array(); + foreach ($this->getColumnDimensions() as $colDimension) { + if ($colDimension->getAutoSize()) { + $autoSizes[$colDimension->getColumnIndex()] = -1; + } + } + + // There is only something to do if there are some auto-size columns + if (!empty($autoSizes)) { + + // build list of cells references that participate in a merge + $isMergeCell = array(); + foreach ($this->getMergeCells() as $cells) { + foreach (PHPExcel_Cell::extractAllCellReferencesInRange($cells) as $cellReference) { + $isMergeCell[$cellReference] = true; + } + } + + // loop through all cells in the worksheet + foreach ($this->getCellCollection(false) as $cellID) { + $cell = $this->getCell($cellID); + if (isset($autoSizes[$this->_cellCollection->getCurrentColumn()])) { + // Determine width if cell does not participate in a merge + if (!isset($isMergeCell[$this->_cellCollection->getCurrentAddress()])) { + // Calculated value + // To formatted string + $cellValue = PHPExcel_Style_NumberFormat::toFormattedString( + $cell->getCalculatedValue(), + $this->getParent()->getCellXfByIndex($cell->getXfIndex())->getNumberFormat()->getFormatCode() + ); + + $autoSizes[$this->_cellCollection->getCurrentColumn()] = max( + (float) $autoSizes[$this->_cellCollection->getCurrentColumn()], + (float)PHPExcel_Shared_Font::calculateColumnWidth( + $this->getParent()->getCellXfByIndex($cell->getXfIndex())->getFont(), + $cellValue, + $this->getParent()->getCellXfByIndex($cell->getXfIndex())->getAlignment()->getTextRotation(), + $this->getDefaultStyle()->getFont() + ) + ); + } + } + } + + // adjust column widths + foreach ($autoSizes as $columnIndex => $width) { + if ($width == -1) $width = $this->getDefaultColumnDimension()->getWidth(); + $this->getColumnDimension($columnIndex)->setWidth($width); + } + } + + return $this; + } + + /** + * Get parent + * + * @return PHPExcel + */ + public function getParent() { + return $this->_parent; + } + + /** + * Re-bind parent + * + * @param PHPExcel $parent + * @return PHPExcel_Worksheet + */ + public function rebindParent(PHPExcel $parent) { + if ($this->_parent !== null) { + $namedRanges = $this->_parent->getNamedRanges(); + foreach ($namedRanges as $namedRange) { + $parent->addNamedRange($namedRange); + } + + $this->_parent->removeSheetByIndex( + $this->_parent->getIndex($this) + ); + } + $this->_parent = $parent; + + return $this; + } + + /** + * Get title + * + * @return string + */ + public function getTitle() + { + return $this->_title; + } + + /** + * Set title + * + * @param string $pValue String containing the dimension of this worksheet + * @param string $updateFormulaCellReferences boolean Flag indicating whether cell references in formulae should + * be updated to reflect the new sheet name. + * This should be left as the default true, unless you are + * certain that no formula cells on any worksheet contain + * references to this worksheet + * @return PHPExcel_Worksheet + */ + public function setTitle($pValue = 'Worksheet', $updateFormulaCellReferences = true) + { + // Is this a 'rename' or not? + if ($this->getTitle() == $pValue) { + return $this; + } + + // Syntax check + self::_checkSheetTitle($pValue); + + // Old title + $oldTitle = $this->getTitle(); + + if ($this->_parent) { + // Is there already such sheet name? + if ($this->_parent->sheetNameExists($pValue)) { + // Use name, but append with lowest possible integer + + if (PHPExcel_Shared_String::CountCharacters($pValue) > 29) { + $pValue = PHPExcel_Shared_String::Substring($pValue,0,29); + } + $i = 1; + while ($this->_parent->sheetNameExists($pValue . ' ' . $i)) { + ++$i; + if ($i == 10) { + if (PHPExcel_Shared_String::CountCharacters($pValue) > 28) { + $pValue = PHPExcel_Shared_String::Substring($pValue,0,28); + } + } elseif ($i == 100) { + if (PHPExcel_Shared_String::CountCharacters($pValue) > 27) { + $pValue = PHPExcel_Shared_String::Substring($pValue,0,27); + } + } + } + + $altTitle = $pValue . ' ' . $i; + return $this->setTitle($altTitle,$updateFormulaCellReferences); + } + } + + // Set title + $this->_title = $pValue; + $this->_dirty = true; + + if ($this->_parent) { + // New title + $newTitle = $this->getTitle(); + PHPExcel_Calculation::getInstance($this->_parent) + ->renameCalculationCacheForWorksheet($oldTitle, $newTitle); + if ($updateFormulaCellReferences) + PHPExcel_ReferenceHelper::getInstance()->updateNamedFormulas($this->_parent, $oldTitle, $newTitle); + } + + return $this; + } + + /** + * Get sheet state + * + * @return string Sheet state (visible, hidden, veryHidden) + */ + public function getSheetState() { + return $this->_sheetState; + } + + /** + * Set sheet state + * + * @param string $value Sheet state (visible, hidden, veryHidden) + * @return PHPExcel_Worksheet + */ + public function setSheetState($value = PHPExcel_Worksheet::SHEETSTATE_VISIBLE) { + $this->_sheetState = $value; + return $this; + } + + /** + * Get page setup + * + * @return PHPExcel_Worksheet_PageSetup + */ + public function getPageSetup() + { + return $this->_pageSetup; + } + + /** + * Set page setup + * + * @param PHPExcel_Worksheet_PageSetup $pValue + * @return PHPExcel_Worksheet + */ + public function setPageSetup(PHPExcel_Worksheet_PageSetup $pValue) + { + $this->_pageSetup = $pValue; + return $this; + } + + /** + * Get page margins + * + * @return PHPExcel_Worksheet_PageMargins + */ + public function getPageMargins() + { + return $this->_pageMargins; + } + + /** + * Set page margins + * + * @param PHPExcel_Worksheet_PageMargins $pValue + * @return PHPExcel_Worksheet + */ + public function setPageMargins(PHPExcel_Worksheet_PageMargins $pValue) + { + $this->_pageMargins = $pValue; + return $this; + } + + /** + * Get page header/footer + * + * @return PHPExcel_Worksheet_HeaderFooter + */ + public function getHeaderFooter() + { + return $this->_headerFooter; + } + + /** + * Set page header/footer + * + * @param PHPExcel_Worksheet_HeaderFooter $pValue + * @return PHPExcel_Worksheet + */ + public function setHeaderFooter(PHPExcel_Worksheet_HeaderFooter $pValue) + { + $this->_headerFooter = $pValue; + return $this; + } + + /** + * Get sheet view + * + * @return PHPExcel_Worksheet_SheetView + */ + public function getSheetView() + { + return $this->_sheetView; + } + + /** + * Set sheet view + * + * @param PHPExcel_Worksheet_SheetView $pValue + * @return PHPExcel_Worksheet + */ + public function setSheetView(PHPExcel_Worksheet_SheetView $pValue) + { + $this->_sheetView = $pValue; + return $this; + } + + /** + * Get Protection + * + * @return PHPExcel_Worksheet_Protection + */ + public function getProtection() + { + return $this->_protection; + } + + /** + * Set Protection + * + * @param PHPExcel_Worksheet_Protection $pValue + * @return PHPExcel_Worksheet + */ + public function setProtection(PHPExcel_Worksheet_Protection $pValue) + { + $this->_protection = $pValue; + $this->_dirty = true; + + return $this; + } + + /** + * Get highest worksheet column + * + * @param string $row Return the data highest column for the specified row, + * or the highest column of any row if no row number is passed + * @return string Highest column name + */ + public function getHighestColumn($row = null) + { + if ($row == null) { + return $this->_cachedHighestColumn; + } + return $this->getHighestDataColumn($row); + } + + /** + * Get highest worksheet column that contains data + * + * @param string $row Return the highest data column for the specified row, + * or the highest data column of any row if no row number is passed + * @return string Highest column name that contains data + */ + public function getHighestDataColumn($row = null) + { + return $this->_cellCollection->getHighestColumn($row); + } + + /** + * Get highest worksheet row + * + * @param string $column Return the highest data row for the specified column, + * or the highest row of any column if no column letter is passed + * @return int Highest row number + */ + public function getHighestRow($column = null) + { + if ($column == null) { + return $this->_cachedHighestRow; + } + return $this->getHighestDataRow($column); + } + + /** + * Get highest worksheet row that contains data + * + * @param string $column Return the highest data row for the specified column, + * or the highest data row of any column if no column letter is passed + * @return string Highest row number that contains data + */ + public function getHighestDataRow($column = null) + { + return $this->_cellCollection->getHighestRow($column); + } + + /** + * Get highest worksheet column and highest row that have cell records + * + * @return array Highest column name and highest row number + */ + public function getHighestRowAndColumn() + { + return $this->_cellCollection->getHighestRowAndColumn(); + } + + /** + * Set a cell value + * + * @param string $pCoordinate Coordinate of the cell + * @param mixed $pValue Value of the cell + * @param bool $returnCell Return the worksheet (false, default) or the cell (true) + * @return PHPExcel_Worksheet|PHPExcel_Cell Depending on the last parameter being specified + */ + public function setCellValue($pCoordinate = 'A1', $pValue = null, $returnCell = false) + { + $cell = $this->getCell($pCoordinate)->setValue($pValue); + return ($returnCell) ? $cell : $this; + } + + /** + * Set a cell value by using numeric cell coordinates + * + * @param string $pColumn Numeric column coordinate of the cell (A = 0) + * @param string $pRow Numeric row coordinate of the cell + * @param mixed $pValue Value of the cell + * @param bool $returnCell Return the worksheet (false, default) or the cell (true) + * @return PHPExcel_Worksheet|PHPExcel_Cell Depending on the last parameter being specified + */ + public function setCellValueByColumnAndRow($pColumn = 0, $pRow = 1, $pValue = null, $returnCell = false) + { + $cell = $this->getCellByColumnAndRow($pColumn, $pRow)->setValue($pValue); + return ($returnCell) ? $cell : $this; + } + + /** + * Set a cell value + * + * @param string $pCoordinate Coordinate of the cell + * @param mixed $pValue Value of the cell + * @param string $pDataType Explicit data type + * @param bool $returnCell Return the worksheet (false, default) or the cell (true) + * @return PHPExcel_Worksheet|PHPExcel_Cell Depending on the last parameter being specified + */ + public function setCellValueExplicit($pCoordinate = 'A1', $pValue = null, $pDataType = PHPExcel_Cell_DataType::TYPE_STRING, $returnCell = false) + { + // Set value + $cell = $this->getCell($pCoordinate)->setValueExplicit($pValue, $pDataType); + return ($returnCell) ? $cell : $this; + } + + /** + * Set a cell value by using numeric cell coordinates + * + * @param string $pColumn Numeric column coordinate of the cell + * @param string $pRow Numeric row coordinate of the cell + * @param mixed $pValue Value of the cell + * @param string $pDataType Explicit data type + * @param bool $returnCell Return the worksheet (false, default) or the cell (true) + * @return PHPExcel_Worksheet|PHPExcel_Cell Depending on the last parameter being specified + */ + public function setCellValueExplicitByColumnAndRow($pColumn = 0, $pRow = 1, $pValue = null, $pDataType = PHPExcel_Cell_DataType::TYPE_STRING, $returnCell = false) + { + $cell = $this->getCellByColumnAndRow($pColumn, $pRow)->setValueExplicit($pValue, $pDataType); + return ($returnCell) ? $cell : $this; + } + + /** + * Get cell at a specific coordinate + * + * @param string $pCoordinate Coordinate of the cell + * @throws PHPExcel_Exception + * @return PHPExcel_Cell Cell that was found + */ + public function getCell($pCoordinate = 'A1') + { + // Check cell collection + if ($this->_cellCollection->isDataSet($pCoordinate)) { + return $this->_cellCollection->getCacheData($pCoordinate); + } + + // Worksheet reference? + if (strpos($pCoordinate, '!') !== false) { + $worksheetReference = PHPExcel_Worksheet::extractSheetTitle($pCoordinate, true); + return $this->_parent->getSheetByName($worksheetReference[0])->getCell($worksheetReference[1]); + } + + // Named range? + if ((!preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_CELLREF.'$/i', $pCoordinate, $matches)) && + (preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_NAMEDRANGE.'$/i', $pCoordinate, $matches))) { + $namedRange = PHPExcel_NamedRange::resolveRange($pCoordinate, $this); + if ($namedRange !== NULL) { + $pCoordinate = $namedRange->getRange(); + return $namedRange->getWorksheet()->getCell($pCoordinate); + } + } + + // Uppercase coordinate + $pCoordinate = strtoupper($pCoordinate); + + if (strpos($pCoordinate, ':') !== false || strpos($pCoordinate, ',') !== false) { + throw new PHPExcel_Exception('Cell coordinate can not be a range of cells.'); + } elseif (strpos($pCoordinate, '$') !== false) { + throw new PHPExcel_Exception('Cell coordinate must not be absolute.'); + } + + // Create new cell object + return $this->_createNewCell($pCoordinate); + } + + /** + * Get cell at a specific coordinate by using numeric cell coordinates + * + * @param string $pColumn Numeric column coordinate of the cell + * @param string $pRow Numeric row coordinate of the cell + * @return PHPExcel_Cell Cell that was found + */ + public function getCellByColumnAndRow($pColumn = 0, $pRow = 1) + { + $columnLetter = PHPExcel_Cell::stringFromColumnIndex($pColumn); + $coordinate = $columnLetter . $pRow; + + if ($this->_cellCollection->isDataSet($coordinate)) { + return $this->_cellCollection->getCacheData($coordinate); + } + + return $this->_createNewCell($coordinate); + } + + /** + * Create a new cell at the specified coordinate + * + * @param string $pCoordinate Coordinate of the cell + * @return PHPExcel_Cell Cell that was created + */ + private function _createNewCell($pCoordinate) + { + $cell = $this->_cellCollection->addCacheData( + $pCoordinate, + new PHPExcel_Cell( + NULL, + PHPExcel_Cell_DataType::TYPE_NULL, + $this + ) + ); + $this->_cellCollectionIsSorted = false; + + // Coordinates + $aCoordinates = PHPExcel_Cell::coordinateFromString($pCoordinate); + if (PHPExcel_Cell::columnIndexFromString($this->_cachedHighestColumn) < PHPExcel_Cell::columnIndexFromString($aCoordinates[0])) + $this->_cachedHighestColumn = $aCoordinates[0]; + $this->_cachedHighestRow = max($this->_cachedHighestRow, $aCoordinates[1]); + + // Cell needs appropriate xfIndex from dimensions records + // but don't create dimension records if they don't already exist + $rowDimension = $this->getRowDimension($aCoordinates[1], FALSE); + $columnDimension = $this->getColumnDimension($aCoordinates[0], FALSE); + + if ($rowDimension !== NULL && $rowDimension->getXfIndex() > 0) { + // then there is a row dimension with explicit style, assign it to the cell + $cell->setXfIndex($rowDimension->getXfIndex()); + } elseif ($columnDimension !== NULL && $columnDimension->getXfIndex() > 0) { + // then there is a column dimension, assign it to the cell + $cell->setXfIndex($columnDimension->getXfIndex()); + } + + return $cell; + } + + /** + * Does the cell at a specific coordinate exist? + * + * @param string $pCoordinate Coordinate of the cell + * @throws PHPExcel_Exception + * @return boolean + */ + public function cellExists($pCoordinate = 'A1') + { + // Worksheet reference? + if (strpos($pCoordinate, '!') !== false) { + $worksheetReference = PHPExcel_Worksheet::extractSheetTitle($pCoordinate, true); + return $this->_parent->getSheetByName($worksheetReference[0])->cellExists($worksheetReference[1]); + } + + // Named range? + if ((!preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_CELLREF.'$/i', $pCoordinate, $matches)) && + (preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_NAMEDRANGE.'$/i', $pCoordinate, $matches))) { + $namedRange = PHPExcel_NamedRange::resolveRange($pCoordinate, $this); + if ($namedRange !== NULL) { + $pCoordinate = $namedRange->getRange(); + if ($this->getHashCode() != $namedRange->getWorksheet()->getHashCode()) { + if (!$namedRange->getLocalOnly()) { + return $namedRange->getWorksheet()->cellExists($pCoordinate); + } else { + throw new PHPExcel_Exception('Named range ' . $namedRange->getName() . ' is not accessible from within sheet ' . $this->getTitle()); + } + } + } + else { return false; } + } + + // Uppercase coordinate + $pCoordinate = strtoupper($pCoordinate); + + if (strpos($pCoordinate,':') !== false || strpos($pCoordinate,',') !== false) { + throw new PHPExcel_Exception('Cell coordinate can not be a range of cells.'); + } elseif (strpos($pCoordinate,'$') !== false) { + throw new PHPExcel_Exception('Cell coordinate must not be absolute.'); + } else { + // Coordinates + $aCoordinates = PHPExcel_Cell::coordinateFromString($pCoordinate); + + // Cell exists? + return $this->_cellCollection->isDataSet($pCoordinate); + } + } + + /** + * Cell at a specific coordinate by using numeric cell coordinates exists? + * + * @param string $pColumn Numeric column coordinate of the cell + * @param string $pRow Numeric row coordinate of the cell + * @return boolean + */ + public function cellExistsByColumnAndRow($pColumn = 0, $pRow = 1) + { + return $this->cellExists(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow); + } + + /** + * Get row dimension at a specific row + * + * @param int $pRow Numeric index of the row + * @return PHPExcel_Worksheet_RowDimension + */ + public function getRowDimension($pRow = 1, $create = TRUE) + { + // Found + $found = null; + + // Get row dimension + if (!isset($this->_rowDimensions[$pRow])) { + if (!$create) + return NULL; + $this->_rowDimensions[$pRow] = new PHPExcel_Worksheet_RowDimension($pRow); + + $this->_cachedHighestRow = max($this->_cachedHighestRow,$pRow); + } + return $this->_rowDimensions[$pRow]; + } + + /** + * Get column dimension at a specific column + * + * @param string $pColumn String index of the column + * @return PHPExcel_Worksheet_ColumnDimension + */ + public function getColumnDimension($pColumn = 'A', $create = TRUE) + { + // Uppercase coordinate + $pColumn = strtoupper($pColumn); + + // Fetch dimensions + if (!isset($this->_columnDimensions[$pColumn])) { + if (!$create) + return NULL; + $this->_columnDimensions[$pColumn] = new PHPExcel_Worksheet_ColumnDimension($pColumn); + + if (PHPExcel_Cell::columnIndexFromString($this->_cachedHighestColumn) < PHPExcel_Cell::columnIndexFromString($pColumn)) + $this->_cachedHighestColumn = $pColumn; + } + return $this->_columnDimensions[$pColumn]; + } + + /** + * Get column dimension at a specific column by using numeric cell coordinates + * + * @param string $pColumn Numeric column coordinate of the cell + * @return PHPExcel_Worksheet_ColumnDimension + */ + public function getColumnDimensionByColumn($pColumn = 0) + { + return $this->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($pColumn)); + } + + /** + * Get styles + * + * @return PHPExcel_Style[] + */ + public function getStyles() + { + return $this->_styles; + } + + /** + * Get default style of workbook. + * + * @deprecated + * @return PHPExcel_Style + * @throws PHPExcel_Exception + */ + public function getDefaultStyle() + { + return $this->_parent->getDefaultStyle(); + } + + /** + * Set default style - should only be used by PHPExcel_IReader implementations! + * + * @deprecated + * @param PHPExcel_Style $pValue + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function setDefaultStyle(PHPExcel_Style $pValue) + { + $this->_parent->getDefaultStyle()->applyFromArray(array( + 'font' => array( + 'name' => $pValue->getFont()->getName(), + 'size' => $pValue->getFont()->getSize(), + ), + )); + return $this; + } + + /** + * Get style for cell + * + * @param string $pCellCoordinate Cell coordinate to get style for + * @return PHPExcel_Style + * @throws PHPExcel_Exception + */ + public function getStyle($pCellCoordinate = 'A1') + { + // set this sheet as active + $this->_parent->setActiveSheetIndex($this->_parent->getIndex($this)); + + // set cell coordinate as active + $this->setSelectedCells($pCellCoordinate); + + return $this->_parent->getCellXfSupervisor(); + } + + /** + * Get conditional styles for a cell + * + * @param string $pCoordinate + * @return PHPExcel_Style_Conditional[] + */ + public function getConditionalStyles($pCoordinate = 'A1') + { + if (!isset($this->_conditionalStylesCollection[$pCoordinate])) { + $this->_conditionalStylesCollection[$pCoordinate] = array(); + } + return $this->_conditionalStylesCollection[$pCoordinate]; + } + + /** + * Do conditional styles exist for this cell? + * + * @param string $pCoordinate + * @return boolean + */ + public function conditionalStylesExists($pCoordinate = 'A1') + { + if (isset($this->_conditionalStylesCollection[$pCoordinate])) { + return true; + } + return false; + } + + /** + * Removes conditional styles for a cell + * + * @param string $pCoordinate + * @return PHPExcel_Worksheet + */ + public function removeConditionalStyles($pCoordinate = 'A1') + { + unset($this->_conditionalStylesCollection[$pCoordinate]); + return $this; + } + + /** + * Get collection of conditional styles + * + * @return array + */ + public function getConditionalStylesCollection() + { + return $this->_conditionalStylesCollection; + } + + /** + * Set conditional styles + * + * @param $pCoordinate string E.g. 'A1' + * @param $pValue PHPExcel_Style_Conditional[] + * @return PHPExcel_Worksheet + */ + public function setConditionalStyles($pCoordinate = 'A1', $pValue) + { + $this->_conditionalStylesCollection[$pCoordinate] = $pValue; + return $this; + } + + /** + * Get style for cell by using numeric cell coordinates + * + * @param int $pColumn Numeric column coordinate of the cell + * @param int $pRow Numeric row coordinate of the cell + * @return PHPExcel_Style + */ + public function getStyleByColumnAndRow($pColumn = 0, $pRow = 1) + { + return $this->getStyle(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow); + } + + /** + * Set shared cell style to a range of cells + * + * Please note that this will overwrite existing cell styles for cells in range! + * + * @deprecated + * @param PHPExcel_Style $pSharedCellStyle Cell style to share + * @param string $pRange Range of cells (i.e. "A1:B10"), or just one cell (i.e. "A1") + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function setSharedStyle(PHPExcel_Style $pSharedCellStyle = null, $pRange = '') + { + $this->duplicateStyle($pSharedCellStyle, $pRange); + return $this; + } + + /** + * Duplicate cell style to a range of cells + * + * Please note that this will overwrite existing cell styles for cells in range! + * + * @param PHPExcel_Style $pCellStyle Cell style to duplicate + * @param string $pRange Range of cells (i.e. "A1:B10"), or just one cell (i.e. "A1") + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function duplicateStyle(PHPExcel_Style $pCellStyle = null, $pRange = '') + { + // make sure we have a real style and not supervisor + $style = $pCellStyle->getIsSupervisor() ? $pCellStyle->getSharedComponent() : $pCellStyle; + + // Add the style to the workbook if necessary + $workbook = $this->_parent; + if ($existingStyle = $this->_parent->getCellXfByHashCode($pCellStyle->getHashCode())) { + // there is already such cell Xf in our collection + $xfIndex = $existingStyle->getIndex(); + } else { + // we don't have such a cell Xf, need to add + $workbook->addCellXf($pCellStyle); + $xfIndex = $pCellStyle->getIndex(); + } + + // Calculate range outer borders + list($rangeStart, $rangeEnd) = PHPExcel_Cell::rangeBoundaries($pRange . ':' . $pRange); + + // Make sure we can loop upwards on rows and columns + if ($rangeStart[0] > $rangeEnd[0] && $rangeStart[1] > $rangeEnd[1]) { + $tmp = $rangeStart; + $rangeStart = $rangeEnd; + $rangeEnd = $tmp; + } + + // Loop through cells and apply styles + for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) { + for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) { + $this->getCell(PHPExcel_Cell::stringFromColumnIndex($col - 1) . $row)->setXfIndex($xfIndex); + } + } + + return $this; + } + + /** + * Duplicate conditional style to a range of cells + * + * Please note that this will overwrite existing cell styles for cells in range! + * + * @param array of PHPExcel_Style_Conditional $pCellStyle Cell style to duplicate + * @param string $pRange Range of cells (i.e. "A1:B10"), or just one cell (i.e. "A1") + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function duplicateConditionalStyle(array $pCellStyle = null, $pRange = '') + { + foreach($pCellStyle as $cellStyle) { + if (!($cellStyle instanceof PHPExcel_Style_Conditional)) { + throw new PHPExcel_Exception('Style is not a conditional style'); + } + } + + // Calculate range outer borders + list($rangeStart, $rangeEnd) = PHPExcel_Cell::rangeBoundaries($pRange . ':' . $pRange); + + // Make sure we can loop upwards on rows and columns + if ($rangeStart[0] > $rangeEnd[0] && $rangeStart[1] > $rangeEnd[1]) { + $tmp = $rangeStart; + $rangeStart = $rangeEnd; + $rangeEnd = $tmp; + } + + // Loop through cells and apply styles + for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) { + for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) { + $this->setConditionalStyles(PHPExcel_Cell::stringFromColumnIndex($col - 1) . $row, $pCellStyle); + } + } + + return $this; + } + + /** + * Duplicate cell style array to a range of cells + * + * Please note that this will overwrite existing cell styles for cells in range, + * if they are in the styles array. For example, if you decide to set a range of + * cells to font bold, only include font bold in the styles array. + * + * @deprecated + * @param array $pStyles Array containing style information + * @param string $pRange Range of cells (i.e. "A1:B10"), or just one cell (i.e. "A1") + * @param boolean $pAdvanced Advanced mode for setting borders. + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function duplicateStyleArray($pStyles = null, $pRange = '', $pAdvanced = true) + { + $this->getStyle($pRange)->applyFromArray($pStyles, $pAdvanced); + return $this; + } + + /** + * Set break on a cell + * + * @param string $pCell Cell coordinate (e.g. A1) + * @param int $pBreak Break type (type of PHPExcel_Worksheet::BREAK_*) + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function setBreak($pCell = 'A1', $pBreak = PHPExcel_Worksheet::BREAK_NONE) + { + // Uppercase coordinate + $pCell = strtoupper($pCell); + + if ($pCell != '') { + if ($pBreak == PHPExcel_Worksheet::BREAK_NONE) { + if (isset($this->_breaks[$pCell])) { + unset($this->_breaks[$pCell]); + } + } else { + $this->_breaks[$pCell] = $pBreak; + } + } else { + throw new PHPExcel_Exception('No cell coordinate specified.'); + } + + return $this; + } + + /** + * Set break on a cell by using numeric cell coordinates + * + * @param integer $pColumn Numeric column coordinate of the cell + * @param integer $pRow Numeric row coordinate of the cell + * @param integer $pBreak Break type (type of PHPExcel_Worksheet::BREAK_*) + * @return PHPExcel_Worksheet + */ + public function setBreakByColumnAndRow($pColumn = 0, $pRow = 1, $pBreak = PHPExcel_Worksheet::BREAK_NONE) + { + return $this->setBreak(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow, $pBreak); + } + + /** + * Get breaks + * + * @return array[] + */ + public function getBreaks() + { + return $this->_breaks; + } + + /** + * Set merge on a cell range + * + * @param string $pRange Cell range (e.g. A1:E1) + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function mergeCells($pRange = 'A1:A1') + { + // Uppercase coordinate + $pRange = strtoupper($pRange); + + if (strpos($pRange,':') !== false) { + $this->_mergeCells[$pRange] = $pRange; + + // make sure cells are created + + // get the cells in the range + $aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($pRange); + + // create upper left cell if it does not already exist + $upperLeft = $aReferences[0]; + if (!$this->cellExists($upperLeft)) { + $this->getCell($upperLeft)->setValueExplicit(null, PHPExcel_Cell_DataType::TYPE_NULL); + } + + // create or blank out the rest of the cells in the range + $count = count($aReferences); + for ($i = 1; $i < $count; $i++) { + $this->getCell($aReferences[$i])->setValueExplicit(null, PHPExcel_Cell_DataType::TYPE_NULL); + } + + } else { + throw new PHPExcel_Exception('Merge must be set on a range of cells.'); + } + + return $this; + } + + /** + * Set merge on a cell range by using numeric cell coordinates + * + * @param int $pColumn1 Numeric column coordinate of the first cell + * @param int $pRow1 Numeric row coordinate of the first cell + * @param int $pColumn2 Numeric column coordinate of the last cell + * @param int $pRow2 Numeric row coordinate of the last cell + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function mergeCellsByColumnAndRow($pColumn1 = 0, $pRow1 = 1, $pColumn2 = 0, $pRow2 = 1) + { + $cellRange = PHPExcel_Cell::stringFromColumnIndex($pColumn1) . $pRow1 . ':' . PHPExcel_Cell::stringFromColumnIndex($pColumn2) . $pRow2; + return $this->mergeCells($cellRange); + } + + /** + * Remove merge on a cell range + * + * @param string $pRange Cell range (e.g. A1:E1) + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function unmergeCells($pRange = 'A1:A1') + { + // Uppercase coordinate + $pRange = strtoupper($pRange); + + if (strpos($pRange,':') !== false) { + if (isset($this->_mergeCells[$pRange])) { + unset($this->_mergeCells[$pRange]); + } else { + throw new PHPExcel_Exception('Cell range ' . $pRange . ' not known as merged.'); + } + } else { + throw new PHPExcel_Exception('Merge can only be removed from a range of cells.'); + } + + return $this; + } + + /** + * Remove merge on a cell range by using numeric cell coordinates + * + * @param int $pColumn1 Numeric column coordinate of the first cell + * @param int $pRow1 Numeric row coordinate of the first cell + * @param int $pColumn2 Numeric column coordinate of the last cell + * @param int $pRow2 Numeric row coordinate of the last cell + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function unmergeCellsByColumnAndRow($pColumn1 = 0, $pRow1 = 1, $pColumn2 = 0, $pRow2 = 1) + { + $cellRange = PHPExcel_Cell::stringFromColumnIndex($pColumn1) . $pRow1 . ':' . PHPExcel_Cell::stringFromColumnIndex($pColumn2) . $pRow2; + return $this->unmergeCells($cellRange); + } + + /** + * Get merge cells array. + * + * @return array[] + */ + public function getMergeCells() + { + return $this->_mergeCells; + } + + /** + * Set merge cells array for the entire sheet. Use instead mergeCells() to merge + * a single cell range. + * + * @param array + */ + public function setMergeCells($pValue = array()) + { + $this->_mergeCells = $pValue; + + return $this; + } + + /** + * Set protection on a cell range + * + * @param string $pRange Cell (e.g. A1) or cell range (e.g. A1:E1) + * @param string $pPassword Password to unlock the protection + * @param boolean $pAlreadyHashed If the password has already been hashed, set this to true + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function protectCells($pRange = 'A1', $pPassword = '', $pAlreadyHashed = false) + { + // Uppercase coordinate + $pRange = strtoupper($pRange); + + if (!$pAlreadyHashed) { + $pPassword = PHPExcel_Shared_PasswordHasher::hashPassword($pPassword); + } + $this->_protectedCells[$pRange] = $pPassword; + + return $this; + } + + /** + * Set protection on a cell range by using numeric cell coordinates + * + * @param int $pColumn1 Numeric column coordinate of the first cell + * @param int $pRow1 Numeric row coordinate of the first cell + * @param int $pColumn2 Numeric column coordinate of the last cell + * @param int $pRow2 Numeric row coordinate of the last cell + * @param string $pPassword Password to unlock the protection + * @param boolean $pAlreadyHashed If the password has already been hashed, set this to true + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function protectCellsByColumnAndRow($pColumn1 = 0, $pRow1 = 1, $pColumn2 = 0, $pRow2 = 1, $pPassword = '', $pAlreadyHashed = false) + { + $cellRange = PHPExcel_Cell::stringFromColumnIndex($pColumn1) . $pRow1 . ':' . PHPExcel_Cell::stringFromColumnIndex($pColumn2) . $pRow2; + return $this->protectCells($cellRange, $pPassword, $pAlreadyHashed); + } + + /** + * Remove protection on a cell range + * + * @param string $pRange Cell (e.g. A1) or cell range (e.g. A1:E1) + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function unprotectCells($pRange = 'A1') + { + // Uppercase coordinate + $pRange = strtoupper($pRange); + + if (isset($this->_protectedCells[$pRange])) { + unset($this->_protectedCells[$pRange]); + } else { + throw new PHPExcel_Exception('Cell range ' . $pRange . ' not known as protected.'); + } + return $this; + } + + /** + * Remove protection on a cell range by using numeric cell coordinates + * + * @param int $pColumn1 Numeric column coordinate of the first cell + * @param int $pRow1 Numeric row coordinate of the first cell + * @param int $pColumn2 Numeric column coordinate of the last cell + * @param int $pRow2 Numeric row coordinate of the last cell + * @param string $pPassword Password to unlock the protection + * @param boolean $pAlreadyHashed If the password has already been hashed, set this to true + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function unprotectCellsByColumnAndRow($pColumn1 = 0, $pRow1 = 1, $pColumn2 = 0, $pRow2 = 1, $pPassword = '', $pAlreadyHashed = false) + { + $cellRange = PHPExcel_Cell::stringFromColumnIndex($pColumn1) . $pRow1 . ':' . PHPExcel_Cell::stringFromColumnIndex($pColumn2) . $pRow2; + return $this->unprotectCells($cellRange, $pPassword, $pAlreadyHashed); + } + + /** + * Get protected cells + * + * @return array[] + */ + public function getProtectedCells() + { + return $this->_protectedCells; + } + + /** + * Get Autofilter + * + * @return PHPExcel_Worksheet_AutoFilter + */ + public function getAutoFilter() + { + return $this->_autoFilter; + } + + /** + * Set AutoFilter + * + * @param PHPExcel_Worksheet_AutoFilter|string $pValue + * A simple string containing a Cell range like 'A1:E10' is permitted for backward compatibility + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function setAutoFilter($pValue) + { + if (is_string($pValue)) { + $this->_autoFilter->setRange($pValue); + } elseif(is_object($pValue) && ($pValue instanceof PHPExcel_Worksheet_AutoFilter)) { + $this->_autoFilter = $pValue; + } + return $this; + } + + /** + * Set Autofilter Range by using numeric cell coordinates + * + * @param integer $pColumn1 Numeric column coordinate of the first cell + * @param integer $pRow1 Numeric row coordinate of the first cell + * @param integer $pColumn2 Numeric column coordinate of the second cell + * @param integer $pRow2 Numeric row coordinate of the second cell + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function setAutoFilterByColumnAndRow($pColumn1 = 0, $pRow1 = 1, $pColumn2 = 0, $pRow2 = 1) + { + return $this->setAutoFilter( + PHPExcel_Cell::stringFromColumnIndex($pColumn1) . $pRow1 + . ':' . + PHPExcel_Cell::stringFromColumnIndex($pColumn2) . $pRow2 + ); + } + + /** + * Remove autofilter + * + * @return PHPExcel_Worksheet + */ + public function removeAutoFilter() + { + $this->_autoFilter->setRange(NULL); + return $this; + } + + /** + * Get Freeze Pane + * + * @return string + */ + public function getFreezePane() + { + return $this->_freezePane; + } + + /** + * Freeze Pane + * + * @param string $pCell Cell (i.e. A2) + * Examples: + * A2 will freeze the rows above cell A2 (i.e row 1) + * B1 will freeze the columns to the left of cell B1 (i.e column A) + * B2 will freeze the rows above and to the left of cell A2 + * (i.e row 1 and column A) + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function freezePane($pCell = '') + { + // Uppercase coordinate + $pCell = strtoupper($pCell); + + if (strpos($pCell,':') === false && strpos($pCell,',') === false) { + $this->_freezePane = $pCell; + } else { + throw new PHPExcel_Exception('Freeze pane can not be set on a range of cells.'); + } + return $this; + } + + /** + * Freeze Pane by using numeric cell coordinates + * + * @param int $pColumn Numeric column coordinate of the cell + * @param int $pRow Numeric row coordinate of the cell + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function freezePaneByColumnAndRow($pColumn = 0, $pRow = 1) + { + return $this->freezePane(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow); + } + + /** + * Unfreeze Pane + * + * @return PHPExcel_Worksheet + */ + public function unfreezePane() + { + return $this->freezePane(''); + } + + /** + * Insert a new row, updating all possible related data + * + * @param int $pBefore Insert before this one + * @param int $pNumRows Number of rows to insert + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function insertNewRowBefore($pBefore = 1, $pNumRows = 1) { + if ($pBefore >= 1) { + $objReferenceHelper = PHPExcel_ReferenceHelper::getInstance(); + $objReferenceHelper->insertNewBefore('A' . $pBefore, 0, $pNumRows, $this); + } else { + throw new PHPExcel_Exception("Rows can only be inserted before at least row 1."); + } + return $this; + } + + /** + * Insert a new column, updating all possible related data + * + * @param int $pBefore Insert before this one + * @param int $pNumCols Number of columns to insert + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function insertNewColumnBefore($pBefore = 'A', $pNumCols = 1) { + if (!is_numeric($pBefore)) { + $objReferenceHelper = PHPExcel_ReferenceHelper::getInstance(); + $objReferenceHelper->insertNewBefore($pBefore . '1', $pNumCols, 0, $this); + } else { + throw new PHPExcel_Exception("Column references should not be numeric."); + } + return $this; + } + + /** + * Insert a new column, updating all possible related data + * + * @param int $pBefore Insert before this one (numeric column coordinate of the cell) + * @param int $pNumCols Number of columns to insert + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function insertNewColumnBeforeByIndex($pBefore = 0, $pNumCols = 1) { + if ($pBefore >= 0) { + return $this->insertNewColumnBefore(PHPExcel_Cell::stringFromColumnIndex($pBefore), $pNumCols); + } else { + throw new PHPExcel_Exception("Columns can only be inserted before at least column A (0)."); + } + } + + /** + * Delete a row, updating all possible related data + * + * @param int $pRow Remove starting with this one + * @param int $pNumRows Number of rows to remove + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function removeRow($pRow = 1, $pNumRows = 1) { + if ($pRow >= 1) { + $objReferenceHelper = PHPExcel_ReferenceHelper::getInstance(); + $objReferenceHelper->insertNewBefore('A' . ($pRow + $pNumRows), 0, -$pNumRows, $this); + } else { + throw new PHPExcel_Exception("Rows to be deleted should at least start from row 1."); + } + return $this; + } + + /** + * Remove a column, updating all possible related data + * + * @param int $pColumn Remove starting with this one + * @param int $pNumCols Number of columns to remove + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function removeColumn($pColumn = 'A', $pNumCols = 1) { + if (!is_numeric($pColumn)) { + $pColumn = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::columnIndexFromString($pColumn) - 1 + $pNumCols); + $objReferenceHelper = PHPExcel_ReferenceHelper::getInstance(); + $objReferenceHelper->insertNewBefore($pColumn . '1', -$pNumCols, 0, $this); + } else { + throw new PHPExcel_Exception("Column references should not be numeric."); + } + return $this; + } + + /** + * Remove a column, updating all possible related data + * + * @param int $pColumn Remove starting with this one (numeric column coordinate of the cell) + * @param int $pNumCols Number of columns to remove + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function removeColumnByIndex($pColumn = 0, $pNumCols = 1) { + if ($pColumn >= 0) { + return $this->removeColumn(PHPExcel_Cell::stringFromColumnIndex($pColumn), $pNumCols); + } else { + throw new PHPExcel_Exception("Columns to be deleted should at least start from column 0"); + } + } + + /** + * Show gridlines? + * + * @return boolean + */ + public function getShowGridlines() { + return $this->_showGridlines; + } + + /** + * Set show gridlines + * + * @param boolean $pValue Show gridlines (true/false) + * @return PHPExcel_Worksheet + */ + public function setShowGridlines($pValue = false) { + $this->_showGridlines = $pValue; + return $this; + } + + /** + * Print gridlines? + * + * @return boolean + */ + public function getPrintGridlines() { + return $this->_printGridlines; + } + + /** + * Set print gridlines + * + * @param boolean $pValue Print gridlines (true/false) + * @return PHPExcel_Worksheet + */ + public function setPrintGridlines($pValue = false) { + $this->_printGridlines = $pValue; + return $this; + } + + /** + * Show row and column headers? + * + * @return boolean + */ + public function getShowRowColHeaders() { + return $this->_showRowColHeaders; + } + + /** + * Set show row and column headers + * + * @param boolean $pValue Show row and column headers (true/false) + * @return PHPExcel_Worksheet + */ + public function setShowRowColHeaders($pValue = false) { + $this->_showRowColHeaders = $pValue; + return $this; + } + + /** + * Show summary below? (Row/Column outlining) + * + * @return boolean + */ + public function getShowSummaryBelow() { + return $this->_showSummaryBelow; + } + + /** + * Set show summary below + * + * @param boolean $pValue Show summary below (true/false) + * @return PHPExcel_Worksheet + */ + public function setShowSummaryBelow($pValue = true) { + $this->_showSummaryBelow = $pValue; + return $this; + } + + /** + * Show summary right? (Row/Column outlining) + * + * @return boolean + */ + public function getShowSummaryRight() { + return $this->_showSummaryRight; + } + + /** + * Set show summary right + * + * @param boolean $pValue Show summary right (true/false) + * @return PHPExcel_Worksheet + */ + public function setShowSummaryRight($pValue = true) { + $this->_showSummaryRight = $pValue; + return $this; + } + + /** + * Get comments + * + * @return PHPExcel_Comment[] + */ + public function getComments() + { + return $this->_comments; + } + + /** + * Set comments array for the entire sheet. + * + * @param array of PHPExcel_Comment + * @return PHPExcel_Worksheet + */ + public function setComments($pValue = array()) + { + $this->_comments = $pValue; + + return $this; + } + + /** + * Get comment for cell + * + * @param string $pCellCoordinate Cell coordinate to get comment for + * @return PHPExcel_Comment + * @throws PHPExcel_Exception + */ + public function getComment($pCellCoordinate = 'A1') + { + // Uppercase coordinate + $pCellCoordinate = strtoupper($pCellCoordinate); + + if (strpos($pCellCoordinate,':') !== false || strpos($pCellCoordinate,',') !== false) { + throw new PHPExcel_Exception('Cell coordinate string can not be a range of cells.'); + } else if (strpos($pCellCoordinate,'$') !== false) { + throw new PHPExcel_Exception('Cell coordinate string must not be absolute.'); + } else if ($pCellCoordinate == '') { + throw new PHPExcel_Exception('Cell coordinate can not be zero-length string.'); + } else { + // Check if we already have a comment for this cell. + // If not, create a new comment. + if (isset($this->_comments[$pCellCoordinate])) { + return $this->_comments[$pCellCoordinate]; + } else { + $newComment = new PHPExcel_Comment(); + $this->_comments[$pCellCoordinate] = $newComment; + return $newComment; + } + } + } + + /** + * Get comment for cell by using numeric cell coordinates + * + * @param int $pColumn Numeric column coordinate of the cell + * @param int $pRow Numeric row coordinate of the cell + * @return PHPExcel_Comment + */ + public function getCommentByColumnAndRow($pColumn = 0, $pRow = 1) + { + return $this->getComment(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow); + } + + /** + * Get selected cell + * + * @deprecated + * @return string + */ + public function getSelectedCell() + { + return $this->getSelectedCells(); + } + + /** + * Get active cell + * + * @return string Example: 'A1' + */ + public function getActiveCell() + { + return $this->_activeCell; + } + + /** + * Get selected cells + * + * @return string + */ + public function getSelectedCells() + { + return $this->_selectedCells; + } + + /** + * Selected cell + * + * @param string $pCoordinate Cell (i.e. A1) + * @return PHPExcel_Worksheet + */ + public function setSelectedCell($pCoordinate = 'A1') + { + return $this->setSelectedCells($pCoordinate); + } + + /** + * Select a range of cells. + * + * @param string $pCoordinate Cell range, examples: 'A1', 'B2:G5', 'A:C', '3:6' + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function setSelectedCells($pCoordinate = 'A1') + { + // Uppercase coordinate + $pCoordinate = strtoupper($pCoordinate); + + // Convert 'A' to 'A:A' + $pCoordinate = preg_replace('/^([A-Z]+)$/', '${1}:${1}', $pCoordinate); + + // Convert '1' to '1:1' + $pCoordinate = preg_replace('/^([0-9]+)$/', '${1}:${1}', $pCoordinate); + + // Convert 'A:C' to 'A1:C1048576' + $pCoordinate = preg_replace('/^([A-Z]+):([A-Z]+)$/', '${1}1:${2}1048576', $pCoordinate); + + // Convert '1:3' to 'A1:XFD3' + $pCoordinate = preg_replace('/^([0-9]+):([0-9]+)$/', 'A${1}:XFD${2}', $pCoordinate); + + if (strpos($pCoordinate,':') !== false || strpos($pCoordinate,',') !== false) { + list($first, ) = PHPExcel_Cell::splitRange($pCoordinate); + $this->_activeCell = $first[0]; + } else { + $this->_activeCell = $pCoordinate; + } + $this->_selectedCells = $pCoordinate; + return $this; + } + + /** + * Selected cell by using numeric cell coordinates + * + * @param int $pColumn Numeric column coordinate of the cell + * @param int $pRow Numeric row coordinate of the cell + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function setSelectedCellByColumnAndRow($pColumn = 0, $pRow = 1) + { + return $this->setSelectedCells(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow); + } + + /** + * Get right-to-left + * + * @return boolean + */ + public function getRightToLeft() { + return $this->_rightToLeft; + } + + /** + * Set right-to-left + * + * @param boolean $value Right-to-left true/false + * @return PHPExcel_Worksheet + */ + public function setRightToLeft($value = false) { + $this->_rightToLeft = $value; + return $this; + } + + /** + * Fill worksheet from values in array + * + * @param array $source Source array + * @param mixed $nullValue Value in source array that stands for blank cell + * @param string $startCell Insert array starting from this cell address as the top left coordinate + * @param boolean $strictNullComparison Apply strict comparison when testing for null values in the array + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function fromArray($source = null, $nullValue = null, $startCell = 'A1', $strictNullComparison = false) { + if (is_array($source)) { + // Convert a 1-D array to 2-D (for ease of looping) + if (!is_array(end($source))) { + $source = array($source); + } + + // start coordinate + list ($startColumn, $startRow) = PHPExcel_Cell::coordinateFromString($startCell); + + // Loop through $source + foreach ($source as $rowData) { + $currentColumn = $startColumn; + foreach($rowData as $cellValue) { + if ($strictNullComparison) { + if ($cellValue !== $nullValue) { + // Set cell value + $this->getCell($currentColumn . $startRow)->setValue($cellValue); + } + } else { + if ($cellValue != $nullValue) { + // Set cell value + $this->getCell($currentColumn . $startRow)->setValue($cellValue); + } + } + ++$currentColumn; + } + ++$startRow; + } + } else { + throw new PHPExcel_Exception("Parameter \$source should be an array."); + } + return $this; + } + + /** + * Create array from a range of cells + * + * @param string $pRange Range of cells (i.e. "A1:B10"), or just one cell (i.e. "A1") + * @param mixed $nullValue Value returned in the array entry if a cell doesn't exist + * @param boolean $calculateFormulas Should formulas be calculated? + * @param boolean $formatData Should formatting be applied to cell values? + * @param boolean $returnCellRef False - Return a simple array of rows and columns indexed by number counting from zero + * True - Return rows and columns indexed by their actual row and column IDs + * @return array + */ + public function rangeToArray($pRange = 'A1', $nullValue = null, $calculateFormulas = true, $formatData = true, $returnCellRef = false) { + // Returnvalue + $returnValue = array(); + // Identify the range that we need to extract from the worksheet + list($rangeStart, $rangeEnd) = PHPExcel_Cell::rangeBoundaries($pRange); + $minCol = PHPExcel_Cell::stringFromColumnIndex($rangeStart[0] -1); + $minRow = $rangeStart[1]; + $maxCol = PHPExcel_Cell::stringFromColumnIndex($rangeEnd[0] -1); + $maxRow = $rangeEnd[1]; + + $maxCol++; + // Loop through rows + $r = -1; + for ($row = $minRow; $row <= $maxRow; ++$row) { + $rRef = ($returnCellRef) ? $row : ++$r; + $c = -1; + // Loop through columns in the current row + for ($col = $minCol; $col != $maxCol; ++$col) { + $cRef = ($returnCellRef) ? $col : ++$c; + // Using getCell() will create a new cell if it doesn't already exist. We don't want that to happen + // so we test and retrieve directly against _cellCollection + if ($this->_cellCollection->isDataSet($col.$row)) { + // Cell exists + $cell = $this->_cellCollection->getCacheData($col.$row); + if ($cell->getValue() !== null) { + if ($cell->getValue() instanceof PHPExcel_RichText) { + $returnValue[$rRef][$cRef] = $cell->getValue()->getPlainText(); + } else { + if ($calculateFormulas) { + $returnValue[$rRef][$cRef] = $cell->getCalculatedValue(); + } else { + $returnValue[$rRef][$cRef] = $cell->getValue(); + } + } + + if ($formatData) { + $style = $this->_parent->getCellXfByIndex($cell->getXfIndex()); + $returnValue[$rRef][$cRef] = PHPExcel_Style_NumberFormat::toFormattedString( + $returnValue[$rRef][$cRef], + ($style && $style->getNumberFormat()) ? + $style->getNumberFormat()->getFormatCode() : + PHPExcel_Style_NumberFormat::FORMAT_GENERAL + ); + } + } else { + // Cell holds a NULL + $returnValue[$rRef][$cRef] = $nullValue; + } + } else { + // Cell doesn't exist + $returnValue[$rRef][$cRef] = $nullValue; + } + } + } + + // Return + return $returnValue; + } + + + /** + * Create array from a range of cells + * + * @param string $pNamedRange Name of the Named Range + * @param mixed $nullValue Value returned in the array entry if a cell doesn't exist + * @param boolean $calculateFormulas Should formulas be calculated? + * @param boolean $formatData Should formatting be applied to cell values? + * @param boolean $returnCellRef False - Return a simple array of rows and columns indexed by number counting from zero + * True - Return rows and columns indexed by their actual row and column IDs + * @return array + * @throws PHPExcel_Exception + */ + public function namedRangeToArray($pNamedRange = '', $nullValue = null, $calculateFormulas = true, $formatData = true, $returnCellRef = false) { + $namedRange = PHPExcel_NamedRange::resolveRange($pNamedRange, $this); + if ($namedRange !== NULL) { + $pWorkSheet = $namedRange->getWorksheet(); + $pCellRange = $namedRange->getRange(); + + return $pWorkSheet->rangeToArray( $pCellRange, + $nullValue, $calculateFormulas, $formatData, $returnCellRef); + } + + throw new PHPExcel_Exception('Named Range '.$pNamedRange.' does not exist.'); + } + + + /** + * Create array from worksheet + * + * @param mixed $nullValue Value returned in the array entry if a cell doesn't exist + * @param boolean $calculateFormulas Should formulas be calculated? + * @param boolean $formatData Should formatting be applied to cell values? + * @param boolean $returnCellRef False - Return a simple array of rows and columns indexed by number counting from zero + * True - Return rows and columns indexed by their actual row and column IDs + * @return array + */ + public function toArray($nullValue = null, $calculateFormulas = true, $formatData = true, $returnCellRef = false) { + // Garbage collect... + $this->garbageCollect(); + + // Identify the range that we need to extract from the worksheet + $maxCol = $this->getHighestColumn(); + $maxRow = $this->getHighestRow(); + // Return + return $this->rangeToArray( 'A1:'.$maxCol.$maxRow, + $nullValue, $calculateFormulas, $formatData, $returnCellRef); + } + + /** + * Get row iterator + * + * @param integer $startRow The row number at which to start iterating + * @return PHPExcel_Worksheet_RowIterator + */ + public function getRowIterator($startRow = 1) { + return new PHPExcel_Worksheet_RowIterator($this,$startRow); + } + + /** + * Run PHPExcel garabage collector. + * + * @return PHPExcel_Worksheet + */ + public function garbageCollect() { + // Flush cache + $this->_cellCollection->getCacheData('A1'); + // Build a reference table from images +// $imageCoordinates = array(); +// $iterator = $this->getDrawingCollection()->getIterator(); +// while ($iterator->valid()) { +// $imageCoordinates[$iterator->current()->getCoordinates()] = true; +// +// $iterator->next(); +// } +// + // Lookup highest column and highest row if cells are cleaned + $colRow = $this->_cellCollection->getHighestRowAndColumn(); + $highestRow = $colRow['row']; + $highestColumn = PHPExcel_Cell::columnIndexFromString($colRow['column']); + + // Loop through column dimensions + foreach ($this->_columnDimensions as $dimension) { + $highestColumn = max($highestColumn,PHPExcel_Cell::columnIndexFromString($dimension->getColumnIndex())); + } + + // Loop through row dimensions + foreach ($this->_rowDimensions as $dimension) { + $highestRow = max($highestRow,$dimension->getRowIndex()); + } + + // Cache values + if ($highestColumn < 0) { + $this->_cachedHighestColumn = 'A'; + } else { + $this->_cachedHighestColumn = PHPExcel_Cell::stringFromColumnIndex(--$highestColumn); + } + $this->_cachedHighestRow = $highestRow; + + // Return + return $this; + } + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() { + if ($this->_dirty) { + $this->_hash = md5( $this->_title . + $this->_autoFilter . + ($this->_protection->isProtectionEnabled() ? 't' : 'f') . + __CLASS__ + ); + $this->_dirty = false; + } + return $this->_hash; + } + + /** + * Extract worksheet title from range. + * + * Example: extractSheetTitle("testSheet!A1") ==> 'A1' + * Example: extractSheetTitle("'testSheet 1'!A1", true) ==> array('testSheet 1', 'A1'); + * + * @param string $pRange Range to extract title from + * @param bool $returnRange Return range? (see example) + * @return mixed + */ + public static function extractSheetTitle($pRange, $returnRange = false) { + // Sheet title included? + if (($sep = strpos($pRange, '!')) === false) { + return ''; + } + + if ($returnRange) { + return array( trim(substr($pRange, 0, $sep),"'"), + substr($pRange, $sep + 1) + ); + } + + return substr($pRange, $sep + 1); + } + + /** + * Get hyperlink + * + * @param string $pCellCoordinate Cell coordinate to get hyperlink for + */ + public function getHyperlink($pCellCoordinate = 'A1') + { + // return hyperlink if we already have one + if (isset($this->_hyperlinkCollection[$pCellCoordinate])) { + return $this->_hyperlinkCollection[$pCellCoordinate]; + } + + // else create hyperlink + $this->_hyperlinkCollection[$pCellCoordinate] = new PHPExcel_Cell_Hyperlink(); + return $this->_hyperlinkCollection[$pCellCoordinate]; + } + + /** + * Set hyperlnk + * + * @param string $pCellCoordinate Cell coordinate to insert hyperlink + * @param PHPExcel_Cell_Hyperlink $pHyperlink + * @return PHPExcel_Worksheet + */ + public function setHyperlink($pCellCoordinate = 'A1', PHPExcel_Cell_Hyperlink $pHyperlink = null) + { + if ($pHyperlink === null) { + unset($this->_hyperlinkCollection[$pCellCoordinate]); + } else { + $this->_hyperlinkCollection[$pCellCoordinate] = $pHyperlink; + } + return $this; + } + + /** + * Hyperlink at a specific coordinate exists? + * + * @param string $pCoordinate + * @return boolean + */ + public function hyperlinkExists($pCoordinate = 'A1') + { + return isset($this->_hyperlinkCollection[$pCoordinate]); + } + + /** + * Get collection of hyperlinks + * + * @return PHPExcel_Cell_Hyperlink[] + */ + public function getHyperlinkCollection() + { + return $this->_hyperlinkCollection; + } + + /** + * Get data validation + * + * @param string $pCellCoordinate Cell coordinate to get data validation for + */ + public function getDataValidation($pCellCoordinate = 'A1') + { + // return data validation if we already have one + if (isset($this->_dataValidationCollection[$pCellCoordinate])) { + return $this->_dataValidationCollection[$pCellCoordinate]; + } + + // else create data validation + $this->_dataValidationCollection[$pCellCoordinate] = new PHPExcel_Cell_DataValidation(); + return $this->_dataValidationCollection[$pCellCoordinate]; + } + + /** + * Set data validation + * + * @param string $pCellCoordinate Cell coordinate to insert data validation + * @param PHPExcel_Cell_DataValidation $pDataValidation + * @return PHPExcel_Worksheet + */ + public function setDataValidation($pCellCoordinate = 'A1', PHPExcel_Cell_DataValidation $pDataValidation = null) + { + if ($pDataValidation === null) { + unset($this->_dataValidationCollection[$pCellCoordinate]); + } else { + $this->_dataValidationCollection[$pCellCoordinate] = $pDataValidation; + } + return $this; + } + + /** + * Data validation at a specific coordinate exists? + * + * @param string $pCoordinate + * @return boolean + */ + public function dataValidationExists($pCoordinate = 'A1') + { + return isset($this->_dataValidationCollection[$pCoordinate]); + } + + /** + * Get collection of data validations + * + * @return PHPExcel_Cell_DataValidation[] + */ + public function getDataValidationCollection() + { + return $this->_dataValidationCollection; + } + + /** + * Accepts a range, returning it as a range that falls within the current highest row and column of the worksheet + * + * @param string $range + * @return string Adjusted range value + */ + public function shrinkRangeToFit($range) { + $maxCol = $this->getHighestColumn(); + $maxRow = $this->getHighestRow(); + $maxCol = PHPExcel_Cell::columnIndexFromString($maxCol); + + $rangeBlocks = explode(' ',$range); + foreach ($rangeBlocks as &$rangeSet) { + $rangeBoundaries = PHPExcel_Cell::getRangeBoundaries($rangeSet); + + if (PHPExcel_Cell::columnIndexFromString($rangeBoundaries[0][0]) > $maxCol) { $rangeBoundaries[0][0] = PHPExcel_Cell::stringFromColumnIndex($maxCol); } + if ($rangeBoundaries[0][1] > $maxRow) { $rangeBoundaries[0][1] = $maxRow; } + if (PHPExcel_Cell::columnIndexFromString($rangeBoundaries[1][0]) > $maxCol) { $rangeBoundaries[1][0] = PHPExcel_Cell::stringFromColumnIndex($maxCol); } + if ($rangeBoundaries[1][1] > $maxRow) { $rangeBoundaries[1][1] = $maxRow; } + $rangeSet = $rangeBoundaries[0][0].$rangeBoundaries[0][1].':'.$rangeBoundaries[1][0].$rangeBoundaries[1][1]; + } + unset($rangeSet); + $stRange = implode(' ',$rangeBlocks); + + return $stRange; + } + + /** + * Get tab color + * + * @return PHPExcel_Style_Color + */ + public function getTabColor() + { + if ($this->_tabColor === NULL) + $this->_tabColor = new PHPExcel_Style_Color(); + + return $this->_tabColor; + } + + /** + * Reset tab color + * + * @return PHPExcel_Worksheet + */ + public function resetTabColor() + { + $this->_tabColor = null; + unset($this->_tabColor); + + return $this; + } + + /** + * Tab color set? + * + * @return boolean + */ + public function isTabColorSet() + { + return ($this->_tabColor !== NULL); + } + + /** + * Copy worksheet (!= clone!) + * + * @return PHPExcel_Worksheet + */ + public function copy() { + $copied = clone $this; + + return $copied; + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + foreach ($this as $key => $val) { + if ($key == '_parent') { + continue; + } + + if (is_object($val) || (is_array($val))) { + if ($key == '_cellCollection') { + $newCollection = clone $this->_cellCollection; + $newCollection->copyCellCollection($this); + $this->_cellCollection = $newCollection; + } elseif ($key == '_drawingCollection') { + $newCollection = clone $this->_drawingCollection; + $this->_drawingCollection = $newCollection; + } elseif (($key == '_autoFilter') && ($this->_autoFilter instanceof PHPExcel_Worksheet_AutoFilter)) { + $newAutoFilter = clone $this->_autoFilter; + $this->_autoFilter = $newAutoFilter; + $this->_autoFilter->setParent($this); + } else { + $this->{$key} = unserialize(serialize($val)); + } + } + } + } +/** + * Define the code name of the sheet + * + * @param null|string Same rule as Title minus space not allowed (but, like Excel, change silently space to underscore) + * @return objWorksheet + * @throws PHPExcel_Exception + */ + public function setCodeName($pValue=null){ + // Is this a 'rename' or not? + if ($this->getCodeName() == $pValue) { + return $this; + } + $pValue = str_replace(' ', '_', $pValue);//Excel does this automatically without flinching, we are doing the same + // Syntax check + // throw an exception if not valid + self::_checkSheetCodeName($pValue); + + // We use the same code that setTitle to find a valid codeName else not using a space (Excel don't like) but a '_' + + if ($this->getParent()) { + // Is there already such sheet name? + if ($this->getParent()->sheetCodeNameExists($pValue)) { + // Use name, but append with lowest possible integer + + if (PHPExcel_Shared_String::CountCharacters($pValue) > 29) { + $pValue = PHPExcel_Shared_String::Substring($pValue,0,29); + } + $i = 1; + while ($this->getParent()->sheetCodeNameExists($pValue . '_' . $i)) { + ++$i; + if ($i == 10) { + if (PHPExcel_Shared_String::CountCharacters($pValue) > 28) { + $pValue = PHPExcel_Shared_String::Substring($pValue,0,28); + } + } elseif ($i == 100) { + if (PHPExcel_Shared_String::CountCharacters($pValue) > 27) { + $pValue = PHPExcel_Shared_String::Substring($pValue,0,27); + } + } + } + + $pValue = $pValue . '_' . $i;// ok, we have a valid name + //codeName is'nt used in formula : no need to call for an update + //return $this->setTitle($altTitle,$updateFormulaCellReferences); + } + } + + $this->_codeName=$pValue; + return $this; + } + /** + * Return the code name of the sheet + * + * @return null|string + */ + public function getCodeName(){ + return $this->_codeName; + } + /** + * Sheet has a code name ? + * @return boolean + */ + public function hasCodeName(){ + return !(is_null($this->_codeName)); + } +} diff --git a/lib/phpexcel/PHPExcel/Worksheet/AutoFilter.php b/lib/phpexcel/PHPExcel/Worksheet/AutoFilter.php new file mode 100644 index 0000000..03055e1 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Worksheet/AutoFilter.php @@ -0,0 +1,858 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Worksheet_AutoFilter + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Worksheet_AutoFilter +{ + /** + * Autofilter Worksheet + * + * @var PHPExcel_Worksheet + */ + private $_workSheet = NULL; + + + /** + * Autofilter Range + * + * @var string + */ + private $_range = ''; + + + /** + * Autofilter Column Ruleset + * + * @var array of PHPExcel_Worksheet_AutoFilter_Column + */ + private $_columns = array(); + + + /** + * Create a new PHPExcel_Worksheet_AutoFilter + * + * @param string $pRange Cell range (i.e. A1:E10) + * @param PHPExcel_Worksheet $pSheet + */ + public function __construct($pRange = '', PHPExcel_Worksheet $pSheet = NULL) + { + $this->_range = $pRange; + $this->_workSheet = $pSheet; + } + + /** + * Get AutoFilter Parent Worksheet + * + * @return PHPExcel_Worksheet + */ + public function getParent() { + return $this->_workSheet; + } + + /** + * Set AutoFilter Parent Worksheet + * + * @param PHPExcel_Worksheet $pSheet + * @return PHPExcel_Worksheet_AutoFilter + */ + public function setParent(PHPExcel_Worksheet $pSheet = NULL) { + $this->_workSheet = $pSheet; + + return $this; + } + + /** + * Get AutoFilter Range + * + * @return string + */ + public function getRange() { + return $this->_range; + } + + /** + * Set AutoFilter Range + * + * @param string $pRange Cell range (i.e. A1:E10) + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter + */ + public function setRange($pRange = '') { + // Uppercase coordinate + $cellAddress = explode('!',strtoupper($pRange)); + if (count($cellAddress) > 1) { + list($worksheet,$pRange) = $cellAddress; + } + + if (strpos($pRange,':') !== FALSE) { + $this->_range = $pRange; + } elseif(empty($pRange)) { + $this->_range = ''; + } else { + throw new PHPExcel_Exception('Autofilter must be set on a range of cells.'); + } + + if (empty($pRange)) { + // Discard all column rules + $this->_columns = array(); + } else { + // Discard any column rules that are no longer valid within this range + list($rangeStart,$rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->_range); + foreach($this->_columns as $key => $value) { + $colIndex = PHPExcel_Cell::columnIndexFromString($key); + if (($rangeStart[0] > $colIndex) || ($rangeEnd[0] < $colIndex)) { + unset($this->_columns[$key]); + } + } + } + + return $this; + } + + /** + * Get all AutoFilter Columns + * + * @throws PHPExcel_Exception + * @return array of PHPExcel_Worksheet_AutoFilter_Column + */ + public function getColumns() { + return $this->_columns; + } + + /** + * Validate that the specified column is in the AutoFilter range + * + * @param string $column Column name (e.g. A) + * @throws PHPExcel_Exception + * @return integer The column offset within the autofilter range + */ + public function testColumnInRange($column) { + if (empty($this->_range)) { + throw new PHPExcel_Exception("No autofilter range is defined."); + } + + $columnIndex = PHPExcel_Cell::columnIndexFromString($column); + list($rangeStart,$rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->_range); + if (($rangeStart[0] > $columnIndex) || ($rangeEnd[0] < $columnIndex)) { + throw new PHPExcel_Exception("Column is outside of current autofilter range."); + } + + return $columnIndex - $rangeStart[0]; + } + + /** + * Get a specified AutoFilter Column Offset within the defined AutoFilter range + * + * @param string $pColumn Column name (e.g. A) + * @throws PHPExcel_Exception + * @return integer The offset of the specified column within the autofilter range + */ + public function getColumnOffset($pColumn) { + return $this->testColumnInRange($pColumn); + } + + /** + * Get a specified AutoFilter Column + * + * @param string $pColumn Column name (e.g. A) + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter_Column + */ + public function getColumn($pColumn) { + $this->testColumnInRange($pColumn); + + if (!isset($this->_columns[$pColumn])) { + $this->_columns[$pColumn] = new PHPExcel_Worksheet_AutoFilter_Column($pColumn, $this); + } + + return $this->_columns[$pColumn]; + } + + /** + * Get a specified AutoFilter Column by it's offset + * + * @param integer $pColumnOffset Column offset within range (starting from 0) + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter_Column + */ + public function getColumnByOffset($pColumnOffset = 0) { + list($rangeStart,$rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->_range); + $pColumn = PHPExcel_Cell::stringFromColumnIndex($rangeStart[0] + $pColumnOffset - 1); + + return $this->getColumn($pColumn); + } + + /** + * Set AutoFilter + * + * @param PHPExcel_Worksheet_AutoFilter_Column|string $pColumn + * A simple string containing a Column ID like 'A' is permitted + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter + */ + public function setColumn($pColumn) + { + if ((is_string($pColumn)) && (!empty($pColumn))) { + $column = $pColumn; + } elseif(is_object($pColumn) && ($pColumn instanceof PHPExcel_Worksheet_AutoFilter_Column)) { + $column = $pColumn->getColumnIndex(); + } else { + throw new PHPExcel_Exception("Column is not within the autofilter range."); + } + $this->testColumnInRange($column); + + if (is_string($pColumn)) { + $this->_columns[$pColumn] = new PHPExcel_Worksheet_AutoFilter_Column($pColumn, $this); + } elseif(is_object($pColumn) && ($pColumn instanceof PHPExcel_Worksheet_AutoFilter_Column)) { + $pColumn->setParent($this); + $this->_columns[$column] = $pColumn; + } + ksort($this->_columns); + + return $this; + } + + /** + * Clear a specified AutoFilter Column + * + * @param string $pColumn Column name (e.g. A) + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter + */ + public function clearColumn($pColumn) { + $this->testColumnInRange($pColumn); + + if (isset($this->_columns[$pColumn])) { + unset($this->_columns[$pColumn]); + } + + return $this; + } + + /** + * Shift an AutoFilter Column Rule to a different column + * + * Note: This method bypasses validation of the destination column to ensure it is within this AutoFilter range. + * Nor does it verify whether any column rule already exists at $toColumn, but will simply overrideany existing value. + * Use with caution. + * + * @param string $fromColumn Column name (e.g. A) + * @param string $toColumn Column name (e.g. B) + * @return PHPExcel_Worksheet_AutoFilter + */ + public function shiftColumn($fromColumn=NULL,$toColumn=NULL) { + $fromColumn = strtoupper($fromColumn); + $toColumn = strtoupper($toColumn); + + if (($fromColumn !== NULL) && (isset($this->_columns[$fromColumn])) && ($toColumn !== NULL)) { + $this->_columns[$fromColumn]->setParent(); + $this->_columns[$fromColumn]->setColumnIndex($toColumn); + $this->_columns[$toColumn] = $this->_columns[$fromColumn]; + $this->_columns[$toColumn]->setParent($this); + unset($this->_columns[$fromColumn]); + + ksort($this->_columns); + } + + return $this; + } + + + /** + * Test if cell value is in the defined set of values + * + * @param mixed $cellValue + * @param mixed[] $dataSet + * @return boolean + */ + private static function _filterTestInSimpleDataSet($cellValue,$dataSet) + { + $dataSetValues = $dataSet['filterValues']; + $blanks = $dataSet['blanks']; + if (($cellValue == '') || ($cellValue === NULL)) { + return $blanks; + } + return in_array($cellValue,$dataSetValues); + } + + /** + * Test if cell value is in the defined set of Excel date values + * + * @param mixed $cellValue + * @param mixed[] $dataSet + * @return boolean + */ + private static function _filterTestInDateGroupSet($cellValue,$dataSet) + { + $dateSet = $dataSet['filterValues']; + $blanks = $dataSet['blanks']; + if (($cellValue == '') || ($cellValue === NULL)) { + return $blanks; + } + + if (is_numeric($cellValue)) { + $dateValue = PHPExcel_Shared_Date::ExcelToPHP($cellValue); + if ($cellValue < 1) { + // Just the time part + $dtVal = date('His',$dateValue); + $dateSet = $dateSet['time']; + } elseif($cellValue == floor($cellValue)) { + // Just the date part + $dtVal = date('Ymd',$dateValue); + $dateSet = $dateSet['date']; + } else { + // date and time parts + $dtVal = date('YmdHis',$dateValue); + $dateSet = $dateSet['dateTime']; + } + foreach($dateSet as $dateValue) { + // Use of substr to extract value at the appropriate group level + if (substr($dtVal,0,strlen($dateValue)) == $dateValue) + return TRUE; + } + } + + return FALSE; + } + + /** + * Test if cell value is within a set of values defined by a ruleset + * + * @param mixed $cellValue + * @param mixed[] $ruleSet + * @return boolean + */ + private static function _filterTestInCustomDataSet($cellValue, $ruleSet) + { + $dataSet = $ruleSet['filterRules']; + $join = $ruleSet['join']; + $customRuleForBlanks = isset($ruleSet['customRuleForBlanks']) ? $ruleSet['customRuleForBlanks'] : FALSE; + + if (!$customRuleForBlanks) { + // Blank cells are always ignored, so return a FALSE + if (($cellValue == '') || ($cellValue === NULL)) { + return FALSE; + } + } + $returnVal = ($join == PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND); + foreach($dataSet as $rule) { + if (is_numeric($rule['value'])) { + // Numeric values are tested using the appropriate operator + switch ($rule['operator']) { + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL : + $retVal = ($cellValue == $rule['value']); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_NOTEQUAL : + $retVal = ($cellValue != $rule['value']); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHAN : + $retVal = ($cellValue > $rule['value']); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL : + $retVal = ($cellValue >= $rule['value']); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHAN : + $retVal = ($cellValue < $rule['value']); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL : + $retVal = ($cellValue <= $rule['value']); + break; + } + } elseif($rule['value'] == '') { + switch ($rule['operator']) { + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL : + $retVal = (($cellValue == '') || ($cellValue === NULL)); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_NOTEQUAL : + $retVal = (($cellValue != '') && ($cellValue !== NULL)); + break; + default : + $retVal = TRUE; + break; + } + } else { + // String values are always tested for equality, factoring in for wildcards (hence a regexp test) + $retVal = preg_match('/^'.$rule['value'].'$/i',$cellValue); + } + // If there are multiple conditions, then we need to test both using the appropriate join operator + switch ($join) { + case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_OR : + $returnVal = $returnVal || $retVal; + // Break as soon as we have a TRUE match for OR joins, + // to avoid unnecessary additional code execution + if ($returnVal) + return $returnVal; + break; + case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND : + $returnVal = $returnVal && $retVal; + break; + } + } + + return $returnVal; + } + + /** + * Test if cell date value is matches a set of values defined by a set of months + * + * @param mixed $cellValue + * @param mixed[] $monthSet + * @return boolean + */ + private static function _filterTestInPeriodDateSet($cellValue, $monthSet) + { + // Blank cells are always ignored, so return a FALSE + if (($cellValue == '') || ($cellValue === NULL)) { + return FALSE; + } + + if (is_numeric($cellValue)) { + $dateValue = date('m',PHPExcel_Shared_Date::ExcelToPHP($cellValue)); + if (in_array($dateValue,$monthSet)) { + return TRUE; + } + } + + return FALSE; + } + + /** + * Search/Replace arrays to convert Excel wildcard syntax to a regexp syntax for preg_matching + * + * @var array + */ + private static $_fromReplace = array('\*', '\?', '~~', '~.*', '~.?'); + private static $_toReplace = array('.*', '.', '~', '\*', '\?'); + + + /** + * Convert a dynamic rule daterange to a custom filter range expression for ease of calculation + * + * @param string $dynamicRuleType + * @param PHPExcel_Worksheet_AutoFilter_Column &$filterColumn + * @return mixed[] + */ + private function _dynamicFilterDateRange($dynamicRuleType, &$filterColumn) + { + $rDateType = PHPExcel_Calculation_Functions::getReturnDateType(); + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC); + $val = $maxVal = NULL; + + $ruleValues = array(); + $baseDate = PHPExcel_Calculation_DateTime::DATENOW(); + // Calculate start/end dates for the required date range based on current date + switch ($dynamicRuleType) { + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTWEEK : + $baseDate = strtotime('-7 days',$baseDate); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTWEEK : + $baseDate = strtotime('-7 days',$baseDate); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTMONTH : + $baseDate = strtotime('-1 month',gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate))); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTMONTH : + $baseDate = strtotime('+1 month',gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate))); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTQUARTER : + $baseDate = strtotime('-3 month',gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate))); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTQUARTER : + $baseDate = strtotime('+3 month',gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate))); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTYEAR : + $baseDate = strtotime('-1 year',gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate))); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTYEAR : + $baseDate = strtotime('+1 year',gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate))); + break; + } + + switch ($dynamicRuleType) { + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_TODAY : + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_YESTERDAY : + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_TOMORROW : + $maxVal = (int) PHPExcel_Shared_Date::PHPtoExcel(strtotime('+1 day',$baseDate)); + $val = (int) PHPExcel_Shared_Date::PHPToExcel($baseDate); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_YEARTODATE : + $maxVal = (int) PHPExcel_Shared_Date::PHPtoExcel(strtotime('+1 day',$baseDate)); + $val = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0,0,0,1,1,date('Y',$baseDate))); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISYEAR : + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTYEAR : + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTYEAR : + $maxVal = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0,0,0,31,12,date('Y',$baseDate))); + ++$maxVal; + $val = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0,0,0,1,1,date('Y',$baseDate))); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISQUARTER : + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTQUARTER : + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTQUARTER : + $thisMonth = date('m',$baseDate); + $thisQuarter = floor(--$thisMonth / 3); + $maxVal = (int) PHPExcel_Shared_Date::PHPtoExcel(gmmktime(0,0,0,date('t',$baseDate),(1+$thisQuarter)*3,date('Y',$baseDate))); + ++$maxVal; + $val = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0,0,0,1,1+$thisQuarter*3,date('Y',$baseDate))); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISMONTH : + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTMONTH : + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTMONTH : + $maxVal = (int) PHPExcel_Shared_Date::PHPtoExcel(gmmktime(0,0,0,date('t',$baseDate),date('m',$baseDate),date('Y',$baseDate))); + ++$maxVal; + $val = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate))); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISWEEK : + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTWEEK : + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTWEEK : + $dayOfWeek = date('w',$baseDate); + $val = (int) PHPExcel_Shared_Date::PHPToExcel($baseDate) - $dayOfWeek; + $maxVal = $val + 7; + break; + } + + switch ($dynamicRuleType) { + // Adjust Today dates for Yesterday and Tomorrow + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_YESTERDAY : + --$maxVal; + --$val; + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_TOMORROW : + ++$maxVal; + ++$val; + break; + } + + // Set the filter column rule attributes ready for writing + $filterColumn->setAttributes(array( 'val' => $val, + 'maxVal' => $maxVal + ) + ); + + // Set the rules for identifying rows for hide/show + $ruleValues[] = array( 'operator' => PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL, + 'value' => $val + ); + $ruleValues[] = array( 'operator' => PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHAN, + 'value' => $maxVal + ); + PHPExcel_Calculation_Functions::setReturnDateType($rDateType); + + return array( + 'method' => '_filterTestInCustomDataSet', + 'arguments' => array( 'filterRules' => $ruleValues, + 'join' => PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND + ) + ); + } + + private function _calculateTopTenValue($columnID,$startRow,$endRow,$ruleType,$ruleValue) { + $range = $columnID.$startRow.':'.$columnID.$endRow; + $dataValues = PHPExcel_Calculation_Functions::flattenArray( + $this->_workSheet->rangeToArray($range,NULL,TRUE,FALSE) + ); + + $dataValues = array_filter($dataValues); + if ($ruleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP) { + rsort($dataValues); + } else { + sort($dataValues); + } + + return array_pop(array_slice($dataValues,0,$ruleValue)); + } + + /** + * Apply the AutoFilter rules to the AutoFilter Range + * + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter + */ + public function showHideRows() + { + list($rangeStart,$rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->_range); + + // The heading row should always be visible +// echo 'AutoFilter Heading Row ',$rangeStart[1],' is always SHOWN',PHP_EOL; + $this->_workSheet->getRowDimension($rangeStart[1])->setVisible(TRUE); + + $columnFilterTests = array(); + foreach($this->_columns as $columnID => $filterColumn) { + $rules = $filterColumn->getRules(); + switch ($filterColumn->getFilterType()) { + case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER : + $ruleValues = array(); + // Build a list of the filter value selections + foreach($rules as $rule) { + $ruleType = $rule->getRuleType(); + $ruleValues[] = $rule->getValue(); + } + // Test if we want to include blanks in our filter criteria + $blanks = FALSE; + $ruleDataSet = array_filter($ruleValues); + if (count($ruleValues) != count($ruleDataSet)) + $blanks = TRUE; + if ($ruleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_FILTER) { + // Filter on absolute values + $columnFilterTests[$columnID] = array( + 'method' => '_filterTestInSimpleDataSet', + 'arguments' => array( 'filterValues' => $ruleDataSet, + 'blanks' => $blanks + ) + ); + } else { + // Filter on date group values + $arguments = array(); + foreach($ruleDataSet as $ruleValue) { + $date = $time = ''; + if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_YEAR])) && + ($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_YEAR] !== '')) + $date .= sprintf('%04d',$ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_YEAR]); + if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MONTH])) && + ($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MONTH] != '')) + $date .= sprintf('%02d',$ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MONTH]); + if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_DAY])) && + ($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_DAY] !== '')) + $date .= sprintf('%02d',$ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_DAY]); + if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_HOUR])) && + ($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_HOUR] !== '')) + $time .= sprintf('%02d',$ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_HOUR]); + if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MINUTE])) && + ($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MINUTE] !== '')) + $time .= sprintf('%02d',$ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MINUTE]); + if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_SECOND])) && + ($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_SECOND] !== '')) + $time .= sprintf('%02d',$ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_SECOND]); + $dateTime = $date . $time; + $arguments['date'][] = $date; + $arguments['time'][] = $time; + $arguments['dateTime'][] = $dateTime; + } + // Remove empty elements + $arguments['date'] = array_filter($arguments['date']); + $arguments['time'] = array_filter($arguments['time']); + $arguments['dateTime'] = array_filter($arguments['dateTime']); + $columnFilterTests[$columnID] = array( + 'method' => '_filterTestInDateGroupSet', + 'arguments' => array( 'filterValues' => $arguments, + 'blanks' => $blanks + ) + ); + } + break; + case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_CUSTOMFILTER : + $customRuleForBlanks = FALSE; + $ruleValues = array(); + // Build a list of the filter value selections + foreach($rules as $rule) { + $ruleType = $rule->getRuleType(); + $ruleValue = $rule->getValue(); + if (!is_numeric($ruleValue)) { + // Convert to a regexp allowing for regexp reserved characters, wildcards and escaped wildcards + $ruleValue = preg_quote($ruleValue); + $ruleValue = str_replace(self::$_fromReplace,self::$_toReplace,$ruleValue); + if (trim($ruleValue) == '') { + $customRuleForBlanks = TRUE; + $ruleValue = trim($ruleValue); + } + } + $ruleValues[] = array( 'operator' => $rule->getOperator(), + 'value' => $ruleValue + ); + } + $join = $filterColumn->getJoin(); + $columnFilterTests[$columnID] = array( + 'method' => '_filterTestInCustomDataSet', + 'arguments' => array( 'filterRules' => $ruleValues, + 'join' => $join, + 'customRuleForBlanks' => $customRuleForBlanks + ) + ); + break; + case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER : + $ruleValues = array(); + foreach($rules as $rule) { + // We should only ever have one Dynamic Filter Rule anyway + $dynamicRuleType = $rule->getGrouping(); + if (($dynamicRuleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_ABOVEAVERAGE) || + ($dynamicRuleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_BELOWAVERAGE)) { + // Number (Average) based + // Calculate the average + $averageFormula = '=AVERAGE('.$columnID.($rangeStart[1]+1).':'.$columnID.$rangeEnd[1].')'; + $average = PHPExcel_Calculation::getInstance()->calculateFormula($averageFormula,NULL,$this->_workSheet->getCell('A1')); + // Set above/below rule based on greaterThan or LessTan + $operator = ($dynamicRuleType === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_ABOVEAVERAGE) + ? PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHAN + : PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHAN; + $ruleValues[] = array( 'operator' => $operator, + 'value' => $average + ); + $columnFilterTests[$columnID] = array( + 'method' => '_filterTestInCustomDataSet', + 'arguments' => array( 'filterRules' => $ruleValues, + 'join' => PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_OR + ) + ); + } else { + // Date based + if ($dynamicRuleType{0} == 'M' || $dynamicRuleType{0} == 'Q') { + // Month or Quarter + sscanf($dynamicRuleType,'%[A-Z]%d', $periodType, $period); + if ($periodType == 'M') { + $ruleValues = array($period); + } else { + --$period; + $periodEnd = (1+$period)*3; + $periodStart = 1+$period*3; + $ruleValues = range($periodStart,periodEnd); + } + $columnFilterTests[$columnID] = array( + 'method' => '_filterTestInPeriodDateSet', + 'arguments' => $ruleValues + ); + $filterColumn->setAttributes(array()); + } else { + // Date Range + $columnFilterTests[$columnID] = $this->_dynamicFilterDateRange($dynamicRuleType, $filterColumn); + break; + } + } + } + break; + case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_TOPTENFILTER : + $ruleValues = array(); + $dataRowCount = $rangeEnd[1] - $rangeStart[1]; + foreach($rules as $rule) { + // We should only ever have one Dynamic Filter Rule anyway + $toptenRuleType = $rule->getGrouping(); + $ruleValue = $rule->getValue(); + $ruleOperator = $rule->getOperator(); + } + if ($ruleOperator === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT) { + $ruleValue = floor($ruleValue * ($dataRowCount / 100)); + } + if ($ruleValue < 1) $ruleValue = 1; + if ($ruleValue > 500) $ruleValue = 500; + + $maxVal = $this->_calculateTopTenValue($columnID,$rangeStart[1]+1,$rangeEnd[1],$toptenRuleType,$ruleValue); + + $operator = ($toptenRuleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP) + ? PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL + : PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL; + $ruleValues[] = array( 'operator' => $operator, + 'value' => $maxVal + ); + $columnFilterTests[$columnID] = array( + 'method' => '_filterTestInCustomDataSet', + 'arguments' => array( 'filterRules' => $ruleValues, + 'join' => PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_OR + ) + ); + $filterColumn->setAttributes( + array('maxVal' => $maxVal) + ); + break; + } + } + +// echo 'Column Filter Test CRITERIA',PHP_EOL; +// var_dump($columnFilterTests); +// + // Execute the column tests for each row in the autoFilter range to determine show/hide, + for ($row = $rangeStart[1]+1; $row <= $rangeEnd[1]; ++$row) { +// echo 'Testing Row = ',$row,PHP_EOL; + $result = TRUE; + foreach($columnFilterTests as $columnID => $columnFilterTest) { +// echo 'Testing cell ',$columnID.$row,PHP_EOL; + $cellValue = $this->_workSheet->getCell($columnID.$row)->getCalculatedValue(); +// echo 'Value is ',$cellValue,PHP_EOL; + // Execute the filter test + $result = $result && + call_user_func_array( + array('PHPExcel_Worksheet_AutoFilter',$columnFilterTest['method']), + array( + $cellValue, + $columnFilterTest['arguments'] + ) + ); +// echo (($result) ? 'VALID' : 'INVALID'),PHP_EOL; + // If filter test has resulted in FALSE, exit the loop straightaway rather than running any more tests + if (!$result) + break; + } + // Set show/hide for the row based on the result of the autoFilter result +// echo (($result) ? 'SHOW' : 'HIDE'),PHP_EOL; + $this->_workSheet->getRowDimension($row)->setVisible($result); + } + + return $this; + } + + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + if ($key == '_workSheet') { + // Detach from worksheet + $this->{$key} = NULL; + } else { + $this->{$key} = clone $value; + } + } elseif ((is_array($value)) && ($key == '_columns')) { + // The columns array of PHPExcel_Worksheet_AutoFilter objects + $this->{$key} = array(); + foreach ($value as $k => $v) { + $this->{$key}[$k] = clone $v; + // attach the new cloned Column to this new cloned Autofilter object + $this->{$key}[$k]->setParent($this); + } + } else { + $this->{$key} = $value; + } + } + } + + /** + * toString method replicates previous behavior by returning the range if object is + * referenced as a property of its parent. + */ + public function __toString() { + return (string) $this->_range; + } + +} diff --git a/lib/phpexcel/PHPExcel/Worksheet/AutoFilter/Column.php b/lib/phpexcel/PHPExcel/Worksheet/AutoFilter/Column.php new file mode 100644 index 0000000..12043d5 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Worksheet/AutoFilter/Column.php @@ -0,0 +1,394 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Worksheet_AutoFilter_Column + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Worksheet_AutoFilter_Column +{ + const AUTOFILTER_FILTERTYPE_FILTER = 'filters'; + const AUTOFILTER_FILTERTYPE_CUSTOMFILTER = 'customFilters'; + // Supports no more than 2 rules, with an And/Or join criteria + // if more than 1 rule is defined + const AUTOFILTER_FILTERTYPE_DYNAMICFILTER = 'dynamicFilter'; + // Even though the filter rule is constant, the filtered data can vary + // e.g. filtered by date = TODAY + const AUTOFILTER_FILTERTYPE_TOPTENFILTER = 'top10'; + + /** + * Types of autofilter rules + * + * @var string[] + */ + private static $_filterTypes = array( + // Currently we're not handling + // colorFilter + // extLst + // iconFilter + self::AUTOFILTER_FILTERTYPE_FILTER, + self::AUTOFILTER_FILTERTYPE_CUSTOMFILTER, + self::AUTOFILTER_FILTERTYPE_DYNAMICFILTER, + self::AUTOFILTER_FILTERTYPE_TOPTENFILTER, + ); + + /* Multiple Rule Connections */ + const AUTOFILTER_COLUMN_JOIN_AND = 'and'; + const AUTOFILTER_COLUMN_JOIN_OR = 'or'; + + /** + * Join options for autofilter rules + * + * @var string[] + */ + private static $_ruleJoins = array( + self::AUTOFILTER_COLUMN_JOIN_AND, + self::AUTOFILTER_COLUMN_JOIN_OR, + ); + + /** + * Autofilter + * + * @var PHPExcel_Worksheet_AutoFilter + */ + private $_parent = NULL; + + + /** + * Autofilter Column Index + * + * @var string + */ + private $_columnIndex = ''; + + + /** + * Autofilter Column Filter Type + * + * @var string + */ + private $_filterType = self::AUTOFILTER_FILTERTYPE_FILTER; + + + /** + * Autofilter Multiple Rules And/Or + * + * @var string + */ + private $_join = self::AUTOFILTER_COLUMN_JOIN_OR; + + + /** + * Autofilter Column Rules + * + * @var array of PHPExcel_Worksheet_AutoFilter_Column_Rule + */ + private $_ruleset = array(); + + + /** + * Autofilter Column Dynamic Attributes + * + * @var array of mixed + */ + private $_attributes = array(); + + + /** + * Create a new PHPExcel_Worksheet_AutoFilter_Column + * + * @param string $pColumn Column (e.g. A) + * @param PHPExcel_Worksheet_AutoFilter $pParent Autofilter for this column + */ + public function __construct($pColumn, PHPExcel_Worksheet_AutoFilter $pParent = NULL) + { + $this->_columnIndex = $pColumn; + $this->_parent = $pParent; + } + + /** + * Get AutoFilter Column Index + * + * @return string + */ + public function getColumnIndex() { + return $this->_columnIndex; + } + + /** + * Set AutoFilter Column Index + * + * @param string $pColumn Column (e.g. A) + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter_Column + */ + public function setColumnIndex($pColumn) { + // Uppercase coordinate + $pColumn = strtoupper($pColumn); + if ($this->_parent !== NULL) { + $this->_parent->testColumnInRange($pColumn); + } + + $this->_columnIndex = $pColumn; + + return $this; + } + + /** + * Get this Column's AutoFilter Parent + * + * @return PHPExcel_Worksheet_AutoFilter + */ + public function getParent() { + return $this->_parent; + } + + /** + * Set this Column's AutoFilter Parent + * + * @param PHPExcel_Worksheet_AutoFilter + * @return PHPExcel_Worksheet_AutoFilter_Column + */ + public function setParent(PHPExcel_Worksheet_AutoFilter $pParent = NULL) { + $this->_parent = $pParent; + + return $this; + } + + /** + * Get AutoFilter Type + * + * @return string + */ + public function getFilterType() { + return $this->_filterType; + } + + /** + * Set AutoFilter Type + * + * @param string $pFilterType + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter_Column + */ + public function setFilterType($pFilterType = self::AUTOFILTER_FILTERTYPE_FILTER) { + if (!in_array($pFilterType,self::$_filterTypes)) { + throw new PHPExcel_Exception('Invalid filter type for column AutoFilter.'); + } + + $this->_filterType = $pFilterType; + + return $this; + } + + /** + * Get AutoFilter Multiple Rules And/Or Join + * + * @return string + */ + public function getJoin() { + return $this->_join; + } + + /** + * Set AutoFilter Multiple Rules And/Or + * + * @param string $pJoin And/Or + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter_Column + */ + public function setJoin($pJoin = self::AUTOFILTER_COLUMN_JOIN_OR) { + // Lowercase And/Or + $pJoin = strtolower($pJoin); + if (!in_array($pJoin,self::$_ruleJoins)) { + throw new PHPExcel_Exception('Invalid rule connection for column AutoFilter.'); + } + + $this->_join = $pJoin; + + return $this; + } + + /** + * Set AutoFilter Attributes + * + * @param string[] $pAttributes + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter_Column + */ + public function setAttributes($pAttributes = array()) { + $this->_attributes = $pAttributes; + + return $this; + } + + /** + * Set An AutoFilter Attribute + * + * @param string $pName Attribute Name + * @param string $pValue Attribute Value + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter_Column + */ + public function setAttribute($pName, $pValue) { + $this->_attributes[$pName] = $pValue; + + return $this; + } + + /** + * Get AutoFilter Column Attributes + * + * @return string + */ + public function getAttributes() { + return $this->_attributes; + } + + /** + * Get specific AutoFilter Column Attribute + * + * @param string $pName Attribute Name + * @return string + */ + public function getAttribute($pName) { + if (isset($this->_attributes[$pName])) + return $this->_attributes[$pName]; + return NULL; + } + + /** + * Get all AutoFilter Column Rules + * + * @throws PHPExcel_Exception + * @return array of PHPExcel_Worksheet_AutoFilter_Column_Rule + */ + public function getRules() { + return $this->_ruleset; + } + + /** + * Get a specified AutoFilter Column Rule + * + * @param integer $pIndex Rule index in the ruleset array + * @return PHPExcel_Worksheet_AutoFilter_Column_Rule + */ + public function getRule($pIndex) { + if (!isset($this->_ruleset[$pIndex])) { + $this->_ruleset[$pIndex] = new PHPExcel_Worksheet_AutoFilter_Column_Rule($this); + } + return $this->_ruleset[$pIndex]; + } + + /** + * Create a new AutoFilter Column Rule in the ruleset + * + * @return PHPExcel_Worksheet_AutoFilter_Column_Rule + */ + public function createRule() { + $this->_ruleset[] = new PHPExcel_Worksheet_AutoFilter_Column_Rule($this); + + return end($this->_ruleset); + } + + /** + * Add a new AutoFilter Column Rule to the ruleset + * + * @param PHPExcel_Worksheet_AutoFilter_Column_Rule $pRule + * @param boolean $returnRule Flag indicating whether the rule object or the column object should be returned + * @return PHPExcel_Worksheet_AutoFilter_Column|PHPExcel_Worksheet_AutoFilter_Column_Rule + */ + public function addRule(PHPExcel_Worksheet_AutoFilter_Column_Rule $pRule, $returnRule=TRUE) { + $pRule->setParent($this); + $this->_ruleset[] = $pRule; + + return ($returnRule) ? $pRule : $this; + } + + /** + * Delete a specified AutoFilter Column Rule + * If the number of rules is reduced to 1, then we reset And/Or logic to Or + * + * @param integer $pIndex Rule index in the ruleset array + * @return PHPExcel_Worksheet_AutoFilter_Column + */ + public function deleteRule($pIndex) { + if (isset($this->_ruleset[$pIndex])) { + unset($this->_ruleset[$pIndex]); + // If we've just deleted down to a single rule, then reset And/Or joining to Or + if (count($this->_ruleset) <= 1) { + $this->setJoin(self::AUTOFILTER_COLUMN_JOIN_OR); + } + } + + return $this; + } + + /** + * Delete all AutoFilter Column Rules + * + * @return PHPExcel_Worksheet_AutoFilter_Column + */ + public function clearRules() { + $this->_ruleset = array(); + $this->setJoin(self::AUTOFILTER_COLUMN_JOIN_OR); + + return $this; + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + if ($key == '_parent') { + // Detach from autofilter parent + $this->$key = NULL; + } else { + $this->$key = clone $value; + } + } elseif ((is_array($value)) && ($key == '_ruleset')) { + // The columns array of PHPExcel_Worksheet_AutoFilter objects + $this->$key = array(); + foreach ($value as $k => $v) { + $this->$key[$k] = clone $v; + // attach the new cloned Rule to this new cloned Autofilter Cloned object + $this->$key[$k]->setParent($this); + } + } else { + $this->$key = $value; + } + } + } + +} diff --git a/lib/phpexcel/PHPExcel/Worksheet/AutoFilter/Column/Rule.php b/lib/phpexcel/PHPExcel/Worksheet/AutoFilter/Column/Rule.php new file mode 100644 index 0000000..ae33683 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Worksheet/AutoFilter/Column/Rule.php @@ -0,0 +1,464 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Worksheet_AutoFilter_Column_Rule + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Worksheet_AutoFilter_Column_Rule +{ + const AUTOFILTER_RULETYPE_FILTER = 'filter'; + const AUTOFILTER_RULETYPE_DATEGROUP = 'dateGroupItem'; + const AUTOFILTER_RULETYPE_CUSTOMFILTER = 'customFilter'; + const AUTOFILTER_RULETYPE_DYNAMICFILTER = 'dynamicFilter'; + const AUTOFILTER_RULETYPE_TOPTENFILTER = 'top10Filter'; + + private static $_ruleTypes = array( + // Currently we're not handling + // colorFilter + // extLst + // iconFilter + self::AUTOFILTER_RULETYPE_FILTER, + self::AUTOFILTER_RULETYPE_DATEGROUP, + self::AUTOFILTER_RULETYPE_CUSTOMFILTER, + self::AUTOFILTER_RULETYPE_DYNAMICFILTER, + self::AUTOFILTER_RULETYPE_TOPTENFILTER, + ); + + const AUTOFILTER_RULETYPE_DATEGROUP_YEAR = 'year'; + const AUTOFILTER_RULETYPE_DATEGROUP_MONTH = 'month'; + const AUTOFILTER_RULETYPE_DATEGROUP_DAY = 'day'; + const AUTOFILTER_RULETYPE_DATEGROUP_HOUR = 'hour'; + const AUTOFILTER_RULETYPE_DATEGROUP_MINUTE = 'minute'; + const AUTOFILTER_RULETYPE_DATEGROUP_SECOND = 'second'; + + private static $_dateTimeGroups = array( + self::AUTOFILTER_RULETYPE_DATEGROUP_YEAR, + self::AUTOFILTER_RULETYPE_DATEGROUP_MONTH, + self::AUTOFILTER_RULETYPE_DATEGROUP_DAY, + self::AUTOFILTER_RULETYPE_DATEGROUP_HOUR, + self::AUTOFILTER_RULETYPE_DATEGROUP_MINUTE, + self::AUTOFILTER_RULETYPE_DATEGROUP_SECOND, + ); + + const AUTOFILTER_RULETYPE_DYNAMIC_YESTERDAY = 'yesterday'; + const AUTOFILTER_RULETYPE_DYNAMIC_TODAY = 'today'; + const AUTOFILTER_RULETYPE_DYNAMIC_TOMORROW = 'tomorrow'; + const AUTOFILTER_RULETYPE_DYNAMIC_YEARTODATE = 'yearToDate'; + const AUTOFILTER_RULETYPE_DYNAMIC_THISYEAR = 'thisYear'; + const AUTOFILTER_RULETYPE_DYNAMIC_THISQUARTER = 'thisQuarter'; + const AUTOFILTER_RULETYPE_DYNAMIC_THISMONTH = 'thisMonth'; + const AUTOFILTER_RULETYPE_DYNAMIC_THISWEEK = 'thisWeek'; + const AUTOFILTER_RULETYPE_DYNAMIC_LASTYEAR = 'lastYear'; + const AUTOFILTER_RULETYPE_DYNAMIC_LASTQUARTER = 'lastQuarter'; + const AUTOFILTER_RULETYPE_DYNAMIC_LASTMONTH = 'lastMonth'; + const AUTOFILTER_RULETYPE_DYNAMIC_LASTWEEK = 'lastWeek'; + const AUTOFILTER_RULETYPE_DYNAMIC_NEXTYEAR = 'nextYear'; + const AUTOFILTER_RULETYPE_DYNAMIC_NEXTQUARTER = 'nextQuarter'; + const AUTOFILTER_RULETYPE_DYNAMIC_NEXTMONTH = 'nextMonth'; + const AUTOFILTER_RULETYPE_DYNAMIC_NEXTWEEK = 'nextWeek'; + const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_1 = 'M1'; + const AUTOFILTER_RULETYPE_DYNAMIC_JANUARY = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_1; + const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_2 = 'M2'; + const AUTOFILTER_RULETYPE_DYNAMIC_FEBRUARY = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_2; + const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_3 = 'M3'; + const AUTOFILTER_RULETYPE_DYNAMIC_MARCH = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_3; + const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_4 = 'M4'; + const AUTOFILTER_RULETYPE_DYNAMIC_APRIL = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_4; + const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_5 = 'M5'; + const AUTOFILTER_RULETYPE_DYNAMIC_MAY = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_5; + const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_6 = 'M6'; + const AUTOFILTER_RULETYPE_DYNAMIC_JUNE = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_6; + const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_7 = 'M7'; + const AUTOFILTER_RULETYPE_DYNAMIC_JULY = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_7; + const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_8 = 'M8'; + const AUTOFILTER_RULETYPE_DYNAMIC_AUGUST = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_8; + const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_9 = 'M9'; + const AUTOFILTER_RULETYPE_DYNAMIC_SEPTEMBER = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_9; + const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_10 = 'M10'; + const AUTOFILTER_RULETYPE_DYNAMIC_OCTOBER = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_10; + const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_11 = 'M11'; + const AUTOFILTER_RULETYPE_DYNAMIC_NOVEMBER = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_11; + const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_12 = 'M12'; + const AUTOFILTER_RULETYPE_DYNAMIC_DECEMBER = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_12; + const AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_1 = 'Q1'; + const AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_2 = 'Q2'; + const AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_3 = 'Q3'; + const AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_4 = 'Q4'; + const AUTOFILTER_RULETYPE_DYNAMIC_ABOVEAVERAGE = 'aboveAverage'; + const AUTOFILTER_RULETYPE_DYNAMIC_BELOWAVERAGE = 'belowAverage'; + + private static $_dynamicTypes = array( + self::AUTOFILTER_RULETYPE_DYNAMIC_YESTERDAY, + self::AUTOFILTER_RULETYPE_DYNAMIC_TODAY, + self::AUTOFILTER_RULETYPE_DYNAMIC_TOMORROW, + self::AUTOFILTER_RULETYPE_DYNAMIC_YEARTODATE, + self::AUTOFILTER_RULETYPE_DYNAMIC_THISYEAR, + self::AUTOFILTER_RULETYPE_DYNAMIC_THISQUARTER, + self::AUTOFILTER_RULETYPE_DYNAMIC_THISMONTH, + self::AUTOFILTER_RULETYPE_DYNAMIC_THISWEEK, + self::AUTOFILTER_RULETYPE_DYNAMIC_LASTYEAR, + self::AUTOFILTER_RULETYPE_DYNAMIC_LASTQUARTER, + self::AUTOFILTER_RULETYPE_DYNAMIC_LASTMONTH, + self::AUTOFILTER_RULETYPE_DYNAMIC_LASTWEEK, + self::AUTOFILTER_RULETYPE_DYNAMIC_NEXTYEAR, + self::AUTOFILTER_RULETYPE_DYNAMIC_NEXTQUARTER, + self::AUTOFILTER_RULETYPE_DYNAMIC_NEXTMONTH, + self::AUTOFILTER_RULETYPE_DYNAMIC_NEXTWEEK, + self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_1, + self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_2, + self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_3, + self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_4, + self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_5, + self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_6, + self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_7, + self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_8, + self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_9, + self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_10, + self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_11, + self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_12, + self::AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_1, + self::AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_2, + self::AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_3, + self::AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_4, + self::AUTOFILTER_RULETYPE_DYNAMIC_ABOVEAVERAGE, + self::AUTOFILTER_RULETYPE_DYNAMIC_BELOWAVERAGE, + ); + + /* + * The only valid filter rule operators for filter and customFilter types are: + * <xsd:enumeration value="equal"/> + * <xsd:enumeration value="lessThan"/> + * <xsd:enumeration value="lessThanOrEqual"/> + * <xsd:enumeration value="notEqual"/> + * <xsd:enumeration value="greaterThanOrEqual"/> + * <xsd:enumeration value="greaterThan"/> + */ + const AUTOFILTER_COLUMN_RULE_EQUAL = 'equal'; + const AUTOFILTER_COLUMN_RULE_NOTEQUAL = 'notEqual'; + const AUTOFILTER_COLUMN_RULE_GREATERTHAN = 'greaterThan'; + const AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL = 'greaterThanOrEqual'; + const AUTOFILTER_COLUMN_RULE_LESSTHAN = 'lessThan'; + const AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL = 'lessThanOrEqual'; + + private static $_operators = array( + self::AUTOFILTER_COLUMN_RULE_EQUAL, + self::AUTOFILTER_COLUMN_RULE_NOTEQUAL, + self::AUTOFILTER_COLUMN_RULE_GREATERTHAN, + self::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL, + self::AUTOFILTER_COLUMN_RULE_LESSTHAN, + self::AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL, + ); + + const AUTOFILTER_COLUMN_RULE_TOPTEN_BY_VALUE = 'byValue'; + const AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT = 'byPercent'; + + private static $_topTenValue = array( + self::AUTOFILTER_COLUMN_RULE_TOPTEN_BY_VALUE, + self::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT, + ); + + const AUTOFILTER_COLUMN_RULE_TOPTEN_TOP = 'top'; + const AUTOFILTER_COLUMN_RULE_TOPTEN_BOTTOM = 'bottom'; + + private static $_topTenType = array( + self::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP, + self::AUTOFILTER_COLUMN_RULE_TOPTEN_BOTTOM, + ); + + + /* Rule Operators (Numeric, Boolean etc) */ +// const AUTOFILTER_COLUMN_RULE_BETWEEN = 'between'; // greaterThanOrEqual 1 && lessThanOrEqual 2 + /* Rule Operators (Numeric Special) which are translated to standard numeric operators with calculated values */ +// const AUTOFILTER_COLUMN_RULE_TOPTEN = 'topTen'; // greaterThan calculated value +// const AUTOFILTER_COLUMN_RULE_TOPTENPERCENT = 'topTenPercent'; // greaterThan calculated value +// const AUTOFILTER_COLUMN_RULE_ABOVEAVERAGE = 'aboveAverage'; // Value is calculated as the average +// const AUTOFILTER_COLUMN_RULE_BELOWAVERAGE = 'belowAverage'; // Value is calculated as the average + /* Rule Operators (String) which are set as wild-carded values */ +// const AUTOFILTER_COLUMN_RULE_BEGINSWITH = 'beginsWith'; // A* +// const AUTOFILTER_COLUMN_RULE_ENDSWITH = 'endsWith'; // *Z +// const AUTOFILTER_COLUMN_RULE_CONTAINS = 'contains'; // *B* +// const AUTOFILTER_COLUMN_RULE_DOESNTCONTAIN = 'notEqual'; // notEqual *B* + /* Rule Operators (Date Special) which are translated to standard numeric operators with calculated values */ +// const AUTOFILTER_COLUMN_RULE_BEFORE = 'lessThan'; +// const AUTOFILTER_COLUMN_RULE_AFTER = 'greaterThan'; +// const AUTOFILTER_COLUMN_RULE_YESTERDAY = 'yesterday'; +// const AUTOFILTER_COLUMN_RULE_TODAY = 'today'; +// const AUTOFILTER_COLUMN_RULE_TOMORROW = 'tomorrow'; +// const AUTOFILTER_COLUMN_RULE_LASTWEEK = 'lastWeek'; +// const AUTOFILTER_COLUMN_RULE_THISWEEK = 'thisWeek'; +// const AUTOFILTER_COLUMN_RULE_NEXTWEEK = 'nextWeek'; +// const AUTOFILTER_COLUMN_RULE_LASTMONTH = 'lastMonth'; +// const AUTOFILTER_COLUMN_RULE_THISMONTH = 'thisMonth'; +// const AUTOFILTER_COLUMN_RULE_NEXTMONTH = 'nextMonth'; +// const AUTOFILTER_COLUMN_RULE_LASTQUARTER = 'lastQuarter'; +// const AUTOFILTER_COLUMN_RULE_THISQUARTER = 'thisQuarter'; +// const AUTOFILTER_COLUMN_RULE_NEXTQUARTER = 'nextQuarter'; +// const AUTOFILTER_COLUMN_RULE_LASTYEAR = 'lastYear'; +// const AUTOFILTER_COLUMN_RULE_THISYEAR = 'thisYear'; +// const AUTOFILTER_COLUMN_RULE_NEXTYEAR = 'nextYear'; +// const AUTOFILTER_COLUMN_RULE_YEARTODATE = 'yearToDate'; // <dynamicFilter val="40909" type="yearToDate" maxVal="41113"/> +// const AUTOFILTER_COLUMN_RULE_ALLDATESINMONTH = 'allDatesInMonth'; // <dynamicFilter type="M2"/> for Month/February +// const AUTOFILTER_COLUMN_RULE_ALLDATESINQUARTER = 'allDatesInQuarter'; // <dynamicFilter type="Q2"/> for Quarter 2 + + /** + * Autofilter Column + * + * @var PHPExcel_Worksheet_AutoFilter_Column + */ + private $_parent = NULL; + + + /** + * Autofilter Rule Type + * + * @var string + */ + private $_ruleType = self::AUTOFILTER_RULETYPE_FILTER; + + + /** + * Autofilter Rule Value + * + * @var string + */ + private $_value = ''; + + /** + * Autofilter Rule Operator + * + * @var string + */ + private $_operator = ''; + + /** + * DateTimeGrouping Group Value + * + * @var string + */ + private $_grouping = ''; + + + /** + * Create a new PHPExcel_Worksheet_AutoFilter_Column_Rule + * + * @param PHPExcel_Worksheet_AutoFilter_Column $pParent + */ + public function __construct(PHPExcel_Worksheet_AutoFilter_Column $pParent = NULL) + { + $this->_parent = $pParent; + } + + /** + * Get AutoFilter Rule Type + * + * @return string + */ + public function getRuleType() { + return $this->_ruleType; + } + + /** + * Set AutoFilter Rule Type + * + * @param string $pRuleType + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter_Column + */ + public function setRuleType($pRuleType = self::AUTOFILTER_RULETYPE_FILTER) { + if (!in_array($pRuleType,self::$_ruleTypes)) { + throw new PHPExcel_Exception('Invalid rule type for column AutoFilter Rule.'); + } + + $this->_ruleType = $pRuleType; + + return $this; + } + + /** + * Get AutoFilter Rule Value + * + * @return string + */ + public function getValue() { + return $this->_value; + } + + /** + * Set AutoFilter Rule Value + * + * @param string|string[] $pValue + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter_Column_Rule + */ + public function setValue($pValue = '') { + if (is_array($pValue)) { + $grouping = -1; + foreach($pValue as $key => $value) { + // Validate array entries + if (!in_array($key,self::$_dateTimeGroups)) { + // Remove any invalid entries from the value array + unset($pValue[$key]); + } else { + // Work out what the dateTime grouping will be + $grouping = max($grouping,array_search($key,self::$_dateTimeGroups)); + } + } + if (count($pValue) == 0) { + throw new PHPExcel_Exception('Invalid rule value for column AutoFilter Rule.'); + } + // Set the dateTime grouping that we've anticipated + $this->setGrouping(self::$_dateTimeGroups[$grouping]); + } + $this->_value = $pValue; + + return $this; + } + + /** + * Get AutoFilter Rule Operator + * + * @return string + */ + public function getOperator() { + return $this->_operator; + } + + /** + * Set AutoFilter Rule Operator + * + * @param string $pOperator + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter_Column_Rule + */ + public function setOperator($pOperator = self::AUTOFILTER_COLUMN_RULE_EQUAL) { + if (empty($pOperator)) + $pOperator = self::AUTOFILTER_COLUMN_RULE_EQUAL; + if ((!in_array($pOperator,self::$_operators)) && + (!in_array($pOperator,self::$_topTenValue))) { + throw new PHPExcel_Exception('Invalid operator for column AutoFilter Rule.'); + } + $this->_operator = $pOperator; + + return $this; + } + + /** + * Get AutoFilter Rule Grouping + * + * @return string + */ + public function getGrouping() { + return $this->_grouping; + } + + /** + * Set AutoFilter Rule Grouping + * + * @param string $pGrouping + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter_Column_Rule + */ + public function setGrouping($pGrouping = NULL) { + if (($pGrouping !== NULL) && + (!in_array($pGrouping,self::$_dateTimeGroups)) && + (!in_array($pGrouping,self::$_dynamicTypes)) && + (!in_array($pGrouping,self::$_topTenType))) { + throw new PHPExcel_Exception('Invalid rule type for column AutoFilter Rule.'); + } + + $this->_grouping = $pGrouping; + + return $this; + } + + /** + * Set AutoFilter Rule + * + * @param string $pOperator + * @param string|string[] $pValue + * @param string $pGrouping + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter_Column_Rule + */ + public function setRule($pOperator = self::AUTOFILTER_COLUMN_RULE_EQUAL, $pValue = '', $pGrouping = NULL) { + $this->setOperator($pOperator); + $this->setValue($pValue); + // Only set grouping if it's been passed in as a user-supplied argument, + // otherwise we're calculating it when we setValue() and don't want to overwrite that + // If the user supplies an argumnet for grouping, then on their own head be it + if ($pGrouping !== NULL) + $this->setGrouping($pGrouping); + + return $this; + } + + /** + * Get this Rule's AutoFilter Column Parent + * + * @return PHPExcel_Worksheet_AutoFilter_Column + */ + public function getParent() { + return $this->_parent; + } + + /** + * Set this Rule's AutoFilter Column Parent + * + * @param PHPExcel_Worksheet_AutoFilter_Column + * @return PHPExcel_Worksheet_AutoFilter_Column_Rule + */ + public function setParent(PHPExcel_Worksheet_AutoFilter_Column $pParent = NULL) { + $this->_parent = $pParent; + + return $this; + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + if ($key == '_parent') { + // Detach from autofilter column parent + $this->$key = NULL; + } else { + $this->$key = clone $value; + } + } else { + $this->$key = $value; + } + } + } + +} diff --git a/lib/phpexcel/PHPExcel/Worksheet/BaseDrawing.php b/lib/phpexcel/PHPExcel/Worksheet/BaseDrawing.php new file mode 100644 index 0000000..4db0f88 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Worksheet/BaseDrawing.php @@ -0,0 +1,485 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Worksheet_BaseDrawing + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable +{ + /** + * Image counter + * + * @var int + */ + private static $_imageCounter = 0; + + /** + * Image index + * + * @var int + */ + private $_imageIndex = 0; + + /** + * Name + * + * @var string + */ + protected $_name; + + /** + * Description + * + * @var string + */ + protected $_description; + + /** + * Worksheet + * + * @var PHPExcel_Worksheet + */ + protected $_worksheet; + + /** + * Coordinates + * + * @var string + */ + protected $_coordinates; + + /** + * Offset X + * + * @var int + */ + protected $_offsetX; + + /** + * Offset Y + * + * @var int + */ + protected $_offsetY; + + /** + * Width + * + * @var int + */ + protected $_width; + + /** + * Height + * + * @var int + */ + protected $_height; + + /** + * Proportional resize + * + * @var boolean + */ + protected $_resizeProportional; + + /** + * Rotation + * + * @var int + */ + protected $_rotation; + + /** + * Shadow + * + * @var PHPExcel_Worksheet_Drawing_Shadow + */ + protected $_shadow; + + /** + * Create a new PHPExcel_Worksheet_BaseDrawing + */ + public function __construct() + { + // Initialise values + $this->_name = ''; + $this->_description = ''; + $this->_worksheet = null; + $this->_coordinates = 'A1'; + $this->_offsetX = 0; + $this->_offsetY = 0; + $this->_width = 0; + $this->_height = 0; + $this->_resizeProportional = true; + $this->_rotation = 0; + $this->_shadow = new PHPExcel_Worksheet_Drawing_Shadow(); + + // Set image index + self::$_imageCounter++; + $this->_imageIndex = self::$_imageCounter; + } + + /** + * Get image index + * + * @return int + */ + public function getImageIndex() { + return $this->_imageIndex; + } + + /** + * Get Name + * + * @return string + */ + public function getName() { + return $this->_name; + } + + /** + * Set Name + * + * @param string $pValue + * @return PHPExcel_Worksheet_BaseDrawing + */ + public function setName($pValue = '') { + $this->_name = $pValue; + return $this; + } + + /** + * Get Description + * + * @return string + */ + public function getDescription() { + return $this->_description; + } + + /** + * Set Description + * + * @param string $pValue + * @return PHPExcel_Worksheet_BaseDrawing + */ + public function setDescription($pValue = '') { + $this->_description = $pValue; + return $this; + } + + /** + * Get Worksheet + * + * @return PHPExcel_Worksheet + */ + public function getWorksheet() { + return $this->_worksheet; + } + + /** + * Set Worksheet + * + * @param PHPExcel_Worksheet $pValue + * @param bool $pOverrideOld If a Worksheet has already been assigned, overwrite it and remove image from old Worksheet? + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_BaseDrawing + */ + public function setWorksheet(PHPExcel_Worksheet $pValue = null, $pOverrideOld = false) { + if (is_null($this->_worksheet)) { + // Add drawing to PHPExcel_Worksheet + $this->_worksheet = $pValue; + $this->_worksheet->getCell($this->_coordinates); + $this->_worksheet->getDrawingCollection()->append($this); + } else { + if ($pOverrideOld) { + // Remove drawing from old PHPExcel_Worksheet + $iterator = $this->_worksheet->getDrawingCollection()->getIterator(); + + while ($iterator->valid()) { + if ($iterator->current()->getHashCode() == $this->getHashCode()) { + $this->_worksheet->getDrawingCollection()->offsetUnset( $iterator->key() ); + $this->_worksheet = null; + break; + } + } + + // Set new PHPExcel_Worksheet + $this->setWorksheet($pValue); + } else { + throw new PHPExcel_Exception("A PHPExcel_Worksheet has already been assigned. Drawings can only exist on one PHPExcel_Worksheet."); + } + } + return $this; + } + + /** + * Get Coordinates + * + * @return string + */ + public function getCoordinates() { + return $this->_coordinates; + } + + /** + * Set Coordinates + * + * @param string $pValue + * @return PHPExcel_Worksheet_BaseDrawing + */ + public function setCoordinates($pValue = 'A1') { + $this->_coordinates = $pValue; + return $this; + } + + /** + * Get OffsetX + * + * @return int + */ + public function getOffsetX() { + return $this->_offsetX; + } + + /** + * Set OffsetX + * + * @param int $pValue + * @return PHPExcel_Worksheet_BaseDrawing + */ + public function setOffsetX($pValue = 0) { + $this->_offsetX = $pValue; + return $this; + } + + /** + * Get OffsetY + * + * @return int + */ + public function getOffsetY() { + return $this->_offsetY; + } + + /** + * Set OffsetY + * + * @param int $pValue + * @return PHPExcel_Worksheet_BaseDrawing + */ + public function setOffsetY($pValue = 0) { + $this->_offsetY = $pValue; + return $this; + } + + /** + * Get Width + * + * @return int + */ + public function getWidth() { + return $this->_width; + } + + /** + * Set Width + * + * @param int $pValue + * @return PHPExcel_Worksheet_BaseDrawing + */ + public function setWidth($pValue = 0) { + // Resize proportional? + if ($this->_resizeProportional && $pValue != 0) { + $ratio = $this->_height / $this->_width; + $this->_height = round($ratio * $pValue); + } + + // Set width + $this->_width = $pValue; + + return $this; + } + + /** + * Get Height + * + * @return int + */ + public function getHeight() { + return $this->_height; + } + + /** + * Set Height + * + * @param int $pValue + * @return PHPExcel_Worksheet_BaseDrawing + */ + public function setHeight($pValue = 0) { + // Resize proportional? + if ($this->_resizeProportional && $pValue != 0) { + $ratio = $this->_width / $this->_height; + $this->_width = round($ratio * $pValue); + } + + // Set height + $this->_height = $pValue; + + return $this; + } + + /** + * Set width and height with proportional resize + * Example: + * <code> + * $objDrawing->setResizeProportional(true); + * $objDrawing->setWidthAndHeight(160,120); + * </code> + * + * @author Vincent@luo MSN:kele_100@hotmail.com + * @param int $width + * @param int $height + * @return PHPExcel_Worksheet_BaseDrawing + */ + public function setWidthAndHeight($width = 0, $height = 0) { + $xratio = $width / $this->_width; + $yratio = $height / $this->_height; + if ($this->_resizeProportional && !($width == 0 || $height == 0)) { + if (($xratio * $this->_height) < $height) { + $this->_height = ceil($xratio * $this->_height); + $this->_width = $width; + } else { + $this->_width = ceil($yratio * $this->_width); + $this->_height = $height; + } + } + return $this; + } + + /** + * Get ResizeProportional + * + * @return boolean + */ + public function getResizeProportional() { + return $this->_resizeProportional; + } + + /** + * Set ResizeProportional + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_BaseDrawing + */ + public function setResizeProportional($pValue = true) { + $this->_resizeProportional = $pValue; + return $this; + } + + /** + * Get Rotation + * + * @return int + */ + public function getRotation() { + return $this->_rotation; + } + + /** + * Set Rotation + * + * @param int $pValue + * @return PHPExcel_Worksheet_BaseDrawing + */ + public function setRotation($pValue = 0) { + $this->_rotation = $pValue; + return $this; + } + + /** + * Get Shadow + * + * @return PHPExcel_Worksheet_Drawing_Shadow + */ + public function getShadow() { + return $this->_shadow; + } + + /** + * Set Shadow + * + * @param PHPExcel_Worksheet_Drawing_Shadow $pValue + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_BaseDrawing + */ + public function setShadow(PHPExcel_Worksheet_Drawing_Shadow $pValue = null) { + $this->_shadow = $pValue; + return $this; + } + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() { + return md5( + $this->_name + . $this->_description + . $this->_worksheet->getHashCode() + . $this->_coordinates + . $this->_offsetX + . $this->_offsetY + . $this->_width + . $this->_height + . $this->_rotation + . $this->_shadow->getHashCode() + . __CLASS__ + ); + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } +} diff --git a/lib/phpexcel/PHPExcel/Worksheet/CellIterator.php b/lib/phpexcel/PHPExcel/Worksheet/CellIterator.php new file mode 100644 index 0000000..4b96816 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Worksheet/CellIterator.php @@ -0,0 +1,161 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Worksheet_CellIterator + * + * Used to iterate rows in a PHPExcel_Worksheet + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Worksheet_CellIterator implements Iterator +{ + /** + * PHPExcel_Worksheet to iterate + * + * @var PHPExcel_Worksheet + */ + private $_subject; + + /** + * Row index + * + * @var int + */ + private $_rowIndex; + + /** + * Current iterator position + * + * @var int + */ + private $_position = 0; + + /** + * Loop only existing cells + * + * @var boolean + */ + private $_onlyExistingCells = true; + + /** + * Create a new cell iterator + * + * @param PHPExcel_Worksheet $subject + * @param int $rowIndex + */ + public function __construct(PHPExcel_Worksheet $subject = null, $rowIndex = 1) { + // Set subject and row index + $this->_subject = $subject; + $this->_rowIndex = $rowIndex; + } + + /** + * Destructor + */ + public function __destruct() { + unset($this->_subject); + } + + /** + * Rewind iterator + */ + public function rewind() { + $this->_position = 0; + } + + /** + * Current PHPExcel_Cell + * + * @return PHPExcel_Cell + */ + public function current() { + return $this->_subject->getCellByColumnAndRow($this->_position, $this->_rowIndex); + } + + /** + * Current key + * + * @return int + */ + public function key() { + return $this->_position; + } + + /** + * Next value + */ + public function next() { + ++$this->_position; + } + + /** + * Are there any more PHPExcel_Cell instances available? + * + * @return boolean + */ + public function valid() { + // columnIndexFromString() returns an index based at one, + // treat it as a count when comparing it to the base zero + // position. + $columnCount = PHPExcel_Cell::columnIndexFromString($this->_subject->getHighestColumn()); + + if ($this->_onlyExistingCells) { + // If we aren't looking at an existing cell, either + // because the first column doesn't exist or next() has + // been called onto a nonexistent cell, then loop until we + // find one, or pass the last column. + while ($this->_position < $columnCount && + !$this->_subject->cellExistsByColumnAndRow($this->_position, $this->_rowIndex)) { + ++$this->_position; + } + } + + return $this->_position < $columnCount; + } + + /** + * Get loop only existing cells + * + * @return boolean + */ + public function getIterateOnlyExistingCells() { + return $this->_onlyExistingCells; + } + + /** + * Set the iterator to loop only existing cells + * + * @param boolean $value + */ + public function setIterateOnlyExistingCells($value = true) { + $this->_onlyExistingCells = $value; + } +} diff --git a/lib/phpexcel/PHPExcel/Worksheet/ColumnDimension.php b/lib/phpexcel/PHPExcel/Worksheet/ColumnDimension.php new file mode 100644 index 0000000..79db1c5 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Worksheet/ColumnDimension.php @@ -0,0 +1,266 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Worksheet_ColumnDimension + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Worksheet_ColumnDimension +{ + /** + * Column index + * + * @var int + */ + private $_columnIndex; + + /** + * Column width + * + * When this is set to a negative value, the column width should be ignored by IWriter + * + * @var double + */ + private $_width = -1; + + /** + * Auto size? + * + * @var bool + */ + private $_autoSize = false; + + /** + * Visible? + * + * @var bool + */ + private $_visible = true; + + /** + * Outline level + * + * @var int + */ + private $_outlineLevel = 0; + + /** + * Collapsed + * + * @var bool + */ + private $_collapsed = false; + + /** + * Index to cellXf + * + * @var int + */ + private $_xfIndex; + + /** + * Create a new PHPExcel_Worksheet_ColumnDimension + * + * @param string $pIndex Character column index + */ + public function __construct($pIndex = 'A') + { + // Initialise values + $this->_columnIndex = $pIndex; + + // set default index to cellXf + $this->_xfIndex = 0; + } + + /** + * Get ColumnIndex + * + * @return string + */ + public function getColumnIndex() { + return $this->_columnIndex; + } + + /** + * Set ColumnIndex + * + * @param string $pValue + * @return PHPExcel_Worksheet_ColumnDimension + */ + public function setColumnIndex($pValue) { + $this->_columnIndex = $pValue; + return $this; + } + + /** + * Get Width + * + * @return double + */ + public function getWidth() { + return $this->_width; + } + + /** + * Set Width + * + * @param double $pValue + * @return PHPExcel_Worksheet_ColumnDimension + */ + public function setWidth($pValue = -1) { + $this->_width = $pValue; + return $this; + } + + /** + * Get Auto Size + * + * @return bool + */ + public function getAutoSize() { + return $this->_autoSize; + } + + /** + * Set Auto Size + * + * @param bool $pValue + * @return PHPExcel_Worksheet_ColumnDimension + */ + public function setAutoSize($pValue = false) { + $this->_autoSize = $pValue; + return $this; + } + + /** + * Get Visible + * + * @return bool + */ + public function getVisible() { + return $this->_visible; + } + + /** + * Set Visible + * + * @param bool $pValue + * @return PHPExcel_Worksheet_ColumnDimension + */ + public function setVisible($pValue = true) { + $this->_visible = $pValue; + return $this; + } + + /** + * Get Outline Level + * + * @return int + */ + public function getOutlineLevel() { + return $this->_outlineLevel; + } + + /** + * Set Outline Level + * + * Value must be between 0 and 7 + * + * @param int $pValue + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_ColumnDimension + */ + public function setOutlineLevel($pValue) { + if ($pValue < 0 || $pValue > 7) { + throw new PHPExcel_Exception("Outline level must range between 0 and 7."); + } + + $this->_outlineLevel = $pValue; + return $this; + } + + /** + * Get Collapsed + * + * @return bool + */ + public function getCollapsed() { + return $this->_collapsed; + } + + /** + * Set Collapsed + * + * @param bool $pValue + * @return PHPExcel_Worksheet_ColumnDimension + */ + public function setCollapsed($pValue = true) { + $this->_collapsed = $pValue; + return $this; + } + + /** + * Get index to cellXf + * + * @return int + */ + public function getXfIndex() + { + return $this->_xfIndex; + } + + /** + * Set index to cellXf + * + * @param int $pValue + * @return PHPExcel_Worksheet_ColumnDimension + */ + public function setXfIndex($pValue = 0) + { + $this->_xfIndex = $pValue; + return $this; + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } + +} diff --git a/lib/phpexcel/PHPExcel/Worksheet/Drawing.php b/lib/phpexcel/PHPExcel/Worksheet/Drawing.php new file mode 100644 index 0000000..56f0cfd --- /dev/null +++ b/lib/phpexcel/PHPExcel/Worksheet/Drawing.php @@ -0,0 +1,148 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Worksheet_Drawing + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Worksheet_Drawing + * + * @category PHPExcel + * @package PHPExcel_Worksheet_Drawing + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Worksheet_Drawing extends PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable +{ + /** + * Path + * + * @var string + */ + private $_path; + + /** + * Create a new PHPExcel_Worksheet_Drawing + */ + public function __construct() + { + // Initialise values + $this->_path = ''; + + // Initialize parent + parent::__construct(); + } + + /** + * Get Filename + * + * @return string + */ + public function getFilename() { + return basename($this->_path); + } + + /** + * Get indexed filename (using image index) + * + * @return string + */ + public function getIndexedFilename() { + $fileName = $this->getFilename(); + $fileName = str_replace(' ', '_', $fileName); + return str_replace('.' . $this->getExtension(), '', $fileName) . $this->getImageIndex() . '.' . $this->getExtension(); + } + + /** + * Get Extension + * + * @return string + */ + public function getExtension() { + $exploded = explode(".", basename($this->_path)); + return $exploded[count($exploded) - 1]; + } + + /** + * Get Path + * + * @return string + */ + public function getPath() { + return $this->_path; + } + + /** + * Set Path + * + * @param string $pValue File path + * @param boolean $pVerifyFile Verify file + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_Drawing + */ + public function setPath($pValue = '', $pVerifyFile = true) { + if ($pVerifyFile) { + if (file_exists($pValue)) { + $this->_path = $pValue; + + if ($this->_width == 0 && $this->_height == 0) { + // Get width/height + list($this->_width, $this->_height) = getimagesize($pValue); + } + } else { + throw new PHPExcel_Exception("File $pValue not found!"); + } + } else { + $this->_path = $pValue; + } + return $this; + } + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() { + return md5( + $this->_path + . parent::getHashCode() + . __CLASS__ + ); + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } +} diff --git a/lib/phpexcel/PHPExcel/Worksheet/Drawing/Shadow.php b/lib/phpexcel/PHPExcel/Worksheet/Drawing/Shadow.php new file mode 100644 index 0000000..5df4489 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Worksheet/Drawing/Shadow.php @@ -0,0 +1,288 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Worksheet_Drawing + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Worksheet_Drawing_Shadow + * + * @category PHPExcel + * @package PHPExcel_Worksheet_Drawing + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Worksheet_Drawing_Shadow implements PHPExcel_IComparable +{ + /* Shadow alignment */ + const SHADOW_BOTTOM = 'b'; + const SHADOW_BOTTOM_LEFT = 'bl'; + const SHADOW_BOTTOM_RIGHT = 'br'; + const SHADOW_CENTER = 'ctr'; + const SHADOW_LEFT = 'l'; + const SHADOW_TOP = 't'; + const SHADOW_TOP_LEFT = 'tl'; + const SHADOW_TOP_RIGHT = 'tr'; + + /** + * Visible + * + * @var boolean + */ + private $_visible; + + /** + * Blur radius + * + * Defaults to 6 + * + * @var int + */ + private $_blurRadius; + + /** + * Shadow distance + * + * Defaults to 2 + * + * @var int + */ + private $_distance; + + /** + * Shadow direction (in degrees) + * + * @var int + */ + private $_direction; + + /** + * Shadow alignment + * + * @var int + */ + private $_alignment; + + /** + * Color + * + * @var PHPExcel_Style_Color + */ + private $_color; + + /** + * Alpha + * + * @var int + */ + private $_alpha; + + /** + * Create a new PHPExcel_Worksheet_Drawing_Shadow + */ + public function __construct() + { + // Initialise values + $this->_visible = false; + $this->_blurRadius = 6; + $this->_distance = 2; + $this->_direction = 0; + $this->_alignment = PHPExcel_Worksheet_Drawing_Shadow::SHADOW_BOTTOM_RIGHT; + $this->_color = new PHPExcel_Style_Color(PHPExcel_Style_Color::COLOR_BLACK); + $this->_alpha = 50; + } + + /** + * Get Visible + * + * @return boolean + */ + public function getVisible() { + return $this->_visible; + } + + /** + * Set Visible + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_Drawing_Shadow + */ + public function setVisible($pValue = false) { + $this->_visible = $pValue; + return $this; + } + + /** + * Get Blur radius + * + * @return int + */ + public function getBlurRadius() { + return $this->_blurRadius; + } + + /** + * Set Blur radius + * + * @param int $pValue + * @return PHPExcel_Worksheet_Drawing_Shadow + */ + public function setBlurRadius($pValue = 6) { + $this->_blurRadius = $pValue; + return $this; + } + + /** + * Get Shadow distance + * + * @return int + */ + public function getDistance() { + return $this->_distance; + } + + /** + * Set Shadow distance + * + * @param int $pValue + * @return PHPExcel_Worksheet_Drawing_Shadow + */ + public function setDistance($pValue = 2) { + $this->_distance = $pValue; + return $this; + } + + /** + * Get Shadow direction (in degrees) + * + * @return int + */ + public function getDirection() { + return $this->_direction; + } + + /** + * Set Shadow direction (in degrees) + * + * @param int $pValue + * @return PHPExcel_Worksheet_Drawing_Shadow + */ + public function setDirection($pValue = 0) { + $this->_direction = $pValue; + return $this; + } + + /** + * Get Shadow alignment + * + * @return int + */ + public function getAlignment() { + return $this->_alignment; + } + + /** + * Set Shadow alignment + * + * @param int $pValue + * @return PHPExcel_Worksheet_Drawing_Shadow + */ + public function setAlignment($pValue = 0) { + $this->_alignment = $pValue; + return $this; + } + + /** + * Get Color + * + * @return PHPExcel_Style_Color + */ + public function getColor() { + return $this->_color; + } + + /** + * Set Color + * + * @param PHPExcel_Style_Color $pValue + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_Drawing_Shadow + */ + public function setColor(PHPExcel_Style_Color $pValue = null) { + $this->_color = $pValue; + return $this; + } + + /** + * Get Alpha + * + * @return int + */ + public function getAlpha() { + return $this->_alpha; + } + + /** + * Set Alpha + * + * @param int $pValue + * @return PHPExcel_Worksheet_Drawing_Shadow + */ + public function setAlpha($pValue = 0) { + $this->_alpha = $pValue; + return $this; + } + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() { + return md5( + ($this->_visible ? 't' : 'f') + . $this->_blurRadius + . $this->_distance + . $this->_direction + . $this->_alignment + . $this->_color->getHashCode() + . $this->_alpha + . __CLASS__ + ); + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } +} diff --git a/lib/phpexcel/PHPExcel/Worksheet/HeaderFooter.php b/lib/phpexcel/PHPExcel/Worksheet/HeaderFooter.php new file mode 100644 index 0000000..82d7faf --- /dev/null +++ b/lib/phpexcel/PHPExcel/Worksheet/HeaderFooter.php @@ -0,0 +1,465 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Worksheet_HeaderFooter + * + * <code> + * Header/Footer Formatting Syntax taken from Office Open XML Part 4 - Markup Language Reference, page 1970: + * + * There are a number of formatting codes that can be written inline with the actual header / footer text, which + * affect the formatting in the header or footer. + * + * Example: This example shows the text "Center Bold Header" on the first line (center section), and the date on + * the second line (center section). + * &CCenter &"-,Bold"Bold&"-,Regular"Header_x000A_&D + * + * General Rules: + * There is no required order in which these codes must appear. + * + * The first occurrence of the following codes turns the formatting ON, the second occurrence turns it OFF again: + * - strikethrough + * - superscript + * - subscript + * Superscript and subscript cannot both be ON at same time. Whichever comes first wins and the other is ignored, + * while the first is ON. + * &L - code for "left section" (there are three header / footer locations, "left", "center", and "right"). When + * two or more occurrences of this section marker exist, the contents from all markers are concatenated, in the + * order of appearance, and placed into the left section. + * &P - code for "current page #" + * &N - code for "total pages" + * &font size - code for "text font size", where font size is a font size in points. + * &K - code for "text font color" + * RGB Color is specified as RRGGBB + * Theme Color is specifed as TTSNN where TT is the theme color Id, S is either "+" or "-" of the tint/shade + * value, NN is the tint/shade value. + * &S - code for "text strikethrough" on / off + * &X - code for "text super script" on / off + * &Y - code for "text subscript" on / off + * &C - code for "center section". When two or more occurrences of this section marker exist, the contents + * from all markers are concatenated, in the order of appearance, and placed into the center section. + * + * &D - code for "date" + * &T - code for "time" + * &G - code for "picture as background" + * &U - code for "text single underline" + * &E - code for "double underline" + * &R - code for "right section". When two or more occurrences of this section marker exist, the contents + * from all markers are concatenated, in the order of appearance, and placed into the right section. + * &Z - code for "this workbook's file path" + * &F - code for "this workbook's file name" + * &A - code for "sheet tab name" + * &+ - code for add to page #. + * &- - code for subtract from page #. + * &"font name,font type" - code for "text font name" and "text font type", where font name and font type + * are strings specifying the name and type of the font, separated by a comma. When a hyphen appears in font + * name, it means "none specified". Both of font name and font type can be localized values. + * &"-,Bold" - code for "bold font style" + * &B - also means "bold font style". + * &"-,Regular" - code for "regular font style" + * &"-,Italic" - code for "italic font style" + * &I - also means "italic font style" + * &"-,Bold Italic" code for "bold italic font style" + * &O - code for "outline style" + * &H - code for "shadow style" + * </code> + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Worksheet_HeaderFooter +{ + /* Header/footer image location */ + const IMAGE_HEADER_LEFT = 'LH'; + const IMAGE_HEADER_CENTER = 'CH'; + const IMAGE_HEADER_RIGHT = 'RH'; + const IMAGE_FOOTER_LEFT = 'LF'; + const IMAGE_FOOTER_CENTER = 'CF'; + const IMAGE_FOOTER_RIGHT = 'RF'; + + /** + * OddHeader + * + * @var string + */ + private $_oddHeader = ''; + + /** + * OddFooter + * + * @var string + */ + private $_oddFooter = ''; + + /** + * EvenHeader + * + * @var string + */ + private $_evenHeader = ''; + + /** + * EvenFooter + * + * @var string + */ + private $_evenFooter = ''; + + /** + * FirstHeader + * + * @var string + */ + private $_firstHeader = ''; + + /** + * FirstFooter + * + * @var string + */ + private $_firstFooter = ''; + + /** + * Different header for Odd/Even, defaults to false + * + * @var boolean + */ + private $_differentOddEven = false; + + /** + * Different header for first page, defaults to false + * + * @var boolean + */ + private $_differentFirst = false; + + /** + * Scale with document, defaults to true + * + * @var boolean + */ + private $_scaleWithDocument = true; + + /** + * Align with margins, defaults to true + * + * @var boolean + */ + private $_alignWithMargins = true; + + /** + * Header/footer images + * + * @var PHPExcel_Worksheet_HeaderFooterDrawing[] + */ + private $_headerFooterImages = array(); + + /** + * Create a new PHPExcel_Worksheet_HeaderFooter + */ + public function __construct() + { + } + + /** + * Get OddHeader + * + * @return string + */ + public function getOddHeader() { + return $this->_oddHeader; + } + + /** + * Set OddHeader + * + * @param string $pValue + * @return PHPExcel_Worksheet_HeaderFooter + */ + public function setOddHeader($pValue) { + $this->_oddHeader = $pValue; + return $this; + } + + /** + * Get OddFooter + * + * @return string + */ + public function getOddFooter() { + return $this->_oddFooter; + } + + /** + * Set OddFooter + * + * @param string $pValue + * @return PHPExcel_Worksheet_HeaderFooter + */ + public function setOddFooter($pValue) { + $this->_oddFooter = $pValue; + return $this; + } + + /** + * Get EvenHeader + * + * @return string + */ + public function getEvenHeader() { + return $this->_evenHeader; + } + + /** + * Set EvenHeader + * + * @param string $pValue + * @return PHPExcel_Worksheet_HeaderFooter + */ + public function setEvenHeader($pValue) { + $this->_evenHeader = $pValue; + return $this; + } + + /** + * Get EvenFooter + * + * @return string + */ + public function getEvenFooter() { + return $this->_evenFooter; + } + + /** + * Set EvenFooter + * + * @param string $pValue + * @return PHPExcel_Worksheet_HeaderFooter + */ + public function setEvenFooter($pValue) { + $this->_evenFooter = $pValue; + return $this; + } + + /** + * Get FirstHeader + * + * @return string + */ + public function getFirstHeader() { + return $this->_firstHeader; + } + + /** + * Set FirstHeader + * + * @param string $pValue + * @return PHPExcel_Worksheet_HeaderFooter + */ + public function setFirstHeader($pValue) { + $this->_firstHeader = $pValue; + return $this; + } + + /** + * Get FirstFooter + * + * @return string + */ + public function getFirstFooter() { + return $this->_firstFooter; + } + + /** + * Set FirstFooter + * + * @param string $pValue + * @return PHPExcel_Worksheet_HeaderFooter + */ + public function setFirstFooter($pValue) { + $this->_firstFooter = $pValue; + return $this; + } + + /** + * Get DifferentOddEven + * + * @return boolean + */ + public function getDifferentOddEven() { + return $this->_differentOddEven; + } + + /** + * Set DifferentOddEven + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_HeaderFooter + */ + public function setDifferentOddEven($pValue = false) { + $this->_differentOddEven = $pValue; + return $this; + } + + /** + * Get DifferentFirst + * + * @return boolean + */ + public function getDifferentFirst() { + return $this->_differentFirst; + } + + /** + * Set DifferentFirst + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_HeaderFooter + */ + public function setDifferentFirst($pValue = false) { + $this->_differentFirst = $pValue; + return $this; + } + + /** + * Get ScaleWithDocument + * + * @return boolean + */ + public function getScaleWithDocument() { + return $this->_scaleWithDocument; + } + + /** + * Set ScaleWithDocument + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_HeaderFooter + */ + public function setScaleWithDocument($pValue = true) { + $this->_scaleWithDocument = $pValue; + return $this; + } + + /** + * Get AlignWithMargins + * + * @return boolean + */ + public function getAlignWithMargins() { + return $this->_alignWithMargins; + } + + /** + * Set AlignWithMargins + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_HeaderFooter + */ + public function setAlignWithMargins($pValue = true) { + $this->_alignWithMargins = $pValue; + return $this; + } + + /** + * Add header/footer image + * + * @param PHPExcel_Worksheet_HeaderFooterDrawing $image + * @param string $location + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_HeaderFooter + */ + public function addImage(PHPExcel_Worksheet_HeaderFooterDrawing $image = null, $location = self::IMAGE_HEADER_LEFT) { + $this->_headerFooterImages[$location] = $image; + return $this; + } + + /** + * Remove header/footer image + * + * @param string $location + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_HeaderFooter + */ + public function removeImage($location = self::IMAGE_HEADER_LEFT) { + if (isset($this->_headerFooterImages[$location])) { + unset($this->_headerFooterImages[$location]); + } + return $this; + } + + /** + * Set header/footer images + * + * @param PHPExcel_Worksheet_HeaderFooterDrawing[] $images + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_HeaderFooter + */ + public function setImages($images) { + if (!is_array($images)) { + throw new PHPExcel_Exception('Invalid parameter!'); + } + + $this->_headerFooterImages = $images; + return $this; + } + + /** + * Get header/footer images + * + * @return PHPExcel_Worksheet_HeaderFooterDrawing[] + */ + public function getImages() { + // Sort array + $images = array(); + if (isset($this->_headerFooterImages[self::IMAGE_HEADER_LEFT])) $images[self::IMAGE_HEADER_LEFT] = $this->_headerFooterImages[self::IMAGE_HEADER_LEFT]; + if (isset($this->_headerFooterImages[self::IMAGE_HEADER_CENTER])) $images[self::IMAGE_HEADER_CENTER] = $this->_headerFooterImages[self::IMAGE_HEADER_CENTER]; + if (isset($this->_headerFooterImages[self::IMAGE_HEADER_RIGHT])) $images[self::IMAGE_HEADER_RIGHT] = $this->_headerFooterImages[self::IMAGE_HEADER_RIGHT]; + if (isset($this->_headerFooterImages[self::IMAGE_FOOTER_LEFT])) $images[self::IMAGE_FOOTER_LEFT] = $this->_headerFooterImages[self::IMAGE_FOOTER_LEFT]; + if (isset($this->_headerFooterImages[self::IMAGE_FOOTER_CENTER])) $images[self::IMAGE_FOOTER_CENTER] = $this->_headerFooterImages[self::IMAGE_FOOTER_CENTER]; + if (isset($this->_headerFooterImages[self::IMAGE_FOOTER_RIGHT])) $images[self::IMAGE_FOOTER_RIGHT] = $this->_headerFooterImages[self::IMAGE_FOOTER_RIGHT]; + $this->_headerFooterImages = $images; + + return $this->_headerFooterImages; + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } +} diff --git a/lib/phpexcel/PHPExcel/Worksheet/HeaderFooterDrawing.php b/lib/phpexcel/PHPExcel/Worksheet/HeaderFooterDrawing.php new file mode 100644 index 0000000..1c6f4e1 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Worksheet/HeaderFooterDrawing.php @@ -0,0 +1,350 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Worksheet_HeaderFooterDrawing + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Worksheet_HeaderFooterDrawing extends PHPExcel_Worksheet_Drawing implements PHPExcel_IComparable +{ + /** + * Path + * + * @var string + */ + private $_path; + + /** + * Name + * + * @var string + */ + protected $_name; + + /** + * Offset X + * + * @var int + */ + protected $_offsetX; + + /** + * Offset Y + * + * @var int + */ + protected $_offsetY; + + /** + * Width + * + * @var int + */ + protected $_width; + + /** + * Height + * + * @var int + */ + protected $_height; + + /** + * Proportional resize + * + * @var boolean + */ + protected $_resizeProportional; + + /** + * Create a new PHPExcel_Worksheet_HeaderFooterDrawing + */ + public function __construct() + { + // Initialise values + $this->_path = ''; + $this->_name = ''; + $this->_offsetX = 0; + $this->_offsetY = 0; + $this->_width = 0; + $this->_height = 0; + $this->_resizeProportional = true; + } + + /** + * Get Name + * + * @return string + */ + public function getName() { + return $this->_name; + } + + /** + * Set Name + * + * @param string $pValue + * @return PHPExcel_Worksheet_HeaderFooterDrawing + */ + public function setName($pValue = '') { + $this->_name = $pValue; + return $this; + } + + /** + * Get OffsetX + * + * @return int + */ + public function getOffsetX() { + return $this->_offsetX; + } + + /** + * Set OffsetX + * + * @param int $pValue + * @return PHPExcel_Worksheet_HeaderFooterDrawing + */ + public function setOffsetX($pValue = 0) { + $this->_offsetX = $pValue; + return $this; + } + + /** + * Get OffsetY + * + * @return int + */ + public function getOffsetY() { + return $this->_offsetY; + } + + /** + * Set OffsetY + * + * @param int $pValue + * @return PHPExcel_Worksheet_HeaderFooterDrawing + */ + public function setOffsetY($pValue = 0) { + $this->_offsetY = $pValue; + return $this; + } + + /** + * Get Width + * + * @return int + */ + public function getWidth() { + return $this->_width; + } + + /** + * Set Width + * + * @param int $pValue + * @return PHPExcel_Worksheet_HeaderFooterDrawing + */ + public function setWidth($pValue = 0) { + // Resize proportional? + if ($this->_resizeProportional && $pValue != 0) { + $ratio = $this->_width / $this->_height; + $this->_height = round($ratio * $pValue); + } + + // Set width + $this->_width = $pValue; + + return $this; + } + + /** + * Get Height + * + * @return int + */ + public function getHeight() { + return $this->_height; + } + + /** + * Set Height + * + * @param int $pValue + * @return PHPExcel_Worksheet_HeaderFooterDrawing + */ + public function setHeight($pValue = 0) { + // Resize proportional? + if ($this->_resizeProportional && $pValue != 0) { + $ratio = $this->_width / $this->_height; + $this->_width = round($ratio * $pValue); + } + + // Set height + $this->_height = $pValue; + + return $this; + } + + /** + * Set width and height with proportional resize + * Example: + * <code> + * $objDrawing->setResizeProportional(true); + * $objDrawing->setWidthAndHeight(160,120); + * </code> + * + * @author Vincent@luo MSN:kele_100@hotmail.com + * @param int $width + * @param int $height + * @return PHPExcel_Worksheet_HeaderFooterDrawing + */ + public function setWidthAndHeight($width = 0, $height = 0) { + $xratio = $width / $this->_width; + $yratio = $height / $this->_height; + if ($this->_resizeProportional && !($width == 0 || $height == 0)) { + if (($xratio * $this->_height) < $height) { + $this->_height = ceil($xratio * $this->_height); + $this->_width = $width; + } else { + $this->_width = ceil($yratio * $this->_width); + $this->_height = $height; + } + } + return $this; + } + + /** + * Get ResizeProportional + * + * @return boolean + */ + public function getResizeProportional() { + return $this->_resizeProportional; + } + + /** + * Set ResizeProportional + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_HeaderFooterDrawing + */ + public function setResizeProportional($pValue = true) { + $this->_resizeProportional = $pValue; + return $this; + } + + /** + * Get Filename + * + * @return string + */ + public function getFilename() { + return basename($this->_path); + } + + /** + * Get Extension + * + * @return string + */ + public function getExtension() { + $parts = explode(".", basename($this->_path)); + return end($parts); + } + + /** + * Get Path + * + * @return string + */ + public function getPath() { + return $this->_path; + } + + /** + * Set Path + * + * @param string $pValue File path + * @param boolean $pVerifyFile Verify file + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_HeaderFooterDrawing + */ + public function setPath($pValue = '', $pVerifyFile = true) { + if ($pVerifyFile) { + if (file_exists($pValue)) { + $this->_path = $pValue; + + if ($this->_width == 0 && $this->_height == 0) { + // Get width/height + list($this->_width, $this->_height) = getimagesize($pValue); + } + } else { + throw new PHPExcel_Exception("File $pValue not found!"); + } + } else { + $this->_path = $pValue; + } + return $this; + } + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() { + return md5( + $this->_path + . $this->_name + . $this->_offsetX + . $this->_offsetY + . $this->_width + . $this->_height + . __CLASS__ + ); + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } +} diff --git a/lib/phpexcel/PHPExcel/Worksheet/MemoryDrawing.php b/lib/phpexcel/PHPExcel/Worksheet/MemoryDrawing.php new file mode 100644 index 0000000..93266d2 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Worksheet/MemoryDrawing.php @@ -0,0 +1,200 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Worksheet_MemoryDrawing + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Worksheet_MemoryDrawing extends PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable +{ + /* Rendering functions */ + const RENDERING_DEFAULT = 'imagepng'; + const RENDERING_PNG = 'imagepng'; + const RENDERING_GIF = 'imagegif'; + const RENDERING_JPEG = 'imagejpeg'; + + /* MIME types */ + const MIMETYPE_DEFAULT = 'image/png'; + const MIMETYPE_PNG = 'image/png'; + const MIMETYPE_GIF = 'image/gif'; + const MIMETYPE_JPEG = 'image/jpeg'; + + /** + * Image resource + * + * @var resource + */ + private $_imageResource; + + /** + * Rendering function + * + * @var string + */ + private $_renderingFunction; + + /** + * Mime type + * + * @var string + */ + private $_mimeType; + + /** + * Unique name + * + * @var string + */ + private $_uniqueName; + + /** + * Create a new PHPExcel_Worksheet_MemoryDrawing + */ + public function __construct() + { + // Initialise values + $this->_imageResource = null; + $this->_renderingFunction = self::RENDERING_DEFAULT; + $this->_mimeType = self::MIMETYPE_DEFAULT; + $this->_uniqueName = md5(rand(0, 9999). time() . rand(0, 9999)); + + // Initialize parent + parent::__construct(); + } + + /** + * Get image resource + * + * @return resource + */ + public function getImageResource() { + return $this->_imageResource; + } + + /** + * Set image resource + * + * @param $value resource + * @return PHPExcel_Worksheet_MemoryDrawing + */ + public function setImageResource($value = null) { + $this->_imageResource = $value; + + if (!is_null($this->_imageResource)) { + // Get width/height + $this->_width = imagesx($this->_imageResource); + $this->_height = imagesy($this->_imageResource); + } + return $this; + } + + /** + * Get rendering function + * + * @return string + */ + public function getRenderingFunction() { + return $this->_renderingFunction; + } + + /** + * Set rendering function + * + * @param string $value + * @return PHPExcel_Worksheet_MemoryDrawing + */ + public function setRenderingFunction($value = PHPExcel_Worksheet_MemoryDrawing::RENDERING_DEFAULT) { + $this->_renderingFunction = $value; + return $this; + } + + /** + * Get mime type + * + * @return string + */ + public function getMimeType() { + return $this->_mimeType; + } + + /** + * Set mime type + * + * @param string $value + * @return PHPExcel_Worksheet_MemoryDrawing + */ + public function setMimeType($value = PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_DEFAULT) { + $this->_mimeType = $value; + return $this; + } + + /** + * Get indexed filename (using image index) + * + * @return string + */ + public function getIndexedFilename() { + $extension = strtolower($this->getMimeType()); + $extension = explode('/', $extension); + $extension = $extension[1]; + + return $this->_uniqueName . $this->getImageIndex() . '.' . $extension; + } + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() { + return md5( + $this->_renderingFunction + . $this->_mimeType + . $this->_uniqueName + . parent::getHashCode() + . __CLASS__ + ); + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } +} diff --git a/lib/phpexcel/PHPExcel/Worksheet/PageMargins.php b/lib/phpexcel/PHPExcel/Worksheet/PageMargins.php new file mode 100644 index 0000000..671711f --- /dev/null +++ b/lib/phpexcel/PHPExcel/Worksheet/PageMargins.php @@ -0,0 +1,220 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Worksheet_PageMargins + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Worksheet_PageMargins +{ + /** + * Left + * + * @var double + */ + private $_left = 0.7; + + /** + * Right + * + * @var double + */ + private $_right = 0.7; + + /** + * Top + * + * @var double + */ + private $_top = 0.75; + + /** + * Bottom + * + * @var double + */ + private $_bottom = 0.75; + + /** + * Header + * + * @var double + */ + private $_header = 0.3; + + /** + * Footer + * + * @var double + */ + private $_footer = 0.3; + + /** + * Create a new PHPExcel_Worksheet_PageMargins + */ + public function __construct() + { + } + + /** + * Get Left + * + * @return double + */ + public function getLeft() { + return $this->_left; + } + + /** + * Set Left + * + * @param double $pValue + * @return PHPExcel_Worksheet_PageMargins + */ + public function setLeft($pValue) { + $this->_left = $pValue; + return $this; + } + + /** + * Get Right + * + * @return double + */ + public function getRight() { + return $this->_right; + } + + /** + * Set Right + * + * @param double $pValue + * @return PHPExcel_Worksheet_PageMargins + */ + public function setRight($pValue) { + $this->_right = $pValue; + return $this; + } + + /** + * Get Top + * + * @return double + */ + public function getTop() { + return $this->_top; + } + + /** + * Set Top + * + * @param double $pValue + * @return PHPExcel_Worksheet_PageMargins + */ + public function setTop($pValue) { + $this->_top = $pValue; + return $this; + } + + /** + * Get Bottom + * + * @return double + */ + public function getBottom() { + return $this->_bottom; + } + + /** + * Set Bottom + * + * @param double $pValue + * @return PHPExcel_Worksheet_PageMargins + */ + public function setBottom($pValue) { + $this->_bottom = $pValue; + return $this; + } + + /** + * Get Header + * + * @return double + */ + public function getHeader() { + return $this->_header; + } + + /** + * Set Header + * + * @param double $pValue + * @return PHPExcel_Worksheet_PageMargins + */ + public function setHeader($pValue) { + $this->_header = $pValue; + return $this; + } + + /** + * Get Footer + * + * @return double + */ + public function getFooter() { + return $this->_footer; + } + + /** + * Set Footer + * + * @param double $pValue + * @return PHPExcel_Worksheet_PageMargins + */ + public function setFooter($pValue) { + $this->_footer = $pValue; + return $this; + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } +} diff --git a/lib/phpexcel/PHPExcel/Worksheet/PageSetup.php b/lib/phpexcel/PHPExcel/Worksheet/PageSetup.php new file mode 100644 index 0000000..9512dbe --- /dev/null +++ b/lib/phpexcel/PHPExcel/Worksheet/PageSetup.php @@ -0,0 +1,798 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Worksheet_PageSetup + * + * <code> + * Paper size taken from Office Open XML Part 4 - Markup Language Reference, page 1988: + * + * 1 = Letter paper (8.5 in. by 11 in.) + * 2 = Letter small paper (8.5 in. by 11 in.) + * 3 = Tabloid paper (11 in. by 17 in.) + * 4 = Ledger paper (17 in. by 11 in.) + * 5 = Legal paper (8.5 in. by 14 in.) + * 6 = Statement paper (5.5 in. by 8.5 in.) + * 7 = Executive paper (7.25 in. by 10.5 in.) + * 8 = A3 paper (297 mm by 420 mm) + * 9 = A4 paper (210 mm by 297 mm) + * 10 = A4 small paper (210 mm by 297 mm) + * 11 = A5 paper (148 mm by 210 mm) + * 12 = B4 paper (250 mm by 353 mm) + * 13 = B5 paper (176 mm by 250 mm) + * 14 = Folio paper (8.5 in. by 13 in.) + * 15 = Quarto paper (215 mm by 275 mm) + * 16 = Standard paper (10 in. by 14 in.) + * 17 = Standard paper (11 in. by 17 in.) + * 18 = Note paper (8.5 in. by 11 in.) + * 19 = #9 envelope (3.875 in. by 8.875 in.) + * 20 = #10 envelope (4.125 in. by 9.5 in.) + * 21 = #11 envelope (4.5 in. by 10.375 in.) + * 22 = #12 envelope (4.75 in. by 11 in.) + * 23 = #14 envelope (5 in. by 11.5 in.) + * 24 = C paper (17 in. by 22 in.) + * 25 = D paper (22 in. by 34 in.) + * 26 = E paper (34 in. by 44 in.) + * 27 = DL envelope (110 mm by 220 mm) + * 28 = C5 envelope (162 mm by 229 mm) + * 29 = C3 envelope (324 mm by 458 mm) + * 30 = C4 envelope (229 mm by 324 mm) + * 31 = C6 envelope (114 mm by 162 mm) + * 32 = C65 envelope (114 mm by 229 mm) + * 33 = B4 envelope (250 mm by 353 mm) + * 34 = B5 envelope (176 mm by 250 mm) + * 35 = B6 envelope (176 mm by 125 mm) + * 36 = Italy envelope (110 mm by 230 mm) + * 37 = Monarch envelope (3.875 in. by 7.5 in.). + * 38 = 6 3/4 envelope (3.625 in. by 6.5 in.) + * 39 = US standard fanfold (14.875 in. by 11 in.) + * 40 = German standard fanfold (8.5 in. by 12 in.) + * 41 = German legal fanfold (8.5 in. by 13 in.) + * 42 = ISO B4 (250 mm by 353 mm) + * 43 = Japanese double postcard (200 mm by 148 mm) + * 44 = Standard paper (9 in. by 11 in.) + * 45 = Standard paper (10 in. by 11 in.) + * 46 = Standard paper (15 in. by 11 in.) + * 47 = Invite envelope (220 mm by 220 mm) + * 50 = Letter extra paper (9.275 in. by 12 in.) + * 51 = Legal extra paper (9.275 in. by 15 in.) + * 52 = Tabloid extra paper (11.69 in. by 18 in.) + * 53 = A4 extra paper (236 mm by 322 mm) + * 54 = Letter transverse paper (8.275 in. by 11 in.) + * 55 = A4 transverse paper (210 mm by 297 mm) + * 56 = Letter extra transverse paper (9.275 in. by 12 in.) + * 57 = SuperA/SuperA/A4 paper (227 mm by 356 mm) + * 58 = SuperB/SuperB/A3 paper (305 mm by 487 mm) + * 59 = Letter plus paper (8.5 in. by 12.69 in.) + * 60 = A4 plus paper (210 mm by 330 mm) + * 61 = A5 transverse paper (148 mm by 210 mm) + * 62 = JIS B5 transverse paper (182 mm by 257 mm) + * 63 = A3 extra paper (322 mm by 445 mm) + * 64 = A5 extra paper (174 mm by 235 mm) + * 65 = ISO B5 extra paper (201 mm by 276 mm) + * 66 = A2 paper (420 mm by 594 mm) + * 67 = A3 transverse paper (297 mm by 420 mm) + * 68 = A3 extra transverse paper (322 mm by 445 mm) + * </code> + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Worksheet_PageSetup +{ + /* Paper size */ + const PAPERSIZE_LETTER = 1; + const PAPERSIZE_LETTER_SMALL = 2; + const PAPERSIZE_TABLOID = 3; + const PAPERSIZE_LEDGER = 4; + const PAPERSIZE_LEGAL = 5; + const PAPERSIZE_STATEMENT = 6; + const PAPERSIZE_EXECUTIVE = 7; + const PAPERSIZE_A3 = 8; + const PAPERSIZE_A4 = 9; + const PAPERSIZE_A4_SMALL = 10; + const PAPERSIZE_A5 = 11; + const PAPERSIZE_B4 = 12; + const PAPERSIZE_B5 = 13; + const PAPERSIZE_FOLIO = 14; + const PAPERSIZE_QUARTO = 15; + const PAPERSIZE_STANDARD_1 = 16; + const PAPERSIZE_STANDARD_2 = 17; + const PAPERSIZE_NOTE = 18; + const PAPERSIZE_NO9_ENVELOPE = 19; + const PAPERSIZE_NO10_ENVELOPE = 20; + const PAPERSIZE_NO11_ENVELOPE = 21; + const PAPERSIZE_NO12_ENVELOPE = 22; + const PAPERSIZE_NO14_ENVELOPE = 23; + const PAPERSIZE_C = 24; + const PAPERSIZE_D = 25; + const PAPERSIZE_E = 26; + const PAPERSIZE_DL_ENVELOPE = 27; + const PAPERSIZE_C5_ENVELOPE = 28; + const PAPERSIZE_C3_ENVELOPE = 29; + const PAPERSIZE_C4_ENVELOPE = 30; + const PAPERSIZE_C6_ENVELOPE = 31; + const PAPERSIZE_C65_ENVELOPE = 32; + const PAPERSIZE_B4_ENVELOPE = 33; + const PAPERSIZE_B5_ENVELOPE = 34; + const PAPERSIZE_B6_ENVELOPE = 35; + const PAPERSIZE_ITALY_ENVELOPE = 36; + const PAPERSIZE_MONARCH_ENVELOPE = 37; + const PAPERSIZE_6_3_4_ENVELOPE = 38; + const PAPERSIZE_US_STANDARD_FANFOLD = 39; + const PAPERSIZE_GERMAN_STANDARD_FANFOLD = 40; + const PAPERSIZE_GERMAN_LEGAL_FANFOLD = 41; + const PAPERSIZE_ISO_B4 = 42; + const PAPERSIZE_JAPANESE_DOUBLE_POSTCARD = 43; + const PAPERSIZE_STANDARD_PAPER_1 = 44; + const PAPERSIZE_STANDARD_PAPER_2 = 45; + const PAPERSIZE_STANDARD_PAPER_3 = 46; + const PAPERSIZE_INVITE_ENVELOPE = 47; + const PAPERSIZE_LETTER_EXTRA_PAPER = 48; + const PAPERSIZE_LEGAL_EXTRA_PAPER = 49; + const PAPERSIZE_TABLOID_EXTRA_PAPER = 50; + const PAPERSIZE_A4_EXTRA_PAPER = 51; + const PAPERSIZE_LETTER_TRANSVERSE_PAPER = 52; + const PAPERSIZE_A4_TRANSVERSE_PAPER = 53; + const PAPERSIZE_LETTER_EXTRA_TRANSVERSE_PAPER = 54; + const PAPERSIZE_SUPERA_SUPERA_A4_PAPER = 55; + const PAPERSIZE_SUPERB_SUPERB_A3_PAPER = 56; + const PAPERSIZE_LETTER_PLUS_PAPER = 57; + const PAPERSIZE_A4_PLUS_PAPER = 58; + const PAPERSIZE_A5_TRANSVERSE_PAPER = 59; + const PAPERSIZE_JIS_B5_TRANSVERSE_PAPER = 60; + const PAPERSIZE_A3_EXTRA_PAPER = 61; + const PAPERSIZE_A5_EXTRA_PAPER = 62; + const PAPERSIZE_ISO_B5_EXTRA_PAPER = 63; + const PAPERSIZE_A2_PAPER = 64; + const PAPERSIZE_A3_TRANSVERSE_PAPER = 65; + const PAPERSIZE_A3_EXTRA_TRANSVERSE_PAPER = 66; + + /* Page orientation */ + const ORIENTATION_DEFAULT = 'default'; + const ORIENTATION_LANDSCAPE = 'landscape'; + const ORIENTATION_PORTRAIT = 'portrait'; + + /* Print Range Set Method */ + const SETPRINTRANGE_OVERWRITE = 'O'; + const SETPRINTRANGE_INSERT = 'I'; + + + /** + * Paper size + * + * @var int + */ + private $_paperSize = PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER; + + /** + * Orientation + * + * @var string + */ + private $_orientation = PHPExcel_Worksheet_PageSetup::ORIENTATION_DEFAULT; + + /** + * Scale (Print Scale) + * + * Print scaling. Valid values range from 10 to 400 + * This setting is overridden when fitToWidth and/or fitToHeight are in use + * + * @var int? + */ + private $_scale = 100; + + /** + * Fit To Page + * Whether scale or fitToWith / fitToHeight applies + * + * @var boolean + */ + private $_fitToPage = FALSE; + + /** + * Fit To Height + * Number of vertical pages to fit on + * + * @var int? + */ + private $_fitToHeight = 1; + + /** + * Fit To Width + * Number of horizontal pages to fit on + * + * @var int? + */ + private $_fitToWidth = 1; + + /** + * Columns to repeat at left + * + * @var array Containing start column and end column, empty array if option unset + */ + private $_columnsToRepeatAtLeft = array('', ''); + + /** + * Rows to repeat at top + * + * @var array Containing start row number and end row number, empty array if option unset + */ + private $_rowsToRepeatAtTop = array(0, 0); + + /** + * Center page horizontally + * + * @var boolean + */ + private $_horizontalCentered = FALSE; + + /** + * Center page vertically + * + * @var boolean + */ + private $_verticalCentered = FALSE; + + /** + * Print area + * + * @var string + */ + private $_printArea = NULL; + + /** + * First page number + * + * @var int + */ + private $_firstPageNumber = NULL; + + /** + * Create a new PHPExcel_Worksheet_PageSetup + */ + public function __construct() + { + } + + /** + * Get Paper Size + * + * @return int + */ + public function getPaperSize() { + return $this->_paperSize; + } + + /** + * Set Paper Size + * + * @param int $pValue + * @return PHPExcel_Worksheet_PageSetup + */ + public function setPaperSize($pValue = PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER) { + $this->_paperSize = $pValue; + return $this; + } + + /** + * Get Orientation + * + * @return string + */ + public function getOrientation() { + return $this->_orientation; + } + + /** + * Set Orientation + * + * @param string $pValue + * @return PHPExcel_Worksheet_PageSetup + */ + public function setOrientation($pValue = PHPExcel_Worksheet_PageSetup::ORIENTATION_DEFAULT) { + $this->_orientation = $pValue; + return $this; + } + + /** + * Get Scale + * + * @return int? + */ + public function getScale() { + return $this->_scale; + } + + /** + * Set Scale + * + * Print scaling. Valid values range from 10 to 400 + * This setting is overridden when fitToWidth and/or fitToHeight are in use + * + * @param int? $pValue + * @param boolean $pUpdate Update fitToPage so scaling applies rather than fitToHeight / fitToWidth + * @return PHPExcel_Worksheet_PageSetup + * @throws PHPExcel_Exception + */ + public function setScale($pValue = 100, $pUpdate = true) { + // Microsoft Office Excel 2007 only allows setting a scale between 10 and 400 via the user interface, + // but it is apparently still able to handle any scale >= 0, where 0 results in 100 + if (($pValue >= 0) || is_null($pValue)) { + $this->_scale = $pValue; + if ($pUpdate) { + $this->_fitToPage = false; + } + } else { + throw new PHPExcel_Exception("Scale must not be negative"); + } + return $this; + } + + /** + * Get Fit To Page + * + * @return boolean + */ + public function getFitToPage() { + return $this->_fitToPage; + } + + /** + * Set Fit To Page + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_PageSetup + */ + public function setFitToPage($pValue = TRUE) { + $this->_fitToPage = $pValue; + return $this; + } + + /** + * Get Fit To Height + * + * @return int? + */ + public function getFitToHeight() { + return $this->_fitToHeight; + } + + /** + * Set Fit To Height + * + * @param int? $pValue + * @param boolean $pUpdate Update fitToPage so it applies rather than scaling + * @return PHPExcel_Worksheet_PageSetup + */ + public function setFitToHeight($pValue = 1, $pUpdate = TRUE) { + $this->_fitToHeight = $pValue; + if ($pUpdate) { + $this->_fitToPage = TRUE; + } + return $this; + } + + /** + * Get Fit To Width + * + * @return int? + */ + public function getFitToWidth() { + return $this->_fitToWidth; + } + + /** + * Set Fit To Width + * + * @param int? $pValue + * @param boolean $pUpdate Update fitToPage so it applies rather than scaling + * @return PHPExcel_Worksheet_PageSetup + */ + public function setFitToWidth($pValue = 1, $pUpdate = TRUE) { + $this->_fitToWidth = $pValue; + if ($pUpdate) { + $this->_fitToPage = TRUE; + } + return $this; + } + + /** + * Is Columns to repeat at left set? + * + * @return boolean + */ + public function isColumnsToRepeatAtLeftSet() { + if (is_array($this->_columnsToRepeatAtLeft)) { + if ($this->_columnsToRepeatAtLeft[0] != '' && $this->_columnsToRepeatAtLeft[1] != '') { + return true; + } + } + + return false; + } + + /** + * Get Columns to repeat at left + * + * @return array Containing start column and end column, empty array if option unset + */ + public function getColumnsToRepeatAtLeft() { + return $this->_columnsToRepeatAtLeft; + } + + /** + * Set Columns to repeat at left + * + * @param array $pValue Containing start column and end column, empty array if option unset + * @return PHPExcel_Worksheet_PageSetup + */ + public function setColumnsToRepeatAtLeft($pValue = null) { + if (is_array($pValue)) { + $this->_columnsToRepeatAtLeft = $pValue; + } + return $this; + } + + /** + * Set Columns to repeat at left by start and end + * + * @param string $pStart + * @param string $pEnd + * @return PHPExcel_Worksheet_PageSetup + */ + public function setColumnsToRepeatAtLeftByStartAndEnd($pStart = 'A', $pEnd = 'A') { + $this->_columnsToRepeatAtLeft = array($pStart, $pEnd); + return $this; + } + + /** + * Is Rows to repeat at top set? + * + * @return boolean + */ + public function isRowsToRepeatAtTopSet() { + if (is_array($this->_rowsToRepeatAtTop)) { + if ($this->_rowsToRepeatAtTop[0] != 0 && $this->_rowsToRepeatAtTop[1] != 0) { + return true; + } + } + + return false; + } + + /** + * Get Rows to repeat at top + * + * @return array Containing start column and end column, empty array if option unset + */ + public function getRowsToRepeatAtTop() { + return $this->_rowsToRepeatAtTop; + } + + /** + * Set Rows to repeat at top + * + * @param array $pValue Containing start column and end column, empty array if option unset + * @return PHPExcel_Worksheet_PageSetup + */ + public function setRowsToRepeatAtTop($pValue = null) { + if (is_array($pValue)) { + $this->_rowsToRepeatAtTop = $pValue; + } + return $this; + } + + /** + * Set Rows to repeat at top by start and end + * + * @param int $pStart + * @param int $pEnd + * @return PHPExcel_Worksheet_PageSetup + */ + public function setRowsToRepeatAtTopByStartAndEnd($pStart = 1, $pEnd = 1) { + $this->_rowsToRepeatAtTop = array($pStart, $pEnd); + return $this; + } + + /** + * Get center page horizontally + * + * @return bool + */ + public function getHorizontalCentered() { + return $this->_horizontalCentered; + } + + /** + * Set center page horizontally + * + * @param bool $value + * @return PHPExcel_Worksheet_PageSetup + */ + public function setHorizontalCentered($value = false) { + $this->_horizontalCentered = $value; + return $this; + } + + /** + * Get center page vertically + * + * @return bool + */ + public function getVerticalCentered() { + return $this->_verticalCentered; + } + + /** + * Set center page vertically + * + * @param bool $value + * @return PHPExcel_Worksheet_PageSetup + */ + public function setVerticalCentered($value = false) { + $this->_verticalCentered = $value; + return $this; + } + + /** + * Get print area + * + * @param int $index Identifier for a specific print area range if several ranges have been set + * Default behaviour, or a index value of 0, will return all ranges as a comma-separated string + * Otherwise, the specific range identified by the value of $index will be returned + * Print areas are numbered from 1 + * @throws PHPExcel_Exception + * @return string + */ + public function getPrintArea($index = 0) { + if ($index == 0) { + return $this->_printArea; + } + $printAreas = explode(',',$this->_printArea); + if (isset($printAreas[$index-1])) { + return $printAreas[$index-1]; + } + throw new PHPExcel_Exception("Requested Print Area does not exist"); + } + + /** + * Is print area set? + * + * @param int $index Identifier for a specific print area range if several ranges have been set + * Default behaviour, or an index value of 0, will identify whether any print range is set + * Otherwise, existence of the range identified by the value of $index will be returned + * Print areas are numbered from 1 + * @return boolean + */ + public function isPrintAreaSet($index = 0) { + if ($index == 0) { + return !is_null($this->_printArea); + } + $printAreas = explode(',',$this->_printArea); + return isset($printAreas[$index-1]); + } + + /** + * Clear a print area + * + * @param int $index Identifier for a specific print area range if several ranges have been set + * Default behaviour, or an index value of 0, will clear all print ranges that are set + * Otherwise, the range identified by the value of $index will be removed from the series + * Print areas are numbered from 1 + * @return PHPExcel_Worksheet_PageSetup + */ + public function clearPrintArea($index = 0) { + if ($index == 0) { + $this->_printArea = NULL; + } else { + $printAreas = explode(',',$this->_printArea); + if (isset($printAreas[$index-1])) { + unset($printAreas[$index-1]); + $this->_printArea = implode(',',$printAreas); + } + } + + return $this; + } + + /** + * Set print area. e.g. 'A1:D10' or 'A1:D10,G5:M20' + * + * @param string $value + * @param int $index Identifier for a specific print area range allowing several ranges to be set + * When the method is "O"verwrite, then a positive integer index will overwrite that indexed + * entry in the print areas list; a negative index value will identify which entry to + * overwrite working bacward through the print area to the list, with the last entry as -1. + * Specifying an index value of 0, will overwrite <b>all</b> existing print ranges. + * When the method is "I"nsert, then a positive index will insert after that indexed entry in + * the print areas list, while a negative index will insert before the indexed entry. + * Specifying an index value of 0, will always append the new print range at the end of the + * list. + * Print areas are numbered from 1 + * @param string $method Determines the method used when setting multiple print areas + * Default behaviour, or the "O" method, overwrites existing print area + * The "I" method, inserts the new print area before any specified index, or at the end of the list + * @return PHPExcel_Worksheet_PageSetup + * @throws PHPExcel_Exception + */ + public function setPrintArea($value, $index = 0, $method = self::SETPRINTRANGE_OVERWRITE) { + if (strpos($value,'!') !== false) { + throw new PHPExcel_Exception('Cell coordinate must not specify a worksheet.'); + } elseif (strpos($value,':') === false) { + throw new PHPExcel_Exception('Cell coordinate must be a range of cells.'); + } elseif (strpos($value,'$') !== false) { + throw new PHPExcel_Exception('Cell coordinate must not be absolute.'); + } + $value = strtoupper($value); + + if ($method == self::SETPRINTRANGE_OVERWRITE) { + if ($index == 0) { + $this->_printArea = $value; + } else { + $printAreas = explode(',',$this->_printArea); + if($index < 0) { + $index = count($printAreas) - abs($index) + 1; + } + if (($index <= 0) || ($index > count($printAreas))) { + throw new PHPExcel_Exception('Invalid index for setting print range.'); + } + $printAreas[$index-1] = $value; + $this->_printArea = implode(',',$printAreas); + } + } elseif($method == self::SETPRINTRANGE_INSERT) { + if ($index == 0) { + $this->_printArea .= ($this->_printArea == '') ? $value : ','.$value; + } else { + $printAreas = explode(',',$this->_printArea); + if($index < 0) { + $index = abs($index) - 1; + } + if ($index > count($printAreas)) { + throw new PHPExcel_Exception('Invalid index for setting print range.'); + } + $printAreas = array_merge(array_slice($printAreas,0,$index),array($value),array_slice($printAreas,$index)); + $this->_printArea = implode(',',$printAreas); + } + } else { + throw new PHPExcel_Exception('Invalid method for setting print range.'); + } + + return $this; + } + + /** + * Add a new print area (e.g. 'A1:D10' or 'A1:D10,G5:M20') to the list of print areas + * + * @param string $value + * @param int $index Identifier for a specific print area range allowing several ranges to be set + * A positive index will insert after that indexed entry in the print areas list, while a + * negative index will insert before the indexed entry. + * Specifying an index value of 0, will always append the new print range at the end of the + * list. + * Print areas are numbered from 1 + * @return PHPExcel_Worksheet_PageSetup + * @throws PHPExcel_Exception + */ + public function addPrintArea($value, $index = -1) { + return $this->setPrintArea($value, $index, self::SETPRINTRANGE_INSERT); + } + + /** + * Set print area + * + * @param int $column1 Column 1 + * @param int $row1 Row 1 + * @param int $column2 Column 2 + * @param int $row2 Row 2 + * @param int $index Identifier for a specific print area range allowing several ranges to be set + * When the method is "O"verwrite, then a positive integer index will overwrite that indexed + * entry in the print areas list; a negative index value will identify which entry to + * overwrite working bacward through the print area to the list, with the last entry as -1. + * Specifying an index value of 0, will overwrite <b>all</b> existing print ranges. + * When the method is "I"nsert, then a positive index will insert after that indexed entry in + * the print areas list, while a negative index will insert before the indexed entry. + * Specifying an index value of 0, will always append the new print range at the end of the + * list. + * Print areas are numbered from 1 + * @param string $method Determines the method used when setting multiple print areas + * Default behaviour, or the "O" method, overwrites existing print area + * The "I" method, inserts the new print area before any specified index, or at the end of the list + * @return PHPExcel_Worksheet_PageSetup + * @throws PHPExcel_Exception + */ + public function setPrintAreaByColumnAndRow($column1, $row1, $column2, $row2, $index = 0, $method = self::SETPRINTRANGE_OVERWRITE) + { + return $this->setPrintArea(PHPExcel_Cell::stringFromColumnIndex($column1) . $row1 . ':' . PHPExcel_Cell::stringFromColumnIndex($column2) . $row2, $index, $method); + } + + /** + * Add a new print area to the list of print areas + * + * @param int $column1 Start Column for the print area + * @param int $row1 Start Row for the print area + * @param int $column2 End Column for the print area + * @param int $row2 End Row for the print area + * @param int $index Identifier for a specific print area range allowing several ranges to be set + * A positive index will insert after that indexed entry in the print areas list, while a + * negative index will insert before the indexed entry. + * Specifying an index value of 0, will always append the new print range at the end of the + * list. + * Print areas are numbered from 1 + * @return PHPExcel_Worksheet_PageSetup + * @throws PHPExcel_Exception + */ + public function addPrintAreaByColumnAndRow($column1, $row1, $column2, $row2, $index = -1) + { + return $this->setPrintArea(PHPExcel_Cell::stringFromColumnIndex($column1) . $row1 . ':' . PHPExcel_Cell::stringFromColumnIndex($column2) . $row2, $index, self::SETPRINTRANGE_INSERT); + } + + /** + * Get first page number + * + * @return int + */ + public function getFirstPageNumber() { + return $this->_firstPageNumber; + } + + /** + * Set first page number + * + * @param int $value + * @return PHPExcel_Worksheet_HeaderFooter + */ + public function setFirstPageNumber($value = null) { + $this->_firstPageNumber = $value; + return $this; + } + + /** + * Reset first page number + * + * @return PHPExcel_Worksheet_HeaderFooter + */ + public function resetFirstPageNumber() { + return $this->setFirstPageNumber(null); + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } +} diff --git a/lib/phpexcel/PHPExcel/Worksheet/Protection.php b/lib/phpexcel/PHPExcel/Worksheet/Protection.php new file mode 100644 index 0000000..f41dd53 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Worksheet/Protection.php @@ -0,0 +1,545 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Worksheet_Protection + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Worksheet_Protection +{ + /** + * Sheet + * + * @var boolean + */ + private $_sheet = false; + + /** + * Objects + * + * @var boolean + */ + private $_objects = false; + + /** + * Scenarios + * + * @var boolean + */ + private $_scenarios = false; + + /** + * Format cells + * + * @var boolean + */ + private $_formatCells = false; + + /** + * Format columns + * + * @var boolean + */ + private $_formatColumns = false; + + /** + * Format rows + * + * @var boolean + */ + private $_formatRows = false; + + /** + * Insert columns + * + * @var boolean + */ + private $_insertColumns = false; + + /** + * Insert rows + * + * @var boolean + */ + private $_insertRows = false; + + /** + * Insert hyperlinks + * + * @var boolean + */ + private $_insertHyperlinks = false; + + /** + * Delete columns + * + * @var boolean + */ + private $_deleteColumns = false; + + /** + * Delete rows + * + * @var boolean + */ + private $_deleteRows = false; + + /** + * Select locked cells + * + * @var boolean + */ + private $_selectLockedCells = false; + + /** + * Sort + * + * @var boolean + */ + private $_sort = false; + + /** + * AutoFilter + * + * @var boolean + */ + private $_autoFilter = false; + + /** + * Pivot tables + * + * @var boolean + */ + private $_pivotTables = false; + + /** + * Select unlocked cells + * + * @var boolean + */ + private $_selectUnlockedCells = false; + + /** + * Password + * + * @var string + */ + private $_password = ''; + + /** + * Create a new PHPExcel_Worksheet_Protection + */ + public function __construct() + { + } + + /** + * Is some sort of protection enabled? + * + * @return boolean + */ + function isProtectionEnabled() { + return $this->_sheet || + $this->_objects || + $this->_scenarios || + $this->_formatCells || + $this->_formatColumns || + $this->_formatRows || + $this->_insertColumns || + $this->_insertRows || + $this->_insertHyperlinks || + $this->_deleteColumns || + $this->_deleteRows || + $this->_selectLockedCells || + $this->_sort || + $this->_autoFilter || + $this->_pivotTables || + $this->_selectUnlockedCells; + } + + /** + * Get Sheet + * + * @return boolean + */ + function getSheet() { + return $this->_sheet; + } + + /** + * Set Sheet + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_Protection + */ + function setSheet($pValue = false) { + $this->_sheet = $pValue; + return $this; + } + + /** + * Get Objects + * + * @return boolean + */ + function getObjects() { + return $this->_objects; + } + + /** + * Set Objects + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_Protection + */ + function setObjects($pValue = false) { + $this->_objects = $pValue; + return $this; + } + + /** + * Get Scenarios + * + * @return boolean + */ + function getScenarios() { + return $this->_scenarios; + } + + /** + * Set Scenarios + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_Protection + */ + function setScenarios($pValue = false) { + $this->_scenarios = $pValue; + return $this; + } + + /** + * Get FormatCells + * + * @return boolean + */ + function getFormatCells() { + return $this->_formatCells; + } + + /** + * Set FormatCells + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_Protection + */ + function setFormatCells($pValue = false) { + $this->_formatCells = $pValue; + return $this; + } + + /** + * Get FormatColumns + * + * @return boolean + */ + function getFormatColumns() { + return $this->_formatColumns; + } + + /** + * Set FormatColumns + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_Protection + */ + function setFormatColumns($pValue = false) { + $this->_formatColumns = $pValue; + return $this; + } + + /** + * Get FormatRows + * + * @return boolean + */ + function getFormatRows() { + return $this->_formatRows; + } + + /** + * Set FormatRows + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_Protection + */ + function setFormatRows($pValue = false) { + $this->_formatRows = $pValue; + return $this; + } + + /** + * Get InsertColumns + * + * @return boolean + */ + function getInsertColumns() { + return $this->_insertColumns; + } + + /** + * Set InsertColumns + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_Protection + */ + function setInsertColumns($pValue = false) { + $this->_insertColumns = $pValue; + return $this; + } + + /** + * Get InsertRows + * + * @return boolean + */ + function getInsertRows() { + return $this->_insertRows; + } + + /** + * Set InsertRows + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_Protection + */ + function setInsertRows($pValue = false) { + $this->_insertRows = $pValue; + return $this; + } + + /** + * Get InsertHyperlinks + * + * @return boolean + */ + function getInsertHyperlinks() { + return $this->_insertHyperlinks; + } + + /** + * Set InsertHyperlinks + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_Protection + */ + function setInsertHyperlinks($pValue = false) { + $this->_insertHyperlinks = $pValue; + return $this; + } + + /** + * Get DeleteColumns + * + * @return boolean + */ + function getDeleteColumns() { + return $this->_deleteColumns; + } + + /** + * Set DeleteColumns + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_Protection + */ + function setDeleteColumns($pValue = false) { + $this->_deleteColumns = $pValue; + return $this; + } + + /** + * Get DeleteRows + * + * @return boolean + */ + function getDeleteRows() { + return $this->_deleteRows; + } + + /** + * Set DeleteRows + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_Protection + */ + function setDeleteRows($pValue = false) { + $this->_deleteRows = $pValue; + return $this; + } + + /** + * Get SelectLockedCells + * + * @return boolean + */ + function getSelectLockedCells() { + return $this->_selectLockedCells; + } + + /** + * Set SelectLockedCells + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_Protection + */ + function setSelectLockedCells($pValue = false) { + $this->_selectLockedCells = $pValue; + return $this; + } + + /** + * Get Sort + * + * @return boolean + */ + function getSort() { + return $this->_sort; + } + + /** + * Set Sort + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_Protection + */ + function setSort($pValue = false) { + $this->_sort = $pValue; + return $this; + } + + /** + * Get AutoFilter + * + * @return boolean + */ + function getAutoFilter() { + return $this->_autoFilter; + } + + /** + * Set AutoFilter + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_Protection + */ + function setAutoFilter($pValue = false) { + $this->_autoFilter = $pValue; + return $this; + } + + /** + * Get PivotTables + * + * @return boolean + */ + function getPivotTables() { + return $this->_pivotTables; + } + + /** + * Set PivotTables + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_Protection + */ + function setPivotTables($pValue = false) { + $this->_pivotTables = $pValue; + return $this; + } + + /** + * Get SelectUnlockedCells + * + * @return boolean + */ + function getSelectUnlockedCells() { + return $this->_selectUnlockedCells; + } + + /** + * Set SelectUnlockedCells + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_Protection + */ + function setSelectUnlockedCells($pValue = false) { + $this->_selectUnlockedCells = $pValue; + return $this; + } + + /** + * Get Password (hashed) + * + * @return string + */ + function getPassword() { + return $this->_password; + } + + /** + * Set Password + * + * @param string $pValue + * @param boolean $pAlreadyHashed If the password has already been hashed, set this to true + * @return PHPExcel_Worksheet_Protection + */ + function setPassword($pValue = '', $pAlreadyHashed = false) { + if (!$pAlreadyHashed) { + $pValue = PHPExcel_Shared_PasswordHasher::hashPassword($pValue); + } + $this->_password = $pValue; + return $this; + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } +} diff --git a/lib/phpexcel/PHPExcel/Worksheet/Row.php b/lib/phpexcel/PHPExcel/Worksheet/Row.php new file mode 100644 index 0000000..2e9bd13 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Worksheet/Row.php @@ -0,0 +1,90 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Worksheet_Row + * + * Represents a row in PHPExcel_Worksheet, used by PHPExcel_Worksheet_RowIterator + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Worksheet_Row +{ + /** + * PHPExcel_Worksheet + * + * @var PHPExcel_Worksheet + */ + private $_parent; + + /** + * Row index + * + * @var int + */ + private $_rowIndex = 0; + + /** + * Create a new row + * + * @param PHPExcel_Worksheet $parent + * @param int $rowIndex + */ + public function __construct(PHPExcel_Worksheet $parent = null, $rowIndex = 1) { + // Set parent and row index + $this->_parent = $parent; + $this->_rowIndex = $rowIndex; + } + + /** + * Destructor + */ + public function __destruct() { + unset($this->_parent); + } + + /** + * Get row index + * + * @return int + */ + public function getRowIndex() { + return $this->_rowIndex; + } + + /** + * Get cell iterator + * + * @return PHPExcel_Worksheet_CellIterator + */ + public function getCellIterator() { + return new PHPExcel_Worksheet_CellIterator($this->_parent, $this->_rowIndex); + } +} diff --git a/lib/phpexcel/PHPExcel/Worksheet/RowDimension.php b/lib/phpexcel/PHPExcel/Worksheet/RowDimension.php new file mode 100644 index 0000000..69b7ba8 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Worksheet/RowDimension.php @@ -0,0 +1,265 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Worksheet_RowDimension + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Worksheet_RowDimension +{ + /** + * Row index + * + * @var int + */ + private $_rowIndex; + + /** + * Row height (in pt) + * + * When this is set to a negative value, the row height should be ignored by IWriter + * + * @var double + */ + private $_rowHeight = -1; + + /** + * ZeroHeight for Row? + * + * @var bool + */ + private $_zeroHeight = false; + + /** + * Visible? + * + * @var bool + */ + private $_visible = true; + + /** + * Outline level + * + * @var int + */ + private $_outlineLevel = 0; + + /** + * Collapsed + * + * @var bool + */ + private $_collapsed = false; + + /** + * Index to cellXf. Null value means row has no explicit cellXf format. + * + * @var int|null + */ + private $_xfIndex; + + /** + * Create a new PHPExcel_Worksheet_RowDimension + * + * @param int $pIndex Numeric row index + */ + public function __construct($pIndex = 0) + { + // Initialise values + $this->_rowIndex = $pIndex; + + // set row dimension as unformatted by default + $this->_xfIndex = null; + } + + /** + * Get Row Index + * + * @return int + */ + public function getRowIndex() { + return $this->_rowIndex; + } + + /** + * Set Row Index + * + * @param int $pValue + * @return PHPExcel_Worksheet_RowDimension + */ + public function setRowIndex($pValue) { + $this->_rowIndex = $pValue; + return $this; + } + + /** + * Get Row Height + * + * @return double + */ + public function getRowHeight() { + return $this->_rowHeight; + } + + /** + * Set Row Height + * + * @param double $pValue + * @return PHPExcel_Worksheet_RowDimension + */ + public function setRowHeight($pValue = -1) { + $this->_rowHeight = $pValue; + return $this; + } + + /** + * Get ZeroHeight + * + * @return bool + */ + public function getzeroHeight() { + return $this->_zeroHeight; + } + + /** + * Set ZeroHeight + * + * @param bool $pValue + * @return PHPExcel_Worksheet_RowDimension + */ + public function setzeroHeight($pValue = false) { + $this->_zeroHeight = $pValue; + return $this; + } + + /** + * Get Visible + * + * @return bool + */ + public function getVisible() { + return $this->_visible; + } + + /** + * Set Visible + * + * @param bool $pValue + * @return PHPExcel_Worksheet_RowDimension + */ + public function setVisible($pValue = true) { + $this->_visible = $pValue; + return $this; + } + + /** + * Get Outline Level + * + * @return int + */ + public function getOutlineLevel() { + return $this->_outlineLevel; + } + + /** + * Set Outline Level + * + * Value must be between 0 and 7 + * + * @param int $pValue + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_RowDimension + */ + public function setOutlineLevel($pValue) { + if ($pValue < 0 || $pValue > 7) { + throw new PHPExcel_Exception("Outline level must range between 0 and 7."); + } + + $this->_outlineLevel = $pValue; + return $this; + } + + /** + * Get Collapsed + * + * @return bool + */ + public function getCollapsed() { + return $this->_collapsed; + } + + /** + * Set Collapsed + * + * @param bool $pValue + * @return PHPExcel_Worksheet_RowDimension + */ + public function setCollapsed($pValue = true) { + $this->_collapsed = $pValue; + return $this; + } + + /** + * Get index to cellXf + * + * @return int + */ + public function getXfIndex() + { + return $this->_xfIndex; + } + + /** + * Set index to cellXf + * + * @param int $pValue + * @return PHPExcel_Worksheet_RowDimension + */ + public function setXfIndex($pValue = 0) + { + $this->_xfIndex = $pValue; + return $this; + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } +} diff --git a/lib/phpexcel/PHPExcel/Worksheet/RowIterator.php b/lib/phpexcel/PHPExcel/Worksheet/RowIterator.php new file mode 100644 index 0000000..f2d962f --- /dev/null +++ b/lib/phpexcel/PHPExcel/Worksheet/RowIterator.php @@ -0,0 +1,148 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Worksheet_RowIterator + * + * Used to iterate rows in a PHPExcel_Worksheet + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Worksheet_RowIterator implements Iterator +{ + /** + * PHPExcel_Worksheet to iterate + * + * @var PHPExcel_Worksheet + */ + private $_subject; + + /** + * Current iterator position + * + * @var int + */ + private $_position = 1; + + /** + * Start position + * + * @var int + */ + private $_startRow = 1; + + + /** + * Create a new row iterator + * + * @param PHPExcel_Worksheet $subject The worksheet to iterate over + * @param integer $startRow The row number at which to start iterating + */ + public function __construct(PHPExcel_Worksheet $subject = null, $startRow = 1) { + // Set subject + $this->_subject = $subject; + $this->resetStart($startRow); + } + + /** + * Destructor + */ + public function __destruct() { + unset($this->_subject); + } + + /** + * (Re)Set the start row and the current row pointer + * + * @param integer $startRow The row number at which to start iterating + */ + public function resetStart($startRow = 1) { + $this->_startRow = $startRow; + $this->seek($startRow); + } + + /** + * Set the row pointer to the selected row + * + * @param integer $row The row number to set the current pointer at + */ + public function seek($row = 1) { + $this->_position = $row; + } + + /** + * Rewind the iterator to the starting row + */ + public function rewind() { + $this->_position = $this->_startRow; + } + + /** + * Return the current row in this worksheet + * + * @return PHPExcel_Worksheet_Row + */ + public function current() { + return new PHPExcel_Worksheet_Row($this->_subject, $this->_position); + } + + /** + * Return the current iterator key + * + * @return int + */ + public function key() { + return $this->_position; + } + + /** + * Set the iterator to its next value + */ + public function next() { + ++$this->_position; + } + + /** + * Set the iterator to its previous value + */ + public function prev() { + if ($this->_position > 1) + --$this->_position; + } + + /** + * Indicate if more rows exist in the worksheet + * + * @return boolean + */ + public function valid() { + return $this->_position <= $this->_subject->getHighestRow(); + } +} diff --git a/lib/phpexcel/PHPExcel/Worksheet/SheetView.php b/lib/phpexcel/PHPExcel/Worksheet/SheetView.php new file mode 100644 index 0000000..05fbf28 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Worksheet/SheetView.php @@ -0,0 +1,188 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Worksheet_SheetView + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Worksheet_SheetView +{ + + /* Sheet View types */ + const SHEETVIEW_NORMAL = 'normal'; + const SHEETVIEW_PAGE_LAYOUT = 'pageLayout'; + const SHEETVIEW_PAGE_BREAK_PREVIEW = 'pageBreakPreview'; + + private static $_sheetViewTypes = array( + self::SHEETVIEW_NORMAL, + self::SHEETVIEW_PAGE_LAYOUT, + self::SHEETVIEW_PAGE_BREAK_PREVIEW, + ); + + /** + * ZoomScale + * + * Valid values range from 10 to 400. + * + * @var int + */ + private $_zoomScale = 100; + + /** + * ZoomScaleNormal + * + * Valid values range from 10 to 400. + * + * @var int + */ + private $_zoomScaleNormal = 100; + + /** + * View + * + * Valid values range from 10 to 400. + * + * @var string + */ + private $_sheetviewType = self::SHEETVIEW_NORMAL; + + /** + * Create a new PHPExcel_Worksheet_SheetView + */ + public function __construct() + { + } + + /** + * Get ZoomScale + * + * @return int + */ + public function getZoomScale() { + return $this->_zoomScale; + } + + /** + * Set ZoomScale + * + * Valid values range from 10 to 400. + * + * @param int $pValue + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_SheetView + */ + public function setZoomScale($pValue = 100) { + // Microsoft Office Excel 2007 only allows setting a scale between 10 and 400 via the user interface, + // but it is apparently still able to handle any scale >= 1 + if (($pValue >= 1) || is_null($pValue)) { + $this->_zoomScale = $pValue; + } else { + throw new PHPExcel_Exception("Scale must be greater than or equal to 1."); + } + return $this; + } + + /** + * Get ZoomScaleNormal + * + * @return int + */ + public function getZoomScaleNormal() { + return $this->_zoomScaleNormal; + } + + /** + * Set ZoomScale + * + * Valid values range from 10 to 400. + * + * @param int $pValue + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_SheetView + */ + public function setZoomScaleNormal($pValue = 100) { + if (($pValue >= 1) || is_null($pValue)) { + $this->_zoomScaleNormal = $pValue; + } else { + throw new PHPExcel_Exception("Scale must be greater than or equal to 1."); + } + return $this; + } + + /** + * Get View + * + * @return string + */ + public function getView() { + return $this->_sheetviewType; + } + + /** + * Set View + * + * Valid values are + * 'normal' self::SHEETVIEW_NORMAL + * 'pageLayout' self::SHEETVIEW_PAGE_LAYOUT + * 'pageBreakPreview' self::SHEETVIEW_PAGE_BREAK_PREVIEW + * + * @param string $pValue + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_SheetView + */ + public function setView($pValue = NULL) { + // MS Excel 2007 allows setting the view to 'normal', 'pageLayout' or 'pageBreakPreview' + // via the user interface + if ($pValue === NULL) + $pValue = self::SHEETVIEW_NORMAL; + if (in_array($pValue, self::$_sheetViewTypes)) { + $this->_sheetviewType = $pValue; + } else { + throw new PHPExcel_Exception("Invalid sheetview layout type."); + } + + return $this; + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } +} diff --git a/lib/phpexcel/PHPExcel/WorksheetIterator.php b/lib/phpexcel/PHPExcel/WorksheetIterator.php new file mode 100644 index 0000000..624b49b --- /dev/null +++ b/lib/phpexcel/PHPExcel/WorksheetIterator.php @@ -0,0 +1,118 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_WorksheetIterator + * + * Used to iterate worksheets in PHPExcel + * + * @category PHPExcel + * @package PHPExcel + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_WorksheetIterator implements Iterator +{ + /** + * Spreadsheet to iterate + * + * @var PHPExcel + */ + private $_subject; + + /** + * Current iterator position + * + * @var int + */ + private $_position = 0; + + /** + * Create a new worksheet iterator + * + * @param PHPExcel $subject + */ + public function __construct(PHPExcel $subject = null) + { + // Set subject + $this->_subject = $subject; + } + + /** + * Destructor + */ + public function __destruct() + { + unset($this->_subject); + } + + /** + * Rewind iterator + */ + public function rewind() + { + $this->_position = 0; + } + + /** + * Current PHPExcel_Worksheet + * + * @return PHPExcel_Worksheet + */ + public function current() + { + return $this->_subject->getSheet($this->_position); + } + + /** + * Current key + * + * @return int + */ + public function key() + { + return $this->_position; + } + + /** + * Next value + */ + public function next() + { + ++$this->_position; + } + + /** + * More PHPExcel_Worksheet instances available? + * + * @return boolean + */ + public function valid() + { + return $this->_position < $this->_subject->getSheetCount(); + } +} diff --git a/lib/phpexcel/PHPExcel/Writer/Abstract.php b/lib/phpexcel/PHPExcel/Writer/Abstract.php new file mode 100644 index 0000000..7e09ef8 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Writer/Abstract.php @@ -0,0 +1,158 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Writer_Abstract + * + * @category PHPExcel + * @package PHPExcel_Writer + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +abstract class PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter +{ + /** + * Write charts that are defined in the workbook? + * Identifies whether the Writer should write definitions for any charts that exist in the PHPExcel object; + * + * @var boolean + */ + protected $_includeCharts = FALSE; + + /** + * Pre-calculate formulas + * Forces PHPExcel to recalculate all formulae in a workbook when saving, so that the pre-calculated values are + * immediately available to MS Excel or other office spreadsheet viewer when opening the file + * + * @var boolean + */ + protected $_preCalculateFormulas = TRUE; + + /** + * Use disk caching where possible? + * + * @var boolean + */ + protected $_useDiskCaching = FALSE; + + /** + * Disk caching directory + * + * @var string + */ + protected $_diskCachingDirectory = './'; + + /** + * Write charts in workbook? + * If this is true, then the Writer will write definitions for any charts that exist in the PHPExcel object. + * If false (the default) it will ignore any charts defined in the PHPExcel object. + * + * @return boolean + */ + public function getIncludeCharts() { + return $this->_includeCharts; + } + + /** + * Set write charts in workbook + * Set to true, to advise the Writer to include any charts that exist in the PHPExcel object. + * Set to false (the default) to ignore charts. + * + * @param boolean $pValue + * @return PHPExcel_Writer_IWriter + */ + public function setIncludeCharts($pValue = FALSE) { + $this->_includeCharts = (boolean) $pValue; + return $this; + } + + /** + * Get Pre-Calculate Formulas flag + * If this is true (the default), then the writer will recalculate all formulae in a workbook when saving, + * so that the pre-calculated values are immediately available to MS Excel or other office spreadsheet + * viewer when opening the file + * If false, then formulae are not calculated on save. This is faster for saving in PHPExcel, but slower + * when opening the resulting file in MS Excel, because Excel has to recalculate the formulae itself + * + * @return boolean + */ + public function getPreCalculateFormulas() { + return $this->_preCalculateFormulas; + } + + /** + * Set Pre-Calculate Formulas + * Set to true (the default) to advise the Writer to calculate all formulae on save + * Set to false to prevent precalculation of formulae on save. + * + * @param boolean $pValue Pre-Calculate Formulas? + * @return PHPExcel_Writer_IWriter + */ + public function setPreCalculateFormulas($pValue = TRUE) { + $this->_preCalculateFormulas = (boolean) $pValue; + return $this; + } + + /** + * Get use disk caching where possible? + * + * @return boolean + */ + public function getUseDiskCaching() { + return $this->_useDiskCaching; + } + + /** + * Set use disk caching where possible? + * + * @param boolean $pValue + * @param string $pDirectory Disk caching directory + * @throws PHPExcel_Writer_Exception when directory does not exist + * @return PHPExcel_Writer_Excel2007 + */ + public function setUseDiskCaching($pValue = FALSE, $pDirectory = NULL) { + $this->_useDiskCaching = $pValue; + + if ($pDirectory !== NULL) { + if (is_dir($pDirectory)) { + $this->_diskCachingDirectory = $pDirectory; + } else { + throw new PHPExcel_Writer_Exception("Directory does not exist: $pDirectory"); + } + } + return $this; + } + + /** + * Get disk caching directory + * + * @return string + */ + public function getDiskCachingDirectory() { + return $this->_diskCachingDirectory; + } +} diff --git a/lib/phpexcel/PHPExcel/Writer/CSV.php b/lib/phpexcel/PHPExcel/Writer/CSV.php new file mode 100644 index 0000000..521874f --- /dev/null +++ b/lib/phpexcel/PHPExcel/Writer/CSV.php @@ -0,0 +1,310 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_CSV + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Writer_CSV + * + * @category PHPExcel + * @package PHPExcel_Writer_CSV + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_CSV extends PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter { + /** + * PHPExcel object + * + * @var PHPExcel + */ + private $_phpExcel; + + /** + * Delimiter + * + * @var string + */ + private $_delimiter = ','; + + /** + * Enclosure + * + * @var string + */ + private $_enclosure = '"'; + + /** + * Line ending + * + * @var string + */ + private $_lineEnding = PHP_EOL; + + /** + * Sheet index to write + * + * @var int + */ + private $_sheetIndex = 0; + + /** + * Whether to write a BOM (for UTF8). + * + * @var boolean + */ + private $_useBOM = false; + + /** + * Whether to write a fully Excel compatible CSV file. + * + * @var boolean + */ + private $_excelCompatibility = false; + + /** + * Create a new PHPExcel_Writer_CSV + * + * @param PHPExcel $phpExcel PHPExcel object + */ + public function __construct(PHPExcel $phpExcel) { + $this->_phpExcel = $phpExcel; + } + + /** + * Save PHPExcel to file + * + * @param string $pFilename + * @throws PHPExcel_Writer_Exception + */ + public function save($pFilename = null) { + // Fetch sheet + $sheet = $this->_phpExcel->getSheet($this->_sheetIndex); + + $saveDebugLog = PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->getWriteDebugLog(); + PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog(FALSE); + $saveArrayReturnType = PHPExcel_Calculation::getArrayReturnType(); + PHPExcel_Calculation::setArrayReturnType(PHPExcel_Calculation::RETURN_ARRAY_AS_VALUE); + + // Open file + $fileHandle = fopen($pFilename, 'wb+'); + if ($fileHandle === false) { + throw new PHPExcel_Writer_Exception("Could not open file $pFilename for writing."); + } + + if ($this->_excelCompatibility) { + fwrite($fileHandle, "\xEF\xBB\xBF"); // Enforce UTF-8 BOM Header + $this->setEnclosure('"'); // Set enclosure to " + $this->setDelimiter(";"); // Set delimiter to a semi-colon + $this->setLineEnding("\r\n"); + fwrite($fileHandle, 'sep=' . $this->getDelimiter() . $this->_lineEnding); + } elseif ($this->_useBOM) { + // Write the UTF-8 BOM code if required + fwrite($fileHandle, "\xEF\xBB\xBF"); + } + + // Identify the range that we need to extract from the worksheet + $maxCol = $sheet->getHighestDataColumn(); + $maxRow = $sheet->getHighestDataRow(); + + // Write rows to file + for($row = 1; $row <= $maxRow; ++$row) { + // Convert the row to an array... + $cellsArray = $sheet->rangeToArray('A'.$row.':'.$maxCol.$row,'', $this->_preCalculateFormulas); + // ... and write to the file + $this->_writeLine($fileHandle, $cellsArray[0]); + } + + // Close file + fclose($fileHandle); + + PHPExcel_Calculation::setArrayReturnType($saveArrayReturnType); + PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog($saveDebugLog); + } + + /** + * Get delimiter + * + * @return string + */ + public function getDelimiter() { + return $this->_delimiter; + } + + /** + * Set delimiter + * + * @param string $pValue Delimiter, defaults to , + * @return PHPExcel_Writer_CSV + */ + public function setDelimiter($pValue = ',') { + $this->_delimiter = $pValue; + return $this; + } + + /** + * Get enclosure + * + * @return string + */ + public function getEnclosure() { + return $this->_enclosure; + } + + /** + * Set enclosure + * + * @param string $pValue Enclosure, defaults to " + * @return PHPExcel_Writer_CSV + */ + public function setEnclosure($pValue = '"') { + if ($pValue == '') { + $pValue = null; + } + $this->_enclosure = $pValue; + return $this; + } + + /** + * Get line ending + * + * @return string + */ + public function getLineEnding() { + return $this->_lineEnding; + } + + /** + * Set line ending + * + * @param string $pValue Line ending, defaults to OS line ending (PHP_EOL) + * @return PHPExcel_Writer_CSV + */ + public function setLineEnding($pValue = PHP_EOL) { + $this->_lineEnding = $pValue; + return $this; + } + + /** + * Get whether BOM should be used + * + * @return boolean + */ + public function getUseBOM() { + return $this->_useBOM; + } + + /** + * Set whether BOM should be used + * + * @param boolean $pValue Use UTF-8 byte-order mark? Defaults to false + * @return PHPExcel_Writer_CSV + */ + public function setUseBOM($pValue = false) { + $this->_useBOM = $pValue; + return $this; + } + + /** + * Get whether the file should be saved with full Excel Compatibility + * + * @return boolean + */ + public function getExcelCompatibility() { + return $this->_excelCompatibility; + } + + /** + * Set whether the file should be saved with full Excel Compatibility + * + * @param boolean $pValue Set the file to be written as a fully Excel compatible csv file + * Note that this overrides other settings such as useBOM, enclosure and delimiter + * @return PHPExcel_Writer_CSV + */ + public function setExcelCompatibility($pValue = false) { + $this->_excelCompatibility = $pValue; + return $this; + } + + /** + * Get sheet index + * + * @return int + */ + public function getSheetIndex() { + return $this->_sheetIndex; + } + + /** + * Set sheet index + * + * @param int $pValue Sheet index + * @return PHPExcel_Writer_CSV + */ + public function setSheetIndex($pValue = 0) { + $this->_sheetIndex = $pValue; + return $this; + } + + /** + * Write line to CSV file + * + * @param mixed $pFileHandle PHP filehandle + * @param array $pValues Array containing values in a row + * @throws PHPExcel_Writer_Exception + */ + private function _writeLine($pFileHandle = null, $pValues = null) { + if (is_array($pValues)) { + // No leading delimiter + $writeDelimiter = false; + + // Build the line + $line = ''; + + foreach ($pValues as $element) { + // Escape enclosures + $element = str_replace($this->_enclosure, $this->_enclosure . $this->_enclosure, $element); + + // Add delimiter + if ($writeDelimiter) { + $line .= $this->_delimiter; + } else { + $writeDelimiter = true; + } + + // Add enclosed string + $line .= $this->_enclosure . $element . $this->_enclosure; + } + + // Add line ending + $line .= $this->_lineEnding; + + // Write to file + fwrite($pFileHandle, $line); + } else { + throw new PHPExcel_Writer_Exception("Invalid data row passed to CSV writer."); + } + } + +} diff --git a/lib/phpexcel/PHPExcel/Writer/Excel2007.php b/lib/phpexcel/PHPExcel/Writer/Excel2007.php new file mode 100644 index 0000000..a8f7593 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Writer/Excel2007.php @@ -0,0 +1,532 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Writer_Excel2007 + * + * @category PHPExcel + * @package PHPExcel_Writer_2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_Excel2007 extends PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter +{ + /** + * Pre-calculate formulas + * Forces PHPExcel to recalculate all formulae in a workbook when saving, so that the pre-calculated values are + * immediately available to MS Excel or other office spreadsheet viewer when opening the file + * + * Overrides the default TRUE for this specific writer for performance reasons + * + * @var boolean + */ + protected $_preCalculateFormulas = FALSE; + + /** + * Office2003 compatibility + * + * @var boolean + */ + private $_office2003compatibility = false; + + /** + * Private writer parts + * + * @var PHPExcel_Writer_Excel2007_WriterPart[] + */ + private $_writerParts = array(); + + /** + * Private PHPExcel + * + * @var PHPExcel + */ + private $_spreadSheet; + + /** + * Private string table + * + * @var string[] + */ + private $_stringTable = array(); + + /** + * Private unique PHPExcel_Style_Conditional HashTable + * + * @var PHPExcel_HashTable + */ + private $_stylesConditionalHashTable; + + /** + * Private unique PHPExcel_Style HashTable + * + * @var PHPExcel_HashTable + */ + private $_styleHashTable; + + /** + * Private unique PHPExcel_Style_Fill HashTable + * + * @var PHPExcel_HashTable + */ + private $_fillHashTable; + + /** + * Private unique PHPExcel_Style_Font HashTable + * + * @var PHPExcel_HashTable + */ + private $_fontHashTable; + + /** + * Private unique PHPExcel_Style_Borders HashTable + * + * @var PHPExcel_HashTable + */ + private $_bordersHashTable ; + + /** + * Private unique PHPExcel_Style_NumberFormat HashTable + * + * @var PHPExcel_HashTable + */ + private $_numFmtHashTable; + + /** + * Private unique PHPExcel_Worksheet_BaseDrawing HashTable + * + * @var PHPExcel_HashTable + */ + private $_drawingHashTable; + + /** + * Create a new PHPExcel_Writer_Excel2007 + * + * @param PHPExcel $pPHPExcel + */ + public function __construct(PHPExcel $pPHPExcel = null) + { + // Assign PHPExcel + $this->setPHPExcel($pPHPExcel); + + $writerPartsArray = array( 'stringtable' => 'PHPExcel_Writer_Excel2007_StringTable', + 'contenttypes' => 'PHPExcel_Writer_Excel2007_ContentTypes', + 'docprops' => 'PHPExcel_Writer_Excel2007_DocProps', + 'rels' => 'PHPExcel_Writer_Excel2007_Rels', + 'theme' => 'PHPExcel_Writer_Excel2007_Theme', + 'style' => 'PHPExcel_Writer_Excel2007_Style', + 'workbook' => 'PHPExcel_Writer_Excel2007_Workbook', + 'worksheet' => 'PHPExcel_Writer_Excel2007_Worksheet', + 'drawing' => 'PHPExcel_Writer_Excel2007_Drawing', + 'comments' => 'PHPExcel_Writer_Excel2007_Comments', + 'chart' => 'PHPExcel_Writer_Excel2007_Chart', + 'relsvba' => 'PHPExcel_Writer_Excel2007_RelsVBA', + 'relsribbonobjects' => 'PHPExcel_Writer_Excel2007_RelsRibbon' + ); + + // Initialise writer parts + // and Assign their parent IWriters + foreach ($writerPartsArray as $writer => $class) { + $this->_writerParts[$writer] = new $class($this); + } + + $hashTablesArray = array( '_stylesConditionalHashTable', '_fillHashTable', '_fontHashTable', + '_bordersHashTable', '_numFmtHashTable', '_drawingHashTable', + '_styleHashTable' + ); + + // Set HashTable variables + foreach ($hashTablesArray as $tableName) { + $this->$tableName = new PHPExcel_HashTable(); + } + } + + /** + * Get writer part + * + * @param string $pPartName Writer part name + * @return PHPExcel_Writer_Excel2007_WriterPart + */ + public function getWriterPart($pPartName = '') { + if ($pPartName != '' && isset($this->_writerParts[strtolower($pPartName)])) { + return $this->_writerParts[strtolower($pPartName)]; + } else { + return null; + } + } + + /** + * Save PHPExcel to file + * + * @param string $pFilename + * @throws PHPExcel_Writer_Exception + */ + public function save($pFilename = null) + { + if ($this->_spreadSheet !== NULL) { + // garbage collect + $this->_spreadSheet->garbageCollect(); + + // If $pFilename is php://output or php://stdout, make it a temporary file... + $originalFilename = $pFilename; + if (strtolower($pFilename) == 'php://output' || strtolower($pFilename) == 'php://stdout') { + $pFilename = @tempnam(PHPExcel_Shared_File::sys_get_temp_dir(), 'phpxltmp'); + if ($pFilename == '') { + $pFilename = $originalFilename; + } + } + + $saveDebugLog = PHPExcel_Calculation::getInstance($this->_spreadSheet)->getDebugLog()->getWriteDebugLog(); + PHPExcel_Calculation::getInstance($this->_spreadSheet)->getDebugLog()->setWriteDebugLog(FALSE); + $saveDateReturnType = PHPExcel_Calculation_Functions::getReturnDateType(); + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); + + // Create string lookup table + $this->_stringTable = array(); + for ($i = 0; $i < $this->_spreadSheet->getSheetCount(); ++$i) { + $this->_stringTable = $this->getWriterPart('StringTable')->createStringTable($this->_spreadSheet->getSheet($i), $this->_stringTable); + } + + // Create styles dictionaries + $this->_styleHashTable->addFromSource( $this->getWriterPart('Style')->allStyles($this->_spreadSheet) ); + $this->_stylesConditionalHashTable->addFromSource( $this->getWriterPart('Style')->allConditionalStyles($this->_spreadSheet) ); + $this->_fillHashTable->addFromSource( $this->getWriterPart('Style')->allFills($this->_spreadSheet) ); + $this->_fontHashTable->addFromSource( $this->getWriterPart('Style')->allFonts($this->_spreadSheet) ); + $this->_bordersHashTable->addFromSource( $this->getWriterPart('Style')->allBorders($this->_spreadSheet) ); + $this->_numFmtHashTable->addFromSource( $this->getWriterPart('Style')->allNumberFormats($this->_spreadSheet) ); + + // Create drawing dictionary + $this->_drawingHashTable->addFromSource( $this->getWriterPart('Drawing')->allDrawings($this->_spreadSheet) ); + + // Create new ZIP file and open it for writing + $zipClass = PHPExcel_Settings::getZipClass(); + $objZip = new $zipClass(); + + // Retrieve OVERWRITE and CREATE constants from the instantiated zip class + // This method of accessing constant values from a dynamic class should work with all appropriate versions of PHP + $ro = new ReflectionObject($objZip); + $zipOverWrite = $ro->getConstant('OVERWRITE'); + $zipCreate = $ro->getConstant('CREATE'); + + if (file_exists($pFilename)) { + unlink($pFilename); + } + // Try opening the ZIP file + if ($objZip->open($pFilename, $zipOverWrite) !== true) { + if ($objZip->open($pFilename, $zipCreate) !== true) { + throw new PHPExcel_Writer_Exception("Could not open " . $pFilename . " for writing."); + } + } + + // Add [Content_Types].xml to ZIP file + $objZip->addFromString('[Content_Types].xml', $this->getWriterPart('ContentTypes')->writeContentTypes($this->_spreadSheet, $this->_includeCharts)); + + //if hasMacros, add the vbaProject.bin file, Certificate file(if exists) + if($this->_spreadSheet->hasMacros()){ + $macrosCode=$this->_spreadSheet->getMacrosCode(); + if(!is_null($macrosCode)){// we have the code ? + $objZip->addFromString('xl/vbaProject.bin', $macrosCode);//allways in 'xl', allways named vbaProject.bin + if($this->_spreadSheet->hasMacrosCertificate()){//signed macros ? + // Yes : add the certificate file and the related rels file + $objZip->addFromString('xl/vbaProjectSignature.bin', $this->_spreadSheet->getMacrosCertificate()); + $objZip->addFromString('xl/_rels/vbaProject.bin.rels', + $this->getWriterPart('RelsVBA')->writeVBARelationships($this->_spreadSheet)); + } + } + } + //a custom UI in this workbook ? add it ("base" xml and additional objects (pictures) and rels) + if($this->_spreadSheet->hasRibbon()){ + $tmpRibbonTarget=$this->_spreadSheet->getRibbonXMLData('target'); + $objZip->addFromString($tmpRibbonTarget, $this->_spreadSheet->getRibbonXMLData('data')); + if($this->_spreadSheet->hasRibbonBinObjects()){ + $tmpRootPath=dirname($tmpRibbonTarget).'/'; + $ribbonBinObjects=$this->_spreadSheet->getRibbonBinObjects('data');//the files to write + foreach($ribbonBinObjects as $aPath=>$aContent){ + $objZip->addFromString($tmpRootPath.$aPath, $aContent); + } + //the rels for files + $objZip->addFromString($tmpRootPath.'_rels/'.basename($tmpRibbonTarget).'.rels', + $this->getWriterPart('RelsRibbonObjects')->writeRibbonRelationships($this->_spreadSheet)); + } + } + + // Add relationships to ZIP file + $objZip->addFromString('_rels/.rels', $this->getWriterPart('Rels')->writeRelationships($this->_spreadSheet)); + $objZip->addFromString('xl/_rels/workbook.xml.rels', $this->getWriterPart('Rels')->writeWorkbookRelationships($this->_spreadSheet)); + + // Add document properties to ZIP file + $objZip->addFromString('docProps/app.xml', $this->getWriterPart('DocProps')->writeDocPropsApp($this->_spreadSheet)); + $objZip->addFromString('docProps/core.xml', $this->getWriterPart('DocProps')->writeDocPropsCore($this->_spreadSheet)); + $customPropertiesPart = $this->getWriterPart('DocProps')->writeDocPropsCustom($this->_spreadSheet); + if ($customPropertiesPart !== NULL) { + $objZip->addFromString('docProps/custom.xml', $customPropertiesPart); + } + + // Add theme to ZIP file + $objZip->addFromString('xl/theme/theme1.xml', $this->getWriterPart('Theme')->writeTheme($this->_spreadSheet)); + + // Add string table to ZIP file + $objZip->addFromString('xl/sharedStrings.xml', $this->getWriterPart('StringTable')->writeStringTable($this->_stringTable)); + + // Add styles to ZIP file + $objZip->addFromString('xl/styles.xml', $this->getWriterPart('Style')->writeStyles($this->_spreadSheet)); + + // Add workbook to ZIP file + $objZip->addFromString('xl/workbook.xml', $this->getWriterPart('Workbook')->writeWorkbook($this->_spreadSheet, $this->_preCalculateFormulas)); + + $chartCount = 0; + // Add worksheets + for ($i = 0; $i < $this->_spreadSheet->getSheetCount(); ++$i) { + $objZip->addFromString('xl/worksheets/sheet' . ($i + 1) . '.xml', $this->getWriterPart('Worksheet')->writeWorksheet($this->_spreadSheet->getSheet($i), $this->_stringTable, $this->_includeCharts)); + if ($this->_includeCharts) { + $charts = $this->_spreadSheet->getSheet($i)->getChartCollection(); + if (count($charts) > 0) { + foreach($charts as $chart) { + $objZip->addFromString('xl/charts/chart' . ($chartCount + 1) . '.xml', $this->getWriterPart('Chart')->writeChart($chart)); + $chartCount++; + } + } + } + } + + $chartRef1 = $chartRef2 = 0; + // Add worksheet relationships (drawings, ...) + for ($i = 0; $i < $this->_spreadSheet->getSheetCount(); ++$i) { + + // Add relationships + $objZip->addFromString('xl/worksheets/_rels/sheet' . ($i + 1) . '.xml.rels', $this->getWriterPart('Rels')->writeWorksheetRelationships($this->_spreadSheet->getSheet($i), ($i + 1), $this->_includeCharts)); + + $drawings = $this->_spreadSheet->getSheet($i)->getDrawingCollection(); + $drawingCount = count($drawings); + if ($this->_includeCharts) { + $chartCount = $this->_spreadSheet->getSheet($i)->getChartCount(); + } + + // Add drawing and image relationship parts + if (($drawingCount > 0) || ($chartCount > 0)) { + // Drawing relationships + $objZip->addFromString('xl/drawings/_rels/drawing' . ($i + 1) . '.xml.rels', $this->getWriterPart('Rels')->writeDrawingRelationships($this->_spreadSheet->getSheet($i),$chartRef1, $this->_includeCharts)); + + // Drawings + $objZip->addFromString('xl/drawings/drawing' . ($i + 1) . '.xml', $this->getWriterPart('Drawing')->writeDrawings($this->_spreadSheet->getSheet($i),$chartRef2,$this->_includeCharts)); + } + + // Add comment relationship parts + if (count($this->_spreadSheet->getSheet($i)->getComments()) > 0) { + // VML Comments + $objZip->addFromString('xl/drawings/vmlDrawing' . ($i + 1) . '.vml', $this->getWriterPart('Comments')->writeVMLComments($this->_spreadSheet->getSheet($i))); + + // Comments + $objZip->addFromString('xl/comments' . ($i + 1) . '.xml', $this->getWriterPart('Comments')->writeComments($this->_spreadSheet->getSheet($i))); + } + + // Add header/footer relationship parts + if (count($this->_spreadSheet->getSheet($i)->getHeaderFooter()->getImages()) > 0) { + // VML Drawings + $objZip->addFromString('xl/drawings/vmlDrawingHF' . ($i + 1) . '.vml', $this->getWriterPart('Drawing')->writeVMLHeaderFooterImages($this->_spreadSheet->getSheet($i))); + + // VML Drawing relationships + $objZip->addFromString('xl/drawings/_rels/vmlDrawingHF' . ($i + 1) . '.vml.rels', $this->getWriterPart('Rels')->writeHeaderFooterDrawingRelationships($this->_spreadSheet->getSheet($i))); + + // Media + foreach ($this->_spreadSheet->getSheet($i)->getHeaderFooter()->getImages() as $image) { + $objZip->addFromString('xl/media/' . $image->getIndexedFilename(), file_get_contents($image->getPath())); + } + } + } + + // Add media + for ($i = 0; $i < $this->getDrawingHashTable()->count(); ++$i) { + if ($this->getDrawingHashTable()->getByIndex($i) instanceof PHPExcel_Worksheet_Drawing) { + $imageContents = null; + $imagePath = $this->getDrawingHashTable()->getByIndex($i)->getPath(); + if (strpos($imagePath, 'zip://') !== false) { + $imagePath = substr($imagePath, 6); + $imagePathSplitted = explode('#', $imagePath); + + $imageZip = new ZipArchive(); + $imageZip->open($imagePathSplitted[0]); + $imageContents = $imageZip->getFromName($imagePathSplitted[1]); + $imageZip->close(); + unset($imageZip); + } else { + $imageContents = file_get_contents($imagePath); + } + + $objZip->addFromString('xl/media/' . str_replace(' ', '_', $this->getDrawingHashTable()->getByIndex($i)->getIndexedFilename()), $imageContents); + } else if ($this->getDrawingHashTable()->getByIndex($i) instanceof PHPExcel_Worksheet_MemoryDrawing) { + ob_start(); + call_user_func( + $this->getDrawingHashTable()->getByIndex($i)->getRenderingFunction(), + $this->getDrawingHashTable()->getByIndex($i)->getImageResource() + ); + $imageContents = ob_get_contents(); + ob_end_clean(); + + $objZip->addFromString('xl/media/' . str_replace(' ', '_', $this->getDrawingHashTable()->getByIndex($i)->getIndexedFilename()), $imageContents); + } + } + + PHPExcel_Calculation_Functions::setReturnDateType($saveDateReturnType); + PHPExcel_Calculation::getInstance($this->_spreadSheet)->getDebugLog()->setWriteDebugLog($saveDebugLog); + + // Close file + if ($objZip->close() === false) { + throw new PHPExcel_Writer_Exception("Could not close zip file $pFilename."); + } + + // If a temporary file was used, copy it to the correct file stream + if ($originalFilename != $pFilename) { + if (copy($pFilename, $originalFilename) === false) { + throw new PHPExcel_Writer_Exception("Could not copy temporary zip file $pFilename to $originalFilename."); + } + @unlink($pFilename); + } + } else { + throw new PHPExcel_Writer_Exception("PHPExcel object unassigned."); + } + } + + /** + * Get PHPExcel object + * + * @return PHPExcel + * @throws PHPExcel_Writer_Exception + */ + public function getPHPExcel() { + if ($this->_spreadSheet !== null) { + return $this->_spreadSheet; + } else { + throw new PHPExcel_Writer_Exception("No PHPExcel assigned."); + } + } + + /** + * Set PHPExcel object + * + * @param PHPExcel $pPHPExcel PHPExcel object + * @throws PHPExcel_Writer_Exception + * @return PHPExcel_Writer_Excel2007 + */ + public function setPHPExcel(PHPExcel $pPHPExcel = null) { + $this->_spreadSheet = $pPHPExcel; + return $this; + } + + /** + * Get string table + * + * @return string[] + */ + public function getStringTable() { + return $this->_stringTable; + } + + /** + * Get PHPExcel_Style HashTable + * + * @return PHPExcel_HashTable + */ + public function getStyleHashTable() { + return $this->_styleHashTable; + } + + /** + * Get PHPExcel_Style_Conditional HashTable + * + * @return PHPExcel_HashTable + */ + public function getStylesConditionalHashTable() { + return $this->_stylesConditionalHashTable; + } + + /** + * Get PHPExcel_Style_Fill HashTable + * + * @return PHPExcel_HashTable + */ + public function getFillHashTable() { + return $this->_fillHashTable; + } + + /** + * Get PHPExcel_Style_Font HashTable + * + * @return PHPExcel_HashTable + */ + public function getFontHashTable() { + return $this->_fontHashTable; + } + + /** + * Get PHPExcel_Style_Borders HashTable + * + * @return PHPExcel_HashTable + */ + public function getBordersHashTable() { + return $this->_bordersHashTable; + } + + /** + * Get PHPExcel_Style_NumberFormat HashTable + * + * @return PHPExcel_HashTable + */ + public function getNumFmtHashTable() { + return $this->_numFmtHashTable; + } + + /** + * Get PHPExcel_Worksheet_BaseDrawing HashTable + * + * @return PHPExcel_HashTable + */ + public function getDrawingHashTable() { + return $this->_drawingHashTable; + } + + /** + * Get Office2003 compatibility + * + * @return boolean + */ + public function getOffice2003Compatibility() { + return $this->_office2003compatibility; + } + + /** + * Set Office2003 compatibility + * + * @param boolean $pValue Office2003 compatibility? + * @return PHPExcel_Writer_Excel2007 + */ + public function setOffice2003Compatibility($pValue = false) { + $this->_office2003compatibility = $pValue; + return $this; + } + +} diff --git a/lib/phpexcel/PHPExcel/Writer/Excel2007/Chart.php b/lib/phpexcel/PHPExcel/Writer/Excel2007/Chart.php new file mode 100644 index 0000000..526daa9 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Writer/Excel2007/Chart.php @@ -0,0 +1,1203 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Writer_Excel2007_Chart + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_Excel2007_Chart extends PHPExcel_Writer_Excel2007_WriterPart +{ + /** + * Write charts to XML format + * + * @param PHPExcel_Chart $pChart + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeChart(PHPExcel_Chart $pChart = null) + { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + // Ensure that data series values are up-to-date before we save + $pChart->refresh(); + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // c:chartSpace + $objWriter->startElement('c:chartSpace'); + $objWriter->writeAttribute('xmlns:c', 'http://schemas.openxmlformats.org/drawingml/2006/chart'); + $objWriter->writeAttribute('xmlns:a', 'http://schemas.openxmlformats.org/drawingml/2006/main'); + $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'); + + $objWriter->startElement('c:date1904'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + $objWriter->startElement('c:lang'); + $objWriter->writeAttribute('val', "en-GB"); + $objWriter->endElement(); + $objWriter->startElement('c:roundedCorners'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + + $this->_writeAlternateContent($objWriter); + + $objWriter->startElement('c:chart'); + + $this->_writeTitle($pChart->getTitle(), $objWriter); + + $objWriter->startElement('c:autoTitleDeleted'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + + $this->_writePlotArea($pChart->getPlotArea(), + $pChart->getXAxisLabel(), + $pChart->getYAxisLabel(), + $objWriter, + $pChart->getWorksheet() + ); + + $this->_writeLegend($pChart->getLegend(), $objWriter); + + + $objWriter->startElement('c:plotVisOnly'); + $objWriter->writeAttribute('val', 1); + $objWriter->endElement(); + + $objWriter->startElement('c:dispBlanksAs'); + $objWriter->writeAttribute('val', "gap"); + $objWriter->endElement(); + + $objWriter->startElement('c:showDLblsOverMax'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + + $objWriter->endElement(); + + $this->_writePrintSettings($objWriter); + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + /** + * Write Chart Title + * + * @param PHPExcel_Chart_Title $title + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @throws PHPExcel_Writer_Exception + */ + private function _writeTitle(PHPExcel_Chart_Title $title = null, $objWriter) + { + if (is_null($title)) { + return; + } + + $objWriter->startElement('c:title'); + $objWriter->startElement('c:tx'); + $objWriter->startElement('c:rich'); + + $objWriter->startElement('a:bodyPr'); + $objWriter->endElement(); + + $objWriter->startElement('a:lstStyle'); + $objWriter->endElement(); + + $objWriter->startElement('a:p'); + + $caption = $title->getCaption(); + if ((is_array($caption)) && (count($caption) > 0)) + $caption = $caption[0]; + $this->getParentWriter()->getWriterPart('stringtable')->writeRichTextForCharts($objWriter, $caption, 'a'); + + $objWriter->endElement(); + $objWriter->endElement(); + $objWriter->endElement(); + + $layout = $title->getLayout(); + $this->_writeLayout($layout, $objWriter); + + $objWriter->startElement('c:overlay'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + + $objWriter->endElement(); + } + + /** + * Write Chart Legend + * + * @param PHPExcel_Chart_Legend $legend + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @throws PHPExcel_Writer_Exception + */ + private function _writeLegend(PHPExcel_Chart_Legend $legend = null, $objWriter) + { + if (is_null($legend)) { + return; + } + + $objWriter->startElement('c:legend'); + + $objWriter->startElement('c:legendPos'); + $objWriter->writeAttribute('val', $legend->getPosition()); + $objWriter->endElement(); + + $layout = $legend->getLayout(); + $this->_writeLayout($layout, $objWriter); + + $objWriter->startElement('c:overlay'); + $objWriter->writeAttribute('val', ($legend->getOverlay()) ? '1' : '0'); + $objWriter->endElement(); + + $objWriter->startElement('c:txPr'); + $objWriter->startElement('a:bodyPr'); + $objWriter->endElement(); + + $objWriter->startElement('a:lstStyle'); + $objWriter->endElement(); + + $objWriter->startElement('a:p'); + $objWriter->startElement('a:pPr'); + $objWriter->writeAttribute('rtl', 0); + + $objWriter->startElement('a:defRPr'); + $objWriter->endElement(); + $objWriter->endElement(); + + $objWriter->startElement('a:endParaRPr'); + $objWriter->writeAttribute('lang', "en-US"); + $objWriter->endElement(); + + $objWriter->endElement(); + $objWriter->endElement(); + + $objWriter->endElement(); + } + + /** + * Write Chart Plot Area + * + * @param PHPExcel_Chart_PlotArea $plotArea + * @param PHPExcel_Chart_Title $xAxisLabel + * @param PHPExcel_Chart_Title $yAxisLabel + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @throws PHPExcel_Writer_Exception + */ + private function _writePlotArea(PHPExcel_Chart_PlotArea $plotArea, + PHPExcel_Chart_Title $xAxisLabel = NULL, + PHPExcel_Chart_Title $yAxisLabel = NULL, + $objWriter, + PHPExcel_Worksheet $pSheet) + { + if (is_null($plotArea)) { + return; + } + + $id1 = $id2 = 0; + $this->_seriesIndex = 0; + $objWriter->startElement('c:plotArea'); + + $layout = $plotArea->getLayout(); + + $this->_writeLayout($layout, $objWriter); + + $chartTypes = self::_getChartType($plotArea); + $catIsMultiLevelSeries = $valIsMultiLevelSeries = FALSE; + $plotGroupingType = ''; + foreach($chartTypes as $chartType) { + $objWriter->startElement('c:'.$chartType); + + $groupCount = $plotArea->getPlotGroupCount(); + for($i = 0; $i < $groupCount; ++$i) { + $plotGroup = $plotArea->getPlotGroupByIndex($i); + $groupType = $plotGroup->getPlotType(); + if ($groupType == $chartType) { + + $plotStyle = $plotGroup->getPlotStyle(); + if ($groupType === PHPExcel_Chart_DataSeries::TYPE_RADARCHART) { + $objWriter->startElement('c:radarStyle'); + $objWriter->writeAttribute('val', $plotStyle ); + $objWriter->endElement(); + } elseif ($groupType === PHPExcel_Chart_DataSeries::TYPE_SCATTERCHART) { + $objWriter->startElement('c:scatterStyle'); + $objWriter->writeAttribute('val', $plotStyle ); + $objWriter->endElement(); + } + + $this->_writePlotGroup($plotGroup, $chartType, $objWriter, $catIsMultiLevelSeries, $valIsMultiLevelSeries, $plotGroupingType, $pSheet); + } + } + + $this->_writeDataLbls($objWriter, $layout); + + if ($chartType === PHPExcel_Chart_DataSeries::TYPE_LINECHART) { + // Line only, Line3D can't be smoothed + + $objWriter->startElement('c:smooth'); + $objWriter->writeAttribute('val', (integer) $plotGroup->getSmoothLine() ); + $objWriter->endElement(); + } elseif (($chartType === PHPExcel_Chart_DataSeries::TYPE_BARCHART) || + ($chartType === PHPExcel_Chart_DataSeries::TYPE_BARCHART_3D)) { + + $objWriter->startElement('c:gapWidth'); + $objWriter->writeAttribute('val', 150 ); + $objWriter->endElement(); + + if ($plotGroupingType == 'percentStacked' || + $plotGroupingType == 'stacked') { + + $objWriter->startElement('c:overlap'); + $objWriter->writeAttribute('val', 100 ); + $objWriter->endElement(); + } + } elseif ($chartType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) { + + $objWriter->startElement('c:bubbleScale'); + $objWriter->writeAttribute('val', 25 ); + $objWriter->endElement(); + + $objWriter->startElement('c:showNegBubbles'); + $objWriter->writeAttribute('val', 0 ); + $objWriter->endElement(); + } elseif ($chartType === PHPExcel_Chart_DataSeries::TYPE_STOCKCHART) { + + $objWriter->startElement('c:hiLowLines'); + $objWriter->endElement(); + + $objWriter->startElement( 'c:upDownBars' ); + + $objWriter->startElement( 'c:gapWidth' ); + $objWriter->writeAttribute('val', 300); + $objWriter->endElement(); + + $objWriter->startElement( 'c:upBars' ); + $objWriter->endElement(); + + $objWriter->startElement( 'c:downBars' ); + $objWriter->endElement(); + + $objWriter->endElement(); + } + + // Generate 2 unique numbers to use for axId values +// $id1 = $id2 = rand(10000000,99999999); +// do { +// $id2 = rand(10000000,99999999); +// } while ($id1 == $id2); + $id1 = '75091328'; + $id2 = '75089408'; + + if (($chartType !== PHPExcel_Chart_DataSeries::TYPE_PIECHART) && + ($chartType !== PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) && + ($chartType !== PHPExcel_Chart_DataSeries::TYPE_DONUTCHART)) { + + $objWriter->startElement('c:axId'); + $objWriter->writeAttribute('val', $id1 ); + $objWriter->endElement(); + $objWriter->startElement('c:axId'); + $objWriter->writeAttribute('val', $id2 ); + $objWriter->endElement(); + } else { + $objWriter->startElement('c:firstSliceAng'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + + if ($chartType === PHPExcel_Chart_DataSeries::TYPE_DONUTCHART) { + + $objWriter->startElement('c:holeSize'); + $objWriter->writeAttribute('val', 50); + $objWriter->endElement(); + } + } + + $objWriter->endElement(); + } + + if (($chartType !== PHPExcel_Chart_DataSeries::TYPE_PIECHART) && + ($chartType !== PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) && + ($chartType !== PHPExcel_Chart_DataSeries::TYPE_DONUTCHART)) { + + if ($chartType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) { + $this->_writeValAx($objWriter,$plotArea,$xAxisLabel,$chartType,$id1,$id2,$catIsMultiLevelSeries); + } else { + $this->_writeCatAx($objWriter,$plotArea,$xAxisLabel,$chartType,$id1,$id2,$catIsMultiLevelSeries); + } + + $this->_writeValAx($objWriter,$plotArea,$yAxisLabel,$chartType,$id1,$id2,$valIsMultiLevelSeries); + } + + $objWriter->endElement(); + } + + /** + * Write Data Labels + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Chart_Layout $chartLayout Chart layout + * @throws PHPExcel_Writer_Exception + */ + private function _writeDataLbls($objWriter, $chartLayout) + { + $objWriter->startElement('c:dLbls'); + + $objWriter->startElement('c:showLegendKey'); + $showLegendKey = (empty($chartLayout)) ? 0 : $chartLayout->getShowLegendKey(); + $objWriter->writeAttribute('val', ((empty($showLegendKey)) ? 0 : 1) ); + $objWriter->endElement(); + + + $objWriter->startElement('c:showVal'); + $showVal = (empty($chartLayout)) ? 0 : $chartLayout->getShowVal(); + $objWriter->writeAttribute('val', ((empty($showVal)) ? 0 : 1) ); + $objWriter->endElement(); + + $objWriter->startElement('c:showCatName'); + $showCatName = (empty($chartLayout)) ? 0 : $chartLayout->getShowCatName(); + $objWriter->writeAttribute('val', ((empty($showCatName)) ? 0 : 1) ); + $objWriter->endElement(); + + $objWriter->startElement('c:showSerName'); + $showSerName = (empty($chartLayout)) ? 0 : $chartLayout->getShowSerName(); + $objWriter->writeAttribute('val', ((empty($showSerName)) ? 0 : 1) ); + $objWriter->endElement(); + + $objWriter->startElement('c:showPercent'); + $showPercent = (empty($chartLayout)) ? 0 : $chartLayout->getShowPercent(); + $objWriter->writeAttribute('val', ((empty($showPercent)) ? 0 : 1) ); + $objWriter->endElement(); + + $objWriter->startElement('c:showBubbleSize'); + $showBubbleSize = (empty($chartLayout)) ? 0 : $chartLayout->getShowBubbleSize(); + $objWriter->writeAttribute('val', ((empty($showBubbleSize)) ? 0 : 1) ); + $objWriter->endElement(); + + $objWriter->startElement('c:showLeaderLines'); + $showLeaderLines = (empty($chartLayout)) ? 1 : $chartLayout->getShowLeaderLines(); + $objWriter->writeAttribute('val', ((empty($showLeaderLines)) ? 0 : 1) ); + $objWriter->endElement(); + + $objWriter->endElement(); + } + + /** + * Write Category Axis + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Chart_PlotArea $plotArea + * @param PHPExcel_Chart_Title $xAxisLabel + * @param string $groupType Chart type + * @param string $id1 + * @param string $id2 + * @param boolean $isMultiLevelSeries + * @throws PHPExcel_Writer_Exception + */ + private function _writeCatAx($objWriter, PHPExcel_Chart_PlotArea $plotArea, $xAxisLabel, $groupType, $id1, $id2, $isMultiLevelSeries) + { + $objWriter->startElement('c:catAx'); + + if ($id1 > 0) { + $objWriter->startElement('c:axId'); + $objWriter->writeAttribute('val', $id1); + $objWriter->endElement(); + } + + $objWriter->startElement('c:scaling'); + $objWriter->startElement('c:orientation'); + $objWriter->writeAttribute('val', "minMax"); + $objWriter->endElement(); + $objWriter->endElement(); + + $objWriter->startElement('c:delete'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + + $objWriter->startElement('c:axPos'); + $objWriter->writeAttribute('val', "b"); + $objWriter->endElement(); + + if (!is_null($xAxisLabel)) { + $objWriter->startElement('c:title'); + $objWriter->startElement('c:tx'); + $objWriter->startElement('c:rich'); + + $objWriter->startElement('a:bodyPr'); + $objWriter->endElement(); + + $objWriter->startElement('a:lstStyle'); + $objWriter->endElement(); + + $objWriter->startElement('a:p'); + $objWriter->startElement('a:r'); + + $caption = $xAxisLabel->getCaption(); + if (is_array($caption)) + $caption = $caption[0]; + $objWriter->startElement('a:t'); +// $objWriter->writeAttribute('xml:space', 'preserve'); + $objWriter->writeRawData(PHPExcel_Shared_String::ControlCharacterPHP2OOXML( $caption )); + $objWriter->endElement(); + + $objWriter->endElement(); + $objWriter->endElement(); + $objWriter->endElement(); + $objWriter->endElement(); + + $layout = $xAxisLabel->getLayout(); + $this->_writeLayout($layout, $objWriter); + + $objWriter->startElement('c:overlay'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + + $objWriter->endElement(); + + } + + $objWriter->startElement('c:numFmt'); + $objWriter->writeAttribute('formatCode', "General"); + $objWriter->writeAttribute('sourceLinked', 1); + $objWriter->endElement(); + + $objWriter->startElement('c:majorTickMark'); + $objWriter->writeAttribute('val', "out"); + $objWriter->endElement(); + + $objWriter->startElement('c:minorTickMark'); + $objWriter->writeAttribute('val', "none"); + $objWriter->endElement(); + + $objWriter->startElement('c:tickLblPos'); + $objWriter->writeAttribute('val', "nextTo"); + $objWriter->endElement(); + + if ($id2 > 0) { + $objWriter->startElement('c:crossAx'); + $objWriter->writeAttribute('val', $id2); + $objWriter->endElement(); + + $objWriter->startElement('c:crosses'); + $objWriter->writeAttribute('val', "autoZero"); + $objWriter->endElement(); + } + + $objWriter->startElement('c:auto'); + $objWriter->writeAttribute('val', 1); + $objWriter->endElement(); + + $objWriter->startElement('c:lblAlgn'); + $objWriter->writeAttribute('val', "ctr"); + $objWriter->endElement(); + + $objWriter->startElement('c:lblOffset'); + $objWriter->writeAttribute('val', 100); + $objWriter->endElement(); + + if ($isMultiLevelSeries) { + $objWriter->startElement('c:noMultiLvlLbl'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + } + $objWriter->endElement(); + + } + + + /** + * Write Value Axis + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Chart_PlotArea $plotArea + * @param PHPExcel_Chart_Title $yAxisLabel + * @param string $groupType Chart type + * @param string $id1 + * @param string $id2 + * @param boolean $isMultiLevelSeries + * @throws PHPExcel_Writer_Exception + */ + private function _writeValAx($objWriter, PHPExcel_Chart_PlotArea $plotArea, $yAxisLabel, $groupType, $id1, $id2, $isMultiLevelSeries) + { + $objWriter->startElement('c:valAx'); + + if ($id2 > 0) { + $objWriter->startElement('c:axId'); + $objWriter->writeAttribute('val', $id2); + $objWriter->endElement(); + } + + $objWriter->startElement('c:scaling'); + $objWriter->startElement('c:orientation'); + $objWriter->writeAttribute('val', "minMax"); + $objWriter->endElement(); + $objWriter->endElement(); + + $objWriter->startElement('c:delete'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + + $objWriter->startElement('c:axPos'); + $objWriter->writeAttribute('val', "l"); + $objWriter->endElement(); + + $objWriter->startElement('c:majorGridlines'); + $objWriter->endElement(); + + if (!is_null($yAxisLabel)) { + $objWriter->startElement('c:title'); + $objWriter->startElement('c:tx'); + $objWriter->startElement('c:rich'); + + $objWriter->startElement('a:bodyPr'); + $objWriter->endElement(); + + $objWriter->startElement('a:lstStyle'); + $objWriter->endElement(); + + $objWriter->startElement('a:p'); + $objWriter->startElement('a:r'); + + $caption = $yAxisLabel->getCaption(); + if (is_array($caption)) + $caption = $caption[0]; + $objWriter->startElement('a:t'); +// $objWriter->writeAttribute('xml:space', 'preserve'); + $objWriter->writeRawData(PHPExcel_Shared_String::ControlCharacterPHP2OOXML( $caption )); + $objWriter->endElement(); + + $objWriter->endElement(); + $objWriter->endElement(); + $objWriter->endElement(); + $objWriter->endElement(); + + if ($groupType !== PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) { + $layout = $yAxisLabel->getLayout(); + $this->_writeLayout($layout, $objWriter); + } + + $objWriter->startElement('c:overlay'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + + $objWriter->endElement(); + } + + $objWriter->startElement('c:numFmt'); + $objWriter->writeAttribute('formatCode', "General"); + $objWriter->writeAttribute('sourceLinked', 1); + $objWriter->endElement(); + + $objWriter->startElement('c:majorTickMark'); + $objWriter->writeAttribute('val', "out"); + $objWriter->endElement(); + + $objWriter->startElement('c:minorTickMark'); + $objWriter->writeAttribute('val', "none"); + $objWriter->endElement(); + + $objWriter->startElement('c:tickLblPos'); + $objWriter->writeAttribute('val', "nextTo"); + $objWriter->endElement(); + + if ($id1 > 0) { + $objWriter->startElement('c:crossAx'); + $objWriter->writeAttribute('val', $id2); + $objWriter->endElement(); + + $objWriter->startElement('c:crosses'); + $objWriter->writeAttribute('val', "autoZero"); + $objWriter->endElement(); + + $objWriter->startElement('c:crossBetween'); + $objWriter->writeAttribute('val', "midCat"); + $objWriter->endElement(); + } + + if ($isMultiLevelSeries) { + if ($groupType !== PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) { + $objWriter->startElement('c:noMultiLvlLbl'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + } + } + $objWriter->endElement(); + + } + + + /** + * Get the data series type(s) for a chart plot series + * + * @param PHPExcel_Chart_PlotArea $plotArea + * @return string|array + * @throws PHPExcel_Writer_Exception + */ + private static function _getChartType($plotArea) + { + $groupCount = $plotArea->getPlotGroupCount(); + + if ($groupCount == 1) { + $chartType = array($plotArea->getPlotGroupByIndex(0)->getPlotType()); + } else { + $chartTypes = array(); + for($i = 0; $i < $groupCount; ++$i) { + $chartTypes[] = $plotArea->getPlotGroupByIndex($i)->getPlotType(); + } + $chartType = array_unique($chartTypes); + if (count($chartTypes) == 0) { + throw new PHPExcel_Writer_Exception('Chart is not yet implemented'); + } + } + + return $chartType; + } + + /** + * Write Plot Group (series of related plots) + * + * @param PHPExcel_Chart_DataSeries $plotGroup + * @param string $groupType Type of plot for dataseries + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param boolean &$catIsMultiLevelSeries Is category a multi-series category + * @param boolean &$valIsMultiLevelSeries Is value set a multi-series set + * @param string &$plotGroupingType Type of grouping for multi-series values + * @param PHPExcel_Worksheet $pSheet + * @throws PHPExcel_Writer_Exception + */ + private function _writePlotGroup( $plotGroup, + $groupType, + $objWriter, + &$catIsMultiLevelSeries, + &$valIsMultiLevelSeries, + &$plotGroupingType, + PHPExcel_Worksheet $pSheet + ) + { + if (is_null($plotGroup)) { + return; + } + + if (($groupType == PHPExcel_Chart_DataSeries::TYPE_BARCHART) || + ($groupType == PHPExcel_Chart_DataSeries::TYPE_BARCHART_3D)) { + $objWriter->startElement('c:barDir'); + $objWriter->writeAttribute('val', $plotGroup->getPlotDirection()); + $objWriter->endElement(); + } + + if (!is_null($plotGroup->getPlotGrouping())) { + $plotGroupingType = $plotGroup->getPlotGrouping(); + $objWriter->startElement('c:grouping'); + $objWriter->writeAttribute('val', $plotGroupingType); + $objWriter->endElement(); + } + + // Get these details before the loop, because we can use the count to check for varyColors + $plotSeriesOrder = $plotGroup->getPlotOrder(); + $plotSeriesCount = count($plotSeriesOrder); + + if (($groupType !== PHPExcel_Chart_DataSeries::TYPE_RADARCHART) && + ($groupType !== PHPExcel_Chart_DataSeries::TYPE_STOCKCHART)) { + + if ($groupType !== PHPExcel_Chart_DataSeries::TYPE_LINECHART) { + if (($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART) || + ($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) || + ($groupType == PHPExcel_Chart_DataSeries::TYPE_DONUTCHART) || + ($plotSeriesCount > 1)) { + $objWriter->startElement('c:varyColors'); + $objWriter->writeAttribute('val', 1); + $objWriter->endElement(); + } else { + $objWriter->startElement('c:varyColors'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + } + } + } + + foreach($plotSeriesOrder as $plotSeriesIdx => $plotSeriesRef) { + $objWriter->startElement('c:ser'); + + $objWriter->startElement('c:idx'); + $objWriter->writeAttribute('val', $this->_seriesIndex + $plotSeriesIdx); + $objWriter->endElement(); + + $objWriter->startElement('c:order'); + $objWriter->writeAttribute('val', $this->_seriesIndex + $plotSeriesRef); + $objWriter->endElement(); + + if (($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART) || + ($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) || + ($groupType == PHPExcel_Chart_DataSeries::TYPE_DONUTCHART)) { + + $objWriter->startElement('c:dPt'); + $objWriter->startElement('c:idx'); + $objWriter->writeAttribute('val', 3); + $objWriter->endElement(); + + $objWriter->startElement('c:bubble3D'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + + $objWriter->startElement('c:spPr'); + $objWriter->startElement('a:solidFill'); + $objWriter->startElement('a:srgbClr'); + $objWriter->writeAttribute('val', 'FF9900'); + $objWriter->endElement(); + $objWriter->endElement(); + $objWriter->endElement(); + $objWriter->endElement(); + } + + // Labels + $plotSeriesLabel = $plotGroup->getPlotLabelByIndex($plotSeriesRef); + if ($plotSeriesLabel && ($plotSeriesLabel->getPointCount() > 0)) { + $objWriter->startElement('c:tx'); + $objWriter->startElement('c:strRef'); + $this->_writePlotSeriesLabel($plotSeriesLabel, $objWriter); + $objWriter->endElement(); + $objWriter->endElement(); + } + + // Formatting for the points + if (($groupType == PHPExcel_Chart_DataSeries::TYPE_LINECHART) || + ($groupType == PHPExcel_Chart_DataSeries::TYPE_STOCKCHART)) { + $objWriter->startElement('c:spPr'); + $objWriter->startElement('a:ln'); + $objWriter->writeAttribute('w', 12700); + if ($groupType == PHPExcel_Chart_DataSeries::TYPE_STOCKCHART) { + $objWriter->startElement('a:noFill'); + $objWriter->endElement(); + } + $objWriter->endElement(); + $objWriter->endElement(); + } + + $plotSeriesValues = $plotGroup->getPlotValuesByIndex($plotSeriesRef); + if ($plotSeriesValues) { + $plotSeriesMarker = $plotSeriesValues->getPointMarker(); + if ($plotSeriesMarker) { + $objWriter->startElement('c:marker'); + $objWriter->startElement('c:symbol'); + $objWriter->writeAttribute('val', $plotSeriesMarker); + $objWriter->endElement(); + + if ($plotSeriesMarker !== 'none') { + $objWriter->startElement('c:size'); + $objWriter->writeAttribute('val', 3); + $objWriter->endElement(); + } + $objWriter->endElement(); + } + } + + if (($groupType === PHPExcel_Chart_DataSeries::TYPE_BARCHART) || + ($groupType === PHPExcel_Chart_DataSeries::TYPE_BARCHART_3D) || + ($groupType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART)) { + + $objWriter->startElement('c:invertIfNegative'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + } + + // Category Labels + $plotSeriesCategory = $plotGroup->getPlotCategoryByIndex($plotSeriesRef); + if ($plotSeriesCategory && ($plotSeriesCategory->getPointCount() > 0)) { + $catIsMultiLevelSeries = $catIsMultiLevelSeries || $plotSeriesCategory->isMultiLevelSeries(); + + if (($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART) || + ($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) || + ($groupType == PHPExcel_Chart_DataSeries::TYPE_DONUTCHART)) { + + if (!is_null($plotGroup->getPlotStyle())) { + $plotStyle = $plotGroup->getPlotStyle(); + if ($plotStyle) { + $objWriter->startElement('c:explosion'); + $objWriter->writeAttribute('val', 25); + $objWriter->endElement(); + } + } + } + + if (($groupType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) || + ($groupType === PHPExcel_Chart_DataSeries::TYPE_SCATTERCHART)) { + $objWriter->startElement('c:xVal'); + } else { + $objWriter->startElement('c:cat'); + } + + $this->_writePlotSeriesValues($plotSeriesCategory, $objWriter, $groupType, 'str', $pSheet); + $objWriter->endElement(); + } + + // Values + if ($plotSeriesValues) { + $valIsMultiLevelSeries = $valIsMultiLevelSeries || $plotSeriesValues->isMultiLevelSeries(); + + if (($groupType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) || + ($groupType === PHPExcel_Chart_DataSeries::TYPE_SCATTERCHART)) { + $objWriter->startElement('c:yVal'); + } else { + $objWriter->startElement('c:val'); + } + + $this->_writePlotSeriesValues($plotSeriesValues, $objWriter, $groupType, 'num', $pSheet); + $objWriter->endElement(); + } + + if ($groupType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) { + $this->_writeBubbles($plotSeriesValues, $objWriter, $pSheet); + } + + $objWriter->endElement(); + + } + + $this->_seriesIndex += $plotSeriesIdx + 1; + } + + /** + * Write Plot Series Label + * + * @param PHPExcel_Chart_DataSeriesValues $plotSeriesLabel + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @throws PHPExcel_Writer_Exception + */ + private function _writePlotSeriesLabel($plotSeriesLabel, $objWriter) + { + if (is_null($plotSeriesLabel)) { + return; + } + + $objWriter->startElement('c:f'); + $objWriter->writeRawData($plotSeriesLabel->getDataSource()); + $objWriter->endElement(); + + $objWriter->startElement('c:strCache'); + $objWriter->startElement('c:ptCount'); + $objWriter->writeAttribute('val', $plotSeriesLabel->getPointCount() ); + $objWriter->endElement(); + + foreach($plotSeriesLabel->getDataValues() as $plotLabelKey => $plotLabelValue) { + $objWriter->startElement('c:pt'); + $objWriter->writeAttribute('idx', $plotLabelKey ); + + $objWriter->startElement('c:v'); + $objWriter->writeRawData( $plotLabelValue ); + $objWriter->endElement(); + $objWriter->endElement(); + } + $objWriter->endElement(); + + } + + /** + * Write Plot Series Values + * + * @param PHPExcel_Chart_DataSeriesValues $plotSeriesValues + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param string $groupType Type of plot for dataseries + * @param string $dataType Datatype of series values + * @param PHPExcel_Worksheet $pSheet + * @throws PHPExcel_Writer_Exception + */ + private function _writePlotSeriesValues( $plotSeriesValues, + $objWriter, + $groupType, + $dataType='str', + PHPExcel_Worksheet $pSheet + ) + { + if (is_null($plotSeriesValues)) { + return; + } + + if ($plotSeriesValues->isMultiLevelSeries()) { + $levelCount = $plotSeriesValues->multiLevelCount(); + + $objWriter->startElement('c:multiLvlStrRef'); + + $objWriter->startElement('c:f'); + $objWriter->writeRawData( $plotSeriesValues->getDataSource() ); + $objWriter->endElement(); + + $objWriter->startElement('c:multiLvlStrCache'); + + $objWriter->startElement('c:ptCount'); + $objWriter->writeAttribute('val', $plotSeriesValues->getPointCount() ); + $objWriter->endElement(); + + for ($level = 0; $level < $levelCount; ++$level) { + $objWriter->startElement('c:lvl'); + + foreach($plotSeriesValues->getDataValues() as $plotSeriesKey => $plotSeriesValue) { + if (isset($plotSeriesValue[$level])) { + $objWriter->startElement('c:pt'); + $objWriter->writeAttribute('idx', $plotSeriesKey ); + + $objWriter->startElement('c:v'); + $objWriter->writeRawData( $plotSeriesValue[$level] ); + $objWriter->endElement(); + $objWriter->endElement(); + } + } + + $objWriter->endElement(); + } + + $objWriter->endElement(); + + $objWriter->endElement(); + } else { + $objWriter->startElement('c:'.$dataType.'Ref'); + + $objWriter->startElement('c:f'); + $objWriter->writeRawData( $plotSeriesValues->getDataSource() ); + $objWriter->endElement(); + + $objWriter->startElement('c:'.$dataType.'Cache'); + + if (($groupType != PHPExcel_Chart_DataSeries::TYPE_PIECHART) && + ($groupType != PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) && + ($groupType != PHPExcel_Chart_DataSeries::TYPE_DONUTCHART)) { + + if (($plotSeriesValues->getFormatCode() !== NULL) && + ($plotSeriesValues->getFormatCode() !== '')) { + $objWriter->startElement('c:formatCode'); + $objWriter->writeRawData( $plotSeriesValues->getFormatCode() ); + $objWriter->endElement(); + } + } + + $objWriter->startElement('c:ptCount'); + $objWriter->writeAttribute('val', $plotSeriesValues->getPointCount() ); + $objWriter->endElement(); + + $dataValues = $plotSeriesValues->getDataValues(); + if (!empty($dataValues)) { + if (is_array($dataValues)) { + foreach($dataValues as $plotSeriesKey => $plotSeriesValue) { + $objWriter->startElement('c:pt'); + $objWriter->writeAttribute('idx', $plotSeriesKey ); + + $objWriter->startElement('c:v'); + $objWriter->writeRawData( $plotSeriesValue ); + $objWriter->endElement(); + $objWriter->endElement(); + } + } + } + + $objWriter->endElement(); + + $objWriter->endElement(); + } + } + + /** + * Write Bubble Chart Details + * + * @param PHPExcel_Chart_DataSeriesValues $plotSeriesValues + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @throws PHPExcel_Writer_Exception + */ + private function _writeBubbles($plotSeriesValues, $objWriter, PHPExcel_Worksheet $pSheet) + { + if (is_null($plotSeriesValues)) { + return; + } + + $objWriter->startElement('c:bubbleSize'); + $objWriter->startElement('c:numLit'); + + $objWriter->startElement('c:formatCode'); + $objWriter->writeRawData( 'General' ); + $objWriter->endElement(); + + $objWriter->startElement('c:ptCount'); + $objWriter->writeAttribute('val', $plotSeriesValues->getPointCount() ); + $objWriter->endElement(); + + $dataValues = $plotSeriesValues->getDataValues(); + if (!empty($dataValues)) { + if (is_array($dataValues)) { + foreach($dataValues as $plotSeriesKey => $plotSeriesValue) { + $objWriter->startElement('c:pt'); + $objWriter->writeAttribute('idx', $plotSeriesKey ); + $objWriter->startElement('c:v'); + $objWriter->writeRawData( 1 ); + $objWriter->endElement(); + $objWriter->endElement(); + } + } + } + + $objWriter->endElement(); + $objWriter->endElement(); + + $objWriter->startElement('c:bubble3D'); + $objWriter->writeAttribute('val', 0 ); + $objWriter->endElement(); + } + + /** + * Write Layout + * + * @param PHPExcel_Chart_Layout $layout + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @throws PHPExcel_Writer_Exception + */ + private function _writeLayout(PHPExcel_Chart_Layout $layout = NULL, $objWriter) + { + $objWriter->startElement('c:layout'); + + if (!is_null($layout)) { + $objWriter->startElement('c:manualLayout'); + + $layoutTarget = $layout->getLayoutTarget(); + if (!is_null($layoutTarget)) { + $objWriter->startElement('c:layoutTarget'); + $objWriter->writeAttribute('val', $layoutTarget); + $objWriter->endElement(); + } + + $xMode = $layout->getXMode(); + if (!is_null($xMode)) { + $objWriter->startElement('c:xMode'); + $objWriter->writeAttribute('val', $xMode); + $objWriter->endElement(); + } + + $yMode = $layout->getYMode(); + if (!is_null($yMode)) { + $objWriter->startElement('c:yMode'); + $objWriter->writeAttribute('val', $yMode); + $objWriter->endElement(); + } + + $x = $layout->getXPosition(); + if (!is_null($x)) { + $objWriter->startElement('c:x'); + $objWriter->writeAttribute('val', $x); + $objWriter->endElement(); + } + + $y = $layout->getYPosition(); + if (!is_null($y)) { + $objWriter->startElement('c:y'); + $objWriter->writeAttribute('val', $y); + $objWriter->endElement(); + } + + $w = $layout->getWidth(); + if (!is_null($w)) { + $objWriter->startElement('c:w'); + $objWriter->writeAttribute('val', $w); + $objWriter->endElement(); + } + + $h = $layout->getHeight(); + if (!is_null($h)) { + $objWriter->startElement('c:h'); + $objWriter->writeAttribute('val', $h); + $objWriter->endElement(); + } + + $objWriter->endElement(); + } + + $objWriter->endElement(); + } + + /** + * Write Alternate Content block + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @throws PHPExcel_Writer_Exception + */ + private function _writeAlternateContent($objWriter) + { + $objWriter->startElement('mc:AlternateContent'); + $objWriter->writeAttribute('xmlns:mc', 'http://schemas.openxmlformats.org/markup-compatibility/2006'); + + $objWriter->startElement('mc:Choice'); + $objWriter->writeAttribute('xmlns:c14', 'http://schemas.microsoft.com/office/drawing/2007/8/2/chart'); + $objWriter->writeAttribute('Requires', 'c14'); + + $objWriter->startElement('c14:style'); + $objWriter->writeAttribute('val', '102'); + $objWriter->endElement(); + $objWriter->endElement(); + + $objWriter->startElement('mc:Fallback'); + $objWriter->startElement('c:style'); + $objWriter->writeAttribute('val', '2'); + $objWriter->endElement(); + $objWriter->endElement(); + + $objWriter->endElement(); + } + + /** + * Write Printer Settings + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @throws PHPExcel_Writer_Exception + */ + private function _writePrintSettings($objWriter) + { + $objWriter->startElement('c:printSettings'); + + $objWriter->startElement('c:headerFooter'); + $objWriter->endElement(); + + $objWriter->startElement('c:pageMargins'); + $objWriter->writeAttribute('footer', 0.3); + $objWriter->writeAttribute('header', 0.3); + $objWriter->writeAttribute('r', 0.7); + $objWriter->writeAttribute('l', 0.7); + $objWriter->writeAttribute('t', 0.75); + $objWriter->writeAttribute('b', 0.75); + $objWriter->endElement(); + + $objWriter->startElement('c:pageSetup'); + $objWriter->writeAttribute('orientation', "portrait"); + $objWriter->endElement(); + + $objWriter->endElement(); + } + +} diff --git a/lib/phpexcel/PHPExcel/Writer/Excel2007/Comments.php b/lib/phpexcel/PHPExcel/Writer/Excel2007/Comments.php new file mode 100644 index 0000000..436219c --- /dev/null +++ b/lib/phpexcel/PHPExcel/Writer/Excel2007/Comments.php @@ -0,0 +1,268 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Writer_Excel2007_Comments + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_Excel2007_Comments extends PHPExcel_Writer_Excel2007_WriterPart +{ + /** + * Write comments to XML format + * + * @param PHPExcel_Worksheet $pWorksheet + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeComments(PHPExcel_Worksheet $pWorksheet = null) + { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // Comments cache + $comments = $pWorksheet->getComments(); + + // Authors cache + $authors = array(); + $authorId = 0; + foreach ($comments as $comment) { + if (!isset($authors[$comment->getAuthor()])) { + $authors[$comment->getAuthor()] = $authorId++; + } + } + + // comments + $objWriter->startElement('comments'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'); + + // Loop through authors + $objWriter->startElement('authors'); + foreach ($authors as $author => $index) { + $objWriter->writeElement('author', $author); + } + $objWriter->endElement(); + + // Loop through comments + $objWriter->startElement('commentList'); + foreach ($comments as $key => $value) { + $this->_writeComment($objWriter, $key, $value, $authors); + } + $objWriter->endElement(); + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + /** + * Write comment to XML format + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param string $pCellReference Cell reference + * @param PHPExcel_Comment $pComment Comment + * @param array $pAuthors Array of authors + * @throws PHPExcel_Writer_Exception + */ + public function _writeComment(PHPExcel_Shared_XMLWriter $objWriter = null, $pCellReference = 'A1', PHPExcel_Comment $pComment = null, $pAuthors = null) + { + // comment + $objWriter->startElement('comment'); + $objWriter->writeAttribute('ref', $pCellReference); + $objWriter->writeAttribute('authorId', $pAuthors[$pComment->getAuthor()]); + + // text + $objWriter->startElement('text'); + $this->getParentWriter()->getWriterPart('stringtable')->writeRichText($objWriter, $pComment->getText()); + $objWriter->endElement(); + + $objWriter->endElement(); + } + + /** + * Write VML comments to XML format + * + * @param PHPExcel_Worksheet $pWorksheet + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeVMLComments(PHPExcel_Worksheet $pWorksheet = null) + { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // Comments cache + $comments = $pWorksheet->getComments(); + + // xml + $objWriter->startElement('xml'); + $objWriter->writeAttribute('xmlns:v', 'urn:schemas-microsoft-com:vml'); + $objWriter->writeAttribute('xmlns:o', 'urn:schemas-microsoft-com:office:office'); + $objWriter->writeAttribute('xmlns:x', 'urn:schemas-microsoft-com:office:excel'); + + // o:shapelayout + $objWriter->startElement('o:shapelayout'); + $objWriter->writeAttribute('v:ext', 'edit'); + + // o:idmap + $objWriter->startElement('o:idmap'); + $objWriter->writeAttribute('v:ext', 'edit'); + $objWriter->writeAttribute('data', '1'); + $objWriter->endElement(); + + $objWriter->endElement(); + + // v:shapetype + $objWriter->startElement('v:shapetype'); + $objWriter->writeAttribute('id', '_x0000_t202'); + $objWriter->writeAttribute('coordsize', '21600,21600'); + $objWriter->writeAttribute('o:spt', '202'); + $objWriter->writeAttribute('path', 'm,l,21600r21600,l21600,xe'); + + // v:stroke + $objWriter->startElement('v:stroke'); + $objWriter->writeAttribute('joinstyle', 'miter'); + $objWriter->endElement(); + + // v:path + $objWriter->startElement('v:path'); + $objWriter->writeAttribute('gradientshapeok', 't'); + $objWriter->writeAttribute('o:connecttype', 'rect'); + $objWriter->endElement(); + + $objWriter->endElement(); + + // Loop through comments + foreach ($comments as $key => $value) { + $this->_writeVMLComment($objWriter, $key, $value); + } + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + /** + * Write VML comment to XML format + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param string $pCellReference Cell reference + * @param PHPExcel_Comment $pComment Comment + * @throws PHPExcel_Writer_Exception + */ + public function _writeVMLComment(PHPExcel_Shared_XMLWriter $objWriter = null, $pCellReference = 'A1', PHPExcel_Comment $pComment = null) + { + // Metadata + list($column, $row) = PHPExcel_Cell::coordinateFromString($pCellReference); + $column = PHPExcel_Cell::columnIndexFromString($column); + $id = 1024 + $column + $row; + $id = substr($id, 0, 4); + + // v:shape + $objWriter->startElement('v:shape'); + $objWriter->writeAttribute('id', '_x0000_s' . $id); + $objWriter->writeAttribute('type', '#_x0000_t202'); + $objWriter->writeAttribute('style', 'position:absolute;margin-left:' . $pComment->getMarginLeft() . ';margin-top:' . $pComment->getMarginTop() . ';width:' . $pComment->getWidth() . ';height:' . $pComment->getHeight() . ';z-index:1;visibility:' . ($pComment->getVisible() ? 'visible' : 'hidden')); + $objWriter->writeAttribute('fillcolor', '#' . $pComment->getFillColor()->getRGB()); + $objWriter->writeAttribute('o:insetmode', 'auto'); + + // v:fill + $objWriter->startElement('v:fill'); + $objWriter->writeAttribute('color2', '#' . $pComment->getFillColor()->getRGB()); + $objWriter->endElement(); + + // v:shadow + $objWriter->startElement('v:shadow'); + $objWriter->writeAttribute('on', 't'); + $objWriter->writeAttribute('color', 'black'); + $objWriter->writeAttribute('obscured', 't'); + $objWriter->endElement(); + + // v:path + $objWriter->startElement('v:path'); + $objWriter->writeAttribute('o:connecttype', 'none'); + $objWriter->endElement(); + + // v:textbox + $objWriter->startElement('v:textbox'); + $objWriter->writeAttribute('style', 'mso-direction-alt:auto'); + + // div + $objWriter->startElement('div'); + $objWriter->writeAttribute('style', 'text-align:left'); + $objWriter->endElement(); + + $objWriter->endElement(); + + // x:ClientData + $objWriter->startElement('x:ClientData'); + $objWriter->writeAttribute('ObjectType', 'Note'); + + // x:MoveWithCells + $objWriter->writeElement('x:MoveWithCells', ''); + + // x:SizeWithCells + $objWriter->writeElement('x:SizeWithCells', ''); + + // x:Anchor + //$objWriter->writeElement('x:Anchor', $column . ', 15, ' . ($row - 2) . ', 10, ' . ($column + 4) . ', 15, ' . ($row + 5) . ', 18'); + + // x:AutoFill + $objWriter->writeElement('x:AutoFill', 'False'); + + // x:Row + $objWriter->writeElement('x:Row', ($row - 1)); + + // x:Column + $objWriter->writeElement('x:Column', ($column - 1)); + + $objWriter->endElement(); + + $objWriter->endElement(); + } +} diff --git a/lib/phpexcel/PHPExcel/Writer/Excel2007/ContentTypes.php b/lib/phpexcel/PHPExcel/Writer/Excel2007/ContentTypes.php new file mode 100644 index 0000000..3c17a16 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Writer/Excel2007/ContentTypes.php @@ -0,0 +1,287 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Writer_Excel2007_ContentTypes + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_Excel2007_ContentTypes extends PHPExcel_Writer_Excel2007_WriterPart +{ + /** + * Write content types to XML format + * + * @param PHPExcel $pPHPExcel + * @param boolean $includeCharts Flag indicating if we should include drawing details for charts + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeContentTypes(PHPExcel $pPHPExcel = null, $includeCharts = FALSE) + { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // Types + $objWriter->startElement('Types'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/content-types'); + + // Theme + $this->_writeOverrideContentType( + $objWriter, '/xl/theme/theme1.xml', 'application/vnd.openxmlformats-officedocument.theme+xml' + ); + + // Styles + $this->_writeOverrideContentType( + $objWriter, '/xl/styles.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml' + ); + + // Rels + $this->_writeDefaultContentType( + $objWriter, 'rels', 'application/vnd.openxmlformats-package.relationships+xml' + ); + + // XML + $this->_writeDefaultContentType( + $objWriter, 'xml', 'application/xml' + ); + + // VML + $this->_writeDefaultContentType( + $objWriter, 'vml', 'application/vnd.openxmlformats-officedocument.vmlDrawing' + ); + + // Workbook + if($pPHPExcel->hasMacros()){ //Macros in workbook ? + // Yes : not standard content but "macroEnabled" + $this->_writeOverrideContentType( + $objWriter, '/xl/workbook.xml', 'application/vnd.ms-excel.sheet.macroEnabled.main+xml' + ); + //... and define a new type for the VBA project + $this->_writeDefaultContentType( + $objWriter, 'bin', 'application/vnd.ms-office.vbaProject' + ); + if($pPHPExcel->hasMacrosCertificate()){// signed macros ? + // Yes : add needed information + $this->_writeOverrideContentType( + $objWriter, '/xl/vbaProjectSignature.bin', 'application/vnd.ms-office.vbaProjectSignature' + ); + } + }else{// no macros in workbook, so standard type + $this->_writeOverrideContentType( + $objWriter, '/xl/workbook.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml' + ); + } + + // DocProps + $this->_writeOverrideContentType( + $objWriter, '/docProps/app.xml', 'application/vnd.openxmlformats-officedocument.extended-properties+xml' + ); + + $this->_writeOverrideContentType( + $objWriter, '/docProps/core.xml', 'application/vnd.openxmlformats-package.core-properties+xml' + ); + + $customPropertyList = $pPHPExcel->getProperties()->getCustomProperties(); + if (!empty($customPropertyList)) { + $this->_writeOverrideContentType( + $objWriter, '/docProps/custom.xml', 'application/vnd.openxmlformats-officedocument.custom-properties+xml' + ); + } + + // Worksheets + $sheetCount = $pPHPExcel->getSheetCount(); + for ($i = 0; $i < $sheetCount; ++$i) { + $this->_writeOverrideContentType( + $objWriter, '/xl/worksheets/sheet' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml' + ); + } + + // Shared strings + $this->_writeOverrideContentType( + $objWriter, '/xl/sharedStrings.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml' + ); + + // Add worksheet relationship content types + $chart = 1; + for ($i = 0; $i < $sheetCount; ++$i) { + $drawings = $pPHPExcel->getSheet($i)->getDrawingCollection(); + $drawingCount = count($drawings); + $chartCount = ($includeCharts) ? $pPHPExcel->getSheet($i)->getChartCount() : 0; + + // We need a drawing relationship for the worksheet if we have either drawings or charts + if (($drawingCount > 0) || ($chartCount > 0)) { + $this->_writeOverrideContentType( + $objWriter, '/xl/drawings/drawing' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.drawing+xml' + ); + } + + // If we have charts, then we need a chart relationship for every individual chart + if ($chartCount > 0) { + for ($c = 0; $c < $chartCount; ++$c) { + $this->_writeOverrideContentType( + $objWriter, '/xl/charts/chart' . $chart++ . '.xml', 'application/vnd.openxmlformats-officedocument.drawingml.chart+xml' + ); + } + } + } + + // Comments + for ($i = 0; $i < $sheetCount; ++$i) { + if (count($pPHPExcel->getSheet($i)->getComments()) > 0) { + $this->_writeOverrideContentType( + $objWriter, '/xl/comments' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml' + ); + } + } + + // Add media content-types + $aMediaContentTypes = array(); + $mediaCount = $this->getParentWriter()->getDrawingHashTable()->count(); + for ($i = 0; $i < $mediaCount; ++$i) { + $extension = ''; + $mimeType = ''; + + if ($this->getParentWriter()->getDrawingHashTable()->getByIndex($i) instanceof PHPExcel_Worksheet_Drawing) { + $extension = strtolower($this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getExtension()); + $mimeType = $this->_getImageMimeType( $this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getPath() ); + } else if ($this->getParentWriter()->getDrawingHashTable()->getByIndex($i) instanceof PHPExcel_Worksheet_MemoryDrawing) { + $extension = strtolower($this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getMimeType()); + $extension = explode('/', $extension); + $extension = $extension[1]; + + $mimeType = $this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getMimeType(); + } + + if (!isset( $aMediaContentTypes[$extension]) ) { + $aMediaContentTypes[$extension] = $mimeType; + + $this->_writeDefaultContentType( + $objWriter, $extension, $mimeType + ); + } + } + if($pPHPExcel->hasRibbonBinObjects()){//Some additional objects in the ribbon ? + //we need to write "Extension" but not already write for media content + $tabRibbonTypes=array_diff($pPHPExcel->getRibbonBinObjects('types'), array_keys($aMediaContentTypes)); + foreach($tabRibbonTypes as $aRibbonType){ + $mimeType='image/.'.$aRibbonType;//we wrote $mimeType like customUI Editor + $this->_writeDefaultContentType( + $objWriter, $aRibbonType, $mimeType + ); + } + } + $sheetCount = $pPHPExcel->getSheetCount(); + for ($i = 0; $i < $sheetCount; ++$i) { + if (count($pPHPExcel->getSheet()->getHeaderFooter()->getImages()) > 0) { + foreach ($pPHPExcel->getSheet()->getHeaderFooter()->getImages() as $image) { + if (!isset( $aMediaContentTypes[strtolower($image->getExtension())]) ) { + $aMediaContentTypes[strtolower($image->getExtension())] = $this->_getImageMimeType( $image->getPath() ); + + $this->_writeDefaultContentType( + $objWriter, strtolower($image->getExtension()), $aMediaContentTypes[strtolower($image->getExtension())] + ); + } + } + } + } + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + /** + * Get image mime type + * + * @param string $pFile Filename + * @return string Mime Type + * @throws PHPExcel_Writer_Exception + */ + private function _getImageMimeType($pFile = '') + { + if (PHPExcel_Shared_File::file_exists($pFile)) { + $image = getimagesize($pFile); + return image_type_to_mime_type($image[2]); + } else { + throw new PHPExcel_Writer_Exception("File $pFile does not exist"); + } + } + + /** + * Write Default content type + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param string $pPartname Part name + * @param string $pContentType Content type + * @throws PHPExcel_Writer_Exception + */ + private function _writeDefaultContentType(PHPExcel_Shared_XMLWriter $objWriter = null, $pPartname = '', $pContentType = '') + { + if ($pPartname != '' && $pContentType != '') { + // Write content type + $objWriter->startElement('Default'); + $objWriter->writeAttribute('Extension', $pPartname); + $objWriter->writeAttribute('ContentType', $pContentType); + $objWriter->endElement(); + } else { + throw new PHPExcel_Writer_Exception("Invalid parameters passed."); + } + } + + /** + * Write Override content type + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param string $pPartname Part name + * @param string $pContentType Content type + * @throws PHPExcel_Writer_Exception + */ + private function _writeOverrideContentType(PHPExcel_Shared_XMLWriter $objWriter = null, $pPartname = '', $pContentType = '') + { + if ($pPartname != '' && $pContentType != '') { + // Write content type + $objWriter->startElement('Override'); + $objWriter->writeAttribute('PartName', $pPartname); + $objWriter->writeAttribute('ContentType', $pContentType); + $objWriter->endElement(); + } else { + throw new PHPExcel_Writer_Exception("Invalid parameters passed."); + } + } +} diff --git a/lib/phpexcel/PHPExcel/Writer/Excel2007/DocProps.php b/lib/phpexcel/PHPExcel/Writer/Excel2007/DocProps.php new file mode 100644 index 0000000..cfc3089 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Writer/Excel2007/DocProps.php @@ -0,0 +1,272 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Writer_Excel2007_DocProps + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_Excel2007_DocProps extends PHPExcel_Writer_Excel2007_WriterPart +{ +/** + * Write docProps/app.xml to XML format + * + * @param PHPExcel $pPHPExcel + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeDocPropsApp(PHPExcel $pPHPExcel = null) + { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // Properties + $objWriter->startElement('Properties'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/officeDocument/2006/extended-properties'); + $objWriter->writeAttribute('xmlns:vt', 'http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes'); + + // Application + $objWriter->writeElement('Application', 'Microsoft Excel'); + + // DocSecurity + $objWriter->writeElement('DocSecurity', '0'); + + // ScaleCrop + $objWriter->writeElement('ScaleCrop', 'false'); + + // HeadingPairs + $objWriter->startElement('HeadingPairs'); + + // Vector + $objWriter->startElement('vt:vector'); + $objWriter->writeAttribute('size', '2'); + $objWriter->writeAttribute('baseType', 'variant'); + + // Variant + $objWriter->startElement('vt:variant'); + $objWriter->writeElement('vt:lpstr', 'Worksheets'); + $objWriter->endElement(); + + // Variant + $objWriter->startElement('vt:variant'); + $objWriter->writeElement('vt:i4', $pPHPExcel->getSheetCount()); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // TitlesOfParts + $objWriter->startElement('TitlesOfParts'); + + // Vector + $objWriter->startElement('vt:vector'); + $objWriter->writeAttribute('size', $pPHPExcel->getSheetCount()); + $objWriter->writeAttribute('baseType', 'lpstr'); + + $sheetCount = $pPHPExcel->getSheetCount(); + for ($i = 0; $i < $sheetCount; ++$i) { + $objWriter->writeElement('vt:lpstr', $pPHPExcel->getSheet($i)->getTitle()); + } + + $objWriter->endElement(); + + $objWriter->endElement(); + + // Company + $objWriter->writeElement('Company', $pPHPExcel->getProperties()->getCompany()); + + // Company + $objWriter->writeElement('Manager', $pPHPExcel->getProperties()->getManager()); + + // LinksUpToDate + $objWriter->writeElement('LinksUpToDate', 'false'); + + // SharedDoc + $objWriter->writeElement('SharedDoc', 'false'); + + // HyperlinksChanged + $objWriter->writeElement('HyperlinksChanged', 'false'); + + // AppVersion + $objWriter->writeElement('AppVersion', '12.0000'); + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + /** + * Write docProps/core.xml to XML format + * + * @param PHPExcel $pPHPExcel + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeDocPropsCore(PHPExcel $pPHPExcel = null) + { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // cp:coreProperties + $objWriter->startElement('cp:coreProperties'); + $objWriter->writeAttribute('xmlns:cp', 'http://schemas.openxmlformats.org/package/2006/metadata/core-properties'); + $objWriter->writeAttribute('xmlns:dc', 'http://purl.org/dc/elements/1.1/'); + $objWriter->writeAttribute('xmlns:dcterms', 'http://purl.org/dc/terms/'); + $objWriter->writeAttribute('xmlns:dcmitype', 'http://purl.org/dc/dcmitype/'); + $objWriter->writeAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance'); + + // dc:creator + $objWriter->writeElement('dc:creator', $pPHPExcel->getProperties()->getCreator()); + + // cp:lastModifiedBy + $objWriter->writeElement('cp:lastModifiedBy', $pPHPExcel->getProperties()->getLastModifiedBy()); + + // dcterms:created + $objWriter->startElement('dcterms:created'); + $objWriter->writeAttribute('xsi:type', 'dcterms:W3CDTF'); + $objWriter->writeRawData(date(DATE_W3C, $pPHPExcel->getProperties()->getCreated())); + $objWriter->endElement(); + + // dcterms:modified + $objWriter->startElement('dcterms:modified'); + $objWriter->writeAttribute('xsi:type', 'dcterms:W3CDTF'); + $objWriter->writeRawData(date(DATE_W3C, $pPHPExcel->getProperties()->getModified())); + $objWriter->endElement(); + + // dc:title + $objWriter->writeElement('dc:title', $pPHPExcel->getProperties()->getTitle()); + + // dc:description + $objWriter->writeElement('dc:description', $pPHPExcel->getProperties()->getDescription()); + + // dc:subject + $objWriter->writeElement('dc:subject', $pPHPExcel->getProperties()->getSubject()); + + // cp:keywords + $objWriter->writeElement('cp:keywords', $pPHPExcel->getProperties()->getKeywords()); + + // cp:category + $objWriter->writeElement('cp:category', $pPHPExcel->getProperties()->getCategory()); + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + /** + * Write docProps/custom.xml to XML format + * + * @param PHPExcel $pPHPExcel + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeDocPropsCustom(PHPExcel $pPHPExcel = null) + { + $customPropertyList = $pPHPExcel->getProperties()->getCustomProperties(); + if (empty($customPropertyList)) { + return; + } + + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // cp:coreProperties + $objWriter->startElement('Properties'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/officeDocument/2006/custom-properties'); + $objWriter->writeAttribute('xmlns:vt', 'http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes'); + + + foreach($customPropertyList as $key => $customProperty) { + $propertyValue = $pPHPExcel->getProperties()->getCustomPropertyValue($customProperty); + $propertyType = $pPHPExcel->getProperties()->getCustomPropertyType($customProperty); + + $objWriter->startElement('property'); + $objWriter->writeAttribute('fmtid', '{D5CDD505-2E9C-101B-9397-08002B2CF9AE}'); + $objWriter->writeAttribute('pid', $key+2); + $objWriter->writeAttribute('name', $customProperty); + + switch($propertyType) { + case 'i' : + $objWriter->writeElement('vt:i4', $propertyValue); + break; + case 'f' : + $objWriter->writeElement('vt:r8', $propertyValue); + break; + case 'b' : + $objWriter->writeElement('vt:bool', ($propertyValue) ? 'true' : 'false'); + break; + case 'd' : + $objWriter->startElement('vt:filetime'); + $objWriter->writeRawData(date(DATE_W3C, $propertyValue)); + $objWriter->endElement(); + break; + default : + $objWriter->writeElement('vt:lpwstr', $propertyValue); + break; + } + + $objWriter->endElement(); + } + + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + +} diff --git a/lib/phpexcel/PHPExcel/Writer/Excel2007/Drawing.php b/lib/phpexcel/PHPExcel/Writer/Excel2007/Drawing.php new file mode 100644 index 0000000..3c52723 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Writer/Excel2007/Drawing.php @@ -0,0 +1,598 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Writer_Excel2007_Drawing + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_Excel2007_Drawing extends PHPExcel_Writer_Excel2007_WriterPart +{ + /** + * Write drawings to XML format + * + * @param PHPExcel_Worksheet $pWorksheet + * @param int &$chartRef Chart ID + * @param boolean $includeCharts Flag indicating if we should include drawing details for charts + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeDrawings(PHPExcel_Worksheet $pWorksheet = null, &$chartRef, $includeCharts = FALSE) + { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // xdr:wsDr + $objWriter->startElement('xdr:wsDr'); + $objWriter->writeAttribute('xmlns:xdr', 'http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing'); + $objWriter->writeAttribute('xmlns:a', 'http://schemas.openxmlformats.org/drawingml/2006/main'); + + // Loop through images and write drawings + $i = 1; + $iterator = $pWorksheet->getDrawingCollection()->getIterator(); + while ($iterator->valid()) { + $this->_writeDrawing($objWriter, $iterator->current(), $i); + + $iterator->next(); + ++$i; + } + + if ($includeCharts) { + $chartCount = $pWorksheet->getChartCount(); + // Loop through charts and write the chart position + if ($chartCount > 0) { + for ($c = 0; $c < $chartCount; ++$c) { + $this->_writeChart($objWriter, $pWorksheet->getChartByIndex($c), $c+$i); + } + } + } + + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + /** + * Write drawings to XML format + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Chart $pChart + * @param int $pRelationId + * @throws PHPExcel_Writer_Exception + */ + public function _writeChart(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Chart $pChart = null, $pRelationId = -1) + { + $tl = $pChart->getTopLeftPosition(); + $tl['colRow'] = PHPExcel_Cell::coordinateFromString($tl['cell']); + $br = $pChart->getBottomRightPosition(); + $br['colRow'] = PHPExcel_Cell::coordinateFromString($br['cell']); + + $objWriter->startElement('xdr:twoCellAnchor'); + + $objWriter->startElement('xdr:from'); + $objWriter->writeElement('xdr:col', PHPExcel_Cell::columnIndexFromString($tl['colRow'][0]) - 1); + $objWriter->writeElement('xdr:colOff', PHPExcel_Shared_Drawing::pixelsToEMU($tl['xOffset'])); + $objWriter->writeElement('xdr:row', $tl['colRow'][1] - 1); + $objWriter->writeElement('xdr:rowOff', PHPExcel_Shared_Drawing::pixelsToEMU($tl['yOffset'])); + $objWriter->endElement(); + $objWriter->startElement('xdr:to'); + $objWriter->writeElement('xdr:col', PHPExcel_Cell::columnIndexFromString($br['colRow'][0]) - 1); + $objWriter->writeElement('xdr:colOff', PHPExcel_Shared_Drawing::pixelsToEMU($br['xOffset'])); + $objWriter->writeElement('xdr:row', $br['colRow'][1] - 1); + $objWriter->writeElement('xdr:rowOff', PHPExcel_Shared_Drawing::pixelsToEMU($br['yOffset'])); + $objWriter->endElement(); + + $objWriter->startElement('xdr:graphicFrame'); + $objWriter->writeAttribute('macro', ''); + $objWriter->startElement('xdr:nvGraphicFramePr'); + $objWriter->startElement('xdr:cNvPr'); + $objWriter->writeAttribute('name', 'Chart '.$pRelationId); + $objWriter->writeAttribute('id', 1025 * $pRelationId); + $objWriter->endElement(); + $objWriter->startElement('xdr:cNvGraphicFramePr'); + $objWriter->startElement('a:graphicFrameLocks'); + $objWriter->endElement(); + $objWriter->endElement(); + $objWriter->endElement(); + + $objWriter->startElement('xdr:xfrm'); + $objWriter->startElement('a:off'); + $objWriter->writeAttribute('x', '0'); + $objWriter->writeAttribute('y', '0'); + $objWriter->endElement(); + $objWriter->startElement('a:ext'); + $objWriter->writeAttribute('cx', '0'); + $objWriter->writeAttribute('cy', '0'); + $objWriter->endElement(); + $objWriter->endElement(); + + $objWriter->startElement('a:graphic'); + $objWriter->startElement('a:graphicData'); + $objWriter->writeAttribute('uri', 'http://schemas.openxmlformats.org/drawingml/2006/chart'); + $objWriter->startElement('c:chart'); + $objWriter->writeAttribute('xmlns:c', 'http://schemas.openxmlformats.org/drawingml/2006/chart'); + $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'); + $objWriter->writeAttribute('r:id', 'rId'.$pRelationId); + $objWriter->endElement(); + $objWriter->endElement(); + $objWriter->endElement(); + $objWriter->endElement(); + + $objWriter->startElement('xdr:clientData'); + $objWriter->endElement(); + + $objWriter->endElement(); + } + + /** + * Write drawings to XML format + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet_BaseDrawing $pDrawing + * @param int $pRelationId + * @throws PHPExcel_Writer_Exception + */ + public function _writeDrawing(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet_BaseDrawing $pDrawing = null, $pRelationId = -1) + { + if ($pRelationId >= 0) { + // xdr:oneCellAnchor + $objWriter->startElement('xdr:oneCellAnchor'); + // Image location + $aCoordinates = PHPExcel_Cell::coordinateFromString($pDrawing->getCoordinates()); + $aCoordinates[0] = PHPExcel_Cell::columnIndexFromString($aCoordinates[0]); + + // xdr:from + $objWriter->startElement('xdr:from'); + $objWriter->writeElement('xdr:col', $aCoordinates[0] - 1); + $objWriter->writeElement('xdr:colOff', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getOffsetX())); + $objWriter->writeElement('xdr:row', $aCoordinates[1] - 1); + $objWriter->writeElement('xdr:rowOff', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getOffsetY())); + $objWriter->endElement(); + + // xdr:ext + $objWriter->startElement('xdr:ext'); + $objWriter->writeAttribute('cx', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getWidth())); + $objWriter->writeAttribute('cy', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getHeight())); + $objWriter->endElement(); + + // xdr:pic + $objWriter->startElement('xdr:pic'); + + // xdr:nvPicPr + $objWriter->startElement('xdr:nvPicPr'); + + // xdr:cNvPr + $objWriter->startElement('xdr:cNvPr'); + $objWriter->writeAttribute('id', $pRelationId); + $objWriter->writeAttribute('name', $pDrawing->getName()); + $objWriter->writeAttribute('descr', $pDrawing->getDescription()); + $objWriter->endElement(); + + // xdr:cNvPicPr + $objWriter->startElement('xdr:cNvPicPr'); + + // a:picLocks + $objWriter->startElement('a:picLocks'); + $objWriter->writeAttribute('noChangeAspect', '1'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // xdr:blipFill + $objWriter->startElement('xdr:blipFill'); + + // a:blip + $objWriter->startElement('a:blip'); + $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'); + $objWriter->writeAttribute('r:embed', 'rId' . $pRelationId); + $objWriter->endElement(); + + // a:stretch + $objWriter->startElement('a:stretch'); + $objWriter->writeElement('a:fillRect', null); + $objWriter->endElement(); + + $objWriter->endElement(); + + // xdr:spPr + $objWriter->startElement('xdr:spPr'); + + // a:xfrm + $objWriter->startElement('a:xfrm'); + $objWriter->writeAttribute('rot', PHPExcel_Shared_Drawing::degreesToAngle($pDrawing->getRotation())); + $objWriter->endElement(); + + // a:prstGeom + $objWriter->startElement('a:prstGeom'); + $objWriter->writeAttribute('prst', 'rect'); + + // a:avLst + $objWriter->writeElement('a:avLst', null); + + $objWriter->endElement(); + +// // a:solidFill +// $objWriter->startElement('a:solidFill'); + +// // a:srgbClr +// $objWriter->startElement('a:srgbClr'); +// $objWriter->writeAttribute('val', 'FFFFFF'); + +///* SHADE +// // a:shade +// $objWriter->startElement('a:shade'); +// $objWriter->writeAttribute('val', '85000'); +// $objWriter->endElement(); +//*/ + +// $objWriter->endElement(); + +// $objWriter->endElement(); +/* + // a:ln + $objWriter->startElement('a:ln'); + $objWriter->writeAttribute('w', '88900'); + $objWriter->writeAttribute('cap', 'sq'); + + // a:solidFill + $objWriter->startElement('a:solidFill'); + + // a:srgbClr + $objWriter->startElement('a:srgbClr'); + $objWriter->writeAttribute('val', 'FFFFFF'); + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:miter + $objWriter->startElement('a:miter'); + $objWriter->writeAttribute('lim', '800000'); + $objWriter->endElement(); + + $objWriter->endElement(); +*/ + + if ($pDrawing->getShadow()->getVisible()) { + // a:effectLst + $objWriter->startElement('a:effectLst'); + + // a:outerShdw + $objWriter->startElement('a:outerShdw'); + $objWriter->writeAttribute('blurRad', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getShadow()->getBlurRadius())); + $objWriter->writeAttribute('dist', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getShadow()->getDistance())); + $objWriter->writeAttribute('dir', PHPExcel_Shared_Drawing::degreesToAngle($pDrawing->getShadow()->getDirection())); + $objWriter->writeAttribute('algn', $pDrawing->getShadow()->getAlignment()); + $objWriter->writeAttribute('rotWithShape', '0'); + + // a:srgbClr + $objWriter->startElement('a:srgbClr'); + $objWriter->writeAttribute('val', $pDrawing->getShadow()->getColor()->getRGB()); + + // a:alpha + $objWriter->startElement('a:alpha'); + $objWriter->writeAttribute('val', $pDrawing->getShadow()->getAlpha() * 1000); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + } +/* + + // a:scene3d + $objWriter->startElement('a:scene3d'); + + // a:camera + $objWriter->startElement('a:camera'); + $objWriter->writeAttribute('prst', 'orthographicFront'); + $objWriter->endElement(); + + // a:lightRig + $objWriter->startElement('a:lightRig'); + $objWriter->writeAttribute('rig', 'twoPt'); + $objWriter->writeAttribute('dir', 't'); + + // a:rot + $objWriter->startElement('a:rot'); + $objWriter->writeAttribute('lat', '0'); + $objWriter->writeAttribute('lon', '0'); + $objWriter->writeAttribute('rev', '0'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); +*/ +/* + // a:sp3d + $objWriter->startElement('a:sp3d'); + + // a:bevelT + $objWriter->startElement('a:bevelT'); + $objWriter->writeAttribute('w', '25400'); + $objWriter->writeAttribute('h', '19050'); + $objWriter->endElement(); + + // a:contourClr + $objWriter->startElement('a:contourClr'); + + // a:srgbClr + $objWriter->startElement('a:srgbClr'); + $objWriter->writeAttribute('val', 'FFFFFF'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); +*/ + $objWriter->endElement(); + + $objWriter->endElement(); + + // xdr:clientData + $objWriter->writeElement('xdr:clientData', null); + + $objWriter->endElement(); + } else { + throw new PHPExcel_Writer_Exception("Invalid parameters passed."); + } + } + + /** + * Write VML header/footer images to XML format + * + * @param PHPExcel_Worksheet $pWorksheet + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeVMLHeaderFooterImages(PHPExcel_Worksheet $pWorksheet = null) + { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // Header/footer images + $images = $pWorksheet->getHeaderFooter()->getImages(); + + // xml + $objWriter->startElement('xml'); + $objWriter->writeAttribute('xmlns:v', 'urn:schemas-microsoft-com:vml'); + $objWriter->writeAttribute('xmlns:o', 'urn:schemas-microsoft-com:office:office'); + $objWriter->writeAttribute('xmlns:x', 'urn:schemas-microsoft-com:office:excel'); + + // o:shapelayout + $objWriter->startElement('o:shapelayout'); + $objWriter->writeAttribute('v:ext', 'edit'); + + // o:idmap + $objWriter->startElement('o:idmap'); + $objWriter->writeAttribute('v:ext', 'edit'); + $objWriter->writeAttribute('data', '1'); + $objWriter->endElement(); + + $objWriter->endElement(); + + // v:shapetype + $objWriter->startElement('v:shapetype'); + $objWriter->writeAttribute('id', '_x0000_t75'); + $objWriter->writeAttribute('coordsize', '21600,21600'); + $objWriter->writeAttribute('o:spt', '75'); + $objWriter->writeAttribute('o:preferrelative', 't'); + $objWriter->writeAttribute('path', 'm@4@5l@4@11@9@11@9@5xe'); + $objWriter->writeAttribute('filled', 'f'); + $objWriter->writeAttribute('stroked', 'f'); + + // v:stroke + $objWriter->startElement('v:stroke'); + $objWriter->writeAttribute('joinstyle', 'miter'); + $objWriter->endElement(); + + // v:formulas + $objWriter->startElement('v:formulas'); + + // v:f + $objWriter->startElement('v:f'); + $objWriter->writeAttribute('eqn', 'if lineDrawn pixelLineWidth 0'); + $objWriter->endElement(); + + // v:f + $objWriter->startElement('v:f'); + $objWriter->writeAttribute('eqn', 'sum @0 1 0'); + $objWriter->endElement(); + + // v:f + $objWriter->startElement('v:f'); + $objWriter->writeAttribute('eqn', 'sum 0 0 @1'); + $objWriter->endElement(); + + // v:f + $objWriter->startElement('v:f'); + $objWriter->writeAttribute('eqn', 'prod @2 1 2'); + $objWriter->endElement(); + + // v:f + $objWriter->startElement('v:f'); + $objWriter->writeAttribute('eqn', 'prod @3 21600 pixelWidth'); + $objWriter->endElement(); + + // v:f + $objWriter->startElement('v:f'); + $objWriter->writeAttribute('eqn', 'prod @3 21600 pixelHeight'); + $objWriter->endElement(); + + // v:f + $objWriter->startElement('v:f'); + $objWriter->writeAttribute('eqn', 'sum @0 0 1'); + $objWriter->endElement(); + + // v:f + $objWriter->startElement('v:f'); + $objWriter->writeAttribute('eqn', 'prod @6 1 2'); + $objWriter->endElement(); + + // v:f + $objWriter->startElement('v:f'); + $objWriter->writeAttribute('eqn', 'prod @7 21600 pixelWidth'); + $objWriter->endElement(); + + // v:f + $objWriter->startElement('v:f'); + $objWriter->writeAttribute('eqn', 'sum @8 21600 0'); + $objWriter->endElement(); + + // v:f + $objWriter->startElement('v:f'); + $objWriter->writeAttribute('eqn', 'prod @7 21600 pixelHeight'); + $objWriter->endElement(); + + // v:f + $objWriter->startElement('v:f'); + $objWriter->writeAttribute('eqn', 'sum @10 21600 0'); + $objWriter->endElement(); + + $objWriter->endElement(); + + // v:path + $objWriter->startElement('v:path'); + $objWriter->writeAttribute('o:extrusionok', 'f'); + $objWriter->writeAttribute('gradientshapeok', 't'); + $objWriter->writeAttribute('o:connecttype', 'rect'); + $objWriter->endElement(); + + // o:lock + $objWriter->startElement('o:lock'); + $objWriter->writeAttribute('v:ext', 'edit'); + $objWriter->writeAttribute('aspectratio', 't'); + $objWriter->endElement(); + + $objWriter->endElement(); + + // Loop through images + foreach ($images as $key => $value) { + $this->_writeVMLHeaderFooterImage($objWriter, $key, $value); + } + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + /** + * Write VML comment to XML format + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param string $pReference Reference + * @param PHPExcel_Worksheet_HeaderFooterDrawing $pImage Image + * @throws PHPExcel_Writer_Exception + */ + public function _writeVMLHeaderFooterImage(PHPExcel_Shared_XMLWriter $objWriter = null, $pReference = '', PHPExcel_Worksheet_HeaderFooterDrawing $pImage = null) + { + // Calculate object id + preg_match('{(\d+)}', md5($pReference), $m); + $id = 1500 + (substr($m[1], 0, 2) * 1); + + // Calculate offset + $width = $pImage->getWidth(); + $height = $pImage->getHeight(); + $marginLeft = $pImage->getOffsetX(); + $marginTop = $pImage->getOffsetY(); + + // v:shape + $objWriter->startElement('v:shape'); + $objWriter->writeAttribute('id', $pReference); + $objWriter->writeAttribute('o:spid', '_x0000_s' . $id); + $objWriter->writeAttribute('type', '#_x0000_t75'); + $objWriter->writeAttribute('style', "position:absolute;margin-left:{$marginLeft}px;margin-top:{$marginTop}px;width:{$width}px;height:{$height}px;z-index:1"); + + // v:imagedata + $objWriter->startElement('v:imagedata'); + $objWriter->writeAttribute('o:relid', 'rId' . $pReference); + $objWriter->writeAttribute('o:title', $pImage->getName()); + $objWriter->endElement(); + + // o:lock + $objWriter->startElement('o:lock'); + $objWriter->writeAttribute('v:ext', 'edit'); + $objWriter->writeAttribute('rotation', 't'); + $objWriter->endElement(); + + $objWriter->endElement(); + } + + + /** + * Get an array of all drawings + * + * @param PHPExcel $pPHPExcel + * @return PHPExcel_Worksheet_Drawing[] All drawings in PHPExcel + * @throws PHPExcel_Writer_Exception + */ + public function allDrawings(PHPExcel $pPHPExcel = null) + { + // Get an array of all drawings + $aDrawings = array(); + + // Loop through PHPExcel + $sheetCount = $pPHPExcel->getSheetCount(); + for ($i = 0; $i < $sheetCount; ++$i) { + // Loop through images and add to array + $iterator = $pPHPExcel->getSheet($i)->getDrawingCollection()->getIterator(); + while ($iterator->valid()) { + $aDrawings[] = $iterator->current(); + + $iterator->next(); + } + } + + return $aDrawings; + } +} diff --git a/lib/phpexcel/PHPExcel/Writer/Excel2007/Rels.php b/lib/phpexcel/PHPExcel/Writer/Excel2007/Rels.php new file mode 100644 index 0000000..0bdb667 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Writer/Excel2007/Rels.php @@ -0,0 +1,437 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Writer_Excel2007_Rels + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_Excel2007_Rels extends PHPExcel_Writer_Excel2007_WriterPart +{ + /** + * Write relationships to XML format + * + * @param PHPExcel $pPHPExcel + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeRelationships(PHPExcel $pPHPExcel = null) + { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // Relationships + $objWriter->startElement('Relationships'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); + + $customPropertyList = $pPHPExcel->getProperties()->getCustomProperties(); + if (!empty($customPropertyList)) { + // Relationship docProps/app.xml + $this->_writeRelationship( + $objWriter, + 4, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties', + 'docProps/custom.xml' + ); + + } + + // Relationship docProps/app.xml + $this->_writeRelationship( + $objWriter, + 3, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties', + 'docProps/app.xml' + ); + + // Relationship docProps/core.xml + $this->_writeRelationship( + $objWriter, + 2, + 'http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties', + 'docProps/core.xml' + ); + + // Relationship xl/workbook.xml + $this->_writeRelationship( + $objWriter, + 1, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument', + 'xl/workbook.xml' + ); + // a custom UI in workbook ? + if($pPHPExcel->hasRibbon()){ + $this->_writeRelationShip( + $objWriter, + 5, + 'http://schemas.microsoft.com/office/2006/relationships/ui/extensibility', + $pPHPExcel->getRibbonXMLData('target') + ); + } + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + /** + * Write workbook relationships to XML format + * + * @param PHPExcel $pPHPExcel + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeWorkbookRelationships(PHPExcel $pPHPExcel = null) + { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // Relationships + $objWriter->startElement('Relationships'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); + + // Relationship styles.xml + $this->_writeRelationship( + $objWriter, + 1, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles', + 'styles.xml' + ); + + // Relationship theme/theme1.xml + $this->_writeRelationship( + $objWriter, + 2, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme', + 'theme/theme1.xml' + ); + + // Relationship sharedStrings.xml + $this->_writeRelationship( + $objWriter, + 3, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings', + 'sharedStrings.xml' + ); + + // Relationships with sheets + $sheetCount = $pPHPExcel->getSheetCount(); + for ($i = 0; $i < $sheetCount; ++$i) { + $this->_writeRelationship( + $objWriter, + ($i + 1 + 3), + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet', + 'worksheets/sheet' . ($i + 1) . '.xml' + ); + } + // Relationships for vbaProject if needed + // id : just after the last sheet + if($pPHPExcel->hasMacros()){ + $this->_writeRelationShip( + $objWriter, + ($i + 1 + 3), + 'http://schemas.microsoft.com/office/2006/relationships/vbaProject', + 'vbaProject.bin' + ); + ++$i;//increment i if needed for an another relation + } + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + /** + * Write worksheet relationships to XML format + * + * Numbering is as follows: + * rId1 - Drawings + * rId_hyperlink_x - Hyperlinks + * + * @param PHPExcel_Worksheet $pWorksheet + * @param int $pWorksheetId + * @param boolean $includeCharts Flag indicating if we should write charts + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeWorksheetRelationships(PHPExcel_Worksheet $pWorksheet = null, $pWorksheetId = 1, $includeCharts = FALSE) + { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // Relationships + $objWriter->startElement('Relationships'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); + + // Write drawing relationships? + $d = 0; + if ($includeCharts) { + $charts = $pWorksheet->getChartCollection(); + } else { + $charts = array(); + } + if (($pWorksheet->getDrawingCollection()->count() > 0) || + (count($charts) > 0)) { + $this->_writeRelationship( + $objWriter, + ++$d, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing', + '../drawings/drawing' . $pWorksheetId . '.xml' + ); + } + + // Write chart relationships? +// $chartCount = 0; +// $charts = $pWorksheet->getChartCollection(); +// echo 'Chart Rels: ' , count($charts) , '<br />'; +// if (count($charts) > 0) { +// foreach($charts as $chart) { +// $this->_writeRelationship( +// $objWriter, +// ++$d, +// 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart', +// '../charts/chart' . ++$chartCount . '.xml' +// ); +// } +// } +// + // Write hyperlink relationships? + $i = 1; + foreach ($pWorksheet->getHyperlinkCollection() as $hyperlink) { + if (!$hyperlink->isInternal()) { + $this->_writeRelationship( + $objWriter, + '_hyperlink_' . $i, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink', + $hyperlink->getUrl(), + 'External' + ); + + ++$i; + } + } + + // Write comments relationship? + $i = 1; + if (count($pWorksheet->getComments()) > 0) { + $this->_writeRelationship( + $objWriter, + '_comments_vml' . $i, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing', + '../drawings/vmlDrawing' . $pWorksheetId . '.vml' + ); + + $this->_writeRelationship( + $objWriter, + '_comments' . $i, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments', + '../comments' . $pWorksheetId . '.xml' + ); + } + + // Write header/footer relationship? + $i = 1; + if (count($pWorksheet->getHeaderFooter()->getImages()) > 0) { + $this->_writeRelationship( + $objWriter, + '_headerfooter_vml' . $i, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing', + '../drawings/vmlDrawingHF' . $pWorksheetId . '.vml' + ); + } + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + /** + * Write drawing relationships to XML format + * + * @param PHPExcel_Worksheet $pWorksheet + * @param int &$chartRef Chart ID + * @param boolean $includeCharts Flag indicating if we should write charts + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeDrawingRelationships(PHPExcel_Worksheet $pWorksheet = null, &$chartRef, $includeCharts = FALSE) + { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // Relationships + $objWriter->startElement('Relationships'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); + + // Loop through images and write relationships + $i = 1; + $iterator = $pWorksheet->getDrawingCollection()->getIterator(); + while ($iterator->valid()) { + if ($iterator->current() instanceof PHPExcel_Worksheet_Drawing + || $iterator->current() instanceof PHPExcel_Worksheet_MemoryDrawing) { + // Write relationship for image drawing + $this->_writeRelationship( + $objWriter, + $i, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image', + '../media/' . str_replace(' ', '', $iterator->current()->getIndexedFilename()) + ); + } + + $iterator->next(); + ++$i; + } + + if ($includeCharts) { + // Loop through charts and write relationships + $chartCount = $pWorksheet->getChartCount(); + if ($chartCount > 0) { + for ($c = 0; $c < $chartCount; ++$c) { + $this->_writeRelationship( + $objWriter, + $i++, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart', + '../charts/chart' . ++$chartRef . '.xml' + ); + } + } + } + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + /** + * Write header/footer drawing relationships to XML format + * + * @param PHPExcel_Worksheet $pWorksheet + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeHeaderFooterDrawingRelationships(PHPExcel_Worksheet $pWorksheet = null) + { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // Relationships + $objWriter->startElement('Relationships'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); + + // Loop through images and write relationships + foreach ($pWorksheet->getHeaderFooter()->getImages() as $key => $value) { + // Write relationship for image drawing + $this->_writeRelationship( + $objWriter, + $key, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image', + '../media/' . $value->getIndexedFilename() + ); + } + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + /** + * Write Override content type + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param int $pId Relationship ID. rId will be prepended! + * @param string $pType Relationship type + * @param string $pTarget Relationship target + * @param string $pTargetMode Relationship target mode + * @throws PHPExcel_Writer_Exception + */ + private function _writeRelationship(PHPExcel_Shared_XMLWriter $objWriter = null, $pId = 1, $pType = '', $pTarget = '', $pTargetMode = '') + { + if ($pType != '' && $pTarget != '') { + // Write relationship + $objWriter->startElement('Relationship'); + $objWriter->writeAttribute('Id', 'rId' . $pId); + $objWriter->writeAttribute('Type', $pType); + $objWriter->writeAttribute('Target', $pTarget); + + if ($pTargetMode != '') { + $objWriter->writeAttribute('TargetMode', $pTargetMode); + } + + $objWriter->endElement(); + } else { + throw new PHPExcel_Writer_Exception("Invalid parameters passed."); + } + } +} diff --git a/lib/phpexcel/PHPExcel/Writer/Excel2007/RelsRibbon.php b/lib/phpexcel/PHPExcel/Writer/Excel2007/RelsRibbon.php new file mode 100644 index 0000000..f924a1d --- /dev/null +++ b/lib/phpexcel/PHPExcel/Writer/Excel2007/RelsRibbon.php @@ -0,0 +1,77 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Writer_Excel2007_RelsRibbon + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_Excel2007_RelsRibbon extends PHPExcel_Writer_Excel2007_WriterPart +{ + /** + * Write relationships for additional objects of custom UI (ribbon) + * + * @param PHPExcel $pPHPExcel + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeRibbonRelationships(PHPExcel $pPHPExcel = null){ + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // Relationships + $objWriter->startElement('Relationships'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); + $localRels=$pPHPExcel->getRibbonBinObjects('names'); + if(is_array($localRels)){ + foreach($localRels as $aId=>$aTarget){ + $objWriter->startElement('Relationship'); + $objWriter->writeAttribute('Id', $aId); + $objWriter->writeAttribute('Type', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image'); + $objWriter->writeAttribute('Target', $aTarget); + $objWriter->endElement();//Relationship + } + } + $objWriter->endElement();//Relationships + + // Return + return $objWriter->getData(); + + } + +} diff --git a/lib/phpexcel/PHPExcel/Writer/Excel2007/RelsVBA.php b/lib/phpexcel/PHPExcel/Writer/Excel2007/RelsVBA.php new file mode 100644 index 0000000..aecb0b8 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Writer/Excel2007/RelsVBA.php @@ -0,0 +1,72 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Writer_Excel2007_RelsVBA + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_Excel2007_RelsVBA extends PHPExcel_Writer_Excel2007_WriterPart +{ + /** + * Write relationships for a signed VBA Project + * + * @param PHPExcel $pPHPExcel + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeVBARelationships(PHPExcel $pPHPExcel = null){ + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // Relationships + $objWriter->startElement('Relationships'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); + $objWriter->startElement('Relationship'); + $objWriter->writeAttribute('Id', 'rId1'); + $objWriter->writeAttribute('Type', 'http://schemas.microsoft.com/office/2006/relationships/vbaProjectSignature'); + $objWriter->writeAttribute('Target', 'vbaProjectSignature.bin'); + $objWriter->endElement();//Relationship + $objWriter->endElement();//Relationships + + // Return + return $objWriter->getData(); + + } + +} diff --git a/lib/phpexcel/PHPExcel/Writer/Excel2007/StringTable.php b/lib/phpexcel/PHPExcel/Writer/Excel2007/StringTable.php new file mode 100644 index 0000000..0e8a259 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Writer/Excel2007/StringTable.php @@ -0,0 +1,319 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Writer_Excel2007_StringTable + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_Excel2007_StringTable extends PHPExcel_Writer_Excel2007_WriterPart +{ + /** + * Create worksheet stringtable + * + * @param PHPExcel_Worksheet $pSheet Worksheet + * @param string[] $pExistingTable Existing table to eventually merge with + * @return string[] String table for worksheet + * @throws PHPExcel_Writer_Exception + */ + public function createStringTable($pSheet = null, $pExistingTable = null) + { + if ($pSheet !== NULL) { + // Create string lookup table + $aStringTable = array(); + $cellCollection = null; + $aFlippedStringTable = null; // For faster lookup + + // Is an existing table given? + if (($pExistingTable !== NULL) && is_array($pExistingTable)) { + $aStringTable = $pExistingTable; + } + + // Fill index array + $aFlippedStringTable = $this->flipStringTable($aStringTable); + + // Loop through cells + foreach ($pSheet->getCellCollection() as $cellID) { + $cell = $pSheet->getCell($cellID); + $cellValue = $cell->getValue(); + if (!is_object($cellValue) && + ($cellValue !== NULL) && + $cellValue !== '' && + !isset($aFlippedStringTable[$cellValue]) && + ($cell->getDataType() == PHPExcel_Cell_DataType::TYPE_STRING || $cell->getDataType() == PHPExcel_Cell_DataType::TYPE_STRING2 || $cell->getDataType() == PHPExcel_Cell_DataType::TYPE_NULL)) { + $aStringTable[] = $cellValue; + $aFlippedStringTable[$cellValue] = true; + } elseif ($cellValue instanceof PHPExcel_RichText && + ($cellValue !== NULL) && + !isset($aFlippedStringTable[$cellValue->getHashCode()])) { + $aStringTable[] = $cellValue; + $aFlippedStringTable[$cellValue->getHashCode()] = true; + } + } + + // Return + return $aStringTable; + } else { + throw new PHPExcel_Writer_Exception("Invalid PHPExcel_Worksheet object passed."); + } + } + + /** + * Write string table to XML format + * + * @param string[] $pStringTable + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeStringTable($pStringTable = null) + { + if ($pStringTable !== NULL) { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // String table + $objWriter->startElement('sst'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'); + $objWriter->writeAttribute('uniqueCount', count($pStringTable)); + + // Loop through string table + foreach ($pStringTable as $textElement) { + $objWriter->startElement('si'); + + if (! $textElement instanceof PHPExcel_RichText) { + $textToWrite = PHPExcel_Shared_String::ControlCharacterPHP2OOXML( $textElement ); + $objWriter->startElement('t'); + if ($textToWrite !== trim($textToWrite)) { + $objWriter->writeAttribute('xml:space', 'preserve'); + } + $objWriter->writeRawData($textToWrite); + $objWriter->endElement(); + } else if ($textElement instanceof PHPExcel_RichText) { + $this->writeRichText($objWriter, $textElement); + } + + $objWriter->endElement(); + } + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } else { + throw new PHPExcel_Writer_Exception("Invalid string table array passed."); + } + } + + /** + * Write Rich Text + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_RichText $pRichText Rich text + * @param string $prefix Optional Namespace prefix + * @throws PHPExcel_Writer_Exception + */ + public function writeRichText(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_RichText $pRichText = null, $prefix=NULL) + { + if ($prefix !== NULL) + $prefix .= ':'; + // Loop through rich text elements + $elements = $pRichText->getRichTextElements(); + foreach ($elements as $element) { + // r + $objWriter->startElement($prefix.'r'); + + // rPr + if ($element instanceof PHPExcel_RichText_Run) { + // rPr + $objWriter->startElement($prefix.'rPr'); + + // rFont + $objWriter->startElement($prefix.'rFont'); + $objWriter->writeAttribute('val', $element->getFont()->getName()); + $objWriter->endElement(); + + // Bold + $objWriter->startElement($prefix.'b'); + $objWriter->writeAttribute('val', ($element->getFont()->getBold() ? 'true' : 'false')); + $objWriter->endElement(); + + // Italic + $objWriter->startElement($prefix.'i'); + $objWriter->writeAttribute('val', ($element->getFont()->getItalic() ? 'true' : 'false')); + $objWriter->endElement(); + + // Superscript / subscript + if ($element->getFont()->getSuperScript() || $element->getFont()->getSubScript()) { + $objWriter->startElement($prefix.'vertAlign'); + if ($element->getFont()->getSuperScript()) { + $objWriter->writeAttribute('val', 'superscript'); + } else if ($element->getFont()->getSubScript()) { + $objWriter->writeAttribute('val', 'subscript'); + } + $objWriter->endElement(); + } + + // Strikethrough + $objWriter->startElement($prefix.'strike'); + $objWriter->writeAttribute('val', ($element->getFont()->getStrikethrough() ? 'true' : 'false')); + $objWriter->endElement(); + + // Color + $objWriter->startElement($prefix.'color'); + $objWriter->writeAttribute('rgb', $element->getFont()->getColor()->getARGB()); + $objWriter->endElement(); + + // Size + $objWriter->startElement($prefix.'sz'); + $objWriter->writeAttribute('val', $element->getFont()->getSize()); + $objWriter->endElement(); + + // Underline + $objWriter->startElement($prefix.'u'); + $objWriter->writeAttribute('val', $element->getFont()->getUnderline()); + $objWriter->endElement(); + + $objWriter->endElement(); + } + + // t + $objWriter->startElement($prefix.'t'); + $objWriter->writeAttribute('xml:space', 'preserve'); + $objWriter->writeRawData(PHPExcel_Shared_String::ControlCharacterPHP2OOXML( $element->getText() )); + $objWriter->endElement(); + + $objWriter->endElement(); + } + } + + /** + * Write Rich Text + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param string|PHPExcel_RichText $pRichText text string or Rich text + * @param string $prefix Optional Namespace prefix + * @throws PHPExcel_Writer_Exception + */ + public function writeRichTextForCharts(PHPExcel_Shared_XMLWriter $objWriter = null, $pRichText = null, $prefix=NULL) + { + if (!$pRichText instanceof PHPExcel_RichText) { + $textRun = $pRichText; + $pRichText = new PHPExcel_RichText(); + $pRichText->createTextRun($textRun); + } + + if ($prefix !== NULL) + $prefix .= ':'; + // Loop through rich text elements + $elements = $pRichText->getRichTextElements(); + foreach ($elements as $element) { + // r + $objWriter->startElement($prefix.'r'); + + // rPr + $objWriter->startElement($prefix.'rPr'); + + // Bold + $objWriter->writeAttribute('b', ($element->getFont()->getBold() ? 1 : 0)); + // Italic + $objWriter->writeAttribute('i', ($element->getFont()->getItalic() ? 1 : 0)); + // Underline + $underlineType = $element->getFont()->getUnderline(); + switch($underlineType) { + case 'single' : + $underlineType = 'sng'; + break; + case 'double' : + $underlineType = 'dbl'; + break; + } + $objWriter->writeAttribute('u', $underlineType); + // Strikethrough + $objWriter->writeAttribute('strike', ($element->getFont()->getStrikethrough() ? 'sngStrike' : 'noStrike')); + + // rFont + $objWriter->startElement($prefix.'latin'); + $objWriter->writeAttribute('typeface', $element->getFont()->getName()); + $objWriter->endElement(); + + // Superscript / subscript +// if ($element->getFont()->getSuperScript() || $element->getFont()->getSubScript()) { +// $objWriter->startElement($prefix.'vertAlign'); +// if ($element->getFont()->getSuperScript()) { +// $objWriter->writeAttribute('val', 'superscript'); +// } else if ($element->getFont()->getSubScript()) { +// $objWriter->writeAttribute('val', 'subscript'); +// } +// $objWriter->endElement(); +// } +// + $objWriter->endElement(); + + // t + $objWriter->startElement($prefix.'t'); +// $objWriter->writeAttribute('xml:space', 'preserve'); // Excel2010 accepts, Excel2007 complains + $objWriter->writeRawData(PHPExcel_Shared_String::ControlCharacterPHP2OOXML( $element->getText() )); + $objWriter->endElement(); + + $objWriter->endElement(); + } + } + + /** + * Flip string table (for index searching) + * + * @param array $stringTable Stringtable + * @return array + */ + public function flipStringTable($stringTable = array()) { + // Return value + $returnValue = array(); + + // Loop through stringtable and add flipped items to $returnValue + foreach ($stringTable as $key => $value) { + if (! $value instanceof PHPExcel_RichText) { + $returnValue[$value] = $key; + } else if ($value instanceof PHPExcel_RichText) { + $returnValue[$value->getHashCode()] = $key; + } + } + + // Return + return $returnValue; + } +} diff --git a/lib/phpexcel/PHPExcel/Writer/Excel2007/Style.php b/lib/phpexcel/PHPExcel/Writer/Excel2007/Style.php new file mode 100644 index 0000000..849ad12 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Writer/Excel2007/Style.php @@ -0,0 +1,704 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Writer_Excel2007_Style + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_Excel2007_Style extends PHPExcel_Writer_Excel2007_WriterPart +{ + /** + * Write styles to XML format + * + * @param PHPExcel $pPHPExcel + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeStyles(PHPExcel $pPHPExcel = null) + { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // styleSheet + $objWriter->startElement('styleSheet'); + $objWriter->writeAttribute('xml:space', 'preserve'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'); + + // numFmts + $objWriter->startElement('numFmts'); + $objWriter->writeAttribute('count', $this->getParentWriter()->getNumFmtHashTable()->count()); + + // numFmt + for ($i = 0; $i < $this->getParentWriter()->getNumFmtHashTable()->count(); ++$i) { + $this->_writeNumFmt($objWriter, $this->getParentWriter()->getNumFmtHashTable()->getByIndex($i), $i); + } + + $objWriter->endElement(); + + // fonts + $objWriter->startElement('fonts'); + $objWriter->writeAttribute('count', $this->getParentWriter()->getFontHashTable()->count()); + + // font + for ($i = 0; $i < $this->getParentWriter()->getFontHashTable()->count(); ++$i) { + $this->_writeFont($objWriter, $this->getParentWriter()->getFontHashTable()->getByIndex($i)); + } + + $objWriter->endElement(); + + // fills + $objWriter->startElement('fills'); + $objWriter->writeAttribute('count', $this->getParentWriter()->getFillHashTable()->count()); + + // fill + for ($i = 0; $i < $this->getParentWriter()->getFillHashTable()->count(); ++$i) { + $this->_writeFill($objWriter, $this->getParentWriter()->getFillHashTable()->getByIndex($i)); + } + + $objWriter->endElement(); + + // borders + $objWriter->startElement('borders'); + $objWriter->writeAttribute('count', $this->getParentWriter()->getBordersHashTable()->count()); + + // border + for ($i = 0; $i < $this->getParentWriter()->getBordersHashTable()->count(); ++$i) { + $this->_writeBorder($objWriter, $this->getParentWriter()->getBordersHashTable()->getByIndex($i)); + } + + $objWriter->endElement(); + + // cellStyleXfs + $objWriter->startElement('cellStyleXfs'); + $objWriter->writeAttribute('count', 1); + + // xf + $objWriter->startElement('xf'); + $objWriter->writeAttribute('numFmtId', 0); + $objWriter->writeAttribute('fontId', 0); + $objWriter->writeAttribute('fillId', 0); + $objWriter->writeAttribute('borderId', 0); + $objWriter->endElement(); + + $objWriter->endElement(); + + // cellXfs + $objWriter->startElement('cellXfs'); + $objWriter->writeAttribute('count', count($pPHPExcel->getCellXfCollection())); + + // xf + foreach ($pPHPExcel->getCellXfCollection() as $cellXf) { + $this->_writeCellStyleXf($objWriter, $cellXf, $pPHPExcel); + } + + $objWriter->endElement(); + + // cellStyles + $objWriter->startElement('cellStyles'); + $objWriter->writeAttribute('count', 1); + + // cellStyle + $objWriter->startElement('cellStyle'); + $objWriter->writeAttribute('name', 'Normal'); + $objWriter->writeAttribute('xfId', 0); + $objWriter->writeAttribute('builtinId', 0); + $objWriter->endElement(); + + $objWriter->endElement(); + + // dxfs + $objWriter->startElement('dxfs'); + $objWriter->writeAttribute('count', $this->getParentWriter()->getStylesConditionalHashTable()->count()); + + // dxf + for ($i = 0; $i < $this->getParentWriter()->getStylesConditionalHashTable()->count(); ++$i) { + $this->_writeCellStyleDxf($objWriter, $this->getParentWriter()->getStylesConditionalHashTable()->getByIndex($i)->getStyle()); + } + + $objWriter->endElement(); + + // tableStyles + $objWriter->startElement('tableStyles'); + $objWriter->writeAttribute('defaultTableStyle', 'TableStyleMedium9'); + $objWriter->writeAttribute('defaultPivotStyle', 'PivotTableStyle1'); + $objWriter->endElement(); + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + /** + * Write Fill + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Style_Fill $pFill Fill style + * @throws PHPExcel_Writer_Exception + */ + private function _writeFill(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_Fill $pFill = null) + { + // Check if this is a pattern type or gradient type + if ($pFill->getFillType() === PHPExcel_Style_Fill::FILL_GRADIENT_LINEAR || + $pFill->getFillType() === PHPExcel_Style_Fill::FILL_GRADIENT_PATH) { + // Gradient fill + $this->_writeGradientFill($objWriter, $pFill); + } elseif($pFill->getFillType() !== NULL) { + // Pattern fill + $this->_writePatternFill($objWriter, $pFill); + } + } + + /** + * Write Gradient Fill + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Style_Fill $pFill Fill style + * @throws PHPExcel_Writer_Exception + */ + private function _writeGradientFill(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_Fill $pFill = null) + { + // fill + $objWriter->startElement('fill'); + + // gradientFill + $objWriter->startElement('gradientFill'); + $objWriter->writeAttribute('type', $pFill->getFillType()); + $objWriter->writeAttribute('degree', $pFill->getRotation()); + + // stop + $objWriter->startElement('stop'); + $objWriter->writeAttribute('position', '0'); + + // color + $objWriter->startElement('color'); + $objWriter->writeAttribute('rgb', $pFill->getStartColor()->getARGB()); + $objWriter->endElement(); + + $objWriter->endElement(); + + // stop + $objWriter->startElement('stop'); + $objWriter->writeAttribute('position', '1'); + + // color + $objWriter->startElement('color'); + $objWriter->writeAttribute('rgb', $pFill->getEndColor()->getARGB()); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + } + + /** + * Write Pattern Fill + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Style_Fill $pFill Fill style + * @throws PHPExcel_Writer_Exception + */ + private function _writePatternFill(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_Fill $pFill = null) + { + // fill + $objWriter->startElement('fill'); + + // patternFill + $objWriter->startElement('patternFill'); + $objWriter->writeAttribute('patternType', $pFill->getFillType()); + + if ($pFill->getFillType() !== PHPExcel_Style_Fill::FILL_NONE) { + // fgColor + if ($pFill->getStartColor()->getARGB()) { + $objWriter->startElement('fgColor'); + $objWriter->writeAttribute('rgb', $pFill->getStartColor()->getARGB()); + $objWriter->endElement(); + } + } + if ($pFill->getFillType() !== PHPExcel_Style_Fill::FILL_NONE) { + // bgColor + if ($pFill->getEndColor()->getARGB()) { + $objWriter->startElement('bgColor'); + $objWriter->writeAttribute('rgb', $pFill->getEndColor()->getARGB()); + $objWriter->endElement(); + } + } + + $objWriter->endElement(); + + $objWriter->endElement(); + } + + /** + * Write Font + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Style_Font $pFont Font style + * @throws PHPExcel_Writer_Exception + */ + private function _writeFont(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_Font $pFont = null) + { + // font + $objWriter->startElement('font'); + // Weird! The order of these elements actually makes a difference when opening Excel2007 + // files in Excel2003 with the compatibility pack. It's not documented behaviour, + // and makes for a real WTF! + + // Bold. We explicitly write this element also when false (like MS Office Excel 2007 does + // for conditional formatting). Otherwise it will apparently not be picked up in conditional + // formatting style dialog + if ($pFont->getBold() !== NULL) { + $objWriter->startElement('b'); + $objWriter->writeAttribute('val', $pFont->getBold() ? '1' : '0'); + $objWriter->endElement(); + } + + // Italic + if ($pFont->getItalic() !== NULL) { + $objWriter->startElement('i'); + $objWriter->writeAttribute('val', $pFont->getItalic() ? '1' : '0'); + $objWriter->endElement(); + } + + // Strikethrough + if ($pFont->getStrikethrough() !== NULL) { + $objWriter->startElement('strike'); + $objWriter->writeAttribute('val', $pFont->getStrikethrough() ? '1' : '0'); + $objWriter->endElement(); + } + + // Underline + if ($pFont->getUnderline() !== NULL) { + $objWriter->startElement('u'); + $objWriter->writeAttribute('val', $pFont->getUnderline()); + $objWriter->endElement(); + } + + // Superscript / subscript + if ($pFont->getSuperScript() === TRUE || $pFont->getSubScript() === TRUE) { + $objWriter->startElement('vertAlign'); + if ($pFont->getSuperScript() === TRUE) { + $objWriter->writeAttribute('val', 'superscript'); + } else if ($pFont->getSubScript() === TRUE) { + $objWriter->writeAttribute('val', 'subscript'); + } + $objWriter->endElement(); + } + + // Size + if ($pFont->getSize() !== NULL) { + $objWriter->startElement('sz'); + $objWriter->writeAttribute('val', $pFont->getSize()); + $objWriter->endElement(); + } + + // Foreground color + if ($pFont->getColor()->getARGB() !== NULL) { + $objWriter->startElement('color'); + $objWriter->writeAttribute('rgb', $pFont->getColor()->getARGB()); + $objWriter->endElement(); + } + + // Name + if ($pFont->getName() !== NULL) { + $objWriter->startElement('name'); + $objWriter->writeAttribute('val', $pFont->getName()); + $objWriter->endElement(); + } + + $objWriter->endElement(); + } + + /** + * Write Border + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Style_Borders $pBorders Borders style + * @throws PHPExcel_Writer_Exception + */ + private function _writeBorder(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_Borders $pBorders = null) + { + // Write border + $objWriter->startElement('border'); + // Diagonal? + switch ($pBorders->getDiagonalDirection()) { + case PHPExcel_Style_Borders::DIAGONAL_UP: + $objWriter->writeAttribute('diagonalUp', 'true'); + $objWriter->writeAttribute('diagonalDown', 'false'); + break; + case PHPExcel_Style_Borders::DIAGONAL_DOWN: + $objWriter->writeAttribute('diagonalUp', 'false'); + $objWriter->writeAttribute('diagonalDown', 'true'); + break; + case PHPExcel_Style_Borders::DIAGONAL_BOTH: + $objWriter->writeAttribute('diagonalUp', 'true'); + $objWriter->writeAttribute('diagonalDown', 'true'); + break; + } + + // BorderPr + $this->_writeBorderPr($objWriter, 'left', $pBorders->getLeft()); + $this->_writeBorderPr($objWriter, 'right', $pBorders->getRight()); + $this->_writeBorderPr($objWriter, 'top', $pBorders->getTop()); + $this->_writeBorderPr($objWriter, 'bottom', $pBorders->getBottom()); + $this->_writeBorderPr($objWriter, 'diagonal', $pBorders->getDiagonal()); + $objWriter->endElement(); + } + + /** + * Write Cell Style Xf + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Style $pStyle Style + * @param PHPExcel $pPHPExcel Workbook + * @throws PHPExcel_Writer_Exception + */ + private function _writeCellStyleXf(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style $pStyle = null, PHPExcel $pPHPExcel = null) + { + // xf + $objWriter->startElement('xf'); + $objWriter->writeAttribute('xfId', 0); + $objWriter->writeAttribute('fontId', (int)$this->getParentWriter()->getFontHashTable()->getIndexForHashCode($pStyle->getFont()->getHashCode())); + if ($pStyle->getQuotePrefix()) { + $objWriter->writeAttribute('quotePrefix', 1); + } + + if ($pStyle->getNumberFormat()->getBuiltInFormatCode() === false) { + $objWriter->writeAttribute('numFmtId', (int)($this->getParentWriter()->getNumFmtHashTable()->getIndexForHashCode($pStyle->getNumberFormat()->getHashCode()) + 164) ); + } else { + $objWriter->writeAttribute('numFmtId', (int)$pStyle->getNumberFormat()->getBuiltInFormatCode()); + } + + $objWriter->writeAttribute('fillId', (int)$this->getParentWriter()->getFillHashTable()->getIndexForHashCode($pStyle->getFill()->getHashCode())); + $objWriter->writeAttribute('borderId', (int)$this->getParentWriter()->getBordersHashTable()->getIndexForHashCode($pStyle->getBorders()->getHashCode())); + + // Apply styles? + $objWriter->writeAttribute('applyFont', ($pPHPExcel->getDefaultStyle()->getFont()->getHashCode() != $pStyle->getFont()->getHashCode()) ? '1' : '0'); + $objWriter->writeAttribute('applyNumberFormat', ($pPHPExcel->getDefaultStyle()->getNumberFormat()->getHashCode() != $pStyle->getNumberFormat()->getHashCode()) ? '1' : '0'); + $objWriter->writeAttribute('applyFill', ($pPHPExcel->getDefaultStyle()->getFill()->getHashCode() != $pStyle->getFill()->getHashCode()) ? '1' : '0'); + $objWriter->writeAttribute('applyBorder', ($pPHPExcel->getDefaultStyle()->getBorders()->getHashCode() != $pStyle->getBorders()->getHashCode()) ? '1' : '0'); + $objWriter->writeAttribute('applyAlignment', ($pPHPExcel->getDefaultStyle()->getAlignment()->getHashCode() != $pStyle->getAlignment()->getHashCode()) ? '1' : '0'); + if ($pStyle->getProtection()->getLocked() != PHPExcel_Style_Protection::PROTECTION_INHERIT || $pStyle->getProtection()->getHidden() != PHPExcel_Style_Protection::PROTECTION_INHERIT) { + $objWriter->writeAttribute('applyProtection', 'true'); + } + + // alignment + $objWriter->startElement('alignment'); + $objWriter->writeAttribute('horizontal', $pStyle->getAlignment()->getHorizontal()); + $objWriter->writeAttribute('vertical', $pStyle->getAlignment()->getVertical()); + + $textRotation = 0; + if ($pStyle->getAlignment()->getTextRotation() >= 0) { + $textRotation = $pStyle->getAlignment()->getTextRotation(); + } else if ($pStyle->getAlignment()->getTextRotation() < 0) { + $textRotation = 90 - $pStyle->getAlignment()->getTextRotation(); + } + $objWriter->writeAttribute('textRotation', $textRotation); + + $objWriter->writeAttribute('wrapText', ($pStyle->getAlignment()->getWrapText() ? 'true' : 'false')); + $objWriter->writeAttribute('shrinkToFit', ($pStyle->getAlignment()->getShrinkToFit() ? 'true' : 'false')); + + if ($pStyle->getAlignment()->getIndent() > 0) { + $objWriter->writeAttribute('indent', $pStyle->getAlignment()->getIndent()); + } + $objWriter->endElement(); + + // protection + if ($pStyle->getProtection()->getLocked() != PHPExcel_Style_Protection::PROTECTION_INHERIT || $pStyle->getProtection()->getHidden() != PHPExcel_Style_Protection::PROTECTION_INHERIT) { + $objWriter->startElement('protection'); + if ($pStyle->getProtection()->getLocked() != PHPExcel_Style_Protection::PROTECTION_INHERIT) { + $objWriter->writeAttribute('locked', ($pStyle->getProtection()->getLocked() == PHPExcel_Style_Protection::PROTECTION_PROTECTED ? 'true' : 'false')); + } + if ($pStyle->getProtection()->getHidden() != PHPExcel_Style_Protection::PROTECTION_INHERIT) { + $objWriter->writeAttribute('hidden', ($pStyle->getProtection()->getHidden() == PHPExcel_Style_Protection::PROTECTION_PROTECTED ? 'true' : 'false')); + } + $objWriter->endElement(); + } + + $objWriter->endElement(); + } + + /** + * Write Cell Style Dxf + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Style $pStyle Style + * @throws PHPExcel_Writer_Exception + */ + private function _writeCellStyleDxf(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style $pStyle = null) + { + // dxf + $objWriter->startElement('dxf'); + + // font + $this->_writeFont($objWriter, $pStyle->getFont()); + + // numFmt + $this->_writeNumFmt($objWriter, $pStyle->getNumberFormat()); + + // fill + $this->_writeFill($objWriter, $pStyle->getFill()); + + // alignment + $objWriter->startElement('alignment'); + if ($pStyle->getAlignment()->getHorizontal() !== NULL) { + $objWriter->writeAttribute('horizontal', $pStyle->getAlignment()->getHorizontal()); + } + if ($pStyle->getAlignment()->getVertical() !== NULL) { + $objWriter->writeAttribute('vertical', $pStyle->getAlignment()->getVertical()); + } + + if ($pStyle->getAlignment()->getTextRotation() !== NULL) { + $textRotation = 0; + if ($pStyle->getAlignment()->getTextRotation() >= 0) { + $textRotation = $pStyle->getAlignment()->getTextRotation(); + } else if ($pStyle->getAlignment()->getTextRotation() < 0) { + $textRotation = 90 - $pStyle->getAlignment()->getTextRotation(); + } + $objWriter->writeAttribute('textRotation', $textRotation); + } + $objWriter->endElement(); + + // border + $this->_writeBorder($objWriter, $pStyle->getBorders()); + + // protection + if (($pStyle->getProtection()->getLocked() !== NULL) || + ($pStyle->getProtection()->getHidden() !== NULL)) { + if ($pStyle->getProtection()->getLocked() !== PHPExcel_Style_Protection::PROTECTION_INHERIT || + $pStyle->getProtection()->getHidden() !== PHPExcel_Style_Protection::PROTECTION_INHERIT) { + $objWriter->startElement('protection'); + if (($pStyle->getProtection()->getLocked() !== NULL) && + ($pStyle->getProtection()->getLocked() !== PHPExcel_Style_Protection::PROTECTION_INHERIT)) { + $objWriter->writeAttribute('locked', ($pStyle->getProtection()->getLocked() == PHPExcel_Style_Protection::PROTECTION_PROTECTED ? 'true' : 'false')); + } + if (($pStyle->getProtection()->getHidden() !== NULL) && + ($pStyle->getProtection()->getHidden() !== PHPExcel_Style_Protection::PROTECTION_INHERIT)) { + $objWriter->writeAttribute('hidden', ($pStyle->getProtection()->getHidden() == PHPExcel_Style_Protection::PROTECTION_PROTECTED ? 'true' : 'false')); + } + $objWriter->endElement(); + } + } + + $objWriter->endElement(); + } + + /** + * Write BorderPr + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param string $pName Element name + * @param PHPExcel_Style_Border $pBorder Border style + * @throws PHPExcel_Writer_Exception + */ + private function _writeBorderPr(PHPExcel_Shared_XMLWriter $objWriter = null, $pName = 'left', PHPExcel_Style_Border $pBorder = null) + { + // Write BorderPr + if ($pBorder->getBorderStyle() != PHPExcel_Style_Border::BORDER_NONE) { + $objWriter->startElement($pName); + $objWriter->writeAttribute('style', $pBorder->getBorderStyle()); + + // color + $objWriter->startElement('color'); + $objWriter->writeAttribute('rgb', $pBorder->getColor()->getARGB()); + $objWriter->endElement(); + + $objWriter->endElement(); + } + } + + /** + * Write NumberFormat + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Style_NumberFormat $pNumberFormat Number Format + * @param int $pId Number Format identifier + * @throws PHPExcel_Writer_Exception + */ + private function _writeNumFmt(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_NumberFormat $pNumberFormat = null, $pId = 0) + { + // Translate formatcode + $formatCode = $pNumberFormat->getFormatCode(); + + // numFmt + if ($formatCode !== NULL) { + $objWriter->startElement('numFmt'); + $objWriter->writeAttribute('numFmtId', ($pId + 164)); + $objWriter->writeAttribute('formatCode', $formatCode); + $objWriter->endElement(); + } + } + + /** + * Get an array of all styles + * + * @param PHPExcel $pPHPExcel + * @return PHPExcel_Style[] All styles in PHPExcel + * @throws PHPExcel_Writer_Exception + */ + public function allStyles(PHPExcel $pPHPExcel = null) + { + $aStyles = $pPHPExcel->getCellXfCollection(); + + return $aStyles; + } + + /** + * Get an array of all conditional styles + * + * @param PHPExcel $pPHPExcel + * @return PHPExcel_Style_Conditional[] All conditional styles in PHPExcel + * @throws PHPExcel_Writer_Exception + */ + public function allConditionalStyles(PHPExcel $pPHPExcel = null) + { + // Get an array of all styles + $aStyles = array(); + + $sheetCount = $pPHPExcel->getSheetCount(); + for ($i = 0; $i < $sheetCount; ++$i) { + foreach ($pPHPExcel->getSheet($i)->getConditionalStylesCollection() as $conditionalStyles) { + foreach ($conditionalStyles as $conditionalStyle) { + $aStyles[] = $conditionalStyle; + } + } + } + + return $aStyles; + } + + /** + * Get an array of all fills + * + * @param PHPExcel $pPHPExcel + * @return PHPExcel_Style_Fill[] All fills in PHPExcel + * @throws PHPExcel_Writer_Exception + */ + public function allFills(PHPExcel $pPHPExcel = null) + { + // Get an array of unique fills + $aFills = array(); + + // Two first fills are predefined + $fill0 = new PHPExcel_Style_Fill(); + $fill0->setFillType(PHPExcel_Style_Fill::FILL_NONE); + $aFills[] = $fill0; + + $fill1 = new PHPExcel_Style_Fill(); + $fill1->setFillType(PHPExcel_Style_Fill::FILL_PATTERN_GRAY125); + $aFills[] = $fill1; + // The remaining fills + $aStyles = $this->allStyles($pPHPExcel); + foreach ($aStyles as $style) { + if (!array_key_exists($style->getFill()->getHashCode(), $aFills)) { + $aFills[ $style->getFill()->getHashCode() ] = $style->getFill(); + } + } + + return $aFills; + } + + /** + * Get an array of all fonts + * + * @param PHPExcel $pPHPExcel + * @return PHPExcel_Style_Font[] All fonts in PHPExcel + * @throws PHPExcel_Writer_Exception + */ + public function allFonts(PHPExcel $pPHPExcel = null) + { + // Get an array of unique fonts + $aFonts = array(); + $aStyles = $this->allStyles($pPHPExcel); + + foreach ($aStyles as $style) { + if (!array_key_exists($style->getFont()->getHashCode(), $aFonts)) { + $aFonts[ $style->getFont()->getHashCode() ] = $style->getFont(); + } + } + + return $aFonts; + } + + /** + * Get an array of all borders + * + * @param PHPExcel $pPHPExcel + * @return PHPExcel_Style_Borders[] All borders in PHPExcel + * @throws PHPExcel_Writer_Exception + */ + public function allBorders(PHPExcel $pPHPExcel = null) + { + // Get an array of unique borders + $aBorders = array(); + $aStyles = $this->allStyles($pPHPExcel); + + foreach ($aStyles as $style) { + if (!array_key_exists($style->getBorders()->getHashCode(), $aBorders)) { + $aBorders[ $style->getBorders()->getHashCode() ] = $style->getBorders(); + } + } + + return $aBorders; + } + + /** + * Get an array of all number formats + * + * @param PHPExcel $pPHPExcel + * @return PHPExcel_Style_NumberFormat[] All number formats in PHPExcel + * @throws PHPExcel_Writer_Exception + */ + public function allNumberFormats(PHPExcel $pPHPExcel = null) + { + // Get an array of unique number formats + $aNumFmts = array(); + $aStyles = $this->allStyles($pPHPExcel); + + foreach ($aStyles as $style) { + if ($style->getNumberFormat()->getBuiltInFormatCode() === false && !array_key_exists($style->getNumberFormat()->getHashCode(), $aNumFmts)) { + $aNumFmts[ $style->getNumberFormat()->getHashCode() ] = $style->getNumberFormat(); + } + } + + return $aNumFmts; + } +} diff --git a/lib/phpexcel/PHPExcel/Writer/Excel2007/Theme.php b/lib/phpexcel/PHPExcel/Writer/Excel2007/Theme.php new file mode 100644 index 0000000..064c3ed --- /dev/null +++ b/lib/phpexcel/PHPExcel/Writer/Excel2007/Theme.php @@ -0,0 +1,871 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Writer_Excel2007_Theme + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_Excel2007_Theme extends PHPExcel_Writer_Excel2007_WriterPart +{ + /** + * Map of Major fonts to write + * @static array of string + * + */ + private static $_majorFonts = array( + 'Jpan' => 'MS Pゴシック', + 'Hang' => '맑은 고딕', + 'Hans' => '宋体', + 'Hant' => '新細明體', + 'Arab' => 'Times New Roman', + 'Hebr' => 'Times New Roman', + 'Thai' => 'Tahoma', + 'Ethi' => 'Nyala', + 'Beng' => 'Vrinda', + 'Gujr' => 'Shruti', + 'Khmr' => 'MoolBoran', + 'Knda' => 'Tunga', + 'Guru' => 'Raavi', + 'Cans' => 'Euphemia', + 'Cher' => 'Plantagenet Cherokee', + 'Yiii' => 'Microsoft Yi Baiti', + 'Tibt' => 'Microsoft Himalaya', + 'Thaa' => 'MV Boli', + 'Deva' => 'Mangal', + 'Telu' => 'Gautami', + 'Taml' => 'Latha', + 'Syrc' => 'Estrangelo Edessa', + 'Orya' => 'Kalinga', + 'Mlym' => 'Kartika', + 'Laoo' => 'DokChampa', + 'Sinh' => 'Iskoola Pota', + 'Mong' => 'Mongolian Baiti', + 'Viet' => 'Times New Roman', + 'Uigh' => 'Microsoft Uighur', + 'Geor' => 'Sylfaen', + ); + + /** + * Map of Minor fonts to write + * @static array of string + * + */ + private static $_minorFonts = array( + 'Jpan' => 'MS Pゴシック', + 'Hang' => '맑은 고딕', + 'Hans' => '宋体', + 'Hant' => '新細明體', + 'Arab' => 'Arial', + 'Hebr' => 'Arial', + 'Thai' => 'Tahoma', + 'Ethi' => 'Nyala', + 'Beng' => 'Vrinda', + 'Gujr' => 'Shruti', + 'Khmr' => 'DaunPenh', + 'Knda' => 'Tunga', + 'Guru' => 'Raavi', + 'Cans' => 'Euphemia', + 'Cher' => 'Plantagenet Cherokee', + 'Yiii' => 'Microsoft Yi Baiti', + 'Tibt' => 'Microsoft Himalaya', + 'Thaa' => 'MV Boli', + 'Deva' => 'Mangal', + 'Telu' => 'Gautami', + 'Taml' => 'Latha', + 'Syrc' => 'Estrangelo Edessa', + 'Orya' => 'Kalinga', + 'Mlym' => 'Kartika', + 'Laoo' => 'DokChampa', + 'Sinh' => 'Iskoola Pota', + 'Mong' => 'Mongolian Baiti', + 'Viet' => 'Arial', + 'Uigh' => 'Microsoft Uighur', + 'Geor' => 'Sylfaen', + ); + + /** + * Map of core colours + * @static array of string + * + */ + private static $_colourScheme = array( + 'dk2' => '1F497D', + 'lt2' => 'EEECE1', + 'accent1' => '4F81BD', + 'accent2' => 'C0504D', + 'accent3' => '9BBB59', + 'accent4' => '8064A2', + 'accent5' => '4BACC6', + 'accent6' => 'F79646', + 'hlink' => '0000FF', + 'folHlink' => '800080', + ); + + /** + * Write theme to XML format + * + * @param PHPExcel $pPHPExcel + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeTheme(PHPExcel $pPHPExcel = null) + { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // a:theme + $objWriter->startElement('a:theme'); + $objWriter->writeAttribute('xmlns:a', 'http://schemas.openxmlformats.org/drawingml/2006/main'); + $objWriter->writeAttribute('name', 'Office Theme'); + + // a:themeElements + $objWriter->startElement('a:themeElements'); + + // a:clrScheme + $objWriter->startElement('a:clrScheme'); + $objWriter->writeAttribute('name', 'Office'); + + // a:dk1 + $objWriter->startElement('a:dk1'); + + // a:sysClr + $objWriter->startElement('a:sysClr'); + $objWriter->writeAttribute('val', 'windowText'); + $objWriter->writeAttribute('lastClr', '000000'); + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:lt1 + $objWriter->startElement('a:lt1'); + + // a:sysClr + $objWriter->startElement('a:sysClr'); + $objWriter->writeAttribute('val', 'window'); + $objWriter->writeAttribute('lastClr', 'FFFFFF'); + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:dk2 + $this->_writeColourScheme($objWriter); + + $objWriter->endElement(); + + // a:fontScheme + $objWriter->startElement('a:fontScheme'); + $objWriter->writeAttribute('name', 'Office'); + + // a:majorFont + $objWriter->startElement('a:majorFont'); + $this->_writeFonts($objWriter, 'Cambria', self::$_majorFonts); + $objWriter->endElement(); + + // a:minorFont + $objWriter->startElement('a:minorFont'); + $this->_writeFonts($objWriter, 'Calibri', self::$_minorFonts); + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:fmtScheme + $objWriter->startElement('a:fmtScheme'); + $objWriter->writeAttribute('name', 'Office'); + + // a:fillStyleLst + $objWriter->startElement('a:fillStyleLst'); + + // a:solidFill + $objWriter->startElement('a:solidFill'); + + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:gradFill + $objWriter->startElement('a:gradFill'); + $objWriter->writeAttribute('rotWithShape', '1'); + + // a:gsLst + $objWriter->startElement('a:gsLst'); + + // a:gs + $objWriter->startElement('a:gs'); + $objWriter->writeAttribute('pos', '0'); + + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); + + // a:tint + $objWriter->startElement('a:tint'); + $objWriter->writeAttribute('val', '50000'); + $objWriter->endElement(); + + // a:satMod + $objWriter->startElement('a:satMod'); + $objWriter->writeAttribute('val', '300000'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:gs + $objWriter->startElement('a:gs'); + $objWriter->writeAttribute('pos', '35000'); + + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); + + // a:tint + $objWriter->startElement('a:tint'); + $objWriter->writeAttribute('val', '37000'); + $objWriter->endElement(); + + // a:satMod + $objWriter->startElement('a:satMod'); + $objWriter->writeAttribute('val', '300000'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:gs + $objWriter->startElement('a:gs'); + $objWriter->writeAttribute('pos', '100000'); + + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); + + // a:tint + $objWriter->startElement('a:tint'); + $objWriter->writeAttribute('val', '15000'); + $objWriter->endElement(); + + // a:satMod + $objWriter->startElement('a:satMod'); + $objWriter->writeAttribute('val', '350000'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:lin + $objWriter->startElement('a:lin'); + $objWriter->writeAttribute('ang', '16200000'); + $objWriter->writeAttribute('scaled', '1'); + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:gradFill + $objWriter->startElement('a:gradFill'); + $objWriter->writeAttribute('rotWithShape', '1'); + + // a:gsLst + $objWriter->startElement('a:gsLst'); + + // a:gs + $objWriter->startElement('a:gs'); + $objWriter->writeAttribute('pos', '0'); + + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); + + // a:shade + $objWriter->startElement('a:shade'); + $objWriter->writeAttribute('val', '51000'); + $objWriter->endElement(); + + // a:satMod + $objWriter->startElement('a:satMod'); + $objWriter->writeAttribute('val', '130000'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:gs + $objWriter->startElement('a:gs'); + $objWriter->writeAttribute('pos', '80000'); + + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); + + // a:shade + $objWriter->startElement('a:shade'); + $objWriter->writeAttribute('val', '93000'); + $objWriter->endElement(); + + // a:satMod + $objWriter->startElement('a:satMod'); + $objWriter->writeAttribute('val', '130000'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:gs + $objWriter->startElement('a:gs'); + $objWriter->writeAttribute('pos', '100000'); + + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); + + // a:shade + $objWriter->startElement('a:shade'); + $objWriter->writeAttribute('val', '94000'); + $objWriter->endElement(); + + // a:satMod + $objWriter->startElement('a:satMod'); + $objWriter->writeAttribute('val', '135000'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:lin + $objWriter->startElement('a:lin'); + $objWriter->writeAttribute('ang', '16200000'); + $objWriter->writeAttribute('scaled', '0'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:lnStyleLst + $objWriter->startElement('a:lnStyleLst'); + + // a:ln + $objWriter->startElement('a:ln'); + $objWriter->writeAttribute('w', '9525'); + $objWriter->writeAttribute('cap', 'flat'); + $objWriter->writeAttribute('cmpd', 'sng'); + $objWriter->writeAttribute('algn', 'ctr'); + + // a:solidFill + $objWriter->startElement('a:solidFill'); + + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); + + // a:shade + $objWriter->startElement('a:shade'); + $objWriter->writeAttribute('val', '95000'); + $objWriter->endElement(); + + // a:satMod + $objWriter->startElement('a:satMod'); + $objWriter->writeAttribute('val', '105000'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:prstDash + $objWriter->startElement('a:prstDash'); + $objWriter->writeAttribute('val', 'solid'); + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:ln + $objWriter->startElement('a:ln'); + $objWriter->writeAttribute('w', '25400'); + $objWriter->writeAttribute('cap', 'flat'); + $objWriter->writeAttribute('cmpd', 'sng'); + $objWriter->writeAttribute('algn', 'ctr'); + + // a:solidFill + $objWriter->startElement('a:solidFill'); + + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:prstDash + $objWriter->startElement('a:prstDash'); + $objWriter->writeAttribute('val', 'solid'); + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:ln + $objWriter->startElement('a:ln'); + $objWriter->writeAttribute('w', '38100'); + $objWriter->writeAttribute('cap', 'flat'); + $objWriter->writeAttribute('cmpd', 'sng'); + $objWriter->writeAttribute('algn', 'ctr'); + + // a:solidFill + $objWriter->startElement('a:solidFill'); + + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:prstDash + $objWriter->startElement('a:prstDash'); + $objWriter->writeAttribute('val', 'solid'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + + + // a:effectStyleLst + $objWriter->startElement('a:effectStyleLst'); + + // a:effectStyle + $objWriter->startElement('a:effectStyle'); + + // a:effectLst + $objWriter->startElement('a:effectLst'); + + // a:outerShdw + $objWriter->startElement('a:outerShdw'); + $objWriter->writeAttribute('blurRad', '40000'); + $objWriter->writeAttribute('dist', '20000'); + $objWriter->writeAttribute('dir', '5400000'); + $objWriter->writeAttribute('rotWithShape', '0'); + + // a:srgbClr + $objWriter->startElement('a:srgbClr'); + $objWriter->writeAttribute('val', '000000'); + + // a:alpha + $objWriter->startElement('a:alpha'); + $objWriter->writeAttribute('val', '38000'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:effectStyle + $objWriter->startElement('a:effectStyle'); + + // a:effectLst + $objWriter->startElement('a:effectLst'); + + // a:outerShdw + $objWriter->startElement('a:outerShdw'); + $objWriter->writeAttribute('blurRad', '40000'); + $objWriter->writeAttribute('dist', '23000'); + $objWriter->writeAttribute('dir', '5400000'); + $objWriter->writeAttribute('rotWithShape', '0'); + + // a:srgbClr + $objWriter->startElement('a:srgbClr'); + $objWriter->writeAttribute('val', '000000'); + + // a:alpha + $objWriter->startElement('a:alpha'); + $objWriter->writeAttribute('val', '35000'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:effectStyle + $objWriter->startElement('a:effectStyle'); + + // a:effectLst + $objWriter->startElement('a:effectLst'); + + // a:outerShdw + $objWriter->startElement('a:outerShdw'); + $objWriter->writeAttribute('blurRad', '40000'); + $objWriter->writeAttribute('dist', '23000'); + $objWriter->writeAttribute('dir', '5400000'); + $objWriter->writeAttribute('rotWithShape', '0'); + + // a:srgbClr + $objWriter->startElement('a:srgbClr'); + $objWriter->writeAttribute('val', '000000'); + + // a:alpha + $objWriter->startElement('a:alpha'); + $objWriter->writeAttribute('val', '35000'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:scene3d + $objWriter->startElement('a:scene3d'); + + // a:camera + $objWriter->startElement('a:camera'); + $objWriter->writeAttribute('prst', 'orthographicFront'); + + // a:rot + $objWriter->startElement('a:rot'); + $objWriter->writeAttribute('lat', '0'); + $objWriter->writeAttribute('lon', '0'); + $objWriter->writeAttribute('rev', '0'); + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:lightRig + $objWriter->startElement('a:lightRig'); + $objWriter->writeAttribute('rig', 'threePt'); + $objWriter->writeAttribute('dir', 't'); + + // a:rot + $objWriter->startElement('a:rot'); + $objWriter->writeAttribute('lat', '0'); + $objWriter->writeAttribute('lon', '0'); + $objWriter->writeAttribute('rev', '1200000'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:sp3d + $objWriter->startElement('a:sp3d'); + + // a:bevelT + $objWriter->startElement('a:bevelT'); + $objWriter->writeAttribute('w', '63500'); + $objWriter->writeAttribute('h', '25400'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:bgFillStyleLst + $objWriter->startElement('a:bgFillStyleLst'); + + // a:solidFill + $objWriter->startElement('a:solidFill'); + + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:gradFill + $objWriter->startElement('a:gradFill'); + $objWriter->writeAttribute('rotWithShape', '1'); + + // a:gsLst + $objWriter->startElement('a:gsLst'); + + // a:gs + $objWriter->startElement('a:gs'); + $objWriter->writeAttribute('pos', '0'); + + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); + + // a:tint + $objWriter->startElement('a:tint'); + $objWriter->writeAttribute('val', '40000'); + $objWriter->endElement(); + + // a:satMod + $objWriter->startElement('a:satMod'); + $objWriter->writeAttribute('val', '350000'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:gs + $objWriter->startElement('a:gs'); + $objWriter->writeAttribute('pos', '40000'); + + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); + + // a:tint + $objWriter->startElement('a:tint'); + $objWriter->writeAttribute('val', '45000'); + $objWriter->endElement(); + + // a:shade + $objWriter->startElement('a:shade'); + $objWriter->writeAttribute('val', '99000'); + $objWriter->endElement(); + + // a:satMod + $objWriter->startElement('a:satMod'); + $objWriter->writeAttribute('val', '350000'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:gs + $objWriter->startElement('a:gs'); + $objWriter->writeAttribute('pos', '100000'); + + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); + + // a:shade + $objWriter->startElement('a:shade'); + $objWriter->writeAttribute('val', '20000'); + $objWriter->endElement(); + + // a:satMod + $objWriter->startElement('a:satMod'); + $objWriter->writeAttribute('val', '255000'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:path + $objWriter->startElement('a:path'); + $objWriter->writeAttribute('path', 'circle'); + + // a:fillToRect + $objWriter->startElement('a:fillToRect'); + $objWriter->writeAttribute('l', '50000'); + $objWriter->writeAttribute('t', '-80000'); + $objWriter->writeAttribute('r', '50000'); + $objWriter->writeAttribute('b', '180000'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:gradFill + $objWriter->startElement('a:gradFill'); + $objWriter->writeAttribute('rotWithShape', '1'); + + // a:gsLst + $objWriter->startElement('a:gsLst'); + + // a:gs + $objWriter->startElement('a:gs'); + $objWriter->writeAttribute('pos', '0'); + + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); + + // a:tint + $objWriter->startElement('a:tint'); + $objWriter->writeAttribute('val', '80000'); + $objWriter->endElement(); + + // a:satMod + $objWriter->startElement('a:satMod'); + $objWriter->writeAttribute('val', '300000'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:gs + $objWriter->startElement('a:gs'); + $objWriter->writeAttribute('pos', '100000'); + + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); + + // a:shade + $objWriter->startElement('a:shade'); + $objWriter->writeAttribute('val', '30000'); + $objWriter->endElement(); + + // a:satMod + $objWriter->startElement('a:satMod'); + $objWriter->writeAttribute('val', '200000'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:path + $objWriter->startElement('a:path'); + $objWriter->writeAttribute('path', 'circle'); + + // a:fillToRect + $objWriter->startElement('a:fillToRect'); + $objWriter->writeAttribute('l', '50000'); + $objWriter->writeAttribute('t', '50000'); + $objWriter->writeAttribute('r', '50000'); + $objWriter->writeAttribute('b', '50000'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:objectDefaults + $objWriter->writeElement('a:objectDefaults', null); + + // a:extraClrSchemeLst + $objWriter->writeElement('a:extraClrSchemeLst', null); + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + /** + * Write fonts to XML format + * + * @param PHPExcel_Shared_XMLWriter $objWriter + * @param string $latinFont + * @param array of string $fontSet + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + private function _writeFonts($objWriter, $latinFont, $fontSet) + { + // a:latin + $objWriter->startElement('a:latin'); + $objWriter->writeAttribute('typeface', $latinFont); + $objWriter->endElement(); + + // a:ea + $objWriter->startElement('a:ea'); + $objWriter->writeAttribute('typeface', ''); + $objWriter->endElement(); + + // a:cs + $objWriter->startElement('a:cs'); + $objWriter->writeAttribute('typeface', ''); + $objWriter->endElement(); + + foreach($fontSet as $fontScript => $typeface) { + $objWriter->startElement('a:font'); + $objWriter->writeAttribute('script', $fontScript); + $objWriter->writeAttribute('typeface', $typeface); + $objWriter->endElement(); + } + + } + + /** + * Write colour scheme to XML format + * + * @param PHPExcel_Shared_XMLWriter $objWriter + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + private function _writeColourScheme($objWriter) + { + foreach(self::$_colourScheme as $colourName => $colourValue) { + $objWriter->startElement('a:'.$colourName); + + $objWriter->startElement('a:srgbClr'); + $objWriter->writeAttribute('val', $colourValue); + $objWriter->endElement(); + + $objWriter->endElement(); + } + + } +} diff --git a/lib/phpexcel/PHPExcel/Writer/Excel2007/Workbook.php b/lib/phpexcel/PHPExcel/Writer/Excel2007/Workbook.php new file mode 100644 index 0000000..d1fe666 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Writer/Excel2007/Workbook.php @@ -0,0 +1,456 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Writer_Excel2007_Workbook + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_Excel2007_Workbook extends PHPExcel_Writer_Excel2007_WriterPart +{ + /** + * Write workbook to XML format + * + * @param PHPExcel $pPHPExcel + * @param boolean $recalcRequired Indicate whether formulas should be recalculated before writing + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeWorkbook(PHPExcel $pPHPExcel = null, $recalcRequired = FALSE) + { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // workbook + $objWriter->startElement('workbook'); + $objWriter->writeAttribute('xml:space', 'preserve'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'); + $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'); + + // fileVersion + $this->_writeFileVersion($objWriter); + + // workbookPr + $this->_writeWorkbookPr($objWriter); + + // workbookProtection + $this->_writeWorkbookProtection($objWriter, $pPHPExcel); + + // bookViews + if ($this->getParentWriter()->getOffice2003Compatibility() === false) { + $this->_writeBookViews($objWriter, $pPHPExcel); + } + + // sheets + $this->_writeSheets($objWriter, $pPHPExcel); + + // definedNames + $this->_writeDefinedNames($objWriter, $pPHPExcel); + + // calcPr + $this->_writeCalcPr($objWriter,$recalcRequired); + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + /** + * Write file version + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @throws PHPExcel_Writer_Exception + */ + private function _writeFileVersion(PHPExcel_Shared_XMLWriter $objWriter = null) + { + $objWriter->startElement('fileVersion'); + $objWriter->writeAttribute('appName', 'xl'); + $objWriter->writeAttribute('lastEdited', '4'); + $objWriter->writeAttribute('lowestEdited', '4'); + $objWriter->writeAttribute('rupBuild', '4505'); + $objWriter->endElement(); + } + + /** + * Write WorkbookPr + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @throws PHPExcel_Writer_Exception + */ + private function _writeWorkbookPr(PHPExcel_Shared_XMLWriter $objWriter = null) + { + $objWriter->startElement('workbookPr'); + + if (PHPExcel_Shared_Date::getExcelCalendar() == PHPExcel_Shared_Date::CALENDAR_MAC_1904) { + $objWriter->writeAttribute('date1904', '1'); + } + + $objWriter->writeAttribute('codeName', 'ThisWorkbook'); + + $objWriter->endElement(); + } + + /** + * Write BookViews + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel $pPHPExcel + * @throws PHPExcel_Writer_Exception + */ + private function _writeBookViews(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel $pPHPExcel = null) + { + // bookViews + $objWriter->startElement('bookViews'); + + // workbookView + $objWriter->startElement('workbookView'); + + $objWriter->writeAttribute('activeTab', $pPHPExcel->getActiveSheetIndex()); + $objWriter->writeAttribute('autoFilterDateGrouping', '1'); + $objWriter->writeAttribute('firstSheet', '0'); + $objWriter->writeAttribute('minimized', '0'); + $objWriter->writeAttribute('showHorizontalScroll', '1'); + $objWriter->writeAttribute('showSheetTabs', '1'); + $objWriter->writeAttribute('showVerticalScroll', '1'); + $objWriter->writeAttribute('tabRatio', '600'); + $objWriter->writeAttribute('visibility', 'visible'); + + $objWriter->endElement(); + + $objWriter->endElement(); + } + + /** + * Write WorkbookProtection + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel $pPHPExcel + * @throws PHPExcel_Writer_Exception + */ + private function _writeWorkbookProtection(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel $pPHPExcel = null) + { + if ($pPHPExcel->getSecurity()->isSecurityEnabled()) { + $objWriter->startElement('workbookProtection'); + $objWriter->writeAttribute('lockRevision', ($pPHPExcel->getSecurity()->getLockRevision() ? 'true' : 'false')); + $objWriter->writeAttribute('lockStructure', ($pPHPExcel->getSecurity()->getLockStructure() ? 'true' : 'false')); + $objWriter->writeAttribute('lockWindows', ($pPHPExcel->getSecurity()->getLockWindows() ? 'true' : 'false')); + + if ($pPHPExcel->getSecurity()->getRevisionsPassword() != '') { + $objWriter->writeAttribute('revisionsPassword', $pPHPExcel->getSecurity()->getRevisionsPassword()); + } + + if ($pPHPExcel->getSecurity()->getWorkbookPassword() != '') { + $objWriter->writeAttribute('workbookPassword', $pPHPExcel->getSecurity()->getWorkbookPassword()); + } + + $objWriter->endElement(); + } + } + + /** + * Write calcPr + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param boolean $recalcRequired Indicate whether formulas should be recalculated before writing + * @throws PHPExcel_Writer_Exception + */ + private function _writeCalcPr(PHPExcel_Shared_XMLWriter $objWriter = null, $recalcRequired = TRUE) + { + $objWriter->startElement('calcPr'); + + // Set the calcid to a higher value than Excel itself will use, otherwise Excel will always recalc + // If MS Excel does do a recalc, then users opening a file in MS Excel will be prompted to save on exit + // because the file has changed + $objWriter->writeAttribute('calcId', '999999'); + $objWriter->writeAttribute('calcMode', 'auto'); + // fullCalcOnLoad isn't needed if we've recalculating for the save + $objWriter->writeAttribute('calcCompleted', ($recalcRequired) ? 1 : 0); + $objWriter->writeAttribute('fullCalcOnLoad', ($recalcRequired) ? 0 : 1); + + $objWriter->endElement(); + } + + /** + * Write sheets + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel $pPHPExcel + * @throws PHPExcel_Writer_Exception + */ + private function _writeSheets(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel $pPHPExcel = null) + { + // Write sheets + $objWriter->startElement('sheets'); + $sheetCount = $pPHPExcel->getSheetCount(); + for ($i = 0; $i < $sheetCount; ++$i) { + // sheet + $this->_writeSheet( + $objWriter, + $pPHPExcel->getSheet($i)->getTitle(), + ($i + 1), + ($i + 1 + 3), + $pPHPExcel->getSheet($i)->getSheetState() + ); + } + + $objWriter->endElement(); + } + + /** + * Write sheet + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param string $pSheetname Sheet name + * @param int $pSheetId Sheet id + * @param int $pRelId Relationship ID + * @param string $sheetState Sheet state (visible, hidden, veryHidden) + * @throws PHPExcel_Writer_Exception + */ + private function _writeSheet(PHPExcel_Shared_XMLWriter $objWriter = null, $pSheetname = '', $pSheetId = 1, $pRelId = 1, $sheetState = 'visible') + { + if ($pSheetname != '') { + // Write sheet + $objWriter->startElement('sheet'); + $objWriter->writeAttribute('name', $pSheetname); + $objWriter->writeAttribute('sheetId', $pSheetId); + if ($sheetState != 'visible' && $sheetState != '') { + $objWriter->writeAttribute('state', $sheetState); + } + $objWriter->writeAttribute('r:id', 'rId' . $pRelId); + $objWriter->endElement(); + } else { + throw new PHPExcel_Writer_Exception("Invalid parameters passed."); + } + } + + /** + * Write Defined Names + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel $pPHPExcel + * @throws PHPExcel_Writer_Exception + */ + private function _writeDefinedNames(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel $pPHPExcel = null) + { + // Write defined names + $objWriter->startElement('definedNames'); + + // Named ranges + if (count($pPHPExcel->getNamedRanges()) > 0) { + // Named ranges + $this->_writeNamedRanges($objWriter, $pPHPExcel); + } + + // Other defined names + $sheetCount = $pPHPExcel->getSheetCount(); + for ($i = 0; $i < $sheetCount; ++$i) { + // definedName for autoFilter + $this->_writeDefinedNameForAutofilter($objWriter, $pPHPExcel->getSheet($i), $i); + + // definedName for Print_Titles + $this->_writeDefinedNameForPrintTitles($objWriter, $pPHPExcel->getSheet($i), $i); + + // definedName for Print_Area + $this->_writeDefinedNameForPrintArea($objWriter, $pPHPExcel->getSheet($i), $i); + } + + $objWriter->endElement(); + } + + /** + * Write named ranges + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel $pPHPExcel + * @throws PHPExcel_Writer_Exception + */ + private function _writeNamedRanges(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel $pPHPExcel) + { + // Loop named ranges + $namedRanges = $pPHPExcel->getNamedRanges(); + foreach ($namedRanges as $namedRange) { + $this->_writeDefinedNameForNamedRange($objWriter, $namedRange); + } + } + + /** + * Write Defined Name for named range + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_NamedRange $pNamedRange + * @throws PHPExcel_Writer_Exception + */ + private function _writeDefinedNameForNamedRange(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_NamedRange $pNamedRange) + { + // definedName for named range + $objWriter->startElement('definedName'); + $objWriter->writeAttribute('name', $pNamedRange->getName()); + if ($pNamedRange->getLocalOnly()) { + $objWriter->writeAttribute('localSheetId', $pNamedRange->getScope()->getParent()->getIndex($pNamedRange->getScope())); + } + + // Create absolute coordinate and write as raw text + $range = PHPExcel_Cell::splitRange($pNamedRange->getRange()); + for ($i = 0; $i < count($range); $i++) { + $range[$i][0] = '\'' . str_replace("'", "''", $pNamedRange->getWorksheet()->getTitle()) . '\'!' . PHPExcel_Cell::absoluteReference($range[$i][0]); + if (isset($range[$i][1])) { + $range[$i][1] = PHPExcel_Cell::absoluteReference($range[$i][1]); + } + } + $range = PHPExcel_Cell::buildRange($range); + + $objWriter->writeRawData($range); + + $objWriter->endElement(); + } + + /** + * Write Defined Name for autoFilter + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet + * @param int $pSheetId + * @throws PHPExcel_Writer_Exception + */ + private function _writeDefinedNameForAutofilter(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pSheetId = 0) + { + // definedName for autoFilter + $autoFilterRange = $pSheet->getAutoFilter()->getRange(); + if (!empty($autoFilterRange)) { + $objWriter->startElement('definedName'); + $objWriter->writeAttribute('name', '_xlnm._FilterDatabase'); + $objWriter->writeAttribute('localSheetId', $pSheetId); + $objWriter->writeAttribute('hidden', '1'); + + // Create absolute coordinate and write as raw text + $range = PHPExcel_Cell::splitRange($autoFilterRange); + $range = $range[0]; + // Strip any worksheet ref so we can make the cell ref absolute + if (strpos($range[0],'!') !== false) { + list($ws,$range[0]) = explode('!',$range[0]); + } + + $range[0] = PHPExcel_Cell::absoluteCoordinate($range[0]); + $range[1] = PHPExcel_Cell::absoluteCoordinate($range[1]); + $range = implode(':', $range); + + $objWriter->writeRawData('\'' . str_replace("'", "''", $pSheet->getTitle()) . '\'!' . $range); + + $objWriter->endElement(); + } + } + + /** + * Write Defined Name for PrintTitles + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet + * @param int $pSheetId + * @throws PHPExcel_Writer_Exception + */ + private function _writeDefinedNameForPrintTitles(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pSheetId = 0) + { + // definedName for PrintTitles + if ($pSheet->getPageSetup()->isColumnsToRepeatAtLeftSet() || $pSheet->getPageSetup()->isRowsToRepeatAtTopSet()) { + $objWriter->startElement('definedName'); + $objWriter->writeAttribute('name', '_xlnm.Print_Titles'); + $objWriter->writeAttribute('localSheetId', $pSheetId); + + // Setting string + $settingString = ''; + + // Columns to repeat + if ($pSheet->getPageSetup()->isColumnsToRepeatAtLeftSet()) { + $repeat = $pSheet->getPageSetup()->getColumnsToRepeatAtLeft(); + + $settingString .= '\'' . str_replace("'", "''", $pSheet->getTitle()) . '\'!$' . $repeat[0] . ':$' . $repeat[1]; + } + + // Rows to repeat + if ($pSheet->getPageSetup()->isRowsToRepeatAtTopSet()) { + if ($pSheet->getPageSetup()->isColumnsToRepeatAtLeftSet()) { + $settingString .= ','; + } + + $repeat = $pSheet->getPageSetup()->getRowsToRepeatAtTop(); + + $settingString .= '\'' . str_replace("'", "''", $pSheet->getTitle()) . '\'!$' . $repeat[0] . ':$' . $repeat[1]; + } + + $objWriter->writeRawData($settingString); + + $objWriter->endElement(); + } + } + + /** + * Write Defined Name for PrintTitles + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet + * @param int $pSheetId + * @throws PHPExcel_Writer_Exception + */ + private function _writeDefinedNameForPrintArea(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pSheetId = 0) + { + // definedName for PrintArea + if ($pSheet->getPageSetup()->isPrintAreaSet()) { + $objWriter->startElement('definedName'); + $objWriter->writeAttribute('name', '_xlnm.Print_Area'); + $objWriter->writeAttribute('localSheetId', $pSheetId); + + // Setting string + $settingString = ''; + + // Print area + $printArea = PHPExcel_Cell::splitRange($pSheet->getPageSetup()->getPrintArea()); + + $chunks = array(); + foreach ($printArea as $printAreaRect) { + $printAreaRect[0] = PHPExcel_Cell::absoluteReference($printAreaRect[0]); + $printAreaRect[1] = PHPExcel_Cell::absoluteReference($printAreaRect[1]); + $chunks[] = '\'' . str_replace("'", "''", $pSheet->getTitle()) . '\'!' . implode(':', $printAreaRect); + } + + $objWriter->writeRawData(implode(',', $chunks)); + + $objWriter->endElement(); + } + } +} diff --git a/lib/phpexcel/PHPExcel/Writer/Excel2007/Worksheet.php b/lib/phpexcel/PHPExcel/Writer/Excel2007/Worksheet.php new file mode 100644 index 0000000..7d93f5a --- /dev/null +++ b/lib/phpexcel/PHPExcel/Writer/Excel2007/Worksheet.php @@ -0,0 +1,1220 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Writer_Excel2007_Worksheet + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_Excel2007_Worksheet extends PHPExcel_Writer_Excel2007_WriterPart +{ + /** + * Write worksheet to XML format + * + * @param PHPExcel_Worksheet $pSheet + * @param string[] $pStringTable + * @param boolean $includeCharts Flag indicating if we should write charts + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeWorksheet($pSheet = null, $pStringTable = null, $includeCharts = FALSE) + { + if (!is_null($pSheet)) { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // Worksheet + $objWriter->startElement('worksheet'); + $objWriter->writeAttribute('xml:space', 'preserve'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'); + $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'); + + // sheetPr + $this->_writeSheetPr($objWriter, $pSheet); + + // Dimension + $this->_writeDimension($objWriter, $pSheet); + + // sheetViews + $this->_writeSheetViews($objWriter, $pSheet); + + // sheetFormatPr + $this->_writeSheetFormatPr($objWriter, $pSheet); + + // cols + $this->_writeCols($objWriter, $pSheet); + + // sheetData + $this->_writeSheetData($objWriter, $pSheet, $pStringTable); + + // sheetProtection + $this->_writeSheetProtection($objWriter, $pSheet); + + // protectedRanges + $this->_writeProtectedRanges($objWriter, $pSheet); + + // autoFilter + $this->_writeAutoFilter($objWriter, $pSheet); + + // mergeCells + $this->_writeMergeCells($objWriter, $pSheet); + + // conditionalFormatting + $this->_writeConditionalFormatting($objWriter, $pSheet); + + // dataValidations + $this->_writeDataValidations($objWriter, $pSheet); + + // hyperlinks + $this->_writeHyperlinks($objWriter, $pSheet); + + // Print options + $this->_writePrintOptions($objWriter, $pSheet); + + // Page margins + $this->_writePageMargins($objWriter, $pSheet); + + // Page setup + $this->_writePageSetup($objWriter, $pSheet); + + // Header / footer + $this->_writeHeaderFooter($objWriter, $pSheet); + + // Breaks + $this->_writeBreaks($objWriter, $pSheet); + + // Drawings and/or Charts + $this->_writeDrawings($objWriter, $pSheet, $includeCharts); + + // LegacyDrawing + $this->_writeLegacyDrawing($objWriter, $pSheet); + + // LegacyDrawingHF + $this->_writeLegacyDrawingHF($objWriter, $pSheet); + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } else { + throw new PHPExcel_Writer_Exception("Invalid PHPExcel_Worksheet object passed."); + } + } + + /** + * Write SheetPr + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writeSheetPr(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + // sheetPr + $objWriter->startElement('sheetPr'); + //$objWriter->writeAttribute('codeName', $pSheet->getTitle()); + if($pSheet->getParent()->hasMacros()){//if the workbook have macros, we need to have codeName for the sheet + if($pSheet->hasCodeName()==false){ + $pSheet->setCodeName($pSheet->getTitle()); + } + $objWriter->writeAttribute('codeName', $pSheet->getCodeName()); + } + $autoFilterRange = $pSheet->getAutoFilter()->getRange(); + if (!empty($autoFilterRange)) { + $objWriter->writeAttribute('filterMode', 1); + $pSheet->getAutoFilter()->showHideRows(); + } + + // tabColor + if ($pSheet->isTabColorSet()) { + $objWriter->startElement('tabColor'); + $objWriter->writeAttribute('rgb', $pSheet->getTabColor()->getARGB()); + $objWriter->endElement(); + } + + // outlinePr + $objWriter->startElement('outlinePr'); + $objWriter->writeAttribute('summaryBelow', ($pSheet->getShowSummaryBelow() ? '1' : '0')); + $objWriter->writeAttribute('summaryRight', ($pSheet->getShowSummaryRight() ? '1' : '0')); + $objWriter->endElement(); + + // pageSetUpPr + if ($pSheet->getPageSetup()->getFitToPage()) { + $objWriter->startElement('pageSetUpPr'); + $objWriter->writeAttribute('fitToPage', '1'); + $objWriter->endElement(); + } + + $objWriter->endElement(); + } + + /** + * Write Dimension + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writeDimension(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + // dimension + $objWriter->startElement('dimension'); + $objWriter->writeAttribute('ref', $pSheet->calculateWorksheetDimension()); + $objWriter->endElement(); + } + + /** + * Write SheetViews + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writeSheetViews(PHPExcel_Shared_XMLWriter $objWriter = NULL, PHPExcel_Worksheet $pSheet = NULL) + { + // sheetViews + $objWriter->startElement('sheetViews'); + + // Sheet selected? + $sheetSelected = false; + if ($this->getParentWriter()->getPHPExcel()->getIndex($pSheet) == $this->getParentWriter()->getPHPExcel()->getActiveSheetIndex()) + $sheetSelected = true; + + + // sheetView + $objWriter->startElement('sheetView'); + $objWriter->writeAttribute('tabSelected', $sheetSelected ? '1' : '0'); + $objWriter->writeAttribute('workbookViewId', '0'); + + // Zoom scales + if ($pSheet->getSheetView()->getZoomScale() != 100) { + $objWriter->writeAttribute('zoomScale', $pSheet->getSheetView()->getZoomScale()); + } + if ($pSheet->getSheetView()->getZoomScaleNormal() != 100) { + $objWriter->writeAttribute('zoomScaleNormal', $pSheet->getSheetView()->getZoomScaleNormal()); + } + + // View Layout Type + if ($pSheet->getSheetView()->getView() !== PHPExcel_Worksheet_SheetView::SHEETVIEW_NORMAL) { + $objWriter->writeAttribute('view', $pSheet->getSheetView()->getView()); + } + + // Gridlines + if ($pSheet->getShowGridlines()) { + $objWriter->writeAttribute('showGridLines', 'true'); + } else { + $objWriter->writeAttribute('showGridLines', 'false'); + } + + // Row and column headers + if ($pSheet->getShowRowColHeaders()) { + $objWriter->writeAttribute('showRowColHeaders', '1'); + } else { + $objWriter->writeAttribute('showRowColHeaders', '0'); + } + + // Right-to-left + if ($pSheet->getRightToLeft()) { + $objWriter->writeAttribute('rightToLeft', 'true'); + } + + $activeCell = $pSheet->getActiveCell(); + + // Pane + $pane = ''; + $topLeftCell = $pSheet->getFreezePane(); + if (($topLeftCell != '') && ($topLeftCell != 'A1')) { + $activeCell = $topLeftCell; + // Calculate freeze coordinates + $xSplit = $ySplit = 0; + + list($xSplit, $ySplit) = PHPExcel_Cell::coordinateFromString($topLeftCell); + $xSplit = PHPExcel_Cell::columnIndexFromString($xSplit); + + // pane + $pane = 'topRight'; + $objWriter->startElement('pane'); + if ($xSplit > 1) + $objWriter->writeAttribute('xSplit', $xSplit - 1); + if ($ySplit > 1) { + $objWriter->writeAttribute('ySplit', $ySplit - 1); + $pane = ($xSplit > 1) ? 'bottomRight' : 'bottomLeft'; + } + $objWriter->writeAttribute('topLeftCell', $topLeftCell); + $objWriter->writeAttribute('activePane', $pane); + $objWriter->writeAttribute('state', 'frozen'); + $objWriter->endElement(); + + if (($xSplit > 1) && ($ySplit > 1)) { + // Write additional selections if more than two panes (ie both an X and a Y split) + $objWriter->startElement('selection'); $objWriter->writeAttribute('pane', 'topRight'); $objWriter->endElement(); + $objWriter->startElement('selection'); $objWriter->writeAttribute('pane', 'bottomLeft'); $objWriter->endElement(); + } + } + + // Selection +// if ($pane != '') { + // Only need to write selection element if we have a split pane + // We cheat a little by over-riding the active cell selection, setting it to the split cell + $objWriter->startElement('selection'); + if ($pane != '') { + $objWriter->writeAttribute('pane', $pane); + } + $objWriter->writeAttribute('activeCell', $activeCell); + $objWriter->writeAttribute('sqref', $activeCell); + $objWriter->endElement(); +// } + + $objWriter->endElement(); + + $objWriter->endElement(); + } + + /** + * Write SheetFormatPr + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writeSheetFormatPr(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + // sheetFormatPr + $objWriter->startElement('sheetFormatPr'); + + // Default row height + if ($pSheet->getDefaultRowDimension()->getRowHeight() >= 0) { + $objWriter->writeAttribute('customHeight', 'true'); + $objWriter->writeAttribute('defaultRowHeight', PHPExcel_Shared_String::FormatNumber($pSheet->getDefaultRowDimension()->getRowHeight())); + } else { + $objWriter->writeAttribute('defaultRowHeight', '14.4'); + } + + // Set Zero Height row + if ((string)$pSheet->getDefaultRowDimension()->getzeroHeight() == '1' || + strtolower((string)$pSheet->getDefaultRowDimension()->getzeroHeight()) == 'true' ) { + $objWriter->writeAttribute('zeroHeight', '1'); + } + + // Default column width + if ($pSheet->getDefaultColumnDimension()->getWidth() >= 0) { + $objWriter->writeAttribute('defaultColWidth', PHPExcel_Shared_String::FormatNumber($pSheet->getDefaultColumnDimension()->getWidth())); + } + + // Outline level - row + $outlineLevelRow = 0; + foreach ($pSheet->getRowDimensions() as $dimension) { + if ($dimension->getOutlineLevel() > $outlineLevelRow) { + $outlineLevelRow = $dimension->getOutlineLevel(); + } + } + $objWriter->writeAttribute('outlineLevelRow', (int)$outlineLevelRow); + + // Outline level - column + $outlineLevelCol = 0; + foreach ($pSheet->getColumnDimensions() as $dimension) { + if ($dimension->getOutlineLevel() > $outlineLevelCol) { + $outlineLevelCol = $dimension->getOutlineLevel(); + } + } + $objWriter->writeAttribute('outlineLevelCol', (int)$outlineLevelCol); + + $objWriter->endElement(); + } + + /** + * Write Cols + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writeCols(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + // cols + if (count($pSheet->getColumnDimensions()) > 0) { + $objWriter->startElement('cols'); + + $pSheet->calculateColumnWidths(); + + // Loop through column dimensions + foreach ($pSheet->getColumnDimensions() as $colDimension) { + // col + $objWriter->startElement('col'); + $objWriter->writeAttribute('min', PHPExcel_Cell::columnIndexFromString($colDimension->getColumnIndex())); + $objWriter->writeAttribute('max', PHPExcel_Cell::columnIndexFromString($colDimension->getColumnIndex())); + + if ($colDimension->getWidth() < 0) { + // No width set, apply default of 10 + $objWriter->writeAttribute('width', '9.10'); + } else { + // Width set + $objWriter->writeAttribute('width', PHPExcel_Shared_String::FormatNumber($colDimension->getWidth())); + } + + // Column visibility + if ($colDimension->getVisible() == false) { + $objWriter->writeAttribute('hidden', 'true'); + } + + // Auto size? + if ($colDimension->getAutoSize()) { + $objWriter->writeAttribute('bestFit', 'true'); + } + + // Custom width? + if ($colDimension->getWidth() != $pSheet->getDefaultColumnDimension()->getWidth()) { + $objWriter->writeAttribute('customWidth', 'true'); + } + + // Collapsed + if ($colDimension->getCollapsed() == true) { + $objWriter->writeAttribute('collapsed', 'true'); + } + + // Outline level + if ($colDimension->getOutlineLevel() > 0) { + $objWriter->writeAttribute('outlineLevel', $colDimension->getOutlineLevel()); + } + + // Style + $objWriter->writeAttribute('style', $colDimension->getXfIndex()); + + $objWriter->endElement(); + } + + $objWriter->endElement(); + } + } + + /** + * Write SheetProtection + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writeSheetProtection(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + // sheetProtection + $objWriter->startElement('sheetProtection'); + + if ($pSheet->getProtection()->getPassword() != '') { + $objWriter->writeAttribute('password', $pSheet->getProtection()->getPassword()); + } + + $objWriter->writeAttribute('sheet', ($pSheet->getProtection()->getSheet() ? 'true' : 'false')); + $objWriter->writeAttribute('objects', ($pSheet->getProtection()->getObjects() ? 'true' : 'false')); + $objWriter->writeAttribute('scenarios', ($pSheet->getProtection()->getScenarios() ? 'true' : 'false')); + $objWriter->writeAttribute('formatCells', ($pSheet->getProtection()->getFormatCells() ? 'true' : 'false')); + $objWriter->writeAttribute('formatColumns', ($pSheet->getProtection()->getFormatColumns() ? 'true' : 'false')); + $objWriter->writeAttribute('formatRows', ($pSheet->getProtection()->getFormatRows() ? 'true' : 'false')); + $objWriter->writeAttribute('insertColumns', ($pSheet->getProtection()->getInsertColumns() ? 'true' : 'false')); + $objWriter->writeAttribute('insertRows', ($pSheet->getProtection()->getInsertRows() ? 'true' : 'false')); + $objWriter->writeAttribute('insertHyperlinks', ($pSheet->getProtection()->getInsertHyperlinks() ? 'true' : 'false')); + $objWriter->writeAttribute('deleteColumns', ($pSheet->getProtection()->getDeleteColumns() ? 'true' : 'false')); + $objWriter->writeAttribute('deleteRows', ($pSheet->getProtection()->getDeleteRows() ? 'true' : 'false')); + $objWriter->writeAttribute('selectLockedCells', ($pSheet->getProtection()->getSelectLockedCells() ? 'true' : 'false')); + $objWriter->writeAttribute('sort', ($pSheet->getProtection()->getSort() ? 'true' : 'false')); + $objWriter->writeAttribute('autoFilter', ($pSheet->getProtection()->getAutoFilter() ? 'true' : 'false')); + $objWriter->writeAttribute('pivotTables', ($pSheet->getProtection()->getPivotTables() ? 'true' : 'false')); + $objWriter->writeAttribute('selectUnlockedCells', ($pSheet->getProtection()->getSelectUnlockedCells() ? 'true' : 'false')); + $objWriter->endElement(); + } + + /** + * Write ConditionalFormatting + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writeConditionalFormatting(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + // Conditional id + $id = 1; + + // Loop through styles in the current worksheet + foreach ($pSheet->getConditionalStylesCollection() as $cellCoordinate => $conditionalStyles) { + foreach ($conditionalStyles as $conditional) { + // WHY was this again? + // if ($this->getParentWriter()->getStylesConditionalHashTable()->getIndexForHashCode( $conditional->getHashCode() ) == '') { + // continue; + // } + if ($conditional->getConditionType() != PHPExcel_Style_Conditional::CONDITION_NONE) { + // conditionalFormatting + $objWriter->startElement('conditionalFormatting'); + $objWriter->writeAttribute('sqref', $cellCoordinate); + + // cfRule + $objWriter->startElement('cfRule'); + $objWriter->writeAttribute('type', $conditional->getConditionType()); + $objWriter->writeAttribute('dxfId', $this->getParentWriter()->getStylesConditionalHashTable()->getIndexForHashCode( $conditional->getHashCode() )); + $objWriter->writeAttribute('priority', $id++); + + if (($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS + || + $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT) + && $conditional->getOperatorType() != PHPExcel_Style_Conditional::OPERATOR_NONE) { + $objWriter->writeAttribute('operator', $conditional->getOperatorType()); + } + + if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT + && !is_null($conditional->getText())) { + $objWriter->writeAttribute('text', $conditional->getText()); + } + + if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT + && $conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_CONTAINSTEXT + && !is_null($conditional->getText())) { + $objWriter->writeElement('formula', 'NOT(ISERROR(SEARCH("' . $conditional->getText() . '",' . $cellCoordinate . ')))'); + } else if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT + && $conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_BEGINSWITH + && !is_null($conditional->getText())) { + $objWriter->writeElement('formula', 'LEFT(' . $cellCoordinate . ',' . strlen($conditional->getText()) . ')="' . $conditional->getText() . '"'); + } else if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT + && $conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_ENDSWITH + && !is_null($conditional->getText())) { + $objWriter->writeElement('formula', 'RIGHT(' . $cellCoordinate . ',' . strlen($conditional->getText()) . ')="' . $conditional->getText() . '"'); + } else if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT + && $conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_NOTCONTAINS + && !is_null($conditional->getText())) { + $objWriter->writeElement('formula', 'ISERROR(SEARCH("' . $conditional->getText() . '",' . $cellCoordinate . '))'); + } else if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS + || $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT + || $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_EXPRESSION) { + foreach ($conditional->getConditions() as $formula) { + // Formula + $objWriter->writeElement('formula', $formula); + } + } + + $objWriter->endElement(); + + $objWriter->endElement(); + } + } + } + } + + /** + * Write DataValidations + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writeDataValidations(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + // Datavalidation collection + $dataValidationCollection = $pSheet->getDataValidationCollection(); + + // Write data validations? + if (!empty($dataValidationCollection)) { + $objWriter->startElement('dataValidations'); + $objWriter->writeAttribute('count', count($dataValidationCollection)); + + foreach ($dataValidationCollection as $coordinate => $dv) { + $objWriter->startElement('dataValidation'); + + if ($dv->getType() != '') { + $objWriter->writeAttribute('type', $dv->getType()); + } + + if ($dv->getErrorStyle() != '') { + $objWriter->writeAttribute('errorStyle', $dv->getErrorStyle()); + } + + if ($dv->getOperator() != '') { + $objWriter->writeAttribute('operator', $dv->getOperator()); + } + + $objWriter->writeAttribute('allowBlank', ($dv->getAllowBlank() ? '1' : '0')); + $objWriter->writeAttribute('showDropDown', (!$dv->getShowDropDown() ? '1' : '0')); + $objWriter->writeAttribute('showInputMessage', ($dv->getShowInputMessage() ? '1' : '0')); + $objWriter->writeAttribute('showErrorMessage', ($dv->getShowErrorMessage() ? '1' : '0')); + + if ($dv->getErrorTitle() !== '') { + $objWriter->writeAttribute('errorTitle', $dv->getErrorTitle()); + } + if ($dv->getError() !== '') { + $objWriter->writeAttribute('error', $dv->getError()); + } + if ($dv->getPromptTitle() !== '') { + $objWriter->writeAttribute('promptTitle', $dv->getPromptTitle()); + } + if ($dv->getPrompt() !== '') { + $objWriter->writeAttribute('prompt', $dv->getPrompt()); + } + + $objWriter->writeAttribute('sqref', $coordinate); + + if ($dv->getFormula1() !== '') { + $objWriter->writeElement('formula1', $dv->getFormula1()); + } + if ($dv->getFormula2() !== '') { + $objWriter->writeElement('formula2', $dv->getFormula2()); + } + + $objWriter->endElement(); + } + + $objWriter->endElement(); + } + } + + /** + * Write Hyperlinks + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writeHyperlinks(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + // Hyperlink collection + $hyperlinkCollection = $pSheet->getHyperlinkCollection(); + + // Relation ID + $relationId = 1; + + // Write hyperlinks? + if (!empty($hyperlinkCollection)) { + $objWriter->startElement('hyperlinks'); + + foreach ($hyperlinkCollection as $coordinate => $hyperlink) { + $objWriter->startElement('hyperlink'); + + $objWriter->writeAttribute('ref', $coordinate); + if (!$hyperlink->isInternal()) { + $objWriter->writeAttribute('r:id', 'rId_hyperlink_' . $relationId); + ++$relationId; + } else { + $objWriter->writeAttribute('location', str_replace('sheet://', '', $hyperlink->getUrl())); + } + + if ($hyperlink->getTooltip() != '') { + $objWriter->writeAttribute('tooltip', $hyperlink->getTooltip()); + } + + $objWriter->endElement(); + } + + $objWriter->endElement(); + } + } + + /** + * Write ProtectedRanges + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writeProtectedRanges(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + if (count($pSheet->getProtectedCells()) > 0) { + // protectedRanges + $objWriter->startElement('protectedRanges'); + + // Loop protectedRanges + foreach ($pSheet->getProtectedCells() as $protectedCell => $passwordHash) { + // protectedRange + $objWriter->startElement('protectedRange'); + $objWriter->writeAttribute('name', 'p' . md5($protectedCell)); + $objWriter->writeAttribute('sqref', $protectedCell); + if (!empty($passwordHash)) { + $objWriter->writeAttribute('password', $passwordHash); + } + $objWriter->endElement(); + } + + $objWriter->endElement(); + } + } + + /** + * Write MergeCells + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writeMergeCells(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + if (count($pSheet->getMergeCells()) > 0) { + // mergeCells + $objWriter->startElement('mergeCells'); + + // Loop mergeCells + foreach ($pSheet->getMergeCells() as $mergeCell) { + // mergeCell + $objWriter->startElement('mergeCell'); + $objWriter->writeAttribute('ref', $mergeCell); + $objWriter->endElement(); + } + + $objWriter->endElement(); + } + } + + /** + * Write PrintOptions + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writePrintOptions(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + // printOptions + $objWriter->startElement('printOptions'); + + $objWriter->writeAttribute('gridLines', ($pSheet->getPrintGridlines() ? 'true': 'false')); + $objWriter->writeAttribute('gridLinesSet', 'true'); + + if ($pSheet->getPageSetup()->getHorizontalCentered()) { + $objWriter->writeAttribute('horizontalCentered', 'true'); + } + + if ($pSheet->getPageSetup()->getVerticalCentered()) { + $objWriter->writeAttribute('verticalCentered', 'true'); + } + + $objWriter->endElement(); + } + + /** + * Write PageMargins + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writePageMargins(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + // pageMargins + $objWriter->startElement('pageMargins'); + $objWriter->writeAttribute('left', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getLeft())); + $objWriter->writeAttribute('right', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getRight())); + $objWriter->writeAttribute('top', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getTop())); + $objWriter->writeAttribute('bottom', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getBottom())); + $objWriter->writeAttribute('header', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getHeader())); + $objWriter->writeAttribute('footer', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getFooter())); + $objWriter->endElement(); + } + + /** + * Write AutoFilter + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writeAutoFilter(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + $autoFilterRange = $pSheet->getAutoFilter()->getRange(); + if (!empty($autoFilterRange)) { + // autoFilter + $objWriter->startElement('autoFilter'); + + // Strip any worksheet reference from the filter coordinates + $range = PHPExcel_Cell::splitRange($autoFilterRange); + $range = $range[0]; + // Strip any worksheet ref + if (strpos($range[0],'!') !== false) { + list($ws,$range[0]) = explode('!',$range[0]); + } + $range = implode(':', $range); + + $objWriter->writeAttribute('ref', str_replace('$','',$range)); + + $columns = $pSheet->getAutoFilter()->getColumns(); + if (count($columns > 0)) { + foreach($columns as $columnID => $column) { + $rules = $column->getRules(); + if (count($rules > 0)) { + $objWriter->startElement('filterColumn'); + $objWriter->writeAttribute('colId', $pSheet->getAutoFilter()->getColumnOffset($columnID)); + + $objWriter->startElement( $column->getFilterType()); + if ($column->getJoin() == PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND) { + $objWriter->writeAttribute('and', 1); + } + + foreach ($rules as $rule) { + if (($column->getFilterType() === PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER) && + ($rule->getOperator() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL) && + ($rule->getValue() === '')) { + // Filter rule for Blanks + $objWriter->writeAttribute('blank', 1); + } elseif($rule->getRuleType() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMICFILTER) { + // Dynamic Filter Rule + $objWriter->writeAttribute('type', $rule->getGrouping()); + $val = $column->getAttribute('val'); + if ($val !== NULL) { + $objWriter->writeAttribute('val', $val); + } + $maxVal = $column->getAttribute('maxVal'); + if ($maxVal !== NULL) { + $objWriter->writeAttribute('maxVal', $maxVal); + } + } elseif($rule->getRuleType() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_TOPTENFILTER) { + // Top 10 Filter Rule + $objWriter->writeAttribute('val', $rule->getValue()); + $objWriter->writeAttribute('percent', (($rule->getOperator() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT) ? '1' : '0')); + $objWriter->writeAttribute('top', (($rule->getGrouping() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP) ? '1': '0')); + } else { + // Filter, DateGroupItem or CustomFilter + $objWriter->startElement($rule->getRuleType()); + + if ($rule->getOperator() !== PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL) { + $objWriter->writeAttribute('operator', $rule->getOperator()); + } + if ($rule->getRuleType() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP) { + // Date Group filters + foreach($rule->getValue() as $key => $value) { + if ($value > '') $objWriter->writeAttribute($key, $value); + } + $objWriter->writeAttribute('dateTimeGrouping', $rule->getGrouping()); + } else { + $objWriter->writeAttribute('val', $rule->getValue()); + } + + $objWriter->endElement(); + } + } + + $objWriter->endElement(); + + $objWriter->endElement(); + } + } + } + + $objWriter->endElement(); + } + } + + /** + * Write PageSetup + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writePageSetup(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + // pageSetup + $objWriter->startElement('pageSetup'); + $objWriter->writeAttribute('paperSize', $pSheet->getPageSetup()->getPaperSize()); + $objWriter->writeAttribute('orientation', $pSheet->getPageSetup()->getOrientation()); + + if (!is_null($pSheet->getPageSetup()->getScale())) { + $objWriter->writeAttribute('scale', $pSheet->getPageSetup()->getScale()); + } + if (!is_null($pSheet->getPageSetup()->getFitToHeight())) { + $objWriter->writeAttribute('fitToHeight', $pSheet->getPageSetup()->getFitToHeight()); + } else { + $objWriter->writeAttribute('fitToHeight', '0'); + } + if (!is_null($pSheet->getPageSetup()->getFitToWidth())) { + $objWriter->writeAttribute('fitToWidth', $pSheet->getPageSetup()->getFitToWidth()); + } else { + $objWriter->writeAttribute('fitToWidth', '0'); + } + if (!is_null($pSheet->getPageSetup()->getFirstPageNumber())) { + $objWriter->writeAttribute('firstPageNumber', $pSheet->getPageSetup()->getFirstPageNumber()); + $objWriter->writeAttribute('useFirstPageNumber', '1'); + } + + $objWriter->endElement(); + } + + /** + * Write Header / Footer + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writeHeaderFooter(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + // headerFooter + $objWriter->startElement('headerFooter'); + $objWriter->writeAttribute('differentOddEven', ($pSheet->getHeaderFooter()->getDifferentOddEven() ? 'true' : 'false')); + $objWriter->writeAttribute('differentFirst', ($pSheet->getHeaderFooter()->getDifferentFirst() ? 'true' : 'false')); + $objWriter->writeAttribute('scaleWithDoc', ($pSheet->getHeaderFooter()->getScaleWithDocument() ? 'true' : 'false')); + $objWriter->writeAttribute('alignWithMargins', ($pSheet->getHeaderFooter()->getAlignWithMargins() ? 'true' : 'false')); + + $objWriter->writeElement('oddHeader', $pSheet->getHeaderFooter()->getOddHeader()); + $objWriter->writeElement('oddFooter', $pSheet->getHeaderFooter()->getOddFooter()); + $objWriter->writeElement('evenHeader', $pSheet->getHeaderFooter()->getEvenHeader()); + $objWriter->writeElement('evenFooter', $pSheet->getHeaderFooter()->getEvenFooter()); + $objWriter->writeElement('firstHeader', $pSheet->getHeaderFooter()->getFirstHeader()); + $objWriter->writeElement('firstFooter', $pSheet->getHeaderFooter()->getFirstFooter()); + $objWriter->endElement(); + } + + /** + * Write Breaks + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writeBreaks(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + // Get row and column breaks + $aRowBreaks = array(); + $aColumnBreaks = array(); + foreach ($pSheet->getBreaks() as $cell => $breakType) { + if ($breakType == PHPExcel_Worksheet::BREAK_ROW) { + $aRowBreaks[] = $cell; + } else if ($breakType == PHPExcel_Worksheet::BREAK_COLUMN) { + $aColumnBreaks[] = $cell; + } + } + + // rowBreaks + if (!empty($aRowBreaks)) { + $objWriter->startElement('rowBreaks'); + $objWriter->writeAttribute('count', count($aRowBreaks)); + $objWriter->writeAttribute('manualBreakCount', count($aRowBreaks)); + + foreach ($aRowBreaks as $cell) { + $coords = PHPExcel_Cell::coordinateFromString($cell); + + $objWriter->startElement('brk'); + $objWriter->writeAttribute('id', $coords[1]); + $objWriter->writeAttribute('man', '1'); + $objWriter->endElement(); + } + + $objWriter->endElement(); + } + + // Second, write column breaks + if (!empty($aColumnBreaks)) { + $objWriter->startElement('colBreaks'); + $objWriter->writeAttribute('count', count($aColumnBreaks)); + $objWriter->writeAttribute('manualBreakCount', count($aColumnBreaks)); + + foreach ($aColumnBreaks as $cell) { + $coords = PHPExcel_Cell::coordinateFromString($cell); + + $objWriter->startElement('brk'); + $objWriter->writeAttribute('id', PHPExcel_Cell::columnIndexFromString($coords[0]) - 1); + $objWriter->writeAttribute('man', '1'); + $objWriter->endElement(); + } + + $objWriter->endElement(); + } + } + + /** + * Write SheetData + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @param string[] $pStringTable String table + * @throws PHPExcel_Writer_Exception + */ + private function _writeSheetData(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pStringTable = null) + { + if (is_array($pStringTable)) { + // Flipped stringtable, for faster index searching + $aFlippedStringTable = $this->getParentWriter()->getWriterPart('stringtable')->flipStringTable($pStringTable); + + // sheetData + $objWriter->startElement('sheetData'); + + // Get column count + $colCount = PHPExcel_Cell::columnIndexFromString($pSheet->getHighestColumn()); + + // Highest row number + $highestRow = $pSheet->getHighestRow(); + + // Loop through cells + $cellsByRow = array(); + foreach ($pSheet->getCellCollection() as $cellID) { + $cellAddress = PHPExcel_Cell::coordinateFromString($cellID); + $cellsByRow[$cellAddress[1]][] = $cellID; + } + + $currentRow = 0; + while($currentRow++ < $highestRow) { + // Get row dimension + $rowDimension = $pSheet->getRowDimension($currentRow); + + // Write current row? + $writeCurrentRow = isset($cellsByRow[$currentRow]) || + $rowDimension->getRowHeight() >= 0 || + $rowDimension->getVisible() == false || + $rowDimension->getCollapsed() == true || + $rowDimension->getOutlineLevel() > 0 || + $rowDimension->getXfIndex() !== null; + + if ($writeCurrentRow) { + // Start a new row + $objWriter->startElement('row'); + $objWriter->writeAttribute('r', $currentRow); + $objWriter->writeAttribute('spans', '1:' . $colCount); + + // Row dimensions + if ($rowDimension->getRowHeight() >= 0) { + $objWriter->writeAttribute('customHeight', '1'); + $objWriter->writeAttribute('ht', PHPExcel_Shared_String::FormatNumber($rowDimension->getRowHeight())); + } + + // Row visibility + if ($rowDimension->getVisible() == false) { + $objWriter->writeAttribute('hidden', 'true'); + } + + // Collapsed + if ($rowDimension->getCollapsed() == true) { + $objWriter->writeAttribute('collapsed', 'true'); + } + + // Outline level + if ($rowDimension->getOutlineLevel() > 0) { + $objWriter->writeAttribute('outlineLevel', $rowDimension->getOutlineLevel()); + } + + // Style + if ($rowDimension->getXfIndex() !== null) { + $objWriter->writeAttribute('s', $rowDimension->getXfIndex()); + $objWriter->writeAttribute('customFormat', '1'); + } + + // Write cells + if (isset($cellsByRow[$currentRow])) { + foreach($cellsByRow[$currentRow] as $cellAddress) { + // Write cell + $this->_writeCell($objWriter, $pSheet, $cellAddress, $pStringTable, $aFlippedStringTable); + } + } + + // End row + $objWriter->endElement(); + } + } + + $objWriter->endElement(); + } else { + throw new PHPExcel_Writer_Exception("Invalid parameters passed."); + } + } + + /** + * Write Cell + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @param PHPExcel_Cell $pCellAddress Cell Address + * @param string[] $pStringTable String table + * @param string[] $pFlippedStringTable String table (flipped), for faster index searching + * @throws PHPExcel_Writer_Exception + */ + private function _writeCell(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pCellAddress = null, $pStringTable = null, $pFlippedStringTable = null) + { + if (is_array($pStringTable) && is_array($pFlippedStringTable)) { + // Cell + $pCell = $pSheet->getCell($pCellAddress); + $objWriter->startElement('c'); + $objWriter->writeAttribute('r', $pCellAddress); + + // Sheet styles + if ($pCell->getXfIndex() != '') { + $objWriter->writeAttribute('s', $pCell->getXfIndex()); + } + + // If cell value is supplied, write cell value + $cellValue = $pCell->getValue(); + if (is_object($cellValue) || $cellValue !== '') { + // Map type + $mappedType = $pCell->getDataType(); + + // Write data type depending on its type + switch (strtolower($mappedType)) { + case 'inlinestr': // Inline string + case 's': // String + case 'b': // Boolean + $objWriter->writeAttribute('t', $mappedType); + break; + case 'f': // Formula + $calculatedValue = ($this->getParentWriter()->getPreCalculateFormulas()) ? + $pCell->getCalculatedValue() : + $cellValue; + if (is_string($calculatedValue)) { + $objWriter->writeAttribute('t', 'str'); + } + break; + case 'e': // Error + $objWriter->writeAttribute('t', $mappedType); + } + + // Write data depending on its type + switch (strtolower($mappedType)) { + case 'inlinestr': // Inline string + if (! $cellValue instanceof PHPExcel_RichText) { + $objWriter->writeElement('t', PHPExcel_Shared_String::ControlCharacterPHP2OOXML( htmlspecialchars($cellValue) ) ); + } else if ($cellValue instanceof PHPExcel_RichText) { + $objWriter->startElement('is'); + $this->getParentWriter()->getWriterPart('stringtable')->writeRichText($objWriter, $cellValue); + $objWriter->endElement(); + } + + break; + case 's': // String + if (! $cellValue instanceof PHPExcel_RichText) { + if (isset($pFlippedStringTable[$cellValue])) { + $objWriter->writeElement('v', $pFlippedStringTable[$cellValue]); + } + } else if ($cellValue instanceof PHPExcel_RichText) { + $objWriter->writeElement('v', $pFlippedStringTable[$cellValue->getHashCode()]); + } + + break; + case 'f': // Formula + $attributes = $pCell->getFormulaAttributes(); + if($attributes['t'] == 'array') { + $objWriter->startElement('f'); + $objWriter->writeAttribute('t', 'array'); + $objWriter->writeAttribute('ref', $pCellAddress); + $objWriter->writeAttribute('aca', '1'); + $objWriter->writeAttribute('ca', '1'); + $objWriter->text(substr($cellValue, 1)); + $objWriter->endElement(); + } else { + $objWriter->writeElement('f', substr($cellValue, 1)); + } + if ($this->getParentWriter()->getOffice2003Compatibility() === false) { + if ($this->getParentWriter()->getPreCalculateFormulas()) { +// $calculatedValue = $pCell->getCalculatedValue(); + if (!is_array($calculatedValue) && substr($calculatedValue, 0, 1) != '#') { + $objWriter->writeElement('v', PHPExcel_Shared_String::FormatNumber($calculatedValue)); + } else { + $objWriter->writeElement('v', '0'); + } + } else { + $objWriter->writeElement('v', '0'); + } + } + break; + case 'n': // Numeric + // force point as decimal separator in case current locale uses comma + $objWriter->writeElement('v', str_replace(',', '.', $cellValue)); + break; + case 'b': // Boolean + $objWriter->writeElement('v', ($cellValue ? '1' : '0')); + break; + case 'e': // Error + if (substr($cellValue, 0, 1) == '=') { + $objWriter->writeElement('f', substr($cellValue, 1)); + $objWriter->writeElement('v', substr($cellValue, 1)); + } else { + $objWriter->writeElement('v', $cellValue); + } + + break; + } + } + + $objWriter->endElement(); + } else { + throw new PHPExcel_Writer_Exception("Invalid parameters passed."); + } + } + + /** + * Write Drawings + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @param boolean $includeCharts Flag indicating if we should include drawing details for charts + * @throws PHPExcel_Writer_Exception + */ + private function _writeDrawings(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $includeCharts = FALSE) + { + $chartCount = ($includeCharts) ? $pSheet->getChartCollection()->count() : 0; + // If sheet contains drawings, add the relationships + if (($pSheet->getDrawingCollection()->count() > 0) || + ($chartCount > 0)) { + $objWriter->startElement('drawing'); + $objWriter->writeAttribute('r:id', 'rId1'); + $objWriter->endElement(); + } + } + + /** + * Write LegacyDrawing + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writeLegacyDrawing(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + // If sheet contains comments, add the relationships + if (count($pSheet->getComments()) > 0) { + $objWriter->startElement('legacyDrawing'); + $objWriter->writeAttribute('r:id', 'rId_comments_vml1'); + $objWriter->endElement(); + } + } + + /** + * Write LegacyDrawingHF + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writeLegacyDrawingHF(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + // If sheet contains images, add the relationships + if (count($pSheet->getHeaderFooter()->getImages()) > 0) { + $objWriter->startElement('legacyDrawingHF'); + $objWriter->writeAttribute('r:id', 'rId_headerfooter_vml1'); + $objWriter->endElement(); + } + } +} diff --git a/lib/phpexcel/PHPExcel/Writer/Excel2007/WriterPart.php b/lib/phpexcel/PHPExcel/Writer/Excel2007/WriterPart.php new file mode 100644 index 0000000..982117b --- /dev/null +++ b/lib/phpexcel/PHPExcel/Writer/Excel2007/WriterPart.php @@ -0,0 +1,81 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Writer_Excel2007_WriterPart + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +abstract class PHPExcel_Writer_Excel2007_WriterPart +{ + /** + * Parent IWriter object + * + * @var PHPExcel_Writer_IWriter + */ + private $_parentWriter; + + /** + * Set parent IWriter object + * + * @param PHPExcel_Writer_IWriter $pWriter + * @throws PHPExcel_Writer_Exception + */ + public function setParentWriter(PHPExcel_Writer_IWriter $pWriter = null) { + $this->_parentWriter = $pWriter; + } + + /** + * Get parent IWriter object + * + * @return PHPExcel_Writer_IWriter + * @throws PHPExcel_Writer_Exception + */ + public function getParentWriter() { + if (!is_null($this->_parentWriter)) { + return $this->_parentWriter; + } else { + throw new PHPExcel_Writer_Exception("No parent PHPExcel_Writer_IWriter assigned."); + } + } + + /** + * Set parent IWriter object + * + * @param PHPExcel_Writer_IWriter $pWriter + * @throws PHPExcel_Writer_Exception + */ + public function __construct(PHPExcel_Writer_IWriter $pWriter = null) { + if (!is_null($pWriter)) { + $this->_parentWriter = $pWriter; + } + } + +} diff --git a/lib/phpexcel/PHPExcel/Writer/Excel5.php b/lib/phpexcel/PHPExcel/Writer/Excel5.php new file mode 100644 index 0000000..3f816fa --- /dev/null +++ b/lib/phpexcel/PHPExcel/Writer/Excel5.php @@ -0,0 +1,935 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel5 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Writer_Excel5 + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel5 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_Excel5 extends PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter +{ + /** + * PHPExcel object + * + * @var PHPExcel + */ + private $_phpExcel; + + /** + * Total number of shared strings in workbook + * + * @var int + */ + private $_str_total = 0; + + /** + * Number of unique shared strings in workbook + * + * @var int + */ + private $_str_unique = 0; + + /** + * Array of unique shared strings in workbook + * + * @var array + */ + private $_str_table = array(); + + /** + * Color cache. Mapping between RGB value and color index. + * + * @var array + */ + private $_colors; + + /** + * Formula parser + * + * @var PHPExcel_Writer_Excel5_Parser + */ + private $_parser; + + /** + * Identifier clusters for drawings. Used in MSODRAWINGGROUP record. + * + * @var array + */ + private $_IDCLs; + + /** + * Basic OLE object summary information + * + * @var array + */ + private $_summaryInformation; + + /** + * Extended OLE object document summary information + * + * @var array + */ + private $_documentSummaryInformation; + + /** + * Create a new PHPExcel_Writer_Excel5 + * + * @param PHPExcel $phpExcel PHPExcel object + */ + public function __construct(PHPExcel $phpExcel) { + $this->_phpExcel = $phpExcel; + + $this->_parser = new PHPExcel_Writer_Excel5_Parser(); + } + + /** + * Save PHPExcel to file + * + * @param string $pFilename + * @throws PHPExcel_Writer_Exception + */ + public function save($pFilename = null) { + + // garbage collect + $this->_phpExcel->garbageCollect(); + + $saveDebugLog = PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->getWriteDebugLog(); + PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog(FALSE); + $saveDateReturnType = PHPExcel_Calculation_Functions::getReturnDateType(); + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); + + // initialize colors array + $this->_colors = array(); + + // Initialise workbook writer + $this->_writerWorkbook = new PHPExcel_Writer_Excel5_Workbook($this->_phpExcel, + $this->_str_total, $this->_str_unique, $this->_str_table, + $this->_colors, $this->_parser); + + // Initialise worksheet writers + $countSheets = $this->_phpExcel->getSheetCount(); + for ($i = 0; $i < $countSheets; ++$i) { + $this->_writerWorksheets[$i] = new PHPExcel_Writer_Excel5_Worksheet($this->_str_total, $this->_str_unique, + $this->_str_table, $this->_colors, + $this->_parser, + $this->_preCalculateFormulas, + $this->_phpExcel->getSheet($i)); + } + + // build Escher objects. Escher objects for workbooks needs to be build before Escher object for workbook. + $this->_buildWorksheetEschers(); + $this->_buildWorkbookEscher(); + + // add 15 identical cell style Xfs + // for now, we use the first cellXf instead of cellStyleXf + $cellXfCollection = $this->_phpExcel->getCellXfCollection(); + for ($i = 0; $i < 15; ++$i) { + $this->_writerWorkbook->addXfWriter($cellXfCollection[0], true); + } + + // add all the cell Xfs + foreach ($this->_phpExcel->getCellXfCollection() as $style) { + $this->_writerWorkbook->addXfWriter($style, false); + } + + // add fonts from rich text eleemnts + for ($i = 0; $i < $countSheets; ++$i) { + foreach ($this->_writerWorksheets[$i]->_phpSheet->getCellCollection() as $cellID) { + $cell = $this->_writerWorksheets[$i]->_phpSheet->getCell($cellID); + $cVal = $cell->getValue(); + if ($cVal instanceof PHPExcel_RichText) { + $elements = $cVal->getRichTextElements(); + foreach ($elements as $element) { + if ($element instanceof PHPExcel_RichText_Run) { + $font = $element->getFont(); + $this->_writerWorksheets[$i]->_fntHashIndex[$font->getHashCode()] = $this->_writerWorkbook->_addFont($font); + } + } + } + } + } + + // initialize OLE file + $workbookStreamName = 'Workbook'; + $OLE = new PHPExcel_Shared_OLE_PPS_File(PHPExcel_Shared_OLE::Asc2Ucs($workbookStreamName)); + + // Write the worksheet streams before the global workbook stream, + // because the byte sizes of these are needed in the global workbook stream + $worksheetSizes = array(); + for ($i = 0; $i < $countSheets; ++$i) { + $this->_writerWorksheets[$i]->close(); + $worksheetSizes[] = $this->_writerWorksheets[$i]->_datasize; + } + + // add binary data for global workbook stream + $OLE->append($this->_writerWorkbook->writeWorkbook($worksheetSizes)); + + // add binary data for sheet streams + for ($i = 0; $i < $countSheets; ++$i) { + $OLE->append($this->_writerWorksheets[$i]->getData()); + } + + $this->_documentSummaryInformation = $this->_writeDocumentSummaryInformation(); + // initialize OLE Document Summary Information + if(isset($this->_documentSummaryInformation) && !empty($this->_documentSummaryInformation)){ + $OLE_DocumentSummaryInformation = new PHPExcel_Shared_OLE_PPS_File(PHPExcel_Shared_OLE::Asc2Ucs(chr(5) . 'DocumentSummaryInformation')); + $OLE_DocumentSummaryInformation->append($this->_documentSummaryInformation); + } + + $this->_summaryInformation = $this->_writeSummaryInformation(); + // initialize OLE Summary Information + if(isset($this->_summaryInformation) && !empty($this->_summaryInformation)){ + $OLE_SummaryInformation = new PHPExcel_Shared_OLE_PPS_File(PHPExcel_Shared_OLE::Asc2Ucs(chr(5) . 'SummaryInformation')); + $OLE_SummaryInformation->append($this->_summaryInformation); + } + + // define OLE Parts + $arrRootData = array($OLE); + // initialize OLE Properties file + if(isset($OLE_SummaryInformation)){ + $arrRootData[] = $OLE_SummaryInformation; + } + // initialize OLE Extended Properties file + if(isset($OLE_DocumentSummaryInformation)){ + $arrRootData[] = $OLE_DocumentSummaryInformation; + } + + $root = new PHPExcel_Shared_OLE_PPS_Root(time(), time(), $arrRootData); + // save the OLE file + $res = $root->save($pFilename); + + PHPExcel_Calculation_Functions::setReturnDateType($saveDateReturnType); + PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog($saveDebugLog); + } + + /** + * Set temporary storage directory + * + * @deprecated + * @param string $pValue Temporary storage directory + * @throws PHPExcel_Writer_Exception when directory does not exist + * @return PHPExcel_Writer_Excel5 + */ + public function setTempDir($pValue = '') { + return $this; + } + + /** + * Build the Worksheet Escher objects + * + */ + private function _buildWorksheetEschers() + { + // 1-based index to BstoreContainer + $blipIndex = 0; + $lastReducedSpId = 0; + $lastSpId = 0; + + foreach ($this->_phpExcel->getAllsheets() as $sheet) { + // sheet index + $sheetIndex = $sheet->getParent()->getIndex($sheet); + + $escher = null; + + // check if there are any shapes for this sheet + $filterRange = $sheet->getAutoFilter()->getRange(); + if (count($sheet->getDrawingCollection()) == 0 && empty($filterRange)) { + continue; + } + + // create intermediate Escher object + $escher = new PHPExcel_Shared_Escher(); + + // dgContainer + $dgContainer = new PHPExcel_Shared_Escher_DgContainer(); + + // set the drawing index (we use sheet index + 1) + $dgId = $sheet->getParent()->getIndex($sheet) + 1; + $dgContainer->setDgId($dgId); + $escher->setDgContainer($dgContainer); + + // spgrContainer + $spgrContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer(); + $dgContainer->setSpgrContainer($spgrContainer); + + // add one shape which is the group shape + $spContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer(); + $spContainer->setSpgr(true); + $spContainer->setSpType(0); + $spContainer->setSpId(($sheet->getParent()->getIndex($sheet) + 1) << 10); + $spgrContainer->addChild($spContainer); + + // add the shapes + + $countShapes[$sheetIndex] = 0; // count number of shapes (minus group shape), in sheet + + foreach ($sheet->getDrawingCollection() as $drawing) { + ++$blipIndex; + + ++$countShapes[$sheetIndex]; + + // add the shape + $spContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer(); + + // set the shape type + $spContainer->setSpType(0x004B); + // set the shape flag + $spContainer->setSpFlag(0x02); + + // set the shape index (we combine 1-based sheet index and $countShapes to create unique shape index) + $reducedSpId = $countShapes[$sheetIndex]; + $spId = $reducedSpId + | ($sheet->getParent()->getIndex($sheet) + 1) << 10; + $spContainer->setSpId($spId); + + // keep track of last reducedSpId + $lastReducedSpId = $reducedSpId; + + // keep track of last spId + $lastSpId = $spId; + + // set the BLIP index + $spContainer->setOPT(0x4104, $blipIndex); + + // set coordinates and offsets, client anchor + $coordinates = $drawing->getCoordinates(); + $offsetX = $drawing->getOffsetX(); + $offsetY = $drawing->getOffsetY(); + $width = $drawing->getWidth(); + $height = $drawing->getHeight(); + + $twoAnchor = PHPExcel_Shared_Excel5::oneAnchor2twoAnchor($sheet, $coordinates, $offsetX, $offsetY, $width, $height); + + $spContainer->setStartCoordinates($twoAnchor['startCoordinates']); + $spContainer->setStartOffsetX($twoAnchor['startOffsetX']); + $spContainer->setStartOffsetY($twoAnchor['startOffsetY']); + $spContainer->setEndCoordinates($twoAnchor['endCoordinates']); + $spContainer->setEndOffsetX($twoAnchor['endOffsetX']); + $spContainer->setEndOffsetY($twoAnchor['endOffsetY']); + + $spgrContainer->addChild($spContainer); + } + + // AutoFilters + if(!empty($filterRange)){ + $rangeBounds = PHPExcel_Cell::rangeBoundaries($filterRange); + $iNumColStart = $rangeBounds[0][0]; + $iNumColEnd = $rangeBounds[1][0]; + + $iInc = $iNumColStart; + while($iInc <= $iNumColEnd){ + ++$countShapes[$sheetIndex]; + + // create an Drawing Object for the dropdown + $oDrawing = new PHPExcel_Worksheet_BaseDrawing(); + // get the coordinates of drawing + $cDrawing = PHPExcel_Cell::stringFromColumnIndex($iInc - 1) . $rangeBounds[0][1]; + $oDrawing->setCoordinates($cDrawing); + $oDrawing->setWorksheet($sheet); + + // add the shape + $spContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer(); + // set the shape type + $spContainer->setSpType(0x00C9); + // set the shape flag + $spContainer->setSpFlag(0x01); + + // set the shape index (we combine 1-based sheet index and $countShapes to create unique shape index) + $reducedSpId = $countShapes[$sheetIndex]; + $spId = $reducedSpId + | ($sheet->getParent()->getIndex($sheet) + 1) << 10; + $spContainer->setSpId($spId); + + // keep track of last reducedSpId + $lastReducedSpId = $reducedSpId; + + // keep track of last spId + $lastSpId = $spId; + + $spContainer->setOPT(0x007F, 0x01040104); // Protection -> fLockAgainstGrouping + $spContainer->setOPT(0x00BF, 0x00080008); // Text -> fFitTextToShape + $spContainer->setOPT(0x01BF, 0x00010000); // Fill Style -> fNoFillHitTest + $spContainer->setOPT(0x01FF, 0x00080000); // Line Style -> fNoLineDrawDash + $spContainer->setOPT(0x03BF, 0x000A0000); // Group Shape -> fPrint + + // set coordinates and offsets, client anchor + $endCoordinates = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::stringFromColumnIndex($iInc - 1)); + $endCoordinates .= $rangeBounds[0][1] + 1; + + $spContainer->setStartCoordinates($cDrawing); + $spContainer->setStartOffsetX(0); + $spContainer->setStartOffsetY(0); + $spContainer->setEndCoordinates($endCoordinates); + $spContainer->setEndOffsetX(0); + $spContainer->setEndOffsetY(0); + + $spgrContainer->addChild($spContainer); + $iInc++; + } + } + + // identifier clusters, used for workbook Escher object + $this->_IDCLs[$dgId] = $lastReducedSpId; + + // set last shape index + $dgContainer->setLastSpId($lastSpId); + + // set the Escher object + $this->_writerWorksheets[$sheetIndex]->setEscher($escher); + } + } + + /** + * Build the Escher object corresponding to the MSODRAWINGGROUP record + */ + private function _buildWorkbookEscher() + { + $escher = null; + + // any drawings in this workbook? + $found = false; + foreach ($this->_phpExcel->getAllSheets() as $sheet) { + if (count($sheet->getDrawingCollection()) > 0) { + $found = true; + break; + } + } + + // nothing to do if there are no drawings + if (!$found) { + return; + } + + // if we reach here, then there are drawings in the workbook + $escher = new PHPExcel_Shared_Escher(); + + // dggContainer + $dggContainer = new PHPExcel_Shared_Escher_DggContainer(); + $escher->setDggContainer($dggContainer); + + // set IDCLs (identifier clusters) + $dggContainer->setIDCLs($this->_IDCLs); + + // this loop is for determining maximum shape identifier of all drawing + $spIdMax = 0; + $totalCountShapes = 0; + $countDrawings = 0; + + foreach ($this->_phpExcel->getAllsheets() as $sheet) { + $sheetCountShapes = 0; // count number of shapes (minus group shape), in sheet + + if (count($sheet->getDrawingCollection()) > 0) { + ++$countDrawings; + + foreach ($sheet->getDrawingCollection() as $drawing) { + ++$sheetCountShapes; + ++$totalCountShapes; + + $spId = $sheetCountShapes + | ($this->_phpExcel->getIndex($sheet) + 1) << 10; + $spIdMax = max($spId, $spIdMax); + } + } + } + + $dggContainer->setSpIdMax($spIdMax + 1); + $dggContainer->setCDgSaved($countDrawings); + $dggContainer->setCSpSaved($totalCountShapes + $countDrawings); // total number of shapes incl. one group shapes per drawing + + // bstoreContainer + $bstoreContainer = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer(); + $dggContainer->setBstoreContainer($bstoreContainer); + + // the BSE's (all the images) + foreach ($this->_phpExcel->getAllsheets() as $sheet) { + foreach ($sheet->getDrawingCollection() as $drawing) { + if ($drawing instanceof PHPExcel_Worksheet_Drawing) { + + $filename = $drawing->getPath(); + + list($imagesx, $imagesy, $imageFormat) = getimagesize($filename); + + switch ($imageFormat) { + + case 1: // GIF, not supported by BIFF8, we convert to PNG + $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG; + ob_start(); + imagepng(imagecreatefromgif($filename)); + $blipData = ob_get_contents(); + ob_end_clean(); + break; + + case 2: // JPEG + $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_JPEG; + $blipData = file_get_contents($filename); + break; + + case 3: // PNG + $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG; + $blipData = file_get_contents($filename); + break; + + case 6: // Windows DIB (BMP), we convert to PNG + $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG; + ob_start(); + imagepng(PHPExcel_Shared_Drawing::imagecreatefrombmp($filename)); + $blipData = ob_get_contents(); + ob_end_clean(); + break; + + default: continue 2; + + } + + $blip = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip(); + $blip->setData($blipData); + + $BSE = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE(); + $BSE->setBlipType($blipType); + $BSE->setBlip($blip); + + $bstoreContainer->addBSE($BSE); + + } else if ($drawing instanceof PHPExcel_Worksheet_MemoryDrawing) { + + switch ($drawing->getRenderingFunction()) { + + case PHPExcel_Worksheet_MemoryDrawing::RENDERING_JPEG: + $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_JPEG; + $renderingFunction = 'imagejpeg'; + break; + + case PHPExcel_Worksheet_MemoryDrawing::RENDERING_GIF: + case PHPExcel_Worksheet_MemoryDrawing::RENDERING_PNG: + case PHPExcel_Worksheet_MemoryDrawing::RENDERING_DEFAULT: + $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG; + $renderingFunction = 'imagepng'; + break; + + } + + ob_start(); + call_user_func($renderingFunction, $drawing->getImageResource()); + $blipData = ob_get_contents(); + ob_end_clean(); + + $blip = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip(); + $blip->setData($blipData); + + $BSE = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE(); + $BSE->setBlipType($blipType); + $BSE->setBlip($blip); + + $bstoreContainer->addBSE($BSE); + } + } + } + + // Set the Escher object + $this->_writerWorkbook->setEscher($escher); + } + + /** + * Build the OLE Part for DocumentSummary Information + * @return string + */ + private function _writeDocumentSummaryInformation(){ + + // offset: 0; size: 2; must be 0xFE 0xFF (UTF-16 LE byte order mark) + $data = pack('v', 0xFFFE); + // offset: 2; size: 2; + $data .= pack('v', 0x0000); + // offset: 4; size: 2; OS version + $data .= pack('v', 0x0106); + // offset: 6; size: 2; OS indicator + $data .= pack('v', 0x0002); + // offset: 8; size: 16 + $data .= pack('VVVV', 0x00, 0x00, 0x00, 0x00); + // offset: 24; size: 4; section count + $data .= pack('V', 0x0001); + + // offset: 28; size: 16; first section's class id: 02 d5 cd d5 9c 2e 1b 10 93 97 08 00 2b 2c f9 ae + $data .= pack('vvvvvvvv', 0xD502, 0xD5CD, 0x2E9C, 0x101B, 0x9793, 0x0008, 0x2C2B, 0xAEF9); + // offset: 44; size: 4; offset of the start + $data .= pack('V', 0x30); + + // SECTION + $dataSection = array(); + $dataSection_NumProps = 0; + $dataSection_Summary = ''; + $dataSection_Content = ''; + + // GKPIDDSI_CODEPAGE: CodePage + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x01), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x02), // 2 byte signed integer + 'data' => array('data' => 1252)); + $dataSection_NumProps++; + + // GKPIDDSI_CATEGORY : Category + if($this->_phpExcel->getProperties()->getCategory()){ + $dataProp = $this->_phpExcel->getProperties()->getCategory(); + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x02), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x1E), + 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); + $dataSection_NumProps++; + } + // GKPIDDSI_VERSION :Version of the application that wrote the property storage + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x17), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x03), + 'data' => array('pack' => 'V', 'data' => 0x000C0000)); + $dataSection_NumProps++; + // GKPIDDSI_SCALE : FALSE + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x0B), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x0B), + 'data' => array('data' => false)); + $dataSection_NumProps++; + // GKPIDDSI_LINKSDIRTY : True if any of the values for the linked properties have changed outside of the application + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x10), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x0B), + 'data' => array('data' => false)); + $dataSection_NumProps++; + // GKPIDDSI_SHAREDOC : FALSE + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x13), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x0B), + 'data' => array('data' => false)); + $dataSection_NumProps++; + // GKPIDDSI_HYPERLINKSCHANGED : True if any of the values for the _PID_LINKS (hyperlink text) have changed outside of the application + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x16), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x0B), + 'data' => array('data' => false)); + $dataSection_NumProps++; + + // GKPIDDSI_DOCSPARTS + // MS-OSHARED p75 (2.3.3.2.2.1) + // Structure is VtVecUnalignedLpstrValue (2.3.3.1.9) + // cElements + $dataProp = pack('v', 0x0001); + $dataProp .= pack('v', 0x0000); + // array of UnalignedLpstr + // cch + $dataProp .= pack('v', 0x000A); + $dataProp .= pack('v', 0x0000); + // value + $dataProp .= 'Worksheet'.chr(0); + + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x0D), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x101E), + 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); + $dataSection_NumProps++; + + // GKPIDDSI_HEADINGPAIR + // VtVecHeadingPairValue + // cElements + $dataProp = pack('v', 0x0002); + $dataProp .= pack('v', 0x0000); + // Array of vtHeadingPair + // vtUnalignedString - headingString + // stringType + $dataProp .= pack('v', 0x001E); + // padding + $dataProp .= pack('v', 0x0000); + // UnalignedLpstr + // cch + $dataProp .= pack('v', 0x0013); + $dataProp .= pack('v', 0x0000); + // value + $dataProp .= 'Feuilles de calcul'; + // vtUnalignedString - headingParts + // wType : 0x0003 = 32 bit signed integer + $dataProp .= pack('v', 0x0300); + // padding + $dataProp .= pack('v', 0x0000); + // value + $dataProp .= pack('v', 0x0100); + $dataProp .= pack('v', 0x0000); + $dataProp .= pack('v', 0x0000); + $dataProp .= pack('v', 0x0000); + + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x0C), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x100C), + 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); + $dataSection_NumProps++; + + // 4 Section Length + // 4 Property count + // 8 * $dataSection_NumProps (8 = ID (4) + OffSet(4)) + $dataSection_Content_Offset = 8 + $dataSection_NumProps * 8; + foreach ($dataSection as $dataProp){ + // Summary + $dataSection_Summary .= pack($dataProp['summary']['pack'], $dataProp['summary']['data']); + // Offset + $dataSection_Summary .= pack($dataProp['offset']['pack'], $dataSection_Content_Offset); + // DataType + $dataSection_Content .= pack($dataProp['type']['pack'], $dataProp['type']['data']); + // Data + if($dataProp['type']['data'] == 0x02){ // 2 byte signed integer + $dataSection_Content .= pack('V', $dataProp['data']['data']); + + $dataSection_Content_Offset += 4 + 4; + } + elseif($dataProp['type']['data'] == 0x03){ // 4 byte signed integer + $dataSection_Content .= pack('V', $dataProp['data']['data']); + + $dataSection_Content_Offset += 4 + 4; + } + elseif($dataProp['type']['data'] == 0x0B){ // Boolean + if($dataProp['data']['data'] == false){ + $dataSection_Content .= pack('V', 0x0000); + } else { + $dataSection_Content .= pack('V', 0x0001); + } + $dataSection_Content_Offset += 4 + 4; + } + elseif($dataProp['type']['data'] == 0x1E){ // null-terminated string prepended by dword string length + // Null-terminated string + $dataProp['data']['data'] .= chr(0); + $dataProp['data']['length'] += 1; + // Complete the string with null string for being a %4 + $dataProp['data']['length'] = $dataProp['data']['length'] + ((4 - $dataProp['data']['length'] % 4)==4 ? 0 : (4 - $dataProp['data']['length'] % 4)); + $dataProp['data']['data'] = str_pad($dataProp['data']['data'], $dataProp['data']['length'], chr(0), STR_PAD_RIGHT); + + $dataSection_Content .= pack('V', $dataProp['data']['length']); + $dataSection_Content .= $dataProp['data']['data']; + + $dataSection_Content_Offset += 4 + 4 + strlen($dataProp['data']['data']); + } + elseif($dataProp['type']['data'] == 0x40){ // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) + $dataSection_Content .= $dataProp['data']['data']; + + $dataSection_Content_Offset += 4 + 8; + } + else { + // Data Type Not Used at the moment + $dataSection_Content .= $dataProp['data']['data']; + + $dataSection_Content_Offset += 4 + $dataProp['data']['length']; + } + } + // Now $dataSection_Content_Offset contains the size of the content + + // section header + // offset: $secOffset; size: 4; section length + // + x Size of the content (summary + content) + $data .= pack('V', $dataSection_Content_Offset); + // offset: $secOffset+4; size: 4; property count + $data .= pack('V', $dataSection_NumProps); + // Section Summary + $data .= $dataSection_Summary; + // Section Content + $data .= $dataSection_Content; + + return $data; + } + + /** + * Build the OLE Part for Summary Information + * @return string + */ + private function _writeSummaryInformation(){ + // offset: 0; size: 2; must be 0xFE 0xFF (UTF-16 LE byte order mark) + $data = pack('v', 0xFFFE); + // offset: 2; size: 2; + $data .= pack('v', 0x0000); + // offset: 4; size: 2; OS version + $data .= pack('v', 0x0106); + // offset: 6; size: 2; OS indicator + $data .= pack('v', 0x0002); + // offset: 8; size: 16 + $data .= pack('VVVV', 0x00, 0x00, 0x00, 0x00); + // offset: 24; size: 4; section count + $data .= pack('V', 0x0001); + + // offset: 28; size: 16; first section's class id: e0 85 9f f2 f9 4f 68 10 ab 91 08 00 2b 27 b3 d9 + $data .= pack('vvvvvvvv', 0x85E0, 0xF29F, 0x4FF9, 0x1068, 0x91AB, 0x0008, 0x272B, 0xD9B3); + // offset: 44; size: 4; offset of the start + $data .= pack('V', 0x30); + + // SECTION + $dataSection = array(); + $dataSection_NumProps = 0; + $dataSection_Summary = ''; + $dataSection_Content = ''; + + // CodePage : CP-1252 + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x01), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x02), // 2 byte signed integer + 'data' => array('data' => 1252)); + $dataSection_NumProps++; + + // Title + if($this->_phpExcel->getProperties()->getTitle()){ + $dataProp = $this->_phpExcel->getProperties()->getTitle(); + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x02), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length + 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); + $dataSection_NumProps++; + } + // Subject + if($this->_phpExcel->getProperties()->getSubject()){ + $dataProp = $this->_phpExcel->getProperties()->getSubject(); + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x03), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length + 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); + $dataSection_NumProps++; + } + // Author (Creator) + if($this->_phpExcel->getProperties()->getCreator()){ + $dataProp = $this->_phpExcel->getProperties()->getCreator(); + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x04), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length + 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); + $dataSection_NumProps++; + } + // Keywords + if($this->_phpExcel->getProperties()->getKeywords()){ + $dataProp = $this->_phpExcel->getProperties()->getKeywords(); + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x05), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length + 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); + $dataSection_NumProps++; + } + // Comments (Description) + if($this->_phpExcel->getProperties()->getDescription()){ + $dataProp = $this->_phpExcel->getProperties()->getDescription(); + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x06), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length + 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); + $dataSection_NumProps++; + } + // Last Saved By (LastModifiedBy) + if($this->_phpExcel->getProperties()->getLastModifiedBy()){ + $dataProp = $this->_phpExcel->getProperties()->getLastModifiedBy(); + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x08), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length + 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); + $dataSection_NumProps++; + } + // Created Date/Time + if($this->_phpExcel->getProperties()->getCreated()){ + $dataProp = $this->_phpExcel->getProperties()->getCreated(); + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x0C), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x40), // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) + 'data' => array('data' => PHPExcel_Shared_OLE::LocalDate2OLE($dataProp))); + $dataSection_NumProps++; + } + // Modified Date/Time + if($this->_phpExcel->getProperties()->getModified()){ + $dataProp = $this->_phpExcel->getProperties()->getModified(); + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x0D), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x40), // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) + 'data' => array('data' => PHPExcel_Shared_OLE::LocalDate2OLE($dataProp))); + $dataSection_NumProps++; + } + // Security + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x13), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x03), // 4 byte signed integer + 'data' => array('data' => 0x00)); + $dataSection_NumProps++; + + + // 4 Section Length + // 4 Property count + // 8 * $dataSection_NumProps (8 = ID (4) + OffSet(4)) + $dataSection_Content_Offset = 8 + $dataSection_NumProps * 8; + foreach ($dataSection as $dataProp){ + // Summary + $dataSection_Summary .= pack($dataProp['summary']['pack'], $dataProp['summary']['data']); + // Offset + $dataSection_Summary .= pack($dataProp['offset']['pack'], $dataSection_Content_Offset); + // DataType + $dataSection_Content .= pack($dataProp['type']['pack'], $dataProp['type']['data']); + // Data + if($dataProp['type']['data'] == 0x02){ // 2 byte signed integer + $dataSection_Content .= pack('V', $dataProp['data']['data']); + + $dataSection_Content_Offset += 4 + 4; + } + elseif($dataProp['type']['data'] == 0x03){ // 4 byte signed integer + $dataSection_Content .= pack('V', $dataProp['data']['data']); + + $dataSection_Content_Offset += 4 + 4; + } + elseif($dataProp['type']['data'] == 0x1E){ // null-terminated string prepended by dword string length + // Null-terminated string + $dataProp['data']['data'] .= chr(0); + $dataProp['data']['length'] += 1; + // Complete the string with null string for being a %4 + $dataProp['data']['length'] = $dataProp['data']['length'] + ((4 - $dataProp['data']['length'] % 4)==4 ? 0 : (4 - $dataProp['data']['length'] % 4)); + $dataProp['data']['data'] = str_pad($dataProp['data']['data'], $dataProp['data']['length'], chr(0), STR_PAD_RIGHT); + + $dataSection_Content .= pack('V', $dataProp['data']['length']); + $dataSection_Content .= $dataProp['data']['data']; + + $dataSection_Content_Offset += 4 + 4 + strlen($dataProp['data']['data']); + } + elseif($dataProp['type']['data'] == 0x40){ // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) + $dataSection_Content .= $dataProp['data']['data']; + + $dataSection_Content_Offset += 4 + 8; + } + else { + // Data Type Not Used at the moment + } + } + // Now $dataSection_Content_Offset contains the size of the content + + // section header + // offset: $secOffset; size: 4; section length + // + x Size of the content (summary + content) + $data .= pack('V', $dataSection_Content_Offset); + // offset: $secOffset+4; size: 4; property count + $data .= pack('V', $dataSection_NumProps); + // Section Summary + $data .= $dataSection_Summary; + // Section Content + $data .= $dataSection_Content; + + return $data; + } +} diff --git a/lib/phpexcel/PHPExcel/Writer/Excel5/BIFFwriter.php b/lib/phpexcel/PHPExcel/Writer/Excel5/BIFFwriter.php new file mode 100644 index 0000000..b3e48bc --- /dev/null +++ b/lib/phpexcel/PHPExcel/Writer/Excel5/BIFFwriter.php @@ -0,0 +1,255 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel5 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + +// Original file header of PEAR::Spreadsheet_Excel_Writer_BIFFwriter (used as the base for this class): +// ----------------------------------------------------------------------------------------- +// * Module written/ported by Xavier Noguer <xnoguer@rezebra.com> +// * +// * The majority of this is _NOT_ my code. I simply ported it from the +// * PERL Spreadsheet::WriteExcel module. +// * +// * The author of the Spreadsheet::WriteExcel module is John McNamara +// * <jmcnamara@cpan.org> +// * +// * I _DO_ maintain this code, and John McNamara has nothing to do with the +// * porting of this code to PHP. Any questions directly related to this +// * class library should be directed to me. +// * +// * License Information: +// * +// * Spreadsheet_Excel_Writer: A library for generating Excel Spreadsheets +// * Copyright (c) 2002-2003 Xavier Noguer xnoguer@rezebra.com +// * +// * This library is free software; you can redistribute it and/or +// * modify it under the terms of the GNU Lesser General Public +// * License as published by the Free Software Foundation; either +// * version 2.1 of the License, or (at your option) any later version. +// * +// * This library is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// * Lesser General Public License for more details. +// * +// * You should have received a copy of the GNU Lesser General Public +// * License along with this library; if not, write to the Free Software +// * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// */ + + +/** + * PHPExcel_Writer_Excel5_BIFFwriter + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel5 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_Excel5_BIFFwriter +{ + /** + * The byte order of this architecture. 0 => little endian, 1 => big endian + * @var integer + */ + private static $_byte_order; + + /** + * The string containing the data of the BIFF stream + * @var string + */ + public $_data; + + /** + * The size of the data in bytes. Should be the same as strlen($this->_data) + * @var integer + */ + public $_datasize; + + /** + * The maximum length for a BIFF record (excluding record header and length field). See _addContinue() + * @var integer + * @see _addContinue() + */ + public $_limit = 8224; + + /** + * Constructor + */ + public function __construct() + { + $this->_data = ''; + $this->_datasize = 0; +// $this->_limit = 8224; + } + + /** + * Determine the byte order and store it as class data to avoid + * recalculating it for each call to new(). + * + * @return int + */ + public static function getByteOrder() + { + if (!isset(self::$_byte_order)) { + // Check if "pack" gives the required IEEE 64bit float + $teststr = pack("d", 1.2345); + $number = pack("C8", 0x8D, 0x97, 0x6E, 0x12, 0x83, 0xC0, 0xF3, 0x3F); + if ($number == $teststr) { + $byte_order = 0; // Little Endian + } elseif ($number == strrev($teststr)){ + $byte_order = 1; // Big Endian + } else { + // Give up. I'll fix this in a later version. + throw new PHPExcel_Writer_Exception("Required floating point format not supported on this platform."); + } + self::$_byte_order = $byte_order; + } + + return self::$_byte_order; + } + + /** + * General storage function + * + * @param string $data binary data to append + * @access private + */ + function _append($data) + { + if (strlen($data) - 4 > $this->_limit) { + $data = $this->_addContinue($data); + } + $this->_data .= $data; + $this->_datasize += strlen($data); + } + + /** + * General storage function like _append, but returns string instead of modifying $this->_data + * + * @param string $data binary data to write + * @return string + */ + public function writeData($data) + { + if (strlen($data) - 4 > $this->_limit) { + $data = $this->_addContinue($data); + } + $this->_datasize += strlen($data); + + return $data; + } + + /** + * Writes Excel BOF record to indicate the beginning of a stream or + * sub-stream in the BIFF file. + * + * @param integer $type Type of BIFF file to write: 0x0005 Workbook, + * 0x0010 Worksheet. + * @access private + */ + function _storeBof($type) + { + $record = 0x0809; // Record identifier (BIFF5-BIFF8) + $length = 0x0010; + + // by inspection of real files, MS Office Excel 2007 writes the following + $unknown = pack("VV", 0x000100D1, 0x00000406); + + $build = 0x0DBB; // Excel 97 + $year = 0x07CC; // Excel 97 + + $version = 0x0600; // BIFF8 + + $header = pack("vv", $record, $length); + $data = pack("vvvv", $version, $type, $build, $year); + $this->_append($header . $data . $unknown); + } + + /** + * Writes Excel EOF record to indicate the end of a BIFF stream. + * + * @access private + */ + function _storeEof() + { + $record = 0x000A; // Record identifier + $length = 0x0000; // Number of bytes to follow + + $header = pack("vv", $record, $length); + $this->_append($header); + } + + /** + * Writes Excel EOF record to indicate the end of a BIFF stream. + * + * @access private + */ + public function writeEof() + { + $record = 0x000A; // Record identifier + $length = 0x0000; // Number of bytes to follow + $header = pack("vv", $record, $length); + return $this->writeData($header); + } + + /** + * Excel limits the size of BIFF records. In Excel 5 the limit is 2084 bytes. In + * Excel 97 the limit is 8228 bytes. Records that are longer than these limits + * must be split up into CONTINUE blocks. + * + * This function takes a long BIFF record and inserts CONTINUE records as + * necessary. + * + * @param string $data The original binary data to be written + * @return string A very convenient string of continue blocks + * @access private + */ + function _addContinue($data) + { + $limit = $this->_limit; + $record = 0x003C; // Record identifier + + // The first 2080/8224 bytes remain intact. However, we have to change + // the length field of the record. + $tmp = substr($data, 0, 2) . pack("v", $limit) . substr($data, 4, $limit); + + $header = pack("vv", $record, $limit); // Headers for continue records + + // Retrieve chunks of 2080/8224 bytes +4 for the header. + $data_length = strlen($data); + for ($i = $limit + 4; $i < ($data_length - $limit); $i += $limit) { + $tmp .= $header; + $tmp .= substr($data, $i, $limit); + } + + // Retrieve the last chunk of data + $header = pack("vv", $record, strlen($data) - $i); + $tmp .= $header; + $tmp .= substr($data, $i, strlen($data) - $i); + + return $tmp; + } + +} diff --git a/lib/phpexcel/PHPExcel/Writer/Excel5/Escher.php b/lib/phpexcel/PHPExcel/Writer/Excel5/Escher.php new file mode 100644 index 0000000..7e9b73a --- /dev/null +++ b/lib/phpexcel/PHPExcel/Writer/Excel5/Escher.php @@ -0,0 +1,537 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel5 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Shared_Escher_DggContainer_BstoreContainer + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel5 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_Excel5_Escher +{ + /** + * The object we are writing + */ + private $_object; + + /** + * The written binary data + */ + private $_data; + + /** + * Shape offsets. Positions in binary stream where a new shape record begins + * + * @var array + */ + private $_spOffsets; + + /** + * Shape types. + * + * @var array + */ + private $_spTypes; + + /** + * Constructor + * + * @param mixed + */ + public function __construct($object) + { + $this->_object = $object; + } + + /** + * Process the object to be written + */ + public function close() + { + // initialize + $this->_data = ''; + + switch (get_class($this->_object)) { + + case 'PHPExcel_Shared_Escher': + if ($dggContainer = $this->_object->getDggContainer()) { + $writer = new PHPExcel_Writer_Excel5_Escher($dggContainer); + $this->_data = $writer->close(); + } else if ($dgContainer = $this->_object->getDgContainer()) { + $writer = new PHPExcel_Writer_Excel5_Escher($dgContainer); + $this->_data = $writer->close(); + $this->_spOffsets = $writer->getSpOffsets(); + $this->_spTypes = $writer->getSpTypes(); + } + break; + + case 'PHPExcel_Shared_Escher_DggContainer': + // this is a container record + + // initialize + $innerData = ''; + + // write the dgg + $recVer = 0x0; + $recInstance = 0x0000; + $recType = 0xF006; + + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; + + // dgg data + $dggData = + pack('VVVV' + , $this->_object->getSpIdMax() // maximum shape identifier increased by one + , $this->_object->getCDgSaved() + 1 // number of file identifier clusters increased by one + , $this->_object->getCSpSaved() + , $this->_object->getCDgSaved() // count total number of drawings saved + ); + + // add file identifier clusters (one per drawing) + $IDCLs = $this->_object->getIDCLs(); + + foreach ($IDCLs as $dgId => $maxReducedSpId) { + $dggData .= pack('VV', $dgId, $maxReducedSpId + 1); + } + + $header = pack('vvV', $recVerInstance, $recType, strlen($dggData)); + $innerData .= $header . $dggData; + + // write the bstoreContainer + if ($bstoreContainer = $this->_object->getBstoreContainer()) { + $writer = new PHPExcel_Writer_Excel5_Escher($bstoreContainer); + $innerData .= $writer->close(); + } + + // write the record + $recVer = 0xF; + $recInstance = 0x0000; + $recType = 0xF000; + $length = strlen($innerData); + + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; + + $header = pack('vvV', $recVerInstance, $recType, $length); + + $this->_data = $header . $innerData; + break; + + case 'PHPExcel_Shared_Escher_DggContainer_BstoreContainer': + // this is a container record + + // initialize + $innerData = ''; + + // treat the inner data + if ($BSECollection = $this->_object->getBSECollection()) { + foreach ($BSECollection as $BSE) { + $writer = new PHPExcel_Writer_Excel5_Escher($BSE); + $innerData .= $writer->close(); + } + } + + // write the record + $recVer = 0xF; + $recInstance = count($this->_object->getBSECollection()); + $recType = 0xF001; + $length = strlen($innerData); + + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; + + $header = pack('vvV', $recVerInstance, $recType, $length); + + $this->_data = $header . $innerData; + break; + + case 'PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE': + // this is a semi-container record + + // initialize + $innerData = ''; + + // here we treat the inner data + if ($blip = $this->_object->getBlip()) { + $writer = new PHPExcel_Writer_Excel5_Escher($blip); + $innerData .= $writer->close(); + } + + // initialize + $data = ''; + + $btWin32 = $this->_object->getBlipType(); + $btMacOS = $this->_object->getBlipType(); + $data .= pack('CC', $btWin32, $btMacOS); + + $rgbUid = pack('VVVV', 0,0,0,0); // todo + $data .= $rgbUid; + + $tag = 0; + $size = strlen($innerData); + $cRef = 1; + $foDelay = 0; //todo + $unused1 = 0x0; + $cbName = 0x0; + $unused2 = 0x0; + $unused3 = 0x0; + $data .= pack('vVVVCCCC', $tag, $size, $cRef, $foDelay, $unused1, $cbName, $unused2, $unused3); + + $data .= $innerData; + + // write the record + $recVer = 0x2; + $recInstance = $this->_object->getBlipType(); + $recType = 0xF007; + $length = strlen($data); + + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; + + $header = pack('vvV', $recVerInstance, $recType, $length); + + $this->_data = $header; + + $this->_data .= $data; + break; + + case 'PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip': + // this is an atom record + + // write the record + switch ($this->_object->getParent()->getBlipType()) { + + case PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_JPEG: + // initialize + $innerData = ''; + + $rgbUid1 = pack('VVVV', 0,0,0,0); // todo + $innerData .= $rgbUid1; + + $tag = 0xFF; // todo + $innerData .= pack('C', $tag); + + $innerData .= $this->_object->getData(); + + $recVer = 0x0; + $recInstance = 0x46A; + $recType = 0xF01D; + $length = strlen($innerData); + + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; + + $header = pack('vvV', $recVerInstance, $recType, $length); + + $this->_data = $header; + + $this->_data .= $innerData; + break; + + case PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG: + // initialize + $innerData = ''; + + $rgbUid1 = pack('VVVV', 0,0,0,0); // todo + $innerData .= $rgbUid1; + + $tag = 0xFF; // todo + $innerData .= pack('C', $tag); + + $innerData .= $this->_object->getData(); + + $recVer = 0x0; + $recInstance = 0x6E0; + $recType = 0xF01E; + $length = strlen($innerData); + + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; + + $header = pack('vvV', $recVerInstance, $recType, $length); + + $this->_data = $header; + + $this->_data .= $innerData; + break; + + } + break; + + case 'PHPExcel_Shared_Escher_DgContainer': + // this is a container record + + // initialize + $innerData = ''; + + // write the dg + $recVer = 0x0; + $recInstance = $this->_object->getDgId(); + $recType = 0xF008; + $length = 8; + + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; + + $header = pack('vvV', $recVerInstance, $recType, $length); + + // number of shapes in this drawing (including group shape) + $countShapes = count($this->_object->getSpgrContainer()->getChildren()); + $innerData .= $header . pack('VV', $countShapes, $this->_object->getLastSpId()); + //$innerData .= $header . pack('VV', 0, 0); + + // write the spgrContainer + if ($spgrContainer = $this->_object->getSpgrContainer()) { + $writer = new PHPExcel_Writer_Excel5_Escher($spgrContainer); + $innerData .= $writer->close(); + + // get the shape offsets relative to the spgrContainer record + $spOffsets = $writer->getSpOffsets(); + $spTypes = $writer->getSpTypes(); + + // save the shape offsets relative to dgContainer + foreach ($spOffsets as & $spOffset) { + $spOffset += 24; // add length of dgContainer header data (8 bytes) plus dg data (16 bytes) + } + + $this->_spOffsets = $spOffsets; + $this->_spTypes = $spTypes; + } + + // write the record + $recVer = 0xF; + $recInstance = 0x0000; + $recType = 0xF002; + $length = strlen($innerData); + + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; + + $header = pack('vvV', $recVerInstance, $recType, $length); + + $this->_data = $header . $innerData; + break; + + case 'PHPExcel_Shared_Escher_DgContainer_SpgrContainer': + // this is a container record + + // initialize + $innerData = ''; + + // initialize spape offsets + $totalSize = 8; + $spOffsets = array(); + $spTypes = array(); + + // treat the inner data + foreach ($this->_object->getChildren() as $spContainer) { + $writer = new PHPExcel_Writer_Excel5_Escher($spContainer); + $spData = $writer->close(); + $innerData .= $spData; + + // save the shape offsets (where new shape records begin) + $totalSize += strlen($spData); + $spOffsets[] = $totalSize; + + $spTypes = array_merge($spTypes, $writer->getSpTypes()); + } + + // write the record + $recVer = 0xF; + $recInstance = 0x0000; + $recType = 0xF003; + $length = strlen($innerData); + + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; + + $header = pack('vvV', $recVerInstance, $recType, $length); + + $this->_data = $header . $innerData; + $this->_spOffsets = $spOffsets; + $this->_spTypes = $spTypes; + break; + + case 'PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer': + // initialize + $data = ''; + + // build the data + + // write group shape record, if necessary? + if ($this->_object->getSpgr()) { + $recVer = 0x1; + $recInstance = 0x0000; + $recType = 0xF009; + $length = 0x00000010; + + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; + + $header = pack('vvV', $recVerInstance, $recType, $length); + + $data .= $header . pack('VVVV', 0,0,0,0); + } + $this->_spTypes[] = ($this->_object->getSpType()); + + // write the shape record + $recVer = 0x2; + $recInstance = $this->_object->getSpType(); // shape type + $recType = 0xF00A; + $length = 0x00000008; + + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; + + $header = pack('vvV', $recVerInstance, $recType, $length); + + $data .= $header . pack('VV', $this->_object->getSpId(), $this->_object->getSpgr() ? 0x0005 : 0x0A00); + + + // the options + if ($this->_object->getOPTCollection()) { + $optData = ''; + + $recVer = 0x3; + $recInstance = count($this->_object->getOPTCollection()); + $recType = 0xF00B; + foreach ($this->_object->getOPTCollection() as $property => $value) { + $optData .= pack('vV', $property, $value); + } + $length = strlen($optData); + + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; + + $header = pack('vvV', $recVerInstance, $recType, $length); + $data .= $header . $optData; + } + + // the client anchor + if ($this->_object->getStartCoordinates()) { + $clientAnchorData = ''; + + $recVer = 0x0; + $recInstance = 0x0; + $recType = 0xF010; + + // start coordinates + list($column, $row) = PHPExcel_Cell::coordinateFromString($this->_object->getStartCoordinates()); + $c1 = PHPExcel_Cell::columnIndexFromString($column) - 1; + $r1 = $row - 1; + + // start offsetX + $startOffsetX = $this->_object->getStartOffsetX(); + + // start offsetY + $startOffsetY = $this->_object->getStartOffsetY(); + + // end coordinates + list($column, $row) = PHPExcel_Cell::coordinateFromString($this->_object->getEndCoordinates()); + $c2 = PHPExcel_Cell::columnIndexFromString($column) - 1; + $r2 = $row - 1; + + // end offsetX + $endOffsetX = $this->_object->getEndOffsetX(); + + // end offsetY + $endOffsetY = $this->_object->getEndOffsetY(); + + $clientAnchorData = pack('vvvvvvvvv', $this->_object->getSpFlag(), + $c1, $startOffsetX, $r1, $startOffsetY, + $c2, $endOffsetX, $r2, $endOffsetY); + + $length = strlen($clientAnchorData); + + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; + + $header = pack('vvV', $recVerInstance, $recType, $length); + $data .= $header . $clientAnchorData; + } + + // the client data, just empty for now + if (!$this->_object->getSpgr()) { + $clientDataData = ''; + + $recVer = 0x0; + $recInstance = 0x0; + $recType = 0xF011; + + $length = strlen($clientDataData); + + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; + + $header = pack('vvV', $recVerInstance, $recType, $length); + $data .= $header . $clientDataData; + } + + // write the record + $recVer = 0xF; + $recInstance = 0x0000; + $recType = 0xF004; + $length = strlen($data); + + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; + + $header = pack('vvV', $recVerInstance, $recType, $length); + + $this->_data = $header . $data; + break; + + } + + return $this->_data; + } + + /** + * Gets the shape offsets + * + * @return array + */ + public function getSpOffsets() + { + return $this->_spOffsets; + } + + /** + * Gets the shape types + * + * @return array + */ + public function getSpTypes() + { + return $this->_spTypes; + } + + +} diff --git a/lib/phpexcel/PHPExcel/Writer/Excel5/Font.php b/lib/phpexcel/PHPExcel/Writer/Excel5/Font.php new file mode 100644 index 0000000..f2dbab2 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Writer/Excel5/Font.php @@ -0,0 +1,165 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel5 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Writer_Excel5_Font + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel5 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_Excel5_Font +{ + /** + * Color index + * + * @var int + */ + private $_colorIndex; + + /** + * Font + * + * @var PHPExcel_Style_Font + */ + private $_font; + + /** + * Constructor + * + * @param PHPExcel_Style_Font $font + */ + public function __construct(PHPExcel_Style_Font $font = null) + { + $this->_colorIndex = 0x7FFF; + $this->_font = $font; + } + + /** + * Set the color index + * + * @param int $colorIndex + */ + public function setColorIndex($colorIndex) + { + $this->_colorIndex = $colorIndex; + } + + /** + * Get font record data + * + * @return string + */ + public function writeFont() + { + $font_outline = 0; + $font_shadow = 0; + + $icv = $this->_colorIndex; // Index to color palette + if ($this->_font->getSuperScript()) { + $sss = 1; + } else if ($this->_font->getSubScript()) { + $sss = 2; + } else { + $sss = 0; + } + $bFamily = 0; // Font family + $bCharSet = PHPExcel_Shared_Font::getCharsetFromFontName($this->_font->getName()); // Character set + + $record = 0x31; // Record identifier + $reserved = 0x00; // Reserved + $grbit = 0x00; // Font attributes + if ($this->_font->getItalic()) { + $grbit |= 0x02; + } + if ($this->_font->getStrikethrough()) { + $grbit |= 0x08; + } + if ($font_outline) { + $grbit |= 0x10; + } + if ($font_shadow) { + $grbit |= 0x20; + } + + $data = pack("vvvvvCCCC", + $this->_font->getSize() * 20, // Fontsize (in twips) + $grbit, + $icv, // Colour + self::_mapBold($this->_font->getBold()), // Font weight + $sss, // Superscript/Subscript + self::_mapUnderline($this->_font->getUnderline()), + $bFamily, + $bCharSet, + $reserved + ); + $data .= PHPExcel_Shared_String::UTF8toBIFF8UnicodeShort($this->_font->getName()); + + $length = strlen($data); + $header = pack("vv", $record, $length); + + return($header . $data); + } + + /** + * Map to BIFF5-BIFF8 codes for bold + * + * @param boolean $bold + * @return int + */ + private static function _mapBold($bold) { + if ($bold) { + return 0x2BC; // 700 = Bold font weight + } + return 0x190; // 400 = Normal font weight + } + + /** + * Map of BIFF2-BIFF8 codes for underline styles + * @static array of int + * + */ + private static $_mapUnderline = array( PHPExcel_Style_Font::UNDERLINE_NONE => 0x00, + PHPExcel_Style_Font::UNDERLINE_SINGLE => 0x01, + PHPExcel_Style_Font::UNDERLINE_DOUBLE => 0x02, + PHPExcel_Style_Font::UNDERLINE_SINGLEACCOUNTING => 0x21, + PHPExcel_Style_Font::UNDERLINE_DOUBLEACCOUNTING => 0x22, + ); + /** + * Map underline + * + * @param string + * @return int + */ + private static function _mapUnderline($underline) { + if (isset(self::$_mapUnderline[$underline])) + return self::$_mapUnderline[$underline]; + return 0x00; + } + +} diff --git a/lib/phpexcel/PHPExcel/Writer/Excel5/Parser.php b/lib/phpexcel/PHPExcel/Writer/Excel5/Parser.php new file mode 100644 index 0000000..04e674a --- /dev/null +++ b/lib/phpexcel/PHPExcel/Writer/Excel5/Parser.php @@ -0,0 +1,1582 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel5 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + +// Original file header of PEAR::Spreadsheet_Excel_Writer_Parser (used as the base for this class): +// ----------------------------------------------------------------------------------------- +// * Class for parsing Excel formulas +// * +// * License Information: +// * +// * Spreadsheet_Excel_Writer: A library for generating Excel Spreadsheets +// * Copyright (c) 2002-2003 Xavier Noguer xnoguer@rezebra.com +// * +// * This library is free software; you can redistribute it and/or +// * modify it under the terms of the GNU Lesser General Public +// * License as published by the Free Software Foundation; either +// * version 2.1 of the License, or (at your option) any later version. +// * +// * This library is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// * Lesser General Public License for more details. +// * +// * You should have received a copy of the GNU Lesser General Public +// * License along with this library; if not, write to the Free Software +// * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// */ + + +/** + * PHPExcel_Writer_Excel5_Parser + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel5 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_Excel5_Parser +{ + /** Constants */ + // Sheet title in unquoted form + // Invalid sheet title characters cannot occur in the sheet title: + // *:/\?[] + // Moreover, there are valid sheet title characters that cannot occur in unquoted form (there may be more?) + // +-% '^&<>=,;#()"{} + const REGEX_SHEET_TITLE_UNQUOTED = '[^\*\:\/\\\\\?\[\]\+\-\% \\\'\^\&\<\>\=\,\;\#\(\)\"\{\}]+'; + + // Sheet title in quoted form (without surrounding quotes) + // Invalid sheet title characters cannot occur in the sheet title: + // *:/\?[] (usual invalid sheet title characters) + // Single quote is represented as a pair '' + const REGEX_SHEET_TITLE_QUOTED = '(([^\*\:\/\\\\\?\[\]\\\'])+|(\\\'\\\')+)+'; + + /** + * The index of the character we are currently looking at + * @var integer + */ + public $_current_char; + + /** + * The token we are working on. + * @var string + */ + public $_current_token; + + /** + * The formula to parse + * @var string + */ + public $_formula; + + /** + * The character ahead of the current char + * @var string + */ + public $_lookahead; + + /** + * The parse tree to be generated + * @var string + */ + public $_parse_tree; + + /** + * Array of external sheets + * @var array + */ + public $_ext_sheets; + + /** + * Array of sheet references in the form of REF structures + * @var array + */ + public $_references; + + /** + * The class constructor + * + */ + public function __construct() + { + $this->_current_char = 0; + $this->_current_token = ''; // The token we are working on. + $this->_formula = ''; // The formula to parse. + $this->_lookahead = ''; // The character ahead of the current char. + $this->_parse_tree = ''; // The parse tree to be generated. + $this->_initializeHashes(); // Initialize the hashes: ptg's and function's ptg's + $this->_ext_sheets = array(); + $this->_references = array(); + } + + /** + * Initialize the ptg and function hashes. + * + * @access private + */ + function _initializeHashes() + { + // The Excel ptg indices + $this->ptg = array( + 'ptgExp' => 0x01, + 'ptgTbl' => 0x02, + 'ptgAdd' => 0x03, + 'ptgSub' => 0x04, + 'ptgMul' => 0x05, + 'ptgDiv' => 0x06, + 'ptgPower' => 0x07, + 'ptgConcat' => 0x08, + 'ptgLT' => 0x09, + 'ptgLE' => 0x0A, + 'ptgEQ' => 0x0B, + 'ptgGE' => 0x0C, + 'ptgGT' => 0x0D, + 'ptgNE' => 0x0E, + 'ptgIsect' => 0x0F, + 'ptgUnion' => 0x10, + 'ptgRange' => 0x11, + 'ptgUplus' => 0x12, + 'ptgUminus' => 0x13, + 'ptgPercent' => 0x14, + 'ptgParen' => 0x15, + 'ptgMissArg' => 0x16, + 'ptgStr' => 0x17, + 'ptgAttr' => 0x19, + 'ptgSheet' => 0x1A, + 'ptgEndSheet' => 0x1B, + 'ptgErr' => 0x1C, + 'ptgBool' => 0x1D, + 'ptgInt' => 0x1E, + 'ptgNum' => 0x1F, + 'ptgArray' => 0x20, + 'ptgFunc' => 0x21, + 'ptgFuncVar' => 0x22, + 'ptgName' => 0x23, + 'ptgRef' => 0x24, + 'ptgArea' => 0x25, + 'ptgMemArea' => 0x26, + 'ptgMemErr' => 0x27, + 'ptgMemNoMem' => 0x28, + 'ptgMemFunc' => 0x29, + 'ptgRefErr' => 0x2A, + 'ptgAreaErr' => 0x2B, + 'ptgRefN' => 0x2C, + 'ptgAreaN' => 0x2D, + 'ptgMemAreaN' => 0x2E, + 'ptgMemNoMemN' => 0x2F, + 'ptgNameX' => 0x39, + 'ptgRef3d' => 0x3A, + 'ptgArea3d' => 0x3B, + 'ptgRefErr3d' => 0x3C, + 'ptgAreaErr3d' => 0x3D, + 'ptgArrayV' => 0x40, + 'ptgFuncV' => 0x41, + 'ptgFuncVarV' => 0x42, + 'ptgNameV' => 0x43, + 'ptgRefV' => 0x44, + 'ptgAreaV' => 0x45, + 'ptgMemAreaV' => 0x46, + 'ptgMemErrV' => 0x47, + 'ptgMemNoMemV' => 0x48, + 'ptgMemFuncV' => 0x49, + 'ptgRefErrV' => 0x4A, + 'ptgAreaErrV' => 0x4B, + 'ptgRefNV' => 0x4C, + 'ptgAreaNV' => 0x4D, + 'ptgMemAreaNV' => 0x4E, + 'ptgMemNoMemN' => 0x4F, + 'ptgFuncCEV' => 0x58, + 'ptgNameXV' => 0x59, + 'ptgRef3dV' => 0x5A, + 'ptgArea3dV' => 0x5B, + 'ptgRefErr3dV' => 0x5C, + 'ptgAreaErr3d' => 0x5D, + 'ptgArrayA' => 0x60, + 'ptgFuncA' => 0x61, + 'ptgFuncVarA' => 0x62, + 'ptgNameA' => 0x63, + 'ptgRefA' => 0x64, + 'ptgAreaA' => 0x65, + 'ptgMemAreaA' => 0x66, + 'ptgMemErrA' => 0x67, + 'ptgMemNoMemA' => 0x68, + 'ptgMemFuncA' => 0x69, + 'ptgRefErrA' => 0x6A, + 'ptgAreaErrA' => 0x6B, + 'ptgRefNA' => 0x6C, + 'ptgAreaNA' => 0x6D, + 'ptgMemAreaNA' => 0x6E, + 'ptgMemNoMemN' => 0x6F, + 'ptgFuncCEA' => 0x78, + 'ptgNameXA' => 0x79, + 'ptgRef3dA' => 0x7A, + 'ptgArea3dA' => 0x7B, + 'ptgRefErr3dA' => 0x7C, + 'ptgAreaErr3d' => 0x7D + ); + + // Thanks to Michael Meeks and Gnumeric for the initial arg values. + // + // The following hash was generated by "function_locale.pl" in the distro. + // Refer to function_locale.pl for non-English function names. + // + // The array elements are as follow: + // ptg: The Excel function ptg code. + // args: The number of arguments that the function takes: + // >=0 is a fixed number of arguments. + // -1 is a variable number of arguments. + // class: The reference, value or array class of the function args. + // vol: The function is volatile. + // + $this->_functions = array( + // function ptg args class vol + 'COUNT' => array( 0, -1, 0, 0 ), + 'IF' => array( 1, -1, 1, 0 ), + 'ISNA' => array( 2, 1, 1, 0 ), + 'ISERROR' => array( 3, 1, 1, 0 ), + 'SUM' => array( 4, -1, 0, 0 ), + 'AVERAGE' => array( 5, -1, 0, 0 ), + 'MIN' => array( 6, -1, 0, 0 ), + 'MAX' => array( 7, -1, 0, 0 ), + 'ROW' => array( 8, -1, 0, 0 ), + 'COLUMN' => array( 9, -1, 0, 0 ), + 'NA' => array( 10, 0, 0, 0 ), + 'NPV' => array( 11, -1, 1, 0 ), + 'STDEV' => array( 12, -1, 0, 0 ), + 'DOLLAR' => array( 13, -1, 1, 0 ), + 'FIXED' => array( 14, -1, 1, 0 ), + 'SIN' => array( 15, 1, 1, 0 ), + 'COS' => array( 16, 1, 1, 0 ), + 'TAN' => array( 17, 1, 1, 0 ), + 'ATAN' => array( 18, 1, 1, 0 ), + 'PI' => array( 19, 0, 1, 0 ), + 'SQRT' => array( 20, 1, 1, 0 ), + 'EXP' => array( 21, 1, 1, 0 ), + 'LN' => array( 22, 1, 1, 0 ), + 'LOG10' => array( 23, 1, 1, 0 ), + 'ABS' => array( 24, 1, 1, 0 ), + 'INT' => array( 25, 1, 1, 0 ), + 'SIGN' => array( 26, 1, 1, 0 ), + 'ROUND' => array( 27, 2, 1, 0 ), + 'LOOKUP' => array( 28, -1, 0, 0 ), + 'INDEX' => array( 29, -1, 0, 1 ), + 'REPT' => array( 30, 2, 1, 0 ), + 'MID' => array( 31, 3, 1, 0 ), + 'LEN' => array( 32, 1, 1, 0 ), + 'VALUE' => array( 33, 1, 1, 0 ), + 'TRUE' => array( 34, 0, 1, 0 ), + 'FALSE' => array( 35, 0, 1, 0 ), + 'AND' => array( 36, -1, 0, 0 ), + 'OR' => array( 37, -1, 0, 0 ), + 'NOT' => array( 38, 1, 1, 0 ), + 'MOD' => array( 39, 2, 1, 0 ), + 'DCOUNT' => array( 40, 3, 0, 0 ), + 'DSUM' => array( 41, 3, 0, 0 ), + 'DAVERAGE' => array( 42, 3, 0, 0 ), + 'DMIN' => array( 43, 3, 0, 0 ), + 'DMAX' => array( 44, 3, 0, 0 ), + 'DSTDEV' => array( 45, 3, 0, 0 ), + 'VAR' => array( 46, -1, 0, 0 ), + 'DVAR' => array( 47, 3, 0, 0 ), + 'TEXT' => array( 48, 2, 1, 0 ), + 'LINEST' => array( 49, -1, 0, 0 ), + 'TREND' => array( 50, -1, 0, 0 ), + 'LOGEST' => array( 51, -1, 0, 0 ), + 'GROWTH' => array( 52, -1, 0, 0 ), + 'PV' => array( 56, -1, 1, 0 ), + 'FV' => array( 57, -1, 1, 0 ), + 'NPER' => array( 58, -1, 1, 0 ), + 'PMT' => array( 59, -1, 1, 0 ), + 'RATE' => array( 60, -1, 1, 0 ), + 'MIRR' => array( 61, 3, 0, 0 ), + 'IRR' => array( 62, -1, 0, 0 ), + 'RAND' => array( 63, 0, 1, 1 ), + 'MATCH' => array( 64, -1, 0, 0 ), + 'DATE' => array( 65, 3, 1, 0 ), + 'TIME' => array( 66, 3, 1, 0 ), + 'DAY' => array( 67, 1, 1, 0 ), + 'MONTH' => array( 68, 1, 1, 0 ), + 'YEAR' => array( 69, 1, 1, 0 ), + 'WEEKDAY' => array( 70, -1, 1, 0 ), + 'HOUR' => array( 71, 1, 1, 0 ), + 'MINUTE' => array( 72, 1, 1, 0 ), + 'SECOND' => array( 73, 1, 1, 0 ), + 'NOW' => array( 74, 0, 1, 1 ), + 'AREAS' => array( 75, 1, 0, 1 ), + 'ROWS' => array( 76, 1, 0, 1 ), + 'COLUMNS' => array( 77, 1, 0, 1 ), + 'OFFSET' => array( 78, -1, 0, 1 ), + 'SEARCH' => array( 82, -1, 1, 0 ), + 'TRANSPOSE' => array( 83, 1, 1, 0 ), + 'TYPE' => array( 86, 1, 1, 0 ), + 'ATAN2' => array( 97, 2, 1, 0 ), + 'ASIN' => array( 98, 1, 1, 0 ), + 'ACOS' => array( 99, 1, 1, 0 ), + 'CHOOSE' => array( 100, -1, 1, 0 ), + 'HLOOKUP' => array( 101, -1, 0, 0 ), + 'VLOOKUP' => array( 102, -1, 0, 0 ), + 'ISREF' => array( 105, 1, 0, 0 ), + 'LOG' => array( 109, -1, 1, 0 ), + 'CHAR' => array( 111, 1, 1, 0 ), + 'LOWER' => array( 112, 1, 1, 0 ), + 'UPPER' => array( 113, 1, 1, 0 ), + 'PROPER' => array( 114, 1, 1, 0 ), + 'LEFT' => array( 115, -1, 1, 0 ), + 'RIGHT' => array( 116, -1, 1, 0 ), + 'EXACT' => array( 117, 2, 1, 0 ), + 'TRIM' => array( 118, 1, 1, 0 ), + 'REPLACE' => array( 119, 4, 1, 0 ), + 'SUBSTITUTE' => array( 120, -1, 1, 0 ), + 'CODE' => array( 121, 1, 1, 0 ), + 'FIND' => array( 124, -1, 1, 0 ), + 'CELL' => array( 125, -1, 0, 1 ), + 'ISERR' => array( 126, 1, 1, 0 ), + 'ISTEXT' => array( 127, 1, 1, 0 ), + 'ISNUMBER' => array( 128, 1, 1, 0 ), + 'ISBLANK' => array( 129, 1, 1, 0 ), + 'T' => array( 130, 1, 0, 0 ), + 'N' => array( 131, 1, 0, 0 ), + 'DATEVALUE' => array( 140, 1, 1, 0 ), + 'TIMEVALUE' => array( 141, 1, 1, 0 ), + 'SLN' => array( 142, 3, 1, 0 ), + 'SYD' => array( 143, 4, 1, 0 ), + 'DDB' => array( 144, -1, 1, 0 ), + 'INDIRECT' => array( 148, -1, 1, 1 ), + 'CALL' => array( 150, -1, 1, 0 ), + 'CLEAN' => array( 162, 1, 1, 0 ), + 'MDETERM' => array( 163, 1, 2, 0 ), + 'MINVERSE' => array( 164, 1, 2, 0 ), + 'MMULT' => array( 165, 2, 2, 0 ), + 'IPMT' => array( 167, -1, 1, 0 ), + 'PPMT' => array( 168, -1, 1, 0 ), + 'COUNTA' => array( 169, -1, 0, 0 ), + 'PRODUCT' => array( 183, -1, 0, 0 ), + 'FACT' => array( 184, 1, 1, 0 ), + 'DPRODUCT' => array( 189, 3, 0, 0 ), + 'ISNONTEXT' => array( 190, 1, 1, 0 ), + 'STDEVP' => array( 193, -1, 0, 0 ), + 'VARP' => array( 194, -1, 0, 0 ), + 'DSTDEVP' => array( 195, 3, 0, 0 ), + 'DVARP' => array( 196, 3, 0, 0 ), + 'TRUNC' => array( 197, -1, 1, 0 ), + 'ISLOGICAL' => array( 198, 1, 1, 0 ), + 'DCOUNTA' => array( 199, 3, 0, 0 ), + 'USDOLLAR' => array( 204, -1, 1, 0 ), + 'FINDB' => array( 205, -1, 1, 0 ), + 'SEARCHB' => array( 206, -1, 1, 0 ), + 'REPLACEB' => array( 207, 4, 1, 0 ), + 'LEFTB' => array( 208, -1, 1, 0 ), + 'RIGHTB' => array( 209, -1, 1, 0 ), + 'MIDB' => array( 210, 3, 1, 0 ), + 'LENB' => array( 211, 1, 1, 0 ), + 'ROUNDUP' => array( 212, 2, 1, 0 ), + 'ROUNDDOWN' => array( 213, 2, 1, 0 ), + 'ASC' => array( 214, 1, 1, 0 ), + 'DBCS' => array( 215, 1, 1, 0 ), + 'RANK' => array( 216, -1, 0, 0 ), + 'ADDRESS' => array( 219, -1, 1, 0 ), + 'DAYS360' => array( 220, -1, 1, 0 ), + 'TODAY' => array( 221, 0, 1, 1 ), + 'VDB' => array( 222, -1, 1, 0 ), + 'MEDIAN' => array( 227, -1, 0, 0 ), + 'SUMPRODUCT' => array( 228, -1, 2, 0 ), + 'SINH' => array( 229, 1, 1, 0 ), + 'COSH' => array( 230, 1, 1, 0 ), + 'TANH' => array( 231, 1, 1, 0 ), + 'ASINH' => array( 232, 1, 1, 0 ), + 'ACOSH' => array( 233, 1, 1, 0 ), + 'ATANH' => array( 234, 1, 1, 0 ), + 'DGET' => array( 235, 3, 0, 0 ), + 'INFO' => array( 244, 1, 1, 1 ), + 'DB' => array( 247, -1, 1, 0 ), + 'FREQUENCY' => array( 252, 2, 0, 0 ), + 'ERROR.TYPE' => array( 261, 1, 1, 0 ), + 'REGISTER.ID' => array( 267, -1, 1, 0 ), + 'AVEDEV' => array( 269, -1, 0, 0 ), + 'BETADIST' => array( 270, -1, 1, 0 ), + 'GAMMALN' => array( 271, 1, 1, 0 ), + 'BETAINV' => array( 272, -1, 1, 0 ), + 'BINOMDIST' => array( 273, 4, 1, 0 ), + 'CHIDIST' => array( 274, 2, 1, 0 ), + 'CHIINV' => array( 275, 2, 1, 0 ), + 'COMBIN' => array( 276, 2, 1, 0 ), + 'CONFIDENCE' => array( 277, 3, 1, 0 ), + 'CRITBINOM' => array( 278, 3, 1, 0 ), + 'EVEN' => array( 279, 1, 1, 0 ), + 'EXPONDIST' => array( 280, 3, 1, 0 ), + 'FDIST' => array( 281, 3, 1, 0 ), + 'FINV' => array( 282, 3, 1, 0 ), + 'FISHER' => array( 283, 1, 1, 0 ), + 'FISHERINV' => array( 284, 1, 1, 0 ), + 'FLOOR' => array( 285, 2, 1, 0 ), + 'GAMMADIST' => array( 286, 4, 1, 0 ), + 'GAMMAINV' => array( 287, 3, 1, 0 ), + 'CEILING' => array( 288, 2, 1, 0 ), + 'HYPGEOMDIST' => array( 289, 4, 1, 0 ), + 'LOGNORMDIST' => array( 290, 3, 1, 0 ), + 'LOGINV' => array( 291, 3, 1, 0 ), + 'NEGBINOMDIST' => array( 292, 3, 1, 0 ), + 'NORMDIST' => array( 293, 4, 1, 0 ), + 'NORMSDIST' => array( 294, 1, 1, 0 ), + 'NORMINV' => array( 295, 3, 1, 0 ), + 'NORMSINV' => array( 296, 1, 1, 0 ), + 'STANDARDIZE' => array( 297, 3, 1, 0 ), + 'ODD' => array( 298, 1, 1, 0 ), + 'PERMUT' => array( 299, 2, 1, 0 ), + 'POISSON' => array( 300, 3, 1, 0 ), + 'TDIST' => array( 301, 3, 1, 0 ), + 'WEIBULL' => array( 302, 4, 1, 0 ), + 'SUMXMY2' => array( 303, 2, 2, 0 ), + 'SUMX2MY2' => array( 304, 2, 2, 0 ), + 'SUMX2PY2' => array( 305, 2, 2, 0 ), + 'CHITEST' => array( 306, 2, 2, 0 ), + 'CORREL' => array( 307, 2, 2, 0 ), + 'COVAR' => array( 308, 2, 2, 0 ), + 'FORECAST' => array( 309, 3, 2, 0 ), + 'FTEST' => array( 310, 2, 2, 0 ), + 'INTERCEPT' => array( 311, 2, 2, 0 ), + 'PEARSON' => array( 312, 2, 2, 0 ), + 'RSQ' => array( 313, 2, 2, 0 ), + 'STEYX' => array( 314, 2, 2, 0 ), + 'SLOPE' => array( 315, 2, 2, 0 ), + 'TTEST' => array( 316, 4, 2, 0 ), + 'PROB' => array( 317, -1, 2, 0 ), + 'DEVSQ' => array( 318, -1, 0, 0 ), + 'GEOMEAN' => array( 319, -1, 0, 0 ), + 'HARMEAN' => array( 320, -1, 0, 0 ), + 'SUMSQ' => array( 321, -1, 0, 0 ), + 'KURT' => array( 322, -1, 0, 0 ), + 'SKEW' => array( 323, -1, 0, 0 ), + 'ZTEST' => array( 324, -1, 0, 0 ), + 'LARGE' => array( 325, 2, 0, 0 ), + 'SMALL' => array( 326, 2, 0, 0 ), + 'QUARTILE' => array( 327, 2, 0, 0 ), + 'PERCENTILE' => array( 328, 2, 0, 0 ), + 'PERCENTRANK' => array( 329, -1, 0, 0 ), + 'MODE' => array( 330, -1, 2, 0 ), + 'TRIMMEAN' => array( 331, 2, 0, 0 ), + 'TINV' => array( 332, 2, 1, 0 ), + 'CONCATENATE' => array( 336, -1, 1, 0 ), + 'POWER' => array( 337, 2, 1, 0 ), + 'RADIANS' => array( 342, 1, 1, 0 ), + 'DEGREES' => array( 343, 1, 1, 0 ), + 'SUBTOTAL' => array( 344, -1, 0, 0 ), + 'SUMIF' => array( 345, -1, 0, 0 ), + 'COUNTIF' => array( 346, 2, 0, 0 ), + 'COUNTBLANK' => array( 347, 1, 0, 0 ), + 'ISPMT' => array( 350, 4, 1, 0 ), + 'DATEDIF' => array( 351, 3, 1, 0 ), + 'DATESTRING' => array( 352, 1, 1, 0 ), + 'NUMBERSTRING' => array( 353, 2, 1, 0 ), + 'ROMAN' => array( 354, -1, 1, 0 ), + 'GETPIVOTDATA' => array( 358, -1, 0, 0 ), + 'HYPERLINK' => array( 359, -1, 1, 0 ), + 'PHONETIC' => array( 360, 1, 0, 0 ), + 'AVERAGEA' => array( 361, -1, 0, 0 ), + 'MAXA' => array( 362, -1, 0, 0 ), + 'MINA' => array( 363, -1, 0, 0 ), + 'STDEVPA' => array( 364, -1, 0, 0 ), + 'VARPA' => array( 365, -1, 0, 0 ), + 'STDEVA' => array( 366, -1, 0, 0 ), + 'VARA' => array( 367, -1, 0, 0 ), + 'BAHTTEXT' => array( 368, 1, 0, 0 ), + ); + } + + /** + * Convert a token to the proper ptg value. + * + * @access private + * @param mixed $token The token to convert. + * @return mixed the converted token on success + */ + function _convert($token) + { + if (preg_match("/\"([^\"]|\"\"){0,255}\"/", $token)) { + return $this->_convertString($token); + + } elseif (is_numeric($token)) { + return $this->_convertNumber($token); + + // match references like A1 or $A$1 + } elseif (preg_match('/^\$?([A-Ia-i]?[A-Za-z])\$?(\d+)$/',$token)) { + return $this->_convertRef2d($token); + + // match external references like Sheet1!A1 or Sheet1:Sheet2!A1 or Sheet1!$A$1 or Sheet1:Sheet2!$A$1 + } elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?[A-Ia-i]?[A-Za-z]\\$?(\d+)$/u",$token)) { + return $this->_convertRef3d($token); + + // match external references like 'Sheet1'!A1 or 'Sheet1:Sheet2'!A1 or 'Sheet1'!$A$1 or 'Sheet1:Sheet2'!$A$1 + } elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?[A-Ia-i]?[A-Za-z]\\$?(\d+)$/u",$token)) { + return $this->_convertRef3d($token); + + // match ranges like A1:B2 or $A$1:$B$2 + } elseif (preg_match('/^(\$)?[A-Ia-i]?[A-Za-z](\$)?(\d+)\:(\$)?[A-Ia-i]?[A-Za-z](\$)?(\d+)$/', $token)) { + return $this->_convertRange2d($token); + + // match external ranges like Sheet1!A1:B2 or Sheet1:Sheet2!A1:B2 or Sheet1!$A$1:$B$2 or Sheet1:Sheet2!$A$1:$B$2 + } elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?([A-Ia-i]?[A-Za-z])?\\$?(\d+)\:\\$?([A-Ia-i]?[A-Za-z])?\\$?(\d+)$/u",$token)) { + return $this->_convertRange3d($token); + + // match external ranges like 'Sheet1'!A1:B2 or 'Sheet1:Sheet2'!A1:B2 or 'Sheet1'!$A$1:$B$2 or 'Sheet1:Sheet2'!$A$1:$B$2 + } elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?([A-Ia-i]?[A-Za-z])?\\$?(\d+)\:\\$?([A-Ia-i]?[A-Za-z])?\\$?(\d+)$/u",$token)) { + return $this->_convertRange3d($token); + + // operators (including parentheses) + } elseif (isset($this->ptg[$token])) { + return pack("C", $this->ptg[$token]); + + // match error codes + } elseif (preg_match("/^#[A-Z0\/]{3,5}[!?]{1}$/", $token) or $token == '#N/A') { + return $this->_convertError($token); + + // commented so argument number can be processed correctly. See toReversePolish(). + /*elseif (preg_match("/[A-Z0-9\xc0-\xdc\.]+/",$token)) + { + return($this->_convertFunction($token,$this->_func_args)); + }*/ + + // if it's an argument, ignore the token (the argument remains) + } elseif ($token == 'arg') { + return ''; + } + + // TODO: use real error codes + throw new PHPExcel_Writer_Exception("Unknown token $token"); + } + + /** + * Convert a number token to ptgInt or ptgNum + * + * @access private + * @param mixed $num an integer or double for conversion to its ptg value + */ + function _convertNumber($num) + { + // Integer in the range 0..2**16-1 + if ((preg_match("/^\d+$/", $num)) and ($num <= 65535)) { + return pack("Cv", $this->ptg['ptgInt'], $num); + } else { // A float + if (PHPExcel_Writer_Excel5_BIFFwriter::getByteOrder()) { // if it's Big Endian + $num = strrev($num); + } + return pack("Cd", $this->ptg['ptgNum'], $num); + } + } + + /** + * Convert a string token to ptgStr + * + * @access private + * @param string $string A string for conversion to its ptg value. + * @return mixed the converted token on success + */ + function _convertString($string) + { + // chop away beggining and ending quotes + $string = substr($string, 1, strlen($string) - 2); + if (strlen($string) > 255) { + throw new PHPExcel_Writer_Exception("String is too long"); + } + + return pack('C', $this->ptg['ptgStr']) . PHPExcel_Shared_String::UTF8toBIFF8UnicodeShort($string); + } + + /** + * Convert a function to a ptgFunc or ptgFuncVarV depending on the number of + * args that it takes. + * + * @access private + * @param string $token The name of the function for convertion to ptg value. + * @param integer $num_args The number of arguments the function receives. + * @return string The packed ptg for the function + */ + function _convertFunction($token, $num_args) + { + $args = $this->_functions[$token][1]; +// $volatile = $this->_functions[$token][3]; + + // Fixed number of args eg. TIME($i,$j,$k). + if ($args >= 0) { + return pack("Cv", $this->ptg['ptgFuncV'], $this->_functions[$token][0]); + } + // Variable number of args eg. SUM($i,$j,$k, ..). + if ($args == -1) { + return pack("CCv", $this->ptg['ptgFuncVarV'], $num_args, $this->_functions[$token][0]); + } + } + + /** + * Convert an Excel range such as A1:D4 to a ptgRefV. + * + * @access private + * @param string $range An Excel range in the A1:A2 + * @param int $class + */ + function _convertRange2d($range, $class=0) + { + + // TODO: possible class value 0,1,2 check Formula.pm + // Split the range into 2 cell refs + if (preg_match('/^(\$)?([A-Ia-i]?[A-Za-z])(\$)?(\d+)\:(\$)?([A-Ia-i]?[A-Za-z])(\$)?(\d+)$/', $range)) { + list($cell1, $cell2) = explode(':', $range); + } else { + // TODO: use real error codes + throw new PHPExcel_Writer_Exception("Unknown range separator"); + } + + // Convert the cell references + list($row1, $col1) = $this->_cellToPackedRowcol($cell1); + list($row2, $col2) = $this->_cellToPackedRowcol($cell2); + + // The ptg value depends on the class of the ptg. + if ($class == 0) { + $ptgArea = pack("C", $this->ptg['ptgArea']); + } elseif ($class == 1) { + $ptgArea = pack("C", $this->ptg['ptgAreaV']); + } elseif ($class == 2) { + $ptgArea = pack("C", $this->ptg['ptgAreaA']); + } else { + // TODO: use real error codes + throw new PHPExcel_Writer_Exception("Unknown class $class"); + } + return $ptgArea . $row1 . $row2 . $col1. $col2; + } + + /** + * Convert an Excel 3d range such as "Sheet1!A1:D4" or "Sheet1:Sheet2!A1:D4" to + * a ptgArea3d. + * + * @access private + * @param string $token An Excel range in the Sheet1!A1:A2 format. + * @return mixed The packed ptgArea3d token on success. + */ + function _convertRange3d($token) + { +// $class = 0; // formulas like Sheet1!$A$1:$A$2 in list type data validation need this class (0x3B) + + // Split the ref at the ! symbol + list($ext_ref, $range) = explode('!', $token); + + // Convert the external reference part (different for BIFF8) + $ext_ref = $this->_getRefIndex($ext_ref); + + // Split the range into 2 cell refs + list($cell1, $cell2) = explode(':', $range); + + // Convert the cell references + if (preg_match("/^(\\$)?[A-Ia-i]?[A-Za-z](\\$)?(\d+)$/", $cell1)) { + list($row1, $col1) = $this->_cellToPackedRowcol($cell1); + list($row2, $col2) = $this->_cellToPackedRowcol($cell2); + } else { // It's a rows range (like 26:27) + list($row1, $col1, $row2, $col2) = $this->_rangeToPackedRange($cell1.':'.$cell2); + } + + // The ptg value depends on the class of the ptg. +// if ($class == 0) { + $ptgArea = pack("C", $this->ptg['ptgArea3d']); +// } elseif ($class == 1) { +// $ptgArea = pack("C", $this->ptg['ptgArea3dV']); +// } elseif ($class == 2) { +// $ptgArea = pack("C", $this->ptg['ptgArea3dA']); +// } else { +// throw new PHPExcel_Writer_Exception("Unknown class $class"); +// } + + return $ptgArea . $ext_ref . $row1 . $row2 . $col1. $col2; + } + + /** + * Convert an Excel reference such as A1, $B2, C$3 or $D$4 to a ptgRefV. + * + * @access private + * @param string $cell An Excel cell reference + * @return string The cell in packed() format with the corresponding ptg + */ + function _convertRef2d($cell) + { +// $class = 2; // as far as I know, this is magick. + + // Convert the cell reference + $cell_array = $this->_cellToPackedRowcol($cell); + list($row, $col) = $cell_array; + + // The ptg value depends on the class of the ptg. +// if ($class == 0) { +// $ptgRef = pack("C", $this->ptg['ptgRef']); +// } elseif ($class == 1) { +// $ptgRef = pack("C", $this->ptg['ptgRefV']); +// } elseif ($class == 2) { + $ptgRef = pack("C", $this->ptg['ptgRefA']); +// } else { +// // TODO: use real error codes +// throw new PHPExcel_Writer_Exception("Unknown class $class"); +// } + return $ptgRef.$row.$col; + } + + /** + * Convert an Excel 3d reference such as "Sheet1!A1" or "Sheet1:Sheet2!A1" to a + * ptgRef3d. + * + * @access private + * @param string $cell An Excel cell reference + * @return mixed The packed ptgRef3d token on success. + */ + function _convertRef3d($cell) + { +// $class = 2; // as far as I know, this is magick. + + // Split the ref at the ! symbol + list($ext_ref, $cell) = explode('!', $cell); + + // Convert the external reference part (different for BIFF8) + $ext_ref = $this->_getRefIndex($ext_ref); + + // Convert the cell reference part + list($row, $col) = $this->_cellToPackedRowcol($cell); + + // The ptg value depends on the class of the ptg. +// if ($class == 0) { +// $ptgRef = pack("C", $this->ptg['ptgRef3d']); +// } elseif ($class == 1) { +// $ptgRef = pack("C", $this->ptg['ptgRef3dV']); +// } elseif ($class == 2) { + $ptgRef = pack("C", $this->ptg['ptgRef3dA']); +// } else { +// throw new PHPExcel_Writer_Exception("Unknown class $class"); +// } + + return $ptgRef . $ext_ref. $row . $col; + } + + /** + * Convert an error code to a ptgErr + * + * @access private + * @param string $errorCode The error code for conversion to its ptg value + * @return string The error code ptgErr + */ + function _convertError($errorCode) + { + switch ($errorCode) { + case '#NULL!': return pack("C", 0x00); + case '#DIV/0!': return pack("C", 0x07); + case '#VALUE!': return pack("C", 0x0F); + case '#REF!': return pack("C", 0x17); + case '#NAME?': return pack("C", 0x1D); + case '#NUM!': return pack("C", 0x24); + case '#N/A': return pack("C", 0x2A); + } + return pack("C", 0xFF); + } + + /** + * Convert the sheet name part of an external reference, for example "Sheet1" or + * "Sheet1:Sheet2", to a packed structure. + * + * @access private + * @param string $ext_ref The name of the external reference + * @return string The reference index in packed() format + */ + function _packExtRef($ext_ref) + { + $ext_ref = preg_replace("/^'/", '', $ext_ref); // Remove leading ' if any. + $ext_ref = preg_replace("/'$/", '', $ext_ref); // Remove trailing ' if any. + + // Check if there is a sheet range eg., Sheet1:Sheet2. + if (preg_match("/:/", $ext_ref)) { + list($sheet_name1, $sheet_name2) = explode(':', $ext_ref); + + $sheet1 = $this->_getSheetIndex($sheet_name1); + if ($sheet1 == -1) { + throw new PHPExcel_Writer_Exception("Unknown sheet name $sheet_name1 in formula"); + } + $sheet2 = $this->_getSheetIndex($sheet_name2); + if ($sheet2 == -1) { + throw new PHPExcel_Writer_Exception("Unknown sheet name $sheet_name2 in formula"); + } + + // Reverse max and min sheet numbers if necessary + if ($sheet1 > $sheet2) { + list($sheet1, $sheet2) = array($sheet2, $sheet1); + } + } else { // Single sheet name only. + $sheet1 = $this->_getSheetIndex($ext_ref); + if ($sheet1 == -1) { + throw new PHPExcel_Writer_Exception("Unknown sheet name $ext_ref in formula"); + } + $sheet2 = $sheet1; + } + + // References are stored relative to 0xFFFF. + $offset = -1 - $sheet1; + + return pack('vdvv', $offset, 0x00, $sheet1, $sheet2); + } + + /** + * Look up the REF index that corresponds to an external sheet name + * (or range). If it doesn't exist yet add it to the workbook's references + * array. It assumes all sheet names given must exist. + * + * @access private + * @param string $ext_ref The name of the external reference + * @return mixed The reference index in packed() format on success + */ + function _getRefIndex($ext_ref) + { + $ext_ref = preg_replace("/^'/", '', $ext_ref); // Remove leading ' if any. + $ext_ref = preg_replace("/'$/", '', $ext_ref); // Remove trailing ' if any. + $ext_ref = str_replace('\'\'', '\'', $ext_ref); // Replace escaped '' with ' + + // Check if there is a sheet range eg., Sheet1:Sheet2. + if (preg_match("/:/", $ext_ref)) { + list($sheet_name1, $sheet_name2) = explode(':', $ext_ref); + + $sheet1 = $this->_getSheetIndex($sheet_name1); + if ($sheet1 == -1) { + throw new PHPExcel_Writer_Exception("Unknown sheet name $sheet_name1 in formula"); + } + $sheet2 = $this->_getSheetIndex($sheet_name2); + if ($sheet2 == -1) { + throw new PHPExcel_Writer_Exception("Unknown sheet name $sheet_name2 in formula"); + } + + // Reverse max and min sheet numbers if necessary + if ($sheet1 > $sheet2) { + list($sheet1, $sheet2) = array($sheet2, $sheet1); + } + } else { // Single sheet name only. + $sheet1 = $this->_getSheetIndex($ext_ref); + if ($sheet1 == -1) { + throw new PHPExcel_Writer_Exception("Unknown sheet name $ext_ref in formula"); + } + $sheet2 = $sheet1; + } + + // assume all references belong to this document + $supbook_index = 0x00; + $ref = pack('vvv', $supbook_index, $sheet1, $sheet2); + $total_references = count($this->_references); + $index = -1; + for ($i = 0; $i < $total_references; ++$i) { + if ($ref == $this->_references[$i]) { + $index = $i; + break; + } + } + // if REF was not found add it to references array + if ($index == -1) { + $this->_references[$total_references] = $ref; + $index = $total_references; + } + + return pack('v', $index); + } + + /** + * Look up the index that corresponds to an external sheet name. The hash of + * sheet names is updated by the addworksheet() method of the + * PHPExcel_Writer_Excel5_Workbook class. + * + * @access private + * @param string $sheet_name Sheet name + * @return integer The sheet index, -1 if the sheet was not found + */ + function _getSheetIndex($sheet_name) + { + if (!isset($this->_ext_sheets[$sheet_name])) { + return -1; + } else { + return $this->_ext_sheets[$sheet_name]; + } + } + + /** + * This method is used to update the array of sheet names. It is + * called by the addWorksheet() method of the + * PHPExcel_Writer_Excel5_Workbook class. + * + * @access public + * @see PHPExcel_Writer_Excel5_Workbook::addWorksheet() + * @param string $name The name of the worksheet being added + * @param integer $index The index of the worksheet being added + */ + function setExtSheet($name, $index) + { + $this->_ext_sheets[$name] = $index; + } + + /** + * pack() row and column into the required 3 or 4 byte format. + * + * @access private + * @param string $cell The Excel cell reference to be packed + * @return array Array containing the row and column in packed() format + */ + function _cellToPackedRowcol($cell) + { + $cell = strtoupper($cell); + list($row, $col, $row_rel, $col_rel) = $this->_cellToRowcol($cell); + if ($col >= 256) { + throw new PHPExcel_Writer_Exception("Column in: $cell greater than 255"); + } + if ($row >= 65536) { + throw new PHPExcel_Writer_Exception("Row in: $cell greater than 65536 "); + } + + // Set the high bits to indicate if row or col are relative. + $col |= $col_rel << 14; + $col |= $row_rel << 15; + $col = pack('v', $col); + + $row = pack('v', $row); + + return array($row, $col); + } + + /** + * pack() row range into the required 3 or 4 byte format. + * Just using maximum col/rows, which is probably not the correct solution + * + * @access private + * @param string $range The Excel range to be packed + * @return array Array containing (row1,col1,row2,col2) in packed() format + */ + function _rangeToPackedRange($range) + { + preg_match('/(\$)?(\d+)\:(\$)?(\d+)/', $range, $match); + // return absolute rows if there is a $ in the ref + $row1_rel = empty($match[1]) ? 1 : 0; + $row1 = $match[2]; + $row2_rel = empty($match[3]) ? 1 : 0; + $row2 = $match[4]; + // Convert 1-index to zero-index + --$row1; + --$row2; + // Trick poor inocent Excel + $col1 = 0; + $col2 = 65535; // FIXME: maximum possible value for Excel 5 (change this!!!) + + // FIXME: this changes for BIFF8 + if (($row1 >= 65536) or ($row2 >= 65536)) { + throw new PHPExcel_Writer_Exception("Row in: $range greater than 65536 "); + } + + // Set the high bits to indicate if rows are relative. + $col1 |= $row1_rel << 15; + $col2 |= $row2_rel << 15; + $col1 = pack('v', $col1); + $col2 = pack('v', $col2); + + $row1 = pack('v', $row1); + $row2 = pack('v', $row2); + + return array($row1, $col1, $row2, $col2); + } + + /** + * Convert an Excel cell reference such as A1 or $B2 or C$3 or $D$4 to a zero + * indexed row and column number. Also returns two (0,1) values to indicate + * whether the row or column are relative references. + * + * @access private + * @param string $cell The Excel cell reference in A1 format. + * @return array + */ + function _cellToRowcol($cell) + { + preg_match('/(\$)?([A-I]?[A-Z])(\$)?(\d+)/',$cell,$match); + // return absolute column if there is a $ in the ref + $col_rel = empty($match[1]) ? 1 : 0; + $col_ref = $match[2]; + $row_rel = empty($match[3]) ? 1 : 0; + $row = $match[4]; + + // Convert base26 column string to a number. + $expn = strlen($col_ref) - 1; + $col = 0; + $col_ref_length = strlen($col_ref); + for ($i = 0; $i < $col_ref_length; ++$i) { + $col += (ord($col_ref{$i}) - 64) * pow(26, $expn); + --$expn; + } + + // Convert 1-index to zero-index + --$row; + --$col; + + return array($row, $col, $row_rel, $col_rel); + } + + /** + * Advance to the next valid token. + * + * @access private + */ + function _advance() + { + $i = $this->_current_char; + $formula_length = strlen($this->_formula); + // eat up white spaces + if ($i < $formula_length) { + while ($this->_formula{$i} == " ") { + ++$i; + } + + if ($i < ($formula_length - 1)) { + $this->_lookahead = $this->_formula{$i+1}; + } + $token = ''; + } + + while ($i < $formula_length) { + $token .= $this->_formula{$i}; + + if ($i < ($formula_length - 1)) { + $this->_lookahead = $this->_formula{$i+1}; + } else { + $this->_lookahead = ''; + } + + if ($this->_match($token) != '') { + //if ($i < strlen($this->_formula) - 1) { + // $this->_lookahead = $this->_formula{$i+1}; + //} + $this->_current_char = $i + 1; + $this->_current_token = $token; + return 1; + } + + if ($i < ($formula_length - 2)) { + $this->_lookahead = $this->_formula{$i+2}; + } else { // if we run out of characters _lookahead becomes empty + $this->_lookahead = ''; + } + ++$i; + } + //die("Lexical error ".$this->_current_char); + } + + /** + * Checks if it's a valid token. + * + * @access private + * @param mixed $token The token to check. + * @return mixed The checked token or false on failure + */ + function _match($token) + { + switch($token) { + case "+": + case "-": + case "*": + case "/": + case "(": + case ")": + case ",": + case ";": + case ">=": + case "<=": + case "=": + case "<>": + case "^": + case "&": + case "%": + return $token; + break; + case ">": + if ($this->_lookahead == '=') { // it's a GE token + break; + } + return $token; + break; + case "<": + // it's a LE or a NE token + if (($this->_lookahead == '=') or ($this->_lookahead == '>')) { + break; + } + return $token; + break; + default: + // if it's a reference A1 or $A$1 or $A1 or A$1 + if (preg_match('/^\$?[A-Ia-i]?[A-Za-z]\$?[0-9]+$/',$token) and + !preg_match("/[0-9]/",$this->_lookahead) and + ($this->_lookahead != ':') and ($this->_lookahead != '.') and + ($this->_lookahead != '!')) + { + return $token; + } + // If it's an external reference (Sheet1!A1 or Sheet1:Sheet2!A1 or Sheet1!$A$1 or Sheet1:Sheet2!$A$1) + elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u",$token) and + !preg_match("/[0-9]/",$this->_lookahead) and + ($this->_lookahead != ':') and ($this->_lookahead != '.')) + { + return $token; + } + // If it's an external reference ('Sheet1'!A1 or 'Sheet1:Sheet2'!A1 or 'Sheet1'!$A$1 or 'Sheet1:Sheet2'!$A$1) + elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u",$token) and + !preg_match("/[0-9]/",$this->_lookahead) and + ($this->_lookahead != ':') and ($this->_lookahead != '.')) + { + return $token; + } + // if it's a range A1:A2 or $A$1:$A$2 + elseif (preg_match('/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+:(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/', $token) and + !preg_match("/[0-9]/",$this->_lookahead)) + { + return $token; + } + // If it's an external range like Sheet1!A1:B2 or Sheet1:Sheet2!A1:B2 or Sheet1!$A$1:$B$2 or Sheet1:Sheet2!$A$1:$B$2 + elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+:\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+$/u",$token) and + !preg_match("/[0-9]/",$this->_lookahead)) + { + return $token; + } + // If it's an external range like 'Sheet1'!A1:B2 or 'Sheet1:Sheet2'!A1:B2 or 'Sheet1'!$A$1:$B$2 or 'Sheet1:Sheet2'!$A$1:$B$2 + elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+:\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+$/u",$token) and + !preg_match("/[0-9]/",$this->_lookahead)) + { + return $token; + } + // If it's a number (check that it's not a sheet name or range) + elseif (is_numeric($token) and + (!is_numeric($token.$this->_lookahead) or ($this->_lookahead == '')) and + ($this->_lookahead != '!') and ($this->_lookahead != ':')) + { + return $token; + } + // If it's a string (of maximum 255 characters) + elseif (preg_match("/\"([^\"]|\"\"){0,255}\"/",$token) and $this->_lookahead != '"' and (substr_count($token, '"')%2 == 0)) + { + return $token; + } + // If it's an error code + elseif (preg_match("/^#[A-Z0\/]{3,5}[!?]{1}$/", $token) or $token == '#N/A') + { + return $token; + } + // if it's a function call + elseif (preg_match("/^[A-Z0-9\xc0-\xdc\.]+$/i",$token) and ($this->_lookahead == "(")) + { + return $token; + } + // It's an argument of some description (e.g. a named range), + // precise nature yet to be determined + elseif(substr($token,-1) == ')') { + return $token; + } + return ''; + } + } + + /** + * The parsing method. It parses a formula. + * + * @access public + * @param string $formula The formula to parse, without the initial equal + * sign (=). + * @return mixed true on success + */ + function parse($formula) + { + $this->_current_char = 0; + $this->_formula = $formula; + $this->_lookahead = isset($formula{1}) ? $formula{1} : ''; + $this->_advance(); + $this->_parse_tree = $this->_condition(); + return true; + } + + /** + * It parses a condition. It assumes the following rule: + * Cond -> Expr [(">" | "<") Expr] + * + * @access private + * @return mixed The parsed ptg'd tree on success + */ + function _condition() + { + $result = $this->_expression(); + if ($this->_current_token == "<") { + $this->_advance(); + $result2 = $this->_expression(); + $result = $this->_createTree('ptgLT', $result, $result2); + } elseif ($this->_current_token == ">") { + $this->_advance(); + $result2 = $this->_expression(); + $result = $this->_createTree('ptgGT', $result, $result2); + } elseif ($this->_current_token == "<=") { + $this->_advance(); + $result2 = $this->_expression(); + $result = $this->_createTree('ptgLE', $result, $result2); + } elseif ($this->_current_token == ">=") { + $this->_advance(); + $result2 = $this->_expression(); + $result = $this->_createTree('ptgGE', $result, $result2); + } elseif ($this->_current_token == "=") { + $this->_advance(); + $result2 = $this->_expression(); + $result = $this->_createTree('ptgEQ', $result, $result2); + } elseif ($this->_current_token == "<>") { + $this->_advance(); + $result2 = $this->_expression(); + $result = $this->_createTree('ptgNE', $result, $result2); + } elseif ($this->_current_token == "&") { + $this->_advance(); + $result2 = $this->_expression(); + $result = $this->_createTree('ptgConcat', $result, $result2); + } + return $result; + } + + /** + * It parses a expression. It assumes the following rule: + * Expr -> Term [("+" | "-") Term] + * -> "string" + * -> "-" Term : Negative value + * -> "+" Term : Positive value + * -> Error code + * + * @access private + * @return mixed The parsed ptg'd tree on success + */ + function _expression() + { + // If it's a string return a string node + if (preg_match("/\"([^\"]|\"\"){0,255}\"/", $this->_current_token)) { + $tmp = str_replace('""', '"', $this->_current_token); + if (($tmp == '"') || ($tmp == '')) $tmp = '""'; // Trap for "" that has been used for an empty string + $result = $this->_createTree($tmp, '', ''); + $this->_advance(); + return $result; + // If it's an error code + } elseif (preg_match("/^#[A-Z0\/]{3,5}[!?]{1}$/", $this->_current_token) or $this->_current_token == '#N/A'){ + $result = $this->_createTree($this->_current_token, 'ptgErr', ''); + $this->_advance(); + return $result; + // If it's a negative value + } elseif ($this->_current_token == "-") { + // catch "-" Term + $this->_advance(); + $result2 = $this->_expression(); + $result = $this->_createTree('ptgUminus', $result2, ''); + return $result; + // If it's a positive value + } elseif ($this->_current_token == "+") { + // catch "+" Term + $this->_advance(); + $result2 = $this->_expression(); + $result = $this->_createTree('ptgUplus', $result2, ''); + return $result; + } + $result = $this->_term(); + while (($this->_current_token == "+") or + ($this->_current_token == "-") or + ($this->_current_token == "^")) { + /**/ + if ($this->_current_token == "+") { + $this->_advance(); + $result2 = $this->_term(); + $result = $this->_createTree('ptgAdd', $result, $result2); + } elseif ($this->_current_token == "-") { + $this->_advance(); + $result2 = $this->_term(); + $result = $this->_createTree('ptgSub', $result, $result2); + } else { + $this->_advance(); + $result2 = $this->_term(); + $result = $this->_createTree('ptgPower', $result, $result2); + } + } + return $result; + } + + /** + * This function just introduces a ptgParen element in the tree, so that Excel + * doesn't get confused when working with a parenthesized formula afterwards. + * + * @access private + * @see _fact() + * @return array The parsed ptg'd tree + */ + function _parenthesizedExpression() + { + $result = $this->_createTree('ptgParen', $this->_expression(), ''); + return $result; + } + + /** + * It parses a term. It assumes the following rule: + * Term -> Fact [("*" | "/") Fact] + * + * @access private + * @return mixed The parsed ptg'd tree on success + */ + function _term() + { + $result = $this->_fact(); + while (($this->_current_token == "*") or + ($this->_current_token == "/")) { + /**/ + if ($this->_current_token == "*") { + $this->_advance(); + $result2 = $this->_fact(); + $result = $this->_createTree('ptgMul', $result, $result2); + } else { + $this->_advance(); + $result2 = $this->_fact(); + $result = $this->_createTree('ptgDiv', $result, $result2); + } + } + return $result; + } + + /** + * It parses a factor. It assumes the following rule: + * Fact -> ( Expr ) + * | CellRef + * | CellRange + * | Number + * | Function + * + * @access private + * @return mixed The parsed ptg'd tree on success + */ + function _fact() + { + if ($this->_current_token == "(") { + $this->_advance(); // eat the "(" + $result = $this->_parenthesizedExpression(); + if ($this->_current_token != ")") { + throw new PHPExcel_Writer_Exception("')' token expected."); + } + $this->_advance(); // eat the ")" + return $result; + } + // if it's a reference + if (preg_match('/^\$?[A-Ia-i]?[A-Za-z]\$?[0-9]+$/',$this->_current_token)) + { + $result = $this->_createTree($this->_current_token, '', ''); + $this->_advance(); + return $result; + } + // If it's an external reference (Sheet1!A1 or Sheet1:Sheet2!A1 or Sheet1!$A$1 or Sheet1:Sheet2!$A$1) + elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u",$this->_current_token)) + { + $result = $this->_createTree($this->_current_token, '', ''); + $this->_advance(); + return $result; + } + // If it's an external reference ('Sheet1'!A1 or 'Sheet1:Sheet2'!A1 or 'Sheet1'!$A$1 or 'Sheet1:Sheet2'!$A$1) + elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u",$this->_current_token)) + { + $result = $this->_createTree($this->_current_token, '', ''); + $this->_advance(); + return $result; + } + // if it's a range A1:B2 or $A$1:$B$2 + elseif (preg_match('/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+:(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/',$this->_current_token) or + preg_match('/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+\.\.(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/',$this->_current_token)) + { + // must be an error? + $result = $this->_createTree($this->_current_token, '', ''); + $this->_advance(); + return $result; + } + // If it's an external range (Sheet1!A1:B2 or Sheet1:Sheet2!A1:B2 or Sheet1!$A$1:$B$2 or Sheet1:Sheet2!$A$1:$B$2) + elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+:\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+$/u",$this->_current_token)) + { + // must be an error? + //$result = $this->_current_token; + $result = $this->_createTree($this->_current_token, '', ''); + $this->_advance(); + return $result; + } + // If it's an external range ('Sheet1'!A1:B2 or 'Sheet1'!A1:B2 or 'Sheet1'!$A$1:$B$2 or 'Sheet1'!$A$1:$B$2) + elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+:\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+$/u",$this->_current_token)) + { + // must be an error? + //$result = $this->_current_token; + $result = $this->_createTree($this->_current_token, '', ''); + $this->_advance(); + return $result; + } + // If it's a number or a percent + elseif (is_numeric($this->_current_token)) + { + if($this->_lookahead == '%'){ + $result = $this->_createTree('ptgPercent', $this->_current_token, ''); + } else { + $result = $this->_createTree($this->_current_token, '', ''); + } + $this->_advance(); + return $result; + } + // if it's a function call + elseif (preg_match("/^[A-Z0-9\xc0-\xdc\.]+$/i",$this->_current_token)) + { + $result = $this->_func(); + return $result; + } + throw new PHPExcel_Writer_Exception("Syntax error: ".$this->_current_token. + ", lookahead: ".$this->_lookahead. + ", current char: ".$this->_current_char); + } + + /** + * It parses a function call. It assumes the following rule: + * Func -> ( Expr [,Expr]* ) + * + * @access private + * @return mixed The parsed ptg'd tree on success + */ + function _func() + { + $num_args = 0; // number of arguments received + $function = strtoupper($this->_current_token); + $result = ''; // initialize result + $this->_advance(); + $this->_advance(); // eat the "(" + while ($this->_current_token != ')') { + /**/ + if ($num_args > 0) { + if ($this->_current_token == "," or + $this->_current_token == ";") + { + $this->_advance(); // eat the "," or ";" + } else { + throw new PHPExcel_Writer_Exception("Syntax error: comma expected in ". + "function $function, arg #{$num_args}"); + } + $result2 = $this->_condition(); + $result = $this->_createTree('arg', $result, $result2); + } else { // first argument + $result2 = $this->_condition(); + $result = $this->_createTree('arg', '', $result2); + } + ++$num_args; + } + if (!isset($this->_functions[$function])) { + throw new PHPExcel_Writer_Exception("Function $function() doesn't exist"); + } + $args = $this->_functions[$function][1]; + // If fixed number of args eg. TIME($i,$j,$k). Check that the number of args is valid. + if (($args >= 0) and ($args != $num_args)) { + throw new PHPExcel_Writer_Exception("Incorrect number of arguments in function $function() "); + } + + $result = $this->_createTree($function, $result, $num_args); + $this->_advance(); // eat the ")" + return $result; + } + + /** + * Creates a tree. In fact an array which may have one or two arrays (sub-trees) + * as elements. + * + * @access private + * @param mixed $value The value of this node. + * @param mixed $left The left array (sub-tree) or a final node. + * @param mixed $right The right array (sub-tree) or a final node. + * @return array A tree + */ + function _createTree($value, $left, $right) + { + return array('value' => $value, 'left' => $left, 'right' => $right); + } + + /** + * Builds a string containing the tree in reverse polish notation (What you + * would use in a HP calculator stack). + * The following tree: + * + * + + * / \ + * 2 3 + * + * produces: "23+" + * + * The following tree: + * + * + + * / \ + * 3 * + * / \ + * 6 A1 + * + * produces: "36A1*+" + * + * In fact all operands, functions, references, etc... are written as ptg's + * + * @access public + * @param array $tree The optional tree to convert. + * @return string The tree in reverse polish notation + */ + function toReversePolish($tree = array()) + { + $polish = ""; // the string we are going to return + if (empty($tree)) { // If it's the first call use _parse_tree + $tree = $this->_parse_tree; + } + + if (is_array($tree['left'])) { + $converted_tree = $this->toReversePolish($tree['left']); + $polish .= $converted_tree; + } elseif ($tree['left'] != '') { // It's a final node + $converted_tree = $this->_convert($tree['left']); + $polish .= $converted_tree; + } + if (is_array($tree['right'])) { + $converted_tree = $this->toReversePolish($tree['right']); + $polish .= $converted_tree; + } elseif ($tree['right'] != '') { // It's a final node + $converted_tree = $this->_convert($tree['right']); + $polish .= $converted_tree; + } + // if it's a function convert it here (so we can set it's arguments) + if (preg_match("/^[A-Z0-9\xc0-\xdc\.]+$/",$tree['value']) and + !preg_match('/^([A-Ia-i]?[A-Za-z])(\d+)$/',$tree['value']) and + !preg_match("/^[A-Ia-i]?[A-Za-z](\d+)\.\.[A-Ia-i]?[A-Za-z](\d+)$/",$tree['value']) and + !is_numeric($tree['value']) and + !isset($this->ptg[$tree['value']])) + { + // left subtree for a function is always an array. + if ($tree['left'] != '') { + $left_tree = $this->toReversePolish($tree['left']); + } else { + $left_tree = ''; + } + // add it's left subtree and return. + return $left_tree.$this->_convertFunction($tree['value'], $tree['right']); + } else { + $converted_tree = $this->_convert($tree['value']); + } + $polish .= $converted_tree; + return $polish; + } + +} diff --git a/lib/phpexcel/PHPExcel/Writer/Excel5/Workbook.php b/lib/phpexcel/PHPExcel/Writer/Excel5/Workbook.php new file mode 100644 index 0000000..e14bcba --- /dev/null +++ b/lib/phpexcel/PHPExcel/Writer/Excel5/Workbook.php @@ -0,0 +1,1450 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel5 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + +// Original file header of PEAR::Spreadsheet_Excel_Writer_Workbook (used as the base for this class): +// ----------------------------------------------------------------------------------------- +// /* +// * Module written/ported by Xavier Noguer <xnoguer@rezebra.com> +// * +// * The majority of this is _NOT_ my code. I simply ported it from the +// * PERL Spreadsheet::WriteExcel module. +// * +// * The author of the Spreadsheet::WriteExcel module is John McNamara +// * <jmcnamara@cpan.org> +// * +// * I _DO_ maintain this code, and John McNamara has nothing to do with the +// * porting of this code to PHP. Any questions directly related to this +// * class library should be directed to me. +// * +// * License Information: +// * +// * Spreadsheet_Excel_Writer: A library for generating Excel Spreadsheets +// * Copyright (c) 2002-2003 Xavier Noguer xnoguer@rezebra.com +// * +// * This library is free software; you can redistribute it and/or +// * modify it under the terms of the GNU Lesser General Public +// * License as published by the Free Software Foundation; either +// * version 2.1 of the License, or (at your option) any later version. +// * +// * This library is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// * Lesser General Public License for more details. +// * +// * You should have received a copy of the GNU Lesser General Public +// * License along with this library; if not, write to the Free Software +// * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// */ + + +/** + * PHPExcel_Writer_Excel5_Workbook + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel5 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_Excel5_Workbook extends PHPExcel_Writer_Excel5_BIFFwriter +{ + /** + * Formula parser + * + * @var PHPExcel_Writer_Excel5_Parser + */ + private $_parser; + + /** + * The BIFF file size for the workbook. + * @var integer + * @see _calcSheetOffsets() + */ + public $_biffsize; + + /** + * XF Writers + * @var PHPExcel_Writer_Excel5_Xf[] + */ + private $_xfWriters = array(); + + /** + * Array containing the colour palette + * @var array + */ + public $_palette; + + /** + * The codepage indicates the text encoding used for strings + * @var integer + */ + public $_codepage; + + /** + * The country code used for localization + * @var integer + */ + public $_country_code; + + /** + * Workbook + * @var PHPExcel + */ + private $_phpExcel; + + /** + * Fonts writers + * + * @var PHPExcel_Writer_Excel5_Font[] + */ + private $_fontWriters = array(); + + /** + * Added fonts. Maps from font's hash => index in workbook + * + * @var array + */ + private $_addedFonts = array(); + + /** + * Shared number formats + * + * @var array + */ + private $_numberFormats = array(); + + /** + * Added number formats. Maps from numberFormat's hash => index in workbook + * + * @var array + */ + private $_addedNumberFormats = array(); + + /** + * Sizes of the binary worksheet streams + * + * @var array + */ + private $_worksheetSizes = array(); + + /** + * Offsets of the binary worksheet streams relative to the start of the global workbook stream + * + * @var array + */ + private $_worksheetOffsets = array(); + + /** + * Total number of shared strings in workbook + * + * @var int + */ + private $_str_total; + + /** + * Number of unique shared strings in workbook + * + * @var int + */ + private $_str_unique; + + /** + * Array of unique shared strings in workbook + * + * @var array + */ + private $_str_table; + + /** + * Color cache + */ + private $_colors; + + /** + * Escher object corresponding to MSODRAWINGGROUP + * + * @var PHPExcel_Shared_Escher + */ + private $_escher; + + + /** + * Class constructor + * + * @param PHPExcel $phpExcel The Workbook + * @param int &$str_total Total number of strings + * @param int &$str_unique Total number of unique strings + * @param array &$str_table String Table + * @param array &$colors Colour Table + * @param mixed $parser The formula parser created for the Workbook + */ + public function __construct(PHPExcel $phpExcel = null, + &$str_total, &$str_unique, &$str_table, &$colors, + $parser ) + { + // It needs to call its parent's constructor explicitly + parent::__construct(); + + $this->_parser = $parser; + $this->_biffsize = 0; + $this->_palette = array(); + $this->_country_code = -1; + + $this->_str_total = &$str_total; + $this->_str_unique = &$str_unique; + $this->_str_table = &$str_table; + $this->_colors = &$colors; + $this->_setPaletteXl97(); + + $this->_phpExcel = $phpExcel; + + // set BIFFwriter limit for CONTINUE records + // $this->_limit = 8224; + $this->_codepage = 0x04B0; + + // Add empty sheets and Build color cache + $countSheets = $phpExcel->getSheetCount(); + for ($i = 0; $i < $countSheets; ++$i) { + $phpSheet = $phpExcel->getSheet($i); + + $this->_parser->setExtSheet($phpSheet->getTitle(), $i); // Register worksheet name with parser + + $supbook_index = 0x00; + $ref = pack('vvv', $supbook_index, $i, $i); + $this->_parser->_references[] = $ref; // Register reference with parser + + // Sheet tab colors? + if ($phpSheet->isTabColorSet()) { + $this->_addColor($phpSheet->getTabColor()->getRGB()); + } + } + + } + + /** + * Add a new XF writer + * + * @param PHPExcel_Style + * @param boolean Is it a style XF? + * @return int Index to XF record + */ + public function addXfWriter($style, $isStyleXf = false) + { + $xfWriter = new PHPExcel_Writer_Excel5_Xf($style); + $xfWriter->setIsStyleXf($isStyleXf); + + // Add the font if not already added + $fontIndex = $this->_addFont($style->getFont()); + + // Assign the font index to the xf record + $xfWriter->setFontIndex($fontIndex); + + // Background colors, best to treat these after the font so black will come after white in custom palette + $xfWriter->setFgColor($this->_addColor($style->getFill()->getStartColor()->getRGB())); + $xfWriter->setBgColor($this->_addColor($style->getFill()->getEndColor()->getRGB())); + $xfWriter->setBottomColor($this->_addColor($style->getBorders()->getBottom()->getColor()->getRGB())); + $xfWriter->setTopColor($this->_addColor($style->getBorders()->getTop()->getColor()->getRGB())); + $xfWriter->setRightColor($this->_addColor($style->getBorders()->getRight()->getColor()->getRGB())); + $xfWriter->setLeftColor($this->_addColor($style->getBorders()->getLeft()->getColor()->getRGB())); + $xfWriter->setDiagColor($this->_addColor($style->getBorders()->getDiagonal()->getColor()->getRGB())); + + // Add the number format if it is not a built-in one and not already added + if ($style->getNumberFormat()->getBuiltInFormatCode() === false) { + $numberFormatHashCode = $style->getNumberFormat()->getHashCode(); + + if (isset($this->_addedNumberFormats[$numberFormatHashCode])) { + $numberFormatIndex = $this->_addedNumberFormats[$numberFormatHashCode]; + } else { + $numberFormatIndex = 164 + count($this->_numberFormats); + $this->_numberFormats[$numberFormatIndex] = $style->getNumberFormat(); + $this->_addedNumberFormats[$numberFormatHashCode] = $numberFormatIndex; + } + } else { + $numberFormatIndex = (int) $style->getNumberFormat()->getBuiltInFormatCode(); + } + + // Assign the number format index to xf record + $xfWriter->setNumberFormatIndex($numberFormatIndex); + + $this->_xfWriters[] = $xfWriter; + + $xfIndex = count($this->_xfWriters) - 1; + return $xfIndex; + } + + /** + * Add a font to added fonts + * + * @param PHPExcel_Style_Font $font + * @return int Index to FONT record + */ + public function _addFont(PHPExcel_Style_Font $font) + { + $fontHashCode = $font->getHashCode(); + if(isset($this->_addedFonts[$fontHashCode])){ + $fontIndex = $this->_addedFonts[$fontHashCode]; + } else { + $countFonts = count($this->_fontWriters); + $fontIndex = ($countFonts < 4) ? $countFonts : $countFonts + 1; + + $fontWriter = new PHPExcel_Writer_Excel5_Font($font); + $fontWriter->setColorIndex($this->_addColor($font->getColor()->getRGB())); + $this->_fontWriters[] = $fontWriter; + + $this->_addedFonts[$fontHashCode] = $fontIndex; + } + return $fontIndex; + } + + /** + * Alter color palette adding a custom color + * + * @param string $rgb E.g. 'FF00AA' + * @return int Color index + */ + private function _addColor($rgb) { + if (!isset($this->_colors[$rgb])) { + if (count($this->_colors) < 57) { + // then we add a custom color altering the palette + $colorIndex = 8 + count($this->_colors); + $this->_palette[$colorIndex] = + array( + hexdec(substr($rgb, 0, 2)), + hexdec(substr($rgb, 2, 2)), + hexdec(substr($rgb, 4)), + 0 + ); + $this->_colors[$rgb] = $colorIndex; + } else { + // no room for more custom colors, just map to black + $colorIndex = 0; + } + } else { + // fetch already added custom color + $colorIndex = $this->_colors[$rgb]; + } + + return $colorIndex; + } + + /** + * Sets the colour palette to the Excel 97+ default. + * + * @access private + */ + function _setPaletteXl97() + { + $this->_palette = array( + 0x08 => array(0x00, 0x00, 0x00, 0x00), + 0x09 => array(0xff, 0xff, 0xff, 0x00), + 0x0A => array(0xff, 0x00, 0x00, 0x00), + 0x0B => array(0x00, 0xff, 0x00, 0x00), + 0x0C => array(0x00, 0x00, 0xff, 0x00), + 0x0D => array(0xff, 0xff, 0x00, 0x00), + 0x0E => array(0xff, 0x00, 0xff, 0x00), + 0x0F => array(0x00, 0xff, 0xff, 0x00), + 0x10 => array(0x80, 0x00, 0x00, 0x00), + 0x11 => array(0x00, 0x80, 0x00, 0x00), + 0x12 => array(0x00, 0x00, 0x80, 0x00), + 0x13 => array(0x80, 0x80, 0x00, 0x00), + 0x14 => array(0x80, 0x00, 0x80, 0x00), + 0x15 => array(0x00, 0x80, 0x80, 0x00), + 0x16 => array(0xc0, 0xc0, 0xc0, 0x00), + 0x17 => array(0x80, 0x80, 0x80, 0x00), + 0x18 => array(0x99, 0x99, 0xff, 0x00), + 0x19 => array(0x99, 0x33, 0x66, 0x00), + 0x1A => array(0xff, 0xff, 0xcc, 0x00), + 0x1B => array(0xcc, 0xff, 0xff, 0x00), + 0x1C => array(0x66, 0x00, 0x66, 0x00), + 0x1D => array(0xff, 0x80, 0x80, 0x00), + 0x1E => array(0x00, 0x66, 0xcc, 0x00), + 0x1F => array(0xcc, 0xcc, 0xff, 0x00), + 0x20 => array(0x00, 0x00, 0x80, 0x00), + 0x21 => array(0xff, 0x00, 0xff, 0x00), + 0x22 => array(0xff, 0xff, 0x00, 0x00), + 0x23 => array(0x00, 0xff, 0xff, 0x00), + 0x24 => array(0x80, 0x00, 0x80, 0x00), + 0x25 => array(0x80, 0x00, 0x00, 0x00), + 0x26 => array(0x00, 0x80, 0x80, 0x00), + 0x27 => array(0x00, 0x00, 0xff, 0x00), + 0x28 => array(0x00, 0xcc, 0xff, 0x00), + 0x29 => array(0xcc, 0xff, 0xff, 0x00), + 0x2A => array(0xcc, 0xff, 0xcc, 0x00), + 0x2B => array(0xff, 0xff, 0x99, 0x00), + 0x2C => array(0x99, 0xcc, 0xff, 0x00), + 0x2D => array(0xff, 0x99, 0xcc, 0x00), + 0x2E => array(0xcc, 0x99, 0xff, 0x00), + 0x2F => array(0xff, 0xcc, 0x99, 0x00), + 0x30 => array(0x33, 0x66, 0xff, 0x00), + 0x31 => array(0x33, 0xcc, 0xcc, 0x00), + 0x32 => array(0x99, 0xcc, 0x00, 0x00), + 0x33 => array(0xff, 0xcc, 0x00, 0x00), + 0x34 => array(0xff, 0x99, 0x00, 0x00), + 0x35 => array(0xff, 0x66, 0x00, 0x00), + 0x36 => array(0x66, 0x66, 0x99, 0x00), + 0x37 => array(0x96, 0x96, 0x96, 0x00), + 0x38 => array(0x00, 0x33, 0x66, 0x00), + 0x39 => array(0x33, 0x99, 0x66, 0x00), + 0x3A => array(0x00, 0x33, 0x00, 0x00), + 0x3B => array(0x33, 0x33, 0x00, 0x00), + 0x3C => array(0x99, 0x33, 0x00, 0x00), + 0x3D => array(0x99, 0x33, 0x66, 0x00), + 0x3E => array(0x33, 0x33, 0x99, 0x00), + 0x3F => array(0x33, 0x33, 0x33, 0x00), + ); + } + + /** + * Assemble worksheets into a workbook and send the BIFF data to an OLE + * storage. + * + * @param array $pWorksheetSizes The sizes in bytes of the binary worksheet streams + * @return string Binary data for workbook stream + */ + public function writeWorkbook($pWorksheetSizes = null) + { + $this->_worksheetSizes = $pWorksheetSizes; + + // Calculate the number of selected worksheet tabs and call the finalization + // methods for each worksheet + $total_worksheets = $this->_phpExcel->getSheetCount(); + + // Add part 1 of the Workbook globals, what goes before the SHEET records + $this->_storeBof(0x0005); + $this->_writeCodepage(); + $this->_writeWindow1(); + + $this->_writeDatemode(); + $this->_writeAllFonts(); + $this->_writeAllNumFormats(); + $this->_writeAllXfs(); + $this->_writeAllStyles(); + $this->_writePalette(); + + // Prepare part 3 of the workbook global stream, what goes after the SHEET records + $part3 = ''; + if ($this->_country_code != -1) { + $part3 .= $this->_writeCountry(); + } + $part3 .= $this->_writeRecalcId(); + + $part3 .= $this->_writeSupbookInternal(); + /* TODO: store external SUPBOOK records and XCT and CRN records + in case of external references for BIFF8 */ + $part3 .= $this->_writeExternsheetBiff8(); + $part3 .= $this->_writeAllDefinedNamesBiff8(); + $part3 .= $this->_writeMsoDrawingGroup(); + $part3 .= $this->_writeSharedStringsTable(); + + $part3 .= $this->writeEof(); + + // Add part 2 of the Workbook globals, the SHEET records + $this->_calcSheetOffsets(); + for ($i = 0; $i < $total_worksheets; ++$i) { + $this->_writeBoundsheet($this->_phpExcel->getSheet($i), $this->_worksheetOffsets[$i]); + } + + // Add part 3 of the Workbook globals + $this->_data .= $part3; + + return $this->_data; + } + + /** + * Calculate offsets for Worksheet BOF records. + * + * @access private + */ + function _calcSheetOffsets() + { + $boundsheet_length = 10; // fixed length for a BOUNDSHEET record + + // size of Workbook globals part 1 + 3 + $offset = $this->_datasize; + + // add size of Workbook globals part 2, the length of the SHEET records + $total_worksheets = count($this->_phpExcel->getAllSheets()); + foreach ($this->_phpExcel->getWorksheetIterator() as $sheet) { + $offset += $boundsheet_length + strlen(PHPExcel_Shared_String::UTF8toBIFF8UnicodeShort($sheet->getTitle())); + } + + // add the sizes of each of the Sheet substreams, respectively + for ($i = 0; $i < $total_worksheets; ++$i) { + $this->_worksheetOffsets[$i] = $offset; + $offset += $this->_worksheetSizes[$i]; + } + $this->_biffsize = $offset; + } + + /** + * Store the Excel FONT records. + */ + private function _writeAllFonts() + { + foreach ($this->_fontWriters as $fontWriter) { + $this->_append($fontWriter->writeFont()); + } + } + + /** + * Store user defined numerical formats i.e. FORMAT records + */ + private function _writeAllNumFormats() + { + foreach ($this->_numberFormats as $numberFormatIndex => $numberFormat) { + $this->_writeNumFormat($numberFormat->getFormatCode(), $numberFormatIndex); + } + } + + /** + * Write all XF records. + */ + private function _writeAllXfs() + { + foreach ($this->_xfWriters as $xfWriter) { + $this->_append($xfWriter->writeXf()); + } + } + + /** + * Write all STYLE records. + */ + private function _writeAllStyles() + { + $this->_writeStyle(); + } + + /** + * Write the EXTERNCOUNT and EXTERNSHEET records. These are used as indexes for + * the NAME records. + */ + private function _writeExterns() + { + $countSheets = $this->_phpExcel->getSheetCount(); + // Create EXTERNCOUNT with number of worksheets + $this->_writeExterncount($countSheets); + + // Create EXTERNSHEET for each worksheet + for ($i = 0; $i < $countSheets; ++$i) { + $this->_writeExternsheet($this->_phpExcel->getSheet($i)->getTitle()); + } + } + + /** + * Write the NAME record to define the print area and the repeat rows and cols. + */ + private function _writeNames() + { + // total number of sheets + $total_worksheets = $this->_phpExcel->getSheetCount(); + + // Create the print area NAME records + for ($i = 0; $i < $total_worksheets; ++$i) { + $sheetSetup = $this->_phpExcel->getSheet($i)->getPageSetup(); + // Write a Name record if the print area has been defined + if ($sheetSetup->isPrintAreaSet()) { + // Print area + $printArea = PHPExcel_Cell::splitRange($sheetSetup->getPrintArea()); + $printArea = $printArea[0]; + $printArea[0] = PHPExcel_Cell::coordinateFromString($printArea[0]); + $printArea[1] = PHPExcel_Cell::coordinateFromString($printArea[1]); + + $print_rowmin = $printArea[0][1] - 1; + $print_rowmax = $printArea[1][1] - 1; + $print_colmin = PHPExcel_Cell::columnIndexFromString($printArea[0][0]) - 1; + $print_colmax = PHPExcel_Cell::columnIndexFromString($printArea[1][0]) - 1; + + $this->_writeNameShort( + $i, // sheet index + 0x06, // NAME type + $print_rowmin, + $print_rowmax, + $print_colmin, + $print_colmax + ); + } + } + + // Create the print title NAME records + for ($i = 0; $i < $total_worksheets; ++$i) { + $sheetSetup = $this->_phpExcel->getSheet($i)->getPageSetup(); + + // simultaneous repeatColumns repeatRows + if ($sheetSetup->isColumnsToRepeatAtLeftSet() && $sheetSetup->isRowsToRepeatAtTopSet()) { + $repeat = $sheetSetup->getColumnsToRepeatAtLeft(); + $colmin = PHPExcel_Cell::columnIndexFromString($repeat[0]) - 1; + $colmax = PHPExcel_Cell::columnIndexFromString($repeat[1]) - 1; + + $repeat = $sheetSetup->getRowsToRepeatAtTop(); + $rowmin = $repeat[0] - 1; + $rowmax = $repeat[1] - 1; + + $this->_writeNameLong( + $i, // sheet index + 0x07, // NAME type + $rowmin, + $rowmax, + $colmin, + $colmax + ); + + // (exclusive) either repeatColumns or repeatRows + } else if ($sheetSetup->isColumnsToRepeatAtLeftSet() || $sheetSetup->isRowsToRepeatAtTopSet()) { + + // Columns to repeat + if ($sheetSetup->isColumnsToRepeatAtLeftSet()) { + $repeat = $sheetSetup->getColumnsToRepeatAtLeft(); + $colmin = PHPExcel_Cell::columnIndexFromString($repeat[0]) - 1; + $colmax = PHPExcel_Cell::columnIndexFromString($repeat[1]) - 1; + } else { + $colmin = 0; + $colmax = 255; + } + + // Rows to repeat + if ($sheetSetup->isRowsToRepeatAtTopSet()) { + $repeat = $sheetSetup->getRowsToRepeatAtTop(); + $rowmin = $repeat[0] - 1; + $rowmax = $repeat[1] - 1; + } else { + $rowmin = 0; + $rowmax = 65535; + } + + $this->_writeNameShort( + $i, // sheet index + 0x07, // NAME type + $rowmin, + $rowmax, + $colmin, + $colmax + ); + } + } + } + + /** + * Writes all the DEFINEDNAME records (BIFF8). + * So far this is only used for repeating rows/columns (print titles) and print areas + */ + private function _writeAllDefinedNamesBiff8() + { + $chunk = ''; + + // Named ranges + if (count($this->_phpExcel->getNamedRanges()) > 0) { + // Loop named ranges + $namedRanges = $this->_phpExcel->getNamedRanges(); + foreach ($namedRanges as $namedRange) { + + // Create absolute coordinate + $range = PHPExcel_Cell::splitRange($namedRange->getRange()); + for ($i = 0; $i < count($range); $i++) { + $range[$i][0] = '\'' . str_replace("'", "''", $namedRange->getWorksheet()->getTitle()) . '\'!' . PHPExcel_Cell::absoluteCoordinate($range[$i][0]); + if (isset($range[$i][1])) { + $range[$i][1] = PHPExcel_Cell::absoluteCoordinate($range[$i][1]); + } + } + $range = PHPExcel_Cell::buildRange($range); // e.g. Sheet1!$A$1:$B$2 + + // parse formula + try { + $error = $this->_parser->parse($range); + $formulaData = $this->_parser->toReversePolish(); + + // make sure tRef3d is of type tRef3dR (0x3A) + if (isset($formulaData{0}) and ($formulaData{0} == "\x7A" or $formulaData{0} == "\x5A")) { + $formulaData = "\x3A" . substr($formulaData, 1); + } + + if ($namedRange->getLocalOnly()) { + // local scope + $scope = $this->_phpExcel->getIndex($namedRange->getScope()) + 1; + } else { + // global scope + $scope = 0; + } + $chunk .= $this->writeData($this->_writeDefinedNameBiff8($namedRange->getName(), $formulaData, $scope, false)); + + } catch(PHPExcel_Exception $e) { + // do nothing + } + } + } + + // total number of sheets + $total_worksheets = $this->_phpExcel->getSheetCount(); + + // write the print titles (repeating rows, columns), if any + for ($i = 0; $i < $total_worksheets; ++$i) { + $sheetSetup = $this->_phpExcel->getSheet($i)->getPageSetup(); + // simultaneous repeatColumns repeatRows + if ($sheetSetup->isColumnsToRepeatAtLeftSet() && $sheetSetup->isRowsToRepeatAtTopSet()) { + $repeat = $sheetSetup->getColumnsToRepeatAtLeft(); + $colmin = PHPExcel_Cell::columnIndexFromString($repeat[0]) - 1; + $colmax = PHPExcel_Cell::columnIndexFromString($repeat[1]) - 1; + + $repeat = $sheetSetup->getRowsToRepeatAtTop(); + $rowmin = $repeat[0] - 1; + $rowmax = $repeat[1] - 1; + + // construct formula data manually + $formulaData = pack('Cv', 0x29, 0x17); // tMemFunc + $formulaData .= pack('Cvvvvv', 0x3B, $i, 0, 65535, $colmin, $colmax); // tArea3d + $formulaData .= pack('Cvvvvv', 0x3B, $i, $rowmin, $rowmax, 0, 255); // tArea3d + $formulaData .= pack('C', 0x10); // tList + + // store the DEFINEDNAME record + $chunk .= $this->writeData($this->_writeDefinedNameBiff8(pack('C', 0x07), $formulaData, $i + 1, true)); + + // (exclusive) either repeatColumns or repeatRows + } else if ($sheetSetup->isColumnsToRepeatAtLeftSet() || $sheetSetup->isRowsToRepeatAtTopSet()) { + + // Columns to repeat + if ($sheetSetup->isColumnsToRepeatAtLeftSet()) { + $repeat = $sheetSetup->getColumnsToRepeatAtLeft(); + $colmin = PHPExcel_Cell::columnIndexFromString($repeat[0]) - 1; + $colmax = PHPExcel_Cell::columnIndexFromString($repeat[1]) - 1; + } else { + $colmin = 0; + $colmax = 255; + } + // Rows to repeat + if ($sheetSetup->isRowsToRepeatAtTopSet()) { + $repeat = $sheetSetup->getRowsToRepeatAtTop(); + $rowmin = $repeat[0] - 1; + $rowmax = $repeat[1] - 1; + } else { + $rowmin = 0; + $rowmax = 65535; + } + + // construct formula data manually because parser does not recognize absolute 3d cell references + $formulaData = pack('Cvvvvv', 0x3B, $i, $rowmin, $rowmax, $colmin, $colmax); + + // store the DEFINEDNAME record + $chunk .= $this->writeData($this->_writeDefinedNameBiff8(pack('C', 0x07), $formulaData, $i + 1, true)); + } + } + + // write the print areas, if any + for ($i = 0; $i < $total_worksheets; ++$i) { + $sheetSetup = $this->_phpExcel->getSheet($i)->getPageSetup(); + if ($sheetSetup->isPrintAreaSet()) { + // Print area, e.g. A3:J6,H1:X20 + $printArea = PHPExcel_Cell::splitRange($sheetSetup->getPrintArea()); + $countPrintArea = count($printArea); + + $formulaData = ''; + for ($j = 0; $j < $countPrintArea; ++$j) { + $printAreaRect = $printArea[$j]; // e.g. A3:J6 + $printAreaRect[0] = PHPExcel_Cell::coordinateFromString($printAreaRect[0]); + $printAreaRect[1] = PHPExcel_Cell::coordinateFromString($printAreaRect[1]); + + $print_rowmin = $printAreaRect[0][1] - 1; + $print_rowmax = $printAreaRect[1][1] - 1; + $print_colmin = PHPExcel_Cell::columnIndexFromString($printAreaRect[0][0]) - 1; + $print_colmax = PHPExcel_Cell::columnIndexFromString($printAreaRect[1][0]) - 1; + + // construct formula data manually because parser does not recognize absolute 3d cell references + $formulaData .= pack('Cvvvvv', 0x3B, $i, $print_rowmin, $print_rowmax, $print_colmin, $print_colmax); + + if ($j > 0) { + $formulaData .= pack('C', 0x10); // list operator token ',' + } + } + + // store the DEFINEDNAME record + $chunk .= $this->writeData($this->_writeDefinedNameBiff8(pack('C', 0x06), $formulaData, $i + 1, true)); + } + } + + // write autofilters, if any + for ($i = 0; $i < $total_worksheets; ++$i) { + $sheetAutoFilter = $this->_phpExcel->getSheet($i)->getAutoFilter(); + $autoFilterRange = $sheetAutoFilter->getRange(); + if(!empty($autoFilterRange)) { + $rangeBounds = PHPExcel_Cell::rangeBoundaries($autoFilterRange); + + //Autofilter built in name + $name = pack('C', 0x0D); + + $chunk .= $this->writeData($this->_writeShortNameBiff8($name, $i + 1, $rangeBounds, true)); + } + } + + return $chunk; + } + + /** + * Write a DEFINEDNAME record for BIFF8 using explicit binary formula data + * + * @param string $name The name in UTF-8 + * @param string $formulaData The binary formula data + * @param string $sheetIndex 1-based sheet index the defined name applies to. 0 = global + * @param boolean $isBuiltIn Built-in name? + * @return string Complete binary record data + */ + private function _writeDefinedNameBiff8($name, $formulaData, $sheetIndex = 0, $isBuiltIn = false) + { + $record = 0x0018; + + // option flags + $options = $isBuiltIn ? 0x20 : 0x00; + + // length of the name, character count + $nlen = PHPExcel_Shared_String::CountCharacters($name); + + // name with stripped length field + $name = substr(PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($name), 2); + + // size of the formula (in bytes) + $sz = strlen($formulaData); + + // combine the parts + $data = pack('vCCvvvCCCC', $options, 0, $nlen, $sz, 0, $sheetIndex, 0, 0, 0, 0) + . $name . $formulaData; + $length = strlen($data); + + $header = pack('vv', $record, $length); + + return $header . $data; + } + + /** + * Write a short NAME record + * + * @param string $name + * @param string $sheetIndex 1-based sheet index the defined name applies to. 0 = global + * @param integer[][] $rangeBounds range boundaries + * @param boolean $isHidden + * @return string Complete binary record data + * */ + private function _writeShortNameBiff8($name, $sheetIndex = 0, $rangeBounds, $isHidden = false){ + $record = 0x0018; + + // option flags + $options = ($isHidden ? 0x21 : 0x00); + + $extra = pack('Cvvvvv', + 0x3B, + $sheetIndex - 1, + $rangeBounds[0][1] - 1, + $rangeBounds[1][1] - 1, + $rangeBounds[0][0] - 1, + $rangeBounds[1][0] - 1); + + // size of the formula (in bytes) + $sz = strlen($extra); + + // combine the parts + $data = pack('vCCvvvCCCCC', $options, 0, 1, $sz, 0, $sheetIndex, 0, 0, 0, 0, 0) + . $name . $extra; + $length = strlen($data); + + $header = pack('vv', $record, $length); + + return $header . $data; + } + + /** + * Stores the CODEPAGE biff record. + */ + private function _writeCodepage() + { + $record = 0x0042; // Record identifier + $length = 0x0002; // Number of bytes to follow + $cv = $this->_codepage; // The code page + + $header = pack('vv', $record, $length); + $data = pack('v', $cv); + + $this->_append($header . $data); + } + + /** + * Write Excel BIFF WINDOW1 record. + */ + private function _writeWindow1() + { + $record = 0x003D; // Record identifier + $length = 0x0012; // Number of bytes to follow + + $xWn = 0x0000; // Horizontal position of window + $yWn = 0x0000; // Vertical position of window + $dxWn = 0x25BC; // Width of window + $dyWn = 0x1572; // Height of window + + $grbit = 0x0038; // Option flags + + // not supported by PHPExcel, so there is only one selected sheet, the active + $ctabsel = 1; // Number of workbook tabs selected + + $wTabRatio = 0x0258; // Tab to scrollbar ratio + + // not supported by PHPExcel, set to 0 + $itabFirst = 0; // 1st displayed worksheet + $itabCur = $this->_phpExcel->getActiveSheetIndex(); // Active worksheet + + $header = pack("vv", $record, $length); + $data = pack("vvvvvvvvv", $xWn, $yWn, $dxWn, $dyWn, + $grbit, + $itabCur, $itabFirst, + $ctabsel, $wTabRatio); + $this->_append($header . $data); + } + + /** + * Writes Excel BIFF BOUNDSHEET record. + * + * @param PHPExcel_Worksheet $sheet Worksheet name + * @param integer $offset Location of worksheet BOF + */ + private function _writeBoundsheet($sheet, $offset) + { + $sheetname = $sheet->getTitle(); + $record = 0x0085; // Record identifier + + // sheet state + switch ($sheet->getSheetState()) { + case PHPExcel_Worksheet::SHEETSTATE_VISIBLE: $ss = 0x00; break; + case PHPExcel_Worksheet::SHEETSTATE_HIDDEN: $ss = 0x01; break; + case PHPExcel_Worksheet::SHEETSTATE_VERYHIDDEN: $ss = 0x02; break; + default: $ss = 0x00; break; + } + + // sheet type + $st = 0x00; + + $grbit = 0x0000; // Visibility and sheet type + + $data = pack("VCC", $offset, $ss, $st); + $data .= PHPExcel_Shared_String::UTF8toBIFF8UnicodeShort($sheetname); + + $length = strlen($data); + $header = pack("vv", $record, $length); + $this->_append($header . $data); + } + + /** + * Write Internal SUPBOOK record + */ + private function _writeSupbookInternal() + { + $record = 0x01AE; // Record identifier + $length = 0x0004; // Bytes to follow + + $header = pack("vv", $record, $length); + $data = pack("vv", $this->_phpExcel->getSheetCount(), 0x0401); + return $this->writeData($header . $data); + } + + /** + * Writes the Excel BIFF EXTERNSHEET record. These references are used by + * formulas. + * + */ + private function _writeExternsheetBiff8() + { + $total_references = count($this->_parser->_references); + $record = 0x0017; // Record identifier + $length = 2 + 6 * $total_references; // Number of bytes to follow + + $supbook_index = 0; // FIXME: only using internal SUPBOOK record + $header = pack("vv", $record, $length); + $data = pack('v', $total_references); + for ($i = 0; $i < $total_references; ++$i) { + $data .= $this->_parser->_references[$i]; + } + return $this->writeData($header . $data); + } + + /** + * Write Excel BIFF STYLE records. + */ + private function _writeStyle() + { + $record = 0x0293; // Record identifier + $length = 0x0004; // Bytes to follow + + $ixfe = 0x8000; // Index to cell style XF + $BuiltIn = 0x00; // Built-in style + $iLevel = 0xff; // Outline style level + + $header = pack("vv", $record, $length); + $data = pack("vCC", $ixfe, $BuiltIn, $iLevel); + $this->_append($header . $data); + } + + /** + * Writes Excel FORMAT record for non "built-in" numerical formats. + * + * @param string $format Custom format string + * @param integer $ifmt Format index code + */ + private function _writeNumFormat($format, $ifmt) + { + $record = 0x041E; // Record identifier + + $numberFormatString = PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($format); + $length = 2 + strlen($numberFormatString); // Number of bytes to follow + + + $header = pack("vv", $record, $length); + $data = pack("v", $ifmt) . $numberFormatString; + $this->_append($header . $data); + } + + /** + * Write DATEMODE record to indicate the date system in use (1904 or 1900). + */ + private function _writeDatemode() + { + $record = 0x0022; // Record identifier + $length = 0x0002; // Bytes to follow + + $f1904 = (PHPExcel_Shared_Date::getExcelCalendar() == PHPExcel_Shared_Date::CALENDAR_MAC_1904) ? + 1 : 0; // Flag for 1904 date system + + $header = pack("vv", $record, $length); + $data = pack("v", $f1904); + $this->_append($header . $data); + } + + /** + * Write BIFF record EXTERNCOUNT to indicate the number of external sheet + * references in the workbook. + * + * Excel only stores references to external sheets that are used in NAME. + * The workbook NAME record is required to define the print area and the repeat + * rows and columns. + * + * A similar method is used in Worksheet.php for a slightly different purpose. + * + * @param integer $cxals Number of external references + */ + private function _writeExterncount($cxals) + { + $record = 0x0016; // Record identifier + $length = 0x0002; // Number of bytes to follow + + $header = pack("vv", $record, $length); + $data = pack("v", $cxals); + $this->_append($header . $data); + } + + /** + * Writes the Excel BIFF EXTERNSHEET record. These references are used by + * formulas. NAME record is required to define the print area and the repeat + * rows and columns. + * + * A similar method is used in Worksheet.php for a slightly different purpose. + * + * @param string $sheetname Worksheet name + */ + private function _writeExternsheet($sheetname) + { + $record = 0x0017; // Record identifier + $length = 0x02 + strlen($sheetname); // Number of bytes to follow + + $cch = strlen($sheetname); // Length of sheet name + $rgch = 0x03; // Filename encoding + + $header = pack("vv", $record, $length); + $data = pack("CC", $cch, $rgch); + $this->_append($header . $data . $sheetname); + } + + /** + * Store the NAME record in the short format that is used for storing the print + * area, repeat rows only and repeat columns only. + * + * @param integer $index Sheet index + * @param integer $type Built-in name type + * @param integer $rowmin Start row + * @param integer $rowmax End row + * @param integer $colmin Start colum + * @param integer $colmax End column + */ + private function _writeNameShort($index, $type, $rowmin, $rowmax, $colmin, $colmax) + { + $record = 0x0018; // Record identifier + $length = 0x0024; // Number of bytes to follow + + $grbit = 0x0020; // Option flags + $chKey = 0x00; // Keyboard shortcut + $cch = 0x01; // Length of text name + $cce = 0x0015; // Length of text definition + $ixals = $index + 1; // Sheet index + $itab = $ixals; // Equal to ixals + $cchCustMenu = 0x00; // Length of cust menu text + $cchDescription = 0x00; // Length of description text + $cchHelptopic = 0x00; // Length of help topic text + $cchStatustext = 0x00; // Length of status bar text + $rgch = $type; // Built-in name type + + $unknown03 = 0x3b; + $unknown04 = 0xffff-$index; + $unknown05 = 0x0000; + $unknown06 = 0x0000; + $unknown07 = 0x1087; + $unknown08 = 0x8005; + + $header = pack("vv", $record, $length); + $data = pack("v", $grbit); + $data .= pack("C", $chKey); + $data .= pack("C", $cch); + $data .= pack("v", $cce); + $data .= pack("v", $ixals); + $data .= pack("v", $itab); + $data .= pack("C", $cchCustMenu); + $data .= pack("C", $cchDescription); + $data .= pack("C", $cchHelptopic); + $data .= pack("C", $cchStatustext); + $data .= pack("C", $rgch); + $data .= pack("C", $unknown03); + $data .= pack("v", $unknown04); + $data .= pack("v", $unknown05); + $data .= pack("v", $unknown06); + $data .= pack("v", $unknown07); + $data .= pack("v", $unknown08); + $data .= pack("v", $index); + $data .= pack("v", $index); + $data .= pack("v", $rowmin); + $data .= pack("v", $rowmax); + $data .= pack("C", $colmin); + $data .= pack("C", $colmax); + $this->_append($header . $data); + } + + /** + * Store the NAME record in the long format that is used for storing the repeat + * rows and columns when both are specified. This shares a lot of code with + * _writeNameShort() but we use a separate method to keep the code clean. + * Code abstraction for reuse can be carried too far, and I should know. ;-) + * + * @param integer $index Sheet index + * @param integer $type Built-in name type + * @param integer $rowmin Start row + * @param integer $rowmax End row + * @param integer $colmin Start colum + * @param integer $colmax End column + */ + private function _writeNameLong($index, $type, $rowmin, $rowmax, $colmin, $colmax) + { + $record = 0x0018; // Record identifier + $length = 0x003d; // Number of bytes to follow + $grbit = 0x0020; // Option flags + $chKey = 0x00; // Keyboard shortcut + $cch = 0x01; // Length of text name + $cce = 0x002e; // Length of text definition + $ixals = $index + 1; // Sheet index + $itab = $ixals; // Equal to ixals + $cchCustMenu = 0x00; // Length of cust menu text + $cchDescription = 0x00; // Length of description text + $cchHelptopic = 0x00; // Length of help topic text + $cchStatustext = 0x00; // Length of status bar text + $rgch = $type; // Built-in name type + + $unknown01 = 0x29; + $unknown02 = 0x002b; + $unknown03 = 0x3b; + $unknown04 = 0xffff-$index; + $unknown05 = 0x0000; + $unknown06 = 0x0000; + $unknown07 = 0x1087; + $unknown08 = 0x8008; + + $header = pack("vv", $record, $length); + $data = pack("v", $grbit); + $data .= pack("C", $chKey); + $data .= pack("C", $cch); + $data .= pack("v", $cce); + $data .= pack("v", $ixals); + $data .= pack("v", $itab); + $data .= pack("C", $cchCustMenu); + $data .= pack("C", $cchDescription); + $data .= pack("C", $cchHelptopic); + $data .= pack("C", $cchStatustext); + $data .= pack("C", $rgch); + $data .= pack("C", $unknown01); + $data .= pack("v", $unknown02); + // Column definition + $data .= pack("C", $unknown03); + $data .= pack("v", $unknown04); + $data .= pack("v", $unknown05); + $data .= pack("v", $unknown06); + $data .= pack("v", $unknown07); + $data .= pack("v", $unknown08); + $data .= pack("v", $index); + $data .= pack("v", $index); + $data .= pack("v", 0x0000); + $data .= pack("v", 0x3fff); + $data .= pack("C", $colmin); + $data .= pack("C", $colmax); + // Row definition + $data .= pack("C", $unknown03); + $data .= pack("v", $unknown04); + $data .= pack("v", $unknown05); + $data .= pack("v", $unknown06); + $data .= pack("v", $unknown07); + $data .= pack("v", $unknown08); + $data .= pack("v", $index); + $data .= pack("v", $index); + $data .= pack("v", $rowmin); + $data .= pack("v", $rowmax); + $data .= pack("C", 0x00); + $data .= pack("C", 0xff); + // End of data + $data .= pack("C", 0x10); + $this->_append($header . $data); + } + + /** + * Stores the COUNTRY record for localization + * + * @return string + */ + private function _writeCountry() + { + $record = 0x008C; // Record identifier + $length = 4; // Number of bytes to follow + + $header = pack('vv', $record, $length); + /* using the same country code always for simplicity */ + $data = pack('vv', $this->_country_code, $this->_country_code); + //$this->_append($header . $data); + return $this->writeData($header . $data); + } + + /** + * Write the RECALCID record + * + * @return string + */ + private function _writeRecalcId() + { + $record = 0x01C1; // Record identifier + $length = 8; // Number of bytes to follow + + $header = pack('vv', $record, $length); + + // by inspection of real Excel files, MS Office Excel 2007 writes this + $data = pack('VV', 0x000001C1, 0x00001E667); + + return $this->writeData($header . $data); + } + + /** + * Stores the PALETTE biff record. + */ + private function _writePalette() + { + $aref = $this->_palette; + + $record = 0x0092; // Record identifier + $length = 2 + 4 * count($aref); // Number of bytes to follow + $ccv = count($aref); // Number of RGB values to follow + $data = ''; // The RGB data + + // Pack the RGB data + foreach ($aref as $color) { + foreach ($color as $byte) { + $data .= pack("C",$byte); + } + } + + $header = pack("vvv", $record, $length, $ccv); + $this->_append($header . $data); + } + + /** + * Handling of the SST continue blocks is complicated by the need to include an + * additional continuation byte depending on whether the string is split between + * blocks or whether it starts at the beginning of the block. (There are also + * additional complications that will arise later when/if Rich Strings are + * supported). + * + * The Excel documentation says that the SST record should be followed by an + * EXTSST record. The EXTSST record is a hash table that is used to optimise + * access to SST. However, despite the documentation it doesn't seem to be + * required so we will ignore it. + * + * @return string Binary data + */ + private function _writeSharedStringsTable() + { + // maximum size of record data (excluding record header) + $continue_limit = 8224; + + // initialize array of record data blocks + $recordDatas = array(); + + // start SST record data block with total number of strings, total number of unique strings + $recordData = pack("VV", $this->_str_total, $this->_str_unique); + + // loop through all (unique) strings in shared strings table + foreach (array_keys($this->_str_table) as $string) { + + // here $string is a BIFF8 encoded string + + // length = character count + $headerinfo = unpack("vlength/Cencoding", $string); + + // currently, this is always 1 = uncompressed + $encoding = $headerinfo["encoding"]; + + // initialize finished writing current $string + $finished = false; + + while ($finished === false) { + + // normally, there will be only one cycle, but if string cannot immediately be written as is + // there will be need for more than one cylcle, if string longer than one record data block, there + // may be need for even more cycles + + if (strlen($recordData) + strlen($string) <= $continue_limit) { + // then we can write the string (or remainder of string) without any problems + $recordData .= $string; + + if (strlen($recordData) + strlen($string) == $continue_limit) { + // we close the record data block, and initialize a new one + $recordDatas[] = $recordData; + $recordData = ''; + } + + // we are finished writing this string + $finished = true; + } else { + // special treatment writing the string (or remainder of the string) + // If the string is very long it may need to be written in more than one CONTINUE record. + + // check how many bytes more there is room for in the current record + $space_remaining = $continue_limit - strlen($recordData); + + // minimum space needed + // uncompressed: 2 byte string length length field + 1 byte option flags + 2 byte character + // compressed: 2 byte string length length field + 1 byte option flags + 1 byte character + $min_space_needed = ($encoding == 1) ? 5 : 4; + + // We have two cases + // 1. space remaining is less than minimum space needed + // here we must waste the space remaining and move to next record data block + // 2. space remaining is greater than or equal to minimum space needed + // here we write as much as we can in the current block, then move to next record data block + + // 1. space remaining is less than minimum space needed + if ($space_remaining < $min_space_needed) { + // we close the block, store the block data + $recordDatas[] = $recordData; + + // and start new record data block where we start writing the string + $recordData = ''; + + // 2. space remaining is greater than or equal to minimum space needed + } else { + // initialize effective remaining space, for Unicode strings this may need to be reduced by 1, see below + $effective_space_remaining = $space_remaining; + + // for uncompressed strings, sometimes effective space remaining is reduced by 1 + if ( $encoding == 1 && (strlen($string) - $space_remaining) % 2 == 1 ) { + --$effective_space_remaining; + } + + // one block fininshed, store the block data + $recordData .= substr($string, 0, $effective_space_remaining); + + $string = substr($string, $effective_space_remaining); // for next cycle in while loop + $recordDatas[] = $recordData; + + // start new record data block with the repeated option flags + $recordData = pack('C', $encoding); + } + } + } + } + + // Store the last record data block unless it is empty + // if there was no need for any continue records, this will be the for SST record data block itself + if (strlen($recordData) > 0) { + $recordDatas[] = $recordData; + } + + // combine into one chunk with all the blocks SST, CONTINUE,... + $chunk = ''; + foreach ($recordDatas as $i => $recordData) { + // first block should have the SST record header, remaing should have CONTINUE header + $record = ($i == 0) ? 0x00FC : 0x003C; + + $header = pack("vv", $record, strlen($recordData)); + $data = $header . $recordData; + + $chunk .= $this->writeData($data); + } + + return $chunk; + } + + /** + * Writes the MSODRAWINGGROUP record if needed. Possibly split using CONTINUE records. + */ + private function _writeMsoDrawingGroup() + { + // write the Escher stream if necessary + if (isset($this->_escher)) { + $writer = new PHPExcel_Writer_Excel5_Escher($this->_escher); + $data = $writer->close(); + + $record = 0x00EB; + $length = strlen($data); + $header = pack("vv", $record, $length); + + return $this->writeData($header . $data); + + } else { + return ''; + } + } + + /** + * Get Escher object + * + * @return PHPExcel_Shared_Escher + */ + public function getEscher() + { + return $this->_escher; + } + + /** + * Set Escher object + * + * @param PHPExcel_Shared_Escher $pValue + */ + public function setEscher(PHPExcel_Shared_Escher $pValue = null) + { + $this->_escher = $pValue; + } +} diff --git a/lib/phpexcel/PHPExcel/Writer/Excel5/Worksheet.php b/lib/phpexcel/PHPExcel/Writer/Excel5/Worksheet.php new file mode 100644 index 0000000..55da26f --- /dev/null +++ b/lib/phpexcel/PHPExcel/Writer/Excel5/Worksheet.php @@ -0,0 +1,3681 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel5 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + +// Original file header of PEAR::Spreadsheet_Excel_Writer_Worksheet (used as the base for this class): +// ----------------------------------------------------------------------------------------- +// /* +// * Module written/ported by Xavier Noguer <xnoguer@rezebra.com> +// * +// * The majority of this is _NOT_ my code. I simply ported it from the +// * PERL Spreadsheet::WriteExcel module. +// * +// * The author of the Spreadsheet::WriteExcel module is John McNamara +// * <jmcnamara@cpan.org> +// * +// * I _DO_ maintain this code, and John McNamara has nothing to do with the +// * porting of this code to PHP. Any questions directly related to this +// * class library should be directed to me. +// * +// * License Information: +// * +// * Spreadsheet_Excel_Writer: A library for generating Excel Spreadsheets +// * Copyright (c) 2002-2003 Xavier Noguer xnoguer@rezebra.com +// * +// * This library is free software; you can redistribute it and/or +// * modify it under the terms of the GNU Lesser General Public +// * License as published by the Free Software Foundation; either +// * version 2.1 of the License, or (at your option) any later version. +// * +// * This library is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// * Lesser General Public License for more details. +// * +// * You should have received a copy of the GNU Lesser General Public +// * License along with this library; if not, write to the Free Software +// * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// */ + + +/** + * PHPExcel_Writer_Excel5_Worksheet + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel5 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_Excel5_Worksheet extends PHPExcel_Writer_Excel5_BIFFwriter +{ + /** + * Formula parser + * + * @var PHPExcel_Writer_Excel5_Parser + */ + private $_parser; + + /** + * Maximum number of characters for a string (LABEL record in BIFF5) + * @var integer + */ + public $_xls_strmax; + + /** + * Array containing format information for columns + * @var array + */ + public $_colinfo; + + /** + * Array containing the selected area for the worksheet + * @var array + */ + public $_selection; + + /** + * The active pane for the worksheet + * @var integer + */ + public $_active_pane; + + /** + * Whether to use outline. + * @var integer + */ + public $_outline_on; + + /** + * Auto outline styles. + * @var bool + */ + public $_outline_style; + + /** + * Whether to have outline summary below. + * @var bool + */ + public $_outline_below; + + /** + * Whether to have outline summary at the right. + * @var bool + */ + public $_outline_right; + + /** + * Reference to the total number of strings in the workbook + * @var integer + */ + public $_str_total; + + /** + * Reference to the number of unique strings in the workbook + * @var integer + */ + public $_str_unique; + + /** + * Reference to the array containing all the unique strings in the workbook + * @var array + */ + public $_str_table; + + /** + * Color cache + */ + private $_colors; + + /** + * Index of first used row (at least 0) + * @var int + */ + private $_firstRowIndex; + + /** + * Index of last used row. (no used rows means -1) + * @var int + */ + private $_lastRowIndex; + + /** + * Index of first used column (at least 0) + * @var int + */ + private $_firstColumnIndex; + + /** + * Index of last used column (no used columns means -1) + * @var int + */ + private $_lastColumnIndex; + + /** + * Sheet object + * @var PHPExcel_Worksheet + */ + public $_phpSheet; + + /** + * Count cell style Xfs + * + * @var int + */ + private $_countCellStyleXfs; + + /** + * Escher object corresponding to MSODRAWING + * + * @var PHPExcel_Shared_Escher + */ + private $_escher; + + /** + * Array of font hashes associated to FONT records index + * + * @var array + */ + public $_fntHashIndex; + + /** + * Constructor + * + * @param int &$str_total Total number of strings + * @param int &$str_unique Total number of unique strings + * @param array &$str_table String Table + * @param array &$colors Colour Table + * @param mixed $parser The formula parser created for the Workbook + * @param boolean $preCalculateFormulas Flag indicating whether formulas should be calculated or just written + * @param string $phpSheet The worksheet to write + * @param PHPExcel_Worksheet $phpSheet + */ + public function __construct(&$str_total, &$str_unique, &$str_table, &$colors, + $parser, $preCalculateFormulas, $phpSheet) + { + // It needs to call its parent's constructor explicitly + parent::__construct(); + + // change BIFFwriter limit for CONTINUE records +// $this->_limit = 8224; + + + $this->_preCalculateFormulas = $preCalculateFormulas; + $this->_str_total = &$str_total; + $this->_str_unique = &$str_unique; + $this->_str_table = &$str_table; + $this->_colors = &$colors; + $this->_parser = $parser; + + $this->_phpSheet = $phpSheet; + + //$this->ext_sheets = array(); + //$this->offset = 0; + $this->_xls_strmax = 255; + $this->_colinfo = array(); + $this->_selection = array(0,0,0,0); + $this->_active_pane = 3; + + $this->_print_headers = 0; + + $this->_outline_style = 0; + $this->_outline_below = 1; + $this->_outline_right = 1; + $this->_outline_on = 1; + + $this->_fntHashIndex = array(); + + // calculate values for DIMENSIONS record + $minR = 1; + $minC = 'A'; + + $maxR = $this->_phpSheet->getHighestRow(); + $maxC = $this->_phpSheet->getHighestColumn(); + + // Determine lowest and highest column and row +// $this->_firstRowIndex = ($minR > 65535) ? 65535 : $minR; + $this->_lastRowIndex = ($maxR > 65535) ? 65535 : $maxR ; + + $this->_firstColumnIndex = PHPExcel_Cell::columnIndexFromString($minC); + $this->_lastColumnIndex = PHPExcel_Cell::columnIndexFromString($maxC); + +// if ($this->_firstColumnIndex > 255) $this->_firstColumnIndex = 255; + if ($this->_lastColumnIndex > 255) $this->_lastColumnIndex = 255; + + $this->_countCellStyleXfs = count($phpSheet->getParent()->getCellStyleXfCollection()); + } + + /** + * Add data to the beginning of the workbook (note the reverse order) + * and to the end of the workbook. + * + * @access public + * @see PHPExcel_Writer_Excel5_Workbook::storeWorkbook() + */ + function close() + { + $_phpSheet = $this->_phpSheet; + + $num_sheets = $_phpSheet->getParent()->getSheetCount(); + + // Write BOF record + $this->_storeBof(0x0010); + + // Write PRINTHEADERS + $this->_writePrintHeaders(); + + // Write PRINTGRIDLINES + $this->_writePrintGridlines(); + + // Write GRIDSET + $this->_writeGridset(); + + // Calculate column widths + $_phpSheet->calculateColumnWidths(); + + // Column dimensions + if (($defaultWidth = $_phpSheet->getDefaultColumnDimension()->getWidth()) < 0) { + $defaultWidth = PHPExcel_Shared_Font::getDefaultColumnWidthByFont($_phpSheet->getParent()->getDefaultStyle()->getFont()); + } + + $columnDimensions = $_phpSheet->getColumnDimensions(); + $maxCol = $this->_lastColumnIndex -1; + for ($i = 0; $i <= $maxCol; ++$i) { + $hidden = 0; + $level = 0; + $xfIndex = 15; // there are 15 cell style Xfs + + $width = $defaultWidth; + + $columnLetter = PHPExcel_Cell::stringFromColumnIndex($i); + if (isset($columnDimensions[$columnLetter])) { + $columnDimension = $columnDimensions[$columnLetter]; + if ($columnDimension->getWidth() >= 0) { + $width = $columnDimension->getWidth(); + } + $hidden = $columnDimension->getVisible() ? 0 : 1; + $level = $columnDimension->getOutlineLevel(); + $xfIndex = $columnDimension->getXfIndex() + 15; // there are 15 cell style Xfs + } + + // Components of _colinfo: + // $firstcol first column on the range + // $lastcol last column on the range + // $width width to set + // $xfIndex The optional cell style Xf index to apply to the columns + // $hidden The optional hidden atribute + // $level The optional outline level + $this->_colinfo[] = array($i, $i, $width, $xfIndex, $hidden, $level); + } + + // Write GUTS + $this->_writeGuts(); + + // Write DEFAULTROWHEIGHT + $this->_writeDefaultRowHeight(); + + // Write WSBOOL + $this->_writeWsbool(); + + // Write horizontal and vertical page breaks + $this->_writeBreaks(); + + // Write page header + $this->_writeHeader(); + + // Write page footer + $this->_writeFooter(); + + // Write page horizontal centering + $this->_writeHcenter(); + + // Write page vertical centering + $this->_writeVcenter(); + + // Write left margin + $this->_writeMarginLeft(); + + // Write right margin + $this->_writeMarginRight(); + + // Write top margin + $this->_writeMarginTop(); + + // Write bottom margin + $this->_writeMarginBottom(); + + // Write page setup + $this->_writeSetup(); + + // Write sheet protection + $this->_writeProtect(); + + // Write SCENPROTECT + $this->_writeScenProtect(); + + // Write OBJECTPROTECT + $this->_writeObjectProtect(); + + // Write sheet password + $this->_writePassword(); + + // Write DEFCOLWIDTH record + $this->_writeDefcol(); + + // Write the COLINFO records if they exist + if (!empty($this->_colinfo)) { + $colcount = count($this->_colinfo); + for ($i = 0; $i < $colcount; ++$i) { + $this->_writeColinfo($this->_colinfo[$i]); + } + } + $autoFilterRange = $_phpSheet->getAutoFilter()->getRange(); + if (!empty($autoFilterRange)) { + // Write AUTOFILTERINFO + $this->_writeAutoFilterInfo(); + } + + // Write sheet dimensions + $this->_writeDimensions(); + + // Row dimensions + foreach ($_phpSheet->getRowDimensions() as $rowDimension) { + $xfIndex = $rowDimension->getXfIndex() + 15; // there are 15 cellXfs + $this->_writeRow( $rowDimension->getRowIndex() - 1, $rowDimension->getRowHeight(), $xfIndex, ($rowDimension->getVisible() ? '0' : '1'), $rowDimension->getOutlineLevel() ); + } + + // Write Cells + foreach ($_phpSheet->getCellCollection() as $cellID) { + $cell = $_phpSheet->getCell($cellID); + $row = $cell->getRow() - 1; + $column = PHPExcel_Cell::columnIndexFromString($cell->getColumn()) - 1; + + // Don't break Excel! +// if ($row + 1 > 65536 or $column + 1 > 256) { + if ($row > 65535 || $column > 255) { + break; + } + + // Write cell value + $xfIndex = $cell->getXfIndex() + 15; // there are 15 cell style Xfs + + $cVal = $cell->getValue(); + if ($cVal instanceof PHPExcel_RichText) { + // $this->_writeString($row, $column, $cVal->getPlainText(), $xfIndex); + $arrcRun = array(); + $str_len = PHPExcel_Shared_String::CountCharacters($cVal->getPlainText(), 'UTF-8'); + $str_pos = 0; + $elements = $cVal->getRichTextElements(); + foreach ($elements as $element) { + // FONT Index + if ($element instanceof PHPExcel_RichText_Run) { + $str_fontidx = $this->_fntHashIndex[$element->getFont()->getHashCode()]; + } + else { + $str_fontidx = 0; + } + $arrcRun[] = array('strlen' => $str_pos, 'fontidx' => $str_fontidx); + // Position FROM + $str_pos += PHPExcel_Shared_String::CountCharacters($element->getText(), 'UTF-8'); + } + $this->_writeRichTextString($row, $column, $cVal->getPlainText(), $xfIndex, $arrcRun); + } else { + switch ($cell->getDatatype()) { + case PHPExcel_Cell_DataType::TYPE_STRING: + case PHPExcel_Cell_DataType::TYPE_NULL: + if ($cVal === '' || $cVal === null) { + $this->_writeBlank($row, $column, $xfIndex); + } else { + $this->_writeString($row, $column, $cVal, $xfIndex); + } + break; + + case PHPExcel_Cell_DataType::TYPE_NUMERIC: + $this->_writeNumber($row, $column, $cVal, $xfIndex); + break; + + case PHPExcel_Cell_DataType::TYPE_FORMULA: + $calculatedValue = $this->_preCalculateFormulas ? + $cell->getCalculatedValue() : null; + $this->_writeFormula($row, $column, $cVal, $xfIndex, $calculatedValue); + break; + + case PHPExcel_Cell_DataType::TYPE_BOOL: + $this->_writeBoolErr($row, $column, $cVal, 0, $xfIndex); + break; + + case PHPExcel_Cell_DataType::TYPE_ERROR: + $this->_writeBoolErr($row, $column, self::_mapErrorCode($cVal), 1, $xfIndex); + break; + + } + } + } + + // Append + $this->_writeMsoDrawing(); + + // Write WINDOW2 record + $this->_writeWindow2(); + + // Write PLV record + $this->_writePageLayoutView(); + + // Write ZOOM record + $this->_writeZoom(); + if ($_phpSheet->getFreezePane()) { + $this->_writePanes(); + } + + // Write SELECTION record + $this->_writeSelection(); + + // Write MergedCellsTable Record + $this->_writeMergedCells(); + + // Hyperlinks + foreach ($_phpSheet->getHyperLinkCollection() as $coordinate => $hyperlink) { + list($column, $row) = PHPExcel_Cell::coordinateFromString($coordinate); + + $url = $hyperlink->getUrl(); + + if ( strpos($url, 'sheet://') !== false ) { + // internal to current workbook + $url = str_replace('sheet://', 'internal:', $url); + + } else if ( preg_match('/^(http:|https:|ftp:|mailto:)/', $url) ) { + // URL + // $url = $url; + + } else { + // external (local file) + $url = 'external:' . $url; + } + + $this->_writeUrl($row - 1, PHPExcel_Cell::columnIndexFromString($column) - 1, $url); + } + + $this->_writeDataValidity(); + $this->_writeSheetLayout(); + + // Write SHEETPROTECTION record + $this->_writeSheetProtection(); + $this->_writeRangeProtection(); + + $arrConditionalStyles = $_phpSheet->getConditionalStylesCollection(); + if(!empty($arrConditionalStyles)){ + $arrConditional = array(); + // @todo CFRule & CFHeader + // Write CFHEADER record + $this->_writeCFHeader(); + // Write ConditionalFormattingTable records + foreach ($arrConditionalStyles as $cellCoordinate => $conditionalStyles) { + foreach ($conditionalStyles as $conditional) { + if($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_EXPRESSION + || $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS){ + if(!in_array($conditional->getHashCode(), $arrConditional)){ + $arrConditional[] = $conditional->getHashCode(); + // Write CFRULE record + $this->_writeCFRule($conditional); + } + } + } + } + } + + $this->_storeEof(); + } + + /** + * Write a cell range address in BIFF8 + * always fixed range + * See section 2.5.14 in OpenOffice.org's Documentation of the Microsoft Excel File Format + * + * @param string $range E.g. 'A1' or 'A1:B6' + * @return string Binary data + */ + private function _writeBIFF8CellRangeAddressFixed($range = 'A1') + { + $explodes = explode(':', $range); + + // extract first cell, e.g. 'A1' + $firstCell = $explodes[0]; + + // extract last cell, e.g. 'B6' + if (count($explodes) == 1) { + $lastCell = $firstCell; + } else { + $lastCell = $explodes[1]; + } + + $firstCellCoordinates = PHPExcel_Cell::coordinateFromString($firstCell); // e.g. array(0, 1) + $lastCellCoordinates = PHPExcel_Cell::coordinateFromString($lastCell); // e.g. array(1, 6) + + return(pack('vvvv', + $firstCellCoordinates[1] - 1, + $lastCellCoordinates[1] - 1, + PHPExcel_Cell::columnIndexFromString($firstCellCoordinates[0]) - 1, + PHPExcel_Cell::columnIndexFromString($lastCellCoordinates[0]) - 1 + )); + } + + /** + * Retrieves data from memory in one chunk, or from disk in $buffer + * sized chunks. + * + * @return string The data + */ + function getData() + { + $buffer = 4096; + + // Return data stored in memory + if (isset($this->_data)) { + $tmp = $this->_data; + unset($this->_data); + return $tmp; + } + // No data to return + return false; + } + + /** + * Set the option to print the row and column headers on the printed page. + * + * @access public + * @param integer $print Whether to print the headers or not. Defaults to 1 (print). + */ + function printRowColHeaders($print = 1) + { + $this->_print_headers = $print; + } + + /** + * This method sets the properties for outlining and grouping. The defaults + * correspond to Excel's defaults. + * + * @param bool $visible + * @param bool $symbols_below + * @param bool $symbols_right + * @param bool $auto_style + */ + function setOutline($visible = true, $symbols_below = true, $symbols_right = true, $auto_style = false) + { + $this->_outline_on = $visible; + $this->_outline_below = $symbols_below; + $this->_outline_right = $symbols_right; + $this->_outline_style = $auto_style; + + // Ensure this is a boolean vale for Window2 + if ($this->_outline_on) { + $this->_outline_on = 1; + } + } + + /** + * Write a double to the specified row and column (zero indexed). + * An integer can be written as a double. Excel will display an + * integer. $format is optional. + * + * Returns 0 : normal termination + * -2 : row or column out of range + * + * @param integer $row Zero indexed row + * @param integer $col Zero indexed column + * @param float $num The number to write + * @param mixed $xfIndex The optional XF format + * @return integer + */ + private function _writeNumber($row, $col, $num, $xfIndex) + { + $record = 0x0203; // Record identifier + $length = 0x000E; // Number of bytes to follow + + $header = pack("vv", $record, $length); + $data = pack("vvv", $row, $col, $xfIndex); + $xl_double = pack("d", $num); + if (self::getByteOrder()) { // if it's Big Endian + $xl_double = strrev($xl_double); + } + + $this->_append($header.$data.$xl_double); + return(0); + } + + /** + * Write a LABELSST record or a LABEL record. Which one depends on BIFF version + * + * @param int $row Row index (0-based) + * @param int $col Column index (0-based) + * @param string $str The string + * @param int $xfIndex Index to XF record + */ + private function _writeString($row, $col, $str, $xfIndex) + { + $this->_writeLabelSst($row, $col, $str, $xfIndex); + } + + /** + * Write a LABELSST record or a LABEL record. Which one depends on BIFF version + * It differs from _writeString by the writing of rich text strings. + * @param int $row Row index (0-based) + * @param int $col Column index (0-based) + * @param string $str The string + * @param mixed $xfIndex The XF format index for the cell + * @param array $arrcRun Index to Font record and characters beginning + */ + private function _writeRichTextString($row, $col, $str, $xfIndex, $arrcRun){ + $record = 0x00FD; // Record identifier + $length = 0x000A; // Bytes to follow + $str = PHPExcel_Shared_String::UTF8toBIFF8UnicodeShort($str, $arrcRun); + + /* check if string is already present */ + if (!isset($this->_str_table[$str])) { + $this->_str_table[$str] = $this->_str_unique++; + } + $this->_str_total++; + + $header = pack('vv', $record, $length); + $data = pack('vvvV', $row, $col, $xfIndex, $this->_str_table[$str]); + $this->_append($header.$data); + } + + /** + * Write a string to the specified row and column (zero indexed). + * NOTE: there is an Excel 5 defined limit of 255 characters. + * $format is optional. + * Returns 0 : normal termination + * -2 : row or column out of range + * -3 : long string truncated to 255 chars + * + * @access public + * @param integer $row Zero indexed row + * @param integer $col Zero indexed column + * @param string $str The string to write + * @param mixed $xfIndex The XF format index for the cell + * @return integer + */ + private function _writeLabel($row, $col, $str, $xfIndex) + { + $strlen = strlen($str); + $record = 0x0204; // Record identifier + $length = 0x0008 + $strlen; // Bytes to follow + + $str_error = 0; + + if ($strlen > $this->_xls_strmax) { // LABEL must be < 255 chars + $str = substr($str, 0, $this->_xls_strmax); + $length = 0x0008 + $this->_xls_strmax; + $strlen = $this->_xls_strmax; + $str_error = -3; + } + + $header = pack("vv", $record, $length); + $data = pack("vvvv", $row, $col, $xfIndex, $strlen); + $this->_append($header . $data . $str); + return($str_error); + } + + /** + * Write a string to the specified row and column (zero indexed). + * This is the BIFF8 version (no 255 chars limit). + * $format is optional. + * Returns 0 : normal termination + * -2 : row or column out of range + * -3 : long string truncated to 255 chars + * + * @access public + * @param integer $row Zero indexed row + * @param integer $col Zero indexed column + * @param string $str The string to write + * @param mixed $xfIndex The XF format index for the cell + * @return integer + */ + private function _writeLabelSst($row, $col, $str, $xfIndex) + { + $record = 0x00FD; // Record identifier + $length = 0x000A; // Bytes to follow + + $str = PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($str); + + /* check if string is already present */ + if (!isset($this->_str_table[$str])) { + $this->_str_table[$str] = $this->_str_unique++; + } + $this->_str_total++; + + $header = pack('vv', $record, $length); + $data = pack('vvvV', $row, $col, $xfIndex, $this->_str_table[$str]); + $this->_append($header.$data); + } + + /** + * Writes a note associated with the cell given by the row and column. + * NOTE records don't have a length limit. + * + * @param integer $row Zero indexed row + * @param integer $col Zero indexed column + * @param string $note The note to write + */ + private function _writeNote($row, $col, $note) + { + $note_length = strlen($note); + $record = 0x001C; // Record identifier + $max_length = 2048; // Maximun length for a NOTE record + + // Length for this record is no more than 2048 + 6 + $length = 0x0006 + min($note_length, 2048); + $header = pack("vv", $record, $length); + $data = pack("vvv", $row, $col, $note_length); + $this->_append($header . $data . substr($note, 0, 2048)); + + for ($i = $max_length; $i < $note_length; $i += $max_length) { + $chunk = substr($note, $i, $max_length); + $length = 0x0006 + strlen($chunk); + $header = pack("vv", $record, $length); + $data = pack("vvv", -1, 0, strlen($chunk)); + $this->_append($header.$data.$chunk); + } + return(0); + } + + /** + * Write a blank cell to the specified row and column (zero indexed). + * A blank cell is used to specify formatting without adding a string + * or a number. + * + * A blank cell without a format serves no purpose. Therefore, we don't write + * a BLANK record unless a format is specified. + * + * Returns 0 : normal termination (including no format) + * -1 : insufficient number of arguments + * -2 : row or column out of range + * + * @param integer $row Zero indexed row + * @param integer $col Zero indexed column + * @param mixed $xfIndex The XF format index + */ + function _writeBlank($row, $col, $xfIndex) + { + $record = 0x0201; // Record identifier + $length = 0x0006; // Number of bytes to follow + + $header = pack("vv", $record, $length); + $data = pack("vvv", $row, $col, $xfIndex); + $this->_append($header . $data); + return 0; + } + + /** + * Write a boolean or an error type to the specified row and column (zero indexed) + * + * @param int $row Row index (0-based) + * @param int $col Column index (0-based) + * @param int $value + * @param boolean $isError Error or Boolean? + * @param int $xfIndex + */ + private function _writeBoolErr($row, $col, $value, $isError, $xfIndex) + { + $record = 0x0205; + $length = 8; + + $header = pack("vv", $record, $length); + $data = pack("vvvCC", $row, $col, $xfIndex, $value, $isError); + $this->_append($header . $data); + return 0; + } + + /** + * Write a formula to the specified row and column (zero indexed). + * The textual representation of the formula is passed to the parser in + * Parser.php which returns a packed binary string. + * + * Returns 0 : normal termination + * -1 : formula errors (bad formula) + * -2 : row or column out of range + * + * @param integer $row Zero indexed row + * @param integer $col Zero indexed column + * @param string $formula The formula text string + * @param mixed $xfIndex The XF format index + * @param mixed $calculatedValue Calculated value + * @return integer + */ + private function _writeFormula($row, $col, $formula, $xfIndex, $calculatedValue) + { + $record = 0x0006; // Record identifier + + // Initialize possible additional value for STRING record that should be written after the FORMULA record? + $stringValue = null; + + // calculated value + if (isset($calculatedValue)) { + // Since we can't yet get the data type of the calculated value, + // we use best effort to determine data type + if (is_bool($calculatedValue)) { + // Boolean value + $num = pack('CCCvCv', 0x01, 0x00, (int)$calculatedValue, 0x00, 0x00, 0xFFFF); + } elseif (is_int($calculatedValue) || is_float($calculatedValue)) { + // Numeric value + $num = pack('d', $calculatedValue); + } elseif (is_string($calculatedValue)) { + if (array_key_exists($calculatedValue, PHPExcel_Cell_DataType::getErrorCodes())) { + // Error value + $num = pack('CCCvCv', 0x02, 0x00, self::_mapErrorCode($calculatedValue), 0x00, 0x00, 0xFFFF); + } elseif ($calculatedValue === '') { + // Empty string (and BIFF8) + $num = pack('CCCvCv', 0x03, 0x00, 0x00, 0x00, 0x00, 0xFFFF); + } else { + // Non-empty string value (or empty string BIFF5) + $stringValue = $calculatedValue; + $num = pack('CCCvCv', 0x00, 0x00, 0x00, 0x00, 0x00, 0xFFFF); + } + } else { + // We are really not supposed to reach here + $num = pack('d', 0x00); + } + } else { + $num = pack('d', 0x00); + } + + $grbit = 0x03; // Option flags + $unknown = 0x0000; // Must be zero + + // Strip the '=' or '@' sign at the beginning of the formula string + if ($formula{0} == '=') { + $formula = substr($formula,1); + } else { + // Error handling + $this->_writeString($row, $col, 'Unrecognised character for formula'); + return -1; + } + + // Parse the formula using the parser in Parser.php + try { + $error = $this->_parser->parse($formula); + $formula = $this->_parser->toReversePolish(); + + $formlen = strlen($formula); // Length of the binary string + $length = 0x16 + $formlen; // Length of the record data + + $header = pack("vv", $record, $length); + + $data = pack("vvv", $row, $col, $xfIndex) + . $num + . pack("vVv", $grbit, $unknown, $formlen); + $this->_append($header . $data . $formula); + + // Append also a STRING record if necessary + if ($stringValue !== null) { + $this->_writeStringRecord($stringValue); + } + + return 0; + + } catch (PHPExcel_Exception $e) { + // do nothing + } + + } + + /** + * Write a STRING record. This + * + * @param string $stringValue + */ + private function _writeStringRecord($stringValue) + { + $record = 0x0207; // Record identifier + $data = PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($stringValue); + + $length = strlen($data); + $header = pack('vv', $record, $length); + + $this->_append($header . $data); + } + + /** + * Write a hyperlink. + * This is comprised of two elements: the visible label and + * the invisible link. The visible label is the same as the link unless an + * alternative string is specified. The label is written using the + * _writeString() method. Therefore the 255 characters string limit applies. + * $string and $format are optional. + * + * The hyperlink can be to a http, ftp, mail, internal sheet (not yet), or external + * directory url. + * + * Returns 0 : normal termination + * -2 : row or column out of range + * -3 : long string truncated to 255 chars + * + * @param integer $row Row + * @param integer $col Column + * @param string $url URL string + * @return integer + */ + private function _writeUrl($row, $col, $url) + { + // Add start row and col to arg list + return($this->_writeUrlRange($row, $col, $row, $col, $url)); + } + + /** + * This is the more general form of _writeUrl(). It allows a hyperlink to be + * written to a range of cells. This function also decides the type of hyperlink + * to be written. These are either, Web (http, ftp, mailto), Internal + * (Sheet1!A1) or external ('c:\temp\foo.xls#Sheet1!A1'). + * + * @access private + * @see _writeUrl() + * @param integer $row1 Start row + * @param integer $col1 Start column + * @param integer $row2 End row + * @param integer $col2 End column + * @param string $url URL string + * @return integer + */ + function _writeUrlRange($row1, $col1, $row2, $col2, $url) + { + // Check for internal/external sheet links or default to web link + if (preg_match('[^internal:]', $url)) { + return($this->_writeUrlInternal($row1, $col1, $row2, $col2, $url)); + } + if (preg_match('[^external:]', $url)) { + return($this->_writeUrlExternal($row1, $col1, $row2, $col2, $url)); + } + return($this->_writeUrlWeb($row1, $col1, $row2, $col2, $url)); + } + + /** + * Used to write http, ftp and mailto hyperlinks. + * The link type ($options) is 0x03 is the same as absolute dir ref without + * sheet. However it is differentiated by the $unknown2 data stream. + * + * @access private + * @see _writeUrl() + * @param integer $row1 Start row + * @param integer $col1 Start column + * @param integer $row2 End row + * @param integer $col2 End column + * @param string $url URL string + * @return integer + */ + function _writeUrlWeb($row1, $col1, $row2, $col2, $url) + { + $record = 0x01B8; // Record identifier + $length = 0x00000; // Bytes to follow + + // Pack the undocumented parts of the hyperlink stream + $unknown1 = pack("H*", "D0C9EA79F9BACE118C8200AA004BA90B02000000"); + $unknown2 = pack("H*", "E0C9EA79F9BACE118C8200AA004BA90B"); + + // Pack the option flags + $options = pack("V", 0x03); + + // Convert URL to a null terminated wchar string + $url = join("\0", preg_split("''", $url, -1, PREG_SPLIT_NO_EMPTY)); + $url = $url . "\0\0\0"; + + // Pack the length of the URL + $url_len = pack("V", strlen($url)); + + // Calculate the data length + $length = 0x34 + strlen($url); + + // Pack the header data + $header = pack("vv", $record, $length); + $data = pack("vvvv", $row1, $row2, $col1, $col2); + + // Write the packed data + $this->_append($header . $data . + $unknown1 . $options . + $unknown2 . $url_len . $url); + return 0; + } + + /** + * Used to write internal reference hyperlinks such as "Sheet1!A1". + * + * @access private + * @see _writeUrl() + * @param integer $row1 Start row + * @param integer $col1 Start column + * @param integer $row2 End row + * @param integer $col2 End column + * @param string $url URL string + * @return integer + */ + function _writeUrlInternal($row1, $col1, $row2, $col2, $url) + { + $record = 0x01B8; // Record identifier + $length = 0x00000; // Bytes to follow + + // Strip URL type + $url = preg_replace('/^internal:/', '', $url); + + // Pack the undocumented parts of the hyperlink stream + $unknown1 = pack("H*", "D0C9EA79F9BACE118C8200AA004BA90B02000000"); + + // Pack the option flags + $options = pack("V", 0x08); + + // Convert the URL type and to a null terminated wchar string + $url .= "\0"; + + // character count + $url_len = PHPExcel_Shared_String::CountCharacters($url); + $url_len = pack('V', $url_len); + + $url = PHPExcel_Shared_String::ConvertEncoding($url, 'UTF-16LE', 'UTF-8'); + + // Calculate the data length + $length = 0x24 + strlen($url); + + // Pack the header data + $header = pack("vv", $record, $length); + $data = pack("vvvv", $row1, $row2, $col1, $col2); + + // Write the packed data + $this->_append($header . $data . + $unknown1 . $options . + $url_len . $url); + return 0; + } + + /** + * Write links to external directory names such as 'c:\foo.xls', + * c:\foo.xls#Sheet1!A1', '../../foo.xls'. and '../../foo.xls#Sheet1!A1'. + * + * Note: Excel writes some relative links with the $dir_long string. We ignore + * these cases for the sake of simpler code. + * + * @access private + * @see _writeUrl() + * @param integer $row1 Start row + * @param integer $col1 Start column + * @param integer $row2 End row + * @param integer $col2 End column + * @param string $url URL string + * @return integer + */ + function _writeUrlExternal($row1, $col1, $row2, $col2, $url) + { + // Network drives are different. We will handle them separately + // MS/Novell network drives and shares start with \\ + if (preg_match('[^external:\\\\]', $url)) { + return; //($this->_writeUrlExternal_net($row1, $col1, $row2, $col2, $url, $str, $format)); + } + + $record = 0x01B8; // Record identifier + $length = 0x00000; // Bytes to follow + + // Strip URL type and change Unix dir separator to Dos style (if needed) + // + $url = preg_replace('/^external:/', '', $url); + $url = preg_replace('/\//', "\\", $url); + + // Determine if the link is relative or absolute: + // relative if link contains no dir separator, "somefile.xls" + // relative if link starts with up-dir, "..\..\somefile.xls" + // otherwise, absolute + + $absolute = 0x00; // relative path + if ( preg_match('/^[A-Z]:/', $url) ) { + $absolute = 0x02; // absolute path on Windows, e.g. C:\... + } + $link_type = 0x01 | $absolute; + + // Determine if the link contains a sheet reference and change some of the + // parameters accordingly. + // Split the dir name and sheet name (if it exists) + $dir_long = $url; + if (preg_match("/\#/", $url)) { + $link_type |= 0x08; + } + + + // Pack the link type + $link_type = pack("V", $link_type); + + // Calculate the up-level dir count e.g.. (..\..\..\ == 3) + $up_count = preg_match_all("/\.\.\\\/", $dir_long, $useless); + $up_count = pack("v", $up_count); + + // Store the short dos dir name (null terminated) + $dir_short = preg_replace("/\.\.\\\/", '', $dir_long) . "\0"; + + // Store the long dir name as a wchar string (non-null terminated) + $dir_long = $dir_long . "\0"; + + // Pack the lengths of the dir strings + $dir_short_len = pack("V", strlen($dir_short) ); + $dir_long_len = pack("V", strlen($dir_long) ); + $stream_len = pack("V", 0);//strlen($dir_long) + 0x06); + + // Pack the undocumented parts of the hyperlink stream + $unknown1 = pack("H*",'D0C9EA79F9BACE118C8200AA004BA90B02000000' ); + $unknown2 = pack("H*",'0303000000000000C000000000000046' ); + $unknown3 = pack("H*",'FFFFADDE000000000000000000000000000000000000000'); + $unknown4 = pack("v", 0x03 ); + + // Pack the main data stream + $data = pack("vvvv", $row1, $row2, $col1, $col2) . + $unknown1 . + $link_type . + $unknown2 . + $up_count . + $dir_short_len. + $dir_short . + $unknown3 . + $stream_len ;/*. + $dir_long_len . + $unknown4 . + $dir_long . + $sheet_len . + $sheet ;*/ + + // Pack the header data + $length = strlen($data); + $header = pack("vv", $record, $length); + + // Write the packed data + $this->_append($header. $data); + return 0; + } + + /** + * This method is used to set the height and format for a row. + * + * @param integer $row The row to set + * @param integer $height Height we are giving to the row. + * Use null to set XF without setting height + * @param integer $xfIndex The optional cell style Xf index to apply to the columns + * @param bool $hidden The optional hidden attribute + * @param integer $level The optional outline level for row, in range [0,7] + */ + private function _writeRow($row, $height, $xfIndex, $hidden = false, $level = 0) + { + $record = 0x0208; // Record identifier + $length = 0x0010; // Number of bytes to follow + + $colMic = 0x0000; // First defined column + $colMac = 0x0000; // Last defined column + $irwMac = 0x0000; // Used by Excel to optimise loading + $reserved = 0x0000; // Reserved + $grbit = 0x0000; // Option flags + $ixfe = $xfIndex; + + if ( $height < 0 ){ + $height = null; + } + + // Use _writeRow($row, null, $XF) to set XF format without setting height + if ($height != null) { + $miyRw = $height * 20; // row height + } else { + $miyRw = 0xff; // default row height is 256 + } + + // Set the options flags. fUnsynced is used to show that the font and row + // heights are not compatible. This is usually the case for WriteExcel. + // The collapsed flag 0x10 doesn't seem to be used to indicate that a row + // is collapsed. Instead it is used to indicate that the previous row is + // collapsed. The zero height flag, 0x20, is used to collapse a row. + + $grbit |= $level; + if ($hidden) { + $grbit |= 0x0020; + } + if ($height !== null) { + $grbit |= 0x0040; // fUnsynced + } + if ($xfIndex !== 0xF) { + $grbit |= 0x0080; + } + $grbit |= 0x0100; + + $header = pack("vv", $record, $length); + $data = pack("vvvvvvvv", $row, $colMic, $colMac, $miyRw, + $irwMac,$reserved, $grbit, $ixfe); + $this->_append($header.$data); + } + + /** + * Writes Excel DIMENSIONS to define the area in which there is data. + */ + private function _writeDimensions() + { + $record = 0x0200; // Record identifier + + $length = 0x000E; + $data = pack('VVvvv' + , $this->_firstRowIndex + , $this->_lastRowIndex + 1 + , $this->_firstColumnIndex + , $this->_lastColumnIndex + 1 + , 0x0000 // reserved + ); + + $header = pack("vv", $record, $length); + $this->_append($header.$data); + } + + /** + * Write BIFF record Window2. + */ + private function _writeWindow2() + { + $record = 0x023E; // Record identifier + $length = 0x0012; + + $grbit = 0x00B6; // Option flags + $rwTop = 0x0000; // Top row visible in window + $colLeft = 0x0000; // Leftmost column visible in window + + + // The options flags that comprise $grbit + $fDspFmla = 0; // 0 - bit + $fDspGrid = $this->_phpSheet->getShowGridlines() ? 1 : 0; // 1 + $fDspRwCol = $this->_phpSheet->getShowRowColHeaders() ? 1 : 0; // 2 + $fFrozen = $this->_phpSheet->getFreezePane() ? 1 : 0; // 3 + $fDspZeros = 1; // 4 + $fDefaultHdr = 1; // 5 + $fArabic = $this->_phpSheet->getRightToLeft() ? 1 : 0; // 6 + $fDspGuts = $this->_outline_on; // 7 + $fFrozenNoSplit = 0; // 0 - bit + // no support in PHPExcel for selected sheet, therefore sheet is only selected if it is the active sheet + $fSelected = ($this->_phpSheet === $this->_phpSheet->getParent()->getActiveSheet()) ? 1 : 0; + $fPaged = 1; // 2 + $fPageBreakPreview = $this->_phpSheet->getSheetView()->getView() === PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_BREAK_PREVIEW; + + $grbit = $fDspFmla; + $grbit |= $fDspGrid << 1; + $grbit |= $fDspRwCol << 2; + $grbit |= $fFrozen << 3; + $grbit |= $fDspZeros << 4; + $grbit |= $fDefaultHdr << 5; + $grbit |= $fArabic << 6; + $grbit |= $fDspGuts << 7; + $grbit |= $fFrozenNoSplit << 8; + $grbit |= $fSelected << 9; + $grbit |= $fPaged << 10; + $grbit |= $fPageBreakPreview << 11; + + $header = pack("vv", $record, $length); + $data = pack("vvv", $grbit, $rwTop, $colLeft); + + // FIXME !!! + $rgbHdr = 0x0040; // Row/column heading and gridline color index + $zoom_factor_page_break = ($fPageBreakPreview? $this->_phpSheet->getSheetView()->getZoomScale() : 0x0000); + $zoom_factor_normal = $this->_phpSheet->getSheetView()->getZoomScaleNormal(); + + $data .= pack("vvvvV", $rgbHdr, 0x0000, $zoom_factor_page_break, $zoom_factor_normal, 0x00000000); + + $this->_append($header.$data); + } + + /** + * Write BIFF record DEFAULTROWHEIGHT. + */ + private function _writeDefaultRowHeight() + { + $defaultRowHeight = $this->_phpSheet->getDefaultRowDimension()->getRowHeight(); + + if ($defaultRowHeight < 0) { + return; + } + + // convert to twips + $defaultRowHeight = (int) 20 * $defaultRowHeight; + + $record = 0x0225; // Record identifier + $length = 0x0004; // Number of bytes to follow + + $header = pack("vv", $record, $length); + $data = pack("vv", 1, $defaultRowHeight); + $this->_append($header . $data); + } + + /** + * Write BIFF record DEFCOLWIDTH if COLINFO records are in use. + */ + private function _writeDefcol() + { + $defaultColWidth = 8; + + $record = 0x0055; // Record identifier + $length = 0x0002; // Number of bytes to follow + + $header = pack("vv", $record, $length); + $data = pack("v", $defaultColWidth); + $this->_append($header . $data); + } + + /** + * Write BIFF record COLINFO to define column widths + * + * Note: The SDK says the record length is 0x0B but Excel writes a 0x0C + * length record. + * + * @param array $col_array This is the only parameter received and is composed of the following: + * 0 => First formatted column, + * 1 => Last formatted column, + * 2 => Col width (8.43 is Excel default), + * 3 => The optional XF format of the column, + * 4 => Option flags. + * 5 => Optional outline level + */ + private function _writeColinfo($col_array) + { + if (isset($col_array[0])) { + $colFirst = $col_array[0]; + } + if (isset($col_array[1])) { + $colLast = $col_array[1]; + } + if (isset($col_array[2])) { + $coldx = $col_array[2]; + } else { + $coldx = 8.43; + } + if (isset($col_array[3])) { + $xfIndex = $col_array[3]; + } else { + $xfIndex = 15; + } + if (isset($col_array[4])) { + $grbit = $col_array[4]; + } else { + $grbit = 0; + } + if (isset($col_array[5])) { + $level = $col_array[5]; + } else { + $level = 0; + } + $record = 0x007D; // Record identifier + $length = 0x000C; // Number of bytes to follow + + $coldx *= 256; // Convert to units of 1/256 of a char + + $ixfe = $xfIndex; + $reserved = 0x0000; // Reserved + + $level = max(0, min($level, 7)); + $grbit |= $level << 8; + + $header = pack("vv", $record, $length); + $data = pack("vvvvvv", $colFirst, $colLast, $coldx, + $ixfe, $grbit, $reserved); + $this->_append($header.$data); + } + + /** + * Write BIFF record SELECTION. + */ + private function _writeSelection() + { + // look up the selected cell range + $selectedCells = $this->_phpSheet->getSelectedCells(); + $selectedCells = PHPExcel_Cell::splitRange($this->_phpSheet->getSelectedCells()); + $selectedCells = $selectedCells[0]; + if (count($selectedCells) == 2) { + list($first, $last) = $selectedCells; + } else { + $first = $selectedCells[0]; + $last = $selectedCells[0]; + } + + list($colFirst, $rwFirst) = PHPExcel_Cell::coordinateFromString($first); + $colFirst = PHPExcel_Cell::columnIndexFromString($colFirst) - 1; // base 0 column index + --$rwFirst; // base 0 row index + + list($colLast, $rwLast) = PHPExcel_Cell::coordinateFromString($last); + $colLast = PHPExcel_Cell::columnIndexFromString($colLast) - 1; // base 0 column index + --$rwLast; // base 0 row index + + // make sure we are not out of bounds + $colFirst = min($colFirst, 255); + $colLast = min($colLast, 255); + + $rwFirst = min($rwFirst, 65535); + $rwLast = min($rwLast, 65535); + + $record = 0x001D; // Record identifier + $length = 0x000F; // Number of bytes to follow + + $pnn = $this->_active_pane; // Pane position + $rwAct = $rwFirst; // Active row + $colAct = $colFirst; // Active column + $irefAct = 0; // Active cell ref + $cref = 1; // Number of refs + + if (!isset($rwLast)) { + $rwLast = $rwFirst; // Last row in reference + } + if (!isset($colLast)) { + $colLast = $colFirst; // Last col in reference + } + + // Swap last row/col for first row/col as necessary + if ($rwFirst > $rwLast) { + list($rwFirst, $rwLast) = array($rwLast, $rwFirst); + } + + if ($colFirst > $colLast) { + list($colFirst, $colLast) = array($colLast, $colFirst); + } + + $header = pack("vv", $record, $length); + $data = pack("CvvvvvvCC", $pnn, $rwAct, $colAct, + $irefAct, $cref, + $rwFirst, $rwLast, + $colFirst, $colLast); + $this->_append($header . $data); + } + + /** + * Store the MERGEDCELLS records for all ranges of merged cells + */ + private function _writeMergedCells() + { + $mergeCells = $this->_phpSheet->getMergeCells(); + $countMergeCells = count($mergeCells); + + if ($countMergeCells == 0) { + return; + } + + // maximum allowed number of merged cells per record + $maxCountMergeCellsPerRecord = 1027; + + // record identifier + $record = 0x00E5; + + // counter for total number of merged cells treated so far by the writer + $i = 0; + + // counter for number of merged cells written in record currently being written + $j = 0; + + // initialize record data + $recordData = ''; + + // loop through the merged cells + foreach ($mergeCells as $mergeCell) { + ++$i; + ++$j; + + // extract the row and column indexes + $range = PHPExcel_Cell::splitRange($mergeCell); + list($first, $last) = $range[0]; + list($firstColumn, $firstRow) = PHPExcel_Cell::coordinateFromString($first); + list($lastColumn, $lastRow) = PHPExcel_Cell::coordinateFromString($last); + + $recordData .= pack('vvvv', $firstRow - 1, $lastRow - 1, PHPExcel_Cell::columnIndexFromString($firstColumn) - 1, PHPExcel_Cell::columnIndexFromString($lastColumn) - 1); + + // flush record if we have reached limit for number of merged cells, or reached final merged cell + if ($j == $maxCountMergeCellsPerRecord or $i == $countMergeCells) { + $recordData = pack('v', $j) . $recordData; + $length = strlen($recordData); + $header = pack('vv', $record, $length); + $this->_append($header . $recordData); + + // initialize for next record, if any + $recordData = ''; + $j = 0; + } + } + } + + /** + * Write SHEETLAYOUT record + */ + private function _writeSheetLayout() + { + if (!$this->_phpSheet->isTabColorSet()) { + return; + } + + $recordData = pack( + 'vvVVVvv' + , 0x0862 + , 0x0000 // unused + , 0x00000000 // unused + , 0x00000000 // unused + , 0x00000014 // size of record data + , $this->_colors[$this->_phpSheet->getTabColor()->getRGB()] // color index + , 0x0000 // unused + ); + + $length = strlen($recordData); + + $record = 0x0862; // Record identifier + $header = pack('vv', $record, $length); + $this->_append($header . $recordData); + } + + /** + * Write SHEETPROTECTION + */ + private function _writeSheetProtection() + { + // record identifier + $record = 0x0867; + + // prepare options + $options = (int) !$this->_phpSheet->getProtection()->getObjects() + | (int) !$this->_phpSheet->getProtection()->getScenarios() << 1 + | (int) !$this->_phpSheet->getProtection()->getFormatCells() << 2 + | (int) !$this->_phpSheet->getProtection()->getFormatColumns() << 3 + | (int) !$this->_phpSheet->getProtection()->getFormatRows() << 4 + | (int) !$this->_phpSheet->getProtection()->getInsertColumns() << 5 + | (int) !$this->_phpSheet->getProtection()->getInsertRows() << 6 + | (int) !$this->_phpSheet->getProtection()->getInsertHyperlinks() << 7 + | (int) !$this->_phpSheet->getProtection()->getDeleteColumns() << 8 + | (int) !$this->_phpSheet->getProtection()->getDeleteRows() << 9 + | (int) !$this->_phpSheet->getProtection()->getSelectLockedCells() << 10 + | (int) !$this->_phpSheet->getProtection()->getSort() << 11 + | (int) !$this->_phpSheet->getProtection()->getAutoFilter() << 12 + | (int) !$this->_phpSheet->getProtection()->getPivotTables() << 13 + | (int) !$this->_phpSheet->getProtection()->getSelectUnlockedCells() << 14 ; + + // record data + $recordData = pack( + 'vVVCVVvv' + , 0x0867 // repeated record identifier + , 0x0000 // not used + , 0x0000 // not used + , 0x00 // not used + , 0x01000200 // unknown data + , 0xFFFFFFFF // unknown data + , $options // options + , 0x0000 // not used + ); + + $length = strlen($recordData); + $header = pack('vv', $record, $length); + + $this->_append($header . $recordData); + } + + /** + * Write BIFF record RANGEPROTECTION + * + * Openoffice.org's Documentaion of the Microsoft Excel File Format uses term RANGEPROTECTION for these records + * Microsoft Office Excel 97-2007 Binary File Format Specification uses term FEAT for these records + */ + private function _writeRangeProtection() + { + foreach ($this->_phpSheet->getProtectedCells() as $range => $password) { + // number of ranges, e.g. 'A1:B3 C20:D25' + $cellRanges = explode(' ', $range); + $cref = count($cellRanges); + + $recordData = pack( + 'vvVVvCVvVv', + 0x0868, + 0x00, + 0x0000, + 0x0000, + 0x02, + 0x0, + 0x0000, + $cref, + 0x0000, + 0x00 + ); + + foreach ($cellRanges as $cellRange) { + $recordData .= $this->_writeBIFF8CellRangeAddressFixed($cellRange); + } + + // the rgbFeat structure + $recordData .= pack( + 'VV', + 0x0000, + hexdec($password) + ); + + $recordData .= PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong('p' . md5($recordData)); + + $length = strlen($recordData); + + $record = 0x0868; // Record identifier + $header = pack("vv", $record, $length); + $this->_append($header . $recordData); + } + } + + /** + * Write BIFF record EXTERNCOUNT to indicate the number of external sheet + * references in a worksheet. + * + * Excel only stores references to external sheets that are used in formulas. + * For simplicity we store references to all the sheets in the workbook + * regardless of whether they are used or not. This reduces the overall + * complexity and eliminates the need for a two way dialogue between the formula + * parser the worksheet objects. + * + * @param integer $count The number of external sheet references in this worksheet + */ + private function _writeExterncount($count) + { + $record = 0x0016; // Record identifier + $length = 0x0002; // Number of bytes to follow + + $header = pack("vv", $record, $length); + $data = pack("v", $count); + $this->_append($header . $data); + } + + /** + * Writes the Excel BIFF EXTERNSHEET record. These references are used by + * formulas. A formula references a sheet name via an index. Since we store a + * reference to all of the external worksheets the EXTERNSHEET index is the same + * as the worksheet index. + * + * @param string $sheetname The name of a external worksheet + */ + private function _writeExternsheet($sheetname) + { + $record = 0x0017; // Record identifier + + // References to the current sheet are encoded differently to references to + // external sheets. + // + if ($this->_phpSheet->getTitle() == $sheetname) { + $sheetname = ''; + $length = 0x02; // The following 2 bytes + $cch = 1; // The following byte + $rgch = 0x02; // Self reference + } else { + $length = 0x02 + strlen($sheetname); + $cch = strlen($sheetname); + $rgch = 0x03; // Reference to a sheet in the current workbook + } + + $header = pack("vv", $record, $length); + $data = pack("CC", $cch, $rgch); + $this->_append($header . $data . $sheetname); + } + + /** + * Writes the Excel BIFF PANE record. + * The panes can either be frozen or thawed (unfrozen). + * Frozen panes are specified in terms of an integer number of rows and columns. + * Thawed panes are specified in terms of Excel's units for rows and columns. + */ + private function _writePanes() + { + $panes = array(); + if ($freezePane = $this->_phpSheet->getFreezePane()) { + list($column, $row) = PHPExcel_Cell::coordinateFromString($freezePane); + $panes[0] = $row - 1; + $panes[1] = PHPExcel_Cell::columnIndexFromString($column) - 1; + } else { + // thaw panes + return; + } + + $y = isset($panes[0]) ? $panes[0] : null; + $x = isset($panes[1]) ? $panes[1] : null; + $rwTop = isset($panes[2]) ? $panes[2] : null; + $colLeft = isset($panes[3]) ? $panes[3] : null; + if (count($panes) > 4) { // if Active pane was received + $pnnAct = $panes[4]; + } else { + $pnnAct = null; + } + $record = 0x0041; // Record identifier + $length = 0x000A; // Number of bytes to follow + + // Code specific to frozen or thawed panes. + if ($this->_phpSheet->getFreezePane()) { + // Set default values for $rwTop and $colLeft + if (!isset($rwTop)) { + $rwTop = $y; + } + if (!isset($colLeft)) { + $colLeft = $x; + } + } else { + // Set default values for $rwTop and $colLeft + if (!isset($rwTop)) { + $rwTop = 0; + } + if (!isset($colLeft)) { + $colLeft = 0; + } + + // Convert Excel's row and column units to the internal units. + // The default row height is 12.75 + // The default column width is 8.43 + // The following slope and intersection values were interpolated. + // + $y = 20*$y + 255; + $x = 113.879*$x + 390; + } + + + // Determine which pane should be active. There is also the undocumented + // option to override this should it be necessary: may be removed later. + // + if (!isset($pnnAct)) { + if ($x != 0 && $y != 0) { + $pnnAct = 0; // Bottom right + } + if ($x != 0 && $y == 0) { + $pnnAct = 1; // Top right + } + if ($x == 0 && $y != 0) { + $pnnAct = 2; // Bottom left + } + if ($x == 0 && $y == 0) { + $pnnAct = 3; // Top left + } + } + + $this->_active_pane = $pnnAct; // Used in _writeSelection + + $header = pack("vv", $record, $length); + $data = pack("vvvvv", $x, $y, $rwTop, $colLeft, $pnnAct); + $this->_append($header . $data); + } + + /** + * Store the page setup SETUP BIFF record. + */ + private function _writeSetup() + { + $record = 0x00A1; // Record identifier + $length = 0x0022; // Number of bytes to follow + + $iPaperSize = $this->_phpSheet->getPageSetup()->getPaperSize(); // Paper size + + $iScale = $this->_phpSheet->getPageSetup()->getScale() ? + $this->_phpSheet->getPageSetup()->getScale() : 100; // Print scaling factor + + $iPageStart = 0x01; // Starting page number + $iFitWidth = (int) $this->_phpSheet->getPageSetup()->getFitToWidth(); // Fit to number of pages wide + $iFitHeight = (int) $this->_phpSheet->getPageSetup()->getFitToHeight(); // Fit to number of pages high + $grbit = 0x00; // Option flags + $iRes = 0x0258; // Print resolution + $iVRes = 0x0258; // Vertical print resolution + + $numHdr = $this->_phpSheet->getPageMargins()->getHeader(); // Header Margin + + $numFtr = $this->_phpSheet->getPageMargins()->getFooter(); // Footer Margin + $iCopies = 0x01; // Number of copies + + $fLeftToRight = 0x0; // Print over then down + + // Page orientation + $fLandscape = ($this->_phpSheet->getPageSetup()->getOrientation() == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE) ? + 0x0 : 0x1; + + $fNoPls = 0x0; // Setup not read from printer + $fNoColor = 0x0; // Print black and white + $fDraft = 0x0; // Print draft quality + $fNotes = 0x0; // Print notes + $fNoOrient = 0x0; // Orientation not set + $fUsePage = 0x0; // Use custom starting page + + $grbit = $fLeftToRight; + $grbit |= $fLandscape << 1; + $grbit |= $fNoPls << 2; + $grbit |= $fNoColor << 3; + $grbit |= $fDraft << 4; + $grbit |= $fNotes << 5; + $grbit |= $fNoOrient << 6; + $grbit |= $fUsePage << 7; + + $numHdr = pack("d", $numHdr); + $numFtr = pack("d", $numFtr); + if (self::getByteOrder()) { // if it's Big Endian + $numHdr = strrev($numHdr); + $numFtr = strrev($numFtr); + } + + $header = pack("vv", $record, $length); + $data1 = pack("vvvvvvvv", $iPaperSize, + $iScale, + $iPageStart, + $iFitWidth, + $iFitHeight, + $grbit, + $iRes, + $iVRes); + $data2 = $numHdr.$numFtr; + $data3 = pack("v", $iCopies); + $this->_append($header . $data1 . $data2 . $data3); + } + + /** + * Store the header caption BIFF record. + */ + private function _writeHeader() + { + $record = 0x0014; // Record identifier + + /* removing for now + // need to fix character count (multibyte!) + if (strlen($this->_phpSheet->getHeaderFooter()->getOddHeader()) <= 255) { + $str = $this->_phpSheet->getHeaderFooter()->getOddHeader(); // header string + } else { + $str = ''; + } + */ + + $recordData = PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($this->_phpSheet->getHeaderFooter()->getOddHeader()); + $length = strlen($recordData); + + $header = pack("vv", $record, $length); + + $this->_append($header . $recordData); + } + + /** + * Store the footer caption BIFF record. + */ + private function _writeFooter() + { + $record = 0x0015; // Record identifier + + /* removing for now + // need to fix character count (multibyte!) + if (strlen($this->_phpSheet->getHeaderFooter()->getOddFooter()) <= 255) { + $str = $this->_phpSheet->getHeaderFooter()->getOddFooter(); + } else { + $str = ''; + } + */ + + $recordData = PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($this->_phpSheet->getHeaderFooter()->getOddFooter()); + $length = strlen($recordData); + + $header = pack("vv", $record, $length); + + $this->_append($header . $recordData); + } + + /** + * Store the horizontal centering HCENTER BIFF record. + * + * @access private + */ + private function _writeHcenter() + { + $record = 0x0083; // Record identifier + $length = 0x0002; // Bytes to follow + + $fHCenter = $this->_phpSheet->getPageSetup()->getHorizontalCentered() ? 1 : 0; // Horizontal centering + + $header = pack("vv", $record, $length); + $data = pack("v", $fHCenter); + + $this->_append($header.$data); + } + + /** + * Store the vertical centering VCENTER BIFF record. + */ + private function _writeVcenter() + { + $record = 0x0084; // Record identifier + $length = 0x0002; // Bytes to follow + + $fVCenter = $this->_phpSheet->getPageSetup()->getVerticalCentered() ? 1 : 0; // Horizontal centering + + $header = pack("vv", $record, $length); + $data = pack("v", $fVCenter); + $this->_append($header . $data); + } + + /** + * Store the LEFTMARGIN BIFF record. + */ + private function _writeMarginLeft() + { + $record = 0x0026; // Record identifier + $length = 0x0008; // Bytes to follow + + $margin = $this->_phpSheet->getPageMargins()->getLeft(); // Margin in inches + + $header = pack("vv", $record, $length); + $data = pack("d", $margin); + if (self::getByteOrder()) { // if it's Big Endian + $data = strrev($data); + } + + $this->_append($header . $data); + } + + /** + * Store the RIGHTMARGIN BIFF record. + */ + private function _writeMarginRight() + { + $record = 0x0027; // Record identifier + $length = 0x0008; // Bytes to follow + + $margin = $this->_phpSheet->getPageMargins()->getRight(); // Margin in inches + + $header = pack("vv", $record, $length); + $data = pack("d", $margin); + if (self::getByteOrder()) { // if it's Big Endian + $data = strrev($data); + } + + $this->_append($header . $data); + } + + /** + * Store the TOPMARGIN BIFF record. + */ + private function _writeMarginTop() + { + $record = 0x0028; // Record identifier + $length = 0x0008; // Bytes to follow + + $margin = $this->_phpSheet->getPageMargins()->getTop(); // Margin in inches + + $header = pack("vv", $record, $length); + $data = pack("d", $margin); + if (self::getByteOrder()) { // if it's Big Endian + $data = strrev($data); + } + + $this->_append($header . $data); + } + + /** + * Store the BOTTOMMARGIN BIFF record. + */ + private function _writeMarginBottom() + { + $record = 0x0029; // Record identifier + $length = 0x0008; // Bytes to follow + + $margin = $this->_phpSheet->getPageMargins()->getBottom(); // Margin in inches + + $header = pack("vv", $record, $length); + $data = pack("d", $margin); + if (self::getByteOrder()) { // if it's Big Endian + $data = strrev($data); + } + + $this->_append($header . $data); + } + + /** + * Write the PRINTHEADERS BIFF record. + */ + private function _writePrintHeaders() + { + $record = 0x002a; // Record identifier + $length = 0x0002; // Bytes to follow + + $fPrintRwCol = $this->_print_headers; // Boolean flag + + $header = pack("vv", $record, $length); + $data = pack("v", $fPrintRwCol); + $this->_append($header . $data); + } + + /** + * Write the PRINTGRIDLINES BIFF record. Must be used in conjunction with the + * GRIDSET record. + */ + private function _writePrintGridlines() + { + $record = 0x002b; // Record identifier + $length = 0x0002; // Bytes to follow + + $fPrintGrid = $this->_phpSheet->getPrintGridlines() ? 1 : 0; // Boolean flag + + $header = pack("vv", $record, $length); + $data = pack("v", $fPrintGrid); + $this->_append($header . $data); + } + + /** + * Write the GRIDSET BIFF record. Must be used in conjunction with the + * PRINTGRIDLINES record. + */ + private function _writeGridset() + { + $record = 0x0082; // Record identifier + $length = 0x0002; // Bytes to follow + + $fGridSet = !$this->_phpSheet->getPrintGridlines(); // Boolean flag + + $header = pack("vv", $record, $length); + $data = pack("v", $fGridSet); + $this->_append($header . $data); + } + + /** + * Write the AUTOFILTERINFO BIFF record. This is used to configure the number of autofilter select used in the sheet. + */ + private function _writeAutoFilterInfo(){ + $record = 0x009D; // Record identifier + $length = 0x0002; // Bytes to follow + + $rangeBounds = PHPExcel_Cell::rangeBoundaries($this->_phpSheet->getAutoFilter()->getRange()); + $iNumFilters = 1 + $rangeBounds[1][0] - $rangeBounds[0][0]; + + $header = pack("vv", $record, $length); + $data = pack("v", $iNumFilters); + $this->_append($header . $data); + } + + /** + * Write the GUTS BIFF record. This is used to configure the gutter margins + * where Excel outline symbols are displayed. The visibility of the gutters is + * controlled by a flag in WSBOOL. + * + * @see _writeWsbool() + */ + private function _writeGuts() + { + $record = 0x0080; // Record identifier + $length = 0x0008; // Bytes to follow + + $dxRwGut = 0x0000; // Size of row gutter + $dxColGut = 0x0000; // Size of col gutter + + // determine maximum row outline level + $maxRowOutlineLevel = 0; + foreach ($this->_phpSheet->getRowDimensions() as $rowDimension) { + $maxRowOutlineLevel = max($maxRowOutlineLevel, $rowDimension->getOutlineLevel()); + } + + $col_level = 0; + + // Calculate the maximum column outline level. The equivalent calculation + // for the row outline level is carried out in _writeRow(). + $colcount = count($this->_colinfo); + for ($i = 0; $i < $colcount; ++$i) { + $col_level = max($this->_colinfo[$i][5], $col_level); + } + + // Set the limits for the outline levels (0 <= x <= 7). + $col_level = max(0, min($col_level, 7)); + + // The displayed level is one greater than the max outline levels + if ($maxRowOutlineLevel) { + ++$maxRowOutlineLevel; + } + if ($col_level) { + ++$col_level; + } + + $header = pack("vv", $record, $length); + $data = pack("vvvv", $dxRwGut, $dxColGut, $maxRowOutlineLevel, $col_level); + + $this->_append($header.$data); + } + + /** + * Write the WSBOOL BIFF record, mainly for fit-to-page. Used in conjunction + * with the SETUP record. + */ + private function _writeWsbool() + { + $record = 0x0081; // Record identifier + $length = 0x0002; // Bytes to follow + $grbit = 0x0000; + + // The only option that is of interest is the flag for fit to page. So we + // set all the options in one go. + // + // Set the option flags + $grbit |= 0x0001; // Auto page breaks visible + if ($this->_outline_style) { + $grbit |= 0x0020; // Auto outline styles + } + if ($this->_phpSheet->getShowSummaryBelow()) { + $grbit |= 0x0040; // Outline summary below + } + if ($this->_phpSheet->getShowSummaryRight()) { + $grbit |= 0x0080; // Outline summary right + } + if ($this->_phpSheet->getPageSetup()->getFitToPage()) { + $grbit |= 0x0100; // Page setup fit to page + } + if ($this->_outline_on) { + $grbit |= 0x0400; // Outline symbols displayed + } + + $header = pack("vv", $record, $length); + $data = pack("v", $grbit); + $this->_append($header . $data); + } + + /** + * Write the HORIZONTALPAGEBREAKS and VERTICALPAGEBREAKS BIFF records. + */ + private function _writeBreaks() + { + // initialize + $vbreaks = array(); + $hbreaks = array(); + + foreach ($this->_phpSheet->getBreaks() as $cell => $breakType) { + // Fetch coordinates + $coordinates = PHPExcel_Cell::coordinateFromString($cell); + + // Decide what to do by the type of break + switch ($breakType) { + case PHPExcel_Worksheet::BREAK_COLUMN: + // Add to list of vertical breaks + $vbreaks[] = PHPExcel_Cell::columnIndexFromString($coordinates[0]) - 1; + break; + + case PHPExcel_Worksheet::BREAK_ROW: + // Add to list of horizontal breaks + $hbreaks[] = $coordinates[1]; + break; + + case PHPExcel_Worksheet::BREAK_NONE: + default: + // Nothing to do + break; + } + } + + //horizontal page breaks + if (!empty($hbreaks)) { + + // Sort and filter array of page breaks + sort($hbreaks, SORT_NUMERIC); + if ($hbreaks[0] == 0) { // don't use first break if it's 0 + array_shift($hbreaks); + } + + $record = 0x001b; // Record identifier + $cbrk = count($hbreaks); // Number of page breaks + $length = 2 + 6 * $cbrk; // Bytes to follow + + $header = pack("vv", $record, $length); + $data = pack("v", $cbrk); + + // Append each page break + foreach ($hbreaks as $hbreak) { + $data .= pack("vvv", $hbreak, 0x0000, 0x00ff); + } + + $this->_append($header . $data); + } + + // vertical page breaks + if (!empty($vbreaks)) { + + // 1000 vertical pagebreaks appears to be an internal Excel 5 limit. + // It is slightly higher in Excel 97/200, approx. 1026 + $vbreaks = array_slice($vbreaks, 0, 1000); + + // Sort and filter array of page breaks + sort($vbreaks, SORT_NUMERIC); + if ($vbreaks[0] == 0) { // don't use first break if it's 0 + array_shift($vbreaks); + } + + $record = 0x001a; // Record identifier + $cbrk = count($vbreaks); // Number of page breaks + $length = 2 + 6 * $cbrk; // Bytes to follow + + $header = pack("vv", $record, $length); + $data = pack("v", $cbrk); + + // Append each page break + foreach ($vbreaks as $vbreak) { + $data .= pack("vvv", $vbreak, 0x0000, 0xffff); + } + + $this->_append($header . $data); + } + } + + /** + * Set the Biff PROTECT record to indicate that the worksheet is protected. + */ + private function _writeProtect() + { + // Exit unless sheet protection has been specified + if (!$this->_phpSheet->getProtection()->getSheet()) { + return; + } + + $record = 0x0012; // Record identifier + $length = 0x0002; // Bytes to follow + + $fLock = 1; // Worksheet is protected + + $header = pack("vv", $record, $length); + $data = pack("v", $fLock); + + $this->_append($header.$data); + } + + /** + * Write SCENPROTECT + */ + private function _writeScenProtect() + { + // Exit if sheet protection is not active + if (!$this->_phpSheet->getProtection()->getSheet()) { + return; + } + + // Exit if scenarios are not protected + if (!$this->_phpSheet->getProtection()->getScenarios()) { + return; + } + + $record = 0x00DD; // Record identifier + $length = 0x0002; // Bytes to follow + + $header = pack('vv', $record, $length); + $data = pack('v', 1); + + $this->_append($header . $data); + } + + /** + * Write OBJECTPROTECT + */ + private function _writeObjectProtect() + { + // Exit if sheet protection is not active + if (!$this->_phpSheet->getProtection()->getSheet()) { + return; + } + + // Exit if objects are not protected + if (!$this->_phpSheet->getProtection()->getObjects()) { + return; + } + + $record = 0x0063; // Record identifier + $length = 0x0002; // Bytes to follow + + $header = pack('vv', $record, $length); + $data = pack('v', 1); + + $this->_append($header . $data); + } + + /** + * Write the worksheet PASSWORD record. + */ + private function _writePassword() + { + // Exit unless sheet protection and password have been specified + if (!$this->_phpSheet->getProtection()->getSheet() || !$this->_phpSheet->getProtection()->getPassword()) { + return; + } + + $record = 0x0013; // Record identifier + $length = 0x0002; // Bytes to follow + + $wPassword = hexdec($this->_phpSheet->getProtection()->getPassword()); // Encoded password + + $header = pack("vv", $record, $length); + $data = pack("v", $wPassword); + + $this->_append($header . $data); + } + + /** + * Insert a 24bit bitmap image in a worksheet. + * + * @access public + * @param integer $row The row we are going to insert the bitmap into + * @param integer $col The column we are going to insert the bitmap into + * @param mixed $bitmap The bitmap filename or GD-image resource + * @param integer $x The horizontal position (offset) of the image inside the cell. + * @param integer $y The vertical position (offset) of the image inside the cell. + * @param float $scale_x The horizontal scale + * @param float $scale_y The vertical scale + */ + function insertBitmap($row, $col, $bitmap, $x = 0, $y = 0, $scale_x = 1, $scale_y = 1) + { + $bitmap_array = (is_resource($bitmap) ? $this->_processBitmapGd($bitmap) : $this->_processBitmap($bitmap)); + list($width, $height, $size, $data) = $bitmap_array; //$this->_processBitmap($bitmap); + + // Scale the frame of the image. + $width *= $scale_x; + $height *= $scale_y; + + // Calculate the vertices of the image and write the OBJ record + $this->_positionImage($col, $row, $x, $y, $width, $height); + + // Write the IMDATA record to store the bitmap data + $record = 0x007f; + $length = 8 + $size; + $cf = 0x09; + $env = 0x01; + $lcb = $size; + + $header = pack("vvvvV", $record, $length, $cf, $env, $lcb); + $this->_append($header.$data); + } + + /** + * Calculate the vertices that define the position of the image as required by + * the OBJ record. + * + * +------------+------------+ + * | A | B | + * +-----+------------+------------+ + * | |(x1,y1) | | + * | 1 |(A1)._______|______ | + * | | | | | + * | | | | | + * +-----+----| BITMAP |-----+ + * | | | | | + * | 2 | |______________. | + * | | | (B2)| + * | | | (x2,y2)| + * +---- +------------+------------+ + * + * Example of a bitmap that covers some of the area from cell A1 to cell B2. + * + * Based on the width and height of the bitmap we need to calculate 8 vars: + * $col_start, $row_start, $col_end, $row_end, $x1, $y1, $x2, $y2. + * The width and height of the cells are also variable and have to be taken into + * account. + * The values of $col_start and $row_start are passed in from the calling + * function. The values of $col_end and $row_end are calculated by subtracting + * the width and height of the bitmap from the width and height of the + * underlying cells. + * The vertices are expressed as a percentage of the underlying cell width as + * follows (rhs values are in pixels): + * + * x1 = X / W *1024 + * y1 = Y / H *256 + * x2 = (X-1) / W *1024 + * y2 = (Y-1) / H *256 + * + * Where: X is distance from the left side of the underlying cell + * Y is distance from the top of the underlying cell + * W is the width of the cell + * H is the height of the cell + * The SDK incorrectly states that the height should be expressed as a + * percentage of 1024. + * + * @access private + * @param integer $col_start Col containing upper left corner of object + * @param integer $row_start Row containing top left corner of object + * @param integer $x1 Distance to left side of object + * @param integer $y1 Distance to top of object + * @param integer $width Width of image frame + * @param integer $height Height of image frame + */ + function _positionImage($col_start, $row_start, $x1, $y1, $width, $height) + { + // Initialise end cell to the same as the start cell + $col_end = $col_start; // Col containing lower right corner of object + $row_end = $row_start; // Row containing bottom right corner of object + + // Zero the specified offset if greater than the cell dimensions + if ($x1 >= PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_start))) { + $x1 = 0; + } + if ($y1 >= PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $row_start + 1)) { + $y1 = 0; + } + + $width = $width + $x1 -1; + $height = $height + $y1 -1; + + // Subtract the underlying cell widths to find the end cell of the image + while ($width >= PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_end))) { + $width -= PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_end)); + ++$col_end; + } + + // Subtract the underlying cell heights to find the end cell of the image + while ($height >= PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $row_end + 1)) { + $height -= PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $row_end + 1); + ++$row_end; + } + + // Bitmap isn't allowed to start or finish in a hidden cell, i.e. a cell + // with zero eight or width. + // + if (PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_start)) == 0) { + return; + } + if (PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_end)) == 0) { + return; + } + if (PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $row_start + 1) == 0) { + return; + } + if (PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $row_end + 1) == 0) { + return; + } + + // Convert the pixel values to the percentage value expected by Excel + $x1 = $x1 / PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_start)) * 1024; + $y1 = $y1 / PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $row_start + 1) * 256; + $x2 = $width / PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_end)) * 1024; // Distance to right side of object + $y2 = $height / PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $row_end + 1) * 256; // Distance to bottom of object + + $this->_writeObjPicture($col_start, $x1, + $row_start, $y1, + $col_end, $x2, + $row_end, $y2); + } + + /** + * Store the OBJ record that precedes an IMDATA record. This could be generalise + * to support other Excel objects. + * + * @param integer $colL Column containing upper left corner of object + * @param integer $dxL Distance from left side of cell + * @param integer $rwT Row containing top left corner of object + * @param integer $dyT Distance from top of cell + * @param integer $colR Column containing lower right corner of object + * @param integer $dxR Distance from right of cell + * @param integer $rwB Row containing bottom right corner of object + * @param integer $dyB Distance from bottom of cell + */ + private function _writeObjPicture($colL,$dxL,$rwT,$dyT,$colR,$dxR,$rwB,$dyB) + { + $record = 0x005d; // Record identifier + $length = 0x003c; // Bytes to follow + + $cObj = 0x0001; // Count of objects in file (set to 1) + $OT = 0x0008; // Object type. 8 = Picture + $id = 0x0001; // Object ID + $grbit = 0x0614; // Option flags + + $cbMacro = 0x0000; // Length of FMLA structure + $Reserved1 = 0x0000; // Reserved + $Reserved2 = 0x0000; // Reserved + + $icvBack = 0x09; // Background colour + $icvFore = 0x09; // Foreground colour + $fls = 0x00; // Fill pattern + $fAuto = 0x00; // Automatic fill + $icv = 0x08; // Line colour + $lns = 0xff; // Line style + $lnw = 0x01; // Line weight + $fAutoB = 0x00; // Automatic border + $frs = 0x0000; // Frame style + $cf = 0x0009; // Image format, 9 = bitmap + $Reserved3 = 0x0000; // Reserved + $cbPictFmla = 0x0000; // Length of FMLA structure + $Reserved4 = 0x0000; // Reserved + $grbit2 = 0x0001; // Option flags + $Reserved5 = 0x0000; // Reserved + + + $header = pack("vv", $record, $length); + $data = pack("V", $cObj); + $data .= pack("v", $OT); + $data .= pack("v", $id); + $data .= pack("v", $grbit); + $data .= pack("v", $colL); + $data .= pack("v", $dxL); + $data .= pack("v", $rwT); + $data .= pack("v", $dyT); + $data .= pack("v", $colR); + $data .= pack("v", $dxR); + $data .= pack("v", $rwB); + $data .= pack("v", $dyB); + $data .= pack("v", $cbMacro); + $data .= pack("V", $Reserved1); + $data .= pack("v", $Reserved2); + $data .= pack("C", $icvBack); + $data .= pack("C", $icvFore); + $data .= pack("C", $fls); + $data .= pack("C", $fAuto); + $data .= pack("C", $icv); + $data .= pack("C", $lns); + $data .= pack("C", $lnw); + $data .= pack("C", $fAutoB); + $data .= pack("v", $frs); + $data .= pack("V", $cf); + $data .= pack("v", $Reserved3); + $data .= pack("v", $cbPictFmla); + $data .= pack("v", $Reserved4); + $data .= pack("v", $grbit2); + $data .= pack("V", $Reserved5); + + $this->_append($header . $data); + } + + /** + * Convert a GD-image into the internal format. + * + * @access private + * @param resource $image The image to process + * @return array Array with data and properties of the bitmap + */ + function _processBitmapGd($image) { + $width = imagesx($image); + $height = imagesy($image); + + $data = pack("Vvvvv", 0x000c, $width, $height, 0x01, 0x18); + for ($j=$height; $j--; ) { + for ($i=0; $i < $width; ++$i) { + $color = imagecolorsforindex($image, imagecolorat($image, $i, $j)); + foreach (array("red", "green", "blue") as $key) { + $color[$key] = $color[$key] + round((255 - $color[$key]) * $color["alpha"] / 127); + } + $data .= chr($color["blue"]) . chr($color["green"]) . chr($color["red"]); + } + if (3*$width % 4) { + $data .= str_repeat("\x00", 4 - 3*$width % 4); + } + } + + return array($width, $height, strlen($data), $data); + } + + /** + * Convert a 24 bit bitmap into the modified internal format used by Windows. + * This is described in BITMAPCOREHEADER and BITMAPCOREINFO structures in the + * MSDN library. + * + * @access private + * @param string $bitmap The bitmap to process + * @return array Array with data and properties of the bitmap + */ + function _processBitmap($bitmap) + { + // Open file. + $bmp_fd = @fopen($bitmap,"rb"); + if (!$bmp_fd) { + throw new PHPExcel_Writer_Exception("Couldn't import $bitmap"); + } + + // Slurp the file into a string. + $data = fread($bmp_fd, filesize($bitmap)); + + // Check that the file is big enough to be a bitmap. + if (strlen($data) <= 0x36) { + throw new PHPExcel_Writer_Exception("$bitmap doesn't contain enough data.\n"); + } + + // The first 2 bytes are used to identify the bitmap. + $identity = unpack("A2ident", $data); + if ($identity['ident'] != "BM") { + throw new PHPExcel_Writer_Exception("$bitmap doesn't appear to be a valid bitmap image.\n"); + } + + // Remove bitmap data: ID. + $data = substr($data, 2); + + // Read and remove the bitmap size. This is more reliable than reading + // the data size at offset 0x22. + // + $size_array = unpack("Vsa", substr($data, 0, 4)); + $size = $size_array['sa']; + $data = substr($data, 4); + $size -= 0x36; // Subtract size of bitmap header. + $size += 0x0C; // Add size of BIFF header. + + // Remove bitmap data: reserved, offset, header length. + $data = substr($data, 12); + + // Read and remove the bitmap width and height. Verify the sizes. + $width_and_height = unpack("V2", substr($data, 0, 8)); + $width = $width_and_height[1]; + $height = $width_and_height[2]; + $data = substr($data, 8); + if ($width > 0xFFFF) { + throw new PHPExcel_Writer_Exception("$bitmap: largest image width supported is 65k.\n"); + } + if ($height > 0xFFFF) { + throw new PHPExcel_Writer_Exception("$bitmap: largest image height supported is 65k.\n"); + } + + // Read and remove the bitmap planes and bpp data. Verify them. + $planes_and_bitcount = unpack("v2", substr($data, 0, 4)); + $data = substr($data, 4); + if ($planes_and_bitcount[2] != 24) { // Bitcount + throw new PHPExcel_Writer_Exception("$bitmap isn't a 24bit true color bitmap.\n"); + } + if ($planes_and_bitcount[1] != 1) { + throw new PHPExcel_Writer_Exception("$bitmap: only 1 plane supported in bitmap image.\n"); + } + + // Read and remove the bitmap compression. Verify compression. + $compression = unpack("Vcomp", substr($data, 0, 4)); + $data = substr($data, 4); + + //$compression = 0; + if ($compression['comp'] != 0) { + throw new PHPExcel_Writer_Exception("$bitmap: compression not supported in bitmap image.\n"); + } + + // Remove bitmap data: data size, hres, vres, colours, imp. colours. + $data = substr($data, 20); + + // Add the BITMAPCOREHEADER data + $header = pack("Vvvvv", 0x000c, $width, $height, 0x01, 0x18); + $data = $header . $data; + + return (array($width, $height, $size, $data)); + } + + /** + * Store the window zoom factor. This should be a reduced fraction but for + * simplicity we will store all fractions with a numerator of 100. + */ + private function _writeZoom() + { + // If scale is 100 we don't need to write a record + if ($this->_phpSheet->getSheetView()->getZoomScale() == 100) { + return; + } + + $record = 0x00A0; // Record identifier + $length = 0x0004; // Bytes to follow + + $header = pack("vv", $record, $length); + $data = pack("vv", $this->_phpSheet->getSheetView()->getZoomScale(), 100); + $this->_append($header . $data); + } + + /** + * Get Escher object + * + * @return PHPExcel_Shared_Escher + */ + public function getEscher() + { + return $this->_escher; + } + + /** + * Set Escher object + * + * @param PHPExcel_Shared_Escher $pValue + */ + public function setEscher(PHPExcel_Shared_Escher $pValue = null) + { + $this->_escher = $pValue; + } + + /** + * Write MSODRAWING record + */ + private function _writeMsoDrawing() + { + // write the Escher stream if necessary + if (isset($this->_escher)) { + $writer = new PHPExcel_Writer_Excel5_Escher($this->_escher); + $data = $writer->close(); + $spOffsets = $writer->getSpOffsets(); + $spTypes = $writer->getSpTypes(); + // write the neccesary MSODRAWING, OBJ records + + // split the Escher stream + $spOffsets[0] = 0; + $nm = count($spOffsets) - 1; // number of shapes excluding first shape + for ($i = 1; $i <= $nm; ++$i) { + // MSODRAWING record + $record = 0x00EC; // Record identifier + + // chunk of Escher stream for one shape + $dataChunk = substr($data, $spOffsets[$i -1], $spOffsets[$i] - $spOffsets[$i - 1]); + + $length = strlen($dataChunk); + $header = pack("vv", $record, $length); + + $this->_append($header . $dataChunk); + + // OBJ record + $record = 0x005D; // record identifier + $objData = ''; + + // ftCmo + if($spTypes[$i] == 0x00C9){ + // Add ftCmo (common object data) subobject + $objData .= + pack('vvvvvVVV' + , 0x0015 // 0x0015 = ftCmo + , 0x0012 // length of ftCmo data + , 0x0014 // object type, 0x0014 = filter + , $i // object id number, Excel seems to use 1-based index, local for the sheet + , 0x2101 // option flags, 0x2001 is what OpenOffice.org uses + , 0 // reserved + , 0 // reserved + , 0 // reserved + ); + + // Add ftSbs Scroll bar subobject + $objData .= pack('vv', 0x00C, 0x0014); + $objData .= pack('H*', '0000000000000000640001000A00000010000100'); + // Add ftLbsData (List box data) subobject + $objData .= pack('vv', 0x0013, 0x1FEE); + $objData .= pack('H*', '00000000010001030000020008005700'); + } + else { + // Add ftCmo (common object data) subobject + $objData .= + pack('vvvvvVVV' + , 0x0015 // 0x0015 = ftCmo + , 0x0012 // length of ftCmo data + , 0x0008 // object type, 0x0008 = picture + , $i // object id number, Excel seems to use 1-based index, local for the sheet + , 0x6011 // option flags, 0x6011 is what OpenOffice.org uses + , 0 // reserved + , 0 // reserved + , 0 // reserved + ); + } + + // ftEnd + $objData .= + pack('vv' + , 0x0000 // 0x0000 = ftEnd + , 0x0000 // length of ftEnd data + ); + + $length = strlen($objData); + $header = pack('vv', $record, $length); + $this->_append($header . $objData); + } + } + } + + /** + * Store the DATAVALIDATIONS and DATAVALIDATION records. + */ + private function _writeDataValidity() + { + // Datavalidation collection + $dataValidationCollection = $this->_phpSheet->getDataValidationCollection(); + + // Write data validations? + if (!empty($dataValidationCollection)) { + + // DATAVALIDATIONS record + $record = 0x01B2; // Record identifier + $length = 0x0012; // Bytes to follow + + $grbit = 0x0000; // Prompt box at cell, no cached validity data at DV records + $horPos = 0x00000000; // Horizontal position of prompt box, if fixed position + $verPos = 0x00000000; // Vertical position of prompt box, if fixed position + $objId = 0xFFFFFFFF; // Object identifier of drop down arrow object, or -1 if not visible + + $header = pack('vv', $record, $length); + $data = pack('vVVVV', $grbit, $horPos, $verPos, $objId, + count($dataValidationCollection)); + $this->_append($header.$data); + + // DATAVALIDATION records + $record = 0x01BE; // Record identifier + + foreach ($dataValidationCollection as $cellCoordinate => $dataValidation) { + // initialize record data + $data = ''; + + // options + $options = 0x00000000; + + // data type + $type = $dataValidation->getType(); + switch ($type) { + case PHPExcel_Cell_DataValidation::TYPE_NONE: $type = 0x00; break; + case PHPExcel_Cell_DataValidation::TYPE_WHOLE: $type = 0x01; break; + case PHPExcel_Cell_DataValidation::TYPE_DECIMAL: $type = 0x02; break; + case PHPExcel_Cell_DataValidation::TYPE_LIST: $type = 0x03; break; + case PHPExcel_Cell_DataValidation::TYPE_DATE: $type = 0x04; break; + case PHPExcel_Cell_DataValidation::TYPE_TIME: $type = 0x05; break; + case PHPExcel_Cell_DataValidation::TYPE_TEXTLENGTH: $type = 0x06; break; + case PHPExcel_Cell_DataValidation::TYPE_CUSTOM: $type = 0x07; break; + } + $options |= $type << 0; + + // error style + $errorStyle = $dataValidation->getType(); + switch ($errorStyle) { + case PHPExcel_Cell_DataValidation::STYLE_STOP: $errorStyle = 0x00; break; + case PHPExcel_Cell_DataValidation::STYLE_WARNING: $errorStyle = 0x01; break; + case PHPExcel_Cell_DataValidation::STYLE_INFORMATION: $errorStyle = 0x02; break; + } + $options |= $errorStyle << 4; + + // explicit formula? + if ($type == 0x03 && preg_match('/^\".*\"$/', $dataValidation->getFormula1())) { + $options |= 0x01 << 7; + } + + // empty cells allowed + $options |= $dataValidation->getAllowBlank() << 8; + + // show drop down + $options |= (!$dataValidation->getShowDropDown()) << 9; + + // show input message + $options |= $dataValidation->getShowInputMessage() << 18; + + // show error message + $options |= $dataValidation->getShowErrorMessage() << 19; + + // condition operator + $operator = $dataValidation->getOperator(); + switch ($operator) { + case PHPExcel_Cell_DataValidation::OPERATOR_BETWEEN: $operator = 0x00 ; break; + case PHPExcel_Cell_DataValidation::OPERATOR_NOTBETWEEN: $operator = 0x01 ; break; + case PHPExcel_Cell_DataValidation::OPERATOR_EQUAL: $operator = 0x02 ; break; + case PHPExcel_Cell_DataValidation::OPERATOR_NOTEQUAL: $operator = 0x03 ; break; + case PHPExcel_Cell_DataValidation::OPERATOR_GREATERTHAN: $operator = 0x04 ; break; + case PHPExcel_Cell_DataValidation::OPERATOR_LESSTHAN: $operator = 0x05 ; break; + case PHPExcel_Cell_DataValidation::OPERATOR_GREATERTHANOREQUAL: $operator = 0x06; break; + case PHPExcel_Cell_DataValidation::OPERATOR_LESSTHANOREQUAL: $operator = 0x07 ; break; + } + $options |= $operator << 20; + + $data = pack('V', $options); + + // prompt title + $promptTitle = $dataValidation->getPromptTitle() !== '' ? + $dataValidation->getPromptTitle() : chr(0); + $data .= PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($promptTitle); + + // error title + $errorTitle = $dataValidation->getErrorTitle() !== '' ? + $dataValidation->getErrorTitle() : chr(0); + $data .= PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($errorTitle); + + // prompt text + $prompt = $dataValidation->getPrompt() !== '' ? + $dataValidation->getPrompt() : chr(0); + $data .= PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($prompt); + + // error text + $error = $dataValidation->getError() !== '' ? + $dataValidation->getError() : chr(0); + $data .= PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($error); + + // formula 1 + try { + $formula1 = $dataValidation->getFormula1(); + if ($type == 0x03) { // list type + $formula1 = str_replace(',', chr(0), $formula1); + } + $this->_parser->parse($formula1); + $formula1 = $this->_parser->toReversePolish(); + $sz1 = strlen($formula1); + + } catch(PHPExcel_Exception $e) { + $sz1 = 0; + $formula1 = ''; + } + $data .= pack('vv', $sz1, 0x0000); + $data .= $formula1; + + // formula 2 + try { + $formula2 = $dataValidation->getFormula2(); + if ($formula2 === '') { + throw new PHPExcel_Writer_Exception('No formula2'); + } + $this->_parser->parse($formula2); + $formula2 = $this->_parser->toReversePolish(); + $sz2 = strlen($formula2); + + } catch(PHPExcel_Exception $e) { + $sz2 = 0; + $formula2 = ''; + } + $data .= pack('vv', $sz2, 0x0000); + $data .= $formula2; + + // cell range address list + $data .= pack('v', 0x0001); + $data .= $this->_writeBIFF8CellRangeAddressFixed($cellCoordinate); + + $length = strlen($data); + $header = pack("vv", $record, $length); + + $this->_append($header . $data); + } + } + } + + /** + * Map Error code + * + * @param string $errorCode + * @return int + */ + private static function _mapErrorCode($errorCode) { + switch ($errorCode) { + case '#NULL!': return 0x00; + case '#DIV/0!': return 0x07; + case '#VALUE!': return 0x0F; + case '#REF!': return 0x17; + case '#NAME?': return 0x1D; + case '#NUM!': return 0x24; + case '#N/A': return 0x2A; + } + + return 0; + } + + /** + * Write PLV Record + */ + private function _writePageLayoutView(){ + $record = 0x088B; // Record identifier + $length = 0x0010; // Bytes to follow + + $rt = 0x088B; // 2 + $grbitFrt = 0x0000; // 2 + $reserved = 0x0000000000000000; // 8 + $wScalvePLV = $this->_phpSheet->getSheetView()->getZoomScale(); // 2 + + // The options flags that comprise $grbit + if($this->_phpSheet->getSheetView()->getView() == PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_LAYOUT){ + $fPageLayoutView = 1; + } else { + $fPageLayoutView = 0; + } + $fRulerVisible = 0; + $fWhitespaceHidden = 0; + + $grbit = $fPageLayoutView; // 2 + $grbit |= $fRulerVisible << 1; + $grbit |= $fWhitespaceHidden << 3; + + $header = pack("vv", $record, $length); + $data = pack("vvVVvv", $rt, $grbitFrt, 0x00000000, 0x00000000, $wScalvePLV, $grbit); + $this->_append($header . $data); + } + + /** + * Write CFRule Record + * @param PHPExcel_Style_Conditional $conditional + */ + private function _writeCFRule(PHPExcel_Style_Conditional $conditional){ + $record = 0x01B1; // Record identifier + + // $type : Type of the CF + // $operatorType : Comparison operator + if($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_EXPRESSION){ + $type = 0x02; + $operatorType = 0x00; + } else if($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS){ + $type = 0x01; + + switch ($conditional->getOperatorType()){ + case PHPExcel_Style_Conditional::OPERATOR_NONE: + $operatorType = 0x00; + break; + case PHPExcel_Style_Conditional::OPERATOR_EQUAL: + $operatorType = 0x03; + break; + case PHPExcel_Style_Conditional::OPERATOR_GREATERTHAN: + $operatorType = 0x05; + break; + case PHPExcel_Style_Conditional::OPERATOR_GREATERTHANOREQUAL: + $operatorType = 0x07; + break; + case PHPExcel_Style_Conditional::OPERATOR_LESSTHAN: + $operatorType = 0x06; + break; + case PHPExcel_Style_Conditional::OPERATOR_LESSTHANOREQUAL: + $operatorType = 0x08; + break; + case PHPExcel_Style_Conditional::OPERATOR_NOTEQUAL: + $operatorType = 0x04; + break; + case PHPExcel_Style_Conditional::OPERATOR_BETWEEN: + $operatorType = 0x01; + break; + // not OPERATOR_NOTBETWEEN 0x02 + } + } + + // $szValue1 : size of the formula data for first value or formula + // $szValue2 : size of the formula data for second value or formula + $arrConditions = $conditional->getConditions(); + $numConditions = sizeof($arrConditions); + if($numConditions == 1){ + $szValue1 = ($arrConditions[0] <= 65535 ? 3 : 0x0000); + $szValue2 = 0x0000; + $operand1 = pack('Cv', 0x1E, $arrConditions[0]); + $operand2 = null; + } else if($numConditions == 2 && ($conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_BETWEEN)){ + $szValue1 = ($arrConditions[0] <= 65535 ? 3 : 0x0000); + $szValue2 = ($arrConditions[1] <= 65535 ? 3 : 0x0000); + $operand1 = pack('Cv', 0x1E, $arrConditions[0]); + $operand2 = pack('Cv', 0x1E, $arrConditions[1]); + } else { + $szValue1 = 0x0000; + $szValue2 = 0x0000; + $operand1 = null; + $operand2 = null; + } + + // $flags : Option flags + // Alignment + $bAlignHz = ($conditional->getStyle()->getAlignment()->getHorizontal() == null ? 1 : 0); + $bAlignVt = ($conditional->getStyle()->getAlignment()->getVertical() == null ? 1 : 0); + $bAlignWrapTx = ($conditional->getStyle()->getAlignment()->getWrapText() == false ? 1 : 0); + $bTxRotation = ($conditional->getStyle()->getAlignment()->getTextRotation() == null ? 1 : 0); + $bIndent = ($conditional->getStyle()->getAlignment()->getIndent() == 0 ? 1 : 0); + $bShrinkToFit = ($conditional->getStyle()->getAlignment()->getShrinkToFit() == false ? 1 : 0); + if($bAlignHz == 0 || $bAlignVt == 0 || $bAlignWrapTx == 0 || $bTxRotation == 0 || $bIndent == 0 || $bShrinkToFit == 0){ + $bFormatAlign = 1; + } else { + $bFormatAlign = 0; + } + // Protection + $bProtLocked = ($conditional->getStyle()->getProtection()->getLocked() == null ? 1 : 0); + $bProtHidden = ($conditional->getStyle()->getProtection()->getHidden() == null ? 1 : 0); + if($bProtLocked == 0 || $bProtHidden == 0){ + $bFormatProt = 1; + } else { + $bFormatProt = 0; + } + // Border + $bBorderLeft = ($conditional->getStyle()->getBorders()->getLeft()->getColor()->getARGB() == PHPExcel_Style_Color::COLOR_BLACK + && $conditional->getStyle()->getBorders()->getLeft()->getBorderStyle() == PHPExcel_Style_Border::BORDER_NONE ? 1 : 0); + $bBorderRight = ($conditional->getStyle()->getBorders()->getRight()->getColor()->getARGB() == PHPExcel_Style_Color::COLOR_BLACK + && $conditional->getStyle()->getBorders()->getRight()->getBorderStyle() == PHPExcel_Style_Border::BORDER_NONE ? 1 : 0); + $bBorderTop = ($conditional->getStyle()->getBorders()->getTop()->getColor()->getARGB() == PHPExcel_Style_Color::COLOR_BLACK + && $conditional->getStyle()->getBorders()->getTop()->getBorderStyle() == PHPExcel_Style_Border::BORDER_NONE ? 1 : 0); + $bBorderBottom = ($conditional->getStyle()->getBorders()->getBottom()->getColor()->getARGB() == PHPExcel_Style_Color::COLOR_BLACK + && $conditional->getStyle()->getBorders()->getBottom()->getBorderStyle() == PHPExcel_Style_Border::BORDER_NONE ? 1 : 0); + if($bBorderLeft == 0 || $bBorderRight == 0 || $bBorderTop == 0 || $bBorderBottom == 0){ + $bFormatBorder = 1; + } else { + $bFormatBorder = 0; + } + // Pattern + $bFillStyle = ($conditional->getStyle()->getFill()->getFillType() == null ? 0 : 1); + $bFillColor = ($conditional->getStyle()->getFill()->getStartColor()->getARGB() == null ? 0 : 1); + $bFillColorBg = ($conditional->getStyle()->getFill()->getEndColor()->getARGB() == null ? 0 : 1); + if($bFillStyle == 0 || $bFillColor == 0 || $bFillColorBg == 0){ + $bFormatFill = 1; + } else { + $bFormatFill = 0; + } + // Font + if($conditional->getStyle()->getFont()->getName() != null + || $conditional->getStyle()->getFont()->getSize() != null + || $conditional->getStyle()->getFont()->getBold() != null + || $conditional->getStyle()->getFont()->getItalic() != null + || $conditional->getStyle()->getFont()->getSuperScript() != null + || $conditional->getStyle()->getFont()->getSubScript() != null + || $conditional->getStyle()->getFont()->getUnderline() != null + || $conditional->getStyle()->getFont()->getStrikethrough() != null + || $conditional->getStyle()->getFont()->getColor()->getARGB() != null){ + $bFormatFont = 1; + } else { + $bFormatFont = 0; + } + // Alignment + $flags = 0; + $flags |= (1 == $bAlignHz ? 0x00000001 : 0); + $flags |= (1 == $bAlignVt ? 0x00000002 : 0); + $flags |= (1 == $bAlignWrapTx ? 0x00000004 : 0); + $flags |= (1 == $bTxRotation ? 0x00000008 : 0); + // Justify last line flag + $flags |= (1 == 1 ? 0x00000010 : 0); + $flags |= (1 == $bIndent ? 0x00000020 : 0); + $flags |= (1 == $bShrinkToFit ? 0x00000040 : 0); + // Default + $flags |= (1 == 1 ? 0x00000080 : 0); + // Protection + $flags |= (1 == $bProtLocked ? 0x00000100 : 0); + $flags |= (1 == $bProtHidden ? 0x00000200 : 0); + // Border + $flags |= (1 == $bBorderLeft ? 0x00000400 : 0); + $flags |= (1 == $bBorderRight ? 0x00000800 : 0); + $flags |= (1 == $bBorderTop ? 0x00001000 : 0); + $flags |= (1 == $bBorderBottom ? 0x00002000 : 0); + $flags |= (1 == 1 ? 0x00004000 : 0); // Top left to Bottom right border + $flags |= (1 == 1 ? 0x00008000 : 0); // Bottom left to Top right border + // Pattern + $flags |= (1 == $bFillStyle ? 0x00010000 : 0); + $flags |= (1 == $bFillColor ? 0x00020000 : 0); + $flags |= (1 == $bFillColorBg ? 0x00040000 : 0); + $flags |= (1 == 1 ? 0x00380000 : 0); + // Font + $flags |= (1 == $bFormatFont ? 0x04000000 : 0); + // Alignment : + $flags |= (1 == $bFormatAlign ? 0x08000000 : 0); + // Border + $flags |= (1 == $bFormatBorder ? 0x10000000 : 0); + // Pattern + $flags |= (1 == $bFormatFill ? 0x20000000 : 0); + // Protection + $flags |= (1 == $bFormatProt ? 0x40000000 : 0); + // Text direction + $flags |= (1 == 0 ? 0x80000000 : 0); + + // Data Blocks + if($bFormatFont == 1){ + // Font Name + if($conditional->getStyle()->getFont()->getName() == null){ + $dataBlockFont = pack('VVVVVVVV', 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000); + $dataBlockFont .= pack('VVVVVVVV', 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000); + } else { + $dataBlockFont = PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($conditional->getStyle()->getFont()->getName()); + } + // Font Size + if($conditional->getStyle()->getFont()->getSize() == null){ + $dataBlockFont .= pack('V', 20 * 11); + } else { + $dataBlockFont .= pack('V', 20 * $conditional->getStyle()->getFont()->getSize()); + } + // Font Options + $dataBlockFont .= pack('V', 0); + // Font weight + if($conditional->getStyle()->getFont()->getBold() == true){ + $dataBlockFont .= pack('v', 0x02BC); + } else { + $dataBlockFont .= pack('v', 0x0190); + } + // Escapement type + if($conditional->getStyle()->getFont()->getSubScript() == true){ + $dataBlockFont .= pack('v', 0x02); + $fontEscapement = 0; + } else if($conditional->getStyle()->getFont()->getSuperScript() == true){ + $dataBlockFont .= pack('v', 0x01); + $fontEscapement = 0; + } else { + $dataBlockFont .= pack('v', 0x00); + $fontEscapement = 1; + } + // Underline type + switch ($conditional->getStyle()->getFont()->getUnderline()){ + case PHPExcel_Style_Font::UNDERLINE_NONE : $dataBlockFont .= pack('C', 0x00); $fontUnderline = 0; break; + case PHPExcel_Style_Font::UNDERLINE_DOUBLE : $dataBlockFont .= pack('C', 0x02); $fontUnderline = 0; break; + case PHPExcel_Style_Font::UNDERLINE_DOUBLEACCOUNTING : $dataBlockFont .= pack('C', 0x22); $fontUnderline = 0; break; + case PHPExcel_Style_Font::UNDERLINE_SINGLE : $dataBlockFont .= pack('C', 0x01); $fontUnderline = 0; break; + case PHPExcel_Style_Font::UNDERLINE_SINGLEACCOUNTING : $dataBlockFont .= pack('C', 0x21); $fontUnderline = 0; break; + default : $dataBlockFont .= pack('C', 0x00); $fontUnderline = 1; break; + } + // Not used (3) + $dataBlockFont .= pack('vC', 0x0000, 0x00); + // Font color index + switch ($conditional->getStyle()->getFont()->getColor()->getRGB()) { + case '000000': $colorIdx = 0x08; break; + case 'FFFFFF': $colorIdx = 0x09; break; + case 'FF0000': $colorIdx = 0x0A; break; + case '00FF00': $colorIdx = 0x0B; break; + case '0000FF': $colorIdx = 0x0C; break; + case 'FFFF00': $colorIdx = 0x0D; break; + case 'FF00FF': $colorIdx = 0x0E; break; + case '00FFFF': $colorIdx = 0x0F; break; + case '800000': $colorIdx = 0x10; break; + case '008000': $colorIdx = 0x11; break; + case '000080': $colorIdx = 0x12; break; + case '808000': $colorIdx = 0x13; break; + case '800080': $colorIdx = 0x14; break; + case '008080': $colorIdx = 0x15; break; + case 'C0C0C0': $colorIdx = 0x16; break; + case '808080': $colorIdx = 0x17; break; + case '9999FF': $colorIdx = 0x18; break; + case '993366': $colorIdx = 0x19; break; + case 'FFFFCC': $colorIdx = 0x1A; break; + case 'CCFFFF': $colorIdx = 0x1B; break; + case '660066': $colorIdx = 0x1C; break; + case 'FF8080': $colorIdx = 0x1D; break; + case '0066CC': $colorIdx = 0x1E; break; + case 'CCCCFF': $colorIdx = 0x1F; break; + case '000080': $colorIdx = 0x20; break; + case 'FF00FF': $colorIdx = 0x21; break; + case 'FFFF00': $colorIdx = 0x22; break; + case '00FFFF': $colorIdx = 0x23; break; + case '800080': $colorIdx = 0x24; break; + case '800000': $colorIdx = 0x25; break; + case '008080': $colorIdx = 0x26; break; + case '0000FF': $colorIdx = 0x27; break; + case '00CCFF': $colorIdx = 0x28; break; + case 'CCFFFF': $colorIdx = 0x29; break; + case 'CCFFCC': $colorIdx = 0x2A; break; + case 'FFFF99': $colorIdx = 0x2B; break; + case '99CCFF': $colorIdx = 0x2C; break; + case 'FF99CC': $colorIdx = 0x2D; break; + case 'CC99FF': $colorIdx = 0x2E; break; + case 'FFCC99': $colorIdx = 0x2F; break; + case '3366FF': $colorIdx = 0x30; break; + case '33CCCC': $colorIdx = 0x31; break; + case '99CC00': $colorIdx = 0x32; break; + case 'FFCC00': $colorIdx = 0x33; break; + case 'FF9900': $colorIdx = 0x34; break; + case 'FF6600': $colorIdx = 0x35; break; + case '666699': $colorIdx = 0x36; break; + case '969696': $colorIdx = 0x37; break; + case '003366': $colorIdx = 0x38; break; + case '339966': $colorIdx = 0x39; break; + case '003300': $colorIdx = 0x3A; break; + case '333300': $colorIdx = 0x3B; break; + case '993300': $colorIdx = 0x3C; break; + case '993366': $colorIdx = 0x3D; break; + case '333399': $colorIdx = 0x3E; break; + case '333333': $colorIdx = 0x3F; break; + default: $colorIdx = 0x00; break; + } + $dataBlockFont .= pack('V', $colorIdx); + // Not used (4) + $dataBlockFont .= pack('V', 0x00000000); + // Options flags for modified font attributes + $optionsFlags = 0; + $optionsFlagsBold = ($conditional->getStyle()->getFont()->getBold() == null ? 1 : 0); + $optionsFlags |= (1 == $optionsFlagsBold ? 0x00000002 : 0); + $optionsFlags |= (1 == 1 ? 0x00000008 : 0); + $optionsFlags |= (1 == 1 ? 0x00000010 : 0); + $optionsFlags |= (1 == 0 ? 0x00000020 : 0); + $optionsFlags |= (1 == 1 ? 0x00000080 : 0); + $dataBlockFont .= pack('V', $optionsFlags); + // Escapement type + $dataBlockFont .= pack('V', $fontEscapement); + // Underline type + $dataBlockFont .= pack('V', $fontUnderline); + // Always + $dataBlockFont .= pack('V', 0x00000000); + // Always + $dataBlockFont .= pack('V', 0x00000000); + // Not used (8) + $dataBlockFont .= pack('VV', 0x00000000, 0x00000000); + // Always + $dataBlockFont .= pack('v', 0x0001); + } + if($bFormatAlign == 1){ + $blockAlign = 0; + // Alignment and text break + switch ($conditional->getStyle()->getAlignment()->getHorizontal()){ + case PHPExcel_Style_Alignment::HORIZONTAL_GENERAL : $blockAlign = 0; break; + case PHPExcel_Style_Alignment::HORIZONTAL_LEFT : $blockAlign = 1; break; + case PHPExcel_Style_Alignment::HORIZONTAL_RIGHT : $blockAlign = 3; break; + case PHPExcel_Style_Alignment::HORIZONTAL_CENTER : $blockAlign = 2; break; + case PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS : $blockAlign = 6; break; + case PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY : $blockAlign = 5; break; + } + if($conditional->getStyle()->getAlignment()->getWrapText() == true){ + $blockAlign |= 1 << 3; + } else { + $blockAlign |= 0 << 3; + } + switch ($conditional->getStyle()->getAlignment()->getVertical()){ + case PHPExcel_Style_Alignment::VERTICAL_BOTTOM : $blockAlign = 2 << 4; break; + case PHPExcel_Style_Alignment::VERTICAL_TOP : $blockAlign = 0 << 4; break; + case PHPExcel_Style_Alignment::VERTICAL_CENTER : $blockAlign = 1 << 4; break; + case PHPExcel_Style_Alignment::VERTICAL_JUSTIFY : $blockAlign = 3 << 4; break; + } + $blockAlign |= 0 << 7; + + // Text rotation angle + $blockRotation = $conditional->getStyle()->getAlignment()->getTextRotation(); + + // Indentation + $blockIndent = $conditional->getStyle()->getAlignment()->getIndent(); + if($conditional->getStyle()->getAlignment()->getShrinkToFit() == true){ + $blockIndent |= 1 << 4; + } else { + $blockIndent |= 0 << 4; + } + $blockIndent |= 0 << 6; + + // Relative indentation + $blockIndentRelative = 255; + + $dataBlockAlign = pack('CCvvv', $blockAlign, $blockRotation, $blockIndent, $blockIndentRelative, 0x0000); + } + if($bFormatBorder == 1){ + $blockLineStyle = 0; + switch ($conditional->getStyle()->getBorders()->getLeft()->getBorderStyle()){ + case PHPExcel_Style_Border::BORDER_NONE : $blockLineStyle |= 0x00; break; + case PHPExcel_Style_Border::BORDER_THIN : $blockLineStyle |= 0x01; break; + case PHPExcel_Style_Border::BORDER_MEDIUM : $blockLineStyle |= 0x02; break; + case PHPExcel_Style_Border::BORDER_DASHED : $blockLineStyle |= 0x03; break; + case PHPExcel_Style_Border::BORDER_DOTTED : $blockLineStyle |= 0x04; break; + case PHPExcel_Style_Border::BORDER_THICK : $blockLineStyle |= 0x05; break; + case PHPExcel_Style_Border::BORDER_DOUBLE : $blockLineStyle |= 0x06; break; + case PHPExcel_Style_Border::BORDER_HAIR : $blockLineStyle |= 0x07; break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHED : $blockLineStyle |= 0x08; break; + case PHPExcel_Style_Border::BORDER_DASHDOT : $blockLineStyle |= 0x09; break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT : $blockLineStyle |= 0x0A; break; + case PHPExcel_Style_Border::BORDER_DASHDOTDOT : $blockLineStyle |= 0x0B; break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT : $blockLineStyle |= 0x0C; break; + case PHPExcel_Style_Border::BORDER_SLANTDASHDOT : $blockLineStyle |= 0x0D; break; + } + switch ($conditional->getStyle()->getBorders()->getRight()->getBorderStyle()){ + case PHPExcel_Style_Border::BORDER_NONE : $blockLineStyle |= 0x00 << 4; break; + case PHPExcel_Style_Border::BORDER_THIN : $blockLineStyle |= 0x01 << 4; break; + case PHPExcel_Style_Border::BORDER_MEDIUM : $blockLineStyle |= 0x02 << 4; break; + case PHPExcel_Style_Border::BORDER_DASHED : $blockLineStyle |= 0x03 << 4; break; + case PHPExcel_Style_Border::BORDER_DOTTED : $blockLineStyle |= 0x04 << 4; break; + case PHPExcel_Style_Border::BORDER_THICK : $blockLineStyle |= 0x05 << 4; break; + case PHPExcel_Style_Border::BORDER_DOUBLE : $blockLineStyle |= 0x06 << 4; break; + case PHPExcel_Style_Border::BORDER_HAIR : $blockLineStyle |= 0x07 << 4; break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHED : $blockLineStyle |= 0x08 << 4; break; + case PHPExcel_Style_Border::BORDER_DASHDOT : $blockLineStyle |= 0x09 << 4; break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT : $blockLineStyle |= 0x0A << 4; break; + case PHPExcel_Style_Border::BORDER_DASHDOTDOT : $blockLineStyle |= 0x0B << 4; break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT : $blockLineStyle |= 0x0C << 4; break; + case PHPExcel_Style_Border::BORDER_SLANTDASHDOT : $blockLineStyle |= 0x0D << 4; break; + } + switch ($conditional->getStyle()->getBorders()->getTop()->getBorderStyle()){ + case PHPExcel_Style_Border::BORDER_NONE : $blockLineStyle |= 0x00 << 8; break; + case PHPExcel_Style_Border::BORDER_THIN : $blockLineStyle |= 0x01 << 8; break; + case PHPExcel_Style_Border::BORDER_MEDIUM : $blockLineStyle |= 0x02 << 8; break; + case PHPExcel_Style_Border::BORDER_DASHED : $blockLineStyle |= 0x03 << 8; break; + case PHPExcel_Style_Border::BORDER_DOTTED : $blockLineStyle |= 0x04 << 8; break; + case PHPExcel_Style_Border::BORDER_THICK : $blockLineStyle |= 0x05 << 8; break; + case PHPExcel_Style_Border::BORDER_DOUBLE : $blockLineStyle |= 0x06 << 8; break; + case PHPExcel_Style_Border::BORDER_HAIR : $blockLineStyle |= 0x07 << 8; break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHED : $blockLineStyle |= 0x08 << 8; break; + case PHPExcel_Style_Border::BORDER_DASHDOT : $blockLineStyle |= 0x09 << 8; break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT : $blockLineStyle |= 0x0A << 8; break; + case PHPExcel_Style_Border::BORDER_DASHDOTDOT : $blockLineStyle |= 0x0B << 8; break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT : $blockLineStyle |= 0x0C << 8; break; + case PHPExcel_Style_Border::BORDER_SLANTDASHDOT : $blockLineStyle |= 0x0D << 8; break; + } + switch ($conditional->getStyle()->getBorders()->getBottom()->getBorderStyle()){ + case PHPExcel_Style_Border::BORDER_NONE : $blockLineStyle |= 0x00 << 12; break; + case PHPExcel_Style_Border::BORDER_THIN : $blockLineStyle |= 0x01 << 12; break; + case PHPExcel_Style_Border::BORDER_MEDIUM : $blockLineStyle |= 0x02 << 12; break; + case PHPExcel_Style_Border::BORDER_DASHED : $blockLineStyle |= 0x03 << 12; break; + case PHPExcel_Style_Border::BORDER_DOTTED : $blockLineStyle |= 0x04 << 12; break; + case PHPExcel_Style_Border::BORDER_THICK : $blockLineStyle |= 0x05 << 12; break; + case PHPExcel_Style_Border::BORDER_DOUBLE : $blockLineStyle |= 0x06 << 12; break; + case PHPExcel_Style_Border::BORDER_HAIR : $blockLineStyle |= 0x07 << 12; break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHED : $blockLineStyle |= 0x08 << 12; break; + case PHPExcel_Style_Border::BORDER_DASHDOT : $blockLineStyle |= 0x09 << 12; break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT : $blockLineStyle |= 0x0A << 12; break; + case PHPExcel_Style_Border::BORDER_DASHDOTDOT : $blockLineStyle |= 0x0B << 12; break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT : $blockLineStyle |= 0x0C << 12; break; + case PHPExcel_Style_Border::BORDER_SLANTDASHDOT : $blockLineStyle |= 0x0D << 12; break; + } + //@todo _writeCFRule() => $blockLineStyle => Index Color for left line + //@todo _writeCFRule() => $blockLineStyle => Index Color for right line + //@todo _writeCFRule() => $blockLineStyle => Top-left to bottom-right on/off + //@todo _writeCFRule() => $blockLineStyle => Bottom-left to top-right on/off + $blockColor = 0; + //@todo _writeCFRule() => $blockColor => Index Color for top line + //@todo _writeCFRule() => $blockColor => Index Color for bottom line + //@todo _writeCFRule() => $blockColor => Index Color for diagonal line + switch ($conditional->getStyle()->getBorders()->getDiagonal()->getBorderStyle()){ + case PHPExcel_Style_Border::BORDER_NONE : $blockColor |= 0x00 << 21; break; + case PHPExcel_Style_Border::BORDER_THIN : $blockColor |= 0x01 << 21; break; + case PHPExcel_Style_Border::BORDER_MEDIUM : $blockColor |= 0x02 << 21; break; + case PHPExcel_Style_Border::BORDER_DASHED : $blockColor |= 0x03 << 21; break; + case PHPExcel_Style_Border::BORDER_DOTTED : $blockColor |= 0x04 << 21; break; + case PHPExcel_Style_Border::BORDER_THICK : $blockColor |= 0x05 << 21; break; + case PHPExcel_Style_Border::BORDER_DOUBLE : $blockColor |= 0x06 << 21; break; + case PHPExcel_Style_Border::BORDER_HAIR : $blockColor |= 0x07 << 21; break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHED : $blockColor |= 0x08 << 21; break; + case PHPExcel_Style_Border::BORDER_DASHDOT : $blockColor |= 0x09 << 21; break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT : $blockColor |= 0x0A << 21; break; + case PHPExcel_Style_Border::BORDER_DASHDOTDOT : $blockColor |= 0x0B << 21; break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT : $blockColor |= 0x0C << 21; break; + case PHPExcel_Style_Border::BORDER_SLANTDASHDOT : $blockColor |= 0x0D << 21; break; + } + $dataBlockBorder = pack('vv', $blockLineStyle, $blockColor); + } + if($bFormatFill == 1){ + // Fill Patern Style + $blockFillPatternStyle = 0; + switch ($conditional->getStyle()->getFill()->getFillType()){ + case PHPExcel_Style_Fill::FILL_NONE : $blockFillPatternStyle = 0x00; break; + case PHPExcel_Style_Fill::FILL_SOLID : $blockFillPatternStyle = 0x01; break; + case PHPExcel_Style_Fill::FILL_PATTERN_MEDIUMGRAY : $blockFillPatternStyle = 0x02; break; + case PHPExcel_Style_Fill::FILL_PATTERN_DARKGRAY : $blockFillPatternStyle = 0x03; break; + case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRAY : $blockFillPatternStyle = 0x04; break; + case PHPExcel_Style_Fill::FILL_PATTERN_DARKHORIZONTAL : $blockFillPatternStyle = 0x05; break; + case PHPExcel_Style_Fill::FILL_PATTERN_DARKVERTICAL : $blockFillPatternStyle = 0x06; break; + case PHPExcel_Style_Fill::FILL_PATTERN_DARKDOWN : $blockFillPatternStyle = 0x07; break; + case PHPExcel_Style_Fill::FILL_PATTERN_DARKUP : $blockFillPatternStyle = 0x08; break; + case PHPExcel_Style_Fill::FILL_PATTERN_DARKGRID : $blockFillPatternStyle = 0x09; break; + case PHPExcel_Style_Fill::FILL_PATTERN_DARKTRELLIS : $blockFillPatternStyle = 0x0A; break; + case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTHORIZONTAL : $blockFillPatternStyle = 0x0B; break; + case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTVERTICAL : $blockFillPatternStyle = 0x0C; break; + case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTDOWN : $blockFillPatternStyle = 0x0D; break; + case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTUP : $blockFillPatternStyle = 0x0E; break; + case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRID : $blockFillPatternStyle = 0x0F; break; + case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTTRELLIS : $blockFillPatternStyle = 0x10; break; + case PHPExcel_Style_Fill::FILL_PATTERN_GRAY125 : $blockFillPatternStyle = 0x11; break; + case PHPExcel_Style_Fill::FILL_PATTERN_GRAY0625 : $blockFillPatternStyle = 0x12; break; + case PHPExcel_Style_Fill::FILL_GRADIENT_LINEAR : $blockFillPatternStyle = 0x00; break; // does not exist in BIFF8 + case PHPExcel_Style_Fill::FILL_GRADIENT_PATH : $blockFillPatternStyle = 0x00; break; // does not exist in BIFF8 + default : $blockFillPatternStyle = 0x00; break; + } + // Color + switch ($conditional->getStyle()->getFill()->getStartColor()->getRGB()) { + case '000000': $colorIdxBg = 0x08; break; + case 'FFFFFF': $colorIdxBg = 0x09; break; + case 'FF0000': $colorIdxBg = 0x0A; break; + case '00FF00': $colorIdxBg = 0x0B; break; + case '0000FF': $colorIdxBg = 0x0C; break; + case 'FFFF00': $colorIdxBg = 0x0D; break; + case 'FF00FF': $colorIdxBg = 0x0E; break; + case '00FFFF': $colorIdxBg = 0x0F; break; + case '800000': $colorIdxBg = 0x10; break; + case '008000': $colorIdxBg = 0x11; break; + case '000080': $colorIdxBg = 0x12; break; + case '808000': $colorIdxBg = 0x13; break; + case '800080': $colorIdxBg = 0x14; break; + case '008080': $colorIdxBg = 0x15; break; + case 'C0C0C0': $colorIdxBg = 0x16; break; + case '808080': $colorIdxBg = 0x17; break; + case '9999FF': $colorIdxBg = 0x18; break; + case '993366': $colorIdxBg = 0x19; break; + case 'FFFFCC': $colorIdxBg = 0x1A; break; + case 'CCFFFF': $colorIdxBg = 0x1B; break; + case '660066': $colorIdxBg = 0x1C; break; + case 'FF8080': $colorIdxBg = 0x1D; break; + case '0066CC': $colorIdxBg = 0x1E; break; + case 'CCCCFF': $colorIdxBg = 0x1F; break; + case '000080': $colorIdxBg = 0x20; break; + case 'FF00FF': $colorIdxBg = 0x21; break; + case 'FFFF00': $colorIdxBg = 0x22; break; + case '00FFFF': $colorIdxBg = 0x23; break; + case '800080': $colorIdxBg = 0x24; break; + case '800000': $colorIdxBg = 0x25; break; + case '008080': $colorIdxBg = 0x26; break; + case '0000FF': $colorIdxBg = 0x27; break; + case '00CCFF': $colorIdxBg = 0x28; break; + case 'CCFFFF': $colorIdxBg = 0x29; break; + case 'CCFFCC': $colorIdxBg = 0x2A; break; + case 'FFFF99': $colorIdxBg = 0x2B; break; + case '99CCFF': $colorIdxBg = 0x2C; break; + case 'FF99CC': $colorIdxBg = 0x2D; break; + case 'CC99FF': $colorIdxBg = 0x2E; break; + case 'FFCC99': $colorIdxBg = 0x2F; break; + case '3366FF': $colorIdxBg = 0x30; break; + case '33CCCC': $colorIdxBg = 0x31; break; + case '99CC00': $colorIdxBg = 0x32; break; + case 'FFCC00': $colorIdxBg = 0x33; break; + case 'FF9900': $colorIdxBg = 0x34; break; + case 'FF6600': $colorIdxBg = 0x35; break; + case '666699': $colorIdxBg = 0x36; break; + case '969696': $colorIdxBg = 0x37; break; + case '003366': $colorIdxBg = 0x38; break; + case '339966': $colorIdxBg = 0x39; break; + case '003300': $colorIdxBg = 0x3A; break; + case '333300': $colorIdxBg = 0x3B; break; + case '993300': $colorIdxBg = 0x3C; break; + case '993366': $colorIdxBg = 0x3D; break; + case '333399': $colorIdxBg = 0x3E; break; + case '333333': $colorIdxBg = 0x3F; break; + default: $colorIdxBg = 0x41; break; + } + // Fg Color + switch ($conditional->getStyle()->getFill()->getEndColor()->getRGB()) { + case '000000': $colorIdxFg = 0x08; break; + case 'FFFFFF': $colorIdxFg = 0x09; break; + case 'FF0000': $colorIdxFg = 0x0A; break; + case '00FF00': $colorIdxFg = 0x0B; break; + case '0000FF': $colorIdxFg = 0x0C; break; + case 'FFFF00': $colorIdxFg = 0x0D; break; + case 'FF00FF': $colorIdxFg = 0x0E; break; + case '00FFFF': $colorIdxFg = 0x0F; break; + case '800000': $colorIdxFg = 0x10; break; + case '008000': $colorIdxFg = 0x11; break; + case '000080': $colorIdxFg = 0x12; break; + case '808000': $colorIdxFg = 0x13; break; + case '800080': $colorIdxFg = 0x14; break; + case '008080': $colorIdxFg = 0x15; break; + case 'C0C0C0': $colorIdxFg = 0x16; break; + case '808080': $colorIdxFg = 0x17; break; + case '9999FF': $colorIdxFg = 0x18; break; + case '993366': $colorIdxFg = 0x19; break; + case 'FFFFCC': $colorIdxFg = 0x1A; break; + case 'CCFFFF': $colorIdxFg = 0x1B; break; + case '660066': $colorIdxFg = 0x1C; break; + case 'FF8080': $colorIdxFg = 0x1D; break; + case '0066CC': $colorIdxFg = 0x1E; break; + case 'CCCCFF': $colorIdxFg = 0x1F; break; + case '000080': $colorIdxFg = 0x20; break; + case 'FF00FF': $colorIdxFg = 0x21; break; + case 'FFFF00': $colorIdxFg = 0x22; break; + case '00FFFF': $colorIdxFg = 0x23; break; + case '800080': $colorIdxFg = 0x24; break; + case '800000': $colorIdxFg = 0x25; break; + case '008080': $colorIdxFg = 0x26; break; + case '0000FF': $colorIdxFg = 0x27; break; + case '00CCFF': $colorIdxFg = 0x28; break; + case 'CCFFFF': $colorIdxFg = 0x29; break; + case 'CCFFCC': $colorIdxFg = 0x2A; break; + case 'FFFF99': $colorIdxFg = 0x2B; break; + case '99CCFF': $colorIdxFg = 0x2C; break; + case 'FF99CC': $colorIdxFg = 0x2D; break; + case 'CC99FF': $colorIdxFg = 0x2E; break; + case 'FFCC99': $colorIdxFg = 0x2F; break; + case '3366FF': $colorIdxFg = 0x30; break; + case '33CCCC': $colorIdxFg = 0x31; break; + case '99CC00': $colorIdxFg = 0x32; break; + case 'FFCC00': $colorIdxFg = 0x33; break; + case 'FF9900': $colorIdxFg = 0x34; break; + case 'FF6600': $colorIdxFg = 0x35; break; + case '666699': $colorIdxFg = 0x36; break; + case '969696': $colorIdxFg = 0x37; break; + case '003366': $colorIdxFg = 0x38; break; + case '339966': $colorIdxFg = 0x39; break; + case '003300': $colorIdxFg = 0x3A; break; + case '333300': $colorIdxFg = 0x3B; break; + case '993300': $colorIdxFg = 0x3C; break; + case '993366': $colorIdxFg = 0x3D; break; + case '333399': $colorIdxFg = 0x3E; break; + case '333333': $colorIdxFg = 0x3F; break; + default: $colorIdxFg = 0x40; break; + } + $dataBlockFill = pack('v', $blockFillPatternStyle); + $dataBlockFill .= pack('v', $colorIdxFg | ($colorIdxBg << 7)); + } + if($bFormatProt == 1){ + $dataBlockProtection = 0; + if($conditional->getStyle()->getProtection()->getLocked() == PHPExcel_Style_Protection::PROTECTION_PROTECTED){ + $dataBlockProtection = 1; + } + if($conditional->getStyle()->getProtection()->getHidden() == PHPExcel_Style_Protection::PROTECTION_PROTECTED){ + $dataBlockProtection = 1 << 1; + } + } + + $data = pack('CCvvVv', $type, $operatorType, $szValue1, $szValue2, $flags, 0x0000); + if($bFormatFont == 1){ // Block Formatting : OK + $data .= $dataBlockFont; + } + if($bFormatAlign == 1){ + $data .= $dataBlockAlign; + } + if($bFormatBorder == 1){ + $data .= $dataBlockBorder; + } + if($bFormatFill == 1){ // Block Formatting : OK + $data .= $dataBlockFill; + } + if($bFormatProt == 1){ + $data .= $dataBlockProtection; + } + if(!is_null($operand1)){ + $data .= $operand1; + } + if(!is_null($operand2)){ + $data .= $operand2; + } + $header = pack('vv', $record, strlen($data)); + $this->_append($header . $data); + } + + /** + * Write CFHeader record + */ + private function _writeCFHeader(){ + $record = 0x01B0; // Record identifier + $length = 0x0016; // Bytes to follow + + $numColumnMin = null; + $numColumnMax = null; + $numRowMin = null; + $numRowMax = null; + $arrConditional = array(); + foreach ($this->_phpSheet->getConditionalStylesCollection() as $cellCoordinate => $conditionalStyles) { + foreach ($conditionalStyles as $conditional) { + if($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_EXPRESSION + || $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS){ + if(!in_array($conditional->getHashCode(), $arrConditional)){ + $arrConditional[] = $conditional->getHashCode(); + } + // Cells + $arrCoord = PHPExcel_Cell::coordinateFromString($cellCoordinate); + if(!is_numeric($arrCoord[0])){ + $arrCoord[0] = PHPExcel_Cell::columnIndexFromString($arrCoord[0]); + } + if(is_null($numColumnMin) || ($numColumnMin > $arrCoord[0])){ + $numColumnMin = $arrCoord[0]; + } + if(is_null($numColumnMax) || ($numColumnMax < $arrCoord[0])){ + $numColumnMax = $arrCoord[0]; + } + if(is_null($numRowMin) || ($numRowMin > $arrCoord[1])){ + $numRowMin = $arrCoord[1]; + } + if(is_null($numRowMax) || ($numRowMax < $arrCoord[1])){ + $numRowMax = $arrCoord[1]; + } + } + } + } + $needRedraw = 1; + $cellRange = pack('vvvv', $numRowMin-1, $numRowMax-1, $numColumnMin-1, $numColumnMax-1); + + $header = pack('vv', $record, $length); + $data = pack('vv', count($arrConditional), $needRedraw); + $data .= $cellRange; + $data .= pack('v', 0x0001); + $data .= $cellRange; + $this->_append($header . $data); + } +} \ No newline at end of file diff --git a/lib/phpexcel/PHPExcel/Writer/Excel5/Xf.php b/lib/phpexcel/PHPExcel/Writer/Excel5/Xf.php new file mode 100644 index 0000000..f803f68 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Writer/Excel5/Xf.php @@ -0,0 +1,547 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel5 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + +// Original file header of PEAR::Spreadsheet_Excel_Writer_Format (used as the base for this class): +// ----------------------------------------------------------------------------------------- +// /* +// * Module written/ported by Xavier Noguer <xnoguer@rezebra.com> +// * +// * The majority of this is _NOT_ my code. I simply ported it from the +// * PERL Spreadsheet::WriteExcel module. +// * +// * The author of the Spreadsheet::WriteExcel module is John McNamara +// * <jmcnamara@cpan.org> +// * +// * I _DO_ maintain this code, and John McNamara has nothing to do with the +// * porting of this code to PHP. Any questions directly related to this +// * class library should be directed to me. +// * +// * License Information: +// * +// * Spreadsheet_Excel_Writer: A library for generating Excel Spreadsheets +// * Copyright (c) 2002-2003 Xavier Noguer xnoguer@rezebra.com +// * +// * This library is free software; you can redistribute it and/or +// * modify it under the terms of the GNU Lesser General Public +// * License as published by the Free Software Foundation; either +// * version 2.1 of the License, or (at your option) any later version. +// * +// * This library is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// * Lesser General Public License for more details. +// * +// * You should have received a copy of the GNU Lesser General Public +// * License along with this library; if not, write to the Free Software +// * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// */ + + +/** + * PHPExcel_Writer_Excel5_Xf + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel5 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_Excel5_Xf +{ + /** + * Style XF or a cell XF ? + * + * @var boolean + */ + private $_isStyleXf; + + /** + * Index to the FONT record. Index 4 does not exist + * @var integer + */ + private $_fontIndex; + + /** + * An index (2 bytes) to a FORMAT record (number format). + * @var integer + */ + public $_numberFormatIndex; + + /** + * 1 bit, apparently not used. + * @var integer + */ + public $_text_justlast; + + /** + * The cell's foreground color. + * @var integer + */ + public $_fg_color; + + /** + * The cell's background color. + * @var integer + */ + public $_bg_color; + + /** + * Color of the bottom border of the cell. + * @var integer + */ + public $_bottom_color; + + /** + * Color of the top border of the cell. + * @var integer + */ + public $_top_color; + + /** + * Color of the left border of the cell. + * @var integer + */ + public $_left_color; + + /** + * Color of the right border of the cell. + * @var integer + */ + public $_right_color; + + /** + * Constructor + * + * @access public + * @param PHPExcel_Style The XF format + */ + public function __construct(PHPExcel_Style $style = null) + { + $this->_isStyleXf = false; + $this->_fontIndex = 0; + + $this->_numberFormatIndex = 0; + + $this->_text_justlast = 0; + + $this->_fg_color = 0x40; + $this->_bg_color = 0x41; + + $this->_diag = 0; + + $this->_bottom_color = 0x40; + $this->_top_color = 0x40; + $this->_left_color = 0x40; + $this->_right_color = 0x40; + $this->_diag_color = 0x40; + $this->_style = $style; + + } + + + /** + * Generate an Excel BIFF XF record (style or cell). + * + * @return string The XF record + */ + function writeXf() + { + // Set the type of the XF record and some of the attributes. + if ($this->_isStyleXf) { + $style = 0xFFF5; + } else { + $style = self::_mapLocked($this->_style->getProtection()->getLocked()); + $style |= self::_mapHidden($this->_style->getProtection()->getHidden()) << 1; + } + + // Flags to indicate if attributes have been set. + $atr_num = ($this->_numberFormatIndex != 0)?1:0; + $atr_fnt = ($this->_fontIndex != 0)?1:0; + $atr_alc = ((int) $this->_style->getAlignment()->getWrapText()) ? 1 : 0; + $atr_bdr = (self::_mapBorderStyle($this->_style->getBorders()->getBottom()->getBorderStyle()) || + self::_mapBorderStyle($this->_style->getBorders()->getTop()->getBorderStyle()) || + self::_mapBorderStyle($this->_style->getBorders()->getLeft()->getBorderStyle()) || + self::_mapBorderStyle($this->_style->getBorders()->getRight()->getBorderStyle()))?1:0; + $atr_pat = (($this->_fg_color != 0x40) || + ($this->_bg_color != 0x41) || + self::_mapFillType($this->_style->getFill()->getFillType()))?1:0; + $atr_prot = self::_mapLocked($this->_style->getProtection()->getLocked()) + | self::_mapHidden($this->_style->getProtection()->getHidden()); + + // Zero the default border colour if the border has not been set. + if (self::_mapBorderStyle($this->_style->getBorders()->getBottom()->getBorderStyle()) == 0) { + $this->_bottom_color = 0; + } + if (self::_mapBorderStyle($this->_style->getBorders()->getTop()->getBorderStyle()) == 0) { + $this->_top_color = 0; + } + if (self::_mapBorderStyle($this->_style->getBorders()->getRight()->getBorderStyle()) == 0) { + $this->_right_color = 0; + } + if (self::_mapBorderStyle($this->_style->getBorders()->getLeft()->getBorderStyle()) == 0) { + $this->_left_color = 0; + } + if (self::_mapBorderStyle($this->_style->getBorders()->getDiagonal()->getBorderStyle()) == 0) { + $this->_diag_color = 0; + } + + $record = 0x00E0; // Record identifier + $length = 0x0014; // Number of bytes to follow + + $ifnt = $this->_fontIndex; // Index to FONT record + $ifmt = $this->_numberFormatIndex; // Index to FORMAT record + + $align = $this->_mapHAlign($this->_style->getAlignment()->getHorizontal()); // Alignment + $align |= (int) $this->_style->getAlignment()->getWrapText() << 3; + $align |= self::_mapVAlign($this->_style->getAlignment()->getVertical()) << 4; + $align |= $this->_text_justlast << 7; + + $used_attrib = $atr_num << 2; + $used_attrib |= $atr_fnt << 3; + $used_attrib |= $atr_alc << 4; + $used_attrib |= $atr_bdr << 5; + $used_attrib |= $atr_pat << 6; + $used_attrib |= $atr_prot << 7; + + $icv = $this->_fg_color; // fg and bg pattern colors + $icv |= $this->_bg_color << 7; + + $border1 = self::_mapBorderStyle($this->_style->getBorders()->getLeft()->getBorderStyle()); // Border line style and color + $border1 |= self::_mapBorderStyle($this->_style->getBorders()->getRight()->getBorderStyle()) << 4; + $border1 |= self::_mapBorderStyle($this->_style->getBorders()->getTop()->getBorderStyle()) << 8; + $border1 |= self::_mapBorderStyle($this->_style->getBorders()->getBottom()->getBorderStyle()) << 12; + $border1 |= $this->_left_color << 16; + $border1 |= $this->_right_color << 23; + + $diagonalDirection = $this->_style->getBorders()->getDiagonalDirection(); + $diag_tl_to_rb = $diagonalDirection == PHPExcel_Style_Borders::DIAGONAL_BOTH + || $diagonalDirection == PHPExcel_Style_Borders::DIAGONAL_DOWN; + $diag_tr_to_lb = $diagonalDirection == PHPExcel_Style_Borders::DIAGONAL_BOTH + || $diagonalDirection == PHPExcel_Style_Borders::DIAGONAL_UP; + $border1 |= $diag_tl_to_rb << 30; + $border1 |= $diag_tr_to_lb << 31; + + $border2 = $this->_top_color; // Border color + $border2 |= $this->_bottom_color << 7; + $border2 |= $this->_diag_color << 14; + $border2 |= self::_mapBorderStyle($this->_style->getBorders()->getDiagonal()->getBorderStyle()) << 21; + $border2 |= self::_mapFillType($this->_style->getFill()->getFillType()) << 26; + + $header = pack("vv", $record, $length); + + //BIFF8 options: identation, shrinkToFit and text direction + $biff8_options = $this->_style->getAlignment()->getIndent(); + $biff8_options |= (int) $this->_style->getAlignment()->getShrinkToFit() << 4; + + $data = pack("vvvC", $ifnt, $ifmt, $style, $align); + $data .= pack("CCC" + , self::_mapTextRotation($this->_style->getAlignment()->getTextRotation()) + , $biff8_options + , $used_attrib + ); + $data .= pack("VVv", $border1, $border2, $icv); + + return($header . $data); + } + + /** + * Is this a style XF ? + * + * @param boolean $value + */ + public function setIsStyleXf($value) + { + $this->_isStyleXf = $value; + } + + /** + * Sets the cell's bottom border color + * + * @access public + * @param int $colorIndex Color index + */ + function setBottomColor($colorIndex) + { + $this->_bottom_color = $colorIndex; + } + + /** + * Sets the cell's top border color + * + * @access public + * @param int $colorIndex Color index + */ + function setTopColor($colorIndex) + { + $this->_top_color = $colorIndex; + } + + /** + * Sets the cell's left border color + * + * @access public + * @param int $colorIndex Color index + */ + function setLeftColor($colorIndex) + { + $this->_left_color = $colorIndex; + } + + /** + * Sets the cell's right border color + * + * @access public + * @param int $colorIndex Color index + */ + function setRightColor($colorIndex) + { + $this->_right_color = $colorIndex; + } + + /** + * Sets the cell's diagonal border color + * + * @access public + * @param int $colorIndex Color index + */ + function setDiagColor($colorIndex) + { + $this->_diag_color = $colorIndex; + } + + + /** + * Sets the cell's foreground color + * + * @access public + * @param int $colorIndex Color index + */ + function setFgColor($colorIndex) + { + $this->_fg_color = $colorIndex; + } + + /** + * Sets the cell's background color + * + * @access public + * @param int $colorIndex Color index + */ + function setBgColor($colorIndex) + { + $this->_bg_color = $colorIndex; + } + + /** + * Sets the index to the number format record + * It can be date, time, currency, etc... + * + * @access public + * @param integer $numberFormatIndex Index to format record + */ + function setNumberFormatIndex($numberFormatIndex) + { + $this->_numberFormatIndex = $numberFormatIndex; + } + + /** + * Set the font index. + * + * @param int $value Font index, note that value 4 does not exist + */ + public function setFontIndex($value) + { + $this->_fontIndex = $value; + } + + /** + * Map of BIFF2-BIFF8 codes for border styles + * @static array of int + * + */ + private static $_mapBorderStyle = array ( PHPExcel_Style_Border::BORDER_NONE => 0x00, + PHPExcel_Style_Border::BORDER_THIN => 0x01, + PHPExcel_Style_Border::BORDER_MEDIUM => 0x02, + PHPExcel_Style_Border::BORDER_DASHED => 0x03, + PHPExcel_Style_Border::BORDER_DOTTED => 0x04, + PHPExcel_Style_Border::BORDER_THICK => 0x05, + PHPExcel_Style_Border::BORDER_DOUBLE => 0x06, + PHPExcel_Style_Border::BORDER_HAIR => 0x07, + PHPExcel_Style_Border::BORDER_MEDIUMDASHED => 0x08, + PHPExcel_Style_Border::BORDER_DASHDOT => 0x09, + PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT => 0x0A, + PHPExcel_Style_Border::BORDER_DASHDOTDOT => 0x0B, + PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT => 0x0C, + PHPExcel_Style_Border::BORDER_SLANTDASHDOT => 0x0D, + ); + + /** + * Map border style + * + * @param string $borderStyle + * @return int + */ + private static function _mapBorderStyle($borderStyle) { + if (isset(self::$_mapBorderStyle[$borderStyle])) + return self::$_mapBorderStyle[$borderStyle]; + return 0x00; + } + + /** + * Map of BIFF2-BIFF8 codes for fill types + * @static array of int + * + */ + private static $_mapFillType = array( PHPExcel_Style_Fill::FILL_NONE => 0x00, + PHPExcel_Style_Fill::FILL_SOLID => 0x01, + PHPExcel_Style_Fill::FILL_PATTERN_MEDIUMGRAY => 0x02, + PHPExcel_Style_Fill::FILL_PATTERN_DARKGRAY => 0x03, + PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRAY => 0x04, + PHPExcel_Style_Fill::FILL_PATTERN_DARKHORIZONTAL => 0x05, + PHPExcel_Style_Fill::FILL_PATTERN_DARKVERTICAL => 0x06, + PHPExcel_Style_Fill::FILL_PATTERN_DARKDOWN => 0x07, + PHPExcel_Style_Fill::FILL_PATTERN_DARKUP => 0x08, + PHPExcel_Style_Fill::FILL_PATTERN_DARKGRID => 0x09, + PHPExcel_Style_Fill::FILL_PATTERN_DARKTRELLIS => 0x0A, + PHPExcel_Style_Fill::FILL_PATTERN_LIGHTHORIZONTAL => 0x0B, + PHPExcel_Style_Fill::FILL_PATTERN_LIGHTVERTICAL => 0x0C, + PHPExcel_Style_Fill::FILL_PATTERN_LIGHTDOWN => 0x0D, + PHPExcel_Style_Fill::FILL_PATTERN_LIGHTUP => 0x0E, + PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRID => 0x0F, + PHPExcel_Style_Fill::FILL_PATTERN_LIGHTTRELLIS => 0x10, + PHPExcel_Style_Fill::FILL_PATTERN_GRAY125 => 0x11, + PHPExcel_Style_Fill::FILL_PATTERN_GRAY0625 => 0x12, + PHPExcel_Style_Fill::FILL_GRADIENT_LINEAR => 0x00, // does not exist in BIFF8 + PHPExcel_Style_Fill::FILL_GRADIENT_PATH => 0x00, // does not exist in BIFF8 + ); + /** + * Map fill type + * + * @param string $fillType + * @return int + */ + private static function _mapFillType($fillType) { + if (isset(self::$_mapFillType[$fillType])) + return self::$_mapFillType[$fillType]; + return 0x00; + } + + /** + * Map of BIFF2-BIFF8 codes for horizontal alignment + * @static array of int + * + */ + private static $_mapHAlign = array( PHPExcel_Style_Alignment::HORIZONTAL_GENERAL => 0, + PHPExcel_Style_Alignment::HORIZONTAL_LEFT => 1, + PHPExcel_Style_Alignment::HORIZONTAL_CENTER => 2, + PHPExcel_Style_Alignment::HORIZONTAL_RIGHT => 3, + PHPExcel_Style_Alignment::HORIZONTAL_FILL => 4, + PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY => 5, + PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS => 6, + ); + /** + * Map to BIFF2-BIFF8 codes for horizontal alignment + * + * @param string $hAlign + * @return int + */ + private function _mapHAlign($hAlign) + { + if (isset(self::$_mapHAlign[$hAlign])) + return self::$_mapHAlign[$hAlign]; + return 0; + } + + /** + * Map of BIFF2-BIFF8 codes for vertical alignment + * @static array of int + * + */ + private static $_mapVAlign = array( PHPExcel_Style_Alignment::VERTICAL_TOP => 0, + PHPExcel_Style_Alignment::VERTICAL_CENTER => 1, + PHPExcel_Style_Alignment::VERTICAL_BOTTOM => 2, + PHPExcel_Style_Alignment::VERTICAL_JUSTIFY => 3, + ); + /** + * Map to BIFF2-BIFF8 codes for vertical alignment + * + * @param string $vAlign + * @return int + */ + private static function _mapVAlign($vAlign) { + if (isset(self::$_mapVAlign[$vAlign])) + return self::$_mapVAlign[$vAlign]; + return 2; + } + + /** + * Map to BIFF8 codes for text rotation angle + * + * @param int $textRotation + * @return int + */ + private static function _mapTextRotation($textRotation) { + if ($textRotation >= 0) { + return $textRotation; + } + if ($textRotation == -165) { + return 255; + } + if ($textRotation < 0) { + return 90 - $textRotation; + } + } + + /** + * Map locked + * + * @param string + * @return int + */ + private static function _mapLocked($locked) { + switch ($locked) { + case PHPExcel_Style_Protection::PROTECTION_INHERIT: return 1; + case PHPExcel_Style_Protection::PROTECTION_PROTECTED: return 1; + case PHPExcel_Style_Protection::PROTECTION_UNPROTECTED: return 0; + default: return 1; + } + } + + /** + * Map hidden + * + * @param string + * @return int + */ + private static function _mapHidden($hidden) { + switch ($hidden) { + case PHPExcel_Style_Protection::PROTECTION_INHERIT: return 0; + case PHPExcel_Style_Protection::PROTECTION_PROTECTED: return 1; + case PHPExcel_Style_Protection::PROTECTION_UNPROTECTED: return 0; + default: return 0; + } + } + +} diff --git a/lib/phpexcel/PHPExcel/Writer/Exception.php b/lib/phpexcel/PHPExcel/Writer/Exception.php new file mode 100644 index 0000000..e8fe9be --- /dev/null +++ b/lib/phpexcel/PHPExcel/Writer/Exception.php @@ -0,0 +1,52 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Writer_Exception + * + * @category PHPExcel + * @package PHPExcel_Writer + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_Exception extends PHPExcel_Exception { + /** + * Error handler callback + * + * @param mixed $code + * @param mixed $string + * @param mixed $file + * @param mixed $line + * @param mixed $context + */ + public static function errorHandlerCallback($code, $string, $file, $line, $context) { + $e = new self($string, $code); + $e->line = $line; + $e->file = $file; + throw $e; + } +} diff --git a/lib/phpexcel/PHPExcel/Writer/HTML.php b/lib/phpexcel/PHPExcel/Writer/HTML.php new file mode 100644 index 0000000..0f2cc08 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Writer/HTML.php @@ -0,0 +1,1532 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_HTML + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Writer_HTML + * + * @category PHPExcel + * @package PHPExcel_Writer_HTML + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_HTML extends PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter { + /** + * PHPExcel object + * + * @var PHPExcel + */ + protected $_phpExcel; + + /** + * Sheet index to write + * + * @var int + */ + private $_sheetIndex = 0; + + /** + * Images root + * + * @var string + */ + private $_imagesRoot = '.'; + + /** + * embed images, or link to images + * + * @var boolean + */ + private $_embedImages = FALSE; + + /** + * Use inline CSS? + * + * @var boolean + */ + private $_useInlineCss = false; + + /** + * Array of CSS styles + * + * @var array + */ + private $_cssStyles = null; + + /** + * Array of column widths in points + * + * @var array + */ + private $_columnWidths = null; + + /** + * Default font + * + * @var PHPExcel_Style_Font + */ + private $_defaultFont; + + /** + * Flag whether spans have been calculated + * + * @var boolean + */ + private $_spansAreCalculated = false; + + /** + * Excel cells that should not be written as HTML cells + * + * @var array + */ + private $_isSpannedCell = array(); + + /** + * Excel cells that are upper-left corner in a cell merge + * + * @var array + */ + private $_isBaseCell = array(); + + /** + * Excel rows that should not be written as HTML rows + * + * @var array + */ + private $_isSpannedRow = array(); + + /** + * Is the current writer creating PDF? + * + * @var boolean + */ + protected $_isPdf = false; + + /** + * Generate the Navigation block + * + * @var boolean + */ + private $_generateSheetNavigationBlock = true; + + /** + * Create a new PHPExcel_Writer_HTML + * + * @param PHPExcel $phpExcel PHPExcel object + */ + public function __construct(PHPExcel $phpExcel) { + $this->_phpExcel = $phpExcel; + $this->_defaultFont = $this->_phpExcel->getDefaultStyle()->getFont(); + } + + /** + * Save PHPExcel to file + * + * @param string $pFilename + * @throws PHPExcel_Writer_Exception + */ + public function save($pFilename = null) { + // garbage collect + $this->_phpExcel->garbageCollect(); + + $saveDebugLog = PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->getWriteDebugLog(); + PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog(FALSE); + $saveArrayReturnType = PHPExcel_Calculation::getArrayReturnType(); + PHPExcel_Calculation::setArrayReturnType(PHPExcel_Calculation::RETURN_ARRAY_AS_VALUE); + + // Build CSS + $this->buildCSS(!$this->_useInlineCss); + + // Open file + $fileHandle = fopen($pFilename, 'wb+'); + if ($fileHandle === false) { + throw new PHPExcel_Writer_Exception("Could not open file $pFilename for writing."); + } + + // Write headers + fwrite($fileHandle, $this->generateHTMLHeader(!$this->_useInlineCss)); + + // Write navigation (tabs) + if ((!$this->_isPdf) && ($this->_generateSheetNavigationBlock)) { + fwrite($fileHandle, $this->generateNavigation()); + } + + // Write data + fwrite($fileHandle, $this->generateSheetData()); + + // Write footer + fwrite($fileHandle, $this->generateHTMLFooter()); + + // Close file + fclose($fileHandle); + + PHPExcel_Calculation::setArrayReturnType($saveArrayReturnType); + PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog($saveDebugLog); + } + + /** + * Map VAlign + * + * @param string $vAlign Vertical alignment + * @return string + */ + private function _mapVAlign($vAlign) { + switch ($vAlign) { + case PHPExcel_Style_Alignment::VERTICAL_BOTTOM: return 'bottom'; + case PHPExcel_Style_Alignment::VERTICAL_TOP: return 'top'; + case PHPExcel_Style_Alignment::VERTICAL_CENTER: + case PHPExcel_Style_Alignment::VERTICAL_JUSTIFY: return 'middle'; + default: return 'baseline'; + } + } + + /** + * Map HAlign + * + * @param string $hAlign Horizontal alignment + * @return string|false + */ + private function _mapHAlign($hAlign) { + switch ($hAlign) { + case PHPExcel_Style_Alignment::HORIZONTAL_GENERAL: return false; + case PHPExcel_Style_Alignment::HORIZONTAL_LEFT: return 'left'; + case PHPExcel_Style_Alignment::HORIZONTAL_RIGHT: return 'right'; + case PHPExcel_Style_Alignment::HORIZONTAL_CENTER: + case PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS: return 'center'; + case PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY: return 'justify'; + default: return false; + } + } + + /** + * Map border style + * + * @param int $borderStyle Sheet index + * @return string + */ + private function _mapBorderStyle($borderStyle) { + switch ($borderStyle) { + case PHPExcel_Style_Border::BORDER_NONE: return 'none'; + case PHPExcel_Style_Border::BORDER_DASHDOT: return '1px dashed'; + case PHPExcel_Style_Border::BORDER_DASHDOTDOT: return '1px dotted'; + case PHPExcel_Style_Border::BORDER_DASHED: return '1px dashed'; + case PHPExcel_Style_Border::BORDER_DOTTED: return '1px dotted'; + case PHPExcel_Style_Border::BORDER_DOUBLE: return '3px double'; + case PHPExcel_Style_Border::BORDER_HAIR: return '1px solid'; + case PHPExcel_Style_Border::BORDER_MEDIUM: return '2px solid'; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT: return '2px dashed'; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT: return '2px dotted'; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHED: return '2px dashed'; + case PHPExcel_Style_Border::BORDER_SLANTDASHDOT: return '2px dashed'; + case PHPExcel_Style_Border::BORDER_THICK: return '3px solid'; + case PHPExcel_Style_Border::BORDER_THIN: return '1px solid'; + default: return '1px solid'; // map others to thin + } + } + + /** + * Get sheet index + * + * @return int + */ + public function getSheetIndex() { + return $this->_sheetIndex; + } + + /** + * Set sheet index + * + * @param int $pValue Sheet index + * @return PHPExcel_Writer_HTML + */ + public function setSheetIndex($pValue = 0) { + $this->_sheetIndex = $pValue; + return $this; + } + + /** + * Get sheet index + * + * @return boolean + */ + public function getGenerateSheetNavigationBlock() { + return $this->_generateSheetNavigationBlock; + } + + /** + * Set sheet index + * + * @param boolean $pValue Flag indicating whether the sheet navigation block should be generated or not + * @return PHPExcel_Writer_HTML + */ + public function setGenerateSheetNavigationBlock($pValue = true) { + $this->_generateSheetNavigationBlock = (bool) $pValue; + return $this; + } + + /** + * Write all sheets (resets sheetIndex to NULL) + */ + public function writeAllSheets() { + $this->_sheetIndex = null; + return $this; + } + + /** + * Generate HTML header + * + * @param boolean $pIncludeStyles Include styles? + * @return string + * @throws PHPExcel_Writer_Exception + */ + public function generateHTMLHeader($pIncludeStyles = false) { + // PHPExcel object known? + if (is_null($this->_phpExcel)) { + throw new PHPExcel_Writer_Exception('Internal PHPExcel object not set to an instance of an object.'); + } + + // Construct HTML + $properties = $this->_phpExcel->getProperties(); + $html = '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">' . PHP_EOL; + $html .= '<!-- Generated by PHPExcel - http://www.phpexcel.net -->' . PHP_EOL; + $html .= '<html>' . PHP_EOL; + $html .= ' <head>' . PHP_EOL; + $html .= ' <meta http-equiv="Content-Type" content="text/html; charset=utf-8">' . PHP_EOL; + if ($properties->getTitle() > '') + $html .= ' <title>' . htmlspecialchars($properties->getTitle()) . '</title>' . PHP_EOL; + + if ($properties->getCreator() > '') + $html .= ' <meta name="author" content="' . htmlspecialchars($properties->getCreator()) . '" />' . PHP_EOL; + if ($properties->getTitle() > '') + $html .= ' <meta name="title" content="' . htmlspecialchars($properties->getTitle()) . '" />' . PHP_EOL; + if ($properties->getDescription() > '') + $html .= ' <meta name="description" content="' . htmlspecialchars($properties->getDescription()) . '" />' . PHP_EOL; + if ($properties->getSubject() > '') + $html .= ' <meta name="subject" content="' . htmlspecialchars($properties->getSubject()) . '" />' . PHP_EOL; + if ($properties->getKeywords() > '') + $html .= ' <meta name="keywords" content="' . htmlspecialchars($properties->getKeywords()) . '" />' . PHP_EOL; + if ($properties->getCategory() > '') + $html .= ' <meta name="category" content="' . htmlspecialchars($properties->getCategory()) . '" />' . PHP_EOL; + if ($properties->getCompany() > '') + $html .= ' <meta name="company" content="' . htmlspecialchars($properties->getCompany()) . '" />' . PHP_EOL; + if ($properties->getManager() > '') + $html .= ' <meta name="manager" content="' . htmlspecialchars($properties->getManager()) . '" />' . PHP_EOL; + + if ($pIncludeStyles) { + $html .= $this->generateStyles(true); + } + + $html .= ' </head>' . PHP_EOL; + $html .= '' . PHP_EOL; + $html .= ' <body>' . PHP_EOL; + + // Return + return $html; + } + + /** + * Generate sheet data + * + * @return string + * @throws PHPExcel_Writer_Exception + */ + public function generateSheetData() { + // PHPExcel object known? + if (is_null($this->_phpExcel)) { + throw new PHPExcel_Writer_Exception('Internal PHPExcel object not set to an instance of an object.'); + } + + // Ensure that Spans have been calculated? + if (!$this->_spansAreCalculated) { + $this->_calculateSpans(); + } + + // Fetch sheets + $sheets = array(); + if (is_null($this->_sheetIndex)) { + $sheets = $this->_phpExcel->getAllSheets(); + } else { + $sheets[] = $this->_phpExcel->getSheet($this->_sheetIndex); + } + + // Construct HTML + $html = ''; + + // Loop all sheets + $sheetId = 0; + foreach ($sheets as $sheet) { + // Write table header + $html .= $this->_generateTableHeader($sheet); + + // Get worksheet dimension + $dimension = explode(':', $sheet->calculateWorksheetDimension()); + $dimension[0] = PHPExcel_Cell::coordinateFromString($dimension[0]); + $dimension[0][0] = PHPExcel_Cell::columnIndexFromString($dimension[0][0]) - 1; + $dimension[1] = PHPExcel_Cell::coordinateFromString($dimension[1]); + $dimension[1][0] = PHPExcel_Cell::columnIndexFromString($dimension[1][0]) - 1; + + // row min,max + $rowMin = $dimension[0][1]; + $rowMax = $dimension[1][1]; + + // calculate start of <tbody>, <thead> + $tbodyStart = $rowMin; + $theadStart = $theadEnd = 0; // default: no <thead> no </thead> + if ($sheet->getPageSetup()->isRowsToRepeatAtTopSet()) { + $rowsToRepeatAtTop = $sheet->getPageSetup()->getRowsToRepeatAtTop(); + + // we can only support repeating rows that start at top row + if ($rowsToRepeatAtTop[0] == 1) { + $theadStart = $rowsToRepeatAtTop[0]; + $theadEnd = $rowsToRepeatAtTop[1]; + $tbodyStart = $rowsToRepeatAtTop[1] + 1; + } + } + + // Loop through cells + $row = $rowMin-1; + while($row++ < $rowMax) { + // <thead> ? + if ($row == $theadStart) { + $html .= ' <thead>' . PHP_EOL; + } + + // <tbody> ? + if ($row == $tbodyStart) { + $html .= ' <tbody>' . PHP_EOL; + } + + // Write row if there are HTML table cells in it + if ( !isset($this->_isSpannedRow[$sheet->getParent()->getIndex($sheet)][$row]) ) { + // Start a new rowData + $rowData = array(); + // Loop through columns + $column = $dimension[0][0] - 1; + while($column++ < $dimension[1][0]) { + // Cell exists? + if ($sheet->cellExistsByColumnAndRow($column, $row)) { + $rowData[$column] = PHPExcel_Cell::stringFromColumnIndex($column) . $row; + } else { + $rowData[$column] = ''; + } + } + $html .= $this->_generateRow($sheet, $rowData, $row - 1); + } + + // </thead> ? + if ($row == $theadEnd) { + $html .= ' </thead>' . PHP_EOL; + } + } + $html .= $this->_extendRowsForChartsAndImages($sheet, $row); + + // Close table body. + $html .= ' </tbody>' . PHP_EOL; + + // Write table footer + $html .= $this->_generateTableFooter(); + + // Writing PDF? + if ($this->_isPdf) { + if (is_null($this->_sheetIndex) && $sheetId + 1 < $this->_phpExcel->getSheetCount()) { + $html .= '<div style="page-break-before:always" />'; + } + } + + // Next sheet + ++$sheetId; + } + + // Return + return $html; + } + + /** + * Generate sheet tabs + * + * @return string + * @throws PHPExcel_Writer_Exception + */ + public function generateNavigation() + { + // PHPExcel object known? + if (is_null($this->_phpExcel)) { + throw new PHPExcel_Writer_Exception('Internal PHPExcel object not set to an instance of an object.'); + } + + // Fetch sheets + $sheets = array(); + if (is_null($this->_sheetIndex)) { + $sheets = $this->_phpExcel->getAllSheets(); + } else { + $sheets[] = $this->_phpExcel->getSheet($this->_sheetIndex); + } + + // Construct HTML + $html = ''; + + // Only if there are more than 1 sheets + if (count($sheets) > 1) { + // Loop all sheets + $sheetId = 0; + + $html .= '<ul class="navigation">' . PHP_EOL; + + foreach ($sheets as $sheet) { + $html .= ' <li class="sheet' . $sheetId . '"><a href="#sheet' . $sheetId . '">' . $sheet->getTitle() . '</a></li>' . PHP_EOL; + ++$sheetId; + } + + $html .= '</ul>' . PHP_EOL; + } + + return $html; + } + + private function _extendRowsForChartsAndImages(PHPExcel_Worksheet $pSheet, $row) { + $rowMax = $row; + $colMax = 'A'; + if ($this->_includeCharts) { + foreach ($pSheet->getChartCollection() as $chart) { + if ($chart instanceof PHPExcel_Chart) { + $chartCoordinates = $chart->getTopLeftPosition(); + $chartTL = PHPExcel_Cell::coordinateFromString($chartCoordinates['cell']); + $chartCol = PHPExcel_Cell::columnIndexFromString($chartTL[0]); + if ($chartTL[1] > $rowMax) { + $rowMax = $chartTL[1]; + if ($chartCol > PHPExcel_Cell::columnIndexFromString($colMax)) { + $colMax = $chartTL[0]; + } + } + } + } + } + + foreach ($pSheet->getDrawingCollection() as $drawing) { + if ($drawing instanceof PHPExcel_Worksheet_Drawing) { + $imageTL = PHPExcel_Cell::coordinateFromString($drawing->getCoordinates()); + $imageCol = PHPExcel_Cell::columnIndexFromString($imageTL[0]); + if ($imageTL[1] > $rowMax) { + $rowMax = $imageTL[1]; + if ($imageCol > PHPExcel_Cell::columnIndexFromString($colMax)) { + $colMax = $imageTL[0]; + } + } + } + } + $html = ''; + $colMax++; + while ($row < $rowMax) { + $html .= '<tr>'; + for ($col = 'A'; $col != $colMax; ++$col) { + $html .= '<td>'; + $html .= $this->_writeImageInCell($pSheet, $col.$row); + if ($this->_includeCharts) { + $html .= $this->_writeChartInCell($pSheet, $col.$row); + } + $html .= '</td>'; + } + ++$row; + $html .= '</tr>'; + } + return $html; + } + + + /** + * Generate image tag in cell + * + * @param PHPExcel_Worksheet $pSheet PHPExcel_Worksheet + * @param string $coordinates Cell coordinates + * @return string + * @throws PHPExcel_Writer_Exception + */ + private function _writeImageInCell(PHPExcel_Worksheet $pSheet, $coordinates) { + // Construct HTML + $html = ''; + + // Write images + foreach ($pSheet->getDrawingCollection() as $drawing) { + if ($drawing instanceof PHPExcel_Worksheet_Drawing) { + if ($drawing->getCoordinates() == $coordinates) { + $filename = $drawing->getPath(); + + // Strip off eventual '.' + if (substr($filename, 0, 1) == '.') { + $filename = substr($filename, 1); + } + + // Prepend images root + $filename = $this->getImagesRoot() . $filename; + + // Strip off eventual '.' + if (substr($filename, 0, 1) == '.' && substr($filename, 0, 2) != './') { + $filename = substr($filename, 1); + } + + // Convert UTF8 data to PCDATA + $filename = htmlspecialchars($filename); + + $html .= PHP_EOL; + if ((!$this->_embedImages) || ($this->_isPdf)) { + $imageData = $filename; + } else { + $imageDetails = getimagesize($filename); + if ($fp = fopen($filename,"rb", 0)) { + $picture = fread($fp,filesize($filename)); + fclose($fp); + // base64 encode the binary data, then break it + // into chunks according to RFC 2045 semantics + $base64 = chunk_split(base64_encode($picture)); + $imageData = 'data:'.$imageDetails['mime'].';base64,' . $base64; + } else { + $imageData = $filename; + } + } + + $html .= '<div style="position: relative;">'; + $html .= '<img style="position: absolute; z-index: 1; left: ' . + $drawing->getOffsetX() . 'px; top: ' . $drawing->getOffsetY() . 'px; width: ' . + $drawing->getWidth() . 'px; height: ' . $drawing->getHeight() . 'px;" src="' . + $imageData . '" border="0" />'; + $html .= '</div>'; + } + } + } + + // Return + return $html; + } + + /** + * Generate chart tag in cell + * + * @param PHPExcel_Worksheet $pSheet PHPExcel_Worksheet + * @param string $coordinates Cell coordinates + * @return string + * @throws PHPExcel_Writer_Exception + */ + private function _writeChartInCell(PHPExcel_Worksheet $pSheet, $coordinates) { + // Construct HTML + $html = ''; + + // Write charts + foreach ($pSheet->getChartCollection() as $chart) { + if ($chart instanceof PHPExcel_Chart) { + $chartCoordinates = $chart->getTopLeftPosition(); + if ($chartCoordinates['cell'] == $coordinates) { + $chartFileName = PHPExcel_Shared_File::sys_get_temp_dir().'/'.uniqid().'.png'; + if (!$chart->render($chartFileName)) { + return; + } + + $html .= PHP_EOL; + $imageDetails = getimagesize($chartFileName); + if ($fp = fopen($chartFileName,"rb", 0)) { + $picture = fread($fp,filesize($chartFileName)); + fclose($fp); + // base64 encode the binary data, then break it + // into chunks according to RFC 2045 semantics + $base64 = chunk_split(base64_encode($picture)); + $imageData = 'data:'.$imageDetails['mime'].';base64,' . $base64; + + $html .= '<div style="position: relative;">'; + $html .= '<img style="position: absolute; z-index: 1; left: ' . $chartCoordinates['xOffset'] . 'px; top: ' . $chartCoordinates['yOffset'] . 'px; width: ' . $imageDetails[0] . 'px; height: ' . $imageDetails[1] . 'px;" src="' . $imageData . '" border="0" />' . PHP_EOL; + $html .= '</div>'; + + unlink($chartFileName); + } + } + } + } + + // Return + return $html; + } + + /** + * Generate CSS styles + * + * @param boolean $generateSurroundingHTML Generate surrounding HTML tags? (<style> and </style>) + * @return string + * @throws PHPExcel_Writer_Exception + */ + public function generateStyles($generateSurroundingHTML = true) { + // PHPExcel object known? + if (is_null($this->_phpExcel)) { + throw new PHPExcel_Writer_Exception('Internal PHPExcel object not set to an instance of an object.'); + } + + // Build CSS + $css = $this->buildCSS($generateSurroundingHTML); + + // Construct HTML + $html = ''; + + // Start styles + if ($generateSurroundingHTML) { + $html .= ' <style type="text/css">' . PHP_EOL; + $html .= ' html { ' . $this->_assembleCSS($css['html']) . ' }' . PHP_EOL; + } + + // Write all other styles + foreach ($css as $styleName => $styleDefinition) { + if ($styleName != 'html') { + $html .= ' ' . $styleName . ' { ' . $this->_assembleCSS($styleDefinition) . ' }' . PHP_EOL; + } + } + + // End styles + if ($generateSurroundingHTML) { + $html .= ' </style>' . PHP_EOL; + } + + // Return + return $html; + } + + /** + * Build CSS styles + * + * @param boolean $generateSurroundingHTML Generate surrounding HTML style? (html { }) + * @return array + * @throws PHPExcel_Writer_Exception + */ + public function buildCSS($generateSurroundingHTML = true) { + // PHPExcel object known? + if (is_null($this->_phpExcel)) { + throw new PHPExcel_Writer_Exception('Internal PHPExcel object not set to an instance of an object.'); + } + + // Cached? + if (!is_null($this->_cssStyles)) { + return $this->_cssStyles; + } + + // Ensure that spans have been calculated + if (!$this->_spansAreCalculated) { + $this->_calculateSpans(); + } + + // Construct CSS + $css = array(); + + // Start styles + if ($generateSurroundingHTML) { + // html { } + $css['html']['font-family'] = 'Calibri, Arial, Helvetica, sans-serif'; + $css['html']['font-size'] = '11pt'; + $css['html']['background-color'] = 'white'; + } + + + // table { } + $css['table']['border-collapse'] = 'collapse'; + if (!$this->_isPdf) { + $css['table']['page-break-after'] = 'always'; + } + + // .gridlines td { } + $css['.gridlines td']['border'] = '1px dotted black'; + + // .b {} + $css['.b']['text-align'] = 'center'; // BOOL + + // .e {} + $css['.e']['text-align'] = 'center'; // ERROR + + // .f {} + $css['.f']['text-align'] = 'right'; // FORMULA + + // .inlineStr {} + $css['.inlineStr']['text-align'] = 'left'; // INLINE + + // .n {} + $css['.n']['text-align'] = 'right'; // NUMERIC + + // .s {} + $css['.s']['text-align'] = 'left'; // STRING + + // Calculate cell style hashes + foreach ($this->_phpExcel->getCellXfCollection() as $index => $style) { + $css['td.style' . $index] = $this->_createCSSStyle( $style ); + } + + // Fetch sheets + $sheets = array(); + if (is_null($this->_sheetIndex)) { + $sheets = $this->_phpExcel->getAllSheets(); + } else { + $sheets[] = $this->_phpExcel->getSheet($this->_sheetIndex); + } + + // Build styles per sheet + foreach ($sheets as $sheet) { + // Calculate hash code + $sheetIndex = $sheet->getParent()->getIndex($sheet); + + // Build styles + // Calculate column widths + $sheet->calculateColumnWidths(); + + // col elements, initialize + $highestColumnIndex = PHPExcel_Cell::columnIndexFromString($sheet->getHighestColumn()) - 1; + $column = -1; + while($column++ < $highestColumnIndex) { + $this->_columnWidths[$sheetIndex][$column] = 42; // approximation + $css['table.sheet' . $sheetIndex . ' col.col' . $column]['width'] = '42pt'; + } + + // col elements, loop through columnDimensions and set width + foreach ($sheet->getColumnDimensions() as $columnDimension) { + if (($width = PHPExcel_Shared_Drawing::cellDimensionToPixels($columnDimension->getWidth(), $this->_defaultFont)) >= 0) { + $width = PHPExcel_Shared_Drawing::pixelsToPoints($width); + $column = PHPExcel_Cell::columnIndexFromString($columnDimension->getColumnIndex()) - 1; + $this->_columnWidths[$sheetIndex][$column] = $width; + $css['table.sheet' . $sheetIndex . ' col.col' . $column]['width'] = $width . 'pt'; + + if ($columnDimension->getVisible() === false) { + $css['table.sheet' . $sheetIndex . ' col.col' . $column]['visibility'] = 'collapse'; + $css['table.sheet' . $sheetIndex . ' col.col' . $column]['*display'] = 'none'; // target IE6+7 + } + } + } + + // Default row height + $rowDimension = $sheet->getDefaultRowDimension(); + + // table.sheetN tr { } + $css['table.sheet' . $sheetIndex . ' tr'] = array(); + + if ($rowDimension->getRowHeight() == -1) { + $pt_height = PHPExcel_Shared_Font::getDefaultRowHeightByFont($this->_phpExcel->getDefaultStyle()->getFont()); + } else { + $pt_height = $rowDimension->getRowHeight(); + } + $css['table.sheet' . $sheetIndex . ' tr']['height'] = $pt_height . 'pt'; + if ($rowDimension->getVisible() === false) { + $css['table.sheet' . $sheetIndex . ' tr']['display'] = 'none'; + $css['table.sheet' . $sheetIndex . ' tr']['visibility'] = 'hidden'; + } + + // Calculate row heights + foreach ($sheet->getRowDimensions() as $rowDimension) { + $row = $rowDimension->getRowIndex() - 1; + + // table.sheetN tr.rowYYYYYY { } + $css['table.sheet' . $sheetIndex . ' tr.row' . $row] = array(); + + if ($rowDimension->getRowHeight() == -1) { + $pt_height = PHPExcel_Shared_Font::getDefaultRowHeightByFont($this->_phpExcel->getDefaultStyle()->getFont()); + } else { + $pt_height = $rowDimension->getRowHeight(); + } + $css['table.sheet' . $sheetIndex . ' tr.row' . $row]['height'] = $pt_height . 'pt'; + if ($rowDimension->getVisible() === false) { + $css['table.sheet' . $sheetIndex . ' tr.row' . $row]['display'] = 'none'; + $css['table.sheet' . $sheetIndex . ' tr.row' . $row]['visibility'] = 'hidden'; + } + } + } + + // Cache + if (is_null($this->_cssStyles)) { + $this->_cssStyles = $css; + } + + // Return + return $css; + } + + /** + * Create CSS style + * + * @param PHPExcel_Style $pStyle PHPExcel_Style + * @return array + */ + private function _createCSSStyle(PHPExcel_Style $pStyle) { + // Construct CSS + $css = ''; + + // Create CSS + $css = array_merge( + $this->_createCSSStyleAlignment($pStyle->getAlignment()) + , $this->_createCSSStyleBorders($pStyle->getBorders()) + , $this->_createCSSStyleFont($pStyle->getFont()) + , $this->_createCSSStyleFill($pStyle->getFill()) + ); + + // Return + return $css; + } + + /** + * Create CSS style (PHPExcel_Style_Alignment) + * + * @param PHPExcel_Style_Alignment $pStyle PHPExcel_Style_Alignment + * @return array + */ + private function _createCSSStyleAlignment(PHPExcel_Style_Alignment $pStyle) { + // Construct CSS + $css = array(); + + // Create CSS + $css['vertical-align'] = $this->_mapVAlign($pStyle->getVertical()); + if ($textAlign = $this->_mapHAlign($pStyle->getHorizontal())) { + $css['text-align'] = $textAlign; + if(in_array($textAlign,array('left','right'))) + $css['padding-'.$textAlign] = (string)((int)$pStyle->getIndent() * 9).'px'; + } + + // Return + return $css; + } + + /** + * Create CSS style (PHPExcel_Style_Font) + * + * @param PHPExcel_Style_Font $pStyle PHPExcel_Style_Font + * @return array + */ + private function _createCSSStyleFont(PHPExcel_Style_Font $pStyle) { + // Construct CSS + $css = array(); + + // Create CSS + if ($pStyle->getBold()) { + $css['font-weight'] = 'bold'; + } + if ($pStyle->getUnderline() != PHPExcel_Style_Font::UNDERLINE_NONE && $pStyle->getStrikethrough()) { + $css['text-decoration'] = 'underline line-through'; + } else if ($pStyle->getUnderline() != PHPExcel_Style_Font::UNDERLINE_NONE) { + $css['text-decoration'] = 'underline'; + } else if ($pStyle->getStrikethrough()) { + $css['text-decoration'] = 'line-through'; + } + if ($pStyle->getItalic()) { + $css['font-style'] = 'italic'; + } + + $css['color'] = '#' . $pStyle->getColor()->getRGB(); + $css['font-family'] = '\'' . $pStyle->getName() . '\''; + $css['font-size'] = $pStyle->getSize() . 'pt'; + + // Return + return $css; + } + + /** + * Create CSS style (PHPExcel_Style_Borders) + * + * @param PHPExcel_Style_Borders $pStyle PHPExcel_Style_Borders + * @return array + */ + private function _createCSSStyleBorders(PHPExcel_Style_Borders $pStyle) { + // Construct CSS + $css = array(); + + // Create CSS + $css['border-bottom'] = $this->_createCSSStyleBorder($pStyle->getBottom()); + $css['border-top'] = $this->_createCSSStyleBorder($pStyle->getTop()); + $css['border-left'] = $this->_createCSSStyleBorder($pStyle->getLeft()); + $css['border-right'] = $this->_createCSSStyleBorder($pStyle->getRight()); + + // Return + return $css; + } + + /** + * Create CSS style (PHPExcel_Style_Border) + * + * @param PHPExcel_Style_Border $pStyle PHPExcel_Style_Border + * @return string + */ + private function _createCSSStyleBorder(PHPExcel_Style_Border $pStyle) { + // Create CSS +// $css = $this->_mapBorderStyle($pStyle->getBorderStyle()) . ' #' . $pStyle->getColor()->getRGB(); + // Create CSS - add !important to non-none border styles for merged cells + $borderStyle = $this->_mapBorderStyle($pStyle->getBorderStyle()); + $css = $borderStyle . ' #' . $pStyle->getColor()->getRGB() . (($borderStyle == 'none') ? '' : ' !important'); + + // Return + return $css; + } + + /** + * Create CSS style (PHPExcel_Style_Fill) + * + * @param PHPExcel_Style_Fill $pStyle PHPExcel_Style_Fill + * @return array + */ + private function _createCSSStyleFill(PHPExcel_Style_Fill $pStyle) { + // Construct HTML + $css = array(); + + // Create CSS + $value = $pStyle->getFillType() == PHPExcel_Style_Fill::FILL_NONE ? + 'white' : '#' . $pStyle->getStartColor()->getRGB(); + $css['background-color'] = $value; + + // Return + return $css; + } + + /** + * Generate HTML footer + */ + public function generateHTMLFooter() { + // Construct HTML + $html = ''; + $html .= ' </body>' . PHP_EOL; + $html .= '</html>' . PHP_EOL; + + // Return + return $html; + } + + /** + * Generate table header + * + * @param PHPExcel_Worksheet $pSheet The worksheet for the table we are writing + * @return string + * @throws PHPExcel_Writer_Exception + */ + private function _generateTableHeader($pSheet) { + $sheetIndex = $pSheet->getParent()->getIndex($pSheet); + + // Construct HTML + $html = ''; + $html .= $this->_setMargins($pSheet); + + if (!$this->_useInlineCss) { + $gridlines = $pSheet->getShowGridlines() ? ' gridlines' : ''; + $html .= ' <table border="0" cellpadding="0" cellspacing="0" id="sheet' . $sheetIndex . '" class="sheet' . $sheetIndex . $gridlines . '">' . PHP_EOL; + } else { + $style = isset($this->_cssStyles['table']) ? + $this->_assembleCSS($this->_cssStyles['table']) : ''; + + if ($this->_isPdf && $pSheet->getShowGridlines()) { + $html .= ' <table border="1" cellpadding="1" id="sheet' . $sheetIndex . '" cellspacing="1" style="' . $style . '">' . PHP_EOL; + } else { + $html .= ' <table border="0" cellpadding="1" id="sheet' . $sheetIndex . '" cellspacing="0" style="' . $style . '">' . PHP_EOL; + } + } + + // Write <col> elements + $highestColumnIndex = PHPExcel_Cell::columnIndexFromString($pSheet->getHighestColumn()) - 1; + $i = -1; + while($i++ < $highestColumnIndex) { + if (!$this->_isPdf) { + if (!$this->_useInlineCss) { + $html .= ' <col class="col' . $i . '">' . PHP_EOL; + } else { + $style = isset($this->_cssStyles['table.sheet' . $sheetIndex . ' col.col' . $i]) ? + $this->_assembleCSS($this->_cssStyles['table.sheet' . $sheetIndex . ' col.col' . $i]) : ''; + $html .= ' <col style="' . $style . '">' . PHP_EOL; + } + } + } + + // Return + return $html; + } + + /** + * Generate table footer + * + * @throws PHPExcel_Writer_Exception + */ + private function _generateTableFooter() { + // Construct HTML + $html = ''; + $html .= ' </table>' . PHP_EOL; + + // Return + return $html; + } + + /** + * Generate row + * + * @param PHPExcel_Worksheet $pSheet PHPExcel_Worksheet + * @param array $pValues Array containing cells in a row + * @param int $pRow Row number (0-based) + * @return string + * @throws PHPExcel_Writer_Exception + */ + private function _generateRow(PHPExcel_Worksheet $pSheet, $pValues = null, $pRow = 0) { + if (is_array($pValues)) { + // Construct HTML + $html = ''; + + // Sheet index + $sheetIndex = $pSheet->getParent()->getIndex($pSheet); + + // DomPDF and breaks + if ($this->_isPdf && count($pSheet->getBreaks()) > 0) { + $breaks = $pSheet->getBreaks(); + + // check if a break is needed before this row + if (isset($breaks['A' . $pRow])) { + // close table: </table> + $html .= $this->_generateTableFooter(); + + // insert page break + $html .= '<div style="page-break-before:always" />'; + + // open table again: <table> + <col> etc. + $html .= $this->_generateTableHeader($pSheet); + } + } + + // Write row start + if (!$this->_useInlineCss) { + $html .= ' <tr class="row' . $pRow . '">' . PHP_EOL; + } else { + $style = isset($this->_cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $pRow]) + ? $this->_assembleCSS($this->_cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $pRow]) : ''; + + $html .= ' <tr style="' . $style . '">' . PHP_EOL; + } + + // Write cells + $colNum = 0; + foreach ($pValues as $cellAddress) { + $cell = ($cellAddress > '') ? $pSheet->getCell($cellAddress) : ''; + $coordinate = PHPExcel_Cell::stringFromColumnIndex($colNum) . ($pRow + 1); + if (!$this->_useInlineCss) { + $cssClass = ''; + $cssClass = 'column' . $colNum; + } else { + $cssClass = array(); + if (isset($this->_cssStyles['table.sheet' . $sheetIndex . ' td.column' . $colNum])) { + $this->_cssStyles['table.sheet' . $sheetIndex . ' td.column' . $colNum]; + } + } + $colSpan = 1; + $rowSpan = 1; + + // initialize + $cellData = '&nbsp;'; + + // PHPExcel_Cell + if ($cell instanceof PHPExcel_Cell) { + $cellData = ''; + if (is_null($cell->getParent())) { + $cell->attach($pSheet); + } + // Value + if ($cell->getValue() instanceof PHPExcel_RichText) { + // Loop through rich text elements + $elements = $cell->getValue()->getRichTextElements(); + foreach ($elements as $element) { + // Rich text start? + if ($element instanceof PHPExcel_RichText_Run) { + $cellData .= '<span style="' . $this->_assembleCSS($this->_createCSSStyleFont($element->getFont())) . '">'; + + if ($element->getFont()->getSuperScript()) { + $cellData .= '<sup>'; + } else if ($element->getFont()->getSubScript()) { + $cellData .= '<sub>'; + } + } + + // Convert UTF8 data to PCDATA + $cellText = $element->getText(); + $cellData .= htmlspecialchars($cellText); + + if ($element instanceof PHPExcel_RichText_Run) { + if ($element->getFont()->getSuperScript()) { + $cellData .= '</sup>'; + } else if ($element->getFont()->getSubScript()) { + $cellData .= '</sub>'; + } + + $cellData .= '</span>'; + } + } + } else { + if ($this->_preCalculateFormulas) { + $cellData = PHPExcel_Style_NumberFormat::toFormattedString( + $cell->getCalculatedValue(), + $pSheet->getParent()->getCellXfByIndex( $cell->getXfIndex() )->getNumberFormat()->getFormatCode(), + array($this, 'formatColor') + ); + } else { + $cellData = PHPExcel_Style_NumberFormat::ToFormattedString( + $cell->getValue(), + $pSheet->getParent()->getCellXfByIndex( $cell->getXfIndex() )->getNumberFormat()->getFormatCode(), + array($this, 'formatColor') + ); + } + $cellData = htmlspecialchars($cellData); + if ($pSheet->getParent()->getCellXfByIndex( $cell->getXfIndex() )->getFont()->getSuperScript()) { + $cellData = '<sup>'.$cellData.'</sup>'; + } elseif ($pSheet->getParent()->getCellXfByIndex( $cell->getXfIndex() )->getFont()->getSubScript()) { + $cellData = '<sub>'.$cellData.'</sub>'; + } + } + + // Converts the cell content so that spaces occuring at beginning of each new line are replaced by &nbsp; + // Example: " Hello\n to the world" is converted to "&nbsp;&nbsp;Hello\n&nbsp;to the world" + $cellData = preg_replace("/(?m)(?:^|\\G) /", '&nbsp;', $cellData); + + // convert newline "\n" to '<br>' + $cellData = nl2br($cellData); + + // Extend CSS class? + if (!$this->_useInlineCss) { + $cssClass .= ' style' . $cell->getXfIndex(); + $cssClass .= ' ' . $cell->getDataType(); + } else { + if (isset($this->_cssStyles['td.style' . $cell->getXfIndex()])) { + $cssClass = array_merge($cssClass, $this->_cssStyles['td.style' . $cell->getXfIndex()]); + } + + // General horizontal alignment: Actual horizontal alignment depends on dataType + $sharedStyle = $pSheet->getParent()->getCellXfByIndex( $cell->getXfIndex() ); + if ($sharedStyle->getAlignment()->getHorizontal() == PHPExcel_Style_Alignment::HORIZONTAL_GENERAL + && isset($this->_cssStyles['.' . $cell->getDataType()]['text-align'])) + { + $cssClass['text-align'] = $this->_cssStyles['.' . $cell->getDataType()]['text-align']; + } + } + } + + // Hyperlink? + if ($pSheet->hyperlinkExists($coordinate) && !$pSheet->getHyperlink($coordinate)->isInternal()) { + $cellData = '<a href="' . htmlspecialchars($pSheet->getHyperlink($coordinate)->getUrl()) . '" title="' . htmlspecialchars($pSheet->getHyperlink($coordinate)->getTooltip()) . '">' . $cellData . '</a>'; + } + + // Should the cell be written or is it swallowed by a rowspan or colspan? + $writeCell = ! ( isset($this->_isSpannedCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum]) + && $this->_isSpannedCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum] ); + + // Colspan and Rowspan + $colspan = 1; + $rowspan = 1; + if (isset($this->_isBaseCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum])) { + $spans = $this->_isBaseCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum]; + $rowSpan = $spans['rowspan']; + $colSpan = $spans['colspan']; + + // Also apply style from last cell in merge to fix borders - + // relies on !important for non-none border declarations in _createCSSStyleBorder + $endCellCoord = PHPExcel_Cell::stringFromColumnIndex($colNum + $colSpan - 1) . ($pRow + $rowSpan); + if (!$this->_useInlineCss) { + $cssClass .= ' style' . $pSheet->getCell($endCellCoord)->getXfIndex(); + } + } + + // Write + if ($writeCell) { + // Column start + $html .= ' <td'; + if (!$this->_useInlineCss) { + $html .= ' class="' . $cssClass . '"'; + } else { + //** Necessary redundant code for the sake of PHPExcel_Writer_PDF ** + // We must explicitly write the width of the <td> element because TCPDF + // does not recognize e.g. <col style="width:42pt"> + $width = 0; + $i = $colNum - 1; + $e = $colNum + $colSpan - 1; + while($i++ < $e) { + if (isset($this->_columnWidths[$sheetIndex][$i])) { + $width += $this->_columnWidths[$sheetIndex][$i]; + } + } + $cssClass['width'] = $width . 'pt'; + + // We must also explicitly write the height of the <td> element because TCPDF + // does not recognize e.g. <tr style="height:50pt"> + if (isset($this->_cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $pRow]['height'])) { + $height = $this->_cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $pRow]['height']; + $cssClass['height'] = $height; + } + //** end of redundant code ** + + $html .= ' style="' . $this->_assembleCSS($cssClass) . '"'; + } + if ($colSpan > 1) { + $html .= ' colspan="' . $colSpan . '"'; + } + if ($rowSpan > 1) { + $html .= ' rowspan="' . $rowSpan . '"'; + } + $html .= '>'; + + // Image? + $html .= $this->_writeImageInCell($pSheet, $coordinate); + + // Chart? + if ($this->_includeCharts) { + $html .= $this->_writeChartInCell($pSheet, $coordinate); + } + + // Cell data + $html .= $cellData; + + // Column end + $html .= '</td>' . PHP_EOL; + } + + // Next column + ++$colNum; + } + + // Write row end + $html .= ' </tr>' . PHP_EOL; + + // Return + return $html; + } else { + throw new PHPExcel_Writer_Exception("Invalid parameters passed."); + } + } + + /** + * Takes array where of CSS properties / values and converts to CSS string + * + * @param array + * @return string + */ + private function _assembleCSS($pValue = array()) + { + $pairs = array(); + foreach ($pValue as $property => $value) { + $pairs[] = $property . ':' . $value; + } + $string = implode('; ', $pairs); + + return $string; + } + + /** + * Get images root + * + * @return string + */ + public function getImagesRoot() { + return $this->_imagesRoot; + } + + /** + * Set images root + * + * @param string $pValue + * @return PHPExcel_Writer_HTML + */ + public function setImagesRoot($pValue = '.') { + $this->_imagesRoot = $pValue; + return $this; + } + + /** + * Get embed images + * + * @return boolean + */ + public function getEmbedImages() { + return $this->_embedImages; + } + + /** + * Set embed images + * + * @param boolean $pValue + * @return PHPExcel_Writer_HTML + */ + public function setEmbedImages($pValue = '.') { + $this->_embedImages = $pValue; + return $this; + } + + /** + * Get use inline CSS? + * + * @return boolean + */ + public function getUseInlineCss() { + return $this->_useInlineCss; + } + + /** + * Set use inline CSS? + * + * @param boolean $pValue + * @return PHPExcel_Writer_HTML + */ + public function setUseInlineCss($pValue = false) { + $this->_useInlineCss = $pValue; + return $this; + } + + /** + * Add color to formatted string as inline style + * + * @param string $pValue Plain formatted value without color + * @param string $pFormat Format code + * @return string + */ + public function formatColor($pValue, $pFormat) + { + // Color information, e.g. [Red] is always at the beginning + $color = null; // initialize + $matches = array(); + + $color_regex = '/^\\[[a-zA-Z]+\\]/'; + if (preg_match($color_regex, $pFormat, $matches)) { + $color = str_replace('[', '', $matches[0]); + $color = str_replace(']', '', $color); + $color = strtolower($color); + } + + // convert to PCDATA + $value = htmlspecialchars($pValue); + + // color span tag + if ($color !== null) { + $value = '<span style="color:' . $color . '">' . $value . '</span>'; + } + + return $value; + } + + /** + * Calculate information about HTML colspan and rowspan which is not always the same as Excel's + */ + private function _calculateSpans() + { + // Identify all cells that should be omitted in HTML due to cell merge. + // In HTML only the upper-left cell should be written and it should have + // appropriate rowspan / colspan attribute + $sheetIndexes = $this->_sheetIndex !== null ? + array($this->_sheetIndex) : range(0, $this->_phpExcel->getSheetCount() - 1); + + foreach ($sheetIndexes as $sheetIndex) { + $sheet = $this->_phpExcel->getSheet($sheetIndex); + + $candidateSpannedRow = array(); + + // loop through all Excel merged cells + foreach ($sheet->getMergeCells() as $cells) { + list($cells, ) = PHPExcel_Cell::splitRange($cells); + $first = $cells[0]; + $last = $cells[1]; + + list($fc, $fr) = PHPExcel_Cell::coordinateFromString($first); + $fc = PHPExcel_Cell::columnIndexFromString($fc) - 1; + + list($lc, $lr) = PHPExcel_Cell::coordinateFromString($last); + $lc = PHPExcel_Cell::columnIndexFromString($lc) - 1; + + // loop through the individual cells in the individual merge + $r = $fr - 1; + while($r++ < $lr) { + // also, flag this row as a HTML row that is candidate to be omitted + $candidateSpannedRow[$r] = $r; + + $c = $fc - 1; + while($c++ < $lc) { + if ( !($c == $fc && $r == $fr) ) { + // not the upper-left cell (should not be written in HTML) + $this->_isSpannedCell[$sheetIndex][$r][$c] = array( + 'baseCell' => array($fr, $fc), + ); + } else { + // upper-left is the base cell that should hold the colspan/rowspan attribute + $this->_isBaseCell[$sheetIndex][$r][$c] = array( + 'xlrowspan' => $lr - $fr + 1, // Excel rowspan + 'rowspan' => $lr - $fr + 1, // HTML rowspan, value may change + 'xlcolspan' => $lc - $fc + 1, // Excel colspan + 'colspan' => $lc - $fc + 1, // HTML colspan, value may change + ); + } + } + } + } + + // Identify which rows should be omitted in HTML. These are the rows where all the cells + // participate in a merge and the where base cells are somewhere above. + $countColumns = PHPExcel_Cell::columnIndexFromString($sheet->getHighestColumn()); + foreach ($candidateSpannedRow as $rowIndex) { + if (isset($this->_isSpannedCell[$sheetIndex][$rowIndex])) { + if (count($this->_isSpannedCell[$sheetIndex][$rowIndex]) == $countColumns) { + $this->_isSpannedRow[$sheetIndex][$rowIndex] = $rowIndex; + }; + } + } + + // For each of the omitted rows we found above, the affected rowspans should be subtracted by 1 + if ( isset($this->_isSpannedRow[$sheetIndex]) ) { + foreach ($this->_isSpannedRow[$sheetIndex] as $rowIndex) { + $adjustedBaseCells = array(); + $c = -1; + $e = $countColumns - 1; + while($c++ < $e) { + $baseCell = $this->_isSpannedCell[$sheetIndex][$rowIndex][$c]['baseCell']; + + if ( !in_array($baseCell, $adjustedBaseCells) ) { + // subtract rowspan by 1 + --$this->_isBaseCell[$sheetIndex][ $baseCell[0] ][ $baseCell[1] ]['rowspan']; + $adjustedBaseCells[] = $baseCell; + } + } + } + } + + // TODO: Same for columns + } + + // We have calculated the spans + $this->_spansAreCalculated = true; + } + + private function _setMargins(PHPExcel_Worksheet $pSheet) { + $htmlPage = '@page { '; + $htmlBody = 'body { '; + + $left = PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getLeft()) . 'in; '; + $htmlPage .= 'left-margin: ' . $left; + $htmlBody .= 'left-margin: ' . $left; + $right = PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getRight()) . 'in; '; + $htmlPage .= 'right-margin: ' . $right; + $htmlBody .= 'right-margin: ' . $right; + $top = PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getTop()) . 'in; '; + $htmlPage .= 'top-margin: ' . $top; + $htmlBody .= 'top-margin: ' . $top; + $bottom = PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getBottom()) . 'in; '; + $htmlPage .= 'bottom-margin: ' . $bottom; + $htmlBody .= 'bottom-margin: ' . $bottom; + + $htmlPage .= "}\n"; + $htmlBody .= "}\n"; + + return "<style>\n" . $htmlPage . $htmlBody . "</style>\n"; + } + +} diff --git a/lib/phpexcel/PHPExcel/Writer/IWriter.php b/lib/phpexcel/PHPExcel/Writer/IWriter.php new file mode 100644 index 0000000..6974c93 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Writer/IWriter.php @@ -0,0 +1,46 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Writer_IWriter + * + * @category PHPExcel + * @package PHPExcel_Writer + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +interface PHPExcel_Writer_IWriter +{ + /** + * Save PHPExcel to file + * + * @param string $pFilename Name of the file to save + * @throws PHPExcel_Writer_Exception + */ + public function save($pFilename = NULL); + +} diff --git a/lib/phpexcel/PHPExcel/Writer/PDF.php b/lib/phpexcel/PHPExcel/Writer/PDF.php new file mode 100644 index 0000000..65fb50e --- /dev/null +++ b/lib/phpexcel/PHPExcel/Writer/PDF.php @@ -0,0 +1,90 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_PDF + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Writer_PDF + * + * @category PHPExcel + * @package PHPExcel_Writer_PDF + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_PDF +{ + + /** + * The wrapper for the requested PDF rendering engine + * + * @var PHPExcel_Writer_PDF_Core + */ + private $_renderer = NULL; + + /** + * Instantiate a new renderer of the configured type within this container class + * + * @param PHPExcel $phpExcel PHPExcel object + * @throws PHPExcel_Writer_Exception when PDF library is not configured + */ + public function __construct(PHPExcel $phpExcel) + { + $pdfLibraryName = PHPExcel_Settings::getPdfRendererName(); + if (is_null($pdfLibraryName)) { + throw new PHPExcel_Writer_Exception("PDF Rendering library has not been defined."); + } + + $pdfLibraryPath = PHPExcel_Settings::getPdfRendererPath(); + if (is_null($pdfLibraryName)) { + throw new PHPExcel_Writer_Exception("PDF Rendering library path has not been defined."); + } + $includePath = str_replace('\\', '/', get_include_path()); + $rendererPath = str_replace('\\', '/', $pdfLibraryPath); + if (strpos($rendererPath, $includePath) === false) { + set_include_path(get_include_path() . PATH_SEPARATOR . $pdfLibraryPath); + } + + $rendererName = 'PHPExcel_Writer_PDF_' . $pdfLibraryName; + $this->_renderer = new $rendererName($phpExcel); + } + + + /** + * Magic method to handle direct calls to the configured PDF renderer wrapper class. + * + * @param string $name Renderer library method name + * @param mixed[] $arguments Array of arguments to pass to the renderer method + * @return mixed Returned data from the PDF renderer wrapper method + */ + public function __call($name, $arguments) + { + if ($this->_renderer === NULL) { + throw new PHPExcel_Writer_Exception("PDF Rendering library has not been defined."); + } + + return call_user_func_array(array($this->_renderer, $name), $arguments); + } + +} diff --git a/lib/phpexcel/PHPExcel/Writer/PDF/Core.php b/lib/phpexcel/PHPExcel/Writer/PDF/Core.php new file mode 100644 index 0000000..3b281f4 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Writer/PDF/Core.php @@ -0,0 +1,364 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_PDF + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Writer_PDF_Core + * + * @category PHPExcel + * @package PHPExcel_Writer_PDF + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +abstract class PHPExcel_Writer_PDF_Core extends PHPExcel_Writer_HTML +{ + /** + * Temporary storage directory + * + * @var string + */ + protected $_tempDir = ''; + + /** + * Font + * + * @var string + */ + protected $_font = 'freesans'; + + /** + * Orientation (Over-ride) + * + * @var string + */ + protected $_orientation = NULL; + + /** + * Paper size (Over-ride) + * + * @var int + */ + protected $_paperSize = NULL; + + + /** + * Temporary storage for Save Array Return type + * + * @var string + */ + private $_saveArrayReturnType; + + /** + * Paper Sizes xRef List + * + * @var array + */ + protected static $_paperSizes = array( + PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER + => 'LETTER', // (8.5 in. by 11 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER_SMALL + => 'LETTER', // (8.5 in. by 11 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_TABLOID + => array(792.00, 1224.00), // (11 in. by 17 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_LEDGER + => array(1224.00, 792.00), // (17 in. by 11 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_LEGAL + => 'LEGAL', // (8.5 in. by 14 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_STATEMENT + => array(396.00, 612.00), // (5.5 in. by 8.5 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_EXECUTIVE + => 'EXECUTIVE', // (7.25 in. by 10.5 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_A3 + => 'A3', // (297 mm by 420 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_A4 + => 'A4', // (210 mm by 297 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_A4_SMALL + => 'A4', // (210 mm by 297 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_A5 + => 'A5', // (148 mm by 210 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_B4 + => 'B4', // (250 mm by 353 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_B5 + => 'B5', // (176 mm by 250 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_FOLIO + => 'FOLIO', // (8.5 in. by 13 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_QUARTO + => array(609.45, 779.53), // (215 mm by 275 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_STANDARD_1 + => array(720.00, 1008.00), // (10 in. by 14 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_STANDARD_2 + => array(792.00, 1224.00), // (11 in. by 17 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_NOTE + => 'LETTER', // (8.5 in. by 11 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_NO9_ENVELOPE + => array(279.00, 639.00), // (3.875 in. by 8.875 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_NO10_ENVELOPE + => array(297.00, 684.00), // (4.125 in. by 9.5 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_NO11_ENVELOPE + => array(324.00, 747.00), // (4.5 in. by 10.375 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_NO12_ENVELOPE + => array(342.00, 792.00), // (4.75 in. by 11 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_NO14_ENVELOPE + => array(360.00, 828.00), // (5 in. by 11.5 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_C + => array(1224.00, 1584.00), // (17 in. by 22 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_D + => array(1584.00, 2448.00), // (22 in. by 34 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_E + => array(2448.00, 3168.00), // (34 in. by 44 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_DL_ENVELOPE + => array(311.81, 623.62), // (110 mm by 220 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_C5_ENVELOPE + => 'C5', // (162 mm by 229 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_C3_ENVELOPE + => 'C3', // (324 mm by 458 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_C4_ENVELOPE + => 'C4', // (229 mm by 324 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_C6_ENVELOPE + => 'C6', // (114 mm by 162 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_C65_ENVELOPE + => array(323.15, 649.13), // (114 mm by 229 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_B4_ENVELOPE + => 'B4', // (250 mm by 353 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_B5_ENVELOPE + => 'B5', // (176 mm by 250 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_B6_ENVELOPE + => array(498.90, 354.33), // (176 mm by 125 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_ITALY_ENVELOPE + => array(311.81, 651.97), // (110 mm by 230 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_MONARCH_ENVELOPE + => array(279.00, 540.00), // (3.875 in. by 7.5 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_6_3_4_ENVELOPE + => array(261.00, 468.00), // (3.625 in. by 6.5 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_US_STANDARD_FANFOLD + => array(1071.00, 792.00), // (14.875 in. by 11 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_GERMAN_STANDARD_FANFOLD + => array(612.00, 864.00), // (8.5 in. by 12 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_GERMAN_LEGAL_FANFOLD + => 'FOLIO', // (8.5 in. by 13 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_ISO_B4 + => 'B4', // (250 mm by 353 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_JAPANESE_DOUBLE_POSTCARD + => array(566.93, 419.53), // (200 mm by 148 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_STANDARD_PAPER_1 + => array(648.00, 792.00), // (9 in. by 11 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_STANDARD_PAPER_2 + => array(720.00, 792.00), // (10 in. by 11 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_STANDARD_PAPER_3 + => array(1080.00, 792.00), // (15 in. by 11 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_INVITE_ENVELOPE + => array(623.62, 623.62), // (220 mm by 220 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER_EXTRA_PAPER + => array(667.80, 864.00), // (9.275 in. by 12 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_LEGAL_EXTRA_PAPER + => array(667.80, 1080.00), // (9.275 in. by 15 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_TABLOID_EXTRA_PAPER + => array(841.68, 1296.00), // (11.69 in. by 18 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_A4_EXTRA_PAPER + => array(668.98, 912.76), // (236 mm by 322 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER_TRANSVERSE_PAPER + => array(595.80, 792.00), // (8.275 in. by 11 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_A4_TRANSVERSE_PAPER + => 'A4', // (210 mm by 297 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER_EXTRA_TRANSVERSE_PAPER + => array(667.80, 864.00), // (9.275 in. by 12 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_SUPERA_SUPERA_A4_PAPER + => array(643.46, 1009.13), // (227 mm by 356 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_SUPERB_SUPERB_A3_PAPER + => array(864.57, 1380.47), // (305 mm by 487 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER_PLUS_PAPER + => array(612.00, 913.68), // (8.5 in. by 12.69 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_A4_PLUS_PAPER + => array(595.28, 935.43), // (210 mm by 330 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_A5_TRANSVERSE_PAPER + => 'A5', // (148 mm by 210 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_JIS_B5_TRANSVERSE_PAPER + => array(515.91, 728.50), // (182 mm by 257 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_A3_EXTRA_PAPER + => array(912.76, 1261.42), // (322 mm by 445 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_A5_EXTRA_PAPER + => array(493.23, 666.14), // (174 mm by 235 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_ISO_B5_EXTRA_PAPER + => array(569.76, 782.36), // (201 mm by 276 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_A2_PAPER + => 'A2', // (420 mm by 594 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_A3_TRANSVERSE_PAPER + => 'A3', // (297 mm by 420 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_A3_EXTRA_TRANSVERSE_PAPER + => array(912.76, 1261.42) // (322 mm by 445 mm) + ); + + /** + * Create a new PHPExcel_Writer_PDF + * + * @param PHPExcel $phpExcel PHPExcel object + */ + public function __construct(PHPExcel $phpExcel) + { + parent::__construct($phpExcel); + $this->setUseInlineCss(TRUE); + $this->_tempDir = PHPExcel_Shared_File::sys_get_temp_dir(); + } + + /** + * Get Font + * + * @return string + */ + public function getFont() + { + return $this->_font; + } + + /** + * Set font. Examples: + * 'arialunicid0-chinese-simplified' + * 'arialunicid0-chinese-traditional' + * 'arialunicid0-korean' + * 'arialunicid0-japanese' + * + * @param string $fontName + */ + public function setFont($fontName) + { + $this->_font = $fontName; + return $this; + } + + /** + * Get Paper Size + * + * @return int + */ + public function getPaperSize() + { + return $this->_paperSize; + } + + /** + * Set Paper Size + * + * @param string $pValue Paper size + * @return PHPExcel_Writer_PDF + */ + public function setPaperSize($pValue = PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER) + { + $this->_paperSize = $pValue; + return $this; + } + + /** + * Get Orientation + * + * @return string + */ + public function getOrientation() + { + return $this->_orientation; + } + + /** + * Set Orientation + * + * @param string $pValue Page orientation + * @return PHPExcel_Writer_PDF + */ + public function setOrientation($pValue = PHPExcel_Worksheet_PageSetup::ORIENTATION_DEFAULT) + { + $this->_orientation = $pValue; + return $this; + } + + /** + * Get temporary storage directory + * + * @return string + */ + public function getTempDir() + { + return $this->_tempDir; + } + + /** + * Set temporary storage directory + * + * @param string $pValue Temporary storage directory + * @throws PHPExcel_Writer_Exception when directory does not exist + * @return PHPExcel_Writer_PDF + */ + public function setTempDir($pValue = '') + { + if (is_dir($pValue)) { + $this->_tempDir = $pValue; + } else { + throw new PHPExcel_Writer_Exception("Directory does not exist: $pValue"); + } + return $this; + } + + /** + * Save PHPExcel to PDF file, pre-save + * + * @param string $pFilename Name of the file to save as + * @throws PHPExcel_Writer_Exception + */ + protected function prepareForSave($pFilename = NULL) + { + // garbage collect + $this->_phpExcel->garbageCollect(); + + $this->_saveArrayReturnType = PHPExcel_Calculation::getArrayReturnType(); + PHPExcel_Calculation::setArrayReturnType(PHPExcel_Calculation::RETURN_ARRAY_AS_VALUE); + + // Open file + $fileHandle = fopen($pFilename, 'w'); + if ($fileHandle === FALSE) { + throw new PHPExcel_Writer_Exception("Could not open file $pFilename for writing."); + } + + // Set PDF + $this->_isPdf = TRUE; + // Build CSS + $this->buildCSS(TRUE); + + return $fileHandle; + } + + /** + * Save PHPExcel to PDF file, post-save + * + * @param resource $fileHandle + * @throws PHPExcel_Writer_Exception + */ + protected function restoreStateAfterSave($fileHandle) + { + // Close file + fclose($fileHandle); + + PHPExcel_Calculation::setArrayReturnType($this->_saveArrayReturnType); + } + +} diff --git a/lib/phpexcel/PHPExcel/Writer/PDF/DomPDF.php b/lib/phpexcel/PHPExcel/Writer/PDF/DomPDF.php new file mode 100644 index 0000000..111dd36 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Writer/PDF/DomPDF.php @@ -0,0 +1,120 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_PDF + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** Require DomPDF library */ +$pdfRendererClassFile = PHPExcel_Settings::getPdfRendererPath() . '/dompdf_config.inc.php'; +if (file_exists($pdfRendererClassFile)) { + require_once $pdfRendererClassFile; +} else { + throw new PHPExcel_Writer_Exception('Unable to load PDF Rendering library'); +} + +/** + * PHPExcel_Writer_PDF_DomPDF + * + * @category PHPExcel + * @package PHPExcel_Writer_PDF + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_PDF_DomPDF extends PHPExcel_Writer_PDF_Core implements PHPExcel_Writer_IWriter +{ + /** + * Create a new PHPExcel_Writer_PDF + * + * @param PHPExcel $phpExcel PHPExcel object + */ + public function __construct(PHPExcel $phpExcel) + { + parent::__construct($phpExcel); + } + + /** + * Save PHPExcel to file + * + * @param string $pFilename Name of the file to save as + * @throws PHPExcel_Writer_Exception + */ + public function save($pFilename = NULL) + { + $fileHandle = parent::prepareForSave($pFilename); + + // Default PDF paper size + $paperSize = 'LETTER'; // Letter (8.5 in. by 11 in.) + + // Check for paper size and page orientation + if (is_null($this->getSheetIndex())) { + $orientation = ($this->_phpExcel->getSheet(0)->getPageSetup()->getOrientation() + == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE) + ? 'L' + : 'P'; + $printPaperSize = $this->_phpExcel->getSheet(0)->getPageSetup()->getPaperSize(); + $printMargins = $this->_phpExcel->getSheet(0)->getPageMargins(); + } else { + $orientation = ($this->_phpExcel->getSheet($this->getSheetIndex())->getPageSetup()->getOrientation() + == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE) + ? 'L' + : 'P'; + $printPaperSize = $this->_phpExcel->getSheet($this->getSheetIndex())->getPageSetup()->getPaperSize(); + $printMargins = $this->_phpExcel->getSheet($this->getSheetIndex())->getPageMargins(); + } + + // Override Page Orientation + if (!is_null($this->getOrientation())) { + $orientation = ($this->getOrientation() == PHPExcel_Worksheet_PageSetup::ORIENTATION_DEFAULT) + ? PHPExcel_Worksheet_PageSetup::ORIENTATION_PORTRAIT + : $this->getOrientation(); + } + // Override Paper Size + if (!is_null($this->getPaperSize())) { + $printPaperSize = $this->getPaperSize(); + } + + if (isset(self::$_paperSizes[$printPaperSize])) { + $paperSize = self::$_paperSizes[$printPaperSize]; + } + + $orientation = ($orientation == 'L') ? 'landscape' : 'portrait'; + + // Create PDF + $pdf = new DOMPDF(); + $pdf->set_paper(strtolower($paperSize), $orientation); + + $pdf->load_html( + $this->generateHTMLHeader(FALSE) . + $this->generateSheetData() . + $this->generateHTMLFooter() + ); + $pdf->render(); + + // Write to file + fwrite($fileHandle, $pdf->output()); + + parent::restoreStateAfterSave($fileHandle); + } + +} diff --git a/lib/phpexcel/PHPExcel/Writer/PDF/mPDF.php b/lib/phpexcel/PHPExcel/Writer/PDF/mPDF.php new file mode 100644 index 0000000..8e274f4 --- /dev/null +++ b/lib/phpexcel/PHPExcel/Writer/PDF/mPDF.php @@ -0,0 +1,130 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_PDF + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** Require mPDF library */ +$pdfRendererClassFile = PHPExcel_Settings::getPdfRendererPath() . '/mpdf.php'; +if (file_exists($pdfRendererClassFile)) { + require_once $pdfRendererClassFile; +} else { + throw new PHPExcel_Writer_Exception('Unable to load PDF Rendering library'); +} + +/** + * PHPExcel_Writer_PDF_mPDF + * + * @category PHPExcel + * @package PHPExcel_Writer_PDF + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_PDF_mPDF extends PHPExcel_Writer_PDF_Core implements PHPExcel_Writer_IWriter +{ + /** + * Create a new PHPExcel_Writer_PDF + * + * @param PHPExcel $phpExcel PHPExcel object + */ + public function __construct(PHPExcel $phpExcel) + { + parent::__construct($phpExcel); + } + + /** + * Save PHPExcel to file + * + * @param string $pFilename Name of the file to save as + * @throws PHPExcel_Writer_Exception + */ + public function save($pFilename = NULL) + { + $fileHandle = parent::prepareForSave($pFilename); + + // Default PDF paper size + $paperSize = 'LETTER'; // Letter (8.5 in. by 11 in.) + + // Check for paper size and page orientation + if (is_null($this->getSheetIndex())) { + $orientation = ($this->_phpExcel->getSheet(0)->getPageSetup()->getOrientation() + == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE) + ? 'L' + : 'P'; + $printPaperSize = $this->_phpExcel->getSheet(0)->getPageSetup()->getPaperSize(); + $printMargins = $this->_phpExcel->getSheet(0)->getPageMargins(); + } else { + $orientation = ($this->_phpExcel->getSheet($this->getSheetIndex())->getPageSetup()->getOrientation() + == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE) + ? 'L' + : 'P'; + $printPaperSize = $this->_phpExcel->getSheet($this->getSheetIndex())->getPageSetup()->getPaperSize(); + $printMargins = $this->_phpExcel->getSheet($this->getSheetIndex())->getPageMargins(); + } + $this->setOrientation($orientation); + + // Override Page Orientation + if (!is_null($this->getOrientation())) { + $orientation = ($this->getOrientation() == PHPExcel_Worksheet_PageSetup::ORIENTATION_DEFAULT) + ? PHPExcel_Worksheet_PageSetup::ORIENTATION_PORTRAIT + : $this->getOrientation(); + } + $orientation = strtoupper($orientation); + + // Override Paper Size + if (!is_null($this->getPaperSize())) { + $printPaperSize = $this->getPaperSize(); + } + + if (isset(self::$_paperSizes[$printPaperSize])) { + $paperSize = self::$_paperSizes[$printPaperSize]; + } + + // Create PDF + $pdf = new mpdf(); + $ortmp = $orientation; + $pdf->_setPageSize(strtoupper($paperSize), $ortmp); + $pdf->DefOrientation = $orientation; + $pdf->AddPage($orientation); + + // Document info + $pdf->SetTitle($this->_phpExcel->getProperties()->getTitle()); + $pdf->SetAuthor($this->_phpExcel->getProperties()->getCreator()); + $pdf->SetSubject($this->_phpExcel->getProperties()->getSubject()); + $pdf->SetKeywords($this->_phpExcel->getProperties()->getKeywords()); + $pdf->SetCreator($this->_phpExcel->getProperties()->getCreator()); + + $pdf->WriteHTML( + $this->generateHTMLHeader(FALSE) . + $this->generateSheetData() . + $this->generateHTMLFooter() + ); + + // Write to file + fwrite($fileHandle, $pdf->Output('', 'S')); + + parent::restoreStateAfterSave($fileHandle); + } + +} diff --git a/lib/phpexcel/PHPExcel/Writer/PDF/tcPDF.php b/lib/phpexcel/PHPExcel/Writer/PDF/tcPDF.php new file mode 100644 index 0000000..c3809ec --- /dev/null +++ b/lib/phpexcel/PHPExcel/Writer/PDF/tcPDF.php @@ -0,0 +1,136 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_PDF + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** Require tcPDF library */ +$pdfRendererClassFile = PHPExcel_Settings::getPdfRendererPath() . '/tcpdf.php'; +if (file_exists($pdfRendererClassFile)) { + $k_path_url = PHPExcel_Settings::getPdfRendererPath(); + require_once $pdfRendererClassFile; +} else { + throw new PHPExcel_Writer_Exception('Unable to load PDF Rendering library'); +} + +/** + * PHPExcel_Writer_PDF_tcPDF + * + * @category PHPExcel + * @package PHPExcel_Writer_PDF + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_PDF_tcPDF extends PHPExcel_Writer_PDF_Core implements PHPExcel_Writer_IWriter +{ + /** + * Create a new PHPExcel_Writer_PDF + * + * @param PHPExcel $phpExcel PHPExcel object + */ + public function __construct(PHPExcel $phpExcel) + { + parent::__construct($phpExcel); + } + + /** + * Save PHPExcel to file + * + * @param string $pFilename Name of the file to save as + * @throws PHPExcel_Writer_Exception + */ + public function save($pFilename = NULL) + { + $fileHandle = parent::prepareForSave($pFilename); + + // Default PDF paper size + $paperSize = 'LETTER'; // Letter (8.5 in. by 11 in.) + + // Check for paper size and page orientation + if (is_null($this->getSheetIndex())) { + $orientation = ($this->_phpExcel->getSheet(0)->getPageSetup()->getOrientation() + == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE) + ? 'L' + : 'P'; + $printPaperSize = $this->_phpExcel->getSheet(0)->getPageSetup()->getPaperSize(); + $printMargins = $this->_phpExcel->getSheet(0)->getPageMargins(); + } else { + $orientation = ($this->_phpExcel->getSheet($this->getSheetIndex())->getPageSetup()->getOrientation() + == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE) + ? 'L' + : 'P'; + $printPaperSize = $this->_phpExcel->getSheet($this->getSheetIndex())->getPageSetup()->getPaperSize(); + $printMargins = $this->_phpExcel->getSheet($this->getSheetIndex())->getPageMargins(); + } + + // Override Page Orientation + if (!is_null($this->getOrientation())) { + $orientation = ($this->getOrientation() == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE) + ? 'L' + : 'P'; + } + // Override Paper Size + if (!is_null($this->getPaperSize())) { + $printPaperSize = $this->getPaperSize(); + } + + if (isset(self::$_paperSizes[$printPaperSize])) { + $paperSize = self::$_paperSizes[$printPaperSize]; + } + + + // Create PDF + $pdf = new TCPDF($orientation, 'pt', $paperSize); + $pdf->setFontSubsetting(FALSE); + // Set margins, converting inches to points (using 72 dpi) + $pdf->SetMargins($printMargins->getLeft() * 72, $printMargins->getTop() * 72, $printMargins->getRight() * 72); + $pdf->SetAutoPageBreak(TRUE, $printMargins->getBottom() * 72); + + $pdf->setPrintHeader(FALSE); + $pdf->setPrintFooter(FALSE); + + $pdf->AddPage(); + + // Set the appropriate font + $pdf->SetFont($this->getFont()); + $pdf->writeHTML( + $this->generateHTMLHeader(FALSE) . + $this->generateSheetData() . + $this->generateHTMLFooter() + ); + + // Document info + $pdf->SetTitle($this->_phpExcel->getProperties()->getTitle()); + $pdf->SetAuthor($this->_phpExcel->getProperties()->getCreator()); + $pdf->SetSubject($this->_phpExcel->getProperties()->getSubject()); + $pdf->SetKeywords($this->_phpExcel->getProperties()->getKeywords()); + $pdf->SetCreator($this->_phpExcel->getProperties()->getCreator()); + + // Write to file + fwrite($fileHandle, $pdf->output($pFilename, 'S')); + + parent::restoreStateAfterSave($fileHandle); + } + +} diff --git a/lib/phpexcel/PHPExcel/locale/bg/config b/lib/phpexcel/PHPExcel/locale/bg/config new file mode 100644 index 0000000..d7ecb2b --- /dev/null +++ b/lib/phpexcel/PHPExcel/locale/bg/config @@ -0,0 +1,49 @@ +## +## PHPExcel +## + +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Settings +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## + + +ArgumentSeparator = ; + + +## +## (For future use) +## +currencySymbol = лв + + +## +## Excel Error Codes (For future use) + +## +NULL = #ПРАЗНО! +DIV0 = #ДЕЛ/0! +VALUE = #СТОЙНОСТ! +REF = #РЕФ! +NAME = #ИМЕ? +NUM = #ЧИСЛО! +NA = #Н/Д diff --git a/lib/phpexcel/PHPExcel/locale/cs/config b/lib/phpexcel/PHPExcel/locale/cs/config new file mode 100644 index 0000000..af4589b --- /dev/null +++ b/lib/phpexcel/PHPExcel/locale/cs/config @@ -0,0 +1,47 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Settings +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## + + +ArgumentSeparator = ; + + +## +## (For future use) +## +currencySymbol = Kč + + +## +## Excel Error Codes (For future use) +## +NULL = #NULL! +DIV0 = #DIV/0! +VALUE = #HODNOTA! +REF = #REF! +NAME = #NÁZEV? +NUM = #NUM! +NA = #N/A diff --git a/lib/phpexcel/PHPExcel/locale/cs/functions b/lib/phpexcel/PHPExcel/locale/cs/functions new file mode 100644 index 0000000..f324759 --- /dev/null +++ b/lib/phpexcel/PHPExcel/locale/cs/functions @@ -0,0 +1,438 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Calculation +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## Data in this file derived from http://www.piuha.fi/excel-function-name-translation/ +## +## + + +## +## Add-in and Automation functions Funkce doplňků a automatizace +## +GETPIVOTDATA = ZÍSKATKONTDATA ## Vrátí data uložená v kontingenční tabulce. Pomocí funkce ZÍSKATKONTDATA můžete načíst souhrnná data z kontingenční tabulky, pokud jsou tato data v kontingenční sestavě zobrazena. + + +## +## Cube functions Funkce pro práci s krychlemi +## +CUBEKPIMEMBER = CUBEKPIMEMBER ## Vrátí název, vlastnost a velikost klíčového ukazatele výkonu (KUV) a zobrazí v buňce název a vlastnost. Klíčový ukazatel výkonu je kvantifikovatelná veličina, například hrubý měsíční zisk nebo čtvrtletní obrat na zaměstnance, která se používá pro sledování výkonnosti organizace. +CUBEMEMBER = CUBEMEMBER ## Vrátí člen nebo n-tici v hierarchii krychle. Slouží k ověření, zda v krychli existuje člen nebo n-tice. +CUBEMEMBERPROPERTY = CUBEMEMBERPROPERTY ## Vrátí hodnotu vlastnosti člena v krychli. Slouží k ověření, zda v krychli existuje člen s daným názvem, a k vrácení konkrétní vlastnosti tohoto člena. +CUBERANKEDMEMBER = CUBERANKEDMEMBER ## Vrátí n-tý nebo pořadový člen sady. Použijte ji pro vrácení jednoho nebo více prvků sady, například obchodníka s nejvyšším obratem nebo deseti nejlepších studentů. +CUBESET = CUBESET ## Definuje vypočtenou sadu členů nebo n-tic odesláním výrazu sady do krychle na serveru, který vytvoří sadu a potom ji vrátí do aplikace Microsoft Office Excel. +CUBESETCOUNT = CUBESETCOUNT ## Vrátí počet položek v množině +CUBEVALUE = CUBEVALUE ## Vrátí úhrnnou hodnotu z krychle. + + +## +## Database functions Funkce databáze +## +DAVERAGE = DPRŮMĚR ## Vrátí průměr vybraných položek databáze. +DCOUNT = DPOČET ## Spočítá buňky databáze obsahující čísla. +DCOUNTA = DPOČET2 ## Spočítá buňky databáze, které nejsou prázdné. +DGET = DZÍSKAT ## Extrahuje z databáze jeden záznam splňující zadaná kritéria. +DMAX = DMAX ## Vrátí maximální hodnotu z vybraných položek databáze. +DMIN = DMIN ## Vrátí minimální hodnotu z vybraných položek databáze. +DPRODUCT = DSOUČIN ## Vynásobí hodnoty určitého pole záznamů v databázi, které splňují daná kritéria. +DSTDEV = DSMODCH.VÝBĚR ## Odhadne směrodatnou odchylku výběru vybraných položek databáze. +DSTDEVP = DSMODCH ## Vypočte směrodatnou odchylku základního souboru vybraných položek databáze. +DSUM = DSUMA ## Sečte čísla ve sloupcovém poli záznamů databáze, která splňují daná kritéria. +DVAR = DVAR.VÝBĚR ## Odhadne rozptyl výběru vybraných položek databáze. +DVARP = DVAR ## Vypočte rozptyl základního souboru vybraných položek databáze. + + +## +## Date and time functions Funkce data a času +## +DATE = DATUM ## Vrátí pořadové číslo určitého data. +DATEVALUE = DATUMHODN ## Převede datum ve formě textu na pořadové číslo. +DAY = DEN ## Převede pořadové číslo na den v měsíci. +DAYS360 = ROK360 ## Vrátí počet dní mezi dvěma daty na základě roku s 360 dny. +EDATE = EDATE ## Vrátí pořadové číslo data, které označuje určený počet měsíců před nebo po počátečním datu. +EOMONTH = EOMONTH ## Vrátí pořadové číslo posledního dne měsíce před nebo po zadaném počtu měsíců. +HOUR = HODINA ## Převede pořadové číslo na hodinu. +MINUTE = MINUTA ## Převede pořadové číslo na minutu. +MONTH = MĚSÍC ## Převede pořadové číslo na měsíc. +NETWORKDAYS = NETWORKDAYS ## Vrátí počet celých pracovních dní mezi dvěma daty. +NOW = NYNÍ ## Vrátí pořadové číslo aktuálního data a času. +SECOND = SEKUNDA ## Převede pořadové číslo na sekundu. +TIME = ČAS ## Vrátí pořadové číslo určitého času. +TIMEVALUE = ČASHODN ## Převede čas ve formě textu na pořadové číslo. +TODAY = DNES ## Vrátí pořadové číslo dnešního data. +WEEKDAY = DENTÝDNE ## Převede pořadové číslo na den v týdnu. +WEEKNUM = WEEKNUM ## Převede pořadové číslo na číslo představující číselnou pozici týdne v roce. +WORKDAY = WORKDAY ## Vrátí pořadové číslo data před nebo po zadaném počtu pracovních dní. +YEAR = ROK ## Převede pořadové číslo na rok. +YEARFRAC = YEARFRAC ## Vrátí část roku vyjádřenou zlomkem a představující počet celých dní mezi počátečním a koncovým datem. + + +## +## Engineering functions Inženýrské funkce (Technické funkce) +## +BESSELI = BESSELI ## Vrátí modifikovanou Besselovu funkci In(x). +BESSELJ = BESSELJ ## Vrátí modifikovanou Besselovu funkci Jn(x). +BESSELK = BESSELK ## Vrátí modifikovanou Besselovu funkci Kn(x). +BESSELY = BESSELY ## Vrátí Besselovu funkci Yn(x). +BIN2DEC = BIN2DEC ## Převede binární číslo na desítkové. +BIN2HEX = BIN2HEX ## Převede binární číslo na šestnáctkové. +BIN2OCT = BIN2OCT ## Převede binární číslo na osmičkové. +COMPLEX = COMPLEX ## Převede reálnou a imaginární část na komplexní číslo. +CONVERT = CONVERT ## Převede číslo do jiného jednotkového měrného systému. +DEC2BIN = DEC2BIN ## Převede desítkového čísla na dvojkové +DEC2HEX = DEC2HEX ## Převede desítkové číslo na šestnáctkové. +DEC2OCT = DEC2OCT ## Převede desítkové číslo na osmičkové. +DELTA = DELTA ## Testuje rovnost dvou hodnot. +ERF = ERF ## Vrátí chybovou funkci. +ERFC = ERFC ## Vrátí doplňkovou chybovou funkci. +GESTEP = GESTEP ## Testuje, zda je číslo větší než mezní hodnota. +HEX2BIN = HEX2BIN ## Převede šestnáctkové číslo na binární. +HEX2DEC = HEX2DEC ## Převede šestnáctkové číslo na desítkové. +HEX2OCT = HEX2OCT ## Převede šestnáctkové číslo na osmičkové. +IMABS = IMABS ## Vrátí absolutní hodnotu (modul) komplexního čísla. +IMAGINARY = IMAGINARY ## Vrátí imaginární část komplexního čísla. +IMARGUMENT = IMARGUMENT ## Vrátí argument théta, úhel vyjádřený v radiánech. +IMCONJUGATE = IMCONJUGATE ## Vrátí komplexně sdružené číslo ke komplexnímu číslu. +IMCOS = IMCOS ## Vrátí kosinus komplexního čísla. +IMDIV = IMDIV ## Vrátí podíl dvou komplexních čísel. +IMEXP = IMEXP ## Vrátí exponenciální tvar komplexního čísla. +IMLN = IMLN ## Vrátí přirozený logaritmus komplexního čísla. +IMLOG10 = IMLOG10 ## Vrátí dekadický logaritmus komplexního čísla. +IMLOG2 = IMLOG2 ## Vrátí logaritmus komplexního čísla při základu 2. +IMPOWER = IMPOWER ## Vrátí komplexní číslo umocněné na celé číslo. +IMPRODUCT = IMPRODUCT ## Vrátí součin komplexních čísel. +IMREAL = IMREAL ## Vrátí reálnou část komplexního čísla. +IMSIN = IMSIN ## Vrátí sinus komplexního čísla. +IMSQRT = IMSQRT ## Vrátí druhou odmocninu komplexního čísla. +IMSUB = IMSUB ## Vrátí rozdíl mezi dvěma komplexními čísly. +IMSUM = IMSUM ## Vrátí součet dvou komplexních čísel. +OCT2BIN = OCT2BIN ## Převede osmičkové číslo na binární. +OCT2DEC = OCT2DEC ## Převede osmičkové číslo na desítkové. +OCT2HEX = OCT2HEX ## Převede osmičkové číslo na šestnáctkové. + + +## +## Financial functions Finanční funkce +## +ACCRINT = ACCRINT ## Vrátí nahromaděný úrok z cenného papíru, ze kterého je úrok placen v pravidelných termínech. +ACCRINTM = ACCRINTM ## Vrátí nahromaděný úrok z cenného papíru, ze kterého je úrok placen k datu splatnosti. +AMORDEGRC = AMORDEGRC ## Vrátí lineární amortizaci v každém účetním období pomocí koeficientu amortizace. +AMORLINC = AMORLINC ## Vrátí lineární amortizaci v každém účetním období. +COUPDAYBS = COUPDAYBS ## Vrátí počet dnů od začátku období placení kupónů do data splatnosti. +COUPDAYS = COUPDAYS ## Vrátí počet dnů v období placení kupónů, které obsahuje den zúčtování. +COUPDAYSNC = COUPDAYSNC ## Vrátí počet dnů od data zúčtování do následujícího data placení kupónu. +COUPNCD = COUPNCD ## Vrátí následující datum placení kupónu po datu zúčtování. +COUPNUM = COUPNUM ## Vrátí počet kupónů splatných mezi datem zúčtování a datem splatnosti. +COUPPCD = COUPPCD ## Vrátí předchozí datum placení kupónu před datem zúčtování. +CUMIPMT = CUMIPMT ## Vrátí kumulativní úrok splacený mezi dvěma obdobími. +CUMPRINC = CUMPRINC ## Vrátí kumulativní jistinu splacenou mezi dvěma obdobími půjčky. +DB = ODPIS.ZRYCH ## Vrátí odpis aktiva za určité období pomocí degresivní metody odpisu s pevným zůstatkem. +DDB = ODPIS.ZRYCH2 ## Vrátí odpis aktiva za určité období pomocí dvojité degresivní metody odpisu nebo jiné metody, kterou zadáte. +DISC = DISC ## Vrátí diskontní sazbu cenného papíru. +DOLLARDE = DOLLARDE ## Převede částku v korunách vyjádřenou zlomkem na částku v korunách vyjádřenou desetinným číslem. +DOLLARFR = DOLLARFR ## Převede částku v korunách vyjádřenou desetinným číslem na částku v korunách vyjádřenou zlomkem. +DURATION = DURATION ## Vrátí roční dobu cenného papíru s pravidelnými úrokovými sazbami. +EFFECT = EFFECT ## Vrátí efektivní roční úrokovou sazbu. +FV = BUDHODNOTA ## Vrátí budoucí hodnotu investice. +FVSCHEDULE = FVSCHEDULE ## Vrátí budoucí hodnotu počáteční jistiny po použití série sazeb složitého úroku. +INTRATE = INTRATE ## Vrátí úrokovou sazbu plně investovaného cenného papíru. +IPMT = PLATBA.ÚROK ## Vrátí výšku úroku investice za dané období. +IRR = MÍRA.VÝNOSNOSTI ## Vrátí vnitřní výnosové procento série peněžních toků. +ISPMT = ISPMT ## Vypočte výši úroku z investice zaplaceného během určitého období. +MDURATION = MDURATION ## Vrátí Macauleyho modifikovanou dobu cenného papíru o nominální hodnotě 100 Kč. +MIRR = MOD.MÍRA.VÝNOSNOSTI ## Vrátí vnitřní sazbu výnosu, přičemž kladné a záporné hodnoty peněžních prostředků jsou financovány podle různých sazeb. +NOMINAL = NOMINAL ## Vrátí nominální roční úrokovou sazbu. +NPER = POČET.OBDOBÍ ## Vrátí počet období pro investici. +NPV = ČISTÁ.SOUČHODNOTA ## Vrátí čistou současnou hodnotu investice vypočítanou na základě série pravidelných peněžních toků a diskontní sazby. +ODDFPRICE = ODDFPRICE ## Vrátí cenu cenného papíru o nominální hodnotě 100 Kč s odlišným prvním obdobím. +ODDFYIELD = ODDFYIELD ## Vrátí výnos cenného papíru s odlišným prvním obdobím. +ODDLPRICE = ODDLPRICE ## Vrátí cenu cenného papíru o nominální hodnotě 100 Kč s odlišným posledním obdobím. +ODDLYIELD = ODDLYIELD ## Vrátí výnos cenného papíru s odlišným posledním obdobím. +PMT = PLATBA ## Vrátí hodnotu pravidelné splátky anuity. +PPMT = PLATBA.ZÁKLAD ## Vrátí hodnotu splátky jistiny pro zadanou investici za dané období. +PRICE = PRICE ## Vrátí cenu cenného papíru o nominální hodnotě 100 Kč, ze kterého je úrok placen v pravidelných termínech. +PRICEDISC = PRICEDISC ## Vrátí cenu diskontního cenného papíru o nominální hodnotě 100 Kč. +PRICEMAT = PRICEMAT ## Vrátí cenu cenného papíru o nominální hodnotě 100 Kč, ze kterého je úrok placen k datu splatnosti. +PV = SOUČHODNOTA ## Vrátí současnou hodnotu investice. +RATE = ÚROKOVÁ.MÍRA ## Vrátí úrokovou sazbu vztaženou na období anuity. +RECEIVED = RECEIVED ## Vrátí částku obdrženou k datu splatnosti plně investovaného cenného papíru. +SLN = ODPIS.LIN ## Vrátí přímé odpisy aktiva pro jedno období. +SYD = ODPIS.NELIN ## Vrátí směrné číslo ročních odpisů aktiva pro zadané období. +TBILLEQ = TBILLEQ ## Vrátí výnos směnky státní pokladny ekvivalentní výnosu obligace. +TBILLPRICE = TBILLPRICE ## Vrátí cenu směnky státní pokladny o nominální hodnotě 100 Kč. +TBILLYIELD = TBILLYIELD ## Vrátí výnos směnky státní pokladny. +VDB = ODPIS.ZA.INT ## Vrátí odpis aktiva pro určité období nebo část období pomocí degresivní metody odpisu. +XIRR = XIRR ## Vrátí vnitřní výnosnost pro harmonogram peněžních toků, který nemusí být nutně periodický. +XNPV = XNPV ## Vrátí čistou současnou hodnotu pro harmonogram peněžních toků, který nemusí být nutně periodický. +YIELD = YIELD ## Vrátí výnos cenného papíru, ze kterého je úrok placen v pravidelných termínech. +YIELDDISC = YIELDDISC ## Vrátí roční výnos diskontního cenného papíru, například směnky státní pokladny. +YIELDMAT = YIELDMAT ## Vrátí roční výnos cenného papíru, ze kterého je úrok placen k datu splatnosti. + + +## +## Information functions Informační funkce +## +CELL = POLÍČKO ## Vrátí informace o formátování, umístění nebo obsahu buňky. +ERROR.TYPE = CHYBA.TYP ## Vrátí číslo odpovídající typu chyby. +INFO = O.PROSTŘEDÍ ## Vrátí informace o aktuálním pracovním prostředí. +ISBLANK = JE.PRÁZDNÉ ## Vrátí hodnotu PRAVDA, pokud se argument hodnota odkazuje na prázdnou buňku. +ISERR = JE.CHYBA ## Vrátí hodnotu PRAVDA, pokud je argument hodnota libovolná chybová hodnota (kromě #N/A). +ISERROR = JE.CHYBHODN ## Vrátí hodnotu PRAVDA, pokud je argument hodnota libovolná chybová hodnota. +ISEVEN = ISEVEN ## Vrátí hodnotu PRAVDA, pokud je číslo sudé. +ISLOGICAL = JE.LOGHODN ## Vrátí hodnotu PRAVDA, pokud je argument hodnota logická hodnota. +ISNA = JE.NEDEF ## Vrátí hodnotu PRAVDA, pokud je argument hodnota chybová hodnota #N/A. +ISNONTEXT = JE.NETEXT ## Vrátí hodnotu PRAVDA, pokud argument hodnota není text. +ISNUMBER = JE.ČÍSLO ## Vrátí hodnotu PRAVDA, pokud je argument hodnota číslo. +ISODD = ISODD ## Vrátí hodnotu PRAVDA, pokud je číslo liché. +ISREF = JE.ODKAZ ## Vrátí hodnotu PRAVDA, pokud je argument hodnota odkaz. +ISTEXT = JE.TEXT ## Vrátí hodnotu PRAVDA, pokud je argument hodnota text. +N = N ## Vrátí hodnotu převedenou na číslo. +NA = NEDEF ## Vrátí chybovou hodnotu #N/A. +TYPE = TYP ## Vrátí číslo označující datový typ hodnoty. + + +## +## Logical functions Logické funkce +## +AND = A ## Vrátí hodnotu PRAVDA, mají-li všechny argumenty hodnotu PRAVDA. +FALSE = NEPRAVDA ## Vrátí logickou hodnotu NEPRAVDA. +IF = KDYŽ ## Určí, který logický test má proběhnout. +IFERROR = IFERROR ## Pokud je vzorec vyhodnocen jako chyba, vrátí zadanou hodnotu. V opačném případě vrátí výsledek vzorce. +NOT = NE ## Provede logickou negaci argumentu funkce. +OR = NEBO ## Vrátí hodnotu PRAVDA, je-li alespoň jeden argument roven hodnotě PRAVDA. +TRUE = PRAVDA ## Vrátí logickou hodnotu PRAVDA. + + +## +## Lookup and reference functions Vyhledávací funkce +## +ADDRESS = ODKAZ ## Vrátí textový odkaz na jednu buňku listu. +AREAS = POČET.BLOKŮ ## Vrátí počet oblastí v odkazu. +CHOOSE = ZVOLIT ## Zvolí hodnotu ze seznamu hodnot. +COLUMN = SLOUPEC ## Vrátí číslo sloupce odkazu. +COLUMNS = SLOUPCE ## Vrátí počet sloupců v odkazu. +HLOOKUP = VVYHLEDAT ## Prohledá horní řádek matice a vrátí hodnotu určené buňky. +HYPERLINK = HYPERTEXTOVÝ.ODKAZ ## Vytvoří zástupce nebo odkaz, který otevře dokument uložený na síťovém serveru, v síti intranet nebo Internet. +INDEX = INDEX ## Pomocí rejstříku zvolí hodnotu z odkazu nebo matice. +INDIRECT = NEPŘÍMÝ.ODKAZ ## Vrátí odkaz určený textovou hodnotou. +LOOKUP = VYHLEDAT ## Vyhledá hodnoty ve vektoru nebo matici. +MATCH = POZVYHLEDAT ## Vyhledá hodnoty v odkazu nebo matici. +OFFSET = POSUN ## Vrátí posun odkazu od zadaného odkazu. +ROW = ŘÁDEK ## Vrátí číslo řádku odkazu. +ROWS = ŘÁDKY ## Vrátí počet řádků v odkazu. +RTD = RTD ## Načte data reálného času z programu, který podporuje automatizaci modelu COM (Automatizace: Způsob práce s objekty určité aplikace z jiné aplikace nebo nástroje pro vývoj. Automatizace (dříve nazývaná automatizace OLE) je počítačovým standardem a je funkcí modelu COM (Component Object Model).). +TRANSPOSE = TRANSPOZICE ## Vrátí transponovanou matici. +VLOOKUP = SVYHLEDAT ## Prohledá první sloupec matice, přesune kurzor v řádku a vrátí hodnotu buňky. + + +## +## Math and trigonometry functions Matematické a trigonometrické funkce +## +ABS = ABS ## Vrátí absolutní hodnotu čísla. +ACOS = ARCCOS ## Vrátí arkuskosinus čísla. +ACOSH = ARCCOSH ## Vrátí hyperbolický arkuskosinus čísla. +ASIN = ARCSIN ## Vrátí arkussinus čísla. +ASINH = ARCSINH ## Vrátí hyperbolický arkussinus čísla. +ATAN = ARCTG ## Vrátí arkustangens čísla. +ATAN2 = ARCTG2 ## Vrátí arkustangens x-ové a y-ové souřadnice. +ATANH = ARCTGH ## Vrátí hyperbolický arkustangens čísla. +CEILING = ZAOKR.NAHORU ## Zaokrouhlí číslo na nejbližší celé číslo nebo na nejbližší násobek zadané hodnoty. +COMBIN = KOMBINACE ## Vrátí počet kombinací pro daný počet položek. +COS = COS ## Vrátí kosinus čísla. +COSH = COSH ## Vrátí hyperbolický kosinus čísla. +DEGREES = DEGREES ## Převede radiány na stupně. +EVEN = ZAOKROUHLIT.NA.SUDÉ ## Zaokrouhlí číslo nahoru na nejbližší celé sudé číslo. +EXP = EXP ## Vrátí základ přirozeného logaritmu e umocněný na zadané číslo. +FACT = FAKTORIÁL ## Vrátí faktoriál čísla. +FACTDOUBLE = FACTDOUBLE ## Vrátí dvojitý faktoriál čísla. +FLOOR = ZAOKR.DOLŮ ## Zaokrouhlí číslo dolů, směrem k nule. +GCD = GCD ## Vrátí největší společný dělitel. +INT = CELÁ.ČÁST ## Zaokrouhlí číslo dolů na nejbližší celé číslo. +LCM = LCM ## Vrátí nejmenší společný násobek. +LN = LN ## Vrátí přirozený logaritmus čísla. +LOG = LOGZ ## Vrátí logaritmus čísla při zadaném základu. +LOG10 = LOG ## Vrátí dekadický logaritmus čísla. +MDETERM = DETERMINANT ## Vrátí determinant matice. +MINVERSE = INVERZE ## Vrátí inverzní matici. +MMULT = SOUČIN.MATIC ## Vrátí součin dvou matic. +MOD = MOD ## Vrátí zbytek po dělení. +MROUND = MROUND ## Vrátí číslo zaokrouhlené na požadovaný násobek. +MULTINOMIAL = MULTINOMIAL ## Vrátí mnohočlen z množiny čísel. +ODD = ZAOKROUHLIT.NA.LICHÉ ## Zaokrouhlí číslo nahoru na nejbližší celé liché číslo. +PI = PI ## Vrátí hodnotu čísla pí. +POWER = POWER ## Umocní číslo na zadanou mocninu. +PRODUCT = SOUČIN ## Vynásobí argumenty funkce. +QUOTIENT = QUOTIENT ## Vrátí celou část dělení. +RADIANS = RADIANS ## Převede stupně na radiány. +RAND = NÁHČÍSLO ## Vrátí náhodné číslo mezi 0 a 1. +RANDBETWEEN = RANDBETWEEN ## Vrátí náhodné číslo mezi zadanými čísly. +ROMAN = ROMAN ## Převede arabskou číslici na římskou ve formátu textu. +ROUND = ZAOKROUHLIT ## Zaokrouhlí číslo na zadaný počet číslic. +ROUNDDOWN = ROUNDDOWN ## Zaokrouhlí číslo dolů, směrem k nule. +ROUNDUP = ROUNDUP ## Zaokrouhlí číslo nahoru, směrem od nuly. +SERIESSUM = SERIESSUM ## Vrátí součet mocninné řady určené podle vzorce. +SIGN = SIGN ## Vrátí znaménko čísla. +SIN = SIN ## Vrátí sinus daného úhlu. +SINH = SINH ## Vrátí hyperbolický sinus čísla. +SQRT = ODMOCNINA ## Vrátí kladnou druhou odmocninu. +SQRTPI = SQRTPI ## Vrátí druhou odmocninu výrazu (číslo * pí). +SUBTOTAL = SUBTOTAL ## Vrátí souhrn v seznamu nebo databázi. +SUM = SUMA ## Sečte argumenty funkce. +SUMIF = SUMIF ## Sečte buňky vybrané podle zadaných kritérií. +SUMIFS = SUMIFS ## Sečte buňky určené více zadanými podmínkami. +SUMPRODUCT = SOUČIN.SKALÁRNÍ ## Vrátí součet součinů odpovídajících prvků matic. +SUMSQ = SUMA.ČTVERCŮ ## Vrátí součet čtverců argumentů. +SUMX2MY2 = SUMX2MY2 ## Vrátí součet rozdílu čtverců odpovídajících hodnot ve dvou maticích. +SUMX2PY2 = SUMX2PY2 ## Vrátí součet součtu čtverců odpovídajících hodnot ve dvou maticích. +SUMXMY2 = SUMXMY2 ## Vrátí součet čtverců rozdílů odpovídajících hodnot ve dvou maticích. +TAN = TGTG ## Vrátí tangens čísla. +TANH = TGH ## Vrátí hyperbolický tangens čísla. +TRUNC = USEKNOUT ## Zkrátí číslo na celé číslo. + + +## +## Statistical functions Statistické funkce +## +AVEDEV = PRŮMODCHYLKA ## Vrátí průměrnou hodnotu absolutních odchylek datových bodů od jejich střední hodnoty. +AVERAGE = PRŮMĚR ## Vrátí průměrnou hodnotu argumentů. +AVERAGEA = AVERAGEA ## Vrátí průměrnou hodnotu argumentů včetně čísel, textu a logických hodnot. +AVERAGEIF = AVERAGEIF ## Vrátí průměrnou hodnotu (aritmetický průměr) všech buněk v oblasti, které vyhovují příslušné podmínce. +AVERAGEIFS = AVERAGEIFS ## Vrátí průměrnou hodnotu (aritmetický průměr) všech buněk vyhovujících několika podmínkám. +BETADIST = BETADIST ## Vrátí hodnotu součtového rozdělení beta. +BETAINV = BETAINV ## Vrátí inverzní hodnotu součtového rozdělení pro zadané rozdělení beta. +BINOMDIST = BINOMDIST ## Vrátí hodnotu binomického rozdělení pravděpodobnosti jednotlivých veličin. +CHIDIST = CHIDIST ## Vrátí jednostrannou pravděpodobnost rozdělení chí-kvadrát. +CHIINV = CHIINV ## Vrátí hodnotu funkce inverzní k distribuční funkci jednostranné pravděpodobnosti rozdělení chí-kvadrát. +CHITEST = CHITEST ## Vrátí test nezávislosti. +CONFIDENCE = CONFIDENCE ## Vrátí interval spolehlivosti pro střední hodnotu základního souboru. +CORREL = CORREL ## Vrátí korelační koeficient mezi dvěma množinami dat. +COUNT = POČET ## Vrátí počet čísel v seznamu argumentů. +COUNTA = POČET2 ## Vrátí počet hodnot v seznamu argumentů. +COUNTBLANK = COUNTBLANK ## Spočítá počet prázdných buněk v oblasti. +COUNTIF = COUNTIF ## Spočítá buňky v oblasti, které odpovídají zadaným kritériím. +COUNTIFS = COUNTIFS ## Spočítá buňky v oblasti, které odpovídají více kritériím. +COVAR = COVAR ## Vrátí hodnotu kovariance, průměrnou hodnotu součinů párových odchylek +CRITBINOM = CRITBINOM ## Vrátí nejmenší hodnotu, pro kterou má součtové binomické rozdělení hodnotu větší nebo rovnu hodnotě kritéria. +DEVSQ = DEVSQ ## Vrátí součet čtverců odchylek. +EXPONDIST = EXPONDIST ## Vrátí hodnotu exponenciálního rozdělení. +FDIST = FDIST ## Vrátí hodnotu rozdělení pravděpodobnosti F. +FINV = FINV ## Vrátí hodnotu inverzní funkce k distribuční funkci rozdělení F. +FISHER = FISHER ## Vrátí hodnotu Fisherovy transformace. +FISHERINV = FISHERINV ## Vrátí hodnotu inverzní funkce k Fisherově transformaci. +FORECAST = FORECAST ## Vrátí hodnotu lineárního trendu. +FREQUENCY = ČETNOSTI ## Vrátí četnost rozdělení jako svislou matici. +FTEST = FTEST ## Vrátí výsledek F-testu. +GAMMADIST = GAMMADIST ## Vrátí hodnotu rozdělení gama. +GAMMAINV = GAMMAINV ## Vrátí hodnotu inverzní funkce k distribuční funkci součtového rozdělení gama. +GAMMALN = GAMMALN ## Vrátí přirozený logaritmus funkce gama, Γ(x). +GEOMEAN = GEOMEAN ## Vrátí geometrický průměr. +GROWTH = LOGLINTREND ## Vrátí hodnoty exponenciálního trendu. +HARMEAN = HARMEAN ## Vrátí harmonický průměr. +HYPGEOMDIST = HYPGEOMDIST ## Vrátí hodnotu hypergeometrického rozdělení. +INTERCEPT = INTERCEPT ## Vrátí úsek lineární regresní čáry. +KURT = KURT ## Vrátí hodnotu excesu množiny dat. +LARGE = LARGE ## Vrátí k-tou největší hodnotu množiny dat. +LINEST = LINREGRESE ## Vrátí parametry lineárního trendu. +LOGEST = LOGLINREGRESE ## Vrátí parametry exponenciálního trendu. +LOGINV = LOGINV ## Vrátí inverzní funkci k distribuční funkci logaritmicko-normálního rozdělení. +LOGNORMDIST = LOGNORMDIST ## Vrátí hodnotu součtového logaritmicko-normálního rozdělení. +MAX = MAX ## Vrátí maximální hodnotu seznamu argumentů. +MAXA = MAXA ## Vrátí maximální hodnotu seznamu argumentů včetně čísel, textu a logických hodnot. +MEDIAN = MEDIAN ## Vrátí střední hodnotu zadaných čísel. +MIN = MIN ## Vrátí minimální hodnotu seznamu argumentů. +MINA = MINA ## Vrátí nejmenší hodnotu v seznamu argumentů včetně čísel, textu a logických hodnot. +MODE = MODE ## Vrátí hodnotu, která se v množině dat vyskytuje nejčastěji. +NEGBINOMDIST = NEGBINOMDIST ## Vrátí hodnotu negativního binomického rozdělení. +NORMDIST = NORMDIST ## Vrátí hodnotu normálního součtového rozdělení. +NORMINV = NORMINV ## Vrátí inverzní funkci k funkci normálního součtového rozdělení. +NORMSDIST = NORMSDIST ## Vrátí hodnotu standardního normálního součtového rozdělení. +NORMSINV = NORMSINV ## Vrátí inverzní funkci k funkci standardního normálního součtového rozdělení. +PEARSON = PEARSON ## Vrátí Pearsonův výsledný momentový korelační koeficient. +PERCENTILE = PERCENTIL ## Vrátí hodnotu k-tého percentilu hodnot v oblasti. +PERCENTRANK = PERCENTRANK ## Vrátí pořadí hodnoty v množině dat vyjádřené procentuální částí množiny dat. +PERMUT = PERMUTACE ## Vrátí počet permutací pro zadaný počet objektů. +POISSON = POISSON ## Vrátí hodnotu distribuční funkce Poissonova rozdělení. +PROB = PROB ## Vrátí pravděpodobnost výskytu hodnot v oblasti mezi dvěma mezními hodnotami. +QUARTILE = QUARTIL ## Vrátí hodnotu kvartilu množiny dat. +RANK = RANK ## Vrátí pořadí čísla v seznamu čísel. +RSQ = RKQ ## Vrátí druhou mocninu Pearsonova výsledného momentového korelačního koeficientu. +SKEW = SKEW ## Vrátí zešikmení rozdělení. +SLOPE = SLOPE ## Vrátí směrnici lineární regresní čáry. +SMALL = SMALL ## Vrátí k-tou nejmenší hodnotu množiny dat. +STANDARDIZE = STANDARDIZE ## Vrátí normalizovanou hodnotu. +STDEV = SMODCH.VÝBĚR ## Vypočte směrodatnou odchylku výběru. +STDEVA = STDEVA ## Vypočte směrodatnou odchylku výběru včetně čísel, textu a logických hodnot. +STDEVP = SMODCH ## Vypočte směrodatnou odchylku základního souboru. +STDEVPA = STDEVPA ## Vypočte směrodatnou odchylku základního souboru včetně čísel, textu a logických hodnot. +STEYX = STEYX ## Vrátí standardní chybu předpovězené hodnoty y pro každou hodnotu x v regresi. +TDIST = TDIST ## Vrátí hodnotu Studentova t-rozdělení. +TINV = TINV ## Vrátí inverzní funkci k distribuční funkci Studentova t-rozdělení. +TREND = LINTREND ## Vrátí hodnoty lineárního trendu. +TRIMMEAN = TRIMMEAN ## Vrátí střední hodnotu vnitřní části množiny dat. +TTEST = TTEST ## Vrátí pravděpodobnost spojenou se Studentovým t-testem. +VAR = VAR.VÝBĚR ## Vypočte rozptyl výběru. +VARA = VARA ## Vypočte rozptyl výběru včetně čísel, textu a logických hodnot. +VARP = VAR ## Vypočte rozptyl základního souboru. +VARPA = VARPA ## Vypočte rozptyl základního souboru včetně čísel, textu a logických hodnot. +WEIBULL = WEIBULL ## Vrátí hodnotu Weibullova rozdělení. +ZTEST = ZTEST ## Vrátí jednostrannou P-hodnotu z-testu. + + +## +## Text functions Textové funkce +## +ASC = ASC ## Změní znaky s plnou šířkou (dvoubajtové)v řetězci znaků na znaky s poloviční šířkou (jednobajtové). +BAHTTEXT = BAHTTEXT ## Převede číslo na text ve formátu, měny ß (baht). +CHAR = ZNAK ## Vrátí znak určený číslem kódu. +CLEAN = VYČISTIT ## Odebere z textu všechny netisknutelné znaky. +CODE = KÓD ## Vrátí číselný kód prvního znaku zadaného textového řetězce. +CONCATENATE = CONCATENATE ## Spojí několik textových položek do jedné. +DOLLAR = KČ ## Převede číslo na text ve formátu měny Kč (česká koruna). +EXACT = STEJNÉ ## Zkontroluje, zda jsou dvě textové hodnoty shodné. +FIND = NAJÍT ## Nalezne textovou hodnotu uvnitř jiné (rozlišuje malá a velká písmena). +FINDB = FINDB ## Nalezne textovou hodnotu uvnitř jiné (rozlišuje malá a velká písmena). +FIXED = ZAOKROUHLIT.NA.TEXT ## Zformátuje číslo jako text s pevným počtem desetinných míst. +JIS = JIS ## Změní znaky s poloviční šířkou (jednobajtové) v řetězci znaků na znaky s plnou šířkou (dvoubajtové). +LEFT = ZLEVA ## Vrátí první znaky textové hodnoty umístěné nejvíce vlevo. +LEFTB = LEFTB ## Vrátí první znaky textové hodnoty umístěné nejvíce vlevo. +LEN = DÉLKA ## Vrátí počet znaků textového řetězce. +LENB = LENB ## Vrátí počet znaků textového řetězce. +LOWER = MALÁ ## Převede text na malá písmena. +MID = ČÁST ## Vrátí určitý počet znaků textového řetězce počínaje zadaným místem. +MIDB = MIDB ## Vrátí určitý počet znaků textového řetězce počínaje zadaným místem. +PHONETIC = ZVUKOVÉ ## Extrahuje fonetické znaky (furigana) z textového řetězce. +PROPER = VELKÁ2 ## Převede první písmeno každého slova textové hodnoty na velké. +REPLACE = NAHRADIT ## Nahradí znaky uvnitř textu. +REPLACEB = NAHRADITB ## Nahradí znaky uvnitř textu. +REPT = OPAKOVAT ## Zopakuje text podle zadaného počtu opakování. +RIGHT = ZPRAVA ## Vrátí první znaky textové hodnoty umístěné nejvíce vpravo. +RIGHTB = RIGHTB ## Vrátí první znaky textové hodnoty umístěné nejvíce vpravo. +SEARCH = HLEDAT ## Nalezne textovou hodnotu uvnitř jiné (malá a velká písmena nejsou rozlišována). +SEARCHB = SEARCHB ## Nalezne textovou hodnotu uvnitř jiné (malá a velká písmena nejsou rozlišována). +SUBSTITUTE = DOSADIT ## V textovém řetězci nahradí starý text novým. +T = T ## Převede argumenty na text. +TEXT = HODNOTA.NA.TEXT ## Zformátuje číslo a převede ho na text. +TRIM = PROČISTIT ## Odstraní z textu mezery. +UPPER = VELKÁ ## Převede text na velká písmena. +VALUE = HODNOTA ## Převede textový argument na číslo. diff --git a/lib/phpexcel/PHPExcel/locale/da/config b/lib/phpexcel/PHPExcel/locale/da/config new file mode 100644 index 0000000..1ddecb9 --- /dev/null +++ b/lib/phpexcel/PHPExcel/locale/da/config @@ -0,0 +1,48 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Settings +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## + + +ArgumentSeparator = ; + + +## +## (For future use) +## +currencySymbol = kr + + + +## +## Excel Error Codes (For future use) +## +NULL = #NUL! +DIV0 = #DIVISION/0! +VALUE = #VÆRDI! +REF = #REFERENCE! +NAME = #NAVN? +NUM = #NUM! +NA = #I/T diff --git a/lib/phpexcel/PHPExcel/locale/da/functions b/lib/phpexcel/PHPExcel/locale/da/functions new file mode 100644 index 0000000..102d578 --- /dev/null +++ b/lib/phpexcel/PHPExcel/locale/da/functions @@ -0,0 +1,438 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Calculation +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## Data in this file derived from http://www.piuha.fi/excel-function-name-translation/ +## +## + + +## +## Add-in and Automation functions Tilføjelsesprogram- og automatiseringsfunktioner +## +GETPIVOTDATA = HENTPIVOTDATA ## Returnerer data, der er lagret i en pivottabelrapport + + +## +## Cube functions Kubefunktioner +## +CUBEKPIMEMBER = KUBE.KPI.MEDLEM ## Returnerer navn, egenskab og mål for en KPI-indikator og viser navnet og egenskaben i cellen. En KPI-indikator er en målbar størrelse, f.eks. bruttooverskud pr. måned eller personaleudskiftning pr. kvartal, der bruges til at overvåge en organisations præstationer. +CUBEMEMBER = KUBE.MEDLEM ## Returnerer et medlem eller en tupel fra kubehierarkiet. Bruges til at validere, om et medlem eller en tupel findes i kuben. +CUBEMEMBERPROPERTY = KUBEMEDLEM.EGENSKAB ## Returnerer værdien af en egenskab for et medlem i kuben. Bruges til at validere, om et medlemsnavn findes i kuben, og returnere den angivne egenskab for medlemmet. +CUBERANKEDMEMBER = KUBEMEDLEM.RANG ## Returnerer det n'te eller rangordnede medlem i et sæt. Bruges til at returnere et eller flere elementer i et sæt, f.eks. topsælgere eller de 10 bedste elever. +CUBESET = KUBESÆT ## Definerer et beregnet sæt medlemmer eller tupler ved at sende et sætudtryk til kuben på serveren, som opretter sættet og returnerer det til Microsoft Office Excel. +CUBESETCOUNT = KUBESÆT.TÆL ## Returnerer antallet af elementer i et sæt. +CUBEVALUE = KUBEVÆRDI ## Returnerer en sammenlagt (aggregeret) værdi fra en kube. + + +## +## Database functions Databasefunktioner +## +DAVERAGE = DMIDDEL ## Returnerer gennemsnittet af markerede databaseposter +DCOUNT = DTÆL ## Tæller de celler, der indeholder tal, i en database +DCOUNTA = DTÆLV ## Tæller udfyldte celler i en database +DGET = DHENT ## Uddrager en enkelt post, der opfylder de angivne kriterier, fra en database +DMAX = DMAKS ## Returnerer den største værdi blandt markerede databaseposter +DMIN = DMIN ## Returnerer den mindste værdi blandt markerede databaseposter +DPRODUCT = DPRODUKT ## Ganger værdierne i et bestemt felt med poster, der opfylder kriterierne i en database +DSTDEV = DSTDAFV ## Beregner et skøn over standardafvigelsen baseret på en stikprøve af markerede databaseposter +DSTDEVP = DSTDAFVP ## Beregner standardafvigelsen baseret på hele populationen af markerede databaseposter +DSUM = DSUM ## Sammenlægger de tal i feltkolonnen i databasen, der opfylder kriterierne +DVAR = DVARIANS ## Beregner varians baseret på en stikprøve af markerede databaseposter +DVARP = DVARIANSP ## Beregner varians baseret på hele populationen af markerede databaseposter + + +## +## Date and time functions Dato- og klokkeslætsfunktioner +## +DATE = DATO ## Returnerer serienummeret for en bestemt dato +DATEVALUE = DATOVÆRDI ## Konverterer en dato i form af tekst til et serienummer +DAY = DAG ## Konverterer et serienummer til en dag i måneden +DAYS360 = DAGE360 ## Beregner antallet af dage mellem to datoer på grundlag af et år med 360 dage +EDATE = EDATO ## Returnerer serienummeret for den dato, der ligger det angivne antal måneder før eller efter startdatoen +EOMONTH = SLUT.PÅ.MÅNED ## Returnerer serienummeret på den sidste dag i måneden før eller efter et angivet antal måneder +HOUR = TIME ## Konverterer et serienummer til en time +MINUTE = MINUT ## Konverterer et serienummer til et minut +MONTH = MÅNED ## Konverterer et serienummer til en måned +NETWORKDAYS = ANTAL.ARBEJDSDAGE ## Returnerer antallet af hele arbejdsdage mellem to datoer +NOW = NU ## Returnerer serienummeret for den aktuelle dato eller det aktuelle klokkeslæt +SECOND = SEKUND ## Konverterer et serienummer til et sekund +TIME = KLOKKESLÆT ## Returnerer serienummeret for et bestemt klokkeslæt +TIMEVALUE = TIDSVÆRDI ## Konverterer et klokkeslæt i form af tekst til et serienummer +TODAY = IDAG ## Returnerer serienummeret for dags dato +WEEKDAY = UGEDAG ## Konverterer et serienummer til en ugedag +WEEKNUM = UGE.NR ## Konverterer et serienummer til et tal, der angiver ugenummeret i året +WORKDAY = ARBEJDSDAG ## Returnerer serienummeret for dagen før eller efter det angivne antal arbejdsdage +YEAR = ÅR ## Konverterer et serienummer til et år +YEARFRAC = ÅR.BRØK ## Returnerer årsbrøken, der repræsenterer antallet af hele dage mellem startdato og slutdato + + +## +## Engineering functions Tekniske funktioner +## +BESSELI = BESSELI ## Returnerer den modificerede Bessel-funktion In(x) +BESSELJ = BESSELJ ## Returnerer Bessel-funktionen Jn(x) +BESSELK = BESSELK ## Returnerer den modificerede Bessel-funktion Kn(x) +BESSELY = BESSELY ## Returnerer Bessel-funktionen Yn(x) +BIN2DEC = BIN.TIL.DEC ## Konverterer et binært tal til et decimaltal +BIN2HEX = BIN.TIL.HEX ## Konverterer et binært tal til et heksadecimalt tal +BIN2OCT = BIN.TIL.OKT ## Konverterer et binært tal til et oktaltal. +COMPLEX = KOMPLEKS ## Konverterer reelle og imaginære koefficienter til et komplekst tal +CONVERT = KONVERTER ## Konverterer et tal fra én måleenhed til en anden +DEC2BIN = DEC.TIL.BIN ## Konverterer et decimaltal til et binært tal +DEC2HEX = DEC.TIL.HEX ## Konverterer et decimaltal til et heksadecimalt tal +DEC2OCT = DEC.TIL.OKT ## Konverterer et decimaltal til et oktaltal +DELTA = DELTA ## Tester, om to værdier er ens +ERF = FEJLFUNK ## Returner fejlfunktionen +ERFC = FEJLFUNK.KOMP ## Returnerer den komplementære fejlfunktion +GESTEP = GETRIN ## Tester, om et tal er større end en grænseværdi +HEX2BIN = HEX.TIL.BIN ## Konverterer et heksadecimalt tal til et binært tal +HEX2DEC = HEX.TIL.DEC ## Konverterer et decimaltal til et heksadecimalt tal +HEX2OCT = HEX.TIL.OKT ## Konverterer et heksadecimalt tal til et oktaltal +IMABS = IMAGABS ## Returnerer den absolutte værdi (modulus) for et komplekst tal +IMAGINARY = IMAGINÆR ## Returnerer den imaginære koefficient for et komplekst tal +IMARGUMENT = IMAGARGUMENT ## Returnerer argumentet theta, en vinkel udtrykt i radianer +IMCONJUGATE = IMAGKONJUGERE ## Returnerer den komplekse konjugation af et komplekst tal +IMCOS = IMAGCOS ## Returnerer et komplekst tals cosinus +IMDIV = IMAGDIV ## Returnerer kvotienten for to komplekse tal +IMEXP = IMAGEKSP ## Returnerer et komplekst tals eksponentialfunktion +IMLN = IMAGLN ## Returnerer et komplekst tals naturlige logaritme +IMLOG10 = IMAGLOG10 ## Returnerer et komplekst tals sædvanlige logaritme (titalslogaritme) +IMLOG2 = IMAGLOG2 ## Returnerer et komplekst tals sædvanlige logaritme (totalslogaritme) +IMPOWER = IMAGPOTENS ## Returnerer et komplekst tal opløftet i en heltalspotens +IMPRODUCT = IMAGPRODUKT ## Returnerer produktet af komplekse tal +IMREAL = IMAGREELT ## Returnerer den reelle koefficient for et komplekst tal +IMSIN = IMAGSIN ## Returnerer et komplekst tals sinus +IMSQRT = IMAGKVROD ## Returnerer et komplekst tals kvadratrod +IMSUB = IMAGSUB ## Returnerer forskellen mellem to komplekse tal +IMSUM = IMAGSUM ## Returnerer summen af komplekse tal +OCT2BIN = OKT.TIL.BIN ## Konverterer et oktaltal til et binært tal +OCT2DEC = OKT.TIL.DEC ## Konverterer et oktaltal til et decimaltal +OCT2HEX = OKT.TIL.HEX ## Konverterer et oktaltal til et heksadecimalt tal + + +## +## Financial functions Finansielle funktioner +## +ACCRINT = PÅLØBRENTE ## Returnerer den påløbne rente for et værdipapir med periodiske renteudbetalinger +ACCRINTM = PÅLØBRENTE.UDLØB ## Returnerer den påløbne rente for et værdipapir, hvor renteudbetalingen finder sted ved papirets udløb +AMORDEGRC = AMORDEGRC ## Returnerer afskrivningsbeløbet for hver regnskabsperiode ved hjælp af en afskrivningskoefficient +AMORLINC = AMORLINC ## Returnerer afskrivningsbeløbet for hver regnskabsperiode +COUPDAYBS = KUPONDAGE.SA ## Returnerer antallet af dage fra starten af kuponperioden til afregningsdatoen +COUPDAYS = KUPONDAGE.A ## Returnerer antallet af dage fra begyndelsen af kuponperioden til afregningsdatoen +COUPDAYSNC = KUPONDAGE.ANK ## Returnerer antallet af dage i den kuponperiode, der indeholder afregningsdatoen +COUPNCD = KUPONDAG.NÆSTE ## Returnerer den næste kupondato efter afregningsdatoen +COUPNUM = KUPONBETALINGER ## Returnerer antallet af kuponudbetalinger mellem afregnings- og udløbsdatoen +COUPPCD = KUPONDAG.FORRIGE ## Returnerer den forrige kupondato før afregningsdatoen +CUMIPMT = AKKUM.RENTE ## Returnerer den akkumulerede rente, der betales på et lån mellem to perioder +CUMPRINC = AKKUM.HOVEDSTOL ## Returnerer den akkumulerede nedbringelse af hovedstol mellem to perioder +DB = DB ## Returnerer afskrivningen på et aktiv i en angivet periode ved anvendelse af saldometoden +DDB = DSA ## Returnerer afskrivningsbeløbet for et aktiv over en bestemt periode ved anvendelse af dobbeltsaldometoden eller en anden afskrivningsmetode, som du angiver +DISC = DISKONTO ## Returnerer et værdipapirs diskonto +DOLLARDE = KR.DECIMAL ## Konverterer en kronepris udtrykt som brøk til en kronepris udtrykt som decimaltal +DOLLARFR = KR.BRØK ## Konverterer en kronepris udtrykt som decimaltal til en kronepris udtrykt som brøk +DURATION = VARIGHED ## Returnerer den årlige løbetid for et værdipapir med periodiske renteudbetalinger +EFFECT = EFFEKTIV.RENTE ## Returnerer den årlige effektive rente +FV = FV ## Returnerer fremtidsværdien af en investering +FVSCHEDULE = FVTABEL ## Returnerer den fremtidige værdi af en hovedstol, når der er tilskrevet rente og rentes rente efter forskellige rentesatser +INTRATE = RENTEFOD ## Returnerer renten på et fuldt ud investeret værdipapir +IPMT = R.YDELSE ## Returnerer renten fra en investering for en given periode +IRR = IA ## Returnerer den interne rente for en række pengestrømme +ISPMT = ISPMT ## Beregner den betalte rente i løbet af en bestemt investeringsperiode +MDURATION = MVARIGHED ## Returnerer Macauleys modificerede løbetid for et værdipapir med en formodet pari på kr. 100 +MIRR = MIA ## Returnerer den interne forrentning, hvor positive og negative pengestrømme finansieres til forskellig rente +NOMINAL = NOMINEL ## Returnerer den årlige nominelle rente +NPER = NPER ## Returnerer antallet af perioder for en investering +NPV = NUTIDSVÆRDI ## Returnerer nettonutidsværdien for en investering baseret på en række periodiske pengestrømme og en diskonteringssats +ODDFPRICE = ULIGE.KURS.PÅLYDENDE ## Returnerer kursen pr. kr. 100 nominel værdi for et værdipapir med en ulige (kort eller lang) første periode +ODDFYIELD = ULIGE.FØRSTE.AFKAST ## Returnerer afkastet for et værdipapir med ulige første periode +ODDLPRICE = ULIGE.SIDSTE.KURS ## Returnerer kursen pr. kr. 100 nominel værdi for et værdipapir med ulige sidste periode +ODDLYIELD = ULIGE.SIDSTE.AFKAST ## Returnerer afkastet for et værdipapir med ulige sidste periode +PMT = YDELSE ## Returnerer renten fra en investering for en given periode +PPMT = H.YDELSE ## Returnerer ydelsen på hovedstolen for en investering i en given periode +PRICE = KURS ## Returnerer kursen pr. kr 100 nominel værdi for et værdipapir med periodiske renteudbetalinger +PRICEDISC = KURS.DISKONTO ## Returnerer kursen pr. kr 100 nominel værdi for et diskonteret værdipapir +PRICEMAT = KURS.UDLØB ## Returnerer kursen pr. kr 100 nominel værdi for et værdipapir, hvor renten udbetales ved papirets udløb +PV = NV ## Returnerer den nuværende værdi af en investering +RATE = RENTE ## Returnerer renten i hver periode for en annuitet +RECEIVED = MODTAGET.VED.UDLØB ## Returnerer det beløb, der modtages ved udløbet af et fuldt ud investeret værdipapir +SLN = LA ## Returnerer den lineære afskrivning for et aktiv i en enkelt periode +SYD = ÅRSAFSKRIVNING ## Returnerer den årlige afskrivning på et aktiv i en bestemt periode +TBILLEQ = STATSOBLIGATION ## Returnerer det obligationsækvivalente afkast for en statsobligation +TBILLPRICE = STATSOBLIGATION.KURS ## Returnerer kursen pr. kr 100 nominel værdi for en statsobligation +TBILLYIELD = STATSOBLIGATION.AFKAST ## Returnerer en afkastet på en statsobligation +VDB = VSA ## Returnerer afskrivningen på et aktiv i en angivet periode, herunder delperioder, ved brug af dobbeltsaldometoden +XIRR = INTERN.RENTE ## Returnerer den interne rente for en plan over pengestrømme, der ikke behøver at være periodiske +XNPV = NETTO.NUTIDSVÆRDI ## Returnerer nutidsværdien for en plan over pengestrømme, der ikke behøver at være periodiske +YIELD = AFKAST ## Returnerer afkastet for et værdipapir med periodiske renteudbetalinger +YIELDDISC = AFKAST.DISKONTO ## Returnerer det årlige afkast for et diskonteret værdipapir, f.eks. en statsobligation +YIELDMAT = AFKAST.UDLØBSDATO ## Returnerer det årlige afkast for et værdipapir, hvor renten udbetales ved papirets udløb + + +## +## Information functions Informationsfunktioner +## +CELL = CELLE ## Returnerer oplysninger om formatering, placering eller indhold af en celle +ERROR.TYPE = FEJLTYPE ## Returnerer et tal, der svarer til en fejltype +INFO = INFO ## Returnerer oplysninger om det aktuelle operativmiljø +ISBLANK = ER.TOM ## Returnerer SAND, hvis værdien er tom +ISERR = ER.FJL ## Returnerer SAND, hvis værdien er en fejlværdi undtagen #I/T +ISERROR = ER.FEJL ## Returnerer SAND, hvis værdien er en fejlværdi +ISEVEN = ER.LIGE ## Returnerer SAND, hvis tallet er lige +ISLOGICAL = ER.LOGISK ## Returnerer SAND, hvis værdien er en logisk værdi +ISNA = ER.IKKE.TILGÆNGELIG ## Returnerer SAND, hvis værdien er fejlværdien #I/T +ISNONTEXT = ER.IKKE.TEKST ## Returnerer SAND, hvis værdien ikke er tekst +ISNUMBER = ER.TAL ## Returnerer SAND, hvis værdien er et tal +ISODD = ER.ULIGE ## Returnerer SAND, hvis tallet er ulige +ISREF = ER.REFERENCE ## Returnerer SAND, hvis værdien er en reference +ISTEXT = ER.TEKST ## Returnerer SAND, hvis værdien er tekst +N = TAL ## Returnerer en værdi konverteret til et tal +NA = IKKE.TILGÆNGELIG ## Returnerer fejlværdien #I/T +TYPE = VÆRDITYPE ## Returnerer et tal, der angiver datatypen for en værdi + + +## +## Logical functions Logiske funktioner +## +AND = OG ## Returnerer SAND, hvis alle argumenterne er sande +FALSE = FALSK ## Returnerer den logiske værdi FALSK +IF = HVIS ## Angiver en logisk test, der skal udføres +IFERROR = HVIS.FEJL ## Returnerer en værdi, du angiver, hvis en formel evauleres som en fejl. Returnerer i modsat fald resultatet af formlen +NOT = IKKE ## Vender argumentets logik om +OR = ELLER ## Returneret værdien SAND, hvis mindst ét argument er sandt +TRUE = SAND ## Returnerer den logiske værdi SAND + + +## +## Lookup and reference functions Opslags- og referencefunktioner +## +ADDRESS = ADRESSE ## Returnerer en reference som tekst til en enkelt celle i et regneark +AREAS = OMRÅDER ## Returnerer antallet af områder i en reference +CHOOSE = VÆLG ## Vælger en værdi på en liste med værdier +COLUMN = KOLONNE ## Returnerer kolonnenummeret i en reference +COLUMNS = KOLONNER ## Returnerer antallet af kolonner i en reference +HLOOKUP = VOPSLAG ## Søger i den øverste række af en matrix og returnerer værdien af den angivne celle +HYPERLINK = HYPERLINK ## Opretter en genvej kaldet et hyperlink, der åbner et dokument, som er lagret på en netværksserver, på et intranet eller på internettet +INDEX = INDEKS ## Anvender et indeks til at vælge en værdi fra en reference eller en matrix +INDIRECT = INDIREKTE ## Returnerer en reference, der er angivet af en tekstværdi +LOOKUP = SLÅ.OP ## Søger værdier i en vektor eller en matrix +MATCH = SAMMENLIGN ## Søger værdier i en reference eller en matrix +OFFSET = FORSKYDNING ## Returnerer en reference forskudt i forhold til en given reference +ROW = RÆKKE ## Returnerer rækkenummeret for en reference +ROWS = RÆKKER ## Returnerer antallet af rækker i en reference +RTD = RTD ## Henter realtidsdata fra et program, der understøtter COM-automatisering (Automation: En metode til at arbejde med objekter fra et andet program eller udviklingsværktøj. Automation, som tidligere blev kaldt OLE Automation, er en industristandard og en funktion i COM (Component Object Model).) +TRANSPOSE = TRANSPONER ## Returnerer en transponeret matrix +VLOOKUP = LOPSLAG ## Søger i øverste række af en matrix og flytter på tværs af rækken for at returnere en celleværdi + + +## +## Math and trigonometry functions Matematiske og trigonometriske funktioner +## +ABS = ABS ## Returnerer den absolutte værdi af et tal +ACOS = ARCCOS ## Returnerer et tals arcus cosinus +ACOSH = ARCCOSH ## Returnerer den inverse hyperbolske cosinus af tal +ASIN = ARCSIN ## Returnerer et tals arcus sinus +ASINH = ARCSINH ## Returnerer den inverse hyperbolske sinus for tal +ATAN = ARCTAN ## Returnerer et tals arcus tangens +ATAN2 = ARCTAN2 ## Returnerer de angivne x- og y-koordinaters arcus tangens +ATANH = ARCTANH ## Returnerer et tals inverse hyperbolske tangens +CEILING = AFRUND.LOFT ## Afrunder et tal til nærmeste heltal eller til nærmeste multiplum af betydning +COMBIN = KOMBIN ## Returnerer antallet af kombinationer for et givet antal objekter +COS = COS ## Returnerer et tals cosinus +COSH = COSH ## Returnerer den inverse hyperbolske cosinus af et tal +DEGREES = GRADER ## Konverterer radianer til grader +EVEN = LIGE ## Runder et tal op til nærmeste lige heltal +EXP = EKSP ## Returnerer e opløftet til en potens af et angivet tal +FACT = FAKULTET ## Returnerer et tals fakultet +FACTDOUBLE = DOBBELT.FAKULTET ## Returnerer et tals dobbelte fakultet +FLOOR = AFRUND.GULV ## Runder et tal ned mod nul +GCD = STØRSTE.FÆLLES.DIVISOR ## Returnerer den største fælles divisor +INT = HELTAL ## Nedrunder et tal til det nærmeste heltal +LCM = MINDSTE.FÆLLES.MULTIPLUM ## Returnerer det mindste fælles multiplum +LN = LN ## Returnerer et tals naturlige logaritme +LOG = LOG ## Returnerer logaritmen for et tal på grundlag af et angivet grundtal +LOG10 = LOG10 ## Returnerer titalslogaritmen af et tal +MDETERM = MDETERM ## Returnerer determinanten for en matrix +MINVERSE = MINVERT ## Returnerer den inverse matrix for en matrix +MMULT = MPRODUKT ## Returnerer matrixproduktet af to matrixer +MOD = REST ## Returnerer restværdien fra division +MROUND = MAFRUND ## Returnerer et tal afrundet til det ønskede multiplum +MULTINOMIAL = MULTINOMIAL ## Returnerer et multinomialt talsæt +ODD = ULIGE ## Runder et tal op til nærmeste ulige heltal +PI = PI ## Returnerer værdien af pi +POWER = POTENS ## Returnerer resultatet af et tal opløftet til en potens +PRODUCT = PRODUKT ## Multiplicerer argumenterne +QUOTIENT = KVOTIENT ## Returnerer heltalsdelen ved division +RADIANS = RADIANER ## Konverterer grader til radianer +RAND = SLUMP ## Returnerer et tilfældigt tal mellem 0 og 1 +RANDBETWEEN = SLUMP.MELLEM ## Returnerer et tilfældigt tal mellem de tal, der angives +ROMAN = ROMERTAL ## Konverterer et arabertal til romertal som tekst +ROUND = AFRUND ## Afrunder et tal til et angivet antal decimaler +ROUNDDOWN = RUND.NED ## Runder et tal ned mod nul +ROUNDUP = RUND.OP ## Runder et tal op, væk fra 0 (nul) +SERIESSUM = SERIESUM ## Returnerer summen af en potensserie baseret på en formel +SIGN = FORTEGN ## Returnerer et tals fortegn +SIN = SIN ## Returnerer en given vinkels sinusværdi +SINH = SINH ## Returnerer den hyperbolske sinus af et tal +SQRT = KVROD ## Returnerer en positiv kvadratrod +SQRTPI = KVRODPI ## Returnerer kvadratroden af (tal * pi;) +SUBTOTAL = SUBTOTAL ## Returnerer en subtotal på en liste eller i en database +SUM = SUM ## Lægger argumenterne sammen +SUMIF = SUM.HVIS ## Lægger de celler sammen, der er specificeret af et givet kriterium. +SUMIFS = SUM.HVISER ## Lægger de celler i et område sammen, der opfylder flere kriterier. +SUMPRODUCT = SUMPRODUKT ## Returnerer summen af produkter af ens matrixkomponenter +SUMSQ = SUMKV ## Returnerer summen af argumenternes kvadrater +SUMX2MY2 = SUMX2MY2 ## Returnerer summen af differensen mellem kvadrater af ens værdier i to matrixer +SUMX2PY2 = SUMX2PY2 ## Returnerer summen af summen af kvadrater af tilsvarende værdier i to matrixer +SUMXMY2 = SUMXMY2 ## Returnerer summen af kvadrater af differenser mellem ens værdier i to matrixer +TAN = TAN ## Returnerer et tals tangens +TANH = TANH ## Returnerer et tals hyperbolske tangens +TRUNC = AFKORT ## Afkorter et tal til et heltal + + +## +## Statistical functions Statistiske funktioner +## +AVEDEV = MAD ## Returnerer den gennemsnitlige numeriske afvigelse fra stikprøvens middelværdi +AVERAGE = MIDDEL ## Returnerer middelværdien af argumenterne +AVERAGEA = MIDDELV ## Returnerer middelværdien af argumenterne og medtager tal, tekst og logiske værdier +AVERAGEIF = MIDDEL.HVIS ## Returnerer gennemsnittet (den aritmetiske middelværdi) af alle de celler, der opfylder et givet kriterium, i et område +AVERAGEIFS = MIDDEL.HVISER ## Returnerer gennemsnittet (den aritmetiske middelværdi) af alle de celler, der opfylder flere kriterier. +BETADIST = BETAFORDELING ## Returnerer den kumulative betafordelingsfunktion +BETAINV = BETAINV ## Returnerer den inverse kumulative fordelingsfunktion for en angivet betafordeling +BINOMDIST = BINOMIALFORDELING ## Returnerer punktsandsynligheden for binomialfordelingen +CHIDIST = CHIFORDELING ## Returnerer fraktilsandsynligheden for en chi2-fordeling +CHIINV = CHIINV ## Returnerer den inverse fraktilsandsynlighed for en chi2-fordeling +CHITEST = CHITEST ## Foretager en test for uafhængighed +CONFIDENCE = KONFIDENSINTERVAL ## Returnerer et konfidensinterval for en population +CORREL = KORRELATION ## Returnerer korrelationskoefficienten mellem to datasæt +COUNT = TÆL ## Tæller antallet af tal på en liste med argumenter +COUNTA = TÆLV ## Tæller antallet af værdier på en liste med argumenter +COUNTBLANK = ANTAL.BLANKE ## Tæller antallet af tomme celler i et område +COUNTIF = TÆLHVIS ## Tæller antallet af celler, som opfylder de givne kriterier, i et område +COUNTIFS = TÆL.HVISER ## Tæller antallet af de celler, som opfylder flere kriterier, i et område +COVAR = KOVARIANS ## Beregner kovariansen mellem to stokastiske variabler +CRITBINOM = KRITBINOM ## Returnerer den mindste værdi for x, for hvilken det gælder, at fordelingsfunktionen er mindre end eller lig med kriterieværdien. +DEVSQ = SAK ## Returnerer summen af de kvadrerede afvigelser fra middelværdien +EXPONDIST = EKSPFORDELING ## Returnerer eksponentialfordelingen +FDIST = FFORDELING ## Returnerer fraktilsandsynligheden for F-fordelingen +FINV = FINV ## Returnerer den inverse fraktilsandsynlighed for F-fordelingen +FISHER = FISHER ## Returnerer Fisher-transformationen +FISHERINV = FISHERINV ## Returnerer den inverse Fisher-transformation +FORECAST = PROGNOSE ## Returnerer en prognoseværdi baseret på lineær tendens +FREQUENCY = FREKVENS ## Returnerer en frekvensfordeling i en søjlevektor +FTEST = FTEST ## Returnerer resultatet af en F-test til sammenligning af varians +GAMMADIST = GAMMAFORDELING ## Returnerer fordelingsfunktionen for gammafordelingen +GAMMAINV = GAMMAINV ## Returnerer den inverse fordelingsfunktion for gammafordelingen +GAMMALN = GAMMALN ## Returnerer den naturlige logaritme til gammafordelingen, G(x) +GEOMEAN = GEOMIDDELVÆRDI ## Returnerer det geometriske gennemsnit +GROWTH = FORØGELSE ## Returnerer værdier langs en eksponentiel tendens +HARMEAN = HARMIDDELVÆRDI ## Returnerer det harmoniske gennemsnit +HYPGEOMDIST = HYPGEOFORDELING ## Returnerer punktsandsynligheden i en hypergeometrisk fordeling +INTERCEPT = SKÆRING ## Returnerer afskæringsværdien på y-aksen i en lineær regression +KURT = TOPSTEJL ## Returnerer kurtosisværdien for en stokastisk variabel +LARGE = STOR ## Returnerer den k'te største værdi i et datasæt +LINEST = LINREGR ## Returnerer parameterestimaterne for en lineær tendens +LOGEST = LOGREGR ## Returnerer parameterestimaterne for en eksponentiel tendens +LOGINV = LOGINV ## Returnerer den inverse fordelingsfunktion for lognormalfordelingen +LOGNORMDIST = LOGNORMFORDELING ## Returnerer fordelingsfunktionen for lognormalfordelingen +MAX = MAKS ## Returnerer den maksimale værdi på en liste med argumenter. +MAXA = MAKSV ## Returnerer den maksimale værdi på en liste med argumenter og medtager tal, tekst og logiske værdier +MEDIAN = MEDIAN ## Returnerer medianen for de angivne tal +MIN = MIN ## Returnerer den mindste værdi på en liste med argumenter. +MINA = MINV ## Returnerer den mindste værdi på en liste med argumenter og medtager tal, tekst og logiske værdier +MODE = HYPPIGST ## Returnerer den hyppigste værdi i et datasæt +NEGBINOMDIST = NEGBINOMFORDELING ## Returnerer den negative binomialfordeling +NORMDIST = NORMFORDELING ## Returnerer fordelingsfunktionen for normalfordelingen +NORMINV = NORMINV ## Returnerer den inverse fordelingsfunktion for normalfordelingen +NORMSDIST = STANDARDNORMFORDELING ## Returnerer fordelingsfunktionen for standardnormalfordelingen +NORMSINV = STANDARDNORMINV ## Returnerer den inverse fordelingsfunktion for standardnormalfordelingen +PEARSON = PEARSON ## Returnerer Pearsons korrelationskoefficient +PERCENTILE = FRAKTIL ## Returnerer den k'te fraktil for datasættet +PERCENTRANK = PROCENTPLADS ## Returnerer den procentuelle rang for en given værdi i et datasæt +PERMUT = PERMUT ## Returnerer antallet af permutationer for et givet sæt objekter +POISSON = POISSON ## Returnerer fordelingsfunktionen for en Poisson-fordeling +PROB = SANDSYNLIGHED ## Returnerer intervalsandsynligheden +QUARTILE = KVARTIL ## Returnerer kvartilen i et givet datasæt +RANK = PLADS ## Returnerer rangen for et tal på en liste med tal +RSQ = FORKLARINGSGRAD ## Returnerer R2-værdien fra en simpel lineær regression +SKEW = SKÆVHED ## Returnerer skævheden for en stokastisk variabel +SLOPE = HÆLDNING ## Returnerer estimatet på hældningen fra en simpel lineær regression +SMALL = MINDSTE ## Returnerer den k'te mindste værdi i datasættet +STANDARDIZE = STANDARDISER ## Returnerer en standardiseret værdi +STDEV = STDAFV ## Estimerer standardafvigelsen på basis af en stikprøve +STDEVA = STDAFVV ## Beregner standardafvigelsen på basis af en prøve og medtager tal, tekst og logiske værdier +STDEVP = STDAFVP ## Beregner standardafvigelsen på basis af en hel population +STDEVPA = STDAFVPV ## Beregner standardafvigelsen på basis af en hel population og medtager tal, tekst og logiske værdier +STEYX = STFYX ## Returnerer standardafvigelsen for de estimerede y-værdier i den simple lineære regression +TDIST = TFORDELING ## Returnerer fordelingsfunktionen for Student's t-fordeling +TINV = TINV ## Returnerer den inverse fordelingsfunktion for Student's t-fordeling +TREND = TENDENS ## Returnerer værdi under antagelse af en lineær tendens +TRIMMEAN = TRIMMIDDELVÆRDI ## Returnerer den trimmede middelværdi for datasættet +TTEST = TTEST ## Returnerer den sandsynlighed, der er forbundet med Student's t-test +VAR = VARIANS ## Beregner variansen på basis af en prøve +VARA = VARIANSV ## Beregner variansen på basis af en prøve og medtager tal, tekst og logiske værdier +VARP = VARIANSP ## Beregner variansen på basis af hele populationen +VARPA = VARIANSPV ## Beregner variansen på basis af hele populationen og medtager tal, tekst og logiske værdier +WEIBULL = WEIBULL ## Returnerer fordelingsfunktionen for Weibull-fordelingen +ZTEST = ZTEST ## Returnerer sandsynlighedsværdien ved en en-sidet z-test + + +## +## Text functions Tekstfunktioner +## +ASC = ASC ## Ændrer engelske tegn i fuld bredde (dobbelt-byte) eller katakana i en tegnstreng til tegn i halv bredde (enkelt-byte) +BAHTTEXT = BAHTTEKST ## Konverterer et tal til tekst ved hjælp af valutaformatet ß (baht) +CHAR = TEGN ## Returnerer det tegn, der svarer til kodenummeret +CLEAN = RENS ## Fjerner alle tegn, der ikke kan udskrives, fra tekst +CODE = KODE ## Returnerer en numerisk kode for det første tegn i en tekststreng +CONCATENATE = SAMMENKÆDNING ## Sammenkæder adskillige tekstelementer til ét tekstelement +DOLLAR = KR ## Konverterer et tal til tekst ved hjælp af valutaformatet kr. (kroner) +EXACT = EKSAKT ## Kontrollerer, om to tekstværdier er identiske +FIND = FIND ## Søger efter en tekstværdi i en anden tekstværdi (der skelnes mellem store og små bogstaver) +FINDB = FINDB ## Søger efter en tekstværdi i en anden tekstværdi (der skelnes mellem store og små bogstaver) +FIXED = FAST ## Formaterer et tal som tekst med et fast antal decimaler +JIS = JIS ## Ændrer engelske tegn i halv bredde (enkelt-byte) eller katakana i en tegnstreng til tegn i fuld bredde (dobbelt-byte) +LEFT = VENSTRE ## Returnerer tegnet længst til venstre i en tekstværdi +LEFTB = VENSTREB ## Returnerer tegnet længst til venstre i en tekstværdi +LEN = LÆNGDE ## Returnerer antallet af tegn i en tekststreng +LENB = LÆNGDEB ## Returnerer antallet af tegn i en tekststreng +LOWER = SMÅ.BOGSTAVER ## Konverterer tekst til små bogstaver +MID = MIDT ## Returnerer et bestemt antal tegn fra en tekststreng fra og med den angivne startposition +MIDB = MIDTB ## Returnerer et bestemt antal tegn fra en tekststreng fra og med den angivne startposition +PHONETIC = FONETISK ## Uddrager de fonetiske (furigana) tegn fra en tekststreng +PROPER = STORT.FORBOGSTAV ## Konverterer første bogstav i hvert ord i teksten til stort bogstav +REPLACE = ERSTAT ## Erstatter tegn i tekst +REPLACEB = ERSTATB ## Erstatter tegn i tekst +REPT = GENTAG ## Gentager tekst et givet antal gange +RIGHT = HØJRE ## Returnerer tegnet længste til højre i en tekstværdi +RIGHTB = HØJREB ## Returnerer tegnet længste til højre i en tekstværdi +SEARCH = SØG ## Søger efter en tekstværdi i en anden tekstværdi (der skelnes ikke mellem store og små bogstaver) +SEARCHB = SØGB ## Søger efter en tekstværdi i en anden tekstværdi (der skelnes ikke mellem store og små bogstaver) +SUBSTITUTE = UDSKIFT ## Udskifter gammel tekst med ny tekst i en tekststreng +T = T ## Konverterer argumenterne til tekst +TEXT = TEKST ## Formaterer et tal og konverterer det til tekst +TRIM = FJERN.OVERFLØDIGE.BLANKE ## Fjerner mellemrum fra tekst +UPPER = STORE.BOGSTAVER ## Konverterer tekst til store bogstaver +VALUE = VÆRDI ## Konverterer et tekstargument til et tal diff --git a/lib/phpexcel/PHPExcel/locale/de/config b/lib/phpexcel/PHPExcel/locale/de/config new file mode 100644 index 0000000..c997275 --- /dev/null +++ b/lib/phpexcel/PHPExcel/locale/de/config @@ -0,0 +1,47 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Settings +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## + + +ArgumentSeparator = ; + + +## +## (For future use) +## +currencySymbol = € + + +## +## Excel Error Codes (For future use) +## +NULL = #NULL! +DIV0 = #DIV/0! +VALUE = #WERT! +REF = #BEZUG! +NAME = #NAME? +NUM = #ZAHL! +NA = #NV diff --git a/lib/phpexcel/PHPExcel/locale/de/functions b/lib/phpexcel/PHPExcel/locale/de/functions new file mode 100644 index 0000000..8ce08de --- /dev/null +++ b/lib/phpexcel/PHPExcel/locale/de/functions @@ -0,0 +1,438 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Calculation +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## Data in this file derived from http://www.piuha.fi/excel-function-name-translation/ +## +## + + +## +## Add-in and Automation functions Add-In- und Automatisierungsfunktionen +## +GETPIVOTDATA = PIVOTDATENZUORDNEN ## In einem PivotTable-Bericht gespeicherte Daten werden zurückgegeben. + + +## +## Cube functions Cubefunktionen +## +CUBEKPIMEMBER = CUBEKPIELEMENT ## Gibt Name, Eigenschaft und Measure eines Key Performance Indicators (KPI) zurück und zeigt den Namen und die Eigenschaft in der Zelle an. Ein KPI ist ein quantifizierbares Maß, wie z. B. der monatliche Bruttogewinn oder die vierteljährliche Mitarbeiterfluktuation, mit dessen Hilfe das Leistungsverhalten eines Unternehmens überwacht werden kann. +CUBEMEMBER = CUBEELEMENT ## Gibt ein Element oder ein Tuple in einer Cubehierarchie zurück. Wird verwendet, um zu überprüfen, ob das Element oder Tuple im Cube vorhanden ist. +CUBEMEMBERPROPERTY = CUBEELEMENTEIGENSCHAFT ## Gibt den Wert einer Elementeigenschaft im Cube zurück. Wird verwendet, um zu überprüfen, ob ein Elementname im Cube vorhanden ist, und um die für dieses Element angegebene Eigenschaft zurückzugeben. +CUBERANKEDMEMBER = CUBERANGELEMENT ## Gibt das n-te oder n-rangige Element in einer Menge zurück. Wird verwendet, um mindestens ein Element in einer Menge zurückzugeben, wie z. B. bester Vertriebsmitarbeiter oder 10 beste Kursteilnehmer. +CUBESET = CUBEMENGE ## Definiert eine berechnete Menge Elemente oder Tuples durch Senden eines Mengenausdrucks an den Cube auf dem Server, der die Menge erstellt und an Microsoft Office Excel zurückgibt. +CUBESETCOUNT = CUBEMENGENANZAHL ## Gibt die Anzahl der Elemente in einer Menge zurück. +CUBEVALUE = CUBEWERT ## Gibt einen Aggregatwert aus einem Cube zurück. + + +## +## Database functions Datenbankfunktionen +## +DAVERAGE = DBMITTELWERT ## Gibt den Mittelwert der ausgewählten Datenbankeinträge zurück +DCOUNT = DBANZAHL ## Zählt die Zellen mit Zahlen in einer Datenbank +DCOUNTA = DBANZAHL2 ## Zählt nicht leere Zellen in einer Datenbank +DGET = DBAUSZUG ## Extrahiert aus einer Datenbank einen einzelnen Datensatz, der den angegebenen Kriterien entspricht +DMAX = DBMAX ## Gibt den größten Wert aus ausgewählten Datenbankeinträgen zurück +DMIN = DBMIN ## Gibt den kleinsten Wert aus ausgewählten Datenbankeinträgen zurück +DPRODUCT = DBPRODUKT ## Multipliziert die Werte in einem bestimmten Feld mit Datensätzen, die den Kriterien in einer Datenbank entsprechen +DSTDEV = DBSTDABW ## Schätzt die Standardabweichung auf der Grundlage einer Stichprobe aus ausgewählten Datenbankeinträgen +DSTDEVP = DBSTDABWN ## Berechnet die Standardabweichung auf der Grundlage der Grundgesamtheit ausgewählter Datenbankeinträge +DSUM = DBSUMME ## Addiert die Zahlen in der Feldspalte mit Datensätzen in der Datenbank, die den Kriterien entsprechen +DVAR = DBVARIANZ ## Schätzt die Varianz auf der Grundlage ausgewählter Datenbankeinträge +DVARP = DBVARIANZEN ## Berechnet die Varianz auf der Grundlage der Grundgesamtheit ausgewählter Datenbankeinträge + + +## +## Date and time functions Datums- und Zeitfunktionen +## +DATE = DATUM ## Gibt die fortlaufende Zahl eines bestimmten Datums zurück +DATEVALUE = DATWERT ## Wandelt ein Datum in Form von Text in eine fortlaufende Zahl um +DAY = TAG ## Wandelt eine fortlaufende Zahl in den Tag des Monats um +DAYS360 = TAGE360 ## Berechnet die Anzahl der Tage zwischen zwei Datumsangaben ausgehend von einem Jahr, das 360 Tage hat +EDATE = EDATUM ## Gibt die fortlaufende Zahl des Datums zurück, bei dem es sich um die angegebene Anzahl von Monaten vor oder nach dem Anfangstermin handelt +EOMONTH = MONATSENDE ## Gibt die fortlaufende Zahl des letzten Tags des Monats vor oder nach einer festgelegten Anzahl von Monaten zurück +HOUR = STUNDE ## Wandelt eine fortlaufende Zahl in eine Stunde um +MINUTE = MINUTE ## Wandelt eine fortlaufende Zahl in eine Minute um +MONTH = MONAT ## Wandelt eine fortlaufende Zahl in einen Monat um +NETWORKDAYS = NETTOARBEITSTAGE ## Gibt die Anzahl von ganzen Arbeitstagen zwischen zwei Datumswerten zurück +NOW = JETZT ## Gibt die fortlaufende Zahl des aktuellen Datums und der aktuellen Uhrzeit zurück +SECOND = SEKUNDE ## Wandelt eine fortlaufende Zahl in eine Sekunde um +TIME = ZEIT ## Gibt die fortlaufende Zahl einer bestimmten Uhrzeit zurück +TIMEVALUE = ZEITWERT ## Wandelt eine Uhrzeit in Form von Text in eine fortlaufende Zahl um +TODAY = HEUTE ## Gibt die fortlaufende Zahl des heutigen Datums zurück +WEEKDAY = WOCHENTAG ## Wandelt eine fortlaufende Zahl in den Wochentag um +WEEKNUM = KALENDERWOCHE ## Wandelt eine fortlaufende Zahl in eine Zahl um, die angibt, in welche Woche eines Jahres das angegebene Datum fällt +WORKDAY = ARBEITSTAG ## Gibt die fortlaufende Zahl des Datums vor oder nach einer bestimmten Anzahl von Arbeitstagen zurück +YEAR = JAHR ## Wandelt eine fortlaufende Zahl in ein Jahr um +YEARFRAC = BRTEILJAHRE ## Gibt die Anzahl der ganzen Tage zwischen Ausgangsdatum und Enddatum in Bruchteilen von Jahren zurück + + +## +## Engineering functions Konstruktionsfunktionen +## +BESSELI = BESSELI ## Gibt die geänderte Besselfunktion In(x) zurück +BESSELJ = BESSELJ ## Gibt die Besselfunktion Jn(x) zurück +BESSELK = BESSELK ## Gibt die geänderte Besselfunktion Kn(x) zurück +BESSELY = BESSELY ## Gibt die Besselfunktion Yn(x) zurück +BIN2DEC = BININDEZ ## Wandelt eine binäre Zahl (Dualzahl) in eine dezimale Zahl um +BIN2HEX = BININHEX ## Wandelt eine binäre Zahl (Dualzahl) in eine hexadezimale Zahl um +BIN2OCT = BININOKT ## Wandelt eine binäre Zahl (Dualzahl) in eine oktale Zahl um +COMPLEX = KOMPLEXE ## Wandelt den Real- und Imaginärteil in eine komplexe Zahl um +CONVERT = UMWANDELN ## Wandelt eine Zahl von einem Maßsystem in ein anderes um +DEC2BIN = DEZINBIN ## Wandelt eine dezimale Zahl in eine binäre Zahl (Dualzahl) um +DEC2HEX = DEZINHEX ## Wandelt eine dezimale Zahl in eine hexadezimale Zahl um +DEC2OCT = DEZINOKT ## Wandelt eine dezimale Zahl in eine oktale Zahl um +DELTA = DELTA ## Überprüft, ob zwei Werte gleich sind +ERF = GAUSSFEHLER ## Gibt die Gauss'sche Fehlerfunktion zurück +ERFC = GAUSSFKOMPL ## Gibt das Komplement zur Gauss'schen Fehlerfunktion zurück +GESTEP = GGANZZAHL ## Überprüft, ob eine Zahl größer als ein gegebener Schwellenwert ist +HEX2BIN = HEXINBIN ## Wandelt eine hexadezimale Zahl in eine Binärzahl um +HEX2DEC = HEXINDEZ ## Wandelt eine hexadezimale Zahl in eine dezimale Zahl um +HEX2OCT = HEXINOKT ## Wandelt eine hexadezimale Zahl in eine Oktalzahl um +IMABS = IMABS ## Gibt den Absolutbetrag (Modulo) einer komplexen Zahl zurück +IMAGINARY = IMAGINÄRTEIL ## Gibt den Imaginärteil einer komplexen Zahl zurück +IMARGUMENT = IMARGUMENT ## Gibt das Argument Theta zurück, einen Winkel, der als Bogenmaß ausgedrückt wird +IMCONJUGATE = IMKONJUGIERTE ## Gibt die konjugierte komplexe Zahl zu einer komplexen Zahl zurück +IMCOS = IMCOS ## Gibt den Kosinus einer komplexen Zahl zurück +IMDIV = IMDIV ## Gibt den Quotienten zweier komplexer Zahlen zurück +IMEXP = IMEXP ## Gibt die algebraische Form einer in exponentieller Schreibweise vorliegenden komplexen Zahl zurück +IMLN = IMLN ## Gibt den natürlichen Logarithmus einer komplexen Zahl zurück +IMLOG10 = IMLOG10 ## Gibt den Logarithmus einer komplexen Zahl zur Basis 10 zurück +IMLOG2 = IMLOG2 ## Gibt den Logarithmus einer komplexen Zahl zur Basis 2 zurück +IMPOWER = IMAPOTENZ ## Potenziert eine komplexe Zahl mit einer ganzen Zahl +IMPRODUCT = IMPRODUKT ## Gibt das Produkt von komplexen Zahlen zurück +IMREAL = IMREALTEIL ## Gibt den Realteil einer komplexen Zahl zurück +IMSIN = IMSIN ## Gibt den Sinus einer komplexen Zahl zurück +IMSQRT = IMWURZEL ## Gibt die Quadratwurzel einer komplexen Zahl zurück +IMSUB = IMSUB ## Gibt die Differenz zwischen zwei komplexen Zahlen zurück +IMSUM = IMSUMME ## Gibt die Summe von komplexen Zahlen zurück +OCT2BIN = OKTINBIN ## Wandelt eine oktale Zahl in eine binäre Zahl (Dualzahl) um +OCT2DEC = OKTINDEZ ## Wandelt eine oktale Zahl in eine dezimale Zahl um +OCT2HEX = OKTINHEX ## Wandelt eine oktale Zahl in eine hexadezimale Zahl um + + +## +## Financial functions Finanzmathematische Funktionen +## +ACCRINT = AUFGELZINS ## Gibt die aufgelaufenen Zinsen (Stückzinsen) eines Wertpapiers mit periodischen Zinszahlungen zurück +ACCRINTM = AUFGELZINSF ## Gibt die aufgelaufenen Zinsen (Stückzinsen) eines Wertpapiers zurück, die bei Fälligkeit ausgezahlt werden +AMORDEGRC = AMORDEGRK ## Gibt die Abschreibung für die einzelnen Abschreibungszeiträume mithilfe eines Abschreibungskoeffizienten zurück +AMORLINC = AMORLINEARK ## Gibt die Abschreibung für die einzelnen Abschreibungszeiträume zurück +COUPDAYBS = ZINSTERMTAGVA ## Gibt die Anzahl der Tage vom Anfang des Zinstermins bis zum Abrechnungstermin zurück +COUPDAYS = ZINSTERMTAGE ## Gibt die Anzahl der Tage der Zinsperiode zurück, die den Abrechnungstermin einschließt +COUPDAYSNC = ZINSTERMTAGNZ ## Gibt die Anzahl der Tage vom Abrechnungstermin bis zum nächsten Zinstermin zurück +COUPNCD = ZINSTERMNZ ## Gibt das Datum des ersten Zinstermins nach dem Abrechnungstermin zurück +COUPNUM = ZINSTERMZAHL ## Gibt die Anzahl der Zinstermine zwischen Abrechnungs- und Fälligkeitsdatum zurück +COUPPCD = ZINSTERMVZ ## Gibt das Datum des letzten Zinstermins vor dem Abrechnungstermin zurück +CUMIPMT = KUMZINSZ ## Berechnet die kumulierten Zinsen, die zwischen zwei Perioden zu zahlen sind +CUMPRINC = KUMKAPITAL ## Berechnet die aufgelaufene Tilgung eines Darlehens, die zwischen zwei Perioden zu zahlen ist +DB = GDA2 ## Gibt die geometrisch-degressive Abschreibung eines Wirtschaftsguts für eine bestimmte Periode zurück +DDB = GDA ## Gibt die Abschreibung eines Anlageguts für einen angegebenen Zeitraum unter Verwendung der degressiven Doppelraten-Abschreibung oder eines anderen von Ihnen angegebenen Abschreibungsverfahrens zurück +DISC = DISAGIO ## Gibt den in Prozent ausgedrückten Abzinsungssatz eines Wertpapiers zurück +DOLLARDE = NOTIERUNGDEZ ## Wandelt eine Notierung, die als Dezimalbruch ausgedrückt wurde, in eine Dezimalzahl um +DOLLARFR = NOTIERUNGBRU ## Wandelt eine Notierung, die als Dezimalzahl ausgedrückt wurde, in einen Dezimalbruch um +DURATION = DURATION ## Gibt die jährliche Duration eines Wertpapiers mit periodischen Zinszahlungen zurück +EFFECT = EFFEKTIV ## Gibt die jährliche Effektivverzinsung zurück +FV = ZW ## Gibt den zukünftigen Wert (Endwert) einer Investition zurück +FVSCHEDULE = ZW2 ## Gibt den aufgezinsten Wert des Anfangskapitals für eine Reihe periodisch unterschiedlicher Zinssätze zurück +INTRATE = ZINSSATZ ## Gibt den Zinssatz eines voll investierten Wertpapiers zurück +IPMT = ZINSZ ## Gibt die Zinszahlung einer Investition für die angegebene Periode zurück +IRR = IKV ## Gibt den internen Zinsfuß einer Investition ohne Finanzierungskosten oder Reinvestitionsgewinne zurück +ISPMT = ISPMT ## Berechnet die während eines bestimmten Zeitraums für eine Investition gezahlten Zinsen +MDURATION = MDURATION ## Gibt die geänderte Dauer für ein Wertpapier mit einem angenommenen Nennwert von 100 € zurück +MIRR = QIKV ## Gibt den internen Zinsfuß zurück, wobei positive und negative Zahlungen zu unterschiedlichen Sätzen finanziert werden +NOMINAL = NOMINAL ## Gibt die jährliche Nominalverzinsung zurück +NPER = ZZR ## Gibt die Anzahl der Zahlungsperioden einer Investition zurück +NPV = NBW ## Gibt den Nettobarwert einer Investition auf Basis periodisch anfallender Zahlungen und eines Abzinsungsfaktors zurück +ODDFPRICE = UNREGER.KURS ## Gibt den Kurs pro 100 € Nennwert eines Wertpapiers mit einem unregelmäßigen ersten Zinstermin zurück +ODDFYIELD = UNREGER.REND ## Gibt die Rendite eines Wertpapiers mit einem unregelmäßigen ersten Zinstermin zurück +ODDLPRICE = UNREGLE.KURS ## Gibt den Kurs pro 100 € Nennwert eines Wertpapiers mit einem unregelmäßigen letzten Zinstermin zurück +ODDLYIELD = UNREGLE.REND ## Gibt die Rendite eines Wertpapiers mit einem unregelmäßigen letzten Zinstermin zurück +PMT = RMZ ## Gibt die periodische Zahlung für eine Annuität zurück +PPMT = KAPZ ## Gibt die Kapitalrückzahlung einer Investition für eine angegebene Periode zurück +PRICE = KURS ## Gibt den Kurs pro 100 € Nennwert eines Wertpapiers zurück, das periodisch Zinsen auszahlt +PRICEDISC = KURSDISAGIO ## Gibt den Kurs pro 100 € Nennwert eines unverzinslichen Wertpapiers zurück +PRICEMAT = KURSFÄLLIG ## Gibt den Kurs pro 100 € Nennwert eines Wertpapiers zurück, das Zinsen am Fälligkeitsdatum auszahlt +PV = BW ## Gibt den Barwert einer Investition zurück +RATE = ZINS ## Gibt den Zinssatz pro Zeitraum einer Annuität zurück +RECEIVED = AUSZAHLUNG ## Gibt den Auszahlungsbetrag eines voll investierten Wertpapiers am Fälligkeitstermin zurück +SLN = LIA ## Gibt die lineare Abschreibung eines Wirtschaftsguts pro Periode zurück +SYD = DIA ## Gibt die arithmetisch-degressive Abschreibung eines Wirtschaftsguts für eine bestimmte Periode zurück +TBILLEQ = TBILLÄQUIV ## Gibt die Rendite für ein Wertpapier zurück +TBILLPRICE = TBILLKURS ## Gibt den Kurs pro 100 € Nennwert eines Wertpapiers zurück +TBILLYIELD = TBILLRENDITE ## Gibt die Rendite für ein Wertpapier zurück +VDB = VDB ## Gibt die degressive Abschreibung eines Wirtschaftsguts für eine bestimmte Periode oder Teilperiode zurück +XIRR = XINTZINSFUSS ## Gibt den internen Zinsfuß einer Reihe nicht periodisch anfallender Zahlungen zurück +XNPV = XKAPITALWERT ## Gibt den Nettobarwert (Kapitalwert) einer Reihe nicht periodisch anfallender Zahlungen zurück +YIELD = RENDITE ## Gibt die Rendite eines Wertpapiers zurück, das periodisch Zinsen auszahlt +YIELDDISC = RENDITEDIS ## Gibt die jährliche Rendite eines unverzinslichen Wertpapiers zurück +YIELDMAT = RENDITEFÄLL ## Gibt die jährliche Rendite eines Wertpapiers zurück, das Zinsen am Fälligkeitsdatum auszahlt + + +## +## Information functions Informationsfunktionen +## +CELL = ZELLE ## Gibt Informationen zu Formatierung, Position oder Inhalt einer Zelle zurück +ERROR.TYPE = FEHLER.TYP ## Gibt eine Zahl zurück, die einem Fehlertyp entspricht +INFO = INFO ## Gibt Informationen zur aktuellen Betriebssystemumgebung zurück +ISBLANK = ISTLEER ## Gibt WAHR zurück, wenn der Wert leer ist +ISERR = ISTFEHL ## Gibt WAHR zurück, wenn der Wert ein beliebiger Fehlerwert außer #N/V ist +ISERROR = ISTFEHLER ## Gibt WAHR zurück, wenn der Wert ein beliebiger Fehlerwert ist +ISEVEN = ISTGERADE ## Gibt WAHR zurück, wenn es sich um eine gerade Zahl handelt +ISLOGICAL = ISTLOG ## Gibt WAHR zurück, wenn der Wert ein Wahrheitswert ist +ISNA = ISTNV ## Gibt WAHR zurück, wenn der Wert der Fehlerwert #N/V ist +ISNONTEXT = ISTKTEXT ## Gibt WAHR zurück, wenn der Wert ein Element ist, das keinen Text enthält +ISNUMBER = ISTZAHL ## Gibt WAHR zurück, wenn der Wert eine Zahl ist +ISODD = ISTUNGERADE ## Gibt WAHR zurück, wenn es sich um eine ungerade Zahl handelt +ISREF = ISTBEZUG ## Gibt WAHR zurück, wenn der Wert ein Bezug ist +ISTEXT = ISTTEXT ## Gibt WAHR zurück, wenn der Wert ein Element ist, das Text enthält +N = N ## Gibt den in eine Zahl umgewandelten Wert zurück +NA = NV ## Gibt den Fehlerwert #NV zurück +TYPE = TYP ## Gibt eine Zahl zurück, die den Datentyp des angegebenen Werts anzeigt + + +## +## Logical functions Logische Funktionen +## +AND = UND ## Gibt WAHR zurück, wenn alle zugehörigen Argumente WAHR sind +FALSE = FALSCH ## Gibt den Wahrheitswert FALSCH zurück +IF = WENN ## Gibt einen logischen Test zum Ausführen an +IFERROR = WENNFEHLER ## Gibt einen von Ihnen festgelegten Wert zurück, wenn die Auswertung der Formel zu einem Fehler führt; andernfalls wird das Ergebnis der Formel zurückgegeben +NOT = NICHT ## Kehrt den Wahrheitswert der zugehörigen Argumente um +OR = ODER ## Gibt WAHR zurück, wenn ein Argument WAHR ist +TRUE = WAHR ## Gibt den Wahrheitswert WAHR zurück + + +## +## Lookup and reference functions Nachschlage- und Verweisfunktionen +## +ADDRESS = ADRESSE ## Gibt einen Bezug auf eine einzelne Zelle in einem Tabellenblatt als Text zurück +AREAS = BEREICHE ## Gibt die Anzahl der innerhalb eines Bezugs aufgeführten Bereiche zurück +CHOOSE = WAHL ## Wählt einen Wert aus eine Liste mit Werten aus +COLUMN = SPALTE ## Gibt die Spaltennummer eines Bezugs zurück +COLUMNS = SPALTEN ## Gibt die Anzahl der Spalten in einem Bezug zurück +HLOOKUP = HVERWEIS ## Sucht in der obersten Zeile einer Matrix und gibt den Wert der angegebenen Zelle zurück +HYPERLINK = HYPERLINK ## Erstellt eine Verknüpfung, über die ein auf einem Netzwerkserver, in einem Intranet oder im Internet gespeichertes Dokument geöffnet wird +INDEX = INDEX ## Verwendet einen Index, um einen Wert aus einem Bezug oder einer Matrix auszuwählen +INDIRECT = INDIREKT ## Gibt einen Bezug zurück, der von einem Textwert angegeben wird +LOOKUP = LOOKUP ## Sucht Werte in einem Vektor oder einer Matrix +MATCH = VERGLEICH ## Sucht Werte in einem Bezug oder einer Matrix +OFFSET = BEREICH.VERSCHIEBEN ## Gibt einen Bezugoffset aus einem gegebenen Bezug zurück +ROW = ZEILE ## Gibt die Zeilennummer eines Bezugs zurück +ROWS = ZEILEN ## Gibt die Anzahl der Zeilen in einem Bezug zurück +RTD = RTD ## Ruft Echtzeitdaten von einem Programm ab, das die COM-Automatisierung (Automatisierung: Ein Verfahren, bei dem aus einer Anwendung oder einem Entwicklungstool heraus mit den Objekten einer anderen Anwendung gearbeitet wird. Die früher als OLE-Automatisierung bezeichnete Automatisierung ist ein Industriestandard und eine Funktion von COM (Component Object Model).) unterstützt +TRANSPOSE = MTRANS ## Gibt die transponierte Matrix einer Matrix zurück +VLOOKUP = SVERWEIS ## Sucht in der ersten Spalte einer Matrix und arbeitet sich durch die Zeile, um den Wert einer Zelle zurückzugeben + + +## +## Math and trigonometry functions Mathematische und trigonometrische Funktionen +## +ABS = ABS ## Gibt den Absolutwert einer Zahl zurück +ACOS = ARCCOS ## Gibt den Arkuskosinus einer Zahl zurück +ACOSH = ARCCOSHYP ## Gibt den umgekehrten hyperbolischen Kosinus einer Zahl zurück +ASIN = ARCSIN ## Gibt den Arkussinus einer Zahl zurück +ASINH = ARCSINHYP ## Gibt den umgekehrten hyperbolischen Sinus einer Zahl zurück +ATAN = ARCTAN ## Gibt den Arkustangens einer Zahl zurück +ATAN2 = ARCTAN2 ## Gibt den Arkustangens einer x- und einer y-Koordinate zurück +ATANH = ARCTANHYP ## Gibt den umgekehrten hyperbolischen Tangens einer Zahl zurück +CEILING = OBERGRENZE ## Rundet eine Zahl auf die nächste ganze Zahl oder das nächste Vielfache von Schritt +COMBIN = KOMBINATIONEN ## Gibt die Anzahl der Kombinationen für eine bestimmte Anzahl von Objekten zurück +COS = COS ## Gibt den Kosinus einer Zahl zurück +COSH = COSHYP ## Gibt den hyperbolischen Kosinus einer Zahl zurück +DEGREES = GRAD ## Wandelt Bogenmaß (Radiant) in Grad um +EVEN = GERADE ## Rundet eine Zahl auf die nächste gerade ganze Zahl auf +EXP = EXP ## Potenziert die Basis e mit der als Argument angegebenen Zahl +FACT = FAKULTÄT ## Gibt die Fakultät einer Zahl zurück +FACTDOUBLE = ZWEIFAKULTÄT ## Gibt die Fakultät zu Zahl mit Schrittlänge 2 zurück +FLOOR = UNTERGRENZE ## Rundet die Zahl auf Anzahl_Stellen ab +GCD = GGT ## Gibt den größten gemeinsamen Teiler zurück +INT = GANZZAHL ## Rundet eine Zahl auf die nächstkleinere ganze Zahl ab +LCM = KGV ## Gibt das kleinste gemeinsame Vielfache zurück +LN = LN ## Gibt den natürlichen Logarithmus einer Zahl zurück +LOG = LOG ## Gibt den Logarithmus einer Zahl zu der angegebenen Basis zurück +LOG10 = LOG10 ## Gibt den Logarithmus einer Zahl zur Basis 10 zurück +MDETERM = MDET ## Gibt die Determinante einer Matrix zurück +MINVERSE = MINV ## Gibt die inverse Matrix einer Matrix zurück +MMULT = MMULT ## Gibt das Produkt zweier Matrizen zurück +MOD = REST ## Gibt den Rest einer Division zurück +MROUND = VRUNDEN ## Gibt eine auf das gewünschte Vielfache gerundete Zahl zurück +MULTINOMIAL = POLYNOMIAL ## Gibt den Polynomialkoeffizienten einer Gruppe von Zahlen zurück +ODD = UNGERADE ## Rundet eine Zahl auf die nächste ungerade ganze Zahl auf +PI = PI ## Gibt den Wert Pi zurück +POWER = POTENZ ## Gibt als Ergebnis eine potenzierte Zahl zurück +PRODUCT = PRODUKT ## Multipliziert die zugehörigen Argumente +QUOTIENT = QUOTIENT ## Gibt den ganzzahligen Anteil einer Division zurück +RADIANS = BOGENMASS ## Wandelt Grad in Bogenmaß (Radiant) um +RAND = ZUFALLSZAHL ## Gibt eine Zufallszahl zwischen 0 und 1 zurück +RANDBETWEEN = ZUFALLSBEREICH ## Gibt eine Zufallszahl aus dem festgelegten Bereich zurück +ROMAN = RÖMISCH ## Wandelt eine arabische Zahl in eine römische Zahl als Text um +ROUND = RUNDEN ## Rundet eine Zahl auf eine bestimmte Anzahl von Dezimalstellen +ROUNDDOWN = ABRUNDEN ## Rundet die Zahl auf Anzahl_Stellen ab +ROUNDUP = AUFRUNDEN ## Rundet die Zahl auf Anzahl_Stellen auf +SERIESSUM = POTENZREIHE ## Gibt die Summe von Potenzen (zur Berechnung von Potenzreihen und dichotomen Wahrscheinlichkeiten) zurück +SIGN = VORZEICHEN ## Gibt das Vorzeichen einer Zahl zurück +SIN = SIN ## Gibt den Sinus einer Zahl zurück +SINH = SINHYP ## Gibt den hyperbolischen Sinus einer Zahl zurück +SQRT = WURZEL ## Gibt die Quadratwurzel einer Zahl zurück +SQRTPI = WURZELPI ## Gibt die Wurzel aus der mit Pi (pi) multiplizierten Zahl zurück +SUBTOTAL = TEILERGEBNIS ## Gibt ein Teilergebnis in einer Liste oder Datenbank zurück +SUM = SUMME ## Addiert die zugehörigen Argumente +SUMIF = SUMMEWENN ## Addiert Zahlen, die mit den Suchkriterien übereinstimmen +SUMIFS = SUMMEWENNS ## Die Zellen, die mehrere Kriterien erfüllen, werden in einem Bereich hinzugefügt +SUMPRODUCT = SUMMENPRODUKT ## Gibt die Summe der Produkte zusammengehöriger Matrixkomponenten zurück +SUMSQ = QUADRATESUMME ## Gibt die Summe der quadrierten Argumente zurück +SUMX2MY2 = SUMMEX2MY2 ## Gibt die Summe der Differenzen der Quadrate für zusammengehörige Komponenten zweier Matrizen zurück +SUMX2PY2 = SUMMEX2PY2 ## Gibt die Summe der Quadrate für zusammengehörige Komponenten zweier Matrizen zurück +SUMXMY2 = SUMMEXMY2 ## Gibt die Summe der quadrierten Differenzen für zusammengehörige Komponenten zweier Matrizen zurück +TAN = TAN ## Gibt den Tangens einer Zahl zurück +TANH = TANHYP ## Gibt den hyperbolischen Tangens einer Zahl zurück +TRUNC = KÜRZEN ## Schneidet die Kommastellen einer Zahl ab und gibt als Ergebnis eine ganze Zahl zurück + + +## +## Statistical functions Statistische Funktionen +## +AVEDEV = MITTELABW ## Gibt die durchschnittliche absolute Abweichung einer Reihe von Merkmalsausprägungen und ihrem Mittelwert zurück +AVERAGE = MITTELWERT ## Gibt den Mittelwert der zugehörigen Argumente zurück +AVERAGEA = MITTELWERTA ## Gibt den Mittelwert der zugehörigen Argumente, die Zahlen, Text und Wahrheitswerte enthalten, zurück +AVERAGEIF = MITTELWERTWENN ## Der Durchschnittswert (arithmetisches Mittel) für alle Zellen in einem Bereich, die einem angegebenen Kriterium entsprechen, wird zurückgegeben +AVERAGEIFS = MITTELWERTWENNS ## Gibt den Durchschnittswert (arithmetisches Mittel) aller Zellen zurück, die mehreren Kriterien entsprechen +BETADIST = BETAVERT ## Gibt die Werte der kumulierten Betaverteilungsfunktion zurück +BETAINV = BETAINV ## Gibt das Quantil der angegebenen Betaverteilung zurück +BINOMDIST = BINOMVERT ## Gibt Wahrscheinlichkeiten einer binomialverteilten Zufallsvariablen zurück +CHIDIST = CHIVERT ## Gibt Werte der Verteilungsfunktion (1-Alpha) einer Chi-Quadrat-verteilten Zufallsgröße zurück +CHIINV = CHIINV ## Gibt Quantile der Verteilungsfunktion (1-Alpha) der Chi-Quadrat-Verteilung zurück +CHITEST = CHITEST ## Gibt die Teststatistik eines Unabhängigkeitstests zurück +CONFIDENCE = KONFIDENZ ## Ermöglicht die Berechnung des 1-Alpha Konfidenzintervalls für den Erwartungswert einer Zufallsvariablen +CORREL = KORREL ## Gibt den Korrelationskoeffizienten zweier Reihen von Merkmalsausprägungen zurück +COUNT = ANZAHL ## Gibt die Anzahl der Zahlen in der Liste mit Argumenten an +COUNTA = ANZAHL2 ## Gibt die Anzahl der Werte in der Liste mit Argumenten an +COUNTBLANK = ANZAHLLEEREZELLEN ## Gibt die Anzahl der leeren Zellen in einem Bereich an +COUNTIF = ZÄHLENWENN ## Gibt die Anzahl der Zellen in einem Bereich an, deren Inhalte mit den Suchkriterien übereinstimmen +COUNTIFS = ZÄHLENWENNS ## Gibt die Anzahl der Zellen in einem Bereich an, deren Inhalte mit mehreren Suchkriterien übereinstimmen +COVAR = KOVAR ## Gibt die Kovarianz zurück, den Mittelwert der für alle Datenpunktpaare gebildeten Produkte der Abweichungen +CRITBINOM = KRITBINOM ## Gibt den kleinsten Wert zurück, für den die kumulierten Wahrscheinlichkeiten der Binomialverteilung kleiner oder gleich einer Grenzwahrscheinlichkeit sind +DEVSQ = SUMQUADABW ## Gibt die Summe der quadrierten Abweichungen der Datenpunkte von ihrem Stichprobenmittelwert zurück +EXPONDIST = EXPONVERT ## Gibt Wahrscheinlichkeiten einer exponential verteilten Zufallsvariablen zurück +FDIST = FVERT ## Gibt Werte der Verteilungsfunktion (1-Alpha) einer F-verteilten Zufallsvariablen zurück +FINV = FINV ## Gibt Quantile der F-Verteilung zurück +FISHER = FISHER ## Gibt die Fisher-Transformation zurück +FISHERINV = FISHERINV ## Gibt die Umkehrung der Fisher-Transformation zurück +FORECAST = PROGNOSE ## Gibt einen Wert zurück, der sich aus einem linearen Trend ergibt +FREQUENCY = HÄUFIGKEIT ## Gibt eine Häufigkeitsverteilung als vertikale Matrix zurück +FTEST = FTEST ## Gibt die Teststatistik eines F-Tests zurück +GAMMADIST = GAMMAVERT ## Gibt Wahrscheinlichkeiten einer gammaverteilten Zufallsvariablen zurück +GAMMAINV = GAMMAINV ## Gibt Quantile der Gammaverteilung zurück +GAMMALN = GAMMALN ## Gibt den natürlichen Logarithmus der Gammafunktion zurück, Γ(x) +GEOMEAN = GEOMITTEL ## Gibt das geometrische Mittel zurück +GROWTH = VARIATION ## Gibt Werte zurück, die sich aus einem exponentiellen Trend ergeben +HARMEAN = HARMITTEL ## Gibt das harmonische Mittel zurück +HYPGEOMDIST = HYPGEOMVERT ## Gibt Wahrscheinlichkeiten einer hypergeometrisch-verteilten Zufallsvariablen zurück +INTERCEPT = ACHSENABSCHNITT ## Gibt den Schnittpunkt der Regressionsgeraden zurück +KURT = KURT ## Gibt die Kurtosis (Exzess) einer Datengruppe zurück +LARGE = KGRÖSSTE ## Gibt den k-größten Wert einer Datengruppe zurück +LINEST = RGP ## Gibt die Parameter eines linearen Trends zurück +LOGEST = RKP ## Gibt die Parameter eines exponentiellen Trends zurück +LOGINV = LOGINV ## Gibt Quantile der Lognormalverteilung zurück +LOGNORMDIST = LOGNORMVERT ## Gibt Werte der Verteilungsfunktion einer lognormalverteilten Zufallsvariablen zurück +MAX = MAX ## Gibt den Maximalwert einer Liste mit Argumenten zurück +MAXA = MAXA ## Gibt den Maximalwert einer Liste mit Argumenten zurück, die Zahlen, Text und Wahrheitswerte enthalten +MEDIAN = MEDIAN ## Gibt den Median der angegebenen Zahlen zurück +MIN = MIN ## Gibt den Minimalwert einer Liste mit Argumenten zurück +MINA = MINA ## Gibt den kleinsten Wert einer Liste mit Argumenten zurück, die Zahlen, Text und Wahrheitswerte enthalten +MODE = MODALWERT ## Gibt den am häufigsten vorkommenden Wert in einer Datengruppe zurück +NEGBINOMDIST = NEGBINOMVERT ## Gibt Wahrscheinlichkeiten einer negativen, binominal verteilten Zufallsvariablen zurück +NORMDIST = NORMVERT ## Gibt Wahrscheinlichkeiten einer normal verteilten Zufallsvariablen zurück +NORMINV = NORMINV ## Gibt Quantile der Normalverteilung zurück +NORMSDIST = STANDNORMVERT ## Gibt Werte der Verteilungsfunktion einer standardnormalverteilten Zufallsvariablen zurück +NORMSINV = STANDNORMINV ## Gibt Quantile der Standardnormalverteilung zurück +PEARSON = PEARSON ## Gibt den Pearsonschen Korrelationskoeffizienten zurück +PERCENTILE = QUANTIL ## Gibt das Alpha-Quantil einer Gruppe von Daten zurück +PERCENTRANK = QUANTILSRANG ## Gibt den prozentualen Rang (Alpha) eines Werts in einer Datengruppe zurück +PERMUT = VARIATIONEN ## Gibt die Anzahl der Möglichkeiten zurück, um k Elemente aus einer Menge von n Elementen ohne Zurücklegen zu ziehen +POISSON = POISSON ## Gibt Wahrscheinlichkeiten einer poissonverteilten Zufallsvariablen zurück +PROB = WAHRSCHBEREICH ## Gibt die Wahrscheinlichkeit für ein von zwei Werten eingeschlossenes Intervall zurück +QUARTILE = QUARTILE ## Gibt die Quartile der Datengruppe zurück +RANK = RANG ## Gibt den Rang zurück, den eine Zahl innerhalb einer Liste von Zahlen einnimmt +RSQ = BESTIMMTHEITSMASS ## Gibt das Quadrat des Pearsonschen Korrelationskoeffizienten zurück +SKEW = SCHIEFE ## Gibt die Schiefe einer Verteilung zurück +SLOPE = STEIGUNG ## Gibt die Steigung der Regressionsgeraden zurück +SMALL = KKLEINSTE ## Gibt den k-kleinsten Wert einer Datengruppe zurück +STANDARDIZE = STANDARDISIERUNG ## Gibt den standardisierten Wert zurück +STDEV = STABW ## Schätzt die Standardabweichung ausgehend von einer Stichprobe +STDEVA = STABWA ## Schätzt die Standardabweichung ausgehend von einer Stichprobe, die Zahlen, Text und Wahrheitswerte enthält +STDEVP = STABWN ## Berechnet die Standardabweichung ausgehend von der Grundgesamtheit +STDEVPA = STABWNA ## Berechnet die Standardabweichung ausgehend von der Grundgesamtheit, die Zahlen, Text und Wahrheitswerte enthält +STEYX = STFEHLERYX ## Gibt den Standardfehler der geschätzten y-Werte für alle x-Werte der Regression zurück +TDIST = TVERT ## Gibt Werte der Verteilungsfunktion (1-Alpha) einer (Student) t-verteilten Zufallsvariablen zurück +TINV = TINV ## Gibt Quantile der t-Verteilung zurück +TREND = TREND ## Gibt Werte zurück, die sich aus einem linearen Trend ergeben +TRIMMEAN = GESTUTZTMITTEL ## Gibt den Mittelwert einer Datengruppe zurück, ohne die Randwerte zu berücksichtigen +TTEST = TTEST ## Gibt die Teststatistik eines Student'schen t-Tests zurück +VAR = VARIANZ ## Schätzt die Varianz ausgehend von einer Stichprobe +VARA = VARIANZA ## Schätzt die Varianz ausgehend von einer Stichprobe, die Zahlen, Text und Wahrheitswerte enthält +VARP = VARIANZEN ## Berechnet die Varianz ausgehend von der Grundgesamtheit +VARPA = VARIANZENA ## Berechnet die Varianz ausgehend von der Grundgesamtheit, die Zahlen, Text und Wahrheitswerte enthält +WEIBULL = WEIBULL ## Gibt Wahrscheinlichkeiten einer weibullverteilten Zufallsvariablen zurück +ZTEST = GTEST ## Gibt den einseitigen Wahrscheinlichkeitswert für einen Gausstest (Normalverteilung) zurück + + +## +## Text functions Textfunktionen +## +ASC = ASC ## Konvertiert DB-Text in einer Zeichenfolge (lateinische Buchstaben oder Katakana) in SB-Text +BAHTTEXT = BAHTTEXT ## Wandelt eine Zahl in Text im Währungsformat ß (Baht) um +CHAR = ZEICHEN ## Gibt das der Codezahl entsprechende Zeichen zurück +CLEAN = SÄUBERN ## Löscht alle nicht druckbaren Zeichen aus einem Text +CODE = CODE ## Gibt die Codezahl des ersten Zeichens in einem Text zurück +CONCATENATE = VERKETTEN ## Verknüpft mehrere Textelemente zu einem Textelement +DOLLAR = DM ## Wandelt eine Zahl in Text im Währungsformat € (Euro) um +EXACT = IDENTISCH ## Prüft, ob zwei Textwerte identisch sind +FIND = FINDEN ## Sucht nach einem Textwert, der in einem anderen Textwert enthalten ist (Groß-/Kleinschreibung wird unterschieden) +FINDB = FINDENB ## Sucht nach einem Textwert, der in einem anderen Textwert enthalten ist (Groß-/Kleinschreibung wird unterschieden) +FIXED = FEST ## Formatiert eine Zahl als Text mit einer festen Anzahl von Dezimalstellen +JIS = JIS ## Konvertiert SB-Text in einer Zeichenfolge (lateinische Buchstaben oder Katakana) in DB-Text +LEFT = LINKS ## Gibt die Zeichen ganz links in einem Textwert zurück +LEFTB = LINKSB ## Gibt die Zeichen ganz links in einem Textwert zurück +LEN = LÄNGE ## Gibt die Anzahl der Zeichen in einer Zeichenfolge zurück +LENB = LÄNGEB ## Gibt die Anzahl der Zeichen in einer Zeichenfolge zurück +LOWER = KLEIN ## Wandelt Text in Kleinbuchstaben um +MID = TEIL ## Gibt eine bestimmte Anzahl Zeichen aus einer Zeichenfolge ab der von Ihnen angegebenen Stelle zurück +MIDB = TEILB ## Gibt eine bestimmte Anzahl Zeichen aus einer Zeichenfolge ab der von Ihnen angegebenen Stelle zurück +PHONETIC = PHONETIC ## Extrahiert die phonetischen (Furigana-)Zeichen aus einer Textzeichenfolge +PROPER = GROSS2 ## Wandelt den ersten Buchstaben aller Wörter eines Textwerts in Großbuchstaben um +REPLACE = ERSETZEN ## Ersetzt Zeichen in Text +REPLACEB = ERSETZENB ## Ersetzt Zeichen in Text +REPT = WIEDERHOLEN ## Wiederholt einen Text so oft wie angegeben +RIGHT = RECHTS ## Gibt die Zeichen ganz rechts in einem Textwert zurück +RIGHTB = RECHTSB ## Gibt die Zeichen ganz rechts in einem Textwert zurück +SEARCH = SUCHEN ## Sucht nach einem Textwert, der in einem anderen Textwert enthalten ist (Groß-/Kleinschreibung wird nicht unterschieden) +SEARCHB = SUCHENB ## Sucht nach einem Textwert, der in einem anderen Textwert enthalten ist (Groß-/Kleinschreibung wird nicht unterschieden) +SUBSTITUTE = WECHSELN ## Ersetzt in einer Zeichenfolge neuen Text gegen alten +T = T ## Wandelt die zugehörigen Argumente in Text um +TEXT = TEXT ## Formatiert eine Zahl und wandelt sie in Text um +TRIM = GLÄTTEN ## Entfernt Leerzeichen aus Text +UPPER = GROSS ## Wandelt Text in Großbuchstaben um +VALUE = WERT ## Wandelt ein Textargument in eine Zahl um diff --git a/lib/phpexcel/PHPExcel/locale/en/uk/config b/lib/phpexcel/PHPExcel/locale/en/uk/config new file mode 100644 index 0000000..dfcc63b --- /dev/null +++ b/lib/phpexcel/PHPExcel/locale/en/uk/config @@ -0,0 +1,32 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Settings +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## + + +## +## (For future use) +## +currencySymbol = £ diff --git a/lib/phpexcel/PHPExcel/locale/es/config b/lib/phpexcel/PHPExcel/locale/es/config new file mode 100644 index 0000000..0b11eb7 --- /dev/null +++ b/lib/phpexcel/PHPExcel/locale/es/config @@ -0,0 +1,47 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Settings +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## + + +ArgumentSeparator = ; + + +## +## (For future use) +## +currencySymbol = $ ## I'm surprised that the Excel Documentation suggests $ rather than € + + +## +## Excel Error Codes (For future use) +## +NULL = #¡NULO! +DIV0 = #¡DIV/0! +VALUE = #¡VALOR! +REF = #¡REF! +NAME = #¿NOMBRE? +NUM = #¡NÚM! +NA = #N/A diff --git a/lib/phpexcel/PHPExcel/locale/es/functions b/lib/phpexcel/PHPExcel/locale/es/functions new file mode 100644 index 0000000..f6e6fd2 --- /dev/null +++ b/lib/phpexcel/PHPExcel/locale/es/functions @@ -0,0 +1,438 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Calculation +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## Data in this file derived from http://www.piuha.fi/excel-function-name-translation/ +## +## + + +## +## Add-in and Automation functions Funciones de complementos y automatización +## +GETPIVOTDATA = IMPORTARDATOSDINAMICOS ## Devuelve los datos almacenados en un informe de tabla dinámica. + + +## +## Cube functions Funciones de cubo +## +CUBEKPIMEMBER = MIEMBROKPICUBO ## Devuelve un nombre, propiedad y medida de indicador de rendimiento clave (KPI) y muestra el nombre y la propiedad en la celda. Un KPI es una medida cuantificable, como los beneficios brutos mensuales o la facturación trimestral por empleado, que se usa para supervisar el rendimiento de una organización. +CUBEMEMBER = MIEMBROCUBO ## Devuelve un miembro o tupla en una jerarquía de cubo. Se usa para validar la existencia del miembro o la tupla en el cubo. +CUBEMEMBERPROPERTY = PROPIEDADMIEMBROCUBO ## Devuelve el valor de una propiedad de miembro del cubo Se usa para validar la existencia de un nombre de miembro en el cubo y para devolver la propiedad especificada para este miembro. +CUBERANKEDMEMBER = MIEMBRORANGOCUBO ## Devuelve el miembro n, o clasificado, de un conjunto. Se usa para devolver uno o más elementos de un conjunto, por ejemplo, el representante con mejores ventas o los diez mejores alumnos. +CUBESET = CONJUNTOCUBO ## Define un conjunto calculado de miembros o tuplas mediante el envío de una expresión de conjunto al cubo en el servidor, lo que crea el conjunto y, después, devuelve dicho conjunto a Microsoft Office Excel. +CUBESETCOUNT = RECUENTOCONJUNTOCUBO ## Devuelve el número de elementos de un conjunto. +CUBEVALUE = VALORCUBO ## Devuelve un valor agregado de un cubo. + + +## +## Database functions Funciones de base de datos +## +DAVERAGE = BDPROMEDIO ## Devuelve el promedio de las entradas seleccionadas en la base de datos. +DCOUNT = BDCONTAR ## Cuenta el número de celdas que contienen números en una base de datos. +DCOUNTA = BDCONTARA ## Cuenta el número de celdas no vacías en una base de datos. +DGET = BDEXTRAER ## Extrae de una base de datos un único registro que cumple los criterios especificados. +DMAX = BDMAX ## Devuelve el valor máximo de las entradas seleccionadas de la base de datos. +DMIN = BDMIN ## Devuelve el valor mínimo de las entradas seleccionadas de la base de datos. +DPRODUCT = BDPRODUCTO ## Multiplica los valores de un campo concreto de registros de una base de datos que cumplen los criterios especificados. +DSTDEV = BDDESVEST ## Calcula la desviación estándar a partir de una muestra de entradas seleccionadas en la base de datos. +DSTDEVP = BDDESVESTP ## Calcula la desviación estándar en función de la población total de las entradas seleccionadas de la base de datos. +DSUM = BDSUMA ## Suma los números de la columna de campo de los registros de la base de datos que cumplen los criterios. +DVAR = BDVAR ## Calcula la varianza a partir de una muestra de entradas seleccionadas de la base de datos. +DVARP = BDVARP ## Calcula la varianza a partir de la población total de entradas seleccionadas de la base de datos. + + +## +## Date and time functions Funciones de fecha y hora +## +DATE = FECHA ## Devuelve el número de serie correspondiente a una fecha determinada. +DATEVALUE = FECHANUMERO ## Convierte una fecha con formato de texto en un valor de número de serie. +DAY = DIA ## Convierte un número de serie en un valor de día del mes. +DAYS360 = DIAS360 ## Calcula el número de días entre dos fechas a partir de un año de 360 días. +EDATE = FECHA.MES ## Devuelve el número de serie de la fecha equivalente al número indicado de meses anteriores o posteriores a la fecha inicial. +EOMONTH = FIN.MES ## Devuelve el número de serie correspondiente al último día del mes anterior o posterior a un número de meses especificado. +HOUR = HORA ## Convierte un número de serie en un valor de hora. +MINUTE = MINUTO ## Convierte un número de serie en un valor de minuto. +MONTH = MES ## Convierte un número de serie en un valor de mes. +NETWORKDAYS = DIAS.LAB ## Devuelve el número de todos los días laborables existentes entre dos fechas. +NOW = AHORA ## Devuelve el número de serie correspondiente a la fecha y hora actuales. +SECOND = SEGUNDO ## Convierte un número de serie en un valor de segundo. +TIME = HORA ## Devuelve el número de serie correspondiente a una hora determinada. +TIMEVALUE = HORANUMERO ## Convierte una hora con formato de texto en un valor de número de serie. +TODAY = HOY ## Devuelve el número de serie correspondiente al día actual. +WEEKDAY = DIASEM ## Convierte un número de serie en un valor de día de la semana. +WEEKNUM = NUM.DE.SEMANA ## Convierte un número de serie en un número que representa el lugar numérico correspondiente a una semana de un año. +WORKDAY = DIA.LAB ## Devuelve el número de serie de la fecha que tiene lugar antes o después de un número determinado de días laborables. +YEAR = AÑO ## Convierte un número de serie en un valor de año. +YEARFRAC = FRAC.AÑO ## Devuelve la fracción de año que representa el número total de días existentes entre el valor de fecha_inicial y el de fecha_final. + + +## +## Engineering functions Funciones de ingeniería +## +BESSELI = BESSELI ## Devuelve la función Bessel In(x) modificada. +BESSELJ = BESSELJ ## Devuelve la función Bessel Jn(x). +BESSELK = BESSELK ## Devuelve la función Bessel Kn(x) modificada. +BESSELY = BESSELY ## Devuelve la función Bessel Yn(x). +BIN2DEC = BIN.A.DEC ## Convierte un número binario en decimal. +BIN2HEX = BIN.A.HEX ## Convierte un número binario en hexadecimal. +BIN2OCT = BIN.A.OCT ## Convierte un número binario en octal. +COMPLEX = COMPLEJO ## Convierte coeficientes reales e imaginarios en un número complejo. +CONVERT = CONVERTIR ## Convierte un número de un sistema de medida a otro. +DEC2BIN = DEC.A.BIN ## Convierte un número decimal en binario. +DEC2HEX = DEC.A.HEX ## Convierte un número decimal en hexadecimal. +DEC2OCT = DEC.A.OCT ## Convierte un número decimal en octal. +DELTA = DELTA ## Comprueba si dos valores son iguales. +ERF = FUN.ERROR ## Devuelve la función de error. +ERFC = FUN.ERROR.COMPL ## Devuelve la función de error complementario. +GESTEP = MAYOR.O.IGUAL ## Comprueba si un número es mayor que un valor de umbral. +HEX2BIN = HEX.A.BIN ## Convierte un número hexadecimal en binario. +HEX2DEC = HEX.A.DEC ## Convierte un número hexadecimal en decimal. +HEX2OCT = HEX.A.OCT ## Convierte un número hexadecimal en octal. +IMABS = IM.ABS ## Devuelve el valor absoluto (módulo) de un número complejo. +IMAGINARY = IMAGINARIO ## Devuelve el coeficiente imaginario de un número complejo. +IMARGUMENT = IM.ANGULO ## Devuelve el argumento theta, un ángulo expresado en radianes. +IMCONJUGATE = IM.CONJUGADA ## Devuelve la conjugada compleja de un número complejo. +IMCOS = IM.COS ## Devuelve el coseno de un número complejo. +IMDIV = IM.DIV ## Devuelve el cociente de dos números complejos. +IMEXP = IM.EXP ## Devuelve el valor exponencial de un número complejo. +IMLN = IM.LN ## Devuelve el logaritmo natural (neperiano) de un número complejo. +IMLOG10 = IM.LOG10 ## Devuelve el logaritmo en base 10 de un número complejo. +IMLOG2 = IM.LOG2 ## Devuelve el logaritmo en base 2 de un número complejo. +IMPOWER = IM.POT ## Devuelve un número complejo elevado a una potencia entera. +IMPRODUCT = IM.PRODUCT ## Devuelve el producto de números complejos. +IMREAL = IM.REAL ## Devuelve el coeficiente real de un número complejo. +IMSIN = IM.SENO ## Devuelve el seno de un número complejo. +IMSQRT = IM.RAIZ2 ## Devuelve la raíz cuadrada de un número complejo. +IMSUB = IM.SUSTR ## Devuelve la diferencia entre dos números complejos. +IMSUM = IM.SUM ## Devuelve la suma de números complejos. +OCT2BIN = OCT.A.BIN ## Convierte un número octal en binario. +OCT2DEC = OCT.A.DEC ## Convierte un número octal en decimal. +OCT2HEX = OCT.A.HEX ## Convierte un número octal en hexadecimal. + + +## +## Financial functions Funciones financieras +## +ACCRINT = INT.ACUM ## Devuelve el interés acumulado de un valor bursátil con pagos de interés periódicos. +ACCRINTM = INT.ACUM.V ## Devuelve el interés acumulado de un valor bursátil con pagos de interés al vencimiento. +AMORDEGRC = AMORTIZ.PROGRE ## Devuelve la amortización de cada período contable mediante el uso de un coeficiente de amortización. +AMORLINC = AMORTIZ.LIN ## Devuelve la amortización de cada uno de los períodos contables. +COUPDAYBS = CUPON.DIAS.L1 ## Devuelve el número de días desde el principio del período de un cupón hasta la fecha de liquidación. +COUPDAYS = CUPON.DIAS ## Devuelve el número de días del período (entre dos cupones) donde se encuentra la fecha de liquidación. +COUPDAYSNC = CUPON.DIAS.L2 ## Devuelve el número de días desde la fecha de liquidación hasta la fecha del próximo cupón. +COUPNCD = CUPON.FECHA.L2 ## Devuelve la fecha del próximo cupón después de la fecha de liquidación. +COUPNUM = CUPON.NUM ## Devuelve el número de pagos de cupón entre la fecha de liquidación y la fecha de vencimiento. +COUPPCD = CUPON.FECHA.L1 ## Devuelve la fecha de cupón anterior a la fecha de liquidación. +CUMIPMT = PAGO.INT.ENTRE ## Devuelve el interés acumulado pagado entre dos períodos. +CUMPRINC = PAGO.PRINC.ENTRE ## Devuelve el capital acumulado pagado de un préstamo entre dos períodos. +DB = DB ## Devuelve la amortización de un bien durante un período específico a través del método de amortización de saldo fijo. +DDB = DDB ## Devuelve la amortización de un bien durante un período específico a través del método de amortización por doble disminución de saldo u otro método que se especifique. +DISC = TASA.DESC ## Devuelve la tasa de descuento de un valor bursátil. +DOLLARDE = MONEDA.DEC ## Convierte una cotización de un valor bursátil expresada en forma fraccionaria en una cotización de un valor bursátil expresada en forma decimal. +DOLLARFR = MONEDA.FRAC ## Convierte una cotización de un valor bursátil expresada en forma decimal en una cotización de un valor bursátil expresada en forma fraccionaria. +DURATION = DURACION ## Devuelve la duración anual de un valor bursátil con pagos de interés periódico. +EFFECT = INT.EFECTIVO ## Devuelve la tasa de interés anual efectiva. +FV = VF ## Devuelve el valor futuro de una inversión. +FVSCHEDULE = VF.PLAN ## Devuelve el valor futuro de un capital inicial después de aplicar una serie de tasas de interés compuesto. +INTRATE = TASA.INT ## Devuelve la tasa de interés para la inversión total de un valor bursátil. +IPMT = PAGOINT ## Devuelve el pago de intereses de una inversión durante un período determinado. +IRR = TIR ## Devuelve la tasa interna de retorno para una serie de flujos de efectivo periódicos. +ISPMT = INT.PAGO.DIR ## Calcula el interés pagado durante un período específico de una inversión. +MDURATION = DURACION.MODIF ## Devuelve la duración de Macauley modificada de un valor bursátil con un valor nominal supuesto de 100 $. +MIRR = TIRM ## Devuelve la tasa interna de retorno donde se financian flujos de efectivo positivos y negativos a tasas diferentes. +NOMINAL = TASA.NOMINAL ## Devuelve la tasa nominal de interés anual. +NPER = NPER ## Devuelve el número de períodos de una inversión. +NPV = VNA ## Devuelve el valor neto actual de una inversión en función de una serie de flujos periódicos de efectivo y una tasa de descuento. +ODDFPRICE = PRECIO.PER.IRREGULAR.1 ## Devuelve el precio por un valor nominal de 100 $ de un valor bursátil con un primer período impar. +ODDFYIELD = RENDTO.PER.IRREGULAR.1 ## Devuelve el rendimiento de un valor bursátil con un primer período impar. +ODDLPRICE = PRECIO.PER.IRREGULAR.2 ## Devuelve el precio por un valor nominal de 100 $ de un valor bursátil con un último período impar. +ODDLYIELD = RENDTO.PER.IRREGULAR.2 ## Devuelve el rendimiento de un valor bursátil con un último período impar. +PMT = PAGO ## Devuelve el pago periódico de una anualidad. +PPMT = PAGOPRIN ## Devuelve el pago de capital de una inversión durante un período determinado. +PRICE = PRECIO ## Devuelve el precio por un valor nominal de 100 $ de un valor bursátil que paga una tasa de interés periódico. +PRICEDISC = PRECIO.DESCUENTO ## Devuelve el precio por un valor nominal de 100 $ de un valor bursátil con descuento. +PRICEMAT = PRECIO.VENCIMIENTO ## Devuelve el precio por un valor nominal de 100 $ de un valor bursátil que paga interés a su vencimiento. +PV = VALACT ## Devuelve el valor actual de una inversión. +RATE = TASA ## Devuelve la tasa de interés por período de una anualidad. +RECEIVED = CANTIDAD.RECIBIDA ## Devuelve la cantidad recibida al vencimiento de un valor bursátil completamente invertido. +SLN = SLN ## Devuelve la amortización por método directo de un bien en un período dado. +SYD = SYD ## Devuelve la amortización por suma de dígitos de los años de un bien durante un período especificado. +TBILLEQ = LETRA.DE.TES.EQV.A.BONO ## Devuelve el rendimiento de un bono equivalente a una letra del Tesoro (de EE.UU.) +TBILLPRICE = LETRA.DE.TES.PRECIO ## Devuelve el precio por un valor nominal de 100 $ de una letra del Tesoro (de EE.UU.) +TBILLYIELD = LETRA.DE.TES.RENDTO ## Devuelve el rendimiento de una letra del Tesoro (de EE.UU.) +VDB = DVS ## Devuelve la amortización de un bien durante un período específico o parcial a través del método de cálculo del saldo en disminución. +XIRR = TIR.NO.PER ## Devuelve la tasa interna de retorno para un flujo de efectivo que no es necesariamente periódico. +XNPV = VNA.NO.PER ## Devuelve el valor neto actual para un flujo de efectivo que no es necesariamente periódico. +YIELD = RENDTO ## Devuelve el rendimiento de un valor bursátil que paga intereses periódicos. +YIELDDISC = RENDTO.DESC ## Devuelve el rendimiento anual de un valor bursátil con descuento; por ejemplo, una letra del Tesoro (de EE.UU.) +YIELDMAT = RENDTO.VENCTO ## Devuelve el rendimiento anual de un valor bursátil que paga intereses al vencimiento. + + +## +## Information functions Funciones de información +## +CELL = CELDA ## Devuelve información acerca del formato, la ubicación o el contenido de una celda. +ERROR.TYPE = TIPO.DE.ERROR ## Devuelve un número que corresponde a un tipo de error. +INFO = INFO ## Devuelve información acerca del entorno operativo en uso. +ISBLANK = ESBLANCO ## Devuelve VERDADERO si el valor está en blanco. +ISERR = ESERR ## Devuelve VERDADERO si el valor es cualquier valor de error excepto #N/A. +ISERROR = ESERROR ## Devuelve VERDADERO si el valor es cualquier valor de error. +ISEVEN = ES.PAR ## Devuelve VERDADERO si el número es par. +ISLOGICAL = ESLOGICO ## Devuelve VERDADERO si el valor es un valor lógico. +ISNA = ESNOD ## Devuelve VERDADERO si el valor es el valor de error #N/A. +ISNONTEXT = ESNOTEXTO ## Devuelve VERDADERO si el valor no es texto. +ISNUMBER = ESNUMERO ## Devuelve VERDADERO si el valor es un número. +ISODD = ES.IMPAR ## Devuelve VERDADERO si el número es impar. +ISREF = ESREF ## Devuelve VERDADERO si el valor es una referencia. +ISTEXT = ESTEXTO ## Devuelve VERDADERO si el valor es texto. +N = N ## Devuelve un valor convertido en un número. +NA = ND ## Devuelve el valor de error #N/A. +TYPE = TIPO ## Devuelve un número que indica el tipo de datos de un valor. + + +## +## Logical functions Funciones lógicas +## +AND = Y ## Devuelve VERDADERO si todos sus argumentos son VERDADERO. +FALSE = FALSO ## Devuelve el valor lógico FALSO. +IF = SI ## Especifica una prueba lógica que realizar. +IFERROR = SI.ERROR ## Devuelve un valor que se especifica si una fórmula lo evalúa como un error; de lo contrario, devuelve el resultado de la fórmula. +NOT = NO ## Invierte el valor lógico del argumento. +OR = O ## Devuelve VERDADERO si cualquier argumento es VERDADERO. +TRUE = VERDADERO ## Devuelve el valor lógico VERDADERO. + + +## +## Lookup and reference functions Funciones de búsqueda y referencia +## +ADDRESS = DIRECCION ## Devuelve una referencia como texto a una sola celda de una hoja de cálculo. +AREAS = AREAS ## Devuelve el número de áreas de una referencia. +CHOOSE = ELEGIR ## Elige un valor de una lista de valores. +COLUMN = COLUMNA ## Devuelve el número de columna de una referencia. +COLUMNS = COLUMNAS ## Devuelve el número de columnas de una referencia. +HLOOKUP = BUSCARH ## Busca en la fila superior de una matriz y devuelve el valor de la celda indicada. +HYPERLINK = HIPERVINCULO ## Crea un acceso directo o un salto que abre un documento almacenado en un servidor de red, en una intranet o en Internet. +INDEX = INDICE ## Usa un índice para elegir un valor de una referencia o matriz. +INDIRECT = INDIRECTO ## Devuelve una referencia indicada por un valor de texto. +LOOKUP = BUSCAR ## Busca valores de un vector o una matriz. +MATCH = COINCIDIR ## Busca valores de una referencia o matriz. +OFFSET = DESREF ## Devuelve un desplazamiento de referencia respecto a una referencia dada. +ROW = FILA ## Devuelve el número de fila de una referencia. +ROWS = FILAS ## Devuelve el número de filas de una referencia. +RTD = RDTR ## Recupera datos en tiempo real desde un programa compatible con la automatización COM (automatización: modo de trabajar con los objetos de una aplicación desde otra aplicación o herramienta de entorno. La automatización, antes denominada automatización OLE, es un estándar de la industria y una función del Modelo de objetos componentes (COM).). +TRANSPOSE = TRANSPONER ## Devuelve la transposición de una matriz. +VLOOKUP = BUSCARV ## Busca en la primera columna de una matriz y se mueve en horizontal por la fila para devolver el valor de una celda. + + +## +## Math and trigonometry functions Funciones matemáticas y trigonométricas +## +ABS = ABS ## Devuelve el valor absoluto de un número. +ACOS = ACOS ## Devuelve el arcocoseno de un número. +ACOSH = ACOSH ## Devuelve el coseno hiperbólico inverso de un número. +ASIN = ASENO ## Devuelve el arcoseno de un número. +ASINH = ASENOH ## Devuelve el seno hiperbólico inverso de un número. +ATAN = ATAN ## Devuelve la arcotangente de un número. +ATAN2 = ATAN2 ## Devuelve la arcotangente de las coordenadas "x" e "y". +ATANH = ATANH ## Devuelve la tangente hiperbólica inversa de un número. +CEILING = MULTIPLO.SUPERIOR ## Redondea un número al entero más próximo o al múltiplo significativo más cercano. +COMBIN = COMBINAT ## Devuelve el número de combinaciones para un número determinado de objetos. +COS = COS ## Devuelve el coseno de un número. +COSH = COSH ## Devuelve el coseno hiperbólico de un número. +DEGREES = GRADOS ## Convierte radianes en grados. +EVEN = REDONDEA.PAR ## Redondea un número hasta el entero par más próximo. +EXP = EXP ## Devuelve e elevado a la potencia de un número dado. +FACT = FACT ## Devuelve el factorial de un número. +FACTDOUBLE = FACT.DOBLE ## Devuelve el factorial doble de un número. +FLOOR = MULTIPLO.INFERIOR ## Redondea un número hacia abajo, en dirección hacia cero. +GCD = M.C.D ## Devuelve el máximo común divisor. +INT = ENTERO ## Redondea un número hacia abajo hasta el entero más próximo. +LCM = M.C.M ## Devuelve el mínimo común múltiplo. +LN = LN ## Devuelve el logaritmo natural (neperiano) de un número. +LOG = LOG ## Devuelve el logaritmo de un número en una base especificada. +LOG10 = LOG10 ## Devuelve el logaritmo en base 10 de un número. +MDETERM = MDETERM ## Devuelve la determinante matricial de una matriz. +MINVERSE = MINVERSA ## Devuelve la matriz inversa de una matriz. +MMULT = MMULT ## Devuelve el producto de matriz de dos matrices. +MOD = RESIDUO ## Devuelve el resto de la división. +MROUND = REDOND.MULT ## Devuelve un número redondeado al múltiplo deseado. +MULTINOMIAL = MULTINOMIAL ## Devuelve el polinomio de un conjunto de números. +ODD = REDONDEA.IMPAR ## Redondea un número hacia arriba hasta el entero impar más próximo. +PI = PI ## Devuelve el valor de pi. +POWER = POTENCIA ## Devuelve el resultado de elevar un número a una potencia. +PRODUCT = PRODUCTO ## Multiplica sus argumentos. +QUOTIENT = COCIENTE ## Devuelve la parte entera de una división. +RADIANS = RADIANES ## Convierte grados en radianes. +RAND = ALEATORIO ## Devuelve un número aleatorio entre 0 y 1. +RANDBETWEEN = ALEATORIO.ENTRE ## Devuelve un número aleatorio entre los números que especifique. +ROMAN = NUMERO.ROMANO ## Convierte un número arábigo en número romano, con formato de texto. +ROUND = REDONDEAR ## Redondea un número al número de decimales especificado. +ROUNDDOWN = REDONDEAR.MENOS ## Redondea un número hacia abajo, en dirección hacia cero. +ROUNDUP = REDONDEAR.MAS ## Redondea un número hacia arriba, en dirección contraria a cero. +SERIESSUM = SUMA.SERIES ## Devuelve la suma de una serie de potencias en función de la fórmula. +SIGN = SIGNO ## Devuelve el signo de un número. +SIN = SENO ## Devuelve el seno de un ángulo determinado. +SINH = SENOH ## Devuelve el seno hiperbólico de un número. +SQRT = RAIZ ## Devuelve la raíz cuadrada positiva de un número. +SQRTPI = RAIZ2PI ## Devuelve la raíz cuadrada de un número multiplicado por PI (número * pi). +SUBTOTAL = SUBTOTALES ## Devuelve un subtotal en una lista o base de datos. +SUM = SUMA ## Suma sus argumentos. +SUMIF = SUMAR.SI ## Suma las celdas especificadas que cumplen unos criterios determinados. +SUMIFS = SUMAR.SI.CONJUNTO ## Suma las celdas de un rango que cumplen varios criterios. +SUMPRODUCT = SUMAPRODUCTO ## Devuelve la suma de los productos de los correspondientes componentes de matriz. +SUMSQ = SUMA.CUADRADOS ## Devuelve la suma de los cuadrados de los argumentos. +SUMX2MY2 = SUMAX2MENOSY2 ## Devuelve la suma de la diferencia de los cuadrados de los valores correspondientes de dos matrices. +SUMX2PY2 = SUMAX2MASY2 ## Devuelve la suma de la suma de los cuadrados de los valores correspondientes de dos matrices. +SUMXMY2 = SUMAXMENOSY2 ## Devuelve la suma de los cuadrados de las diferencias de los valores correspondientes de dos matrices. +TAN = TAN ## Devuelve la tangente de un número. +TANH = TANH ## Devuelve la tangente hiperbólica de un número. +TRUNC = TRUNCAR ## Trunca un número a un entero. + + +## +## Statistical functions Funciones estadísticas +## +AVEDEV = DESVPROM ## Devuelve el promedio de las desviaciones absolutas de la media de los puntos de datos. +AVERAGE = PROMEDIO ## Devuelve el promedio de sus argumentos. +AVERAGEA = PROMEDIOA ## Devuelve el promedio de sus argumentos, incluidos números, texto y valores lógicos. +AVERAGEIF = PROMEDIO.SI ## Devuelve el promedio (media aritmética) de todas las celdas de un rango que cumplen unos criterios determinados. +AVERAGEIFS = PROMEDIO.SI.CONJUNTO ## Devuelve el promedio (media aritmética) de todas las celdas que cumplen múltiples criterios. +BETADIST = DISTR.BETA ## Devuelve la función de distribución beta acumulativa. +BETAINV = DISTR.BETA.INV ## Devuelve la función inversa de la función de distribución acumulativa de una distribución beta especificada. +BINOMDIST = DISTR.BINOM ## Devuelve la probabilidad de una variable aleatoria discreta siguiendo una distribución binomial. +CHIDIST = DISTR.CHI ## Devuelve la probabilidad de una variable aleatoria continua siguiendo una distribución chi cuadrado de una sola cola. +CHIINV = PRUEBA.CHI.INV ## Devuelve la función inversa de la probabilidad de una variable aleatoria continua siguiendo una distribución chi cuadrado de una sola cola. +CHITEST = PRUEBA.CHI ## Devuelve la prueba de independencia. +CONFIDENCE = INTERVALO.CONFIANZA ## Devuelve el intervalo de confianza de la media de una población. +CORREL = COEF.DE.CORREL ## Devuelve el coeficiente de correlación entre dos conjuntos de datos. +COUNT = CONTAR ## Cuenta cuántos números hay en la lista de argumentos. +COUNTA = CONTARA ## Cuenta cuántos valores hay en la lista de argumentos. +COUNTBLANK = CONTAR.BLANCO ## Cuenta el número de celdas en blanco de un rango. +COUNTIF = CONTAR.SI ## Cuenta el número de celdas, dentro del rango, que cumplen el criterio especificado. +COUNTIFS = CONTAR.SI.CONJUNTO ## Cuenta el número de celdas, dentro del rango, que cumplen varios criterios. +COVAR = COVAR ## Devuelve la covarianza, que es el promedio de los productos de las desviaciones para cada pareja de puntos de datos. +CRITBINOM = BINOM.CRIT ## Devuelve el menor valor cuya distribución binomial acumulativa es menor o igual a un valor de criterio. +DEVSQ = DESVIA2 ## Devuelve la suma de los cuadrados de las desviaciones. +EXPONDIST = DISTR.EXP ## Devuelve la distribución exponencial. +FDIST = DISTR.F ## Devuelve la distribución de probabilidad F. +FINV = DISTR.F.INV ## Devuelve la función inversa de la distribución de probabilidad F. +FISHER = FISHER ## Devuelve la transformación Fisher. +FISHERINV = PRUEBA.FISHER.INV ## Devuelve la función inversa de la transformación Fisher. +FORECAST = PRONOSTICO ## Devuelve un valor en una tendencia lineal. +FREQUENCY = FRECUENCIA ## Devuelve una distribución de frecuencia como una matriz vertical. +FTEST = PRUEBA.F ## Devuelve el resultado de una prueba F. +GAMMADIST = DISTR.GAMMA ## Devuelve la distribución gamma. +GAMMAINV = DISTR.GAMMA.INV ## Devuelve la función inversa de la distribución gamma acumulativa. +GAMMALN = GAMMA.LN ## Devuelve el logaritmo natural de la función gamma, G(x). +GEOMEAN = MEDIA.GEOM ## Devuelve la media geométrica. +GROWTH = CRECIMIENTO ## Devuelve valores en una tendencia exponencial. +HARMEAN = MEDIA.ARMO ## Devuelve la media armónica. +HYPGEOMDIST = DISTR.HIPERGEOM ## Devuelve la distribución hipergeométrica. +INTERCEPT = INTERSECCION.EJE ## Devuelve la intersección de la línea de regresión lineal. +KURT = CURTOSIS ## Devuelve la curtosis de un conjunto de datos. +LARGE = K.ESIMO.MAYOR ## Devuelve el k-ésimo mayor valor de un conjunto de datos. +LINEST = ESTIMACION.LINEAL ## Devuelve los parámetros de una tendencia lineal. +LOGEST = ESTIMACION.LOGARITMICA ## Devuelve los parámetros de una tendencia exponencial. +LOGINV = DISTR.LOG.INV ## Devuelve la función inversa de la distribución logarítmico-normal. +LOGNORMDIST = DISTR.LOG.NORM ## Devuelve la distribución logarítmico-normal acumulativa. +MAX = MAX ## Devuelve el valor máximo de una lista de argumentos. +MAXA = MAXA ## Devuelve el valor máximo de una lista de argumentos, incluidos números, texto y valores lógicos. +MEDIAN = MEDIANA ## Devuelve la mediana de los números dados. +MIN = MIN ## Devuelve el valor mínimo de una lista de argumentos. +MINA = MINA ## Devuelve el valor mínimo de una lista de argumentos, incluidos números, texto y valores lógicos. +MODE = MODA ## Devuelve el valor más común de un conjunto de datos. +NEGBINOMDIST = NEGBINOMDIST ## Devuelve la distribución binomial negativa. +NORMDIST = DISTR.NORM ## Devuelve la distribución normal acumulativa. +NORMINV = DISTR.NORM.INV ## Devuelve la función inversa de la distribución normal acumulativa. +NORMSDIST = DISTR.NORM.ESTAND ## Devuelve la distribución normal estándar acumulativa. +NORMSINV = DISTR.NORM.ESTAND.INV ## Devuelve la función inversa de la distribución normal estándar acumulativa. +PEARSON = PEARSON ## Devuelve el coeficiente de momento de correlación de producto Pearson. +PERCENTILE = PERCENTIL ## Devuelve el k-ésimo percentil de los valores de un rango. +PERCENTRANK = RANGO.PERCENTIL ## Devuelve el rango porcentual de un valor de un conjunto de datos. +PERMUT = PERMUTACIONES ## Devuelve el número de permutaciones de un número determinado de objetos. +POISSON = POISSON ## Devuelve la distribución de Poisson. +PROB = PROBABILIDAD ## Devuelve la probabilidad de que los valores de un rango se encuentren entre dos límites. +QUARTILE = CUARTIL ## Devuelve el cuartil de un conjunto de datos. +RANK = JERARQUIA ## Devuelve la jerarquía de un número en una lista de números. +RSQ = COEFICIENTE.R2 ## Devuelve el cuadrado del coeficiente de momento de correlación de producto Pearson. +SKEW = COEFICIENTE.ASIMETRIA ## Devuelve la asimetría de una distribución. +SLOPE = PENDIENTE ## Devuelve la pendiente de la línea de regresión lineal. +SMALL = K.ESIMO.MENOR ## Devuelve el k-ésimo menor valor de un conjunto de datos. +STANDARDIZE = NORMALIZACION ## Devuelve un valor normalizado. +STDEV = DESVEST ## Calcula la desviación estándar a partir de una muestra. +STDEVA = DESVESTA ## Calcula la desviación estándar a partir de una muestra, incluidos números, texto y valores lógicos. +STDEVP = DESVESTP ## Calcula la desviación estándar en función de toda la población. +STDEVPA = DESVESTPA ## Calcula la desviación estándar en función de toda la población, incluidos números, texto y valores lógicos. +STEYX = ERROR.TIPICO.XY ## Devuelve el error estándar del valor de "y" previsto para cada "x" de la regresión. +TDIST = DISTR.T ## Devuelve la distribución de t de Student. +TINV = DISTR.T.INV ## Devuelve la función inversa de la distribución de t de Student. +TREND = TENDENCIA ## Devuelve valores en una tendencia lineal. +TRIMMEAN = MEDIA.ACOTADA ## Devuelve la media del interior de un conjunto de datos. +TTEST = PRUEBA.T ## Devuelve la probabilidad asociada a una prueba t de Student. +VAR = VAR ## Calcula la varianza en función de una muestra. +VARA = VARA ## Calcula la varianza en función de una muestra, incluidos números, texto y valores lógicos. +VARP = VARP ## Calcula la varianza en función de toda la población. +VARPA = VARPA ## Calcula la varianza en función de toda la población, incluidos números, texto y valores lógicos. +WEIBULL = DIST.WEIBULL ## Devuelve la distribución de Weibull. +ZTEST = PRUEBA.Z ## Devuelve el valor de una probabilidad de una cola de una prueba z. + + +## +## Text functions Funciones de texto +## +ASC = ASC ## Convierte las letras inglesas o katakana de ancho completo (de dos bytes) dentro de una cadena de caracteres en caracteres de ancho medio (de un byte). +BAHTTEXT = TEXTOBAHT ## Convierte un número en texto, con el formato de moneda ß (Baht). +CHAR = CARACTER ## Devuelve el carácter especificado por el número de código. +CLEAN = LIMPIAR ## Quita del texto todos los caracteres no imprimibles. +CODE = CODIGO ## Devuelve un código numérico del primer carácter de una cadena de texto. +CONCATENATE = CONCATENAR ## Concatena varios elementos de texto en uno solo. +DOLLAR = MONEDA ## Convierte un número en texto, con el formato de moneda $ (dólar). +EXACT = IGUAL ## Comprueba si dos valores de texto son idénticos. +FIND = ENCONTRAR ## Busca un valor de texto dentro de otro (distingue mayúsculas de minúsculas). +FINDB = ENCONTRARB ## Busca un valor de texto dentro de otro (distingue mayúsculas de minúsculas). +FIXED = DECIMAL ## Da formato a un número como texto con un número fijo de decimales. +JIS = JIS ## Convierte las letras inglesas o katakana de ancho medio (de un byte) dentro de una cadena de caracteres en caracteres de ancho completo (de dos bytes). +LEFT = IZQUIERDA ## Devuelve los caracteres del lado izquierdo de un valor de texto. +LEFTB = IZQUIERDAB ## Devuelve los caracteres del lado izquierdo de un valor de texto. +LEN = LARGO ## Devuelve el número de caracteres de una cadena de texto. +LENB = LARGOB ## Devuelve el número de caracteres de una cadena de texto. +LOWER = MINUSC ## Pone el texto en minúsculas. +MID = EXTRAE ## Devuelve un número específico de caracteres de una cadena de texto que comienza en la posición que se especifique. +MIDB = EXTRAEB ## Devuelve un número específico de caracteres de una cadena de texto que comienza en la posición que se especifique. +PHONETIC = FONETICO ## Extrae los caracteres fonéticos (furigana) de una cadena de texto. +PROPER = NOMPROPIO ## Pone en mayúscula la primera letra de cada palabra de un valor de texto. +REPLACE = REEMPLAZAR ## Reemplaza caracteres de texto. +REPLACEB = REEMPLAZARB ## Reemplaza caracteres de texto. +REPT = REPETIR ## Repite el texto un número determinado de veces. +RIGHT = DERECHA ## Devuelve los caracteres del lado derecho de un valor de texto. +RIGHTB = DERECHAB ## Devuelve los caracteres del lado derecho de un valor de texto. +SEARCH = HALLAR ## Busca un valor de texto dentro de otro (no distingue mayúsculas de minúsculas). +SEARCHB = HALLARB ## Busca un valor de texto dentro de otro (no distingue mayúsculas de minúsculas). +SUBSTITUTE = SUSTITUIR ## Sustituye texto nuevo por texto antiguo en una cadena de texto. +T = T ## Convierte sus argumentos a texto. +TEXT = TEXTO ## Da formato a un número y lo convierte en texto. +TRIM = ESPACIOS ## Quita los espacios del texto. +UPPER = MAYUSC ## Pone el texto en mayúsculas. +VALUE = VALOR ## Convierte un argumento de texto en un número. diff --git a/lib/phpexcel/PHPExcel/locale/fi/config b/lib/phpexcel/PHPExcel/locale/fi/config new file mode 100644 index 0000000..380f397 --- /dev/null +++ b/lib/phpexcel/PHPExcel/locale/fi/config @@ -0,0 +1,47 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Settings +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## + + +ArgumentSeparator = ; + + +## +## (For future use) +## +currencySymbol = $ # Symbol not known, should it be a € (Euro)? + + +## +## Excel Error Codes (For future use) +## +NULL = #TYHJÄ! +DIV0 = #JAKO/0! +VALUE = #ARVO! +REF = #VIITTAUS! +NAME = #NIMI? +NUM = #LUKU! +NA = #PUUTTUU diff --git a/lib/phpexcel/PHPExcel/locale/fi/functions b/lib/phpexcel/PHPExcel/locale/fi/functions new file mode 100644 index 0000000..bf60bec --- /dev/null +++ b/lib/phpexcel/PHPExcel/locale/fi/functions @@ -0,0 +1,438 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Calculation +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## Data in this file derived from http://www.piuha.fi/excel-function-name-translation/ +## +## + + +## +## Add-in and Automation functions Apuohjelma- ja automaatiofunktiot +## +GETPIVOTDATA = NOUDA.PIVOT.TIEDOT ## Palauttaa pivot-taulukkoraporttiin tallennettuja tietoja. + + +## +## Cube functions Kuutiofunktiot +## +CUBEKPIMEMBER = KUUTIOKPIJÄSEN ## Palauttaa suorituskykyilmaisimen (KPI) nimen, ominaisuuden sekä mitan ja näyttää nimen sekä ominaisuuden solussa. KPI on mitattavissa oleva suure, kuten kuukauden bruttotuotto tai vuosineljänneksen työntekijäkohtainen liikevaihto, joiden avulla tarkkaillaan organisaation suorituskykyä. +CUBEMEMBER = KUUTIONJÄSEN ## Palauttaa kuutiohierarkian jäsenen tai monikon. Tällä funktiolla voit tarkistaa, että jäsen tai monikko on olemassa kuutiossa. +CUBEMEMBERPROPERTY = KUUTIONJÄSENENOMINAISUUS ## Palauttaa kuution jäsenominaisuuden arvon. Tällä funktiolla voit tarkistaa, että nimi on olemassa kuutiossa, ja palauttaa tämän jäsenen määritetyn ominaisuuden. +CUBERANKEDMEMBER = KUUTIONLUOKITELTUJÄSEN ## Palauttaa joukon n:nnen jäsenen. Tällä funktiolla voit palauttaa joukosta elementtejä, kuten parhaan myyjän tai 10 parasta opiskelijaa. +CUBESET = KUUTIOJOUKKO ## Määrittää lasketun jäsen- tai monikkojoukon lähettämällä joukon lausekkeita palvelimessa olevalle kuutiolle. Palvelin luo joukon ja palauttaa sen Microsoft Office Excelille. +CUBESETCOUNT = KUUTIOJOUKKOJENMÄÄRÄ ## Palauttaa joukon kohteiden määrän. +CUBEVALUE = KUUTIONARVO ## Palauttaa koostetun arvon kuutiosta. + + +## +## Database functions Tietokantafunktiot +## +DAVERAGE = TKESKIARVO ## Palauttaa valittujen tietokantamerkintöjen keskiarvon. +DCOUNT = TLASKE ## Laskee tietokannan lukuja sisältävien solujen määrän. +DCOUNTA = TLASKEA ## Laskee tietokannan tietoja sisältävien solujen määrän. +DGET = TNOUDA ## Hakee määritettyjä ehtoja vastaavan tietueen tietokannasta. +DMAX = TMAKS ## Palauttaa suurimman arvon tietokannasta valittujen arvojen joukosta. +DMIN = TMIN ## Palauttaa pienimmän arvon tietokannasta valittujen arvojen joukosta. +DPRODUCT = TTULO ## Kertoo määritetyn ehdon täyttävien tietokannan tietueiden tietyssä kentässä olevat arvot. +DSTDEV = TKESKIHAJONTA ## Laskee keskihajonnan tietokannasta valituista arvoista muodostuvan otoksen perusteella. +DSTDEVP = TKESKIHAJONTAP ## Laskee keskihajonnan tietokannasta valittujen arvojen koko populaation perusteella. +DSUM = TSUMMA ## Lisää luvut määritetyn ehdon täyttävien tietokannan tietueiden kenttäsarakkeeseen. +DVAR = TVARIANSSI ## Laskee varianssin tietokannasta valittujen arvojen otoksen perusteella. +DVARP = TVARIANSSIP ## Laskee varianssin tietokannasta valittujen arvojen koko populaation perusteella. + + +## +## Date and time functions Päivämäärä- ja aikafunktiot +## +DATE = PÄIVÄYS ## Palauttaa annetun päivämäärän järjestysluvun. +DATEVALUE = PÄIVÄYSARVO ## Muuntaa tekstimuodossa olevan päivämäärän järjestysluvuksi. +DAY = PÄIVÄ ## Muuntaa järjestysluvun kuukauden päiväksi. +DAYS360 = PÄIVÄT360 ## Laskee kahden päivämäärän välisten päivien määrän käyttäen perustana 360-päiväistä vuotta. +EDATE = PÄIVÄ.KUUKAUSI ## Palauttaa järjestyslukuna päivämäärän, joka poikkeaa aloituspäivän päivämäärästä annetun kuukausimäärän verran joko eteen- tai taaksepäin. +EOMONTH = KUUKAUSI.LOPPU ## Palauttaa järjestyslukuna sen kuukauden viimeisen päivämäärän, joka poikkeaa annetun kuukausimäärän verran eteen- tai taaksepäin. +HOUR = TUNNIT ## Muuntaa järjestysluvun tunneiksi. +MINUTE = MINUUTIT ## Muuntaa järjestysluvun minuuteiksi. +MONTH = KUUKAUSI ## Muuntaa järjestysluvun kuukausiksi. +NETWORKDAYS = TYÖPÄIVÄT ## Palauttaa kahden päivämäärän välissä olevien täysien työpäivien määrän. +NOW = NYT ## Palauttaa kuluvan päivämäärän ja ajan järjestysnumeron. +SECOND = SEKUNNIT ## Muuntaa järjestysluvun sekunneiksi. +TIME = AIKA ## Palauttaa annetun kellonajan järjestysluvun. +TIMEVALUE = AIKA_ARVO ## Muuntaa tekstimuodossa olevan kellonajan järjestysluvuksi. +TODAY = TÄMÄ.PÄIVÄ ## Palauttaa kuluvan päivän päivämäärän järjestysluvun. +WEEKDAY = VIIKONPÄIVÄ ## Muuntaa järjestysluvun viikonpäiväksi. +WEEKNUM = VIIKKO.NRO ## Muuntaa järjestysluvun luvuksi, joka ilmaisee viikon järjestysluvun vuoden alusta laskettuna. +WORKDAY = TYÖPÄIVÄ ## Palauttaa järjestysluvun päivämäärälle, joka sijaitsee annettujen työpäivien verran eteen tai taaksepäin. +YEAR = VUOSI ## Muuntaa järjestysluvun vuosiksi. +YEARFRAC = VUOSI.OSA ## Palauttaa määritettyjen päivämäärien (aloituspäivä ja lopetuspäivä) välisen osan vuodesta. + + +## +## Engineering functions Tekniset funktiot +## +BESSELI = BESSELI ## Palauttaa muunnetun Bessel-funktion In(x). +BESSELJ = BESSELJ ## Palauttaa Bessel-funktion Jn(x). +BESSELK = BESSELK ## Palauttaa muunnetun Bessel-funktion Kn(x). +BESSELY = BESSELY ## Palauttaa Bessel-funktion Yn(x). +BIN2DEC = BINDES ## Muuntaa binaariluvun desimaaliluvuksi. +BIN2HEX = BINHEKSA ## Muuntaa binaariluvun heksadesimaaliluvuksi. +BIN2OCT = BINOKT ## Muuntaa binaariluvun oktaaliluvuksi. +COMPLEX = KOMPLEKSI ## Muuntaa reaali- ja imaginaariosien kertoimet kompleksiluvuksi. +CONVERT = MUUNNA ## Muuntaa luvun toisen mittajärjestelmän mukaiseksi. +DEC2BIN = DESBIN ## Muuntaa desimaaliluvun binaariluvuksi. +DEC2HEX = DESHEKSA ## Muuntaa kymmenjärjestelmän luvun heksadesimaaliluvuksi. +DEC2OCT = DESOKT ## Muuntaa kymmenjärjestelmän luvun oktaaliluvuksi. +DELTA = SAMA.ARVO ## Tarkistaa, ovatko kaksi arvoa yhtä suuria. +ERF = VIRHEFUNKTIO ## Palauttaa virhefunktion. +ERFC = VIRHEFUNKTIO.KOMPLEMENTTI ## Palauttaa komplementtivirhefunktion. +GESTEP = RAJA ## Testaa, onko luku suurempi kuin kynnysarvo. +HEX2BIN = HEKSABIN ## Muuntaa heksadesimaaliluvun binaariluvuksi. +HEX2DEC = HEKSADES ## Muuntaa heksadesimaaliluvun desimaaliluvuksi. +HEX2OCT = HEKSAOKT ## Muuntaa heksadesimaaliluvun oktaaliluvuksi. +IMABS = KOMPLEKSI.ITSEISARVO ## Palauttaa kompleksiluvun itseisarvon (moduluksen). +IMAGINARY = KOMPLEKSI.IMAG ## Palauttaa kompleksiluvun imaginaariosan kertoimen. +IMARGUMENT = KOMPLEKSI.ARG ## Palauttaa theeta-argumentin, joka on radiaaneina annettu kulma. +IMCONJUGATE = KOMPLEKSI.KONJ ## Palauttaa kompleksiluvun konjugaattiluvun. +IMCOS = KOMPLEKSI.COS ## Palauttaa kompleksiluvun kosinin. +IMDIV = KOMPLEKSI.OSAM ## Palauttaa kahden kompleksiluvun osamäärän. +IMEXP = KOMPLEKSI.EKSP ## Palauttaa kompleksiluvun eksponentin. +IMLN = KOMPLEKSI.LN ## Palauttaa kompleksiluvun luonnollisen logaritmin. +IMLOG10 = KOMPLEKSI.LOG10 ## Palauttaa kompleksiluvun kymmenkantaisen logaritmin. +IMLOG2 = KOMPLEKSI.LOG2 ## Palauttaa kompleksiluvun kaksikantaisen logaritmin. +IMPOWER = KOMPLEKSI.POT ## Palauttaa kokonaislukupotenssiin korotetun kompleksiluvun. +IMPRODUCT = KOMPLEKSI.TULO ## Palauttaa kompleksilukujen tulon. +IMREAL = KOMPLEKSI.REAALI ## Palauttaa kompleksiluvun reaaliosan kertoimen. +IMSIN = KOMPLEKSI.SIN ## Palauttaa kompleksiluvun sinin. +IMSQRT = KOMPLEKSI.NELIÖJ ## Palauttaa kompleksiluvun neliöjuuren. +IMSUB = KOMPLEKSI.EROTUS ## Palauttaa kahden kompleksiluvun erotuksen. +IMSUM = KOMPLEKSI.SUM ## Palauttaa kompleksilukujen summan. +OCT2BIN = OKTBIN ## Muuntaa oktaaliluvun binaariluvuksi. +OCT2DEC = OKTDES ## Muuntaa oktaaliluvun desimaaliluvuksi. +OCT2HEX = OKTHEKSA ## Muuntaa oktaaliluvun heksadesimaaliluvuksi. + + +## +## Financial functions Rahoitusfunktiot +## +ACCRINT = KERTYNYT.KORKO ## Laskee arvopaperille kertyneen koron, kun korko kertyy säännöllisin väliajoin. +ACCRINTM = KERTYNYT.KORKO.LOPUSSA ## Laskee arvopaperille kertyneen koron, kun korko maksetaan eräpäivänä. +AMORDEGRC = AMORDEGRC ## Laskee kunkin laskentakauden poiston poistokerrointa käyttämällä. +AMORLINC = AMORLINC ## Palauttaa kunkin laskentakauden poiston. +COUPDAYBS = KORKOPÄIVÄT.ALUSTA ## Palauttaa koronmaksukauden aloituspäivän ja tilityspäivän välisen ajanjakson päivien määrän. +COUPDAYS = KORKOPÄIVÄT ## Palauttaa päivien määrän koronmaksukaudelta, johon tilityspäivä kuuluu. +COUPDAYSNC = KORKOPÄIVÄT.SEURAAVA ## Palauttaa tilityspäivän ja seuraavan koronmaksupäivän välisen ajanjakson päivien määrän. +COUPNCD = KORKOMAKSU.SEURAAVA ## Palauttaa tilityspäivän jälkeisen seuraavan koronmaksupäivän. +COUPNUM = KORKOPÄIVÄJAKSOT ## Palauttaa arvopaperin ostopäivän ja erääntymispäivän välisten koronmaksupäivien määrän. +COUPPCD = KORKOPÄIVÄ.EDELLINEN ## Palauttaa tilityspäivää edeltävän koronmaksupäivän. +CUMIPMT = MAKSETTU.KORKO ## Palauttaa kahden jakson välisenä aikana kertyneen koron. +CUMPRINC = MAKSETTU.LYHENNYS ## Palauttaa lainalle kahden jakson välisenä aikana kertyneen lyhennyksen. +DB = DB ## Palauttaa kauden kirjanpidollisen poiston amerikkalaisen DB-menetelmän (Fixed-declining balance) mukaan. +DDB = DDB ## Palauttaa kauden kirjanpidollisen poiston amerikkalaisen DDB-menetelmän (Double-Declining Balance) tai jonkin muun määrittämäsi menetelmän mukaan. +DISC = DISKONTTOKORKO ## Palauttaa arvopaperin diskonttokoron. +DOLLARDE = VALUUTTA.DES ## Muuntaa murtolukuna ilmoitetun valuuttamäärän desimaaliluvuksi. +DOLLARFR = VALUUTTA.MURTO ## Muuntaa desimaalilukuna ilmaistun valuuttamäärän murtoluvuksi. +DURATION = KESTO ## Palauttaa keston arvopaperille, jonka koronmaksu tapahtuu säännöllisesti. +EFFECT = KORKO.EFEKT ## Palauttaa todellisen vuosikoron. +FV = TULEVA.ARVO ## Palauttaa sijoituksen tulevan arvon. +FVSCHEDULE = TULEVA.ARVO.ERIKORKO ## Palauttaa pääoman tulevan arvon, kun pääomalle on kertynyt korkoa vaihtelevasti. +INTRATE = KORKO.ARVOPAPERI ## Palauttaa arvopaperin korkokannan täysin sijoitetulle arvopaperille. +IPMT = IPMT ## Laskee sijoitukselle tai lainalle tiettynä ajanjaksona kertyvän koron. +IRR = SISÄINEN.KORKO ## Laskee sisäisen korkokannan kassavirrasta muodostuvalle sarjalle. +ISPMT = ONMAKSU ## Laskee sijoituksen maksetun koron tietyllä jaksolla. +MDURATION = KESTO.MUUNN ## Palauttaa muunnetun Macauley-keston arvopaperille, jonka oletettu nimellisarvo on 100 euroa. +MIRR = MSISÄINEN ## Palauttaa sisäisen korkokannan, kun positiivisten ja negatiivisten kassavirtojen rahoituskorko on erilainen. +NOMINAL = KORKO.VUOSI ## Palauttaa vuosittaisen nimelliskoron. +NPER = NJAKSO ## Palauttaa sijoituksen jaksojen määrän. +NPV = NNA ## Palauttaa sijoituksen nykyarvon toistuvista kassavirroista muodostuvan sarjan ja diskonttokoron perusteella. +ODDFPRICE = PARITON.ENS.NIMELLISARVO ## Palauttaa arvopaperin hinnan tilanteessa, jossa ensimmäinen jakso on pariton. +ODDFYIELD = PARITON.ENS.TUOTTO ## Palauttaa arvopaperin tuoton tilanteessa, jossa ensimmäinen jakso on pariton. +ODDLPRICE = PARITON.VIIM.NIMELLISARVO ## Palauttaa arvopaperin hinnan tilanteessa, jossa viimeinen jakso on pariton. +ODDLYIELD = PARITON.VIIM.TUOTTO ## Palauttaa arvopaperin tuoton tilanteessa, jossa viimeinen jakso on pariton. +PMT = MAKSU ## Palauttaa annuiteetin kausittaisen maksuerän. +PPMT = PPMT ## Laskee sijoitukselle tai lainalle tiettynä ajanjaksona maksettavan lyhennyksen. +PRICE = HINTA ## Palauttaa hinnan 100 euron nimellisarvoa kohden arvopaperille, jonka korko maksetaan säännöllisin väliajoin. +PRICEDISC = HINTA.DISK ## Palauttaa diskontatun arvopaperin hinnan 100 euron nimellisarvoa kohden. +PRICEMAT = HINTA.LUNASTUS ## Palauttaa hinnan 100 euron nimellisarvoa kohden arvopaperille, jonka korko maksetaan erääntymispäivänä. +PV = NA ## Palauttaa sijoituksen nykyarvon. +RATE = KORKO ## Palauttaa annuiteetin kausittaisen korkokannan. +RECEIVED = SAATU.HINTA ## Palauttaa arvopaperin tuoton erääntymispäivänä kokonaan maksetulle sijoitukselle. +SLN = STP ## Palauttaa sijoituksen tasapoiston yhdeltä jaksolta. +SYD = VUOSIPOISTO ## Palauttaa sijoituksen vuosipoiston annettuna kautena amerikkalaisen SYD-menetelmän (Sum-of-Year's Digits) avulla. +TBILLEQ = OBLIG.TUOTTOPROS ## Palauttaa valtion obligaation tuoton vastaavana joukkovelkakirjan tuottona. +TBILLPRICE = OBLIG.HINTA ## Palauttaa obligaation hinnan 100 euron nimellisarvoa kohden. +TBILLYIELD = OBLIG.TUOTTO ## Palauttaa obligaation tuoton. +VDB = VDB ## Palauttaa annetun kauden tai kauden osan kirjanpidollisen poiston amerikkalaisen DB-menetelmän (Fixed-declining balance) mukaan. +XIRR = SISÄINEN.KORKO.JAKSOTON ## Palauttaa sisäisen korkokannan kassavirtojen sarjoille, jotka eivät välttämättä ole säännöllisiä. +XNPV = NNA.JAKSOTON ## Palauttaa nettonykyarvon kassavirtasarjalle, joka ei välttämättä ole kausittainen. +YIELD = TUOTTO ## Palauttaa tuoton arvopaperille, jonka korko maksetaan säännöllisin väliajoin. +YIELDDISC = TUOTTO.DISK ## Palauttaa diskontatun arvopaperin, kuten obligaation, vuosittaisen tuoton. +YIELDMAT = TUOTTO.ERÄP ## Palauttaa erääntymispäivänään korkoa tuottavan arvopaperin vuosittaisen tuoton. + + +## +## Information functions Erikoisfunktiot +## +CELL = SOLU ## Palauttaa tietoja solun muotoilusta, sijainnista ja sisällöstä. +ERROR.TYPE = VIRHEEN.LAJI ## Palauttaa virhetyyppiä vastaavan luvun. +INFO = KUVAUS ## Palauttaa tietoja nykyisestä käyttöympäristöstä. +ISBLANK = ONTYHJÄ ## Palauttaa arvon TOSI, jos arvo on tyhjä. +ISERR = ONVIRH ## Palauttaa arvon TOSI, jos arvo on mikä tahansa virhearvo paitsi arvo #PUUTTUU!. +ISERROR = ONVIRHE ## Palauttaa arvon TOSI, jos arvo on mikä tahansa virhearvo. +ISEVEN = ONPARILLINEN ## Palauttaa arvon TOSI, jos arvo on parillinen. +ISLOGICAL = ONTOTUUS ## Palauttaa arvon TOSI, jos arvo on mikä tahansa looginen arvo. +ISNA = ONPUUTTUU ## Palauttaa arvon TOSI, jos virhearvo on #PUUTTUU!. +ISNONTEXT = ONEI_TEKSTI ## Palauttaa arvon TOSI, jos arvo ei ole teksti. +ISNUMBER = ONLUKU ## Palauttaa arvon TOSI, jos arvo on luku. +ISODD = ONPARITON ## Palauttaa arvon TOSI, jos arvo on pariton. +ISREF = ONVIITT ## Palauttaa arvon TOSI, jos arvo on viittaus. +ISTEXT = ONTEKSTI ## Palauttaa arvon TOSI, jos arvo on teksti. +N = N ## Palauttaa arvon luvuksi muunnettuna. +NA = PUUTTUU ## Palauttaa virhearvon #PUUTTUU!. +TYPE = TYYPPI ## Palauttaa luvun, joka ilmaisee arvon tietotyypin. + + +## +## Logical functions Loogiset funktiot +## +AND = JA ## Palauttaa arvon TOSI, jos kaikkien argumenttien arvo on TOSI. +FALSE = EPÄTOSI ## Palauttaa totuusarvon EPÄTOSI. +IF = JOS ## Määrittää suoritettavan loogisen testin. +IFERROR = JOSVIRHE ## Palauttaa määrittämäsi arvon, jos kaavan tulos on virhe; muussa tapauksessa palauttaa kaavan tuloksen. +NOT = EI ## Kääntää argumentin loogisen arvon. +OR = TAI ## Palauttaa arvon TOSI, jos minkä tahansa argumentin arvo on TOSI. +TRUE = TOSI ## Palauttaa totuusarvon TOSI. + + +## +## Lookup and reference functions Haku- ja viitefunktiot +## +ADDRESS = OSOITE ## Palauttaa laskentataulukon soluun osoittavan viittauksen tekstinä. +AREAS = ALUEET ## Palauttaa viittauksessa olevien alueiden määrän. +CHOOSE = VALITSE.INDEKSI ## Valitsee arvon arvoluettelosta. +COLUMN = SARAKE ## Palauttaa viittauksen sarakenumeron. +COLUMNS = SARAKKEET ## Palauttaa viittauksessa olevien sarakkeiden määrän. +HLOOKUP = VHAKU ## Suorittaa haun matriisin ylimmältä riviltä ja palauttaa määritetyn solun arvon. +HYPERLINK = HYPERLINKKI ## Luo pikakuvakkeen tai tekstin, joka avaa verkkopalvelimeen, intranetiin tai Internetiin tallennetun tiedoston. +INDEX = INDEKSI ## Valitsee arvon viittauksesta tai matriisista indeksin mukaan. +INDIRECT = EPÄSUORA ## Palauttaa tekstiarvona ilmaistun viittauksen. +LOOKUP = HAKU ## Etsii arvoja vektorista tai matriisista. +MATCH = VASTINE ## Etsii arvoja viittauksesta tai matriisista. +OFFSET = SIIRTYMÄ ## Palauttaa annetun viittauksen siirtymän. +ROW = RIVI ## Palauttaa viittauksen rivinumeron. +ROWS = RIVIT ## Palauttaa viittauksessa olevien rivien määrän. +RTD = RTD ## Noutaa COM-automaatiota (automaatio: Tapa käsitellä sovelluksen objekteja toisesta sovelluksesta tai kehitystyökalusta. Automaatio, jota aiemmin kutsuttiin OLE-automaatioksi, on teollisuusstandardi ja COM-mallin (Component Object Model) ominaisuus.) tukevasta ohjelmasta reaaliaikaisia tietoja. +TRANSPOSE = TRANSPONOI ## Palauttaa matriisin käänteismatriisin. +VLOOKUP = PHAKU ## Suorittaa haun matriisin ensimmäisestä sarakkeesta ja palauttaa rivillä olevan solun arvon. + + +## +## Math and trigonometry functions Matemaattiset ja trigonometriset funktiot +## +ABS = ITSEISARVO ## Palauttaa luvun itseisarvon. +ACOS = ACOS ## Palauttaa luvun arkuskosinin. +ACOSH = ACOSH ## Palauttaa luvun käänteisen hyperbolisen kosinin. +ASIN = ASIN ## Palauttaa luvun arkussinin. +ASINH = ASINH ## Palauttaa luvun käänteisen hyperbolisen sinin. +ATAN = ATAN ## Palauttaa luvun arkustangentin. +ATAN2 = ATAN2 ## Palauttaa arkustangentin x- ja y-koordinaatin perusteella. +ATANH = ATANH ## Palauttaa luvun käänteisen hyperbolisen tangentin. +CEILING = PYÖRISTÄ.KERR.YLÖS ## Pyöristää luvun lähimpään kokonaislukuun tai tarkkuusargumentin lähimpään kerrannaiseen. +COMBIN = KOMBINAATIO ## Palauttaa mahdollisten kombinaatioiden määrän annetulle objektien määrälle. +COS = COS ## Palauttaa luvun kosinin. +COSH = COSH ## Palauttaa luvun hyperbolisen kosinin. +DEGREES = ASTEET ## Muuntaa radiaanit asteiksi. +EVEN = PARILLINEN ## Pyöristää luvun ylöspäin lähimpään parilliseen kokonaislukuun. +EXP = EKSPONENTTI ## Palauttaa e:n korotettuna annetun luvun osoittamaan potenssiin. +FACT = KERTOMA ## Palauttaa luvun kertoman. +FACTDOUBLE = KERTOMA.OSA ## Palauttaa luvun osakertoman. +FLOOR = PYÖRISTÄ.KERR.ALAS ## Pyöristää luvun alaspäin (nollaa kohti). +GCD = SUURIN.YHT.TEKIJÄ ## Palauttaa suurimman yhteisen tekijän. +INT = KOKONAISLUKU ## Pyöristää luvun alaspäin lähimpään kokonaislukuun. +LCM = PIENIN.YHT.JAETTAVA ## Palauttaa pienimmän yhteisen tekijän. +LN = LUONNLOG ## Palauttaa luvun luonnollisen logaritmin. +LOG = LOG ## Laskee luvun logaritmin käyttämällä annettua kantalukua. +LOG10 = LOG10 ## Palauttaa luvun kymmenkantaisen logaritmin. +MDETERM = MDETERM ## Palauttaa matriisin matriisideterminantin. +MINVERSE = MKÄÄNTEINEN ## Palauttaa matriisin käänteismatriisin. +MMULT = MKERRO ## Palauttaa kahden matriisin tulon. +MOD = JAKOJ ## Palauttaa jakolaskun jäännöksen. +MROUND = PYÖRISTÄ.KERR ## Palauttaa luvun pyöristettynä annetun luvun kerrannaiseen. +MULTINOMIAL = MULTINOMI ## Palauttaa lukujoukon multinomin. +ODD = PARITON ## Pyöristää luvun ylöspäin lähimpään parittomaan kokonaislukuun. +PI = PII ## Palauttaa piin arvon. +POWER = POTENSSI ## Palauttaa luvun korotettuna haluttuun potenssiin. +PRODUCT = TULO ## Kertoo annetut argumentit. +QUOTIENT = OSAMÄÄRÄ ## Palauttaa osamäärän kokonaislukuosan. +RADIANS = RADIAANIT ## Muuntaa asteet radiaaneiksi. +RAND = SATUNNAISLUKU ## Palauttaa satunnaisluvun väliltä 0–1. +RANDBETWEEN = SATUNNAISLUKU.VÄLILTÄ ## Palauttaa satunnaisluvun määritettyjen lukujen väliltä. +ROMAN = ROMAN ## Muuntaa arabialaisen numeron tekstimuotoiseksi roomalaiseksi numeroksi. +ROUND = PYÖRISTÄ ## Pyöristää luvun annettuun määrään desimaaleja. +ROUNDDOWN = PYÖRISTÄ.DES.ALAS ## Pyöristää luvun alaspäin (nollaa kohti). +ROUNDUP = PYÖRISTÄ.DES.YLÖS ## Pyöristää luvun ylöspäin (poispäin nollasta). +SERIESSUM = SARJA.SUMMA ## Palauttaa kaavaan perustuvan potenssisarjan arvon. +SIGN = ETUMERKKI ## Palauttaa luvun etumerkin. +SIN = SIN ## Palauttaa annetun kulman sinin. +SINH = SINH ## Palauttaa luvun hyperbolisen sinin. +SQRT = NELIÖJUURI ## Palauttaa positiivisen neliöjuuren. +SQRTPI = NELIÖJUURI.PII ## Palauttaa tulon (luku * pii) neliöjuuren. +SUBTOTAL = VÄLISUMMA ## Palauttaa luettelon tai tietokannan välisumman. +SUM = SUMMA ## Laskee yhteen annetut argumentit. +SUMIF = SUMMA.JOS ## Laskee ehdot täyttävien solujen summan. +SUMIFS = SUMMA.JOS.JOUKKO ## Laskee yhteen solualueen useita ehtoja vastaavat solut. +SUMPRODUCT = TULOJEN.SUMMA ## Palauttaa matriisin toisiaan vastaavien osien tulojen summan. +SUMSQ = NELIÖSUMMA ## Palauttaa argumenttien neliöiden summan. +SUMX2MY2 = NELIÖSUMMIEN.EROTUS ## Palauttaa kahden matriisin toisiaan vastaavien arvojen laskettujen neliösummien erotuksen. +SUMX2PY2 = NELIÖSUMMIEN.SUMMA ## Palauttaa kahden matriisin toisiaan vastaavien arvojen neliösummien summan. +SUMXMY2 = EROTUSTEN.NELIÖSUMMA ## Palauttaa kahden matriisin toisiaan vastaavien arvojen erotusten neliösumman. +TAN = TAN ## Palauttaa luvun tangentin. +TANH = TANH ## Palauttaa luvun hyperbolisen tangentin. +TRUNC = KATKAISE ## Katkaisee luvun kokonaisluvuksi. + + +## +## Statistical functions Tilastolliset funktiot +## +AVEDEV = KESKIPOIKKEAMA ## Palauttaa hajontojen itseisarvojen keskiarvon. +AVERAGE = KESKIARVO ## Palauttaa argumenttien keskiarvon. +AVERAGEA = KESKIARVOA ## Palauttaa argumenttien, mukaan lukien lukujen, tekstin ja loogisten arvojen, keskiarvon. +AVERAGEIF = KESKIARVO.JOS ## Palauttaa alueen niiden solujen keskiarvon (aritmeettisen keskiarvon), jotka täyttävät annetut ehdot. +AVERAGEIFS = KESKIARVO.JOS.JOUKKO ## Palauttaa niiden solujen keskiarvon (aritmeettisen keskiarvon), jotka vastaavat useita ehtoja. +BETADIST = BEETAJAKAUMA ## Palauttaa kumulatiivisen beetajakaumafunktion arvon. +BETAINV = BEETAJAKAUMA.KÄÄNT ## Palauttaa määritetyn beetajakauman käänteisen kumulatiivisen jakaumafunktion arvon. +BINOMDIST = BINOMIJAKAUMA ## Palauttaa yksittäisen termin binomijakaumatodennäköisyyden. +CHIDIST = CHIJAKAUMA ## Palauttaa yksisuuntaisen chi-neliön jakauman todennäköisyyden. +CHIINV = CHIJAKAUMA.KÄÄNT ## Palauttaa yksisuuntaisen chi-neliön jakauman todennäköisyyden käänteisarvon. +CHITEST = CHITESTI ## Palauttaa riippumattomuustestin tuloksen. +CONFIDENCE = LUOTTAMUSVÄLI ## Palauttaa luottamusvälin populaation keskiarvolle. +CORREL = KORRELAATIO ## Palauttaa kahden arvojoukon korrelaatiokertoimen. +COUNT = LASKE ## Laskee argumenttiluettelossa olevien lukujen määrän. +COUNTA = LASKE.A ## Laskee argumenttiluettelossa olevien arvojen määrän. +COUNTBLANK = LASKE.TYHJÄT ## Laskee alueella olevien tyhjien solujen määrän. +COUNTIF = LASKE.JOS ## Laskee alueella olevien sellaisten solujen määrän, joiden sisältö vastaa annettuja ehtoja. +COUNTIFS = LASKE.JOS.JOUKKO ## Laskee alueella olevien sellaisten solujen määrän, joiden sisältö vastaa useita ehtoja. +COVAR = KOVARIANSSI ## Palauttaa kovarianssin, joka on keskiarvo havaintoaineiston kunkin pisteparin poikkeamien tuloista. +CRITBINOM = BINOMIJAKAUMA.KRIT ## Palauttaa pienimmän arvon, jossa binomijakauman kertymäfunktion arvo on pienempi tai yhtä suuri kuin vertailuarvo. +DEVSQ = OIKAISTU.NELIÖSUMMA ## Palauttaa keskipoikkeamien neliösumman. +EXPONDIST = EKSPONENTIAALIJAKAUMA ## Palauttaa eksponentiaalijakauman. +FDIST = FJAKAUMA ## Palauttaa F-todennäköisyysjakauman. +FINV = FJAKAUMA.KÄÄNT ## Palauttaa F-todennäköisyysjakauman käänteisfunktion. +FISHER = FISHER ## Palauttaa Fisher-muunnoksen. +FISHERINV = FISHER.KÄÄNT ## Palauttaa käänteisen Fisher-muunnoksen. +FORECAST = ENNUSTE ## Palauttaa lineaarisen trendin arvon. +FREQUENCY = TAAJUUS ## Palauttaa frekvenssijakautuman pystysuuntaisena matriisina. +FTEST = FTESTI ## Palauttaa F-testin tuloksen. +GAMMADIST = GAMMAJAKAUMA ## Palauttaa gammajakauman. +GAMMAINV = GAMMAJAKAUMA.KÄÄNT ## Palauttaa käänteisen gammajakauman kertymäfunktion. +GAMMALN = GAMMALN ## Palauttaa gammafunktion luonnollisen logaritmin G(x). +GEOMEAN = KESKIARVO.GEOM ## Palauttaa geometrisen keskiarvon. +GROWTH = KASVU ## Palauttaa eksponentiaalisen trendin arvon. +HARMEAN = KESKIARVO.HARM ## Palauttaa harmonisen keskiarvon. +HYPGEOMDIST = HYPERGEOM.JAKAUMA ## Palauttaa hypergeometrisen jakauman. +INTERCEPT = LEIKKAUSPISTE ## Palauttaa lineaarisen regressiosuoran leikkauspisteen. +KURT = KURT ## Palauttaa tietoalueen vinous-arvon eli huipukkuuden. +LARGE = SUURI ## Palauttaa tietojoukon k:nneksi suurimman arvon. +LINEST = LINREGR ## Palauttaa lineaarisen trendin parametrit. +LOGEST = LOGREGR ## Palauttaa eksponentiaalisen trendin parametrit. +LOGINV = LOGNORM.JAKAUMA.KÄÄNT ## Palauttaa lognormeeratun jakauman käänteisfunktion. +LOGNORMDIST = LOGNORM.JAKAUMA ## Palauttaa lognormaalisen jakauman kertymäfunktion. +MAX = MAKS ## Palauttaa suurimman arvon argumenttiluettelosta. +MAXA = MAKSA ## Palauttaa argumenttien, mukaan lukien lukujen, tekstin ja loogisten arvojen, suurimman arvon. +MEDIAN = MEDIAANI ## Palauttaa annettujen lukujen mediaanin. +MIN = MIN ## Palauttaa pienimmän arvon argumenttiluettelosta. +MINA = MINA ## Palauttaa argumenttien, mukaan lukien lukujen, tekstin ja loogisten arvojen, pienimmän arvon. +MODE = MOODI ## Palauttaa tietojoukossa useimmin esiintyvän arvon. +NEGBINOMDIST = BINOMIJAKAUMA.NEG ## Palauttaa negatiivisen binomijakauman. +NORMDIST = NORM.JAKAUMA ## Palauttaa normaalijakauman kertymäfunktion. +NORMINV = NORM.JAKAUMA.KÄÄNT ## Palauttaa käänteisen normaalijakauman kertymäfunktion. +NORMSDIST = NORM.JAKAUMA.NORMIT ## Palauttaa normitetun normaalijakauman kertymäfunktion. +NORMSINV = NORM.JAKAUMA.NORMIT.KÄÄNT ## Palauttaa normitetun normaalijakauman kertymäfunktion käänteisarvon. +PEARSON = PEARSON ## Palauttaa Pearsonin tulomomenttikorrelaatiokertoimen. +PERCENTILE = PROSENTTIPISTE ## Palauttaa alueen arvojen k:nnen prosenttipisteen. +PERCENTRANK = PROSENTTIJÄRJESTYS ## Palauttaa tietojoukon arvon prosentuaalisen järjestysluvun. +PERMUT = PERMUTAATIO ## Palauttaa mahdollisten permutaatioiden määrän annetulle objektien määrälle. +POISSON = POISSON ## Palauttaa Poissonin todennäköisyysjakauman. +PROB = TODENNÄKÖISYYS ## Palauttaa todennäköisyyden sille, että arvot ovat tietyltä väliltä. +QUARTILE = NELJÄNNES ## Palauttaa tietoalueen neljänneksen. +RANK = ARVON.MUKAAN ## Palauttaa luvun paikan lukuarvoluettelossa. +RSQ = PEARSON.NELIÖ ## Palauttaa Pearsonin tulomomenttikorrelaatiokertoimen neliön. +SKEW = JAKAUMAN.VINOUS ## Palauttaa jakauman vinouden. +SLOPE = KULMAKERROIN ## Palauttaa lineaarisen regressiosuoran kulmakertoimen. +SMALL = PIENI ## Palauttaa tietojoukon k:nneksi pienimmän arvon. +STANDARDIZE = NORMITA ## Palauttaa normitetun arvon. +STDEV = KESKIHAJONTA ## Laskee populaation keskihajonnan otoksen perusteella. +STDEVA = KESKIHAJONTAA ## Laskee populaation keskihajonnan otoksen perusteella, mukaan lukien luvut, tekstin ja loogiset arvot. +STDEVP = KESKIHAJONTAP ## Laskee normaalijakautuman koko populaation perusteella. +STDEVPA = KESKIHAJONTAPA ## Laskee populaation keskihajonnan koko populaation perusteella, mukaan lukien luvut, tekstin ja totuusarvot. +STEYX = KESKIVIRHE ## Palauttaa regression kutakin x-arvoa vastaavan ennustetun y-arvon keskivirheen. +TDIST = TJAKAUMA ## Palauttaa t-jakautuman. +TINV = TJAKAUMA.KÄÄNT ## Palauttaa käänteisen t-jakauman. +TREND = SUUNTAUS ## Palauttaa lineaarisen trendin arvoja. +TRIMMEAN = KESKIARVO.TASATTU ## Palauttaa tietojoukon tasatun keskiarvon. +TTEST = TTESTI ## Palauttaa t-testiin liittyvän todennäköisyyden. +VAR = VAR ## Arvioi populaation varianssia otoksen perusteella. +VARA = VARA ## Laskee populaation varianssin otoksen perusteella, mukaan lukien luvut, tekstin ja loogiset arvot. +VARP = VARP ## Laskee varianssin koko populaation perusteella. +VARPA = VARPA ## Laskee populaation varianssin koko populaation perusteella, mukaan lukien luvut, tekstin ja totuusarvot. +WEIBULL = WEIBULL ## Palauttaa Weibullin jakauman. +ZTEST = ZTESTI ## Palauttaa z-testin yksisuuntaisen todennäköisyysarvon. + + +## +## Text functions Tekstifunktiot +## +ASC = ASC ## Muuntaa merkkijonossa olevat englanninkieliset DBCS- tai katakana-merkit SBCS-merkeiksi. +BAHTTEXT = BAHTTEKSTI ## Muuntaa luvun tekstiksi ß (baht) -valuuttamuotoa käyttämällä. +CHAR = MERKKI ## Palauttaa koodin lukua vastaavan merkin. +CLEAN = SIIVOA ## Poistaa tekstistä kaikki tulostumattomat merkit. +CODE = KOODI ## Palauttaa tekstimerkkijonon ensimmäisen merkin numerokoodin. +CONCATENATE = KETJUTA ## Yhdistää useat merkkijonot yhdeksi merkkijonoksi. +DOLLAR = VALUUTTA ## Muuntaa luvun tekstiksi $ (dollari) -valuuttamuotoa käyttämällä. +EXACT = VERTAA ## Tarkistaa, ovatko kaksi tekstiarvoa samanlaiset. +FIND = ETSI ## Etsii tekstiarvon toisen tekstin sisältä (tunnistaa isot ja pienet kirjaimet). +FINDB = ETSIB ## Etsii tekstiarvon toisen tekstin sisältä (tunnistaa isot ja pienet kirjaimet). +FIXED = KIINTEÄ ## Muotoilee luvun tekstiksi, jossa on kiinteä määrä desimaaleja. +JIS = JIS ## Muuntaa merkkijonossa olevat englanninkieliset SBCS- tai katakana-merkit DBCS-merkeiksi. +LEFT = VASEN ## Palauttaa tekstiarvon vasemmanpuoliset merkit. +LEFTB = VASENB ## Palauttaa tekstiarvon vasemmanpuoliset merkit. +LEN = PITUUS ## Palauttaa tekstimerkkijonon merkkien määrän. +LENB = PITUUSB ## Palauttaa tekstimerkkijonon merkkien määrän. +LOWER = PIENET ## Muuntaa tekstin pieniksi kirjaimiksi. +MID = POIMI.TEKSTI ## Palauttaa määritetyn määrän merkkejä merkkijonosta alkaen annetusta kohdasta. +MIDB = POIMI.TEKSTIB ## Palauttaa määritetyn määrän merkkejä merkkijonosta alkaen annetusta kohdasta. +PHONETIC = FONEETTINEN ## Hakee foneettiset (furigana) merkit merkkijonosta. +PROPER = ERISNIMI ## Muuttaa merkkijonon kunkin sanan ensimmäisen kirjaimen isoksi. +REPLACE = KORVAA ## Korvaa tekstissä olevat merkit. +REPLACEB = KORVAAB ## Korvaa tekstissä olevat merkit. +REPT = TOISTA ## Toistaa tekstin annetun määrän kertoja. +RIGHT = OIKEA ## Palauttaa tekstiarvon oikeanpuoliset merkit. +RIGHTB = OIKEAB ## Palauttaa tekstiarvon oikeanpuoliset merkit. +SEARCH = KÄY.LÄPI ## Etsii tekstiarvon toisen tekstin sisältä (isot ja pienet kirjaimet tulkitaan samoiksi merkeiksi). +SEARCHB = KÄY.LÄPIB ## Etsii tekstiarvon toisen tekstin sisältä (isot ja pienet kirjaimet tulkitaan samoiksi merkeiksi). +SUBSTITUTE = VAIHDA ## Korvaa merkkijonossa olevan tekstin toisella. +T = T ## Muuntaa argumentit tekstiksi. +TEXT = TEKSTI ## Muotoilee luvun ja muuntaa sen tekstiksi. +TRIM = POISTA.VÄLIT ## Poistaa välilyönnit tekstistä. +UPPER = ISOT ## Muuntaa tekstin isoiksi kirjaimiksi. +VALUE = ARVO ## Muuntaa tekstiargumentin luvuksi. diff --git a/lib/phpexcel/PHPExcel/locale/fr/config b/lib/phpexcel/PHPExcel/locale/fr/config new file mode 100644 index 0000000..368b3c3 --- /dev/null +++ b/lib/phpexcel/PHPExcel/locale/fr/config @@ -0,0 +1,47 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Settings +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## + + +ArgumentSeparator = ; + + +## +## (For future use) +## +currencySymbol = € + + +## +## Excel Error Codes (For future use) +## +NULL = #NUL! +DIV0 = #DIV/0! +VALUE = #VALEUR! +REF = #REF! +NAME = #NOM? +NUM = #NOMBRE! +NA = #N/A diff --git a/lib/phpexcel/PHPExcel/locale/fr/functions b/lib/phpexcel/PHPExcel/locale/fr/functions new file mode 100644 index 0000000..e85dba5 --- /dev/null +++ b/lib/phpexcel/PHPExcel/locale/fr/functions @@ -0,0 +1,438 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Calculation +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## Data in this file derived from http://www.piuha.fi/excel-function-name-translation/ +## +## + + +## +## Add-in and Automation functions Fonctions de complément et d’automatisation +## +GETPIVOTDATA = LIREDONNEESTABCROISDYNAMIQUE ## Renvoie les données stockées dans un rapport de tableau croisé dynamique. + + +## +## Cube functions Fonctions Cube +## +CUBEKPIMEMBER = MEMBREKPICUBE ## Renvoie un nom, une propriété et une mesure d’indicateur de performance clé et affiche le nom et la propriété dans la cellule. Un indicateur de performance clé est une mesure quantifiable, telle que la marge bénéficiaire brute mensuelle ou la rotation trimestrielle du personnel, utilisée pour évaluer les performances d’une entreprise. +CUBEMEMBER = MEMBRECUBE ## Renvoie un membre ou un uplet dans une hiérarchie de cubes. Utilisez cette fonction pour valider l’existence du membre ou de l’uplet dans le cube. +CUBEMEMBERPROPERTY = PROPRIETEMEMBRECUBE ## Renvoie la valeur d’une propriété de membre du cube. Utilisez cette fonction pour valider l’existence d’un nom de membre dans le cube et pour renvoyer la propriété spécifiée pour ce membre. +CUBERANKEDMEMBER = RANGMEMBRECUBE ## Renvoie le nième membre ou le membre placé à un certain rang dans un ensemble. Utilisez cette fonction pour renvoyer un ou plusieurs éléments d’un ensemble, tels que les meilleurs vendeurs ou les 10 meilleurs étudiants. +CUBESET = JEUCUBE ## Définit un ensemble calculé de membres ou d’uplets en envoyant une expression définie au cube sur le serveur qui crée l’ensemble et le renvoie à Microsoft Office Excel. +CUBESETCOUNT = NBJEUCUBE ## Renvoie le nombre d’éléments dans un jeu. +CUBEVALUE = VALEURCUBE ## Renvoie une valeur d’agrégation issue d’un cube. + + +## +## Database functions Fonctions de base de données +## +DAVERAGE = BDMOYENNE ## Renvoie la moyenne des entrées de base de données sélectionnées. +DCOUNT = BCOMPTE ## Compte le nombre de cellules d’une base de données qui contiennent des nombres. +DCOUNTA = BDNBVAL ## Compte les cellules non vides d’une base de données. +DGET = BDLIRE ## Extrait d’une base de données un enregistrement unique répondant aux critères spécifiés. +DMAX = BDMAX ## Renvoie la valeur maximale des entrées de base de données sélectionnées. +DMIN = BDMIN ## Renvoie la valeur minimale des entrées de base de données sélectionnées. +DPRODUCT = BDPRODUIT ## Multiplie les valeurs d’un champ particulier des enregistrements d’une base de données, qui répondent aux critères spécifiés. +DSTDEV = BDECARTYPE ## Calcule l’écart type pour un échantillon d’entrées de base de données sélectionnées. +DSTDEVP = BDECARTYPEP ## Calcule l’écart type pour l’ensemble d’une population d’entrées de base de données sélectionnées. +DSUM = BDSOMME ## Ajoute les nombres dans la colonne de champ des enregistrements de la base de données, qui répondent aux critères. +DVAR = BDVAR ## Calcule la variance pour un échantillon d’entrées de base de données sélectionnées. +DVARP = BDVARP ## Calcule la variance pour l’ensemble d’une population d’entrées de base de données sélectionnées. + + +## +## Date and time functions Fonctions de date et d’heure +## +DATE = DATE ## Renvoie le numéro de série d’une date précise. +DATEVALUE = DATEVAL ## Convertit une date représentée sous forme de texte en numéro de série. +DAY = JOUR ## Convertit un numéro de série en jour du mois. +DAYS360 = JOURS360 ## Calcule le nombre de jours qui séparent deux dates sur la base d’une année de 360 jours. +EDATE = MOIS.DECALER ## Renvoie le numéro séquentiel de la date qui représente une date spécifiée (l’argument date_départ), corrigée en plus ou en moins du nombre de mois indiqué. +EOMONTH = FIN.MOIS ## Renvoie le numéro séquentiel de la date du dernier jour du mois précédant ou suivant la date_départ du nombre de mois indiqué. +HOUR = HEURE ## Convertit un numéro de série en heure. +MINUTE = MINUTE ## Convertit un numéro de série en minute. +MONTH = MOIS ## Convertit un numéro de série en mois. +NETWORKDAYS = NB.JOURS.OUVRES ## Renvoie le nombre de jours ouvrés entiers compris entre deux dates. +NOW = MAINTENANT ## Renvoie le numéro de série de la date et de l’heure du jour. +SECOND = SECONDE ## Convertit un numéro de série en seconde. +TIME = TEMPS ## Renvoie le numéro de série d’une heure précise. +TIMEVALUE = TEMPSVAL ## Convertit une date représentée sous forme de texte en numéro de série. +TODAY = AUJOURDHUI ## Renvoie le numéro de série de la date du jour. +WEEKDAY = JOURSEM ## Convertit un numéro de série en jour de la semaine. +WEEKNUM = NO.SEMAINE ## Convertit un numéro de série en un numéro représentant l’ordre de la semaine dans l’année. +WORKDAY = SERIE.JOUR.OUVRE ## Renvoie le numéro de série de la date avant ou après le nombre de jours ouvrés spécifiés. +YEAR = ANNEE ## Convertit un numéro de série en année. +YEARFRAC = FRACTION.ANNEE ## Renvoie la fraction de l’année représentant le nombre de jours entre la date de début et la date de fin. + + +## +## Engineering functions Fonctions d’ingénierie +## +BESSELI = BESSELI ## Renvoie la fonction Bessel modifiée In(x). +BESSELJ = BESSELJ ## Renvoie la fonction Bessel Jn(x). +BESSELK = BESSELK ## Renvoie la fonction Bessel modifiée Kn(x). +BESSELY = BESSELY ## Renvoie la fonction Bessel Yn(x). +BIN2DEC = BINDEC ## Convertit un nombre binaire en nombre décimal. +BIN2HEX = BINHEX ## Convertit un nombre binaire en nombre hexadécimal. +BIN2OCT = BINOCT ## Convertit un nombre binaire en nombre octal. +COMPLEX = COMPLEXE ## Convertit des coefficients réel et imaginaire en un nombre complexe. +CONVERT = CONVERT ## Convertit un nombre d’une unité de mesure à une autre. +DEC2BIN = DECBIN ## Convertit un nombre décimal en nombre binaire. +DEC2HEX = DECHEX ## Convertit un nombre décimal en nombre hexadécimal. +DEC2OCT = DECOCT ## Convertit un nombre décimal en nombre octal. +DELTA = DELTA ## Teste l’égalité de deux nombres. +ERF = ERF ## Renvoie la valeur de la fonction d’erreur. +ERFC = ERFC ## Renvoie la valeur de la fonction d’erreur complémentaire. +GESTEP = SUP.SEUIL ## Teste si un nombre est supérieur à une valeur de seuil. +HEX2BIN = HEXBIN ## Convertit un nombre hexadécimal en nombre binaire. +HEX2DEC = HEXDEC ## Convertit un nombre hexadécimal en nombre décimal. +HEX2OCT = HEXOCT ## Convertit un nombre hexadécimal en nombre octal. +IMABS = COMPLEXE.MODULE ## Renvoie la valeur absolue (module) d’un nombre complexe. +IMAGINARY = COMPLEXE.IMAGINAIRE ## Renvoie le coefficient imaginaire d’un nombre complexe. +IMARGUMENT = COMPLEXE.ARGUMENT ## Renvoie l’argument thêta, un angle exprimé en radians. +IMCONJUGATE = COMPLEXE.CONJUGUE ## Renvoie le nombre complexe conjugué d’un nombre complexe. +IMCOS = IMCOS ## Renvoie le cosinus d’un nombre complexe. +IMDIV = COMPLEXE.DIV ## Renvoie le quotient de deux nombres complexes. +IMEXP = COMPLEXE.EXP ## Renvoie la fonction exponentielle d’un nombre complexe. +IMLN = COMPLEXE.LN ## Renvoie le logarithme népérien d’un nombre complexe. +IMLOG10 = COMPLEXE.LOG10 ## Calcule le logarithme en base 10 d’un nombre complexe. +IMLOG2 = COMPLEXE.LOG2 ## Calcule le logarithme en base 2 d’un nombre complexe. +IMPOWER = COMPLEXE.PUISSANCE ## Renvoie un nombre complexe élevé à une puissance entière. +IMPRODUCT = COMPLEXE.PRODUIT ## Renvoie le produit de plusieurs nombres complexes. +IMREAL = COMPLEXE.REEL ## Renvoie le coefficient réel d’un nombre complexe. +IMSIN = COMPLEXE.SIN ## Renvoie le sinus d’un nombre complexe. +IMSQRT = COMPLEXE.RACINE ## Renvoie la racine carrée d’un nombre complexe. +IMSUB = COMPLEXE.DIFFERENCE ## Renvoie la différence entre deux nombres complexes. +IMSUM = COMPLEXE.SOMME ## Renvoie la somme de plusieurs nombres complexes. +OCT2BIN = OCTBIN ## Convertit un nombre octal en nombre binaire. +OCT2DEC = OCTDEC ## Convertit un nombre octal en nombre décimal. +OCT2HEX = OCTHEX ## Convertit un nombre octal en nombre hexadécimal. + + +## +## Financial functions Fonctions financières +## +ACCRINT = INTERET.ACC ## Renvoie l’intérêt couru non échu d’un titre dont l’intérêt est perçu périodiquement. +ACCRINTM = INTERET.ACC.MAT ## Renvoie l’intérêt couru non échu d’un titre dont l’intérêt est perçu à l’échéance. +AMORDEGRC = AMORDEGRC ## Renvoie l’amortissement correspondant à chaque période comptable en utilisant un coefficient d’amortissement. +AMORLINC = AMORLINC ## Renvoie l’amortissement d’un bien à la fin d’une période fiscale donnée. +COUPDAYBS = NB.JOURS.COUPON.PREC ## Renvoie le nombre de jours entre le début de la période de coupon et la date de liquidation. +COUPDAYS = NB.JOURS.COUPONS ## Renvoie le nombre de jours pour la période du coupon contenant la date de liquidation. +COUPDAYSNC = NB.JOURS.COUPON.SUIV ## Renvoie le nombre de jours entre la date de liquidation et la date du coupon suivant la date de liquidation. +COUPNCD = DATE.COUPON.SUIV ## Renvoie la première date de coupon ultérieure à la date de règlement. +COUPNUM = NB.COUPONS ## Renvoie le nombre de coupons dus entre la date de règlement et la date d’échéance. +COUPPCD = DATE.COUPON.PREC ## Renvoie la date de coupon précédant la date de règlement. +CUMIPMT = CUMUL.INTER ## Renvoie l’intérêt cumulé payé sur un emprunt entre deux périodes. +CUMPRINC = CUMUL.PRINCPER ## Renvoie le montant cumulé des remboursements du capital d’un emprunt effectués entre deux périodes. +DB = DB ## Renvoie l’amortissement d’un bien pour une période spécifiée en utilisant la méthode de l’amortissement dégressif à taux fixe. +DDB = DDB ## Renvoie l’amortissement d’un bien pour toute période spécifiée, en utilisant la méthode de l’amortissement dégressif à taux double ou selon un coefficient à spécifier. +DISC = TAUX.ESCOMPTE ## Calcule le taux d’escompte d’une transaction. +DOLLARDE = PRIX.DEC ## Convertit un prix en euros, exprimé sous forme de fraction, en un prix en euros exprimé sous forme de nombre décimal. +DOLLARFR = PRIX.FRAC ## Convertit un prix en euros, exprimé sous forme de nombre décimal, en un prix en euros exprimé sous forme de fraction. +DURATION = DUREE ## Renvoie la durée, en années, d’un titre dont l’intérêt est perçu périodiquement. +EFFECT = TAUX.EFFECTIF ## Renvoie le taux d’intérêt annuel effectif. +FV = VC ## Renvoie la valeur future d’un investissement. +FVSCHEDULE = VC.PAIEMENTS ## Calcule la valeur future d’un investissement en appliquant une série de taux d’intérêt composites. +INTRATE = TAUX.INTERET ## Affiche le taux d’intérêt d’un titre totalement investi. +IPMT = INTPER ## Calcule le montant des intérêts d’un investissement pour une période donnée. +IRR = TRI ## Calcule le taux de rentabilité interne d’un investissement pour une succession de trésoreries. +ISPMT = ISPMT ## Calcule le montant des intérêts d’un investissement pour une période donnée. +MDURATION = DUREE.MODIFIEE ## Renvoie la durée de Macauley modifiée pour un titre ayant une valeur nominale hypothétique de 100_euros. +MIRR = TRIM ## Calcule le taux de rentabilité interne lorsque les paiements positifs et négatifs sont financés à des taux différents. +NOMINAL = TAUX.NOMINAL ## Calcule le taux d’intérêt nominal annuel. +NPER = NPM ## Renvoie le nombre de versements nécessaires pour rembourser un emprunt. +NPV = VAN ## Calcule la valeur actuelle nette d’un investissement basé sur une série de décaissements et un taux d’escompte. +ODDFPRICE = PRIX.PCOUPON.IRREG ## Renvoie le prix par tranche de valeur nominale de 100 euros d’un titre dont la première période de coupon est irrégulière. +ODDFYIELD = REND.PCOUPON.IRREG ## Renvoie le taux de rendement d’un titre dont la première période de coupon est irrégulière. +ODDLPRICE = PRIX.DCOUPON.IRREG ## Renvoie le prix par tranche de valeur nominale de 100 euros d’un titre dont la première période de coupon est irrégulière. +ODDLYIELD = REND.DCOUPON.IRREG ## Renvoie le taux de rendement d’un titre dont la dernière période de coupon est irrégulière. +PMT = VPM ## Calcule le paiement périodique d’un investissement donné. +PPMT = PRINCPER ## Calcule, pour une période donnée, la part de remboursement du principal d’un investissement. +PRICE = PRIX.TITRE ## Renvoie le prix d’un titre rapportant des intérêts périodiques, pour une valeur nominale de 100 euros. +PRICEDISC = VALEUR.ENCAISSEMENT ## Renvoie la valeur d’encaissement d’un escompte commercial, pour une valeur nominale de 100 euros. +PRICEMAT = PRIX.TITRE.ECHEANCE ## Renvoie le prix d’un titre dont la valeur nominale est 100 euros et qui rapporte des intérêts à l’échéance. +PV = PV ## Calcule la valeur actuelle d’un investissement. +RATE = TAUX ## Calcule le taux d’intérêt par période pour une annuité. +RECEIVED = VALEUR.NOMINALE ## Renvoie la valeur nominale à échéance d’un effet de commerce. +SLN = AMORLIN ## Calcule l’amortissement linéaire d’un bien pour une période donnée. +SYD = SYD ## Calcule l’amortissement d’un bien pour une période donnée sur la base de la méthode américaine Sum-of-Years Digits (amortissement dégressif à taux décroissant appliqué à une valeur constante). +TBILLEQ = TAUX.ESCOMPTE.R ## Renvoie le taux d’escompte rationnel d’un bon du Trésor. +TBILLPRICE = PRIX.BON.TRESOR ## Renvoie le prix d’un bon du Trésor d’une valeur nominale de 100 euros. +TBILLYIELD = RENDEMENT.BON.TRESOR ## Calcule le taux de rendement d’un bon du Trésor. +VDB = VDB ## Renvoie l’amortissement d’un bien pour une période spécifiée ou partielle en utilisant une méthode de l’amortissement dégressif à taux fixe. +XIRR = TRI.PAIEMENTS ## Calcule le taux de rentabilité interne d’un ensemble de paiements non périodiques. +XNPV = VAN.PAIEMENTS ## Renvoie la valeur actuelle nette d’un ensemble de paiements non périodiques. +YIELD = RENDEMENT.TITRE ## Calcule le rendement d’un titre rapportant des intérêts périodiquement. +YIELDDISC = RENDEMENT.SIMPLE ## Calcule le taux de rendement d’un emprunt à intérêt simple (par exemple, un bon du Trésor). +YIELDMAT = RENDEMENT.TITRE.ECHEANCE ## Renvoie le rendement annuel d’un titre qui rapporte des intérêts à l’échéance. + + +## +## Information functions Fonctions d’information +## +CELL = CELLULE ## Renvoie des informations sur la mise en forme, l’emplacement et le contenu d’une cellule. +ERROR.TYPE = TYPE.ERREUR ## Renvoie un nombre correspondant à un type d’erreur. +INFO = INFORMATIONS ## Renvoie des informations sur l’environnement d’exploitation actuel. +ISBLANK = ESTVIDE ## Renvoie VRAI si l’argument valeur est vide. +ISERR = ESTERR ## Renvoie VRAI si l’argument valeur fait référence à une valeur d’erreur, sauf #N/A. +ISERROR = ESTERREUR ## Renvoie VRAI si l’argument valeur fait référence à une valeur d’erreur. +ISEVEN = EST.PAIR ## Renvoie VRAI si le chiffre est pair. +ISLOGICAL = ESTLOGIQUE ## Renvoie VRAI si l’argument valeur fait référence à une valeur logique. +ISNA = ESTNA ## Renvoie VRAI si l’argument valeur fait référence à la valeur d’erreur #N/A. +ISNONTEXT = ESTNONTEXTE ## Renvoie VRAI si l’argument valeur ne se présente pas sous forme de texte. +ISNUMBER = ESTNUM ## Renvoie VRAI si l’argument valeur représente un nombre. +ISODD = EST.IMPAIR ## Renvoie VRAI si le chiffre est impair. +ISREF = ESTREF ## Renvoie VRAI si l’argument valeur est une référence. +ISTEXT = ESTTEXTE ## Renvoie VRAI si l’argument valeur se présente sous forme de texte. +N = N ## Renvoie une valeur convertie en nombre. +NA = NA ## Renvoie la valeur d’erreur #N/A. +TYPE = TYPE ## Renvoie un nombre indiquant le type de données d’une valeur. + + +## +## Logical functions Fonctions logiques +## +AND = ET ## Renvoie VRAI si tous ses arguments sont VRAI. +FALSE = FAUX ## Renvoie la valeur logique FAUX. +IF = SI ## Spécifie un test logique à effectuer. +IFERROR = SIERREUR ## Renvoie une valeur que vous spécifiez si une formule génère une erreur ; sinon, elle renvoie le résultat de la formule. +NOT = NON ## Inverse la logique de cet argument. +OR = OU ## Renvoie VRAI si un des arguments est VRAI. +TRUE = VRAI ## Renvoie la valeur logique VRAI. + + +## +## Lookup and reference functions Fonctions de recherche et de référence +## +ADDRESS = ADRESSE ## Renvoie une référence sous forme de texte à une seule cellule d’une feuille de calcul. +AREAS = ZONES ## Renvoie le nombre de zones dans une référence. +CHOOSE = CHOISIR ## Choisit une valeur dans une liste. +COLUMN = COLONNE ## Renvoie le numéro de colonne d’une référence. +COLUMNS = COLONNES ## Renvoie le nombre de colonnes dans une référence. +HLOOKUP = RECHERCHEH ## Effectue une recherche dans la première ligne d’une matrice et renvoie la valeur de la cellule indiquée. +HYPERLINK = LIEN_HYPERTEXTE ## Crée un raccourci ou un renvoi qui ouvre un document stocké sur un serveur réseau, sur un réseau Intranet ou sur Internet. +INDEX = INDEX ## Utilise un index pour choisir une valeur provenant d’une référence ou d’une matrice. +INDIRECT = INDIRECT ## Renvoie une référence indiquée par une valeur de texte. +LOOKUP = RECHERCHE ## Recherche des valeurs dans un vecteur ou une matrice. +MATCH = EQUIV ## Recherche des valeurs dans une référence ou une matrice. +OFFSET = DECALER ## Renvoie une référence décalée par rapport à une référence donnée. +ROW = LIGNE ## Renvoie le numéro de ligne d’une référence. +ROWS = LIGNES ## Renvoie le nombre de lignes dans une référence. +RTD = RTD ## Extrait les données en temps réel à partir d’un programme prenant en charge l’automation COM (Automation : utilisation des objets d'une application à partir d'une autre application ou d'un autre outil de développement. Autrefois appelée OLE Automation, Automation est une norme industrielle et une fonctionnalité du modèle d'objet COM (Component Object Model).). +TRANSPOSE = TRANSPOSE ## Renvoie la transposition d’une matrice. +VLOOKUP = RECHERCHEV ## Effectue une recherche dans la première colonne d’une matrice et se déplace sur la ligne pour renvoyer la valeur d’une cellule. + + +## +## Math and trigonometry functions Fonctions mathématiques et trigonométriques +## +ABS = ABS ## Renvoie la valeur absolue d’un nombre. +ACOS = ACOS ## Renvoie l’arccosinus d’un nombre. +ACOSH = ACOSH ## Renvoie le cosinus hyperbolique inverse d’un nombre. +ASIN = ASIN ## Renvoie l’arcsinus d’un nombre. +ASINH = ASINH ## Renvoie le sinus hyperbolique inverse d’un nombre. +ATAN = ATAN ## Renvoie l’arctangente d’un nombre. +ATAN2 = ATAN2 ## Renvoie l’arctangente des coordonnées x et y. +ATANH = ATANH ## Renvoie la tangente hyperbolique inverse d’un nombre. +CEILING = PLAFOND ## Arrondit un nombre au nombre entier le plus proche ou au multiple le plus proche de l’argument précision en s’éloignant de zéro. +COMBIN = COMBIN ## Renvoie le nombre de combinaisons que l’on peut former avec un nombre donné d’objets. +COS = COS ## Renvoie le cosinus d’un nombre. +COSH = COSH ## Renvoie le cosinus hyperbolique d’un nombre. +DEGREES = DEGRES ## Convertit des radians en degrés. +EVEN = PAIR ## Arrondit un nombre au nombre entier pair le plus proche en s’éloignant de zéro. +EXP = EXP ## Renvoie e élevé à la puissance d’un nombre donné. +FACT = FACT ## Renvoie la factorielle d’un nombre. +FACTDOUBLE = FACTDOUBLE ## Renvoie la factorielle double d’un nombre. +FLOOR = PLANCHER ## Arrondit un nombre en tendant vers 0 (zéro). +GCD = PGCD ## Renvoie le plus grand commun diviseur. +INT = ENT ## Arrondit un nombre à l’entier immédiatement inférieur. +LCM = PPCM ## Renvoie le plus petit commun multiple. +LN = LN ## Renvoie le logarithme népérien d’un nombre. +LOG = LOG ## Renvoie le logarithme d’un nombre dans la base spécifiée. +LOG10 = LOG10 ## Calcule le logarithme en base 10 d’un nombre. +MDETERM = DETERMAT ## Renvoie le déterminant d’une matrice. +MINVERSE = INVERSEMAT ## Renvoie la matrice inverse d’une matrice. +MMULT = PRODUITMAT ## Renvoie le produit de deux matrices. +MOD = MOD ## Renvoie le reste d’une division. +MROUND = ARRONDI.AU.MULTIPLE ## Donne l’arrondi d’un nombre au multiple spécifié. +MULTINOMIAL = MULTINOMIALE ## Calcule la multinomiale d’un ensemble de nombres. +ODD = IMPAIR ## Renvoie le nombre, arrondi à la valeur du nombre entier impair le plus proche en s’éloignant de zéro. +PI = PI ## Renvoie la valeur de pi. +POWER = PUISSANCE ## Renvoie la valeur du nombre élevé à une puissance. +PRODUCT = PRODUIT ## Multiplie ses arguments. +QUOTIENT = QUOTIENT ## Renvoie la partie entière du résultat d’une division. +RADIANS = RADIANS ## Convertit des degrés en radians. +RAND = ALEA ## Renvoie un nombre aléatoire compris entre 0 et 1. +RANDBETWEEN = ALEA.ENTRE.BORNES ## Renvoie un nombre aléatoire entre les nombres que vous spécifiez. +ROMAN = ROMAIN ## Convertit des chiffres arabes en chiffres romains, sous forme de texte. +ROUND = ARRONDI ## Arrondit un nombre au nombre de chiffres indiqué. +ROUNDDOWN = ARRONDI.INF ## Arrondit un nombre en tendant vers 0 (zéro). +ROUNDUP = ARRONDI.SUP ## Arrondit un nombre à l’entier supérieur, en s’éloignant de zéro. +SERIESSUM = SOMME.SERIES ## Renvoie la somme d’une série géométrique en s’appuyant sur la formule suivante : +SIGN = SIGNE ## Renvoie le signe d’un nombre. +SIN = SIN ## Renvoie le sinus d’un angle donné. +SINH = SINH ## Renvoie le sinus hyperbolique d’un nombre. +SQRT = RACINE ## Renvoie la racine carrée d’un nombre. +SQRTPI = RACINE.PI ## Renvoie la racine carrée de (nombre * pi). +SUBTOTAL = SOUS.TOTAL ## Renvoie un sous-total dans une liste ou une base de données. +SUM = SOMME ## Calcule la somme de ses arguments. +SUMIF = SOMME.SI ## Additionne les cellules spécifiées si elles répondent à un critère donné. +SUMIFS = SOMME.SI.ENS ## Ajoute les cellules d’une plage qui répondent à plusieurs critères. +SUMPRODUCT = SOMMEPROD ## Multiplie les valeurs correspondantes des matrices spécifiées et calcule la somme de ces produits. +SUMSQ = SOMME.CARRES ## Renvoie la somme des carrés des arguments. +SUMX2MY2 = SOMME.X2MY2 ## Renvoie la somme de la différence des carrés des valeurs correspondantes de deux matrices. +SUMX2PY2 = SOMME.X2PY2 ## Renvoie la somme de la somme des carrés des valeurs correspondantes de deux matrices. +SUMXMY2 = SOMME.XMY2 ## Renvoie la somme des carrés des différences entre les valeurs correspondantes de deux matrices. +TAN = TAN ## Renvoie la tangente d’un nombre. +TANH = TANH ## Renvoie la tangente hyperbolique d’un nombre. +TRUNC = TRONQUE ## Renvoie la partie entière d’un nombre. + + +## +## Statistical functions Fonctions statistiques +## +AVEDEV = ECART.MOYEN ## Renvoie la moyenne des écarts absolus observés dans la moyenne des points de données. +AVERAGE = MOYENNE ## Renvoie la moyenne de ses arguments. +AVERAGEA = AVERAGEA ## Renvoie la moyenne de ses arguments, nombres, texte et valeurs logiques inclus. +AVERAGEIF = MOYENNE.SI ## Renvoie la moyenne (arithmétique) de toutes les cellules d’une plage qui répondent à des critères donnés. +AVERAGEIFS = MOYENNE.SI.ENS ## Renvoie la moyenne (arithmétique) de toutes les cellules qui répondent à plusieurs critères. +BETADIST = LOI.BETA ## Renvoie la fonction de distribution cumulée. +BETAINV = BETA.INVERSE ## Renvoie l’inverse de la fonction de distribution cumulée pour une distribution bêta spécifiée. +BINOMDIST = LOI.BINOMIALE ## Renvoie la probabilité d’une variable aléatoire discrète suivant la loi binomiale. +CHIDIST = LOI.KHIDEUX ## Renvoie la probabilité unilatérale de la distribution khi-deux. +CHIINV = KHIDEUX.INVERSE ## Renvoie l’inverse de la probabilité unilatérale de la distribution khi-deux. +CHITEST = TEST.KHIDEUX ## Renvoie le test d’indépendance. +CONFIDENCE = INTERVALLE.CONFIANCE ## Renvoie l’intervalle de confiance pour une moyenne de population. +CORREL = COEFFICIENT.CORRELATION ## Renvoie le coefficient de corrélation entre deux séries de données. +COUNT = NB ## Détermine les nombres compris dans la liste des arguments. +COUNTA = NBVAL ## Détermine le nombre de valeurs comprises dans la liste des arguments. +COUNTBLANK = NB.VIDE ## Compte le nombre de cellules vides dans une plage. +COUNTIF = NB.SI ## Compte le nombre de cellules qui répondent à un critère donné dans une plage. +COUNTIFS = NB.SI.ENS ## Compte le nombre de cellules à l’intérieur d’une plage qui répondent à plusieurs critères. +COVAR = COVARIANCE ## Renvoie la covariance, moyenne des produits des écarts pour chaque série d’observations. +CRITBINOM = CRITERE.LOI.BINOMIALE ## Renvoie la plus petite valeur pour laquelle la distribution binomiale cumulée est inférieure ou égale à une valeur de critère. +DEVSQ = SOMME.CARRES.ECARTS ## Renvoie la somme des carrés des écarts. +EXPONDIST = LOI.EXPONENTIELLE ## Renvoie la distribution exponentielle. +FDIST = LOI.F ## Renvoie la distribution de probabilité F. +FINV = INVERSE.LOI.F ## Renvoie l’inverse de la distribution de probabilité F. +FISHER = FISHER ## Renvoie la transformation de Fisher. +FISHERINV = FISHER.INVERSE ## Renvoie l’inverse de la transformation de Fisher. +FORECAST = PREVISION ## Calcule une valeur par rapport à une tendance linéaire. +FREQUENCY = FREQUENCE ## Calcule la fréquence d’apparition des valeurs dans une plage de valeurs, puis renvoie des nombres sous forme de matrice verticale. +FTEST = TEST.F ## Renvoie le résultat d’un test F. +GAMMADIST = LOI.GAMMA ## Renvoie la probabilité d’une variable aléatoire suivant une loi Gamma. +GAMMAINV = LOI.GAMMA.INVERSE ## Renvoie, pour une probabilité donnée, la valeur d’une variable aléatoire suivant une loi Gamma. +GAMMALN = LNGAMMA ## Renvoie le logarithme népérien de la fonction Gamma, G(x) +GEOMEAN = MOYENNE.GEOMETRIQUE ## Renvoie la moyenne géométrique. +GROWTH = CROISSANCE ## Calcule des valeurs par rapport à une tendance exponentielle. +HARMEAN = MOYENNE.HARMONIQUE ## Renvoie la moyenne harmonique. +HYPGEOMDIST = LOI.HYPERGEOMETRIQUE ## Renvoie la probabilité d’une variable aléatoire discrète suivant une loi hypergéométrique. +INTERCEPT = ORDONNEE.ORIGINE ## Renvoie l’ordonnée à l’origine d’une droite de régression linéaire. +KURT = KURTOSIS ## Renvoie le kurtosis d’une série de données. +LARGE = GRANDE.VALEUR ## Renvoie la k-ième plus grande valeur d’une série de données. +LINEST = DROITEREG ## Renvoie les paramètres d’une tendance linéaire. +LOGEST = LOGREG ## Renvoie les paramètres d’une tendance exponentielle. +LOGINV = LOI.LOGNORMALE.INVERSE ## Renvoie l’inverse de la probabilité pour une variable aléatoire suivant la loi lognormale. +LOGNORMDIST = LOI.LOGNORMALE ## Renvoie la probabilité d’une variable aléatoire continue suivant une loi lognormale. +MAX = MAX ## Renvoie la valeur maximale contenue dans une liste d’arguments. +MAXA = MAXA ## Renvoie la valeur maximale d’une liste d’arguments, nombres, texte et valeurs logiques inclus. +MEDIAN = MEDIANE ## Renvoie la valeur médiane des nombres donnés. +MIN = MIN ## Renvoie la valeur minimale contenue dans une liste d’arguments. +MINA = MINA ## Renvoie la plus petite valeur d’une liste d’arguments, nombres, texte et valeurs logiques inclus. +MODE = MODE ## Renvoie la valeur la plus courante d’une série de données. +NEGBINOMDIST = LOI.BINOMIALE.NEG ## Renvoie la probabilité d’une variable aléatoire discrète suivant une loi binomiale négative. +NORMDIST = LOI.NORMALE ## Renvoie la probabilité d’une variable aléatoire continue suivant une loi normale. +NORMINV = LOI.NORMALE.INVERSE ## Renvoie, pour une probabilité donnée, la valeur d’une variable aléatoire suivant une loi normale standard. +NORMSDIST = LOI.NORMALE.STANDARD ## Renvoie la probabilité d’une variable aléatoire continue suivant une loi normale standard. +NORMSINV = LOI.NORMALE.STANDARD.INVERSE ## Renvoie l’inverse de la distribution cumulée normale standard. +PEARSON = PEARSON ## Renvoie le coefficient de corrélation d’échantillonnage de Pearson. +PERCENTILE = CENTILE ## Renvoie le k-ième centile des valeurs d’une plage. +PERCENTRANK = RANG.POURCENTAGE ## Renvoie le rang en pourcentage d’une valeur d’une série de données. +PERMUT = PERMUTATION ## Renvoie le nombre de permutations pour un nombre donné d’objets. +POISSON = LOI.POISSON ## Renvoie la probabilité d’une variable aléatoire suivant une loi de Poisson. +PROB = PROBABILITE ## Renvoie la probabilité que des valeurs d’une plage soient comprises entre deux limites. +QUARTILE = QUARTILE ## Renvoie le quartile d’une série de données. +RANK = RANG ## Renvoie le rang d’un nombre contenu dans une liste. +RSQ = COEFFICIENT.DETERMINATION ## Renvoie la valeur du coefficient de détermination R^2 d’une régression linéaire. +SKEW = COEFFICIENT.ASYMETRIE ## Renvoie l’asymétrie d’une distribution. +SLOPE = PENTE ## Renvoie la pente d’une droite de régression linéaire. +SMALL = PETITE.VALEUR ## Renvoie la k-ième plus petite valeur d’une série de données. +STANDARDIZE = CENTREE.REDUITE ## Renvoie une valeur centrée réduite. +STDEV = ECARTYPE ## Évalue l’écart type d’une population en se basant sur un échantillon de cette population. +STDEVA = STDEVA ## Évalue l’écart type d’une population en se basant sur un échantillon de cette population, nombres, texte et valeurs logiques inclus. +STDEVP = ECARTYPEP ## Calcule l’écart type d’une population à partir de la population entière. +STDEVPA = STDEVPA ## Calcule l’écart type d’une population à partir de l’ensemble de la population, nombres, texte et valeurs logiques inclus. +STEYX = ERREUR.TYPE.XY ## Renvoie l’erreur type de la valeur y prévue pour chaque x de la régression. +TDIST = LOI.STUDENT ## Renvoie la probabilité d’une variable aléatoire suivant une loi T de Student. +TINV = LOI.STUDENT.INVERSE ## Renvoie, pour une probabilité donnée, la valeur d’une variable aléatoire suivant une loi T de Student. +TREND = TENDANCE ## Renvoie des valeurs par rapport à une tendance linéaire. +TRIMMEAN = MOYENNE.REDUITE ## Renvoie la moyenne de l’intérieur d’une série de données. +TTEST = TEST.STUDENT ## Renvoie la probabilité associée à un test T de Student. +VAR = VAR ## Calcule la variance sur la base d’un échantillon. +VARA = VARA ## Estime la variance d’une population en se basant sur un échantillon de cette population, nombres, texte et valeurs logiques incluses. +VARP = VAR.P ## Calcule la variance sur la base de l’ensemble de la population. +VARPA = VARPA ## Calcule la variance d’une population en se basant sur la population entière, nombres, texte et valeurs logiques inclus. +WEIBULL = LOI.WEIBULL ## Renvoie la probabilité d’une variable aléatoire suivant une loi de Weibull. +ZTEST = TEST.Z ## Renvoie la valeur de probabilité unilatérale d’un test z. + + +## +## Text functions Fonctions de texte +## +ASC = ASC ## Change les caractères anglais ou katakana à pleine chasse (codés sur deux octets) à l’intérieur d’une chaîne de caractères en caractères à demi-chasse (codés sur un octet). +BAHTTEXT = BAHTTEXT ## Convertit un nombre en texte en utilisant le format monétaire ß (baht). +CHAR = CAR ## Renvoie le caractère spécifié par le code numérique. +CLEAN = EPURAGE ## Supprime tous les caractères de contrôle du texte. +CODE = CODE ## Renvoie le numéro de code du premier caractère du texte. +CONCATENATE = CONCATENER ## Assemble plusieurs éléments textuels de façon à n’en former qu’un seul. +DOLLAR = EURO ## Convertit un nombre en texte en utilisant le format monétaire € (euro). +EXACT = EXACT ## Vérifie si deux valeurs de texte sont identiques. +FIND = TROUVE ## Trouve un valeur textuelle dans une autre, en respectant la casse. +FINDB = TROUVERB ## Trouve un valeur textuelle dans une autre, en respectant la casse. +FIXED = CTXT ## Convertit un nombre au format texte avec un nombre de décimales spécifié. +JIS = JIS ## Change les caractères anglais ou katakana à demi-chasse (codés sur un octet) à l’intérieur d’une chaîne de caractères en caractères à à pleine chasse (codés sur deux octets). +LEFT = GAUCHE ## Renvoie des caractères situés à l’extrême gauche d’une chaîne de caractères. +LEFTB = GAUCHEB ## Renvoie des caractères situés à l’extrême gauche d’une chaîne de caractères. +LEN = NBCAR ## Renvoie le nombre de caractères contenus dans une chaîne de texte. +LENB = LENB ## Renvoie le nombre de caractères contenus dans une chaîne de texte. +LOWER = MINUSCULE ## Convertit le texte en minuscules. +MID = STXT ## Renvoie un nombre déterminé de caractères d’une chaîne de texte à partir de la position que vous indiquez. +MIDB = STXTB ## Renvoie un nombre déterminé de caractères d’une chaîne de texte à partir de la position que vous indiquez. +PHONETIC = PHONETIQUE ## Extrait les caractères phonétiques (furigana) d’une chaîne de texte. +PROPER = NOMPROPRE ## Met en majuscules la première lettre de chaque mot dans une chaîne textuelle. +REPLACE = REMPLACER ## Remplace des caractères dans un texte. +REPLACEB = REMPLACERB ## Remplace des caractères dans un texte. +REPT = REPT ## Répète un texte un certain nombre de fois. +RIGHT = DROITE ## Renvoie des caractères situés à l’extrême droite d’une chaîne de caractères. +RIGHTB = DROITEB ## Renvoie des caractères situés à l’extrême droite d’une chaîne de caractères. +SEARCH = CHERCHE ## Trouve un texte dans un autre texte (sans respecter la casse). +SEARCHB = CHERCHERB ## Trouve un texte dans un autre texte (sans respecter la casse). +SUBSTITUTE = SUBSTITUE ## Remplace l’ancien texte d’une chaîne de caractères par un nouveau. +T = T ## Convertit ses arguments en texte. +TEXT = TEXTE ## Convertit un nombre au format texte. +TRIM = SUPPRESPACE ## Supprime les espaces du texte. +UPPER = MAJUSCULE ## Convertit le texte en majuscules. +VALUE = CNUM ## Convertit un argument textuel en nombre diff --git a/lib/phpexcel/PHPExcel/locale/hu/config b/lib/phpexcel/PHPExcel/locale/hu/config new file mode 100644 index 0000000..e04151c --- /dev/null +++ b/lib/phpexcel/PHPExcel/locale/hu/config @@ -0,0 +1,47 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Settings +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## + + +ArgumentSeparator = ; + + +## +## (For future use) +## +currencySymbol = Ft + + +## +## Excel Error Codes (For future use) +## +NULL = #NULLA! +DIV0 = #ZÉRÓOSZTÓ! +VALUE = #ÉRTÉK! +REF = #HIV! +NAME = #NÉV? +NUM = #SZÁM! +NA = #HIÁNYZIK diff --git a/lib/phpexcel/PHPExcel/locale/hu/functions b/lib/phpexcel/PHPExcel/locale/hu/functions new file mode 100644 index 0000000..77cae92 --- /dev/null +++ b/lib/phpexcel/PHPExcel/locale/hu/functions @@ -0,0 +1,438 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Calculation +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## Data in this file derived from http://www.piuha.fi/excel-function-name-translation/ +## +## + + +## +## Add-in and Automation functions Bővítmények és automatizálási függvények +## +GETPIVOTDATA = KIMUTATÁSADATOT.VESZ ## A kimutatásokban tárolt adatok visszaadására használható. + + +## +## Cube functions Kockafüggvények +## +CUBEKPIMEMBER = KOCKA.FŐTELJMUT ## Egy fő teljesítménymutató (KPI) nevét, tulajdonságát és mértékegységét adja eredményül, a nevet és a tulajdonságot megjeleníti a cellában. A KPI-k számszerűsíthető mérési lehetőséget jelentenek – ilyen mutató például a havi bruttó nyereség vagy az egy alkalmazottra jutó negyedéves forgalom –, egy szervezet teljesítményének nyomonkövetésére használhatók. +CUBEMEMBER = KOCKA.TAG ## Kockahierachia tagját vagy rekordját adja eredményül. Ellenőrizhető vele, hogy szerepel-e a kockában az adott tag vagy rekord. +CUBEMEMBERPROPERTY = KOCKA.TAG.TUL ## A kocka egyik tagtulajdonságának értékét adja eredményül. Használatával ellenőrizhető, hogy szerepel-e egy tagnév a kockában, eredménye pedig az erre a tagra vonatkozó, megadott tulajdonság. +CUBERANKEDMEMBER = KOCKA.HALM.ELEM ## Egy halmaz rangsor szerinti n-edik tagját adja eredményül. Használatával egy halmaz egy vagy több elemét kaphatja meg, például a legnagyobb teljesítményű üzletkötőt vagy a 10 legjobb tanulót. +CUBESET = KOCKA.HALM ## Számított tagok vagy rekordok halmazát adja eredményül, ehhez egy beállított kifejezést elküld a kiszolgálón található kockának, majd ezt a halmazt adja vissza a Microsoft Office Excel alkalmazásnak. +CUBESETCOUNT = KOCKA.HALM.DB ## Egy halmaz elemszámát adja eredményül. +CUBEVALUE = KOCKA.ÉRTÉK ## Kockából összesített értéket ad eredményül. + + +## +## Database functions Adatbázis-kezelő függvények +## +DAVERAGE = AB.ÁTLAG ## A kijelölt adatbáziselemek átlagát számítja ki. +DCOUNT = AB.DARAB ## Megszámolja, hogy az adatbázisban hány cella tartalmaz számokat. +DCOUNTA = AB.DARAB2 ## Megszámolja az adatbázisban lévő nem üres cellákat. +DGET = AB.MEZŐ ## Egy adatbázisból egyetlen olyan rekordot ad vissza, amely megfelel a megadott feltételeknek. +DMAX = AB.MAX ## A kiválasztott adatbáziselemek közül a legnagyobb értéket adja eredményül. +DMIN = AB.MIN ## A kijelölt adatbáziselemek közül a legkisebb értéket adja eredményül. +DPRODUCT = AB.SZORZAT ## Az adatbázis megadott feltételeknek eleget tevő rekordjaira összeszorozza a megadott mezőben található számértékeket, és eredményül ezt a szorzatot adja. +DSTDEV = AB.SZÓRÁS ## A kijelölt adatbáziselemek egy mintája alapján megbecsüli a szórást. +DSTDEVP = AB.SZÓRÁS2 ## A kijelölt adatbáziselemek teljes sokasága alapján kiszámítja a szórást. +DSUM = AB.SZUM ## Összeadja a feltételnek megfelelő adatbázisrekordok mezőoszlopában a számokat. +DVAR = AB.VAR ## A kijelölt adatbáziselemek mintája alapján becslést ad a szórásnégyzetre. +DVARP = AB.VAR2 ## A kijelölt adatbáziselemek teljes sokasága alapján kiszámítja a szórásnégyzetet. + + +## +## Date and time functions Dátumfüggvények +## +DATE = DÁTUM ## Adott dátum dátumértékét adja eredményül. +DATEVALUE = DÁTUMÉRTÉK ## Szövegként megadott dátumot dátumértékké alakít át. +DAY = NAP ## Dátumértéket a hónap egy napjává (0-31) alakít. +DAYS360 = NAP360 ## Két dátum közé eső napok számát számítja ki a 360 napos év alapján. +EDATE = EDATE ## Adott dátumnál adott számú hónappal korábbi vagy későbbi dátum dátumértékét adja eredményül. +EOMONTH = EOMONTH ## Adott dátumnál adott számú hónappal korábbi vagy későbbi hónap utolsó napjának dátumértékét adja eredményül. +HOUR = ÓRA ## Időértéket órákká alakít. +MINUTE = PERC ## Időértéket percekké alakít. +MONTH = HÓNAP ## Időértéket hónapokká alakít. +NETWORKDAYS = NETWORKDAYS ## Két dátum között a teljes munkanapok számát adja meg. +NOW = MOST ## A napi dátum dátumértékét és a pontos idő időértékét adja eredményül. +SECOND = MPERC ## Időértéket másodpercekké alakít át. +TIME = IDŐ ## Adott időpont időértékét adja meg. +TIMEVALUE = IDŐÉRTÉK ## Szövegként megadott időpontot időértékké alakít át. +TODAY = MA ## A napi dátum dátumértékét adja eredményül. +WEEKDAY = HÉT.NAPJA ## Dátumértéket a hét napjává alakítja át. +WEEKNUM = WEEKNUM ## Visszatérési értéke egy szám, amely azt mutatja meg, hogy a megadott dátum az év hányadik hetére esik. +WORKDAY = WORKDAY ## Adott dátumnál adott munkanappal korábbi vagy későbbi dátum dátumértékét adja eredményül. +YEAR = ÉV ## Sorszámot évvé alakít át. +YEARFRAC = YEARFRAC ## Az adott dátumok közötti teljes napok számát törtévként adja meg. + + +## +## Engineering functions Mérnöki függvények +## +BESSELI = BESSELI ## Az In(x) módosított Bessel-függvény értékét adja eredményül. +BESSELJ = BESSELJ ## A Jn(x) Bessel-függvény értékét adja eredményül. +BESSELK = BESSELK ## A Kn(x) módosított Bessel-függvény értékét adja eredményül. +BESSELY = BESSELY ## Az Yn(x) módosított Bessel-függvény értékét adja eredményül. +BIN2DEC = BIN2DEC ## Bináris számot decimálissá alakít át. +BIN2HEX = BIN2HEX ## Bináris számot hexadecimálissá alakít át. +BIN2OCT = BIN2OCT ## Bináris számot oktálissá alakít át. +COMPLEX = COMPLEX ## Valós és képzetes részből komplex számot képez. +CONVERT = CONVERT ## Mértékegységeket vált át. +DEC2BIN = DEC2BIN ## Decimális számot binárissá alakít át. +DEC2HEX = DEC2HEX ## Decimális számot hexadecimálissá alakít át. +DEC2OCT = DEC2OCT ## Decimális számot oktálissá alakít át. +DELTA = DELTA ## Azt vizsgálja, hogy két érték egyenlő-e. +ERF = ERF ## A hibafüggvény értékét adja eredményül. +ERFC = ERFC ## A kiegészített hibafüggvény értékét adja eredményül. +GESTEP = GESTEP ## Azt vizsgálja, hogy egy szám nagyobb-e adott küszöbértéknél. +HEX2BIN = HEX2BIN ## Hexadecimális számot binárissá alakít át. +HEX2DEC = HEX2DEC ## Hexadecimális számot decimálissá alakít át. +HEX2OCT = HEX2OCT ## Hexadecimális számot oktálissá alakít át. +IMABS = IMABS ## Komplex szám abszolút értékét (modulusát) adja eredményül. +IMAGINARY = IMAGINARY ## Komplex szám képzetes részét adja eredményül. +IMARGUMENT = IMARGUMENT ## A komplex szám radiánban kifejezett théta argumentumát adja eredményül. +IMCONJUGATE = IMCONJUGATE ## Komplex szám komplex konjugáltját adja eredményül. +IMCOS = IMCOS ## Komplex szám koszinuszát adja eredményül. +IMDIV = IMDIV ## Két komplex szám hányadosát adja eredményül. +IMEXP = IMEXP ## Az e szám komplex kitevőjű hatványát adja eredményül. +IMLN = IMLN ## Komplex szám természetes logaritmusát adja eredményül. +IMLOG10 = IMLOG10 ## Komplex szám tízes alapú logaritmusát adja eredményül. +IMLOG2 = IMLOG2 ## Komplex szám kettes alapú logaritmusát adja eredményül. +IMPOWER = IMPOWER ## Komplex szám hatványát adja eredményül. +IMPRODUCT = IMPRODUCT ## Komplex számok szorzatát adja eredményül. +IMREAL = IMREAL ## Komplex szám valós részét adja eredményül. +IMSIN = IMSIN ## Komplex szám szinuszát adja eredményül. +IMSQRT = IMSQRT ## Komplex szám négyzetgyökét adja eredményül. +IMSUB = IMSUB ## Két komplex szám különbségét adja eredményül. +IMSUM = IMSUM ## Komplex számok összegét adja eredményül. +OCT2BIN = OCT2BIN ## Oktális számot binárissá alakít át. +OCT2DEC = OCT2DEC ## Oktális számot decimálissá alakít át. +OCT2HEX = OCT2HEX ## Oktális számot hexadecimálissá alakít át. + + +## +## Financial functions Pénzügyi függvények +## +ACCRINT = ACCRINT ## Periodikusan kamatozó értékpapír felszaporodott kamatát adja eredményül. +ACCRINTM = ACCRINTM ## Lejáratkor kamatozó értékpapír felszaporodott kamatát adja eredményül. +AMORDEGRC = AMORDEGRC ## Állóeszköz lineáris értékcsökkenését adja meg az egyes könyvelési időszakokra vonatkozóan. +AMORLINC = AMORLINC ## Az egyes könyvelési időszakokban az értékcsökkenést adja meg. +COUPDAYBS = COUPDAYBS ## A szelvényidőszak kezdetétől a kifizetés időpontjáig eltelt napokat adja vissza. +COUPDAYS = COUPDAYS ## A kifizetés időpontját magában foglaló szelvényperiódus hosszát adja meg napokban. +COUPDAYSNC = COUPDAYSNC ## A kifizetés időpontja és a legközelebbi szelvénydátum közötti napok számát adja meg. +COUPNCD = COUPNCD ## A kifizetést követő legelső szelvénydátumot adja eredményül. +COUPNUM = COUPNUM ## A kifizetés és a lejárat időpontja között kifizetendő szelvények számát adja eredményül. +COUPPCD = COUPPCD ## A kifizetés előtti utolsó szelvénydátumot adja eredményül. +CUMIPMT = CUMIPMT ## Két fizetési időszak között kifizetett kamat halmozott értékét adja eredményül. +CUMPRINC = CUMPRINC ## Két fizetési időszak között kifizetett részletek halmozott (kamatot nem tartalmazó) értékét adja eredményül. +DB = KCS2 ## Eszköz adott időszak alatti értékcsökkenését számítja ki a lineáris leírási modell alkalmazásával. +DDB = KCSA ## Eszköz értékcsökkenését számítja ki adott időszakra vonatkozóan a progresszív vagy egyéb megadott leírási modell alkalmazásával. +DISC = DISC ## Értékpapír leszámítolási kamatlábát adja eredményül. +DOLLARDE = DOLLARDE ## Egy közönséges törtként megadott számot tizedes törtté alakít át. +DOLLARFR = DOLLARFR ## Tizedes törtként megadott számot közönséges törtté alakít át. +DURATION = DURATION ## Periodikus kamatfizetésű értékpapír éves kamatérzékenységét adja eredményül. +EFFECT = EFFECT ## Az éves tényleges kamatláb értékét adja eredményül. +FV = JBÉ ## Befektetés jövőbeli értékét számítja ki. +FVSCHEDULE = FVSCHEDULE ## A kezdőtőke adott kamatlábak szerint megnövelt jövőbeli értékét adja eredményül. +INTRATE = INTRATE ## A lejáratig teljesen lekötött értékpapír kamatrátáját adja eredményül. +IPMT = RRÉSZLET ## Hiteltörlesztésen belül a tőketörlesztés nagyságát számítja ki adott időszakra. +IRR = BMR ## A befektetés belső megtérülési rátáját számítja ki pénzáramláshoz. +ISPMT = LRÉSZLETKAMAT ## A befektetés adott időszakára fizetett kamatot számítja ki. +MDURATION = MDURATION ## Egy 100 Ft névértékű értékpapír Macauley-féle módosított kamatérzékenységét adja eredményül. +MIRR = MEGTÉRÜLÉS ## A befektetés belső megtérülési rátáját számítja ki a költségek és a bevételek különböző kamatlába mellett. +NOMINAL = NOMINAL ## Az éves névleges kamatláb értékét adja eredményül. +NPER = PER.SZÁM ## A törlesztési időszakok számát adja meg. +NPV = NMÉ ## Befektetéshez kapcsolódó pénzáramlás nettó jelenértékét számítja ki ismert pénzáramlás és kamatláb mellett. +ODDFPRICE = ODDFPRICE ## Egy 100 Ft névértékű, a futamidő elején töredék-időszakos értékpapír árát adja eredményül. +ODDFYIELD = ODDFYIELD ## A futamidő elején töredék-időszakos értékpapír hozamát adja eredményül. +ODDLPRICE = ODDLPRICE ## Egy 100 Ft névértékű, a futamidő végén töredék-időszakos értékpapír árát adja eredményül. +ODDLYIELD = ODDLYIELD ## A futamidő végén töredék-időszakos értékpapír hozamát adja eredményül. +PMT = RÉSZLET ## A törlesztési időszakra vonatkozó törlesztési összeget számítja ki. +PPMT = PRÉSZLET ## Hiteltörlesztésen belül a tőketörlesztés nagyságát számítja ki adott időszakra. +PRICE = PRICE ## Egy 100 Ft névértékű, periodikusan kamatozó értékpapír árát adja eredményül. +PRICEDISC = PRICEDISC ## Egy 100 Ft névértékű leszámítolt értékpapír árát adja eredményül. +PRICEMAT = PRICEMAT ## Egy 100 Ft névértékű, a lejáratkor kamatozó értékpapír árát adja eredményül. +PV = MÉ ## Befektetés jelenlegi értékét számítja ki. +RATE = RÁTA ## Egy törlesztési időszakban az egy időszakra eső kamatláb nagyságát számítja ki. +RECEIVED = RECEIVED ## A lejáratig teljesen lekötött értékpapír lejáratakor kapott összegét adja eredményül. +SLN = LCSA ## Tárgyi eszköz egy időszakra eső amortizációját adja meg bruttó érték szerinti lineáris leírási kulcsot alkalmazva. +SYD = SYD ## Tárgyi eszköz értékcsökkenését számítja ki adott időszakra az évek számjegyösszegével dolgozó módszer alapján. +TBILLEQ = TBILLEQ ## Kincstárjegy kötvény-egyenértékű hozamát adja eredményül. +TBILLPRICE = TBILLPRICE ## Egy 100 Ft névértékű kincstárjegy árát adja eredményül. +TBILLYIELD = TBILLYIELD ## Kincstárjegy hozamát adja eredményül. +VDB = ÉCSRI ## Tárgyi eszköz amortizációját számítja ki megadott vagy részidőszakra a csökkenő egyenleg módszerének alkalmazásával. +XIRR = XIRR ## Ütemezett készpénzforgalom (cash flow) belső megtérülési kamatrátáját adja eredményül. +XNPV = XNPV ## Ütemezett készpénzforgalom (cash flow) nettó jelenlegi értékét adja eredményül. +YIELD = YIELD ## Periodikusan kamatozó értékpapír hozamát adja eredményül. +YIELDDISC = YIELDDISC ## Leszámítolt értékpapír (például kincstárjegy) éves hozamát adja eredményül. +YIELDMAT = YIELDMAT ## Lejáratkor kamatozó értékpapír éves hozamát adja eredményül. + + +## +## Information functions Információs függvények +## +CELL = CELLA ## Egy cella formátumára, elhelyezkedésére vagy tartalmára vonatkozó adatokat ad eredményül. +ERROR.TYPE = HIBA.TÍPUS ## Egy hibatípushoz tartozó számot ad eredményül. +INFO = INFÓ ## A rendszer- és munkakörnyezet pillanatnyi állapotáról ad felvilágosítást. +ISBLANK = ÜRES ## Eredménye IGAZ, ha az érték üres. +ISERR = HIBA ## Eredménye IGAZ, ha az érték valamelyik hibaérték a #HIÁNYZIK kivételével. +ISERROR = HIBÁS ## Eredménye IGAZ, ha az érték valamelyik hibaérték. +ISEVEN = ISEVEN ## Eredménye IGAZ, ha argumentuma páros szám. +ISLOGICAL = LOGIKAI ## Eredménye IGAZ, ha az érték logikai érték. +ISNA = NINCS ## Eredménye IGAZ, ha az érték a #HIÁNYZIK hibaérték. +ISNONTEXT = NEM.SZÖVEG ## Eredménye IGAZ, ha az érték nem szöveg. +ISNUMBER = SZÁM ## Eredménye IGAZ, ha az érték szám. +ISODD = ISODD ## Eredménye IGAZ, ha argumentuma páratlan szám. +ISREF = HIVATKOZÁS ## Eredménye IGAZ, ha az érték hivatkozás. +ISTEXT = SZÖVEG.E ## Eredménye IGAZ, ha az érték szöveg. +N = N ## Argumentumának értékét számmá alakítja. +NA = HIÁNYZIK ## Eredménye a #HIÁNYZIK hibaérték. +TYPE = TÍPUS ## Érték adattípusának azonosítószámát adja eredményül. + + +## +## Logical functions Logikai függvények +## +AND = ÉS ## Eredménye IGAZ, ha minden argumentuma IGAZ. +FALSE = HAMIS ## A HAMIS logikai értéket adja eredményül. +IF = HA ## Logikai vizsgálatot hajt végre. +IFERROR = HAHIBA ## A megadott értéket adja vissza, ha egy képlet hibához vezet; más esetben a képlet értékét adja eredményül. +NOT = NEM ## Argumentuma értékének ellentettjét adja eredményül. +OR = VAGY ## Eredménye IGAZ, ha bármely argumentuma IGAZ. +TRUE = IGAZ ## Az IGAZ logikai értéket adja eredményül. + + +## +## Lookup and reference functions Keresési és hivatkozási függvények +## +ADDRESS = CÍM ## A munkalap egy cellájára való hivatkozást adja szövegként eredményül. +AREAS = TERÜLET ## Hivatkozásban a területek számát adja eredményül. +CHOOSE = VÁLASZT ## Értékek listájából választ ki egy elemet. +COLUMN = OSZLOP ## Egy hivatkozás oszlopszámát adja eredményül. +COLUMNS = OSZLOPOK ## A hivatkozásban található oszlopok számát adja eredményül. +HLOOKUP = VKERES ## A megadott tömb felső sorában adott értékű elemet keres, és a megtalált elem oszlopából adott sorban elhelyezkedő értékkel tér vissza. +HYPERLINK = HIPERHIVATKOZÁS ## Hálózati kiszolgálón, intraneten vagy az interneten tárolt dokumentumot megnyitó parancsikont vagy hivatkozást hoz létre. +INDEX = INDEX ## Tömb- vagy hivatkozás indexszel megadott értékét adja vissza. +INDIRECT = INDIREKT ## Szöveg megadott hivatkozást ad eredményül. +LOOKUP = KERES ## Vektorban vagy tömbben keres meg értékeket. +MATCH = HOL.VAN ## Hivatkozásban vagy tömbben értékeket keres. +OFFSET = OFSZET ## Hivatkozás egy másik hivatkozástól számított távolságát adja meg. +ROW = SOR ## Egy hivatkozás sorának számát adja meg. +ROWS = SOROK ## Egy hivatkozás sorainak számát adja meg. +RTD = RTD ## Valós idejű adatokat keres vissza a COM automatizmust (automatizálás: Egy alkalmazás objektumaival való munka másik alkalmazásból vagy fejlesztőeszközből. A korábban OLE automatizmusnak nevezett automatizálás iparági szabvány, a Component Object Model (COM) szolgáltatása.) támogató programból. +TRANSPOSE = TRANSZPONÁLÁS ## Egy tömb transzponáltját adja eredményül. +VLOOKUP = FKERES ## A megadott tömb bal szélső oszlopában megkeres egy értéket, majd annak sora és a megadott oszlop metszéspontjában levő értéked adja eredményül. + + +## +## Math and trigonometry functions Matematikai és trigonometrikus függvények +## +ABS = ABS ## Egy szám abszolút értékét adja eredményül. +ACOS = ARCCOS ## Egy szám arkusz koszinuszát számítja ki. +ACOSH = ACOSH ## Egy szám inverz koszinusz hiperbolikuszát számítja ki. +ASIN = ARCSIN ## Egy szám arkusz szinuszát számítja ki. +ASINH = ASINH ## Egy szám inverz szinusz hiperbolikuszát számítja ki. +ATAN = ARCTAN ## Egy szám arkusz tangensét számítja ki. +ATAN2 = ARCTAN2 ## X és y koordináták alapján számítja ki az arkusz tangens értéket. +ATANH = ATANH ## A szám inverz tangens hiperbolikuszát számítja ki. +CEILING = PLAFON ## Egy számot a legközelebbi egészre vagy a pontosságként megadott érték legközelebb eső többszörösére kerekít. +COMBIN = KOMBINÁCIÓK ## Adott számú objektum összes lehetséges kombinációinak számát számítja ki. +COS = COS ## Egy szám koszinuszát számítja ki. +COSH = COSH ## Egy szám koszinusz hiperbolikuszát számítja ki. +DEGREES = FOK ## Radiánt fokká alakít át. +EVEN = PÁROS ## Egy számot a legközelebbi páros egész számra kerekít. +EXP = KITEVŐ ## Az e adott kitevőjű hatványát adja eredményül. +FACT = FAKT ## Egy szám faktoriálisát számítja ki. +FACTDOUBLE = FACTDOUBLE ## Egy szám dupla faktoriálisát adja eredményül. +FLOOR = PADLÓ ## Egy számot lefelé, a nulla felé kerekít. +GCD = GCD ## A legnagyobb közös osztót adja eredményül. +INT = INT ## Egy számot lefelé kerekít a legközelebbi egészre. +LCM = LCM ## A legkisebb közös többszöröst adja eredményül. +LN = LN ## Egy szám természetes logaritmusát számítja ki. +LOG = LOG ## Egy szám adott alapú logaritmusát számítja ki. +LOG10 = LOG10 ## Egy szám 10-es alapú logaritmusát számítja ki. +MDETERM = MDETERM ## Egy tömb mátrix-determinánsát számítja ki. +MINVERSE = INVERZ.MÁTRIX ## Egy tömb mátrix inverzét adja eredményül. +MMULT = MSZORZAT ## Két tömb mátrix-szorzatát adja meg. +MOD = MARADÉK ## Egy szám osztási maradékát adja eredményül. +MROUND = MROUND ## A kívánt többszörösére kerekített értéket ad eredményül. +MULTINOMIAL = MULTINOMIAL ## Számhalmaz multinomiálisát adja eredményül. +ODD = PÁRATLAN ## Egy számot a legközelebbi páratlan számra kerekít. +PI = PI ## A pi matematikai állandót adja vissza. +POWER = HATVÁNY ## Egy szám adott kitevőjű hatványát számítja ki. +PRODUCT = SZORZAT ## Argumentumai szorzatát számítja ki. +QUOTIENT = QUOTIENT ## Egy hányados egész részét adja eredményül. +RADIANS = RADIÁN ## Fokot radiánná alakít át. +RAND = VÉL ## Egy 0 és 1 közötti véletlen számot ad eredményül. +RANDBETWEEN = RANDBETWEEN ## Megadott számok közé eső véletlen számot állít elő. +ROMAN = RÓMAI ## Egy számot római számokkal kifejezve szövegként ad eredményül. +ROUND = KEREKÍTÉS ## Egy számot adott számú számjegyre kerekít. +ROUNDDOWN = KEREKÍTÉS.LE ## Egy számot lefelé, a nulla felé kerekít. +ROUNDUP = KEREKÍTÉS.FEL ## Egy számot felfelé, a nullától távolabbra kerekít. +SERIESSUM = SERIESSUM ## Hatványsor összegét adja eredményül. +SIGN = ELŐJEL ## Egy szám előjelét adja meg. +SIN = SIN ## Egy szög szinuszát számítja ki. +SINH = SINH ## Egy szám szinusz hiperbolikuszát számítja ki. +SQRT = GYÖK ## Egy szám pozitív négyzetgyökét számítja ki. +SQRTPI = SQRTPI ## A (szám*pi) négyzetgyökét adja eredményül. +SUBTOTAL = RÉSZÖSSZEG ## Lista vagy adatbázis részösszegét adja eredményül. +SUM = SZUM ## Összeadja az argumentumlistájában lévő számokat. +SUMIF = SZUMHA ## A megadott feltételeknek eleget tevő cellákban található értékeket adja össze. +SUMIFS = SZUMHATÖBB ## Több megadott feltételnek eleget tévő tartománycellák összegét adja eredményül. +SUMPRODUCT = SZORZATÖSSZEG ## A megfelelő tömbelemek szorzatának összegét számítja ki. +SUMSQ = NÉGYZETÖSSZEG ## Argumentumai négyzetének összegét számítja ki. +SUMX2MY2 = SZUMX2BŐLY2 ## Két tömb megfelelő elemei négyzetének különbségét összegzi. +SUMX2PY2 = SZUMX2MEGY2 ## Két tömb megfelelő elemei négyzetének összegét összegzi. +SUMXMY2 = SZUMXBŐLY2 ## Két tömb megfelelő elemei különbségének négyzetösszegét számítja ki. +TAN = TAN ## Egy szám tangensét számítja ki. +TANH = TANH ## Egy szám tangens hiperbolikuszát számítja ki. +TRUNC = CSONK ## Egy számot egésszé csonkít. + + +## +## Statistical functions Statisztikai függvények +## +AVEDEV = ÁTL.ELTÉRÉS ## Az adatpontoknak átlaguktól való átlagos abszolút eltérését számítja ki. +AVERAGE = ÁTLAG ## Argumentumai átlagát számítja ki. +AVERAGEA = ÁTLAGA ## Argumentumai átlagát számítja ki (beleértve a számokat, szöveget és logikai értékeket). +AVERAGEIF = ÁTLAGHA ## A megadott feltételnek eleget tévő tartomány celláinak átlagát (számtani közepét) adja eredményül. +AVERAGEIFS = ÁTLAGHATÖBB ## A megadott feltételeknek eleget tévő cellák átlagát (számtani közepét) adja eredményül. +BETADIST = BÉTA.ELOSZLÁS ## A béta-eloszlás függvényt számítja ki. +BETAINV = INVERZ.BÉTA ## Adott béta-eloszláshoz kiszámítja a béta eloszlásfüggvény inverzét. +BINOMDIST = BINOM.ELOSZLÁS ## A diszkrét binomiális eloszlás valószínűségértékét számítja ki. +CHIDIST = KHI.ELOSZLÁS ## A khi-négyzet-eloszlás egyszélű valószínűségértékét számítja ki. +CHIINV = INVERZ.KHI ## A khi-négyzet-eloszlás egyszélű valószínűségértékének inverzét számítja ki. +CHITEST = KHI.PRÓBA ## Függetlenségvizsgálatot hajt végre. +CONFIDENCE = MEGBÍZHATÓSÁG ## Egy statisztikai sokaság várható értékének megbízhatósági intervallumát adja eredményül. +CORREL = KORREL ## Két adathalmaz korrelációs együtthatóját számítja ki. +COUNT = DARAB ## Megszámolja, hogy argumentumlistájában hány szám található. +COUNTA = DARAB2 ## Megszámolja, hogy argumentumlistájában hány érték található. +COUNTBLANK = DARABÜRES ## Egy tartományban összeszámolja az üres cellákat. +COUNTIF = DARABTELI ## Egy tartományban összeszámolja azokat a cellákat, amelyek eleget tesznek a megadott feltételnek. +COUNTIFS = DARABHATÖBB ## Egy tartományban összeszámolja azokat a cellákat, amelyek eleget tesznek több feltételnek. +COVAR = KOVAR ## A kovarianciát, azaz a páronkénti eltérések szorzatának átlagát számítja ki. +CRITBINOM = KRITBINOM ## Azt a legkisebb számot adja eredményül, amelyre a binomiális eloszlásfüggvény értéke nem kisebb egy adott határértéknél. +DEVSQ = SQ ## Az átlagtól való eltérések négyzetének összegét számítja ki. +EXPONDIST = EXP.ELOSZLÁS ## Az exponenciális eloszlás értékét számítja ki. +FDIST = F.ELOSZLÁS ## Az F-eloszlás értékét számítja ki. +FINV = INVERZ.F ## Az F-eloszlás inverzének értékét számítja ki. +FISHER = FISHER ## Fisher-transzformációt hajt végre. +FISHERINV = INVERZ.FISHER ## A Fisher-transzformáció inverzét hajtja végre. +FORECAST = ELŐREJELZÉS ## Az ismert értékek alapján lineáris regresszióval becsült értéket ad eredményül. +FREQUENCY = GYAKORISÁG ## A gyakorisági vagy empirikus eloszlás értékét függőleges tömbként adja eredményül. +FTEST = F.PRÓBA ## Az F-próba értékét adja eredményül. +GAMMADIST = GAMMA.ELOSZLÁS ## A gamma-eloszlás értékét számítja ki. +GAMMAINV = INVERZ.GAMMA ## A gamma-eloszlás eloszlásfüggvénye inverzének értékét számítja ki. +GAMMALN = GAMMALN ## A gamma-függvény természetes logaritmusát számítja ki. +GEOMEAN = MÉRTANI.KÖZÉP ## Argumentumai mértani középértékét számítja ki. +GROWTH = NÖV ## Exponenciális regresszió alapján ad becslést. +HARMEAN = HARM.KÖZÉP ## Argumentumai harmonikus átlagát számítja ki. +HYPGEOMDIST = HIPERGEOM.ELOSZLÁS ## A hipergeometriai eloszlás értékét számítja ki. +INTERCEPT = METSZ ## A regressziós egyenes y tengellyel való metszéspontját határozza meg. +KURT = CSÚCSOSSÁG ## Egy adathalmaz csúcsosságát számítja ki. +LARGE = NAGY ## Egy adathalmaz k-adik legnagyobb elemét adja eredményül. +LINEST = LIN.ILL ## A legkisebb négyzetek módszerével az adatokra illesztett egyenes paramétereit határozza meg. +LOGEST = LOG.ILL ## Az adatokra illesztett exponenciális görbe paramétereit határozza meg. +LOGINV = INVERZ.LOG.ELOSZLÁS ## A lognormális eloszlás inverzét számítja ki. +LOGNORMDIST = LOG.ELOSZLÁS ## A lognormális eloszlásfüggvény értékét számítja ki. +MAX = MAX ## Az argumentumai között szereplő legnagyobb számot adja meg. +MAXA = MAX2 ## Az argumentumai között szereplő legnagyobb számot adja meg (beleértve a számokat, szöveget és logikai értékeket). +MEDIAN = MEDIÁN ## Adott számhalmaz mediánját számítja ki. +MIN = MIN ## Az argumentumai között szereplő legkisebb számot adja meg. +MINA = MIN2 ## Az argumentumai között szereplő legkisebb számot adja meg, beleértve a számokat, szöveget és logikai értékeket. +MODE = MÓDUSZ ## Egy adathalmazból kiválasztja a leggyakrabban előforduló számot. +NEGBINOMDIST = NEGBINOM.ELOSZL ## A negatív binomiális eloszlás értékét számítja ki. +NORMDIST = NORM.ELOSZL ## A normális eloszlás értékét számítja ki. +NORMINV = INVERZ.NORM ## A normális eloszlás eloszlásfüggvénye inverzének értékét számítja ki. +NORMSDIST = STNORMELOSZL ## A standard normális eloszlás eloszlásfüggvényének értékét számítja ki. +NORMSINV = INVERZ.STNORM ## A standard normális eloszlás eloszlásfüggvénye inverzének értékét számítja ki. +PEARSON = PEARSON ## A Pearson-féle korrelációs együtthatót számítja ki. +PERCENTILE = PERCENTILIS ## Egy tartományban található értékek k-adik percentilisét, azaz százalékosztályát adja eredményül. +PERCENTRANK = SZÁZALÉKRANG ## Egy értéknek egy adathalmazon belül vett százalékos rangját (elhelyezkedését) számítja ki. +PERMUT = VARIÁCIÓK ## Adott számú objektum k-ad osztályú ismétlés nélküli variációinak számát számítja ki. +POISSON = POISSON ## A Poisson-eloszlás értékét számítja ki. +PROB = VALÓSZÍNŰSÉG ## Annak valószínűségét számítja ki, hogy adott értékek két határérték közé esnek. +QUARTILE = KVARTILIS ## Egy adathalmaz kvartilisét (negyedszintjét) számítja ki. +RANK = SORSZÁM ## Kiszámítja, hogy egy szám hányadik egy számsorozatban. +RSQ = RNÉGYZET ## Kiszámítja a Pearson-féle szorzatmomentum korrelációs együtthatójának négyzetét. +SKEW = FERDESÉG ## Egy eloszlás ferdeségét határozza meg. +SLOPE = MEREDEKSÉG ## Egy lineáris regressziós egyenes meredekségét számítja ki. +SMALL = KICSI ## Egy adathalmaz k-adik legkisebb elemét adja meg. +STANDARDIZE = NORMALIZÁLÁS ## Normalizált értéket ad eredményül. +STDEV = SZÓRÁS ## Egy statisztikai sokaság mintájából kiszámítja annak szórását. +STDEVA = SZÓRÁSA ## Egy statisztikai sokaság mintájából kiszámítja annak szórását (beleértve a számokat, szöveget és logikai értékeket). +STDEVP = SZÓRÁSP ## Egy statisztikai sokaság egészéből kiszámítja annak szórását. +STDEVPA = SZÓRÁSPA ## Egy statisztikai sokaság egészéből kiszámítja annak szórását (beleértve számokat, szöveget és logikai értékeket). +STEYX = STHIBAYX ## Egy regresszió esetén az egyes x-értékek alapján meghatározott y-értékek standard hibáját számítja ki. +TDIST = T.ELOSZLÁS ## A Student-féle t-eloszlás értékét számítja ki. +TINV = INVERZ.T ## A Student-féle t-eloszlás inverzét számítja ki. +TREND = TREND ## Lineáris trend értékeit számítja ki. +TRIMMEAN = RÉSZÁTLAG ## Egy adathalmaz középső részének átlagát számítja ki. +TTEST = T.PRÓBA ## A Student-féle t-próbához tartozó valószínűséget számítja ki. +VAR = VAR ## Minta alapján becslést ad a varianciára. +VARA = VARA ## Minta alapján becslést ad a varianciára (beleértve számokat, szöveget és logikai értékeket). +VARP = VARP ## Egy statisztikai sokaság varianciáját számítja ki. +VARPA = VARPA ## Egy statisztikai sokaság varianciáját számítja ki (beleértve számokat, szöveget és logikai értékeket). +WEIBULL = WEIBULL ## A Weibull-féle eloszlás értékét számítja ki. +ZTEST = Z.PRÓBA ## Az egyszélű z-próbával kapott valószínűségértéket számítja ki. + + +## +## Text functions Szövegműveletekhez használható függvények +## +ASC = ASC ## Szöveg teljes szélességű (kétbájtos) latin és katakana karaktereit félszélességű (egybájtos) karakterekké alakítja. +BAHTTEXT = BAHTSZÖVEG ## Számot szöveggé alakít a ß (baht) pénznemformátum használatával. +CHAR = KARAKTER ## A kódszámmal meghatározott karaktert adja eredményül. +CLEAN = TISZTÍT ## A szövegből eltávolítja az összes nem nyomtatható karaktert. +CODE = KÓD ## Karaktersorozat első karakterének numerikus kódját adja eredményül. +CONCATENATE = ÖSSZEFŰZ ## Több szövegelemet egyetlen szöveges elemmé fűz össze. +DOLLAR = FORINT ## Számot pénznem formátumú szöveggé alakít át. +EXACT = AZONOS ## Megvizsgálja, hogy két érték azonos-e. +FIND = SZÖVEG.TALÁL ## Karaktersorozatot keres egy másikban (a kis- és nagybetűk megkülönböztetésével). +FINDB = SZÖVEG.TALÁL2 ## Karaktersorozatot keres egy másikban (a kis- és nagybetűk megkülönböztetésével). +FIXED = FIX ## Számot szöveges formátumúra alakít adott számú tizedesjegyre kerekítve. +JIS = JIS ## A félszélességű (egybájtos) latin és a katakana karaktereket teljes szélességű (kétbájtos) karakterekké alakítja. +LEFT = BAL ## Szöveg bal szélső karaktereit adja eredményül. +LEFTB = BAL2 ## Szöveg bal szélső karaktereit adja eredményül. +LEN = HOSSZ ## Szöveg karakterekben mért hosszát adja eredményül. +LENB = HOSSZ2 ## Szöveg karakterekben mért hosszát adja eredményül. +LOWER = KISBETŰ ## Szöveget kisbetűssé alakít át. +MID = KÖZÉP ## A szöveg adott pozíciójától kezdve megadott számú karaktert ad vissza eredményként. +MIDB = KÖZÉP2 ## A szöveg adott pozíciójától kezdve megadott számú karaktert ad vissza eredményként. +PHONETIC = PHONETIC ## Szöveg furigana (fonetikus) karaktereit adja vissza. +PROPER = TNÉV ## Szöveg minden szavának kezdőbetűjét nagybetűsre cseréli. +REPLACE = CSERE ## A szövegen belül karaktereket cserél. +REPLACEB = CSERE2 ## A szövegen belül karaktereket cserél. +REPT = SOKSZOR ## Megadott számú alkalommal megismétel egy szövegrészt. +RIGHT = JOBB ## Szövegrész jobb szélső karaktereit adja eredményül. +RIGHTB = JOBB2 ## Szövegrész jobb szélső karaktereit adja eredményül. +SEARCH = SZÖVEG.KERES ## Karaktersorozatot keres egy másikban (a kis- és nagybetűk között nem tesz különbséget). +SEARCHB = SZÖVEG.KERES2 ## Karaktersorozatot keres egy másikban (a kis- és nagybetűk között nem tesz különbséget). +SUBSTITUTE = HELYETTE ## Szövegben adott karaktereket másikra cserél. +T = T ## Argumentumát szöveggé alakítja át. +TEXT = SZÖVEG ## Számértéket alakít át adott számformátumú szöveggé. +TRIM = TRIM ## A szövegből eltávolítja a szóközöket. +UPPER = NAGYBETŰS ## Szöveget nagybetűssé alakít át. +VALUE = ÉRTÉK ## Szöveget számmá alakít át. diff --git a/lib/phpexcel/PHPExcel/locale/it/config b/lib/phpexcel/PHPExcel/locale/it/config new file mode 100644 index 0000000..94499fe --- /dev/null +++ b/lib/phpexcel/PHPExcel/locale/it/config @@ -0,0 +1,47 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Settings +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## + + +ArgumentSeparator = ; + + +## +## (For future use) +## +currencySymbol = € + + +## +## Excel Error Codes (For future use) +## +NULL = #NULLO! +DIV0 = #DIV/0! +VALUE = #VALORE! +REF = #RIF! +NAME = #NOME? +NUM = #NUM! +NA = #N/D diff --git a/lib/phpexcel/PHPExcel/locale/it/functions b/lib/phpexcel/PHPExcel/locale/it/functions new file mode 100644 index 0000000..033b969 --- /dev/null +++ b/lib/phpexcel/PHPExcel/locale/it/functions @@ -0,0 +1,438 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Calculation +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## Data in this file derived from http://www.piuha.fi/excel-function-name-translation/ +## +## + + +## +## Add-in and Automation functions Funzioni di automazione e dei componenti aggiuntivi +## +GETPIVOTDATA = INFO.DATI.TAB.PIVOT ## Restituisce i dati memorizzati in un rapporto di tabella pivot + + +## +## Cube functions Funzioni cubo +## +CUBEKPIMEMBER = MEMBRO.KPI.CUBO ## Restituisce il nome, la proprietà e la misura di un indicatore di prestazioni chiave (KPI) e visualizza il nome e la proprietà nella cella. Un KPI è una misura quantificabile, ad esempio l'utile lordo mensile o il fatturato trimestrale dei dipendenti, utilizzata per il monitoraggio delle prestazioni di un'organizzazione. +CUBEMEMBER = MEMBRO.CUBO ## Restituisce un membro o una tupla in una gerarchia di cubi. Consente di verificare l'esistenza del membro o della tupla nel cubo. +CUBEMEMBERPROPERTY = PROPRIETÀ.MEMBRO.CUBO ## Restituisce il valore di una proprietà di un membro del cubo. Consente di verificare l'esistenza di un nome di membro all'interno del cubo e di restituire la proprietà specificata per tale membro. +CUBERANKEDMEMBER = MEMBRO.CUBO.CON.RANGO ## Restituisce l'n-esimo membro o il membro ordinato di un insieme. Consente di restituire uno o più elementi in un insieme, ad esempio l'agente di vendita migliore o i primi 10 studenti. +CUBESET = SET.CUBO ## Definisce un insieme di tuple o membri calcolati mediante l'invio di un'espressione di insieme al cubo sul server. In questo modo l'insieme viene creato e restituito a Microsoft Office Excel. +CUBESETCOUNT = CONTA.SET.CUBO ## Restituisce il numero di elementi di un insieme. +CUBEVALUE = VALORE.CUBO ## Restituisce un valore aggregato da un cubo. + + +## +## Database functions Funzioni di database +## +DAVERAGE = DB.MEDIA ## Restituisce la media di voci del database selezionate +DCOUNT = DB.CONTA.NUMERI ## Conta le celle di un database contenenti numeri +DCOUNTA = DB.CONTA.VALORI ## Conta le celle non vuote in un database +DGET = DB.VALORI ## Estrae da un database un singolo record che soddisfa i criteri specificati +DMAX = DB.MAX ## Restituisce il valore massimo dalle voci selezionate in un database +DMIN = DB.MIN ## Restituisce il valore minimo dalle voci di un database selezionate +DPRODUCT = DB.PRODOTTO ## Moltiplica i valori in un determinato campo di record che soddisfano i criteri del database +DSTDEV = DB.DEV.ST ## Restituisce una stima della deviazione standard sulla base di un campione di voci di un database selezionate +DSTDEVP = DB.DEV.ST.POP ## Calcola la deviazione standard sulla base di tutte le voci di un database selezionate +DSUM = DB.SOMMA ## Aggiunge i numeri nel campo colonna di record del database che soddisfa determinati criteri +DVAR = DB.VAR ## Restituisce una stima della varianza sulla base di un campione da voci di un database selezionate +DVARP = DB.VAR.POP ## Calcola la varianza sulla base di tutte le voci di un database selezionate + + +## +## Date and time functions Funzioni data e ora +## +DATE = DATA ## Restituisce il numero seriale di una determinata data +DATEVALUE = DATA.VALORE ## Converte una data sotto forma di testo in un numero seriale +DAY = GIORNO ## Converte un numero seriale in un giorno del mese +DAYS360 = GIORNO360 ## Calcola il numero di giorni compreso tra due date basandosi su un anno di 360 giorni +EDATE = DATA.MESE ## Restituisce il numero seriale della data che rappresenta il numero di mesi prima o dopo la data di inizio +EOMONTH = FINE.MESE ## Restituisce il numero seriale dell'ultimo giorno del mese, prima o dopo un determinato numero di mesi +HOUR = ORA ## Converte un numero seriale in un'ora +MINUTE = MINUTO ## Converte un numero seriale in un minuto +MONTH = MESE ## Converte un numero seriale in un mese +NETWORKDAYS = GIORNI.LAVORATIVI.TOT ## Restituisce il numero di tutti i giorni lavorativi compresi fra due date +NOW = ADESSO ## Restituisce il numero seriale della data e dell'ora corrente +SECOND = SECONDO ## Converte un numero seriale in un secondo +TIME = ORARIO ## Restituisce il numero seriale di una determinata ora +TIMEVALUE = ORARIO.VALORE ## Converte un orario in forma di testo in un numero seriale +TODAY = OGGI ## Restituisce il numero seriale relativo alla data odierna +WEEKDAY = GIORNO.SETTIMANA ## Converte un numero seriale in un giorno della settimana +WEEKNUM = NUM.SETTIMANA ## Converte un numero seriale in un numero che rappresenta la posizione numerica di una settimana nell'anno +WORKDAY = GIORNO.LAVORATIVO ## Restituisce il numero della data prima o dopo un determinato numero di giorni lavorativi +YEAR = ANNO ## Converte un numero seriale in un anno +YEARFRAC = FRAZIONE.ANNO ## Restituisce la frazione dell'anno che rappresenta il numero dei giorni compresi tra una data_ iniziale e una data_finale + + +## +## Engineering functions Funzioni ingegneristiche +## +BESSELI = BESSEL.I ## Restituisce la funzione di Bessel modificata In(x) +BESSELJ = BESSEL.J ## Restituisce la funzione di Bessel Jn(x) +BESSELK = BESSEL.K ## Restituisce la funzione di Bessel modificata Kn(x) +BESSELY = BESSEL.Y ## Restituisce la funzione di Bessel Yn(x) +BIN2DEC = BINARIO.DECIMALE ## Converte un numero binario in decimale +BIN2HEX = BINARIO.HEX ## Converte un numero binario in esadecimale +BIN2OCT = BINARIO.OCT ## Converte un numero binario in ottale +COMPLEX = COMPLESSO ## Converte i coefficienti reali e immaginari in numeri complessi +CONVERT = CONVERTI ## Converte un numero da un sistema di misura in un altro +DEC2BIN = DECIMALE.BINARIO ## Converte un numero decimale in binario +DEC2HEX = DECIMALE.HEX ## Converte un numero decimale in esadecimale +DEC2OCT = DECIMALE.OCT ## Converte un numero decimale in ottale +DELTA = DELTA ## Verifica se due valori sono uguali +ERF = FUNZ.ERRORE ## Restituisce la funzione di errore +ERFC = FUNZ.ERRORE.COMP ## Restituisce la funzione di errore complementare +GESTEP = SOGLIA ## Verifica se un numero è maggiore del valore di soglia +HEX2BIN = HEX.BINARIO ## Converte un numero esadecimale in binario +HEX2DEC = HEX.DECIMALE ## Converte un numero esadecimale in decimale +HEX2OCT = HEX.OCT ## Converte un numero esadecimale in ottale +IMABS = COMP.MODULO ## Restituisce il valore assoluto (modulo) di un numero complesso +IMAGINARY = COMP.IMMAGINARIO ## Restituisce il coefficiente immaginario di un numero complesso +IMARGUMENT = COMP.ARGOMENTO ## Restituisce l'argomento theta, un angolo espresso in radianti +IMCONJUGATE = COMP.CONIUGATO ## Restituisce il complesso coniugato del numero complesso +IMCOS = COMP.COS ## Restituisce il coseno di un numero complesso +IMDIV = COMP.DIV ## Restituisce il quoziente di due numeri complessi +IMEXP = COMP.EXP ## Restituisce il valore esponenziale di un numero complesso +IMLN = COMP.LN ## Restituisce il logaritmo naturale di un numero complesso +IMLOG10 = COMP.LOG10 ## Restituisce il logaritmo in base 10 di un numero complesso +IMLOG2 = COMP.LOG2 ## Restituisce un logaritmo in base 2 di un numero complesso +IMPOWER = COMP.POTENZA ## Restituisce il numero complesso elevato a una potenza intera +IMPRODUCT = COMP.PRODOTTO ## Restituisce il prodotto di numeri complessi compresi tra 2 e 29 +IMREAL = COMP.PARTE.REALE ## Restituisce il coefficiente reale di un numero complesso +IMSIN = COMP.SEN ## Restituisce il seno di un numero complesso +IMSQRT = COMP.RADQ ## Restituisce la radice quadrata di un numero complesso +IMSUB = COMP.DIFF ## Restituisce la differenza fra due numeri complessi +IMSUM = COMP.SOMMA ## Restituisce la somma di numeri complessi +OCT2BIN = OCT.BINARIO ## Converte un numero ottale in binario +OCT2DEC = OCT.DECIMALE ## Converte un numero ottale in decimale +OCT2HEX = OCT.HEX ## Converte un numero ottale in esadecimale + + +## +## Financial functions Funzioni finanziarie +## +ACCRINT = INT.MATURATO.PER ## Restituisce l'interesse maturato di un titolo che paga interessi periodici +ACCRINTM = INT.MATURATO.SCAD ## Restituisce l'interesse maturato di un titolo che paga interessi alla scadenza +AMORDEGRC = AMMORT.DEGR ## Restituisce l'ammortamento per ogni periodo contabile utilizzando un coefficiente di ammortamento +AMORLINC = AMMORT.PER ## Restituisce l'ammortamento per ogni periodo contabile +COUPDAYBS = GIORNI.CED.INIZ.LIQ ## Restituisce il numero dei giorni che vanno dall'inizio del periodo di durata della cedola alla data di liquidazione +COUPDAYS = GIORNI.CED ## Restituisce il numero dei giorni relativi al periodo della cedola che contiene la data di liquidazione +COUPDAYSNC = GIORNI.CED.NUOVA ## Restituisce il numero di giorni che vanno dalla data di liquidazione alla data della cedola successiva +COUPNCD = DATA.CED.SUCC ## Restituisce un numero che rappresenta la data della cedola successiva alla data di liquidazione +COUPNUM = NUM.CED ## Restituisce il numero di cedole pagabili fra la data di liquidazione e la data di scadenza +COUPPCD = DATA.CED.PREC ## Restituisce un numero che rappresenta la data della cedola precedente alla data di liquidazione +CUMIPMT = INT.CUMUL ## Restituisce l'interesse cumulativo pagato fra due periodi +CUMPRINC = CAP.CUM ## Restituisce il capitale cumulativo pagato per estinguere un debito fra due periodi +DB = DB ## Restituisce l'ammortamento di un bene per un periodo specificato utilizzando il metodo di ammortamento a quote fisse decrescenti +DDB = AMMORT ## Restituisce l'ammortamento di un bene per un periodo specificato utilizzando il metodo di ammortamento a doppie quote decrescenti o altri metodi specificati +DISC = TASSO.SCONTO ## Restituisce il tasso di sconto per un titolo +DOLLARDE = VALUTA.DEC ## Converte un prezzo valuta, espresso come frazione, in prezzo valuta, espresso come numero decimale +DOLLARFR = VALUTA.FRAZ ## Converte un prezzo valuta, espresso come numero decimale, in prezzo valuta, espresso come frazione +DURATION = DURATA ## Restituisce la durata annuale di un titolo con i pagamenti di interesse periodico +EFFECT = EFFETTIVO ## Restituisce l'effettivo tasso di interesse annuo +FV = VAL.FUT ## Restituisce il valore futuro di un investimento +FVSCHEDULE = VAL.FUT.CAPITALE ## Restituisce il valore futuro di un capitale iniziale dopo aver applicato una serie di tassi di interesse composti +INTRATE = TASSO.INT ## Restituisce il tasso di interesse per un titolo interamente investito +IPMT = INTERESSI ## Restituisce il valore degli interessi per un investimento relativo a un periodo specifico +IRR = TIR.COST ## Restituisce il tasso di rendimento interno per una serie di flussi di cassa +ISPMT = INTERESSE.RATA ## Calcola l'interesse di un investimento pagato durante un periodo specifico +MDURATION = DURATA.M ## Restituisce la durata Macauley modificata per un titolo con un valore presunto di € 100 +MIRR = TIR.VAR ## Restituisce il tasso di rendimento interno in cui i flussi di cassa positivi e negativi sono finanziati a tassi differenti +NOMINAL = NOMINALE ## Restituisce il tasso di interesse nominale annuale +NPER = NUM.RATE ## Restituisce un numero di periodi relativi a un investimento +NPV = VAN ## Restituisce il valore attuale netto di un investimento basato su una serie di flussi di cassa periodici e sul tasso di sconto +ODDFPRICE = PREZZO.PRIMO.IRR ## Restituisce il prezzo di un titolo dal valore nominale di € 100 avente il primo periodo di durata irregolare +ODDFYIELD = REND.PRIMO.IRR ## Restituisce il rendimento di un titolo avente il primo periodo di durata irregolare +ODDLPRICE = PREZZO.ULTIMO.IRR ## Restituisce il prezzo di un titolo dal valore nominale di € 100 avente l'ultimo periodo di durata irregolare +ODDLYIELD = REND.ULTIMO.IRR ## Restituisce il rendimento di un titolo avente l'ultimo periodo di durata irregolare +PMT = RATA ## Restituisce il pagamento periodico di una rendita annua +PPMT = P.RATA ## Restituisce il pagamento sul capitale di un investimento per un dato periodo +PRICE = PREZZO ## Restituisce il prezzo di un titolo dal valore nominale di € 100 che paga interessi periodici +PRICEDISC = PREZZO.SCONT ## Restituisce il prezzo di un titolo scontato dal valore nominale di € 100 +PRICEMAT = PREZZO.SCAD ## Restituisce il prezzo di un titolo dal valore nominale di € 100 che paga gli interessi alla scadenza +PV = VA ## Restituisce il valore attuale di un investimento +RATE = TASSO ## Restituisce il tasso di interesse per un periodo di un'annualità +RECEIVED = RICEV.SCAD ## Restituisce l'ammontare ricevuto alla scadenza di un titolo interamente investito +SLN = AMMORT.COST ## Restituisce l'ammortamento a quote costanti di un bene per un singolo periodo +SYD = AMMORT.ANNUO ## Restituisce l'ammortamento a somma degli anni di un bene per un periodo specificato +TBILLEQ = BOT.EQUIV ## Restituisce il rendimento equivalente ad un'obbligazione per un Buono ordinario del Tesoro +TBILLPRICE = BOT.PREZZO ## Restituisce il prezzo di un Buono del Tesoro dal valore nominale di € 100 +TBILLYIELD = BOT.REND ## Restituisce il rendimento di un Buono del Tesoro +VDB = AMMORT.VAR ## Restituisce l'ammortamento di un bene per un periodo specificato o parziale utilizzando il metodo a doppie quote proporzionali ai valori residui +XIRR = TIR.X ## Restituisce il tasso di rendimento interno di un impiego di flussi di cassa +XNPV = VAN.X ## Restituisce il valore attuale netto di un impiego di flussi di cassa non necessariamente periodici +YIELD = REND ## Restituisce il rendimento di un titolo che frutta interessi periodici +YIELDDISC = REND.TITOLI.SCONT ## Restituisce il rendimento annuale di un titolo scontato, ad esempio un Buono del Tesoro +YIELDMAT = REND.SCAD ## Restituisce il rendimento annuo di un titolo che paga interessi alla scadenza + + +## +## Information functions Funzioni relative alle informazioni +## +CELL = CELLA ## Restituisce le informazioni sulla formattazione, la posizione o i contenuti di una cella +ERROR.TYPE = ERRORE.TIPO ## Restituisce un numero che corrisponde a un tipo di errore +INFO = INFO ## Restituisce le informazioni sull'ambiente operativo corrente +ISBLANK = VAL.VUOTO ## Restituisce VERO se il valore è vuoto +ISERR = VAL.ERR ## Restituisce VERO se il valore è un valore di errore qualsiasi tranne #N/D +ISERROR = VAL.ERRORE ## Restituisce VERO se il valore è un valore di errore qualsiasi +ISEVEN = VAL.PARI ## Restituisce VERO se il numero è pari +ISLOGICAL = VAL.LOGICO ## Restituisce VERO se il valore è un valore logico +ISNA = VAL.NON.DISP ## Restituisce VERO se il valore è un valore di errore #N/D +ISNONTEXT = VAL.NON.TESTO ## Restituisce VERO se il valore non è in formato testo +ISNUMBER = VAL.NUMERO ## Restituisce VERO se il valore è un numero +ISODD = VAL.DISPARI ## Restituisce VERO se il numero è dispari +ISREF = VAL.RIF ## Restituisce VERO se il valore è un riferimento +ISTEXT = VAL.TESTO ## Restituisce VERO se il valore è in formato testo +N = NUM ## Restituisce un valore convertito in numero +NA = NON.DISP ## Restituisce il valore di errore #N/D +TYPE = TIPO ## Restituisce un numero che indica il tipo di dati relativi a un valore + + +## +## Logical functions Funzioni logiche +## +AND = E ## Restituisce VERO se tutti gli argomenti sono VERO +FALSE = FALSO ## Restituisce il valore logico FALSO +IF = SE ## Specifica un test logico da eseguire +IFERROR = SE.ERRORE ## Restituisce un valore specificato se una formula fornisce un errore come risultato; in caso contrario, restituisce il risultato della formula +NOT = NON ## Inverte la logica degli argomenti +OR = O ## Restituisce VERO se un argomento qualsiasi è VERO +TRUE = VERO ## Restituisce il valore logico VERO + + +## +## Lookup and reference functions Funzioni di ricerca e di riferimento +## +ADDRESS = INDIRIZZO ## Restituisce un riferimento come testo in una singola cella di un foglio di lavoro +AREAS = AREE ## Restituisce il numero di aree in un riferimento +CHOOSE = SCEGLI ## Sceglie un valore da un elenco di valori +COLUMN = RIF.COLONNA ## Restituisce il numero di colonna di un riferimento +COLUMNS = COLONNE ## Restituisce il numero di colonne in un riferimento +HLOOKUP = CERCA.ORIZZ ## Effettua una ricerca nella riga superiore di una matrice e restituisce il valore della cella specificata +HYPERLINK = COLLEG.IPERTESTUALE ## Crea un collegamento che apre un documento memorizzato in un server di rete, una rete Intranet o Internet +INDEX = INDICE ## Utilizza un indice per scegliere un valore da un riferimento o da una matrice +INDIRECT = INDIRETTO ## Restituisce un riferimento specificato da un valore testo +LOOKUP = CERCA ## Ricerca i valori in un vettore o in una matrice +MATCH = CONFRONTA ## Ricerca i valori in un riferimento o in una matrice +OFFSET = SCARTO ## Restituisce uno scarto di riferimento da un riferimento dato +ROW = RIF.RIGA ## Restituisce il numero di riga di un riferimento +ROWS = RIGHE ## Restituisce il numero delle righe in un riferimento +RTD = DATITEMPOREALE ## Recupera dati in tempo reale da un programma che supporta l'automazione COM (automazione: Metodo per utilizzare gli oggetti di un'applicazione da un'altra applicazione o da un altro strumento di sviluppo. Precedentemente nota come automazione OLE, l'automazione è uno standard del settore e una caratteristica del modello COM (Component Object Model).) +TRANSPOSE = MATR.TRASPOSTA ## Restituisce la trasposizione di una matrice +VLOOKUP = CERCA.VERT ## Effettua una ricerca nella prima colonna di una matrice e si sposta attraverso la riga per restituire il valore di una cella + + +## +## Math and trigonometry functions Funzioni matematiche e trigonometriche +## +ABS = ASS ## Restituisce il valore assoluto di un numero. +ACOS = ARCCOS ## Restituisce l'arcocoseno di un numero +ACOSH = ARCCOSH ## Restituisce l'inverso del coseno iperbolico di un numero +ASIN = ARCSEN ## Restituisce l'arcoseno di un numero +ASINH = ARCSENH ## Restituisce l'inverso del seno iperbolico di un numero +ATAN = ARCTAN ## Restituisce l'arcotangente di un numero +ATAN2 = ARCTAN.2 ## Restituisce l'arcotangente delle coordinate x e y specificate +ATANH = ARCTANH ## Restituisce l'inverso della tangente iperbolica di un numero +CEILING = ARROTONDA.ECCESSO ## Arrotonda un numero per eccesso all'intero più vicino o al multiplo più vicino a peso +COMBIN = COMBINAZIONE ## Restituisce il numero di combinazioni possibili per un numero assegnato di elementi +COS = COS ## Restituisce il coseno dell'angolo specificato +COSH = COSH ## Restituisce il coseno iperbolico di un numero +DEGREES = GRADI ## Converte i radianti in gradi +EVEN = PARI ## Arrotonda il valore assoluto di un numero per eccesso al più vicino intero pari +EXP = ESP ## Restituisce il numero e elevato alla potenza di num +FACT = FATTORIALE ## Restituisce il fattoriale di un numero +FACTDOUBLE = FATT.DOPPIO ## Restituisce il fattoriale doppio di un numero +FLOOR = ARROTONDA.DIFETTO ## Arrotonda un numero per difetto al multiplo più vicino a zero +GCD = MCD ## Restituisce il massimo comune divisore +INT = INT ## Arrotonda un numero per difetto al numero intero più vicino +LCM = MCM ## Restituisce il minimo comune multiplo +LN = LN ## Restituisce il logaritmo naturale di un numero +LOG = LOG ## Restituisce il logaritmo di un numero in una specificata base +LOG10 = LOG10 ## Restituisce il logaritmo in base 10 di un numero +MDETERM = MATR.DETERM ## Restituisce il determinante di una matrice +MINVERSE = MATR.INVERSA ## Restituisce l'inverso di una matrice +MMULT = MATR.PRODOTTO ## Restituisce il prodotto di due matrici +MOD = RESTO ## Restituisce il resto della divisione +MROUND = ARROTONDA.MULTIPLO ## Restituisce un numero arrotondato al multiplo desiderato +MULTINOMIAL = MULTINOMIALE ## Restituisce il multinomiale di un insieme di numeri +ODD = DISPARI ## Arrotonda un numero per eccesso al più vicino intero dispari +PI = PI.GRECO ## Restituisce il valore di pi greco +POWER = POTENZA ## Restituisce il risultato di un numero elevato a potenza +PRODUCT = PRODOTTO ## Moltiplica i suoi argomenti +QUOTIENT = QUOZIENTE ## Restituisce la parte intera di una divisione +RADIANS = RADIANTI ## Converte i gradi in radianti +RAND = CASUALE ## Restituisce un numero casuale compreso tra 0 e 1 +RANDBETWEEN = CASUALE.TRA ## Restituisce un numero casuale compreso tra i numeri specificati +ROMAN = ROMANO ## Restituisce il numero come numero romano sotto forma di testo +ROUND = ARROTONDA ## Arrotonda il numero al numero di cifre specificato +ROUNDDOWN = ARROTONDA.PER.DIF ## Arrotonda il valore assoluto di un numero per difetto +ROUNDUP = ARROTONDA.PER.ECC ## Arrotonda il valore assoluto di un numero per eccesso +SERIESSUM = SOMMA.SERIE ## Restituisce la somma di una serie di potenze in base alla formula +SIGN = SEGNO ## Restituisce il segno di un numero +SIN = SEN ## Restituisce il seno di un dato angolo +SINH = SENH ## Restituisce il seno iperbolico di un numero +SQRT = RADQ ## Restituisce una radice quadrata +SQRTPI = RADQ.PI.GRECO ## Restituisce la radice quadrata di un numero (numero * pi greco) +SUBTOTAL = SUBTOTALE ## Restituisce un subtotale in un elenco o in un database +SUM = SOMMA ## Somma i suoi argomenti +SUMIF = SOMMA.SE ## Somma le celle specificate da un dato criterio +SUMIFS = SOMMA.PIÙ.SE ## Somma le celle in un intervallo che soddisfano più criteri +SUMPRODUCT = MATR.SOMMA.PRODOTTO ## Restituisce la somma dei prodotti dei componenti corrispondenti della matrice +SUMSQ = SOMMA.Q ## Restituisce la somma dei quadrati degli argomenti +SUMX2MY2 = SOMMA.DIFF.Q ## Restituisce la somma della differenza dei quadrati dei corrispondenti elementi in due matrici +SUMX2PY2 = SOMMA.SOMMA.Q ## Restituisce la somma della somma dei quadrati dei corrispondenti elementi in due matrici +SUMXMY2 = SOMMA.Q.DIFF ## Restituisce la somma dei quadrati delle differenze dei corrispondenti elementi in due matrici +TAN = TAN ## Restituisce la tangente di un numero +TANH = TANH ## Restituisce la tangente iperbolica di un numero +TRUNC = TRONCA ## Tronca la parte decimale di un numero + + +## +## Statistical functions Funzioni statistiche +## +AVEDEV = MEDIA.DEV ## Restituisce la media delle deviazioni assolute delle coordinate rispetto alla loro media +AVERAGE = MEDIA ## Restituisce la media degli argomenti +AVERAGEA = MEDIA.VALORI ## Restituisce la media degli argomenti, inclusi i numeri, il testo e i valori logici +AVERAGEIF = MEDIA.SE ## Restituisce la media aritmetica di tutte le celle in un intervallo che soddisfano un determinato criterio +AVERAGEIFS = MEDIA.PIÙ.SE ## Restituisce la media aritmetica di tutte le celle che soddisfano più criteri +BETADIST = DISTRIB.BETA ## Restituisce la funzione di distribuzione cumulativa beta +BETAINV = INV.BETA ## Restituisce l'inverso della funzione di distribuzione cumulativa per una distribuzione beta specificata +BINOMDIST = DISTRIB.BINOM ## Restituisce la distribuzione binomiale per il termine individuale +CHIDIST = DISTRIB.CHI ## Restituisce la probabilità a una coda per la distribuzione del chi quadrato +CHIINV = INV.CHI ## Restituisce l'inverso della probabilità ad una coda per la distribuzione del chi quadrato +CHITEST = TEST.CHI ## Restituisce il test per l'indipendenza +CONFIDENCE = CONFIDENZA ## Restituisce l'intervallo di confidenza per una popolazione +CORREL = CORRELAZIONE ## Restituisce il coefficiente di correlazione tra due insiemi di dati +COUNT = CONTA.NUMERI ## Conta la quantità di numeri nell'elenco di argomenti +COUNTA = CONTA.VALORI ## Conta il numero di valori nell'elenco di argomenti +COUNTBLANK = CONTA.VUOTE ## Conta il numero di celle vuote all'interno di un intervallo +COUNTIF = CONTA.SE ## Conta il numero di celle all'interno di un intervallo che soddisfa i criteri specificati +COUNTIFS = CONTA.PIÙ.SE ## Conta il numero di celle in un intervallo che soddisfano più criteri. +COVAR = COVARIANZA ## Calcola la covarianza, la media dei prodotti delle deviazioni accoppiate +CRITBINOM = CRIT.BINOM ## Restituisce il più piccolo valore per il quale la distribuzione cumulativa binomiale risulta maggiore o uguale ad un valore di criterio +DEVSQ = DEV.Q ## Restituisce la somma dei quadrati delle deviazioni +EXPONDIST = DISTRIB.EXP ## Restituisce la distribuzione esponenziale +FDIST = DISTRIB.F ## Restituisce la distribuzione di probabilità F +FINV = INV.F ## Restituisce l'inverso della distribuzione della probabilità F +FISHER = FISHER ## Restituisce la trasformazione di Fisher +FISHERINV = INV.FISHER ## Restituisce l'inverso della trasformazione di Fisher +FORECAST = PREVISIONE ## Restituisce i valori lungo una tendenza lineare +FREQUENCY = FREQUENZA ## Restituisce la distribuzione di frequenza come matrice verticale +FTEST = TEST.F ## Restituisce il risultato di un test F +GAMMADIST = DISTRIB.GAMMA ## Restituisce la distribuzione gamma +GAMMAINV = INV.GAMMA ## Restituisce l'inverso della distribuzione cumulativa gamma +GAMMALN = LN.GAMMA ## Restituisce il logaritmo naturale della funzione gamma, G(x) +GEOMEAN = MEDIA.GEOMETRICA ## Restituisce la media geometrica +GROWTH = CRESCITA ## Restituisce i valori lungo una linea di tendenza esponenziale +HARMEAN = MEDIA.ARMONICA ## Restituisce la media armonica +HYPGEOMDIST = DISTRIB.IPERGEOM ## Restituisce la distribuzione ipergeometrica +INTERCEPT = INTERCETTA ## Restituisce l'intercetta della retta di regressione lineare +KURT = CURTOSI ## Restituisce la curtosi di un insieme di dati +LARGE = GRANDE ## Restituisce il k-esimo valore più grande in un insieme di dati +LINEST = REGR.LIN ## Restituisce i parametri di una tendenza lineare +LOGEST = REGR.LOG ## Restituisce i parametri di una linea di tendenza esponenziale +LOGINV = INV.LOGNORM ## Restituisce l'inverso di una distribuzione lognormale +LOGNORMDIST = DISTRIB.LOGNORM ## Restituisce la distribuzione lognormale cumulativa +MAX = MAX ## Restituisce il valore massimo in un elenco di argomenti +MAXA = MAX.VALORI ## Restituisce il valore massimo in un elenco di argomenti, inclusi i numeri, il testo e i valori logici +MEDIAN = MEDIANA ## Restituisce la mediana dei numeri specificati +MIN = MIN ## Restituisce il valore minimo in un elenco di argomenti +MINA = MIN.VALORI ## Restituisce il più piccolo valore in un elenco di argomenti, inclusi i numeri, il testo e i valori logici +MODE = MODA ## Restituisce il valore più comune in un insieme di dati +NEGBINOMDIST = DISTRIB.BINOM.NEG ## Restituisce la distribuzione binomiale negativa +NORMDIST = DISTRIB.NORM ## Restituisce la distribuzione cumulativa normale +NORMINV = INV.NORM ## Restituisce l'inverso della distribuzione cumulativa normale standard +NORMSDIST = DISTRIB.NORM.ST ## Restituisce la distribuzione cumulativa normale standard +NORMSINV = INV.NORM.ST ## Restituisce l'inverso della distribuzione cumulativa normale +PEARSON = PEARSON ## Restituisce il coefficiente del momento di correlazione di Pearson +PERCENTILE = PERCENTILE ## Restituisce il k-esimo dato percentile di valori in un intervallo +PERCENTRANK = PERCENT.RANGO ## Restituisce il rango di un valore in un insieme di dati come percentuale +PERMUT = PERMUTAZIONE ## Restituisce il numero delle permutazioni per un determinato numero di oggetti +POISSON = POISSON ## Restituisce la distribuzione di Poisson +PROB = PROBABILITÀ ## Calcola la probabilità che dei valori in un intervallo siano compresi tra due limiti +QUARTILE = QUARTILE ## Restituisce il quartile di un insieme di dati +RANK = RANGO ## Restituisce il rango di un numero in un elenco di numeri +RSQ = RQ ## Restituisce la radice quadrata del coefficiente di momento di correlazione di Pearson +SKEW = ASIMMETRIA ## Restituisce il grado di asimmetria di una distribuzione +SLOPE = PENDENZA ## Restituisce la pendenza di una retta di regressione lineare +SMALL = PICCOLO ## Restituisce il k-esimo valore più piccolo in un insieme di dati +STANDARDIZE = NORMALIZZA ## Restituisce un valore normalizzato +STDEV = DEV.ST ## Restituisce una stima della deviazione standard sulla base di un campione +STDEVA = DEV.ST.VALORI ## Restituisce una stima della deviazione standard sulla base di un campione, inclusi i numeri, il testo e i valori logici +STDEVP = DEV.ST.POP ## Calcola la deviazione standard sulla base di un'intera popolazione +STDEVPA = DEV.ST.POP.VALORI ## Calcola la deviazione standard sulla base sull'intera popolazione, inclusi i numeri, il testo e i valori logici +STEYX = ERR.STD.YX ## Restituisce l'errore standard del valore previsto per y per ogni valore x nella regressione +TDIST = DISTRIB.T ## Restituisce la distribuzione t di Student +TINV = INV.T ## Restituisce l'inversa della distribuzione t di Student +TREND = TENDENZA ## Restituisce i valori lungo una linea di tendenza lineare +TRIMMEAN = MEDIA.TRONCATA ## Restituisce la media della parte interna di un insieme di dati +TTEST = TEST.T ## Restituisce la probabilità associata ad un test t di Student +VAR = VAR ## Stima la varianza sulla base di un campione +VARA = VAR.VALORI ## Stima la varianza sulla base di un campione, inclusi i numeri, il testo e i valori logici +VARP = VAR.POP ## Calcola la varianza sulla base dell'intera popolazione +VARPA = VAR.POP.VALORI ## Calcola la deviazione standard sulla base sull'intera popolazione, inclusi i numeri, il testo e i valori logici +WEIBULL = WEIBULL ## Restituisce la distribuzione di Weibull +ZTEST = TEST.Z ## Restituisce il valore di probabilità a una coda per un test z + + +## +## Text functions Funzioni di testo +## +ASC = ASC ## Modifica le lettere inglesi o il katakana a doppio byte all'interno di una stringa di caratteri in caratteri a singolo byte +BAHTTEXT = BAHTTESTO ## Converte un numero in testo, utilizzando il formato valuta ß (baht) +CHAR = CODICE.CARATT ## Restituisce il carattere specificato dal numero di codice +CLEAN = LIBERA ## Elimina dal testo tutti i caratteri che non è possibile stampare +CODE = CODICE ## Restituisce il codice numerico del primo carattere di una stringa di testo +CONCATENATE = CONCATENA ## Unisce diversi elementi di testo in un unico elemento di testo +DOLLAR = VALUTA ## Converte un numero in testo, utilizzando il formato valuta € (euro) +EXACT = IDENTICO ## Verifica se due valori di testo sono uguali +FIND = TROVA ## Rileva un valore di testo all'interno di un altro (distinzione tra maiuscole e minuscole) +FINDB = TROVA.B ## Rileva un valore di testo all'interno di un altro (distinzione tra maiuscole e minuscole) +FIXED = FISSO ## Formatta un numero come testo con un numero fisso di decimali +JIS = ORDINAMENTO.JIS ## Modifica le lettere inglesi o i caratteri katakana a byte singolo all'interno di una stringa di caratteri in caratteri a byte doppio. +LEFT = SINISTRA ## Restituisce il carattere più a sinistra di un valore di testo +LEFTB = SINISTRA.B ## Restituisce il carattere più a sinistra di un valore di testo +LEN = LUNGHEZZA ## Restituisce il numero di caratteri di una stringa di testo +LENB = LUNB ## Restituisce il numero di caratteri di una stringa di testo +LOWER = MINUSC ## Converte il testo in lettere minuscole +MID = MEDIA ## Restituisce un numero specifico di caratteri di una stringa di testo a partire dalla posizione specificata +MIDB = MEDIA.B ## Restituisce un numero specifico di caratteri di una stringa di testo a partire dalla posizione specificata +PHONETIC = FURIGANA ## Estrae i caratteri fonetici (furigana) da una stringa di testo. +PROPER = MAIUSC.INIZ ## Converte in maiuscolo la prima lettera di ogni parola di un valore di testo +REPLACE = RIMPIAZZA ## Sostituisce i caratteri all'interno di un testo +REPLACEB = SOSTITUISCI.B ## Sostituisce i caratteri all'interno di un testo +REPT = RIPETI ## Ripete un testo per un dato numero di volte +RIGHT = DESTRA ## Restituisce il carattere più a destra di un valore di testo +RIGHTB = DESTRA.B ## Restituisce il carattere più a destra di un valore di testo +SEARCH = RICERCA ## Rileva un valore di testo all'interno di un altro (non è sensibile alle maiuscole e minuscole) +SEARCHB = CERCA.B ## Rileva un valore di testo all'interno di un altro (non è sensibile alle maiuscole e minuscole) +SUBSTITUTE = SOSTITUISCI ## Sostituisce il nuovo testo al testo contenuto in una stringa +T = T ## Converte gli argomenti in testo +TEXT = TESTO ## Formatta un numero e lo converte in testo +TRIM = ANNULLA.SPAZI ## Elimina gli spazi dal testo +UPPER = MAIUSC ## Converte il testo in lettere maiuscole +VALUE = VALORE ## Converte un argomento di testo in numero diff --git a/lib/phpexcel/PHPExcel/locale/nl/config b/lib/phpexcel/PHPExcel/locale/nl/config new file mode 100644 index 0000000..00c1b0f --- /dev/null +++ b/lib/phpexcel/PHPExcel/locale/nl/config @@ -0,0 +1,47 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Settings +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## + + +ArgumentSeparator = ; + + +## +## (For future use) +## +currencySymbol = € + + +## +## Excel Error Codes (For future use) +## +NULL = #LEEG! +DIV0 = #DEEL/0! +VALUE = #WAARDE! +REF = #VERW! +NAME = #NAAM? +NUM = #GETAL! +NA = #N/B diff --git a/lib/phpexcel/PHPExcel/locale/nl/functions b/lib/phpexcel/PHPExcel/locale/nl/functions new file mode 100644 index 0000000..6380008 --- /dev/null +++ b/lib/phpexcel/PHPExcel/locale/nl/functions @@ -0,0 +1,438 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Calculation +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## Data in this file derived from http://www.piuha.fi/excel-function-name-translation/ +## +## + + +## +## Add-in and Automation functions Automatiseringsfuncties en functies in invoegtoepassingen +## +GETPIVOTDATA = DRAAITABEL.OPHALEN ## Geeft gegevens uit een draaitabelrapport als resultaat + + +## +## Cube functions Kubusfuncties +## +CUBEKPIMEMBER = KUBUSKPILID ## Retourneert de naam, eigenschap en waarde van een KPI (prestatie-indicator) en geeft de naam en de eigenschap in de cel weer. Een KPI is een meetbare waarde, zoals de maandelijkse brutowinst of de omzet per kwartaal per werknemer, die wordt gebruikt om de prestaties van een organisatie te bewaken +CUBEMEMBER = KUBUSLID ## Retourneert een lid of tupel in een kubushiërarchie. Wordt gebruikt om te controleren of het lid of de tupel in de kubus aanwezig is +CUBEMEMBERPROPERTY = KUBUSLIDEIGENSCHAP ## Retourneert de waarde van een lideigenschap in de kubus. Wordt gebruikt om te controleren of de lidnaam in de kubus bestaat en retourneert de opgegeven eigenschap voor dit lid +CUBERANKEDMEMBER = KUBUSGERANGCHIKTLID ## Retourneert het zoveelste, gerangschikte lid in een set. Wordt gebruikt om een of meer elementen in een set te retourneren, zoals de tien beste verkopers of de tien beste studenten +CUBESET = KUBUSSET ## Definieert een berekende set leden of tupels door een ingestelde expressie naar de kubus op de server te sturen, alwaar de set wordt gemaakt en vervolgens wordt geretourneerd naar Microsoft Office Excel +CUBESETCOUNT = KUBUSSETAANTAL ## Retourneert het aantal onderdelen in een set +CUBEVALUE = KUBUSWAARDE ## Retourneert een samengestelde waarde van een kubus + + +## +## Database functions Databasefuncties +## +DAVERAGE = DBGEMIDDELDE ## Berekent de gemiddelde waarde in geselecteerde databasegegevens +DCOUNT = DBAANTAL ## Telt de cellen met getallen in een database +DCOUNTA = DBAANTALC ## Telt de niet-lege cellen in een database +DGET = DBLEZEN ## Retourneert één record dat voldoet aan de opgegeven criteria uit een database +DMAX = DBMAX ## Retourneert de maximumwaarde in de geselecteerde databasegegevens +DMIN = DBMIN ## Retourneert de minimumwaarde in de geselecteerde databasegegevens +DPRODUCT = DBPRODUCT ## Vermenigvuldigt de waarden in een bepaald veld van de records die voldoen aan de criteria in een database +DSTDEV = DBSTDEV ## Maakt een schatting van de standaarddeviatie op basis van een steekproef uit geselecteerde databasegegevens +DSTDEVP = DBSTDEVP ## Berekent de standaarddeviatie op basis van de volledige populatie van geselecteerde databasegegevens +DSUM = DBSOM ## Telt de getallen uit een kolom records in de database op die voldoen aan de criteria +DVAR = DBVAR ## Maakt een schatting van de variantie op basis van een steekproef uit geselecteerde databasegegevens +DVARP = DBVARP ## Berekent de variantie op basis van de volledige populatie van geselecteerde databasegegevens + + +## +## Date and time functions Datum- en tijdfuncties +## +DATE = DATUM ## Geeft als resultaat het seriële getal van een opgegeven datum +DATEVALUE = DATUMWAARDE ## Converteert een datum in de vorm van tekst naar een serieel getal +DAY = DAG ## Converteert een serieel getal naar een dag van de maand +DAYS360 = DAGEN360 ## Berekent het aantal dagen tussen twee datums op basis van een jaar met 360 dagen +EDATE = ZELFDE.DAG ## Geeft als resultaat het seriële getal van een datum die het opgegeven aantal maanden voor of na de begindatum ligt +EOMONTH = LAATSTE.DAG ## Geeft als resultaat het seriële getal van de laatste dag van de maand voor of na het opgegeven aantal maanden +HOUR = UUR ## Converteert een serieel getal naar uren +MINUTE = MINUUT ## Converteert een serieel naar getal minuten +MONTH = MAAND ## Converteert een serieel getal naar een maand +NETWORKDAYS = NETTO.WERKDAGEN ## Geeft als resultaat het aantal hele werkdagen tussen twee datums +NOW = NU ## Geeft als resultaat het seriële getal van de huidige datum en tijd +SECOND = SECONDE ## Converteert een serieel getal naar seconden +TIME = TIJD ## Geeft als resultaat het seriële getal van een bepaald tijdstip +TIMEVALUE = TIJDWAARDE ## Converteert de tijd in de vorm van tekst naar een serieel getal +TODAY = VANDAAG ## Geeft als resultaat het seriële getal van de huidige datum +WEEKDAY = WEEKDAG ## Converteert een serieel getal naar een weekdag +WEEKNUM = WEEKNUMMER ## Converteert een serieel getal naar een weeknummer +WORKDAY = WERKDAG ## Geeft als resultaat het seriële getal van de datum voor of na een bepaald aantal werkdagen +YEAR = JAAR ## Converteert een serieel getal naar een jaar +YEARFRAC = JAAR.DEEL ## Geeft als resultaat het gedeelte van het jaar, uitgedrukt in het aantal hele dagen tussen begindatum en einddatum + + +## +## Engineering functions Technische functies +## +BESSELI = BESSEL.Y ## Geeft als resultaat de gewijzigde Bessel-functie In(x) +BESSELJ = BESSEL.J ## Geeft als resultaat de Bessel-functie Jn(x) +BESSELK = BESSEL.K ## Geeft als resultaat de gewijzigde Bessel-functie Kn(x) +BESSELY = BESSEL.Y ## Geeft als resultaat de gewijzigde Bessel-functie Yn(x) +BIN2DEC = BIN.N.DEC ## Converteert een binair getal naar een decimaal getal +BIN2HEX = BIN.N.HEX ## Converteert een binair getal naar een hexadecimaal getal +BIN2OCT = BIN.N.OCT ## Converteert een binair getal naar een octaal getal +COMPLEX = COMPLEX ## Converteert reële en imaginaire coëfficiënten naar een complex getal +CONVERT = CONVERTEREN ## Converteert een getal in de ene maateenheid naar een getal in een andere maateenheid +DEC2BIN = DEC.N.BIN ## Converteert een decimaal getal naar een binair getal +DEC2HEX = DEC.N.HEX ## Converteert een decimaal getal naar een hexadecimaal getal +DEC2OCT = DEC.N.OCT ## Converteert een decimaal getal naar een octaal getal +DELTA = DELTA ## Test of twee waarden gelijk zijn +ERF = FOUTFUNCTIE ## Geeft als resultaat de foutfunctie +ERFC = FOUT.COMPLEMENT ## Geeft als resultaat de complementaire foutfunctie +GESTEP = GROTER.DAN ## Test of een getal groter is dan de drempelwaarde +HEX2BIN = HEX.N.BIN ## Converteert een hexadecimaal getal naar een binair getal +HEX2DEC = HEX.N.DEC ## Converteert een hexadecimaal getal naar een decimaal getal +HEX2OCT = HEX.N.OCT ## Converteert een hexadecimaal getal naar een octaal getal +IMABS = C.ABS ## Geeft als resultaat de absolute waarde (modulus) van een complex getal +IMAGINARY = C.IM.DEEL ## Geeft als resultaat de imaginaire coëfficiënt van een complex getal +IMARGUMENT = C.ARGUMENT ## Geeft als resultaat het argument thèta, een hoek uitgedrukt in radialen +IMCONJUGATE = C.TOEGEVOEGD ## Geeft als resultaat het complexe toegevoegde getal van een complex getal +IMCOS = C.COS ## Geeft als resultaat de cosinus van een complex getal +IMDIV = C.QUOTIENT ## Geeft als resultaat het quotiënt van twee complexe getallen +IMEXP = C.EXP ## Geeft als resultaat de exponent van een complex getal +IMLN = C.LN ## Geeft als resultaat de natuurlijke logaritme van een complex getal +IMLOG10 = C.LOG10 ## Geeft als resultaat de logaritme met grondtal 10 van een complex getal +IMLOG2 = C.LOG2 ## Geeft als resultaat de logaritme met grondtal 2 van een complex getal +IMPOWER = C.MACHT ## Geeft als resultaat een complex getal dat is verheven tot de macht van een geheel getal +IMPRODUCT = C.PRODUCT ## Geeft als resultaat het product van complexe getallen +IMREAL = C.REEEL.DEEL ## Geeft als resultaat de reële coëfficiënt van een complex getal +IMSIN = C.SIN ## Geeft als resultaat de sinus van een complex getal +IMSQRT = C.WORTEL ## Geeft als resultaat de vierkantswortel van een complex getal +IMSUB = C.VERSCHIL ## Geeft als resultaat het verschil tussen twee complexe getallen +IMSUM = C.SOM ## Geeft als resultaat de som van complexe getallen +OCT2BIN = OCT.N.BIN ## Converteert een octaal getal naar een binair getal +OCT2DEC = OCT.N.DEC ## Converteert een octaal getal naar een decimaal getal +OCT2HEX = OCT.N.HEX ## Converteert een octaal getal naar een hexadecimaal getal + + +## +## Financial functions Financiële functies +## +ACCRINT = SAMENG.RENTE ## Berekent de opgelopen rente voor een waardepapier waarvan de rente periodiek wordt uitgekeerd +ACCRINTM = SAMENG.RENTE.V ## Berekent de opgelopen rente voor een waardepapier waarvan de rente op de vervaldatum wordt uitgekeerd +AMORDEGRC = AMORDEGRC ## Geeft als resultaat de afschrijving voor elke boekingsperiode door een afschrijvingscoëfficiënt toe te passen +AMORLINC = AMORLINC ## Berekent de afschrijving voor elke boekingsperiode +COUPDAYBS = COUP.DAGEN.BB ## Berekent het aantal dagen vanaf het begin van de coupontermijn tot de stortingsdatum +COUPDAYS = COUP.DAGEN ## Geeft als resultaat het aantal dagen in de coupontermijn waarin de stortingsdatum valt +COUPDAYSNC = COUP.DAGEN.VV ## Geeft als resultaat het aantal dagen vanaf de stortingsdatum tot de volgende couponvervaldatum +COUPNCD = COUP.DATUM.NB ## Geeft als resultaat de volgende coupondatum na de stortingsdatum +COUPNUM = COUP.AANTAL ## Geeft als resultaat het aantal coupons dat nog moet worden uitbetaald tussen de stortingsdatum en de vervaldatum +COUPPCD = COUP.DATUM.VB ## Geeft als resultaat de vorige couponvervaldatum vóór de stortingsdatum +CUMIPMT = CUM.RENTE ## Geeft als resultaat de cumulatieve rente die tussen twee termijnen is uitgekeerd +CUMPRINC = CUM.HOOFDSOM ## Geeft als resultaat de cumulatieve hoofdsom van een lening die tussen twee termijnen is terugbetaald +DB = DB ## Geeft als resultaat de afschrijving van activa voor een bepaalde periode met behulp van de 'fixed declining balance'-methode +DDB = DDB ## Geeft als resultaat de afschrijving van activa over een bepaalde termijn met behulp van de 'double declining balance'-methode of een andere methode die u opgeeft +DISC = DISCONTO ## Geeft als resultaat het discontopercentage voor een waardepapier +DOLLARDE = EURO.DE ## Converteert een prijs in euro's, uitgedrukt in een breuk, naar een prijs in euro's, uitgedrukt in een decimaal getal +DOLLARFR = EURO.BR ## Converteert een prijs in euro's, uitgedrukt in een decimaal getal, naar een prijs in euro's, uitgedrukt in een breuk +DURATION = DUUR ## Geeft als resultaat de gewogen gemiddelde looptijd voor een waardepapier met periodieke rentebetalingen +EFFECT = EFFECT.RENTE ## Geeft als resultaat het effectieve jaarlijkse rentepercentage +FV = TW ## Geeft als resultaat de toekomstige waarde van een investering +FVSCHEDULE = TOEK.WAARDE2 ## Geeft als resultaat de toekomstige waarde van een bepaalde hoofdsom na het toepassen van een reeks samengestelde rentepercentages +INTRATE = RENTEPERCENTAGE ## Geeft als resultaat het rentepercentage voor een volgestort waardepapier +IPMT = IBET ## Geeft als resultaat de te betalen rente voor een investering over een bepaalde termijn +IRR = IR ## Geeft als resultaat de interne rentabiliteit voor een reeks cashflows +ISPMT = ISBET ## Geeft als resultaat de rente die is betaald tijdens een bepaalde termijn van een investering +MDURATION = AANG.DUUR ## Geeft als resultaat de aangepaste Macauley-looptijd voor een waardepapier, aangenomen dat de nominale waarde € 100 bedraagt +MIRR = GIR ## Geeft als resultaat de interne rentabiliteit voor een serie cashflows, waarbij voor betalingen een ander rentepercentage geldt dan voor inkomsten +NOMINAL = NOMINALE.RENTE ## Geeft als resultaat het nominale jaarlijkse rentepercentage +NPER = NPER ## Geeft als resultaat het aantal termijnen van een investering +NPV = NHW ## Geeft als resultaat de netto huidige waarde van een investering op basis van een reeks periodieke cashflows en een discontopercentage +ODDFPRICE = AFW.ET.PRIJS ## Geeft als resultaat de prijs per € 100 nominale waarde voor een waardepapier met een afwijkende eerste termijn +ODDFYIELD = AFW.ET.REND ## Geeft als resultaat het rendement voor een waardepapier met een afwijkende eerste termijn +ODDLPRICE = AFW.LT.PRIJS ## Geeft als resultaat de prijs per € 100 nominale waarde voor een waardepapier met een afwijkende laatste termijn +ODDLYIELD = AFW.LT.REND ## Geeft als resultaat het rendement voor een waardepapier met een afwijkende laatste termijn +PMT = BET ## Geeft als resultaat de periodieke betaling voor een annuïteit +PPMT = PBET ## Geeft als resultaat de afbetaling op de hoofdsom voor een bepaalde termijn +PRICE = PRIJS.NOM ## Geeft als resultaat de prijs per € 100 nominale waarde voor een waardepapier waarvan de rente periodiek wordt uitgekeerd +PRICEDISC = PRIJS.DISCONTO ## Geeft als resultaat de prijs per € 100 nominale waarde voor een verdisconteerd waardepapier +PRICEMAT = PRIJS.VERVALDAG ## Geeft als resultaat de prijs per € 100 nominale waarde voor een waardepapier waarvan de rente wordt uitgekeerd op de vervaldatum +PV = HW ## Geeft als resultaat de huidige waarde van een investering +RATE = RENTE ## Geeft als resultaat het periodieke rentepercentage voor een annuïteit +RECEIVED = OPBRENGST ## Geeft als resultaat het bedrag dat op de vervaldatum wordt uitgekeerd voor een volgestort waardepapier +SLN = LIN.AFSCHR ## Geeft als resultaat de lineaire afschrijving van activa over één termijn +SYD = SYD ## Geeft als resultaat de afschrijving van activa over een bepaalde termijn met behulp van de 'Sum-Of-Years-Digits'-methode +TBILLEQ = SCHATK.OBL ## Geeft als resultaat het rendement op schatkistpapier, dat op dezelfde manier wordt berekend als het rendement op obligaties +TBILLPRICE = SCHATK.PRIJS ## Bepaalt de prijs per € 100 nominale waarde voor schatkistpapier +TBILLYIELD = SCHATK.REND ## Berekent het rendement voor schatkistpapier +VDB = VDB ## Geeft als resultaat de afschrijving van activa over een gehele of gedeeltelijke termijn met behulp van de 'declining balance'-methode +XIRR = IR.SCHEMA ## Berekent de interne rentabiliteit voor een betalingsschema van cashflows +XNPV = NHW2 ## Berekent de huidige nettowaarde voor een betalingsschema van cashflows +YIELD = RENDEMENT ## Geeft als resultaat het rendement voor een waardepapier waarvan de rente periodiek wordt uitgekeerd +YIELDDISC = REND.DISCONTO ## Geeft als resultaat het jaarlijkse rendement voor een verdisconteerd waardepapier, bijvoorbeeld schatkistpapier +YIELDMAT = REND.VERVAL ## Geeft als resultaat het jaarlijkse rendement voor een waardepapier waarvan de rente wordt uitgekeerd op de vervaldatum + + +## +## Information functions Informatiefuncties +## +CELL = CEL ## Geeft als resultaat informatie over de opmaak, locatie of inhoud van een cel +ERROR.TYPE = TYPE.FOUT ## Geeft als resultaat een getal dat overeenkomt met een van de foutwaarden van Microsoft Excel +INFO = INFO ## Geeft als resultaat informatie over de huidige besturingsomgeving +ISBLANK = ISLEEG ## Geeft als resultaat WAAR als de waarde leeg is +ISERR = ISFOUT2 ## Geeft als resultaat WAAR als de waarde een foutwaarde is, met uitzondering van #N/B +ISERROR = ISFOUT ## Geeft als resultaat WAAR als de waarde een foutwaarde is +ISEVEN = IS.EVEN ## Geeft als resultaat WAAR als het getal even is +ISLOGICAL = ISLOGISCH ## Geeft als resultaat WAAR als de waarde een logische waarde is +ISNA = ISNB ## Geeft als resultaat WAAR als de waarde de foutwaarde #N/B is +ISNONTEXT = ISGEENTEKST ## Geeft als resultaat WAAR als de waarde geen tekst is +ISNUMBER = ISGETAL ## Geeft als resultaat WAAR als de waarde een getal is +ISODD = IS.ONEVEN ## Geeft als resultaat WAAR als het getal oneven is +ISREF = ISVERWIJZING ## Geeft als resultaat WAAR als de waarde een verwijzing is +ISTEXT = ISTEKST ## Geeft als resultaat WAAR als de waarde tekst is +N = N ## Geeft als resultaat een waarde die is geconverteerd naar een getal +NA = NB ## Geeft als resultaat de foutwaarde #N/B +TYPE = TYPE ## Geeft als resultaat een getal dat het gegevenstype van een waarde aangeeft + + +## +## Logical functions Logische functies +## +AND = EN ## Geeft als resultaat WAAR als alle argumenten WAAR zijn +FALSE = ONWAAR ## Geeft als resultaat de logische waarde ONWAAR +IF = ALS ## Geeft een logische test aan +IFERROR = ALS.FOUT ## Retourneert een waarde die u opgeeft als een formule een fout oplevert, anders wordt het resultaat van de formule geretourneerd +NOT = NIET ## Keert de logische waarde van het argument om +OR = OF ## Geeft als resultaat WAAR als minimaal een van de argumenten WAAR is +TRUE = WAAR ## Geeft als resultaat de logische waarde WAAR + + +## +## Lookup and reference functions Zoek- en verwijzingsfuncties +## +ADDRESS = ADRES ## Geeft als resultaat een verwijzing, in de vorm van tekst, naar één bepaalde cel in een werkblad +AREAS = BEREIKEN ## Geeft als resultaat het aantal bereiken in een verwijzing +CHOOSE = KIEZEN ## Kiest een waarde uit een lijst met waarden +COLUMN = KOLOM ## Geeft als resultaat het kolomnummer van een verwijzing +COLUMNS = KOLOMMEN ## Geeft als resultaat het aantal kolommen in een verwijzing +HLOOKUP = HORIZ.ZOEKEN ## Zoekt in de bovenste rij van een matrix naar een bepaalde waarde en geeft als resultaat de gevonden waarde in de opgegeven cel +HYPERLINK = HYPERLINK ## Maakt een snelkoppeling of een sprong waarmee een document wordt geopend dat is opgeslagen op een netwerkserver, een intranet of op internet +INDEX = INDEX ## Kiest met een index een waarde uit een verwijzing of een matrix +INDIRECT = INDIRECT ## Geeft als resultaat een verwijzing die wordt aangegeven met een tekstwaarde +LOOKUP = ZOEKEN ## Zoekt naar bepaalde waarden in een vector of een matrix +MATCH = VERGELIJKEN ## Zoekt naar bepaalde waarden in een verwijzing of een matrix +OFFSET = VERSCHUIVING ## Geeft als resultaat een nieuwe verwijzing die is verschoven ten opzichte van een bepaalde verwijzing +ROW = RIJ ## Geeft als resultaat het rijnummer van een verwijzing +ROWS = RIJEN ## Geeft als resultaat het aantal rijen in een verwijzing +RTD = RTG ## Haalt realtimegegevens op uit een programma dat COM-automatisering (automatisering: een methode waarmee de ene toepassing objecten van een andere toepassing of ontwikkelprogramma kan besturen. Automatisering werd vroeger OLE-automatisering genoemd. Automatisering is een industrienorm die deel uitmaakt van het Component Object Model (COM).) ondersteunt +TRANSPOSE = TRANSPONEREN ## Geeft als resultaat de getransponeerde van een matrix +VLOOKUP = VERT.ZOEKEN ## Zoekt in de meest linkse kolom van een matrix naar een bepaalde waarde en geeft als resultaat de waarde in de opgegeven cel + + +## +## Math and trigonometry functions Wiskundige en trigonometrische functies +## +ABS = ABS ## Geeft als resultaat de absolute waarde van een getal +ACOS = BOOGCOS ## Geeft als resultaat de boogcosinus van een getal +ACOSH = BOOGCOSH ## Geeft als resultaat de inverse cosinus hyperbolicus van een getal +ASIN = BOOGSIN ## Geeft als resultaat de boogsinus van een getal +ASINH = BOOGSINH ## Geeft als resultaat de inverse sinus hyperbolicus van een getal +ATAN = BOOGTAN ## Geeft als resultaat de boogtangens van een getal +ATAN2 = BOOGTAN2 ## Geeft als resultaat de boogtangens van de x- en y-coördinaten +ATANH = BOOGTANH ## Geeft als resultaat de inverse tangens hyperbolicus van een getal +CEILING = AFRONDEN.BOVEN ## Rondt de absolute waarde van een getal naar boven af op het dichtstbijzijnde gehele getal of het dichtstbijzijnde significante veelvoud +COMBIN = COMBINATIES ## Geeft als resultaat het aantal combinaties voor een bepaald aantal objecten +COS = COS ## Geeft als resultaat de cosinus van een getal +COSH = COSH ## Geeft als resultaat de cosinus hyperbolicus van een getal +DEGREES = GRADEN ## Converteert radialen naar graden +EVEN = EVEN ## Rondt het getal af op het dichtstbijzijnde gehele even getal +EXP = EXP ## Verheft e tot de macht van een bepaald getal +FACT = FACULTEIT ## Geeft als resultaat de faculteit van een getal +FACTDOUBLE = DUBBELE.FACULTEIT ## Geeft als resultaat de dubbele faculteit van een getal +FLOOR = AFRONDEN.BENEDEN ## Rondt de absolute waarde van een getal naar beneden af +GCD = GGD ## Geeft als resultaat de grootste gemene deler +INT = INTEGER ## Rondt een getal naar beneden af op het dichtstbijzijnde gehele getal +LCM = KGV ## Geeft als resultaat het kleinste gemene veelvoud +LN = LN ## Geeft als resultaat de natuurlijke logaritme van een getal +LOG = LOG ## Geeft als resultaat de logaritme met het opgegeven grondtal van een getal +LOG10 = LOG10 ## Geeft als resultaat de logaritme met grondtal 10 van een getal +MDETERM = DETERMINANTMAT ## Geeft als resultaat de determinant van een matrix +MINVERSE = INVERSEMAT ## Geeft als resultaat de inverse van een matrix +MMULT = PRODUCTMAT ## Geeft als resultaat het product van twee matrices +MOD = REST ## Geeft als resultaat het restgetal van een deling +MROUND = AFRONDEN.N.VEELVOUD ## Geeft als resultaat een getal afgerond op het gewenste veelvoud +MULTINOMIAL = MULTINOMIAAL ## Geeft als resultaat de multinomiaalcoëfficiënt van een reeks getallen +ODD = ONEVEN ## Rondt de absolute waarde van het getal naar boven af op het dichtstbijzijnde gehele oneven getal +PI = PI ## Geeft als resultaat de waarde van pi +POWER = MACHT ## Verheft een getal tot een macht +PRODUCT = PRODUCT ## Vermenigvuldigt de argumenten met elkaar +QUOTIENT = QUOTIENT ## Geeft als resultaat de uitkomst van een deling als geheel getal +RADIANS = RADIALEN ## Converteert graden naar radialen +RAND = ASELECT ## Geeft als resultaat een willekeurig getal tussen 0 en 1 +RANDBETWEEN = ASELECTTUSSEN ## Geeft een willekeurig getal tussen de getallen die u hebt opgegeven +ROMAN = ROMEINS ## Converteert een Arabisch getal naar een Romeins getal en geeft het resultaat weer in de vorm van tekst +ROUND = AFRONDEN ## Rondt een getal af op het opgegeven aantal decimalen +ROUNDDOWN = AFRONDEN.NAAR.BENEDEN ## Rondt de absolute waarde van een getal naar beneden af +ROUNDUP = AFRONDEN.NAAR.BOVEN ## Rondt de absolute waarde van een getal naar boven af +SERIESSUM = SOM.MACHTREEKS ## Geeft als resultaat de som van een machtreeks die is gebaseerd op de formule +SIGN = POS.NEG ## Geeft als resultaat het teken van een getal +SIN = SIN ## Geeft als resultaat de sinus van de opgegeven hoek +SINH = SINH ## Geeft als resultaat de sinus hyperbolicus van een getal +SQRT = WORTEL ## Geeft als resultaat de positieve vierkantswortel van een getal +SQRTPI = WORTEL.PI ## Geeft als resultaat de vierkantswortel van (getal * pi) +SUBTOTAL = SUBTOTAAL ## Geeft als resultaat een subtotaal voor een bereik +SUM = SOM ## Telt de argumenten op +SUMIF = SOM.ALS ## Telt de getallen bij elkaar op die voldoen aan een bepaald criterium +SUMIFS = SOMMEN.ALS ## Telt de cellen in een bereik op die aan meerdere criteria voldoen +SUMPRODUCT = SOMPRODUCT ## Geeft als resultaat de som van de producten van de corresponderende matrixelementen +SUMSQ = KWADRATENSOM ## Geeft als resultaat de som van de kwadraten van de argumenten +SUMX2MY2 = SOM.X2MINY2 ## Geeft als resultaat de som van het verschil tussen de kwadraten van corresponderende waarden in twee matrices +SUMX2PY2 = SOM.X2PLUSY2 ## Geeft als resultaat de som van de kwadratensom van corresponderende waarden in twee matrices +SUMXMY2 = SOM.XMINY.2 ## Geeft als resultaat de som van de kwadraten van de verschillen tussen de corresponderende waarden in twee matrices +TAN = TAN ## Geeft als resultaat de tangens van een getal +TANH = TANH ## Geeft als resultaat de tangens hyperbolicus van een getal +TRUNC = GEHEEL ## Kapt een getal af tot een geheel getal + + +## +## Statistical functions Statistische functies +## +AVEDEV = GEM.DEVIATIE ## Geeft als resultaat het gemiddelde van de absolute deviaties van gegevenspunten ten opzichte van hun gemiddelde waarde +AVERAGE = GEMIDDELDE ## Geeft als resultaat het gemiddelde van de argumenten +AVERAGEA = GEMIDDELDEA ## Geeft als resultaat het gemiddelde van de argumenten, inclusief getallen, tekst en logische waarden +AVERAGEIF = GEMIDDELDE.ALS ## Geeft het gemiddelde (rekenkundig gemiddelde) als resultaat van alle cellen in een bereik die voldoen aan de opgegeven criteria +AVERAGEIFS = GEMIDDELDEN.ALS ## Geeft het gemiddelde (rekenkundig gemiddelde) als resultaat van alle cellen die aan meerdere criteria voldoen +BETADIST = BETA.VERD ## Geeft als resultaat de cumulatieve bèta-verdelingsfunctie +BETAINV = BETA.INV ## Geeft als resultaat de inverse van de cumulatieve verdelingsfunctie voor een gegeven bèta-verdeling +BINOMDIST = BINOMIALE.VERD ## Geeft als resultaat de binomiale verdeling +CHIDIST = CHI.KWADRAAT ## Geeft als resultaat de eenzijdige kans van de chi-kwadraatverdeling +CHIINV = CHI.KWADRAAT.INV ## Geeft als resultaat de inverse van een eenzijdige kans van de chi-kwadraatverdeling +CHITEST = CHI.TOETS ## Geeft als resultaat de onafhankelijkheidstoets +CONFIDENCE = BETROUWBAARHEID ## Geeft als resultaat het betrouwbaarheidsinterval van een gemiddelde waarde voor de elementen van een populatie +CORREL = CORRELATIE ## Geeft als resultaat de correlatiecoëfficiënt van twee gegevensverzamelingen +COUNT = AANTAL ## Telt het aantal getallen in de argumentenlijst +COUNTA = AANTALARG ## Telt het aantal waarden in de argumentenlijst +COUNTBLANK = AANTAL.LEGE.CELLEN ## Telt het aantal lege cellen in een bereik +COUNTIF = AANTAL.ALS ## Telt in een bereik het aantal cellen die voldoen aan een bepaald criterium +COUNTIFS = AANTALLEN.ALS ## Telt in een bereik het aantal cellen die voldoen aan meerdere criteria +COVAR = COVARIANTIE ## Geeft als resultaat de covariantie, het gemiddelde van de producten van de gepaarde deviaties +CRITBINOM = CRIT.BINOM ## Geeft als resultaat de kleinste waarde waarvoor de binomiale verdeling kleiner is dan of gelijk is aan het criterium +DEVSQ = DEV.KWAD ## Geeft als resultaat de som van de deviaties in het kwadraat +EXPONDIST = EXPON.VERD ## Geeft als resultaat de exponentiële verdeling +FDIST = F.VERDELING ## Geeft als resultaat de F-verdeling +FINV = F.INVERSE ## Geeft als resultaat de inverse van de F-verdeling +FISHER = FISHER ## Geeft als resultaat de Fisher-transformatie +FISHERINV = FISHER.INV ## Geeft als resultaat de inverse van de Fisher-transformatie +FORECAST = VOORSPELLEN ## Geeft als resultaat een waarde op basis van een lineaire trend +FREQUENCY = FREQUENTIE ## Geeft als resultaat een frequentieverdeling in de vorm van een verticale matrix +FTEST = F.TOETS ## Geeft als resultaat een F-toets +GAMMADIST = GAMMA.VERD ## Geeft als resultaat de gamma-verdeling +GAMMAINV = GAMMA.INV ## Geeft als resultaat de inverse van de cumulatieve gamma-verdeling +GAMMALN = GAMMA.LN ## Geeft als resultaat de natuurlijke logaritme van de gamma-functie, G(x) +GEOMEAN = MEETK.GEM ## Geeft als resultaat het meetkundige gemiddelde +GROWTH = GROEI ## Geeft als resultaat de waarden voor een exponentiële trend +HARMEAN = HARM.GEM ## Geeft als resultaat het harmonische gemiddelde +HYPGEOMDIST = HYPERGEO.VERD ## Geeft als resultaat de hypergeometrische verdeling +INTERCEPT = SNIJPUNT ## Geeft als resultaat het snijpunt van de lineaire regressielijn met de y-as +KURT = KURTOSIS ## Geeft als resultaat de kurtosis van een gegevensverzameling +LARGE = GROOTSTE ## Geeft als resultaat de op k-1 na grootste waarde in een gegevensverzameling +LINEST = LIJNSCH ## Geeft als resultaat de parameters van een lineaire trend +LOGEST = LOGSCH ## Geeft als resultaat de parameters van een exponentiële trend +LOGINV = LOG.NORM.INV ## Geeft als resultaat de inverse van de logaritmische normale verdeling +LOGNORMDIST = LOG.NORM.VERD ## Geeft als resultaat de cumulatieve logaritmische normale verdeling +MAX = MAX ## Geeft als resultaat de maximumwaarde in een lijst met argumenten +MAXA = MAXA ## Geeft als resultaat de maximumwaarde in een lijst met argumenten, inclusief getallen, tekst en logische waarden +MEDIAN = MEDIAAN ## Geeft als resultaat de mediaan van de opgegeven getallen +MIN = MIN ## Geeft als resultaat de minimumwaarde in een lijst met argumenten +MINA = MINA ## Geeft als resultaat de minimumwaarde in een lijst met argumenten, inclusief getallen, tekst en logische waarden +MODE = MODUS ## Geeft als resultaat de meest voorkomende waarde in een gegevensverzameling +NEGBINOMDIST = NEG.BINOM.VERD ## Geeft als resultaat de negatieve binomiaalverdeling +NORMDIST = NORM.VERD ## Geeft als resultaat de cumulatieve normale verdeling +NORMINV = NORM.INV ## Geeft als resultaat de inverse van de cumulatieve standaardnormale verdeling +NORMSDIST = STAND.NORM.VERD ## Geeft als resultaat de cumulatieve standaardnormale verdeling +NORMSINV = STAND.NORM.INV ## Geeft als resultaat de inverse van de cumulatieve normale verdeling +PEARSON = PEARSON ## Geeft als resultaat de correlatiecoëfficiënt van Pearson +PERCENTILE = PERCENTIEL ## Geeft als resultaat het k-de percentiel van waarden in een bereik +PERCENTRANK = PERCENT.RANG ## Geeft als resultaat de positie, in procenten uitgedrukt, van een waarde in de rangorde van een gegevensverzameling +PERMUT = PERMUTATIES ## Geeft als resultaat het aantal permutaties voor een gegeven aantal objecten +POISSON = POISSON ## Geeft als resultaat de Poisson-verdeling +PROB = KANS ## Geeft als resultaat de kans dat waarden zich tussen twee grenzen bevinden +QUARTILE = KWARTIEL ## Geeft als resultaat het kwartiel van een gegevensverzameling +RANK = RANG ## Geeft als resultaat het rangnummer van een getal in een lijst getallen +RSQ = R.KWADRAAT ## Geeft als resultaat het kwadraat van de Pearson-correlatiecoëfficiënt +SKEW = SCHEEFHEID ## Geeft als resultaat de mate van asymmetrie van een verdeling +SLOPE = RICHTING ## Geeft als resultaat de richtingscoëfficiënt van een lineaire regressielijn +SMALL = KLEINSTE ## Geeft als resultaat de op k-1 na kleinste waarde in een gegevensverzameling +STANDARDIZE = NORMALISEREN ## Geeft als resultaat een genormaliseerde waarde +STDEV = STDEV ## Maakt een schatting van de standaarddeviatie op basis van een steekproef +STDEVA = STDEVA ## Maakt een schatting van de standaarddeviatie op basis van een steekproef, inclusief getallen, tekst en logische waarden +STDEVP = STDEVP ## Berekent de standaarddeviatie op basis van de volledige populatie +STDEVPA = STDEVPA ## Berekent de standaarddeviatie op basis van de volledige populatie, inclusief getallen, tekst en logische waarden +STEYX = STAND.FOUT.YX ## Geeft als resultaat de standaardfout in de voorspelde y-waarde voor elke x in een regressie +TDIST = T.VERD ## Geeft als resultaat de Student T-verdeling +TINV = T.INV ## Geeft als resultaat de inverse van de Student T-verdeling +TREND = TREND ## Geeft als resultaat de waarden voor een lineaire trend +TRIMMEAN = GETRIMD.GEM ## Geeft als resultaat het gemiddelde van waarden in een gegevensverzameling +TTEST = T.TOETS ## Geeft als resultaat de kans met behulp van de Student T-toets +VAR = VAR ## Maakt een schatting van de variantie op basis van een steekproef +VARA = VARA ## Maakt een schatting van de variantie op basis van een steekproef, inclusief getallen, tekst en logische waarden +VARP = VARP ## Berekent de variantie op basis van de volledige populatie +VARPA = VARPA ## Berekent de standaarddeviatie op basis van de volledige populatie, inclusief getallen, tekst en logische waarden +WEIBULL = WEIBULL ## Geeft als resultaat de Weibull-verdeling +ZTEST = Z.TOETS ## Geeft als resultaat de eenzijdige kanswaarde van een Z-toets + + +## +## Text functions Tekstfuncties +## +ASC = ASC ## Wijzigt Nederlandse letters of katakanatekens over de volle breedte (dubbel-bytetekens) binnen een tekenreeks in tekens over de halve breedte (enkel-bytetekens) +BAHTTEXT = BAHT.TEKST ## Converteert een getal naar tekst met de valutanotatie ß (baht) +CHAR = TEKEN ## Geeft als resultaat het teken dat hoort bij de opgegeven code +CLEAN = WISSEN.CONTROL ## Verwijdert alle niet-afdrukbare tekens uit een tekst +CODE = CODE ## Geeft als resultaat de numerieke code voor het eerste teken in een tekenreeks +CONCATENATE = TEKST.SAMENVOEGEN ## Voegt verschillende tekstfragmenten samen tot één tekstfragment +DOLLAR = EURO ## Converteert een getal naar tekst met de valutanotatie € (euro) +EXACT = GELIJK ## Controleert of twee tekenreeksen identiek zijn +FIND = VIND.ALLES ## Zoekt een bepaalde tekenreeks in een tekst (waarbij onderscheid wordt gemaakt tussen hoofdletters en kleine letters) +FINDB = VIND.ALLES.B ## Zoekt een bepaalde tekenreeks in een tekst (waarbij onderscheid wordt gemaakt tussen hoofdletters en kleine letters) +FIXED = VAST ## Maakt een getal als tekst met een vast aantal decimalen op +JIS = JIS ## Wijzigt Nederlandse letters of katakanatekens over de halve breedte (enkel-bytetekens) binnen een tekenreeks in tekens over de volle breedte (dubbel-bytetekens) +LEFT = LINKS ## Geeft als resultaat de meest linkse tekens in een tekenreeks +LEFTB = LINKSB ## Geeft als resultaat de meest linkse tekens in een tekenreeks +LEN = LENGTE ## Geeft als resultaat het aantal tekens in een tekenreeks +LENB = LENGTEB ## Geeft als resultaat het aantal tekens in een tekenreeks +LOWER = KLEINE.LETTERS ## Zet tekst om in kleine letters +MID = MIDDEN ## Geeft als resultaat een bepaald aantal tekens van een tekenreeks vanaf de positie die u opgeeft +MIDB = DEELB ## Geeft als resultaat een bepaald aantal tekens van een tekenreeks vanaf de positie die u opgeeft +PHONETIC = FONETISCH ## Haalt de fonetische tekens (furigana) uit een tekenreeks op +PROPER = BEGINLETTERS ## Zet de eerste letter van elk woord in een tekst om in een hoofdletter +REPLACE = VERVANG ## Vervangt tekens binnen een tekst +REPLACEB = VERVANGENB ## Vervangt tekens binnen een tekst +REPT = HERHALING ## Herhaalt een tekst een aantal malen +RIGHT = RECHTS ## Geeft als resultaat de meest rechtse tekens in een tekenreeks +RIGHTB = RECHTSB ## Geeft als resultaat de meest rechtse tekens in een tekenreeks +SEARCH = VIND.SPEC ## Zoekt een bepaalde tekenreeks in een tekst (waarbij geen onderscheid wordt gemaakt tussen hoofdletters en kleine letters) +SEARCHB = VIND.SPEC.B ## Zoekt een bepaalde tekenreeks in een tekst (waarbij geen onderscheid wordt gemaakt tussen hoofdletters en kleine letters) +SUBSTITUTE = SUBSTITUEREN ## Vervangt oude tekst door nieuwe tekst in een tekenreeks +T = T ## Converteert de argumenten naar tekst +TEXT = TEKST ## Maakt een getal op en converteert het getal naar tekst +TRIM = SPATIES.WISSEN ## Verwijdert de spaties uit een tekst +UPPER = HOOFDLETTERS ## Zet tekst om in hoofdletters +VALUE = WAARDE ## Converteert tekst naar een getal diff --git a/lib/phpexcel/PHPExcel/locale/no/config b/lib/phpexcel/PHPExcel/locale/no/config new file mode 100644 index 0000000..5bf96a1 --- /dev/null +++ b/lib/phpexcel/PHPExcel/locale/no/config @@ -0,0 +1,47 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Settings +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## + + +ArgumentSeparator = ; + + +## +## (For future use) +## +currencySymbol = kr + + +## +## Excel Error Codes (For future use) +## +NULL = #NULL! +DIV0 = #DIV/0! +VALUE = #VERDI! +REF = #REF! +NAME = #NAVN? +NUM = #NUM! +NA = #I/T diff --git a/lib/phpexcel/PHPExcel/locale/no/functions b/lib/phpexcel/PHPExcel/locale/no/functions new file mode 100644 index 0000000..917c7f7 --- /dev/null +++ b/lib/phpexcel/PHPExcel/locale/no/functions @@ -0,0 +1,438 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Calculation +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## Data in this file derived from http://www.piuha.fi/excel-function-name-translation/ +## +## + + +## +## Add-in and Automation functions Funksjonene Tillegg og Automatisering +## +GETPIVOTDATA = HENTPIVOTDATA ## Returnerer data som er lagret i en pivottabellrapport + + +## +## Cube functions Kubefunksjoner +## +CUBEKPIMEMBER = KUBEKPIMEDLEM ## Returnerer navnet, egenskapen og målet for en viktig ytelsesindikator (KPI), og viser navnet og egenskapen i cellen. En KPI er en målbar enhet, for eksempel månedlig bruttoinntjening eller kvartalsvis inntjening per ansatt, og brukes til å overvåke ytelsen i en organisasjon. +CUBEMEMBER = KUBEMEDLEM ## Returnerer et medlem eller en tuppel i et kubehierarki. Brukes til å validere at medlemmet eller tuppelen finnes i kuben. +CUBEMEMBERPROPERTY = KUBEMEDLEMEGENSKAP ## Returnerer verdien til en medlemsegenskap i kuben. Brukes til å validere at et medlemsnavn finnes i kuben, og til å returnere den angitte egenskapen for dette medlemmet. +CUBERANKEDMEMBER = KUBERANGERTMEDLEM ## Returnerer det n-te, eller rangerte, medlemmet i et sett. Brukes til å returnere ett eller flere elementer i et sett, for eksempel de 10 beste studentene. +CUBESET = KUBESETT ## Definerer et beregnet sett av medlemmer eller tuppeler ved å sende et settuttrykk til kuben på serveren, noe som oppretter settet og deretter returnerer dette settet til Microsoft Office Excel. +CUBESETCOUNT = KUBESETTANTALL ## Returnerer antallet elementer i et sett. +CUBEVALUE = KUBEVERDI ## Returnerer en aggregert verdi fra en kube. + + +## +## Database functions Databasefunksjoner +## +DAVERAGE = DGJENNOMSNITT ## Returnerer gjennomsnittet av merkede databaseposter +DCOUNT = DANTALL ## Teller celler som inneholder tall i en database +DCOUNTA = DANTALLA ## Teller celler som ikke er tomme i en database +DGET = DHENT ## Trekker ut fra en database en post som oppfyller angitte vilkår +DMAX = DMAKS ## Returnerer maksimumsverdien fra merkede databaseposter +DMIN = DMIN ## Returnerer minimumsverdien fra merkede databaseposter +DPRODUCT = DPRODUKT ## Multipliserer verdiene i et bestemt felt med poster som oppfyller vilkårene i en database +DSTDEV = DSTDAV ## Estimerer standardavviket basert på et utvalg av merkede databaseposter +DSTDEVP = DSTAVP ## Beregner standardavviket basert på at merkede databaseposter utgjør hele populasjonen +DSUM = DSUMMER ## Legger til tallene i feltkolonnen med poster, i databasen som oppfyller vilkårene +DVAR = DVARIANS ## Estimerer variansen basert på et utvalg av merkede databaseposter +DVARP = DVARIANSP ## Beregner variansen basert på at merkede databaseposter utgjør hele populasjonen + + +## +## Date and time functions Dato- og tidsfunksjoner +## +DATE = DATO ## Returnerer serienummeret som svarer til en bestemt dato +DATEVALUE = DATOVERDI ## Konverterer en dato med tekstformat til et serienummer +DAY = DAG ## Konverterer et serienummer til en dag i måneden +DAYS360 = DAGER360 ## Beregner antall dager mellom to datoer basert på et år med 360 dager +EDATE = DAG.ETTER ## Returnerer serienummeret som svarer til datoen som er det indikerte antall måneder før eller etter startdatoen +EOMONTH = MÅNEDSSLUTT ## Returnerer serienummeret som svarer til siste dag i måneden, før eller etter et angitt antall måneder +HOUR = TIME ## Konverterer et serienummer til en time +MINUTE = MINUTT ## Konverterer et serienummer til et minutt +MONTH = MÅNED ## Konverterer et serienummer til en måned +NETWORKDAYS = NETT.ARBEIDSDAGER ## Returnerer antall hele arbeidsdager mellom to datoer +NOW = NÅ ## Returnerer serienummeret som svarer til gjeldende dato og klokkeslett +SECOND = SEKUND ## Konverterer et serienummer til et sekund +TIME = TID ## Returnerer serienummeret som svarer til et bestemt klokkeslett +TIMEVALUE = TIDSVERDI ## Konverterer et klokkeslett i tekstformat til et serienummer +TODAY = IDAG ## Returnerer serienummeret som svarer til dagens dato +WEEKDAY = UKEDAG ## Konverterer et serienummer til en ukedag +WEEKNUM = UKENR ## Konverterer et serienummer til et tall som representerer hvilket nummer uken har i et år +WORKDAY = ARBEIDSDAG ## Returnerer serienummeret som svarer til datoen før eller etter et angitt antall arbeidsdager +YEAR = ÅR ## Konverterer et serienummer til et år +YEARFRAC = ÅRDEL ## Returnerer brøkdelen for året, som svarer til antall hele dager mellom startdato og sluttdato + + +## +## Engineering functions Tekniske funksjoner +## +BESSELI = BESSELI ## Returnerer den endrede Bessel-funksjonen In(x) +BESSELJ = BESSELJ ## Returnerer Bessel-funksjonen Jn(x) +BESSELK = BESSELK ## Returnerer den endrede Bessel-funksjonen Kn(x) +BESSELY = BESSELY ## Returnerer Bessel-funksjonen Yn(x) +BIN2DEC = BINTILDES ## Konverterer et binært tall til et desimaltall +BIN2HEX = BINTILHEKS ## Konverterer et binært tall til et heksadesimaltall +BIN2OCT = BINTILOKT ## Konverterer et binært tall til et oktaltall +COMPLEX = KOMPLEKS ## Konverterer reelle og imaginære koeffisienter til et komplekst tall +CONVERT = KONVERTER ## Konverterer et tall fra ett målsystem til et annet +DEC2BIN = DESTILBIN ## Konverterer et desimaltall til et binærtall +DEC2HEX = DESTILHEKS ## Konverterer et heltall i 10-tallsystemet til et heksadesimalt tall +DEC2OCT = DESTILOKT ## Konverterer et heltall i 10-tallsystemet til et oktaltall +DELTA = DELTA ## Undersøker om to verdier er like +ERF = FEILF ## Returnerer feilfunksjonen +ERFC = FEILFK ## Returnerer den komplementære feilfunksjonen +GESTEP = GRENSEVERDI ## Tester om et tall er større enn en terskelverdi +HEX2BIN = HEKSTILBIN ## Konverterer et heksadesimaltall til et binært tall +HEX2DEC = HEKSTILDES ## Konverterer et heksadesimalt tall til et heltall i 10-tallsystemet +HEX2OCT = HEKSTILOKT ## Konverterer et heksadesimalt tall til et oktaltall +IMABS = IMABS ## Returnerer absoluttverdien (koeffisienten) til et komplekst tall +IMAGINARY = IMAGINÆR ## Returnerer den imaginære koeffisienten til et komplekst tall +IMARGUMENT = IMARGUMENT ## Returnerer argumentet theta, som er en vinkel uttrykt i radianer +IMCONJUGATE = IMKONJUGERT ## Returnerer den komplekse konjugaten til et komplekst tall +IMCOS = IMCOS ## Returnerer cosinus til et komplekst tall +IMDIV = IMDIV ## Returnerer kvotienten til to komplekse tall +IMEXP = IMEKSP ## Returnerer eksponenten til et komplekst tall +IMLN = IMLN ## Returnerer den naturlige logaritmen for et komplekst tall +IMLOG10 = IMLOG10 ## Returnerer logaritmen med grunntall 10 for et komplekst tall +IMLOG2 = IMLOG2 ## Returnerer logaritmen med grunntall 2 for et komplekst tall +IMPOWER = IMOPPHØY ## Returnerer et komplekst tall opphøyd til en heltallspotens +IMPRODUCT = IMPRODUKT ## Returnerer produktet av komplekse tall +IMREAL = IMREELL ## Returnerer den reelle koeffisienten til et komplekst tall +IMSIN = IMSIN ## Returnerer sinus til et komplekst tall +IMSQRT = IMROT ## Returnerer kvadratroten av et komplekst tall +IMSUB = IMSUB ## Returnerer differansen mellom to komplekse tall +IMSUM = IMSUMMER ## Returnerer summen av komplekse tall +OCT2BIN = OKTTILBIN ## Konverterer et oktaltall til et binært tall +OCT2DEC = OKTTILDES ## Konverterer et oktaltall til et desimaltall +OCT2HEX = OKTTILHEKS ## Konverterer et oktaltall til et heksadesimaltall + + +## +## Financial functions Økonomiske funksjoner +## +ACCRINT = PÅLØPT.PERIODISK.RENTE ## Returnerer påløpte renter for et verdipapir som betaler periodisk rente +ACCRINTM = PÅLØPT.FORFALLSRENTE ## Returnerer den påløpte renten for et verdipapir som betaler rente ved forfall +AMORDEGRC = AMORDEGRC ## Returnerer avskrivningen for hver regnskapsperiode ved hjelp av en avskrivingskoeffisient +AMORLINC = AMORLINC ## Returnerer avskrivingen for hver regnskapsperiode +COUPDAYBS = OBLIG.DAGER.FF ## Returnerer antall dager fra begynnelsen av den rentebærende perioden til innløsningsdatoen +COUPDAYS = OBLIG.DAGER ## Returnerer antall dager i den rentebærende perioden som inneholder innløsningsdatoen +COUPDAYSNC = OBLIG.DAGER.NF ## Returnerer antall dager fra betalingsdato til neste renteinnbetalingsdato +COUPNCD = OBLIG.DAGER.EF ## Returnerer obligasjonsdatoen som kommer etter oppgjørsdatoen +COUPNUM = OBLIG.ANTALL ## Returnerer antall obligasjoner som skal betales mellom oppgjørsdatoen og forfallsdatoen +COUPPCD = OBLIG.DAG.FORRIGE ## Returnerer obligasjonsdatoen som kommer før oppgjørsdatoen +CUMIPMT = SAMLET.RENTE ## Returnerer den kumulative renten som er betalt mellom to perioder +CUMPRINC = SAMLET.HOVEDSTOL ## Returnerer den kumulative hovedstolen som er betalt for et lån mellom to perioder +DB = DAVSKR ## Returnerer avskrivningen for et aktivum i en angitt periode, foretatt med fast degressiv avskrivning +DDB = DEGRAVS ## Returnerer avskrivningen for et aktivum for en gitt periode, ved hjelp av dobbel degressiv avskrivning eller en metode som du selv angir +DISC = DISKONTERT ## Returnerer diskonteringsraten for et verdipapir +DOLLARDE = DOLLARDE ## Konverterer en valutapris uttrykt som en brøk, til en valutapris uttrykt som et desimaltall +DOLLARFR = DOLLARBR ## Konverterer en valutapris uttrykt som et desimaltall, til en valutapris uttrykt som en brøk +DURATION = VARIGHET ## Returnerer årlig varighet for et verdipapir med renter som betales periodisk +EFFECT = EFFEKTIV.RENTE ## Returnerer den effektive årlige rentesatsen +FV = SLUTTVERDI ## Returnerer fremtidig verdi for en investering +FVSCHEDULE = SVPLAN ## Returnerer den fremtidige verdien av en inngående hovedstol etter å ha anvendt en serie med sammensatte rentesatser +INTRATE = RENTESATS ## Returnerer rentefoten av et fullfinansiert verdipapir +IPMT = RAVDRAG ## Returnerer betalte renter på en investering for en gitt periode +IRR = IR ## Returnerer internrenten for en serie kontantstrømmer +ISPMT = ER.AVDRAG ## Beregner renten som er betalt for en investering i løpet av en bestemt periode +MDURATION = MVARIGHET ## Returnerer Macauleys modifiserte varighet for et verdipapir med en antatt pålydende verdi på kr 100,00 +MIRR = MODIR ## Returnerer internrenten der positive og negative kontantstrømmer finansieres med forskjellige satser +NOMINAL = NOMINELL ## Returnerer årlig nominell rentesats +NPER = PERIODER ## Returnerer antall perioder for en investering +NPV = NNV ## Returnerer netto nåverdi for en investering, basert på en serie periodiske kontantstrømmer og en rentesats +ODDFPRICE = AVVIKFP.PRIS ## Returnerer pris pålydende kr 100 for et verdipapir med en odde første periode +ODDFYIELD = AVVIKFP.AVKASTNING ## Returnerer avkastingen for et verdipapir med en odde første periode +ODDLPRICE = AVVIKSP.PRIS ## Returnerer pris pålydende kr 100 for et verdipapir med en odde siste periode +ODDLYIELD = AVVIKSP.AVKASTNING ## Returnerer avkastingen for et verdipapir med en odde siste periode +PMT = AVDRAG ## Returnerer periodisk betaling for en annuitet +PPMT = AMORT ## Returnerer betalingen på hovedstolen for en investering i en gitt periode +PRICE = PRIS ## Returnerer prisen per pålydende kr 100 for et verdipapir som gir periodisk avkastning +PRICEDISC = PRIS.DISKONTERT ## Returnerer prisen per pålydende kr 100 for et diskontert verdipapir +PRICEMAT = PRIS.FORFALL ## Returnerer prisen per pålydende kr 100 av et verdipapir som betaler rente ved forfall +PV = NÅVERDI ## Returnerer nåverdien av en investering +RATE = RENTE ## Returnerer rentesatsen per periode for en annuitet +RECEIVED = MOTTATT.AVKAST ## Returnerer summen som mottas ved forfallsdato for et fullinvestert verdipapir +SLN = LINAVS ## Returnerer den lineære avskrivningen for et aktivum i én periode +SYD = ÅRSAVS ## Returnerer årsavskrivningen for et aktivum i en angitt periode +TBILLEQ = TBILLEKV ## Returnerer den obligasjonsekvivalente avkastningen for en statsobligasjon +TBILLPRICE = TBILLPRIS ## Returnerer prisen per pålydende kr 100 for en statsobligasjon +TBILLYIELD = TBILLAVKASTNING ## Returnerer avkastningen til en statsobligasjon +VDB = VERDIAVS ## Returnerer avskrivningen for et aktivum i en angitt periode eller delperiode, ved hjelp av degressiv avskrivning +XIRR = XIR ## Returnerer internrenten for en serie kontantstrømmer som ikke nødvendigvis er periodiske +XNPV = XNNV ## Returnerer netto nåverdi for en serie kontantstrømmer som ikke nødvendigvis er periodiske +YIELD = AVKAST ## Returnerer avkastningen på et verdipapir som betaler periodisk rente +YIELDDISC = AVKAST.DISKONTERT ## Returnerer årlig avkastning for et diskontert verdipapir, for eksempel en statskasseveksel +YIELDMAT = AVKAST.FORFALL ## Returnerer den årlige avkastningen for et verdipapir som betaler rente ved forfallsdato + + +## +## Information functions Informasjonsfunksjoner +## +CELL = CELLE ## Returnerer informasjon om formatering, plassering eller innholdet til en celle +ERROR.TYPE = FEIL.TYPE ## Returnerer et tall som svarer til en feiltype +INFO = INFO ## Returnerer informasjon om gjeldende operativmiljø +ISBLANK = ERTOM ## Returnerer SANN hvis verdien er tom +ISERR = ERFEIL ## Returnerer SANN hvis verdien er en hvilken som helst annen feilverdi enn #I/T +ISERROR = ERFEIL ## Returnerer SANN hvis verdien er en hvilken som helst feilverdi +ISEVEN = ERPARTALL ## Returnerer SANN hvis tallet er et partall +ISLOGICAL = ERLOGISK ## Returnerer SANN hvis verdien er en logisk verdi +ISNA = ERIT ## Returnerer SANN hvis verdien er feilverdien #I/T +ISNONTEXT = ERIKKETEKST ## Returnerer SANN hvis verdien ikke er tekst +ISNUMBER = ERTALL ## Returnerer SANN hvis verdien er et tall +ISODD = ERODDETALL ## Returnerer SANN hvis tallet er et oddetall +ISREF = ERREF ## Returnerer SANN hvis verdien er en referanse +ISTEXT = ERTEKST ## Returnerer SANN hvis verdien er tekst +N = N ## Returnerer en verdi som er konvertert til et tall +NA = IT ## Returnerer feilverdien #I/T +TYPE = VERDITYPE ## Returnerer et tall som indikerer datatypen til en verdi + + +## +## Logical functions Logiske funksjoner +## +AND = OG ## Returnerer SANN hvis alle argumentene er lik SANN +FALSE = USANN ## Returnerer den logiske verdien USANN +IF = HVIS ## Angir en logisk test som skal utføres +IFERROR = HVISFEIL ## Returnerer en verdi du angir hvis en formel evaluerer til en feil. Ellers returnerer den resultatet av formelen. +NOT = IKKE ## Reverserer logikken til argumentet +OR = ELLER ## Returnerer SANN hvis ett eller flere argumenter er lik SANN +TRUE = SANN ## Returnerer den logiske verdien SANN + + +## +## Lookup and reference functions Oppslag- og referansefunksjoner +## +ADDRESS = ADRESSE ## Returnerer en referanse som tekst til en enkelt celle i et regneark +AREAS = OMRÅDER ## Returnerer antall områder i en referanse +CHOOSE = VELG ## Velger en verdi fra en liste med verdier +COLUMN = KOLONNE ## Returnerer kolonnenummeret for en referanse +COLUMNS = KOLONNER ## Returnerer antall kolonner i en referanse +HLOOKUP = FINN.KOLONNE ## Leter i den øverste raden i en matrise og returnerer verdien for den angitte cellen +HYPERLINK = HYPERKOBLING ## Oppretter en snarvei eller et hopp som åpner et dokument som er lagret på en nettverksserver, et intranett eller Internett +INDEX = INDEKS ## Bruker en indeks til å velge en verdi fra en referanse eller matrise +INDIRECT = INDIREKTE ## Returnerer en referanse angitt av en tekstverdi +LOOKUP = SLÅ.OPP ## Slår opp verdier i en vektor eller matrise +MATCH = SAMMENLIGNE ## Slår opp verdier i en referanse eller matrise +OFFSET = FORSKYVNING ## Returnerer en referanseforskyvning fra en gitt referanse +ROW = RAD ## Returnerer radnummeret for en referanse +ROWS = RADER ## Returnerer antall rader i en referanse +RTD = RTD ## Henter sanntidsdata fra et program som støtter COM-automatisering (automatisering: En måte å arbeide på med programobjekter fra et annet program- eller utviklingsverktøy. Tidligere kalt OLE-automatisering. Automatisering er en bransjestandard og en funksjon i Component Object Model (COM).) +TRANSPOSE = TRANSPONER ## Returnerer transponeringen av en matrise +VLOOKUP = FINN.RAD ## Leter i den første kolonnen i en matrise og flytter bortover raden for å returnere verdien til en celle + + +## +## Math and trigonometry functions Matematikk- og trigonometrifunksjoner +## +ABS = ABS ## Returnerer absoluttverdien til et tall +ACOS = ARCCOS ## Returnerer arcus cosinus til et tall +ACOSH = ARCCOSH ## Returnerer den inverse hyperbolske cosinus til et tall +ASIN = ARCSIN ## Returnerer arcus sinus til et tall +ASINH = ARCSINH ## Returnerer den inverse hyperbolske sinus til et tall +ATAN = ARCTAN ## Returnerer arcus tangens til et tall +ATAN2 = ARCTAN2 ## Returnerer arcus tangens fra x- og y-koordinater +ATANH = ARCTANH ## Returnerer den inverse hyperbolske tangens til et tall +CEILING = AVRUND.GJELDENDE.MULTIPLUM ## Runder av et tall til nærmeste heltall eller til nærmeste signifikante multiplum +COMBIN = KOMBINASJON ## Returnerer antall kombinasjoner for ett gitt antall objekter +COS = COS ## Returnerer cosinus til et tall +COSH = COSH ## Returnerer den hyperbolske cosinus til et tall +DEGREES = GRADER ## Konverterer radianer til grader +EVEN = AVRUND.TIL.PARTALL ## Runder av et tall oppover til nærmeste heltall som er et partall +EXP = EKSP ## Returnerer e opphøyd i en angitt potens +FACT = FAKULTET ## Returnerer fakultet til et tall +FACTDOUBLE = DOBBELFAKT ## Returnerer et talls doble fakultet +FLOOR = AVRUND.GJELDENDE.MULTIPLUM.NED ## Avrunder et tall nedover, mot null +GCD = SFF ## Returnerer høyeste felles divisor +INT = HELTALL ## Avrunder et tall nedover til nærmeste heltall +LCM = MFM ## Returnerer minste felles multiplum +LN = LN ## Returnerer den naturlige logaritmen til et tall +LOG = LOG ## Returnerer logaritmen for et tall til et angitt grunntall +LOG10 = LOG10 ## Returnerer logaritmen med grunntall 10 for et tall +MDETERM = MDETERM ## Returnerer matrisedeterminanten til en matrise +MINVERSE = MINVERS ## Returnerer den inverse matrisen til en matrise +MMULT = MMULT ## Returnerer matriseproduktet av to matriser +MOD = REST ## Returnerer resten fra en divisjon +MROUND = MRUND ## Returnerer et tall avrundet til det ønskede multiplum +MULTINOMIAL = MULTINOMINELL ## Returnerer det multinominelle for et sett med tall +ODD = AVRUND.TIL.ODDETALL ## Runder av et tall oppover til nærmeste heltall som er et oddetall +PI = PI ## Returnerer verdien av pi +POWER = OPPHØYD.I ## Returnerer resultatet av et tall opphøyd i en potens +PRODUCT = PRODUKT ## Multipliserer argumentene +QUOTIENT = KVOTIENT ## Returnerer heltallsdelen av en divisjon +RADIANS = RADIANER ## Konverterer grader til radianer +RAND = TILFELDIG ## Returnerer et tilfeldig tall mellom 0 og 1 +RANDBETWEEN = TILFELDIGMELLOM ## Returnerer et tilfeldig tall innenfor et angitt område +ROMAN = ROMERTALL ## Konverterer vanlige tall til romertall, som tekst +ROUND = AVRUND ## Avrunder et tall til et angitt antall sifre +ROUNDDOWN = AVRUND.NED ## Avrunder et tall nedover, mot null +ROUNDUP = AVRUND.OPP ## Runder av et tall oppover, bort fra null +SERIESSUM = SUMMER.REKKE ## Returnerer summen av en geometrisk rekke, basert på formelen +SIGN = FORTEGN ## Returnerer fortegnet for et tall +SIN = SIN ## Returnerer sinus til en gitt vinkel +SINH = SINH ## Returnerer den hyperbolske sinus til et tall +SQRT = ROT ## Returnerer en positiv kvadratrot +SQRTPI = ROTPI ## Returnerer kvadratroten av (tall * pi) +SUBTOTAL = DELSUM ## Returnerer en delsum i en liste eller database +SUM = SUMMER ## Legger sammen argumentene +SUMIF = SUMMERHVIS ## Legger sammen cellene angitt ved et gitt vilkår +SUMIFS = SUMMER.HVIS.SETT ## Legger sammen cellene i et område som oppfyller flere vilkår +SUMPRODUCT = SUMMERPRODUKT ## Returnerer summen av produktene av tilsvarende matrisekomponenter +SUMSQ = SUMMERKVADRAT ## Returnerer kvadratsummen av argumentene +SUMX2MY2 = SUMMERX2MY2 ## Returnerer summen av differansen av kvadratene for tilsvarende verdier i to matriser +SUMX2PY2 = SUMMERX2PY2 ## Returnerer summen av kvadratsummene for tilsvarende verdier i to matriser +SUMXMY2 = SUMMERXMY2 ## Returnerer summen av kvadratene av differansen for tilsvarende verdier i to matriser +TAN = TAN ## Returnerer tangens for et tall +TANH = TANH ## Returnerer den hyperbolske tangens for et tall +TRUNC = AVKORT ## Korter av et tall til et heltall + + +## +## Statistical functions Statistiske funksjoner +## +AVEDEV = GJENNOMSNITTSAVVIK ## Returnerer datapunktenes gjennomsnittlige absoluttavvik fra middelverdien +AVERAGE = GJENNOMSNITT ## Returnerer gjennomsnittet for argumentene +AVERAGEA = GJENNOMSNITTA ## Returnerer gjennomsnittet for argumentene, inkludert tall, tekst og logiske verdier +AVERAGEIF = GJENNOMSNITTHVIS ## Returnerer gjennomsnittet (aritmetisk gjennomsnitt) av alle cellene i et område som oppfyller et bestemt vilkår +AVERAGEIFS = GJENNOMSNITT.HVIS.SETT ## Returnerer gjennomsnittet (aritmetisk middelverdi) av alle celler som oppfyller flere vilkår. +BETADIST = BETA.FORDELING ## Returnerer den kumulative betafordelingsfunksjonen +BETAINV = INVERS.BETA.FORDELING ## Returnerer den inverse verdien til fordelingsfunksjonen for en angitt betafordeling +BINOMDIST = BINOM.FORDELING ## Returnerer den individuelle binomiske sannsynlighetsfordelingen +CHIDIST = KJI.FORDELING ## Returnerer den ensidige sannsynligheten for en kjikvadrert fordeling +CHIINV = INVERS.KJI.FORDELING ## Returnerer den inverse av den ensidige sannsynligheten for den kjikvadrerte fordelingen +CHITEST = KJI.TEST ## Utfører testen for uavhengighet +CONFIDENCE = KONFIDENS ## Returnerer konfidensintervallet til gjennomsnittet for en populasjon +CORREL = KORRELASJON ## Returnerer korrelasjonskoeffisienten mellom to datasett +COUNT = ANTALL ## Teller hvor mange tall som er i argumentlisten +COUNTA = ANTALLA ## Teller hvor mange verdier som er i argumentlisten +COUNTBLANK = TELLBLANKE ## Teller antall tomme celler i et område. +COUNTIF = ANTALL.HVIS ## Teller antall celler i et område som oppfyller gitte vilkår +COUNTIFS = ANTALL.HVIS.SETT ## Teller antallet ikke-tomme celler i et område som oppfyller flere vilkår +COVAR = KOVARIANS ## Returnerer kovariansen, gjennomsnittet av produktene av parvise avvik +CRITBINOM = GRENSE.BINOM ## Returnerer den minste verdien der den kumulative binomiske fordelingen er mindre enn eller lik en vilkårsverdi +DEVSQ = AVVIK.KVADRERT ## Returnerer summen av kvadrerte avvik +EXPONDIST = EKSP.FORDELING ## Returnerer eksponentialfordelingen +FDIST = FFORDELING ## Returnerer F-sannsynlighetsfordelingen +FINV = FFORDELING.INVERS ## Returnerer den inverse av den sannsynlige F-fordelingen +FISHER = FISHER ## Returnerer Fisher-transformasjonen +FISHERINV = FISHERINV ## Returnerer den inverse av Fisher-transformasjonen +FORECAST = PROGNOSE ## Returnerer en verdi langs en lineær trend +FREQUENCY = FREKVENS ## Returnerer en frekvensdistribusjon som en loddrett matrise +FTEST = FTEST ## Returnerer resultatet av en F-test +GAMMADIST = GAMMAFORDELING ## Returnerer gammafordelingen +GAMMAINV = GAMMAINV ## Returnerer den inverse av den gammakumulative fordelingen +GAMMALN = GAMMALN ## Returnerer den naturlige logaritmen til gammafunksjonen G(x) +GEOMEAN = GJENNOMSNITT.GEOMETRISK ## Returnerer den geometriske middelverdien +GROWTH = VEKST ## Returnerer verdier langs en eksponentiell trend +HARMEAN = GJENNOMSNITT.HARMONISK ## Returnerer den harmoniske middelverdien +HYPGEOMDIST = HYPGEOM.FORDELING ## Returnerer den hypergeometriske fordelingen +INTERCEPT = SKJÆRINGSPUNKT ## Returnerer skjæringspunktet til den lineære regresjonslinjen +KURT = KURT ## Returnerer kurtosen til et datasett +LARGE = N.STØRST ## Returnerer den n-te største verdien i et datasett +LINEST = RETTLINJE ## Returnerer parameterne til en lineær trend +LOGEST = KURVE ## Returnerer parameterne til en eksponentiell trend +LOGINV = LOGINV ## Returnerer den inverse lognormale fordelingen +LOGNORMDIST = LOGNORMFORD ## Returnerer den kumulative lognormale fordelingen +MAX = STØRST ## Returnerer maksimumsverdien i en argumentliste +MAXA = MAKSA ## Returnerer maksimumsverdien i en argumentliste, inkludert tall, tekst og logiske verdier +MEDIAN = MEDIAN ## Returnerer medianen til tallene som er gitt +MIN = MIN ## Returnerer minimumsverdien i en argumentliste +MINA = MINA ## Returnerer den minste verdien i en argumentliste, inkludert tall, tekst og logiske verdier +MODE = MODUS ## Returnerer den vanligste verdien i et datasett +NEGBINOMDIST = NEGBINOM.FORDELING ## Returnerer den negative binomiske fordelingen +NORMDIST = NORMALFORDELING ## Returnerer den kumulative normalfordelingen +NORMINV = NORMINV ## Returnerer den inverse kumulative normalfordelingen +NORMSDIST = NORMSFORDELING ## Returnerer standard kumulativ normalfordeling +NORMSINV = NORMSINV ## Returnerer den inverse av den den kumulative standard normalfordelingen +PEARSON = PEARSON ## Returnerer produktmomentkorrelasjonskoeffisienten, Pearson +PERCENTILE = PERSENTIL ## Returnerer den n-te persentil av verdiene i et område +PERCENTRANK = PROSENTDEL ## Returnerer prosentrangeringen av en verdi i et datasett +PERMUT = PERMUTER ## Returnerer antall permutasjoner for et gitt antall objekter +POISSON = POISSON ## Returnerer Poissons sannsynlighetsfordeling +PROB = SANNSYNLIG ## Returnerer sannsynligheten for at verdier i et område ligger mellom to grenser +QUARTILE = KVARTIL ## Returnerer kvartilen til et datasett +RANK = RANG ## Returnerer rangeringen av et tall, eller plassen tallet har i en rekke +RSQ = RKVADRAT ## Returnerer kvadratet av produktmomentkorrelasjonskoeffisienten (Pearsons r) +SKEW = SKJEVFORDELING ## Returnerer skjevheten i en fordeling +SLOPE = STIGNINGSTALL ## Returnerer stigningtallet for den lineære regresjonslinjen +SMALL = N.MINST ## Returnerer den n-te minste verdien i et datasett +STANDARDIZE = NORMALISER ## Returnerer en normalisert verdi +STDEV = STDAV ## Estimere standardavvik på grunnlag av et utvalg +STDEVA = STDAVVIKA ## Estimerer standardavvik basert på et utvalg, inkludert tall, tekst og logiske verdier +STDEVP = STDAVP ## Beregner standardavvik basert på hele populasjonen +STDEVPA = STDAVVIKPA ## Beregner standardavvik basert på hele populasjonen, inkludert tall, tekst og logiske verdier +STEYX = STANDARDFEIL ## Returnerer standardfeilen for den predikerte y-verdien for hver x i regresjonen +TDIST = TFORDELING ## Returnerer en Student t-fordeling +TINV = TINV ## Returnerer den inverse Student t-fordelingen +TREND = TREND ## Returnerer verdier langs en lineær trend +TRIMMEAN = TRIMMET.GJENNOMSNITT ## Returnerer den interne middelverdien til et datasett +TTEST = TTEST ## Returnerer sannsynligheten assosiert med en Student t-test +VAR = VARIANS ## Estimerer varians basert på et utvalg +VARA = VARIANSA ## Estimerer varians basert på et utvalg, inkludert tall, tekst og logiske verdier +VARP = VARIANSP ## Beregner varians basert på hele populasjonen +VARPA = VARIANSPA ## Beregner varians basert på hele populasjonen, inkludert tall, tekst og logiske verdier +WEIBULL = WEIBULL.FORDELING ## Returnerer Weibull-fordelingen +ZTEST = ZTEST ## Returnerer den ensidige sannsynlighetsverdien for en z-test + + +## +## Text functions Tekstfunksjoner +## +ASC = STIGENDE ## Endrer fullbreddes (dobbeltbyte) engelske bokstaver eller katakana i en tegnstreng, til halvbreddes (enkeltbyte) tegn +BAHTTEXT = BAHTTEKST ## Konverterer et tall til tekst, og bruker valutaformatet ß (baht) +CHAR = TEGNKODE ## Returnerer tegnet som svarer til kodenummeret +CLEAN = RENSK ## Fjerner alle tegn som ikke kan skrives ut, fra teksten +CODE = KODE ## Returnerer en numerisk kode for det første tegnet i en tekststreng +CONCATENATE = KJEDE.SAMMEN ## Slår sammen flere tekstelementer til ett tekstelement +DOLLAR = VALUTA ## Konverterer et tall til tekst, og bruker valutaformatet $ (dollar) +EXACT = EKSAKT ## Kontrollerer om to tekstverdier er like +FIND = FINN ## Finner en tekstverdi inne i en annen (skiller mellom store og små bokstaver) +FINDB = FINNB ## Finner en tekstverdi inne i en annen (skiller mellom store og små bokstaver) +FIXED = FASTSATT ## Formaterer et tall som tekst med et bestemt antall desimaler +JIS = JIS ## Endrer halvbreddes (enkeltbyte) engelske bokstaver eller katakana i en tegnstreng, til fullbreddes (dobbeltbyte) tegn +LEFT = VENSTRE ## Returnerer tegnene lengst til venstre i en tekstverdi +LEFTB = VENSTREB ## Returnerer tegnene lengst til venstre i en tekstverdi +LEN = LENGDE ## Returnerer antall tegn i en tekststreng +LENB = LENGDEB ## Returnerer antall tegn i en tekststreng +LOWER = SMÅ ## Konverterer tekst til små bokstaver +MID = DELTEKST ## Returnerer et angitt antall tegn fra en tekststreng, og begynner fra posisjonen du angir +MIDB = DELTEKSTB ## Returnerer et angitt antall tegn fra en tekststreng, og begynner fra posisjonen du angir +PHONETIC = FURIGANA ## Trekker ut fonetiske tegn (furigana) fra en tekststreng +PROPER = STOR.FORBOKSTAV ## Gir den første bokstaven i hvert ord i en tekstverdi stor forbokstav +REPLACE = ERSTATT ## Erstatter tegn i en tekst +REPLACEB = ERSTATTB ## Erstatter tegn i en tekst +REPT = GJENTA ## Gjentar tekst et gitt antall ganger +RIGHT = HØYRE ## Returnerer tegnene lengst til høyre i en tekstverdi +RIGHTB = HØYREB ## Returnerer tegnene lengst til høyre i en tekstverdi +SEARCH = SØK ## Finner en tekstverdi inne i en annen (skiller ikke mellom store og små bokstaver) +SEARCHB = SØKB ## Finner en tekstverdi inne i en annen (skiller ikke mellom store og små bokstaver) +SUBSTITUTE = BYTT.UT ## Bytter ut gammel tekst med ny tekst i en tekststreng +T = T ## Konverterer argumentene til tekst +TEXT = TEKST ## Formaterer et tall og konverterer det til tekst +TRIM = TRIMME ## Fjerner mellomrom fra tekst +UPPER = STORE ## Konverterer tekst til store bokstaver +VALUE = VERDI ## Konverterer et tekstargument til et tall diff --git a/lib/phpexcel/PHPExcel/locale/pl/config b/lib/phpexcel/PHPExcel/locale/pl/config new file mode 100644 index 0000000..5061311 --- /dev/null +++ b/lib/phpexcel/PHPExcel/locale/pl/config @@ -0,0 +1,47 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Settings +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## + + +ArgumentSeparator = ; + + +## +## (For future use) +## +currencySymbol = zł + + +## +## Excel Error Codes (For future use) +## +NULL = #ZERO! +DIV0 = #DZIEL/0! +VALUE = #ARG! +REF = #ADR! +NAME = #NAZWA? +NUM = #LICZBA! +NA = #N/D! diff --git a/lib/phpexcel/PHPExcel/locale/pl/functions b/lib/phpexcel/PHPExcel/locale/pl/functions new file mode 100644 index 0000000..14499c0 --- /dev/null +++ b/lib/phpexcel/PHPExcel/locale/pl/functions @@ -0,0 +1,438 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Calculation +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## Data in this file derived from http://www.piuha.fi/excel-function-name-translation/ +## +## + + +## +## Add-in and Automation functions Funkcje dodatków i automatyzacji +## +GETPIVOTDATA = WEŹDANETABELI ## Zwraca dane przechowywane w raporcie tabeli przestawnej. + + +## +## Cube functions Funkcje modułów +## +CUBEKPIMEMBER = ELEMENT.KPI.MODUŁU ## Zwraca nazwę, właściwość i miarę kluczowego wskaźnika wydajności (KPI) oraz wyświetla nazwę i właściwość w komórce. Wskaźnik KPI jest miarą ilościową, taką jak miesięczny zysk brutto lub kwartalna fluktuacja pracowników, używaną do monitorowania wydajności organizacji. +CUBEMEMBER = ELEMENT.MODUŁU ## Zwraca element lub krotkę z hierarchii modułu. Służy do sprawdzania, czy element lub krotka istnieje w module. +CUBEMEMBERPROPERTY = WŁAŚCIWOŚĆ.ELEMENTU.MODUŁU ## Zwraca wartość właściwości elementu w module. Służy do sprawdzania, czy nazwa elementu istnieje w module, i zwracania określonej właściwości dla tego elementu. +CUBERANKEDMEMBER = USZEREGOWANY.ELEMENT.MODUŁU ## Zwraca n-ty (albo uszeregowany) element zestawu. Służy do zwracania elementu lub elementów zestawu, na przykład najlepszego sprzedawcy lub 10 najlepszych studentów. +CUBESET = ZESTAW.MODUŁÓW ## Definiuje obliczony zestaw elementów lub krotek, wysyłając wyrażenie zestawu do serwera modułu, który tworzy zestaw i zwraca go do programu Microsoft Office Excel. +CUBESETCOUNT = LICZNIK.MODUŁÓW.ZESTAWU ## Zwraca liczbę elementów zestawu. +CUBEVALUE = WARTOŚĆ.MODUŁU ## Zwraca zagregowaną wartość z modułu. + + +## +## Database functions Funkcje baz danych +## +DAVERAGE = BD.ŚREDNIA ## Zwraca wartość średniej wybranych wpisów bazy danych. +DCOUNT = BD.ILE.REKORDÓW ## Zlicza komórki zawierające liczby w bazie danych. +DCOUNTA = BD.ILE.REKORDÓW.A ## Zlicza niepuste komórki w bazie danych. +DGET = BD.POLE ## Wyodrębnia z bazy danych jeden rekord spełniający określone kryteria. +DMAX = BD.MAX ## Zwraca wartość maksymalną z wybranych wpisów bazy danych. +DMIN = BD.MIN ## Zwraca wartość minimalną z wybranych wpisów bazy danych. +DPRODUCT = BD.ILOCZYN ## Mnoży wartości w konkretnym, spełniającym kryteria polu rekordów bazy danych. +DSTDEV = BD.ODCH.STANDARD ## Szacuje odchylenie standardowe na podstawie próbki z wybranych wpisów bazy danych. +DSTDEVP = BD.ODCH.STANDARD.POPUL ## Oblicza odchylenie standardowe na podstawie całej populacji wybranych wpisów bazy danych. +DSUM = BD.SUMA ## Dodaje liczby w kolumnie pól rekordów bazy danych, które spełniają kryteria. +DVAR = BD.WARIANCJA ## Szacuje wariancję na podstawie próbki z wybranych wpisów bazy danych. +DVARP = BD.WARIANCJA.POPUL ## Oblicza wariancję na podstawie całej populacji wybranych wpisów bazy danych. + + +## +## Date and time functions Funkcje dat, godzin i czasu +## +DATE = DATA ## Zwraca liczbę seryjną dla wybranej daty. +DATEVALUE = DATA.WARTOŚĆ ## Konwertuje datę w formie tekstu na liczbę seryjną. +DAY = DZIEŃ ## Konwertuje liczbę seryjną na dzień miesiąca. +DAYS360 = DNI.360 ## Oblicza liczbę dni między dwiema datami na podstawie roku 360-dniowego. +EDATE = UPŁDNI ## Zwraca liczbę seryjną daty jako wskazaną liczbę miesięcy przed określoną datą początkową lub po niej. +EOMONTH = EOMONTH ## Zwraca liczbę seryjną ostatniego dnia miesiąca przed określoną liczbą miesięcy lub po niej. +HOUR = GODZINA ## Konwertuje liczbę seryjną na godzinę. +MINUTE = MINUTA ## Konwertuje liczbę seryjną na minutę. +MONTH = MIESIĄC ## Konwertuje liczbę seryjną na miesiąc. +NETWORKDAYS = NETWORKDAYS ## Zwraca liczbę pełnych dni roboczych między dwiema datami. +NOW = TERAZ ## Zwraca liczbę seryjną bieżącej daty i godziny. +SECOND = SEKUNDA ## Konwertuje liczbę seryjną na sekundę. +TIME = CZAS ## Zwraca liczbę seryjną określonego czasu. +TIMEVALUE = CZAS.WARTOŚĆ ## Konwertuje czas w formie tekstu na liczbę seryjną. +TODAY = DZIŚ ## Zwraca liczbę seryjną dla daty bieżącej. +WEEKDAY = DZIEŃ.TYG ## Konwertuje liczbę seryjną na dzień tygodnia. +WEEKNUM = WEEKNUM ## Konwertuje liczbę seryjną na liczbę reprezentującą numer tygodnia w roku. +WORKDAY = WORKDAY ## Zwraca liczbę seryjną dla daty przed określoną liczbą dni roboczych lub po niej. +YEAR = ROK ## Konwertuje liczbę seryjną na rok. +YEARFRAC = YEARFRAC ## Zwraca część roku reprezentowaną przez pełną liczbę dni między datą początkową a datą końcową. + + +## +## Engineering functions Funkcje inżynierskie +## +BESSELI = BESSELI ## Zwraca wartość zmodyfikowanej funkcji Bessela In(x). +BESSELJ = BESSELJ ## Zwraca wartość funkcji Bessela Jn(x). +BESSELK = BESSELK ## Zwraca wartość zmodyfikowanej funkcji Bessela Kn(x). +BESSELY = BESSELY ## Zwraca wartość funkcji Bessela Yn(x). +BIN2DEC = BIN2DEC ## Konwertuje liczbę w postaci dwójkowej na liczbę w postaci dziesiętnej. +BIN2HEX = BIN2HEX ## Konwertuje liczbę w postaci dwójkowej na liczbę w postaci szesnastkowej. +BIN2OCT = BIN2OCT ## Konwertuje liczbę w postaci dwójkowej na liczbę w postaci ósemkowej. +COMPLEX = COMPLEX ## Konwertuje część rzeczywistą i urojoną na liczbę zespoloną. +CONVERT = CONVERT ## Konwertuje liczbę z jednego systemu miar na inny. +DEC2BIN = DEC2BIN ## Konwertuje liczbę w postaci dziesiętnej na postać dwójkową. +DEC2HEX = DEC2HEX ## Konwertuje liczbę w postaci dziesiętnej na liczbę w postaci szesnastkowej. +DEC2OCT = DEC2OCT ## Konwertuje liczbę w postaci dziesiętnej na liczbę w postaci ósemkowej. +DELTA = DELTA ## Sprawdza, czy dwie wartości są równe. +ERF = ERF ## Zwraca wartość funkcji błędu. +ERFC = ERFC ## Zwraca wartość komplementarnej funkcji błędu. +GESTEP = GESTEP ## Sprawdza, czy liczba jest większa niż wartość progowa. +HEX2BIN = HEX2BIN ## Konwertuje liczbę w postaci szesnastkowej na liczbę w postaci dwójkowej. +HEX2DEC = HEX2DEC ## Konwertuje liczbę w postaci szesnastkowej na liczbę w postaci dziesiętnej. +HEX2OCT = HEX2OCT ## Konwertuje liczbę w postaci szesnastkowej na liczbę w postaci ósemkowej. +IMABS = IMABS ## Zwraca wartość bezwzględną (moduł) liczby zespolonej. +IMAGINARY = IMAGINARY ## Zwraca wartość części urojonej liczby zespolonej. +IMARGUMENT = IMARGUMENT ## Zwraca wartość argumentu liczby zespolonej, przy czym kąt wyrażony jest w radianach. +IMCONJUGATE = IMCONJUGATE ## Zwraca wartość liczby sprzężonej danej liczby zespolonej. +IMCOS = IMCOS ## Zwraca wartość cosinusa liczby zespolonej. +IMDIV = IMDIV ## Zwraca wartość ilorazu dwóch liczb zespolonych. +IMEXP = IMEXP ## Zwraca postać wykładniczą liczby zespolonej. +IMLN = IMLN ## Zwraca wartość logarytmu naturalnego liczby zespolonej. +IMLOG10 = IMLOG10 ## Zwraca wartość logarytmu dziesiętnego liczby zespolonej. +IMLOG2 = IMLOG2 ## Zwraca wartość logarytmu liczby zespolonej przy podstawie 2. +IMPOWER = IMPOWER ## Zwraca wartość liczby zespolonej podniesionej do potęgi całkowitej. +IMPRODUCT = IMPRODUCT ## Zwraca wartość iloczynu liczb zespolonych. +IMREAL = IMREAL ## Zwraca wartość części rzeczywistej liczby zespolonej. +IMSIN = IMSIN ## Zwraca wartość sinusa liczby zespolonej. +IMSQRT = IMSQRT ## Zwraca wartość pierwiastka kwadratowego z liczby zespolonej. +IMSUB = IMSUB ## Zwraca wartość różnicy dwóch liczb zespolonych. +IMSUM = IMSUM ## Zwraca wartość sumy liczb zespolonych. +OCT2BIN = OCT2BIN ## Konwertuje liczbę w postaci ósemkowej na liczbę w postaci dwójkowej. +OCT2DEC = OCT2DEC ## Konwertuje liczbę w postaci ósemkowej na liczbę w postaci dziesiętnej. +OCT2HEX = OCT2HEX ## Konwertuje liczbę w postaci ósemkowej na liczbę w postaci szesnastkowej. + + +## +## Financial functions Funkcje finansowe +## +ACCRINT = ACCRINT ## Zwraca narosłe odsetki dla papieru wartościowego z oprocentowaniem okresowym. +ACCRINTM = ACCRINTM ## Zwraca narosłe odsetki dla papieru wartościowego z oprocentowaniem w terminie wykupu. +AMORDEGRC = AMORDEGRC ## Zwraca amortyzację dla każdego okresu rozliczeniowego z wykorzystaniem współczynnika amortyzacji. +AMORLINC = AMORLINC ## Zwraca amortyzację dla każdego okresu rozliczeniowego. +COUPDAYBS = COUPDAYBS ## Zwraca liczbę dni od początku okresu dywidendy do dnia rozliczeniowego. +COUPDAYS = COUPDAYS ## Zwraca liczbę dni w okresie dywidendy, z uwzględnieniem dnia rozliczeniowego. +COUPDAYSNC = COUPDAYSNC ## Zwraca liczbę dni od dnia rozliczeniowego do daty następnego dnia dywidendy. +COUPNCD = COUPNCD ## Zwraca dzień następnej dywidendy po dniu rozliczeniowym. +COUPNUM = COUPNUM ## Zwraca liczbę dywidend płatnych między dniem rozliczeniowym a dniem wykupu. +COUPPCD = COUPPCD ## Zwraca dzień poprzedniej dywidendy przed dniem rozliczeniowym. +CUMIPMT = CUMIPMT ## Zwraca wartość procentu składanego płatnego między dwoma okresami. +CUMPRINC = CUMPRINC ## Zwraca wartość kapitału skumulowanego spłaty pożyczki między dwoma okresami. +DB = DB ## Zwraca amortyzację środka trwałego w danym okresie metodą degresywną z zastosowaniem stałej bazowej. +DDB = DDB ## Zwraca amortyzację środka trwałego za podany okres metodą degresywną z zastosowaniem podwójnej bazowej lub metodą określoną przez użytkownika. +DISC = DISC ## Zwraca wartość stopy dyskontowej papieru wartościowego. +DOLLARDE = DOLLARDE ## Konwertuje cenę w postaci ułamkowej na cenę wyrażoną w postaci dziesiętnej. +DOLLARFR = DOLLARFR ## Konwertuje cenę wyrażoną w postaci dziesiętnej na cenę wyrażoną w postaci ułamkowej. +DURATION = DURATION ## Zwraca wartość rocznego przychodu z papieru wartościowego o okresowych wypłatach oprocentowania. +EFFECT = EFFECT ## Zwraca wartość efektywnej rocznej stopy procentowej. +FV = FV ## Zwraca przyszłą wartość lokaty. +FVSCHEDULE = FVSCHEDULE ## Zwraca przyszłą wartość kapitału początkowego wraz z szeregiem procentów składanych. +INTRATE = INTRATE ## Zwraca wartość stopy procentowej papieru wartościowego całkowicie ulokowanego. +IPMT = IPMT ## Zwraca wysokość spłaty oprocentowania lokaty za dany okres. +IRR = IRR ## Zwraca wartość wewnętrznej stopy zwrotu dla serii przepływów gotówkowych. +ISPMT = ISPMT ## Oblicza wysokość spłaty oprocentowania za dany okres lokaty. +MDURATION = MDURATION ## Zwraca wartość zmodyfikowanego okresu Macauleya dla papieru wartościowego o założonej wartości nominalnej 100 zł. +MIRR = MIRR ## Zwraca wartość wewnętrznej stopy zwrotu dla przypadku, gdy dodatnie i ujemne przepływy gotówkowe mają różne stopy. +NOMINAL = NOMINAL ## Zwraca wysokość nominalnej rocznej stopy procentowej. +NPER = NPER ## Zwraca liczbę okresów dla lokaty. +NPV = NPV ## Zwraca wartość bieżącą netto lokaty na podstawie szeregu okresowych przepływów gotówkowych i stopy dyskontowej. +ODDFPRICE = ODDFPRICE ## Zwraca cenę za 100 zł wartości nominalnej papieru wartościowego z nietypowym pierwszym okresem. +ODDFYIELD = ODDFYIELD ## Zwraca rentowność papieru wartościowego z nietypowym pierwszym okresem. +ODDLPRICE = ODDLPRICE ## Zwraca cenę za 100 zł wartości nominalnej papieru wartościowego z nietypowym ostatnim okresem. +ODDLYIELD = ODDLYIELD ## Zwraca rentowność papieru wartościowego z nietypowym ostatnim okresem. +PMT = PMT ## Zwraca wartość okresowej płatności raty rocznej. +PPMT = PPMT ## Zwraca wysokość spłaty kapitału w przypadku lokaty dla danego okresu. +PRICE = PRICE ## Zwraca cenę za 100 zł wartości nominalnej papieru wartościowego z oprocentowaniem okresowym. +PRICEDISC = PRICEDISC ## Zwraca cenę za 100 zł wartości nominalnej papieru wartościowego zdyskontowanego. +PRICEMAT = PRICEMAT ## Zwraca cenę za 100 zł wartości nominalnej papieru wartościowego z oprocentowaniem w terminie wykupu. +PV = PV ## Zwraca wartość bieżącą lokaty. +RATE = RATE ## Zwraca wysokość stopy procentowej w okresie raty rocznej. +RECEIVED = RECEIVED ## Zwraca wartość kapitału otrzymanego przy wykupie papieru wartościowego całkowicie ulokowanego. +SLN = SLN ## Zwraca amortyzację środka trwałego za jeden okres metodą liniową. +SYD = SYD ## Zwraca amortyzację środka trwałego za dany okres metodą sumy cyfr lat amortyzacji. +TBILLEQ = TBILLEQ ## Zwraca rentowność ekwiwalentu obligacji dla bonu skarbowego. +TBILLPRICE = TBILLPRICE ## Zwraca cenę za 100 zł wartości nominalnej bonu skarbowego. +TBILLYIELD = TBILLYIELD ## Zwraca rentowność bonu skarbowego. +VDB = VDB ## Oblicza amortyzację środka trwałego w danym okresie lub jego części metodą degresywną. +XIRR = XIRR ## Zwraca wartość wewnętrznej stopy zwrotu dla serii rozłożonych w czasie przepływów gotówkowych, niekoniecznie okresowych. +XNPV = XNPV ## Zwraca wartość bieżącą netto dla serii rozłożonych w czasie przepływów gotówkowych, niekoniecznie okresowych. +YIELD = YIELD ## Zwraca rentowność papieru wartościowego z oprocentowaniem okresowym. +YIELDDISC = YIELDDISC ## Zwraca roczną rentowność zdyskontowanego papieru wartościowego, na przykład bonu skarbowego. +YIELDMAT = YIELDMAT ## Zwraca roczną rentowność papieru wartościowego oprocentowanego przy wykupie. + + +## +## Information functions Funkcje informacyjne +## +CELL = KOMÓRKA ## Zwraca informacje o formacie, położeniu lub zawartości komórki. +ERROR.TYPE = NR.BŁĘDU ## Zwraca liczbę odpowiadającą typowi błędu. +INFO = INFO ## Zwraca informację o aktualnym środowisku pracy. +ISBLANK = CZY.PUSTA ## Zwraca wartość PRAWDA, jeśli wartość jest pusta. +ISERR = CZY.BŁ ## Zwraca wartość PRAWDA, jeśli wartość jest dowolną wartością błędu, z wyjątkiem #N/D!. +ISERROR = CZY.BŁĄD ## Zwraca wartość PRAWDA, jeśli wartość jest dowolną wartością błędu. +ISEVEN = ISEVEN ## Zwraca wartość PRAWDA, jeśli liczba jest parzysta. +ISLOGICAL = CZY.LOGICZNA ## Zwraca wartość PRAWDA, jeśli wartość jest wartością logiczną. +ISNA = CZY.BRAK ## Zwraca wartość PRAWDA, jeśli wartość jest wartością błędu #N/D!. +ISNONTEXT = CZY.NIE.TEKST ## Zwraca wartość PRAWDA, jeśli wartość nie jest tekstem. +ISNUMBER = CZY.LICZBA ## Zwraca wartość PRAWDA, jeśli wartość jest liczbą. +ISODD = ISODD ## Zwraca wartość PRAWDA, jeśli liczba jest nieparzysta. +ISREF = CZY.ADR ## Zwraca wartość PRAWDA, jeśli wartość jest odwołaniem. +ISTEXT = CZY.TEKST ## Zwraca wartość PRAWDA, jeśli wartość jest tekstem. +N = L ## Zwraca wartość przekonwertowaną na postać liczbową. +NA = BRAK ## Zwraca wartość błędu #N/D!. +TYPE = TYP ## Zwraca liczbę wskazującą typ danych wartości. + + +## +## Logical functions Funkcje logiczne +## +AND = ORAZ ## Zwraca wartość PRAWDA, jeśli wszystkie argumenty mają wartość PRAWDA. +FALSE = FAŁSZ ## Zwraca wartość logiczną FAŁSZ. +IF = JEŻELI ## Określa warunek logiczny do sprawdzenia. +IFERROR = JEŻELI.BŁĄD ## Zwraca określoną wartość, jeśli wynikiem obliczenia formuły jest błąd; w przeciwnym przypadku zwraca wynik formuły. +NOT = NIE ## Odwraca wartość logiczną argumentu. +OR = LUB ## Zwraca wartość PRAWDA, jeśli co najmniej jeden z argumentów ma wartość PRAWDA. +TRUE = PRAWDA ## Zwraca wartość logiczną PRAWDA. + + +## +## Lookup and reference functions Funkcje wyszukiwania i odwołań +## +ADDRESS = ADRES ## Zwraca odwołanie do jednej komórki w arkuszu jako wartość tekstową. +AREAS = OBSZARY ## Zwraca liczbę obszarów występujących w odwołaniu. +CHOOSE = WYBIERZ ## Wybiera wartość z listy wartości. +COLUMN = NR.KOLUMNY ## Zwraca numer kolumny z odwołania. +COLUMNS = LICZBA.KOLUMN ## Zwraca liczbę kolumn dla danego odwołania. +HLOOKUP = WYSZUKAJ.POZIOMO ## Przegląda górny wiersz tablicy i zwraca wartość wskazanej komórki. +HYPERLINK = HIPERŁĄCZE ## Tworzy skrót lub skok, który pozwala otwierać dokument przechowywany na serwerze sieciowym, w sieci intranet lub w Internecie. +INDEX = INDEKS ## Używa indeksu do wybierania wartości z odwołania lub tablicy. +INDIRECT = ADR.POŚR ## Zwraca odwołanie określone przez wartość tekstową. +LOOKUP = WYSZUKAJ ## Wyszukuje wartości w wektorze lub tablicy. +MATCH = PODAJ.POZYCJĘ ## Wyszukuje wartości w odwołaniu lub w tablicy. +OFFSET = PRZESUNIĘCIE ## Zwraca adres przesunięty od danego odwołania. +ROW = WIERSZ ## Zwraca numer wiersza odwołania. +ROWS = ILE.WIERSZY ## Zwraca liczbę wierszy dla danego odwołania. +RTD = RTD ## Pobiera dane w czasie rzeczywistym z programu obsługującego automatyzację COM (Automatyzacja: Sposób pracy z obiektami aplikacji pochodzącymi z innej aplikacji lub narzędzia projektowania. Nazywana wcześniej Automatyzacją OLE, Automatyzacja jest standardem przemysłowym i funkcją obiektowego modelu składników (COM, Component Object Model).). +TRANSPOSE = TRANSPONUJ ## Zwraca transponowaną tablicę. +VLOOKUP = WYSZUKAJ.PIONOWO ## Przeszukuje pierwszą kolumnę tablicy i przechodzi wzdłuż wiersza, aby zwrócić wartość komórki. + + +## +## Math and trigonometry functions Funkcje matematyczne i trygonometryczne +## +ABS = MODUŁ.LICZBY ## Zwraca wartość absolutną liczby. +ACOS = ACOS ## Zwraca arcus cosinus liczby. +ACOSH = ACOSH ## Zwraca arcus cosinus hiperboliczny liczby. +ASIN = ASIN ## Zwraca arcus sinus liczby. +ASINH = ASINH ## Zwraca arcus sinus hiperboliczny liczby. +ATAN = ATAN ## Zwraca arcus tangens liczby. +ATAN2 = ATAN2 ## Zwraca arcus tangens liczby na podstawie współrzędnych x i y. +ATANH = ATANH ## Zwraca arcus tangens hiperboliczny liczby. +CEILING = ZAOKR.W.GÓRĘ ## Zaokrągla liczbę do najbliższej liczby całkowitej lub do najbliższej wielokrotności dokładności. +COMBIN = KOMBINACJE ## Zwraca liczbę kombinacji dla danej liczby obiektów. +COS = COS ## Zwraca cosinus liczby. +COSH = COSH ## Zwraca cosinus hiperboliczny liczby. +DEGREES = STOPNIE ## Konwertuje radiany na stopnie. +EVEN = ZAOKR.DO.PARZ ## Zaokrągla liczbę w górę do najbliższej liczby parzystej. +EXP = EXP ## Zwraca wartość liczby e podniesionej do potęgi określonej przez podaną liczbę. +FACT = SILNIA ## Zwraca silnię liczby. +FACTDOUBLE = FACTDOUBLE ## Zwraca podwójną silnię liczby. +FLOOR = ZAOKR.W.DÓŁ ## Zaokrągla liczbę w dół, w kierunku zera. +GCD = GCD ## Zwraca największy wspólny dzielnik. +INT = ZAOKR.DO.CAŁK ## Zaokrągla liczbę w dół do najbliższej liczby całkowitej. +LCM = LCM ## Zwraca najmniejszą wspólną wielokrotność. +LN = LN ## Zwraca logarytm naturalny podanej liczby. +LOG = LOG ## Zwraca logarytm danej liczby przy zadanej podstawie. +LOG10 = LOG10 ## Zwraca logarytm dziesiętny liczby. +MDETERM = WYZNACZNIK.MACIERZY ## Zwraca wyznacznik macierzy tablicy. +MINVERSE = MACIERZ.ODW ## Zwraca odwrotność macierzy tablicy. +MMULT = MACIERZ.ILOCZYN ## Zwraca iloczyn macierzy dwóch tablic. +MOD = MOD ## Zwraca resztę z dzielenia. +MROUND = MROUND ## Zwraca liczbę zaokrągloną do żądanej wielokrotności. +MULTINOMIAL = MULTINOMIAL ## Zwraca wielomian dla zbioru liczb. +ODD = ZAOKR.DO.NPARZ ## Zaokrągla liczbę w górę do najbliższej liczby nieparzystej. +PI = PI ## Zwraca wartość liczby Pi. +POWER = POTĘGA ## Zwraca liczbę podniesioną do potęgi. +PRODUCT = ILOCZYN ## Mnoży argumenty. +QUOTIENT = QUOTIENT ## Zwraca iloraz (całkowity). +RADIANS = RADIANY ## Konwertuje stopnie na radiany. +RAND = LOS ## Zwraca liczbę pseudolosową z zakresu od 0 do 1. +RANDBETWEEN = RANDBETWEEN ## Zwraca liczbę pseudolosową z zakresu określonego przez podane argumenty. +ROMAN = RZYMSKIE ## Konwertuje liczbę arabską na rzymską jako tekst. +ROUND = ZAOKR ## Zaokrągla liczbę do określonej liczby cyfr. +ROUNDDOWN = ZAOKR.DÓŁ ## Zaokrągla liczbę w dół, w kierunku zera. +ROUNDUP = ZAOKR.GÓRA ## Zaokrągla liczbę w górę, w kierunku od zera. +SERIESSUM = SERIESSUM ## Zwraca sumę szeregu potęgowego na podstawie wzoru. +SIGN = ZNAK.LICZBY ## Zwraca znak liczby. +SIN = SIN ## Zwraca sinus danego kąta. +SINH = SINH ## Zwraca sinus hiperboliczny liczby. +SQRT = PIERWIASTEK ## Zwraca dodatni pierwiastek kwadratowy. +SQRTPI = SQRTPI ## Zwraca pierwiastek kwadratowy iloczynu (liczba * Pi). +SUBTOTAL = SUMY.POŚREDNIE ## Zwraca sumę częściową listy lub bazy danych. +SUM = SUMA ## Dodaje argumenty. +SUMIF = SUMA.JEŻELI ## Dodaje komórki określone przez podane kryterium. +SUMIFS = SUMA.WARUNKÓW ## Dodaje komórki w zakresie, które spełniają wiele kryteriów. +SUMPRODUCT = SUMA.ILOCZYNÓW ## Zwraca sumę iloczynów odpowiednich elementów tablicy. +SUMSQ = SUMA.KWADRATÓW ## Zwraca sumę kwadratów argumentów. +SUMX2MY2 = SUMA.X2.M.Y2 ## Zwraca sumę różnic kwadratów odpowiednich wartości w dwóch tablicach. +SUMX2PY2 = SUMA.X2.P.Y2 ## Zwraca sumę sum kwadratów odpowiednich wartości w dwóch tablicach. +SUMXMY2 = SUMA.XMY.2 ## Zwraca sumę kwadratów różnic odpowiednich wartości w dwóch tablicach. +TAN = TAN ## Zwraca tangens liczby. +TANH = TANH ## Zwraca tangens hiperboliczny liczby. +TRUNC = LICZBA.CAŁK ## Przycina liczbę do wartości całkowitej. + + +## +## Statistical functions Funkcje statystyczne +## +AVEDEV = ODCH.ŚREDNIE ## Zwraca średnią wartość odchyleń absolutnych punktów danych od ich wartości średniej. +AVERAGE = ŚREDNIA ## Zwraca wartość średnią argumentów. +AVERAGEA = ŚREDNIA.A ## Zwraca wartość średnią argumentów, z uwzględnieniem liczb, tekstów i wartości logicznych. +AVERAGEIF = ŚREDNIA.JEŻELI ## Zwraca średnią (średnią arytmetyczną) wszystkich komórek w zakresie, które spełniają podane kryteria. +AVERAGEIFS = ŚREDNIA.WARUNKÓW ## Zwraca średnią (średnią arytmetyczną) wszystkich komórek, które spełniają jedno lub więcej kryteriów. +BETADIST = ROZKŁAD.BETA ## Zwraca skumulowaną funkcję gęstości prawdopodobieństwa beta. +BETAINV = ROZKŁAD.BETA.ODW ## Zwraca odwrotność skumulowanej funkcji gęstości prawdopodobieństwa beta. +BINOMDIST = ROZKŁAD.DWUM ## Zwraca pojedynczy składnik dwumianowego rozkładu prawdopodobieństwa. +CHIDIST = ROZKŁAD.CHI ## Zwraca wartość jednostronnego prawdopodobieństwa rozkładu chi-kwadrat. +CHIINV = ROZKŁAD.CHI.ODW ## Zwraca odwrotność wartości jednostronnego prawdopodobieństwa rozkładu chi-kwadrat. +CHITEST = TEST.CHI ## Zwraca test niezależności. +CONFIDENCE = UFNOŚĆ ## Zwraca interwał ufności dla średniej populacji. +CORREL = WSP.KORELACJI ## Zwraca współczynnik korelacji dwóch zbiorów danych. +COUNT = ILE.LICZB ## Zlicza liczby znajdujące się na liście argumentów. +COUNTA = ILE.NIEPUSTYCH ## Zlicza wartości znajdujące się na liście argumentów. +COUNTBLANK = LICZ.PUSTE ## Zwraca liczbę pustych komórek w pewnym zakresie. +COUNTIF = LICZ.JEŻELI ## Zlicza komórki wewnątrz zakresu, które spełniają podane kryteria. +COUNTIFS = LICZ.WARUNKI ## Zlicza komórki wewnątrz zakresu, które spełniają wiele kryteriów. +COVAR = KOWARIANCJA ## Zwraca kowariancję, czyli średnią wartość iloczynów odpowiednich odchyleń. +CRITBINOM = PRÓG.ROZKŁAD.DWUM ## Zwraca najmniejszą wartość, dla której skumulowany rozkład dwumianowy jest mniejszy niż wartość kryterium lub równy jej. +DEVSQ = ODCH.KWADRATOWE ## Zwraca sumę kwadratów odchyleń. +EXPONDIST = ROZKŁAD.EXP ## Zwraca rozkład wykładniczy. +FDIST = ROZKŁAD.F ## Zwraca rozkład prawdopodobieństwa F. +FINV = ROZKŁAD.F.ODW ## Zwraca odwrotność rozkładu prawdopodobieństwa F. +FISHER = ROZKŁAD.FISHER ## Zwraca transformację Fishera. +FISHERINV = ROZKŁAD.FISHER.ODW ## Zwraca odwrotność transformacji Fishera. +FORECAST = REGLINX ## Zwraca wartość trendu liniowego. +FREQUENCY = CZĘSTOŚĆ ## Zwraca rozkład częstotliwości jako tablicę pionową. +FTEST = TEST.F ## Zwraca wynik testu F. +GAMMADIST = ROZKŁAD.GAMMA ## Zwraca rozkład gamma. +GAMMAINV = ROZKŁAD.GAMMA.ODW ## Zwraca odwrotność skumulowanego rozkładu gamma. +GAMMALN = ROZKŁAD.LIN.GAMMA ## Zwraca logarytm naturalny funkcji gamma, Γ(x). +GEOMEAN = ŚREDNIA.GEOMETRYCZNA ## Zwraca średnią geometryczną. +GROWTH = REGEXPW ## Zwraca wartości trendu wykładniczego. +HARMEAN = ŚREDNIA.HARMONICZNA ## Zwraca średnią harmoniczną. +HYPGEOMDIST = ROZKŁAD.HIPERGEOM ## Zwraca rozkład hipergeometryczny. +INTERCEPT = ODCIĘTA ## Zwraca punkt przecięcia osi pionowej z linią regresji liniowej. +KURT = KURTOZA ## Zwraca kurtozę zbioru danych. +LARGE = MAX.K ## Zwraca k-tą największą wartość ze zbioru danych. +LINEST = REGLINP ## Zwraca parametry trendu liniowego. +LOGEST = REGEXPP ## Zwraca parametry trendu wykładniczego. +LOGINV = ROZKŁAD.LOG.ODW ## Zwraca odwrotność rozkładu logarytmu naturalnego. +LOGNORMDIST = ROZKŁAD.LOG ## Zwraca skumulowany rozkład logarytmu naturalnego. +MAX = MAX ## Zwraca maksymalną wartość listy argumentów. +MAXA = MAX.A ## Zwraca maksymalną wartość listy argumentów, z uwzględnieniem liczb, tekstów i wartości logicznych. +MEDIAN = MEDIANA ## Zwraca medianę podanych liczb. +MIN = MIN ## Zwraca minimalną wartość listy argumentów. +MINA = MIN.A ## Zwraca najmniejszą wartość listy argumentów, z uwzględnieniem liczb, tekstów i wartości logicznych. +MODE = WYST.NAJCZĘŚCIEJ ## Zwraca wartość najczęściej występującą w zbiorze danych. +NEGBINOMDIST = ROZKŁAD.DWUM.PRZEC ## Zwraca ujemny rozkład dwumianowy. +NORMDIST = ROZKŁAD.NORMALNY ## Zwraca rozkład normalny skumulowany. +NORMINV = ROZKŁAD.NORMALNY.ODW ## Zwraca odwrotność rozkładu normalnego skumulowanego. +NORMSDIST = ROZKŁAD.NORMALNY.S ## Zwraca standardowy rozkład normalny skumulowany. +NORMSINV = ROZKŁAD.NORMALNY.S.ODW ## Zwraca odwrotność standardowego rozkładu normalnego skumulowanego. +PEARSON = PEARSON ## Zwraca współczynnik korelacji momentu iloczynu Pearsona. +PERCENTILE = PERCENTYL ## Wyznacza k-ty percentyl wartości w zakresie. +PERCENTRANK = PROCENT.POZYCJA ## Zwraca procentową pozycję wartości w zbiorze danych. +PERMUT = PERMUTACJE ## Zwraca liczbę permutacji dla danej liczby obiektów. +POISSON = ROZKŁAD.POISSON ## Zwraca rozkład Poissona. +PROB = PRAWDPD ## Zwraca prawdopodobieństwo, że wartości w zakresie leżą pomiędzy dwiema granicami. +QUARTILE = KWARTYL ## Wyznacza kwartyl zbioru danych. +RANK = POZYCJA ## Zwraca pozycję liczby na liście liczb. +RSQ = R.KWADRAT ## Zwraca kwadrat współczynnika korelacji momentu iloczynu Pearsona. +SKEW = SKOŚNOŚĆ ## Zwraca skośność rozkładu. +SLOPE = NACHYLENIE ## Zwraca nachylenie linii regresji liniowej. +SMALL = MIN.K ## Zwraca k-tą najmniejszą wartość ze zbioru danych. +STANDARDIZE = NORMALIZUJ ## Zwraca wartość znormalizowaną. +STDEV = ODCH.STANDARDOWE ## Szacuje odchylenie standardowe na podstawie próbki. +STDEVA = ODCH.STANDARDOWE.A ## Szacuje odchylenie standardowe na podstawie próbki, z uwzględnieniem liczb, tekstów i wartości logicznych. +STDEVP = ODCH.STANDARD.POPUL ## Oblicza odchylenie standardowe na podstawie całej populacji. +STDEVPA = ODCH.STANDARD.POPUL.A ## Oblicza odchylenie standardowe na podstawie całej populacji, z uwzględnieniem liczb, teksów i wartości logicznych. +STEYX = REGBŁSTD ## Zwraca błąd standardowy przewidzianej wartości y dla każdej wartości x w regresji. +TDIST = ROZKŁAD.T ## Zwraca rozkład t-Studenta. +TINV = ROZKŁAD.T.ODW ## Zwraca odwrotność rozkładu t-Studenta. +TREND = REGLINW ## Zwraca wartości trendu liniowego. +TRIMMEAN = ŚREDNIA.WEWN ## Zwraca średnią wartość dla wnętrza zbioru danych. +TTEST = TEST.T ## Zwraca prawdopodobieństwo związane z testem t-Studenta. +VAR = WARIANCJA ## Szacuje wariancję na podstawie próbki. +VARA = WARIANCJA.A ## Szacuje wariancję na podstawie próbki, z uwzględnieniem liczb, tekstów i wartości logicznych. +VARP = WARIANCJA.POPUL ## Oblicza wariancję na podstawie całej populacji. +VARPA = WARIANCJA.POPUL.A ## Oblicza wariancję na podstawie całej populacji, z uwzględnieniem liczb, tekstów i wartości logicznych. +WEIBULL = ROZKŁAD.WEIBULL ## Zwraca rozkład Weibulla. +ZTEST = TEST.Z ## Zwraca wartość jednostronnego prawdopodobieństwa testu z. + + +## +## Text functions Funkcje tekstowe +## +ASC = ASC ## Zamienia litery angielskie lub katakana o pełnej szerokości (dwubajtowe) w ciągu znaków na znaki o szerokości połówkowej (jednobajtowe). +BAHTTEXT = BAHTTEXT ## Konwertuje liczbę na tekst, stosując format walutowy ß (baht). +CHAR = ZNAK ## Zwraca znak o podanym numerze kodu. +CLEAN = OCZYŚĆ ## Usuwa z tekstu wszystkie znaki, które nie mogą być drukowane. +CODE = KOD ## Zwraca kod numeryczny pierwszego znaku w ciągu tekstowym. +CONCATENATE = ZŁĄCZ.TEKSTY ## Łączy kilka oddzielnych tekstów w jeden tekst. +DOLLAR = KWOTA ## Konwertuje liczbę na tekst, stosując format walutowy $ (dolar). +EXACT = PORÓWNAJ ## Sprawdza identyczność dwóch wartości tekstowych. +FIND = ZNAJDŹ ## Znajduje jedną wartość tekstową wewnątrz innej (z uwzględnieniem wielkich i małych liter). +FINDB = ZNAJDŹB ## Znajduje jedną wartość tekstową wewnątrz innej (z uwzględnieniem wielkich i małych liter). +FIXED = ZAOKR.DO.TEKST ## Formatuje liczbę jako tekst przy stałej liczbie miejsc dziesiętnych. +JIS = JIS ## Zmienia litery angielskie lub katakana o szerokości połówkowej (jednobajtowe) w ciągu znaków na znaki o pełnej szerokości (dwubajtowe). +LEFT = LEWY ## Zwraca skrajne lewe znaki z wartości tekstowej. +LEFTB = LEWYB ## Zwraca skrajne lewe znaki z wartości tekstowej. +LEN = DŁ ## Zwraca liczbę znaków ciągu tekstowego. +LENB = DŁ.B ## Zwraca liczbę znaków ciągu tekstowego. +LOWER = LITERY.MAŁE ## Konwertuje wielkie litery tekstu na małe litery. +MID = FRAGMENT.TEKSTU ## Zwraca określoną liczbę znaków z ciągu tekstowego, zaczynając od zadanej pozycji. +MIDB = FRAGMENT.TEKSTU.B ## Zwraca określoną liczbę znaków z ciągu tekstowego, zaczynając od zadanej pozycji. +PHONETIC = PHONETIC ## Wybiera znaki fonetyczne (furigana) z ciągu tekstowego. +PROPER = Z.WIELKIEJ.LITERY ## Zastępuje pierwszą literę każdego wyrazu tekstu wielką literą. +REPLACE = ZASTĄP ## Zastępuje znaki w tekście. +REPLACEB = ZASTĄP.B ## Zastępuje znaki w tekście. +REPT = POWT ## Powiela tekst daną liczbę razy. +RIGHT = PRAWY ## Zwraca skrajne prawe znaki z wartości tekstowej. +RIGHTB = PRAWYB ## Zwraca skrajne prawe znaki z wartości tekstowej. +SEARCH = SZUKAJ.TEKST ## Wyszukuje jedną wartość tekstową wewnątrz innej (bez uwzględniania wielkości liter). +SEARCHB = SZUKAJ.TEKST.B ## Wyszukuje jedną wartość tekstową wewnątrz innej (bez uwzględniania wielkości liter). +SUBSTITUTE = PODSTAW ## Podstawia nowy tekst w miejsce poprzedniego tekstu w ciągu tekstowym. +T = T ## Konwertuje argumenty na tekst. +TEXT = TEKST ## Formatuje liczbę i konwertuje ją na tekst. +TRIM = USUŃ.ZBĘDNE.ODSTĘPY ## Usuwa spacje z tekstu. +UPPER = LITERY.WIELKIE ## Konwertuje znaki tekstu na wielkie litery. +VALUE = WARTOŚĆ ## Konwertuje argument tekstowy na liczbę. diff --git a/lib/phpexcel/PHPExcel/locale/pt/br/config b/lib/phpexcel/PHPExcel/locale/pt/br/config new file mode 100644 index 0000000..b4bf704 --- /dev/null +++ b/lib/phpexcel/PHPExcel/locale/pt/br/config @@ -0,0 +1,47 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Settings +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## + + +ArgumentSeparator = ; + + +## +## (For future use) +## +currencySymbol = R$ + + +## +## Excel Error Codes (For future use) +## +NULL = #NULO! +DIV0 = #DIV/0! +VALUE = #VALOR! +REF = #REF! +NAME = #NOME? +NUM = #NÚM! +NA = #N/D diff --git a/lib/phpexcel/PHPExcel/locale/pt/br/functions b/lib/phpexcel/PHPExcel/locale/pt/br/functions new file mode 100644 index 0000000..f3ba3a3 --- /dev/null +++ b/lib/phpexcel/PHPExcel/locale/pt/br/functions @@ -0,0 +1,408 @@ +## +## Add-in and Automation functions Funções Suplemento e Automação +## +GETPIVOTDATA = INFODADOSTABELADINÂMICA ## Retorna os dados armazenados em um relatório de tabela dinâmica + + +## +## Cube functions Funções de Cubo +## +CUBEKPIMEMBER = MEMBROKPICUBO ## Retorna o nome de um KPI (indicador de desempenho-chave), uma propriedade e uma medida e exibe o nome e a propriedade na célula. Um KPI é uma medida quantificável, como o lucro bruto mensal ou a rotatividade trimestral dos funcionários, usada para monitorar o desempenho de uma organização. +CUBEMEMBER = MEMBROCUBO ## Retorna um membro ou tupla em uma hierarquia de cubo. Use para validar se o membro ou tupla existe no cubo. +CUBEMEMBERPROPERTY = PROPRIEDADEMEMBROCUBO ## Retorna o valor da propriedade de um membro no cubo. Usada para validar a existência do nome do membro no cubo e para retornar a propriedade especificada para esse membro. +CUBERANKEDMEMBER = MEMBROCLASSIFICADOCUBO ## Retorna o enésimo membro, ou o membro ordenado, em um conjunto. Use para retornar um ou mais elementos em um conjunto, assim como o melhor vendedor ou os dez melhores alunos. +CUBESET = CONJUNTOCUBO ## Define um conjunto calculado de membros ou tuplas enviando uma expressão do conjunto para o cubo no servidor, que cria o conjunto e o retorna para o Microsoft Office Excel. +CUBESETCOUNT = CONTAGEMCONJUNTOCUBO ## Retorna o número de itens em um conjunto. +CUBEVALUE = VALORCUBO ## Retorna um valor agregado de um cubo. + + +## +## Database functions Funções de banco de dados +## +DAVERAGE = BDMÉDIA ## Retorna a média das entradas selecionadas de um banco de dados +DCOUNT = BDCONTAR ## Conta as células que contêm números em um banco de dados +DCOUNTA = BDCONTARA ## Conta células não vazias em um banco de dados +DGET = BDEXTRAIR ## Extrai de um banco de dados um único registro que corresponde a um critério específico +DMAX = BDMÁX ## Retorna o valor máximo de entradas selecionadas de um banco de dados +DMIN = BDMÍN ## Retorna o valor mínimo de entradas selecionadas de um banco de dados +DPRODUCT = BDMULTIPL ## Multiplica os valores em um campo específico de registros que correspondem ao critério em um banco de dados +DSTDEV = BDEST ## Estima o desvio padrão com base em uma amostra de entradas selecionadas de um banco de dados +DSTDEVP = BDDESVPA ## Calcula o desvio padrão com base na população inteira de entradas selecionadas de um banco de dados +DSUM = BDSOMA ## Adiciona os números à coluna de campos de registros do banco de dados que correspondem ao critério +DVAR = BDVAREST ## Estima a variância com base em uma amostra de entradas selecionadas de um banco de dados +DVARP = BDVARP ## Calcula a variância com base na população inteira de entradas selecionadas de um banco de dados + + +## +## Date and time functions Funções de data e hora +## +DATE = DATA ## Retorna o número de série de uma data específica +DATEVALUE = DATA.VALOR ## Converte uma data na forma de texto para um número de série +DAY = DIA ## Converte um número de série em um dia do mês +DAYS360 = DIAS360 ## Calcula o número de dias entre duas datas com base em um ano de 360 dias +EDATE = DATAM ## Retorna o número de série da data que é o número indicado de meses antes ou depois da data inicial +EOMONTH = FIMMÊS ## Retorna o número de série do último dia do mês antes ou depois de um número especificado de meses +HOUR = HORA ## Converte um número de série em uma hora +MINUTE = MINUTO ## Converte um número de série em um minuto +MONTH = MÊS ## Converte um número de série em um mês +NETWORKDAYS = DIATRABALHOTOTAL ## Retorna o número de dias úteis inteiros entre duas datas +NOW = AGORA ## Retorna o número de série seqüencial da data e hora atuais +SECOND = SEGUNDO ## Converte um número de série em um segundo +TIME = HORA ## Retorna o número de série de uma hora específica +TIMEVALUE = VALOR.TEMPO ## Converte um horário na forma de texto para um número de série +TODAY = HOJE ## Retorna o número de série da data de hoje +WEEKDAY = DIA.DA.SEMANA ## Converte um número de série em um dia da semana +WEEKNUM = NÚMSEMANA ## Converte um número de série em um número que representa onde a semana cai numericamente em um ano +WORKDAY = DIATRABALHO ## Retorna o número de série da data antes ou depois de um número específico de dias úteis +YEAR = ANO ## Converte um número de série em um ano +YEARFRAC = FRAÇÃOANO ## Retorna a fração do ano que representa o número de dias entre data_inicial e data_final + + +## +## Engineering functions Funções de engenharia +## +BESSELI = BESSELI ## Retorna a função de Bessel In(x) modificada +BESSELJ = BESSELJ ## Retorna a função de Bessel Jn(x) +BESSELK = BESSELK ## Retorna a função de Bessel Kn(x) modificada +BESSELY = BESSELY ## Retorna a função de Bessel Yn(x) +BIN2DEC = BIN2DEC ## Converte um número binário em decimal +BIN2HEX = BIN2HEX ## Converte um número binário em hexadecimal +BIN2OCT = BIN2OCT ## Converte um número binário em octal +COMPLEX = COMPLEX ## Converte coeficientes reais e imaginários e um número complexo +CONVERT = CONVERTER ## Converte um número de um sistema de medida para outro +DEC2BIN = DECABIN ## Converte um número decimal em binário +DEC2HEX = DECAHEX ## Converte um número decimal em hexadecimal +DEC2OCT = DECAOCT ## Converte um número decimal em octal +DELTA = DELTA ## Testa se dois valores são iguais +ERF = FUNERRO ## Retorna a função de erro +ERFC = FUNERROCOMPL ## Retorna a função de erro complementar +GESTEP = DEGRAU ## Testa se um número é maior do que um valor limite +HEX2BIN = HEXABIN ## Converte um número hexadecimal em binário +HEX2DEC = HEXADEC ## Converte um número hexadecimal em decimal +HEX2OCT = HEXAOCT ## Converte um número hexadecimal em octal +IMABS = IMABS ## Retorna o valor absoluto (módulo) de um número complexo +IMAGINARY = IMAGINÁRIO ## Retorna o coeficiente imaginário de um número complexo +IMARGUMENT = IMARG ## Retorna o argumento teta, um ângulo expresso em radianos +IMCONJUGATE = IMCONJ ## Retorna o conjugado complexo de um número complexo +IMCOS = IMCOS ## Retorna o cosseno de um número complexo +IMDIV = IMDIV ## Retorna o quociente de dois números complexos +IMEXP = IMEXP ## Retorna o exponencial de um número complexo +IMLN = IMLN ## Retorna o logaritmo natural de um número complexo +IMLOG10 = IMLOG10 ## Retorna o logaritmo de base 10 de um número complexo +IMLOG2 = IMLOG2 ## Retorna o logaritmo de base 2 de um número complexo +IMPOWER = IMPOT ## Retorna um número complexo elevado a uma potência inteira +IMPRODUCT = IMPROD ## Retorna o produto de números complexos +IMREAL = IMREAL ## Retorna o coeficiente real de um número complexo +IMSIN = IMSENO ## Retorna o seno de um número complexo +IMSQRT = IMRAIZ ## Retorna a raiz quadrada de um número complexo +IMSUB = IMSUBTR ## Retorna a diferença entre dois números complexos +IMSUM = IMSOMA ## Retorna a soma de números complexos +OCT2BIN = OCTABIN ## Converte um número octal em binário +OCT2DEC = OCTADEC ## Converte um número octal em decimal +OCT2HEX = OCTAHEX ## Converte um número octal em hexadecimal + + +## +## Financial functions Funções financeiras +## +ACCRINT = JUROSACUM ## Retorna a taxa de juros acumulados de um título que paga uma taxa periódica de juros +ACCRINTM = JUROSACUMV ## Retorna os juros acumulados de um título que paga juros no vencimento +AMORDEGRC = AMORDEGRC ## Retorna a depreciação para cada período contábil usando o coeficiente de depreciação +AMORLINC = AMORLINC ## Retorna a depreciação para cada período contábil +COUPDAYBS = CUPDIASINLIQ ## Retorna o número de dias do início do período de cupom até a data de liquidação +COUPDAYS = CUPDIAS ## Retorna o número de dias no período de cupom que contém a data de quitação +COUPDAYSNC = CUPDIASPRÓX ## Retorna o número de dias da data de liquidação até a data do próximo cupom +COUPNCD = CUPDATAPRÓX ## Retorna a próxima data de cupom após a data de quitação +COUPNUM = CUPNÚM ## Retorna o número de cupons pagáveis entre as datas de quitação e vencimento +COUPPCD = CUPDATAANT ## Retorna a data de cupom anterior à data de quitação +CUMIPMT = PGTOJURACUM ## Retorna os juros acumulados pagos entre dois períodos +CUMPRINC = PGTOCAPACUM ## Retorna o capital acumulado pago sobre um empréstimo entre dois períodos +DB = BD ## Retorna a depreciação de um ativo para um período especificado, usando o método de balanço de declínio fixo +DDB = BDD ## Retorna a depreciação de um ativo com relação a um período especificado usando o método de saldos decrescentes duplos ou qualquer outro método especificado por você +DISC = DESC ## Retorna a taxa de desconto de um título +DOLLARDE = MOEDADEC ## Converte um preço em formato de moeda, na forma fracionária, em um preço na forma decimal +DOLLARFR = MOEDAFRA ## Converte um preço, apresentado na forma decimal, em um preço apresentado na forma fracionária +DURATION = DURAÇÃO ## Retorna a duração anual de um título com pagamentos de juros periódicos +EFFECT = EFETIVA ## Retorna a taxa de juros anual efetiva +FV = VF ## Retorna o valor futuro de um investimento +FVSCHEDULE = VFPLANO ## Retorna o valor futuro de um capital inicial após a aplicação de uma série de taxas de juros compostas +INTRATE = TAXAJUROS ## Retorna a taxa de juros de um título totalmente investido +IPMT = IPGTO ## Retorna o pagamento de juros para um investimento em um determinado período +IRR = TIR ## Retorna a taxa interna de retorno de uma série de fluxos de caixa +ISPMT = ÉPGTO ## Calcula os juros pagos durante um período específico de um investimento +MDURATION = MDURAÇÃO ## Retorna a duração de Macauley modificada para um título com um valor de paridade equivalente a R$ 100 +MIRR = MTIR ## Calcula a taxa interna de retorno em que fluxos de caixa positivos e negativos são financiados com diferentes taxas +NOMINAL = NOMINAL ## Retorna a taxa de juros nominal anual +NPER = NPER ## Retorna o número de períodos de um investimento +NPV = VPL ## Retorna o valor líquido atual de um investimento com base em uma série de fluxos de caixa periódicos e em uma taxa de desconto +ODDFPRICE = PREÇOPRIMINC ## Retorna o preço por R$ 100 de valor nominal de um título com um primeiro período indefinido +ODDFYIELD = LUCROPRIMINC ## Retorna o rendimento de um título com um primeiro período indefinido +ODDLPRICE = PREÇOÚLTINC ## Retorna o preço por R$ 100 de valor nominal de um título com um último período de cupom indefinido +ODDLYIELD = LUCROÚLTINC ## Retorna o rendimento de um título com um último período indefinido +PMT = PGTO ## Retorna o pagamento periódico de uma anuidade +PPMT = PPGTO ## Retorna o pagamento de capital para determinado período de investimento +PRICE = PREÇO ## Retorna a preço por R$ 100,00 de valor nominal de um título que paga juros periódicos +PRICEDISC = PREÇODESC ## Retorna o preço por R$ 100,00 de valor nominal de um título descontado +PRICEMAT = PREÇOVENC ## Retorna o preço por R$ 100,00 de valor nominal de um título que paga juros no vencimento +PV = VP ## Retorna o valor presente de um investimento +RATE = TAXA ## Retorna a taxa de juros por período de uma anuidade +RECEIVED = RECEBER ## Retorna a quantia recebida no vencimento de um título totalmente investido +SLN = DPD ## Retorna a depreciação em linha reta de um ativo durante um período +SYD = SDA ## Retorna a depreciação dos dígitos da soma dos anos de um ativo para um período especificado +TBILLEQ = OTN ## Retorna o rendimento de um título equivalente a uma obrigação do Tesouro +TBILLPRICE = OTNVALOR ## Retorna o preço por R$ 100,00 de valor nominal de uma obrigação do Tesouro +TBILLYIELD = OTNLUCRO ## Retorna o rendimento de uma obrigação do Tesouro +VDB = BDV ## Retorna a depreciação de um ativo para um período especificado ou parcial usando um método de balanço declinante +XIRR = XTIR ## Fornece a taxa interna de retorno para um programa de fluxos de caixa que não é necessariamente periódico +XNPV = XVPL ## Retorna o valor presente líquido de um programa de fluxos de caixa que não é necessariamente periódico +YIELD = LUCRO ## Retorna o lucro de um título que paga juros periódicos +YIELDDISC = LUCRODESC ## Retorna o rendimento anual de um título descontado. Por exemplo, uma obrigação do Tesouro +YIELDMAT = LUCROVENC ## Retorna o lucro anual de um título que paga juros no vencimento + + +## +## Information functions Funções de informação +## +CELL = CÉL ## Retorna informações sobre formatação, localização ou conteúdo de uma célula +ERROR.TYPE = TIPO.ERRO ## Retorna um número correspondente a um tipo de erro +INFO = INFORMAÇÃO ## Retorna informações sobre o ambiente operacional atual +ISBLANK = ÉCÉL.VAZIA ## Retorna VERDADEIRO se o valor for vazio +ISERR = ÉERRO ## Retorna VERDADEIRO se o valor for um valor de erro diferente de #N/D +ISERROR = ÉERROS ## Retorna VERDADEIRO se o valor for um valor de erro +ISEVEN = ÉPAR ## Retorna VERDADEIRO se o número for par +ISLOGICAL = ÉLÓGICO ## Retorna VERDADEIRO se o valor for um valor lógico +ISNA = É.NÃO.DISP ## Retorna VERDADEIRO se o valor for o valor de erro #N/D +ISNONTEXT = É.NÃO.TEXTO ## Retorna VERDADEIRO se o valor for diferente de texto +ISNUMBER = ÉNÚM ## Retorna VERDADEIRO se o valor for um número +ISODD = ÉIMPAR ## Retorna VERDADEIRO se o número for ímpar +ISREF = ÉREF ## Retorna VERDADEIRO se o valor for uma referência +ISTEXT = ÉTEXTO ## Retorna VERDADEIRO se o valor for texto +N = N ## Retorna um valor convertido em um número +NA = NÃO.DISP ## Retorna o valor de erro #N/D +TYPE = TIPO ## Retorna um número indicando o tipo de dados de um valor + + +## +## Logical functions Funções lógicas +## +AND = E ## Retorna VERDADEIRO se todos os seus argumentos forem VERDADEIROS +FALSE = FALSO ## Retorna o valor lógico FALSO +IF = SE ## Especifica um teste lógico a ser executado +IFERROR = SEERRO ## Retornará um valor que você especifica se uma fórmula for avaliada para um erro; do contrário, retornará o resultado da fórmula +NOT = NÃO ## Inverte o valor lógico do argumento +OR = OU ## Retorna VERDADEIRO se um dos argumentos for VERDADEIRO +TRUE = VERDADEIRO ## Retorna o valor lógico VERDADEIRO + + +## +## Lookup and reference functions Funções de pesquisa e referência +## +ADDRESS = ENDEREÇO ## Retorna uma referência como texto para uma única célula em uma planilha +AREAS = ÁREAS ## Retorna o número de áreas em uma referência +CHOOSE = ESCOLHER ## Escolhe um valor a partir de uma lista de valores +COLUMN = COL ## Retorna o número da coluna de uma referência +COLUMNS = COLS ## Retorna o número de colunas em uma referência +HLOOKUP = PROCH ## Procura na linha superior de uma matriz e retorna o valor da célula especificada +HYPERLINK = HYPERLINK ## Cria um atalho ou salto que abre um documento armazenado em um servidor de rede, uma intranet ou na Internet +INDEX = ÍNDICE ## Usa um índice para escolher um valor de uma referência ou matriz +INDIRECT = INDIRETO ## Retorna uma referência indicada por um valor de texto +LOOKUP = PROC ## Procura valores em um vetor ou em uma matriz +MATCH = CORRESP ## Procura valores em uma referência ou em uma matriz +OFFSET = DESLOC ## Retorna um deslocamento de referência com base em uma determinada referência +ROW = LIN ## Retorna o número da linha de uma referência +ROWS = LINS ## Retorna o número de linhas em uma referência +RTD = RTD ## Recupera dados em tempo real de um programa que ofereça suporte a automação COM (automação: uma forma de trabalhar com objetos de um aplicativo a partir de outro aplicativo ou ferramenta de desenvolvimento. Chamada inicialmente de automação OLE, a automação é um padrão industrial e um recurso do modelo de objeto componente (COM).) +TRANSPOSE = TRANSPOR ## Retorna a transposição de uma matriz +VLOOKUP = PROCV ## Procura na primeira coluna de uma matriz e move ao longo da linha para retornar o valor de uma célula + + +## +## Math and trigonometry functions Funções matemáticas e trigonométricas +## +ABS = ABS ## Retorna o valor absoluto de um número +ACOS = ACOS ## Retorna o arco cosseno de um número +ACOSH = ACOSH ## Retorna o cosseno hiperbólico inverso de um número +ASIN = ASEN ## Retorna o arco seno de um número +ASINH = ASENH ## Retorna o seno hiperbólico inverso de um número +ATAN = ATAN ## Retorna o arco tangente de um número +ATAN2 = ATAN2 ## Retorna o arco tangente das coordenadas x e y especificadas +ATANH = ATANH ## Retorna a tangente hiperbólica inversa de um número +CEILING = TETO ## Arredonda um número para o inteiro mais próximo ou para o múltiplo mais próximo de significância +COMBIN = COMBIN ## Retorna o número de combinações de um determinado número de objetos +COS = COS ## Retorna o cosseno de um número +COSH = COSH ## Retorna o cosseno hiperbólico de um número +DEGREES = GRAUS ## Converte radianos em graus +EVEN = PAR ## Arredonda um número para cima até o inteiro par mais próximo +EXP = EXP ## Retorna e elevado à potência de um número especificado +FACT = FATORIAL ## Retorna o fatorial de um número +FACTDOUBLE = FATDUPLO ## Retorna o fatorial duplo de um número +FLOOR = ARREDMULTB ## Arredonda um número para baixo até zero +GCD = MDC ## Retorna o máximo divisor comum +INT = INT ## Arredonda um número para baixo até o número inteiro mais próximo +LCM = MMC ## Retorna o mínimo múltiplo comum +LN = LN ## Retorna o logaritmo natural de um número +LOG = LOG ## Retorna o logaritmo de um número de uma base especificada +LOG10 = LOG10 ## Retorna o logaritmo de base 10 de um número +MDETERM = MATRIZ.DETERM ## Retorna o determinante de uma matriz de uma variável do tipo matriz +MINVERSE = MATRIZ.INVERSO ## Retorna a matriz inversa de uma matriz +MMULT = MATRIZ.MULT ## Retorna o produto de duas matrizes +MOD = RESTO ## Retorna o resto da divisão +MROUND = MARRED ## Retorna um número arredondado ao múltiplo desejado +MULTINOMIAL = MULTINOMIAL ## Retorna o multinomial de um conjunto de números +ODD = ÍMPAR ## Arredonda um número para cima até o inteiro ímpar mais próximo +PI = PI ## Retorna o valor de Pi +POWER = POTÊNCIA ## Fornece o resultado de um número elevado a uma potência +PRODUCT = MULT ## Multiplica seus argumentos +QUOTIENT = QUOCIENTE ## Retorna a parte inteira de uma divisão +RADIANS = RADIANOS ## Converte graus em radianos +RAND = ALEATÓRIO ## Retorna um número aleatório entre 0 e 1 +RANDBETWEEN = ALEATÓRIOENTRE ## Retorna um número aleatório entre os números especificados +ROMAN = ROMANO ## Converte um algarismo arábico em romano, como texto +ROUND = ARRED ## Arredonda um número até uma quantidade especificada de dígitos +ROUNDDOWN = ARREDONDAR.PARA.BAIXO ## Arredonda um número para baixo até zero +ROUNDUP = ARREDONDAR.PARA.CIMA ## Arredonda um número para cima, afastando-o de zero +SERIESSUM = SOMASEQÜÊNCIA ## Retorna a soma de uma série polinomial baseada na fórmula +SIGN = SINAL ## Retorna o sinal de um número +SIN = SEN ## Retorna o seno de um ângulo dado +SINH = SENH ## Retorna o seno hiperbólico de um número +SQRT = RAIZ ## Retorna uma raiz quadrada positiva +SQRTPI = RAIZPI ## Retorna a raiz quadrada de (núm* pi) +SUBTOTAL = SUBTOTAL ## Retorna um subtotal em uma lista ou em um banco de dados +SUM = SOMA ## Soma seus argumentos +SUMIF = SOMASE ## Adiciona as células especificadas por um determinado critério +SUMIFS = SOMASE ## Adiciona as células em um intervalo que atende a vários critérios +SUMPRODUCT = SOMARPRODUTO ## Retorna a soma dos produtos de componentes correspondentes de matrizes +SUMSQ = SOMAQUAD ## Retorna a soma dos quadrados dos argumentos +SUMX2MY2 = SOMAX2DY2 ## Retorna a soma da diferença dos quadrados dos valores correspondentes em duas matrizes +SUMX2PY2 = SOMAX2SY2 ## Retorna a soma da soma dos quadrados dos valores correspondentes em duas matrizes +SUMXMY2 = SOMAXMY2 ## Retorna a soma dos quadrados das diferenças dos valores correspondentes em duas matrizes +TAN = TAN ## Retorna a tangente de um número +TANH = TANH ## Retorna a tangente hiperbólica de um número +TRUNC = TRUNCAR ## Trunca um número para um inteiro + + +## +## Statistical functions Funções estatísticas +## +AVEDEV = DESV.MÉDIO ## Retorna a média aritmética dos desvios médios dos pontos de dados a partir de sua média +AVERAGE = MÉDIA ## Retorna a média dos argumentos +AVERAGEA = MÉDIAA ## Retorna a média dos argumentos, inclusive números, texto e valores lógicos +AVERAGEIF = MÉDIASE ## Retorna a média (média aritmética) de todas as células em um intervalo que atendem a um determinado critério +AVERAGEIFS = MÉDIASES ## Retorna a média (média aritmética) de todas as células que atendem a múltiplos critérios. +BETADIST = DISTBETA ## Retorna a função de distribuição cumulativa beta +BETAINV = BETA.ACUM.INV ## Retorna o inverso da função de distribuição cumulativa para uma distribuição beta especificada +BINOMDIST = DISTRBINOM ## Retorna a probabilidade de distribuição binomial do termo individual +CHIDIST = DIST.QUI ## Retorna a probabilidade unicaudal da distribuição qui-quadrada +CHIINV = INV.QUI ## Retorna o inverso da probabilidade uni-caudal da distribuição qui-quadrada +CHITEST = TESTE.QUI ## Retorna o teste para independência +CONFIDENCE = INT.CONFIANÇA ## Retorna o intervalo de confiança para uma média da população +CORREL = CORREL ## Retorna o coeficiente de correlação entre dois conjuntos de dados +COUNT = CONT.NÚM ## Calcula quantos números há na lista de argumentos +COUNTA = CONT.VALORES ## Calcula quantos valores há na lista de argumentos +COUNTBLANK = CONTAR.VAZIO ## Conta o número de células vazias no intervalo especificado +COUNTIF = CONT.SE ## Calcula o número de células não vazias em um intervalo que corresponde a determinados critérios +COUNTIFS = CONT.SES ## Conta o número de células dentro de um intervalo que atende a múltiplos critérios +COVAR = COVAR ## Retorna a covariância, a média dos produtos dos desvios pares +CRITBINOM = CRIT.BINOM ## Retorna o menor valor para o qual a distribuição binomial cumulativa é menor ou igual ao valor padrão +DEVSQ = DESVQ ## Retorna a soma dos quadrados dos desvios +EXPONDIST = DISTEXPON ## Retorna a distribuição exponencial +FDIST = DISTF ## Retorna a distribuição de probabilidade F +FINV = INVF ## Retorna o inverso da distribuição de probabilidades F +FISHER = FISHER ## Retorna a transformação Fisher +FISHERINV = FISHERINV ## Retorna o inverso da transformação Fisher +FORECAST = PREVISÃO ## Retorna um valor ao longo de uma linha reta +FREQUENCY = FREQÜÊNCIA ## Retorna uma distribuição de freqüência como uma matriz vertical +FTEST = TESTEF ## Retorna o resultado de um teste F +GAMMADIST = DISTGAMA ## Retorna a distribuição gama +GAMMAINV = INVGAMA ## Retorna o inverso da distribuição cumulativa gama +GAMMALN = LNGAMA ## Retorna o logaritmo natural da função gama, G(x) +GEOMEAN = MÉDIA.GEOMÉTRICA ## Retorna a média geométrica +GROWTH = CRESCIMENTO ## Retorna valores ao longo de uma tendência exponencial +HARMEAN = MÉDIA.HARMÔNICA ## Retorna a média harmônica +HYPGEOMDIST = DIST.HIPERGEOM ## Retorna a distribuição hipergeométrica +INTERCEPT = INTERCEPÇÃO ## Retorna a intercepção da linha de regressão linear +KURT = CURT ## Retorna a curtose de um conjunto de dados +LARGE = MAIOR ## Retorna o maior valor k-ésimo de um conjunto de dados +LINEST = PROJ.LIN ## Retorna os parâmetros de uma tendência linear +LOGEST = PROJ.LOG ## Retorna os parâmetros de uma tendência exponencial +LOGINV = INVLOG ## Retorna o inverso da distribuição lognormal +LOGNORMDIST = DIST.LOGNORMAL ## Retorna a distribuição lognormal cumulativa +MAX = MÁXIMO ## Retorna o valor máximo em uma lista de argumentos +MAXA = MÁXIMOA ## Retorna o maior valor em uma lista de argumentos, inclusive números, texto e valores lógicos +MEDIAN = MED ## Retorna a mediana dos números indicados +MIN = MÍNIMO ## Retorna o valor mínimo em uma lista de argumentos +MINA = MÍNIMOA ## Retorna o menor valor em uma lista de argumentos, inclusive números, texto e valores lógicos +MODE = MODO ## Retorna o valor mais comum em um conjunto de dados +NEGBINOMDIST = DIST.BIN.NEG ## Retorna a distribuição binomial negativa +NORMDIST = DIST.NORM ## Retorna a distribuição cumulativa normal +NORMINV = INV.NORM ## Retorna o inverso da distribuição cumulativa normal +NORMSDIST = DIST.NORMP ## Retorna a distribuição cumulativa normal padrão +NORMSINV = INV.NORMP ## Retorna o inverso da distribuição cumulativa normal padrão +PEARSON = PEARSON ## Retorna o coeficiente de correlação do momento do produto Pearson +PERCENTILE = PERCENTIL ## Retorna o k-ésimo percentil de valores em um intervalo +PERCENTRANK = ORDEM.PORCENTUAL ## Retorna a ordem percentual de um valor em um conjunto de dados +PERMUT = PERMUT ## Retorna o número de permutações de um determinado número de objetos +POISSON = POISSON ## Retorna a distribuição Poisson +PROB = PROB ## Retorna a probabilidade de valores em um intervalo estarem entre dois limites +QUARTILE = QUARTIL ## Retorna o quartil do conjunto de dados +RANK = ORDEM ## Retorna a posição de um número em uma lista de números +RSQ = RQUAD ## Retorna o quadrado do coeficiente de correlação do momento do produto de Pearson +SKEW = DISTORÇÃO ## Retorna a distorção de uma distribuição +SLOPE = INCLINAÇÃO ## Retorna a inclinação da linha de regressão linear +SMALL = MENOR ## Retorna o menor valor k-ésimo do conjunto de dados +STANDARDIZE = PADRONIZAR ## Retorna um valor normalizado +STDEV = DESVPAD ## Estima o desvio padrão com base em uma amostra +STDEVA = DESVPADA ## Estima o desvio padrão com base em uma amostra, inclusive números, texto e valores lógicos +STDEVP = DESVPADP ## Calcula o desvio padrão com base na população total +STDEVPA = DESVPADPA ## Calcula o desvio padrão com base na população total, inclusive números, texto e valores lógicos +STEYX = EPADYX ## Retorna o erro padrão do valor-y previsto para cada x da regressão +TDIST = DISTT ## Retorna a distribuição t de Student +TINV = INVT ## Retorna o inverso da distribuição t de Student +TREND = TENDÊNCIA ## Retorna valores ao longo de uma tendência linear +TRIMMEAN = MÉDIA.INTERNA ## Retorna a média do interior de um conjunto de dados +TTEST = TESTET ## Retorna a probabilidade associada ao teste t de Student +VAR = VAR ## Estima a variância com base em uma amostra +VARA = VARA ## Estima a variância com base em uma amostra, inclusive números, texto e valores lógicos +VARP = VARP ## Calcula a variância com base na população inteira +VARPA = VARPA ## Calcula a variância com base na população total, inclusive números, texto e valores lógicos +WEIBULL = WEIBULL ## Retorna a distribuição Weibull +ZTEST = TESTEZ ## Retorna o valor de probabilidade uni-caudal de um teste-z + + +## +## Text functions Funções de texto +## +ASC = ASC ## Altera letras do inglês ou katakana de largura total (bytes duplos) dentro de uma seqüência de caracteres para caracteres de meia largura (byte único) +BAHTTEXT = BAHTTEXT ## Converte um número em um texto, usando o formato de moeda ß (baht) +CHAR = CARACT ## Retorna o caractere especificado pelo número de código +CLEAN = TIRAR ## Remove todos os caracteres do texto que não podem ser impressos +CODE = CÓDIGO ## Retorna um código numérico para o primeiro caractere de uma seqüência de caracteres de texto +CONCATENATE = CONCATENAR ## Agrupa vários itens de texto em um único item de texto +DOLLAR = MOEDA ## Converte um número em texto, usando o formato de moeda $ (dólar) +EXACT = EXATO ## Verifica se dois valores de texto são idênticos +FIND = PROCURAR ## Procura um valor de texto dentro de outro (diferencia maiúsculas de minúsculas) +FINDB = PROCURARB ## Procura um valor de texto dentro de outro (diferencia maiúsculas de minúsculas) +FIXED = DEF.NÚM.DEC ## Formata um número como texto com um número fixo de decimais +JIS = JIS ## Altera letras do inglês ou katakana de meia largura (byte único) dentro de uma seqüência de caracteres para caracteres de largura total (bytes duplos) +LEFT = ESQUERDA ## Retorna os caracteres mais à esquerda de um valor de texto +LEFTB = ESQUERDAB ## Retorna os caracteres mais à esquerda de um valor de texto +LEN = NÚM.CARACT ## Retorna o número de caracteres em uma seqüência de texto +LENB = NÚM.CARACTB ## Retorna o número de caracteres em uma seqüência de texto +LOWER = MINÚSCULA ## Converte texto para minúsculas +MID = EXT.TEXTO ## Retorna um número específico de caracteres de uma seqüência de texto começando na posição especificada +MIDB = EXT.TEXTOB ## Retorna um número específico de caracteres de uma seqüência de texto começando na posição especificada +PHONETIC = FONÉTICA ## Extrai os caracteres fonéticos (furigana) de uma seqüência de caracteres de texto +PROPER = PRI.MAIÚSCULA ## Coloca a primeira letra de cada palavra em maiúscula em um valor de texto +REPLACE = MUDAR ## Muda os caracteres dentro do texto +REPLACEB = MUDARB ## Muda os caracteres dentro do texto +REPT = REPT ## Repete o texto um determinado número de vezes +RIGHT = DIREITA ## Retorna os caracteres mais à direita de um valor de texto +RIGHTB = DIREITAB ## Retorna os caracteres mais à direita de um valor de texto +SEARCH = LOCALIZAR ## Localiza um valor de texto dentro de outro (não diferencia maiúsculas de minúsculas) +SEARCHB = LOCALIZARB ## Localiza um valor de texto dentro de outro (não diferencia maiúsculas de minúsculas) +SUBSTITUTE = SUBSTITUIR ## Substitui um novo texto por um texto antigo em uma seqüência de texto +T = T ## Converte os argumentos em texto +TEXT = TEXTO ## Formata um número e o converte em texto +TRIM = ARRUMAR ## Remove espaços do texto +UPPER = MAIÚSCULA ## Converte o texto em maiúsculas +VALUE = VALOR ## Converte um argumento de texto em um número diff --git a/lib/phpexcel/PHPExcel/locale/pt/config b/lib/phpexcel/PHPExcel/locale/pt/config new file mode 100644 index 0000000..60b422b --- /dev/null +++ b/lib/phpexcel/PHPExcel/locale/pt/config @@ -0,0 +1,47 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Settings +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## + + +ArgumentSeparator = ; + + +## +## (For future use) +## +currencySymbol = € + + +## +## Excel Error Codes (For future use) +## +NULL = #NULO! +DIV0 = #DIV/0! +VALUE = #VALOR! +REF = #REF! +NAME = #NOME? +NUM = #NÚM! +NA = #N/D diff --git a/lib/phpexcel/PHPExcel/locale/pt/functions b/lib/phpexcel/PHPExcel/locale/pt/functions new file mode 100644 index 0000000..7fe9e3b --- /dev/null +++ b/lib/phpexcel/PHPExcel/locale/pt/functions @@ -0,0 +1,408 @@ +## +## Add-in and Automation functions Funções de Suplemento e Automatização +## +GETPIVOTDATA = OBTERDADOSDIN ## Devolve dados armazenados num relatório de Tabela Dinâmica + + +## +## Cube functions Funções de cubo +## +CUBEKPIMEMBER = MEMBROKPICUBO ## Devolve o nome, propriedade e medição de um KPI (key performance indicator) e apresenta o nome e a propriedade na célula. Um KPI é uma medida quantificável, como, por exemplo, o lucro mensal bruto ou a rotatividade trimestral de pessoal, utilizada para monitorizar o desempenho de uma organização. +CUBEMEMBER = MEMBROCUBO ## Devolve um membro ou cadeia de identificação numa hierarquia de cubo. Utilizada para validar a existência do membro ou cadeia de identificação no cubo. +CUBEMEMBERPROPERTY = PROPRIEDADEMEMBROCUBO ## Devolve o valor de uma propriedade de membro no cubo. Utilizada para validar a existência de um nome de membro no cubo e para devolver a propriedade especificada para esse membro. +CUBERANKEDMEMBER = MEMBROCLASSIFICADOCUBO ## Devolve o enésimo ou a classificação mais alta num conjunto. Utilizada para devolver um ou mais elementos num conjunto, tal como o melhor vendedor ou os 10 melhores alunos. +CUBESET = CONJUNTOCUBO ## Define um conjunto calculado de membros ou cadeias de identificação enviando uma expressão de conjunto para o cubo no servidor, que cria o conjunto e, em seguida, devolve o conjunto ao Microsoft Office Excel. +CUBESETCOUNT = CONTARCONJUNTOCUBO ## Devolve o número de itens num conjunto. +CUBEVALUE = VALORCUBO ## Devolve um valor agregado do cubo. + + +## +## Database functions Funções de base de dados +## +DAVERAGE = BDMÉDIA ## Devolve a média das entradas da base de dados seleccionadas +DCOUNT = BDCONTAR ## Conta as células que contêm números numa base de dados +DCOUNTA = BDCONTAR.VAL ## Conta as células que não estejam em branco numa base de dados +DGET = BDOBTER ## Extrai de uma base de dados um único registo que corresponde aos critérios especificados +DMAX = BDMÁX ## Devolve o valor máximo das entradas da base de dados seleccionadas +DMIN = BDMÍN ## Devolve o valor mínimo das entradas da base de dados seleccionadas +DPRODUCT = BDMULTIPL ## Multiplica os valores de um determinado campo de registos que correspondem aos critérios numa base de dados +DSTDEV = BDDESVPAD ## Calcula o desvio-padrão com base numa amostra de entradas da base de dados seleccionadas +DSTDEVP = BDDESVPADP ## Calcula o desvio-padrão com base na população total das entradas da base de dados seleccionadas +DSUM = BDSOMA ## Adiciona os números na coluna de campo dos registos de base de dados que correspondem aos critérios +DVAR = BDVAR ## Calcula a variância com base numa amostra das entradas de base de dados seleccionadas +DVARP = BDVARP ## Calcula a variância com base na população total das entradas de base de dados seleccionadas + + +## +## Date and time functions Funções de data e hora +## +DATE = DATA ## Devolve o número de série de uma determinada data +DATEVALUE = DATA.VALOR ## Converte uma data em forma de texto num número de série +DAY = DIA ## Converte um número de série num dia do mês +DAYS360 = DIAS360 ## Calcula o número de dias entre duas datas com base num ano com 360 dias +EDATE = DATAM ## Devolve um número de série de data que corresponde ao número de meses indicado antes ou depois da data de início +EOMONTH = FIMMÊS ## Devolve o número de série do último dia do mês antes ou depois de um número de meses especificado +HOUR = HORA ## Converte um número de série numa hora +MINUTE = MINUTO ## Converte um número de série num minuto +MONTH = MÊS ## Converte um número de série num mês +NETWORKDAYS = DIATRABALHOTOTAL ## Devolve o número total de dias úteis entre duas datas +NOW = AGORA ## Devolve o número de série da data e hora actuais +SECOND = SEGUNDO ## Converte um número de série num segundo +TIME = TEMPO ## Devolve o número de série de um determinado tempo +TIMEVALUE = VALOR.TEMPO ## Converte um tempo em forma de texto num número de série +TODAY = HOJE ## Devolve o número de série da data actual +WEEKDAY = DIA.SEMANA ## Converte um número de série num dia da semana +WEEKNUM = NÚMSEMANA ## Converte um número de série num número que representa o número da semana num determinado ano +WORKDAY = DIA.TRABALHO ## Devolve o número de série da data antes ou depois de um número de dias úteis especificado +YEAR = ANO ## Converte um número de série num ano +YEARFRAC = FRACÇÃOANO ## Devolve a fracção de ano que representa o número de dias inteiros entre a data_de_início e a data_de_fim + + +## +## Engineering functions Funções de engenharia +## +BESSELI = BESSELI ## Devolve a função de Bessel modificada In(x) +BESSELJ = BESSELJ ## Devolve a função de Bessel Jn(x) +BESSELK = BESSELK ## Devolve a função de Bessel modificada Kn(x) +BESSELY = BESSELY ## Devolve a função de Bessel Yn(x) +BIN2DEC = BINADEC ## Converte um número binário em decimal +BIN2HEX = BINAHEX ## Converte um número binário em hexadecimal +BIN2OCT = BINAOCT ## Converte um número binário em octal +COMPLEX = COMPLEXO ## Converte coeficientes reais e imaginários num número complexo +CONVERT = CONVERTER ## Converte um número de um sistema de medida noutro +DEC2BIN = DECABIN ## Converte um número decimal em binário +DEC2HEX = DECAHEX ## Converte um número decimal em hexadecimal +DEC2OCT = DECAOCT ## Converte um número decimal em octal +DELTA = DELTA ## Testa se dois valores são iguais +ERF = FUNCERRO ## Devolve a função de erro +ERFC = FUNCERROCOMPL ## Devolve a função de erro complementar +GESTEP = DEGRAU ## Testa se um número é maior do que um valor limite +HEX2BIN = HEXABIN ## Converte um número hexadecimal em binário +HEX2DEC = HEXADEC ## Converte um número hexadecimal em decimal +HEX2OCT = HEXAOCT ## Converte um número hexadecimal em octal +IMABS = IMABS ## Devolve o valor absoluto (módulo) de um número complexo +IMAGINARY = IMAGINÁRIO ## Devolve o coeficiente imaginário de um número complexo +IMARGUMENT = IMARG ## Devolve o argumento Teta, um ângulo expresso em radianos +IMCONJUGATE = IMCONJ ## Devolve o conjugado complexo de um número complexo +IMCOS = IMCOS ## Devolve o co-seno de um número complexo +IMDIV = IMDIV ## Devolve o quociente de dois números complexos +IMEXP = IMEXP ## Devolve o exponencial de um número complexo +IMLN = IMLN ## Devolve o logaritmo natural de um número complexo +IMLOG10 = IMLOG10 ## Devolve o logaritmo de base 10 de um número complexo +IMLOG2 = IMLOG2 ## Devolve o logaritmo de base 2 de um número complexo +IMPOWER = IMPOT ## Devolve um número complexo elevado a uma potência inteira +IMPRODUCT = IMPROD ## Devolve o produto de números complexos +IMREAL = IMREAL ## Devolve o coeficiente real de um número complexo +IMSIN = IMSENO ## Devolve o seno de um número complexo +IMSQRT = IMRAIZ ## Devolve a raiz quadrada de um número complexo +IMSUB = IMSUBTR ## Devolve a diferença entre dois números complexos +IMSUM = IMSOMA ## Devolve a soma de números complexos +OCT2BIN = OCTABIN ## Converte um número octal em binário +OCT2DEC = OCTADEC ## Converte um número octal em decimal +OCT2HEX = OCTAHEX ## Converte um número octal em hexadecimal + + +## +## Financial functions Funções financeiras +## +ACCRINT = JUROSACUM ## Devolve os juros acumulados de um título que paga juros periódicos +ACCRINTM = JUROSACUMV ## Devolve os juros acumulados de um título que paga juros no vencimento +AMORDEGRC = AMORDEGRC ## Devolve a depreciação correspondente a cada período contabilístico utilizando um coeficiente de depreciação +AMORLINC = AMORLINC ## Devolve a depreciação correspondente a cada período contabilístico +COUPDAYBS = CUPDIASINLIQ ## Devolve o número de dias entre o início do período do cupão e a data de regularização +COUPDAYS = CUPDIAS ## Devolve o número de dias no período do cupão que contém a data de regularização +COUPDAYSNC = CUPDIASPRÓX ## Devolve o número de dias entre a data de regularização e a data do cupão seguinte +COUPNCD = CUPDATAPRÓX ## Devolve a data do cupão seguinte após a data de regularização +COUPNUM = CUPNÚM ## Devolve o número de cupões a serem pagos entre a data de regularização e a data de vencimento +COUPPCD = CUPDATAANT ## Devolve a data do cupão anterior antes da data de regularização +CUMIPMT = PGTOJURACUM ## Devolve os juros cumulativos pagos entre dois períodos +CUMPRINC = PGTOCAPACUM ## Devolve o capital cumulativo pago a título de empréstimo entre dois períodos +DB = BD ## Devolve a depreciação de um activo relativo a um período especificado utilizando o método das quotas degressivas fixas +DDB = BDD ## Devolve a depreciação de um activo relativo a um período especificado utilizando o método das quotas degressivas duplas ou qualquer outro método especificado +DISC = DESC ## Devolve a taxa de desconto de um título +DOLLARDE = MOEDADEC ## Converte um preço em unidade monetária, expresso como uma fracção, num preço em unidade monetária, expresso como um número decimal +DOLLARFR = MOEDAFRA ## Converte um preço em unidade monetária, expresso como um número decimal, num preço em unidade monetária, expresso como uma fracção +DURATION = DURAÇÃO ## Devolve a duração anual de um título com pagamentos de juros periódicos +EFFECT = EFECTIVA ## Devolve a taxa de juros anual efectiva +FV = VF ## Devolve o valor futuro de um investimento +FVSCHEDULE = VFPLANO ## Devolve o valor futuro de um capital inicial após a aplicação de uma série de taxas de juro compostas +INTRATE = TAXAJUROS ## Devolve a taxa de juros de um título investido na totalidade +IPMT = IPGTO ## Devolve o pagamento dos juros de um investimento durante um determinado período +IRR = TIR ## Devolve a taxa de rentabilidade interna para uma série de fluxos monetários +ISPMT = É.PGTO ## Calcula os juros pagos durante um período específico de um investimento +MDURATION = MDURAÇÃO ## Devolve a duração modificada de Macauley de um título com um valor de paridade equivalente a € 100 +MIRR = MTIR ## Devolve a taxa interna de rentabilidade em que os fluxos monetários positivos e negativos são financiados com taxas diferentes +NOMINAL = NOMINAL ## Devolve a taxa de juros nominal anual +NPER = NPER ## Devolve o número de períodos de um investimento +NPV = VAL ## Devolve o valor actual líquido de um investimento com base numa série de fluxos monetários periódicos e numa taxa de desconto +ODDFPRICE = PREÇOPRIMINC ## Devolve o preço por € 100 do valor nominal de um título com um período inicial incompleto +ODDFYIELD = LUCROPRIMINC ## Devolve o lucro de um título com um período inicial incompleto +ODDLPRICE = PREÇOÚLTINC ## Devolve o preço por € 100 do valor nominal de um título com um período final incompleto +ODDLYIELD = LUCROÚLTINC ## Devolve o lucro de um título com um período final incompleto +PMT = PGTO ## Devolve o pagamento periódico de uma anuidade +PPMT = PPGTO ## Devolve o pagamento sobre o capital de um investimento num determinado período +PRICE = PREÇO ## Devolve o preço por € 100 do valor nominal de um título que paga juros periódicos +PRICEDISC = PREÇODESC ## Devolve o preço por € 100 do valor nominal de um título descontado +PRICEMAT = PREÇOVENC ## Devolve o preço por € 100 do valor nominal de um título que paga juros no vencimento +PV = VA ## Devolve o valor actual de um investimento +RATE = TAXA ## Devolve a taxa de juros por período de uma anuidade +RECEIVED = RECEBER ## Devolve o montante recebido no vencimento de um título investido na totalidade +SLN = AMORT ## Devolve uma depreciação linear de um activo durante um período +SYD = AMORTD ## Devolve a depreciação por algarismos da soma dos anos de um activo durante um período especificado +TBILLEQ = OTN ## Devolve o lucro de um título equivalente a uma Obrigação do Tesouro +TBILLPRICE = OTNVALOR ## Devolve o preço por € 100 de valor nominal de uma Obrigação do Tesouro +TBILLYIELD = OTNLUCRO ## Devolve o lucro de uma Obrigação do Tesouro +VDB = BDV ## Devolve a depreciação de um activo relativo a um período específico ou parcial utilizando um método de quotas degressivas +XIRR = XTIR ## Devolve a taxa interna de rentabilidade de um plano de fluxos monetários que não seja necessariamente periódica +XNPV = XVAL ## Devolve o valor actual líquido de um plano de fluxos monetários que não seja necessariamente periódico +YIELD = LUCRO ## Devolve o lucro de um título que paga juros periódicos +YIELDDISC = LUCRODESC ## Devolve o lucro anual de um título emitido abaixo do valor nominal, por exemplo, uma Obrigação do Tesouro +YIELDMAT = LUCROVENC ## Devolve o lucro anual de um título que paga juros na data de vencimento + + +## +## Information functions Funções de informação +## +CELL = CÉL ## Devolve informações sobre a formatação, localização ou conteúdo de uma célula +ERROR.TYPE = TIPO.ERRO ## Devolve um número correspondente a um tipo de erro +INFO = INFORMAÇÃO ## Devolve informações sobre o ambiente de funcionamento actual +ISBLANK = É.CÉL.VAZIA ## Devolve VERDADEIRO se o valor estiver em branco +ISERR = É.ERROS ## Devolve VERDADEIRO se o valor for um valor de erro diferente de #N/D +ISERROR = É.ERRO ## Devolve VERDADEIRO se o valor for um valor de erro +ISEVEN = ÉPAR ## Devolve VERDADEIRO se o número for par +ISLOGICAL = É.LÓGICO ## Devolve VERDADEIRO se o valor for lógico +ISNA = É.NÃO.DISP ## Devolve VERDADEIRO se o valor for o valor de erro #N/D +ISNONTEXT = É.NÃO.TEXTO ## Devolve VERDADEIRO se o valor não for texto +ISNUMBER = É.NÚM ## Devolve VERDADEIRO se o valor for um número +ISODD = ÉÍMPAR ## Devolve VERDADEIRO se o número for ímpar +ISREF = É.REF ## Devolve VERDADEIRO se o valor for uma referência +ISTEXT = É.TEXTO ## Devolve VERDADEIRO se o valor for texto +N = N ## Devolve um valor convertido num número +NA = NÃO.DISP ## Devolve o valor de erro #N/D +TYPE = TIPO ## Devolve um número que indica o tipo de dados de um valor + + +## +## Logical functions Funções lógicas +## +AND = E ## Devolve VERDADEIRO se todos os respectivos argumentos corresponderem a VERDADEIRO +FALSE = FALSO ## Devolve o valor lógico FALSO +IF = SE ## Especifica um teste lógico a ser executado +IFERROR = SE.ERRO ## Devolve um valor definido pelo utilizador se ocorrer um erro na fórmula, e devolve o resultado da fórmula se não ocorrer nenhum erro +NOT = NÃO ## Inverte a lógica do respectivo argumento +OR = OU ## Devolve VERDADEIRO se qualquer argumento for VERDADEIRO +TRUE = VERDADEIRO ## Devolve o valor lógico VERDADEIRO + + +## +## Lookup and reference functions Funções de pesquisa e referência +## +ADDRESS = ENDEREÇO ## Devolve uma referência a uma única célula numa folha de cálculo como texto +AREAS = ÁREAS ## Devolve o número de áreas numa referência +CHOOSE = SELECCIONAR ## Selecciona um valor a partir de uma lista de valores +COLUMN = COL ## Devolve o número da coluna de uma referência +COLUMNS = COLS ## Devolve o número de colunas numa referência +HLOOKUP = PROCH ## Procura na linha superior de uma matriz e devolve o valor da célula indicada +HYPERLINK = HIPERLIGAÇÃO ## Cria um atalho ou hiperligação que abre um documento armazenado num servidor de rede, numa intranet ou na Internet +INDEX = ÍNDICE ## Utiliza um índice para escolher um valor de uma referência ou de uma matriz +INDIRECT = INDIRECTO ## Devolve uma referência indicada por um valor de texto +LOOKUP = PROC ## Procura valores num vector ou numa matriz +MATCH = CORRESP ## Procura valores numa referência ou numa matriz +OFFSET = DESLOCAMENTO ## Devolve o deslocamento de referência de uma determinada referência +ROW = LIN ## Devolve o número da linha de uma referência +ROWS = LINS ## Devolve o número de linhas numa referência +RTD = RTD ## Obtém dados em tempo real a partir de um programa que suporte automatização COM (automatização: modo de trabalhar com objectos de uma aplicação a partir de outra aplicação ou ferramenta de desenvolvimento. Anteriormente conhecida como automatização OLE, a automatização é uma norma da indústria de software e uma funcionalidade COM (Component Object Model).) +TRANSPOSE = TRANSPOR ## Devolve a transposição de uma matriz +VLOOKUP = PROCV ## Procura na primeira coluna de uma matriz e percorre a linha para devolver o valor de uma célula + + +## +## Math and trigonometry functions Funções matemáticas e trigonométricas +## +ABS = ABS ## Devolve o valor absoluto de um número +ACOS = ACOS ## Devolve o arco de co-seno de um número +ACOSH = ACOSH ## Devolve o co-seno hiperbólico inverso de um número +ASIN = ASEN ## Devolve o arco de seno de um número +ASINH = ASENH ## Devolve o seno hiperbólico inverso de um número +ATAN = ATAN ## Devolve o arco de tangente de um número +ATAN2 = ATAN2 ## Devolve o arco de tangente das coordenadas x e y +ATANH = ATANH ## Devolve a tangente hiperbólica inversa de um número +CEILING = ARRED.EXCESSO ## Arredonda um número para o número inteiro mais próximo ou para o múltiplo de significância mais próximo +COMBIN = COMBIN ## Devolve o número de combinações de um determinado número de objectos +COS = COS ## Devolve o co-seno de um número +COSH = COSH ## Devolve o co-seno hiperbólico de um número +DEGREES = GRAUS ## Converte radianos em graus +EVEN = PAR ## Arredonda um número por excesso para o número inteiro mais próximo +EXP = EXP ## Devolve e elevado à potência de um determinado número +FACT = FACTORIAL ## Devolve o factorial de um número +FACTDOUBLE = FACTDUPLO ## Devolve o factorial duplo de um número +FLOOR = ARRED.DEFEITO ## Arredonda um número por defeito até zero +GCD = MDC ## Devolve o maior divisor comum +INT = INT ## Arredonda um número por defeito para o número inteiro mais próximo +LCM = MMC ## Devolve o mínimo múltiplo comum +LN = LN ## Devolve o logaritmo natural de um número +LOG = LOG ## Devolve o logaritmo de um número com uma base especificada +LOG10 = LOG10 ## Devolve o logaritmo de base 10 de um número +MDETERM = MATRIZ.DETERM ## Devolve o determinante matricial de uma matriz +MINVERSE = MATRIZ.INVERSA ## Devolve o inverso matricial de uma matriz +MMULT = MATRIZ.MULT ## Devolve o produto matricial de duas matrizes +MOD = RESTO ## Devolve o resto da divisão +MROUND = MARRED ## Devolve um número arredondado para o múltiplo pretendido +MULTINOMIAL = POLINOMIAL ## Devolve o polinomial de um conjunto de números +ODD = ÍMPAR ## Arredonda por excesso um número para o número inteiro ímpar mais próximo +PI = PI ## Devolve o valor de pi +POWER = POTÊNCIA ## Devolve o resultado de um número elevado a uma potência +PRODUCT = PRODUTO ## Multiplica os respectivos argumentos +QUOTIENT = QUOCIENTE ## Devolve a parte inteira de uma divisão +RADIANS = RADIANOS ## Converte graus em radianos +RAND = ALEATÓRIO ## Devolve um número aleatório entre 0 e 1 +RANDBETWEEN = ALEATÓRIOENTRE ## Devolve um número aleatório entre os números especificados +ROMAN = ROMANO ## Converte um número árabe em romano, como texto +ROUND = ARRED ## Arredonda um número para um número de dígitos especificado +ROUNDDOWN = ARRED.PARA.BAIXO ## Arredonda um número por defeito até zero +ROUNDUP = ARRED.PARA.CIMA ## Arredonda um número por excesso, afastando-o de zero +SERIESSUM = SOMASÉRIE ## Devolve a soma de uma série de potências baseada na fórmula +SIGN = SINAL ## Devolve o sinal de um número +SIN = SEN ## Devolve o seno de um determinado ângulo +SINH = SENH ## Devolve o seno hiperbólico de um número +SQRT = RAIZQ ## Devolve uma raiz quadrada positiva +SQRTPI = RAIZPI ## Devolve a raiz quadrada de (núm * pi) +SUBTOTAL = SUBTOTAL ## Devolve um subtotal numa lista ou base de dados +SUM = SOMA ## Adiciona os respectivos argumentos +SUMIF = SOMA.SE ## Adiciona as células especificadas por um determinado critério +SUMIFS = SOMA.SE.S ## Adiciona as células num intervalo que cumpre vários critérios +SUMPRODUCT = SOMARPRODUTO ## Devolve a soma dos produtos de componentes de matrizes correspondentes +SUMSQ = SOMARQUAD ## Devolve a soma dos quadrados dos argumentos +SUMX2MY2 = SOMAX2DY2 ## Devolve a soma da diferença dos quadrados dos valores correspondentes em duas matrizes +SUMX2PY2 = SOMAX2SY2 ## Devolve a soma da soma dos quadrados dos valores correspondentes em duas matrizes +SUMXMY2 = SOMAXMY2 ## Devolve a soma dos quadrados da diferença dos valores correspondentes em duas matrizes +TAN = TAN ## Devolve a tangente de um número +TANH = TANH ## Devolve a tangente hiperbólica de um número +TRUNC = TRUNCAR ## Trunca um número para um número inteiro + + +## +## Statistical functions Funções estatísticas +## +AVEDEV = DESV.MÉDIO ## Devolve a média aritmética dos desvios absolutos à média dos pontos de dados +AVERAGE = MÉDIA ## Devolve a média dos respectivos argumentos +AVERAGEA = MÉDIAA ## Devolve uma média dos respectivos argumentos, incluindo números, texto e valores lógicos +AVERAGEIF = MÉDIA.SE ## Devolve a média aritmética de todas as células num intervalo que cumprem determinado critério +AVERAGEIFS = MÉDIA.SE.S ## Devolve a média aritmética de todas as células que cumprem múltiplos critérios +BETADIST = DISTBETA ## Devolve a função de distribuição cumulativa beta +BETAINV = BETA.ACUM.INV ## Devolve o inverso da função de distribuição cumulativa relativamente a uma distribuição beta específica +BINOMDIST = DISTRBINOM ## Devolve a probabilidade de distribuição binomial de termo individual +CHIDIST = DIST.CHI ## Devolve a probabilidade unicaudal da distribuição qui-quadrada +CHIINV = INV.CHI ## Devolve o inverso da probabilidade unicaudal da distribuição qui-quadrada +CHITEST = TESTE.CHI ## Devolve o teste para independência +CONFIDENCE = INT.CONFIANÇA ## Devolve o intervalo de confiança correspondente a uma média de população +CORREL = CORREL ## Devolve o coeficiente de correlação entre dois conjuntos de dados +COUNT = CONTAR ## Conta os números que existem na lista de argumentos +COUNTA = CONTAR.VAL ## Conta os valores que existem na lista de argumentos +COUNTBLANK = CONTAR.VAZIO ## Conta o número de células em branco num intervalo +COUNTIF = CONTAR.SE ## Calcula o número de células num intervalo que corresponde aos critérios determinados +COUNTIFS = CONTAR.SE.S ## Conta o número de células num intervalo que cumprem múltiplos critérios +COVAR = COVAR ## Devolve a covariância, que é a média dos produtos de desvios de pares +CRITBINOM = CRIT.BINOM ## Devolve o menor valor em que a distribuição binomial cumulativa é inferior ou igual a um valor de critério +DEVSQ = DESVQ ## Devolve a soma dos quadrados dos desvios +EXPONDIST = DISTEXPON ## Devolve a distribuição exponencial +FDIST = DISTF ## Devolve a distribuição da probabilidade F +FINV = INVF ## Devolve o inverso da distribuição da probabilidade F +FISHER = FISHER ## Devolve a transformação Fisher +FISHERINV = FISHERINV ## Devolve o inverso da transformação Fisher +FORECAST = PREVISÃO ## Devolve um valor ao longo de uma tendência linear +FREQUENCY = FREQUÊNCIA ## Devolve uma distribuição de frequência como uma matriz vertical +FTEST = TESTEF ## Devolve o resultado de um teste F +GAMMADIST = DISTGAMA ## Devolve a distribuição gama +GAMMAINV = INVGAMA ## Devolve o inverso da distribuição gama cumulativa +GAMMALN = LNGAMA ## Devolve o logaritmo natural da função gama, Γ(x) +GEOMEAN = MÉDIA.GEOMÉTRICA ## Devolve a média geométrica +GROWTH = CRESCIMENTO ## Devolve valores ao longo de uma tendência exponencial +HARMEAN = MÉDIA.HARMÓNICA ## Devolve a média harmónica +HYPGEOMDIST = DIST.HIPERGEOM ## Devolve a distribuição hipergeométrica +INTERCEPT = INTERCEPTAR ## Devolve a intercepção da linha de regressão linear +KURT = CURT ## Devolve a curtose de um conjunto de dados +LARGE = MAIOR ## Devolve o maior valor k-ésimo de um conjunto de dados +LINEST = PROJ.LIN ## Devolve os parâmetros de uma tendência linear +LOGEST = PROJ.LOG ## Devolve os parâmetros de uma tendência exponencial +LOGINV = INVLOG ## Devolve o inverso da distribuição normal logarítmica +LOGNORMDIST = DIST.NORMALLOG ## Devolve a distribuição normal logarítmica cumulativa +MAX = MÁXIMO ## Devolve o valor máximo numa lista de argumentos +MAXA = MÁXIMOA ## Devolve o valor máximo numa lista de argumentos, incluindo números, texto e valores lógicos +MEDIAN = MED ## Devolve a mediana dos números indicados +MIN = MÍNIMO ## Devolve o valor mínimo numa lista de argumentos +MINA = MÍNIMOA ## Devolve o valor mínimo numa lista de argumentos, incluindo números, texto e valores lógicos +MODE = MODA ## Devolve o valor mais comum num conjunto de dados +NEGBINOMDIST = DIST.BIN.NEG ## Devolve a distribuição binominal negativa +NORMDIST = DIST.NORM ## Devolve a distribuição cumulativa normal +NORMINV = INV.NORM ## Devolve o inverso da distribuição cumulativa normal +NORMSDIST = DIST.NORMP ## Devolve a distribuição cumulativa normal padrão +NORMSINV = INV.NORMP ## Devolve o inverso da distribuição cumulativa normal padrão +PEARSON = PEARSON ## Devolve o coeficiente de correlação momento/produto de Pearson +PERCENTILE = PERCENTIL ## Devolve o k-ésimo percentil de valores num intervalo +PERCENTRANK = ORDEM.PERCENTUAL ## Devolve a ordem percentual de um valor num conjunto de dados +PERMUT = PERMUTAR ## Devolve o número de permutações de um determinado número de objectos +POISSON = POISSON ## Devolve a distribuição de Poisson +PROB = PROB ## Devolve a probabilidade dos valores num intervalo se encontrarem entre dois limites +QUARTILE = QUARTIL ## Devolve o quartil de um conjunto de dados +RANK = ORDEM ## Devolve a ordem de um número numa lista numérica +RSQ = RQUAD ## Devolve o quadrado do coeficiente de correlação momento/produto de Pearson +SKEW = DISTORÇÃO ## Devolve a distorção de uma distribuição +SLOPE = DECLIVE ## Devolve o declive da linha de regressão linear +SMALL = MENOR ## Devolve o menor valor de k-ésimo de um conjunto de dados +STANDARDIZE = NORMALIZAR ## Devolve um valor normalizado +STDEV = DESVPAD ## Calcula o desvio-padrão com base numa amostra +STDEVA = DESVPADA ## Calcula o desvio-padrão com base numa amostra, incluindo números, texto e valores lógicos +STDEVP = DESVPADP ## Calcula o desvio-padrão com base na população total +STDEVPA = DESVPADPA ## Calcula o desvio-padrão com base na população total, incluindo números, texto e valores lógicos +STEYX = EPADYX ## Devolve o erro-padrão do valor de y previsto para cada x na regressão +TDIST = DISTT ## Devolve a distribuição t de Student +TINV = INVT ## Devolve o inverso da distribuição t de Student +TREND = TENDÊNCIA ## Devolve valores ao longo de uma tendência linear +TRIMMEAN = MÉDIA.INTERNA ## Devolve a média do interior de um conjunto de dados +TTEST = TESTET ## Devolve a probabilidade associada ao teste t de Student +VAR = VAR ## Calcula a variância com base numa amostra +VARA = VARA ## Calcula a variância com base numa amostra, incluindo números, texto e valores lógicos +VARP = VARP ## Calcula a variância com base na população total +VARPA = VARPA ## Calcula a variância com base na população total, incluindo números, texto e valores lógicos +WEIBULL = WEIBULL ## Devolve a distribuição Weibull +ZTEST = TESTEZ ## Devolve o valor de probabilidade unicaudal de um teste-z + + +## +## Text functions Funções de texto +## +ASC = ASC ## Altera letras ou katakana de largura total (byte duplo) numa cadeia de caracteres para caracteres de largura média (byte único) +BAHTTEXT = TEXTO.BAHT ## Converte um número em texto, utilizando o formato monetário ß (baht) +CHAR = CARÁCT ## Devolve o carácter especificado pelo número de código +CLEAN = LIMPAR ## Remove do texto todos os caracteres não imprimíveis +CODE = CÓDIGO ## Devolve um código numérico correspondente ao primeiro carácter numa cadeia de texto +CONCATENATE = CONCATENAR ## Agrupa vários itens de texto num único item de texto +DOLLAR = MOEDA ## Converte um número em texto, utilizando o formato monetário € (Euro) +EXACT = EXACTO ## Verifica se dois valores de texto são idênticos +FIND = LOCALIZAR ## Localiza um valor de texto dentro de outro (sensível às maiúsculas e minúsculas) +FINDB = LOCALIZARB ## Localiza um valor de texto dentro de outro (sensível às maiúsculas e minúsculas) +FIXED = FIXA ## Formata um número como texto com um número fixo de decimais +JIS = JIS ## Altera letras ou katakana de largura média (byte único) numa cadeia de caracteres para caracteres de largura total (byte duplo) +LEFT = ESQUERDA ## Devolve os caracteres mais à esquerda de um valor de texto +LEFTB = ESQUERDAB ## Devolve os caracteres mais à esquerda de um valor de texto +LEN = NÚM.CARACT ## Devolve o número de caracteres de uma cadeia de texto +LENB = NÚM.CARACTB ## Devolve o número de caracteres de uma cadeia de texto +LOWER = MINÚSCULAS ## Converte o texto em minúsculas +MID = SEG.TEXTO ## Devolve um número específico de caracteres de uma cadeia de texto, a partir da posição especificada +MIDB = SEG.TEXTOB ## Devolve um número específico de caracteres de uma cadeia de texto, a partir da posição especificada +PHONETIC = FONÉTICA ## Retira os caracteres fonéticos (furigana) de uma cadeia de texto +PROPER = INICIAL.MAIÚSCULA ## Coloca em maiúsculas a primeira letra de cada palavra de um valor de texto +REPLACE = SUBSTITUIR ## Substitui caracteres no texto +REPLACEB = SUBSTITUIRB ## Substitui caracteres no texto +REPT = REPETIR ## Repete texto um determinado número de vezes +RIGHT = DIREITA ## Devolve os caracteres mais à direita de um valor de texto +RIGHTB = DIREITAB ## Devolve os caracteres mais à direita de um valor de texto +SEARCH = PROCURAR ## Localiza um valor de texto dentro de outro (não sensível a maiúsculas e minúsculas) +SEARCHB = PROCURARB ## Localiza um valor de texto dentro de outro (não sensível a maiúsculas e minúsculas) +SUBSTITUTE = SUBST ## Substitui texto novo por texto antigo numa cadeia de texto +T = T ## Converte os respectivos argumentos em texto +TEXT = TEXTO ## Formata um número e converte-o em texto +TRIM = COMPACTAR ## Remove espaços do texto +UPPER = MAIÚSCULAS ## Converte texto em maiúsculas +VALUE = VALOR ## Converte um argumento de texto num número diff --git a/lib/phpexcel/PHPExcel/locale/ru/config b/lib/phpexcel/PHPExcel/locale/ru/config new file mode 100644 index 0000000..6f6ace2 --- /dev/null +++ b/lib/phpexcel/PHPExcel/locale/ru/config @@ -0,0 +1,47 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Settings +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## + + +ArgumentSeparator = ; + + +## +## (For future use) +## +currencySymbol = р + + +## +## Excel Error Codes (For future use) +## +NULL = #ПУСТО! +DIV0 = #ДЕЛ/0! +VALUE = #ЗНАЧ! +REF = #ССЫЛ! +NAME = #ИМЯ? +NUM = #ЧИСЛО! +NA = #Н/Д diff --git a/lib/phpexcel/PHPExcel/locale/ru/functions b/lib/phpexcel/PHPExcel/locale/ru/functions new file mode 100644 index 0000000..bd63686 --- /dev/null +++ b/lib/phpexcel/PHPExcel/locale/ru/functions @@ -0,0 +1,438 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Calculation +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## Data in this file derived from information provided by web-junior (http://www.web-junior.net/) +## +## + + +## +## Add-in and Automation functions Функции надстроек и автоматизации +## +GETPIVOTDATA = ПОЛУЧИТЬ.ДАННЫЕ.СВОДНОЙ.ТАБЛИЦЫ ## Возвращает данные, хранящиеся в отчете сводной таблицы. + + +## +## Cube functions Функции Куб +## +CUBEKPIMEMBER = КУБЭЛЕМЕНТКИП ## Возвращает свойство ключевого индикатора производительности «(КИП)» и отображает имя «КИП» в ячейке. «КИП» представляет собой количественную величину, такую как ежемесячная валовая прибыль или ежеквартальная текучесть кадров, используемой для контроля эффективности работы организации. +CUBEMEMBER = КУБЭЛЕМЕНТ ## Возвращает элемент или кортеж из куба. Используется для проверки существования элемента или кортежа в кубе. +CUBEMEMBERPROPERTY = КУБСВОЙСТВОЭЛЕМЕНТА ## Возвращает значение свойства элемента из куба. Используется для проверки существования имени элемента в кубе и возвращает указанное свойство для этого элемента. +CUBERANKEDMEMBER = КУБПОРЭЛЕМЕНТ ## Возвращает n-ый или ранжированный элемент в множество. Используется для возвращения одного или нескольких элементов в множество, например, лучшего продавца или 10 лучших студентов. +CUBESET = КУБМНОЖ ## Определяет вычислительное множество элементов или кортежей, отправляя на сервер выражение, которое создает множество, а затем возвращает его в Microsoft Office Excel. +CUBESETCOUNT = КУБЧИСЛОЭЛМНОЖ ## Возвращает число элементов множества. +CUBEVALUE = КУБЗНАЧЕНИЕ ## Возвращает обобщенное значение из куба. + + +## +## Database functions Функции для работы с базами данных +## +DAVERAGE = ДСРЗНАЧ ## Возвращает среднее значение выбранных записей базы данных. +DCOUNT = БСЧЁТ ## Подсчитывает количество числовых ячеек в базе данных. +DCOUNTA = БСЧЁТА ## Подсчитывает количество непустых ячеек в базе данных. +DGET = БИЗВЛЕЧЬ ## Извлекает из базы данных одну запись, удовлетворяющую заданному условию. +DMAX = ДМАКС ## Возвращает максимальное значение среди выделенных записей базы данных. +DMIN = ДМИН ## Возвращает минимальное значение среди выделенных записей базы данных. +DPRODUCT = БДПРОИЗВЕД ## Перемножает значения определенного поля в записях базы данных, удовлетворяющих условию. +DSTDEV = ДСТАНДОТКЛ ## Оценивает стандартное отклонение по выборке для выделенных записей базы данных. +DSTDEVP = ДСТАНДОТКЛП ## Вычисляет стандартное отклонение по генеральной совокупности для выделенных записей базы данных +DSUM = БДСУММ ## Суммирует числа в поле для записей базы данных, удовлетворяющих условию. +DVAR = БДДИСП ## Оценивает дисперсию по выборке из выделенных записей базы данных +DVARP = БДДИСПП ## Вычисляет дисперсию по генеральной совокупности для выделенных записей базы данных + + +## +## Date and time functions Функции даты и времени +## +DATE = ДАТА ## Возвращает заданную дату в числовом формате. +DATEVALUE = ДАТАЗНАЧ ## Преобразует дату из текстового формата в числовой формат. +DAY = ДЕНЬ ## Преобразует дату в числовом формате в день месяца. +DAYS360 = ДНЕЙ360 ## Вычисляет количество дней между двумя датами на основе 360-дневного года. +EDATE = ДАТАМЕС ## Возвращает дату в числовом формате, отстоящую на заданное число месяцев вперед или назад от начальной даты. +EOMONTH = КОНМЕСЯЦА ## Возвращает дату в числовом формате для последнего дня месяца, отстоящего вперед или назад на заданное число месяцев. +HOUR = ЧАС ## Преобразует дату в числовом формате в часы. +MINUTE = МИНУТЫ ## Преобразует дату в числовом формате в минуты. +MONTH = МЕСЯЦ ## Преобразует дату в числовом формате в месяцы. +NETWORKDAYS = ЧИСТРАБДНИ ## Возвращает количество рабочих дней между двумя датами. +NOW = ТДАТА ## Возвращает текущую дату и время в числовом формате. +SECOND = СЕКУНДЫ ## Преобразует дату в числовом формате в секунды. +TIME = ВРЕМЯ ## Возвращает заданное время в числовом формате. +TIMEVALUE = ВРЕМЗНАЧ ## Преобразует время из текстового формата в числовой формат. +TODAY = СЕГОДНЯ ## Возвращает текущую дату в числовом формате. +WEEKDAY = ДЕНЬНЕД ## Преобразует дату в числовом формате в день недели. +WEEKNUM = НОМНЕДЕЛИ ## Преобразует числовое представление в число, которое указывает, на какую неделю года приходится указанная дата. +WORKDAY = РАБДЕНЬ ## Возвращает дату в числовом формате, отстоящую вперед или назад на заданное количество рабочих дней. +YEAR = ГОД ## Преобразует дату в числовом формате в год. +YEARFRAC = ДОЛЯГОДА ## Возвращает долю года, которую составляет количество дней между начальной и конечной датами. + + +## +## Engineering functions Инженерные функции +## +BESSELI = БЕССЕЛЬ.I ## Возвращает модифицированную функцию Бесселя In(x). +BESSELJ = БЕССЕЛЬ.J ## Возвращает функцию Бесселя Jn(x). +BESSELK = БЕССЕЛЬ.K ## Возвращает модифицированную функцию Бесселя Kn(x). +BESSELY = БЕССЕЛЬ.Y ## Возвращает функцию Бесселя Yn(x). +BIN2DEC = ДВ.В.ДЕС ## Преобразует двоичное число в десятичное. +BIN2HEX = ДВ.В.ШЕСТН ## Преобразует двоичное число в шестнадцатеричное. +BIN2OCT = ДВ.В.ВОСЬМ ## Преобразует двоичное число в восьмеричное. +COMPLEX = КОМПЛЕКСН ## Преобразует коэффициенты при вещественной и мнимой частях комплексного числа в комплексное число. +CONVERT = ПРЕОБР ## Преобразует число из одной системы единиц измерения в другую. +DEC2BIN = ДЕС.В.ДВ ## Преобразует десятичное число в двоичное. +DEC2HEX = ДЕС.В.ШЕСТН ## Преобразует десятичное число в шестнадцатеричное. +DEC2OCT = ДЕС.В.ВОСЬМ ## Преобразует десятичное число в восьмеричное. +DELTA = ДЕЛЬТА ## Проверяет равенство двух значений. +ERF = ФОШ ## Возвращает функцию ошибки. +ERFC = ДФОШ ## Возвращает дополнительную функцию ошибки. +GESTEP = ПОРОГ ## Проверяет, не превышает ли данное число порогового значения. +HEX2BIN = ШЕСТН.В.ДВ ## Преобразует шестнадцатеричное число в двоичное. +HEX2DEC = ШЕСТН.В.ДЕС ## Преобразует шестнадцатеричное число в десятичное. +HEX2OCT = ШЕСТН.В.ВОСЬМ ## Преобразует шестнадцатеричное число в восьмеричное. +IMABS = МНИМ.ABS ## Возвращает абсолютную величину (модуль) комплексного числа. +IMAGINARY = МНИМ.ЧАСТЬ ## Возвращает коэффициент при мнимой части комплексного числа. +IMARGUMENT = МНИМ.АРГУМЕНТ ## Возвращает значение аргумента комплексного числа (тета) — угол, выраженный в радианах. +IMCONJUGATE = МНИМ.СОПРЯЖ ## Возвращает комплексно-сопряженное комплексное число. +IMCOS = МНИМ.COS ## Возвращает косинус комплексного числа. +IMDIV = МНИМ.ДЕЛ ## Возвращает частное от деления двух комплексных чисел. +IMEXP = МНИМ.EXP ## Возвращает экспоненту комплексного числа. +IMLN = МНИМ.LN ## Возвращает натуральный логарифм комплексного числа. +IMLOG10 = МНИМ.LOG10 ## Возвращает обычный (десятичный) логарифм комплексного числа. +IMLOG2 = МНИМ.LOG2 ## Возвращает двоичный логарифм комплексного числа. +IMPOWER = МНИМ.СТЕПЕНЬ ## Возвращает комплексное число, возведенное в целую степень. +IMPRODUCT = МНИМ.ПРОИЗВЕД ## Возвращает произведение от 2 до 29 комплексных чисел. +IMREAL = МНИМ.ВЕЩ ## Возвращает коэффициент при вещественной части комплексного числа. +IMSIN = МНИМ.SIN ## Возвращает синус комплексного числа. +IMSQRT = МНИМ.КОРЕНЬ ## Возвращает значение квадратного корня из комплексного числа. +IMSUB = МНИМ.РАЗН ## Возвращает разность двух комплексных чисел. +IMSUM = МНИМ.СУММ ## Возвращает сумму комплексных чисел. +OCT2BIN = ВОСЬМ.В.ДВ ## Преобразует восьмеричное число в двоичное. +OCT2DEC = ВОСЬМ.В.ДЕС ## Преобразует восьмеричное число в десятичное. +OCT2HEX = ВОСЬМ.В.ШЕСТН ## Преобразует восьмеричное число в шестнадцатеричное. + + +## +## Financial functions Финансовые функции +## +ACCRINT = НАКОПДОХОД ## Возвращает накопленный процент по ценным бумагам с периодической выплатой процентов. +ACCRINTM = НАКОПДОХОДПОГАШ ## Возвращает накопленный процент по ценным бумагам, проценты по которым выплачиваются в срок погашения. +AMORDEGRC = АМОРУМ ## Возвращает величину амортизации для каждого периода, используя коэффициент амортизации. +AMORLINC = АМОРУВ ## Возвращает величину амортизации для каждого периода. +COUPDAYBS = ДНЕЙКУПОНДО ## Возвращает количество дней от начала действия купона до даты соглашения. +COUPDAYS = ДНЕЙКУПОН ## Возвращает число дней в периоде купона, содержащем дату соглашения. +COUPDAYSNC = ДНЕЙКУПОНПОСЛЕ ## Возвращает число дней от даты соглашения до срока следующего купона. +COUPNCD = ДАТАКУПОНПОСЛЕ ## Возвращает следующую дату купона после даты соглашения. +COUPNUM = ЧИСЛКУПОН ## Возвращает количество купонов, которые могут быть оплачены между датой соглашения и сроком вступления в силу. +COUPPCD = ДАТАКУПОНДО ## Возвращает предыдущую дату купона перед датой соглашения. +CUMIPMT = ОБЩПЛАТ ## Возвращает общую выплату, произведенную между двумя периодическими выплатами. +CUMPRINC = ОБЩДОХОД ## Возвращает общую выплату по займу между двумя периодами. +DB = ФУО ## Возвращает величину амортизации актива для заданного периода, рассчитанную методом фиксированного уменьшения остатка. +DDB = ДДОБ ## Возвращает величину амортизации актива за данный период, используя метод двойного уменьшения остатка или иной явно указанный метод. +DISC = СКИДКА ## Возвращает норму скидки для ценных бумаг. +DOLLARDE = РУБЛЬ.ДЕС ## Преобразует цену в рублях, выраженную в виде дроби, в цену в рублях, выраженную десятичным числом. +DOLLARFR = РУБЛЬ.ДРОБЬ ## Преобразует цену в рублях, выраженную десятичным числом, в цену в рублях, выраженную в виде дроби. +DURATION = ДЛИТ ## Возвращает ежегодную продолжительность действия ценных бумаг с периодическими выплатами по процентам. +EFFECT = ЭФФЕКТ ## Возвращает действующие ежегодные процентные ставки. +FV = БС ## Возвращает будущую стоимость инвестиции. +FVSCHEDULE = БЗРАСПИС ## Возвращает будущую стоимость первоначальной основной суммы после начисления ряда сложных процентов. +INTRATE = ИНОРМА ## Возвращает процентную ставку для полностью инвестированных ценных бумаг. +IPMT = ПРПЛТ ## Возвращает величину выплаты прибыли на вложения за данный период. +IRR = ВСД ## Возвращает внутреннюю ставку доходности для ряда потоков денежных средств. +ISPMT = ПРОЦПЛАТ ## Вычисляет выплаты за указанный период инвестиции. +MDURATION = МДЛИТ ## Возвращает модифицированную длительность Маколея для ценных бумаг с предполагаемой номинальной стоимостью 100 рублей. +MIRR = МВСД ## Возвращает внутреннюю ставку доходности, при которой положительные и отрицательные денежные потоки имеют разные значения ставки. +NOMINAL = НОМИНАЛ ## Возвращает номинальную годовую процентную ставку. +NPER = КПЕР ## Возвращает общее количество периодов выплаты для данного вклада. +NPV = ЧПС ## Возвращает чистую приведенную стоимость инвестиции, основанной на серии периодических денежных потоков и ставке дисконтирования. +ODDFPRICE = ЦЕНАПЕРВНЕРЕГ ## Возвращает цену за 100 рублей нарицательной стоимости ценных бумаг с нерегулярным первым периодом. +ODDFYIELD = ДОХОДПЕРВНЕРЕГ ## Возвращает доход по ценным бумагам с нерегулярным первым периодом. +ODDLPRICE = ЦЕНАПОСЛНЕРЕГ ## Возвращает цену за 100 рублей нарицательной стоимости ценных бумаг с нерегулярным последним периодом. +ODDLYIELD = ДОХОДПОСЛНЕРЕГ ## Возвращает доход по ценным бумагам с нерегулярным последним периодом. +PMT = ПЛТ ## Возвращает величину выплаты за один период аннуитета. +PPMT = ОСПЛТ ## Возвращает величину выплат в погашение основной суммы по инвестиции за заданный период. +PRICE = ЦЕНА ## Возвращает цену за 100 рублей нарицательной стоимости ценных бумаг, по которым производится периодическая выплата процентов. +PRICEDISC = ЦЕНАСКИДКА ## Возвращает цену за 100 рублей номинальной стоимости ценных бумаг, на которые сделана скидка. +PRICEMAT = ЦЕНАПОГАШ ## Возвращает цену за 100 рублей номинальной стоимости ценных бумаг, проценты по которым выплачиваются в срок погашения. +PV = ПС ## Возвращает приведенную (к текущему моменту) стоимость инвестиции. +RATE = СТАВКА ## Возвращает процентную ставку по аннуитету за один период. +RECEIVED = ПОЛУЧЕНО ## Возвращает сумму, полученную к сроку погашения полностью обеспеченных ценных бумаг. +SLN = АПЛ ## Возвращает величину линейной амортизации актива за один период. +SYD = АСЧ ## Возвращает величину амортизации актива за данный период, рассчитанную методом суммы годовых чисел. +TBILLEQ = РАВНОКЧЕК ## Возвращает эквивалентный облигации доход по казначейскому чеку. +TBILLPRICE = ЦЕНАКЧЕК ## Возвращает цену за 100 рублей нарицательной стоимости для казначейского чека. +TBILLYIELD = ДОХОДКЧЕК ## Возвращает доход по казначейскому чеку. +VDB = ПУО ## Возвращает величину амортизации актива для указанного или частичного периода при использовании метода сокращающегося баланса. +XIRR = ЧИСТВНДОХ ## Возвращает внутреннюю ставку доходности для графика денежных потоков, которые не обязательно носят периодический характер. +XNPV = ЧИСТНЗ ## Возвращает чистую приведенную стоимость для денежных потоков, которые не обязательно являются периодическими. +YIELD = ДОХОД ## Возвращает доход от ценных бумаг, по которым производятся периодические выплаты процентов. +YIELDDISC = ДОХОДСКИДКА ## Возвращает годовой доход по ценным бумагам, на которые сделана скидка (пример — казначейские чеки). +YIELDMAT = ДОХОДПОГАШ ## Возвращает годовой доход от ценных бумаг, проценты по которым выплачиваются в срок погашения. + + +## +## Information functions Информационные функции +## +CELL = ЯЧЕЙКА ## Возвращает информацию о формате, расположении или содержимом ячейки. +ERROR.TYPE = ТИП.ОШИБКИ ## Возвращает числовой код, соответствующий типу ошибки. +INFO = ИНФОРМ ## Возвращает информацию о текущей операционной среде. +ISBLANK = ЕПУСТО ## Возвращает значение ИСТИНА, если аргумент является ссылкой на пустую ячейку. +ISERR = ЕОШ ## Возвращает значение ИСТИНА, если аргумент ссылается на любое значение ошибки, кроме #Н/Д. +ISERROR = ЕОШИБКА ## Возвращает значение ИСТИНА, если аргумент ссылается на любое значение ошибки. +ISEVEN = ЕЧЁТН ## Возвращает значение ИСТИНА, если значение аргумента является четным числом. +ISLOGICAL = ЕЛОГИЧ ## Возвращает значение ИСТИНА, если аргумент ссылается на логическое значение. +ISNA = ЕНД ## Возвращает значение ИСТИНА, если аргумент ссылается на значение ошибки #Н/Д. +ISNONTEXT = ЕНЕТЕКСТ ## Возвращает значение ИСТИНА, если значение аргумента не является текстом. +ISNUMBER = ЕЧИСЛО ## Возвращает значение ИСТИНА, если аргумент ссылается на число. +ISODD = ЕНЕЧЁТ ## Возвращает значение ИСТИНА, если значение аргумента является нечетным числом. +ISREF = ЕССЫЛКА ## Возвращает значение ИСТИНА, если значение аргумента является ссылкой. +ISTEXT = ЕТЕКСТ ## Возвращает значение ИСТИНА, если значение аргумента является текстом. +N = Ч ## Возвращает значение, преобразованное в число. +NA = НД ## Возвращает значение ошибки #Н/Д. +TYPE = ТИП ## Возвращает число, обозначающее тип данных значения. + + +## +## Logical functions Логические функции +## +AND = И ## Renvoie VRAI si tous ses arguments sont VRAI. +FALSE = ЛОЖЬ ## Возвращает логическое значение ЛОЖЬ. +IF = ЕСЛИ ## Выполняет проверку условия. +IFERROR = ЕСЛИОШИБКА ## Возвращает введённое значение, если вычисление по формуле вызывает ошибку; в противном случае функция возвращает результат вычисления. +NOT = НЕ ## Меняет логическое значение своего аргумента на противоположное. +OR = ИЛИ ## Возвращает значение ИСТИНА, если хотя бы один аргумент имеет значение ИСТИНА. +TRUE = ИСТИНА ## Возвращает логическое значение ИСТИНА. + + +## +## Lookup and reference functions Функции ссылки и поиска +## +ADDRESS = АДРЕС ## Возвращает ссылку на отдельную ячейку листа в виде текста. +AREAS = ОБЛАСТИ ## Возвращает количество областей в ссылке. +CHOOSE = ВЫБОР ## Выбирает значение из списка значений по индексу. +COLUMN = СТОЛБЕЦ ## Возвращает номер столбца, на который указывает ссылка. +COLUMNS = ЧИСЛСТОЛБ ## Возвращает количество столбцов в ссылке. +HLOOKUP = ГПР ## Ищет в первой строке массива и возвращает значение отмеченной ячейки +HYPERLINK = ГИПЕРССЫЛКА ## Создает ссылку, открывающую документ, который находится на сервере сети, в интрасети или в Интернете. +INDEX = ИНДЕКС ## Использует индекс для выбора значения из ссылки или массива. +INDIRECT = ДВССЫЛ ## Возвращает ссылку, заданную текстовым значением. +LOOKUP = ПРОСМОТР ## Ищет значения в векторе или массиве. +MATCH = ПОИСКПОЗ ## Ищет значения в ссылке или массиве. +OFFSET = СМЕЩ ## Возвращает смещение ссылки относительно заданной ссылки. +ROW = СТРОКА ## Возвращает номер строки, определяемой ссылкой. +ROWS = ЧСТРОК ## Возвращает количество строк в ссылке. +RTD = ДРВ ## Извлекает данные реального времени из программ, поддерживающих автоматизацию COM (Программирование объектов. Стандартное средство для работы с объектами некоторого приложения из другого приложения или средства разработки. Программирование объектов (ранее называемое программированием OLE) является функцией модели COM (Component Object Model, модель компонентных объектов).). +TRANSPOSE = ТРАНСП ## Возвращает транспонированный массив. +VLOOKUP = ВПР ## Ищет значение в первом столбце массива и возвращает значение из ячейки в найденной строке и указанном столбце. + + +## +## Math and trigonometry functions Математические и тригонометрические функции +## +ABS = ABS ## Возвращает модуль (абсолютную величину) числа. +ACOS = ACOS ## Возвращает арккосинус числа. +ACOSH = ACOSH ## Возвращает гиперболический арккосинус числа. +ASIN = ASIN ## Возвращает арксинус числа. +ASINH = ASINH ## Возвращает гиперболический арксинус числа. +ATAN = ATAN ## Возвращает арктангенс числа. +ATAN2 = ATAN2 ## Возвращает арктангенс для заданных координат x и y. +ATANH = ATANH ## Возвращает гиперболический арктангенс числа. +CEILING = ОКРВВЕРХ ## Округляет число до ближайшего целого или до ближайшего кратного указанному значению. +COMBIN = ЧИСЛКОМБ ## Возвращает количество комбинаций для заданного числа объектов. +COS = COS ## Возвращает косинус числа. +COSH = COSH ## Возвращает гиперболический косинус числа. +DEGREES = ГРАДУСЫ ## Преобразует радианы в градусы. +EVEN = ЧЁТН ## Округляет число до ближайшего четного целого. +EXP = EXP ## Возвращает число e, возведенное в указанную степень. +FACT = ФАКТР ## Возвращает факториал числа. +FACTDOUBLE = ДВФАКТР ## Возвращает двойной факториал числа. +FLOOR = ОКРВНИЗ ## Округляет число до ближайшего меньшего по модулю значения. +GCD = НОД ## Возвращает наибольший общий делитель. +INT = ЦЕЛОЕ ## Округляет число до ближайшего меньшего целого. +LCM = НОК ## Возвращает наименьшее общее кратное. +LN = LN ## Возвращает натуральный логарифм числа. +LOG = LOG ## Возвращает логарифм числа по заданному основанию. +LOG10 = LOG10 ## Возвращает десятичный логарифм числа. +MDETERM = МОПРЕД ## Возвращает определитель матрицы массива. +MINVERSE = МОБР ## Возвращает обратную матрицу массива. +MMULT = МУМНОЖ ## Возвращает произведение матриц двух массивов. +MOD = ОСТАТ ## Возвращает остаток от деления. +MROUND = ОКРУГЛТ ## Возвращает число, округленное с требуемой точностью. +MULTINOMIAL = МУЛЬТИНОМ ## Возвращает мультиномиальный коэффициент множества чисел. +ODD = НЕЧЁТ ## Округляет число до ближайшего нечетного целого. +PI = ПИ ## Возвращает число пи. +POWER = СТЕПЕНЬ ## Возвращает результат возведения числа в степень. +PRODUCT = ПРОИЗВЕД ## Возвращает произведение аргументов. +QUOTIENT = ЧАСТНОЕ ## Возвращает целую часть частного при делении. +RADIANS = РАДИАНЫ ## Преобразует градусы в радианы. +RAND = СЛЧИС ## Возвращает случайное число в интервале от 0 до 1. +RANDBETWEEN = СЛУЧМЕЖДУ ## Возвращает случайное число в интервале между двумя заданными числами. +ROMAN = РИМСКОЕ ## Преобразует арабские цифры в римские в виде текста. +ROUND = ОКРУГЛ ## Округляет число до указанного количества десятичных разрядов. +ROUNDDOWN = ОКРУГЛВНИЗ ## Округляет число до ближайшего меньшего по модулю значения. +ROUNDUP = ОКРУГЛВВЕРХ ## Округляет число до ближайшего большего по модулю значения. +SERIESSUM = РЯД.СУММ ## Возвращает сумму степенного ряда, вычисленную по формуле. +SIGN = ЗНАК ## Возвращает знак числа. +SIN = SIN ## Возвращает синус заданного угла. +SINH = SINH ## Возвращает гиперболический синус числа. +SQRT = КОРЕНЬ ## Возвращает положительное значение квадратного корня. +SQRTPI = КОРЕНЬПИ ## Возвращает квадратный корень из значения выражения (число * ПИ). +SUBTOTAL = ПРОМЕЖУТОЧНЫЕ.ИТОГИ ## Возвращает промежуточный итог в списке или базе данных. +SUM = СУММ ## Суммирует аргументы. +SUMIF = СУММЕСЛИ ## Суммирует ячейки, удовлетворяющие заданному условию. +SUMIFS = СУММЕСЛИМН ## Суммирует диапазон ячеек, удовлетворяющих нескольким условиям. +SUMPRODUCT = СУММПРОИЗВ ## Возвращает сумму произведений соответствующих элементов массивов. +SUMSQ = СУММКВ ## Возвращает сумму квадратов аргументов. +SUMX2MY2 = СУММРАЗНКВ ## Возвращает сумму разностей квадратов соответствующих значений в двух массивах. +SUMX2PY2 = СУММСУММКВ ## Возвращает сумму сумм квадратов соответствующих элементов двух массивов. +SUMXMY2 = СУММКВРАЗН ## Возвращает сумму квадратов разностей соответствующих значений в двух массивах. +TAN = TAN ## Возвращает тангенс числа. +TANH = TANH ## Возвращает гиперболический тангенс числа. +TRUNC = ОТБР ## Отбрасывает дробную часть числа. + + +## +## Statistical functions Статистические функции +## +AVEDEV = СРОТКЛ ## Возвращает среднее арифметическое абсолютных значений отклонений точек данных от среднего. +AVERAGE = СРЗНАЧ ## Возвращает среднее арифметическое аргументов. +AVERAGEA = СРЗНАЧА ## Возвращает среднее арифметическое аргументов, включая числа, текст и логические значения. +AVERAGEIF = СРЗНАЧЕСЛИ ## Возвращает среднее значение (среднее арифметическое) всех ячеек в диапазоне, которые удовлетворяют данному условию. +AVERAGEIFS = СРЗНАЧЕСЛИМН ## Возвращает среднее значение (среднее арифметическое) всех ячеек, которые удовлетворяют нескольким условиям. +BETADIST = БЕТАРАСП ## Возвращает интегральную функцию бета-распределения. +BETAINV = БЕТАОБР ## Возвращает обратную интегральную функцию указанного бета-распределения. +BINOMDIST = БИНОМРАСП ## Возвращает отдельное значение биномиального распределения. +CHIDIST = ХИ2РАСП ## Возвращает одностороннюю вероятность распределения хи-квадрат. +CHIINV = ХИ2ОБР ## Возвращает обратное значение односторонней вероятности распределения хи-квадрат. +CHITEST = ХИ2ТЕСТ ## Возвращает тест на независимость. +CONFIDENCE = ДОВЕРИТ ## Возвращает доверительный интервал для среднего значения по генеральной совокупности. +CORREL = КОРРЕЛ ## Возвращает коэффициент корреляции между двумя множествами данных. +COUNT = СЧЁТ ## Подсчитывает количество чисел в списке аргументов. +COUNTA = СЧЁТЗ ## Подсчитывает количество значений в списке аргументов. +COUNTBLANK = СЧИТАТЬПУСТОТЫ ## Подсчитывает количество пустых ячеек в диапазоне +COUNTIF = СЧЁТЕСЛИ ## Подсчитывает количество ячеек в диапазоне, удовлетворяющих заданному условию +COUNTIFS = СЧЁТЕСЛИМН ## Подсчитывает количество ячеек внутри диапазона, удовлетворяющих нескольким условиям. +COVAR = КОВАР ## Возвращает ковариацию, среднее произведений парных отклонений +CRITBINOM = КРИТБИНОМ ## Возвращает наименьшее значение, для которого интегральное биномиальное распределение меньше или равно заданному критерию. +DEVSQ = КВАДРОТКЛ ## Возвращает сумму квадратов отклонений. +EXPONDIST = ЭКСПРАСП ## Возвращает экспоненциальное распределение. +FDIST = FРАСП ## Возвращает F-распределение вероятности. +FINV = FРАСПОБР ## Возвращает обратное значение для F-распределения вероятности. +FISHER = ФИШЕР ## Возвращает преобразование Фишера. +FISHERINV = ФИШЕРОБР ## Возвращает обратное преобразование Фишера. +FORECAST = ПРЕДСКАЗ ## Возвращает значение линейного тренда. +FREQUENCY = ЧАСТОТА ## Возвращает распределение частот в виде вертикального массива. +FTEST = ФТЕСТ ## Возвращает результат F-теста. +GAMMADIST = ГАММАРАСП ## Возвращает гамма-распределение. +GAMMAINV = ГАММАОБР ## Возвращает обратное гамма-распределение. +GAMMALN = ГАММАНЛОГ ## Возвращает натуральный логарифм гамма функции, Γ(x). +GEOMEAN = СРГЕОМ ## Возвращает среднее геометрическое. +GROWTH = РОСТ ## Возвращает значения в соответствии с экспоненциальным трендом. +HARMEAN = СРГАРМ ## Возвращает среднее гармоническое. +HYPGEOMDIST = ГИПЕРГЕОМЕТ ## Возвращает гипергеометрическое распределение. +INTERCEPT = ОТРЕЗОК ## Возвращает отрезок, отсекаемый на оси линией линейной регрессии. +KURT = ЭКСЦЕСС ## Возвращает эксцесс множества данных. +LARGE = НАИБОЛЬШИЙ ## Возвращает k-ое наибольшее значение в множестве данных. +LINEST = ЛИНЕЙН ## Возвращает параметры линейного тренда. +LOGEST = ЛГРФПРИБЛ ## Возвращает параметры экспоненциального тренда. +LOGINV = ЛОГНОРМОБР ## Возвращает обратное логарифмическое нормальное распределение. +LOGNORMDIST = ЛОГНОРМРАСП ## Возвращает интегральное логарифмическое нормальное распределение. +MAX = МАКС ## Возвращает наибольшее значение в списке аргументов. +MAXA = МАКСА ## Возвращает наибольшее значение в списке аргументов, включая числа, текст и логические значения. +MEDIAN = МЕДИАНА ## Возвращает медиану заданных чисел. +MIN = МИН ## Возвращает наименьшее значение в списке аргументов. +MINA = МИНА ## Возвращает наименьшее значение в списке аргументов, включая числа, текст и логические значения. +MODE = МОДА ## Возвращает значение моды множества данных. +NEGBINOMDIST = ОТРБИНОМРАСП ## Возвращает отрицательное биномиальное распределение. +NORMDIST = НОРМРАСП ## Возвращает нормальную функцию распределения. +NORMINV = НОРМОБР ## Возвращает обратное нормальное распределение. +NORMSDIST = НОРМСТРАСП ## Возвращает стандартное нормальное интегральное распределение. +NORMSINV = НОРМСТОБР ## Возвращает обратное значение стандартного нормального распределения. +PEARSON = ПИРСОН ## Возвращает коэффициент корреляции Пирсона. +PERCENTILE = ПЕРСЕНТИЛЬ ## Возвращает k-ую персентиль для значений диапазона. +PERCENTRANK = ПРОЦЕНТРАНГ ## Возвращает процентную норму значения в множестве данных. +PERMUT = ПЕРЕСТ ## Возвращает количество перестановок для заданного числа объектов. +POISSON = ПУАССОН ## Возвращает распределение Пуассона. +PROB = ВЕРОЯТНОСТЬ ## Возвращает вероятность того, что значение из диапазона находится внутри заданных пределов. +QUARTILE = КВАРТИЛЬ ## Возвращает квартиль множества данных. +RANK = РАНГ ## Возвращает ранг числа в списке чисел. +RSQ = КВПИРСОН ## Возвращает квадрат коэффициента корреляции Пирсона. +SKEW = СКОС ## Возвращает асимметрию распределения. +SLOPE = НАКЛОН ## Возвращает наклон линии линейной регрессии. +SMALL = НАИМЕНЬШИЙ ## Возвращает k-ое наименьшее значение в множестве данных. +STANDARDIZE = НОРМАЛИЗАЦИЯ ## Возвращает нормализованное значение. +STDEV = СТАНДОТКЛОН ## Оценивает стандартное отклонение по выборке. +STDEVA = СТАНДОТКЛОНА ## Оценивает стандартное отклонение по выборке, включая числа, текст и логические значения. +STDEVP = СТАНДОТКЛОНП ## Вычисляет стандартное отклонение по генеральной совокупности. +STDEVPA = СТАНДОТКЛОНПА ## Вычисляет стандартное отклонение по генеральной совокупности, включая числа, текст и логические значения. +STEYX = СТОШYX ## Возвращает стандартную ошибку предсказанных значений y для каждого значения x в регрессии. +TDIST = СТЬЮДРАСП ## Возвращает t-распределение Стьюдента. +TINV = СТЬЮДРАСПОБР ## Возвращает обратное t-распределение Стьюдента. +TREND = ТЕНДЕНЦИЯ ## Возвращает значения в соответствии с линейным трендом. +TRIMMEAN = УРЕЗСРЕДНЕЕ ## Возвращает среднее внутренности множества данных. +TTEST = ТТЕСТ ## Возвращает вероятность, соответствующую критерию Стьюдента. +VAR = ДИСП ## Оценивает дисперсию по выборке. +VARA = ДИСПА ## Оценивает дисперсию по выборке, включая числа, текст и логические значения. +VARP = ДИСПР ## Вычисляет дисперсию для генеральной совокупности. +VARPA = ДИСПРА ## Вычисляет дисперсию для генеральной совокупности, включая числа, текст и логические значения. +WEIBULL = ВЕЙБУЛЛ ## Возвращает распределение Вейбулла. +ZTEST = ZТЕСТ ## Возвращает двустороннее P-значение z-теста. + + +## +## Text functions Текстовые функции +## +ASC = ASC ## Для языков с двухбайтовыми наборами знаков (например, катакана) преобразует полноширинные (двухбайтовые) знаки в полуширинные (однобайтовые). +BAHTTEXT = БАТТЕКСТ ## Преобразует число в текст, используя денежный формат ß (БАТ). +CHAR = СИМВОЛ ## Возвращает знак с заданным кодом. +CLEAN = ПЕЧСИМВ ## Удаляет все непечатаемые знаки из текста. +CODE = КОДСИМВ ## Возвращает числовой код первого знака в текстовой строке. +CONCATENATE = СЦЕПИТЬ ## Объединяет несколько текстовых элементов в один. +DOLLAR = РУБЛЬ ## Преобразует число в текст, используя денежный формат. +EXACT = СОВПАД ## Проверяет идентичность двух текстовых значений. +FIND = НАЙТИ ## Ищет вхождения одного текстового значения в другом (с учетом регистра). +FINDB = НАЙТИБ ## Ищет вхождения одного текстового значения в другом (с учетом регистра). +FIXED = ФИКСИРОВАННЫЙ ## Форматирует число и преобразует его в текст с заданным числом десятичных знаков. +JIS = JIS ## Для языков с двухбайтовыми наборами знаков (например, катакана) преобразует полуширинные (однобайтовые) знаки в текстовой строке в полноширинные (двухбайтовые). +LEFT = ЛЕВСИМВ ## Возвращает крайние слева знаки текстового значения. +LEFTB = ЛЕВБ ## Возвращает крайние слева знаки текстового значения. +LEN = ДЛСТР ## Возвращает количество знаков в текстовой строке. +LENB = ДЛИНБ ## Возвращает количество знаков в текстовой строке. +LOWER = СТРОЧН ## Преобразует все буквы текста в строчные. +MID = ПСТР ## Возвращает заданное число знаков из строки текста, начиная с указанной позиции. +MIDB = ПСТРБ ## Возвращает заданное число знаков из строки текста, начиная с указанной позиции. +PHONETIC = PHONETIC ## Извлекает фонетические (фуригана) знаки из текстовой строки. +PROPER = ПРОПНАЧ ## Преобразует первую букву в каждом слове текста в прописную. +REPLACE = ЗАМЕНИТЬ ## Заменяет знаки в тексте. +REPLACEB = ЗАМЕНИТЬБ ## Заменяет знаки в тексте. +REPT = ПОВТОР ## Повторяет текст заданное число раз. +RIGHT = ПРАВСИМВ ## Возвращает крайние справа знаки текстовой строки. +RIGHTB = ПРАВБ ## Возвращает крайние справа знаки текстовой строки. +SEARCH = ПОИСК ## Ищет вхождения одного текстового значения в другом (без учета регистра). +SEARCHB = ПОИСКБ ## Ищет вхождения одного текстового значения в другом (без учета регистра). +SUBSTITUTE = ПОДСТАВИТЬ ## Заменяет в текстовой строке старый текст новым. +T = Т ## Преобразует аргументы в текст. +TEXT = ТЕКСТ ## Форматирует число и преобразует его в текст. +TRIM = СЖПРОБЕЛЫ ## Удаляет из текста пробелы. +UPPER = ПРОПИСН ## Преобразует все буквы текста в прописные. +VALUE = ЗНАЧЕН ## Преобразует текстовый аргумент в число. diff --git a/lib/phpexcel/PHPExcel/locale/sv/config b/lib/phpexcel/PHPExcel/locale/sv/config new file mode 100644 index 0000000..5d1a9a9 --- /dev/null +++ b/lib/phpexcel/PHPExcel/locale/sv/config @@ -0,0 +1,47 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Settings +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## + + +ArgumentSeparator = ; + + +## +## (For future use) +## +currencySymbol = kr + + +## +## Excel Error Codes (For future use) +## +NULL = #Skärning! +DIV0 = #Division/0! +VALUE = #Värdefel! +REF = #Referens! +NAME = #Namn? +NUM = #Ogiltigt! +NA = #Saknas! diff --git a/lib/phpexcel/PHPExcel/locale/sv/functions b/lib/phpexcel/PHPExcel/locale/sv/functions new file mode 100644 index 0000000..9af37d8 --- /dev/null +++ b/lib/phpexcel/PHPExcel/locale/sv/functions @@ -0,0 +1,408 @@ +## +## Add-in and Automation functions Tilläggs- och automatiseringsfunktioner +## +GETPIVOTDATA = HÄMTA.PIVOTDATA ## Returnerar data som lagrats i en pivottabellrapport + + +## +## Cube functions Kubfunktioner +## +CUBEKPIMEMBER = KUBKPIMEDLEM ## Returnerar namn, egenskap och mått för en KPI och visar namnet och egenskapen i cellen. En KPI, eller prestandaindikator, är ett kvantifierbart mått, t.ex. månatlig bruttovinst eller personalomsättning per kvartal, som används för att analysera ett företags resultat. +CUBEMEMBER = KUBMEDLEM ## Returnerar en medlem eller ett par i en kubhierarki. Används för att verifiera att medlemmen eller paret finns i kuben. +CUBEMEMBERPROPERTY = KUBMEDLEMSEGENSKAP ## Returnerar värdet för en medlemsegenskap i kuben. Används för att verifiera att ett medlemsnamn finns i kuben, samt för att returnera den angivna egenskapen för medlemmen. +CUBERANKEDMEMBER = KUBRANGORDNADMEDLEM ## Returnerar den n:te, eller rangordnade, medlemmen i en uppsättning. Används för att returnera ett eller flera element i en uppsättning, till exempelvis den bästa försäljaren eller de tio bästa eleverna. +CUBESET = KUBINSTÄLLNING ## Definierar en beräknad uppsättning medlemmar eller par genom att skicka ett bestämt uttryck till kuben på servern, som skapar uppsättningen och sedan returnerar den till Microsoft Office Excel. +CUBESETCOUNT = KUBINSTÄLLNINGANTAL ## Returnerar antalet objekt i en uppsättning. +CUBEVALUE = KUBVÄRDE ## Returnerar ett mängdvärde från en kub. + + +## +## Database functions Databasfunktioner +## +DAVERAGE = DMEDEL ## Returnerar medelvärdet av databasposterna +DCOUNT = DANTAL ## Räknar antalet celler som innehåller tal i en databas +DCOUNTA = DANTALV ## Räknar ifyllda celler i en databas +DGET = DHÄMTA ## Hämtar en enstaka post från en databas som uppfyller de angivna villkoren +DMAX = DMAX ## Returnerar det största värdet från databasposterna +DMIN = DMIN ## Returnerar det minsta värdet från databasposterna +DPRODUCT = DPRODUKT ## Multiplicerar värdena i ett visst fält i poster som uppfyller villkoret +DSTDEV = DSTDAV ## Uppskattar standardavvikelsen baserat på ett urval av databasposterna +DSTDEVP = DSTDAVP ## Beräknar standardavvikelsen utifrån hela populationen av valda databasposter +DSUM = DSUMMA ## Summerar talen i kolumnfält i databasposter som uppfyller villkoret +DVAR = DVARIANS ## Uppskattar variansen baserat på ett urval av databasposterna +DVARP = DVARIANSP ## Beräknar variansen utifrån hela populationen av valda databasposter + + +## +## Date and time functions Tid- och datumfunktioner +## +DATE = DATUM ## Returnerar ett serienummer för ett visst datum +DATEVALUE = DATUMVÄRDE ## Konverterar ett datum i textformat till ett serienummer +DAY = DAG ## Konverterar ett serienummer till dag i månaden +DAYS360 = DAGAR360 ## Beräknar antalet dagar mellan två datum baserat på ett 360-dagarsår +EDATE = EDATUM ## Returnerar serienumret för ett datum som infaller ett visst antal månader före eller efter startdatumet +EOMONTH = SLUTMÅNAD ## Returnerar serienumret för sista dagen i månaden ett visst antal månader tidigare eller senare +HOUR = TIMME ## Konverterar ett serienummer till en timme +MINUTE = MINUT ## Konverterar ett serienummer till en minut +MONTH = MÅNAD ## Konverterar ett serienummer till en månad +NETWORKDAYS = NETTOARBETSDAGAR ## Returnerar antalet hela arbetsdagar mellan två datum +NOW = NU ## Returnerar serienumret för dagens datum och aktuell tid +SECOND = SEKUND ## Konverterar ett serienummer till en sekund +TIME = KLOCKSLAG ## Returnerar serienumret för en viss tid +TIMEVALUE = TIDVÄRDE ## Konverterar en tid i textformat till ett serienummer +TODAY = IDAG ## Returnerar serienumret för dagens datum +WEEKDAY = VECKODAG ## Konverterar ett serienummer till en dag i veckan +WEEKNUM = VECKONR ## Konverterar ett serienummer till ett veckonummer +WORKDAY = ARBETSDAGAR ## Returnerar serienumret för ett datum ett visst antal arbetsdagar tidigare eller senare +YEAR = ÅR ## Konverterar ett serienummer till ett år +YEARFRAC = ÅRDEL ## Returnerar en del av ett år som representerar antalet hela dagar mellan start- och slutdatum + + +## +## Engineering functions Tekniska funktioner +## +BESSELI = BESSELI ## Returnerar den modifierade Bessel-funktionen In(x) +BESSELJ = BESSELJ ## Returnerar Bessel-funktionen Jn(x) +BESSELK = BESSELK ## Returnerar den modifierade Bessel-funktionen Kn(x) +BESSELY = BESSELY ## Returnerar Bessel-funktionen Yn(x) +BIN2DEC = BIN.TILL.DEC ## Omvandlar ett binärt tal till decimalt +BIN2HEX = BIN.TILL.HEX ## Omvandlar ett binärt tal till hexadecimalt +BIN2OCT = BIN.TILL.OKT ## Omvandlar ett binärt tal till oktalt +COMPLEX = KOMPLEX ## Omvandlar reella och imaginära koefficienter till ett komplext tal +CONVERT = KONVERTERA ## Omvandlar ett tal från ett måttsystem till ett annat +DEC2BIN = DEC.TILL.BIN ## Omvandlar ett decimalt tal till binärt +DEC2HEX = DEC.TILL.HEX ## Omvandlar ett decimalt tal till hexadecimalt +DEC2OCT = DEC.TILL.OKT ## Omvandlar ett decimalt tal till oktalt +DELTA = DELTA ## Testar om två värden är lika +ERF = FELF ## Returnerar felfunktionen +ERFC = FELFK ## Returnerar den komplementära felfunktionen +GESTEP = SLSTEG ## Testar om ett tal är större än ett tröskelvärde +HEX2BIN = HEX.TILL.BIN ## Omvandlar ett hexadecimalt tal till binärt +HEX2DEC = HEX.TILL.DEC ## Omvandlar ett hexadecimalt tal till decimalt +HEX2OCT = HEX.TILL.OKT ## Omvandlar ett hexadecimalt tal till oktalt +IMABS = IMABS ## Returnerar absolutvärdet (modulus) för ett komplext tal +IMAGINARY = IMAGINÄR ## Returnerar den imaginära koefficienten för ett komplext tal +IMARGUMENT = IMARGUMENT ## Returnerar det komplexa talets argument, en vinkel uttryckt i radianer +IMCONJUGATE = IMKONJUGAT ## Returnerar det komplexa talets konjugat +IMCOS = IMCOS ## Returnerar cosinus för ett komplext tal +IMDIV = IMDIV ## Returnerar kvoten för två komplexa tal +IMEXP = IMEUPPHÖJT ## Returnerar exponenten för ett komplext tal +IMLN = IMLN ## Returnerar den naturliga logaritmen för ett komplext tal +IMLOG10 = IMLOG10 ## Returnerar 10-logaritmen för ett komplext tal +IMLOG2 = IMLOG2 ## Returnerar 2-logaritmen för ett komplext tal +IMPOWER = IMUPPHÖJT ## Returnerar ett komplext tal upphöjt till en exponent +IMPRODUCT = IMPRODUKT ## Returnerar produkten av komplexa tal +IMREAL = IMREAL ## Returnerar den reella koefficienten för ett komplext tal +IMSIN = IMSIN ## Returnerar sinus för ett komplext tal +IMSQRT = IMROT ## Returnerar kvadratroten av ett komplext tal +IMSUB = IMDIFF ## Returnerar differensen mellan två komplexa tal +IMSUM = IMSUM ## Returnerar summan av komplexa tal +OCT2BIN = OKT.TILL.BIN ## Omvandlar ett oktalt tal till binärt +OCT2DEC = OKT.TILL.DEC ## Omvandlar ett oktalt tal till decimalt +OCT2HEX = OKT.TILL.HEX ## Omvandlar ett oktalt tal till hexadecimalt + + +## +## Financial functions Finansiella funktioner +## +ACCRINT = UPPLRÄNTA ## Returnerar den upplupna räntan för värdepapper med periodisk ränta +ACCRINTM = UPPLOBLRÄNTA ## Returnerar den upplupna räntan för ett värdepapper som ger avkastning på förfallodagen +AMORDEGRC = AMORDEGRC ## Returnerar avskrivningen för varje redovisningsperiod med hjälp av en avskrivningskoefficient +AMORLINC = AMORLINC ## Returnerar avskrivningen för varje redovisningsperiod +COUPDAYBS = KUPDAGBB ## Returnerar antal dagar från början av kupongperioden till likviddagen +COUPDAYS = KUPDAGARS ## Returnerar antalet dagar i kupongperioden som innehåller betalningsdatumet +COUPDAYSNC = KUPDAGNK ## Returnerar antalet dagar från betalningsdatumet till nästa kupongdatum +COUPNCD = KUPNKD ## Returnerar nästa kupongdatum efter likviddagen +COUPNUM = KUPANT ## Returnerar kuponger som förfaller till betalning mellan likviddagen och förfallodagen +COUPPCD = KUPFKD ## Returnerar föregående kupongdatum före likviddagen +CUMIPMT = KUMRÄNTA ## Returnerar den ackumulerade räntan som betalats mellan två perioder +CUMPRINC = KUMPRIS ## Returnerar det ackumulerade kapitalbeloppet som betalats på ett lån mellan två perioder +DB = DB ## Returnerar avskrivningen för en tillgång under en angiven tid enligt metoden för fast degressiv avskrivning +DDB = DEGAVSKR ## Returnerar en tillgångs värdeminskning under en viss period med hjälp av dubbel degressiv avskrivning eller någon annan metod som du anger +DISC = DISK ## Returnerar diskonteringsräntan för ett värdepapper +DOLLARDE = DECTAL ## Omvandlar ett pris uttryckt som ett bråk till ett decimaltal +DOLLARFR = BRÅK ## Omvandlar ett pris i kronor uttryckt som ett decimaltal till ett bråk +DURATION = LÖPTID ## Returnerar den årliga löptiden för en säkerhet med periodiska räntebetalningar +EFFECT = EFFRÄNTA ## Returnerar den årliga effektiva räntesatsen +FV = SLUTVÄRDE ## Returnerar det framtida värdet på en investering +FVSCHEDULE = FÖRRÄNTNING ## Returnerar det framtida värdet av ett begynnelsekapital beräknat på olika räntenivåer +INTRATE = ÅRSRÄNTA ## Returnerar räntesatsen för ett betalt värdepapper +IPMT = RBETALNING ## Returnerar räntedelen av en betalning för en given period +IRR = IR ## Returnerar internräntan för en serie betalningar +ISPMT = RALÅN ## Beräknar räntan som har betalats under en specifik betalningsperiod +MDURATION = MLÖPTID ## Returnerar den modifierade Macauley-löptiden för ett värdepapper med det antagna nominella värdet 100 kr +MIRR = MODIR ## Returnerar internräntan där positiva och negativa betalningar finansieras med olika räntor +NOMINAL = NOMRÄNTA ## Returnerar den årliga nominella räntesatsen +NPER = PERIODER ## Returnerar antalet perioder för en investering +NPV = NETNUVÄRDE ## Returnerar nuvärdet av en serie periodiska betalningar vid en given diskonteringsränta +ODDFPRICE = UDDAFPRIS ## Returnerar priset per 100 kr nominellt värde för ett värdepapper med en udda första period +ODDFYIELD = UDDAFAVKASTNING ## Returnerar avkastningen för en säkerhet med en udda första period +ODDLPRICE = UDDASPRIS ## Returnerar priset per 100 kr nominellt värde för ett värdepapper med en udda sista period +ODDLYIELD = UDDASAVKASTNING ## Returnerar avkastningen för en säkerhet med en udda sista period +PMT = BETALNING ## Returnerar den periodiska betalningen för en annuitet +PPMT = AMORT ## Returnerar amorteringsdelen av en annuitetsbetalning för en given period +PRICE = PRIS ## Returnerar priset per 100 kr nominellt värde för ett värdepapper som ger periodisk ränta +PRICEDISC = PRISDISK ## Returnerar priset per 100 kr nominellt värde för ett diskonterat värdepapper +PRICEMAT = PRISFÖRF ## Returnerar priset per 100 kr nominellt värde för ett värdepapper som ger ränta på förfallodagen +PV = PV ## Returnerar nuvärdet av en serie lika stora periodiska betalningar +RATE = RÄNTA ## Returnerar räntesatsen per period i en annuitet +RECEIVED = BELOPP ## Returnerar beloppet som utdelas på förfallodagen för ett betalat värdepapper +SLN = LINAVSKR ## Returnerar den linjära avskrivningen för en tillgång under en period +SYD = ÅRSAVSKR ## Returnerar den årliga avskrivningssumman för en tillgång under en angiven period +TBILLEQ = SSVXEKV ## Returnerar avkastningen motsvarande en obligation för en statsskuldväxel +TBILLPRICE = SSVXPRIS ## Returnerar priset per 100 kr nominellt värde för en statsskuldväxel +TBILLYIELD = SSVXRÄNTA ## Returnerar avkastningen för en statsskuldväxel +VDB = VDEGRAVSKR ## Returnerar avskrivningen för en tillgång under en angiven period (med degressiv avskrivning) +XIRR = XIRR ## Returnerar internräntan för en serie betalningar som inte nödvändigtvis är periodiska +XNPV = XNUVÄRDE ## Returnerar det nuvarande nettovärdet för en serie betalningar som inte nödvändigtvis är periodiska +YIELD = NOMAVK ## Returnerar avkastningen för ett värdepapper som ger periodisk ränta +YIELDDISC = NOMAVKDISK ## Returnerar den årliga avkastningen för diskonterade värdepapper, exempelvis en statsskuldväxel +YIELDMAT = NOMAVKFÖRF ## Returnerar den årliga avkastningen för ett värdepapper som ger ränta på förfallodagen + + +## +## Information functions Informationsfunktioner +## +CELL = CELL ## Returnerar information om formatering, plats och innehåll i en cell +ERROR.TYPE = FEL.TYP ## Returnerar ett tal som motsvarar ett felvärde +INFO = INFO ## Returnerar information om operativsystemet +ISBLANK = ÄRREF ## Returnerar SANT om värdet är tomt +ISERR = Ä ## Returnerar SANT om värdet är ett felvärde annat än #SAKNAS! +ISERROR = ÄRFEL ## Returnerar SANT om värdet är ett felvärde +ISEVEN = ÄRJÄMN ## Returnerar SANT om talet är jämnt +ISLOGICAL = ÄREJTEXT ## Returnerar SANT om värdet är ett logiskt värde +ISNA = ÄRLOGISK ## Returnerar SANT om värdet är felvärdet #SAKNAS! +ISNONTEXT = ÄRSAKNAD ## Returnerar SANT om värdet inte är text +ISNUMBER = ÄRTAL ## Returnerar SANT om värdet är ett tal +ISODD = ÄRUDDA ## Returnerar SANT om talet är udda +ISREF = ÄRTOM ## Returnerar SANT om värdet är en referens +ISTEXT = ÄRTEXT ## Returnerar SANT om värdet är text +N = N ## Returnerar ett värde omvandlat till ett tal +NA = SAKNAS ## Returnerar felvärdet #SAKNAS! +TYPE = VÄRDETYP ## Returnerar ett tal som anger värdets datatyp + + +## +## Logical functions Logiska funktioner +## +AND = OCH ## Returnerar SANT om alla argument är sanna +FALSE = FALSKT ## Returnerar det logiska värdet FALSKT +IF = OM ## Anger vilket logiskt test som ska utföras +IFERROR = OMFEL ## Returnerar ett värde som du anger om en formel utvärderar till ett fel; annars returneras resultatet av formeln +NOT = ICKE ## Inverterar logiken för argumenten +OR = ELLER ## Returnerar SANT om något argument är SANT +TRUE = SANT ## Returnerar det logiska värdet SANT + + +## +## Lookup and reference functions Sök- och referensfunktioner +## +ADDRESS = ADRESS ## Returnerar en referens som text till en enstaka cell i ett kalkylblad +AREAS = OMRÅDEN ## Returnerar antalet områden i en referens +CHOOSE = VÄLJ ## Väljer ett värde i en lista över värden +COLUMN = KOLUMN ## Returnerar kolumnnumret för en referens +COLUMNS = KOLUMNER ## Returnerar antalet kolumner i en referens +HLOOKUP = LETAKOLUMN ## Söker i den översta raden i en matris och returnerar värdet för angiven cell +HYPERLINK = HYPERLÄNK ## Skapar en genväg eller ett hopp till ett dokument i nätverket, i ett intranät eller på Internet +INDEX = INDEX ## Använder ett index för ett välja ett värde i en referens eller matris +INDIRECT = INDIREKT ## Returnerar en referens som anges av ett textvärde +LOOKUP = LETAUPP ## Letar upp värden i en vektor eller matris +MATCH = PASSA ## Letar upp värden i en referens eller matris +OFFSET = FÖRSKJUTNING ## Returnerar en referens förskjuten i förhållande till en given referens +ROW = RAD ## Returnerar radnumret för en referens +ROWS = RADER ## Returnerar antalet rader i en referens +RTD = RTD ## Hämtar realtidsdata från ett program som stöder COM-automation (Automation: Ett sätt att arbeta med ett programs objekt från ett annat program eller utvecklingsverktyg. Detta kallades tidigare för OLE Automation, och är en branschstandard och ingår i Component Object Model (COM).) +TRANSPOSE = TRANSPONERA ## Transponerar en matris +VLOOKUP = LETARAD ## Letar i den första kolumnen i en matris och flyttar över raden för att returnera värdet för en cell + + +## +## Math and trigonometry functions Matematiska och trigonometriska funktioner +## +ABS = ABS ## Returnerar absolutvärdet av ett tal +ACOS = ARCCOS ## Returnerar arcus cosinus för ett tal +ACOSH = ARCCOSH ## Returnerar inverterad hyperbolisk cosinus för ett tal +ASIN = ARCSIN ## Returnerar arcus cosinus för ett tal +ASINH = ARCSINH ## Returnerar hyperbolisk arcus sinus för ett tal +ATAN = ARCTAN ## Returnerar arcus tangens för ett tal +ATAN2 = ARCTAN2 ## Returnerar arcus tangens för en x- och en y- koordinat +ATANH = ARCTANH ## Returnerar hyperbolisk arcus tangens för ett tal +CEILING = RUNDA.UPP ## Avrundar ett tal till närmaste heltal eller närmaste signifikanta multipel +COMBIN = KOMBIN ## Returnerar antalet kombinationer för ett givet antal objekt +COS = COS ## Returnerar cosinus för ett tal +COSH = COSH ## Returnerar hyperboliskt cosinus för ett tal +DEGREES = GRADER ## Omvandlar radianer till grader +EVEN = JÄMN ## Avrundar ett tal uppåt till närmaste heltal +EXP = EXP ## Returnerar e upphöjt till ett givet tal +FACT = FAKULTET ## Returnerar fakulteten för ett tal +FACTDOUBLE = DUBBELFAKULTET ## Returnerar dubbelfakulteten för ett tal +FLOOR = RUNDA.NED ## Avrundar ett tal nedåt mot noll +GCD = SGD ## Returnerar den största gemensamma nämnaren +INT = HELTAL ## Avrundar ett tal nedåt till närmaste heltal +LCM = MGM ## Returnerar den minsta gemensamma multipeln +LN = LN ## Returnerar den naturliga logaritmen för ett tal +LOG = LOG ## Returnerar logaritmen för ett tal för en given bas +LOG10 = LOG10 ## Returnerar 10-logaritmen för ett tal +MDETERM = MDETERM ## Returnerar matrisen som är avgörandet av en matris +MINVERSE = MINVERT ## Returnerar matrisinversen av en matris +MMULT = MMULT ## Returnerar matrisprodukten av två matriser +MOD = REST ## Returnerar resten vid en division +MROUND = MAVRUNDA ## Returnerar ett tal avrundat till en given multipel +MULTINOMIAL = MULTINOMIAL ## Returnerar multinomialen för en uppsättning tal +ODD = UDDA ## Avrundar ett tal uppåt till närmaste udda heltal +PI = PI ## Returnerar värdet pi +POWER = UPPHÖJT.TILL ## Returnerar resultatet av ett tal upphöjt till en exponent +PRODUCT = PRODUKT ## Multiplicerar argumenten +QUOTIENT = KVOT ## Returnerar heltalsdelen av en division +RADIANS = RADIANER ## Omvandlar grader till radianer +RAND = SLUMP ## Returnerar ett slumptal mellan 0 och 1 +RANDBETWEEN = SLUMP.MELLAN ## Returnerar ett slumptal mellan de tal som du anger +ROMAN = ROMERSK ## Omvandlar vanliga (arabiska) siffror till romerska som text +ROUND = AVRUNDA ## Avrundar ett tal till ett angivet antal siffror +ROUNDDOWN = AVRUNDA.NEDÅT ## Avrundar ett tal nedåt mot noll +ROUNDUP = AVRUNDA.UPPÅT ## Avrundar ett tal uppåt, från noll +SERIESSUM = SERIESUMMA ## Returnerar summan av en potensserie baserat på formeln +SIGN = TECKEN ## Returnerar tecknet för ett tal +SIN = SIN ## Returnerar sinus för en given vinkel +SINH = SINH ## Returnerar hyperbolisk sinus för ett tal +SQRT = ROT ## Returnerar den positiva kvadratroten +SQRTPI = ROTPI ## Returnerar kvadratroten för (tal * pi) +SUBTOTAL = DELSUMMA ## Returnerar en delsumma i en lista eller databas +SUM = SUMMA ## Summerar argumenten +SUMIF = SUMMA.OM ## Summerar celler enligt ett angivet villkor +SUMIFS = SUMMA.OMF ## Lägger till cellerna i ett område som uppfyller flera kriterier +SUMPRODUCT = PRODUKTSUMMA ## Returnerar summan av produkterna i motsvarande matriskomponenter +SUMSQ = KVADRATSUMMA ## Returnerar summan av argumentens kvadrater +SUMX2MY2 = SUMMAX2MY2 ## Returnerar summan av differensen mellan kvadraterna för motsvarande värden i två matriser +SUMX2PY2 = SUMMAX2PY2 ## Returnerar summan av summan av kvadraterna av motsvarande värden i två matriser +SUMXMY2 = SUMMAXMY2 ## Returnerar summan av kvadraten av skillnaden mellan motsvarande värden i två matriser +TAN = TAN ## Returnerar tangens för ett tal +TANH = TANH ## Returnerar hyperbolisk tangens för ett tal +TRUNC = AVKORTA ## Avkortar ett tal till ett heltal + + +## +## Statistical functions Statistiska funktioner +## +AVEDEV = MEDELAVV ## Returnerar medelvärdet för datapunkters absoluta avvikelse från deras medelvärde +AVERAGE = MEDEL ## Returnerar medelvärdet av argumenten +AVERAGEA = AVERAGEA ## Returnerar medelvärdet av argumenten, inklusive tal, text och logiska värden +AVERAGEIF = MEDELOM ## Returnerar medelvärdet (aritmetiskt medelvärde) för alla celler i ett område som uppfyller ett givet kriterium +AVERAGEIFS = MEDELOMF ## Returnerar medelvärdet (det aritmetiska medelvärdet) för alla celler som uppfyller flera villkor. +BETADIST = BETAFÖRD ## Returnerar den kumulativa betafördelningsfunktionen +BETAINV = BETAINV ## Returnerar inversen till den kumulativa fördelningsfunktionen för en viss betafördelning +BINOMDIST = BINOMFÖRD ## Returnerar den individuella binomialfördelningen +CHIDIST = CHI2FÖRD ## Returnerar den ensidiga sannolikheten av c2-fördelningen +CHIINV = CHI2INV ## Returnerar inversen av chi2-fördelningen +CHITEST = CHI2TEST ## Returnerar oberoendetesten +CONFIDENCE = KONFIDENS ## Returnerar konfidensintervallet för en populations medelvärde +CORREL = KORREL ## Returnerar korrelationskoefficienten mellan två datamängder +COUNT = ANTAL ## Räknar hur många tal som finns bland argumenten +COUNTA = ANTALV ## Räknar hur många värden som finns bland argumenten +COUNTBLANK = ANTAL.TOMMA ## Räknar antalet tomma celler i ett område +COUNTIF = ANTAL.OM ## Räknar antalet celler i ett område som uppfyller angivna villkor. +COUNTIFS = ANTAL.OMF ## Räknar antalet celler i ett område som uppfyller flera villkor. +COVAR = KOVAR ## Returnerar kovariansen, d.v.s. medelvärdet av produkterna för parade avvikelser +CRITBINOM = KRITBINOM ## Returnerar det minsta värdet för vilket den kumulativa binomialfördelningen är mindre än eller lika med ett villkorsvärde +DEVSQ = KVADAVV ## Returnerar summan av kvadrater på avvikelser +EXPONDIST = EXPONFÖRD ## Returnerar exponentialfördelningen +FDIST = FFÖRD ## Returnerar F-sannolikhetsfördelningen +FINV = FINV ## Returnerar inversen till F-sannolikhetsfördelningen +FISHER = FISHER ## Returnerar Fisher-transformationen +FISHERINV = FISHERINV ## Returnerar inversen till Fisher-transformationen +FORECAST = PREDIKTION ## Returnerar ett värde längs en linjär trendlinje +FREQUENCY = FREKVENS ## Returnerar en frekvensfördelning som en lodrät matris +FTEST = FTEST ## Returnerar resultatet av en F-test +GAMMADIST = GAMMAFÖRD ## Returnerar gammafördelningen +GAMMAINV = GAMMAINV ## Returnerar inversen till den kumulativa gammafördelningen +GAMMALN = GAMMALN ## Returnerar den naturliga logaritmen för gammafunktionen, G(x) +GEOMEAN = GEOMEDEL ## Returnerar det geometriska medelvärdet +GROWTH = EXPTREND ## Returnerar värden längs en exponentiell trend +HARMEAN = HARMMEDEL ## Returnerar det harmoniska medelvärdet +HYPGEOMDIST = HYPGEOMFÖRD ## Returnerar den hypergeometriska fördelningen +INTERCEPT = SKÄRNINGSPUNKT ## Returnerar skärningspunkten för en linjär regressionslinje +KURT = TOPPIGHET ## Returnerar toppigheten av en mängd data +LARGE = STÖRSTA ## Returnerar det n:te största värdet i en mängd data +LINEST = REGR ## Returnerar parametrar till en linjär trendlinje +LOGEST = EXPREGR ## Returnerar parametrarna i en exponentiell trend +LOGINV = LOGINV ## Returnerar inversen till den lognormala fördelningen +LOGNORMDIST = LOGNORMFÖRD ## Returnerar den kumulativa lognormala fördelningen +MAX = MAX ## Returnerar det största värdet i en lista av argument +MAXA = MAXA ## Returnerar det största värdet i en lista av argument, inklusive tal, text och logiska värden +MEDIAN = MEDIAN ## Returnerar medianen för angivna tal +MIN = MIN ## Returnerar det minsta värdet i en lista med argument +MINA = MINA ## Returnerar det minsta värdet i en lista över argument, inklusive tal, text och logiska värden +MODE = TYPVÄRDE ## Returnerar det vanligaste värdet i en datamängd +NEGBINOMDIST = NEGBINOMFÖRD ## Returnerar den negativa binomialfördelningen +NORMDIST = NORMFÖRD ## Returnerar den kumulativa normalfördelningen +NORMINV = NORMINV ## Returnerar inversen till den kumulativa normalfördelningen +NORMSDIST = NORMSFÖRD ## Returnerar den kumulativa standardnormalfördelningen +NORMSINV = NORMSINV ## Returnerar inversen till den kumulativa standardnormalfördelningen +PEARSON = PEARSON ## Returnerar korrelationskoefficienten till Pearsons momentprodukt +PERCENTILE = PERCENTIL ## Returnerar den n:te percentilen av värden i ett område +PERCENTRANK = PROCENTRANG ## Returnerar procentrangen för ett värde i en datamängd +PERMUT = PERMUT ## Returnerar antal permutationer för ett givet antal objekt +POISSON = POISSON ## Returnerar Poisson-fördelningen +PROB = SANNOLIKHET ## Returnerar sannolikheten att värden i ett område ligger mellan två gränser +QUARTILE = KVARTIL ## Returnerar kvartilen av en mängd data +RANK = RANG ## Returnerar rangordningen för ett tal i en lista med tal +RSQ = RKV ## Returnerar kvadraten av Pearsons produktmomentkorrelationskoefficient +SKEW = SNEDHET ## Returnerar snedheten för en fördelning +SLOPE = LUTNING ## Returnerar lutningen på en linjär regressionslinje +SMALL = MINSTA ## Returnerar det n:te minsta värdet i en mängd data +STANDARDIZE = STANDARDISERA ## Returnerar ett normaliserat värde +STDEV = STDAV ## Uppskattar standardavvikelsen baserat på ett urval +STDEVA = STDEVA ## Uppskattar standardavvikelsen baserat på ett urval, inklusive tal, text och logiska värden +STDEVP = STDAVP ## Beräknar standardavvikelsen baserat på hela populationen +STDEVPA = STDEVPA ## Beräknar standardavvikelsen baserat på hela populationen, inklusive tal, text och logiska värden +STEYX = STDFELYX ## Returnerar standardfelet för ett förutspått y-värde för varje x-värde i regressionen +TDIST = TFÖRD ## Returnerar Students t-fördelning +TINV = TINV ## Returnerar inversen till Students t-fördelning +TREND = TREND ## Returnerar värden längs en linjär trend +TRIMMEAN = TRIMMEDEL ## Returnerar medelvärdet av mittpunkterna i en datamängd +TTEST = TTEST ## Returnerar sannolikheten beräknad ur Students t-test +VAR = VARIANS ## Uppskattar variansen baserat på ett urval +VARA = VARA ## Uppskattar variansen baserat på ett urval, inklusive tal, text och logiska värden +VARP = VARIANSP ## Beräknar variansen baserat på hela populationen +VARPA = VARPA ## Beräknar variansen baserat på hela populationen, inklusive tal, text och logiska värden +WEIBULL = WEIBULL ## Returnerar Weibull-fördelningen +ZTEST = ZTEST ## Returnerar det ensidiga sannolikhetsvärdet av ett z-test + + +## +## Text functions Textfunktioner +## +ASC = ASC ## Ändrar helbredds (dubbel byte) engelska bokstäver eller katakana inom en teckensträng till tecken med halvt breddsteg (enkel byte) +BAHTTEXT = BAHTTEXT ## Omvandlar ett tal till text med valutaformatet ß (baht) +CHAR = TECKENKOD ## Returnerar tecknet som anges av kod +CLEAN = STÄDA ## Tar bort alla icke utskrivbara tecken i en text +CODE = KOD ## Returnerar en numerisk kod för det första tecknet i en textsträng +CONCATENATE = SAMMANFOGA ## Sammanfogar flera textdelar till en textsträng +DOLLAR = VALUTA ## Omvandlar ett tal till text med valutaformat +EXACT = EXAKT ## Kontrollerar om två textvärden är identiska +FIND = HITTA ## Hittar en text i en annan (skiljer på gemener och versaler) +FINDB = HITTAB ## Hittar en text i en annan (skiljer på gemener och versaler) +FIXED = FASTTAL ## Formaterar ett tal som text med ett fast antal decimaler +JIS = JIS ## Ändrar halvbredds (enkel byte) engelska bokstäver eller katakana inom en teckensträng till tecken med helt breddsteg (dubbel byte) +LEFT = VÄNSTER ## Returnerar tecken längst till vänster i en sträng +LEFTB = VÄNSTERB ## Returnerar tecken längst till vänster i en sträng +LEN = LÄNGD ## Returnerar antalet tecken i en textsträng +LENB = LÄNGDB ## Returnerar antalet tecken i en textsträng +LOWER = GEMENER ## Omvandlar text till gemener +MID = EXTEXT ## Returnerar angivet antal tecken från en text med början vid den position som du anger +MIDB = EXTEXTB ## Returnerar angivet antal tecken från en text med början vid den position som du anger +PHONETIC = PHONETIC ## Returnerar de fonetiska (furigana) tecknen i en textsträng +PROPER = INITIAL ## Ändrar första bokstaven i varje ord i ett textvärde till versal +REPLACE = ERSÄTT ## Ersätter tecken i text +REPLACEB = ERSÄTTB ## Ersätter tecken i text +REPT = REP ## Upprepar en text ett bestämt antal gånger +RIGHT = HÖGER ## Returnerar tecken längst till höger i en sträng +RIGHTB = HÖGERB ## Returnerar tecken längst till höger i en sträng +SEARCH = SÖK ## Hittar ett textvärde i ett annat (skiljer inte på gemener och versaler) +SEARCHB = SÖKB ## Hittar ett textvärde i ett annat (skiljer inte på gemener och versaler) +SUBSTITUTE = BYT.UT ## Ersätter gammal text med ny text i en textsträng +T = T ## Omvandlar argumenten till text +TEXT = TEXT ## Formaterar ett tal och omvandlar det till text +TRIM = RENSA ## Tar bort blanksteg från text +UPPER = VERSALER ## Omvandlar text till versaler +VALUE = TEXTNUM ## Omvandlar ett textargument till ett tal diff --git a/lib/phpexcel/PHPExcel/locale/tr/config b/lib/phpexcel/PHPExcel/locale/tr/config new file mode 100644 index 0000000..de69cf5 --- /dev/null +++ b/lib/phpexcel/PHPExcel/locale/tr/config @@ -0,0 +1,47 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Settings +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## + + +ArgumentSeparator = ; + + +## +## (For future use) +## +currencySymbol = YTL + + +## +## Excel Error Codes (For future use) +## +NULL = #BOŞ! +DIV0 = #SAYI/0! +VALUE = #DEĞER! +REF = #BAŞV! +NAME = #AD? +NUM = #SAYI! +NA = #YOK diff --git a/lib/phpexcel/PHPExcel/locale/tr/functions b/lib/phpexcel/PHPExcel/locale/tr/functions new file mode 100644 index 0000000..c327bca --- /dev/null +++ b/lib/phpexcel/PHPExcel/locale/tr/functions @@ -0,0 +1,438 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Calculation +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## Data in this file derived from http://www.piuha.fi/excel-function-name-translation/ +## +## + + +## +## Add-in and Automation functions Eklenti ve Otomasyon fonksiyonları +## +GETPIVOTDATA = ÖZETVERİAL ## Bir Özet Tablo raporunda saklanan verileri verir. + + +## +## Cube functions Küp işlevleri +## +CUBEKPIMEMBER = KÜPKPIÜYE ## Kilit performans göstergesi (KPI-Key Performance Indicator) adını, özelliğini ve ölçüsünü verir ve hücredeki ad ve özelliği gösterir. KPI, bir kurumun performansını izlemek için kullanılan aylık brüt kâr ya da üç aylık çalışan giriş çıkışları gibi ölçülebilen bir birimdir. +CUBEMEMBER = KÜPÜYE ## Bir küp hiyerarşisinde bir üyeyi veya kaydı verir. Üye veya kaydın küpte varolduğunu doğrulamak için kullanılır. +CUBEMEMBERPROPERTY = KÜPÜYEÖZELLİĞİ ## Bir küpte bir üyenin özelliğinin değerini verir. Küp içinde üye adının varlığını doğrulamak ve bu üyenin belli özelliklerini getirmek için kullanılır. +CUBERANKEDMEMBER = KÜPÜYESIRASI ## Bir küme içindeki üyenin derecesini veya kaçıncı olduğunu verir. En iyi satış elemanı, veya en iyi on öğrenci gibi bir kümedeki bir veya daha fazla öğeyi getirmek için kullanılır. +CUBESET = KÜPKÜME ## Kümeyi oluşturan ve ardından bu kümeyi Microsoft Office Excel'e getiren sunucudaki küpe küme ifadelerini göndererek hesaplanan üye veya kayıt kümesini tanımlar. +CUBESETCOUNT = KÜPKÜMESAY ## Bir kümedeki öğelerin sayısını getirir. +CUBEVALUE = KÜPDEĞER ## Bir küpten toplam değeri getirir. + + +## +## Database functions Veritabanı işlevleri +## +DAVERAGE = VSEÇORT ## Seçili veritabanı girdilerinin ortalamasını verir. +DCOUNT = VSEÇSAY ## Veritabanında sayı içeren hücre sayısını hesaplar. +DCOUNTA = VSEÇSAYDOLU ## Veritabanındaki boş olmayan hücreleri sayar. +DGET = VAL ## Veritabanından, belirtilen ölçütlerle eşleşen tek bir rapor çıkarır. +DMAX = VSEÇMAK ## Seçili veritabanı girişlerinin en yüksek değerini verir. +DMIN = VSEÇMİN ## Seçili veritabanı girişlerinin en düşük değerini verir. +DPRODUCT = VSEÇÇARP ## Kayıtların belli bir alanında bulunan, bir veritabanındaki ölçütlerle eşleşen değerleri çarpar. +DSTDEV = VSEÇSTDSAPMA ## Seçili veritabanı girişlerinden oluşan bir örneğe dayanarak, standart sapmayı tahmin eder. +DSTDEVP = VSEÇSTDSAPMAS ## Standart sapmayı, seçili veritabanı girişlerinin tüm popülasyonunu esas alarak hesaplar. +DSUM = VSEÇTOPLA ## Kayıtların alan sütununda bulunan, ölçütle eşleşen sayıları toplar. +DVAR = VSEÇVAR ## Seçili veritabanı girişlerinden oluşan bir örneği esas alarak farkı tahmin eder. +DVARP = VSEÇVARS ## Seçili veritabanı girişlerinin tüm popülasyonunu esas alarak farkı hesaplar. + + +## +## Date and time functions Tarih ve saat işlevleri +## +DATE = TARİH ## Belirli bir tarihin seri numarasını verir. +DATEVALUE = TARİHSAYISI ## Metin biçimindeki bir tarihi seri numarasına dönüştürür. +DAY = GÜN ## Seri numarasını, ayın bir gününe dönüştürür. +DAYS360 = GÜN360 ## İki tarih arasındaki gün sayısını, 360 günlük yılı esas alarak hesaplar. +EDATE = SERİTARİH ## Başlangıç tarihinden itibaren, belirtilen ay sayısından önce veya sonraki tarihin seri numarasını verir. +EOMONTH = SERİAY ## Belirtilen sayıda ay önce veya sonraki ayın son gününün seri numarasını verir. +HOUR = SAAT ## Bir seri numarasını saate dönüştürür. +MINUTE = DAKİKA ## Bir seri numarasını dakikaya dönüştürür. +MONTH = AY ## Bir seri numarasını aya dönüştürür. +NETWORKDAYS = TAMİŞGÜNÜ ## İki tarih arasındaki tam çalışma günlerinin sayısını verir. +NOW = ŞİMDİ ## Geçerli tarihin ve saatin seri numarasını verir. +SECOND = SANİYE ## Bir seri numarasını saniyeye dönüştürür. +TIME = ZAMAN ## Belirli bir zamanın seri numarasını verir. +TIMEVALUE = ZAMANSAYISI ## Metin biçimindeki zamanı seri numarasına dönüştürür. +TODAY = BUGÜN ## Bugünün tarihini seri numarasına dönüştürür. +WEEKDAY = HAFTANINGÜNÜ ## Bir seri numarasını, haftanın gününe dönüştürür. +WEEKNUM = HAFTASAY ## Dizisel değerini, haftanın yıl içinde bulunduğu konumu sayısal olarak gösteren sayıya dönüştürür. +WORKDAY = İŞGÜNÜ ## Belirtilen sayıda çalışma günü öncesinin ya da sonrasının tarihinin seri numarasını verir. +YEAR = YIL ## Bir seri numarasını yıla dönüştürür. +YEARFRAC = YILORAN ## Başlangıç_tarihi ve bitiş_tarihi arasındaki tam günleri gösteren yıl kesrini verir. + + +## +## Engineering functions Mühendislik işlevleri +## +BESSELI = BESSELI ## Değiştirilmiş Bessel fonksiyonu In(x)'i verir. +BESSELJ = BESSELJ ## Bessel fonksiyonu Jn(x)'i verir. +BESSELK = BESSELK ## Değiştirilmiş Bessel fonksiyonu Kn(x)'i verir. +BESSELY = BESSELY ## Bessel fonksiyonu Yn(x)'i verir. +BIN2DEC = BIN2DEC ## İkili bir sayıyı, ondalık sayıya dönüştürür. +BIN2HEX = BIN2HEX ## İkili bir sayıyı, onaltılıya dönüştürür. +BIN2OCT = BIN2OCT ## İkili bir sayıyı, sekizliye dönüştürür. +COMPLEX = KARMAŞIK ## Gerçek ve sanal katsayıları, karmaşık sayıya dönüştürür. +CONVERT = ÇEVİR ## Bir sayıyı, bir ölçüm sisteminden bir başka ölçüm sistemine dönüştürür. +DEC2BIN = DEC2BIN ## Ondalık bir sayıyı, ikiliye dönüştürür. +DEC2HEX = DEC2HEX ## Ondalık bir sayıyı, onaltılıya dönüştürür. +DEC2OCT = DEC2OCT ## Ondalık bir sayıyı sekizliğe dönüştürür. +DELTA = DELTA ## İki değerin eşit olup olmadığını sınar. +ERF = HATAİŞLEV ## Hata işlevini verir. +ERFC = TÜMHATAİŞLEV ## Tümleyici hata işlevini verir. +GESTEP = BESINIR ## Bir sayının eşik değerinden büyük olup olmadığını sınar. +HEX2BIN = HEX2BIN ## Onaltılı bir sayıyı ikiliye dönüştürür. +HEX2DEC = HEX2DEC ## Onaltılı bir sayıyı ondalığa dönüştürür. +HEX2OCT = HEX2OCT ## Onaltılı bir sayıyı sekizliğe dönüştürür. +IMABS = SANMUTLAK ## Karmaşık bir sayının mutlak değerini (modül) verir. +IMAGINARY = SANAL ## Karmaşık bir sayının sanal katsayısını verir. +IMARGUMENT = SANBAĞ_DEĞİŞKEN ## Radyanlarla belirtilen bir açı olan teta bağımsız değişkenini verir. +IMCONJUGATE = SANEŞLENEK ## Karmaşık bir sayının karmaşık eşleniğini verir. +IMCOS = SANCOS ## Karmaşık bir sayının kosinüsünü verir. +IMDIV = SANBÖL ## İki karmaşık sayının bölümünü verir. +IMEXP = SANÜS ## Karmaşık bir sayının üssünü verir. +IMLN = SANLN ## Karmaşık bir sayının doğal logaritmasını verir. +IMLOG10 = SANLOG10 ## Karmaşık bir sayının, 10 tabanında logaritmasını verir. +IMLOG2 = SANLOG2 ## Karmaşık bir sayının 2 tabanında logaritmasını verir. +IMPOWER = SANÜSSÜ ## Karmaşık bir sayıyı, bir tamsayı üssüne yükseltilmiş olarak verir. +IMPRODUCT = SANÇARP ## Karmaşık sayıların çarpımını verir. +IMREAL = SANGERÇEK ## Karmaşık bir sayının, gerçek katsayısını verir. +IMSIN = SANSIN ## Karmaşık bir sayının sinüsünü verir. +IMSQRT = SANKAREKÖK ## Karmaşık bir sayının karekökünü verir. +IMSUB = SANÇIKAR ## İki karmaşık sayının farkını verir. +IMSUM = SANTOPLA ## Karmaşık sayıların toplamını verir. +OCT2BIN = OCT2BIN ## Sekizli bir sayıyı ikiliye dönüştürür. +OCT2DEC = OCT2DEC ## Sekizli bir sayıyı ondalığa dönüştürür. +OCT2HEX = OCT2HEX ## Sekizli bir sayıyı onaltılıya dönüştürür. + + +## +## Financial functions Finansal fonksiyonlar +## +ACCRINT = GERÇEKFAİZ ## Dönemsel faiz ödeyen hisse senedine ilişkin tahakkuk eden faizi getirir. +ACCRINTM = GERÇEKFAİZV ## Vadesinde ödeme yapan bir tahvilin tahakkuk etmiş faizini verir. +AMORDEGRC = AMORDEGRC ## Yıpranma katsayısı kullanarak her hesap döneminin değer kaybını verir. +AMORLINC = AMORLINC ## Her hesap dönemi içindeki yıpranmayı verir. +COUPDAYBS = KUPONGÜNBD ## Kupon süresinin başlangıcından alış tarihine kadar olan süredeki gün sayısını verir. +COUPDAYS = KUPONGÜN ## Kupon süresindeki, gün sayısını, alış tarihini de içermek üzere, verir. +COUPDAYSNC = KUPONGÜNDSK ## Alış tarihinden bir sonraki kupon tarihine kadar olan gün sayısını verir. +COUPNCD = KUPONGÜNSKT ## Alış tarihinden bir sonraki kupon tarihini verir. +COUPNUM = KUPONSAYI ## Alış tarihiyle vade tarihi arasında ödenecek kuponların sayısını verir. +COUPPCD = KUPONGÜNÖKT ## Alış tarihinden bir önceki kupon tarihini verir. +CUMIPMT = AİÇVERİMORANI ## İki dönem arasında ödenen kümülatif faizi verir. +CUMPRINC = ANA_PARA_ÖDEMESİ ## İki dönem arasında bir borç üzerine ödenen birikimli temeli verir. +DB = AZALANBAKİYE ## Bir malın belirtilen bir süre içindeki yıpranmasını, sabit azalan bakiye yöntemini kullanarak verir. +DDB = ÇİFTAZALANBAKİYE ## Bir malın belirtilen bir süre içindeki yıpranmasını, çift azalan bakiye yöntemi ya da sizin belirttiğiniz başka bir yöntemi kullanarak verir. +DISC = İNDİRİM ## Bir tahvilin indirim oranını verir. +DOLLARDE = LİRAON ## Kesir olarak tanımlanmış lira fiyatını, ondalık sayı olarak tanımlanmış lira fiyatına dönüştürür. +DOLLARFR = LİRAKES ## Ondalık sayı olarak tanımlanmış lira fiyatını, kesir olarak tanımlanmış lira fiyatına dönüştürür. +DURATION = SÜRE ## Belli aralıklarla faiz ödemesi yapan bir tahvilin yıllık süresini verir. +EFFECT = ETKİN ## Efektif yıllık faiz oranını verir. +FV = ANBD ## Bir yatırımın gelecekteki değerini verir. +FVSCHEDULE = GDPROGRAM ## Bir seri birleşik faiz oranı uyguladıktan sonra, bir başlangıçtaki anaparanın gelecekteki değerini verir. +INTRATE = FAİZORANI ## Tam olarak yatırım yapılmış bir tahvilin faiz oranını verir. +IPMT = FAİZTUTARI ## Bir yatırımın verilen bir süre için faiz ödemesini verir. +IRR = İÇ_VERİM_ORANI ## Bir para akışı serisi için, iç verim oranını verir. +ISPMT = ISPMT ## Yatırımın belirli bir dönemi boyunca ödenen faizi hesaplar. +MDURATION = MSÜRE ## Varsayılan par değeri 10.000.000 lira olan bir tahvil için Macauley değiştirilmiş süreyi verir. +MIRR = D_İÇ_VERİM_ORANI ## Pozitif ve negatif para akışlarının farklı oranlarda finanse edildiği durumlarda, iç verim oranını verir. +NOMINAL = NOMİNAL ## Yıllık nominal faiz oranını verir. +NPER = DÖNEM_SAYISI ## Bir yatırımın dönem sayısını verir. +NPV = NBD ## Bir yatırımın bugünkü net değerini, bir dönemsel para akışları serisine ve bir indirim oranına bağlı olarak verir. +ODDFPRICE = TEKYDEĞER ## Tek bir ilk dönemi olan bir tahvilin değerini, her 100.000.000 lirada bir verir. +ODDFYIELD = TEKYÖDEME ## Tek bir ilk dönemi olan bir tahvilin ödemesini verir. +ODDLPRICE = TEKSDEĞER ## Tek bir son dönemi olan bir tahvilin fiyatını her 10.000.000 lirada bir verir. +ODDLYIELD = TEKSÖDEME ## Tek bir son dönemi olan bir tahvilin ödemesini verir. +PMT = DEVRESEL_ÖDEME ## Bir yıllık dönemsel ödemeyi verir. +PPMT = ANA_PARA_ÖDEMESİ ## Verilen bir süre için, bir yatırımın anaparasına dayanan ödemeyi verir. +PRICE = DEĞER ## Dönemsel faiz ödeyen bir tahvilin fiyatını 10.000.00 liralık değer başına verir. +PRICEDISC = DEĞERİND ## İndirimli bir tahvilin fiyatını 10.000.000 liralık nominal değer başına verir. +PRICEMAT = DEĞERVADE ## Faizini vade sonunda ödeyen bir tahvilin fiyatını 10.000.000 nominal değer başına verir. +PV = BD ## Bir yatırımın bugünkü değerini verir. +RATE = FAİZ_ORANI ## Bir yıllık dönem başına düşen faiz oranını verir. +RECEIVED = GETİRİ ## Tam olarak yatırılmış bir tahvilin vadesinin bitiminde alınan miktarı verir. +SLN = DA ## Bir malın bir dönem içindeki doğrusal yıpranmasını verir. +SYD = YAT ## Bir malın belirli bir dönem için olan amortismanını verir. +TBILLEQ = HTAHEŞ ## Bir Hazine bonosunun bono eşdeğeri ödemesini verir. +TBILLPRICE = HTAHDEĞER ## Bir Hazine bonosunun değerini, 10.000.000 liralık nominal değer başına verir. +TBILLYIELD = HTAHÖDEME ## Bir Hazine bonosunun ödemesini verir. +VDB = DAB ## Bir malın amortismanını, belirlenmiş ya da kısmi bir dönem için, bir azalan bakiye yöntemi kullanarak verir. +XIRR = AİÇVERİMORANI ## Dönemsel olması gerekmeyen bir para akışları programı için, iç verim oranını verir. +XNPV = ANBD ## Dönemsel olması gerekmeyen bir para akışları programı için, bugünkü net değeri verir. +YIELD = ÖDEME ## Belirli aralıklarla faiz ödeyen bir tahvilin ödemesini verir. +YIELDDISC = ÖDEMEİND ## İndirimli bir tahvilin yıllık ödemesini verir; örneğin, bir Hazine bonosunun. +YIELDMAT = ÖDEMEVADE ## Vadesinin bitiminde faiz ödeyen bir tahvilin yıllık ödemesini verir. + + +## +## Information functions Bilgi fonksiyonları +## +CELL = HÜCRE ## Bir hücrenin biçimlendirmesi, konumu ya da içeriği hakkında bilgi verir. +ERROR.TYPE = HATA.TİPİ ## Bir hata türüne ilişkin sayıları verir. +INFO = BİLGİ ## Geçerli işletim ortamı hakkında bilgi verir. +ISBLANK = EBOŞSA ## Değer boşsa, DOĞRU verir. +ISERR = EHATA ## Değer, #YOK dışındaki bir hata değeriyse, DOĞRU verir. +ISERROR = EHATALIYSA ## Değer, herhangi bir hata değeriyse, DOĞRU verir. +ISEVEN = ÇİFTTİR ## Sayı çiftse, DOĞRU verir. +ISLOGICAL = EMANTIKSALSA ## Değer, mantıksal bir değerse, DOĞRU verir. +ISNA = EYOKSA ## Değer, #YOK hata değeriyse, DOĞRU verir. +ISNONTEXT = EMETİNDEĞİLSE ## Değer, metin değilse, DOĞRU verir. +ISNUMBER = ESAYIYSA ## Değer, bir sayıysa, DOĞRU verir. +ISODD = TEKTİR ## Sayı tekse, DOĞRU verir. +ISREF = EREFSE ## Değer bir başvuruysa, DOĞRU verir. +ISTEXT = EMETİNSE ## Değer bir metinse DOĞRU verir. +N = N ## Sayıya dönüştürülmüş bir değer verir. +NA = YOKSAY ## #YOK hata değerini verir. +TYPE = TİP ## Bir değerin veri türünü belirten bir sayı verir. + + +## +## Logical functions Mantıksal fonksiyonlar +## +AND = VE ## Bütün bağımsız değişkenleri DOĞRU ise, DOĞRU verir. +FALSE = YANLIŞ ## YANLIŞ mantıksal değerini verir. +IF = EĞER ## Gerçekleştirilecek bir mantıksal sınama belirtir. +IFERROR = EĞERHATA ## Formül hatalıysa belirttiğiniz değeri verir; bunun dışındaki durumlarda formülün sonucunu verir. +NOT = DEĞİL ## Bağımsız değişkeninin mantığını tersine çevirir. +OR = YADA ## Bağımsız değişkenlerden herhangi birisi DOĞRU ise, DOĞRU verir. +TRUE = DOĞRU ## DOĞRU mantıksal değerini verir. + + +## +## Lookup and reference functions Arama ve Başvuru fonksiyonları +## +ADDRESS = ADRES ## Bir başvuruyu, çalışma sayfasındaki tek bir hücreye metin olarak verir. +AREAS = ALANSAY ## Renvoie le nombre de zones dans une référence. +CHOOSE = ELEMAN ## Değerler listesinden bir değer seçer. +COLUMN = SÜTUN ## Bir başvurunun sütun sayısını verir. +COLUMNS = SÜTUNSAY ## Bir başvurudaki sütunların sayısını verir. +HLOOKUP = YATAYARA ## Bir dizinin en üst satırına bakar ve belirtilen hücrenin değerini verir. +HYPERLINK = KÖPRÜ ## Bir ağ sunucusunda, bir intranette ya da Internet'te depolanan bir belgeyi açan bir kısayol ya da atlama oluşturur. +INDEX = İNDİS ## Başvurudan veya diziden bir değer seçmek için, bir dizin kullanır. +INDIRECT = DOLAYLI ## Metin değeriyle belirtilen bir başvuru verir. +LOOKUP = ARA ## Bir vektördeki veya dizideki değerleri arar. +MATCH = KAÇINCI ## Bir başvurudaki veya dizideki değerleri arar. +OFFSET = KAYDIR ## Verilen bir başvurudan, bir başvuru kaydırmayı verir. +ROW = SATIR ## Bir başvurunun satır sayısını verir. +ROWS = SATIRSAY ## Bir başvurudaki satırların sayısını verir. +RTD = RTD ## COM otomasyonunu destekleyen programdan gerçek zaman verileri alır. +TRANSPOSE = DEVRİK_DÖNÜŞÜM ## Bir dizinin devrik dönüşümünü verir. +VLOOKUP = DÜŞEYARA ## Bir dizinin ilk sütununa bakar ve bir hücrenin değerini vermek için satır boyunca hareket eder. + + +## +## Math and trigonometry functions Matematik ve trigonometri fonksiyonları +## +ABS = MUTLAK ## Bir sayının mutlak değerini verir. +ACOS = ACOS ## Bir sayının ark kosinüsünü verir. +ACOSH = ACOSH ## Bir sayının ters hiperbolik kosinüsünü verir. +ASIN = ASİN ## Bir sayının ark sinüsünü verir. +ASINH = ASİNH ## Bir sayının ters hiperbolik sinüsünü verir. +ATAN = ATAN ## Bir sayının ark tanjantını verir. +ATAN2 = ATAN2 ## Ark tanjantı, x- ve y- koordinatlarından verir. +ATANH = ATANH ## Bir sayının ters hiperbolik tanjantını verir. +CEILING = TAVANAYUVARLA ## Bir sayıyı, en yakın tamsayıya ya da en yakın katına yuvarlar. +COMBIN = KOMBİNASYON ## Verilen sayıda öğenin kombinasyon sayısını verir. +COS = COS ## Bir sayının kosinüsünü verir. +COSH = COSH ## Bir sayının hiperbolik kosinüsünü verir. +DEGREES = DERECE ## Radyanları dereceye dönüştürür. +EVEN = ÇİFT ## Bir sayıyı, en yakın daha büyük çift tamsayıya yuvarlar. +EXP = ÜS ## e'yi, verilen bir sayının üssüne yükseltilmiş olarak verir. +FACT = ÇARPINIM ## Bir sayının faktörünü verir. +FACTDOUBLE = ÇİFTFAKTÖR ## Bir sayının çift çarpınımını verir. +FLOOR = TABANAYUVARLA ## Bir sayıyı, daha küçük sayıya, sıfıra yakınsayarak yuvarlar. +GCD = OBEB ## En büyük ortak böleni verir. +INT = TAMSAYI ## Bir sayıyı aşağıya doğru en yakın tamsayıya yuvarlar. +LCM = OKEK ## En küçük ortak katı verir. +LN = LN ## Bir sayının doğal logaritmasını verir. +LOG = LOG ## Bir sayının, belirtilen bir tabandaki logaritmasını verir. +LOG10 = LOG10 ## Bir sayının 10 tabanında logaritmasını verir. +MDETERM = DETERMİNANT ## Bir dizinin dizey determinantını verir. +MINVERSE = DİZEY_TERS ## Bir dizinin dizey tersini verir. +MMULT = DÇARP ## İki dizinin dizey çarpımını verir. +MOD = MODÜLO ## Bölmeden kalanı verir. +MROUND = KYUVARLA ## İstenen kata yuvarlanmış bir sayı verir. +MULTINOMIAL = ÇOKTERİMLİ ## Bir sayılar kümesinin çok terimlisini verir. +ODD = TEK ## Bir sayıyı en yakın daha büyük tek sayıya yuvarlar. +PI = Pİ ## Pi değerini verir. +POWER = KUVVET ## Bir üsse yükseltilmiş sayının sonucunu verir. +PRODUCT = ÇARPIM ## Bağımsız değişkenlerini çarpar. +QUOTIENT = BÖLÜM ## Bir bölme işleminin tamsayı kısmını verir. +RADIANS = RADYAN ## Dereceleri radyanlara dönüştürür. +RAND = S_SAYI_ÜRET ## 0 ile 1 arasında rastgele bir sayı verir. +RANDBETWEEN = RASTGELEARALIK ## Belirttiğiniz sayılar arasında rastgele bir sayı verir. +ROMAN = ROMEN ## Bir normal rakamı, metin olarak, romen rakamına çevirir. +ROUND = YUVARLA ## Bir sayıyı, belirtilen basamak sayısına yuvarlar. +ROUNDDOWN = AŞAĞIYUVARLA ## Bir sayıyı, daha küçük sayıya, sıfıra yakınsayarak yuvarlar. +ROUNDUP = YUKARIYUVARLA ## Bir sayıyı daha büyük sayıya, sıfırdan ıraksayarak yuvarlar. +SERIESSUM = SERİTOPLA ## Bir üs serisinin toplamını, formüle bağlı olarak verir. +SIGN = İŞARET ## Bir sayının işaretini verir. +SIN = SİN ## Verilen bir açının sinüsünü verir. +SINH = SİNH ## Bir sayının hiperbolik sinüsünü verir. +SQRT = KAREKÖK ## Pozitif bir karekök verir. +SQRTPI = KAREKÖKPİ ## (* Pi sayısının) kare kökünü verir. +SUBTOTAL = ALTTOPLAM ## Bir listedeki ya da veritabanındaki bir alt toplamı verir. +SUM = TOPLA ## Bağımsız değişkenlerini toplar. +SUMIF = ETOPLA ## Verilen ölçütle belirlenen hücreleri toplar. +SUMIFS = SUMIFS ## Bir aralıktaki, birden fazla ölçüte uyan hücreleri ekler. +SUMPRODUCT = TOPLA.ÇARPIM ## İlişkili dizi bileşenlerinin çarpımlarının toplamını verir. +SUMSQ = TOPKARE ## Bağımsız değişkenlerin karelerinin toplamını verir. +SUMX2MY2 = TOPX2EY2 ## İki dizideki ilişkili değerlerin farkının toplamını verir. +SUMX2PY2 = TOPX2AY2 ## İki dizideki ilişkili değerlerin karelerinin toplamının toplamını verir. +SUMXMY2 = TOPXEY2 ## İki dizideki ilişkili değerlerin farklarının karelerinin toplamını verir. +TAN = TAN ## Bir sayının tanjantını verir. +TANH = TANH ## Bir sayının hiperbolik tanjantını verir. +TRUNC = NSAT ## Bir sayının, tamsayı durumuna gelecek şekilde, fazlalıklarını atar. + + +## +## Statistical functions İstatistiksel fonksiyonlar +## +AVEDEV = ORTSAP ## Veri noktalarının ortalamalarından mutlak sapmalarının ortalamasını verir. +AVERAGE = ORTALAMA ## Bağımsız değişkenlerinin ortalamasını verir. +AVERAGEA = ORTALAMAA ## Bağımsız değişkenlerinin, sayılar, metin ve mantıksal değerleri içermek üzere ortalamasını verir. +AVERAGEIF = EĞERORTALAMA ## Verili ölçütü karşılayan bir aralıktaki bütün hücrelerin ortalamasını (aritmetik ortalama) hesaplar. +AVERAGEIFS = EĞERLERORTALAMA ## Birden çok ölçüte uyan tüm hücrelerin ortalamasını (aritmetik ortalama) hesaplar. +BETADIST = BETADAĞ ## Beta birikimli dağılım fonksiyonunu verir. +BETAINV = BETATERS ## Belirli bir beta dağılımı için birikimli dağılım fonksiyonunun tersini verir. +BINOMDIST = BİNOMDAĞ ## Tek terimli binom dağılımı olasılığını verir. +CHIDIST = KİKAREDAĞ ## Kikare dağılımın tek kuyruklu olasılığını verir. +CHIINV = KİKARETERS ## Kikare dağılımın kuyruklu olasılığının tersini verir. +CHITEST = KİKARETEST ## Bağımsızlık sınamalarını verir. +CONFIDENCE = GÜVENİRLİK ## Bir popülasyon ortalaması için güvenirlik aralığını verir. +CORREL = KORELASYON ## İki veri kümesi arasındaki bağlantı katsayısını verir. +COUNT = BAĞ_DEĞ_SAY ## Bağımsız değişkenler listesinde kaç tane sayı bulunduğunu sayar. +COUNTA = BAĞ_DEĞ_DOLU_SAY ## Bağımsız değişkenler listesinde kaç tane değer bulunduğunu sayar. +COUNTBLANK = BOŞLUKSAY ## Aralıktaki boş hücre sayısını hesaplar. +COUNTIF = EĞERSAY ## Verilen ölçütlere uyan bir aralık içindeki hücreleri sayar. +COUNTIFS = ÇOKEĞERSAY ## Birden çok ölçüte uyan bir aralık içindeki hücreleri sayar. +COVAR = KOVARYANS ## Eşleştirilmiş sapmaların ortalaması olan kovaryansı verir. +CRITBINOM = KRİTİKBİNOM ## Birikimli binom dağılımının bir ölçüt değerinden küçük veya ölçüt değerine eşit olduğu en küçük değeri verir. +DEVSQ = SAPKARE ## Sapmaların karelerinin toplamını verir. +EXPONDIST = ÜSTELDAĞ ## Üstel dağılımı verir. +FDIST = FDAĞ ## F olasılık dağılımını verir. +FINV = FTERS ## F olasılık dağılımının tersini verir. +FISHER = FISHER ## Fisher dönüşümünü verir. +FISHERINV = FISHERTERS ## Fisher dönüşümünün tersini verir. +FORECAST = TAHMİN ## Bir doğrusal eğilim boyunca bir değer verir. +FREQUENCY = SIKLIK ## Bir sıklık dağılımını, dikey bir dizi olarak verir. +FTEST = FTEST ## Bir F-test'in sonucunu verir. +GAMMADIST = GAMADAĞ ## Gama dağılımını verir. +GAMMAINV = GAMATERS ## Gama kümülatif dağılımının tersini verir. +GAMMALN = GAMALN ## Gama fonksiyonunun (?(x)) doğal logaritmasını verir. +GEOMEAN = GEOORT ## Geometrik ortayı verir. +GROWTH = BÜYÜME ## Üstel bir eğilim boyunca değerler verir. +HARMEAN = HARORT ## Harmonik ortayı verir. +HYPGEOMDIST = HİPERGEOMDAĞ ## Hipergeometrik dağılımı verir. +INTERCEPT = KESMENOKTASI ## Doğrusal çakıştırma çizgisinin kesişme noktasını verir. +KURT = BASIKLIK ## Bir veri kümesinin basıklığını verir. +LARGE = BÜYÜK ## Bir veri kümesinde k. en büyük değeri verir. +LINEST = DOT ## Doğrusal bir eğilimin parametrelerini verir. +LOGEST = LOT ## Üstel bir eğilimin parametrelerini verir. +LOGINV = LOGTERS ## Bir lognormal dağılımının tersini verir. +LOGNORMDIST = LOGNORMDAĞ ## Birikimli lognormal dağılımını verir. +MAX = MAK ## Bir bağımsız değişkenler listesindeki en büyük değeri verir. +MAXA = MAKA ## Bir bağımsız değişkenler listesindeki, sayılar, metin ve mantıksal değerleri içermek üzere, en büyük değeri verir. +MEDIAN = ORTANCA ## Belirtilen sayıların orta değerini verir. +MIN = MİN ## Bir bağımsız değişkenler listesindeki en küçük değeri verir. +MINA = MİNA ## Bir bağımsız değişkenler listesindeki, sayılar, metin ve mantıksal değerleri de içermek üzere, en küçük değeri verir. +MODE = ENÇOK_OLAN ## Bir veri kümesindeki en sık rastlanan değeri verir. +NEGBINOMDIST = NEGBİNOMDAĞ ## Negatif binom dağılımını verir. +NORMDIST = NORMDAĞ ## Normal birikimli dağılımı verir. +NORMINV = NORMTERS ## Normal kümülatif dağılımın tersini verir. +NORMSDIST = NORMSDAĞ ## Standart normal birikimli dağılımı verir. +NORMSINV = NORMSTERS ## Standart normal birikimli dağılımın tersini verir. +PEARSON = PEARSON ## Pearson çarpım moment korelasyon katsayısını verir. +PERCENTILE = YÜZDEBİRLİK ## Bir aralık içerisinde bulunan değerlerin k. frekans toplamını verir. +PERCENTRANK = YÜZDERANK ## Bir veri kümesindeki bir değerin yüzde mertebesini verir. +PERMUT = PERMÜTASYON ## Verilen sayıda nesne için permütasyon sayısını verir. +POISSON = POISSON ## Poisson dağılımını verir. +PROB = OLASILIK ## Bir aralıktaki değerlerin iki sınır arasında olması olasılığını verir. +QUARTILE = DÖRTTEBİRLİK ## Bir veri kümesinin dörtte birliğini verir. +RANK = RANK ## Bir sayılar listesinde bir sayının mertebesini verir. +RSQ = RKARE ## Pearson çarpım moment korelasyon katsayısının karesini verir. +SKEW = ÇARPIKLIK ## Bir dağılımın çarpıklığını verir. +SLOPE = EĞİM ## Doğrusal çakışma çizgisinin eğimini verir. +SMALL = KÜÇÜK ## Bir veri kümesinde k. en küçük değeri verir. +STANDARDIZE = STANDARTLAŞTIRMA ## Normalleştirilmiş bir değer verir. +STDEV = STDSAPMA ## Bir örneğe dayanarak standart sapmayı tahmin eder. +STDEVA = STDSAPMAA ## Standart sapmayı, sayılar, metin ve mantıksal değerleri içermek üzere, bir örneğe bağlı olarak tahmin eder. +STDEVP = STDSAPMAS ## Standart sapmayı, tüm popülasyona bağlı olarak hesaplar. +STDEVPA = STDSAPMASA ## Standart sapmayı, sayılar, metin ve mantıksal değerleri içermek üzere, tüm popülasyona bağlı olarak hesaplar. +STEYX = STHYX ## Regresyondaki her x için tahmini y değerinin standart hatasını verir. +TDIST = TDAĞ ## T-dağılımını verir. +TINV = TTERS ## T-dağılımının tersini verir. +TREND = EĞİLİM ## Doğrusal bir eğilim boyunca değerler verir. +TRIMMEAN = KIRPORTALAMA ## Bir veri kümesinin içinin ortalamasını verir. +TTEST = TTEST ## T-test'le ilişkilendirilmiş olasılığı verir. +VAR = VAR ## Varyansı, bir örneğe bağlı olarak tahmin eder. +VARA = VARA ## Varyansı, sayılar, metin ve mantıksal değerleri içermek üzere, bir örneğe bağlı olarak tahmin eder. +VARP = VARS ## Varyansı, tüm popülasyona dayanarak hesaplar. +VARPA = VARSA ## Varyansı, sayılar, metin ve mantıksal değerleri içermek üzere, tüm popülasyona bağlı olarak hesaplar. +WEIBULL = WEIBULL ## Weibull dağılımını hesaplar. +ZTEST = ZTEST ## Z-testinin tek kuyruklu olasılık değerini hesaplar. + + +## +## Text functions Metin fonksiyonları +## +ASC = ASC ## Bir karakter dizesindeki çift enli (iki bayt) İngilizce harfleri veya katakanayı yarım enli (tek bayt) karakterlerle değiştirir. +BAHTTEXT = BAHTTEXT ## Sayıyı, ß (baht) para birimi biçimini kullanarak metne dönüştürür. +CHAR = DAMGA ## Kod sayısıyla belirtilen karakteri verir. +CLEAN = TEMİZ ## Metindeki bütün yazdırılamaz karakterleri kaldırır. +CODE = KOD ## Bir metin dizesindeki ilk karakter için sayısal bir kod verir. +CONCATENATE = BİRLEŞTİR ## Pek çok metin öğesini bir metin öğesi olarak birleştirir. +DOLLAR = LİRA ## Bir sayıyı YTL (yeni Türk lirası) para birimi biçimini kullanarak metne dönüştürür. +EXACT = ÖZDEŞ ## İki metin değerinin özdeş olup olmadığını anlamak için, değerleri denetler. +FIND = BUL ## Bir metin değerini, bir başkasının içinde bulur (büyük küçük harf duyarlıdır). +FINDB = BULB ## Bir metin değerini, bir başkasının içinde bulur (büyük küçük harf duyarlıdır). +FIXED = SAYIDÜZENLE ## Bir sayıyı, sabit sayıda ondalıkla, metin olarak biçimlendirir. +JIS = JIS ## Bir karakter dizesindeki tek enli (tek bayt) İngilizce harfleri veya katakanayı çift enli (iki bayt) karakterlerle değiştirir. +LEFT = SOL ## Bir metin değerinden en soldaki karakterleri verir. +LEFTB = SOLB ## Bir metin değerinden en soldaki karakterleri verir. +LEN = UZUNLUK ## Bir metin dizesindeki karakter sayısını verir. +LENB = UZUNLUKB ## Bir metin dizesindeki karakter sayısını verir. +LOWER = KÜÇÜKHARF ## Metni küçük harfe çevirir. +MID = ORTA ## Bir metin dizesinden belirli sayıda karakteri, belirttiğiniz konumdan başlamak üzere verir. +MIDB = ORTAB ## Bir metin dizesinden belirli sayıda karakteri, belirttiğiniz konumdan başlamak üzere verir. +PHONETIC = SES ## Metin dizesinden ses (furigana) karakterlerini ayıklar. +PROPER = YAZIM.DÜZENİ ## Bir metin değerinin her bir sözcüğünün ilk harfini büyük harfe çevirir. +REPLACE = DEĞİŞTİR ## Metnin içindeki karakterleri değiştirir. +REPLACEB = DEĞİŞTİRB ## Metnin içindeki karakterleri değiştirir. +REPT = YİNELE ## Metni belirtilen sayıda yineler. +RIGHT = SAĞ ## Bir metin değerinden en sağdaki karakterleri verir. +RIGHTB = SAĞB ## Bir metin değerinden en sağdaki karakterleri verir. +SEARCH = BUL ## Bir metin değerini, bir başkasının içinde bulur (büyük küçük harf duyarlı değildir). +SEARCHB = BULB ## Bir metin değerini, bir başkasının içinde bulur (büyük küçük harf duyarlı değildir). +SUBSTITUTE = YERİNEKOY ## Bir metin dizesinde, eski metnin yerine yeni metin koyar. +T = M ## Bağımsız değerlerini metne dönüştürür. +TEXT = METNEÇEVİR ## Bir sayıyı biçimlendirir ve metne dönüştürür. +TRIM = KIRP ## Metindeki boşlukları kaldırır. +UPPER = BÜYÜKHARF ## Metni büyük harfe çevirir. +VALUE = SAYIYAÇEVİR ## Bir metin bağımsız değişkenini sayıya dönüştürür. diff --git a/lib/player/APlayer.min.css b/lib/player/APlayer.min.css new file mode 100644 index 0000000..8b7b1d8 --- /dev/null +++ b/lib/player/APlayer.min.css @@ -0,0 +1 @@ +@font-face{font-family:aplayer-fontello;src:url(dist/font/aplayer-fontello.eot?72550380);src:url(dist/font/aplayer-fontello.eot?72550380#iefix) format("embedded-opentype"),url(dist/font/aplayer-fontello.woff?72550380) format("woff"),url(dist/font/aplayer-fontello.ttf?72550380) format("truetype"),url(dist/font/aplayer-fontello.svg?72550380#fontello) format("svg");font-weight:400;font-style:normal}.aplayer-narrow{width:66px}.aplayer-narrow .aplayer-info{display:none}.aplayer-withlrc.aplayer-narrow{width:106px}.aplayer-withlrc.aplayer .aplayer-pic{height:106px;width:106px}.aplayer-withlrc.aplayer .aplayer-info{margin-left:106px;height:106px}.aplayer-withlrc.aplayer .aplayer-lrc{display:block}.aplayer{font-family:Arial,Helvetica,sans-serif;margin:5px;box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12);border-radius:2px;overflow:hidden;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;line-height:initial}.aplayer [class*=" aplayer-icon-"]:before,.aplayer [class^=aplayer-icon-]:before{font-family:aplayer-fontello;font-style:normal;font-weight:400;display:inline-block;text-decoration:inherit;width:1em;text-align:center;font-variant:normal;text-transform:none;line-height:1em}.aplayer .aplayer-icon-play:before{content:'\e806'}.aplayer .aplayer-icon-pause:before{content:'\e807'}.aplayer .aplayer-icon-to-start:before{content:'\e808'}.aplayer .aplayer-icon-to-end:before{content:'\e809'}.aplayer .aplayer-icon-loop:before{content:'\e803'}.aplayer .aplayer-icon-menu:before{content:'\e80b'}.aplayer .aplayer-icon-volume-off:before{content:'\e800'}.aplayer .aplayer-icon-volume-down:before{content:'\e801'}.aplayer .aplayer-icon-volume-up:before{content:'\e802'}.aplayer .aplayer-lrc-content{display:none}.aplayer .aplayer-pic{position:relative;float:left;height:66px;width:66px;background-image:url(default.jpg);background-size:100%;-webkit-transition:all .3s ease;transition:all .3s ease}.aplayer .aplayer-pic .aplayer-button{position:absolute;color:#fff;border-radius:50%;opacity:.8;cursor:pointer;text-shadow:0 1px 1px rgba(0,0,0,.2);box-shadow:0 1px 1px rgba(0,0,0,.2);background:rgba(0,0,0,.2);-webkit-transition:all .1s ease;transition:all .1s ease}.aplayer .aplayer-pic .aplayer-button:hover{opacity:1}.aplayer .aplayer-pic .aplayer-hide{display:none}.aplayer .aplayer-pic .aplayer-play{width:26px;height:26px;border:2px solid #fff;bottom:50%;right:50%;margin:0 -15px -15px 0}.aplayer .aplayer-pic .aplayer-play .aplayer-icon-play{position:absolute;top:2px;left:4px;font-size:20px;line-height:23px}.aplayer .aplayer-pic .aplayer-pause{width:16px;height:16px;border:2px solid #fff;bottom:4px;right:4px}.aplayer .aplayer-pic .aplayer-pause .aplayer-icon-pause{position:absolute;top:1px;left:2px;font-size:12px;line-height:14px}.aplayer .aplayer-info{margin-left:66px;padding:14px 7px 0 10px;height:66px;box-sizing:border-box}.aplayer .aplayer-info .aplayer-music{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;margin-bottom:17px}.aplayer .aplayer-info .aplayer-music .aplayer-title{font-size:14px}.aplayer .aplayer-info .aplayer-music .aplayer-author{font-size:12px;color:#666}.aplayer .aplayer-info .aplayer-controller{position:relative}.aplayer .aplayer-info .aplayer-controller .aplayer-bar-wrap{margin:0 140px 0 5px}.aplayer .aplayer-info .aplayer-controller .aplayer-bar-wrap .aplayer-bar{position:relative;height:2px;width:100%;background:#cdcdcd;cursor:pointer!important}.aplayer .aplayer-info .aplayer-controller .aplayer-bar-wrap .aplayer-bar .aplayer-loaded{position:absolute;left:0;top:0;bottom:0;background:#aaa;height:2px;-webkit-transition:all .5s ease;transition:all .5s ease}.aplayer .aplayer-info .aplayer-controller .aplayer-bar-wrap .aplayer-bar .aplayer-played{position:absolute;left:0;top:0;bottom:0;height:2px}.aplayer .aplayer-info .aplayer-controller .aplayer-bar-wrap .aplayer-bar .aplayer-played .aplayer-thumb{position:absolute;top:0;right:5px;margin-top:-4px;margin-right:-10px;height:8px;width:8px;border-radius:50%;background:#fff;cursor:pointer!important}.aplayer .aplayer-info .aplayer-controller .aplayer-time{position:absolute;right:0;bottom:-5px;height:17px;color:#999;font-size:11px}.aplayer .aplayer-info .aplayer-controller .aplayer-time i{color:#666;font-size:15px;cursor:pointer;-webkit-transition:all .2s ease;transition:all .2s ease}.aplayer .aplayer-info .aplayer-controller .aplayer-time i.aplayer-icon-loop{margin:2px}.aplayer .aplayer-info .aplayer-controller .aplayer-time i.aplayer-noloop{color:#ddd}.aplayer .aplayer-info .aplayer-controller .aplayer-time i.aplayer-noloop:hover{color:#bbb}.aplayer .aplayer-info .aplayer-controller .aplayer-time i:hover{color:#000}.aplayer .aplayer-info .aplayer-controller .aplayer-volume-wrap{position:relative;display:inline-block;margin-left:7px;cursor:pointer!important}.aplayer .aplayer-info .aplayer-controller .aplayer-volume-wrap:hover .aplayer-volume-bar-wrap{display:block}.aplayer .aplayer-info .aplayer-controller .aplayer-volume-wrap .aplayer-volume-bar-wrap{display:none;position:absolute;bottom:17px;right:-5px;width:25px;height:40px;z-index:2}.aplayer .aplayer-info .aplayer-controller .aplayer-volume-wrap .aplayer-volume-bar-wrap .aplayer-volume-bar{position:absolute;bottom:0;right:10px;width:5px;height:35px;background:#aaa}.aplayer .aplayer-info .aplayer-controller .aplayer-volume-wrap .aplayer-volume-bar-wrap .aplayer-volume-bar .aplayer-volume{position:absolute;bottom:0;right:0;width:5px;-webkit-transition:all .1s ease;transition:all .1s ease}.aplayer .aplayer-lrc{display:none;position:relative;height:40px;background:#fff;text-align:center;overflow:hidden;margin:-10px 0 10px}.aplayer .aplayer-lrc:before{top:0;height:10%;background:-webkit-linear-gradient(top,#fff,hsla(0,0%,100%,0));background:-webkit-gradient(linear,left top,left bottom,from(#fff),to(hsla(0,0%,100%,0)));background:linear-gradient(180deg,#fff 0,hsla(0,0%,100%,0));filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff',endColorstr='#00ffffff',GradientType=0)}.aplayer .aplayer-lrc:after,.aplayer .aplayer-lrc:before{position:absolute;z-index:1;display:block;overflow:hidden;width:100%;content:' '}.aplayer .aplayer-lrc:after{bottom:0;height:33%;background:-webkit-linear-gradient(bottom,#fff,hsla(0,0%,100%,0));background:-webkit-gradient(linear,left bottom,left top,from(#fff),to(hsla(0,0%,100%,0)));background:linear-gradient(0deg,#fff 0,hsla(0,0%,100%,0));filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00ffffff',endColorstr='#ffffff',GradientType=0)}.aplayer .aplayer-lrc p{font-size:12px;color:#666;line-height:20px!important;height:20px!important;padding:0!important;margin:0!important;-webkit-transition:all .5s ease-out;transition:all .5s ease-out;opacity:.4;overflow:hidden}.aplayer .aplayer-lrc p.aplayer-lrc-current{opacity:1}.aplayer .aplayer-lrc .aplayer-lrc-contents{width:100%;-webkit-transition:all .5s ease-out;transition:all .5s ease-out}.aplayer .aplayer-list{max-height:650px;overflow:auto;-webkit-transition:all .5s ease;transition:all .5s ease}.aplayer .aplayer-list.aplayer-list-hide{max-height:0}.aplayer .aplayer-list ol{list-style-type:none;margin:0;padding:0}.aplayer .aplayer-list ol li{position:relative;height:32px;line-height:32px;padding:0 15px;font-size:12px;border-top:1px solid #e9e9e9;cursor:pointer;-webkit-transition:all .2s ease;transition:all .2s ease}.aplayer .aplayer-list ol li:hover{background:#efefef}.aplayer .aplayer-list ol li.aplayer-list-light{background:#e9e9e9}.aplayer .aplayer-list ol li.aplayer-list-light .aplayer-list-cur{display:inline-block}.aplayer .aplayer-list ol li .aplayer-list-cur{display:none;width:3px;height:22px;position:absolute;left:0;top:5px;cursor:pointer}.aplayer .aplayer-list ol li .aplayer-list-index{color:#666;margin-right:12px;cursor:pointer}.aplayer .aplayer-list ol li .aplayer-list-author{color:#666;float:right;cursor:pointer} \ No newline at end of file diff --git a/lib/player/APlayer.min.js b/lib/player/APlayer.min.js new file mode 100644 index 0000000..bdceb2b --- /dev/null +++ b/lib/player/APlayer.min.js @@ -0,0 +1 @@ +!function(){function e(e){this.isMobile=navigator.userAgent.match(/(iPad)|(iPhone)|(iPod)|(android)|(webOS)/i),this.isMobile&&(e.autoplay=!1);var t={element:document.getElementsByClassName("aplayer")[0],narrow:!1,autoplay:!1,showlrc:!1,theme:"#b7daff"};for(var a in t)t.hasOwnProperty(a)&&!e.hasOwnProperty(a)&&(e[a]=t[a]);this.playIndex="[object Array]"===Object.prototype.toString.call(e.music)?0:-1,this.option=e,this.audios=[],this.loop=!0}e.prototype.init=function(){function e(e){var t=e||window.event,s=(t.clientX-a(o.bar))/r;s=s>0?s:0,s=1>s?s:1,o.updateBar.call(o,"played",s,"width"),o.option.showlrc&&o.updateLrc.call(o,parseFloat(o.playedBar.style.width)/100*o.audio.duration),o.element.getElementsByClassName("aplayer-ptime")[0].innerHTML=o.secondToTime(s*o.audio.duration)}function t(){document.removeEventListener("mouseup",t),document.removeEventListener("mousemove",e),o.audio.currentTime=parseFloat(o.playedBar.style.width)/100*o.audio.duration,o.play()}function a(e){for(var t,a=e.offsetLeft,s=e.offsetParent;null!==s;)a+=s.offsetLeft,s=s.offsetParent;return t=document.body.scrollLeft+document.documentElement.scrollLeft,a-t}function s(e){for(var t,a=e.offsetTop,s=e.offsetParent;null!==s;)a+=s.offsetTop,s=s.offsetParent;return t=document.body.scrollTop+document.documentElement.scrollTop,a-t}this.element=this.option.element,this.music=this.playIndex>-1?this.option.music[this.playIndex]:this.option.music;var i;if(this.option.showlrc){var l=[];for(i=0;i<this.element.getElementsByClassName("aplayer-lrc-content").length;i++)l.push(this.element.getElementsByClassName("aplayer-lrc-content")[i].innerHTML);this.lrcs=this.parseLrc(l)}var n='<div class="aplayer-pic"><div class="aplayer-button aplayer-play"><i class="demo-icon aplayer-icon-play"></i></div></div><div class="aplayer-info"><div class="aplayer-music"><span class="aplayer-title"></span><span class="aplayer-author"></span></div><div class="aplayer-lrc"><div class="aplayer-lrc-contents" style="transform: translateY(0); -webkit-transform: translateY(0);"></div></div><div class="aplayer-controller"><div class="aplayer-bar-wrap"><div class="aplayer-bar"><div class="aplayer-loaded" style="width: 0"></div><div class="aplayer-played" style="width: 0; background: '+this.option.theme+';"><span class="aplayer-thumb" style="border: 1px solid '+this.option.theme+';"></span></div></div></div><div class="aplayer-time"> - <span class="aplayer-ptime">00:00</span> / <span class="aplayer-dtime">00:00</span><div class="aplayer-volume-wrap"><i class="demo-icon aplayer-icon-volume-down"></i><div class="aplayer-volume-bar-wrap"><div class="aplayer-volume-bar"><div class="aplayer-volume" style="height: 80%; background: '+this.option.theme+';"></div></div></div></div><i class="demo-icon aplayer-icon-loop"></i>'+(this.playIndex>-1?'<i class="demo-icon aplayer-icon-menu"></i>':"")+"</div></div></div>";if(this.playIndex>-1){for(n+='<div class="aplayer-list"><ol>',i=0;i<this.option.music.length;i++)n+='<li><span class="aplayer-list-cur" style="background: '+this.option.theme+';"></span><span class="aplayer-list-index">'+(i+1)+'</span><span class="aplayer-list-title">'+this.option.music[i].title+'</span><span class="aplayer-list-author">'+this.option.music[i].author+"</span></li>";n+="</ol></div>"}this.element.innerHTML=n,this.option.narrow&&this.element.classList.add("aplayer-narrow");var o=this;if(this.button=this.element.getElementsByClassName("aplayer-button")[0],this.button.addEventListener("click",function(){this.classList.contains("aplayer-play")?o.play.call(o):this.classList.contains("aplayer-pause")&&o.pause.call(o)}),this.playIndex>-1)for(i=0;i<this.option.music.length;i++)this.element.getElementsByClassName("aplayer-list")[0].getElementsByTagName("li")[i].addEventListener("click",function(){var e=parseInt(this.getElementsByClassName("aplayer-list-index")[0].innerHTML)-1;e!==o.playIndex&&o.setMusic(e),o.play()});this.playedBar=this.element.getElementsByClassName("aplayer-played")[0],this.loadedBar=this.element.getElementsByClassName("aplayer-loaded")[0],this.thumb=this.element.getElementsByClassName("aplayer-thumb")[0],this.bar=this.element.getElementsByClassName("aplayer-bar")[0];var r;this.bar.addEventListener("click",function(e){var t=e||window.event;r=o.bar.clientWidth;var s=(t.clientX-a(o.bar))/r;o.updateBar.call(o,"played",s,"width"),o.element.getElementsByClassName("aplayer-ptime")[0].innerHTML=o.secondToTime(s*o.audio.duration),o.audio.currentTime=parseFloat(o.playedBar.style.width)/100*o.audio.duration}),this.thumb.addEventListener("mouseover",function(){this.style.background=o.option.theme}),this.thumb.addEventListener("mouseout",function(){this.style.background="#fff"}),this.thumb.addEventListener("mousedown",function(){r=o.bar.clientWidth,clearInterval(o.playedTime),document.addEventListener("mousemove",e),document.addEventListener("mouseup",t)}),this.volumeBar=this.element.getElementsByClassName("aplayer-volume")[0];var d=this.element.getElementsByClassName("aplayer-volume-bar")[0],p=o.element.getElementsByClassName("aplayer-time")[0].getElementsByTagName("i")[0],c=35;this.element.getElementsByClassName("aplayer-volume-bar-wrap")[0].addEventListener("click",function(e){var t=e||window.event,a=(c-t.clientY+s(d))/c;a=a>0?a:0,a=1>a?a:1,o.updateBar.call(o,"volume",a,"height"),o.audio.volume=a,o.audio.muted&&(o.audio.muted=!1),1===a?p.className="demo-icon aplayer-icon-volume-up":p.className="demo-icon aplayer-icon-volume-down"}),p.addEventListener("click",function(){o.audio.muted?(o.audio.muted=!1,p.className=1===o.audio.volume?"demo-icon aplayer-icon-volume-up":"demo-icon aplayer-icon-volume-down",o.updateBar.call(o,"volume",o.audio.volume,"height")):(o.audio.muted=!0,p.className="demo-icon aplayer-icon-volume-off",o.updateBar.call(o,"volume",0,"height"))}),this.element.getElementsByClassName("aplayer-icon-loop")[0].addEventListener("click",function(){o.loop?(this.classList.add("aplayer-noloop"),o.loop=!1,o.audio.loop=o.playIndex>-1?!1:o.loop):(this.classList.remove("aplayer-noloop"),o.loop=!0,o.audio.loop=o.playIndex>-1?!1:o.loop)}),this.playIndex>-1&&this.element.getElementsByClassName("aplayer-icon-menu")[0].addEventListener("click",function(){var e=o.element.getElementsByClassName("aplayer-list")[0];e.classList.contains("aplayer-list-hide")?e.classList.remove("aplayer-list-hide"):e.classList.add("aplayer-list-hide")}),this.setMusic(0)},e.prototype.setMusic=function(e){this.playIndex>-1&&"undefined"!=typeof arguments[0]&&(this.playIndex=arguments[0]);var t=this.playIndex;if(this.music=this.playIndex>-1?this.option.music[t]:this.option.music,this.music.pic&&(this.element.getElementsByClassName("aplayer-pic")[0].style.backgroundImage="url("+encodeURI(this.music.pic)+")"),this.element.getElementsByClassName("aplayer-title")[0].innerHTML=this.music.title,this.element.getElementsByClassName("aplayer-author")[0].innerHTML=" - "+this.music.author,this.playIndex>-1&&(this.element.getElementsByClassName("aplayer-list-light")[0]&&this.element.getElementsByClassName("aplayer-list-light")[0].classList.remove("aplayer-list-light"),this.element.getElementsByClassName("aplayer-list")[0].getElementsByTagName("li")[t].classList.add("aplayer-list-light")),this.audio&&(this.pause(),this.audio.currentTime=0),this.playIndex>-1&&!this.audios[t]||-1===this.playIndex){this.audio=document.createElement("audio"),this.audio.src=this.music.url,this.audio.preload=this.isMobile?"none":"metadata";var a=this;this.audio.addEventListener("durationchange",function(){1!==a.audio.duration&&(a.element.getElementsByClassName("aplayer-dtime")[0].innerHTML=a.secondToTime(a.audio.duration))}),a.audio.addEventListener("progress",function(){var e=a.audio.buffered.length?a.audio.buffered.end(a.audio.buffered.length-1)/a.audio.duration:0;a.updateBar.call(a,"loaded",e,"width")}),this.audio.addEventListener("error",function(){a.element.getElementsByClassName("aplayer-author")[0].innerHTML=" - Error happens ╥﹏╥"}),this.playIndex>-1?this.audio.addEventListener("ended",function(){a.playIndex<a.option.music.length-1?a.setMusic(++a.playIndex):a.loop?a.setMusic(0):a.loop||a.pause()}):this.audio.addEventListener("ended",function(){a.loop||a.pause()}),this.audio.volume=parseInt(this.element.getElementsByClassName("aplayer-volume")[0].style.height)/100,this.audio.loop=this.playIndex>-1?!1:this.loop,this.playIndex>-1&&(this.audios[t]=this.audio)}else this.audio=this.audios[t],this.audio.volume=parseInt(this.element.getElementsByClassName("aplayer-volume")[0].style.height)/100,this.audio.currentTime=0;if(this.option.showlrc){this.lrc=this.playIndex>-1?this.lrcs[t]:this.lrcs[0],this.element.classList.add("aplayer-withlrc");var s="";this.lrcContents=this.element.getElementsByClassName("aplayer-lrc-contents")[0];for(var i=0;i<this.lrc.length;i++)s+="<p>"+this.lrc[i][1]+"</p>";this.lrcContents.innerHTML=s,this.lrcIndex||(this.lrcIndex=0),this.lrcContents.getElementsByTagName("p")[0].classList.add("aplayer-lrc-current"),this.lrcContents.style.transform="translateY(0px)",this.lrcContents.style.webkitTransform="translateY(0px)"}1!==this.audio.duration&&(this.element.getElementsByClassName("aplayer-dtime")[0].innerHTML=this.audio.duration?this.secondToTime(this.audio.duration):"00:00"),this.option.autoplay&&!this.isMobile&&this.play(),this.option.autoplay=!0,this.isMobile&&this.pause()},e.prototype.play=function(){var e=this;this.button.classList.remove("aplayer-play"),this.button.classList.add("aplayer-pause"),this.button.innerHTML="",setTimeout(function(){e.button.innerHTML='<i class="demo-icon aplayer-icon-pause"></i>'},100),this.audio.play(),this.playedTime&&clearInterval(this.playedTime),this.playedTime=setInterval(function(){e.updateBar.call(e,"played",e.audio.currentTime/e.audio.duration,"width"),e.option.showlrc&&e.updateLrc.call(e),e.element.getElementsByClassName("aplayer-ptime")[0].innerHTML=e.secondToTime(e.audio.currentTime)},100)},e.prototype.pause=function(){var e=this;this.button.classList.remove("aplayer-pause"),this.button.classList.add("aplayer-play"),this.button.innerHTML="",setTimeout(function(){e.button.innerHTML='<i class="demo-icon aplayer-icon-play"></i>'},100),this.audio.pause(),clearInterval(this.playedTime)},e.prototype.updateBar=function(e,t,a){t=t>0?t:0,t=1>t?t:1,this[e+"Bar"].style[a]=100*t+"%"},e.prototype.updateLrc=function(e){if("undefined"==typeof arguments[0]&&(e=this.audio.currentTime),this.lrcIndex>this.lrc.length-1||e<this.lrc[this.lrcIndex][0]||!this.lrc[this.lrcIndex+1]||e>=this.lrc[this.lrcIndex+1][0])for(var t=0;t<this.lrc.length;t++)e>=this.lrc[t][0]&&(!this.lrc[t+1]||e<this.lrc[t+1][0])&&(this.lrcIndex=t,this.lrcContents.style.transform="translateY("+20*-this.lrcIndex+"px)",this.lrcContents.style.webkitTransform="translateY("+20*-this.lrcIndex+"px)",this.lrcContents.getElementsByClassName("aplayer-lrc-current")[0].classList.remove("aplayer-lrc-current"),this.lrcContents.getElementsByTagName("p")[t].classList.add("aplayer-lrc-current"))},e.prototype.secondToTime=function(e){var t=function(e){return 10>e?"0"+e:""+e},a=parseInt(e/60),s=parseInt(e-60*a);return t(a)+":"+t(s)},e.prototype.parseLrc=function(e){for(var t=[],a=0;a<e.length;a++){for(var s=e[a].split("\n"),i=[],l=s.length,n=0;l>n;n++){var o=s[n].match(/\[(\d{2}):(\d{2})\.(\d{2,3})]/g),r=s[n].replace(/\[(\d{2}):(\d{2})\.(\d{2,3})]/g,"").replace(/^\s+|\s+$/g,"");if(null!=o)for(var d=o.length,p=0;d>p;p++){var c=/\[(\d{2}):(\d{2})\.(\d{2,3})]/.exec(o[p]),u=60*c[1]+parseInt(c[2])+parseInt(c[3])/(2===(c[3]+"").length?100:1e3);i.push([u,r])}}i.sort(function(e,t){return e[0]-t[0]}),t.push(i)}return t},"undefined"!=typeof module&&"undefined"!=typeof module.exports?module.exports=e:window.APlayer=e}(); \ No newline at end of file diff --git a/lib/player/pl.js b/lib/player/pl.js new file mode 100644 index 0000000..c83dfdc --- /dev/null +++ b/lib/player/pl.js @@ -0,0 +1,8 @@ +/* + HTML5 Shiv v3.7.0 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed +*/ +(function(l,f){function m(){var a=e.elements;return"string"==typeof a?a.split(" "):a}function i(a){var b=n[a[o]];b||(b={},h++,a[o]=h,n[h]=b);return b}function p(a,b,c){b||(b=f);if(g)return b.createElement(a);c||(c=i(b));b=c.cache[a]?c.cache[a].cloneNode():r.test(a)?(c.cache[a]=c.createElem(a)).cloneNode():c.createElem(a);return b.canHaveChildren&&!s.test(a)?c.frag.appendChild(b):b}function t(a,b){if(!b.cache)b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag(); +a.createElement=function(c){return!e.shivMethods?b.createElem(c):p(c,a,b)};a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+m().join().replace(/[\w\-]+/g,function(a){b.createElem(a);b.frag.createElement(a);return'c("'+a+'")'})+");return n}")(e,b.frag)}function q(a){a||(a=f);var b=i(a);if(e.shivCSS&&!j&&!b.hasCSS){var c,d=a;c=d.createElement("p");d=d.getElementsByTagName("head")[0]||d.documentElement;c.innerHTML="x<style>article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}</style>"; +c=d.insertBefore(c.lastChild,d.firstChild);b.hasCSS=!!c}g||t(a,b);return a}var k=l.html5||{},s=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,r=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,j,o="_html5shiv",h=0,n={},g;(function(){try{var a=f.createElement("a");a.innerHTML="<xyz></xyz>";j="hidden"in a;var b;if(!(b=1==a.childNodes.length)){f.createElement("a");var c=f.createDocumentFragment();b="undefined"==typeof c.cloneNode|| +"undefined"==typeof c.createDocumentFragment||"undefined"==typeof c.createElement}g=b}catch(d){g=j=!0}})();var e={elements:k.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video",version:"3.7.0",shivCSS:!1!==k.shivCSS,supportsUnknownElements:g,shivMethods:!1!==k.shivMethods,type:"default",shivDocument:q,createElement:p,createDocumentFragment:function(a,b){a||(a=f); +if(g)return a.createDocumentFragment();for(var b=b||i(a),c=b.frag.cloneNode(),d=0,e=m(),h=e.length;d<h;d++)c.createElement(e[d]);return c}};l.html5=e;q(f)})(this,document); \ No newline at end of file diff --git a/lib/player/src/APlayer.js b/lib/player/src/APlayer.js new file mode 100644 index 0000000..7a48268 --- /dev/null +++ b/lib/player/src/APlayer.js @@ -0,0 +1,545 @@ +/** + * APlayer constructor function + * + * @param {Object} option - See README + * @constructor + */ +(function () { + function APlayer(option) { + + this.isMobile = navigator.userAgent.match(/(iPad)|(iPhone)|(iPod)|(android)|(webOS)/i); + // compatibility: some mobile browsers don't suppose autoplay + if (this.isMobile) { + option.autoplay = false; + } + + // default options + var defaultOption = { + element: document.getElementsByClassName('aplayer')[0], + narrow: false, + autoplay: false, + showlrc: false, + theme: '#b7daff' + }; + for (var defaultKey in defaultOption) { + if (defaultOption.hasOwnProperty(defaultKey) && !option.hasOwnProperty(defaultKey)) { + option[defaultKey] = defaultOption[defaultKey]; + } + } + + // multiple music + this.playIndex = Object.prototype.toString.call(option.music) === '[object Array]' ? 0 : -1; + + this.option = option; + this.audios = []; + this.loop = true; + } + + /** + * AutoLink initialization function + */ + APlayer.prototype.init = function () { + this.element = this.option.element; + this.music = this.playIndex > -1 ? this.option.music[this.playIndex] : this.option.music; + + var i; + // parser lrc + if (this.option.showlrc) { + var lrcs = []; + for (i = 0; i < this.element.getElementsByClassName('aplayer-lrc-content').length; i++) { + lrcs.push(this.element.getElementsByClassName('aplayer-lrc-content')[i].innerHTML); + } + this.lrcs = this.parseLrc(lrcs); + } + + // fill in HTML + var eleHTML = '' + + '<div class="aplayer-pic">' + + '<div class="aplayer-button aplayer-play">' + + '<i class="demo-icon aplayer-icon-play"></i>' + + '</div>' + + '</div>' + + '<div class="aplayer-info">' + + '<div class="aplayer-music">' + + '<span class="aplayer-title"></span>' + + '<span class="aplayer-author"></span>' + + '</div>' + + '<div class="aplayer-lrc">' + + '<div class="aplayer-lrc-contents" style="transform: translateY(0); -webkit-transform: translateY(0);"></div>' + + '</div>' + + '<div class="aplayer-controller">' + + '<div class="aplayer-bar-wrap">' + + '<div class="aplayer-bar">' + + '<div class="aplayer-loaded" style="width: 0"></div>' + + '<div class="aplayer-played" style="width: 0; background: ' + this.option.theme + ';">' + + '<span class="aplayer-thumb" style="border: 1px solid ' + this.option.theme + ';"></span>' + + '</div>' + + '</div>' + + '</div>' + + '<div class="aplayer-time">' + + ' - <span class="aplayer-ptime">00:00</span> / <span class="aplayer-dtime">00:00</span>' + + '<div class="aplayer-volume-wrap">' + + '<i class="demo-icon aplayer-icon-volume-down"></i>' + + '<div class="aplayer-volume-bar-wrap">' + + '<div class="aplayer-volume-bar">' + + '<div class="aplayer-volume" style="height: 80%; background: ' + this.option.theme + ';"></div>' + + '</div>' + + '</div>' + + '</div>' + + '<i class="demo-icon aplayer-icon-loop"></i>' + + (this.playIndex > -1 ? '<i class="demo-icon aplayer-icon-menu"></i>' : '') + + '</div>' + + '</div>' + + '</div>'; + if (this.playIndex > -1) { + eleHTML += '' + + '<div class="aplayer-list">' + + '<ol>'; + for (i = 0; i < this.option.music.length; i++) { + eleHTML += '' + + '<li>' + + '<span class="aplayer-list-cur" style="background: ' + this.option.theme + ';"></span>' + + '<span class="aplayer-list-index">' + (i + 1) + '</span>' + + '<span class="aplayer-list-title">' + this.option.music[i].title + '</span>' + + '<span class="aplayer-list-author">' + this.option.music[i].author + '</span>' + + '</li>' + } + eleHTML += '' + + '</ol>' + + '</div>' + } + this.element.innerHTML = eleHTML; + + // switch to narrow style + if (this.option.narrow) { + this.element.classList.add('aplayer-narrow'); + } + + var _self = this; + + // play and pause button + this.button = this.element.getElementsByClassName('aplayer-button')[0]; + this.button.addEventListener('click', function () { + if (this.classList.contains('aplayer-play')) { + _self.play.call(_self); + } + else if (this.classList.contains('aplayer-pause')) { + _self.pause.call(_self); + } + }); + + // click music list: change music + if (this.playIndex > -1) { + for (i = 0; i < this.option.music.length; i++) { + this.element.getElementsByClassName('aplayer-list')[0].getElementsByTagName('li')[i].addEventListener('click', function () { + var musicIndex = parseInt(this.getElementsByClassName('aplayer-list-index')[0].innerHTML) - 1; + if (musicIndex !== _self.playIndex) { + _self.setMusic(musicIndex); + } + _self.play(); + }); + } + } + + // control play progress + this.playedBar = this.element.getElementsByClassName('aplayer-played')[0]; + this.loadedBar = this.element.getElementsByClassName('aplayer-loaded')[0]; + this.thumb = this.element.getElementsByClassName('aplayer-thumb')[0]; + this.bar = this.element.getElementsByClassName('aplayer-bar')[0]; + var barWidth; + this.bar.addEventListener('click', function (event) { + var e = event || window.event; + barWidth = _self.bar.clientWidth; + var percentage = (e.clientX - getElementViewLeft(_self.bar)) / barWidth; + _self.updateBar.call(_self, 'played', percentage, 'width'); + _self.element.getElementsByClassName('aplayer-ptime')[0].innerHTML = _self.secondToTime(percentage * _self.audio.duration); + _self.audio.currentTime = parseFloat(_self.playedBar.style.width) / 100 * _self.audio.duration; + }); + + this.thumb.addEventListener('mouseover', function () { + this.style.background = _self.option.theme; + }); + this.thumb.addEventListener('mouseout', function () { + this.style.background = '#fff'; + }); + + this.thumb.addEventListener('mousedown', function () { + barWidth = _self.bar.clientWidth; + clearInterval(_self.playedTime); + document.addEventListener('mousemove', thumbMove); + document.addEventListener('mouseup', thumbUp); + }); + + function thumbMove(event) { + var e = event || window.event; + var percentage = (e.clientX - getElementViewLeft(_self.bar)) / barWidth; + percentage = percentage > 0 ? percentage : 0; + percentage = percentage < 1 ? percentage : 1; + _self.updateBar.call(_self, 'played', percentage, 'width'); + if (_self.option.showlrc) { + _self.updateLrc.call(_self, parseFloat(_self.playedBar.style.width) / 100 * _self.audio.duration); + } + _self.element.getElementsByClassName('aplayer-ptime')[0].innerHTML = _self.secondToTime(percentage * _self.audio.duration); + } + + function thumbUp() { + document.removeEventListener('mouseup', thumbUp); + document.removeEventListener('mousemove', thumbMove); + _self.audio.currentTime = parseFloat(_self.playedBar.style.width) / 100 * _self.audio.duration; + _self.play(); + } + + // control volume + this.volumeBar = this.element.getElementsByClassName('aplayer-volume')[0]; + var volumeBarWrap = this.element.getElementsByClassName('aplayer-volume-bar')[0]; + var volumeicon = _self.element.getElementsByClassName('aplayer-time')[0].getElementsByTagName('i')[0]; + var barHeight = 35; + this.element.getElementsByClassName('aplayer-volume-bar-wrap')[0].addEventListener('click', function (event) { + var e = event || window.event; + var percentage = (barHeight - e.clientY + getElementViewTop(volumeBarWrap)) / barHeight; + percentage = percentage > 0 ? percentage : 0; + percentage = percentage < 1 ? percentage : 1; + _self.updateBar.call(_self, 'volume', percentage, 'height'); + _self.audio.volume = percentage; + if (_self.audio.muted) { + _self.audio.muted = false; + } + if (percentage === 1) { + volumeicon.className = 'demo-icon aplayer-icon-volume-up'; + } + else { + volumeicon.className = 'demo-icon aplayer-icon-volume-down'; + } + }); + volumeicon.addEventListener('click', function () { + if (_self.audio.muted) { + _self.audio.muted = false; + volumeicon.className = _self.audio.volume === 1 ? 'demo-icon aplayer-icon-volume-up' : 'demo-icon aplayer-icon-volume-down'; + _self.updateBar.call(_self, 'volume', _self.audio.volume, 'height'); + } + else { + _self.audio.muted = true; + volumeicon.className = 'demo-icon aplayer-icon-volume-off'; + _self.updateBar.call(_self, 'volume', 0, 'height'); + } + }); + + // get element's view position + function getElementViewLeft(element) { + var actualLeft = element.offsetLeft; + var current = element.offsetParent; + var elementScrollLeft; + while (current !== null) { + actualLeft += current.offsetLeft; + current = current.offsetParent; + } + elementScrollLeft = document.body.scrollLeft + document.documentElement.scrollLeft; + return actualLeft - elementScrollLeft; + } + + function getElementViewTop(element) { + var actualTop = element.offsetTop; + var current = element.offsetParent; + var elementScrollTop; + while (current !== null) { + actualTop += current.offsetTop; + current = current.offsetParent; + } + elementScrollTop = document.body.scrollTop + document.documentElement.scrollTop; + return actualTop - elementScrollTop; + } + + // loop control + this.element.getElementsByClassName('aplayer-icon-loop')[0].addEventListener('click', function () { + if (_self.loop) { + this.classList.add('aplayer-noloop'); + _self.loop = false; + _self.audio.loop = _self.playIndex > -1 ? false : _self.loop; + } + else { + this.classList.remove('aplayer-noloop'); + _self.loop = true; + _self.audio.loop = _self.playIndex > -1 ? false : _self.loop; + } + }); + + // toggle menu control + if (this.playIndex > -1) { + this.element.getElementsByClassName('aplayer-icon-menu')[0].addEventListener('click', function () { + var list = _self.element.getElementsByClassName('aplayer-list')[0]; + if (!list.classList.contains('aplayer-list-hide')) { + list.classList.add('aplayer-list-hide'); + } + else { + list.classList.remove('aplayer-list-hide'); + } + }); + } + + this.setMusic(0); + }; + + /** + * Set music + */ + APlayer.prototype.setMusic = function (index) { + // get this.music + if (this.playIndex > -1 && typeof(arguments[0]) !== 'undefined') { + this.playIndex = arguments[0]; + } + var indexMusic = this.playIndex; + this.music = this.playIndex > -1 ? this.option.music[indexMusic] : this.option.music; + + // set html + if (this.music.pic) { + this.element.getElementsByClassName('aplayer-pic')[0].style.backgroundImage = 'url(' + encodeURI(this.music.pic) + ')'; + } + this.element.getElementsByClassName('aplayer-title')[0].innerHTML = this.music.title; + this.element.getElementsByClassName('aplayer-author')[0].innerHTML = ' - ' + this.music.author; + if (this.playIndex > -1) { + if (this.element.getElementsByClassName('aplayer-list-light')[0]) { + this.element.getElementsByClassName('aplayer-list-light')[0].classList.remove('aplayer-list-light'); + } + this.element.getElementsByClassName('aplayer-list')[0].getElementsByTagName('li')[indexMusic].classList.add('aplayer-list-light'); + } + + // set the previous audio object + if (this.audio) { + this.pause(); + this.audio.currentTime = 0; + } + + // get this audio object + if ((this.playIndex > -1 && !this.audios[indexMusic]) || this.playIndex === -1) { + this.audio = document.createElement("audio"); + this.audio.src = this.music.url; + this.audio.preload = this.isMobile ? 'none' : 'metadata'; + + // show audio time + var _self = this; + this.audio.addEventListener('durationchange', function () { + if (_self.audio.duration !== 1) { // compatibility: Android browsers will output 1 at first + _self.element.getElementsByClassName('aplayer-dtime')[0].innerHTML = _self.secondToTime(_self.audio.duration); + } + }); + + // show audio loaded bar + _self.audio.addEventListener('progress', function () { + var percentage = _self.audio.buffered.length ? _self.audio.buffered.end(_self.audio.buffered.length - 1) / _self.audio.duration : 0; + _self.updateBar.call(_self, 'loaded', percentage, 'width'); + }); + + // audio download error + this.audio.addEventListener('error', function () { + _self.element.getElementsByClassName('aplayer-author')[0].innerHTML = ' - ' + 'Error happens ╥﹏╥'; + }); + + // multiple music play + if (this.playIndex > -1) { + this.audio.addEventListener('ended', function () { + if (_self.playIndex < _self.option.music.length - 1) { + _self.setMusic(++_self.playIndex); + } + else if (_self.loop) { + _self.setMusic(0); + } + else if (!_self.loop) { + _self.pause(); + } + }); + } + else { + this.audio.addEventListener('ended', function () { + if (!_self.loop) { + _self.pause(); + } + }); + } + + // control volume + this.audio.volume = parseInt(this.element.getElementsByClassName('aplayer-volume')[0].style.height) / 100; + + // loop + this.audio.loop = this.playIndex > -1 ? false : this.loop; + + if (this.playIndex > -1) { + this.audios[indexMusic] = this.audio; + } + } + else { + this.audio = this.audios[indexMusic]; + this.audio.volume = parseInt(this.element.getElementsByClassName('aplayer-volume')[0].style.height) / 100; + this.audio.currentTime = 0; + } + + // fill in lrc + if (this.option.showlrc) { + this.lrc = this.playIndex > -1 ? this.lrcs[indexMusic] : this.lrcs[0]; + this.element.classList.add('aplayer-withlrc'); + var lrcHTML = ''; + this.lrcContents = this.element.getElementsByClassName('aplayer-lrc-contents')[0]; + for (var i = 0; i < this.lrc.length; i++) { + lrcHTML += '<p>' + this.lrc[i][1] + '</p>'; + } + this.lrcContents.innerHTML = lrcHTML; + if (!this.lrcIndex) { + this.lrcIndex = 0; + } + this.lrcContents.getElementsByTagName('p')[0].classList.add('aplayer-lrc-current'); + this.lrcContents.style.transform = 'translateY(0px)'; + this.lrcContents.style.webkitTransform = 'translateY(0px)'; + } + + // set duration time + if (this.audio.duration !== 1) { // compatibility: Android browsers will output 1 at first + this.element.getElementsByClassName('aplayer-dtime')[0].innerHTML = this.audio.duration ? this.secondToTime(this.audio.duration) : '00:00'; + } + + // autoplay + if (this.option.autoplay && !this.isMobile) { + this.play(); + } + this.option.autoplay = true; // autoplay next music + + if (this.isMobile) { + this.pause(); + } + }; + + /** + * Play music + */ + APlayer.prototype.play = function () { + var _self = this; + this.button.classList.remove('aplayer-play'); + this.button.classList.add('aplayer-pause'); + this.button.innerHTML = ''; + setTimeout(function () { + _self.button.innerHTML = '<i class="demo-icon aplayer-icon-pause"></i>'; + }, 100); + this.audio.play(); + if (this.playedTime) { + clearInterval(this.playedTime); + } + this.playedTime = setInterval(function () { + _self.updateBar.call(_self, 'played', _self.audio.currentTime / _self.audio.duration, 'width'); + if (_self.option.showlrc) { + _self.updateLrc.call(_self); + } + _self.element.getElementsByClassName('aplayer-ptime')[0].innerHTML = _self.secondToTime(_self.audio.currentTime); + }, 100); + }; + + /** + * Pause music + */ + APlayer.prototype.pause = function () { + var _self = this; + this.button.classList.remove('aplayer-pause'); + this.button.classList.add('aplayer-play'); + this.button.innerHTML = ''; + setTimeout(function () { + _self.button.innerHTML = '<i class="demo-icon aplayer-icon-play"></i>'; + }, 100); + this.audio.pause(); + clearInterval(this.playedTime); + }; + + /** + * Update progress bar, including loading progress bar and play progress bar + * + * @param {String} type - Point out which bar it is, should be played loaded or volume + * @param {Number} percentage + * @param {String} direction - Point out the direction of this bar, Should be height or width + */ + APlayer.prototype.updateBar = function (type, percentage, direction) { + percentage = percentage > 0 ? percentage : 0; + percentage = percentage < 1 ? percentage : 1; + this[type + 'Bar'].style[direction] = percentage * 100 + '%'; + }; + + /** + * Update lrc + * + * @param {Number} currentTime + */ + APlayer.prototype.updateLrc = function (currentTime) { + if (typeof(arguments[0]) === 'undefined') { + currentTime = this.audio.currentTime; + } + if (this.lrcIndex > this.lrc.length - 1 || currentTime < this.lrc[this.lrcIndex][0] || (!this.lrc[this.lrcIndex + 1] || currentTime >= this.lrc[this.lrcIndex + 1][0])) { + for (var i = 0; i < this.lrc.length; i++) { + if (currentTime >= this.lrc[i][0] && (!this.lrc[i + 1] || currentTime < this.lrc[i + 1][0])) { + this.lrcIndex = i; + this.lrcContents.style.transform = 'translateY(' + -this.lrcIndex * 20 + 'px)'; + this.lrcContents.style.webkitTransform = 'translateY(' + -this.lrcIndex * 20 + 'px)'; + this.lrcContents.getElementsByClassName('aplayer-lrc-current')[0].classList.remove('aplayer-lrc-current'); + this.lrcContents.getElementsByTagName('p')[i].classList.add('aplayer-lrc-current'); + } + } + } + }; + + /** + * Parse second to 00:00 format + * + * @param {Number} second + * @return {String} 00:00 format + */ + APlayer.prototype.secondToTime = function (second) { + var add0 = function (num) { + return num < 10 ? '0' + num : '' + num; + }; + var min = parseInt(second / 60); + var sec = parseInt(second - min * 60); + return add0(min) + ':' + add0(sec); + }; + + /** + * Parse lrc, suppose multiple time tag + * + * @param {Array} arr - Format: + * [mm:ss.xx]lyric + * [mm:ss.xxx]lyric + * [mm:ss.xx][mm:ss.xx][mm:ss.xx]lyric + * + * @return {Array} [[[time, text], [time, text], [time, text], ...], [[time, text], [time, text], [time, text], ...], ...] + */ + APlayer.prototype.parseLrc = function (arr) { + var lrcs = []; + for (var k = 0; k < arr.length; k++) { + var lyric = arr[k].split('\n'); + var lrc = []; + var lyricLen = lyric.length; + for (var i = 0; i < lyricLen; i++) { + // match lrc time + var lrcTimes = lyric[i].match(/\[(\d{2}):(\d{2})\.(\d{2,3})]/g); + // match lrc text + var lrcText = lyric[i].replace(/\[(\d{2}):(\d{2})\.(\d{2,3})]/g, '').replace(/^\s+|\s+$/g, ''); + + if (lrcTimes != null) { + // handle multiple time tag + var timeLen = lrcTimes.length; + for (var j = 0; j < timeLen; j++) { + var oneTime = /\[(\d{2}):(\d{2})\.(\d{2,3})]/.exec(lrcTimes[j]); + var lrcTime = (oneTime[1]) * 60 + parseInt(oneTime[2]) + parseInt(oneTime[3]) / ((oneTime[3] + '').length === 2 ? 100 : 1000); + lrc.push([lrcTime, lrcText]); + } + } + } + // sort by time + lrc.sort(function (a, b) { + return a[0] - b[0]; + }); + lrcs.push(lrc); + } + return lrcs; + }; + + if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') { + module.exports = APlayer + } + else { + window.APlayer = APlayer; + } +})(); \ No newline at end of file diff --git a/lib/player/src/APlayer.scss b/lib/player/src/APlayer.scss new file mode 100644 index 0000000..b0dcf2a --- /dev/null +++ b/lib/player/src/APlayer.scss @@ -0,0 +1,424 @@ +$aplayer-height: 66px; +$lrc-height: 40px; +$aplayer-height-lrc: $aplayer-height + $lrc-height; + +@font-face { + font-family: 'aplayer-fontello'; + src: url('font/aplayer-fontello.eot?72550380'); + src: url('font/aplayer-fontello.eot?72550380#iefix') format('embedded-opentype'), + url('font/aplayer-fontello.woff?72550380') format('woff'), + url('font/aplayer-fontello.ttf?72550380') format('truetype'), + url('font/aplayer-fontello.svg?72550380#fontello') format('svg'); + font-weight: normal; + font-style: normal; +} + +.aplayer-narrow { + width: $aplayer-height; + .aplayer-info { + display: none; + } +} + +.aplayer-withlrc { + &.aplayer-narrow { + width: $aplayer-height-lrc; + } + &.aplayer .aplayer-pic { + height: $aplayer-height-lrc; + width: $aplayer-height-lrc; + } + &.aplayer .aplayer-info { + margin-left: $aplayer-height-lrc; + height: $aplayer-height-lrc; + } + &.aplayer .aplayer-lrc { + display: block; + } +} + +.aplayer { + font-family: Arial, Helvetica, sans-serif; + margin: 5px; + box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .14), 0 3px 1px -2px rgba(0, 0, 0, .2), 0 1px 5px 0 rgba(0, 0, 0, .12); + border-radius: 2px; + overflow: hidden; + user-select: none; + line-height: initial; + + [class^="aplayer-icon-"]:before, [class*=" aplayer-icon-"]:before { + font-family: "aplayer-fontello"; + font-style: normal; + font-weight: normal; + display: inline-block; + text-decoration: inherit; + width: 1em; + text-align: center; + font-variant: normal; + text-transform: none; + line-height: 1em; + } + + .aplayer-icon-play:before { + content: '\e806'; + } + + .aplayer-icon-pause:before { + content: '\e807'; + } + + .aplayer-icon-to-start:before { + content: '\e808'; + } + + .aplayer-icon-to-end:before { + content: '\e809'; + } + + .aplayer-icon-loop:before { + content: '\e803'; + } + + .aplayer-icon-menu:before { + content: '\e80b'; + } + + .aplayer-icon-volume-off:before { + content: '\e800'; + } + + .aplayer-icon-volume-down:before { + content: '\e801'; + } + + .aplayer-icon-volume-up:before { + content: '\e802'; + } + + .aplayer-lrc-content { + display: none; + } + + .aplayer-pic { + position: relative; + float: left; + height: $aplayer-height; + width: $aplayer-height; + background-image: url(./default.jpg); + background-size: 100%; + transition: all 0.3s ease; + + .aplayer-button { + position: absolute; + color: #fff; + border-radius: 50%; + opacity: 0.8; + cursor: pointer; + text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); + background: rgba(0, 0, 0, 0.2); + transition: all 0.1s ease; + &:hover { + opacity: 1; + } + } + + .aplayer-hide { + display: none; + } + + .aplayer-play { + width: 26px; + height: 26px; + border: 2px solid #fff; + bottom: 50%; + right: 50%; + margin: 0 -15px -15px 0; + .aplayer-icon-play { + position: absolute; + top: 2px; + left: 4px; + font-size: 20px; + line-height: 23px; + } + } + + .aplayer-pause { + width: 16px; + height: 16px; + border: 2px solid #fff; + bottom: 4px; + right: 4px; + .aplayer-icon-pause { + position: absolute; + top: 1px; + left: 2px; + font-size: 12px; + line-height: 14px; + } + } + } + + .aplayer-info { + margin-left: $aplayer-height; + padding: 14px 7px 0 10px; + height: $aplayer-height; + box-sizing: border-box; + + .aplayer-music { + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + margin-bottom: 17px; + + .aplayer-title { + font-size: 14px; + } + + .aplayer-author { + font-size: 12px; + color: #666; + } + } + + .aplayer-controller { + position: relative; + + .aplayer-bar-wrap { + margin: 0 140px 0 5px; + + .aplayer-bar { + position: relative; + height: 2px; + width: 100%; + background: #cdcdcd; + cursor: pointer !important; + + .aplayer-loaded { + position: absolute; + left: 0; + top: 0; + bottom: 0; + background: #aaa; + height: 2px; + transition: all 0.5s ease; + } + + .aplayer-played { + position: absolute; + left: 0; + top: 0; + bottom: 0; + height: 2px; + + .aplayer-thumb { + position: absolute; + top: 0; + right: 5px; + margin-top: -4px; + margin-right: -10px; + height: 8px; + width: 8px; + border-radius: 50%; + background: #fff; + cursor: pointer !important; + } + } + } + } + + .aplayer-time { + position: absolute; + right: 0; + bottom: -5px; + height: 17px; + color: #999; + font-size: 11px; + + i { + color: #666; + font-size: 15px; + cursor: pointer; + transition: all 0.2s ease; + + &.aplayer-icon-loop { + margin: 2px; + } + &.aplayer-noloop { + color: #ddd; + &:hover { + color: #bbb; + } + } + + &:hover { + color: #000; + } + } + } + + .aplayer-volume-wrap { + position: relative; + display: inline-block; + margin-left: 7px; + cursor: pointer !important; + + &:hover .aplayer-volume-bar-wrap { + display: block; + } + + .aplayer-volume-bar-wrap { + display: none; + position: absolute; + bottom: 17px; + right: -5px; + width: 25px; + height: 40px; + z-index: 99; + + .aplayer-volume-bar { + position: absolute; + bottom: 0; + right: 10px; + width: 5px; + height: 35px; + background: #aaa; + + .aplayer-volume { + position: absolute; + bottom: 0; + right: 0; + width: 5px; + transition: all 0.1s ease; + } + } + } + } + } + } + + .aplayer-lrc { + display: none; + position: relative; + height: $lrc-height; + background: #fff; + text-align: center; + overflow: hidden; + margin: -10px 0 10px; + + &:before { + position: absolute; + top: 0; + z-index: 1; + display: block; + overflow: hidden; + width: 100%; + height: 10%; + content: ' '; + background: -moz-linear-gradient(top, rgba(255,255,255,1) 0%, rgba(255,255,255,0) 100%); + background: -webkit-linear-gradient(top, rgba(255,255,255,1) 0%,rgba(255,255,255,0) 100%); + background: linear-gradient(to bottom, rgba(255,255,255,1) 0%,rgba(255,255,255,0) 100%); + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#00ffffff',GradientType=0 ); + } + + &:after { + position: absolute; + bottom: 0; + z-index: 1; + display: block; + overflow: hidden; + width: 100%; + height: 33%; + content: ' '; + background: -moz-linear-gradient(bottom, rgba(255,255,255,1) 0%, rgba(255,255,255,0) 100%); + background: -webkit-linear-gradient(bottom, rgba(255,255,255,1) 0%,rgba(255,255,255,0) 100%); + background: linear-gradient(to top, rgba(255,255,255,1) 0%,rgba(255,255,255,0) 100%); + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#00ffffff', endColorstr='#ffffff',GradientType=0 ); + } + + p { + font-size: 12px; + color: #666; + line-height: 20px !important; + height: 20px !important; + padding: 0 !important; + margin: 0 !important; + transition: all 0.5s ease-out; + opacity: 0.4; + overflow: hidden; + + &.aplayer-lrc-current { + opacity: 1; + } + } + + .aplayer-lrc-contents { + width: 100%; + transition: all 0.5s ease-out; + } + } + + .aplayer-list { + max-height: 300px; + overflow: auto; + transition: all 0.5s ease; + + &.aplayer-list-hide { + max-height: 0; + } + + ol { + list-style-type: none; + margin: 0; + padding: 0; + + li { + position: relative; + height: 32px; + line-height: 32px; + padding: 0 15px; + font-size: 12px; + border-top: 1px solid #e9e9e9; + cursor: pointer; + transition: all 0.2s ease; + + &:hover { + background: #efefef; + } + + &.aplayer-list-light { + background: #e9e9e9; + + .aplayer-list-cur { + display: inline-block; + } + } + + .aplayer-list-cur { + display: none; + width: 3px; + height: 22px; + position: absolute; + left: 0; + top: 5px; + cursor: pointer; + } + .aplayer-list-index { + color: #666; + margin-right: 12px; + cursor: pointer; + } + .aplayer-list-author { + color: #666; + float: right; + cursor: pointer; + } + } + } + } +} + +@keyframes aplayer-roll { + 0%{left:0} + 100%{left: -100%} +} \ No newline at end of file diff --git a/lib/player/src/default.jpg b/lib/player/src/default.jpg new file mode 100644 index 0000000..4559258 Binary files /dev/null and b/lib/player/src/default.jpg differ diff --git a/lib/player/src/font/aplayer-fontello.eot b/lib/player/src/font/aplayer-fontello.eot new file mode 100644 index 0000000..bf18c1c Binary files /dev/null and b/lib/player/src/font/aplayer-fontello.eot differ diff --git a/lib/player/src/font/aplayer-fontello.svg b/lib/player/src/font/aplayer-fontello.svg new file mode 100644 index 0000000..e87db9c --- /dev/null +++ b/lib/player/src/font/aplayer-fontello.svg @@ -0,0 +1,20 @@ +<?xml version="1.0" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<svg xmlns="http://www.w3.org/2000/svg"> +<metadata>Copyright (C) 2016 by original authors @ fontello.com</metadata> +<defs> +<font id="fontello" horiz-adv-x="1000" > +<font-face font-family="fontello" font-weight="400" font-stretch="normal" units-per-em="1000" ascent="850" descent="-150" /> +<missing-glyph horiz-adv-x="1000" /> +<glyph glyph-name="volume-off" unicode="&#xe800;" d="m429 654v-608q0-14-11-25t-25-10-25 10l-186 186h-146q-15 0-25 11t-11 25v214q0 15 11 25t25 11h146l186 186q10 10 25 10t25-10 11-25z" horiz-adv-x="428.6" /> +<glyph glyph-name="volume-down" unicode="&#xe801;" d="m429 654v-608q0-14-11-25t-25-10-25 10l-186 186h-146q-15 0-25 11t-11 25v214q0 15 11 25t25 11h146l186 186q10 10 25 10t25-10 11-25z m214-304q0-42-24-79t-63-52q-5-3-14-3-14 0-25 10t-10 26q0 12 6 20t17 14 19 12 16 20 6 32-6 32-16 20-19 12-17 14-6 20q0 15 10 26t25 10q9 0 14-3 39-15 63-52t24-79z" horiz-adv-x="642.9" /> +<glyph glyph-name="volume-up" unicode="&#xe802;" d="m429 654v-608q0-14-11-25t-25-10-25 10l-186 186h-146q-15 0-25 11t-11 25v214q0 15 11 25t25 11h146l186 186q10 10 25 10t25-10 11-25z m214-304q0-42-24-79t-63-52q-5-3-14-3-14 0-25 10t-10 26q0 12 6 20t17 14 19 12 16 20 6 32-6 32-16 20-19 12-17 14-6 20q0 15 10 26t25 10q9 0 14-3 39-15 63-52t24-79z m143 0q0-85-48-158t-125-105q-8-3-14-3-15 0-26 11t-10 25q0 22 21 33 32 16 43 25 41 30 64 75t23 97-23 97-64 75q-11 9-43 25-21 11-21 33 0 14 10 25t25 11q7 0 15-3 78-33 125-105t48-158z m143 0q0-128-71-236t-189-158q-7-3-14-3-15 0-26 11t-10 25q0 20 22 33 4 2 12 6t13 6q25 14 45 28 69 51 108 127t38 161-38 161-108 127q-20 14-45 28-4 3-13 6t-12 6q-22 13-22 33 0 14 10 25t26 11q7 0 14-3 118-51 189-158t71-236z" horiz-adv-x="928.6" /> +<glyph glyph-name="loop" unicode="&#xe803;" d="m800 540q42 0 71-29t29-71l0-290q0-40-29-70t-71-30l-700 0q-40 0-70 30t-30 70l0 290q0 42 30 71t70 29l250 0 0 110 200-180-200-180 0 110-210 0 0-210 620 0 0 210-150 0 0 140 190 0z" horiz-adv-x="900" /> +<glyph glyph-name="play" unicode="&#xe806;" d="m486 376q14-10 14-26 0-14-14-24l-428-266q-24-16-41-6t-17 40l0 514q0 30 17 40t41-6z" horiz-adv-x="500" /> +<glyph glyph-name="pause" unicode="&#xe807;" d="m440 700q90 0 90-64l0-570q0-66-90-66t-90 66l0 570q0 64 90 64z m-350 0q90 0 90-64l0-570q0-66-90-66t-90 66l0 570q0 64 90 64z" horiz-adv-x="530" /> +<glyph glyph-name="to-start" unicode="&#xe808;" d="m174 350q0 14 14 24l364 228q20 14 34 5t14-35l0-442q0-26-14-35t-34 5l-364 228q-14 10-14 22z m-174 234q0 58 76 58 74 0 74-58l0-466q0-58-74-58-76 0-76 58l0 466z" horiz-adv-x="600" /> +<glyph glyph-name="to-end" unicode="&#xe809;" d="m412 374q14-10 14-24 0-12-14-22l-362-228q-22-14-36-5t-14 35l0 442q0 26 14 35t36-5z m114 268q74 0 74-58l0-466q0-58-74-58-76 0-76 58l0 466q0 58 76 58z" horiz-adv-x="600" /> +<glyph glyph-name="menu" unicode="&#xe80b;" d="m650 400q22 0 36-15t14-35-15-35-35-15l-600 0q-20 0-35 15t-15 35 14 35 36 15l600 0z m-600 100q-20 0-35 15t-15 35 14 35 36 15l600 0q22 0 36-15t14-35-15-35-35-15l-600 0z m600-300q22 0 36-15t14-35-15-35-35-15l-600 0q-20 0-35 15t-15 35 14 35 36 15l600 0z" horiz-adv-x="700" /> +</font> +</defs> +</svg> \ No newline at end of file diff --git a/lib/player/src/font/aplayer-fontello.ttf b/lib/player/src/font/aplayer-fontello.ttf new file mode 100644 index 0000000..1d1ec93 Binary files /dev/null and b/lib/player/src/font/aplayer-fontello.ttf differ diff --git a/lib/player/src/font/aplayer-fontello.woff b/lib/player/src/font/aplayer-fontello.woff new file mode 100644 index 0000000..dfb0daf Binary files /dev/null and b/lib/player/src/font/aplayer-fontello.woff differ diff --git a/models/Cartriges.php b/models/Cartriges.php new file mode 100644 index 0000000..7532290 --- /dev/null +++ b/models/Cartriges.php @@ -0,0 +1,313 @@ +<?php + +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +/** + * Description of Catriges + * + * @author andrey + */ +class Cartriges { + //put your code here + + public static function getSumAllCarteiges(){ //получаем сумму всех картриджей(доставленных и замененных) по запросу ниже + + /*SELECT c.name as Имя, sum(aC.value) as Сумма FROM actionsCartriges aC + INNER JOIN cartriges c ON aC.id_cartriges = c.id + GROUP BY c.name;*/ + $db = Db::getConnection(); + + $sql = "SELECT c.name as name, sum(aC.action) as value FROM cartridges aC " + . "RIGHT JOIN cartriges c ON aC.id_cartrige = c.id " + . "WHERE c.action = 1 " + . "GROUP BY c.name"; + $result = $db->query($sql); + $result->setFetchMode(PDO::FETCH_ASSOC); + $i = 0; + while($row = $result->fetch()){ + $summ_cart[$i]['name'] = $row['name']; + $summ_cart[$i]['value'] = $row['value']; + if($summ_cart[$i]['value'] == NULL) $summ_cart[$i]['value'] = 0; + $i++; + } + + return $summ_cart; +//return arr(); + } + + public static function getActivCartriges(){ + + $db = Db::getConnection(); + + $result = $db->query('SELECT id, name FROM cartriges WHERE action = 1'); + $result->setFetchMode(PDO::FETCH_ASSOC); + $i = 0; + while($row = $result->fetch()){ + $cart[$i]['id'] = $row['id']; + $cart[$i]['name'] = $row['name']; + $i++; + } + return $cart; + } + + public static function getAllCartriges(){ + + $db = Db::getConnection(); + + $result = $db->query('SELECT id, name, action FROM cartriges'); + $result->setFetchMode(PDO::FETCH_ASSOC); + $i = 0; + while($row = $result->fetch()){ + $cart[$i]['id'] = $row['id']; + $cart[$i]['name'] = $row['name']; + $cart[$i]['action'] = $row['action']; + if(!Printer::getAllPrintersByCartrige($row['id'])) $cart[$i]['print_list'] = "Нет принтеров использующих данный картридж"; + else $cart[$i]['print_list'] = Printer::getAllPrintersByCartrige($row['id']); + $i++; + } + return $cart; + } + + public static function getHistoryCartridges($limit = 5){ + $db = Db::getConnection(); + $result = $db->query('SELECT hc.id, hc.user, hc.date, c.name, hc.action + FROM history_cartridges hc + LEFT JOIN cartriges c ON hc.id_cartridge = c.id + ORDER BY hc.id DESC + LIMIT '.$limit.';'); + + $result->setFetchMode(PDO::FETCH_ASSOC); + $i = 0; + while($row = $result->fetch()){ + foreach($row as $key=>$value){ + $cartridges[$i][$key] = $value; + } + $i++; + } + + return $cartridges; + } + + + + private static function setActionCartriges($user_name, $id_cartrige, $quatity, $act){ + + $db = Db::getConnection(); + $date = date("Y-m-d H:i:s"); + if($act == "out"){ + $action = $quatity * -1; + }elseif ($act == "in" || "zaro") { + $action = $quatity; + } + /* история действий по картриджам */ + if($act == "out"){ + $actions = "Замена ".$quatity." шт"; + }elseif ($act == "in") { + $actions = "Доставка ".$quatity." шт"; + }elseif ($act == "zero") { + $actions = "!!!Обнуление: ".$quatity." шт"; + } + Unit::setToHistoryCartridges($user_name, $id_cartrige, $actions); + /*end*/ + //внесение денных об изменениях принтера в бд + $stmt = $db->prepare("INSERT INTO cartridges (date, id_cartrige, action, user) VALUES (:date, :id_cartrige, :action, :user)"); + $stmt->bindParam(':date', $date); + $stmt->bindParam(':id_cartrige', $id_cartrige); + $stmt->bindParam(':action', $action); + $stmt->bindParam(':user', $user_name); + + return $stmt->execute(); + + + } + + public static function ActionCartriges($post_data, $session_data){ + + for($i = 0; $i < count($post_data)-2; $i++){ + self::setActionCartriges($session_data['user_id'], $post_data[$i]['cartrige'], $post_data[$i]['quatity'], $post_data['action']); + } + + return "all right"; + + } + + public static function colorRow($a){ + if($a < 3 && $a >= 2) return "class='warning'"; + elseif($a < 2) return "class='danger'"; + else return ""; + } + + public static function resetToZero(){ + $db = Db::getConnection(); + + $sql = "SELECT id_cartrige as id, sum(action) as value FROM cartridges GROUP BY id_cartrige"; + $result = $db->query($sql); + $result->setFetchMode(PDO::FETCH_ASSOC); + $i = 0; + while($row = $result->fetch()){ + $summ_cart[$i]['id'] = $row['id']; + $summ_cart[$i]['value'] = $row['value']; + if($summ_cart[$i]['value'] == NULL) $summ_cart[$i]['value'] = 0; + $i++; + } + + for($i = 0; $i < count($summ_cart); $i++){ + self::setActionCartriges($_SESSION["user_id"]."/resetToZero", $summ_cart[$i]['id'], $summ_cart[$i]['value']*-1, "zero"); + } + + /*return $stmt->execute(); + echo "<pre>"; + print_r($summ_cart); + echo "</pre>"; */ + + } + + + + public static function addCartriges($cart){ //добавление действия с картриджеми + + $db = Db::getConnection(); + + $name = $cart['name']; + (!$cart['action']) ? $action = 0 : $action = $cart['action']; + //добавление картриджа в бд + $stmt = $db->prepare("INSERT INTO cartriges (name, action) VALUES (:name, :action)"); + $stmt->bindParam(':name', $name); + $stmt->bindParam(':action', $action); + + return $stmt->execute(); + + } + + //public static function RemoveCartriges() + + public static function reactivCartriges($id){ // изменение статуза задействования принтера + + $db = Db::getConnection(); + $act_val = 0; + $cart = Printer::getCartrigeByID($id); + var_dump($cart); + ($cart[0]['action'] == 1) ? $act_val = 0 : $act_val = 1; + //добавление картриджа в бд + $stmt = $db->prepare("UPDATE cartriges SET action = :action WHERE id=:id"); + $stmt->bindParam(':action', $act_val); + $stmt->bindParam(':id', $id); + + return $stmt->execute(); + + } + + public static function orderCartriges($data){ //формирования массива принтеров для заказа картриджей + + /*приходящие данные + + * array(3) { + [0]=> + array(2) { + ["cartrige"]=> + string(1) "1" + ["quatity"]=> + string(1) "3" + } + [1]=> + array(2) { + ["cartrige"]=> + string(1) "2" + ["quatity"]=> + string(0) "" + } + ["submit"]=> + string(0) "" + *} + */ + + //запрос к базе - забираем список всех id принтеров по первому массиву заказа + //вставляем в массив $arr + $list = "";//список для IN + //случайные числа + for($j = 0; $j < count($data) - 1; $j++){ + $arr = self::setListPrintByID($data[$j]['cartrige']); //id принетров + $quantity = ceil($data[$j]['quantity']/2); + + //получаем нужные поля из таблицы с помощью случайного id из списка + if(count($arr)> 1){ + if(count($arr) < $quantity) $quantity = count($arr); + $rand_key = array_rand($arr, $quantity);// подставляем в цикл случайное число из массива + + for($i = 0; $i < $quantity; $i++){ + $list .= $arr[$rand_key[$i]].","; + } + + }elseif(count($arr)== 1){ + $list .= $arr[0].","; + } + } + + $list = substr($list, 0, -1); + //print_r ($list); + $data_ord = array(); + + $db = Db::getConnection(); + + $result = $db->query("SELECT model, name, unit, is_color FROM print WHERE id IN (".$list.")"); + $result->setFetchMode(PDO::FETCH_ASSOC); + $i = 0; + while($row = $result->fetch()){ + $data_ord[$i]['model'] = $row['model']; + $data_ord[$i]['name'] = $row['name']; + $data_ord[$i]['unit'] = $row['unit']; + $data_ord[$i]['is_color'] = $row['is_color']; + //if($row['is_color'] == 1) $data_ord[$i]['unit'] .= " (black, yellow, magenta, blue)"; + $i++; + } + + //print_r($data_ord); + return $data_ord; + //формируем нужный массив с данными для отправки письма + /* + * + * Array ( [0] => Array ( [model] => HP LJM1212 [name] => PRN0175 [unit] => 0055-7357 ) [1] => Array ( [model] => HP LJ 3030 [name] => DSK0173 [unit] => 0000-0297 ) [2] => Array ( [model] => HP LJ 3030 [name] => DKUR0151 [unit] => 0000-5280 ) [3] => Array ( [model] => HP LJ 3020 [name] => DSK4719 [unit] => 0000-5428 ) [4] => Array ( [model] => HP LJM1212 [name] => PRN0173 [unit] => 0053-3585 ) [5] => Array ( [model] => HP LJ 3030 [name] => dsk0651 [unit] => 0045-5575 ) [6] => Array ( [model] => HP LJM1212 [name] => prn0180 [unit] => 0043-8493 ) [7] => Array ( [model] => Ricoh Aficio SP 3510SF [name] => PRN0185 [unit] => 0045-1758 ) ) + * + */ + } + + private static function setListPrintByID($id){ + + $db = Db::getConnection(); + + $result = $db->query("SELECT id FROM print WHERE id_cartriges=".$id." AND id_status IN (1, 6, 8)"); + //$result->setFetchMode(PDO::FETCH_ASSOC); + $i = 0; + while($row = $result->fetch()){ + $ids[$i] = $row['id']; + $i++; + } + return $ids; + } + + public static function changeIsPublic($id){ + + $db = Db::getConnection(); + $result = $db->query('SELECT * FROM cartriges WHERE id='.$id); + $result->setFetchMode(PDO::FETCH_ASSOC); + $row = $result->fetch(); + + $is_publication = $row['action']; + + if($is_publication == 0) $is_publication_new = 1; + else $is_publication_new = 0; + + $stmt = $db->prepare("UPDATE cartriges SET action = :action WHERE id = :id"); + $stmt->bindParam(':id', $id); + $stmt->bindParam(':action', $is_publication_new); + $stmt->execute(); + + return true; + } + + +} diff --git a/models/Phonebook.php b/models/Phonebook.php new file mode 100644 index 0000000..e205995 --- /dev/null +++ b/models/Phonebook.php @@ -0,0 +1,292 @@ +<?php + +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +/** + * Description of Phonebook + * + * @author adm_azashchepkin + */ +class Phonebook { + //put your code here + public static function gelAllPhoneList($is_activ = 1){ + + $db = Db::getConnection(); + $arr_dep = Array(); + + if($is_activ == 1){ + $result = $db->query('SELECT id, department FROM dep'); + $result->setFetchMode(PDO::FETCH_ASSOC); + $i = 0; + while($row = $result->fetch()){ + $arr_dep[$i]['id'] = $row['id']; + $arr_dep[$i]['department'] = $row['department']; + $i++; + for($j = 0; count($arr_dep)>$j; $j++){ + $phonelist[$arr_dep[$j]['department']] = self::getPhoneInDepartment($arr_dep[$j]['id'], $is_activ); + } + } + }else{ + $phonelist = self::getPhoneInDepartment(0, $is_activ); + } + + return $phonelist; + } + + private static function getPhoneInDepartment($id_department = 0, $is_activ = 1){ + $db = Db::getConnection(); + $id = intval($id_department); + $list = []; + $sql = "SELECT book.id AS id, book.name AS name, book.mac_address AS mac, book.number AS number, book.post AS post, book.parent_post_id AS parent_id, book.subordination_id AS subordination, book.activ AS activ, dep.department AS department + FROM book + LEFT JOIN dep + ON book.department_id = dep.id"; + if($id_department != 0){ + $sql .= " WHERE book.department_id = ".$id; + } + if($is_activ == 1){ + $sql .= " AND book.activ = 1"; + } + $sql .= " ORDER BY book.department_id, book.subordination_id, book.post;"; + + $result = $db->query($sql); + $result->setFetchMode(PDO::FETCH_ASSOC); + + $i = 0; + while($row = $result->fetch()){ + if($row == NULL) break; + foreach($row as $key=>$value){ + $list[$i][$key] = $value; + } + $i++; + } + + return $list; + } + + public static function gerResultSearch($searching, $is_adm = 0){ + + $db = Db::getConnection(); + $list = false; + $sql = "SELECT book.id AS id, book.name AS name, book.mac_address AS mac, book.number AS number, book.post AS post, book.activ AS activ, dep.department AS department + FROM book + LEFT JOIN dep + ON book.department_id = dep.id + WHERE book.number LIKE '%".$searching."%' OR book.name LIKE '%".$searching."%' OR book.mac_address LIKE '%".$searching."%' "; + if($is_adm == 0) $sql .= " ORDER BY book.department_id, book.subordination_id, book.post;"; + else $sql .= " ORDER BY book.activ, book.number;"; + $result = $db->query($sql); + $result->setFetchMode(PDO::FETCH_ASSOC); + + $i = 0; + while($row = $result->fetch()){ + if($row == NULL) break; + foreach($row as $key=>$value){ + $list[$i][$key] = $value; + } + $i++; + } + + return $list; + } + + public static function getExcelList(){ + include ROOT.'/lib/phpexcel/PHPExcel.php'; + $phone_list = self::gelAllPhoneList(); + + $excel = new PHPExcel(); + $excelRead = PHPExcel_IOFactory::createReader('Excel2007'); + $excel = $excelRead->load('phonebook.xlsx'); + $excel->setActiveSheetIndex(0); + + # массив с параметрами + $arHeadStyle = array( + 'background'=> array( + 'color' => array('rgb' => 'ff0000') + ), + 'font' => array( + 'bold' => true, + 'color' => array('rgb' => '778899'), + 'size' => 13, + 'name' => 'Verdana' + ) + ); + + $i = 2; + + foreach($phone_list as $key => $value){ + + $excel->getActiveSheet()->mergeCells("A".$i.":C".$i.""); + $excel->getActiveSheet()->setCellValue('A'.$i,$key); + $excel->getActiveSheet()->getStyle('A'.$i)->applyFromArray($arHeadStyle); + $i++; + for($j = 0; count($value) > $j; $j++){ + $excel->getActiveSheet()->setCellValue('A'.$i,$value[$j]['name']) + ->setCellValue('B'.$i,$value[$j]['number']) + ->setCellValue('C'.$i,$value[$j]['post']); + $i++; + } + + } + + //Отдаем на скачивание + header("Content-Type:application/vnd.ms-excel"); + header("Content-Disposition:attachment;filename=Телефонный Справочник на ".date("d-m-Y").".xlsx"); + + $Writer = PHPExcel_IOFactory::createWriter($excel, 'Excel2007'); + + return $Writer->save('php://output'); + + } + + public static function changeIsActiv($id){ + + $db = Db::getConnection(); + $result = $db->query('SELECT * FROM book WHERE id='.$id); + $result->setFetchMode(PDO::FETCH_ASSOC); + $row = $result->fetch(); + + $activ = $row['activ']; + + if($activ == 0) {$activ = 1;} + else {$activ = 0;} + + $stmt = $db->prepare("UPDATE book SET activ = :activ WHERE id = :id"); + $stmt->bindParam(':id', $id); + $stmt->bindParam(':activ', $activ); + $stmt->execute(); + return true; + } + + public static function getElementByID($id){ + $id = intval($id); + $db = Db::getConnection(); + + $sql = "SELECT book.id AS id, book.name AS name, book.mac_address AS mac, book.number AS number, book.post AS post, book.parent_post_id AS parent_id, book.subordination_id AS subordination, book.department_id AS department, book.activ AS activ, book.login AS login + FROM book + WHERE book.id=".$id.";"; + + $result = $db->query($sql); + $result->setFetchMode(PDO::FETCH_ASSOC); + $row = $result->fetch(); + + return $row; + } + + public static function getSubordination(){ + + $db = Db::getConnection(); + + $sql = "SELECT * FROM subordination;"; + + $result = $db->query($sql); + $result->setFetchMode(PDO::FETCH_ASSOC); + $i = 0; + while($row = $result->fetch()){ + if($row == NULL) break; + foreach($row as $key=>$value){ + $list[$i][$key] = $value; + } + $i++; + } + + return $list; + } + + public static function getParents(){ + + $db = Db::getConnection(); + + $sql = "SELECT id, name FROM book WHERE subordination_id IN (1,2,3,4) AND activ = 1;"; + + $result = $db->query($sql); + $result->setFetchMode(PDO::FETCH_ASSOC); + $i = 0; + while($row = $result->fetch()){ + if($row == NULL) break; + foreach($row as $key=>$value){ + $list[$i][$key] = $value; + } + $i++; + } + + return $list; + } + + public static function getDepatmnents(){ + + $db = Db::getConnection(); + + $sql = "SELECT id, department FROM dep;"; + + $result = $db->query($sql); + $result->setFetchMode(PDO::FETCH_ASSOC); + $i = 0; + while($row = $result->fetch()){ + if($row == NULL) break; + foreach($row as $key=>$value){ + $list[$i][$key] = $value; + } + $i++; + } + + return $list; + } + + public static function save($data) { + $db = Db::getConnection(); + /*array(11) { + ["id"]=> + string(1) "1" + ["name"]=> + string(27) "Токарева Олеся" + ["number"]=> + string(5) "15005" + ["mac"]=> + string(15) "SEP001D70FCF8B8" + ["parent_id"]=> + string(1) "0" + ["subord"]=> + string(1) "1" + ["department"]=> + string(1) "1" + ["login"]=> + string(65) "intranet.rencredit.ru/my/Person.aspx?accountname=rccf%5Cotokareva" + ["post"]=> + string(18) " Директор" + ["activ"]=> + string(2) "on" + ["save"]=> + string(0) "" + }*/ + $id = filter_input(INPUT_POST, 'id'); + $name = filter_input(INPUT_POST, 'name'); + $number = filter_input(INPUT_POST, 'number'); + $mac = filter_input(INPUT_POST, 'mac'); + $parent_id = filter_input(INPUT_POST, 'parent_id'); + $subord = filter_input(INPUT_POST, 'subord'); + $department = filter_input(INPUT_POST, 'department'); + $login = filter_input(INPUT_POST, 'login'); + $post = filter_input(INPUT_POST, 'post'); + $activ = filter_input(INPUT_POST, 'activ'); + $activ == NULL ? $activ = 0 : $activ =1; + + $stmt = $db->prepare("UPDATE book SET name=:name, number=:number, mac_address=:mac, parent_post_id=:parent_id, subordination_id=:subord, department_id=:department, login=:login, post=:post, activ=:activ WHERE id = :id"); + $stmt->bindParam(':id', $id); + $stmt->bindParam(':name', $name); + $stmt->bindParam(':number', $number); + $stmt->bindParam(':mac', $mac); + $stmt->bindParam(':parent_id', $parent_id); + $stmt->bindParam(':subord', $subord); + $stmt->bindParam(':department', $department); + $stmt->bindParam(':login', $login); + $stmt->bindParam(':post', $post); + $stmt->bindParam(':activ', $activ); + + return $stmt->execute(); + } +} diff --git a/models/Printer.php b/models/Printer.php new file mode 100644 index 0000000..694f0d2 --- /dev/null +++ b/models/Printer.php @@ -0,0 +1,653 @@ +<?php + +/** + * Created on 04.10.2016 + * By NetBeans IDE 8.1 + * Author: Andrey Zashchepkin + * + * + * ******** Contacts:********* + * my e-mails - yaslonane@yandex.ru + * - andrey@zashchepkin.ru + * - info@zashchepkin.ru + * my site zashchepkin.ru + * ******** end contacts ********* + * + * + * Copyright zashchepkin.ru © 2016. All Rights Reserved. + * License https://opensource.org/licenses/mit-license.php MIT License (MIT) + * + * + * Description of Printer + * + * @author andrey + * */ +class Printer { + + public static function getListPrinters($id_status_print = 1){ + + $db = Db::getConnection(); + + /*$name = ""; + $unit = ""; + $floor = ""; + $department = ""; + $cartrige = ""; + $status = "";*/ + + if(isset($_POST['submit']) && (isset($_POST['name']) || isset($_POST['unit']) || isset($_POST['floor']) || isset($_POST['department']) || isset($_POST['cartrige']) || isset($_POST['status']))){ + + $sql = "SELECT * FROM print"; + /*echo "<pre>"; + var_dump($_POST) ; + echo "</pre>";*/ + if(!empty($_POST['name']) || !empty($_POST['unit']) || !empty($_POST['floor']) || !empty($_POST['department']) || !empty($_POST['cartrige']) || !empty($_POST['status'])) { + + $sql .= " WHERE "; + + if(!empty($_POST['name'])) { + $name = $_POST['name']; + $sql .= "name LIKE '%$name%', "; + } + + if(!empty($_POST['unit'])) { + $unit = $_POST['unit']; + $sql .= "unit = '$unit', "; + } + + if(!empty($_POST['floor'])) { + $floor = $_POST['floor']; + $sql .= "id_floor = $floor, "; + } + + if(!empty($_POST['department'])) { + $department = $_POST['department']; + $sql .= "id_department = $department, "; + } + + if(!empty($_POST['cartrige'])) { + $cartrige = $_POST['cartrige']; + $sql .= "id_cartrige = $cartrige, "; + } + + if(!empty($_POST['status'])) { + $status = $_POST['status']; + $sql .= "id_status = $status, "; + } + + + $sql = substr($sql, 0, -2); + $sql .= ";"; + + }else $sql .= ";"; + //echo $sql; + $result = $db->query($sql); + if($result == false) return 0; + $result->setFetchMode(PDO::FETCH_ASSOC); + //$row = $result->fetch(); + + //if($result->fetch() == false) $print = 0; + + $i = 0; + while($row = $result->fetch()){ + $print[$i]['id'] = $row['id']; + $print[$i]['name'] = $row['name']; + $print[$i]['model'] = $row['model']; + $print[$i]['unit'] = $row['unit']; + $fl = self::getAllValuesInTable('name', 'floor', $where = 'id', $where_value = $row['id_floor']); + $print[$i]['id_floor'] = $fl[0]['name']; + $dp = self::getAllValuesInTable('name', 'departments', $where = 'id', $where_value = $row['id_department']); + $print[$i]['id_department'] = $dp[0]['name'];; + $print[$i]['img'] = $row['img']; + $i++; + } + + return $print; + + + }else { + $sql = 'SELECT + print.id as id, + print.name as name, + print.model as model, + print.unit as unit, + print.inventar as indentar, + print.sn as sn, + cartriges.name as cartrige, + departments.name as department, + floor.name as floor, + status.name as status, + print.img as img + FROM print + LEFT JOIN `cartriges` ON cartriges.id = print.id_cartriges + LEFT JOIN `departments` ON departments.id = print.id_department + LEFT JOIN `floor` ON floor.id = print.id_floor + LEFT JOIN `status` ON status.id = print.id_status '; + + if($id_status_print == 'all'){ + $sql .= ';'; + }else + $sql .= 'WHERE print.id_status = '.$id_status_print.';'; + + + // $result = $db->query('SELECT * FROM print WHERE id_status = 1'); + $result = $db->query($sql); + + /* + * SELECT id + * FROM actionsCartriges aC + * INNER JOIN cartriges c ON aC.id_cartriges = c.id + */ + + $result->setFetchMode(PDO::FETCH_ASSOC); + //$row = $result->fetch(); + + //if($result->fetch() == false) $print = 0; + + $i = 0; + while($row = $result->fetch()){ + $print[$i]['id'] = $row['id']; + $print[$i]['name'] = $row['name']; + $print[$i]['model'] = $row['model']; + $print[$i]['unit'] = $row['unit']; + $print[$i]['id_floor'] = $row['floor']; + $print[$i]['id_department'] = $row['department']; + $print[$i]['img'] = $row['img']; + $i++; + } + + return $print; + } + + + } + + private static function getListFunction($id_functions){ + $error = "Отсутствует"; + if($id_functions){ + $db = Db::getConnection(); + $sql = 'SELECT id, name, description FROM functions '; + $sql .= 'WHERE id IN ('.$id_functions.')'; + $result = $db->query($sql); + $result->setFetchMode(PDO::FETCH_ASSOC); + $i = 0; + while($row = $result->fetch()){ + $arr[$i]['id'] = $row['id']; + $arr[$i]['name'] = $row['name']; + $arr[$i]['description'] = $row['description']; + $i++; + } + return $arr; + }else return $error; + } + + public static function getPrintByID($id){ + $db = Db::getConnection(); + $result = $db->query(' + SELECT + print.id as id, + print.name as name, + print.model as model, + print.unit as unit, + print.inventar as inventar, + print.id_functions as functions, + print.sn as sn, + cartriges.name as cartrige, + departments.name as department, + adress.city as city, + adress.street as street, + adress.house as house, + floor.name as floor, + status.name as status, + print.img as img + FROM print + LEFT JOIN `cartriges` ON cartriges.id = print.id_cartriges + LEFT JOIN `departments` ON departments.id = print.id_department + LEFT JOIN `adress` ON adress.id = print.id_adress + LEFT JOIN `floor` ON floor.id = print.id_floor + LEFT JOIN `status` ON status.id = print.id_status + WHERE print.id = '.$id.' + '); + + /* + * SELECT id + * FROM actionsCartriges aC + * INNER JOIN cartriges c ON aC.id_cartriges = c.id + */ + + $result->setFetchMode(PDO::FETCH_ASSOC); + //$row = $result->fetch(); + + //if($result->fetch() == false) $print = 0; + + $row = $result->fetch(); + $print['id'] = $row['id']; + $print['name'] = $row['name']; + $print['model'] = $row['model']; + $print['unit'] = $row['unit']; + $print['inventar'] = $row['inventar']; + $print['sn'] = $row['sn']; + $print['adress'] = $row['city'] .", ". $row['street'].", ". $row['house']; + $print['floor'] = $row['floor']; + $print['department'] = $row['department']; + $print['status'] = $row['status']; + $print['cartrige'] = $row['cartrige']; + $print['img'] = $row['img']; + $print['functions'] = self::getListFunction($row['functions']); + + return $print; + } + + public static function getPrintByIDFullData($id){ + $db = Db::getConnection(); + $result = $db->query(' + SELECT + print.id as id, + print.name as name, + print.model as model, + print.unit as unit, + print.inventar as inventar, + print.id_functions as functions, + print.sn as sn, + cartriges.name as cartrige, + print.id_cartriges as id_cart, + departments.name as department, + print.id_department as id_dep, + floor.name as floor, + print.id_floor as id_fl, + status.name as status, + print.id_status as id_st, + print.img as img + FROM print + LEFT JOIN `cartriges` ON cartriges.id = print.id_cartriges + LEFT JOIN `departments` ON departments.id = print.id_department + LEFT JOIN `floor` ON floor.id = print.id_floor + LEFT JOIN `status` ON status.id = print.id_status + WHERE print.id = '.$id.' + '); + + /* + * SELECT id + * FROM actionsCartriges aC + * INNER JOIN cartriges c ON aC.id_cartriges = c.id + */ + + $result->setFetchMode(PDO::FETCH_ASSOC); + //$row = $result->fetch(); + + //if($result->fetch() == false) $print = 0; + + $row = $result->fetch(); + $print['id'] = $row['id']; + $print['name'] = $row['name']; + $print['model'] = $row['model']; + $print['unit'] = $row['unit']; + $print['inventar'] = $row['inventar']; + $print['sn'] = $row['sn']; + $print['floor'] = $row['floor']; + $print['id_fl'] = $row['id_fl']; + $print['department'] = $row['department']; + $print['id_dep'] = $row['id_dep']; + $print['status'] = $row['status']; + $print['id_st'] = $row['id_st']; + $print['cartrige'] = $row['cartrige']; + $print['id_cart'] = $row['id_cart']; + $print['img'] = $row['img']; + $print['functions'] = self::getListFunction($row['functions']); + + return $print; + } + + public static function checkDataUpdatePrint($old_data, $new_data){ + + $message = ""; + $update = array(); + $i = 0; + + if($old_data['name'] != $new_data['name']){ + $i++; + $update[$i]['object'] = "Имя принтера"; + $update[$i]['old_data'] = $old_data['name']; + $update[$i]['new_data'] = $new_data['name']; + } + if($old_data['model'] != $new_data['model']){ + $i++; + $update[$i]['object'] = "Модель принтера"; + $update[$i]['old_data'] = $old_data['model']; + $update[$i]['new_data'] = $new_data['model']; + } + if($old_data['unit'] != $new_data['unit']){ + $i++; + $update[$i]['object'] = "Номер UNIT принтера"; + $update[$i]['old_data'] = $old_data['unit']; + $update[$i]['new_data'] = $new_data['unit']; + } + if($old_data['inventar'] != $new_data['inventar']){ + $i++; + $update[$i]['object'] = "Инвентарный номер принтера"; + $update[$i]['old_data'] = $old_data['inventar']; + $update[$i]['new_data'] = $new_data['inventar']; + } + if($old_data['sn'] != $new_data['sn']){ + $i++; + $update[$i]['object'] = "Серийный номер принтера"; + $update[$i]['old_data'] = $old_data['sn']; + $update[$i]['new_data'] = $new_data['sn']; + } + + if($old_data['id_fl'] != $new_data['id_floor']){ + $i++; + $update[$i]['object'] = "Этаж"; + $update[$i]['old_data'] = $old_data['id_fl']; + $update[$i]['new_data'] = $new_data['id_floor']; + } + if($old_data['id_dep'] != $new_data['id_department']){ + $i++; + $update[$i]['object'] = "Отдел"; + $update[$i]['old_data'] = $old_data['id_dep']; + $update[$i]['new_data'] = $new_data['id_department']; + } + if($old_data['id_cart'] != $new_data['id_cartrige']){ + $i++; + $update[$i]['object'] = "Картридж"; + $update[$i]['old_data'] = $old_data['id_cart']; + $update[$i]['new_data'] = $new_data['id_cartrige']; + } + if($old_data['id_st'] != $new_data['id_status']){ + $i++; + $update[$i]['object'] = "Статус"; + $update[$i]['old_data'] = $old_data['id_st']; + $update[$i]['new_data'] = $new_data['id_status']; + } + + if(self::identical_values(self::modAndCheckFunctions($old_data['functions']), $new_data['id_functions']) == false){ + if($old_data['functions'] != "Отсутствует"){ + $del = array_diff(self::modAndCheckFunctions($old_data['functions']), $new_data['id_functions']); + $add = array_diff( $new_data['id_functions'], self::modAndCheckFunctions($old_data['functions'])); + }else { + $del = false; + $add = $new_data['id_functions']; + } + + if($del){ + $i++; + $update[$i]['object'] = "Функции удалили"; + $update[$i]['old_data'] = implode(",", $del); + $update[$i]['new_data'] = ""; + } + if($add){ + $i++; + $update[$i]['object'] = "Функции добавили"; + $update[$i]['old_data'] = ""; + $update[$i]['new_data'] = implode(",", $add); + } + + } + + return $update; + + } + + public static function setHistoryChange($data_change, $id_print, $id_user){ + //формирования запроса + for($i=1; $i <= count($data_change); $i++){ + self::InsertHistoryChange($id_print, $id_user, $data_change[$i]['object'], $data_change[$i]['old_data'], $data_change[$i]['new_data']); + } + return true; + } + + public static function getHistoryChangeByID($id_print){ + //формирования запроса + $db = Db::getConnection(); + + $history = $db->query('SELECT * FROM history_change WHERE id_print ='.$id_print.';'); + + $history->setFetchMode(PDO::FETCH_ASSOC); + + $i = 0; + while($row = $history->fetch()){ + foreach($row as $key => $value){ + $arr[$i][$key] = $value; + } + $i++; + } + return $arr; + } + + public static function message(){ + if(isset($_SESSION['message'])){ + return true; + } + return false; + } + + private static function InsertHistoryChange($id_print, $user, $object_change, $old_data, $new_data){ + $db = Db::getConnection(); + $date = date("Y-m-d H:i:s"); + //внесение денных об изменениях принтера в бд + $stmt = $db->prepare("INSERT INTO history_change (date, id_print, user, object_change, old_data, new_data) VALUES (:date, :id_print, :user, :object_change, :old_data, :new_data)"); + $stmt->bindParam(':date', $date); + $stmt->bindParam(':id_print', $id_print); + $stmt->bindParam(':user', $user); + $stmt->bindParam(':object_change', $object_change); + $stmt->bindParam(':old_data', $old_data); + $stmt->bindParam(':new_data', $new_data); + + return $stmt->execute(); + } + + public static function insertPrint($data, $return_id = false){ + //формирование запроса и обновление данных в базе + $db = Db::getConnection(); + $functions = ""; + if(isset($data['id_functions'])) $functions = implode(",", $data['id_functions']); + //внесение денных об изменениях принтера в бд + $stmt = $db->prepare("INSERT INTO print + (name, unit, model, sn, inventar, id_floor, id_department, id_cartriges, id_status, id_functions) + VALUES + (:name, :unit, :model, :sn, :inventar, :id_floor, :id_department, :id_cartrige, :id_status, :id_functions)"); + //$stmt->bindParam(':id', $id_print, PDO::PARAM_INT); + $stmt->bindParam(':name', $data['name']); + $stmt->bindParam(':unit', $data['unit']); + $stmt->bindParam(':model', $data['model']); + $stmt->bindParam(':sn', $data['sn']); + $stmt->bindParam(':inventar', $data['inventar']); + $stmt->bindParam(':id_floor', $data['id_floor']); + $stmt->bindParam(':id_department', $data['id_department']); + $stmt->bindParam(':id_cartrige', $data['id_cartrige']); + $stmt->bindParam(':id_status', $data['id_status']); + $stmt->bindParam(':id_functions', $functions); + + $stmt->execute(); + + if($return_id = false) return true; + else return $db->lastInsertId(); + + } + + public static function updatePrint($id_print, $data){ + //формирование запроса и обновление данных в базе + $db = Db::getConnection(); + $functions = implode(",", $data['id_functions']); + //внесение денных об изменениях принтера в бд + $stmt = $db->prepare("UPDATE print set name=:name, unit=:unit, model=:model, sn=:sn, inventar=:inventar, id_floor=:id_floor, id_department=:id_department, id_cartriges=:id_cartrige, id_status=:id_status, id_functions=:id_functions WHERE id = :id"); + $stmt->bindParam(':id', $id_print, PDO::PARAM_INT); + $stmt->bindParam(':name', $data['name']); + $stmt->bindParam(':unit', $data['unit']); + $stmt->bindParam(':model', $data['model']); + $stmt->bindParam(':sn', $data['sn']); + $stmt->bindParam(':inventar', $data['inventar']); + $stmt->bindParam(':id_floor', $data['id_floor']); + $stmt->bindParam(':id_department', $data['id_department']); + $stmt->bindParam(':id_cartrige', $data['id_cartrige']); + $stmt->bindParam(':id_status', $data['id_status']); + $stmt->bindParam(':id_functions', $functions); + + return $stmt->execute(); + } + + private static function identical_values($arrayA, $arrayB) { + if(!is_array($arrayA) || !is_array($arrayA)) return false; + else{ + sort( $arrayA ); + sort( $arrayB ); + + return $arrayA == $arrayB; + } + } + + + private static function modAndCheckFunctions($old_functions){ + if($old_functions != "Отсутствует"){ + $old_mod_functions = array(); + + for($i=0; $i < count($old_functions); $i++){ + $old_mod_functions[] = $old_functions[$i]['id']; + } + + return $old_mod_functions; + } else return false; + } + + + public static function getAllFloors(){ + + return self::getAllValuesInTable('*', 'floor'); + + } + + public static function getAllDepartments(){ + + return self::getAllValuesInTable(array('id', 'name'), 'departments', $where = 'action', $where_value = '1'); + + } + + public static function getAllCartriges(){ + + return self::getAllValuesInTable(array('id', 'name'), 'cartriges', $where = 'action', $where_value = '1'); + + } + + public static function getAllPrintersByCartrige($id_cartriges){ + + return self::getAllValuesInTable(array('id', 'name', 'id_status'), 'print', $where = 'id_cartriges', $where_value = $id_cartriges); + + } + + public static function getCartrigeByID($id){ + + return self::getAllValuesInTable("*", 'cartriges', $where = 'id', $where_value = $id); + + } + + public static function getAllStatuses(){ + + return self::getAllValuesInTable('*', 'status'); + } + + public static function getAllFunctions(){ + + return self::getAllValuesInTable('*', 'functions'); + } + + private static function getAllValuesInTable($columns, $table, $where = false, $where_value = false){ + + $db = Db::getConnection(); + $arr = null; + $sql = "SELECT "; + + if(is_array($columns)) $columns = implode(",", $columns); + + $sql .= "$columns FROM $table"; + + if($where != false) { + + $sql .= " WHERE $where=$where_value"; + } + + $sql .= ";"; + + $result = $db->query($sql); + $result->setFetchMode(PDO::FETCH_ASSOC); + //$result->fetch(); + //var_dump($row = $result->fetch()); + //if($result->fetch() == false) return false; СДЕЛАТЬ ИМЕНА КЛЮЧЕЙ МАССИВА ИЗ ВЫГРУЖАЕМЫХ ДАННЫХ!!!!!!!!! НИЖЕ + + $i = 0; + while($row = $result->fetch()){ + + foreach($row as $key => $value){ + $arr[$i][$key] = $value; + } + /*$arr[$i]['id'] = $row['id']; + $arr[$i]['name'] = $row['name']; + if(isset($row['id_status'])) $arr[$i]['id_status'] = $row['id_status'];*/ + $i++; + } + + return $arr; + } + + public static function getRandPrint($quantity){ + $db = Db::getConnection(); + $list = "";//список для IN + $arr = array(); + $print = []; + + $id_list = $db->query('SELECT id FROM print WHERE id_status = 1'); + + $id_list->setFetchMode(PDO::FETCH_ASSOC); + + $i = 0; + while($row = $id_list->fetch()){ + $arr[$i] = $row['id']; + $i++; + } + + $rand_key = array_rand($arr, $quantity);// подставляем в цикл случайное число из массива + + for($j = 0; $j < $quantity; $j++){ + $list .= $arr[$rand_key[$j]].","; + } + + $list = substr($list, 0, -1); + + echo $list; + + $result = $db->query(' + SELECT + print.id as id, + print.name as name, + print.model as model, + print.unit as unit, + print.inventar as indentar, + print.sn as sn, + cartriges.name as cartrige, + departments.name as department, + floor.name as floor, + status.name as status, + print.img as img, + print.is_color as color + FROM print + LEFT JOIN `cartriges` ON cartriges.id = print.id_cartriges + LEFT JOIN `departments` ON departments.id = print.id_department + LEFT JOIN `floor` ON floor.id = print.id_floor + LEFT JOIN `status` ON status.id = print.id_status + WHERE print.id IN ('.$list.')'); + + $result->setFetchMode(PDO::FETCH_ASSOC); + $k = 0; + while($row = $result->fetch()){ + $print[$k]['id'] = $row['id']; + $print[$k]['name'] = $row['name']; + $print[$k]['model'] = $row['model']; + $print[$k]['unit'] = $row['unit']; + $print[$k]['id_floor'] = $row['floor']; + $print[$k]['id_department'] = $row['department']; + $print[$k]['img'] = $row['img']; + $print[$k]['color'] = $row['color']; + $k++; + } + return $print; + } +} diff --git a/models/Radio.php b/models/Radio.php new file mode 100644 index 0000000..207635d --- /dev/null +++ b/models/Radio.php @@ -0,0 +1,94 @@ +<?php + +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +/** + * Description of radio + * + * @author adm_azashchepkin + */ +class Radio { + //put your code here + + public static function radioList(){ + + $radio = Icecast::getConnection(); + + //$scfp = fsockopen($scip, $scport, $errno, $errstr, 10); + $scfp = fopen("http://".$radio['ip'].":".$radio['port']."/status3.xsl", "r"); + + if($scfp) { + //fwrite($scfp,"GET /status3.xsl HTTP/1.0\r\n User-Agent: Icecast Song Status (Mozilla Compatible)\r\n\r\n"); + $info = ''; + while(!feof($scfp)) { + $listeners = fgets($scfp, 1000); // Вот то, что нам надо + //вывод количества слушателей + $info .= trim($listeners); + } + + fclose($scfp); + + $info = explode('!!', $info); + unset($info[0]); + + foreach ($info as $value) { + $exploded = explode('%%', $value); + $new_info[$exploded[0]] = $exploded; + } + + return $new_info; + } + } + + public static function radioImg($a){ + $a = substr($a,1); + $img = "http://dsk7681/player/img/".$a.".jpg"; + if (@fopen($img, "r")) { + return $a; + } else { + return 'none'; + } + } + + public static function getStatistic(){ + $radio = Icecast::getConnection(); + + $scfp = fopen("http://".$radio['ip'].":".$radio['port']."/status3.xsl", "r"); + $list = fread($scfp, 10000); + + $statistics = []; + + $info = explode('!!', $list); + for($i=0; count($info)>$i; $i++){ + $elements = explode('%%', $info[$i]); + $statistics[$i]['stream'] = $elements[0]; + $statistics[$i]['quantity_listens'] = @$elements[1]; + $statistics[$i]['artist'] = @$elements[2]; + $statistics[$i]['title'] = @$elements[3]; + } + /*array(3) { + ["host"]=> + string(7) "dsk7681" + ["ip"]=> + string(11) "10.20.4.219" + ["port"]=> + string(4) "8000" + } + + * + * + * 0 name stream + * 1 quantity listens + * 2 artist + * 3 name composiition + * + */ + array_shift($statistics); + + return $statistics; + } +} diff --git a/models/Unit.php b/models/Unit.php new file mode 100644 index 0000000..ad875d4 --- /dev/null +++ b/models/Unit.php @@ -0,0 +1,300 @@ +<?php + +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +/** + * Description of Unit + * + * @author adm_azashchepkin + */ +class Unit { + //put your code here + private static $db; + + const SHOW_BY_DEFAULT = 10; + + public function __construct() { + self::$db = Db::getConnection(); + } + + public static function setRequest($user_id, $id_print, $description){ + + $db = Db::getConnection(); + $date = strval(time()); + $status = 1; + //$username = $user_id; + //$id_prn = intval($id_print); + //$description = htmlspecialchars($description); + + //внесение денных об изменениях принтера в бд + $stmt = $db->prepare("INSERT INTO requests (date_create, user, id_print, description, status) VALUES (:date_create, :user, :id_print, :description, :status)"); + $stmt->bindParam(':date_create', $date); + $stmt->bindParam(':user', $user_id); + $stmt->bindParam(':id_print', $id_print); + $stmt->bindParam(':description', $description); + $stmt->bindParam(':status', $status); + + $stmt->execute(); + return $db->lastInsertId(); + } + + public static function createNewAction($id_request, $act, $user){ + $db = Db::getConnection(); + $date = strval(time()); + if($act === 0) {$action = 1;} + + $stmt = $db->prepare("INSERT INTO actions_request (request_id, action_id, date, user) VALUES (:request_id, :action, :date, :user)"); + $stmt->bindParam(':request_id', $id_request); + $stmt->bindParam(':action', $action); + $stmt->bindParam(':date', $date); + $stmt->bindParam(':user', $user); + + return $stmt->execute(); + } + + public static function getAllActionByIDRequest($id_request){ + $db = Db::getConnection(); + $sql = "SELECT + actions_request.id AS id, + actions_request.request_id AS request_id, + actions_request.action_id AS action_id, + actions_request.description AS description, + actions_request.date AS date, + actions_request.user AS user, + actions.name AS actname + FROM actions_request + LEFT JOIN actions ON actions.id = actions_request.action_id + WHERE actions_request.request_id=".$id_request.";"; + $result = $db->query($sql); + $result->setFetchMode(PDO::FETCH_ASSOC); + + $actions = NULL; + + $i = 0; + while($row = $result->fetch()){ + //if($row == NULL) return NULL; + foreach($row as $key=>$value){ + $actions[$i][$key] = $value; + //$actions[$i]['docs'] = self::getAllLinkByActionID($actions[$i]['id']); + } + $i++; + } + + for($i=0; count($actions)>$i; $i++){ + $actions[$i]['docs'] = self::getAllLinkByActionID($actions[$i]['id']); + } + + return $actions; + } + + public static function getAllLinkByActionID($id){ + $docs = false; + $db = Db::getConnection(); + $sql = "SELECT docname, link, id_request, id_actions FROM doc_for_requests WHERE id_actions=".$id.";"; + $result = $db->query($sql); + + $result->setFetchMode(PDO::FETCH_ASSOC); + $i = 0; + while($row = $result->fetch()){ + //if($row == NULL) return NULL; + foreach($row as $key=>$value){ + $docs[$i][$key] = $value; + } + $i++; + } + + return $docs; + } + + public static function getRequests($page){ + + $db = Db::getConnection(); + + $page = intval($page); + $offset = ($page - 1) * self::SHOW_BY_DEFAULT; + $sql =""; + //$sql = "SELECT * FROM requests ORDER BY id DESC LIMIT ".self::SHOW_BY_DEFAULT." OFFSET ".$offset; + $sql .= "SELECT + requests.id AS id, + requests.date_create AS date_create, + requests.user AS user, + requests.id_print AS id_print, + print.name AS printname, + print.unit AS unit, + print.model AS printmodel, + requests.description, + requests.status AS id_status, + request_status.name AS status, + requests.date_close + FROM requests + LEFT JOIN print ON requests.id_print = print.id + LEFT JOIN request_status ON requests.status = request_status.id"; + $sql .= " ORDER BY id DESC LIMIT ".self::SHOW_BY_DEFAULT." OFFSET ".$offset; + $result = $db->query($sql); + $result->setFetchMode(PDO::FETCH_ASSOC); + + $list = NULL; + + $i = 0; + while($row = $result->fetch()){ + if($row == NULL) break; + foreach($row as $key=>$value){ + $list[$i][$key] = $value; + $list[$i]['actions'] = self::getAllActionByIDRequest($list[$i]['id']); + } + $i++; + } + + return $list; + } + + public static function getTotalRequests(){ + $db = Db::getConnection(); + + $result = $db->query('SELECT count(id) AS count FROM requests'); + $result->setFetchMode(PDO::FETCH_ASSOC); + $row = $result->fetch(); + + return $row['count']; + } + + public static function getRequestByID($id){ + $db = Db::getConnection(); + $sql = "SELECT + requests.id AS id, + requests.date_create AS date_create, + requests.user AS user, + requests.id_print AS id_print, + print.name AS printname, + print.unit AS unit, + print.model AS printmodel, + print.img AS img, + requests.description, + requests.status AS id_status, + request_status.name AS status, + requests.date_close + FROM requests + LEFT JOIN print ON requests.id_print = print.id + LEFT JOIN request_status ON requests.status = request_status.id + WHERE requests.id =".$id.";"; + + $result = $db->query($sql); + $result->setFetchMode(PDO::FETCH_ASSOC); + $row = $result->fetch(); + + return $row; + } + + public static function getStringJSONbyModal($data){ + $data['user'] = $_SESSION['user_id']; + return json_encode($data); + } + + public static function setNewActions(){ + + $request_id = filter_input(INPUT_POST, 'request_id'); + $user = filter_input(INPUT_POST, 'user'); + $date = filter_input(INPUT_POST, 'date'); //2017-10-27 + $action_id = filter_input(INPUT_POST, 'action_id'); + $description = filter_input(INPUT_POST, 'description'); + //$docs = filter_input(INPUT_POST, 'docs'); + $arr_date = explode("-", $date); + $U_date = mktime(0,0,0,$arr_date[1],$arr_date[2],$arr_date[0]); //"2017-10-27" + + $db = Db::getConnection(); + + if($action_id == 2){ + $stmt = $db->prepare("UPDATE requests SET status=2 WHERE id=:id"); + $stmt->bindParam(':id', $request_id, PDO::PARAM_INT); + $stmt->execute(); + }elseif($action_id == 4){ + $stmt = $db->prepare("UPDATE requests SET status=3, date_close=:date WHERE id=:id"); + $stmt->bindParam(':id', $request_id, PDO::PARAM_INT); + $stmt->bindParam(':date', $U_date); + $stmt->execute(); + } + //внесение денных об изменениях принтера в бд + $stmt = $db->prepare("INSERT INTO actions_request (request_id, action_id, description, date, user) VALUES (:request_id, :action_id, :description, :date, :user)"); + $stmt->bindParam(':date', $U_date); + $stmt->bindParam(':request_id', $request_id); + $stmt->bindParam(':user', $user); + $stmt->bindParam(':description', $description); + $stmt->bindParam(':action_id', $action_id); + + $stmt->execute(); + return $db->lastInsertId(); + } + + public static function setNewDocs($id_action, $id_request, $docs){ + + $links = explode("\n", $docs); + + $link = array_slice($links, 0, (count($links)-1)); + + $docs = []; + for($i=0; count($link)>$i;$i++){ + $docs[$i]['name'] = substr(strrchr($link[$i], "/"), 1); //обрезаем ссылку и получаем имя файла + $docs[$i]['link'] = $link[$i]; //обрезаем ссылку и получаем имя файла + } + + $db = Db::getConnection(); + + for($j=0;count($docs)>$j;$j++){ + $docname = $docs[$j]['name']; + $doclink = $docs[$j]['link']; + + $stmt = $db->prepare("INSERT INTO doc_for_requests (link, docname, id_request, id_actions) VALUES (:link, :docname, :id_request, :id_actions)"); + $stmt->bindParam(':link', $doclink); + $stmt->bindParam(':docname', $docname); + $stmt->bindParam(':id_request', $id_request); + $stmt->bindParam(':id_actions', $id_action); + + $stmt->execute(); + } + + return true; + } + + public static function saveOrder($user, $data){ + + /*array(3) { + [0]=> + array(2) { + ["cartrige"]=> + string(1) "1" + ["quatity"]=> + string(1) "3" + } + [1]=> + array(2) { + ["cartrige"]=> + string(1) "2" + ["quatity"]=> + string(0) "" + }*/ + + for($i=0; $i < count($data)-1; $i++){ + $a = "Заказ ".$data[$i]['quantity']." шт"; + self::setToHistoryCartridges($user, $data[$i]['cartrige'], $a); + /*$a = "Заказ ".$data[$i]['quantity']." штук"; + self::setToHistoryCartridges($user, $data[$i]['cartrige'], $a);*/ + } + + return true; + } + + public static function setToHistoryCartridges($user, $id_catridge, $action){ + $db = Db::getConnection(); + $stmt = $db->prepare("INSERT INTO history_cartridges (user, date, id_cartridge, action) VALUES (:user, UNIX_TIMESTAMP(), :id_cartridge, :action)"); + $stmt->bindParam(':user', $user); + $stmt->bindParam(':id_cartridge', $id_catridge); + $stmt->bindParam(':action', $action); + $stmt->execute(); + + return true; + } +} diff --git a/models/user.php b/models/user.php new file mode 100644 index 0000000..5261696 --- /dev/null +++ b/models/user.php @@ -0,0 +1,149 @@ +<?php + +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +/** + * Description of user + * + * @author andrey + */ +class user { + //put your code here + + /*public static function register($name, $password, $email){ + + $db = Db::getConnection(); + + $sql = 'INSERT INTO user (name, password, email) VALUES (:name, :password, :email)'; + + $result = $db->prepare($sql); + $result->bindParam(':name', $name, PDO::PARAM_STR); + $result->bindParam(':password', $password, PDO::PARAM_STR); + $result->bindParam(':email', $email, PDO::PARAM_STR); + + return $result->execute(); + + }*/ + + public static function checkAuth(){ + if(isset($_SESSION['user_id'])) return true; + else return false; + } + + public static function checkAdmin(){ + if(isset($_SESSION['user_id']) && ($_SESSION['department'] == "Отдел информационных технологий")) return true; + else return false; + } + + /* public static function checkName($name){ + + if(strlen($name) >= 2){ + return true; + } + return false; + } + + public static function checkPassword($password){ + + if(strlen($password) >= 6){ + return true; + } + return false; + } + + public static function checkEmail($email){ + + if(filter_var($email, FILTER_VALIDATE_EMAIL)){ + return true; + } + return false; + } + + public static function checkEmailExists($email){ + + $db = Db::getConnection(); + + $sql = 'SELECT COUNT(*) FROM user WHERE email = :email'; + + $result = $db->prepare($sql); + $result->bindParam(':email', $email, PDO::PARAM_STR); + $result->execute(); + + if($result->fetchColumn()) + return true; + return false; + } + + public static function checkUserData($email, $password){ + + $db = Db::getConnection(); + + $sql = 'SELECT * FROM user WHERE email = :email AND password = :password'; + + $result = $db->prepare($sql); + $result->bindParam(':email', $email, PDO::PARAM_INT); + $result->bindParam(':password', $password, PDO::PARAM_INT); + $result->execute(); + + $user = $result->fetch(); + if($user){ + return $user['id']; + } + return false; + } + + public static function checkLogged(){ + + if($_SESSION['user']){ + return $_SESSION['user']; + } + + header("location: /user/login/"); + } + + public static function auth($userId){ + + $_SESSION['user'] = $userId; + } + + public static function isGuest(){ + if(isset($_SESSION['user'])){ + return false; + } + return true; + } + + public static function getUserById($id) { + if ($id){ + + $db = Db::getConnection(); + + $sql = 'SELECT * FROM user WHERE id = :id'; + $result = $db->prepare($sql); + $result->bindParam(':id', $id, PDO::PARAM_INT); + $result->setFetchMode(PDO::FETCH_ASSOC); + $result->execute(); + + return $result->fetch(); + } + } + + public static function edit($id, $name, $password, $email){ + + $db = DB::getConnection(); + + $sql = 'UPDATE user SET name=:name, password=:password, email=:email WHERE id=:id'; + + $result = $db->prepare($sql); + $result->bindParam(':id', $id, PDO::PARAM_INT); + $result->bindParam(':name', $name, PDO::PARAM_INT); + $result->bindParam(':password', $password, PDO::PARAM_INT); + $result->bindParam(':email', $email, PDO::PARAM_INT); + return $result->execute(); + }*/ + +} diff --git a/nbproject/private/private.properties b/nbproject/private/private.properties new file mode 100644 index 0000000..e68bd53 --- /dev/null +++ b/nbproject/private/private.properties @@ -0,0 +1,2 @@ +index.file=index.php +url=http://localhost/prints/ diff --git a/nbproject/project.properties b/nbproject/project.properties new file mode 100644 index 0000000..9282ba4 --- /dev/null +++ b/nbproject/project.properties @@ -0,0 +1,7 @@ +include.path=${php.global.include.path} +php.version=PHP_70 +source.encoding=UTF-8 +src.dir=. +tags.asp=false +tags.short=false +web.root=. diff --git a/nbproject/project.xml b/nbproject/project.xml new file mode 100644 index 0000000..4ba8533 --- /dev/null +++ b/nbproject/project.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://www.netbeans.org/ns/project/1"> + <type>org.netbeans.modules.php.project</type> + <configuration> + <data xmlns="http://www.netbeans.org/ns/php-project/1"> + <name>prints</name> + </data> + </configuration> +</project> diff --git a/phonebook.xlsx b/phonebook.xlsx new file mode 100644 index 0000000..13c336b Binary files /dev/null and b/phonebook.xlsx differ diff --git a/template/css/style.css b/template/css/style.css new file mode 100644 index 0000000..e69de29 diff --git a/views/default/action_cartriges.php b/views/default/action_cartriges.php new file mode 100644 index 0000000..83fd349 --- /dev/null +++ b/views/default/action_cartriges.php @@ -0,0 +1,80 @@ +<?php include ROOT . TMPL . 'header.php'; ?> +<?php if($act_error == 1): ?> + <script> + $(document).ready(function() { + $("#error_action").modal('show'); + }); + </script> +<?php endif; ?> + + <!-- HTML-код модального окна --> +<div id="error_action" class="modal fade"> + <div class="modal-dialog"> + <div class="modal-content"> + <!-- Заголовок модального окна --> + <div class="modal-header"> + <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> + <h4 class="modal-title">Не выбрано действие</h4> + </div> + <!-- Основное содержимое модального окна --> + <div class="modal-body"> + <h3>Вы производили замену картриджей или была доставка?</h3> + <div class="btn-group btn-group-justified"> + <a href="?act=out" class="btn btn-primary btn-lg" target="_blank">Замена</a> + <a href="?act=in" class="btn btn-primary btn-lg" target="_blank">Доставка</a> + </div> + </div> + <!-- Футер модального окна --> + <div class="modal-footer"> + <!--<button type="button" class="btn btn-default" data-dismiss="modal">Закрыть</button>--> + </div> + </div> + </div> +</div> + + + + + <p class="text-center"> + <?php if($action == "in"):?> + <h2>Доставка картриджей</h2> + <?php elseif($action == "out"): ?> + <h2>Замена картриджей</h2> + <?php endif; ?> + <form action="/cartriges" method="post"> + <table class="table"> + <thead> + <tr> + <th scope="col">Наименование</th> + <th scope="col">Количество</th> + <th scope="col">&nbsp;</th> + </tr> + </thead> + <tbody id="dynamic"> + <!-- ЭТА СТРОКА БУДЕТ ШАБЛОНОМ ДЛЯ ВНОВЬ СОЗДАВАЕМЫХ //--> + <tr> + <td class="col-xs-3"> + <select class="form-control input-lg" name="cartrige"> + <option selected value="">Выбирете картридж</option> + <?php foreach($cartriges as $cart): ?> + <option value="<?php echo $cart['id']; ?>"><?php echo $cart['name']; ?></option> + <?php endforeach; ?> + </select> + </td> + <td class="col-xs-3"> + <input class="form-control input-lg" type='number' name='quatity' value='' min='0' max='10' step='1' placeholder="Укажите кол-во"/> + </td> + <td class="col-xs-2"> + <button type="button" class="btn btn-primary add">+</button> + <button type="button" class="btn btn-primary del">-</button> + </td> + </tr> + </tbody> + </table> + <!-- конец СТРОКи БУДЕТ ШАБЛОНОМ ДЛЯ ВНОВЬ СОЗДАВАЕМЫХ //--> + <input type="hidden" name='action' value="<?php echo $action; ?>" />. + <button type="submit" name="submit" class="btn btn-primary">Внести</button> + </form> + </p> + +<?php include ROOT . TMPL . 'footer.php'; ?> diff --git a/views/default/action_request.php b/views/default/action_request.php new file mode 100644 index 0000000..b210f59 --- /dev/null +++ b/views/default/action_request.php @@ -0,0 +1,139 @@ +<?php include ROOT . TMPL . 'header.php'; ?> + +<?php if($error == "access denied"): ?> + <div class="panel panel-danger col-xs-offset-4 col-xs-4"> + <div class="panel-heading"> + <h3 class="panel-title">Error!!!</h3> + </div> + <div class="panel-body"> + Ошибка доступа + </div> + </div> +<?php else: ?> + +<!-- HTML-код модального окна --> +<div class="modal fade" id="newactionrequest" tabindex="-1" role="dialog" aria-labelledby="newactionrequestLabel" aria-hidden="true"> + <div class="modal-dialog" role="document"> + <div class="modal-content"> + <div class="modal-header"> + <button type="button" class="close" data-dismiss="modal" aria-label="Close"> + <span aria-hidden="true">&times;</span> + </button> + <h4 class="modal-title" id="newactionrequestLabel">Редактирование записи</h4> + </div> + <div class="modal-body"> + <form id="newaction" method="POST" action="/unit/newactionrequest"> + <div class="form-group"> + <input type="hidden" class="form-control" name="request_id" id="id"> + <label for="user" class="form-control-label">Логин:</label> + <input type="text" class="form-control" id="user" name="user"> + <label for="date" class="form-control-label">Дата:</label> + <input type="date" class="form-control" id="date" name="date"> + <label for="action" class="form-control-label">Действие:</label> + <select class="form-control" id="action_id" name="action_id"> + <datalist id="action_id"> + <option disabled selected>Действие</option> + <option value="1">Создание запроса</option> + <option value="2">Подтверждение от юнита</option> + <option value="3">Визит инжененра</option> + <option value="4">Закрытине запроса</option> + </select> + <label for="description" class="form-control-label">Описание:</label> + <textarea class="form-control" id="description" name="description"></textarea> + <label for="docs" class="form-control-label">Документы:</label> + <script type="text/javascript"> + function openKCFinder(textarea) { + window.KCFinder = { + callBackMultiple: function(files) { + window.KCFinder = null; + textarea.value = ""; + for (var i = 0; i < files.length; i++) + textarea.value += files[i] + "\n"; + } + }; + window.open('<?php echo LIB ?>/kcfinder/browse.php?type=files&dir=files/public', + 'kcfinder_multiple', 'status=0, toolbar=0, location=0, menubar=0, ' + + 'directories=0, resizable=1, scrollbars=0, width=800, height=600' + ); + } + </script> + + <textarea id="docs" name="docs" class="form-control" readonly="readonly" onclick="openKCFinder(this)">Нажмите здесь и выберите несколько файлов с помощью клавиши Ctrl/command. Затем нажмите правой кнопкой мыши на одном из них и выберите " Выбрать"</textarea> + + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> + <button type="submit" class="btn btn-primary" name="save">Сохранить</button> + </div> + </form> + </div> + </div> + </div> + </div> + + +<h4>Основная информация <br><small>Заявка № <?php echo $list['id']; ?></small></h4> +<br /> + <div class="row" id="history"> + <div class="col-xs-3 col-xs-offset-1"> + <label class="control-label " for="date_create">Дата открытия: </label> <?php echo date("d-m-Y", $list['date_create']); ?> + <br /><label class="control-label " for="user">Логин автора: </label> <?php echo $list['user']; ?> + <br /><label class="control-label " for="status">Статус заявки: </label> <?php echo $list['status']; ?> + <br /><label class="control-label " for="date_close">Дата закрытия: </label> <?php echo date("d-m-Y", $list['date_close']); ?> + </div> + <div class="col-xs-4"> + <label class="control-label " for="printname">Имя: </label> <?php echo $list['printname']; ?> + <br /><label class="control-label " for="printmodel">Модель: </label> <?php echo $list['printmodel']; ?> + <br /><label class="control-label " for="unit">№ юнит: </label> <?php echo $list['unit']; ?> + <br /><label class="control-label " for="description">Описание: </label> <?php echo $list['description']; ?> + </div> + <div class="col-xs-4"> + <img width="150px" src="<?php echo $list['img']; ?>"/> + </div> + </div> + + +<h4>История движения <br><small>Заявка № <?php echo $list['id']; ?> Текущий статус: <i><?php echo $list['status']; ?></i></small></h4> + + +<ul class="timeline"> + <?php foreach($act as $action): ?> + <li><!---Time Line Element---> + <div class="timeline-badge up"> + <?php if($action['action_id'] == 1): ?> + <i class="fa fa-envelope-o" aria-hidden="true"></i> + <?php elseif($action['action_id'] == 2): ?> + <i class="fa fa-envelope-open-o" aria-hidden="true"></i> + <?php elseif($action['action_id'] == 3): ?> + <i class="fa fa-handshake-o" aria-hidden="true"></i> + <?php elseif($action['action_id'] == 4): ?> + <i class="fa fa-floppy-o" aria-hidden="true"></i> + <?php else: ?> + <i class="fa fa-thumbs-up"></i> + <?php endif; ?> + </div> + <div class="timeline-panel"> + <div class="timeline-heading"> + <h4 class="timeline-title"><p><?php echo $action['actname']; ?></p> + <small><strong>Дата:</strong> <em><?php echo date("d-m-Y", $action['date']) ?></em></small> <small><strong>Пользователь:</strong> <em><?php echo $action['user'] ?></em></small> </h4> + </div> + <div class="timeline-body"><!---Time Line Body&Content---> + <p><?php echo $action['description'] ?></p> + </div> + + <dl class="row"> + <dt class="col-xs-1 text-right">Документы</dt> + <?php for($i=0;count($action['docs']) > $i; $i++): ?> + <?php if($i==0):?><dd class="col-xs-10"><a href="<?php echo $action['docs'][$i]['link']; ?>" target="_blank"><?php echo $action['docs'][$i]['docname']; ?></a></dd> + <?php else:?> <dd class="col-xs-offset-1 col-xs-10"><a href="<?php echo $action['docs'][$i]['link']; ?>" target="_blank"><?php echo $action['docs'][$i]['docname']; ?></a></dd> + <?php endif; ?> + <?php endfor; ?> + </dl> + </div> + </li> + <?php endforeach; ?> +</ul> + +<button type="button" class="btn btn-link" data-toggle="modal" data-target="#newactionrequest" data-whatever='<?php echo Unit::getStringJSONbyModal($list); ?>'><i class="fa fa-cogs" aria-hidden="true"></i></button> +<?php endif; ?> +<?php include ROOT . TMPL . 'footer.php'; ?> \ No newline at end of file diff --git a/views/default/add_prn.php b/views/default/add_prn.php new file mode 100644 index 0000000..1ca8cb0 --- /dev/null +++ b/views/default/add_prn.php @@ -0,0 +1,97 @@ +<?php include ROOT . TMPL . 'header.php'; ?> + + <div class="row"> + <div class="col-md-4"> + <img class="img-responsive" src="/img/print.png" alt="..."> + <br><button type="submit" class="btn btn-primary">Сменить изображение</button> + </div> + <div class="col-md-8"> + <?php if(Printer::message() != false): ?> + <?php if($_SESSION['message'] == "good"): ?> + <!-- Сообщение об успешном выполнения действия --> + <div class="alert alert-success"> + <!-- Кнопка для закрытия сообщения, созданная с помощью элемента button --> + <button type="button" class="close" data-dismiss="alert">×</button> + Изменения сохранены. + </div> + + <?php else: ?> + <!-- Сообщение об ошибке --> + <div class="alert alert-danger"> + <!-- Кнопка для закрытия сообщения, созданная с помощью элемента a --> + <a href="#" class="close" data-dismiss="alert">×</a> + Неизвестная ошибка при передаче данных. + </div> + <?php endif; ?> + <?php endif; ?> + <form action="" method="post"> + <h4>ID <strong></strong></h4><br> + <input type="text" class="form-control" name="name" placeholder="Name" value=""><br> + <input type="text" class="form-control" name="unit" placeholder="#Unit" value=""><br> + <input type="text" class="form-control" name="model" placeholder="Model" value=""><br> + <input type="text" class="form-control" name="sn" placeholder="Серийный" value=""><br> + <input type="text" class="form-control" name="inventar" placeholder="Инвентарный" value=""><br> + + <select class="form-control" name="id_floor" > + <option selected>Этаж</option> + <?php foreach($floor as $fl): ?> + <option value="<?php echo $fl['id']; ?>"><?php echo $fl['name']; ?></option> + <?php endforeach; ?> + + </select><br> + <select class="form-control" name="id_department" > + <option selected>Отдел</option> + <?php foreach($department as $dp): ?> + <option value="<?php echo $dp['id']; ?>"><?php echo $dp['name']; ?></option> + <?php endforeach; ?> + </select><br> + <select class="form-control" name="id_cartrige" > + <option selected>Картридж</option> + <?php foreach($cartrige as $c): ?> + <option value="<?php echo $c['id']; ?>"><?php echo $c['name']; ?></option> + <?php endforeach; ?> + </select><br> + <select class="form-control" name="id_status" > + <option selected>Статус</option> + <?php foreach($status as $st): ?> + <option value="<?php echo $st['id']; ?>"><?php echo $st['name']; ?></option> + <?php endforeach; ?> + </select><br> + <label>Функционал</label> + + <table> + <tr> + <td> + <select id="src_countries" style="width:270px" class='select form-control' multiple="multiple" size="10"> + <option disabled selected>Выберите функцию</option> + <?php foreach($functions as $fn): ?> + <option value="<?php echo $fn['id']; ?>"><?php echo $fn['name']; ?></option> <!-- <?php //if($print['functions'][$i]['id'] == $fn['id']) echo "selected"; ?>--> + <?php endforeach; ?> + </select> + </td> + <td> + <p><button type="button" id="take" >&gt;&gt;</button></p> + <p><button type="button" id="drop" >&lt;&lt;</button></p> + </td> + <td> + <select name="id_functions[]" id="dst_countries" style="width:270px" multiple="multiple" size="10" class='select form-control'> + <option disabled selected>Выбраные функции</option> + <?php if($print['functions'] != "Отсутствует"):?> + <?php for($i=0; $i < count($print['functions']); $i++): ?> + <option value="<?php echo $print['functions'][$i]['id']; ?>"><?php echo $print['functions'][$i]['name']; ?></option> + <?php endfor; ?> + <?php endif; ?> + </select> + </td> + </tr> + </table> + <br> + <button type="submit" name="submit" class="btn btn-primary">Save</button> + </form> + </div> + </div> + + + <hr> + <br> +<?php include ROOT . TMPL . 'footer.php'; ?> \ No newline at end of file diff --git a/views/default/addcartrige.php b/views/default/addcartrige.php new file mode 100644 index 0000000..5aad8b2 --- /dev/null +++ b/views/default/addcartrige.php @@ -0,0 +1,86 @@ +<?php include ROOT . TMPL . 'header.php'; ?> +<table class="table table-condensed"> + <thead> + <tr> + <th>id</th> + <th>name</th> + <th>activ</th> + <th>list printers</th> + </tr> + </thead> + <tbody> + <?php for($i=0; $i < count($cartriges); $i++): ?> + <tr> + <td> <?php echo $cartriges[$i]['id']; ?> </td> + <td> <?php echo $cartriges[$i]['name']; ?> </td> + <!--<td> <?php //echo $cartriges[$i]['action']; ?> </td>--> + + <td><a href="<?php DOMEN; ?>/cartriges/add/public/<?php echo $cartriges[$i]['id']; ?>" > <i <?php echo ($cartriges[$i]['action'] == 0) ? 'class="fa fa-times" style="font-size:20px; color:#cc0000 "' : "class='fa fa-check'"; ?>></i></a></td> + + <td><?php if(is_array($cartriges[$i]['print_list'])): ?> + <?php foreach($cartriges[$i]['print_list'] as $prn_lst): ?> + <a href='/printer/<?php echo $prn_lst['id']; ?>'><span class="label <?php echo ($prn_lst['id_status'] == 1) ? "label-default" : "label-danger"; ?>"><?php echo $prn_lst['name']; ?></span></a> + <?php endforeach; ?> + <?php else: ?> + <h4> <?php echo $cartriges[$i]['print_list']; ?></h4> + <?php endif; ?> + </td> + </tr> + <?php endfor; ?> + </tbody> +</table> + </br> + + <hr> + <div class="row"> + <div class="col-md-5"> + <H2>Добавить новый картридж</H2> + <form action="" method="post"> + <table> + <thead><tr> + <th> + Введите имя картриджа + </th> + <th> + Активный + </th> + </tr></thead> + <tr> + <td><input type="text" class="form-control" name="name" placeholder="Name" value=""></td> + <td><input type="checkbox" class="form-control" name="action" value="1" checked></td> + </tr> + <tr> + <td colspan="2"><button type="submit" name="addcartrige" class="btn btn-primary">Добавить</button></td> + </tr> + </table> + </form> + </div> + <div class="col-md-7"> + <H2>Движение картриджей</H2> + <table class="table table-bordered"> + <thead> + <tr> + <th>Номер</th> + <th>Пользователь</th> + <th>Дата</th> + <th>Картридж</th> + <th>Действие</th> + </tr> + </thead> + <tbody> + <?php foreach($cartrridges_history as $cart):?> + <tr> + <td><?php echo $cart['id']; ?></td> + <td><?php echo $cart['user']; ?></td> + <td><?php echo Date::changeLocaleDate(date("d F Y", $cart['date'])); ?></td> + <td><?php echo $cart['name']; ?></td> + <td><?php echo $cart['action']; ?></td> + </tr> + <?php endforeach; ?> + </tbody> + </table> + </div> + </div> + + +<?php include ROOT . TMPL . 'footer.php'; ?> \ No newline at end of file diff --git a/views/default/cartriges.php b/views/default/cartriges.php new file mode 100644 index 0000000..f529f7d --- /dev/null +++ b/views/default/cartriges.php @@ -0,0 +1,29 @@ +<?php include ROOT . TMPL . 'header.php'; ?> + <table class="table table-bordered"> + <caption><h2>Количество картриджей</h2> </caption> + <thead> + <tr> + <?php for($i = 0; $i < count($summ_cart); $i++):?> + <th><?php echo $summ_cart[$i]['name']; ?></th> + <?php endfor;?> + </tr> + </thead> + <tbody> + <tr align="center"> + <?php for($i = 0; $i < count($summ_cart); $i++):?> + <th <?php echo Cartriges::colorRow($summ_cart[$i]['value']); ?>><?php echo $summ_cart[$i]['value']; ?></th> + <?php endfor;?> + </tr> + </tbody> + </table> + +<?php /*if(isset($_POST['submit'])) echo $messages;*/ ?> + <?php if(user::checkAdmin() == true): ?> + <p class="text-center"> + <a href="http://<?php echo DOMEN; ?>/cartriges/action/?act=out" class="btn btn-warning"><i class="fa fa-sign-out" aria-hidden="true"></i> Замена</a> + <a href="http://<?php echo DOMEN; ?>/cartriges/action/?act=in" class="btn btn-success"><i class="fa fa-sign-in" aria-hidden="true"></i> Доставка</a> + <a href="http://<?php echo DOMEN; ?>/cartriges/orders" class="btn btn-inverse"><i class="fa fa-shopping-cart" aria-hidden="true"></i> Заказ</a> + </p> + <?php endif; ?> + </br> +<?php include ROOT . TMPL . 'footer.php'; ?> \ No newline at end of file diff --git a/views/default/cartriges_order.php b/views/default/cartriges_order.php new file mode 100644 index 0000000..87bca5f --- /dev/null +++ b/views/default/cartriges_order.php @@ -0,0 +1,93 @@ +<?php include ROOT . TMPL . 'header.php'; ?> + +<?php if(isset($_POST['submit'])): ?> + <!-- Скрипт, вызывающий модальное окно после загрузки страницы --> + <script> + $(document).ready(function() { + $("#myModalBox").modal('show'); + }); + </script> + +<?php endif; ?> + + <!-- HTML-код модального окна --> +<div id="myModalBox" class="modal fade"> + <div class="modal-dialog"> + <div class="modal-content"> + <!-- Заголовок модального окна --> + <div class="modal-header"> + <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> + <h4 class="modal-title">Заказ сформирован</h4> + </div> + <!-- Основное содержимое модального окна --> + <form action="" method="post"> + <div class="modal-body"> + Нажмите на ссылку для завершения процедуры заказа <?php echo $a;?> + </div> + <!-- Футер модального окна --> + <div class="modal-footer"> + <button type="button" class="btn btn-default" data-dismiss="modal">Закрыть</button> + <input type="hidden" name="data" value='<?php echo $data_ord;?>'> + <button type="submit" class="btn btn-primary" name="save_order">В базу запросов</button> + </div> + </form> + </div> + </div> +</div> + + <table class="table table-bordered"> + <caption><h2>Количество картриджей</h2> </caption> + <thead> + <tr> + <?php for($i = 0; $i < count($summ_cart); $i++):?> + <th><?php echo $summ_cart[$i]['name']; ?></th> + <?php endfor;?> + </tr> + </thead> + <tbody> + <tr align="center"> + <?php for($i = 0; $i < count($summ_cart); $i++):?> + <th <?php echo Cartriges::colorRow($summ_cart[$i]['value']); ?>><?php echo $summ_cart[$i]['value']; ?></th> + <?php endfor;?> + </tr> + </tbody> + </table> +<br /> +<p class="text-center"><h2>Заказ картриджей</h2></p> + + <form action="" method="post"> + <table class="table"> + <thead> + <tr> + <th scope="col">Наименование</th> + <th scope="col">Количество</th> + <th scope="col">&nbsp;</th> + </tr> + </thead> + <tbody id="dynamic"> + <!-- ЭТА СТРОКА БУДЕТ ШАБЛОНОМ ДЛЯ ВНОВЬ СОЗДАВАЕМЫХ //--> + <tr> + <td class="col-xs-3"> + <select class="form-control input-lg" name="cartrige"> + <option selected value="">Выбирете картридж</option> + <?php foreach($cartriges as $cart): ?> + <option value="<?php echo $cart['id']; ?>"><?php echo $cart['name']; ?></option> + <?php endforeach; ?> + </select> + </td> + <td class="col-xs-3"> + <input class="form-control input-lg" type='number' name='quantity' value='' min='0' max='10' step='1' placeholder="Укажите кол-во"/> + </td> + <td class="col-xs-2"> + <button type="button" class="btn btn-primary add">+</button> + <button type="button" class="btn btn-primary del">-</button> + </td> + </tr> + </tbody> + </table> + <!-- конец СТРОКи БУДЕТ ШАБЛОНОМ ДЛЯ ВНОВЬ СОЗДАВАЕМЫХ //--> + <button type="submit" name="submit" class="btn btn-primary">Заказать</button> + </form> + </p> + +<?php include ROOT . TMPL . 'footer.php'; ?> \ No newline at end of file diff --git a/views/default/create_request.php b/views/default/create_request.php new file mode 100644 index 0000000..a2a3c25 --- /dev/null +++ b/views/default/create_request.php @@ -0,0 +1,158 @@ +<?php include ROOT . TMPL . 'header.php'; ?> + +<?php if(isset($_POST['create'])): ?> + <!-- Скрипт, вызывающий модальное окно после загрузки страницы --> + <script> + $(document).ready(function() { + $("#myModalBox").modal('show'); + }); + </script> + +<?php endif; ?> + +<style type="text/css"> +#kcfinder_div { + display: none; + position: absolute; + width: 670px; + height: 400px; + background: #e0dfde; + border: 2px solid #3687e2; + border-radius: 6px; + -moz-border-radius: 6px; + -webkit-border-radius: 6px; + padding: 1px; + z-index: 9999; +} +</style> + +<script type="text/javascript"> +function openKCFinder(field) { + var div = document.getElementById('kcfinder_div'); + if (div.style.display == "block") { + div.style.display = 'none'; + div.innerHTML = ''; + return; + } + window.KCFinder = { + callBack: function(url) { + window.KCFinder = null; + field.value = url; + div.style.display = 'none'; + div.innerHTML = ''; + } + }; + div.innerHTML = '<iframe name="kcfinder_iframe" src="<?php echo LIB ?>/kcfinder/browse.php?type=files&dir=files/public" ' + + 'frameborder="0" width="100%" height="100%" marginwidth="0" marginheight="0" scrolling="no" />'; + div.style.display = 'block'; +} +</script> + + <?php if($message == "ok"): ?> + <!-- Сообщение об успешном выполнения действия --> + <div class="alert alert-success"> + <!-- Кнопка для закрытия сообщения, созданная с помощью элемента button --> + <button type="button" class="close" data-dismiss="alert">×</button> + Запрос зарегистрирован. + </div> + <?php endif; ?> + + <!-- HTML-код модального окна --> +<div id="myModalBox" class="modal fade"> + <div class="modal-dialog"> + <div class="modal-content"> + <!-- Заголовок модального окна --> + <div class="modal-header"> + <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> + <h4 class="modal-title">Запрос сформирован</h4> + </div> + <form action="" method="post"> + <!-- Основное содержимое модального окна --> + <div class="modal-body"> + Нажмите на ссылку для завершения процедуры оформления запроса <?php echo $lnk;?> + </div> + <!-- Футер модального окна --> + <div class="modal-footer"> + <button type="button" class="btn btn-default" data-dismiss="modal">Закрыть</button> + <input type="hidden" name="print_id" value="<?php echo $print_id;?>"> + <input type="hidden" name="user_id" value="<?php echo $user_id;?>"> + <input type="hidden" name="description" value="<?php echo $description;?>"> + <button type="submit" class="btn btn-primary" name="save_request">В базу запросов</button> + </div> + </form> + </div> + </div> +</div> + + +<?php if($error == "access denied"): ?> + <div class="panel panel-danger col-xs-offset-4 col-xs-4"> + <div class="panel-heading"> + <h3 class="panel-title">Error!!!</h3> + </div> + <div class="panel-body"> + Ошибка доступа + </div> + </div> +<?php else: ?> + <div class="row"> + <form action="" method="post" class="form-horizontal"> + + <div class="form-group"> + <label class="control-label col-xs-2" for="username">Заказчик:</label> + <div class="col-xs-9"> + <input type="text" class="form-control" name="username" value="<?php echo $_SESSION['user_id']; ?>"> + </div> + </div> + <div class="form-group"> + <label class="control-label col-xs-2" for="print_id">Аппарат:</label> + <div class="col-xs-5"> + <select class="form-control" name="print_id" id="select_prn" > + <option selected value="0">Выберите принтер</option> + <?php foreach($printers as $print): ?> + <option value="<?php echo $print['id']; ?>"><?php echo $print['name']; ?> <?php echo $print['model']; ?> <?php echo $print['unit']; ?></option> + <?php endforeach; ?> + </select> + </div> + <div class="col-xs-4"> + <input type="text" class="form-control" id="value_prn"> + </div> + + <script type='text/javascript'> + var elems = document.getElementById("select_prn").options; + var similar = function (A, B) { + for (var i = 0; i < B.length; i++) + if (A.charAt(i) != B.charAt(i)) break; + return i; + }; + document.getElementById("value_prn").onkeypress = function (event) { + var max = 0; + for (var i = 0; i < elems.length; i++) { + var A = elems[i].innerHTML.replace(/^\s+|\s+$/g, "").toLowerCase(), + B = (this.value + String.fromCharCode(event.keyCode)).toLowerCase(); + if (similar(A, B) > max) + elems[i].selected = "selected", max = similar(A, B); + } + }; + </script> + + </div> + <div class="form-group"> + <label class="control-label col-xs-2" for="text">Описание:</label> + <div class="col-xs-9"> + <textarea rows="4" class="form-control" name="text"></textarea> + </div> + </div> + + <div class="form-group"> + <div class="col-xs-offset-2 col-xs-2"> + <button type="submit" name="create" class="btn btn-primary">Создать запрос</button> + </div> + </div> + <input class="form-control" name="img" type="text" readonly="readonly" placeholder="Нажмите для выбора\загрузки файла" value="" onclick="openKCFinder(this)" style="cursor:pointer" /> + <div id="kcfinder_div"></div> + + </form> + </div> +<?php endif; ?> +<?php include ROOT . TMPL . 'footer.php'; ?> \ No newline at end of file diff --git a/views/default/css/bootstrap-switch.css b/views/default/css/bootstrap-switch.css new file mode 100644 index 0000000..9e4a7a0 --- /dev/null +++ b/views/default/css/bootstrap-switch.css @@ -0,0 +1,197 @@ +/* +To change this license header, choose License Headers in Project Properties. +To change this template file, choose Tools | Templates +and open the template in the editor. +*/ +/* + Created on : 04.10.2017, 14:48:46 + Author : adm_azashchepkin +*/ +/** + * bootstrap-switch - Turn checkboxes and radio buttons into toggle switches. + * + * @version v3.3.4 + * @homepage https://bttstrp.github.io/bootstrap-switch + * @author Mattia Larentis <mattia@larentis.eu> (http://larentis.eu) + * @license Apache-2.0 + */ + +.bootstrap-switch { + display: inline-block; + direction: ltr; + cursor: pointer; + border-radius: 4px; + border: 1px solid; + border-color: #ccc; + position: relative; + text-align: left; + overflow: hidden; + line-height: 8px; + z-index: 0; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + vertical-align: middle; + -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; + -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; + transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; +} +.bootstrap-switch .bootstrap-switch-container { + display: inline-block; + top: 0; + border-radius: 4px; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); +} +.bootstrap-switch .bootstrap-switch-handle-on, +.bootstrap-switch .bootstrap-switch-handle-off, +.bootstrap-switch .bootstrap-switch-label { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + cursor: pointer; + display: table-cell; + vertical-align: middle; + padding: 6px 12px; + font-size: 14px; + line-height: 20px; +} +.bootstrap-switch .bootstrap-switch-handle-on, +.bootstrap-switch .bootstrap-switch-handle-off { + text-align: center; + z-index: 1; +} +.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-primary, +.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-primary { + color: #fff; + background: #337ab7; +} +.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-info, +.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-info { + color: #fff; + background: #5bc0de; +} +.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-success, +.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-success { + color: #fff; + background: #5cb85c; +} +.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-warning, +.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-warning { + background: #f0ad4e; + color: #fff; +} +.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-danger, +.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-danger { + color: #fff; + background: #d9534f; +} +.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-default, +.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-default { + color: #000; + background: #eeeeee; +} +.bootstrap-switch .bootstrap-switch-label { + text-align: center; + margin-top: -1px; + margin-bottom: -1px; + z-index: 100; + color: #333; + background: #fff; +} +.bootstrap-switch span::before { + content: "\200b"; +} +.bootstrap-switch .bootstrap-switch-handle-on { + border-bottom-left-radius: 3px; + border-top-left-radius: 3px; +} +.bootstrap-switch .bootstrap-switch-handle-off { + border-bottom-right-radius: 3px; + border-top-right-radius: 3px; +} +.bootstrap-switch input[type='radio'], +.bootstrap-switch input[type='checkbox'] { + position: absolute !important; + top: 0; + left: 0; + margin: 0; + z-index: -1; + opacity: 0; + filter: alpha(opacity=0); + visibility: hidden; +} +.bootstrap-switch.bootstrap-switch-mini .bootstrap-switch-handle-on, +.bootstrap-switch.bootstrap-switch-mini .bootstrap-switch-handle-off, +.bootstrap-switch.bootstrap-switch-mini .bootstrap-switch-label { + padding: 1px 5px; + font-size: 12px; + line-height: 1.5; +} +.bootstrap-switch.bootstrap-switch-small .bootstrap-switch-handle-on, +.bootstrap-switch.bootstrap-switch-small .bootstrap-switch-handle-off, +.bootstrap-switch.bootstrap-switch-small .bootstrap-switch-label { + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; +} +.bootstrap-switch.bootstrap-switch-large .bootstrap-switch-handle-on, +.bootstrap-switch.bootstrap-switch-large .bootstrap-switch-handle-off, +.bootstrap-switch.bootstrap-switch-large .bootstrap-switch-label { + padding: 6px 16px; + font-size: 18px; + line-height: 1.3333333; +} +.bootstrap-switch.bootstrap-switch-disabled, +.bootstrap-switch.bootstrap-switch-readonly, +.bootstrap-switch.bootstrap-switch-indeterminate { + cursor: default !important; +} +.bootstrap-switch.bootstrap-switch-disabled .bootstrap-switch-handle-on, +.bootstrap-switch.bootstrap-switch-readonly .bootstrap-switch-handle-on, +.bootstrap-switch.bootstrap-switch-indeterminate .bootstrap-switch-handle-on, +.bootstrap-switch.bootstrap-switch-disabled .bootstrap-switch-handle-off, +.bootstrap-switch.bootstrap-switch-readonly .bootstrap-switch-handle-off, +.bootstrap-switch.bootstrap-switch-indeterminate .bootstrap-switch-handle-off, +.bootstrap-switch.bootstrap-switch-disabled .bootstrap-switch-label, +.bootstrap-switch.bootstrap-switch-readonly .bootstrap-switch-label, +.bootstrap-switch.bootstrap-switch-indeterminate .bootstrap-switch-label { + opacity: 0.5; + filter: alpha(opacity=50); + cursor: default !important; +} +.bootstrap-switch.bootstrap-switch-animate .bootstrap-switch-container { + -webkit-transition: margin-left 0.5s; + -o-transition: margin-left 0.5s; + transition: margin-left 0.5s; +} +.bootstrap-switch.bootstrap-switch-inverse .bootstrap-switch-handle-on { + border-bottom-left-radius: 0; + border-top-left-radius: 0; + border-bottom-right-radius: 3px; + border-top-right-radius: 3px; +} +.bootstrap-switch.bootstrap-switch-inverse .bootstrap-switch-handle-off { + border-bottom-right-radius: 0; + border-top-right-radius: 0; + border-bottom-left-radius: 3px; + border-top-left-radius: 3px; +} +.bootstrap-switch.bootstrap-switch-focused { + border-color: #66afe9; + outline: 0; + -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6); + box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6); +} +.bootstrap-switch.bootstrap-switch-on .bootstrap-switch-label, +.bootstrap-switch.bootstrap-switch-inverse.bootstrap-switch-off .bootstrap-switch-label { + border-bottom-right-radius: 3px; + border-top-right-radius: 3px; +} +.bootstrap-switch.bootstrap-switch-off .bootstrap-switch-label, +.bootstrap-switch.bootstrap-switch-inverse.bootstrap-switch-on .bootstrap-switch-label { + border-bottom-left-radius: 3px; + border-top-left-radius: 3px; +} + diff --git a/views/default/css/bootstrap-theme.css b/views/default/css/bootstrap-theme.css new file mode 100644 index 0000000..bb66349 --- /dev/null +++ b/views/default/css/bootstrap-theme.css @@ -0,0 +1,476 @@ +/*! + * Bootstrap v3.3.2 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ + +.btn-default, +.btn-primary, +.btn-success, +.btn-info, +.btn-warning, +.btn-danger { + text-shadow: 0 -1px 0 rgba(0, 0, 0, .2); + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075); +} +.btn-default:active, +.btn-primary:active, +.btn-success:active, +.btn-info:active, +.btn-warning:active, +.btn-danger:active, +.btn-default.active, +.btn-primary.active, +.btn-success.active, +.btn-info.active, +.btn-warning.active, +.btn-danger.active { + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); +} +.btn-default .badge, +.btn-primary .badge, +.btn-success .badge, +.btn-info .badge, +.btn-warning .badge, +.btn-danger .badge { + text-shadow: none; +} +.btn:active, +.btn.active { + background-image: none; +} +.btn-default { + text-shadow: 0 1px 0 #fff; + background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%); + background-image: -o-linear-gradient(top, #fff 0%, #e0e0e0 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#e0e0e0)); + background-image: linear-gradient(to bottom, #fff 0%, #e0e0e0 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #dbdbdb; + border-color: #ccc; +} +.btn-default:hover, +.btn-default:focus { + background-color: #e0e0e0; + background-position: 0 -15px; +} +.btn-default:active, +.btn-default.active { + background-color: #e0e0e0; + border-color: #dbdbdb; +} +.btn-default.disabled, +.btn-default:disabled, +.btn-default[disabled] { + background-color: #e0e0e0; + background-image: none; +} +.btn-primary { + background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%); + background-image: -o-linear-gradient(top, #337ab7 0%, #265a88 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#265a88)); + background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #245580; +} +.btn-primary:hover, +.btn-primary:focus { + background-color: #265a88; + background-position: 0 -15px; +} +.btn-primary:active, +.btn-primary.active { + background-color: #265a88; + border-color: #245580; +} +.btn-primary.disabled, +.btn-primary:disabled, +.btn-primary[disabled] { + background-color: #265a88; + background-image: none; +} +.btn-success { + background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%); + background-image: -o-linear-gradient(top, #5cb85c 0%, #419641 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#419641)); + background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #3e8f3e; +} +.btn-success:hover, +.btn-success:focus { + background-color: #419641; + background-position: 0 -15px; +} +.btn-success:active, +.btn-success.active { + background-color: #419641; + border-color: #3e8f3e; +} +.btn-success.disabled, +.btn-success:disabled, +.btn-success[disabled] { + background-color: #419641; + background-image: none; +} +.btn-info { + background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%); + background-image: -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#2aabd2)); + background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #28a4c9; +} +.btn-info:hover, +.btn-info:focus { + background-color: #2aabd2; + background-position: 0 -15px; +} +.btn-info:active, +.btn-info.active { + background-color: #2aabd2; + border-color: #28a4c9; +} +.btn-info.disabled, +.btn-info:disabled, +.btn-info[disabled] { + background-color: #2aabd2; + background-image: none; +} +.btn-warning { + background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%); + background-image: -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#eb9316)); + background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #e38d13; +} +.btn-warning:hover, +.btn-warning:focus { + background-color: #eb9316; + background-position: 0 -15px; +} +.btn-warning:active, +.btn-warning.active { + background-color: #eb9316; + border-color: #e38d13; +} +.btn-warning.disabled, +.btn-warning:disabled, +.btn-warning[disabled] { + background-color: #eb9316; + background-image: none; +} +.btn-danger { + background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%); + background-image: -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c12e2a)); + background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #b92c28; +} +.btn-danger:hover, +.btn-danger:focus { + background-color: #c12e2a; + background-position: 0 -15px; +} +.btn-danger:active, +.btn-danger.active { + background-color: #c12e2a; + border-color: #b92c28; +} +.btn-danger.disabled, +.btn-danger:disabled, +.btn-danger[disabled] { + background-color: #c12e2a; + background-image: none; +} +.thumbnail, +.img-thumbnail { + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075); + box-shadow: 0 1px 2px rgba(0, 0, 0, .075); +} +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus { + background-color: #e8e8e8; + background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); + background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8)); + background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0); + background-repeat: repeat-x; +} +.dropdown-menu > .active > a, +.dropdown-menu > .active > a:hover, +.dropdown-menu > .active > a:focus { + background-color: #2e6da4; + background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%); + background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4)); + background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); + background-repeat: repeat-x; +} +.navbar-default { + background-image: -webkit-linear-gradient(top, #fff 0%, #f8f8f8 100%); + background-image: -o-linear-gradient(top, #fff 0%, #f8f8f8 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#f8f8f8)); + background-image: linear-gradient(to bottom, #fff 0%, #f8f8f8 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075); +} +.navbar-default .navbar-nav > .open > a, +.navbar-default .navbar-nav > .active > a { + background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%); + background-image: -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#dbdbdb), to(#e2e2e2)); + background-image: linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0); + background-repeat: repeat-x; + -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075); + box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075); +} +.navbar-brand, +.navbar-nav > li > a { + text-shadow: 0 1px 0 rgba(255, 255, 255, .25); +} +.navbar-inverse { + background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%); + background-image: -o-linear-gradient(top, #3c3c3c 0%, #222 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#3c3c3c), to(#222)); + background-image: linear-gradient(to bottom, #3c3c3c 0%, #222 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; +} +.navbar-inverse .navbar-nav > .open > a, +.navbar-inverse .navbar-nav > .active > a { + background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%); + background-image: -o-linear-gradient(top, #080808 0%, #0f0f0f 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#080808), to(#0f0f0f)); + background-image: linear-gradient(to bottom, #080808 0%, #0f0f0f 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0); + background-repeat: repeat-x; + -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25); + box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25); +} +.navbar-inverse .navbar-brand, +.navbar-inverse .navbar-nav > li > a { + text-shadow: 0 -1px 0 rgba(0, 0, 0, .25); +} +.navbar-static-top, +.navbar-fixed-top, +.navbar-fixed-bottom { + border-radius: 0; +} +@media (max-width: 767px) { + .navbar .navbar-nav .open .dropdown-menu > .active > a, + .navbar .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #fff; + background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%); + background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4)); + background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); + background-repeat: repeat-x; + } +} +.alert { + text-shadow: 0 1px 0 rgba(255, 255, 255, .2); + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05); +} +.alert-success { + background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%); + background-image: -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#c8e5bc)); + background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0); + background-repeat: repeat-x; + border-color: #b2dba1; +} +.alert-info { + background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%); + background-image: -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#b9def0)); + background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0); + background-repeat: repeat-x; + border-color: #9acfea; +} +.alert-warning { + background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%); + background-image: -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#f8efc0)); + background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0); + background-repeat: repeat-x; + border-color: #f5e79e; +} +.alert-danger { + background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%); + background-image: -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#e7c3c3)); + background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0); + background-repeat: repeat-x; + border-color: #dca7a7; +} +.progress { + background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%); + background-image: -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#ebebeb), to(#f5f5f5)); + background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0); + background-repeat: repeat-x; +} +.progress-bar { + background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%); + background-image: -o-linear-gradient(top, #337ab7 0%, #286090 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#286090)); + background-image: linear-gradient(to bottom, #337ab7 0%, #286090 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0); + background-repeat: repeat-x; +} +.progress-bar-success { + background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%); + background-image: -o-linear-gradient(top, #5cb85c 0%, #449d44 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#449d44)); + background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0); + background-repeat: repeat-x; +} +.progress-bar-info { + background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%); + background-image: -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#31b0d5)); + background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0); + background-repeat: repeat-x; +} +.progress-bar-warning { + background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%); + background-image: -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#ec971f)); + background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0); + background-repeat: repeat-x; +} +.progress-bar-danger { + background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%); + background-image: -o-linear-gradient(top, #d9534f 0%, #c9302c 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c9302c)); + background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0); + background-repeat: repeat-x; +} +.progress-bar-striped { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); +} +.list-group { + border-radius: 4px; + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075); + box-shadow: 0 1px 2px rgba(0, 0, 0, .075); +} +.list-group-item.active, +.list-group-item.active:hover, +.list-group-item.active:focus { + text-shadow: 0 -1px 0 #286090; + background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%); + background-image: -o-linear-gradient(top, #337ab7 0%, #2b669a 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2b669a)); + background-image: linear-gradient(to bottom, #337ab7 0%, #2b669a 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0); + background-repeat: repeat-x; + border-color: #2b669a; +} +.list-group-item.active .badge, +.list-group-item.active:hover .badge, +.list-group-item.active:focus .badge { + text-shadow: none; +} +.panel { + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .05); + box-shadow: 0 1px 2px rgba(0, 0, 0, .05); +} +.panel-default > .panel-heading { + background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); + background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8)); + background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0); + background-repeat: repeat-x; +} +.panel-primary > .panel-heading { + background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%); + background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4)); + background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); + background-repeat: repeat-x; +} +.panel-success > .panel-heading { + background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%); + background-image: -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#d0e9c6)); + background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0); + background-repeat: repeat-x; +} +.panel-info > .panel-heading { + background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%); + background-image: -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#c4e3f3)); + background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0); + background-repeat: repeat-x; +} +.panel-warning > .panel-heading { + background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%); + background-image: -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#faf2cc)); + background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0); + background-repeat: repeat-x; +} +.panel-danger > .panel-heading { + background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%); + background-image: -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#ebcccc)); + background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0); + background-repeat: repeat-x; +} +.well { + background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%); + background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#e8e8e8), to(#f5f5f5)); + background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0); + background-repeat: repeat-x; + border-color: #dcdcdc; + -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1); + box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1); +} +/*# sourceMappingURL=bootstrap-theme.css.map */ diff --git a/views/default/css/bootstrap-theme.css.map b/views/default/css/bootstrap-theme.css.map new file mode 100644 index 0000000..5a12d63 --- /dev/null +++ b/views/default/css/bootstrap-theme.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["less/theme.less","less/mixins/vendor-prefixes.less","bootstrap-theme.css","less/mixins/gradients.less","less/mixins/reset-filter.less"],"names":[],"mappings":"AAcA;;;;;;EAME,0CAAA;ECgDA,6FAAA;EACQ,qFAAA;EC5DT;AFgBC;;;;;;;;;;;;EC2CA,0DAAA;EACQ,kDAAA;EC7CT;AFVD;;;;;;EAiBI,mBAAA;EECH;AFiCC;;EAEE,wBAAA;EE/BH;AFoCD;EGnDI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EAEA,wHAAA;ECnBF,qEAAA;EJiCA,6BAAA;EACA,uBAAA;EAgC2C,2BAAA;EAA2B,oBAAA;EEzBvE;AFLC;;EAEE,2BAAA;EACA,8BAAA;EEOH;AFJC;;EAEE,2BAAA;EACA,uBAAA;EEMH;AFHC;;;EAGE,2BAAA;EACA,wBAAA;EEKH;AFUD;EGpDI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EAEA,wHAAA;ECnBF,qEAAA;EJiCA,6BAAA;EACA,uBAAA;EEgCD;AF9BC;;EAEE,2BAAA;EACA,8BAAA;EEgCH;AF7BC;;EAEE,2BAAA;EACA,uBAAA;EE+BH;AF5BC;;;EAGE,2BAAA;EACA,wBAAA;EE8BH;AFdD;EGrDI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EAEA,wHAAA;ECnBF,qEAAA;EJiCA,6BAAA;EACA,uBAAA;EEyDD;AFvDC;;EAEE,2BAAA;EACA,8BAAA;EEyDH;AFtDC;;EAEE,2BAAA;EACA,uBAAA;EEwDH;AFrDC;;;EAGE,2BAAA;EACA,wBAAA;EEuDH;AFtCD;EGtDI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EAEA,wHAAA;ECnBF,qEAAA;EJiCA,6BAAA;EACA,uBAAA;EEkFD;AFhFC;;EAEE,2BAAA;EACA,8BAAA;EEkFH;AF/EC;;EAEE,2BAAA;EACA,uBAAA;EEiFH;AF9EC;;;EAGE,2BAAA;EACA,wBAAA;EEgFH;AF9DD;EGvDI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EAEA,wHAAA;ECnBF,qEAAA;EJiCA,6BAAA;EACA,uBAAA;EE2GD;AFzGC;;EAEE,2BAAA;EACA,8BAAA;EE2GH;AFxGC;;EAEE,2BAAA;EACA,uBAAA;EE0GH;AFvGC;;;EAGE,2BAAA;EACA,wBAAA;EEyGH;AFtFD;EGxDI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EAEA,wHAAA;ECnBF,qEAAA;EJiCA,6BAAA;EACA,uBAAA;EEoID;AFlIC;;EAEE,2BAAA;EACA,8BAAA;EEoIH;AFjIC;;EAEE,2BAAA;EACA,uBAAA;EEmIH;AFhIC;;;EAGE,2BAAA;EACA,wBAAA;EEkIH;AFxGD;;EChBE,oDAAA;EACQ,4CAAA;EC4HT;AFnGD;;EGzEI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EHwEF,2BAAA;EEyGD;AFvGD;;;EG9EI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EH8EF,2BAAA;EE6GD;AFpGD;EG3FI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;ECnBF,qEAAA;EJ6GA,oBAAA;EC/CA,6FAAA;EACQ,qFAAA;EC0JT;AF/GD;;EG3FI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EF2CF,0DAAA;EACQ,kDAAA;ECoKT;AF5GD;;EAEE,gDAAA;EE8GD;AF1GD;EG9GI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;ECnBF,qEAAA;EF+OD;AFlHD;;EG9GI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EF2CF,yDAAA;EACQ,iDAAA;EC0LT;AF5HD;;EAYI,2CAAA;EEoHH;AF/GD;;;EAGE,kBAAA;EEiHD;AF5FD;EAfI;;;IAGE,aAAA;IG3IF,0EAAA;IACA,qEAAA;IACA,+FAAA;IAAA,wEAAA;IACA,6BAAA;IACA,wHAAA;ID0PD;EACF;AFxGD;EACE,+CAAA;ECzGA,4FAAA;EACQ,oFAAA;ECoNT;AFhGD;EGpKI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EH4JF,uBAAA;EE4GD;AFvGD;EGrKI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EH4JF,uBAAA;EEoHD;AF9GD;EGtKI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EH4JF,uBAAA;EE4HD;AFrHD;EGvKI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EH4JF,uBAAA;EEoID;AFrHD;EG/KI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EDuSH;AFlHD;EGzLI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;ED8SH;AFxHD;EG1LI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EDqTH;AF9HD;EG3LI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;ED4TH;AFpID;EG5LI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EDmUH;AF1ID;EG7LI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;ED0UH;AF7ID;EGhKI,+MAAA;EACA,0MAAA;EACA,uMAAA;EDgTH;AFzID;EACE,oBAAA;EC5JA,oDAAA;EACQ,4CAAA;ECwST;AF1ID;;;EAGE,+BAAA;EGjNE,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EH+MF,uBAAA;EEgJD;AFrJD;;;EAQI,mBAAA;EEkJH;AFxID;ECjLE,mDAAA;EACQ,2CAAA;EC4TT;AFlID;EG1OI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;ED+WH;AFxID;EG3OI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EDsXH;AF9ID;EG5OI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;ED6XH;AFpJD;EG7OI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EDoYH;AF1JD;EG9OI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;ED2YH;AFhKD;EG/OI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EDkZH;AFhKD;EGtPI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EHoPF,uBAAA;ECzMA,2FAAA;EACQ,mFAAA;ECgXT","file":"bootstrap-theme.css","sourcesContent":["\n//\n// Load core variables and mixins\n// --------------------------------------------------\n\n@import \"variables.less\";\n@import \"mixins.less\";\n\n\n//\n// Buttons\n// --------------------------------------------------\n\n// Common styles\n.btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n text-shadow: 0 -1px 0 rgba(0,0,0,.2);\n @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 1px rgba(0,0,0,.075);\n .box-shadow(@shadow);\n\n // Reset the shadow\n &:active,\n &.active {\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n }\n\n .badge {\n text-shadow: none;\n }\n}\n\n// Mixin for generating new styles\n.btn-styles(@btn-color: #555) {\n #gradient > .vertical(@start-color: @btn-color; @end-color: darken(@btn-color, 12%));\n .reset-filter(); // Disable gradients for IE9 because filter bleeds through rounded corners; see https://github.com/twbs/bootstrap/issues/10620\n background-repeat: repeat-x;\n border-color: darken(@btn-color, 14%);\n\n &:hover,\n &:focus {\n background-color: darken(@btn-color, 12%);\n background-position: 0 -15px;\n }\n\n &:active,\n &.active {\n background-color: darken(@btn-color, 12%);\n border-color: darken(@btn-color, 14%);\n }\n\n &.disabled,\n &:disabled,\n &[disabled] {\n background-color: darken(@btn-color, 12%);\n background-image: none;\n }\n}\n\n// Common styles\n.btn {\n // Remove the gradient for the pressed/active state\n &:active,\n &.active {\n background-image: none;\n }\n}\n\n// Apply the mixin to the buttons\n.btn-default { .btn-styles(@btn-default-bg); text-shadow: 0 1px 0 #fff; border-color: #ccc; }\n.btn-primary { .btn-styles(@btn-primary-bg); }\n.btn-success { .btn-styles(@btn-success-bg); }\n.btn-info { .btn-styles(@btn-info-bg); }\n.btn-warning { .btn-styles(@btn-warning-bg); }\n.btn-danger { .btn-styles(@btn-danger-bg); }\n\n\n//\n// Images\n// --------------------------------------------------\n\n.thumbnail,\n.img-thumbnail {\n .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n\n\n//\n// Dropdowns\n// --------------------------------------------------\n\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n #gradient > .vertical(@start-color: @dropdown-link-hover-bg; @end-color: darken(@dropdown-link-hover-bg, 5%));\n background-color: darken(@dropdown-link-hover-bg, 5%);\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n background-color: darken(@dropdown-link-active-bg, 5%);\n}\n\n\n//\n// Navbar\n// --------------------------------------------------\n\n// Default navbar\n.navbar-default {\n #gradient > .vertical(@start-color: lighten(@navbar-default-bg, 10%); @end-color: @navbar-default-bg);\n .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered\n border-radius: @navbar-border-radius;\n @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 5px rgba(0,0,0,.075);\n .box-shadow(@shadow);\n\n .navbar-nav > .open > a,\n .navbar-nav > .active > a {\n #gradient > .vertical(@start-color: darken(@navbar-default-link-active-bg, 5%); @end-color: darken(@navbar-default-link-active-bg, 2%));\n .box-shadow(inset 0 3px 9px rgba(0,0,0,.075));\n }\n}\n.navbar-brand,\n.navbar-nav > li > a {\n text-shadow: 0 1px 0 rgba(255,255,255,.25);\n}\n\n// Inverted navbar\n.navbar-inverse {\n #gradient > .vertical(@start-color: lighten(@navbar-inverse-bg, 10%); @end-color: @navbar-inverse-bg);\n .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered; see https://github.com/twbs/bootstrap/issues/10257\n\n .navbar-nav > .open > a,\n .navbar-nav > .active > a {\n #gradient > .vertical(@start-color: @navbar-inverse-link-active-bg; @end-color: lighten(@navbar-inverse-link-active-bg, 2.5%));\n .box-shadow(inset 0 3px 9px rgba(0,0,0,.25));\n }\n\n .navbar-brand,\n .navbar-nav > li > a {\n text-shadow: 0 -1px 0 rgba(0,0,0,.25);\n }\n}\n\n// Undo rounded corners in static and fixed navbars\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n border-radius: 0;\n}\n\n// Fix active state of dropdown items in collapsed mode\n@media (max-width: @grid-float-breakpoint-max) {\n .navbar .navbar-nav .open .dropdown-menu > .active > a {\n &,\n &:hover,\n &:focus {\n color: #fff;\n #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n }\n }\n}\n\n\n//\n// Alerts\n// --------------------------------------------------\n\n// Common styles\n.alert {\n text-shadow: 0 1px 0 rgba(255,255,255,.2);\n @shadow: inset 0 1px 0 rgba(255,255,255,.25), 0 1px 2px rgba(0,0,0,.05);\n .box-shadow(@shadow);\n}\n\n// Mixin for generating new styles\n.alert-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 7.5%));\n border-color: darken(@color, 15%);\n}\n\n// Apply the mixin to the alerts\n.alert-success { .alert-styles(@alert-success-bg); }\n.alert-info { .alert-styles(@alert-info-bg); }\n.alert-warning { .alert-styles(@alert-warning-bg); }\n.alert-danger { .alert-styles(@alert-danger-bg); }\n\n\n//\n// Progress bars\n// --------------------------------------------------\n\n// Give the progress background some depth\n.progress {\n #gradient > .vertical(@start-color: darken(@progress-bg, 4%); @end-color: @progress-bg)\n}\n\n// Mixin for generating new styles\n.progress-bar-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 10%));\n}\n\n// Apply the mixin to the progress bars\n.progress-bar { .progress-bar-styles(@progress-bar-bg); }\n.progress-bar-success { .progress-bar-styles(@progress-bar-success-bg); }\n.progress-bar-info { .progress-bar-styles(@progress-bar-info-bg); }\n.progress-bar-warning { .progress-bar-styles(@progress-bar-warning-bg); }\n.progress-bar-danger { .progress-bar-styles(@progress-bar-danger-bg); }\n\n// Reset the striped class because our mixins don't do multiple gradients and\n// the above custom styles override the new `.progress-bar-striped` in v3.2.0.\n.progress-bar-striped {\n #gradient > .striped();\n}\n\n\n//\n// List groups\n// --------------------------------------------------\n\n.list-group {\n border-radius: @border-radius-base;\n .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n text-shadow: 0 -1px 0 darken(@list-group-active-bg, 10%);\n #gradient > .vertical(@start-color: @list-group-active-bg; @end-color: darken(@list-group-active-bg, 7.5%));\n border-color: darken(@list-group-active-border, 7.5%);\n\n .badge {\n text-shadow: none;\n }\n}\n\n\n//\n// Panels\n// --------------------------------------------------\n\n// Common styles\n.panel {\n .box-shadow(0 1px 2px rgba(0,0,0,.05));\n}\n\n// Mixin for generating new styles\n.panel-heading-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 5%));\n}\n\n// Apply the mixin to the panel headings only\n.panel-default > .panel-heading { .panel-heading-styles(@panel-default-heading-bg); }\n.panel-primary > .panel-heading { .panel-heading-styles(@panel-primary-heading-bg); }\n.panel-success > .panel-heading { .panel-heading-styles(@panel-success-heading-bg); }\n.panel-info > .panel-heading { .panel-heading-styles(@panel-info-heading-bg); }\n.panel-warning > .panel-heading { .panel-heading-styles(@panel-warning-heading-bg); }\n.panel-danger > .panel-heading { .panel-heading-styles(@panel-danger-heading-bg); }\n\n\n//\n// Wells\n// --------------------------------------------------\n\n.well {\n #gradient > .vertical(@start-color: darken(@well-bg, 5%); @end-color: @well-bg);\n border-color: darken(@well-bg, 10%);\n @shadow: inset 0 1px 3px rgba(0,0,0,.05), 0 1px 0 rgba(255,255,255,.1);\n .box-shadow(@shadow);\n}\n","// Vendor Prefixes\n//\n// All vendor mixins are deprecated as of v3.2.0 due to the introduction of\n// Autoprefixer in our Gruntfile. They will be removed in v4.\n\n// - Animations\n// - Backface visibility\n// - Box shadow\n// - Box sizing\n// - Content columns\n// - Hyphens\n// - Placeholder text\n// - Transformations\n// - Transitions\n// - User Select\n\n\n// Animations\n.animation(@animation) {\n -webkit-animation: @animation;\n -o-animation: @animation;\n animation: @animation;\n}\n.animation-name(@name) {\n -webkit-animation-name: @name;\n animation-name: @name;\n}\n.animation-duration(@duration) {\n -webkit-animation-duration: @duration;\n animation-duration: @duration;\n}\n.animation-timing-function(@timing-function) {\n -webkit-animation-timing-function: @timing-function;\n animation-timing-function: @timing-function;\n}\n.animation-delay(@delay) {\n -webkit-animation-delay: @delay;\n animation-delay: @delay;\n}\n.animation-iteration-count(@iteration-count) {\n -webkit-animation-iteration-count: @iteration-count;\n animation-iteration-count: @iteration-count;\n}\n.animation-direction(@direction) {\n -webkit-animation-direction: @direction;\n animation-direction: @direction;\n}\n.animation-fill-mode(@fill-mode) {\n -webkit-animation-fill-mode: @fill-mode;\n animation-fill-mode: @fill-mode;\n}\n\n// Backface visibility\n// Prevent browsers from flickering when using CSS 3D transforms.\n// Default value is `visible`, but can be changed to `hidden`\n\n.backface-visibility(@visibility){\n -webkit-backface-visibility: @visibility;\n -moz-backface-visibility: @visibility;\n backface-visibility: @visibility;\n}\n\n// Drop shadows\n//\n// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's\n// supported browsers that have box shadow capabilities now support it.\n\n.box-shadow(@shadow) {\n -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n box-shadow: @shadow;\n}\n\n// Box sizing\n.box-sizing(@boxmodel) {\n -webkit-box-sizing: @boxmodel;\n -moz-box-sizing: @boxmodel;\n box-sizing: @boxmodel;\n}\n\n// CSS3 Content Columns\n.content-columns(@column-count; @column-gap: @grid-gutter-width) {\n -webkit-column-count: @column-count;\n -moz-column-count: @column-count;\n column-count: @column-count;\n -webkit-column-gap: @column-gap;\n -moz-column-gap: @column-gap;\n column-gap: @column-gap;\n}\n\n// Optional hyphenation\n.hyphens(@mode: auto) {\n word-wrap: break-word;\n -webkit-hyphens: @mode;\n -moz-hyphens: @mode;\n -ms-hyphens: @mode; // IE10+\n -o-hyphens: @mode;\n hyphens: @mode;\n}\n\n// Placeholder text\n.placeholder(@color: @input-color-placeholder) {\n // Firefox\n &::-moz-placeholder {\n color: @color;\n opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526\n }\n &:-ms-input-placeholder { color: @color; } // Internet Explorer 10+\n &::-webkit-input-placeholder { color: @color; } // Safari and Chrome\n}\n\n// Transformations\n.scale(@ratio) {\n -webkit-transform: scale(@ratio);\n -ms-transform: scale(@ratio); // IE9 only\n -o-transform: scale(@ratio);\n transform: scale(@ratio);\n}\n.scale(@ratioX; @ratioY) {\n -webkit-transform: scale(@ratioX, @ratioY);\n -ms-transform: scale(@ratioX, @ratioY); // IE9 only\n -o-transform: scale(@ratioX, @ratioY);\n transform: scale(@ratioX, @ratioY);\n}\n.scaleX(@ratio) {\n -webkit-transform: scaleX(@ratio);\n -ms-transform: scaleX(@ratio); // IE9 only\n -o-transform: scaleX(@ratio);\n transform: scaleX(@ratio);\n}\n.scaleY(@ratio) {\n -webkit-transform: scaleY(@ratio);\n -ms-transform: scaleY(@ratio); // IE9 only\n -o-transform: scaleY(@ratio);\n transform: scaleY(@ratio);\n}\n.skew(@x; @y) {\n -webkit-transform: skewX(@x) skewY(@y);\n -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+\n -o-transform: skewX(@x) skewY(@y);\n transform: skewX(@x) skewY(@y);\n}\n.translate(@x; @y) {\n -webkit-transform: translate(@x, @y);\n -ms-transform: translate(@x, @y); // IE9 only\n -o-transform: translate(@x, @y);\n transform: translate(@x, @y);\n}\n.translate3d(@x; @y; @z) {\n -webkit-transform: translate3d(@x, @y, @z);\n transform: translate3d(@x, @y, @z);\n}\n.rotate(@degrees) {\n -webkit-transform: rotate(@degrees);\n -ms-transform: rotate(@degrees); // IE9 only\n -o-transform: rotate(@degrees);\n transform: rotate(@degrees);\n}\n.rotateX(@degrees) {\n -webkit-transform: rotateX(@degrees);\n -ms-transform: rotateX(@degrees); // IE9 only\n -o-transform: rotateX(@degrees);\n transform: rotateX(@degrees);\n}\n.rotateY(@degrees) {\n -webkit-transform: rotateY(@degrees);\n -ms-transform: rotateY(@degrees); // IE9 only\n -o-transform: rotateY(@degrees);\n transform: rotateY(@degrees);\n}\n.perspective(@perspective) {\n -webkit-perspective: @perspective;\n -moz-perspective: @perspective;\n perspective: @perspective;\n}\n.perspective-origin(@perspective) {\n -webkit-perspective-origin: @perspective;\n -moz-perspective-origin: @perspective;\n perspective-origin: @perspective;\n}\n.transform-origin(@origin) {\n -webkit-transform-origin: @origin;\n -moz-transform-origin: @origin;\n -ms-transform-origin: @origin; // IE9 only\n transform-origin: @origin;\n}\n\n\n// Transitions\n\n.transition(@transition) {\n -webkit-transition: @transition;\n -o-transition: @transition;\n transition: @transition;\n}\n.transition-property(@transition-property) {\n -webkit-transition-property: @transition-property;\n transition-property: @transition-property;\n}\n.transition-delay(@transition-delay) {\n -webkit-transition-delay: @transition-delay;\n transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n -webkit-transition-duration: @transition-duration;\n transition-duration: @transition-duration;\n}\n.transition-timing-function(@timing-function) {\n -webkit-transition-timing-function: @timing-function;\n transition-timing-function: @timing-function;\n}\n.transition-transform(@transition) {\n -webkit-transition: -webkit-transform @transition;\n -moz-transition: -moz-transform @transition;\n -o-transition: -o-transform @transition;\n transition: transform @transition;\n}\n\n\n// User select\n// For selecting text on the page\n\n.user-select(@select) {\n -webkit-user-select: @select;\n -moz-user-select: @select;\n -ms-user-select: @select; // IE10+\n user-select: @select;\n}\n",".btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2);\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.btn-default:active,\n.btn-primary:active,\n.btn-success:active,\n.btn-info:active,\n.btn-warning:active,\n.btn-danger:active,\n.btn-default.active,\n.btn-primary.active,\n.btn-success.active,\n.btn-info.active,\n.btn-warning.active,\n.btn-danger.active {\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn-default .badge,\n.btn-primary .badge,\n.btn-success .badge,\n.btn-info .badge,\n.btn-warning .badge,\n.btn-danger .badge {\n text-shadow: none;\n}\n.btn:active,\n.btn.active {\n background-image: none;\n}\n.btn-default {\n background-image: -webkit-linear-gradient(top, #ffffff 0%, #e0e0e0 100%);\n background-image: -o-linear-gradient(top, #ffffff 0%, #e0e0e0 100%);\n background-image: linear-gradient(to bottom, #ffffff 0%, #e0e0e0 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #dbdbdb;\n text-shadow: 0 1px 0 #fff;\n border-color: #ccc;\n}\n.btn-default:hover,\n.btn-default:focus {\n background-color: #e0e0e0;\n background-position: 0 -15px;\n}\n.btn-default:active,\n.btn-default.active {\n background-color: #e0e0e0;\n border-color: #dbdbdb;\n}\n.btn-default.disabled,\n.btn-default:disabled,\n.btn-default[disabled] {\n background-color: #e0e0e0;\n background-image: none;\n}\n.btn-primary {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #265a88 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #245580;\n}\n.btn-primary:hover,\n.btn-primary:focus {\n background-color: #265a88;\n background-position: 0 -15px;\n}\n.btn-primary:active,\n.btn-primary.active {\n background-color: #265a88;\n border-color: #245580;\n}\n.btn-primary.disabled,\n.btn-primary:disabled,\n.btn-primary[disabled] {\n background-color: #265a88;\n background-image: none;\n}\n.btn-success {\n background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%);\n background-image: -o-linear-gradient(top, #5cb85c 0%, #419641 100%);\n background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #3e8f3e;\n}\n.btn-success:hover,\n.btn-success:focus {\n background-color: #419641;\n background-position: 0 -15px;\n}\n.btn-success:active,\n.btn-success.active {\n background-color: #419641;\n border-color: #3e8f3e;\n}\n.btn-success.disabled,\n.btn-success:disabled,\n.btn-success[disabled] {\n background-color: #419641;\n background-image: none;\n}\n.btn-info {\n background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);\n background-image: -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);\n background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #28a4c9;\n}\n.btn-info:hover,\n.btn-info:focus {\n background-color: #2aabd2;\n background-position: 0 -15px;\n}\n.btn-info:active,\n.btn-info.active {\n background-color: #2aabd2;\n border-color: #28a4c9;\n}\n.btn-info.disabled,\n.btn-info:disabled,\n.btn-info[disabled] {\n background-color: #2aabd2;\n background-image: none;\n}\n.btn-warning {\n background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);\n background-image: -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);\n background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #e38d13;\n}\n.btn-warning:hover,\n.btn-warning:focus {\n background-color: #eb9316;\n background-position: 0 -15px;\n}\n.btn-warning:active,\n.btn-warning.active {\n background-color: #eb9316;\n border-color: #e38d13;\n}\n.btn-warning.disabled,\n.btn-warning:disabled,\n.btn-warning[disabled] {\n background-color: #eb9316;\n background-image: none;\n}\n.btn-danger {\n background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%);\n background-image: -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%);\n background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #b92c28;\n}\n.btn-danger:hover,\n.btn-danger:focus {\n background-color: #c12e2a;\n background-position: 0 -15px;\n}\n.btn-danger:active,\n.btn-danger.active {\n background-color: #c12e2a;\n border-color: #b92c28;\n}\n.btn-danger.disabled,\n.btn-danger:disabled,\n.btn-danger[disabled] {\n background-color: #c12e2a;\n background-image: none;\n}\n.thumbnail,\n.img-thumbnail {\n -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);\n background-color: #e8e8e8;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n background-color: #2e6da4;\n}\n.navbar-default {\n background-image: -webkit-linear-gradient(top, #ffffff 0%, #f8f8f8 100%);\n background-image: -o-linear-gradient(top, #ffffff 0%, #f8f8f8 100%);\n background-image: linear-gradient(to bottom, #ffffff 0%, #f8f8f8 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .active > a {\n background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);\n background-image: -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);\n background-image: linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);\n -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);\n}\n.navbar-brand,\n.navbar-nav > li > a {\n text-shadow: 0 1px 0 rgba(255, 255, 255, 0.25);\n}\n.navbar-inverse {\n background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222222 100%);\n background-image: -o-linear-gradient(top, #3c3c3c 0%, #222222 100%);\n background-image: linear-gradient(to bottom, #3c3c3c 0%, #222222 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .active > a {\n background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%);\n background-image: -o-linear-gradient(top, #080808 0%, #0f0f0f 100%);\n background-image: linear-gradient(to bottom, #080808 0%, #0f0f0f 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);\n -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);\n box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);\n}\n.navbar-inverse .navbar-brand,\n.navbar-inverse .navbar-nav > li > a {\n text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n border-radius: 0;\n}\n@media (max-width: 767px) {\n .navbar .navbar-nav .open .dropdown-menu > .active > a,\n .navbar .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #fff;\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n }\n}\n.alert {\n text-shadow: 0 1px 0 rgba(255, 255, 255, 0.2);\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n.alert-success {\n background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);\n background-image: -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);\n background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);\n border-color: #b2dba1;\n}\n.alert-info {\n background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%);\n background-image: -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%);\n background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);\n border-color: #9acfea;\n}\n.alert-warning {\n background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);\n background-image: -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);\n background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);\n border-color: #f5e79e;\n}\n.alert-danger {\n background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);\n background-image: -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);\n background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);\n border-color: #dca7a7;\n}\n.progress {\n background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);\n background-image: -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);\n background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);\n}\n.progress-bar {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #286090 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #286090 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);\n}\n.progress-bar-success {\n background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%);\n background-image: -o-linear-gradient(top, #5cb85c 0%, #449d44 100%);\n background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);\n}\n.progress-bar-info {\n background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);\n background-image: -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);\n background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);\n}\n.progress-bar-warning {\n background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);\n background-image: -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);\n background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);\n}\n.progress-bar-danger {\n background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%);\n background-image: -o-linear-gradient(top, #d9534f 0%, #c9302c 100%);\n background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);\n}\n.progress-bar-striped {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.list-group {\n border-radius: 4px;\n -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n text-shadow: 0 -1px 0 #286090;\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2b669a 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2b669a 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);\n border-color: #2b669a;\n}\n.list-group-item.active .badge,\n.list-group-item.active:hover .badge,\n.list-group-item.active:focus .badge {\n text-shadow: none;\n}\n.panel {\n -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n.panel-default > .panel-heading {\n background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);\n}\n.panel-primary > .panel-heading {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n}\n.panel-success > .panel-heading {\n background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);\n background-image: -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);\n background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);\n}\n.panel-info > .panel-heading {\n background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);\n background-image: -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);\n background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);\n}\n.panel-warning > .panel-heading {\n background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);\n background-image: -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);\n background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);\n}\n.panel-danger > .panel-heading {\n background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%);\n background-image: -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%);\n background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);\n}\n.well {\n background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);\n background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);\n background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);\n border-color: #dcdcdc;\n -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);\n box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);\n}\n/*# sourceMappingURL=bootstrap-theme.css.map */","// Gradients\n\n#gradient {\n\n // Horizontal gradient, from left to right\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n // Vertical gradient, from top to bottom\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n .directional(@start-color: #555; @end-color: #333; @deg: 45deg) {\n background-repeat: repeat-x;\n background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(@deg, @start-color, @end-color); // Opera 12\n background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n }\n .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .radial(@inner-color: #555; @outer-color: #333) {\n background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);\n background-image: radial-gradient(circle, @inner-color, @outer-color);\n background-repeat: no-repeat;\n }\n .striped(@color: rgba(255,255,255,.15); @angle: 45deg) {\n background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n }\n}\n","// Reset filters for IE\n//\n// When you need to remove a gradient background, do not forget to use this to reset\n// the IE filter for IE9 and below.\n\n.reset-filter() {\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\"));\n}\n"]} \ No newline at end of file diff --git a/views/default/css/bootstrap-theme.min.css b/views/default/css/bootstrap-theme.min.css new file mode 100644 index 0000000..ac8dd55 --- /dev/null +++ b/views/default/css/bootstrap-theme.min.css @@ -0,0 +1,5 @@ +/*! + * Bootstrap v3.3.2 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */.btn-danger,.btn-default,.btn-info,.btn-primary,.btn-success,.btn-warning{text-shadow:0 -1px 0 rgba(0,0,0,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075)}.btn-danger.active,.btn-danger:active,.btn-default.active,.btn-default:active,.btn-info.active,.btn-info:active,.btn-primary.active,.btn-primary:active,.btn-success.active,.btn-success:active,.btn-warning.active,.btn-warning:active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-danger .badge,.btn-default .badge,.btn-info .badge,.btn-primary .badge,.btn-success .badge,.btn-warning .badge{text-shadow:none}.btn.active,.btn:active{background-image:none}.btn-default{text-shadow:0 1px 0 #fff;background-image:-webkit-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-o-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e0e0e0));background-image:linear-gradient(to bottom,#fff 0,#e0e0e0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#dbdbdb;border-color:#ccc}.btn-default:focus,.btn-default:hover{background-color:#e0e0e0;background-position:0 -15px}.btn-default.active,.btn-default:active{background-color:#e0e0e0;border-color:#dbdbdb}.btn-default.disabled,.btn-default:disabled,.btn-default[disabled]{background-color:#e0e0e0;background-image:none}.btn-primary{background-image:-webkit-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-o-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#265a88));background-image:linear-gradient(to bottom,#337ab7 0,#265a88 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#245580}.btn-primary:focus,.btn-primary:hover{background-color:#265a88;background-position:0 -15px}.btn-primary.active,.btn-primary:active{background-color:#265a88;border-color:#245580}.btn-primary.disabled,.btn-primary:disabled,.btn-primary[disabled]{background-color:#265a88;background-image:none}.btn-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#419641));background-image:linear-gradient(to bottom,#5cb85c 0,#419641 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#3e8f3e}.btn-success:focus,.btn-success:hover{background-color:#419641;background-position:0 -15px}.btn-success.active,.btn-success:active{background-color:#419641;border-color:#3e8f3e}.btn-success.disabled,.btn-success:disabled,.btn-success[disabled]{background-color:#419641;background-image:none}.btn-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#2aabd2));background-image:linear-gradient(to bottom,#5bc0de 0,#2aabd2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#28a4c9}.btn-info:focus,.btn-info:hover{background-color:#2aabd2;background-position:0 -15px}.btn-info.active,.btn-info:active{background-color:#2aabd2;border-color:#28a4c9}.btn-info.disabled,.btn-info:disabled,.btn-info[disabled]{background-color:#2aabd2;background-image:none}.btn-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#eb9316));background-image:linear-gradient(to bottom,#f0ad4e 0,#eb9316 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#e38d13}.btn-warning:focus,.btn-warning:hover{background-color:#eb9316;background-position:0 -15px}.btn-warning.active,.btn-warning:active{background-color:#eb9316;border-color:#e38d13}.btn-warning.disabled,.btn-warning:disabled,.btn-warning[disabled]{background-color:#eb9316;background-image:none}.btn-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c12e2a));background-image:linear-gradient(to bottom,#d9534f 0,#c12e2a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#b92c28}.btn-danger:focus,.btn-danger:hover{background-color:#c12e2a;background-position:0 -15px}.btn-danger.active,.btn-danger:active{background-color:#c12e2a;border-color:#b92c28}.btn-danger.disabled,.btn-danger:disabled,.btn-danger[disabled]{background-color:#c12e2a;background-image:none}.img-thumbnail,.thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{background-color:#e8e8e8;background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{background-color:#2e6da4;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.navbar-default{background-image:-webkit-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-o-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#f8f8f8));background-image:linear-gradient(to bottom,#fff 0,#f8f8f8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075)}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-o-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dbdbdb),to(#e2e2e2));background-image:linear-gradient(to bottom,#dbdbdb 0,#e2e2e2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.075);box-shadow:inset 0 3px 9px rgba(0,0,0,.075)}.navbar-brand,.navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,.25)}.navbar-inverse{background-image:-webkit-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-o-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#3c3c3c),to(#222));background-image:linear-gradient(to bottom,#3c3c3c 0,#222 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-o-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#080808),to(#0f0f0f));background-image:linear-gradient(to bottom,#080808 0,#0f0f0f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.25);box-shadow:inset 0 3px 9px rgba(0,0,0,.25)}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,.25)}.navbar-fixed-bottom,.navbar-fixed-top,.navbar-static-top{border-radius:0}@media (max-width:767px){.navbar .navbar-nav .open .dropdown-menu>.active>a,.navbar .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}}.alert{text-shadow:0 1px 0 rgba(255,255,255,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05)}.alert-success{background-image:-webkit-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#c8e5bc));background-image:linear-gradient(to bottom,#dff0d8 0,#c8e5bc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);background-repeat:repeat-x;border-color:#b2dba1}.alert-info{background-image:-webkit-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#b9def0));background-image:linear-gradient(to bottom,#d9edf7 0,#b9def0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);background-repeat:repeat-x;border-color:#9acfea}.alert-warning{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#f8efc0));background-image:linear-gradient(to bottom,#fcf8e3 0,#f8efc0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);background-repeat:repeat-x;border-color:#f5e79e}.alert-danger{background-image:-webkit-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-o-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#e7c3c3));background-image:linear-gradient(to bottom,#f2dede 0,#e7c3c3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);background-repeat:repeat-x;border-color:#dca7a7}.progress{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#f5f5f5));background-image:linear-gradient(to bottom,#ebebeb 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x}.progress-bar{background-image:-webkit-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-o-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#286090));background-image:linear-gradient(to bottom,#337ab7 0,#286090 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);background-repeat:repeat-x}.progress-bar-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#449d44));background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);background-repeat:repeat-x}.progress-bar-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#31b0d5));background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);background-repeat:repeat-x}.progress-bar-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#ec971f));background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);background-repeat:repeat-x}.progress-bar-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c9302c));background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);background-repeat:repeat-x}.progress-bar-striped{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{text-shadow:0 -1px 0 #286090;background-image:-webkit-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2b669a));background-image:linear-gradient(to bottom,#337ab7 0,#2b669a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);background-repeat:repeat-x;border-color:#2b669a}.list-group-item.active .badge,.list-group-item.active:focus .badge,.list-group-item.active:hover .badge{text-shadow:none}.panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.05);box-shadow:0 1px 2px rgba(0,0,0,.05)}.panel-default>.panel-heading{background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.panel-primary>.panel-heading{background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.panel-success>.panel-heading{background-image:-webkit-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#d0e9c6));background-image:linear-gradient(to bottom,#dff0d8 0,#d0e9c6 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);background-repeat:repeat-x}.panel-info>.panel-heading{background-image:-webkit-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#c4e3f3));background-image:linear-gradient(to bottom,#d9edf7 0,#c4e3f3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);background-repeat:repeat-x}.panel-warning>.panel-heading{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#faf2cc));background-image:linear-gradient(to bottom,#fcf8e3 0,#faf2cc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);background-repeat:repeat-x}.panel-danger>.panel-heading{background-image:-webkit-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-o-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#ebcccc));background-image:linear-gradient(to bottom,#f2dede 0,#ebcccc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);background-repeat:repeat-x}.well{background-image:-webkit-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#e8e8e8),to(#f5f5f5));background-image:linear-gradient(to bottom,#e8e8e8 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x;border-color:#dcdcdc;-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1)} \ No newline at end of file diff --git a/views/default/css/bootstrap.css b/views/default/css/bootstrap.css new file mode 100644 index 0000000..c46af7d --- /dev/null +++ b/views/default/css/bootstrap.css @@ -0,0 +1,6566 @@ +/*! + * Bootstrap v3.3.2 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ + +/*! normalize.css v3.0.2 | MIT License | git.io/normalize */ +html { + font-family: sans-serif; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; +} +body { + margin: 0; +} +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +menu, +nav, +section, +summary { + display: block; +} +audio, +canvas, +progress, +video { + display: inline-block; + vertical-align: baseline; +} +audio:not([controls]) { + display: none; + height: 0; +} +[hidden], +template { + display: none; +} +a { + background-color: transparent; +} +a:active, +a:hover { + outline: 0; +} +abbr[title] { + border-bottom: 1px dotted; +} +b, +strong { + font-weight: bold; +} +dfn { + font-style: italic; +} +h1 { + margin: .67em 0; + font-size: 2em; +} +mark { + color: #000; + background: #ff0; +} +small { + font-size: 80%; +} +sub, +sup { + position: relative; + font-size: 75%; + line-height: 0; + vertical-align: baseline; +} +sup { + top: -.5em; +} +sub { + bottom: -.25em; +} +img { + border: 0; +} +svg:not(:root) { + overflow: hidden; +} +figure { + margin: 1em 40px; +} +hr { + height: 0; + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; +} +pre { + overflow: auto; +} +code, +kbd, +pre, +samp { + font-family: monospace, monospace; + font-size: 1em; +} +button, +input, +optgroup, +select, +textarea { + margin: 0; + font: inherit; + color: inherit; +} +button { + overflow: visible; +} +button, +select { + text-transform: none; +} +button, +html input[type="button"], +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; + cursor: pointer; +} +button[disabled], +html input[disabled] { + cursor: default; +} +button::-moz-focus-inner, +input::-moz-focus-inner { + padding: 0; + border: 0; +} +input { + line-height: normal; +} +input[type="checkbox"], +input[type="radio"] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 0; +} +input[type="number"]::-webkit-inner-spin-button, +input[type="number"]::-webkit-outer-spin-button { + height: auto; +} +input[type="search"] { + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + -webkit-appearance: textfield; +} +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} +fieldset { + padding: .35em .625em .75em; + margin: 0 2px; + border: 1px solid #c0c0c0; +} +legend { + padding: 0; + border: 0; +} +textarea { + overflow: auto; +} +optgroup { + font-weight: bold; +} +table { + border-spacing: 0; + border-collapse: collapse; +} +td, +th { + padding: 0; +} +/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */ +@media print { + *, + *:before, + *:after { + color: #000 !important; + text-shadow: none !important; + background: transparent !important; + -webkit-box-shadow: none !important; + box-shadow: none !important; + } + a, + a:visited { + text-decoration: underline; + } + a[href]:after { + content: " (" attr(href) ")"; + } + abbr[title]:after { + content: " (" attr(title) ")"; + } + a[href^="#"]:after, + a[href^="javascript:"]:after { + content: ""; + } + pre, + blockquote { + border: 1px solid #999; + + page-break-inside: avoid; + } + thead { + display: table-header-group; + } + tr, + img { + page-break-inside: avoid; + } + img { + max-width: 100% !important; + } + p, + h2, + h3 { + orphans: 3; + widows: 3; + } + h2, + h3 { + page-break-after: avoid; + } + select { + background: #fff !important; + } + .navbar { + display: none; + } + .btn > .caret, + .dropup > .btn > .caret { + border-top-color: #000 !important; + } + .label { + border: 1px solid #000; + } + .table { + border-collapse: collapse !important; + } + .table td, + .table th { + background-color: #fff !important; + } + .table-bordered th, + .table-bordered td { + border: 1px solid #ddd !important; + } +} +@font-face { + font-family: 'Glyphicons Halflings'; + + src: url('../fonts/glyphicons-halflings-regular.eot'); + src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg'); +} +.glyphicon { + position: relative; + top: 1px; + display: inline-block; + font-family: 'Glyphicons Halflings'; + font-style: normal; + font-weight: normal; + line-height: 1; + + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +.glyphicon-asterisk:before { + content: "\2a"; +} +.glyphicon-plus:before { + content: "\2b"; +} +.glyphicon-euro:before, +.glyphicon-eur:before { + content: "\20ac"; +} +.glyphicon-minus:before { + content: "\2212"; +} +.glyphicon-cloud:before { + content: "\2601"; +} +.glyphicon-envelope:before { + content: "\2709"; +} +.glyphicon-pencil:before { + content: "\270f"; +} +.glyphicon-glass:before { + content: "\e001"; +} +.glyphicon-music:before { + content: "\e002"; +} +.glyphicon-search:before { + content: "\e003"; +} +.glyphicon-heart:before { + content: "\e005"; +} +.glyphicon-star:before { + content: "\e006"; +} +.glyphicon-star-empty:before { + content: "\e007"; +} +.glyphicon-user:before { + content: "\e008"; +} +.glyphicon-film:before { + content: "\e009"; +} +.glyphicon-th-large:before { + content: "\e010"; +} +.glyphicon-th:before { + content: "\e011"; +} +.glyphicon-th-list:before { + content: "\e012"; +} +.glyphicon-ok:before { + content: "\e013"; +} +.glyphicon-remove:before { + content: "\e014"; +} +.glyphicon-zoom-in:before { + content: "\e015"; +} +.glyphicon-zoom-out:before { + content: "\e016"; +} +.glyphicon-off:before { + content: "\e017"; +} +.glyphicon-signal:before { + content: "\e018"; +} +.glyphicon-cog:before { + content: "\e019"; +} +.glyphicon-trash:before { + content: "\e020"; +} +.glyphicon-home:before { + content: "\e021"; +} +.glyphicon-file:before { + content: "\e022"; +} +.glyphicon-time:before { + content: "\e023"; +} +.glyphicon-road:before { + content: "\e024"; +} +.glyphicon-download-alt:before { + content: "\e025"; +} +.glyphicon-download:before { + content: "\e026"; +} +.glyphicon-upload:before { + content: "\e027"; +} +.glyphicon-inbox:before { + content: "\e028"; +} +.glyphicon-play-circle:before { + content: "\e029"; +} +.glyphicon-repeat:before { + content: "\e030"; +} +.glyphicon-refresh:before { + content: "\e031"; +} +.glyphicon-list-alt:before { + content: "\e032"; +} +.glyphicon-lock:before { + content: "\e033"; +} +.glyphicon-flag:before { + content: "\e034"; +} +.glyphicon-headphones:before { + content: "\e035"; +} +.glyphicon-volume-off:before { + content: "\e036"; +} +.glyphicon-volume-down:before { + content: "\e037"; +} +.glyphicon-volume-up:before { + content: "\e038"; +} +.glyphicon-qrcode:before { + content: "\e039"; +} +.glyphicon-barcode:before { + content: "\e040"; +} +.glyphicon-tag:before { + content: "\e041"; +} +.glyphicon-tags:before { + content: "\e042"; +} +.glyphicon-book:before { + content: "\e043"; +} +.glyphicon-bookmark:before { + content: "\e044"; +} +.glyphicon-print:before { + content: "\e045"; +} +.glyphicon-camera:before { + content: "\e046"; +} +.glyphicon-font:before { + content: "\e047"; +} +.glyphicon-bold:before { + content: "\e048"; +} +.glyphicon-italic:before { + content: "\e049"; +} +.glyphicon-text-height:before { + content: "\e050"; +} +.glyphicon-text-width:before { + content: "\e051"; +} +.glyphicon-align-left:before { + content: "\e052"; +} +.glyphicon-align-center:before { + content: "\e053"; +} +.glyphicon-align-right:before { + content: "\e054"; +} +.glyphicon-align-justify:before { + content: "\e055"; +} +.glyphicon-list:before { + content: "\e056"; +} +.glyphicon-indent-left:before { + content: "\e057"; +} +.glyphicon-indent-right:before { + content: "\e058"; +} +.glyphicon-facetime-video:before { + content: "\e059"; +} +.glyphicon-picture:before { + content: "\e060"; +} +.glyphicon-map-marker:before { + content: "\e062"; +} +.glyphicon-adjust:before { + content: "\e063"; +} +.glyphicon-tint:before { + content: "\e064"; +} +.glyphicon-edit:before { + content: "\e065"; +} +.glyphicon-share:before { + content: "\e066"; +} +.glyphicon-check:before { + content: "\e067"; +} +.glyphicon-move:before { + content: "\e068"; +} +.glyphicon-step-backward:before { + content: "\e069"; +} +.glyphicon-fast-backward:before { + content: "\e070"; +} +.glyphicon-backward:before { + content: "\e071"; +} +.glyphicon-play:before { + content: "\e072"; +} +.glyphicon-pause:before { + content: "\e073"; +} +.glyphicon-stop:before { + content: "\e074"; +} +.glyphicon-forward:before { + content: "\e075"; +} +.glyphicon-fast-forward:before { + content: "\e076"; +} +.glyphicon-step-forward:before { + content: "\e077"; +} +.glyphicon-eject:before { + content: "\e078"; +} +.glyphicon-chevron-left:before { + content: "\e079"; +} +.glyphicon-chevron-right:before { + content: "\e080"; +} +.glyphicon-plus-sign:before { + content: "\e081"; +} +.glyphicon-minus-sign:before { + content: "\e082"; +} +.glyphicon-remove-sign:before { + content: "\e083"; +} +.glyphicon-ok-sign:before { + content: "\e084"; +} +.glyphicon-question-sign:before { + content: "\e085"; +} +.glyphicon-info-sign:before { + content: "\e086"; +} +.glyphicon-screenshot:before { + content: "\e087"; +} +.glyphicon-remove-circle:before { + content: "\e088"; +} +.glyphicon-ok-circle:before { + content: "\e089"; +} +.glyphicon-ban-circle:before { + content: "\e090"; +} +.glyphicon-arrow-left:before { + content: "\e091"; +} +.glyphicon-arrow-right:before { + content: "\e092"; +} +.glyphicon-arrow-up:before { + content: "\e093"; +} +.glyphicon-arrow-down:before { + content: "\e094"; +} +.glyphicon-share-alt:before { + content: "\e095"; +} +.glyphicon-resize-full:before { + content: "\e096"; +} +.glyphicon-resize-small:before { + content: "\e097"; +} +.glyphicon-exclamation-sign:before { + content: "\e101"; +} +.glyphicon-gift:before { + content: "\e102"; +} +.glyphicon-leaf:before { + content: "\e103"; +} +.glyphicon-fire:before { + content: "\e104"; +} +.glyphicon-eye-open:before { + content: "\e105"; +} +.glyphicon-eye-close:before { + content: "\e106"; +} +.glyphicon-warning-sign:before { + content: "\e107"; +} +.glyphicon-plane:before { + content: "\e108"; +} +.glyphicon-calendar:before { + content: "\e109"; +} +.glyphicon-random:before { + content: "\e110"; +} +.glyphicon-comment:before { + content: "\e111"; +} +.glyphicon-magnet:before { + content: "\e112"; +} +.glyphicon-chevron-up:before { + content: "\e113"; +} +.glyphicon-chevron-down:before { + content: "\e114"; +} +.glyphicon-retweet:before { + content: "\e115"; +} +.glyphicon-shopping-cart:before { + content: "\e116"; +} +.glyphicon-folder-close:before { + content: "\e117"; +} +.glyphicon-folder-open:before { + content: "\e118"; +} +.glyphicon-resize-vertical:before { + content: "\e119"; +} +.glyphicon-resize-horizontal:before { + content: "\e120"; +} +.glyphicon-hdd:before { + content: "\e121"; +} +.glyphicon-bullhorn:before { + content: "\e122"; +} +.glyphicon-bell:before { + content: "\e123"; +} +.glyphicon-certificate:before { + content: "\e124"; +} +.glyphicon-thumbs-up:before { + content: "\e125"; +} +.glyphicon-thumbs-down:before { + content: "\e126"; +} +.glyphicon-hand-right:before { + content: "\e127"; +} +.glyphicon-hand-left:before { + content: "\e128"; +} +.glyphicon-hand-up:before { + content: "\e129"; +} +.glyphicon-hand-down:before { + content: "\e130"; +} +.glyphicon-circle-arrow-right:before { + content: "\e131"; +} +.glyphicon-circle-arrow-left:before { + content: "\e132"; +} +.glyphicon-circle-arrow-up:before { + content: "\e133"; +} +.glyphicon-circle-arrow-down:before { + content: "\e134"; +} +.glyphicon-globe:before { + content: "\e135"; +} +.glyphicon-wrench:before { + content: "\e136"; +} +.glyphicon-tasks:before { + content: "\e137"; +} +.glyphicon-filter:before { + content: "\e138"; +} +.glyphicon-briefcase:before { + content: "\e139"; +} +.glyphicon-fullscreen:before { + content: "\e140"; +} +.glyphicon-dashboard:before { + content: "\e141"; +} +.glyphicon-paperclip:before { + content: "\e142"; +} +.glyphicon-heart-empty:before { + content: "\e143"; +} +.glyphicon-link:before { + content: "\e144"; +} +.glyphicon-phone:before { + content: "\e145"; +} +.glyphicon-pushpin:before { + content: "\e146"; +} +.glyphicon-usd:before { + content: "\e148"; +} +.glyphicon-gbp:before { + content: "\e149"; +} +.glyphicon-sort:before { + content: "\e150"; +} +.glyphicon-sort-by-alphabet:before { + content: "\e151"; +} +.glyphicon-sort-by-alphabet-alt:before { + content: "\e152"; +} +.glyphicon-sort-by-order:before { + content: "\e153"; +} +.glyphicon-sort-by-order-alt:before { + content: "\e154"; +} +.glyphicon-sort-by-attributes:before { + content: "\e155"; +} +.glyphicon-sort-by-attributes-alt:before { + content: "\e156"; +} +.glyphicon-unchecked:before { + content: "\e157"; +} +.glyphicon-expand:before { + content: "\e158"; +} +.glyphicon-collapse-down:before { + content: "\e159"; +} +.glyphicon-collapse-up:before { + content: "\e160"; +} +.glyphicon-log-in:before { + content: "\e161"; +} +.glyphicon-flash:before { + content: "\e162"; +} +.glyphicon-log-out:before { + content: "\e163"; +} +.glyphicon-new-window:before { + content: "\e164"; +} +.glyphicon-record:before { + content: "\e165"; +} +.glyphicon-save:before { + content: "\e166"; +} +.glyphicon-open:before { + content: "\e167"; +} +.glyphicon-saved:before { + content: "\e168"; +} +.glyphicon-import:before { + content: "\e169"; +} +.glyphicon-export:before { + content: "\e170"; +} +.glyphicon-send:before { + content: "\e171"; +} +.glyphicon-floppy-disk:before { + content: "\e172"; +} +.glyphicon-floppy-saved:before { + content: "\e173"; +} +.glyphicon-floppy-remove:before { + content: "\e174"; +} +.glyphicon-floppy-save:before { + content: "\e175"; +} +.glyphicon-floppy-open:before { + content: "\e176"; +} +.glyphicon-credit-card:before { + content: "\e177"; +} +.glyphicon-transfer:before { + content: "\e178"; +} +.glyphicon-cutlery:before { + content: "\e179"; +} +.glyphicon-header:before { + content: "\e180"; +} +.glyphicon-compressed:before { + content: "\e181"; +} +.glyphicon-earphone:before { + content: "\e182"; +} +.glyphicon-phone-alt:before { + content: "\e183"; +} +.glyphicon-tower:before { + content: "\e184"; +} +.glyphicon-stats:before { + content: "\e185"; +} +.glyphicon-sd-video:before { + content: "\e186"; +} +.glyphicon-hd-video:before { + content: "\e187"; +} +.glyphicon-subtitles:before { + content: "\e188"; +} +.glyphicon-sound-stereo:before { + content: "\e189"; +} +.glyphicon-sound-dolby:before { + content: "\e190"; +} +.glyphicon-sound-5-1:before { + content: "\e191"; +} +.glyphicon-sound-6-1:before { + content: "\e192"; +} +.glyphicon-sound-7-1:before { + content: "\e193"; +} +.glyphicon-copyright-mark:before { + content: "\e194"; +} +.glyphicon-registration-mark:before { + content: "\e195"; +} +.glyphicon-cloud-download:before { + content: "\e197"; +} +.glyphicon-cloud-upload:before { + content: "\e198"; +} +.glyphicon-tree-conifer:before { + content: "\e199"; +} +.glyphicon-tree-deciduous:before { + content: "\e200"; +} +.glyphicon-cd:before { + content: "\e201"; +} +.glyphicon-save-file:before { + content: "\e202"; +} +.glyphicon-open-file:before { + content: "\e203"; +} +.glyphicon-level-up:before { + content: "\e204"; +} +.glyphicon-copy:before { + content: "\e205"; +} +.glyphicon-paste:before { + content: "\e206"; +} +.glyphicon-alert:before { + content: "\e209"; +} +.glyphicon-equalizer:before { + content: "\e210"; +} +.glyphicon-king:before { + content: "\e211"; +} +.glyphicon-queen:before { + content: "\e212"; +} +.glyphicon-pawn:before { + content: "\e213"; +} +.glyphicon-bishop:before { + content: "\e214"; +} +.glyphicon-knight:before { + content: "\e215"; +} +.glyphicon-baby-formula:before { + content: "\e216"; +} +.glyphicon-tent:before { + content: "\26fa"; +} +.glyphicon-blackboard:before { + content: "\e218"; +} +.glyphicon-bed:before { + content: "\e219"; +} +.glyphicon-apple:before { + content: "\f8ff"; +} +.glyphicon-erase:before { + content: "\e221"; +} +.glyphicon-hourglass:before { + content: "\231b"; +} +.glyphicon-lamp:before { + content: "\e223"; +} +.glyphicon-duplicate:before { + content: "\e224"; +} +.glyphicon-piggy-bank:before { + content: "\e225"; +} +.glyphicon-scissors:before { + content: "\e226"; +} +.glyphicon-bitcoin:before { + content: "\e227"; +} +.glyphicon-yen:before { + content: "\00a5"; +} +.glyphicon-ruble:before { + content: "\20bd"; +} +.glyphicon-scale:before { + content: "\e230"; +} +.glyphicon-ice-lolly:before { + content: "\e231"; +} +.glyphicon-ice-lolly-tasted:before { + content: "\e232"; +} +.glyphicon-education:before { + content: "\e233"; +} +.glyphicon-option-horizontal:before { + content: "\e234"; +} +.glyphicon-option-vertical:before { + content: "\e235"; +} +.glyphicon-menu-hamburger:before { + content: "\e236"; +} +.glyphicon-modal-window:before { + content: "\e237"; +} +.glyphicon-oil:before { + content: "\e238"; +} +.glyphicon-grain:before { + content: "\e239"; +} +.glyphicon-sunglasses:before { + content: "\e240"; +} +.glyphicon-text-size:before { + content: "\e241"; +} +.glyphicon-text-color:before { + content: "\e242"; +} +.glyphicon-text-background:before { + content: "\e243"; +} +.glyphicon-object-align-top:before { + content: "\e244"; +} +.glyphicon-object-align-bottom:before { + content: "\e245"; +} +.glyphicon-object-align-horizontal:before { + content: "\e246"; +} +.glyphicon-object-align-left:before { + content: "\e247"; +} +.glyphicon-object-align-vertical:before { + content: "\e248"; +} +.glyphicon-object-align-right:before { + content: "\e249"; +} +.glyphicon-triangle-right:before { + content: "\e250"; +} +.glyphicon-triangle-left:before { + content: "\e251"; +} +.glyphicon-triangle-bottom:before { + content: "\e252"; +} +.glyphicon-triangle-top:before { + content: "\e253"; +} +.glyphicon-console:before { + content: "\e254"; +} +.glyphicon-superscript:before { + content: "\e255"; +} +.glyphicon-subscript:before { + content: "\e256"; +} +.glyphicon-menu-left:before { + content: "\e257"; +} +.glyphicon-menu-right:before { + content: "\e258"; +} +.glyphicon-menu-down:before { + content: "\e259"; +} +.glyphicon-menu-up:before { + content: "\e260"; +} +* { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +*:before, +*:after { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +html { + font-size: 10px; + + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); +} +body { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + line-height: 1.42857143; + color: #333; + background-color: #fff; +} +input, +button, +select, +textarea { + font-family: inherit; + font-size: inherit; + line-height: inherit; +} +a { + color: #337ab7; + text-decoration: none; +} +a:hover, +a:focus { + color: #23527c; + text-decoration: underline; +} +a:focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +figure { + margin: 0; +} +img { + vertical-align: middle; +} +.img-responsive, +.thumbnail > img, +.thumbnail a > img, +.carousel-inner > .item > img, +.carousel-inner > .item > a > img { + display: block; + max-width: 100%; + height: auto; +} +.img-rounded { + border-radius: 6px; +} +.img-thumbnail { + display: inline-block; + max-width: 100%; + height: auto; + padding: 4px; + line-height: 1.42857143; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 4px; + -webkit-transition: all .2s ease-in-out; + -o-transition: all .2s ease-in-out; + transition: all .2s ease-in-out; +} +.img-circle { + border-radius: 50%; +} +hr { + margin-top: 20px; + margin-bottom: 20px; + border: 0; + border-top: 1px solid #eee; +} +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; +} +.sr-only-focusable:active, +.sr-only-focusable:focus { + position: static; + width: auto; + height: auto; + margin: 0; + overflow: visible; + clip: auto; +} +h1, +h2, +h3, +h4, +h5, +h6, +.h1, +.h2, +.h3, +.h4, +.h5, +.h6 { + font-family: inherit; + font-weight: 500; + line-height: 1.1; + color: inherit; +} +h1 small, +h2 small, +h3 small, +h4 small, +h5 small, +h6 small, +.h1 small, +.h2 small, +.h3 small, +.h4 small, +.h5 small, +.h6 small, +h1 .small, +h2 .small, +h3 .small, +h4 .small, +h5 .small, +h6 .small, +.h1 .small, +.h2 .small, +.h3 .small, +.h4 .small, +.h5 .small, +.h6 .small { + font-weight: normal; + line-height: 1; + color: #777; +} +h1, +.h1, +h2, +.h2, +h3, +.h3 { + margin-top: 20px; + margin-bottom: 10px; +} +h1 small, +.h1 small, +h2 small, +.h2 small, +h3 small, +.h3 small, +h1 .small, +.h1 .small, +h2 .small, +.h2 .small, +h3 .small, +.h3 .small { + font-size: 65%; +} +h4, +.h4, +h5, +.h5, +h6, +.h6 { + margin-top: 10px; + margin-bottom: 10px; +} +h4 small, +.h4 small, +h5 small, +.h5 small, +h6 small, +.h6 small, +h4 .small, +.h4 .small, +h5 .small, +.h5 .small, +h6 .small, +.h6 .small { + font-size: 75%; +} +h1, +.h1 { + font-size: 36px; +} +h2, +.h2 { + font-size: 30px; +} +h3, +.h3 { + font-size: 24px; +} +h4, +.h4 { + font-size: 18px; +} +h5, +.h5 { + font-size: 14px; +} +h6, +.h6 { + font-size: 12px; +} +p { + margin: 0 0 10px; +} +.lead { + margin-bottom: 20px; + font-size: 16px; + font-weight: 300; + line-height: 1.4; +} +@media (min-width: 768px) { + .lead { + font-size: 21px; + } +} +small, +.small { + font-size: 85%; +} +mark, +.mark { + padding: .2em; + background-color: #fcf8e3; +} +.text-left { + text-align: left; +} +.text-right { + text-align: right; +} +.text-center { + text-align: center; +} +.text-justify { + text-align: justify; +} +.text-nowrap { + white-space: nowrap; +} +.text-lowercase { + text-transform: lowercase; +} +.text-uppercase { + text-transform: uppercase; +} +.text-capitalize { + text-transform: capitalize; +} +.text-muted { + color: #777; +} +.text-primary { + color: #337ab7; +} +a.text-primary:hover { + color: #286090; +} +.text-success { + color: #3c763d; +} +a.text-success:hover { + color: #2b542c; +} +.text-info { + color: #31708f; +} +a.text-info:hover { + color: #245269; +} +.text-warning { + color: #8a6d3b; +} +a.text-warning:hover { + color: #66512c; +} +.text-danger { + color: #a94442; +} +a.text-danger:hover { + color: #843534; +} +.bg-primary { + color: #fff; + background-color: #337ab7; +} +a.bg-primary:hover { + background-color: #286090; +} +.bg-success { + background-color: #dff0d8; +} +a.bg-success:hover { + background-color: #c1e2b3; +} +.bg-info { + background-color: #d9edf7; +} +a.bg-info:hover { + background-color: #afd9ee; +} +.bg-warning { + background-color: #fcf8e3; +} +a.bg-warning:hover { + background-color: #f7ecb5; +} +.bg-danger { + background-color: #f2dede; +} +a.bg-danger:hover { + background-color: #e4b9b9; +} +.page-header { + padding-bottom: 9px; + margin: 40px 0 20px; + border-bottom: 1px solid #eee; +} +ul, +ol { + margin-top: 0; + margin-bottom: 10px; +} +ul ul, +ol ul, +ul ol, +ol ol { + margin-bottom: 0; +} +.list-unstyled { + padding-left: 0; + list-style: none; +} +.list-inline { + padding-left: 0; + margin-left: -5px; + list-style: none; +} +.list-inline > li { + display: inline-block; + padding-right: 5px; + padding-left: 5px; +} +dl { + margin-top: 0; + margin-bottom: 20px; +} +dt, +dd { + line-height: 1.42857143; +} +dt { + font-weight: bold; +} +dd { + margin-left: 0; +} +@media (min-width: 768px) { + .dl-horizontal dt { + float: left; + width: 160px; + overflow: hidden; + clear: left; + text-align: right; + text-overflow: ellipsis; + white-space: nowrap; + } + .dl-horizontal dd { + margin-left: 180px; + } +} +abbr[title], +abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #777; +} +.initialism { + font-size: 90%; + text-transform: uppercase; +} +blockquote { + padding: 10px 20px; + margin: 0 0 20px; + font-size: 17.5px; + border-left: 5px solid #eee; +} +blockquote p:last-child, +blockquote ul:last-child, +blockquote ol:last-child { + margin-bottom: 0; +} +blockquote footer, +blockquote small, +blockquote .small { + display: block; + font-size: 80%; + line-height: 1.42857143; + color: #777; +} +blockquote footer:before, +blockquote small:before, +blockquote .small:before { + content: '\2014 \00A0'; +} +.blockquote-reverse, +blockquote.pull-right { + padding-right: 15px; + padding-left: 0; + text-align: right; + border-right: 5px solid #eee; + border-left: 0; +} +.blockquote-reverse footer:before, +blockquote.pull-right footer:before, +.blockquote-reverse small:before, +blockquote.pull-right small:before, +.blockquote-reverse .small:before, +blockquote.pull-right .small:before { + content: ''; +} +.blockquote-reverse footer:after, +blockquote.pull-right footer:after, +.blockquote-reverse small:after, +blockquote.pull-right small:after, +.blockquote-reverse .small:after, +blockquote.pull-right .small:after { + content: '\00A0 \2014'; +} +address { + margin-bottom: 20px; + font-style: normal; + line-height: 1.42857143; +} +code, +kbd, +pre, +samp { + font-family: Menlo, Monaco, Consolas, "Courier New", monospace; +} +code { + padding: 2px 4px; + font-size: 90%; + color: #c7254e; + background-color: #f9f2f4; + border-radius: 4px; +} +kbd { + padding: 2px 4px; + font-size: 90%; + color: #fff; + background-color: #333; + border-radius: 3px; + -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25); +} +kbd kbd { + padding: 0; + font-size: 100%; + font-weight: bold; + -webkit-box-shadow: none; + box-shadow: none; +} +pre { + display: block; + padding: 9.5px; + margin: 0 0 10px; + font-size: 13px; + line-height: 1.42857143; + color: #333; + word-break: break-all; + word-wrap: break-word; + background-color: #f5f5f5; + border: 1px solid #ccc; + border-radius: 4px; +} +pre code { + padding: 0; + font-size: inherit; + color: inherit; + white-space: pre-wrap; + background-color: transparent; + border-radius: 0; +} +.pre-scrollable { + max-height: 340px; + overflow-y: scroll; +} +.container { + padding-right: 15px; + padding-left: 15px; + margin-right: auto; + margin-left: auto; +} +@media (min-width: 768px) { + .container { + width: 750px; + } +} +@media (min-width: 992px) { + .container { + width: 970px; + } +} +@media (min-width: 1200px) { + .container { + width: 1170px; + } +} +.container-fluid { + padding-right: 15px; + padding-left: 15px; + margin-right: auto; + margin-left: auto; +} +.row { + margin-right: -15px; + margin-left: -15px; +} +.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 { + position: relative; + min-height: 1px; + padding-right: 15px; + padding-left: 15px; +} +.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 { + float: left; +} +.col-xs-12 { + width: 100%; +} +.col-xs-11 { + width: 91.66666667%; +} +.col-xs-10 { + width: 83.33333333%; +} +.col-xs-9 { + width: 75%; +} +.col-xs-8 { + width: 66.66666667%; +} +.col-xs-7 { + width: 58.33333333%; +} +.col-xs-6 { + width: 50%; +} +.col-xs-5 { + width: 41.66666667%; +} +.col-xs-4 { + width: 33.33333333%; +} +.col-xs-3 { + width: 25%; +} +.col-xs-2 { + width: 16.66666667%; +} +.col-xs-1 { + width: 8.33333333%; +} +.col-xs-pull-12 { + right: 100%; +} +.col-xs-pull-11 { + right: 91.66666667%; +} +.col-xs-pull-10 { + right: 83.33333333%; +} +.col-xs-pull-9 { + right: 75%; +} +.col-xs-pull-8 { + right: 66.66666667%; +} +.col-xs-pull-7 { + right: 58.33333333%; +} +.col-xs-pull-6 { + right: 50%; +} +.col-xs-pull-5 { + right: 41.66666667%; +} +.col-xs-pull-4 { + right: 33.33333333%; +} +.col-xs-pull-3 { + right: 25%; +} +.col-xs-pull-2 { + right: 16.66666667%; +} +.col-xs-pull-1 { + right: 8.33333333%; +} +.col-xs-pull-0 { + right: auto; +} +.col-xs-push-12 { + left: 100%; +} +.col-xs-push-11 { + left: 91.66666667%; +} +.col-xs-push-10 { + left: 83.33333333%; +} +.col-xs-push-9 { + left: 75%; +} +.col-xs-push-8 { + left: 66.66666667%; +} +.col-xs-push-7 { + left: 58.33333333%; +} +.col-xs-push-6 { + left: 50%; +} +.col-xs-push-5 { + left: 41.66666667%; +} +.col-xs-push-4 { + left: 33.33333333%; +} +.col-xs-push-3 { + left: 25%; +} +.col-xs-push-2 { + left: 16.66666667%; +} +.col-xs-push-1 { + left: 8.33333333%; +} +.col-xs-push-0 { + left: auto; +} +.col-xs-offset-12 { + margin-left: 100%; +} +.col-xs-offset-11 { + margin-left: 91.66666667%; +} +.col-xs-offset-10 { + margin-left: 83.33333333%; +} +.col-xs-offset-9 { + margin-left: 75%; +} +.col-xs-offset-8 { + margin-left: 66.66666667%; +} +.col-xs-offset-7 { + margin-left: 58.33333333%; +} +.col-xs-offset-6 { + margin-left: 50%; +} +.col-xs-offset-5 { + margin-left: 41.66666667%; +} +.col-xs-offset-4 { + margin-left: 33.33333333%; +} +.col-xs-offset-3 { + margin-left: 25%; +} +.col-xs-offset-2 { + margin-left: 16.66666667%; +} +.col-xs-offset-1 { + margin-left: 8.33333333%; +} +.col-xs-offset-0 { + margin-left: 0; +} +@media (min-width: 768px) { + .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 { + float: left; + } + .col-sm-12 { + width: 100%; + } + .col-sm-11 { + width: 91.66666667%; + } + .col-sm-10 { + width: 83.33333333%; + } + .col-sm-9 { + width: 75%; + } + .col-sm-8 { + width: 66.66666667%; + } + .col-sm-7 { + width: 58.33333333%; + } + .col-sm-6 { + width: 50%; + } + .col-sm-5 { + width: 41.66666667%; + } + .col-sm-4 { + width: 33.33333333%; + } + .col-sm-3 { + width: 25%; + } + .col-sm-2 { + width: 16.66666667%; + } + .col-sm-1 { + width: 8.33333333%; + } + .col-sm-pull-12 { + right: 100%; + } + .col-sm-pull-11 { + right: 91.66666667%; + } + .col-sm-pull-10 { + right: 83.33333333%; + } + .col-sm-pull-9 { + right: 75%; + } + .col-sm-pull-8 { + right: 66.66666667%; + } + .col-sm-pull-7 { + right: 58.33333333%; + } + .col-sm-pull-6 { + right: 50%; + } + .col-sm-pull-5 { + right: 41.66666667%; + } + .col-sm-pull-4 { + right: 33.33333333%; + } + .col-sm-pull-3 { + right: 25%; + } + .col-sm-pull-2 { + right: 16.66666667%; + } + .col-sm-pull-1 { + right: 8.33333333%; + } + .col-sm-pull-0 { + right: auto; + } + .col-sm-push-12 { + left: 100%; + } + .col-sm-push-11 { + left: 91.66666667%; + } + .col-sm-push-10 { + left: 83.33333333%; + } + .col-sm-push-9 { + left: 75%; + } + .col-sm-push-8 { + left: 66.66666667%; + } + .col-sm-push-7 { + left: 58.33333333%; + } + .col-sm-push-6 { + left: 50%; + } + .col-sm-push-5 { + left: 41.66666667%; + } + .col-sm-push-4 { + left: 33.33333333%; + } + .col-sm-push-3 { + left: 25%; + } + .col-sm-push-2 { + left: 16.66666667%; + } + .col-sm-push-1 { + left: 8.33333333%; + } + .col-sm-push-0 { + left: auto; + } + .col-sm-offset-12 { + margin-left: 100%; + } + .col-sm-offset-11 { + margin-left: 91.66666667%; + } + .col-sm-offset-10 { + margin-left: 83.33333333%; + } + .col-sm-offset-9 { + margin-left: 75%; + } + .col-sm-offset-8 { + margin-left: 66.66666667%; + } + .col-sm-offset-7 { + margin-left: 58.33333333%; + } + .col-sm-offset-6 { + margin-left: 50%; + } + .col-sm-offset-5 { + margin-left: 41.66666667%; + } + .col-sm-offset-4 { + margin-left: 33.33333333%; + } + .col-sm-offset-3 { + margin-left: 25%; + } + .col-sm-offset-2 { + margin-left: 16.66666667%; + } + .col-sm-offset-1 { + margin-left: 8.33333333%; + } + .col-sm-offset-0 { + margin-left: 0; + } +} +@media (min-width: 992px) { + .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 { + float: left; + } + .col-md-12 { + width: 100%; + } + .col-md-11 { + width: 91.66666667%; + } + .col-md-10 { + width: 83.33333333%; + } + .col-md-9 { + width: 75%; + } + .col-md-8 { + width: 66.66666667%; + } + .col-md-7 { + width: 58.33333333%; + } + .col-md-6 { + width: 50%; + } + .col-md-5 { + width: 41.66666667%; + } + .col-md-4 { + width: 33.33333333%; + } + .col-md-3 { + width: 25%; + } + .col-md-2 { + width: 16.66666667%; + } + .col-md-1 { + width: 8.33333333%; + } + .col-md-pull-12 { + right: 100%; + } + .col-md-pull-11 { + right: 91.66666667%; + } + .col-md-pull-10 { + right: 83.33333333%; + } + .col-md-pull-9 { + right: 75%; + } + .col-md-pull-8 { + right: 66.66666667%; + } + .col-md-pull-7 { + right: 58.33333333%; + } + .col-md-pull-6 { + right: 50%; + } + .col-md-pull-5 { + right: 41.66666667%; + } + .col-md-pull-4 { + right: 33.33333333%; + } + .col-md-pull-3 { + right: 25%; + } + .col-md-pull-2 { + right: 16.66666667%; + } + .col-md-pull-1 { + right: 8.33333333%; + } + .col-md-pull-0 { + right: auto; + } + .col-md-push-12 { + left: 100%; + } + .col-md-push-11 { + left: 91.66666667%; + } + .col-md-push-10 { + left: 83.33333333%; + } + .col-md-push-9 { + left: 75%; + } + .col-md-push-8 { + left: 66.66666667%; + } + .col-md-push-7 { + left: 58.33333333%; + } + .col-md-push-6 { + left: 50%; + } + .col-md-push-5 { + left: 41.66666667%; + } + .col-md-push-4 { + left: 33.33333333%; + } + .col-md-push-3 { + left: 25%; + } + .col-md-push-2 { + left: 16.66666667%; + } + .col-md-push-1 { + left: 8.33333333%; + } + .col-md-push-0 { + left: auto; + } + .col-md-offset-12 { + margin-left: 100%; + } + .col-md-offset-11 { + margin-left: 91.66666667%; + } + .col-md-offset-10 { + margin-left: 83.33333333%; + } + .col-md-offset-9 { + margin-left: 75%; + } + .col-md-offset-8 { + margin-left: 66.66666667%; + } + .col-md-offset-7 { + margin-left: 58.33333333%; + } + .col-md-offset-6 { + margin-left: 50%; + } + .col-md-offset-5 { + margin-left: 41.66666667%; + } + .col-md-offset-4 { + margin-left: 33.33333333%; + } + .col-md-offset-3 { + margin-left: 25%; + } + .col-md-offset-2 { + margin-left: 16.66666667%; + } + .col-md-offset-1 { + margin-left: 8.33333333%; + } + .col-md-offset-0 { + margin-left: 0; + } +} +@media (min-width: 1200px) { + .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 { + float: left; + } + .col-lg-12 { + width: 100%; + } + .col-lg-11 { + width: 91.66666667%; + } + .col-lg-10 { + width: 83.33333333%; + } + .col-lg-9 { + width: 75%; + } + .col-lg-8 { + width: 66.66666667%; + } + .col-lg-7 { + width: 58.33333333%; + } + .col-lg-6 { + width: 50%; + } + .col-lg-5 { + width: 41.66666667%; + } + .col-lg-4 { + width: 33.33333333%; + } + .col-lg-3 { + width: 25%; + } + .col-lg-2 { + width: 16.66666667%; + } + .col-lg-1 { + width: 8.33333333%; + } + .col-lg-pull-12 { + right: 100%; + } + .col-lg-pull-11 { + right: 91.66666667%; + } + .col-lg-pull-10 { + right: 83.33333333%; + } + .col-lg-pull-9 { + right: 75%; + } + .col-lg-pull-8 { + right: 66.66666667%; + } + .col-lg-pull-7 { + right: 58.33333333%; + } + .col-lg-pull-6 { + right: 50%; + } + .col-lg-pull-5 { + right: 41.66666667%; + } + .col-lg-pull-4 { + right: 33.33333333%; + } + .col-lg-pull-3 { + right: 25%; + } + .col-lg-pull-2 { + right: 16.66666667%; + } + .col-lg-pull-1 { + right: 8.33333333%; + } + .col-lg-pull-0 { + right: auto; + } + .col-lg-push-12 { + left: 100%; + } + .col-lg-push-11 { + left: 91.66666667%; + } + .col-lg-push-10 { + left: 83.33333333%; + } + .col-lg-push-9 { + left: 75%; + } + .col-lg-push-8 { + left: 66.66666667%; + } + .col-lg-push-7 { + left: 58.33333333%; + } + .col-lg-push-6 { + left: 50%; + } + .col-lg-push-5 { + left: 41.66666667%; + } + .col-lg-push-4 { + left: 33.33333333%; + } + .col-lg-push-3 { + left: 25%; + } + .col-lg-push-2 { + left: 16.66666667%; + } + .col-lg-push-1 { + left: 8.33333333%; + } + .col-lg-push-0 { + left: auto; + } + .col-lg-offset-12 { + margin-left: 100%; + } + .col-lg-offset-11 { + margin-left: 91.66666667%; + } + .col-lg-offset-10 { + margin-left: 83.33333333%; + } + .col-lg-offset-9 { + margin-left: 75%; + } + .col-lg-offset-8 { + margin-left: 66.66666667%; + } + .col-lg-offset-7 { + margin-left: 58.33333333%; + } + .col-lg-offset-6 { + margin-left: 50%; + } + .col-lg-offset-5 { + margin-left: 41.66666667%; + } + .col-lg-offset-4 { + margin-left: 33.33333333%; + } + .col-lg-offset-3 { + margin-left: 25%; + } + .col-lg-offset-2 { + margin-left: 16.66666667%; + } + .col-lg-offset-1 { + margin-left: 8.33333333%; + } + .col-lg-offset-0 { + margin-left: 0; + } +} +table { + background-color: transparent; +} +caption { + padding-top: 8px; + padding-bottom: 8px; + color: #777; + text-align: left; +} +th { + text-align: left; +} +.table { + width: 100%; + max-width: 100%; + margin-bottom: 20px; +} +.table > thead > tr > th, +.table > tbody > tr > th, +.table > tfoot > tr > th, +.table > thead > tr > td, +.table > tbody > tr > td, +.table > tfoot > tr > td { + padding: 8px; + line-height: 1.42857143; + vertical-align: top; + border-top: 1px solid #ddd; +} +.table > thead > tr > th { + vertical-align: bottom; + border-bottom: 2px solid #ddd; +} +.table > caption + thead > tr:first-child > th, +.table > colgroup + thead > tr:first-child > th, +.table > thead:first-child > tr:first-child > th, +.table > caption + thead > tr:first-child > td, +.table > colgroup + thead > tr:first-child > td, +.table > thead:first-child > tr:first-child > td { + border-top: 0; +} +.table > tbody + tbody { + border-top: 2px solid #ddd; +} +.table .table { + background-color: #fff; +} +.table-condensed > thead > tr > th, +.table-condensed > tbody > tr > th, +.table-condensed > tfoot > tr > th, +.table-condensed > thead > tr > td, +.table-condensed > tbody > tr > td, +.table-condensed > tfoot > tr > td { + padding: 5px; +} +.table-bordered { + border: 1px solid #ddd; +} +.table-bordered > thead > tr > th, +.table-bordered > tbody > tr > th, +.table-bordered > tfoot > tr > th, +.table-bordered > thead > tr > td, +.table-bordered > tbody > tr > td, +.table-bordered > tfoot > tr > td { + border: 1px solid #ddd; +} +.table-bordered > thead > tr > th, +.table-bordered > thead > tr > td { + border-bottom-width: 2px; +} +.table-striped > tbody > tr:nth-of-type(odd) { + background-color: #f9f9f9; +} +.table-hover > tbody > tr:hover { + background-color: #f5f5f5; +} +table col[class*="col-"] { + position: static; + display: table-column; + float: none; +} +table td[class*="col-"], +table th[class*="col-"] { + position: static; + display: table-cell; + float: none; +} +.table > thead > tr > td.active, +.table > tbody > tr > td.active, +.table > tfoot > tr > td.active, +.table > thead > tr > th.active, +.table > tbody > tr > th.active, +.table > tfoot > tr > th.active, +.table > thead > tr.active > td, +.table > tbody > tr.active > td, +.table > tfoot > tr.active > td, +.table > thead > tr.active > th, +.table > tbody > tr.active > th, +.table > tfoot > tr.active > th { + background-color: #f5f5f5; +} +.table-hover > tbody > tr > td.active:hover, +.table-hover > tbody > tr > th.active:hover, +.table-hover > tbody > tr.active:hover > td, +.table-hover > tbody > tr:hover > .active, +.table-hover > tbody > tr.active:hover > th { + background-color: #e8e8e8; +} +.table > thead > tr > td.success, +.table > tbody > tr > td.success, +.table > tfoot > tr > td.success, +.table > thead > tr > th.success, +.table > tbody > tr > th.success, +.table > tfoot > tr > th.success, +.table > thead > tr.success > td, +.table > tbody > tr.success > td, +.table > tfoot > tr.success > td, +.table > thead > tr.success > th, +.table > tbody > tr.success > th, +.table > tfoot > tr.success > th { + background-color: #dff0d8; +} +.table-hover > tbody > tr > td.success:hover, +.table-hover > tbody > tr > th.success:hover, +.table-hover > tbody > tr.success:hover > td, +.table-hover > tbody > tr:hover > .success, +.table-hover > tbody > tr.success:hover > th { + background-color: #d0e9c6; +} +.table > thead > tr > td.info, +.table > tbody > tr > td.info, +.table > tfoot > tr > td.info, +.table > thead > tr > th.info, +.table > tbody > tr > th.info, +.table > tfoot > tr > th.info, +.table > thead > tr.info > td, +.table > tbody > tr.info > td, +.table > tfoot > tr.info > td, +.table > thead > tr.info > th, +.table > tbody > tr.info > th, +.table > tfoot > tr.info > th { + background-color: #d9edf7; +} +.table-hover > tbody > tr > td.info:hover, +.table-hover > tbody > tr > th.info:hover, +.table-hover > tbody > tr.info:hover > td, +.table-hover > tbody > tr:hover > .info, +.table-hover > tbody > tr.info:hover > th { + background-color: #c4e3f3; +} +.table > thead > tr > td.warning, +.table > tbody > tr > td.warning, +.table > tfoot > tr > td.warning, +.table > thead > tr > th.warning, +.table > tbody > tr > th.warning, +.table > tfoot > tr > th.warning, +.table > thead > tr.warning > td, +.table > tbody > tr.warning > td, +.table > tfoot > tr.warning > td, +.table > thead > tr.warning > th, +.table > tbody > tr.warning > th, +.table > tfoot > tr.warning > th { + background-color: #fcf8e3; +} +.table-hover > tbody > tr > td.warning:hover, +.table-hover > tbody > tr > th.warning:hover, +.table-hover > tbody > tr.warning:hover > td, +.table-hover > tbody > tr:hover > .warning, +.table-hover > tbody > tr.warning:hover > th { + background-color: #faf2cc; +} +.table > thead > tr > td.danger, +.table > tbody > tr > td.danger, +.table > tfoot > tr > td.danger, +.table > thead > tr > th.danger, +.table > tbody > tr > th.danger, +.table > tfoot > tr > th.danger, +.table > thead > tr.danger > td, +.table > tbody > tr.danger > td, +.table > tfoot > tr.danger > td, +.table > thead > tr.danger > th, +.table > tbody > tr.danger > th, +.table > tfoot > tr.danger > th { + background-color: #f2dede; +} +.table-hover > tbody > tr > td.danger:hover, +.table-hover > tbody > tr > th.danger:hover, +.table-hover > tbody > tr.danger:hover > td, +.table-hover > tbody > tr:hover > .danger, +.table-hover > tbody > tr.danger:hover > th { + background-color: #ebcccc; +} +.table-responsive { + min-height: .01%; + overflow-x: auto; +} +@media screen and (max-width: 767px) { + .table-responsive { + width: 100%; + margin-bottom: 15px; + overflow-y: hidden; + -ms-overflow-style: -ms-autohiding-scrollbar; + border: 1px solid #ddd; + } + .table-responsive > .table { + margin-bottom: 0; + } + .table-responsive > .table > thead > tr > th, + .table-responsive > .table > tbody > tr > th, + .table-responsive > .table > tfoot > tr > th, + .table-responsive > .table > thead > tr > td, + .table-responsive > .table > tbody > tr > td, + .table-responsive > .table > tfoot > tr > td { + white-space: nowrap; + } + .table-responsive > .table-bordered { + border: 0; + } + .table-responsive > .table-bordered > thead > tr > th:first-child, + .table-responsive > .table-bordered > tbody > tr > th:first-child, + .table-responsive > .table-bordered > tfoot > tr > th:first-child, + .table-responsive > .table-bordered > thead > tr > td:first-child, + .table-responsive > .table-bordered > tbody > tr > td:first-child, + .table-responsive > .table-bordered > tfoot > tr > td:first-child { + border-left: 0; + } + .table-responsive > .table-bordered > thead > tr > th:last-child, + .table-responsive > .table-bordered > tbody > tr > th:last-child, + .table-responsive > .table-bordered > tfoot > tr > th:last-child, + .table-responsive > .table-bordered > thead > tr > td:last-child, + .table-responsive > .table-bordered > tbody > tr > td:last-child, + .table-responsive > .table-bordered > tfoot > tr > td:last-child { + border-right: 0; + } + .table-responsive > .table-bordered > tbody > tr:last-child > th, + .table-responsive > .table-bordered > tfoot > tr:last-child > th, + .table-responsive > .table-bordered > tbody > tr:last-child > td, + .table-responsive > .table-bordered > tfoot > tr:last-child > td { + border-bottom: 0; + } +} +fieldset { + min-width: 0; + padding: 0; + margin: 0; + border: 0; +} +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: 20px; + font-size: 21px; + line-height: inherit; + color: #333; + border: 0; + border-bottom: 1px solid #e5e5e5; +} +label { + display: inline-block; + max-width: 100%; + margin-bottom: 5px; + font-weight: bold; +} +input[type="search"] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +input[type="radio"], +input[type="checkbox"] { + margin: 4px 0 0; + margin-top: 1px \9; + line-height: normal; +} +input[type="file"] { + display: block; +} +input[type="range"] { + display: block; + width: 100%; +} +select[multiple], +select[size] { + height: auto; +} +input[type="file"]:focus, +input[type="radio"]:focus, +input[type="checkbox"]:focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +output { + display: block; + padding-top: 7px; + font-size: 14px; + line-height: 1.42857143; + color: #555; +} +.form-control { + display: block; + width: 100%; + height: 34px; + padding: 6px 12px; + font-size: 14px; + line-height: 1.42857143; + color: #555; + background-color: #fff; + background-image: none; + border: 1px solid #ccc; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s; + -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; + transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; +} +.form-control:focus { + border-color: #66afe9; + outline: 0; + -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6); + box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6); +} +.form-control::-moz-placeholder { + color: #999; + opacity: 1; +} +.form-control:-ms-input-placeholder { + color: #999; +} +.form-control::-webkit-input-placeholder { + color: #999; +} +.form-control[disabled], +.form-control[readonly], +fieldset[disabled] .form-control { + cursor: not-allowed; + background-color: #eee; + opacity: 1; +} +textarea.form-control { + height: auto; +} +input[type="search"] { + -webkit-appearance: none; +} +@media screen and (-webkit-min-device-pixel-ratio: 0) { + input[type="date"], + input[type="time"], + input[type="datetime-local"], + input[type="month"] { + line-height: 34px; + } + input[type="date"].input-sm, + input[type="time"].input-sm, + input[type="datetime-local"].input-sm, + input[type="month"].input-sm, + .input-group-sm input[type="date"], + .input-group-sm input[type="time"], + .input-group-sm input[type="datetime-local"], + .input-group-sm input[type="month"] { + line-height: 30px; + } + input[type="date"].input-lg, + input[type="time"].input-lg, + input[type="datetime-local"].input-lg, + input[type="month"].input-lg, + .input-group-lg input[type="date"], + .input-group-lg input[type="time"], + .input-group-lg input[type="datetime-local"], + .input-group-lg input[type="month"] { + line-height: 46px; + } +} +.form-group { + margin-bottom: 15px; +} +.radio, +.checkbox { + position: relative; + display: block; + margin-top: 10px; + margin-bottom: 10px; +} +.radio label, +.checkbox label { + min-height: 20px; + padding-left: 20px; + margin-bottom: 0; + font-weight: normal; + cursor: pointer; +} +.radio input[type="radio"], +.radio-inline input[type="radio"], +.checkbox input[type="checkbox"], +.checkbox-inline input[type="checkbox"] { + position: absolute; + margin-top: 4px \9; + margin-left: -20px; +} +.radio + .radio, +.checkbox + .checkbox { + margin-top: -5px; +} +.radio-inline, +.checkbox-inline { + display: inline-block; + padding-left: 20px; + margin-bottom: 0; + font-weight: normal; + vertical-align: middle; + cursor: pointer; +} +.radio-inline + .radio-inline, +.checkbox-inline + .checkbox-inline { + margin-top: 0; + margin-left: 10px; +} +input[type="radio"][disabled], +input[type="checkbox"][disabled], +input[type="radio"].disabled, +input[type="checkbox"].disabled, +fieldset[disabled] input[type="radio"], +fieldset[disabled] input[type="checkbox"] { + cursor: not-allowed; +} +.radio-inline.disabled, +.checkbox-inline.disabled, +fieldset[disabled] .radio-inline, +fieldset[disabled] .checkbox-inline { + cursor: not-allowed; +} +.radio.disabled label, +.checkbox.disabled label, +fieldset[disabled] .radio label, +fieldset[disabled] .checkbox label { + cursor: not-allowed; +} +.form-control-static { + padding-top: 7px; + padding-bottom: 7px; + margin-bottom: 0; +} +.form-control-static.input-lg, +.form-control-static.input-sm { + padding-right: 0; + padding-left: 0; +} +.input-sm { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +select.input-sm { + height: 30px; + line-height: 30px; +} +textarea.input-sm, +select[multiple].input-sm { + height: auto; +} +.form-group-sm .form-control { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +select.form-group-sm .form-control { + height: 30px; + line-height: 30px; +} +textarea.form-group-sm .form-control, +select[multiple].form-group-sm .form-control { + height: auto; +} +.form-group-sm .form-control-static { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; +} +.input-lg { + height: 46px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; + border-radius: 6px; +} +select.input-lg { + height: 46px; + line-height: 46px; +} +textarea.input-lg, +select[multiple].input-lg { + height: auto; +} +.form-group-lg .form-control { + height: 46px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; + border-radius: 6px; +} +select.form-group-lg .form-control { + height: 46px; + line-height: 46px; +} +textarea.form-group-lg .form-control, +select[multiple].form-group-lg .form-control { + height: auto; +} +.form-group-lg .form-control-static { + height: 46px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; +} +.has-feedback { + position: relative; +} +.has-feedback .form-control { + padding-right: 42.5px; +} +.form-control-feedback { + position: absolute; + top: 0; + right: 0; + z-index: 2; + display: block; + width: 34px; + height: 34px; + line-height: 34px; + text-align: center; + pointer-events: none; +} +.input-lg + .form-control-feedback { + width: 46px; + height: 46px; + line-height: 46px; +} +.input-sm + .form-control-feedback { + width: 30px; + height: 30px; + line-height: 30px; +} +.has-success .help-block, +.has-success .control-label, +.has-success .radio, +.has-success .checkbox, +.has-success .radio-inline, +.has-success .checkbox-inline, +.has-success.radio label, +.has-success.checkbox label, +.has-success.radio-inline label, +.has-success.checkbox-inline label { + color: #3c763d; +} +.has-success .form-control { + border-color: #3c763d; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); +} +.has-success .form-control:focus { + border-color: #2b542c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168; +} +.has-success .input-group-addon { + color: #3c763d; + background-color: #dff0d8; + border-color: #3c763d; +} +.has-success .form-control-feedback { + color: #3c763d; +} +.has-warning .help-block, +.has-warning .control-label, +.has-warning .radio, +.has-warning .checkbox, +.has-warning .radio-inline, +.has-warning .checkbox-inline, +.has-warning.radio label, +.has-warning.checkbox label, +.has-warning.radio-inline label, +.has-warning.checkbox-inline label { + color: #8a6d3b; +} +.has-warning .form-control { + border-color: #8a6d3b; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); +} +.has-warning .form-control:focus { + border-color: #66512c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b; +} +.has-warning .input-group-addon { + color: #8a6d3b; + background-color: #fcf8e3; + border-color: #8a6d3b; +} +.has-warning .form-control-feedback { + color: #8a6d3b; +} +.has-error .help-block, +.has-error .control-label, +.has-error .radio, +.has-error .checkbox, +.has-error .radio-inline, +.has-error .checkbox-inline, +.has-error.radio label, +.has-error.checkbox label, +.has-error.radio-inline label, +.has-error.checkbox-inline label { + color: #a94442; +} +.has-error .form-control { + border-color: #a94442; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); +} +.has-error .form-control:focus { + border-color: #843534; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483; +} +.has-error .input-group-addon { + color: #a94442; + background-color: #f2dede; + border-color: #a94442; +} +.has-error .form-control-feedback { + color: #a94442; +} +.has-feedback label ~ .form-control-feedback { + top: 25px; +} +.has-feedback label.sr-only ~ .form-control-feedback { + top: 0; +} +.help-block { + display: block; + margin-top: 5px; + margin-bottom: 10px; + color: #737373; +} +@media (min-width: 768px) { + .form-inline .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .form-control { + display: inline-block; + width: auto; + vertical-align: middle; + } + .form-inline .form-control-static { + display: inline-block; + } + .form-inline .input-group { + display: inline-table; + vertical-align: middle; + } + .form-inline .input-group .input-group-addon, + .form-inline .input-group .input-group-btn, + .form-inline .input-group .form-control { + width: auto; + } + .form-inline .input-group > .form-control { + width: 100%; + } + .form-inline .control-label { + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .radio, + .form-inline .checkbox { + display: inline-block; + margin-top: 0; + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .radio label, + .form-inline .checkbox label { + padding-left: 0; + } + .form-inline .radio input[type="radio"], + .form-inline .checkbox input[type="checkbox"] { + position: relative; + margin-left: 0; + } + .form-inline .has-feedback .form-control-feedback { + top: 0; + } +} +.form-horizontal .radio, +.form-horizontal .checkbox, +.form-horizontal .radio-inline, +.form-horizontal .checkbox-inline { + padding-top: 7px; + margin-top: 0; + margin-bottom: 0; +} +.form-horizontal .radio, +.form-horizontal .checkbox { + min-height: 27px; +} +.form-horizontal .form-group { + margin-right: -15px; + margin-left: -15px; +} +@media (min-width: 768px) { + .form-horizontal .control-label { + padding-top: 7px; + margin-bottom: 0; + text-align: right; + } +} +.form-horizontal .has-feedback .form-control-feedback { + right: 15px; +} +@media (min-width: 768px) { + .form-horizontal .form-group-lg .control-label { + padding-top: 14.333333px; + } +} +@media (min-width: 768px) { + .form-horizontal .form-group-sm .control-label { + padding-top: 6px; + } +} +.btn { + display: inline-block; + padding: 6px 12px; + margin-bottom: 0; + font-size: 14px; + font-weight: normal; + line-height: 1.42857143; + text-align: center; + white-space: nowrap; + vertical-align: middle; + -ms-touch-action: manipulation; + touch-action: manipulation; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + background-image: none; + border: 1px solid transparent; + border-radius: 4px; +} +.btn:focus, +.btn:active:focus, +.btn.active:focus, +.btn.focus, +.btn:active.focus, +.btn.active.focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +.btn:hover, +.btn:focus, +.btn.focus { + color: #333; + text-decoration: none; +} +.btn:active, +.btn.active { + background-image: none; + outline: 0; + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); +} +.btn.disabled, +.btn[disabled], +fieldset[disabled] .btn { + pointer-events: none; + cursor: not-allowed; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + box-shadow: none; + opacity: .65; +} +.btn-default { + color: #333; + background-color: #fff; + border-color: #ccc; +} +.btn-default:hover, +.btn-default:focus, +.btn-default.focus, +.btn-default:active, +.btn-default.active, +.open > .dropdown-toggle.btn-default { + color: #333; + background-color: #e6e6e6; + border-color: #adadad; +} +.btn-default:active, +.btn-default.active, +.open > .dropdown-toggle.btn-default { + background-image: none; +} +.btn-default.disabled, +.btn-default[disabled], +fieldset[disabled] .btn-default, +.btn-default.disabled:hover, +.btn-default[disabled]:hover, +fieldset[disabled] .btn-default:hover, +.btn-default.disabled:focus, +.btn-default[disabled]:focus, +fieldset[disabled] .btn-default:focus, +.btn-default.disabled.focus, +.btn-default[disabled].focus, +fieldset[disabled] .btn-default.focus, +.btn-default.disabled:active, +.btn-default[disabled]:active, +fieldset[disabled] .btn-default:active, +.btn-default.disabled.active, +.btn-default[disabled].active, +fieldset[disabled] .btn-default.active { + background-color: #fff; + border-color: #ccc; +} +.btn-default .badge { + color: #fff; + background-color: #333; +} +.btn-primary { + color: #fff; + background-color: #337ab7; + border-color: #2e6da4; +} +.btn-primary:hover, +.btn-primary:focus, +.btn-primary.focus, +.btn-primary:active, +.btn-primary.active, +.open > .dropdown-toggle.btn-primary { + color: #fff; + background-color: #286090; + border-color: #204d74; +} +.btn-primary:active, +.btn-primary.active, +.open > .dropdown-toggle.btn-primary { + background-image: none; +} +.btn-primary.disabled, +.btn-primary[disabled], +fieldset[disabled] .btn-primary, +.btn-primary.disabled:hover, +.btn-primary[disabled]:hover, +fieldset[disabled] .btn-primary:hover, +.btn-primary.disabled:focus, +.btn-primary[disabled]:focus, +fieldset[disabled] .btn-primary:focus, +.btn-primary.disabled.focus, +.btn-primary[disabled].focus, +fieldset[disabled] .btn-primary.focus, +.btn-primary.disabled:active, +.btn-primary[disabled]:active, +fieldset[disabled] .btn-primary:active, +.btn-primary.disabled.active, +.btn-primary[disabled].active, +fieldset[disabled] .btn-primary.active { + background-color: #337ab7; + border-color: #2e6da4; +} +.btn-primary .badge { + color: #337ab7; + background-color: #fff; +} +.btn-success { + color: #fff; + background-color: #5cb85c; + border-color: #4cae4c; +} +.btn-success:hover, +.btn-success:focus, +.btn-success.focus, +.btn-success:active, +.btn-success.active, +.open > .dropdown-toggle.btn-success { + color: #fff; + background-color: #449d44; + border-color: #398439; +} +.btn-success:active, +.btn-success.active, +.open > .dropdown-toggle.btn-success { + background-image: none; +} +.btn-success.disabled, +.btn-success[disabled], +fieldset[disabled] .btn-success, +.btn-success.disabled:hover, +.btn-success[disabled]:hover, +fieldset[disabled] .btn-success:hover, +.btn-success.disabled:focus, +.btn-success[disabled]:focus, +fieldset[disabled] .btn-success:focus, +.btn-success.disabled.focus, +.btn-success[disabled].focus, +fieldset[disabled] .btn-success.focus, +.btn-success.disabled:active, +.btn-success[disabled]:active, +fieldset[disabled] .btn-success:active, +.btn-success.disabled.active, +.btn-success[disabled].active, +fieldset[disabled] .btn-success.active { + background-color: #5cb85c; + border-color: #4cae4c; +} +.btn-success .badge { + color: #5cb85c; + background-color: #fff; +} +.btn-info { + color: #fff; + background-color: #5bc0de; + border-color: #46b8da; +} +.btn-info:hover, +.btn-info:focus, +.btn-info.focus, +.btn-info:active, +.btn-info.active, +.open > .dropdown-toggle.btn-info { + color: #fff; + background-color: #31b0d5; + border-color: #269abc; +} +.btn-info:active, +.btn-info.active, +.open > .dropdown-toggle.btn-info { + background-image: none; +} +.btn-info.disabled, +.btn-info[disabled], +fieldset[disabled] .btn-info, +.btn-info.disabled:hover, +.btn-info[disabled]:hover, +fieldset[disabled] .btn-info:hover, +.btn-info.disabled:focus, +.btn-info[disabled]:focus, +fieldset[disabled] .btn-info:focus, +.btn-info.disabled.focus, +.btn-info[disabled].focus, +fieldset[disabled] .btn-info.focus, +.btn-info.disabled:active, +.btn-info[disabled]:active, +fieldset[disabled] .btn-info:active, +.btn-info.disabled.active, +.btn-info[disabled].active, +fieldset[disabled] .btn-info.active { + background-color: #5bc0de; + border-color: #46b8da; +} +.btn-info .badge { + color: #5bc0de; + background-color: #fff; +} +.btn-warning { + color: #fff; + background-color: #f0ad4e; + border-color: #eea236; +} +.btn-warning:hover, +.btn-warning:focus, +.btn-warning.focus, +.btn-warning:active, +.btn-warning.active, +.open > .dropdown-toggle.btn-warning { + color: #fff; + background-color: #ec971f; + border-color: #d58512; +} +.btn-warning:active, +.btn-warning.active, +.open > .dropdown-toggle.btn-warning { + background-image: none; +} +.btn-warning.disabled, +.btn-warning[disabled], +fieldset[disabled] .btn-warning, +.btn-warning.disabled:hover, +.btn-warning[disabled]:hover, +fieldset[disabled] .btn-warning:hover, +.btn-warning.disabled:focus, +.btn-warning[disabled]:focus, +fieldset[disabled] .btn-warning:focus, +.btn-warning.disabled.focus, +.btn-warning[disabled].focus, +fieldset[disabled] .btn-warning.focus, +.btn-warning.disabled:active, +.btn-warning[disabled]:active, +fieldset[disabled] .btn-warning:active, +.btn-warning.disabled.active, +.btn-warning[disabled].active, +fieldset[disabled] .btn-warning.active { + background-color: #f0ad4e; + border-color: #eea236; +} +.btn-warning .badge { + color: #f0ad4e; + background-color: #fff; +} +.btn-danger { + color: #fff; + background-color: #d9534f; + border-color: #d43f3a; +} +.btn-danger:hover, +.btn-danger:focus, +.btn-danger.focus, +.btn-danger:active, +.btn-danger.active, +.open > .dropdown-toggle.btn-danger { + color: #fff; + background-color: #c9302c; + border-color: #ac2925; +} +.btn-danger:active, +.btn-danger.active, +.open > .dropdown-toggle.btn-danger { + background-image: none; +} +.btn-danger.disabled, +.btn-danger[disabled], +fieldset[disabled] .btn-danger, +.btn-danger.disabled:hover, +.btn-danger[disabled]:hover, +fieldset[disabled] .btn-danger:hover, +.btn-danger.disabled:focus, +.btn-danger[disabled]:focus, +fieldset[disabled] .btn-danger:focus, +.btn-danger.disabled.focus, +.btn-danger[disabled].focus, +fieldset[disabled] .btn-danger.focus, +.btn-danger.disabled:active, +.btn-danger[disabled]:active, +fieldset[disabled] .btn-danger:active, +.btn-danger.disabled.active, +.btn-danger[disabled].active, +fieldset[disabled] .btn-danger.active { + background-color: #d9534f; + border-color: #d43f3a; +} +.btn-danger .badge { + color: #d9534f; + background-color: #fff; +} +.btn-link { + font-weight: normal; + color: #337ab7; + border-radius: 0; +} +.btn-link, +.btn-link:active, +.btn-link.active, +.btn-link[disabled], +fieldset[disabled] .btn-link { + background-color: transparent; + -webkit-box-shadow: none; + box-shadow: none; +} +.btn-link, +.btn-link:hover, +.btn-link:focus, +.btn-link:active { + border-color: transparent; +} +.btn-link:hover, +.btn-link:focus { + color: #23527c; + text-decoration: underline; + background-color: transparent; +} +.btn-link[disabled]:hover, +fieldset[disabled] .btn-link:hover, +.btn-link[disabled]:focus, +fieldset[disabled] .btn-link:focus { + color: #777; + text-decoration: none; +} +.btn-lg, +.btn-group-lg > .btn { + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; + border-radius: 6px; +} +.btn-sm, +.btn-group-sm > .btn { + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +.btn-xs, +.btn-group-xs > .btn { + padding: 1px 5px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +.btn-block { + display: block; + width: 100%; +} +.btn-block + .btn-block { + margin-top: 5px; +} +input[type="submit"].btn-block, +input[type="reset"].btn-block, +input[type="button"].btn-block { + width: 100%; +} +.fade { + opacity: 0; + -webkit-transition: opacity .15s linear; + -o-transition: opacity .15s linear; + transition: opacity .15s linear; +} +.fade.in { + opacity: 1; +} +.collapse { + display: none; + visibility: hidden; +} +.collapse.in { + display: block; + visibility: visible; +} +tr.collapse.in { + display: table-row; +} +tbody.collapse.in { + display: table-row-group; +} +.collapsing { + position: relative; + height: 0; + overflow: hidden; + -webkit-transition-timing-function: ease; + -o-transition-timing-function: ease; + transition-timing-function: ease; + -webkit-transition-duration: .35s; + -o-transition-duration: .35s; + transition-duration: .35s; + -webkit-transition-property: height, visibility; + -o-transition-property: height, visibility; + transition-property: height, visibility; +} +.caret { + display: inline-block; + width: 0; + height: 0; + margin-left: 2px; + vertical-align: middle; + border-top: 4px solid; + border-right: 4px solid transparent; + border-left: 4px solid transparent; +} +.dropup, +.dropdown { + position: relative; +} +.dropdown-toggle:focus { + outline: 0; +} +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 160px; + padding: 5px 0; + margin: 2px 0 0; + font-size: 14px; + text-align: left; + list-style: none; + background-color: #fff; + -webkit-background-clip: padding-box; + background-clip: padding-box; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, .15); + border-radius: 4px; + -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175); + box-shadow: 0 6px 12px rgba(0, 0, 0, .175); +} +.dropdown-menu.pull-right { + right: 0; + left: auto; +} +.dropdown-menu .divider { + height: 1px; + margin: 9px 0; + overflow: hidden; + background-color: #e5e5e5; +} +.dropdown-menu > li > a { + display: block; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: 1.42857143; + color: #333; + white-space: nowrap; +} +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus { + color: #262626; + text-decoration: none; + background-color: #f5f5f5; +} +.dropdown-menu > .active > a, +.dropdown-menu > .active > a:hover, +.dropdown-menu > .active > a:focus { + color: #fff; + text-decoration: none; + background-color: #337ab7; + outline: 0; +} +.dropdown-menu > .disabled > a, +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + color: #777; +} +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + text-decoration: none; + cursor: not-allowed; + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.open > .dropdown-menu { + display: block; +} +.open > a { + outline: 0; +} +.dropdown-menu-right { + right: 0; + left: auto; +} +.dropdown-menu-left { + right: auto; + left: 0; +} +.dropdown-header { + display: block; + padding: 3px 20px; + font-size: 12px; + line-height: 1.42857143; + color: #777; + white-space: nowrap; +} +.dropdown-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 990; +} +.pull-right > .dropdown-menu { + right: 0; + left: auto; +} +.dropup .caret, +.navbar-fixed-bottom .dropdown .caret { + content: ""; + border-top: 0; + border-bottom: 4px solid; +} +.dropup .dropdown-menu, +.navbar-fixed-bottom .dropdown .dropdown-menu { + top: auto; + bottom: 100%; + margin-bottom: 2px; +} +@media (min-width: 768px) { + .navbar-right .dropdown-menu { + right: 0; + left: auto; + } + .navbar-right .dropdown-menu-left { + right: auto; + left: 0; + } +} +.btn-group, +.btn-group-vertical { + position: relative; + display: inline-block; + vertical-align: middle; +} +.btn-group > .btn, +.btn-group-vertical > .btn { + position: relative; + float: left; +} +.btn-group > .btn:hover, +.btn-group-vertical > .btn:hover, +.btn-group > .btn:focus, +.btn-group-vertical > .btn:focus, +.btn-group > .btn:active, +.btn-group-vertical > .btn:active, +.btn-group > .btn.active, +.btn-group-vertical > .btn.active { + z-index: 2; +} +.btn-group .btn + .btn, +.btn-group .btn + .btn-group, +.btn-group .btn-group + .btn, +.btn-group .btn-group + .btn-group { + margin-left: -1px; +} +.btn-toolbar { + margin-left: -5px; +} +.btn-toolbar .btn-group, +.btn-toolbar .input-group { + float: left; +} +.btn-toolbar > .btn, +.btn-toolbar > .btn-group, +.btn-toolbar > .input-group { + margin-left: 5px; +} +.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { + border-radius: 0; +} +.btn-group > .btn:first-child { + margin-left: 0; +} +.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.btn-group > .btn:last-child:not(:first-child), +.btn-group > .dropdown-toggle:not(:first-child) { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group > .btn-group { + float: left; +} +.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} +.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child, +.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group .dropdown-toggle:active, +.btn-group.open .dropdown-toggle { + outline: 0; +} +.btn-group > .btn + .dropdown-toggle { + padding-right: 8px; + padding-left: 8px; +} +.btn-group > .btn-lg + .dropdown-toggle { + padding-right: 12px; + padding-left: 12px; +} +.btn-group.open .dropdown-toggle { + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); +} +.btn-group.open .dropdown-toggle.btn-link { + -webkit-box-shadow: none; + box-shadow: none; +} +.btn .caret { + margin-left: 0; +} +.btn-lg .caret { + border-width: 5px 5px 0; + border-bottom-width: 0; +} +.dropup .btn-lg .caret { + border-width: 0 5px 5px; +} +.btn-group-vertical > .btn, +.btn-group-vertical > .btn-group, +.btn-group-vertical > .btn-group > .btn { + display: block; + float: none; + width: 100%; + max-width: 100%; +} +.btn-group-vertical > .btn-group > .btn { + float: none; +} +.btn-group-vertical > .btn + .btn, +.btn-group-vertical > .btn + .btn-group, +.btn-group-vertical > .btn-group + .btn, +.btn-group-vertical > .btn-group + .btn-group { + margin-top: -1px; + margin-left: 0; +} +.btn-group-vertical > .btn:not(:first-child):not(:last-child) { + border-radius: 0; +} +.btn-group-vertical > .btn:first-child:not(:last-child) { + border-top-right-radius: 4px; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group-vertical > .btn:last-child:not(:first-child) { + border-top-left-radius: 0; + border-top-right-radius: 0; + border-bottom-left-radius: 4px; +} +.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} +.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child, +.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child { + border-top-left-radius: 0; + border-top-right-radius: 0; +} +.btn-group-justified { + display: table; + width: 100%; + table-layout: fixed; + border-collapse: separate; +} +.btn-group-justified > .btn, +.btn-group-justified > .btn-group { + display: table-cell; + float: none; + width: 1%; +} +.btn-group-justified > .btn-group .btn { + width: 100%; +} +.btn-group-justified > .btn-group .dropdown-menu { + left: auto; +} +[data-toggle="buttons"] > .btn input[type="radio"], +[data-toggle="buttons"] > .btn-group > .btn input[type="radio"], +[data-toggle="buttons"] > .btn input[type="checkbox"], +[data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] { + position: absolute; + clip: rect(0, 0, 0, 0); + pointer-events: none; +} +.input-group { + position: relative; + display: table; + border-collapse: separate; +} +.input-group[class*="col-"] { + float: none; + padding-right: 0; + padding-left: 0; +} +.input-group .form-control { + position: relative; + z-index: 2; + float: left; + width: 100%; + margin-bottom: 0; +} +.input-group-lg > .form-control, +.input-group-lg > .input-group-addon, +.input-group-lg > .input-group-btn > .btn { + height: 46px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; + border-radius: 6px; +} +select.input-group-lg > .form-control, +select.input-group-lg > .input-group-addon, +select.input-group-lg > .input-group-btn > .btn { + height: 46px; + line-height: 46px; +} +textarea.input-group-lg > .form-control, +textarea.input-group-lg > .input-group-addon, +textarea.input-group-lg > .input-group-btn > .btn, +select[multiple].input-group-lg > .form-control, +select[multiple].input-group-lg > .input-group-addon, +select[multiple].input-group-lg > .input-group-btn > .btn { + height: auto; +} +.input-group-sm > .form-control, +.input-group-sm > .input-group-addon, +.input-group-sm > .input-group-btn > .btn { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +select.input-group-sm > .form-control, +select.input-group-sm > .input-group-addon, +select.input-group-sm > .input-group-btn > .btn { + height: 30px; + line-height: 30px; +} +textarea.input-group-sm > .form-control, +textarea.input-group-sm > .input-group-addon, +textarea.input-group-sm > .input-group-btn > .btn, +select[multiple].input-group-sm > .form-control, +select[multiple].input-group-sm > .input-group-addon, +select[multiple].input-group-sm > .input-group-btn > .btn { + height: auto; +} +.input-group-addon, +.input-group-btn, +.input-group .form-control { + display: table-cell; +} +.input-group-addon:not(:first-child):not(:last-child), +.input-group-btn:not(:first-child):not(:last-child), +.input-group .form-control:not(:first-child):not(:last-child) { + border-radius: 0; +} +.input-group-addon, +.input-group-btn { + width: 1%; + white-space: nowrap; + vertical-align: middle; +} +.input-group-addon { + padding: 6px 12px; + font-size: 14px; + font-weight: normal; + line-height: 1; + color: #555; + text-align: center; + background-color: #eee; + border: 1px solid #ccc; + border-radius: 4px; +} +.input-group-addon.input-sm { + padding: 5px 10px; + font-size: 12px; + border-radius: 3px; +} +.input-group-addon.input-lg { + padding: 10px 16px; + font-size: 18px; + border-radius: 6px; +} +.input-group-addon input[type="radio"], +.input-group-addon input[type="checkbox"] { + margin-top: 0; +} +.input-group .form-control:first-child, +.input-group-addon:first-child, +.input-group-btn:first-child > .btn, +.input-group-btn:first-child > .btn-group > .btn, +.input-group-btn:first-child > .dropdown-toggle, +.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle), +.input-group-btn:last-child > .btn-group:not(:last-child) > .btn { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.input-group-addon:first-child { + border-right: 0; +} +.input-group .form-control:last-child, +.input-group-addon:last-child, +.input-group-btn:last-child > .btn, +.input-group-btn:last-child > .btn-group > .btn, +.input-group-btn:last-child > .dropdown-toggle, +.input-group-btn:first-child > .btn:not(:first-child), +.input-group-btn:first-child > .btn-group:not(:first-child) > .btn { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} +.input-group-addon:last-child { + border-left: 0; +} +.input-group-btn { + position: relative; + font-size: 0; + white-space: nowrap; +} +.input-group-btn > .btn { + position: relative; +} +.input-group-btn > .btn + .btn { + margin-left: -1px; +} +.input-group-btn > .btn:hover, +.input-group-btn > .btn:focus, +.input-group-btn > .btn:active { + z-index: 2; +} +.input-group-btn:first-child > .btn, +.input-group-btn:first-child > .btn-group { + margin-right: -1px; +} +.input-group-btn:last-child > .btn, +.input-group-btn:last-child > .btn-group { + margin-left: -1px; +} +.nav { + padding-left: 0; + margin-bottom: 0; + list-style: none; +} +.nav > li { + position: relative; + display: block; +} +.nav > li > a { + position: relative; + display: block; + padding: 10px 15px; +} +.nav > li > a:hover, +.nav > li > a:focus { + text-decoration: none; + background-color: #eee; +} +.nav > li.disabled > a { + color: #777; +} +.nav > li.disabled > a:hover, +.nav > li.disabled > a:focus { + color: #777; + text-decoration: none; + cursor: not-allowed; + background-color: transparent; +} +.nav .open > a, +.nav .open > a:hover, +.nav .open > a:focus { + background-color: #eee; + border-color: #337ab7; +} +.nav .nav-divider { + height: 1px; + margin: 9px 0; + overflow: hidden; + background-color: #e5e5e5; +} +.nav > li > a > img { + max-width: none; +} +.nav-tabs { + border-bottom: 1px solid #ddd; +} +.nav-tabs > li { + float: left; + margin-bottom: -1px; +} +.nav-tabs > li > a { + margin-right: 2px; + line-height: 1.42857143; + border: 1px solid transparent; + border-radius: 4px 4px 0 0; +} +.nav-tabs > li > a:hover { + border-color: #eee #eee #ddd; +} +.nav-tabs > li.active > a, +.nav-tabs > li.active > a:hover, +.nav-tabs > li.active > a:focus { + color: #555; + cursor: default; + background-color: #fff; + border: 1px solid #ddd; + border-bottom-color: transparent; +} +.nav-tabs.nav-justified { + width: 100%; + border-bottom: 0; +} +.nav-tabs.nav-justified > li { + float: none; +} +.nav-tabs.nav-justified > li > a { + margin-bottom: 5px; + text-align: center; +} +.nav-tabs.nav-justified > .dropdown .dropdown-menu { + top: auto; + left: auto; +} +@media (min-width: 768px) { + .nav-tabs.nav-justified > li { + display: table-cell; + width: 1%; + } + .nav-tabs.nav-justified > li > a { + margin-bottom: 0; + } +} +.nav-tabs.nav-justified > li > a { + margin-right: 0; + border-radius: 4px; +} +.nav-tabs.nav-justified > .active > a, +.nav-tabs.nav-justified > .active > a:hover, +.nav-tabs.nav-justified > .active > a:focus { + border: 1px solid #ddd; +} +@media (min-width: 768px) { + .nav-tabs.nav-justified > li > a { + border-bottom: 1px solid #ddd; + border-radius: 4px 4px 0 0; + } + .nav-tabs.nav-justified > .active > a, + .nav-tabs.nav-justified > .active > a:hover, + .nav-tabs.nav-justified > .active > a:focus { + border-bottom-color: #fff; + } +} +.nav-pills > li { + float: left; +} +.nav-pills > li > a { + border-radius: 4px; +} +.nav-pills > li + li { + margin-left: 2px; +} +.nav-pills > li.active > a, +.nav-pills > li.active > a:hover, +.nav-pills > li.active > a:focus { + color: #fff; + background-color: #337ab7; +} +.nav-stacked > li { + float: none; +} +.nav-stacked > li + li { + margin-top: 2px; + margin-left: 0; +} +.nav-justified { + width: 100%; +} +.nav-justified > li { + float: none; +} +.nav-justified > li > a { + margin-bottom: 5px; + text-align: center; +} +.nav-justified > .dropdown .dropdown-menu { + top: auto; + left: auto; +} +@media (min-width: 768px) { + .nav-justified > li { + display: table-cell; + width: 1%; + } + .nav-justified > li > a { + margin-bottom: 0; + } +} +.nav-tabs-justified { + border-bottom: 0; +} +.nav-tabs-justified > li > a { + margin-right: 0; + border-radius: 4px; +} +.nav-tabs-justified > .active > a, +.nav-tabs-justified > .active > a:hover, +.nav-tabs-justified > .active > a:focus { + border: 1px solid #ddd; +} +@media (min-width: 768px) { + .nav-tabs-justified > li > a { + border-bottom: 1px solid #ddd; + border-radius: 4px 4px 0 0; + } + .nav-tabs-justified > .active > a, + .nav-tabs-justified > .active > a:hover, + .nav-tabs-justified > .active > a:focus { + border-bottom-color: #fff; + } +} +.tab-content > .tab-pane { + display: none; + visibility: hidden; +} +.tab-content > .active { + display: block; + visibility: visible; +} +.nav-tabs .dropdown-menu { + margin-top: -1px; + border-top-left-radius: 0; + border-top-right-radius: 0; +} +.navbar { + position: relative; + min-height: 50px; + margin-bottom: 20px; + border: 1px solid transparent; +} +@media (min-width: 768px) { + .navbar { + border-radius: 4px; + } +} +@media (min-width: 768px) { + .navbar-header { + float: left; + } +} +.navbar-collapse { + padding-right: 15px; + padding-left: 15px; + overflow-x: visible; + -webkit-overflow-scrolling: touch; + border-top: 1px solid transparent; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1); +} +.navbar-collapse.in { + overflow-y: auto; +} +@media (min-width: 768px) { + .navbar-collapse { + width: auto; + border-top: 0; + -webkit-box-shadow: none; + box-shadow: none; + } + .navbar-collapse.collapse { + display: block !important; + height: auto !important; + padding-bottom: 0; + overflow: visible !important; + visibility: visible !important; + } + .navbar-collapse.in { + overflow-y: visible; + } + .navbar-fixed-top .navbar-collapse, + .navbar-static-top .navbar-collapse, + .navbar-fixed-bottom .navbar-collapse { + padding-right: 0; + padding-left: 0; + } +} +.navbar-fixed-top .navbar-collapse, +.navbar-fixed-bottom .navbar-collapse { + max-height: 340px; +} +@media (max-device-width: 480px) and (orientation: landscape) { + .navbar-fixed-top .navbar-collapse, + .navbar-fixed-bottom .navbar-collapse { + max-height: 200px; + } +} +.container > .navbar-header, +.container-fluid > .navbar-header, +.container > .navbar-collapse, +.container-fluid > .navbar-collapse { + margin-right: -15px; + margin-left: -15px; +} +@media (min-width: 768px) { + .container > .navbar-header, + .container-fluid > .navbar-header, + .container > .navbar-collapse, + .container-fluid > .navbar-collapse { + margin-right: 0; + margin-left: 0; + } +} +.navbar-static-top { + z-index: 1000; + border-width: 0 0 1px; +} +@media (min-width: 768px) { + .navbar-static-top { + border-radius: 0; + } +} +.navbar-fixed-top, +.navbar-fixed-bottom { + position: fixed; + right: 0; + left: 0; + z-index: 1030; +} +@media (min-width: 768px) { + .navbar-fixed-top, + .navbar-fixed-bottom { + border-radius: 0; + } +} +.navbar-fixed-top { + top: 0; + border-width: 0 0 1px; +} +.navbar-fixed-bottom { + bottom: 0; + margin-bottom: 0; + border-width: 1px 0 0; +} +.navbar-brand { + float: left; + height: 50px; + padding: 15px 15px; + font-size: 18px; + line-height: 20px; +} +.navbar-brand:hover, +.navbar-brand:focus { + text-decoration: none; +} +.navbar-brand > img { + display: block; +} +@media (min-width: 768px) { + .navbar > .container .navbar-brand, + .navbar > .container-fluid .navbar-brand { + margin-left: -15px; + } +} +.navbar-toggle { + position: relative; + float: right; + padding: 9px 10px; + margin-top: 8px; + margin-right: 15px; + margin-bottom: 8px; + background-color: transparent; + background-image: none; + border: 1px solid transparent; + border-radius: 4px; +} +.navbar-toggle:focus { + outline: 0; +} +.navbar-toggle .icon-bar { + display: block; + width: 22px; + height: 2px; + border-radius: 1px; +} +.navbar-toggle .icon-bar + .icon-bar { + margin-top: 4px; +} +@media (min-width: 768px) { + .navbar-toggle { + display: none; + } +} +.navbar-nav { + margin: 7.5px -15px; +} +.navbar-nav > li > a { + padding-top: 10px; + padding-bottom: 10px; + line-height: 20px; +} +@media (max-width: 767px) { + .navbar-nav .open .dropdown-menu { + position: static; + float: none; + width: auto; + margin-top: 0; + background-color: transparent; + border: 0; + -webkit-box-shadow: none; + box-shadow: none; + } + .navbar-nav .open .dropdown-menu > li > a, + .navbar-nav .open .dropdown-menu .dropdown-header { + padding: 5px 15px 5px 25px; + } + .navbar-nav .open .dropdown-menu > li > a { + line-height: 20px; + } + .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-nav .open .dropdown-menu > li > a:focus { + background-image: none; + } +} +@media (min-width: 768px) { + .navbar-nav { + float: left; + margin: 0; + } + .navbar-nav > li { + float: left; + } + .navbar-nav > li > a { + padding-top: 15px; + padding-bottom: 15px; + } +} +.navbar-form { + padding: 10px 15px; + margin-top: 8px; + margin-right: -15px; + margin-bottom: 8px; + margin-left: -15px; + border-top: 1px solid transparent; + border-bottom: 1px solid transparent; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1); +} +@media (min-width: 768px) { + .navbar-form .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .form-control { + display: inline-block; + width: auto; + vertical-align: middle; + } + .navbar-form .form-control-static { + display: inline-block; + } + .navbar-form .input-group { + display: inline-table; + vertical-align: middle; + } + .navbar-form .input-group .input-group-addon, + .navbar-form .input-group .input-group-btn, + .navbar-form .input-group .form-control { + width: auto; + } + .navbar-form .input-group > .form-control { + width: 100%; + } + .navbar-form .control-label { + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .radio, + .navbar-form .checkbox { + display: inline-block; + margin-top: 0; + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .radio label, + .navbar-form .checkbox label { + padding-left: 0; + } + .navbar-form .radio input[type="radio"], + .navbar-form .checkbox input[type="checkbox"] { + position: relative; + margin-left: 0; + } + .navbar-form .has-feedback .form-control-feedback { + top: 0; + } +} +@media (max-width: 767px) { + .navbar-form .form-group { + margin-bottom: 5px; + } + .navbar-form .form-group:last-child { + margin-bottom: 0; + } +} +@media (min-width: 768px) { + .navbar-form { + width: auto; + padding-top: 0; + padding-bottom: 0; + margin-right: 0; + margin-left: 0; + border: 0; + -webkit-box-shadow: none; + box-shadow: none; + } +} +.navbar-nav > li > .dropdown-menu { + margin-top: 0; + border-top-left-radius: 0; + border-top-right-radius: 0; +} +.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu { + margin-bottom: 0; + border-top-left-radius: 4px; + border-top-right-radius: 4px; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.navbar-btn { + margin-top: 8px; + margin-bottom: 8px; +} +.navbar-btn.btn-sm { + margin-top: 10px; + margin-bottom: 10px; +} +.navbar-btn.btn-xs { + margin-top: 14px; + margin-bottom: 14px; +} +.navbar-text { + margin-top: 15px; + margin-bottom: 15px; +} +@media (min-width: 768px) { + .navbar-text { + float: left; + margin-right: 15px; + margin-left: 15px; + } +} +@media (min-width: 768px) { + .navbar-left { + float: left !important; + } + .navbar-right { + float: right !important; + margin-right: -15px; + } + .navbar-right ~ .navbar-right { + margin-right: 0; + } +} +.navbar-default { + background-color: #f8f8f8; + border-color: #e7e7e7; +} +.navbar-default .navbar-brand { + color: #777; +} +.navbar-default .navbar-brand:hover, +.navbar-default .navbar-brand:focus { + color: #5e5e5e; + background-color: transparent; +} +.navbar-default .navbar-text { + color: #777; +} +.navbar-default .navbar-nav > li > a { + color: #777; +} +.navbar-default .navbar-nav > li > a:hover, +.navbar-default .navbar-nav > li > a:focus { + color: #333; + background-color: transparent; +} +.navbar-default .navbar-nav > .active > a, +.navbar-default .navbar-nav > .active > a:hover, +.navbar-default .navbar-nav > .active > a:focus { + color: #555; + background-color: #e7e7e7; +} +.navbar-default .navbar-nav > .disabled > a, +.navbar-default .navbar-nav > .disabled > a:hover, +.navbar-default .navbar-nav > .disabled > a:focus { + color: #ccc; + background-color: transparent; +} +.navbar-default .navbar-toggle { + border-color: #ddd; +} +.navbar-default .navbar-toggle:hover, +.navbar-default .navbar-toggle:focus { + background-color: #ddd; +} +.navbar-default .navbar-toggle .icon-bar { + background-color: #888; +} +.navbar-default .navbar-collapse, +.navbar-default .navbar-form { + border-color: #e7e7e7; +} +.navbar-default .navbar-nav > .open > a, +.navbar-default .navbar-nav > .open > a:hover, +.navbar-default .navbar-nav > .open > a:focus { + color: #555; + background-color: #e7e7e7; +} +@media (max-width: 767px) { + .navbar-default .navbar-nav .open .dropdown-menu > li > a { + color: #777; + } + .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus { + color: #333; + background-color: transparent; + } + .navbar-default .navbar-nav .open .dropdown-menu > .active > a, + .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #555; + background-color: #e7e7e7; + } + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a, + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus { + color: #ccc; + background-color: transparent; + } +} +.navbar-default .navbar-link { + color: #777; +} +.navbar-default .navbar-link:hover { + color: #333; +} +.navbar-default .btn-link { + color: #777; +} +.navbar-default .btn-link:hover, +.navbar-default .btn-link:focus { + color: #333; +} +.navbar-default .btn-link[disabled]:hover, +fieldset[disabled] .navbar-default .btn-link:hover, +.navbar-default .btn-link[disabled]:focus, +fieldset[disabled] .navbar-default .btn-link:focus { + color: #ccc; +} +.navbar-inverse { + background-color: #222; + border-color: #080808; +} +.navbar-inverse .navbar-brand { + color: #9d9d9d; +} +.navbar-inverse .navbar-brand:hover, +.navbar-inverse .navbar-brand:focus { + color: #fff; + background-color: transparent; +} +.navbar-inverse .navbar-text { + color: #9d9d9d; +} +.navbar-inverse .navbar-nav > li > a { + color: #9d9d9d; +} +.navbar-inverse .navbar-nav > li > a:hover, +.navbar-inverse .navbar-nav > li > a:focus { + color: #fff; + background-color: transparent; +} +.navbar-inverse .navbar-nav > .active > a, +.navbar-inverse .navbar-nav > .active > a:hover, +.navbar-inverse .navbar-nav > .active > a:focus { + color: #fff; + background-color: #080808; +} +.navbar-inverse .navbar-nav > .disabled > a, +.navbar-inverse .navbar-nav > .disabled > a:hover, +.navbar-inverse .navbar-nav > .disabled > a:focus { + color: #444; + background-color: transparent; +} +.navbar-inverse .navbar-toggle { + border-color: #333; +} +.navbar-inverse .navbar-toggle:hover, +.navbar-inverse .navbar-toggle:focus { + background-color: #333; +} +.navbar-inverse .navbar-toggle .icon-bar { + background-color: #fff; +} +.navbar-inverse .navbar-collapse, +.navbar-inverse .navbar-form { + border-color: #101010; +} +.navbar-inverse .navbar-nav > .open > a, +.navbar-inverse .navbar-nav > .open > a:hover, +.navbar-inverse .navbar-nav > .open > a:focus { + color: #fff; + background-color: #080808; +} +@media (max-width: 767px) { + .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header { + border-color: #080808; + } + .navbar-inverse .navbar-nav .open .dropdown-menu .divider { + background-color: #080808; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a { + color: #9d9d9d; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus { + color: #fff; + background-color: transparent; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a, + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #fff; + background-color: #080808; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a, + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus { + color: #444; + background-color: transparent; + } +} +.navbar-inverse .navbar-link { + color: #9d9d9d; +} +.navbar-inverse .navbar-link:hover { + color: #fff; +} +.navbar-inverse .btn-link { + color: #9d9d9d; +} +.navbar-inverse .btn-link:hover, +.navbar-inverse .btn-link:focus { + color: #fff; +} +.navbar-inverse .btn-link[disabled]:hover, +fieldset[disabled] .navbar-inverse .btn-link:hover, +.navbar-inverse .btn-link[disabled]:focus, +fieldset[disabled] .navbar-inverse .btn-link:focus { + color: #444; +} +.breadcrumb { + padding: 8px 15px; + margin-bottom: 20px; + list-style: none; + background-color: #f5f5f5; + border-radius: 4px; +} +.breadcrumb > li { + display: inline-block; +} +.breadcrumb > li + li:before { + padding: 0 5px; + color: #ccc; + content: "/\00a0"; +} +.breadcrumb > .active { + color: #777; +} +.pagination { + display: inline-block; + padding-left: 0; + margin: 20px 0; + border-radius: 4px; +} +.pagination > li { + display: inline; +} +.pagination > li > a, +.pagination > li > span { + position: relative; + float: left; + padding: 6px 12px; + margin-left: -1px; + line-height: 1.42857143; + color: #337ab7; + text-decoration: none; + background-color: #fff; + border: 1px solid #ddd; +} +.pagination > li:first-child > a, +.pagination > li:first-child > span { + margin-left: 0; + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; +} +.pagination > li:last-child > a, +.pagination > li:last-child > span { + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; +} +.pagination > li > a:hover, +.pagination > li > span:hover, +.pagination > li > a:focus, +.pagination > li > span:focus { + color: #23527c; + background-color: #eee; + border-color: #ddd; +} +.pagination > .active > a, +.pagination > .active > span, +.pagination > .active > a:hover, +.pagination > .active > span:hover, +.pagination > .active > a:focus, +.pagination > .active > span:focus { + z-index: 2; + color: #fff; + cursor: default; + background-color: #337ab7; + border-color: #337ab7; +} +.pagination > .disabled > span, +.pagination > .disabled > span:hover, +.pagination > .disabled > span:focus, +.pagination > .disabled > a, +.pagination > .disabled > a:hover, +.pagination > .disabled > a:focus { + color: #777; + cursor: not-allowed; + background-color: #fff; + border-color: #ddd; +} +.pagination-lg > li > a, +.pagination-lg > li > span { + padding: 10px 16px; + font-size: 18px; +} +.pagination-lg > li:first-child > a, +.pagination-lg > li:first-child > span { + border-top-left-radius: 6px; + border-bottom-left-radius: 6px; +} +.pagination-lg > li:last-child > a, +.pagination-lg > li:last-child > span { + border-top-right-radius: 6px; + border-bottom-right-radius: 6px; +} +.pagination-sm > li > a, +.pagination-sm > li > span { + padding: 5px 10px; + font-size: 12px; +} +.pagination-sm > li:first-child > a, +.pagination-sm > li:first-child > span { + border-top-left-radius: 3px; + border-bottom-left-radius: 3px; +} +.pagination-sm > li:last-child > a, +.pagination-sm > li:last-child > span { + border-top-right-radius: 3px; + border-bottom-right-radius: 3px; +} +.pager { + padding-left: 0; + margin: 20px 0; + text-align: center; + list-style: none; +} +.pager li { + display: inline; +} +.pager li > a, +.pager li > span { + display: inline-block; + padding: 5px 14px; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 15px; +} +.pager li > a:hover, +.pager li > a:focus { + text-decoration: none; + background-color: #eee; +} +.pager .next > a, +.pager .next > span { + float: right; +} +.pager .previous > a, +.pager .previous > span { + float: left; +} +.pager .disabled > a, +.pager .disabled > a:hover, +.pager .disabled > a:focus, +.pager .disabled > span { + color: #777; + cursor: not-allowed; + background-color: #fff; +} +.label { + display: inline; + padding: .2em .6em .3em; + font-size: 75%; + font-weight: bold; + line-height: 1; + color: #fff; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: .25em; +} +a.label:hover, +a.label:focus { + color: #fff; + text-decoration: none; + cursor: pointer; +} +.label:empty { + display: none; +} +.btn .label { + position: relative; + top: -1px; +} +.label-default { + background-color: #777; +} +.label-default[href]:hover, +.label-default[href]:focus { + background-color: #5e5e5e; +} +.label-primary { + background-color: #337ab7; +} +.label-primary[href]:hover, +.label-primary[href]:focus { + background-color: #286090; +} +.label-success { + background-color: #5cb85c; +} +.label-success[href]:hover, +.label-success[href]:focus { + background-color: #449d44; +} +.label-info { + background-color: #5bc0de; +} +.label-info[href]:hover, +.label-info[href]:focus { + background-color: #31b0d5; +} +.label-warning { + background-color: #f0ad4e; +} +.label-warning[href]:hover, +.label-warning[href]:focus { + background-color: #ec971f; +} +.label-danger { + background-color: #d9534f; +} +.label-danger[href]:hover, +.label-danger[href]:focus { + background-color: #c9302c; +} +.badge { + display: inline-block; + min-width: 10px; + padding: 3px 7px; + font-size: 12px; + font-weight: bold; + line-height: 1; + color: #fff; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + background-color: #777; + border-radius: 10px; +} +.badge:empty { + display: none; +} +.btn .badge { + position: relative; + top: -1px; +} +.btn-xs .badge { + top: 0; + padding: 1px 5px; +} +a.badge:hover, +a.badge:focus { + color: #fff; + text-decoration: none; + cursor: pointer; +} +.list-group-item.active > .badge, +.nav-pills > .active > a > .badge { + color: #337ab7; + background-color: #fff; +} +.list-group-item > .badge { + float: right; +} +.list-group-item > .badge + .badge { + margin-right: 5px; +} +.nav-pills > li > a > .badge { + margin-left: 3px; +} +.jumbotron { + padding: 30px 15px; + margin-bottom: 30px; + color: inherit; + background-color: #eee; +} +.jumbotron h1, +.jumbotron .h1 { + color: inherit; +} +.jumbotron p { + margin-bottom: 15px; + font-size: 21px; + font-weight: 200; +} +.jumbotron > hr { + border-top-color: #d5d5d5; +} +.container .jumbotron, +.container-fluid .jumbotron { + border-radius: 6px; +} +.jumbotron .container { + max-width: 100%; +} +@media screen and (min-width: 768px) { + .jumbotron { + padding: 48px 0; + } + .container .jumbotron, + .container-fluid .jumbotron { + padding-right: 60px; + padding-left: 60px; + } + .jumbotron h1, + .jumbotron .h1 { + font-size: 63px; + } +} +.thumbnail { + display: block; + padding: 4px; + margin-bottom: 20px; + line-height: 1.42857143; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 4px; + -webkit-transition: border .2s ease-in-out; + -o-transition: border .2s ease-in-out; + transition: border .2s ease-in-out; +} +.thumbnail > img, +.thumbnail a > img { + margin-right: auto; + margin-left: auto; +} +a.thumbnail:hover, +a.thumbnail:focus, +a.thumbnail.active { + border-color: #337ab7; +} +.thumbnail .caption { + padding: 9px; + color: #333; +} +.alert { + padding: 15px; + margin-bottom: 20px; + border: 1px solid transparent; + border-radius: 4px; +} +.alert h4 { + margin-top: 0; + color: inherit; +} +.alert .alert-link { + font-weight: bold; +} +.alert > p, +.alert > ul { + margin-bottom: 0; +} +.alert > p + p { + margin-top: 5px; +} +.alert-dismissable, +.alert-dismissible { + padding-right: 35px; +} +.alert-dismissable .close, +.alert-dismissible .close { + position: relative; + top: -2px; + right: -21px; + color: inherit; +} +.alert-success { + color: #3c763d; + background-color: #dff0d8; + border-color: #d6e9c6; +} +.alert-success hr { + border-top-color: #c9e2b3; +} +.alert-success .alert-link { + color: #2b542c; +} +.alert-info { + color: #31708f; + background-color: #d9edf7; + border-color: #bce8f1; +} +.alert-info hr { + border-top-color: #a6e1ec; +} +.alert-info .alert-link { + color: #245269; +} +.alert-warning { + color: #8a6d3b; + background-color: #fcf8e3; + border-color: #faebcc; +} +.alert-warning hr { + border-top-color: #f7e1b5; +} +.alert-warning .alert-link { + color: #66512c; +} +.alert-danger { + color: #a94442; + background-color: #f2dede; + border-color: #ebccd1; +} +.alert-danger hr { + border-top-color: #e4b9c0; +} +.alert-danger .alert-link { + color: #843534; +} +@-webkit-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@-o-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +.progress { + height: 20px; + margin-bottom: 20px; + overflow: hidden; + background-color: #f5f5f5; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1); +} +.progress-bar { + float: left; + width: 0; + height: 100%; + font-size: 12px; + line-height: 20px; + color: #fff; + text-align: center; + background-color: #337ab7; + -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15); + -webkit-transition: width .6s ease; + -o-transition: width .6s ease; + transition: width .6s ease; +} +.progress-striped .progress-bar, +.progress-bar-striped { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + -webkit-background-size: 40px 40px; + background-size: 40px 40px; +} +.progress.active .progress-bar, +.progress-bar.active { + -webkit-animation: progress-bar-stripes 2s linear infinite; + -o-animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; +} +.progress-bar-success { + background-color: #5cb85c; +} +.progress-striped .progress-bar-success { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); +} +.progress-bar-info { + background-color: #5bc0de; +} +.progress-striped .progress-bar-info { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); +} +.progress-bar-warning { + background-color: #f0ad4e; +} +.progress-striped .progress-bar-warning { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); +} +.progress-bar-danger { + background-color: #d9534f; +} +.progress-striped .progress-bar-danger { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); +} +.media { + margin-top: 15px; +} +.media:first-child { + margin-top: 0; +} +.media, +.media-body { + overflow: hidden; + zoom: 1; +} +.media-body { + width: 10000px; +} +.media-object { + display: block; +} +.media-right, +.media > .pull-right { + padding-left: 10px; +} +.media-left, +.media > .pull-left { + padding-right: 10px; +} +.media-left, +.media-right, +.media-body { + display: table-cell; + vertical-align: top; +} +.media-middle { + vertical-align: middle; +} +.media-bottom { + vertical-align: bottom; +} +.media-heading { + margin-top: 0; + margin-bottom: 5px; +} +.media-list { + padding-left: 0; + list-style: none; +} +.list-group { + padding-left: 0; + margin-bottom: 20px; +} +.list-group-item { + position: relative; + display: block; + padding: 10px 15px; + margin-bottom: -1px; + background-color: #fff; + border: 1px solid #ddd; +} +.list-group-item:first-child { + border-top-left-radius: 4px; + border-top-right-radius: 4px; +} +.list-group-item:last-child { + margin-bottom: 0; + border-bottom-right-radius: 4px; + border-bottom-left-radius: 4px; +} +a.list-group-item { + color: #555; +} +a.list-group-item .list-group-item-heading { + color: #333; +} +a.list-group-item:hover, +a.list-group-item:focus { + color: #555; + text-decoration: none; + background-color: #f5f5f5; +} +.list-group-item.disabled, +.list-group-item.disabled:hover, +.list-group-item.disabled:focus { + color: #777; + cursor: not-allowed; + background-color: #eee; +} +.list-group-item.disabled .list-group-item-heading, +.list-group-item.disabled:hover .list-group-item-heading, +.list-group-item.disabled:focus .list-group-item-heading { + color: inherit; +} +.list-group-item.disabled .list-group-item-text, +.list-group-item.disabled:hover .list-group-item-text, +.list-group-item.disabled:focus .list-group-item-text { + color: #777; +} +.list-group-item.active, +.list-group-item.active:hover, +.list-group-item.active:focus { + z-index: 2; + color: #fff; + background-color: #337ab7; + border-color: #337ab7; +} +.list-group-item.active .list-group-item-heading, +.list-group-item.active:hover .list-group-item-heading, +.list-group-item.active:focus .list-group-item-heading, +.list-group-item.active .list-group-item-heading > small, +.list-group-item.active:hover .list-group-item-heading > small, +.list-group-item.active:focus .list-group-item-heading > small, +.list-group-item.active .list-group-item-heading > .small, +.list-group-item.active:hover .list-group-item-heading > .small, +.list-group-item.active:focus .list-group-item-heading > .small { + color: inherit; +} +.list-group-item.active .list-group-item-text, +.list-group-item.active:hover .list-group-item-text, +.list-group-item.active:focus .list-group-item-text { + color: #c7ddef; +} +.list-group-item-success { + color: #3c763d; + background-color: #dff0d8; +} +a.list-group-item-success { + color: #3c763d; +} +a.list-group-item-success .list-group-item-heading { + color: inherit; +} +a.list-group-item-success:hover, +a.list-group-item-success:focus { + color: #3c763d; + background-color: #d0e9c6; +} +a.list-group-item-success.active, +a.list-group-item-success.active:hover, +a.list-group-item-success.active:focus { + color: #fff; + background-color: #3c763d; + border-color: #3c763d; +} +.list-group-item-info { + color: #31708f; + background-color: #d9edf7; +} +a.list-group-item-info { + color: #31708f; +} +a.list-group-item-info .list-group-item-heading { + color: inherit; +} +a.list-group-item-info:hover, +a.list-group-item-info:focus { + color: #31708f; + background-color: #c4e3f3; +} +a.list-group-item-info.active, +a.list-group-item-info.active:hover, +a.list-group-item-info.active:focus { + color: #fff; + background-color: #31708f; + border-color: #31708f; +} +.list-group-item-warning { + color: #8a6d3b; + background-color: #fcf8e3; +} +a.list-group-item-warning { + color: #8a6d3b; +} +a.list-group-item-warning .list-group-item-heading { + color: inherit; +} +a.list-group-item-warning:hover, +a.list-group-item-warning:focus { + color: #8a6d3b; + background-color: #faf2cc; +} +a.list-group-item-warning.active, +a.list-group-item-warning.active:hover, +a.list-group-item-warning.active:focus { + color: #fff; + background-color: #8a6d3b; + border-color: #8a6d3b; +} +.list-group-item-danger { + color: #a94442; + background-color: #f2dede; +} +a.list-group-item-danger { + color: #a94442; +} +a.list-group-item-danger .list-group-item-heading { + color: inherit; +} +a.list-group-item-danger:hover, +a.list-group-item-danger:focus { + color: #a94442; + background-color: #ebcccc; +} +a.list-group-item-danger.active, +a.list-group-item-danger.active:hover, +a.list-group-item-danger.active:focus { + color: #fff; + background-color: #a94442; + border-color: #a94442; +} +.list-group-item-heading { + margin-top: 0; + margin-bottom: 5px; +} +.list-group-item-text { + margin-bottom: 0; + line-height: 1.3; +} +.panel { + margin-bottom: 20px; + background-color: #fff; + border: 1px solid transparent; + border-radius: 4px; + -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .05); + box-shadow: 0 1px 1px rgba(0, 0, 0, .05); +} +.panel-body { + padding: 15px; +} +.panel-heading { + padding: 10px 15px; + border-bottom: 1px solid transparent; + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} +.panel-heading > .dropdown .dropdown-toggle { + color: inherit; +} +.panel-title { + margin-top: 0; + margin-bottom: 0; + font-size: 16px; + color: inherit; +} +.panel-title > a, +.panel-title > small, +.panel-title > .small, +.panel-title > small > a, +.panel-title > .small > a { + color: inherit; +} +.panel-footer { + padding: 10px 15px; + background-color: #f5f5f5; + border-top: 1px solid #ddd; + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel > .list-group, +.panel > .panel-collapse > .list-group { + margin-bottom: 0; +} +.panel > .list-group .list-group-item, +.panel > .panel-collapse > .list-group .list-group-item { + border-width: 1px 0; + border-radius: 0; +} +.panel > .list-group:first-child .list-group-item:first-child, +.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child { + border-top: 0; + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} +.panel > .list-group:last-child .list-group-item:last-child, +.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child { + border-bottom: 0; + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel-heading + .list-group .list-group-item:first-child { + border-top-width: 0; +} +.list-group + .panel-footer { + border-top-width: 0; +} +.panel > .table, +.panel > .table-responsive > .table, +.panel > .panel-collapse > .table { + margin-bottom: 0; +} +.panel > .table caption, +.panel > .table-responsive > .table caption, +.panel > .panel-collapse > .table caption { + padding-right: 15px; + padding-left: 15px; +} +.panel > .table:first-child, +.panel > .table-responsive:first-child > .table:first-child { + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} +.panel > .table:first-child > thead:first-child > tr:first-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child, +.panel > .table:first-child > tbody:first-child > tr:first-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child { + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} +.panel > .table:first-child > thead:first-child > tr:first-child td:first-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child, +.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child, +.panel > .table:first-child > thead:first-child > tr:first-child th:first-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child, +.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child { + border-top-left-radius: 3px; +} +.panel > .table:first-child > thead:first-child > tr:first-child td:last-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child, +.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child, +.panel > .table:first-child > thead:first-child > tr:first-child th:last-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child, +.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child { + border-top-right-radius: 3px; +} +.panel > .table:last-child, +.panel > .table-responsive:last-child > .table:last-child { + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel > .table:last-child > tbody:last-child > tr:last-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child { + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child, +.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child { + border-bottom-left-radius: 3px; +} +.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child, +.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child { + border-bottom-right-radius: 3px; +} +.panel > .panel-body + .table, +.panel > .panel-body + .table-responsive, +.panel > .table + .panel-body, +.panel > .table-responsive + .panel-body { + border-top: 1px solid #ddd; +} +.panel > .table > tbody:first-child > tr:first-child th, +.panel > .table > tbody:first-child > tr:first-child td { + border-top: 0; +} +.panel > .table-bordered, +.panel > .table-responsive > .table-bordered { + border: 0; +} +.panel > .table-bordered > thead > tr > th:first-child, +.panel > .table-responsive > .table-bordered > thead > tr > th:first-child, +.panel > .table-bordered > tbody > tr > th:first-child, +.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child, +.panel > .table-bordered > tfoot > tr > th:first-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child, +.panel > .table-bordered > thead > tr > td:first-child, +.panel > .table-responsive > .table-bordered > thead > tr > td:first-child, +.panel > .table-bordered > tbody > tr > td:first-child, +.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child, +.panel > .table-bordered > tfoot > tr > td:first-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child { + border-left: 0; +} +.panel > .table-bordered > thead > tr > th:last-child, +.panel > .table-responsive > .table-bordered > thead > tr > th:last-child, +.panel > .table-bordered > tbody > tr > th:last-child, +.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child, +.panel > .table-bordered > tfoot > tr > th:last-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child, +.panel > .table-bordered > thead > tr > td:last-child, +.panel > .table-responsive > .table-bordered > thead > tr > td:last-child, +.panel > .table-bordered > tbody > tr > td:last-child, +.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child, +.panel > .table-bordered > tfoot > tr > td:last-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child { + border-right: 0; +} +.panel > .table-bordered > thead > tr:first-child > td, +.panel > .table-responsive > .table-bordered > thead > tr:first-child > td, +.panel > .table-bordered > tbody > tr:first-child > td, +.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td, +.panel > .table-bordered > thead > tr:first-child > th, +.panel > .table-responsive > .table-bordered > thead > tr:first-child > th, +.panel > .table-bordered > tbody > tr:first-child > th, +.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th { + border-bottom: 0; +} +.panel > .table-bordered > tbody > tr:last-child > td, +.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td, +.panel > .table-bordered > tfoot > tr:last-child > td, +.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td, +.panel > .table-bordered > tbody > tr:last-child > th, +.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th, +.panel > .table-bordered > tfoot > tr:last-child > th, +.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th { + border-bottom: 0; +} +.panel > .table-responsive { + margin-bottom: 0; + border: 0; +} +.panel-group { + margin-bottom: 20px; +} +.panel-group .panel { + margin-bottom: 0; + border-radius: 4px; +} +.panel-group .panel + .panel { + margin-top: 5px; +} +.panel-group .panel-heading { + border-bottom: 0; +} +.panel-group .panel-heading + .panel-collapse > .panel-body, +.panel-group .panel-heading + .panel-collapse > .list-group { + border-top: 1px solid #ddd; +} +.panel-group .panel-footer { + border-top: 0; +} +.panel-group .panel-footer + .panel-collapse .panel-body { + border-bottom: 1px solid #ddd; +} +.panel-default { + border-color: #ddd; +} +.panel-default > .panel-heading { + color: #333; + background-color: #f5f5f5; + border-color: #ddd; +} +.panel-default > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #ddd; +} +.panel-default > .panel-heading .badge { + color: #f5f5f5; + background-color: #333; +} +.panel-default > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #ddd; +} +.panel-primary { + border-color: #337ab7; +} +.panel-primary > .panel-heading { + color: #fff; + background-color: #337ab7; + border-color: #337ab7; +} +.panel-primary > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #337ab7; +} +.panel-primary > .panel-heading .badge { + color: #337ab7; + background-color: #fff; +} +.panel-primary > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #337ab7; +} +.panel-success { + border-color: #d6e9c6; +} +.panel-success > .panel-heading { + color: #3c763d; + background-color: #dff0d8; + border-color: #d6e9c6; +} +.panel-success > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #d6e9c6; +} +.panel-success > .panel-heading .badge { + color: #dff0d8; + background-color: #3c763d; +} +.panel-success > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #d6e9c6; +} +.panel-info { + border-color: #bce8f1; +} +.panel-info > .panel-heading { + color: #31708f; + background-color: #d9edf7; + border-color: #bce8f1; +} +.panel-info > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #bce8f1; +} +.panel-info > .panel-heading .badge { + color: #d9edf7; + background-color: #31708f; +} +.panel-info > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #bce8f1; +} +.panel-warning { + border-color: #faebcc; +} +.panel-warning > .panel-heading { + color: #8a6d3b; + background-color: #fcf8e3; + border-color: #faebcc; +} +.panel-warning > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #faebcc; +} +.panel-warning > .panel-heading .badge { + color: #fcf8e3; + background-color: #8a6d3b; +} +.panel-warning > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #faebcc; +} +.panel-danger { + border-color: #ebccd1; +} +.panel-danger > .panel-heading { + color: #a94442; + background-color: #f2dede; + border-color: #ebccd1; +} +.panel-danger > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #ebccd1; +} +.panel-danger > .panel-heading .badge { + color: #f2dede; + background-color: #a94442; +} +.panel-danger > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #ebccd1; +} +.embed-responsive { + position: relative; + display: block; + height: 0; + padding: 0; + overflow: hidden; +} +.embed-responsive .embed-responsive-item, +.embed-responsive iframe, +.embed-responsive embed, +.embed-responsive object, +.embed-responsive video { + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + border: 0; +} +.embed-responsive.embed-responsive-16by9 { + padding-bottom: 56.25%; +} +.embed-responsive.embed-responsive-4by3 { + padding-bottom: 75%; +} +.well { + min-height: 20px; + padding: 19px; + margin-bottom: 20px; + background-color: #f5f5f5; + border: 1px solid #e3e3e3; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05); +} +.well blockquote { + border-color: #ddd; + border-color: rgba(0, 0, 0, .15); +} +.well-lg { + padding: 24px; + border-radius: 6px; +} +.well-sm { + padding: 9px; + border-radius: 3px; +} +.close { + float: right; + font-size: 21px; + font-weight: bold; + line-height: 1; + color: #000; + text-shadow: 0 1px 0 #fff; + filter: alpha(opacity=20); + opacity: .2; +} +.close:hover, +.close:focus { + color: #000; + text-decoration: none; + cursor: pointer; + filter: alpha(opacity=50); + opacity: .5; +} +button.close { + -webkit-appearance: none; + padding: 0; + cursor: pointer; + background: transparent; + border: 0; +} +.modal-open { + overflow: hidden; +} +.modal { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + display: none; + overflow: hidden; + -webkit-overflow-scrolling: touch; + outline: 0; +} +.modal.fade .modal-dialog { + -webkit-transition: -webkit-transform .3s ease-out; + -o-transition: -o-transform .3s ease-out; + transition: transform .3s ease-out; + -webkit-transform: translate(0, -25%); + -ms-transform: translate(0, -25%); + -o-transform: translate(0, -25%); + transform: translate(0, -25%); +} +.modal.in .modal-dialog { + -webkit-transform: translate(0, 0); + -ms-transform: translate(0, 0); + -o-transform: translate(0, 0); + transform: translate(0, 0); +} +.modal-open .modal { + overflow-x: hidden; + overflow-y: auto; +} +.modal-dialog { + position: relative; + width: auto; + margin: 10px; +} +.modal-content { + position: relative; + background-color: #fff; + -webkit-background-clip: padding-box; + background-clip: padding-box; + border: 1px solid #999; + border: 1px solid rgba(0, 0, 0, .2); + border-radius: 6px; + outline: 0; + -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, .5); + box-shadow: 0 3px 9px rgba(0, 0, 0, .5); +} +.modal-backdrop { + position: absolute; + top: 0; + right: 0; + left: 0; + background-color: #000; +} +.modal-backdrop.fade { + filter: alpha(opacity=0); + opacity: 0; +} +.modal-backdrop.in { + filter: alpha(opacity=50); + opacity: .5; +} +.modal-header { + min-height: 16.42857143px; + padding: 15px; + border-bottom: 1px solid #e5e5e5; +} +.modal-header .close { + margin-top: -2px; +} +.modal-title { + margin: 0; + line-height: 1.42857143; +} +.modal-body { + position: relative; + padding: 15px; +} +.modal-footer { + padding: 15px; + text-align: right; + border-top: 1px solid #e5e5e5; +} +.modal-footer .btn + .btn { + margin-bottom: 0; + margin-left: 5px; +} +.modal-footer .btn-group .btn + .btn { + margin-left: -1px; +} +.modal-footer .btn-block + .btn-block { + margin-left: 0; +} +.modal-scrollbar-measure { + position: absolute; + top: -9999px; + width: 50px; + height: 50px; + overflow: scroll; +} +@media (min-width: 768px) { + .modal-dialog { + width: 600px; + margin: 30px auto; + } + .modal-content { + -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, .5); + box-shadow: 0 5px 15px rgba(0, 0, 0, .5); + } + .modal-sm { + width: 300px; + } +} +@media (min-width: 992px) { + .modal-lg { + width: 900px; + } +} +.tooltip { + position: absolute; + z-index: 1070; + display: block; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 12px; + font-weight: normal; + line-height: 1.4; + visibility: visible; + filter: alpha(opacity=0); + opacity: 0; +} +.tooltip.in { + filter: alpha(opacity=90); + opacity: .9; +} +.tooltip.top { + padding: 5px 0; + margin-top: -3px; +} +.tooltip.right { + padding: 0 5px; + margin-left: 3px; +} +.tooltip.bottom { + padding: 5px 0; + margin-top: 3px; +} +.tooltip.left { + padding: 0 5px; + margin-left: -3px; +} +.tooltip-inner { + max-width: 200px; + padding: 3px 8px; + color: #fff; + text-align: center; + text-decoration: none; + background-color: #000; + border-radius: 4px; +} +.tooltip-arrow { + position: absolute; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} +.tooltip.top .tooltip-arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-width: 5px 5px 0; + border-top-color: #000; +} +.tooltip.top-left .tooltip-arrow { + right: 5px; + bottom: 0; + margin-bottom: -5px; + border-width: 5px 5px 0; + border-top-color: #000; +} +.tooltip.top-right .tooltip-arrow { + bottom: 0; + left: 5px; + margin-bottom: -5px; + border-width: 5px 5px 0; + border-top-color: #000; +} +.tooltip.right .tooltip-arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-width: 5px 5px 5px 0; + border-right-color: #000; +} +.tooltip.left .tooltip-arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-width: 5px 0 5px 5px; + border-left-color: #000; +} +.tooltip.bottom .tooltip-arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000; +} +.tooltip.bottom-left .tooltip-arrow { + top: 0; + right: 5px; + margin-top: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000; +} +.tooltip.bottom-right .tooltip-arrow { + top: 0; + left: 5px; + margin-top: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000; +} +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1060; + display: none; + max-width: 276px; + padding: 1px; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + font-weight: normal; + line-height: 1.42857143; + text-align: left; + white-space: normal; + background-color: #fff; + -webkit-background-clip: padding-box; + background-clip: padding-box; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, .2); + border-radius: 6px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2); + box-shadow: 0 5px 10px rgba(0, 0, 0, .2); +} +.popover.top { + margin-top: -10px; +} +.popover.right { + margin-left: 10px; +} +.popover.bottom { + margin-top: 10px; +} +.popover.left { + margin-left: -10px; +} +.popover-title { + padding: 8px 14px; + margin: 0; + font-size: 14px; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; + border-radius: 5px 5px 0 0; +} +.popover-content { + padding: 9px 14px; +} +.popover > .arrow, +.popover > .arrow:after { + position: absolute; + display: block; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} +.popover > .arrow { + border-width: 11px; +} +.popover > .arrow:after { + content: ""; + border-width: 10px; +} +.popover.top > .arrow { + bottom: -11px; + left: 50%; + margin-left: -11px; + border-top-color: #999; + border-top-color: rgba(0, 0, 0, .25); + border-bottom-width: 0; +} +.popover.top > .arrow:after { + bottom: 1px; + margin-left: -10px; + content: " "; + border-top-color: #fff; + border-bottom-width: 0; +} +.popover.right > .arrow { + top: 50%; + left: -11px; + margin-top: -11px; + border-right-color: #999; + border-right-color: rgba(0, 0, 0, .25); + border-left-width: 0; +} +.popover.right > .arrow:after { + bottom: -10px; + left: 1px; + content: " "; + border-right-color: #fff; + border-left-width: 0; +} +.popover.bottom > .arrow { + top: -11px; + left: 50%; + margin-left: -11px; + border-top-width: 0; + border-bottom-color: #999; + border-bottom-color: rgba(0, 0, 0, .25); +} +.popover.bottom > .arrow:after { + top: 1px; + margin-left: -10px; + content: " "; + border-top-width: 0; + border-bottom-color: #fff; +} +.popover.left > .arrow { + top: 50%; + right: -11px; + margin-top: -11px; + border-right-width: 0; + border-left-color: #999; + border-left-color: rgba(0, 0, 0, .25); +} +.popover.left > .arrow:after { + right: 1px; + bottom: -10px; + content: " "; + border-right-width: 0; + border-left-color: #fff; +} +.carousel { + position: relative; +} +.carousel-inner { + position: relative; + width: 100%; + overflow: hidden; +} +.carousel-inner > .item { + position: relative; + display: none; + -webkit-transition: .6s ease-in-out left; + -o-transition: .6s ease-in-out left; + transition: .6s ease-in-out left; +} +.carousel-inner > .item > img, +.carousel-inner > .item > a > img { + line-height: 1; +} +@media all and (transform-3d), (-webkit-transform-3d) { + .carousel-inner > .item { + -webkit-transition: -webkit-transform .6s ease-in-out; + -o-transition: -o-transform .6s ease-in-out; + transition: transform .6s ease-in-out; + + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + -webkit-perspective: 1000; + perspective: 1000; + } + .carousel-inner > .item.next, + .carousel-inner > .item.active.right { + left: 0; + -webkit-transform: translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0); + } + .carousel-inner > .item.prev, + .carousel-inner > .item.active.left { + left: 0; + -webkit-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); + } + .carousel-inner > .item.next.left, + .carousel-inner > .item.prev.right, + .carousel-inner > .item.active { + left: 0; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} +.carousel-inner > .active, +.carousel-inner > .next, +.carousel-inner > .prev { + display: block; +} +.carousel-inner > .active { + left: 0; +} +.carousel-inner > .next, +.carousel-inner > .prev { + position: absolute; + top: 0; + width: 100%; +} +.carousel-inner > .next { + left: 100%; +} +.carousel-inner > .prev { + left: -100%; +} +.carousel-inner > .next.left, +.carousel-inner > .prev.right { + left: 0; +} +.carousel-inner > .active.left { + left: -100%; +} +.carousel-inner > .active.right { + left: 100%; +} +.carousel-control { + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: 15%; + font-size: 20px; + color: #fff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, .6); + filter: alpha(opacity=50); + opacity: .5; +} +.carousel-control.left { + background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%); + background-image: -o-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%); + background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .5)), to(rgba(0, 0, 0, .0001))); + background-image: linear-gradient(to right, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1); + background-repeat: repeat-x; +} +.carousel-control.right { + right: 0; + left: auto; + background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%); + background-image: -o-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%); + background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .0001)), to(rgba(0, 0, 0, .5))); + background-image: linear-gradient(to right, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1); + background-repeat: repeat-x; +} +.carousel-control:hover, +.carousel-control:focus { + color: #fff; + text-decoration: none; + filter: alpha(opacity=90); + outline: 0; + opacity: .9; +} +.carousel-control .icon-prev, +.carousel-control .icon-next, +.carousel-control .glyphicon-chevron-left, +.carousel-control .glyphicon-chevron-right { + position: absolute; + top: 50%; + z-index: 5; + display: inline-block; +} +.carousel-control .icon-prev, +.carousel-control .glyphicon-chevron-left { + left: 50%; + margin-left: -10px; +} +.carousel-control .icon-next, +.carousel-control .glyphicon-chevron-right { + right: 50%; + margin-right: -10px; +} +.carousel-control .icon-prev, +.carousel-control .icon-next { + width: 20px; + height: 20px; + margin-top: -10px; + font-family: serif; + line-height: 1; +} +.carousel-control .icon-prev:before { + content: '\2039'; +} +.carousel-control .icon-next:before { + content: '\203a'; +} +.carousel-indicators { + position: absolute; + bottom: 10px; + left: 50%; + z-index: 15; + width: 60%; + padding-left: 0; + margin-left: -30%; + text-align: center; + list-style: none; +} +.carousel-indicators li { + display: inline-block; + width: 10px; + height: 10px; + margin: 1px; + text-indent: -999px; + cursor: pointer; + background-color: #000 \9; + background-color: rgba(0, 0, 0, 0); + border: 1px solid #fff; + border-radius: 10px; +} +.carousel-indicators .active { + width: 12px; + height: 12px; + margin: 0; + background-color: #fff; +} +.carousel-caption { + position: absolute; + right: 15%; + bottom: 20px; + left: 15%; + z-index: 10; + padding-top: 20px; + padding-bottom: 20px; + color: #fff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, .6); +} +.carousel-caption .btn { + text-shadow: none; +} +@media screen and (min-width: 768px) { + .carousel-control .glyphicon-chevron-left, + .carousel-control .glyphicon-chevron-right, + .carousel-control .icon-prev, + .carousel-control .icon-next { + width: 30px; + height: 30px; + margin-top: -15px; + font-size: 30px; + } + .carousel-control .glyphicon-chevron-left, + .carousel-control .icon-prev { + margin-left: -15px; + } + .carousel-control .glyphicon-chevron-right, + .carousel-control .icon-next { + margin-right: -15px; + } + .carousel-caption { + right: 20%; + left: 20%; + padding-bottom: 30px; + } + .carousel-indicators { + bottom: 20px; + } +} +.clearfix:before, +.clearfix:after, +.dl-horizontal dd:before, +.dl-horizontal dd:after, +.container:before, +.container:after, +.container-fluid:before, +.container-fluid:after, +.row:before, +.row:after, +.form-horizontal .form-group:before, +.form-horizontal .form-group:after, +.btn-toolbar:before, +.btn-toolbar:after, +.btn-group-vertical > .btn-group:before, +.btn-group-vertical > .btn-group:after, +.nav:before, +.nav:after, +.navbar:before, +.navbar:after, +.navbar-header:before, +.navbar-header:after, +.navbar-collapse:before, +.navbar-collapse:after, +.pager:before, +.pager:after, +.panel-body:before, +.panel-body:after, +.modal-footer:before, +.modal-footer:after { + display: table; + content: " "; +} +.clearfix:after, +.dl-horizontal dd:after, +.container:after, +.container-fluid:after, +.row:after, +.form-horizontal .form-group:after, +.btn-toolbar:after, +.btn-group-vertical > .btn-group:after, +.nav:after, +.navbar:after, +.navbar-header:after, +.navbar-collapse:after, +.pager:after, +.panel-body:after, +.modal-footer:after { + clear: both; +} +.center-block { + display: block; + margin-right: auto; + margin-left: auto; +} +.pull-right { + float: right !important; +} +.pull-left { + float: left !important; +} +.hide { + display: none !important; +} +.show { + display: block !important; +} +.invisible { + visibility: hidden; +} +.text-hide { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} +.hidden { + display: none !important; + visibility: hidden !important; +} +.affix { + position: fixed; +} +@-ms-viewport { + width: device-width; +} +.visible-xs, +.visible-sm, +.visible-md, +.visible-lg { + display: none !important; +} +.visible-xs-block, +.visible-xs-inline, +.visible-xs-inline-block, +.visible-sm-block, +.visible-sm-inline, +.visible-sm-inline-block, +.visible-md-block, +.visible-md-inline, +.visible-md-inline-block, +.visible-lg-block, +.visible-lg-inline, +.visible-lg-inline-block { + display: none !important; +} +@media (max-width: 767px) { + .visible-xs { + display: block !important; + } + table.visible-xs { + display: table; + } + tr.visible-xs { + display: table-row !important; + } + th.visible-xs, + td.visible-xs { + display: table-cell !important; + } +} +@media (max-width: 767px) { + .visible-xs-block { + display: block !important; + } +} +@media (max-width: 767px) { + .visible-xs-inline { + display: inline !important; + } +} +@media (max-width: 767px) { + .visible-xs-inline-block { + display: inline-block !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm { + display: block !important; + } + table.visible-sm { + display: table; + } + tr.visible-sm { + display: table-row !important; + } + th.visible-sm, + td.visible-sm { + display: table-cell !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm-block { + display: block !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm-inline { + display: inline !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm-inline-block { + display: inline-block !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md { + display: block !important; + } + table.visible-md { + display: table; + } + tr.visible-md { + display: table-row !important; + } + th.visible-md, + td.visible-md { + display: table-cell !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md-block { + display: block !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md-inline { + display: inline !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md-inline-block { + display: inline-block !important; + } +} +@media (min-width: 1200px) { + .visible-lg { + display: block !important; + } + table.visible-lg { + display: table; + } + tr.visible-lg { + display: table-row !important; + } + th.visible-lg, + td.visible-lg { + display: table-cell !important; + } +} +@media (min-width: 1200px) { + .visible-lg-block { + display: block !important; + } +} +@media (min-width: 1200px) { + .visible-lg-inline { + display: inline !important; + } +} +@media (min-width: 1200px) { + .visible-lg-inline-block { + display: inline-block !important; + } +} +@media (max-width: 767px) { + .hidden-xs { + display: none !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .hidden-sm { + display: none !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .hidden-md { + display: none !important; + } +} +@media (min-width: 1200px) { + .hidden-lg { + display: none !important; + } +} +.visible-print { + display: none !important; +} +@media print { + .visible-print { + display: block !important; + } + table.visible-print { + display: table; + } + tr.visible-print { + display: table-row !important; + } + th.visible-print, + td.visible-print { + display: table-cell !important; + } +} +.visible-print-block { + display: none !important; +} +@media print { + .visible-print-block { + display: block !important; + } +} +.visible-print-inline { + display: none !important; +} +@media print { + .visible-print-inline { + display: inline !important; + } +} +.visible-print-inline-block { + display: none !important; +} +@media print { + .visible-print-inline-block { + display: inline-block !important; + } +} +@media print { + .hidden-print { + display: none !important; + } +} +/*# sourceMappingURL=bootstrap.css.map */ diff --git a/views/default/css/bootstrap.css.map b/views/default/css/bootstrap.css.map new file mode 100644 index 0000000..ff579ff --- /dev/null +++ b/views/default/css/bootstrap.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["bootstrap.css","less/normalize.less","less/print.less","less/glyphicons.less","less/scaffolding.less","less/mixins/vendor-prefixes.less","less/mixins/tab-focus.less","less/mixins/image.less","less/type.less","less/mixins/text-emphasis.less","less/mixins/background-variant.less","less/mixins/text-overflow.less","less/code.less","less/grid.less","less/mixins/grid.less","less/mixins/grid-framework.less","less/tables.less","less/mixins/table-row.less","less/forms.less","less/mixins/forms.less","less/buttons.less","less/mixins/buttons.less","less/mixins/opacity.less","less/component-animations.less","less/dropdowns.less","less/mixins/nav-divider.less","less/mixins/reset-filter.less","less/button-groups.less","less/mixins/border-radius.less","less/input-groups.less","less/navs.less","less/navbar.less","less/mixins/nav-vertical-align.less","less/utilities.less","less/breadcrumbs.less","less/pagination.less","less/mixins/pagination.less","less/pager.less","less/labels.less","less/mixins/labels.less","less/badges.less","less/jumbotron.less","less/thumbnails.less","less/alerts.less","less/mixins/alerts.less","less/progress-bars.less","less/mixins/gradients.less","less/mixins/progress-bar.less","less/media.less","less/list-group.less","less/mixins/list-group.less","less/panels.less","less/mixins/panels.less","less/responsive-embed.less","less/wells.less","less/close.less","less/modals.less","less/tooltip.less","less/popovers.less","less/carousel.less","less/mixins/clearfix.less","less/mixins/center-block.less","less/mixins/hide-text.less","less/responsive-utilities.less","less/mixins/responsive-visibility.less"],"names":[],"mappings":"AAAA,6DAA4D;ACQ5D;EACE,yBAAA;EACA,4BAAA;EACA,gCAAA;EDND;ACaD;EACE,WAAA;EDXD;ACwBD;;;;;;;;;;;;;EAaE,gBAAA;EDtBD;AC8BD;;;;EAIE,uBAAA;EACA,0BAAA;ED5BD;ACoCD;EACE,eAAA;EACA,WAAA;EDlCD;AC0CD;;EAEE,eAAA;EDxCD;ACkDD;EACE,+BAAA;EDhDD;ACuDD;;EAEE,YAAA;EDrDD;AC+DD;EACE,2BAAA;ED7DD;ACoED;;EAEE,mBAAA;EDlED;ACyED;EACE,oBAAA;EDvED;AC+ED;EACE,gBAAA;EACA,kBAAA;ED7ED;ACoFD;EACE,kBAAA;EACA,aAAA;EDlFD;ACyFD;EACE,gBAAA;EDvFD;AC8FD;;EAEE,gBAAA;EACA,gBAAA;EACA,oBAAA;EACA,0BAAA;ED5FD;AC+FD;EACE,aAAA;ED7FD;ACgGD;EACE,iBAAA;ED9FD;ACwGD;EACE,WAAA;EDtGD;AC6GD;EACE,kBAAA;ED3GD;ACqHD;EACE,kBAAA;EDnHD;AC0HD;EACE,8BAAA;EACA,iCAAA;UAAA,yBAAA;EACA,WAAA;EDxHD;AC+HD;EACE,gBAAA;ED7HD;ACoID;;;;EAIE,mCAAA;EACA,gBAAA;EDlID;ACoJD;;;;;EAKE,gBAAA;EACA,eAAA;EACA,WAAA;EDlJD;ACyJD;EACE,mBAAA;EDvJD;ACiKD;;EAEE,sBAAA;ED/JD;AC0KD;;;;EAIE,4BAAA;EACA,iBAAA;EDxKD;AC+KD;;EAEE,iBAAA;ED7KD;ACoLD;;EAEE,WAAA;EACA,YAAA;EDlLD;AC0LD;EACE,qBAAA;EDxLD;ACmMD;;EAEE,gCAAA;KAAA,6BAAA;UAAA,wBAAA;EACA,YAAA;EDjMD;AC0MD;;EAEE,cAAA;EDxMD;ACiND;EACE,+BAAA;EACA,8BAAA;EACA,iCAAA;EACA,yBAAA;ED/MD;ACwND;;EAEE,0BAAA;EDtND;AC6ND;EACE,2BAAA;EACA,eAAA;EACA,gCAAA;ED3ND;ACmOD;EACE,WAAA;EACA,YAAA;EDjOD;ACwOD;EACE,gBAAA;EDtOD;AC8OD;EACE,mBAAA;ED5OD;ACsPD;EACE,2BAAA;EACA,mBAAA;EDpPD;ACuPD;;EAEE,YAAA;EDrPD;AACD,sFAAqF;AE1ErF;EAnGI;;;IAGI,oCAAA;IACA,wBAAA;IACA,qCAAA;YAAA,6BAAA;IACA,8BAAA;IFgLL;EE7KC;;IAEI,4BAAA;IF+KL;EE5KC;IACI,8BAAA;IF8KL;EE3KC;IACI,+BAAA;IF6KL;EExKC;;IAEI,aAAA;IF0KL;EEvKC;;IAEI,wBAAA;IACA,0BAAA;IFyKL;EEtKC;IACI,6BAAA;IFwKL;EErKC;;IAEI,0BAAA;IFuKL;EEpKC;IACI,4BAAA;IFsKL;EEnKC;;;IAGI,YAAA;IACA,WAAA;IFqKL;EElKC;;IAEI,yBAAA;IFoKL;EE7JC;IACI,6BAAA;IF+JL;EE3JC;IACI,eAAA;IF6JL;EE3JC;;IAGQ,mCAAA;IF4JT;EEzJC;IACI,wBAAA;IF2JL;EExJC;IACI,sCAAA;IF0JL;EE3JC;;IAKQ,mCAAA;IF0JT;EEvJC;;IAGQ,mCAAA;IFwJT;EACF;AGpPD;EACE,qCAAA;EACA,uDAAA;EACA,iYAAA;EHsPD;AG9OD;EACE,oBAAA;EACA,UAAA;EACA,uBAAA;EACA,qCAAA;EACA,oBAAA;EACA,qBAAA;EACA,gBAAA;EACA,qCAAA;EACA,oCAAA;EHgPD;AG5OmC;EAAW,gBAAA;EH+O9C;AG9OmC;EAAW,gBAAA;EHiP9C;AG/OmC;;EAAW,kBAAA;EHmP9C;AGlPmC;EAAW,kBAAA;EHqP9C;AGpPmC;EAAW,kBAAA;EHuP9C;AGtPmC;EAAW,kBAAA;EHyP9C;AGxPmC;EAAW,kBAAA;EH2P9C;AG1PmC;EAAW,kBAAA;EH6P9C;AG5PmC;EAAW,kBAAA;EH+P9C;AG9PmC;EAAW,kBAAA;EHiQ9C;AGhQmC;EAAW,kBAAA;EHmQ9C;AGlQmC;EAAW,kBAAA;EHqQ9C;AGpQmC;EAAW,kBAAA;EHuQ9C;AGtQmC;EAAW,kBAAA;EHyQ9C;AGxQmC;EAAW,kBAAA;EH2Q9C;AG1QmC;EAAW,kBAAA;EH6Q9C;AG5QmC;EAAW,kBAAA;EH+Q9C;AG9QmC;EAAW,kBAAA;EHiR9C;AGhRmC;EAAW,kBAAA;EHmR9C;AGlRmC;EAAW,kBAAA;EHqR9C;AGpRmC;EAAW,kBAAA;EHuR9C;AGtRmC;EAAW,kBAAA;EHyR9C;AGxRmC;EAAW,kBAAA;EH2R9C;AG1RmC;EAAW,kBAAA;EH6R9C;AG5RmC;EAAW,kBAAA;EH+R9C;AG9RmC;EAAW,kBAAA;EHiS9C;AGhSmC;EAAW,kBAAA;EHmS9C;AGlSmC;EAAW,kBAAA;EHqS9C;AGpSmC;EAAW,kBAAA;EHuS9C;AGtSmC;EAAW,kBAAA;EHyS9C;AGxSmC;EAAW,kBAAA;EH2S9C;AG1SmC;EAAW,kBAAA;EH6S9C;AG5SmC;EAAW,kBAAA;EH+S9C;AG9SmC;EAAW,kBAAA;EHiT9C;AGhTmC;EAAW,kBAAA;EHmT9C;AGlTmC;EAAW,kBAAA;EHqT9C;AGpTmC;EAAW,kBAAA;EHuT9C;AGtTmC;EAAW,kBAAA;EHyT9C;AGxTmC;EAAW,kBAAA;EH2T9C;AG1TmC;EAAW,kBAAA;EH6T9C;AG5TmC;EAAW,kBAAA;EH+T9C;AG9TmC;EAAW,kBAAA;EHiU9C;AGhUmC;EAAW,kBAAA;EHmU9C;AGlUmC;EAAW,kBAAA;EHqU9C;AGpUmC;EAAW,kBAAA;EHuU9C;AGtUmC;EAAW,kBAAA;EHyU9C;AGxUmC;EAAW,kBAAA;EH2U9C;AG1UmC;EAAW,kBAAA;EH6U9C;AG5UmC;EAAW,kBAAA;EH+U9C;AG9UmC;EAAW,kBAAA;EHiV9C;AGhVmC;EAAW,kBAAA;EHmV9C;AGlVmC;EAAW,kBAAA;EHqV9C;AGpVmC;EAAW,kBAAA;EHuV9C;AGtVmC;EAAW,kBAAA;EHyV9C;AGxVmC;EAAW,kBAAA;EH2V9C;AG1VmC;EAAW,kBAAA;EH6V9C;AG5VmC;EAAW,kBAAA;EH+V9C;AG9VmC;EAAW,kBAAA;EHiW9C;AGhWmC;EAAW,kBAAA;EHmW9C;AGlWmC;EAAW,kBAAA;EHqW9C;AGpWmC;EAAW,kBAAA;EHuW9C;AGtWmC;EAAW,kBAAA;EHyW9C;AGxWmC;EAAW,kBAAA;EH2W9C;AG1WmC;EAAW,kBAAA;EH6W9C;AG5WmC;EAAW,kBAAA;EH+W9C;AG9WmC;EAAW,kBAAA;EHiX9C;AGhXmC;EAAW,kBAAA;EHmX9C;AGlXmC;EAAW,kBAAA;EHqX9C;AGpXmC;EAAW,kBAAA;EHuX9C;AGtXmC;EAAW,kBAAA;EHyX9C;AGxXmC;EAAW,kBAAA;EH2X9C;AG1XmC;EAAW,kBAAA;EH6X9C;AG5XmC;EAAW,kBAAA;EH+X9C;AG9XmC;EAAW,kBAAA;EHiY9C;AGhYmC;EAAW,kBAAA;EHmY9C;AGlYmC;EAAW,kBAAA;EHqY9C;AGpYmC;EAAW,kBAAA;EHuY9C;AGtYmC;EAAW,kBAAA;EHyY9C;AGxYmC;EAAW,kBAAA;EH2Y9C;AG1YmC;EAAW,kBAAA;EH6Y9C;AG5YmC;EAAW,kBAAA;EH+Y9C;AG9YmC;EAAW,kBAAA;EHiZ9C;AGhZmC;EAAW,kBAAA;EHmZ9C;AGlZmC;EAAW,kBAAA;EHqZ9C;AGpZmC;EAAW,kBAAA;EHuZ9C;AGtZmC;EAAW,kBAAA;EHyZ9C;AGxZmC;EAAW,kBAAA;EH2Z9C;AG1ZmC;EAAW,kBAAA;EH6Z9C;AG5ZmC;EAAW,kBAAA;EH+Z9C;AG9ZmC;EAAW,kBAAA;EHia9C;AGhamC;EAAW,kBAAA;EHma9C;AGlamC;EAAW,kBAAA;EHqa9C;AGpamC;EAAW,kBAAA;EHua9C;AGtamC;EAAW,kBAAA;EHya9C;AGxamC;EAAW,kBAAA;EH2a9C;AG1amC;EAAW,kBAAA;EH6a9C;AG5amC;EAAW,kBAAA;EH+a9C;AG9amC;EAAW,kBAAA;EHib9C;AGhbmC;EAAW,kBAAA;EHmb9C;AGlbmC;EAAW,kBAAA;EHqb9C;AGpbmC;EAAW,kBAAA;EHub9C;AGtbmC;EAAW,kBAAA;EHyb9C;AGxbmC;EAAW,kBAAA;EH2b9C;AG1bmC;EAAW,kBAAA;EH6b9C;AG5bmC;EAAW,kBAAA;EH+b9C;AG9bmC;EAAW,kBAAA;EHic9C;AGhcmC;EAAW,kBAAA;EHmc9C;AGlcmC;EAAW,kBAAA;EHqc9C;AGpcmC;EAAW,kBAAA;EHuc9C;AGtcmC;EAAW,kBAAA;EHyc9C;AGxcmC;EAAW,kBAAA;EH2c9C;AG1cmC;EAAW,kBAAA;EH6c9C;AG5cmC;EAAW,kBAAA;EH+c9C;AG9cmC;EAAW,kBAAA;EHid9C;AGhdmC;EAAW,kBAAA;EHmd9C;AGldmC;EAAW,kBAAA;EHqd9C;AGpdmC;EAAW,kBAAA;EHud9C;AGtdmC;EAAW,kBAAA;EHyd9C;AGxdmC;EAAW,kBAAA;EH2d9C;AG1dmC;EAAW,kBAAA;EH6d9C;AG5dmC;EAAW,kBAAA;EH+d9C;AG9dmC;EAAW,kBAAA;EHie9C;AGhemC;EAAW,kBAAA;EHme9C;AGlemC;EAAW,kBAAA;EHqe9C;AGpemC;EAAW,kBAAA;EHue9C;AGtemC;EAAW,kBAAA;EHye9C;AGxemC;EAAW,kBAAA;EH2e9C;AG1emC;EAAW,kBAAA;EH6e9C;AG5emC;EAAW,kBAAA;EH+e9C;AG9emC;EAAW,kBAAA;EHif9C;AGhfmC;EAAW,kBAAA;EHmf9C;AGlfmC;EAAW,kBAAA;EHqf9C;AGpfmC;EAAW,kBAAA;EHuf9C;AGtfmC;EAAW,kBAAA;EHyf9C;AGxfmC;EAAW,kBAAA;EH2f9C;AG1fmC;EAAW,kBAAA;EH6f9C;AG5fmC;EAAW,kBAAA;EH+f9C;AG9fmC;EAAW,kBAAA;EHigB9C;AGhgBmC;EAAW,kBAAA;EHmgB9C;AGlgBmC;EAAW,kBAAA;EHqgB9C;AGpgBmC;EAAW,kBAAA;EHugB9C;AGtgBmC;EAAW,kBAAA;EHygB9C;AGxgBmC;EAAW,kBAAA;EH2gB9C;AG1gBmC;EAAW,kBAAA;EH6gB9C;AG5gBmC;EAAW,kBAAA;EH+gB9C;AG9gBmC;EAAW,kBAAA;EHihB9C;AGhhBmC;EAAW,kBAAA;EHmhB9C;AGlhBmC;EAAW,kBAAA;EHqhB9C;AGphBmC;EAAW,kBAAA;EHuhB9C;AGthBmC;EAAW,kBAAA;EHyhB9C;AGxhBmC;EAAW,kBAAA;EH2hB9C;AG1hBmC;EAAW,kBAAA;EH6hB9C;AG5hBmC;EAAW,kBAAA;EH+hB9C;AG9hBmC;EAAW,kBAAA;EHiiB9C;AGhiBmC;EAAW,kBAAA;EHmiB9C;AGliBmC;EAAW,kBAAA;EHqiB9C;AGpiBmC;EAAW,kBAAA;EHuiB9C;AGtiBmC;EAAW,kBAAA;EHyiB9C;AGxiBmC;EAAW,kBAAA;EH2iB9C;AG1iBmC;EAAW,kBAAA;EH6iB9C;AG5iBmC;EAAW,kBAAA;EH+iB9C;AG9iBmC;EAAW,kBAAA;EHijB9C;AGhjBmC;EAAW,kBAAA;EHmjB9C;AGljBmC;EAAW,kBAAA;EHqjB9C;AGpjBmC;EAAW,kBAAA;EHujB9C;AGtjBmC;EAAW,kBAAA;EHyjB9C;AGxjBmC;EAAW,kBAAA;EH2jB9C;AG1jBmC;EAAW,kBAAA;EH6jB9C;AG5jBmC;EAAW,kBAAA;EH+jB9C;AG9jBmC;EAAW,kBAAA;EHikB9C;AGhkBmC;EAAW,kBAAA;EHmkB9C;AGlkBmC;EAAW,kBAAA;EHqkB9C;AGpkBmC;EAAW,kBAAA;EHukB9C;AGtkBmC;EAAW,kBAAA;EHykB9C;AGxkBmC;EAAW,kBAAA;EH2kB9C;AG1kBmC;EAAW,kBAAA;EH6kB9C;AG5kBmC;EAAW,kBAAA;EH+kB9C;AG9kBmC;EAAW,kBAAA;EHilB9C;AGhlBmC;EAAW,kBAAA;EHmlB9C;AGllBmC;EAAW,kBAAA;EHqlB9C;AGplBmC;EAAW,kBAAA;EHulB9C;AGtlBmC;EAAW,kBAAA;EHylB9C;AGxlBmC;EAAW,kBAAA;EH2lB9C;AG1lBmC;EAAW,kBAAA;EH6lB9C;AG5lBmC;EAAW,kBAAA;EH+lB9C;AG9lBmC;EAAW,kBAAA;EHimB9C;AGhmBmC;EAAW,kBAAA;EHmmB9C;AGlmBmC;EAAW,kBAAA;EHqmB9C;AGpmBmC;EAAW,kBAAA;EHumB9C;AGtmBmC;EAAW,kBAAA;EHymB9C;AGxmBmC;EAAW,kBAAA;EH2mB9C;AG1mBmC;EAAW,kBAAA;EH6mB9C;AG5mBmC;EAAW,kBAAA;EH+mB9C;AG9mBmC;EAAW,kBAAA;EHinB9C;AGhnBmC;EAAW,kBAAA;EHmnB9C;AGlnBmC;EAAW,kBAAA;EHqnB9C;AGpnBmC;EAAW,kBAAA;EHunB9C;AGtnBmC;EAAW,kBAAA;EHynB9C;AGxnBmC;EAAW,kBAAA;EH2nB9C;AG1nBmC;EAAW,kBAAA;EH6nB9C;AG5nBmC;EAAW,kBAAA;EH+nB9C;AG9nBmC;EAAW,kBAAA;EHioB9C;AGhoBmC;EAAW,kBAAA;EHmoB9C;AGloBmC;EAAW,kBAAA;EHqoB9C;AGpoBmC;EAAW,kBAAA;EHuoB9C;AGtoBmC;EAAW,kBAAA;EHyoB9C;AGhoBmC;EAAW,kBAAA;EHmoB9C;AGloBmC;EAAW,kBAAA;EHqoB9C;AGpoBmC;EAAW,kBAAA;EHuoB9C;AGtoBmC;EAAW,kBAAA;EHyoB9C;AGxoBmC;EAAW,kBAAA;EH2oB9C;AG1oBmC;EAAW,kBAAA;EH6oB9C;AG5oBmC;EAAW,kBAAA;EH+oB9C;AG9oBmC;EAAW,kBAAA;EHipB9C;AGhpBmC;EAAW,kBAAA;EHmpB9C;AGlpBmC;EAAW,kBAAA;EHqpB9C;AGppBmC;EAAW,kBAAA;EHupB9C;AGtpBmC;EAAW,kBAAA;EHypB9C;AGxpBmC;EAAW,kBAAA;EH2pB9C;AG1pBmC;EAAW,kBAAA;EH6pB9C;AG5pBmC;EAAW,kBAAA;EH+pB9C;AG9pBmC;EAAW,kBAAA;EHiqB9C;AGhqBmC;EAAW,kBAAA;EHmqB9C;AGlqBmC;EAAW,kBAAA;EHqqB9C;AGpqBmC;EAAW,kBAAA;EHuqB9C;AGtqBmC;EAAW,kBAAA;EHyqB9C;AGxqBmC;EAAW,kBAAA;EH2qB9C;AG1qBmC;EAAW,kBAAA;EH6qB9C;AG5qBmC;EAAW,kBAAA;EH+qB9C;AG9qBmC;EAAW,kBAAA;EHirB9C;AGhrBmC;EAAW,kBAAA;EHmrB9C;AGlrBmC;EAAW,kBAAA;EHqrB9C;AGprBmC;EAAW,kBAAA;EHurB9C;AGtrBmC;EAAW,kBAAA;EHyrB9C;AGxrBmC;EAAW,kBAAA;EH2rB9C;AG1rBmC;EAAW,kBAAA;EH6rB9C;AG5rBmC;EAAW,kBAAA;EH+rB9C;AG9rBmC;EAAW,kBAAA;EHisB9C;AGhsBmC;EAAW,kBAAA;EHmsB9C;AGlsBmC;EAAW,kBAAA;EHqsB9C;AGpsBmC;EAAW,kBAAA;EHusB9C;AGtsBmC;EAAW,kBAAA;EHysB9C;AGxsBmC;EAAW,kBAAA;EH2sB9C;AG1sBmC;EAAW,kBAAA;EH6sB9C;AG5sBmC;EAAW,kBAAA;EH+sB9C;AG9sBmC;EAAW,kBAAA;EHitB9C;AGhtBmC;EAAW,kBAAA;EHmtB9C;AGltBmC;EAAW,kBAAA;EHqtB9C;AGptBmC;EAAW,kBAAA;EHutB9C;AGttBmC;EAAW,kBAAA;EHytB9C;AGxtBmC;EAAW,kBAAA;EH2tB9C;AG1tBmC;EAAW,kBAAA;EH6tB9C;AG5tBmC;EAAW,kBAAA;EH+tB9C;AG9tBmC;EAAW,kBAAA;EHiuB9C;AGhuBmC;EAAW,kBAAA;EHmuB9C;AGluBmC;EAAW,kBAAA;EHquB9C;AGpuBmC;EAAW,kBAAA;EHuuB9C;AGtuBmC;EAAW,kBAAA;EHyuB9C;AI3gCD;ECgEE,gCAAA;EACG,6BAAA;EACK,wBAAA;EL88BT;AI7gCD;;EC6DE,gCAAA;EACG,6BAAA;EACK,wBAAA;ELo9BT;AI3gCD;EACE,iBAAA;EACA,+CAAA;EJ6gCD;AI1gCD;EACE,6DAAA;EACA,iBAAA;EACA,yBAAA;EACA,gBAAA;EACA,2BAAA;EJ4gCD;AIxgCD;;;;EAIE,sBAAA;EACA,oBAAA;EACA,sBAAA;EJ0gCD;AIpgCD;EACE,gBAAA;EACA,uBAAA;EJsgCD;AIpgCC;;EAEE,gBAAA;EACA,4BAAA;EJsgCH;AIngCC;EErDA,sBAAA;EAEA,4CAAA;EACA,sBAAA;EN0jCD;AI7/BD;EACE,WAAA;EJ+/BD;AIz/BD;EACE,wBAAA;EJ2/BD;AIv/BD;;;;;EGvEE,gBAAA;EACA,iBAAA;EACA,cAAA;EPqkCD;AI3/BD;EACE,oBAAA;EJ6/BD;AIv/BD;EACE,cAAA;EACA,yBAAA;EACA,2BAAA;EACA,2BAAA;EACA,oBAAA;EC6FA,0CAAA;EACK,qCAAA;EACG,kCAAA;EEvLR,uBAAA;EACA,iBAAA;EACA,cAAA;EPqlCD;AIv/BD;EACE,oBAAA;EJy/BD;AIn/BD;EACE,kBAAA;EACA,qBAAA;EACA,WAAA;EACA,+BAAA;EJq/BD;AI7+BD;EACE,oBAAA;EACA,YAAA;EACA,aAAA;EACA,cAAA;EACA,YAAA;EACA,kBAAA;EACA,wBAAA;EACA,WAAA;EJ++BD;AIv+BC;;EAEE,kBAAA;EACA,aAAA;EACA,cAAA;EACA,WAAA;EACA,mBAAA;EACA,YAAA;EJy+BH;AQpnCD;;;;;;;;;;;;EAEE,sBAAA;EACA,kBAAA;EACA,kBAAA;EACA,gBAAA;ERgoCD;AQroCD;;;;;;;;;;;;;;;;;;;;;;;;EASI,qBAAA;EACA,gBAAA;EACA,gBAAA;ERspCH;AQlpCD;;;;;;EAGE,kBAAA;EACA,qBAAA;ERupCD;AQ3pCD;;;;;;;;;;;;EAQI,gBAAA;ERiqCH;AQ9pCD;;;;;;EAGE,kBAAA;EACA,qBAAA;ERmqCD;AQvqCD;;;;;;;;;;;;EAQI,gBAAA;ER6qCH;AQzqCD;;EAAU,iBAAA;ER6qCT;AQ5qCD;;EAAU,iBAAA;ERgrCT;AQ/qCD;;EAAU,iBAAA;ERmrCT;AQlrCD;;EAAU,iBAAA;ERsrCT;AQrrCD;;EAAU,iBAAA;ERyrCT;AQxrCD;;EAAU,iBAAA;ER4rCT;AQtrCD;EACE,kBAAA;ERwrCD;AQrrCD;EACE,qBAAA;EACA,iBAAA;EACA,kBAAA;EACA,kBAAA;ERurCD;AQlrCD;EAAA;IAFI,iBAAA;IRwrCD;EACF;AQhrCD;;EAEE,gBAAA;ERkrCD;AQ/qCD;;EAEE,2BAAA;EACA,eAAA;ERirCD;AQ7qCD;EAAuB,kBAAA;ERgrCtB;AQ/qCD;EAAuB,mBAAA;ERkrCtB;AQjrCD;EAAuB,oBAAA;ERorCtB;AQnrCD;EAAuB,qBAAA;ERsrCtB;AQrrCD;EAAuB,qBAAA;ERwrCtB;AQrrCD;EAAuB,2BAAA;ERwrCtB;AQvrCD;EAAuB,2BAAA;ER0rCtB;AQzrCD;EAAuB,4BAAA;ER4rCtB;AQzrCD;EACE,gBAAA;ER2rCD;AQzrCD;ECrGE,gBAAA;ETiyCD;AShyCC;EACE,gBAAA;ETkyCH;AQ5rCD;ECxGE,gBAAA;ETuyCD;AStyCC;EACE,gBAAA;ETwyCH;AQ/rCD;EC3GE,gBAAA;ET6yCD;AS5yCC;EACE,gBAAA;ET8yCH;AQlsCD;EC9GE,gBAAA;ETmzCD;ASlzCC;EACE,gBAAA;ETozCH;AQrsCD;ECjHE,gBAAA;ETyzCD;ASxzCC;EACE,gBAAA;ET0zCH;AQpsCD;EAGE,aAAA;EE3HA,2BAAA;EVg0CD;AU/zCC;EACE,2BAAA;EVi0CH;AQrsCD;EE9HE,2BAAA;EVs0CD;AUr0CC;EACE,2BAAA;EVu0CH;AQxsCD;EEjIE,2BAAA;EV40CD;AU30CC;EACE,2BAAA;EV60CH;AQ3sCD;EEpIE,2BAAA;EVk1CD;AUj1CC;EACE,2BAAA;EVm1CH;AQ9sCD;EEvIE,2BAAA;EVw1CD;AUv1CC;EACE,2BAAA;EVy1CH;AQ5sCD;EACE,qBAAA;EACA,qBAAA;EACA,kCAAA;ER8sCD;AQtsCD;;EAEE,eAAA;EACA,qBAAA;ERwsCD;AQ3sCD;;;;EAMI,kBAAA;ER2sCH;AQpsCD;EACE,iBAAA;EACA,kBAAA;ERssCD;AQlsCD;EALE,iBAAA;EACA,kBAAA;EAMA,mBAAA;ERqsCD;AQvsCD;EAKI,uBAAA;EACA,mBAAA;EACA,oBAAA;ERqsCH;AQhsCD;EACE,eAAA;EACA,qBAAA;ERksCD;AQhsCD;;EAEE,yBAAA;ERksCD;AQhsCD;EACE,mBAAA;ERksCD;AQhsCD;EACE,gBAAA;ERksCD;AQzqCD;EAAA;IAVM,aAAA;IACA,cAAA;IACA,aAAA;IACA,mBAAA;IGtNJ,kBAAA;IACA,yBAAA;IACA,qBAAA;IX84CC;EQnrCH;IAHM,oBAAA;IRyrCH;EACF;AQhrCD;;EAGE,cAAA;EACA,mCAAA;ERirCD;AQ/qCD;EACE,gBAAA;EACA,2BAAA;ERirCD;AQ7qCD;EACE,oBAAA;EACA,kBAAA;EACA,mBAAA;EACA,gCAAA;ER+qCD;AQ1qCG;;;EACE,kBAAA;ER8qCL;AQxrCD;;;EAmBI,gBAAA;EACA,gBAAA;EACA,yBAAA;EACA,gBAAA;ER0qCH;AQxqCG;;;EACE,wBAAA;ER4qCL;AQpqCD;;EAEE,qBAAA;EACA,iBAAA;EACA,iCAAA;EACA,gBAAA;EACA,mBAAA;ERsqCD;AQhqCG;;;;;;EAAW,aAAA;ERwqCd;AQvqCG;;;;;;EACE,wBAAA;ER8qCL;AQxqCD;EACE,qBAAA;EACA,oBAAA;EACA,yBAAA;ER0qCD;AYh9CD;;;;EAIE,gEAAA;EZk9CD;AY98CD;EACE,kBAAA;EACA,gBAAA;EACA,gBAAA;EACA,2BAAA;EACA,oBAAA;EZg9CD;AY58CD;EACE,kBAAA;EACA,gBAAA;EACA,gBAAA;EACA,2BAAA;EACA,oBAAA;EACA,wDAAA;UAAA,gDAAA;EZ88CD;AYp9CD;EASI,YAAA;EACA,iBAAA;EACA,mBAAA;EACA,0BAAA;UAAA,kBAAA;EZ88CH;AYz8CD;EACE,gBAAA;EACA,gBAAA;EACA,kBAAA;EACA,iBAAA;EACA,yBAAA;EACA,uBAAA;EACA,uBAAA;EACA,gBAAA;EACA,2BAAA;EACA,2BAAA;EACA,oBAAA;EZ28CD;AYt9CD;EAeI,YAAA;EACA,oBAAA;EACA,gBAAA;EACA,uBAAA;EACA,+BAAA;EACA,kBAAA;EZ08CH;AYr8CD;EACE,mBAAA;EACA,oBAAA;EZu8CD;AajgDD;ECHE,oBAAA;EACA,mBAAA;EACA,oBAAA;EACA,qBAAA;EdugDD;AajgDC;EAAA;IAFE,cAAA;IbugDD;EACF;AangDC;EAAA;IAFE,cAAA;IbygDD;EACF;AargDD;EAAA;IAFI,eAAA;Ib2gDD;EACF;AalgDD;ECvBE,oBAAA;EACA,mBAAA;EACA,oBAAA;EACA,qBAAA;Ed4hDD;Aa//CD;ECvBE,oBAAA;EACA,qBAAA;EdyhDD;AezhDG;EACE,oBAAA;EAEA,iBAAA;EAEA,oBAAA;EACA,qBAAA;EfyhDL;AezgDG;EACE,aAAA;Ef2gDL;AepgDC;EACE,aAAA;EfsgDH;AevgDC;EACE,qBAAA;EfygDH;Ae1gDC;EACE,qBAAA;Ef4gDH;Ae7gDC;EACE,YAAA;Ef+gDH;AehhDC;EACE,qBAAA;EfkhDH;AenhDC;EACE,qBAAA;EfqhDH;AethDC;EACE,YAAA;EfwhDH;AezhDC;EACE,qBAAA;Ef2hDH;Ae5hDC;EACE,qBAAA;Ef8hDH;Ae/hDC;EACE,YAAA;EfiiDH;AeliDC;EACE,qBAAA;EfoiDH;AeriDC;EACE,oBAAA;EfuiDH;AezhDC;EACE,aAAA;Ef2hDH;Ae5hDC;EACE,qBAAA;Ef8hDH;Ae/hDC;EACE,qBAAA;EfiiDH;AeliDC;EACE,YAAA;EfoiDH;AeriDC;EACE,qBAAA;EfuiDH;AexiDC;EACE,qBAAA;Ef0iDH;Ae3iDC;EACE,YAAA;Ef6iDH;Ae9iDC;EACE,qBAAA;EfgjDH;AejjDC;EACE,qBAAA;EfmjDH;AepjDC;EACE,YAAA;EfsjDH;AevjDC;EACE,qBAAA;EfyjDH;Ae1jDC;EACE,oBAAA;Ef4jDH;AexjDC;EACE,aAAA;Ef0jDH;Ae1kDC;EACE,YAAA;Ef4kDH;Ae7kDC;EACE,oBAAA;Ef+kDH;AehlDC;EACE,oBAAA;EfklDH;AenlDC;EACE,WAAA;EfqlDH;AetlDC;EACE,oBAAA;EfwlDH;AezlDC;EACE,oBAAA;Ef2lDH;Ae5lDC;EACE,WAAA;Ef8lDH;Ae/lDC;EACE,oBAAA;EfimDH;AelmDC;EACE,oBAAA;EfomDH;AermDC;EACE,WAAA;EfumDH;AexmDC;EACE,oBAAA;Ef0mDH;Ae3mDC;EACE,mBAAA;Ef6mDH;AezmDC;EACE,YAAA;Ef2mDH;Ae7lDC;EACE,mBAAA;Ef+lDH;AehmDC;EACE,2BAAA;EfkmDH;AenmDC;EACE,2BAAA;EfqmDH;AetmDC;EACE,kBAAA;EfwmDH;AezmDC;EACE,2BAAA;Ef2mDH;Ae5mDC;EACE,2BAAA;Ef8mDH;Ae/mDC;EACE,kBAAA;EfinDH;AelnDC;EACE,2BAAA;EfonDH;AernDC;EACE,2BAAA;EfunDH;AexnDC;EACE,kBAAA;Ef0nDH;Ae3nDC;EACE,2BAAA;Ef6nDH;Ae9nDC;EACE,0BAAA;EfgoDH;AejoDC;EACE,iBAAA;EfmoDH;AanoDD;EElCI;IACE,aAAA;IfwqDH;EejqDD;IACE,aAAA;IfmqDD;EepqDD;IACE,qBAAA;IfsqDD;EevqDD;IACE,qBAAA;IfyqDD;Ee1qDD;IACE,YAAA;If4qDD;Ee7qDD;IACE,qBAAA;If+qDD;EehrDD;IACE,qBAAA;IfkrDD;EenrDD;IACE,YAAA;IfqrDD;EetrDD;IACE,qBAAA;IfwrDD;EezrDD;IACE,qBAAA;If2rDD;Ee5rDD;IACE,YAAA;If8rDD;Ee/rDD;IACE,qBAAA;IfisDD;EelsDD;IACE,oBAAA;IfosDD;EetrDD;IACE,aAAA;IfwrDD;EezrDD;IACE,qBAAA;If2rDD;Ee5rDD;IACE,qBAAA;If8rDD;Ee/rDD;IACE,YAAA;IfisDD;EelsDD;IACE,qBAAA;IfosDD;EersDD;IACE,qBAAA;IfusDD;EexsDD;IACE,YAAA;If0sDD;Ee3sDD;IACE,qBAAA;If6sDD;Ee9sDD;IACE,qBAAA;IfgtDD;EejtDD;IACE,YAAA;IfmtDD;EeptDD;IACE,qBAAA;IfstDD;EevtDD;IACE,oBAAA;IfytDD;EertDD;IACE,aAAA;IfutDD;EevuDD;IACE,YAAA;IfyuDD;Ee1uDD;IACE,oBAAA;If4uDD;Ee7uDD;IACE,oBAAA;If+uDD;EehvDD;IACE,WAAA;IfkvDD;EenvDD;IACE,oBAAA;IfqvDD;EetvDD;IACE,oBAAA;IfwvDD;EezvDD;IACE,WAAA;If2vDD;Ee5vDD;IACE,oBAAA;If8vDD;Ee/vDD;IACE,oBAAA;IfiwDD;EelwDD;IACE,WAAA;IfowDD;EerwDD;IACE,oBAAA;IfuwDD;EexwDD;IACE,mBAAA;If0wDD;EetwDD;IACE,YAAA;IfwwDD;Ee1vDD;IACE,mBAAA;If4vDD;Ee7vDD;IACE,2BAAA;If+vDD;EehwDD;IACE,2BAAA;IfkwDD;EenwDD;IACE,kBAAA;IfqwDD;EetwDD;IACE,2BAAA;IfwwDD;EezwDD;IACE,2BAAA;If2wDD;Ee5wDD;IACE,kBAAA;If8wDD;Ee/wDD;IACE,2BAAA;IfixDD;EelxDD;IACE,2BAAA;IfoxDD;EerxDD;IACE,kBAAA;IfuxDD;EexxDD;IACE,2BAAA;If0xDD;Ee3xDD;IACE,0BAAA;If6xDD;Ee9xDD;IACE,iBAAA;IfgyDD;EACF;AaxxDD;EE3CI;IACE,aAAA;Ifs0DH;Ee/zDD;IACE,aAAA;Ifi0DD;Eel0DD;IACE,qBAAA;Ifo0DD;Eer0DD;IACE,qBAAA;Ifu0DD;Eex0DD;IACE,YAAA;If00DD;Ee30DD;IACE,qBAAA;If60DD;Ee90DD;IACE,qBAAA;Ifg1DD;Eej1DD;IACE,YAAA;Ifm1DD;Eep1DD;IACE,qBAAA;Ifs1DD;Eev1DD;IACE,qBAAA;Ify1DD;Ee11DD;IACE,YAAA;If41DD;Ee71DD;IACE,qBAAA;If+1DD;Eeh2DD;IACE,oBAAA;Ifk2DD;Eep1DD;IACE,aAAA;Ifs1DD;Eev1DD;IACE,qBAAA;Ify1DD;Ee11DD;IACE,qBAAA;If41DD;Ee71DD;IACE,YAAA;If+1DD;Eeh2DD;IACE,qBAAA;Ifk2DD;Een2DD;IACE,qBAAA;Ifq2DD;Eet2DD;IACE,YAAA;Ifw2DD;Eez2DD;IACE,qBAAA;If22DD;Ee52DD;IACE,qBAAA;If82DD;Ee/2DD;IACE,YAAA;Ifi3DD;Eel3DD;IACE,qBAAA;Ifo3DD;Eer3DD;IACE,oBAAA;Ifu3DD;Een3DD;IACE,aAAA;Ifq3DD;Eer4DD;IACE,YAAA;Ifu4DD;Eex4DD;IACE,oBAAA;If04DD;Ee34DD;IACE,oBAAA;If64DD;Ee94DD;IACE,WAAA;Ifg5DD;Eej5DD;IACE,oBAAA;Ifm5DD;Eep5DD;IACE,oBAAA;Ifs5DD;Eev5DD;IACE,WAAA;Ify5DD;Ee15DD;IACE,oBAAA;If45DD;Ee75DD;IACE,oBAAA;If+5DD;Eeh6DD;IACE,WAAA;Ifk6DD;Een6DD;IACE,oBAAA;Ifq6DD;Eet6DD;IACE,mBAAA;Ifw6DD;Eep6DD;IACE,YAAA;Ifs6DD;Eex5DD;IACE,mBAAA;If05DD;Ee35DD;IACE,2BAAA;If65DD;Ee95DD;IACE,2BAAA;Ifg6DD;Eej6DD;IACE,kBAAA;Ifm6DD;Eep6DD;IACE,2BAAA;Ifs6DD;Eev6DD;IACE,2BAAA;Ify6DD;Ee16DD;IACE,kBAAA;If46DD;Ee76DD;IACE,2BAAA;If+6DD;Eeh7DD;IACE,2BAAA;Ifk7DD;Een7DD;IACE,kBAAA;Ifq7DD;Eet7DD;IACE,2BAAA;Ifw7DD;Eez7DD;IACE,0BAAA;If27DD;Ee57DD;IACE,iBAAA;If87DD;EACF;Aan7DD;EE9CI;IACE,aAAA;Ifo+DH;Ee79DD;IACE,aAAA;If+9DD;Eeh+DD;IACE,qBAAA;Ifk+DD;Een+DD;IACE,qBAAA;Ifq+DD;Eet+DD;IACE,YAAA;Ifw+DD;Eez+DD;IACE,qBAAA;If2+DD;Ee5+DD;IACE,qBAAA;If8+DD;Ee/+DD;IACE,YAAA;Ifi/DD;Eel/DD;IACE,qBAAA;Ifo/DD;Eer/DD;IACE,qBAAA;Ifu/DD;Eex/DD;IACE,YAAA;If0/DD;Ee3/DD;IACE,qBAAA;If6/DD;Ee9/DD;IACE,oBAAA;IfggED;Eel/DD;IACE,aAAA;Ifo/DD;Eer/DD;IACE,qBAAA;Ifu/DD;Eex/DD;IACE,qBAAA;If0/DD;Ee3/DD;IACE,YAAA;If6/DD;Ee9/DD;IACE,qBAAA;IfggED;EejgED;IACE,qBAAA;IfmgED;EepgED;IACE,YAAA;IfsgED;EevgED;IACE,qBAAA;IfygED;Ee1gED;IACE,qBAAA;If4gED;Ee7gED;IACE,YAAA;If+gED;EehhED;IACE,qBAAA;IfkhED;EenhED;IACE,oBAAA;IfqhED;EejhED;IACE,aAAA;IfmhED;EeniED;IACE,YAAA;IfqiED;EetiED;IACE,oBAAA;IfwiED;EeziED;IACE,oBAAA;If2iED;Ee5iED;IACE,WAAA;If8iED;Ee/iED;IACE,oBAAA;IfijED;EeljED;IACE,oBAAA;IfojED;EerjED;IACE,WAAA;IfujED;EexjED;IACE,oBAAA;If0jED;Ee3jED;IACE,oBAAA;If6jED;Ee9jED;IACE,WAAA;IfgkED;EejkED;IACE,oBAAA;IfmkED;EepkED;IACE,mBAAA;IfskED;EelkED;IACE,YAAA;IfokED;EetjED;IACE,mBAAA;IfwjED;EezjED;IACE,2BAAA;If2jED;Ee5jED;IACE,2BAAA;If8jED;Ee/jED;IACE,kBAAA;IfikED;EelkED;IACE,2BAAA;IfokED;EerkED;IACE,2BAAA;IfukED;EexkED;IACE,kBAAA;If0kED;Ee3kED;IACE,2BAAA;If6kED;Ee9kED;IACE,2BAAA;IfglED;EejlED;IACE,kBAAA;IfmlED;EeplED;IACE,2BAAA;IfslED;EevlED;IACE,0BAAA;IfylED;Ee1lED;IACE,iBAAA;If4lED;EACF;AgBhqED;EACE,+BAAA;EhBkqED;AgBhqED;EACE,kBAAA;EACA,qBAAA;EACA,gBAAA;EACA,kBAAA;EhBkqED;AgBhqED;EACE,kBAAA;EhBkqED;AgB5pED;EACE,aAAA;EACA,iBAAA;EACA,qBAAA;EhB8pED;AgBjqED;;;;;;EAWQ,cAAA;EACA,yBAAA;EACA,qBAAA;EACA,+BAAA;EhB8pEP;AgB5qED;EAoBI,wBAAA;EACA,kCAAA;EhB2pEH;AgBhrED;;;;;;EA8BQ,eAAA;EhB0pEP;AgBxrED;EAoCI,+BAAA;EhBupEH;AgB3rED;EAyCI,2BAAA;EhBqpEH;AgB9oED;;;;;;EAOQ,cAAA;EhB+oEP;AgBpoED;EACE,2BAAA;EhBsoED;AgBvoED;;;;;;EAQQ,2BAAA;EhBuoEP;AgB/oED;;EAeM,0BAAA;EhBooEL;AgB1nED;EAEI,2BAAA;EhB2nEH;AgBlnED;EAEI,2BAAA;EhBmnEH;AgB1mED;EACE,kBAAA;EACA,aAAA;EACA,uBAAA;EhB4mED;AgBvmEG;;EACE,kBAAA;EACA,aAAA;EACA,qBAAA;EhB0mEL;AiBtvEC;;;;;;;;;;;;EAOI,2BAAA;EjB6vEL;AiBvvEC;;;;;EAMI,2BAAA;EjBwvEL;AiB3wEC;;;;;;;;;;;;EAOI,2BAAA;EjBkxEL;AiB5wEC;;;;;EAMI,2BAAA;EjB6wEL;AiBhyEC;;;;;;;;;;;;EAOI,2BAAA;EjBuyEL;AiBjyEC;;;;;EAMI,2BAAA;EjBkyEL;AiBrzEC;;;;;;;;;;;;EAOI,2BAAA;EjB4zEL;AiBtzEC;;;;;EAMI,2BAAA;EjBuzEL;AiB10EC;;;;;;;;;;;;EAOI,2BAAA;EjBi1EL;AiB30EC;;;;;EAMI,2BAAA;EjB40EL;AgB1rED;EACE,kBAAA;EACA,mBAAA;EhB4rED;AgB/nED;EAAA;IA1DI,aAAA;IACA,qBAAA;IACA,oBAAA;IACA,8CAAA;IACA,2BAAA;IhB6rED;EgBvoEH;IAlDM,kBAAA;IhB4rEH;EgB1oEH;;;;;;IAzCY,qBAAA;IhB2rET;EgBlpEH;IAjCM,WAAA;IhBsrEH;EgBrpEH;;;;;;IAxBY,gBAAA;IhBqrET;EgB7pEH;;;;;;IApBY,iBAAA;IhByrET;EgBrqEH;;;;IAPY,kBAAA;IhBkrET;EACF;AkB54ED;EACE,YAAA;EACA,WAAA;EACA,WAAA;EAIA,cAAA;ElB24ED;AkBx4ED;EACE,gBAAA;EACA,aAAA;EACA,YAAA;EACA,qBAAA;EACA,iBAAA;EACA,sBAAA;EACA,gBAAA;EACA,WAAA;EACA,kCAAA;ElB04ED;AkBv4ED;EACE,uBAAA;EACA,iBAAA;EACA,oBAAA;EACA,mBAAA;ElBy4ED;AkB93ED;Eb4BE,gCAAA;EACG,6BAAA;EACK,wBAAA;ELq2ET;AkB93ED;;EAEE,iBAAA;EACA,oBAAA;EACA,qBAAA;ElBg4ED;AkB53ED;EACE,gBAAA;ElB83ED;AkB13ED;EACE,gBAAA;EACA,aAAA;ElB43ED;AkBx3ED;;EAEE,cAAA;ElB03ED;AkBt3ED;;;EZxEE,sBAAA;EAEA,4CAAA;EACA,sBAAA;ENk8ED;AkBt3ED;EACE,gBAAA;EACA,kBAAA;EACA,iBAAA;EACA,yBAAA;EACA,gBAAA;ElBw3ED;AkB91ED;EACE,gBAAA;EACA,aAAA;EACA,cAAA;EACA,mBAAA;EACA,iBAAA;EACA,yBAAA;EACA,gBAAA;EACA,2BAAA;EACA,wBAAA;EACA,2BAAA;EACA,oBAAA;EbzDA,0DAAA;EACQ,kDAAA;EAyHR,wFAAA;EACK,2EAAA;EACG,wEAAA;ELkyET;AmB16EC;EACE,uBAAA;EACA,YAAA;EdUF,wFAAA;EACQ,gFAAA;ELm6ET;AKl4EC;EACE,gBAAA;EACA,YAAA;ELo4EH;AKl4EC;EAA0B,gBAAA;ELq4E3B;AKp4EC;EAAgC,gBAAA;ELu4EjC;AkBt2EC;;;EAGE,qBAAA;EACA,2BAAA;EACA,YAAA;ElBw2EH;AkBp2EC;EACE,cAAA;ElBs2EH;AkB11ED;EACE,0BAAA;ElB41ED;AkBxzED;EAxBE;;;;IAIE,mBAAA;IlBm1ED;EkBj1EC;;;;;;;;IAEE,mBAAA;IlBy1EH;EkBt1EC;;;;;;;;IAEE,mBAAA;IlB81EH;EACF;AkBp1ED;EACE,qBAAA;ElBs1ED;AkB90ED;;EAEE,oBAAA;EACA,gBAAA;EACA,kBAAA;EACA,qBAAA;ElBg1ED;AkBr1ED;;EAQI,kBAAA;EACA,oBAAA;EACA,kBAAA;EACA,qBAAA;EACA,iBAAA;ElBi1EH;AkB90ED;;;;EAIE,oBAAA;EACA,oBAAA;EACA,oBAAA;ElBg1ED;AkB70ED;;EAEE,kBAAA;ElB+0ED;AkB30ED;;EAEE,uBAAA;EACA,oBAAA;EACA,kBAAA;EACA,wBAAA;EACA,qBAAA;EACA,iBAAA;ElB60ED;AkB30ED;;EAEE,eAAA;EACA,mBAAA;ElB60ED;AkBp0EC;;;;;;EAGE,qBAAA;ElBy0EH;AkBn0EC;;;;EAEE,qBAAA;ElBu0EH;AkBj0EC;;;;EAGI,qBAAA;ElBo0EL;AkBzzED;EAEE,kBAAA;EACA,qBAAA;EAEA,kBAAA;ElByzED;AkBvzEC;;EAEE,iBAAA;EACA,kBAAA;ElByzEH;AkB5yED;ECpPE,cAAA;EACA,mBAAA;EACA,iBAAA;EACA,kBAAA;EACA,oBAAA;EnBmiFD;AmBjiFC;EACE,cAAA;EACA,mBAAA;EnBmiFH;AmBhiFC;;EAEE,cAAA;EnBkiFH;AkBxzED;ECvPE,cAAA;EACA,mBAAA;EACA,iBAAA;EACA,kBAAA;EACA,oBAAA;EnBkjFD;AmBhjFC;EACE,cAAA;EACA,mBAAA;EnBkjFH;AmB/iFC;;EAEE,cAAA;EnBijFH;AkBv0ED;EAKI,cAAA;EACA,mBAAA;EACA,iBAAA;EACA,kBAAA;ElBq0EH;AkBj0ED;ECnQE,cAAA;EACA,oBAAA;EACA,iBAAA;EACA,wBAAA;EACA,oBAAA;EnBukFD;AmBrkFC;EACE,cAAA;EACA,mBAAA;EnBukFH;AmBpkFC;;EAEE,cAAA;EnBskFH;AkB70ED;ECtQE,cAAA;EACA,oBAAA;EACA,iBAAA;EACA,wBAAA;EACA,oBAAA;EnBslFD;AmBplFC;EACE,cAAA;EACA,mBAAA;EnBslFH;AmBnlFC;;EAEE,cAAA;EnBqlFH;AkB51ED;EAKI,cAAA;EACA,oBAAA;EACA,iBAAA;EACA,wBAAA;ElB01EH;AkBj1ED;EAEE,oBAAA;ElBk1ED;AkBp1ED;EAMI,uBAAA;ElBi1EH;AkB70ED;EACE,oBAAA;EACA,QAAA;EACA,UAAA;EACA,YAAA;EACA,gBAAA;EACA,aAAA;EACA,cAAA;EACA,mBAAA;EACA,oBAAA;EACA,sBAAA;ElB+0ED;AkB70ED;EACE,aAAA;EACA,cAAA;EACA,mBAAA;ElB+0ED;AkB70ED;EACE,aAAA;EACA,cAAA;EACA,mBAAA;ElB+0ED;AkB30ED;;;;;;;;;;EC7WI,gBAAA;EnBosFH;AkBv1ED;ECzWI,uBAAA;Ed+CF,0DAAA;EACQ,kDAAA;ELqpFT;AmBnsFG;EACE,uBAAA;Ed4CJ,2EAAA;EACQ,mEAAA;EL0pFT;AkBj2ED;EC/VI,gBAAA;EACA,uBAAA;EACA,2BAAA;EnBmsFH;AkBt2ED;ECzVI,gBAAA;EnBksFH;AkBt2ED;;;;;;;;;;EChXI,gBAAA;EnBkuFH;AkBl3ED;EC5WI,uBAAA;Ed+CF,0DAAA;EACQ,kDAAA;ELmrFT;AmBjuFG;EACE,uBAAA;Ed4CJ,2EAAA;EACQ,mEAAA;ELwrFT;AkB53ED;EClWI,gBAAA;EACA,uBAAA;EACA,2BAAA;EnBiuFH;AkBj4ED;EC5VI,gBAAA;EnBguFH;AkBj4ED;;;;;;;;;;ECnXI,gBAAA;EnBgwFH;AkB74ED;EC/WI,uBAAA;Ed+CF,0DAAA;EACQ,kDAAA;ELitFT;AmB/vFG;EACE,uBAAA;Ed4CJ,2EAAA;EACQ,mEAAA;ELstFT;AkBv5ED;ECrWI,gBAAA;EACA,uBAAA;EACA,2BAAA;EnB+vFH;AkB55ED;EC/VI,gBAAA;EnB8vFH;AkBx5EC;EACG,WAAA;ElB05EJ;AkBx5EC;EACG,QAAA;ElB05EJ;AkBh5ED;EACE,gBAAA;EACA,iBAAA;EACA,qBAAA;EACA,gBAAA;ElBk5ED;AkB/zED;EAAA;IA9DM,uBAAA;IACA,kBAAA;IACA,wBAAA;IlBi4EH;EkBr0EH;IAvDM,uBAAA;IACA,aAAA;IACA,wBAAA;IlB+3EH;EkB10EH;IAhDM,uBAAA;IlB63EH;EkB70EH;IA5CM,uBAAA;IACA,wBAAA;IlB43EH;EkBj1EH;;;IAtCQ,aAAA;IlB43EL;EkBt1EH;IAhCM,aAAA;IlBy3EH;EkBz1EH;IA5BM,kBAAA;IACA,wBAAA;IlBw3EH;EkB71EH;;IApBM,uBAAA;IACA,eAAA;IACA,kBAAA;IACA,wBAAA;IlBq3EH;EkBp2EH;;IAdQ,iBAAA;IlBs3EL;EkBx2EH;;IATM,oBAAA;IACA,gBAAA;IlBq3EH;EkB72EH;IAHM,QAAA;IlBm3EH;EACF;AkBz2ED;;;;EASI,eAAA;EACA,kBAAA;EACA,kBAAA;ElBs2EH;AkBj3ED;;EAiBI,kBAAA;ElBo2EH;AkBr3ED;EJzeE,oBAAA;EACA,qBAAA;Edi2FD;AkBl1EC;EAAA;IAVI,mBAAA;IACA,kBAAA;IACA,kBAAA;IlBg2EH;EACF;AkBh4ED;EAwCI,aAAA;ElB21EH;AkB90EC;EAAA;IAHM,0BAAA;IlBq1EL;EACF;AkB50EC;EAAA;IAHM,kBAAA;IlBm1EL;EACF;AoB73FD;EACE,uBAAA;EACA,kBAAA;EACA,qBAAA;EACA,oBAAA;EACA,wBAAA;EACA,gCAAA;MAAA,4BAAA;EACA,iBAAA;EACA,wBAAA;EACA,+BAAA;EACA,qBAAA;EC6BA,mBAAA;EACA,iBAAA;EACA,yBAAA;EACA,oBAAA;EhB4KA,2BAAA;EACG,wBAAA;EACC,uBAAA;EACI,mBAAA;ELwrFT;AoBh4FG;;;;;;EdrBF,sBAAA;EAEA,4CAAA;EACA,sBAAA;EN45FD;AoBp4FC;;;EAGE,gBAAA;EACA,uBAAA;EpBs4FH;AoBn4FC;;EAEE,YAAA;EACA,wBAAA;Ef2BF,0DAAA;EACQ,kDAAA;EL22FT;AoBn4FC;;;EAGE,qBAAA;EACA,sBAAA;EE9CF,eAAA;EAGA,2BAAA;EjB8DA,0BAAA;EACQ,kBAAA;ELq3FT;AoB/3FD;ECrDE,gBAAA;EACA,2BAAA;EACA,uBAAA;ErBu7FD;AqBr7FC;;;;;;EAME,gBAAA;EACA,2BAAA;EACI,uBAAA;ErBu7FP;AqBr7FC;;;EAGE,wBAAA;ErBu7FH;AqBl7FG;;;;;;;;;;;;;;;;;;EAME,2BAAA;EACI,uBAAA;ErBg8FT;AoBx6FD;ECnBI,gBAAA;EACA,2BAAA;ErB87FH;AoBz6FD;ECxDE,gBAAA;EACA,2BAAA;EACA,uBAAA;ErBo+FD;AqBl+FC;;;;;;EAME,gBAAA;EACA,2BAAA;EACI,uBAAA;ErBo+FP;AqBl+FC;;;EAGE,wBAAA;ErBo+FH;AqB/9FG;;;;;;;;;;;;;;;;;;EAME,2BAAA;EACI,uBAAA;ErB6+FT;AoBl9FD;ECtBI,gBAAA;EACA,2BAAA;ErB2+FH;AoBl9FD;EC5DE,gBAAA;EACA,2BAAA;EACA,uBAAA;ErBihGD;AqB/gGC;;;;;;EAME,gBAAA;EACA,2BAAA;EACI,uBAAA;ErBihGP;AqB/gGC;;;EAGE,wBAAA;ErBihGH;AqB5gGG;;;;;;;;;;;;;;;;;;EAME,2BAAA;EACI,uBAAA;ErB0hGT;AoB3/FD;EC1BI,gBAAA;EACA,2BAAA;ErBwhGH;AoB3/FD;EChEE,gBAAA;EACA,2BAAA;EACA,uBAAA;ErB8jGD;AqB5jGC;;;;;;EAME,gBAAA;EACA,2BAAA;EACI,uBAAA;ErB8jGP;AqB5jGC;;;EAGE,wBAAA;ErB8jGH;AqBzjGG;;;;;;;;;;;;;;;;;;EAME,2BAAA;EACI,uBAAA;ErBukGT;AoBpiGD;EC9BI,gBAAA;EACA,2BAAA;ErBqkGH;AoBpiGD;ECpEE,gBAAA;EACA,2BAAA;EACA,uBAAA;ErB2mGD;AqBzmGC;;;;;;EAME,gBAAA;EACA,2BAAA;EACI,uBAAA;ErB2mGP;AqBzmGC;;;EAGE,wBAAA;ErB2mGH;AqBtmGG;;;;;;;;;;;;;;;;;;EAME,2BAAA;EACI,uBAAA;ErBonGT;AoB7kGD;EClCI,gBAAA;EACA,2BAAA;ErBknGH;AoB7kGD;ECxEE,gBAAA;EACA,2BAAA;EACA,uBAAA;ErBwpGD;AqBtpGC;;;;;;EAME,gBAAA;EACA,2BAAA;EACI,uBAAA;ErBwpGP;AqBtpGC;;;EAGE,wBAAA;ErBwpGH;AqBnpGG;;;;;;;;;;;;;;;;;;EAME,2BAAA;EACI,uBAAA;ErBiqGT;AoBtnGD;ECtCI,gBAAA;EACA,2BAAA;ErB+pGH;AoBjnGD;EACE,gBAAA;EACA,qBAAA;EACA,kBAAA;EpBmnGD;AoBjnGC;;;;;EAKE,+BAAA;Ef7BF,0BAAA;EACQ,kBAAA;ELipGT;AoBlnGC;;;;EAIE,2BAAA;EpBonGH;AoBlnGC;;EAEE,gBAAA;EACA,4BAAA;EACA,+BAAA;EpBonGH;AoBhnGG;;;;EAEE,gBAAA;EACA,uBAAA;EpBonGL;AoB3mGD;;EC/EE,oBAAA;EACA,iBAAA;EACA,wBAAA;EACA,oBAAA;ErB8rGD;AoB9mGD;;ECnFE,mBAAA;EACA,iBAAA;EACA,kBAAA;EACA,oBAAA;ErBqsGD;AoBjnGD;;ECvFE,kBAAA;EACA,iBAAA;EACA,kBAAA;EACA,oBAAA;ErB4sGD;AoBhnGD;EACE,gBAAA;EACA,aAAA;EpBknGD;AoB9mGD;EACE,iBAAA;EpBgnGD;AoBzmGC;;;EACE,aAAA;EpB6mGH;AuBjwGD;EACE,YAAA;ElBoLA,0CAAA;EACK,qCAAA;EACG,kCAAA;ELglGT;AuBpwGC;EACE,YAAA;EvBswGH;AuBlwGD;EACE,eAAA;EACA,oBAAA;EvBowGD;AuBlwGC;EAAY,gBAAA;EAAgB,qBAAA;EvBswG7B;AuBrwGC;EAAY,oBAAA;EvBwwGb;AuBvwGC;EAAY,0BAAA;EvB0wGb;AuBvwGD;EACE,oBAAA;EACA,WAAA;EACA,kBAAA;ElBsKA,iDAAA;EACQ,4CAAA;KAAA,yCAAA;EAOR,oCAAA;EACQ,+BAAA;KAAA,4BAAA;EAGR,0CAAA;EACQ,qCAAA;KAAA,kCAAA;EL4lGT;AwBtyGD;EACE,uBAAA;EACA,UAAA;EACA,WAAA;EACA,kBAAA;EACA,wBAAA;EACA,uBAAA;EACA,qCAAA;EACA,oCAAA;ExBwyGD;AwBpyGD;;EAEE,oBAAA;ExBsyGD;AwBlyGD;EACE,YAAA;ExBoyGD;AwBhyGD;EACE,oBAAA;EACA,WAAA;EACA,SAAA;EACA,eAAA;EACA,eAAA;EACA,aAAA;EACA,kBAAA;EACA,gBAAA;EACA,iBAAA;EACA,kBAAA;EACA,iBAAA;EACA,kBAAA;EACA,2BAAA;EACA,2BAAA;EACA,uCAAA;EACA,oBAAA;EnBuBA,qDAAA;EACQ,6CAAA;EmBtBR,sCAAA;UAAA,8BAAA;ExBmyGD;AwB9xGC;EACE,UAAA;EACA,YAAA;ExBgyGH;AwBzzGD;ECxBE,aAAA;EACA,eAAA;EACA,kBAAA;EACA,2BAAA;EzBo1GD;AwB/zGD;EAmCI,gBAAA;EACA,mBAAA;EACA,aAAA;EACA,qBAAA;EACA,yBAAA;EACA,gBAAA;EACA,qBAAA;ExB+xGH;AwBzxGC;;EAEE,uBAAA;EACA,gBAAA;EACA,2BAAA;ExB2xGH;AwBrxGC;;;EAGE,gBAAA;EACA,uBAAA;EACA,YAAA;EACA,2BAAA;ExBuxGH;AwB9wGC;;;EAGE,gBAAA;ExBgxGH;AwB5wGC;;EAEE,uBAAA;EACA,+BAAA;EACA,wBAAA;EE1GF,qEAAA;EF4GE,qBAAA;ExB8wGH;AwBzwGD;EAGI,gBAAA;ExBywGH;AwB5wGD;EAQI,YAAA;ExBuwGH;AwB/vGD;EACE,YAAA;EACA,UAAA;ExBiwGD;AwBzvGD;EACE,SAAA;EACA,aAAA;ExB2vGD;AwBvvGD;EACE,gBAAA;EACA,mBAAA;EACA,iBAAA;EACA,yBAAA;EACA,gBAAA;EACA,qBAAA;ExByvGD;AwBrvGD;EACE,iBAAA;EACA,SAAA;EACA,UAAA;EACA,WAAA;EACA,QAAA;EACA,cAAA;ExBuvGD;AwBnvGD;EACE,UAAA;EACA,YAAA;ExBqvGD;AwB7uGD;;EAII,eAAA;EACA,0BAAA;EACA,aAAA;ExB6uGH;AwBnvGD;;EAUI,WAAA;EACA,cAAA;EACA,oBAAA;ExB6uGH;AwBxtGD;EAXE;IAnEA,YAAA;IACA,UAAA;IxB0yGC;EwBxuGD;IAzDA,SAAA;IACA,aAAA;IxBoyGC;EACF;A2Bn7GD;;EAEE,oBAAA;EACA,uBAAA;EACA,wBAAA;E3Bq7GD;A2Bz7GD;;EAMI,oBAAA;EACA,aAAA;E3Bu7GH;A2Br7GG;;;;;;;;EAIE,YAAA;E3B27GL;A2Br7GD;;;;EAKI,mBAAA;E3Bs7GH;A2Bj7GD;EACE,mBAAA;E3Bm7GD;A2Bp7GD;;EAMI,aAAA;E3Bk7GH;A2Bx7GD;;;EAWI,kBAAA;E3Bk7GH;A2B96GD;EACE,kBAAA;E3Bg7GD;A2B56GD;EACE,gBAAA;E3B86GD;A2B76GC;ECjDA,+BAAA;EACG,4BAAA;E5Bi+GJ;A2B56GD;;EC9CE,8BAAA;EACG,2BAAA;E5B89GJ;A2B36GD;EACE,aAAA;E3B66GD;A2B36GD;EACE,kBAAA;E3B66GD;A2B36GD;;EClEE,+BAAA;EACG,4BAAA;E5Bi/GJ;A2B16GD;EChEE,8BAAA;EACG,2BAAA;E5B6+GJ;A2Bz6GD;;EAEE,YAAA;E3B26GD;A2B15GD;EACE,mBAAA;EACA,oBAAA;E3B45GD;A2B15GD;EACE,oBAAA;EACA,qBAAA;E3B45GD;A2Bv5GD;EtB9CE,0DAAA;EACQ,kDAAA;ELw8GT;A2Bv5GC;EtBlDA,0BAAA;EACQ,kBAAA;EL48GT;A2Bp5GD;EACE,gBAAA;E3Bs5GD;A2Bn5GD;EACE,yBAAA;EACA,wBAAA;E3Bq5GD;A2Bl5GD;EACE,yBAAA;E3Bo5GD;A2B74GD;;;EAII,gBAAA;EACA,aAAA;EACA,aAAA;EACA,iBAAA;E3B84GH;A2Br5GD;EAcM,aAAA;E3B04GL;A2Bx5GD;;;;EAsBI,kBAAA;EACA,gBAAA;E3Bw4GH;A2Bn4GC;EACE,kBAAA;E3Bq4GH;A2Bn4GC;EACE,8BAAA;ECnKF,+BAAA;EACC,8BAAA;E5ByiHF;A2Bp4GC;EACE,gCAAA;EC/KF,4BAAA;EACC,2BAAA;E5BsjHF;A2Bp4GD;EACE,kBAAA;E3Bs4GD;A2Bp4GD;;EC9KE,+BAAA;EACC,8BAAA;E5BsjHF;A2Bn4GD;EC5LE,4BAAA;EACC,2BAAA;E5BkkHF;A2B/3GD;EACE,gBAAA;EACA,aAAA;EACA,qBAAA;EACA,2BAAA;E3Bi4GD;A2Br4GD;;EAOI,aAAA;EACA,qBAAA;EACA,WAAA;E3Bk4GH;A2B34GD;EAYI,aAAA;E3Bk4GH;A2B94GD;EAgBI,YAAA;E3Bi4GH;A2Bh3GD;;;;EAKM,oBAAA;EACA,wBAAA;EACA,sBAAA;E3Bi3GL;A6B1lHD;EACE,oBAAA;EACA,gBAAA;EACA,2BAAA;E7B4lHD;A6BzlHC;EACE,aAAA;EACA,iBAAA;EACA,kBAAA;E7B2lHH;A6BpmHD;EAeI,oBAAA;EACA,YAAA;EAKA,aAAA;EAEA,aAAA;EACA,kBAAA;E7BmlHH;A6B1kHD;;;EV8BE,cAAA;EACA,oBAAA;EACA,iBAAA;EACA,wBAAA;EACA,oBAAA;EnBijHD;AmB/iHC;;;EACE,cAAA;EACA,mBAAA;EnBmjHH;AmBhjHC;;;;;;EAEE,cAAA;EnBsjHH;A6B5lHD;;;EVyBE,cAAA;EACA,mBAAA;EACA,iBAAA;EACA,kBAAA;EACA,oBAAA;EnBwkHD;AmBtkHC;;;EACE,cAAA;EACA,mBAAA;EnB0kHH;AmBvkHC;;;;;;EAEE,cAAA;EnB6kHH;A6B1mHD;;;EAGE,qBAAA;E7B4mHD;A6B1mHC;;;EACE,kBAAA;E7B8mHH;A6B1mHD;;EAEE,WAAA;EACA,qBAAA;EACA,wBAAA;E7B4mHD;A6BvmHD;EACE,mBAAA;EACA,iBAAA;EACA,qBAAA;EACA,gBAAA;EACA,gBAAA;EACA,oBAAA;EACA,2BAAA;EACA,2BAAA;EACA,oBAAA;E7BymHD;A6BtmHC;EACE,mBAAA;EACA,iBAAA;EACA,oBAAA;E7BwmHH;A6BtmHC;EACE,oBAAA;EACA,iBAAA;EACA,oBAAA;E7BwmHH;A6B5nHD;;EA0BI,eAAA;E7BsmHH;A6BjmHD;;;;;;;EDhGE,+BAAA;EACG,4BAAA;E5B0sHJ;A6BlmHD;EACE,iBAAA;E7BomHD;A6BlmHD;;;;;;;EDpGE,8BAAA;EACG,2BAAA;E5B+sHJ;A6BnmHD;EACE,gBAAA;E7BqmHD;A6BhmHD;EACE,oBAAA;EAGA,cAAA;EACA,qBAAA;E7BgmHD;A6BrmHD;EAUI,oBAAA;E7B8lHH;A6BxmHD;EAYM,mBAAA;E7B+lHL;A6B5lHG;;;EAGE,YAAA;E7B8lHL;A6BzlHC;;EAGI,oBAAA;E7B0lHL;A6BvlHC;;EAGI,mBAAA;E7BwlHL;A8BlvHD;EACE,kBAAA;EACA,iBAAA;EACA,kBAAA;E9BovHD;A8BvvHD;EAOI,oBAAA;EACA,gBAAA;E9BmvHH;A8B3vHD;EAWM,oBAAA;EACA,gBAAA;EACA,oBAAA;E9BmvHL;A8BlvHK;;EAEE,uBAAA;EACA,2BAAA;E9BovHP;A8B/uHG;EACE,gBAAA;E9BivHL;A8B/uHK;;EAEE,gBAAA;EACA,uBAAA;EACA,+BAAA;EACA,qBAAA;E9BivHP;A8B1uHG;;;EAGE,2BAAA;EACA,uBAAA;E9B4uHL;A8BrxHD;ELHE,aAAA;EACA,eAAA;EACA,kBAAA;EACA,2BAAA;EzB2xHD;A8B3xHD;EA0DI,iBAAA;E9BouHH;A8B3tHD;EACE,kCAAA;E9B6tHD;A8B9tHD;EAGI,aAAA;EAEA,qBAAA;E9B6tHH;A8BluHD;EASM,mBAAA;EACA,yBAAA;EACA,+BAAA;EACA,4BAAA;E9B4tHL;A8B3tHK;EACE,uCAAA;E9B6tHP;A8BvtHK;;;EAGE,gBAAA;EACA,2BAAA;EACA,2BAAA;EACA,kCAAA;EACA,iBAAA;E9BytHP;A8BptHC;EAqDA,aAAA;EA8BA,kBAAA;E9BqoHD;A8BxtHC;EAwDE,aAAA;E9BmqHH;A8B3tHC;EA0DI,oBAAA;EACA,oBAAA;E9BoqHL;A8B/tHC;EAgEE,WAAA;EACA,YAAA;E9BkqHH;A8BtpHD;EAAA;IAPM,qBAAA;IACA,WAAA;I9BiqHH;E8B3pHH;IAJQ,kBAAA;I9BkqHL;EACF;A8B5uHC;EAuFE,iBAAA;EACA,oBAAA;E9BwpHH;A8BhvHC;;;EA8FE,2BAAA;E9BupHH;A8BzoHD;EAAA;IATM,kCAAA;IACA,4BAAA;I9BspHH;E8B9oHH;;;IAHM,8BAAA;I9BspHH;EACF;A8BvvHD;EAEI,aAAA;E9BwvHH;A8B1vHD;EAMM,oBAAA;E9BuvHL;A8B7vHD;EASM,kBAAA;E9BuvHL;A8BlvHK;;;EAGE,gBAAA;EACA,2BAAA;E9BovHP;A8B5uHD;EAEI,aAAA;E9B6uHH;A8B/uHD;EAIM,iBAAA;EACA,gBAAA;E9B8uHL;A8BluHD;EACE,aAAA;E9BouHD;A8BruHD;EAII,aAAA;E9BouHH;A8BxuHD;EAMM,oBAAA;EACA,oBAAA;E9BquHL;A8B5uHD;EAYI,WAAA;EACA,YAAA;E9BmuHH;A8BvtHD;EAAA;IAPM,qBAAA;IACA,WAAA;I9BkuHH;E8B5tHH;IAJQ,kBAAA;I9BmuHL;EACF;A8B3tHD;EACE,kBAAA;E9B6tHD;A8B9tHD;EAKI,iBAAA;EACA,oBAAA;E9B4tHH;A8BluHD;;;EAYI,2BAAA;E9B2tHH;A8B7sHD;EAAA;IATM,kCAAA;IACA,4BAAA;I9B0tHH;E8BltHH;;;IAHM,8BAAA;I9B0tHH;EACF;A8BjtHD;EAEI,eAAA;EACA,oBAAA;E9BktHH;A8BrtHD;EAMI,gBAAA;EACA,qBAAA;E9BktHH;A8BzsHD;EAEE,kBAAA;EF7OA,4BAAA;EACC,2BAAA;E5Bw7HF;A+Bl7HD;EACE,oBAAA;EACA,kBAAA;EACA,qBAAA;EACA,+BAAA;E/Bo7HD;A+B56HD;EAAA;IAFI,oBAAA;I/Bk7HD;EACF;A+Bn6HD;EAAA;IAFI,aAAA;I/By6HD;EACF;A+B35HD;EACE,qBAAA;EACA,qBAAA;EACA,oBAAA;EACA,mCAAA;EACA,4DAAA;UAAA,oDAAA;EAEA,mCAAA;E/B45HD;A+B15HC;EACE,kBAAA;E/B45HH;A+B/3HD;EAAA;IAzBI,aAAA;IACA,eAAA;IACA,0BAAA;YAAA,kBAAA;I/B45HD;E+B15HC;IACE,2BAAA;IACA,gCAAA;IACA,yBAAA;IACA,mBAAA;IACA,8BAAA;I/B45HH;E+Bz5HC;IACE,qBAAA;I/B25HH;E+Bt5HC;;;IAGE,iBAAA;IACA,kBAAA;I/Bw5HH;EACF;A+Bp5HD;;EAGI,mBAAA;E/Bq5HH;A+Bh5HC;EAAA;;IAFI,mBAAA;I/Bu5HH;EACF;A+B94HD;;;;EAII,qBAAA;EACA,oBAAA;E/Bg5HH;A+B14HC;EAAA;;;;IAHI,iBAAA;IACA,gBAAA;I/Bo5HH;EACF;A+Bx4HD;EACE,eAAA;EACA,uBAAA;E/B04HD;A+Br4HD;EAAA;IAFI,kBAAA;I/B24HD;EACF;A+Bv4HD;;EAEE,iBAAA;EACA,UAAA;EACA,SAAA;EACA,eAAA;E/By4HD;A+Bn4HD;EAAA;;IAFI,kBAAA;I/B04HD;EACF;A+Bx4HD;EACE,QAAA;EACA,uBAAA;E/B04HD;A+Bx4HD;EACE,WAAA;EACA,kBAAA;EACA,uBAAA;E/B04HD;A+Bp4HD;EACE,aAAA;EACA,oBAAA;EACA,iBAAA;EACA,mBAAA;EACA,cAAA;E/Bs4HD;A+Bp4HC;;EAEE,uBAAA;E/Bs4HH;A+B/4HD;EAaI,gBAAA;E/Bq4HH;A+B53HD;EALI;;IAEE,oBAAA;I/Bo4HH;EACF;A+B13HD;EACE,oBAAA;EACA,cAAA;EACA,oBAAA;EACA,mBAAA;EC/LA,iBAAA;EACA,oBAAA;EDgMA,+BAAA;EACA,wBAAA;EACA,+BAAA;EACA,oBAAA;E/B63HD;A+Bz3HC;EACE,YAAA;E/B23HH;A+Bz4HD;EAmBI,gBAAA;EACA,aAAA;EACA,aAAA;EACA,oBAAA;E/By3HH;A+B/4HD;EAyBI,iBAAA;E/By3HH;A+Bn3HD;EAAA;IAFI,eAAA;I/By3HD;EACF;A+Bh3HD;EACE,qBAAA;E/Bk3HD;A+Bn3HD;EAII,mBAAA;EACA,sBAAA;EACA,mBAAA;E/Bk3HH;A+Bt1HC;EAAA;IAtBI,kBAAA;IACA,aAAA;IACA,aAAA;IACA,eAAA;IACA,+BAAA;IACA,WAAA;IACA,0BAAA;YAAA,kBAAA;I/Bg3HH;E+Bh2HD;;IAbM,4BAAA;I/Bi3HL;E+Bp2HD;IAVM,mBAAA;I/Bi3HL;E+Bh3HK;;IAEE,wBAAA;I/Bk3HP;EACF;A+Bh2HD;EAAA;IAXI,aAAA;IACA,WAAA;I/B+2HD;E+Br2HH;IAPM,aAAA;I/B+2HH;E+Bx2HH;IALQ,mBAAA;IACA,sBAAA;I/Bg3HL;EACF;A+Br2HD;EACE,oBAAA;EACA,qBAAA;EACA,oBAAA;EACA,mCAAA;EACA,sCAAA;E1B/NA,8FAAA;EACQ,sFAAA;E2B/DR,iBAAA;EACA,oBAAA;EhCuoID;AkB9pHD;EAAA;IA9DM,uBAAA;IACA,kBAAA;IACA,wBAAA;IlBguHH;EkBpqHH;IAvDM,uBAAA;IACA,aAAA;IACA,wBAAA;IlB8tHH;EkBzqHH;IAhDM,uBAAA;IlB4tHH;EkB5qHH;IA5CM,uBAAA;IACA,wBAAA;IlB2tHH;EkBhrHH;;;IAtCQ,aAAA;IlB2tHL;EkBrrHH;IAhCM,aAAA;IlBwtHH;EkBxrHH;IA5BM,kBAAA;IACA,wBAAA;IlButHH;EkB5rHH;;IApBM,uBAAA;IACA,eAAA;IACA,kBAAA;IACA,wBAAA;IlBotHH;EkBnsHH;;IAdQ,iBAAA;IlBqtHL;EkBvsHH;;IATM,oBAAA;IACA,gBAAA;IlBotHH;EkB5sHH;IAHM,QAAA;IlBktHH;EACF;A+B94HC;EAAA;IANI,oBAAA;I/Bw5HH;E+Bt5HG;IACE,kBAAA;I/Bw5HL;EACF;A+Bv4HD;EAAA;IARI,aAAA;IACA,WAAA;IACA,gBAAA;IACA,iBAAA;IACA,gBAAA;IACA,mBAAA;I1B1PF,0BAAA;IACQ,kBAAA;IL8oIP;EACF;A+B74HD;EACE,eAAA;EHrUA,4BAAA;EACC,2BAAA;E5BqtIF;A+B74HD;EACE,kBAAA;EH1UA,8BAAA;EACC,6BAAA;EAOD,+BAAA;EACC,8BAAA;E5BotIF;A+Bz4HD;ECjVE,iBAAA;EACA,oBAAA;EhC6tID;A+B14HC;ECpVA,kBAAA;EACA,qBAAA;EhCiuID;A+B34HC;ECvVA,kBAAA;EACA,qBAAA;EhCquID;A+Br4HD;ECjWE,kBAAA;EACA,qBAAA;EhCyuID;A+Bj4HD;EAAA;IAJI,aAAA;IACA,mBAAA;IACA,oBAAA;I/By4HD;EACF;A+B52HD;EAhBE;IEzWA,wBAAA;IjCyuIC;E+B/3HD;IE7WA,yBAAA;IF+WE,qBAAA;I/Bi4HD;E+Bn4HD;IAKI,iBAAA;I/Bi4HH;EACF;A+Bx3HD;EACE,2BAAA;EACA,uBAAA;E/B03HD;A+B53HD;EAKI,gBAAA;E/B03HH;A+Bz3HG;;EAEE,gBAAA;EACA,+BAAA;E/B23HL;A+Bp4HD;EAcI,gBAAA;E/By3HH;A+Bv4HD;EAmBM,gBAAA;E/Bu3HL;A+Br3HK;;EAEE,gBAAA;EACA,+BAAA;E/Bu3HP;A+Bn3HK;;;EAGE,gBAAA;EACA,2BAAA;E/Bq3HP;A+Bj3HK;;;EAGE,gBAAA;EACA,+BAAA;E/Bm3HP;A+B35HD;EA8CI,uBAAA;E/Bg3HH;A+B/2HG;;EAEE,2BAAA;E/Bi3HL;A+Bl6HD;EAoDM,2BAAA;E/Bi3HL;A+Br6HD;;EA0DI,uBAAA;E/B+2HH;A+Bx2HK;;;EAGE,2BAAA;EACA,gBAAA;E/B02HP;A+Bz0HC;EAAA;IAzBQ,gBAAA;I/Bs2HP;E+Br2HO;;IAEE,gBAAA;IACA,+BAAA;I/Bu2HT;E+Bn2HO;;;IAGE,gBAAA;IACA,2BAAA;I/Bq2HT;E+Bj2HO;;;IAGE,gBAAA;IACA,+BAAA;I/Bm2HT;EACF;A+Br8HD;EA8GI,gBAAA;E/B01HH;A+Bz1HG;EACE,gBAAA;E/B21HL;A+B38HD;EAqHI,gBAAA;E/By1HH;A+Bx1HG;;EAEE,gBAAA;E/B01HL;A+Bt1HK;;;;EAEE,gBAAA;E/B01HP;A+Bl1HD;EACE,2BAAA;EACA,uBAAA;E/Bo1HD;A+Bt1HD;EAKI,gBAAA;E/Bo1HH;A+Bn1HG;;EAEE,gBAAA;EACA,+BAAA;E/Bq1HL;A+B91HD;EAcI,gBAAA;E/Bm1HH;A+Bj2HD;EAmBM,gBAAA;E/Bi1HL;A+B/0HK;;EAEE,gBAAA;EACA,+BAAA;E/Bi1HP;A+B70HK;;;EAGE,gBAAA;EACA,2BAAA;E/B+0HP;A+B30HK;;;EAGE,gBAAA;EACA,+BAAA;E/B60HP;A+Br3HD;EA+CI,uBAAA;E/By0HH;A+Bx0HG;;EAEE,2BAAA;E/B00HL;A+B53HD;EAqDM,2BAAA;E/B00HL;A+B/3HD;;EA2DI,uBAAA;E/Bw0HH;A+Bl0HK;;;EAGE,2BAAA;EACA,gBAAA;E/Bo0HP;A+B7xHC;EAAA;IA/BQ,uBAAA;I/Bg0HP;E+BjyHD;IA5BQ,2BAAA;I/Bg0HP;E+BpyHD;IAzBQ,gBAAA;I/Bg0HP;E+B/zHO;;IAEE,gBAAA;IACA,+BAAA;I/Bi0HT;E+B7zHO;;;IAGE,gBAAA;IACA,2BAAA;I/B+zHT;E+B3zHO;;;IAGE,gBAAA;IACA,+BAAA;I/B6zHT;EACF;A+Br6HD;EA+GI,gBAAA;E/ByzHH;A+BxzHG;EACE,gBAAA;E/B0zHL;A+B36HD;EAsHI,gBAAA;E/BwzHH;A+BvzHG;;EAEE,gBAAA;E/ByzHL;A+BrzHK;;;;EAEE,gBAAA;E/ByzHP;AkCp8ID;EACE,mBAAA;EACA,qBAAA;EACA,kBAAA;EACA,2BAAA;EACA,oBAAA;ElCs8ID;AkC38ID;EAQI,uBAAA;ElCs8IH;AkC98ID;EAWM,mBAAA;EACA,gBAAA;EACA,gBAAA;ElCs8IL;AkCn9ID;EAkBI,gBAAA;ElCo8IH;AmCx9ID;EACE,uBAAA;EACA,iBAAA;EACA,gBAAA;EACA,oBAAA;EnC09ID;AmC99ID;EAOI,iBAAA;EnC09IH;AmCj+ID;;EAUM,oBAAA;EACA,aAAA;EACA,mBAAA;EACA,yBAAA;EACA,uBAAA;EACA,gBAAA;EACA,2BAAA;EACA,2BAAA;EACA,mBAAA;EnC29IL;AmCz9IG;;EAGI,gBAAA;EPXN,gCAAA;EACG,6BAAA;E5Bs+IJ;AmCx9IG;;EPvBF,iCAAA;EACG,8BAAA;E5Bm/IJ;AmCn9IG;;;;EAEE,gBAAA;EACA,2BAAA;EACA,uBAAA;EnCu9IL;AmCj9IG;;;;;;EAGE,YAAA;EACA,gBAAA;EACA,2BAAA;EACA,uBAAA;EACA,iBAAA;EnCs9IL;AmC5gJD;;;;;;EAiEM,gBAAA;EACA,2BAAA;EACA,uBAAA;EACA,qBAAA;EnCm9IL;AmC18ID;;EC1EM,oBAAA;EACA,iBAAA;EpCwhJL;AoCthJG;;ERMF,gCAAA;EACG,6BAAA;E5BohJJ;AoCrhJG;;ERRF,iCAAA;EACG,8BAAA;E5BiiJJ;AmCp9ID;;EC/EM,mBAAA;EACA,iBAAA;EpCuiJL;AoCriJG;;ERMF,gCAAA;EACG,6BAAA;E5BmiJJ;AoCpiJG;;ERRF,iCAAA;EACG,8BAAA;E5BgjJJ;AqCnjJD;EACE,iBAAA;EACA,gBAAA;EACA,kBAAA;EACA,oBAAA;ErCqjJD;AqCzjJD;EAOI,iBAAA;ErCqjJH;AqC5jJD;;EAUM,uBAAA;EACA,mBAAA;EACA,2BAAA;EACA,2BAAA;EACA,qBAAA;ErCsjJL;AqCpkJD;;EAmBM,uBAAA;EACA,2BAAA;ErCqjJL;AqCzkJD;;EA2BM,cAAA;ErCkjJL;AqC7kJD;;EAkCM,aAAA;ErC+iJL;AqCjlJD;;;;EA2CM,gBAAA;EACA,2BAAA;EACA,qBAAA;ErC4iJL;AsC1lJD;EACE,iBAAA;EACA,yBAAA;EACA,gBAAA;EACA,mBAAA;EACA,gBAAA;EACA,gBAAA;EACA,oBAAA;EACA,qBAAA;EACA,0BAAA;EACA,sBAAA;EtC4lJD;AsCxlJG;;EAEE,gBAAA;EACA,uBAAA;EACA,iBAAA;EtC0lJL;AsCrlJC;EACE,eAAA;EtCulJH;AsCnlJC;EACE,oBAAA;EACA,WAAA;EtCqlJH;AsC9kJD;ECtCE,2BAAA;EvCunJD;AuCpnJG;;EAEE,2BAAA;EvCsnJL;AsCjlJD;EC1CE,2BAAA;EvC8nJD;AuC3nJG;;EAEE,2BAAA;EvC6nJL;AsCplJD;EC9CE,2BAAA;EvCqoJD;AuCloJG;;EAEE,2BAAA;EvCooJL;AsCvlJD;EClDE,2BAAA;EvC4oJD;AuCzoJG;;EAEE,2BAAA;EvC2oJL;AsC1lJD;ECtDE,2BAAA;EvCmpJD;AuChpJG;;EAEE,2BAAA;EvCkpJL;AsC7lJD;EC1DE,2BAAA;EvC0pJD;AuCvpJG;;EAEE,2BAAA;EvCypJL;AwC3pJD;EACE,uBAAA;EACA,iBAAA;EACA,kBAAA;EACA,iBAAA;EACA,mBAAA;EACA,gBAAA;EACA,gBAAA;EACA,0BAAA;EACA,qBAAA;EACA,oBAAA;EACA,2BAAA;EACA,qBAAA;ExC6pJD;AwC1pJC;EACE,eAAA;ExC4pJH;AwCxpJC;EACE,oBAAA;EACA,WAAA;ExC0pJH;AwCvpJC;EACE,QAAA;EACA,kBAAA;ExCypJH;AwCppJG;;EAEE,gBAAA;EACA,uBAAA;EACA,iBAAA;ExCspJL;AwCjpJC;;EAEE,gBAAA;EACA,2BAAA;ExCmpJH;AwChpJC;EACE,cAAA;ExCkpJH;AwC/oJC;EACE,mBAAA;ExCipJH;AwC9oJC;EACE,kBAAA;ExCgpJH;AyCzsJD;EACE,oBAAA;EACA,qBAAA;EACA,gBAAA;EACA,2BAAA;EzC2sJD;AyC/sJD;;EAQI,gBAAA;EzC2sJH;AyCntJD;EAYI,qBAAA;EACA,iBAAA;EACA,kBAAA;EzC0sJH;AyCxtJD;EAkBI,2BAAA;EzCysJH;AyCtsJC;;EAEE,oBAAA;EzCwsJH;AyC/tJD;EA2BI,iBAAA;EzCusJH;AyCtrJD;EAAA;IAbI,iBAAA;IzCusJD;EyCrsJC;;IAEE,oBAAA;IACA,qBAAA;IzCusJH;EyC/rJH;;IAHM,iBAAA;IzCssJH;EACF;A0C/uJD;EACE,gBAAA;EACA,cAAA;EACA,qBAAA;EACA,yBAAA;EACA,2BAAA;EACA,2BAAA;EACA,oBAAA;ErCiLA,6CAAA;EACK,wCAAA;EACG,qCAAA;ELikJT;A0C3vJD;;EAaI,mBAAA;EACA,oBAAA;E1CkvJH;A0C9uJC;;;EAGE,uBAAA;E1CgvJH;A0CrwJD;EA0BI,cAAA;EACA,gBAAA;E1C8uJH;A2CvwJD;EACE,eAAA;EACA,qBAAA;EACA,+BAAA;EACA,oBAAA;E3CywJD;A2C7wJD;EAQI,eAAA;EAEA,gBAAA;E3CuwJH;A2CjxJD;EAeI,mBAAA;E3CqwJH;A2CpxJD;;EAqBI,kBAAA;E3CmwJH;A2CxxJD;EAyBI,iBAAA;E3CkwJH;A2C1vJD;;EAEE,qBAAA;E3C4vJD;A2C9vJD;;EAMI,oBAAA;EACA,WAAA;EACA,cAAA;EACA,gBAAA;E3C4vJH;A2CpvJD;ECvDE,2BAAA;EACA,uBAAA;EACA,gBAAA;E5C8yJD;A2CzvJD;EClDI,2BAAA;E5C8yJH;A2C5vJD;EC/CI,gBAAA;E5C8yJH;A2C3vJD;EC3DE,2BAAA;EACA,uBAAA;EACA,gBAAA;E5CyzJD;A2ChwJD;ECtDI,2BAAA;E5CyzJH;A2CnwJD;ECnDI,gBAAA;E5CyzJH;A2ClwJD;EC/DE,2BAAA;EACA,uBAAA;EACA,gBAAA;E5Co0JD;A2CvwJD;EC1DI,2BAAA;E5Co0JH;A2C1wJD;ECvDI,gBAAA;E5Co0JH;A2CzwJD;ECnEE,2BAAA;EACA,uBAAA;EACA,gBAAA;E5C+0JD;A2C9wJD;EC9DI,2BAAA;E5C+0JH;A2CjxJD;EC3DI,gBAAA;E5C+0JH;A6Cj1JD;EACE;IAAQ,6BAAA;I7Co1JP;E6Cn1JD;IAAQ,0BAAA;I7Cs1JP;EACF;A6Cn1JD;EACE;IAAQ,6BAAA;I7Cs1JP;E6Cr1JD;IAAQ,0BAAA;I7Cw1JP;EACF;A6C31JD;EACE;IAAQ,6BAAA;I7Cs1JP;E6Cr1JD;IAAQ,0BAAA;I7Cw1JP;EACF;A6Cj1JD;EACE,kBAAA;EACA,cAAA;EACA,qBAAA;EACA,2BAAA;EACA,oBAAA;ExCsCA,wDAAA;EACQ,gDAAA;EL8yJT;A6Ch1JD;EACE,aAAA;EACA,WAAA;EACA,cAAA;EACA,iBAAA;EACA,mBAAA;EACA,gBAAA;EACA,oBAAA;EACA,2BAAA;ExCyBA,wDAAA;EACQ,gDAAA;EAyHR,qCAAA;EACK,gCAAA;EACG,6BAAA;ELksJT;A6C70JD;;ECCI,+MAAA;EACA,0MAAA;EACA,uMAAA;EDAF,oCAAA;UAAA,4BAAA;E7Ci1JD;A6C10JD;;ExC5CE,4DAAA;EACK,uDAAA;EACG,oDAAA;EL03JT;A6Cv0JD;EErEE,2BAAA;E/C+4JD;A+C54JC;EDgDE,+MAAA;EACA,0MAAA;EACA,uMAAA;E9C+1JH;A6C30JD;EEzEE,2BAAA;E/Cu5JD;A+Cp5JC;EDgDE,+MAAA;EACA,0MAAA;EACA,uMAAA;E9Cu2JH;A6C/0JD;EE7EE,2BAAA;E/C+5JD;A+C55JC;EDgDE,+MAAA;EACA,0MAAA;EACA,uMAAA;E9C+2JH;A6Cn1JD;EEjFE,2BAAA;E/Cu6JD;A+Cp6JC;EDgDE,+MAAA;EACA,0MAAA;EACA,uMAAA;E9Cu3JH;AgD/6JD;EAEE,kBAAA;EhDg7JD;AgD96JC;EACE,eAAA;EhDg7JH;AgD56JD;;EAEE,SAAA;EACA,kBAAA;EhD86JD;AgD36JD;EACE,gBAAA;EhD66JD;AgD16JD;EACE,gBAAA;EhD46JD;AgDz6JD;;EAEE,oBAAA;EhD26JD;AgDx6JD;;EAEE,qBAAA;EhD06JD;AgDv6JD;;;EAGE,qBAAA;EACA,qBAAA;EhDy6JD;AgDt6JD;EACE,wBAAA;EhDw6JD;AgDr6JD;EACE,wBAAA;EhDu6JD;AgDn6JD;EACE,eAAA;EACA,oBAAA;EhDq6JD;AgD/5JD;EACE,iBAAA;EACA,kBAAA;EhDi6JD;AiDn9JD;EAEE,qBAAA;EACA,iBAAA;EjDo9JD;AiD58JD;EACE,oBAAA;EACA,gBAAA;EACA,oBAAA;EAEA,qBAAA;EACA,2BAAA;EACA,2BAAA;EjD68JD;AiD18JC;ErB3BA,8BAAA;EACC,6BAAA;E5Bw+JF;AiD38JC;EACE,kBAAA;ErBvBF,iCAAA;EACC,gCAAA;E5Bq+JF;AiDp8JD;EACE,gBAAA;EjDs8JD;AiDv8JD;EAII,gBAAA;EjDs8JH;AiDl8JC;;EAEE,uBAAA;EACA,gBAAA;EACA,2BAAA;EjDo8JH;AiD97JC;;;EAGE,2BAAA;EACA,gBAAA;EACA,qBAAA;EjDg8JH;AiDr8JC;;;EASI,gBAAA;EjDi8JL;AiD18JC;;;EAYI,gBAAA;EjDm8JL;AiD97JC;;;EAGE,YAAA;EACA,gBAAA;EACA,2BAAA;EACA,uBAAA;EjDg8JH;AiDt8JC;;;;;;;;;EAYI,gBAAA;EjDq8JL;AiDj9JC;;;EAeI,gBAAA;EjDu8JL;AkDniKC;EACE,gBAAA;EACA,2BAAA;ElDqiKH;AkDniKG;EACE,gBAAA;ElDqiKL;AkDtiKG;EAII,gBAAA;ElDqiKP;AkDliKK;;EAEE,gBAAA;EACA,2BAAA;ElDoiKP;AkDliKK;;;EAGE,aAAA;EACA,2BAAA;EACA,uBAAA;ElDoiKP;AkDzjKC;EACE,gBAAA;EACA,2BAAA;ElD2jKH;AkDzjKG;EACE,gBAAA;ElD2jKL;AkD5jKG;EAII,gBAAA;ElD2jKP;AkDxjKK;;EAEE,gBAAA;EACA,2BAAA;ElD0jKP;AkDxjKK;;;EAGE,aAAA;EACA,2BAAA;EACA,uBAAA;ElD0jKP;AkD/kKC;EACE,gBAAA;EACA,2BAAA;ElDilKH;AkD/kKG;EACE,gBAAA;ElDilKL;AkDllKG;EAII,gBAAA;ElDilKP;AkD9kKK;;EAEE,gBAAA;EACA,2BAAA;ElDglKP;AkD9kKK;;;EAGE,aAAA;EACA,2BAAA;EACA,uBAAA;ElDglKP;AkDrmKC;EACE,gBAAA;EACA,2BAAA;ElDumKH;AkDrmKG;EACE,gBAAA;ElDumKL;AkDxmKG;EAII,gBAAA;ElDumKP;AkDpmKK;;EAEE,gBAAA;EACA,2BAAA;ElDsmKP;AkDpmKK;;;EAGE,aAAA;EACA,2BAAA;EACA,uBAAA;ElDsmKP;AiD1gKD;EACE,eAAA;EACA,oBAAA;EjD4gKD;AiD1gKD;EACE,kBAAA;EACA,kBAAA;EjD4gKD;AmDhoKD;EACE,qBAAA;EACA,2BAAA;EACA,+BAAA;EACA,oBAAA;E9C0DA,mDAAA;EACQ,2CAAA;ELykKT;AmD/nKD;EACE,eAAA;EnDioKD;AmD5nKD;EACE,oBAAA;EACA,sCAAA;EvBpBA,8BAAA;EACC,6BAAA;E5BmpKF;AmDloKD;EAMI,gBAAA;EnD+nKH;AmD1nKD;EACE,eAAA;EACA,kBAAA;EACA,iBAAA;EACA,gBAAA;EnD4nKD;AmDhoKD;;;;;EAWI,gBAAA;EnD4nKH;AmDvnKD;EACE,oBAAA;EACA,2BAAA;EACA,+BAAA;EvBxCA,iCAAA;EACC,gCAAA;E5BkqKF;AmDjnKD;;EAGI,kBAAA;EnDknKH;AmDrnKD;;EAMM,qBAAA;EACA,kBAAA;EnDmnKL;AmD/mKG;;EAEI,eAAA;EvBvEN,8BAAA;EACC,6BAAA;E5ByrKF;AmD9mKG;;EAEI,kBAAA;EvBtEN,iCAAA;EACC,gCAAA;E5BurKF;AmD3mKD;EAEI,qBAAA;EnD4mKH;AmDzmKD;EACE,qBAAA;EnD2mKD;AmDnmKD;;;EAII,kBAAA;EnDomKH;AmDxmKD;;;EAOM,oBAAA;EACA,qBAAA;EnDsmKL;AmD9mKD;;EvBnGE,8BAAA;EACC,6BAAA;E5BqtKF;AmDnnKD;;;;EAmBQ,6BAAA;EACA,8BAAA;EnDsmKP;AmD1nKD;;;;;;;;EAwBU,6BAAA;EnD4mKT;AmDpoKD;;;;;;;;EA4BU,8BAAA;EnDknKT;AmD9oKD;;EvB3FE,iCAAA;EACC,gCAAA;E5B6uKF;AmDnpKD;;;;EAyCQ,gCAAA;EACA,iCAAA;EnDgnKP;AmD1pKD;;;;;;;;EA8CU,gCAAA;EnDsnKT;AmDpqKD;;;;;;;;EAkDU,iCAAA;EnD4nKT;AmD9qKD;;;;EA2DI,+BAAA;EnDynKH;AmDprKD;;EA+DI,eAAA;EnDynKH;AmDxrKD;;EAmEI,WAAA;EnDynKH;AmD5rKD;;;;;;;;;;;;EA0EU,gBAAA;EnDgoKT;AmD1sKD;;;;;;;;;;;;EA8EU,iBAAA;EnD0oKT;AmDxtKD;;;;;;;;EAuFU,kBAAA;EnD2oKT;AmDluKD;;;;;;;;EAgGU,kBAAA;EnD4oKT;AmD5uKD;EAsGI,WAAA;EACA,kBAAA;EnDyoKH;AmD/nKD;EACE,qBAAA;EnDioKD;AmDloKD;EAKI,kBAAA;EACA,oBAAA;EnDgoKH;AmDtoKD;EASM,iBAAA;EnDgoKL;AmDzoKD;EAcI,kBAAA;EnD8nKH;AmD5oKD;;EAkBM,+BAAA;EnD8nKL;AmDhpKD;EAuBI,eAAA;EnD4nKH;AmDnpKD;EAyBM,kCAAA;EnD6nKL;AmDtnKD;ECpPE,uBAAA;EpD62KD;AoD32KC;EACE,gBAAA;EACA,2BAAA;EACA,uBAAA;EpD62KH;AoDh3KC;EAMI,2BAAA;EpD62KL;AoDn3KC;EASI,gBAAA;EACA,2BAAA;EpD62KL;AoD12KC;EAEI,8BAAA;EpD22KL;AmDroKD;ECvPE,uBAAA;EpD+3KD;AoD73KC;EACE,gBAAA;EACA,2BAAA;EACA,uBAAA;EpD+3KH;AoDl4KC;EAMI,2BAAA;EpD+3KL;AoDr4KC;EASI,gBAAA;EACA,2BAAA;EpD+3KL;AoD53KC;EAEI,8BAAA;EpD63KL;AmDppKD;EC1PE,uBAAA;EpDi5KD;AoD/4KC;EACE,gBAAA;EACA,2BAAA;EACA,uBAAA;EpDi5KH;AoDp5KC;EAMI,2BAAA;EpDi5KL;AoDv5KC;EASI,gBAAA;EACA,2BAAA;EpDi5KL;AoD94KC;EAEI,8BAAA;EpD+4KL;AmDnqKD;EC7PE,uBAAA;EpDm6KD;AoDj6KC;EACE,gBAAA;EACA,2BAAA;EACA,uBAAA;EpDm6KH;AoDt6KC;EAMI,2BAAA;EpDm6KL;AoDz6KC;EASI,gBAAA;EACA,2BAAA;EpDm6KL;AoDh6KC;EAEI,8BAAA;EpDi6KL;AmDlrKD;EChQE,uBAAA;EpDq7KD;AoDn7KC;EACE,gBAAA;EACA,2BAAA;EACA,uBAAA;EpDq7KH;AoDx7KC;EAMI,2BAAA;EpDq7KL;AoD37KC;EASI,gBAAA;EACA,2BAAA;EpDq7KL;AoDl7KC;EAEI,8BAAA;EpDm7KL;AmDjsKD;ECnQE,uBAAA;EpDu8KD;AoDr8KC;EACE,gBAAA;EACA,2BAAA;EACA,uBAAA;EpDu8KH;AoD18KC;EAMI,2BAAA;EpDu8KL;AoD78KC;EASI,gBAAA;EACA,2BAAA;EpDu8KL;AoDp8KC;EAEI,8BAAA;EpDq8KL;AqDr9KD;EACE,oBAAA;EACA,gBAAA;EACA,WAAA;EACA,YAAA;EACA,kBAAA;ErDu9KD;AqD59KD;;;;;EAYI,oBAAA;EACA,QAAA;EACA,SAAA;EACA,WAAA;EACA,cAAA;EACA,aAAA;EACA,WAAA;ErDu9KH;AqDn9KC;EACE,wBAAA;ErDq9KH;AqDj9KC;EACE,qBAAA;ErDm9KH;AsD7+KD;EACE,kBAAA;EACA,eAAA;EACA,qBAAA;EACA,2BAAA;EACA,2BAAA;EACA,oBAAA;EjDwDA,yDAAA;EACQ,iDAAA;ELw7KT;AsDv/KD;EASI,oBAAA;EACA,mCAAA;EtDi/KH;AsD5+KD;EACE,eAAA;EACA,oBAAA;EtD8+KD;AsD5+KD;EACE,cAAA;EACA,oBAAA;EtD8+KD;AuDpgLD;EACE,cAAA;EACA,iBAAA;EACA,mBAAA;EACA,gBAAA;EACA,gBAAA;EACA,8BAAA;EjCRA,cAAA;EAGA,2BAAA;EtB6gLD;AuDrgLC;;EAEE,gBAAA;EACA,uBAAA;EACA,iBAAA;EjCfF,cAAA;EAGA,2BAAA;EtBqhLD;AuDjgLC;EACE,YAAA;EACA,iBAAA;EACA,yBAAA;EACA,WAAA;EACA,0BAAA;EvDmgLH;AwDxhLD;EACE,kBAAA;ExD0hLD;AwDthLD;EACE,eAAA;EACA,kBAAA;EACA,iBAAA;EACA,QAAA;EACA,UAAA;EACA,WAAA;EACA,SAAA;EACA,eAAA;EACA,mCAAA;EAIA,YAAA;ExDqhLD;AwDlhLC;EnD+GA,uCAAA;EACI,mCAAA;EACC,kCAAA;EACG,+BAAA;EAkER,qDAAA;EAEK,2CAAA;EACG,qCAAA;ELq2KT;AwDxhLC;EnD2GA,oCAAA;EACI,gCAAA;EACC,+BAAA;EACG,4BAAA;ELg7KT;AwD5hLD;EACE,oBAAA;EACA,kBAAA;ExD8hLD;AwD1hLD;EACE,oBAAA;EACA,aAAA;EACA,cAAA;ExD4hLD;AwDxhLD;EACE,oBAAA;EACA,2BAAA;EACA,2BAAA;EACA,sCAAA;EACA,oBAAA;EnDaA,kDAAA;EACQ,0CAAA;EmDZR,sCAAA;UAAA,8BAAA;EAEA,YAAA;ExD0hLD;AwDthLD;EACE,oBAAA;EACA,QAAA;EACA,UAAA;EACA,SAAA;EACA,2BAAA;ExDwhLD;AwDthLC;ElCnEA,YAAA;EAGA,0BAAA;EtB0lLD;AwDzhLC;ElCpEA,cAAA;EAGA,2BAAA;EtB8lLD;AwDxhLD;EACE,eAAA;EACA,kCAAA;EACA,2BAAA;ExD0hLD;AwDvhLD;EACE,kBAAA;ExDyhLD;AwDrhLD;EACE,WAAA;EACA,yBAAA;ExDuhLD;AwDlhLD;EACE,oBAAA;EACA,eAAA;ExDohLD;AwDhhLD;EACE,eAAA;EACA,mBAAA;EACA,+BAAA;ExDkhLD;AwDrhLD;EAQI,kBAAA;EACA,kBAAA;ExDghLH;AwDzhLD;EAaI,mBAAA;ExD+gLH;AwD5hLD;EAiBI,gBAAA;ExD8gLH;AwDzgLD;EACE,oBAAA;EACA,cAAA;EACA,aAAA;EACA,cAAA;EACA,kBAAA;ExD2gLD;AwDz/KD;EAZE;IACE,cAAA;IACA,mBAAA;IxDwgLD;EwDtgLD;InDrEA,mDAAA;IACQ,2CAAA;IL8kLP;EwDrgLD;IAAY,cAAA;IxDwgLX;EACF;AwDngLD;EAFE;IAAY,cAAA;IxDygLX;EACF;AyDtpLD;EACE,oBAAA;EACA,eAAA;EACA,gBAAA;EACA,qBAAA;EAEA,6DAAA;EACA,iBAAA;EACA,qBAAA;EACA,kBAAA;EnCZA,YAAA;EAGA,0BAAA;EtBkqLD;AyDtpLC;EnCfA,cAAA;EAGA,2BAAA;EtBsqLD;AyDzpLC;EAAW,kBAAA;EAAmB,gBAAA;EzD6pL/B;AyD5pLC;EAAW,kBAAA;EAAmB,gBAAA;EzDgqL/B;AyD/pLC;EAAW,iBAAA;EAAmB,gBAAA;EzDmqL/B;AyDlqLC;EAAW,mBAAA;EAAmB,gBAAA;EzDsqL/B;AyDlqLD;EACE,kBAAA;EACA,kBAAA;EACA,gBAAA;EACA,oBAAA;EACA,uBAAA;EACA,2BAAA;EACA,oBAAA;EzDoqLD;AyDhqLD;EACE,oBAAA;EACA,UAAA;EACA,WAAA;EACA,2BAAA;EACA,qBAAA;EzDkqLD;AyD9pLC;EACE,WAAA;EACA,WAAA;EACA,mBAAA;EACA,yBAAA;EACA,2BAAA;EzDgqLH;AyD9pLC;EACE,WAAA;EACA,YAAA;EACA,qBAAA;EACA,yBAAA;EACA,2BAAA;EzDgqLH;AyD9pLC;EACE,WAAA;EACA,WAAA;EACA,qBAAA;EACA,yBAAA;EACA,2BAAA;EzDgqLH;AyD9pLC;EACE,UAAA;EACA,SAAA;EACA,kBAAA;EACA,6BAAA;EACA,6BAAA;EzDgqLH;AyD9pLC;EACE,UAAA;EACA,UAAA;EACA,kBAAA;EACA,6BAAA;EACA,4BAAA;EzDgqLH;AyD9pLC;EACE,QAAA;EACA,WAAA;EACA,mBAAA;EACA,yBAAA;EACA,8BAAA;EzDgqLH;AyD9pLC;EACE,QAAA;EACA,YAAA;EACA,kBAAA;EACA,yBAAA;EACA,8BAAA;EzDgqLH;AyD9pLC;EACE,QAAA;EACA,WAAA;EACA,kBAAA;EACA,yBAAA;EACA,8BAAA;EzDgqLH;A0D/vLD;EACE,oBAAA;EACA,QAAA;EACA,SAAA;EACA,eAAA;EACA,eAAA;EACA,kBAAA;EACA,cAAA;EAEA,6DAAA;EACA,iBAAA;EACA,qBAAA;EACA,yBAAA;EACA,kBAAA;EACA,2BAAA;EACA,sCAAA;UAAA,8BAAA;EACA,2BAAA;EACA,sCAAA;EACA,oBAAA;ErD6CA,mDAAA;EACQ,2CAAA;EqD1CR,qBAAA;E1D+vLD;A0D5vLC;EAAY,mBAAA;E1D+vLb;A0D9vLC;EAAY,mBAAA;E1DiwLb;A0DhwLC;EAAY,kBAAA;E1DmwLb;A0DlwLC;EAAY,oBAAA;E1DqwLb;A0DlwLD;EACE,WAAA;EACA,mBAAA;EACA,iBAAA;EACA,2BAAA;EACA,kCAAA;EACA,4BAAA;E1DowLD;A0DjwLD;EACE,mBAAA;E1DmwLD;A0D3vLC;;EAEE,oBAAA;EACA,gBAAA;EACA,UAAA;EACA,WAAA;EACA,2BAAA;EACA,qBAAA;E1D6vLH;A0D1vLD;EACE,oBAAA;E1D4vLD;A0D1vLD;EACE,oBAAA;EACA,aAAA;E1D4vLD;A0DxvLC;EACE,WAAA;EACA,oBAAA;EACA,wBAAA;EACA,2BAAA;EACA,uCAAA;EACA,eAAA;E1D0vLH;A0DzvLG;EACE,cAAA;EACA,aAAA;EACA,oBAAA;EACA,wBAAA;EACA,2BAAA;E1D2vLL;A0DxvLC;EACE,UAAA;EACA,aAAA;EACA,mBAAA;EACA,sBAAA;EACA,6BAAA;EACA,yCAAA;E1D0vLH;A0DzvLG;EACE,cAAA;EACA,WAAA;EACA,eAAA;EACA,sBAAA;EACA,6BAAA;E1D2vLL;A0DxvLC;EACE,WAAA;EACA,oBAAA;EACA,qBAAA;EACA,8BAAA;EACA,0CAAA;EACA,YAAA;E1D0vLH;A0DzvLG;EACE,cAAA;EACA,UAAA;EACA,oBAAA;EACA,qBAAA;EACA,8BAAA;E1D2vLL;A0DvvLC;EACE,UAAA;EACA,cAAA;EACA,mBAAA;EACA,uBAAA;EACA,4BAAA;EACA,wCAAA;E1DyvLH;A0DxvLG;EACE,cAAA;EACA,YAAA;EACA,uBAAA;EACA,4BAAA;EACA,eAAA;E1D0vLL;A2Dv3LD;EACE,oBAAA;E3Dy3LD;A2Dt3LD;EACE,oBAAA;EACA,kBAAA;EACA,aAAA;E3Dw3LD;A2D33LD;EAMI,eAAA;EACA,oBAAA;EtD6KF,2CAAA;EACK,sCAAA;EACG,mCAAA;EL4sLT;A2Dl4LD;;EAcM,gBAAA;E3Dw3LL;A2D91LC;EAAA;ItDiKA,wDAAA;IAEK,8CAAA;IACG,wCAAA;IA7JR,qCAAA;IAEQ,6BAAA;IA+GR,2BAAA;IAEQ,mBAAA;ILivLP;E2D53LG;;ItDmHJ,4CAAA;IACQ,oCAAA;IsDjHF,SAAA;I3D+3LL;E2D73LG;;ItD8GJ,6CAAA;IACQ,qCAAA;IsD5GF,SAAA;I3Dg4LL;E2D93LG;;;ItDyGJ,yCAAA;IACQ,iCAAA;IsDtGF,SAAA;I3Di4LL;EACF;A2Dv6LD;;;EA6CI,gBAAA;E3D+3LH;A2D56LD;EAiDI,SAAA;E3D83LH;A2D/6LD;;EAsDI,oBAAA;EACA,QAAA;EACA,aAAA;E3D63LH;A2Dr7LD;EA4DI,YAAA;E3D43LH;A2Dx7LD;EA+DI,aAAA;E3D43LH;A2D37LD;;EAmEI,SAAA;E3D43LH;A2D/7LD;EAuEI,aAAA;E3D23LH;A2Dl8LD;EA0EI,YAAA;E3D23LH;A2Dn3LD;EACE,oBAAA;EACA,QAAA;EACA,SAAA;EACA,WAAA;EACA,YAAA;ErC9FA,cAAA;EAGA,2BAAA;EqC6FA,iBAAA;EACA,gBAAA;EACA,oBAAA;EACA,2CAAA;E3Ds3LD;A2Dj3LC;EblGE,oGAAA;EACA,+FAAA;EACA,sHAAA;EAAA,gGAAA;EACA,6BAAA;EACA,wHAAA;E9Cs9LH;A2Dr3LC;EACE,YAAA;EACA,UAAA;EbvGA,oGAAA;EACA,+FAAA;EACA,sHAAA;EAAA,gGAAA;EACA,6BAAA;EACA,wHAAA;E9C+9LH;A2Dv3LC;;EAEE,YAAA;EACA,gBAAA;EACA,uBAAA;ErCtHF,cAAA;EAGA,2BAAA;EtB8+LD;A2Dx5LD;;;;EAsCI,oBAAA;EACA,UAAA;EACA,YAAA;EACA,uBAAA;E3Dw3LH;A2Dj6LD;;EA6CI,WAAA;EACA,oBAAA;E3Dw3LH;A2Dt6LD;;EAkDI,YAAA;EACA,qBAAA;E3Dw3LH;A2D36LD;;EAuDI,aAAA;EACA,cAAA;EACA,mBAAA;EACA,gBAAA;EACA,oBAAA;E3Dw3LH;A2Dn3LG;EACE,kBAAA;E3Dq3LL;A2Dj3LG;EACE,kBAAA;E3Dm3LL;A2Dz2LD;EACE,oBAAA;EACA,cAAA;EACA,WAAA;EACA,aAAA;EACA,YAAA;EACA,mBAAA;EACA,iBAAA;EACA,kBAAA;EACA,oBAAA;E3D22LD;A2Dp3LD;EAYI,uBAAA;EACA,aAAA;EACA,cAAA;EACA,aAAA;EACA,qBAAA;EACA,2BAAA;EACA,qBAAA;EACA,iBAAA;EAWA,2BAAA;EACA,oCAAA;E3Di2LH;A2Dh4LD;EAkCI,WAAA;EACA,aAAA;EACA,cAAA;EACA,2BAAA;E3Di2LH;A2D11LD;EACE,oBAAA;EACA,WAAA;EACA,YAAA;EACA,cAAA;EACA,aAAA;EACA,mBAAA;EACA,sBAAA;EACA,gBAAA;EACA,oBAAA;EACA,2CAAA;E3D41LD;A2D31LC;EACE,mBAAA;E3D61LH;A2DpzLD;EAhCE;;;;IAKI,aAAA;IACA,cAAA;IACA,mBAAA;IACA,iBAAA;I3Ds1LH;E2D91LD;;IAYI,oBAAA;I3Ds1LH;E2Dl2LD;;IAgBI,qBAAA;I3Ds1LH;E2Dj1LD;IACE,WAAA;IACA,YAAA;IACA,sBAAA;I3Dm1LD;E2D/0LD;IACE,cAAA;I3Di1LD;EACF;A4D/kMC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAEE,cAAA;EACA,gBAAA;E5D6mMH;A4D3mMC;;;;;;;;;;;;;;;EACE,aAAA;E5D2nMH;AiCnoMD;E4BRE,gBAAA;EACA,mBAAA;EACA,oBAAA;E7D8oMD;AiCroMD;EACE,yBAAA;EjCuoMD;AiCroMD;EACE,wBAAA;EjCuoMD;AiC/nMD;EACE,0BAAA;EjCioMD;AiC/nMD;EACE,2BAAA;EjCioMD;AiC/nMD;EACE,oBAAA;EjCioMD;AiC/nMD;E6BzBE,aAAA;EACA,oBAAA;EACA,mBAAA;EACA,+BAAA;EACA,WAAA;E9D2pMD;AiC7nMD;EACE,0BAAA;EACA,+BAAA;EjC+nMD;AiCxnMD;EACE,iBAAA;EjC0nMD;A+D5pMD;EACE,qBAAA;E/D8pMD;A+DxpMD;;;;ECdE,0BAAA;EhE4qMD;A+DvpMD;;;;;;;;;;;;EAYE,0BAAA;E/DypMD;A+DlpMD;EAAA;IChDE,2BAAA;IhEssMC;EgErsMD;IAAU,gBAAA;IhEwsMT;EgEvsMD;IAAU,+BAAA;IhE0sMT;EgEzsMD;;IACU,gCAAA;IhE4sMT;EACF;A+D5pMD;EAAA;IAFI,2BAAA;I/DkqMD;EACF;A+D5pMD;EAAA;IAFI,4BAAA;I/DkqMD;EACF;A+D5pMD;EAAA;IAFI,kCAAA;I/DkqMD;EACF;A+D3pMD;EAAA;ICrEE,2BAAA;IhEouMC;EgEnuMD;IAAU,gBAAA;IhEsuMT;EgEruMD;IAAU,+BAAA;IhEwuMT;EgEvuMD;;IACU,gCAAA;IhE0uMT;EACF;A+DrqMD;EAAA;IAFI,2BAAA;I/D2qMD;EACF;A+DrqMD;EAAA;IAFI,4BAAA;I/D2qMD;EACF;A+DrqMD;EAAA;IAFI,kCAAA;I/D2qMD;EACF;A+DpqMD;EAAA;IC1FE,2BAAA;IhEkwMC;EgEjwMD;IAAU,gBAAA;IhEowMT;EgEnwMD;IAAU,+BAAA;IhEswMT;EgErwMD;;IACU,gCAAA;IhEwwMT;EACF;A+D9qMD;EAAA;IAFI,2BAAA;I/DorMD;EACF;A+D9qMD;EAAA;IAFI,4BAAA;I/DorMD;EACF;A+D9qMD;EAAA;IAFI,kCAAA;I/DorMD;EACF;A+D7qMD;EAAA;IC/GE,2BAAA;IhEgyMC;EgE/xMD;IAAU,gBAAA;IhEkyMT;EgEjyMD;IAAU,+BAAA;IhEoyMT;EgEnyMD;;IACU,gCAAA;IhEsyMT;EACF;A+DvrMD;EAAA;IAFI,2BAAA;I/D6rMD;EACF;A+DvrMD;EAAA;IAFI,4BAAA;I/D6rMD;EACF;A+DvrMD;EAAA;IAFI,kCAAA;I/D6rMD;EACF;A+DtrMD;EAAA;IC5HE,0BAAA;IhEszMC;EACF;A+DtrMD;EAAA;ICjIE,0BAAA;IhE2zMC;EACF;A+DtrMD;EAAA;ICtIE,0BAAA;IhEg0MC;EACF;A+DtrMD;EAAA;IC3IE,0BAAA;IhEq0MC;EACF;A+DnrMD;ECnJE,0BAAA;EhEy0MD;A+DhrMD;EAAA;ICjKE,2BAAA;IhEq1MC;EgEp1MD;IAAU,gBAAA;IhEu1MT;EgEt1MD;IAAU,+BAAA;IhEy1MT;EgEx1MD;;IACU,gCAAA;IhE21MT;EACF;A+D9rMD;EACE,0BAAA;E/DgsMD;A+D3rMD;EAAA;IAFI,2BAAA;I/DisMD;EACF;A+D/rMD;EACE,0BAAA;E/DisMD;A+D5rMD;EAAA;IAFI,4BAAA;I/DksMD;EACF;A+DhsMD;EACE,0BAAA;E/DksMD;A+D7rMD;EAAA;IAFI,kCAAA;I/DmsMD;EACF;A+D5rMD;EAAA;ICpLE,0BAAA;IhEo3MC;EACF","file":"bootstrap.css","sourcesContent":["/*! normalize.css v3.0.2 | MIT License | git.io/normalize */\nhtml {\n font-family: sans-serif;\n -ms-text-size-adjust: 100%;\n -webkit-text-size-adjust: 100%;\n}\nbody {\n margin: 0;\n}\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n display: block;\n}\naudio,\ncanvas,\nprogress,\nvideo {\n display: inline-block;\n vertical-align: baseline;\n}\naudio:not([controls]) {\n display: none;\n height: 0;\n}\n[hidden],\ntemplate {\n display: none;\n}\na {\n background-color: transparent;\n}\na:active,\na:hover {\n outline: 0;\n}\nabbr[title] {\n border-bottom: 1px dotted;\n}\nb,\nstrong {\n font-weight: bold;\n}\ndfn {\n font-style: italic;\n}\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\nmark {\n background: #ff0;\n color: #000;\n}\nsmall {\n font-size: 80%;\n}\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\nsup {\n top: -0.5em;\n}\nsub {\n bottom: -0.25em;\n}\nimg {\n border: 0;\n}\nsvg:not(:root) {\n overflow: hidden;\n}\nfigure {\n margin: 1em 40px;\n}\nhr {\n -moz-box-sizing: content-box;\n box-sizing: content-box;\n height: 0;\n}\npre {\n overflow: auto;\n}\ncode,\nkbd,\npre,\nsamp {\n font-family: monospace, monospace;\n font-size: 1em;\n}\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n color: inherit;\n font: inherit;\n margin: 0;\n}\nbutton {\n overflow: visible;\n}\nbutton,\nselect {\n text-transform: none;\n}\nbutton,\nhtml input[type=\"button\"],\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n -webkit-appearance: button;\n cursor: pointer;\n}\nbutton[disabled],\nhtml input[disabled] {\n cursor: default;\n}\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n border: 0;\n padding: 0;\n}\ninput {\n line-height: normal;\n}\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n box-sizing: border-box;\n padding: 0;\n}\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\ninput[type=\"search\"] {\n -webkit-appearance: textfield;\n -moz-box-sizing: content-box;\n -webkit-box-sizing: content-box;\n box-sizing: content-box;\n}\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\nfieldset {\n border: 1px solid #c0c0c0;\n margin: 0 2px;\n padding: 0.35em 0.625em 0.75em;\n}\nlegend {\n border: 0;\n padding: 0;\n}\ntextarea {\n overflow: auto;\n}\noptgroup {\n font-weight: bold;\n}\ntable {\n border-collapse: collapse;\n border-spacing: 0;\n}\ntd,\nth {\n padding: 0;\n}\n/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n@media print {\n *,\n *:before,\n *:after {\n background: transparent !important;\n color: #000 !important;\n box-shadow: none !important;\n text-shadow: none !important;\n }\n a,\n a:visited {\n text-decoration: underline;\n }\n a[href]:after {\n content: \" (\" attr(href) \")\";\n }\n abbr[title]:after {\n content: \" (\" attr(title) \")\";\n }\n a[href^=\"#\"]:after,\n a[href^=\"javascript:\"]:after {\n content: \"\";\n }\n pre,\n blockquote {\n border: 1px solid #999;\n page-break-inside: avoid;\n }\n thead {\n display: table-header-group;\n }\n tr,\n img {\n page-break-inside: avoid;\n }\n img {\n max-width: 100% !important;\n }\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n h2,\n h3 {\n page-break-after: avoid;\n }\n select {\n background: #fff !important;\n }\n .navbar {\n display: none;\n }\n .btn > .caret,\n .dropup > .btn > .caret {\n border-top-color: #000 !important;\n }\n .label {\n border: 1px solid #000;\n }\n .table {\n border-collapse: collapse !important;\n }\n .table td,\n .table th {\n background-color: #fff !important;\n }\n .table-bordered th,\n .table-bordered td {\n border: 1px solid #ddd !important;\n }\n}\n@font-face {\n font-family: 'Glyphicons Halflings';\n src: url('../fonts/glyphicons-halflings-regular.eot');\n src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');\n}\n.glyphicon {\n position: relative;\n top: 1px;\n display: inline-block;\n font-family: 'Glyphicons Halflings';\n font-style: normal;\n font-weight: normal;\n line-height: 1;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n.glyphicon-asterisk:before {\n content: \"\\2a\";\n}\n.glyphicon-plus:before {\n content: \"\\2b\";\n}\n.glyphicon-euro:before,\n.glyphicon-eur:before {\n content: \"\\20ac\";\n}\n.glyphicon-minus:before {\n content: \"\\2212\";\n}\n.glyphicon-cloud:before {\n content: \"\\2601\";\n}\n.glyphicon-envelope:before {\n content: \"\\2709\";\n}\n.glyphicon-pencil:before {\n content: \"\\270f\";\n}\n.glyphicon-glass:before {\n content: \"\\e001\";\n}\n.glyphicon-music:before {\n content: \"\\e002\";\n}\n.glyphicon-search:before {\n content: \"\\e003\";\n}\n.glyphicon-heart:before {\n content: \"\\e005\";\n}\n.glyphicon-star:before {\n content: \"\\e006\";\n}\n.glyphicon-star-empty:before {\n content: \"\\e007\";\n}\n.glyphicon-user:before {\n content: \"\\e008\";\n}\n.glyphicon-film:before {\n content: \"\\e009\";\n}\n.glyphicon-th-large:before {\n content: \"\\e010\";\n}\n.glyphicon-th:before {\n content: \"\\e011\";\n}\n.glyphicon-th-list:before {\n content: \"\\e012\";\n}\n.glyphicon-ok:before {\n content: \"\\e013\";\n}\n.glyphicon-remove:before {\n content: \"\\e014\";\n}\n.glyphicon-zoom-in:before {\n content: \"\\e015\";\n}\n.glyphicon-zoom-out:before {\n content: \"\\e016\";\n}\n.glyphicon-off:before {\n content: \"\\e017\";\n}\n.glyphicon-signal:before {\n content: \"\\e018\";\n}\n.glyphicon-cog:before {\n content: \"\\e019\";\n}\n.glyphicon-trash:before {\n content: \"\\e020\";\n}\n.glyphicon-home:before {\n content: \"\\e021\";\n}\n.glyphicon-file:before {\n content: \"\\e022\";\n}\n.glyphicon-time:before {\n content: \"\\e023\";\n}\n.glyphicon-road:before {\n content: \"\\e024\";\n}\n.glyphicon-download-alt:before {\n content: \"\\e025\";\n}\n.glyphicon-download:before {\n content: \"\\e026\";\n}\n.glyphicon-upload:before {\n content: \"\\e027\";\n}\n.glyphicon-inbox:before {\n content: \"\\e028\";\n}\n.glyphicon-play-circle:before {\n content: \"\\e029\";\n}\n.glyphicon-repeat:before {\n content: \"\\e030\";\n}\n.glyphicon-refresh:before {\n content: \"\\e031\";\n}\n.glyphicon-list-alt:before {\n content: \"\\e032\";\n}\n.glyphicon-lock:before {\n content: \"\\e033\";\n}\n.glyphicon-flag:before {\n content: \"\\e034\";\n}\n.glyphicon-headphones:before {\n content: \"\\e035\";\n}\n.glyphicon-volume-off:before {\n content: \"\\e036\";\n}\n.glyphicon-volume-down:before {\n content: \"\\e037\";\n}\n.glyphicon-volume-up:before {\n content: \"\\e038\";\n}\n.glyphicon-qrcode:before {\n content: \"\\e039\";\n}\n.glyphicon-barcode:before {\n content: \"\\e040\";\n}\n.glyphicon-tag:before {\n content: \"\\e041\";\n}\n.glyphicon-tags:before {\n content: \"\\e042\";\n}\n.glyphicon-book:before {\n content: \"\\e043\";\n}\n.glyphicon-bookmark:before {\n content: \"\\e044\";\n}\n.glyphicon-print:before {\n content: \"\\e045\";\n}\n.glyphicon-camera:before {\n content: \"\\e046\";\n}\n.glyphicon-font:before {\n content: \"\\e047\";\n}\n.glyphicon-bold:before {\n content: \"\\e048\";\n}\n.glyphicon-italic:before {\n content: \"\\e049\";\n}\n.glyphicon-text-height:before {\n content: \"\\e050\";\n}\n.glyphicon-text-width:before {\n content: \"\\e051\";\n}\n.glyphicon-align-left:before {\n content: \"\\e052\";\n}\n.glyphicon-align-center:before {\n content: \"\\e053\";\n}\n.glyphicon-align-right:before {\n content: \"\\e054\";\n}\n.glyphicon-align-justify:before {\n content: \"\\e055\";\n}\n.glyphicon-list:before {\n content: \"\\e056\";\n}\n.glyphicon-indent-left:before {\n content: \"\\e057\";\n}\n.glyphicon-indent-right:before {\n content: \"\\e058\";\n}\n.glyphicon-facetime-video:before {\n content: \"\\e059\";\n}\n.glyphicon-picture:before {\n content: \"\\e060\";\n}\n.glyphicon-map-marker:before {\n content: \"\\e062\";\n}\n.glyphicon-adjust:before {\n content: \"\\e063\";\n}\n.glyphicon-tint:before {\n content: \"\\e064\";\n}\n.glyphicon-edit:before {\n content: \"\\e065\";\n}\n.glyphicon-share:before {\n content: \"\\e066\";\n}\n.glyphicon-check:before {\n content: \"\\e067\";\n}\n.glyphicon-move:before {\n content: \"\\e068\";\n}\n.glyphicon-step-backward:before {\n content: \"\\e069\";\n}\n.glyphicon-fast-backward:before {\n content: \"\\e070\";\n}\n.glyphicon-backward:before {\n content: \"\\e071\";\n}\n.glyphicon-play:before {\n content: \"\\e072\";\n}\n.glyphicon-pause:before {\n content: \"\\e073\";\n}\n.glyphicon-stop:before {\n content: \"\\e074\";\n}\n.glyphicon-forward:before {\n content: \"\\e075\";\n}\n.glyphicon-fast-forward:before {\n content: \"\\e076\";\n}\n.glyphicon-step-forward:before {\n content: \"\\e077\";\n}\n.glyphicon-eject:before {\n content: \"\\e078\";\n}\n.glyphicon-chevron-left:before {\n content: \"\\e079\";\n}\n.glyphicon-chevron-right:before {\n content: \"\\e080\";\n}\n.glyphicon-plus-sign:before {\n content: \"\\e081\";\n}\n.glyphicon-minus-sign:before {\n content: \"\\e082\";\n}\n.glyphicon-remove-sign:before {\n content: \"\\e083\";\n}\n.glyphicon-ok-sign:before {\n content: \"\\e084\";\n}\n.glyphicon-question-sign:before {\n content: \"\\e085\";\n}\n.glyphicon-info-sign:before {\n content: \"\\e086\";\n}\n.glyphicon-screenshot:before {\n content: \"\\e087\";\n}\n.glyphicon-remove-circle:before {\n content: \"\\e088\";\n}\n.glyphicon-ok-circle:before {\n content: \"\\e089\";\n}\n.glyphicon-ban-circle:before {\n content: \"\\e090\";\n}\n.glyphicon-arrow-left:before {\n content: \"\\e091\";\n}\n.glyphicon-arrow-right:before {\n content: \"\\e092\";\n}\n.glyphicon-arrow-up:before {\n content: \"\\e093\";\n}\n.glyphicon-arrow-down:before {\n content: \"\\e094\";\n}\n.glyphicon-share-alt:before {\n content: \"\\e095\";\n}\n.glyphicon-resize-full:before {\n content: \"\\e096\";\n}\n.glyphicon-resize-small:before {\n content: \"\\e097\";\n}\n.glyphicon-exclamation-sign:before {\n content: \"\\e101\";\n}\n.glyphicon-gift:before {\n content: \"\\e102\";\n}\n.glyphicon-leaf:before {\n content: \"\\e103\";\n}\n.glyphicon-fire:before {\n content: \"\\e104\";\n}\n.glyphicon-eye-open:before {\n content: \"\\e105\";\n}\n.glyphicon-eye-close:before {\n content: \"\\e106\";\n}\n.glyphicon-warning-sign:before {\n content: \"\\e107\";\n}\n.glyphicon-plane:before {\n content: \"\\e108\";\n}\n.glyphicon-calendar:before {\n content: \"\\e109\";\n}\n.glyphicon-random:before {\n content: \"\\e110\";\n}\n.glyphicon-comment:before {\n content: \"\\e111\";\n}\n.glyphicon-magnet:before {\n content: \"\\e112\";\n}\n.glyphicon-chevron-up:before {\n content: \"\\e113\";\n}\n.glyphicon-chevron-down:before {\n content: \"\\e114\";\n}\n.glyphicon-retweet:before {\n content: \"\\e115\";\n}\n.glyphicon-shopping-cart:before {\n content: \"\\e116\";\n}\n.glyphicon-folder-close:before {\n content: \"\\e117\";\n}\n.glyphicon-folder-open:before {\n content: \"\\e118\";\n}\n.glyphicon-resize-vertical:before {\n content: \"\\e119\";\n}\n.glyphicon-resize-horizontal:before {\n content: \"\\e120\";\n}\n.glyphicon-hdd:before {\n content: \"\\e121\";\n}\n.glyphicon-bullhorn:before {\n content: \"\\e122\";\n}\n.glyphicon-bell:before {\n content: \"\\e123\";\n}\n.glyphicon-certificate:before {\n content: \"\\e124\";\n}\n.glyphicon-thumbs-up:before {\n content: \"\\e125\";\n}\n.glyphicon-thumbs-down:before {\n content: \"\\e126\";\n}\n.glyphicon-hand-right:before {\n content: \"\\e127\";\n}\n.glyphicon-hand-left:before {\n content: \"\\e128\";\n}\n.glyphicon-hand-up:before {\n content: \"\\e129\";\n}\n.glyphicon-hand-down:before {\n content: \"\\e130\";\n}\n.glyphicon-circle-arrow-right:before {\n content: \"\\e131\";\n}\n.glyphicon-circle-arrow-left:before {\n content: \"\\e132\";\n}\n.glyphicon-circle-arrow-up:before {\n content: \"\\e133\";\n}\n.glyphicon-circle-arrow-down:before {\n content: \"\\e134\";\n}\n.glyphicon-globe:before {\n content: \"\\e135\";\n}\n.glyphicon-wrench:before {\n content: \"\\e136\";\n}\n.glyphicon-tasks:before {\n content: \"\\e137\";\n}\n.glyphicon-filter:before {\n content: \"\\e138\";\n}\n.glyphicon-briefcase:before {\n content: \"\\e139\";\n}\n.glyphicon-fullscreen:before {\n content: \"\\e140\";\n}\n.glyphicon-dashboard:before {\n content: \"\\e141\";\n}\n.glyphicon-paperclip:before {\n content: \"\\e142\";\n}\n.glyphicon-heart-empty:before {\n content: \"\\e143\";\n}\n.glyphicon-link:before {\n content: \"\\e144\";\n}\n.glyphicon-phone:before {\n content: \"\\e145\";\n}\n.glyphicon-pushpin:before {\n content: \"\\e146\";\n}\n.glyphicon-usd:before {\n content: \"\\e148\";\n}\n.glyphicon-gbp:before {\n content: \"\\e149\";\n}\n.glyphicon-sort:before {\n content: \"\\e150\";\n}\n.glyphicon-sort-by-alphabet:before {\n content: \"\\e151\";\n}\n.glyphicon-sort-by-alphabet-alt:before {\n content: \"\\e152\";\n}\n.glyphicon-sort-by-order:before {\n content: \"\\e153\";\n}\n.glyphicon-sort-by-order-alt:before {\n content: \"\\e154\";\n}\n.glyphicon-sort-by-attributes:before {\n content: \"\\e155\";\n}\n.glyphicon-sort-by-attributes-alt:before {\n content: \"\\e156\";\n}\n.glyphicon-unchecked:before {\n content: \"\\e157\";\n}\n.glyphicon-expand:before {\n content: \"\\e158\";\n}\n.glyphicon-collapse-down:before {\n content: \"\\e159\";\n}\n.glyphicon-collapse-up:before {\n content: \"\\e160\";\n}\n.glyphicon-log-in:before {\n content: \"\\e161\";\n}\n.glyphicon-flash:before {\n content: \"\\e162\";\n}\n.glyphicon-log-out:before {\n content: \"\\e163\";\n}\n.glyphicon-new-window:before {\n content: \"\\e164\";\n}\n.glyphicon-record:before {\n content: \"\\e165\";\n}\n.glyphicon-save:before {\n content: \"\\e166\";\n}\n.glyphicon-open:before {\n content: \"\\e167\";\n}\n.glyphicon-saved:before {\n content: \"\\e168\";\n}\n.glyphicon-import:before {\n content: \"\\e169\";\n}\n.glyphicon-export:before {\n content: \"\\e170\";\n}\n.glyphicon-send:before {\n content: \"\\e171\";\n}\n.glyphicon-floppy-disk:before {\n content: \"\\e172\";\n}\n.glyphicon-floppy-saved:before {\n content: \"\\e173\";\n}\n.glyphicon-floppy-remove:before {\n content: \"\\e174\";\n}\n.glyphicon-floppy-save:before {\n content: \"\\e175\";\n}\n.glyphicon-floppy-open:before {\n content: \"\\e176\";\n}\n.glyphicon-credit-card:before {\n content: \"\\e177\";\n}\n.glyphicon-transfer:before {\n content: \"\\e178\";\n}\n.glyphicon-cutlery:before {\n content: \"\\e179\";\n}\n.glyphicon-header:before {\n content: \"\\e180\";\n}\n.glyphicon-compressed:before {\n content: \"\\e181\";\n}\n.glyphicon-earphone:before {\n content: \"\\e182\";\n}\n.glyphicon-phone-alt:before {\n content: \"\\e183\";\n}\n.glyphicon-tower:before {\n content: \"\\e184\";\n}\n.glyphicon-stats:before {\n content: \"\\e185\";\n}\n.glyphicon-sd-video:before {\n content: \"\\e186\";\n}\n.glyphicon-hd-video:before {\n content: \"\\e187\";\n}\n.glyphicon-subtitles:before {\n content: \"\\e188\";\n}\n.glyphicon-sound-stereo:before {\n content: \"\\e189\";\n}\n.glyphicon-sound-dolby:before {\n content: \"\\e190\";\n}\n.glyphicon-sound-5-1:before {\n content: \"\\e191\";\n}\n.glyphicon-sound-6-1:before {\n content: \"\\e192\";\n}\n.glyphicon-sound-7-1:before {\n content: \"\\e193\";\n}\n.glyphicon-copyright-mark:before {\n content: \"\\e194\";\n}\n.glyphicon-registration-mark:before {\n content: \"\\e195\";\n}\n.glyphicon-cloud-download:before {\n content: \"\\e197\";\n}\n.glyphicon-cloud-upload:before {\n content: \"\\e198\";\n}\n.glyphicon-tree-conifer:before {\n content: \"\\e199\";\n}\n.glyphicon-tree-deciduous:before {\n content: \"\\e200\";\n}\n.glyphicon-cd:before {\n content: \"\\e201\";\n}\n.glyphicon-save-file:before {\n content: \"\\e202\";\n}\n.glyphicon-open-file:before {\n content: \"\\e203\";\n}\n.glyphicon-level-up:before {\n content: \"\\e204\";\n}\n.glyphicon-copy:before {\n content: \"\\e205\";\n}\n.glyphicon-paste:before {\n content: \"\\e206\";\n}\n.glyphicon-alert:before {\n content: \"\\e209\";\n}\n.glyphicon-equalizer:before {\n content: \"\\e210\";\n}\n.glyphicon-king:before {\n content: \"\\e211\";\n}\n.glyphicon-queen:before {\n content: \"\\e212\";\n}\n.glyphicon-pawn:before {\n content: \"\\e213\";\n}\n.glyphicon-bishop:before {\n content: \"\\e214\";\n}\n.glyphicon-knight:before {\n content: \"\\e215\";\n}\n.glyphicon-baby-formula:before {\n content: \"\\e216\";\n}\n.glyphicon-tent:before {\n content: \"\\26fa\";\n}\n.glyphicon-blackboard:before {\n content: \"\\e218\";\n}\n.glyphicon-bed:before {\n content: \"\\e219\";\n}\n.glyphicon-apple:before {\n content: \"\\f8ff\";\n}\n.glyphicon-erase:before {\n content: \"\\e221\";\n}\n.glyphicon-hourglass:before {\n content: \"\\231b\";\n}\n.glyphicon-lamp:before {\n content: \"\\e223\";\n}\n.glyphicon-duplicate:before {\n content: \"\\e224\";\n}\n.glyphicon-piggy-bank:before {\n content: \"\\e225\";\n}\n.glyphicon-scissors:before {\n content: \"\\e226\";\n}\n.glyphicon-bitcoin:before {\n content: \"\\e227\";\n}\n.glyphicon-yen:before {\n content: \"\\00a5\";\n}\n.glyphicon-ruble:before {\n content: \"\\20bd\";\n}\n.glyphicon-scale:before {\n content: \"\\e230\";\n}\n.glyphicon-ice-lolly:before {\n content: \"\\e231\";\n}\n.glyphicon-ice-lolly-tasted:before {\n content: \"\\e232\";\n}\n.glyphicon-education:before {\n content: \"\\e233\";\n}\n.glyphicon-option-horizontal:before {\n content: \"\\e234\";\n}\n.glyphicon-option-vertical:before {\n content: \"\\e235\";\n}\n.glyphicon-menu-hamburger:before {\n content: \"\\e236\";\n}\n.glyphicon-modal-window:before {\n content: \"\\e237\";\n}\n.glyphicon-oil:before {\n content: \"\\e238\";\n}\n.glyphicon-grain:before {\n content: \"\\e239\";\n}\n.glyphicon-sunglasses:before {\n content: \"\\e240\";\n}\n.glyphicon-text-size:before {\n content: \"\\e241\";\n}\n.glyphicon-text-color:before {\n content: \"\\e242\";\n}\n.glyphicon-text-background:before {\n content: \"\\e243\";\n}\n.glyphicon-object-align-top:before {\n content: \"\\e244\";\n}\n.glyphicon-object-align-bottom:before {\n content: \"\\e245\";\n}\n.glyphicon-object-align-horizontal:before {\n content: \"\\e246\";\n}\n.glyphicon-object-align-left:before {\n content: \"\\e247\";\n}\n.glyphicon-object-align-vertical:before {\n content: \"\\e248\";\n}\n.glyphicon-object-align-right:before {\n content: \"\\e249\";\n}\n.glyphicon-triangle-right:before {\n content: \"\\e250\";\n}\n.glyphicon-triangle-left:before {\n content: \"\\e251\";\n}\n.glyphicon-triangle-bottom:before {\n content: \"\\e252\";\n}\n.glyphicon-triangle-top:before {\n content: \"\\e253\";\n}\n.glyphicon-console:before {\n content: \"\\e254\";\n}\n.glyphicon-superscript:before {\n content: \"\\e255\";\n}\n.glyphicon-subscript:before {\n content: \"\\e256\";\n}\n.glyphicon-menu-left:before {\n content: \"\\e257\";\n}\n.glyphicon-menu-right:before {\n content: \"\\e258\";\n}\n.glyphicon-menu-down:before {\n content: \"\\e259\";\n}\n.glyphicon-menu-up:before {\n content: \"\\e260\";\n}\n* {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\n*:before,\n*:after {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\nhtml {\n font-size: 10px;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\nbody {\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-size: 14px;\n line-height: 1.42857143;\n color: #333333;\n background-color: #ffffff;\n}\ninput,\nbutton,\nselect,\ntextarea {\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\na {\n color: #337ab7;\n text-decoration: none;\n}\na:hover,\na:focus {\n color: #23527c;\n text-decoration: underline;\n}\na:focus {\n outline: thin dotted;\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\nfigure {\n margin: 0;\n}\nimg {\n vertical-align: middle;\n}\n.img-responsive,\n.thumbnail > img,\n.thumbnail a > img,\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n display: block;\n max-width: 100%;\n height: auto;\n}\n.img-rounded {\n border-radius: 6px;\n}\n.img-thumbnail {\n padding: 4px;\n line-height: 1.42857143;\n background-color: #ffffff;\n border: 1px solid #dddddd;\n border-radius: 4px;\n -webkit-transition: all 0.2s ease-in-out;\n -o-transition: all 0.2s ease-in-out;\n transition: all 0.2s ease-in-out;\n display: inline-block;\n max-width: 100%;\n height: auto;\n}\n.img-circle {\n border-radius: 50%;\n}\nhr {\n margin-top: 20px;\n margin-bottom: 20px;\n border: 0;\n border-top: 1px solid #eeeeee;\n}\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n border: 0;\n}\n.sr-only-focusable:active,\n.sr-only-focusable:focus {\n position: static;\n width: auto;\n height: auto;\n margin: 0;\n overflow: visible;\n clip: auto;\n}\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\n.h1,\n.h2,\n.h3,\n.h4,\n.h5,\n.h6 {\n font-family: inherit;\n font-weight: 500;\n line-height: 1.1;\n color: inherit;\n}\nh1 small,\nh2 small,\nh3 small,\nh4 small,\nh5 small,\nh6 small,\n.h1 small,\n.h2 small,\n.h3 small,\n.h4 small,\n.h5 small,\n.h6 small,\nh1 .small,\nh2 .small,\nh3 .small,\nh4 .small,\nh5 .small,\nh6 .small,\n.h1 .small,\n.h2 .small,\n.h3 .small,\n.h4 .small,\n.h5 .small,\n.h6 .small {\n font-weight: normal;\n line-height: 1;\n color: #777777;\n}\nh1,\n.h1,\nh2,\n.h2,\nh3,\n.h3 {\n margin-top: 20px;\n margin-bottom: 10px;\n}\nh1 small,\n.h1 small,\nh2 small,\n.h2 small,\nh3 small,\n.h3 small,\nh1 .small,\n.h1 .small,\nh2 .small,\n.h2 .small,\nh3 .small,\n.h3 .small {\n font-size: 65%;\n}\nh4,\n.h4,\nh5,\n.h5,\nh6,\n.h6 {\n margin-top: 10px;\n margin-bottom: 10px;\n}\nh4 small,\n.h4 small,\nh5 small,\n.h5 small,\nh6 small,\n.h6 small,\nh4 .small,\n.h4 .small,\nh5 .small,\n.h5 .small,\nh6 .small,\n.h6 .small {\n font-size: 75%;\n}\nh1,\n.h1 {\n font-size: 36px;\n}\nh2,\n.h2 {\n font-size: 30px;\n}\nh3,\n.h3 {\n font-size: 24px;\n}\nh4,\n.h4 {\n font-size: 18px;\n}\nh5,\n.h5 {\n font-size: 14px;\n}\nh6,\n.h6 {\n font-size: 12px;\n}\np {\n margin: 0 0 10px;\n}\n.lead {\n margin-bottom: 20px;\n font-size: 16px;\n font-weight: 300;\n line-height: 1.4;\n}\n@media (min-width: 768px) {\n .lead {\n font-size: 21px;\n }\n}\nsmall,\n.small {\n font-size: 85%;\n}\nmark,\n.mark {\n background-color: #fcf8e3;\n padding: .2em;\n}\n.text-left {\n text-align: left;\n}\n.text-right {\n text-align: right;\n}\n.text-center {\n text-align: center;\n}\n.text-justify {\n text-align: justify;\n}\n.text-nowrap {\n white-space: nowrap;\n}\n.text-lowercase {\n text-transform: lowercase;\n}\n.text-uppercase {\n text-transform: uppercase;\n}\n.text-capitalize {\n text-transform: capitalize;\n}\n.text-muted {\n color: #777777;\n}\n.text-primary {\n color: #337ab7;\n}\na.text-primary:hover {\n color: #286090;\n}\n.text-success {\n color: #3c763d;\n}\na.text-success:hover {\n color: #2b542c;\n}\n.text-info {\n color: #31708f;\n}\na.text-info:hover {\n color: #245269;\n}\n.text-warning {\n color: #8a6d3b;\n}\na.text-warning:hover {\n color: #66512c;\n}\n.text-danger {\n color: #a94442;\n}\na.text-danger:hover {\n color: #843534;\n}\n.bg-primary {\n color: #fff;\n background-color: #337ab7;\n}\na.bg-primary:hover {\n background-color: #286090;\n}\n.bg-success {\n background-color: #dff0d8;\n}\na.bg-success:hover {\n background-color: #c1e2b3;\n}\n.bg-info {\n background-color: #d9edf7;\n}\na.bg-info:hover {\n background-color: #afd9ee;\n}\n.bg-warning {\n background-color: #fcf8e3;\n}\na.bg-warning:hover {\n background-color: #f7ecb5;\n}\n.bg-danger {\n background-color: #f2dede;\n}\na.bg-danger:hover {\n background-color: #e4b9b9;\n}\n.page-header {\n padding-bottom: 9px;\n margin: 40px 0 20px;\n border-bottom: 1px solid #eeeeee;\n}\nul,\nol {\n margin-top: 0;\n margin-bottom: 10px;\n}\nul ul,\nol ul,\nul ol,\nol ol {\n margin-bottom: 0;\n}\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n.list-inline {\n padding-left: 0;\n list-style: none;\n margin-left: -5px;\n}\n.list-inline > li {\n display: inline-block;\n padding-left: 5px;\n padding-right: 5px;\n}\ndl {\n margin-top: 0;\n margin-bottom: 20px;\n}\ndt,\ndd {\n line-height: 1.42857143;\n}\ndt {\n font-weight: bold;\n}\ndd {\n margin-left: 0;\n}\n@media (min-width: 768px) {\n .dl-horizontal dt {\n float: left;\n width: 160px;\n clear: left;\n text-align: right;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .dl-horizontal dd {\n margin-left: 180px;\n }\n}\nabbr[title],\nabbr[data-original-title] {\n cursor: help;\n border-bottom: 1px dotted #777777;\n}\n.initialism {\n font-size: 90%;\n text-transform: uppercase;\n}\nblockquote {\n padding: 10px 20px;\n margin: 0 0 20px;\n font-size: 17.5px;\n border-left: 5px solid #eeeeee;\n}\nblockquote p:last-child,\nblockquote ul:last-child,\nblockquote ol:last-child {\n margin-bottom: 0;\n}\nblockquote footer,\nblockquote small,\nblockquote .small {\n display: block;\n font-size: 80%;\n line-height: 1.42857143;\n color: #777777;\n}\nblockquote footer:before,\nblockquote small:before,\nblockquote .small:before {\n content: '\\2014 \\00A0';\n}\n.blockquote-reverse,\nblockquote.pull-right {\n padding-right: 15px;\n padding-left: 0;\n border-right: 5px solid #eeeeee;\n border-left: 0;\n text-align: right;\n}\n.blockquote-reverse footer:before,\nblockquote.pull-right footer:before,\n.blockquote-reverse small:before,\nblockquote.pull-right small:before,\n.blockquote-reverse .small:before,\nblockquote.pull-right .small:before {\n content: '';\n}\n.blockquote-reverse footer:after,\nblockquote.pull-right footer:after,\n.blockquote-reverse small:after,\nblockquote.pull-right small:after,\n.blockquote-reverse .small:after,\nblockquote.pull-right .small:after {\n content: '\\00A0 \\2014';\n}\naddress {\n margin-bottom: 20px;\n font-style: normal;\n line-height: 1.42857143;\n}\ncode,\nkbd,\npre,\nsamp {\n font-family: Menlo, Monaco, Consolas, \"Courier New\", monospace;\n}\ncode {\n padding: 2px 4px;\n font-size: 90%;\n color: #c7254e;\n background-color: #f9f2f4;\n border-radius: 4px;\n}\nkbd {\n padding: 2px 4px;\n font-size: 90%;\n color: #ffffff;\n background-color: #333333;\n border-radius: 3px;\n box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\nkbd kbd {\n padding: 0;\n font-size: 100%;\n font-weight: bold;\n box-shadow: none;\n}\npre {\n display: block;\n padding: 9.5px;\n margin: 0 0 10px;\n font-size: 13px;\n line-height: 1.42857143;\n word-break: break-all;\n word-wrap: break-word;\n color: #333333;\n background-color: #f5f5f5;\n border: 1px solid #cccccc;\n border-radius: 4px;\n}\npre code {\n padding: 0;\n font-size: inherit;\n color: inherit;\n white-space: pre-wrap;\n background-color: transparent;\n border-radius: 0;\n}\n.pre-scrollable {\n max-height: 340px;\n overflow-y: scroll;\n}\n.container {\n margin-right: auto;\n margin-left: auto;\n padding-left: 15px;\n padding-right: 15px;\n}\n@media (min-width: 768px) {\n .container {\n width: 750px;\n }\n}\n@media (min-width: 992px) {\n .container {\n width: 970px;\n }\n}\n@media (min-width: 1200px) {\n .container {\n width: 1170px;\n }\n}\n.container-fluid {\n margin-right: auto;\n margin-left: auto;\n padding-left: 15px;\n padding-right: 15px;\n}\n.row {\n margin-left: -15px;\n margin-right: -15px;\n}\n.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {\n position: relative;\n min-height: 1px;\n padding-left: 15px;\n padding-right: 15px;\n}\n.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {\n float: left;\n}\n.col-xs-12 {\n width: 100%;\n}\n.col-xs-11 {\n width: 91.66666667%;\n}\n.col-xs-10 {\n width: 83.33333333%;\n}\n.col-xs-9 {\n width: 75%;\n}\n.col-xs-8 {\n width: 66.66666667%;\n}\n.col-xs-7 {\n width: 58.33333333%;\n}\n.col-xs-6 {\n width: 50%;\n}\n.col-xs-5 {\n width: 41.66666667%;\n}\n.col-xs-4 {\n width: 33.33333333%;\n}\n.col-xs-3 {\n width: 25%;\n}\n.col-xs-2 {\n width: 16.66666667%;\n}\n.col-xs-1 {\n width: 8.33333333%;\n}\n.col-xs-pull-12 {\n right: 100%;\n}\n.col-xs-pull-11 {\n right: 91.66666667%;\n}\n.col-xs-pull-10 {\n right: 83.33333333%;\n}\n.col-xs-pull-9 {\n right: 75%;\n}\n.col-xs-pull-8 {\n right: 66.66666667%;\n}\n.col-xs-pull-7 {\n right: 58.33333333%;\n}\n.col-xs-pull-6 {\n right: 50%;\n}\n.col-xs-pull-5 {\n right: 41.66666667%;\n}\n.col-xs-pull-4 {\n right: 33.33333333%;\n}\n.col-xs-pull-3 {\n right: 25%;\n}\n.col-xs-pull-2 {\n right: 16.66666667%;\n}\n.col-xs-pull-1 {\n right: 8.33333333%;\n}\n.col-xs-pull-0 {\n right: auto;\n}\n.col-xs-push-12 {\n left: 100%;\n}\n.col-xs-push-11 {\n left: 91.66666667%;\n}\n.col-xs-push-10 {\n left: 83.33333333%;\n}\n.col-xs-push-9 {\n left: 75%;\n}\n.col-xs-push-8 {\n left: 66.66666667%;\n}\n.col-xs-push-7 {\n left: 58.33333333%;\n}\n.col-xs-push-6 {\n left: 50%;\n}\n.col-xs-push-5 {\n left: 41.66666667%;\n}\n.col-xs-push-4 {\n left: 33.33333333%;\n}\n.col-xs-push-3 {\n left: 25%;\n}\n.col-xs-push-2 {\n left: 16.66666667%;\n}\n.col-xs-push-1 {\n left: 8.33333333%;\n}\n.col-xs-push-0 {\n left: auto;\n}\n.col-xs-offset-12 {\n margin-left: 100%;\n}\n.col-xs-offset-11 {\n margin-left: 91.66666667%;\n}\n.col-xs-offset-10 {\n margin-left: 83.33333333%;\n}\n.col-xs-offset-9 {\n margin-left: 75%;\n}\n.col-xs-offset-8 {\n margin-left: 66.66666667%;\n}\n.col-xs-offset-7 {\n margin-left: 58.33333333%;\n}\n.col-xs-offset-6 {\n margin-left: 50%;\n}\n.col-xs-offset-5 {\n margin-left: 41.66666667%;\n}\n.col-xs-offset-4 {\n margin-left: 33.33333333%;\n}\n.col-xs-offset-3 {\n margin-left: 25%;\n}\n.col-xs-offset-2 {\n margin-left: 16.66666667%;\n}\n.col-xs-offset-1 {\n margin-left: 8.33333333%;\n}\n.col-xs-offset-0 {\n margin-left: 0%;\n}\n@media (min-width: 768px) {\n .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {\n float: left;\n }\n .col-sm-12 {\n width: 100%;\n }\n .col-sm-11 {\n width: 91.66666667%;\n }\n .col-sm-10 {\n width: 83.33333333%;\n }\n .col-sm-9 {\n width: 75%;\n }\n .col-sm-8 {\n width: 66.66666667%;\n }\n .col-sm-7 {\n width: 58.33333333%;\n }\n .col-sm-6 {\n width: 50%;\n }\n .col-sm-5 {\n width: 41.66666667%;\n }\n .col-sm-4 {\n width: 33.33333333%;\n }\n .col-sm-3 {\n width: 25%;\n }\n .col-sm-2 {\n width: 16.66666667%;\n }\n .col-sm-1 {\n width: 8.33333333%;\n }\n .col-sm-pull-12 {\n right: 100%;\n }\n .col-sm-pull-11 {\n right: 91.66666667%;\n }\n .col-sm-pull-10 {\n right: 83.33333333%;\n }\n .col-sm-pull-9 {\n right: 75%;\n }\n .col-sm-pull-8 {\n right: 66.66666667%;\n }\n .col-sm-pull-7 {\n right: 58.33333333%;\n }\n .col-sm-pull-6 {\n right: 50%;\n }\n .col-sm-pull-5 {\n right: 41.66666667%;\n }\n .col-sm-pull-4 {\n right: 33.33333333%;\n }\n .col-sm-pull-3 {\n right: 25%;\n }\n .col-sm-pull-2 {\n right: 16.66666667%;\n }\n .col-sm-pull-1 {\n right: 8.33333333%;\n }\n .col-sm-pull-0 {\n right: auto;\n }\n .col-sm-push-12 {\n left: 100%;\n }\n .col-sm-push-11 {\n left: 91.66666667%;\n }\n .col-sm-push-10 {\n left: 83.33333333%;\n }\n .col-sm-push-9 {\n left: 75%;\n }\n .col-sm-push-8 {\n left: 66.66666667%;\n }\n .col-sm-push-7 {\n left: 58.33333333%;\n }\n .col-sm-push-6 {\n left: 50%;\n }\n .col-sm-push-5 {\n left: 41.66666667%;\n }\n .col-sm-push-4 {\n left: 33.33333333%;\n }\n .col-sm-push-3 {\n left: 25%;\n }\n .col-sm-push-2 {\n left: 16.66666667%;\n }\n .col-sm-push-1 {\n left: 8.33333333%;\n }\n .col-sm-push-0 {\n left: auto;\n }\n .col-sm-offset-12 {\n margin-left: 100%;\n }\n .col-sm-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-sm-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-sm-offset-9 {\n margin-left: 75%;\n }\n .col-sm-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-sm-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-sm-offset-6 {\n margin-left: 50%;\n }\n .col-sm-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-sm-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-sm-offset-3 {\n margin-left: 25%;\n }\n .col-sm-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-sm-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-sm-offset-0 {\n margin-left: 0%;\n }\n}\n@media (min-width: 992px) {\n .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 {\n float: left;\n }\n .col-md-12 {\n width: 100%;\n }\n .col-md-11 {\n width: 91.66666667%;\n }\n .col-md-10 {\n width: 83.33333333%;\n }\n .col-md-9 {\n width: 75%;\n }\n .col-md-8 {\n width: 66.66666667%;\n }\n .col-md-7 {\n width: 58.33333333%;\n }\n .col-md-6 {\n width: 50%;\n }\n .col-md-5 {\n width: 41.66666667%;\n }\n .col-md-4 {\n width: 33.33333333%;\n }\n .col-md-3 {\n width: 25%;\n }\n .col-md-2 {\n width: 16.66666667%;\n }\n .col-md-1 {\n width: 8.33333333%;\n }\n .col-md-pull-12 {\n right: 100%;\n }\n .col-md-pull-11 {\n right: 91.66666667%;\n }\n .col-md-pull-10 {\n right: 83.33333333%;\n }\n .col-md-pull-9 {\n right: 75%;\n }\n .col-md-pull-8 {\n right: 66.66666667%;\n }\n .col-md-pull-7 {\n right: 58.33333333%;\n }\n .col-md-pull-6 {\n right: 50%;\n }\n .col-md-pull-5 {\n right: 41.66666667%;\n }\n .col-md-pull-4 {\n right: 33.33333333%;\n }\n .col-md-pull-3 {\n right: 25%;\n }\n .col-md-pull-2 {\n right: 16.66666667%;\n }\n .col-md-pull-1 {\n right: 8.33333333%;\n }\n .col-md-pull-0 {\n right: auto;\n }\n .col-md-push-12 {\n left: 100%;\n }\n .col-md-push-11 {\n left: 91.66666667%;\n }\n .col-md-push-10 {\n left: 83.33333333%;\n }\n .col-md-push-9 {\n left: 75%;\n }\n .col-md-push-8 {\n left: 66.66666667%;\n }\n .col-md-push-7 {\n left: 58.33333333%;\n }\n .col-md-push-6 {\n left: 50%;\n }\n .col-md-push-5 {\n left: 41.66666667%;\n }\n .col-md-push-4 {\n left: 33.33333333%;\n }\n .col-md-push-3 {\n left: 25%;\n }\n .col-md-push-2 {\n left: 16.66666667%;\n }\n .col-md-push-1 {\n left: 8.33333333%;\n }\n .col-md-push-0 {\n left: auto;\n }\n .col-md-offset-12 {\n margin-left: 100%;\n }\n .col-md-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-md-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-md-offset-9 {\n margin-left: 75%;\n }\n .col-md-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-md-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-md-offset-6 {\n margin-left: 50%;\n }\n .col-md-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-md-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-md-offset-3 {\n margin-left: 25%;\n }\n .col-md-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-md-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-md-offset-0 {\n margin-left: 0%;\n }\n}\n@media (min-width: 1200px) {\n .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 {\n float: left;\n }\n .col-lg-12 {\n width: 100%;\n }\n .col-lg-11 {\n width: 91.66666667%;\n }\n .col-lg-10 {\n width: 83.33333333%;\n }\n .col-lg-9 {\n width: 75%;\n }\n .col-lg-8 {\n width: 66.66666667%;\n }\n .col-lg-7 {\n width: 58.33333333%;\n }\n .col-lg-6 {\n width: 50%;\n }\n .col-lg-5 {\n width: 41.66666667%;\n }\n .col-lg-4 {\n width: 33.33333333%;\n }\n .col-lg-3 {\n width: 25%;\n }\n .col-lg-2 {\n width: 16.66666667%;\n }\n .col-lg-1 {\n width: 8.33333333%;\n }\n .col-lg-pull-12 {\n right: 100%;\n }\n .col-lg-pull-11 {\n right: 91.66666667%;\n }\n .col-lg-pull-10 {\n right: 83.33333333%;\n }\n .col-lg-pull-9 {\n right: 75%;\n }\n .col-lg-pull-8 {\n right: 66.66666667%;\n }\n .col-lg-pull-7 {\n right: 58.33333333%;\n }\n .col-lg-pull-6 {\n right: 50%;\n }\n .col-lg-pull-5 {\n right: 41.66666667%;\n }\n .col-lg-pull-4 {\n right: 33.33333333%;\n }\n .col-lg-pull-3 {\n right: 25%;\n }\n .col-lg-pull-2 {\n right: 16.66666667%;\n }\n .col-lg-pull-1 {\n right: 8.33333333%;\n }\n .col-lg-pull-0 {\n right: auto;\n }\n .col-lg-push-12 {\n left: 100%;\n }\n .col-lg-push-11 {\n left: 91.66666667%;\n }\n .col-lg-push-10 {\n left: 83.33333333%;\n }\n .col-lg-push-9 {\n left: 75%;\n }\n .col-lg-push-8 {\n left: 66.66666667%;\n }\n .col-lg-push-7 {\n left: 58.33333333%;\n }\n .col-lg-push-6 {\n left: 50%;\n }\n .col-lg-push-5 {\n left: 41.66666667%;\n }\n .col-lg-push-4 {\n left: 33.33333333%;\n }\n .col-lg-push-3 {\n left: 25%;\n }\n .col-lg-push-2 {\n left: 16.66666667%;\n }\n .col-lg-push-1 {\n left: 8.33333333%;\n }\n .col-lg-push-0 {\n left: auto;\n }\n .col-lg-offset-12 {\n margin-left: 100%;\n }\n .col-lg-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-lg-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-lg-offset-9 {\n margin-left: 75%;\n }\n .col-lg-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-lg-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-lg-offset-6 {\n margin-left: 50%;\n }\n .col-lg-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-lg-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-lg-offset-3 {\n margin-left: 25%;\n }\n .col-lg-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-lg-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-lg-offset-0 {\n margin-left: 0%;\n }\n}\ntable {\n background-color: transparent;\n}\ncaption {\n padding-top: 8px;\n padding-bottom: 8px;\n color: #777777;\n text-align: left;\n}\nth {\n text-align: left;\n}\n.table {\n width: 100%;\n max-width: 100%;\n margin-bottom: 20px;\n}\n.table > thead > tr > th,\n.table > tbody > tr > th,\n.table > tfoot > tr > th,\n.table > thead > tr > td,\n.table > tbody > tr > td,\n.table > tfoot > tr > td {\n padding: 8px;\n line-height: 1.42857143;\n vertical-align: top;\n border-top: 1px solid #dddddd;\n}\n.table > thead > tr > th {\n vertical-align: bottom;\n border-bottom: 2px solid #dddddd;\n}\n.table > caption + thead > tr:first-child > th,\n.table > colgroup + thead > tr:first-child > th,\n.table > thead:first-child > tr:first-child > th,\n.table > caption + thead > tr:first-child > td,\n.table > colgroup + thead > tr:first-child > td,\n.table > thead:first-child > tr:first-child > td {\n border-top: 0;\n}\n.table > tbody + tbody {\n border-top: 2px solid #dddddd;\n}\n.table .table {\n background-color: #ffffff;\n}\n.table-condensed > thead > tr > th,\n.table-condensed > tbody > tr > th,\n.table-condensed > tfoot > tr > th,\n.table-condensed > thead > tr > td,\n.table-condensed > tbody > tr > td,\n.table-condensed > tfoot > tr > td {\n padding: 5px;\n}\n.table-bordered {\n border: 1px solid #dddddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > tbody > tr > th,\n.table-bordered > tfoot > tr > th,\n.table-bordered > thead > tr > td,\n.table-bordered > tbody > tr > td,\n.table-bordered > tfoot > tr > td {\n border: 1px solid #dddddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > thead > tr > td {\n border-bottom-width: 2px;\n}\n.table-striped > tbody > tr:nth-of-type(odd) {\n background-color: #f9f9f9;\n}\n.table-hover > tbody > tr:hover {\n background-color: #f5f5f5;\n}\ntable col[class*=\"col-\"] {\n position: static;\n float: none;\n display: table-column;\n}\ntable td[class*=\"col-\"],\ntable th[class*=\"col-\"] {\n position: static;\n float: none;\n display: table-cell;\n}\n.table > thead > tr > td.active,\n.table > tbody > tr > td.active,\n.table > tfoot > tr > td.active,\n.table > thead > tr > th.active,\n.table > tbody > tr > th.active,\n.table > tfoot > tr > th.active,\n.table > thead > tr.active > td,\n.table > tbody > tr.active > td,\n.table > tfoot > tr.active > td,\n.table > thead > tr.active > th,\n.table > tbody > tr.active > th,\n.table > tfoot > tr.active > th {\n background-color: #f5f5f5;\n}\n.table-hover > tbody > tr > td.active:hover,\n.table-hover > tbody > tr > th.active:hover,\n.table-hover > tbody > tr.active:hover > td,\n.table-hover > tbody > tr:hover > .active,\n.table-hover > tbody > tr.active:hover > th {\n background-color: #e8e8e8;\n}\n.table > thead > tr > td.success,\n.table > tbody > tr > td.success,\n.table > tfoot > tr > td.success,\n.table > thead > tr > th.success,\n.table > tbody > tr > th.success,\n.table > tfoot > tr > th.success,\n.table > thead > tr.success > td,\n.table > tbody > tr.success > td,\n.table > tfoot > tr.success > td,\n.table > thead > tr.success > th,\n.table > tbody > tr.success > th,\n.table > tfoot > tr.success > th {\n background-color: #dff0d8;\n}\n.table-hover > tbody > tr > td.success:hover,\n.table-hover > tbody > tr > th.success:hover,\n.table-hover > tbody > tr.success:hover > td,\n.table-hover > tbody > tr:hover > .success,\n.table-hover > tbody > tr.success:hover > th {\n background-color: #d0e9c6;\n}\n.table > thead > tr > td.info,\n.table > tbody > tr > td.info,\n.table > tfoot > tr > td.info,\n.table > thead > tr > th.info,\n.table > tbody > tr > th.info,\n.table > tfoot > tr > th.info,\n.table > thead > tr.info > td,\n.table > tbody > tr.info > td,\n.table > tfoot > tr.info > td,\n.table > thead > tr.info > th,\n.table > tbody > tr.info > th,\n.table > tfoot > tr.info > th {\n background-color: #d9edf7;\n}\n.table-hover > tbody > tr > td.info:hover,\n.table-hover > tbody > tr > th.info:hover,\n.table-hover > tbody > tr.info:hover > td,\n.table-hover > tbody > tr:hover > .info,\n.table-hover > tbody > tr.info:hover > th {\n background-color: #c4e3f3;\n}\n.table > thead > tr > td.warning,\n.table > tbody > tr > td.warning,\n.table > tfoot > tr > td.warning,\n.table > thead > tr > th.warning,\n.table > tbody > tr > th.warning,\n.table > tfoot > tr > th.warning,\n.table > thead > tr.warning > td,\n.table > tbody > tr.warning > td,\n.table > tfoot > tr.warning > td,\n.table > thead > tr.warning > th,\n.table > tbody > tr.warning > th,\n.table > tfoot > tr.warning > th {\n background-color: #fcf8e3;\n}\n.table-hover > tbody > tr > td.warning:hover,\n.table-hover > tbody > tr > th.warning:hover,\n.table-hover > tbody > tr.warning:hover > td,\n.table-hover > tbody > tr:hover > .warning,\n.table-hover > tbody > tr.warning:hover > th {\n background-color: #faf2cc;\n}\n.table > thead > tr > td.danger,\n.table > tbody > tr > td.danger,\n.table > tfoot > tr > td.danger,\n.table > thead > tr > th.danger,\n.table > tbody > tr > th.danger,\n.table > tfoot > tr > th.danger,\n.table > thead > tr.danger > td,\n.table > tbody > tr.danger > td,\n.table > tfoot > tr.danger > td,\n.table > thead > tr.danger > th,\n.table > tbody > tr.danger > th,\n.table > tfoot > tr.danger > th {\n background-color: #f2dede;\n}\n.table-hover > tbody > tr > td.danger:hover,\n.table-hover > tbody > tr > th.danger:hover,\n.table-hover > tbody > tr.danger:hover > td,\n.table-hover > tbody > tr:hover > .danger,\n.table-hover > tbody > tr.danger:hover > th {\n background-color: #ebcccc;\n}\n.table-responsive {\n overflow-x: auto;\n min-height: 0.01%;\n}\n@media screen and (max-width: 767px) {\n .table-responsive {\n width: 100%;\n margin-bottom: 15px;\n overflow-y: hidden;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n border: 1px solid #dddddd;\n }\n .table-responsive > .table {\n margin-bottom: 0;\n }\n .table-responsive > .table > thead > tr > th,\n .table-responsive > .table > tbody > tr > th,\n .table-responsive > .table > tfoot > tr > th,\n .table-responsive > .table > thead > tr > td,\n .table-responsive > .table > tbody > tr > td,\n .table-responsive > .table > tfoot > tr > td {\n white-space: nowrap;\n }\n .table-responsive > .table-bordered {\n border: 0;\n }\n .table-responsive > .table-bordered > thead > tr > th:first-child,\n .table-responsive > .table-bordered > tbody > tr > th:first-child,\n .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n .table-responsive > .table-bordered > thead > tr > td:first-child,\n .table-responsive > .table-bordered > tbody > tr > td:first-child,\n .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n border-left: 0;\n }\n .table-responsive > .table-bordered > thead > tr > th:last-child,\n .table-responsive > .table-bordered > tbody > tr > th:last-child,\n .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n .table-responsive > .table-bordered > thead > tr > td:last-child,\n .table-responsive > .table-bordered > tbody > tr > td:last-child,\n .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n border-right: 0;\n }\n .table-responsive > .table-bordered > tbody > tr:last-child > th,\n .table-responsive > .table-bordered > tfoot > tr:last-child > th,\n .table-responsive > .table-bordered > tbody > tr:last-child > td,\n .table-responsive > .table-bordered > tfoot > tr:last-child > td {\n border-bottom: 0;\n }\n}\nfieldset {\n padding: 0;\n margin: 0;\n border: 0;\n min-width: 0;\n}\nlegend {\n display: block;\n width: 100%;\n padding: 0;\n margin-bottom: 20px;\n font-size: 21px;\n line-height: inherit;\n color: #333333;\n border: 0;\n border-bottom: 1px solid #e5e5e5;\n}\nlabel {\n display: inline-block;\n max-width: 100%;\n margin-bottom: 5px;\n font-weight: bold;\n}\ninput[type=\"search\"] {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n margin: 4px 0 0;\n margin-top: 1px \\9;\n line-height: normal;\n}\ninput[type=\"file\"] {\n display: block;\n}\ninput[type=\"range\"] {\n display: block;\n width: 100%;\n}\nselect[multiple],\nselect[size] {\n height: auto;\n}\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n outline: thin dotted;\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\noutput {\n display: block;\n padding-top: 7px;\n font-size: 14px;\n line-height: 1.42857143;\n color: #555555;\n}\n.form-control {\n display: block;\n width: 100%;\n height: 34px;\n padding: 6px 12px;\n font-size: 14px;\n line-height: 1.42857143;\n color: #555555;\n background-color: #ffffff;\n background-image: none;\n border: 1px solid #cccccc;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n}\n.form-control:focus {\n border-color: #66afe9;\n outline: 0;\n -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);\n box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);\n}\n.form-control::-moz-placeholder {\n color: #999999;\n opacity: 1;\n}\n.form-control:-ms-input-placeholder {\n color: #999999;\n}\n.form-control::-webkit-input-placeholder {\n color: #999999;\n}\n.form-control[disabled],\n.form-control[readonly],\nfieldset[disabled] .form-control {\n cursor: not-allowed;\n background-color: #eeeeee;\n opacity: 1;\n}\ntextarea.form-control {\n height: auto;\n}\ninput[type=\"search\"] {\n -webkit-appearance: none;\n}\n@media screen and (-webkit-min-device-pixel-ratio: 0) {\n input[type=\"date\"],\n input[type=\"time\"],\n input[type=\"datetime-local\"],\n input[type=\"month\"] {\n line-height: 34px;\n }\n input[type=\"date\"].input-sm,\n input[type=\"time\"].input-sm,\n input[type=\"datetime-local\"].input-sm,\n input[type=\"month\"].input-sm,\n .input-group-sm input[type=\"date\"],\n .input-group-sm input[type=\"time\"],\n .input-group-sm input[type=\"datetime-local\"],\n .input-group-sm input[type=\"month\"] {\n line-height: 30px;\n }\n input[type=\"date\"].input-lg,\n input[type=\"time\"].input-lg,\n input[type=\"datetime-local\"].input-lg,\n input[type=\"month\"].input-lg,\n .input-group-lg input[type=\"date\"],\n .input-group-lg input[type=\"time\"],\n .input-group-lg input[type=\"datetime-local\"],\n .input-group-lg input[type=\"month\"] {\n line-height: 46px;\n }\n}\n.form-group {\n margin-bottom: 15px;\n}\n.radio,\n.checkbox {\n position: relative;\n display: block;\n margin-top: 10px;\n margin-bottom: 10px;\n}\n.radio label,\n.checkbox label {\n min-height: 20px;\n padding-left: 20px;\n margin-bottom: 0;\n font-weight: normal;\n cursor: pointer;\n}\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n position: absolute;\n margin-left: -20px;\n margin-top: 4px \\9;\n}\n.radio + .radio,\n.checkbox + .checkbox {\n margin-top: -5px;\n}\n.radio-inline,\n.checkbox-inline {\n display: inline-block;\n padding-left: 20px;\n margin-bottom: 0;\n vertical-align: middle;\n font-weight: normal;\n cursor: pointer;\n}\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n margin-top: 0;\n margin-left: 10px;\n}\ninput[type=\"radio\"][disabled],\ninput[type=\"checkbox\"][disabled],\ninput[type=\"radio\"].disabled,\ninput[type=\"checkbox\"].disabled,\nfieldset[disabled] input[type=\"radio\"],\nfieldset[disabled] input[type=\"checkbox\"] {\n cursor: not-allowed;\n}\n.radio-inline.disabled,\n.checkbox-inline.disabled,\nfieldset[disabled] .radio-inline,\nfieldset[disabled] .checkbox-inline {\n cursor: not-allowed;\n}\n.radio.disabled label,\n.checkbox.disabled label,\nfieldset[disabled] .radio label,\nfieldset[disabled] .checkbox label {\n cursor: not-allowed;\n}\n.form-control-static {\n padding-top: 7px;\n padding-bottom: 7px;\n margin-bottom: 0;\n}\n.form-control-static.input-lg,\n.form-control-static.input-sm {\n padding-left: 0;\n padding-right: 0;\n}\n.input-sm {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\nselect.input-sm {\n height: 30px;\n line-height: 30px;\n}\ntextarea.input-sm,\nselect[multiple].input-sm {\n height: auto;\n}\n.form-group-sm .form-control {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\nselect.form-group-sm .form-control {\n height: 30px;\n line-height: 30px;\n}\ntextarea.form-group-sm .form-control,\nselect[multiple].form-group-sm .form-control {\n height: auto;\n}\n.form-group-sm .form-control-static {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n}\n.input-lg {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\nselect.input-lg {\n height: 46px;\n line-height: 46px;\n}\ntextarea.input-lg,\nselect[multiple].input-lg {\n height: auto;\n}\n.form-group-lg .form-control {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\nselect.form-group-lg .form-control {\n height: 46px;\n line-height: 46px;\n}\ntextarea.form-group-lg .form-control,\nselect[multiple].form-group-lg .form-control {\n height: auto;\n}\n.form-group-lg .form-control-static {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n}\n.has-feedback {\n position: relative;\n}\n.has-feedback .form-control {\n padding-right: 42.5px;\n}\n.form-control-feedback {\n position: absolute;\n top: 0;\n right: 0;\n z-index: 2;\n display: block;\n width: 34px;\n height: 34px;\n line-height: 34px;\n text-align: center;\n pointer-events: none;\n}\n.input-lg + .form-control-feedback {\n width: 46px;\n height: 46px;\n line-height: 46px;\n}\n.input-sm + .form-control-feedback {\n width: 30px;\n height: 30px;\n line-height: 30px;\n}\n.has-success .help-block,\n.has-success .control-label,\n.has-success .radio,\n.has-success .checkbox,\n.has-success .radio-inline,\n.has-success .checkbox-inline,\n.has-success.radio label,\n.has-success.checkbox label,\n.has-success.radio-inline label,\n.has-success.checkbox-inline label {\n color: #3c763d;\n}\n.has-success .form-control {\n border-color: #3c763d;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-success .form-control:focus {\n border-color: #2b542c;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;\n}\n.has-success .input-group-addon {\n color: #3c763d;\n border-color: #3c763d;\n background-color: #dff0d8;\n}\n.has-success .form-control-feedback {\n color: #3c763d;\n}\n.has-warning .help-block,\n.has-warning .control-label,\n.has-warning .radio,\n.has-warning .checkbox,\n.has-warning .radio-inline,\n.has-warning .checkbox-inline,\n.has-warning.radio label,\n.has-warning.checkbox label,\n.has-warning.radio-inline label,\n.has-warning.checkbox-inline label {\n color: #8a6d3b;\n}\n.has-warning .form-control {\n border-color: #8a6d3b;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-warning .form-control:focus {\n border-color: #66512c;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;\n}\n.has-warning .input-group-addon {\n color: #8a6d3b;\n border-color: #8a6d3b;\n background-color: #fcf8e3;\n}\n.has-warning .form-control-feedback {\n color: #8a6d3b;\n}\n.has-error .help-block,\n.has-error .control-label,\n.has-error .radio,\n.has-error .checkbox,\n.has-error .radio-inline,\n.has-error .checkbox-inline,\n.has-error.radio label,\n.has-error.checkbox label,\n.has-error.radio-inline label,\n.has-error.checkbox-inline label {\n color: #a94442;\n}\n.has-error .form-control {\n border-color: #a94442;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-error .form-control:focus {\n border-color: #843534;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;\n}\n.has-error .input-group-addon {\n color: #a94442;\n border-color: #a94442;\n background-color: #f2dede;\n}\n.has-error .form-control-feedback {\n color: #a94442;\n}\n.has-feedback label ~ .form-control-feedback {\n top: 25px;\n}\n.has-feedback label.sr-only ~ .form-control-feedback {\n top: 0;\n}\n.help-block {\n display: block;\n margin-top: 5px;\n margin-bottom: 10px;\n color: #737373;\n}\n@media (min-width: 768px) {\n .form-inline .form-group {\n display: inline-block;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .form-inline .form-control-static {\n display: inline-block;\n }\n .form-inline .input-group {\n display: inline-table;\n vertical-align: middle;\n }\n .form-inline .input-group .input-group-addon,\n .form-inline .input-group .input-group-btn,\n .form-inline .input-group .form-control {\n width: auto;\n }\n .form-inline .input-group > .form-control {\n width: 100%;\n }\n .form-inline .control-label {\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .radio,\n .form-inline .checkbox {\n display: inline-block;\n margin-top: 0;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .radio label,\n .form-inline .checkbox label {\n padding-left: 0;\n }\n .form-inline .radio input[type=\"radio\"],\n .form-inline .checkbox input[type=\"checkbox\"] {\n position: relative;\n margin-left: 0;\n }\n .form-inline .has-feedback .form-control-feedback {\n top: 0;\n }\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox,\n.form-horizontal .radio-inline,\n.form-horizontal .checkbox-inline {\n margin-top: 0;\n margin-bottom: 0;\n padding-top: 7px;\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox {\n min-height: 27px;\n}\n.form-horizontal .form-group {\n margin-left: -15px;\n margin-right: -15px;\n}\n@media (min-width: 768px) {\n .form-horizontal .control-label {\n text-align: right;\n margin-bottom: 0;\n padding-top: 7px;\n }\n}\n.form-horizontal .has-feedback .form-control-feedback {\n right: 15px;\n}\n@media (min-width: 768px) {\n .form-horizontal .form-group-lg .control-label {\n padding-top: 14.333333px;\n }\n}\n@media (min-width: 768px) {\n .form-horizontal .form-group-sm .control-label {\n padding-top: 6px;\n }\n}\n.btn {\n display: inline-block;\n margin-bottom: 0;\n font-weight: normal;\n text-align: center;\n vertical-align: middle;\n touch-action: manipulation;\n cursor: pointer;\n background-image: none;\n border: 1px solid transparent;\n white-space: nowrap;\n padding: 6px 12px;\n font-size: 14px;\n line-height: 1.42857143;\n border-radius: 4px;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n.btn:focus,\n.btn:active:focus,\n.btn.active:focus,\n.btn.focus,\n.btn:active.focus,\n.btn.active.focus {\n outline: thin dotted;\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\n.btn:hover,\n.btn:focus,\n.btn.focus {\n color: #333333;\n text-decoration: none;\n}\n.btn:active,\n.btn.active {\n outline: 0;\n background-image: none;\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn.disabled,\n.btn[disabled],\nfieldset[disabled] .btn {\n cursor: not-allowed;\n pointer-events: none;\n opacity: 0.65;\n filter: alpha(opacity=65);\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn-default {\n color: #333333;\n background-color: #ffffff;\n border-color: #cccccc;\n}\n.btn-default:hover,\n.btn-default:focus,\n.btn-default.focus,\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n color: #333333;\n background-color: #e6e6e6;\n border-color: #adadad;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n background-image: none;\n}\n.btn-default.disabled,\n.btn-default[disabled],\nfieldset[disabled] .btn-default,\n.btn-default.disabled:hover,\n.btn-default[disabled]:hover,\nfieldset[disabled] .btn-default:hover,\n.btn-default.disabled:focus,\n.btn-default[disabled]:focus,\nfieldset[disabled] .btn-default:focus,\n.btn-default.disabled.focus,\n.btn-default[disabled].focus,\nfieldset[disabled] .btn-default.focus,\n.btn-default.disabled:active,\n.btn-default[disabled]:active,\nfieldset[disabled] .btn-default:active,\n.btn-default.disabled.active,\n.btn-default[disabled].active,\nfieldset[disabled] .btn-default.active {\n background-color: #ffffff;\n border-color: #cccccc;\n}\n.btn-default .badge {\n color: #ffffff;\n background-color: #333333;\n}\n.btn-primary {\n color: #ffffff;\n background-color: #337ab7;\n border-color: #2e6da4;\n}\n.btn-primary:hover,\n.btn-primary:focus,\n.btn-primary.focus,\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n color: #ffffff;\n background-color: #286090;\n border-color: #204d74;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n background-image: none;\n}\n.btn-primary.disabled,\n.btn-primary[disabled],\nfieldset[disabled] .btn-primary,\n.btn-primary.disabled:hover,\n.btn-primary[disabled]:hover,\nfieldset[disabled] .btn-primary:hover,\n.btn-primary.disabled:focus,\n.btn-primary[disabled]:focus,\nfieldset[disabled] .btn-primary:focus,\n.btn-primary.disabled.focus,\n.btn-primary[disabled].focus,\nfieldset[disabled] .btn-primary.focus,\n.btn-primary.disabled:active,\n.btn-primary[disabled]:active,\nfieldset[disabled] .btn-primary:active,\n.btn-primary.disabled.active,\n.btn-primary[disabled].active,\nfieldset[disabled] .btn-primary.active {\n background-color: #337ab7;\n border-color: #2e6da4;\n}\n.btn-primary .badge {\n color: #337ab7;\n background-color: #ffffff;\n}\n.btn-success {\n color: #ffffff;\n background-color: #5cb85c;\n border-color: #4cae4c;\n}\n.btn-success:hover,\n.btn-success:focus,\n.btn-success.focus,\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n color: #ffffff;\n background-color: #449d44;\n border-color: #398439;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n background-image: none;\n}\n.btn-success.disabled,\n.btn-success[disabled],\nfieldset[disabled] .btn-success,\n.btn-success.disabled:hover,\n.btn-success[disabled]:hover,\nfieldset[disabled] .btn-success:hover,\n.btn-success.disabled:focus,\n.btn-success[disabled]:focus,\nfieldset[disabled] .btn-success:focus,\n.btn-success.disabled.focus,\n.btn-success[disabled].focus,\nfieldset[disabled] .btn-success.focus,\n.btn-success.disabled:active,\n.btn-success[disabled]:active,\nfieldset[disabled] .btn-success:active,\n.btn-success.disabled.active,\n.btn-success[disabled].active,\nfieldset[disabled] .btn-success.active {\n background-color: #5cb85c;\n border-color: #4cae4c;\n}\n.btn-success .badge {\n color: #5cb85c;\n background-color: #ffffff;\n}\n.btn-info {\n color: #ffffff;\n background-color: #5bc0de;\n border-color: #46b8da;\n}\n.btn-info:hover,\n.btn-info:focus,\n.btn-info.focus,\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n color: #ffffff;\n background-color: #31b0d5;\n border-color: #269abc;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n background-image: none;\n}\n.btn-info.disabled,\n.btn-info[disabled],\nfieldset[disabled] .btn-info,\n.btn-info.disabled:hover,\n.btn-info[disabled]:hover,\nfieldset[disabled] .btn-info:hover,\n.btn-info.disabled:focus,\n.btn-info[disabled]:focus,\nfieldset[disabled] .btn-info:focus,\n.btn-info.disabled.focus,\n.btn-info[disabled].focus,\nfieldset[disabled] .btn-info.focus,\n.btn-info.disabled:active,\n.btn-info[disabled]:active,\nfieldset[disabled] .btn-info:active,\n.btn-info.disabled.active,\n.btn-info[disabled].active,\nfieldset[disabled] .btn-info.active {\n background-color: #5bc0de;\n border-color: #46b8da;\n}\n.btn-info .badge {\n color: #5bc0de;\n background-color: #ffffff;\n}\n.btn-warning {\n color: #ffffff;\n background-color: #f0ad4e;\n border-color: #eea236;\n}\n.btn-warning:hover,\n.btn-warning:focus,\n.btn-warning.focus,\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n color: #ffffff;\n background-color: #ec971f;\n border-color: #d58512;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n background-image: none;\n}\n.btn-warning.disabled,\n.btn-warning[disabled],\nfieldset[disabled] .btn-warning,\n.btn-warning.disabled:hover,\n.btn-warning[disabled]:hover,\nfieldset[disabled] .btn-warning:hover,\n.btn-warning.disabled:focus,\n.btn-warning[disabled]:focus,\nfieldset[disabled] .btn-warning:focus,\n.btn-warning.disabled.focus,\n.btn-warning[disabled].focus,\nfieldset[disabled] .btn-warning.focus,\n.btn-warning.disabled:active,\n.btn-warning[disabled]:active,\nfieldset[disabled] .btn-warning:active,\n.btn-warning.disabled.active,\n.btn-warning[disabled].active,\nfieldset[disabled] .btn-warning.active {\n background-color: #f0ad4e;\n border-color: #eea236;\n}\n.btn-warning .badge {\n color: #f0ad4e;\n background-color: #ffffff;\n}\n.btn-danger {\n color: #ffffff;\n background-color: #d9534f;\n border-color: #d43f3a;\n}\n.btn-danger:hover,\n.btn-danger:focus,\n.btn-danger.focus,\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n color: #ffffff;\n background-color: #c9302c;\n border-color: #ac2925;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n background-image: none;\n}\n.btn-danger.disabled,\n.btn-danger[disabled],\nfieldset[disabled] .btn-danger,\n.btn-danger.disabled:hover,\n.btn-danger[disabled]:hover,\nfieldset[disabled] .btn-danger:hover,\n.btn-danger.disabled:focus,\n.btn-danger[disabled]:focus,\nfieldset[disabled] .btn-danger:focus,\n.btn-danger.disabled.focus,\n.btn-danger[disabled].focus,\nfieldset[disabled] .btn-danger.focus,\n.btn-danger.disabled:active,\n.btn-danger[disabled]:active,\nfieldset[disabled] .btn-danger:active,\n.btn-danger.disabled.active,\n.btn-danger[disabled].active,\nfieldset[disabled] .btn-danger.active {\n background-color: #d9534f;\n border-color: #d43f3a;\n}\n.btn-danger .badge {\n color: #d9534f;\n background-color: #ffffff;\n}\n.btn-link {\n color: #337ab7;\n font-weight: normal;\n border-radius: 0;\n}\n.btn-link,\n.btn-link:active,\n.btn-link.active,\n.btn-link[disabled],\nfieldset[disabled] .btn-link {\n background-color: transparent;\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn-link,\n.btn-link:hover,\n.btn-link:focus,\n.btn-link:active {\n border-color: transparent;\n}\n.btn-link:hover,\n.btn-link:focus {\n color: #23527c;\n text-decoration: underline;\n background-color: transparent;\n}\n.btn-link[disabled]:hover,\nfieldset[disabled] .btn-link:hover,\n.btn-link[disabled]:focus,\nfieldset[disabled] .btn-link:focus {\n color: #777777;\n text-decoration: none;\n}\n.btn-lg,\n.btn-group-lg > .btn {\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\n.btn-sm,\n.btn-group-sm > .btn {\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.btn-xs,\n.btn-group-xs > .btn {\n padding: 1px 5px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.btn-block {\n display: block;\n width: 100%;\n}\n.btn-block + .btn-block {\n margin-top: 5px;\n}\ninput[type=\"submit\"].btn-block,\ninput[type=\"reset\"].btn-block,\ninput[type=\"button\"].btn-block {\n width: 100%;\n}\n.fade {\n opacity: 0;\n -webkit-transition: opacity 0.15s linear;\n -o-transition: opacity 0.15s linear;\n transition: opacity 0.15s linear;\n}\n.fade.in {\n opacity: 1;\n}\n.collapse {\n display: none;\n visibility: hidden;\n}\n.collapse.in {\n display: block;\n visibility: visible;\n}\ntr.collapse.in {\n display: table-row;\n}\ntbody.collapse.in {\n display: table-row-group;\n}\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n -webkit-transition-property: height, visibility;\n transition-property: height, visibility;\n -webkit-transition-duration: 0.35s;\n transition-duration: 0.35s;\n -webkit-transition-timing-function: ease;\n transition-timing-function: ease;\n}\n.caret {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 2px;\n vertical-align: middle;\n border-top: 4px solid;\n border-right: 4px solid transparent;\n border-left: 4px solid transparent;\n}\n.dropup,\n.dropdown {\n position: relative;\n}\n.dropdown-toggle:focus {\n outline: 0;\n}\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 1000;\n display: none;\n float: left;\n min-width: 160px;\n padding: 5px 0;\n margin: 2px 0 0;\n list-style: none;\n font-size: 14px;\n text-align: left;\n background-color: #ffffff;\n border: 1px solid #cccccc;\n border: 1px solid rgba(0, 0, 0, 0.15);\n border-radius: 4px;\n -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n background-clip: padding-box;\n}\n.dropdown-menu.pull-right {\n right: 0;\n left: auto;\n}\n.dropdown-menu .divider {\n height: 1px;\n margin: 9px 0;\n overflow: hidden;\n background-color: #e5e5e5;\n}\n.dropdown-menu > li > a {\n display: block;\n padding: 3px 20px;\n clear: both;\n font-weight: normal;\n line-height: 1.42857143;\n color: #333333;\n white-space: nowrap;\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n text-decoration: none;\n color: #262626;\n background-color: #f5f5f5;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n color: #ffffff;\n text-decoration: none;\n outline: 0;\n background-color: #337ab7;\n}\n.dropdown-menu > .disabled > a,\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n color: #777777;\n}\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n text-decoration: none;\n background-color: transparent;\n background-image: none;\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n cursor: not-allowed;\n}\n.open > .dropdown-menu {\n display: block;\n}\n.open > a {\n outline: 0;\n}\n.dropdown-menu-right {\n left: auto;\n right: 0;\n}\n.dropdown-menu-left {\n left: 0;\n right: auto;\n}\n.dropdown-header {\n display: block;\n padding: 3px 20px;\n font-size: 12px;\n line-height: 1.42857143;\n color: #777777;\n white-space: nowrap;\n}\n.dropdown-backdrop {\n position: fixed;\n left: 0;\n right: 0;\n bottom: 0;\n top: 0;\n z-index: 990;\n}\n.pull-right > .dropdown-menu {\n right: 0;\n left: auto;\n}\n.dropup .caret,\n.navbar-fixed-bottom .dropdown .caret {\n border-top: 0;\n border-bottom: 4px solid;\n content: \"\";\n}\n.dropup .dropdown-menu,\n.navbar-fixed-bottom .dropdown .dropdown-menu {\n top: auto;\n bottom: 100%;\n margin-bottom: 2px;\n}\n@media (min-width: 768px) {\n .navbar-right .dropdown-menu {\n left: auto;\n right: 0;\n }\n .navbar-right .dropdown-menu-left {\n left: 0;\n right: auto;\n }\n}\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-block;\n vertical-align: middle;\n}\n.btn-group > .btn,\n.btn-group-vertical > .btn {\n position: relative;\n float: left;\n}\n.btn-group > .btn:hover,\n.btn-group-vertical > .btn:hover,\n.btn-group > .btn:focus,\n.btn-group-vertical > .btn:focus,\n.btn-group > .btn:active,\n.btn-group-vertical > .btn:active,\n.btn-group > .btn.active,\n.btn-group-vertical > .btn.active {\n z-index: 2;\n}\n.btn-group .btn + .btn,\n.btn-group .btn + .btn-group,\n.btn-group .btn-group + .btn,\n.btn-group .btn-group + .btn-group {\n margin-left: -1px;\n}\n.btn-toolbar {\n margin-left: -5px;\n}\n.btn-toolbar .btn-group,\n.btn-toolbar .input-group {\n float: left;\n}\n.btn-toolbar > .btn,\n.btn-toolbar > .btn-group,\n.btn-toolbar > .input-group {\n margin-left: 5px;\n}\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n border-radius: 0;\n}\n.btn-group > .btn:first-child {\n margin-left: 0;\n}\n.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {\n border-bottom-right-radius: 0;\n border-top-right-radius: 0;\n}\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n border-bottom-left-radius: 0;\n border-top-left-radius: 0;\n}\n.btn-group > .btn-group {\n float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n border-bottom-right-radius: 0;\n border-top-right-radius: 0;\n}\n.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {\n border-bottom-left-radius: 0;\n border-top-left-radius: 0;\n}\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n outline: 0;\n}\n.btn-group > .btn + .dropdown-toggle {\n padding-left: 8px;\n padding-right: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n padding-left: 12px;\n padding-right: 12px;\n}\n.btn-group.open .dropdown-toggle {\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn-group.open .dropdown-toggle.btn-link {\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn .caret {\n margin-left: 0;\n}\n.btn-lg .caret {\n border-width: 5px 5px 0;\n border-bottom-width: 0;\n}\n.dropup .btn-lg .caret {\n border-width: 0 5px 5px;\n}\n.btn-group-vertical > .btn,\n.btn-group-vertical > .btn-group,\n.btn-group-vertical > .btn-group > .btn {\n display: block;\n float: none;\n width: 100%;\n max-width: 100%;\n}\n.btn-group-vertical > .btn-group > .btn {\n float: none;\n}\n.btn-group-vertical > .btn + .btn,\n.btn-group-vertical > .btn + .btn-group,\n.btn-group-vertical > .btn-group + .btn,\n.btn-group-vertical > .btn-group + .btn-group {\n margin-top: -1px;\n margin-left: 0;\n}\n.btn-group-vertical > .btn:not(:first-child):not(:last-child) {\n border-radius: 0;\n}\n.btn-group-vertical > .btn:first-child:not(:last-child) {\n border-top-right-radius: 4px;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn:last-child:not(:first-child) {\n border-bottom-left-radius: 4px;\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.btn-group-justified {\n display: table;\n width: 100%;\n table-layout: fixed;\n border-collapse: separate;\n}\n.btn-group-justified > .btn,\n.btn-group-justified > .btn-group {\n float: none;\n display: table-cell;\n width: 1%;\n}\n.btn-group-justified > .btn-group .btn {\n width: 100%;\n}\n.btn-group-justified > .btn-group .dropdown-menu {\n left: auto;\n}\n[data-toggle=\"buttons\"] > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn input[type=\"checkbox\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0, 0, 0, 0);\n pointer-events: none;\n}\n.input-group {\n position: relative;\n display: table;\n border-collapse: separate;\n}\n.input-group[class*=\"col-\"] {\n float: none;\n padding-left: 0;\n padding-right: 0;\n}\n.input-group .form-control {\n position: relative;\n z-index: 2;\n float: left;\n width: 100%;\n margin-bottom: 0;\n}\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\nselect.input-group-lg > .form-control,\nselect.input-group-lg > .input-group-addon,\nselect.input-group-lg > .input-group-btn > .btn {\n height: 46px;\n line-height: 46px;\n}\ntextarea.input-group-lg > .form-control,\ntextarea.input-group-lg > .input-group-addon,\ntextarea.input-group-lg > .input-group-btn > .btn,\nselect[multiple].input-group-lg > .form-control,\nselect[multiple].input-group-lg > .input-group-addon,\nselect[multiple].input-group-lg > .input-group-btn > .btn {\n height: auto;\n}\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\nselect.input-group-sm > .form-control,\nselect.input-group-sm > .input-group-addon,\nselect.input-group-sm > .input-group-btn > .btn {\n height: 30px;\n line-height: 30px;\n}\ntextarea.input-group-sm > .form-control,\ntextarea.input-group-sm > .input-group-addon,\ntextarea.input-group-sm > .input-group-btn > .btn,\nselect[multiple].input-group-sm > .form-control,\nselect[multiple].input-group-sm > .input-group-addon,\nselect[multiple].input-group-sm > .input-group-btn > .btn {\n height: auto;\n}\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n display: table-cell;\n}\n.input-group-addon:not(:first-child):not(:last-child),\n.input-group-btn:not(:first-child):not(:last-child),\n.input-group .form-control:not(:first-child):not(:last-child) {\n border-radius: 0;\n}\n.input-group-addon,\n.input-group-btn {\n width: 1%;\n white-space: nowrap;\n vertical-align: middle;\n}\n.input-group-addon {\n padding: 6px 12px;\n font-size: 14px;\n font-weight: normal;\n line-height: 1;\n color: #555555;\n text-align: center;\n background-color: #eeeeee;\n border: 1px solid #cccccc;\n border-radius: 4px;\n}\n.input-group-addon.input-sm {\n padding: 5px 10px;\n font-size: 12px;\n border-radius: 3px;\n}\n.input-group-addon.input-lg {\n padding: 10px 16px;\n font-size: 18px;\n border-radius: 6px;\n}\n.input-group-addon input[type=\"radio\"],\n.input-group-addon input[type=\"checkbox\"] {\n margin-top: 0;\n}\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {\n border-bottom-right-radius: 0;\n border-top-right-radius: 0;\n}\n.input-group-addon:first-child {\n border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child),\n.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {\n border-bottom-left-radius: 0;\n border-top-left-radius: 0;\n}\n.input-group-addon:last-child {\n border-left: 0;\n}\n.input-group-btn {\n position: relative;\n font-size: 0;\n white-space: nowrap;\n}\n.input-group-btn > .btn {\n position: relative;\n}\n.input-group-btn > .btn + .btn {\n margin-left: -1px;\n}\n.input-group-btn > .btn:hover,\n.input-group-btn > .btn:focus,\n.input-group-btn > .btn:active {\n z-index: 2;\n}\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group {\n margin-right: -1px;\n}\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group {\n margin-left: -1px;\n}\n.nav {\n margin-bottom: 0;\n padding-left: 0;\n list-style: none;\n}\n.nav > li {\n position: relative;\n display: block;\n}\n.nav > li > a {\n position: relative;\n display: block;\n padding: 10px 15px;\n}\n.nav > li > a:hover,\n.nav > li > a:focus {\n text-decoration: none;\n background-color: #eeeeee;\n}\n.nav > li.disabled > a {\n color: #777777;\n}\n.nav > li.disabled > a:hover,\n.nav > li.disabled > a:focus {\n color: #777777;\n text-decoration: none;\n background-color: transparent;\n cursor: not-allowed;\n}\n.nav .open > a,\n.nav .open > a:hover,\n.nav .open > a:focus {\n background-color: #eeeeee;\n border-color: #337ab7;\n}\n.nav .nav-divider {\n height: 1px;\n margin: 9px 0;\n overflow: hidden;\n background-color: #e5e5e5;\n}\n.nav > li > a > img {\n max-width: none;\n}\n.nav-tabs {\n border-bottom: 1px solid #dddddd;\n}\n.nav-tabs > li {\n float: left;\n margin-bottom: -1px;\n}\n.nav-tabs > li > a {\n margin-right: 2px;\n line-height: 1.42857143;\n border: 1px solid transparent;\n border-radius: 4px 4px 0 0;\n}\n.nav-tabs > li > a:hover {\n border-color: #eeeeee #eeeeee #dddddd;\n}\n.nav-tabs > li.active > a,\n.nav-tabs > li.active > a:hover,\n.nav-tabs > li.active > a:focus {\n color: #555555;\n background-color: #ffffff;\n border: 1px solid #dddddd;\n border-bottom-color: transparent;\n cursor: default;\n}\n.nav-tabs.nav-justified {\n width: 100%;\n border-bottom: 0;\n}\n.nav-tabs.nav-justified > li {\n float: none;\n}\n.nav-tabs.nav-justified > li > a {\n text-align: center;\n margin-bottom: 5px;\n}\n.nav-tabs.nav-justified > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n}\n@media (min-width: 768px) {\n .nav-tabs.nav-justified > li {\n display: table-cell;\n width: 1%;\n }\n .nav-tabs.nav-justified > li > a {\n margin-bottom: 0;\n }\n}\n.nav-tabs.nav-justified > li > a {\n margin-right: 0;\n border-radius: 4px;\n}\n.nav-tabs.nav-justified > .active > a,\n.nav-tabs.nav-justified > .active > a:hover,\n.nav-tabs.nav-justified > .active > a:focus {\n border: 1px solid #dddddd;\n}\n@media (min-width: 768px) {\n .nav-tabs.nav-justified > li > a {\n border-bottom: 1px solid #dddddd;\n border-radius: 4px 4px 0 0;\n }\n .nav-tabs.nav-justified > .active > a,\n .nav-tabs.nav-justified > .active > a:hover,\n .nav-tabs.nav-justified > .active > a:focus {\n border-bottom-color: #ffffff;\n }\n}\n.nav-pills > li {\n float: left;\n}\n.nav-pills > li > a {\n border-radius: 4px;\n}\n.nav-pills > li + li {\n margin-left: 2px;\n}\n.nav-pills > li.active > a,\n.nav-pills > li.active > a:hover,\n.nav-pills > li.active > a:focus {\n color: #ffffff;\n background-color: #337ab7;\n}\n.nav-stacked > li {\n float: none;\n}\n.nav-stacked > li + li {\n margin-top: 2px;\n margin-left: 0;\n}\n.nav-justified {\n width: 100%;\n}\n.nav-justified > li {\n float: none;\n}\n.nav-justified > li > a {\n text-align: center;\n margin-bottom: 5px;\n}\n.nav-justified > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n}\n@media (min-width: 768px) {\n .nav-justified > li {\n display: table-cell;\n width: 1%;\n }\n .nav-justified > li > a {\n margin-bottom: 0;\n }\n}\n.nav-tabs-justified {\n border-bottom: 0;\n}\n.nav-tabs-justified > li > a {\n margin-right: 0;\n border-radius: 4px;\n}\n.nav-tabs-justified > .active > a,\n.nav-tabs-justified > .active > a:hover,\n.nav-tabs-justified > .active > a:focus {\n border: 1px solid #dddddd;\n}\n@media (min-width: 768px) {\n .nav-tabs-justified > li > a {\n border-bottom: 1px solid #dddddd;\n border-radius: 4px 4px 0 0;\n }\n .nav-tabs-justified > .active > a,\n .nav-tabs-justified > .active > a:hover,\n .nav-tabs-justified > .active > a:focus {\n border-bottom-color: #ffffff;\n }\n}\n.tab-content > .tab-pane {\n display: none;\n visibility: hidden;\n}\n.tab-content > .active {\n display: block;\n visibility: visible;\n}\n.nav-tabs .dropdown-menu {\n margin-top: -1px;\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.navbar {\n position: relative;\n min-height: 50px;\n margin-bottom: 20px;\n border: 1px solid transparent;\n}\n@media (min-width: 768px) {\n .navbar {\n border-radius: 4px;\n }\n}\n@media (min-width: 768px) {\n .navbar-header {\n float: left;\n }\n}\n.navbar-collapse {\n overflow-x: visible;\n padding-right: 15px;\n padding-left: 15px;\n border-top: 1px solid transparent;\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1);\n -webkit-overflow-scrolling: touch;\n}\n.navbar-collapse.in {\n overflow-y: auto;\n}\n@media (min-width: 768px) {\n .navbar-collapse {\n width: auto;\n border-top: 0;\n box-shadow: none;\n }\n .navbar-collapse.collapse {\n display: block !important;\n visibility: visible !important;\n height: auto !important;\n padding-bottom: 0;\n overflow: visible !important;\n }\n .navbar-collapse.in {\n overflow-y: visible;\n }\n .navbar-fixed-top .navbar-collapse,\n .navbar-static-top .navbar-collapse,\n .navbar-fixed-bottom .navbar-collapse {\n padding-left: 0;\n padding-right: 0;\n }\n}\n.navbar-fixed-top .navbar-collapse,\n.navbar-fixed-bottom .navbar-collapse {\n max-height: 340px;\n}\n@media (max-device-width: 480px) and (orientation: landscape) {\n .navbar-fixed-top .navbar-collapse,\n .navbar-fixed-bottom .navbar-collapse {\n max-height: 200px;\n }\n}\n.container > .navbar-header,\n.container-fluid > .navbar-header,\n.container > .navbar-collapse,\n.container-fluid > .navbar-collapse {\n margin-right: -15px;\n margin-left: -15px;\n}\n@media (min-width: 768px) {\n .container > .navbar-header,\n .container-fluid > .navbar-header,\n .container > .navbar-collapse,\n .container-fluid > .navbar-collapse {\n margin-right: 0;\n margin-left: 0;\n }\n}\n.navbar-static-top {\n z-index: 1000;\n border-width: 0 0 1px;\n}\n@media (min-width: 768px) {\n .navbar-static-top {\n border-radius: 0;\n }\n}\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n position: fixed;\n right: 0;\n left: 0;\n z-index: 1030;\n}\n@media (min-width: 768px) {\n .navbar-fixed-top,\n .navbar-fixed-bottom {\n border-radius: 0;\n }\n}\n.navbar-fixed-top {\n top: 0;\n border-width: 0 0 1px;\n}\n.navbar-fixed-bottom {\n bottom: 0;\n margin-bottom: 0;\n border-width: 1px 0 0;\n}\n.navbar-brand {\n float: left;\n padding: 15px 15px;\n font-size: 18px;\n line-height: 20px;\n height: 50px;\n}\n.navbar-brand:hover,\n.navbar-brand:focus {\n text-decoration: none;\n}\n.navbar-brand > img {\n display: block;\n}\n@media (min-width: 768px) {\n .navbar > .container .navbar-brand,\n .navbar > .container-fluid .navbar-brand {\n margin-left: -15px;\n }\n}\n.navbar-toggle {\n position: relative;\n float: right;\n margin-right: 15px;\n padding: 9px 10px;\n margin-top: 8px;\n margin-bottom: 8px;\n background-color: transparent;\n background-image: none;\n border: 1px solid transparent;\n border-radius: 4px;\n}\n.navbar-toggle:focus {\n outline: 0;\n}\n.navbar-toggle .icon-bar {\n display: block;\n width: 22px;\n height: 2px;\n border-radius: 1px;\n}\n.navbar-toggle .icon-bar + .icon-bar {\n margin-top: 4px;\n}\n@media (min-width: 768px) {\n .navbar-toggle {\n display: none;\n }\n}\n.navbar-nav {\n margin: 7.5px -15px;\n}\n.navbar-nav > li > a {\n padding-top: 10px;\n padding-bottom: 10px;\n line-height: 20px;\n}\n@media (max-width: 767px) {\n .navbar-nav .open .dropdown-menu {\n position: static;\n float: none;\n width: auto;\n margin-top: 0;\n background-color: transparent;\n border: 0;\n box-shadow: none;\n }\n .navbar-nav .open .dropdown-menu > li > a,\n .navbar-nav .open .dropdown-menu .dropdown-header {\n padding: 5px 15px 5px 25px;\n }\n .navbar-nav .open .dropdown-menu > li > a {\n line-height: 20px;\n }\n .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-nav .open .dropdown-menu > li > a:focus {\n background-image: none;\n }\n}\n@media (min-width: 768px) {\n .navbar-nav {\n float: left;\n margin: 0;\n }\n .navbar-nav > li {\n float: left;\n }\n .navbar-nav > li > a {\n padding-top: 15px;\n padding-bottom: 15px;\n }\n}\n.navbar-form {\n margin-left: -15px;\n margin-right: -15px;\n padding: 10px 15px;\n border-top: 1px solid transparent;\n border-bottom: 1px solid transparent;\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n margin-top: 8px;\n margin-bottom: 8px;\n}\n@media (min-width: 768px) {\n .navbar-form .form-group {\n display: inline-block;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .navbar-form .form-control-static {\n display: inline-block;\n }\n .navbar-form .input-group {\n display: inline-table;\n vertical-align: middle;\n }\n .navbar-form .input-group .input-group-addon,\n .navbar-form .input-group .input-group-btn,\n .navbar-form .input-group .form-control {\n width: auto;\n }\n .navbar-form .input-group > .form-control {\n width: 100%;\n }\n .navbar-form .control-label {\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .radio,\n .navbar-form .checkbox {\n display: inline-block;\n margin-top: 0;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .radio label,\n .navbar-form .checkbox label {\n padding-left: 0;\n }\n .navbar-form .radio input[type=\"radio\"],\n .navbar-form .checkbox input[type=\"checkbox\"] {\n position: relative;\n margin-left: 0;\n }\n .navbar-form .has-feedback .form-control-feedback {\n top: 0;\n }\n}\n@media (max-width: 767px) {\n .navbar-form .form-group {\n margin-bottom: 5px;\n }\n .navbar-form .form-group:last-child {\n margin-bottom: 0;\n }\n}\n@media (min-width: 768px) {\n .navbar-form {\n width: auto;\n border: 0;\n margin-left: 0;\n margin-right: 0;\n padding-top: 0;\n padding-bottom: 0;\n -webkit-box-shadow: none;\n box-shadow: none;\n }\n}\n.navbar-nav > li > .dropdown-menu {\n margin-top: 0;\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n margin-bottom: 0;\n border-top-right-radius: 4px;\n border-top-left-radius: 4px;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.navbar-btn {\n margin-top: 8px;\n margin-bottom: 8px;\n}\n.navbar-btn.btn-sm {\n margin-top: 10px;\n margin-bottom: 10px;\n}\n.navbar-btn.btn-xs {\n margin-top: 14px;\n margin-bottom: 14px;\n}\n.navbar-text {\n margin-top: 15px;\n margin-bottom: 15px;\n}\n@media (min-width: 768px) {\n .navbar-text {\n float: left;\n margin-left: 15px;\n margin-right: 15px;\n }\n}\n@media (min-width: 768px) {\n .navbar-left {\n float: left !important;\n }\n .navbar-right {\n float: right !important;\n margin-right: -15px;\n }\n .navbar-right ~ .navbar-right {\n margin-right: 0;\n }\n}\n.navbar-default {\n background-color: #f8f8f8;\n border-color: #e7e7e7;\n}\n.navbar-default .navbar-brand {\n color: #777777;\n}\n.navbar-default .navbar-brand:hover,\n.navbar-default .navbar-brand:focus {\n color: #5e5e5e;\n background-color: transparent;\n}\n.navbar-default .navbar-text {\n color: #777777;\n}\n.navbar-default .navbar-nav > li > a {\n color: #777777;\n}\n.navbar-default .navbar-nav > li > a:hover,\n.navbar-default .navbar-nav > li > a:focus {\n color: #333333;\n background-color: transparent;\n}\n.navbar-default .navbar-nav > .active > a,\n.navbar-default .navbar-nav > .active > a:hover,\n.navbar-default .navbar-nav > .active > a:focus {\n color: #555555;\n background-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .disabled > a,\n.navbar-default .navbar-nav > .disabled > a:hover,\n.navbar-default .navbar-nav > .disabled > a:focus {\n color: #cccccc;\n background-color: transparent;\n}\n.navbar-default .navbar-toggle {\n border-color: #dddddd;\n}\n.navbar-default .navbar-toggle:hover,\n.navbar-default .navbar-toggle:focus {\n background-color: #dddddd;\n}\n.navbar-default .navbar-toggle .icon-bar {\n background-color: #888888;\n}\n.navbar-default .navbar-collapse,\n.navbar-default .navbar-form {\n border-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .open > a:hover,\n.navbar-default .navbar-nav > .open > a:focus {\n background-color: #e7e7e7;\n color: #555555;\n}\n@media (max-width: 767px) {\n .navbar-default .navbar-nav .open .dropdown-menu > li > a {\n color: #777777;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {\n color: #333333;\n background-color: transparent;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a,\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #555555;\n background-color: #e7e7e7;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n color: #cccccc;\n background-color: transparent;\n }\n}\n.navbar-default .navbar-link {\n color: #777777;\n}\n.navbar-default .navbar-link:hover {\n color: #333333;\n}\n.navbar-default .btn-link {\n color: #777777;\n}\n.navbar-default .btn-link:hover,\n.navbar-default .btn-link:focus {\n color: #333333;\n}\n.navbar-default .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-default .btn-link:hover,\n.navbar-default .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-default .btn-link:focus {\n color: #cccccc;\n}\n.navbar-inverse {\n background-color: #222222;\n border-color: #080808;\n}\n.navbar-inverse .navbar-brand {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-brand:hover,\n.navbar-inverse .navbar-brand:focus {\n color: #ffffff;\n background-color: transparent;\n}\n.navbar-inverse .navbar-text {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a:hover,\n.navbar-inverse .navbar-nav > li > a:focus {\n color: #ffffff;\n background-color: transparent;\n}\n.navbar-inverse .navbar-nav > .active > a,\n.navbar-inverse .navbar-nav > .active > a:hover,\n.navbar-inverse .navbar-nav > .active > a:focus {\n color: #ffffff;\n background-color: #080808;\n}\n.navbar-inverse .navbar-nav > .disabled > a,\n.navbar-inverse .navbar-nav > .disabled > a:hover,\n.navbar-inverse .navbar-nav > .disabled > a:focus {\n color: #444444;\n background-color: transparent;\n}\n.navbar-inverse .navbar-toggle {\n border-color: #333333;\n}\n.navbar-inverse .navbar-toggle:hover,\n.navbar-inverse .navbar-toggle:focus {\n background-color: #333333;\n}\n.navbar-inverse .navbar-toggle .icon-bar {\n background-color: #ffffff;\n}\n.navbar-inverse .navbar-collapse,\n.navbar-inverse .navbar-form {\n border-color: #101010;\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .open > a:hover,\n.navbar-inverse .navbar-nav > .open > a:focus {\n background-color: #080808;\n color: #ffffff;\n}\n@media (max-width: 767px) {\n .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {\n border-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu .divider {\n background-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {\n color: #9d9d9d;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {\n color: #ffffff;\n background-color: transparent;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #ffffff;\n background-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n color: #444444;\n background-color: transparent;\n }\n}\n.navbar-inverse .navbar-link {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-link:hover {\n color: #ffffff;\n}\n.navbar-inverse .btn-link {\n color: #9d9d9d;\n}\n.navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link:focus {\n color: #ffffff;\n}\n.navbar-inverse .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-inverse .btn-link:focus {\n color: #444444;\n}\n.breadcrumb {\n padding: 8px 15px;\n margin-bottom: 20px;\n list-style: none;\n background-color: #f5f5f5;\n border-radius: 4px;\n}\n.breadcrumb > li {\n display: inline-block;\n}\n.breadcrumb > li + li:before {\n content: \"/\\00a0\";\n padding: 0 5px;\n color: #cccccc;\n}\n.breadcrumb > .active {\n color: #777777;\n}\n.pagination {\n display: inline-block;\n padding-left: 0;\n margin: 20px 0;\n border-radius: 4px;\n}\n.pagination > li {\n display: inline;\n}\n.pagination > li > a,\n.pagination > li > span {\n position: relative;\n float: left;\n padding: 6px 12px;\n line-height: 1.42857143;\n text-decoration: none;\n color: #337ab7;\n background-color: #ffffff;\n border: 1px solid #dddddd;\n margin-left: -1px;\n}\n.pagination > li:first-child > a,\n.pagination > li:first-child > span {\n margin-left: 0;\n border-bottom-left-radius: 4px;\n border-top-left-radius: 4px;\n}\n.pagination > li:last-child > a,\n.pagination > li:last-child > span {\n border-bottom-right-radius: 4px;\n border-top-right-radius: 4px;\n}\n.pagination > li > a:hover,\n.pagination > li > span:hover,\n.pagination > li > a:focus,\n.pagination > li > span:focus {\n color: #23527c;\n background-color: #eeeeee;\n border-color: #dddddd;\n}\n.pagination > .active > a,\n.pagination > .active > span,\n.pagination > .active > a:hover,\n.pagination > .active > span:hover,\n.pagination > .active > a:focus,\n.pagination > .active > span:focus {\n z-index: 2;\n color: #ffffff;\n background-color: #337ab7;\n border-color: #337ab7;\n cursor: default;\n}\n.pagination > .disabled > span,\n.pagination > .disabled > span:hover,\n.pagination > .disabled > span:focus,\n.pagination > .disabled > a,\n.pagination > .disabled > a:hover,\n.pagination > .disabled > a:focus {\n color: #777777;\n background-color: #ffffff;\n border-color: #dddddd;\n cursor: not-allowed;\n}\n.pagination-lg > li > a,\n.pagination-lg > li > span {\n padding: 10px 16px;\n font-size: 18px;\n}\n.pagination-lg > li:first-child > a,\n.pagination-lg > li:first-child > span {\n border-bottom-left-radius: 6px;\n border-top-left-radius: 6px;\n}\n.pagination-lg > li:last-child > a,\n.pagination-lg > li:last-child > span {\n border-bottom-right-radius: 6px;\n border-top-right-radius: 6px;\n}\n.pagination-sm > li > a,\n.pagination-sm > li > span {\n padding: 5px 10px;\n font-size: 12px;\n}\n.pagination-sm > li:first-child > a,\n.pagination-sm > li:first-child > span {\n border-bottom-left-radius: 3px;\n border-top-left-radius: 3px;\n}\n.pagination-sm > li:last-child > a,\n.pagination-sm > li:last-child > span {\n border-bottom-right-radius: 3px;\n border-top-right-radius: 3px;\n}\n.pager {\n padding-left: 0;\n margin: 20px 0;\n list-style: none;\n text-align: center;\n}\n.pager li {\n display: inline;\n}\n.pager li > a,\n.pager li > span {\n display: inline-block;\n padding: 5px 14px;\n background-color: #ffffff;\n border: 1px solid #dddddd;\n border-radius: 15px;\n}\n.pager li > a:hover,\n.pager li > a:focus {\n text-decoration: none;\n background-color: #eeeeee;\n}\n.pager .next > a,\n.pager .next > span {\n float: right;\n}\n.pager .previous > a,\n.pager .previous > span {\n float: left;\n}\n.pager .disabled > a,\n.pager .disabled > a:hover,\n.pager .disabled > a:focus,\n.pager .disabled > span {\n color: #777777;\n background-color: #ffffff;\n cursor: not-allowed;\n}\n.label {\n display: inline;\n padding: .2em .6em .3em;\n font-size: 75%;\n font-weight: bold;\n line-height: 1;\n color: #ffffff;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n border-radius: .25em;\n}\na.label:hover,\na.label:focus {\n color: #ffffff;\n text-decoration: none;\n cursor: pointer;\n}\n.label:empty {\n display: none;\n}\n.btn .label {\n position: relative;\n top: -1px;\n}\n.label-default {\n background-color: #777777;\n}\n.label-default[href]:hover,\n.label-default[href]:focus {\n background-color: #5e5e5e;\n}\n.label-primary {\n background-color: #337ab7;\n}\n.label-primary[href]:hover,\n.label-primary[href]:focus {\n background-color: #286090;\n}\n.label-success {\n background-color: #5cb85c;\n}\n.label-success[href]:hover,\n.label-success[href]:focus {\n background-color: #449d44;\n}\n.label-info {\n background-color: #5bc0de;\n}\n.label-info[href]:hover,\n.label-info[href]:focus {\n background-color: #31b0d5;\n}\n.label-warning {\n background-color: #f0ad4e;\n}\n.label-warning[href]:hover,\n.label-warning[href]:focus {\n background-color: #ec971f;\n}\n.label-danger {\n background-color: #d9534f;\n}\n.label-danger[href]:hover,\n.label-danger[href]:focus {\n background-color: #c9302c;\n}\n.badge {\n display: inline-block;\n min-width: 10px;\n padding: 3px 7px;\n font-size: 12px;\n font-weight: bold;\n color: #ffffff;\n line-height: 1;\n vertical-align: baseline;\n white-space: nowrap;\n text-align: center;\n background-color: #777777;\n border-radius: 10px;\n}\n.badge:empty {\n display: none;\n}\n.btn .badge {\n position: relative;\n top: -1px;\n}\n.btn-xs .badge {\n top: 0;\n padding: 1px 5px;\n}\na.badge:hover,\na.badge:focus {\n color: #ffffff;\n text-decoration: none;\n cursor: pointer;\n}\n.list-group-item.active > .badge,\n.nav-pills > .active > a > .badge {\n color: #337ab7;\n background-color: #ffffff;\n}\n.list-group-item > .badge {\n float: right;\n}\n.list-group-item > .badge + .badge {\n margin-right: 5px;\n}\n.nav-pills > li > a > .badge {\n margin-left: 3px;\n}\n.jumbotron {\n padding: 30px 15px;\n margin-bottom: 30px;\n color: inherit;\n background-color: #eeeeee;\n}\n.jumbotron h1,\n.jumbotron .h1 {\n color: inherit;\n}\n.jumbotron p {\n margin-bottom: 15px;\n font-size: 21px;\n font-weight: 200;\n}\n.jumbotron > hr {\n border-top-color: #d5d5d5;\n}\n.container .jumbotron,\n.container-fluid .jumbotron {\n border-radius: 6px;\n}\n.jumbotron .container {\n max-width: 100%;\n}\n@media screen and (min-width: 768px) {\n .jumbotron {\n padding: 48px 0;\n }\n .container .jumbotron,\n .container-fluid .jumbotron {\n padding-left: 60px;\n padding-right: 60px;\n }\n .jumbotron h1,\n .jumbotron .h1 {\n font-size: 63px;\n }\n}\n.thumbnail {\n display: block;\n padding: 4px;\n margin-bottom: 20px;\n line-height: 1.42857143;\n background-color: #ffffff;\n border: 1px solid #dddddd;\n border-radius: 4px;\n -webkit-transition: border 0.2s ease-in-out;\n -o-transition: border 0.2s ease-in-out;\n transition: border 0.2s ease-in-out;\n}\n.thumbnail > img,\n.thumbnail a > img {\n margin-left: auto;\n margin-right: auto;\n}\na.thumbnail:hover,\na.thumbnail:focus,\na.thumbnail.active {\n border-color: #337ab7;\n}\n.thumbnail .caption {\n padding: 9px;\n color: #333333;\n}\n.alert {\n padding: 15px;\n margin-bottom: 20px;\n border: 1px solid transparent;\n border-radius: 4px;\n}\n.alert h4 {\n margin-top: 0;\n color: inherit;\n}\n.alert .alert-link {\n font-weight: bold;\n}\n.alert > p,\n.alert > ul {\n margin-bottom: 0;\n}\n.alert > p + p {\n margin-top: 5px;\n}\n.alert-dismissable,\n.alert-dismissible {\n padding-right: 35px;\n}\n.alert-dismissable .close,\n.alert-dismissible .close {\n position: relative;\n top: -2px;\n right: -21px;\n color: inherit;\n}\n.alert-success {\n background-color: #dff0d8;\n border-color: #d6e9c6;\n color: #3c763d;\n}\n.alert-success hr {\n border-top-color: #c9e2b3;\n}\n.alert-success .alert-link {\n color: #2b542c;\n}\n.alert-info {\n background-color: #d9edf7;\n border-color: #bce8f1;\n color: #31708f;\n}\n.alert-info hr {\n border-top-color: #a6e1ec;\n}\n.alert-info .alert-link {\n color: #245269;\n}\n.alert-warning {\n background-color: #fcf8e3;\n border-color: #faebcc;\n color: #8a6d3b;\n}\n.alert-warning hr {\n border-top-color: #f7e1b5;\n}\n.alert-warning .alert-link {\n color: #66512c;\n}\n.alert-danger {\n background-color: #f2dede;\n border-color: #ebccd1;\n color: #a94442;\n}\n.alert-danger hr {\n border-top-color: #e4b9c0;\n}\n.alert-danger .alert-link {\n color: #843534;\n}\n@-webkit-keyframes progress-bar-stripes {\n from {\n background-position: 40px 0;\n }\n to {\n background-position: 0 0;\n }\n}\n@keyframes progress-bar-stripes {\n from {\n background-position: 40px 0;\n }\n to {\n background-position: 0 0;\n }\n}\n.progress {\n overflow: hidden;\n height: 20px;\n margin-bottom: 20px;\n background-color: #f5f5f5;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n}\n.progress-bar {\n float: left;\n width: 0%;\n height: 100%;\n font-size: 12px;\n line-height: 20px;\n color: #ffffff;\n text-align: center;\n background-color: #337ab7;\n -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n -webkit-transition: width 0.6s ease;\n -o-transition: width 0.6s ease;\n transition: width 0.6s ease;\n}\n.progress-striped .progress-bar,\n.progress-bar-striped {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-size: 40px 40px;\n}\n.progress.active .progress-bar,\n.progress-bar.active {\n -webkit-animation: progress-bar-stripes 2s linear infinite;\n -o-animation: progress-bar-stripes 2s linear infinite;\n animation: progress-bar-stripes 2s linear infinite;\n}\n.progress-bar-success {\n background-color: #5cb85c;\n}\n.progress-striped .progress-bar-success {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.progress-bar-info {\n background-color: #5bc0de;\n}\n.progress-striped .progress-bar-info {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.progress-bar-warning {\n background-color: #f0ad4e;\n}\n.progress-striped .progress-bar-warning {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.progress-bar-danger {\n background-color: #d9534f;\n}\n.progress-striped .progress-bar-danger {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.media {\n margin-top: 15px;\n}\n.media:first-child {\n margin-top: 0;\n}\n.media,\n.media-body {\n zoom: 1;\n overflow: hidden;\n}\n.media-body {\n width: 10000px;\n}\n.media-object {\n display: block;\n}\n.media-right,\n.media > .pull-right {\n padding-left: 10px;\n}\n.media-left,\n.media > .pull-left {\n padding-right: 10px;\n}\n.media-left,\n.media-right,\n.media-body {\n display: table-cell;\n vertical-align: top;\n}\n.media-middle {\n vertical-align: middle;\n}\n.media-bottom {\n vertical-align: bottom;\n}\n.media-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.media-list {\n padding-left: 0;\n list-style: none;\n}\n.list-group {\n margin-bottom: 20px;\n padding-left: 0;\n}\n.list-group-item {\n position: relative;\n display: block;\n padding: 10px 15px;\n margin-bottom: -1px;\n background-color: #ffffff;\n border: 1px solid #dddddd;\n}\n.list-group-item:first-child {\n border-top-right-radius: 4px;\n border-top-left-radius: 4px;\n}\n.list-group-item:last-child {\n margin-bottom: 0;\n border-bottom-right-radius: 4px;\n border-bottom-left-radius: 4px;\n}\na.list-group-item {\n color: #555555;\n}\na.list-group-item .list-group-item-heading {\n color: #333333;\n}\na.list-group-item:hover,\na.list-group-item:focus {\n text-decoration: none;\n color: #555555;\n background-color: #f5f5f5;\n}\n.list-group-item.disabled,\n.list-group-item.disabled:hover,\n.list-group-item.disabled:focus {\n background-color: #eeeeee;\n color: #777777;\n cursor: not-allowed;\n}\n.list-group-item.disabled .list-group-item-heading,\n.list-group-item.disabled:hover .list-group-item-heading,\n.list-group-item.disabled:focus .list-group-item-heading {\n color: inherit;\n}\n.list-group-item.disabled .list-group-item-text,\n.list-group-item.disabled:hover .list-group-item-text,\n.list-group-item.disabled:focus .list-group-item-text {\n color: #777777;\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n z-index: 2;\n color: #ffffff;\n background-color: #337ab7;\n border-color: #337ab7;\n}\n.list-group-item.active .list-group-item-heading,\n.list-group-item.active:hover .list-group-item-heading,\n.list-group-item.active:focus .list-group-item-heading,\n.list-group-item.active .list-group-item-heading > small,\n.list-group-item.active:hover .list-group-item-heading > small,\n.list-group-item.active:focus .list-group-item-heading > small,\n.list-group-item.active .list-group-item-heading > .small,\n.list-group-item.active:hover .list-group-item-heading > .small,\n.list-group-item.active:focus .list-group-item-heading > .small {\n color: inherit;\n}\n.list-group-item.active .list-group-item-text,\n.list-group-item.active:hover .list-group-item-text,\n.list-group-item.active:focus .list-group-item-text {\n color: #c7ddef;\n}\n.list-group-item-success {\n color: #3c763d;\n background-color: #dff0d8;\n}\na.list-group-item-success {\n color: #3c763d;\n}\na.list-group-item-success .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-success:hover,\na.list-group-item-success:focus {\n color: #3c763d;\n background-color: #d0e9c6;\n}\na.list-group-item-success.active,\na.list-group-item-success.active:hover,\na.list-group-item-success.active:focus {\n color: #fff;\n background-color: #3c763d;\n border-color: #3c763d;\n}\n.list-group-item-info {\n color: #31708f;\n background-color: #d9edf7;\n}\na.list-group-item-info {\n color: #31708f;\n}\na.list-group-item-info .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-info:hover,\na.list-group-item-info:focus {\n color: #31708f;\n background-color: #c4e3f3;\n}\na.list-group-item-info.active,\na.list-group-item-info.active:hover,\na.list-group-item-info.active:focus {\n color: #fff;\n background-color: #31708f;\n border-color: #31708f;\n}\n.list-group-item-warning {\n color: #8a6d3b;\n background-color: #fcf8e3;\n}\na.list-group-item-warning {\n color: #8a6d3b;\n}\na.list-group-item-warning .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-warning:hover,\na.list-group-item-warning:focus {\n color: #8a6d3b;\n background-color: #faf2cc;\n}\na.list-group-item-warning.active,\na.list-group-item-warning.active:hover,\na.list-group-item-warning.active:focus {\n color: #fff;\n background-color: #8a6d3b;\n border-color: #8a6d3b;\n}\n.list-group-item-danger {\n color: #a94442;\n background-color: #f2dede;\n}\na.list-group-item-danger {\n color: #a94442;\n}\na.list-group-item-danger .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-danger:hover,\na.list-group-item-danger:focus {\n color: #a94442;\n background-color: #ebcccc;\n}\na.list-group-item-danger.active,\na.list-group-item-danger.active:hover,\na.list-group-item-danger.active:focus {\n color: #fff;\n background-color: #a94442;\n border-color: #a94442;\n}\n.list-group-item-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.list-group-item-text {\n margin-bottom: 0;\n line-height: 1.3;\n}\n.panel {\n margin-bottom: 20px;\n background-color: #ffffff;\n border: 1px solid transparent;\n border-radius: 4px;\n -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n.panel-body {\n padding: 15px;\n}\n.panel-heading {\n padding: 10px 15px;\n border-bottom: 1px solid transparent;\n border-top-right-radius: 3px;\n border-top-left-radius: 3px;\n}\n.panel-heading > .dropdown .dropdown-toggle {\n color: inherit;\n}\n.panel-title {\n margin-top: 0;\n margin-bottom: 0;\n font-size: 16px;\n color: inherit;\n}\n.panel-title > a,\n.panel-title > small,\n.panel-title > .small,\n.panel-title > small > a,\n.panel-title > .small > a {\n color: inherit;\n}\n.panel-footer {\n padding: 10px 15px;\n background-color: #f5f5f5;\n border-top: 1px solid #dddddd;\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .list-group,\n.panel > .panel-collapse > .list-group {\n margin-bottom: 0;\n}\n.panel > .list-group .list-group-item,\n.panel > .panel-collapse > .list-group .list-group-item {\n border-width: 1px 0;\n border-radius: 0;\n}\n.panel > .list-group:first-child .list-group-item:first-child,\n.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child {\n border-top: 0;\n border-top-right-radius: 3px;\n border-top-left-radius: 3px;\n}\n.panel > .list-group:last-child .list-group-item:last-child,\n.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child {\n border-bottom: 0;\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel-heading + .list-group .list-group-item:first-child {\n border-top-width: 0;\n}\n.list-group + .panel-footer {\n border-top-width: 0;\n}\n.panel > .table,\n.panel > .table-responsive > .table,\n.panel > .panel-collapse > .table {\n margin-bottom: 0;\n}\n.panel > .table caption,\n.panel > .table-responsive > .table caption,\n.panel > .panel-collapse > .table caption {\n padding-left: 15px;\n padding-right: 15px;\n}\n.panel > .table:first-child,\n.panel > .table-responsive:first-child > .table:first-child {\n border-top-right-radius: 3px;\n border-top-left-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child {\n border-top-left-radius: 3px;\n border-top-right-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {\n border-top-left-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {\n border-top-right-radius: 3px;\n}\n.panel > .table:last-child,\n.panel > .table-responsive:last-child > .table:last-child {\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child {\n border-bottom-left-radius: 3px;\n border-bottom-right-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {\n border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child {\n border-bottom-right-radius: 3px;\n}\n.panel > .panel-body + .table,\n.panel > .panel-body + .table-responsive,\n.panel > .table + .panel-body,\n.panel > .table-responsive + .panel-body {\n border-top: 1px solid #dddddd;\n}\n.panel > .table > tbody:first-child > tr:first-child th,\n.panel > .table > tbody:first-child > tr:first-child td {\n border-top: 0;\n}\n.panel > .table-bordered,\n.panel > .table-responsive > .table-bordered {\n border: 0;\n}\n.panel > .table-bordered > thead > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:first-child,\n.panel > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-bordered > thead > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:first-child,\n.panel > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-bordered > tfoot > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n border-left: 0;\n}\n.panel > .table-bordered > thead > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:last-child,\n.panel > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-bordered > thead > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:last-child,\n.panel > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-bordered > tfoot > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n border-right: 0;\n}\n.panel > .table-bordered > thead > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > td,\n.panel > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-bordered > thead > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > th,\n.panel > .table-bordered > tbody > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {\n border-bottom: 0;\n}\n.panel > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-bordered > tfoot > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {\n border-bottom: 0;\n}\n.panel > .table-responsive {\n border: 0;\n margin-bottom: 0;\n}\n.panel-group {\n margin-bottom: 20px;\n}\n.panel-group .panel {\n margin-bottom: 0;\n border-radius: 4px;\n}\n.panel-group .panel + .panel {\n margin-top: 5px;\n}\n.panel-group .panel-heading {\n border-bottom: 0;\n}\n.panel-group .panel-heading + .panel-collapse > .panel-body,\n.panel-group .panel-heading + .panel-collapse > .list-group {\n border-top: 1px solid #dddddd;\n}\n.panel-group .panel-footer {\n border-top: 0;\n}\n.panel-group .panel-footer + .panel-collapse .panel-body {\n border-bottom: 1px solid #dddddd;\n}\n.panel-default {\n border-color: #dddddd;\n}\n.panel-default > .panel-heading {\n color: #333333;\n background-color: #f5f5f5;\n border-color: #dddddd;\n}\n.panel-default > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #dddddd;\n}\n.panel-default > .panel-heading .badge {\n color: #f5f5f5;\n background-color: #333333;\n}\n.panel-default > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #dddddd;\n}\n.panel-primary {\n border-color: #337ab7;\n}\n.panel-primary > .panel-heading {\n color: #ffffff;\n background-color: #337ab7;\n border-color: #337ab7;\n}\n.panel-primary > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #337ab7;\n}\n.panel-primary > .panel-heading .badge {\n color: #337ab7;\n background-color: #ffffff;\n}\n.panel-primary > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #337ab7;\n}\n.panel-success {\n border-color: #d6e9c6;\n}\n.panel-success > .panel-heading {\n color: #3c763d;\n background-color: #dff0d8;\n border-color: #d6e9c6;\n}\n.panel-success > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #d6e9c6;\n}\n.panel-success > .panel-heading .badge {\n color: #dff0d8;\n background-color: #3c763d;\n}\n.panel-success > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #d6e9c6;\n}\n.panel-info {\n border-color: #bce8f1;\n}\n.panel-info > .panel-heading {\n color: #31708f;\n background-color: #d9edf7;\n border-color: #bce8f1;\n}\n.panel-info > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #bce8f1;\n}\n.panel-info > .panel-heading .badge {\n color: #d9edf7;\n background-color: #31708f;\n}\n.panel-info > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #bce8f1;\n}\n.panel-warning {\n border-color: #faebcc;\n}\n.panel-warning > .panel-heading {\n color: #8a6d3b;\n background-color: #fcf8e3;\n border-color: #faebcc;\n}\n.panel-warning > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #faebcc;\n}\n.panel-warning > .panel-heading .badge {\n color: #fcf8e3;\n background-color: #8a6d3b;\n}\n.panel-warning > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #faebcc;\n}\n.panel-danger {\n border-color: #ebccd1;\n}\n.panel-danger > .panel-heading {\n color: #a94442;\n background-color: #f2dede;\n border-color: #ebccd1;\n}\n.panel-danger > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #ebccd1;\n}\n.panel-danger > .panel-heading .badge {\n color: #f2dede;\n background-color: #a94442;\n}\n.panel-danger > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #ebccd1;\n}\n.embed-responsive {\n position: relative;\n display: block;\n height: 0;\n padding: 0;\n overflow: hidden;\n}\n.embed-responsive .embed-responsive-item,\n.embed-responsive iframe,\n.embed-responsive embed,\n.embed-responsive object,\n.embed-responsive video {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n height: 100%;\n width: 100%;\n border: 0;\n}\n.embed-responsive.embed-responsive-16by9 {\n padding-bottom: 56.25%;\n}\n.embed-responsive.embed-responsive-4by3 {\n padding-bottom: 75%;\n}\n.well {\n min-height: 20px;\n padding: 19px;\n margin-bottom: 20px;\n background-color: #f5f5f5;\n border: 1px solid #e3e3e3;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n.well blockquote {\n border-color: #ddd;\n border-color: rgba(0, 0, 0, 0.15);\n}\n.well-lg {\n padding: 24px;\n border-radius: 6px;\n}\n.well-sm {\n padding: 9px;\n border-radius: 3px;\n}\n.close {\n float: right;\n font-size: 21px;\n font-weight: bold;\n line-height: 1;\n color: #000000;\n text-shadow: 0 1px 0 #ffffff;\n opacity: 0.2;\n filter: alpha(opacity=20);\n}\n.close:hover,\n.close:focus {\n color: #000000;\n text-decoration: none;\n cursor: pointer;\n opacity: 0.5;\n filter: alpha(opacity=50);\n}\nbutton.close {\n padding: 0;\n cursor: pointer;\n background: transparent;\n border: 0;\n -webkit-appearance: none;\n}\n.modal-open {\n overflow: hidden;\n}\n.modal {\n display: none;\n overflow: hidden;\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1040;\n -webkit-overflow-scrolling: touch;\n outline: 0;\n}\n.modal.fade .modal-dialog {\n -webkit-transform: translate(0, -25%);\n -ms-transform: translate(0, -25%);\n -o-transform: translate(0, -25%);\n transform: translate(0, -25%);\n -webkit-transition: -webkit-transform 0.3s ease-out;\n -moz-transition: -moz-transform 0.3s ease-out;\n -o-transition: -o-transform 0.3s ease-out;\n transition: transform 0.3s ease-out;\n}\n.modal.in .modal-dialog {\n -webkit-transform: translate(0, 0);\n -ms-transform: translate(0, 0);\n -o-transform: translate(0, 0);\n transform: translate(0, 0);\n}\n.modal-open .modal {\n overflow-x: hidden;\n overflow-y: auto;\n}\n.modal-dialog {\n position: relative;\n width: auto;\n margin: 10px;\n}\n.modal-content {\n position: relative;\n background-color: #ffffff;\n border: 1px solid #999999;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 6px;\n -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n background-clip: padding-box;\n outline: 0;\n}\n.modal-backdrop {\n position: absolute;\n top: 0;\n right: 0;\n left: 0;\n background-color: #000000;\n}\n.modal-backdrop.fade {\n opacity: 0;\n filter: alpha(opacity=0);\n}\n.modal-backdrop.in {\n opacity: 0.5;\n filter: alpha(opacity=50);\n}\n.modal-header {\n padding: 15px;\n border-bottom: 1px solid #e5e5e5;\n min-height: 16.42857143px;\n}\n.modal-header .close {\n margin-top: -2px;\n}\n.modal-title {\n margin: 0;\n line-height: 1.42857143;\n}\n.modal-body {\n position: relative;\n padding: 15px;\n}\n.modal-footer {\n padding: 15px;\n text-align: right;\n border-top: 1px solid #e5e5e5;\n}\n.modal-footer .btn + .btn {\n margin-left: 5px;\n margin-bottom: 0;\n}\n.modal-footer .btn-group .btn + .btn {\n margin-left: -1px;\n}\n.modal-footer .btn-block + .btn-block {\n margin-left: 0;\n}\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n@media (min-width: 768px) {\n .modal-dialog {\n width: 600px;\n margin: 30px auto;\n }\n .modal-content {\n -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n }\n .modal-sm {\n width: 300px;\n }\n}\n@media (min-width: 992px) {\n .modal-lg {\n width: 900px;\n }\n}\n.tooltip {\n position: absolute;\n z-index: 1070;\n display: block;\n visibility: visible;\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-size: 12px;\n font-weight: normal;\n line-height: 1.4;\n opacity: 0;\n filter: alpha(opacity=0);\n}\n.tooltip.in {\n opacity: 0.9;\n filter: alpha(opacity=90);\n}\n.tooltip.top {\n margin-top: -3px;\n padding: 5px 0;\n}\n.tooltip.right {\n margin-left: 3px;\n padding: 0 5px;\n}\n.tooltip.bottom {\n margin-top: 3px;\n padding: 5px 0;\n}\n.tooltip.left {\n margin-left: -3px;\n padding: 0 5px;\n}\n.tooltip-inner {\n max-width: 200px;\n padding: 3px 8px;\n color: #ffffff;\n text-align: center;\n text-decoration: none;\n background-color: #000000;\n border-radius: 4px;\n}\n.tooltip-arrow {\n position: absolute;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n.tooltip.top .tooltip-arrow {\n bottom: 0;\n left: 50%;\n margin-left: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000000;\n}\n.tooltip.top-left .tooltip-arrow {\n bottom: 0;\n right: 5px;\n margin-bottom: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000000;\n}\n.tooltip.top-right .tooltip-arrow {\n bottom: 0;\n left: 5px;\n margin-bottom: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000000;\n}\n.tooltip.right .tooltip-arrow {\n top: 50%;\n left: 0;\n margin-top: -5px;\n border-width: 5px 5px 5px 0;\n border-right-color: #000000;\n}\n.tooltip.left .tooltip-arrow {\n top: 50%;\n right: 0;\n margin-top: -5px;\n border-width: 5px 0 5px 5px;\n border-left-color: #000000;\n}\n.tooltip.bottom .tooltip-arrow {\n top: 0;\n left: 50%;\n margin-left: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000000;\n}\n.tooltip.bottom-left .tooltip-arrow {\n top: 0;\n right: 5px;\n margin-top: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000000;\n}\n.tooltip.bottom-right .tooltip-arrow {\n top: 0;\n left: 5px;\n margin-top: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000000;\n}\n.popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 1060;\n display: none;\n max-width: 276px;\n padding: 1px;\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-size: 14px;\n font-weight: normal;\n line-height: 1.42857143;\n text-align: left;\n background-color: #ffffff;\n background-clip: padding-box;\n border: 1px solid #cccccc;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 6px;\n -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n white-space: normal;\n}\n.popover.top {\n margin-top: -10px;\n}\n.popover.right {\n margin-left: 10px;\n}\n.popover.bottom {\n margin-top: 10px;\n}\n.popover.left {\n margin-left: -10px;\n}\n.popover-title {\n margin: 0;\n padding: 8px 14px;\n font-size: 14px;\n background-color: #f7f7f7;\n border-bottom: 1px solid #ebebeb;\n border-radius: 5px 5px 0 0;\n}\n.popover-content {\n padding: 9px 14px;\n}\n.popover > .arrow,\n.popover > .arrow:after {\n position: absolute;\n display: block;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n.popover > .arrow {\n border-width: 11px;\n}\n.popover > .arrow:after {\n border-width: 10px;\n content: \"\";\n}\n.popover.top > .arrow {\n left: 50%;\n margin-left: -11px;\n border-bottom-width: 0;\n border-top-color: #999999;\n border-top-color: rgba(0, 0, 0, 0.25);\n bottom: -11px;\n}\n.popover.top > .arrow:after {\n content: \" \";\n bottom: 1px;\n margin-left: -10px;\n border-bottom-width: 0;\n border-top-color: #ffffff;\n}\n.popover.right > .arrow {\n top: 50%;\n left: -11px;\n margin-top: -11px;\n border-left-width: 0;\n border-right-color: #999999;\n border-right-color: rgba(0, 0, 0, 0.25);\n}\n.popover.right > .arrow:after {\n content: \" \";\n left: 1px;\n bottom: -10px;\n border-left-width: 0;\n border-right-color: #ffffff;\n}\n.popover.bottom > .arrow {\n left: 50%;\n margin-left: -11px;\n border-top-width: 0;\n border-bottom-color: #999999;\n border-bottom-color: rgba(0, 0, 0, 0.25);\n top: -11px;\n}\n.popover.bottom > .arrow:after {\n content: \" \";\n top: 1px;\n margin-left: -10px;\n border-top-width: 0;\n border-bottom-color: #ffffff;\n}\n.popover.left > .arrow {\n top: 50%;\n right: -11px;\n margin-top: -11px;\n border-right-width: 0;\n border-left-color: #999999;\n border-left-color: rgba(0, 0, 0, 0.25);\n}\n.popover.left > .arrow:after {\n content: \" \";\n right: 1px;\n border-right-width: 0;\n border-left-color: #ffffff;\n bottom: -10px;\n}\n.carousel {\n position: relative;\n}\n.carousel-inner {\n position: relative;\n overflow: hidden;\n width: 100%;\n}\n.carousel-inner > .item {\n display: none;\n position: relative;\n -webkit-transition: 0.6s ease-in-out left;\n -o-transition: 0.6s ease-in-out left;\n transition: 0.6s ease-in-out left;\n}\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n line-height: 1;\n}\n@media all and (transform-3d), (-webkit-transform-3d) {\n .carousel-inner > .item {\n -webkit-transition: -webkit-transform 0.6s ease-in-out;\n -moz-transition: -moz-transform 0.6s ease-in-out;\n -o-transition: -o-transform 0.6s ease-in-out;\n transition: transform 0.6s ease-in-out;\n -webkit-backface-visibility: hidden;\n -moz-backface-visibility: hidden;\n backface-visibility: hidden;\n -webkit-perspective: 1000;\n -moz-perspective: 1000;\n perspective: 1000;\n }\n .carousel-inner > .item.next,\n .carousel-inner > .item.active.right {\n -webkit-transform: translate3d(100%, 0, 0);\n transform: translate3d(100%, 0, 0);\n left: 0;\n }\n .carousel-inner > .item.prev,\n .carousel-inner > .item.active.left {\n -webkit-transform: translate3d(-100%, 0, 0);\n transform: translate3d(-100%, 0, 0);\n left: 0;\n }\n .carousel-inner > .item.next.left,\n .carousel-inner > .item.prev.right,\n .carousel-inner > .item.active {\n -webkit-transform: translate3d(0, 0, 0);\n transform: translate3d(0, 0, 0);\n left: 0;\n }\n}\n.carousel-inner > .active,\n.carousel-inner > .next,\n.carousel-inner > .prev {\n display: block;\n}\n.carousel-inner > .active {\n left: 0;\n}\n.carousel-inner > .next,\n.carousel-inner > .prev {\n position: absolute;\n top: 0;\n width: 100%;\n}\n.carousel-inner > .next {\n left: 100%;\n}\n.carousel-inner > .prev {\n left: -100%;\n}\n.carousel-inner > .next.left,\n.carousel-inner > .prev.right {\n left: 0;\n}\n.carousel-inner > .active.left {\n left: -100%;\n}\n.carousel-inner > .active.right {\n left: 100%;\n}\n.carousel-control {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n width: 15%;\n opacity: 0.5;\n filter: alpha(opacity=50);\n font-size: 20px;\n color: #ffffff;\n text-align: center;\n text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n}\n.carousel-control.left {\n background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);\n}\n.carousel-control.right {\n left: auto;\n right: 0;\n background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);\n}\n.carousel-control:hover,\n.carousel-control:focus {\n outline: 0;\n color: #ffffff;\n text-decoration: none;\n opacity: 0.9;\n filter: alpha(opacity=90);\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-left,\n.carousel-control .glyphicon-chevron-right {\n position: absolute;\n top: 50%;\n z-index: 5;\n display: inline-block;\n}\n.carousel-control .icon-prev,\n.carousel-control .glyphicon-chevron-left {\n left: 50%;\n margin-left: -10px;\n}\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-right {\n right: 50%;\n margin-right: -10px;\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next {\n width: 20px;\n height: 20px;\n margin-top: -10px;\n line-height: 1;\n font-family: serif;\n}\n.carousel-control .icon-prev:before {\n content: '\\2039';\n}\n.carousel-control .icon-next:before {\n content: '\\203a';\n}\n.carousel-indicators {\n position: absolute;\n bottom: 10px;\n left: 50%;\n z-index: 15;\n width: 60%;\n margin-left: -30%;\n padding-left: 0;\n list-style: none;\n text-align: center;\n}\n.carousel-indicators li {\n display: inline-block;\n width: 10px;\n height: 10px;\n margin: 1px;\n text-indent: -999px;\n border: 1px solid #ffffff;\n border-radius: 10px;\n cursor: pointer;\n background-color: #000 \\9;\n background-color: rgba(0, 0, 0, 0);\n}\n.carousel-indicators .active {\n margin: 0;\n width: 12px;\n height: 12px;\n background-color: #ffffff;\n}\n.carousel-caption {\n position: absolute;\n left: 15%;\n right: 15%;\n bottom: 20px;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: #ffffff;\n text-align: center;\n text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n}\n.carousel-caption .btn {\n text-shadow: none;\n}\n@media screen and (min-width: 768px) {\n .carousel-control .glyphicon-chevron-left,\n .carousel-control .glyphicon-chevron-right,\n .carousel-control .icon-prev,\n .carousel-control .icon-next {\n width: 30px;\n height: 30px;\n margin-top: -15px;\n font-size: 30px;\n }\n .carousel-control .glyphicon-chevron-left,\n .carousel-control .icon-prev {\n margin-left: -15px;\n }\n .carousel-control .glyphicon-chevron-right,\n .carousel-control .icon-next {\n margin-right: -15px;\n }\n .carousel-caption {\n left: 20%;\n right: 20%;\n padding-bottom: 30px;\n }\n .carousel-indicators {\n bottom: 20px;\n }\n}\n.clearfix:before,\n.clearfix:after,\n.dl-horizontal dd:before,\n.dl-horizontal dd:after,\n.container:before,\n.container:after,\n.container-fluid:before,\n.container-fluid:after,\n.row:before,\n.row:after,\n.form-horizontal .form-group:before,\n.form-horizontal .form-group:after,\n.btn-toolbar:before,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:before,\n.btn-group-vertical > .btn-group:after,\n.nav:before,\n.nav:after,\n.navbar:before,\n.navbar:after,\n.navbar-header:before,\n.navbar-header:after,\n.navbar-collapse:before,\n.navbar-collapse:after,\n.pager:before,\n.pager:after,\n.panel-body:before,\n.panel-body:after,\n.modal-footer:before,\n.modal-footer:after {\n content: \" \";\n display: table;\n}\n.clearfix:after,\n.dl-horizontal dd:after,\n.container:after,\n.container-fluid:after,\n.row:after,\n.form-horizontal .form-group:after,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:after,\n.nav:after,\n.navbar:after,\n.navbar-header:after,\n.navbar-collapse:after,\n.pager:after,\n.panel-body:after,\n.modal-footer:after {\n clear: both;\n}\n.center-block {\n display: block;\n margin-left: auto;\n margin-right: auto;\n}\n.pull-right {\n float: right !important;\n}\n.pull-left {\n float: left !important;\n}\n.hide {\n display: none !important;\n}\n.show {\n display: block !important;\n}\n.invisible {\n visibility: hidden;\n}\n.text-hide {\n font: 0/0 a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n}\n.hidden {\n display: none !important;\n visibility: hidden !important;\n}\n.affix {\n position: fixed;\n}\n@-ms-viewport {\n width: device-width;\n}\n.visible-xs,\n.visible-sm,\n.visible-md,\n.visible-lg {\n display: none !important;\n}\n.visible-xs-block,\n.visible-xs-inline,\n.visible-xs-inline-block,\n.visible-sm-block,\n.visible-sm-inline,\n.visible-sm-inline-block,\n.visible-md-block,\n.visible-md-inline,\n.visible-md-inline-block,\n.visible-lg-block,\n.visible-lg-inline,\n.visible-lg-inline-block {\n display: none !important;\n}\n@media (max-width: 767px) {\n .visible-xs {\n display: block !important;\n }\n table.visible-xs {\n display: table;\n }\n tr.visible-xs {\n display: table-row !important;\n }\n th.visible-xs,\n td.visible-xs {\n display: table-cell !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-block {\n display: block !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-inline {\n display: inline !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm {\n display: block !important;\n }\n table.visible-sm {\n display: table;\n }\n tr.visible-sm {\n display: table-row !important;\n }\n th.visible-sm,\n td.visible-sm {\n display: table-cell !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-block {\n display: block !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-inline {\n display: inline !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md {\n display: block !important;\n }\n table.visible-md {\n display: table;\n }\n tr.visible-md {\n display: table-row !important;\n }\n th.visible-md,\n td.visible-md {\n display: table-cell !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-block {\n display: block !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-inline {\n display: inline !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg {\n display: block !important;\n }\n table.visible-lg {\n display: table;\n }\n tr.visible-lg {\n display: table-row !important;\n }\n th.visible-lg,\n td.visible-lg {\n display: table-cell !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-block {\n display: block !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-inline {\n display: inline !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-inline-block {\n display: inline-block !important;\n }\n}\n@media (max-width: 767px) {\n .hidden-xs {\n display: none !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .hidden-sm {\n display: none !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .hidden-md {\n display: none !important;\n }\n}\n@media (min-width: 1200px) {\n .hidden-lg {\n display: none !important;\n }\n}\n.visible-print {\n display: none !important;\n}\n@media print {\n .visible-print {\n display: block !important;\n }\n table.visible-print {\n display: table;\n }\n tr.visible-print {\n display: table-row !important;\n }\n th.visible-print,\n td.visible-print {\n display: table-cell !important;\n }\n}\n.visible-print-block {\n display: none !important;\n}\n@media print {\n .visible-print-block {\n display: block !important;\n }\n}\n.visible-print-inline {\n display: none !important;\n}\n@media print {\n .visible-print-inline {\n display: inline !important;\n }\n}\n.visible-print-inline-block {\n display: none !important;\n}\n@media print {\n .visible-print-inline-block {\n display: inline-block !important;\n }\n}\n@media print {\n .hidden-print {\n display: none !important;\n }\n}\n/*# sourceMappingURL=bootstrap.css.map */","/*! normalize.css v3.0.2 | MIT License | git.io/normalize */\n\n//\n// 1. Set default font family to sans-serif.\n// 2. Prevent iOS text size adjust after orientation change, without disabling\n// user zoom.\n//\n\nhtml {\n font-family: sans-serif; // 1\n -ms-text-size-adjust: 100%; // 2\n -webkit-text-size-adjust: 100%; // 2\n}\n\n//\n// Remove default margin.\n//\n\nbody {\n margin: 0;\n}\n\n// HTML5 display definitions\n// ==========================================================================\n\n//\n// Correct `block` display not defined for any HTML5 element in IE 8/9.\n// Correct `block` display not defined for `details` or `summary` in IE 10/11\n// and Firefox.\n// Correct `block` display not defined for `main` in IE 11.\n//\n\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n display: block;\n}\n\n//\n// 1. Correct `inline-block` display not defined in IE 8/9.\n// 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.\n//\n\naudio,\ncanvas,\nprogress,\nvideo {\n display: inline-block; // 1\n vertical-align: baseline; // 2\n}\n\n//\n// Prevent modern browsers from displaying `audio` without controls.\n// Remove excess height in iOS 5 devices.\n//\n\naudio:not([controls]) {\n display: none;\n height: 0;\n}\n\n//\n// Address `[hidden]` styling not present in IE 8/9/10.\n// Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22.\n//\n\n[hidden],\ntemplate {\n display: none;\n}\n\n// Links\n// ==========================================================================\n\n//\n// Remove the gray background color from active links in IE 10.\n//\n\na {\n background-color: transparent;\n}\n\n//\n// Improve readability when focused and also mouse hovered in all browsers.\n//\n\na:active,\na:hover {\n outline: 0;\n}\n\n// Text-level semantics\n// ==========================================================================\n\n//\n// Address styling not present in IE 8/9/10/11, Safari, and Chrome.\n//\n\nabbr[title] {\n border-bottom: 1px dotted;\n}\n\n//\n// Address style set to `bolder` in Firefox 4+, Safari, and Chrome.\n//\n\nb,\nstrong {\n font-weight: bold;\n}\n\n//\n// Address styling not present in Safari and Chrome.\n//\n\ndfn {\n font-style: italic;\n}\n\n//\n// Address variable `h1` font-size and margin within `section` and `article`\n// contexts in Firefox 4+, Safari, and Chrome.\n//\n\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\n\n//\n// Address styling not present in IE 8/9.\n//\n\nmark {\n background: #ff0;\n color: #000;\n}\n\n//\n// Address inconsistent and variable font size in all browsers.\n//\n\nsmall {\n font-size: 80%;\n}\n\n//\n// Prevent `sub` and `sup` affecting `line-height` in all browsers.\n//\n\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\n\nsup {\n top: -0.5em;\n}\n\nsub {\n bottom: -0.25em;\n}\n\n// Embedded content\n// ==========================================================================\n\n//\n// Remove border when inside `a` element in IE 8/9/10.\n//\n\nimg {\n border: 0;\n}\n\n//\n// Correct overflow not hidden in IE 9/10/11.\n//\n\nsvg:not(:root) {\n overflow: hidden;\n}\n\n// Grouping content\n// ==========================================================================\n\n//\n// Address margin not present in IE 8/9 and Safari.\n//\n\nfigure {\n margin: 1em 40px;\n}\n\n//\n// Address differences between Firefox and other browsers.\n//\n\nhr {\n -moz-box-sizing: content-box;\n box-sizing: content-box;\n height: 0;\n}\n\n//\n// Contain overflow in all browsers.\n//\n\npre {\n overflow: auto;\n}\n\n//\n// Address odd `em`-unit font size rendering in all browsers.\n//\n\ncode,\nkbd,\npre,\nsamp {\n font-family: monospace, monospace;\n font-size: 1em;\n}\n\n// Forms\n// ==========================================================================\n\n//\n// Known limitation: by default, Chrome and Safari on OS X allow very limited\n// styling of `select`, unless a `border` property is set.\n//\n\n//\n// 1. Correct color not being inherited.\n// Known issue: affects color of disabled elements.\n// 2. Correct font properties not being inherited.\n// 3. Address margins set differently in Firefox 4+, Safari, and Chrome.\n//\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n color: inherit; // 1\n font: inherit; // 2\n margin: 0; // 3\n}\n\n//\n// Address `overflow` set to `hidden` in IE 8/9/10/11.\n//\n\nbutton {\n overflow: visible;\n}\n\n//\n// Address inconsistent `text-transform` inheritance for `button` and `select`.\n// All other form control elements do not inherit `text-transform` values.\n// Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.\n// Correct `select` style inheritance in Firefox.\n//\n\nbutton,\nselect {\n text-transform: none;\n}\n\n//\n// 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`\n// and `video` controls.\n// 2. Correct inability to style clickable `input` types in iOS.\n// 3. Improve usability and consistency of cursor style between image-type\n// `input` and others.\n//\n\nbutton,\nhtml input[type=\"button\"], // 1\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n -webkit-appearance: button; // 2\n cursor: pointer; // 3\n}\n\n//\n// Re-set default cursor for disabled elements.\n//\n\nbutton[disabled],\nhtml input[disabled] {\n cursor: default;\n}\n\n//\n// Remove inner padding and border in Firefox 4+.\n//\n\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n border: 0;\n padding: 0;\n}\n\n//\n// Address Firefox 4+ setting `line-height` on `input` using `!important` in\n// the UA stylesheet.\n//\n\ninput {\n line-height: normal;\n}\n\n//\n// It's recommended that you don't attempt to style these elements.\n// Firefox's implementation doesn't respect box-sizing, padding, or width.\n//\n// 1. Address box sizing set to `content-box` in IE 8/9/10.\n// 2. Remove excess padding in IE 8/9/10.\n//\n\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n box-sizing: border-box; // 1\n padding: 0; // 2\n}\n\n//\n// Fix the cursor style for Chrome's increment/decrement buttons. For certain\n// `font-size` values of the `input`, it causes the cursor style of the\n// decrement button to change from `default` to `text`.\n//\n\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n//\n// 1. Address `appearance` set to `searchfield` in Safari and Chrome.\n// 2. Address `box-sizing` set to `border-box` in Safari and Chrome\n// (include `-moz` to future-proof).\n//\n\ninput[type=\"search\"] {\n -webkit-appearance: textfield; // 1\n -moz-box-sizing: content-box;\n -webkit-box-sizing: content-box; // 2\n box-sizing: content-box;\n}\n\n//\n// Remove inner padding and search cancel button in Safari and Chrome on OS X.\n// Safari (but not Chrome) clips the cancel button when the search input has\n// padding (and `textfield` appearance).\n//\n\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n//\n// Define consistent border, margin, and padding.\n//\n\nfieldset {\n border: 1px solid #c0c0c0;\n margin: 0 2px;\n padding: 0.35em 0.625em 0.75em;\n}\n\n//\n// 1. Correct `color` not being inherited in IE 8/9/10/11.\n// 2. Remove padding so people aren't caught out if they zero out fieldsets.\n//\n\nlegend {\n border: 0; // 1\n padding: 0; // 2\n}\n\n//\n// Remove default vertical scrollbar in IE 8/9/10/11.\n//\n\ntextarea {\n overflow: auto;\n}\n\n//\n// Don't inherit the `font-weight` (applied by a rule above).\n// NOTE: the default cannot safely be changed in Chrome and Safari on OS X.\n//\n\noptgroup {\n font-weight: bold;\n}\n\n// Tables\n// ==========================================================================\n\n//\n// Remove most spacing between table cells.\n//\n\ntable {\n border-collapse: collapse;\n border-spacing: 0;\n}\n\ntd,\nth {\n padding: 0;\n}\n","/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n\n// ==========================================================================\n// Print styles.\n// Inlined to avoid the additional HTTP request: h5bp.com/r\n// ==========================================================================\n\n@media print {\n *,\n *:before,\n *:after {\n background: transparent !important;\n color: #000 !important; // Black prints faster: h5bp.com/s\n box-shadow: none !important;\n text-shadow: none !important;\n }\n\n a,\n a:visited {\n text-decoration: underline;\n }\n\n a[href]:after {\n content: \" (\" attr(href) \")\";\n }\n\n abbr[title]:after {\n content: \" (\" attr(title) \")\";\n }\n\n // Don't show links that are fragment identifiers,\n // or use the `javascript:` pseudo protocol\n a[href^=\"#\"]:after,\n a[href^=\"javascript:\"]:after {\n content: \"\";\n }\n\n pre,\n blockquote {\n border: 1px solid #999;\n page-break-inside: avoid;\n }\n\n thead {\n display: table-header-group; // h5bp.com/t\n }\n\n tr,\n img {\n page-break-inside: avoid;\n }\n\n img {\n max-width: 100% !important;\n }\n\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n\n h2,\n h3 {\n page-break-after: avoid;\n }\n\n // Bootstrap specific changes start\n //\n // Chrome (OSX) fix for https://github.com/twbs/bootstrap/issues/11245\n // Once fixed, we can just straight up remove this.\n select {\n background: #fff !important;\n }\n\n // Bootstrap components\n .navbar {\n display: none;\n }\n .btn,\n .dropup > .btn {\n > .caret {\n border-top-color: #000 !important;\n }\n }\n .label {\n border: 1px solid #000;\n }\n\n .table {\n border-collapse: collapse !important;\n\n td,\n th {\n background-color: #fff !important;\n }\n }\n .table-bordered {\n th,\n td {\n border: 1px solid #ddd !important;\n }\n }\n\n // Bootstrap specific changes end\n}\n","//\n// Glyphicons for Bootstrap\n//\n// Since icons are fonts, they can be placed anywhere text is placed and are\n// thus automatically sized to match the surrounding child. To use, create an\n// inline element with the appropriate classes, like so:\n//\n// <a href=\"#\"><span class=\"glyphicon glyphicon-star\"></span> Star</a>\n\n// Import the fonts\n@font-face {\n font-family: 'Glyphicons Halflings';\n src: url('@{icon-font-path}@{icon-font-name}.eot');\n src: url('@{icon-font-path}@{icon-font-name}.eot?#iefix') format('embedded-opentype'),\n url('@{icon-font-path}@{icon-font-name}.woff2') format('woff2'),\n url('@{icon-font-path}@{icon-font-name}.woff') format('woff'),\n url('@{icon-font-path}@{icon-font-name}.ttf') format('truetype'),\n url('@{icon-font-path}@{icon-font-name}.svg#@{icon-font-svg-id}') format('svg');\n}\n\n// Catchall baseclass\n.glyphicon {\n position: relative;\n top: 1px;\n display: inline-block;\n font-family: 'Glyphicons Halflings';\n font-style: normal;\n font-weight: normal;\n line-height: 1;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\n// Individual icons\n.glyphicon-asterisk { &:before { content: \"\\2a\"; } }\n.glyphicon-plus { &:before { content: \"\\2b\"; } }\n.glyphicon-euro,\n.glyphicon-eur { &:before { content: \"\\20ac\"; } }\n.glyphicon-minus { &:before { content: \"\\2212\"; } }\n.glyphicon-cloud { &:before { content: \"\\2601\"; } }\n.glyphicon-envelope { &:before { content: \"\\2709\"; } }\n.glyphicon-pencil { &:before { content: \"\\270f\"; } }\n.glyphicon-glass { &:before { content: \"\\e001\"; } }\n.glyphicon-music { &:before { content: \"\\e002\"; } }\n.glyphicon-search { &:before { content: \"\\e003\"; } }\n.glyphicon-heart { &:before { content: \"\\e005\"; } }\n.glyphicon-star { &:before { content: \"\\e006\"; } }\n.glyphicon-star-empty { &:before { content: \"\\e007\"; } }\n.glyphicon-user { &:before { content: \"\\e008\"; } }\n.glyphicon-film { &:before { content: \"\\e009\"; } }\n.glyphicon-th-large { &:before { content: \"\\e010\"; } }\n.glyphicon-th { &:before { content: \"\\e011\"; } }\n.glyphicon-th-list { &:before { content: \"\\e012\"; } }\n.glyphicon-ok { &:before { content: \"\\e013\"; } }\n.glyphicon-remove { &:before { content: \"\\e014\"; } }\n.glyphicon-zoom-in { &:before { content: \"\\e015\"; } }\n.glyphicon-zoom-out { &:before { content: \"\\e016\"; } }\n.glyphicon-off { &:before { content: \"\\e017\"; } }\n.glyphicon-signal { &:before { content: \"\\e018\"; } }\n.glyphicon-cog { &:before { content: \"\\e019\"; } }\n.glyphicon-trash { &:before { content: \"\\e020\"; } }\n.glyphicon-home { &:before { content: \"\\e021\"; } }\n.glyphicon-file { &:before { content: \"\\e022\"; } }\n.glyphicon-time { &:before { content: \"\\e023\"; } }\n.glyphicon-road { &:before { content: \"\\e024\"; } }\n.glyphicon-download-alt { &:before { content: \"\\e025\"; } }\n.glyphicon-download { &:before { content: \"\\e026\"; } }\n.glyphicon-upload { &:before { content: \"\\e027\"; } }\n.glyphicon-inbox { &:before { content: \"\\e028\"; } }\n.glyphicon-play-circle { &:before { content: \"\\e029\"; } }\n.glyphicon-repeat { &:before { content: \"\\e030\"; } }\n.glyphicon-refresh { &:before { content: \"\\e031\"; } }\n.glyphicon-list-alt { &:before { content: \"\\e032\"; } }\n.glyphicon-lock { &:before { content: \"\\e033\"; } }\n.glyphicon-flag { &:before { content: \"\\e034\"; } }\n.glyphicon-headphones { &:before { content: \"\\e035\"; } }\n.glyphicon-volume-off { &:before { content: \"\\e036\"; } }\n.glyphicon-volume-down { &:before { content: \"\\e037\"; } }\n.glyphicon-volume-up { &:before { content: \"\\e038\"; } }\n.glyphicon-qrcode { &:before { content: \"\\e039\"; } }\n.glyphicon-barcode { &:before { content: \"\\e040\"; } }\n.glyphicon-tag { &:before { content: \"\\e041\"; } }\n.glyphicon-tags { &:before { content: \"\\e042\"; } }\n.glyphicon-book { &:before { content: \"\\e043\"; } }\n.glyphicon-bookmark { &:before { content: \"\\e044\"; } }\n.glyphicon-print { &:before { content: \"\\e045\"; } }\n.glyphicon-camera { &:before { content: \"\\e046\"; } }\n.glyphicon-font { &:before { content: \"\\e047\"; } }\n.glyphicon-bold { &:before { content: \"\\e048\"; } }\n.glyphicon-italic { &:before { content: \"\\e049\"; } }\n.glyphicon-text-height { &:before { content: \"\\e050\"; } }\n.glyphicon-text-width { &:before { content: \"\\e051\"; } }\n.glyphicon-align-left { &:before { content: \"\\e052\"; } }\n.glyphicon-align-center { &:before { content: \"\\e053\"; } }\n.glyphicon-align-right { &:before { content: \"\\e054\"; } }\n.glyphicon-align-justify { &:before { content: \"\\e055\"; } }\n.glyphicon-list { &:before { content: \"\\e056\"; } }\n.glyphicon-indent-left { &:before { content: \"\\e057\"; } }\n.glyphicon-indent-right { &:before { content: \"\\e058\"; } }\n.glyphicon-facetime-video { &:before { content: \"\\e059\"; } }\n.glyphicon-picture { &:before { content: \"\\e060\"; } }\n.glyphicon-map-marker { &:before { content: \"\\e062\"; } }\n.glyphicon-adjust { &:before { content: \"\\e063\"; } }\n.glyphicon-tint { &:before { content: \"\\e064\"; } }\n.glyphicon-edit { &:before { content: \"\\e065\"; } }\n.glyphicon-share { &:before { content: \"\\e066\"; } }\n.glyphicon-check { &:before { content: \"\\e067\"; } }\n.glyphicon-move { &:before { content: \"\\e068\"; } }\n.glyphicon-step-backward { &:before { content: \"\\e069\"; } }\n.glyphicon-fast-backward { &:before { content: \"\\e070\"; } }\n.glyphicon-backward { &:before { content: \"\\e071\"; } }\n.glyphicon-play { &:before { content: \"\\e072\"; } }\n.glyphicon-pause { &:before { content: \"\\e073\"; } }\n.glyphicon-stop { &:before { content: \"\\e074\"; } }\n.glyphicon-forward { &:before { content: \"\\e075\"; } }\n.glyphicon-fast-forward { &:before { content: \"\\e076\"; } }\n.glyphicon-step-forward { &:before { content: \"\\e077\"; } }\n.glyphicon-eject { &:before { content: \"\\e078\"; } }\n.glyphicon-chevron-left { &:before { content: \"\\e079\"; } }\n.glyphicon-chevron-right { &:before { content: \"\\e080\"; } }\n.glyphicon-plus-sign { &:before { content: \"\\e081\"; } }\n.glyphicon-minus-sign { &:before { content: \"\\e082\"; } }\n.glyphicon-remove-sign { &:before { content: \"\\e083\"; } }\n.glyphicon-ok-sign { &:before { content: \"\\e084\"; } }\n.glyphicon-question-sign { &:before { content: \"\\e085\"; } }\n.glyphicon-info-sign { &:before { content: \"\\e086\"; } }\n.glyphicon-screenshot { &:before { content: \"\\e087\"; } }\n.glyphicon-remove-circle { &:before { content: \"\\e088\"; } }\n.glyphicon-ok-circle { &:before { content: \"\\e089\"; } }\n.glyphicon-ban-circle { &:before { content: \"\\e090\"; } }\n.glyphicon-arrow-left { &:before { content: \"\\e091\"; } }\n.glyphicon-arrow-right { &:before { content: \"\\e092\"; } }\n.glyphicon-arrow-up { &:before { content: \"\\e093\"; } }\n.glyphicon-arrow-down { &:before { content: \"\\e094\"; } }\n.glyphicon-share-alt { &:before { content: \"\\e095\"; } }\n.glyphicon-resize-full { &:before { content: \"\\e096\"; } }\n.glyphicon-resize-small { &:before { content: \"\\e097\"; } }\n.glyphicon-exclamation-sign { &:before { content: \"\\e101\"; } }\n.glyphicon-gift { &:before { content: \"\\e102\"; } }\n.glyphicon-leaf { &:before { content: \"\\e103\"; } }\n.glyphicon-fire { &:before { content: \"\\e104\"; } }\n.glyphicon-eye-open { &:before { content: \"\\e105\"; } }\n.glyphicon-eye-close { &:before { content: \"\\e106\"; } }\n.glyphicon-warning-sign { &:before { content: \"\\e107\"; } }\n.glyphicon-plane { &:before { content: \"\\e108\"; } }\n.glyphicon-calendar { &:before { content: \"\\e109\"; } }\n.glyphicon-random { &:before { content: \"\\e110\"; } }\n.glyphicon-comment { &:before { content: \"\\e111\"; } }\n.glyphicon-magnet { &:before { content: \"\\e112\"; } }\n.glyphicon-chevron-up { &:before { content: \"\\e113\"; } }\n.glyphicon-chevron-down { &:before { content: \"\\e114\"; } }\n.glyphicon-retweet { &:before { content: \"\\e115\"; } }\n.glyphicon-shopping-cart { &:before { content: \"\\e116\"; } }\n.glyphicon-folder-close { &:before { content: \"\\e117\"; } }\n.glyphicon-folder-open { &:before { content: \"\\e118\"; } }\n.glyphicon-resize-vertical { &:before { content: \"\\e119\"; } }\n.glyphicon-resize-horizontal { &:before { content: \"\\e120\"; } }\n.glyphicon-hdd { &:before { content: \"\\e121\"; } }\n.glyphicon-bullhorn { &:before { content: \"\\e122\"; } }\n.glyphicon-bell { &:before { content: \"\\e123\"; } }\n.glyphicon-certificate { &:before { content: \"\\e124\"; } }\n.glyphicon-thumbs-up { &:before { content: \"\\e125\"; } }\n.glyphicon-thumbs-down { &:before { content: \"\\e126\"; } }\n.glyphicon-hand-right { &:before { content: \"\\e127\"; } }\n.glyphicon-hand-left { &:before { content: \"\\e128\"; } }\n.glyphicon-hand-up { &:before { content: \"\\e129\"; } }\n.glyphicon-hand-down { &:before { content: \"\\e130\"; } }\n.glyphicon-circle-arrow-right { &:before { content: \"\\e131\"; } }\n.glyphicon-circle-arrow-left { &:before { content: \"\\e132\"; } }\n.glyphicon-circle-arrow-up { &:before { content: \"\\e133\"; } }\n.glyphicon-circle-arrow-down { &:before { content: \"\\e134\"; } }\n.glyphicon-globe { &:before { content: \"\\e135\"; } }\n.glyphicon-wrench { &:before { content: \"\\e136\"; } }\n.glyphicon-tasks { &:before { content: \"\\e137\"; } }\n.glyphicon-filter { &:before { content: \"\\e138\"; } }\n.glyphicon-briefcase { &:before { content: \"\\e139\"; } }\n.glyphicon-fullscreen { &:before { content: \"\\e140\"; } }\n.glyphicon-dashboard { &:before { content: \"\\e141\"; } }\n.glyphicon-paperclip { &:before { content: \"\\e142\"; } }\n.glyphicon-heart-empty { &:before { content: \"\\e143\"; } }\n.glyphicon-link { &:before { content: \"\\e144\"; } }\n.glyphicon-phone { &:before { content: \"\\e145\"; } }\n.glyphicon-pushpin { &:before { content: \"\\e146\"; } }\n.glyphicon-usd { &:before { content: \"\\e148\"; } }\n.glyphicon-gbp { &:before { content: \"\\e149\"; } }\n.glyphicon-sort { &:before { content: \"\\e150\"; } }\n.glyphicon-sort-by-alphabet { &:before { content: \"\\e151\"; } }\n.glyphicon-sort-by-alphabet-alt { &:before { content: \"\\e152\"; } }\n.glyphicon-sort-by-order { &:before { content: \"\\e153\"; } }\n.glyphicon-sort-by-order-alt { &:before { content: \"\\e154\"; } }\n.glyphicon-sort-by-attributes { &:before { content: \"\\e155\"; } }\n.glyphicon-sort-by-attributes-alt { &:before { content: \"\\e156\"; } }\n.glyphicon-unchecked { &:before { content: \"\\e157\"; } }\n.glyphicon-expand { &:before { content: \"\\e158\"; } }\n.glyphicon-collapse-down { &:before { content: \"\\e159\"; } }\n.glyphicon-collapse-up { &:before { content: \"\\e160\"; } }\n.glyphicon-log-in { &:before { content: \"\\e161\"; } }\n.glyphicon-flash { &:before { content: \"\\e162\"; } }\n.glyphicon-log-out { &:before { content: \"\\e163\"; } }\n.glyphicon-new-window { &:before { content: \"\\e164\"; } }\n.glyphicon-record { &:before { content: \"\\e165\"; } }\n.glyphicon-save { &:before { content: \"\\e166\"; } }\n.glyphicon-open { &:before { content: \"\\e167\"; } }\n.glyphicon-saved { &:before { content: \"\\e168\"; } }\n.glyphicon-import { &:before { content: \"\\e169\"; } }\n.glyphicon-export { &:before { content: \"\\e170\"; } }\n.glyphicon-send { &:before { content: \"\\e171\"; } }\n.glyphicon-floppy-disk { &:before { content: \"\\e172\"; } }\n.glyphicon-floppy-saved { &:before { content: \"\\e173\"; } }\n.glyphicon-floppy-remove { &:before { content: \"\\e174\"; } }\n.glyphicon-floppy-save { &:before { content: \"\\e175\"; } }\n.glyphicon-floppy-open { &:before { content: \"\\e176\"; } }\n.glyphicon-credit-card { &:before { content: \"\\e177\"; } }\n.glyphicon-transfer { &:before { content: \"\\e178\"; } }\n.glyphicon-cutlery { &:before { content: \"\\e179\"; } }\n.glyphicon-header { &:before { content: \"\\e180\"; } }\n.glyphicon-compressed { &:before { content: \"\\e181\"; } }\n.glyphicon-earphone { &:before { content: \"\\e182\"; } }\n.glyphicon-phone-alt { &:before { content: \"\\e183\"; } }\n.glyphicon-tower { &:before { content: \"\\e184\"; } }\n.glyphicon-stats { &:before { content: \"\\e185\"; } }\n.glyphicon-sd-video { &:before { content: \"\\e186\"; } }\n.glyphicon-hd-video { &:before { content: \"\\e187\"; } }\n.glyphicon-subtitles { &:before { content: \"\\e188\"; } }\n.glyphicon-sound-stereo { &:before { content: \"\\e189\"; } }\n.glyphicon-sound-dolby { &:before { content: \"\\e190\"; } }\n.glyphicon-sound-5-1 { &:before { content: \"\\e191\"; } }\n.glyphicon-sound-6-1 { &:before { content: \"\\e192\"; } }\n.glyphicon-sound-7-1 { &:before { content: \"\\e193\"; } }\n.glyphicon-copyright-mark { &:before { content: \"\\e194\"; } }\n.glyphicon-registration-mark { &:before { content: \"\\e195\"; } }\n.glyphicon-cloud-download { &:before { content: \"\\e197\"; } }\n.glyphicon-cloud-upload { &:before { content: \"\\e198\"; } }\n.glyphicon-tree-conifer { &:before { content: \"\\e199\"; } }\n.glyphicon-tree-deciduous { &:before { content: \"\\e200\"; } }\n.glyphicon-cd { &:before { content: \"\\e201\"; } }\n.glyphicon-save-file { &:before { content: \"\\e202\"; } }\n.glyphicon-open-file { &:before { content: \"\\e203\"; } }\n.glyphicon-level-up { &:before { content: \"\\e204\"; } }\n.glyphicon-copy { &:before { content: \"\\e205\"; } }\n.glyphicon-paste { &:before { content: \"\\e206\"; } }\n// The following 2 Glyphicons are omitted for the time being because\n// they currently use Unicode codepoints that are outside the\n// Basic Multilingual Plane (BMP). Older buggy versions of WebKit can't handle\n// non-BMP codepoints in CSS string escapes, and thus can't display these two icons.\n// Notably, the bug affects some older versions of the Android Browser.\n// More info: https://github.com/twbs/bootstrap/issues/10106\n// .glyphicon-door { &:before { content: \"\\1f6aa\"; } }\n// .glyphicon-key { &:before { content: \"\\1f511\"; } }\n.glyphicon-alert { &:before { content: \"\\e209\"; } }\n.glyphicon-equalizer { &:before { content: \"\\e210\"; } }\n.glyphicon-king { &:before { content: \"\\e211\"; } }\n.glyphicon-queen { &:before { content: \"\\e212\"; } }\n.glyphicon-pawn { &:before { content: \"\\e213\"; } }\n.glyphicon-bishop { &:before { content: \"\\e214\"; } }\n.glyphicon-knight { &:before { content: \"\\e215\"; } }\n.glyphicon-baby-formula { &:before { content: \"\\e216\"; } }\n.glyphicon-tent { &:before { content: \"\\26fa\"; } }\n.glyphicon-blackboard { &:before { content: \"\\e218\"; } }\n.glyphicon-bed { &:before { content: \"\\e219\"; } }\n.glyphicon-apple { &:before { content: \"\\f8ff\"; } }\n.glyphicon-erase { &:before { content: \"\\e221\"; } }\n.glyphicon-hourglass { &:before { content: \"\\231b\"; } }\n.glyphicon-lamp { &:before { content: \"\\e223\"; } }\n.glyphicon-duplicate { &:before { content: \"\\e224\"; } }\n.glyphicon-piggy-bank { &:before { content: \"\\e225\"; } }\n.glyphicon-scissors { &:before { content: \"\\e226\"; } }\n.glyphicon-bitcoin { &:before { content: \"\\e227\"; } }\n.glyphicon-yen { &:before { content: \"\\00a5\"; } }\n.glyphicon-ruble { &:before { content: \"\\20bd\"; } }\n.glyphicon-scale { &:before { content: \"\\e230\"; } }\n.glyphicon-ice-lolly { &:before { content: \"\\e231\"; } }\n.glyphicon-ice-lolly-tasted { &:before { content: \"\\e232\"; } }\n.glyphicon-education { &:before { content: \"\\e233\"; } }\n.glyphicon-option-horizontal { &:before { content: \"\\e234\"; } }\n.glyphicon-option-vertical { &:before { content: \"\\e235\"; } }\n.glyphicon-menu-hamburger { &:before { content: \"\\e236\"; } }\n.glyphicon-modal-window { &:before { content: \"\\e237\"; } }\n.glyphicon-oil { &:before { content: \"\\e238\"; } }\n.glyphicon-grain { &:before { content: \"\\e239\"; } }\n.glyphicon-sunglasses { &:before { content: \"\\e240\"; } }\n.glyphicon-text-size { &:before { content: \"\\e241\"; } }\n.glyphicon-text-color { &:before { content: \"\\e242\"; } }\n.glyphicon-text-background { &:before { content: \"\\e243\"; } }\n.glyphicon-object-align-top { &:before { content: \"\\e244\"; } }\n.glyphicon-object-align-bottom { &:before { content: \"\\e245\"; } }\n.glyphicon-object-align-horizontal{ &:before { content: \"\\e246\"; } }\n.glyphicon-object-align-left { &:before { content: \"\\e247\"; } }\n.glyphicon-object-align-vertical { &:before { content: \"\\e248\"; } }\n.glyphicon-object-align-right { &:before { content: \"\\e249\"; } }\n.glyphicon-triangle-right { &:before { content: \"\\e250\"; } }\n.glyphicon-triangle-left { &:before { content: \"\\e251\"; } }\n.glyphicon-triangle-bottom { &:before { content: \"\\e252\"; } }\n.glyphicon-triangle-top { &:before { content: \"\\e253\"; } }\n.glyphicon-console { &:before { content: \"\\e254\"; } }\n.glyphicon-superscript { &:before { content: \"\\e255\"; } }\n.glyphicon-subscript { &:before { content: \"\\e256\"; } }\n.glyphicon-menu-left { &:before { content: \"\\e257\"; } }\n.glyphicon-menu-right { &:before { content: \"\\e258\"; } }\n.glyphicon-menu-down { &:before { content: \"\\e259\"; } }\n.glyphicon-menu-up { &:before { content: \"\\e260\"; } }\n","//\n// Scaffolding\n// --------------------------------------------------\n\n\n// Reset the box-sizing\n//\n// Heads up! This reset may cause conflicts with some third-party widgets.\n// For recommendations on resolving such conflicts, see\n// http://getbootstrap.com/getting-started/#third-box-sizing\n* {\n .box-sizing(border-box);\n}\n*:before,\n*:after {\n .box-sizing(border-box);\n}\n\n\n// Body reset\n\nhtml {\n font-size: 10px;\n -webkit-tap-highlight-color: rgba(0,0,0,0);\n}\n\nbody {\n font-family: @font-family-base;\n font-size: @font-size-base;\n line-height: @line-height-base;\n color: @text-color;\n background-color: @body-bg;\n}\n\n// Reset fonts for relevant elements\ninput,\nbutton,\nselect,\ntextarea {\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\n\n// Links\n\na {\n color: @link-color;\n text-decoration: none;\n\n &:hover,\n &:focus {\n color: @link-hover-color;\n text-decoration: @link-hover-decoration;\n }\n\n &:focus {\n .tab-focus();\n }\n}\n\n\n// Figures\n//\n// We reset this here because previously Normalize had no `figure` margins. This\n// ensures we don't break anyone's use of the element.\n\nfigure {\n margin: 0;\n}\n\n\n// Images\n\nimg {\n vertical-align: middle;\n}\n\n// Responsive images (ensure images don't scale beyond their parents)\n.img-responsive {\n .img-responsive();\n}\n\n// Rounded corners\n.img-rounded {\n border-radius: @border-radius-large;\n}\n\n// Image thumbnails\n//\n// Heads up! This is mixin-ed into thumbnails.less for `.thumbnail`.\n.img-thumbnail {\n padding: @thumbnail-padding;\n line-height: @line-height-base;\n background-color: @thumbnail-bg;\n border: 1px solid @thumbnail-border;\n border-radius: @thumbnail-border-radius;\n .transition(all .2s ease-in-out);\n\n // Keep them at most 100% wide\n .img-responsive(inline-block);\n}\n\n// Perfect circle\n.img-circle {\n border-radius: 50%; // set radius in percents\n}\n\n\n// Horizontal rules\n\nhr {\n margin-top: @line-height-computed;\n margin-bottom: @line-height-computed;\n border: 0;\n border-top: 1px solid @hr-border;\n}\n\n\n// Only display content to screen readers\n//\n// See: http://a11yproject.com/posts/how-to-hide-content/\n\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0,0,0,0);\n border: 0;\n}\n\n// Use in conjunction with .sr-only to only display content when it's focused.\n// Useful for \"Skip to main content\" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1\n// Credit: HTML5 Boilerplate\n\n.sr-only-focusable {\n &:active,\n &:focus {\n position: static;\n width: auto;\n height: auto;\n margin: 0;\n overflow: visible;\n clip: auto;\n }\n}\n","// Vendor Prefixes\n//\n// All vendor mixins are deprecated as of v3.2.0 due to the introduction of\n// Autoprefixer in our Gruntfile. They will be removed in v4.\n\n// - Animations\n// - Backface visibility\n// - Box shadow\n// - Box sizing\n// - Content columns\n// - Hyphens\n// - Placeholder text\n// - Transformations\n// - Transitions\n// - User Select\n\n\n// Animations\n.animation(@animation) {\n -webkit-animation: @animation;\n -o-animation: @animation;\n animation: @animation;\n}\n.animation-name(@name) {\n -webkit-animation-name: @name;\n animation-name: @name;\n}\n.animation-duration(@duration) {\n -webkit-animation-duration: @duration;\n animation-duration: @duration;\n}\n.animation-timing-function(@timing-function) {\n -webkit-animation-timing-function: @timing-function;\n animation-timing-function: @timing-function;\n}\n.animation-delay(@delay) {\n -webkit-animation-delay: @delay;\n animation-delay: @delay;\n}\n.animation-iteration-count(@iteration-count) {\n -webkit-animation-iteration-count: @iteration-count;\n animation-iteration-count: @iteration-count;\n}\n.animation-direction(@direction) {\n -webkit-animation-direction: @direction;\n animation-direction: @direction;\n}\n.animation-fill-mode(@fill-mode) {\n -webkit-animation-fill-mode: @fill-mode;\n animation-fill-mode: @fill-mode;\n}\n\n// Backface visibility\n// Prevent browsers from flickering when using CSS 3D transforms.\n// Default value is `visible`, but can be changed to `hidden`\n\n.backface-visibility(@visibility){\n -webkit-backface-visibility: @visibility;\n -moz-backface-visibility: @visibility;\n backface-visibility: @visibility;\n}\n\n// Drop shadows\n//\n// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's\n// supported browsers that have box shadow capabilities now support it.\n\n.box-shadow(@shadow) {\n -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n box-shadow: @shadow;\n}\n\n// Box sizing\n.box-sizing(@boxmodel) {\n -webkit-box-sizing: @boxmodel;\n -moz-box-sizing: @boxmodel;\n box-sizing: @boxmodel;\n}\n\n// CSS3 Content Columns\n.content-columns(@column-count; @column-gap: @grid-gutter-width) {\n -webkit-column-count: @column-count;\n -moz-column-count: @column-count;\n column-count: @column-count;\n -webkit-column-gap: @column-gap;\n -moz-column-gap: @column-gap;\n column-gap: @column-gap;\n}\n\n// Optional hyphenation\n.hyphens(@mode: auto) {\n word-wrap: break-word;\n -webkit-hyphens: @mode;\n -moz-hyphens: @mode;\n -ms-hyphens: @mode; // IE10+\n -o-hyphens: @mode;\n hyphens: @mode;\n}\n\n// Placeholder text\n.placeholder(@color: @input-color-placeholder) {\n // Firefox\n &::-moz-placeholder {\n color: @color;\n opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526\n }\n &:-ms-input-placeholder { color: @color; } // Internet Explorer 10+\n &::-webkit-input-placeholder { color: @color; } // Safari and Chrome\n}\n\n// Transformations\n.scale(@ratio) {\n -webkit-transform: scale(@ratio);\n -ms-transform: scale(@ratio); // IE9 only\n -o-transform: scale(@ratio);\n transform: scale(@ratio);\n}\n.scale(@ratioX; @ratioY) {\n -webkit-transform: scale(@ratioX, @ratioY);\n -ms-transform: scale(@ratioX, @ratioY); // IE9 only\n -o-transform: scale(@ratioX, @ratioY);\n transform: scale(@ratioX, @ratioY);\n}\n.scaleX(@ratio) {\n -webkit-transform: scaleX(@ratio);\n -ms-transform: scaleX(@ratio); // IE9 only\n -o-transform: scaleX(@ratio);\n transform: scaleX(@ratio);\n}\n.scaleY(@ratio) {\n -webkit-transform: scaleY(@ratio);\n -ms-transform: scaleY(@ratio); // IE9 only\n -o-transform: scaleY(@ratio);\n transform: scaleY(@ratio);\n}\n.skew(@x; @y) {\n -webkit-transform: skewX(@x) skewY(@y);\n -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+\n -o-transform: skewX(@x) skewY(@y);\n transform: skewX(@x) skewY(@y);\n}\n.translate(@x; @y) {\n -webkit-transform: translate(@x, @y);\n -ms-transform: translate(@x, @y); // IE9 only\n -o-transform: translate(@x, @y);\n transform: translate(@x, @y);\n}\n.translate3d(@x; @y; @z) {\n -webkit-transform: translate3d(@x, @y, @z);\n transform: translate3d(@x, @y, @z);\n}\n.rotate(@degrees) {\n -webkit-transform: rotate(@degrees);\n -ms-transform: rotate(@degrees); // IE9 only\n -o-transform: rotate(@degrees);\n transform: rotate(@degrees);\n}\n.rotateX(@degrees) {\n -webkit-transform: rotateX(@degrees);\n -ms-transform: rotateX(@degrees); // IE9 only\n -o-transform: rotateX(@degrees);\n transform: rotateX(@degrees);\n}\n.rotateY(@degrees) {\n -webkit-transform: rotateY(@degrees);\n -ms-transform: rotateY(@degrees); // IE9 only\n -o-transform: rotateY(@degrees);\n transform: rotateY(@degrees);\n}\n.perspective(@perspective) {\n -webkit-perspective: @perspective;\n -moz-perspective: @perspective;\n perspective: @perspective;\n}\n.perspective-origin(@perspective) {\n -webkit-perspective-origin: @perspective;\n -moz-perspective-origin: @perspective;\n perspective-origin: @perspective;\n}\n.transform-origin(@origin) {\n -webkit-transform-origin: @origin;\n -moz-transform-origin: @origin;\n -ms-transform-origin: @origin; // IE9 only\n transform-origin: @origin;\n}\n\n\n// Transitions\n\n.transition(@transition) {\n -webkit-transition: @transition;\n -o-transition: @transition;\n transition: @transition;\n}\n.transition-property(@transition-property) {\n -webkit-transition-property: @transition-property;\n transition-property: @transition-property;\n}\n.transition-delay(@transition-delay) {\n -webkit-transition-delay: @transition-delay;\n transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n -webkit-transition-duration: @transition-duration;\n transition-duration: @transition-duration;\n}\n.transition-timing-function(@timing-function) {\n -webkit-transition-timing-function: @timing-function;\n transition-timing-function: @timing-function;\n}\n.transition-transform(@transition) {\n -webkit-transition: -webkit-transform @transition;\n -moz-transition: -moz-transform @transition;\n -o-transition: -o-transform @transition;\n transition: transform @transition;\n}\n\n\n// User select\n// For selecting text on the page\n\n.user-select(@select) {\n -webkit-user-select: @select;\n -moz-user-select: @select;\n -ms-user-select: @select; // IE10+\n user-select: @select;\n}\n","// WebKit-style focus\n\n.tab-focus() {\n // Default\n outline: thin dotted;\n // WebKit\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\n","// Image Mixins\n// - Responsive image\n// - Retina image\n\n\n// Responsive image\n//\n// Keep images from scaling beyond the width of their parents.\n.img-responsive(@display: block) {\n display: @display;\n max-width: 100%; // Part 1: Set a maximum relative to the parent\n height: auto; // Part 2: Scale the height according to the width, otherwise you get stretching\n}\n\n\n// Retina image\n//\n// Short retina mixin for setting background-image and -size. Note that the\n// spelling of `min--moz-device-pixel-ratio` is intentional.\n.img-retina(@file-1x; @file-2x; @width-1x; @height-1x) {\n background-image: url(\"@{file-1x}\");\n\n @media\n only screen and (-webkit-min-device-pixel-ratio: 2),\n only screen and ( min--moz-device-pixel-ratio: 2),\n only screen and ( -o-min-device-pixel-ratio: 2/1),\n only screen and ( min-device-pixel-ratio: 2),\n only screen and ( min-resolution: 192dpi),\n only screen and ( min-resolution: 2dppx) {\n background-image: url(\"@{file-2x}\");\n background-size: @width-1x @height-1x;\n }\n}\n","//\n// Typography\n// --------------------------------------------------\n\n\n// Headings\n// -------------------------\n\nh1, h2, h3, h4, h5, h6,\n.h1, .h2, .h3, .h4, .h5, .h6 {\n font-family: @headings-font-family;\n font-weight: @headings-font-weight;\n line-height: @headings-line-height;\n color: @headings-color;\n\n small,\n .small {\n font-weight: normal;\n line-height: 1;\n color: @headings-small-color;\n }\n}\n\nh1, .h1,\nh2, .h2,\nh3, .h3 {\n margin-top: @line-height-computed;\n margin-bottom: (@line-height-computed / 2);\n\n small,\n .small {\n font-size: 65%;\n }\n}\nh4, .h4,\nh5, .h5,\nh6, .h6 {\n margin-top: (@line-height-computed / 2);\n margin-bottom: (@line-height-computed / 2);\n\n small,\n .small {\n font-size: 75%;\n }\n}\n\nh1, .h1 { font-size: @font-size-h1; }\nh2, .h2 { font-size: @font-size-h2; }\nh3, .h3 { font-size: @font-size-h3; }\nh4, .h4 { font-size: @font-size-h4; }\nh5, .h5 { font-size: @font-size-h5; }\nh6, .h6 { font-size: @font-size-h6; }\n\n\n// Body text\n// -------------------------\n\np {\n margin: 0 0 (@line-height-computed / 2);\n}\n\n.lead {\n margin-bottom: @line-height-computed;\n font-size: floor((@font-size-base * 1.15));\n font-weight: 300;\n line-height: 1.4;\n\n @media (min-width: @screen-sm-min) {\n font-size: (@font-size-base * 1.5);\n }\n}\n\n\n// Emphasis & misc\n// -------------------------\n\n// Ex: (12px small font / 14px base font) * 100% = about 85%\nsmall,\n.small {\n font-size: floor((100% * @font-size-small / @font-size-base));\n}\n\nmark,\n.mark {\n background-color: @state-warning-bg;\n padding: .2em;\n}\n\n// Alignment\n.text-left { text-align: left; }\n.text-right { text-align: right; }\n.text-center { text-align: center; }\n.text-justify { text-align: justify; }\n.text-nowrap { white-space: nowrap; }\n\n// Transformation\n.text-lowercase { text-transform: lowercase; }\n.text-uppercase { text-transform: uppercase; }\n.text-capitalize { text-transform: capitalize; }\n\n// Contextual colors\n.text-muted {\n color: @text-muted;\n}\n.text-primary {\n .text-emphasis-variant(@brand-primary);\n}\n.text-success {\n .text-emphasis-variant(@state-success-text);\n}\n.text-info {\n .text-emphasis-variant(@state-info-text);\n}\n.text-warning {\n .text-emphasis-variant(@state-warning-text);\n}\n.text-danger {\n .text-emphasis-variant(@state-danger-text);\n}\n\n// Contextual backgrounds\n// For now we'll leave these alongside the text classes until v4 when we can\n// safely shift things around (per SemVer rules).\n.bg-primary {\n // Given the contrast here, this is the only class to have its color inverted\n // automatically.\n color: #fff;\n .bg-variant(@brand-primary);\n}\n.bg-success {\n .bg-variant(@state-success-bg);\n}\n.bg-info {\n .bg-variant(@state-info-bg);\n}\n.bg-warning {\n .bg-variant(@state-warning-bg);\n}\n.bg-danger {\n .bg-variant(@state-danger-bg);\n}\n\n\n// Page header\n// -------------------------\n\n.page-header {\n padding-bottom: ((@line-height-computed / 2) - 1);\n margin: (@line-height-computed * 2) 0 @line-height-computed;\n border-bottom: 1px solid @page-header-border-color;\n}\n\n\n// Lists\n// -------------------------\n\n// Unordered and Ordered lists\nul,\nol {\n margin-top: 0;\n margin-bottom: (@line-height-computed / 2);\n ul,\n ol {\n margin-bottom: 0;\n }\n}\n\n// List options\n\n// Unstyled keeps list items block level, just removes default browser padding and list-style\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n\n// Inline turns list items into inline-block\n.list-inline {\n .list-unstyled();\n margin-left: -5px;\n\n > li {\n display: inline-block;\n padding-left: 5px;\n padding-right: 5px;\n }\n}\n\n// Description Lists\ndl {\n margin-top: 0; // Remove browser default\n margin-bottom: @line-height-computed;\n}\ndt,\ndd {\n line-height: @line-height-base;\n}\ndt {\n font-weight: bold;\n}\ndd {\n margin-left: 0; // Undo browser default\n}\n\n// Horizontal description lists\n//\n// Defaults to being stacked without any of the below styles applied, until the\n// grid breakpoint is reached (default of ~768px).\n\n.dl-horizontal {\n dd {\n &:extend(.clearfix all); // Clear the floated `dt` if an empty `dd` is present\n }\n\n @media (min-width: @grid-float-breakpoint) {\n dt {\n float: left;\n width: (@dl-horizontal-offset - 20);\n clear: left;\n text-align: right;\n .text-overflow();\n }\n dd {\n margin-left: @dl-horizontal-offset;\n }\n }\n}\n\n\n// Misc\n// -------------------------\n\n// Abbreviations and acronyms\nabbr[title],\n// Add data-* attribute to help out our tooltip plugin, per https://github.com/twbs/bootstrap/issues/5257\nabbr[data-original-title] {\n cursor: help;\n border-bottom: 1px dotted @abbr-border-color;\n}\n.initialism {\n font-size: 90%;\n text-transform: uppercase;\n}\n\n// Blockquotes\nblockquote {\n padding: (@line-height-computed / 2) @line-height-computed;\n margin: 0 0 @line-height-computed;\n font-size: @blockquote-font-size;\n border-left: 5px solid @blockquote-border-color;\n\n p,\n ul,\n ol {\n &:last-child {\n margin-bottom: 0;\n }\n }\n\n // Note: Deprecated small and .small as of v3.1.0\n // Context: https://github.com/twbs/bootstrap/issues/11660\n footer,\n small,\n .small {\n display: block;\n font-size: 80%; // back to default font-size\n line-height: @line-height-base;\n color: @blockquote-small-color;\n\n &:before {\n content: '\\2014 \\00A0'; // em dash, nbsp\n }\n }\n}\n\n// Opposite alignment of blockquote\n//\n// Heads up: `blockquote.pull-right` has been deprecated as of v3.1.0.\n.blockquote-reverse,\nblockquote.pull-right {\n padding-right: 15px;\n padding-left: 0;\n border-right: 5px solid @blockquote-border-color;\n border-left: 0;\n text-align: right;\n\n // Account for citation\n footer,\n small,\n .small {\n &:before { content: ''; }\n &:after {\n content: '\\00A0 \\2014'; // nbsp, em dash\n }\n }\n}\n\n// Addresses\naddress {\n margin-bottom: @line-height-computed;\n font-style: normal;\n line-height: @line-height-base;\n}\n","// Typography\n\n.text-emphasis-variant(@color) {\n color: @color;\n a&:hover {\n color: darken(@color, 10%);\n }\n}\n","// Contextual backgrounds\n\n.bg-variant(@color) {\n background-color: @color;\n a&:hover {\n background-color: darken(@color, 10%);\n }\n}\n","// Text overflow\n// Requires inline-block or block for proper styling\n\n.text-overflow() {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n","//\n// Code (inline and block)\n// --------------------------------------------------\n\n\n// Inline and block code styles\ncode,\nkbd,\npre,\nsamp {\n font-family: @font-family-monospace;\n}\n\n// Inline code\ncode {\n padding: 2px 4px;\n font-size: 90%;\n color: @code-color;\n background-color: @code-bg;\n border-radius: @border-radius-base;\n}\n\n// User input typically entered via keyboard\nkbd {\n padding: 2px 4px;\n font-size: 90%;\n color: @kbd-color;\n background-color: @kbd-bg;\n border-radius: @border-radius-small;\n box-shadow: inset 0 -1px 0 rgba(0,0,0,.25);\n\n kbd {\n padding: 0;\n font-size: 100%;\n font-weight: bold;\n box-shadow: none;\n }\n}\n\n// Blocks of code\npre {\n display: block;\n padding: ((@line-height-computed - 1) / 2);\n margin: 0 0 (@line-height-computed / 2);\n font-size: (@font-size-base - 1); // 14px to 13px\n line-height: @line-height-base;\n word-break: break-all;\n word-wrap: break-word;\n color: @pre-color;\n background-color: @pre-bg;\n border: 1px solid @pre-border-color;\n border-radius: @border-radius-base;\n\n // Account for some code outputs that place code tags in pre tags\n code {\n padding: 0;\n font-size: inherit;\n color: inherit;\n white-space: pre-wrap;\n background-color: transparent;\n border-radius: 0;\n }\n}\n\n// Enable scrollable blocks of code\n.pre-scrollable {\n max-height: @pre-scrollable-max-height;\n overflow-y: scroll;\n}\n","//\n// Grid system\n// --------------------------------------------------\n\n\n// Container widths\n//\n// Set the container width, and override it for fixed navbars in media queries.\n\n.container {\n .container-fixed();\n\n @media (min-width: @screen-sm-min) {\n width: @container-sm;\n }\n @media (min-width: @screen-md-min) {\n width: @container-md;\n }\n @media (min-width: @screen-lg-min) {\n width: @container-lg;\n }\n}\n\n\n// Fluid container\n//\n// Utilizes the mixin meant for fixed width containers, but without any defined\n// width for fluid, full width layouts.\n\n.container-fluid {\n .container-fixed();\n}\n\n\n// Row\n//\n// Rows contain and clear the floats of your columns.\n\n.row {\n .make-row();\n}\n\n\n// Columns\n//\n// Common styles for small and large grid columns\n\n.make-grid-columns();\n\n\n// Extra small grid\n//\n// Columns, offsets, pushes, and pulls for extra small devices like\n// smartphones.\n\n.make-grid(xs);\n\n\n// Small grid\n//\n// Columns, offsets, pushes, and pulls for the small device range, from phones\n// to tablets.\n\n@media (min-width: @screen-sm-min) {\n .make-grid(sm);\n}\n\n\n// Medium grid\n//\n// Columns, offsets, pushes, and pulls for the desktop device range.\n\n@media (min-width: @screen-md-min) {\n .make-grid(md);\n}\n\n\n// Large grid\n//\n// Columns, offsets, pushes, and pulls for the large desktop device range.\n\n@media (min-width: @screen-lg-min) {\n .make-grid(lg);\n}\n","// Grid system\n//\n// Generate semantic grid columns with these mixins.\n\n// Centered container element\n.container-fixed(@gutter: @grid-gutter-width) {\n margin-right: auto;\n margin-left: auto;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n &:extend(.clearfix all);\n}\n\n// Creates a wrapper for a series of columns\n.make-row(@gutter: @grid-gutter-width) {\n margin-left: (@gutter / -2);\n margin-right: (@gutter / -2);\n &:extend(.clearfix all);\n}\n\n// Generate the extra small columns\n.make-xs-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n float: left;\n width: percentage((@columns / @grid-columns));\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n}\n.make-xs-column-offset(@columns) {\n margin-left: percentage((@columns / @grid-columns));\n}\n.make-xs-column-push(@columns) {\n left: percentage((@columns / @grid-columns));\n}\n.make-xs-column-pull(@columns) {\n right: percentage((@columns / @grid-columns));\n}\n\n// Generate the small columns\n.make-sm-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n @media (min-width: @screen-sm-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-offset(@columns) {\n @media (min-width: @screen-sm-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-push(@columns) {\n @media (min-width: @screen-sm-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-pull(@columns) {\n @media (min-width: @screen-sm-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n\n// Generate the medium columns\n.make-md-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n @media (min-width: @screen-md-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-offset(@columns) {\n @media (min-width: @screen-md-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-push(@columns) {\n @media (min-width: @screen-md-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-pull(@columns) {\n @media (min-width: @screen-md-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n\n// Generate the large columns\n.make-lg-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n @media (min-width: @screen-lg-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-offset(@columns) {\n @media (min-width: @screen-lg-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-push(@columns) {\n @media (min-width: @screen-lg-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-pull(@columns) {\n @media (min-width: @screen-lg-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n","// Framework grid generation\n//\n// Used only by Bootstrap to generate the correct number of grid classes given\n// any value of `@grid-columns`.\n\n.make-grid-columns() {\n // Common styles for all sizes of grid columns, widths 1-12\n .col(@index) { // initial\n @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n .col((@index + 1), @item);\n }\n .col(@index, @list) when (@index =< @grid-columns) { // general; \"=<\" isn't a typo\n @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n .col((@index + 1), ~\"@{list}, @{item}\");\n }\n .col(@index, @list) when (@index > @grid-columns) { // terminal\n @{list} {\n position: relative;\n // Prevent columns from collapsing when empty\n min-height: 1px;\n // Inner gutter via padding\n padding-left: (@grid-gutter-width / 2);\n padding-right: (@grid-gutter-width / 2);\n }\n }\n .col(1); // kickstart it\n}\n\n.float-grid-columns(@class) {\n .col(@index) { // initial\n @item: ~\".col-@{class}-@{index}\";\n .col((@index + 1), @item);\n }\n .col(@index, @list) when (@index =< @grid-columns) { // general\n @item: ~\".col-@{class}-@{index}\";\n .col((@index + 1), ~\"@{list}, @{item}\");\n }\n .col(@index, @list) when (@index > @grid-columns) { // terminal\n @{list} {\n float: left;\n }\n }\n .col(1); // kickstart it\n}\n\n.calc-grid-column(@index, @class, @type) when (@type = width) and (@index > 0) {\n .col-@{class}-@{index} {\n width: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = push) and (@index > 0) {\n .col-@{class}-push-@{index} {\n left: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = push) and (@index = 0) {\n .col-@{class}-push-0 {\n left: auto;\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index > 0) {\n .col-@{class}-pull-@{index} {\n right: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index = 0) {\n .col-@{class}-pull-0 {\n right: auto;\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = offset) {\n .col-@{class}-offset-@{index} {\n margin-left: percentage((@index / @grid-columns));\n }\n}\n\n// Basic looping in LESS\n.loop-grid-columns(@index, @class, @type) when (@index >= 0) {\n .calc-grid-column(@index, @class, @type);\n // next iteration\n .loop-grid-columns((@index - 1), @class, @type);\n}\n\n// Create grid for specific class\n.make-grid(@class) {\n .float-grid-columns(@class);\n .loop-grid-columns(@grid-columns, @class, width);\n .loop-grid-columns(@grid-columns, @class, pull);\n .loop-grid-columns(@grid-columns, @class, push);\n .loop-grid-columns(@grid-columns, @class, offset);\n}\n","//\n// Tables\n// --------------------------------------------------\n\n\ntable {\n background-color: @table-bg;\n}\ncaption {\n padding-top: @table-cell-padding;\n padding-bottom: @table-cell-padding;\n color: @text-muted;\n text-align: left;\n}\nth {\n text-align: left;\n}\n\n\n// Baseline styles\n\n.table {\n width: 100%;\n max-width: 100%;\n margin-bottom: @line-height-computed;\n // Cells\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n padding: @table-cell-padding;\n line-height: @line-height-base;\n vertical-align: top;\n border-top: 1px solid @table-border-color;\n }\n }\n }\n // Bottom align for column headings\n > thead > tr > th {\n vertical-align: bottom;\n border-bottom: 2px solid @table-border-color;\n }\n // Remove top border from thead by default\n > caption + thead,\n > colgroup + thead,\n > thead:first-child {\n > tr:first-child {\n > th,\n > td {\n border-top: 0;\n }\n }\n }\n // Account for multiple tbody instances\n > tbody + tbody {\n border-top: 2px solid @table-border-color;\n }\n\n // Nesting\n .table {\n background-color: @body-bg;\n }\n}\n\n\n// Condensed table w/ half padding\n\n.table-condensed {\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n padding: @table-condensed-cell-padding;\n }\n }\n }\n}\n\n\n// Bordered version\n//\n// Add borders all around the table and between all the columns.\n\n.table-bordered {\n border: 1px solid @table-border-color;\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n border: 1px solid @table-border-color;\n }\n }\n }\n > thead > tr {\n > th,\n > td {\n border-bottom-width: 2px;\n }\n }\n}\n\n\n// Zebra-striping\n//\n// Default zebra-stripe styles (alternating gray and transparent backgrounds)\n\n.table-striped {\n > tbody > tr:nth-of-type(odd) {\n background-color: @table-bg-accent;\n }\n}\n\n\n// Hover effect\n//\n// Placed here since it has to come after the potential zebra striping\n\n.table-hover {\n > tbody > tr:hover {\n background-color: @table-bg-hover;\n }\n}\n\n\n// Table cell sizing\n//\n// Reset default table behavior\n\ntable col[class*=\"col-\"] {\n position: static; // Prevent border hiding in Firefox and IE9-11 (see https://github.com/twbs/bootstrap/issues/11623)\n float: none;\n display: table-column;\n}\ntable {\n td,\n th {\n &[class*=\"col-\"] {\n position: static; // Prevent border hiding in Firefox and IE9-11 (see https://github.com/twbs/bootstrap/issues/11623)\n float: none;\n display: table-cell;\n }\n }\n}\n\n\n// Table backgrounds\n//\n// Exact selectors below required to override `.table-striped` and prevent\n// inheritance to nested tables.\n\n// Generate the contextual variants\n.table-row-variant(active; @table-bg-active);\n.table-row-variant(success; @state-success-bg);\n.table-row-variant(info; @state-info-bg);\n.table-row-variant(warning; @state-warning-bg);\n.table-row-variant(danger; @state-danger-bg);\n\n\n// Responsive tables\n//\n// Wrap your tables in `.table-responsive` and we'll make them mobile friendly\n// by enabling horizontal scrolling. Only applies <768px. Everything above that\n// will display normally.\n\n.table-responsive {\n overflow-x: auto;\n min-height: 0.01%; // Workaround for IE9 bug (see https://github.com/twbs/bootstrap/issues/14837)\n\n @media screen and (max-width: @screen-xs-max) {\n width: 100%;\n margin-bottom: (@line-height-computed * 0.75);\n overflow-y: hidden;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n border: 1px solid @table-border-color;\n\n // Tighten up spacing\n > .table {\n margin-bottom: 0;\n\n // Ensure the content doesn't wrap\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n white-space: nowrap;\n }\n }\n }\n }\n\n // Special overrides for the bordered tables\n > .table-bordered {\n border: 0;\n\n // Nuke the appropriate borders so that the parent can handle them\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th:first-child,\n > td:first-child {\n border-left: 0;\n }\n > th:last-child,\n > td:last-child {\n border-right: 0;\n }\n }\n }\n\n // Only nuke the last row's bottom-border in `tbody` and `tfoot` since\n // chances are there will be only one `tr` in a `thead` and that would\n // remove the border altogether.\n > tbody,\n > tfoot {\n > tr:last-child {\n > th,\n > td {\n border-bottom: 0;\n }\n }\n }\n\n }\n }\n}\n","// Tables\n\n.table-row-variant(@state; @background) {\n // Exact selectors below required to override `.table-striped` and prevent\n // inheritance to nested tables.\n .table > thead > tr,\n .table > tbody > tr,\n .table > tfoot > tr {\n > td.@{state},\n > th.@{state},\n &.@{state} > td,\n &.@{state} > th {\n background-color: @background;\n }\n }\n\n // Hover states for `.table-hover`\n // Note: this is not available for cells or rows within `thead` or `tfoot`.\n .table-hover > tbody > tr {\n > td.@{state}:hover,\n > th.@{state}:hover,\n &.@{state}:hover > td,\n &:hover > .@{state},\n &.@{state}:hover > th {\n background-color: darken(@background, 5%);\n }\n }\n}\n","//\n// Forms\n// --------------------------------------------------\n\n\n// Normalize non-controls\n//\n// Restyle and baseline non-control form elements.\n\nfieldset {\n padding: 0;\n margin: 0;\n border: 0;\n // Chrome and Firefox set a `min-width: min-content;` on fieldsets,\n // so we reset that to ensure it behaves more like a standard block element.\n // See https://github.com/twbs/bootstrap/issues/12359.\n min-width: 0;\n}\n\nlegend {\n display: block;\n width: 100%;\n padding: 0;\n margin-bottom: @line-height-computed;\n font-size: (@font-size-base * 1.5);\n line-height: inherit;\n color: @legend-color;\n border: 0;\n border-bottom: 1px solid @legend-border-color;\n}\n\nlabel {\n display: inline-block;\n max-width: 100%; // Force IE8 to wrap long content (see https://github.com/twbs/bootstrap/issues/13141)\n margin-bottom: 5px;\n font-weight: bold;\n}\n\n\n// Normalize form controls\n//\n// While most of our form styles require extra classes, some basic normalization\n// is required to ensure optimum display with or without those classes to better\n// address browser inconsistencies.\n\n// Override content-box in Normalize (* isn't specific enough)\ninput[type=\"search\"] {\n .box-sizing(border-box);\n}\n\n// Position radios and checkboxes better\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n margin: 4px 0 0;\n margin-top: 1px \\9; // IE8-9\n line-height: normal;\n}\n\n// Set the height of file controls to match text inputs\ninput[type=\"file\"] {\n display: block;\n}\n\n// Make range inputs behave like textual form controls\ninput[type=\"range\"] {\n display: block;\n width: 100%;\n}\n\n// Make multiple select elements height not fixed\nselect[multiple],\nselect[size] {\n height: auto;\n}\n\n// Focus for file, radio, and checkbox\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n .tab-focus();\n}\n\n// Adjust output element\noutput {\n display: block;\n padding-top: (@padding-base-vertical + 1);\n font-size: @font-size-base;\n line-height: @line-height-base;\n color: @input-color;\n}\n\n\n// Common form controls\n//\n// Shared size and type resets for form controls. Apply `.form-control` to any\n// of the following form controls:\n//\n// select\n// textarea\n// input[type=\"text\"]\n// input[type=\"password\"]\n// input[type=\"datetime\"]\n// input[type=\"datetime-local\"]\n// input[type=\"date\"]\n// input[type=\"month\"]\n// input[type=\"time\"]\n// input[type=\"week\"]\n// input[type=\"number\"]\n// input[type=\"email\"]\n// input[type=\"url\"]\n// input[type=\"search\"]\n// input[type=\"tel\"]\n// input[type=\"color\"]\n\n.form-control {\n display: block;\n width: 100%;\n height: @input-height-base; // Make inputs at least the height of their button counterpart (base line-height + padding + border)\n padding: @padding-base-vertical @padding-base-horizontal;\n font-size: @font-size-base;\n line-height: @line-height-base;\n color: @input-color;\n background-color: @input-bg;\n background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n border: 1px solid @input-border;\n border-radius: @input-border-radius; // Note: This has no effect on <select>s in some browsers, due to the limited stylability of <select>s in CSS.\n .box-shadow(inset 0 1px 1px rgba(0,0,0,.075));\n .transition(~\"border-color ease-in-out .15s, box-shadow ease-in-out .15s\");\n\n // Customize the `:focus` state to imitate native WebKit styles.\n .form-control-focus();\n\n // Placeholder\n .placeholder();\n\n // Disabled and read-only inputs\n //\n // HTML5 says that controls under a fieldset > legend:first-child won't be\n // disabled if the fieldset is disabled. Due to implementation difficulty, we\n // don't honor that edge case; we style them as disabled anyway.\n &[disabled],\n &[readonly],\n fieldset[disabled] & {\n cursor: @cursor-disabled;\n background-color: @input-bg-disabled;\n opacity: 1; // iOS fix for unreadable disabled content; see https://github.com/twbs/bootstrap/issues/11655\n }\n\n // Reset height for `textarea`s\n textarea& {\n height: auto;\n }\n}\n\n\n// Search inputs in iOS\n//\n// This overrides the extra rounded corners on search inputs in iOS so that our\n// `.form-control` class can properly style them. Note that this cannot simply\n// be added to `.form-control` as it's not specific enough. For details, see\n// https://github.com/twbs/bootstrap/issues/11586.\n\ninput[type=\"search\"] {\n -webkit-appearance: none;\n}\n\n\n// Special styles for iOS temporal inputs\n//\n// In Mobile Safari, setting `display: block` on temporal inputs causes the\n// text within the input to become vertically misaligned. As a workaround, we\n// set a pixel line-height that matches the given height of the input, but only\n// for Safari. See https://bugs.webkit.org/show_bug.cgi?id=139848\n\n@media screen and (-webkit-min-device-pixel-ratio: 0) {\n input[type=\"date\"],\n input[type=\"time\"],\n input[type=\"datetime-local\"],\n input[type=\"month\"] {\n line-height: @input-height-base;\n\n &.input-sm,\n .input-group-sm & {\n line-height: @input-height-small;\n }\n\n &.input-lg,\n .input-group-lg & {\n line-height: @input-height-large;\n }\n }\n}\n\n\n// Form groups\n//\n// Designed to help with the organization and spacing of vertical forms. For\n// horizontal forms, use the predefined grid classes.\n\n.form-group {\n margin-bottom: 15px;\n}\n\n\n// Checkboxes and radios\n//\n// Indent the labels to position radios/checkboxes as hanging controls.\n\n.radio,\n.checkbox {\n position: relative;\n display: block;\n margin-top: 10px;\n margin-bottom: 10px;\n\n label {\n min-height: @line-height-computed; // Ensure the input doesn't jump when there is no text\n padding-left: 20px;\n margin-bottom: 0;\n font-weight: normal;\n cursor: pointer;\n }\n}\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n position: absolute;\n margin-left: -20px;\n margin-top: 4px \\9;\n}\n\n.radio + .radio,\n.checkbox + .checkbox {\n margin-top: -5px; // Move up sibling radios or checkboxes for tighter spacing\n}\n\n// Radios and checkboxes on same line\n.radio-inline,\n.checkbox-inline {\n display: inline-block;\n padding-left: 20px;\n margin-bottom: 0;\n vertical-align: middle;\n font-weight: normal;\n cursor: pointer;\n}\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n margin-top: 0;\n margin-left: 10px; // space out consecutive inline controls\n}\n\n// Apply same disabled cursor tweak as for inputs\n// Some special care is needed because <label>s don't inherit their parent's `cursor`.\n//\n// Note: Neither radios nor checkboxes can be readonly.\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n &[disabled],\n &.disabled,\n fieldset[disabled] & {\n cursor: @cursor-disabled;\n }\n}\n// These classes are used directly on <label>s\n.radio-inline,\n.checkbox-inline {\n &.disabled,\n fieldset[disabled] & {\n cursor: @cursor-disabled;\n }\n}\n// These classes are used on elements with <label> descendants\n.radio,\n.checkbox {\n &.disabled,\n fieldset[disabled] & {\n label {\n cursor: @cursor-disabled;\n }\n }\n}\n\n\n// Static form control text\n//\n// Apply class to a `p` element to make any string of text align with labels in\n// a horizontal form layout.\n\n.form-control-static {\n // Size it appropriately next to real form controls\n padding-top: (@padding-base-vertical + 1);\n padding-bottom: (@padding-base-vertical + 1);\n // Remove default margin from `p`\n margin-bottom: 0;\n\n &.input-lg,\n &.input-sm {\n padding-left: 0;\n padding-right: 0;\n }\n}\n\n\n// Form control sizing\n//\n// Build on `.form-control` with modifier classes to decrease or increase the\n// height and font-size of form controls.\n//\n// The `.form-group-* form-control` variations are sadly duplicated to avoid the\n// issue documented in https://github.com/twbs/bootstrap/issues/15074.\n\n.input-sm {\n .input-size(@input-height-small; @padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @input-border-radius-small);\n}\n.form-group-sm {\n .form-control {\n .input-size(@input-height-small; @padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @input-border-radius-small);\n }\n .form-control-static {\n height: @input-height-small;\n padding: @padding-small-vertical @padding-small-horizontal;\n font-size: @font-size-small;\n line-height: @line-height-small;\n }\n}\n\n.input-lg {\n .input-size(@input-height-large; @padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @input-border-radius-large);\n}\n.form-group-lg {\n .form-control {\n .input-size(@input-height-large; @padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @input-border-radius-large);\n }\n .form-control-static {\n height: @input-height-large;\n padding: @padding-large-vertical @padding-large-horizontal;\n font-size: @font-size-large;\n line-height: @line-height-large;\n }\n}\n\n\n// Form control feedback states\n//\n// Apply contextual and semantic states to individual form controls.\n\n.has-feedback {\n // Enable absolute positioning\n position: relative;\n\n // Ensure icons don't overlap text\n .form-control {\n padding-right: (@input-height-base * 1.25);\n }\n}\n// Feedback icon (requires .glyphicon classes)\n.form-control-feedback {\n position: absolute;\n top: 0;\n right: 0;\n z-index: 2; // Ensure icon is above input groups\n display: block;\n width: @input-height-base;\n height: @input-height-base;\n line-height: @input-height-base;\n text-align: center;\n pointer-events: none;\n}\n.input-lg + .form-control-feedback {\n width: @input-height-large;\n height: @input-height-large;\n line-height: @input-height-large;\n}\n.input-sm + .form-control-feedback {\n width: @input-height-small;\n height: @input-height-small;\n line-height: @input-height-small;\n}\n\n// Feedback states\n.has-success {\n .form-control-validation(@state-success-text; @state-success-text; @state-success-bg);\n}\n.has-warning {\n .form-control-validation(@state-warning-text; @state-warning-text; @state-warning-bg);\n}\n.has-error {\n .form-control-validation(@state-danger-text; @state-danger-text; @state-danger-bg);\n}\n\n// Reposition feedback icon if input has visible label above\n.has-feedback label {\n\n & ~ .form-control-feedback {\n top: (@line-height-computed + 5); // Height of the `label` and its margin\n }\n &.sr-only ~ .form-control-feedback {\n top: 0;\n }\n}\n\n\n// Help text\n//\n// Apply to any element you wish to create light text for placement immediately\n// below a form control. Use for general help, formatting, or instructional text.\n\n.help-block {\n display: block; // account for any element using help-block\n margin-top: 5px;\n margin-bottom: 10px;\n color: lighten(@text-color, 25%); // lighten the text some for contrast\n}\n\n\n// Inline forms\n//\n// Make forms appear inline(-block) by adding the `.form-inline` class. Inline\n// forms begin stacked on extra small (mobile) devices and then go inline when\n// viewports reach <768px.\n//\n// Requires wrapping inputs and labels with `.form-group` for proper display of\n// default HTML form controls and our custom form controls (e.g., input groups).\n//\n// Heads up! This is mixin-ed into `.navbar-form` in navbars.less.\n\n.form-inline {\n\n // Kick in the inline\n @media (min-width: @screen-sm-min) {\n // Inline-block all the things for \"inline\"\n .form-group {\n display: inline-block;\n margin-bottom: 0;\n vertical-align: middle;\n }\n\n // In navbar-form, allow folks to *not* use `.form-group`\n .form-control {\n display: inline-block;\n width: auto; // Prevent labels from stacking above inputs in `.form-group`\n vertical-align: middle;\n }\n\n // Make static controls behave like regular ones\n .form-control-static {\n display: inline-block;\n }\n\n .input-group {\n display: inline-table;\n vertical-align: middle;\n\n .input-group-addon,\n .input-group-btn,\n .form-control {\n width: auto;\n }\n }\n\n // Input groups need that 100% width though\n .input-group > .form-control {\n width: 100%;\n }\n\n .control-label {\n margin-bottom: 0;\n vertical-align: middle;\n }\n\n // Remove default margin on radios/checkboxes that were used for stacking, and\n // then undo the floating of radios and checkboxes to match.\n .radio,\n .checkbox {\n display: inline-block;\n margin-top: 0;\n margin-bottom: 0;\n vertical-align: middle;\n\n label {\n padding-left: 0;\n }\n }\n .radio input[type=\"radio\"],\n .checkbox input[type=\"checkbox\"] {\n position: relative;\n margin-left: 0;\n }\n\n // Re-override the feedback icon.\n .has-feedback .form-control-feedback {\n top: 0;\n }\n }\n}\n\n\n// Horizontal forms\n//\n// Horizontal forms are built on grid classes and allow you to create forms with\n// labels on the left and inputs on the right.\n\n.form-horizontal {\n\n // Consistent vertical alignment of radios and checkboxes\n //\n // Labels also get some reset styles, but that is scoped to a media query below.\n .radio,\n .checkbox,\n .radio-inline,\n .checkbox-inline {\n margin-top: 0;\n margin-bottom: 0;\n padding-top: (@padding-base-vertical + 1); // Default padding plus a border\n }\n // Account for padding we're adding to ensure the alignment and of help text\n // and other content below items\n .radio,\n .checkbox {\n min-height: (@line-height-computed + (@padding-base-vertical + 1));\n }\n\n // Make form groups behave like rows\n .form-group {\n .make-row();\n }\n\n // Reset spacing and right align labels, but scope to media queries so that\n // labels on narrow viewports stack the same as a default form example.\n @media (min-width: @screen-sm-min) {\n .control-label {\n text-align: right;\n margin-bottom: 0;\n padding-top: (@padding-base-vertical + 1); // Default padding plus a border\n }\n }\n\n // Validation states\n //\n // Reposition the icon because it's now within a grid column and columns have\n // `position: relative;` on them. Also accounts for the grid gutter padding.\n .has-feedback .form-control-feedback {\n right: (@grid-gutter-width / 2);\n }\n\n // Form group sizes\n //\n // Quick utility class for applying `.input-lg` and `.input-sm` styles to the\n // inputs and labels within a `.form-group`.\n .form-group-lg {\n @media (min-width: @screen-sm-min) {\n .control-label {\n padding-top: ((@padding-large-vertical * @line-height-large) + 1);\n }\n }\n }\n .form-group-sm {\n @media (min-width: @screen-sm-min) {\n .control-label {\n padding-top: (@padding-small-vertical + 1);\n }\n }\n }\n}\n","// Form validation states\n//\n// Used in forms.less to generate the form validation CSS for warnings, errors,\n// and successes.\n\n.form-control-validation(@text-color: #555; @border-color: #ccc; @background-color: #f5f5f5) {\n // Color the label and help text\n .help-block,\n .control-label,\n .radio,\n .checkbox,\n .radio-inline,\n .checkbox-inline,\n &.radio label,\n &.checkbox label,\n &.radio-inline label,\n &.checkbox-inline label {\n color: @text-color;\n }\n // Set the border and box shadow on specific inputs to match\n .form-control {\n border-color: @border-color;\n .box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); // Redeclare so transitions work\n &:focus {\n border-color: darken(@border-color, 10%);\n @shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 6px lighten(@border-color, 20%);\n .box-shadow(@shadow);\n }\n }\n // Set validation states also for addons\n .input-group-addon {\n color: @text-color;\n border-color: @border-color;\n background-color: @background-color;\n }\n // Optional feedback icon\n .form-control-feedback {\n color: @text-color;\n }\n}\n\n\n// Form control focus state\n//\n// Generate a customized focus state and for any input with the specified color,\n// which defaults to the `@input-border-focus` variable.\n//\n// We highly encourage you to not customize the default value, but instead use\n// this to tweak colors on an as-needed basis. This aesthetic change is based on\n// WebKit's default styles, but applicable to a wider range of browsers. Its\n// usability and accessibility should be taken into account with any change.\n//\n// Example usage: change the default blue border and shadow to white for better\n// contrast against a dark gray background.\n.form-control-focus(@color: @input-border-focus) {\n @color-rgba: rgba(red(@color), green(@color), blue(@color), .6);\n &:focus {\n border-color: @color;\n outline: 0;\n .box-shadow(~\"inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px @{color-rgba}\");\n }\n}\n\n// Form control sizing\n//\n// Relative text size, padding, and border-radii changes for form controls. For\n// horizontal sizing, wrap controls in the predefined grid classes. `<select>`\n// element gets special love because it's special, and that's a fact!\n.input-size(@input-height; @padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n height: @input-height;\n padding: @padding-vertical @padding-horizontal;\n font-size: @font-size;\n line-height: @line-height;\n border-radius: @border-radius;\n\n select& {\n height: @input-height;\n line-height: @input-height;\n }\n\n textarea&,\n select[multiple]& {\n height: auto;\n }\n}\n","//\n// Buttons\n// --------------------------------------------------\n\n\n// Base styles\n// --------------------------------------------------\n\n.btn {\n display: inline-block;\n margin-bottom: 0; // For input.btn\n font-weight: @btn-font-weight;\n text-align: center;\n vertical-align: middle;\n touch-action: manipulation;\n cursor: pointer;\n background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n border: 1px solid transparent;\n white-space: nowrap;\n .button-size(@padding-base-vertical; @padding-base-horizontal; @font-size-base; @line-height-base; @border-radius-base);\n .user-select(none);\n\n &,\n &:active,\n &.active {\n &:focus,\n &.focus {\n .tab-focus();\n }\n }\n\n &:hover,\n &:focus,\n &.focus {\n color: @btn-default-color;\n text-decoration: none;\n }\n\n &:active,\n &.active {\n outline: 0;\n background-image: none;\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n }\n\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n cursor: @cursor-disabled;\n pointer-events: none; // Future-proof disabling of clicks\n .opacity(.65);\n .box-shadow(none);\n }\n}\n\n\n// Alternate buttons\n// --------------------------------------------------\n\n.btn-default {\n .button-variant(@btn-default-color; @btn-default-bg; @btn-default-border);\n}\n.btn-primary {\n .button-variant(@btn-primary-color; @btn-primary-bg; @btn-primary-border);\n}\n// Success appears as green\n.btn-success {\n .button-variant(@btn-success-color; @btn-success-bg; @btn-success-border);\n}\n// Info appears as blue-green\n.btn-info {\n .button-variant(@btn-info-color; @btn-info-bg; @btn-info-border);\n}\n// Warning appears as orange\n.btn-warning {\n .button-variant(@btn-warning-color; @btn-warning-bg; @btn-warning-border);\n}\n// Danger and error appear as red\n.btn-danger {\n .button-variant(@btn-danger-color; @btn-danger-bg; @btn-danger-border);\n}\n\n\n// Link buttons\n// -------------------------\n\n// Make a button look and behave like a link\n.btn-link {\n color: @link-color;\n font-weight: normal;\n border-radius: 0;\n\n &,\n &:active,\n &.active,\n &[disabled],\n fieldset[disabled] & {\n background-color: transparent;\n .box-shadow(none);\n }\n &,\n &:hover,\n &:focus,\n &:active {\n border-color: transparent;\n }\n &:hover,\n &:focus {\n color: @link-hover-color;\n text-decoration: @link-hover-decoration;\n background-color: transparent;\n }\n &[disabled],\n fieldset[disabled] & {\n &:hover,\n &:focus {\n color: @btn-link-disabled-color;\n text-decoration: none;\n }\n }\n}\n\n\n// Button Sizes\n// --------------------------------------------------\n\n.btn-lg {\n // line-height: ensure even-numbered height of button next to large input\n .button-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @border-radius-large);\n}\n.btn-sm {\n // line-height: ensure proper height of button next to small input\n .button-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @border-radius-small);\n}\n.btn-xs {\n .button-size(@padding-xs-vertical; @padding-xs-horizontal; @font-size-small; @line-height-small; @border-radius-small);\n}\n\n\n// Block button\n// --------------------------------------------------\n\n.btn-block {\n display: block;\n width: 100%;\n}\n\n// Vertically space out multiple block buttons\n.btn-block + .btn-block {\n margin-top: 5px;\n}\n\n// Specificity overrides\ninput[type=\"submit\"],\ninput[type=\"reset\"],\ninput[type=\"button\"] {\n &.btn-block {\n width: 100%;\n }\n}\n","// Button variants\n//\n// Easily pump out default styles, as well as :hover, :focus, :active,\n// and disabled options for all buttons\n\n.button-variant(@color; @background; @border) {\n color: @color;\n background-color: @background;\n border-color: @border;\n\n &:hover,\n &:focus,\n &.focus,\n &:active,\n &.active,\n .open > .dropdown-toggle& {\n color: @color;\n background-color: darken(@background, 10%);\n border-color: darken(@border, 12%);\n }\n &:active,\n &.active,\n .open > .dropdown-toggle& {\n background-image: none;\n }\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n &,\n &:hover,\n &:focus,\n &.focus,\n &:active,\n &.active {\n background-color: @background;\n border-color: @border;\n }\n }\n\n .badge {\n color: @background;\n background-color: @color;\n }\n}\n\n// Button sizes\n.button-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n padding: @padding-vertical @padding-horizontal;\n font-size: @font-size;\n line-height: @line-height;\n border-radius: @border-radius;\n}\n","// Opacity\n\n.opacity(@opacity) {\n opacity: @opacity;\n // IE8 filter\n @opacity-ie: (@opacity * 100);\n filter: ~\"alpha(opacity=@{opacity-ie})\";\n}\n","//\n// Component animations\n// --------------------------------------------------\n\n// Heads up!\n//\n// We don't use the `.opacity()` mixin here since it causes a bug with text\n// fields in IE7-8. Source: https://github.com/twbs/bootstrap/pull/3552.\n\n.fade {\n opacity: 0;\n .transition(opacity .15s linear);\n &.in {\n opacity: 1;\n }\n}\n\n.collapse {\n display: none;\n visibility: hidden;\n\n &.in { display: block; visibility: visible; }\n tr&.in { display: table-row; }\n tbody&.in { display: table-row-group; }\n}\n\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n .transition-property(~\"height, visibility\");\n .transition-duration(.35s);\n .transition-timing-function(ease);\n}\n","//\n// Dropdown menus\n// --------------------------------------------------\n\n\n// Dropdown arrow/caret\n.caret {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 2px;\n vertical-align: middle;\n border-top: @caret-width-base solid;\n border-right: @caret-width-base solid transparent;\n border-left: @caret-width-base solid transparent;\n}\n\n// The dropdown wrapper (div)\n.dropup,\n.dropdown {\n position: relative;\n}\n\n// Prevent the focus on the dropdown toggle when closing dropdowns\n.dropdown-toggle:focus {\n outline: 0;\n}\n\n// The dropdown menu (ul)\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: @zindex-dropdown;\n display: none; // none by default, but block on \"open\" of the menu\n float: left;\n min-width: 160px;\n padding: 5px 0;\n margin: 2px 0 0; // override default ul\n list-style: none;\n font-size: @font-size-base;\n text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer)\n background-color: @dropdown-bg;\n border: 1px solid @dropdown-fallback-border; // IE8 fallback\n border: 1px solid @dropdown-border;\n border-radius: @border-radius-base;\n .box-shadow(0 6px 12px rgba(0,0,0,.175));\n background-clip: padding-box;\n\n // Aligns the dropdown menu to right\n //\n // Deprecated as of 3.1.0 in favor of `.dropdown-menu-[dir]`\n &.pull-right {\n right: 0;\n left: auto;\n }\n\n // Dividers (basically an hr) within the dropdown\n .divider {\n .nav-divider(@dropdown-divider-bg);\n }\n\n // Links within the dropdown menu\n > li > a {\n display: block;\n padding: 3px 20px;\n clear: both;\n font-weight: normal;\n line-height: @line-height-base;\n color: @dropdown-link-color;\n white-space: nowrap; // prevent links from randomly breaking onto new lines\n }\n}\n\n// Hover/Focus state\n.dropdown-menu > li > a {\n &:hover,\n &:focus {\n text-decoration: none;\n color: @dropdown-link-hover-color;\n background-color: @dropdown-link-hover-bg;\n }\n}\n\n// Active state\n.dropdown-menu > .active > a {\n &,\n &:hover,\n &:focus {\n color: @dropdown-link-active-color;\n text-decoration: none;\n outline: 0;\n background-color: @dropdown-link-active-bg;\n }\n}\n\n// Disabled state\n//\n// Gray out text and ensure the hover/focus state remains gray\n\n.dropdown-menu > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @dropdown-link-disabled-color;\n }\n\n // Nuke hover/focus effects\n &:hover,\n &:focus {\n text-decoration: none;\n background-color: transparent;\n background-image: none; // Remove CSS gradient\n .reset-filter();\n cursor: @cursor-disabled;\n }\n}\n\n// Open state for the dropdown\n.open {\n // Show the menu\n > .dropdown-menu {\n display: block;\n }\n\n // Remove the outline when :focus is triggered\n > a {\n outline: 0;\n }\n}\n\n// Menu positioning\n//\n// Add extra class to `.dropdown-menu` to flip the alignment of the dropdown\n// menu with the parent.\n.dropdown-menu-right {\n left: auto; // Reset the default from `.dropdown-menu`\n right: 0;\n}\n// With v3, we enabled auto-flipping if you have a dropdown within a right\n// aligned nav component. To enable the undoing of that, we provide an override\n// to restore the default dropdown menu alignment.\n//\n// This is only for left-aligning a dropdown menu within a `.navbar-right` or\n// `.pull-right` nav component.\n.dropdown-menu-left {\n left: 0;\n right: auto;\n}\n\n// Dropdown section headers\n.dropdown-header {\n display: block;\n padding: 3px 20px;\n font-size: @font-size-small;\n line-height: @line-height-base;\n color: @dropdown-header-color;\n white-space: nowrap; // as with > li > a\n}\n\n// Backdrop to catch body clicks on mobile, etc.\n.dropdown-backdrop {\n position: fixed;\n left: 0;\n right: 0;\n bottom: 0;\n top: 0;\n z-index: (@zindex-dropdown - 10);\n}\n\n// Right aligned dropdowns\n.pull-right > .dropdown-menu {\n right: 0;\n left: auto;\n}\n\n// Allow for dropdowns to go bottom up (aka, dropup-menu)\n//\n// Just add .dropup after the standard .dropdown class and you're set, bro.\n// TODO: abstract this so that the navbar fixed styles are not placed here?\n\n.dropup,\n.navbar-fixed-bottom .dropdown {\n // Reverse the caret\n .caret {\n border-top: 0;\n border-bottom: @caret-width-base solid;\n content: \"\";\n }\n // Different positioning for bottom up menu\n .dropdown-menu {\n top: auto;\n bottom: 100%;\n margin-bottom: 2px;\n }\n}\n\n\n// Component alignment\n//\n// Reiterate per navbar.less and the modified component alignment there.\n\n@media (min-width: @grid-float-breakpoint) {\n .navbar-right {\n .dropdown-menu {\n .dropdown-menu-right();\n }\n // Necessary for overrides of the default right aligned menu.\n // Will remove come v4 in all likelihood.\n .dropdown-menu-left {\n .dropdown-menu-left();\n }\n }\n}\n","// Horizontal dividers\n//\n// Dividers (basically an hr) within dropdowns and nav lists\n\n.nav-divider(@color: #e5e5e5) {\n height: 1px;\n margin: ((@line-height-computed / 2) - 1) 0;\n overflow: hidden;\n background-color: @color;\n}\n","// Reset filters for IE\n//\n// When you need to remove a gradient background, do not forget to use this to reset\n// the IE filter for IE9 and below.\n\n.reset-filter() {\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\"));\n}\n","//\n// Button groups\n// --------------------------------------------------\n\n// Make the div behave like a button\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-block;\n vertical-align: middle; // match .btn alignment given font-size hack above\n > .btn {\n position: relative;\n float: left;\n // Bring the \"active\" button to the front\n &:hover,\n &:focus,\n &:active,\n &.active {\n z-index: 2;\n }\n }\n}\n\n// Prevent double borders when buttons are next to each other\n.btn-group {\n .btn + .btn,\n .btn + .btn-group,\n .btn-group + .btn,\n .btn-group + .btn-group {\n margin-left: -1px;\n }\n}\n\n// Optional: Group multiple button groups together for a toolbar\n.btn-toolbar {\n margin-left: -5px; // Offset the first child's margin\n &:extend(.clearfix all);\n\n .btn-group,\n .input-group {\n float: left;\n }\n > .btn,\n > .btn-group,\n > .input-group {\n margin-left: 5px;\n }\n}\n\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n border-radius: 0;\n}\n\n// Set corners individual because sometimes a single button can be in a .btn-group and we need :first-child and :last-child to both match\n.btn-group > .btn:first-child {\n margin-left: 0;\n &:not(:last-child):not(.dropdown-toggle) {\n .border-right-radius(0);\n }\n}\n// Need .dropdown-toggle since :last-child doesn't apply given a .dropdown-menu immediately after it\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n .border-left-radius(0);\n}\n\n// Custom edits for including btn-groups within btn-groups (useful for including dropdown buttons within a btn-group)\n.btn-group > .btn-group {\n float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group > .btn-group:first-child:not(:last-child) {\n > .btn:last-child,\n > .dropdown-toggle {\n .border-right-radius(0);\n }\n}\n.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {\n .border-left-radius(0);\n}\n\n// On active and open, don't show outline\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n outline: 0;\n}\n\n\n// Sizing\n//\n// Remix the default button sizing classes into new ones for easier manipulation.\n\n.btn-group-xs > .btn { &:extend(.btn-xs); }\n.btn-group-sm > .btn { &:extend(.btn-sm); }\n.btn-group-lg > .btn { &:extend(.btn-lg); }\n\n\n// Split button dropdowns\n// ----------------------\n\n// Give the line between buttons some depth\n.btn-group > .btn + .dropdown-toggle {\n padding-left: 8px;\n padding-right: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n padding-left: 12px;\n padding-right: 12px;\n}\n\n// The clickable button for toggling the menu\n// Remove the gradient and set the same inset shadow as the :active state\n.btn-group.open .dropdown-toggle {\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n\n // Show no shadow for `.btn-link` since it has no other button styles.\n &.btn-link {\n .box-shadow(none);\n }\n}\n\n\n// Reposition the caret\n.btn .caret {\n margin-left: 0;\n}\n// Carets in other button sizes\n.btn-lg .caret {\n border-width: @caret-width-large @caret-width-large 0;\n border-bottom-width: 0;\n}\n// Upside down carets for .dropup\n.dropup .btn-lg .caret {\n border-width: 0 @caret-width-large @caret-width-large;\n}\n\n\n// Vertical button groups\n// ----------------------\n\n.btn-group-vertical {\n > .btn,\n > .btn-group,\n > .btn-group > .btn {\n display: block;\n float: none;\n width: 100%;\n max-width: 100%;\n }\n\n // Clear floats so dropdown menus can be properly placed\n > .btn-group {\n &:extend(.clearfix all);\n > .btn {\n float: none;\n }\n }\n\n > .btn + .btn,\n > .btn + .btn-group,\n > .btn-group + .btn,\n > .btn-group + .btn-group {\n margin-top: -1px;\n margin-left: 0;\n }\n}\n\n.btn-group-vertical > .btn {\n &:not(:first-child):not(:last-child) {\n border-radius: 0;\n }\n &:first-child:not(:last-child) {\n border-top-right-radius: @border-radius-base;\n .border-bottom-radius(0);\n }\n &:last-child:not(:first-child) {\n border-bottom-left-radius: @border-radius-base;\n .border-top-radius(0);\n }\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child:not(:last-child) {\n > .btn:last-child,\n > .dropdown-toggle {\n .border-bottom-radius(0);\n }\n}\n.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {\n .border-top-radius(0);\n}\n\n\n// Justified button groups\n// ----------------------\n\n.btn-group-justified {\n display: table;\n width: 100%;\n table-layout: fixed;\n border-collapse: separate;\n > .btn,\n > .btn-group {\n float: none;\n display: table-cell;\n width: 1%;\n }\n > .btn-group .btn {\n width: 100%;\n }\n\n > .btn-group .dropdown-menu {\n left: auto;\n }\n}\n\n\n// Checkbox and radio options\n//\n// In order to support the browser's form validation feedback, powered by the\n// `required` attribute, we have to \"hide\" the inputs via `clip`. We cannot use\n// `display: none;` or `visibility: hidden;` as that also hides the popover.\n// Simply visually hiding the inputs via `opacity` would leave them clickable in\n// certain cases which is prevented by using `clip` and `pointer-events`.\n// This way, we ensure a DOM element is visible to position the popover from.\n//\n// See https://github.com/twbs/bootstrap/pull/12794 and\n// https://github.com/twbs/bootstrap/pull/14559 for more information.\n\n[data-toggle=\"buttons\"] {\n > .btn,\n > .btn-group > .btn {\n input[type=\"radio\"],\n input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0,0,0,0);\n pointer-events: none;\n }\n }\n}\n","// Single side border-radius\n\n.border-top-radius(@radius) {\n border-top-right-radius: @radius;\n border-top-left-radius: @radius;\n}\n.border-right-radius(@radius) {\n border-bottom-right-radius: @radius;\n border-top-right-radius: @radius;\n}\n.border-bottom-radius(@radius) {\n border-bottom-right-radius: @radius;\n border-bottom-left-radius: @radius;\n}\n.border-left-radius(@radius) {\n border-bottom-left-radius: @radius;\n border-top-left-radius: @radius;\n}\n","//\n// Input groups\n// --------------------------------------------------\n\n// Base styles\n// -------------------------\n.input-group {\n position: relative; // For dropdowns\n display: table;\n border-collapse: separate; // prevent input groups from inheriting border styles from table cells when placed within a table\n\n // Undo padding and float of grid classes\n &[class*=\"col-\"] {\n float: none;\n padding-left: 0;\n padding-right: 0;\n }\n\n .form-control {\n // Ensure that the input is always above the *appended* addon button for\n // proper border colors.\n position: relative;\n z-index: 2;\n\n // IE9 fubars the placeholder attribute in text inputs and the arrows on\n // select elements in input groups. To fix it, we float the input. Details:\n // https://github.com/twbs/bootstrap/issues/11561#issuecomment-28936855\n float: left;\n\n width: 100%;\n margin-bottom: 0;\n }\n}\n\n// Sizing options\n//\n// Remix the default form control sizing classes into new ones for easier\n// manipulation.\n\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn {\n .input-lg();\n}\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn {\n .input-sm();\n}\n\n\n// Display as table-cell\n// -------------------------\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n display: table-cell;\n\n &:not(:first-child):not(:last-child) {\n border-radius: 0;\n }\n}\n// Addon and addon wrapper for buttons\n.input-group-addon,\n.input-group-btn {\n width: 1%;\n white-space: nowrap;\n vertical-align: middle; // Match the inputs\n}\n\n// Text input groups\n// -------------------------\n.input-group-addon {\n padding: @padding-base-vertical @padding-base-horizontal;\n font-size: @font-size-base;\n font-weight: normal;\n line-height: 1;\n color: @input-color;\n text-align: center;\n background-color: @input-group-addon-bg;\n border: 1px solid @input-group-addon-border-color;\n border-radius: @border-radius-base;\n\n // Sizing\n &.input-sm {\n padding: @padding-small-vertical @padding-small-horizontal;\n font-size: @font-size-small;\n border-radius: @border-radius-small;\n }\n &.input-lg {\n padding: @padding-large-vertical @padding-large-horizontal;\n font-size: @font-size-large;\n border-radius: @border-radius-large;\n }\n\n // Nuke default margins from checkboxes and radios to vertically center within.\n input[type=\"radio\"],\n input[type=\"checkbox\"] {\n margin-top: 0;\n }\n}\n\n// Reset rounded corners\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {\n .border-right-radius(0);\n}\n.input-group-addon:first-child {\n border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child),\n.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {\n .border-left-radius(0);\n}\n.input-group-addon:last-child {\n border-left: 0;\n}\n\n// Button input groups\n// -------------------------\n.input-group-btn {\n position: relative;\n // Jankily prevent input button groups from wrapping with `white-space` and\n // `font-size` in combination with `inline-block` on buttons.\n font-size: 0;\n white-space: nowrap;\n\n // Negative margin for spacing, position for bringing hovered/focused/actived\n // element above the siblings.\n > .btn {\n position: relative;\n + .btn {\n margin-left: -1px;\n }\n // Bring the \"active\" button to the front\n &:hover,\n &:focus,\n &:active {\n z-index: 2;\n }\n }\n\n // Negative margin to only have a 1px border between the two\n &:first-child {\n > .btn,\n > .btn-group {\n margin-right: -1px;\n }\n }\n &:last-child {\n > .btn,\n > .btn-group {\n margin-left: -1px;\n }\n }\n}\n","//\n// Navs\n// --------------------------------------------------\n\n\n// Base class\n// --------------------------------------------------\n\n.nav {\n margin-bottom: 0;\n padding-left: 0; // Override default ul/ol\n list-style: none;\n &:extend(.clearfix all);\n\n > li {\n position: relative;\n display: block;\n\n > a {\n position: relative;\n display: block;\n padding: @nav-link-padding;\n &:hover,\n &:focus {\n text-decoration: none;\n background-color: @nav-link-hover-bg;\n }\n }\n\n // Disabled state sets text to gray and nukes hover/tab effects\n &.disabled > a {\n color: @nav-disabled-link-color;\n\n &:hover,\n &:focus {\n color: @nav-disabled-link-hover-color;\n text-decoration: none;\n background-color: transparent;\n cursor: @cursor-disabled;\n }\n }\n }\n\n // Open dropdowns\n .open > a {\n &,\n &:hover,\n &:focus {\n background-color: @nav-link-hover-bg;\n border-color: @link-color;\n }\n }\n\n // Nav dividers (deprecated with v3.0.1)\n //\n // This should have been removed in v3 with the dropping of `.nav-list`, but\n // we missed it. We don't currently support this anywhere, but in the interest\n // of maintaining backward compatibility in case you use it, it's deprecated.\n .nav-divider {\n .nav-divider();\n }\n\n // Prevent IE8 from misplacing imgs\n //\n // See https://github.com/h5bp/html5-boilerplate/issues/984#issuecomment-3985989\n > li > a > img {\n max-width: none;\n }\n}\n\n\n// Tabs\n// -------------------------\n\n// Give the tabs something to sit on\n.nav-tabs {\n border-bottom: 1px solid @nav-tabs-border-color;\n > li {\n float: left;\n // Make the list-items overlay the bottom border\n margin-bottom: -1px;\n\n // Actual tabs (as links)\n > a {\n margin-right: 2px;\n line-height: @line-height-base;\n border: 1px solid transparent;\n border-radius: @border-radius-base @border-radius-base 0 0;\n &:hover {\n border-color: @nav-tabs-link-hover-border-color @nav-tabs-link-hover-border-color @nav-tabs-border-color;\n }\n }\n\n // Active state, and its :hover to override normal :hover\n &.active > a {\n &,\n &:hover,\n &:focus {\n color: @nav-tabs-active-link-hover-color;\n background-color: @nav-tabs-active-link-hover-bg;\n border: 1px solid @nav-tabs-active-link-hover-border-color;\n border-bottom-color: transparent;\n cursor: default;\n }\n }\n }\n // pulling this in mainly for less shorthand\n &.nav-justified {\n .nav-justified();\n .nav-tabs-justified();\n }\n}\n\n\n// Pills\n// -------------------------\n.nav-pills {\n > li {\n float: left;\n\n // Links rendered as pills\n > a {\n border-radius: @nav-pills-border-radius;\n }\n + li {\n margin-left: 2px;\n }\n\n // Active state\n &.active > a {\n &,\n &:hover,\n &:focus {\n color: @nav-pills-active-link-hover-color;\n background-color: @nav-pills-active-link-hover-bg;\n }\n }\n }\n}\n\n\n// Stacked pills\n.nav-stacked {\n > li {\n float: none;\n + li {\n margin-top: 2px;\n margin-left: 0; // no need for this gap between nav items\n }\n }\n}\n\n\n// Nav variations\n// --------------------------------------------------\n\n// Justified nav links\n// -------------------------\n\n.nav-justified {\n width: 100%;\n\n > li {\n float: none;\n > a {\n text-align: center;\n margin-bottom: 5px;\n }\n }\n\n > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n }\n\n @media (min-width: @screen-sm-min) {\n > li {\n display: table-cell;\n width: 1%;\n > a {\n margin-bottom: 0;\n }\n }\n }\n}\n\n// Move borders to anchors instead of bottom of list\n//\n// Mixin for adding on top the shared `.nav-justified` styles for our tabs\n.nav-tabs-justified {\n border-bottom: 0;\n\n > li > a {\n // Override margin from .nav-tabs\n margin-right: 0;\n border-radius: @border-radius-base;\n }\n\n > .active > a,\n > .active > a:hover,\n > .active > a:focus {\n border: 1px solid @nav-tabs-justified-link-border-color;\n }\n\n @media (min-width: @screen-sm-min) {\n > li > a {\n border-bottom: 1px solid @nav-tabs-justified-link-border-color;\n border-radius: @border-radius-base @border-radius-base 0 0;\n }\n > .active > a,\n > .active > a:hover,\n > .active > a:focus {\n border-bottom-color: @nav-tabs-justified-active-link-border-color;\n }\n }\n}\n\n\n// Tabbable tabs\n// -------------------------\n\n// Hide tabbable panes to start, show them when `.active`\n.tab-content {\n > .tab-pane {\n display: none;\n visibility: hidden;\n }\n > .active {\n display: block;\n visibility: visible;\n }\n}\n\n\n// Dropdowns\n// -------------------------\n\n// Specific dropdowns\n.nav-tabs .dropdown-menu {\n // make dropdown border overlap tab border\n margin-top: -1px;\n // Remove the top rounded corners here since there is a hard edge above the menu\n .border-top-radius(0);\n}\n","//\n// Navbars\n// --------------------------------------------------\n\n\n// Wrapper and base class\n//\n// Provide a static navbar from which we expand to create full-width, fixed, and\n// other navbar variations.\n\n.navbar {\n position: relative;\n min-height: @navbar-height; // Ensure a navbar always shows (e.g., without a .navbar-brand in collapsed mode)\n margin-bottom: @navbar-margin-bottom;\n border: 1px solid transparent;\n\n // Prevent floats from breaking the navbar\n &:extend(.clearfix all);\n\n @media (min-width: @grid-float-breakpoint) {\n border-radius: @navbar-border-radius;\n }\n}\n\n\n// Navbar heading\n//\n// Groups `.navbar-brand` and `.navbar-toggle` into a single component for easy\n// styling of responsive aspects.\n\n.navbar-header {\n &:extend(.clearfix all);\n\n @media (min-width: @grid-float-breakpoint) {\n float: left;\n }\n}\n\n\n// Navbar collapse (body)\n//\n// Group your navbar content into this for easy collapsing and expanding across\n// various device sizes. By default, this content is collapsed when <768px, but\n// will expand past that for a horizontal display.\n//\n// To start (on mobile devices) the navbar links, forms, and buttons are stacked\n// vertically and include a `max-height` to overflow in case you have too much\n// content for the user's viewport.\n\n.navbar-collapse {\n overflow-x: visible;\n padding-right: @navbar-padding-horizontal;\n padding-left: @navbar-padding-horizontal;\n border-top: 1px solid transparent;\n box-shadow: inset 0 1px 0 rgba(255,255,255,.1);\n &:extend(.clearfix all);\n -webkit-overflow-scrolling: touch;\n\n &.in {\n overflow-y: auto;\n }\n\n @media (min-width: @grid-float-breakpoint) {\n width: auto;\n border-top: 0;\n box-shadow: none;\n\n &.collapse {\n display: block !important;\n visibility: visible !important;\n height: auto !important;\n padding-bottom: 0; // Override default setting\n overflow: visible !important;\n }\n\n &.in {\n overflow-y: visible;\n }\n\n // Undo the collapse side padding for navbars with containers to ensure\n // alignment of right-aligned contents.\n .navbar-fixed-top &,\n .navbar-static-top &,\n .navbar-fixed-bottom & {\n padding-left: 0;\n padding-right: 0;\n }\n }\n}\n\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n .navbar-collapse {\n max-height: @navbar-collapse-max-height;\n\n @media (max-device-width: @screen-xs-min) and (orientation: landscape) {\n max-height: 200px;\n }\n }\n}\n\n\n// Both navbar header and collapse\n//\n// When a container is present, change the behavior of the header and collapse.\n\n.container,\n.container-fluid {\n > .navbar-header,\n > .navbar-collapse {\n margin-right: -@navbar-padding-horizontal;\n margin-left: -@navbar-padding-horizontal;\n\n @media (min-width: @grid-float-breakpoint) {\n margin-right: 0;\n margin-left: 0;\n }\n }\n}\n\n\n//\n// Navbar alignment options\n//\n// Display the navbar across the entirety of the page or fixed it to the top or\n// bottom of the page.\n\n// Static top (unfixed, but 100% wide) navbar\n.navbar-static-top {\n z-index: @zindex-navbar;\n border-width: 0 0 1px;\n\n @media (min-width: @grid-float-breakpoint) {\n border-radius: 0;\n }\n}\n\n// Fix the top/bottom navbars when screen real estate supports it\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n position: fixed;\n right: 0;\n left: 0;\n z-index: @zindex-navbar-fixed;\n\n // Undo the rounded corners\n @media (min-width: @grid-float-breakpoint) {\n border-radius: 0;\n }\n}\n.navbar-fixed-top {\n top: 0;\n border-width: 0 0 1px;\n}\n.navbar-fixed-bottom {\n bottom: 0;\n margin-bottom: 0; // override .navbar defaults\n border-width: 1px 0 0;\n}\n\n\n// Brand/project name\n\n.navbar-brand {\n float: left;\n padding: @navbar-padding-vertical @navbar-padding-horizontal;\n font-size: @font-size-large;\n line-height: @line-height-computed;\n height: @navbar-height;\n\n &:hover,\n &:focus {\n text-decoration: none;\n }\n\n > img {\n display: block;\n }\n\n @media (min-width: @grid-float-breakpoint) {\n .navbar > .container &,\n .navbar > .container-fluid & {\n margin-left: -@navbar-padding-horizontal;\n }\n }\n}\n\n\n// Navbar toggle\n//\n// Custom button for toggling the `.navbar-collapse`, powered by the collapse\n// JavaScript plugin.\n\n.navbar-toggle {\n position: relative;\n float: right;\n margin-right: @navbar-padding-horizontal;\n padding: 9px 10px;\n .navbar-vertical-align(34px);\n background-color: transparent;\n background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n border: 1px solid transparent;\n border-radius: @border-radius-base;\n\n // We remove the `outline` here, but later compensate by attaching `:hover`\n // styles to `:focus`.\n &:focus {\n outline: 0;\n }\n\n // Bars\n .icon-bar {\n display: block;\n width: 22px;\n height: 2px;\n border-radius: 1px;\n }\n .icon-bar + .icon-bar {\n margin-top: 4px;\n }\n\n @media (min-width: @grid-float-breakpoint) {\n display: none;\n }\n}\n\n\n// Navbar nav links\n//\n// Builds on top of the `.nav` components with its own modifier class to make\n// the nav the full height of the horizontal nav (above 768px).\n\n.navbar-nav {\n margin: (@navbar-padding-vertical / 2) -@navbar-padding-horizontal;\n\n > li > a {\n padding-top: 10px;\n padding-bottom: 10px;\n line-height: @line-height-computed;\n }\n\n @media (max-width: @grid-float-breakpoint-max) {\n // Dropdowns get custom display when collapsed\n .open .dropdown-menu {\n position: static;\n float: none;\n width: auto;\n margin-top: 0;\n background-color: transparent;\n border: 0;\n box-shadow: none;\n > li > a,\n .dropdown-header {\n padding: 5px 15px 5px 25px;\n }\n > li > a {\n line-height: @line-height-computed;\n &:hover,\n &:focus {\n background-image: none;\n }\n }\n }\n }\n\n // Uncollapse the nav\n @media (min-width: @grid-float-breakpoint) {\n float: left;\n margin: 0;\n\n > li {\n float: left;\n > a {\n padding-top: @navbar-padding-vertical;\n padding-bottom: @navbar-padding-vertical;\n }\n }\n }\n}\n\n\n// Navbar form\n//\n// Extension of the `.form-inline` with some extra flavor for optimum display in\n// our navbars.\n\n.navbar-form {\n margin-left: -@navbar-padding-horizontal;\n margin-right: -@navbar-padding-horizontal;\n padding: 10px @navbar-padding-horizontal;\n border-top: 1px solid transparent;\n border-bottom: 1px solid transparent;\n @shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);\n .box-shadow(@shadow);\n\n // Mixin behavior for optimum display\n .form-inline();\n\n .form-group {\n @media (max-width: @grid-float-breakpoint-max) {\n margin-bottom: 5px;\n\n &:last-child {\n margin-bottom: 0;\n }\n }\n }\n\n // Vertically center in expanded, horizontal navbar\n .navbar-vertical-align(@input-height-base);\n\n // Undo 100% width for pull classes\n @media (min-width: @grid-float-breakpoint) {\n width: auto;\n border: 0;\n margin-left: 0;\n margin-right: 0;\n padding-top: 0;\n padding-bottom: 0;\n .box-shadow(none);\n }\n}\n\n\n// Dropdown menus\n\n// Menu position and menu carets\n.navbar-nav > li > .dropdown-menu {\n margin-top: 0;\n .border-top-radius(0);\n}\n// Menu position and menu caret support for dropups via extra dropup class\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n margin-bottom: 0;\n .border-top-radius(@navbar-border-radius);\n .border-bottom-radius(0);\n}\n\n\n// Buttons in navbars\n//\n// Vertically center a button within a navbar (when *not* in a form).\n\n.navbar-btn {\n .navbar-vertical-align(@input-height-base);\n\n &.btn-sm {\n .navbar-vertical-align(@input-height-small);\n }\n &.btn-xs {\n .navbar-vertical-align(22);\n }\n}\n\n\n// Text in navbars\n//\n// Add a class to make any element properly align itself vertically within the navbars.\n\n.navbar-text {\n .navbar-vertical-align(@line-height-computed);\n\n @media (min-width: @grid-float-breakpoint) {\n float: left;\n margin-left: @navbar-padding-horizontal;\n margin-right: @navbar-padding-horizontal;\n }\n}\n\n\n// Component alignment\n//\n// Repurpose the pull utilities as their own navbar utilities to avoid specificity\n// issues with parents and chaining. Only do this when the navbar is uncollapsed\n// though so that navbar contents properly stack and align in mobile.\n//\n// Declared after the navbar components to ensure more specificity on the margins.\n\n@media (min-width: @grid-float-breakpoint) {\n .navbar-left { .pull-left(); }\n .navbar-right {\n .pull-right();\n margin-right: -@navbar-padding-horizontal;\n\n ~ .navbar-right {\n margin-right: 0;\n }\n }\n}\n\n\n// Alternate navbars\n// --------------------------------------------------\n\n// Default navbar\n.navbar-default {\n background-color: @navbar-default-bg;\n border-color: @navbar-default-border;\n\n .navbar-brand {\n color: @navbar-default-brand-color;\n &:hover,\n &:focus {\n color: @navbar-default-brand-hover-color;\n background-color: @navbar-default-brand-hover-bg;\n }\n }\n\n .navbar-text {\n color: @navbar-default-color;\n }\n\n .navbar-nav {\n > li > a {\n color: @navbar-default-link-color;\n\n &:hover,\n &:focus {\n color: @navbar-default-link-hover-color;\n background-color: @navbar-default-link-hover-bg;\n }\n }\n > .active > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-default-link-active-color;\n background-color: @navbar-default-link-active-bg;\n }\n }\n > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-default-link-disabled-color;\n background-color: @navbar-default-link-disabled-bg;\n }\n }\n }\n\n .navbar-toggle {\n border-color: @navbar-default-toggle-border-color;\n &:hover,\n &:focus {\n background-color: @navbar-default-toggle-hover-bg;\n }\n .icon-bar {\n background-color: @navbar-default-toggle-icon-bar-bg;\n }\n }\n\n .navbar-collapse,\n .navbar-form {\n border-color: @navbar-default-border;\n }\n\n // Dropdown menu items\n .navbar-nav {\n // Remove background color from open dropdown\n > .open > a {\n &,\n &:hover,\n &:focus {\n background-color: @navbar-default-link-active-bg;\n color: @navbar-default-link-active-color;\n }\n }\n\n @media (max-width: @grid-float-breakpoint-max) {\n // Dropdowns get custom display when collapsed\n .open .dropdown-menu {\n > li > a {\n color: @navbar-default-link-color;\n &:hover,\n &:focus {\n color: @navbar-default-link-hover-color;\n background-color: @navbar-default-link-hover-bg;\n }\n }\n > .active > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-default-link-active-color;\n background-color: @navbar-default-link-active-bg;\n }\n }\n > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-default-link-disabled-color;\n background-color: @navbar-default-link-disabled-bg;\n }\n }\n }\n }\n }\n\n\n // Links in navbars\n //\n // Add a class to ensure links outside the navbar nav are colored correctly.\n\n .navbar-link {\n color: @navbar-default-link-color;\n &:hover {\n color: @navbar-default-link-hover-color;\n }\n }\n\n .btn-link {\n color: @navbar-default-link-color;\n &:hover,\n &:focus {\n color: @navbar-default-link-hover-color;\n }\n &[disabled],\n fieldset[disabled] & {\n &:hover,\n &:focus {\n color: @navbar-default-link-disabled-color;\n }\n }\n }\n}\n\n// Inverse navbar\n\n.navbar-inverse {\n background-color: @navbar-inverse-bg;\n border-color: @navbar-inverse-border;\n\n .navbar-brand {\n color: @navbar-inverse-brand-color;\n &:hover,\n &:focus {\n color: @navbar-inverse-brand-hover-color;\n background-color: @navbar-inverse-brand-hover-bg;\n }\n }\n\n .navbar-text {\n color: @navbar-inverse-color;\n }\n\n .navbar-nav {\n > li > a {\n color: @navbar-inverse-link-color;\n\n &:hover,\n &:focus {\n color: @navbar-inverse-link-hover-color;\n background-color: @navbar-inverse-link-hover-bg;\n }\n }\n > .active > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-inverse-link-active-color;\n background-color: @navbar-inverse-link-active-bg;\n }\n }\n > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-inverse-link-disabled-color;\n background-color: @navbar-inverse-link-disabled-bg;\n }\n }\n }\n\n // Darken the responsive nav toggle\n .navbar-toggle {\n border-color: @navbar-inverse-toggle-border-color;\n &:hover,\n &:focus {\n background-color: @navbar-inverse-toggle-hover-bg;\n }\n .icon-bar {\n background-color: @navbar-inverse-toggle-icon-bar-bg;\n }\n }\n\n .navbar-collapse,\n .navbar-form {\n border-color: darken(@navbar-inverse-bg, 7%);\n }\n\n // Dropdowns\n .navbar-nav {\n > .open > a {\n &,\n &:hover,\n &:focus {\n background-color: @navbar-inverse-link-active-bg;\n color: @navbar-inverse-link-active-color;\n }\n }\n\n @media (max-width: @grid-float-breakpoint-max) {\n // Dropdowns get custom display\n .open .dropdown-menu {\n > .dropdown-header {\n border-color: @navbar-inverse-border;\n }\n .divider {\n background-color: @navbar-inverse-border;\n }\n > li > a {\n color: @navbar-inverse-link-color;\n &:hover,\n &:focus {\n color: @navbar-inverse-link-hover-color;\n background-color: @navbar-inverse-link-hover-bg;\n }\n }\n > .active > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-inverse-link-active-color;\n background-color: @navbar-inverse-link-active-bg;\n }\n }\n > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-inverse-link-disabled-color;\n background-color: @navbar-inverse-link-disabled-bg;\n }\n }\n }\n }\n }\n\n .navbar-link {\n color: @navbar-inverse-link-color;\n &:hover {\n color: @navbar-inverse-link-hover-color;\n }\n }\n\n .btn-link {\n color: @navbar-inverse-link-color;\n &:hover,\n &:focus {\n color: @navbar-inverse-link-hover-color;\n }\n &[disabled],\n fieldset[disabled] & {\n &:hover,\n &:focus {\n color: @navbar-inverse-link-disabled-color;\n }\n }\n }\n}\n","// Navbar vertical align\n//\n// Vertically center elements in the navbar.\n// Example: an element has a height of 30px, so write out `.navbar-vertical-align(30px);` to calculate the appropriate top margin.\n\n.navbar-vertical-align(@element-height) {\n margin-top: ((@navbar-height - @element-height) / 2);\n margin-bottom: ((@navbar-height - @element-height) / 2);\n}\n","//\n// Utility classes\n// --------------------------------------------------\n\n\n// Floats\n// -------------------------\n\n.clearfix {\n .clearfix();\n}\n.center-block {\n .center-block();\n}\n.pull-right {\n float: right !important;\n}\n.pull-left {\n float: left !important;\n}\n\n\n// Toggling content\n// -------------------------\n\n// Note: Deprecated .hide in favor of .hidden or .sr-only (as appropriate) in v3.0.1\n.hide {\n display: none !important;\n}\n.show {\n display: block !important;\n}\n.invisible {\n visibility: hidden;\n}\n.text-hide {\n .text-hide();\n}\n\n\n// Hide from screenreaders and browsers\n//\n// Credit: HTML5 Boilerplate\n\n.hidden {\n display: none !important;\n visibility: hidden !important;\n}\n\n\n// For Affix plugin\n// -------------------------\n\n.affix {\n position: fixed;\n}\n","//\n// Breadcrumbs\n// --------------------------------------------------\n\n\n.breadcrumb {\n padding: @breadcrumb-padding-vertical @breadcrumb-padding-horizontal;\n margin-bottom: @line-height-computed;\n list-style: none;\n background-color: @breadcrumb-bg;\n border-radius: @border-radius-base;\n\n > li {\n display: inline-block;\n\n + li:before {\n content: \"@{breadcrumb-separator}\\00a0\"; // Unicode space added since inline-block means non-collapsing white-space\n padding: 0 5px;\n color: @breadcrumb-color;\n }\n }\n\n > .active {\n color: @breadcrumb-active-color;\n }\n}\n","//\n// Pagination (multiple pages)\n// --------------------------------------------------\n.pagination {\n display: inline-block;\n padding-left: 0;\n margin: @line-height-computed 0;\n border-radius: @border-radius-base;\n\n > li {\n display: inline; // Remove list-style and block-level defaults\n > a,\n > span {\n position: relative;\n float: left; // Collapse white-space\n padding: @padding-base-vertical @padding-base-horizontal;\n line-height: @line-height-base;\n text-decoration: none;\n color: @pagination-color;\n background-color: @pagination-bg;\n border: 1px solid @pagination-border;\n margin-left: -1px;\n }\n &:first-child {\n > a,\n > span {\n margin-left: 0;\n .border-left-radius(@border-radius-base);\n }\n }\n &:last-child {\n > a,\n > span {\n .border-right-radius(@border-radius-base);\n }\n }\n }\n\n > li > a,\n > li > span {\n &:hover,\n &:focus {\n color: @pagination-hover-color;\n background-color: @pagination-hover-bg;\n border-color: @pagination-hover-border;\n }\n }\n\n > .active > a,\n > .active > span {\n &,\n &:hover,\n &:focus {\n z-index: 2;\n color: @pagination-active-color;\n background-color: @pagination-active-bg;\n border-color: @pagination-active-border;\n cursor: default;\n }\n }\n\n > .disabled {\n > span,\n > span:hover,\n > span:focus,\n > a,\n > a:hover,\n > a:focus {\n color: @pagination-disabled-color;\n background-color: @pagination-disabled-bg;\n border-color: @pagination-disabled-border;\n cursor: @cursor-disabled;\n }\n }\n}\n\n// Sizing\n// --------------------------------------------------\n\n// Large\n.pagination-lg {\n .pagination-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @border-radius-large);\n}\n\n// Small\n.pagination-sm {\n .pagination-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @border-radius-small);\n}\n","// Pagination\n\n.pagination-size(@padding-vertical; @padding-horizontal; @font-size; @border-radius) {\n > li {\n > a,\n > span {\n padding: @padding-vertical @padding-horizontal;\n font-size: @font-size;\n }\n &:first-child {\n > a,\n > span {\n .border-left-radius(@border-radius);\n }\n }\n &:last-child {\n > a,\n > span {\n .border-right-radius(@border-radius);\n }\n }\n }\n}\n","//\n// Pager pagination\n// --------------------------------------------------\n\n\n.pager {\n padding-left: 0;\n margin: @line-height-computed 0;\n list-style: none;\n text-align: center;\n &:extend(.clearfix all);\n li {\n display: inline;\n > a,\n > span {\n display: inline-block;\n padding: 5px 14px;\n background-color: @pager-bg;\n border: 1px solid @pager-border;\n border-radius: @pager-border-radius;\n }\n\n > a:hover,\n > a:focus {\n text-decoration: none;\n background-color: @pager-hover-bg;\n }\n }\n\n .next {\n > a,\n > span {\n float: right;\n }\n }\n\n .previous {\n > a,\n > span {\n float: left;\n }\n }\n\n .disabled {\n > a,\n > a:hover,\n > a:focus,\n > span {\n color: @pager-disabled-color;\n background-color: @pager-bg;\n cursor: @cursor-disabled;\n }\n }\n}\n","//\n// Labels\n// --------------------------------------------------\n\n.label {\n display: inline;\n padding: .2em .6em .3em;\n font-size: 75%;\n font-weight: bold;\n line-height: 1;\n color: @label-color;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n border-radius: .25em;\n\n // Add hover effects, but only for links\n a& {\n &:hover,\n &:focus {\n color: @label-link-hover-color;\n text-decoration: none;\n cursor: pointer;\n }\n }\n\n // Empty labels collapse automatically (not available in IE8)\n &:empty {\n display: none;\n }\n\n // Quick fix for labels in buttons\n .btn & {\n position: relative;\n top: -1px;\n }\n}\n\n// Colors\n// Contextual variations (linked labels get darker on :hover)\n\n.label-default {\n .label-variant(@label-default-bg);\n}\n\n.label-primary {\n .label-variant(@label-primary-bg);\n}\n\n.label-success {\n .label-variant(@label-success-bg);\n}\n\n.label-info {\n .label-variant(@label-info-bg);\n}\n\n.label-warning {\n .label-variant(@label-warning-bg);\n}\n\n.label-danger {\n .label-variant(@label-danger-bg);\n}\n","// Labels\n\n.label-variant(@color) {\n background-color: @color;\n\n &[href] {\n &:hover,\n &:focus {\n background-color: darken(@color, 10%);\n }\n }\n}\n","//\n// Badges\n// --------------------------------------------------\n\n\n// Base class\n.badge {\n display: inline-block;\n min-width: 10px;\n padding: 3px 7px;\n font-size: @font-size-small;\n font-weight: @badge-font-weight;\n color: @badge-color;\n line-height: @badge-line-height;\n vertical-align: baseline;\n white-space: nowrap;\n text-align: center;\n background-color: @badge-bg;\n border-radius: @badge-border-radius;\n\n // Empty badges collapse automatically (not available in IE8)\n &:empty {\n display: none;\n }\n\n // Quick fix for badges in buttons\n .btn & {\n position: relative;\n top: -1px;\n }\n \n .btn-xs & {\n top: 0;\n padding: 1px 5px;\n }\n\n // Hover state, but only for links\n a& {\n &:hover,\n &:focus {\n color: @badge-link-hover-color;\n text-decoration: none;\n cursor: pointer;\n }\n }\n\n // Account for badges in navs\n .list-group-item.active > &,\n .nav-pills > .active > a > & {\n color: @badge-active-color;\n background-color: @badge-active-bg;\n }\n \n .list-group-item > & {\n float: right;\n }\n \n .list-group-item > & + & {\n margin-right: 5px;\n }\n \n .nav-pills > li > a > & {\n margin-left: 3px;\n }\n}\n","//\n// Jumbotron\n// --------------------------------------------------\n\n\n.jumbotron {\n padding: @jumbotron-padding (@jumbotron-padding / 2);\n margin-bottom: @jumbotron-padding;\n color: @jumbotron-color;\n background-color: @jumbotron-bg;\n\n h1,\n .h1 {\n color: @jumbotron-heading-color;\n }\n \n p {\n margin-bottom: (@jumbotron-padding / 2);\n font-size: @jumbotron-font-size;\n font-weight: 200;\n }\n\n > hr {\n border-top-color: darken(@jumbotron-bg, 10%);\n }\n\n .container &,\n .container-fluid & {\n border-radius: @border-radius-large; // Only round corners at higher resolutions if contained in a container\n }\n\n .container {\n max-width: 100%;\n }\n\n @media screen and (min-width: @screen-sm-min) {\n padding: (@jumbotron-padding * 1.6) 0;\n\n .container &,\n .container-fluid & {\n padding-left: (@jumbotron-padding * 2);\n padding-right: (@jumbotron-padding * 2);\n }\n\n h1,\n .h1 {\n font-size: (@font-size-base * 4.5);\n }\n }\n}\n","//\n// Thumbnails\n// --------------------------------------------------\n\n\n// Mixin and adjust the regular image class\n.thumbnail {\n display: block;\n padding: @thumbnail-padding;\n margin-bottom: @line-height-computed;\n line-height: @line-height-base;\n background-color: @thumbnail-bg;\n border: 1px solid @thumbnail-border;\n border-radius: @thumbnail-border-radius;\n .transition(border .2s ease-in-out);\n\n > img,\n a > img {\n &:extend(.img-responsive);\n margin-left: auto;\n margin-right: auto;\n }\n\n // Add a hover state for linked versions only\n a&:hover,\n a&:focus,\n a&.active {\n border-color: @link-color;\n }\n\n // Image captions\n .caption {\n padding: @thumbnail-caption-padding;\n color: @thumbnail-caption-color;\n }\n}\n","//\n// Alerts\n// --------------------------------------------------\n\n\n// Base styles\n// -------------------------\n\n.alert {\n padding: @alert-padding;\n margin-bottom: @line-height-computed;\n border: 1px solid transparent;\n border-radius: @alert-border-radius;\n\n // Headings for larger alerts\n h4 {\n margin-top: 0;\n // Specified for the h4 to prevent conflicts of changing @headings-color\n color: inherit;\n }\n \n // Provide class for links that match alerts\n .alert-link {\n font-weight: @alert-link-font-weight;\n }\n\n // Improve alignment and spacing of inner content\n > p,\n > ul {\n margin-bottom: 0;\n }\n \n > p + p {\n margin-top: 5px;\n }\n}\n\n// Dismissible alerts\n//\n// Expand the right padding and account for the close button's positioning.\n\n.alert-dismissable, // The misspelled .alert-dismissable was deprecated in 3.2.0.\n.alert-dismissible {\n padding-right: (@alert-padding + 20);\n\n // Adjust close link position\n .close {\n position: relative;\n top: -2px;\n right: -21px;\n color: inherit;\n }\n}\n\n// Alternate styles\n//\n// Generate contextual modifier classes for colorizing the alert.\n\n.alert-success {\n .alert-variant(@alert-success-bg; @alert-success-border; @alert-success-text);\n}\n\n.alert-info {\n .alert-variant(@alert-info-bg; @alert-info-border; @alert-info-text);\n}\n\n.alert-warning {\n .alert-variant(@alert-warning-bg; @alert-warning-border; @alert-warning-text);\n}\n\n.alert-danger {\n .alert-variant(@alert-danger-bg; @alert-danger-border; @alert-danger-text);\n}\n","// Alerts\n\n.alert-variant(@background; @border; @text-color) {\n background-color: @background;\n border-color: @border;\n color: @text-color;\n\n hr {\n border-top-color: darken(@border, 5%);\n }\n .alert-link {\n color: darken(@text-color, 10%);\n }\n}\n","//\n// Progress bars\n// --------------------------------------------------\n\n\n// Bar animations\n// -------------------------\n\n// WebKit\n@-webkit-keyframes progress-bar-stripes {\n from { background-position: 40px 0; }\n to { background-position: 0 0; }\n}\n\n// Spec and IE10+\n@keyframes progress-bar-stripes {\n from { background-position: 40px 0; }\n to { background-position: 0 0; }\n}\n\n\n// Bar itself\n// -------------------------\n\n// Outer container\n.progress {\n overflow: hidden;\n height: @line-height-computed;\n margin-bottom: @line-height-computed;\n background-color: @progress-bg;\n border-radius: @progress-border-radius;\n .box-shadow(inset 0 1px 2px rgba(0,0,0,.1));\n}\n\n// Bar of progress\n.progress-bar {\n float: left;\n width: 0%;\n height: 100%;\n font-size: @font-size-small;\n line-height: @line-height-computed;\n color: @progress-bar-color;\n text-align: center;\n background-color: @progress-bar-bg;\n .box-shadow(inset 0 -1px 0 rgba(0,0,0,.15));\n .transition(width .6s ease);\n}\n\n// Striped bars\n//\n// `.progress-striped .progress-bar` is deprecated as of v3.2.0 in favor of the\n// `.progress-bar-striped` class, which you just add to an existing\n// `.progress-bar`.\n.progress-striped .progress-bar,\n.progress-bar-striped {\n #gradient > .striped();\n background-size: 40px 40px;\n}\n\n// Call animation for the active one\n//\n// `.progress.active .progress-bar` is deprecated as of v3.2.0 in favor of the\n// `.progress-bar.active` approach.\n.progress.active .progress-bar,\n.progress-bar.active {\n .animation(progress-bar-stripes 2s linear infinite);\n}\n\n\n// Variations\n// -------------------------\n\n.progress-bar-success {\n .progress-bar-variant(@progress-bar-success-bg);\n}\n\n.progress-bar-info {\n .progress-bar-variant(@progress-bar-info-bg);\n}\n\n.progress-bar-warning {\n .progress-bar-variant(@progress-bar-warning-bg);\n}\n\n.progress-bar-danger {\n .progress-bar-variant(@progress-bar-danger-bg);\n}\n","// Gradients\n\n#gradient {\n\n // Horizontal gradient, from left to right\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n // Vertical gradient, from top to bottom\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n .directional(@start-color: #555; @end-color: #333; @deg: 45deg) {\n background-repeat: repeat-x;\n background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(@deg, @start-color, @end-color); // Opera 12\n background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n }\n .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .radial(@inner-color: #555; @outer-color: #333) {\n background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);\n background-image: radial-gradient(circle, @inner-color, @outer-color);\n background-repeat: no-repeat;\n }\n .striped(@color: rgba(255,255,255,.15); @angle: 45deg) {\n background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n }\n}\n","// Progress bars\n\n.progress-bar-variant(@color) {\n background-color: @color;\n\n // Deprecated parent class requirement as of v3.2.0\n .progress-striped & {\n #gradient > .striped();\n }\n}\n",".media {\n // Proper spacing between instances of .media\n margin-top: 15px;\n\n &:first-child {\n margin-top: 0;\n }\n}\n\n.media,\n.media-body {\n zoom: 1;\n overflow: hidden;\n}\n\n.media-body {\n width: 10000px;\n}\n\n.media-object {\n display: block;\n}\n\n.media-right,\n.media > .pull-right {\n padding-left: 10px;\n}\n\n.media-left,\n.media > .pull-left {\n padding-right: 10px;\n}\n\n.media-left,\n.media-right,\n.media-body {\n display: table-cell;\n vertical-align: top;\n}\n\n.media-middle {\n vertical-align: middle;\n}\n\n.media-bottom {\n vertical-align: bottom;\n}\n\n// Reset margins on headings for tighter default spacing\n.media-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n\n// Media list variation\n//\n// Undo default ul/ol styles\n.media-list {\n padding-left: 0;\n list-style: none;\n}\n","//\n// List groups\n// --------------------------------------------------\n\n\n// Base class\n//\n// Easily usable on <ul>, <ol>, or <div>.\n\n.list-group {\n // No need to set list-style: none; since .list-group-item is block level\n margin-bottom: 20px;\n padding-left: 0; // reset padding because ul and ol\n}\n\n\n// Individual list items\n//\n// Use on `li`s or `div`s within the `.list-group` parent.\n\n.list-group-item {\n position: relative;\n display: block;\n padding: 10px 15px;\n // Place the border on the list items and negative margin up for better styling\n margin-bottom: -1px;\n background-color: @list-group-bg;\n border: 1px solid @list-group-border;\n\n // Round the first and last items\n &:first-child {\n .border-top-radius(@list-group-border-radius);\n }\n &:last-child {\n margin-bottom: 0;\n .border-bottom-radius(@list-group-border-radius);\n }\n}\n\n\n// Linked list items\n//\n// Use anchor elements instead of `li`s or `div`s to create linked list items.\n// Includes an extra `.active` modifier class for showing selected items.\n\na.list-group-item {\n color: @list-group-link-color;\n\n .list-group-item-heading {\n color: @list-group-link-heading-color;\n }\n\n // Hover state\n &:hover,\n &:focus {\n text-decoration: none;\n color: @list-group-link-hover-color;\n background-color: @list-group-hover-bg;\n }\n}\n\n.list-group-item {\n // Disabled state\n &.disabled,\n &.disabled:hover,\n &.disabled:focus {\n background-color: @list-group-disabled-bg;\n color: @list-group-disabled-color;\n cursor: @cursor-disabled;\n\n // Force color to inherit for custom content\n .list-group-item-heading {\n color: inherit;\n }\n .list-group-item-text {\n color: @list-group-disabled-text-color;\n }\n }\n\n // Active class on item itself, not parent\n &.active,\n &.active:hover,\n &.active:focus {\n z-index: 2; // Place active items above their siblings for proper border styling\n color: @list-group-active-color;\n background-color: @list-group-active-bg;\n border-color: @list-group-active-border;\n\n // Force color to inherit for custom content\n .list-group-item-heading,\n .list-group-item-heading > small,\n .list-group-item-heading > .small {\n color: inherit;\n }\n .list-group-item-text {\n color: @list-group-active-text-color;\n }\n }\n}\n\n\n// Contextual variants\n//\n// Add modifier classes to change text and background color on individual items.\n// Organizationally, this must come after the `:hover` states.\n\n.list-group-item-variant(success; @state-success-bg; @state-success-text);\n.list-group-item-variant(info; @state-info-bg; @state-info-text);\n.list-group-item-variant(warning; @state-warning-bg; @state-warning-text);\n.list-group-item-variant(danger; @state-danger-bg; @state-danger-text);\n\n\n// Custom content options\n//\n// Extra classes for creating well-formatted content within `.list-group-item`s.\n\n.list-group-item-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.list-group-item-text {\n margin-bottom: 0;\n line-height: 1.3;\n}\n","// List Groups\n\n.list-group-item-variant(@state; @background; @color) {\n .list-group-item-@{state} {\n color: @color;\n background-color: @background;\n\n a& {\n color: @color;\n\n .list-group-item-heading {\n color: inherit;\n }\n\n &:hover,\n &:focus {\n color: @color;\n background-color: darken(@background, 5%);\n }\n &.active,\n &.active:hover,\n &.active:focus {\n color: #fff;\n background-color: @color;\n border-color: @color;\n }\n }\n }\n}\n","//\n// Panels\n// --------------------------------------------------\n\n\n// Base class\n.panel {\n margin-bottom: @line-height-computed;\n background-color: @panel-bg;\n border: 1px solid transparent;\n border-radius: @panel-border-radius;\n .box-shadow(0 1px 1px rgba(0,0,0,.05));\n}\n\n// Panel contents\n.panel-body {\n padding: @panel-body-padding;\n &:extend(.clearfix all);\n}\n\n// Optional heading\n.panel-heading {\n padding: @panel-heading-padding;\n border-bottom: 1px solid transparent;\n .border-top-radius((@panel-border-radius - 1));\n\n > .dropdown .dropdown-toggle {\n color: inherit;\n }\n}\n\n// Within heading, strip any `h*` tag of its default margins for spacing.\n.panel-title {\n margin-top: 0;\n margin-bottom: 0;\n font-size: ceil((@font-size-base * 1.125));\n color: inherit;\n\n > a,\n > small,\n > .small,\n > small > a,\n > .small > a {\n color: inherit;\n }\n}\n\n// Optional footer (stays gray in every modifier class)\n.panel-footer {\n padding: @panel-footer-padding;\n background-color: @panel-footer-bg;\n border-top: 1px solid @panel-inner-border;\n .border-bottom-radius((@panel-border-radius - 1));\n}\n\n\n// List groups in panels\n//\n// By default, space out list group content from panel headings to account for\n// any kind of custom content between the two.\n\n.panel {\n > .list-group,\n > .panel-collapse > .list-group {\n margin-bottom: 0;\n\n .list-group-item {\n border-width: 1px 0;\n border-radius: 0;\n }\n\n // Add border top radius for first one\n &:first-child {\n .list-group-item:first-child {\n border-top: 0;\n .border-top-radius((@panel-border-radius - 1));\n }\n }\n // Add border bottom radius for last one\n &:last-child {\n .list-group-item:last-child {\n border-bottom: 0;\n .border-bottom-radius((@panel-border-radius - 1));\n }\n }\n }\n}\n// Collapse space between when there's no additional content.\n.panel-heading + .list-group {\n .list-group-item:first-child {\n border-top-width: 0;\n }\n}\n.list-group + .panel-footer {\n border-top-width: 0;\n}\n\n// Tables in panels\n//\n// Place a non-bordered `.table` within a panel (not within a `.panel-body`) and\n// watch it go full width.\n\n.panel {\n > .table,\n > .table-responsive > .table,\n > .panel-collapse > .table {\n margin-bottom: 0;\n\n caption {\n padding-left: @panel-body-padding;\n padding-right: @panel-body-padding;\n }\n }\n // Add border top radius for first one\n > .table:first-child,\n > .table-responsive:first-child > .table:first-child {\n .border-top-radius((@panel-border-radius - 1));\n\n > thead:first-child,\n > tbody:first-child {\n > tr:first-child {\n border-top-left-radius: (@panel-border-radius - 1);\n border-top-right-radius: (@panel-border-radius - 1);\n\n td:first-child,\n th:first-child {\n border-top-left-radius: (@panel-border-radius - 1);\n }\n td:last-child,\n th:last-child {\n border-top-right-radius: (@panel-border-radius - 1);\n }\n }\n }\n }\n // Add border bottom radius for last one\n > .table:last-child,\n > .table-responsive:last-child > .table:last-child {\n .border-bottom-radius((@panel-border-radius - 1));\n\n > tbody:last-child,\n > tfoot:last-child {\n > tr:last-child {\n border-bottom-left-radius: (@panel-border-radius - 1);\n border-bottom-right-radius: (@panel-border-radius - 1);\n\n td:first-child,\n th:first-child {\n border-bottom-left-radius: (@panel-border-radius - 1);\n }\n td:last-child,\n th:last-child {\n border-bottom-right-radius: (@panel-border-radius - 1);\n }\n }\n }\n }\n > .panel-body + .table,\n > .panel-body + .table-responsive,\n > .table + .panel-body,\n > .table-responsive + .panel-body {\n border-top: 1px solid @table-border-color;\n }\n > .table > tbody:first-child > tr:first-child th,\n > .table > tbody:first-child > tr:first-child td {\n border-top: 0;\n }\n > .table-bordered,\n > .table-responsive > .table-bordered {\n border: 0;\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th:first-child,\n > td:first-child {\n border-left: 0;\n }\n > th:last-child,\n > td:last-child {\n border-right: 0;\n }\n }\n }\n > thead,\n > tbody {\n > tr:first-child {\n > td,\n > th {\n border-bottom: 0;\n }\n }\n }\n > tbody,\n > tfoot {\n > tr:last-child {\n > td,\n > th {\n border-bottom: 0;\n }\n }\n }\n }\n > .table-responsive {\n border: 0;\n margin-bottom: 0;\n }\n}\n\n\n// Collapsable panels (aka, accordion)\n//\n// Wrap a series of panels in `.panel-group` to turn them into an accordion with\n// the help of our collapse JavaScript plugin.\n\n.panel-group {\n margin-bottom: @line-height-computed;\n\n // Tighten up margin so it's only between panels\n .panel {\n margin-bottom: 0;\n border-radius: @panel-border-radius;\n\n + .panel {\n margin-top: 5px;\n }\n }\n\n .panel-heading {\n border-bottom: 0;\n\n + .panel-collapse > .panel-body,\n + .panel-collapse > .list-group {\n border-top: 1px solid @panel-inner-border;\n }\n }\n\n .panel-footer {\n border-top: 0;\n + .panel-collapse .panel-body {\n border-bottom: 1px solid @panel-inner-border;\n }\n }\n}\n\n\n// Contextual variations\n.panel-default {\n .panel-variant(@panel-default-border; @panel-default-text; @panel-default-heading-bg; @panel-default-border);\n}\n.panel-primary {\n .panel-variant(@panel-primary-border; @panel-primary-text; @panel-primary-heading-bg; @panel-primary-border);\n}\n.panel-success {\n .panel-variant(@panel-success-border; @panel-success-text; @panel-success-heading-bg; @panel-success-border);\n}\n.panel-info {\n .panel-variant(@panel-info-border; @panel-info-text; @panel-info-heading-bg; @panel-info-border);\n}\n.panel-warning {\n .panel-variant(@panel-warning-border; @panel-warning-text; @panel-warning-heading-bg; @panel-warning-border);\n}\n.panel-danger {\n .panel-variant(@panel-danger-border; @panel-danger-text; @panel-danger-heading-bg; @panel-danger-border);\n}\n","// Panels\n\n.panel-variant(@border; @heading-text-color; @heading-bg-color; @heading-border) {\n border-color: @border;\n\n & > .panel-heading {\n color: @heading-text-color;\n background-color: @heading-bg-color;\n border-color: @heading-border;\n\n + .panel-collapse > .panel-body {\n border-top-color: @border;\n }\n .badge {\n color: @heading-bg-color;\n background-color: @heading-text-color;\n }\n }\n & > .panel-footer {\n + .panel-collapse > .panel-body {\n border-bottom-color: @border;\n }\n }\n}\n","// Embeds responsive\n//\n// Credit: Nicolas Gallagher and SUIT CSS.\n\n.embed-responsive {\n position: relative;\n display: block;\n height: 0;\n padding: 0;\n overflow: hidden;\n\n .embed-responsive-item,\n iframe,\n embed,\n object,\n video {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n height: 100%;\n width: 100%;\n border: 0;\n }\n\n // Modifier class for 16:9 aspect ratio\n &.embed-responsive-16by9 {\n padding-bottom: 56.25%;\n }\n\n // Modifier class for 4:3 aspect ratio\n &.embed-responsive-4by3 {\n padding-bottom: 75%;\n }\n}\n","//\n// Wells\n// --------------------------------------------------\n\n\n// Base class\n.well {\n min-height: 20px;\n padding: 19px;\n margin-bottom: 20px;\n background-color: @well-bg;\n border: 1px solid @well-border;\n border-radius: @border-radius-base;\n .box-shadow(inset 0 1px 1px rgba(0,0,0,.05));\n blockquote {\n border-color: #ddd;\n border-color: rgba(0,0,0,.15);\n }\n}\n\n// Sizes\n.well-lg {\n padding: 24px;\n border-radius: @border-radius-large;\n}\n.well-sm {\n padding: 9px;\n border-radius: @border-radius-small;\n}\n","//\n// Close icons\n// --------------------------------------------------\n\n\n.close {\n float: right;\n font-size: (@font-size-base * 1.5);\n font-weight: @close-font-weight;\n line-height: 1;\n color: @close-color;\n text-shadow: @close-text-shadow;\n .opacity(.2);\n\n &:hover,\n &:focus {\n color: @close-color;\n text-decoration: none;\n cursor: pointer;\n .opacity(.5);\n }\n\n // Additional properties for button version\n // iOS requires the button element instead of an anchor tag.\n // If you want the anchor version, it requires `href=\"#\"`.\n // See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile\n button& {\n padding: 0;\n cursor: pointer;\n background: transparent;\n border: 0;\n -webkit-appearance: none;\n }\n}\n","//\n// Modals\n// --------------------------------------------------\n\n// .modal-open - body class for killing the scroll\n// .modal - container to scroll within\n// .modal-dialog - positioning shell for the actual modal\n// .modal-content - actual modal w/ bg and corners and shit\n\n// Kill the scroll on the body\n.modal-open {\n overflow: hidden;\n}\n\n// Container that the modal scrolls within\n.modal {\n display: none;\n overflow: hidden;\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: @zindex-modal;\n -webkit-overflow-scrolling: touch;\n\n // Prevent Chrome on Windows from adding a focus outline. For details, see\n // https://github.com/twbs/bootstrap/pull/10951.\n outline: 0;\n\n // When fading in the modal, animate it to slide down\n &.fade .modal-dialog {\n .translate(0, -25%);\n .transition-transform(~\"0.3s ease-out\");\n }\n &.in .modal-dialog { .translate(0, 0) }\n}\n.modal-open .modal {\n overflow-x: hidden;\n overflow-y: auto;\n}\n\n// Shell div to position the modal with bottom padding\n.modal-dialog {\n position: relative;\n width: auto;\n margin: 10px;\n}\n\n// Actual modal\n.modal-content {\n position: relative;\n background-color: @modal-content-bg;\n border: 1px solid @modal-content-fallback-border-color; //old browsers fallback (ie8 etc)\n border: 1px solid @modal-content-border-color;\n border-radius: @border-radius-large;\n .box-shadow(0 3px 9px rgba(0,0,0,.5));\n background-clip: padding-box;\n // Remove focus outline from opened modal\n outline: 0;\n}\n\n// Modal background\n.modal-backdrop {\n position: absolute;\n top: 0;\n right: 0;\n left: 0;\n background-color: @modal-backdrop-bg;\n // Fade for backdrop\n &.fade { .opacity(0); }\n &.in { .opacity(@modal-backdrop-opacity); }\n}\n\n// Modal header\n// Top section of the modal w/ title and dismiss\n.modal-header {\n padding: @modal-title-padding;\n border-bottom: 1px solid @modal-header-border-color;\n min-height: (@modal-title-padding + @modal-title-line-height);\n}\n// Close icon\n.modal-header .close {\n margin-top: -2px;\n}\n\n// Title text within header\n.modal-title {\n margin: 0;\n line-height: @modal-title-line-height;\n}\n\n// Modal body\n// Where all modal content resides (sibling of .modal-header and .modal-footer)\n.modal-body {\n position: relative;\n padding: @modal-inner-padding;\n}\n\n// Footer (for actions)\n.modal-footer {\n padding: @modal-inner-padding;\n text-align: right; // right align buttons\n border-top: 1px solid @modal-footer-border-color;\n &:extend(.clearfix all); // clear it in case folks use .pull-* classes on buttons\n\n // Properly space out buttons\n .btn + .btn {\n margin-left: 5px;\n margin-bottom: 0; // account for input[type=\"submit\"] which gets the bottom margin like all other inputs\n }\n // but override that for button groups\n .btn-group .btn + .btn {\n margin-left: -1px;\n }\n // and override it for block buttons as well\n .btn-block + .btn-block {\n margin-left: 0;\n }\n}\n\n// Measure scrollbar width for padding body during modal show/hide\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n\n// Scale up the modal\n@media (min-width: @screen-sm-min) {\n // Automatically set modal's width for larger viewports\n .modal-dialog {\n width: @modal-md;\n margin: 30px auto;\n }\n .modal-content {\n .box-shadow(0 5px 15px rgba(0,0,0,.5));\n }\n\n // Modal sizes\n .modal-sm { width: @modal-sm; }\n}\n\n@media (min-width: @screen-md-min) {\n .modal-lg { width: @modal-lg; }\n}\n","//\n// Tooltips\n// --------------------------------------------------\n\n\n// Base class\n.tooltip {\n position: absolute;\n z-index: @zindex-tooltip;\n display: block;\n visibility: visible;\n // Reset font and text properties given new insertion method\n font-family: @font-family-base;\n font-size: @font-size-small;\n font-weight: normal;\n line-height: 1.4;\n .opacity(0);\n\n &.in { .opacity(@tooltip-opacity); }\n &.top { margin-top: -3px; padding: @tooltip-arrow-width 0; }\n &.right { margin-left: 3px; padding: 0 @tooltip-arrow-width; }\n &.bottom { margin-top: 3px; padding: @tooltip-arrow-width 0; }\n &.left { margin-left: -3px; padding: 0 @tooltip-arrow-width; }\n}\n\n// Wrapper for the tooltip content\n.tooltip-inner {\n max-width: @tooltip-max-width;\n padding: 3px 8px;\n color: @tooltip-color;\n text-align: center;\n text-decoration: none;\n background-color: @tooltip-bg;\n border-radius: @border-radius-base;\n}\n\n// Arrows\n.tooltip-arrow {\n position: absolute;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n// Note: Deprecated .top-left, .top-right, .bottom-left, and .bottom-right as of v3.3.1\n.tooltip {\n &.top .tooltip-arrow {\n bottom: 0;\n left: 50%;\n margin-left: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n border-top-color: @tooltip-arrow-color;\n }\n &.top-left .tooltip-arrow {\n bottom: 0;\n right: @tooltip-arrow-width;\n margin-bottom: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n border-top-color: @tooltip-arrow-color;\n }\n &.top-right .tooltip-arrow {\n bottom: 0;\n left: @tooltip-arrow-width;\n margin-bottom: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n border-top-color: @tooltip-arrow-color;\n }\n &.right .tooltip-arrow {\n top: 50%;\n left: 0;\n margin-top: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width @tooltip-arrow-width @tooltip-arrow-width 0;\n border-right-color: @tooltip-arrow-color;\n }\n &.left .tooltip-arrow {\n top: 50%;\n right: 0;\n margin-top: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width 0 @tooltip-arrow-width @tooltip-arrow-width;\n border-left-color: @tooltip-arrow-color;\n }\n &.bottom .tooltip-arrow {\n top: 0;\n left: 50%;\n margin-left: -@tooltip-arrow-width;\n border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n border-bottom-color: @tooltip-arrow-color;\n }\n &.bottom-left .tooltip-arrow {\n top: 0;\n right: @tooltip-arrow-width;\n margin-top: -@tooltip-arrow-width;\n border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n border-bottom-color: @tooltip-arrow-color;\n }\n &.bottom-right .tooltip-arrow {\n top: 0;\n left: @tooltip-arrow-width;\n margin-top: -@tooltip-arrow-width;\n border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n border-bottom-color: @tooltip-arrow-color;\n }\n}\n","//\n// Popovers\n// --------------------------------------------------\n\n\n.popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: @zindex-popover;\n display: none;\n max-width: @popover-max-width;\n padding: 1px;\n // Reset font and text properties given new insertion method\n font-family: @font-family-base;\n font-size: @font-size-base;\n font-weight: normal;\n line-height: @line-height-base;\n text-align: left;\n background-color: @popover-bg;\n background-clip: padding-box;\n border: 1px solid @popover-fallback-border-color;\n border: 1px solid @popover-border-color;\n border-radius: @border-radius-large;\n .box-shadow(0 5px 10px rgba(0,0,0,.2));\n\n // Overrides for proper insertion\n white-space: normal;\n\n // Offset the popover to account for the popover arrow\n &.top { margin-top: -@popover-arrow-width; }\n &.right { margin-left: @popover-arrow-width; }\n &.bottom { margin-top: @popover-arrow-width; }\n &.left { margin-left: -@popover-arrow-width; }\n}\n\n.popover-title {\n margin: 0; // reset heading margin\n padding: 8px 14px;\n font-size: @font-size-base;\n background-color: @popover-title-bg;\n border-bottom: 1px solid darken(@popover-title-bg, 5%);\n border-radius: (@border-radius-large - 1) (@border-radius-large - 1) 0 0;\n}\n\n.popover-content {\n padding: 9px 14px;\n}\n\n// Arrows\n//\n// .arrow is outer, .arrow:after is inner\n\n.popover > .arrow {\n &,\n &:after {\n position: absolute;\n display: block;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n }\n}\n.popover > .arrow {\n border-width: @popover-arrow-outer-width;\n}\n.popover > .arrow:after {\n border-width: @popover-arrow-width;\n content: \"\";\n}\n\n.popover {\n &.top > .arrow {\n left: 50%;\n margin-left: -@popover-arrow-outer-width;\n border-bottom-width: 0;\n border-top-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n border-top-color: @popover-arrow-outer-color;\n bottom: -@popover-arrow-outer-width;\n &:after {\n content: \" \";\n bottom: 1px;\n margin-left: -@popover-arrow-width;\n border-bottom-width: 0;\n border-top-color: @popover-arrow-color;\n }\n }\n &.right > .arrow {\n top: 50%;\n left: -@popover-arrow-outer-width;\n margin-top: -@popover-arrow-outer-width;\n border-left-width: 0;\n border-right-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n border-right-color: @popover-arrow-outer-color;\n &:after {\n content: \" \";\n left: 1px;\n bottom: -@popover-arrow-width;\n border-left-width: 0;\n border-right-color: @popover-arrow-color;\n }\n }\n &.bottom > .arrow {\n left: 50%;\n margin-left: -@popover-arrow-outer-width;\n border-top-width: 0;\n border-bottom-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n border-bottom-color: @popover-arrow-outer-color;\n top: -@popover-arrow-outer-width;\n &:after {\n content: \" \";\n top: 1px;\n margin-left: -@popover-arrow-width;\n border-top-width: 0;\n border-bottom-color: @popover-arrow-color;\n }\n }\n\n &.left > .arrow {\n top: 50%;\n right: -@popover-arrow-outer-width;\n margin-top: -@popover-arrow-outer-width;\n border-right-width: 0;\n border-left-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n border-left-color: @popover-arrow-outer-color;\n &:after {\n content: \" \";\n right: 1px;\n border-right-width: 0;\n border-left-color: @popover-arrow-color;\n bottom: -@popover-arrow-width;\n }\n }\n}\n","//\n// Carousel\n// --------------------------------------------------\n\n\n// Wrapper for the slide container and indicators\n.carousel {\n position: relative;\n}\n\n.carousel-inner {\n position: relative;\n overflow: hidden;\n width: 100%;\n\n > .item {\n display: none;\n position: relative;\n .transition(.6s ease-in-out left);\n\n // Account for jankitude on images\n > img,\n > a > img {\n &:extend(.img-responsive);\n line-height: 1;\n }\n\n // WebKit CSS3 transforms for supported devices\n @media all and (transform-3d), (-webkit-transform-3d) {\n .transition-transform(~'0.6s ease-in-out');\n .backface-visibility(~'hidden');\n .perspective(1000);\n\n &.next,\n &.active.right {\n .translate3d(100%, 0, 0);\n left: 0;\n }\n &.prev,\n &.active.left {\n .translate3d(-100%, 0, 0);\n left: 0;\n }\n &.next.left,\n &.prev.right,\n &.active {\n .translate3d(0, 0, 0);\n left: 0;\n }\n }\n }\n\n > .active,\n > .next,\n > .prev {\n display: block;\n }\n\n > .active {\n left: 0;\n }\n\n > .next,\n > .prev {\n position: absolute;\n top: 0;\n width: 100%;\n }\n\n > .next {\n left: 100%;\n }\n > .prev {\n left: -100%;\n }\n > .next.left,\n > .prev.right {\n left: 0;\n }\n\n > .active.left {\n left: -100%;\n }\n > .active.right {\n left: 100%;\n }\n\n}\n\n// Left/right controls for nav\n// ---------------------------\n\n.carousel-control {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n width: @carousel-control-width;\n .opacity(@carousel-control-opacity);\n font-size: @carousel-control-font-size;\n color: @carousel-control-color;\n text-align: center;\n text-shadow: @carousel-text-shadow;\n // We can't have this transition here because WebKit cancels the carousel\n // animation if you trip this while in the middle of another animation.\n\n // Set gradients for backgrounds\n &.left {\n #gradient > .horizontal(@start-color: rgba(0,0,0,.5); @end-color: rgba(0,0,0,.0001));\n }\n &.right {\n left: auto;\n right: 0;\n #gradient > .horizontal(@start-color: rgba(0,0,0,.0001); @end-color: rgba(0,0,0,.5));\n }\n\n // Hover/focus state\n &:hover,\n &:focus {\n outline: 0;\n color: @carousel-control-color;\n text-decoration: none;\n .opacity(.9);\n }\n\n // Toggles\n .icon-prev,\n .icon-next,\n .glyphicon-chevron-left,\n .glyphicon-chevron-right {\n position: absolute;\n top: 50%;\n z-index: 5;\n display: inline-block;\n }\n .icon-prev,\n .glyphicon-chevron-left {\n left: 50%;\n margin-left: -10px;\n }\n .icon-next,\n .glyphicon-chevron-right {\n right: 50%;\n margin-right: -10px;\n }\n .icon-prev,\n .icon-next {\n width: 20px;\n height: 20px;\n margin-top: -10px;\n line-height: 1;\n font-family: serif;\n }\n\n\n .icon-prev {\n &:before {\n content: '\\2039';// SINGLE LEFT-POINTING ANGLE QUOTATION MARK (U+2039)\n }\n }\n .icon-next {\n &:before {\n content: '\\203a';// SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (U+203A)\n }\n }\n}\n\n// Optional indicator pips\n//\n// Add an unordered list with the following class and add a list item for each\n// slide your carousel holds.\n\n.carousel-indicators {\n position: absolute;\n bottom: 10px;\n left: 50%;\n z-index: 15;\n width: 60%;\n margin-left: -30%;\n padding-left: 0;\n list-style: none;\n text-align: center;\n\n li {\n display: inline-block;\n width: 10px;\n height: 10px;\n margin: 1px;\n text-indent: -999px;\n border: 1px solid @carousel-indicator-border-color;\n border-radius: 10px;\n cursor: pointer;\n\n // IE8-9 hack for event handling\n //\n // Internet Explorer 8-9 does not support clicks on elements without a set\n // `background-color`. We cannot use `filter` since that's not viewed as a\n // background color by the browser. Thus, a hack is needed.\n // See https://developer.mozilla.org/en-US/docs/Web/Events/click#Internet_Explorer\n //\n // For IE8, we set solid black as it doesn't support `rgba()`. For IE9, we\n // set alpha transparency for the best results possible.\n background-color: #000 \\9; // IE8\n background-color: rgba(0,0,0,0); // IE9\n }\n .active {\n margin: 0;\n width: 12px;\n height: 12px;\n background-color: @carousel-indicator-active-bg;\n }\n}\n\n// Optional captions\n// -----------------------------\n// Hidden by default for smaller viewports\n.carousel-caption {\n position: absolute;\n left: 15%;\n right: 15%;\n bottom: 20px;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: @carousel-caption-color;\n text-align: center;\n text-shadow: @carousel-text-shadow;\n & .btn {\n text-shadow: none; // No shadow for button elements in carousel-caption\n }\n}\n\n\n// Scale up controls for tablets and up\n@media screen and (min-width: @screen-sm-min) {\n\n // Scale up the controls a smidge\n .carousel-control {\n .glyphicon-chevron-left,\n .glyphicon-chevron-right,\n .icon-prev,\n .icon-next {\n width: 30px;\n height: 30px;\n margin-top: -15px;\n font-size: 30px;\n }\n .glyphicon-chevron-left,\n .icon-prev {\n margin-left: -15px;\n }\n .glyphicon-chevron-right,\n .icon-next {\n margin-right: -15px;\n }\n }\n\n // Show and left align the captions\n .carousel-caption {\n left: 20%;\n right: 20%;\n padding-bottom: 30px;\n }\n\n // Move up the indicators\n .carousel-indicators {\n bottom: 20px;\n }\n}\n","// Clearfix\n//\n// For modern browsers\n// 1. The space content is one way to avoid an Opera bug when the\n// contenteditable attribute is included anywhere else in the document.\n// Otherwise it causes space to appear at the top and bottom of elements\n// that are clearfixed.\n// 2. The use of `table` rather than `block` is only necessary if using\n// `:before` to contain the top-margins of child elements.\n//\n// Source: http://nicolasgallagher.com/micro-clearfix-hack/\n\n.clearfix() {\n &:before,\n &:after {\n content: \" \"; // 1\n display: table; // 2\n }\n &:after {\n clear: both;\n }\n}\n","// Center-align a block level element\n\n.center-block() {\n display: block;\n margin-left: auto;\n margin-right: auto;\n}\n","// CSS image replacement\n//\n// Heads up! v3 launched with with only `.hide-text()`, but per our pattern for\n// mixins being reused as classes with the same name, this doesn't hold up. As\n// of v3.0.1 we have added `.text-hide()` and deprecated `.hide-text()`.\n//\n// Source: https://github.com/h5bp/html5-boilerplate/commit/aa0396eae757\n\n// Deprecated as of v3.0.1 (will be removed in v4)\n.hide-text() {\n font: ~\"0/0\" a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n}\n\n// New mixin to use as of v3.0.1\n.text-hide() {\n .hide-text();\n}\n","//\n// Responsive: Utility classes\n// --------------------------------------------------\n\n\n// IE10 in Windows (Phone) 8\n//\n// Support for responsive views via media queries is kind of borked in IE10, for\n// Surface/desktop in split view and for Windows Phone 8. This particular fix\n// must be accompanied by a snippet of JavaScript to sniff the user agent and\n// apply some conditional CSS to *only* the Surface/desktop Windows 8. Look at\n// our Getting Started page for more information on this bug.\n//\n// For more information, see the following:\n//\n// Issue: https://github.com/twbs/bootstrap/issues/10497\n// Docs: http://getbootstrap.com/getting-started/#support-ie10-width\n// Source: http://timkadlec.com/2013/01/windows-phone-8-and-device-width/\n// Source: http://timkadlec.com/2012/10/ie10-snap-mode-and-responsive-design/\n\n@-ms-viewport {\n width: device-width;\n}\n\n\n// Visibility utilities\n// Note: Deprecated .visible-xs, .visible-sm, .visible-md, and .visible-lg as of v3.2.0\n.visible-xs,\n.visible-sm,\n.visible-md,\n.visible-lg {\n .responsive-invisibility();\n}\n\n.visible-xs-block,\n.visible-xs-inline,\n.visible-xs-inline-block,\n.visible-sm-block,\n.visible-sm-inline,\n.visible-sm-inline-block,\n.visible-md-block,\n.visible-md-inline,\n.visible-md-inline-block,\n.visible-lg-block,\n.visible-lg-inline,\n.visible-lg-inline-block {\n display: none !important;\n}\n\n.visible-xs {\n @media (max-width: @screen-xs-max) {\n .responsive-visibility();\n }\n}\n.visible-xs-block {\n @media (max-width: @screen-xs-max) {\n display: block !important;\n }\n}\n.visible-xs-inline {\n @media (max-width: @screen-xs-max) {\n display: inline !important;\n }\n}\n.visible-xs-inline-block {\n @media (max-width: @screen-xs-max) {\n display: inline-block !important;\n }\n}\n\n.visible-sm {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n .responsive-visibility();\n }\n}\n.visible-sm-block {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n display: block !important;\n }\n}\n.visible-sm-inline {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n display: inline !important;\n }\n}\n.visible-sm-inline-block {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n display: inline-block !important;\n }\n}\n\n.visible-md {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n .responsive-visibility();\n }\n}\n.visible-md-block {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n display: block !important;\n }\n}\n.visible-md-inline {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n display: inline !important;\n }\n}\n.visible-md-inline-block {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n display: inline-block !important;\n }\n}\n\n.visible-lg {\n @media (min-width: @screen-lg-min) {\n .responsive-visibility();\n }\n}\n.visible-lg-block {\n @media (min-width: @screen-lg-min) {\n display: block !important;\n }\n}\n.visible-lg-inline {\n @media (min-width: @screen-lg-min) {\n display: inline !important;\n }\n}\n.visible-lg-inline-block {\n @media (min-width: @screen-lg-min) {\n display: inline-block !important;\n }\n}\n\n.hidden-xs {\n @media (max-width: @screen-xs-max) {\n .responsive-invisibility();\n }\n}\n.hidden-sm {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n .responsive-invisibility();\n }\n}\n.hidden-md {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n .responsive-invisibility();\n }\n}\n.hidden-lg {\n @media (min-width: @screen-lg-min) {\n .responsive-invisibility();\n }\n}\n\n\n// Print utilities\n//\n// Media queries are placed on the inside to be mixin-friendly.\n\n// Note: Deprecated .visible-print as of v3.2.0\n.visible-print {\n .responsive-invisibility();\n\n @media print {\n .responsive-visibility();\n }\n}\n.visible-print-block {\n display: none !important;\n\n @media print {\n display: block !important;\n }\n}\n.visible-print-inline {\n display: none !important;\n\n @media print {\n display: inline !important;\n }\n}\n.visible-print-inline-block {\n display: none !important;\n\n @media print {\n display: inline-block !important;\n }\n}\n\n.hidden-print {\n @media print {\n .responsive-invisibility();\n }\n}\n","// Responsive utilities\n\n//\n// More easily include all the states for responsive-utilities.less.\n.responsive-visibility() {\n display: block !important;\n table& { display: table; }\n tr& { display: table-row !important; }\n th&,\n td& { display: table-cell !important; }\n}\n\n.responsive-invisibility() {\n display: none !important;\n}\n"]} \ No newline at end of file diff --git a/views/default/css/bootstrap.min.css b/views/default/css/bootstrap.min.css new file mode 100644 index 0000000..28f154d --- /dev/null +++ b/views/default/css/bootstrap.min.css @@ -0,0 +1,5 @@ +/*! + * Bootstrap v3.3.2 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + *//*! normalize.css v3.0.2 | MIT License | git.io/normalize */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}select{background:#fff!important}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=checkbox]:focus,input[type=radio]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{cursor:not-allowed;background-color:#eee;opacity:1}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date],input[type=time],input[type=datetime-local],input[type=month]{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px \9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.form-control-static{padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.form-group-sm .form-control{height:30px;line-height:30px}select[multiple].form-group-sm .form-control,textarea.form-group-sm .form-control{height:auto}.form-group-sm .form-control-static{height:30px;padding:5px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.form-group-lg .form-control{height:46px;line-height:46px}select[multiple].form-group-lg .form-control,textarea.form-group-lg .form-control{height:auto}.form-group-lg .form-control-static{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:14.33px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{pointer-events:none;cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.active,.btn-default.focus,.btn-default:active,.btn-default:focus,.btn-default:hover,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled.focus,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled].focus,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.active,.btn-primary.focus,.btn-primary:active,.btn-primary:focus,.btn-primary:hover,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled.focus,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled].focus,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.active,.btn-success.focus,.btn-success:active,.btn-success:focus,.btn-success:hover,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled.focus,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled].focus,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.active,.btn-info.focus,.btn-info:active,.btn-info:focus,.btn-info:hover,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled.focus,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled].focus,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.active,.btn-warning.focus,.btn-warning:active,.btn-warning:focus,.btn-warning:hover,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled.focus,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled].focus,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.active,.btn-danger.focus,.btn-danger:active,.btn-danger:focus,.btn-danger:hover,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled.focus,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled].focus,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none;visibility:hidden}.collapse.in{display:block;visibility:visible}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px solid;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px solid}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none;visibility:hidden}.tab-content>.active{display:block;visibility:visible}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important;visibility:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:2;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding:30px 15px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding:48px 0}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item{color:#555}a.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:absolute;top:0;right:0;left:0;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{min-height:16.43px;padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-weight:400;line-height:1.4;visibility:visible;filter:alpha(opacity=0);opacity:0}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-weight:400;line-height:1.42857143;text-align:left;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2)}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000;perspective:1000}.carousel-inner>.item.active.right,.carousel-inner>.item.next{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;margin-top:-10px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-15px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-15px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-15px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important;visibility:hidden!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}} \ No newline at end of file diff --git a/views/default/css/font-awesome.css b/views/default/css/font-awesome.css new file mode 100644 index 0000000..ee906a8 --- /dev/null +++ b/views/default/css/font-awesome.css @@ -0,0 +1,2337 @@ +/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */ +/* FONT PATH + * -------------------------- */ +@font-face { + font-family: 'FontAwesome'; + src: url('../fonts/fontawesome-webfont.eot?v=4.7.0'); + src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'), url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg'); + font-weight: normal; + font-style: normal; +} +.fa { + display: inline-block; + font: normal normal normal 14px/1 FontAwesome; + font-size: inherit; + text-rendering: auto; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +/* makes the font 33% larger relative to the icon container */ +.fa-lg { + font-size: 1.33333333em; + line-height: 0.75em; + vertical-align: -15%; +} +.fa-2x { + font-size: 2em; +} +.fa-3x { + font-size: 3em; +} +.fa-4x { + font-size: 4em; +} +.fa-5x { + font-size: 5em; +} +.fa-fw { + width: 1.28571429em; + text-align: center; +} +.fa-ul { + padding-left: 0; + margin-left: 2.14285714em; + list-style-type: none; +} +.fa-ul > li { + position: relative; +} +.fa-li { + position: absolute; + left: -2.14285714em; + width: 2.14285714em; + top: 0.14285714em; + text-align: center; +} +.fa-li.fa-lg { + left: -1.85714286em; +} +.fa-border { + padding: .2em .25em .15em; + border: solid 0.08em #eeeeee; + border-radius: .1em; +} +.fa-pull-left { + float: left; +} +.fa-pull-right { + float: right; +} +.fa.fa-pull-left { + margin-right: .3em; +} +.fa.fa-pull-right { + margin-left: .3em; +} +/* Deprecated as of 4.4.0 */ +.pull-right { + float: right; +} +.pull-left { + float: left; +} +.fa.pull-left { + margin-right: .3em; +} +.fa.pull-right { + margin-left: .3em; +} +.fa-spin { + -webkit-animation: fa-spin 2s infinite linear; + animation: fa-spin 2s infinite linear; +} +.fa-pulse { + -webkit-animation: fa-spin 1s infinite steps(8); + animation: fa-spin 1s infinite steps(8); +} +@-webkit-keyframes fa-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@keyframes fa-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +.fa-rotate-90 { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)"; + -webkit-transform: rotate(90deg); + -ms-transform: rotate(90deg); + transform: rotate(90deg); +} +.fa-rotate-180 { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2)"; + -webkit-transform: rotate(180deg); + -ms-transform: rotate(180deg); + transform: rotate(180deg); +} +.fa-rotate-270 { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)"; + -webkit-transform: rotate(270deg); + -ms-transform: rotate(270deg); + transform: rotate(270deg); +} +.fa-flip-horizontal { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)"; + -webkit-transform: scale(-1, 1); + -ms-transform: scale(-1, 1); + transform: scale(-1, 1); +} +.fa-flip-vertical { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"; + -webkit-transform: scale(1, -1); + -ms-transform: scale(1, -1); + transform: scale(1, -1); +} +:root .fa-rotate-90, +:root .fa-rotate-180, +:root .fa-rotate-270, +:root .fa-flip-horizontal, +:root .fa-flip-vertical { + filter: none; +} +.fa-stack { + position: relative; + display: inline-block; + width: 2em; + height: 2em; + line-height: 2em; + vertical-align: middle; +} +.fa-stack-1x, +.fa-stack-2x { + position: absolute; + left: 0; + width: 100%; + text-align: center; +} +.fa-stack-1x { + line-height: inherit; +} +.fa-stack-2x { + font-size: 2em; +} +.fa-inverse { + color: #ffffff; +} +/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen + readers do not read off random characters that represent icons */ +.fa-glass:before { + content: "\f000"; +} +.fa-music:before { + content: "\f001"; +} +.fa-search:before { + content: "\f002"; +} +.fa-envelope-o:before { + content: "\f003"; +} +.fa-heart:before { + content: "\f004"; +} +.fa-star:before { + content: "\f005"; +} +.fa-star-o:before { + content: "\f006"; +} +.fa-user:before { + content: "\f007"; +} +.fa-film:before { + content: "\f008"; +} +.fa-th-large:before { + content: "\f009"; +} +.fa-th:before { + content: "\f00a"; +} +.fa-th-list:before { + content: "\f00b"; +} +.fa-check:before { + content: "\f00c"; +} +.fa-remove:before, +.fa-close:before, +.fa-times:before { + content: "\f00d"; +} +.fa-search-plus:before { + content: "\f00e"; +} +.fa-search-minus:before { + content: "\f010"; +} +.fa-power-off:before { + content: "\f011"; +} +.fa-signal:before { + content: "\f012"; +} +.fa-gear:before, +.fa-cog:before { + content: "\f013"; +} +.fa-trash-o:before { + content: "\f014"; +} +.fa-home:before { + content: "\f015"; +} +.fa-file-o:before { + content: "\f016"; +} +.fa-clock-o:before { + content: "\f017"; +} +.fa-road:before { + content: "\f018"; +} +.fa-download:before { + content: "\f019"; +} +.fa-arrow-circle-o-down:before { + content: "\f01a"; +} +.fa-arrow-circle-o-up:before { + content: "\f01b"; +} +.fa-inbox:before { + content: "\f01c"; +} +.fa-play-circle-o:before { + content: "\f01d"; +} +.fa-rotate-right:before, +.fa-repeat:before { + content: "\f01e"; +} +.fa-refresh:before { + content: "\f021"; +} +.fa-list-alt:before { + content: "\f022"; +} +.fa-lock:before { + content: "\f023"; +} +.fa-flag:before { + content: "\f024"; +} +.fa-headphones:before { + content: "\f025"; +} +.fa-volume-off:before { + content: "\f026"; +} +.fa-volume-down:before { + content: "\f027"; +} +.fa-volume-up:before { + content: "\f028"; +} +.fa-qrcode:before { + content: "\f029"; +} +.fa-barcode:before { + content: "\f02a"; +} +.fa-tag:before { + content: "\f02b"; +} +.fa-tags:before { + content: "\f02c"; +} +.fa-book:before { + content: "\f02d"; +} +.fa-bookmark:before { + content: "\f02e"; +} +.fa-print:before { + content: "\f02f"; +} +.fa-camera:before { + content: "\f030"; +} +.fa-font:before { + content: "\f031"; +} +.fa-bold:before { + content: "\f032"; +} +.fa-italic:before { + content: "\f033"; +} +.fa-text-height:before { + content: "\f034"; +} +.fa-text-width:before { + content: "\f035"; +} +.fa-align-left:before { + content: "\f036"; +} +.fa-align-center:before { + content: "\f037"; +} +.fa-align-right:before { + content: "\f038"; +} +.fa-align-justify:before { + content: "\f039"; +} +.fa-list:before { + content: "\f03a"; +} +.fa-dedent:before, +.fa-outdent:before { + content: "\f03b"; +} +.fa-indent:before { + content: "\f03c"; +} +.fa-video-camera:before { + content: "\f03d"; +} +.fa-photo:before, +.fa-image:before, +.fa-picture-o:before { + content: "\f03e"; +} +.fa-pencil:before { + content: "\f040"; +} +.fa-map-marker:before { + content: "\f041"; +} +.fa-adjust:before { + content: "\f042"; +} +.fa-tint:before { + content: "\f043"; +} +.fa-edit:before, +.fa-pencil-square-o:before { + content: "\f044"; +} +.fa-share-square-o:before { + content: "\f045"; +} +.fa-check-square-o:before { + content: "\f046"; +} +.fa-arrows:before { + content: "\f047"; +} +.fa-step-backward:before { + content: "\f048"; +} +.fa-fast-backward:before { + content: "\f049"; +} +.fa-backward:before { + content: "\f04a"; +} +.fa-play:before { + content: "\f04b"; +} +.fa-pause:before { + content: "\f04c"; +} +.fa-stop:before { + content: "\f04d"; +} +.fa-forward:before { + content: "\f04e"; +} +.fa-fast-forward:before { + content: "\f050"; +} +.fa-step-forward:before { + content: "\f051"; +} +.fa-eject:before { + content: "\f052"; +} +.fa-chevron-left:before { + content: "\f053"; +} +.fa-chevron-right:before { + content: "\f054"; +} +.fa-plus-circle:before { + content: "\f055"; +} +.fa-minus-circle:before { + content: "\f056"; +} +.fa-times-circle:before { + content: "\f057"; +} +.fa-check-circle:before { + content: "\f058"; +} +.fa-question-circle:before { + content: "\f059"; +} +.fa-info-circle:before { + content: "\f05a"; +} +.fa-crosshairs:before { + content: "\f05b"; +} +.fa-times-circle-o:before { + content: "\f05c"; +} +.fa-check-circle-o:before { + content: "\f05d"; +} +.fa-ban:before { + content: "\f05e"; +} +.fa-arrow-left:before { + content: "\f060"; +} +.fa-arrow-right:before { + content: "\f061"; +} +.fa-arrow-up:before { + content: "\f062"; +} +.fa-arrow-down:before { + content: "\f063"; +} +.fa-mail-forward:before, +.fa-share:before { + content: "\f064"; +} +.fa-expand:before { + content: "\f065"; +} +.fa-compress:before { + content: "\f066"; +} +.fa-plus:before { + content: "\f067"; +} +.fa-minus:before { + content: "\f068"; +} +.fa-asterisk:before { + content: "\f069"; +} +.fa-exclamation-circle:before { + content: "\f06a"; +} +.fa-gift:before { + content: "\f06b"; +} +.fa-leaf:before { + content: "\f06c"; +} +.fa-fire:before { + content: "\f06d"; +} +.fa-eye:before { + content: "\f06e"; +} +.fa-eye-slash:before { + content: "\f070"; +} +.fa-warning:before, +.fa-exclamation-triangle:before { + content: "\f071"; +} +.fa-plane:before { + content: "\f072"; +} +.fa-calendar:before { + content: "\f073"; +} +.fa-random:before { + content: "\f074"; +} +.fa-comment:before { + content: "\f075"; +} +.fa-magnet:before { + content: "\f076"; +} +.fa-chevron-up:before { + content: "\f077"; +} +.fa-chevron-down:before { + content: "\f078"; +} +.fa-retweet:before { + content: "\f079"; +} +.fa-shopping-cart:before { + content: "\f07a"; +} +.fa-folder:before { + content: "\f07b"; +} +.fa-folder-open:before { + content: "\f07c"; +} +.fa-arrows-v:before { + content: "\f07d"; +} +.fa-arrows-h:before { + content: "\f07e"; +} +.fa-bar-chart-o:before, +.fa-bar-chart:before { + content: "\f080"; +} +.fa-twitter-square:before { + content: "\f081"; +} +.fa-facebook-square:before { + content: "\f082"; +} +.fa-camera-retro:before { + content: "\f083"; +} +.fa-key:before { + content: "\f084"; +} +.fa-gears:before, +.fa-cogs:before { + content: "\f085"; +} +.fa-comments:before { + content: "\f086"; +} +.fa-thumbs-o-up:before { + content: "\f087"; +} +.fa-thumbs-o-down:before { + content: "\f088"; +} +.fa-star-half:before { + content: "\f089"; +} +.fa-heart-o:before { + content: "\f08a"; +} +.fa-sign-out:before { + content: "\f08b"; +} +.fa-linkedin-square:before { + content: "\f08c"; +} +.fa-thumb-tack:before { + content: "\f08d"; +} +.fa-external-link:before { + content: "\f08e"; +} +.fa-sign-in:before { + content: "\f090"; +} +.fa-trophy:before { + content: "\f091"; +} +.fa-github-square:before { + content: "\f092"; +} +.fa-upload:before { + content: "\f093"; +} +.fa-lemon-o:before { + content: "\f094"; +} +.fa-phone:before { + content: "\f095"; +} +.fa-square-o:before { + content: "\f096"; +} +.fa-bookmark-o:before { + content: "\f097"; +} +.fa-phone-square:before { + content: "\f098"; +} +.fa-twitter:before { + content: "\f099"; +} +.fa-facebook-f:before, +.fa-facebook:before { + content: "\f09a"; +} +.fa-github:before { + content: "\f09b"; +} +.fa-unlock:before { + content: "\f09c"; +} +.fa-credit-card:before { + content: "\f09d"; +} +.fa-feed:before, +.fa-rss:before { + content: "\f09e"; +} +.fa-hdd-o:before { + content: "\f0a0"; +} +.fa-bullhorn:before { + content: "\f0a1"; +} +.fa-bell:before { + content: "\f0f3"; +} +.fa-certificate:before { + content: "\f0a3"; +} +.fa-hand-o-right:before { + content: "\f0a4"; +} +.fa-hand-o-left:before { + content: "\f0a5"; +} +.fa-hand-o-up:before { + content: "\f0a6"; +} +.fa-hand-o-down:before { + content: "\f0a7"; +} +.fa-arrow-circle-left:before { + content: "\f0a8"; +} +.fa-arrow-circle-right:before { + content: "\f0a9"; +} +.fa-arrow-circle-up:before { + content: "\f0aa"; +} +.fa-arrow-circle-down:before { + content: "\f0ab"; +} +.fa-globe:before { + content: "\f0ac"; +} +.fa-wrench:before { + content: "\f0ad"; +} +.fa-tasks:before { + content: "\f0ae"; +} +.fa-filter:before { + content: "\f0b0"; +} +.fa-briefcase:before { + content: "\f0b1"; +} +.fa-arrows-alt:before { + content: "\f0b2"; +} +.fa-group:before, +.fa-users:before { + content: "\f0c0"; +} +.fa-chain:before, +.fa-link:before { + content: "\f0c1"; +} +.fa-cloud:before { + content: "\f0c2"; +} +.fa-flask:before { + content: "\f0c3"; +} +.fa-cut:before, +.fa-scissors:before { + content: "\f0c4"; +} +.fa-copy:before, +.fa-files-o:before { + content: "\f0c5"; +} +.fa-paperclip:before { + content: "\f0c6"; +} +.fa-save:before, +.fa-floppy-o:before { + content: "\f0c7"; +} +.fa-square:before { + content: "\f0c8"; +} +.fa-navicon:before, +.fa-reorder:before, +.fa-bars:before { + content: "\f0c9"; +} +.fa-list-ul:before { + content: "\f0ca"; +} +.fa-list-ol:before { + content: "\f0cb"; +} +.fa-strikethrough:before { + content: "\f0cc"; +} +.fa-underline:before { + content: "\f0cd"; +} +.fa-table:before { + content: "\f0ce"; +} +.fa-magic:before { + content: "\f0d0"; +} +.fa-truck:before { + content: "\f0d1"; +} +.fa-pinterest:before { + content: "\f0d2"; +} +.fa-pinterest-square:before { + content: "\f0d3"; +} +.fa-google-plus-square:before { + content: "\f0d4"; +} +.fa-google-plus:before { + content: "\f0d5"; +} +.fa-money:before { + content: "\f0d6"; +} +.fa-caret-down:before { + content: "\f0d7"; +} +.fa-caret-up:before { + content: "\f0d8"; +} +.fa-caret-left:before { + content: "\f0d9"; +} +.fa-caret-right:before { + content: "\f0da"; +} +.fa-columns:before { + content: "\f0db"; +} +.fa-unsorted:before, +.fa-sort:before { + content: "\f0dc"; +} +.fa-sort-down:before, +.fa-sort-desc:before { + content: "\f0dd"; +} +.fa-sort-up:before, +.fa-sort-asc:before { + content: "\f0de"; +} +.fa-envelope:before { + content: "\f0e0"; +} +.fa-linkedin:before { + content: "\f0e1"; +} +.fa-rotate-left:before, +.fa-undo:before { + content: "\f0e2"; +} +.fa-legal:before, +.fa-gavel:before { + content: "\f0e3"; +} +.fa-dashboard:before, +.fa-tachometer:before { + content: "\f0e4"; +} +.fa-comment-o:before { + content: "\f0e5"; +} +.fa-comments-o:before { + content: "\f0e6"; +} +.fa-flash:before, +.fa-bolt:before { + content: "\f0e7"; +} +.fa-sitemap:before { + content: "\f0e8"; +} +.fa-umbrella:before { + content: "\f0e9"; +} +.fa-paste:before, +.fa-clipboard:before { + content: "\f0ea"; +} +.fa-lightbulb-o:before { + content: "\f0eb"; +} +.fa-exchange:before { + content: "\f0ec"; +} +.fa-cloud-download:before { + content: "\f0ed"; +} +.fa-cloud-upload:before { + content: "\f0ee"; +} +.fa-user-md:before { + content: "\f0f0"; +} +.fa-stethoscope:before { + content: "\f0f1"; +} +.fa-suitcase:before { + content: "\f0f2"; +} +.fa-bell-o:before { + content: "\f0a2"; +} +.fa-coffee:before { + content: "\f0f4"; +} +.fa-cutlery:before { + content: "\f0f5"; +} +.fa-file-text-o:before { + content: "\f0f6"; +} +.fa-building-o:before { + content: "\f0f7"; +} +.fa-hospital-o:before { + content: "\f0f8"; +} +.fa-ambulance:before { + content: "\f0f9"; +} +.fa-medkit:before { + content: "\f0fa"; +} +.fa-fighter-jet:before { + content: "\f0fb"; +} +.fa-beer:before { + content: "\f0fc"; +} +.fa-h-square:before { + content: "\f0fd"; +} +.fa-plus-square:before { + content: "\f0fe"; +} +.fa-angle-double-left:before { + content: "\f100"; +} +.fa-angle-double-right:before { + content: "\f101"; +} +.fa-angle-double-up:before { + content: "\f102"; +} +.fa-angle-double-down:before { + content: "\f103"; +} +.fa-angle-left:before { + content: "\f104"; +} +.fa-angle-right:before { + content: "\f105"; +} +.fa-angle-up:before { + content: "\f106"; +} +.fa-angle-down:before { + content: "\f107"; +} +.fa-desktop:before { + content: "\f108"; +} +.fa-laptop:before { + content: "\f109"; +} +.fa-tablet:before { + content: "\f10a"; +} +.fa-mobile-phone:before, +.fa-mobile:before { + content: "\f10b"; +} +.fa-circle-o:before { + content: "\f10c"; +} +.fa-quote-left:before { + content: "\f10d"; +} +.fa-quote-right:before { + content: "\f10e"; +} +.fa-spinner:before { + content: "\f110"; +} +.fa-circle:before { + content: "\f111"; +} +.fa-mail-reply:before, +.fa-reply:before { + content: "\f112"; +} +.fa-github-alt:before { + content: "\f113"; +} +.fa-folder-o:before { + content: "\f114"; +} +.fa-folder-open-o:before { + content: "\f115"; +} +.fa-smile-o:before { + content: "\f118"; +} +.fa-frown-o:before { + content: "\f119"; +} +.fa-meh-o:before { + content: "\f11a"; +} +.fa-gamepad:before { + content: "\f11b"; +} +.fa-keyboard-o:before { + content: "\f11c"; +} +.fa-flag-o:before { + content: "\f11d"; +} +.fa-flag-checkered:before { + content: "\f11e"; +} +.fa-terminal:before { + content: "\f120"; +} +.fa-code:before { + content: "\f121"; +} +.fa-mail-reply-all:before, +.fa-reply-all:before { + content: "\f122"; +} +.fa-star-half-empty:before, +.fa-star-half-full:before, +.fa-star-half-o:before { + content: "\f123"; +} +.fa-location-arrow:before { + content: "\f124"; +} +.fa-crop:before { + content: "\f125"; +} +.fa-code-fork:before { + content: "\f126"; +} +.fa-unlink:before, +.fa-chain-broken:before { + content: "\f127"; +} +.fa-question:before { + content: "\f128"; +} +.fa-info:before { + content: "\f129"; +} +.fa-exclamation:before { + content: "\f12a"; +} +.fa-superscript:before { + content: "\f12b"; +} +.fa-subscript:before { + content: "\f12c"; +} +.fa-eraser:before { + content: "\f12d"; +} +.fa-puzzle-piece:before { + content: "\f12e"; +} +.fa-microphone:before { + content: "\f130"; +} +.fa-microphone-slash:before { + content: "\f131"; +} +.fa-shield:before { + content: "\f132"; +} +.fa-calendar-o:before { + content: "\f133"; +} +.fa-fire-extinguisher:before { + content: "\f134"; +} +.fa-rocket:before { + content: "\f135"; +} +.fa-maxcdn:before { + content: "\f136"; +} +.fa-chevron-circle-left:before { + content: "\f137"; +} +.fa-chevron-circle-right:before { + content: "\f138"; +} +.fa-chevron-circle-up:before { + content: "\f139"; +} +.fa-chevron-circle-down:before { + content: "\f13a"; +} +.fa-html5:before { + content: "\f13b"; +} +.fa-css3:before { + content: "\f13c"; +} +.fa-anchor:before { + content: "\f13d"; +} +.fa-unlock-alt:before { + content: "\f13e"; +} +.fa-bullseye:before { + content: "\f140"; +} +.fa-ellipsis-h:before { + content: "\f141"; +} +.fa-ellipsis-v:before { + content: "\f142"; +} +.fa-rss-square:before { + content: "\f143"; +} +.fa-play-circle:before { + content: "\f144"; +} +.fa-ticket:before { + content: "\f145"; +} +.fa-minus-square:before { + content: "\f146"; +} +.fa-minus-square-o:before { + content: "\f147"; +} +.fa-level-up:before { + content: "\f148"; +} +.fa-level-down:before { + content: "\f149"; +} +.fa-check-square:before { + content: "\f14a"; +} +.fa-pencil-square:before { + content: "\f14b"; +} +.fa-external-link-square:before { + content: "\f14c"; +} +.fa-share-square:before { + content: "\f14d"; +} +.fa-compass:before { + content: "\f14e"; +} +.fa-toggle-down:before, +.fa-caret-square-o-down:before { + content: "\f150"; +} +.fa-toggle-up:before, +.fa-caret-square-o-up:before { + content: "\f151"; +} +.fa-toggle-right:before, +.fa-caret-square-o-right:before { + content: "\f152"; +} +.fa-euro:before, +.fa-eur:before { + content: "\f153"; +} +.fa-gbp:before { + content: "\f154"; +} +.fa-dollar:before, +.fa-usd:before { + content: "\f155"; +} +.fa-rupee:before, +.fa-inr:before { + content: "\f156"; +} +.fa-cny:before, +.fa-rmb:before, +.fa-yen:before, +.fa-jpy:before { + content: "\f157"; +} +.fa-ruble:before, +.fa-rouble:before, +.fa-rub:before { + content: "\f158"; +} +.fa-won:before, +.fa-krw:before { + content: "\f159"; +} +.fa-bitcoin:before, +.fa-btc:before { + content: "\f15a"; +} +.fa-file:before { + content: "\f15b"; +} +.fa-file-text:before { + content: "\f15c"; +} +.fa-sort-alpha-asc:before { + content: "\f15d"; +} +.fa-sort-alpha-desc:before { + content: "\f15e"; +} +.fa-sort-amount-asc:before { + content: "\f160"; +} +.fa-sort-amount-desc:before { + content: "\f161"; +} +.fa-sort-numeric-asc:before { + content: "\f162"; +} +.fa-sort-numeric-desc:before { + content: "\f163"; +} +.fa-thumbs-up:before { + content: "\f164"; +} +.fa-thumbs-down:before { + content: "\f165"; +} +.fa-youtube-square:before { + content: "\f166"; +} +.fa-youtube:before { + content: "\f167"; +} +.fa-xing:before { + content: "\f168"; +} +.fa-xing-square:before { + content: "\f169"; +} +.fa-youtube-play:before { + content: "\f16a"; +} +.fa-dropbox:before { + content: "\f16b"; +} +.fa-stack-overflow:before { + content: "\f16c"; +} +.fa-instagram:before { + content: "\f16d"; +} +.fa-flickr:before { + content: "\f16e"; +} +.fa-adn:before { + content: "\f170"; +} +.fa-bitbucket:before { + content: "\f171"; +} +.fa-bitbucket-square:before { + content: "\f172"; +} +.fa-tumblr:before { + content: "\f173"; +} +.fa-tumblr-square:before { + content: "\f174"; +} +.fa-long-arrow-down:before { + content: "\f175"; +} +.fa-long-arrow-up:before { + content: "\f176"; +} +.fa-long-arrow-left:before { + content: "\f177"; +} +.fa-long-arrow-right:before { + content: "\f178"; +} +.fa-apple:before { + content: "\f179"; +} +.fa-windows:before { + content: "\f17a"; +} +.fa-android:before { + content: "\f17b"; +} +.fa-linux:before { + content: "\f17c"; +} +.fa-dribbble:before { + content: "\f17d"; +} +.fa-skype:before { + content: "\f17e"; +} +.fa-foursquare:before { + content: "\f180"; +} +.fa-trello:before { + content: "\f181"; +} +.fa-female:before { + content: "\f182"; +} +.fa-male:before { + content: "\f183"; +} +.fa-gittip:before, +.fa-gratipay:before { + content: "\f184"; +} +.fa-sun-o:before { + content: "\f185"; +} +.fa-moon-o:before { + content: "\f186"; +} +.fa-archive:before { + content: "\f187"; +} +.fa-bug:before { + content: "\f188"; +} +.fa-vk:before { + content: "\f189"; +} +.fa-weibo:before { + content: "\f18a"; +} +.fa-renren:before { + content: "\f18b"; +} +.fa-pagelines:before { + content: "\f18c"; +} +.fa-stack-exchange:before { + content: "\f18d"; +} +.fa-arrow-circle-o-right:before { + content: "\f18e"; +} +.fa-arrow-circle-o-left:before { + content: "\f190"; +} +.fa-toggle-left:before, +.fa-caret-square-o-left:before { + content: "\f191"; +} +.fa-dot-circle-o:before { + content: "\f192"; +} +.fa-wheelchair:before { + content: "\f193"; +} +.fa-vimeo-square:before { + content: "\f194"; +} +.fa-turkish-lira:before, +.fa-try:before { + content: "\f195"; +} +.fa-plus-square-o:before { + content: "\f196"; +} +.fa-space-shuttle:before { + content: "\f197"; +} +.fa-slack:before { + content: "\f198"; +} +.fa-envelope-square:before { + content: "\f199"; +} +.fa-wordpress:before { + content: "\f19a"; +} +.fa-openid:before { + content: "\f19b"; +} +.fa-institution:before, +.fa-bank:before, +.fa-university:before { + content: "\f19c"; +} +.fa-mortar-board:before, +.fa-graduation-cap:before { + content: "\f19d"; +} +.fa-yahoo:before { + content: "\f19e"; +} +.fa-google:before { + content: "\f1a0"; +} +.fa-reddit:before { + content: "\f1a1"; +} +.fa-reddit-square:before { + content: "\f1a2"; +} +.fa-stumbleupon-circle:before { + content: "\f1a3"; +} +.fa-stumbleupon:before { + content: "\f1a4"; +} +.fa-delicious:before { + content: "\f1a5"; +} +.fa-digg:before { + content: "\f1a6"; +} +.fa-pied-piper-pp:before { + content: "\f1a7"; +} +.fa-pied-piper-alt:before { + content: "\f1a8"; +} +.fa-drupal:before { + content: "\f1a9"; +} +.fa-joomla:before { + content: "\f1aa"; +} +.fa-language:before { + content: "\f1ab"; +} +.fa-fax:before { + content: "\f1ac"; +} +.fa-building:before { + content: "\f1ad"; +} +.fa-child:before { + content: "\f1ae"; +} +.fa-paw:before { + content: "\f1b0"; +} +.fa-spoon:before { + content: "\f1b1"; +} +.fa-cube:before { + content: "\f1b2"; +} +.fa-cubes:before { + content: "\f1b3"; +} +.fa-behance:before { + content: "\f1b4"; +} +.fa-behance-square:before { + content: "\f1b5"; +} +.fa-steam:before { + content: "\f1b6"; +} +.fa-steam-square:before { + content: "\f1b7"; +} +.fa-recycle:before { + content: "\f1b8"; +} +.fa-automobile:before, +.fa-car:before { + content: "\f1b9"; +} +.fa-cab:before, +.fa-taxi:before { + content: "\f1ba"; +} +.fa-tree:before { + content: "\f1bb"; +} +.fa-spotify:before { + content: "\f1bc"; +} +.fa-deviantart:before { + content: "\f1bd"; +} +.fa-soundcloud:before { + content: "\f1be"; +} +.fa-database:before { + content: "\f1c0"; +} +.fa-file-pdf-o:before { + content: "\f1c1"; +} +.fa-file-word-o:before { + content: "\f1c2"; +} +.fa-file-excel-o:before { + content: "\f1c3"; +} +.fa-file-powerpoint-o:before { + content: "\f1c4"; +} +.fa-file-photo-o:before, +.fa-file-picture-o:before, +.fa-file-image-o:before { + content: "\f1c5"; +} +.fa-file-zip-o:before, +.fa-file-archive-o:before { + content: "\f1c6"; +} +.fa-file-sound-o:before, +.fa-file-audio-o:before { + content: "\f1c7"; +} +.fa-file-movie-o:before, +.fa-file-video-o:before { + content: "\f1c8"; +} +.fa-file-code-o:before { + content: "\f1c9"; +} +.fa-vine:before { + content: "\f1ca"; +} +.fa-codepen:before { + content: "\f1cb"; +} +.fa-jsfiddle:before { + content: "\f1cc"; +} +.fa-life-bouy:before, +.fa-life-buoy:before, +.fa-life-saver:before, +.fa-support:before, +.fa-life-ring:before { + content: "\f1cd"; +} +.fa-circle-o-notch:before { + content: "\f1ce"; +} +.fa-ra:before, +.fa-resistance:before, +.fa-rebel:before { + content: "\f1d0"; +} +.fa-ge:before, +.fa-empire:before { + content: "\f1d1"; +} +.fa-git-square:before { + content: "\f1d2"; +} +.fa-git:before { + content: "\f1d3"; +} +.fa-y-combinator-square:before, +.fa-yc-square:before, +.fa-hacker-news:before { + content: "\f1d4"; +} +.fa-tencent-weibo:before { + content: "\f1d5"; +} +.fa-qq:before { + content: "\f1d6"; +} +.fa-wechat:before, +.fa-weixin:before { + content: "\f1d7"; +} +.fa-send:before, +.fa-paper-plane:before { + content: "\f1d8"; +} +.fa-send-o:before, +.fa-paper-plane-o:before { + content: "\f1d9"; +} +.fa-history:before { + content: "\f1da"; +} +.fa-circle-thin:before { + content: "\f1db"; +} +.fa-header:before { + content: "\f1dc"; +} +.fa-paragraph:before { + content: "\f1dd"; +} +.fa-sliders:before { + content: "\f1de"; +} +.fa-share-alt:before { + content: "\f1e0"; +} +.fa-share-alt-square:before { + content: "\f1e1"; +} +.fa-bomb:before { + content: "\f1e2"; +} +.fa-soccer-ball-o:before, +.fa-futbol-o:before { + content: "\f1e3"; +} +.fa-tty:before { + content: "\f1e4"; +} +.fa-binoculars:before { + content: "\f1e5"; +} +.fa-plug:before { + content: "\f1e6"; +} +.fa-slideshare:before { + content: "\f1e7"; +} +.fa-twitch:before { + content: "\f1e8"; +} +.fa-yelp:before { + content: "\f1e9"; +} +.fa-newspaper-o:before { + content: "\f1ea"; +} +.fa-wifi:before { + content: "\f1eb"; +} +.fa-calculator:before { + content: "\f1ec"; +} +.fa-paypal:before { + content: "\f1ed"; +} +.fa-google-wallet:before { + content: "\f1ee"; +} +.fa-cc-visa:before { + content: "\f1f0"; +} +.fa-cc-mastercard:before { + content: "\f1f1"; +} +.fa-cc-discover:before { + content: "\f1f2"; +} +.fa-cc-amex:before { + content: "\f1f3"; +} +.fa-cc-paypal:before { + content: "\f1f4"; +} +.fa-cc-stripe:before { + content: "\f1f5"; +} +.fa-bell-slash:before { + content: "\f1f6"; +} +.fa-bell-slash-o:before { + content: "\f1f7"; +} +.fa-trash:before { + content: "\f1f8"; +} +.fa-copyright:before { + content: "\f1f9"; +} +.fa-at:before { + content: "\f1fa"; +} +.fa-eyedropper:before { + content: "\f1fb"; +} +.fa-paint-brush:before { + content: "\f1fc"; +} +.fa-birthday-cake:before { + content: "\f1fd"; +} +.fa-area-chart:before { + content: "\f1fe"; +} +.fa-pie-chart:before { + content: "\f200"; +} +.fa-line-chart:before { + content: "\f201"; +} +.fa-lastfm:before { + content: "\f202"; +} +.fa-lastfm-square:before { + content: "\f203"; +} +.fa-toggle-off:before { + content: "\f204"; +} +.fa-toggle-on:before { + content: "\f205"; +} +.fa-bicycle:before { + content: "\f206"; +} +.fa-bus:before { + content: "\f207"; +} +.fa-ioxhost:before { + content: "\f208"; +} +.fa-angellist:before { + content: "\f209"; +} +.fa-cc:before { + content: "\f20a"; +} +.fa-shekel:before, +.fa-sheqel:before, +.fa-ils:before { + content: "\f20b"; +} +.fa-meanpath:before { + content: "\f20c"; +} +.fa-buysellads:before { + content: "\f20d"; +} +.fa-connectdevelop:before { + content: "\f20e"; +} +.fa-dashcube:before { + content: "\f210"; +} +.fa-forumbee:before { + content: "\f211"; +} +.fa-leanpub:before { + content: "\f212"; +} +.fa-sellsy:before { + content: "\f213"; +} +.fa-shirtsinbulk:before { + content: "\f214"; +} +.fa-simplybuilt:before { + content: "\f215"; +} +.fa-skyatlas:before { + content: "\f216"; +} +.fa-cart-plus:before { + content: "\f217"; +} +.fa-cart-arrow-down:before { + content: "\f218"; +} +.fa-diamond:before { + content: "\f219"; +} +.fa-ship:before { + content: "\f21a"; +} +.fa-user-secret:before { + content: "\f21b"; +} +.fa-motorcycle:before { + content: "\f21c"; +} +.fa-street-view:before { + content: "\f21d"; +} +.fa-heartbeat:before { + content: "\f21e"; +} +.fa-venus:before { + content: "\f221"; +} +.fa-mars:before { + content: "\f222"; +} +.fa-mercury:before { + content: "\f223"; +} +.fa-intersex:before, +.fa-transgender:before { + content: "\f224"; +} +.fa-transgender-alt:before { + content: "\f225"; +} +.fa-venus-double:before { + content: "\f226"; +} +.fa-mars-double:before { + content: "\f227"; +} +.fa-venus-mars:before { + content: "\f228"; +} +.fa-mars-stroke:before { + content: "\f229"; +} +.fa-mars-stroke-v:before { + content: "\f22a"; +} +.fa-mars-stroke-h:before { + content: "\f22b"; +} +.fa-neuter:before { + content: "\f22c"; +} +.fa-genderless:before { + content: "\f22d"; +} +.fa-facebook-official:before { + content: "\f230"; +} +.fa-pinterest-p:before { + content: "\f231"; +} +.fa-whatsapp:before { + content: "\f232"; +} +.fa-server:before { + content: "\f233"; +} +.fa-user-plus:before { + content: "\f234"; +} +.fa-user-times:before { + content: "\f235"; +} +.fa-hotel:before, +.fa-bed:before { + content: "\f236"; +} +.fa-viacoin:before { + content: "\f237"; +} +.fa-train:before { + content: "\f238"; +} +.fa-subway:before { + content: "\f239"; +} +.fa-medium:before { + content: "\f23a"; +} +.fa-yc:before, +.fa-y-combinator:before { + content: "\f23b"; +} +.fa-optin-monster:before { + content: "\f23c"; +} +.fa-opencart:before { + content: "\f23d"; +} +.fa-expeditedssl:before { + content: "\f23e"; +} +.fa-battery-4:before, +.fa-battery:before, +.fa-battery-full:before { + content: "\f240"; +} +.fa-battery-3:before, +.fa-battery-three-quarters:before { + content: "\f241"; +} +.fa-battery-2:before, +.fa-battery-half:before { + content: "\f242"; +} +.fa-battery-1:before, +.fa-battery-quarter:before { + content: "\f243"; +} +.fa-battery-0:before, +.fa-battery-empty:before { + content: "\f244"; +} +.fa-mouse-pointer:before { + content: "\f245"; +} +.fa-i-cursor:before { + content: "\f246"; +} +.fa-object-group:before { + content: "\f247"; +} +.fa-object-ungroup:before { + content: "\f248"; +} +.fa-sticky-note:before { + content: "\f249"; +} +.fa-sticky-note-o:before { + content: "\f24a"; +} +.fa-cc-jcb:before { + content: "\f24b"; +} +.fa-cc-diners-club:before { + content: "\f24c"; +} +.fa-clone:before { + content: "\f24d"; +} +.fa-balance-scale:before { + content: "\f24e"; +} +.fa-hourglass-o:before { + content: "\f250"; +} +.fa-hourglass-1:before, +.fa-hourglass-start:before { + content: "\f251"; +} +.fa-hourglass-2:before, +.fa-hourglass-half:before { + content: "\f252"; +} +.fa-hourglass-3:before, +.fa-hourglass-end:before { + content: "\f253"; +} +.fa-hourglass:before { + content: "\f254"; +} +.fa-hand-grab-o:before, +.fa-hand-rock-o:before { + content: "\f255"; +} +.fa-hand-stop-o:before, +.fa-hand-paper-o:before { + content: "\f256"; +} +.fa-hand-scissors-o:before { + content: "\f257"; +} +.fa-hand-lizard-o:before { + content: "\f258"; +} +.fa-hand-spock-o:before { + content: "\f259"; +} +.fa-hand-pointer-o:before { + content: "\f25a"; +} +.fa-hand-peace-o:before { + content: "\f25b"; +} +.fa-trademark:before { + content: "\f25c"; +} +.fa-registered:before { + content: "\f25d"; +} +.fa-creative-commons:before { + content: "\f25e"; +} +.fa-gg:before { + content: "\f260"; +} +.fa-gg-circle:before { + content: "\f261"; +} +.fa-tripadvisor:before { + content: "\f262"; +} +.fa-odnoklassniki:before { + content: "\f263"; +} +.fa-odnoklassniki-square:before { + content: "\f264"; +} +.fa-get-pocket:before { + content: "\f265"; +} +.fa-wikipedia-w:before { + content: "\f266"; +} +.fa-safari:before { + content: "\f267"; +} +.fa-chrome:before { + content: "\f268"; +} +.fa-firefox:before { + content: "\f269"; +} +.fa-opera:before { + content: "\f26a"; +} +.fa-internet-explorer:before { + content: "\f26b"; +} +.fa-tv:before, +.fa-television:before { + content: "\f26c"; +} +.fa-contao:before { + content: "\f26d"; +} +.fa-500px:before { + content: "\f26e"; +} +.fa-amazon:before { + content: "\f270"; +} +.fa-calendar-plus-o:before { + content: "\f271"; +} +.fa-calendar-minus-o:before { + content: "\f272"; +} +.fa-calendar-times-o:before { + content: "\f273"; +} +.fa-calendar-check-o:before { + content: "\f274"; +} +.fa-industry:before { + content: "\f275"; +} +.fa-map-pin:before { + content: "\f276"; +} +.fa-map-signs:before { + content: "\f277"; +} +.fa-map-o:before { + content: "\f278"; +} +.fa-map:before { + content: "\f279"; +} +.fa-commenting:before { + content: "\f27a"; +} +.fa-commenting-o:before { + content: "\f27b"; +} +.fa-houzz:before { + content: "\f27c"; +} +.fa-vimeo:before { + content: "\f27d"; +} +.fa-black-tie:before { + content: "\f27e"; +} +.fa-fonticons:before { + content: "\f280"; +} +.fa-reddit-alien:before { + content: "\f281"; +} +.fa-edge:before { + content: "\f282"; +} +.fa-credit-card-alt:before { + content: "\f283"; +} +.fa-codiepie:before { + content: "\f284"; +} +.fa-modx:before { + content: "\f285"; +} +.fa-fort-awesome:before { + content: "\f286"; +} +.fa-usb:before { + content: "\f287"; +} +.fa-product-hunt:before { + content: "\f288"; +} +.fa-mixcloud:before { + content: "\f289"; +} +.fa-scribd:before { + content: "\f28a"; +} +.fa-pause-circle:before { + content: "\f28b"; +} +.fa-pause-circle-o:before { + content: "\f28c"; +} +.fa-stop-circle:before { + content: "\f28d"; +} +.fa-stop-circle-o:before { + content: "\f28e"; +} +.fa-shopping-bag:before { + content: "\f290"; +} +.fa-shopping-basket:before { + content: "\f291"; +} +.fa-hashtag:before { + content: "\f292"; +} +.fa-bluetooth:before { + content: "\f293"; +} +.fa-bluetooth-b:before { + content: "\f294"; +} +.fa-percent:before { + content: "\f295"; +} +.fa-gitlab:before { + content: "\f296"; +} +.fa-wpbeginner:before { + content: "\f297"; +} +.fa-wpforms:before { + content: "\f298"; +} +.fa-envira:before { + content: "\f299"; +} +.fa-universal-access:before { + content: "\f29a"; +} +.fa-wheelchair-alt:before { + content: "\f29b"; +} +.fa-question-circle-o:before { + content: "\f29c"; +} +.fa-blind:before { + content: "\f29d"; +} +.fa-audio-description:before { + content: "\f29e"; +} +.fa-volume-control-phone:before { + content: "\f2a0"; +} +.fa-braille:before { + content: "\f2a1"; +} +.fa-assistive-listening-systems:before { + content: "\f2a2"; +} +.fa-asl-interpreting:before, +.fa-american-sign-language-interpreting:before { + content: "\f2a3"; +} +.fa-deafness:before, +.fa-hard-of-hearing:before, +.fa-deaf:before { + content: "\f2a4"; +} +.fa-glide:before { + content: "\f2a5"; +} +.fa-glide-g:before { + content: "\f2a6"; +} +.fa-signing:before, +.fa-sign-language:before { + content: "\f2a7"; +} +.fa-low-vision:before { + content: "\f2a8"; +} +.fa-viadeo:before { + content: "\f2a9"; +} +.fa-viadeo-square:before { + content: "\f2aa"; +} +.fa-snapchat:before { + content: "\f2ab"; +} +.fa-snapchat-ghost:before { + content: "\f2ac"; +} +.fa-snapchat-square:before { + content: "\f2ad"; +} +.fa-pied-piper:before { + content: "\f2ae"; +} +.fa-first-order:before { + content: "\f2b0"; +} +.fa-yoast:before { + content: "\f2b1"; +} +.fa-themeisle:before { + content: "\f2b2"; +} +.fa-google-plus-circle:before, +.fa-google-plus-official:before { + content: "\f2b3"; +} +.fa-fa:before, +.fa-font-awesome:before { + content: "\f2b4"; +} +.fa-handshake-o:before { + content: "\f2b5"; +} +.fa-envelope-open:before { + content: "\f2b6"; +} +.fa-envelope-open-o:before { + content: "\f2b7"; +} +.fa-linode:before { + content: "\f2b8"; +} +.fa-address-book:before { + content: "\f2b9"; +} +.fa-address-book-o:before { + content: "\f2ba"; +} +.fa-vcard:before, +.fa-address-card:before { + content: "\f2bb"; +} +.fa-vcard-o:before, +.fa-address-card-o:before { + content: "\f2bc"; +} +.fa-user-circle:before { + content: "\f2bd"; +} +.fa-user-circle-o:before { + content: "\f2be"; +} +.fa-user-o:before { + content: "\f2c0"; +} +.fa-id-badge:before { + content: "\f2c1"; +} +.fa-drivers-license:before, +.fa-id-card:before { + content: "\f2c2"; +} +.fa-drivers-license-o:before, +.fa-id-card-o:before { + content: "\f2c3"; +} +.fa-quora:before { + content: "\f2c4"; +} +.fa-free-code-camp:before { + content: "\f2c5"; +} +.fa-telegram:before { + content: "\f2c6"; +} +.fa-thermometer-4:before, +.fa-thermometer:before, +.fa-thermometer-full:before { + content: "\f2c7"; +} +.fa-thermometer-3:before, +.fa-thermometer-three-quarters:before { + content: "\f2c8"; +} +.fa-thermometer-2:before, +.fa-thermometer-half:before { + content: "\f2c9"; +} +.fa-thermometer-1:before, +.fa-thermometer-quarter:before { + content: "\f2ca"; +} +.fa-thermometer-0:before, +.fa-thermometer-empty:before { + content: "\f2cb"; +} +.fa-shower:before { + content: "\f2cc"; +} +.fa-bathtub:before, +.fa-s15:before, +.fa-bath:before { + content: "\f2cd"; +} +.fa-podcast:before { + content: "\f2ce"; +} +.fa-window-maximize:before { + content: "\f2d0"; +} +.fa-window-minimize:before { + content: "\f2d1"; +} +.fa-window-restore:before { + content: "\f2d2"; +} +.fa-times-rectangle:before, +.fa-window-close:before { + content: "\f2d3"; +} +.fa-times-rectangle-o:before, +.fa-window-close-o:before { + content: "\f2d4"; +} +.fa-bandcamp:before { + content: "\f2d5"; +} +.fa-grav:before { + content: "\f2d6"; +} +.fa-etsy:before { + content: "\f2d7"; +} +.fa-imdb:before { + content: "\f2d8"; +} +.fa-ravelry:before { + content: "\f2d9"; +} +.fa-eercast:before { + content: "\f2da"; +} +.fa-microchip:before { + content: "\f2db"; +} +.fa-snowflake-o:before { + content: "\f2dc"; +} +.fa-superpowers:before { + content: "\f2dd"; +} +.fa-wpexplorer:before { + content: "\f2de"; +} +.fa-meetup:before { + content: "\f2e0"; +} +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; +} +.sr-only-focusable:active, +.sr-only-focusable:focus { + position: static; + width: auto; + height: auto; + margin: 0; + overflow: visible; + clip: auto; +} diff --git a/views/default/css/font-awesome.min.css b/views/default/css/font-awesome.min.css new file mode 100644 index 0000000..540440c --- /dev/null +++ b/views/default/css/font-awesome.min.css @@ -0,0 +1,4 @@ +/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.7.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}.fa-gitlab:before{content:"\f296"}.fa-wpbeginner:before{content:"\f297"}.fa-wpforms:before{content:"\f298"}.fa-envira:before{content:"\f299"}.fa-universal-access:before{content:"\f29a"}.fa-wheelchair-alt:before{content:"\f29b"}.fa-question-circle-o:before{content:"\f29c"}.fa-blind:before{content:"\f29d"}.fa-audio-description:before{content:"\f29e"}.fa-volume-control-phone:before{content:"\f2a0"}.fa-braille:before{content:"\f2a1"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:"\f2a4"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-signing:before,.fa-sign-language:before{content:"\f2a7"}.fa-low-vision:before{content:"\f2a8"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-pied-piper:before{content:"\f2ae"}.fa-first-order:before{content:"\f2b0"}.fa-yoast:before{content:"\f2b1"}.fa-themeisle:before{content:"\f2b2"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:"\f2b3"}.fa-fa:before,.fa-font-awesome:before{content:"\f2b4"}.fa-handshake-o:before{content:"\f2b5"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-o:before{content:"\f2b7"}.fa-linode:before{content:"\f2b8"}.fa-address-book:before{content:"\f2b9"}.fa-address-book-o:before{content:"\f2ba"}.fa-vcard:before,.fa-address-card:before{content:"\f2bb"}.fa-vcard-o:before,.fa-address-card-o:before{content:"\f2bc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-circle-o:before{content:"\f2be"}.fa-user-o:before{content:"\f2c0"}.fa-id-badge:before{content:"\f2c1"}.fa-drivers-license:before,.fa-id-card:before{content:"\f2c2"}.fa-drivers-license-o:before,.fa-id-card-o:before{content:"\f2c3"}.fa-quora:before{content:"\f2c4"}.fa-free-code-camp:before{content:"\f2c5"}.fa-telegram:before{content:"\f2c6"}.fa-thermometer-4:before,.fa-thermometer:before,.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-thermometer-2:before,.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:"\f2cb"}.fa-shower:before{content:"\f2cc"}.fa-bathtub:before,.fa-s15:before,.fa-bath:before{content:"\f2cd"}.fa-podcast:before{content:"\f2ce"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-times-rectangle:before,.fa-window-close:before{content:"\f2d3"}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:"\f2d4"}.fa-bandcamp:before{content:"\f2d5"}.fa-grav:before{content:"\f2d6"}.fa-etsy:before{content:"\f2d7"}.fa-imdb:before{content:"\f2d8"}.fa-ravelry:before{content:"\f2d9"}.fa-eercast:before{content:"\f2da"}.fa-microchip:before{content:"\f2db"}.fa-snowflake-o:before{content:"\f2dc"}.fa-superpowers:before{content:"\f2dd"}.fa-wpexplorer:before{content:"\f2de"}.fa-meetup:before{content:"\f2e0"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto} diff --git a/views/default/css/footer.css b/views/default/css/footer.css new file mode 100644 index 0000000..4546cf3 --- /dev/null +++ b/views/default/css/footer.css @@ -0,0 +1,15 @@ + + +.footer { + position: relative; + bottom: 0; + height: auto; + background-color: #e7e7e7; + width: 100%; + max-width: 1480px; + + +} + + + diff --git a/views/default/css/timeline.css b/views/default/css/timeline.css new file mode 100644 index 0000000..df13a4b --- /dev/null +++ b/views/default/css/timeline.css @@ -0,0 +1,139 @@ +.timeline { + list-style: none; + padding: 20px 0 20px; + position: relative; +} +.timeline:before { + top: 0; + bottom: 0; + position: absolute; + content: " "; + width: 2px; + background-color: #CCCCCC; + left: 25px; + margin-left: -1.5px; +} +.timeline > li { + margin-bottom: 20px; + position: relative; +} +.timeline > li:before, +.timeline > li:after { + content: " "; + display: table; +} +.timeline > li:after { + clear: both; +} +.timeline > li:before, +.timeline > li:after { + content: " "; + display: table; +} +.timeline > li:after { + clear: both; +} +.timeline > li > .timeline-panel { + width: calc( 100% - 55px ); + float: right; + border: 1px solid #d4d4d4; + border-radius: 22px; + padding: 10px; + position: relative; + -webkit-box-shadow: 0 1px 6px rgba(0, 0, 0, 0.175); + box-shadow: 0 1px 6px rgba(0, 0, 0, 0.175); +} +.timeline > li > .timeline-panel:before { + position: absolute; + top: 26px; + left: -15px; + display: inline-block; +} +.timeline > li > .timeline-panel:after { + position: absolute; + top: 27px; + left: -14px; + display: inline-block; +} +.timeline > li > .timeline-badge { + + width: 25px; + height: 25px; + line-height: 25px; + font-size: 1.4em; + text-align: center; + position: absolute; + top: 16px; + left: 13px; + + + z-index: 100; + border-top-right-radius: 50%; + border-top-left-radius: 50%; + border-bottom-right-radius: 50%; + border-bottom-left-radius: 50%; +} +.timeline > li.timeline-inverted > .timeline-panel { + float: left; +} +.timeline > li.timeline-inverted > .timeline-panel:before { + border-left-width: 0; + border-right-width: 15px; + right: -15px; + right: auto; +} +.timeline > li.timeline-inverted > .timeline-panel:after { + border-left-width: 0; + border-right-width: 14px; + left: -14px; + right: auto; +} + +.timeline-title { + margin-top: 0; + color: inherit; +} +.timeline-body > p, +.timeline-body > ul { + margin-bottom: 0; +} +.timeline-body > p + p { + margin-top: 5px; +} + + + +.timelineBar { + width: 2px; + background-color: #BDBDBD; + display: inline-block; + position: absolute; + height: 100%; + left: 34.5%; + margin-left: 10px; + margin-right: 10px; +} +.shadowBox { + box-shadow: rgba(0, 0, 0, 0.796875) 0px 0px 2px; + -webkit-box-shadow: rgba(0, 0, 0, 0.796875) 0px 0px 2px; + border:2px solid white; + border-radius: 10px; + margin: 10px; + background-color: #FFFFFF; +} +.timelineDot{ + width: 10px; + height: 10px; + background-color: #BDBDBD; + opacity: 1; + display: inline-block; + position: static; + left: 34.5%; + + margin-left: 6px; + border-radius: 10px; +} + +.right{ + text-align: right; +} \ No newline at end of file diff --git a/views/default/edit.html b/views/default/edit.html new file mode 100644 index 0000000..c9bb965 --- /dev/null +++ b/views/default/edit.html @@ -0,0 +1,130 @@ +<!DOCTYPE html> +<html lang="ru"> + <head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <title>Home</title> + + <!-- Bootstrap --> + <link href="css/bootstrap.css" rel="stylesheet"> + <link rel="stylesheet" href="css/font-awesome.css"> + <link href="css/bootstrap-responsive.css" rel="stylesheet"> + <link href="css/footer.css" rel="stylesheet"> + <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries --> + <!-- WARNING: Respond.js doesn't work if you view the page via file:// --> + <!--[if lt IE 9]> + <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> + <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script> + <![endif]--> + </head> + <body> + <div class="container"> + <header> + <nav role="navigation" class="navbar navbar-default"> + <!-- Brand and toggle get grouped for better mobile display --> + <div class="navbar-header"> + <button type="button" data-target="#navbarCollapse" data-toggle="collapse" class="navbar-toggle"> + <span class="sr-only">Toggle navigation</span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + <a href="#" class="navbar-brand">Бренд</a> + </div> + <!-- Collection of nav links, forms, and other content for toggling --> + <div id="navbarCollapse" class="collapse navbar-collapse"> + <ul class="nav navbar-nav"> + <li class="active"><a href="#">Главная</a></li> + <li class="dropdown"> + <a data-toggle="dropdown" class="dropdown-toggle" href="#"><i class="fa fa-paint-brush" aria-hidden="true"></i> Cartriges <b class="caret"></b></a> + <ul role="menu" class="dropdown-menu"> + <li><a href="#">add</a></li> + <li><a href="#">Remove</a></li> + <li><a href="#">order</a></li> + <li><a href="#">hestory</a></li> + </ul> + </li> + <li class="dropdown"> + <a data-toggle="dropdown" class="dropdown-toggle" href="#"><i class="fa fa-print" aria-hidden="true"></i> Prints <b class="caret"></b></a> + <ul role="menu" class="dropdown-menu"> + <li><a href="#">search</a></li> + <li><a href="#">add</a></li> + <li><a href="#">edit</a></li> + <li class="divider"></li> + <li><a href="#">delete</a></li> + </ul> + </li> + <li class="dropdown"> + <a data-toggle="dropdown" class="dropdown-toggle" href="#"><i class="fa fa-wrench" aria-hidden="true"></i> Unit <b class="caret"></b></a> + <ul role="menu" class="dropdown-menu"> + <li><a href="#">history requests</a></li> + <li><a href="#">history repairs</a></li> + <li><a href="#">create requests</a></li> + <li class="divider"></li> + <li><a href="#">doc stor</a></li> + </ul> + </li> + </ul> + <ul class="nav navbar-nav navbar-right"> + <li><a href="#"><i class="fa fa-lock" aria-hidden="true"></i> Войти / <i class="fa fa-sign-out" aria-hidden="true"></i></a></li> + </ul> + </div> + </nav> + +</header> +<main> + <div class="row"> + <div class="col-md-3 col-md-offset-2"> + <img src="img/3030.jpg" alt="..." class="img-thumbnail"> + </div> + <div class="col-md-5"> + <p class="text-align"> + <h4>ID <strong>1</strong></h4> + <input type="text" class="form-control" placeholder="Name" value="132"><br> + <input type="text" class="form-control" placeholder="#Unit"><br> + <input type="text" class="form-control" placeholder="Model"><br> + <input type="text" class="form-control" placeholder="Серийный"><br> + <input type="text" class="form-control" placeholder="Инвентарный"><br> + <select class="form-control"> + <option selected>Этаж</option> + <option value="">111</option> + <option value="">222</option> + <option value="">333</option> + </select><br> + <select class="form-control"> + <option selected>Отдел</option> + <option value="">111</option> + <option value="">222</option> + <option value="">333</option> + </select><br> + <select class="form-control"> + <option selected>Картридж</option> + <option value="">111</option> + <option value="">222</option> + <option value="">333</option> + </select><br> + <select class="form-control"> + <option selected>Статус</option> + <option value="">111</option> + <option value="">222</option> + <option value="">333</option> + </select><br> + <input type="text" class="form-control" placeholder="Функционал"> + <hr> + <br> + </p> + </div> + </div> + </main> + <!--Футер--> + <footer> + <p >info by IT Kursk</p> + </footer> +</div> + <!-- jQuery (necessary for Bootstrap's JavaScript plugins) --> + <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> + <!-- Include all compiled plugins (below), or include individual files as needed --> + <script src="js/bootstrap.js"></script> + </body> +</html> \ No newline at end of file diff --git a/views/default/edit_print.php b/views/default/edit_print.php new file mode 100644 index 0000000..7691c1c --- /dev/null +++ b/views/default/edit_print.php @@ -0,0 +1,127 @@ +<?php include ROOT . TMPL . 'header.php'; ?> + + <div class="row"> + <div class="col-md-4"> + <?php if($print['img'] != ""): ?> + <img class="img-responsive" src="<?php echo $print['img']; ?>" alt="..."> + <?php else: ?> + <img class="img-responsive" src="/img/not_img_print.png" alt="..."> + <?php endif; ?> + <!-- Кнопка, вызывающее модальное окно --> + <br><a href="#up_img_print" class="btn btn-primary" data-toggle="modal">Сменить изображение</a> + <!-- HTML-код модального окна --> + <div id="up_img_print" class="modal fade"> + <div class="modal-dialog"> + <div class="modal-content"> + <!-- Заголовок модального окна --> + <div class="modal-header"> + <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> + <h4 class="modal-title">Upload image by printer</h4> + </div> + <!-- Основное содержимое модального окна --> + <div class="modal-body"> + <form enctype="multipart/form-data" action="/imgupload" method="post" name="upload"> + <input name="print_id" type="hidden" value="<?php echo $print['id']; ?>"/> + <input name="img" type="file" /> + </div> + <!-- Футер модального окна --> + <div class="modal-footer"> + <button type="button" class="btn btn-default" data-dismiss="modal">Закрыть</button> + <button type="submit" class="btn btn-primary" name="upload">Сохранить изображение</button> + </form> + </div> + </div> + </div> + </div> + + </div> + <div class="col-md-8"> + <?php if(Printer::message() != false): ?> + <?php if($_SESSION['message'] == "good"): ?> + <!-- Сообщение об успешном выполнения действия --> + <div class="alert alert-success"> + <!-- Кнопка для закрытия сообщения, созданная с помощью элемента button --> + <button type="button" class="close" data-dismiss="alert">×</button> + Изменения сохранены. + </div> + + <?php else: ?> + <!-- Сообщение об ошибке --> + <div class="alert alert-danger"> + <!-- Кнопка для закрытия сообщения, созданная с помощью элемента a --> + <a href="#" class="close" data-dismiss="alert">×</a> + Неизвестная ошибка при передаче данных. + </div> + <?php endif; ?> + <?php endif; ?> + <form action="" method="post"> + <h4>ID <strong><?php echo $print['id']; ?></strong></h4><br> + <input type="text" class="form-control" name="name" placeholder="Name" value="<?php echo $print['name']; ?>"><br> + <input type="text" class="form-control" name="unit" placeholder="#Unit" value="<?php echo $print['unit']; ?>"><br> + <input type="text" class="form-control" name="model" placeholder="Model" value="<?php echo $print['model']; ?>"><br> + <input type="text" class="form-control" name="sn" placeholder="Серийный" value="<?php echo $print['sn']; ?>"><br> + <input type="text" class="form-control" name="inventar" placeholder="Инвентарный" value="<?php echo $print['inventar']; ?>"><br> + + <select class="form-control" name="id_floor" > + <option selected>Этаж</option> + <?php foreach($floor as $fl): ?> + <option value="<?php echo $fl['id']; ?>" <?php if($print['id_fl'] == $fl['id']) echo "selected"; ?>><?php echo $fl['name']; ?></option> + <?php endforeach; ?> + + </select><br> + <select class="form-control" name="id_department" > + <option selected>Отдел</option> + <?php foreach($department as $dp): ?> + <option value="<?php echo $dp['id']; ?>" <?php if($print['id_dep'] == $dp['id']) echo "selected"; ?>><?php echo $dp['name']; ?></option> + <?php endforeach; ?> + </select><br> + <select class="form-control" name="id_cartrige" > + <option selected>Картридж</option> + <?php foreach($cartrige as $c): ?> + <option value="<?php echo $c['id']; ?>" <?php if($print['id_cart'] == $c['id']) echo "selected"; ?>><?php echo $c['name']; ?></option> + <?php endforeach; ?> + </select><br> + <select class="form-control" name="id_status" > + <option selected>Статус</option> + <?php foreach($status as $st): ?> + <option value="<?php echo $st['id']; ?>" <?php if($print['id_st'] == $st['id']) echo "selected"; ?>><?php echo $st['name']; ?></option> + <?php endforeach; ?> + </select><br> + <label>Функционал</label> + + <table> + <tr> + <td> + <select id="src_countries" style="width:270px" class='select form-control' multiple="multiple" size="10"> + <option disabled selected>Выберите функцию</option> + <?php foreach($functions as $fn): ?> + <option value="<?php echo $fn['id']; ?>"><?php echo $fn['name']; ?></option> <!-- <?php //if($print['functions'][$i]['id'] == $fn['id']) echo "selected"; ?>--> + <?php endforeach; ?> + </select> + </td> + <td> + <p><button type="button" id="take" >&gt;&gt;</button></p> + <p><button type="button" id="drop" >&lt;&lt;</button></p> + </td> + <td> + <select name="id_functions[]" id="dst_countries" style="width:270px" multiple="multiple" size="10" class='select form-control'> + <option disabled selected>Выбраные функции</option> + <?php if($print['functions'] != "Отсутствует"):?> + <?php for($i=0; $i < count($print['functions']); $i++): ?> + <option value="<?php echo $print['functions'][$i]['id']; ?>"><?php echo $print['functions'][$i]['name']; ?></option> + <?php endfor; ?> + <?php endif; ?> + </select> + </td> + </tr> + </table> + <br> + <button type="submit" name="submit" class="btn btn-primary">Save</button> + </form> + </div> + </div> + + + <hr> + <br> +<?php include ROOT . TMPL . 'footer.php'; ?> \ No newline at end of file diff --git a/views/default/edit_print_1.php b/views/default/edit_print_1.php new file mode 100644 index 0000000..6c3ccb8 --- /dev/null +++ b/views/default/edit_print_1.php @@ -0,0 +1,100 @@ +<?php include ROOT . TMPL . 'header.php'; ?> + + <div class="row"> + <div class="col-md-4"> + <?php if($print['img'] != ""): ?> + <img class="img-responsive" src="/img/<?php echo $print['img']; ?>" alt="..."> + <?php else: ?> + <img class="img-responsive" src="/img/print.png" alt="..."> + <?php endif; ?> + <br><button type="submit" class="btn btn-primary">Сменить изображение</button> + </div> + <div class="col-md-8"> + <form action="" method="post"> + <h4>ID <strong><?php echo $print['id']; ?></strong></h4><br> + <input type="text" class="form-control" name="name" placeholder="Name" value="<?php echo $print['name']; ?>"><br> + <input type="text" class="form-control" name="unit" placeholder="#Unit" value="<?php echo $print['unit']; ?>"><br> + <input type="text" class="form-control" name="model" placeholder="Model" value="<?php echo $print['model']; ?>"><br> + <input type="text" class="form-control" name="sn" placeholder="Серийный" value="<?php echo $print['sn']; ?>"><br> + <input type="text" class="form-control" name="inventar" placeholder="Инвентарный" value="<?php echo $print['inventar']; ?>"><br> + + <select class="form-control" name="id_floor" > + <option selected>Этаж</option> + <?php foreach($floor as $fl): ?> + <option value="<?php echo $fl['id']; ?>" <?php if($print['id_fl'] == $fl['id']) echo "selected"; ?>><?php echo $fl['name']; ?></option> + <?php endforeach; ?> + + </select><br> + <select class="form-control" name="id_department" > + <option selected>Отдел</option> + <?php foreach($department as $dp): ?> + <option value="<?php echo $dp['id']; ?>" <?php if($print['id_dep'] == $dp['id']) echo "selected"; ?>><?php echo $dp['name']; ?></option> + <?php endforeach; ?> + </select><br> + <select class="form-control" name="id_cartrige" > + <option selected>Картридж</option> + <?php foreach($cartrige as $c): ?> + <option value="<?php echo $c['id']; ?>" <?php if($print['id_cart'] == $c['id']) echo "selected"; ?>><?php echo $c['name']; ?></option> + <?php endforeach; ?> + </select><br> + <select class="form-control" name="id_status" > + <option selected>Статус</option> + <?php foreach($status as $st): ?> + <option value="<?php echo $st['id']; ?>" <?php if($print['id_st'] == $st['id']) echo "selected"; ?>><?php echo $st['name']; ?></option> + <?php endforeach; ?> + </select><br> + <label>Функционал</label> + <?php if(!is_array($print['functions'])): ?> + функций нет + <table class="table"> + <tbody id="dynamic"> + <tr> + <td> + <select class='select form-control' name="id_functions"> + <option disabled selected>Выберите функцию</option> + <?php foreach($functions as $fn): ?> + <option value="<?php echo $fn['id']; ?>"><?php echo $fn['name']; ?></option> + <?php endforeach; ?> + </select> + </td> + <td> + <button type="button" class="add">+</button> + <button type="button" class="del">-</button> + </td> + </tr> + </tbody> + </table> + <?php else: ?> + <table class="table"> + <tbody id="dynamic"> + <!-- ЭТА СТРОКА БУДЕТ ШАБЛОНОМ ДЛЯ ВНОВЬ СОЗДАВАЕМЫХ //--> + <?php for($i=0; $i < count($print['functions']); $i++): ?> + <tr> + <td> + <select class='select form-control' name="id_functions"> + <option disabled selected>Выберите функцию</option> + <?php foreach($functions as $fn): ?> + <option value="<?php echo $fn['id']; ?>" <?php if($print['functions'][$i]['id'] == $fn['id']) echo "selected"; ?>><?php echo $fn['name']; ?></option> + <?php endforeach; ?> + </select> + </td> + <td> + <button type="button" class="add">+</button> + <button type="button" class="del">-</button> + </td> + </tr> + <?php endfor; ?> + <!-- конец СТРОКи БУДЕТ ШАБЛОНОМ ДЛЯ ВНОВЬ СОЗДАВАЕМЫХ //--> + </tbody> + </table> + <?php endif; ?> + <br> + <button type="submit" name="submit" class="btn btn-primary">Save</button> + </form> + </div> + </div> + + + <hr> + <br> +<?php include ROOT . TMPL . 'footer.php'; ?> \ No newline at end of file diff --git a/views/default/error.php b/views/default/error.php new file mode 100644 index 0000000..7041db6 --- /dev/null +++ b/views/default/error.php @@ -0,0 +1,4 @@ +<?php +echo "Ошибка в том что ты вообще родился"; +echo "Страницы " .$er. " не существует"; + diff --git a/views/default/fonts/FontAwesome.otf b/views/default/fonts/FontAwesome.otf new file mode 100644 index 0000000..401ec0f Binary files /dev/null and b/views/default/fonts/FontAwesome.otf differ diff --git a/views/default/fonts/fontawesome-webfont.eot b/views/default/fonts/fontawesome-webfont.eot new file mode 100644 index 0000000..e9f60ca Binary files /dev/null and b/views/default/fonts/fontawesome-webfont.eot differ diff --git a/views/default/fonts/fontawesome-webfont.svg b/views/default/fonts/fontawesome-webfont.svg new file mode 100644 index 0000000..855c845 --- /dev/null +++ b/views/default/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ +<?xml version="1.0" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" > +<svg> +<metadata> +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. +</metadata> +<defs> +<font id="FontAwesome" horiz-adv-x="1536" > + <font-face + font-family="FontAwesome" + font-weight="400" + font-stretch="normal" + units-per-em="1792" + panose-1="0 0 0 0 0 0 0 0 0 0" + ascent="1536" + descent="-256" + bbox="-1.02083 -256.962 2304.6 1537.02" + underline-thickness="0" + underline-position="0" + unicode-range="U+0020-F500" + /> +<missing-glyph horiz-adv-x="896" +d="M224 112h448v1312h-448v-1312zM112 0v1536h672v-1536h-672z" /> + <glyph glyph-name=".notdef" horiz-adv-x="896" +d="M224 112h448v1312h-448v-1312zM112 0v1536h672v-1536h-672z" /> + <glyph glyph-name=".null" horiz-adv-x="0" + /> + <glyph glyph-name="nonmarkingreturn" horiz-adv-x="597" + /> + <glyph glyph-name="space" unicode=" " horiz-adv-x="448" + /> + <glyph glyph-name="dieresis" unicode="&#xa8;" horiz-adv-x="1792" + /> + <glyph glyph-name="copyright" unicode="&#xa9;" horiz-adv-x="1792" + /> + <glyph glyph-name="registered" unicode="&#xae;" horiz-adv-x="1792" + /> + <glyph glyph-name="acute" unicode="&#xb4;" horiz-adv-x="1792" + /> + <glyph glyph-name="AE" unicode="&#xc6;" horiz-adv-x="1792" + /> + <glyph glyph-name="Oslash" unicode="&#xd8;" horiz-adv-x="1792" + /> + <glyph glyph-name="trademark" unicode="&#x2122;" horiz-adv-x="1792" + /> + <glyph glyph-name="infinity" unicode="&#x221e;" horiz-adv-x="1792" + /> + <glyph glyph-name="notequal" unicode="&#x2260;" horiz-adv-x="1792" + /> + <glyph glyph-name="glass" unicode="&#xf000;" horiz-adv-x="1792" +d="M1699 1350q0 -35 -43 -78l-632 -632v-768h320q26 0 45 -19t19 -45t-19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45t45 19h320v768l-632 632q-43 43 -43 78q0 23 18 36.5t38 17.5t43 4h1408q23 0 43 -4t38 -17.5t18 -36.5z" /> + <glyph glyph-name="music" unicode="&#xf001;" +d="M1536 1312v-1120q0 -50 -34 -89t-86 -60.5t-103.5 -32t-96.5 -10.5t-96.5 10.5t-103.5 32t-86 60.5t-34 89t34 89t86 60.5t103.5 32t96.5 10.5q105 0 192 -39v537l-768 -237v-709q0 -50 -34 -89t-86 -60.5t-103.5 -32t-96.5 -10.5t-96.5 10.5t-103.5 32t-86 60.5t-34 89 +t34 89t86 60.5t103.5 32t96.5 10.5q105 0 192 -39v967q0 31 19 56.5t49 35.5l832 256q12 4 28 4q40 0 68 -28t28 -68z" /> + <glyph glyph-name="search" unicode="&#xf002;" horiz-adv-x="1664" +d="M1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5zM1664 -128q0 -52 -38 -90t-90 -38q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5 +t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z" /> + <glyph glyph-name="envelope" unicode="&#xf003;" horiz-adv-x="1792" +d="M1664 32v768q-32 -36 -69 -66q-268 -206 -426 -338q-51 -43 -83 -67t-86.5 -48.5t-102.5 -24.5h-1h-1q-48 0 -102.5 24.5t-86.5 48.5t-83 67q-158 132 -426 338q-37 30 -69 66v-768q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5zM1664 1083v11v13.5t-0.5 13 +t-3 12.5t-5.5 9t-9 7.5t-14 2.5h-1472q-13 0 -22.5 -9.5t-9.5 -22.5q0 -168 147 -284q193 -152 401 -317q6 -5 35 -29.5t46 -37.5t44.5 -31.5t50.5 -27.5t43 -9h1h1q20 0 43 9t50.5 27.5t44.5 31.5t46 37.5t35 29.5q208 165 401 317q54 43 100.5 115.5t46.5 131.5z +M1792 1120v-1088q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1472q66 0 113 -47t47 -113z" /> + <glyph glyph-name="heart" unicode="&#xf004;" horiz-adv-x="1792" +d="M896 -128q-26 0 -44 18l-624 602q-10 8 -27.5 26t-55.5 65.5t-68 97.5t-53.5 121t-23.5 138q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5q224 0 351 -124t127 -344q0 -221 -229 -450l-623 -600 +q-18 -18 -44 -18z" /> + <glyph glyph-name="star" unicode="&#xf005;" horiz-adv-x="1664" +d="M1664 889q0 -22 -26 -48l-363 -354l86 -500q1 -7 1 -20q0 -21 -10.5 -35.5t-30.5 -14.5q-19 0 -40 12l-449 236l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41t49 -41l225 -455 +l502 -73q56 -9 56 -46z" /> + <glyph glyph-name="star_empty" unicode="&#xf006;" horiz-adv-x="1664" +d="M1137 532l306 297l-422 62l-189 382l-189 -382l-422 -62l306 -297l-73 -421l378 199l377 -199zM1664 889q0 -22 -26 -48l-363 -354l86 -500q1 -7 1 -20q0 -50 -41 -50q-19 0 -40 12l-449 236l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500 +l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41t49 -41l225 -455l502 -73q56 -9 56 -46z" /> + <glyph glyph-name="user" unicode="&#xf007;" horiz-adv-x="1280" +d="M1280 137q0 -109 -62.5 -187t-150.5 -78h-854q-88 0 -150.5 78t-62.5 187q0 85 8.5 160.5t31.5 152t58.5 131t94 89t134.5 34.5q131 -128 313 -128t313 128q76 0 134.5 -34.5t94 -89t58.5 -131t31.5 -152t8.5 -160.5zM1024 1024q0 -159 -112.5 -271.5t-271.5 -112.5 +t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5z" /> + <glyph glyph-name="film" unicode="&#xf008;" horiz-adv-x="1920" +d="M384 -64v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM384 320v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM384 704v128q0 26 -19 45t-45 19h-128 +q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1408 -64v512q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-512q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM384 1088v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45 +t45 -19h128q26 0 45 19t19 45zM1792 -64v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1408 704v512q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-512q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM1792 320v128 +q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1792 704v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1792 1088v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19 +t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1920 1248v-1344q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1344q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" /> + <glyph glyph-name="th_large" unicode="&#xf009;" horiz-adv-x="1664" +d="M768 512v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM768 1280v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM1664 512v-384q0 -52 -38 -90t-90 -38 +h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM1664 1280v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90z" /> + <glyph glyph-name="th" unicode="&#xf00a;" horiz-adv-x="1792" +d="M512 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 288v-192q0 -40 -28 -68t-68 -28h-320 +q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28 +h320q40 0 68 -28t28 -68zM1792 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 800v-192 +q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68z" /> + <glyph glyph-name="th_list" unicode="&#xf00b;" horiz-adv-x="1792" +d="M512 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 288v-192q0 -40 -28 -68t-68 -28h-960 +q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h960q40 0 68 -28t28 -68zM512 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 800v-192q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v192q0 40 28 68t68 28 +h960q40 0 68 -28t28 -68zM1792 1312v-192q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h960q40 0 68 -28t28 -68z" /> + <glyph glyph-name="ok" unicode="&#xf00c;" horiz-adv-x="1792" +d="M1671 970q0 -40 -28 -68l-724 -724l-136 -136q-28 -28 -68 -28t-68 28l-136 136l-362 362q-28 28 -28 68t28 68l136 136q28 28 68 28t68 -28l294 -295l656 657q28 28 68 28t68 -28l136 -136q28 -28 28 -68z" /> + <glyph glyph-name="remove" unicode="&#xf00d;" horiz-adv-x="1408" +d="M1298 214q0 -40 -28 -68l-136 -136q-28 -28 -68 -28t-68 28l-294 294l-294 -294q-28 -28 -68 -28t-68 28l-136 136q-28 28 -28 68t28 68l294 294l-294 294q-28 28 -28 68t28 68l136 136q28 28 68 28t68 -28l294 -294l294 294q28 28 68 28t68 -28l136 -136q28 -28 28 -68 +t-28 -68l-294 -294l294 -294q28 -28 28 -68z" /> + <glyph glyph-name="zoom_in" unicode="&#xf00e;" horiz-adv-x="1664" +d="M1024 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-224v-224q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v224h-224q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h224v224q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-224h224 +q13 0 22.5 -9.5t9.5 -22.5zM1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5zM1664 -128q0 -53 -37.5 -90.5t-90.5 -37.5q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5 +t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z" /> + <glyph glyph-name="zoom_out" unicode="&#xf010;" horiz-adv-x="1664" +d="M1024 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-576q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h576q13 0 22.5 -9.5t9.5 -22.5zM1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5z +M1664 -128q0 -53 -37.5 -90.5t-90.5 -37.5q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z +" /> + <glyph glyph-name="off" unicode="&#xf011;" +d="M1536 640q0 -156 -61 -298t-164 -245t-245 -164t-298 -61t-298 61t-245 164t-164 245t-61 298q0 182 80.5 343t226.5 270q43 32 95.5 25t83.5 -50q32 -42 24.5 -94.5t-49.5 -84.5q-98 -74 -151.5 -181t-53.5 -228q0 -104 40.5 -198.5t109.5 -163.5t163.5 -109.5 +t198.5 -40.5t198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5q0 121 -53.5 228t-151.5 181q-42 32 -49.5 84.5t24.5 94.5q31 43 84 50t95 -25q146 -109 226.5 -270t80.5 -343zM896 1408v-640q0 -52 -38 -90t-90 -38t-90 38t-38 90v640q0 52 38 90t90 38t90 -38t38 -90z" /> + <glyph glyph-name="signal" unicode="&#xf012;" horiz-adv-x="1792" +d="M256 96v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM640 224v-320q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v320q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1024 480v-576q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23 +v576q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1408 864v-960q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v960q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1792 1376v-1472q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v1472q0 14 9 23t23 9h192q14 0 23 -9t9 -23z" /> + <glyph glyph-name="cog" unicode="&#xf013;" +d="M1024 640q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1536 749v-222q0 -12 -8 -23t-20 -13l-185 -28q-19 -54 -39 -91q35 -50 107 -138q10 -12 10 -25t-9 -23q-27 -37 -99 -108t-94 -71q-12 0 -26 9l-138 108q-44 -23 -91 -38 +q-16 -136 -29 -186q-7 -28 -36 -28h-222q-14 0 -24.5 8.5t-11.5 21.5l-28 184q-49 16 -90 37l-141 -107q-10 -9 -25 -9q-14 0 -25 11q-126 114 -165 168q-7 10 -7 23q0 12 8 23q15 21 51 66.5t54 70.5q-27 50 -41 99l-183 27q-13 2 -21 12.5t-8 23.5v222q0 12 8 23t19 13 +l186 28q14 46 39 92q-40 57 -107 138q-10 12 -10 24q0 10 9 23q26 36 98.5 107.5t94.5 71.5q13 0 26 -10l138 -107q44 23 91 38q16 136 29 186q7 28 36 28h222q14 0 24.5 -8.5t11.5 -21.5l28 -184q49 -16 90 -37l142 107q9 9 24 9q13 0 25 -10q129 -119 165 -170q7 -8 7 -22 +q0 -12 -8 -23q-15 -21 -51 -66.5t-54 -70.5q26 -50 41 -98l183 -28q13 -2 21 -12.5t8 -23.5z" /> + <glyph glyph-name="trash" unicode="&#xf014;" horiz-adv-x="1408" +d="M512 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM768 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1024 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576 +q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1152 76v948h-896v-948q0 -22 7 -40.5t14.5 -27t10.5 -8.5h832q3 0 10.5 8.5t14.5 27t7 40.5zM480 1152h448l-48 117q-7 9 -17 11h-317q-10 -2 -17 -11zM1408 1120v-64q0 -14 -9 -23t-23 -9h-96v-948q0 -83 -47 -143.5t-113 -60.5h-832 +q-66 0 -113 58.5t-47 141.5v952h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h309l70 167q15 37 54 63t79 26h320q40 0 79 -26t54 -63l70 -167h309q14 0 23 -9t9 -23z" /> + <glyph glyph-name="home" unicode="&#xf015;" horiz-adv-x="1664" +d="M1408 544v-480q0 -26 -19 -45t-45 -19h-384v384h-256v-384h-384q-26 0 -45 19t-19 45v480q0 1 0.5 3t0.5 3l575 474l575 -474q1 -2 1 -6zM1631 613l-62 -74q-8 -9 -21 -11h-3q-13 0 -21 7l-692 577l-692 -577q-12 -8 -24 -7q-13 2 -21 11l-62 74q-8 10 -7 23.5t11 21.5 +l719 599q32 26 76 26t76 -26l244 -204v195q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-408l219 -182q10 -8 11 -21.5t-7 -23.5z" /> + <glyph glyph-name="file_alt" unicode="&#xf016;" +d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z +" /> + <glyph glyph-name="time" unicode="&#xf017;" +d="M896 992v-448q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640 +q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="road" unicode="&#xf018;" horiz-adv-x="1920" +d="M1111 540v4l-24 320q-1 13 -11 22.5t-23 9.5h-186q-13 0 -23 -9.5t-11 -22.5l-24 -320v-4q-1 -12 8 -20t21 -8h244q12 0 21 8t8 20zM1870 73q0 -73 -46 -73h-704q13 0 22 9.5t8 22.5l-20 256q-1 13 -11 22.5t-23 9.5h-272q-13 0 -23 -9.5t-11 -22.5l-20 -256 +q-1 -13 8 -22.5t22 -9.5h-704q-46 0 -46 73q0 54 26 116l417 1044q8 19 26 33t38 14h339q-13 0 -23 -9.5t-11 -22.5l-15 -192q-1 -14 8 -23t22 -9h166q13 0 22 9t8 23l-15 192q-1 13 -11 22.5t-23 9.5h339q20 0 38 -14t26 -33l417 -1044q26 -62 26 -116z" /> + <glyph glyph-name="download_alt" unicode="&#xf019;" horiz-adv-x="1664" +d="M1280 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 416v-320q0 -40 -28 -68t-68 -28h-1472q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h465l135 -136 +q58 -56 136 -56t136 56l136 136h464q40 0 68 -28t28 -68zM1339 985q17 -41 -14 -70l-448 -448q-18 -19 -45 -19t-45 19l-448 448q-31 29 -14 70q17 39 59 39h256v448q0 26 19 45t45 19h256q26 0 45 -19t19 -45v-448h256q42 0 59 -39z" /> + <glyph glyph-name="download" unicode="&#xf01a;" +d="M1120 608q0 -12 -10 -24l-319 -319q-11 -9 -23 -9t-23 9l-320 320q-15 16 -7 35q8 20 30 20h192v352q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-352h192q14 0 23 -9t9 -23zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273 +t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="upload" unicode="&#xf01b;" +d="M1118 660q-8 -20 -30 -20h-192v-352q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v352h-192q-14 0 -23 9t-9 23q0 12 10 24l319 319q11 9 23 9t23 -9l320 -320q15 -16 7 -35zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198 +t73 273t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="inbox" unicode="&#xf01c;" +d="M1023 576h316q-1 3 -2.5 8.5t-2.5 7.5l-212 496h-708l-212 -496q-1 -3 -2.5 -8.5t-2.5 -7.5h316l95 -192h320zM1536 546v-482q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v482q0 62 25 123l238 552q10 25 36.5 42t52.5 17h832q26 0 52.5 -17t36.5 -42l238 -552 +q25 -61 25 -123z" /> + <glyph glyph-name="play_circle" unicode="&#xf01d;" +d="M1184 640q0 -37 -32 -55l-544 -320q-15 -9 -32 -9q-16 0 -32 8q-32 19 -32 56v640q0 37 32 56q33 18 64 -1l544 -320q32 -18 32 -55zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640 +q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="repeat" unicode="&#xf01e;" +d="M1536 1280v-448q0 -26 -19 -45t-45 -19h-448q-42 0 -59 40q-17 39 14 69l138 138q-148 137 -349 137q-104 0 -198.5 -40.5t-163.5 -109.5t-109.5 -163.5t-40.5 -198.5t40.5 -198.5t109.5 -163.5t163.5 -109.5t198.5 -40.5q119 0 225 52t179 147q7 10 23 12q15 0 25 -9 +l137 -138q9 -8 9.5 -20.5t-7.5 -22.5q-109 -132 -264 -204.5t-327 -72.5q-156 0 -298 61t-245 164t-164 245t-61 298t61 298t164 245t245 164t298 61q147 0 284.5 -55.5t244.5 -156.5l130 129q29 31 70 14q39 -17 39 -59z" /> + <glyph glyph-name="refresh" unicode="&#xf021;" +d="M1511 480q0 -5 -1 -7q-64 -268 -268 -434.5t-478 -166.5q-146 0 -282.5 55t-243.5 157l-129 -129q-19 -19 -45 -19t-45 19t-19 45v448q0 26 19 45t45 19h448q26 0 45 -19t19 -45t-19 -45l-137 -137q71 -66 161 -102t187 -36q134 0 250 65t186 179q11 17 53 117 +q8 23 30 23h192q13 0 22.5 -9.5t9.5 -22.5zM1536 1280v-448q0 -26 -19 -45t-45 -19h-448q-26 0 -45 19t-19 45t19 45l138 138q-148 137 -349 137q-134 0 -250 -65t-186 -179q-11 -17 -53 -117q-8 -23 -30 -23h-199q-13 0 -22.5 9.5t-9.5 22.5v7q65 268 270 434.5t480 166.5 +q146 0 284 -55.5t245 -156.5l130 129q19 19 45 19t45 -19t19 -45z" /> + <glyph glyph-name="list_alt" unicode="&#xf022;" horiz-adv-x="1792" +d="M384 352v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 608v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z +M384 864v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1536 352v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5t9.5 -22.5z +M1536 608v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5t9.5 -22.5zM1536 864v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5 +t9.5 -22.5zM1664 160v832q0 13 -9.5 22.5t-22.5 9.5h-1472q-13 0 -22.5 -9.5t-9.5 -22.5v-832q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5zM1792 1248v-1088q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1472q66 0 113 -47 +t47 -113z" /> + <glyph glyph-name="lock" unicode="&#xf023;" horiz-adv-x="1152" +d="M320 768h512v192q0 106 -75 181t-181 75t-181 -75t-75 -181v-192zM1152 672v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v576q0 40 28 68t68 28h32v192q0 184 132 316t316 132t316 -132t132 -316v-192h32q40 0 68 -28t28 -68z" /> + <glyph glyph-name="flag" unicode="&#xf024;" horiz-adv-x="1792" +d="M320 1280q0 -72 -64 -110v-1266q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v1266q-64 38 -64 110q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1792 1216v-763q0 -25 -12.5 -38.5t-39.5 -27.5q-215 -116 -369 -116q-61 0 -123.5 22t-108.5 48 +t-115.5 48t-142.5 22q-192 0 -464 -146q-17 -9 -33 -9q-26 0 -45 19t-19 45v742q0 32 31 55q21 14 79 43q236 120 421 120q107 0 200 -29t219 -88q38 -19 88 -19q54 0 117.5 21t110 47t88 47t54.5 21q26 0 45 -19t19 -45z" /> + <glyph glyph-name="headphones" unicode="&#xf025;" horiz-adv-x="1664" +d="M1664 650q0 -166 -60 -314l-20 -49l-185 -33q-22 -83 -90.5 -136.5t-156.5 -53.5v-32q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-32q71 0 130 -35.5t93 -95.5l68 12q29 95 29 193q0 148 -88 279t-236.5 209t-315.5 78 +t-315.5 -78t-236.5 -209t-88 -279q0 -98 29 -193l68 -12q34 60 93 95.5t130 35.5v32q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v32q-88 0 -156.5 53.5t-90.5 136.5l-185 33l-20 49q-60 148 -60 314q0 151 67 291t179 242.5 +t266 163.5t320 61t320 -61t266 -163.5t179 -242.5t67 -291z" /> + <glyph glyph-name="volume_off" unicode="&#xf026;" horiz-adv-x="768" +d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45z" /> + <glyph glyph-name="volume_down" unicode="&#xf027;" horiz-adv-x="1152" +d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45zM1152 640q0 -76 -42.5 -141.5t-112.5 -93.5q-10 -5 -25 -5q-26 0 -45 18.5t-19 45.5q0 21 12 35.5t29 25t34 23t29 36 +t12 56.5t-12 56.5t-29 36t-34 23t-29 25t-12 35.5q0 27 19 45.5t45 18.5q15 0 25 -5q70 -27 112.5 -93t42.5 -142z" /> + <glyph glyph-name="volume_up" unicode="&#xf028;" horiz-adv-x="1664" +d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45zM1152 640q0 -76 -42.5 -141.5t-112.5 -93.5q-10 -5 -25 -5q-26 0 -45 18.5t-19 45.5q0 21 12 35.5t29 25t34 23t29 36 +t12 56.5t-12 56.5t-29 36t-34 23t-29 25t-12 35.5q0 27 19 45.5t45 18.5q15 0 25 -5q70 -27 112.5 -93t42.5 -142zM1408 640q0 -153 -85 -282.5t-225 -188.5q-13 -5 -25 -5q-27 0 -46 19t-19 45q0 39 39 59q56 29 76 44q74 54 115.5 135.5t41.5 173.5t-41.5 173.5 +t-115.5 135.5q-20 15 -76 44q-39 20 -39 59q0 26 19 45t45 19q13 0 26 -5q140 -59 225 -188.5t85 -282.5zM1664 640q0 -230 -127 -422.5t-338 -283.5q-13 -5 -26 -5q-26 0 -45 19t-19 45q0 36 39 59q7 4 22.5 10.5t22.5 10.5q46 25 82 51q123 91 192 227t69 289t-69 289 +t-192 227q-36 26 -82 51q-7 4 -22.5 10.5t-22.5 10.5q-39 23 -39 59q0 26 19 45t45 19q13 0 26 -5q211 -91 338 -283.5t127 -422.5z" /> + <glyph glyph-name="qrcode" unicode="&#xf029;" horiz-adv-x="1408" +d="M384 384v-128h-128v128h128zM384 1152v-128h-128v128h128zM1152 1152v-128h-128v128h128zM128 129h384v383h-384v-383zM128 896h384v384h-384v-384zM896 896h384v384h-384v-384zM640 640v-640h-640v640h640zM1152 128v-128h-128v128h128zM1408 128v-128h-128v128h128z +M1408 640v-384h-384v128h-128v-384h-128v640h384v-128h128v128h128zM640 1408v-640h-640v640h640zM1408 1408v-640h-640v640h640z" /> + <glyph glyph-name="barcode" unicode="&#xf02a;" horiz-adv-x="1792" +d="M63 0h-63v1408h63v-1408zM126 1h-32v1407h32v-1407zM220 1h-31v1407h31v-1407zM377 1h-31v1407h31v-1407zM534 1h-62v1407h62v-1407zM660 1h-31v1407h31v-1407zM723 1h-31v1407h31v-1407zM786 1h-31v1407h31v-1407zM943 1h-63v1407h63v-1407zM1100 1h-63v1407h63v-1407z +M1226 1h-63v1407h63v-1407zM1352 1h-63v1407h63v-1407zM1446 1h-63v1407h63v-1407zM1635 1h-94v1407h94v-1407zM1698 1h-32v1407h32v-1407zM1792 0h-63v1408h63v-1408z" /> + <glyph glyph-name="tag" unicode="&#xf02b;" +d="M448 1088q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1515 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-53 0 -90 37l-715 716q-38 37 -64.5 101t-26.5 117v416q0 52 38 90t90 38h416q53 0 117 -26.5t102 -64.5 +l715 -714q37 -39 37 -91z" /> + <glyph glyph-name="tags" unicode="&#xf02c;" horiz-adv-x="1920" +d="M448 1088q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1515 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-53 0 -90 37l-715 716q-38 37 -64.5 101t-26.5 117v416q0 52 38 90t90 38h416q53 0 117 -26.5t102 -64.5 +l715 -714q37 -39 37 -91zM1899 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-36 0 -59 14t-53 45l470 470q37 37 37 90q0 52 -37 91l-715 714q-38 38 -102 64.5t-117 26.5h224q53 0 117 -26.5t102 -64.5l715 -714q37 -39 37 -91z" /> + <glyph glyph-name="book" unicode="&#xf02d;" horiz-adv-x="1664" +d="M1639 1058q40 -57 18 -129l-275 -906q-19 -64 -76.5 -107.5t-122.5 -43.5h-923q-77 0 -148.5 53.5t-99.5 131.5q-24 67 -2 127q0 4 3 27t4 37q1 8 -3 21.5t-3 19.5q2 11 8 21t16.5 23.5t16.5 23.5q23 38 45 91.5t30 91.5q3 10 0.5 30t-0.5 28q3 11 17 28t17 23 +q21 36 42 92t25 90q1 9 -2.5 32t0.5 28q4 13 22 30.5t22 22.5q19 26 42.5 84.5t27.5 96.5q1 8 -3 25.5t-2 26.5q2 8 9 18t18 23t17 21q8 12 16.5 30.5t15 35t16 36t19.5 32t26.5 23.5t36 11.5t47.5 -5.5l-1 -3q38 9 51 9h761q74 0 114 -56t18 -130l-274 -906 +q-36 -119 -71.5 -153.5t-128.5 -34.5h-869q-27 0 -38 -15q-11 -16 -1 -43q24 -70 144 -70h923q29 0 56 15.5t35 41.5l300 987q7 22 5 57q38 -15 59 -43zM575 1056q-4 -13 2 -22.5t20 -9.5h608q13 0 25.5 9.5t16.5 22.5l21 64q4 13 -2 22.5t-20 9.5h-608q-13 0 -25.5 -9.5 +t-16.5 -22.5zM492 800q-4 -13 2 -22.5t20 -9.5h608q13 0 25.5 9.5t16.5 22.5l21 64q4 13 -2 22.5t-20 9.5h-608q-13 0 -25.5 -9.5t-16.5 -22.5z" /> + <glyph glyph-name="bookmark" unicode="&#xf02e;" horiz-adv-x="1280" +d="M1164 1408q23 0 44 -9q33 -13 52.5 -41t19.5 -62v-1289q0 -34 -19.5 -62t-52.5 -41q-19 -8 -44 -8q-48 0 -83 32l-441 424l-441 -424q-36 -33 -83 -33q-23 0 -44 9q-33 13 -52.5 41t-19.5 62v1289q0 34 19.5 62t52.5 41q21 9 44 9h1048z" /> + <glyph glyph-name="print" unicode="&#xf02f;" horiz-adv-x="1664" +d="M384 0h896v256h-896v-256zM384 640h896v384h-160q-40 0 -68 28t-28 68v160h-640v-640zM1536 576q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 576v-416q0 -13 -9.5 -22.5t-22.5 -9.5h-224v-160q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68 +v160h-224q-13 0 -22.5 9.5t-9.5 22.5v416q0 79 56.5 135.5t135.5 56.5h64v544q0 40 28 68t68 28h672q40 0 88 -20t76 -48l152 -152q28 -28 48 -76t20 -88v-256h64q79 0 135.5 -56.5t56.5 -135.5z" /> + <glyph glyph-name="camera" unicode="&#xf030;" horiz-adv-x="1920" +d="M960 864q119 0 203.5 -84.5t84.5 -203.5t-84.5 -203.5t-203.5 -84.5t-203.5 84.5t-84.5 203.5t84.5 203.5t203.5 84.5zM1664 1280q106 0 181 -75t75 -181v-896q0 -106 -75 -181t-181 -75h-1408q-106 0 -181 75t-75 181v896q0 106 75 181t181 75h224l51 136 +q19 49 69.5 84.5t103.5 35.5h512q53 0 103.5 -35.5t69.5 -84.5l51 -136h224zM960 128q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" /> + <glyph glyph-name="font" unicode="&#xf031;" horiz-adv-x="1664" +d="M725 977l-170 -450q33 0 136.5 -2t160.5 -2q19 0 57 2q-87 253 -184 452zM0 -128l2 79q23 7 56 12.5t57 10.5t49.5 14.5t44.5 29t31 50.5l237 616l280 724h75h53q8 -14 11 -21l205 -480q33 -78 106 -257.5t114 -274.5q15 -34 58 -144.5t72 -168.5q20 -45 35 -57 +q19 -15 88 -29.5t84 -20.5q6 -38 6 -57q0 -5 -0.5 -13.5t-0.5 -12.5q-63 0 -190 8t-191 8q-76 0 -215 -7t-178 -8q0 43 4 78l131 28q1 0 12.5 2.5t15.5 3.5t14.5 4.5t15 6.5t11 8t9 11t2.5 14q0 16 -31 96.5t-72 177.5t-42 100l-450 2q-26 -58 -76.5 -195.5t-50.5 -162.5 +q0 -22 14 -37.5t43.5 -24.5t48.5 -13.5t57 -8.5t41 -4q1 -19 1 -58q0 -9 -2 -27q-58 0 -174.5 10t-174.5 10q-8 0 -26.5 -4t-21.5 -4q-80 -14 -188 -14z" /> + <glyph glyph-name="bold" unicode="&#xf032;" horiz-adv-x="1408" +d="M555 15q74 -32 140 -32q376 0 376 335q0 114 -41 180q-27 44 -61.5 74t-67.5 46.5t-80.5 25t-84 10.5t-94.5 2q-73 0 -101 -10q0 -53 -0.5 -159t-0.5 -158q0 -8 -1 -67.5t-0.5 -96.5t4.5 -83.5t12 -66.5zM541 761q42 -7 109 -7q82 0 143 13t110 44.5t74.5 89.5t25.5 142 +q0 70 -29 122.5t-79 82t-108 43.5t-124 14q-50 0 -130 -13q0 -50 4 -151t4 -152q0 -27 -0.5 -80t-0.5 -79q0 -46 1 -69zM0 -128l2 94q15 4 85 16t106 27q7 12 12.5 27t8.5 33.5t5.5 32.5t3 37.5t0.5 34v35.5v30q0 982 -22 1025q-4 8 -22 14.5t-44.5 11t-49.5 7t-48.5 4.5 +t-30.5 3l-4 83q98 2 340 11.5t373 9.5q23 0 68 -0.5t68 -0.5q70 0 136.5 -13t128.5 -42t108 -71t74 -104.5t28 -137.5q0 -52 -16.5 -95.5t-39 -72t-64.5 -57.5t-73 -45t-84 -40q154 -35 256.5 -134t102.5 -248q0 -100 -35 -179.5t-93.5 -130.5t-138 -85.5t-163.5 -48.5 +t-176 -14q-44 0 -132 3t-132 3q-106 0 -307 -11t-231 -12z" /> + <glyph glyph-name="italic" unicode="&#xf033;" horiz-adv-x="1024" +d="M0 -126l17 85q22 7 61.5 16.5t72 19t59.5 23.5q28 35 41 101q1 7 62 289t114 543.5t52 296.5v25q-24 13 -54.5 18.5t-69.5 8t-58 5.5l19 103q33 -2 120 -6.5t149.5 -7t120.5 -2.5q48 0 98.5 2.5t121 7t98.5 6.5q-5 -39 -19 -89q-30 -10 -101.5 -28.5t-108.5 -33.5 +q-8 -19 -14 -42.5t-9 -40t-7.5 -45.5t-6.5 -42q-27 -148 -87.5 -419.5t-77.5 -355.5q-2 -9 -13 -58t-20 -90t-16 -83.5t-6 -57.5l1 -18q17 -4 185 -31q-3 -44 -16 -99q-11 0 -32.5 -1.5t-32.5 -1.5q-29 0 -87 10t-86 10q-138 2 -206 2q-51 0 -143 -9t-121 -11z" /> + <glyph glyph-name="text_height" unicode="&#xf034;" horiz-adv-x="1792" +d="M1744 128q33 0 42 -18.5t-11 -44.5l-126 -162q-20 -26 -49 -26t-49 26l-126 162q-20 26 -11 44.5t42 18.5h80v1024h-80q-33 0 -42 18.5t11 44.5l126 162q20 26 49 26t49 -26l126 -162q20 -26 11 -44.5t-42 -18.5h-80v-1024h80zM81 1407l54 -27q12 -5 211 -5q44 0 132 2 +t132 2q36 0 107.5 -0.5t107.5 -0.5h293q6 0 21 -0.5t20.5 0t16 3t17.5 9t15 17.5l42 1q4 0 14 -0.5t14 -0.5q2 -112 2 -336q0 -80 -5 -109q-39 -14 -68 -18q-25 44 -54 128q-3 9 -11 48t-14.5 73.5t-7.5 35.5q-6 8 -12 12.5t-15.5 6t-13 2.5t-18 0.5t-16.5 -0.5 +q-17 0 -66.5 0.5t-74.5 0.5t-64 -2t-71 -6q-9 -81 -8 -136q0 -94 2 -388t2 -455q0 -16 -2.5 -71.5t0 -91.5t12.5 -69q40 -21 124 -42.5t120 -37.5q5 -40 5 -50q0 -14 -3 -29l-34 -1q-76 -2 -218 8t-207 10q-50 0 -151 -9t-152 -9q-3 51 -3 52v9q17 27 61.5 43t98.5 29t78 27 +q19 42 19 383q0 101 -3 303t-3 303v117q0 2 0.5 15.5t0.5 25t-1 25.5t-3 24t-5 14q-11 12 -162 12q-33 0 -93 -12t-80 -26q-19 -13 -34 -72.5t-31.5 -111t-42.5 -53.5q-42 26 -56 44v383z" /> + <glyph glyph-name="text_width" unicode="&#xf035;" +d="M81 1407l54 -27q12 -5 211 -5q44 0 132 2t132 2q70 0 246.5 1t304.5 0.5t247 -4.5q33 -1 56 31l42 1q4 0 14 -0.5t14 -0.5q2 -112 2 -336q0 -80 -5 -109q-39 -14 -68 -18q-25 44 -54 128q-3 9 -11 47.5t-15 73.5t-7 36q-10 13 -27 19q-5 2 -66 2q-30 0 -93 1t-103 1 +t-94 -2t-96 -7q-9 -81 -8 -136l1 -152v52q0 -55 1 -154t1.5 -180t0.5 -153q0 -16 -2.5 -71.5t0 -91.5t12.5 -69q40 -21 124 -42.5t120 -37.5q5 -40 5 -50q0 -14 -3 -29l-34 -1q-76 -2 -218 8t-207 10q-50 0 -151 -9t-152 -9q-3 51 -3 52v9q17 27 61.5 43t98.5 29t78 27 +q7 16 11.5 74t6 145.5t1.5 155t-0.5 153.5t-0.5 89q0 7 -2.5 21.5t-2.5 22.5q0 7 0.5 44t1 73t0 76.5t-3 67.5t-6.5 32q-11 12 -162 12q-41 0 -163 -13.5t-138 -24.5q-19 -12 -34 -71.5t-31.5 -111.5t-42.5 -54q-42 26 -56 44v383zM1310 125q12 0 42 -19.5t57.5 -41.5 +t59.5 -49t36 -30q26 -21 26 -49t-26 -49q-4 -3 -36 -30t-59.5 -49t-57.5 -41.5t-42 -19.5q-13 0 -20.5 10.5t-10 28.5t-2.5 33.5t1.5 33t1.5 19.5h-1024q0 -2 1.5 -19.5t1.5 -33t-2.5 -33.5t-10 -28.5t-20.5 -10.5q-12 0 -42 19.5t-57.5 41.5t-59.5 49t-36 30q-26 21 -26 49 +t26 49q4 3 36 30t59.5 49t57.5 41.5t42 19.5q13 0 20.5 -10.5t10 -28.5t2.5 -33.5t-1.5 -33t-1.5 -19.5h1024q0 2 -1.5 19.5t-1.5 33t2.5 33.5t10 28.5t20.5 10.5z" /> + <glyph glyph-name="align_left" unicode="&#xf036;" horiz-adv-x="1792" +d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1408 576v-128q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1280q26 0 45 -19t19 -45zM1664 960v-128q0 -26 -19 -45 +t-45 -19h-1536q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1536q26 0 45 -19t19 -45zM1280 1344v-128q0 -26 -19 -45t-45 -19h-1152q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" /> + <glyph glyph-name="align_center" unicode="&#xf037;" horiz-adv-x="1792" +d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1408 576v-128q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h896q26 0 45 -19t19 -45zM1664 960v-128q0 -26 -19 -45t-45 -19 +h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1280 1344v-128q0 -26 -19 -45t-45 -19h-640q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h640q26 0 45 -19t19 -45z" /> + <glyph glyph-name="align_right" unicode="&#xf038;" horiz-adv-x="1792" +d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 576v-128q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1280q26 0 45 -19t19 -45zM1792 960v-128q0 -26 -19 -45 +t-45 -19h-1536q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1536q26 0 45 -19t19 -45zM1792 1344v-128q0 -26 -19 -45t-45 -19h-1152q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" /> + <glyph glyph-name="align_justify" unicode="&#xf039;" horiz-adv-x="1792" +d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 576v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 960v-128q0 -26 -19 -45 +t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 1344v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45z" /> + <glyph glyph-name="list" unicode="&#xf03a;" horiz-adv-x="1792" +d="M256 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM256 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5 +t9.5 -22.5zM256 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1344 +q13 0 22.5 -9.5t9.5 -22.5zM256 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5 +t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192 +q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5z" /> + <glyph glyph-name="indent_left" unicode="&#xf03b;" horiz-adv-x="1792" +d="M384 992v-576q0 -13 -9.5 -22.5t-22.5 -9.5q-14 0 -23 9l-288 288q-9 9 -9 23t9 23l288 288q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5 +t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088 +q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5z" /> + <glyph glyph-name="indent_right" unicode="&#xf03c;" horiz-adv-x="1792" +d="M352 704q0 -14 -9 -23l-288 -288q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v576q0 13 9.5 22.5t22.5 9.5q14 0 23 -9l288 -288q9 -9 9 -23zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5 +t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088 +q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5z" /> + <glyph glyph-name="facetime_video" unicode="&#xf03d;" horiz-adv-x="1792" +d="M1792 1184v-1088q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-403 403v-166q0 -119 -84.5 -203.5t-203.5 -84.5h-704q-119 0 -203.5 84.5t-84.5 203.5v704q0 119 84.5 203.5t203.5 84.5h704q119 0 203.5 -84.5t84.5 -203.5v-165l403 402q18 19 45 19q12 0 25 -5 +q39 -17 39 -59z" /> + <glyph glyph-name="picture" unicode="&#xf03e;" horiz-adv-x="1920" +d="M640 960q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1664 576v-448h-1408v192l320 320l160 -160l512 512zM1760 1280h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-1216q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5v1216 +q0 13 -9.5 22.5t-22.5 9.5zM1920 1248v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" /> + <glyph glyph-name="pencil" unicode="&#xf040;" +d="M363 0l91 91l-235 235l-91 -91v-107h128v-128h107zM886 928q0 22 -22 22q-10 0 -17 -7l-542 -542q-7 -7 -7 -17q0 -22 22 -22q10 0 17 7l542 542q7 7 7 17zM832 1120l416 -416l-832 -832h-416v416zM1515 1024q0 -53 -37 -90l-166 -166l-416 416l166 165q36 38 90 38 +q53 0 91 -38l235 -234q37 -39 37 -91z" /> + <glyph glyph-name="map_marker" unicode="&#xf041;" horiz-adv-x="1024" +d="M768 896q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1024 896q0 -109 -33 -179l-364 -774q-16 -33 -47.5 -52t-67.5 -19t-67.5 19t-46.5 52l-365 774q-33 70 -33 179q0 212 150 362t362 150t362 -150t150 -362z" /> + <glyph glyph-name="adjust" unicode="&#xf042;" +d="M768 96v1088q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="tint" unicode="&#xf043;" horiz-adv-x="1024" +d="M512 384q0 36 -20 69q-1 1 -15.5 22.5t-25.5 38t-25 44t-21 50.5q-4 16 -21 16t-21 -16q-7 -23 -21 -50.5t-25 -44t-25.5 -38t-15.5 -22.5q-20 -33 -20 -69q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1024 512q0 -212 -150 -362t-362 -150t-362 150t-150 362 +q0 145 81 275q6 9 62.5 90.5t101 151t99.5 178t83 201.5q9 30 34 47t51 17t51.5 -17t33.5 -47q28 -93 83 -201.5t99.5 -178t101 -151t62.5 -90.5q81 -127 81 -275z" /> + <glyph glyph-name="edit" unicode="&#xf044;" horiz-adv-x="1792" +d="M888 352l116 116l-152 152l-116 -116v-56h96v-96h56zM1328 1072q-16 16 -33 -1l-350 -350q-17 -17 -1 -33t33 1l350 350q17 17 1 33zM1408 478v-190q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832 +q63 0 117 -25q15 -7 18 -23q3 -17 -9 -29l-49 -49q-14 -14 -32 -8q-23 6 -45 6h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v126q0 13 9 22l64 64q15 15 35 7t20 -29zM1312 1216l288 -288l-672 -672h-288v288zM1756 1084l-92 -92 +l-288 288l92 92q28 28 68 28t68 -28l152 -152q28 -28 28 -68t-28 -68z" /> + <glyph glyph-name="share" unicode="&#xf045;" horiz-adv-x="1664" +d="M1408 547v-259q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h255v0q13 0 22.5 -9.5t9.5 -22.5q0 -27 -26 -32q-77 -26 -133 -60q-10 -4 -16 -4h-112q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832 +q66 0 113 47t47 113v214q0 19 18 29q28 13 54 37q16 16 35 8q21 -9 21 -29zM1645 1043l-384 -384q-18 -19 -45 -19q-12 0 -25 5q-39 17 -39 59v192h-160q-323 0 -438 -131q-119 -137 -74 -473q3 -23 -20 -34q-8 -2 -12 -2q-16 0 -26 13q-10 14 -21 31t-39.5 68.5t-49.5 99.5 +t-38.5 114t-17.5 122q0 49 3.5 91t14 90t28 88t47 81.5t68.5 74t94.5 61.5t124.5 48.5t159.5 30.5t196.5 11h160v192q0 42 39 59q13 5 25 5q26 0 45 -19l384 -384q19 -19 19 -45t-19 -45z" /> + <glyph glyph-name="check" unicode="&#xf046;" horiz-adv-x="1664" +d="M1408 606v-318q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832q63 0 117 -25q15 -7 18 -23q3 -17 -9 -29l-49 -49q-10 -10 -23 -10q-3 0 -9 2q-23 6 -45 6h-832q-66 0 -113 -47t-47 -113v-832 +q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v254q0 13 9 22l64 64q10 10 23 10q6 0 12 -3q20 -8 20 -29zM1639 1095l-814 -814q-24 -24 -57 -24t-57 24l-430 430q-24 24 -24 57t24 57l110 110q24 24 57 24t57 -24l263 -263l647 647q24 24 57 24t57 -24l110 -110 +q24 -24 24 -57t-24 -57z" /> + <glyph glyph-name="move" unicode="&#xf047;" horiz-adv-x="1792" +d="M1792 640q0 -26 -19 -45l-256 -256q-19 -19 -45 -19t-45 19t-19 45v128h-384v-384h128q26 0 45 -19t19 -45t-19 -45l-256 -256q-19 -19 -45 -19t-45 19l-256 256q-19 19 -19 45t19 45t45 19h128v384h-384v-128q0 -26 -19 -45t-45 -19t-45 19l-256 256q-19 19 -19 45 +t19 45l256 256q19 19 45 19t45 -19t19 -45v-128h384v384h-128q-26 0 -45 19t-19 45t19 45l256 256q19 19 45 19t45 -19l256 -256q19 -19 19 -45t-19 -45t-45 -19h-128v-384h384v128q0 26 19 45t45 19t45 -19l256 -256q19 -19 19 -45z" /> + <glyph glyph-name="step_backward" unicode="&#xf048;" horiz-adv-x="1024" +d="M979 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-678q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-678q4 10 13 19z" /> + <glyph glyph-name="fast_backward" unicode="&#xf049;" horiz-adv-x="1792" +d="M1747 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-710q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-678q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-678q4 10 13 19l710 710 +q19 19 32 13t13 -32v-710q4 10 13 19z" /> + <glyph glyph-name="backward" unicode="&#xf04a;" horiz-adv-x="1664" +d="M1619 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-710q0 -26 -13 -32t-32 13l-710 710q-19 19 -19 45t19 45l710 710q19 19 32 13t13 -32v-710q4 10 13 19z" /> + <glyph glyph-name="play" unicode="&#xf04b;" horiz-adv-x="1408" +d="M1384 609l-1328 -738q-23 -13 -39.5 -3t-16.5 36v1472q0 26 16.5 36t39.5 -3l1328 -738q23 -13 23 -31t-23 -31z" /> + <glyph glyph-name="pause" unicode="&#xf04c;" +d="M1536 1344v-1408q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h512q26 0 45 -19t19 -45zM640 1344v-1408q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h512q26 0 45 -19t19 -45z" /> + <glyph glyph-name="stop" unicode="&#xf04d;" +d="M1536 1344v-1408q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h1408q26 0 45 -19t19 -45z" /> + <glyph glyph-name="forward" unicode="&#xf04e;" horiz-adv-x="1664" +d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q9 -9 13 -19v710q0 26 13 32t32 -13l710 -710q19 -19 19 -45t-19 -45l-710 -710q-19 -19 -32 -13t-13 32v710q-4 -10 -13 -19z" /> + <glyph glyph-name="fast_forward" unicode="&#xf050;" horiz-adv-x="1792" +d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q9 -9 13 -19v710q0 26 13 32t32 -13l710 -710q9 -9 13 -19v678q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v678q-4 -10 -13 -19l-710 -710 +q-19 -19 -32 -13t-13 32v710q-4 -10 -13 -19z" /> + <glyph glyph-name="step_forward" unicode="&#xf051;" horiz-adv-x="1024" +d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q9 -9 13 -19v678q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v678q-4 -10 -13 -19z" /> + <glyph glyph-name="eject" unicode="&#xf052;" horiz-adv-x="1538" +d="M14 557l710 710q19 19 45 19t45 -19l710 -710q19 -19 13 -32t-32 -13h-1472q-26 0 -32 13t13 32zM1473 0h-1408q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1408q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19z" /> + <glyph glyph-name="chevron_left" unicode="&#xf053;" horiz-adv-x="1280" +d="M1171 1235l-531 -531l531 -531q19 -19 19 -45t-19 -45l-166 -166q-19 -19 -45 -19t-45 19l-742 742q-19 19 -19 45t19 45l742 742q19 19 45 19t45 -19l166 -166q19 -19 19 -45t-19 -45z" /> + <glyph glyph-name="chevron_right" unicode="&#xf054;" horiz-adv-x="1280" +d="M1107 659l-742 -742q-19 -19 -45 -19t-45 19l-166 166q-19 19 -19 45t19 45l531 531l-531 531q-19 19 -19 45t19 45l166 166q19 19 45 19t45 -19l742 -742q19 -19 19 -45t-19 -45z" /> + <glyph glyph-name="plus_sign" unicode="&#xf055;" +d="M1216 576v128q0 26 -19 45t-45 19h-256v256q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-256h-256q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h256v-256q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v256h256q26 0 45 19t19 45zM1536 640q0 -209 -103 -385.5 +t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="minus_sign" unicode="&#xf056;" +d="M1216 576v128q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5 +t103 -385.5z" /> + <glyph glyph-name="remove_sign" unicode="&#xf057;" +d="M1149 414q0 26 -19 45l-181 181l181 181q19 19 19 45q0 27 -19 46l-90 90q-19 19 -46 19q-26 0 -45 -19l-181 -181l-181 181q-19 19 -45 19q-27 0 -46 -19l-90 -90q-19 -19 -19 -46q0 -26 19 -45l181 -181l-181 -181q-19 -19 -19 -45q0 -27 19 -46l90 -90q19 -19 46 -19 +q26 0 45 19l181 181l181 -181q19 -19 45 -19q27 0 46 19l90 90q19 19 19 46zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="ok_sign" unicode="&#xf058;" +d="M1284 802q0 28 -18 46l-91 90q-19 19 -45 19t-45 -19l-408 -407l-226 226q-19 19 -45 19t-45 -19l-91 -90q-18 -18 -18 -46q0 -27 18 -45l362 -362q19 -19 45 -19q27 0 46 19l543 543q18 18 18 45zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103 +t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="question_sign" unicode="&#xf059;" +d="M896 160v192q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h192q14 0 23 9t9 23zM1152 832q0 88 -55.5 163t-138.5 116t-170 41q-243 0 -371 -213q-15 -24 8 -42l132 -100q7 -6 19 -6q16 0 25 12q53 68 86 92q34 24 86 24q48 0 85.5 -26t37.5 -59 +q0 -38 -20 -61t-68 -45q-63 -28 -115.5 -86.5t-52.5 -125.5v-36q0 -14 9 -23t23 -9h192q14 0 23 9t9 23q0 19 21.5 49.5t54.5 49.5q32 18 49 28.5t46 35t44.5 48t28 60.5t12.5 81zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 +t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="info_sign" unicode="&#xf05a;" +d="M1024 160v160q0 14 -9 23t-23 9h-96v512q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23t23 -9h96v-320h-96q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23t23 -9h448q14 0 23 9t9 23zM896 1056v160q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23 +t23 -9h192q14 0 23 9t9 23zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="screenshot" unicode="&#xf05b;" +d="M1197 512h-109q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h109q-32 108 -112.5 188.5t-188.5 112.5v-109q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v109q-108 -32 -188.5 -112.5t-112.5 -188.5h109q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-109 +q32 -108 112.5 -188.5t188.5 -112.5v109q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-109q108 32 188.5 112.5t112.5 188.5zM1536 704v-128q0 -26 -19 -45t-45 -19h-143q-37 -161 -154.5 -278.5t-278.5 -154.5v-143q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v143 +q-161 37 -278.5 154.5t-154.5 278.5h-143q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h143q37 161 154.5 278.5t278.5 154.5v143q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-143q161 -37 278.5 -154.5t154.5 -278.5h143q26 0 45 -19t19 -45z" /> + <glyph glyph-name="remove_circle" unicode="&#xf05c;" +d="M1097 457l-146 -146q-10 -10 -23 -10t-23 10l-137 137l-137 -137q-10 -10 -23 -10t-23 10l-146 146q-10 10 -10 23t10 23l137 137l-137 137q-10 10 -10 23t10 23l146 146q10 10 23 10t23 -10l137 -137l137 137q10 10 23 10t23 -10l146 -146q10 -10 10 -23t-10 -23 +l-137 -137l137 -137q10 -10 10 -23t-10 -23zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5 +t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="ok_circle" unicode="&#xf05d;" +d="M1171 723l-422 -422q-19 -19 -45 -19t-45 19l-294 294q-19 19 -19 45t19 45l102 102q19 19 45 19t45 -19l147 -147l275 275q19 19 45 19t45 -19l102 -102q19 -19 19 -45t-19 -45zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198 +t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="ban_circle" unicode="&#xf05e;" +d="M1312 643q0 161 -87 295l-754 -753q137 -89 297 -89q111 0 211.5 43.5t173.5 116.5t116 174.5t43 212.5zM313 344l755 754q-135 91 -300 91q-148 0 -273 -73t-198 -199t-73 -274q0 -162 89 -299zM1536 643q0 -157 -61 -300t-163.5 -246t-245 -164t-298.5 -61t-298.5 61 +t-245 164t-163.5 246t-61 300t61 299.5t163.5 245.5t245 164t298.5 61t298.5 -61t245 -164t163.5 -245.5t61 -299.5z" /> + <glyph glyph-name="arrow_left" unicode="&#xf060;" +d="M1536 640v-128q0 -53 -32.5 -90.5t-84.5 -37.5h-704l293 -294q38 -36 38 -90t-38 -90l-75 -76q-37 -37 -90 -37q-52 0 -91 37l-651 652q-37 37 -37 90q0 52 37 91l651 650q38 38 91 38q52 0 90 -38l75 -74q38 -38 38 -91t-38 -91l-293 -293h704q52 0 84.5 -37.5 +t32.5 -90.5z" /> + <glyph glyph-name="arrow_right" unicode="&#xf061;" +d="M1472 576q0 -54 -37 -91l-651 -651q-39 -37 -91 -37q-51 0 -90 37l-75 75q-38 38 -38 91t38 91l293 293h-704q-52 0 -84.5 37.5t-32.5 90.5v128q0 53 32.5 90.5t84.5 37.5h704l-293 294q-38 36 -38 90t38 90l75 75q38 38 90 38q53 0 91 -38l651 -651q37 -35 37 -90z" /> + <glyph glyph-name="arrow_up" unicode="&#xf062;" horiz-adv-x="1664" +d="M1611 565q0 -51 -37 -90l-75 -75q-38 -38 -91 -38q-54 0 -90 38l-294 293v-704q0 -52 -37.5 -84.5t-90.5 -32.5h-128q-53 0 -90.5 32.5t-37.5 84.5v704l-294 -293q-36 -38 -90 -38t-90 38l-75 75q-38 38 -38 90q0 53 38 91l651 651q35 37 90 37q54 0 91 -37l651 -651 +q37 -39 37 -91z" /> + <glyph glyph-name="arrow_down" unicode="&#xf063;" horiz-adv-x="1664" +d="M1611 704q0 -53 -37 -90l-651 -652q-39 -37 -91 -37q-53 0 -90 37l-651 652q-38 36 -38 90q0 53 38 91l74 75q39 37 91 37q53 0 90 -37l294 -294v704q0 52 38 90t90 38h128q52 0 90 -38t38 -90v-704l294 294q37 37 90 37q52 0 91 -37l75 -75q37 -39 37 -91z" /> + <glyph glyph-name="share_alt" unicode="&#xf064;" horiz-adv-x="1792" +d="M1792 896q0 -26 -19 -45l-512 -512q-19 -19 -45 -19t-45 19t-19 45v256h-224q-98 0 -175.5 -6t-154 -21.5t-133 -42.5t-105.5 -69.5t-80 -101t-48.5 -138.5t-17.5 -181q0 -55 5 -123q0 -6 2.5 -23.5t2.5 -26.5q0 -15 -8.5 -25t-23.5 -10q-16 0 -28 17q-7 9 -13 22 +t-13.5 30t-10.5 24q-127 285 -127 451q0 199 53 333q162 403 875 403h224v256q0 26 19 45t45 19t45 -19l512 -512q19 -19 19 -45z" /> + <glyph glyph-name="resize_full" unicode="&#xf065;" +d="M755 480q0 -13 -10 -23l-332 -332l144 -144q19 -19 19 -45t-19 -45t-45 -19h-448q-26 0 -45 19t-19 45v448q0 26 19 45t45 19t45 -19l144 -144l332 332q10 10 23 10t23 -10l114 -114q10 -10 10 -23zM1536 1344v-448q0 -26 -19 -45t-45 -19t-45 19l-144 144l-332 -332 +q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l332 332l-144 144q-19 19 -19 45t19 45t45 19h448q26 0 45 -19t19 -45z" /> + <glyph glyph-name="resize_small" unicode="&#xf066;" +d="M768 576v-448q0 -26 -19 -45t-45 -19t-45 19l-144 144l-332 -332q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l332 332l-144 144q-19 19 -19 45t19 45t45 19h448q26 0 45 -19t19 -45zM1523 1248q0 -13 -10 -23l-332 -332l144 -144q19 -19 19 -45t-19 -45 +t-45 -19h-448q-26 0 -45 19t-19 45v448q0 26 19 45t45 19t45 -19l144 -144l332 332q10 10 23 10t23 -10l114 -114q10 -10 10 -23z" /> + <glyph glyph-name="plus" unicode="&#xf067;" horiz-adv-x="1408" +d="M1408 800v-192q0 -40 -28 -68t-68 -28h-416v-416q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v416h-416q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h416v416q0 40 28 68t68 28h192q40 0 68 -28t28 -68v-416h416q40 0 68 -28t28 -68z" /> + <glyph glyph-name="minus" unicode="&#xf068;" horiz-adv-x="1408" +d="M1408 800v-192q0 -40 -28 -68t-68 -28h-1216q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h1216q40 0 68 -28t28 -68z" /> + <glyph glyph-name="asterisk" unicode="&#xf069;" horiz-adv-x="1664" +d="M1482 486q46 -26 59.5 -77.5t-12.5 -97.5l-64 -110q-26 -46 -77.5 -59.5t-97.5 12.5l-266 153v-307q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v307l-266 -153q-46 -26 -97.5 -12.5t-77.5 59.5l-64 110q-26 46 -12.5 97.5t59.5 77.5l266 154l-266 154 +q-46 26 -59.5 77.5t12.5 97.5l64 110q26 46 77.5 59.5t97.5 -12.5l266 -153v307q0 52 38 90t90 38h128q52 0 90 -38t38 -90v-307l266 153q46 26 97.5 12.5t77.5 -59.5l64 -110q26 -46 12.5 -97.5t-59.5 -77.5l-266 -154z" /> + <glyph glyph-name="exclamation_sign" unicode="&#xf06a;" +d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM896 161v190q0 14 -9 23.5t-22 9.5h-192q-13 0 -23 -10t-10 -23v-190q0 -13 10 -23t23 -10h192 +q13 0 22 9.5t9 23.5zM894 505l18 621q0 12 -10 18q-10 8 -24 8h-220q-14 0 -24 -8q-10 -6 -10 -18l17 -621q0 -10 10 -17.5t24 -7.5h185q14 0 23.5 7.5t10.5 17.5z" /> + <glyph glyph-name="gift" unicode="&#xf06b;" +d="M928 180v56v468v192h-320v-192v-468v-56q0 -25 18 -38.5t46 -13.5h192q28 0 46 13.5t18 38.5zM472 1024h195l-126 161q-26 31 -69 31q-40 0 -68 -28t-28 -68t28 -68t68 -28zM1160 1120q0 40 -28 68t-68 28q-43 0 -69 -31l-125 -161h194q40 0 68 28t28 68zM1536 864v-320 +q0 -14 -9 -23t-23 -9h-96v-416q0 -40 -28 -68t-68 -28h-1088q-40 0 -68 28t-28 68v416h-96q-14 0 -23 9t-9 23v320q0 14 9 23t23 9h440q-93 0 -158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5q107 0 168 -77l128 -165l128 165q61 77 168 77q93 0 158.5 -65.5t65.5 -158.5 +t-65.5 -158.5t-158.5 -65.5h440q14 0 23 -9t9 -23z" /> + <glyph glyph-name="leaf" unicode="&#xf06c;" horiz-adv-x="1792" +d="M1280 832q0 26 -19 45t-45 19q-172 0 -318 -49.5t-259.5 -134t-235.5 -219.5q-19 -21 -19 -45q0 -26 19 -45t45 -19q24 0 45 19q27 24 74 71t67 66q137 124 268.5 176t313.5 52q26 0 45 19t19 45zM1792 1030q0 -95 -20 -193q-46 -224 -184.5 -383t-357.5 -268 +q-214 -108 -438 -108q-148 0 -286 47q-15 5 -88 42t-96 37q-16 0 -39.5 -32t-45 -70t-52.5 -70t-60 -32q-43 0 -63.5 17.5t-45.5 59.5q-2 4 -6 11t-5.5 10t-3 9.5t-1.5 13.5q0 35 31 73.5t68 65.5t68 56t31 48q0 4 -14 38t-16 44q-9 51 -9 104q0 115 43.5 220t119 184.5 +t170.5 139t204 95.5q55 18 145 25.5t179.5 9t178.5 6t163.5 24t113.5 56.5l29.5 29.5t29.5 28t27 20t36.5 16t43.5 4.5q39 0 70.5 -46t47.5 -112t24 -124t8 -96z" /> + <glyph glyph-name="fire" unicode="&#xf06d;" horiz-adv-x="1408" +d="M1408 -160v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1152 896q0 -78 -24.5 -144t-64 -112.5t-87.5 -88t-96 -77.5t-87.5 -72t-64 -81.5t-24.5 -96.5q0 -96 67 -224l-4 1l1 -1 +q-90 41 -160 83t-138.5 100t-113.5 122.5t-72.5 150.5t-27.5 184q0 78 24.5 144t64 112.5t87.5 88t96 77.5t87.5 72t64 81.5t24.5 96.5q0 94 -66 224l3 -1l-1 1q90 -41 160 -83t138.5 -100t113.5 -122.5t72.5 -150.5t27.5 -184z" /> + <glyph glyph-name="eye_open" unicode="&#xf06e;" horiz-adv-x="1792" +d="M1664 576q-152 236 -381 353q61 -104 61 -225q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 121 61 225q-229 -117 -381 -353q133 -205 333.5 -326.5t434.5 -121.5t434.5 121.5t333.5 326.5zM944 960q0 20 -14 34t-34 14q-125 0 -214.5 -89.5 +t-89.5 -214.5q0 -20 14 -34t34 -14t34 14t14 34q0 86 61 147t147 61q20 0 34 14t14 34zM1792 576q0 -34 -20 -69q-140 -230 -376.5 -368.5t-499.5 -138.5t-499.5 139t-376.5 368q-20 35 -20 69t20 69q140 229 376.5 368t499.5 139t499.5 -139t376.5 -368q20 -35 20 -69z" /> + <glyph glyph-name="eye_close" unicode="&#xf070;" horiz-adv-x="1792" +d="M555 201l78 141q-87 63 -136 159t-49 203q0 121 61 225q-229 -117 -381 -353q167 -258 427 -375zM944 960q0 20 -14 34t-34 14q-125 0 -214.5 -89.5t-89.5 -214.5q0 -20 14 -34t34 -14t34 14t14 34q0 86 61 147t147 61q20 0 34 14t14 34zM1307 1151q0 -7 -1 -9 +q-106 -189 -316 -567t-315 -566l-49 -89q-10 -16 -28 -16q-12 0 -134 70q-16 10 -16 28q0 12 44 87q-143 65 -263.5 173t-208.5 245q-20 31 -20 69t20 69q153 235 380 371t496 136q89 0 180 -17l54 97q10 16 28 16q5 0 18 -6t31 -15.5t33 -18.5t31.5 -18.5t19.5 -11.5 +q16 -10 16 -27zM1344 704q0 -139 -79 -253.5t-209 -164.5l280 502q8 -45 8 -84zM1792 576q0 -35 -20 -69q-39 -64 -109 -145q-150 -172 -347.5 -267t-419.5 -95l74 132q212 18 392.5 137t301.5 307q-115 179 -282 294l63 112q95 -64 182.5 -153t144.5 -184q20 -34 20 -69z +" /> + <glyph glyph-name="warning_sign" unicode="&#xf071;" horiz-adv-x="1792" +d="M1024 161v190q0 14 -9.5 23.5t-22.5 9.5h-192q-13 0 -22.5 -9.5t-9.5 -23.5v-190q0 -14 9.5 -23.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 23.5zM1022 535l18 459q0 12 -10 19q-13 11 -24 11h-220q-11 0 -24 -11q-10 -7 -10 -21l17 -457q0 -10 10 -16.5t24 -6.5h185 +q14 0 23.5 6.5t10.5 16.5zM1008 1469l768 -1408q35 -63 -2 -126q-17 -29 -46.5 -46t-63.5 -17h-1536q-34 0 -63.5 17t-46.5 46q-37 63 -2 126l768 1408q17 31 47 49t65 18t65 -18t47 -49z" /> + <glyph glyph-name="plane" unicode="&#xf072;" horiz-adv-x="1408" +d="M1376 1376q44 -52 12 -148t-108 -172l-161 -161l160 -696q5 -19 -12 -33l-128 -96q-7 -6 -19 -6q-4 0 -7 1q-15 3 -21 16l-279 508l-259 -259l53 -194q5 -17 -8 -31l-96 -96q-9 -9 -23 -9h-2q-15 2 -24 13l-189 252l-252 189q-11 7 -13 23q-1 13 9 25l96 97q9 9 23 9 +q6 0 8 -1l194 -53l259 259l-508 279q-14 8 -17 24q-2 16 9 27l128 128q14 13 30 8l665 -159l160 160q76 76 172 108t148 -12z" /> + <glyph glyph-name="calendar" unicode="&#xf073;" horiz-adv-x="1664" +d="M128 -128h288v288h-288v-288zM480 -128h320v288h-320v-288zM128 224h288v320h-288v-320zM480 224h320v320h-320v-320zM128 608h288v288h-288v-288zM864 -128h320v288h-320v-288zM480 608h320v288h-320v-288zM1248 -128h288v288h-288v-288zM864 224h320v320h-320v-320z +M512 1088v288q0 13 -9.5 22.5t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-288q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5zM1248 224h288v320h-288v-320zM864 608h320v288h-320v-288zM1248 608h288v288h-288v-288zM1280 1088v288q0 13 -9.5 22.5t-22.5 9.5h-64 +q-13 0 -22.5 -9.5t-9.5 -22.5v-288q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5zM1664 1152v-1280q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47 +h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90z" /> + <glyph glyph-name="random" unicode="&#xf074;" horiz-adv-x="1792" +d="M666 1055q-60 -92 -137 -273q-22 45 -37 72.5t-40.5 63.5t-51 56.5t-63 35t-81.5 14.5h-224q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h224q250 0 410 -225zM1792 256q0 -14 -9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v192q-32 0 -85 -0.5t-81 -1t-73 1 +t-71 5t-64 10.5t-63 18.5t-58 28.5t-59 40t-55 53.5t-56 69.5q59 93 136 273q22 -45 37 -72.5t40.5 -63.5t51 -56.5t63 -35t81.5 -14.5h256v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23zM1792 1152q0 -14 -9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5 +v192h-256q-48 0 -87 -15t-69 -45t-51 -61.5t-45 -77.5q-32 -62 -78 -171q-29 -66 -49.5 -111t-54 -105t-64 -100t-74 -83t-90 -68.5t-106.5 -42t-128 -16.5h-224q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h224q48 0 87 15t69 45t51 61.5t45 77.5q32 62 78 171q29 66 49.5 111 +t54 105t64 100t74 83t90 68.5t106.5 42t128 16.5h256v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23z" /> + <glyph glyph-name="comment" unicode="&#xf075;" horiz-adv-x="1792" +d="M1792 640q0 -174 -120 -321.5t-326 -233t-450 -85.5q-70 0 -145 8q-198 -175 -460 -242q-49 -14 -114 -22q-17 -2 -30.5 9t-17.5 29v1q-3 4 -0.5 12t2 10t4.5 9.5l6 9t7 8.5t8 9q7 8 31 34.5t34.5 38t31 39.5t32.5 51t27 59t26 76q-157 89 -247.5 220t-90.5 281 +q0 130 71 248.5t191 204.5t286 136.5t348 50.5q244 0 450 -85.5t326 -233t120 -321.5z" /> + <glyph glyph-name="magnet" unicode="&#xf076;" +d="M1536 704v-128q0 -201 -98.5 -362t-274 -251.5t-395.5 -90.5t-395.5 90.5t-274 251.5t-98.5 362v128q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-128q0 -52 23.5 -90t53.5 -57t71 -30t64 -13t44 -2t44 2t64 13t71 30t53.5 57t23.5 90v128q0 26 19 45t45 19h384 +q26 0 45 -19t19 -45zM512 1344v-384q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h384q26 0 45 -19t19 -45zM1536 1344v-384q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h384q26 0 45 -19t19 -45z" /> + <glyph glyph-name="chevron_up" unicode="&#xf077;" horiz-adv-x="1792" +d="M1683 205l-166 -165q-19 -19 -45 -19t-45 19l-531 531l-531 -531q-19 -19 -45 -19t-45 19l-166 165q-19 19 -19 45.5t19 45.5l742 741q19 19 45 19t45 -19l742 -741q19 -19 19 -45.5t-19 -45.5z" /> + <glyph glyph-name="chevron_down" unicode="&#xf078;" horiz-adv-x="1792" +d="M1683 728l-742 -741q-19 -19 -45 -19t-45 19l-742 741q-19 19 -19 45.5t19 45.5l166 165q19 19 45 19t45 -19l531 -531l531 531q19 19 45 19t45 -19l166 -165q19 -19 19 -45.5t-19 -45.5z" /> + <glyph glyph-name="retweet" unicode="&#xf079;" horiz-adv-x="1920" +d="M1280 32q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-8 0 -13.5 2t-9 7t-5.5 8t-3 11.5t-1 11.5v13v11v160v416h-192q-26 0 -45 19t-19 45q0 24 15 41l320 384q19 22 49 22t49 -22l320 -384q15 -17 15 -41q0 -26 -19 -45t-45 -19h-192v-384h576q16 0 25 -11l160 -192q7 -10 7 -21 +zM1920 448q0 -24 -15 -41l-320 -384q-20 -23 -49 -23t-49 23l-320 384q-15 17 -15 41q0 26 19 45t45 19h192v384h-576q-16 0 -25 12l-160 192q-7 9 -7 20q0 13 9.5 22.5t22.5 9.5h960q8 0 13.5 -2t9 -7t5.5 -8t3 -11.5t1 -11.5v-13v-11v-160v-416h192q26 0 45 -19t19 -45z +" /> + <glyph glyph-name="shopping_cart" unicode="&#xf07a;" horiz-adv-x="1664" +d="M640 0q0 -52 -38 -90t-90 -38t-90 38t-38 90t38 90t90 38t90 -38t38 -90zM1536 0q0 -52 -38 -90t-90 -38t-90 38t-38 90t38 90t90 38t90 -38t38 -90zM1664 1088v-512q0 -24 -16.5 -42.5t-40.5 -21.5l-1044 -122q13 -60 13 -70q0 -16 -24 -64h920q26 0 45 -19t19 -45 +t-19 -45t-45 -19h-1024q-26 0 -45 19t-19 45q0 11 8 31.5t16 36t21.5 40t15.5 29.5l-177 823h-204q-26 0 -45 19t-19 45t19 45t45 19h256q16 0 28.5 -6.5t19.5 -15.5t13 -24.5t8 -26t5.5 -29.5t4.5 -26h1201q26 0 45 -19t19 -45z" /> + <glyph glyph-name="folder_close" unicode="&#xf07b;" horiz-adv-x="1664" +d="M1664 928v-704q0 -92 -66 -158t-158 -66h-1216q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h672q92 0 158 -66t66 -158z" /> + <glyph glyph-name="folder_open" unicode="&#xf07c;" horiz-adv-x="1920" +d="M1879 584q0 -31 -31 -66l-336 -396q-43 -51 -120.5 -86.5t-143.5 -35.5h-1088q-34 0 -60.5 13t-26.5 43q0 31 31 66l336 396q43 51 120.5 86.5t143.5 35.5h1088q34 0 60.5 -13t26.5 -43zM1536 928v-160h-832q-94 0 -197 -47.5t-164 -119.5l-337 -396l-5 -6q0 4 -0.5 12.5 +t-0.5 12.5v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h544q92 0 158 -66t66 -158z" /> + <glyph glyph-name="resize_vertical" unicode="&#xf07d;" horiz-adv-x="768" +d="M704 1216q0 -26 -19 -45t-45 -19h-128v-1024h128q26 0 45 -19t19 -45t-19 -45l-256 -256q-19 -19 -45 -19t-45 19l-256 256q-19 19 -19 45t19 45t45 19h128v1024h-128q-26 0 -45 19t-19 45t19 45l256 256q19 19 45 19t45 -19l256 -256q19 -19 19 -45z" /> + <glyph glyph-name="resize_horizontal" unicode="&#xf07e;" horiz-adv-x="1792" +d="M1792 640q0 -26 -19 -45l-256 -256q-19 -19 -45 -19t-45 19t-19 45v128h-1024v-128q0 -26 -19 -45t-45 -19t-45 19l-256 256q-19 19 -19 45t19 45l256 256q19 19 45 19t45 -19t19 -45v-128h1024v128q0 26 19 45t45 19t45 -19l256 -256q19 -19 19 -45z" /> + <glyph glyph-name="bar_chart" unicode="&#xf080;" horiz-adv-x="2048" +d="M640 640v-512h-256v512h256zM1024 1152v-1024h-256v1024h256zM2048 0v-128h-2048v1536h128v-1408h1920zM1408 896v-768h-256v768h256zM1792 1280v-1152h-256v1152h256z" /> + <glyph glyph-name="twitter_sign" unicode="&#xf081;" +d="M1280 926q-56 -25 -121 -34q68 40 93 117q-65 -38 -134 -51q-61 66 -153 66q-87 0 -148.5 -61.5t-61.5 -148.5q0 -29 5 -48q-129 7 -242 65t-192 155q-29 -50 -29 -106q0 -114 91 -175q-47 1 -100 26v-2q0 -75 50 -133.5t123 -72.5q-29 -8 -51 -8q-13 0 -39 4 +q21 -63 74.5 -104t121.5 -42q-116 -90 -261 -90q-26 0 -50 3q148 -94 322 -94q112 0 210 35.5t168 95t120.5 137t75 162t24.5 168.5q0 18 -1 27q63 45 105 109zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5 +t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="facebook_sign" unicode="&#xf082;" +d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-188v595h199l30 232h-229v148q0 56 23.5 84t91.5 28l122 1v207q-63 9 -178 9q-136 0 -217.5 -80t-81.5 -226v-171h-200v-232h200v-595h-532q-119 0 -203.5 84.5t-84.5 203.5v960 +q0 119 84.5 203.5t203.5 84.5h960z" /> + <glyph glyph-name="camera_retro" unicode="&#xf083;" horiz-adv-x="1792" +d="M928 704q0 14 -9 23t-23 9q-66 0 -113 -47t-47 -113q0 -14 9 -23t23 -9t23 9t9 23q0 40 28 68t68 28q14 0 23 9t9 23zM1152 574q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181zM128 0h1536v128h-1536v-128zM1280 574q0 159 -112.5 271.5 +t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5zM256 1216h384v128h-384v-128zM128 1024h1536v118v138h-828l-64 -128h-644v-128zM1792 1280v-1280q0 -53 -37.5 -90.5t-90.5 -37.5h-1536q-53 0 -90.5 37.5t-37.5 90.5v1280 +q0 53 37.5 90.5t90.5 37.5h1536q53 0 90.5 -37.5t37.5 -90.5z" /> + <glyph glyph-name="key" unicode="&#xf084;" horiz-adv-x="1792" +d="M832 1024q0 80 -56 136t-136 56t-136 -56t-56 -136q0 -42 19 -83q-41 19 -83 19q-80 0 -136 -56t-56 -136t56 -136t136 -56t136 56t56 136q0 42 -19 83q41 -19 83 -19q80 0 136 56t56 136zM1683 320q0 -17 -49 -66t-66 -49q-9 0 -28.5 16t-36.5 33t-38.5 40t-24.5 26 +l-96 -96l220 -220q28 -28 28 -68q0 -42 -39 -81t-81 -39q-40 0 -68 28l-671 671q-176 -131 -365 -131q-163 0 -265.5 102.5t-102.5 265.5q0 160 95 313t248 248t313 95q163 0 265.5 -102.5t102.5 -265.5q0 -189 -131 -365l355 -355l96 96q-3 3 -26 24.5t-40 38.5t-33 36.5 +t-16 28.5q0 17 49 66t66 49q13 0 23 -10q6 -6 46 -44.5t82 -79.5t86.5 -86t73 -78t28.5 -41z" /> + <glyph glyph-name="cogs" unicode="&#xf085;" horiz-adv-x="1920" +d="M896 640q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1664 128q0 52 -38 90t-90 38t-90 -38t-38 -90q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1664 1152q0 52 -38 90t-90 38t-90 -38t-38 -90q0 -53 37.5 -90.5t90.5 -37.5 +t90.5 37.5t37.5 90.5zM1280 731v-185q0 -10 -7 -19.5t-16 -10.5l-155 -24q-11 -35 -32 -76q34 -48 90 -115q7 -11 7 -20q0 -12 -7 -19q-23 -30 -82.5 -89.5t-78.5 -59.5q-11 0 -21 7l-115 90q-37 -19 -77 -31q-11 -108 -23 -155q-7 -24 -30 -24h-186q-11 0 -20 7.5t-10 17.5 +l-23 153q-34 10 -75 31l-118 -89q-7 -7 -20 -7q-11 0 -21 8q-144 133 -144 160q0 9 7 19q10 14 41 53t47 61q-23 44 -35 82l-152 24q-10 1 -17 9.5t-7 19.5v185q0 10 7 19.5t16 10.5l155 24q11 35 32 76q-34 48 -90 115q-7 11 -7 20q0 12 7 20q22 30 82 89t79 59q11 0 21 -7 +l115 -90q34 18 77 32q11 108 23 154q7 24 30 24h186q11 0 20 -7.5t10 -17.5l23 -153q34 -10 75 -31l118 89q8 7 20 7q11 0 21 -8q144 -133 144 -160q0 -8 -7 -19q-12 -16 -42 -54t-45 -60q23 -48 34 -82l152 -23q10 -2 17 -10.5t7 -19.5zM1920 198v-140q0 -16 -149 -31 +q-12 -27 -30 -52q51 -113 51 -138q0 -4 -4 -7q-122 -71 -124 -71q-8 0 -46 47t-52 68q-20 -2 -30 -2t-30 2q-14 -21 -52 -68t-46 -47q-2 0 -124 71q-4 3 -4 7q0 25 51 138q-18 25 -30 52q-149 15 -149 31v140q0 16 149 31q13 29 30 52q-51 113 -51 138q0 4 4 7q4 2 35 20 +t59 34t30 16q8 0 46 -46.5t52 -67.5q20 2 30 2t30 -2q51 71 92 112l6 2q4 0 124 -70q4 -3 4 -7q0 -25 -51 -138q17 -23 30 -52q149 -15 149 -31zM1920 1222v-140q0 -16 -149 -31q-12 -27 -30 -52q51 -113 51 -138q0 -4 -4 -7q-122 -71 -124 -71q-8 0 -46 47t-52 68 +q-20 -2 -30 -2t-30 2q-14 -21 -52 -68t-46 -47q-2 0 -124 71q-4 3 -4 7q0 25 51 138q-18 25 -30 52q-149 15 -149 31v140q0 16 149 31q13 29 30 52q-51 113 -51 138q0 4 4 7q4 2 35 20t59 34t30 16q8 0 46 -46.5t52 -67.5q20 2 30 2t30 -2q51 71 92 112l6 2q4 0 124 -70 +q4 -3 4 -7q0 -25 -51 -138q17 -23 30 -52q149 -15 149 -31z" /> + <glyph glyph-name="comments" unicode="&#xf086;" horiz-adv-x="1792" +d="M1408 768q0 -139 -94 -257t-256.5 -186.5t-353.5 -68.5q-86 0 -176 16q-124 -88 -278 -128q-36 -9 -86 -16h-3q-11 0 -20.5 8t-11.5 21q-1 3 -1 6.5t0.5 6.5t2 6l2.5 5t3.5 5.5t4 5t4.5 5t4 4.5q5 6 23 25t26 29.5t22.5 29t25 38.5t20.5 44q-124 72 -195 177t-71 224 +q0 139 94 257t256.5 186.5t353.5 68.5t353.5 -68.5t256.5 -186.5t94 -257zM1792 512q0 -120 -71 -224.5t-195 -176.5q10 -24 20.5 -44t25 -38.5t22.5 -29t26 -29.5t23 -25q1 -1 4 -4.5t4.5 -5t4 -5t3.5 -5.5l2.5 -5t2 -6t0.5 -6.5t-1 -6.5q-3 -14 -13 -22t-22 -7 +q-50 7 -86 16q-154 40 -278 128q-90 -16 -176 -16q-271 0 -472 132q58 -4 88 -4q161 0 309 45t264 129q125 92 192 212t67 254q0 77 -23 152q129 -71 204 -178t75 -230z" /> + <glyph glyph-name="thumbs_up_alt" unicode="&#xf087;" +d="M256 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 768q0 51 -39 89.5t-89 38.5h-352q0 58 48 159.5t48 160.5q0 98 -32 145t-128 47q-26 -26 -38 -85t-30.5 -125.5t-59.5 -109.5q-22 -23 -77 -91q-4 -5 -23 -30t-31.5 -41t-34.5 -42.5 +t-40 -44t-38.5 -35.5t-40 -27t-35.5 -9h-32v-640h32q13 0 31.5 -3t33 -6.5t38 -11t35 -11.5t35.5 -12.5t29 -10.5q211 -73 342 -73h121q192 0 192 167q0 26 -5 56q30 16 47.5 52.5t17.5 73.5t-18 69q53 50 53 119q0 25 -10 55.5t-25 47.5q32 1 53.5 47t21.5 81zM1536 769 +q0 -89 -49 -163q9 -33 9 -69q0 -77 -38 -144q3 -21 3 -43q0 -101 -60 -178q1 -139 -85 -219.5t-227 -80.5h-36h-93q-96 0 -189.5 22.5t-216.5 65.5q-116 40 -138 40h-288q-53 0 -90.5 37.5t-37.5 90.5v640q0 53 37.5 90.5t90.5 37.5h274q36 24 137 155q58 75 107 128 +q24 25 35.5 85.5t30.5 126.5t62 108q39 37 90 37q84 0 151 -32.5t102 -101.5t35 -186q0 -93 -48 -192h176q104 0 180 -76t76 -179z" /> + <glyph glyph-name="thumbs_down_alt" unicode="&#xf088;" +d="M256 1088q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 512q0 35 -21.5 81t-53.5 47q15 17 25 47.5t10 55.5q0 69 -53 119q18 31 18 69q0 37 -17.5 73.5t-47.5 52.5q5 30 5 56q0 85 -49 126t-136 41h-128q-131 0 -342 -73q-5 -2 -29 -10.5 +t-35.5 -12.5t-35 -11.5t-38 -11t-33 -6.5t-31.5 -3h-32v-640h32q16 0 35.5 -9t40 -27t38.5 -35.5t40 -44t34.5 -42.5t31.5 -41t23 -30q55 -68 77 -91q41 -43 59.5 -109.5t30.5 -125.5t38 -85q96 0 128 47t32 145q0 59 -48 160.5t-48 159.5h352q50 0 89 38.5t39 89.5z +M1536 511q0 -103 -76 -179t-180 -76h-176q48 -99 48 -192q0 -118 -35 -186q-35 -69 -102 -101.5t-151 -32.5q-51 0 -90 37q-34 33 -54 82t-25.5 90.5t-17.5 84.5t-31 64q-48 50 -107 127q-101 131 -137 155h-274q-53 0 -90.5 37.5t-37.5 90.5v640q0 53 37.5 90.5t90.5 37.5 +h288q22 0 138 40q128 44 223 66t200 22h112q140 0 226.5 -79t85.5 -216v-5q60 -77 60 -178q0 -22 -3 -43q38 -67 38 -144q0 -36 -9 -69q49 -73 49 -163z" /> + <glyph glyph-name="star_half" unicode="&#xf089;" horiz-adv-x="896" +d="M832 1504v-1339l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41z" /> + <glyph glyph-name="heart_empty" unicode="&#xf08a;" horiz-adv-x="1792" +d="M1664 940q0 81 -21.5 143t-55 98.5t-81.5 59.5t-94 31t-98 8t-112 -25.5t-110.5 -64t-86.5 -72t-60 -61.5q-18 -22 -49 -22t-49 22q-24 28 -60 61.5t-86.5 72t-110.5 64t-112 25.5t-98 -8t-94 -31t-81.5 -59.5t-55 -98.5t-21.5 -143q0 -168 187 -355l581 -560l580 559 +q188 188 188 356zM1792 940q0 -221 -229 -450l-623 -600q-18 -18 -44 -18t-44 18l-624 602q-10 8 -27.5 26t-55.5 65.5t-68 97.5t-53.5 121t-23.5 138q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5 +q224 0 351 -124t127 -344z" /> + <glyph glyph-name="signout" unicode="&#xf08b;" horiz-adv-x="1664" +d="M640 96q0 -4 1 -20t0.5 -26.5t-3 -23.5t-10 -19.5t-20.5 -6.5h-320q-119 0 -203.5 84.5t-84.5 203.5v704q0 119 84.5 203.5t203.5 84.5h320q13 0 22.5 -9.5t9.5 -22.5q0 -4 1 -20t0.5 -26.5t-3 -23.5t-10 -19.5t-20.5 -6.5h-320q-66 0 -113 -47t-47 -113v-704 +q0 -66 47 -113t113 -47h288h11h13t11.5 -1t11.5 -3t8 -5.5t7 -9t2 -13.5zM1568 640q0 -26 -19 -45l-544 -544q-19 -19 -45 -19t-45 19t-19 45v288h-448q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h448v288q0 26 19 45t45 19t45 -19l544 -544q19 -19 19 -45z" /> + <glyph glyph-name="linkedin_sign" unicode="&#xf08c;" +d="M237 122h231v694h-231v-694zM483 1030q-1 52 -36 86t-93 34t-94.5 -34t-36.5 -86q0 -51 35.5 -85.5t92.5 -34.5h1q59 0 95 34.5t36 85.5zM1068 122h231v398q0 154 -73 233t-193 79q-136 0 -209 -117h2v101h-231q3 -66 0 -694h231v388q0 38 7 56q15 35 45 59.5t74 24.5 +q116 0 116 -157v-371zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="pushpin" unicode="&#xf08d;" horiz-adv-x="1152" +d="M480 672v448q0 14 -9 23t-23 9t-23 -9t-9 -23v-448q0 -14 9 -23t23 -9t23 9t9 23zM1152 320q0 -26 -19 -45t-45 -19h-429l-51 -483q-2 -12 -10.5 -20.5t-20.5 -8.5h-1q-27 0 -32 27l-76 485h-404q-26 0 -45 19t-19 45q0 123 78.5 221.5t177.5 98.5v512q-52 0 -90 38 +t-38 90t38 90t90 38h640q52 0 90 -38t38 -90t-38 -90t-90 -38v-512q99 0 177.5 -98.5t78.5 -221.5z" /> + <glyph glyph-name="external_link" unicode="&#xf08e;" horiz-adv-x="1792" +d="M1408 608v-320q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h704q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v320 +q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1792 1472v-512q0 -26 -19 -45t-45 -19t-45 19l-176 176l-652 -652q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l652 652l-176 176q-19 19 -19 45t19 45t45 19h512q26 0 45 -19t19 -45z" /> + <glyph glyph-name="signin" unicode="&#xf090;" +d="M1184 640q0 -26 -19 -45l-544 -544q-19 -19 -45 -19t-45 19t-19 45v288h-448q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h448v288q0 26 19 45t45 19t45 -19l544 -544q19 -19 19 -45zM1536 992v-704q0 -119 -84.5 -203.5t-203.5 -84.5h-320q-13 0 -22.5 9.5t-9.5 22.5 +q0 4 -1 20t-0.5 26.5t3 23.5t10 19.5t20.5 6.5h320q66 0 113 47t47 113v704q0 66 -47 113t-113 47h-288h-11h-13t-11.5 1t-11.5 3t-8 5.5t-7 9t-2 13.5q0 4 -1 20t-0.5 26.5t3 23.5t10 19.5t20.5 6.5h320q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="trophy" unicode="&#xf091;" horiz-adv-x="1664" +d="M458 653q-74 162 -74 371h-256v-96q0 -78 94.5 -162t235.5 -113zM1536 928v96h-256q0 -209 -74 -371q141 29 235.5 113t94.5 162zM1664 1056v-128q0 -71 -41.5 -143t-112 -130t-173 -97.5t-215.5 -44.5q-42 -54 -95 -95q-38 -34 -52.5 -72.5t-14.5 -89.5q0 -54 30.5 -91 +t97.5 -37q75 0 133.5 -45.5t58.5 -114.5v-64q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v64q0 69 58.5 114.5t133.5 45.5q67 0 97.5 37t30.5 91q0 51 -14.5 89.5t-52.5 72.5q-53 41 -95 95q-113 5 -215.5 44.5t-173 97.5t-112 130t-41.5 143v128q0 40 28 68t68 28h288v96 +q0 66 47 113t113 47h576q66 0 113 -47t47 -113v-96h288q40 0 68 -28t28 -68z" /> + <glyph glyph-name="github_sign" unicode="&#xf092;" +d="M519 336q4 6 -3 13q-9 7 -14 2q-4 -6 3 -13q9 -7 14 -2zM491 377q-5 7 -12 4q-6 -4 0 -12q7 -8 12 -5q6 4 0 13zM450 417q2 4 -5 8q-7 2 -8 -2q-3 -5 4 -8q8 -2 9 2zM471 394q2 1 1.5 4.5t-3.5 5.5q-6 7 -10 3t1 -11q6 -6 11 -2zM557 319q2 7 -9 11q-9 3 -13 -4 +q-2 -7 9 -11q9 -3 13 4zM599 316q0 8 -12 8q-10 0 -10 -8t11 -8t11 8zM638 323q-2 7 -13 5t-9 -9q2 -8 12 -6t10 10zM1280 640q0 212 -150 362t-362 150t-362 -150t-150 -362q0 -167 98 -300.5t252 -185.5q18 -3 26.5 5t8.5 20q0 52 -1 95q-6 -1 -15.5 -2.5t-35.5 -2t-48 4 +t-43.5 20t-29.5 41.5q-23 59 -57 74q-2 1 -4.5 3.5l-8 8t-7 9.5t4 7.5t19.5 3.5q6 0 15 -2t30 -15.5t33 -35.5q16 -28 37.5 -42t43.5 -14t38 3.5t30 9.5q7 47 33 69q-49 6 -86 18.5t-73 39t-55.5 76t-19.5 119.5q0 79 53 137q-24 62 5 136q19 6 54.5 -7.5t60.5 -29.5l26 -16 +q58 17 128 17t128 -17q11 7 28.5 18t55.5 26t57 9q29 -74 5 -136q53 -58 53 -137q0 -57 -14 -100.5t-35.5 -70t-53.5 -44.5t-62.5 -26t-68.5 -12q35 -31 35 -95q0 -40 -0.5 -89t-0.5 -51q0 -12 8.5 -20t26.5 -5q154 52 252 185.5t98 300.5zM1536 1120v-960 +q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="upload_alt" unicode="&#xf093;" horiz-adv-x="1664" +d="M1280 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 288v-320q0 -40 -28 -68t-68 -28h-1472q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h427q21 -56 70.5 -92 +t110.5 -36h256q61 0 110.5 36t70.5 92h427q40 0 68 -28t28 -68zM1339 936q-17 -40 -59 -40h-256v-448q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v448h-256q-42 0 -59 40q-17 39 14 69l448 448q18 19 45 19t45 -19l448 -448q31 -30 14 -69z" /> + <glyph glyph-name="lemon" unicode="&#xf094;" +d="M1407 710q0 44 -7 113.5t-18 96.5q-12 30 -17 44t-9 36.5t-4 48.5q0 23 5 68.5t5 67.5q0 37 -10 55q-4 1 -13 1q-19 0 -58 -4.5t-59 -4.5q-60 0 -176 24t-175 24q-43 0 -94.5 -11.5t-85 -23.5t-89.5 -34q-137 -54 -202 -103q-96 -73 -159.5 -189.5t-88 -236t-24.5 -248.5 +q0 -40 12.5 -120t12.5 -121q0 -23 -11 -66.5t-11 -65.5t12 -36.5t34 -14.5q24 0 72.5 11t73.5 11q57 0 169.5 -15.5t169.5 -15.5q181 0 284 36q129 45 235.5 152.5t166 245.5t59.5 275zM1535 712q0 -165 -70 -327.5t-196 -288t-281 -180.5q-124 -44 -326 -44 +q-57 0 -170 14.5t-169 14.5q-24 0 -72.5 -14.5t-73.5 -14.5q-73 0 -123.5 55.5t-50.5 128.5q0 24 11 68t11 67q0 40 -12.5 120.5t-12.5 121.5q0 111 18 217.5t54.5 209.5t100.5 194t150 156q78 59 232 120q194 78 316 78q60 0 175.5 -24t173.5 -24q19 0 57 5t58 5 +q81 0 118 -50.5t37 -134.5q0 -23 -5 -68t-5 -68q0 -13 2 -25t3.5 -16.5t7.5 -20.5t8 -20q16 -40 25 -118.5t9 -136.5z" /> + <glyph glyph-name="phone" unicode="&#xf095;" horiz-adv-x="1408" +d="M1408 296q0 -27 -10 -70.5t-21 -68.5q-21 -50 -122 -106q-94 -51 -186 -51q-27 0 -53 3.5t-57.5 12.5t-47 14.5t-55.5 20.5t-49 18q-98 35 -175 83q-127 79 -264 216t-216 264q-48 77 -83 175q-3 9 -18 49t-20.5 55.5t-14.5 47t-12.5 57.5t-3.5 53q0 92 51 186 +q56 101 106 122q25 11 68.5 21t70.5 10q14 0 21 -3q18 -6 53 -76q11 -19 30 -54t35 -63.5t31 -53.5q3 -4 17.5 -25t21.5 -35.5t7 -28.5q0 -20 -28.5 -50t-62 -55t-62 -53t-28.5 -46q0 -9 5 -22.5t8.5 -20.5t14 -24t11.5 -19q76 -137 174 -235t235 -174q2 -1 19 -11.5t24 -14 +t20.5 -8.5t22.5 -5q18 0 46 28.5t53 62t55 62t50 28.5q14 0 28.5 -7t35.5 -21.5t25 -17.5q25 -15 53.5 -31t63.5 -35t54 -30q70 -35 76 -53q3 -7 3 -21z" /> + <glyph glyph-name="check_empty" unicode="&#xf096;" horiz-adv-x="1408" +d="M1120 1280h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v832q0 66 -47 113t-113 47zM1408 1120v-832q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832 +q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="bookmark_empty" unicode="&#xf097;" horiz-adv-x="1280" +d="M1152 1280h-1024v-1242l423 406l89 85l89 -85l423 -406v1242zM1164 1408q23 0 44 -9q33 -13 52.5 -41t19.5 -62v-1289q0 -34 -19.5 -62t-52.5 -41q-19 -8 -44 -8q-48 0 -83 32l-441 424l-441 -424q-36 -33 -83 -33q-23 0 -44 9q-33 13 -52.5 41t-19.5 62v1289 +q0 34 19.5 62t52.5 41q21 9 44 9h1048z" /> + <glyph glyph-name="phone_sign" unicode="&#xf098;" +d="M1280 343q0 11 -2 16t-18 16.5t-40.5 25t-47.5 26.5t-45.5 25t-28.5 15q-5 3 -19 13t-25 15t-21 5q-15 0 -36.5 -20.5t-39.5 -45t-38.5 -45t-33.5 -20.5q-7 0 -16.5 3.5t-15.5 6.5t-17 9.5t-14 8.5q-99 55 -170 126.5t-127 170.5q-2 3 -8.5 14t-9.5 17t-6.5 15.5 +t-3.5 16.5q0 13 20.5 33.5t45 38.5t45 39.5t20.5 36.5q0 10 -5 21t-15 25t-13 19q-3 6 -15 28.5t-25 45.5t-26.5 47.5t-25 40.5t-16.5 18t-16 2q-48 0 -101 -22q-46 -21 -80 -94.5t-34 -130.5q0 -16 2.5 -34t5 -30.5t9 -33t10 -29.5t12.5 -33t11 -30q60 -164 216.5 -320.5 +t320.5 -216.5q6 -2 30 -11t33 -12.5t29.5 -10t33 -9t30.5 -5t34 -2.5q57 0 130.5 34t94.5 80q22 53 22 101zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z +" /> + <glyph glyph-name="twitter" unicode="&#xf099;" horiz-adv-x="1664" +d="M1620 1128q-67 -98 -162 -167q1 -14 1 -42q0 -130 -38 -259.5t-115.5 -248.5t-184.5 -210.5t-258 -146t-323 -54.5q-271 0 -496 145q35 -4 78 -4q225 0 401 138q-105 2 -188 64.5t-114 159.5q33 -5 61 -5q43 0 85 11q-112 23 -185.5 111.5t-73.5 205.5v4q68 -38 146 -41 +q-66 44 -105 115t-39 154q0 88 44 163q121 -149 294.5 -238.5t371.5 -99.5q-8 38 -8 74q0 134 94.5 228.5t228.5 94.5q140 0 236 -102q109 21 205 78q-37 -115 -142 -178q93 10 186 50z" /> + <glyph glyph-name="facebook" unicode="&#xf09a;" horiz-adv-x="1024" +d="M959 1524v-264h-157q-86 0 -116 -36t-30 -108v-189h293l-39 -296h-254v-759h-306v759h-255v296h255v218q0 186 104 288.5t277 102.5q147 0 228 -12z" /> + <glyph glyph-name="github" unicode="&#xf09b;" +d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5q0 -251 -146.5 -451.5t-378.5 -277.5q-27 -5 -40 7t-13 30q0 3 0.5 76.5t0.5 134.5q0 97 -52 142q57 6 102.5 18t94 39t81 66.5t53 105t20.5 150.5q0 119 -79 206q37 91 -8 204q-28 9 -81 -11t-92 -44l-38 -24 +q-93 26 -192 26t-192 -26q-16 11 -42.5 27t-83.5 38.5t-85 13.5q-45 -113 -8 -204q-79 -87 -79 -206q0 -85 20.5 -150t52.5 -105t80.5 -67t94 -39t102.5 -18q-39 -36 -49 -103q-21 -10 -45 -15t-57 -5t-65.5 21.5t-55.5 62.5q-19 32 -48.5 52t-49.5 24l-20 3q-21 0 -29 -4.5 +t-5 -11.5t9 -14t13 -12l7 -5q22 -10 43.5 -38t31.5 -51l10 -23q13 -38 44 -61.5t67 -30t69.5 -7t55.5 3.5l23 4q0 -38 0.5 -88.5t0.5 -54.5q0 -18 -13 -30t-40 -7q-232 77 -378.5 277.5t-146.5 451.5q0 209 103 385.5t279.5 279.5t385.5 103zM291 305q3 7 -7 12 +q-10 3 -13 -2q-3 -7 7 -12q9 -6 13 2zM322 271q7 5 -2 16q-10 9 -16 3q-7 -5 2 -16q10 -10 16 -3zM352 226q9 7 0 19q-8 13 -17 6q-9 -5 0 -18t17 -7zM394 184q8 8 -4 19q-12 12 -20 3q-9 -8 4 -19q12 -12 20 -3zM451 159q3 11 -13 16q-15 4 -19 -7t13 -15q15 -6 19 6z +M514 154q0 13 -17 11q-16 0 -16 -11q0 -13 17 -11q16 0 16 11zM572 164q-2 11 -18 9q-16 -3 -14 -15t18 -8t14 14z" /> + <glyph glyph-name="unlock" unicode="&#xf09c;" horiz-adv-x="1664" +d="M1664 960v-256q0 -26 -19 -45t-45 -19h-64q-26 0 -45 19t-19 45v256q0 106 -75 181t-181 75t-181 -75t-75 -181v-192h96q40 0 68 -28t28 -68v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v576q0 40 28 68t68 28h672v192q0 185 131.5 316.5t316.5 131.5 +t316.5 -131.5t131.5 -316.5z" /> + <glyph glyph-name="credit_card" unicode="&#xf09d;" horiz-adv-x="1920" +d="M1760 1408q66 0 113 -47t47 -113v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1600zM160 1280q-13 0 -22.5 -9.5t-9.5 -22.5v-224h1664v224q0 13 -9.5 22.5t-22.5 9.5h-1600zM1760 0q13 0 22.5 9.5t9.5 22.5v608h-1664v-608 +q0 -13 9.5 -22.5t22.5 -9.5h1600zM256 128v128h256v-128h-256zM640 128v128h384v-128h-384z" /> + <glyph glyph-name="rss" unicode="&#xf09e;" horiz-adv-x="1408" +d="M384 192q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM896 69q2 -28 -17 -48q-18 -21 -47 -21h-135q-25 0 -43 16.5t-20 41.5q-22 229 -184.5 391.5t-391.5 184.5q-25 2 -41.5 20t-16.5 43v135q0 29 21 47q17 17 43 17h5q160 -13 306 -80.5 +t259 -181.5q114 -113 181.5 -259t80.5 -306zM1408 67q2 -27 -18 -47q-18 -20 -46 -20h-143q-26 0 -44.5 17.5t-19.5 42.5q-12 215 -101 408.5t-231.5 336t-336 231.5t-408.5 102q-25 1 -42.5 19.5t-17.5 43.5v143q0 28 20 46q18 18 44 18h3q262 -13 501.5 -120t425.5 -294 +q187 -186 294 -425.5t120 -501.5z" /> + <glyph glyph-name="hdd" unicode="&#xf0a0;" +d="M1040 320q0 -33 -23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5t23.5 56.5t56.5 23.5t56.5 -23.5t23.5 -56.5zM1296 320q0 -33 -23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5t23.5 56.5t56.5 23.5t56.5 -23.5t23.5 -56.5zM1408 160v320q0 13 -9.5 22.5t-22.5 9.5 +h-1216q-13 0 -22.5 -9.5t-9.5 -22.5v-320q0 -13 9.5 -22.5t22.5 -9.5h1216q13 0 22.5 9.5t9.5 22.5zM178 640h1180l-157 482q-4 13 -16 21.5t-26 8.5h-782q-14 0 -26 -8.5t-16 -21.5zM1536 480v-320q0 -66 -47 -113t-113 -47h-1216q-66 0 -113 47t-47 113v320q0 25 16 75 +l197 606q17 53 63 86t101 33h782q55 0 101 -33t63 -86l197 -606q16 -50 16 -75z" /> + <glyph glyph-name="bullhorn" unicode="&#xf0a1;" horiz-adv-x="1792" +d="M1664 896q53 0 90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5v-384q0 -52 -38 -90t-90 -38q-417 347 -812 380q-58 -19 -91 -66t-31 -100.5t40 -92.5q-20 -33 -23 -65.5t6 -58t33.5 -55t48 -50t61.5 -50.5q-29 -58 -111.5 -83t-168.5 -11.5t-132 55.5q-7 23 -29.5 87.5 +t-32 94.5t-23 89t-15 101t3.5 98.5t22 110.5h-122q-66 0 -113 47t-47 113v192q0 66 47 113t113 47h480q435 0 896 384q52 0 90 -38t38 -90v-384zM1536 292v954q-394 -302 -768 -343v-270q377 -42 768 -341z" /> + <glyph glyph-name="bell" unicode="&#xf0a2;" horiz-adv-x="1792" +d="M912 -160q0 16 -16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16zM246 128h1300q-266 300 -266 832q0 51 -24 105t-69 103t-121.5 80.5t-169.5 31.5t-169.5 -31.5t-121.5 -80.5t-69 -103t-24 -105q0 -532 -266 -832z +M1728 128q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-181 75t-75 181h-448q-52 0 -90 38t-38 90q50 42 91 88t85 119.5t74.5 158.5t50 206t19.5 260q0 152 117 282.5t307 158.5q-8 19 -8 39q0 40 28 68t68 28t68 -28t28 -68q0 -20 -8 -39q190 -28 307 -158.5 +t117 -282.5q0 -139 19.5 -260t50 -206t74.5 -158.5t85 -119.5t91 -88z" /> + <glyph glyph-name="certificate" unicode="&#xf0a3;" +d="M1376 640l138 -135q30 -28 20 -70q-12 -41 -52 -51l-188 -48l53 -186q12 -41 -19 -70q-29 -31 -70 -19l-186 53l-48 -188q-10 -40 -51 -52q-12 -2 -19 -2q-31 0 -51 22l-135 138l-135 -138q-28 -30 -70 -20q-41 11 -51 52l-48 188l-186 -53q-41 -12 -70 19q-31 29 -19 70 +l53 186l-188 48q-40 10 -52 51q-10 42 20 70l138 135l-138 135q-30 28 -20 70q12 41 52 51l188 48l-53 186q-12 41 19 70q29 31 70 19l186 -53l48 188q10 41 51 51q41 12 70 -19l135 -139l135 139q29 30 70 19q41 -10 51 -51l48 -188l186 53q41 12 70 -19q31 -29 19 -70 +l-53 -186l188 -48q40 -10 52 -51q10 -42 -20 -70z" /> + <glyph glyph-name="hand_right" unicode="&#xf0a4;" horiz-adv-x="1792" +d="M256 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 768q0 51 -39 89.5t-89 38.5h-576q0 20 15 48.5t33 55t33 68t15 84.5q0 67 -44.5 97.5t-115.5 30.5q-24 0 -90 -139q-24 -44 -37 -65q-40 -64 -112 -145q-71 -81 -101 -106 +q-69 -57 -140 -57h-32v-640h32q72 0 167 -32t193.5 -64t179.5 -32q189 0 189 167q0 26 -5 56q30 16 47.5 52.5t17.5 73.5t-18 69q53 50 53 119q0 25 -10 55.5t-25 47.5h331q52 0 90 38t38 90zM1792 769q0 -105 -75.5 -181t-180.5 -76h-169q-4 -62 -37 -119q3 -21 3 -43 +q0 -101 -60 -178q1 -139 -85 -219.5t-227 -80.5q-133 0 -322 69q-164 59 -223 59h-288q-53 0 -90.5 37.5t-37.5 90.5v640q0 53 37.5 90.5t90.5 37.5h288q10 0 21.5 4.5t23.5 14t22.5 18t24 22.5t20.5 21.5t19 21.5t14 17q65 74 100 129q13 21 33 62t37 72t40.5 63t55 49.5 +t69.5 17.5q125 0 206.5 -67t81.5 -189q0 -68 -22 -128h374q104 0 180 -76t76 -179z" /> + <glyph glyph-name="hand_left" unicode="&#xf0a5;" horiz-adv-x="1792" +d="M1376 128h32v640h-32q-35 0 -67.5 12t-62.5 37t-50 46t-49 54q-8 9 -12 14q-72 81 -112 145q-14 22 -38 68q-1 3 -10.5 22.5t-18.5 36t-20 35.5t-21.5 30.5t-18.5 11.5q-71 0 -115.5 -30.5t-44.5 -97.5q0 -43 15 -84.5t33 -68t33 -55t15 -48.5h-576q-50 0 -89 -38.5 +t-39 -89.5q0 -52 38 -90t90 -38h331q-15 -17 -25 -47.5t-10 -55.5q0 -69 53 -119q-18 -32 -18 -69t17.5 -73.5t47.5 -52.5q-4 -24 -4 -56q0 -85 48.5 -126t135.5 -41q84 0 183 32t194 64t167 32zM1664 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45z +M1792 768v-640q0 -53 -37.5 -90.5t-90.5 -37.5h-288q-59 0 -223 -59q-190 -69 -317 -69q-142 0 -230 77.5t-87 217.5l1 5q-61 76 -61 178q0 22 3 43q-33 57 -37 119h-169q-105 0 -180.5 76t-75.5 181q0 103 76 179t180 76h374q-22 60 -22 128q0 122 81.5 189t206.5 67 +q38 0 69.5 -17.5t55 -49.5t40.5 -63t37 -72t33 -62q35 -55 100 -129q2 -3 14 -17t19 -21.5t20.5 -21.5t24 -22.5t22.5 -18t23.5 -14t21.5 -4.5h288q53 0 90.5 -37.5t37.5 -90.5z" /> + <glyph glyph-name="hand_up" unicode="&#xf0a6;" +d="M1280 -64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 700q0 189 -167 189q-26 0 -56 -5q-16 30 -52.5 47.5t-73.5 17.5t-69 -18q-50 53 -119 53q-25 0 -55.5 -10t-47.5 -25v331q0 52 -38 90t-90 38q-51 0 -89.5 -39t-38.5 -89v-576 +q-20 0 -48.5 15t-55 33t-68 33t-84.5 15q-67 0 -97.5 -44.5t-30.5 -115.5q0 -24 139 -90q44 -24 65 -37q64 -40 145 -112q81 -71 106 -101q57 -69 57 -140v-32h640v32q0 72 32 167t64 193.5t32 179.5zM1536 705q0 -133 -69 -322q-59 -164 -59 -223v-288q0 -53 -37.5 -90.5 +t-90.5 -37.5h-640q-53 0 -90.5 37.5t-37.5 90.5v288q0 10 -4.5 21.5t-14 23.5t-18 22.5t-22.5 24t-21.5 20.5t-21.5 19t-17 14q-74 65 -129 100q-21 13 -62 33t-72 37t-63 40.5t-49.5 55t-17.5 69.5q0 125 67 206.5t189 81.5q68 0 128 -22v374q0 104 76 180t179 76 +q105 0 181 -75.5t76 -180.5v-169q62 -4 119 -37q21 3 43 3q101 0 178 -60q139 1 219.5 -85t80.5 -227z" /> + <glyph glyph-name="hand_down" unicode="&#xf0a7;" +d="M1408 576q0 84 -32 183t-64 194t-32 167v32h-640v-32q0 -35 -12 -67.5t-37 -62.5t-46 -50t-54 -49q-9 -8 -14 -12q-81 -72 -145 -112q-22 -14 -68 -38q-3 -1 -22.5 -10.5t-36 -18.5t-35.5 -20t-30.5 -21.5t-11.5 -18.5q0 -71 30.5 -115.5t97.5 -44.5q43 0 84.5 15t68 33 +t55 33t48.5 15v-576q0 -50 38.5 -89t89.5 -39q52 0 90 38t38 90v331q46 -35 103 -35q69 0 119 53q32 -18 69 -18t73.5 17.5t52.5 47.5q24 -4 56 -4q85 0 126 48.5t41 135.5zM1280 1344q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 580 +q0 -142 -77.5 -230t-217.5 -87l-5 1q-76 -61 -178 -61q-22 0 -43 3q-54 -30 -119 -37v-169q0 -105 -76 -180.5t-181 -75.5q-103 0 -179 76t-76 180v374q-54 -22 -128 -22q-121 0 -188.5 81.5t-67.5 206.5q0 38 17.5 69.5t49.5 55t63 40.5t72 37t62 33q55 35 129 100 +q3 2 17 14t21.5 19t21.5 20.5t22.5 24t18 22.5t14 23.5t4.5 21.5v288q0 53 37.5 90.5t90.5 37.5h640q53 0 90.5 -37.5t37.5 -90.5v-288q0 -59 59 -223q69 -190 69 -317z" /> + <glyph glyph-name="circle_arrow_left" unicode="&#xf0a8;" +d="M1280 576v128q0 26 -19 45t-45 19h-502l189 189q19 19 19 45t-19 45l-91 91q-18 18 -45 18t-45 -18l-362 -362l-91 -91q-18 -18 -18 -45t18 -45l91 -91l362 -362q18 -18 45 -18t45 18l91 91q18 18 18 45t-18 45l-189 189h502q26 0 45 19t19 45zM1536 640 +q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="circle_arrow_right" unicode="&#xf0a9;" +d="M1285 640q0 27 -18 45l-91 91l-362 362q-18 18 -45 18t-45 -18l-91 -91q-18 -18 -18 -45t18 -45l189 -189h-502q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h502l-189 -189q-19 -19 -19 -45t19 -45l91 -91q18 -18 45 -18t45 18l362 362l91 91q18 18 18 45zM1536 640 +q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="circle_arrow_up" unicode="&#xf0aa;" +d="M1284 641q0 27 -18 45l-362 362l-91 91q-18 18 -45 18t-45 -18l-91 -91l-362 -362q-18 -18 -18 -45t18 -45l91 -91q18 -18 45 -18t45 18l189 189v-502q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v502l189 -189q19 -19 45 -19t45 19l91 91q18 18 18 45zM1536 640 +q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="circle_arrow_down" unicode="&#xf0ab;" +d="M1284 639q0 27 -18 45l-91 91q-18 18 -45 18t-45 -18l-189 -189v502q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-502l-189 189q-19 19 -45 19t-45 -19l-91 -91q-18 -18 -18 -45t18 -45l362 -362l91 -91q18 -18 45 -18t45 18l91 91l362 362q18 18 18 45zM1536 640 +q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="globe" unicode="&#xf0ac;" +d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM1042 887q-2 -1 -9.5 -9.5t-13.5 -9.5q2 0 4.5 5t5 11t3.5 7q6 7 22 15q14 6 52 12q34 8 51 -11 +q-2 2 9.5 13t14.5 12q3 2 15 4.5t15 7.5l2 22q-12 -1 -17.5 7t-6.5 21q0 -2 -6 -8q0 7 -4.5 8t-11.5 -1t-9 -1q-10 3 -15 7.5t-8 16.5t-4 15q-2 5 -9.5 11t-9.5 10q-1 2 -2.5 5.5t-3 6.5t-4 5.5t-5.5 2.5t-7 -5t-7.5 -10t-4.5 -5q-3 2 -6 1.5t-4.5 -1t-4.5 -3t-5 -3.5 +q-3 -2 -8.5 -3t-8.5 -2q15 5 -1 11q-10 4 -16 3q9 4 7.5 12t-8.5 14h5q-1 4 -8.5 8.5t-17.5 8.5t-13 6q-8 5 -34 9.5t-33 0.5q-5 -6 -4.5 -10.5t4 -14t3.5 -12.5q1 -6 -5.5 -13t-6.5 -12q0 -7 14 -15.5t10 -21.5q-3 -8 -16 -16t-16 -12q-5 -8 -1.5 -18.5t10.5 -16.5 +q2 -2 1.5 -4t-3.5 -4.5t-5.5 -4t-6.5 -3.5l-3 -2q-11 -5 -20.5 6t-13.5 26q-7 25 -16 30q-23 8 -29 -1q-5 13 -41 26q-25 9 -58 4q6 1 0 15q-7 15 -19 12q3 6 4 17.5t1 13.5q3 13 12 23q1 1 7 8.5t9.5 13.5t0.5 6q35 -4 50 11q5 5 11.5 17t10.5 17q9 6 14 5.5t14.5 -5.5 +t14.5 -5q14 -1 15.5 11t-7.5 20q12 -1 3 17q-4 7 -8 9q-12 4 -27 -5q-8 -4 2 -8q-1 1 -9.5 -10.5t-16.5 -17.5t-16 5q-1 1 -5.5 13.5t-9.5 13.5q-8 0 -16 -15q3 8 -11 15t-24 8q19 12 -8 27q-7 4 -20.5 5t-19.5 -4q-5 -7 -5.5 -11.5t5 -8t10.5 -5.5t11.5 -4t8.5 -3 +q14 -10 8 -14q-2 -1 -8.5 -3.5t-11.5 -4.5t-6 -4q-3 -4 0 -14t-2 -14q-5 5 -9 17.5t-7 16.5q7 -9 -25 -6l-10 1q-4 0 -16 -2t-20.5 -1t-13.5 8q-4 8 0 20q1 4 4 2q-4 3 -11 9.5t-10 8.5q-46 -15 -94 -41q6 -1 12 1q5 2 13 6.5t10 5.5q34 14 42 7l5 5q14 -16 20 -25 +q-7 4 -30 1q-20 -6 -22 -12q7 -12 5 -18q-4 3 -11.5 10t-14.5 11t-15 5q-16 0 -22 -1q-146 -80 -235 -222q7 -7 12 -8q4 -1 5 -9t2.5 -11t11.5 3q9 -8 3 -19q1 1 44 -27q19 -17 21 -21q3 -11 -10 -18q-1 2 -9 9t-9 4q-3 -5 0.5 -18.5t10.5 -12.5q-7 0 -9.5 -16t-2.5 -35.5 +t-1 -23.5l2 -1q-3 -12 5.5 -34.5t21.5 -19.5q-13 -3 20 -43q6 -8 8 -9q3 -2 12 -7.5t15 -10t10 -10.5q4 -5 10 -22.5t14 -23.5q-2 -6 9.5 -20t10.5 -23q-1 0 -2.5 -1t-2.5 -1q3 -7 15.5 -14t15.5 -13q1 -3 2 -10t3 -11t8 -2q2 20 -24 62q-15 25 -17 29q-3 5 -5.5 15.5 +t-4.5 14.5q2 0 6 -1.5t8.5 -3.5t7.5 -4t2 -3q-3 -7 2 -17.5t12 -18.5t17 -19t12 -13q6 -6 14 -19.5t0 -13.5q9 0 20 -10.5t17 -19.5q5 -8 8 -26t5 -24q2 -7 8.5 -13.5t12.5 -9.5l16 -8t13 -7q5 -2 18.5 -10.5t21.5 -11.5q10 -4 16 -4t14.5 2.5t13.5 3.5q15 2 29 -15t21 -21 +q36 -19 55 -11q-2 -1 0.5 -7.5t8 -15.5t9 -14.5t5.5 -8.5q5 -6 18 -15t18 -15q6 4 7 9q-3 -8 7 -20t18 -10q14 3 14 32q-31 -15 -49 18q0 1 -2.5 5.5t-4 8.5t-2.5 8.5t0 7.5t5 3q9 0 10 3.5t-2 12.5t-4 13q-1 8 -11 20t-12 15q-5 -9 -16 -8t-16 9q0 -1 -1.5 -5.5t-1.5 -6.5 +q-13 0 -15 1q1 3 2.5 17.5t3.5 22.5q1 4 5.5 12t7.5 14.5t4 12.5t-4.5 9.5t-17.5 2.5q-19 -1 -26 -20q-1 -3 -3 -10.5t-5 -11.5t-9 -7q-7 -3 -24 -2t-24 5q-13 8 -22.5 29t-9.5 37q0 10 2.5 26.5t3 25t-5.5 24.5q3 2 9 9.5t10 10.5q2 1 4.5 1.5t4.5 0t4 1.5t3 6q-1 1 -4 3 +q-3 3 -4 3q7 -3 28.5 1.5t27.5 -1.5q15 -11 22 2q0 1 -2.5 9.5t-0.5 13.5q5 -27 29 -9q3 -3 15.5 -5t17.5 -5q3 -2 7 -5.5t5.5 -4.5t5 0.5t8.5 6.5q10 -14 12 -24q11 -40 19 -44q7 -3 11 -2t4.5 9.5t0 14t-1.5 12.5l-1 8v18l-1 8q-15 3 -18.5 12t1.5 18.5t15 18.5q1 1 8 3.5 +t15.5 6.5t12.5 8q21 19 15 35q7 0 11 9q-1 0 -5 3t-7.5 5t-4.5 2q9 5 2 16q5 3 7.5 11t7.5 10q9 -12 21 -2q8 8 1 16q5 7 20.5 10.5t18.5 9.5q7 -2 8 2t1 12t3 12q4 5 15 9t13 5l17 11q3 4 0 4q18 -2 31 11q10 11 -6 20q3 6 -3 9.5t-15 5.5q3 1 11.5 0.5t10.5 1.5 +q15 10 -7 16q-17 5 -43 -12zM879 10q206 36 351 189q-3 3 -12.5 4.5t-12.5 3.5q-18 7 -24 8q1 7 -2.5 13t-8 9t-12.5 8t-11 7q-2 2 -7 6t-7 5.5t-7.5 4.5t-8.5 2t-10 -1l-3 -1q-3 -1 -5.5 -2.5t-5.5 -3t-4 -3t0 -2.5q-21 17 -36 22q-5 1 -11 5.5t-10.5 7t-10 1.5t-11.5 -7 +q-5 -5 -6 -15t-2 -13q-7 5 0 17.5t2 18.5q-3 6 -10.5 4.5t-12 -4.5t-11.5 -8.5t-9 -6.5t-8.5 -5.5t-8.5 -7.5q-3 -4 -6 -12t-5 -11q-2 4 -11.5 6.5t-9.5 5.5q2 -10 4 -35t5 -38q7 -31 -12 -48q-27 -25 -29 -40q-4 -22 12 -26q0 -7 -8 -20.5t-7 -21.5q0 -6 2 -16z" /> + <glyph glyph-name="wrench" unicode="&#xf0ad;" horiz-adv-x="1664" +d="M384 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1028 484l-682 -682q-37 -37 -90 -37q-52 0 -91 37l-106 108q-38 36 -38 90q0 53 38 91l681 681q39 -98 114.5 -173.5t173.5 -114.5zM1662 919q0 -39 -23 -106q-47 -134 -164.5 -217.5 +t-258.5 -83.5q-185 0 -316.5 131.5t-131.5 316.5t131.5 316.5t316.5 131.5q58 0 121.5 -16.5t107.5 -46.5q16 -11 16 -28t-16 -28l-293 -169v-224l193 -107q5 3 79 48.5t135.5 81t70.5 35.5q15 0 23.5 -10t8.5 -25z" /> + <glyph glyph-name="tasks" unicode="&#xf0ae;" horiz-adv-x="1792" +d="M1024 128h640v128h-640v-128zM640 640h1024v128h-1024v-128zM1280 1152h384v128h-384v-128zM1792 320v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 832v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19 +t-19 45v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 1344v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45z" /> + <glyph glyph-name="filter" unicode="&#xf0b0;" horiz-adv-x="1408" +d="M1403 1241q17 -41 -14 -70l-493 -493v-742q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-256 256q-19 19 -19 45v486l-493 493q-31 29 -14 70q17 39 59 39h1280q42 0 59 -39z" /> + <glyph glyph-name="briefcase" unicode="&#xf0b1;" horiz-adv-x="1792" +d="M640 1280h512v128h-512v-128zM1792 640v-480q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v480h672v-160q0 -26 19 -45t45 -19h320q26 0 45 19t19 45v160h672zM1024 640v-128h-256v128h256zM1792 1120v-384h-1792v384q0 66 47 113t113 47h352v160q0 40 28 68 +t68 28h576q40 0 68 -28t28 -68v-160h352q66 0 113 -47t47 -113z" /> + <glyph glyph-name="fullscreen" unicode="&#xf0b2;" +d="M1283 995l-355 -355l355 -355l144 144q29 31 70 14q39 -17 39 -59v-448q0 -26 -19 -45t-45 -19h-448q-42 0 -59 40q-17 39 14 69l144 144l-355 355l-355 -355l144 -144q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19t-19 45v448q0 42 40 59q39 17 69 -14l144 -144 +l355 355l-355 355l-144 -144q-19 -19 -45 -19q-12 0 -24 5q-40 17 -40 59v448q0 26 19 45t45 19h448q42 0 59 -40q17 -39 -14 -69l-144 -144l355 -355l355 355l-144 144q-31 30 -14 69q17 40 59 40h448q26 0 45 -19t19 -45v-448q0 -42 -39 -59q-13 -5 -25 -5q-26 0 -45 19z +" /> + <glyph glyph-name="group" unicode="&#xf0c0;" horiz-adv-x="1920" +d="M593 640q-162 -5 -265 -128h-134q-82 0 -138 40.5t-56 118.5q0 353 124 353q6 0 43.5 -21t97.5 -42.5t119 -21.5q67 0 133 23q-5 -37 -5 -66q0 -139 81 -256zM1664 3q0 -120 -73 -189.5t-194 -69.5h-874q-121 0 -194 69.5t-73 189.5q0 53 3.5 103.5t14 109t26.5 108.5 +t43 97.5t62 81t85.5 53.5t111.5 20q10 0 43 -21.5t73 -48t107 -48t135 -21.5t135 21.5t107 48t73 48t43 21.5q61 0 111.5 -20t85.5 -53.5t62 -81t43 -97.5t26.5 -108.5t14 -109t3.5 -103.5zM640 1280q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75 +t75 -181zM1344 896q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5zM1920 671q0 -78 -56 -118.5t-138 -40.5h-134q-103 123 -265 128q81 117 81 256q0 29 -5 66q66 -23 133 -23q59 0 119 21.5t97.5 42.5 +t43.5 21q124 0 124 -353zM1792 1280q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181z" /> + <glyph glyph-name="link" unicode="&#xf0c1;" horiz-adv-x="1664" +d="M1456 320q0 40 -28 68l-208 208q-28 28 -68 28q-42 0 -72 -32q3 -3 19 -18.5t21.5 -21.5t15 -19t13 -25.5t3.5 -27.5q0 -40 -28 -68t-68 -28q-15 0 -27.5 3.5t-25.5 13t-19 15t-21.5 21.5t-18.5 19q-33 -31 -33 -73q0 -40 28 -68l206 -207q27 -27 68 -27q40 0 68 26 +l147 146q28 28 28 67zM753 1025q0 40 -28 68l-206 207q-28 28 -68 28q-39 0 -68 -27l-147 -146q-28 -28 -28 -67q0 -40 28 -68l208 -208q27 -27 68 -27q42 0 72 31q-3 3 -19 18.5t-21.5 21.5t-15 19t-13 25.5t-3.5 27.5q0 40 28 68t68 28q15 0 27.5 -3.5t25.5 -13t19 -15 +t21.5 -21.5t18.5 -19q33 31 33 73zM1648 320q0 -120 -85 -203l-147 -146q-83 -83 -203 -83q-121 0 -204 85l-206 207q-83 83 -83 203q0 123 88 209l-88 88q-86 -88 -208 -88q-120 0 -204 84l-208 208q-84 84 -84 204t85 203l147 146q83 83 203 83q121 0 204 -85l206 -207 +q83 -83 83 -203q0 -123 -88 -209l88 -88q86 88 208 88q120 0 204 -84l208 -208q84 -84 84 -204z" /> + <glyph glyph-name="cloud" unicode="&#xf0c2;" horiz-adv-x="1920" +d="M1920 384q0 -159 -112.5 -271.5t-271.5 -112.5h-1088q-185 0 -316.5 131.5t-131.5 316.5q0 132 71 241.5t187 163.5q-2 28 -2 43q0 212 150 362t362 150q158 0 286.5 -88t187.5 -230q70 62 166 62q106 0 181 -75t75 -181q0 -75 -41 -138q129 -30 213 -134.5t84 -239.5z +" /> + <glyph glyph-name="beaker" unicode="&#xf0c3;" horiz-adv-x="1664" +d="M1527 88q56 -89 21.5 -152.5t-140.5 -63.5h-1152q-106 0 -140.5 63.5t21.5 152.5l503 793v399h-64q-26 0 -45 19t-19 45t19 45t45 19h512q26 0 45 -19t19 -45t-19 -45t-45 -19h-64v-399zM748 813l-272 -429h712l-272 429l-20 31v37v399h-128v-399v-37z" /> + <glyph glyph-name="cut" unicode="&#xf0c4;" horiz-adv-x="1792" +d="M960 640q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1260 576l507 -398q28 -20 25 -56q-5 -35 -35 -51l-128 -64q-13 -7 -29 -7q-17 0 -31 8l-690 387l-110 -66q-8 -4 -12 -5q14 -49 10 -97q-7 -77 -56 -147.5t-132 -123.5q-132 -84 -277 -84 +q-136 0 -222 78q-90 84 -79 207q7 76 56 147t131 124q132 84 278 84q83 0 151 -31q9 13 22 22l122 73l-122 73q-13 9 -22 22q-68 -31 -151 -31q-146 0 -278 84q-82 53 -131 124t-56 147q-5 59 15.5 113t63.5 93q85 79 222 79q145 0 277 -84q83 -52 132 -123t56 -148 +q4 -48 -10 -97q4 -1 12 -5l110 -66l690 387q14 8 31 8q16 0 29 -7l128 -64q30 -16 35 -51q3 -36 -25 -56zM579 836q46 42 21 108t-106 117q-92 59 -192 59q-74 0 -113 -36q-46 -42 -21 -108t106 -117q92 -59 192 -59q74 0 113 36zM494 91q81 51 106 117t-21 108 +q-39 36 -113 36q-100 0 -192 -59q-81 -51 -106 -117t21 -108q39 -36 113 -36q100 0 192 59zM672 704l96 -58v11q0 36 33 56l14 8l-79 47l-26 -26q-3 -3 -10 -11t-12 -12q-2 -2 -4 -3.5t-3 -2.5zM896 480l96 -32l736 576l-128 64l-768 -431v-113l-160 -96l9 -8q2 -2 7 -6 +q4 -4 11 -12t11 -12l26 -26zM1600 64l128 64l-520 408l-177 -138q-2 -3 -13 -7z" /> + <glyph glyph-name="copy" unicode="&#xf0c5;" horiz-adv-x="1792" +d="M1696 1152q40 0 68 -28t28 -68v-1216q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v288h-544q-40 0 -68 28t-28 68v672q0 40 20 88t48 76l408 408q28 28 76 48t88 20h416q40 0 68 -28t28 -68v-328q68 40 128 40h416zM1152 939l-299 -299h299v299zM512 1323l-299 -299 +h299v299zM708 676l316 316v416h-384v-416q0 -40 -28 -68t-68 -28h-416v-640h512v256q0 40 20 88t48 76zM1664 -128v1152h-384v-416q0 -40 -28 -68t-68 -28h-416v-640h896z" /> + <glyph glyph-name="paper_clip" unicode="&#xf0c6;" horiz-adv-x="1408" +d="M1404 151q0 -117 -79 -196t-196 -79q-135 0 -235 100l-777 776q-113 115 -113 271q0 159 110 270t269 111q158 0 273 -113l605 -606q10 -10 10 -22q0 -16 -30.5 -46.5t-46.5 -30.5q-13 0 -23 10l-606 607q-79 77 -181 77q-106 0 -179 -75t-73 -181q0 -105 76 -181 +l776 -777q63 -63 145 -63q64 0 106 42t42 106q0 82 -63 145l-581 581q-26 24 -60 24q-29 0 -48 -19t-19 -48q0 -32 25 -59l410 -410q10 -10 10 -22q0 -16 -31 -47t-47 -31q-12 0 -22 10l-410 410q-63 61 -63 149q0 82 57 139t139 57q88 0 149 -63l581 -581q100 -98 100 -235 +z" /> + <glyph glyph-name="save" unicode="&#xf0c7;" +d="M384 0h768v384h-768v-384zM1280 0h128v896q0 14 -10 38.5t-20 34.5l-281 281q-10 10 -34 20t-39 10v-416q0 -40 -28 -68t-68 -28h-576q-40 0 -68 28t-28 68v416h-128v-1280h128v416q0 40 28 68t68 28h832q40 0 68 -28t28 -68v-416zM896 928v320q0 13 -9.5 22.5t-22.5 9.5 +h-192q-13 0 -22.5 -9.5t-9.5 -22.5v-320q0 -13 9.5 -22.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 22.5zM1536 896v-928q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h928q40 0 88 -20t76 -48l280 -280q28 -28 48 -76t20 -88z" /> + <glyph glyph-name="sign_blank" unicode="&#xf0c8;" +d="M1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="reorder" unicode="&#xf0c9;" +d="M1536 192v-128q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1536 704v-128q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1536 1216v-128q0 -26 -19 -45 +t-45 -19h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45z" /> + <glyph glyph-name="ul" unicode="&#xf0ca;" horiz-adv-x="1792" +d="M384 128q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM384 640q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5 +t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5zM384 1152q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1792 736v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5z +M1792 1248v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5z" /> + <glyph glyph-name="ol" unicode="&#xf0cb;" horiz-adv-x="1792" +d="M381 -84q0 -80 -54.5 -126t-135.5 -46q-106 0 -172 66l57 88q49 -45 106 -45q29 0 50.5 14.5t21.5 42.5q0 64 -105 56l-26 56q8 10 32.5 43.5t42.5 54t37 38.5v1q-16 0 -48.5 -1t-48.5 -1v-53h-106v152h333v-88l-95 -115q51 -12 81 -49t30 -88zM383 543v-159h-362 +q-6 36 -6 54q0 51 23.5 93t56.5 68t66 47.5t56.5 43.5t23.5 45q0 25 -14.5 38.5t-39.5 13.5q-46 0 -81 -58l-85 59q24 51 71.5 79.5t105.5 28.5q73 0 123 -41.5t50 -112.5q0 -50 -34 -91.5t-75 -64.5t-75.5 -50.5t-35.5 -52.5h127v60h105zM1792 224v-192q0 -13 -9.5 -22.5 +t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 14 9 23t23 9h1216q13 0 22.5 -9.5t9.5 -22.5zM384 1123v-99h-335v99h107q0 41 0.5 121.5t0.5 121.5v12h-2q-8 -17 -50 -54l-71 76l136 127h106v-404h108zM1792 736v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216 +q-13 0 -22.5 9.5t-9.5 22.5v192q0 14 9 23t23 9h1216q13 0 22.5 -9.5t9.5 -22.5zM1792 1248v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5z" /> + <glyph glyph-name="strikethrough" unicode="&#xf0cc;" horiz-adv-x="1792" +d="M1760 640q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1728q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h1728zM483 704q-28 35 -51 80q-48 98 -48 188q0 181 134 309q133 127 393 127q50 0 167 -19q66 -12 177 -48q10 -38 21 -118q14 -123 14 -183q0 -18 -5 -45l-12 -3l-84 6 +l-14 2q-50 149 -103 205q-88 91 -210 91q-114 0 -182 -59q-67 -58 -67 -146q0 -73 66 -140t279 -129q69 -20 173 -66q58 -28 95 -52h-743zM990 448h411q7 -39 7 -92q0 -111 -41 -212q-23 -56 -71 -104q-37 -35 -109 -81q-80 -48 -153 -66q-80 -21 -203 -21q-114 0 -195 23 +l-140 40q-57 16 -72 28q-8 8 -8 22v13q0 108 -2 156q-1 30 0 68l2 37v44l102 2q15 -34 30 -71t22.5 -56t12.5 -27q35 -57 80 -94q43 -36 105 -57q59 -22 132 -22q64 0 139 27q77 26 122 86q47 61 47 129q0 84 -81 157q-34 29 -137 71z" /> + <glyph glyph-name="underline" unicode="&#xf0cd;" +d="M48 1313q-37 2 -45 4l-3 88q13 1 40 1q60 0 112 -4q132 -7 166 -7q86 0 168 3q116 4 146 5q56 0 86 2l-1 -14l2 -64v-9q-60 -9 -124 -9q-60 0 -79 -25q-13 -14 -13 -132q0 -13 0.5 -32.5t0.5 -25.5l1 -229l14 -280q6 -124 51 -202q35 -59 96 -92q88 -47 177 -47 +q104 0 191 28q56 18 99 51q48 36 65 64q36 56 53 114q21 73 21 229q0 79 -3.5 128t-11 122.5t-13.5 159.5l-4 59q-5 67 -24 88q-34 35 -77 34l-100 -2l-14 3l2 86h84l205 -10q76 -3 196 10l18 -2q6 -38 6 -51q0 -7 -4 -31q-45 -12 -84 -13q-73 -11 -79 -17q-15 -15 -15 -41 +q0 -7 1.5 -27t1.5 -31q8 -19 22 -396q6 -195 -15 -304q-15 -76 -41 -122q-38 -65 -112 -123q-75 -57 -182 -89q-109 -33 -255 -33q-167 0 -284 46q-119 47 -179 122q-61 76 -83 195q-16 80 -16 237v333q0 188 -17 213q-25 36 -147 39zM1536 -96v64q0 14 -9 23t-23 9h-1472 +q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h1472q14 0 23 9t9 23z" /> + <glyph glyph-name="table" unicode="&#xf0ce;" horiz-adv-x="1664" +d="M512 160v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM512 544v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1024 160v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23 +v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM512 928v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1024 544v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1536 160v192 +q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1024 928v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1536 544v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192 +q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1536 928v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1664 1248v-1088q0 -66 -47 -113t-113 -47h-1344q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1344q66 0 113 -47t47 -113 +z" /> + <glyph glyph-name="magic" unicode="&#xf0d0;" horiz-adv-x="1664" +d="M1190 955l293 293l-107 107l-293 -293zM1637 1248q0 -27 -18 -45l-1286 -1286q-18 -18 -45 -18t-45 18l-198 198q-18 18 -18 45t18 45l1286 1286q18 18 45 18t45 -18l198 -198q18 -18 18 -45zM286 1438l98 -30l-98 -30l-30 -98l-30 98l-98 30l98 30l30 98zM636 1276 +l196 -60l-196 -60l-60 -196l-60 196l-196 60l196 60l60 196zM1566 798l98 -30l-98 -30l-30 -98l-30 98l-98 30l98 30l30 98zM926 1438l98 -30l-98 -30l-30 -98l-30 98l-98 30l98 30l30 98z" /> + <glyph glyph-name="truck" unicode="&#xf0d1;" horiz-adv-x="1792" +d="M640 128q0 52 -38 90t-90 38t-90 -38t-38 -90t38 -90t90 -38t90 38t38 90zM256 640h384v256h-158q-13 0 -22 -9l-195 -195q-9 -9 -9 -22v-30zM1536 128q0 52 -38 90t-90 38t-90 -38t-38 -90t38 -90t90 -38t90 38t38 90zM1792 1216v-1024q0 -15 -4 -26.5t-13.5 -18.5 +t-16.5 -11.5t-23.5 -6t-22.5 -2t-25.5 0t-22.5 0.5q0 -106 -75 -181t-181 -75t-181 75t-75 181h-384q0 -106 -75 -181t-181 -75t-181 75t-75 181h-64q-3 0 -22.5 -0.5t-25.5 0t-22.5 2t-23.5 6t-16.5 11.5t-13.5 18.5t-4 26.5q0 26 19 45t45 19v320q0 8 -0.5 35t0 38 +t2.5 34.5t6.5 37t14 30.5t22.5 30l198 198q19 19 50.5 32t58.5 13h160v192q0 26 19 45t45 19h1024q26 0 45 -19t19 -45z" /> + <glyph glyph-name="pinterest" unicode="&#xf0d2;" +d="M1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103q-111 0 -218 32q59 93 78 164q9 34 54 211q20 -39 73 -67.5t114 -28.5q121 0 216 68.5t147 188.5t52 270q0 114 -59.5 214t-172.5 163t-255 63q-105 0 -196 -29t-154.5 -77t-109 -110.5t-67 -129.5t-21.5 -134 +q0 -104 40 -183t117 -111q30 -12 38 20q2 7 8 31t8 30q6 23 -11 43q-51 61 -51 151q0 151 104.5 259.5t273.5 108.5q151 0 235.5 -82t84.5 -213q0 -170 -68.5 -289t-175.5 -119q-61 0 -98 43.5t-23 104.5q8 35 26.5 93.5t30 103t11.5 75.5q0 50 -27 83t-77 33 +q-62 0 -105 -57t-43 -142q0 -73 25 -122l-99 -418q-17 -70 -13 -177q-206 91 -333 281t-127 423q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="pinterest_sign" unicode="&#xf0d3;" +d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-725q85 122 108 210q9 34 53 209q21 -39 73.5 -67t112.5 -28q181 0 295.5 147.5t114.5 373.5q0 84 -35 162.5t-96.5 139t-152.5 97t-197 36.5q-104 0 -194.5 -28.5t-153 -76.5 +t-107.5 -109.5t-66.5 -128t-21.5 -132.5q0 -102 39.5 -180t116.5 -110q13 -5 23.5 0t14.5 19q10 44 15 61q6 23 -11 42q-50 62 -50 150q0 150 103.5 256.5t270.5 106.5q149 0 232.5 -81t83.5 -210q0 -168 -67.5 -286t-173.5 -118q-60 0 -97 43.5t-23 103.5q8 34 26.5 92.5 +t29.5 102t11 74.5q0 49 -26.5 81.5t-75.5 32.5q-61 0 -103.5 -56.5t-42.5 -139.5q0 -72 24 -121l-98 -414q-24 -100 -7 -254h-183q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960z" /> + <glyph glyph-name="google_plus_sign" unicode="&#xf0d4;" +d="M917 631q0 26 -6 64h-362v-132h217q-3 -24 -16.5 -50t-37.5 -53t-66.5 -44.5t-96.5 -17.5q-99 0 -169 71t-70 171t70 171t169 71q92 0 153 -59l104 101q-108 100 -257 100q-160 0 -272 -112.5t-112 -271.5t112 -271.5t272 -112.5q165 0 266.5 105t101.5 270zM1262 585 +h109v110h-109v110h-110v-110h-110v-110h110v-110h110v110zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="google_plus" unicode="&#xf0d5;" horiz-adv-x="2304" +d="M1437 623q0 -208 -87 -370.5t-248 -254t-369 -91.5q-149 0 -285 58t-234 156t-156 234t-58 285t58 285t156 234t234 156t285 58q286 0 491 -192l-199 -191q-117 113 -292 113q-123 0 -227.5 -62t-165.5 -168.5t-61 -232.5t61 -232.5t165.5 -168.5t227.5 -62 +q83 0 152.5 23t114.5 57.5t78.5 78.5t49 83t21.5 74h-416v252h692q12 -63 12 -122zM2304 745v-210h-209v-209h-210v209h-209v210h209v209h210v-209h209z" /> + <glyph glyph-name="money" unicode="&#xf0d6;" horiz-adv-x="1920" +d="M768 384h384v96h-128v448h-114l-148 -137l77 -80q42 37 55 57h2v-288h-128v-96zM1280 640q0 -70 -21 -142t-59.5 -134t-101.5 -101t-138 -39t-138 39t-101.5 101t-59.5 134t-21 142t21 142t59.5 134t101.5 101t138 39t138 -39t101.5 -101t59.5 -134t21 -142zM1792 384 +v512q-106 0 -181 75t-75 181h-1152q0 -106 -75 -181t-181 -75v-512q106 0 181 -75t75 -181h1152q0 106 75 181t181 75zM1920 1216v-1152q0 -26 -19 -45t-45 -19h-1792q-26 0 -45 19t-19 45v1152q0 26 19 45t45 19h1792q26 0 45 -19t19 -45z" /> + <glyph glyph-name="caret_down" unicode="&#xf0d7;" horiz-adv-x="1024" +d="M1024 832q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45t19 45t45 19h896q26 0 45 -19t19 -45z" /> + <glyph glyph-name="caret_up" unicode="&#xf0d8;" horiz-adv-x="1024" +d="M1024 320q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45z" /> + <glyph glyph-name="caret_left" unicode="&#xf0d9;" horiz-adv-x="640" +d="M640 1088v-896q0 -26 -19 -45t-45 -19t-45 19l-448 448q-19 19 -19 45t19 45l448 448q19 19 45 19t45 -19t19 -45z" /> + <glyph glyph-name="caret_right" unicode="&#xf0da;" horiz-adv-x="640" +d="M576 640q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19t-19 45v896q0 26 19 45t45 19t45 -19l448 -448q19 -19 19 -45z" /> + <glyph glyph-name="columns" unicode="&#xf0db;" horiz-adv-x="1664" +d="M160 0h608v1152h-640v-1120q0 -13 9.5 -22.5t22.5 -9.5zM1536 32v1120h-640v-1152h608q13 0 22.5 9.5t9.5 22.5zM1664 1248v-1216q0 -66 -47 -113t-113 -47h-1344q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1344q66 0 113 -47t47 -113z" /> + <glyph glyph-name="sort" unicode="&#xf0dc;" horiz-adv-x="1024" +d="M1024 448q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45t19 45t45 19h896q26 0 45 -19t19 -45zM1024 832q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45z" /> + <glyph glyph-name="sort_down" unicode="&#xf0dd;" horiz-adv-x="1024" +d="M1024 448q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45t19 45t45 19h896q26 0 45 -19t19 -45z" /> + <glyph glyph-name="sort_up" unicode="&#xf0de;" horiz-adv-x="1024" +d="M1024 832q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45z" /> + <glyph glyph-name="envelope_alt" unicode="&#xf0e0;" horiz-adv-x="1792" +d="M1792 826v-794q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v794q44 -49 101 -87q362 -246 497 -345q57 -42 92.5 -65.5t94.5 -48t110 -24.5h1h1q51 0 110 24.5t94.5 48t92.5 65.5q170 123 498 345q57 39 100 87zM1792 1120q0 -79 -49 -151t-122 -123 +q-376 -261 -468 -325q-10 -7 -42.5 -30.5t-54 -38t-52 -32.5t-57.5 -27t-50 -9h-1h-1q-23 0 -50 9t-57.5 27t-52 32.5t-54 38t-42.5 30.5q-91 64 -262 182.5t-205 142.5q-62 42 -117 115.5t-55 136.5q0 78 41.5 130t118.5 52h1472q65 0 112.5 -47t47.5 -113z" /> + <glyph glyph-name="linkedin" unicode="&#xf0e1;" +d="M349 911v-991h-330v991h330zM370 1217q1 -73 -50.5 -122t-135.5 -49h-2q-82 0 -132 49t-50 122q0 74 51.5 122.5t134.5 48.5t133 -48.5t51 -122.5zM1536 488v-568h-329v530q0 105 -40.5 164.5t-126.5 59.5q-63 0 -105.5 -34.5t-63.5 -85.5q-11 -30 -11 -81v-553h-329 +q2 399 2 647t-1 296l-1 48h329v-144h-2q20 32 41 56t56.5 52t87 43.5t114.5 15.5q171 0 275 -113.5t104 -332.5z" /> + <glyph glyph-name="undo" unicode="&#xf0e2;" +d="M1536 640q0 -156 -61 -298t-164 -245t-245 -164t-298 -61q-172 0 -327 72.5t-264 204.5q-7 10 -6.5 22.5t8.5 20.5l137 138q10 9 25 9q16 -2 23 -12q73 -95 179 -147t225 -52q104 0 198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5t-40.5 198.5t-109.5 163.5 +t-163.5 109.5t-198.5 40.5q-98 0 -188 -35.5t-160 -101.5l137 -138q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19t-19 45v448q0 42 40 59q39 17 69 -14l130 -129q107 101 244.5 156.5t284.5 55.5q156 0 298 -61t245 -164t164 -245t61 -298z" /> + <glyph glyph-name="legal" unicode="&#xf0e3;" horiz-adv-x="1792" +d="M1771 0q0 -53 -37 -90l-107 -108q-39 -37 -91 -37q-53 0 -90 37l-363 364q-38 36 -38 90q0 53 43 96l-256 256l-126 -126q-14 -14 -34 -14t-34 14q2 -2 12.5 -12t12.5 -13t10 -11.5t10 -13.5t6 -13.5t5.5 -16.5t1.5 -18q0 -38 -28 -68q-3 -3 -16.5 -18t-19 -20.5 +t-18.5 -16.5t-22 -15.5t-22 -9t-26 -4.5q-40 0 -68 28l-408 408q-28 28 -28 68q0 13 4.5 26t9 22t15.5 22t16.5 18.5t20.5 19t18 16.5q30 28 68 28q10 0 18 -1.5t16.5 -5.5t13.5 -6t13.5 -10t11.5 -10t13 -12.5t12 -12.5q-14 14 -14 34t14 34l348 348q14 14 34 14t34 -14 +q-2 2 -12.5 12t-12.5 13t-10 11.5t-10 13.5t-6 13.5t-5.5 16.5t-1.5 18q0 38 28 68q3 3 16.5 18t19 20.5t18.5 16.5t22 15.5t22 9t26 4.5q40 0 68 -28l408 -408q28 -28 28 -68q0 -13 -4.5 -26t-9 -22t-15.5 -22t-16.5 -18.5t-20.5 -19t-18 -16.5q-30 -28 -68 -28 +q-10 0 -18 1.5t-16.5 5.5t-13.5 6t-13.5 10t-11.5 10t-13 12.5t-12 12.5q14 -14 14 -34t-14 -34l-126 -126l256 -256q43 43 96 43q52 0 91 -37l363 -363q37 -39 37 -91z" /> + <glyph glyph-name="dashboard" unicode="&#xf0e4;" horiz-adv-x="1792" +d="M384 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM576 832q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1004 351l101 382q6 26 -7.5 48.5t-38.5 29.5 +t-48 -6.5t-30 -39.5l-101 -382q-60 -5 -107 -43.5t-63 -98.5q-20 -77 20 -146t117 -89t146 20t89 117q16 60 -6 117t-72 91zM1664 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1024 1024q0 53 -37.5 90.5 +t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1472 832q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1792 384q0 -261 -141 -483q-19 -29 -54 -29h-1402q-35 0 -54 29 +q-141 221 -141 483q0 182 71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" /> + <glyph glyph-name="comment_alt" unicode="&#xf0e5;" horiz-adv-x="1792" +d="M896 1152q-204 0 -381.5 -69.5t-282 -187.5t-104.5 -255q0 -112 71.5 -213.5t201.5 -175.5l87 -50l-27 -96q-24 -91 -70 -172q152 63 275 171l43 38l57 -6q69 -8 130 -8q204 0 381.5 69.5t282 187.5t104.5 255t-104.5 255t-282 187.5t-381.5 69.5zM1792 640 +q0 -174 -120 -321.5t-326 -233t-450 -85.5q-70 0 -145 8q-198 -175 -460 -242q-49 -14 -114 -22h-5q-15 0 -27 10.5t-16 27.5v1q-3 4 -0.5 12t2 10t4.5 9.5l6 9t7 8.5t8 9q7 8 31 34.5t34.5 38t31 39.5t32.5 51t27 59t26 76q-157 89 -247.5 220t-90.5 281q0 174 120 321.5 +t326 233t450 85.5t450 -85.5t326 -233t120 -321.5z" /> + <glyph glyph-name="comments_alt" unicode="&#xf0e6;" horiz-adv-x="1792" +d="M704 1152q-153 0 -286 -52t-211.5 -141t-78.5 -191q0 -82 53 -158t149 -132l97 -56l-35 -84q34 20 62 39l44 31l53 -10q78 -14 153 -14q153 0 286 52t211.5 141t78.5 191t-78.5 191t-211.5 141t-286 52zM704 1280q191 0 353.5 -68.5t256.5 -186.5t94 -257t-94 -257 +t-256.5 -186.5t-353.5 -68.5q-86 0 -176 16q-124 -88 -278 -128q-36 -9 -86 -16h-3q-11 0 -20.5 8t-11.5 21q-1 3 -1 6.5t0.5 6.5t2 6l2.5 5t3.5 5.5t4 5t4.5 5t4 4.5q5 6 23 25t26 29.5t22.5 29t25 38.5t20.5 44q-124 72 -195 177t-71 224q0 139 94 257t256.5 186.5 +t353.5 68.5zM1526 111q10 -24 20.5 -44t25 -38.5t22.5 -29t26 -29.5t23 -25q1 -1 4 -4.5t4.5 -5t4 -5t3.5 -5.5l2.5 -5t2 -6t0.5 -6.5t-1 -6.5q-3 -14 -13 -22t-22 -7q-50 7 -86 16q-154 40 -278 128q-90 -16 -176 -16q-271 0 -472 132q58 -4 88 -4q161 0 309 45t264 129 +q125 92 192 212t67 254q0 77 -23 152q129 -71 204 -178t75 -230q0 -120 -71 -224.5t-195 -176.5z" /> + <glyph glyph-name="bolt" unicode="&#xf0e7;" horiz-adv-x="896" +d="M885 970q18 -20 7 -44l-540 -1157q-13 -25 -42 -25q-4 0 -14 2q-17 5 -25.5 19t-4.5 30l197 808l-406 -101q-4 -1 -12 -1q-18 0 -31 11q-18 15 -13 39l201 825q4 14 16 23t28 9h328q19 0 32 -12.5t13 -29.5q0 -8 -5 -18l-171 -463l396 98q8 2 12 2q19 0 34 -15z" /> + <glyph glyph-name="sitemap" unicode="&#xf0e8;" horiz-adv-x="1792" +d="M1792 288v-320q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h96v192h-512v-192h96q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h96v192h-512v-192h96q40 0 68 -28t28 -68v-320 +q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h96v192q0 52 38 90t90 38h512v192h-96q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-96v-192h512q52 0 90 -38t38 -90v-192h96q40 0 68 -28t28 -68 +z" /> + <glyph glyph-name="umbrella" unicode="&#xf0e9;" horiz-adv-x="1664" +d="M896 708v-580q0 -104 -76 -180t-180 -76t-180 76t-76 180q0 26 19 45t45 19t45 -19t19 -45q0 -50 39 -89t89 -39t89 39t39 89v580q33 11 64 11t64 -11zM1664 681q0 -13 -9.5 -22.5t-22.5 -9.5q-11 0 -23 10q-49 46 -93 69t-102 23q-68 0 -128 -37t-103 -97 +q-7 -10 -17.5 -28t-14.5 -24q-11 -17 -28 -17q-18 0 -29 17q-4 6 -14.5 24t-17.5 28q-43 60 -102.5 97t-127.5 37t-127.5 -37t-102.5 -97q-7 -10 -17.5 -28t-14.5 -24q-11 -17 -29 -17q-17 0 -28 17q-4 6 -14.5 24t-17.5 28q-43 60 -103 97t-128 37q-58 0 -102 -23t-93 -69 +q-12 -10 -23 -10q-13 0 -22.5 9.5t-9.5 22.5q0 5 1 7q45 183 172.5 319.5t298 204.5t360.5 68q140 0 274.5 -40t246.5 -113.5t194.5 -187t115.5 -251.5q1 -2 1 -7zM896 1408v-98q-42 2 -64 2t-64 -2v98q0 26 19 45t45 19t45 -19t19 -45z" /> + <glyph glyph-name="paste" unicode="&#xf0ea;" horiz-adv-x="1792" +d="M768 -128h896v640h-416q-40 0 -68 28t-28 68v416h-384v-1152zM1024 1312v64q0 13 -9.5 22.5t-22.5 9.5h-704q-13 0 -22.5 -9.5t-9.5 -22.5v-64q0 -13 9.5 -22.5t22.5 -9.5h704q13 0 22.5 9.5t9.5 22.5zM1280 640h299l-299 299v-299zM1792 512v-672q0 -40 -28 -68t-68 -28 +h-960q-40 0 -68 28t-28 68v160h-544q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h1088q40 0 68 -28t28 -68v-328q21 -13 36 -28l408 -408q28 -28 48 -76t20 -88z" /> + <glyph glyph-name="light_bulb" unicode="&#xf0eb;" horiz-adv-x="1024" +d="M736 960q0 -13 -9.5 -22.5t-22.5 -9.5t-22.5 9.5t-9.5 22.5q0 46 -54 71t-106 25q-13 0 -22.5 9.5t-9.5 22.5t9.5 22.5t22.5 9.5q50 0 99.5 -16t87 -54t37.5 -90zM896 960q0 72 -34.5 134t-90 101.5t-123 62t-136.5 22.5t-136.5 -22.5t-123 -62t-90 -101.5t-34.5 -134 +q0 -101 68 -180q10 -11 30.5 -33t30.5 -33q128 -153 141 -298h228q13 145 141 298q10 11 30.5 33t30.5 33q68 79 68 180zM1024 960q0 -155 -103 -268q-45 -49 -74.5 -87t-59.5 -95.5t-34 -107.5q47 -28 47 -82q0 -37 -25 -64q25 -27 25 -64q0 -52 -45 -81q13 -23 13 -47 +q0 -46 -31.5 -71t-77.5 -25q-20 -44 -60 -70t-87 -26t-87 26t-60 70q-46 0 -77.5 25t-31.5 71q0 24 13 47q-45 29 -45 81q0 37 25 64q-25 27 -25 64q0 54 47 82q-4 50 -34 107.5t-59.5 95.5t-74.5 87q-103 113 -103 268q0 99 44.5 184.5t117 142t164 89t186.5 32.5 +t186.5 -32.5t164 -89t117 -142t44.5 -184.5z" /> + <glyph glyph-name="exchange" unicode="&#xf0ec;" horiz-adv-x="1792" +d="M1792 352v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5q-12 0 -24 10l-319 320q-9 9 -9 22q0 14 9 23l320 320q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5v-192h1376q13 0 22.5 -9.5t9.5 -22.5zM1792 896q0 -14 -9 -23l-320 -320q-9 -9 -23 -9 +q-13 0 -22.5 9.5t-9.5 22.5v192h-1376q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1376v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23z" /> + <glyph glyph-name="cloud_download" unicode="&#xf0ed;" horiz-adv-x="1920" +d="M1280 608q0 14 -9 23t-23 9h-224v352q0 13 -9.5 22.5t-22.5 9.5h-192q-13 0 -22.5 -9.5t-9.5 -22.5v-352h-224q-13 0 -22.5 -9.5t-9.5 -22.5q0 -14 9 -23l352 -352q9 -9 23 -9t23 9l351 351q10 12 10 24zM1920 384q0 -159 -112.5 -271.5t-271.5 -112.5h-1088 +q-185 0 -316.5 131.5t-131.5 316.5q0 130 70 240t188 165q-2 30 -2 43q0 212 150 362t362 150q156 0 285.5 -87t188.5 -231q71 62 166 62q106 0 181 -75t75 -181q0 -76 -41 -138q130 -31 213.5 -135.5t83.5 -238.5z" /> + <glyph glyph-name="cloud_upload" unicode="&#xf0ee;" horiz-adv-x="1920" +d="M1280 672q0 14 -9 23l-352 352q-9 9 -23 9t-23 -9l-351 -351q-10 -12 -10 -24q0 -14 9 -23t23 -9h224v-352q0 -13 9.5 -22.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 22.5v352h224q13 0 22.5 9.5t9.5 22.5zM1920 384q0 -159 -112.5 -271.5t-271.5 -112.5h-1088 +q-185 0 -316.5 131.5t-131.5 316.5q0 130 70 240t188 165q-2 30 -2 43q0 212 150 362t362 150q156 0 285.5 -87t188.5 -231q71 62 166 62q106 0 181 -75t75 -181q0 -76 -41 -138q130 -31 213.5 -135.5t83.5 -238.5z" /> + <glyph glyph-name="user_md" unicode="&#xf0f0;" horiz-adv-x="1408" +d="M384 192q0 -26 -19 -45t-45 -19t-45 19t-19 45t19 45t45 19t45 -19t19 -45zM1408 131q0 -121 -73 -190t-194 -69h-874q-121 0 -194 69t-73 190q0 68 5.5 131t24 138t47.5 132.5t81 103t120 60.5q-22 -52 -22 -120v-203q-58 -20 -93 -70t-35 -111q0 -80 56 -136t136 -56 +t136 56t56 136q0 61 -35.5 111t-92.5 70v203q0 62 25 93q132 -104 295 -104t295 104q25 -31 25 -93v-64q-106 0 -181 -75t-75 -181v-89q-32 -29 -32 -71q0 -40 28 -68t68 -28t68 28t28 68q0 42 -32 71v89q0 52 38 90t90 38t90 -38t38 -90v-89q-32 -29 -32 -71q0 -40 28 -68 +t68 -28t68 28t28 68q0 42 -32 71v89q0 68 -34.5 127.5t-93.5 93.5q0 10 0.5 42.5t0 48t-2.5 41.5t-7 47t-13 40q68 -15 120 -60.5t81 -103t47.5 -132.5t24 -138t5.5 -131zM1088 1024q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5 +t271.5 -112.5t112.5 -271.5z" /> + <glyph glyph-name="stethoscope" unicode="&#xf0f1;" horiz-adv-x="1408" +d="M1280 832q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 832q0 -62 -35.5 -111t-92.5 -70v-395q0 -159 -131.5 -271.5t-316.5 -112.5t-316.5 112.5t-131.5 271.5v132q-164 20 -274 128t-110 252v512q0 26 19 45t45 19q6 0 16 -2q17 30 47 48 +t65 18q53 0 90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5q-33 0 -64 18v-402q0 -106 94 -181t226 -75t226 75t94 181v402q-31 -18 -64 -18q-53 0 -90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5q35 0 65 -18t47 -48q10 2 16 2q26 0 45 -19t19 -45v-512q0 -144 -110 -252 +t-274 -128v-132q0 -106 94 -181t226 -75t226 75t94 181v395q-57 21 -92.5 70t-35.5 111q0 80 56 136t136 56t136 -56t56 -136z" /> + <glyph glyph-name="suitcase" unicode="&#xf0f2;" horiz-adv-x="1792" +d="M640 1152h512v128h-512v-128zM288 1152v-1280h-64q-92 0 -158 66t-66 158v832q0 92 66 158t158 66h64zM1408 1152v-1280h-1024v1280h128v160q0 40 28 68t68 28h576q40 0 68 -28t28 -68v-160h128zM1792 928v-832q0 -92 -66 -158t-158 -66h-64v1280h64q92 0 158 -66 +t66 -158z" /> + <glyph glyph-name="bell_alt" unicode="&#xf0f3;" horiz-adv-x="1792" +d="M912 -160q0 16 -16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16zM1728 128q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-181 75t-75 181h-448q-52 0 -90 38t-38 90q50 42 91 88t85 119.5t74.5 158.5 +t50 206t19.5 260q0 152 117 282.5t307 158.5q-8 19 -8 39q0 40 28 68t68 28t68 -28t28 -68q0 -20 -8 -39q190 -28 307 -158.5t117 -282.5q0 -139 19.5 -260t50 -206t74.5 -158.5t85 -119.5t91 -88z" /> + <glyph glyph-name="coffee" unicode="&#xf0f4;" horiz-adv-x="1920" +d="M1664 896q0 80 -56 136t-136 56h-64v-384h64q80 0 136 56t56 136zM0 128h1792q0 -106 -75 -181t-181 -75h-1280q-106 0 -181 75t-75 181zM1856 896q0 -159 -112.5 -271.5t-271.5 -112.5h-64v-32q0 -92 -66 -158t-158 -66h-704q-92 0 -158 66t-66 158v736q0 26 19 45 +t45 19h1152q159 0 271.5 -112.5t112.5 -271.5z" /> + <glyph glyph-name="food" unicode="&#xf0f5;" horiz-adv-x="1408" +d="M640 1472v-640q0 -61 -35.5 -111t-92.5 -70v-779q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v779q-57 20 -92.5 70t-35.5 111v640q0 26 19 45t45 19t45 -19t19 -45v-416q0 -26 19 -45t45 -19t45 19t19 45v416q0 26 19 45t45 19t45 -19t19 -45v-416q0 -26 19 -45 +t45 -19t45 19t19 45v416q0 26 19 45t45 19t45 -19t19 -45zM1408 1472v-1600q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v512h-224q-13 0 -22.5 9.5t-9.5 22.5v800q0 132 94 226t226 94h256q26 0 45 -19t19 -45z" /> + <glyph glyph-name="file_text_alt" unicode="&#xf0f6;" +d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z +M384 736q0 14 9 23t23 9h704q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23v64zM1120 512q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h704zM1120 256q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704 +q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h704z" /> + <glyph glyph-name="building" unicode="&#xf0f7;" horiz-adv-x="1408" +d="M384 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z +M640 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z +M1152 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z +M640 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z +M1152 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z +M640 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z +M1152 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z +M640 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z +M896 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z +M896 -128h384v1536h-1152v-1536h384v224q0 13 9.5 22.5t22.5 9.5h320q13 0 22.5 -9.5t9.5 -22.5v-224zM1408 1472v-1664q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v1664q0 26 19 45t45 19h1280q26 0 45 -19t19 -45z" /> + <glyph glyph-name="hospital" unicode="&#xf0f8;" horiz-adv-x="1408" +d="M384 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z +M640 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z +M1152 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z +M640 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z +M896 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z +M896 -128h384v1152h-256v-32q0 -40 -28 -68t-68 -28h-448q-40 0 -68 28t-28 68v32h-256v-1152h384v224q0 13 9.5 22.5t22.5 9.5h320q13 0 22.5 -9.5t9.5 -22.5v-224zM896 1056v320q0 13 -9.5 22.5t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-96h-128v96q0 13 -9.5 22.5 +t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-320q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5v96h128v-96q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5zM1408 1088v-1280q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v1280q0 26 19 45t45 19h320 +v288q0 40 28 68t68 28h448q40 0 68 -28t28 -68v-288h320q26 0 45 -19t19 -45z" /> + <glyph glyph-name="ambulance" unicode="&#xf0f9;" horiz-adv-x="1920" +d="M640 128q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM256 640h384v256h-158q-14 -2 -22 -9l-195 -195q-7 -12 -9 -22v-30zM1536 128q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5 +t90.5 37.5t37.5 90.5zM1664 800v192q0 14 -9 23t-23 9h-224v224q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-224h-224q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h224v-224q0 -14 9 -23t23 -9h192q14 0 23 9t9 23v224h224q14 0 23 9t9 23zM1920 1344v-1152 +q0 -26 -19 -45t-45 -19h-192q0 -106 -75 -181t-181 -75t-181 75t-75 181h-384q0 -106 -75 -181t-181 -75t-181 75t-75 181h-128q-26 0 -45 19t-19 45t19 45t45 19v416q0 26 13 58t32 51l198 198q19 19 51 32t58 13h160v320q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" /> + <glyph glyph-name="medkit" unicode="&#xf0fa;" horiz-adv-x="1792" +d="M1280 416v192q0 14 -9 23t-23 9h-224v224q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-224h-224q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h224v-224q0 -14 9 -23t23 -9h192q14 0 23 9t9 23v224h224q14 0 23 9t9 23zM640 1152h512v128h-512v-128zM256 1152v-1280h-32 +q-92 0 -158 66t-66 158v832q0 92 66 158t158 66h32zM1440 1152v-1280h-1088v1280h160v160q0 40 28 68t68 28h576q40 0 68 -28t28 -68v-160h160zM1792 928v-832q0 -92 -66 -158t-158 -66h-32v1280h32q92 0 158 -66t66 -158z" /> + <glyph glyph-name="fighter_jet" unicode="&#xf0fb;" horiz-adv-x="1920" +d="M1920 576q-1 -32 -288 -96l-352 -32l-224 -64h-64l-293 -352h69q26 0 45 -4.5t19 -11.5t-19 -11.5t-45 -4.5h-96h-160h-64v32h64v416h-160l-192 -224h-96l-32 32v192h32v32h128v8l-192 24v128l192 24v8h-128v32h-32v192l32 32h96l192 -224h160v416h-64v32h64h160h96 +q26 0 45 -4.5t19 -11.5t-19 -11.5t-45 -4.5h-69l293 -352h64l224 -64l352 -32q128 -28 200 -52t80 -34z" /> + <glyph glyph-name="beer" unicode="&#xf0fc;" horiz-adv-x="1664" +d="M640 640v384h-256v-256q0 -53 37.5 -90.5t90.5 -37.5h128zM1664 192v-192h-1152v192l128 192h-128q-159 0 -271.5 112.5t-112.5 271.5v320l-64 64l32 128h480l32 128h960l32 -192l-64 -32v-800z" /> + <glyph glyph-name="h_sign" unicode="&#xf0fd;" +d="M1280 192v896q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-320h-512v320q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-896q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v320h512v-320q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1536 1120v-960 +q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="f0fe" unicode="&#xf0fe;" +d="M1280 576v128q0 26 -19 45t-45 19h-320v320q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-320h-320q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h320v-320q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v320h320q26 0 45 19t19 45zM1536 1120v-960 +q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="double_angle_left" unicode="&#xf100;" horiz-adv-x="1024" +d="M627 160q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23zM1011 160q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23 +t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23z" /> + <glyph glyph-name="double_angle_right" unicode="&#xf101;" horiz-adv-x="1024" +d="M595 576q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23zM979 576q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23 +l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" /> + <glyph glyph-name="double_angle_up" unicode="&#xf102;" horiz-adv-x="1152" +d="M1075 224q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23zM1075 608q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393 +q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" /> + <glyph glyph-name="double_angle_down" unicode="&#xf103;" horiz-adv-x="1152" +d="M1075 672q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23zM1075 1056q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23 +t10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23z" /> + <glyph glyph-name="angle_left" unicode="&#xf104;" horiz-adv-x="640" +d="M627 992q0 -13 -10 -23l-393 -393l393 -393q10 -10 10 -23t-10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23z" /> + <glyph glyph-name="angle_right" unicode="&#xf105;" horiz-adv-x="640" +d="M595 576q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" /> + <glyph glyph-name="angle_up" unicode="&#xf106;" horiz-adv-x="1152" +d="M1075 352q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" /> + <glyph glyph-name="angle_down" unicode="&#xf107;" horiz-adv-x="1152" +d="M1075 800q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23z" /> + <glyph glyph-name="desktop" unicode="&#xf108;" horiz-adv-x="1920" +d="M1792 544v832q0 13 -9.5 22.5t-22.5 9.5h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-832q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5zM1920 1376v-1088q0 -66 -47 -113t-113 -47h-544q0 -37 16 -77.5t32 -71t16 -43.5q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19 +t-19 45q0 14 16 44t32 70t16 78h-544q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" /> + <glyph glyph-name="laptop" unicode="&#xf109;" horiz-adv-x="1920" +d="M416 256q-66 0 -113 47t-47 113v704q0 66 47 113t113 47h1088q66 0 113 -47t47 -113v-704q0 -66 -47 -113t-113 -47h-1088zM384 1120v-704q0 -13 9.5 -22.5t22.5 -9.5h1088q13 0 22.5 9.5t9.5 22.5v704q0 13 -9.5 22.5t-22.5 9.5h-1088q-13 0 -22.5 -9.5t-9.5 -22.5z +M1760 192h160v-96q0 -40 -47 -68t-113 -28h-1600q-66 0 -113 28t-47 68v96h160h1600zM1040 96q16 0 16 16t-16 16h-160q-16 0 -16 -16t16 -16h160z" /> + <glyph glyph-name="tablet" unicode="&#xf10a;" horiz-adv-x="1152" +d="M640 128q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1024 288v960q0 13 -9.5 22.5t-22.5 9.5h-832q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h832q13 0 22.5 9.5t9.5 22.5zM1152 1248v-1088q0 -66 -47 -113t-113 -47h-832 +q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h832q66 0 113 -47t47 -113z" /> + <glyph glyph-name="mobile_phone" unicode="&#xf10b;" horiz-adv-x="768" +d="M464 128q0 33 -23.5 56.5t-56.5 23.5t-56.5 -23.5t-23.5 -56.5t23.5 -56.5t56.5 -23.5t56.5 23.5t23.5 56.5zM672 288v704q0 13 -9.5 22.5t-22.5 9.5h-512q-13 0 -22.5 -9.5t-9.5 -22.5v-704q0 -13 9.5 -22.5t22.5 -9.5h512q13 0 22.5 9.5t9.5 22.5zM480 1136 +q0 16 -16 16h-160q-16 0 -16 -16t16 -16h160q16 0 16 16zM768 1152v-1024q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v1024q0 52 38 90t90 38h512q52 0 90 -38t38 -90z" /> + <glyph glyph-name="circle_blank" unicode="&#xf10c;" +d="M768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103 +t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="quote_left" unicode="&#xf10d;" horiz-adv-x="1664" +d="M768 576v-384q0 -80 -56 -136t-136 -56h-384q-80 0 -136 56t-56 136v704q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5h64q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-64q-106 0 -181 -75t-75 -181v-32q0 -40 28 -68t68 -28h224q80 0 136 -56t56 -136z +M1664 576v-384q0 -80 -56 -136t-136 -56h-384q-80 0 -136 56t-56 136v704q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5h64q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-64q-106 0 -181 -75t-75 -181v-32q0 -40 28 -68t68 -28h224q80 0 136 -56t56 -136z" /> + <glyph glyph-name="quote_right" unicode="&#xf10e;" horiz-adv-x="1664" +d="M768 1216v-704q0 -104 -40.5 -198.5t-109.5 -163.5t-163.5 -109.5t-198.5 -40.5h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64q106 0 181 75t75 181v32q0 40 -28 68t-68 28h-224q-80 0 -136 56t-56 136v384q0 80 56 136t136 56h384q80 0 136 -56t56 -136zM1664 1216 +v-704q0 -104 -40.5 -198.5t-109.5 -163.5t-163.5 -109.5t-198.5 -40.5h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64q106 0 181 75t75 181v32q0 40 -28 68t-68 28h-224q-80 0 -136 56t-56 136v384q0 80 56 136t136 56h384q80 0 136 -56t56 -136z" /> + <glyph glyph-name="spinner" unicode="&#xf110;" horiz-adv-x="1792" +d="M526 142q0 -53 -37.5 -90.5t-90.5 -37.5q-52 0 -90 38t-38 90q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1024 -64q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM320 640q0 -53 -37.5 -90.5t-90.5 -37.5 +t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1522 142q0 -52 -38 -90t-90 -38q-53 0 -90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM558 1138q0 -66 -47 -113t-113 -47t-113 47t-47 113t47 113t113 47t113 -47t47 -113z +M1728 640q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1088 1344q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1618 1138q0 -93 -66 -158.5t-158 -65.5q-93 0 -158.5 65.5t-65.5 158.5 +q0 92 65.5 158t158.5 66q92 0 158 -66t66 -158z" /> + <glyph glyph-name="circle" unicode="&#xf111;" +d="M1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="reply" unicode="&#xf112;" horiz-adv-x="1792" +d="M1792 416q0 -166 -127 -451q-3 -7 -10.5 -24t-13.5 -30t-13 -22q-12 -17 -28 -17q-15 0 -23.5 10t-8.5 25q0 9 2.5 26.5t2.5 23.5q5 68 5 123q0 101 -17.5 181t-48.5 138.5t-80 101t-105.5 69.5t-133 42.5t-154 21.5t-175.5 6h-224v-256q0 -26 -19 -45t-45 -19t-45 19 +l-512 512q-19 19 -19 45t19 45l512 512q19 19 45 19t45 -19t19 -45v-256h224q713 0 875 -403q53 -134 53 -333z" /> + <glyph glyph-name="github_alt" unicode="&#xf113;" horiz-adv-x="1664" +d="M640 320q0 -40 -12.5 -82t-43 -76t-72.5 -34t-72.5 34t-43 76t-12.5 82t12.5 82t43 76t72.5 34t72.5 -34t43 -76t12.5 -82zM1280 320q0 -40 -12.5 -82t-43 -76t-72.5 -34t-72.5 34t-43 76t-12.5 82t12.5 82t43 76t72.5 34t72.5 -34t43 -76t12.5 -82zM1440 320 +q0 120 -69 204t-187 84q-41 0 -195 -21q-71 -11 -157 -11t-157 11q-152 21 -195 21q-118 0 -187 -84t-69 -204q0 -88 32 -153.5t81 -103t122 -60t140 -29.5t149 -7h168q82 0 149 7t140 29.5t122 60t81 103t32 153.5zM1664 496q0 -207 -61 -331q-38 -77 -105.5 -133t-141 -86 +t-170 -47.5t-171.5 -22t-167 -4.5q-78 0 -142 3t-147.5 12.5t-152.5 30t-137 51.5t-121 81t-86 115q-62 123 -62 331q0 237 136 396q-27 82 -27 170q0 116 51 218q108 0 190 -39.5t189 -123.5q147 35 309 35q148 0 280 -32q105 82 187 121t189 39q51 -102 51 -218 +q0 -87 -27 -168q136 -160 136 -398z" /> + <glyph glyph-name="folder_close_alt" unicode="&#xf114;" horiz-adv-x="1664" +d="M1536 224v704q0 40 -28 68t-68 28h-704q-40 0 -68 28t-28 68v64q0 40 -28 68t-68 28h-320q-40 0 -68 -28t-28 -68v-960q0 -40 28 -68t68 -28h1216q40 0 68 28t28 68zM1664 928v-704q0 -92 -66 -158t-158 -66h-1216q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320 +q92 0 158 -66t66 -158v-32h672q92 0 158 -66t66 -158z" /> + <glyph glyph-name="folder_open_alt" unicode="&#xf115;" horiz-adv-x="1920" +d="M1781 605q0 35 -53 35h-1088q-40 0 -85.5 -21.5t-71.5 -52.5l-294 -363q-18 -24 -18 -40q0 -35 53 -35h1088q40 0 86 22t71 53l294 363q18 22 18 39zM640 768h768v160q0 40 -28 68t-68 28h-576q-40 0 -68 28t-28 68v64q0 40 -28 68t-68 28h-320q-40 0 -68 -28t-28 -68 +v-853l256 315q44 53 116 87.5t140 34.5zM1909 605q0 -62 -46 -120l-295 -363q-43 -53 -116 -87.5t-140 -34.5h-1088q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h544q92 0 158 -66t66 -158v-160h192q54 0 99 -24.5t67 -70.5q15 -32 15 -68z +" /> + <glyph glyph-name="expand_alt" unicode="&#xf116;" horiz-adv-x="1792" + /> + <glyph glyph-name="collapse_alt" unicode="&#xf117;" horiz-adv-x="1792" + /> + <glyph glyph-name="smile" unicode="&#xf118;" +d="M1134 461q-37 -121 -138 -195t-228 -74t-228 74t-138 195q-8 25 4 48.5t38 31.5q25 8 48.5 -4t31.5 -38q25 -80 92.5 -129.5t151.5 -49.5t151.5 49.5t92.5 129.5q8 26 32 38t49 4t37 -31.5t4 -48.5zM640 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5 +t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1152 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5 +t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="frown" unicode="&#xf119;" +d="M1134 307q8 -25 -4 -48.5t-37 -31.5t-49 4t-32 38q-25 80 -92.5 129.5t-151.5 49.5t-151.5 -49.5t-92.5 -129.5q-8 -26 -31.5 -38t-48.5 -4q-26 8 -38 31.5t-4 48.5q37 121 138 195t228 74t228 -74t138 -195zM640 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5 +t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1152 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204 +t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="meh" unicode="&#xf11a;" +d="M1152 448q0 -26 -19 -45t-45 -19h-640q-26 0 -45 19t-19 45t19 45t45 19h640q26 0 45 -19t19 -45zM640 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1152 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5 +t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640 +q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="gamepad" unicode="&#xf11b;" horiz-adv-x="1920" +d="M832 448v128q0 14 -9 23t-23 9h-192v192q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-192h-192q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h192v-192q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v192h192q14 0 23 9t9 23zM1408 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5 +t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1664 640q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1920 512q0 -212 -150 -362t-362 -150q-192 0 -338 128h-220q-146 -128 -338 -128q-212 0 -362 150 +t-150 362t150 362t362 150h896q212 0 362 -150t150 -362z" /> + <glyph glyph-name="keyboard" unicode="&#xf11c;" horiz-adv-x="1920" +d="M384 368v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM512 624v-96q0 -16 -16 -16h-224q-16 0 -16 16v96q0 16 16 16h224q16 0 16 -16zM384 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1408 368v-96q0 -16 -16 -16 +h-864q-16 0 -16 16v96q0 16 16 16h864q16 0 16 -16zM768 624v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM640 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1024 624v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16 +h96q16 0 16 -16zM896 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1280 624v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1664 368v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1152 880v-96 +q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1408 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1664 880v-352q0 -16 -16 -16h-224q-16 0 -16 16v96q0 16 16 16h112v240q0 16 16 16h96q16 0 16 -16zM1792 128v896h-1664v-896 +h1664zM1920 1024v-896q0 -53 -37.5 -90.5t-90.5 -37.5h-1664q-53 0 -90.5 37.5t-37.5 90.5v896q0 53 37.5 90.5t90.5 37.5h1664q53 0 90.5 -37.5t37.5 -90.5z" /> + <glyph glyph-name="flag_alt" unicode="&#xf11d;" horiz-adv-x="1792" +d="M1664 491v616q-169 -91 -306 -91q-82 0 -145 32q-100 49 -184 76.5t-178 27.5q-173 0 -403 -127v-599q245 113 433 113q55 0 103.5 -7.5t98 -26t77 -31t82.5 -39.5l28 -14q44 -22 101 -22q120 0 293 92zM320 1280q0 -35 -17.5 -64t-46.5 -46v-1266q0 -14 -9 -23t-23 -9 +h-64q-14 0 -23 9t-9 23v1266q-29 17 -46.5 46t-17.5 64q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1792 1216v-763q0 -39 -35 -57q-10 -5 -17 -9q-218 -116 -369 -116q-88 0 -158 35l-28 14q-64 33 -99 48t-91 29t-114 14q-102 0 -235.5 -44t-228.5 -102 +q-15 -9 -33 -9q-16 0 -32 8q-32 19 -32 56v742q0 35 31 55q35 21 78.5 42.5t114 52t152.5 49.5t155 19q112 0 209 -31t209 -86q38 -19 89 -19q122 0 310 112q22 12 31 17q31 16 62 -2q31 -20 31 -55z" /> + <glyph glyph-name="flag_checkered" unicode="&#xf11e;" horiz-adv-x="1792" +d="M832 536v192q-181 -16 -384 -117v-185q205 96 384 110zM832 954v197q-172 -8 -384 -126v-189q215 111 384 118zM1664 491v184q-235 -116 -384 -71v224q-20 6 -39 15q-5 3 -33 17t-34.5 17t-31.5 15t-34.5 15.5t-32.5 13t-36 12.5t-35 8.5t-39.5 7.5t-39.5 4t-44 2 +q-23 0 -49 -3v-222h19q102 0 192.5 -29t197.5 -82q19 -9 39 -15v-188q42 -17 91 -17q120 0 293 92zM1664 918v189q-169 -91 -306 -91q-45 0 -78 8v-196q148 -42 384 90zM320 1280q0 -35 -17.5 -64t-46.5 -46v-1266q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v1266 +q-29 17 -46.5 46t-17.5 64q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1792 1216v-763q0 -39 -35 -57q-10 -5 -17 -9q-218 -116 -369 -116q-88 0 -158 35l-28 14q-64 33 -99 48t-91 29t-114 14q-102 0 -235.5 -44t-228.5 -102q-15 -9 -33 -9q-16 0 -32 8 +q-32 19 -32 56v742q0 35 31 55q35 21 78.5 42.5t114 52t152.5 49.5t155 19q112 0 209 -31t209 -86q38 -19 89 -19q122 0 310 112q22 12 31 17q31 16 62 -2q31 -20 31 -55z" /> + <glyph glyph-name="terminal" unicode="&#xf120;" horiz-adv-x="1664" +d="M585 553l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23zM1664 96v-64q0 -14 -9 -23t-23 -9h-960q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h960q14 0 23 -9 +t9 -23z" /> + <glyph glyph-name="code" unicode="&#xf121;" horiz-adv-x="1920" +d="M617 137l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23t-10 -23zM1208 1204l-373 -1291q-4 -13 -15.5 -19.5t-23.5 -2.5l-62 17q-13 4 -19.5 15.5t-2.5 24.5 +l373 1291q4 13 15.5 19.5t23.5 2.5l62 -17q13 -4 19.5 -15.5t2.5 -24.5zM1865 553l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23z" /> + <glyph glyph-name="reply_all" unicode="&#xf122;" horiz-adv-x="1792" +d="M640 454v-70q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-512 512q-19 19 -19 45t19 45l512 512q29 31 70 14q39 -17 39 -59v-69l-397 -398q-19 -19 -19 -45t19 -45zM1792 416q0 -58 -17 -133.5t-38.5 -138t-48 -125t-40.5 -90.5l-20 -40q-8 -17 -28 -17q-6 0 -9 1 +q-25 8 -23 34q43 400 -106 565q-64 71 -170.5 110.5t-267.5 52.5v-251q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-512 512q-19 19 -19 45t19 45l512 512q29 31 70 14q39 -17 39 -59v-262q411 -28 599 -221q169 -173 169 -509z" /> + <glyph glyph-name="star_half_empty" unicode="&#xf123;" horiz-adv-x="1664" +d="M1186 579l257 250l-356 52l-66 10l-30 60l-159 322v-963l59 -31l318 -168l-60 355l-12 66zM1638 841l-363 -354l86 -500q5 -33 -6 -51.5t-34 -18.5q-17 0 -40 12l-449 236l-449 -236q-23 -12 -40 -12q-23 0 -34 18.5t-6 51.5l86 500l-364 354q-32 32 -23 59.5t54 34.5 +l502 73l225 455q20 41 49 41q28 0 49 -41l225 -455l502 -73q45 -7 54 -34.5t-24 -59.5z" /> + <glyph glyph-name="location_arrow" unicode="&#xf124;" horiz-adv-x="1408" +d="M1401 1187l-640 -1280q-17 -35 -57 -35q-5 0 -15 2q-22 5 -35.5 22.5t-13.5 39.5v576h-576q-22 0 -39.5 13.5t-22.5 35.5t4 42t29 30l1280 640q13 7 29 7q27 0 45 -19q15 -14 18.5 -34.5t-6.5 -39.5z" /> + <glyph glyph-name="crop" unicode="&#xf125;" horiz-adv-x="1664" +d="M557 256h595v595zM512 301l595 595h-595v-595zM1664 224v-192q0 -14 -9 -23t-23 -9h-224v-224q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v224h-864q-14 0 -23 9t-9 23v864h-224q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h224v224q0 14 9 23t23 9h192q14 0 23 -9t9 -23 +v-224h851l246 247q10 9 23 9t23 -9q9 -10 9 -23t-9 -23l-247 -246v-851h224q14 0 23 -9t9 -23z" /> + <glyph glyph-name="code_fork" unicode="&#xf126;" horiz-adv-x="1024" +d="M288 64q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM288 1216q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM928 1088q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1024 1088q0 -52 -26 -96.5t-70 -69.5 +q-2 -287 -226 -414q-67 -38 -203 -81q-128 -40 -169.5 -71t-41.5 -100v-26q44 -25 70 -69.5t26 -96.5q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 52 26 96.5t70 69.5v820q-44 25 -70 69.5t-26 96.5q0 80 56 136t136 56t136 -56t56 -136q0 -52 -26 -96.5t-70 -69.5v-497 +q54 26 154 57q55 17 87.5 29.5t70.5 31t59 39.5t40.5 51t28 69.5t8.5 91.5q-44 25 -70 69.5t-26 96.5q0 80 56 136t136 56t136 -56t56 -136z" /> + <glyph glyph-name="unlink" unicode="&#xf127;" horiz-adv-x="1664" +d="M439 265l-256 -256q-11 -9 -23 -9t-23 9q-9 10 -9 23t9 23l256 256q10 9 23 9t23 -9q9 -10 9 -23t-9 -23zM608 224v-320q0 -14 -9 -23t-23 -9t-23 9t-9 23v320q0 14 9 23t23 9t23 -9t9 -23zM384 448q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23t9 23t23 9h320 +q14 0 23 -9t9 -23zM1648 320q0 -120 -85 -203l-147 -146q-83 -83 -203 -83q-121 0 -204 85l-334 335q-21 21 -42 56l239 18l273 -274q27 -27 68 -27.5t68 26.5l147 146q28 28 28 67q0 40 -28 68l-274 275l18 239q35 -21 56 -42l336 -336q84 -86 84 -204zM1031 1044l-239 -18 +l-273 274q-28 28 -68 28q-39 0 -68 -27l-147 -146q-28 -28 -28 -67q0 -40 28 -68l274 -274l-18 -240q-35 21 -56 42l-336 336q-84 86 -84 204q0 120 85 203l147 146q83 83 203 83q121 0 204 -85l334 -335q21 -21 42 -56zM1664 960q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9 +t-9 23t9 23t23 9h320q14 0 23 -9t9 -23zM1120 1504v-320q0 -14 -9 -23t-23 -9t-23 9t-9 23v320q0 14 9 23t23 9t23 -9t9 -23zM1527 1353l-256 -256q-11 -9 -23 -9t-23 9q-9 10 -9 23t9 23l256 256q10 9 23 9t23 -9q9 -10 9 -23t-9 -23z" /> + <glyph glyph-name="question" unicode="&#xf128;" horiz-adv-x="1024" +d="M704 280v-240q0 -16 -12 -28t-28 -12h-240q-16 0 -28 12t-12 28v240q0 16 12 28t28 12h240q16 0 28 -12t12 -28zM1020 880q0 -54 -15.5 -101t-35 -76.5t-55 -59.5t-57.5 -43.5t-61 -35.5q-41 -23 -68.5 -65t-27.5 -67q0 -17 -12 -32.5t-28 -15.5h-240q-15 0 -25.5 18.5 +t-10.5 37.5v45q0 83 65 156.5t143 108.5q59 27 84 56t25 76q0 42 -46.5 74t-107.5 32q-65 0 -108 -29q-35 -25 -107 -115q-13 -16 -31 -16q-12 0 -25 8l-164 125q-13 10 -15.5 25t5.5 28q160 266 464 266q80 0 161 -31t146 -83t106 -127.5t41 -158.5z" /> + <glyph glyph-name="_279" unicode="&#xf129;" horiz-adv-x="640" +d="M640 192v-128q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64v384h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-576h64q26 0 45 -19t19 -45zM512 1344v-192q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v192 +q0 26 19 45t45 19h256q26 0 45 -19t19 -45z" /> + <glyph glyph-name="exclamation" unicode="&#xf12a;" horiz-adv-x="640" +d="M512 288v-224q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v224q0 26 19 45t45 19h256q26 0 45 -19t19 -45zM542 1344l-28 -768q-1 -26 -20.5 -45t-45.5 -19h-256q-26 0 -45.5 19t-20.5 45l-28 768q-1 26 17.5 45t44.5 19h320q26 0 44.5 -19t17.5 -45z" /> + <glyph glyph-name="superscript" unicode="&#xf12b;" +d="M897 167v-167h-248l-159 252l-24 42q-8 9 -11 21h-3q-1 -3 -2.5 -6.5t-3.5 -8t-3 -6.5q-10 -20 -25 -44l-155 -250h-258v167h128l197 291l-185 272h-137v168h276l139 -228q2 -4 23 -42q8 -9 11 -21h3q3 9 11 21l25 42l140 228h257v-168h-125l-184 -267l204 -296h109z +M1534 846v-206h-514l-3 27q-4 28 -4 46q0 64 26 117t65 86.5t84 65t84 54.5t65 54t26 64q0 38 -29.5 62.5t-70.5 24.5q-51 0 -97 -39q-14 -11 -36 -38l-105 92q26 37 63 66q83 65 188 65q110 0 178 -59.5t68 -158.5q0 -56 -24.5 -103t-62 -76.5t-81.5 -58.5t-82 -50.5 +t-65.5 -51.5t-30.5 -63h232v80h126z" /> + <glyph glyph-name="subscript" unicode="&#xf12c;" +d="M897 167v-167h-248l-159 252l-24 42q-8 9 -11 21h-3q-1 -3 -2.5 -6.5t-3.5 -8t-3 -6.5q-10 -20 -25 -44l-155 -250h-258v167h128l197 291l-185 272h-137v168h276l139 -228q2 -4 23 -42q8 -9 11 -21h3q3 9 11 21l25 42l140 228h257v-168h-125l-184 -267l204 -296h109z +M1536 -50v-206h-514l-4 27q-3 45 -3 46q0 64 26 117t65 86.5t84 65t84 54.5t65 54t26 64q0 38 -29.5 62.5t-70.5 24.5q-51 0 -97 -39q-14 -11 -36 -38l-105 92q26 37 63 66q80 65 188 65q110 0 178 -59.5t68 -158.5q0 -66 -34.5 -118.5t-84 -86t-99.5 -62.5t-87 -63t-41 -73 +h232v80h126z" /> + <glyph glyph-name="_283" unicode="&#xf12d;" horiz-adv-x="1920" +d="M896 128l336 384h-768l-336 -384h768zM1909 1205q15 -34 9.5 -71.5t-30.5 -65.5l-896 -1024q-38 -44 -96 -44h-768q-38 0 -69.5 20.5t-47.5 54.5q-15 34 -9.5 71.5t30.5 65.5l896 1024q38 44 96 44h768q38 0 69.5 -20.5t47.5 -54.5z" /> + <glyph glyph-name="puzzle_piece" unicode="&#xf12e;" horiz-adv-x="1664" +d="M1664 438q0 -81 -44.5 -135t-123.5 -54q-41 0 -77.5 17.5t-59 38t-56.5 38t-71 17.5q-110 0 -110 -124q0 -39 16 -115t15 -115v-5q-22 0 -33 -1q-34 -3 -97.5 -11.5t-115.5 -13.5t-98 -5q-61 0 -103 26.5t-42 83.5q0 37 17.5 71t38 56.5t38 59t17.5 77.5q0 79 -54 123.5 +t-135 44.5q-84 0 -143 -45.5t-59 -127.5q0 -43 15 -83t33.5 -64.5t33.5 -53t15 -50.5q0 -45 -46 -89q-37 -35 -117 -35q-95 0 -245 24q-9 2 -27.5 4t-27.5 4l-13 2q-1 0 -3 1q-2 0 -2 1v1024q2 -1 17.5 -3.5t34 -5t21.5 -3.5q150 -24 245 -24q80 0 117 35q46 44 46 89 +q0 22 -15 50.5t-33.5 53t-33.5 64.5t-15 83q0 82 59 127.5t144 45.5q80 0 134 -44.5t54 -123.5q0 -41 -17.5 -77.5t-38 -59t-38 -56.5t-17.5 -71q0 -57 42 -83.5t103 -26.5q64 0 180 15t163 17v-2q-1 -2 -3.5 -17.5t-5 -34t-3.5 -21.5q-24 -150 -24 -245q0 -80 35 -117 +q44 -46 89 -46q22 0 50.5 15t53 33.5t64.5 33.5t83 15q82 0 127.5 -59t45.5 -143z" /> + <glyph glyph-name="microphone" unicode="&#xf130;" horiz-adv-x="1152" +d="M1152 832v-128q0 -221 -147.5 -384.5t-364.5 -187.5v-132h256q26 0 45 -19t19 -45t-19 -45t-45 -19h-640q-26 0 -45 19t-19 45t19 45t45 19h256v132q-217 24 -364.5 187.5t-147.5 384.5v128q0 26 19 45t45 19t45 -19t19 -45v-128q0 -185 131.5 -316.5t316.5 -131.5 +t316.5 131.5t131.5 316.5v128q0 26 19 45t45 19t45 -19t19 -45zM896 1216v-512q0 -132 -94 -226t-226 -94t-226 94t-94 226v512q0 132 94 226t226 94t226 -94t94 -226z" /> + <glyph glyph-name="microphone_off" unicode="&#xf131;" horiz-adv-x="1408" +d="M271 591l-101 -101q-42 103 -42 214v128q0 26 19 45t45 19t45 -19t19 -45v-128q0 -53 15 -113zM1385 1193l-361 -361v-128q0 -132 -94 -226t-226 -94q-55 0 -109 19l-96 -96q97 -51 205 -51q185 0 316.5 131.5t131.5 316.5v128q0 26 19 45t45 19t45 -19t19 -45v-128 +q0 -221 -147.5 -384.5t-364.5 -187.5v-132h256q26 0 45 -19t19 -45t-19 -45t-45 -19h-640q-26 0 -45 19t-19 45t19 45t45 19h256v132q-125 13 -235 81l-254 -254q-10 -10 -23 -10t-23 10l-82 82q-10 10 -10 23t10 23l1234 1234q10 10 23 10t23 -10l82 -82q10 -10 10 -23 +t-10 -23zM1005 1325l-621 -621v512q0 132 94 226t226 94q102 0 184.5 -59t116.5 -152z" /> + <glyph glyph-name="shield" unicode="&#xf132;" horiz-adv-x="1280" +d="M1088 576v640h-448v-1137q119 63 213 137q235 184 235 360zM1280 1344v-768q0 -86 -33.5 -170.5t-83 -150t-118 -127.5t-126.5 -103t-121 -77.5t-89.5 -49.5t-42.5 -20q-12 -6 -26 -6t-26 6q-16 7 -42.5 20t-89.5 49.5t-121 77.5t-126.5 103t-118 127.5t-83 150 +t-33.5 170.5v768q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" /> + <glyph glyph-name="calendar_empty" unicode="&#xf133;" horiz-adv-x="1664" +d="M128 -128h1408v1024h-1408v-1024zM512 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1280 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1664 1152v-1280 +q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90z" /> + <glyph glyph-name="fire_extinguisher" unicode="&#xf134;" horiz-adv-x="1408" +d="M512 1344q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 1376v-320q0 -16 -12 -25q-8 -7 -20 -7q-4 0 -7 1l-448 96q-11 2 -18 11t-7 20h-256v-102q111 -23 183.5 -111t72.5 -203v-800q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v800 +q0 106 62.5 190.5t161.5 114.5v111h-32q-59 0 -115 -23.5t-91.5 -53t-66 -66.5t-40.5 -53.5t-14 -24.5q-17 -35 -57 -35q-16 0 -29 7q-23 12 -31.5 37t3.5 49q5 10 14.5 26t37.5 53.5t60.5 70t85 67t108.5 52.5q-25 42 -25 86q0 66 47 113t113 47t113 -47t47 -113 +q0 -33 -14 -64h302q0 11 7 20t18 11l448 96q3 1 7 1q12 0 20 -7q12 -9 12 -25z" /> + <glyph glyph-name="rocket" unicode="&#xf135;" horiz-adv-x="1664" +d="M1440 1088q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1664 1376q0 -249 -75.5 -430.5t-253.5 -360.5q-81 -80 -195 -176l-20 -379q-2 -16 -16 -26l-384 -224q-7 -4 -16 -4q-12 0 -23 9l-64 64q-13 14 -8 32l85 276l-281 281l-276 -85q-3 -1 -9 -1 +q-14 0 -23 9l-64 64q-17 19 -5 39l224 384q10 14 26 16l379 20q96 114 176 195q188 187 358 258t431 71q14 0 24 -9.5t10 -22.5z" /> + <glyph glyph-name="maxcdn" unicode="&#xf136;" horiz-adv-x="1792" +d="M1745 763l-164 -763h-334l178 832q13 56 -15 88q-27 33 -83 33h-169l-204 -953h-334l204 953h-286l-204 -953h-334l204 953l-153 327h1276q101 0 189.5 -40.5t147.5 -113.5q60 -73 81 -168.5t0 -194.5z" /> + <glyph glyph-name="chevron_sign_left" unicode="&#xf137;" +d="M909 141l102 102q19 19 19 45t-19 45l-307 307l307 307q19 19 19 45t-19 45l-102 102q-19 19 -45 19t-45 -19l-454 -454q-19 -19 -19 -45t19 -45l454 -454q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 +t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="chevron_sign_right" unicode="&#xf138;" +d="M717 141l454 454q19 19 19 45t-19 45l-454 454q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45t19 -45l307 -307l-307 -307q-19 -19 -19 -45t19 -45l102 -102q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 +t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="chevron_sign_up" unicode="&#xf139;" +d="M1165 397l102 102q19 19 19 45t-19 45l-454 454q-19 19 -45 19t-45 -19l-454 -454q-19 -19 -19 -45t19 -45l102 -102q19 -19 45 -19t45 19l307 307l307 -307q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 +t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="chevron_sign_down" unicode="&#xf13a;" +d="M813 237l454 454q19 19 19 45t-19 45l-102 102q-19 19 -45 19t-45 -19l-307 -307l-307 307q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45t19 -45l454 -454q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 +t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="html5" unicode="&#xf13b;" horiz-adv-x="1408" +d="M1130 939l16 175h-884l47 -534h612l-22 -228l-197 -53l-196 53l-13 140h-175l22 -278l362 -100h4v1l359 99l50 544h-644l-15 181h674zM0 1408h1408l-128 -1438l-578 -162l-574 162z" /> + <glyph glyph-name="css3" unicode="&#xf13c;" horiz-adv-x="1792" +d="M275 1408h1505l-266 -1333l-804 -267l-698 267l71 356h297l-29 -147l422 -161l486 161l68 339h-1208l58 297h1209l38 191h-1208z" /> + <glyph glyph-name="anchor" unicode="&#xf13d;" horiz-adv-x="1792" +d="M960 1280q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1792 352v-352q0 -22 -20 -30q-8 -2 -12 -2q-12 0 -23 9l-93 93q-119 -143 -318.5 -226.5t-429.5 -83.5t-429.5 83.5t-318.5 226.5l-93 -93q-9 -9 -23 -9q-4 0 -12 2q-20 8 -20 30v352 +q0 14 9 23t23 9h352q22 0 30 -20q8 -19 -7 -35l-100 -100q67 -91 189.5 -153.5t271.5 -82.5v647h-192q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h192v163q-58 34 -93 92.5t-35 128.5q0 106 75 181t181 75t181 -75t75 -181q0 -70 -35 -128.5t-93 -92.5v-163h192q26 0 45 -19 +t19 -45v-128q0 -26 -19 -45t-45 -19h-192v-647q149 20 271.5 82.5t189.5 153.5l-100 100q-15 16 -7 35q8 20 30 20h352q14 0 23 -9t9 -23z" /> + <glyph glyph-name="unlock_alt" unicode="&#xf13e;" horiz-adv-x="1152" +d="M1056 768q40 0 68 -28t28 -68v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v576q0 40 28 68t68 28h32v320q0 185 131.5 316.5t316.5 131.5t316.5 -131.5t131.5 -316.5q0 -26 -19 -45t-45 -19h-64q-26 0 -45 19t-19 45q0 106 -75 181t-181 75t-181 -75t-75 -181 +v-320h736z" /> + <glyph glyph-name="bullseye" unicode="&#xf140;" +d="M1024 640q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181zM1152 640q0 159 -112.5 271.5t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5zM1280 640q0 -212 -150 -362t-362 -150t-362 150 +t-150 362t150 362t362 150t362 -150t150 -362zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640 +q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="ellipsis_horizontal" unicode="&#xf141;" horiz-adv-x="1408" +d="M384 800v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM896 800v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM1408 800v-192q0 -40 -28 -68t-68 -28h-192 +q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68z" /> + <glyph glyph-name="ellipsis_vertical" unicode="&#xf142;" horiz-adv-x="384" +d="M384 288v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM384 800v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM384 1312v-192q0 -40 -28 -68t-68 -28h-192 +q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68z" /> + <glyph glyph-name="_303" unicode="&#xf143;" +d="M512 256q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM863 162q-13 233 -176.5 396.5t-396.5 176.5q-14 1 -24 -9t-10 -23v-128q0 -13 8.5 -22t21.5 -10q154 -11 264 -121t121 -264q1 -13 10 -21.5t22 -8.5h128 +q13 0 23 10t9 24zM1247 161q-5 154 -56 297.5t-139.5 260t-205 205t-260 139.5t-297.5 56q-14 1 -23 -9q-10 -10 -10 -23v-128q0 -13 9 -22t22 -10q204 -7 378 -111.5t278.5 -278.5t111.5 -378q1 -13 10 -22t22 -9h128q13 0 23 10q11 9 9 23zM1536 1120v-960 +q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="play_sign" unicode="&#xf144;" +d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM1152 585q32 18 32 55t-32 55l-544 320q-31 19 -64 1q-32 -19 -32 -56v-640q0 -37 32 -56 +q16 -8 32 -8q17 0 32 9z" /> + <glyph glyph-name="ticket" unicode="&#xf145;" horiz-adv-x="1792" +d="M1024 1084l316 -316l-572 -572l-316 316zM813 105l618 618q19 19 19 45t-19 45l-362 362q-18 18 -45 18t-45 -18l-618 -618q-19 -19 -19 -45t19 -45l362 -362q18 -18 45 -18t45 18zM1702 742l-907 -908q-37 -37 -90.5 -37t-90.5 37l-126 126q56 56 56 136t-56 136 +t-136 56t-136 -56l-125 126q-37 37 -37 90.5t37 90.5l907 906q37 37 90.5 37t90.5 -37l125 -125q-56 -56 -56 -136t56 -136t136 -56t136 56l126 -125q37 -37 37 -90.5t-37 -90.5z" /> + <glyph glyph-name="minus_sign_alt" unicode="&#xf146;" +d="M1280 576v128q0 26 -19 45t-45 19h-896q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h896q26 0 45 19t19 45zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5 +t84.5 -203.5z" /> + <glyph glyph-name="check_minus" unicode="&#xf147;" horiz-adv-x="1408" +d="M1152 736v-64q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h832q14 0 23 -9t9 -23zM1280 288v832q0 66 -47 113t-113 47h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113zM1408 1120v-832q0 -119 -84.5 -203.5 +t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="level_up" unicode="&#xf148;" horiz-adv-x="1024" +d="M1018 933q-18 -37 -58 -37h-192v-864q0 -14 -9 -23t-23 -9h-704q-21 0 -29 18q-8 20 4 35l160 192q9 11 25 11h320v640h-192q-40 0 -58 37q-17 37 9 68l320 384q18 22 49 22t49 -22l320 -384q27 -32 9 -68z" /> + <glyph glyph-name="level_down" unicode="&#xf149;" horiz-adv-x="1024" +d="M32 1280h704q13 0 22.5 -9.5t9.5 -23.5v-863h192q40 0 58 -37t-9 -69l-320 -384q-18 -22 -49 -22t-49 22l-320 384q-26 31 -9 69q18 37 58 37h192v640h-320q-14 0 -25 11l-160 192q-13 14 -4 34q9 19 29 19z" /> + <glyph glyph-name="check_sign" unicode="&#xf14a;" +d="M685 237l614 614q19 19 19 45t-19 45l-102 102q-19 19 -45 19t-45 -19l-467 -467l-211 211q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45t19 -45l358 -358q19 -19 45 -19t45 19zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5 +t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="edit_sign" unicode="&#xf14b;" +d="M404 428l152 -152l-52 -52h-56v96h-96v56zM818 818q14 -13 -3 -30l-291 -291q-17 -17 -30 -3q-14 13 3 30l291 291q17 17 30 3zM544 128l544 544l-288 288l-544 -544v-288h288zM1152 736l92 92q28 28 28 68t-28 68l-152 152q-28 28 -68 28t-68 -28l-92 -92zM1536 1120 +v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="_312" unicode="&#xf14c;" +d="M1280 608v480q0 26 -19 45t-45 19h-480q-42 0 -59 -39q-17 -41 14 -70l144 -144l-534 -534q-19 -19 -19 -45t19 -45l102 -102q19 -19 45 -19t45 19l534 534l144 -144q18 -19 45 -19q12 0 25 5q39 17 39 59zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960 +q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="share_sign" unicode="&#xf14d;" +d="M1005 435l352 352q19 19 19 45t-19 45l-352 352q-30 31 -69 14q-40 -17 -40 -59v-160q-119 0 -216 -19.5t-162.5 -51t-114 -79t-76.5 -95.5t-44.5 -109t-21.5 -111.5t-5 -110.5q0 -181 167 -404q11 -12 25 -12q7 0 13 3q22 9 19 33q-44 354 62 473q46 52 130 75.5 +t224 23.5v-160q0 -42 40 -59q12 -5 24 -5q26 0 45 19zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="compass" unicode="&#xf14e;" +d="M640 448l256 128l-256 128v-256zM1024 1039v-542l-512 -256v542zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103 +t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="collapse" unicode="&#xf150;" +d="M1145 861q18 -35 -5 -66l-320 -448q-19 -27 -52 -27t-52 27l-320 448q-23 31 -5 66q17 35 57 35h640q40 0 57 -35zM1280 160v960q0 13 -9.5 22.5t-22.5 9.5h-960q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5zM1536 1120 +v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="collapse_top" unicode="&#xf151;" +d="M1145 419q-17 -35 -57 -35h-640q-40 0 -57 35q-18 35 5 66l320 448q19 27 52 27t52 -27l320 -448q23 -31 5 -66zM1280 160v960q0 13 -9.5 22.5t-22.5 9.5h-960q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5zM1536 1120v-960 +q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="_317" unicode="&#xf152;" +d="M1088 640q0 -33 -27 -52l-448 -320q-31 -23 -66 -5q-35 17 -35 57v640q0 40 35 57q35 18 66 -5l448 -320q27 -19 27 -52zM1280 160v960q0 14 -9 23t-23 9h-960q-14 0 -23 -9t-9 -23v-960q0 -14 9 -23t23 -9h960q14 0 23 9t9 23zM1536 1120v-960q0 -119 -84.5 -203.5 +t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="eur" unicode="&#xf153;" horiz-adv-x="1024" +d="M976 229l35 -159q3 -12 -3 -22.5t-17 -14.5l-5 -1q-4 -2 -10.5 -3.5t-16 -4.5t-21.5 -5.5t-25.5 -5t-30 -5t-33.5 -4.5t-36.5 -3t-38.5 -1q-234 0 -409 130.5t-238 351.5h-95q-13 0 -22.5 9.5t-9.5 22.5v113q0 13 9.5 22.5t22.5 9.5h66q-2 57 1 105h-67q-14 0 -23 9 +t-9 23v114q0 14 9 23t23 9h98q67 210 243.5 338t400.5 128q102 0 194 -23q11 -3 20 -15q6 -11 3 -24l-43 -159q-3 -13 -14 -19.5t-24 -2.5l-4 1q-4 1 -11.5 2.5l-17.5 3.5t-22.5 3.5t-26 3t-29 2.5t-29.5 1q-126 0 -226 -64t-150 -176h468q16 0 25 -12q10 -12 7 -26 +l-24 -114q-5 -26 -32 -26h-488q-3 -37 0 -105h459q15 0 25 -12q9 -12 6 -27l-24 -112q-2 -11 -11 -18.5t-20 -7.5h-387q48 -117 149.5 -185.5t228.5 -68.5q18 0 36 1.5t33.5 3.5t29.5 4.5t24.5 5t18.5 4.5l12 3l5 2q13 5 26 -2q12 -7 15 -21z" /> + <glyph glyph-name="gbp" unicode="&#xf154;" horiz-adv-x="1024" +d="M1020 399v-367q0 -14 -9 -23t-23 -9h-956q-14 0 -23 9t-9 23v150q0 13 9.5 22.5t22.5 9.5h97v383h-95q-14 0 -23 9.5t-9 22.5v131q0 14 9 23t23 9h95v223q0 171 123.5 282t314.5 111q185 0 335 -125q9 -8 10 -20.5t-7 -22.5l-103 -127q-9 -11 -22 -12q-13 -2 -23 7 +q-5 5 -26 19t-69 32t-93 18q-85 0 -137 -47t-52 -123v-215h305q13 0 22.5 -9t9.5 -23v-131q0 -13 -9.5 -22.5t-22.5 -9.5h-305v-379h414v181q0 13 9 22.5t23 9.5h162q14 0 23 -9.5t9 -22.5z" /> + <glyph glyph-name="usd" unicode="&#xf155;" horiz-adv-x="1024" +d="M978 351q0 -153 -99.5 -263.5t-258.5 -136.5v-175q0 -14 -9 -23t-23 -9h-135q-13 0 -22.5 9.5t-9.5 22.5v175q-66 9 -127.5 31t-101.5 44.5t-74 48t-46.5 37.5t-17.5 18q-17 21 -2 41l103 135q7 10 23 12q15 2 24 -9l2 -2q113 -99 243 -125q37 -8 74 -8q81 0 142.5 43 +t61.5 122q0 28 -15 53t-33.5 42t-58.5 37.5t-66 32t-80 32.5q-39 16 -61.5 25t-61.5 26.5t-62.5 31t-56.5 35.5t-53.5 42.5t-43.5 49t-35.5 58t-21 66.5t-8.5 78q0 138 98 242t255 134v180q0 13 9.5 22.5t22.5 9.5h135q14 0 23 -9t9 -23v-176q57 -6 110.5 -23t87 -33.5 +t63.5 -37.5t39 -29t15 -14q17 -18 5 -38l-81 -146q-8 -15 -23 -16q-14 -3 -27 7q-3 3 -14.5 12t-39 26.5t-58.5 32t-74.5 26t-85.5 11.5q-95 0 -155 -43t-60 -111q0 -26 8.5 -48t29.5 -41.5t39.5 -33t56 -31t60.5 -27t70 -27.5q53 -20 81 -31.5t76 -35t75.5 -42.5t62 -50 +t53 -63.5t31.5 -76.5t13 -94z" /> + <glyph glyph-name="inr" unicode="&#xf156;" horiz-adv-x="898" +d="M898 1066v-102q0 -14 -9 -23t-23 -9h-168q-23 -144 -129 -234t-276 -110q167 -178 459 -536q14 -16 4 -34q-8 -18 -29 -18h-195q-16 0 -25 12q-306 367 -498 571q-9 9 -9 22v127q0 13 9.5 22.5t22.5 9.5h112q132 0 212.5 43t102.5 125h-427q-14 0 -23 9t-9 23v102 +q0 14 9 23t23 9h413q-57 113 -268 113h-145q-13 0 -22.5 9.5t-9.5 22.5v133q0 14 9 23t23 9h832q14 0 23 -9t9 -23v-102q0 -14 -9 -23t-23 -9h-233q47 -61 64 -144h171q14 0 23 -9t9 -23z" /> + <glyph glyph-name="jpy" unicode="&#xf157;" horiz-adv-x="1027" +d="M603 0h-172q-13 0 -22.5 9t-9.5 23v330h-288q-13 0 -22.5 9t-9.5 23v103q0 13 9.5 22.5t22.5 9.5h288v85h-288q-13 0 -22.5 9t-9.5 23v104q0 13 9.5 22.5t22.5 9.5h214l-321 578q-8 16 0 32q10 16 28 16h194q19 0 29 -18l215 -425q19 -38 56 -125q10 24 30.5 68t27.5 61 +l191 420q8 19 29 19h191q17 0 27 -16q9 -14 1 -31l-313 -579h215q13 0 22.5 -9.5t9.5 -22.5v-104q0 -14 -9.5 -23t-22.5 -9h-290v-85h290q13 0 22.5 -9.5t9.5 -22.5v-103q0 -14 -9.5 -23t-22.5 -9h-290v-330q0 -13 -9.5 -22.5t-22.5 -9.5z" /> + <glyph glyph-name="rub" unicode="&#xf158;" horiz-adv-x="1280" +d="M1043 971q0 100 -65 162t-171 62h-320v-448h320q106 0 171 62t65 162zM1280 971q0 -193 -126.5 -315t-326.5 -122h-340v-118h505q14 0 23 -9t9 -23v-128q0 -14 -9 -23t-23 -9h-505v-192q0 -14 -9.5 -23t-22.5 -9h-167q-14 0 -23 9t-9 23v192h-224q-14 0 -23 9t-9 23v128 +q0 14 9 23t23 9h224v118h-224q-14 0 -23 9t-9 23v149q0 13 9 22.5t23 9.5h224v629q0 14 9 23t23 9h539q200 0 326.5 -122t126.5 -315z" /> + <glyph glyph-name="krw" unicode="&#xf159;" horiz-adv-x="1792" +d="M514 341l81 299h-159l75 -300q1 -1 1 -3t1 -3q0 1 0.5 3.5t0.5 3.5zM630 768l35 128h-292l32 -128h225zM822 768h139l-35 128h-70zM1271 340l78 300h-162l81 -299q0 -1 0.5 -3.5t1.5 -3.5q0 1 0.5 3t0.5 3zM1382 768l33 128h-297l34 -128h230zM1792 736v-64q0 -14 -9 -23 +t-23 -9h-213l-164 -616q-7 -24 -31 -24h-159q-24 0 -31 24l-166 616h-209l-167 -616q-7 -24 -31 -24h-159q-11 0 -19.5 7t-10.5 17l-160 616h-208q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h175l-33 128h-142q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h109l-89 344q-5 15 5 28 +q10 12 26 12h137q26 0 31 -24l90 -360h359l97 360q7 24 31 24h126q24 0 31 -24l98 -360h365l93 360q5 24 31 24h137q16 0 26 -12q10 -13 5 -28l-91 -344h111q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-145l-34 -128h179q14 0 23 -9t9 -23z" /> + <glyph glyph-name="btc" unicode="&#xf15a;" horiz-adv-x="1280" +d="M1167 896q18 -182 -131 -258q117 -28 175 -103t45 -214q-7 -71 -32.5 -125t-64.5 -89t-97 -58.5t-121.5 -34.5t-145.5 -15v-255h-154v251q-80 0 -122 1v-252h-154v255q-18 0 -54 0.5t-55 0.5h-200l31 183h111q50 0 58 51v402h16q-6 1 -16 1v287q-13 68 -89 68h-111v164 +l212 -1q64 0 97 1v252h154v-247q82 2 122 2v245h154v-252q79 -7 140 -22.5t113 -45t82.5 -78t36.5 -114.5zM952 351q0 36 -15 64t-37 46t-57.5 30.5t-65.5 18.5t-74 9t-69 3t-64.5 -1t-47.5 -1v-338q8 0 37 -0.5t48 -0.5t53 1.5t58.5 4t57 8.5t55.5 14t47.5 21t39.5 30 +t24.5 40t9.5 51zM881 827q0 33 -12.5 58.5t-30.5 42t-48 28t-55 16.5t-61.5 8t-58 2.5t-54 -1t-39.5 -0.5v-307q5 0 34.5 -0.5t46.5 0t50 2t55 5.5t51.5 11t48.5 18.5t37 27t27 38.5t9 51z" /> + <glyph glyph-name="file" unicode="&#xf15b;" +d="M1024 1024v472q22 -14 36 -28l408 -408q14 -14 28 -36h-472zM896 992q0 -40 28 -68t68 -28h544v-1056q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h800v-544z" /> + <glyph glyph-name="file_text" unicode="&#xf15c;" +d="M1468 1060q14 -14 28 -36h-472v472q22 -14 36 -28zM992 896h544v-1056q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h800v-544q0 -40 28 -68t68 -28zM1152 160v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704 +q14 0 23 9t9 23zM1152 416v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704q14 0 23 9t9 23zM1152 672v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704q14 0 23 9t9 23z" /> + <glyph glyph-name="sort_by_alphabet" unicode="&#xf15d;" horiz-adv-x="1664" +d="M1191 1128h177l-72 218l-12 47q-2 16 -2 20h-4l-3 -20q0 -1 -3.5 -18t-7.5 -29zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23zM1572 -23 +v-233h-584v90l369 529q12 18 21 27l11 9v3q-2 0 -6.5 -0.5t-7.5 -0.5q-12 -3 -30 -3h-232v-115h-120v229h567v-89l-369 -530q-6 -8 -21 -26l-11 -11v-2l14 2q9 2 30 2h248v119h121zM1661 874v-106h-288v106h75l-47 144h-243l-47 -144h75v-106h-287v106h70l230 662h162 +l230 -662h70z" /> + <glyph glyph-name="_329" unicode="&#xf15e;" horiz-adv-x="1664" +d="M1191 104h177l-72 218l-12 47q-2 16 -2 20h-4l-3 -20q0 -1 -3.5 -18t-7.5 -29zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23zM1661 -150 +v-106h-288v106h75l-47 144h-243l-47 -144h75v-106h-287v106h70l230 662h162l230 -662h70zM1572 1001v-233h-584v90l369 529q12 18 21 27l11 9v3q-2 0 -6.5 -0.5t-7.5 -0.5q-12 -3 -30 -3h-232v-115h-120v229h567v-89l-369 -530q-6 -8 -21 -26l-11 -10v-3l14 3q9 1 30 1h248 +v119h121z" /> + <glyph glyph-name="sort_by_attributes" unicode="&#xf160;" horiz-adv-x="1792" +d="M736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23zM1792 -32v-192q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h832 +q14 0 23 -9t9 -23zM1600 480v-192q0 -14 -9 -23t-23 -9h-640q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h640q14 0 23 -9t9 -23zM1408 992v-192q0 -14 -9 -23t-23 -9h-448q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h448q14 0 23 -9t9 -23zM1216 1504v-192q0 -14 -9 -23t-23 -9h-256 +q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h256q14 0 23 -9t9 -23z" /> + <glyph glyph-name="sort_by_attributes_alt" unicode="&#xf161;" horiz-adv-x="1792" +d="M1216 -32v-192q0 -14 -9 -23t-23 -9h-256q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h256q14 0 23 -9t9 -23zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192 +q14 0 23 -9t9 -23zM1408 480v-192q0 -14 -9 -23t-23 -9h-448q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h448q14 0 23 -9t9 -23zM1600 992v-192q0 -14 -9 -23t-23 -9h-640q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h640q14 0 23 -9t9 -23zM1792 1504v-192q0 -14 -9 -23t-23 -9h-832 +q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h832q14 0 23 -9t9 -23z" /> + <glyph glyph-name="sort_by_order" unicode="&#xf162;" +d="M1346 223q0 63 -44 116t-103 53q-52 0 -83 -37t-31 -94t36.5 -95t104.5 -38q50 0 85 27t35 68zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23 +zM1486 165q0 -62 -13 -121.5t-41 -114t-68 -95.5t-98.5 -65.5t-127.5 -24.5q-62 0 -108 16q-24 8 -42 15l39 113q15 -7 31 -11q37 -13 75 -13q84 0 134.5 58.5t66.5 145.5h-2q-21 -23 -61.5 -37t-84.5 -14q-106 0 -173 71.5t-67 172.5q0 105 72 178t181 73q123 0 205 -94.5 +t82 -252.5zM1456 882v-114h-469v114h167v432q0 7 0.5 19t0.5 17v16h-2l-7 -12q-8 -13 -26 -31l-62 -58l-82 86l192 185h123v-654h165z" /> + <glyph glyph-name="sort_by_order_alt" unicode="&#xf163;" +d="M1346 1247q0 63 -44 116t-103 53q-52 0 -83 -37t-31 -94t36.5 -95t104.5 -38q50 0 85 27t35 68zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9 +t9 -23zM1456 -142v-114h-469v114h167v432q0 7 0.5 19t0.5 17v16h-2l-7 -12q-8 -13 -26 -31l-62 -58l-82 86l192 185h123v-654h165zM1486 1189q0 -62 -13 -121.5t-41 -114t-68 -95.5t-98.5 -65.5t-127.5 -24.5q-62 0 -108 16q-24 8 -42 15l39 113q15 -7 31 -11q37 -13 75 -13 +q84 0 134.5 58.5t66.5 145.5h-2q-21 -23 -61.5 -37t-84.5 -14q-106 0 -173 71.5t-67 172.5q0 105 72 178t181 73q123 0 205 -94.5t82 -252.5z" /> + <glyph glyph-name="_334" unicode="&#xf164;" horiz-adv-x="1664" +d="M256 192q0 26 -19 45t-45 19q-27 0 -45.5 -19t-18.5 -45q0 -27 18.5 -45.5t45.5 -18.5q26 0 45 18.5t19 45.5zM416 704v-640q0 -26 -19 -45t-45 -19h-288q-26 0 -45 19t-19 45v640q0 26 19 45t45 19h288q26 0 45 -19t19 -45zM1600 704q0 -86 -55 -149q15 -44 15 -76 +q3 -76 -43 -137q17 -56 0 -117q-15 -57 -54 -94q9 -112 -49 -181q-64 -76 -197 -78h-36h-76h-17q-66 0 -144 15.5t-121.5 29t-120.5 39.5q-123 43 -158 44q-26 1 -45 19.5t-19 44.5v641q0 25 18 43.5t43 20.5q24 2 76 59t101 121q68 87 101 120q18 18 31 48t17.5 48.5 +t13.5 60.5q7 39 12.5 61t19.5 52t34 50q19 19 45 19q46 0 82.5 -10.5t60 -26t40 -40.5t24 -45t12 -50t5 -45t0.5 -39q0 -38 -9.5 -76t-19 -60t-27.5 -56q-3 -6 -10 -18t-11 -22t-8 -24h277q78 0 135 -57t57 -135z" /> + <glyph glyph-name="_335" unicode="&#xf165;" horiz-adv-x="1664" +d="M256 960q0 -26 -19 -45t-45 -19q-27 0 -45.5 19t-18.5 45q0 27 18.5 45.5t45.5 18.5q26 0 45 -18.5t19 -45.5zM416 448v640q0 26 -19 45t-45 19h-288q-26 0 -45 -19t-19 -45v-640q0 -26 19 -45t45 -19h288q26 0 45 19t19 45zM1545 597q55 -61 55 -149q-1 -78 -57.5 -135 +t-134.5 -57h-277q4 -14 8 -24t11 -22t10 -18q18 -37 27 -57t19 -58.5t10 -76.5q0 -24 -0.5 -39t-5 -45t-12 -50t-24 -45t-40 -40.5t-60 -26t-82.5 -10.5q-26 0 -45 19q-20 20 -34 50t-19.5 52t-12.5 61q-9 42 -13.5 60.5t-17.5 48.5t-31 48q-33 33 -101 120q-49 64 -101 121 +t-76 59q-25 2 -43 20.5t-18 43.5v641q0 26 19 44.5t45 19.5q35 1 158 44q77 26 120.5 39.5t121.5 29t144 15.5h17h76h36q133 -2 197 -78q58 -69 49 -181q39 -37 54 -94q17 -61 0 -117q46 -61 43 -137q0 -32 -15 -76z" /> + <glyph glyph-name="youtube_sign" unicode="&#xf166;" +d="M919 233v157q0 50 -29 50q-17 0 -33 -16v-224q16 -16 33 -16q29 0 29 49zM1103 355h66v34q0 51 -33 51t-33 -51v-34zM532 621v-70h-80v-423h-74v423h-78v70h232zM733 495v-367h-67v40q-39 -45 -76 -45q-33 0 -42 28q-6 17 -6 54v290h66v-270q0 -24 1 -26q1 -15 15 -15 +q20 0 42 31v280h67zM985 384v-146q0 -52 -7 -73q-12 -42 -53 -42q-35 0 -68 41v-36h-67v493h67v-161q32 40 68 40q41 0 53 -42q7 -21 7 -74zM1236 255v-9q0 -29 -2 -43q-3 -22 -15 -40q-27 -40 -80 -40q-52 0 -81 38q-21 27 -21 86v129q0 59 20 86q29 38 80 38t78 -38 +q21 -29 21 -86v-76h-133v-65q0 -51 34 -51q24 0 30 26q0 1 0.5 7t0.5 16.5v21.5h68zM785 1079v-156q0 -51 -32 -51t-32 51v156q0 52 32 52t32 -52zM1318 366q0 177 -19 260q-10 44 -43 73.5t-76 34.5q-136 15 -412 15q-275 0 -411 -15q-44 -5 -76.5 -34.5t-42.5 -73.5 +q-20 -87 -20 -260q0 -176 20 -260q10 -43 42.5 -73t75.5 -35q137 -15 412 -15t412 15q43 5 75.5 35t42.5 73q20 84 20 260zM563 1017l90 296h-75l-51 -195l-53 195h-78q7 -23 23 -69l24 -69q35 -103 46 -158v-201h74v201zM852 936v130q0 58 -21 87q-29 38 -78 38 +q-51 0 -78 -38q-21 -29 -21 -87v-130q0 -58 21 -87q27 -38 78 -38q49 0 78 38q21 27 21 87zM1033 816h67v370h-67v-283q-22 -31 -42 -31q-15 0 -16 16q-1 2 -1 26v272h-67v-293q0 -37 6 -55q11 -27 43 -27q36 0 77 45v-40zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5 +h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="youtube" unicode="&#xf167;" +d="M971 292v-211q0 -67 -39 -67q-23 0 -45 22v301q22 22 45 22q39 0 39 -67zM1309 291v-46h-90v46q0 68 45 68t45 -68zM343 509h107v94h-312v-94h105v-569h100v569zM631 -60h89v494h-89v-378q-30 -42 -57 -42q-18 0 -21 21q-1 3 -1 35v364h-89v-391q0 -49 8 -73 +q12 -37 58 -37q48 0 102 61v-54zM1060 88v197q0 73 -9 99q-17 56 -71 56q-50 0 -93 -54v217h-89v-663h89v48q45 -55 93 -55q54 0 71 55q9 27 9 100zM1398 98v13h-91q0 -51 -2 -61q-7 -36 -40 -36q-46 0 -46 69v87h179v103q0 79 -27 116q-39 51 -106 51q-68 0 -107 -51 +q-28 -37 -28 -116v-173q0 -79 29 -116q39 -51 108 -51q72 0 108 53q18 27 21 54q2 9 2 58zM790 1011v210q0 69 -43 69t-43 -69v-210q0 -70 43 -70t43 70zM1509 260q0 -234 -26 -350q-14 -59 -58 -99t-102 -46q-184 -21 -555 -21t-555 21q-58 6 -102.5 46t-57.5 99 +q-26 112 -26 350q0 234 26 350q14 59 58 99t103 47q183 20 554 20t555 -20q58 -7 102.5 -47t57.5 -99q26 -112 26 -350zM511 1536h102l-121 -399v-271h-100v271q-14 74 -61 212q-37 103 -65 187h106l71 -263zM881 1203v-175q0 -81 -28 -118q-38 -51 -106 -51q-67 0 -105 51 +q-28 38 -28 118v175q0 80 28 117q38 51 105 51q68 0 106 -51q28 -37 28 -117zM1216 1365v-499h-91v55q-53 -62 -103 -62q-46 0 -59 37q-8 24 -8 75v394h91v-367q0 -33 1 -35q3 -22 21 -22q27 0 57 43v381h91z" /> + <glyph glyph-name="xing" unicode="&#xf168;" horiz-adv-x="1408" +d="M597 869q-10 -18 -257 -456q-27 -46 -65 -46h-239q-21 0 -31 17t0 36l253 448q1 0 0 1l-161 279q-12 22 -1 37q9 15 32 15h239q40 0 66 -45zM1403 1511q11 -16 0 -37l-528 -934v-1l336 -615q11 -20 1 -37q-10 -15 -32 -15h-239q-42 0 -66 45l-339 622q18 32 531 942 +q25 45 64 45h241q22 0 31 -15z" /> + <glyph glyph-name="xing_sign" unicode="&#xf169;" +d="M685 771q0 1 -126 222q-21 34 -52 34h-184q-18 0 -26 -11q-7 -12 1 -29l125 -216v-1l-196 -346q-9 -14 0 -28q8 -13 24 -13h185q31 0 50 36zM1309 1268q-7 12 -24 12h-187q-30 0 -49 -35l-411 -729q1 -2 262 -481q20 -35 52 -35h184q18 0 25 12q8 13 -1 28l-260 476v1 +l409 723q8 16 0 28zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="youtube_play" unicode="&#xf16a;" horiz-adv-x="1792" +d="M711 408l484 250l-484 253v-503zM896 1270q168 0 324.5 -4.5t229.5 -9.5l73 -4q1 0 17 -1.5t23 -3t23.5 -4.5t28.5 -8t28 -13t31 -19.5t29 -26.5q6 -6 15.5 -18.5t29 -58.5t26.5 -101q8 -64 12.5 -136.5t5.5 -113.5v-40v-136q1 -145 -18 -290q-7 -55 -25 -99.5t-32 -61.5 +l-14 -17q-14 -15 -29 -26.5t-31 -19t-28 -12.5t-28.5 -8t-24 -4.5t-23 -3t-16.5 -1.5q-251 -19 -627 -19q-207 2 -359.5 6.5t-200.5 7.5l-49 4l-36 4q-36 5 -54.5 10t-51 21t-56.5 41q-6 6 -15.5 18.5t-29 58.5t-26.5 101q-8 64 -12.5 136.5t-5.5 113.5v40v136 +q-1 145 18 290q7 55 25 99.5t32 61.5l14 17q14 15 29 26.5t31 19.5t28 13t28.5 8t23.5 4.5t23 3t17 1.5q251 18 627 18z" /> + <glyph glyph-name="dropbox" unicode="&#xf16b;" horiz-adv-x="1792" +d="M402 829l494 -305l-342 -285l-490 319zM1388 274v-108l-490 -293v-1l-1 1l-1 -1v1l-489 293v108l147 -96l342 284v2l1 -1l1 1v-2l343 -284zM554 1418l342 -285l-494 -304l-338 270zM1390 829l338 -271l-489 -319l-343 285zM1239 1418l489 -319l-338 -270l-494 304z" /> + <glyph glyph-name="stackexchange" unicode="&#xf16c;" +d="M1289 -96h-1118v480h-160v-640h1438v640h-160v-480zM347 428l33 157l783 -165l-33 -156zM450 802l67 146l725 -339l-67 -145zM651 1158l102 123l614 -513l-102 -123zM1048 1536l477 -641l-128 -96l-477 641zM330 65v159h800v-159h-800z" /> + <glyph glyph-name="instagram" unicode="&#xf16d;" +d="M1024 640q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1162 640q0 -164 -115 -279t-279 -115t-279 115t-115 279t115 279t279 115t279 -115t115 -279zM1270 1050q0 -38 -27 -65t-65 -27t-65 27t-27 65t27 65t65 27t65 -27t27 -65zM768 1270 +q-7 0 -76.5 0.5t-105.5 0t-96.5 -3t-103 -10t-71.5 -18.5q-50 -20 -88 -58t-58 -88q-11 -29 -18.5 -71.5t-10 -103t-3 -96.5t0 -105.5t0.5 -76.5t-0.5 -76.5t0 -105.5t3 -96.5t10 -103t18.5 -71.5q20 -50 58 -88t88 -58q29 -11 71.5 -18.5t103 -10t96.5 -3t105.5 0t76.5 0.5 +t76.5 -0.5t105.5 0t96.5 3t103 10t71.5 18.5q50 20 88 58t58 88q11 29 18.5 71.5t10 103t3 96.5t0 105.5t-0.5 76.5t0.5 76.5t0 105.5t-3 96.5t-10 103t-18.5 71.5q-20 50 -58 88t-88 58q-29 11 -71.5 18.5t-103 10t-96.5 3t-105.5 0t-76.5 -0.5zM1536 640q0 -229 -5 -317 +q-10 -208 -124 -322t-322 -124q-88 -5 -317 -5t-317 5q-208 10 -322 124t-124 322q-5 88 -5 317t5 317q10 208 124 322t322 124q88 5 317 5t317 -5q208 -10 322 -124t124 -322q5 -88 5 -317z" /> + <glyph glyph-name="flickr" unicode="&#xf16e;" +d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960zM698 640q0 88 -62 150t-150 62t-150 -62t-62 -150t62 -150t150 -62t150 62t62 150zM1262 640q0 88 -62 150 +t-150 62t-150 -62t-62 -150t62 -150t150 -62t150 62t62 150z" /> + <glyph glyph-name="adn" unicode="&#xf170;" +d="M768 914l201 -306h-402zM1133 384h94l-459 691l-459 -691h94l104 160h522zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="f171" unicode="&#xf171;" horiz-adv-x="1408" +d="M815 677q8 -63 -50.5 -101t-111.5 -6q-39 17 -53.5 58t-0.5 82t52 58q36 18 72.5 12t64 -35.5t27.5 -67.5zM926 698q-14 107 -113 164t-197 13q-63 -28 -100.5 -88.5t-34.5 -129.5q4 -91 77.5 -155t165.5 -56q91 8 152 84t50 168zM1165 1240q-20 27 -56 44.5t-58 22 +t-71 12.5q-291 47 -566 -2q-43 -7 -66 -12t-55 -22t-50 -43q30 -28 76 -45.5t73.5 -22t87.5 -11.5q228 -29 448 -1q63 8 89.5 12t72.5 21.5t75 46.5zM1222 205q-8 -26 -15.5 -76.5t-14 -84t-28.5 -70t-58 -56.5q-86 -48 -189.5 -71.5t-202 -22t-201.5 18.5q-46 8 -81.5 18 +t-76.5 27t-73 43.5t-52 61.5q-25 96 -57 292l6 16l18 9q223 -148 506.5 -148t507.5 148q21 -6 24 -23t-5 -45t-8 -37zM1403 1166q-26 -167 -111 -655q-5 -30 -27 -56t-43.5 -40t-54.5 -31q-252 -126 -610 -88q-248 27 -394 139q-15 12 -25.5 26.5t-17 35t-9 34t-6 39.5 +t-5.5 35q-9 50 -26.5 150t-28 161.5t-23.5 147.5t-22 158q3 26 17.5 48.5t31.5 37.5t45 30t46 22.5t48 18.5q125 46 313 64q379 37 676 -50q155 -46 215 -122q16 -20 16.5 -51t-5.5 -54z" /> + <glyph glyph-name="bitbucket_sign" unicode="&#xf172;" +d="M848 666q0 43 -41 66t-77 1q-43 -20 -42.5 -72.5t43.5 -70.5q39 -23 81 4t36 72zM928 682q8 -66 -36 -121t-110 -61t-119 40t-56 113q-2 49 25.5 93t72.5 64q70 31 141.5 -10t81.5 -118zM1100 1073q-20 -21 -53.5 -34t-53 -16t-63.5 -8q-155 -20 -324 0q-44 6 -63 9.5 +t-52.5 16t-54.5 32.5q13 19 36 31t40 15.5t47 8.5q198 35 408 1q33 -5 51 -8.5t43 -16t39 -31.5zM1142 327q0 7 5.5 26.5t3 32t-17.5 16.5q-161 -106 -365 -106t-366 106l-12 -6l-5 -12q26 -154 41 -210q47 -81 204 -108q249 -46 428 53q34 19 49 51.5t22.5 85.5t12.5 71z +M1272 1020q9 53 -8 75q-43 55 -155 88q-216 63 -487 36q-132 -12 -226 -46q-38 -15 -59.5 -25t-47 -34t-29.5 -54q8 -68 19 -138t29 -171t24 -137q1 -5 5 -31t7 -36t12 -27t22 -28q105 -80 284 -100q259 -28 440 63q24 13 39.5 23t31 29t19.5 40q48 267 80 473zM1536 1120 +v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="tumblr" unicode="&#xf173;" horiz-adv-x="1024" +d="M944 207l80 -237q-23 -35 -111 -66t-177 -32q-104 -2 -190.5 26t-142.5 74t-95 106t-55.5 120t-16.5 118v544h-168v215q72 26 129 69.5t91 90t58 102t34 99t15 88.5q1 5 4.5 8.5t7.5 3.5h244v-424h333v-252h-334v-518q0 -30 6.5 -56t22.5 -52.5t49.5 -41.5t81.5 -14 +q78 2 134 29z" /> + <glyph glyph-name="tumblr_sign" unicode="&#xf174;" +d="M1136 75l-62 183q-44 -22 -103 -22q-36 -1 -62 10.5t-38.5 31.5t-17.5 40.5t-5 43.5v398h257v194h-256v326h-188q-8 0 -9 -10q-5 -44 -17.5 -87t-39 -95t-77 -95t-118.5 -68v-165h130v-418q0 -57 21.5 -115t65 -111t121 -85.5t176.5 -30.5q69 1 136.5 25t85.5 50z +M1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="long_arrow_down" unicode="&#xf175;" horiz-adv-x="768" +d="M765 237q8 -19 -5 -35l-350 -384q-10 -10 -23 -10q-14 0 -24 10l-355 384q-13 16 -5 35q9 19 29 19h224v1248q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1248h224q21 0 29 -19z" /> + <glyph glyph-name="long_arrow_up" unicode="&#xf176;" horiz-adv-x="768" +d="M765 1043q-9 -19 -29 -19h-224v-1248q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v1248h-224q-21 0 -29 19t5 35l350 384q10 10 23 10q14 0 24 -10l355 -384q13 -16 5 -35z" /> + <glyph glyph-name="long_arrow_left" unicode="&#xf177;" horiz-adv-x="1792" +d="M1792 736v-192q0 -14 -9 -23t-23 -9h-1248v-224q0 -21 -19 -29t-35 5l-384 350q-10 10 -10 23q0 14 10 24l384 354q16 14 35 6q19 -9 19 -29v-224h1248q14 0 23 -9t9 -23z" /> + <glyph glyph-name="long_arrow_right" unicode="&#xf178;" horiz-adv-x="1792" +d="M1728 643q0 -14 -10 -24l-384 -354q-16 -14 -35 -6q-19 9 -19 29v224h-1248q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h1248v224q0 21 19 29t35 -5l384 -350q10 -10 10 -23z" /> + <glyph glyph-name="apple" unicode="&#xf179;" horiz-adv-x="1408" +d="M1393 321q-39 -125 -123 -250q-129 -196 -257 -196q-49 0 -140 32q-86 32 -151 32q-61 0 -142 -33q-81 -34 -132 -34q-152 0 -301 259q-147 261 -147 503q0 228 113 374q113 144 284 144q72 0 177 -30q104 -30 138 -30q45 0 143 34q102 34 173 34q119 0 213 -65 +q52 -36 104 -100q-79 -67 -114 -118q-65 -94 -65 -207q0 -124 69 -223t158 -126zM1017 1494q0 -61 -29 -136q-30 -75 -93 -138q-54 -54 -108 -72q-37 -11 -104 -17q3 149 78 257q74 107 250 148q1 -3 2.5 -11t2.5 -11q0 -4 0.5 -10t0.5 -10z" /> + <glyph glyph-name="windows" unicode="&#xf17a;" horiz-adv-x="1664" +d="M682 530v-651l-682 94v557h682zM682 1273v-659h-682v565zM1664 530v-786l-907 125v661h907zM1664 1408v-794h-907v669z" /> + <glyph glyph-name="android" unicode="&#xf17b;" horiz-adv-x="1408" +d="M493 1053q16 0 27.5 11.5t11.5 27.5t-11.5 27.5t-27.5 11.5t-27 -11.5t-11 -27.5t11 -27.5t27 -11.5zM915 1053q16 0 27 11.5t11 27.5t-11 27.5t-27 11.5t-27.5 -11.5t-11.5 -27.5t11.5 -27.5t27.5 -11.5zM103 869q42 0 72 -30t30 -72v-430q0 -43 -29.5 -73t-72.5 -30 +t-73 30t-30 73v430q0 42 30 72t73 30zM1163 850v-666q0 -46 -32 -78t-77 -32h-75v-227q0 -43 -30 -73t-73 -30t-73 30t-30 73v227h-138v-227q0 -43 -30 -73t-73 -30q-42 0 -72 30t-30 73l-1 227h-74q-46 0 -78 32t-32 78v666h918zM931 1255q107 -55 171 -153.5t64 -215.5 +h-925q0 117 64 215.5t172 153.5l-71 131q-7 13 5 20q13 6 20 -6l72 -132q95 42 201 42t201 -42l72 132q7 12 20 6q12 -7 5 -20zM1408 767v-430q0 -43 -30 -73t-73 -30q-42 0 -72 30t-30 73v430q0 43 30 72.5t72 29.5q43 0 73 -29.5t30 -72.5z" /> + <glyph glyph-name="linux" unicode="&#xf17c;" +d="M663 1125q-11 -1 -15.5 -10.5t-8.5 -9.5q-5 -1 -5 5q0 12 19 15h10zM750 1111q-4 -1 -11.5 6.5t-17.5 4.5q24 11 32 -2q3 -6 -3 -9zM399 684q-4 1 -6 -3t-4.5 -12.5t-5.5 -13.5t-10 -13q-10 -11 -1 -12q4 -1 12.5 7t12.5 18q1 3 2 7t2 6t1.5 4.5t0.5 4v3t-1 2.5t-3 2z +M1254 325q0 18 -55 42q4 15 7.5 27.5t5 26t3 21.5t0.5 22.5t-1 19.5t-3.5 22t-4 20.5t-5 25t-5.5 26.5q-10 48 -47 103t-72 75q24 -20 57 -83q87 -162 54 -278q-11 -40 -50 -42q-31 -4 -38.5 18.5t-8 83.5t-11.5 107q-9 39 -19.5 69t-19.5 45.5t-15.5 24.5t-13 15t-7.5 7 +q-14 62 -31 103t-29.5 56t-23.5 33t-15 40q-4 21 6 53.5t4.5 49.5t-44.5 25q-15 3 -44.5 18t-35.5 16q-8 1 -11 26t8 51t36 27q37 3 51 -30t4 -58q-11 -19 -2 -26.5t30 -0.5q13 4 13 36v37q-5 30 -13.5 50t-21 30.5t-23.5 15t-27 7.5q-107 -8 -89 -134q0 -15 -1 -15 +q-9 9 -29.5 10.5t-33 -0.5t-15.5 5q1 57 -16 90t-45 34q-27 1 -41.5 -27.5t-16.5 -59.5q-1 -15 3.5 -37t13 -37.5t15.5 -13.5q10 3 16 14q4 9 -7 8q-7 0 -15.5 14.5t-9.5 33.5q-1 22 9 37t34 14q17 0 27 -21t9.5 -39t-1.5 -22q-22 -15 -31 -29q-8 -12 -27.5 -23.5 +t-20.5 -12.5q-13 -14 -15.5 -27t7.5 -18q14 -8 25 -19.5t16 -19t18.5 -13t35.5 -6.5q47 -2 102 15q2 1 23 7t34.5 10.5t29.5 13t21 17.5q9 14 20 8q5 -3 6.5 -8.5t-3 -12t-16.5 -9.5q-20 -6 -56.5 -21.5t-45.5 -19.5q-44 -19 -70 -23q-25 -5 -79 2q-10 2 -9 -2t17 -19 +q25 -23 67 -22q17 1 36 7t36 14t33.5 17.5t30 17t24.5 12t17.5 2.5t8.5 -11q0 -2 -1 -4.5t-4 -5t-6 -4.5t-8.5 -5t-9 -4.5t-10 -5t-9.5 -4.5q-28 -14 -67.5 -44t-66.5 -43t-49 -1q-21 11 -63 73q-22 31 -25 22q-1 -3 -1 -10q0 -25 -15 -56.5t-29.5 -55.5t-21 -58t11.5 -63 +q-23 -6 -62.5 -90t-47.5 -141q-2 -18 -1.5 -69t-5.5 -59q-8 -24 -29 -3q-32 31 -36 94q-2 28 4 56q4 19 -1 18q-2 -1 -4 -5q-36 -65 10 -166q5 -12 25 -28t24 -20q20 -23 104 -90.5t93 -76.5q16 -15 17.5 -38t-14 -43t-45.5 -23q8 -15 29 -44.5t28 -54t7 -70.5q46 24 7 92 +q-4 8 -10.5 16t-9.5 12t-2 6q3 5 13 9.5t20 -2.5q46 -52 166 -36q133 15 177 87q23 38 34 30q12 -6 10 -52q-1 -25 -23 -92q-9 -23 -6 -37.5t24 -15.5q3 19 14.5 77t13.5 90q2 21 -6.5 73.5t-7.5 97t23 70.5q15 18 51 18q1 37 34.5 53t72.5 10.5t60 -22.5zM626 1152 +q3 17 -2.5 30t-11.5 15q-9 2 -9 -7q2 -5 5 -6q10 0 7 -15q-3 -20 8 -20q3 0 3 3zM1045 955q-2 8 -6.5 11.5t-13 5t-14.5 5.5q-5 3 -9.5 8t-7 8t-5.5 6.5t-4 4t-4 -1.5q-14 -16 7 -43.5t39 -31.5q9 -1 14.5 8t3.5 20zM867 1168q0 11 -5 19.5t-11 12.5t-9 3q-6 0 -8 -2t0 -4 +t5 -3q14 -4 18 -31q0 -3 8 2q2 2 2 3zM921 1401q0 2 -2.5 5t-9 7t-9.5 6q-15 15 -24 15q-9 -1 -11.5 -7.5t-1 -13t-0.5 -12.5q-1 -4 -6 -10.5t-6 -9t3 -8.5q4 -3 8 0t11 9t15 9q1 1 9 1t15 2t9 7zM1486 60q20 -12 31 -24.5t12 -24t-2.5 -22.5t-15.5 -22t-23.5 -19.5 +t-30 -18.5t-31.5 -16.5t-32 -15.5t-27 -13q-38 -19 -85.5 -56t-75.5 -64q-17 -16 -68 -19.5t-89 14.5q-18 9 -29.5 23.5t-16.5 25.5t-22 19.5t-47 9.5q-44 1 -130 1q-19 0 -57 -1.5t-58 -2.5q-44 -1 -79.5 -15t-53.5 -30t-43.5 -28.5t-53.5 -11.5q-29 1 -111 31t-146 43 +q-19 4 -51 9.5t-50 9t-39.5 9.5t-33.5 14.5t-17 19.5q-10 23 7 66.5t18 54.5q1 16 -4 40t-10 42.5t-4.5 36.5t10.5 27q14 12 57 14t60 12q30 18 42 35t12 51q21 -73 -32 -106q-32 -20 -83 -15q-34 3 -43 -10q-13 -15 5 -57q2 -6 8 -18t8.5 -18t4.5 -17t1 -22q0 -15 -17 -49 +t-14 -48q3 -17 37 -26q20 -6 84.5 -18.5t99.5 -20.5q24 -6 74 -22t82.5 -23t55.5 -4q43 6 64.5 28t23 48t-7.5 58.5t-19 52t-20 36.5q-121 190 -169 242q-68 74 -113 40q-11 -9 -15 15q-3 16 -2 38q1 29 10 52t24 47t22 42q8 21 26.5 72t29.5 78t30 61t39 54 +q110 143 124 195q-12 112 -16 310q-2 90 24 151.5t106 104.5q39 21 104 21q53 1 106 -13.5t89 -41.5q57 -42 91.5 -121.5t29.5 -147.5q-5 -95 30 -214q34 -113 133 -218q55 -59 99.5 -163t59.5 -191q8 -49 5 -84.5t-12 -55.5t-20 -22q-10 -2 -23.5 -19t-27 -35.5 +t-40.5 -33.5t-61 -14q-18 1 -31.5 5t-22.5 13.5t-13.5 15.5t-11.5 20.5t-9 19.5q-22 37 -41 30t-28 -49t7 -97q20 -70 1 -195q-10 -65 18 -100.5t73 -33t85 35.5q59 49 89.5 66.5t103.5 42.5q53 18 77 36.5t18.5 34.5t-25 28.5t-51.5 23.5q-33 11 -49.5 48t-15 72.5 +t15.5 47.5q1 -31 8 -56.5t14.5 -40.5t20.5 -28.5t21 -19t21.5 -13t16.5 -9.5z" /> + <glyph glyph-name="dribble" unicode="&#xf17d;" +d="M1024 36q-42 241 -140 498h-2l-2 -1q-16 -6 -43 -16.5t-101 -49t-137 -82t-131 -114.5t-103 -148l-15 11q184 -150 418 -150q132 0 256 52zM839 643q-21 49 -53 111q-311 -93 -673 -93q-1 -7 -1 -21q0 -124 44 -236.5t124 -201.5q50 89 123.5 166.5t142.5 124.5t130.5 81 +t99.5 48l37 13q4 1 13 3.5t13 4.5zM732 855q-120 213 -244 378q-138 -65 -234 -186t-128 -272q302 0 606 80zM1416 536q-210 60 -409 29q87 -239 128 -469q111 75 185 189.5t96 250.5zM611 1277q-1 0 -2 -1q1 1 2 1zM1201 1132q-185 164 -433 164q-76 0 -155 -19 +q131 -170 246 -382q69 26 130 60.5t96.5 61.5t65.5 57t37.5 40.5zM1424 647q-3 232 -149 410l-1 -1q-9 -12 -19 -24.5t-43.5 -44.5t-71 -60.5t-100 -65t-131.5 -64.5q25 -53 44 -95q2 -5 6.5 -17t7.5 -17q36 5 74.5 7t73.5 2t69 -1.5t64 -4t56.5 -5.5t48 -6.5t36.5 -6 +t25 -4.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="skype" unicode="&#xf17e;" +d="M1173 473q0 50 -19.5 91.5t-48.5 68.5t-73 49t-82.5 34t-87.5 23l-104 24q-30 7 -44 10.5t-35 11.5t-30 16t-16.5 21t-7.5 30q0 77 144 77q43 0 77 -12t54 -28.5t38 -33.5t40 -29t48 -12q47 0 75.5 32t28.5 77q0 55 -56 99.5t-142 67.5t-182 23q-68 0 -132 -15.5 +t-119.5 -47t-89 -87t-33.5 -128.5q0 -61 19 -106.5t56 -75.5t80 -48.5t103 -32.5l146 -36q90 -22 112 -36q32 -20 32 -60q0 -39 -40 -64.5t-105 -25.5q-51 0 -91.5 16t-65 38.5t-45.5 45t-46 38.5t-54 16q-50 0 -75.5 -30t-25.5 -75q0 -92 122 -157.5t291 -65.5 +q73 0 140 18.5t122.5 53.5t88.5 93.5t33 131.5zM1536 256q0 -159 -112.5 -271.5t-271.5 -112.5q-130 0 -234 80q-77 -16 -150 -16q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5q0 73 16 150q-80 104 -80 234q0 159 112.5 271.5t271.5 112.5q130 0 234 -80 +q77 16 150 16q143 0 273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -73 -16 -150q80 -104 80 -234z" /> + <glyph glyph-name="foursquare" unicode="&#xf180;" horiz-adv-x="1280" +d="M1000 1102l37 194q5 23 -9 40t-35 17h-712q-23 0 -38.5 -17t-15.5 -37v-1101q0 -7 6 -1l291 352q23 26 38 33.5t48 7.5h239q22 0 37 14.5t18 29.5q24 130 37 191q4 21 -11.5 40t-36.5 19h-294q-29 0 -48 19t-19 48v42q0 29 19 47.5t48 18.5h346q18 0 35 13.5t20 29.5z +M1227 1324q-15 -73 -53.5 -266.5t-69.5 -350t-35 -173.5q-6 -22 -9 -32.5t-14 -32.5t-24.5 -33t-38.5 -21t-58 -10h-271q-13 0 -22 -10q-8 -9 -426 -494q-22 -25 -58.5 -28.5t-48.5 5.5q-55 22 -55 98v1410q0 55 38 102.5t120 47.5h888q95 0 127 -53t10 -159zM1227 1324 +l-158 -790q4 17 35 173.5t69.5 350t53.5 266.5z" /> + <glyph glyph-name="trello" unicode="&#xf181;" +d="M704 192v1024q0 14 -9 23t-23 9h-480q-14 0 -23 -9t-9 -23v-1024q0 -14 9 -23t23 -9h480q14 0 23 9t9 23zM1376 576v640q0 14 -9 23t-23 9h-480q-14 0 -23 -9t-9 -23v-640q0 -14 9 -23t23 -9h480q14 0 23 9t9 23zM1536 1344v-1408q0 -26 -19 -45t-45 -19h-1408 +q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h1408q26 0 45 -19t19 -45z" /> + <glyph glyph-name="female" unicode="&#xf182;" horiz-adv-x="1280" +d="M1280 480q0 -40 -28 -68t-68 -28q-51 0 -80 43l-227 341h-45v-132l247 -411q9 -15 9 -33q0 -26 -19 -45t-45 -19h-192v-272q0 -46 -33 -79t-79 -33h-160q-46 0 -79 33t-33 79v272h-192q-26 0 -45 19t-19 45q0 18 9 33l247 411v132h-45l-227 -341q-29 -43 -80 -43 +q-40 0 -68 28t-28 68q0 29 16 53l256 384q73 107 176 107h384q103 0 176 -107l256 -384q16 -24 16 -53zM864 1280q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5z" /> + <glyph glyph-name="male" unicode="&#xf183;" horiz-adv-x="1024" +d="M1024 832v-416q0 -40 -28 -68t-68 -28t-68 28t-28 68v352h-64v-912q0 -46 -33 -79t-79 -33t-79 33t-33 79v464h-64v-464q0 -46 -33 -79t-79 -33t-79 33t-33 79v912h-64v-352q0 -40 -28 -68t-68 -28t-68 28t-28 68v416q0 80 56 136t136 56h640q80 0 136 -56t56 -136z +M736 1280q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5z" /> + <glyph glyph-name="gittip" unicode="&#xf184;" +d="M773 234l350 473q16 22 24.5 59t-6 85t-61.5 79q-40 26 -83 25.5t-73.5 -17.5t-54.5 -45q-36 -40 -96 -40q-59 0 -95 40q-24 28 -54.5 45t-73.5 17.5t-84 -25.5q-46 -31 -60.5 -79t-6 -85t24.5 -59zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103 +t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="sun" unicode="&#xf185;" horiz-adv-x="1792" +d="M1472 640q0 117 -45.5 223.5t-123 184t-184 123t-223.5 45.5t-223.5 -45.5t-184 -123t-123 -184t-45.5 -223.5t45.5 -223.5t123 -184t184 -123t223.5 -45.5t223.5 45.5t184 123t123 184t45.5 223.5zM1748 363q-4 -15 -20 -20l-292 -96v-306q0 -16 -13 -26q-15 -10 -29 -4 +l-292 94l-180 -248q-10 -13 -26 -13t-26 13l-180 248l-292 -94q-14 -6 -29 4q-13 10 -13 26v306l-292 96q-16 5 -20 20q-5 17 4 29l180 248l-180 248q-9 13 -4 29q4 15 20 20l292 96v306q0 16 13 26q15 10 29 4l292 -94l180 248q9 12 26 12t26 -12l180 -248l292 94 +q14 6 29 -4q13 -10 13 -26v-306l292 -96q16 -5 20 -20q5 -16 -4 -29l-180 -248l180 -248q9 -12 4 -29z" /> + <glyph glyph-name="_366" unicode="&#xf186;" +d="M1262 233q-54 -9 -110 -9q-182 0 -337 90t-245 245t-90 337q0 192 104 357q-201 -60 -328.5 -229t-127.5 -384q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51q144 0 273.5 61.5t220.5 171.5zM1465 318q-94 -203 -283.5 -324.5t-413.5 -121.5q-156 0 -298 61 +t-245 164t-164 245t-61 298q0 153 57.5 292.5t156 241.5t235.5 164.5t290 68.5q44 2 61 -39q18 -41 -15 -72q-86 -78 -131.5 -181.5t-45.5 -218.5q0 -148 73 -273t198 -198t273 -73q118 0 228 51q41 18 72 -13q14 -14 17.5 -34t-4.5 -38z" /> + <glyph glyph-name="archive" unicode="&#xf187;" horiz-adv-x="1792" +d="M1088 704q0 26 -19 45t-45 19h-256q-26 0 -45 -19t-19 -45t19 -45t45 -19h256q26 0 45 19t19 45zM1664 896v-960q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v960q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1728 1344v-256q0 -26 -19 -45t-45 -19h-1536 +q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1536q26 0 45 -19t19 -45z" /> + <glyph glyph-name="bug" unicode="&#xf188;" horiz-adv-x="1664" +d="M1632 576q0 -26 -19 -45t-45 -19h-224q0 -171 -67 -290l208 -209q19 -19 19 -45t-19 -45q-18 -19 -45 -19t-45 19l-198 197q-5 -5 -15 -13t-42 -28.5t-65 -36.5t-82 -29t-97 -13v896h-128v-896q-51 0 -101.5 13.5t-87 33t-66 39t-43.5 32.5l-15 14l-183 -207 +q-20 -21 -48 -21q-24 0 -43 16q-19 18 -20.5 44.5t15.5 46.5l202 227q-58 114 -58 274h-224q-26 0 -45 19t-19 45t19 45t45 19h224v294l-173 173q-19 19 -19 45t19 45t45 19t45 -19l173 -173h844l173 173q19 19 45 19t45 -19t19 -45t-19 -45l-173 -173v-294h224q26 0 45 -19 +t19 -45zM1152 1152h-640q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5z" /> + <glyph glyph-name="vk" unicode="&#xf189;" horiz-adv-x="1920" +d="M1917 1016q23 -64 -150 -294q-24 -32 -65 -85q-40 -51 -55 -72t-30.5 -49.5t-12 -42t13 -34.5t32.5 -43t57 -53q4 -2 5 -4q141 -131 191 -221q3 -5 6.5 -12.5t7 -26.5t-0.5 -34t-25 -27.5t-59 -12.5l-256 -4q-24 -5 -56 5t-52 22l-20 12q-30 21 -70 64t-68.5 77.5t-61 58 +t-56.5 15.5q-3 -1 -8 -3.5t-17 -14.5t-21.5 -29.5t-17 -52t-6.5 -77.5q0 -15 -3.5 -27.5t-7.5 -18.5l-4 -5q-18 -19 -53 -22h-115q-71 -4 -146 16.5t-131.5 53t-103 66t-70.5 57.5l-25 24q-10 10 -27.5 30t-71.5 91t-106 151t-122.5 211t-130.5 272q-6 16 -6 27t3 16l4 6 +q15 19 57 19l274 2q12 -2 23 -6.5t16 -8.5l5 -3q16 -11 24 -32q20 -50 46 -103.5t41 -81.5l16 -29q29 -60 56 -104t48.5 -68.5t41.5 -38.5t34 -14t27 5q2 1 5 5t12 22t13.5 47t9.5 81t0 125q-2 40 -9 73t-14 46l-6 12q-25 34 -85 43q-13 2 5 24q16 19 38 30q53 26 239 24 +q82 -1 135 -13q20 -5 33.5 -13.5t20.5 -24t10.5 -32t3.5 -45.5t-1 -55t-2.5 -70.5t-1.5 -82.5q0 -11 -1 -42t-0.5 -48t3.5 -40.5t11.5 -39t22.5 -24.5q8 -2 17 -4t26 11t38 34.5t52 67t68 107.5q60 104 107 225q4 10 10 17.5t11 10.5l4 3l5 2.5t13 3t20 0.5l288 2 +q39 5 64 -2.5t31 -16.5z" /> + <glyph glyph-name="weibo" unicode="&#xf18a;" horiz-adv-x="1792" +d="M675 252q21 34 11 69t-45 50q-34 14 -73 1t-60 -46q-22 -34 -13 -68.5t43 -50.5t74.5 -2.5t62.5 47.5zM769 373q8 13 3.5 26.5t-17.5 18.5q-14 5 -28.5 -0.5t-21.5 -18.5q-17 -31 13 -45q14 -5 29 0.5t22 18.5zM943 266q-45 -102 -158 -150t-224 -12 +q-107 34 -147.5 126.5t6.5 187.5q47 93 151.5 139t210.5 19q111 -29 158.5 -119.5t2.5 -190.5zM1255 426q-9 96 -89 170t-208.5 109t-274.5 21q-223 -23 -369.5 -141.5t-132.5 -264.5q9 -96 89 -170t208.5 -109t274.5 -21q223 23 369.5 141.5t132.5 264.5zM1563 422 +q0 -68 -37 -139.5t-109 -137t-168.5 -117.5t-226 -83t-270.5 -31t-275 33.5t-240.5 93t-171.5 151t-65 199.5q0 115 69.5 245t197.5 258q169 169 341.5 236t246.5 -7q65 -64 20 -209q-4 -14 -1 -20t10 -7t14.5 0.5t13.5 3.5l6 2q139 59 246 59t153 -61q45 -63 0 -178 +q-2 -13 -4.5 -20t4.5 -12.5t12 -7.5t17 -6q57 -18 103 -47t80 -81.5t34 -116.5zM1489 1046q42 -47 54.5 -108.5t-6.5 -117.5q-8 -23 -29.5 -34t-44.5 -4q-23 8 -34 29.5t-4 44.5q20 63 -24 111t-107 35q-24 -5 -45 8t-25 37q-5 24 8 44.5t37 25.5q60 13 119 -5.5t101 -65.5z +M1670 1209q87 -96 112.5 -222.5t-13.5 -241.5q-9 -27 -34 -40t-52 -4t-40 34t-5 52q28 82 10 172t-80 158q-62 69 -148 95.5t-173 8.5q-28 -6 -52 9.5t-30 43.5t9.5 51.5t43.5 29.5q123 26 244 -11.5t208 -134.5z" /> + <glyph glyph-name="renren" unicode="&#xf18b;" +d="M1133 -34q-171 -94 -368 -94q-196 0 -367 94q138 87 235.5 211t131.5 268q35 -144 132.5 -268t235.5 -211zM638 1394v-485q0 -252 -126.5 -459.5t-330.5 -306.5q-181 215 -181 495q0 187 83.5 349.5t229.5 269.5t325 137zM1536 638q0 -280 -181 -495 +q-204 99 -330.5 306.5t-126.5 459.5v485q179 -30 325 -137t229.5 -269.5t83.5 -349.5z" /> + <glyph glyph-name="_372" unicode="&#xf18c;" horiz-adv-x="1408" +d="M1402 433q-32 -80 -76 -138t-91 -88.5t-99 -46.5t-101.5 -14.5t-96.5 8.5t-86.5 22t-69.5 27.5t-46 22.5l-17 10q-113 -228 -289.5 -359.5t-384.5 -132.5q-19 0 -32 13t-13 32t13 31.5t32 12.5q173 1 322.5 107.5t251.5 294.5q-36 -14 -72 -23t-83 -13t-91 2.5t-93 28.5 +t-92 59t-84.5 100t-74.5 146q114 47 214 57t167.5 -7.5t124.5 -56.5t88.5 -77t56.5 -82q53 131 79 291q-7 -1 -18 -2.5t-46.5 -2.5t-69.5 0.5t-81.5 10t-88.5 23t-84 42.5t-75 65t-54.5 94.5t-28.5 127.5q70 28 133.5 36.5t112.5 -1t92 -30t73.5 -50t56 -61t42 -63t27.5 -56 +t16 -39.5l4 -16q12 122 12 195q-8 6 -21.5 16t-49 44.5t-63.5 71.5t-54 93t-33 112.5t12 127t70 138.5q73 -25 127.5 -61.5t84.5 -76.5t48 -85t20.5 -89t-0.5 -85.5t-13 -76.5t-19 -62t-17 -42l-7 -15q1 -4 1 -50t-1 -72q3 7 10 18.5t30.5 43t50.5 58t71 55.5t91.5 44.5 +t112 14.5t132.5 -24q-2 -78 -21.5 -141.5t-50 -104.5t-69.5 -71.5t-81.5 -45.5t-84.5 -24t-80 -9.5t-67.5 1t-46.5 4.5l-17 3q-23 -147 -73 -283q6 7 18 18.5t49.5 41t77.5 52.5t99.5 42t117.5 20t129 -23.5t137 -77.5z" /> + <glyph glyph-name="stack_exchange" unicode="&#xf18d;" horiz-adv-x="1280" +d="M1259 283v-66q0 -85 -57.5 -144.5t-138.5 -59.5h-57l-260 -269v269h-529q-81 0 -138.5 59.5t-57.5 144.5v66h1238zM1259 609v-255h-1238v255h1238zM1259 937v-255h-1238v255h1238zM1259 1077v-67h-1238v67q0 84 57.5 143.5t138.5 59.5h846q81 0 138.5 -59.5t57.5 -143.5z +" /> + <glyph glyph-name="_374" unicode="&#xf18e;" +d="M1152 640q0 -14 -9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v192h-352q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h352v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198 +t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="arrow_circle_alt_left" unicode="&#xf190;" +d="M1152 736v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-352v-192q0 -14 -9 -23t-23 -9q-12 0 -24 10l-319 319q-9 9 -9 23t9 23l320 320q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5v-192h352q13 0 22.5 -9.5t9.5 -22.5zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198 +t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="_376" unicode="&#xf191;" +d="M1024 960v-640q0 -26 -19 -45t-45 -19q-20 0 -37 12l-448 320q-27 19 -27 52t27 52l448 320q17 12 37 12q26 0 45 -19t19 -45zM1280 160v960q0 13 -9.5 22.5t-22.5 9.5h-960q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5z +M1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="dot_circle_alt" unicode="&#xf192;" +d="M1024 640q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5 +t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="_378" unicode="&#xf193;" horiz-adv-x="1664" +d="M1023 349l102 -204q-58 -179 -210 -290t-339 -111q-156 0 -288.5 77.5t-210 210t-77.5 288.5q0 181 104.5 330t274.5 211l17 -131q-122 -54 -195 -165.5t-73 -244.5q0 -185 131.5 -316.5t316.5 -131.5q126 0 232.5 65t165 175.5t49.5 236.5zM1571 249l58 -114l-256 -128 +q-13 -7 -29 -7q-40 0 -57 35l-239 477h-472q-24 0 -42.5 16.5t-21.5 40.5l-96 779q-2 17 6 42q14 51 57 82.5t97 31.5q66 0 113 -47t47 -113q0 -69 -52 -117.5t-120 -41.5l37 -289h423v-128h-407l16 -128h455q40 0 57 -35l228 -455z" /> + <glyph glyph-name="vimeo_square" unicode="&#xf194;" +d="M1292 898q10 216 -161 222q-231 8 -312 -261q44 19 82 19q85 0 74 -96q-4 -57 -74 -167t-105 -110q-43 0 -82 169q-13 54 -45 255q-30 189 -160 177q-59 -7 -164 -100l-81 -72l-81 -72l52 -67q76 52 87 52q57 0 107 -179q15 -55 45 -164.5t45 -164.5q68 -179 164 -179 +q157 0 383 294q220 283 226 444zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="_380" unicode="&#xf195;" horiz-adv-x="1152" +d="M1152 704q0 -191 -94.5 -353t-256.5 -256.5t-353 -94.5h-160q-14 0 -23 9t-9 23v611l-215 -66q-3 -1 -9 -1q-10 0 -19 6q-13 10 -13 26v128q0 23 23 31l233 71v93l-215 -66q-3 -1 -9 -1q-10 0 -19 6q-13 10 -13 26v128q0 23 23 31l233 71v250q0 14 9 23t23 9h160 +q14 0 23 -9t9 -23v-181l375 116q15 5 28 -5t13 -26v-128q0 -23 -23 -31l-393 -121v-93l375 116q15 5 28 -5t13 -26v-128q0 -23 -23 -31l-393 -121v-487q188 13 318 151t130 328q0 14 9 23t23 9h160q14 0 23 -9t9 -23z" /> + <glyph glyph-name="plus_square_o" unicode="&#xf196;" horiz-adv-x="1408" +d="M1152 736v-64q0 -14 -9 -23t-23 -9h-352v-352q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v352h-352q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h352v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-352h352q14 0 23 -9t9 -23zM1280 288v832q0 66 -47 113t-113 47h-832 +q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113zM1408 1120v-832q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="_382" unicode="&#xf197;" horiz-adv-x="2176" +d="M620 416q-110 -64 -268 -64h-128v64h-64q-13 0 -22.5 23.5t-9.5 56.5q0 24 7 49q-58 2 -96.5 10.5t-38.5 20.5t38.5 20.5t96.5 10.5q-7 25 -7 49q0 33 9.5 56.5t22.5 23.5h64v64h128q158 0 268 -64h1113q42 -7 106.5 -18t80.5 -14q89 -15 150 -40.5t83.5 -47.5t22.5 -40 +t-22.5 -40t-83.5 -47.5t-150 -40.5q-16 -3 -80.5 -14t-106.5 -18h-1113zM1739 668q53 -36 53 -92t-53 -92l81 -30q68 48 68 122t-68 122zM625 400h1015q-217 -38 -456 -80q-57 0 -113 -24t-83 -48l-28 -24l-288 -288q-26 -26 -70.5 -45t-89.5 -19h-96l-93 464h29 +q157 0 273 64zM352 816h-29l93 464h96q46 0 90 -19t70 -45l288 -288q4 -4 11 -10.5t30.5 -23t48.5 -29t61.5 -23t72.5 -10.5l456 -80h-1015q-116 64 -273 64z" /> + <glyph glyph-name="_383" unicode="&#xf198;" horiz-adv-x="1664" +d="M1519 760q62 0 103.5 -40.5t41.5 -101.5q0 -97 -93 -130l-172 -59l56 -167q7 -21 7 -47q0 -59 -42 -102t-101 -43q-47 0 -85.5 27t-53.5 72l-55 165l-310 -106l55 -164q8 -24 8 -47q0 -59 -42 -102t-102 -43q-47 0 -85 27t-53 72l-55 163l-153 -53q-29 -9 -50 -9 +q-61 0 -101.5 40t-40.5 101q0 47 27.5 85t71.5 53l156 53l-105 313l-156 -54q-26 -8 -48 -8q-60 0 -101 40.5t-41 100.5q0 47 27.5 85t71.5 53l157 53l-53 159q-8 24 -8 47q0 60 42 102.5t102 42.5q47 0 85 -27t53 -72l54 -160l310 105l-54 160q-8 24 -8 47q0 59 42.5 102 +t101.5 43q47 0 85.5 -27.5t53.5 -71.5l53 -161l162 55q21 6 43 6q60 0 102.5 -39.5t42.5 -98.5q0 -45 -30 -81.5t-74 -51.5l-157 -54l105 -316l164 56q24 8 46 8zM725 498l310 105l-105 315l-310 -107z" /> + <glyph glyph-name="_384" unicode="&#xf199;" +d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960zM1280 352v436q-31 -35 -64 -55q-34 -22 -132.5 -85t-151.5 -99q-98 -69 -164 -69v0v0q-66 0 -164 69 +q-47 32 -142 92.5t-142 92.5q-12 8 -33 27t-31 27v-436q0 -40 28 -68t68 -28h832q40 0 68 28t28 68zM1280 925q0 41 -27.5 70t-68.5 29h-832q-40 0 -68 -28t-28 -68q0 -37 30.5 -76.5t67.5 -64.5q47 -32 137.5 -89t129.5 -83q3 -2 17 -11.5t21 -14t21 -13t23.5 -13 +t21.5 -9.5t22.5 -7.5t20.5 -2.5t20.5 2.5t22.5 7.5t21.5 9.5t23.5 13t21 13t21 14t17 11.5l267 174q35 23 66.5 62.5t31.5 73.5z" /> + <glyph glyph-name="_385" unicode="&#xf19a;" horiz-adv-x="1792" +d="M127 640q0 163 67 313l367 -1005q-196 95 -315 281t-119 411zM1415 679q0 -19 -2.5 -38.5t-10 -49.5t-11.5 -44t-17.5 -59t-17.5 -58l-76 -256l-278 826q46 3 88 8q19 2 26 18.5t-2.5 31t-28.5 13.5l-205 -10q-75 1 -202 10q-12 1 -20.5 -5t-11.5 -15t-1.5 -18.5t9 -16.5 +t19.5 -8l80 -8l120 -328l-168 -504l-280 832q46 3 88 8q19 2 26 18.5t-2.5 31t-28.5 13.5l-205 -10q-7 0 -23 0.5t-26 0.5q105 160 274.5 253.5t367.5 93.5q147 0 280.5 -53t238.5 -149h-10q-55 0 -92 -40.5t-37 -95.5q0 -12 2 -24t4 -21.5t8 -23t9 -21t12 -22.5t12.5 -21 +t14.5 -24t14 -23q63 -107 63 -212zM909 573l237 -647q1 -6 5 -11q-126 -44 -255 -44q-112 0 -217 32zM1570 1009q95 -174 95 -369q0 -209 -104 -385.5t-279 -278.5l235 678q59 169 59 276q0 42 -6 79zM896 1536q182 0 348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286 +t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71zM896 -215q173 0 331.5 68t273 182.5t182.5 273t68 331.5t-68 331.5t-182.5 273t-273 182.5t-331.5 68t-331.5 -68t-273 -182.5t-182.5 -273t-68 -331.5t68 -331.5t182.5 -273 +t273 -182.5t331.5 -68z" /> + <glyph glyph-name="_386" unicode="&#xf19b;" horiz-adv-x="1792" +d="M1086 1536v-1536l-272 -128q-228 20 -414 102t-293 208.5t-107 272.5q0 140 100.5 263.5t275 205.5t391.5 108v-172q-217 -38 -356.5 -150t-139.5 -255q0 -152 154.5 -267t388.5 -145v1360zM1755 954l37 -390l-525 114l147 83q-119 70 -280 99v172q277 -33 481 -157z" /> + <glyph glyph-name="_387" unicode="&#xf19c;" horiz-adv-x="2048" +d="M960 1536l960 -384v-128h-128q0 -26 -20.5 -45t-48.5 -19h-1526q-28 0 -48.5 19t-20.5 45h-128v128zM256 896h256v-768h128v768h256v-768h128v768h256v-768h128v768h256v-768h59q28 0 48.5 -19t20.5 -45v-64h-1664v64q0 26 20.5 45t48.5 19h59v768zM1851 -64 +q28 0 48.5 -19t20.5 -45v-128h-1920v128q0 26 20.5 45t48.5 19h1782z" /> + <glyph glyph-name="_388" unicode="&#xf19d;" horiz-adv-x="2304" +d="M1774 700l18 -316q4 -69 -82 -128t-235 -93.5t-323 -34.5t-323 34.5t-235 93.5t-82 128l18 316l574 -181q22 -7 48 -7t48 7zM2304 1024q0 -23 -22 -31l-1120 -352q-4 -1 -10 -1t-10 1l-652 206q-43 -34 -71 -111.5t-34 -178.5q63 -36 63 -109q0 -69 -58 -107l58 -433 +q2 -14 -8 -25q-9 -11 -24 -11h-192q-15 0 -24 11q-10 11 -8 25l58 433q-58 38 -58 107q0 73 65 111q11 207 98 330l-333 104q-22 8 -22 31t22 31l1120 352q4 1 10 1t10 -1l1120 -352q22 -8 22 -31z" /> + <glyph glyph-name="_389" unicode="&#xf19e;" +d="M859 579l13 -707q-62 11 -105 11q-41 0 -105 -11l13 707q-40 69 -168.5 295.5t-216.5 374.5t-181 287q58 -15 108 -15q44 0 111 15q63 -111 133.5 -229.5t167 -276.5t138.5 -227q37 61 109.5 177.5t117.5 190t105 176t107 189.5q54 -14 107 -14q56 0 114 14v0 +q-28 -39 -60 -88.5t-49.5 -78.5t-56.5 -96t-49 -84q-146 -248 -353 -610z" /> + <glyph glyph-name="uniF1A0" unicode="&#xf1a0;" +d="M768 750h725q12 -67 12 -128q0 -217 -91 -387.5t-259.5 -266.5t-386.5 -96q-157 0 -299 60.5t-245 163.5t-163.5 245t-60.5 299t60.5 299t163.5 245t245 163.5t299 60.5q300 0 515 -201l-209 -201q-123 119 -306 119q-129 0 -238.5 -65t-173.5 -176.5t-64 -243.5 +t64 -243.5t173.5 -176.5t238.5 -65q87 0 160 24t120 60t82 82t51.5 87t22.5 78h-436v264z" /> + <glyph glyph-name="f1a1" unicode="&#xf1a1;" horiz-adv-x="1792" +d="M1095 369q16 -16 0 -31q-62 -62 -199 -62t-199 62q-16 15 0 31q6 6 15 6t15 -6q48 -49 169 -49q120 0 169 49q6 6 15 6t15 -6zM788 550q0 -37 -26 -63t-63 -26t-63.5 26t-26.5 63q0 38 26.5 64t63.5 26t63 -26.5t26 -63.5zM1183 550q0 -37 -26.5 -63t-63.5 -26t-63 26 +t-26 63t26 63.5t63 26.5t63.5 -26t26.5 -64zM1434 670q0 49 -35 84t-85 35t-86 -36q-130 90 -311 96l63 283l200 -45q0 -37 26 -63t63 -26t63.5 26.5t26.5 63.5t-26.5 63.5t-63.5 26.5q-54 0 -80 -50l-221 49q-19 5 -25 -16l-69 -312q-180 -7 -309 -97q-35 37 -87 37 +q-50 0 -85 -35t-35 -84q0 -35 18.5 -64t49.5 -44q-6 -27 -6 -56q0 -142 140 -243t337 -101q198 0 338 101t140 243q0 32 -7 57q30 15 48 43.5t18 63.5zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191 +t348 71t348 -71t286 -191t191 -286t71 -348z" /> + <glyph glyph-name="_392" unicode="&#xf1a2;" +d="M939 407q13 -13 0 -26q-53 -53 -171 -53t-171 53q-13 13 0 26q5 6 13 6t13 -6q42 -42 145 -42t145 42q5 6 13 6t13 -6zM676 563q0 -31 -23 -54t-54 -23t-54 23t-23 54q0 32 22.5 54.5t54.5 22.5t54.5 -22.5t22.5 -54.5zM1014 563q0 -31 -23 -54t-54 -23t-54 23t-23 54 +q0 32 22.5 54.5t54.5 22.5t54.5 -22.5t22.5 -54.5zM1229 666q0 42 -30 72t-73 30q-42 0 -73 -31q-113 78 -267 82l54 243l171 -39q1 -32 23.5 -54t53.5 -22q32 0 54.5 22.5t22.5 54.5t-22.5 54.5t-54.5 22.5q-48 0 -69 -43l-189 42q-17 5 -21 -13l-60 -268q-154 -6 -265 -83 +q-30 32 -74 32q-43 0 -73 -30t-30 -72q0 -30 16 -55t42 -38q-5 -25 -5 -48q0 -122 120 -208.5t289 -86.5q170 0 290 86.5t120 208.5q0 25 -6 49q25 13 40.5 37.5t15.5 54.5zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960 +q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="_393" unicode="&#xf1a3;" +d="M866 697l90 27v62q0 79 -58 135t-138 56t-138 -55.5t-58 -134.5v-283q0 -20 -14 -33.5t-33 -13.5t-32.5 13.5t-13.5 33.5v120h-151v-122q0 -82 57.5 -139t139.5 -57q81 0 138.5 56.5t57.5 136.5v280q0 19 13.5 33t33.5 14q19 0 32.5 -14t13.5 -33v-54zM1199 502v122h-150 +v-126q0 -20 -13.5 -33.5t-33.5 -13.5q-19 0 -32.5 14t-13.5 33v123l-90 -26l-60 28v-123q0 -80 58 -137t139 -57t138.5 57t57.5 139zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103 +t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="f1a4" unicode="&#xf1a4;" horiz-adv-x="1920" +d="M1062 824v118q0 42 -30 72t-72 30t-72 -30t-30 -72v-612q0 -175 -126 -299t-303 -124q-178 0 -303.5 125.5t-125.5 303.5v266h328v-262q0 -43 30 -72.5t72 -29.5t72 29.5t30 72.5v620q0 171 126.5 292t301.5 121q176 0 302 -122t126 -294v-136l-195 -58zM1592 602h328 +v-266q0 -178 -125.5 -303.5t-303.5 -125.5q-177 0 -303 124.5t-126 300.5v268l131 -61l195 58v-270q0 -42 30 -71.5t72 -29.5t72 29.5t30 71.5v275z" /> + <glyph glyph-name="_395" unicode="&#xf1a5;" +d="M1472 160v480h-704v704h-480q-93 0 -158.5 -65.5t-65.5 -158.5v-480h704v-704h480q93 0 158.5 65.5t65.5 158.5zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5 +t84.5 -203.5z" /> + <glyph glyph-name="_396" unicode="&#xf1a6;" horiz-adv-x="2048" +d="M328 1254h204v-983h-532v697h328v286zM328 435v369h-123v-369h123zM614 968v-697h205v697h-205zM614 1254v-204h205v204h-205zM901 968h533v-942h-533v163h328v82h-328v697zM1229 435v369h-123v-369h123zM1516 968h532v-942h-532v163h327v82h-327v697zM1843 435v369h-123 +v-369h123z" /> + <glyph glyph-name="_397" unicode="&#xf1a7;" +d="M1046 516q0 -64 -38 -109t-91 -45q-43 0 -70 15v277q28 17 70 17q53 0 91 -45.5t38 -109.5zM703 944q0 -64 -38 -109.5t-91 -45.5q-43 0 -70 15v277q28 17 70 17q53 0 91 -45t38 -109zM1265 513q0 134 -88 229t-213 95q-20 0 -39 -3q-23 -78 -78 -136q-87 -95 -211 -101 +v-636l211 41v206q51 -19 117 -19q125 0 213 95t88 229zM922 940q0 134 -88.5 229t-213.5 95q-74 0 -141 -36h-186v-840l211 41v206q55 -19 116 -19q125 0 213.5 95t88.5 229zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960 +q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="_398" unicode="&#xf1a8;" horiz-adv-x="2038" +d="M1222 607q75 3 143.5 -20.5t118 -58.5t101 -94.5t84 -108t75.5 -120.5q33 -56 78.5 -109t75.5 -80.5t99 -88.5q-48 -30 -108.5 -57.5t-138.5 -59t-114 -47.5q-44 37 -74 115t-43.5 164.5t-33 180.5t-42.5 168.5t-72.5 123t-122.5 48.5l-10 -2l-6 -4q4 -5 13 -14 +q6 -5 28 -23.5t25.5 -22t19 -18t18 -20.5t11.5 -21t10.5 -27.5t4.5 -31t4 -40.5l1 -33q1 -26 -2.5 -57.5t-7.5 -52t-12.5 -58.5t-11.5 -53q-35 1 -101 -9.5t-98 -10.5q-39 0 -72 10q-2 16 -2 47q0 74 3 96q2 13 31.5 41.5t57 59t26.5 51.5q-24 2 -43 -24 +q-36 -53 -111.5 -99.5t-136.5 -46.5q-25 0 -75.5 63t-106.5 139.5t-84 96.5q-6 4 -27 30q-482 -112 -513 -112q-16 0 -28 11t-12 27q0 15 8.5 26.5t22.5 14.5l486 106q-8 14 -8 25t5.5 17.5t16 11.5t20 7t23 4.5t18.5 4.5q4 1 15.5 7.5t17.5 6.5q15 0 28 -16t20 -33 +q163 37 172 37q17 0 29.5 -11t12.5 -28q0 -15 -8.5 -26t-23.5 -14l-182 -40l-1 -16q-1 -26 81.5 -117.5t104.5 -91.5q47 0 119 80t72 129q0 36 -23.5 53t-51 18.5t-51 11.5t-23.5 34q0 16 10 34l-68 19q43 44 43 117q0 26 -5 58q82 16 144 16q44 0 71.5 -1.5t48.5 -8.5 +t31 -13.5t20.5 -24.5t15.5 -33.5t17 -47.5t24 -60l50 25q-3 -40 -23 -60t-42.5 -21t-40 -6.5t-16.5 -20.5zM1282 842q-5 5 -13.5 15.5t-12 14.5t-10.5 11.5t-10 10.5l-8 8t-8.5 7.5t-8 5t-8.5 4.5q-7 3 -14.5 5t-20.5 2.5t-22 0.5h-32.5h-37.5q-126 0 -217 -43 +q16 30 36 46.5t54 29.5t65.5 36t46 36.5t50 55t43.5 50.5q12 -9 28 -31.5t32 -36.5t38 -13l12 1v-76l22 -1q247 95 371 190q28 21 50 39t42.5 37.5t33 31t29.5 34t24 31t24.5 37t23 38t27 47.5t29.5 53l7 9q-2 -53 -43 -139q-79 -165 -205 -264t-306 -142q-14 -3 -42 -7.5 +t-50 -9.5t-39 -14q3 -19 24.5 -46t21.5 -34q0 -11 -26 -30zM1061 -79q39 26 131.5 47.5t146.5 21.5q9 0 22.5 -15.5t28 -42.5t26 -50t24 -51t14.5 -33q-121 -45 -244 -45q-61 0 -125 11zM822 568l48 12l109 -177l-73 -48zM1323 51q3 -15 3 -16q0 -7 -17.5 -14.5t-46 -13 +t-54 -9.5t-53.5 -7.5t-32 -4.5l-7 43q21 2 60.5 8.5t72 10t60.5 3.5h14zM866 679l-96 -20l-6 17q10 1 32.5 7t34.5 6q19 0 35 -10zM1061 45h31l10 -83l-41 -12v95zM1950 1535v1v-1zM1950 1535l-1 -5l-2 -2l1 3zM1950 1535l1 1z" /> + <glyph glyph-name="_399" unicode="&#xf1a9;" +d="M1167 -50q-5 19 -24 5q-30 -22 -87 -39t-131 -17q-129 0 -193 49q-5 4 -13 4q-11 0 -26 -12q-7 -6 -7.5 -16t7.5 -20q34 -32 87.5 -46t102.5 -12.5t99 4.5q41 4 84.5 20.5t65 30t28.5 20.5q12 12 7 29zM1128 65q-19 47 -39 61q-23 15 -76 15q-47 0 -71 -10 +q-29 -12 -78 -56q-26 -24 -12 -44q9 -8 17.5 -4.5t31.5 23.5q3 2 10.5 8.5t10.5 8.5t10 7t11.5 7t12.5 5t15 4.5t16.5 2.5t20.5 1q27 0 44.5 -7.5t23 -14.5t13.5 -22q10 -17 12.5 -20t12.5 1q23 12 14 34zM1483 346q0 22 -5 44.5t-16.5 45t-34 36.5t-52.5 14 +q-33 0 -97 -41.5t-129 -83.5t-101 -42q-27 -1 -63.5 19t-76 49t-83.5 58t-100 49t-111 19q-115 -1 -197 -78.5t-84 -178.5q-2 -112 74 -164q29 -20 62.5 -28.5t103.5 -8.5q57 0 132 32.5t134 71t120 70.5t93 31q26 -1 65 -31.5t71.5 -67t68 -67.5t55.5 -32q35 -3 58.5 14 +t55.5 63q28 41 42.5 101t14.5 106zM1536 506q0 -164 -62 -304.5t-166 -236t-242.5 -149.5t-290.5 -54t-293 57.5t-247.5 157t-170.5 241.5t-64 302q0 89 19.5 172.5t49 145.5t70.5 118.5t78.5 94t78.5 69.5t64.5 46.5t42.5 24.5q14 8 51 26.5t54.5 28.5t48 30t60.5 44 +q36 28 58 72.5t30 125.5q129 -155 186 -193q44 -29 130 -68t129 -66q21 -13 39 -25t60.5 -46.5t76 -70.5t75 -95t69 -122t47 -148.5t19.5 -177.5z" /> + <glyph glyph-name="_400" unicode="&#xf1aa;" +d="M1070 463l-160 -160l-151 -152l-30 -30q-65 -64 -151.5 -87t-171.5 -2q-16 -70 -72 -115t-129 -45q-85 0 -145 60.5t-60 145.5q0 72 44.5 128t113.5 72q-22 86 1 173t88 152l12 12l151 -152l-11 -11q-37 -37 -37 -89t37 -90q37 -37 89 -37t89 37l30 30l151 152l161 160z +M729 1145l12 -12l-152 -152l-12 12q-37 37 -89 37t-89 -37t-37 -89.5t37 -89.5l29 -29l152 -152l160 -160l-151 -152l-161 160l-151 152l-30 30q-68 67 -90 159.5t5 179.5q-70 15 -115 71t-45 129q0 85 60 145.5t145 60.5q76 0 133.5 -49t69.5 -123q84 20 169.5 -3.5 +t149.5 -87.5zM1536 78q0 -85 -60 -145.5t-145 -60.5q-74 0 -131 47t-71 118q-86 -28 -179.5 -6t-161.5 90l-11 12l151 152l12 -12q37 -37 89 -37t89 37t37 89t-37 89l-30 30l-152 152l-160 160l152 152l160 -160l152 -152l29 -30q64 -64 87.5 -150.5t2.5 -171.5 +q76 -11 126.5 -68.5t50.5 -134.5zM1534 1202q0 -77 -51 -135t-127 -69q26 -85 3 -176.5t-90 -158.5l-12 -12l-151 152l12 12q37 37 37 89t-37 89t-89 37t-89 -37l-30 -30l-152 -152l-160 -160l-152 152l161 160l152 152l29 30q67 67 159 89.5t178 -3.5q11 75 68.5 126 +t135.5 51q85 0 145 -60.5t60 -145.5z" /> + <glyph glyph-name="f1ab" unicode="&#xf1ab;" +d="M654 458q-1 -3 -12.5 0.5t-31.5 11.5l-20 9q-44 20 -87 49q-7 5 -41 31.5t-38 28.5q-67 -103 -134 -181q-81 -95 -105 -110q-4 -2 -19.5 -4t-18.5 0q6 4 82 92q21 24 85.5 115t78.5 118q17 30 51 98.5t36 77.5q-8 1 -110 -33q-8 -2 -27.5 -7.5t-34.5 -9.5t-17 -5 +q-2 -2 -2 -10.5t-1 -9.5q-5 -10 -31 -15q-23 -7 -47 0q-18 4 -28 21q-4 6 -5 23q6 2 24.5 5t29.5 6q58 16 105 32q100 35 102 35q10 2 43 19.5t44 21.5q9 3 21.5 8t14.5 5.5t6 -0.5q2 -12 -1 -33q0 -2 -12.5 -27t-26.5 -53.5t-17 -33.5q-25 -50 -77 -131l64 -28 +q12 -6 74.5 -32t67.5 -28q4 -1 10.5 -25.5t4.5 -30.5zM449 944q3 -15 -4 -28q-12 -23 -50 -38q-30 -12 -60 -12q-26 3 -49 26q-14 15 -18 41l1 3q3 -3 19.5 -5t26.5 0t58 16q36 12 55 14q17 0 21 -17zM1147 815l63 -227l-139 42zM39 15l694 232v1032l-694 -233v-1031z +M1280 332l102 -31l-181 657l-100 31l-216 -536l102 -31l45 110l211 -65zM777 1294l573 -184v380zM1088 -29l158 -13l-54 -160l-40 66q-130 -83 -276 -108q-58 -12 -91 -12h-84q-79 0 -199.5 39t-183.5 85q-8 7 -8 16q0 8 5 13.5t13 5.5q4 0 18 -7.5t30.5 -16.5t20.5 -11 +q73 -37 159.5 -61.5t157.5 -24.5q95 0 167 14.5t157 50.5q15 7 30.5 15.5t34 19t28.5 16.5zM1536 1050v-1079l-774 246q-14 -6 -375 -127.5t-368 -121.5q-13 0 -18 13q0 1 -1 3v1078q3 9 4 10q5 6 20 11q107 36 149 50v384l558 -198q2 0 160.5 55t316 108.5t161.5 53.5 +q20 0 20 -21v-418z" /> + <glyph glyph-name="_402" unicode="&#xf1ac;" horiz-adv-x="1792" +d="M288 1152q66 0 113 -47t47 -113v-1088q0 -66 -47 -113t-113 -47h-128q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h128zM1664 989q58 -34 93 -93t35 -128v-768q0 -106 -75 -181t-181 -75h-864q-66 0 -113 47t-47 113v1536q0 40 28 68t68 28h672q40 0 88 -20t76 -48 +l152 -152q28 -28 48 -76t20 -88v-163zM928 0v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM928 256v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM928 512v128q0 14 -9 23 +t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1184 0v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1184 256v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128 +q14 0 23 9t9 23zM1184 512v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1440 0v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1440 256v128q0 14 -9 23t-23 9h-128 +q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1440 512v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1536 896v256h-160q-40 0 -68 28t-28 68v160h-640v-512h896z" /> + <glyph glyph-name="_403" unicode="&#xf1ad;" +d="M1344 1536q26 0 45 -19t19 -45v-1664q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v1664q0 26 19 45t45 19h1280zM512 1248v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM512 992v-64q0 -14 9 -23t23 -9h64q14 0 23 9 +t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM512 736v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM512 480v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM384 160v64 +q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM384 416v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM384 672v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64 +q14 0 23 9t9 23zM384 928v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM384 1184v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM896 -96v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9 +t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM896 416v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM896 672v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM896 928v64 +q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM896 1184v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1152 160v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64 +q14 0 23 9t9 23zM1152 416v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1152 672v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1152 928v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9 +t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1152 1184v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23z" /> + <glyph glyph-name="_404" unicode="&#xf1ae;" horiz-adv-x="1280" +d="M1188 988l-292 -292v-824q0 -46 -33 -79t-79 -33t-79 33t-33 79v384h-64v-384q0 -46 -33 -79t-79 -33t-79 33t-33 79v824l-292 292q-28 28 -28 68t28 68q29 28 68.5 28t67.5 -28l228 -228h368l228 228q28 28 68 28t68 -28q28 -29 28 -68.5t-28 -67.5zM864 1152 +q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5z" /> + <glyph glyph-name="uniF1B1" unicode="&#xf1b0;" horiz-adv-x="1664" +d="M780 1064q0 -60 -19 -113.5t-63 -92.5t-105 -39q-76 0 -138 57.5t-92 135.5t-30 151q0 60 19 113.5t63 92.5t105 39q77 0 138.5 -57.5t91.5 -135t30 -151.5zM438 581q0 -80 -42 -139t-119 -59q-76 0 -141.5 55.5t-100.5 133.5t-35 152q0 80 42 139.5t119 59.5 +q76 0 141.5 -55.5t100.5 -134t35 -152.5zM832 608q118 0 255 -97.5t229 -237t92 -254.5q0 -46 -17 -76.5t-48.5 -45t-64.5 -20t-76 -5.5q-68 0 -187.5 45t-182.5 45q-66 0 -192.5 -44.5t-200.5 -44.5q-183 0 -183 146q0 86 56 191.5t139.5 192.5t187.5 146t193 59zM1071 819 +q-61 0 -105 39t-63 92.5t-19 113.5q0 74 30 151.5t91.5 135t138.5 57.5q61 0 105 -39t63 -92.5t19 -113.5q0 -73 -30 -151t-92 -135.5t-138 -57.5zM1503 923q77 0 119 -59.5t42 -139.5q0 -74 -35 -152t-100.5 -133.5t-141.5 -55.5q-77 0 -119 59t-42 139q0 74 35 152.5 +t100.5 134t141.5 55.5z" /> + <glyph glyph-name="_406" unicode="&#xf1b1;" horiz-adv-x="768" +d="M704 1008q0 -145 -57 -243.5t-152 -135.5l45 -821q2 -26 -16 -45t-44 -19h-192q-26 0 -44 19t-16 45l45 821q-95 37 -152 135.5t-57 243.5q0 128 42.5 249.5t117.5 200t160 78.5t160 -78.5t117.5 -200t42.5 -249.5z" /> + <glyph glyph-name="_407" unicode="&#xf1b2;" horiz-adv-x="1792" +d="M896 -93l640 349v636l-640 -233v-752zM832 772l698 254l-698 254l-698 -254zM1664 1024v-768q0 -35 -18 -65t-49 -47l-704 -384q-28 -16 -61 -16t-61 16l-704 384q-31 17 -49 47t-18 65v768q0 40 23 73t61 47l704 256q22 8 44 8t44 -8l704 -256q38 -14 61 -47t23 -73z +" /> + <glyph glyph-name="_408" unicode="&#xf1b3;" horiz-adv-x="2304" +d="M640 -96l384 192v314l-384 -164v-342zM576 358l404 173l-404 173l-404 -173zM1664 -96l384 192v314l-384 -164v-342zM1600 358l404 173l-404 173l-404 -173zM1152 651l384 165v266l-384 -164v-267zM1088 1030l441 189l-441 189l-441 -189zM2176 512v-416q0 -36 -19 -67 +t-52 -47l-448 -224q-25 -14 -57 -14t-57 14l-448 224q-4 2 -7 4q-2 -2 -7 -4l-448 -224q-25 -14 -57 -14t-57 14l-448 224q-33 16 -52 47t-19 67v416q0 38 21.5 70t56.5 48l434 186v400q0 38 21.5 70t56.5 48l448 192q23 10 50 10t50 -10l448 -192q35 -16 56.5 -48t21.5 -70 +v-400l434 -186q36 -16 57 -48t21 -70z" /> + <glyph glyph-name="_409" unicode="&#xf1b4;" horiz-adv-x="2048" +d="M1848 1197h-511v-124h511v124zM1596 771q-90 0 -146 -52.5t-62 -142.5h408q-18 195 -200 195zM1612 186q63 0 122 32t76 87h221q-100 -307 -427 -307q-214 0 -340.5 132t-126.5 347q0 208 130.5 345.5t336.5 137.5q138 0 240.5 -68t153 -179t50.5 -248q0 -17 -2 -47h-658 +q0 -111 57.5 -171.5t166.5 -60.5zM277 236h296q205 0 205 167q0 180 -199 180h-302v-347zM277 773h281q78 0 123.5 36.5t45.5 113.5q0 144 -190 144h-260v-294zM0 1282h594q87 0 155 -14t126.5 -47.5t90 -96.5t31.5 -154q0 -181 -172 -263q114 -32 172 -115t58 -204 +q0 -75 -24.5 -136.5t-66 -103.5t-98.5 -71t-121 -42t-134 -13h-611v1260z" /> + <glyph glyph-name="_410" unicode="&#xf1b5;" +d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960zM499 1041h-371v-787h382q117 0 197 57.5t80 170.5q0 158 -143 200q107 52 107 164q0 57 -19.5 96.5 +t-56.5 60.5t-79 29.5t-97 8.5zM477 723h-176v184h163q119 0 119 -90q0 -94 -106 -94zM486 388h-185v217h189q124 0 124 -113q0 -104 -128 -104zM1136 356q-68 0 -104 38t-36 107h411q1 10 1 30q0 132 -74.5 220.5t-203.5 88.5q-128 0 -210 -86t-82 -216q0 -135 79 -217 +t213 -82q205 0 267 191h-138q-11 -34 -47.5 -54t-75.5 -20zM1126 722q113 0 124 -122h-254q4 56 39 89t91 33zM964 988h319v-77h-319v77z" /> + <glyph glyph-name="_411" unicode="&#xf1b6;" horiz-adv-x="1792" +d="M1582 954q0 -101 -71.5 -172.5t-172.5 -71.5t-172.5 71.5t-71.5 172.5t71.5 172.5t172.5 71.5t172.5 -71.5t71.5 -172.5zM812 212q0 104 -73 177t-177 73q-27 0 -54 -6l104 -42q77 -31 109.5 -106.5t1.5 -151.5q-31 -77 -107 -109t-152 -1q-21 8 -62 24.5t-61 24.5 +q32 -60 91 -96.5t130 -36.5q104 0 177 73t73 177zM1642 953q0 126 -89.5 215.5t-215.5 89.5q-127 0 -216.5 -89.5t-89.5 -215.5q0 -127 89.5 -216t216.5 -89q126 0 215.5 89t89.5 216zM1792 953q0 -189 -133.5 -322t-321.5 -133l-437 -319q-12 -129 -109 -218t-229 -89 +q-121 0 -214 76t-118 192l-230 92v429l389 -157q79 48 173 48q13 0 35 -2l284 407q2 187 135.5 319t320.5 132q188 0 321.5 -133.5t133.5 -321.5z" /> + <glyph glyph-name="_412" unicode="&#xf1b7;" +d="M1242 889q0 80 -57 136.5t-137 56.5t-136.5 -57t-56.5 -136q0 -80 56.5 -136.5t136.5 -56.5t137 56.5t57 136.5zM632 301q0 -83 -58 -140.5t-140 -57.5q-56 0 -103 29t-72 77q52 -20 98 -40q60 -24 120 1.5t85 86.5q24 60 -1.5 120t-86.5 84l-82 33q22 5 42 5 +q82 0 140 -57.5t58 -140.5zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v153l172 -69q20 -92 93.5 -152t168.5 -60q104 0 181 70t87 173l345 252q150 0 255.5 105.5t105.5 254.5q0 150 -105.5 255.5t-255.5 105.5 +q-148 0 -253 -104.5t-107 -252.5l-225 -322q-9 1 -28 1q-75 0 -137 -37l-297 119v468q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5zM1289 887q0 -100 -71 -170.5t-171 -70.5t-170.5 70.5t-70.5 170.5t70.5 171t170.5 71q101 0 171.5 -70.5t70.5 -171.5z +" /> + <glyph glyph-name="_413" unicode="&#xf1b8;" horiz-adv-x="1792" +d="M836 367l-15 -368l-2 -22l-420 29q-36 3 -67 31.5t-47 65.5q-11 27 -14.5 55t4 65t12 55t21.5 64t19 53q78 -12 509 -28zM449 953l180 -379l-147 92q-63 -72 -111.5 -144.5t-72.5 -125t-39.5 -94.5t-18.5 -63l-4 -21l-190 357q-17 26 -18 56t6 47l8 18q35 63 114 188 +l-140 86zM1680 436l-188 -359q-12 -29 -36.5 -46.5t-43.5 -20.5l-18 -4q-71 -7 -219 -12l8 -164l-230 367l211 362l7 -173q170 -16 283 -5t170 33zM895 1360q-47 -63 -265 -435l-317 187l-19 12l225 356q20 31 60 45t80 10q24 -2 48.5 -12t42 -21t41.5 -33t36 -34.5 +t36 -39.5t32 -35zM1550 1053l212 -363q18 -37 12.5 -76t-27.5 -74q-13 -20 -33 -37t-38 -28t-48.5 -22t-47 -16t-51.5 -14t-46 -12q-34 72 -265 436l313 195zM1407 1279l142 83l-220 -373l-419 20l151 86q-34 89 -75 166t-75.5 123.5t-64.5 80t-47 46.5l-17 13l405 -1 +q31 3 58 -10.5t39 -28.5l11 -15q39 -61 112 -190z" /> + <glyph glyph-name="_414" unicode="&#xf1b9;" horiz-adv-x="2048" +d="M480 448q0 66 -47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47t113 47t47 113zM516 768h1016l-89 357q-2 8 -14 17.5t-21 9.5h-768q-9 0 -21 -9.5t-14 -17.5zM1888 448q0 66 -47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47t113 47t47 113zM2048 544v-384 +q0 -14 -9 -23t-23 -9h-96v-128q0 -80 -56 -136t-136 -56t-136 56t-56 136v128h-1024v-128q0 -80 -56 -136t-136 -56t-136 56t-56 136v128h-96q-14 0 -23 9t-9 23v384q0 93 65.5 158.5t158.5 65.5h28l105 419q23 94 104 157.5t179 63.5h768q98 0 179 -63.5t104 -157.5 +l105 -419h28q93 0 158.5 -65.5t65.5 -158.5z" /> + <glyph glyph-name="_415" unicode="&#xf1ba;" horiz-adv-x="2048" +d="M1824 640q93 0 158.5 -65.5t65.5 -158.5v-384q0 -14 -9 -23t-23 -9h-96v-64q0 -80 -56 -136t-136 -56t-136 56t-56 136v64h-1024v-64q0 -80 -56 -136t-136 -56t-136 56t-56 136v64h-96q-14 0 -23 9t-9 23v384q0 93 65.5 158.5t158.5 65.5h28l105 419q23 94 104 157.5 +t179 63.5h128v224q0 14 9 23t23 9h448q14 0 23 -9t9 -23v-224h128q98 0 179 -63.5t104 -157.5l105 -419h28zM320 160q66 0 113 47t47 113t-47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47zM516 640h1016l-89 357q-2 8 -14 17.5t-21 9.5h-768q-9 0 -21 -9.5t-14 -17.5z +M1728 160q66 0 113 47t47 113t-47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47z" /> + <glyph glyph-name="_416" unicode="&#xf1bb;" +d="M1504 64q0 -26 -19 -45t-45 -19h-462q1 -17 6 -87.5t5 -108.5q0 -25 -18 -42.5t-43 -17.5h-320q-25 0 -43 17.5t-18 42.5q0 38 5 108.5t6 87.5h-462q-26 0 -45 19t-19 45t19 45l402 403h-229q-26 0 -45 19t-19 45t19 45l402 403h-197q-26 0 -45 19t-19 45t19 45l384 384 +q19 19 45 19t45 -19l384 -384q19 -19 19 -45t-19 -45t-45 -19h-197l402 -403q19 -19 19 -45t-19 -45t-45 -19h-229l402 -403q19 -19 19 -45z" /> + <glyph glyph-name="_417" unicode="&#xf1bc;" +d="M1127 326q0 32 -30 51q-193 115 -447 115q-133 0 -287 -34q-42 -9 -42 -52q0 -20 13.5 -34.5t35.5 -14.5q5 0 37 8q132 27 243 27q226 0 397 -103q19 -11 33 -11q19 0 33 13.5t14 34.5zM1223 541q0 40 -35 61q-237 141 -548 141q-153 0 -303 -42q-48 -13 -48 -64 +q0 -25 17.5 -42.5t42.5 -17.5q7 0 37 8q122 33 251 33q279 0 488 -124q24 -13 38 -13q25 0 42.5 17.5t17.5 42.5zM1331 789q0 47 -40 70q-126 73 -293 110.5t-343 37.5q-204 0 -364 -47q-23 -7 -38.5 -25.5t-15.5 -48.5q0 -31 20.5 -52t51.5 -21q11 0 40 8q133 37 307 37 +q159 0 309.5 -34t253.5 -95q21 -12 40 -12q29 0 50.5 20.5t21.5 51.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="_418" unicode="&#xf1bd;" horiz-adv-x="1024" +d="M1024 1233l-303 -582l24 -31h279v-415h-507l-44 -30l-142 -273l-30 -30h-301v303l303 583l-24 30h-279v415h507l44 30l142 273l30 30h301v-303z" /> + <glyph glyph-name="_419" unicode="&#xf1be;" horiz-adv-x="2304" +d="M784 164l16 241l-16 523q-1 10 -7.5 17t-16.5 7q-9 0 -16 -7t-7 -17l-14 -523l14 -241q1 -10 7.5 -16.5t15.5 -6.5q22 0 24 23zM1080 193l11 211l-12 586q0 16 -13 24q-8 5 -16 5t-16 -5q-13 -8 -13 -24l-1 -6l-10 -579q0 -1 11 -236v-1q0 -10 6 -17q9 -11 23 -11 +q11 0 20 9q9 7 9 20zM35 533l20 -128l-20 -126q-2 -9 -9 -9t-9 9l-17 126l17 128q2 9 9 9t9 -9zM121 612l26 -207l-26 -203q-2 -9 -10 -9q-9 0 -9 10l-23 202l23 207q0 9 9 9q8 0 10 -9zM401 159zM213 650l25 -245l-25 -237q0 -11 -11 -11q-10 0 -12 11l-21 237l21 245 +q2 12 12 12q11 0 11 -12zM307 657l23 -252l-23 -244q-2 -13 -14 -13q-13 0 -13 13l-21 244l21 252q0 13 13 13q12 0 14 -13zM401 639l21 -234l-21 -246q-2 -16 -16 -16q-6 0 -10.5 4.5t-4.5 11.5l-20 246l20 234q0 6 4.5 10.5t10.5 4.5q14 0 16 -15zM784 164zM495 785 +l21 -380l-21 -246q0 -7 -5 -12.5t-12 -5.5q-16 0 -18 18l-18 246l18 380q2 18 18 18q7 0 12 -5.5t5 -12.5zM589 871l19 -468l-19 -244q0 -8 -5.5 -13.5t-13.5 -5.5q-18 0 -20 19l-16 244l16 468q2 19 20 19q8 0 13.5 -5.5t5.5 -13.5zM687 911l18 -506l-18 -242 +q-2 -21 -22 -21q-19 0 -21 21l-16 242l16 506q0 9 6.5 15.5t14.5 6.5q9 0 15 -6.5t7 -15.5zM1079 169v0v0v0zM881 915l15 -510l-15 -239q0 -10 -7.5 -17.5t-17.5 -7.5t-17 7t-8 18l-14 239l14 510q0 11 7.5 18t17.5 7t17.5 -7t7.5 -18zM980 896l14 -492l-14 -236 +q0 -11 -8 -19t-19 -8t-19 8t-9 19l-12 236l12 492q1 12 9 20t19 8t18.5 -8t8.5 -20zM1192 404l-14 -231v0q0 -13 -9 -22t-22 -9t-22 9t-10 22l-6 114l-6 117l12 636v3q2 15 12 24q9 7 20 7q8 0 15 -5q14 -8 16 -26zM2304 423q0 -117 -83 -199.5t-200 -82.5h-786 +q-13 2 -22 11t-9 22v899q0 23 28 33q85 34 181 34q195 0 338 -131.5t160 -323.5q53 22 110 22q117 0 200 -83t83 -201z" /> + <glyph glyph-name="uniF1C0" unicode="&#xf1c0;" +d="M768 768q237 0 443 43t325 127v-170q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5t-103 128v170q119 -84 325 -127t443 -43zM768 0q237 0 443 43t325 127v-170q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5t-103 128v170q119 -84 325 -127 +t443 -43zM768 384q237 0 443 43t325 127v-170q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5t-103 128v170q119 -84 325 -127t443 -43zM768 1536q208 0 385 -34.5t280 -93.5t103 -128v-128q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5 +t-103 128v128q0 69 103 128t280 93.5t385 34.5z" /> + <glyph glyph-name="uniF1C1" unicode="&#xf1c1;" +d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z +M894 465q33 -26 84 -56q59 7 117 7q147 0 177 -49q16 -22 2 -52q0 -1 -1 -2l-2 -2v-1q-6 -38 -71 -38q-48 0 -115 20t-130 53q-221 -24 -392 -83q-153 -262 -242 -262q-15 0 -28 7l-24 12q-1 1 -6 5q-10 10 -6 36q9 40 56 91.5t132 96.5q14 9 23 -6q2 -2 2 -4q52 85 107 197 +q68 136 104 262q-24 82 -30.5 159.5t6.5 127.5q11 40 42 40h21h1q23 0 35 -15q18 -21 9 -68q-2 -6 -4 -8q1 -3 1 -8v-30q-2 -123 -14 -192q55 -164 146 -238zM318 54q52 24 137 158q-51 -40 -87.5 -84t-49.5 -74zM716 974q-15 -42 -2 -132q1 7 7 44q0 3 7 43q1 4 4 8 +q-1 1 -1 2q-1 2 -1 3q-1 22 -13 36q0 -1 -1 -2v-2zM592 313q135 54 284 81q-2 1 -13 9.5t-16 13.5q-76 67 -127 176q-27 -86 -83 -197q-30 -56 -45 -83zM1238 329q-24 24 -140 24q76 -28 124 -28q14 0 18 1q0 1 -2 3z" /> + <glyph glyph-name="_422" unicode="&#xf1c2;" +d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z +M233 768v-107h70l164 -661h159l128 485q7 20 10 46q2 16 2 24h4l3 -24q1 -3 3.5 -20t5.5 -26l128 -485h159l164 661h70v107h-300v-107h90l-99 -438q-5 -20 -7 -46l-2 -21h-4q0 3 -0.5 6.5t-1.5 8t-1 6.5q-1 5 -4 21t-5 25l-144 545h-114l-144 -545q-2 -9 -4.5 -24.5 +t-3.5 -21.5l-4 -21h-4l-2 21q-2 26 -7 46l-99 438h90v107h-300z" /> + <glyph glyph-name="_423" unicode="&#xf1c3;" +d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z +M429 106v-106h281v106h-75l103 161q5 7 10 16.5t7.5 13.5t3.5 4h2q1 -4 5 -10q2 -4 4.5 -7.5t6 -8t6.5 -8.5l107 -161h-76v-106h291v106h-68l-192 273l195 282h67v107h-279v-107h74l-103 -159q-4 -7 -10 -16.5t-9 -13.5l-2 -3h-2q-1 4 -5 10q-6 11 -17 23l-106 159h76v107 +h-290v-107h68l189 -272l-194 -283h-68z" /> + <glyph glyph-name="_424" unicode="&#xf1c4;" +d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z +M416 106v-106h327v106h-93v167h137q76 0 118 15q67 23 106.5 87t39.5 146q0 81 -37 141t-100 87q-48 19 -130 19h-368v-107h92v-555h-92zM769 386h-119v268h120q52 0 83 -18q56 -33 56 -115q0 -89 -62 -120q-31 -15 -78 -15z" /> + <glyph glyph-name="_425" unicode="&#xf1c5;" +d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z +M1280 320v-320h-1024v192l192 192l128 -128l384 384zM448 512q-80 0 -136 56t-56 136t56 136t136 56t136 -56t56 -136t-56 -136t-136 -56z" /> + <glyph glyph-name="_426" unicode="&#xf1c6;" +d="M640 1152v128h-128v-128h128zM768 1024v128h-128v-128h128zM640 896v128h-128v-128h128zM768 768v128h-128v-128h128zM1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400 +v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-128v-128h-128v128h-512v-1536h1280zM781 593l107 -349q8 -27 8 -52q0 -83 -72.5 -137.5t-183.5 -54.5t-183.5 54.5t-72.5 137.5q0 25 8 52q21 63 120 396v128h128v-128h79 +q22 0 39 -13t23 -34zM640 128q53 0 90.5 19t37.5 45t-37.5 45t-90.5 19t-90.5 -19t-37.5 -45t37.5 -45t90.5 -19z" /> + <glyph glyph-name="_427" unicode="&#xf1c7;" +d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z +M620 686q20 -8 20 -30v-544q0 -22 -20 -30q-8 -2 -12 -2q-12 0 -23 9l-166 167h-131q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h131l166 167q16 15 35 7zM1037 -3q31 0 50 24q129 159 129 363t-129 363q-16 21 -43 24t-47 -14q-21 -17 -23.5 -43.5t14.5 -47.5 +q100 -123 100 -282t-100 -282q-17 -21 -14.5 -47.5t23.5 -42.5q18 -15 40 -15zM826 145q27 0 47 20q87 93 87 219t-87 219q-18 19 -45 20t-46 -17t-20 -44.5t18 -46.5q52 -57 52 -131t-52 -131q-19 -20 -18 -46.5t20 -44.5q20 -17 44 -17z" /> + <glyph glyph-name="_428" unicode="&#xf1c8;" +d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z +M768 768q52 0 90 -38t38 -90v-384q0 -52 -38 -90t-90 -38h-384q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h384zM1260 766q20 -8 20 -30v-576q0 -22 -20 -30q-8 -2 -12 -2q-14 0 -23 9l-265 266v90l265 266q9 9 23 9q4 0 12 -2z" /> + <glyph glyph-name="_429" unicode="&#xf1c9;" +d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z +M480 768q8 11 21 12.5t24 -6.5l51 -38q11 -8 12.5 -21t-6.5 -24l-182 -243l182 -243q8 -11 6.5 -24t-12.5 -21l-51 -38q-11 -8 -24 -6.5t-21 12.5l-226 301q-14 19 0 38zM1282 467q14 -19 0 -38l-226 -301q-8 -11 -21 -12.5t-24 6.5l-51 38q-11 8 -12.5 21t6.5 24l182 243 +l-182 243q-8 11 -6.5 24t12.5 21l51 38q11 8 24 6.5t21 -12.5zM662 6q-13 2 -20.5 13t-5.5 24l138 831q2 13 13 20.5t24 5.5l63 -10q13 -2 20.5 -13t5.5 -24l-138 -831q-2 -13 -13 -20.5t-24 -5.5z" /> + <glyph glyph-name="_430" unicode="&#xf1ca;" +d="M1497 709v-198q-101 -23 -198 -23q-65 -136 -165.5 -271t-181.5 -215.5t-128 -106.5q-80 -45 -162 3q-28 17 -60.5 43.5t-85 83.5t-102.5 128.5t-107.5 184t-105.5 244t-91.5 314.5t-70.5 390h283q26 -218 70 -398.5t104.5 -317t121.5 -235.5t140 -195q169 169 287 406 +q-142 72 -223 220t-81 333q0 192 104 314.5t284 122.5q178 0 273 -105.5t95 -297.5q0 -159 -58 -286q-7 -1 -19.5 -3t-46 -2t-63 6t-62 25.5t-50.5 51.5q31 103 31 184q0 87 -29 132t-79 45q-53 0 -85 -49.5t-32 -140.5q0 -186 105 -293.5t267 -107.5q62 0 121 14z" /> + <glyph glyph-name="_431" unicode="&#xf1cb;" horiz-adv-x="1792" +d="M216 367l603 -402v359l-334 223zM154 511l193 129l-193 129v-258zM973 -35l603 402l-269 180l-334 -223v-359zM896 458l272 182l-272 182l-272 -182zM485 733l334 223v359l-603 -402zM1445 640l193 -129v258zM1307 733l269 180l-603 402v-359zM1792 913v-546 +q0 -41 -34 -64l-819 -546q-21 -13 -43 -13t-43 13l-819 546q-34 23 -34 64v546q0 41 34 64l819 546q21 13 43 13t43 -13l819 -546q34 -23 34 -64z" /> + <glyph glyph-name="_432" unicode="&#xf1cc;" horiz-adv-x="2048" +d="M1800 764q111 -46 179.5 -145.5t68.5 -221.5q0 -164 -118 -280.5t-285 -116.5q-4 0 -11.5 0.5t-10.5 0.5h-1209h-1h-2h-5q-170 10 -288 125.5t-118 280.5q0 110 55 203t147 147q-12 39 -12 82q0 115 82 196t199 81q95 0 172 -58q75 154 222.5 248t326.5 94 +q166 0 306 -80.5t221.5 -218.5t81.5 -301q0 -6 -0.5 -18t-0.5 -18zM468 498q0 -122 84 -193t208 -71q137 0 240 99q-16 20 -47.5 56.5t-43.5 50.5q-67 -65 -144 -65q-55 0 -93.5 33.5t-38.5 87.5q0 53 38.5 87t91.5 34q44 0 84.5 -21t73 -55t65 -75t69 -82t77 -75t97 -55 +t121.5 -21q121 0 204.5 71.5t83.5 190.5q0 121 -84 192t-207 71q-143 0 -241 -97l93 -108q66 64 142 64q52 0 92 -33t40 -84q0 -57 -37 -91.5t-94 -34.5q-43 0 -82.5 21t-72 55t-65.5 75t-69.5 82t-77.5 75t-96.5 55t-118.5 21q-122 0 -207 -70.5t-85 -189.5z" /> + <glyph glyph-name="_433" unicode="&#xf1cd;" horiz-adv-x="1792" +d="M896 1536q182 0 348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71zM896 1408q-190 0 -361 -90l194 -194q82 28 167 28t167 -28l194 194q-171 90 -361 90zM218 279l194 194 +q-28 82 -28 167t28 167l-194 194q-90 -171 -90 -361t90 -361zM896 -128q190 0 361 90l-194 194q-82 -28 -167 -28t-167 28l-194 -194q171 -90 361 -90zM896 256q159 0 271.5 112.5t112.5 271.5t-112.5 271.5t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5 +t271.5 -112.5zM1380 473l194 -194q90 171 90 361t-90 361l-194 -194q28 -82 28 -167t-28 -167z" /> + <glyph glyph-name="_434" unicode="&#xf1ce;" horiz-adv-x="1792" +d="M1760 640q0 -176 -68.5 -336t-184 -275.5t-275.5 -184t-336 -68.5t-336 68.5t-275.5 184t-184 275.5t-68.5 336q0 213 97 398.5t265 305.5t374 151v-228q-221 -45 -366.5 -221t-145.5 -406q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5 +t136.5 204t51 248.5q0 230 -145.5 406t-366.5 221v228q206 -31 374 -151t265 -305.5t97 -398.5z" /> + <glyph glyph-name="uniF1D0" unicode="&#xf1d0;" horiz-adv-x="1792" +d="M19 662q8 217 116 406t305 318h5q0 -1 -1 -3q-8 -8 -28 -33.5t-52 -76.5t-60 -110.5t-44.5 -135.5t-14 -150.5t39 -157.5t108.5 -154q50 -50 102 -69.5t90.5 -11.5t69.5 23.5t47 32.5l16 16q39 51 53 116.5t6.5 122.5t-21 107t-26.5 80l-14 29q-10 25 -30.5 49.5t-43 41 +t-43.5 29.5t-35 19l-13 6l104 115q39 -17 78 -52t59 -61l19 -27q1 48 -18.5 103.5t-40.5 87.5l-20 31l161 183l160 -181q-33 -46 -52.5 -102.5t-22.5 -90.5l-4 -33q22 37 61.5 72.5t67.5 52.5l28 17l103 -115q-44 -14 -85 -50t-60 -65l-19 -29q-31 -56 -48 -133.5t-7 -170 +t57 -156.5q33 -45 77.5 -60.5t85 -5.5t76 26.5t57.5 33.5l21 16q60 53 96.5 115t48.5 121.5t10 121.5t-18 118t-37 107.5t-45.5 93t-45 72t-34.5 47.5l-13 17q-14 13 -7 13l10 -3q40 -29 62.5 -46t62 -50t64 -58t58.5 -65t55.5 -77t45.5 -88t38 -103t23.5 -117t10.5 -136 +q3 -259 -108 -465t-312 -321t-456 -115q-185 0 -351 74t-283.5 198t-184 293t-60.5 353z" /> + <glyph glyph-name="uniF1D1" unicode="&#xf1d1;" horiz-adv-x="1792" +d="M874 -102v-66q-208 6 -385 109.5t-283 275.5l58 34q29 -49 73 -99l65 57q148 -168 368 -212l-17 -86q65 -12 121 -13zM276 428l-83 -28q22 -60 49 -112l-57 -33q-98 180 -98 385t98 385l57 -33q-30 -56 -49 -112l82 -28q-35 -100 -35 -212q0 -109 36 -212zM1528 251 +l58 -34q-106 -172 -283 -275.5t-385 -109.5v66q56 1 121 13l-17 86q220 44 368 212l65 -57q44 50 73 99zM1377 805l-233 -80q14 -42 14 -85t-14 -85l232 -80q-31 -92 -98 -169l-185 162q-57 -67 -147 -85l48 -241q-52 -10 -98 -10t-98 10l48 241q-90 18 -147 85l-185 -162 +q-67 77 -98 169l232 80q-14 42 -14 85t14 85l-233 80q33 93 99 169l185 -162q59 68 147 86l-48 240q44 10 98 10t98 -10l-48 -240q88 -18 147 -86l185 162q66 -76 99 -169zM874 1448v-66q-65 -2 -121 -13l17 -86q-220 -42 -368 -211l-65 56q-38 -42 -73 -98l-57 33 +q106 172 282 275.5t385 109.5zM1705 640q0 -205 -98 -385l-57 33q27 52 49 112l-83 28q36 103 36 212q0 112 -35 212l82 28q-19 56 -49 112l57 33q98 -180 98 -385zM1585 1063l-57 -33q-35 56 -73 98l-65 -56q-148 169 -368 211l17 86q-56 11 -121 13v66q209 -6 385 -109.5 +t282 -275.5zM1748 640q0 173 -67.5 331t-181.5 272t-272 181.5t-331 67.5t-331 -67.5t-272 -181.5t-181.5 -272t-67.5 -331t67.5 -331t181.5 -272t272 -181.5t331 -67.5t331 67.5t272 181.5t181.5 272t67.5 331zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71 +t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" /> + <glyph glyph-name="uniF1D2" unicode="&#xf1d2;" +d="M582 228q0 -66 -93 -66q-107 0 -107 63q0 64 98 64q102 0 102 -61zM546 694q0 -85 -74 -85q-77 0 -77 84q0 90 77 90q36 0 55 -25.5t19 -63.5zM712 769v125q-78 -29 -135 -29q-50 29 -110 29q-86 0 -145 -57t-59 -143q0 -50 29.5 -102t73.5 -67v-3q-38 -17 -38 -85 +q0 -53 41 -77v-3q-113 -37 -113 -139q0 -45 20 -78.5t54 -51t72 -25.5t81 -8q224 0 224 188q0 67 -48 99t-126 46q-27 5 -51.5 20.5t-24.5 39.5q0 44 49 52q77 15 122 70t45 134q0 24 -10 52q37 9 49 13zM771 350h137q-2 27 -2 82v387q0 46 2 69h-137q3 -23 3 -71v-392 +q0 -50 -3 -75zM1280 366v121q-30 -21 -68 -21q-53 0 -53 82v225h52q9 0 26.5 -1t26.5 -1v117h-105q0 82 3 102h-140q4 -24 4 -55v-47h-60v-117q36 3 37 3q3 0 11 -0.5t12 -0.5v-2h-2v-217q0 -37 2.5 -64t11.5 -56.5t24.5 -48.5t43.5 -31t66 -12q64 0 108 24zM924 1072 +q0 36 -24 63.5t-60 27.5t-60.5 -27t-24.5 -64q0 -36 25 -62.5t60 -26.5t59.5 27t24.5 62zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="_438" unicode="&#xf1d3;" horiz-adv-x="1792" +d="M595 22q0 100 -165 100q-158 0 -158 -104q0 -101 172 -101q151 0 151 105zM536 777q0 61 -30 102t-89 41q-124 0 -124 -145q0 -135 124 -135q119 0 119 137zM805 1101v-202q-36 -12 -79 -22q16 -43 16 -84q0 -127 -73 -216.5t-197 -112.5q-40 -8 -59.5 -27t-19.5 -58 +q0 -31 22.5 -51.5t58 -32t78.5 -22t86 -25.5t78.5 -37.5t58 -64t22.5 -98.5q0 -304 -363 -304q-69 0 -130 12.5t-116 41t-87.5 82t-32.5 127.5q0 165 182 225v4q-67 41 -67 126q0 109 63 137v4q-72 24 -119.5 108.5t-47.5 165.5q0 139 95 231.5t235 92.5q96 0 178 -47 +q98 0 218 47zM1123 220h-222q4 45 4 134v609q0 94 -4 128h222q-4 -33 -4 -124v-613q0 -89 4 -134zM1724 442v-196q-71 -39 -174 -39q-62 0 -107 20t-70 50t-39.5 78t-18.5 92t-4 103v351h2v4q-7 0 -19 1t-18 1q-21 0 -59 -6v190h96v76q0 54 -6 89h227q-6 -41 -6 -165h171 +v-190q-15 0 -43.5 2t-42.5 2h-85v-365q0 -131 87 -131q61 0 109 33zM1148 1389q0 -58 -39 -101.5t-96 -43.5q-58 0 -98 43.5t-40 101.5q0 59 39.5 103t98.5 44q58 0 96.5 -44.5t38.5 -102.5z" /> + <glyph glyph-name="_439" unicode="&#xf1d4;" +d="M809 532l266 499h-112l-157 -312q-24 -48 -44 -92l-42 92l-155 312h-120l263 -493v-324h101v318zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="uniF1D5" unicode="&#xf1d5;" horiz-adv-x="1280" +d="M842 964q0 -80 -57 -136.5t-136 -56.5q-60 0 -111 35q-62 -67 -115 -146q-247 -371 -202 -859q1 -22 -12.5 -38.5t-34.5 -18.5h-5q-20 0 -35 13.5t-17 33.5q-14 126 -3.5 247.5t29.5 217t54 186t69 155.5t74 125q61 90 132 165q-16 35 -16 77q0 80 56.5 136.5t136.5 56.5 +t136.5 -56.5t56.5 -136.5zM1223 953q0 -158 -78 -292t-212.5 -212t-292.5 -78q-64 0 -131 14q-21 5 -32.5 23.5t-6.5 39.5q5 20 23 31.5t39 7.5q51 -13 108 -13q97 0 186 38t153 102t102 153t38 186t-38 186t-102 153t-153 102t-186 38t-186 -38t-153 -102t-102 -153 +t-38 -186q0 -114 52 -218q10 -20 3.5 -40t-25.5 -30t-39.5 -3t-30.5 26q-64 123 -64 265q0 119 46.5 227t124.5 186t186 124t226 46q158 0 292.5 -78t212.5 -212.5t78 -292.5z" /> + <glyph glyph-name="uniF1D6" unicode="&#xf1d6;" horiz-adv-x="1792" +d="M270 730q-8 19 -8 52q0 20 11 49t24 45q-1 22 7.5 53t22.5 43q0 139 92.5 288.5t217.5 209.5q139 66 324 66q133 0 266 -55q49 -21 90 -48t71 -56t55 -68t42 -74t32.5 -84.5t25.5 -89.5t22 -98l1 -5q55 -83 55 -150q0 -14 -9 -40t-9 -38q0 -1 1.5 -3.5t3.5 -5t2 -3.5 +q77 -114 120.5 -214.5t43.5 -208.5q0 -43 -19.5 -100t-55.5 -57q-9 0 -19.5 7.5t-19 17.5t-19 26t-16 26.5t-13.5 26t-9 17.5q-1 1 -3 1l-5 -4q-59 -154 -132 -223q20 -20 61.5 -38.5t69 -41.5t35.5 -65q-2 -4 -4 -16t-7 -18q-64 -97 -302 -97q-53 0 -110.5 9t-98 20 +t-104.5 30q-15 5 -23 7q-14 4 -46 4.5t-40 1.5q-41 -45 -127.5 -65t-168.5 -20q-35 0 -69 1.5t-93 9t-101 20.5t-74.5 40t-32.5 64q0 40 10 59.5t41 48.5q11 2 40.5 13t49.5 12q4 0 14 2q2 2 2 4l-2 3q-48 11 -108 105.5t-73 156.5l-5 3q-4 0 -12 -20q-18 -41 -54.5 -74.5 +t-77.5 -37.5h-1q-4 0 -6 4.5t-5 5.5q-23 54 -23 100q0 275 252 466z" /> + <glyph glyph-name="uniF1D7" unicode="&#xf1d7;" horiz-adv-x="2048" +d="M580 1075q0 41 -25 66t-66 25q-43 0 -76 -25.5t-33 -65.5q0 -39 33 -64.5t76 -25.5q41 0 66 24.5t25 65.5zM1323 568q0 28 -25.5 50t-65.5 22q-27 0 -49.5 -22.5t-22.5 -49.5q0 -28 22.5 -50.5t49.5 -22.5q40 0 65.5 22t25.5 51zM1087 1075q0 41 -24.5 66t-65.5 25 +q-43 0 -76 -25.5t-33 -65.5q0 -39 33 -64.5t76 -25.5q41 0 65.5 24.5t24.5 65.5zM1722 568q0 28 -26 50t-65 22q-27 0 -49.5 -22.5t-22.5 -49.5q0 -28 22.5 -50.5t49.5 -22.5q39 0 65 22t26 51zM1456 965q-31 4 -70 4q-169 0 -311 -77t-223.5 -208.5t-81.5 -287.5 +q0 -78 23 -152q-35 -3 -68 -3q-26 0 -50 1.5t-55 6.5t-44.5 7t-54.5 10.5t-50 10.5l-253 -127l72 218q-290 203 -290 490q0 169 97.5 311t264 223.5t363.5 81.5q176 0 332.5 -66t262 -182.5t136.5 -260.5zM2048 404q0 -117 -68.5 -223.5t-185.5 -193.5l55 -181l-199 109 +q-150 -37 -218 -37q-169 0 -311 70.5t-223.5 191.5t-81.5 264t81.5 264t223.5 191.5t311 70.5q161 0 303 -70.5t227.5 -192t85.5 -263.5z" /> + <glyph glyph-name="_443" unicode="&#xf1d8;" horiz-adv-x="1792" +d="M1764 1525q33 -24 27 -64l-256 -1536q-5 -29 -32 -45q-14 -8 -31 -8q-11 0 -24 5l-453 185l-242 -295q-18 -23 -49 -23q-13 0 -22 4q-19 7 -30.5 23.5t-11.5 36.5v349l864 1059l-1069 -925l-395 162q-37 14 -40 55q-2 40 32 59l1664 960q15 9 32 9q20 0 36 -11z" /> + <glyph glyph-name="_444" unicode="&#xf1d9;" horiz-adv-x="1792" +d="M1764 1525q33 -24 27 -64l-256 -1536q-5 -29 -32 -45q-14 -8 -31 -8q-11 0 -24 5l-527 215l-298 -327q-18 -21 -47 -21q-14 0 -23 4q-19 7 -30 23.5t-11 36.5v452l-472 193q-37 14 -40 55q-3 39 32 59l1664 960q35 21 68 -2zM1422 26l221 1323l-1434 -827l336 -137 +l863 639l-478 -797z" /> + <glyph glyph-name="_445" unicode="&#xf1da;" +d="M1536 640q0 -156 -61 -298t-164 -245t-245 -164t-298 -61q-172 0 -327 72.5t-264 204.5q-7 10 -6.5 22.5t8.5 20.5l137 138q10 9 25 9q16 -2 23 -12q73 -95 179 -147t225 -52q104 0 198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5t-40.5 198.5t-109.5 163.5 +t-163.5 109.5t-198.5 40.5q-98 0 -188 -35.5t-160 -101.5l137 -138q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19t-19 45v448q0 42 40 59q39 17 69 -14l130 -129q107 101 244.5 156.5t284.5 55.5q156 0 298 -61t245 -164t164 -245t61 -298zM896 928v-448q0 -14 -9 -23 +t-23 -9h-320q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23z" /> + <glyph glyph-name="_446" unicode="&#xf1db;" +d="M768 1280q-130 0 -248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5t-51 248.5t-136.5 204t-204 136.5t-248.5 51zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103 +t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="_447" unicode="&#xf1dc;" horiz-adv-x="1792" +d="M1682 -128q-44 0 -132.5 3.5t-133.5 3.5q-44 0 -132 -3.5t-132 -3.5q-24 0 -37 20.5t-13 45.5q0 31 17 46t39 17t51 7t45 15q33 21 33 140l-1 391q0 21 -1 31q-13 4 -50 4h-675q-38 0 -51 -4q-1 -10 -1 -31l-1 -371q0 -142 37 -164q16 -10 48 -13t57 -3.5t45 -15 +t20 -45.5q0 -26 -12.5 -48t-36.5 -22q-47 0 -139.5 3.5t-138.5 3.5q-43 0 -128 -3.5t-127 -3.5q-23 0 -35.5 21t-12.5 45q0 30 15.5 45t36 17.5t47.5 7.5t42 15q33 23 33 143l-1 57v813q0 3 0.5 26t0 36.5t-1.5 38.5t-3.5 42t-6.5 36.5t-11 31.5t-16 18q-15 10 -45 12t-53 2 +t-41 14t-18 45q0 26 12 48t36 22q46 0 138.5 -3.5t138.5 -3.5q42 0 126.5 3.5t126.5 3.5q25 0 37.5 -22t12.5 -48q0 -30 -17 -43.5t-38.5 -14.5t-49.5 -4t-43 -13q-35 -21 -35 -160l1 -320q0 -21 1 -32q13 -3 39 -3h699q25 0 38 3q1 11 1 32l1 320q0 139 -35 160 +q-18 11 -58.5 12.5t-66 13t-25.5 49.5q0 26 12.5 48t37.5 22q44 0 132 -3.5t132 -3.5q43 0 129 3.5t129 3.5q25 0 37.5 -22t12.5 -48q0 -30 -17.5 -44t-40 -14.5t-51.5 -3t-44 -12.5q-35 -23 -35 -161l1 -943q0 -119 34 -140q16 -10 46 -13.5t53.5 -4.5t41.5 -15.5t18 -44.5 +q0 -26 -12 -48t-36 -22z" /> + <glyph glyph-name="_448" unicode="&#xf1dd;" horiz-adv-x="1280" +d="M1278 1347v-73q0 -29 -18.5 -61t-42.5 -32q-50 0 -54 -1q-26 -6 -32 -31q-3 -11 -3 -64v-1152q0 -25 -18 -43t-43 -18h-108q-25 0 -43 18t-18 43v1218h-143v-1218q0 -25 -17.5 -43t-43.5 -18h-108q-26 0 -43.5 18t-17.5 43v496q-147 12 -245 59q-126 58 -192 179 +q-64 117 -64 259q0 166 88 286q88 118 209 159q111 37 417 37h479q25 0 43 -18t18 -43z" /> + <glyph glyph-name="_449" unicode="&#xf1de;" +d="M352 128v-128h-352v128h352zM704 256q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h256zM864 640v-128h-864v128h864zM224 1152v-128h-224v128h224zM1536 128v-128h-736v128h736zM576 1280q26 0 45 -19t19 -45v-256 +q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h256zM1216 768q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h256zM1536 640v-128h-224v128h224zM1536 1152v-128h-864v128h864z" /> + <glyph glyph-name="uniF1E0" unicode="&#xf1e0;" +d="M1216 512q133 0 226.5 -93.5t93.5 -226.5t-93.5 -226.5t-226.5 -93.5t-226.5 93.5t-93.5 226.5q0 12 2 34l-360 180q-92 -86 -218 -86q-133 0 -226.5 93.5t-93.5 226.5t93.5 226.5t226.5 93.5q126 0 218 -86l360 180q-2 22 -2 34q0 133 93.5 226.5t226.5 93.5 +t226.5 -93.5t93.5 -226.5t-93.5 -226.5t-226.5 -93.5q-126 0 -218 86l-360 -180q2 -22 2 -34t-2 -34l360 -180q92 86 218 86z" /> + <glyph glyph-name="_451" unicode="&#xf1e1;" +d="M1280 341q0 88 -62.5 151t-150.5 63q-84 0 -145 -58l-241 120q2 16 2 23t-2 23l241 120q61 -58 145 -58q88 0 150.5 63t62.5 151t-62.5 150.5t-150.5 62.5t-151 -62.5t-63 -150.5q0 -7 2 -23l-241 -120q-62 57 -145 57q-88 0 -150.5 -62.5t-62.5 -150.5t62.5 -150.5 +t150.5 -62.5q83 0 145 57l241 -120q-2 -16 -2 -23q0 -88 63 -150.5t151 -62.5t150.5 62.5t62.5 150.5zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="_452" unicode="&#xf1e2;" horiz-adv-x="1792" +d="M571 947q-10 25 -34 35t-49 0q-108 -44 -191 -127t-127 -191q-10 -25 0 -49t35 -34q13 -5 24 -5q42 0 60 40q34 84 98.5 148.5t148.5 98.5q25 11 35 35t0 49zM1513 1303l46 -46l-244 -243l68 -68q19 -19 19 -45.5t-19 -45.5l-64 -64q89 -161 89 -343q0 -143 -55.5 -273.5 +t-150 -225t-225 -150t-273.5 -55.5t-273.5 55.5t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5q182 0 343 -89l64 64q19 19 45.5 19t45.5 -19l68 -68zM1521 1359q-10 -10 -22 -10q-13 0 -23 10l-91 90q-9 10 -9 23t9 23q10 9 23 9t23 -9l90 -91 +q10 -9 10 -22.5t-10 -22.5zM1751 1129q-11 -9 -23 -9t-23 9l-90 91q-10 9 -10 22.5t10 22.5q9 10 22.5 10t22.5 -10l91 -90q9 -10 9 -23t-9 -23zM1792 1312q0 -14 -9 -23t-23 -9h-96q-14 0 -23 9t-9 23t9 23t23 9h96q14 0 23 -9t9 -23zM1600 1504v-96q0 -14 -9 -23t-23 -9 +t-23 9t-9 23v96q0 14 9 23t23 9t23 -9t9 -23zM1751 1449l-91 -90q-10 -10 -22 -10q-13 0 -23 10q-10 9 -10 22.5t10 22.5l90 91q10 9 23 9t23 -9q9 -10 9 -23t-9 -23z" /> + <glyph glyph-name="_453" unicode="&#xf1e3;" horiz-adv-x="1792" +d="M609 720l287 208l287 -208l-109 -336h-355zM896 1536q182 0 348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71zM1515 186q149 203 149 454v3l-102 -89l-240 224l63 323 +l134 -12q-150 206 -389 282l53 -124l-287 -159l-287 159l53 124q-239 -76 -389 -282l135 12l62 -323l-240 -224l-102 89v-3q0 -251 149 -454l30 132l326 -40l139 -298l-116 -69q117 -39 240 -39t240 39l-116 69l139 298l326 40z" /> + <glyph glyph-name="_454" unicode="&#xf1e4;" horiz-adv-x="1792" +d="M448 224v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM256 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM832 224v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23 +v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM640 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM66 768q-28 0 -47 19t-19 46v129h514v-129q0 -27 -19 -46t-46 -19h-383zM1216 224v-192q0 -14 -9 -23t-23 -9h-192 +q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1024 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1600 224v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23 +zM1408 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1792 1016v-13h-514v10q0 104 -382 102q-382 -1 -382 -102v-10h-514v13q0 17 8.5 43t34 64t65.5 75.5t110.5 76t160 67.5t224 47.5t293.5 18.5t293 -18.5t224 -47.5 +t160.5 -67.5t110.5 -76t65.5 -75.5t34 -64t8.5 -43zM1792 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1792 962v-129q0 -27 -19 -46t-46 -19h-384q-27 0 -46 19t-19 46v129h514z" /> + <glyph glyph-name="_455" unicode="&#xf1e5;" horiz-adv-x="1792" +d="M704 1216v-768q0 -26 -19 -45t-45 -19v-576q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v512l249 873q7 23 31 23h424zM1024 1216v-704h-256v704h256zM1792 320v-512q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v576q-26 0 -45 19t-19 45v768h424q24 0 31 -23z +M736 1504v-224h-352v224q0 14 9 23t23 9h288q14 0 23 -9t9 -23zM1408 1504v-224h-352v224q0 14 9 23t23 9h288q14 0 23 -9t9 -23z" /> + <glyph glyph-name="_456" unicode="&#xf1e6;" horiz-adv-x="1792" +d="M1755 1083q37 -38 37 -90.5t-37 -90.5l-401 -400l150 -150l-160 -160q-163 -163 -389.5 -186.5t-411.5 100.5l-362 -362h-181v181l362 362q-124 185 -100.5 411.5t186.5 389.5l160 160l150 -150l400 401q38 37 91 37t90 -37t37 -90.5t-37 -90.5l-400 -401l234 -234 +l401 400q38 37 91 37t90 -37z" /> + <glyph glyph-name="_457" unicode="&#xf1e7;" horiz-adv-x="1792" +d="M873 796q0 -83 -63.5 -142.5t-152.5 -59.5t-152.5 59.5t-63.5 142.5q0 84 63.5 143t152.5 59t152.5 -59t63.5 -143zM1375 796q0 -83 -63 -142.5t-153 -59.5q-89 0 -152.5 59.5t-63.5 142.5q0 84 63.5 143t152.5 59q90 0 153 -59t63 -143zM1600 616v667q0 87 -32 123.5 +t-111 36.5h-1112q-83 0 -112.5 -34t-29.5 -126v-673q43 -23 88.5 -40t81 -28t81 -18.5t71 -11t70 -4t58.5 -0.5t56.5 2t44.5 2q68 1 95 -27q6 -6 10 -9q26 -25 61 -51q7 91 118 87q5 0 36.5 -1.5t43 -2t45.5 -1t53 1t54.5 4.5t61 8.5t62 13.5t67 19.5t67.5 27t72 34.5z +M1763 621q-121 -149 -372 -252q84 -285 -23 -465q-66 -113 -183 -148q-104 -32 -182 15q-86 51 -82 164l-1 326v1q-8 2 -24.5 6t-23.5 5l-1 -338q4 -114 -83 -164q-79 -47 -183 -15q-117 36 -182 150q-105 180 -22 463q-251 103 -372 252q-25 37 -4 63t60 -1q4 -2 11.5 -7 +t10.5 -8v694q0 72 47 123t114 51h1257q67 0 114 -51t47 -123v-694l21 15q39 27 60 1t-4 -63z" /> + <glyph glyph-name="_458" unicode="&#xf1e8;" horiz-adv-x="1792" +d="M896 1102v-434h-145v434h145zM1294 1102v-434h-145v434h145zM1294 342l253 254v795h-1194v-1049h326v-217l217 217h398zM1692 1536v-1013l-434 -434h-326l-217 -217h-217v217h-398v1158l109 289h1483z" /> + <glyph glyph-name="_459" unicode="&#xf1e9;" +d="M773 217v-127q-1 -292 -6 -305q-12 -32 -51 -40q-54 -9 -181.5 38t-162.5 89q-13 15 -17 36q-1 12 4 26q4 10 34 47t181 216q1 0 60 70q15 19 39.5 24.5t49.5 -3.5q24 -10 37.5 -29t12.5 -42zM624 468q-3 -55 -52 -70l-120 -39q-275 -88 -292 -88q-35 2 -54 36 +q-12 25 -17 75q-8 76 1 166.5t30 124.5t56 32q13 0 202 -77q71 -29 115 -47l84 -34q23 -9 35.5 -30.5t11.5 -48.5zM1450 171q-7 -54 -91.5 -161t-135.5 -127q-37 -14 -63 7q-14 10 -184 287l-47 77q-14 21 -11.5 46t19.5 46q35 43 83 26q1 -1 119 -40q203 -66 242 -79.5 +t47 -20.5q28 -22 22 -61zM778 803q5 -102 -54 -122q-58 -17 -114 71l-378 598q-8 35 19 62q41 43 207.5 89.5t224.5 31.5q40 -10 49 -45q3 -18 22 -305.5t24 -379.5zM1440 695q3 -39 -26 -59q-15 -10 -329 -86q-67 -15 -91 -23l1 2q-23 -6 -46 4t-37 32q-30 47 0 87 +q1 1 75 102q125 171 150 204t34 39q28 19 65 2q48 -23 123 -133.5t81 -167.5v-3z" /> + <glyph glyph-name="_460" unicode="&#xf1ea;" horiz-adv-x="2048" +d="M1024 1024h-384v-384h384v384zM1152 384v-128h-640v128h640zM1152 1152v-640h-640v640h640zM1792 384v-128h-512v128h512zM1792 640v-128h-512v128h512zM1792 896v-128h-512v128h512zM1792 1152v-128h-512v128h512zM256 192v960h-128v-960q0 -26 19 -45t45 -19t45 19 +t19 45zM1920 192v1088h-1536v-1088q0 -33 -11 -64h1483q26 0 45 19t19 45zM2048 1408v-1216q0 -80 -56 -136t-136 -56h-1664q-80 0 -136 56t-56 136v1088h256v128h1792z" /> + <glyph glyph-name="_461" unicode="&#xf1eb;" horiz-adv-x="2048" +d="M1024 13q-20 0 -93 73.5t-73 93.5q0 32 62.5 54t103.5 22t103.5 -22t62.5 -54q0 -20 -73 -93.5t-93 -73.5zM1294 284q-2 0 -40 25t-101.5 50t-128.5 25t-128.5 -25t-101 -50t-40.5 -25q-18 0 -93.5 75t-75.5 93q0 13 10 23q78 77 196 121t233 44t233 -44t196 -121 +q10 -10 10 -23q0 -18 -75.5 -93t-93.5 -75zM1567 556q-11 0 -23 8q-136 105 -252 154.5t-268 49.5q-85 0 -170.5 -22t-149 -53t-113.5 -62t-79 -53t-31 -22q-17 0 -92 75t-75 93q0 12 10 22q132 132 320 205t380 73t380 -73t320 -205q10 -10 10 -22q0 -18 -75 -93t-92 -75z +M1838 827q-11 0 -22 9q-179 157 -371.5 236.5t-420.5 79.5t-420.5 -79.5t-371.5 -236.5q-11 -9 -22 -9q-17 0 -92.5 75t-75.5 93q0 13 10 23q187 186 445 288t527 102t527 -102t445 -288q10 -10 10 -23q0 -18 -75.5 -93t-92.5 -75z" /> + <glyph glyph-name="_462" unicode="&#xf1ec;" horiz-adv-x="1792" +d="M384 0q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM768 0q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM384 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5 +t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1152 0q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM768 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5 +t37.5 90.5zM384 768q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1152 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM768 768q0 53 -37.5 90.5t-90.5 37.5 +t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1536 0v384q0 52 -38 90t-90 38t-90 -38t-38 -90v-384q0 -52 38 -90t90 -38t90 38t38 90zM1152 768q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5z +M1536 1088v256q0 26 -19 45t-45 19h-1280q-26 0 -45 -19t-19 -45v-256q0 -26 19 -45t45 -19h1280q26 0 45 19t19 45zM1536 768q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1664 1408v-1536q0 -52 -38 -90t-90 -38 +h-1408q-52 0 -90 38t-38 90v1536q0 52 38 90t90 38h1408q52 0 90 -38t38 -90z" /> + <glyph glyph-name="_463" unicode="&#xf1ed;" +d="M1519 890q18 -84 -4 -204q-87 -444 -565 -444h-44q-25 0 -44 -16.5t-24 -42.5l-4 -19l-55 -346l-2 -15q-5 -26 -24.5 -42.5t-44.5 -16.5h-251q-21 0 -33 15t-9 36q9 56 26.5 168t26.5 168t27 167.5t27 167.5q5 37 43 37h131q133 -2 236 21q175 39 287 144q102 95 155 246 +q24 70 35 133q1 6 2.5 7.5t3.5 1t6 -3.5q79 -59 98 -162zM1347 1172q0 -107 -46 -236q-80 -233 -302 -315q-113 -40 -252 -42q0 -1 -90 -1l-90 1q-100 0 -118 -96q-2 -8 -85 -530q-1 -10 -12 -10h-295q-22 0 -36.5 16.5t-11.5 38.5l232 1471q5 29 27.5 48t51.5 19h598 +q34 0 97.5 -13t111.5 -32q107 -41 163.5 -123t56.5 -196z" /> + <glyph glyph-name="_464" unicode="&#xf1ee;" horiz-adv-x="1792" +d="M441 864q33 0 52 -26q266 -364 362 -774h-446q-127 441 -367 749q-12 16 -3 33.5t29 17.5h373zM1000 507q-49 -199 -125 -393q-79 310 -256 594q40 221 44 449q211 -340 337 -650zM1099 1216q235 -324 384.5 -698.5t184.5 -773.5h-451q-41 665 -553 1472h435zM1792 640 +q0 -424 -101 -812q-67 560 -359 1083q-25 301 -106 584q-4 16 5.5 28.5t25.5 12.5h359q21 0 38.5 -13t22.5 -33q115 -409 115 -850z" /> + <glyph glyph-name="uniF1F0" unicode="&#xf1f0;" horiz-adv-x="2304" +d="M1975 546h-138q14 37 66 179l3 9q4 10 10 26t9 26l12 -55zM531 611l-58 295q-11 54 -75 54h-268l-2 -13q311 -79 403 -336zM710 960l-162 -438l-17 89q-26 70 -85 129.5t-131 88.5l135 -510h175l261 641h-176zM849 318h166l104 642h-166zM1617 944q-69 27 -149 27 +q-123 0 -201 -59t-79 -153q-1 -102 145 -174q48 -23 67 -41t19 -39q0 -30 -30 -46t-69 -16q-86 0 -156 33l-22 11l-23 -144q74 -34 185 -34q130 -1 208.5 59t80.5 160q0 106 -140 174q-49 25 -71 42t-22 38q0 22 24.5 38.5t70.5 16.5q70 1 124 -24l15 -8zM2042 960h-128 +q-65 0 -87 -54l-246 -588h174l35 96h212q5 -22 20 -96h154zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" /> + <glyph glyph-name="_466" unicode="&#xf1f1;" horiz-adv-x="2304" +d="M1119 1195q-128 85 -281 85q-103 0 -197.5 -40.5t-162.5 -108.5t-108.5 -162t-40.5 -197q0 -104 40.5 -198t108.5 -162t162 -108.5t198 -40.5q153 0 281 85q-131 107 -178 265.5t0.5 316.5t177.5 265zM1152 1171q-126 -99 -172 -249.5t-0.5 -300.5t172.5 -249 +q127 99 172.5 249t-0.5 300.5t-172 249.5zM1185 1195q130 -107 177.5 -265.5t0.5 -317t-178 -264.5q128 -85 281 -85q104 0 198 40.5t162 108.5t108.5 162t40.5 198q0 103 -40.5 197t-108.5 162t-162.5 108.5t-197.5 40.5q-153 0 -281 -85zM1926 473h7v3h-17v-3h7v-17h3v17z +M1955 456h4v20h-5l-6 -13l-6 13h-5v-20h3v15l6 -13h4l5 13v-15zM1947 16v-2h-2h-3v3h3h2v-1zM1947 7h3l-4 5h2l1 1q1 1 1 3t-1 3l-1 1h-3h-6v-13h3v5h1zM685 75q0 19 11 31t30 12q18 0 29 -12.5t11 -30.5q0 -19 -11 -31t-29 -12q-19 0 -30 12t-11 31zM1158 119q30 0 35 -32 +h-70q5 32 35 32zM1514 75q0 19 11 31t29 12t29.5 -12.5t11.5 -30.5q0 -19 -11 -31t-30 -12q-18 0 -29 12t-11 31zM1786 75q0 18 11.5 30.5t29.5 12.5t29.5 -12.5t11.5 -30.5q0 -19 -11.5 -31t-29.5 -12t-29.5 12.5t-11.5 30.5zM1944 3q-2 0 -4 1q-1 0 -3 2t-2 3q-1 2 -1 4 +q0 3 1 4q0 2 2 4l1 1q2 0 2 1q2 1 4 1q3 0 4 -1l4 -2l2 -4v-1q1 -2 1 -3l-1 -1v-3t-1 -1l-1 -2q-2 -2 -4 -2q-1 -1 -4 -1zM599 7h30v85q0 24 -14.5 38.5t-39.5 15.5q-32 0 -47 -24q-14 24 -45 24q-24 0 -39 -20v16h-30v-135h30v75q0 36 33 36q30 0 30 -36v-75h29v75 +q0 36 33 36q30 0 30 -36v-75zM765 7h29v68v67h-29v-16q-17 20 -43 20q-29 0 -48 -20t-19 -51t19 -51t48 -20q28 0 43 20v-17zM943 48q0 34 -47 40l-14 2q-23 4 -23 14q0 15 25 15q23 0 43 -11l12 24q-22 14 -55 14q-26 0 -41 -12t-15 -32q0 -33 47 -39l13 -2q24 -4 24 -14 +q0 -17 -31 -17q-25 0 -45 14l-13 -23q25 -17 58 -17q29 0 45.5 12t16.5 32zM1073 14l-8 25q-13 -7 -26 -7q-19 0 -19 22v61h48v27h-48v41h-30v-41h-28v-27h28v-61q0 -50 47 -50q21 0 36 10zM1159 146q-29 0 -48 -20t-19 -51q0 -32 19.5 -51.5t49.5 -19.5q33 0 55 19l-14 22 +q-18 -15 -39 -15q-34 0 -41 33h101v12q0 32 -18 51.5t-46 19.5zM1318 146q-23 0 -35 -20v16h-30v-135h30v76q0 35 29 35q10 0 18 -4l9 28q-9 4 -21 4zM1348 75q0 -31 19.5 -51t52.5 -20q29 0 48 16l-14 24q-18 -13 -35 -12q-18 0 -29.5 12t-11.5 31t11.5 31t29.5 12 +q19 0 35 -12l14 24q-20 16 -48 16q-33 0 -52.5 -20t-19.5 -51zM1593 7h30v68v67h-30v-16q-15 20 -42 20q-29 0 -48.5 -20t-19.5 -51t19.5 -51t48.5 -20q28 0 42 20v-17zM1726 146q-23 0 -35 -20v16h-29v-135h29v76q0 35 29 35q10 0 18 -4l9 28q-8 4 -21 4zM1866 7h29v68v122 +h-29v-71q-15 20 -43 20t-47.5 -20.5t-19.5 -50.5t19.5 -50.5t47.5 -20.5q29 0 43 20v-17zM1944 27l-2 -1h-3q-2 -1 -4 -3q-3 -1 -3 -4q-1 -2 -1 -6q0 -3 1 -5q0 -2 3 -4q2 -2 4 -3t5 -1q4 0 6 1q0 1 2 2l2 1q1 1 3 4q1 2 1 5q0 4 -1 6q-1 1 -3 4q0 1 -2 2l-2 1q-1 0 -3 0.5 +t-3 0.5zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" /> + <glyph glyph-name="_467" unicode="&#xf1f2;" horiz-adv-x="2304" +d="M313 759q0 -51 -36 -84q-29 -26 -89 -26h-17v220h17q61 0 89 -27q36 -31 36 -83zM2089 824q0 -52 -64 -52h-19v101h20q63 0 63 -49zM380 759q0 74 -50 120.5t-129 46.5h-95v-333h95q74 0 119 38q60 51 60 128zM410 593h65v333h-65v-333zM730 694q0 40 -20.5 62t-75.5 42 +q-29 10 -39.5 19t-10.5 23q0 16 13.5 26.5t34.5 10.5q29 0 53 -27l34 44q-41 37 -98 37q-44 0 -74 -27.5t-30 -67.5q0 -35 18 -55.5t64 -36.5q37 -13 45 -19q19 -12 19 -34q0 -20 -14 -33.5t-36 -13.5q-48 0 -71 44l-42 -40q44 -64 115 -64q51 0 83 30.5t32 79.5zM1008 604 +v77q-37 -37 -78 -37q-49 0 -80.5 32.5t-31.5 82.5q0 48 31.5 81.5t77.5 33.5q43 0 81 -38v77q-40 20 -80 20q-74 0 -125.5 -50.5t-51.5 -123.5t51 -123.5t125 -50.5q42 0 81 19zM2240 0v527q-65 -40 -144.5 -84t-237.5 -117t-329.5 -137.5t-417.5 -134.5t-504 -118h1569 +q26 0 45 19t19 45zM1389 757q0 75 -53 128t-128 53t-128 -53t-53 -128t53 -128t128 -53t128 53t53 128zM1541 584l144 342h-71l-90 -224l-89 224h-71l142 -342h35zM1714 593h184v56h-119v90h115v56h-115v74h119v57h-184v-333zM2105 593h80l-105 140q76 16 76 94q0 47 -31 73 +t-87 26h-97v-333h65v133h9zM2304 1274v-1268q0 -56 -38.5 -95t-93.5 -39h-2040q-55 0 -93.5 39t-38.5 95v1268q0 56 38.5 95t93.5 39h2040q55 0 93.5 -39t38.5 -95z" /> + <glyph glyph-name="f1f3" unicode="&#xf1f3;" horiz-adv-x="2304" +d="M119 854h89l-45 108zM740 328l74 79l-70 79h-163v-49h142v-55h-142v-54h159zM898 406l99 -110v217zM1186 453q0 33 -40 33h-84v-69h83q41 0 41 36zM1475 457q0 29 -42 29h-82v-61h81q43 0 43 32zM1197 923q0 29 -42 29h-82v-60h81q43 0 43 31zM1656 854h89l-44 108z +M699 1009v-271h-66v212l-94 -212h-57l-94 212v-212h-132l-25 60h-135l-25 -60h-70l116 271h96l110 -257v257h106l85 -184l77 184h108zM1255 453q0 -20 -5.5 -35t-14 -25t-22.5 -16.5t-26 -10t-31.5 -4.5t-31.5 -1t-32.5 0.5t-29.5 0.5v-91h-126l-80 90l-83 -90h-256v271h260 +l80 -89l82 89h207q109 0 109 -89zM964 794v-56h-217v271h217v-57h-152v-49h148v-55h-148v-54h152zM2304 235v-229q0 -55 -38.5 -94.5t-93.5 -39.5h-2040q-55 0 -93.5 39.5t-38.5 94.5v678h111l25 61h55l25 -61h218v46l19 -46h113l20 47v-47h541v99l10 1q10 0 10 -14v-86h279 +v23q23 -12 55 -18t52.5 -6.5t63 0.5t51.5 1l25 61h56l25 -61h227v58l34 -58h182v378h-180v-44l-25 44h-185v-44l-23 44h-249q-69 0 -109 -22v22h-172v-22q-24 22 -73 22h-628l-43 -97l-43 97h-198v-44l-22 44h-169l-78 -179v391q0 55 38.5 94.5t93.5 39.5h2040 +q55 0 93.5 -39.5t38.5 -94.5v-678h-120q-51 0 -81 -22v22h-177q-55 0 -78 -22v22h-316v-22q-31 22 -87 22h-209v-22q-23 22 -91 22h-234l-54 -58l-50 58h-349v-378h343l55 59l52 -59h211v89h21q59 0 90 13v-102h174v99h8q8 0 10 -2t2 -10v-87h529q57 0 88 24v-24h168 +q60 0 95 17zM1546 469q0 -23 -12 -43t-34 -29q25 -9 34 -26t9 -46v-54h-65v45q0 33 -12 43.5t-46 10.5h-69v-99h-65v271h154q48 0 77 -15t29 -58zM1269 936q0 -24 -12.5 -44t-33.5 -29q26 -9 34.5 -25.5t8.5 -46.5v-53h-65q0 9 0.5 26.5t0 25t-3 18.5t-8.5 16t-17.5 8.5 +t-29.5 3.5h-70v-98h-64v271l153 -1q49 0 78 -14.5t29 -57.5zM1798 327v-56h-216v271h216v-56h-151v-49h148v-55h-148v-54zM1372 1009v-271h-66v271h66zM2065 357q0 -86 -102 -86h-126v58h126q34 0 34 25q0 16 -17 21t-41.5 5t-49.5 3.5t-42 22.5t-17 55q0 39 26 60t66 21 +h130v-57h-119q-36 0 -36 -25q0 -16 17.5 -20.5t42 -4t49 -2.5t42 -21.5t17.5 -54.5zM2304 407v-101q-24 -35 -88 -35h-125v58h125q33 0 33 25q0 13 -12.5 19t-31 5.5t-40 2t-40 8t-31 24t-12.5 48.5q0 39 26.5 60t66.5 21h129v-57h-118q-36 0 -36 -25q0 -20 29 -22t68.5 -5 +t56.5 -26zM2139 1008v-270h-92l-122 203v-203h-132l-26 60h-134l-25 -60h-75q-129 0 -129 133q0 138 133 138h63v-59q-7 0 -28 1t-28.5 0.5t-23 -2t-21.5 -6.5t-14.5 -13.5t-11.5 -23t-3 -33.5q0 -38 13.5 -58t49.5 -20h29l92 213h97l109 -256v256h99l114 -188v188h66z" /> + <glyph glyph-name="_469" unicode="&#xf1f4;" horiz-adv-x="2304" +d="M745 630q0 -37 -25.5 -61.5t-62.5 -24.5q-29 0 -46.5 16t-17.5 44q0 37 25 62.5t62 25.5q28 0 46.5 -16.5t18.5 -45.5zM1530 779q0 -42 -22 -57t-66 -15l-32 -1l17 107q2 11 13 11h18q22 0 35 -2t25 -12.5t12 -30.5zM1881 630q0 -36 -25.5 -61t-61.5 -25q-29 0 -47 16 +t-18 44q0 37 25 62.5t62 25.5q28 0 46.5 -16.5t18.5 -45.5zM513 801q0 59 -38.5 85.5t-100.5 26.5h-160q-19 0 -21 -19l-65 -408q-1 -6 3 -11t10 -5h76q20 0 22 19l18 110q1 8 7 13t15 6.5t17 1.5t19 -1t14 -1q86 0 135 48.5t49 134.5zM822 489l41 261q1 6 -3 11t-10 5h-76 +q-14 0 -17 -33q-27 40 -95 40q-72 0 -122.5 -54t-50.5 -127q0 -59 34.5 -94t92.5 -35q28 0 58 12t48 32q-4 -12 -4 -21q0 -16 13 -16h69q19 0 22 19zM1269 752q0 5 -4 9.5t-9 4.5h-77q-11 0 -18 -10l-106 -156l-44 150q-5 16 -22 16h-75q-5 0 -9 -4.5t-4 -9.5q0 -2 19.5 -59 +t42 -123t23.5 -70q-82 -112 -82 -120q0 -13 13 -13h77q11 0 18 10l255 368q2 2 2 7zM1649 801q0 59 -38.5 85.5t-100.5 26.5h-159q-20 0 -22 -19l-65 -408q-1 -6 3 -11t10 -5h82q12 0 16 13l18 116q1 8 7 13t15 6.5t17 1.5t19 -1t14 -1q86 0 135 48.5t49 134.5zM1958 489 +l41 261q1 6 -3 11t-10 5h-76q-14 0 -17 -33q-26 40 -95 40q-72 0 -122.5 -54t-50.5 -127q0 -59 34.5 -94t92.5 -35q29 0 59 12t47 32q0 -1 -2 -9t-2 -12q0 -16 13 -16h69q19 0 22 19zM2176 898v1q0 14 -13 14h-74q-11 0 -13 -11l-65 -416l-1 -2q0 -5 4 -9.5t10 -4.5h66 +q19 0 21 19zM392 764q-5 -35 -26 -46t-60 -11l-33 -1l17 107q2 11 13 11h19q40 0 58 -11.5t12 -48.5zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" /> + <glyph glyph-name="_470" unicode="&#xf1f5;" horiz-adv-x="2304" +d="M1597 633q0 -69 -21 -106q-19 -35 -52 -35q-23 0 -41 9v224q29 30 57 30q57 0 57 -122zM2035 669h-110q6 98 56 98q51 0 54 -98zM476 534q0 59 -33 91.5t-101 57.5q-36 13 -52 24t-16 25q0 26 38 26q58 0 124 -33l18 112q-67 32 -149 32q-77 0 -123 -38q-48 -39 -48 -109 +q0 -58 32.5 -90.5t99.5 -56.5q39 -14 54.5 -25.5t15.5 -27.5q0 -31 -48 -31q-29 0 -70 12.5t-72 30.5l-18 -113q72 -41 168 -41q81 0 129 37q51 41 51 117zM771 749l19 111h-96v135l-129 -21l-18 -114l-46 -8l-17 -103h62v-219q0 -84 44 -120q38 -30 111 -30q32 0 79 11v118 +q-32 -7 -44 -7q-42 0 -42 50v197h77zM1087 724v139q-15 3 -28 3q-32 0 -55.5 -16t-33.5 -46l-10 56h-131v-471h150v306q26 31 82 31q16 0 26 -2zM1124 389h150v471h-150v-471zM1746 638q0 122 -45 179q-40 52 -111 52q-64 0 -117 -56l-8 47h-132v-645l150 25v151 +q36 -11 68 -11q83 0 134 56q61 65 61 202zM1278 986q0 33 -23 56t-56 23t-56 -23t-23 -56t23 -56.5t56 -23.5t56 23.5t23 56.5zM2176 629q0 113 -48 176q-50 64 -144 64q-96 0 -151.5 -66t-55.5 -180q0 -128 63 -188q55 -55 161 -55q101 0 160 40l-16 103q-57 -31 -128 -31 +q-43 0 -63 19q-23 19 -28 66h248q2 14 2 52zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" /> + <glyph glyph-name="_471" unicode="&#xf1f6;" horiz-adv-x="2048" +d="M1558 684q61 -356 298 -556q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-180.5 74.5t-75.5 180.5zM1024 -176q16 0 16 16t-16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5zM2026 1424q8 -10 7.5 -23.5t-10.5 -22.5 +l-1872 -1622q-10 -8 -23.5 -7t-21.5 11l-84 96q-8 10 -7.5 23.5t10.5 21.5l186 161q-19 32 -19 66q50 42 91 88t85 119.5t74.5 158.5t50 206t19.5 260q0 152 117 282.5t307 158.5q-8 19 -8 39q0 40 28 68t68 28t68 -28t28 -68q0 -20 -8 -39q124 -18 219 -82.5t148 -157.5 +l418 363q10 8 23.5 7t21.5 -11z" /> + <glyph glyph-name="_472" unicode="&#xf1f7;" horiz-adv-x="2048" +d="M1040 -160q0 16 -16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16zM503 315l877 760q-42 88 -132.5 146.5t-223.5 58.5q-93 0 -169.5 -31.5t-121.5 -80.5t-69 -103t-24 -105q0 -384 -137 -645zM1856 128 +q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-180.5 74.5t-75.5 180.5l149 129h757q-166 187 -227 459l111 97q61 -356 298 -556zM1942 1520l84 -96q8 -10 7.5 -23.5t-10.5 -22.5l-1872 -1622q-10 -8 -23.5 -7t-21.5 11l-84 96q-8 10 -7.5 23.5t10.5 21.5l186 161 +q-19 32 -19 66q50 42 91 88t85 119.5t74.5 158.5t50 206t19.5 260q0 152 117 282.5t307 158.5q-8 19 -8 39q0 40 28 68t68 28t68 -28t28 -68q0 -20 -8 -39q124 -18 219 -82.5t148 -157.5l418 363q10 8 23.5 7t21.5 -11z" /> + <glyph glyph-name="_473" unicode="&#xf1f8;" horiz-adv-x="1408" +d="M512 160v704q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-704q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM768 160v704q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-704q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1024 160v704q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-704 +q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM480 1152h448l-48 117q-7 9 -17 11h-317q-10 -2 -17 -11zM1408 1120v-64q0 -14 -9 -23t-23 -9h-96v-948q0 -83 -47 -143.5t-113 -60.5h-832q-66 0 -113 58.5t-47 141.5v952h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h309l70 167 +q15 37 54 63t79 26h320q40 0 79 -26t54 -63l70 -167h309q14 0 23 -9t9 -23z" /> + <glyph glyph-name="_474" unicode="&#xf1f9;" +d="M1150 462v-109q0 -50 -36.5 -89t-94 -60.5t-118 -32.5t-117.5 -11q-205 0 -342.5 139t-137.5 346q0 203 136 339t339 136q34 0 75.5 -4.5t93 -18t92.5 -34t69 -56.5t28 -81v-109q0 -16 -16 -16h-118q-16 0 -16 16v70q0 43 -65.5 67.5t-137.5 24.5q-140 0 -228.5 -91.5 +t-88.5 -237.5q0 -151 91.5 -249.5t233.5 -98.5q68 0 138 24t70 66v70q0 7 4.5 11.5t10.5 4.5h119q6 0 11 -4.5t5 -11.5zM768 1280q-130 0 -248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5 +t-51 248.5t-136.5 204t-204 136.5t-248.5 51zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="_475" unicode="&#xf1fa;" +d="M972 761q0 108 -53.5 169t-147.5 61q-63 0 -124 -30.5t-110 -84.5t-79.5 -137t-30.5 -180q0 -112 53.5 -173t150.5 -61q96 0 176 66.5t122.5 166t42.5 203.5zM1536 640q0 -111 -37 -197t-98.5 -135t-131.5 -74.5t-145 -27.5q-6 0 -15.5 -0.5t-16.5 -0.5q-95 0 -142 53 +q-28 33 -33 83q-52 -66 -131.5 -110t-173.5 -44q-161 0 -249.5 95.5t-88.5 269.5q0 157 66 290t179 210.5t246 77.5q87 0 155 -35.5t106 -99.5l2 19l11 56q1 6 5.5 12t9.5 6h118q5 0 13 -11q5 -5 3 -16l-120 -614q-5 -24 -5 -48q0 -39 12.5 -52t44.5 -13q28 1 57 5.5t73 24 +t77 50t57 89.5t24 137q0 292 -174 466t-466 174q-130 0 -248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51q228 0 405 144q11 9 24 8t21 -12l41 -49q8 -12 7 -24q-2 -13 -12 -22q-102 -83 -227.5 -128t-258.5 -45q-156 0 -298 61 +t-245 164t-164 245t-61 298t61 298t164 245t245 164t298 61q344 0 556 -212t212 -556z" /> + <glyph glyph-name="_476" unicode="&#xf1fb;" horiz-adv-x="1792" +d="M1698 1442q94 -94 94 -226.5t-94 -225.5l-225 -223l104 -104q10 -10 10 -23t-10 -23l-210 -210q-10 -10 -23 -10t-23 10l-105 105l-603 -603q-37 -37 -90 -37h-203l-256 -128l-64 64l128 256v203q0 53 37 90l603 603l-105 105q-10 10 -10 23t10 23l210 210q10 10 23 10 +t23 -10l104 -104l223 225q93 94 225.5 94t226.5 -94zM512 64l576 576l-192 192l-576 -576v-192h192z" /> + <glyph glyph-name="f1fc" unicode="&#xf1fc;" horiz-adv-x="1792" +d="M1615 1536q70 0 122.5 -46.5t52.5 -116.5q0 -63 -45 -151q-332 -629 -465 -752q-97 -91 -218 -91q-126 0 -216.5 92.5t-90.5 219.5q0 128 92 212l638 579q59 54 130 54zM706 502q39 -76 106.5 -130t150.5 -76l1 -71q4 -213 -129.5 -347t-348.5 -134q-123 0 -218 46.5 +t-152.5 127.5t-86.5 183t-29 220q7 -5 41 -30t62 -44.5t59 -36.5t46 -17q41 0 55 37q25 66 57.5 112.5t69.5 76t88 47.5t103 25.5t125 10.5z" /> + <glyph glyph-name="_478" unicode="&#xf1fd;" horiz-adv-x="1792" +d="M1792 128v-384h-1792v384q45 0 85 14t59 27.5t47 37.5q30 27 51.5 38t56.5 11q24 0 44 -7t31 -15t33 -27q29 -25 47 -38t58 -27t86 -14q45 0 85 14.5t58 27t48 37.5q21 19 32.5 27t31 15t43.5 7q35 0 56.5 -11t51.5 -38q28 -24 47 -37.5t59 -27.5t85 -14t85 14t59 27.5 +t47 37.5q30 27 51.5 38t56.5 11q34 0 55.5 -11t51.5 -38q28 -24 47 -37.5t59 -27.5t85 -14zM1792 448v-192q-24 0 -44 7t-31 15t-33 27q-29 25 -47 38t-58 27t-85 14q-46 0 -86 -14t-58 -27t-47 -38q-22 -19 -33 -27t-31 -15t-44 -7q-35 0 -56.5 11t-51.5 38q-29 25 -47 38 +t-58 27t-86 14q-45 0 -85 -14.5t-58 -27t-48 -37.5q-21 -19 -32.5 -27t-31 -15t-43.5 -7q-35 0 -56.5 11t-51.5 38q-28 24 -47 37.5t-59 27.5t-85 14q-46 0 -86 -14t-58 -27t-47 -38q-30 -27 -51.5 -38t-56.5 -11v192q0 80 56 136t136 56h64v448h256v-448h256v448h256v-448 +h256v448h256v-448h64q80 0 136 -56t56 -136zM512 1312q0 -77 -36 -118.5t-92 -41.5q-53 0 -90.5 37.5t-37.5 90.5q0 29 9.5 51t23.5 34t31 28t31 31.5t23.5 44.5t9.5 67q38 0 83 -74t45 -150zM1024 1312q0 -77 -36 -118.5t-92 -41.5q-53 0 -90.5 37.5t-37.5 90.5 +q0 29 9.5 51t23.5 34t31 28t31 31.5t23.5 44.5t9.5 67q38 0 83 -74t45 -150zM1536 1312q0 -77 -36 -118.5t-92 -41.5q-53 0 -90.5 37.5t-37.5 90.5q0 29 9.5 51t23.5 34t31 28t31 31.5t23.5 44.5t9.5 67q38 0 83 -74t45 -150z" /> + <glyph glyph-name="_479" unicode="&#xf1fe;" horiz-adv-x="2048" +d="M2048 0v-128h-2048v1536h128v-1408h1920zM1664 1024l256 -896h-1664v576l448 576l576 -576z" /> + <glyph glyph-name="_480" unicode="&#xf200;" horiz-adv-x="1792" +d="M768 646l546 -546q-106 -108 -247.5 -168t-298.5 -60q-209 0 -385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103v-762zM955 640h773q0 -157 -60 -298.5t-168 -247.5zM1664 768h-768v768q209 0 385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="_481" unicode="&#xf201;" horiz-adv-x="2048" +d="M2048 0v-128h-2048v1536h128v-1408h1920zM1920 1248v-435q0 -21 -19.5 -29.5t-35.5 7.5l-121 121l-633 -633q-10 -10 -23 -10t-23 10l-233 233l-416 -416l-192 192l585 585q10 10 23 10t23 -10l233 -233l464 464l-121 121q-16 16 -7.5 35.5t29.5 19.5h435q14 0 23 -9 +t9 -23z" /> + <glyph glyph-name="_482" unicode="&#xf202;" horiz-adv-x="1792" +d="M1292 832q0 -6 10 -41q10 -29 25 -49.5t41 -34t44 -20t55 -16.5q325 -91 325 -332q0 -146 -105.5 -242.5t-254.5 -96.5q-59 0 -111.5 18.5t-91.5 45.5t-77 74.5t-63 87.5t-53.5 103.5t-43.5 103t-39.5 106.5t-35.5 95q-32 81 -61.5 133.5t-73.5 96.5t-104 64t-142 20 +q-96 0 -183 -55.5t-138 -144.5t-51 -185q0 -160 106.5 -279.5t263.5 -119.5q177 0 258 95q56 63 83 116l84 -152q-15 -34 -44 -70l1 -1q-131 -152 -388 -152q-147 0 -269.5 79t-190.5 207.5t-68 274.5q0 105 43.5 206t116 176.5t172 121.5t204.5 46q87 0 159 -19t123.5 -50 +t95 -80t72.5 -99t58.5 -117t50.5 -124.5t50 -130.5t55 -127q96 -200 233 -200q81 0 138.5 48.5t57.5 128.5q0 42 -19 72t-50.5 46t-72.5 31.5t-84.5 27t-87.5 34t-81 52t-65 82t-39 122.5q-3 16 -3 33q0 110 87.5 192t198.5 78q78 -3 120.5 -14.5t90.5 -53.5h-1 +q12 -11 23 -24.5t26 -36t19 -27.5l-129 -99q-26 49 -54 70v1q-23 21 -97 21q-49 0 -84 -33t-35 -83z" /> + <glyph glyph-name="_483" unicode="&#xf203;" +d="M1432 484q0 173 -234 239q-35 10 -53 16.5t-38 25t-29 46.5q0 2 -2 8.5t-3 12t-1 7.5q0 36 24.5 59.5t60.5 23.5q54 0 71 -15h-1q20 -15 39 -51l93 71q-39 54 -49 64q-33 29 -67.5 39t-85.5 10q-80 0 -142 -57.5t-62 -137.5q0 -7 2 -23q16 -96 64.5 -140t148.5 -73 +q29 -8 49 -15.5t45 -21.5t38.5 -34.5t13.5 -46.5v-5q1 -58 -40.5 -93t-100.5 -35q-97 0 -167 144q-23 47 -51.5 121.5t-48 125.5t-54 110.5t-74 95.5t-103.5 60.5t-147 24.5q-101 0 -192 -56t-144 -148t-50 -192v-1q4 -108 50.5 -199t133.5 -147.5t196 -56.5q186 0 279 110 +q20 27 31 51l-60 109q-42 -80 -99 -116t-146 -36q-115 0 -191 87t-76 204q0 105 82 189t186 84q112 0 170 -53.5t104 -172.5q8 -21 25.5 -68.5t28.5 -76.5t31.5 -74.5t38.5 -74t45.5 -62.5t55.5 -53.5t66 -33t80 -13.5q107 0 183 69.5t76 174.5zM1536 1120v-960 +q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="_484" unicode="&#xf204;" horiz-adv-x="2048" +d="M1152 640q0 104 -40.5 198.5t-109.5 163.5t-163.5 109.5t-198.5 40.5t-198.5 -40.5t-163.5 -109.5t-109.5 -163.5t-40.5 -198.5t40.5 -198.5t109.5 -163.5t163.5 -109.5t198.5 -40.5t198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5zM1920 640q0 104 -40.5 198.5 +t-109.5 163.5t-163.5 109.5t-198.5 40.5h-386q119 -90 188.5 -224t69.5 -288t-69.5 -288t-188.5 -224h386q104 0 198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5zM2048 640q0 -130 -51 -248.5t-136.5 -204t-204 -136.5t-248.5 -51h-768q-130 0 -248.5 51t-204 136.5 +t-136.5 204t-51 248.5t51 248.5t136.5 204t204 136.5t248.5 51h768q130 0 248.5 -51t204 -136.5t136.5 -204t51 -248.5z" /> + <glyph glyph-name="_485" unicode="&#xf205;" horiz-adv-x="2048" +d="M0 640q0 130 51 248.5t136.5 204t204 136.5t248.5 51h768q130 0 248.5 -51t204 -136.5t136.5 -204t51 -248.5t-51 -248.5t-136.5 -204t-204 -136.5t-248.5 -51h-768q-130 0 -248.5 51t-204 136.5t-136.5 204t-51 248.5zM1408 128q104 0 198.5 40.5t163.5 109.5 +t109.5 163.5t40.5 198.5t-40.5 198.5t-109.5 163.5t-163.5 109.5t-198.5 40.5t-198.5 -40.5t-163.5 -109.5t-109.5 -163.5t-40.5 -198.5t40.5 -198.5t109.5 -163.5t163.5 -109.5t198.5 -40.5z" /> + <glyph glyph-name="_486" unicode="&#xf206;" horiz-adv-x="2304" +d="M762 384h-314q-40 0 -57.5 35t6.5 67l188 251q-65 31 -137 31q-132 0 -226 -94t-94 -226t94 -226t226 -94q115 0 203 72.5t111 183.5zM576 512h186q-18 85 -75 148zM1056 512l288 384h-480l-99 -132q105 -103 126 -252h165zM2176 448q0 132 -94 226t-226 94 +q-60 0 -121 -24l174 -260q15 -23 10 -49t-27 -40q-15 -11 -36 -11q-35 0 -53 29l-174 260q-93 -95 -93 -225q0 -132 94 -226t226 -94t226 94t94 226zM2304 448q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 97 39.5 183.5t109.5 149.5l-65 98l-353 -469 +q-18 -26 -51 -26h-197q-23 -164 -149 -274t-294 -110q-185 0 -316.5 131.5t-131.5 316.5t131.5 316.5t316.5 131.5q114 0 215 -55l137 183h-224q-26 0 -45 19t-19 45t19 45t45 19h384v-128h435l-85 128h-222q-26 0 -45 19t-19 45t19 45t45 19h256q33 0 53 -28l267 -400 +q91 44 192 44q185 0 316.5 -131.5t131.5 -316.5z" /> + <glyph glyph-name="_487" unicode="&#xf207;" +d="M384 320q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1408 320q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1362 716l-72 384q-5 23 -22.5 37.5t-40.5 14.5 +h-918q-23 0 -40.5 -14.5t-22.5 -37.5l-72 -384q-5 -30 14 -53t49 -23h1062q30 0 49 23t14 53zM1136 1328q0 20 -14 34t-34 14h-640q-20 0 -34 -14t-14 -34t14 -34t34 -14h640q20 0 34 14t14 34zM1536 603v-603h-128v-128q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5 +t-37.5 90.5v128h-768v-128q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5v128h-128v603q0 112 25 223l103 454q9 78 97.5 137t230 89t312.5 30t312.5 -30t230 -89t97.5 -137l105 -454q23 -102 23 -223z" /> + <glyph glyph-name="_488" unicode="&#xf208;" horiz-adv-x="2048" +d="M1463 704q0 -35 -25 -60.5t-61 -25.5h-702q-36 0 -61 25.5t-25 60.5t25 60.5t61 25.5h702q36 0 61 -25.5t25 -60.5zM1677 704q0 86 -23 170h-982q-36 0 -61 25t-25 60q0 36 25 61t61 25h908q-88 143 -235 227t-320 84q-177 0 -327.5 -87.5t-238 -237.5t-87.5 -327 +q0 -86 23 -170h982q36 0 61 -25t25 -60q0 -36 -25 -61t-61 -25h-908q88 -143 235.5 -227t320.5 -84q132 0 253 51.5t208 139t139 208t52 253.5zM2048 959q0 -35 -25 -60t-61 -25h-131q17 -85 17 -170q0 -167 -65.5 -319.5t-175.5 -263t-262.5 -176t-319.5 -65.5 +q-246 0 -448.5 133t-301.5 350h-189q-36 0 -61 25t-25 61q0 35 25 60t61 25h132q-17 85 -17 170q0 167 65.5 319.5t175.5 263t262.5 176t320.5 65.5q245 0 447.5 -133t301.5 -350h188q36 0 61 -25t25 -61z" /> + <glyph glyph-name="_489" unicode="&#xf209;" horiz-adv-x="1280" +d="M953 1158l-114 -328l117 -21q165 451 165 518q0 56 -38 56q-57 0 -130 -225zM654 471l33 -88q37 42 71 67l-33 5.5t-38.5 7t-32.5 8.5zM362 1367q0 -98 159 -521q17 10 49 10q15 0 75 -5l-121 351q-75 220 -123 220q-19 0 -29 -17.5t-10 -37.5zM283 608q0 -36 51.5 -119 +t117.5 -153t100 -70q14 0 25.5 13t11.5 27q0 24 -32 102q-13 32 -32 72t-47.5 89t-61.5 81t-62 32q-20 0 -45.5 -27t-25.5 -47zM125 273q0 -41 25 -104q59 -145 183.5 -227t281.5 -82q227 0 382 170q152 169 152 427q0 43 -1 67t-11.5 62t-30.5 56q-56 49 -211.5 75.5 +t-270.5 26.5q-37 0 -49 -11q-12 -5 -12 -35q0 -34 21.5 -60t55.5 -40t77.5 -23.5t87.5 -11.5t85 -4t70 0h23q24 0 40 -19q15 -19 19 -55q-28 -28 -96 -54q-61 -22 -93 -46q-64 -46 -108.5 -114t-44.5 -137q0 -31 18.5 -88.5t18.5 -87.5l-3 -12q-4 -12 -4 -14 +q-137 10 -146 216q-8 -2 -41 -2q2 -7 2 -21q0 -53 -40.5 -89.5t-94.5 -36.5q-82 0 -166.5 78t-84.5 159q0 34 33 67q52 -64 60 -76q77 -104 133 -104q12 0 26.5 8.5t14.5 20.5q0 34 -87.5 145t-116.5 111q-43 0 -70 -44.5t-27 -90.5zM11 264q0 101 42.5 163t136.5 88 +q-28 74 -28 104q0 62 61 123t122 61q29 0 70 -15q-163 462 -163 567q0 80 41 130.5t119 50.5q131 0 325 -581q6 -17 8 -23q6 16 29 79.5t43.5 118.5t54 127.5t64.5 123t70.5 86.5t76.5 36q71 0 112 -49t41 -122q0 -108 -159 -550q61 -15 100.5 -46t58.5 -78t26 -93.5 +t7 -110.5q0 -150 -47 -280t-132 -225t-211 -150t-278 -55q-111 0 -223 42q-149 57 -258 191.5t-109 286.5z" /> + <glyph glyph-name="_490" unicode="&#xf20a;" horiz-adv-x="2048" +d="M785 528h207q-14 -158 -98.5 -248.5t-214.5 -90.5q-162 0 -254.5 116t-92.5 316q0 194 93 311.5t233 117.5q148 0 232 -87t97 -247h-203q-5 64 -35.5 99t-81.5 35q-57 0 -88.5 -60.5t-31.5 -177.5q0 -48 5 -84t18 -69.5t40 -51.5t66 -18q95 0 109 139zM1497 528h206 +q-14 -158 -98 -248.5t-214 -90.5q-162 0 -254.5 116t-92.5 316q0 194 93 311.5t233 117.5q148 0 232 -87t97 -247h-204q-4 64 -35 99t-81 35q-57 0 -88.5 -60.5t-31.5 -177.5q0 -48 5 -84t18 -69.5t39.5 -51.5t65.5 -18q49 0 76.5 38t33.5 101zM1856 647q0 207 -15.5 307 +t-60.5 161q-6 8 -13.5 14t-21.5 15t-16 11q-86 63 -697 63q-625 0 -710 -63q-5 -4 -17.5 -11.5t-21 -14t-14.5 -14.5q-45 -60 -60 -159.5t-15 -308.5q0 -208 15 -307.5t60 -160.5q6 -8 15 -15t20.5 -14t17.5 -12q44 -33 239.5 -49t470.5 -16q610 0 697 65q5 4 17 11t20.5 14 +t13.5 16q46 60 61 159t15 309zM2048 1408v-1536h-2048v1536h2048z" /> + <glyph glyph-name="_491" unicode="&#xf20b;" +d="M992 912v-496q0 -14 -9 -23t-23 -9h-160q-14 0 -23 9t-9 23v496q0 112 -80 192t-192 80h-272v-1152q0 -14 -9 -23t-23 -9h-160q-14 0 -23 9t-9 23v1344q0 14 9 23t23 9h464q135 0 249 -66.5t180.5 -180.5t66.5 -249zM1376 1376v-880q0 -135 -66.5 -249t-180.5 -180.5 +t-249 -66.5h-464q-14 0 -23 9t-9 23v960q0 14 9 23t23 9h160q14 0 23 -9t9 -23v-768h272q112 0 192 80t80 192v880q0 14 9 23t23 9h160q14 0 23 -9t9 -23z" /> + <glyph glyph-name="_492" unicode="&#xf20c;" +d="M1311 694v-114q0 -24 -13.5 -38t-37.5 -14h-202q-24 0 -38 14t-14 38v114q0 24 14 38t38 14h202q24 0 37.5 -14t13.5 -38zM821 464v250q0 53 -32.5 85.5t-85.5 32.5h-133q-68 0 -96 -52q-28 52 -96 52h-130q-53 0 -85.5 -32.5t-32.5 -85.5v-250q0 -22 21 -22h55 +q22 0 22 22v230q0 24 13.5 38t38.5 14h94q24 0 38 -14t14 -38v-230q0 -22 21 -22h54q22 0 22 22v230q0 24 14 38t38 14h97q24 0 37.5 -14t13.5 -38v-230q0 -22 22 -22h55q21 0 21 22zM1410 560v154q0 53 -33 85.5t-86 32.5h-264q-53 0 -86 -32.5t-33 -85.5v-410 +q0 -21 22 -21h55q21 0 21 21v180q31 -42 94 -42h191q53 0 86 32.5t33 85.5zM1536 1176v-1072q0 -96 -68 -164t-164 -68h-1072q-96 0 -164 68t-68 164v1072q0 96 68 164t164 68h1072q96 0 164 -68t68 -164z" /> + <glyph glyph-name="_493" unicode="&#xf20d;" +d="M915 450h-294l147 551zM1001 128h311l-324 1024h-440l-324 -1024h311l383 314zM1536 1120v-960q0 -118 -85 -203t-203 -85h-960q-118 0 -203 85t-85 203v960q0 118 85 203t203 85h960q118 0 203 -85t85 -203z" /> + <glyph glyph-name="_494" unicode="&#xf20e;" horiz-adv-x="2048" +d="M2048 641q0 -21 -13 -36.5t-33 -19.5l-205 -356q3 -9 3 -18q0 -20 -12.5 -35.5t-32.5 -19.5l-193 -337q3 -8 3 -16q0 -23 -16.5 -40t-40.5 -17q-25 0 -41 18h-400q-17 -20 -43 -20t-43 20h-399q-17 -20 -43 -20q-23 0 -40 16.5t-17 40.5q0 8 4 20l-193 335 +q-20 4 -32.5 19.5t-12.5 35.5q0 9 3 18l-206 356q-20 5 -32.5 20.5t-12.5 35.5q0 21 13.5 36.5t33.5 19.5l199 344q0 1 -0.5 3t-0.5 3q0 36 34 51l209 363q-4 10 -4 18q0 24 17 40.5t40 16.5q26 0 44 -21h396q16 21 43 21t43 -21h398q18 21 44 21q23 0 40 -16.5t17 -40.5 +q0 -6 -4 -18l207 -358q23 -1 39 -17.5t16 -38.5q0 -13 -7 -27l187 -324q19 -4 31.5 -19.5t12.5 -35.5zM1063 -158h389l-342 354h-143l-342 -354h360q18 16 39 16t39 -16zM112 654q1 -4 1 -13q0 -10 -2 -15l208 -360l15 -6l188 199v347l-187 194q-13 -8 -29 -10zM986 1438 +h-388l190 -200l554 200h-280q-16 -16 -38 -16t-38 16zM1689 226q1 6 5 11l-64 68l-17 -79h76zM1583 226l22 105l-252 266l-296 -307l63 -64h463zM1495 -142l16 28l65 310h-427l333 -343q8 4 13 5zM578 -158h5l342 354h-373v-335l4 -6q14 -5 22 -13zM552 226h402l64 66 +l-309 321l-157 -166v-221zM359 226h163v189l-168 -177q4 -8 5 -12zM358 1051q0 -1 0.5 -2t0.5 -2q0 -16 -8 -29l171 -177v269zM552 1121v-311l153 -157l297 314l-223 236zM556 1425l-4 -8v-264l205 74l-191 201q-6 -2 -10 -3zM1447 1438h-16l-621 -224l213 -225zM1023 946 +l-297 -315l311 -319l296 307zM688 634l-136 141v-284zM1038 270l-42 -44h85zM1374 618l238 -251l132 624l-3 5l-1 1zM1718 1018q-8 13 -8 29v2l-216 376q-5 1 -13 5l-437 -463l310 -327zM522 1142v223l-163 -282zM522 196h-163l163 -283v283zM1607 196l-48 -227l130 227h-82 +zM1729 266l207 361q-2 10 -2 14q0 1 3 16l-171 296l-129 -612l77 -82q5 3 15 7z" /> + <glyph glyph-name="f210" unicode="&#xf210;" +d="M0 856q0 131 91.5 226.5t222.5 95.5h742l352 358v-1470q0 -132 -91.5 -227t-222.5 -95h-780q-131 0 -222.5 95t-91.5 227v790zM1232 102l-176 180v425q0 46 -32 79t-78 33h-484q-46 0 -78 -33t-32 -79v-492q0 -46 32.5 -79.5t77.5 -33.5h770z" /> + <glyph glyph-name="_496" unicode="&#xf211;" +d="M934 1386q-317 -121 -556 -362.5t-358 -560.5q-20 89 -20 176q0 208 102.5 384.5t278.5 279t384 102.5q82 0 169 -19zM1203 1267q93 -65 164 -155q-389 -113 -674.5 -400.5t-396.5 -676.5q-93 72 -155 162q112 386 395 671t667 399zM470 -67q115 356 379.5 622t619.5 384 +q40 -92 54 -195q-292 -120 -516 -345t-343 -518q-103 14 -194 52zM1536 -125q-193 50 -367 115q-135 -84 -290 -107q109 205 274 370.5t369 275.5q-21 -152 -101 -284q65 -175 115 -370z" /> + <glyph glyph-name="f212" unicode="&#xf212;" horiz-adv-x="2048" +d="M1893 1144l155 -1272q-131 0 -257 57q-200 91 -393 91q-226 0 -374 -148q-148 148 -374 148q-193 0 -393 -91q-128 -57 -252 -57h-5l155 1272q224 127 482 127q233 0 387 -106q154 106 387 106q258 0 482 -127zM1398 157q129 0 232 -28.5t260 -93.5l-124 1021 +q-171 78 -368 78q-224 0 -374 -141q-150 141 -374 141q-197 0 -368 -78l-124 -1021q105 43 165.5 65t148.5 39.5t178 17.5q202 0 374 -108q172 108 374 108zM1438 191l-55 907q-211 -4 -359 -155q-152 155 -374 155q-176 0 -336 -66l-114 -941q124 51 228.5 76t221.5 25 +q209 0 374 -102q172 107 374 102z" /> + <glyph glyph-name="_498" unicode="&#xf213;" horiz-adv-x="2048" +d="M1500 165v733q0 21 -15 36t-35 15h-93q-20 0 -35 -15t-15 -36v-733q0 -20 15 -35t35 -15h93q20 0 35 15t15 35zM1216 165v531q0 20 -15 35t-35 15h-101q-20 0 -35 -15t-15 -35v-531q0 -20 15 -35t35 -15h101q20 0 35 15t15 35zM924 165v429q0 20 -15 35t-35 15h-101 +q-20 0 -35 -15t-15 -35v-429q0 -20 15 -35t35 -15h101q20 0 35 15t15 35zM632 165v362q0 20 -15 35t-35 15h-101q-20 0 -35 -15t-15 -35v-362q0 -20 15 -35t35 -15h101q20 0 35 15t15 35zM2048 311q0 -166 -118 -284t-284 -118h-1244q-166 0 -284 118t-118 284 +q0 116 63 214.5t168 148.5q-10 34 -10 73q0 113 80.5 193.5t193.5 80.5q102 0 180 -67q45 183 194 300t338 117q149 0 275 -73.5t199.5 -199.5t73.5 -275q0 -66 -14 -122q135 -33 221 -142.5t86 -247.5z" /> + <glyph glyph-name="_499" unicode="&#xf214;" +d="M0 1536h1536v-1392l-776 -338l-760 338v1392zM1436 209v926h-1336v-926l661 -294zM1436 1235v201h-1336v-201h1336zM181 937v-115h-37v115h37zM181 789v-115h-37v115h37zM181 641v-115h-37v115h37zM181 493v-115h-37v115h37zM181 345v-115h-37v115h37zM207 202l15 34 +l105 -47l-15 -33zM343 142l15 34l105 -46l-15 -34zM478 82l15 34l105 -46l-15 -34zM614 23l15 33l104 -46l-15 -34zM797 10l105 46l15 -33l-105 -47zM932 70l105 46l15 -34l-105 -46zM1068 130l105 46l15 -34l-105 -46zM1203 189l105 47l15 -34l-105 -46zM259 1389v-36h-114 +v36h114zM421 1389v-36h-115v36h115zM583 1389v-36h-115v36h115zM744 1389v-36h-114v36h114zM906 1389v-36h-114v36h114zM1068 1389v-36h-115v36h115zM1230 1389v-36h-115v36h115zM1391 1389v-36h-114v36h114zM181 1049v-79h-37v115h115v-36h-78zM421 1085v-36h-115v36h115z +M583 1085v-36h-115v36h115zM744 1085v-36h-114v36h114zM906 1085v-36h-114v36h114zM1068 1085v-36h-115v36h115zM1230 1085v-36h-115v36h115zM1355 970v79h-78v36h115v-115h-37zM1355 822v115h37v-115h-37zM1355 674v115h37v-115h-37zM1355 526v115h37v-115h-37zM1355 378 +v115h37v-115h-37zM1355 230v115h37v-115h-37zM760 265q-129 0 -221 91.5t-92 221.5q0 129 92 221t221 92q130 0 221.5 -92t91.5 -221q0 -130 -91.5 -221.5t-221.5 -91.5zM595 646q0 -36 19.5 -56.5t49.5 -25t64 -7t64 -2t49.5 -9t19.5 -30.5q0 -49 -112 -49q-97 0 -123 51 +h-3l-31 -63q67 -42 162 -42q29 0 56.5 5t55.5 16t45.5 33t17.5 53q0 46 -27.5 69.5t-67.5 27t-79.5 3t-67 5t-27.5 25.5q0 21 20.5 33t40.5 15t41 3q34 0 70.5 -11t51.5 -34h3l30 58q-3 1 -21 8.5t-22.5 9t-19.5 7t-22 7t-20 4.5t-24 4t-23 1q-29 0 -56.5 -5t-54 -16.5 +t-43 -34t-16.5 -53.5z" /> + <glyph glyph-name="_500" unicode="&#xf215;" horiz-adv-x="2048" +d="M863 504q0 112 -79.5 191.5t-191.5 79.5t-191 -79.5t-79 -191.5t79 -191t191 -79t191.5 79t79.5 191zM1726 505q0 112 -79 191t-191 79t-191.5 -79t-79.5 -191q0 -113 79.5 -192t191.5 -79t191 79.5t79 191.5zM2048 1314v-1348q0 -44 -31.5 -75.5t-76.5 -31.5h-1832 +q-45 0 -76.5 31.5t-31.5 75.5v1348q0 44 31.5 75.5t76.5 31.5h431q44 0 76 -31.5t32 -75.5v-161h754v161q0 44 32 75.5t76 31.5h431q45 0 76.5 -31.5t31.5 -75.5z" /> + <glyph glyph-name="_501" unicode="&#xf216;" horiz-adv-x="2048" +d="M1430 953zM1690 749q148 0 253 -98.5t105 -244.5q0 -157 -109 -261.5t-267 -104.5q-85 0 -162 27.5t-138 73.5t-118 106t-109 126t-103.5 132.5t-108.5 126.5t-117 106t-136 73.5t-159 27.5q-154 0 -251.5 -91.5t-97.5 -244.5q0 -157 104 -250t263 -93q100 0 208 37.5 +t193 98.5q5 4 21 18.5t30 24t22 9.5q14 0 24.5 -10.5t10.5 -24.5q0 -24 -60 -77q-101 -88 -234.5 -142t-260.5 -54q-133 0 -245.5 58t-180 165t-67.5 241q0 205 141.5 341t347.5 136q120 0 226.5 -43.5t185.5 -113t151.5 -153t139 -167.5t133.5 -153.5t149.5 -113 +t172.5 -43.5q102 0 168.5 61.5t66.5 162.5q0 95 -64.5 159t-159.5 64q-30 0 -81.5 -18.5t-68.5 -18.5q-20 0 -35.5 15t-15.5 35q0 18 8.5 57t8.5 59q0 159 -107.5 263t-266.5 104q-58 0 -111.5 -18.5t-84 -40.5t-55.5 -40.5t-33 -18.5q-15 0 -25.5 10.5t-10.5 25.5 +q0 19 25 46q59 67 147 103.5t182 36.5q191 0 318 -125.5t127 -315.5q0 -37 -4 -66q57 15 115 15z" /> + <glyph glyph-name="_502" unicode="&#xf217;" horiz-adv-x="1664" +d="M1216 832q0 26 -19 45t-45 19h-128v128q0 26 -19 45t-45 19t-45 -19t-19 -45v-128h-128q-26 0 -45 -19t-19 -45t19 -45t45 -19h128v-128q0 -26 19 -45t45 -19t45 19t19 45v128h128q26 0 45 19t19 45zM640 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5 +t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1536 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1664 1088v-512q0 -24 -16 -42.5t-41 -21.5l-1044 -122q1 -7 4.5 -21.5t6 -26.5t2.5 -22q0 -16 -24 -64h920 +q26 0 45 -19t19 -45t-19 -45t-45 -19h-1024q-26 0 -45 19t-19 45q0 14 11 39.5t29.5 59.5t20.5 38l-177 823h-204q-26 0 -45 19t-19 45t19 45t45 19h256q16 0 28.5 -6.5t20 -15.5t13 -24.5t7.5 -26.5t5.5 -29.5t4.5 -25.5h1201q26 0 45 -19t19 -45z" /> + <glyph glyph-name="_503" unicode="&#xf218;" horiz-adv-x="1664" +d="M1280 832q0 26 -19 45t-45 19t-45 -19l-147 -146v293q0 26 -19 45t-45 19t-45 -19t-19 -45v-293l-147 146q-19 19 -45 19t-45 -19t-19 -45t19 -45l256 -256q19 -19 45 -19t45 19l256 256q19 19 19 45zM640 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5 +t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1536 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1664 1088v-512q0 -24 -16 -42.5t-41 -21.5l-1044 -122q1 -7 4.5 -21.5t6 -26.5t2.5 -22q0 -16 -24 -64h920 +q26 0 45 -19t19 -45t-19 -45t-45 -19h-1024q-26 0 -45 19t-19 45q0 14 11 39.5t29.5 59.5t20.5 38l-177 823h-204q-26 0 -45 19t-19 45t19 45t45 19h256q16 0 28.5 -6.5t20 -15.5t13 -24.5t7.5 -26.5t5.5 -29.5t4.5 -25.5h1201q26 0 45 -19t19 -45z" /> + <glyph glyph-name="_504" unicode="&#xf219;" horiz-adv-x="2048" +d="M212 768l623 -665l-300 665h-323zM1024 -4l349 772h-698zM538 896l204 384h-262l-288 -384h346zM1213 103l623 665h-323zM683 896h682l-204 384h-274zM1510 896h346l-288 384h-262zM1651 1382l384 -512q14 -18 13 -41.5t-17 -40.5l-960 -1024q-18 -20 -47 -20t-47 20 +l-960 1024q-16 17 -17 40.5t13 41.5l384 512q18 26 51 26h1152q33 0 51 -26z" /> + <glyph glyph-name="_505" unicode="&#xf21a;" horiz-adv-x="2048" +d="M1811 -19q19 19 45 19t45 -19l128 -128l-90 -90l-83 83l-83 -83q-18 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83 +q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-128 128l90 90l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83 +q19 19 45 19t45 -19l83 -83zM237 19q-19 -19 -45 -19t-45 19l-128 128l90 90l83 -82l83 82q19 19 45 19t45 -19l83 -82l64 64v293l-210 314q-17 26 -7 56.5t40 40.5l177 58v299h128v128h256v128h256v-128h256v-128h128v-299l177 -58q30 -10 40 -40.5t-7 -56.5l-210 -314 +v-293l19 18q19 19 45 19t45 -19l83 -82l83 82q19 19 45 19t45 -19l128 -128l-90 -90l-83 83l-83 -83q-18 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83 +q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83zM640 1152v-128l384 128l384 -128v128h-128v128h-512v-128h-128z" /> + <glyph glyph-name="_506" unicode="&#xf21b;" +d="M576 0l96 448l-96 128l-128 64zM832 0l128 640l-128 -64l-96 -128zM992 1010q-2 4 -4 6q-10 8 -96 8q-70 0 -167 -19q-7 -2 -21 -2t-21 2q-97 19 -167 19q-86 0 -96 -8q-2 -2 -4 -6q2 -18 4 -27q2 -3 7.5 -6.5t7.5 -10.5q2 -4 7.5 -20.5t7 -20.5t7.5 -17t8.5 -17t9 -14 +t12 -13.5t14 -9.5t17.5 -8t20.5 -4t24.5 -2q36 0 59 12.5t32.5 30t14.5 34.5t11.5 29.5t17.5 12.5h12q11 0 17.5 -12.5t11.5 -29.5t14.5 -34.5t32.5 -30t59 -12.5q13 0 24.5 2t20.5 4t17.5 8t14 9.5t12 13.5t9 14t8.5 17t7.5 17t7 20.5t7.5 20.5q2 7 7.5 10.5t7.5 6.5 +q2 9 4 27zM1408 131q0 -121 -73 -190t-194 -69h-874q-121 0 -194 69t-73 190q0 61 4.5 118t19 125.5t37.5 123.5t63.5 103.5t93.5 74.5l-90 220h214q-22 64 -22 128q0 12 2 32q-194 40 -194 96q0 57 210 99q17 62 51.5 134t70.5 114q32 37 76 37q30 0 84 -31t84 -31t84 31 +t84 31q44 0 76 -37q36 -42 70.5 -114t51.5 -134q210 -42 210 -99q0 -56 -194 -96q7 -81 -20 -160h214l-82 -225q63 -33 107.5 -96.5t65.5 -143.5t29 -151.5t8 -148.5z" /> + <glyph glyph-name="_507" unicode="&#xf21c;" horiz-adv-x="2304" +d="M2301 500q12 -103 -22 -198.5t-99 -163.5t-158.5 -106t-196.5 -31q-161 11 -279.5 125t-134.5 274q-12 111 27.5 210.5t118.5 170.5l-71 107q-96 -80 -151 -194t-55 -244q0 -27 -18.5 -46.5t-45.5 -19.5h-256h-69q-23 -164 -149 -274t-294 -110q-185 0 -316.5 131.5 +t-131.5 316.5t131.5 316.5t316.5 131.5q76 0 152 -27l24 45q-123 110 -304 110h-64q-26 0 -45 19t-19 45t19 45t45 19h128q78 0 145 -13.5t116.5 -38.5t71.5 -39.5t51 -36.5h512h115l-85 128h-222q-30 0 -49 22.5t-14 52.5q4 23 23 38t43 15h253q33 0 53 -28l70 -105 +l114 114q19 19 46 19h101q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-179l115 -172q131 63 275 36q143 -26 244 -134.5t118 -253.5zM448 128q115 0 203 72.5t111 183.5h-314q-35 0 -55 31q-18 32 -1 63l147 277q-47 13 -91 13q-132 0 -226 -94t-94 -226t94 -226 +t226 -94zM1856 128q132 0 226 94t94 226t-94 226t-226 94q-60 0 -121 -24l174 -260q15 -23 10 -49t-27 -40q-15 -11 -36 -11q-35 0 -53 29l-174 260q-93 -95 -93 -225q0 -132 94 -226t226 -94z" /> + <glyph glyph-name="_508" unicode="&#xf21d;" +d="M1408 0q0 -63 -61.5 -113.5t-164 -81t-225 -46t-253.5 -15.5t-253.5 15.5t-225 46t-164 81t-61.5 113.5q0 49 33 88.5t91 66.5t118 44.5t131 29.5q26 5 48 -10.5t26 -41.5q5 -26 -10.5 -48t-41.5 -26q-58 -10 -106 -23.5t-76.5 -25.5t-48.5 -23.5t-27.5 -19.5t-8.5 -12 +q3 -11 27 -26.5t73 -33t114 -32.5t160.5 -25t201.5 -10t201.5 10t160.5 25t114 33t73 33.5t27 27.5q-1 4 -8.5 11t-27.5 19t-48.5 23.5t-76.5 25t-106 23.5q-26 4 -41.5 26t-10.5 48q4 26 26 41.5t48 10.5q71 -12 131 -29.5t118 -44.5t91 -66.5t33 -88.5zM1024 896v-384 +q0 -26 -19 -45t-45 -19h-64v-384q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v384h-64q-26 0 -45 19t-19 45v384q0 53 37.5 90.5t90.5 37.5h384q53 0 90.5 -37.5t37.5 -90.5zM928 1280q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5 +t158.5 -65.5t65.5 -158.5z" /> + <glyph glyph-name="_509" unicode="&#xf21e;" horiz-adv-x="1792" +d="M1280 512h305q-5 -6 -10 -10.5t-9 -7.5l-3 -4l-623 -600q-18 -18 -44 -18t-44 18l-624 602q-5 2 -21 20h369q22 0 39.5 13.5t22.5 34.5l70 281l190 -667q6 -20 23 -33t39 -13q21 0 38 13t23 33l146 485l56 -112q18 -35 57 -35zM1792 940q0 -145 -103 -300h-369l-111 221 +q-8 17 -25.5 27t-36.5 8q-45 -5 -56 -46l-129 -430l-196 686q-6 20 -23.5 33t-39.5 13t-39 -13.5t-22 -34.5l-116 -464h-423q-103 155 -103 300q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5q224 0 351 -124 +t127 -344z" /> + <glyph glyph-name="venus" unicode="&#xf221;" horiz-adv-x="1280" +d="M1152 960q0 -221 -147.5 -384.5t-364.5 -187.5v-260h224q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-224v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-224q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v260q-150 16 -271.5 103t-186 224t-52.5 292 +q11 134 80.5 249t182 188t245.5 88q170 19 319 -54t236 -212t87 -306zM128 960q0 -185 131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5z" /> + <glyph glyph-name="_511" unicode="&#xf222;" +d="M1472 1408q26 0 45 -19t19 -45v-416q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v262l-382 -383q126 -156 126 -359q0 -117 -45.5 -223.5t-123 -184t-184 -123t-223.5 -45.5t-223.5 45.5t-184 123t-123 184t-45.5 223.5t45.5 223.5t123 184t184 123t223.5 45.5 +q203 0 359 -126l382 382h-261q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h416zM576 0q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" /> + <glyph glyph-name="_512" unicode="&#xf223;" horiz-adv-x="1280" +d="M830 1220q145 -72 233.5 -210.5t88.5 -305.5q0 -221 -147.5 -384.5t-364.5 -187.5v-132h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96v-96q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v96h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v132q-217 24 -364.5 187.5 +t-147.5 384.5q0 167 88.5 305.5t233.5 210.5q-165 96 -228 273q-6 16 3.5 29.5t26.5 13.5h69q21 0 29 -20q44 -106 140 -171t214 -65t214 65t140 171q8 20 37 20h61q17 0 26.5 -13.5t3.5 -29.5q-63 -177 -228 -273zM576 256q185 0 316.5 131.5t131.5 316.5t-131.5 316.5 +t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" /> + <glyph glyph-name="_513" unicode="&#xf224;" +d="M1024 1504q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q126 -158 126 -359q0 -221 -147.5 -384.5t-364.5 -187.5v-132h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96v-96q0 -14 -9 -23t-23 -9h-64 +q-14 0 -23 9t-9 23v96h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v132q-149 16 -270.5 103t-186.5 223.5t-53 291.5q16 204 160 353.5t347 172.5q118 14 228 -19t198 -103l255 254h-134q-14 0 -23 9t-9 23v64zM576 256q185 0 316.5 131.5t131.5 316.5t-131.5 316.5 +t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" /> + <glyph glyph-name="_514" unicode="&#xf225;" horiz-adv-x="1792" +d="M1280 1504q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q126 -158 126 -359q0 -221 -147.5 -384.5t-364.5 -187.5v-132h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96v-96q0 -14 -9 -23t-23 -9h-64 +q-14 0 -23 9t-9 23v96h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v132q-217 24 -364.5 187.5t-147.5 384.5q0 201 126 359l-52 53l-101 -111q-9 -10 -22 -10.5t-23 7.5l-48 44q-10 8 -10.5 21.5t8.5 23.5l105 115l-111 112v-134q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9 +t-9 23v288q0 26 19 45t45 19h288q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-133l106 -107l86 94q9 10 22 10.5t23 -7.5l48 -44q10 -8 10.5 -21.5t-8.5 -23.5l-90 -99l57 -56q158 126 359 126t359 -126l255 254h-134q-14 0 -23 9t-9 23v64zM832 256q185 0 316.5 131.5 +t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" /> + <glyph glyph-name="_515" unicode="&#xf226;" horiz-adv-x="1792" +d="M1790 1007q12 -155 -52.5 -292t-186 -224t-271.5 -103v-260h224q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-224v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-512v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-224q-14 0 -23 9t-9 23v64q0 14 9 23 +t23 9h224v260q-150 16 -271.5 103t-186 224t-52.5 292q17 206 164.5 356.5t352.5 169.5q206 21 377 -94q171 115 377 94q205 -19 352.5 -169.5t164.5 -356.5zM896 647q128 131 128 313t-128 313q-128 -131 -128 -313t128 -313zM576 512q115 0 218 57q-154 165 -154 391 +q0 224 154 391q-103 57 -218 57q-185 0 -316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5zM1152 128v260q-137 15 -256 94q-119 -79 -256 -94v-260h512zM1216 512q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5q-115 0 -218 -57q154 -167 154 -391 +q0 -226 -154 -391q103 -57 218 -57z" /> + <glyph glyph-name="_516" unicode="&#xf227;" horiz-adv-x="1920" +d="M1536 1120q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q76 -95 107.5 -214t9.5 -247q-31 -182 -166 -312t-318 -156q-210 -29 -384.5 80t-241.5 300q-117 6 -221 57.5t-177.5 133t-113.5 192.5t-32 230 +q9 135 78 252t182 191.5t248 89.5q118 14 227.5 -19t198.5 -103l255 254h-134q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q59 -74 93 -169q182 -9 328 -124l255 254h-134q-14 0 -23 9 +t-9 23v64zM1024 704q0 20 -4 58q-162 -25 -271 -150t-109 -292q0 -20 4 -58q162 25 271 150t109 292zM128 704q0 -168 111 -294t276 -149q-3 29 -3 59q0 210 135 369.5t338 196.5q-53 120 -163.5 193t-245.5 73q-185 0 -316.5 -131.5t-131.5 -316.5zM1088 -128 +q185 0 316.5 131.5t131.5 316.5q0 168 -111 294t-276 149q3 -28 3 -59q0 -210 -135 -369.5t-338 -196.5q53 -120 163.5 -193t245.5 -73z" /> + <glyph glyph-name="_517" unicode="&#xf228;" horiz-adv-x="2048" +d="M1664 1504q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q76 -95 107.5 -214t9.5 -247q-32 -180 -164.5 -310t-313.5 -157q-223 -34 -409 90q-117 -78 -256 -93v-132h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23 +t-23 -9h-96v-96q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v96h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v132q-155 17 -279.5 109.5t-187 237.5t-39.5 307q25 187 159.5 322.5t320.5 164.5q224 34 410 -90q146 97 320 97q201 0 359 -126l255 254h-134q-14 0 -23 9 +t-9 23v64zM896 391q128 131 128 313t-128 313q-128 -131 -128 -313t128 -313zM128 704q0 -185 131.5 -316.5t316.5 -131.5q117 0 218 57q-154 167 -154 391t154 391q-101 57 -218 57q-185 0 -316.5 -131.5t-131.5 -316.5zM1216 256q185 0 316.5 131.5t131.5 316.5 +t-131.5 316.5t-316.5 131.5q-117 0 -218 -57q154 -167 154 -391t-154 -391q101 -57 218 -57z" /> + <glyph glyph-name="_518" unicode="&#xf229;" +d="M1472 1408q26 0 45 -19t19 -45v-416q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v262l-213 -214l140 -140q9 -10 9 -23t-9 -22l-46 -46q-9 -9 -22 -9t-23 9l-140 141l-78 -79q126 -156 126 -359q0 -117 -45.5 -223.5t-123 -184t-184 -123t-223.5 -45.5t-223.5 45.5 +t-184 123t-123 184t-45.5 223.5t45.5 223.5t123 184t184 123t223.5 45.5q203 0 359 -126l78 78l-172 172q-9 10 -9 23t9 22l46 46q9 9 22 9t23 -9l172 -172l213 213h-261q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h416zM576 0q185 0 316.5 131.5t131.5 316.5t-131.5 316.5 +t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" /> + <glyph glyph-name="_519" unicode="&#xf22a;" horiz-adv-x="1280" +d="M640 892q217 -24 364.5 -187.5t147.5 -384.5q0 -167 -87 -306t-236 -212t-319 -54q-133 15 -245.5 88t-182 188t-80.5 249q-12 155 52.5 292t186 224t271.5 103v132h-160q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h160v165l-92 -92q-10 -9 -23 -9t-22 9l-46 46q-9 9 -9 22 +t9 23l202 201q19 19 45 19t45 -19l202 -201q9 -10 9 -23t-9 -22l-46 -46q-9 -9 -22 -9t-23 9l-92 92v-165h160q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-160v-132zM576 -128q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5 +t131.5 -316.5t316.5 -131.5z" /> + <glyph glyph-name="_520" unicode="&#xf22b;" horiz-adv-x="2048" +d="M1901 621q19 -19 19 -45t-19 -45l-294 -294q-9 -10 -22.5 -10t-22.5 10l-45 45q-10 9 -10 22.5t10 22.5l185 185h-294v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-132q-24 -217 -187.5 -364.5t-384.5 -147.5q-167 0 -306 87t-212 236t-54 319q15 133 88 245.5 +t188 182t249 80.5q155 12 292 -52.5t224 -186t103 -271.5h132v224q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-224h294l-185 185q-10 9 -10 22.5t10 22.5l45 45q9 10 22.5 10t22.5 -10zM576 128q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5 +t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" /> + <glyph glyph-name="_521" unicode="&#xf22c;" horiz-adv-x="1280" +d="M1152 960q0 -221 -147.5 -384.5t-364.5 -187.5v-612q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v612q-217 24 -364.5 187.5t-147.5 384.5q0 117 45.5 223.5t123 184t184 123t223.5 45.5t223.5 -45.5t184 -123t123 -184t45.5 -223.5zM576 512q185 0 316.5 131.5 +t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" /> + <glyph glyph-name="_522" unicode="&#xf22d;" horiz-adv-x="1280" +d="M1024 576q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5zM1152 576q0 -117 -45.5 -223.5t-123 -184t-184 -123t-223.5 -45.5t-223.5 45.5t-184 123t-123 184t-45.5 223.5t45.5 223.5t123 184t184 123 +t223.5 45.5t223.5 -45.5t184 -123t123 -184t45.5 -223.5z" /> + <glyph glyph-name="_523" unicode="&#xf22e;" horiz-adv-x="1792" + /> + <glyph glyph-name="_524" unicode="&#xf22f;" horiz-adv-x="1792" + /> + <glyph glyph-name="_525" unicode="&#xf230;" +d="M1451 1408q35 0 60 -25t25 -60v-1366q0 -35 -25 -60t-60 -25h-391v595h199l30 232h-229v148q0 56 23.5 84t91.5 28l122 1v207q-63 9 -178 9q-136 0 -217.5 -80t-81.5 -226v-171h-200v-232h200v-595h-735q-35 0 -60 25t-25 60v1366q0 35 25 60t60 25h1366z" /> + <glyph glyph-name="_526" unicode="&#xf231;" horiz-adv-x="1280" +d="M0 939q0 108 37.5 203.5t103.5 166.5t152 123t185 78t202 26q158 0 294 -66.5t221 -193.5t85 -287q0 -96 -19 -188t-60 -177t-100 -149.5t-145 -103t-189 -38.5q-68 0 -135 32t-96 88q-10 -39 -28 -112.5t-23.5 -95t-20.5 -71t-26 -71t-32 -62.5t-46 -77.5t-62 -86.5 +l-14 -5l-9 10q-15 157 -15 188q0 92 21.5 206.5t66.5 287.5t52 203q-32 65 -32 169q0 83 52 156t132 73q61 0 95 -40.5t34 -102.5q0 -66 -44 -191t-44 -187q0 -63 45 -104.5t109 -41.5q55 0 102 25t78.5 68t56 95t38 110.5t20 111t6.5 99.5q0 173 -109.5 269.5t-285.5 96.5 +q-200 0 -334 -129.5t-134 -328.5q0 -44 12.5 -85t27 -65t27 -45.5t12.5 -30.5q0 -28 -15 -73t-37 -45q-2 0 -17 3q-51 15 -90.5 56t-61 94.5t-32.5 108t-11 106.5z" /> + <glyph glyph-name="_527" unicode="&#xf232;" +d="M985 562q13 0 97.5 -44t89.5 -53q2 -5 2 -15q0 -33 -17 -76q-16 -39 -71 -65.5t-102 -26.5q-57 0 -190 62q-98 45 -170 118t-148 185q-72 107 -71 194v8q3 91 74 158q24 22 52 22q6 0 18 -1.5t19 -1.5q19 0 26.5 -6.5t15.5 -27.5q8 -20 33 -88t25 -75q0 -21 -34.5 -57.5 +t-34.5 -46.5q0 -7 5 -15q34 -73 102 -137q56 -53 151 -101q12 -7 22 -7q15 0 54 48.5t52 48.5zM782 32q127 0 243.5 50t200.5 134t134 200.5t50 243.5t-50 243.5t-134 200.5t-200.5 134t-243.5 50t-243.5 -50t-200.5 -134t-134 -200.5t-50 -243.5q0 -203 120 -368l-79 -233 +l242 77q158 -104 345 -104zM782 1414q153 0 292.5 -60t240.5 -161t161 -240.5t60 -292.5t-60 -292.5t-161 -240.5t-240.5 -161t-292.5 -60q-195 0 -365 94l-417 -134l136 405q-108 178 -108 389q0 153 60 292.5t161 240.5t240.5 161t292.5 60z" /> + <glyph glyph-name="_528" unicode="&#xf233;" horiz-adv-x="1792" +d="M128 128h1024v128h-1024v-128zM128 640h1024v128h-1024v-128zM1696 192q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM128 1152h1024v128h-1024v-128zM1696 704q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1696 1216 +q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1792 384v-384h-1792v384h1792zM1792 896v-384h-1792v384h1792zM1792 1408v-384h-1792v384h1792z" /> + <glyph glyph-name="_529" unicode="&#xf234;" horiz-adv-x="2048" +d="M704 640q-159 0 -271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5t-112.5 -271.5t-271.5 -112.5zM1664 512h352q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-352v-352q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5 +t-9.5 22.5v352h-352q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h352v352q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5v-352zM928 288q0 -52 38 -90t90 -38h256v-238q-68 -50 -171 -50h-874q-121 0 -194 69t-73 190q0 53 3.5 103.5t14 109t26.5 108.5 +t43 97.5t62 81t85.5 53.5t111.5 20q19 0 39 -17q79 -61 154.5 -91.5t164.5 -30.5t164.5 30.5t154.5 91.5q20 17 39 17q132 0 217 -96h-223q-52 0 -90 -38t-38 -90v-192z" /> + <glyph glyph-name="_530" unicode="&#xf235;" horiz-adv-x="2048" +d="M704 640q-159 0 -271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5t-112.5 -271.5t-271.5 -112.5zM1781 320l249 -249q9 -9 9 -23q0 -13 -9 -22l-136 -136q-9 -9 -22 -9q-14 0 -23 9l-249 249l-249 -249q-9 -9 -23 -9q-13 0 -22 9l-136 136 +q-9 9 -9 22q0 14 9 23l249 249l-249 249q-9 9 -9 23q0 13 9 22l136 136q9 9 22 9q14 0 23 -9l249 -249l249 249q9 9 23 9q13 0 22 -9l136 -136q9 -9 9 -22q0 -14 -9 -23zM1283 320l-181 -181q-37 -37 -37 -91q0 -53 37 -90l83 -83q-21 -3 -44 -3h-874q-121 0 -194 69 +t-73 190q0 53 3.5 103.5t14 109t26.5 108.5t43 97.5t62 81t85.5 53.5t111.5 20q19 0 39 -17q154 -122 319 -122t319 122q20 17 39 17q28 0 57 -6q-28 -27 -41 -50t-13 -56q0 -54 37 -91z" /> + <glyph glyph-name="_531" unicode="&#xf236;" horiz-adv-x="2048" +d="M256 512h1728q26 0 45 -19t19 -45v-448h-256v256h-1536v-256h-256v1216q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-704zM832 832q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM2048 576v64q0 159 -112.5 271.5t-271.5 112.5h-704 +q-26 0 -45 -19t-19 -45v-384h1152z" /> + <glyph glyph-name="_532" unicode="&#xf237;" +d="M1536 1536l-192 -448h192v-192h-274l-55 -128h329v-192h-411l-357 -832l-357 832h-411v192h329l-55 128h-274v192h192l-192 448h256l323 -768h378l323 768h256zM768 320l108 256h-216z" /> + <glyph glyph-name="_533" unicode="&#xf238;" +d="M1088 1536q185 0 316.5 -93.5t131.5 -226.5v-896q0 -130 -125.5 -222t-305.5 -97l213 -202q16 -15 8 -35t-30 -20h-1056q-22 0 -30 20t8 35l213 202q-180 5 -305.5 97t-125.5 222v896q0 133 131.5 226.5t316.5 93.5h640zM768 192q80 0 136 56t56 136t-56 136t-136 56 +t-136 -56t-56 -136t56 -136t136 -56zM1344 768v512h-1152v-512h1152z" /> + <glyph glyph-name="_534" unicode="&#xf239;" +d="M1088 1536q185 0 316.5 -93.5t131.5 -226.5v-896q0 -130 -125.5 -222t-305.5 -97l213 -202q16 -15 8 -35t-30 -20h-1056q-22 0 -30 20t8 35l213 202q-180 5 -305.5 97t-125.5 222v896q0 133 131.5 226.5t316.5 93.5h640zM288 224q66 0 113 47t47 113t-47 113t-113 47 +t-113 -47t-47 -113t47 -113t113 -47zM704 768v512h-544v-512h544zM1248 224q66 0 113 47t47 113t-47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47zM1408 768v512h-576v-512h576z" /> + <glyph glyph-name="_535" unicode="&#xf23a;" horiz-adv-x="1792" +d="M597 1115v-1173q0 -25 -12.5 -42.5t-36.5 -17.5q-17 0 -33 8l-465 233q-21 10 -35.5 33.5t-14.5 46.5v1140q0 20 10 34t29 14q14 0 44 -15l511 -256q3 -3 3 -5zM661 1014l534 -866l-534 266v600zM1792 996v-1054q0 -25 -14 -40.5t-38 -15.5t-47 13l-441 220zM1789 1116 +q0 -3 -256.5 -419.5t-300.5 -487.5l-390 634l324 527q17 28 52 28q14 0 26 -6l541 -270q4 -2 4 -6z" /> + <glyph glyph-name="_536" unicode="&#xf23b;" +d="M809 532l266 499h-112l-157 -312q-24 -48 -44 -92l-42 92l-155 312h-120l263 -493v-324h101v318zM1536 1408v-1536h-1536v1536h1536z" /> + <glyph glyph-name="_537" unicode="&#xf23c;" horiz-adv-x="2296" +d="M478 -139q-8 -16 -27 -34.5t-37 -25.5q-25 -9 -51.5 3.5t-28.5 31.5q-1 22 40 55t68 38q23 4 34 -21.5t2 -46.5zM1819 -139q7 -16 26 -34.5t38 -25.5q25 -9 51.5 3.5t27.5 31.5q2 22 -39.5 55t-68.5 38q-22 4 -33 -21.5t-2 -46.5zM1867 -30q13 -27 56.5 -59.5t77.5 -41.5 +q45 -13 82 4.5t37 50.5q0 46 -67.5 100.5t-115.5 59.5q-40 5 -63.5 -37.5t-6.5 -76.5zM428 -30q-13 -27 -56 -59.5t-77 -41.5q-45 -13 -82 4.5t-37 50.5q0 46 67.5 100.5t115.5 59.5q40 5 63 -37.5t6 -76.5zM1158 1094h1q-41 0 -76 -15q27 -8 44 -30.5t17 -49.5 +q0 -35 -27 -60t-65 -25q-52 0 -80 43q-5 -23 -5 -42q0 -74 56 -126.5t135 -52.5q80 0 136 52.5t56 126.5t-56 126.5t-136 52.5zM1462 1312q-99 109 -220.5 131.5t-245.5 -44.5q27 60 82.5 96.5t118 39.5t121.5 -17t99.5 -74.5t44.5 -131.5zM2212 73q8 -11 -11 -42 +q7 -23 7 -40q1 -56 -44.5 -112.5t-109.5 -91.5t-118 -37q-48 -2 -92 21.5t-66 65.5q-687 -25 -1259 0q-23 -41 -66.5 -65t-92.5 -22q-86 3 -179.5 80.5t-92.5 160.5q2 22 7 40q-19 31 -11 42q6 10 31 1q14 22 41 51q-7 29 2 38q11 10 39 -4q29 20 59 34q0 29 13 37 +q23 12 51 -16q35 5 61 -2q18 -4 38 -19v73q-11 0 -18 2q-53 10 -97 44.5t-55 87.5q-9 38 0 81q15 62 93 95q2 17 19 35.5t36 23.5t33 -7.5t19 -30.5h13q46 -5 60 -23q3 -3 5 -7q10 1 30.5 3.5t30.5 3.5q-15 11 -30 17q-23 40 -91 43q0 6 1 10q-62 2 -118.5 18.5t-84.5 47.5 +q-32 36 -42.5 92t-2.5 112q16 126 90 179q23 16 52 4.5t32 -40.5q0 -1 1.5 -14t2.5 -21t3 -20t5.5 -19t8.5 -10q27 -14 76 -12q48 46 98 74q-40 4 -162 -14l47 46q61 58 163 111q145 73 282 86q-20 8 -41 15.5t-47 14t-42.5 10.5t-47.5 11t-43 10q595 126 904 -139 +q98 -84 158 -222q85 -10 121 9h1q5 3 8.5 10t5.5 19t3 19.5t3 21.5l1 14q3 28 32 40t52 -5q73 -52 91 -178q7 -57 -3.5 -113t-42.5 -91q-28 -32 -83.5 -48.5t-115.5 -18.5v-10q-71 -2 -95 -43q-14 -5 -31 -17q11 -1 32 -3.5t30 -3.5q1 5 5 8q16 18 60 23h13q5 18 19 30t33 8 +t36 -23t19 -36q79 -32 93 -95q9 -40 1 -81q-12 -53 -56 -88t-97 -44q-10 -2 -17 -2q0 -49 -1 -73q20 15 38 19q26 7 61 2q28 28 51 16q14 -9 14 -37q33 -16 59 -34q27 13 38 4q10 -10 2 -38q28 -30 41 -51q23 8 31 -1zM1937 1025q0 -29 -9 -54q82 -32 112 -132 +q4 37 -9.5 98.5t-41.5 90.5q-20 19 -36 17t-16 -20zM1859 925q35 -42 47.5 -108.5t-0.5 -124.5q67 13 97 45q13 14 18 28q-3 64 -31 114.5t-79 66.5q-15 -15 -52 -21zM1822 921q-30 0 -44 1q42 -115 53 -239q21 0 43 3q16 68 1 135t-53 100zM258 839q30 100 112 132 +q-9 25 -9 54q0 18 -16.5 20t-35.5 -17q-28 -29 -41.5 -90.5t-9.5 -98.5zM294 737q29 -31 97 -45q-13 58 -0.5 124.5t47.5 108.5v0q-37 6 -52 21q-51 -16 -78.5 -66t-31.5 -115q9 -17 18 -28zM471 683q14 124 73 235q-19 -4 -55 -18l-45 -19v1q-46 -89 -20 -196q25 -3 47 -3z +M1434 644q8 -38 16.5 -108.5t11.5 -89.5q3 -18 9.5 -21.5t23.5 4.5q40 20 62 85.5t23 125.5q-24 2 -146 4zM1152 1285q-116 0 -199 -82.5t-83 -198.5q0 -117 83 -199.5t199 -82.5t199 82.5t83 199.5q0 116 -83 198.5t-199 82.5zM1380 646q-105 2 -211 0v1q-1 -27 2.5 -86 +t13.5 -66q29 -14 93.5 -14.5t95.5 10.5q9 3 11 39t-0.5 69.5t-4.5 46.5zM1112 447q8 4 9.5 48t-0.5 88t-4 63v1q-212 -3 -214 -3q-4 -20 -7 -62t0 -83t14 -46q34 -15 101 -16t101 10zM718 636q-16 -59 4.5 -118.5t77.5 -84.5q15 -8 24 -5t12 21q3 16 8 90t10 103 +q-69 -2 -136 -6zM591 510q3 -23 -34 -36q132 -141 271.5 -240t305.5 -154q172 49 310.5 146t293.5 250q-33 13 -30 34q0 2 0.5 3.5t1.5 3t1 2.5v1v-1q-17 2 -50 5.5t-48 4.5q-26 -90 -82 -132q-51 -38 -82 1q-5 6 -9 14q-7 13 -17 62q-2 -5 -5 -9t-7.5 -7t-8 -5.5t-9.5 -4 +l-10 -2.5t-12 -2l-12 -1.5t-13.5 -1t-13.5 -0.5q-106 -9 -163 11q-4 -17 -10 -26.5t-21 -15t-23 -7t-36 -3.5q-6 -1 -9 -1q-179 -17 -203 40q-2 -63 -56 -54q-47 8 -91 54q-12 13 -20 26q-17 29 -26 65q-58 -6 -87 -10q1 -2 4 -10zM507 -118q3 14 3 30q-17 71 -51 130 +t-73 70q-41 12 -101.5 -14.5t-104.5 -80t-39 -107.5q35 -53 100 -93t119 -42q51 -2 94 28t53 79zM510 53q23 -63 27 -119q195 113 392 174q-98 52 -180.5 120t-179.5 165q-6 -4 -29 -13q0 -1 -1 -4t-1 -5q31 -18 22 -37q-12 -23 -56 -34q-10 -13 -29 -24h-1q-2 -83 1 -150 +q19 -34 35 -73zM579 -113q532 -21 1145 0q-254 147 -428 196q-76 -35 -156 -57q-8 -3 -16 0q-65 21 -129 49q-208 -60 -416 -188h-1v-1q1 0 1 1zM1763 -67q4 54 28 120q14 38 33 71l-1 -1q3 77 3 153q-15 8 -30 25q-42 9 -56 33q-9 20 22 38q-2 4 -2 9q-16 4 -28 12 +q-204 -190 -383 -284q198 -59 414 -176zM2155 -90q5 54 -39 107.5t-104 80t-102 14.5q-38 -11 -72.5 -70.5t-51.5 -129.5q0 -16 3 -30q10 -49 53 -79t94 -28q54 2 119 42t100 93z" /> + <glyph glyph-name="_538" unicode="&#xf23d;" horiz-adv-x="2304" +d="M1524 -25q0 -68 -48 -116t-116 -48t-116.5 48t-48.5 116t48.5 116.5t116.5 48.5t116 -48.5t48 -116.5zM775 -25q0 -68 -48.5 -116t-116.5 -48t-116 48t-48 116t48 116.5t116 48.5t116.5 -48.5t48.5 -116.5zM0 1469q57 -60 110.5 -104.5t121 -82t136 -63t166 -45.5 +t200 -31.5t250 -18.5t304 -9.5t372.5 -2.5q139 0 244.5 -5t181 -16.5t124 -27.5t71 -39.5t24 -51.5t-19.5 -64t-56.5 -76.5t-89.5 -91t-116 -104.5t-139 -119q-185 -157 -286 -247q29 51 76.5 109t94 105.5t94.5 98.5t83 91.5t54 80.5t13 70t-45.5 55.5t-116.5 41t-204 23.5 +t-304 5q-168 -2 -314 6t-256 23t-204.5 41t-159.5 51.5t-122.5 62.5t-91.5 66.5t-68 71.5t-50.5 69.5t-40 68t-36.5 59.5z" /> + <glyph glyph-name="_539" unicode="&#xf23e;" horiz-adv-x="1792" +d="M896 1472q-169 0 -323 -66t-265.5 -177.5t-177.5 -265.5t-66 -323t66 -323t177.5 -265.5t265.5 -177.5t323 -66t323 66t265.5 177.5t177.5 265.5t66 323t-66 323t-177.5 265.5t-265.5 177.5t-323 66zM896 1536q182 0 348 -71t286 -191t191 -286t71 -348t-71 -348 +t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71zM496 704q16 0 16 -16v-480q0 -16 -16 -16h-32q-16 0 -16 16v480q0 16 16 16h32zM896 640q53 0 90.5 -37.5t37.5 -90.5q0 -35 -17.5 -64t-46.5 -46v-114q0 -14 -9 -23 +t-23 -9h-64q-14 0 -23 9t-9 23v114q-29 17 -46.5 46t-17.5 64q0 53 37.5 90.5t90.5 37.5zM896 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM544 928v-96 +q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v96q0 93 65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5v-96q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v96q0 146 -103 249t-249 103t-249 -103t-103 -249zM1408 192v512q0 26 -19 45t-45 19h-896q-26 0 -45 -19t-19 -45v-512 +q0 -26 19 -45t45 -19h896q26 0 45 19t19 45z" /> + <glyph glyph-name="_540" unicode="&#xf240;" horiz-adv-x="2304" +d="M1920 1024v-768h-1664v768h1664zM2048 448h128v384h-128v288q0 14 -9 23t-23 9h-1856q-14 0 -23 -9t-9 -23v-960q0 -14 9 -23t23 -9h1856q14 0 23 9t9 23v288zM2304 832v-384q0 -53 -37.5 -90.5t-90.5 -37.5v-160q0 -66 -47 -113t-113 -47h-1856q-66 0 -113 47t-47 113 +v960q0 66 47 113t113 47h1856q66 0 113 -47t47 -113v-160q53 0 90.5 -37.5t37.5 -90.5z" /> + <glyph glyph-name="_541" unicode="&#xf241;" horiz-adv-x="2304" +d="M256 256v768h1280v-768h-1280zM2176 960q53 0 90.5 -37.5t37.5 -90.5v-384q0 -53 -37.5 -90.5t-90.5 -37.5v-160q0 -66 -47 -113t-113 -47h-1856q-66 0 -113 47t-47 113v960q0 66 47 113t113 47h1856q66 0 113 -47t47 -113v-160zM2176 448v384h-128v288q0 14 -9 23t-23 9 +h-1856q-14 0 -23 -9t-9 -23v-960q0 -14 9 -23t23 -9h1856q14 0 23 9t9 23v288h128z" /> + <glyph glyph-name="_542" unicode="&#xf242;" horiz-adv-x="2304" +d="M256 256v768h896v-768h-896zM2176 960q53 0 90.5 -37.5t37.5 -90.5v-384q0 -53 -37.5 -90.5t-90.5 -37.5v-160q0 -66 -47 -113t-113 -47h-1856q-66 0 -113 47t-47 113v960q0 66 47 113t113 47h1856q66 0 113 -47t47 -113v-160zM2176 448v384h-128v288q0 14 -9 23t-23 9 +h-1856q-14 0 -23 -9t-9 -23v-960q0 -14 9 -23t23 -9h1856q14 0 23 9t9 23v288h128z" /> + <glyph glyph-name="_543" unicode="&#xf243;" horiz-adv-x="2304" +d="M256 256v768h512v-768h-512zM2176 960q53 0 90.5 -37.5t37.5 -90.5v-384q0 -53 -37.5 -90.5t-90.5 -37.5v-160q0 -66 -47 -113t-113 -47h-1856q-66 0 -113 47t-47 113v960q0 66 47 113t113 47h1856q66 0 113 -47t47 -113v-160zM2176 448v384h-128v288q0 14 -9 23t-23 9 +h-1856q-14 0 -23 -9t-9 -23v-960q0 -14 9 -23t23 -9h1856q14 0 23 9t9 23v288h128z" /> + <glyph glyph-name="_544" unicode="&#xf244;" horiz-adv-x="2304" +d="M2176 960q53 0 90.5 -37.5t37.5 -90.5v-384q0 -53 -37.5 -90.5t-90.5 -37.5v-160q0 -66 -47 -113t-113 -47h-1856q-66 0 -113 47t-47 113v960q0 66 47 113t113 47h1856q66 0 113 -47t47 -113v-160zM2176 448v384h-128v288q0 14 -9 23t-23 9h-1856q-14 0 -23 -9t-9 -23 +v-960q0 -14 9 -23t23 -9h1856q14 0 23 9t9 23v288h128z" /> + <glyph glyph-name="_545" unicode="&#xf245;" horiz-adv-x="1280" +d="M1133 493q31 -30 14 -69q-17 -40 -59 -40h-382l201 -476q10 -25 0 -49t-34 -35l-177 -75q-25 -10 -49 0t-35 34l-191 452l-312 -312q-19 -19 -45 -19q-12 0 -24 5q-40 17 -40 59v1504q0 42 40 59q12 5 24 5q27 0 45 -19z" /> + <glyph glyph-name="_546" unicode="&#xf246;" horiz-adv-x="1024" +d="M832 1408q-320 0 -320 -224v-416h128v-128h-128v-544q0 -224 320 -224h64v-128h-64q-272 0 -384 146q-112 -146 -384 -146h-64v128h64q320 0 320 224v544h-128v128h128v416q0 224 -320 224h-64v128h64q272 0 384 -146q112 146 384 146h64v-128h-64z" /> + <glyph glyph-name="_547" unicode="&#xf247;" horiz-adv-x="2048" +d="M2048 1152h-128v-1024h128v-384h-384v128h-1280v-128h-384v384h128v1024h-128v384h384v-128h1280v128h384v-384zM1792 1408v-128h128v128h-128zM128 1408v-128h128v128h-128zM256 -128v128h-128v-128h128zM1664 0v128h128v1024h-128v128h-1280v-128h-128v-1024h128v-128 +h1280zM1920 -128v128h-128v-128h128zM1280 896h384v-768h-896v256h-384v768h896v-256zM512 512h640v512h-640v-512zM1536 256v512h-256v-384h-384v-128h640z" /> + <glyph glyph-name="_548" unicode="&#xf248;" horiz-adv-x="2304" +d="M2304 768h-128v-640h128v-384h-384v128h-896v-128h-384v384h128v128h-384v-128h-384v384h128v640h-128v384h384v-128h896v128h384v-384h-128v-128h384v128h384v-384zM2048 1024v-128h128v128h-128zM1408 1408v-128h128v128h-128zM128 1408v-128h128v128h-128zM256 256 +v128h-128v-128h128zM1536 384h-128v-128h128v128zM384 384h896v128h128v640h-128v128h-896v-128h-128v-640h128v-128zM896 -128v128h-128v-128h128zM2176 -128v128h-128v-128h128zM2048 128v640h-128v128h-384v-384h128v-384h-384v128h-384v-128h128v-128h896v128h128z" /> + <glyph glyph-name="_549" unicode="&#xf249;" +d="M1024 288v-416h-928q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h1344q40 0 68 -28t28 -68v-928h-416q-40 0 -68 -28t-28 -68zM1152 256h381q-15 -82 -65 -132l-184 -184q-50 -50 -132 -65v381z" /> + <glyph glyph-name="_550" unicode="&#xf24a;" +d="M1400 256h-248v-248q29 10 41 22l185 185q12 12 22 41zM1120 384h288v896h-1280v-1280h896v288q0 40 28 68t68 28zM1536 1312v-1024q0 -40 -20 -88t-48 -76l-184 -184q-28 -28 -76 -48t-88 -20h-1024q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h1344q40 0 68 -28t28 -68 +z" /> + <glyph glyph-name="_551" unicode="&#xf24b;" horiz-adv-x="2304" +d="M1951 538q0 -26 -15.5 -44.5t-38.5 -23.5q-8 -2 -18 -2h-153v140h153q10 0 18 -2q23 -5 38.5 -23.5t15.5 -44.5zM1933 751q0 -25 -15 -42t-38 -21q-3 -1 -15 -1h-139v129h139q3 0 8.5 -0.5t6.5 -0.5q23 -4 38 -21.5t15 -42.5zM728 587v308h-228v-308q0 -58 -38 -94.5 +t-105 -36.5q-108 0 -229 59v-112q53 -15 121 -23t109 -9l42 -1q328 0 328 217zM1442 403v113q-99 -52 -200 -59q-108 -8 -169 41t-61 142t61 142t169 41q101 -7 200 -58v112q-48 12 -100 19.5t-80 9.5l-28 2q-127 6 -218.5 -14t-140.5 -60t-71 -88t-22 -106t22 -106t71 -88 +t140.5 -60t218.5 -14q101 4 208 31zM2176 518q0 54 -43 88.5t-109 39.5v3q57 8 89 41.5t32 79.5q0 55 -41 88t-107 36q-3 0 -12 0.5t-14 0.5h-455v-510h491q74 0 121.5 36.5t47.5 96.5zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90 +t90 38h2048q52 0 90 -38t38 -90z" /> + <glyph glyph-name="_552" unicode="&#xf24c;" horiz-adv-x="2304" +d="M858 295v693q-106 -41 -172 -135.5t-66 -211.5t66 -211.5t172 -134.5zM1362 641q0 117 -66 211.5t-172 135.5v-694q106 41 172 135.5t66 211.5zM1577 641q0 -159 -78.5 -294t-213.5 -213.5t-294 -78.5q-119 0 -227.5 46.5t-187 125t-125 187t-46.5 227.5q0 159 78.5 294 +t213.5 213.5t294 78.5t294 -78.5t213.5 -213.5t78.5 -294zM1960 634q0 139 -55.5 261.5t-147.5 205.5t-213.5 131t-252.5 48h-301q-176 0 -323.5 -81t-235 -230t-87.5 -335q0 -171 87 -317.5t236 -231.5t323 -85h301q129 0 251.5 50.5t214.5 135t147.5 202.5t55.5 246z +M2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" /> + <glyph glyph-name="_553" unicode="&#xf24d;" horiz-adv-x="1792" +d="M1664 -96v1088q0 13 -9.5 22.5t-22.5 9.5h-1088q-13 0 -22.5 -9.5t-9.5 -22.5v-1088q0 -13 9.5 -22.5t22.5 -9.5h1088q13 0 22.5 9.5t9.5 22.5zM1792 992v-1088q0 -66 -47 -113t-113 -47h-1088q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1088q66 0 113 -47t47 -113 +zM1408 1376v-160h-128v160q0 13 -9.5 22.5t-22.5 9.5h-1088q-13 0 -22.5 -9.5t-9.5 -22.5v-1088q0 -13 9.5 -22.5t22.5 -9.5h160v-128h-160q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1088q66 0 113 -47t47 -113z" /> + <glyph glyph-name="_554" unicode="&#xf24e;" horiz-adv-x="2304" +d="M1728 1088l-384 -704h768zM448 1088l-384 -704h768zM1269 1280q-14 -40 -45.5 -71.5t-71.5 -45.5v-1291h608q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1344q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h608v1291q-40 14 -71.5 45.5t-45.5 71.5h-491q-14 0 -23 9t-9 23v64 +q0 14 9 23t23 9h491q21 57 70 92.5t111 35.5t111 -35.5t70 -92.5h491q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-491zM1088 1264q33 0 56.5 23.5t23.5 56.5t-23.5 56.5t-56.5 23.5t-56.5 -23.5t-23.5 -56.5t23.5 -56.5t56.5 -23.5zM2176 384q0 -73 -46.5 -131t-117.5 -91 +t-144.5 -49.5t-139.5 -16.5t-139.5 16.5t-144.5 49.5t-117.5 91t-46.5 131q0 11 35 81t92 174.5t107 195.5t102 184t56 100q18 33 56 33t56 -33q4 -7 56 -100t102 -184t107 -195.5t92 -174.5t35 -81zM896 384q0 -73 -46.5 -131t-117.5 -91t-144.5 -49.5t-139.5 -16.5 +t-139.5 16.5t-144.5 49.5t-117.5 91t-46.5 131q0 11 35 81t92 174.5t107 195.5t102 184t56 100q18 33 56 33t56 -33q4 -7 56 -100t102 -184t107 -195.5t92 -174.5t35 -81z" /> + <glyph glyph-name="_555" unicode="&#xf250;" +d="M1408 1408q0 -261 -106.5 -461.5t-266.5 -306.5q160 -106 266.5 -306.5t106.5 -461.5h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1472q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96q0 261 106.5 461.5t266.5 306.5q-160 106 -266.5 306.5t-106.5 461.5h-96q-14 0 -23 9 +t-9 23v64q0 14 9 23t23 9h1472q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96zM874 700q77 29 149 92.5t129.5 152.5t92.5 210t35 253h-1024q0 -132 35 -253t92.5 -210t129.5 -152.5t149 -92.5q19 -7 30.5 -23.5t11.5 -36.5t-11.5 -36.5t-30.5 -23.5q-77 -29 -149 -92.5 +t-129.5 -152.5t-92.5 -210t-35 -253h1024q0 132 -35 253t-92.5 210t-129.5 152.5t-149 92.5q-19 7 -30.5 23.5t-11.5 36.5t11.5 36.5t30.5 23.5z" /> + <glyph glyph-name="_556" unicode="&#xf251;" +d="M1408 1408q0 -261 -106.5 -461.5t-266.5 -306.5q160 -106 266.5 -306.5t106.5 -461.5h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1472q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96q0 261 106.5 461.5t266.5 306.5q-160 106 -266.5 306.5t-106.5 461.5h-96q-14 0 -23 9 +t-9 23v64q0 14 9 23t23 9h1472q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96zM1280 1408h-1024q0 -66 9 -128h1006q9 61 9 128zM1280 -128q0 130 -34 249.5t-90.5 208t-126.5 152t-146 94.5h-230q-76 -31 -146 -94.5t-126.5 -152t-90.5 -208t-34 -249.5h1024z" /> + <glyph glyph-name="_557" unicode="&#xf252;" +d="M1408 1408q0 -261 -106.5 -461.5t-266.5 -306.5q160 -106 266.5 -306.5t106.5 -461.5h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1472q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96q0 261 106.5 461.5t266.5 306.5q-160 106 -266.5 306.5t-106.5 461.5h-96q-14 0 -23 9 +t-9 23v64q0 14 9 23t23 9h1472q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96zM1280 1408h-1024q0 -206 85 -384h854q85 178 85 384zM1223 192q-54 141 -145.5 241.5t-194.5 142.5h-230q-103 -42 -194.5 -142.5t-145.5 -241.5h910z" /> + <glyph glyph-name="_558" unicode="&#xf253;" +d="M1408 1408q0 -261 -106.5 -461.5t-266.5 -306.5q160 -106 266.5 -306.5t106.5 -461.5h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1472q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96q0 261 106.5 461.5t266.5 306.5q-160 106 -266.5 306.5t-106.5 461.5h-96q-14 0 -23 9 +t-9 23v64q0 14 9 23t23 9h1472q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96zM874 700q77 29 149 92.5t129.5 152.5t92.5 210t35 253h-1024q0 -132 35 -253t92.5 -210t129.5 -152.5t149 -92.5q19 -7 30.5 -23.5t11.5 -36.5t-11.5 -36.5t-30.5 -23.5q-137 -51 -244 -196 +h700q-107 145 -244 196q-19 7 -30.5 23.5t-11.5 36.5t11.5 36.5t30.5 23.5z" /> + <glyph glyph-name="_559" unicode="&#xf254;" +d="M1504 -64q14 0 23 -9t9 -23v-128q0 -14 -9 -23t-23 -9h-1472q-14 0 -23 9t-9 23v128q0 14 9 23t23 9h1472zM130 0q3 55 16 107t30 95t46 87t53.5 76t64.5 69.5t66 60t70.5 55t66.5 47.5t65 43q-43 28 -65 43t-66.5 47.5t-70.5 55t-66 60t-64.5 69.5t-53.5 76t-46 87 +t-30 95t-16 107h1276q-3 -55 -16 -107t-30 -95t-46 -87t-53.5 -76t-64.5 -69.5t-66 -60t-70.5 -55t-66.5 -47.5t-65 -43q43 -28 65 -43t66.5 -47.5t70.5 -55t66 -60t64.5 -69.5t53.5 -76t46 -87t30 -95t16 -107h-1276zM1504 1536q14 0 23 -9t9 -23v-128q0 -14 -9 -23t-23 -9 +h-1472q-14 0 -23 9t-9 23v128q0 14 9 23t23 9h1472z" /> + <glyph glyph-name="_560" unicode="&#xf255;" +d="M768 1152q-53 0 -90.5 -37.5t-37.5 -90.5v-128h-32v93q0 48 -32 81.5t-80 33.5q-46 0 -79 -33t-33 -79v-429l-32 30v172q0 48 -32 81.5t-80 33.5q-46 0 -79 -33t-33 -79v-224q0 -47 35 -82l310 -296q39 -39 39 -102q0 -26 19 -45t45 -19h640q26 0 45 19t19 45v25 +q0 41 10 77l108 436q10 36 10 77v246q0 48 -32 81.5t-80 33.5q-46 0 -79 -33t-33 -79v-32h-32v125q0 40 -25 72.5t-64 40.5q-14 2 -23 2q-46 0 -79 -33t-33 -79v-128h-32v122q0 51 -32.5 89.5t-82.5 43.5q-5 1 -13 1zM768 1280q84 0 149 -50q57 34 123 34q59 0 111 -27 +t86 -76q27 7 59 7q100 0 170 -71.5t70 -171.5v-246q0 -51 -13 -108l-109 -436q-6 -24 -6 -71q0 -80 -56 -136t-136 -56h-640q-84 0 -138 58.5t-54 142.5l-308 296q-76 73 -76 175v224q0 99 70.5 169.5t169.5 70.5q11 0 16 -1q6 95 75.5 160t164.5 65q52 0 98 -21 +q72 69 174 69z" /> + <glyph glyph-name="_561" unicode="&#xf256;" horiz-adv-x="1792" +d="M880 1408q-46 0 -79 -33t-33 -79v-656h-32v528q0 46 -33 79t-79 33t-79 -33t-33 -79v-528v-256l-154 205q-38 51 -102 51q-53 0 -90.5 -37.5t-37.5 -90.5q0 -43 26 -77l384 -512q38 -51 102 -51h688q34 0 61 22t34 56l76 405q5 32 5 59v498q0 46 -33 79t-79 33t-79 -33 +t-33 -79v-272h-32v528q0 46 -33 79t-79 33t-79 -33t-33 -79v-528h-32v656q0 46 -33 79t-79 33zM880 1536q68 0 125.5 -35.5t88.5 -96.5q19 4 42 4q99 0 169.5 -70.5t70.5 -169.5v-17q105 6 180.5 -64t75.5 -175v-498q0 -40 -8 -83l-76 -404q-14 -79 -76.5 -131t-143.5 -52 +h-688q-60 0 -114.5 27.5t-90.5 74.5l-384 512q-51 68 -51 154q0 106 75 181t181 75q78 0 128 -34v434q0 99 70.5 169.5t169.5 70.5q23 0 42 -4q31 61 88.5 96.5t125.5 35.5z" /> + <glyph glyph-name="_562" unicode="&#xf257;" horiz-adv-x="1792" +d="M1073 -128h-177q-163 0 -226 141q-23 49 -23 102v5q-62 30 -98.5 88.5t-36.5 127.5q0 38 5 48h-261q-106 0 -181 75t-75 181t75 181t181 75h113l-44 17q-74 28 -119.5 93.5t-45.5 145.5q0 106 75 181t181 75q46 0 91 -17l628 -239h401q106 0 181 -75t75 -181v-668 +q0 -88 -54 -157.5t-140 -90.5l-339 -85q-92 -23 -186 -23zM1024 583l-155 -71l-163 -74q-30 -14 -48 -41.5t-18 -60.5q0 -46 33 -79t79 -33q26 0 46 10l338 154q-49 10 -80.5 50t-31.5 90v55zM1344 272q0 46 -33 79t-79 33q-26 0 -46 -10l-290 -132q-28 -13 -37 -17 +t-30.5 -17t-29.5 -23.5t-16 -29t-8 -40.5q0 -50 31.5 -82t81.5 -32q20 0 38 9l352 160q30 14 48 41.5t18 60.5zM1112 1024l-650 248q-24 8 -46 8q-53 0 -90.5 -37.5t-37.5 -90.5q0 -40 22.5 -73t59.5 -47l526 -200v-64h-640q-53 0 -90.5 -37.5t-37.5 -90.5t37.5 -90.5 +t90.5 -37.5h535l233 106v198q0 63 46 106l111 102h-69zM1073 0q82 0 155 19l339 85q43 11 70 45.5t27 78.5v668q0 53 -37.5 90.5t-90.5 37.5h-308l-136 -126q-36 -33 -36 -82v-296q0 -46 33 -77t79 -31t79 35t33 81v208h32v-208q0 -70 -57 -114q52 -8 86.5 -48.5t34.5 -93.5 +q0 -42 -23 -78t-61 -53l-310 -141h91z" /> + <glyph glyph-name="_563" unicode="&#xf258;" horiz-adv-x="2048" +d="M1151 1536q61 0 116 -28t91 -77l572 -781q118 -159 118 -359v-355q0 -80 -56 -136t-136 -56h-384q-80 0 -136 56t-56 136v177l-286 143h-546q-80 0 -136 56t-56 136v32q0 119 84.5 203.5t203.5 84.5h420l42 128h-686q-100 0 -173.5 67.5t-81.5 166.5q-65 79 -65 182v32 +q0 80 56 136t136 56h959zM1920 -64v355q0 157 -93 284l-573 781q-39 52 -103 52h-959q-26 0 -45 -19t-19 -45q0 -32 1.5 -49.5t9.5 -40.5t25 -43q10 31 35.5 50t56.5 19h832v-32h-832q-26 0 -45 -19t-19 -45q0 -44 3 -58q8 -44 44 -73t81 -29h640h91q40 0 68 -28t28 -68 +q0 -15 -5 -30l-64 -192q-10 -29 -35 -47.5t-56 -18.5h-443q-66 0 -113 -47t-47 -113v-32q0 -26 19 -45t45 -19h561q16 0 29 -7l317 -158q24 -13 38.5 -36t14.5 -50v-197q0 -26 19 -45t45 -19h384q26 0 45 19t19 45z" /> + <glyph glyph-name="_564" unicode="&#xf259;" horiz-adv-x="2048" +d="M459 -256q-77 0 -137.5 47.5t-79.5 122.5l-101 401q-13 57 -13 108q0 45 -5 67l-116 477q-7 27 -7 57q0 93 62 161t155 78q17 85 82.5 139t152.5 54q83 0 148 -51.5t85 -132.5l83 -348l103 428q20 81 85 132.5t148 51.5q89 0 155.5 -57.5t80.5 -144.5q92 -10 152 -79 +t60 -162q0 -24 -7 -59l-123 -512q10 7 37.5 28.5t38.5 29.5t35 23t41 20.5t41.5 11t49.5 5.5q105 0 180 -74t75 -179q0 -62 -28.5 -118t-78.5 -94l-507 -380q-68 -51 -153 -51h-694zM1104 1408q-38 0 -68.5 -24t-39.5 -62l-164 -682h-127l-145 602q-9 38 -39.5 62t-68.5 24 +q-48 0 -80 -33t-32 -80q0 -15 3 -28l132 -547h-26l-99 408q-9 37 -40 62.5t-69 25.5q-47 0 -80 -33t-33 -79q0 -14 3 -26l116 -478q7 -28 9 -86t10 -88l100 -401q8 -32 34 -52.5t59 -20.5h694q42 0 76 26l507 379q56 43 56 110q0 52 -37.5 88.5t-89.5 36.5q-43 0 -77 -26 +l-307 -230v227q0 4 32 138t68 282t39 161q4 18 4 29q0 47 -32 81t-79 34q-39 0 -69.5 -24t-39.5 -62l-116 -482h-26l150 624q3 14 3 28q0 48 -31.5 82t-79.5 34z" /> + <glyph glyph-name="_565" unicode="&#xf25a;" horiz-adv-x="1792" +d="M640 1408q-53 0 -90.5 -37.5t-37.5 -90.5v-512v-384l-151 202q-41 54 -107 54q-52 0 -89 -38t-37 -90q0 -43 26 -77l384 -512q38 -51 102 -51h718q22 0 39.5 13.5t22.5 34.5l92 368q24 96 24 194v217q0 41 -28 71t-68 30t-68 -28t-28 -68h-32v61q0 48 -32 81.5t-80 33.5 +q-46 0 -79 -33t-33 -79v-64h-32v90q0 55 -37 94.5t-91 39.5q-53 0 -90.5 -37.5t-37.5 -90.5v-96h-32v570q0 55 -37 94.5t-91 39.5zM640 1536q107 0 181.5 -77.5t74.5 -184.5v-220q22 2 32 2q99 0 173 -69q47 21 99 21q113 0 184 -87q27 7 56 7q94 0 159 -67.5t65 -161.5 +v-217q0 -116 -28 -225l-92 -368q-16 -64 -68 -104.5t-118 -40.5h-718q-60 0 -114.5 27.5t-90.5 74.5l-384 512q-51 68 -51 154q0 105 74.5 180.5t179.5 75.5q71 0 130 -35v547q0 106 75 181t181 75zM768 128v384h-32v-384h32zM1024 128v384h-32v-384h32zM1280 128v384h-32 +v-384h32z" /> + <glyph glyph-name="_566" unicode="&#xf25b;" +d="M1288 889q60 0 107 -23q141 -63 141 -226v-177q0 -94 -23 -186l-85 -339q-21 -86 -90.5 -140t-157.5 -54h-668q-106 0 -181 75t-75 181v401l-239 628q-17 45 -17 91q0 106 75 181t181 75q80 0 145.5 -45.5t93.5 -119.5l17 -44v113q0 106 75 181t181 75t181 -75t75 -181 +v-261q27 5 48 5q69 0 127.5 -36.5t88.5 -98.5zM1072 896q-33 0 -60.5 -18t-41.5 -48l-74 -163l-71 -155h55q50 0 90 -31.5t50 -80.5l154 338q10 20 10 46q0 46 -33 79t-79 33zM1293 761q-22 0 -40.5 -8t-29 -16t-23.5 -29.5t-17 -30.5t-17 -37l-132 -290q-10 -20 -10 -46 +q0 -46 33 -79t79 -33q33 0 60.5 18t41.5 48l160 352q9 18 9 38q0 50 -32 81.5t-82 31.5zM128 1120q0 -22 8 -46l248 -650v-69l102 111q43 46 106 46h198l106 233v535q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5v-640h-64l-200 526q-14 37 -47 59.5t-73 22.5 +q-53 0 -90.5 -37.5t-37.5 -90.5zM1180 -128q44 0 78.5 27t45.5 70l85 339q19 73 19 155v91l-141 -310q-17 -38 -53 -61t-78 -23q-53 0 -93.5 34.5t-48.5 86.5q-44 -57 -114 -57h-208v32h208q46 0 81 33t35 79t-31 79t-77 33h-296q-49 0 -82 -36l-126 -136v-308 +q0 -53 37.5 -90.5t90.5 -37.5h668z" /> + <glyph glyph-name="_567" unicode="&#xf25c;" horiz-adv-x="1973" +d="M857 992v-117q0 -13 -9.5 -22t-22.5 -9h-298v-812q0 -13 -9 -22.5t-22 -9.5h-135q-13 0 -22.5 9t-9.5 23v812h-297q-13 0 -22.5 9t-9.5 22v117q0 14 9 23t23 9h793q13 0 22.5 -9.5t9.5 -22.5zM1895 995l77 -961q1 -13 -8 -24q-10 -10 -23 -10h-134q-12 0 -21 8.5 +t-10 20.5l-46 588l-189 -425q-8 -19 -29 -19h-120q-20 0 -29 19l-188 427l-45 -590q-1 -12 -10 -20.5t-21 -8.5h-135q-13 0 -23 10q-9 10 -9 24l78 961q1 12 10 20.5t21 8.5h142q20 0 29 -19l220 -520q10 -24 20 -51q3 7 9.5 24.5t10.5 26.5l221 520q9 19 29 19h141 +q13 0 22 -8.5t10 -20.5z" /> + <glyph glyph-name="_568" unicode="&#xf25d;" horiz-adv-x="1792" +d="M1042 833q0 88 -60 121q-33 18 -117 18h-123v-281h162q66 0 102 37t36 105zM1094 548l205 -373q8 -17 -1 -31q-8 -16 -27 -16h-152q-20 0 -28 17l-194 365h-155v-350q0 -14 -9 -23t-23 -9h-134q-14 0 -23 9t-9 23v960q0 14 9 23t23 9h294q128 0 190 -24q85 -31 134 -109 +t49 -180q0 -92 -42.5 -165.5t-115.5 -109.5q6 -10 9 -16zM896 1376q-150 0 -286 -58.5t-234.5 -157t-157 -234.5t-58.5 -286t58.5 -286t157 -234.5t234.5 -157t286 -58.5t286 58.5t234.5 157t157 234.5t58.5 286t-58.5 286t-157 234.5t-234.5 157t-286 58.5zM1792 640 +q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" /> + <glyph glyph-name="_569" unicode="&#xf25e;" horiz-adv-x="1792" +d="M605 303q153 0 257 104q14 18 3 36l-45 82q-6 13 -24 17q-16 2 -27 -11l-4 -3q-4 -4 -11.5 -10t-17.5 -13.5t-23.5 -14.5t-28.5 -13t-33.5 -9.5t-37.5 -3.5q-76 0 -125 50t-49 127q0 76 48 125.5t122 49.5q37 0 71.5 -14t50.5 -28l16 -14q11 -11 26 -10q16 2 24 14l53 78 +q13 20 -2 39q-3 4 -11 12t-30 23.5t-48.5 28t-67.5 22.5t-86 10q-148 0 -246 -96.5t-98 -240.5q0 -146 97 -241.5t247 -95.5zM1235 303q153 0 257 104q14 18 4 36l-45 82q-8 14 -25 17q-16 2 -27 -11l-4 -3q-4 -4 -11.5 -10t-17.5 -13.5t-23.5 -14.5t-28.5 -13t-33.5 -9.5 +t-37.5 -3.5q-76 0 -125 50t-49 127q0 76 48 125.5t122 49.5q37 0 71.5 -14t50.5 -28l16 -14q11 -11 26 -10q16 2 24 14l53 78q13 20 -2 39q-3 4 -11 12t-30 23.5t-48.5 28t-67.5 22.5t-86 10q-147 0 -245.5 -96.5t-98.5 -240.5q0 -146 97 -241.5t247 -95.5zM896 1376 +q-150 0 -286 -58.5t-234.5 -157t-157 -234.5t-58.5 -286t58.5 -286t157 -234.5t234.5 -157t286 -58.5t286 58.5t234.5 157t157 234.5t58.5 286t-58.5 286t-157 234.5t-234.5 157t-286 58.5zM896 1536q182 0 348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286t-286 -191 +t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71z" /> + <glyph glyph-name="f260" unicode="&#xf260;" horiz-adv-x="2048" +d="M736 736l384 -384l-384 -384l-672 672l672 672l168 -168l-96 -96l-72 72l-480 -480l480 -480l193 193l-289 287zM1312 1312l672 -672l-672 -672l-168 168l96 96l72 -72l480 480l-480 480l-193 -193l289 -287l-96 -96l-384 384z" /> + <glyph glyph-name="f261" unicode="&#xf261;" horiz-adv-x="1792" +d="M717 182l271 271l-279 279l-88 -88l192 -191l-96 -96l-279 279l279 279l40 -40l87 87l-127 128l-454 -454zM1075 190l454 454l-454 454l-271 -271l279 -279l88 88l-192 191l96 96l279 -279l-279 -279l-40 40l-87 -88zM1792 640q0 -182 -71 -348t-191 -286t-286 -191 +t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" /> + <glyph glyph-name="_572" unicode="&#xf262;" horiz-adv-x="2304" +d="M651 539q0 -39 -27.5 -66.5t-65.5 -27.5q-39 0 -66.5 27.5t-27.5 66.5q0 38 27.5 65.5t66.5 27.5q38 0 65.5 -27.5t27.5 -65.5zM1805 540q0 -39 -27.5 -66.5t-66.5 -27.5t-66.5 27.5t-27.5 66.5t27.5 66t66.5 27t66.5 -27t27.5 -66zM765 539q0 79 -56.5 136t-136.5 57 +t-136.5 -56.5t-56.5 -136.5t56.5 -136.5t136.5 -56.5t136.5 56.5t56.5 136.5zM1918 540q0 80 -56.5 136.5t-136.5 56.5q-79 0 -136 -56.5t-57 -136.5t56.5 -136.5t136.5 -56.5t136.5 56.5t56.5 136.5zM850 539q0 -116 -81.5 -197.5t-196.5 -81.5q-116 0 -197.5 82t-81.5 197 +t82 196.5t197 81.5t196.5 -81.5t81.5 -196.5zM2004 540q0 -115 -81.5 -196.5t-197.5 -81.5q-115 0 -196.5 81.5t-81.5 196.5t81.5 196.5t196.5 81.5q116 0 197.5 -81.5t81.5 -196.5zM1040 537q0 191 -135.5 326.5t-326.5 135.5q-125 0 -231 -62t-168 -168.5t-62 -231.5 +t62 -231.5t168 -168.5t231 -62q191 0 326.5 135.5t135.5 326.5zM1708 1110q-254 111 -556 111q-319 0 -573 -110q117 0 223 -45.5t182.5 -122.5t122 -183t45.5 -223q0 115 43.5 219.5t118 180.5t177.5 123t217 50zM2187 537q0 191 -135 326.5t-326 135.5t-326.5 -135.5 +t-135.5 -326.5t135.5 -326.5t326.5 -135.5t326 135.5t135 326.5zM1921 1103h383q-44 -51 -75 -114.5t-40 -114.5q110 -151 110 -337q0 -156 -77 -288t-209 -208.5t-287 -76.5q-133 0 -249 56t-196 155q-47 -56 -129 -179q-11 22 -53.5 82.5t-74.5 97.5 +q-80 -99 -196.5 -155.5t-249.5 -56.5q-155 0 -287 76.5t-209 208.5t-77 288q0 186 110 337q-9 51 -40 114.5t-75 114.5h365q149 100 355 156.5t432 56.5q224 0 421 -56t348 -157z" /> + <glyph glyph-name="f263" unicode="&#xf263;" horiz-adv-x="1280" +d="M640 629q-188 0 -321 133t-133 320q0 188 133 321t321 133t321 -133t133 -321q0 -187 -133 -320t-321 -133zM640 1306q-92 0 -157.5 -65.5t-65.5 -158.5q0 -92 65.5 -157.5t157.5 -65.5t157.5 65.5t65.5 157.5q0 93 -65.5 158.5t-157.5 65.5zM1163 574q13 -27 15 -49.5 +t-4.5 -40.5t-26.5 -38.5t-42.5 -37t-61.5 -41.5q-115 -73 -315 -94l73 -72l267 -267q30 -31 30 -74t-30 -73l-12 -13q-31 -30 -74 -30t-74 30q-67 68 -267 268l-267 -268q-31 -30 -74 -30t-73 30l-12 13q-31 30 -31 73t31 74l267 267l72 72q-203 21 -317 94 +q-39 25 -61.5 41.5t-42.5 37t-26.5 38.5t-4.5 40.5t15 49.5q10 20 28 35t42 22t56 -2t65 -35q5 -4 15 -11t43 -24.5t69 -30.5t92 -24t113 -11q91 0 174 25.5t120 50.5l38 25q33 26 65 35t56 2t42 -22t28 -35z" /> + <glyph glyph-name="_574" unicode="&#xf264;" +d="M927 956q0 -66 -46.5 -112.5t-112.5 -46.5t-112.5 46.5t-46.5 112.5t46.5 112.5t112.5 46.5t112.5 -46.5t46.5 -112.5zM1141 593q-10 20 -28 32t-47.5 9.5t-60.5 -27.5q-10 -8 -29 -20t-81 -32t-127 -20t-124 18t-86 36l-27 18q-31 25 -60.5 27.5t-47.5 -9.5t-28 -32 +q-22 -45 -2 -74.5t87 -73.5q83 -53 226 -67l-51 -52q-142 -142 -191 -190q-22 -22 -22 -52.5t22 -52.5l9 -9q22 -22 52.5 -22t52.5 22l191 191q114 -115 191 -191q22 -22 52.5 -22t52.5 22l9 9q22 22 22 52.5t-22 52.5l-191 190l-52 52q141 14 225 67q67 44 87 73.5t-2 74.5 +zM1092 956q0 134 -95 229t-229 95t-229 -95t-95 -229t95 -229t229 -95t229 95t95 229zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="_575" unicode="&#xf265;" horiz-adv-x="1720" +d="M1565 1408q65 0 110 -45.5t45 -110.5v-519q0 -176 -68 -336t-182.5 -275t-274 -182.5t-334.5 -67.5q-176 0 -335.5 67.5t-274.5 182.5t-183 275t-68 336v519q0 64 46 110t110 46h1409zM861 344q47 0 82 33l404 388q37 35 37 85q0 49 -34.5 83.5t-83.5 34.5q-47 0 -82 -33 +l-323 -310l-323 310q-35 33 -81 33q-49 0 -83.5 -34.5t-34.5 -83.5q0 -51 36 -85l405 -388q33 -33 81 -33z" /> + <glyph glyph-name="_576" unicode="&#xf266;" horiz-adv-x="2304" +d="M1494 -103l-295 695q-25 -49 -158.5 -305.5t-198.5 -389.5q-1 -1 -27.5 -0.5t-26.5 1.5q-82 193 -255.5 587t-259.5 596q-21 50 -66.5 107.5t-103.5 100.5t-102 43q0 5 -0.5 24t-0.5 27h583v-50q-39 -2 -79.5 -16t-66.5 -43t-10 -64q26 -59 216.5 -499t235.5 -540 +q31 61 140 266.5t131 247.5q-19 39 -126 281t-136 295q-38 69 -201 71v50l513 -1v-47q-60 -2 -93.5 -25t-12.5 -69q33 -70 87 -189.5t86 -187.5q110 214 173 363q24 55 -10 79.5t-129 26.5q1 7 1 25v24q64 0 170.5 0.5t180 1t92.5 0.5v-49q-62 -2 -119 -33t-90 -81 +l-213 -442q13 -33 127.5 -290t121.5 -274l441 1017q-14 38 -49.5 62.5t-65 31.5t-55.5 8v50l460 -4l1 -2l-1 -44q-139 -4 -201 -145q-526 -1216 -559 -1291h-49z" /> + <glyph glyph-name="_577" unicode="&#xf267;" horiz-adv-x="1792" +d="M949 643q0 -26 -16.5 -45t-41.5 -19q-26 0 -45 16.5t-19 41.5q0 26 17 45t42 19t44 -16.5t19 -41.5zM964 585l350 581q-9 -8 -67.5 -62.5t-125.5 -116.5t-136.5 -127t-117 -110.5t-50.5 -51.5l-349 -580q7 7 67 62t126 116.5t136 127t117 111t50 50.5zM1611 640 +q0 -201 -104 -371q-3 2 -17 11t-26.5 16.5t-16.5 7.5q-13 0 -13 -13q0 -10 59 -44q-74 -112 -184.5 -190.5t-241.5 -110.5l-16 67q-1 10 -15 10q-5 0 -8 -5.5t-2 -9.5l16 -68q-72 -15 -146 -15q-199 0 -372 105q1 2 13 20.5t21.5 33.5t9.5 19q0 13 -13 13q-6 0 -17 -14.5 +t-22.5 -34.5t-13.5 -23q-113 75 -192 187.5t-110 244.5l69 15q10 3 10 15q0 5 -5.5 8t-10.5 2l-68 -15q-14 72 -14 139q0 206 109 379q2 -1 18.5 -12t30 -19t17.5 -8q13 0 13 12q0 6 -12.5 15.5t-32.5 21.5l-20 12q77 112 189 189t244 107l15 -67q2 -10 15 -10q5 0 8 5.5 +t2 10.5l-15 66q71 13 134 13q204 0 379 -109q-39 -56 -39 -65q0 -13 12 -13q11 0 48 64q111 -75 187.5 -186t107.5 -241l-56 -12q-10 -2 -10 -16q0 -5 5.5 -8t9.5 -2l57 13q14 -72 14 -140zM1696 640q0 163 -63.5 311t-170.5 255t-255 170.5t-311 63.5t-311 -63.5 +t-255 -170.5t-170.5 -255t-63.5 -311t63.5 -311t170.5 -255t255 -170.5t311 -63.5t311 63.5t255 170.5t170.5 255t63.5 311zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191 +t191 -286t71 -348z" /> + <glyph glyph-name="_578" unicode="&#xf268;" horiz-adv-x="1792" +d="M893 1536q240 2 451 -120q232 -134 352 -372l-742 39q-160 9 -294 -74.5t-185 -229.5l-276 424q128 159 311 245.5t383 87.5zM146 1131l337 -663q72 -143 211 -217t293 -45l-230 -451q-212 33 -385 157.5t-272.5 316t-99.5 411.5q0 267 146 491zM1732 962 +q58 -150 59.5 -310.5t-48.5 -306t-153 -272t-246 -209.5q-230 -133 -498 -119l405 623q88 131 82.5 290.5t-106.5 277.5zM896 942q125 0 213.5 -88.5t88.5 -213.5t-88.5 -213.5t-213.5 -88.5t-213.5 88.5t-88.5 213.5t88.5 213.5t213.5 88.5z" /> + <glyph glyph-name="_579" unicode="&#xf269;" horiz-adv-x="1792" +d="M903 -256q-283 0 -504.5 150.5t-329.5 398.5q-58 131 -67 301t26 332.5t111 312t179 242.5l-11 -281q11 14 68 15.5t70 -15.5q42 81 160.5 138t234.5 59q-54 -45 -119.5 -148.5t-58.5 -163.5q25 -8 62.5 -13.5t63 -7.5t68 -4t50.5 -3q15 -5 9.5 -45.5t-30.5 -75.5 +q-5 -7 -16.5 -18.5t-56.5 -35.5t-101 -34l15 -189l-139 67q-18 -43 -7.5 -81.5t36 -66.5t65.5 -41.5t81 -6.5q51 9 98 34.5t83.5 45t73.5 17.5q61 -4 89.5 -33t19.5 -65q-1 -2 -2.5 -5.5t-8.5 -12.5t-18 -15.5t-31.5 -10.5t-46.5 -1q-60 -95 -144.5 -135.5t-209.5 -29.5 +q74 -61 162.5 -82.5t168.5 -6t154.5 52t128 87.5t80.5 104q43 91 39 192.5t-37.5 188.5t-78.5 125q87 -38 137 -79.5t77 -112.5q15 170 -57.5 343t-209.5 284q265 -77 412 -279.5t151 -517.5q2 -127 -40.5 -255t-123.5 -238t-189 -196t-247.5 -135.5t-288.5 -49.5z" /> + <glyph glyph-name="_580" unicode="&#xf26a;" horiz-adv-x="1792" +d="M1493 1308q-165 110 -359 110q-155 0 -293 -73t-240 -200q-75 -93 -119.5 -218t-48.5 -266v-42q4 -141 48.5 -266t119.5 -218q102 -127 240 -200t293 -73q194 0 359 110q-121 -108 -274.5 -168t-322.5 -60q-29 0 -43 1q-175 8 -333 82t-272 193t-181 281t-67 339 +q0 182 71 348t191 286t286 191t348 71h3q168 -1 320.5 -60.5t273.5 -167.5zM1792 640q0 -192 -77 -362.5t-213 -296.5q-104 -63 -222 -63q-137 0 -255 84q154 56 253.5 233t99.5 405q0 227 -99 404t-253 234q119 83 254 83q119 0 226 -65q135 -125 210.5 -295t75.5 -361z +" /> + <glyph glyph-name="_581" unicode="&#xf26b;" horiz-adv-x="1792" +d="M1792 599q0 -56 -7 -104h-1151q0 -146 109.5 -244.5t257.5 -98.5q99 0 185.5 46.5t136.5 130.5h423q-56 -159 -170.5 -281t-267.5 -188.5t-321 -66.5q-187 0 -356 83q-228 -116 -394 -116q-237 0 -237 263q0 115 45 275q17 60 109 229q199 360 475 606 +q-184 -79 -427 -354q63 274 283.5 449.5t501.5 175.5q30 0 45 -1q255 117 433 117q64 0 116 -13t94.5 -40.5t66.5 -76.5t24 -115q0 -116 -75 -286q101 -182 101 -390zM1722 1239q0 83 -53 132t-137 49q-108 0 -254 -70q121 -47 222.5 -131.5t170.5 -195.5q51 135 51 216z +M128 2q0 -86 48.5 -132.5t134.5 -46.5q115 0 266 83q-122 72 -213.5 183t-137.5 245q-98 -205 -98 -332zM632 715h728q-5 142 -113 237t-251 95q-144 0 -251.5 -95t-112.5 -237z" /> + <glyph glyph-name="_582" unicode="&#xf26c;" horiz-adv-x="2048" +d="M1792 288v960q0 13 -9.5 22.5t-22.5 9.5h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5zM1920 1248v-960q0 -66 -47 -113t-113 -47h-736v-128h352q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23 +v64q0 14 9 23t23 9h352v128h-736q-66 0 -113 47t-47 113v960q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" /> + <glyph glyph-name="_583" unicode="&#xf26d;" horiz-adv-x="1792" +d="M138 1408h197q-70 -64 -126 -149q-36 -56 -59 -115t-30 -125.5t-8.5 -120t10.5 -132t21 -126t28 -136.5q4 -19 6 -28q51 -238 81 -329q57 -171 152 -275h-272q-48 0 -82 34t-34 82v1304q0 48 34 82t82 34zM1346 1408h308q48 0 82 -34t34 -82v-1304q0 -48 -34 -82t-82 -34 +h-178q212 210 196 565l-469 -101q-2 -45 -12 -82t-31 -72t-59.5 -59.5t-93.5 -36.5q-123 -26 -199 40q-32 27 -53 61t-51.5 129t-64.5 258q-35 163 -45.5 263t-5.5 139t23 77q20 41 62.5 73t102.5 45q45 12 83.5 6.5t67 -17t54 -35t43 -48t34.5 -56.5l468 100 +q-68 175 -180 287z" /> + <glyph glyph-name="_584" unicode="&#xf26e;" +d="M1401 -11l-6 -6q-113 -113 -259 -175q-154 -64 -317 -64q-165 0 -317 64q-148 63 -259 175q-113 112 -175 258q-42 103 -54 189q-4 28 48 36q51 8 56 -20q1 -1 1 -4q18 -90 46 -159q50 -124 152 -226q98 -98 226 -152q132 -56 276 -56q143 0 276 56q128 55 225 152l6 6 +q10 10 25 6q12 -3 33 -22q36 -37 17 -58zM929 604l-66 -66l63 -63q21 -21 -7 -49q-17 -17 -32 -17q-10 0 -19 10l-62 61l-66 -66q-5 -5 -15 -5q-15 0 -31 16l-2 2q-18 15 -18 29q0 7 8 17l66 65l-66 66q-16 16 14 45q18 18 31 18q6 0 13 -5l65 -66l65 65q18 17 48 -13 +q27 -27 11 -44zM1400 547q0 -118 -46 -228q-45 -105 -126 -186q-80 -80 -187 -126t-228 -46t-228 46t-187 126q-82 82 -125 186q-15 33 -15 40h-1q-9 27 43 44q50 16 60 -12q37 -99 97 -167h1v339v2q3 136 102 232q105 103 253 103q147 0 251 -103t104 -249 +q0 -147 -104.5 -251t-250.5 -104q-58 0 -112 16q-28 11 -13 61q16 51 44 43l14 -3q14 -3 33 -6t30 -3q104 0 176 71.5t72 174.5q0 101 -72 171q-71 71 -175 71q-107 0 -178 -80q-64 -72 -64 -160v-413q110 -67 242 -67q96 0 185 36.5t156 103.5t103.5 155t36.5 183 +q0 198 -141 339q-140 140 -339 140q-200 0 -340 -140q-53 -53 -77 -87l-2 -2q-8 -11 -13 -15.5t-21.5 -9.5t-38.5 3q-21 5 -36.5 16.5t-15.5 26.5v680q0 15 10.5 26.5t27.5 11.5h877q30 0 30 -55t-30 -55h-811v-483h1q40 42 102 84t108 61q109 46 231 46q121 0 228 -46 +t187 -126q81 -81 126 -186q46 -112 46 -229zM1369 1128q9 -8 9 -18t-5.5 -18t-16.5 -21q-26 -26 -39 -26q-9 0 -16 7q-106 91 -207 133q-128 56 -276 56q-133 0 -262 -49q-27 -10 -45 37q-9 25 -8 38q3 16 16 20q130 57 299 57q164 0 316 -64q137 -58 235 -152z" /> + <glyph glyph-name="_585" unicode="&#xf270;" horiz-adv-x="1792" +d="M1551 60q15 6 26 3t11 -17.5t-15 -33.5q-13 -16 -44 -43.5t-95.5 -68t-141 -74t-188 -58t-229.5 -24.5q-119 0 -238 31t-209 76.5t-172.5 104t-132.5 105t-84 87.5q-8 9 -10 16.5t1 12t8 7t11.5 2t11.5 -4.5q192 -117 300 -166q389 -176 799 -90q190 40 391 135z +M1758 175q11 -16 2.5 -69.5t-28.5 -102.5q-34 -83 -85 -124q-17 -14 -26 -9t0 24q21 45 44.5 121.5t6.5 98.5q-5 7 -15.5 11.5t-27 6t-29.5 2.5t-35 0t-31.5 -2t-31 -3t-22.5 -2q-6 -1 -13 -1.5t-11 -1t-8.5 -1t-7 -0.5h-5.5h-4.5t-3 0.5t-2 1.5l-1.5 3q-6 16 47 40t103 30 +q46 7 108 1t76 -24zM1364 618q0 -31 13.5 -64t32 -58t37.5 -46t33 -32l13 -11l-227 -224q-40 37 -79 75.5t-58 58.5l-19 20q-11 11 -25 33q-38 -59 -97.5 -102.5t-127.5 -63.5t-140 -23t-137.5 21t-117.5 65.5t-83 113t-31 162.5q0 84 28 154t72 116.5t106.5 83t122.5 57 +t130 34.5t119.5 18.5t99.5 6.5v127q0 65 -21 97q-34 53 -121 53q-6 0 -16.5 -1t-40.5 -12t-56 -29.5t-56 -59.5t-48 -96l-294 27q0 60 22 119t67 113t108 95t151.5 65.5t190.5 24.5q100 0 181 -25t129.5 -61.5t81 -83t45 -86t12.5 -73.5v-589zM692 597q0 -86 70 -133 +q66 -44 139 -22q84 25 114 123q14 45 14 101v162q-59 -2 -111 -12t-106.5 -33.5t-87 -71t-32.5 -114.5z" /> + <glyph glyph-name="_586" unicode="&#xf271;" horiz-adv-x="1792" +d="M1536 1280q52 0 90 -38t38 -90v-1280q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h128zM1152 1376v-288q0 -14 9 -23t23 -9 +h64q14 0 23 9t9 23v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM384 1376v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM1536 -128v1024h-1408v-1024h1408zM896 448h224q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-224 +v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-224q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v224q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-224z" /> + <glyph glyph-name="_587" unicode="&#xf272;" horiz-adv-x="1792" +d="M1152 416v-64q0 -14 -9 -23t-23 -9h-576q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h576q14 0 23 -9t9 -23zM128 -128h1408v1024h-1408v-1024zM512 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1280 1088v288q0 14 -9 23 +t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1664 1152v-1280q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47 +t47 -113v-96h128q52 0 90 -38t38 -90z" /> + <glyph glyph-name="_588" unicode="&#xf273;" horiz-adv-x="1792" +d="M1111 151l-46 -46q-9 -9 -22 -9t-23 9l-188 189l-188 -189q-10 -9 -23 -9t-22 9l-46 46q-9 9 -9 22t9 23l189 188l-189 188q-9 10 -9 23t9 22l46 46q9 9 22 9t23 -9l188 -188l188 188q10 9 23 9t22 -9l46 -46q9 -9 9 -22t-9 -23l-188 -188l188 -188q9 -10 9 -23t-9 -22z +M128 -128h1408v1024h-1408v-1024zM512 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1280 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1664 1152v-1280 +q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90z" /> + <glyph glyph-name="_589" unicode="&#xf274;" horiz-adv-x="1792" +d="M1303 572l-512 -512q-10 -9 -23 -9t-23 9l-288 288q-9 10 -9 23t9 22l46 46q9 9 22 9t23 -9l220 -220l444 444q10 9 23 9t22 -9l46 -46q9 -9 9 -22t-9 -23zM128 -128h1408v1024h-1408v-1024zM512 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23 +t23 -9h64q14 0 23 9t9 23zM1280 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1664 1152v-1280q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47 +t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90z" /> + <glyph glyph-name="_590" unicode="&#xf275;" horiz-adv-x="1792" +d="M448 1536q26 0 45 -19t19 -45v-891l536 429q17 14 40 14q26 0 45 -19t19 -45v-379l536 429q17 14 40 14q26 0 45 -19t19 -45v-1152q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v1664q0 26 19 45t45 19h384z" /> + <glyph glyph-name="_591" unicode="&#xf276;" horiz-adv-x="1024" +d="M512 448q66 0 128 15v-655q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v655q62 -15 128 -15zM512 1536q212 0 362 -150t150 -362t-150 -362t-362 -150t-362 150t-150 362t150 362t362 150zM512 1312q14 0 23 9t9 23t-9 23t-23 9q-146 0 -249 -103t-103 -249 +q0 -14 9 -23t23 -9t23 9t9 23q0 119 84.5 203.5t203.5 84.5z" /> + <glyph glyph-name="_592" unicode="&#xf277;" horiz-adv-x="1792" +d="M1745 1239q10 -10 10 -23t-10 -23l-141 -141q-28 -28 -68 -28h-1344q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h576v64q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-64h512q40 0 68 -28zM768 320h256v-512q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v512zM1600 768 +q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19h-1344q-40 0 -68 28l-141 141q-10 10 -10 23t10 23l141 141q28 28 68 28h512v192h256v-192h576z" /> + <glyph glyph-name="_593" unicode="&#xf278;" horiz-adv-x="2048" +d="M2020 1525q28 -20 28 -53v-1408q0 -20 -11 -36t-29 -23l-640 -256q-24 -11 -48 0l-616 246l-616 -246q-10 -5 -24 -5q-19 0 -36 11q-28 20 -28 53v1408q0 20 11 36t29 23l640 256q24 11 48 0l616 -246l616 246q32 13 60 -6zM736 1390v-1270l576 -230v1270zM128 1173 +v-1270l544 217v1270zM1920 107v1270l-544 -217v-1270z" /> + <glyph glyph-name="_594" unicode="&#xf279;" horiz-adv-x="1792" +d="M512 1536q13 0 22.5 -9.5t9.5 -22.5v-1472q0 -20 -17 -28l-480 -256q-7 -4 -15 -4q-13 0 -22.5 9.5t-9.5 22.5v1472q0 20 17 28l480 256q7 4 15 4zM1760 1536q13 0 22.5 -9.5t9.5 -22.5v-1472q0 -20 -17 -28l-480 -256q-7 -4 -15 -4q-13 0 -22.5 9.5t-9.5 22.5v1472 +q0 20 17 28l480 256q7 4 15 4zM640 1536q8 0 14 -3l512 -256q18 -10 18 -29v-1472q0 -13 -9.5 -22.5t-22.5 -9.5q-8 0 -14 3l-512 256q-18 10 -18 29v1472q0 13 9.5 22.5t22.5 9.5z" /> + <glyph glyph-name="_595" unicode="&#xf27a;" horiz-adv-x="1792" +d="M640 640q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1024 640q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1408 640q0 53 -37.5 90.5t-90.5 37.5 +t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1792 640q0 -174 -120 -321.5t-326 -233t-450 -85.5q-110 0 -211 18q-173 -173 -435 -229q-52 -10 -86 -13q-12 -1 -22 6t-13 18q-4 15 20 37q5 5 23.5 21.5t25.5 23.5t23.5 25.5t24 31.5t20.5 37 +t20 48t14.5 57.5t12.5 72.5q-146 90 -229.5 216.5t-83.5 269.5q0 174 120 321.5t326 233t450 85.5t450 -85.5t326 -233t120 -321.5z" /> + <glyph glyph-name="_596" unicode="&#xf27b;" horiz-adv-x="1792" +d="M640 640q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1024 640q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 -53 -37.5 -90.5t-90.5 -37.5 +t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM896 1152q-204 0 -381.5 -69.5t-282 -187.5t-104.5 -255q0 -112 71.5 -213.5t201.5 -175.5l87 -50l-27 -96q-24 -91 -70 -172q152 63 275 171l43 38l57 -6q69 -8 130 -8q204 0 381.5 69.5t282 187.5 +t104.5 255t-104.5 255t-282 187.5t-381.5 69.5zM1792 640q0 -174 -120 -321.5t-326 -233t-450 -85.5q-70 0 -145 8q-198 -175 -460 -242q-49 -14 -114 -22h-5q-15 0 -27 10.5t-16 27.5v1q-3 4 -0.5 12t2 10t4.5 9.5l6 9t7 8.5t8 9q7 8 31 34.5t34.5 38t31 39.5t32.5 51 +t27 59t26 76q-157 89 -247.5 220t-90.5 281q0 130 71 248.5t191 204.5t286 136.5t348 50.5t348 -50.5t286 -136.5t191 -204.5t71 -248.5z" /> + <glyph glyph-name="_597" unicode="&#xf27c;" horiz-adv-x="1024" +d="M512 345l512 295v-591l-512 -296v592zM0 640v-591l512 296zM512 1527v-591l-512 -296v591zM512 936l512 295v-591z" /> + <glyph glyph-name="_598" unicode="&#xf27d;" horiz-adv-x="1792" +d="M1709 1018q-10 -236 -332 -651q-333 -431 -562 -431q-142 0 -240 263q-44 160 -132 482q-72 262 -157 262q-18 0 -127 -76l-77 98q24 21 108 96.5t130 115.5q156 138 241 146q95 9 153 -55.5t81 -203.5q44 -287 66 -373q55 -249 120 -249q51 0 154 161q101 161 109 246 +q13 139 -109 139q-57 0 -121 -26q120 393 459 382q251 -8 236 -326z" /> + <glyph glyph-name="f27e" unicode="&#xf27e;" +d="M0 1408h1536v-1536h-1536v1536zM1085 293l-221 631l221 297h-634l221 -297l-221 -631l317 -304z" /> + <glyph glyph-name="uniF280" unicode="&#xf280;" +d="M0 1408h1536v-1536h-1536v1536zM908 1088l-12 -33l75 -83l-31 -114l25 -25l107 57l107 -57l25 25l-31 114l75 83l-12 33h-95l-53 96h-32l-53 -96h-95zM641 925q32 0 44.5 -16t11.5 -63l174 21q0 55 -17.5 92.5t-50.5 56t-69 25.5t-85 7q-133 0 -199 -57.5t-66 -182.5v-72 +h-96v-128h76q20 0 20 -8v-382q0 -14 -5 -20t-18 -7l-73 -7v-88h448v86l-149 14q-6 1 -8.5 1.5t-3.5 2.5t-0.5 4t1 7t0.5 10v387h191l38 128h-231q-6 0 -2 6t4 9v80q0 27 1.5 40.5t7.5 28t19.5 20t36.5 5.5zM1248 96v86l-54 9q-7 1 -9.5 2.5t-2.5 3t1 7.5t1 12v520h-275 +l-23 -101l83 -22q23 -7 23 -27v-370q0 -14 -6 -18.5t-20 -6.5l-70 -9v-86h352z" /> + <glyph glyph-name="uniF281" unicode="&#xf281;" horiz-adv-x="1792" +d="M1792 690q0 -58 -29.5 -105.5t-79.5 -72.5q12 -46 12 -96q0 -155 -106.5 -287t-290.5 -208.5t-400 -76.5t-399.5 76.5t-290 208.5t-106.5 287q0 47 11 94q-51 25 -82 73.5t-31 106.5q0 82 58 140.5t141 58.5q85 0 145 -63q218 152 515 162l116 521q3 13 15 21t26 5 +l369 -81q18 37 54 59.5t79 22.5q62 0 106 -43.5t44 -105.5t-44 -106t-106 -44t-105.5 43.5t-43.5 105.5l-334 74l-104 -472q300 -9 519 -160q58 61 143 61q83 0 141 -58.5t58 -140.5zM418 491q0 -62 43.5 -106t105.5 -44t106 44t44 106t-44 105.5t-106 43.5q-61 0 -105 -44 +t-44 -105zM1228 136q11 11 11 26t-11 26q-10 10 -25 10t-26 -10q-41 -42 -121 -62t-160 -20t-160 20t-121 62q-11 10 -26 10t-25 -10q-11 -10 -11 -25.5t11 -26.5q43 -43 118.5 -68t122.5 -29.5t91 -4.5t91 4.5t122.5 29.5t118.5 68zM1225 341q62 0 105.5 44t43.5 106 +q0 61 -44 105t-105 44q-62 0 -106 -43.5t-44 -105.5t44 -106t106 -44z" /> + <glyph glyph-name="_602" unicode="&#xf282;" horiz-adv-x="1792" +d="M69 741h1q16 126 58.5 241.5t115 217t167.5 176t223.5 117.5t276.5 43q231 0 414 -105.5t294 -303.5q104 -187 104 -442v-188h-1125q1 -111 53.5 -192.5t136.5 -122.5t189.5 -57t213 -3t208 46.5t173.5 84.5v-377q-92 -55 -229.5 -92t-312.5 -38t-316 53 +q-189 73 -311.5 249t-124.5 372q-3 242 111 412t325 268q-48 -60 -78 -125.5t-46 -159.5h635q8 77 -8 140t-47 101.5t-70.5 66.5t-80.5 41t-75 20.5t-56 8.5l-22 1q-135 -5 -259.5 -44.5t-223.5 -104.5t-176 -140.5t-138 -163.5z" /> + <glyph glyph-name="_603" unicode="&#xf283;" horiz-adv-x="2304" +d="M0 32v608h2304v-608q0 -66 -47 -113t-113 -47h-1984q-66 0 -113 47t-47 113zM640 256v-128h384v128h-384zM256 256v-128h256v128h-256zM2144 1408q66 0 113 -47t47 -113v-224h-2304v224q0 66 47 113t113 47h1984z" /> + <glyph glyph-name="_604" unicode="&#xf284;" horiz-adv-x="1792" +d="M1584 246l-218 111q-74 -120 -196.5 -189t-263.5 -69q-147 0 -271 72t-196 196t-72 270q0 110 42.5 209.5t115 172t172 115t209.5 42.5q131 0 247.5 -60.5t192.5 -168.5l215 125q-110 169 -286.5 265t-378.5 96q-161 0 -308 -63t-253 -169t-169 -253t-63 -308t63 -308 +t169 -253t253 -169t308 -63q213 0 397.5 107t290.5 292zM1030 643l693 -352q-116 -253 -334.5 -400t-492.5 -147q-182 0 -348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71q260 0 470.5 -133.5t335.5 -366.5zM1543 640h-39v-160h-96v352h136q32 0 54.5 -20 +t28.5 -48t1 -56t-27.5 -48t-57.5 -20z" /> + <glyph glyph-name="uniF285" unicode="&#xf285;" horiz-adv-x="1792" +d="M1427 827l-614 386l92 151h855zM405 562l-184 116v858l1183 -743zM1424 697l147 -95v-858l-532 335zM1387 718l-500 -802h-855l356 571z" /> + <glyph glyph-name="uniF286" unicode="&#xf286;" horiz-adv-x="1792" +d="M640 528v224q0 16 -16 16h-96q-16 0 -16 -16v-224q0 -16 16 -16h96q16 0 16 16zM1152 528v224q0 16 -16 16h-96q-16 0 -16 -16v-224q0 -16 16 -16h96q16 0 16 16zM1664 496v-752h-640v320q0 80 -56 136t-136 56t-136 -56t-56 -136v-320h-640v752q0 16 16 16h96 +q16 0 16 -16v-112h128v624q0 16 16 16h96q16 0 16 -16v-112h128v112q0 16 16 16h96q16 0 16 -16v-112h128v112q0 6 2.5 9.5t8.5 5t9.5 2t11.5 0t9 -0.5v391q-32 15 -32 50q0 23 16.5 39t38.5 16t38.5 -16t16.5 -39q0 -35 -32 -50v-17q45 10 83 10q21 0 59.5 -7.5t54.5 -7.5 +q17 0 47 7.5t37 7.5q16 0 16 -16v-210q0 -15 -35 -21.5t-62 -6.5q-18 0 -54.5 7.5t-55.5 7.5q-40 0 -90 -12v-133q1 0 9 0.5t11.5 0t9.5 -2t8.5 -5t2.5 -9.5v-112h128v112q0 16 16 16h96q16 0 16 -16v-112h128v112q0 16 16 16h96q16 0 16 -16v-624h128v112q0 16 16 16h96 +q16 0 16 -16z" /> + <glyph glyph-name="_607" unicode="&#xf287;" horiz-adv-x="2304" +d="M2288 731q16 -8 16 -27t-16 -27l-320 -192q-8 -5 -16 -5q-9 0 -16 4q-16 10 -16 28v128h-858q37 -58 83 -165q16 -37 24.5 -55t24 -49t27 -47t27 -34t31.5 -26t33 -8h96v96q0 14 9 23t23 9h320q14 0 23 -9t9 -23v-320q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23v96h-96 +q-32 0 -61 10t-51 23.5t-45 40.5t-37 46t-33.5 57t-28.5 57.5t-28 60.5q-23 53 -37 81.5t-36 65t-44.5 53.5t-46.5 17h-360q-22 -84 -91 -138t-157 -54q-106 0 -181 75t-75 181t75 181t181 75q88 0 157 -54t91 -138h104q24 0 46.5 17t44.5 53.5t36 65t37 81.5q19 41 28 60.5 +t28.5 57.5t33.5 57t37 46t45 40.5t51 23.5t61 10h107q21 57 70 92.5t111 35.5q80 0 136 -56t56 -136t-56 -136t-136 -56q-62 0 -111 35.5t-70 92.5h-107q-17 0 -33 -8t-31.5 -26t-27 -34t-27 -47t-24 -49t-24.5 -55q-46 -107 -83 -165h1114v128q0 18 16 28t32 -1z" /> + <glyph glyph-name="_608" unicode="&#xf288;" horiz-adv-x="1792" +d="M1150 774q0 -56 -39.5 -95t-95.5 -39h-253v269h253q56 0 95.5 -39.5t39.5 -95.5zM1329 774q0 130 -91.5 222t-222.5 92h-433v-896h180v269h253q130 0 222 91.5t92 221.5zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348 +t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" /> + <glyph glyph-name="_609" unicode="&#xf289;" horiz-adv-x="2304" +d="M1645 438q0 59 -34 106.5t-87 68.5q-7 -45 -23 -92q-7 -24 -27.5 -38t-44.5 -14q-12 0 -24 3q-31 10 -45 38.5t-4 58.5q23 71 23 143q0 123 -61 227.5t-166 165.5t-228 61q-134 0 -247 -73t-167 -194q108 -28 188 -106q22 -23 22 -55t-22 -54t-54 -22t-55 22 +q-75 75 -180 75q-106 0 -181 -74.5t-75 -180.5t75 -180.5t181 -74.5h1046q79 0 134.5 55.5t55.5 133.5zM1798 438q0 -142 -100.5 -242t-242.5 -100h-1046q-169 0 -289 119.5t-120 288.5q0 153 100 267t249 136q62 184 221 298t354 114q235 0 408.5 -158.5t196.5 -389.5 +q116 -25 192.5 -118.5t76.5 -214.5zM2048 438q0 -175 -97 -319q-23 -33 -64 -33q-24 0 -43 13q-26 17 -32 48.5t12 57.5q71 104 71 233t-71 233q-18 26 -12 57t32 49t57.5 11.5t49.5 -32.5q97 -142 97 -318zM2304 438q0 -244 -134 -443q-23 -34 -64 -34q-23 0 -42 13 +q-26 18 -32.5 49t11.5 57q108 164 108 358q0 195 -108 357q-18 26 -11.5 57.5t32.5 48.5q26 18 57 12t49 -33q134 -198 134 -442z" /> + <glyph glyph-name="_610" unicode="&#xf28a;" +d="M1500 -13q0 -89 -63 -152.5t-153 -63.5t-153.5 63.5t-63.5 152.5q0 90 63.5 153.5t153.5 63.5t153 -63.5t63 -153.5zM1267 268q-115 -15 -192.5 -102.5t-77.5 -205.5q0 -74 33 -138q-146 -78 -379 -78q-109 0 -201 21t-153.5 54.5t-110.5 76.5t-76 85t-44.5 83 +t-23.5 66.5t-6 39.5q0 19 4.5 42.5t18.5 56t36.5 58t64 43.5t94.5 18t94 -17.5t63 -41t35.5 -53t17.5 -49t4 -33.5q0 -34 -23 -81q28 -27 82 -42t93 -17l40 -1q115 0 190 51t75 133q0 26 -9 48.5t-31.5 44.5t-49.5 41t-74 44t-93.5 47.5t-119.5 56.5q-28 13 -43 20 +q-116 55 -187 100t-122.5 102t-72 125.5t-20.5 162.5q0 78 20.5 150t66 137.5t112.5 114t166.5 77t221.5 28.5q120 0 220 -26t164.5 -67t109.5 -94t64 -105.5t19 -103.5q0 -46 -15 -82.5t-36.5 -58t-48.5 -36t-49 -19.5t-39 -5h-8h-32t-39 5t-44 14t-41 28t-37 46t-24 70.5 +t-10 97.5q-15 16 -59 25.5t-81 10.5l-37 1q-68 0 -117.5 -31t-70.5 -70t-21 -76q0 -24 5 -43t24 -46t53 -51t97 -53.5t150 -58.5q76 -25 138.5 -53.5t109 -55.5t83 -59t60.5 -59.5t41 -62.5t26.5 -62t14.5 -63.5t6 -62t1 -62.5z" /> + <glyph glyph-name="_611" unicode="&#xf28b;" +d="M704 352v576q0 14 -9 23t-23 9h-256q-14 0 -23 -9t-9 -23v-576q0 -14 9 -23t23 -9h256q14 0 23 9t9 23zM1152 352v576q0 14 -9 23t-23 9h-256q-14 0 -23 -9t-9 -23v-576q0 -14 9 -23t23 -9h256q14 0 23 9t9 23zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103 +t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="_612" unicode="&#xf28c;" +d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM768 96q148 0 273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273 +t73 -273t198 -198t273 -73zM864 320q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-192zM480 320q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-192z" /> + <glyph glyph-name="_613" unicode="&#xf28d;" +d="M1088 352v576q0 14 -9 23t-23 9h-576q-14 0 -23 -9t-9 -23v-576q0 -14 9 -23t23 -9h576q14 0 23 9t9 23zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5 +t103 -385.5z" /> + <glyph glyph-name="_614" unicode="&#xf28e;" +d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM768 96q148 0 273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273 +t73 -273t198 -198t273 -73zM480 320q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h576q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-576z" /> + <glyph glyph-name="_615" unicode="&#xf290;" horiz-adv-x="1792" +d="M1757 128l35 -313q3 -28 -16 -50q-19 -21 -48 -21h-1664q-29 0 -48 21q-19 22 -16 50l35 313h1722zM1664 967l86 -775h-1708l86 775q3 24 21 40.5t43 16.5h256v-128q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5v128h384v-128q0 -53 37.5 -90.5t90.5 -37.5 +t90.5 37.5t37.5 90.5v128h256q25 0 43 -16.5t21 -40.5zM1280 1152v-256q0 -26 -19 -45t-45 -19t-45 19t-19 45v256q0 106 -75 181t-181 75t-181 -75t-75 -181v-256q0 -26 -19 -45t-45 -19t-45 19t-19 45v256q0 159 112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5z" /> + <glyph glyph-name="_616" unicode="&#xf291;" horiz-adv-x="2048" +d="M1920 768q53 0 90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5h-15l-115 -662q-8 -46 -44 -76t-82 -30h-1280q-46 0 -82 30t-44 76l-115 662h-15q-53 0 -90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5h1792zM485 -32q26 2 43.5 22.5t15.5 46.5l-32 416q-2 26 -22.5 43.5 +t-46.5 15.5t-43.5 -22.5t-15.5 -46.5l32 -416q2 -25 20.5 -42t43.5 -17h5zM896 32v416q0 26 -19 45t-45 19t-45 -19t-19 -45v-416q0 -26 19 -45t45 -19t45 19t19 45zM1280 32v416q0 26 -19 45t-45 19t-45 -19t-19 -45v-416q0 -26 19 -45t45 -19t45 19t19 45zM1632 27l32 416 +q2 26 -15.5 46.5t-43.5 22.5t-46.5 -15.5t-22.5 -43.5l-32 -416q-2 -26 15.5 -46.5t43.5 -22.5h5q25 0 43.5 17t20.5 42zM476 1244l-93 -412h-132l101 441q19 88 89 143.5t160 55.5h167q0 26 19 45t45 19h384q26 0 45 -19t19 -45h167q90 0 160 -55.5t89 -143.5l101 -441 +h-132l-93 412q-11 44 -45.5 72t-79.5 28h-167q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45h-167q-45 0 -79.5 -28t-45.5 -72z" /> + <glyph glyph-name="_617" unicode="&#xf292;" horiz-adv-x="1792" +d="M991 512l64 256h-254l-64 -256h254zM1759 1016l-56 -224q-7 -24 -31 -24h-327l-64 -256h311q15 0 25 -12q10 -14 6 -28l-56 -224q-5 -24 -31 -24h-327l-81 -328q-7 -24 -31 -24h-224q-16 0 -26 12q-9 12 -6 28l78 312h-254l-81 -328q-7 -24 -31 -24h-225q-15 0 -25 12 +q-9 12 -6 28l78 312h-311q-15 0 -25 12q-9 12 -6 28l56 224q7 24 31 24h327l64 256h-311q-15 0 -25 12q-10 14 -6 28l56 224q5 24 31 24h327l81 328q7 24 32 24h224q15 0 25 -12q9 -12 6 -28l-78 -312h254l81 328q7 24 32 24h224q15 0 25 -12q9 -12 6 -28l-78 -312h311 +q15 0 25 -12q9 -12 6 -28z" /> + <glyph glyph-name="_618" unicode="&#xf293;" +d="M841 483l148 -148l-149 -149zM840 1094l149 -149l-148 -148zM710 -130l464 464l-306 306l306 306l-464 464v-611l-255 255l-93 -93l320 -321l-320 -321l93 -93l255 255v-611zM1429 640q0 -209 -32 -365.5t-87.5 -257t-140.5 -162.5t-181.5 -86.5t-219.5 -24.5 +t-219.5 24.5t-181.5 86.5t-140.5 162.5t-87.5 257t-32 365.5t32 365.5t87.5 257t140.5 162.5t181.5 86.5t219.5 24.5t219.5 -24.5t181.5 -86.5t140.5 -162.5t87.5 -257t32 -365.5z" /> + <glyph glyph-name="_619" unicode="&#xf294;" horiz-adv-x="1024" +d="M596 113l173 172l-173 172v-344zM596 823l173 172l-173 172v-344zM628 640l356 -356l-539 -540v711l-297 -296l-108 108l372 373l-372 373l108 108l297 -296v711l539 -540z" /> + <glyph glyph-name="_620" unicode="&#xf295;" +d="M1280 256q0 52 -38 90t-90 38t-90 -38t-38 -90t38 -90t90 -38t90 38t38 90zM512 1024q0 52 -38 90t-90 38t-90 -38t-38 -90t38 -90t90 -38t90 38t38 90zM1536 256q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5 +t112.5 -271.5zM1440 1344q0 -20 -13 -38l-1056 -1408q-19 -26 -51 -26h-160q-26 0 -45 19t-19 45q0 20 13 38l1056 1408q19 26 51 26h160q26 0 45 -19t19 -45zM768 1024q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5 +t271.5 -112.5t112.5 -271.5z" /> + <glyph glyph-name="_621" unicode="&#xf296;" horiz-adv-x="1792" +d="M104 830l792 -1015l-868 630q-18 13 -25 34.5t0 42.5l101 308v0zM566 830h660l-330 -1015v0zM368 1442l198 -612h-462l198 612q8 23 33 23t33 -23zM1688 830l101 -308q7 -21 0 -42.5t-25 -34.5l-868 -630l792 1015v0zM1688 830h-462l198 612q8 23 33 23t33 -23z" /> + <glyph glyph-name="_622" unicode="&#xf297;" horiz-adv-x="1792" +d="M384 704h160v224h-160v-224zM1221 372v92q-104 -36 -243 -38q-135 -1 -259.5 46.5t-220.5 122.5l1 -96q88 -80 212 -128.5t272 -47.5q129 0 238 49zM640 704h640v224h-640v-224zM1792 736q0 -187 -99 -352q89 -102 89 -229q0 -157 -129.5 -268t-313.5 -111 +q-122 0 -225 52.5t-161 140.5q-19 -1 -57 -1t-57 1q-58 -88 -161 -140.5t-225 -52.5q-184 0 -313.5 111t-129.5 268q0 127 89 229q-99 165 -99 352q0 209 120 385.5t326.5 279.5t449.5 103t449.5 -103t326.5 -279.5t120 -385.5z" /> + <glyph glyph-name="_623" unicode="&#xf298;" +d="M515 625v-128h-252v128h252zM515 880v-127h-252v127h252zM1273 369v-128h-341v128h341zM1273 625v-128h-672v128h672zM1273 880v-127h-672v127h672zM1408 20v1240q0 8 -6 14t-14 6h-32l-378 -256l-210 171l-210 -171l-378 256h-32q-8 0 -14 -6t-6 -14v-1240q0 -8 6 -14 +t14 -6h1240q8 0 14 6t6 14zM553 1130l185 150h-406zM983 1130l221 150h-406zM1536 1260v-1240q0 -62 -43 -105t-105 -43h-1240q-62 0 -105 43t-43 105v1240q0 62 43 105t105 43h1240q62 0 105 -43t43 -105z" /> + <glyph glyph-name="_624" unicode="&#xf299;" horiz-adv-x="1792" +d="M896 720q-104 196 -160 278q-139 202 -347 318q-34 19 -70 36q-89 40 -94 32t34 -38l39 -31q62 -43 112.5 -93.5t94.5 -116.5t70.5 -113t70.5 -131q9 -17 13 -25q44 -84 84 -153t98 -154t115.5 -150t131 -123.5t148.5 -90.5q153 -66 154 -60q1 3 -49 37q-53 36 -81 57 +q-77 58 -179 211t-185 310zM549 177q-76 60 -132.5 125t-98 143.5t-71 154.5t-58.5 186t-52 209t-60.5 252t-76.5 289q273 0 497.5 -36t379 -92t271 -144.5t185.5 -172.5t110 -198.5t56 -199.5t12.5 -198.5t-9.5 -173t-20 -143.5t-13 -107l323 -327h-104l-281 285 +q-22 -2 -91.5 -14t-121.5 -19t-138 -6t-160.5 17t-167.5 59t-179 111z" /> + <glyph glyph-name="_625" unicode="&#xf29a;" horiz-adv-x="1792" +d="M1374 879q-6 26 -28.5 39.5t-48.5 7.5q-261 -62 -401 -62t-401 62q-26 6 -48.5 -7.5t-28.5 -39.5t7.5 -48.5t39.5 -28.5q194 -46 303 -58q-2 -158 -15.5 -269t-26.5 -155.5t-41 -115.5l-9 -21q-10 -25 1 -49t36 -34q9 -4 23 -4q44 0 60 41l8 20q54 139 71 259h42 +q17 -120 71 -259l8 -20q16 -41 60 -41q14 0 23 4q25 10 36 34t1 49l-9 21q-28 71 -41 115.5t-26.5 155.5t-15.5 269q109 12 303 58q26 6 39.5 28.5t7.5 48.5zM1024 1024q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5z +M1600 640q0 -143 -55.5 -273.5t-150 -225t-225 -150t-273.5 -55.5t-273.5 55.5t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5zM896 1408q-156 0 -298 -61t-245 -164t-164 -245t-61 -298t61 -298 +t164 -245t245 -164t298 -61t298 61t245 164t164 245t61 298t-61 298t-164 245t-245 164t-298 61zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" /> + <glyph glyph-name="_626" unicode="&#xf29b;" +d="M1438 723q34 -35 29 -82l-44 -551q-4 -42 -34.5 -70t-71.5 -28q-6 0 -9 1q-44 3 -72.5 36.5t-25.5 77.5l35 429l-143 -8q55 -113 55 -240q0 -216 -148 -372l-137 137q91 101 91 235q0 145 -102.5 248t-247.5 103q-134 0 -236 -92l-137 138q120 114 284 141l264 300 +l-149 87l-181 -161q-33 -30 -77 -27.5t-73 35.5t-26.5 77t34.5 73l239 213q26 23 60 26.5t64 -14.5l488 -283q36 -21 48 -68q17 -67 -26 -117l-205 -232l371 20q49 3 83 -32zM1240 1180q-74 0 -126 52t-52 126t52 126t126 52t126.5 -52t52.5 -126t-52.5 -126t-126.5 -52z +M613 -62q106 0 196 61l139 -139q-146 -116 -335 -116q-148 0 -273.5 73t-198.5 198t-73 273q0 188 116 336l139 -139q-60 -88 -60 -197q0 -145 102.5 -247.5t247.5 -102.5z" /> + <glyph glyph-name="_627" unicode="&#xf29c;" +d="M880 336v-160q0 -14 -9 -23t-23 -9h-160q-14 0 -23 9t-9 23v160q0 14 9 23t23 9h160q14 0 23 -9t9 -23zM1136 832q0 -50 -15 -90t-45.5 -69t-52 -44t-59.5 -36q-32 -18 -46.5 -28t-26 -24t-11.5 -29v-32q0 -14 -9 -23t-23 -9h-160q-14 0 -23 9t-9 23v68q0 35 10.5 64.5 +t24 47.5t39 35.5t41 25.5t44.5 21q53 25 75 43t22 49q0 42 -43.5 71.5t-95.5 29.5q-56 0 -95 -27q-29 -20 -80 -83q-9 -12 -25 -12q-11 0 -19 6l-108 82q-10 7 -12 20t5 23q122 192 349 192q129 0 238.5 -89.5t109.5 -214.5zM768 1280q-130 0 -248.5 -51t-204 -136.5 +t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5t-51 248.5t-136.5 204t-204 136.5t-248.5 51zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5 +t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="_628" unicode="&#xf29d;" horiz-adv-x="1408" +d="M366 1225q-64 0 -110 45.5t-46 110.5q0 64 46 109.5t110 45.5t109.5 -45.5t45.5 -109.5q0 -65 -45.5 -110.5t-109.5 -45.5zM917 583q0 -50 -30 -67.5t-63.5 -6.5t-47.5 34l-367 438q-7 12 -14 15.5t-11 1.5l-3 -3q-7 -8 4 -21l122 -139l1 -354l-161 -457 +q-67 -192 -92 -234q-15 -26 -28 -32q-50 -26 -103 -1q-29 13 -41.5 43t-9.5 57q2 17 197 618l5 416l-85 -164l35 -222q4 -24 -1 -42t-14 -27.5t-19 -16t-17 -7.5l-7 -2q-19 -3 -34.5 3t-24 16t-14 22t-7.5 19.5t-2 9.5l-46 299l211 381q23 34 113 34q75 0 107 -40l424 -521 +q7 -5 14 -17l3 -3l-1 -1q7 -13 7 -29zM514 433q43 -113 88.5 -225t69.5 -168l24 -55q36 -93 42 -125q11 -70 -36 -97q-35 -22 -66 -16t-51 22t-29 35h-1q-6 16 -8 25l-124 351zM1338 -159q31 -49 31 -57q0 -5 -3 -7q-9 -5 -14.5 0.5t-15.5 26t-16 30.5q-114 172 -423 661 +q3 -1 7 1t7 4l3 2q11 9 11 17z" /> + <glyph glyph-name="_629" unicode="&#xf29e;" horiz-adv-x="2304" +d="M504 542h171l-1 265zM1530 641q0 87 -50.5 140t-146.5 53h-54v-388h52q91 0 145 57t54 138zM956 1018l1 -756q0 -14 -9.5 -24t-23.5 -10h-216q-14 0 -23.5 10t-9.5 24v62h-291l-55 -81q-10 -15 -28 -15h-267q-21 0 -30.5 18t3.5 35l556 757q9 14 27 14h332q14 0 24 -10 +t10 -24zM1783 641q0 -193 -125.5 -303t-324.5 -110h-270q-14 0 -24 10t-10 24v756q0 14 10 24t24 10h268q200 0 326 -109t126 -302zM1939 640q0 -11 -0.5 -29t-8 -71.5t-21.5 -102t-44.5 -108t-73.5 -102.5h-51q38 45 66.5 104.5t41.5 112t21 98t9 72.5l1 27q0 8 -0.5 22.5 +t-7.5 60t-20 91.5t-41 111.5t-66 124.5h43q41 -47 72 -107t45.5 -111.5t23 -96t10.5 -70.5zM2123 640q0 -11 -0.5 -29t-8 -71.5t-21.5 -102t-45 -108t-74 -102.5h-51q38 45 66.5 104.5t41.5 112t21 98t9 72.5l1 27q0 8 -0.5 22.5t-7.5 60t-19.5 91.5t-40.5 111.5t-66 124.5 +h43q41 -47 72 -107t45.5 -111.5t23 -96t10.5 -70.5zM2304 640q0 -11 -0.5 -29t-8 -71.5t-21.5 -102t-44.5 -108t-73.5 -102.5h-51q38 45 66 104.5t41 112t21 98t9 72.5l1 27q0 8 -0.5 22.5t-7.5 60t-19.5 91.5t-40.5 111.5t-66 124.5h43q41 -47 72 -107t45.5 -111.5t23 -96 +t9.5 -70.5z" /> + <glyph glyph-name="uniF2A0" unicode="&#xf2a0;" horiz-adv-x="1408" +d="M617 -153q0 11 -13 58t-31 107t-20 69q-1 4 -5 26.5t-8.5 36t-13.5 21.5q-15 14 -51 14q-23 0 -70 -5.5t-71 -5.5q-34 0 -47 11q-6 5 -11 15.5t-7.5 20t-6.5 24t-5 18.5q-37 128 -37 255t37 255q1 4 5 18.5t6.5 24t7.5 20t11 15.5q13 11 47 11q24 0 71 -5.5t70 -5.5 +q36 0 51 14q9 8 13.5 21.5t8.5 36t5 26.5q2 9 20 69t31 107t13 58q0 22 -43.5 52.5t-75.5 42.5q-20 8 -45 8q-34 0 -98 -18q-57 -17 -96.5 -40.5t-71 -66t-46 -70t-45.5 -94.5q-6 -12 -9 -19q-49 -107 -68 -216t-19 -244t19 -244t68 -216q56 -122 83 -161q63 -91 179 -127 +l6 -2q64 -18 98 -18q25 0 45 8q32 12 75.5 42.5t43.5 52.5zM776 760q-26 0 -45 19t-19 45.5t19 45.5q37 37 37 90q0 52 -37 91q-19 19 -19 45t19 45t45 19t45 -19q75 -75 75 -181t-75 -181q-21 -19 -45 -19zM957 579q-27 0 -45 19q-19 19 -19 45t19 45q112 114 112 272 +t-112 272q-19 19 -19 45t19 45t45 19t45 -19q150 -150 150 -362t-150 -362q-18 -19 -45 -19zM1138 398q-27 0 -45 19q-19 19 -19 45t19 45q90 91 138.5 208t48.5 245t-48.5 245t-138.5 208q-19 19 -19 45t19 45t45 19t45 -19q109 -109 167 -249t58 -294t-58 -294t-167 -249 +q-18 -19 -45 -19z" /> + <glyph glyph-name="uniF2A1" unicode="&#xf2a1;" horiz-adv-x="2176" +d="M192 352q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM704 352q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM704 864q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM1472 352 +q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM1984 352q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM1472 864q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM1984 864 +q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM1984 1376q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM384 192q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM896 192q0 -80 -56 -136 +t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM384 704q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM896 704q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM384 1216q0 -80 -56 -136t-136 -56 +t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1664 192q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM896 1216q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM2176 192q0 -80 -56 -136t-136 -56t-136 56 +t-56 136t56 136t136 56t136 -56t56 -136zM1664 704q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM2176 704q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1664 1216q0 -80 -56 -136t-136 -56t-136 56t-56 136 +t56 136t136 56t136 -56t56 -136zM2176 1216q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136z" /> + <glyph glyph-name="uniF2A2" unicode="&#xf2a2;" horiz-adv-x="1792" +d="M128 -192q0 -26 -19 -45t-45 -19t-45 19t-19 45t19 45t45 19t45 -19t19 -45zM320 0q0 -26 -19 -45t-45 -19t-45 19t-19 45t19 45t45 19t45 -19t19 -45zM365 365l256 -256l-90 -90l-256 256zM704 384q0 -26 -19 -45t-45 -19t-45 19t-19 45t19 45t45 19t45 -19t19 -45z +M1411 704q0 -59 -11.5 -108.5t-37.5 -93.5t-44 -67.5t-53 -64.5q-31 -35 -45.5 -54t-33.5 -50t-26.5 -64t-7.5 -74q0 -159 -112.5 -271.5t-271.5 -112.5q-26 0 -45 19t-19 45t19 45t45 19q106 0 181 75t75 181q0 57 11.5 105.5t37 91t43.5 66.5t52 63q40 46 59.5 72 +t37.5 74.5t18 103.5q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5q0 -26 -19 -45t-45 -19t-45 19t-19 45q0 117 45.5 223.5t123 184t184 123t223.5 45.5t223.5 -45.5t184 -123t123 -184t45.5 -223.5zM896 576q0 -26 -19 -45t-45 -19t-45 19t-19 45t19 45 +t45 19t45 -19t19 -45zM1184 704q0 -26 -19 -45t-45 -19t-45 19t-19 45q0 93 -65.5 158.5t-158.5 65.5q-92 0 -158 -65.5t-66 -158.5q0 -26 -19 -45t-45 -19t-45 19t-19 45q0 146 103 249t249 103t249 -103t103 -249zM1578 993q10 -25 -1 -49t-36 -34q-9 -4 -23 -4 +q-19 0 -35.5 11t-23.5 30q-68 178 -224 295q-21 16 -25 42t12 47q17 21 43 25t47 -12q183 -137 266 -351zM1788 1074q9 -25 -1.5 -49t-35.5 -34q-11 -4 -23 -4q-44 0 -60 41q-92 238 -297 393q-22 16 -25.5 42t12.5 47q16 22 42 25.5t47 -12.5q235 -175 341 -449z" /> + <glyph glyph-name="uniF2A3" unicode="&#xf2a3;" horiz-adv-x="2304" +d="M1032 576q-59 2 -84 55q-17 34 -48 53.5t-68 19.5q-53 0 -90.5 -37.5t-37.5 -90.5q0 -56 36 -89l10 -8q34 -31 82 -31q37 0 68 19.5t48 53.5q25 53 84 55zM1600 704q0 56 -36 89l-10 8q-34 31 -82 31q-37 0 -68 -19.5t-48 -53.5q-25 -53 -84 -55q59 -2 84 -55 +q17 -34 48 -53.5t68 -19.5q53 0 90.5 37.5t37.5 90.5zM1174 925q-17 -35 -55 -48t-73 4q-62 31 -134 31q-51 0 -99 -17q3 0 9.5 0.5t9.5 0.5q92 0 170.5 -50t118.5 -133q17 -36 3.5 -73.5t-49.5 -54.5q-18 -9 -39 -9q21 0 39 -9q36 -17 49.5 -54.5t-3.5 -73.5 +q-40 -83 -118.5 -133t-170.5 -50h-6q-16 2 -44 4l-290 27l-239 -120q-14 -7 -29 -7q-40 0 -57 35l-160 320q-11 23 -4 47.5t29 37.5l209 119l148 267q17 155 91.5 291.5t195.5 236.5q31 25 70.5 21.5t64.5 -34.5t21.5 -70t-34.5 -65q-70 -59 -117 -128q123 84 267 101 +q40 5 71.5 -19t35.5 -64q5 -40 -19 -71.5t-64 -35.5q-84 -10 -159 -55q46 10 99 10q115 0 218 -50q36 -18 49 -55.5t-5 -73.5zM2137 1085l160 -320q11 -23 4 -47.5t-29 -37.5l-209 -119l-148 -267q-17 -155 -91.5 -291.5t-195.5 -236.5q-26 -22 -61 -22q-45 0 -74 35 +q-25 31 -21.5 70t34.5 65q70 59 117 128q-123 -84 -267 -101q-4 -1 -12 -1q-36 0 -63.5 24t-31.5 60q-5 40 19 71.5t64 35.5q84 10 159 55q-46 -10 -99 -10q-115 0 -218 50q-36 18 -49 55.5t5 73.5q17 35 55 48t73 -4q62 -31 134 -31q51 0 99 17q-3 0 -9.5 -0.5t-9.5 -0.5 +q-92 0 -170.5 50t-118.5 133q-17 36 -3.5 73.5t49.5 54.5q18 9 39 9q-21 0 -39 9q-36 17 -49.5 54.5t3.5 73.5q40 83 118.5 133t170.5 50h6h1q14 -2 42 -4l291 -27l239 120q14 7 29 7q40 0 57 -35z" /> + <glyph glyph-name="uniF2A4" unicode="&#xf2a4;" horiz-adv-x="1792" +d="M1056 704q0 -26 19 -45t45 -19t45 19t19 45q0 146 -103 249t-249 103t-249 -103t-103 -249q0 -26 19 -45t45 -19t45 19t19 45q0 93 66 158.5t158 65.5t158 -65.5t66 -158.5zM835 1280q-117 0 -223.5 -45.5t-184 -123t-123 -184t-45.5 -223.5q0 -26 19 -45t45 -19t45 19 +t19 45q0 185 131.5 316.5t316.5 131.5t316.5 -131.5t131.5 -316.5q0 -55 -18 -103.5t-37.5 -74.5t-59.5 -72q-34 -39 -52 -63t-43.5 -66.5t-37 -91t-11.5 -105.5q0 -106 -75 -181t-181 -75q-26 0 -45 -19t-19 -45t19 -45t45 -19q159 0 271.5 112.5t112.5 271.5q0 41 7.5 74 +t26.5 64t33.5 50t45.5 54q35 41 53 64.5t44 67.5t37.5 93.5t11.5 108.5q0 117 -45.5 223.5t-123 184t-184 123t-223.5 45.5zM591 561l226 -226l-579 -579q-12 -12 -29 -12t-29 12l-168 168q-12 12 -12 29t12 29zM1612 1524l168 -168q12 -12 12 -29t-12 -30l-233 -233 +l-26 -25l-71 -71q-66 153 -195 258l91 91l207 207q13 12 30 12t29 -12z" /> + <glyph glyph-name="uniF2A5" unicode="&#xf2a5;" +d="M866 1021q0 -27 -13 -94q-11 -50 -31.5 -150t-30.5 -150q-2 -11 -4.5 -12.5t-13.5 -2.5q-20 -2 -31 -2q-58 0 -84 49.5t-26 113.5q0 88 35 174t103 124q28 14 51 14q28 0 36.5 -16.5t8.5 -47.5zM1352 597q0 14 -39 75.5t-52 66.5q-21 8 -34 8q-91 0 -226 -77l-2 2 +q3 22 27.5 135t24.5 178q0 233 -242 233q-24 0 -68 -6q-94 -17 -168.5 -89.5t-111.5 -166.5t-37 -189q0 -146 80.5 -225t227.5 -79q25 0 25 -3t-1 -5q-4 -34 -26 -117q-14 -52 -51.5 -101t-82.5 -49q-42 0 -42 47q0 24 10.5 47.5t25 39.5t29.5 28.5t26 20t11 8.5q0 3 -7 10 +q-24 22 -58.5 36.5t-65.5 14.5q-35 0 -63.5 -34t-41 -75t-12.5 -75q0 -88 51.5 -142t138.5 -54q82 0 155 53t117.5 126t65.5 153q6 22 15.5 66.5t14.5 66.5q3 12 14 18q118 60 227 60q48 0 127 -18q1 -1 4 -1q5 0 9.5 4.5t4.5 8.5zM1536 1120v-960q0 -119 -84.5 -203.5 +t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="uniF2A6" unicode="&#xf2a6;" horiz-adv-x="1535" +d="M744 1231q0 24 -2 38.5t-8.5 30t-21 23t-37.5 7.5q-39 0 -78 -23q-105 -58 -159 -190.5t-54 -269.5q0 -44 8.5 -85.5t26.5 -80.5t52.5 -62.5t81.5 -23.5q4 0 18 -0.5t20 0t16 3t15 8.5t7 16q16 77 48 231.5t48 231.5q19 91 19 146zM1498 575q0 -7 -7.5 -13.5t-15.5 -6.5 +l-6 1q-22 3 -62 11t-72 12.5t-63 4.5q-167 0 -351 -93q-15 -8 -21 -27q-10 -36 -24.5 -105.5t-22.5 -100.5q-23 -91 -70 -179.5t-112.5 -164.5t-154.5 -123t-185 -47q-135 0 -214.5 83.5t-79.5 219.5q0 53 19.5 117t63 116.5t97.5 52.5q38 0 120 -33.5t83 -61.5 +q0 -1 -16.5 -12.5t-39.5 -31t-46 -44.5t-39 -61t-16 -74q0 -33 16.5 -53t48.5 -20q45 0 85 31.5t66.5 78t48 105.5t32.5 107t16 90v9q0 2 -3.5 3.5t-8.5 1.5h-10t-10 -0.5t-6 -0.5q-227 0 -352 122.5t-125 348.5q0 108 34.5 221t96 210t156 167.5t204.5 89.5q52 9 106 9 +q374 0 374 -360q0 -98 -38 -273t-43 -211l3 -3q101 57 182.5 88t167.5 31q22 0 53 -13q19 -7 80 -102.5t61 -116.5z" /> + <glyph glyph-name="uniF2A7" unicode="&#xf2a7;" horiz-adv-x="1664" +d="M831 863q32 0 59 -18l222 -148q61 -40 110 -97l146 -170q40 -46 29 -106l-72 -413q-6 -32 -29.5 -53.5t-55.5 -25.5l-527 -56l-352 -32h-9q-39 0 -67.5 28t-28.5 68q0 37 27 64t65 32l260 32h-448q-41 0 -69.5 30t-26.5 71q2 39 32 65t69 26l442 1l-521 64q-41 5 -66 37 +t-19 73q6 35 34.5 57.5t65.5 22.5h10l481 -60l-351 94q-38 10 -62 41.5t-18 68.5q6 36 33 58.5t62 22.5q6 0 20 -2l448 -96l217 -37q1 0 3 -0.5t3 -0.5q23 0 30.5 23t-12.5 36l-186 125q-35 23 -42 63.5t18 73.5q27 38 76 38zM761 661l186 -125l-218 37l-5 2l-36 38 +l-238 262q-1 1 -2.5 3.5t-2.5 3.5q-24 31 -18.5 70t37.5 64q31 23 68 17.5t64 -33.5l142 -147q-2 -1 -5 -3.5t-4 -4.5q-32 -45 -23 -99t55 -85zM1648 1115l15 -266q4 -73 -11 -147l-48 -219q-12 -59 -67 -87l-106 -54q2 62 -39 109l-146 170q-53 61 -117 103l-222 148 +q-34 23 -76 23q-51 0 -88 -37l-235 312q-25 33 -18 73.5t41 63.5q33 22 71.5 14t62.5 -40l266 -352l-262 455q-21 35 -10.5 75t47.5 59q35 18 72.5 6t57.5 -46l241 -420l-136 337q-15 35 -4.5 74t44.5 56q37 19 76 6t56 -51l193 -415l101 -196q8 -15 23 -17.5t27 7.5t11 26 +l-12 224q-2 41 26 71t69 31q39 0 67 -28.5t30 -67.5z" /> + <glyph glyph-name="uniF2A8" unicode="&#xf2a8;" horiz-adv-x="1792" +d="M335 180q-2 0 -6 2q-86 57 -168.5 145t-139.5 180q-21 30 -21 69q0 9 2 19t4 18t7 18t8.5 16t10.5 17t10 15t12 15.5t11 14.5q184 251 452 365q-110 198 -110 211q0 19 17 29q116 64 128 64q18 0 28 -16l124 -229q92 19 192 19q266 0 497.5 -137.5t378.5 -369.5 +q20 -31 20 -69t-20 -69q-91 -142 -218.5 -253.5t-278.5 -175.5q110 -198 110 -211q0 -20 -17 -29q-116 -64 -127 -64q-19 0 -29 16l-124 229l-64 119l-444 820l7 7q-58 -24 -99 -47q3 -5 127 -234t243 -449t119 -223q0 -7 -9 -9q-13 -3 -72 -3q-57 0 -60 7l-456 841 +q-39 -28 -82 -68q24 -43 214 -393.5t190 -354.5q0 -10 -11 -10q-14 0 -82.5 22t-72.5 28l-106 197l-224 413q-44 -53 -78 -106q2 -3 18 -25t23 -34l176 -327q0 -10 -10 -10zM1165 282l49 -91q273 111 450 385q-180 277 -459 389q67 -64 103 -148.5t36 -176.5 +q0 -106 -47 -200.5t-132 -157.5zM848 896q0 -20 14 -34t34 -14q86 0 147 -61t61 -147q0 -20 14 -34t34 -14t34 14t14 34q0 126 -89 215t-215 89q-20 0 -34 -14t-14 -34zM1214 961l-9 4l7 -7z" /> + <glyph glyph-name="uniF2A9" unicode="&#xf2a9;" horiz-adv-x="1280" +d="M1050 430q0 -215 -147 -374q-148 -161 -378 -161q-232 0 -378 161q-147 159 -147 374q0 147 68 270.5t189 196.5t268 73q96 0 182 -31q-32 -62 -39 -126q-66 28 -143 28q-167 0 -280.5 -123t-113.5 -291q0 -170 112.5 -288.5t281.5 -118.5t281 118.5t112 288.5 +q0 89 -32 166q66 13 123 49q41 -98 41 -212zM846 619q0 -192 -79.5 -345t-238.5 -253l-14 -1q-29 0 -62 5q83 32 146.5 102.5t99.5 154.5t58.5 189t30 192.5t7.5 178.5q0 69 -3 103q55 -160 55 -326zM791 947v-2q-73 214 -206 440q88 -59 142.5 -186.5t63.5 -251.5z +M1035 744q-83 0 -160 75q218 120 290 247q19 37 21 56q-42 -94 -139.5 -166.5t-204.5 -97.5q-35 54 -35 113q0 37 17 79t43 68q46 44 157 74q59 16 106 58.5t74 100.5q74 -105 74 -253q0 -109 -24 -170q-32 -77 -88.5 -130.5t-130.5 -53.5z" /> + <glyph glyph-name="uniF2AA" unicode="&#xf2aa;" +d="M1050 495q0 78 -28 147q-41 -25 -85 -34q22 -50 22 -114q0 -117 -77 -198.5t-193 -81.5t-193.5 81.5t-77.5 198.5q0 115 78 199.5t193 84.5q53 0 98 -19q4 43 27 87q-60 21 -125 21q-154 0 -257.5 -108.5t-103.5 -263.5t103.5 -261t257.5 -106t257.5 106.5t103.5 260.5z +M872 850q2 -24 2 -71q0 -63 -5 -123t-20.5 -132.5t-40.5 -130t-68.5 -106t-100.5 -70.5q21 -3 42 -3h10q219 139 219 411q0 116 -38 225zM872 850q-4 80 -44 171.5t-98 130.5q92 -156 142 -302zM1207 955q0 102 -51 174q-41 -86 -124 -109q-69 -19 -109 -53.5t-40 -99.5 +q0 -40 24 -77q74 17 140.5 67t95.5 115q-4 -52 -74.5 -111.5t-138.5 -97.5q52 -52 110 -52q51 0 90 37t60 90q17 42 17 117zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5 +t84.5 -203.5z" /> + <glyph glyph-name="uniF2AB" unicode="&#xf2ab;" +d="M1279 388q0 22 -22 27q-67 15 -118 59t-80 108q-7 19 -7 25q0 15 19.5 26t43 17t43 20.5t19.5 36.5q0 19 -18.5 31.5t-38.5 12.5q-12 0 -32 -8t-31 -8q-4 0 -12 2q5 95 5 114q0 79 -17 114q-36 78 -103 121.5t-152 43.5q-199 0 -275 -165q-17 -35 -17 -114q0 -19 5 -114 +q-4 -2 -14 -2q-12 0 -32 7.5t-30 7.5q-21 0 -38.5 -12t-17.5 -32q0 -21 19.5 -35.5t43 -20.5t43 -17t19.5 -26q0 -6 -7 -25q-64 -138 -198 -167q-22 -5 -22 -27q0 -46 137 -68q2 -5 6 -26t11.5 -30.5t23.5 -9.5q12 0 37.5 4.5t39.5 4.5q35 0 67 -15t54 -32.5t57.5 -32.5 +t76.5 -15q43 0 79 15t57.5 32.5t53.5 32.5t67 15q14 0 39.5 -4t38.5 -4q16 0 23 10t11 30t6 25q137 22 137 68zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5 +t103 -385.5z" /> + <glyph glyph-name="uniF2AC" unicode="&#xf2ac;" horiz-adv-x="1664" +d="M848 1408q134 1 240.5 -68.5t163.5 -192.5q27 -58 27 -179q0 -47 -9 -191q14 -7 28 -7q18 0 51 13.5t51 13.5q29 0 56 -18t27 -46q0 -32 -31.5 -54t-69 -31.5t-69 -29t-31.5 -47.5q0 -15 12 -43q37 -82 102.5 -150t144.5 -101q28 -12 80 -23q28 -6 28 -35 +q0 -70 -219 -103q-7 -11 -11 -39t-14 -46.5t-33 -18.5q-20 0 -62 6.5t-64 6.5q-37 0 -62 -5q-32 -5 -63 -22.5t-58 -38t-58 -40.5t-76 -33.5t-99 -13.5q-52 0 -96.5 13.5t-75 33.5t-57.5 40.5t-58 38t-62 22.5q-26 5 -63 5q-24 0 -65.5 -7.5t-58.5 -7.5q-25 0 -35 18.5 +t-14 47.5t-11 40q-219 33 -219 103q0 29 28 35q52 11 80 23q78 32 144.5 101t102.5 150q12 28 12 43q0 28 -31.5 47.5t-69.5 29.5t-69.5 31.5t-31.5 52.5q0 27 26 45.5t55 18.5q15 0 48 -13t53 -13q18 0 32 7q-9 142 -9 190q0 122 27 180q64 137 172 198t264 63z" /> + <glyph glyph-name="uniF2AD" unicode="&#xf2ad;" +d="M1280 388q0 22 -22 27q-67 14 -118 58t-80 109q-7 14 -7 25q0 15 19.5 26t42.5 17t42.5 20.5t19.5 36.5q0 19 -18.5 31.5t-38.5 12.5q-11 0 -31 -8t-32 -8q-4 0 -12 2q5 63 5 115q0 78 -17 114q-36 78 -102.5 121.5t-152.5 43.5q-198 0 -275 -165q-18 -38 -18 -115 +q0 -38 6 -114q-10 -2 -15 -2q-11 0 -31.5 8t-30.5 8q-20 0 -37.5 -12.5t-17.5 -32.5q0 -21 19.5 -35.5t42.5 -20.5t42.5 -17t19.5 -26q0 -11 -7 -25q-64 -138 -198 -167q-22 -5 -22 -27q0 -47 138 -69q2 -5 6 -26t11 -30.5t23 -9.5q13 0 38.5 5t38.5 5q35 0 67.5 -15 +t54.5 -32.5t57.5 -32.5t76.5 -15q43 0 79 15t57.5 32.5t54 32.5t67.5 15q13 0 39 -4.5t39 -4.5q15 0 22.5 9.5t11.5 31t5 24.5q138 22 138 69zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960 +q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="uniF2AE" unicode="&#xf2ae;" horiz-adv-x="2304" +d="M2304 1536q-69 -46 -125 -92t-89 -81t-59.5 -71.5t-37.5 -57.5t-22 -44.5t-14 -29.5q-10 -18 -35.5 -136.5t-48.5 -164.5q-15 -29 -50 -60.5t-67.5 -50.5t-72.5 -41t-48 -28q-47 -31 -151 -231q-341 14 -630 -158q-92 -53 -303 -179q47 16 86 31t55 22l15 7 +q71 27 163 64.5t133.5 53.5t108 34.5t142.5 31.5q186 31 465 -7q1 0 10 -3q11 -6 14 -17t-3 -22l-194 -345q-15 -29 -47 -22q-128 24 -354 24q-146 0 -402 -44.5t-392 -46.5q-82 -1 -149 13t-107 37t-61 40t-33 34l-1 1v2q0 6 6 6q138 0 371 55q192 366 374.5 524t383.5 158 +q5 0 14.5 -0.5t38 -5t55 -12t61.5 -24.5t63 -39.5t54 -59t40 -82.5l102 177q2 4 21 42.5t44.5 86.5t61 109.5t84 133.5t100.5 137q66 82 128 141.5t121.5 96.5t92.5 53.5t88 39.5z" /> + <glyph glyph-name="uniF2B0" unicode="&#xf2b0;" +d="M1322 640q0 -45 -5 -76l-236 14l224 -78q-19 -73 -58 -141l-214 103l177 -158q-44 -61 -107 -108l-157 178l103 -215q-61 -37 -140 -59l-79 228l14 -240q-38 -6 -76 -6t-76 6l14 238l-78 -226q-74 19 -140 59l103 215l-157 -178q-59 43 -108 108l178 158l-214 -104 +q-39 69 -58 141l224 79l-237 -14q-5 42 -5 76q0 35 5 77l238 -14l-225 79q19 73 58 140l214 -104l-177 159q46 61 107 108l158 -178l-103 215q67 39 140 58l77 -224l-13 236q36 6 75 6q38 0 76 -6l-14 -237l78 225q74 -19 140 -59l-103 -214l158 178q61 -47 107 -108 +l-177 -159l213 104q37 -62 58 -141l-224 -78l237 14q5 -31 5 -77zM1352 640q0 160 -78.5 295.5t-213 214t-292.5 78.5q-119 0 -227 -46.5t-186.5 -125t-124.5 -187.5t-46 -229q0 -119 46 -228t124.5 -187.5t186.5 -125t227 -46.5q158 0 292.5 78.5t213 214t78.5 294.5z +M1425 1023v-766l-657 -383l-657 383v766l657 383zM768 -183l708 412v823l-708 411l-708 -411v-823zM1536 1088v-896l-768 -448l-768 448v896l768 448z" /> + <glyph glyph-name="uniF2B1" unicode="&#xf2b1;" horiz-adv-x="1664" +d="M339 1318h691l-26 -72h-665q-110 0 -188.5 -79t-78.5 -189v-771q0 -95 60.5 -169.5t153.5 -93.5q23 -5 98 -5v-72h-45q-140 0 -239.5 100t-99.5 240v771q0 140 99.5 240t239.5 100zM1190 1536h247l-482 -1294q-23 -61 -40.5 -103.5t-45 -98t-54 -93.5t-64.5 -78.5 +t-79.5 -65t-95.5 -41t-116 -18.5v195q163 26 220 182q20 52 20 105q0 54 -20 106l-285 733h228l187 -585zM1664 978v-1111h-795q37 55 45 73h678v1038q0 85 -49.5 155t-129.5 99l25 67q101 -34 163.5 -123.5t62.5 -197.5z" /> + <glyph glyph-name="uniF2B2" unicode="&#xf2b2;" horiz-adv-x="1792" +d="M852 1227q0 -29 -17 -52.5t-45 -23.5t-45 23.5t-17 52.5t17 52.5t45 23.5t45 -23.5t17 -52.5zM688 -149v114q0 30 -20.5 51.5t-50.5 21.5t-50 -21.5t-20 -51.5v-114q0 -30 20.5 -52t49.5 -22q30 0 50.5 22t20.5 52zM860 -149v114q0 30 -20 51.5t-50 21.5t-50.5 -21.5 +t-20.5 -51.5v-114q0 -30 20.5 -52t50.5 -22q29 0 49.5 22t20.5 52zM1034 -149v114q0 30 -20.5 51.5t-50.5 21.5t-50.5 -21.5t-20.5 -51.5v-114q0 -30 20.5 -52t50.5 -22t50.5 22t20.5 52zM1208 -149v114q0 30 -20.5 51.5t-50.5 21.5t-50.5 -21.5t-20.5 -51.5v-114 +q0 -30 20.5 -52t50.5 -22t50.5 22t20.5 52zM1476 535q-84 -160 -232 -259.5t-323 -99.5q-123 0 -229.5 51.5t-178.5 137t-113 197.5t-41 232q0 88 21 174q-104 -175 -104 -390q0 -162 65 -312t185 -251q30 57 91 57q56 0 86 -50q32 50 87 50q56 0 86 -50q32 50 87 50t87 -50 +q30 50 86 50q28 0 52.5 -15.5t37.5 -40.5q112 94 177 231.5t73 287.5zM1326 564q0 75 -72 75q-17 0 -47 -6q-95 -19 -149 -19q-226 0 -226 243q0 86 30 204q-83 -127 -83 -275q0 -150 89 -260.5t235 -110.5q111 0 210 70q13 48 13 79zM884 1223q0 50 -32 89.5t-81 39.5 +t-81 -39.5t-32 -89.5q0 -51 31.5 -90.5t81.5 -39.5t81.5 39.5t31.5 90.5zM1513 884q0 96 -37.5 179t-113 137t-173.5 54q-77 0 -149 -35t-127 -94q-48 -159 -48 -268q0 -104 45.5 -157t147.5 -53q53 0 142 19q36 6 53 6q51 0 77.5 -28t26.5 -80q0 -26 -4 -46 +q75 68 117.5 165.5t42.5 200.5zM1792 667q0 -111 -33.5 -249.5t-93.5 -204.5q-58 -64 -195 -142.5t-228 -104.5l-4 -1v-114q0 -43 -29.5 -75t-72.5 -32q-56 0 -86 50q-32 -50 -87 -50t-87 50q-30 -50 -86 -50q-55 0 -87 50q-30 -50 -86 -50q-47 0 -75 33.5t-28 81.5 +q-90 -68 -198 -68q-118 0 -211 80q54 1 106 20q-113 31 -182 127q32 -7 71 -7q89 0 164 46q-192 192 -240 306q-24 56 -24 160q0 57 9 125.5t31.5 146.5t55 141t86.5 105t120 42q59 0 81 -52q19 29 42 54q2 3 12 13t13 16q10 15 23 38t25 42t28 39q87 111 211.5 177 +t260.5 66q35 0 62 -4q59 64 146 64q83 0 140 -57q5 -5 5 -12q0 -5 -6 -13.5t-12.5 -16t-16 -17l-10.5 -10.5q17 -6 36 -18t19 -24q0 -6 -16 -25q157 -138 197 -378q25 30 60 30q45 0 100 -49q90 -80 90 -279z" /> + <glyph glyph-name="uniF2B3" unicode="&#xf2b3;" +d="M917 631q0 33 -6 64h-362v-132h217q-12 -76 -74.5 -120.5t-142.5 -44.5q-99 0 -169 71.5t-70 170.5t70 170.5t169 71.5q93 0 153 -59l104 101q-108 100 -257 100q-160 0 -272 -112.5t-112 -271.5t112 -271.5t272 -112.5q165 0 266.5 105t101.5 270zM1262 585h109v110 +h-109v110h-110v-110h-110v-110h110v-110h110v110zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="uniF2B4" unicode="&#xf2b4;" +d="M1536 1024v-839q0 -48 -49 -62q-174 -52 -338 -52q-73 0 -215.5 29.5t-227.5 29.5q-164 0 -370 -48v-338h-160v1368q-63 25 -101 81t-38 124q0 91 64 155t155 64t155 -64t64 -155q0 -68 -38 -124t-101 -81v-68q190 44 343 44q99 0 198 -15q14 -2 111.5 -22.5t149.5 -20.5 +q77 0 165 18q11 2 80 21t89 19q26 0 45 -19t19 -45z" /> + <glyph glyph-name="uniF2B5" unicode="&#xf2b5;" horiz-adv-x="2304" +d="M192 384q40 0 56 32t0 64t-56 32t-56 -32t0 -64t56 -32zM1665 442q-10 13 -38.5 50t-41.5 54t-38 49t-42.5 53t-40.5 47t-45 49l-125 -140q-83 -94 -208.5 -92t-205.5 98q-57 69 -56.5 158t58.5 157l177 206q-22 11 -51 16.5t-47.5 6t-56.5 -0.5t-49 -1q-92 0 -158 -66 +l-158 -158h-155v-544q5 0 21 0.5t22 0t19.5 -2t20.5 -4.5t17.5 -8.5t18.5 -13.5l297 -292q115 -111 227 -111q78 0 125 47q57 -20 112.5 8t72.5 85q74 -6 127 44q20 18 36 45.5t14 50.5q10 -10 43 -10q43 0 77 21t49.5 53t12 71.5t-30.5 73.5zM1824 384h96v512h-93l-157 180 +q-66 76 -169 76h-167q-89 0 -146 -67l-209 -243q-28 -33 -28 -75t27 -75q43 -51 110 -52t111 49l193 218q25 23 53.5 21.5t47 -27t8.5 -56.5q16 -19 56 -63t60 -68q29 -36 82.5 -105.5t64.5 -84.5q52 -66 60 -140zM2112 384q40 0 56 32t0 64t-56 32t-56 -32t0 -64t56 -32z +M2304 960v-640q0 -26 -19 -45t-45 -19h-434q-27 -65 -82 -106.5t-125 -51.5q-33 -48 -80.5 -81.5t-102.5 -45.5q-42 -53 -104.5 -81.5t-128.5 -24.5q-60 -34 -126 -39.5t-127.5 14t-117 53.5t-103.5 81l-287 282h-358q-26 0 -45 19t-19 45v672q0 26 19 45t45 19h421 +q14 14 47 48t47.5 48t44 40t50.5 37.5t51 25.5t62 19.5t68 5.5h117q99 0 181 -56q82 56 181 56h167q35 0 67 -6t56.5 -14.5t51.5 -26.5t44.5 -31t43 -39.5t39 -42t41 -48t41.5 -48.5h355q26 0 45 -19t19 -45z" /> + <glyph glyph-name="uniF2B6" unicode="&#xf2b6;" horiz-adv-x="1792" +d="M1792 882v-978q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v978q0 15 11 24q8 7 39 34.5t41.5 36t45.5 37.5t70 55.5t96 73t143.5 107t192.5 140.5q5 4 52.5 40t71.5 52.5t64 35t69 18.5t69 -18.5t65 -35.5t71 -52t52 -40q110 -80 192.5 -140.5t143.5 -107 +t96 -73t70 -55.5t45.5 -37.5t41.5 -36t39 -34.5q11 -9 11 -24zM1228 297q263 191 345 252q11 8 12.5 20.5t-6.5 23.5l-38 52q-8 11 -21 12.5t-24 -6.5q-231 -169 -343 -250q-5 -3 -52 -39t-71.5 -52.5t-64.5 -35t-69 -18.5t-69 18.5t-64.5 35t-71.5 52.5t-52 39 +q-186 134 -343 250q-11 8 -24 6.5t-21 -12.5l-38 -52q-8 -11 -6.5 -23.5t12.5 -20.5q82 -61 345 -252q10 -8 50 -38t65 -47t64 -39.5t77.5 -33.5t75.5 -11t75.5 11t79 34.5t64.5 39.5t65 47.5t48 36.5z" /> + <glyph glyph-name="uniF2B7" unicode="&#xf2b7;" horiz-adv-x="1792" +d="M1474 623l39 -51q8 -11 6.5 -23.5t-11.5 -20.5q-43 -34 -126.5 -98.5t-146.5 -113t-67 -51.5q-39 -32 -60 -48t-60.5 -41t-76.5 -36.5t-74 -11.5h-1h-1q-37 0 -74 11.5t-76 36.5t-61 41.5t-60 47.5q-5 4 -65 50.5t-143.5 111t-122.5 94.5q-11 8 -12.5 20.5t6.5 23.5 +l37 52q8 11 21.5 13t24.5 -7q94 -73 306 -236q5 -4 43.5 -35t60.5 -46.5t56.5 -32.5t58.5 -17h1h1q24 0 58.5 17t56.5 32.5t60.5 46.5t43.5 35q258 198 313 242q11 8 24 6.5t21 -12.5zM1664 -96v928q-90 83 -159 139q-91 74 -389 304q-3 2 -43 35t-61 48t-56 32.5t-59 17.5 +h-1h-1q-24 0 -59 -17.5t-56 -32.5t-61 -48t-43 -35q-215 -166 -315.5 -245.5t-129.5 -104t-82 -74.5q-14 -12 -21 -19v-928q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5zM1792 832v-928q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v928q0 56 41 94 +q123 114 350 290.5t233 181.5q36 30 59 47.5t61.5 42t76 36.5t74.5 12h1h1q37 0 74.5 -12t76 -36.5t61.5 -42t59 -47.5q43 -36 156 -122t226 -177t201 -173q41 -38 41 -94z" /> + <glyph glyph-name="uniF2B8" unicode="&#xf2b8;" +d="M330 1l202 -214l-34 236l-216 213zM556 -225l274 218l-11 245l-300 -215zM245 413l227 -213l-48 327l-245 204zM495 189l317 214l-14 324l-352 -200zM843 178l95 -80l-2 239l-103 79q0 -1 1 -8.5t0 -12t-5 -7.5l-78 -52l85 -70q7 -6 7 -88zM138 930l256 -200l-68 465 +l-279 173zM1173 267l15 234l-230 -164l2 -240zM417 722l373 194l-19 441l-423 -163zM1270 357l20 233l-226 142l-2 -105l144 -95q6 -4 4 -9l-7 -119zM1461 496l30 222l-179 -128l-20 -228zM1273 329l-71 49l-8 -117q0 -5 -4 -8l-234 -187q-7 -5 -14 0l-98 83l7 -161 +q0 -5 -4 -8l-293 -234q-4 -2 -6 -2q-8 2 -8 3l-228 242q-4 4 -59 277q-2 7 5 11l61 37q-94 86 -95 92l-72 351q-2 7 6 12l94 45q-133 100 -135 108l-96 466q-2 10 7 13l433 135q5 0 8 -1l317 -153q6 -4 6 -9l20 -463q0 -7 -6 -10l-118 -61l126 -85q5 -2 5 -8l5 -123l121 74 +q5 4 11 0l84 -56l3 110q0 6 5 9l206 126q6 3 11 0l245 -135q4 -4 5 -7t-6.5 -60t-17.5 -124.5t-10 -70.5q0 -5 -4 -7l-191 -153q-6 -5 -13 0z" /> + <glyph glyph-name="uniF2B9" unicode="&#xf2b9;" horiz-adv-x="1664" +d="M1201 298q0 57 -5.5 107t-21 100.5t-39.5 86t-64 58t-91 22.5q-6 -4 -33.5 -20.5t-42.5 -24.5t-40.5 -20t-49 -17t-46.5 -5t-46.5 5t-49 17t-40.5 20t-42.5 24.5t-33.5 20.5q-51 0 -91 -22.5t-64 -58t-39.5 -86t-21 -100.5t-5.5 -107q0 -73 42 -121.5t103 -48.5h576 +q61 0 103 48.5t42 121.5zM1028 892q0 108 -76.5 184t-183.5 76t-183.5 -76t-76.5 -184q0 -107 76.5 -183t183.5 -76t183.5 76t76.5 183zM1664 352v-192q0 -14 -9 -23t-23 -9h-96v-224q0 -66 -47 -113t-113 -47h-1216q-66 0 -113 47t-47 113v1472q0 66 47 113t113 47h1216 +q66 0 113 -47t47 -113v-224h96q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-96v-128h96q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-96v-128h96q14 0 23 -9t9 -23z" /> + <glyph glyph-name="uniF2BA" unicode="&#xf2ba;" horiz-adv-x="1664" +d="M1028 892q0 -107 -76.5 -183t-183.5 -76t-183.5 76t-76.5 183q0 108 76.5 184t183.5 76t183.5 -76t76.5 -184zM980 672q46 0 82.5 -17t60 -47.5t39.5 -67t24 -81t11.5 -82.5t3.5 -79q0 -67 -39.5 -118.5t-105.5 -51.5h-576q-66 0 -105.5 51.5t-39.5 118.5q0 48 4.5 93.5 +t18.5 98.5t36.5 91.5t63 64.5t93.5 26h5q7 -4 32 -19.5t35.5 -21t33 -17t37 -16t35 -9t39.5 -4.5t39.5 4.5t35 9t37 16t33 17t35.5 21t32 19.5zM1664 928q0 -13 -9.5 -22.5t-22.5 -9.5h-96v-128h96q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-96v-128h96 +q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-96v-224q0 -66 -47 -113t-113 -47h-1216q-66 0 -113 47t-47 113v1472q0 66 47 113t113 47h1216q66 0 113 -47t47 -113v-224h96q13 0 22.5 -9.5t9.5 -22.5v-192zM1408 -96v1472q0 13 -9.5 22.5t-22.5 9.5h-1216 +q-13 0 -22.5 -9.5t-9.5 -22.5v-1472q0 -13 9.5 -22.5t22.5 -9.5h1216q13 0 22.5 9.5t9.5 22.5z" /> + <glyph glyph-name="uniF2BB" unicode="&#xf2bb;" horiz-adv-x="2048" +d="M1024 405q0 64 -9 117.5t-29.5 103t-60.5 78t-97 28.5q-6 -4 -30 -18t-37.5 -21.5t-35.5 -17.5t-43 -14.5t-42 -4.5t-42 4.5t-43 14.5t-35.5 17.5t-37.5 21.5t-30 18q-57 0 -97 -28.5t-60.5 -78t-29.5 -103t-9 -117.5t37 -106.5t91 -42.5h512q54 0 91 42.5t37 106.5z +M867 925q0 94 -66.5 160.5t-160.5 66.5t-160.5 -66.5t-66.5 -160.5t66.5 -160.5t160.5 -66.5t160.5 66.5t66.5 160.5zM1792 416v64q0 14 -9 23t-23 9h-576q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h576q14 0 23 9t9 23zM1792 676v56q0 15 -10.5 25.5t-25.5 10.5h-568 +q-15 0 -25.5 -10.5t-10.5 -25.5v-56q0 -15 10.5 -25.5t25.5 -10.5h568q15 0 25.5 10.5t10.5 25.5zM1792 928v64q0 14 -9 23t-23 9h-576q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h576q14 0 23 9t9 23zM2048 1248v-1216q0 -66 -47 -113t-113 -47h-352v96q0 14 -9 23t-23 9 +h-64q-14 0 -23 -9t-9 -23v-96h-768v96q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-96h-352q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1728q66 0 113 -47t47 -113z" /> + <glyph glyph-name="uniF2BC" unicode="&#xf2bc;" horiz-adv-x="2048" +d="M1024 405q0 -64 -37 -106.5t-91 -42.5h-512q-54 0 -91 42.5t-37 106.5t9 117.5t29.5 103t60.5 78t97 28.5q6 -4 30 -18t37.5 -21.5t35.5 -17.5t43 -14.5t42 -4.5t42 4.5t43 14.5t35.5 17.5t37.5 21.5t30 18q57 0 97 -28.5t60.5 -78t29.5 -103t9 -117.5zM867 925 +q0 -94 -66.5 -160.5t-160.5 -66.5t-160.5 66.5t-66.5 160.5t66.5 160.5t160.5 66.5t160.5 -66.5t66.5 -160.5zM1792 480v-64q0 -14 -9 -23t-23 -9h-576q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h576q14 0 23 -9t9 -23zM1792 732v-56q0 -15 -10.5 -25.5t-25.5 -10.5h-568 +q-15 0 -25.5 10.5t-10.5 25.5v56q0 15 10.5 25.5t25.5 10.5h568q15 0 25.5 -10.5t10.5 -25.5zM1792 992v-64q0 -14 -9 -23t-23 -9h-576q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h576q14 0 23 -9t9 -23zM1920 32v1216q0 13 -9.5 22.5t-22.5 9.5h-1728q-13 0 -22.5 -9.5 +t-9.5 -22.5v-1216q0 -13 9.5 -22.5t22.5 -9.5h352v96q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-96h768v96q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-96h352q13 0 22.5 9.5t9.5 22.5zM2048 1248v-1216q0 -66 -47 -113t-113 -47h-1728q-66 0 -113 47t-47 113v1216q0 66 47 113 +t113 47h1728q66 0 113 -47t47 -113z" /> + <glyph glyph-name="uniF2BD" unicode="&#xf2bd;" horiz-adv-x="1792" +d="M1523 197q-22 155 -87.5 257.5t-184.5 118.5q-67 -74 -159.5 -115.5t-195.5 -41.5t-195.5 41.5t-159.5 115.5q-119 -16 -184.5 -118.5t-87.5 -257.5q106 -150 271 -237.5t356 -87.5t356 87.5t271 237.5zM1280 896q0 159 -112.5 271.5t-271.5 112.5t-271.5 -112.5 +t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5zM1792 640q0 -182 -71 -347.5t-190.5 -286t-285.5 -191.5t-349 -71q-182 0 -348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" /> + <glyph glyph-name="uniF2BE" unicode="&#xf2be;" horiz-adv-x="1792" +d="M896 1536q182 0 348 -71t286 -191t191 -286t71 -348q0 -181 -70.5 -347t-190.5 -286t-286 -191.5t-349 -71.5t-349 71t-285.5 191.5t-190.5 286t-71 347.5t71 348t191 286t286 191t348 71zM1515 185q149 205 149 455q0 156 -61 298t-164 245t-245 164t-298 61t-298 -61 +t-245 -164t-164 -245t-61 -298q0 -250 149 -455q66 327 306 327q131 -128 313 -128t313 128q240 0 306 -327zM1280 832q0 159 -112.5 271.5t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5z" /> + <glyph glyph-name="uniF2C0" unicode="&#xf2c0;" +d="M1201 752q47 -14 89.5 -38t89 -73t79.5 -115.5t55 -172t22 -236.5q0 -154 -100 -263.5t-241 -109.5h-854q-141 0 -241 109.5t-100 263.5q0 131 22 236.5t55 172t79.5 115.5t89 73t89.5 38q-79 125 -79 272q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5 +t198.5 -40.5t163.5 -109.5t109.5 -163.5t40.5 -198.5q0 -147 -79 -272zM768 1408q-159 0 -271.5 -112.5t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5t-112.5 271.5t-271.5 112.5zM1195 -128q88 0 150.5 71.5t62.5 173.5q0 239 -78.5 377t-225.5 145 +q-145 -127 -336 -127t-336 127q-147 -7 -225.5 -145t-78.5 -377q0 -102 62.5 -173.5t150.5 -71.5h854z" /> + <glyph glyph-name="uniF2C1" unicode="&#xf2c1;" horiz-adv-x="1280" +d="M1024 278q0 -64 -37 -107t-91 -43h-512q-54 0 -91 43t-37 107t9 118t29.5 104t61 78.5t96.5 28.5q80 -75 188 -75t188 75q56 0 96.5 -28.5t61 -78.5t29.5 -104t9 -118zM870 797q0 -94 -67.5 -160.5t-162.5 -66.5t-162.5 66.5t-67.5 160.5t67.5 160.5t162.5 66.5 +t162.5 -66.5t67.5 -160.5zM1152 -96v1376h-1024v-1376q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5zM1280 1376v-1472q0 -66 -47 -113t-113 -47h-960q-66 0 -113 47t-47 113v1472q0 66 47 113t113 47h352v-96q0 -14 9 -23t23 -9h192q14 0 23 9t9 23v96h352 +q66 0 113 -47t47 -113z" /> + <glyph glyph-name="uniF2C2" unicode="&#xf2c2;" horiz-adv-x="2048" +d="M896 324q0 54 -7.5 100.5t-24.5 90t-51 68.5t-81 25q-64 -64 -156 -64t-156 64q-47 0 -81 -25t-51 -68.5t-24.5 -90t-7.5 -100.5q0 -55 31.5 -93.5t75.5 -38.5h426q44 0 75.5 38.5t31.5 93.5zM768 768q0 80 -56 136t-136 56t-136 -56t-56 -136t56 -136t136 -56t136 56 +t56 136zM1792 288v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704q14 0 23 9t9 23zM1408 544v64q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1792 544v64q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23 +v-64q0 -14 9 -23t23 -9h192q14 0 23 9t9 23zM1792 800v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704q14 0 23 9t9 23zM128 1152h1792v96q0 14 -9 23t-23 9h-1728q-14 0 -23 -9t-9 -23v-96zM2048 1248v-1216q0 -66 -47 -113t-113 -47h-1728 +q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1728q66 0 113 -47t47 -113z" /> + <glyph glyph-name="uniF2C3" unicode="&#xf2c3;" horiz-adv-x="2048" +d="M896 324q0 -55 -31.5 -93.5t-75.5 -38.5h-426q-44 0 -75.5 38.5t-31.5 93.5q0 54 7.5 100.5t24.5 90t51 68.5t81 25q64 -64 156 -64t156 64q47 0 81 -25t51 -68.5t24.5 -90t7.5 -100.5zM768 768q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136z +M1792 352v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h704q14 0 23 -9t9 -23zM1408 608v-64q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h320q14 0 23 -9t9 -23zM1792 608v-64q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v64 +q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1792 864v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h704q14 0 23 -9t9 -23zM1920 32v1120h-1792v-1120q0 -13 9.5 -22.5t22.5 -9.5h1728q13 0 22.5 9.5t9.5 22.5zM2048 1248v-1216q0 -66 -47 -113t-113 -47 +h-1728q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1728q66 0 113 -47t47 -113z" /> + <glyph glyph-name="uniF2C4" unicode="&#xf2c4;" horiz-adv-x="1792" +d="M1255 749q0 318 -105 474.5t-330 156.5q-222 0 -326 -157t-104 -474q0 -316 104 -471.5t326 -155.5q74 0 131 17q-22 43 -39 73t-44 65t-53.5 56.5t-63 36t-77.5 14.5q-46 0 -79 -16l-49 97q105 91 276 91q132 0 215.5 -54t150.5 -155q67 149 67 402zM1645 117h117 +q3 -27 -2 -67t-26.5 -95t-58 -100.5t-107 -78t-162.5 -32.5q-71 0 -130.5 19t-105.5 56t-79 78t-66 96q-97 -27 -205 -27q-150 0 -292.5 58t-253 158.5t-178 249t-67.5 317.5q0 170 67.5 319.5t178.5 250.5t253.5 159t291.5 58q121 0 238.5 -36t217 -106t176 -164.5 +t119.5 -219t43 -261.5q0 -190 -80.5 -347.5t-218.5 -264.5q47 -70 93.5 -106.5t104.5 -36.5q61 0 94 37.5t38 85.5z" /> + <glyph glyph-name="uniF2C5" unicode="&#xf2c5;" horiz-adv-x="2304" +d="M453 -101q0 -21 -16 -37.5t-37 -16.5q-1 0 -13 3q-63 15 -162 140q-225 284 -225 676q0 341 213 614q39 51 95 103.5t94 52.5q19 0 35 -13.5t16 -32.5q0 -27 -63 -90q-98 -102 -147 -184q-119 -199 -119 -449q0 -281 123 -491q50 -85 136 -173q2 -3 14.5 -16t19.5 -21 +t17 -20.5t14.5 -23.5t4.5 -21zM1796 33q0 -29 -17.5 -48.5t-46.5 -19.5h-1081q-26 0 -45 19t-19 45q0 29 17.5 48.5t46.5 19.5h1081q26 0 45 -19t19 -45zM1581 644q0 -134 -67 -233q-25 -38 -69.5 -78.5t-83.5 -60.5q-16 -10 -27 -10q-7 0 -15 6t-8 12q0 9 19 30t42 46 +t42 67.5t19 88.5q0 76 -35 130q-29 42 -46 42q-3 0 -3 -5q0 -12 7.5 -35.5t7.5 -36.5q0 -22 -21.5 -35t-44.5 -13q-66 0 -66 76q0 15 1.5 44t1.5 44q0 25 -10 46q-13 25 -42 53.5t-51 28.5q-5 0 -7 -0.5t-3.5 -2.5t-1.5 -6q0 -2 16 -26t16 -54q0 -37 -19 -68t-46 -54 +t-53.5 -46t-45.5 -54t-19 -68q0 -98 42 -160q29 -43 79 -63q16 -5 17 -10q1 -2 1 -5q0 -16 -18 -16q-6 0 -33 11q-119 43 -195 139.5t-76 218.5q0 55 24.5 115.5t60 115t70.5 108.5t59.5 113.5t24.5 111.5q0 53 -25 94q-29 48 -56 64q-19 9 -19 21q0 20 41 20q50 0 110 -29 +q41 -19 71 -44.5t49.5 -51t33.5 -62.5t22 -69t16 -80q0 -1 3 -17.5t4.5 -25t5.5 -25t9 -27t11 -21.5t14.5 -16.5t18.5 -5.5q23 0 37 14t14 37q0 25 -20 67t-20 52t10 10q27 0 93 -70q72 -76 102.5 -156t30.5 -186zM2304 615q0 -274 -138 -503q-19 -32 -48 -72t-68 -86.5 +t-81 -77t-74 -30.5q-16 0 -31 15.5t-15 31.5q0 15 29 50.5t68.5 77t48.5 52.5q183 230 183 531q0 131 -20.5 235t-72.5 211q-58 119 -163 228q-2 3 -13 13.5t-16.5 16.5t-15 17.5t-15 20t-9.5 18.5t-4 19q0 19 16 35.5t35 16.5q70 0 196 -169q98 -131 146 -273t60 -314 +q2 -42 2 -64z" /> + <glyph glyph-name="uniF2C6" unicode="&#xf2c6;" horiz-adv-x="1792" +d="M1189 229l147 693q9 44 -10.5 63t-51.5 7l-864 -333q-29 -11 -39.5 -25t-2.5 -26.5t32 -19.5l221 -69l513 323q21 14 32 6q7 -5 -4 -15l-415 -375v0v0l-16 -228q23 0 45 22l108 104l224 -165q64 -36 81 38zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71 +t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" /> + <glyph glyph-name="uniF2C7" unicode="&#xf2c7;" horiz-adv-x="1024" +d="M640 192q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 60 35 110t93 71v907h128v-907q58 -21 93 -71t35 -110zM768 192q0 77 -34 144t-94 112v768q0 80 -56 136t-136 56t-136 -56t-56 -136v-768q-60 -45 -94 -112t-34 -144q0 -133 93.5 -226.5t226.5 -93.5t226.5 93.5 +t93.5 226.5zM896 192q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 182 128 313v711q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5v-711q128 -131 128 -313zM1024 768v-128h-192v128h192zM1024 1024v-128h-192v128h192zM1024 1280v-128h-192 +v128h192z" /> + <glyph glyph-name="uniF2C8" unicode="&#xf2c8;" horiz-adv-x="1024" +d="M640 192q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 60 35 110t93 71v651h128v-651q58 -21 93 -71t35 -110zM768 192q0 77 -34 144t-94 112v768q0 80 -56 136t-136 56t-136 -56t-56 -136v-768q-60 -45 -94 -112t-34 -144q0 -133 93.5 -226.5t226.5 -93.5t226.5 93.5 +t93.5 226.5zM896 192q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 182 128 313v711q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5v-711q128 -131 128 -313zM1024 768v-128h-192v128h192zM1024 1024v-128h-192v128h192zM1024 1280v-128h-192 +v128h192z" /> + <glyph glyph-name="uniF2C9" unicode="&#xf2c9;" horiz-adv-x="1024" +d="M640 192q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 60 35 110t93 71v395h128v-395q58 -21 93 -71t35 -110zM768 192q0 77 -34 144t-94 112v768q0 80 -56 136t-136 56t-136 -56t-56 -136v-768q-60 -45 -94 -112t-34 -144q0 -133 93.5 -226.5t226.5 -93.5t226.5 93.5 +t93.5 226.5zM896 192q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 182 128 313v711q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5v-711q128 -131 128 -313zM1024 768v-128h-192v128h192zM1024 1024v-128h-192v128h192zM1024 1280v-128h-192 +v128h192z" /> + <glyph glyph-name="uniF2CA" unicode="&#xf2ca;" horiz-adv-x="1024" +d="M640 192q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 60 35 110t93 71v139h128v-139q58 -21 93 -71t35 -110zM768 192q0 77 -34 144t-94 112v768q0 80 -56 136t-136 56t-136 -56t-56 -136v-768q-60 -45 -94 -112t-34 -144q0 -133 93.5 -226.5t226.5 -93.5t226.5 93.5 +t93.5 226.5zM896 192q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 182 128 313v711q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5v-711q128 -131 128 -313zM1024 768v-128h-192v128h192zM1024 1024v-128h-192v128h192zM1024 1280v-128h-192 +v128h192z" /> + <glyph glyph-name="uniF2CB" unicode="&#xf2cb;" horiz-adv-x="1024" +d="M640 192q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 79 56 135.5t136 56.5t136 -56.5t56 -135.5zM768 192q0 77 -34 144t-94 112v768q0 80 -56 136t-136 56t-136 -56t-56 -136v-768q-60 -45 -94 -112t-34 -144q0 -133 93.5 -226.5t226.5 -93.5t226.5 93.5t93.5 226.5z +M896 192q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 182 128 313v711q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5v-711q128 -131 128 -313zM1024 768v-128h-192v128h192zM1024 1024v-128h-192v128h192zM1024 1280v-128h-192v128h192z" /> + <glyph glyph-name="uniF2CC" unicode="&#xf2cc;" horiz-adv-x="1920" +d="M1433 1287q10 -10 10 -23t-10 -23l-626 -626q-10 -10 -23 -10t-23 10l-82 82q-10 10 -10 23t10 23l44 44q-72 91 -81.5 207t46.5 215q-74 71 -176 71q-106 0 -181 -75t-75 -181v-1280h-256v1280q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5q106 0 201 -41 +t166 -115q94 39 197 24.5t185 -79.5l44 44q10 10 23 10t23 -10zM1344 1024q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1600 896q-26 0 -45 19t-19 45t19 45t45 19t45 -19t19 -45t-19 -45t-45 -19zM1856 1024q26 0 45 -19t19 -45t-19 -45t-45 -19 +t-45 19t-19 45t19 45t45 19zM1216 896q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1408 832q0 26 19 45t45 19t45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45zM1728 896q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1088 768 +q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1344 640q-26 0 -45 19t-19 45t19 45t45 19t45 -19t19 -45t-19 -45t-45 -19zM1600 768q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1216 512q-26 0 -45 19t-19 45t19 45t45 19t45 -19 +t19 -45t-19 -45t-45 -19zM1472 640q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1088 512q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1344 512q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1216 384 +q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1088 256q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19z" /> + <glyph glyph-name="uniF2CD" unicode="&#xf2cd;" horiz-adv-x="1792" +d="M1664 448v-192q0 -169 -128 -286v-194q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v118q-63 -22 -128 -22h-768q-65 0 -128 22v-110q0 -17 -9.5 -28.5t-22.5 -11.5h-64q-13 0 -22.5 11.5t-9.5 28.5v186q-128 117 -128 286v192h1536zM704 864q0 -14 -9 -23t-23 -9t-23 9 +t-9 23t9 23t23 9t23 -9t9 -23zM768 928q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM704 992q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM832 992q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM768 1056q0 -14 -9 -23t-23 -9t-23 9 +t-9 23t9 23t23 9t23 -9t9 -23zM704 1120q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM1792 608v-64q0 -14 -9 -23t-23 -9h-1728q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v640q0 106 75 181t181 75q108 0 184 -78q46 19 98 12t93 -39l22 22q11 11 22 0l42 -42 +q11 -11 0 -22l-314 -314q-11 -11 -22 0l-42 42q-11 11 0 22l22 22q-36 46 -40.5 104t23.5 108q-37 35 -88 35q-53 0 -90.5 -37.5t-37.5 -90.5v-640h1504q14 0 23 -9t9 -23zM896 1056q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM832 1120q0 -14 -9 -23t-23 -9 +t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM768 1184q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM960 1120q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM896 1184q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM832 1248q0 -14 -9 -23 +t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM1024 1184q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM960 1248q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM1088 1248q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23z" /> + <glyph glyph-name="uniF2CE" unicode="&#xf2ce;" +d="M994 344q0 -86 -17 -197q-31 -215 -55 -313q-22 -90 -152 -90t-152 90q-24 98 -55 313q-17 110 -17 197q0 168 224 168t224 -168zM1536 768q0 -240 -134 -434t-350 -280q-8 -3 -15 3t-6 15q7 48 10 66q4 32 6 47q1 9 9 12q159 81 255.5 234t96.5 337q0 180 -91 330.5 +t-247 234.5t-337 74q-124 -7 -237 -61t-193.5 -140.5t-128 -202t-46.5 -240.5q1 -184 99 -336.5t257 -231.5q7 -3 9 -12q3 -21 6 -45q1 -9 5 -32.5t6 -35.5q1 -9 -6.5 -15t-15.5 -2q-148 58 -261 169.5t-173.5 264t-52.5 319.5q7 143 66 273.5t154.5 227t225 157.5t272.5 70 +q164 10 315.5 -46.5t261 -160.5t175 -250.5t65.5 -308.5zM994 800q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5zM1282 768q0 -122 -53.5 -228.5t-146.5 -177.5q-8 -6 -16 -2t-10 14q-6 52 -29 92q-7 10 3 20 +q58 54 91 127t33 155q0 111 -58.5 204t-157.5 141.5t-212 36.5q-133 -15 -229 -113t-109 -231q-10 -92 23.5 -176t98.5 -144q10 -10 3 -20q-24 -41 -29 -93q-2 -9 -10 -13t-16 2q-95 74 -148.5 183t-51.5 234q3 131 69 244t177 181.5t241 74.5q144 7 268 -60t196.5 -187.5 +t72.5 -263.5z" /> + <glyph glyph-name="uniF2D0" unicode="&#xf2d0;" horiz-adv-x="1792" +d="M256 128h1280v768h-1280v-768zM1792 1248v-1216q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1472q66 0 113 -47t47 -113z" /> + <glyph glyph-name="uniF2D1" unicode="&#xf2d1;" horiz-adv-x="1792" +d="M1792 224v-192q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v192q0 66 47 113t113 47h1472q66 0 113 -47t47 -113z" /> + <glyph glyph-name="uniF2D2" unicode="&#xf2d2;" horiz-adv-x="2048" +d="M256 0h768v512h-768v-512zM1280 512h512v768h-768v-256h96q66 0 113 -47t47 -113v-352zM2048 1376v-960q0 -66 -47 -113t-113 -47h-608v-352q0 -66 -47 -113t-113 -47h-960q-66 0 -113 47t-47 113v960q0 66 47 113t113 47h608v352q0 66 47 113t113 47h960q66 0 113 -47 +t47 -113z" /> + <glyph glyph-name="uniF2D3" unicode="&#xf2d3;" horiz-adv-x="1792" +d="M1175 215l146 146q10 10 10 23t-10 23l-233 233l233 233q10 10 10 23t-10 23l-146 146q-10 10 -23 10t-23 -10l-233 -233l-233 233q-10 10 -23 10t-23 -10l-146 -146q-10 -10 -10 -23t10 -23l233 -233l-233 -233q-10 -10 -10 -23t10 -23l146 -146q10 -10 23 -10t23 10 +l233 233l233 -233q10 -10 23 -10t23 10zM1792 1248v-1216q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1472q66 0 113 -47t47 -113z" /> + <glyph glyph-name="uniF2D4" unicode="&#xf2d4;" horiz-adv-x="1792" +d="M1257 425l-146 -146q-10 -10 -23 -10t-23 10l-169 169l-169 -169q-10 -10 -23 -10t-23 10l-146 146q-10 10 -10 23t10 23l169 169l-169 169q-10 10 -10 23t10 23l146 146q10 10 23 10t23 -10l169 -169l169 169q10 10 23 10t23 -10l146 -146q10 -10 10 -23t-10 -23 +l-169 -169l169 -169q10 -10 10 -23t-10 -23zM256 128h1280v1024h-1280v-1024zM1792 1248v-1216q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1472q66 0 113 -47t47 -113z" /> + <glyph glyph-name="uniF2D5" unicode="&#xf2d5;" horiz-adv-x="1792" +d="M1070 358l306 564h-654l-306 -564h654zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" /> + <glyph glyph-name="uniF2D6" unicode="&#xf2d6;" horiz-adv-x="1794" +d="M1291 1060q-15 17 -35 8.5t-26 -28.5t5 -38q14 -17 40 -14.5t34 20.5t-18 52zM895 814q-8 -8 -19.5 -8t-18.5 8q-8 8 -8 19t8 18q7 8 18.5 8t19.5 -8q7 -7 7 -18t-7 -19zM1060 740l-35 -35q-12 -13 -29.5 -13t-30.5 13l-38 38q-12 13 -12 30t12 30l35 35q12 12 29.5 12 +t30.5 -12l38 -39q12 -12 12 -29.5t-12 -29.5zM951 870q-7 -8 -18.5 -8t-19.5 8q-7 8 -7 19t7 19q8 8 19 8t19 -8t8 -19t-8 -19zM1354 968q-34 -64 -107.5 -85.5t-127.5 16.5q-38 28 -61 66.5t-21 87.5t39 92t75.5 53t70.5 -5t70 -51q2 -2 13 -12.5t14.5 -13.5t13 -13.5 +t12.5 -15.5t10 -15.5t8.5 -18t4 -18.5t1 -21t-5 -22t-9.5 -24zM1555 486q3 20 -8.5 34.5t-27.5 21.5t-33 17t-23 20q-40 71 -84 98.5t-113 11.5q19 13 40 18.5t33 4.5l12 -1q2 45 -34 90q6 20 6.5 40.5t-2.5 30.5l-3 10q43 24 71 65t34 91q10 84 -43 150.5t-137 76.5 +q-60 7 -114 -18.5t-82 -74.5q-30 -51 -33.5 -101t14.5 -87t43.5 -64t56.5 -42q-45 4 -88 36t-57 88q-28 108 32 222q-16 21 -29 32q-50 0 -89 -19q19 24 42 37t36 14l13 1q0 50 -13 78q-10 21 -32.5 28.5t-47 -3.5t-37.5 -40q2 4 4 7q-7 -28 -6.5 -75.5t19 -117t48.5 -122.5 +q-25 -14 -47 -36q-35 -16 -85.5 -70.5t-84.5 -101.5l-33 -46q-90 -34 -181 -125.5t-75 -162.5q1 -16 11 -27q-15 -12 -30 -30q-21 -25 -21 -54t21.5 -40t63.5 6q41 19 77 49.5t55 60.5q-2 2 -6.5 5t-20.5 7.5t-33 3.5q23 5 51 12.5t40 10t27.5 6t26 4t23.5 0.5q14 -7 22 34 +q7 37 7 90q0 102 -40 150q106 -103 101 -219q-1 -29 -15 -50t-27 -27l-13 -6q-4 -7 -19 -32t-26 -45.5t-26.5 -52t-25 -61t-17 -63t-6.5 -66.5t10 -63q-35 54 -37 80q-22 -24 -34.5 -39t-33.5 -42t-30.5 -46t-16.5 -41t-0.5 -38t25.5 -27q45 -25 144 64t190.5 221.5 +t122.5 228.5q86 52 145 115.5t86 119.5q47 -93 154 -178q104 -83 167 -80q39 2 46 43zM1794 640q0 -182 -71 -348t-191 -286t-286.5 -191t-348.5 -71t-348.5 71t-286.5 191t-191 286t-71 348t71 348t191 286t286.5 191t348.5 71t348.5 -71t286.5 -191t191 -286t71 -348z" /> + <glyph glyph-name="uniF2D7" unicode="&#xf2d7;" +d="M518 1353v-655q103 -1 191.5 1.5t125.5 5.5l37 3q68 2 90.5 24.5t39.5 94.5l33 142h103l-14 -322l7 -319h-103l-29 127q-15 68 -45 93t-84 26q-87 8 -352 8v-556q0 -78 43.5 -115.5t133.5 -37.5h357q35 0 59.5 2t55 7.5t54 18t48.5 32t46 50.5t39 73l93 216h89 +q-6 -37 -31.5 -252t-30.5 -276q-146 5 -263.5 8t-162.5 4h-44h-628l-376 -12v102l127 25q67 13 91.5 37t25.5 79l8 643q3 402 -8 645q-2 61 -25.5 84t-91.5 36l-127 24v102l376 -12h702q139 0 374 27q-6 -68 -14 -194.5t-12 -219.5l-5 -92h-93l-32 124q-31 121 -74 179.5 +t-113 58.5h-548q-28 0 -35.5 -8.5t-7.5 -30.5z" /> + <glyph glyph-name="uniF2D8" unicode="&#xf2d8;" +d="M922 739v-182q0 -4 0.5 -15t0 -15l-1.5 -12t-3.5 -11.5t-6.5 -7.5t-11 -5.5t-16 -1.5v309q9 0 16 -1t11 -5t6.5 -5.5t3.5 -9.5t1 -10.5v-13.5v-14zM1238 643v-121q0 -1 0.5 -12.5t0 -15.5t-2.5 -11.5t-7.5 -10.5t-13.5 -3q-9 0 -14 9q-4 10 -4 165v7v8.5v9t1.5 8.5l3.5 7 +t5 5.5t8 1.5q6 0 10 -1.5t6.5 -4.5t4 -6t2 -8.5t0.5 -8v-9.5v-9zM180 407h122v472h-122v-472zM614 407h106v472h-159l-28 -221q-20 148 -32 221h-158v-472h107v312l45 -312h76l43 319v-319zM1039 712q0 67 -5 90q-3 16 -11 28.5t-17 20.5t-25 14t-26.5 8.5t-31 4t-29 1.5 +h-29.5h-12h-91v-472h56q169 -1 197 24.5t25 180.5q-1 62 -1 100zM1356 515v133q0 29 -2 45t-9.5 33.5t-24.5 25t-46 7.5q-46 0 -77 -34v154h-117v-472h110l7 30q30 -36 77 -36q50 0 66 30.5t16 83.5zM1536 1248v-1216q0 -66 -47 -113t-113 -47h-1216q-66 0 -113 47t-47 113 +v1216q0 66 47 113t113 47h1216q66 0 113 -47t47 -113z" /> + <glyph glyph-name="uniF2D9" unicode="&#xf2d9;" horiz-adv-x="2176" +d="M1143 -197q-6 1 -11 4q-13 8 -36 23t-86 65t-116.5 104.5t-112 140t-89.5 172.5q-17 3 -175 37q66 -213 235 -362t391 -184zM502 409l168 -28q-25 76 -41 167.5t-19 145.5l-4 53q-84 -82 -121 -224q5 -65 17 -114zM612 1018q-43 -64 -77 -148q44 46 74 68zM2049 584 +q0 161 -62 307t-167.5 252t-250.5 168.5t-304 62.5q-147 0 -281 -52.5t-240 -148.5q-30 -58 -45 -160q60 51 143 83.5t158.5 43t143 13.5t108.5 -1l40 -3q33 -1 53 -15.5t24.5 -33t6.5 -37t-1 -28.5q-126 11 -227.5 0.5t-183 -43.5t-142.5 -71.5t-131 -98.5 +q4 -36 11.5 -92.5t35.5 -178t62 -179.5q123 -6 247.5 14.5t214.5 53.5t162.5 67t109.5 59l37 24q22 16 39.5 20.5t30.5 -5t17 -34.5q14 -97 -39 -121q-208 -97 -467 -134q-135 -20 -317 -16q41 -96 110 -176.5t137 -127t130.5 -79t101.5 -43.5l39 -12q143 -23 263 15 +q195 99 314 289t119 418zM2123 621q-14 -135 -40 -212q-70 -208 -181.5 -346.5t-318.5 -253.5q-48 -33 -82 -44q-72 -26 -163 -16q-36 -3 -73 -3q-283 0 -504.5 173t-295.5 442q-1 0 -4 0.5t-5 0.5q-6 -50 2.5 -112.5t26 -115t36 -98t31.5 -71.5l14 -26q8 -12 54 -82 +q-71 38 -124.5 106.5t-78.5 140t-39.5 137t-17.5 107.5l-2 42q-5 2 -33.5 12.5t-48.5 18t-53 20.5t-57.5 25t-50 25.5t-42.5 27t-25 25.5q19 -10 50.5 -25.5t113 -45.5t145.5 -38l2 32q11 149 94 290q41 202 176 365q28 115 81 214q15 28 32 45t49 32q158 74 303.5 104 +t302 11t306.5 -97q220 -115 333 -336t87 -474z" /> + <glyph glyph-name="uniF2DA" unicode="&#xf2da;" horiz-adv-x="1792" +d="M1341 752q29 44 -6.5 129.5t-121.5 142.5q-58 39 -125.5 53.5t-118 4.5t-68.5 -37q-12 -23 -4.5 -28t42.5 -10q23 -3 38.5 -5t44.5 -9.5t56 -17.5q36 -13 67.5 -31.5t53 -37t40 -38.5t30.5 -38t22 -34.5t16.5 -28.5t12 -18.5t10.5 -6t11 9.5zM1704 178 +q-52 -127 -148.5 -220t-214.5 -141.5t-253 -60.5t-266 13.5t-251 91t-210 161.5t-141.5 235.5t-46.5 303.5q1 41 8.5 84.5t12.5 64t24 80.5t23 73q-51 -208 1 -397t173 -318t291 -206t346 -83t349 74.5t289 244.5q20 27 18 14q0 -4 -4 -14zM1465 627q0 -104 -40.5 -199 +t-108.5 -164t-162 -109.5t-198 -40.5t-198 40.5t-162 109.5t-108.5 164t-40.5 199t40.5 199t108.5 164t162 109.5t198 40.5t198 -40.5t162 -109.5t108.5 -164t40.5 -199zM1752 915q-65 147 -180.5 251t-253 153.5t-292 53.5t-301 -36.5t-275.5 -129t-220 -211.5t-131 -297 +t-10 -373q-49 161 -51.5 311.5t35.5 272.5t109 227t165.5 180.5t207 126t232 71t242.5 9t236 -54t216 -124.5t178 -197q33 -50 62 -121t31 -112zM1690 573q12 244 -136.5 416t-396.5 240q-8 0 -10 5t24 8q125 -4 230 -50t173 -120t116 -168.5t58.5 -199t-1 -208 +t-61.5 -197.5t-122.5 -167t-185 -117.5t-248.5 -46.5q108 30 201.5 80t174 123t129.5 176.5t55 225.5z" /> + <glyph glyph-name="uniF2DB" unicode="&#xf2db;" +d="M192 256v-128h-112q-16 0 -16 16v16h-48q-16 0 -16 16v32q0 16 16 16h48v16q0 16 16 16h112zM192 512v-128h-112q-16 0 -16 16v16h-48q-16 0 -16 16v32q0 16 16 16h48v16q0 16 16 16h112zM192 768v-128h-112q-16 0 -16 16v16h-48q-16 0 -16 16v32q0 16 16 16h48v16 +q0 16 16 16h112zM192 1024v-128h-112q-16 0 -16 16v16h-48q-16 0 -16 16v32q0 16 16 16h48v16q0 16 16 16h112zM192 1280v-128h-112q-16 0 -16 16v16h-48q-16 0 -16 16v32q0 16 16 16h48v16q0 16 16 16h112zM1280 1440v-1472q0 -40 -28 -68t-68 -28h-832q-40 0 -68 28 +t-28 68v1472q0 40 28 68t68 28h832q40 0 68 -28t28 -68zM1536 208v-32q0 -16 -16 -16h-48v-16q0 -16 -16 -16h-112v128h112q16 0 16 -16v-16h48q16 0 16 -16zM1536 464v-32q0 -16 -16 -16h-48v-16q0 -16 -16 -16h-112v128h112q16 0 16 -16v-16h48q16 0 16 -16zM1536 720v-32 +q0 -16 -16 -16h-48v-16q0 -16 -16 -16h-112v128h112q16 0 16 -16v-16h48q16 0 16 -16zM1536 976v-32q0 -16 -16 -16h-48v-16q0 -16 -16 -16h-112v128h112q16 0 16 -16v-16h48q16 0 16 -16zM1536 1232v-32q0 -16 -16 -16h-48v-16q0 -16 -16 -16h-112v128h112q16 0 16 -16v-16 +h48q16 0 16 -16z" /> + <glyph glyph-name="uniF2DC" unicode="&#xf2dc;" horiz-adv-x="1664" +d="M1566 419l-167 -33l186 -107q23 -13 29.5 -38.5t-6.5 -48.5q-14 -23 -39 -29.5t-48 6.5l-186 106l55 -160q13 -38 -12 -63.5t-60.5 -20.5t-48.5 42l-102 300l-271 156v-313l208 -238q16 -18 17 -39t-11 -36.5t-28.5 -25t-37 -5.5t-36.5 22l-112 128v-214q0 -26 -19 -45 +t-45 -19t-45 19t-19 45v214l-112 -128q-16 -18 -36.5 -22t-37 5.5t-28.5 25t-11 36.5t17 39l208 238v313l-271 -156l-102 -300q-13 -37 -48.5 -42t-60.5 20.5t-12 63.5l55 160l-186 -106q-23 -13 -48 -6.5t-39 29.5q-13 23 -6.5 48.5t29.5 38.5l186 107l-167 33 +q-29 6 -42 29t-8.5 46.5t25.5 40t50 10.5l310 -62l271 157l-271 157l-310 -62q-4 -1 -13 -1q-27 0 -44 18t-19 40t11 43t40 26l167 33l-186 107q-23 13 -29.5 38.5t6.5 48.5t39 30t48 -7l186 -106l-55 160q-13 38 12 63.5t60.5 20.5t48.5 -42l102 -300l271 -156v313 +l-208 238q-16 18 -17 39t11 36.5t28.5 25t37 5.5t36.5 -22l112 -128v214q0 26 19 45t45 19t45 -19t19 -45v-214l112 128q16 18 36.5 22t37 -5.5t28.5 -25t11 -36.5t-17 -39l-208 -238v-313l271 156l102 300q13 37 48.5 42t60.5 -20.5t12 -63.5l-55 -160l186 106 +q23 13 48 6.5t39 -29.5q13 -23 6.5 -48.5t-29.5 -38.5l-186 -107l167 -33q27 -5 40 -26t11 -43t-19 -40t-44 -18q-9 0 -13 1l-310 62l-271 -157l271 -157l310 62q29 6 50 -10.5t25.5 -40t-8.5 -46.5t-42 -29z" /> + <glyph glyph-name="uniF2DD" unicode="&#xf2dd;" horiz-adv-x="1792" +d="M1473 607q7 118 -33 226.5t-113 189t-177 131t-221 57.5q-116 7 -225.5 -32t-192 -110.5t-135 -175t-59.5 -220.5q-7 -118 33 -226.5t113 -189t177.5 -131t221.5 -57.5q155 -9 293 59t224 195.5t94 283.5zM1792 1536l-349 -348q120 -117 180.5 -272t50.5 -321 +q-11 -183 -102 -339t-241 -255.5t-332 -124.5l-999 -132l347 347q-120 116 -180.5 271.5t-50.5 321.5q11 184 102 340t241.5 255.5t332.5 124.5q167 22 500 66t500 66z" /> + <glyph glyph-name="uniF2DE" unicode="&#xf2de;" horiz-adv-x="1792" +d="M948 508l163 -329h-51l-175 350l-171 -350h-49l179 374l-78 33l21 49l240 -102l-21 -50zM563 1100l304 -130l-130 -304l-304 130zM907 915l240 -103l-103 -239l-239 102zM1188 765l191 -81l-82 -190l-190 81zM1680 640q0 159 -62 304t-167.5 250.5t-250.5 167.5t-304 62 +t-304 -62t-250.5 -167.5t-167.5 -250.5t-62 -304t62 -304t167.5 -250.5t250.5 -167.5t304 -62t304 62t250.5 167.5t167.5 250.5t62 304zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71 +t286 -191t191 -286t71 -348z" /> + <glyph glyph-name="uniF2E0" unicode="&#xf2e0;" horiz-adv-x="1920" +d="M1334 302q-4 24 -27.5 34t-49.5 10.5t-48.5 12.5t-25.5 38q-5 47 33 139.5t75 181t32 127.5q-14 101 -117 103q-45 1 -75 -16l-3 -2l-5 -2.5t-4.5 -2t-5 -2t-5 -0.5t-6 1.5t-6 3.5t-6.5 5q-3 2 -9 8.5t-9 9t-8.5 7.5t-9.5 7.5t-9.5 5.5t-11 4.5t-11.5 2.5q-30 5 -48 -3 +t-45 -31q-1 -1 -9 -8.5t-12.5 -11t-15 -10t-16.5 -5.5t-17 3q-54 27 -84 40q-41 18 -94 -5t-76 -65q-16 -28 -41 -98.5t-43.5 -132.5t-40 -134t-21.5 -73q-22 -69 18.5 -119t110.5 -46q30 2 50.5 15t38.5 46q7 13 79 199.5t77 194.5q6 11 21.5 18t29.5 0q27 -15 21 -53 +q-2 -18 -51 -139.5t-50 -132.5q-6 -38 19.5 -56.5t60.5 -7t55 49.5q4 8 45.5 92t81.5 163.5t46 88.5q20 29 41 28q29 0 25 -38q-2 -16 -65.5 -147.5t-70.5 -159.5q-12 -53 13 -103t74 -74q17 -9 51 -15.5t71.5 -8t62.5 14t20 48.5zM383 86q3 -15 -5 -27.5t-23 -15.5 +q-14 -3 -26.5 5t-15.5 23q-3 14 5 27t22 16t27 -5t16 -23zM953 -177q12 -17 8.5 -37.5t-20.5 -32.5t-37.5 -8t-32.5 21q-11 17 -7.5 37.5t20.5 32.5t37.5 8t31.5 -21zM177 635q-18 -27 -49.5 -33t-57.5 13q-26 18 -32 50t12 58q18 27 49.5 33t57.5 -12q26 -19 32 -50.5 +t-12 -58.5zM1467 -42q19 -28 13 -61.5t-34 -52.5t-60.5 -13t-51.5 34t-13 61t33 53q28 19 60.5 13t52.5 -34zM1579 562q69 -113 42.5 -244.5t-134.5 -207.5q-90 -63 -199 -60q-20 -80 -84.5 -127t-143.5 -44.5t-140 57.5q-12 -9 -13 -10q-103 -71 -225 -48.5t-193 126.5 +q-50 73 -53 164q-83 14 -142.5 70.5t-80.5 128t-2 152t81 138.5q-36 60 -38 128t24.5 125t79.5 98.5t121 50.5q32 85 99 148t146.5 91.5t168 17t159.5 -66.5q72 21 140 17.5t128.5 -36t104.5 -80t67.5 -115t17.5 -140.5q52 -16 87 -57t45.5 -89t-5.5 -99.5t-58 -87.5z +M455 1222q14 -20 9.5 -44.5t-24.5 -38.5q-19 -14 -43.5 -9.5t-37.5 24.5q-14 20 -9.5 44.5t24.5 38.5q19 14 43.5 9.5t37.5 -24.5zM614 1503q4 -16 -5 -30.5t-26 -18.5t-31 5.5t-18 26.5q-3 17 6.5 31t25.5 18q17 4 31 -5.5t17 -26.5zM1800 555q4 -20 -6.5 -37t-30.5 -21 +q-19 -4 -36 6.5t-21 30.5t6.5 37t30.5 22q20 4 36.5 -7.5t20.5 -30.5zM1136 1448q16 -27 8.5 -58.5t-35.5 -47.5q-27 -16 -57.5 -8.5t-46.5 34.5q-16 28 -8.5 59t34.5 48t58 9t47 -36zM1882 792q4 -15 -4 -27.5t-23 -16.5q-15 -3 -27.5 5.5t-15.5 22.5q-3 15 5 28t23 16 +q14 3 26.5 -5t15.5 -23zM1691 1033q15 -22 10.5 -49t-26.5 -43q-22 -15 -49 -10t-42 27t-10 49t27 43t48.5 11t41.5 -28z" /> + <glyph glyph-name="uniF2E1" unicode="&#xf2e1;" horiz-adv-x="1792" + /> + <glyph glyph-name="uniF2E2" unicode="&#xf2e2;" horiz-adv-x="1792" + /> + <glyph glyph-name="uniF2E3" unicode="&#xf2e3;" horiz-adv-x="1792" + /> + <glyph glyph-name="uniF2E4" unicode="&#xf2e4;" horiz-adv-x="1792" + /> + <glyph glyph-name="uniF2E5" unicode="&#xf2e5;" horiz-adv-x="1792" + /> + <glyph glyph-name="uniF2E6" unicode="&#xf2e6;" horiz-adv-x="1792" + /> + <glyph glyph-name="uniF2E7" unicode="&#xf2e7;" horiz-adv-x="1792" + /> + <glyph glyph-name="_698" unicode="&#xf2e8;" horiz-adv-x="1792" + /> + <glyph glyph-name="uniF2E9" unicode="&#xf2e9;" horiz-adv-x="1792" + /> + <glyph glyph-name="uniF2EA" unicode="&#xf2ea;" horiz-adv-x="1792" + /> + <glyph glyph-name="uniF2EB" unicode="&#xf2eb;" horiz-adv-x="1792" + /> + <glyph glyph-name="uniF2EC" unicode="&#xf2ec;" horiz-adv-x="1792" + /> + <glyph glyph-name="uniF2ED" unicode="&#xf2ed;" horiz-adv-x="1792" + /> + <glyph glyph-name="uniF2EE" unicode="&#xf2ee;" horiz-adv-x="1792" + /> + <glyph glyph-name="lessequal" unicode="&#xf500;" horiz-adv-x="1792" + /> + </font> +</defs></svg> diff --git a/views/default/fonts/fontawesome-webfont.ttf b/views/default/fonts/fontawesome-webfont.ttf new file mode 100644 index 0000000..35acda2 Binary files /dev/null and b/views/default/fonts/fontawesome-webfont.ttf differ diff --git a/views/default/fonts/fontawesome-webfont.woff b/views/default/fonts/fontawesome-webfont.woff new file mode 100644 index 0000000..400014a Binary files /dev/null and b/views/default/fonts/fontawesome-webfont.woff differ diff --git a/views/default/fonts/fontawesome-webfont.woff2 b/views/default/fonts/fontawesome-webfont.woff2 new file mode 100644 index 0000000..4d13fc6 Binary files /dev/null and b/views/default/fonts/fontawesome-webfont.woff2 differ diff --git a/views/default/fonts/glyphicons-halflings-regular.eot b/views/default/fonts/glyphicons-halflings-regular.eot new file mode 100644 index 0000000..b93a495 Binary files /dev/null and b/views/default/fonts/glyphicons-halflings-regular.eot differ diff --git a/views/default/fonts/glyphicons-halflings-regular.svg b/views/default/fonts/glyphicons-halflings-regular.svg new file mode 100644 index 0000000..94fb549 --- /dev/null +++ b/views/default/fonts/glyphicons-halflings-regular.svg @@ -0,0 +1,288 @@ +<?xml version="1.0" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" > +<svg xmlns="http://www.w3.org/2000/svg"> +<metadata></metadata> +<defs> +<font id="glyphicons_halflingsregular" horiz-adv-x="1200" > +<font-face units-per-em="1200" ascent="960" descent="-240" /> +<missing-glyph horiz-adv-x="500" /> +<glyph horiz-adv-x="0" /> +<glyph horiz-adv-x="400" /> +<glyph unicode=" " /> +<glyph unicode="*" d="M600 1100q15 0 34 -1.5t30 -3.5l11 -1q10 -2 17.5 -10.5t7.5 -18.5v-224l158 158q7 7 18 8t19 -6l106 -106q7 -8 6 -19t-8 -18l-158 -158h224q10 0 18.5 -7.5t10.5 -17.5q6 -41 6 -75q0 -15 -1.5 -34t-3.5 -30l-1 -11q-2 -10 -10.5 -17.5t-18.5 -7.5h-224l158 -158 q7 -7 8 -18t-6 -19l-106 -106q-8 -7 -19 -6t-18 8l-158 158v-224q0 -10 -7.5 -18.5t-17.5 -10.5q-41 -6 -75 -6q-15 0 -34 1.5t-30 3.5l-11 1q-10 2 -17.5 10.5t-7.5 18.5v224l-158 -158q-7 -7 -18 -8t-19 6l-106 106q-7 8 -6 19t8 18l158 158h-224q-10 0 -18.5 7.5 t-10.5 17.5q-6 41 -6 75q0 15 1.5 34t3.5 30l1 11q2 10 10.5 17.5t18.5 7.5h224l-158 158q-7 7 -8 18t6 19l106 106q8 7 19 6t18 -8l158 -158v224q0 10 7.5 18.5t17.5 10.5q41 6 75 6z" /> +<glyph unicode="+" d="M450 1100h200q21 0 35.5 -14.5t14.5 -35.5v-350h350q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-350v-350q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v350h-350q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5 h350v350q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xa0;" /> +<glyph unicode="&#xa5;" d="M825 1100h250q10 0 12.5 -5t-5.5 -13l-364 -364q-6 -6 -11 -18h268q10 0 13 -6t-3 -14l-120 -160q-6 -8 -18 -14t-22 -6h-125v-100h275q10 0 13 -6t-3 -14l-120 -160q-6 -8 -18 -14t-22 -6h-125v-174q0 -11 -7.5 -18.5t-18.5 -7.5h-148q-11 0 -18.5 7.5t-7.5 18.5v174 h-275q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h125v100h-275q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h118q-5 12 -11 18l-364 364q-8 8 -5.5 13t12.5 5h250q25 0 43 -18l164 -164q8 -8 18 -8t18 8l164 164q18 18 43 18z" /> +<glyph unicode="&#x2000;" horiz-adv-x="650" /> +<glyph unicode="&#x2001;" horiz-adv-x="1300" /> +<glyph unicode="&#x2002;" horiz-adv-x="650" /> +<glyph unicode="&#x2003;" horiz-adv-x="1300" /> +<glyph unicode="&#x2004;" horiz-adv-x="433" /> +<glyph unicode="&#x2005;" horiz-adv-x="325" /> +<glyph unicode="&#x2006;" horiz-adv-x="216" /> +<glyph unicode="&#x2007;" horiz-adv-x="216" /> +<glyph unicode="&#x2008;" horiz-adv-x="162" /> +<glyph unicode="&#x2009;" horiz-adv-x="260" /> +<glyph unicode="&#x200a;" horiz-adv-x="72" /> +<glyph unicode="&#x202f;" horiz-adv-x="260" /> +<glyph unicode="&#x205f;" horiz-adv-x="325" /> +<glyph unicode="&#x20ac;" d="M744 1198q242 0 354 -189q60 -104 66 -209h-181q0 45 -17.5 82.5t-43.5 61.5t-58 40.5t-60.5 24t-51.5 7.5q-19 0 -40.5 -5.5t-49.5 -20.5t-53 -38t-49 -62.5t-39 -89.5h379l-100 -100h-300q-6 -50 -6 -100h406l-100 -100h-300q9 -74 33 -132t52.5 -91t61.5 -54.5t59 -29 t47 -7.5q22 0 50.5 7.5t60.5 24.5t58 41t43.5 61t17.5 80h174q-30 -171 -128 -278q-107 -117 -274 -117q-206 0 -324 158q-36 48 -69 133t-45 204h-217l100 100h112q1 47 6 100h-218l100 100h134q20 87 51 153.5t62 103.5q117 141 297 141z" /> +<glyph unicode="&#x20bd;" d="M428 1200h350q67 0 120 -13t86 -31t57 -49.5t35 -56.5t17 -64.5t6.5 -60.5t0.5 -57v-16.5v-16.5q0 -36 -0.5 -57t-6.5 -61t-17 -65t-35 -57t-57 -50.5t-86 -31.5t-120 -13h-178l-2 -100h288q10 0 13 -6t-3 -14l-120 -160q-6 -8 -18 -14t-22 -6h-138v-175q0 -11 -5.5 -18 t-15.5 -7h-149q-10 0 -17.5 7.5t-7.5 17.5v175h-267q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h117v100h-267q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h117v475q0 10 7.5 17.5t17.5 7.5zM600 1000v-300h203q64 0 86.5 33t22.5 119q0 84 -22.5 116t-86.5 32h-203z" /> +<glyph unicode="&#x2212;" d="M250 700h800q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#x231b;" d="M1000 1200v-150q0 -21 -14.5 -35.5t-35.5 -14.5h-50v-100q0 -91 -49.5 -165.5t-130.5 -109.5q81 -35 130.5 -109.5t49.5 -165.5v-150h50q21 0 35.5 -14.5t14.5 -35.5v-150h-800v150q0 21 14.5 35.5t35.5 14.5h50v150q0 91 49.5 165.5t130.5 109.5q-81 35 -130.5 109.5 t-49.5 165.5v100h-50q-21 0 -35.5 14.5t-14.5 35.5v150h800zM400 1000v-100q0 -60 32.5 -109.5t87.5 -73.5q28 -12 44 -37t16 -55t-16 -55t-44 -37q-55 -24 -87.5 -73.5t-32.5 -109.5v-150h400v150q0 60 -32.5 109.5t-87.5 73.5q-28 12 -44 37t-16 55t16 55t44 37 q55 24 87.5 73.5t32.5 109.5v100h-400z" /> +<glyph unicode="&#x25fc;" horiz-adv-x="500" d="M0 0z" /> +<glyph unicode="&#x2601;" d="M503 1089q110 0 200.5 -59.5t134.5 -156.5q44 14 90 14q120 0 205 -86.5t85 -206.5q0 -121 -85 -207.5t-205 -86.5h-750q-79 0 -135.5 57t-56.5 137q0 69 42.5 122.5t108.5 67.5q-2 12 -2 37q0 153 108 260.5t260 107.5z" /> +<glyph unicode="&#x26fa;" d="M774 1193.5q16 -9.5 20.5 -27t-5.5 -33.5l-136 -187l467 -746h30q20 0 35 -18.5t15 -39.5v-42h-1200v42q0 21 15 39.5t35 18.5h30l468 746l-135 183q-10 16 -5.5 34t20.5 28t34 5.5t28 -20.5l111 -148l112 150q9 16 27 20.5t34 -5zM600 200h377l-182 112l-195 534v-646z " /> +<glyph unicode="&#x2709;" d="M25 1100h1150q10 0 12.5 -5t-5.5 -13l-564 -567q-8 -8 -18 -8t-18 8l-564 567q-8 8 -5.5 13t12.5 5zM18 882l264 -264q8 -8 8 -18t-8 -18l-264 -264q-8 -8 -13 -5.5t-5 12.5v550q0 10 5 12.5t13 -5.5zM918 618l264 264q8 8 13 5.5t5 -12.5v-550q0 -10 -5 -12.5t-13 5.5 l-264 264q-8 8 -8 18t8 18zM818 482l364 -364q8 -8 5.5 -13t-12.5 -5h-1150q-10 0 -12.5 5t5.5 13l364 364q8 8 18 8t18 -8l164 -164q8 -8 18 -8t18 8l164 164q8 8 18 8t18 -8z" /> +<glyph unicode="&#x270f;" d="M1011 1210q19 0 33 -13l153 -153q13 -14 13 -33t-13 -33l-99 -92l-214 214l95 96q13 14 32 14zM1013 800l-615 -614l-214 214l614 614zM317 96l-333 -112l110 335z" /> +<glyph unicode="&#xe001;" d="M700 650v-550h250q21 0 35.5 -14.5t14.5 -35.5v-50h-800v50q0 21 14.5 35.5t35.5 14.5h250v550l-500 550h1200z" /> +<glyph unicode="&#xe002;" d="M368 1017l645 163q39 15 63 0t24 -49v-831q0 -55 -41.5 -95.5t-111.5 -63.5q-79 -25 -147 -4.5t-86 75t25.5 111.5t122.5 82q72 24 138 8v521l-600 -155v-606q0 -42 -44 -90t-109 -69q-79 -26 -147 -5.5t-86 75.5t25.5 111.5t122.5 82.5q72 24 138 7v639q0 38 14.5 59 t53.5 34z" /> +<glyph unicode="&#xe003;" d="M500 1191q100 0 191 -39t156.5 -104.5t104.5 -156.5t39 -191l-1 -2l1 -5q0 -141 -78 -262l275 -274q23 -26 22.5 -44.5t-22.5 -42.5l-59 -58q-26 -20 -46.5 -20t-39.5 20l-275 274q-119 -77 -261 -77l-5 1l-2 -1q-100 0 -191 39t-156.5 104.5t-104.5 156.5t-39 191 t39 191t104.5 156.5t156.5 104.5t191 39zM500 1022q-88 0 -162 -43t-117 -117t-43 -162t43 -162t117 -117t162 -43t162 43t117 117t43 162t-43 162t-117 117t-162 43z" /> +<glyph unicode="&#xe005;" d="M649 949q48 68 109.5 104t121.5 38.5t118.5 -20t102.5 -64t71 -100.5t27 -123q0 -57 -33.5 -117.5t-94 -124.5t-126.5 -127.5t-150 -152.5t-146 -174q-62 85 -145.5 174t-150 152.5t-126.5 127.5t-93.5 124.5t-33.5 117.5q0 64 28 123t73 100.5t104 64t119 20 t120.5 -38.5t104.5 -104z" /> +<glyph unicode="&#xe006;" d="M407 800l131 353q7 19 17.5 19t17.5 -19l129 -353h421q21 0 24 -8.5t-14 -20.5l-342 -249l130 -401q7 -20 -0.5 -25.5t-24.5 6.5l-343 246l-342 -247q-17 -12 -24.5 -6.5t-0.5 25.5l130 400l-347 251q-17 12 -14 20.5t23 8.5h429z" /> +<glyph unicode="&#xe007;" d="M407 800l131 353q7 19 17.5 19t17.5 -19l129 -353h421q21 0 24 -8.5t-14 -20.5l-342 -249l130 -401q7 -20 -0.5 -25.5t-24.5 6.5l-343 246l-342 -247q-17 -12 -24.5 -6.5t-0.5 25.5l130 400l-347 251q-17 12 -14 20.5t23 8.5h429zM477 700h-240l197 -142l-74 -226 l193 139l195 -140l-74 229l192 140h-234l-78 211z" /> +<glyph unicode="&#xe008;" d="M600 1200q124 0 212 -88t88 -212v-250q0 -46 -31 -98t-69 -52v-75q0 -10 6 -21.5t15 -17.5l358 -230q9 -5 15 -16.5t6 -21.5v-93q0 -10 -7.5 -17.5t-17.5 -7.5h-1150q-10 0 -17.5 7.5t-7.5 17.5v93q0 10 6 21.5t15 16.5l358 230q9 6 15 17.5t6 21.5v75q-38 0 -69 52 t-31 98v250q0 124 88 212t212 88z" /> +<glyph unicode="&#xe009;" d="M25 1100h1150q10 0 17.5 -7.5t7.5 -17.5v-1050q0 -10 -7.5 -17.5t-17.5 -7.5h-1150q-10 0 -17.5 7.5t-7.5 17.5v1050q0 10 7.5 17.5t17.5 7.5zM100 1000v-100h100v100h-100zM875 1000h-550q-10 0 -17.5 -7.5t-7.5 -17.5v-350q0 -10 7.5 -17.5t17.5 -7.5h550 q10 0 17.5 7.5t7.5 17.5v350q0 10 -7.5 17.5t-17.5 7.5zM1000 1000v-100h100v100h-100zM100 800v-100h100v100h-100zM1000 800v-100h100v100h-100zM100 600v-100h100v100h-100zM1000 600v-100h100v100h-100zM875 500h-550q-10 0 -17.5 -7.5t-7.5 -17.5v-350q0 -10 7.5 -17.5 t17.5 -7.5h550q10 0 17.5 7.5t7.5 17.5v350q0 10 -7.5 17.5t-17.5 7.5zM100 400v-100h100v100h-100zM1000 400v-100h100v100h-100zM100 200v-100h100v100h-100zM1000 200v-100h100v100h-100z" /> +<glyph unicode="&#xe010;" d="M50 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM650 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400 q0 21 14.5 35.5t35.5 14.5zM50 500h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM650 500h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe011;" d="M50 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200 q0 21 14.5 35.5t35.5 14.5zM850 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM50 700h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200 q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 700h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM850 700h200q21 0 35.5 -14.5t14.5 -35.5v-200 q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM50 300h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 300h200 q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM850 300h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5 t35.5 14.5z" /> +<glyph unicode="&#xe012;" d="M50 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 1100h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v200 q0 21 14.5 35.5t35.5 14.5zM50 700h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 700h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700 q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM50 300h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 300h700q21 0 35.5 -14.5t14.5 -35.5v-200 q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe013;" d="M465 477l571 571q8 8 18 8t17 -8l177 -177q8 -7 8 -17t-8 -18l-783 -784q-7 -8 -17.5 -8t-17.5 8l-384 384q-8 8 -8 18t8 17l177 177q7 8 17 8t18 -8l171 -171q7 -7 18 -7t18 7z" /> +<glyph unicode="&#xe014;" d="M904 1083l178 -179q8 -8 8 -18.5t-8 -17.5l-267 -268l267 -268q8 -7 8 -17.5t-8 -18.5l-178 -178q-8 -8 -18.5 -8t-17.5 8l-268 267l-268 -267q-7 -8 -17.5 -8t-18.5 8l-178 178q-8 8 -8 18.5t8 17.5l267 268l-267 268q-8 7 -8 17.5t8 18.5l178 178q8 8 18.5 8t17.5 -8 l268 -267l268 268q7 7 17.5 7t18.5 -7z" /> +<glyph unicode="&#xe015;" d="M507 1177q98 0 187.5 -38.5t154.5 -103.5t103.5 -154.5t38.5 -187.5q0 -141 -78 -262l300 -299q8 -8 8 -18.5t-8 -18.5l-109 -108q-7 -8 -17.5 -8t-18.5 8l-300 299q-119 -77 -261 -77q-98 0 -188 38.5t-154.5 103t-103 154.5t-38.5 188t38.5 187.5t103 154.5 t154.5 103.5t188 38.5zM506.5 1023q-89.5 0 -165.5 -44t-120 -120.5t-44 -166t44 -165.5t120 -120t165.5 -44t166 44t120.5 120t44 165.5t-44 166t-120.5 120.5t-166 44zM425 900h150q10 0 17.5 -7.5t7.5 -17.5v-75h75q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5 t-17.5 -7.5h-75v-75q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v75h-75q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h75v75q0 10 7.5 17.5t17.5 7.5z" /> +<glyph unicode="&#xe016;" d="M507 1177q98 0 187.5 -38.5t154.5 -103.5t103.5 -154.5t38.5 -187.5q0 -141 -78 -262l300 -299q8 -8 8 -18.5t-8 -18.5l-109 -108q-7 -8 -17.5 -8t-18.5 8l-300 299q-119 -77 -261 -77q-98 0 -188 38.5t-154.5 103t-103 154.5t-38.5 188t38.5 187.5t103 154.5 t154.5 103.5t188 38.5zM506.5 1023q-89.5 0 -165.5 -44t-120 -120.5t-44 -166t44 -165.5t120 -120t165.5 -44t166 44t120.5 120t44 165.5t-44 166t-120.5 120.5t-166 44zM325 800h350q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-350q-10 0 -17.5 7.5 t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5z" /> +<glyph unicode="&#xe017;" d="M550 1200h100q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM800 975v166q167 -62 272 -209.5t105 -331.5q0 -117 -45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5 t-184.5 123t-123 184.5t-45.5 224q0 184 105 331.5t272 209.5v-166q-103 -55 -165 -155t-62 -220q0 -116 57 -214.5t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5q0 120 -62 220t-165 155z" /> +<glyph unicode="&#xe018;" d="M1025 1200h150q10 0 17.5 -7.5t7.5 -17.5v-1150q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v1150q0 10 7.5 17.5t17.5 7.5zM725 800h150q10 0 17.5 -7.5t7.5 -17.5v-750q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v750 q0 10 7.5 17.5t17.5 7.5zM425 500h150q10 0 17.5 -7.5t7.5 -17.5v-450q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v450q0 10 7.5 17.5t17.5 7.5zM125 300h150q10 0 17.5 -7.5t7.5 -17.5v-250q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5 v250q0 10 7.5 17.5t17.5 7.5z" /> +<glyph unicode="&#xe019;" d="M600 1174q33 0 74 -5l38 -152l5 -1q49 -14 94 -39l5 -2l134 80q61 -48 104 -105l-80 -134l3 -5q25 -44 39 -93l1 -6l152 -38q5 -43 5 -73q0 -34 -5 -74l-152 -38l-1 -6q-15 -49 -39 -93l-3 -5l80 -134q-48 -61 -104 -105l-134 81l-5 -3q-44 -25 -94 -39l-5 -2l-38 -151 q-43 -5 -74 -5q-33 0 -74 5l-38 151l-5 2q-49 14 -94 39l-5 3l-134 -81q-60 48 -104 105l80 134l-3 5q-25 45 -38 93l-2 6l-151 38q-6 42 -6 74q0 33 6 73l151 38l2 6q13 48 38 93l3 5l-80 134q47 61 105 105l133 -80l5 2q45 25 94 39l5 1l38 152q43 5 74 5zM600 815 q-89 0 -152 -63t-63 -151.5t63 -151.5t152 -63t152 63t63 151.5t-63 151.5t-152 63z" /> +<glyph unicode="&#xe020;" d="M500 1300h300q41 0 70.5 -29.5t29.5 -70.5v-100h275q10 0 17.5 -7.5t7.5 -17.5v-75h-1100v75q0 10 7.5 17.5t17.5 7.5h275v100q0 41 29.5 70.5t70.5 29.5zM500 1200v-100h300v100h-300zM1100 900v-800q0 -41 -29.5 -70.5t-70.5 -29.5h-700q-41 0 -70.5 29.5t-29.5 70.5 v800h900zM300 800v-700h100v700h-100zM500 800v-700h100v700h-100zM700 800v-700h100v700h-100zM900 800v-700h100v700h-100z" /> +<glyph unicode="&#xe021;" d="M18 618l620 608q8 7 18.5 7t17.5 -7l608 -608q8 -8 5.5 -13t-12.5 -5h-175v-575q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v375h-300v-375q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v575h-175q-10 0 -12.5 5t5.5 13z" /> +<glyph unicode="&#xe022;" d="M600 1200v-400q0 -41 29.5 -70.5t70.5 -29.5h300v-650q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v1100q0 21 14.5 35.5t35.5 14.5h450zM1000 800h-250q-21 0 -35.5 14.5t-14.5 35.5v250z" /> +<glyph unicode="&#xe023;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM525 900h50q10 0 17.5 -7.5t7.5 -17.5v-275h175q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5z" /> +<glyph unicode="&#xe024;" d="M1300 0h-538l-41 400h-242l-41 -400h-538l431 1200h209l-21 -300h162l-20 300h208zM515 800l-27 -300h224l-27 300h-170z" /> +<glyph unicode="&#xe025;" d="M550 1200h200q21 0 35.5 -14.5t14.5 -35.5v-450h191q20 0 25.5 -11.5t-7.5 -27.5l-327 -400q-13 -16 -32 -16t-32 16l-327 400q-13 16 -7.5 27.5t25.5 11.5h191v450q0 21 14.5 35.5t35.5 14.5zM1125 400h50q10 0 17.5 -7.5t7.5 -17.5v-350q0 -10 -7.5 -17.5t-17.5 -7.5 h-1050q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h50q10 0 17.5 -7.5t7.5 -17.5v-175h900v175q0 10 7.5 17.5t17.5 7.5z" /> +<glyph unicode="&#xe026;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM525 900h150q10 0 17.5 -7.5t7.5 -17.5v-275h137q21 0 26 -11.5t-8 -27.5l-223 -275q-13 -16 -32 -16t-32 16l-223 275q-13 16 -8 27.5t26 11.5h137v275q0 10 7.5 17.5t17.5 7.5z " /> +<glyph unicode="&#xe027;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM632 914l223 -275q13 -16 8 -27.5t-26 -11.5h-137v-275q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v275h-137q-21 0 -26 11.5t8 27.5l223 275q13 16 32 16 t32 -16z" /> +<glyph unicode="&#xe028;" d="M225 1200h750q10 0 19.5 -7t12.5 -17l186 -652q7 -24 7 -49v-425q0 -12 -4 -27t-9 -17q-12 -6 -37 -6h-1100q-12 0 -27 4t-17 8q-6 13 -6 38l1 425q0 25 7 49l185 652q3 10 12.5 17t19.5 7zM878 1000h-556q-10 0 -19 -7t-11 -18l-87 -450q-2 -11 4 -18t16 -7h150 q10 0 19.5 -7t11.5 -17l38 -152q2 -10 11.5 -17t19.5 -7h250q10 0 19.5 7t11.5 17l38 152q2 10 11.5 17t19.5 7h150q10 0 16 7t4 18l-87 450q-2 11 -11 18t-19 7z" /> +<glyph unicode="&#xe029;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM540 820l253 -190q17 -12 17 -30t-17 -30l-253 -190q-16 -12 -28 -6.5t-12 26.5v400q0 21 12 26.5t28 -6.5z" /> +<glyph unicode="&#xe030;" d="M947 1060l135 135q7 7 12.5 5t5.5 -13v-362q0 -10 -7.5 -17.5t-17.5 -7.5h-362q-11 0 -13 5.5t5 12.5l133 133q-109 76 -238 76q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5h150q0 -117 -45.5 -224 t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5q192 0 347 -117z" /> +<glyph unicode="&#xe031;" d="M947 1060l135 135q7 7 12.5 5t5.5 -13v-361q0 -11 -7.5 -18.5t-18.5 -7.5h-361q-11 0 -13 5.5t5 12.5l134 134q-110 75 -239 75q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5h-150q0 117 45.5 224t123 184.5t184.5 123t224 45.5q192 0 347 -117zM1027 600h150 q0 -117 -45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5q-192 0 -348 118l-134 -134q-7 -8 -12.5 -5.5t-5.5 12.5v360q0 11 7.5 18.5t18.5 7.5h360q10 0 12.5 -5.5t-5.5 -12.5l-133 -133q110 -76 240 -76q116 0 214.5 57t155.5 155.5t57 214.5z" /> +<glyph unicode="&#xe032;" d="M125 1200h1050q10 0 17.5 -7.5t7.5 -17.5v-1150q0 -10 -7.5 -17.5t-17.5 -7.5h-1050q-10 0 -17.5 7.5t-7.5 17.5v1150q0 10 7.5 17.5t17.5 7.5zM1075 1000h-850q-10 0 -17.5 -7.5t-7.5 -17.5v-850q0 -10 7.5 -17.5t17.5 -7.5h850q10 0 17.5 7.5t7.5 17.5v850 q0 10 -7.5 17.5t-17.5 7.5zM325 900h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 900h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5zM325 700h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 700h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5zM325 500h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 500h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5zM325 300h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 300h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5z" /> +<glyph unicode="&#xe033;" d="M900 800v200q0 83 -58.5 141.5t-141.5 58.5h-300q-82 0 -141 -59t-59 -141v-200h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-600q0 -41 29.5 -70.5t70.5 -29.5h900q41 0 70.5 29.5t29.5 70.5v600q0 41 -29.5 70.5t-70.5 29.5h-100zM400 800v150q0 21 15 35.5t35 14.5h200 q20 0 35 -14.5t15 -35.5v-150h-300z" /> +<glyph unicode="&#xe034;" d="M125 1100h50q10 0 17.5 -7.5t7.5 -17.5v-1075h-100v1075q0 10 7.5 17.5t17.5 7.5zM1075 1052q4 0 9 -2q16 -6 16 -23v-421q0 -6 -3 -12q-33 -59 -66.5 -99t-65.5 -58t-56.5 -24.5t-52.5 -6.5q-26 0 -57.5 6.5t-52.5 13.5t-60 21q-41 15 -63 22.5t-57.5 15t-65.5 7.5 q-85 0 -160 -57q-7 -5 -15 -5q-6 0 -11 3q-14 7 -14 22v438q22 55 82 98.5t119 46.5q23 2 43 0.5t43 -7t32.5 -8.5t38 -13t32.5 -11q41 -14 63.5 -21t57 -14t63.5 -7q103 0 183 87q7 8 18 8z" /> +<glyph unicode="&#xe035;" d="M600 1175q116 0 227 -49.5t192.5 -131t131 -192.5t49.5 -227v-300q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v300q0 127 -70.5 231.5t-184.5 161.5t-245 57t-245 -57t-184.5 -161.5t-70.5 -231.5v-300q0 -10 -7.5 -17.5t-17.5 -7.5h-50 q-10 0 -17.5 7.5t-7.5 17.5v300q0 116 49.5 227t131 192.5t192.5 131t227 49.5zM220 500h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14v460q0 8 6 14t14 6zM820 500h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14v460 q0 8 6 14t14 6z" /> +<glyph unicode="&#xe036;" d="M321 814l258 172q9 6 15 2.5t6 -13.5v-750q0 -10 -6 -13.5t-15 2.5l-258 172q-21 14 -46 14h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h250q25 0 46 14zM900 668l120 120q7 7 17 7t17 -7l34 -34q7 -7 7 -17t-7 -17l-120 -120l120 -120q7 -7 7 -17 t-7 -17l-34 -34q-7 -7 -17 -7t-17 7l-120 119l-120 -119q-7 -7 -17 -7t-17 7l-34 34q-7 7 -7 17t7 17l119 120l-119 120q-7 7 -7 17t7 17l34 34q7 8 17 8t17 -8z" /> +<glyph unicode="&#xe037;" d="M321 814l258 172q9 6 15 2.5t6 -13.5v-750q0 -10 -6 -13.5t-15 2.5l-258 172q-21 14 -46 14h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h250q25 0 46 14zM766 900h4q10 -1 16 -10q96 -129 96 -290q0 -154 -90 -281q-6 -9 -17 -10l-3 -1q-9 0 -16 6 l-29 23q-7 7 -8.5 16.5t4.5 17.5q72 103 72 229q0 132 -78 238q-6 8 -4.5 18t9.5 17l29 22q7 5 15 5z" /> +<glyph unicode="&#xe038;" d="M967 1004h3q11 -1 17 -10q135 -179 135 -396q0 -105 -34 -206.5t-98 -185.5q-7 -9 -17 -10h-3q-9 0 -16 6l-42 34q-8 6 -9 16t5 18q111 150 111 328q0 90 -29.5 176t-84.5 157q-6 9 -5 19t10 16l42 33q7 5 15 5zM321 814l258 172q9 6 15 2.5t6 -13.5v-750q0 -10 -6 -13.5 t-15 2.5l-258 172q-21 14 -46 14h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h250q25 0 46 14zM766 900h4q10 -1 16 -10q96 -129 96 -290q0 -154 -90 -281q-6 -9 -17 -10l-3 -1q-9 0 -16 6l-29 23q-7 7 -8.5 16.5t4.5 17.5q72 103 72 229q0 132 -78 238 q-6 8 -4.5 18.5t9.5 16.5l29 22q7 5 15 5z" /> +<glyph unicode="&#xe039;" d="M500 900h100v-100h-100v-100h-400v-100h-100v600h500v-300zM1200 700h-200v-100h200v-200h-300v300h-200v300h-100v200h600v-500zM100 1100v-300h300v300h-300zM800 1100v-300h300v300h-300zM300 900h-100v100h100v-100zM1000 900h-100v100h100v-100zM300 500h200v-500 h-500v500h200v100h100v-100zM800 300h200v-100h-100v-100h-200v100h-100v100h100v200h-200v100h300v-300zM100 400v-300h300v300h-300zM300 200h-100v100h100v-100zM1200 200h-100v100h100v-100zM700 0h-100v100h100v-100zM1200 0h-300v100h300v-100z" /> +<glyph unicode="&#xe040;" d="M100 200h-100v1000h100v-1000zM300 200h-100v1000h100v-1000zM700 200h-200v1000h200v-1000zM900 200h-100v1000h100v-1000zM1200 200h-200v1000h200v-1000zM400 0h-300v100h300v-100zM600 0h-100v91h100v-91zM800 0h-100v91h100v-91zM1100 0h-200v91h200v-91z" /> +<glyph unicode="&#xe041;" d="M500 1200l682 -682q8 -8 8 -18t-8 -18l-464 -464q-8 -8 -18 -8t-18 8l-682 682l1 475q0 10 7.5 17.5t17.5 7.5h474zM319.5 1024.5q-29.5 29.5 -71 29.5t-71 -29.5t-29.5 -71.5t29.5 -71.5t71 -29.5t71 29.5t29.5 71.5t-29.5 71.5z" /> +<glyph unicode="&#xe042;" d="M500 1200l682 -682q8 -8 8 -18t-8 -18l-464 -464q-8 -8 -18 -8t-18 8l-682 682l1 475q0 10 7.5 17.5t17.5 7.5h474zM800 1200l682 -682q8 -8 8 -18t-8 -18l-464 -464q-8 -8 -18 -8t-18 8l-56 56l424 426l-700 700h150zM319.5 1024.5q-29.5 29.5 -71 29.5t-71 -29.5 t-29.5 -71.5t29.5 -71.5t71 -29.5t71 29.5t29.5 71.5t-29.5 71.5z" /> +<glyph unicode="&#xe043;" d="M300 1200h825q75 0 75 -75v-900q0 -25 -18 -43l-64 -64q-8 -8 -13 -5.5t-5 12.5v950q0 10 -7.5 17.5t-17.5 7.5h-700q-25 0 -43 -18l-64 -64q-8 -8 -5.5 -13t12.5 -5h700q10 0 17.5 -7.5t7.5 -17.5v-950q0 -10 -7.5 -17.5t-17.5 -7.5h-850q-10 0 -17.5 7.5t-7.5 17.5v975 q0 25 18 43l139 139q18 18 43 18z" /> +<glyph unicode="&#xe044;" d="M250 1200h800q21 0 35.5 -14.5t14.5 -35.5v-1150l-450 444l-450 -445v1151q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe045;" d="M822 1200h-444q-11 0 -19 -7.5t-9 -17.5l-78 -301q-7 -24 7 -45l57 -108q6 -9 17.5 -15t21.5 -6h450q10 0 21.5 6t17.5 15l62 108q14 21 7 45l-83 301q-1 10 -9 17.5t-19 7.5zM1175 800h-150q-10 0 -21 -6.5t-15 -15.5l-78 -156q-4 -9 -15 -15.5t-21 -6.5h-550 q-10 0 -21 6.5t-15 15.5l-78 156q-4 9 -15 15.5t-21 6.5h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-650q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h750q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5 t7.5 17.5v650q0 10 -7.5 17.5t-17.5 7.5zM850 200h-500q-10 0 -19.5 -7t-11.5 -17l-38 -152q-2 -10 3.5 -17t15.5 -7h600q10 0 15.5 7t3.5 17l-38 152q-2 10 -11.5 17t-19.5 7z" /> +<glyph unicode="&#xe046;" d="M500 1100h200q56 0 102.5 -20.5t72.5 -50t44 -59t25 -50.5l6 -20h150q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5v600q0 41 29.5 70.5t70.5 29.5h150q2 8 6.5 21.5t24 48t45 61t72 48t102.5 21.5zM900 800v-100 h100v100h-100zM600 730q-95 0 -162.5 -67.5t-67.5 -162.5t67.5 -162.5t162.5 -67.5t162.5 67.5t67.5 162.5t-67.5 162.5t-162.5 67.5zM600 603q43 0 73 -30t30 -73t-30 -73t-73 -30t-73 30t-30 73t30 73t73 30z" /> +<glyph unicode="&#xe047;" d="M681 1199l385 -998q20 -50 60 -92q18 -19 36.5 -29.5t27.5 -11.5l10 -2v-66h-417v66q53 0 75 43.5t5 88.5l-82 222h-391q-58 -145 -92 -234q-11 -34 -6.5 -57t25.5 -37t46 -20t55 -6v-66h-365v66q56 24 84 52q12 12 25 30.5t20 31.5l7 13l399 1006h93zM416 521h340 l-162 457z" /> +<glyph unicode="&#xe048;" d="M753 641q5 -1 14.5 -4.5t36 -15.5t50.5 -26.5t53.5 -40t50.5 -54.5t35.5 -70t14.5 -87q0 -67 -27.5 -125.5t-71.5 -97.5t-98.5 -66.5t-108.5 -40.5t-102 -13h-500v89q41 7 70.5 32.5t29.5 65.5v827q0 24 -0.5 34t-3.5 24t-8.5 19.5t-17 13.5t-28 12.5t-42.5 11.5v71 l471 -1q57 0 115.5 -20.5t108 -57t80.5 -94t31 -124.5q0 -51 -15.5 -96.5t-38 -74.5t-45 -50.5t-38.5 -30.5zM400 700h139q78 0 130.5 48.5t52.5 122.5q0 41 -8.5 70.5t-29.5 55.5t-62.5 39.5t-103.5 13.5h-118v-350zM400 200h216q80 0 121 50.5t41 130.5q0 90 -62.5 154.5 t-156.5 64.5h-159v-400z" /> +<glyph unicode="&#xe049;" d="M877 1200l2 -57q-83 -19 -116 -45.5t-40 -66.5l-132 -839q-9 -49 13 -69t96 -26v-97h-500v97q186 16 200 98l173 832q3 17 3 30t-1.5 22.5t-9 17.5t-13.5 12.5t-21.5 10t-26 8.5t-33.5 10q-13 3 -19 5v57h425z" /> +<glyph unicode="&#xe050;" d="M1300 900h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-200v-850q0 -22 25 -34.5t50 -13.5l25 -2v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v850h-200q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h1000v-300zM175 1000h-75v-800h75l-125 -167l-125 167h75v800h-75l125 167z" /> +<glyph unicode="&#xe051;" d="M1100 900h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-200v-650q0 -22 25 -34.5t50 -13.5l25 -2v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v650h-200q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h1000v-300zM1167 50l-167 -125v75h-800v-75l-167 125l167 125v-75h800v75z" /> +<glyph unicode="&#xe052;" d="M50 1100h600q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 800h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM50 500h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe053;" d="M250 1100h700q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 800h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM250 500h700q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe054;" d="M500 950v100q0 21 14.5 35.5t35.5 14.5h600q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5zM100 650v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000 q-21 0 -35.5 14.5t-14.5 35.5zM300 350v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5zM0 50v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100 q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5z" /> +<glyph unicode="&#xe055;" d="M50 1100h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 800h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM50 500h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe056;" d="M50 1100h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 1100h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM50 800h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 800h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 500h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 500h800q21 0 35.5 -14.5t14.5 -35.5v-100 q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 200h800 q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe057;" d="M400 0h-100v1100h100v-1100zM550 1100h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM550 800h500q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-500 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM267 550l-167 -125v75h-200v100h200v75zM550 500h300q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM550 200h600 q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe058;" d="M50 1100h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM900 0h-100v1100h100v-1100zM50 800h500q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-500 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM1100 600h200v-100h-200v-75l-167 125l167 125v-75zM50 500h300q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h600 q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe059;" d="M75 1000h750q31 0 53 -22t22 -53v-650q0 -31 -22 -53t-53 -22h-750q-31 0 -53 22t-22 53v650q0 31 22 53t53 22zM1200 300l-300 300l300 300v-600z" /> +<glyph unicode="&#xe060;" d="M44 1100h1112q18 0 31 -13t13 -31v-1012q0 -18 -13 -31t-31 -13h-1112q-18 0 -31 13t-13 31v1012q0 18 13 31t31 13zM100 1000v-737l247 182l298 -131l-74 156l293 318l236 -288v500h-1000zM342 884q56 0 95 -39t39 -94.5t-39 -95t-95 -39.5t-95 39.5t-39 95t39 94.5 t95 39z" /> +<glyph unicode="&#xe062;" d="M648 1169q117 0 216 -60t156.5 -161t57.5 -218q0 -115 -70 -258q-69 -109 -158 -225.5t-143 -179.5l-54 -62q-9 8 -25.5 24.5t-63.5 67.5t-91 103t-98.5 128t-95.5 148q-60 132 -60 249q0 88 34 169.5t91.5 142t137 96.5t166.5 36zM652.5 974q-91.5 0 -156.5 -65 t-65 -157t65 -156.5t156.5 -64.5t156.5 64.5t65 156.5t-65 157t-156.5 65z" /> +<glyph unicode="&#xe063;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 173v854q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57z" /> +<glyph unicode="&#xe064;" d="M554 1295q21 -72 57.5 -143.5t76 -130t83 -118t82.5 -117t70 -116t49.5 -126t18.5 -136.5q0 -71 -25.5 -135t-68.5 -111t-99 -82t-118.5 -54t-125.5 -23q-84 5 -161.5 34t-139.5 78.5t-99 125t-37 164.5q0 69 18 136.5t49.5 126.5t69.5 116.5t81.5 117.5t83.5 119 t76.5 131t58.5 143zM344 710q-23 -33 -43.5 -70.5t-40.5 -102.5t-17 -123q1 -37 14.5 -69.5t30 -52t41 -37t38.5 -24.5t33 -15q21 -7 32 -1t13 22l6 34q2 10 -2.5 22t-13.5 19q-5 4 -14 12t-29.5 40.5t-32.5 73.5q-26 89 6 271q2 11 -6 11q-8 1 -15 -10z" /> +<glyph unicode="&#xe065;" d="M1000 1013l108 115q2 1 5 2t13 2t20.5 -1t25 -9.5t28.5 -21.5q22 -22 27 -43t0 -32l-6 -10l-108 -115zM350 1100h400q50 0 105 -13l-187 -187h-368q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v182l200 200v-332 q0 -165 -93.5 -257.5t-256.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5zM1009 803l-362 -362l-161 -50l55 170l355 355z" /> +<glyph unicode="&#xe066;" d="M350 1100h361q-164 -146 -216 -200h-195q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5l200 153v-103q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5z M824 1073l339 -301q8 -7 8 -17.5t-8 -17.5l-340 -306q-7 -6 -12.5 -4t-6.5 11v203q-26 1 -54.5 0t-78.5 -7.5t-92 -17.5t-86 -35t-70 -57q10 59 33 108t51.5 81.5t65 58.5t68.5 40.5t67 24.5t56 13.5t40 4.5v210q1 10 6.5 12.5t13.5 -4.5z" /> +<glyph unicode="&#xe067;" d="M350 1100h350q60 0 127 -23l-178 -177h-349q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v69l200 200v-219q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5z M643 639l395 395q7 7 17.5 7t17.5 -7l101 -101q7 -7 7 -17.5t-7 -17.5l-531 -532q-7 -7 -17.5 -7t-17.5 7l-248 248q-7 7 -7 17.5t7 17.5l101 101q7 7 17.5 7t17.5 -7l111 -111q8 -7 18 -7t18 7z" /> +<glyph unicode="&#xe068;" d="M318 918l264 264q8 8 18 8t18 -8l260 -264q7 -8 4.5 -13t-12.5 -5h-170v-200h200v173q0 10 5 12t13 -5l264 -260q8 -7 8 -17.5t-8 -17.5l-264 -265q-8 -7 -13 -5t-5 12v173h-200v-200h170q10 0 12.5 -5t-4.5 -13l-260 -264q-8 -8 -18 -8t-18 8l-264 264q-8 8 -5.5 13 t12.5 5h175v200h-200v-173q0 -10 -5 -12t-13 5l-264 265q-8 7 -8 17.5t8 17.5l264 260q8 7 13 5t5 -12v-173h200v200h-175q-10 0 -12.5 5t5.5 13z" /> +<glyph unicode="&#xe069;" d="M250 1100h100q21 0 35.5 -14.5t14.5 -35.5v-438l464 453q15 14 25.5 10t10.5 -25v-1000q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v1000q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe070;" d="M50 1100h100q21 0 35.5 -14.5t14.5 -35.5v-438l464 453q15 14 25.5 10t10.5 -25v-438l464 453q15 14 25.5 10t10.5 -25v-1000q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5 t-14.5 35.5v1000q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe071;" d="M1200 1050v-1000q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -10.5 -25t-25.5 10l-492 480q-15 14 -15 35t15 35l492 480q15 14 25.5 10t10.5 -25v-438l464 453q15 14 25.5 10t10.5 -25z" /> +<glyph unicode="&#xe072;" d="M243 1074l814 -498q18 -11 18 -26t-18 -26l-814 -498q-18 -11 -30.5 -4t-12.5 28v1000q0 21 12.5 28t30.5 -4z" /> +<glyph unicode="&#xe073;" d="M250 1000h200q21 0 35.5 -14.5t14.5 -35.5v-800q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v800q0 21 14.5 35.5t35.5 14.5zM650 1000h200q21 0 35.5 -14.5t14.5 -35.5v-800q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v800 q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe074;" d="M1100 950v-800q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v800q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5z" /> +<glyph unicode="&#xe075;" d="M500 612v438q0 21 10.5 25t25.5 -10l492 -480q15 -14 15 -35t-15 -35l-492 -480q-15 -14 -25.5 -10t-10.5 25v438l-464 -453q-15 -14 -25.5 -10t-10.5 25v1000q0 21 10.5 25t25.5 -10z" /> +<glyph unicode="&#xe076;" d="M1048 1102l100 1q20 0 35 -14.5t15 -35.5l5 -1000q0 -21 -14.5 -35.5t-35.5 -14.5l-100 -1q-21 0 -35.5 14.5t-14.5 35.5l-2 437l-463 -454q-14 -15 -24.5 -10.5t-10.5 25.5l-2 437l-462 -455q-15 -14 -25.5 -9.5t-10.5 24.5l-5 1000q0 21 10.5 25.5t25.5 -10.5l466 -450 l-2 438q0 20 10.5 24.5t25.5 -9.5l466 -451l-2 438q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe077;" d="M850 1100h100q21 0 35.5 -14.5t14.5 -35.5v-1000q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v438l-464 -453q-15 -14 -25.5 -10t-10.5 25v1000q0 21 10.5 25t25.5 -10l464 -453v438q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe078;" d="M686 1081l501 -540q15 -15 10.5 -26t-26.5 -11h-1042q-22 0 -26.5 11t10.5 26l501 540q15 15 36 15t36 -15zM150 400h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe079;" d="M885 900l-352 -353l352 -353l-197 -198l-552 552l552 550z" /> +<glyph unicode="&#xe080;" d="M1064 547l-551 -551l-198 198l353 353l-353 353l198 198z" /> +<glyph unicode="&#xe081;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM650 900h-100q-21 0 -35.5 -14.5t-14.5 -35.5v-150h-150 q-21 0 -35.5 -14.5t-14.5 -35.5v-100q0 -21 14.5 -35.5t35.5 -14.5h150v-150q0 -21 14.5 -35.5t35.5 -14.5h100q21 0 35.5 14.5t14.5 35.5v150h150q21 0 35.5 14.5t14.5 35.5v100q0 21 -14.5 35.5t-35.5 14.5h-150v150q0 21 -14.5 35.5t-35.5 14.5z" /> +<glyph unicode="&#xe082;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM850 700h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100q0 -21 14.5 -35.5 t35.5 -14.5h500q21 0 35.5 14.5t14.5 35.5v100q0 21 -14.5 35.5t-35.5 14.5z" /> +<glyph unicode="&#xe083;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM741.5 913q-12.5 0 -21.5 -9l-120 -120l-120 120q-9 9 -21.5 9 t-21.5 -9l-141 -141q-9 -9 -9 -21.5t9 -21.5l120 -120l-120 -120q-9 -9 -9 -21.5t9 -21.5l141 -141q9 -9 21.5 -9t21.5 9l120 120l120 -120q9 -9 21.5 -9t21.5 9l141 141q9 9 9 21.5t-9 21.5l-120 120l120 120q9 9 9 21.5t-9 21.5l-141 141q-9 9 -21.5 9z" /> +<glyph unicode="&#xe084;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM546 623l-84 85q-7 7 -17.5 7t-18.5 -7l-139 -139q-7 -8 -7 -18t7 -18 l242 -241q7 -8 17.5 -8t17.5 8l375 375q7 7 7 17.5t-7 18.5l-139 139q-7 7 -17.5 7t-17.5 -7z" /> +<glyph unicode="&#xe085;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM588 941q-29 0 -59 -5.5t-63 -20.5t-58 -38.5t-41.5 -63t-16.5 -89.5 q0 -25 20 -25h131q30 -5 35 11q6 20 20.5 28t45.5 8q20 0 31.5 -10.5t11.5 -28.5q0 -23 -7 -34t-26 -18q-1 0 -13.5 -4t-19.5 -7.5t-20 -10.5t-22 -17t-18.5 -24t-15.5 -35t-8 -46q-1 -8 5.5 -16.5t20.5 -8.5h173q7 0 22 8t35 28t37.5 48t29.5 74t12 100q0 47 -17 83 t-42.5 57t-59.5 34.5t-64 18t-59 4.5zM675 400h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5z" /> +<glyph unicode="&#xe086;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM675 1000h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5 t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5zM675 700h-250q-10 0 -17.5 -7.5t-7.5 -17.5v-50q0 -10 7.5 -17.5t17.5 -7.5h75v-200h-75q-10 0 -17.5 -7.5t-7.5 -17.5v-50q0 -10 7.5 -17.5t17.5 -7.5h350q10 0 17.5 7.5t7.5 17.5v50q0 10 -7.5 17.5 t-17.5 7.5h-75v275q0 10 -7.5 17.5t-17.5 7.5z" /> +<glyph unicode="&#xe087;" d="M525 1200h150q10 0 17.5 -7.5t7.5 -17.5v-194q103 -27 178.5 -102.5t102.5 -178.5h194q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-194q-27 -103 -102.5 -178.5t-178.5 -102.5v-194q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v194 q-103 27 -178.5 102.5t-102.5 178.5h-194q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h194q27 103 102.5 178.5t178.5 102.5v194q0 10 7.5 17.5t17.5 7.5zM700 893v-168q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v168q-68 -23 -119 -74 t-74 -119h168q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-168q23 -68 74 -119t119 -74v168q0 10 7.5 17.5t17.5 7.5h150q10 0 17.5 -7.5t7.5 -17.5v-168q68 23 119 74t74 119h-168q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h168 q-23 68 -74 119t-119 74z" /> +<glyph unicode="&#xe088;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM759 823l64 -64q7 -7 7 -17.5t-7 -17.5l-124 -124l124 -124q7 -7 7 -17.5t-7 -17.5l-64 -64q-7 -7 -17.5 -7t-17.5 7l-124 124l-124 -124q-7 -7 -17.5 -7t-17.5 7l-64 64 q-7 7 -7 17.5t7 17.5l124 124l-124 124q-7 7 -7 17.5t7 17.5l64 64q7 7 17.5 7t17.5 -7l124 -124l124 124q7 7 17.5 7t17.5 -7z" /> +<glyph unicode="&#xe089;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM782 788l106 -106q7 -7 7 -17.5t-7 -17.5l-320 -321q-8 -7 -18 -7t-18 7l-202 203q-8 7 -8 17.5t8 17.5l106 106q7 8 17.5 8t17.5 -8l79 -79l197 197q7 7 17.5 7t17.5 -7z" /> +<glyph unicode="&#xe090;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5q0 -120 65 -225 l587 587q-105 65 -225 65zM965 819l-584 -584q104 -62 219 -62q116 0 214.5 57t155.5 155.5t57 214.5q0 115 -62 219z" /> +<glyph unicode="&#xe091;" d="M39 582l522 427q16 13 27.5 8t11.5 -26v-291h550q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-550v-291q0 -21 -11.5 -26t-27.5 8l-522 427q-16 13 -16 32t16 32z" /> +<glyph unicode="&#xe092;" d="M639 1009l522 -427q16 -13 16 -32t-16 -32l-522 -427q-16 -13 -27.5 -8t-11.5 26v291h-550q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5h550v291q0 21 11.5 26t27.5 -8z" /> +<glyph unicode="&#xe093;" d="M682 1161l427 -522q13 -16 8 -27.5t-26 -11.5h-291v-550q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v550h-291q-21 0 -26 11.5t8 27.5l427 522q13 16 32 16t32 -16z" /> +<glyph unicode="&#xe094;" d="M550 1200h200q21 0 35.5 -14.5t14.5 -35.5v-550h291q21 0 26 -11.5t-8 -27.5l-427 -522q-13 -16 -32 -16t-32 16l-427 522q-13 16 -8 27.5t26 11.5h291v550q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe095;" d="M639 1109l522 -427q16 -13 16 -32t-16 -32l-522 -427q-16 -13 -27.5 -8t-11.5 26v291q-94 -2 -182 -20t-170.5 -52t-147 -92.5t-100.5 -135.5q5 105 27 193.5t67.5 167t113 135t167 91.5t225.5 42v262q0 21 11.5 26t27.5 -8z" /> +<glyph unicode="&#xe096;" d="M850 1200h300q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -10.5 -25t-24.5 10l-94 94l-249 -249q-8 -7 -18 -7t-18 7l-106 106q-7 8 -7 18t7 18l249 249l-94 94q-14 14 -10 24.5t25 10.5zM350 0h-300q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 10.5 25t24.5 -10l94 -94l249 249 q8 7 18 7t18 -7l106 -106q7 -8 7 -18t-7 -18l-249 -249l94 -94q14 -14 10 -24.5t-25 -10.5z" /> +<glyph unicode="&#xe097;" d="M1014 1120l106 -106q7 -8 7 -18t-7 -18l-249 -249l94 -94q14 -14 10 -24.5t-25 -10.5h-300q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 10.5 25t24.5 -10l94 -94l249 249q8 7 18 7t18 -7zM250 600h300q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -10.5 -25t-24.5 10l-94 94 l-249 -249q-8 -7 -18 -7t-18 7l-106 106q-7 8 -7 18t7 18l249 249l-94 94q-14 14 -10 24.5t25 10.5z" /> +<glyph unicode="&#xe101;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM704 900h-208q-20 0 -32 -14.5t-8 -34.5l58 -302q4 -20 21.5 -34.5 t37.5 -14.5h54q20 0 37.5 14.5t21.5 34.5l58 302q4 20 -8 34.5t-32 14.5zM675 400h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5z" /> +<glyph unicode="&#xe102;" d="M260 1200q9 0 19 -2t15 -4l5 -2q22 -10 44 -23l196 -118q21 -13 36 -24q29 -21 37 -12q11 13 49 35l196 118q22 13 45 23q17 7 38 7q23 0 47 -16.5t37 -33.5l13 -16q14 -21 18 -45l25 -123l8 -44q1 -9 8.5 -14.5t17.5 -5.5h61q10 0 17.5 -7.5t7.5 -17.5v-50 q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 -7.5t-7.5 -17.5v-175h-400v300h-200v-300h-400v175q0 10 -7.5 17.5t-17.5 7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5h61q11 0 18 3t7 8q0 4 9 52l25 128q5 25 19 45q2 3 5 7t13.5 15t21.5 19.5t26.5 15.5 t29.5 7zM915 1079l-166 -162q-7 -7 -5 -12t12 -5h219q10 0 15 7t2 17l-51 149q-3 10 -11 12t-15 -6zM463 917l-177 157q-8 7 -16 5t-11 -12l-51 -143q-3 -10 2 -17t15 -7h231q11 0 12.5 5t-5.5 12zM500 0h-375q-10 0 -17.5 7.5t-7.5 17.5v375h400v-400zM1100 400v-375 q0 -10 -7.5 -17.5t-17.5 -7.5h-375v400h400z" /> +<glyph unicode="&#xe103;" d="M1165 1190q8 3 21 -6.5t13 -17.5q-2 -178 -24.5 -323.5t-55.5 -245.5t-87 -174.5t-102.5 -118.5t-118 -68.5t-118.5 -33t-120 -4.5t-105 9.5t-90 16.5q-61 12 -78 11q-4 1 -12.5 0t-34 -14.5t-52.5 -40.5l-153 -153q-26 -24 -37 -14.5t-11 43.5q0 64 42 102q8 8 50.5 45 t66.5 58q19 17 35 47t13 61q-9 55 -10 102.5t7 111t37 130t78 129.5q39 51 80 88t89.5 63.5t94.5 45t113.5 36t129 31t157.5 37t182 47.5zM1116 1098q-8 9 -22.5 -3t-45.5 -50q-38 -47 -119 -103.5t-142 -89.5l-62 -33q-56 -30 -102 -57t-104 -68t-102.5 -80.5t-85.5 -91 t-64 -104.5q-24 -56 -31 -86t2 -32t31.5 17.5t55.5 59.5q25 30 94 75.5t125.5 77.5t147.5 81q70 37 118.5 69t102 79.5t99 111t86.5 148.5q22 50 24 60t-6 19z" /> +<glyph unicode="&#xe104;" d="M653 1231q-39 -67 -54.5 -131t-10.5 -114.5t24.5 -96.5t47.5 -80t63.5 -62.5t68.5 -46.5t65 -30q-4 7 -17.5 35t-18.5 39.5t-17 39.5t-17 43t-13 42t-9.5 44.5t-2 42t4 43t13.5 39t23 38.5q96 -42 165 -107.5t105 -138t52 -156t13 -159t-19 -149.5q-13 -55 -44 -106.5 t-68 -87t-78.5 -64.5t-72.5 -45t-53 -22q-72 -22 -127 -11q-31 6 -13 19q6 3 17 7q13 5 32.5 21t41 44t38.5 63.5t21.5 81.5t-6.5 94.5t-50 107t-104 115.5q10 -104 -0.5 -189t-37 -140.5t-65 -93t-84 -52t-93.5 -11t-95 24.5q-80 36 -131.5 114t-53.5 171q-2 23 0 49.5 t4.5 52.5t13.5 56t27.5 60t46 64.5t69.5 68.5q-8 -53 -5 -102.5t17.5 -90t34 -68.5t44.5 -39t49 -2q31 13 38.5 36t-4.5 55t-29 64.5t-36 75t-26 75.5q-15 85 2 161.5t53.5 128.5t85.5 92.5t93.5 61t81.5 25.5z" /> +<glyph unicode="&#xe105;" d="M600 1094q82 0 160.5 -22.5t140 -59t116.5 -82.5t94.5 -95t68 -95t42.5 -82.5t14 -57.5t-14 -57.5t-43 -82.5t-68.5 -95t-94.5 -95t-116.5 -82.5t-140 -59t-159.5 -22.5t-159.5 22.5t-140 59t-116.5 82.5t-94.5 95t-68.5 95t-43 82.5t-14 57.5t14 57.5t42.5 82.5t68 95 t94.5 95t116.5 82.5t140 59t160.5 22.5zM888 829q-15 15 -18 12t5 -22q25 -57 25 -119q0 -124 -88 -212t-212 -88t-212 88t-88 212q0 59 23 114q8 19 4.5 22t-17.5 -12q-70 -69 -160 -184q-13 -16 -15 -40.5t9 -42.5q22 -36 47 -71t70 -82t92.5 -81t113 -58.5t133.5 -24.5 t133.5 24t113 58.5t92.5 81.5t70 81.5t47 70.5q11 18 9 42.5t-14 41.5q-90 117 -163 189zM448 727l-35 -36q-15 -15 -19.5 -38.5t4.5 -41.5q37 -68 93 -116q16 -13 38.5 -11t36.5 17l35 34q14 15 12.5 33.5t-16.5 33.5q-44 44 -89 117q-11 18 -28 20t-32 -12z" /> +<glyph unicode="&#xe106;" d="M592 0h-148l31 120q-91 20 -175.5 68.5t-143.5 106.5t-103.5 119t-66.5 110t-22 76q0 21 14 57.5t42.5 82.5t68 95t94.5 95t116.5 82.5t140 59t160.5 22.5q61 0 126 -15l32 121h148zM944 770l47 181q108 -85 176.5 -192t68.5 -159q0 -26 -19.5 -71t-59.5 -102t-93 -112 t-129 -104.5t-158 -75.5l46 173q77 49 136 117t97 131q11 18 9 42.5t-14 41.5q-54 70 -107 130zM310 824q-70 -69 -160 -184q-13 -16 -15 -40.5t9 -42.5q18 -30 39 -60t57 -70.5t74 -73t90 -61t105 -41.5l41 154q-107 18 -178.5 101.5t-71.5 193.5q0 59 23 114q8 19 4.5 22 t-17.5 -12zM448 727l-35 -36q-15 -15 -19.5 -38.5t4.5 -41.5q37 -68 93 -116q16 -13 38.5 -11t36.5 17l12 11l22 86l-3 4q-44 44 -89 117q-11 18 -28 20t-32 -12z" /> +<glyph unicode="&#xe107;" d="M-90 100l642 1066q20 31 48 28.5t48 -35.5l642 -1056q21 -32 7.5 -67.5t-50.5 -35.5h-1294q-37 0 -50.5 34t7.5 66zM155 200h345v75q0 10 7.5 17.5t17.5 7.5h150q10 0 17.5 -7.5t7.5 -17.5v-75h345l-445 723zM496 700h208q20 0 32 -14.5t8 -34.5l-58 -252 q-4 -20 -21.5 -34.5t-37.5 -14.5h-54q-20 0 -37.5 14.5t-21.5 34.5l-58 252q-4 20 8 34.5t32 14.5z" /> +<glyph unicode="&#xe108;" d="M650 1200q62 0 106 -44t44 -106v-339l363 -325q15 -14 26 -38.5t11 -44.5v-41q0 -20 -12 -26.5t-29 5.5l-359 249v-263q100 -93 100 -113v-64q0 -21 -13 -29t-32 1l-205 128l-205 -128q-19 -9 -32 -1t-13 29v64q0 20 100 113v263l-359 -249q-17 -12 -29 -5.5t-12 26.5v41 q0 20 11 44.5t26 38.5l363 325v339q0 62 44 106t106 44z" /> +<glyph unicode="&#xe109;" d="M850 1200h100q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-150h-1100v150q0 21 14.5 35.5t35.5 14.5h50v50q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-50h500v50q0 21 14.5 35.5t35.5 14.5zM1100 800v-750q0 -21 -14.5 -35.5 t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v750h1100zM100 600v-100h100v100h-100zM300 600v-100h100v100h-100zM500 600v-100h100v100h-100zM700 600v-100h100v100h-100zM900 600v-100h100v100h-100zM100 400v-100h100v100h-100zM300 400v-100h100v100h-100zM500 400 v-100h100v100h-100zM700 400v-100h100v100h-100zM900 400v-100h100v100h-100zM100 200v-100h100v100h-100zM300 200v-100h100v100h-100zM500 200v-100h100v100h-100zM700 200v-100h100v100h-100zM900 200v-100h100v100h-100z" /> +<glyph unicode="&#xe110;" d="M1135 1165l249 -230q15 -14 15 -35t-15 -35l-249 -230q-14 -14 -24.5 -10t-10.5 25v150h-159l-600 -600h-291q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h209l600 600h241v150q0 21 10.5 25t24.5 -10zM522 819l-141 -141l-122 122h-209q-21 0 -35.5 14.5 t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h291zM1135 565l249 -230q15 -14 15 -35t-15 -35l-249 -230q-14 -14 -24.5 -10t-10.5 25v150h-241l-181 181l141 141l122 -122h159v150q0 21 10.5 25t24.5 -10z" /> +<glyph unicode="&#xe111;" d="M100 1100h1000q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-596l-304 -300v300h-100q-41 0 -70.5 29.5t-29.5 70.5v600q0 41 29.5 70.5t70.5 29.5z" /> +<glyph unicode="&#xe112;" d="M150 1200h200q21 0 35.5 -14.5t14.5 -35.5v-250h-300v250q0 21 14.5 35.5t35.5 14.5zM850 1200h200q21 0 35.5 -14.5t14.5 -35.5v-250h-300v250q0 21 14.5 35.5t35.5 14.5zM1100 800v-300q0 -41 -3 -77.5t-15 -89.5t-32 -96t-58 -89t-89 -77t-129 -51t-174 -20t-174 20 t-129 51t-89 77t-58 89t-32 96t-15 89.5t-3 77.5v300h300v-250v-27v-42.5t1.5 -41t5 -38t10 -35t16.5 -30t25.5 -24.5t35 -19t46.5 -12t60 -4t60 4.5t46.5 12.5t35 19.5t25 25.5t17 30.5t10 35t5 38t2 40.5t-0.5 42v25v250h300z" /> +<glyph unicode="&#xe113;" d="M1100 411l-198 -199l-353 353l-353 -353l-197 199l551 551z" /> +<glyph unicode="&#xe114;" d="M1101 789l-550 -551l-551 551l198 199l353 -353l353 353z" /> +<glyph unicode="&#xe115;" d="M404 1000h746q21 0 35.5 -14.5t14.5 -35.5v-551h150q21 0 25 -10.5t-10 -24.5l-230 -249q-14 -15 -35 -15t-35 15l-230 249q-14 14 -10 24.5t25 10.5h150v401h-381zM135 984l230 -249q14 -14 10 -24.5t-25 -10.5h-150v-400h385l215 -200h-750q-21 0 -35.5 14.5 t-14.5 35.5v550h-150q-21 0 -25 10.5t10 24.5l230 249q14 15 35 15t35 -15z" /> +<glyph unicode="&#xe116;" d="M56 1200h94q17 0 31 -11t18 -27l38 -162h896q24 0 39 -18.5t10 -42.5l-100 -475q-5 -21 -27 -42.5t-55 -21.5h-633l48 -200h535q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-50q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v50h-300v-50 q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v50h-31q-18 0 -32.5 10t-20.5 19l-5 10l-201 961h-54q-20 0 -35 14.5t-15 35.5t15 35.5t35 14.5z" /> +<glyph unicode="&#xe117;" d="M1200 1000v-100h-1200v100h200q0 41 29.5 70.5t70.5 29.5h300q41 0 70.5 -29.5t29.5 -70.5h500zM0 800h1200v-800h-1200v800z" /> +<glyph unicode="&#xe118;" d="M200 800l-200 -400v600h200q0 41 29.5 70.5t70.5 29.5h300q42 0 71 -29.5t29 -70.5h500v-200h-1000zM1500 700l-300 -700h-1200l300 700h1200z" /> +<glyph unicode="&#xe119;" d="M635 1184l230 -249q14 -14 10 -24.5t-25 -10.5h-150v-601h150q21 0 25 -10.5t-10 -24.5l-230 -249q-14 -15 -35 -15t-35 15l-230 249q-14 14 -10 24.5t25 10.5h150v601h-150q-21 0 -25 10.5t10 24.5l230 249q14 15 35 15t35 -15z" /> +<glyph unicode="&#xe120;" d="M936 864l249 -229q14 -15 14 -35.5t-14 -35.5l-249 -229q-15 -15 -25.5 -10.5t-10.5 24.5v151h-600v-151q0 -20 -10.5 -24.5t-25.5 10.5l-249 229q-14 15 -14 35.5t14 35.5l249 229q15 15 25.5 10.5t10.5 -25.5v-149h600v149q0 21 10.5 25.5t25.5 -10.5z" /> +<glyph unicode="&#xe121;" d="M1169 400l-172 732q-5 23 -23 45.5t-38 22.5h-672q-20 0 -38 -20t-23 -41l-172 -739h1138zM1100 300h-1000q-41 0 -70.5 -29.5t-29.5 -70.5v-100q0 -41 29.5 -70.5t70.5 -29.5h1000q41 0 70.5 29.5t29.5 70.5v100q0 41 -29.5 70.5t-70.5 29.5zM800 100v100h100v-100h-100 zM1000 100v100h100v-100h-100z" /> +<glyph unicode="&#xe122;" d="M1150 1100q21 0 35.5 -14.5t14.5 -35.5v-850q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v850q0 21 14.5 35.5t35.5 14.5zM1000 200l-675 200h-38l47 -276q3 -16 -5.5 -20t-29.5 -4h-7h-84q-20 0 -34.5 14t-18.5 35q-55 337 -55 351v250v6q0 16 1 23.5t6.5 14 t17.5 6.5h200l675 250v-850zM0 750v-250q-4 0 -11 0.5t-24 6t-30 15t-24 30t-11 48.5v50q0 26 10.5 46t25 30t29 16t25.5 7z" /> +<glyph unicode="&#xe123;" d="M553 1200h94q20 0 29 -10.5t3 -29.5l-18 -37q83 -19 144 -82.5t76 -140.5l63 -327l118 -173h17q19 0 33 -14.5t14 -35t-13 -40.5t-31 -27q-8 -4 -23 -9.5t-65 -19.5t-103 -25t-132.5 -20t-158.5 -9q-57 0 -115 5t-104 12t-88.5 15.5t-73.5 17.5t-54.5 16t-35.5 12l-11 4 q-18 8 -31 28t-13 40.5t14 35t33 14.5h17l118 173l63 327q15 77 76 140t144 83l-18 32q-6 19 3.5 32t28.5 13zM498 110q50 -6 102 -6q53 0 102 6q-12 -49 -39.5 -79.5t-62.5 -30.5t-63 30.5t-39 79.5z" /> +<glyph unicode="&#xe124;" d="M800 946l224 78l-78 -224l234 -45l-180 -155l180 -155l-234 -45l78 -224l-224 78l-45 -234l-155 180l-155 -180l-45 234l-224 -78l78 224l-234 45l180 155l-180 155l234 45l-78 224l224 -78l45 234l155 -180l155 180z" /> +<glyph unicode="&#xe125;" d="M650 1200h50q40 0 70 -40.5t30 -84.5v-150l-28 -125h328q40 0 70 -40.5t30 -84.5v-100q0 -45 -29 -74l-238 -344q-16 -24 -38 -40.5t-45 -16.5h-250q-7 0 -42 25t-66 50l-31 25h-61q-45 0 -72.5 18t-27.5 57v400q0 36 20 63l145 196l96 198q13 28 37.5 48t51.5 20z M650 1100l-100 -212l-150 -213v-375h100l136 -100h214l250 375v125h-450l50 225v175h-50zM50 800h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v500q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe126;" d="M600 1100h250q23 0 45 -16.5t38 -40.5l238 -344q29 -29 29 -74v-100q0 -44 -30 -84.5t-70 -40.5h-328q28 -118 28 -125v-150q0 -44 -30 -84.5t-70 -40.5h-50q-27 0 -51.5 20t-37.5 48l-96 198l-145 196q-20 27 -20 63v400q0 39 27.5 57t72.5 18h61q124 100 139 100z M50 1000h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v500q0 21 14.5 35.5t35.5 14.5zM636 1000l-136 -100h-100v-375l150 -213l100 -212h50v175l-50 225h450v125l-250 375h-214z" /> +<glyph unicode="&#xe127;" d="M356 873l363 230q31 16 53 -6l110 -112q13 -13 13.5 -32t-11.5 -34l-84 -121h302q84 0 138 -38t54 -110t-55 -111t-139 -39h-106l-131 -339q-6 -21 -19.5 -41t-28.5 -20h-342q-7 0 -90 81t-83 94v525q0 17 14 35.5t28 28.5zM400 792v-503l100 -89h293l131 339 q6 21 19.5 41t28.5 20h203q21 0 30.5 25t0.5 50t-31 25h-456h-7h-6h-5.5t-6 0.5t-5 1.5t-5 2t-4 2.5t-4 4t-2.5 4.5q-12 25 5 47l146 183l-86 83zM50 800h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v500 q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe128;" d="M475 1103l366 -230q2 -1 6 -3.5t14 -10.5t18 -16.5t14.5 -20t6.5 -22.5v-525q0 -13 -86 -94t-93 -81h-342q-15 0 -28.5 20t-19.5 41l-131 339h-106q-85 0 -139.5 39t-54.5 111t54 110t138 38h302l-85 121q-11 15 -10.5 34t13.5 32l110 112q22 22 53 6zM370 945l146 -183 q17 -22 5 -47q-2 -2 -3.5 -4.5t-4 -4t-4 -2.5t-5 -2t-5 -1.5t-6 -0.5h-6h-6.5h-6h-475v-100h221q15 0 29 -20t20 -41l130 -339h294l106 89v503l-342 236zM1050 800h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5 v500q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe129;" d="M550 1294q72 0 111 -55t39 -139v-106l339 -131q21 -6 41 -19.5t20 -28.5v-342q0 -7 -81 -90t-94 -83h-525q-17 0 -35.5 14t-28.5 28l-9 14l-230 363q-16 31 6 53l112 110q13 13 32 13.5t34 -11.5l121 -84v302q0 84 38 138t110 54zM600 972v203q0 21 -25 30.5t-50 0.5 t-25 -31v-456v-7v-6v-5.5t-0.5 -6t-1.5 -5t-2 -5t-2.5 -4t-4 -4t-4.5 -2.5q-25 -12 -47 5l-183 146l-83 -86l236 -339h503l89 100v293l-339 131q-21 6 -41 19.5t-20 28.5zM450 200h500q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-500 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe130;" d="M350 1100h500q21 0 35.5 14.5t14.5 35.5v100q0 21 -14.5 35.5t-35.5 14.5h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100q0 -21 14.5 -35.5t35.5 -14.5zM600 306v-106q0 -84 -39 -139t-111 -55t-110 54t-38 138v302l-121 -84q-15 -12 -34 -11.5t-32 13.5l-112 110 q-22 22 -6 53l230 363q1 2 3.5 6t10.5 13.5t16.5 17t20 13.5t22.5 6h525q13 0 94 -83t81 -90v-342q0 -15 -20 -28.5t-41 -19.5zM308 900l-236 -339l83 -86l183 146q22 17 47 5q2 -1 4.5 -2.5t4 -4t2.5 -4t2 -5t1.5 -5t0.5 -6v-5.5v-6v-7v-456q0 -22 25 -31t50 0.5t25 30.5 v203q0 15 20 28.5t41 19.5l339 131v293l-89 100h-503z" /> +<glyph unicode="&#xe131;" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM914 632l-275 223q-16 13 -27.5 8t-11.5 -26v-137h-275 q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h275v-137q0 -21 11.5 -26t27.5 8l275 223q16 13 16 32t-16 32z" /> +<glyph unicode="&#xe132;" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM561 855l-275 -223q-16 -13 -16 -32t16 -32l275 -223q16 -13 27.5 -8 t11.5 26v137h275q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5h-275v137q0 21 -11.5 26t-27.5 -8z" /> +<glyph unicode="&#xe133;" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM855 639l-223 275q-13 16 -32 16t-32 -16l-223 -275q-13 -16 -8 -27.5 t26 -11.5h137v-275q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v275h137q21 0 26 11.5t-8 27.5z" /> +<glyph unicode="&#xe134;" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM675 900h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-275h-137q-21 0 -26 -11.5 t8 -27.5l223 -275q13 -16 32 -16t32 16l223 275q13 16 8 27.5t-26 11.5h-137v275q0 10 -7.5 17.5t-17.5 7.5z" /> +<glyph unicode="&#xe135;" d="M600 1176q116 0 222.5 -46t184 -123.5t123.5 -184t46 -222.5t-46 -222.5t-123.5 -184t-184 -123.5t-222.5 -46t-222.5 46t-184 123.5t-123.5 184t-46 222.5t46 222.5t123.5 184t184 123.5t222.5 46zM627 1101q-15 -12 -36.5 -20.5t-35.5 -12t-43 -8t-39 -6.5 q-15 -3 -45.5 0t-45.5 -2q-20 -7 -51.5 -26.5t-34.5 -34.5q-3 -11 6.5 -22.5t8.5 -18.5q-3 -34 -27.5 -91t-29.5 -79q-9 -34 5 -93t8 -87q0 -9 17 -44.5t16 -59.5q12 0 23 -5t23.5 -15t19.5 -14q16 -8 33 -15t40.5 -15t34.5 -12q21 -9 52.5 -32t60 -38t57.5 -11 q7 -15 -3 -34t-22.5 -40t-9.5 -38q13 -21 23 -34.5t27.5 -27.5t36.5 -18q0 -7 -3.5 -16t-3.5 -14t5 -17q104 -2 221 112q30 29 46.5 47t34.5 49t21 63q-13 8 -37 8.5t-36 7.5q-15 7 -49.5 15t-51.5 19q-18 0 -41 -0.5t-43 -1.5t-42 -6.5t-38 -16.5q-51 -35 -66 -12 q-4 1 -3.5 25.5t0.5 25.5q-6 13 -26.5 17.5t-24.5 6.5q1 15 -0.5 30.5t-7 28t-18.5 11.5t-31 -21q-23 -25 -42 4q-19 28 -8 58q6 16 22 22q6 -1 26 -1.5t33.5 -4t19.5 -13.5q7 -12 18 -24t21.5 -20.5t20 -15t15.5 -10.5l5 -3q2 12 7.5 30.5t8 34.5t-0.5 32q-3 18 3.5 29 t18 22.5t15.5 24.5q6 14 10.5 35t8 31t15.5 22.5t34 22.5q-6 18 10 36q8 0 24 -1.5t24.5 -1.5t20 4.5t20.5 15.5q-10 23 -31 42.5t-37.5 29.5t-49 27t-43.5 23q0 1 2 8t3 11.5t1.5 10.5t-1 9.5t-4.5 4.5q31 -13 58.5 -14.5t38.5 2.5l12 5q5 28 -9.5 46t-36.5 24t-50 15 t-41 20q-18 -4 -37 0zM613 994q0 -17 8 -42t17 -45t9 -23q-8 1 -39.5 5.5t-52.5 10t-37 16.5q3 11 16 29.5t16 25.5q10 -10 19 -10t14 6t13.5 14.5t16.5 12.5z" /> +<glyph unicode="&#xe136;" d="M756 1157q164 92 306 -9l-259 -138l145 -232l251 126q6 -89 -34 -156.5t-117 -110.5q-60 -34 -127 -39.5t-126 16.5l-596 -596q-15 -16 -36.5 -16t-36.5 16l-111 110q-15 15 -15 36.5t15 37.5l600 599q-34 101 5.5 201.5t135.5 154.5z" /> +<glyph unicode="&#xe137;" horiz-adv-x="1220" d="M100 1196h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5v100q0 41 29.5 70.5t70.5 29.5zM1100 1096h-200v-100h200v100zM100 796h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000 q-41 0 -70.5 29.5t-29.5 70.5v100q0 41 29.5 70.5t70.5 29.5zM1100 696h-500v-100h500v100zM100 396h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5v100q0 41 29.5 70.5t70.5 29.5zM1100 296h-300v-100h300v100z " /> +<glyph unicode="&#xe138;" d="M150 1200h900q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM700 500v-300l-200 -200v500l-350 500h900z" /> +<glyph unicode="&#xe139;" d="M500 1200h200q41 0 70.5 -29.5t29.5 -70.5v-100h300q41 0 70.5 -29.5t29.5 -70.5v-400h-500v100h-200v-100h-500v400q0 41 29.5 70.5t70.5 29.5h300v100q0 41 29.5 70.5t70.5 29.5zM500 1100v-100h200v100h-200zM1200 400v-200q0 -41 -29.5 -70.5t-70.5 -29.5h-1000 q-41 0 -70.5 29.5t-29.5 70.5v200h1200z" /> +<glyph unicode="&#xe140;" d="M50 1200h300q21 0 25 -10.5t-10 -24.5l-94 -94l199 -199q7 -8 7 -18t-7 -18l-106 -106q-8 -7 -18 -7t-18 7l-199 199l-94 -94q-14 -14 -24.5 -10t-10.5 25v300q0 21 14.5 35.5t35.5 14.5zM850 1200h300q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -10.5 -25t-24.5 10l-94 94 l-199 -199q-8 -7 -18 -7t-18 7l-106 106q-7 8 -7 18t7 18l199 199l-94 94q-14 14 -10 24.5t25 10.5zM364 470l106 -106q7 -8 7 -18t-7 -18l-199 -199l94 -94q14 -14 10 -24.5t-25 -10.5h-300q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 10.5 25t24.5 -10l94 -94l199 199 q8 7 18 7t18 -7zM1071 271l94 94q14 14 24.5 10t10.5 -25v-300q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -25 10.5t10 24.5l94 94l-199 199q-7 8 -7 18t7 18l106 106q8 7 18 7t18 -7z" /> +<glyph unicode="&#xe141;" d="M596 1192q121 0 231.5 -47.5t190 -127t127 -190t47.5 -231.5t-47.5 -231.5t-127 -190.5t-190 -127t-231.5 -47t-231.5 47t-190.5 127t-127 190.5t-47 231.5t47 231.5t127 190t190.5 127t231.5 47.5zM596 1010q-112 0 -207.5 -55.5t-151 -151t-55.5 -207.5t55.5 -207.5 t151 -151t207.5 -55.5t207.5 55.5t151 151t55.5 207.5t-55.5 207.5t-151 151t-207.5 55.5zM454.5 905q22.5 0 38.5 -16t16 -38.5t-16 -39t-38.5 -16.5t-38.5 16.5t-16 39t16 38.5t38.5 16zM754.5 905q22.5 0 38.5 -16t16 -38.5t-16 -39t-38 -16.5q-14 0 -29 10l-55 -145 q17 -23 17 -51q0 -36 -25.5 -61.5t-61.5 -25.5t-61.5 25.5t-25.5 61.5q0 32 20.5 56.5t51.5 29.5l122 126l1 1q-9 14 -9 28q0 23 16 39t38.5 16zM345.5 709q22.5 0 38.5 -16t16 -38.5t-16 -38.5t-38.5 -16t-38.5 16t-16 38.5t16 38.5t38.5 16zM854.5 709q22.5 0 38.5 -16 t16 -38.5t-16 -38.5t-38.5 -16t-38.5 16t-16 38.5t16 38.5t38.5 16z" /> +<glyph unicode="&#xe142;" d="M546 173l469 470q91 91 99 192q7 98 -52 175.5t-154 94.5q-22 4 -47 4q-34 0 -66.5 -10t-56.5 -23t-55.5 -38t-48 -41.5t-48.5 -47.5q-376 -375 -391 -390q-30 -27 -45 -41.5t-37.5 -41t-32 -46.5t-16 -47.5t-1.5 -56.5q9 -62 53.5 -95t99.5 -33q74 0 125 51l548 548 q36 36 20 75q-7 16 -21.5 26t-32.5 10q-26 0 -50 -23q-13 -12 -39 -38l-341 -338q-15 -15 -35.5 -15.5t-34.5 13.5t-14 34.5t14 34.5q327 333 361 367q35 35 67.5 51.5t78.5 16.5q14 0 29 -1q44 -8 74.5 -35.5t43.5 -68.5q14 -47 2 -96.5t-47 -84.5q-12 -11 -32 -32 t-79.5 -81t-114.5 -115t-124.5 -123.5t-123 -119.5t-96.5 -89t-57 -45q-56 -27 -120 -27q-70 0 -129 32t-93 89q-48 78 -35 173t81 163l511 511q71 72 111 96q91 55 198 55q80 0 152 -33q78 -36 129.5 -103t66.5 -154q17 -93 -11 -183.5t-94 -156.5l-482 -476 q-15 -15 -36 -16t-37 14t-17.5 34t14.5 35z" /> +<glyph unicode="&#xe143;" d="M649 949q48 68 109.5 104t121.5 38.5t118.5 -20t102.5 -64t71 -100.5t27 -123q0 -57 -33.5 -117.5t-94 -124.5t-126.5 -127.5t-150 -152.5t-146 -174q-62 85 -145.5 174t-150 152.5t-126.5 127.5t-93.5 124.5t-33.5 117.5q0 64 28 123t73 100.5t104 64t119 20 t120.5 -38.5t104.5 -104zM896 972q-33 0 -64.5 -19t-56.5 -46t-47.5 -53.5t-43.5 -45.5t-37.5 -19t-36 19t-40 45.5t-43 53.5t-54 46t-65.5 19q-67 0 -122.5 -55.5t-55.5 -132.5q0 -23 13.5 -51t46 -65t57.5 -63t76 -75l22 -22q15 -14 44 -44t50.5 -51t46 -44t41 -35t23 -12 t23.5 12t42.5 36t46 44t52.5 52t44 43q4 4 12 13q43 41 63.5 62t52 55t46 55t26 46t11.5 44q0 79 -53 133.5t-120 54.5z" /> +<glyph unicode="&#xe144;" d="M776.5 1214q93.5 0 159.5 -66l141 -141q66 -66 66 -160q0 -42 -28 -95.5t-62 -87.5l-29 -29q-31 53 -77 99l-18 18l95 95l-247 248l-389 -389l212 -212l-105 -106l-19 18l-141 141q-66 66 -66 159t66 159l283 283q65 66 158.5 66zM600 706l105 105q10 -8 19 -17l141 -141 q66 -66 66 -159t-66 -159l-283 -283q-66 -66 -159 -66t-159 66l-141 141q-66 66 -66 159.5t66 159.5l55 55q29 -55 75 -102l18 -17l-95 -95l247 -248l389 389z" /> +<glyph unicode="&#xe145;" d="M603 1200q85 0 162 -15t127 -38t79 -48t29 -46v-953q0 -41 -29.5 -70.5t-70.5 -29.5h-600q-41 0 -70.5 29.5t-29.5 70.5v953q0 21 30 46.5t81 48t129 37.5t163 15zM300 1000v-700h600v700h-600zM600 254q-43 0 -73.5 -30.5t-30.5 -73.5t30.5 -73.5t73.5 -30.5t73.5 30.5 t30.5 73.5t-30.5 73.5t-73.5 30.5z" /> +<glyph unicode="&#xe146;" d="M902 1185l283 -282q15 -15 15 -36t-14.5 -35.5t-35.5 -14.5t-35 15l-36 35l-279 -267v-300l-212 210l-308 -307l-280 -203l203 280l307 308l-210 212h300l267 279l-35 36q-15 14 -15 35t14.5 35.5t35.5 14.5t35 -15z" /> +<glyph unicode="&#xe148;" d="M700 1248v-78q38 -5 72.5 -14.5t75.5 -31.5t71 -53.5t52 -84t24 -118.5h-159q-4 36 -10.5 59t-21 45t-40 35.5t-64.5 20.5v-307l64 -13q34 -7 64 -16.5t70 -32t67.5 -52.5t47.5 -80t20 -112q0 -139 -89 -224t-244 -97v-77h-100v79q-150 16 -237 103q-40 40 -52.5 93.5 t-15.5 139.5h139q5 -77 48.5 -126t117.5 -65v335l-27 8q-46 14 -79 26.5t-72 36t-63 52t-40 72.5t-16 98q0 70 25 126t67.5 92t94.5 57t110 27v77h100zM600 754v274q-29 -4 -50 -11t-42 -21.5t-31.5 -41.5t-10.5 -65q0 -29 7 -50.5t16.5 -34t28.5 -22.5t31.5 -14t37.5 -10 q9 -3 13 -4zM700 547v-310q22 2 42.5 6.5t45 15.5t41.5 27t29 42t12 59.5t-12.5 59.5t-38 44.5t-53 31t-66.5 24.5z" /> +<glyph unicode="&#xe149;" d="M561 1197q84 0 160.5 -40t123.5 -109.5t47 -147.5h-153q0 40 -19.5 71.5t-49.5 48.5t-59.5 26t-55.5 9q-37 0 -79 -14.5t-62 -35.5q-41 -44 -41 -101q0 -26 13.5 -63t26.5 -61t37 -66q6 -9 9 -14h241v-100h-197q8 -50 -2.5 -115t-31.5 -95q-45 -62 -99 -112 q34 10 83 17.5t71 7.5q32 1 102 -16t104 -17q83 0 136 30l50 -147q-31 -19 -58 -30.5t-55 -15.5t-42 -4.5t-46 -0.5q-23 0 -76 17t-111 32.5t-96 11.5q-39 -3 -82 -16t-67 -25l-23 -11l-55 145q4 3 16 11t15.5 10.5t13 9t15.5 12t14.5 14t17.5 18.5q48 55 54 126.5 t-30 142.5h-221v100h166q-23 47 -44 104q-7 20 -12 41.5t-6 55.5t6 66.5t29.5 70.5t58.5 71q97 88 263 88z" /> +<glyph unicode="&#xe150;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM935 1184l230 -249q14 -14 10 -24.5t-25 -10.5h-150v-900h-200v900h-150q-21 0 -25 10.5t10 24.5l230 249q14 15 35 15t35 -15z" /> +<glyph unicode="&#xe151;" d="M1000 700h-100v100h-100v-100h-100v500h300v-500zM400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM801 1100v-200h100v200h-100zM1000 350l-200 -250h200v-100h-300v150l200 250h-200v100h300v-150z " /> +<glyph unicode="&#xe152;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1000 1050l-200 -250h200v-100h-300v150l200 250h-200v100h300v-150zM1000 0h-100v100h-100v-100h-100v500h300v-500zM801 400v-200h100v200h-100z " /> +<glyph unicode="&#xe153;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1000 700h-100v400h-100v100h200v-500zM1100 0h-100v100h-200v400h300v-500zM901 400v-200h100v200h-100z" /> +<glyph unicode="&#xe154;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1100 700h-100v100h-200v400h300v-500zM901 1100v-200h100v200h-100zM1000 0h-100v400h-100v100h200v-500z" /> +<glyph unicode="&#xe155;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM900 1000h-200v200h200v-200zM1000 700h-300v200h300v-200zM1100 400h-400v200h400v-200zM1200 100h-500v200h500v-200z" /> +<glyph unicode="&#xe156;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1200 1000h-500v200h500v-200zM1100 700h-400v200h400v-200zM1000 400h-300v200h300v-200zM900 100h-200v200h200v-200z" /> +<glyph unicode="&#xe157;" d="M350 1100h400q162 0 256 -93.5t94 -256.5v-400q0 -165 -93.5 -257.5t-256.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5z" /> +<glyph unicode="&#xe158;" d="M350 1100h400q165 0 257.5 -92.5t92.5 -257.5v-400q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-163 0 -256.5 92.5t-93.5 257.5v400q0 163 94 256.5t256 93.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5zM440 770l253 -190q17 -12 17 -30t-17 -30l-253 -190q-16 -12 -28 -6.5t-12 26.5v400q0 21 12 26.5t28 -6.5z" /> +<glyph unicode="&#xe159;" d="M350 1100h400q163 0 256.5 -94t93.5 -256v-400q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 163 92.5 256.5t257.5 93.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5zM350 700h400q21 0 26.5 -12t-6.5 -28l-190 -253q-12 -17 -30 -17t-30 17l-190 253q-12 16 -6.5 28t26.5 12z" /> +<glyph unicode="&#xe160;" d="M350 1100h400q165 0 257.5 -92.5t92.5 -257.5v-400q0 -163 -92.5 -256.5t-257.5 -93.5h-400q-163 0 -256.5 94t-93.5 256v400q0 165 92.5 257.5t257.5 92.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5zM580 693l190 -253q12 -16 6.5 -28t-26.5 -12h-400q-21 0 -26.5 12t6.5 28l190 253q12 17 30 17t30 -17z" /> +<glyph unicode="&#xe161;" d="M550 1100h400q165 0 257.5 -92.5t92.5 -257.5v-400q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h450q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5h-450q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM338 867l324 -284q16 -14 16 -33t-16 -33l-324 -284q-16 -14 -27 -9t-11 26v150h-250q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5h250v150q0 21 11 26t27 -9z" /> +<glyph unicode="&#xe162;" d="M793 1182l9 -9q8 -10 5 -27q-3 -11 -79 -225.5t-78 -221.5l300 1q24 0 32.5 -17.5t-5.5 -35.5q-1 0 -133.5 -155t-267 -312.5t-138.5 -162.5q-12 -15 -26 -15h-9l-9 8q-9 11 -4 32q2 9 42 123.5t79 224.5l39 110h-302q-23 0 -31 19q-10 21 6 41q75 86 209.5 237.5 t228 257t98.5 111.5q9 16 25 16h9z" /> +<glyph unicode="&#xe163;" d="M350 1100h400q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-450q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h450q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400 q0 165 92.5 257.5t257.5 92.5zM938 867l324 -284q16 -14 16 -33t-16 -33l-324 -284q-16 -14 -27 -9t-11 26v150h-250q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5h250v150q0 21 11 26t27 -9z" /> +<glyph unicode="&#xe164;" d="M750 1200h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -10.5 -25t-24.5 10l-109 109l-312 -312q-15 -15 -35.5 -15t-35.5 15l-141 141q-15 15 -15 35.5t15 35.5l312 312l-109 109q-14 14 -10 24.5t25 10.5zM456 900h-156q-41 0 -70.5 -29.5t-29.5 -70.5v-500 q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v148l200 200v-298q0 -165 -93.5 -257.5t-256.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5h300z" /> +<glyph unicode="&#xe165;" d="M600 1186q119 0 227.5 -46.5t187 -125t125 -187t46.5 -227.5t-46.5 -227.5t-125 -187t-187 -125t-227.5 -46.5t-227.5 46.5t-187 125t-125 187t-46.5 227.5t46.5 227.5t125 187t187 125t227.5 46.5zM600 1022q-115 0 -212 -56.5t-153.5 -153.5t-56.5 -212t56.5 -212 t153.5 -153.5t212 -56.5t212 56.5t153.5 153.5t56.5 212t-56.5 212t-153.5 153.5t-212 56.5zM600 794q80 0 137 -57t57 -137t-57 -137t-137 -57t-137 57t-57 137t57 137t137 57z" /> +<glyph unicode="&#xe166;" d="M450 1200h200q21 0 35.5 -14.5t14.5 -35.5v-350h245q20 0 25 -11t-9 -26l-383 -426q-14 -15 -33.5 -15t-32.5 15l-379 426q-13 15 -8.5 26t25.5 11h250v350q0 21 14.5 35.5t35.5 14.5zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5z M900 200v-50h100v50h-100z" /> +<glyph unicode="&#xe167;" d="M583 1182l378 -435q14 -15 9 -31t-26 -16h-244v-250q0 -20 -17 -35t-39 -15h-200q-20 0 -32 14.5t-12 35.5v250h-250q-20 0 -25.5 16.5t8.5 31.5l383 431q14 16 33.5 17t33.5 -14zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5z M900 200v-50h100v50h-100z" /> +<glyph unicode="&#xe168;" d="M396 723l369 369q7 7 17.5 7t17.5 -7l139 -139q7 -8 7 -18.5t-7 -17.5l-525 -525q-7 -8 -17.5 -8t-17.5 8l-292 291q-7 8 -7 18t7 18l139 139q8 7 18.5 7t17.5 -7zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5zM900 200v-50h100v50 h-100z" /> +<glyph unicode="&#xe169;" d="M135 1023l142 142q14 14 35 14t35 -14l77 -77l-212 -212l-77 76q-14 15 -14 36t14 35zM655 855l210 210q14 14 24.5 10t10.5 -25l-2 -599q-1 -20 -15.5 -35t-35.5 -15l-597 -1q-21 0 -25 10.5t10 24.5l208 208l-154 155l212 212zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5 v-250h-1100v250q0 21 14.5 35.5t35.5 14.5zM900 200v-50h100v50h-100z" /> +<glyph unicode="&#xe170;" d="M350 1200l599 -2q20 -1 35 -15.5t15 -35.5l1 -597q0 -21 -10.5 -25t-24.5 10l-208 208l-155 -154l-212 212l155 154l-210 210q-14 14 -10 24.5t25 10.5zM524 512l-76 -77q-15 -14 -36 -14t-35 14l-142 142q-14 14 -14 35t14 35l77 77zM50 300h1000q21 0 35.5 -14.5 t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5zM900 200v-50h100v50h-100z" /> +<glyph unicode="&#xe171;" d="M1200 103l-483 276l-314 -399v423h-399l1196 796v-1096zM483 424v-230l683 953z" /> +<glyph unicode="&#xe172;" d="M1100 1000v-850q0 -21 -14.5 -35.5t-35.5 -14.5h-150v400h-700v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200z" /> +<glyph unicode="&#xe173;" d="M1100 1000l-2 -149l-299 -299l-95 95q-9 9 -21.5 9t-21.5 -9l-149 -147h-312v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM1132 638l106 -106q7 -7 7 -17.5t-7 -17.5l-420 -421q-8 -7 -18 -7 t-18 7l-202 203q-8 7 -8 17.5t8 17.5l106 106q7 8 17.5 8t17.5 -8l79 -79l297 297q7 7 17.5 7t17.5 -7z" /> +<glyph unicode="&#xe174;" d="M1100 1000v-269l-103 -103l-134 134q-15 15 -33.5 16.5t-34.5 -12.5l-266 -266h-329v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM1202 572l70 -70q15 -15 15 -35.5t-15 -35.5l-131 -131 l131 -131q15 -15 15 -35.5t-15 -35.5l-70 -70q-15 -15 -35.5 -15t-35.5 15l-131 131l-131 -131q-15 -15 -35.5 -15t-35.5 15l-70 70q-15 15 -15 35.5t15 35.5l131 131l-131 131q-15 15 -15 35.5t15 35.5l70 70q15 15 35.5 15t35.5 -15l131 -131l131 131q15 15 35.5 15 t35.5 -15z" /> +<glyph unicode="&#xe175;" d="M1100 1000v-300h-350q-21 0 -35.5 -14.5t-14.5 -35.5v-150h-500v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM850 600h100q21 0 35.5 -14.5t14.5 -35.5v-250h150q21 0 25 -10.5t-10 -24.5 l-230 -230q-14 -14 -35 -14t-35 14l-230 230q-14 14 -10 24.5t25 10.5h150v250q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe176;" d="M1100 1000v-400l-165 165q-14 15 -35 15t-35 -15l-263 -265h-402v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM935 565l230 -229q14 -15 10 -25.5t-25 -10.5h-150v-250q0 -20 -14.5 -35 t-35.5 -15h-100q-21 0 -35.5 15t-14.5 35v250h-150q-21 0 -25 10.5t10 25.5l230 229q14 15 35 15t35 -15z" /> +<glyph unicode="&#xe177;" d="M50 1100h1100q21 0 35.5 -14.5t14.5 -35.5v-150h-1200v150q0 21 14.5 35.5t35.5 14.5zM1200 800v-550q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v550h1200zM100 500v-200h400v200h-400z" /> +<glyph unicode="&#xe178;" d="M935 1165l248 -230q14 -14 14 -35t-14 -35l-248 -230q-14 -14 -24.5 -10t-10.5 25v150h-400v200h400v150q0 21 10.5 25t24.5 -10zM200 800h-50q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h50v-200zM400 800h-100v200h100v-200zM18 435l247 230 q14 14 24.5 10t10.5 -25v-150h400v-200h-400v-150q0 -21 -10.5 -25t-24.5 10l-247 230q-15 14 -15 35t15 35zM900 300h-100v200h100v-200zM1000 500h51q20 0 34.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-34.5 -14.5h-51v200z" /> +<glyph unicode="&#xe179;" d="M862 1073l276 116q25 18 43.5 8t18.5 -41v-1106q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v397q-4 1 -11 5t-24 17.5t-30 29t-24 42t-11 56.5v359q0 31 18.5 65t43.5 52zM550 1200q22 0 34.5 -12.5t14.5 -24.5l1 -13v-450q0 -28 -10.5 -59.5 t-25 -56t-29 -45t-25.5 -31.5l-10 -11v-447q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v447q-4 4 -11 11.5t-24 30.5t-30 46t-24 55t-11 60v450q0 2 0.5 5.5t4 12t8.5 15t14.5 12t22.5 5.5q20 0 32.5 -12.5t14.5 -24.5l3 -13v-350h100v350v5.5t2.5 12 t7 15t15 12t25.5 5.5q23 0 35.5 -12.5t13.5 -24.5l1 -13v-350h100v350q0 2 0.5 5.5t3 12t7 15t15 12t24.5 5.5z" /> +<glyph unicode="&#xe180;" d="M1200 1100v-56q-4 0 -11 -0.5t-24 -3t-30 -7.5t-24 -15t-11 -24v-888q0 -22 25 -34.5t50 -13.5l25 -2v-56h-400v56q75 0 87.5 6.5t12.5 43.5v394h-500v-394q0 -37 12.5 -43.5t87.5 -6.5v-56h-400v56q4 0 11 0.5t24 3t30 7.5t24 15t11 24v888q0 22 -25 34.5t-50 13.5 l-25 2v56h400v-56q-75 0 -87.5 -6.5t-12.5 -43.5v-394h500v394q0 37 -12.5 43.5t-87.5 6.5v56h400z" /> +<glyph unicode="&#xe181;" d="M675 1000h375q21 0 35.5 -14.5t14.5 -35.5v-150h-105l-295 -98v98l-200 200h-400l100 100h375zM100 900h300q41 0 70.5 -29.5t29.5 -70.5v-500q0 -41 -29.5 -70.5t-70.5 -29.5h-300q-41 0 -70.5 29.5t-29.5 70.5v500q0 41 29.5 70.5t70.5 29.5zM100 800v-200h300v200 h-300zM1100 535l-400 -133v163l400 133v-163zM100 500v-200h300v200h-300zM1100 398v-248q0 -21 -14.5 -35.5t-35.5 -14.5h-375l-100 -100h-375l-100 100h400l200 200h105z" /> +<glyph unicode="&#xe182;" d="M17 1007l162 162q17 17 40 14t37 -22l139 -194q14 -20 11 -44.5t-20 -41.5l-119 -118q102 -142 228 -268t267 -227l119 118q17 17 42.5 19t44.5 -12l192 -136q19 -14 22.5 -37.5t-13.5 -40.5l-163 -162q-3 -1 -9.5 -1t-29.5 2t-47.5 6t-62.5 14.5t-77.5 26.5t-90 42.5 t-101.5 60t-111 83t-119 108.5q-74 74 -133.5 150.5t-94.5 138.5t-60 119.5t-34.5 100t-15 74.5t-4.5 48z" /> +<glyph unicode="&#xe183;" d="M600 1100q92 0 175 -10.5t141.5 -27t108.5 -36.5t81.5 -40t53.5 -37t31 -27l9 -10v-200q0 -21 -14.5 -33t-34.5 -9l-202 34q-20 3 -34.5 20t-14.5 38v146q-141 24 -300 24t-300 -24v-146q0 -21 -14.5 -38t-34.5 -20l-202 -34q-20 -3 -34.5 9t-14.5 33v200q3 4 9.5 10.5 t31 26t54 37.5t80.5 39.5t109 37.5t141 26.5t175 10.5zM600 795q56 0 97 -9.5t60 -23.5t30 -28t12 -24l1 -10v-50l365 -303q14 -15 24.5 -40t10.5 -45v-212q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v212q0 20 10.5 45t24.5 40l365 303v50 q0 4 1 10.5t12 23t30 29t60 22.5t97 10z" /> +<glyph unicode="&#xe184;" d="M1100 700l-200 -200h-600l-200 200v500h200v-200h200v200h200v-200h200v200h200v-500zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-12l137 -100h-950l137 100h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5 t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe185;" d="M700 1100h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-1000h300v1000q0 41 -29.5 70.5t-70.5 29.5zM1100 800h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-700h300v700q0 41 -29.5 70.5t-70.5 29.5zM400 0h-300v400q0 41 29.5 70.5t70.5 29.5h100q41 0 70.5 -29.5t29.5 -70.5v-400z " /> +<glyph unicode="&#xe186;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 700h-200v-100h200v-300h-300v100h200v100h-200v300h300v-100zM900 700v-300l-100 -100h-200v500h200z M700 700v-300h100v300h-100z" /> +<glyph unicode="&#xe187;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 300h-100v200h-100v-200h-100v500h100v-200h100v200h100v-500zM900 700v-300l-100 -100h-200v500h200z M700 700v-300h100v300h-100z" /> +<glyph unicode="&#xe188;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 700h-200v-300h200v-100h-300v500h300v-100zM900 700h-200v-300h200v-100h-300v500h300v-100z" /> +<glyph unicode="&#xe189;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 400l-300 150l300 150v-300zM900 550l-300 -150v300z" /> +<glyph unicode="&#xe190;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM900 300h-700v500h700v-500zM800 700h-130q-38 0 -66.5 -43t-28.5 -108t27 -107t68 -42h130v300zM300 700v-300 h130q41 0 68 42t27 107t-28.5 108t-66.5 43h-130z" /> +<glyph unicode="&#xe191;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 700h-200v-100h200v-300h-300v100h200v100h-200v300h300v-100zM900 300h-100v400h-100v100h200v-500z M700 300h-100v100h100v-100z" /> +<glyph unicode="&#xe192;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM300 700h200v-400h-300v500h100v-100zM900 300h-100v400h-100v100h200v-500zM300 600v-200h100v200h-100z M700 300h-100v100h100v-100z" /> +<glyph unicode="&#xe193;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 500l-199 -200h-100v50l199 200v150h-200v100h300v-300zM900 300h-100v400h-100v100h200v-500zM701 300h-100 v100h100v-100z" /> +<glyph unicode="&#xe194;" d="M600 1191q120 0 229.5 -47t188.5 -126t126 -188.5t47 -229.5t-47 -229.5t-126 -188.5t-188.5 -126t-229.5 -47t-229.5 47t-188.5 126t-126 188.5t-47 229.5t47 229.5t126 188.5t188.5 126t229.5 47zM600 1021q-114 0 -211 -56.5t-153.5 -153.5t-56.5 -211t56.5 -211 t153.5 -153.5t211 -56.5t211 56.5t153.5 153.5t56.5 211t-56.5 211t-153.5 153.5t-211 56.5zM800 700h-300v-200h300v-100h-300l-100 100v200l100 100h300v-100z" /> +<glyph unicode="&#xe195;" d="M600 1191q120 0 229.5 -47t188.5 -126t126 -188.5t47 -229.5t-47 -229.5t-126 -188.5t-188.5 -126t-229.5 -47t-229.5 47t-188.5 126t-126 188.5t-47 229.5t47 229.5t126 188.5t188.5 126t229.5 47zM600 1021q-114 0 -211 -56.5t-153.5 -153.5t-56.5 -211t56.5 -211 t153.5 -153.5t211 -56.5t211 56.5t153.5 153.5t56.5 211t-56.5 211t-153.5 153.5t-211 56.5zM800 700v-100l-50 -50l100 -100v-50h-100l-100 100h-150v-100h-100v400h300zM500 700v-100h200v100h-200z" /> +<glyph unicode="&#xe197;" d="M503 1089q110 0 200.5 -59.5t134.5 -156.5q44 14 90 14q120 0 205 -86.5t85 -207t-85 -207t-205 -86.5h-128v250q0 21 -14.5 35.5t-35.5 14.5h-300q-21 0 -35.5 -14.5t-14.5 -35.5v-250h-222q-80 0 -136 57.5t-56 136.5q0 69 43 122.5t108 67.5q-2 19 -2 37q0 100 49 185 t134 134t185 49zM525 500h150q10 0 17.5 -7.5t7.5 -17.5v-275h137q21 0 26 -11.5t-8 -27.5l-223 -244q-13 -16 -32 -16t-32 16l-223 244q-13 16 -8 27.5t26 11.5h137v275q0 10 7.5 17.5t17.5 7.5z" /> +<glyph unicode="&#xe198;" d="M502 1089q110 0 201 -59.5t135 -156.5q43 15 89 15q121 0 206 -86.5t86 -206.5q0 -99 -60 -181t-150 -110l-378 360q-13 16 -31.5 16t-31.5 -16l-381 -365h-9q-79 0 -135.5 57.5t-56.5 136.5q0 69 43 122.5t108 67.5q-2 19 -2 38q0 100 49 184.5t133.5 134t184.5 49.5z M632 467l223 -228q13 -16 8 -27.5t-26 -11.5h-137v-275q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v275h-137q-21 0 -26 11.5t8 27.5q199 204 223 228q19 19 31.5 19t32.5 -19z" /> +<glyph unicode="&#xe199;" d="M700 100v100h400l-270 300h170l-270 300h170l-300 333l-300 -333h170l-270 -300h170l-270 -300h400v-100h-50q-21 0 -35.5 -14.5t-14.5 -35.5v-50h400v50q0 21 -14.5 35.5t-35.5 14.5h-50z" /> +<glyph unicode="&#xe200;" d="M600 1179q94 0 167.5 -56.5t99.5 -145.5q89 -6 150.5 -71.5t61.5 -155.5q0 -61 -29.5 -112.5t-79.5 -82.5q9 -29 9 -55q0 -74 -52.5 -126.5t-126.5 -52.5q-55 0 -100 30v-251q21 0 35.5 -14.5t14.5 -35.5v-50h-300v50q0 21 14.5 35.5t35.5 14.5v251q-45 -30 -100 -30 q-74 0 -126.5 52.5t-52.5 126.5q0 18 4 38q-47 21 -75.5 65t-28.5 97q0 74 52.5 126.5t126.5 52.5q5 0 23 -2q0 2 -1 10t-1 13q0 116 81.5 197.5t197.5 81.5z" /> +<glyph unicode="&#xe201;" d="M1010 1010q111 -111 150.5 -260.5t0 -299t-150.5 -260.5q-83 -83 -191.5 -126.5t-218.5 -43.5t-218.5 43.5t-191.5 126.5q-111 111 -150.5 260.5t0 299t150.5 260.5q83 83 191.5 126.5t218.5 43.5t218.5 -43.5t191.5 -126.5zM476 1065q-4 0 -8 -1q-121 -34 -209.5 -122.5 t-122.5 -209.5q-4 -12 2.5 -23t18.5 -14l36 -9q3 -1 7 -1q23 0 29 22q27 96 98 166q70 71 166 98q11 3 17.5 13.5t3.5 22.5l-9 35q-3 13 -14 19q-7 4 -15 4zM512 920q-4 0 -9 -2q-80 -24 -138.5 -82.5t-82.5 -138.5q-4 -13 2 -24t19 -14l34 -9q4 -1 8 -1q22 0 28 21 q18 58 58.5 98.5t97.5 58.5q12 3 18 13.5t3 21.5l-9 35q-3 12 -14 19q-7 4 -15 4zM719.5 719.5q-49.5 49.5 -119.5 49.5t-119.5 -49.5t-49.5 -119.5t49.5 -119.5t119.5 -49.5t119.5 49.5t49.5 119.5t-49.5 119.5zM855 551q-22 0 -28 -21q-18 -58 -58.5 -98.5t-98.5 -57.5 q-11 -4 -17 -14.5t-3 -21.5l9 -35q3 -12 14 -19q7 -4 15 -4q4 0 9 2q80 24 138.5 82.5t82.5 138.5q4 13 -2.5 24t-18.5 14l-34 9q-4 1 -8 1zM1000 515q-23 0 -29 -22q-27 -96 -98 -166q-70 -71 -166 -98q-11 -3 -17.5 -13.5t-3.5 -22.5l9 -35q3 -13 14 -19q7 -4 15 -4 q4 0 8 1q121 34 209.5 122.5t122.5 209.5q4 12 -2.5 23t-18.5 14l-36 9q-3 1 -7 1z" /> +<glyph unicode="&#xe202;" d="M700 800h300v-380h-180v200h-340v-200h-380v755q0 10 7.5 17.5t17.5 7.5h575v-400zM1000 900h-200v200zM700 300h162l-212 -212l-212 212h162v200h100v-200zM520 0h-395q-10 0 -17.5 7.5t-7.5 17.5v395zM1000 220v-195q0 -10 -7.5 -17.5t-17.5 -7.5h-195z" /> +<glyph unicode="&#xe203;" d="M700 800h300v-520l-350 350l-550 -550v1095q0 10 7.5 17.5t17.5 7.5h575v-400zM1000 900h-200v200zM862 200h-162v-200h-100v200h-162l212 212zM480 0h-355q-10 0 -17.5 7.5t-7.5 17.5v55h380v-80zM1000 80v-55q0 -10 -7.5 -17.5t-17.5 -7.5h-155v80h180z" /> +<glyph unicode="&#xe204;" d="M1162 800h-162v-200h100l100 -100h-300v300h-162l212 212zM200 800h200q27 0 40 -2t29.5 -10.5t23.5 -30t7 -57.5h300v-100h-600l-200 -350v450h100q0 36 7 57.5t23.5 30t29.5 10.5t40 2zM800 400h240l-240 -400h-800l300 500h500v-100z" /> +<glyph unicode="&#xe205;" d="M650 1100h100q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h50v50q0 21 14.5 35.5t35.5 14.5zM1000 850v150q41 0 70.5 -29.5t29.5 -70.5v-800 q0 -41 -29.5 -70.5t-70.5 -29.5h-600q-1 0 -20 4l246 246l-326 326v324q0 41 29.5 70.5t70.5 29.5v-150q0 -62 44 -106t106 -44h300q62 0 106 44t44 106zM412 250l-212 -212v162h-200v100h200v162z" /> +<glyph unicode="&#xe206;" d="M450 1100h100q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h50v50q0 21 14.5 35.5t35.5 14.5zM800 850v150q41 0 70.5 -29.5t29.5 -70.5v-500 h-200v-300h200q0 -36 -7 -57.5t-23.5 -30t-29.5 -10.5t-40 -2h-600q-41 0 -70.5 29.5t-29.5 70.5v800q0 41 29.5 70.5t70.5 29.5v-150q0 -62 44 -106t106 -44h300q62 0 106 44t44 106zM1212 250l-212 -212v162h-200v100h200v162z" /> +<glyph unicode="&#xe209;" d="M658 1197l637 -1104q23 -38 7 -65.5t-60 -27.5h-1276q-44 0 -60 27.5t7 65.5l637 1104q22 39 54 39t54 -39zM704 800h-208q-20 0 -32 -14.5t-8 -34.5l58 -302q4 -20 21.5 -34.5t37.5 -14.5h54q20 0 37.5 14.5t21.5 34.5l58 302q4 20 -8 34.5t-32 14.5zM500 300v-100h200 v100h-200z" /> +<glyph unicode="&#xe210;" d="M425 1100h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM425 800h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5 t17.5 7.5zM825 800h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM25 500h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150 q0 10 7.5 17.5t17.5 7.5zM425 500h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM825 500h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5 v150q0 10 7.5 17.5t17.5 7.5zM25 200h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM425 200h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5 t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM825 200h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5z" /> +<glyph unicode="&#xe211;" d="M700 1200h100v-200h-100v-100h350q62 0 86.5 -39.5t-3.5 -94.5l-66 -132q-41 -83 -81 -134h-772q-40 51 -81 134l-66 132q-28 55 -3.5 94.5t86.5 39.5h350v100h-100v200h100v100h200v-100zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-12l137 -100 h-950l138 100h-13q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe212;" d="M600 1300q40 0 68.5 -29.5t28.5 -70.5h-194q0 41 28.5 70.5t68.5 29.5zM443 1100h314q18 -37 18 -75q0 -8 -3 -25h328q41 0 44.5 -16.5t-30.5 -38.5l-175 -145h-678l-178 145q-34 22 -29 38.5t46 16.5h328q-3 17 -3 25q0 38 18 75zM250 700h700q21 0 35.5 -14.5 t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-150v-200l275 -200h-950l275 200v200h-150q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe213;" d="M600 1181q75 0 128 -53t53 -128t-53 -128t-128 -53t-128 53t-53 128t53 128t128 53zM602 798h46q34 0 55.5 -28.5t21.5 -86.5q0 -76 39 -183h-324q39 107 39 183q0 58 21.5 86.5t56.5 28.5h45zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-13 l138 -100h-950l137 100h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe214;" d="M600 1300q47 0 92.5 -53.5t71 -123t25.5 -123.5q0 -78 -55.5 -133.5t-133.5 -55.5t-133.5 55.5t-55.5 133.5q0 62 34 143l144 -143l111 111l-163 163q34 26 63 26zM602 798h46q34 0 55.5 -28.5t21.5 -86.5q0 -76 39 -183h-324q39 107 39 183q0 58 21.5 86.5t56.5 28.5h45 zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-13l138 -100h-950l137 100h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe215;" d="M600 1200l300 -161v-139h-300q0 -57 18.5 -108t50 -91.5t63 -72t70 -67.5t57.5 -61h-530q-60 83 -90.5 177.5t-30.5 178.5t33 164.5t87.5 139.5t126 96.5t145.5 41.5v-98zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-13l138 -100h-950l137 100 h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe216;" d="M600 1300q41 0 70.5 -29.5t29.5 -70.5v-78q46 -26 73 -72t27 -100v-50h-400v50q0 54 27 100t73 72v78q0 41 29.5 70.5t70.5 29.5zM400 800h400q54 0 100 -27t72 -73h-172v-100h200v-100h-200v-100h200v-100h-200v-100h200q0 -83 -58.5 -141.5t-141.5 -58.5h-400 q-83 0 -141.5 58.5t-58.5 141.5v400q0 83 58.5 141.5t141.5 58.5z" /> +<glyph unicode="&#xe218;" d="M150 1100h900q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v500q0 21 14.5 35.5t35.5 14.5zM125 400h950q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-283l224 -224q13 -13 13 -31.5t-13 -32 t-31.5 -13.5t-31.5 13l-88 88h-524l-87 -88q-13 -13 -32 -13t-32 13.5t-13 32t13 31.5l224 224h-289q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM541 300l-100 -100h324l-100 100h-124z" /> +<glyph unicode="&#xe219;" d="M200 1100h800q83 0 141.5 -58.5t58.5 -141.5v-200h-100q0 41 -29.5 70.5t-70.5 29.5h-250q-41 0 -70.5 -29.5t-29.5 -70.5h-100q0 41 -29.5 70.5t-70.5 29.5h-250q-41 0 -70.5 -29.5t-29.5 -70.5h-100v200q0 83 58.5 141.5t141.5 58.5zM100 600h1000q41 0 70.5 -29.5 t29.5 -70.5v-300h-1200v300q0 41 29.5 70.5t70.5 29.5zM300 100v-50q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v50h200zM1100 100v-50q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v50h200z" /> +<glyph unicode="&#xe221;" d="M480 1165l682 -683q31 -31 31 -75.5t-31 -75.5l-131 -131h-481l-517 518q-32 31 -32 75.5t32 75.5l295 296q31 31 75.5 31t76.5 -31zM108 794l342 -342l303 304l-341 341zM250 100h800q21 0 35.5 -14.5t14.5 -35.5v-50h-900v50q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe223;" d="M1057 647l-189 506q-8 19 -27.5 33t-40.5 14h-400q-21 0 -40.5 -14t-27.5 -33l-189 -506q-8 -19 1.5 -33t30.5 -14h625v-150q0 -21 14.5 -35.5t35.5 -14.5t35.5 14.5t14.5 35.5v150h125q21 0 30.5 14t1.5 33zM897 0h-595v50q0 21 14.5 35.5t35.5 14.5h50v50 q0 21 14.5 35.5t35.5 14.5h48v300h200v-300h47q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-50z" /> +<glyph unicode="&#xe224;" d="M900 800h300v-575q0 -10 -7.5 -17.5t-17.5 -7.5h-375v591l-300 300v84q0 10 7.5 17.5t17.5 7.5h375v-400zM1200 900h-200v200zM400 600h300v-575q0 -10 -7.5 -17.5t-17.5 -7.5h-650q-10 0 -17.5 7.5t-7.5 17.5v950q0 10 7.5 17.5t17.5 7.5h375v-400zM700 700h-200v200z " /> +<glyph unicode="&#xe225;" d="M484 1095h195q75 0 146 -32.5t124 -86t89.5 -122.5t48.5 -142q18 -14 35 -20q31 -10 64.5 6.5t43.5 48.5q10 34 -15 71q-19 27 -9 43q5 8 12.5 11t19 -1t23.5 -16q41 -44 39 -105q-3 -63 -46 -106.5t-104 -43.5h-62q-7 -55 -35 -117t-56 -100l-39 -234q-3 -20 -20 -34.5 t-38 -14.5h-100q-21 0 -33 14.5t-9 34.5l12 70q-49 -14 -91 -14h-195q-24 0 -65 8l-11 -64q-3 -20 -20 -34.5t-38 -14.5h-100q-21 0 -33 14.5t-9 34.5l26 157q-84 74 -128 175l-159 53q-19 7 -33 26t-14 40v50q0 21 14.5 35.5t35.5 14.5h124q11 87 56 166l-111 95 q-16 14 -12.5 23.5t24.5 9.5h203q116 101 250 101zM675 1000h-250q-10 0 -17.5 -7.5t-7.5 -17.5v-50q0 -10 7.5 -17.5t17.5 -7.5h250q10 0 17.5 7.5t7.5 17.5v50q0 10 -7.5 17.5t-17.5 7.5z" /> +<glyph unicode="&#xe226;" d="M641 900l423 247q19 8 42 2.5t37 -21.5l32 -38q14 -15 12.5 -36t-17.5 -34l-139 -120h-390zM50 1100h106q67 0 103 -17t66 -71l102 -212h823q21 0 35.5 -14.5t14.5 -35.5v-50q0 -21 -14 -40t-33 -26l-737 -132q-23 -4 -40 6t-26 25q-42 67 -100 67h-300q-62 0 -106 44 t-44 106v200q0 62 44 106t106 44zM173 928h-80q-19 0 -28 -14t-9 -35v-56q0 -51 42 -51h134q16 0 21.5 8t5.5 24q0 11 -16 45t-27 51q-18 28 -43 28zM550 727q-32 0 -54.5 -22.5t-22.5 -54.5t22.5 -54.5t54.5 -22.5t54.5 22.5t22.5 54.5t-22.5 54.5t-54.5 22.5zM130 389 l152 130q18 19 34 24t31 -3.5t24.5 -17.5t25.5 -28q28 -35 50.5 -51t48.5 -13l63 5l48 -179q13 -61 -3.5 -97.5t-67.5 -79.5l-80 -69q-47 -40 -109 -35.5t-103 51.5l-130 151q-40 47 -35.5 109.5t51.5 102.5zM380 377l-102 -88q-31 -27 2 -65l37 -43q13 -15 27.5 -19.5 t31.5 6.5l61 53q19 16 14 49q-2 20 -12 56t-17 45q-11 12 -19 14t-23 -8z" /> +<glyph unicode="&#xe227;" d="M625 1200h150q10 0 17.5 -7.5t7.5 -17.5v-109q79 -33 131 -87.5t53 -128.5q1 -46 -15 -84.5t-39 -61t-46 -38t-39 -21.5l-17 -6q6 0 15 -1.5t35 -9t50 -17.5t53 -30t50 -45t35.5 -64t14.5 -84q0 -59 -11.5 -105.5t-28.5 -76.5t-44 -51t-49.5 -31.5t-54.5 -16t-49.5 -6.5 t-43.5 -1v-75q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v75h-100v-75q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v75h-175q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h75v600h-75q-10 0 -17.5 7.5t-7.5 17.5v150 q0 10 7.5 17.5t17.5 7.5h175v75q0 10 7.5 17.5t17.5 7.5h150q10 0 17.5 -7.5t7.5 -17.5v-75h100v75q0 10 7.5 17.5t17.5 7.5zM400 900v-200h263q28 0 48.5 10.5t30 25t15 29t5.5 25.5l1 10q0 4 -0.5 11t-6 24t-15 30t-30 24t-48.5 11h-263zM400 500v-200h363q28 0 48.5 10.5 t30 25t15 29t5.5 25.5l1 10q0 4 -0.5 11t-6 24t-15 30t-30 24t-48.5 11h-363z" /> +<glyph unicode="&#xe230;" d="M212 1198h780q86 0 147 -61t61 -147v-416q0 -51 -18 -142.5t-36 -157.5l-18 -66q-29 -87 -93.5 -146.5t-146.5 -59.5h-572q-82 0 -147 59t-93 147q-8 28 -20 73t-32 143.5t-20 149.5v416q0 86 61 147t147 61zM600 1045q-70 0 -132.5 -11.5t-105.5 -30.5t-78.5 -41.5 t-57 -45t-36 -41t-20.5 -30.5l-6 -12l156 -243h560l156 243q-2 5 -6 12.5t-20 29.5t-36.5 42t-57 44.5t-79 42t-105 29.5t-132.5 12zM762 703h-157l195 261z" /> +<glyph unicode="&#xe231;" d="M475 1300h150q103 0 189 -86t86 -189v-500q0 -41 -42 -83t-83 -42h-450q-41 0 -83 42t-42 83v500q0 103 86 189t189 86zM700 300v-225q0 -21 -27 -48t-48 -27h-150q-21 0 -48 27t-27 48v225h300z" /> +<glyph unicode="&#xe232;" d="M475 1300h96q0 -150 89.5 -239.5t239.5 -89.5v-446q0 -41 -42 -83t-83 -42h-450q-41 0 -83 42t-42 83v500q0 103 86 189t189 86zM700 300v-225q0 -21 -27 -48t-48 -27h-150q-21 0 -48 27t-27 48v225h300z" /> +<glyph unicode="&#xe233;" d="M1294 767l-638 -283l-378 170l-78 -60v-224l100 -150v-199l-150 148l-150 -149v200l100 150v250q0 4 -0.5 10.5t0 9.5t1 8t3 8t6.5 6l47 40l-147 65l642 283zM1000 380l-350 -166l-350 166v147l350 -165l350 165v-147z" /> +<glyph unicode="&#xe234;" d="M250 800q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM650 800q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM1050 800q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44z" /> +<glyph unicode="&#xe235;" d="M550 1100q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM550 700q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM550 300q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44z" /> +<glyph unicode="&#xe236;" d="M125 1100h950q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-950q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM125 700h950q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-950q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5 t17.5 7.5zM125 300h950q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-950q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5z" /> +<glyph unicode="&#xe237;" d="M350 1200h500q162 0 256 -93.5t94 -256.5v-500q0 -165 -93.5 -257.5t-256.5 -92.5h-500q-165 0 -257.5 92.5t-92.5 257.5v500q0 165 92.5 257.5t257.5 92.5zM900 1000h-600q-41 0 -70.5 -29.5t-29.5 -70.5v-600q0 -41 29.5 -70.5t70.5 -29.5h600q41 0 70.5 29.5 t29.5 70.5v600q0 41 -29.5 70.5t-70.5 29.5zM350 900h500q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -14.5 -35.5t-35.5 -14.5h-500q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 14.5 35.5t35.5 14.5zM400 800v-200h400v200h-400z" /> +<glyph unicode="&#xe238;" d="M150 1100h1000q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-200h50q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-200h50q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-200h50q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5 t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5h50v200h-50q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5h50v200h-50q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5h50v200h-50q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe239;" d="M650 1187q87 -67 118.5 -156t0 -178t-118.5 -155q-87 66 -118.5 155t0 178t118.5 156zM300 800q124 0 212 -88t88 -212q-124 0 -212 88t-88 212zM1000 800q0 -124 -88 -212t-212 -88q0 124 88 212t212 88zM300 500q124 0 212 -88t88 -212q-124 0 -212 88t-88 212z M1000 500q0 -124 -88 -212t-212 -88q0 124 88 212t212 88zM700 199v-144q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v142q40 -4 43 -4q17 0 57 6z" /> +<glyph unicode="&#xe240;" d="M745 878l69 19q25 6 45 -12l298 -295q11 -11 15 -26.5t-2 -30.5q-5 -14 -18 -23.5t-28 -9.5h-8q1 0 1 -13q0 -29 -2 -56t-8.5 -62t-20 -63t-33 -53t-51 -39t-72.5 -14h-146q-184 0 -184 288q0 24 10 47q-20 4 -62 4t-63 -4q11 -24 11 -47q0 -288 -184 -288h-142 q-48 0 -84.5 21t-56 51t-32 71.5t-16 75t-3.5 68.5q0 13 2 13h-7q-15 0 -27.5 9.5t-18.5 23.5q-6 15 -2 30.5t15 25.5l298 296q20 18 46 11l76 -19q20 -5 30.5 -22.5t5.5 -37.5t-22.5 -31t-37.5 -5l-51 12l-182 -193h891l-182 193l-44 -12q-20 -5 -37.5 6t-22.5 31t6 37.5 t31 22.5z" /> +<glyph unicode="&#xe241;" d="M1200 900h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-200v-850q0 -22 25 -34.5t50 -13.5l25 -2v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v850h-200q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h1000v-300zM500 450h-25q0 15 -4 24.5t-9 14.5t-17 7.5t-20 3t-25 0.5h-100v-425q0 -11 12.5 -17.5t25.5 -7.5h12v-50h-200v50q50 0 50 25v425h-100q-17 0 -25 -0.5t-20 -3t-17 -7.5t-9 -14.5t-4 -24.5h-25v150h500v-150z" /> +<glyph unicode="&#xe242;" d="M1000 300v50q-25 0 -55 32q-14 14 -25 31t-16 27l-4 11l-289 747h-69l-300 -754q-18 -35 -39 -56q-9 -9 -24.5 -18.5t-26.5 -14.5l-11 -5v-50h273v50q-49 0 -78.5 21.5t-11.5 67.5l69 176h293l61 -166q13 -34 -3.5 -66.5t-55.5 -32.5v-50h312zM412 691l134 342l121 -342 h-255zM1100 150v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5z" /> +<glyph unicode="&#xe243;" d="M50 1200h1100q21 0 35.5 -14.5t14.5 -35.5v-1100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v1100q0 21 14.5 35.5t35.5 14.5zM611 1118h-70q-13 0 -18 -12l-299 -753q-17 -32 -35 -51q-18 -18 -56 -34q-12 -5 -12 -18v-50q0 -8 5.5 -14t14.5 -6 h273q8 0 14 6t6 14v50q0 8 -6 14t-14 6q-55 0 -71 23q-10 14 0 39l63 163h266l57 -153q11 -31 -6 -55q-12 -17 -36 -17q-8 0 -14 -6t-6 -14v-50q0 -8 6 -14t14 -6h313q8 0 14 6t6 14v50q0 7 -5.5 13t-13.5 7q-17 0 -42 25q-25 27 -40 63h-1l-288 748q-5 12 -19 12zM639 611 h-197l103 264z" /> +<glyph unicode="&#xe244;" d="M1200 1100h-1200v100h1200v-100zM50 1000h400q21 0 35.5 -14.5t14.5 -35.5v-900q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v900q0 21 14.5 35.5t35.5 14.5zM650 1000h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM700 900v-300h300v300h-300z" /> +<glyph unicode="&#xe245;" d="M50 1200h400q21 0 35.5 -14.5t14.5 -35.5v-900q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v900q0 21 14.5 35.5t35.5 14.5zM650 700h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400 q0 21 14.5 35.5t35.5 14.5zM700 600v-300h300v300h-300zM1200 0h-1200v100h1200v-100z" /> +<glyph unicode="&#xe246;" d="M50 1000h400q21 0 35.5 -14.5t14.5 -35.5v-350h100v150q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-150h100v-100h-100v-150q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v150h-100v-350q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5v800q0 21 14.5 35.5t35.5 14.5zM700 700v-300h300v300h-300z" /> +<glyph unicode="&#xe247;" d="M100 0h-100v1200h100v-1200zM250 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM300 1000v-300h300v300h-300zM250 500h900q21 0 35.5 -14.5t14.5 -35.5v-400 q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe248;" d="M600 1100h150q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-150v-100h450q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5h350v100h-150q-21 0 -35.5 14.5 t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5h150v100h100v-100zM400 1000v-300h300v300h-300z" /> +<glyph unicode="&#xe249;" d="M1200 0h-100v1200h100v-1200zM550 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM600 1000v-300h300v300h-300zM50 500h900q21 0 35.5 -14.5t14.5 -35.5v-400 q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe250;" d="M865 565l-494 -494q-23 -23 -41 -23q-14 0 -22 13.5t-8 38.5v1000q0 25 8 38.5t22 13.5q18 0 41 -23l494 -494q14 -14 14 -35t-14 -35z" /> +<glyph unicode="&#xe251;" d="M335 635l494 494q29 29 50 20.5t21 -49.5v-1000q0 -41 -21 -49.5t-50 20.5l-494 494q-14 14 -14 35t14 35z" /> +<glyph unicode="&#xe252;" d="M100 900h1000q41 0 49.5 -21t-20.5 -50l-494 -494q-14 -14 -35 -14t-35 14l-494 494q-29 29 -20.5 50t49.5 21z" /> +<glyph unicode="&#xe253;" d="M635 865l494 -494q29 -29 20.5 -50t-49.5 -21h-1000q-41 0 -49.5 21t20.5 50l494 494q14 14 35 14t35 -14z" /> +<glyph unicode="&#xe254;" d="M700 741v-182l-692 -323v221l413 193l-413 193v221zM1200 0h-800v200h800v-200z" /> +<glyph unicode="&#xe255;" d="M1200 900h-200v-100h200v-100h-300v300h200v100h-200v100h300v-300zM0 700h50q0 21 4 37t9.5 26.5t18 17.5t22 11t28.5 5.5t31 2t37 0.5h100v-550q0 -22 -25 -34.5t-50 -13.5l-25 -2v-100h400v100q-4 0 -11 0.5t-24 3t-30 7t-24 15t-11 24.5v550h100q25 0 37 -0.5t31 -2 t28.5 -5.5t22 -11t18 -17.5t9.5 -26.5t4 -37h50v300h-800v-300z" /> +<glyph unicode="&#xe256;" d="M800 700h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-100v-550q0 -22 25 -34.5t50 -14.5l25 -1v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v550h-100q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h800v-300zM1100 200h-200v-100h200v-100h-300v300h200v100h-200v100h300v-300z" /> +<glyph unicode="&#xe257;" d="M701 1098h160q16 0 21 -11t-7 -23l-464 -464l464 -464q12 -12 7 -23t-21 -11h-160q-13 0 -23 9l-471 471q-7 8 -7 18t7 18l471 471q10 9 23 9z" /> +<glyph unicode="&#xe258;" d="M339 1098h160q13 0 23 -9l471 -471q7 -8 7 -18t-7 -18l-471 -471q-10 -9 -23 -9h-160q-16 0 -21 11t7 23l464 464l-464 464q-12 12 -7 23t21 11z" /> +<glyph unicode="&#xe259;" d="M1087 882q11 -5 11 -21v-160q0 -13 -9 -23l-471 -471q-8 -7 -18 -7t-18 7l-471 471q-9 10 -9 23v160q0 16 11 21t23 -7l464 -464l464 464q12 12 23 7z" /> +<glyph unicode="&#xe260;" d="M618 993l471 -471q9 -10 9 -23v-160q0 -16 -11 -21t-23 7l-464 464l-464 -464q-12 -12 -23 -7t-11 21v160q0 13 9 23l471 471q8 7 18 7t18 -7z" /> +<glyph unicode="&#xf8ff;" d="M1000 1200q0 -124 -88 -212t-212 -88q0 124 88 212t212 88zM450 1000h100q21 0 40 -14t26 -33l79 -194q5 1 16 3q34 6 54 9.5t60 7t65.5 1t61 -10t56.5 -23t42.5 -42t29 -64t5 -92t-19.5 -121.5q-1 -7 -3 -19.5t-11 -50t-20.5 -73t-32.5 -81.5t-46.5 -83t-64 -70 t-82.5 -50q-13 -5 -42 -5t-65.5 2.5t-47.5 2.5q-14 0 -49.5 -3.5t-63 -3.5t-43.5 7q-57 25 -104.5 78.5t-75 111.5t-46.5 112t-26 90l-7 35q-15 63 -18 115t4.5 88.5t26 64t39.5 43.5t52 25.5t58.5 13t62.5 2t59.5 -4.5t55.5 -8l-147 192q-12 18 -5.5 30t27.5 12z" /> +<glyph unicode="&#x1f511;" d="M250 1200h600q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-150v-500l-255 -178q-19 -9 -32 -1t-13 29v650h-150q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM400 1100v-100h300v100h-300z" /> +<glyph unicode="&#x1f6aa;" d="M250 1200h750q39 0 69.5 -40.5t30.5 -84.5v-933l-700 -117v950l600 125h-700v-1000h-100v1025q0 23 15.5 49t34.5 26zM500 525v-100l100 20v100z" /> +</font> +</defs></svg> \ No newline at end of file diff --git a/views/default/fonts/glyphicons-halflings-regular.ttf b/views/default/fonts/glyphicons-halflings-regular.ttf new file mode 100644 index 0000000..1413fc6 Binary files /dev/null and b/views/default/fonts/glyphicons-halflings-regular.ttf differ diff --git a/views/default/fonts/glyphicons-halflings-regular.woff b/views/default/fonts/glyphicons-halflings-regular.woff new file mode 100644 index 0000000..9e61285 Binary files /dev/null and b/views/default/fonts/glyphicons-halflings-regular.woff differ diff --git a/views/default/fonts/glyphicons-halflings-regular.woff2 b/views/default/fonts/glyphicons-halflings-regular.woff2 new file mode 100644 index 0000000..64539b5 Binary files /dev/null and b/views/default/fonts/glyphicons-halflings-regular.woff2 differ diff --git a/views/default/footer.php b/views/default/footer.php new file mode 100644 index 0000000..c507597 --- /dev/null +++ b/views/default/footer.php @@ -0,0 +1,71 @@ +</main> + +<hr> <!--Футер--> + <div class="row"> + <!--Футер--> + <footer class="col-sm-12"> + <p >info by IT Kursk</p> + </footer> + </div> +</div> + <!-- jQuery (necessary for Bootstrap's JavaScript plugins) --> + + <!-- Include all compiled plugins (below), or include individual files as needed --> + <script src="<?php echo TMPL; ?>js/bootstrap.js"></script> + <script type="text/javascript" src="/js/multiselect.js"></script> + <script type="text/javascript"> + MultiSelect(document.getElementById("src_countries"), + document.getElementById("dst_countries"), + document.getElementById("take"), + document.getElementById("drop")); + </script> + <script src="<?php echo TMPL; ?>js/dynamicTable.js"></script> + <script src="<?php echo TMPL; ?>js/bootstrap-switch.js"></script> + <script> + new DynamicTable( document.getElementById("dynamic") ); + </script> + <script> + $('#exampleModal').on('show.bs.modal', function (event) { + var button = $(event.relatedTarget) // Кнопка, что спровоцировало модальное окно + + var recipient = button.data('whatever')// Извлечение информации из данных-* атрибутов + + // Если необходимо, вы могли бы начать здесь AJAX-запрос (и выполните обновление в обратного вызова). + + // Обновление модальное окно Контента. Мы будем использовать jQuery здесь, но вместо него можно использовать привязки данных библиотеки или других методов. + + var modal = $(this) + modal.find('.modal-title').text('Редактирование записи № ' + recipient.id) + modal.find('.modal-body #id').val(recipient.id) + modal.find('.modal-body #name').val(recipient.name) + modal.find('.modal-body #post').val(recipient.post) + modal.find('.modal-body #department').val(recipient.department) + modal.find('.modal-body #parent_id').val(recipient.parent_id) + modal.find('.modal-body #mac').val(recipient.mac) + modal.find('.modal-body #number').val(recipient.number) + modal.find('.modal-body #subord').val(recipient.subordination) + modal.find('.modal-body #login').val(recipient.login) + if(recipient.activ == 1){$('#activ').prop('checked', true);} + + }) + </script> + <script> + $('#newactionrequest').on('show.bs.modal', function (event) { + var button = $(event.relatedTarget) // Кнопка, что спровоцировало модальное окно + + var recipient = button.data('whatever')// Извлечение информации из данных-* атрибутов + + // Если необходимо, вы могли бы начать здесь AJAX-запрос (и выполните обновление в обратного вызова). + + // Обновление модальное окно Контента. Мы будем использовать jQuery здесь, но вместо него можно использовать привязки данных библиотеки или других методов. + + var modal = $(this) + modal.find('.modal-title').text('Новое событие для заявки № ' + recipient.id) + modal.find('.modal-body #id').val(recipient.id) + modal.find('.modal-body #user').val(recipient.user); + + }) + </script> + + </body> +</html> diff --git a/views/default/header.php b/views/default/header.php new file mode 100644 index 0000000..b3f1e99 --- /dev/null +++ b/views/default/header.php @@ -0,0 +1,125 @@ +<!DOCTYPE html> +<html lang="ru"> + <head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <title>IT Assistent |<?php echo $title; ?></title> + <!-- Bootstrap --> + <link href="<?php echo TMPL; ?>css/bootstrap.css" rel="stylesheet"> + <link rel="stylesheet" href="<?php echo TMPL; ?>css/font-awesome.css"> + <link href="<?php echo TMPL; ?>css/bootstrap-responsive.css" rel="stylesheet"> + <link href="<?php echo TMPL; ?>css/bootstrap-switch.css" rel="stylesheet"> + <link href="<?php echo TMPL; ?>css/footer.css" rel="stylesheet"> + <link href="<?php echo TMPL; ?>css/timeline.css" rel="stylesheet"> + <!--<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>--> + <script type="text/javascript" src="http://code.jquery.com/jquery-2.2.3.js"></script> + <link rel="stylesheet" href="<?php echo LIB; ?>/player/APlayer.min.css"> + <script type="text/javascript" src="<?php echo LIB; ?>/player/pl.js"></script> + + <!--ckeditor--> + <script type="text/javascript" src="<?php echo LIB; ?>ckeditor/ckeditor.js"></script> + + <script type="text/javascript"> + $('document').ready(function(){ + $('#modal').modal(); + }); + </script> + <script type="text/javascript"> + $('document').ready(function(){ + $('#modal2').modal(); + }); + </script> + + + <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries --> + <!-- WARNING: Respond.js doesn't work if you view the page via file:// --> + <!--[if lt IE 9]> + <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> + <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script> + <![endif]--> + </head> + <body> + <div class="container"> + <header> + <nav role="navigation" class="navbar navbar-default"> + <!-- Brand and toggle get grouped for better mobile display --> + <div class="navbar-header"> + <button type="button" data-target="#navbarCollapse" data-toggle="collapse" class="navbar-toggle"> + <span class="sr-only">Toggle navigation</span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + <a href="#" class="navbar-brand">Бренд</a> + </div> + <!-- Collection of nav links, forms, and other content for toggling --> + <div id="navbarCollapse" class="collapse navbar-collapse"> + <ul class="nav navbar-nav"> + <li class="active"><a href="/">Главная</a></li> + <li class="dropdown"> + <a data-toggle="dropdown" class="dropdown-toggle" href="#"><i class="fa fa-paint-brush" aria-hidden="true"></i> Cartriges <b class="caret"></b></a> + <ul role="menu" class="dropdown-menu"> + <li><a href="/cartriges">view</a></li> + <li class="divider"></li> + <li><a href="/cartriges/add">add</a></li> + <li><a href="#">Remove</a></li> + <li><a href="/cartriges/orders">order</a></li> + <li class="divider"></li> + <li><a href="#">history</a></li> + </ul> + </li> + <li class="dropdown"> + <a data-toggle="dropdown" class="dropdown-toggle" href="#"><i class="fa fa-print" aria-hidden="true"></i> Prints <b class="caret"></b></a> + <ul role="menu" class="dropdown-menu"> + <li><a href="/printers">search</a></li> + <li class="divider"></li> + <li><a href="/printer/add">add</a></li> + <li><a href="#">edit</a></li> + <li class="divider"></li> + <li><a href="#">delete</a></li> + </ul> + </li> + <li class="dropdown"> + <a data-toggle="dropdown" class="dropdown-toggle" href="#"><i class="fa fa-wrench" aria-hidden="true"></i> Unit <b class="caret"></b></a> + <ul role="menu" class="dropdown-menu"> + <li><a href="/unit/requests">history requests</a></li> + <li><a href="#">history repairs</a></li> + <li><a href="/unit/createrequest">create requests</a></li> + <li class="divider"></li> + <li><a href="#">doc stor</a></li> + </ul> + </li> + <li class="dropdown"> + <a data-toggle="dropdown" class="dropdown-toggle" href="#"><i class="fa fa-phone" aria-hidden="true"></i> PhoneBook <b class="caret"></b></a> + <ul role="menu" class="dropdown-menu"> + <li><a href="/phonebook">Список телефонов ОЦ</a></li> + <li><a href="/phonebook/search">Поиск</a></li> + <li class="divider">Админам</li> + <li><a href="/phonebook/admsearch">Редактирование</a></li> + <li><a href="#">Добавление</a></li> + </ul> + </li> + </ul> + <ul class="nav navbar-nav navbar-right"> + <li class="dropdown"> + <?php if(user::checkAuth() == false): ?> + <a href="/user/login"><i class="fa fa-lock" aria-hidden="true"></i> Войти </a> + <?php else: ?> + <a data-toggle="dropdown" class="dropdown-toggle" href="#"><?php echo $_SESSION['name_en']; ?> <!--<img src="data:image/png;base64,<?php //echo base64_encode($_SESSION['photo']); ?>" height="36px" class="img-rounded">--></a> + <ul role="menu" class="dropdown-menu"> + <li><a href="#">history requests</a></li> + <li><a href="#">history repairs</a></li> + <li><a href="#">create requests</a></li> + <li class="divider"></li> + <li><a href="/user/logout"><i class="fa fa-sign-out" aria-hidden="true"></i> Logout</a></li> + </ul> + <?php endif; ?> + </li> + </ul> + </div> + </nav> + +</header> +<main> + diff --git a/views/default/index.html b/views/default/index.html new file mode 100644 index 0000000..969d28e --- /dev/null +++ b/views/default/index.html @@ -0,0 +1,156 @@ +<!DOCTYPE html> +<html lang="ru"> + <head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <title>Home</title> + + <!-- Bootstrap --> + <link href="css/bootstrap.css" rel="stylesheet"> + <link rel="stylesheet" href="css/font-awesome.css"> + <link href="css/bootstrap-responsive.css" rel="stylesheet"> + <link href="css/footer.css" rel="stylesheet"> + <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries --> + <!-- WARNING: Respond.js doesn't work if you view the page via file:// --> + <!--[if lt IE 9]> + <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> + <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script> + <![endif]--> + </head> + <body> + <div class="container"> + <header> + <nav role="navigation" class="navbar navbar-default"> + <!-- Brand and toggle get grouped for better mobile display --> + <div class="navbar-header"> + <button type="button" data-target="#navbarCollapse" data-toggle="collapse" class="navbar-toggle"> + <span class="sr-only">Toggle navigation</span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + <a href="#" class="navbar-brand">Бренд</a> + </div> + <!-- Collection of nav links, forms, and other content for toggling --> + <div id="navbarCollapse" class="collapse navbar-collapse"> + <ul class="nav navbar-nav"> + <li class="active"><a href="#">Главная</a></li> + <li class="dropdown"> + <a data-toggle="dropdown" class="dropdown-toggle" href="#"><i class="fa fa-paint-brush" aria-hidden="true"></i> Cartriges <b class="caret"></b></a> + <ul role="menu" class="dropdown-menu"> + <li><a href="#">add</a></li> + <li><a href="#">Remove</a></li> + <li><a href="#">order</a></li> + <li><a href="#">hestory</a></li> + </ul> + </li> + <li class="dropdown"> + <a data-toggle="dropdown" class="dropdown-toggle" href="#"><i class="fa fa-print" aria-hidden="true"></i> Prints <b class="caret"></b></a> + <ul role="menu" class="dropdown-menu"> + <li><a href="#">search</a></li> + <li><a href="#">add</a></li> + <li><a href="#">edit</a></li> + <li class="divider"></li> + <li><a href="#">delete</a></li> + </ul> + </li> + <li class="dropdown"> + <a data-toggle="dropdown" class="dropdown-toggle" href="#"><i class="fa fa-wrench" aria-hidden="true"></i> Unit <b class="caret"></b></a> + <ul role="menu" class="dropdown-menu"> + <li><a href="#">history requests</a></li> + <li><a href="#">history repairs</a></li> + <li><a href="#">create requests</a></li> + <li class="divider"></li> + <li><a href="#">doc stor</a></li> + </ul> + </li> + </ul> + <ul class="nav navbar-nav navbar-right"> + <li><a href="#"><i class="fa fa-lock" aria-hidden="true"></i> Войти / <i class="fa fa-sign-out" aria-hidden="true"></i></a></li> + </ul> + </div> + </nav> + +</header> +<main> + <table class="table table-bordered"> + <caption><h2>Количество картриджей</h2> </caption> + <thead> + <tr> + <th>k_sp3500xe</th><th>k_12</th><th>k_285</th><th>k_505</th><th>k_5945</th><th>k_209</th><th>k_83</th><th>k_oki_drum</th><th>k_oki_tuba</th><th>k_color</th><th>k_205</th> + </tr> + </thead> + <tbody> + <tr align="center"> + <td class="danger">1</td><td>10</td><td>4</td><td class="danger">1</td><td class="warning">2</td><td>4</td><td>3</td><td class="warning">2</td><td class="warning">2</td><td class="danger">1</td><td>5</td> + </tr> + </tbody> + </table> + <p class="text-center"> + <a href="#" class="btn btn-warning"><i class="fa fa-sign-out" aria-hidden="true"></i> Замена</a> + <a href="#" class="btn btn-success"><i class="fa fa-sign-in" aria-hidden="true"></i> Доставка</a> + <a href="#" class="btn btn-inverse"><i class="fa fa-shopping-cart" aria-hidden="true"></i> Заказ</a> + </p> + </br> + <hr> + <h2><p class="text-center">Вас интересуют эти принтеры? </p></h2> + <div class="row"> + <!-- 1 Изображение --> + <div class="col-sm-6 col-md-4"> + <div class="thumbnail"> + <img src="..." alt="..."> + <div class="caption"> + <h3>Заголовок...</h3> + <p>Контент...</p> + <p><a href="#" class="btn btn-primary" role="button">Button</a> <a href="#" class="btn btn-default" role="button">Button</a></p> + </div> + </div> + </div> + + <div class="col-sm-6 col-md-4"> + <div class="thumbnail"> + <img src="..." alt="..."> + <div class="caption"> + <h3>Заголовок...</h3> + <p>Контент...</p> + <p><a href="#" class="btn btn-primary" role="button">Button</a> <a href="#" class="btn btn-default" role="button">Button</a></p> + </div> + </div> + </div> + + <!--...--> + + <!-- 12 Изображение --> + <div class="col-sm-6 col-md-4"> + <div class="thumbnail"> + <img src="..." alt="..."> + <div class="caption"> + <h3>Заголовок...</h3> + <p>Контент...</p> + <p><a href="#" class="btn btn-primary" role="button">Button</a> <a href="#" class="btn btn-default" role="button">Button</a></p> + </div> + </div> + </div> + + </div> + + + </main> + <!--Футер--> + <footer> + + <div id="footer"> + + <p >info by IT Kursk</p> + + </div> + + </footer> +</div> + <!-- jQuery (necessary for Bootstrap's JavaScript plugins) --> + <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> + <!-- Include all compiled plugins (below), or include individual files as needed --> + <script src="js/bootstrap.js"></script> + </body> +</html> \ No newline at end of file diff --git a/views/default/index.php b/views/default/index.php new file mode 100644 index 0000000..b3cfce7 --- /dev/null +++ b/views/default/index.php @@ -0,0 +1,59 @@ +<?php include ROOT . TMPL . 'header.php'; ?> + <table class="table table-bordered"> + <caption><h2>Количество картриджей</h2> </caption> + <thead> + <tr> + <?php for($i = 0; $i < count($summ_cart); $i++):?> + <th><?php echo $summ_cart[$i]['name']; ?></th> + <?php endfor;?> + </tr> + </thead> + <tbody> + <tr align="center"> + <?php for($i = 0; $i < count($summ_cart); $i++):?> + <th <?php echo Cartriges::colorRow($summ_cart[$i]['value']); ?>><?php echo $summ_cart[$i]['value']; ?></th> + <?php endfor;?> + </tr> + </tbody> + </table> + <?php if(user::checkAdmin() == true): ?> + <p class="text-center"> + <a href="http://<?php echo DOMEN; ?>/cartriges/action/?act=out" class="btn btn-warning"><i class="fa fa-sign-out" aria-hidden="true"></i> Замена</a> + <a href="http://<?php echo DOMEN; ?>/cartriges/action/?act=in" class="btn btn-success"><i class="fa fa-sign-in" aria-hidden="true"></i> Доставка</a> + <a href="http://<?php echo DOMEN; ?>/cartriges/orders" class="btn btn-inverse"><i class="fa fa-shopping-cart" aria-hidden="true"></i> Заказ</a> + </p> + <?php endif; ?> + </br> + <hr> + <h2><p class="text-center">Вас интересуют эти принтеры? </p></h2> + <div class="row"> + <!-- 1 Изображение --> + <?php foreach ($printList as $print): ?> + <div class="col-sm-6 col-md-4"> + <div class="thumbnail"> + <?php if($print['img'] != ""): ?> + <img src="<?php echo $print['img']; ?>" class="img" alt="..."> + <?php else: ?> + <img src="img/not_img_print.png" class="img" alt="..."> + <?php endif; ?> + <div class="caption"> + <h3><?php echo $print['name']; ?> + <?php if($print['color'] == 1): ?> + <img src="/img/rgb.png" alt="" /> + <?php endif; ?> + </h3> + <p>Расположение <strong><?php echo $print['id_floor']; ?></strong></p> + <p>Отдел <strong><?php echo $print['id_department']; ?></strong></p> + <p>Юнит <strong><?php echo $print['unit']; ?></strong></p> + <p>Модель <strong><?php echo $print['model']; ?></strong></p> + <p><a href="/printer/<?php echo $print['id']; ?>" class="btn btn-primary" role="button">Подробнее</a> + <?php if(user::checkAdmin() == true): ?> + <a href="/printer/edit/<?php echo $print['id']; ?>" class="btn btn-default" role="button">Редактировать</a></p> + <?php endif; ?> + </div> + </div> + </div> + <?php endforeach; ?> + + </div> +<?php include ROOT . TMPL . 'footer.php'; ?> \ No newline at end of file diff --git a/views/default/info.html b/views/default/info.html new file mode 100644 index 0000000..802c926 --- /dev/null +++ b/views/default/info.html @@ -0,0 +1,163 @@ +<!DOCTYPE html> +<html lang="ru"> + <head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <title>Home</title> + + <!-- Bootstrap --> + <link href="css/bootstrap.css" rel="stylesheet"> + <link rel="stylesheet" href="css/font-awesome.css"> + <link href="css/bootstrap-responsive.css" rel="stylesheet"> + <link href="css/footer.css" rel="stylesheet"> + <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries --> + <!-- WARNING: Respond.js doesn't work if you view the page via file:// --> + <!--[if lt IE 9]> + <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> + <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script> + <![endif]--> + </head> + <body> + <div class="container"> + <header> + <nav role="navigation" class="navbar navbar-default"> + <!-- Brand and toggle get grouped for better mobile display --> + <div class="navbar-header"> + <button type="button" data-target="#navbarCollapse" data-toggle="collapse" class="navbar-toggle"> + <span class="sr-only">Toggle navigation</span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + <a href="#" class="navbar-brand">Бренд</a> + </div> + <!-- Collection of nav links, forms, and other content for toggling --> + <div id="navbarCollapse" class="collapse navbar-collapse"> + <ul class="nav navbar-nav"> + <li class="active"><a href="#">Главная</a></li> + <li class="dropdown"> + <a data-toggle="dropdown" class="dropdown-toggle" href="#"><i class="fa fa-paint-brush" aria-hidden="true"></i> Cartriges <b class="caret"></b></a> + <ul role="menu" class="dropdown-menu"> + <li><a href="#">add</a></li> + <li><a href="#">Remove</a></li> + <li><a href="#">order</a></li> + <li><a href="#">hestory</a></li> + </ul> + </li> + <li class="dropdown"> + <a data-toggle="dropdown" class="dropdown-toggle" href="#"><i class="fa fa-print" aria-hidden="true"></i> Prints <b class="caret"></b></a> + <ul role="menu" class="dropdown-menu"> + <li><a href="#">search</a></li> + <li><a href="#">add</a></li> + <li><a href="#">edit</a></li> + <li class="divider"></li> + <li><a href="#">delete</a></li> + </ul> + </li> + <li class="dropdown"> + <a data-toggle="dropdown" class="dropdown-toggle" href="#"><i class="fa fa-wrench" aria-hidden="true"></i> Unit <b class="caret"></b></a> + <ul role="menu" class="dropdown-menu"> + <li><a href="#">history requests</a></li> + <li><a href="#">history repairs</a></li> + <li><a href="#">create requests</a></li> + <li class="divider"></li> + <li><a href="#">doc stor</a></li> + </ul> + </li> + </ul> + <ul class="nav navbar-nav navbar-right"> + <li><a href="#"><i class="fa fa-lock" aria-hidden="true"></i> Войти / <i class="fa fa-sign-out" aria-hidden="true"></i></a></li> + </ul> + </div> + </nav> + +</header> +<main> + <div class="row"> + <div class="col-md-4"> + <img src="img/3030.jpg" alt="..." class="img-thumbnail"> + </div> + <div class="col-md-4"> + <input type="text" class="form-control" placeholder="Name" value="132"><br> + <input type="text" class="form-control" placeholder="#Unit"><br> + <input type="text" class="form-control" placeholder="Model"><br> + <input type="text" class="form-control" placeholder="Серийный"><br> + <input type="text" class="form-control" placeholder="Инвентарный"><br> + <h4>ID <strong>1</strong></h4> + </div> + <div class="col-md-4"> + <select class="form-control"> + <option selected>Этаж</option> + <option value="">111</option> + <option value="">222</option> + <option value="">333</option> + </select><br> + <select class="form-control"> + <option selected>Отдел</option> + <option value="">111</option> + <option value="">222</option> + <option value="">333</option> + </select><br> + <select class="form-control"> + <option selected>Картридж</option> + <option value="">111</option> + <option value="">222</option> + <option value="">333</option> + </select><br> + <select class="form-control"> + <option selected>Статус</option> + <option value="">111</option> + <option value="">222</option> + <option value="">333</option> + </select><br> + <input type="text" class="form-control" placeholder="Функционал"><br> + <button type="submit" class="btn btn-primary">Save</button> + </div> + </div> + <br> + <hr> + <br> + <table class="table table-hover"> + <thead> + <tr> + <th>№ п/п</th> + <th>Имя</th> + <th>Фамилия</th> + <th>E-mail</th> + + </tr> + </thead> + <tbody> + <tr onclick="window.location.href='edit/1'; return false"> + <td>1</td> + <td>Иван</td> + <td>Чмель</td> + <td>ivan@mail.ru</td> + </tr> + <tr> + <td>2</td> + <td>Петр</td> + <td>Щербаков</td> + <td>petr@mail.ru</td> + </tr> + <tr> + <td>3</td> + <td>Юрий</td> + <td>Голов</td> + <td>yuri@mail.ru</td> + </tr> + </tbody> + </table> + </main> + <!--Футер--> + <footer> + <p >info by IT Kursk</p> + </footer> +</div> + <!-- jQuery (necessary for Bootstrap's JavaScript plugins) --> + <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> + <!-- Include all compiled plugins (below), or include individual files as needed --> + <script src="js/bootstrap.js"></script> + </body> +</html> \ No newline at end of file diff --git a/views/default/info.php b/views/default/info.php new file mode 100644 index 0000000..b0ee279 --- /dev/null +++ b/views/default/info.php @@ -0,0 +1,166 @@ +<?php include ROOT . TMPL . 'header.php'; ?> + <div class="row"> + <div class="col-md-offset-2 col-md-4"> + <?php if($print['img'] != ""): ?> + <img class="img-responsive" src="<?php echo $print['img']; ?>" alt="..."> + <?php else: ?> + <img class="img-responsive" src="/img/not_img_print.png" alt="..."> + <?php endif; ?> + </div> + <div class="col-md-6"> + <p><big> + <dl class="dl-horizontal"> + <dt>ID</dt> + <dd><?php echo $print['id']; ?></dd> + <dt>Имя</dt> + <dd><?php echo $print['name']; ?></dd> + <dt>Модель</dt> + <dd><?php echo $print['model']; ?></dd> + <dt># UNIT</dt> + <dd><?php echo $print['unit']; ?></dd> + <dt>S/N</dt> + <dd><?php echo $print['sn']; ?></dd> + <dt>Инвентарный</dt> + <dd><?php echo $print['inventar']; ?></dd> + <dt>Расположение</dt> + <dd><?php echo $print['adress']; ?></dd> + <dd><?php echo $print['floor']; ?></dd> + <dt>Отдел</dt> + <dd><?php echo $print['department']; ?></dd> + <dt>Картридж</dt> + <dd><?php echo $print['cartrige']; ?></dd> + <dt>Статус</dt> + <dd><?php echo $print['status']; ?></dd> + <dt>Функционал</dt> + <?php if($print['functions'] == 0): ?> + <dd><b>Не заполнено</b></dd> + <?php else: ?> + <?php for($i=0; $i<count($print['functions']); $i++){ + echo "<dd>".$print['functions'][$i]['name']."</dd>"; + } + ?> + <?php endif; ?> + </dl> + </p></big> + <?php if(user::checkAdmin() == true): ?> + <a href="/printer/edit/<?php echo $print['id']; ?>" class="btn btn-default" role="button">Редактировать</a></p> + <?php endif; ?> + </div> + </div> + <br> + <h2>История изменений</h2> + <br> + <table class="table table-hover"> + <thead> + <tr> + <th>id action</th> + <th>дата изменения</th> + <th>id принтера</th> + <th>Кто изменял</th> + <th>Что изменял</th> + <th>Исходные данные</th> + <th>Конечные данные</th> + + </tr> + </thead> + <tbody> + <?php foreach($history as $hist): ?> + <tr onclick="window.location.href='/edit/1'; return false"> + <td><?php echo $hist['id']; ?></td> + <td><?php echo $hist['date']; ?></td> + <td><?php echo $hist['id_print']; ?></td> + <td><?php echo $hist['user']; ?></td> + <td><?php echo $hist['object_change']; ?></td> + <td><?php echo $hist['old_data']; ?></td> + <td><?php echo $hist['new_data']; ?></td> + </tr> + <?php endforeach; ?> + </tbody> + </table> + <br> + <h2>История заявок в UNIT</h2> + <br> + <table class="table table-hover"> + <thead> + <tr> + <th>id заявки</th> + <th>дата заведения</th> + <th>id принтера</th> + <th>Кто заводил</th> + <th>Проблема</th> + <th>Текущий статус</th> + <th>Дата закрытия</th> + <th>Коментарий</th> + <th>Файлы</th> + </tr> + </thead> + <tbody> + <tr onclick="window.location.href='/request/1'; return false"> + <td>1</td> + <td>11.09.2000</td> + <td>2</td> + <td>кто-то</td> + <td>что-то сломалось и теперь всё не работает</td> + <td>чё-то делаеют там</td> + <td>не закрыто</td> + <td>блин, как часто он ломается :(</td> + <td>файлы есть</td> + </tr> + <tr onclick="window.location.href='/request/2'; return false"> + <td>2</td> + <td>11.09.2000</td> + <td>2</td> + <td>кто-то</td> + <td>что-то сломалось и теперь всё не работает</td> + <td>чё-то делаеют там</td> + <td>не закрыто</td> + <td>блин, как часто он ломается :(</td> + <td>файлы есть</td> + </tr> + <tr onclick="window.location.href='/request/3'; return false"> + <td>3</td> + <td>11.09.2000</td> + <td>2</td> + <td>кто-то</td> + <td>что-то сломалось и теперь всё не работает</td> + <td>чё-то делаеют там</td> + <td>не закрыто</td> + <td>блин, как часто он ломается :(</td> + <td>файлы есть</td> + </tr> + <tr onclick="window.location.href='/request/4'; return false"> + <td>4</td> + <td>11.09.2000</td> + <td>2</td> + <td>кто-то</td> + <td>что-то сломалось и теперь всё не работает</td> + <td>чё-то делаеют там</td> + <td>не закрыто</td> + <td>блин, как часто он ломается :(</td> + <td>файлы есть</td> + </tr> + <tr onclick="window.location.href='/request/5'; return false"> + <td>5</td> + <td>11.09.2000</td> + <td>2</td> + <td>кто-то</td> + <td>что-то сломалось и теперь всё не работает</td> + <td>чё-то делаеют там</td> + <td>не закрыто</td> + <td>блин, как часто он ломается :(</td> + <td>файлы есть</td> + </tr> + <tr onclick="window.location.href='/request/6'; return false"> + <td>6</td> + <td>11.09.2000</td> + <td>2</td> + <td>кто-то</td> + <td>что-то сломалось и теперь всё не работает</td> + <td>чё-то делаеют там</td> + <td>не закрыто</td> + <td>блин, как часто он ломается :(</td> + <td>файлы есть</td> + </tr> + </tbody> + </table> +<?php include ROOT . TMPL . 'footer.php'; ?> \ No newline at end of file diff --git a/views/default/js/bootstrap-switch.js b/views/default/js/bootstrap-switch.js new file mode 100644 index 0000000..0d112b4 --- /dev/null +++ b/views/default/js/bootstrap-switch.js @@ -0,0 +1,785 @@ +/** + * bootstrap-switch - Turn checkboxes and radio buttons into toggle switches. + * + * @version v3.3.4 + * @homepage https://bttstrp.github.io/bootstrap-switch + * @author Mattia Larentis <mattia@larentis.eu> (http://larentis.eu) + * @license Apache-2.0 + */ + +(function (global, factory) { + if (typeof define === "function" && define.amd) { + define(['jquery'], factory); + } else if (typeof exports !== "undefined") { + factory(require('jquery')); + } else { + var mod = { + exports: {} + }; + factory(global.jquery); + global.bootstrapSwitch = mod.exports; + } +})(this, function (_jquery) { + 'use strict'; + + var _jquery2 = _interopRequireDefault(_jquery); + + function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { + default: obj + }; + } + + var _extends = Object.assign || function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + + return target; + }; + + function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } + } + + var _createClass = function () { + function defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + return function (Constructor, protoProps, staticProps) { + if (protoProps) defineProperties(Constructor.prototype, protoProps); + if (staticProps) defineProperties(Constructor, staticProps); + return Constructor; + }; + }(); + + var $ = _jquery2.default || window.jQuery || window.$; + + var BootstrapSwitch = function () { + function BootstrapSwitch(element) { + var _this = this; + + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + _classCallCheck(this, BootstrapSwitch); + + this.$element = $(element); + this.options = $.extend({}, $.fn.bootstrapSwitch.defaults, this._getElementOptions(), options); + this.prevOptions = {}; + this.$wrapper = $('<div>', { + class: function _class() { + var classes = []; + classes.push(_this.options.state ? 'on' : 'off'); + if (_this.options.size) { + classes.push(_this.options.size); + } + if (_this.options.disabled) { + classes.push('disabled'); + } + if (_this.options.readonly) { + classes.push('readonly'); + } + if (_this.options.indeterminate) { + classes.push('indeterminate'); + } + if (_this.options.inverse) { + classes.push('inverse'); + } + if (_this.$element.attr('id')) { + classes.push('id-' + _this.$element.attr('id')); + } + return classes.map(_this._getClass.bind(_this)).concat([_this.options.baseClass], _this._getClasses(_this.options.wrapperClass)).join(' '); + } + }); + this.$container = $('<div>', { class: this._getClass('container') }); + this.$on = $('<span>', { + html: this.options.onText, + class: this._getClass('handle-on') + ' ' + this._getClass(this.options.onColor) + }); + this.$off = $('<span>', { + html: this.options.offText, + class: this._getClass('handle-off') + ' ' + this._getClass(this.options.offColor) + }); + this.$label = $('<span>', { + html: this.options.labelText, + class: this._getClass('label') + }); + + this.$element.on('init.bootstrapSwitch', this.options.onInit.bind(this, element)); + this.$element.on('switchChange.bootstrapSwitch', function () { + for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + if (_this.options.onSwitchChange.apply(element, args) === false) { + if (_this.$element.is(':radio')) { + $('[name="' + _this.$element.attr('name') + '"]').trigger('previousState.bootstrapSwitch', true); + } else { + _this.$element.trigger('previousState.bootstrapSwitch', true); + } + } + }); + + this.$container = this.$element.wrap(this.$container).parent(); + this.$wrapper = this.$container.wrap(this.$wrapper).parent(); + this.$element.before(this.options.inverse ? this.$off : this.$on).before(this.$label).before(this.options.inverse ? this.$on : this.$off); + + if (this.options.indeterminate) { + this.$element.prop('indeterminate', true); + } + + this._init(); + this._elementHandlers(); + this._handleHandlers(); + this._labelHandlers(); + this._formHandler(); + this._externalLabelHandler(); + this.$element.trigger('init.bootstrapSwitch', this.options.state); + } + + _createClass(BootstrapSwitch, [{ + key: 'setPrevOptions', + value: function setPrevOptions() { + this.prevOptions = _extends({}, this.options); + } + }, { + key: 'state', + value: function state(value, skip) { + if (typeof value === 'undefined') { + return this.options.state; + } + if (this.options.disabled || this.options.readonly || this.options.state && !this.options.radioAllOff && this.$element.is(':radio')) { + return this.$element; + } + if (this.$element.is(':radio')) { + $('[name="' + this.$element.attr('name') + '"]').trigger('setPreviousOptions.bootstrapSwitch'); + } else { + this.$element.trigger('setPreviousOptions.bootstrapSwitch'); + } + if (this.options.indeterminate) { + this.indeterminate(false); + } + this.$element.prop('checked', Boolean(value)).trigger('change.bootstrapSwitch', skip); + return this.$element; + } + }, { + key: 'toggleState', + value: function toggleState(skip) { + if (this.options.disabled || this.options.readonly) { + return this.$element; + } + if (this.options.indeterminate) { + this.indeterminate(false); + return this.state(true); + } else { + return this.$element.prop('checked', !this.options.state).trigger('change.bootstrapSwitch', skip); + } + } + }, { + key: 'size', + value: function size(value) { + if (typeof value === 'undefined') { + return this.options.size; + } + if (this.options.size != null) { + this.$wrapper.removeClass(this._getClass(this.options.size)); + } + if (value) { + this.$wrapper.addClass(this._getClass(value)); + } + this._width(); + this._containerPosition(); + this.options.size = value; + return this.$element; + } + }, { + key: 'animate', + value: function animate(value) { + if (typeof value === 'undefined') { + return this.options.animate; + } + if (this.options.animate === Boolean(value)) { + return this.$element; + } + return this.toggleAnimate(); + } + }, { + key: 'toggleAnimate', + value: function toggleAnimate() { + this.options.animate = !this.options.animate; + this.$wrapper.toggleClass(this._getClass('animate')); + return this.$element; + } + }, { + key: 'disabled', + value: function disabled(value) { + if (typeof value === 'undefined') { + return this.options.disabled; + } + if (this.options.disabled === Boolean(value)) { + return this.$element; + } + return this.toggleDisabled(); + } + }, { + key: 'toggleDisabled', + value: function toggleDisabled() { + this.options.disabled = !this.options.disabled; + this.$element.prop('disabled', this.options.disabled); + this.$wrapper.toggleClass(this._getClass('disabled')); + return this.$element; + } + }, { + key: 'readonly', + value: function readonly(value) { + if (typeof value === 'undefined') { + return this.options.readonly; + } + if (this.options.readonly === Boolean(value)) { + return this.$element; + } + return this.toggleReadonly(); + } + }, { + key: 'toggleReadonly', + value: function toggleReadonly() { + this.options.readonly = !this.options.readonly; + this.$element.prop('readonly', this.options.readonly); + this.$wrapper.toggleClass(this._getClass('readonly')); + return this.$element; + } + }, { + key: 'indeterminate', + value: function indeterminate(value) { + if (typeof value === 'undefined') { + return this.options.indeterminate; + } + if (this.options.indeterminate === Boolean(value)) { + return this.$element; + } + return this.toggleIndeterminate(); + } + }, { + key: 'toggleIndeterminate', + value: function toggleIndeterminate() { + this.options.indeterminate = !this.options.indeterminate; + this.$element.prop('indeterminate', this.options.indeterminate); + this.$wrapper.toggleClass(this._getClass('indeterminate')); + this._containerPosition(); + return this.$element; + } + }, { + key: 'inverse', + value: function inverse(value) { + if (typeof value === 'undefined') { + return this.options.inverse; + } + if (this.options.inverse === Boolean(value)) { + return this.$element; + } + return this.toggleInverse(); + } + }, { + key: 'toggleInverse', + value: function toggleInverse() { + this.$wrapper.toggleClass(this._getClass('inverse')); + var $on = this.$on.clone(true); + var $off = this.$off.clone(true); + this.$on.replaceWith($off); + this.$off.replaceWith($on); + this.$on = $off; + this.$off = $on; + this.options.inverse = !this.options.inverse; + return this.$element; + } + }, { + key: 'onColor', + value: function onColor(value) { + if (typeof value === 'undefined') { + return this.options.onColor; + } + if (this.options.onColor) { + this.$on.removeClass(this._getClass(this.options.onColor)); + } + this.$on.addClass(this._getClass(value)); + this.options.onColor = value; + return this.$element; + } + }, { + key: 'offColor', + value: function offColor(value) { + if (typeof value === 'undefined') { + return this.options.offColor; + } + if (this.options.offColor) { + this.$off.removeClass(this._getClass(this.options.offColor)); + } + this.$off.addClass(this._getClass(value)); + this.options.offColor = value; + return this.$element; + } + }, { + key: 'onText', + value: function onText(value) { + if (typeof value === 'undefined') { + return this.options.onText; + } + this.$on.html(value); + this._width(); + this._containerPosition(); + this.options.onText = value; + return this.$element; + } + }, { + key: 'offText', + value: function offText(value) { + if (typeof value === 'undefined') { + return this.options.offText; + } + this.$off.html(value); + this._width(); + this._containerPosition(); + this.options.offText = value; + return this.$element; + } + }, { + key: 'labelText', + value: function labelText(value) { + if (typeof value === 'undefined') { + return this.options.labelText; + } + this.$label.html(value); + this._width(); + this.options.labelText = value; + return this.$element; + } + }, { + key: 'handleWidth', + value: function handleWidth(value) { + if (typeof value === 'undefined') { + return this.options.handleWidth; + } + this.options.handleWidth = value; + this._width(); + this._containerPosition(); + return this.$element; + } + }, { + key: 'labelWidth', + value: function labelWidth(value) { + if (typeof value === 'undefined') { + return this.options.labelWidth; + } + this.options.labelWidth = value; + this._width(); + this._containerPosition(); + return this.$element; + } + }, { + key: 'baseClass', + value: function baseClass(value) { + return this.options.baseClass; + } + }, { + key: 'wrapperClass', + value: function wrapperClass(value) { + if (typeof value === 'undefined') { + return this.options.wrapperClass; + } + if (!value) { + value = $.fn.bootstrapSwitch.defaults.wrapperClass; + } + this.$wrapper.removeClass(this._getClasses(this.options.wrapperClass).join(' ')); + this.$wrapper.addClass(this._getClasses(value).join(' ')); + this.options.wrapperClass = value; + return this.$element; + } + }, { + key: 'radioAllOff', + value: function radioAllOff(value) { + if (typeof value === 'undefined') { + return this.options.radioAllOff; + } + var val = Boolean(value); + if (this.options.radioAllOff === val) { + return this.$element; + } + this.options.radioAllOff = val; + return this.$element; + } + }, { + key: 'onInit', + value: function onInit(value) { + if (typeof value === 'undefined') { + return this.options.onInit; + } + if (!value) { + value = $.fn.bootstrapSwitch.defaults.onInit; + } + this.options.onInit = value; + return this.$element; + } + }, { + key: 'onSwitchChange', + value: function onSwitchChange(value) { + if (typeof value === 'undefined') { + return this.options.onSwitchChange; + } + if (!value) { + value = $.fn.bootstrapSwitch.defaults.onSwitchChange; + } + this.options.onSwitchChange = value; + return this.$element; + } + }, { + key: 'destroy', + value: function destroy() { + var $form = this.$element.closest('form'); + if ($form.length) { + $form.off('reset.bootstrapSwitch').removeData('bootstrap-switch'); + } + this.$container.children().not(this.$element).remove(); + this.$element.unwrap().unwrap().off('.bootstrapSwitch').removeData('bootstrap-switch'); + return this.$element; + } + }, { + key: '_getElementOptions', + value: function _getElementOptions() { + return { + state: this.$element.is(':checked'), + size: this.$element.data('size'), + animate: this.$element.data('animate'), + disabled: this.$element.is(':disabled'), + readonly: this.$element.is('[readonly]'), + indeterminate: this.$element.data('indeterminate'), + inverse: this.$element.data('inverse'), + radioAllOff: this.$element.data('radio-all-off'), + onColor: this.$element.data('on-color'), + offColor: this.$element.data('off-color'), + onText: this.$element.data('on-text'), + offText: this.$element.data('off-text'), + labelText: this.$element.data('label-text'), + handleWidth: this.$element.data('handle-width'), + labelWidth: this.$element.data('label-width'), + baseClass: this.$element.data('base-class'), + wrapperClass: this.$element.data('wrapper-class') + }; + } + }, { + key: '_width', + value: function _width() { + var _this2 = this; + + var $handles = this.$on.add(this.$off).add(this.$label).css('width', ''); + var handleWidth = this.options.handleWidth === 'auto' ? Math.round(Math.max(this.$on.width(), this.$off.width())) : this.options.handleWidth; + $handles.width(handleWidth); + this.$label.width(function (index, width) { + if (_this2.options.labelWidth !== 'auto') { + return _this2.options.labelWidth; + } + if (width < handleWidth) { + return handleWidth; + } + return width; + }); + this._handleWidth = this.$on.outerWidth(); + this._labelWidth = this.$label.outerWidth(); + this.$container.width(this._handleWidth * 2 + this._labelWidth); + return this.$wrapper.width(this._handleWidth + this._labelWidth); + } + }, { + key: '_containerPosition', + value: function _containerPosition() { + var _this3 = this; + + var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.options.state; + var callback = arguments[1]; + + this.$container.css('margin-left', function () { + var values = [0, '-' + _this3._handleWidth + 'px']; + if (_this3.options.indeterminate) { + return '-' + _this3._handleWidth / 2 + 'px'; + } + if (state) { + if (_this3.options.inverse) { + return values[1]; + } else { + return values[0]; + } + } else { + if (_this3.options.inverse) { + return values[0]; + } else { + return values[1]; + } + } + }); + } + }, { + key: '_init', + value: function _init() { + var _this4 = this; + + var init = function init() { + _this4.setPrevOptions(); + _this4._width(); + _this4._containerPosition(); + setTimeout(function () { + if (_this4.options.animate) { + return _this4.$wrapper.addClass(_this4._getClass('animate')); + } + }, 50); + }; + if (this.$wrapper.is(':visible')) { + init(); + return; + } + var initInterval = window.setInterval(function () { + if (_this4.$wrapper.is(':visible')) { + init(); + return window.clearInterval(initInterval); + } + }, 50); + } + }, { + key: '_elementHandlers', + value: function _elementHandlers() { + var _this5 = this; + + return this.$element.on({ + 'setPreviousOptions.bootstrapSwitch': this.setPrevOptions.bind(this), + + 'previousState.bootstrapSwitch': function previousStateBootstrapSwitch() { + _this5.options = _this5.prevOptions; + if (_this5.options.indeterminate) { + _this5.$wrapper.addClass(_this5._getClass('indeterminate')); + } + _this5.$element.prop('checked', _this5.options.state).trigger('change.bootstrapSwitch', true); + }, + + 'change.bootstrapSwitch': function changeBootstrapSwitch(event, skip) { + event.preventDefault(); + event.stopImmediatePropagation(); + var state = _this5.$element.is(':checked'); + _this5._containerPosition(state); + if (state === _this5.options.state) { + return; + } + _this5.options.state = state; + _this5.$wrapper.toggleClass(_this5._getClass('off')).toggleClass(_this5._getClass('on')); + if (!skip) { + if (_this5.$element.is(':radio')) { + $('[name="' + _this5.$element.attr('name') + '"]').not(_this5.$element).prop('checked', false).trigger('change.bootstrapSwitch', true); + } + _this5.$element.trigger('switchChange.bootstrapSwitch', [state]); + } + }, + + 'focus.bootstrapSwitch': function focusBootstrapSwitch(event) { + event.preventDefault(); + _this5.$wrapper.addClass(_this5._getClass('focused')); + }, + + 'blur.bootstrapSwitch': function blurBootstrapSwitch(event) { + event.preventDefault(); + _this5.$wrapper.removeClass(_this5._getClass('focused')); + }, + + 'keydown.bootstrapSwitch': function keydownBootstrapSwitch(event) { + if (!event.which || _this5.options.disabled || _this5.options.readonly) { + return; + } + if (event.which === 37 || event.which === 39) { + event.preventDefault(); + event.stopImmediatePropagation(); + _this5.state(event.which === 39); + } + } + }); + } + }, { + key: '_handleHandlers', + value: function _handleHandlers() { + var _this6 = this; + + this.$on.on('click.bootstrapSwitch', function (event) { + event.preventDefault(); + event.stopPropagation(); + _this6.state(false); + return _this6.$element.trigger('focus.bootstrapSwitch'); + }); + return this.$off.on('click.bootstrapSwitch', function (event) { + event.preventDefault(); + event.stopPropagation(); + _this6.state(true); + return _this6.$element.trigger('focus.bootstrapSwitch'); + }); + } + }, { + key: '_labelHandlers', + value: function _labelHandlers() { + var _this7 = this; + + var handlers = { + click: function click(event) { + event.stopPropagation(); + }, + + + 'mousedown.bootstrapSwitch touchstart.bootstrapSwitch': function mousedownBootstrapSwitchTouchstartBootstrapSwitch(event) { + if (_this7._dragStart || _this7.options.disabled || _this7.options.readonly) { + return; + } + event.preventDefault(); + event.stopPropagation(); + _this7._dragStart = (event.pageX || event.originalEvent.touches[0].pageX) - parseInt(_this7.$container.css('margin-left'), 10); + if (_this7.options.animate) { + _this7.$wrapper.removeClass(_this7._getClass('animate')); + } + _this7.$element.trigger('focus.bootstrapSwitch'); + }, + + 'mousemove.bootstrapSwitch touchmove.bootstrapSwitch': function mousemoveBootstrapSwitchTouchmoveBootstrapSwitch(event) { + if (_this7._dragStart == null) { + return; + } + var difference = (event.pageX || event.originalEvent.touches[0].pageX) - _this7._dragStart; + event.preventDefault(); + if (difference < -_this7._handleWidth || difference > 0) { + return; + } + _this7._dragEnd = difference; + _this7.$container.css('margin-left', _this7._dragEnd + 'px'); + }, + + 'mouseup.bootstrapSwitch touchend.bootstrapSwitch': function mouseupBootstrapSwitchTouchendBootstrapSwitch(event) { + if (!_this7._dragStart) { + return; + } + event.preventDefault(); + if (_this7.options.animate) { + _this7.$wrapper.addClass(_this7._getClass('animate')); + } + if (_this7._dragEnd) { + var state = _this7._dragEnd > -(_this7._handleWidth / 2); + _this7._dragEnd = false; + _this7.state(_this7.options.inverse ? !state : state); + } else { + _this7.state(!_this7.options.state); + } + _this7._dragStart = false; + }, + + 'mouseleave.bootstrapSwitch': function mouseleaveBootstrapSwitch() { + _this7.$label.trigger('mouseup.bootstrapSwitch'); + } + }; + this.$label.on(handlers); + } + }, { + key: '_externalLabelHandler', + value: function _externalLabelHandler() { + var _this8 = this; + + var $externalLabel = this.$element.closest('label'); + $externalLabel.on('click', function (event) { + event.preventDefault(); + event.stopImmediatePropagation(); + if (event.target === $externalLabel[0]) { + _this8.toggleState(); + } + }); + } + }, { + key: '_formHandler', + value: function _formHandler() { + var $form = this.$element.closest('form'); + if ($form.data('bootstrap-switch')) { + return; + } + $form.on('reset.bootstrapSwitch', function () { + window.setTimeout(function () { + $form.find('input').filter(function () { + return $(this).data('bootstrap-switch'); + }).each(function () { + return $(this).bootstrapSwitch('state', this.checked); + }); + }, 1); + }).data('bootstrap-switch', true); + } + }, { + key: '_getClass', + value: function _getClass(name) { + return this.options.baseClass + '-' + name; + } + }, { + key: '_getClasses', + value: function _getClasses(classes) { + if (!$.isArray(classes)) { + return [this._getClass(classes)]; + } + return classes.map(this._getClass.bind(this)); + } + }]); + + return BootstrapSwitch; + }(); + + $.fn.bootstrapSwitch = function (option) { + for (var _len2 = arguments.length, args = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { + args[_key2 - 1] = arguments[_key2]; + } + + function reducer(ret, next) { + var $this = $(next); + var existingData = $this.data('bootstrap-switch'); + var data = existingData || new BootstrapSwitch(next, option); + if (!existingData) { + $this.data('bootstrap-switch', data); + } + if (typeof option === 'string') { + return data[option].apply(data, args); + } + return ret; + } + return Array.prototype.reduce.call(this, reducer, this); + }; + $.fn.bootstrapSwitch.Constructor = BootstrapSwitch; + $.fn.bootstrapSwitch.defaults = { + state: true, + size: null, + animate: true, + disabled: false, + readonly: false, + indeterminate: false, + inverse: false, + radioAllOff: false, + onColor: 'primary', + offColor: 'default', + onText: 'ON', + offText: 'OFF', + labelText: '&nbsp', + handleWidth: 'auto', + labelWidth: 'auto', + baseClass: 'bootstrap-switch', + wrapperClass: 'wrapper', + onInit: function onInit() {}, + onSwitchChange: function onSwitchChange() {} + }; +}); + diff --git a/views/default/js/bootstrap.js b/views/default/js/bootstrap.js new file mode 100644 index 0000000..4139b6f --- /dev/null +++ b/views/default/js/bootstrap.js @@ -0,0 +1,2306 @@ +/*! + * Bootstrap v3.3.2 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ + +if (typeof jQuery === 'undefined') { + throw new Error('Bootstrap\'s JavaScript requires jQuery') +} + ++function ($) { + 'use strict'; + var version = $.fn.jquery.split(' ')[0].split('.') + if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1)) { + throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher') + } +}(jQuery); + +/* ======================================================================== + * Bootstrap: transition.js v3.3.2 + * http://getbootstrap.com/javascript/#transitions + * ======================================================================== + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/) + // ============================================================ + + function transitionEnd() { + var el = document.createElement('bootstrap') + + var transEndEventNames = { + WebkitTransition : 'webkitTransitionEnd', + MozTransition : 'transitionend', + OTransition : 'oTransitionEnd otransitionend', + transition : 'transitionend' + } + + for (var name in transEndEventNames) { + if (el.style[name] !== undefined) { + return { end: transEndEventNames[name] } + } + } + + return false // explicit for ie8 ( ._.) + } + + // http://blog.alexmaccaw.com/css-transitions + $.fn.emulateTransitionEnd = function (duration) { + var called = false + var $el = this + $(this).one('bsTransitionEnd', function () { called = true }) + var callback = function () { if (!called) $($el).trigger($.support.transition.end) } + setTimeout(callback, duration) + return this + } + + $(function () { + $.support.transition = transitionEnd() + + if (!$.support.transition) return + + $.event.special.bsTransitionEnd = { + bindType: $.support.transition.end, + delegateType: $.support.transition.end, + handle: function (e) { + if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments) + } + } + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: alert.js v3.3.2 + * http://getbootstrap.com/javascript/#alerts + * ======================================================================== + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // ALERT CLASS DEFINITION + // ====================== + + var dismiss = '[data-dismiss="alert"]' + var Alert = function (el) { + $(el).on('click', dismiss, this.close) + } + + Alert.VERSION = '3.3.2' + + Alert.TRANSITION_DURATION = 150 + + Alert.prototype.close = function (e) { + var $this = $(this) + var selector = $this.attr('data-target') + + if (!selector) { + selector = $this.attr('href') + selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 + } + + var $parent = $(selector) + + if (e) e.preventDefault() + + if (!$parent.length) { + $parent = $this.closest('.alert') + } + + $parent.trigger(e = $.Event('close.bs.alert')) + + if (e.isDefaultPrevented()) return + + $parent.removeClass('in') + + function removeElement() { + // detach from parent, fire event then clean up data + $parent.detach().trigger('closed.bs.alert').remove() + } + + $.support.transition && $parent.hasClass('fade') ? + $parent + .one('bsTransitionEnd', removeElement) + .emulateTransitionEnd(Alert.TRANSITION_DURATION) : + removeElement() + } + + + // ALERT PLUGIN DEFINITION + // ======================= + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.alert') + + if (!data) $this.data('bs.alert', (data = new Alert(this))) + if (typeof option == 'string') data[option].call($this) + }) + } + + var old = $.fn.alert + + $.fn.alert = Plugin + $.fn.alert.Constructor = Alert + + + // ALERT NO CONFLICT + // ================= + + $.fn.alert.noConflict = function () { + $.fn.alert = old + return this + } + + + // ALERT DATA-API + // ============== + + $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: button.js v3.3.2 + * http://getbootstrap.com/javascript/#buttons + * ======================================================================== + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // BUTTON PUBLIC CLASS DEFINITION + // ============================== + + var Button = function (element, options) { + this.$element = $(element) + this.options = $.extend({}, Button.DEFAULTS, options) + this.isLoading = false + } + + Button.VERSION = '3.3.2' + + Button.DEFAULTS = { + loadingText: 'loading...' + } + + Button.prototype.setState = function (state) { + var d = 'disabled' + var $el = this.$element + var val = $el.is('input') ? 'val' : 'html' + var data = $el.data() + + state = state + 'Text' + + if (data.resetText == null) $el.data('resetText', $el[val]()) + + // push to event loop to allow forms to submit + setTimeout($.proxy(function () { + $el[val](data[state] == null ? this.options[state] : data[state]) + + if (state == 'loadingText') { + this.isLoading = true + $el.addClass(d).attr(d, d) + } else if (this.isLoading) { + this.isLoading = false + $el.removeClass(d).removeAttr(d) + } + }, this), 0) + } + + Button.prototype.toggle = function () { + var changed = true + var $parent = this.$element.closest('[data-toggle="buttons"]') + + if ($parent.length) { + var $input = this.$element.find('input') + if ($input.prop('type') == 'radio') { + if ($input.prop('checked') && this.$element.hasClass('active')) changed = false + else $parent.find('.active').removeClass('active') + } + if (changed) $input.prop('checked', !this.$element.hasClass('active')).trigger('change') + } else { + this.$element.attr('aria-pressed', !this.$element.hasClass('active')) + } + + if (changed) this.$element.toggleClass('active') + } + + + // BUTTON PLUGIN DEFINITION + // ======================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.button') + var options = typeof option == 'object' && option + + if (!data) $this.data('bs.button', (data = new Button(this, options))) + + if (option == 'toggle') data.toggle() + else if (option) data.setState(option) + }) + } + + var old = $.fn.button + + $.fn.button = Plugin + $.fn.button.Constructor = Button + + + // BUTTON NO CONFLICT + // ================== + + $.fn.button.noConflict = function () { + $.fn.button = old + return this + } + + + // BUTTON DATA-API + // =============== + + $(document) + .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) { + var $btn = $(e.target) + if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn') + Plugin.call($btn, 'toggle') + e.preventDefault() + }) + .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) { + $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type)) + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: carousel.js v3.3.2 + * http://getbootstrap.com/javascript/#carousel + * ======================================================================== + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // CAROUSEL CLASS DEFINITION + // ========================= + + var Carousel = function (element, options) { + this.$element = $(element) + this.$indicators = this.$element.find('.carousel-indicators') + this.options = options + this.paused = + this.sliding = + this.interval = + this.$active = + this.$items = null + + this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this)) + + this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element + .on('mouseenter.bs.carousel', $.proxy(this.pause, this)) + .on('mouseleave.bs.carousel', $.proxy(this.cycle, this)) + } + + Carousel.VERSION = '3.3.2' + + Carousel.TRANSITION_DURATION = 600 + + Carousel.DEFAULTS = { + interval: 5000, + pause: 'hover', + wrap: true, + keyboard: true + } + + Carousel.prototype.keydown = function (e) { + if (/input|textarea/i.test(e.target.tagName)) return + switch (e.which) { + case 37: this.prev(); break + case 39: this.next(); break + default: return + } + + e.preventDefault() + } + + Carousel.prototype.cycle = function (e) { + e || (this.paused = false) + + this.interval && clearInterval(this.interval) + + this.options.interval + && !this.paused + && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) + + return this + } + + Carousel.prototype.getItemIndex = function (item) { + this.$items = item.parent().children('.item') + return this.$items.index(item || this.$active) + } + + Carousel.prototype.getItemForDirection = function (direction, active) { + var activeIndex = this.getItemIndex(active) + var willWrap = (direction == 'prev' && activeIndex === 0) + || (direction == 'next' && activeIndex == (this.$items.length - 1)) + if (willWrap && !this.options.wrap) return active + var delta = direction == 'prev' ? -1 : 1 + var itemIndex = (activeIndex + delta) % this.$items.length + return this.$items.eq(itemIndex) + } + + Carousel.prototype.to = function (pos) { + var that = this + var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active')) + + if (pos > (this.$items.length - 1) || pos < 0) return + + if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid" + if (activeIndex == pos) return this.pause().cycle() + + return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos)) + } + + Carousel.prototype.pause = function (e) { + e || (this.paused = true) + + if (this.$element.find('.next, .prev').length && $.support.transition) { + this.$element.trigger($.support.transition.end) + this.cycle(true) + } + + this.interval = clearInterval(this.interval) + + return this + } + + Carousel.prototype.next = function () { + if (this.sliding) return + return this.slide('next') + } + + Carousel.prototype.prev = function () { + if (this.sliding) return + return this.slide('prev') + } + + Carousel.prototype.slide = function (type, next) { + var $active = this.$element.find('.item.active') + var $next = next || this.getItemForDirection(type, $active) + var isCycling = this.interval + var direction = type == 'next' ? 'left' : 'right' + var that = this + + if ($next.hasClass('active')) return (this.sliding = false) + + var relatedTarget = $next[0] + var slideEvent = $.Event('slide.bs.carousel', { + relatedTarget: relatedTarget, + direction: direction + }) + this.$element.trigger(slideEvent) + if (slideEvent.isDefaultPrevented()) return + + this.sliding = true + + isCycling && this.pause() + + if (this.$indicators.length) { + this.$indicators.find('.active').removeClass('active') + var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)]) + $nextIndicator && $nextIndicator.addClass('active') + } + + var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid" + if ($.support.transition && this.$element.hasClass('slide')) { + $next.addClass(type) + $next[0].offsetWidth // force reflow + $active.addClass(direction) + $next.addClass(direction) + $active + .one('bsTransitionEnd', function () { + $next.removeClass([type, direction].join(' ')).addClass('active') + $active.removeClass(['active', direction].join(' ')) + that.sliding = false + setTimeout(function () { + that.$element.trigger(slidEvent) + }, 0) + }) + .emulateTransitionEnd(Carousel.TRANSITION_DURATION) + } else { + $active.removeClass('active') + $next.addClass('active') + this.sliding = false + this.$element.trigger(slidEvent) + } + + isCycling && this.cycle() + + return this + } + + + // CAROUSEL PLUGIN DEFINITION + // ========================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.carousel') + var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option) + var action = typeof option == 'string' ? option : options.slide + + if (!data) $this.data('bs.carousel', (data = new Carousel(this, options))) + if (typeof option == 'number') data.to(option) + else if (action) data[action]() + else if (options.interval) data.pause().cycle() + }) + } + + var old = $.fn.carousel + + $.fn.carousel = Plugin + $.fn.carousel.Constructor = Carousel + + + // CAROUSEL NO CONFLICT + // ==================== + + $.fn.carousel.noConflict = function () { + $.fn.carousel = old + return this + } + + + // CAROUSEL DATA-API + // ================= + + var clickHandler = function (e) { + var href + var $this = $(this) + var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7 + if (!$target.hasClass('carousel')) return + var options = $.extend({}, $target.data(), $this.data()) + var slideIndex = $this.attr('data-slide-to') + if (slideIndex) options.interval = false + + Plugin.call($target, options) + + if (slideIndex) { + $target.data('bs.carousel').to(slideIndex) + } + + e.preventDefault() + } + + $(document) + .on('click.bs.carousel.data-api', '[data-slide]', clickHandler) + .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler) + + $(window).on('load', function () { + $('[data-ride="carousel"]').each(function () { + var $carousel = $(this) + Plugin.call($carousel, $carousel.data()) + }) + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: collapse.js v3.3.2 + * http://getbootstrap.com/javascript/#collapse + * ======================================================================== + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // COLLAPSE PUBLIC CLASS DEFINITION + // ================================ + + var Collapse = function (element, options) { + this.$element = $(element) + this.options = $.extend({}, Collapse.DEFAULTS, options) + this.$trigger = $(this.options.trigger).filter('[href="#' + element.id + '"], [data-target="#' + element.id + '"]') + this.transitioning = null + + if (this.options.parent) { + this.$parent = this.getParent() + } else { + this.addAriaAndCollapsedClass(this.$element, this.$trigger) + } + + if (this.options.toggle) this.toggle() + } + + Collapse.VERSION = '3.3.2' + + Collapse.TRANSITION_DURATION = 350 + + Collapse.DEFAULTS = { + toggle: true, + trigger: '[data-toggle="collapse"]' + } + + Collapse.prototype.dimension = function () { + var hasWidth = this.$element.hasClass('width') + return hasWidth ? 'width' : 'height' + } + + Collapse.prototype.show = function () { + if (this.transitioning || this.$element.hasClass('in')) return + + var activesData + var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing') + + if (actives && actives.length) { + activesData = actives.data('bs.collapse') + if (activesData && activesData.transitioning) return + } + + var startEvent = $.Event('show.bs.collapse') + this.$element.trigger(startEvent) + if (startEvent.isDefaultPrevented()) return + + if (actives && actives.length) { + Plugin.call(actives, 'hide') + activesData || actives.data('bs.collapse', null) + } + + var dimension = this.dimension() + + this.$element + .removeClass('collapse') + .addClass('collapsing')[dimension](0) + .attr('aria-expanded', true) + + this.$trigger + .removeClass('collapsed') + .attr('aria-expanded', true) + + this.transitioning = 1 + + var complete = function () { + this.$element + .removeClass('collapsing') + .addClass('collapse in')[dimension]('') + this.transitioning = 0 + this.$element + .trigger('shown.bs.collapse') + } + + if (!$.support.transition) return complete.call(this) + + var scrollSize = $.camelCase(['scroll', dimension].join('-')) + + this.$element + .one('bsTransitionEnd', $.proxy(complete, this)) + .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize]) + } + + Collapse.prototype.hide = function () { + if (this.transitioning || !this.$element.hasClass('in')) return + + var startEvent = $.Event('hide.bs.collapse') + this.$element.trigger(startEvent) + if (startEvent.isDefaultPrevented()) return + + var dimension = this.dimension() + + this.$element[dimension](this.$element[dimension]())[0].offsetHeight + + this.$element + .addClass('collapsing') + .removeClass('collapse in') + .attr('aria-expanded', false) + + this.$trigger + .addClass('collapsed') + .attr('aria-expanded', false) + + this.transitioning = 1 + + var complete = function () { + this.transitioning = 0 + this.$element + .removeClass('collapsing') + .addClass('collapse') + .trigger('hidden.bs.collapse') + } + + if (!$.support.transition) return complete.call(this) + + this.$element + [dimension](0) + .one('bsTransitionEnd', $.proxy(complete, this)) + .emulateTransitionEnd(Collapse.TRANSITION_DURATION) + } + + Collapse.prototype.toggle = function () { + this[this.$element.hasClass('in') ? 'hide' : 'show']() + } + + Collapse.prototype.getParent = function () { + return $(this.options.parent) + .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]') + .each($.proxy(function (i, element) { + var $element = $(element) + this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element) + }, this)) + .end() + } + + Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) { + var isOpen = $element.hasClass('in') + + $element.attr('aria-expanded', isOpen) + $trigger + .toggleClass('collapsed', !isOpen) + .attr('aria-expanded', isOpen) + } + + function getTargetFromTrigger($trigger) { + var href + var target = $trigger.attr('data-target') + || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7 + + return $(target) + } + + + // COLLAPSE PLUGIN DEFINITION + // ========================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.collapse') + var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) + + if (!data && options.toggle && option == 'show') options.toggle = false + if (!data) $this.data('bs.collapse', (data = new Collapse(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.collapse + + $.fn.collapse = Plugin + $.fn.collapse.Constructor = Collapse + + + // COLLAPSE NO CONFLICT + // ==================== + + $.fn.collapse.noConflict = function () { + $.fn.collapse = old + return this + } + + + // COLLAPSE DATA-API + // ================= + + $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) { + var $this = $(this) + + if (!$this.attr('data-target')) e.preventDefault() + + var $target = getTargetFromTrigger($this) + var data = $target.data('bs.collapse') + var option = data ? 'toggle' : $.extend({}, $this.data(), { trigger: this }) + + Plugin.call($target, option) + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: dropdown.js v3.3.2 + * http://getbootstrap.com/javascript/#dropdowns + * ======================================================================== + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // DROPDOWN CLASS DEFINITION + // ========================= + + var backdrop = '.dropdown-backdrop' + var toggle = '[data-toggle="dropdown"]' + var Dropdown = function (element) { + $(element).on('click.bs.dropdown', this.toggle) + } + + Dropdown.VERSION = '3.3.2' + + Dropdown.prototype.toggle = function (e) { + var $this = $(this) + + if ($this.is('.disabled, :disabled')) return + + var $parent = getParent($this) + var isActive = $parent.hasClass('open') + + clearMenus() + + if (!isActive) { + if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) { + // if mobile we use a backdrop because click events don't delegate + $('<div class="dropdown-backdrop"/>').insertAfter($(this)).on('click', clearMenus) + } + + var relatedTarget = { relatedTarget: this } + $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget)) + + if (e.isDefaultPrevented()) return + + $this + .trigger('focus') + .attr('aria-expanded', 'true') + + $parent + .toggleClass('open') + .trigger('shown.bs.dropdown', relatedTarget) + } + + return false + } + + Dropdown.prototype.keydown = function (e) { + if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return + + var $this = $(this) + + e.preventDefault() + e.stopPropagation() + + if ($this.is('.disabled, :disabled')) return + + var $parent = getParent($this) + var isActive = $parent.hasClass('open') + + if ((!isActive && e.which != 27) || (isActive && e.which == 27)) { + if (e.which == 27) $parent.find(toggle).trigger('focus') + return $this.trigger('click') + } + + var desc = ' li:not(.divider):visible a' + var $items = $parent.find('[role="menu"]' + desc + ', [role="listbox"]' + desc) + + if (!$items.length) return + + var index = $items.index(e.target) + + if (e.which == 38 && index > 0) index-- // up + if (e.which == 40 && index < $items.length - 1) index++ // down + if (!~index) index = 0 + + $items.eq(index).trigger('focus') + } + + function clearMenus(e) { + if (e && e.which === 3) return + $(backdrop).remove() + $(toggle).each(function () { + var $this = $(this) + var $parent = getParent($this) + var relatedTarget = { relatedTarget: this } + + if (!$parent.hasClass('open')) return + + $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget)) + + if (e.isDefaultPrevented()) return + + $this.attr('aria-expanded', 'false') + $parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget) + }) + } + + function getParent($this) { + var selector = $this.attr('data-target') + + if (!selector) { + selector = $this.attr('href') + selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 + } + + var $parent = selector && $(selector) + + return $parent && $parent.length ? $parent : $this.parent() + } + + + // DROPDOWN PLUGIN DEFINITION + // ========================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.dropdown') + + if (!data) $this.data('bs.dropdown', (data = new Dropdown(this))) + if (typeof option == 'string') data[option].call($this) + }) + } + + var old = $.fn.dropdown + + $.fn.dropdown = Plugin + $.fn.dropdown.Constructor = Dropdown + + + // DROPDOWN NO CONFLICT + // ==================== + + $.fn.dropdown.noConflict = function () { + $.fn.dropdown = old + return this + } + + + // APPLY TO STANDARD DROPDOWN ELEMENTS + // =================================== + + $(document) + .on('click.bs.dropdown.data-api', clearMenus) + .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() }) + .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle) + .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown) + .on('keydown.bs.dropdown.data-api', '[role="menu"]', Dropdown.prototype.keydown) + .on('keydown.bs.dropdown.data-api', '[role="listbox"]', Dropdown.prototype.keydown) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: modal.js v3.3.2 + * http://getbootstrap.com/javascript/#modals + * ======================================================================== + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // MODAL CLASS DEFINITION + // ====================== + + var Modal = function (element, options) { + this.options = options + this.$body = $(document.body) + this.$element = $(element) + this.$backdrop = + this.isShown = null + this.scrollbarWidth = 0 + + if (this.options.remote) { + this.$element + .find('.modal-content') + .load(this.options.remote, $.proxy(function () { + this.$element.trigger('loaded.bs.modal') + }, this)) + } + } + + Modal.VERSION = '3.3.2' + + Modal.TRANSITION_DURATION = 300 + Modal.BACKDROP_TRANSITION_DURATION = 150 + + Modal.DEFAULTS = { + backdrop: true, + keyboard: true, + show: true + } + + Modal.prototype.toggle = function (_relatedTarget) { + return this.isShown ? this.hide() : this.show(_relatedTarget) + } + + Modal.prototype.show = function (_relatedTarget) { + var that = this + var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget }) + + this.$element.trigger(e) + + if (this.isShown || e.isDefaultPrevented()) return + + this.isShown = true + + this.checkScrollbar() + this.setScrollbar() + this.$body.addClass('modal-open') + + this.escape() + this.resize() + + this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this)) + + this.backdrop(function () { + var transition = $.support.transition && that.$element.hasClass('fade') + + if (!that.$element.parent().length) { + that.$element.appendTo(that.$body) // don't move modals dom position + } + + that.$element + .show() + .scrollTop(0) + + if (that.options.backdrop) that.adjustBackdrop() + that.adjustDialog() + + if (transition) { + that.$element[0].offsetWidth // force reflow + } + + that.$element + .addClass('in') + .attr('aria-hidden', false) + + that.enforceFocus() + + var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget }) + + transition ? + that.$element.find('.modal-dialog') // wait for modal to slide in + .one('bsTransitionEnd', function () { + that.$element.trigger('focus').trigger(e) + }) + .emulateTransitionEnd(Modal.TRANSITION_DURATION) : + that.$element.trigger('focus').trigger(e) + }) + } + + Modal.prototype.hide = function (e) { + if (e) e.preventDefault() + + e = $.Event('hide.bs.modal') + + this.$element.trigger(e) + + if (!this.isShown || e.isDefaultPrevented()) return + + this.isShown = false + + this.escape() + this.resize() + + $(document).off('focusin.bs.modal') + + this.$element + .removeClass('in') + .attr('aria-hidden', true) + .off('click.dismiss.bs.modal') + + $.support.transition && this.$element.hasClass('fade') ? + this.$element + .one('bsTransitionEnd', $.proxy(this.hideModal, this)) + .emulateTransitionEnd(Modal.TRANSITION_DURATION) : + this.hideModal() + } + + Modal.prototype.enforceFocus = function () { + $(document) + .off('focusin.bs.modal') // guard against infinite focus loop + .on('focusin.bs.modal', $.proxy(function (e) { + if (this.$element[0] !== e.target && !this.$element.has(e.target).length) { + this.$element.trigger('focus') + } + }, this)) + } + + Modal.prototype.escape = function () { + if (this.isShown && this.options.keyboard) { + this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) { + e.which == 27 && this.hide() + }, this)) + } else if (!this.isShown) { + this.$element.off('keydown.dismiss.bs.modal') + } + } + + Modal.prototype.resize = function () { + if (this.isShown) { + $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this)) + } else { + $(window).off('resize.bs.modal') + } + } + + Modal.prototype.hideModal = function () { + var that = this + this.$element.hide() + this.backdrop(function () { + that.$body.removeClass('modal-open') + that.resetAdjustments() + that.resetScrollbar() + that.$element.trigger('hidden.bs.modal') + }) + } + + Modal.prototype.removeBackdrop = function () { + this.$backdrop && this.$backdrop.remove() + this.$backdrop = null + } + + Modal.prototype.backdrop = function (callback) { + var that = this + var animate = this.$element.hasClass('fade') ? 'fade' : '' + + if (this.isShown && this.options.backdrop) { + var doAnimate = $.support.transition && animate + + this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />') + .prependTo(this.$element) + .on('click.dismiss.bs.modal', $.proxy(function (e) { + if (e.target !== e.currentTarget) return + this.options.backdrop == 'static' + ? this.$element[0].focus.call(this.$element[0]) + : this.hide.call(this) + }, this)) + + if (doAnimate) this.$backdrop[0].offsetWidth // force reflow + + this.$backdrop.addClass('in') + + if (!callback) return + + doAnimate ? + this.$backdrop + .one('bsTransitionEnd', callback) + .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) : + callback() + + } else if (!this.isShown && this.$backdrop) { + this.$backdrop.removeClass('in') + + var callbackRemove = function () { + that.removeBackdrop() + callback && callback() + } + $.support.transition && this.$element.hasClass('fade') ? + this.$backdrop + .one('bsTransitionEnd', callbackRemove) + .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) : + callbackRemove() + + } else if (callback) { + callback() + } + } + + // these following methods are used to handle overflowing modals + + Modal.prototype.handleUpdate = function () { + if (this.options.backdrop) this.adjustBackdrop() + this.adjustDialog() + } + + Modal.prototype.adjustBackdrop = function () { + this.$backdrop + .css('height', 0) + .css('height', this.$element[0].scrollHeight) + } + + Modal.prototype.adjustDialog = function () { + var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight + + this.$element.css({ + paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '', + paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : '' + }) + } + + Modal.prototype.resetAdjustments = function () { + this.$element.css({ + paddingLeft: '', + paddingRight: '' + }) + } + + Modal.prototype.checkScrollbar = function () { + this.bodyIsOverflowing = document.body.scrollHeight > document.documentElement.clientHeight + this.scrollbarWidth = this.measureScrollbar() + } + + Modal.prototype.setScrollbar = function () { + var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10) + if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth) + } + + Modal.prototype.resetScrollbar = function () { + this.$body.css('padding-right', '') + } + + Modal.prototype.measureScrollbar = function () { // thx walsh + var scrollDiv = document.createElement('div') + scrollDiv.className = 'modal-scrollbar-measure' + this.$body.append(scrollDiv) + var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth + this.$body[0].removeChild(scrollDiv) + return scrollbarWidth + } + + + // MODAL PLUGIN DEFINITION + // ======================= + + function Plugin(option, _relatedTarget) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.modal') + var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option) + + if (!data) $this.data('bs.modal', (data = new Modal(this, options))) + if (typeof option == 'string') data[option](_relatedTarget) + else if (options.show) data.show(_relatedTarget) + }) + } + + var old = $.fn.modal + + $.fn.modal = Plugin + $.fn.modal.Constructor = Modal + + + // MODAL NO CONFLICT + // ================= + + $.fn.modal.noConflict = function () { + $.fn.modal = old + return this + } + + + // MODAL DATA-API + // ============== + + $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) { + var $this = $(this) + var href = $this.attr('href') + var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7 + var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data()) + + if ($this.is('a')) e.preventDefault() + + $target.one('show.bs.modal', function (showEvent) { + if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown + $target.one('hidden.bs.modal', function () { + $this.is(':visible') && $this.trigger('focus') + }) + }) + Plugin.call($target, option, this) + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: tooltip.js v3.3.2 + * http://getbootstrap.com/javascript/#tooltip + * Inspired by the original jQuery.tipsy by Jason Frame + * ======================================================================== + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // TOOLTIP PUBLIC CLASS DEFINITION + // =============================== + + var Tooltip = function (element, options) { + this.type = + this.options = + this.enabled = + this.timeout = + this.hoverState = + this.$element = null + + this.init('tooltip', element, options) + } + + Tooltip.VERSION = '3.3.2' + + Tooltip.TRANSITION_DURATION = 150 + + Tooltip.DEFAULTS = { + animation: true, + placement: 'top', + selector: false, + template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>', + trigger: 'hover focus', + title: '', + delay: 0, + html: false, + container: false, + viewport: { + selector: 'body', + padding: 0 + } + } + + Tooltip.prototype.init = function (type, element, options) { + this.enabled = true + this.type = type + this.$element = $(element) + this.options = this.getOptions(options) + this.$viewport = this.options.viewport && $(this.options.viewport.selector || this.options.viewport) + + var triggers = this.options.trigger.split(' ') + + for (var i = triggers.length; i--;) { + var trigger = triggers[i] + + if (trigger == 'click') { + this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this)) + } else if (trigger != 'manual') { + var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin' + var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout' + + this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this)) + this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this)) + } + } + + this.options.selector ? + (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) : + this.fixTitle() + } + + Tooltip.prototype.getDefaults = function () { + return Tooltip.DEFAULTS + } + + Tooltip.prototype.getOptions = function (options) { + options = $.extend({}, this.getDefaults(), this.$element.data(), options) + + if (options.delay && typeof options.delay == 'number') { + options.delay = { + show: options.delay, + hide: options.delay + } + } + + return options + } + + Tooltip.prototype.getDelegateOptions = function () { + var options = {} + var defaults = this.getDefaults() + + this._options && $.each(this._options, function (key, value) { + if (defaults[key] != value) options[key] = value + }) + + return options + } + + Tooltip.prototype.enter = function (obj) { + var self = obj instanceof this.constructor ? + obj : $(obj.currentTarget).data('bs.' + this.type) + + if (self && self.$tip && self.$tip.is(':visible')) { + self.hoverState = 'in' + return + } + + if (!self) { + self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) + $(obj.currentTarget).data('bs.' + this.type, self) + } + + clearTimeout(self.timeout) + + self.hoverState = 'in' + + if (!self.options.delay || !self.options.delay.show) return self.show() + + self.timeout = setTimeout(function () { + if (self.hoverState == 'in') self.show() + }, self.options.delay.show) + } + + Tooltip.prototype.leave = function (obj) { + var self = obj instanceof this.constructor ? + obj : $(obj.currentTarget).data('bs.' + this.type) + + if (!self) { + self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) + $(obj.currentTarget).data('bs.' + this.type, self) + } + + clearTimeout(self.timeout) + + self.hoverState = 'out' + + if (!self.options.delay || !self.options.delay.hide) return self.hide() + + self.timeout = setTimeout(function () { + if (self.hoverState == 'out') self.hide() + }, self.options.delay.hide) + } + + Tooltip.prototype.show = function () { + var e = $.Event('show.bs.' + this.type) + + if (this.hasContent() && this.enabled) { + this.$element.trigger(e) + + var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0]) + if (e.isDefaultPrevented() || !inDom) return + var that = this + + var $tip = this.tip() + + var tipId = this.getUID(this.type) + + this.setContent() + $tip.attr('id', tipId) + this.$element.attr('aria-describedby', tipId) + + if (this.options.animation) $tip.addClass('fade') + + var placement = typeof this.options.placement == 'function' ? + this.options.placement.call(this, $tip[0], this.$element[0]) : + this.options.placement + + var autoToken = /\s?auto?\s?/i + var autoPlace = autoToken.test(placement) + if (autoPlace) placement = placement.replace(autoToken, '') || 'top' + + $tip + .detach() + .css({ top: 0, left: 0, display: 'block' }) + .addClass(placement) + .data('bs.' + this.type, this) + + this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element) + + var pos = this.getPosition() + var actualWidth = $tip[0].offsetWidth + var actualHeight = $tip[0].offsetHeight + + if (autoPlace) { + var orgPlacement = placement + var $container = this.options.container ? $(this.options.container) : this.$element.parent() + var containerDim = this.getPosition($container) + + placement = placement == 'bottom' && pos.bottom + actualHeight > containerDim.bottom ? 'top' : + placement == 'top' && pos.top - actualHeight < containerDim.top ? 'bottom' : + placement == 'right' && pos.right + actualWidth > containerDim.width ? 'left' : + placement == 'left' && pos.left - actualWidth < containerDim.left ? 'right' : + placement + + $tip + .removeClass(orgPlacement) + .addClass(placement) + } + + var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight) + + this.applyPlacement(calculatedOffset, placement) + + var complete = function () { + var prevHoverState = that.hoverState + that.$element.trigger('shown.bs.' + that.type) + that.hoverState = null + + if (prevHoverState == 'out') that.leave(that) + } + + $.support.transition && this.$tip.hasClass('fade') ? + $tip + .one('bsTransitionEnd', complete) + .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : + complete() + } + } + + Tooltip.prototype.applyPlacement = function (offset, placement) { + var $tip = this.tip() + var width = $tip[0].offsetWidth + var height = $tip[0].offsetHeight + + // manually read margins because getBoundingClientRect includes difference + var marginTop = parseInt($tip.css('margin-top'), 10) + var marginLeft = parseInt($tip.css('margin-left'), 10) + + // we must check for NaN for ie 8/9 + if (isNaN(marginTop)) marginTop = 0 + if (isNaN(marginLeft)) marginLeft = 0 + + offset.top = offset.top + marginTop + offset.left = offset.left + marginLeft + + // $.fn.offset doesn't round pixel values + // so we use setOffset directly with our own function B-0 + $.offset.setOffset($tip[0], $.extend({ + using: function (props) { + $tip.css({ + top: Math.round(props.top), + left: Math.round(props.left) + }) + } + }, offset), 0) + + $tip.addClass('in') + + // check to see if placing tip in new offset caused the tip to resize itself + var actualWidth = $tip[0].offsetWidth + var actualHeight = $tip[0].offsetHeight + + if (placement == 'top' && actualHeight != height) { + offset.top = offset.top + height - actualHeight + } + + var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight) + + if (delta.left) offset.left += delta.left + else offset.top += delta.top + + var isVertical = /top|bottom/.test(placement) + var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight + var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight' + + $tip.offset(offset) + this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical) + } + + Tooltip.prototype.replaceArrow = function (delta, dimension, isHorizontal) { + this.arrow() + .css(isHorizontal ? 'left' : 'top', 50 * (1 - delta / dimension) + '%') + .css(isHorizontal ? 'top' : 'left', '') + } + + Tooltip.prototype.setContent = function () { + var $tip = this.tip() + var title = this.getTitle() + + $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title) + $tip.removeClass('fade in top bottom left right') + } + + Tooltip.prototype.hide = function (callback) { + var that = this + var $tip = this.tip() + var e = $.Event('hide.bs.' + this.type) + + function complete() { + if (that.hoverState != 'in') $tip.detach() + that.$element + .removeAttr('aria-describedby') + .trigger('hidden.bs.' + that.type) + callback && callback() + } + + this.$element.trigger(e) + + if (e.isDefaultPrevented()) return + + $tip.removeClass('in') + + $.support.transition && this.$tip.hasClass('fade') ? + $tip + .one('bsTransitionEnd', complete) + .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : + complete() + + this.hoverState = null + + return this + } + + Tooltip.prototype.fixTitle = function () { + var $e = this.$element + if ($e.attr('title') || typeof ($e.attr('data-original-title')) != 'string') { + $e.attr('data-original-title', $e.attr('title') || '').attr('title', '') + } + } + + Tooltip.prototype.hasContent = function () { + return this.getTitle() + } + + Tooltip.prototype.getPosition = function ($element) { + $element = $element || this.$element + + var el = $element[0] + var isBody = el.tagName == 'BODY' + + var elRect = el.getBoundingClientRect() + if (elRect.width == null) { + // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093 + elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top }) + } + var elOffset = isBody ? { top: 0, left: 0 } : $element.offset() + var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() } + var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null + + return $.extend({}, elRect, scroll, outerDims, elOffset) + } + + Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) { + return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } : + placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } : + placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } : + /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width } + + } + + Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) { + var delta = { top: 0, left: 0 } + if (!this.$viewport) return delta + + var viewportPadding = this.options.viewport && this.options.viewport.padding || 0 + var viewportDimensions = this.getPosition(this.$viewport) + + if (/right|left/.test(placement)) { + var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll + var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight + if (topEdgeOffset < viewportDimensions.top) { // top overflow + delta.top = viewportDimensions.top - topEdgeOffset + } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow + delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset + } + } else { + var leftEdgeOffset = pos.left - viewportPadding + var rightEdgeOffset = pos.left + viewportPadding + actualWidth + if (leftEdgeOffset < viewportDimensions.left) { // left overflow + delta.left = viewportDimensions.left - leftEdgeOffset + } else if (rightEdgeOffset > viewportDimensions.width) { // right overflow + delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset + } + } + + return delta + } + + Tooltip.prototype.getTitle = function () { + var title + var $e = this.$element + var o = this.options + + title = $e.attr('data-original-title') + || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title) + + return title + } + + Tooltip.prototype.getUID = function (prefix) { + do prefix += ~~(Math.random() * 1000000) + while (document.getElementById(prefix)) + return prefix + } + + Tooltip.prototype.tip = function () { + return (this.$tip = this.$tip || $(this.options.template)) + } + + Tooltip.prototype.arrow = function () { + return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow')) + } + + Tooltip.prototype.enable = function () { + this.enabled = true + } + + Tooltip.prototype.disable = function () { + this.enabled = false + } + + Tooltip.prototype.toggleEnabled = function () { + this.enabled = !this.enabled + } + + Tooltip.prototype.toggle = function (e) { + var self = this + if (e) { + self = $(e.currentTarget).data('bs.' + this.type) + if (!self) { + self = new this.constructor(e.currentTarget, this.getDelegateOptions()) + $(e.currentTarget).data('bs.' + this.type, self) + } + } + + self.tip().hasClass('in') ? self.leave(self) : self.enter(self) + } + + Tooltip.prototype.destroy = function () { + var that = this + clearTimeout(this.timeout) + this.hide(function () { + that.$element.off('.' + that.type).removeData('bs.' + that.type) + }) + } + + + // TOOLTIP PLUGIN DEFINITION + // ========================= + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.tooltip') + var options = typeof option == 'object' && option + + if (!data && option == 'destroy') return + if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.tooltip + + $.fn.tooltip = Plugin + $.fn.tooltip.Constructor = Tooltip + + + // TOOLTIP NO CONFLICT + // =================== + + $.fn.tooltip.noConflict = function () { + $.fn.tooltip = old + return this + } + +}(jQuery); + +/* ======================================================================== + * Bootstrap: popover.js v3.3.2 + * http://getbootstrap.com/javascript/#popovers + * ======================================================================== + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // POPOVER PUBLIC CLASS DEFINITION + // =============================== + + var Popover = function (element, options) { + this.init('popover', element, options) + } + + if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js') + + Popover.VERSION = '3.3.2' + + Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, { + placement: 'right', + trigger: 'click', + content: '', + template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>' + }) + + + // NOTE: POPOVER EXTENDS tooltip.js + // ================================ + + Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype) + + Popover.prototype.constructor = Popover + + Popover.prototype.getDefaults = function () { + return Popover.DEFAULTS + } + + Popover.prototype.setContent = function () { + var $tip = this.tip() + var title = this.getTitle() + var content = this.getContent() + + $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title) + $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events + this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text' + ](content) + + $tip.removeClass('fade top bottom left right in') + + // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do + // this manually by checking the contents. + if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide() + } + + Popover.prototype.hasContent = function () { + return this.getTitle() || this.getContent() + } + + Popover.prototype.getContent = function () { + var $e = this.$element + var o = this.options + + return $e.attr('data-content') + || (typeof o.content == 'function' ? + o.content.call($e[0]) : + o.content) + } + + Popover.prototype.arrow = function () { + return (this.$arrow = this.$arrow || this.tip().find('.arrow')) + } + + Popover.prototype.tip = function () { + if (!this.$tip) this.$tip = $(this.options.template) + return this.$tip + } + + + // POPOVER PLUGIN DEFINITION + // ========================= + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.popover') + var options = typeof option == 'object' && option + + if (!data && option == 'destroy') return + if (!data) $this.data('bs.popover', (data = new Popover(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.popover + + $.fn.popover = Plugin + $.fn.popover.Constructor = Popover + + + // POPOVER NO CONFLICT + // =================== + + $.fn.popover.noConflict = function () { + $.fn.popover = old + return this + } + +}(jQuery); + +/* ======================================================================== + * Bootstrap: scrollspy.js v3.3.2 + * http://getbootstrap.com/javascript/#scrollspy + * ======================================================================== + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // SCROLLSPY CLASS DEFINITION + // ========================== + + function ScrollSpy(element, options) { + var process = $.proxy(this.process, this) + + this.$body = $('body') + this.$scrollElement = $(element).is('body') ? $(window) : $(element) + this.options = $.extend({}, ScrollSpy.DEFAULTS, options) + this.selector = (this.options.target || '') + ' .nav li > a' + this.offsets = [] + this.targets = [] + this.activeTarget = null + this.scrollHeight = 0 + + this.$scrollElement.on('scroll.bs.scrollspy', process) + this.refresh() + this.process() + } + + ScrollSpy.VERSION = '3.3.2' + + ScrollSpy.DEFAULTS = { + offset: 10 + } + + ScrollSpy.prototype.getScrollHeight = function () { + return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight) + } + + ScrollSpy.prototype.refresh = function () { + var offsetMethod = 'offset' + var offsetBase = 0 + + if (!$.isWindow(this.$scrollElement[0])) { + offsetMethod = 'position' + offsetBase = this.$scrollElement.scrollTop() + } + + this.offsets = [] + this.targets = [] + this.scrollHeight = this.getScrollHeight() + + var self = this + + this.$body + .find(this.selector) + .map(function () { + var $el = $(this) + var href = $el.data('target') || $el.attr('href') + var $href = /^#./.test(href) && $(href) + + return ($href + && $href.length + && $href.is(':visible') + && [[$href[offsetMethod]().top + offsetBase, href]]) || null + }) + .sort(function (a, b) { return a[0] - b[0] }) + .each(function () { + self.offsets.push(this[0]) + self.targets.push(this[1]) + }) + } + + ScrollSpy.prototype.process = function () { + var scrollTop = this.$scrollElement.scrollTop() + this.options.offset + var scrollHeight = this.getScrollHeight() + var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height() + var offsets = this.offsets + var targets = this.targets + var activeTarget = this.activeTarget + var i + + if (this.scrollHeight != scrollHeight) { + this.refresh() + } + + if (scrollTop >= maxScroll) { + return activeTarget != (i = targets[targets.length - 1]) && this.activate(i) + } + + if (activeTarget && scrollTop < offsets[0]) { + this.activeTarget = null + return this.clear() + } + + for (i = offsets.length; i--;) { + activeTarget != targets[i] + && scrollTop >= offsets[i] + && (!offsets[i + 1] || scrollTop <= offsets[i + 1]) + && this.activate(targets[i]) + } + } + + ScrollSpy.prototype.activate = function (target) { + this.activeTarget = target + + this.clear() + + var selector = this.selector + + '[data-target="' + target + '"],' + + this.selector + '[href="' + target + '"]' + + var active = $(selector) + .parents('li') + .addClass('active') + + if (active.parent('.dropdown-menu').length) { + active = active + .closest('li.dropdown') + .addClass('active') + } + + active.trigger('activate.bs.scrollspy') + } + + ScrollSpy.prototype.clear = function () { + $(this.selector) + .parentsUntil(this.options.target, '.active') + .removeClass('active') + } + + + // SCROLLSPY PLUGIN DEFINITION + // =========================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.scrollspy') + var options = typeof option == 'object' && option + + if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.scrollspy + + $.fn.scrollspy = Plugin + $.fn.scrollspy.Constructor = ScrollSpy + + + // SCROLLSPY NO CONFLICT + // ===================== + + $.fn.scrollspy.noConflict = function () { + $.fn.scrollspy = old + return this + } + + + // SCROLLSPY DATA-API + // ================== + + $(window).on('load.bs.scrollspy.data-api', function () { + $('[data-spy="scroll"]').each(function () { + var $spy = $(this) + Plugin.call($spy, $spy.data()) + }) + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: tab.js v3.3.2 + * http://getbootstrap.com/javascript/#tabs + * ======================================================================== + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // TAB CLASS DEFINITION + // ==================== + + var Tab = function (element) { + this.element = $(element) + } + + Tab.VERSION = '3.3.2' + + Tab.TRANSITION_DURATION = 150 + + Tab.prototype.show = function () { + var $this = this.element + var $ul = $this.closest('ul:not(.dropdown-menu)') + var selector = $this.data('target') + + if (!selector) { + selector = $this.attr('href') + selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 + } + + if ($this.parent('li').hasClass('active')) return + + var $previous = $ul.find('.active:last a') + var hideEvent = $.Event('hide.bs.tab', { + relatedTarget: $this[0] + }) + var showEvent = $.Event('show.bs.tab', { + relatedTarget: $previous[0] + }) + + $previous.trigger(hideEvent) + $this.trigger(showEvent) + + if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return + + var $target = $(selector) + + this.activate($this.closest('li'), $ul) + this.activate($target, $target.parent(), function () { + $previous.trigger({ + type: 'hidden.bs.tab', + relatedTarget: $this[0] + }) + $this.trigger({ + type: 'shown.bs.tab', + relatedTarget: $previous[0] + }) + }) + } + + Tab.prototype.activate = function (element, container, callback) { + var $active = container.find('> .active') + var transition = callback + && $.support.transition + && (($active.length && $active.hasClass('fade')) || !!container.find('> .fade').length) + + function next() { + $active + .removeClass('active') + .find('> .dropdown-menu > .active') + .removeClass('active') + .end() + .find('[data-toggle="tab"]') + .attr('aria-expanded', false) + + element + .addClass('active') + .find('[data-toggle="tab"]') + .attr('aria-expanded', true) + + if (transition) { + element[0].offsetWidth // reflow for transition + element.addClass('in') + } else { + element.removeClass('fade') + } + + if (element.parent('.dropdown-menu')) { + element + .closest('li.dropdown') + .addClass('active') + .end() + .find('[data-toggle="tab"]') + .attr('aria-expanded', true) + } + + callback && callback() + } + + $active.length && transition ? + $active + .one('bsTransitionEnd', next) + .emulateTransitionEnd(Tab.TRANSITION_DURATION) : + next() + + $active.removeClass('in') + } + + + // TAB PLUGIN DEFINITION + // ===================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.tab') + + if (!data) $this.data('bs.tab', (data = new Tab(this))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.tab + + $.fn.tab = Plugin + $.fn.tab.Constructor = Tab + + + // TAB NO CONFLICT + // =============== + + $.fn.tab.noConflict = function () { + $.fn.tab = old + return this + } + + + // TAB DATA-API + // ============ + + var clickHandler = function (e) { + e.preventDefault() + Plugin.call($(this), 'show') + } + + $(document) + .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler) + .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: affix.js v3.3.2 + * http://getbootstrap.com/javascript/#affix + * ======================================================================== + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // AFFIX CLASS DEFINITION + // ====================== + + var Affix = function (element, options) { + this.options = $.extend({}, Affix.DEFAULTS, options) + + this.$target = $(this.options.target) + .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this)) + .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this)) + + this.$element = $(element) + this.affixed = + this.unpin = + this.pinnedOffset = null + + this.checkPosition() + } + + Affix.VERSION = '3.3.2' + + Affix.RESET = 'affix affix-top affix-bottom' + + Affix.DEFAULTS = { + offset: 0, + target: window + } + + Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) { + var scrollTop = this.$target.scrollTop() + var position = this.$element.offset() + var targetHeight = this.$target.height() + + if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false + + if (this.affixed == 'bottom') { + if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom' + return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom' + } + + var initializing = this.affixed == null + var colliderTop = initializing ? scrollTop : position.top + var colliderHeight = initializing ? targetHeight : height + + if (offsetTop != null && scrollTop <= offsetTop) return 'top' + if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom' + + return false + } + + Affix.prototype.getPinnedOffset = function () { + if (this.pinnedOffset) return this.pinnedOffset + this.$element.removeClass(Affix.RESET).addClass('affix') + var scrollTop = this.$target.scrollTop() + var position = this.$element.offset() + return (this.pinnedOffset = position.top - scrollTop) + } + + Affix.prototype.checkPositionWithEventLoop = function () { + setTimeout($.proxy(this.checkPosition, this), 1) + } + + Affix.prototype.checkPosition = function () { + if (!this.$element.is(':visible')) return + + var height = this.$element.height() + var offset = this.options.offset + var offsetTop = offset.top + var offsetBottom = offset.bottom + var scrollHeight = $('body').height() + + if (typeof offset != 'object') offsetBottom = offsetTop = offset + if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element) + if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element) + + var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom) + + if (this.affixed != affix) { + if (this.unpin != null) this.$element.css('top', '') + + var affixType = 'affix' + (affix ? '-' + affix : '') + var e = $.Event(affixType + '.bs.affix') + + this.$element.trigger(e) + + if (e.isDefaultPrevented()) return + + this.affixed = affix + this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null + + this.$element + .removeClass(Affix.RESET) + .addClass(affixType) + .trigger(affixType.replace('affix', 'affixed') + '.bs.affix') + } + + if (affix == 'bottom') { + this.$element.offset({ + top: scrollHeight - height - offsetBottom + }) + } + } + + + // AFFIX PLUGIN DEFINITION + // ======================= + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.affix') + var options = typeof option == 'object' && option + + if (!data) $this.data('bs.affix', (data = new Affix(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.affix + + $.fn.affix = Plugin + $.fn.affix.Constructor = Affix + + + // AFFIX NO CONFLICT + // ================= + + $.fn.affix.noConflict = function () { + $.fn.affix = old + return this + } + + + // AFFIX DATA-API + // ============== + + $(window).on('load', function () { + $('[data-spy="affix"]').each(function () { + var $spy = $(this) + var data = $spy.data() + + data.offset = data.offset || {} + + if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom + if (data.offsetTop != null) data.offset.top = data.offsetTop + + Plugin.call($spy, data) + }) + }) + +}(jQuery); diff --git a/views/default/js/bootstrap.min.js b/views/default/js/bootstrap.min.js new file mode 100644 index 0000000..c6d3692 --- /dev/null +++ b/views/default/js/bootstrap.min.js @@ -0,0 +1,7 @@ +/*! + * Bootstrap v3.3.2 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ +if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.2",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.2",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")&&(c.prop("checked")&&this.$element.hasClass("active")?a=!1:b.find(".active").removeClass("active")),a&&c.prop("checked",!this.$element.hasClass("active")).trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active"));a&&this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),c.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=this.sliding=this.interval=this.$active=this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.2",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));return a>this.$items.length-1||0>a?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&"show"==b&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a(this.options.trigger).filter('[href="#'+b.id+'"], [data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.2",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0,trigger:'[data-toggle="collapse"]'},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":a.extend({},e.data(),{trigger:this});c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){b&&3===b.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=c(d),f={relatedTarget:this};e.hasClass("open")&&(e.trigger(b=a.Event("hide.bs.dropdown",f)),b.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger("hidden.bs.dropdown",f)))}))}function c(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.2",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=c(e),g=f.hasClass("open");if(b(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a('<div class="dropdown-backdrop"/>').insertAfter(a(this)).on("click",b);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger("shown.bs.dropdown",h)}return!1}},g.prototype.keydown=function(b){if(/(38|40|27|32)/.test(b.which)&&!/input|textarea/i.test(b.target.tagName)){var d=a(this);if(b.preventDefault(),b.stopPropagation(),!d.is(".disabled, :disabled")){var e=c(d),g=e.hasClass("open");if(!g&&27!=b.which||g&&27==b.which)return 27==b.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.divider):visible a",i=e.find('[role="menu"]'+h+', [role="listbox"]'+h);if(i.length){var j=i.index(b.target);38==b.which&&j>0&&j--,40==b.which&&j<i.length-1&&j++,~j||(j=0),i.eq(j).trigger("focus")}}}};var h=a.fn.dropdown;a.fn.dropdown=d,a.fn.dropdown.Constructor=g,a.fn.dropdown.noConflict=function(){return a.fn.dropdown=h,this},a(document).on("click.bs.dropdown.data-api",b).on("click.bs.dropdown.data-api",".dropdown form",function(a){a.stopPropagation()}).on("click.bs.dropdown.data-api",f,g.prototype.toggle).on("keydown.bs.dropdown.data-api",f,g.prototype.keydown).on("keydown.bs.dropdown.data-api",'[role="menu"]',g.prototype.keydown).on("keydown.bs.dropdown.data-api",'[role="listbox"]',g.prototype.keydown)}(jQuery),+function(a){"use strict";function b(b,d){return this.each(function(){var e=a(this),f=e.data("bs.modal"),g=a.extend({},c.DEFAULTS,e.data(),"object"==typeof b&&b);f||e.data("bs.modal",f=new c(this,g)),"string"==typeof b?f[b](d):g.show&&f.show(d)})}var c=function(b,c){this.options=c,this.$body=a(document.body),this.$element=a(b),this.$backdrop=this.isShown=null,this.scrollbarWidth=0,this.options.remote&&this.$element.find(".modal-content").load(this.options.remote,a.proxy(function(){this.$element.trigger("loaded.bs.modal")},this))};c.VERSION="3.3.2",c.TRANSITION_DURATION=300,c.BACKDROP_TRANSITION_DURATION=150,c.DEFAULTS={backdrop:!0,keyboard:!0,show:!0},c.prototype.toggle=function(a){return this.isShown?this.hide():this.show(a)},c.prototype.show=function(b){var d=this,e=a.Event("show.bs.modal",{relatedTarget:b});this.$element.trigger(e),this.isShown||e.isDefaultPrevented()||(this.isShown=!0,this.checkScrollbar(),this.setScrollbar(),this.$body.addClass("modal-open"),this.escape(),this.resize(),this.$element.on("click.dismiss.bs.modal",'[data-dismiss="modal"]',a.proxy(this.hide,this)),this.backdrop(function(){var e=a.support.transition&&d.$element.hasClass("fade");d.$element.parent().length||d.$element.appendTo(d.$body),d.$element.show().scrollTop(0),d.options.backdrop&&d.adjustBackdrop(),d.adjustDialog(),e&&d.$element[0].offsetWidth,d.$element.addClass("in").attr("aria-hidden",!1),d.enforceFocus();var f=a.Event("shown.bs.modal",{relatedTarget:b});e?d.$element.find(".modal-dialog").one("bsTransitionEnd",function(){d.$element.trigger("focus").trigger(f)}).emulateTransitionEnd(c.TRANSITION_DURATION):d.$element.trigger("focus").trigger(f)}))},c.prototype.hide=function(b){b&&b.preventDefault(),b=a.Event("hide.bs.modal"),this.$element.trigger(b),this.isShown&&!b.isDefaultPrevented()&&(this.isShown=!1,this.escape(),this.resize(),a(document).off("focusin.bs.modal"),this.$element.removeClass("in").attr("aria-hidden",!0).off("click.dismiss.bs.modal"),a.support.transition&&this.$element.hasClass("fade")?this.$element.one("bsTransitionEnd",a.proxy(this.hideModal,this)).emulateTransitionEnd(c.TRANSITION_DURATION):this.hideModal())},c.prototype.enforceFocus=function(){a(document).off("focusin.bs.modal").on("focusin.bs.modal",a.proxy(function(a){this.$element[0]===a.target||this.$element.has(a.target).length||this.$element.trigger("focus")},this))},c.prototype.escape=function(){this.isShown&&this.options.keyboard?this.$element.on("keydown.dismiss.bs.modal",a.proxy(function(a){27==a.which&&this.hide()},this)):this.isShown||this.$element.off("keydown.dismiss.bs.modal")},c.prototype.resize=function(){this.isShown?a(window).on("resize.bs.modal",a.proxy(this.handleUpdate,this)):a(window).off("resize.bs.modal")},c.prototype.hideModal=function(){var a=this;this.$element.hide(),this.backdrop(function(){a.$body.removeClass("modal-open"),a.resetAdjustments(),a.resetScrollbar(),a.$element.trigger("hidden.bs.modal")})},c.prototype.removeBackdrop=function(){this.$backdrop&&this.$backdrop.remove(),this.$backdrop=null},c.prototype.backdrop=function(b){var d=this,e=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var f=a.support.transition&&e;if(this.$backdrop=a('<div class="modal-backdrop '+e+'" />').prependTo(this.$element).on("click.dismiss.bs.modal",a.proxy(function(a){a.target===a.currentTarget&&("static"==this.options.backdrop?this.$element[0].focus.call(this.$element[0]):this.hide.call(this))},this)),f&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),!b)return;f?this.$backdrop.one("bsTransitionEnd",b).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):b()}else if(!this.isShown&&this.$backdrop){this.$backdrop.removeClass("in");var g=function(){d.removeBackdrop(),b&&b()};a.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one("bsTransitionEnd",g).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):g()}else b&&b()},c.prototype.handleUpdate=function(){this.options.backdrop&&this.adjustBackdrop(),this.adjustDialog()},c.prototype.adjustBackdrop=function(){this.$backdrop.css("height",0).css("height",this.$element[0].scrollHeight)},c.prototype.adjustDialog=function(){var a=this.$element[0].scrollHeight>document.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){this.bodyIsOverflowing=document.body.scrollHeight>document.documentElement.clientHeight,this.scrollbarWidth=this.measureScrollbar()},c.prototype.setScrollbar=function(){var a=parseInt(this.$body.css("padding-right")||0,10);this.bodyIsOverflowing&&this.$body.css("padding-right",a+this.scrollbarWidth)},c.prototype.resetScrollbar=function(){this.$body.css("padding-right","")},c.prototype.measureScrollbar=function(){var a=document.createElement("div");a.className="modal-scrollbar-measure",this.$body.append(a);var b=a.offsetWidth-a.clientWidth;return this.$body[0].removeChild(a),b};var d=a.fn.modal;a.fn.modal=b,a.fn.modal.Constructor=c,a.fn.modal.noConflict=function(){return a.fn.modal=d,this},a(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',function(c){var d=a(this),e=d.attr("href"),f=a(d.attr("data-target")||e&&e.replace(/.*(?=#[^\s]+$)/,"")),g=f.data("bs.modal")?"toggle":a.extend({remote:!/#/.test(e)&&e},f.data(),d.data());d.is("a")&&c.preventDefault(),f.one("show.bs.modal",function(a){a.isDefaultPrevented()||f.one("hidden.bs.modal",function(){d.is(":visible")&&d.trigger("focus")})}),b.call(f,g,this)})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tooltip"),f="object"==typeof b&&b;(e||"destroy"!=b)&&(e||d.data("bs.tooltip",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.type=this.options=this.enabled=this.timeout=this.hoverState=this.$element=null,this.init("tooltip",a,b)};c.VERSION="3.3.2",c.TRANSITION_DURATION=150,c.DEFAULTS={animation:!0,placement:"top",selector:!1,template:'<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(this.options.viewport.selector||this.options.viewport);for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c&&c.$tip&&c.$tip.is(":visible")?void(c.hoverState="in"):(c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide()},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.options.container?a(this.options.container):this.$element.parent(),p=this.getPosition(o);h="bottom"==h&&k.bottom+m>p.bottom?"top":"top"==h&&k.top-m<p.top?"bottom":"right"==h&&k.right+l>p.width?"left":"left"==h&&k.left-l<p.left?"right":h,f.removeClass(n).addClass(h)}var q=this.getCalculatedOffset(h,k,l,m);this.applyPlacement(q,h);var r=function(){var a=e.hoverState;e.$element.trigger("shown.bs."+e.type),e.hoverState=null,"out"==a&&e.leave(e)};a.support.transition&&this.$tip.hasClass("fade")?f.one("bsTransitionEnd",r).emulateTransitionEnd(c.TRANSITION_DURATION):r()}},c.prototype.applyPlacement=function(b,c){var d=this.tip(),e=d[0].offsetWidth,f=d[0].offsetHeight,g=parseInt(d.css("margin-top"),10),h=parseInt(d.css("margin-left"),10);isNaN(g)&&(g=0),isNaN(h)&&(h=0),b.top=b.top+g,b.left=b.left+h,a.offset.setOffset(d[0],a.extend({using:function(a){d.css({top:Math.round(a.top),left:Math.round(a.left)})}},b),0),d.addClass("in");var i=d[0].offsetWidth,j=d[0].offsetHeight;"top"==c&&j!=f&&(b.top=b.top+f-j);var k=this.getViewportAdjustedDelta(c,b,i,j);k.left?b.left+=k.left:b.top+=k.top;var l=/top|bottom/.test(c),m=l?2*k.left-e+i:2*k.top-f+j,n=l?"offsetWidth":"offsetHeight";d.offset(b),this.replaceArrow(m,d[0][n],l)},c.prototype.replaceArrow=function(a,b,c){this.arrow().css(c?"left":"top",50*(1-a/b)+"%").css(c?"top":"left","")},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle();a.find(".tooltip-inner")[this.options.html?"html":"text"](b),a.removeClass("fade in top bottom left right")},c.prototype.hide=function(b){function d(){"in"!=e.hoverState&&f.detach(),e.$element.removeAttr("aria-describedby").trigger("hidden.bs."+e.type),b&&b()}var e=this,f=this.tip(),g=a.Event("hide.bs."+this.type);return this.$element.trigger(g),g.isDefaultPrevented()?void 0:(f.removeClass("in"),a.support.transition&&this.$tip.hasClass("fade")?f.one("bsTransitionEnd",d).emulateTransitionEnd(c.TRANSITION_DURATION):d(),this.hoverState=null,this)},c.prototype.fixTitle=function(){var a=this.$element;(a.attr("title")||"string"!=typeof a.attr("data-original-title"))&&a.attr("data-original-title",a.attr("title")||"").attr("title","")},c.prototype.hasContent=function(){return this.getTitle()},c.prototype.getPosition=function(b){b=b||this.$element;var c=b[0],d="BODY"==c.tagName,e=c.getBoundingClientRect();null==e.width&&(e=a.extend({},e,{width:e.right-e.left,height:e.bottom-e.top}));var f=d?{top:0,left:0}:b.offset(),g={scroll:d?document.documentElement.scrollTop||document.body.scrollTop:b.scrollTop()},h=d?{width:a(window).width(),height:a(window).height()}:null;return a.extend({},e,g,h,f)},c.prototype.getCalculatedOffset=function(a,b,c,d){return"bottom"==a?{top:b.top+b.height,left:b.left+b.width/2-c/2}:"top"==a?{top:b.top-d,left:b.left+b.width/2-c/2}:"left"==a?{top:b.top+b.height/2-d/2,left:b.left-c}:{top:b.top+b.height/2-d/2,left:b.left+b.width}},c.prototype.getViewportAdjustedDelta=function(a,b,c,d){var e={top:0,left:0};if(!this.$viewport)return e;var f=this.options.viewport&&this.options.viewport.padding||0,g=this.getPosition(this.$viewport);if(/right|left/.test(a)){var h=b.top-f-g.scroll,i=b.top+f-g.scroll+d;h<g.top?e.top=g.top-h:i>g.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;j<g.left?e.left=g.left-j:k>g.width&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){return this.$tip=this.$tip||a(this.options.template)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type)})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;(e||"destroy"!=b)&&(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.2",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")},c.prototype.tip=function(){return this.$tip||(this.$tip=a(this.options.template)),this.$tip};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){var e=a.proxy(this.process,this);this.$body=a("body"),this.$scrollElement=a(a(c).is("body")?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",e),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.2",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b="offset",c=0;a.isWindow(this.$scrollElement[0])||(b="position",c=this.$scrollElement.scrollTop()),this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight();var d=this;this.$body.find(this.selector).map(function(){var d=a(this),e=d.data("target")||d.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[b]().top+c,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){d.offsets.push(this[0]),d.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b<e[0])return this.activeTarget=null,this.clear();for(a=e.length;a--;)g!=f[a]&&b>=e[a]&&(!e[a+1]||b<=e[a+1])&&this.activate(f[a])},b.prototype.activate=function(b){this.activeTarget=b,this.clear();var c=this.selector+'[data-target="'+b+'"],'+this.selector+'[href="'+b+'"]',d=a(c).parents("li").addClass("active");d.parent(".dropdown-menu").length&&(d=d.closest("li.dropdown").addClass("active")),d.trigger("activate.bs.scrollspy")},b.prototype.clear=function(){a(this.selector).parentsUntil(this.options.target,".active").removeClass("active")};var d=a.fn.scrollspy;a.fn.scrollspy=c,a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=d,this},a(window).on("load.bs.scrollspy.data-api",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);c.call(b,b.data())})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new c(this)),"string"==typeof b&&e[b]()})}var c=function(b){this.element=a(b)};c.VERSION="3.3.2",c.TRANSITION_DURATION=150,c.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.data("target");if(d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),!b.parent("li").hasClass("active")){var e=c.find(".active:last a"),f=a.Event("hide.bs.tab",{relatedTarget:b[0]}),g=a.Event("show.bs.tab",{relatedTarget:e[0]});if(e.trigger(f),b.trigger(g),!g.isDefaultPrevented()&&!f.isDefaultPrevented()){var h=a(d);this.activate(b.closest("li"),c),this.activate(h,h.parent(),function(){e.trigger({type:"hidden.bs.tab",relatedTarget:b[0]}),b.trigger({type:"shown.bs.tab",relatedTarget:e[0]})})}}},c.prototype.activate=function(b,d,e){function f(){g.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu")&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e() +}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=this.unpin=this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.2",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return c>e?"top":!1;if("bottom"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:"bottom":a-d>=e+g?!1:"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=e?"top":null!=d&&i+j>=a-d?"bottom":!1},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=a("body").height();"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery); \ No newline at end of file diff --git a/views/default/js/checkall.js b/views/default/js/checkall.js new file mode 100644 index 0000000..72b3ff8 --- /dev/null +++ b/views/default/js/checkall.js @@ -0,0 +1,21 @@ + +function checkAll(obj) { + 'use strict'; + // Получаем NodeList дочерних элементов input формы: + var items = obj.form.getElementsByTagName("input"), + len, i; + // Здесь, увы цикл по элементам формы: + for (i = 0, len = items.length; i < len; i += 1) { + // Если текущий элемент является чекбоксом... + if (items.item(i).type && items.item(i).type === "checkbox") { + // Дальше логика простая: если checkbox "Выбрать всё" - отмечен + if (obj.checked) { + // Отмечаем все чекбоксы... + items.item(i).checked = true; + } else { + // Иначе снимаем отметки со всех чекбоксов: + items.item(i).checked = false; + } + } + } +} diff --git a/views/default/js/dynamicTable.js b/views/default/js/dynamicTable.js new file mode 100644 index 0000000..496ee05 --- /dev/null +++ b/views/default/js/dynamicTable.js @@ -0,0 +1,50 @@ +/** + * Created by moskitos80 on 23.08.14. + */ +var DynamicTable = (function (GLOB) { + var RID = 0; + return function (tBody) { + /* Если ф-цию вызвали не как конструктор фиксим этот момент: */ + if (!(this instanceof arguments.callee)) { + return new arguments.callee.apply(arguments); + } + //Делегируем прослушку событий элементу tbody + tBody.onclick = function(e) { + var evt = e || GLOB.event, + trg = evt.target || evt.srcElement; + if (trg.className && trg.className.indexOf("add") !== -1) { + _addRow(trg.parentNode.parentNode, tBody); + } else if (trg.className && trg.className.indexOf("del") !== -1) { + tBody.rows.length > 1 && _delRow(trg.parentNode.parentNode, tBody); + } + }; + var _rowTpl = tBody.rows[0].cloneNode(true); + // Корректируем имена элементов формы + var _correctNames = function (row) { + var elements = row.getElementsByTagName("*"); + for (var i = 0; i < elements.length; i += 1) { + if (elements.item(i).name) { + if (elements.item(i).type && + elements.item(i).type === "radio" && + elements.item(i).className && + elements.item(i).className.indexOf("glob") !== -1) + { + elements.item(i).value = RID; + } else { + elements.item(i).name = RID + "["+ elements.item(i).name +"]"; + } + } + } + RID++; + return row; + }; + var _addRow = function (before, tBody) { + var newNode = _correctNames(_rowTpl.cloneNode(true)); + tBody.insertBefore(newNode, before.nextSibling); + }; + var _delRow = function (row, tBody) { + tBody.removeChild(row); + }; + _correctNames(tBody.rows[0]); + }; +})(this); diff --git a/views/default/js/jquery-1.11.0.min.map b/views/default/js/jquery-1.11.0.min.map new file mode 100644 index 0000000..2775c54 --- /dev/null +++ b/views/default/js/jquery-1.11.0.min.map @@ -0,0 +1 @@ +{"version":3,"file":"jquery-1.11.0.min.js","sources":["jquery-1.11.0.js"],"names":["global","factory","module","exports","document","w","Error","window","this","noGlobal","deletedIds","slice","concat","push","indexOf","class2type","toString","hasOwn","hasOwnProperty","trim","support","version","jQuery","selector","context","fn","init","rtrim","rmsPrefix","rdashAlpha","fcamelCase","all","letter","toUpperCase","prototype","jquery","constructor","length","toArray","call","get","num","pushStack","elems","ret","merge","prevObject","each","callback","args","map","elem","i","apply","arguments","first","eq","last","len","j","end","sort","splice","extend","src","copyIsArray","copy","name","options","clone","target","deep","isFunction","isPlainObject","isArray","undefined","expando","Math","random","replace","isReady","error","msg","noop","obj","type","Array","isWindow","isNumeric","parseFloat","isEmptyObject","key","nodeType","e","ownLast","globalEval","data","execScript","camelCase","string","nodeName","toLowerCase","value","isArraylike","text","makeArray","arr","results","Object","inArray","max","second","grep","invert","callbackInverse","matches","callbackExpect","arg","guid","proxy","tmp","now","Date","split","Sizzle","Expr","getText","isXML","compile","outermostContext","sortInput","hasDuplicate","setDocument","docElem","documentIsHTML","rbuggyQSA","rbuggyMatches","contains","preferredDoc","dirruns","done","classCache","createCache","tokenCache","compilerCache","sortOrder","a","b","strundefined","MAX_NEGATIVE","pop","push_native","booleans","whitespace","characterEncoding","identifier","attributes","pseudos","RegExp","rcomma","rcombinators","rattributeQuotes","rpseudo","ridentifier","matchExpr","ID","CLASS","TAG","ATTR","PSEUDO","CHILD","bool","needsContext","rinputs","rheader","rnative","rquickExpr","rsibling","rescape","runescape","funescape","_","escaped","escapedWhitespace","high","String","fromCharCode","childNodes","els","seed","match","m","groups","old","nid","newContext","newSelector","ownerDocument","exec","getElementById","parentNode","id","getElementsByTagName","getElementsByClassName","qsa","test","tokenize","getAttribute","setAttribute","toSelector","testContext","join","querySelectorAll","qsaError","removeAttribute","select","keys","cache","cacheLength","shift","markFunction","assert","div","createElement","removeChild","addHandle","attrs","handler","attrHandle","siblingCheck","cur","diff","sourceIndex","nextSibling","createInputPseudo","createButtonPseudo","createPositionalPseudo","argument","matchIndexes","documentElement","node","hasCompare","doc","parent","defaultView","top","addEventListener","attachEvent","className","appendChild","createComment","innerHTML","firstChild","getById","getElementsByName","find","filter","attrId","getAttributeNode","tag","input","matchesSelector","webkitMatchesSelector","mozMatchesSelector","oMatchesSelector","msMatchesSelector","disconnectedMatch","compareDocumentPosition","adown","bup","compare","sortDetached","aup","ap","bp","unshift","expr","elements","attr","val","specified","uniqueSort","duplicates","detectDuplicates","sortStable","textContent","nodeValue","selectors","createPseudo","relative",">","dir"," ","+","~","preFilter","excess","unquoted","nodeNameSelector","pattern","operator","check","result","what","simple","forward","ofType","xml","outerCache","nodeIndex","start","useCache","lastChild","pseudo","setFilters","idx","matched","not","matcher","unmatched","has","innerText","lang","elemLang","hash","location","root","focus","activeElement","hasFocus","href","tabIndex","enabled","disabled","checked","selected","selectedIndex","empty","header","button","even","odd","lt","gt","radio","checkbox","file","password","image","submit","reset","filters","parseOnly","tokens","soFar","preFilters","cached","addCombinator","combinator","base","checkNonElements","doneName","oldCache","newCache","elementMatcher","matchers","condense","newUnmatched","mapped","setMatcher","postFilter","postFinder","postSelector","temp","preMap","postMap","preexisting","multipleContexts","matcherIn","matcherOut","matcherFromTokens","checkContext","leadingRelative","implicitRelative","matchContext","matchAnyContext","matcherFromGroupMatchers","elementMatchers","setMatchers","bySet","byElement","superMatcher","outermost","matchedCount","setMatched","contextBackup","dirrunsUnique","group","contexts","token","div1","defaultValue","unique","isXMLDoc","rneedsContext","rsingleTag","risSimple","winnow","qualifier","self","is","rootjQuery","charAt","parseHTML","ready","rparentsprev","guaranteedUnique","children","contents","next","prev","until","sibling","n","r","targets","closest","l","pos","index","prevAll","add","addBack","parents","parentsUntil","nextAll","nextUntil","prevUntil","siblings","contentDocument","contentWindow","reverse","rnotwhite","optionsCache","createOptions","object","flag","Callbacks","firing","memory","fired","firingLength","firingIndex","firingStart","list","stack","once","fire","stopOnFalse","disable","remove","lock","locked","fireWith","Deferred","func","tuples","state","promise","always","deferred","fail","then","fns","newDefer","tuple","returned","resolve","reject","progress","notify","pipe","stateString","when","subordinate","resolveValues","remaining","updateFunc","values","progressValues","notifyWith","resolveWith","progressContexts","resolveContexts","readyList","readyWait","holdReady","hold","wait","body","setTimeout","trigger","off","detach","removeEventListener","completed","detachEvent","event","readyState","frameElement","doScroll","doScrollCheck","inlineBlockNeedsLayout","container","style","cssText","zoom","offsetWidth","deleteExpando","acceptData","noData","rbrace","rmultiDash","dataAttr","parseJSON","isEmptyDataObject","internalData","pvt","thisCache","internalKey","isNode","toJSON","internalRemoveData","cleanData","applet ","embed ","object ","hasData","removeData","_data","_removeData","queue","dequeue","startLength","hooks","_queueHooks","stop","setter","clearQueue","count","defer","pnum","source","cssExpand","isHidden","el","css","access","chainable","emptyGet","raw","bulk","rcheckableType","fragment","createDocumentFragment","leadingWhitespace","tbody","htmlSerialize","html5Clone","cloneNode","outerHTML","appendChecked","noCloneChecked","checkClone","noCloneEvent","click","eventName","change","focusin","rformElems","rkeyEvent","rmouseEvent","rfocusMorph","rtypenamespace","returnTrue","returnFalse","safeActiveElement","err","types","events","t","handleObjIn","special","eventHandle","handleObj","handlers","namespaces","origType","elemData","handle","triggered","dispatch","delegateType","bindType","namespace","delegateCount","setup","mappedTypes","origCount","teardown","removeEvent","onlyHandlers","ontype","bubbleType","eventPath","Event","isTrigger","namespace_re","noBubble","parentWindow","isPropagationStopped","preventDefault","isDefaultPrevented","_default","fix","handlerQueue","delegateTarget","preDispatch","currentTarget","isImmediatePropagationStopped","stopPropagation","postDispatch","sel","prop","originalEvent","fixHook","fixHooks","mouseHooks","keyHooks","props","srcElement","metaKey","original","which","charCode","keyCode","eventDoc","fromElement","pageX","clientX","scrollLeft","clientLeft","pageY","clientY","scrollTop","clientTop","relatedTarget","toElement","load","blur","beforeunload","returnValue","simulate","bubble","isSimulated","defaultPrevented","getPreventDefault","timeStamp","cancelBubble","stopImmediatePropagation","mouseenter","mouseleave","orig","related","submitBubbles","form","_submit_bubble","changeBubbles","propertyName","_just_changed","focusinBubbles","attaches","on","one","origFn","triggerHandler","createSafeFragment","nodeNames","safeFrag","rinlinejQuery","rnoshimcache","rleadingWhitespace","rxhtmlTag","rtagName","rtbody","rhtml","rnoInnerhtml","rchecked","rscriptType","rscriptTypeMasked","rcleanScript","wrapMap","option","legend","area","param","thead","tr","col","td","safeFragment","fragmentDiv","optgroup","tfoot","colgroup","caption","th","getAll","found","fixDefaultChecked","defaultChecked","manipulationTarget","content","disableScript","restoreScript","setGlobalEval","refElements","cloneCopyEvent","dest","oldData","curData","fixCloneNodeIssues","defaultSelected","dataAndEvents","deepDataAndEvents","destElements","srcElements","inPage","buildFragment","scripts","selection","wrap","safe","nodes","createTextNode","append","domManip","prepend","insertBefore","before","after","keepData","html","replaceWith","replaceChild","hasScripts","set","iNoClone","_evalUrl","appendTo","prependTo","insertAfter","replaceAll","insert","iframe","elemdisplay","actualDisplay","display","getDefaultComputedStyle","defaultDisplay","write","close","shrinkWrapBlocksVal","divReset","opacity","cssFloat","backgroundClip","clearCloneStyle","shrinkWrapBlocks","containerStyles","width","rmargin","rnumnonpx","getStyles","curCSS","rposition","getComputedStyle","computed","minWidth","maxWidth","getPropertyValue","currentStyle","left","rs","rsLeft","runtimeStyle","pixelLeft","addGetHookIf","conditionFn","hookFn","condition","reliableHiddenOffsetsVal","boxSizingVal","boxSizingReliableVal","pixelPositionVal","reliableMarginRightVal","reliableHiddenOffsets","tds","isSupported","offsetHeight","boxSizing","computeStyleTests","boxSizingReliable","pixelPosition","reliableMarginRight","marginDiv","marginRight","swap","ralpha","ropacity","rdisplayswap","rnumsplit","rrelNum","cssShow","position","visibility","cssNormalTransform","letterSpacing","fontWeight","cssPrefixes","vendorPropName","capName","origName","showHide","show","hidden","setPositiveNumber","subtract","augmentWidthOrHeight","extra","isBorderBox","styles","getWidthOrHeight","valueIsBorderBox","cssHooks","cssNumber","columnCount","fillOpacity","lineHeight","order","orphans","widows","zIndex","cssProps","float","$1","margin","padding","border","prefix","suffix","expand","expanded","parts","hide","toggle","Tween","easing","unit","propHooks","run","percent","eased","duration","step","tween","fx","linear","p","swing","cos","PI","fxNow","timerId","rfxtypes","rfxnum","rrun","animationPrefilters","defaultPrefilter","tweeners","*","createTween","scale","maxIterations","createFxNow","genFx","includeWidth","height","animation","collection","opts","oldfire","dDisplay","anim","dataShow","unqueued","overflow","overflowX","overflowY","propFilter","specialEasing","Animation","properties","stopped","tick","currentTime","startTime","tweens","originalProperties","originalOptions","gotoEnd","rejectWith","timer","complete","tweener","prefilter","speed","opt","speeds","fadeTo","to","animate","optall","doAnimation","finish","stopQueue","timers","cssFn","slideDown","slideUp","slideToggle","fadeIn","fadeOut","fadeToggle","interval","setInterval","clearInterval","slow","fast","delay","time","timeout","clearTimeout","getSetAttribute","hrefNormalized","checkOn","optSelected","enctype","optDisabled","radioValue","rreturn","valHooks","optionSet","scrollHeight","nodeHook","boolHook","ruseDefault","getSetInput","removeAttr","nType","attrHooks","propName","attrNames","propFix","getter","setAttributeNode","createAttribute","coords","contenteditable","rfocusable","rclickable","removeProp","for","class","notxml","tabindex","parseInt","rclass","addClass","classes","clazz","finalValue","proceed","removeClass","toggleClass","stateVal","classNames","hasClass","hover","fnOver","fnOut","bind","unbind","delegate","undelegate","nonce","rquery","rvalidtokens","JSON","parse","requireNonComma","depth","str","comma","open","Function","parseXML","DOMParser","parseFromString","ActiveXObject","async","loadXML","ajaxLocParts","ajaxLocation","rhash","rts","rheaders","rlocalProtocol","rnoContent","rprotocol","rurl","prefilters","transports","allTypes","addToPrefiltersOrTransports","structure","dataTypeExpression","dataType","dataTypes","inspectPrefiltersOrTransports","jqXHR","inspected","seekingTransport","inspect","prefilterOrFactory","dataTypeOrTransport","ajaxExtend","flatOptions","ajaxSettings","ajaxHandleResponses","s","responses","firstDataType","ct","finalDataType","mimeType","getResponseHeader","converters","ajaxConvert","response","isSuccess","conv2","current","conv","responseFields","dataFilter","active","lastModified","etag","url","isLocal","processData","contentType","accepts","json","* text","text html","text json","text xml","ajaxSetup","settings","ajaxPrefilter","ajaxTransport","ajax","cacheURL","responseHeadersString","timeoutTimer","fireGlobals","transport","responseHeaders","callbackContext","globalEventContext","completeDeferred","statusCode","requestHeaders","requestHeadersNames","strAbort","getAllResponseHeaders","setRequestHeader","lname","overrideMimeType","code","status","abort","statusText","finalText","success","method","crossDomain","traditional","hasContent","ifModified","headers","beforeSend","send","nativeStatusText","modified","getJSON","getScript","throws","wrapAll","wrapInner","unwrap","visible","r20","rbracket","rCRLF","rsubmitterTypes","rsubmittable","buildParams","v","encodeURIComponent","serialize","serializeArray","xhr","createStandardXHR","createActiveXHR","xhrId","xhrCallbacks","xhrSupported","cors","username","xhrFields","isAbort","onreadystatechange","responseText","XMLHttpRequest","script","text script","head","scriptCharset","charset","onload","oldCallbacks","rjsonp","jsonp","jsonpCallback","originalSettings","callbackName","overwritten","responseContainer","jsonProp","keepScripts","parsed","_load","params","animated","getWindow","offset","setOffset","curPosition","curLeft","curCSSTop","curTop","curOffset","curCSSLeft","calculatePosition","curElem","using","win","box","getBoundingClientRect","pageYOffset","pageXOffset","offsetParent","parentOffset","scrollTo","Height","Width","defaultExtra","funcName","size","andSelf","define","amd","_jQuery","_$","$","noConflict"],"mappings":";CAcC,SAAUA,EAAQC,GAEK,gBAAXC,SAAiD,gBAAnBA,QAAOC,QAQhDD,OAAOC,QAAUH,EAAOI,SACvBH,EAASD,GAAQ,GACjB,SAAUK,GACT,IAAMA,EAAED,SACP,KAAM,IAAIE,OAAO,2CAElB,OAAOL,GAASI,IAGlBJ,EAASD,IAIS,mBAAXO,QAAyBA,OAASC,KAAM,SAAUD,EAAQE,GAQnE,GAAIC,MAEAC,EAAQD,EAAWC,MAEnBC,EAASF,EAAWE,OAEpBC,EAAOH,EAAWG,KAElBC,EAAUJ,EAAWI,QAErBC,KAEAC,EAAWD,EAAWC,SAEtBC,EAASF,EAAWG,eAEpBC,EAAO,GAAGA,KAEVC,KAKHC,EAAU,SAGVC,EAAS,SAAUC,EAAUC,GAG5B,MAAO,IAAIF,GAAOG,GAAGC,KAAMH,EAAUC,IAItCG,EAAQ,qCAGRC,EAAY,QACZC,EAAa,eAGbC,EAAa,SAAUC,EAAKC,GAC3B,MAAOA,GAAOC,cAGhBX,GAAOG,GAAKH,EAAOY,WAElBC,OAAQd,EAERe,YAAad,EAGbC,SAAU,GAGVc,OAAQ,EAERC,QAAS,WACR,MAAO3B,GAAM4B,KAAM/B,OAKpBgC,IAAK,SAAUC,GACd,MAAc,OAAPA,EAGE,EAANA,EAAUjC,KAAMiC,EAAMjC,KAAK6B,QAAW7B,KAAMiC,GAG9C9B,EAAM4B,KAAM/B,OAKdkC,UAAW,SAAUC,GAGpB,GAAIC,GAAMtB,EAAOuB,MAAOrC,KAAK4B,cAAeO,EAO5C,OAJAC,GAAIE,WAAatC,KACjBoC,EAAIpB,QAAUhB,KAAKgB,QAGZoB,GAMRG,KAAM,SAAUC,EAAUC,GACzB,MAAO3B,GAAOyB,KAAMvC,KAAMwC,EAAUC,IAGrCC,IAAK,SAAUF,GACd,MAAOxC,MAAKkC,UAAWpB,EAAO4B,IAAI1C,KAAM,SAAU2C,EAAMC,GACvD,MAAOJ,GAAST,KAAMY,EAAMC,EAAGD,OAIjCxC,MAAO,WACN,MAAOH,MAAKkC,UAAW/B,EAAM0C,MAAO7C,KAAM8C,aAG3CC,MAAO,WACN,MAAO/C,MAAKgD,GAAI,IAGjBC,KAAM,WACL,MAAOjD,MAAKgD,GAAI,KAGjBA,GAAI,SAAUJ,GACb,GAAIM,GAAMlD,KAAK6B,OACdsB,GAAKP,GAAU,EAAJA,EAAQM,EAAM,EAC1B,OAAOlD,MAAKkC,UAAWiB,GAAK,GAASD,EAAJC,GAAYnD,KAAKmD,SAGnDC,IAAK,WACJ,MAAOpD,MAAKsC,YAActC,KAAK4B,YAAY,OAK5CvB,KAAMA,EACNgD,KAAMnD,EAAWmD,KACjBC,OAAQpD,EAAWoD,QAGpBxC,EAAOyC,OAASzC,EAAOG,GAAGsC,OAAS,WAClC,GAAIC,GAAKC,EAAaC,EAAMC,EAAMC,EAASC,EAC1CC,EAAShB,UAAU,OACnBF,EAAI,EACJf,EAASiB,UAAUjB,OACnBkC,GAAO,CAsBR,KAnBuB,iBAAXD,KACXC,EAAOD,EAGPA,EAAShB,UAAWF,OACpBA,KAIsB,gBAAXkB,IAAwBhD,EAAOkD,WAAWF,KACrDA,MAIIlB,IAAMf,IACViC,EAAS9D,KACT4C,KAGWf,EAAJe,EAAYA,IAEnB,GAAmC,OAA7BgB,EAAUd,UAAWF,IAE1B,IAAMe,IAAQC,GACbJ,EAAMM,EAAQH,GACdD,EAAOE,EAASD,GAGXG,IAAWJ,IAKXK,GAAQL,IAAU5C,EAAOmD,cAAcP,KAAUD,EAAc3C,EAAOoD,QAAQR,MAC7ED,GACJA,GAAc,EACdI,EAAQL,GAAO1C,EAAOoD,QAAQV,GAAOA,MAGrCK,EAAQL,GAAO1C,EAAOmD,cAAcT,GAAOA,KAI5CM,EAAQH,GAAS7C,EAAOyC,OAAQQ,EAAMF,EAAOH,IAGzBS,SAATT,IACXI,EAAQH,GAASD,GAOrB,OAAOI,IAGRhD,EAAOyC,QAENa,QAAS,UAAavD,EAAUwD,KAAKC,UAAWC,QAAS,MAAO,IAGhEC,SAAS,EAETC,MAAO,SAAUC,GAChB,KAAM,IAAI5E,OAAO4E,IAGlBC,KAAM,aAKNX,WAAY,SAAUY,GACrB,MAA4B,aAArB9D,EAAO+D,KAAKD,IAGpBV,QAASY,MAAMZ,SAAW,SAAUU,GACnC,MAA4B,UAArB9D,EAAO+D,KAAKD,IAGpBG,SAAU,SAAUH,GAEnB,MAAc,OAAPA,GAAeA,GAAOA,EAAI7E,QAGlCiF,UAAW,SAAUJ,GAIpB,MAAOA,GAAMK,WAAYL,IAAS,GAGnCM,cAAe,SAAUN,GACxB,GAAIjB,EACJ,KAAMA,IAAQiB,GACb,OAAO,CAER,QAAO,GAGRX,cAAe,SAAUW,GACxB,GAAIO,EAKJ,KAAMP,GAA4B,WAArB9D,EAAO+D,KAAKD,IAAqBA,EAAIQ,UAAYtE,EAAOiE,SAAUH,GAC9E,OAAO,CAGR,KAEC,GAAKA,EAAIhD,cACPnB,EAAOsB,KAAK6C,EAAK,iBACjBnE,EAAOsB,KAAK6C,EAAIhD,YAAYF,UAAW,iBACxC,OAAO,EAEP,MAAQ2D,GAET,OAAO,EAKR,GAAKzE,EAAQ0E,QACZ,IAAMH,IAAOP,GACZ,MAAOnE,GAAOsB,KAAM6C,EAAKO,EAM3B,KAAMA,IAAOP,IAEb,MAAeT,UAARgB,GAAqB1E,EAAOsB,KAAM6C,EAAKO,IAG/CN,KAAM,SAAUD,GACf,MAAY,OAAPA,EACGA,EAAM,GAEQ,gBAARA,IAAmC,kBAARA,GACxCrE,EAAYC,EAASuB,KAAK6C,KAAU,eAC7BA,IAMTW,WAAY,SAAUC,GAChBA,GAAQ1E,EAAOH,KAAM6E,KAIvBzF,EAAO0F,YAAc,SAAUD,GAChCzF,EAAe,KAAEgC,KAAMhC,EAAQyF,KAC3BA,IAMPE,UAAW,SAAUC,GACpB,MAAOA,GAAOpB,QAASnD,EAAW,OAAQmD,QAASlD,EAAYC,IAGhEsE,SAAU,SAAUjD,EAAMgB,GACzB,MAAOhB,GAAKiD,UAAYjD,EAAKiD,SAASC,gBAAkBlC,EAAKkC,eAI9DtD,KAAM,SAAUqC,EAAKpC,EAAUC,GAC9B,GAAIqD,GACHlD,EAAI,EACJf,EAAS+C,EAAI/C,OACbqC,EAAU6B,EAAanB,EAExB,IAAKnC,GACJ,GAAKyB,GACJ,KAAYrC,EAAJe,EAAYA,IAGnB,GAFAkD,EAAQtD,EAASK,MAAO+B,EAAKhC,GAAKH,GAE7BqD,KAAU,EACd,UAIF,KAAMlD,IAAKgC,GAGV,GAFAkB,EAAQtD,EAASK,MAAO+B,EAAKhC,GAAKH,GAE7BqD,KAAU,EACd,UAOH,IAAK5B,GACJ,KAAYrC,EAAJe,EAAYA,IAGnB,GAFAkD,EAAQtD,EAAST,KAAM6C,EAAKhC,GAAKA,EAAGgC,EAAKhC,IAEpCkD,KAAU,EACd,UAIF,KAAMlD,IAAKgC,GAGV,GAFAkB,EAAQtD,EAAST,KAAM6C,EAAKhC,GAAKA,EAAGgC,EAAKhC,IAEpCkD,KAAU,EACd,KAMJ,OAAOlB,IAIRjE,KAAMA,IAASA,EAAKoB,KAAK,cACxB,SAAUiE,GACT,MAAe,OAARA,EACN,GACArF,EAAKoB,KAAMiE,IAIb,SAAUA,GACT,MAAe,OAARA,EACN,IACEA,EAAO,IAAKzB,QAASpD,EAAO,KAIjC8E,UAAW,SAAUC,EAAKC,GACzB,GAAI/D,GAAM+D,KAaV,OAXY,OAAPD,IACCH,EAAaK,OAAOF,IACxBpF,EAAOuB,MAAOD,EACE,gBAAR8D,IACLA,GAAQA,GAGX7F,EAAK0B,KAAMK,EAAK8D,IAIX9D,GAGRiE,QAAS,SAAU1D,EAAMuD,EAAKtD,GAC7B,GAAIM,EAEJ,IAAKgD,EAAM,CACV,GAAK5F,EACJ,MAAOA,GAAQyB,KAAMmE,EAAKvD,EAAMC,EAMjC,KAHAM,EAAMgD,EAAIrE,OACVe,EAAIA,EAAQ,EAAJA,EAAQyB,KAAKiC,IAAK,EAAGpD,EAAMN,GAAMA,EAAI,EAEjCM,EAAJN,EAASA,IAEhB,GAAKA,IAAKsD,IAAOA,EAAKtD,KAAQD,EAC7B,MAAOC,GAKV,MAAO,IAGRP,MAAO,SAAUU,EAAOwD,GACvB,GAAIrD,IAAOqD,EAAO1E,OACjBsB,EAAI,EACJP,EAAIG,EAAMlB,MAEX,OAAYqB,EAAJC,EACPJ,EAAOH,KAAQ2D,EAAQpD,IAKxB,IAAKD,IAAQA,EACZ,MAAsBiB,SAAdoC,EAAOpD,GACdJ,EAAOH,KAAQ2D,EAAQpD,IAMzB,OAFAJ,GAAMlB,OAASe,EAERG,GAGRyD,KAAM,SAAUrE,EAAOK,EAAUiE,GAShC,IARA,GAAIC,GACHC,KACA/D,EAAI,EACJf,EAASM,EAAMN,OACf+E,GAAkBH,EAIP5E,EAAJe,EAAYA,IACnB8D,GAAmBlE,EAAUL,EAAOS,GAAKA,GACpC8D,IAAoBE,GACxBD,EAAQtG,KAAM8B,EAAOS,GAIvB,OAAO+D,IAIRjE,IAAK,SAAUP,EAAOK,EAAUqE,GAC/B,GAAIf,GACHlD,EAAI,EACJf,EAASM,EAAMN,OACfqC,EAAU6B,EAAa5D,GACvBC,IAGD,IAAK8B,EACJ,KAAYrC,EAAJe,EAAYA,IACnBkD,EAAQtD,EAAUL,EAAOS,GAAKA,EAAGiE,GAEnB,MAATf,GACJ1D,EAAI/B,KAAMyF,OAMZ,KAAMlD,IAAKT,GACV2D,EAAQtD,EAAUL,EAAOS,GAAKA,EAAGiE,GAEnB,MAATf,GACJ1D,EAAI/B,KAAMyF,EAMb,OAAO1F,GAAOyC,SAAWT,IAI1B0E,KAAM,EAINC,MAAO,SAAU9F,EAAID,GACpB,GAAIyB,GAAMsE,EAAOC,CAUjB,OARwB,gBAAZhG,KACXgG,EAAM/F,EAAID,GACVA,EAAUC,EACVA,EAAK+F,GAKAlG,EAAOkD,WAAY/C,IAKzBwB,EAAOtC,EAAM4B,KAAMe,UAAW,GAC9BiE,EAAQ,WACP,MAAO9F,GAAG4B,MAAO7B,GAAWhB,KAAMyC,EAAKrC,OAAQD,EAAM4B,KAAMe,cAI5DiE,EAAMD,KAAO7F,EAAG6F,KAAO7F,EAAG6F,MAAQhG,EAAOgG,OAElCC,GAZC5C,QAeT8C,IAAK,WACJ,OAAQ,GAAMC,OAKftG,QAASA,IAIVE,EAAOyB,KAAK,gEAAgE4E,MAAM,KAAM,SAASvE,EAAGe,GACnGpD,EAAY,WAAaoD,EAAO,KAAQA,EAAKkC,eAG9C,SAASE,GAAanB,GACrB,GAAI/C,GAAS+C,EAAI/C,OAChBgD,EAAO/D,EAAO+D,KAAMD,EAErB,OAAc,aAATC,GAAuB/D,EAAOiE,SAAUH,IACrC,EAGc,IAAjBA,EAAIQ,UAAkBvD,GACnB,EAGQ,UAATgD,GAA+B,IAAXhD,GACR,gBAAXA,IAAuBA,EAAS,GAAOA,EAAS,IAAO+C,GAEhE,GAAIwC,GAWJ,SAAWrH,GAEX,GAAI6C,GACHhC,EACAyG,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EAGAC,EACAhI,EACAiI,EACAC,EACAC,EACAC,EACArB,EACAsB,EAGA7D,EAAU,UAAY,GAAK8C,MAC3BgB,EAAenI,EAAOH,SACtBuI,EAAU,EACVC,EAAO,EACPC,EAAaC,KACbC,EAAaD,KACbE,EAAgBF,KAChBG,EAAY,SAAUC,EAAGC,GAIxB,MAHKD,KAAMC,IACVhB,GAAe,GAET,GAIRiB,EAAe,YACfC,EAAe,GAAK,GAGpBpI,KAAcC,eACdwF,KACA4C,EAAM5C,EAAI4C,IACVC,EAAc7C,EAAI7F,KAClBA,EAAO6F,EAAI7F,KACXF,EAAQ+F,EAAI/F,MAEZG,EAAU4F,EAAI5F,SAAW,SAAUqC,GAGlC,IAFA,GAAIC,GAAI,EACPM,EAAMlD,KAAK6B,OACAqB,EAAJN,EAASA,IAChB,GAAK5C,KAAK4C,KAAOD,EAChB,MAAOC,EAGT,OAAO,IAGRoG,EAAW,6HAKXC,EAAa,sBAEbC,EAAoB,mCAKpBC,EAAaD,EAAkB3E,QAAS,IAAK,MAG7C6E,EAAa,MAAQH,EAAa,KAAOC,EAAoB,IAAMD,EAClE,mBAAqBA,EAAa,wCAA0CE,EAAa,QAAUF,EAAa,OAQjHI,EAAU,KAAOH,EAAoB,mEAAqEE,EAAW7E,QAAS,EAAG,GAAM,eAGvIpD,EAAQ,GAAImI,QAAQ,IAAML,EAAa,8BAAgCA,EAAa,KAAM,KAE1FM,EAAS,GAAID,QAAQ,IAAML,EAAa,KAAOA,EAAa,KAC5DO,EAAe,GAAIF,QAAQ,IAAML,EAAa,WAAaA,EAAa,IAAMA,EAAa,KAE3FQ,EAAmB,GAAIH,QAAQ,IAAML,EAAa,iBAAmBA,EAAa,OAAQ,KAE1FS,EAAU,GAAIJ,QAAQD,GACtBM,EAAc,GAAIL,QAAQ,IAAMH,EAAa,KAE7CS,GACCC,GAAM,GAAIP,QAAQ,MAAQJ,EAAoB,KAC9CY,MAAS,GAAIR,QAAQ,QAAUJ,EAAoB,KACnDa,IAAO,GAAIT,QAAQ,KAAOJ,EAAkB3E,QAAS,IAAK,MAAS,KACnEyF,KAAQ,GAAIV,QAAQ,IAAMF,GAC1Ba,OAAU,GAAIX,QAAQ,IAAMD,GAC5Ba,MAAS,GAAIZ,QAAQ,yDAA2DL,EAC/E,+BAAiCA,EAAa,cAAgBA,EAC9D,aAAeA,EAAa,SAAU,KACvCkB,KAAQ,GAAIb,QAAQ,OAASN,EAAW,KAAM,KAG9CoB,aAAgB,GAAId,QAAQ,IAAML,EAAa,mDAC9CA,EAAa,mBAAqBA,EAAa,mBAAoB,MAGrEoB,EAAU,sCACVC,EAAU,SAEVC,EAAU,yBAGVC,EAAa,mCAEbC,EAAW,OACXC,EAAU,QAGVC,GAAY,GAAIrB,QAAQ,qBAAuBL,EAAa,MAAQA,EAAa,OAAQ,MACzF2B,GAAY,SAAUC,EAAGC,EAASC,GACjC,GAAIC,GAAO,KAAOF,EAAU,KAI5B,OAAOE,KAASA,GAAQD,EACvBD,EACO,EAAPE,EAECC,OAAOC,aAAcF,EAAO,OAE5BC,OAAOC,aAAcF,GAAQ,GAAK,MAAe,KAAPA,EAAe,OAI7D,KACC3K,EAAKwC,MACHqD,EAAM/F,EAAM4B,KAAMmG,EAAaiD,YAChCjD,EAAaiD,YAIdjF,EAAKgC,EAAaiD,WAAWtJ,QAASuD,SACrC,MAAQC,IACThF,GAASwC,MAAOqD,EAAIrE,OAGnB,SAAUiC,EAAQsH,GACjBrC,EAAYlG,MAAOiB,EAAQ3D,EAAM4B,KAAKqJ,KAKvC,SAAUtH,EAAQsH,GACjB,GAAIjI,GAAIW,EAAOjC,OACde,EAAI,CAEL,OAASkB,EAAOX,KAAOiI,EAAIxI,MAC3BkB,EAAOjC,OAASsB,EAAI,IAKvB,QAASiE,IAAQrG,EAAUC,EAASmF,EAASkF,GAC5C,GAAIC,GAAO3I,EAAM4I,EAAGnG,EAEnBxC,EAAG4I,EAAQC,EAAKC,EAAKC,EAAYC,CASlC,KAPO5K,EAAUA,EAAQ6K,eAAiB7K,EAAUkH,KAAmBtI,GACtEgI,EAAa5G,GAGdA,EAAUA,GAAWpB,EACrBuG,EAAUA,OAEJpF,GAAgC,gBAAbA,GACxB,MAAOoF,EAGR,IAAuC,KAAjCf,EAAWpE,EAAQoE,WAAgC,IAAbA,EAC3C,QAGD,IAAK0C,IAAmBuD,EAAO,CAG9B,GAAMC,EAAQd,EAAWsB,KAAM/K,GAE9B,GAAMwK,EAAID,EAAM,IACf,GAAkB,IAAblG,EAAiB,CAIrB,GAHAzC,EAAO3B,EAAQ+K,eAAgBR,IAG1B5I,IAAQA,EAAKqJ,WAQjB,MAAO7F,EALP,IAAKxD,EAAKsJ,KAAOV,EAEhB,MADApF,GAAQ9F,KAAMsC,GACPwD,MAOT,IAAKnF,EAAQ6K,gBAAkBlJ,EAAO3B,EAAQ6K,cAAcE,eAAgBR,KAC3EtD,EAAUjH,EAAS2B,IAAUA,EAAKsJ,KAAOV,EAEzC,MADApF,GAAQ9F,KAAMsC,GACPwD,MAKH,CAAA,GAAKmF,EAAM,GAEjB,MADAjL,GAAKwC,MAAOsD,EAASnF,EAAQkL,qBAAsBnL,IAC5CoF,CAGD,KAAMoF,EAAID,EAAM,KAAO1K,EAAQuL,wBAA0BnL,EAAQmL,uBAEvE,MADA9L,GAAKwC,MAAOsD,EAASnF,EAAQmL,uBAAwBZ,IAC9CpF,EAKT,GAAKvF,EAAQwL,OAASrE,IAAcA,EAAUsE,KAAMtL,IAAc,CASjE,GARA2K,EAAMD,EAAMrH,EACZuH,EAAa3K,EACb4K,EAA2B,IAAbxG,GAAkBrE,EAMd,IAAbqE,GAAqD,WAAnCpE,EAAQ4E,SAASC,cAA6B,CACpE2F,EAASc,GAAUvL,IAEb0K,EAAMzK,EAAQuL,aAAa,OAChCb,EAAMD,EAAIlH,QAASmG,EAAS,QAE5B1J,EAAQwL,aAAc,KAAMd,GAE7BA,EAAM,QAAUA,EAAM,MAEtB9I,EAAI4I,EAAO3J,MACX,OAAQe,IACP4I,EAAO5I,GAAK8I,EAAMe,GAAYjB,EAAO5I,GAEtC+I,GAAalB,EAAS4B,KAAMtL,IAAc2L,GAAa1L,EAAQgL,aAAgBhL,EAC/E4K,EAAcJ,EAAOmB,KAAK,KAG3B,GAAKf,EACJ,IAIC,MAHAvL,GAAKwC,MAAOsD,EACXwF,EAAWiB,iBAAkBhB,IAEvBzF,EACN,MAAM0G,IACN,QACKpB,GACLzK,EAAQ8L,gBAAgB,QAQ7B,MAAOC,IAAQhM,EAASwD,QAASpD,EAAO,MAAQH,EAASmF,EAASkF,GASnE,QAAS/C,MACR,GAAI0E,KAEJ,SAASC,GAAO9H,EAAKW,GAMpB,MAJKkH,GAAK3M,KAAM8E,EAAM,KAAQkC,EAAK6F,mBAE3BD,GAAOD,EAAKG,SAEZF,EAAO9H,EAAM,KAAQW,EAE9B,MAAOmH,GAOR,QAASG,IAAcnM,GAEtB,MADAA,GAAImD,IAAY,EACTnD,EAOR,QAASoM,IAAQpM,GAChB,GAAIqM,GAAM1N,EAAS2N,cAAc,MAEjC,KACC,QAAStM,EAAIqM,GACZ,MAAOjI,GACR,OAAO,EACN,QAEIiI,EAAItB,YACRsB,EAAItB,WAAWwB,YAAaF,GAG7BA,EAAM,MASR,QAASG,IAAWC,EAAOC,GAC1B,GAAIzH,GAAMwH,EAAMvG,MAAM,KACrBvE,EAAI8K,EAAM7L,MAEX,OAAQe,IACPyE,EAAKuG,WAAY1H,EAAItD,IAAO+K,EAU9B,QAASE,IAAcnF,EAAGC,GACzB,GAAImF,GAAMnF,GAAKD,EACdqF,EAAOD,GAAsB,IAAfpF,EAAEtD,UAAiC,IAAfuD,EAAEvD,YAChCuD,EAAEqF,aAAenF,KACjBH,EAAEsF,aAAenF,EAGtB,IAAKkF,EACJ,MAAOA,EAIR,IAAKD,EACJ,MAASA,EAAMA,EAAIG,YAClB,GAAKH,IAAQnF,EACZ,MAAO,EAKV,OAAOD,GAAI,EAAI,GAOhB,QAASwF,IAAmBrJ,GAC3B,MAAO,UAAUlC,GAChB,GAAIgB,GAAOhB,EAAKiD,SAASC,aACzB,OAAgB,UAATlC,GAAoBhB,EAAKkC,OAASA,GAQ3C,QAASsJ,IAAoBtJ,GAC5B,MAAO,UAAUlC,GAChB,GAAIgB,GAAOhB,EAAKiD,SAASC,aACzB,QAAiB,UAATlC,GAA6B,WAATA,IAAsBhB,EAAKkC,OAASA,GAQlE,QAASuJ,IAAwBnN,GAChC,MAAOmM,IAAa,SAAUiB,GAE7B,MADAA,IAAYA,EACLjB,GAAa,SAAU/B,EAAM1E,GACnC,GAAIxD,GACHmL,EAAerN,KAAQoK,EAAKxJ,OAAQwM,GACpCzL,EAAI0L,EAAazM,MAGlB,OAAQe,IACFyI,EAAOlI,EAAImL,EAAa1L,MAC5ByI,EAAKlI,KAAOwD,EAAQxD,GAAKkI,EAAKlI,SAYnC,QAASuJ,IAAa1L,GACrB,MAAOA,UAAkBA,GAAQkL,uBAAyBtD,GAAgB5H,EAI3EJ,EAAUwG,GAAOxG,WAOjB2G,EAAQH,GAAOG,MAAQ,SAAU5E,GAGhC,GAAI4L,GAAkB5L,IAASA,EAAKkJ,eAAiBlJ,GAAM4L,eAC3D,OAAOA,GAA+C,SAA7BA,EAAgB3I,UAAsB,GAQhEgC,EAAcR,GAAOQ,YAAc,SAAU4G,GAC5C,GAAIC,GACHC,EAAMF,EAAOA,EAAK3C,eAAiB2C,EAAOtG,EAC1CyG,EAASD,EAAIE,WAGd,OAAKF,KAAQ9O,GAA6B,IAAjB8O,EAAItJ,UAAmBsJ,EAAIH,iBAKpD3O,EAAW8O,EACX7G,EAAU6G,EAAIH,gBAGdzG,GAAkBP,EAAOmH,GAMpBC,GAAUA,IAAWA,EAAOE,MAE3BF,EAAOG,iBACXH,EAAOG,iBAAkB,SAAU,WAClClH,MACE,GACQ+G,EAAOI,aAClBJ,EAAOI,YAAa,WAAY,WAC/BnH,OAUHhH,EAAQwI,WAAaiE,GAAO,SAAUC,GAErC,MADAA,GAAI0B,UAAY,KACR1B,EAAIf,aAAa,eAO1B3L,EAAQsL,qBAAuBmB,GAAO,SAAUC,GAE/C,MADAA,GAAI2B,YAAaP,EAAIQ,cAAc,MAC3B5B,EAAIpB,qBAAqB,KAAKrK,SAIvCjB,EAAQuL,uBAAyB5B,EAAQ8B,KAAMqC,EAAIvC,yBAA4BkB,GAAO,SAAUC,GAQ/F,MAPAA,GAAI6B,UAAY,+CAIhB7B,EAAI8B,WAAWJ,UAAY,IAGuB,IAA3C1B,EAAInB,uBAAuB,KAAKtK,SAOxCjB,EAAQyO,QAAUhC,GAAO,SAAUC,GAElC,MADAzF,GAAQoH,YAAa3B,GAAMrB,GAAK7H,GACxBsK,EAAIY,oBAAsBZ,EAAIY,kBAAmBlL,GAAUvC,SAI/DjB,EAAQyO,SACZhI,EAAKkI,KAAS,GAAI,SAAUtD,EAAIjL,GAC/B,SAAYA,GAAQ+K,iBAAmBnD,GAAgBd,EAAiB,CACvE,GAAIyD,GAAIvK,EAAQ+K,eAAgBE,EAGhC,OAAOV,IAAKA,EAAES,YAAcT,QAG9BlE,EAAKmI,OAAW,GAAI,SAAUvD,GAC7B,GAAIwD,GAASxD,EAAG1H,QAASoG,GAAWC,GACpC,OAAO,UAAUjI,GAChB,MAAOA,GAAK4J,aAAa,QAAUkD,YAM9BpI,GAAKkI,KAAS,GAErBlI,EAAKmI,OAAW,GAAK,SAAUvD,GAC9B,GAAIwD,GAASxD,EAAG1H,QAASoG,GAAWC,GACpC,OAAO,UAAUjI,GAChB,GAAI6L,SAAc7L,GAAK+M,mBAAqB9G,GAAgBjG,EAAK+M,iBAAiB,KAClF,OAAOlB,IAAQA,EAAK1I,QAAU2J,KAMjCpI,EAAKkI,KAAU,IAAI3O,EAAQsL,qBAC1B,SAAUyD,EAAK3O,GACd,aAAYA,GAAQkL,uBAAyBtD,EACrC5H,EAAQkL,qBAAsByD,GADtC,QAID,SAAUA,EAAK3O,GACd,GAAI2B,GACHqE,KACApE,EAAI,EACJuD,EAAUnF,EAAQkL,qBAAsByD,EAGzC,IAAa,MAARA,EAAc,CAClB,MAAShN,EAAOwD,EAAQvD,KACA,IAAlBD,EAAKyC,UACT4B,EAAI3G,KAAMsC,EAIZ,OAAOqE,GAER,MAAOb,IAITkB,EAAKkI,KAAY,MAAI3O,EAAQuL,wBAA0B,SAAU6C,EAAWhO,GAC3E,aAAYA,GAAQmL,yBAA2BvD,GAAgBd,EACvD9G,EAAQmL,uBAAwB6C,GADxC,QAWDhH,KAOAD,MAEMnH,EAAQwL,IAAM7B,EAAQ8B,KAAMqC,EAAI9B,qBAGrCS,GAAO,SAAUC,GAMhBA,EAAI6B,UAAY,sDAIX7B,EAAIV,iBAAiB,WAAW/K,QACpCkG,EAAU1H,KAAM,SAAW4I,EAAa,gBAKnCqE,EAAIV,iBAAiB,cAAc/K,QACxCkG,EAAU1H,KAAM,MAAQ4I,EAAa,aAAeD,EAAW,KAM1DsE,EAAIV,iBAAiB,YAAY/K,QACtCkG,EAAU1H,KAAK,cAIjBgN,GAAO,SAAUC,GAGhB,GAAIsC,GAAQlB,EAAInB,cAAc,QAC9BqC,GAAMpD,aAAc,OAAQ,UAC5Bc,EAAI2B,YAAaW,GAAQpD,aAAc,OAAQ,KAI1Cc,EAAIV,iBAAiB,YAAY/K,QACrCkG,EAAU1H,KAAM,OAAS4I,EAAa,eAKjCqE,EAAIV,iBAAiB,YAAY/K,QACtCkG,EAAU1H,KAAM,WAAY,aAI7BiN,EAAIV,iBAAiB,QACrB7E,EAAU1H,KAAK,YAIXO,EAAQiP,gBAAkBtF,EAAQ8B,KAAO1F,EAAUkB,EAAQiI,uBAChEjI,EAAQkI,oBACRlI,EAAQmI,kBACRnI,EAAQoI,qBAER5C,GAAO,SAAUC,GAGhB1M,EAAQsP,kBAAoBvJ,EAAQ5E,KAAMuL,EAAK,OAI/C3G,EAAQ5E,KAAMuL,EAAK,aACnBtF,EAAc3H,KAAM,KAAMgJ,KAI5BtB,EAAYA,EAAUlG,QAAU,GAAIyH,QAAQvB,EAAU4E,KAAK,MAC3D3E,EAAgBA,EAAcnG,QAAU,GAAIyH,QAAQtB,EAAc2E,KAAK,MAIvE8B,EAAalE,EAAQ8B,KAAMxE,EAAQsI,yBAKnClI,EAAWwG,GAAclE,EAAQ8B,KAAMxE,EAAQI,UAC9C,SAAUS,EAAGC,GACZ,GAAIyH,GAAuB,IAAf1H,EAAEtD,SAAiBsD,EAAE6F,gBAAkB7F,EAClD2H,EAAM1H,GAAKA,EAAEqD,UACd,OAAOtD,KAAM2H,MAAWA,GAAwB,IAAjBA,EAAIjL,YAClCgL,EAAMnI,SACLmI,EAAMnI,SAAUoI,GAChB3H,EAAEyH,yBAA8D,GAAnCzH,EAAEyH,wBAAyBE,MAG3D,SAAU3H,EAAGC,GACZ,GAAKA,EACJ,MAASA,EAAIA,EAAEqD,WACd,GAAKrD,IAAMD,EACV,OAAO,CAIV,QAAO,GAOTD,EAAYgG,EACZ,SAAU/F,EAAGC,GAGZ,GAAKD,IAAMC,EAEV,MADAhB,IAAe,EACR,CAIR,IAAI2I,IAAW5H,EAAEyH,yBAA2BxH,EAAEwH,uBAC9C,OAAKG,GACGA,GAIRA,GAAY5H,EAAEmD,eAAiBnD,MAAUC,EAAEkD,eAAiBlD,GAC3DD,EAAEyH,wBAAyBxH,GAG3B,EAGc,EAAV2H,IACF1P,EAAQ2P,cAAgB5H,EAAEwH,wBAAyBzH,KAAQ4H,EAGxD5H,IAAMgG,GAAOhG,EAAEmD,gBAAkB3D,GAAgBD,EAASC,EAAcQ,GACrE,GAEHC,IAAM+F,GAAO/F,EAAEkD,gBAAkB3D,GAAgBD,EAASC,EAAcS,GACrE,EAIDjB,EACJpH,EAAQyB,KAAM2F,EAAWgB,GAAMpI,EAAQyB,KAAM2F,EAAWiB,GAC1D,EAGe,EAAV2H,EAAc,GAAK,IAE3B,SAAU5H,EAAGC,GAEZ,GAAKD,IAAMC,EAEV,MADAhB,IAAe,EACR,CAGR,IAAImG,GACHlL,EAAI,EACJ4N,EAAM9H,EAAEsD,WACRqE,EAAM1H,EAAEqD,WACRyE,GAAO/H,GACPgI,GAAO/H,EAGR,KAAM6H,IAAQH,EACb,MAAO3H,KAAMgG,EAAM,GAClB/F,IAAM+F,EAAM,EACZ8B,EAAM,GACNH,EAAM,EACN3I,EACEpH,EAAQyB,KAAM2F,EAAWgB,GAAMpI,EAAQyB,KAAM2F,EAAWiB,GAC1D,CAGK,IAAK6H,IAAQH,EACnB,MAAOxC,IAAcnF,EAAGC,EAIzBmF,GAAMpF,CACN,OAASoF,EAAMA,EAAI9B,WAClByE,EAAGE,QAAS7C,EAEbA,GAAMnF,CACN,OAASmF,EAAMA,EAAI9B,WAClB0E,EAAGC,QAAS7C,EAIb,OAAQ2C,EAAG7N,KAAO8N,EAAG9N,GACpBA,GAGD,OAAOA,GAENiL,GAAc4C,EAAG7N,GAAI8N,EAAG9N,IAGxB6N,EAAG7N,KAAOsF,EAAe,GACzBwI,EAAG9N,KAAOsF,EAAe,EACzB,GAGKwG,GA7VC9O,GAgWTwH,GAAOT,QAAU,SAAUiK,EAAMC,GAChC,MAAOzJ,IAAQwJ,EAAM,KAAM,KAAMC,IAGlCzJ,GAAOyI,gBAAkB,SAAUlN,EAAMiO,GASxC,IAPOjO,EAAKkJ,eAAiBlJ,KAAW/C,GACvCgI,EAAajF,GAIdiO,EAAOA,EAAKrM,QAASkF,EAAkB,aAElC7I,EAAQiP,kBAAmB/H,GAC5BE,GAAkBA,EAAcqE,KAAMuE,IACtC7I,GAAkBA,EAAUsE,KAAMuE,IAErC,IACC,GAAIxO,GAAMuE,EAAQ5E,KAAMY,EAAMiO,EAG9B,IAAKxO,GAAOxB,EAAQsP,mBAGlBvN,EAAK/C,UAAuC,KAA3B+C,EAAK/C,SAASwF,SAChC,MAAOhD,GAEP,MAAMiD,IAGT,MAAO+B,IAAQwJ,EAAMhR,EAAU,MAAO+C,IAAQd,OAAS,GAGxDuF,GAAOa,SAAW,SAAUjH,EAAS2B,GAKpC,OAHO3B,EAAQ6K,eAAiB7K,KAAcpB,GAC7CgI,EAAa5G,GAEPiH,EAAUjH,EAAS2B,IAG3ByE,GAAO0J,KAAO,SAAUnO,EAAMgB,IAEtBhB,EAAKkJ,eAAiBlJ,KAAW/C,GACvCgI,EAAajF,EAGd,IAAI1B,GAAKoG,EAAKuG,WAAYjK,EAAKkC,eAE9BkL,EAAM9P,GAAMR,EAAOsB,KAAMsF,EAAKuG,WAAYjK,EAAKkC,eAC9C5E,EAAI0B,EAAMgB,GAAOmE,GACjB3D,MAEF,OAAeA,UAAR4M,EACNA,EACAnQ,EAAQwI,aAAetB,EACtBnF,EAAK4J,aAAc5I,IAClBoN,EAAMpO,EAAK+M,iBAAiB/L,KAAUoN,EAAIC,UAC1CD,EAAIjL,MACJ,MAGJsB,GAAO3C,MAAQ,SAAUC,GACxB,KAAM,IAAI5E,OAAO,0CAA4C4E,IAO9D0C,GAAO6J,WAAa,SAAU9K,GAC7B,GAAIxD,GACHuO,KACA/N,EAAI,EACJP,EAAI,CAOL,IAJA+E,GAAgB/G,EAAQuQ,iBACxBzJ,GAAa9G,EAAQwQ,YAAcjL,EAAQhG,MAAO,GAClDgG,EAAQ9C,KAAMoF,GAETd,EAAe,CACnB,MAAShF,EAAOwD,EAAQvD,KAClBD,IAASwD,EAASvD,KACtBO,EAAI+N,EAAW7Q,KAAMuC,GAGvB,OAAQO,IACPgD,EAAQ7C,OAAQ4N,EAAY/N,GAAK,GAQnC,MAFAuE,GAAY,KAELvB,GAORmB,EAAUF,GAAOE,QAAU,SAAU3E,GACpC,GAAI6L,GACHpM,EAAM,GACNQ,EAAI,EACJwC,EAAWzC,EAAKyC,QAEjB,IAAMA,GAMC,GAAkB,IAAbA,GAA+B,IAAbA,GAA+B,KAAbA,EAAkB,CAGjE,GAAiC,gBAArBzC,GAAK0O,YAChB,MAAO1O,GAAK0O,WAGZ,KAAM1O,EAAOA,EAAKyM,WAAYzM,EAAMA,EAAOA,EAAKsL,YAC/C7L,GAAOkF,EAAS3E,OAGZ,IAAkB,IAAbyC,GAA+B,IAAbA,EAC7B,MAAOzC,GAAK2O,cAhBZ,OAAS9C,EAAO7L,EAAKC,KAEpBR,GAAOkF,EAASkH,EAkBlB,OAAOpM,IAGRiF,EAAOD,GAAOmK,WAGbrE,YAAa,GAEbsE,aAAcpE,GAEd9B,MAAO1B,EAEPgE,cAEA2B,QAEAkC,UACCC,KAAOC,IAAK,aAAc5O,OAAO,GACjC6O,KAAOD,IAAK,cACZE,KAAOF,IAAK,kBAAmB5O,OAAO,GACtC+O,KAAOH,IAAK,oBAGbI,WACC/H,KAAQ,SAAUsB,GAUjB,MATAA,GAAM,GAAKA,EAAM,GAAG/G,QAASoG,GAAWC,IAGxCU,EAAM,IAAOA,EAAM,IAAMA,EAAM,IAAM,IAAK/G,QAASoG,GAAWC,IAE5C,OAAbU,EAAM,KACVA,EAAM,GAAK,IAAMA,EAAM,GAAK,KAGtBA,EAAMnL,MAAO,EAAG,IAGxB+J,MAAS,SAAUoB,GA6BlB,MAlBAA,GAAM,GAAKA,EAAM,GAAGzF,cAEY,QAA3ByF,EAAM,GAAGnL,MAAO,EAAG,IAEjBmL,EAAM,IACXlE,GAAO3C,MAAO6G,EAAM,IAKrBA,EAAM,KAAQA,EAAM,GAAKA,EAAM,IAAMA,EAAM,IAAM,GAAK,GAAmB,SAAbA,EAAM,IAA8B,QAAbA,EAAM,KACzFA,EAAM,KAAUA,EAAM,GAAKA,EAAM,IAAqB,QAAbA,EAAM,KAGpCA,EAAM,IACjBlE,GAAO3C,MAAO6G,EAAM,IAGdA,GAGRrB,OAAU,SAAUqB,GACnB,GAAI0G,GACHC,GAAY3G,EAAM,IAAMA,EAAM,EAE/B,OAAK1B,GAAiB,MAAEyC,KAAMf,EAAM,IAC5B,MAIHA,EAAM,IAAmBnH,SAAbmH,EAAM,GACtBA,EAAM,GAAKA,EAAM,GAGN2G,GAAYvI,EAAQ2C,KAAM4F,KAEpCD,EAAS1F,GAAU2F,GAAU,MAE7BD,EAASC,EAAS3R,QAAS,IAAK2R,EAASpQ,OAASmQ,GAAWC,EAASpQ,UAGvEyJ,EAAM,GAAKA,EAAM,GAAGnL,MAAO,EAAG6R,GAC9B1G,EAAM,GAAK2G,EAAS9R,MAAO,EAAG6R,IAIxB1G,EAAMnL,MAAO,EAAG,MAIzBqP,QAECzF,IAAO,SAAUmI,GAChB,GAAItM,GAAWsM,EAAiB3N,QAASoG,GAAWC,IAAY/E,aAChE,OAA4B,MAArBqM,EACN,WAAa,OAAO,GACpB,SAAUvP,GACT,MAAOA,GAAKiD,UAAYjD,EAAKiD,SAASC,gBAAkBD,IAI3DkE,MAAS,SAAUkF,GAClB,GAAImD,GAAU9J,EAAY2G,EAAY,IAEtC,OAAOmD,KACLA,EAAU,GAAI7I,QAAQ,MAAQL,EAAa,IAAM+F,EAAY,IAAM/F,EAAa,SACjFZ,EAAY2G,EAAW,SAAUrM,GAChC,MAAOwP,GAAQ9F,KAAgC,gBAAnB1J,GAAKqM,WAA0BrM,EAAKqM,iBAAoBrM,GAAK4J,eAAiB3D,GAAgBjG,EAAK4J,aAAa,UAAY,OAI3JvC,KAAQ,SAAUrG,EAAMyO,EAAUC,GACjC,MAAO,UAAU1P,GAChB,GAAI2P,GAASlL,GAAO0J,KAAMnO,EAAMgB,EAEhC,OAAe,OAAV2O,EACgB,OAAbF,EAEFA,GAINE,GAAU,GAEU,MAAbF,EAAmBE,IAAWD,EACvB,OAAbD,EAAoBE,IAAWD,EAClB,OAAbD,EAAoBC,GAAqC,IAA5BC,EAAOhS,QAAS+R,GAChC,OAAbD,EAAoBC,GAASC,EAAOhS,QAAS+R,GAAU,GAC1C,OAAbD,EAAoBC,GAASC,EAAOnS,OAAQkS,EAAMxQ,UAAawQ,EAClD,OAAbD,GAAsB,IAAME,EAAS,KAAMhS,QAAS+R,GAAU,GACjD,OAAbD,EAAoBE,IAAWD,GAASC,EAAOnS,MAAO,EAAGkS,EAAMxQ,OAAS,KAAQwQ,EAAQ,KACxF,IAZO,IAgBVnI,MAAS,SAAUrF,EAAM0N,EAAMlE,EAAUtL,EAAOE,GAC/C,GAAIuP,GAAgC,QAAvB3N,EAAK1E,MAAO,EAAG,GAC3BsS,EAA+B,SAArB5N,EAAK1E,MAAO,IACtBuS,EAAkB,YAATH,CAEV,OAAiB,KAAVxP,GAAwB,IAATE,EAGrB,SAAUN,GACT,QAASA,EAAKqJ,YAGf,SAAUrJ,EAAM3B,EAAS2R,GACxB,GAAI1F,GAAO2F,EAAYpE,EAAMT,EAAM8E,EAAWC,EAC7CnB,EAAMa,IAAWC,EAAU,cAAgB,kBAC3C9D,EAAShM,EAAKqJ,WACdrI,EAAO+O,GAAU/P,EAAKiD,SAASC,cAC/BkN,GAAYJ,IAAQD,CAErB,IAAK/D,EAAS,CAGb,GAAK6D,EAAS,CACb,MAAQb,EAAM,CACbnD,EAAO7L,CACP,OAAS6L,EAAOA,EAAMmD,GACrB,GAAKe,EAASlE,EAAK5I,SAASC,gBAAkBlC,EAAyB,IAAlB6K,EAAKpJ,SACzD,OAAO,CAIT0N,GAAQnB,EAAe,SAAT9M,IAAoBiO,GAAS,cAE5C,OAAO,EAMR,GAHAA,GAAUL,EAAU9D,EAAOS,WAAaT,EAAOqE,WAG1CP,GAAWM,EAAW,CAE1BH,EAAajE,EAAQvK,KAAcuK,EAAQvK,OAC3C6I,EAAQ2F,EAAY/N,OACpBgO,EAAY5F,EAAM,KAAO9E,GAAW8E,EAAM,GAC1Cc,EAAOd,EAAM,KAAO9E,GAAW8E,EAAM,GACrCuB,EAAOqE,GAAalE,EAAOxD,WAAY0H,EAEvC,OAASrE,IAASqE,GAAarE,GAAQA,EAAMmD,KAG3C5D,EAAO8E,EAAY,IAAMC,EAAMhK,MAGhC,GAAuB,IAAlB0F,EAAKpJ,YAAoB2I,GAAQS,IAAS7L,EAAO,CACrDiQ,EAAY/N,IAAWsD,EAAS0K,EAAW9E,EAC3C,YAKI,IAAKgF,IAAa9F,GAAStK,EAAMyB,KAAczB,EAAMyB,QAAkBS,KAAWoI,EAAM,KAAO9E,EACrG4F,EAAOd,EAAM,OAKb,OAASuB,IAASqE,GAAarE,GAAQA,EAAMmD,KAC3C5D,EAAO8E,EAAY,IAAMC,EAAMhK,MAEhC,IAAO4J,EAASlE,EAAK5I,SAASC,gBAAkBlC,EAAyB,IAAlB6K,EAAKpJ,aAAsB2I,IAE5EgF,KACHvE,EAAMpK,KAAcoK,EAAMpK,QAAkBS,IAAWsD,EAAS4F,IAG7DS,IAAS7L,GACb,KAQJ,OADAoL,IAAQ9K,EACD8K,IAAShL,GAAWgL,EAAOhL,IAAU,GAAKgL,EAAOhL,GAAS,KAKrEkH,OAAU,SAAUgJ,EAAQ5E,GAK3B,GAAI5L,GACHxB,EAAKoG,EAAKgC,QAAS4J,IAAY5L,EAAK6L,WAAYD,EAAOpN,gBACtDuB,GAAO3C,MAAO,uBAAyBwO,EAKzC,OAAKhS,GAAImD,GACDnD,EAAIoN,GAIPpN,EAAGY,OAAS,GAChBY,GAASwQ,EAAQA,EAAQ,GAAI5E,GACtBhH,EAAK6L,WAAWxS,eAAgBuS,EAAOpN,eAC7CuH,GAAa,SAAU/B,EAAM1E,GAC5B,GAAIwM,GACHC,EAAUnS,EAAIoK,EAAMgD,GACpBzL,EAAIwQ,EAAQvR,MACb,OAAQe,IACPuQ,EAAM7S,EAAQyB,KAAMsJ,EAAM+H,EAAQxQ,IAClCyI,EAAM8H,KAAWxM,EAASwM,GAAQC,EAAQxQ,MAG5C,SAAUD,GACT,MAAO1B,GAAI0B,EAAM,EAAGF,KAIhBxB,IAIToI,SAECgK,IAAOjG,GAAa,SAAUrM,GAI7B,GAAI6O,MACHzJ,KACAmN,EAAU9L,EAASzG,EAASwD,QAASpD,EAAO,MAE7C,OAAOmS,GAASlP,GACfgJ,GAAa,SAAU/B,EAAM1E,EAAS3F,EAAS2R,GAC9C,GAAIhQ,GACH4Q,EAAYD,EAASjI,EAAM,KAAMsH,MACjC/P,EAAIyI,EAAKxJ,MAGV,OAAQe,KACDD,EAAO4Q,EAAU3Q,MACtByI,EAAKzI,KAAO+D,EAAQ/D,GAAKD,MAI5B,SAAUA,EAAM3B,EAAS2R,GAGxB,MAFA/C,GAAM,GAAKjN,EACX2Q,EAAS1D,EAAO,KAAM+C,EAAKxM,IACnBA,EAAQ2C,SAInB0K,IAAOpG,GAAa,SAAUrM,GAC7B,MAAO,UAAU4B,GAChB,MAAOyE,IAAQrG,EAAU4B,GAAOd,OAAS,KAI3CoG,SAAYmF,GAAa,SAAUpH,GAClC,MAAO,UAAUrD,GAChB,OAASA,EAAK0O,aAAe1O,EAAK8Q,WAAanM,EAAS3E,IAASrC,QAAS0F,GAAS,MAWrF0N,KAAQtG,GAAc,SAAUsG,GAM/B,MAJM/J,GAAY0C,KAAKqH,GAAQ,KAC9BtM,GAAO3C,MAAO,qBAAuBiP,GAEtCA,EAAOA,EAAKnP,QAASoG,GAAWC,IAAY/E,cACrC,SAAUlD,GAChB,GAAIgR,EACJ,GACC,IAAMA,EAAW7L,EAChBnF,EAAK+Q,KACL/Q,EAAK4J,aAAa,aAAe5J,EAAK4J,aAAa,QAGnD,MADAoH,GAAWA,EAAS9N,cACb8N,IAAaD,GAA2C,IAAnCC,EAASrT,QAASoT,EAAO,YAE5C/Q,EAAOA,EAAKqJ,aAAiC,IAAlBrJ,EAAKyC,SAC3C,QAAO,KAKTtB,OAAU,SAAUnB,GACnB,GAAIiR,GAAO7T,EAAO8T,UAAY9T,EAAO8T,SAASD,IAC9C,OAAOA,IAAQA,EAAKzT,MAAO,KAAQwC,EAAKsJ,IAGzC6H,KAAQ,SAAUnR,GACjB,MAAOA,KAASkF,GAGjBkM,MAAS,SAAUpR,GAClB,MAAOA,KAAS/C,EAASoU,iBAAmBpU,EAASqU,UAAYrU,EAASqU,gBAAkBtR,EAAKkC,MAAQlC,EAAKuR,OAASvR,EAAKwR,WAI7HC,QAAW,SAAUzR,GACpB,MAAOA,GAAK0R,YAAa,GAG1BA,SAAY,SAAU1R,GACrB,MAAOA,GAAK0R,YAAa,GAG1BC,QAAW,SAAU3R,GAGpB,GAAIiD,GAAWjD,EAAKiD,SAASC,aAC7B,OAAqB,UAAbD,KAA0BjD,EAAK2R,SAA0B,WAAb1O,KAA2BjD,EAAK4R,UAGrFA,SAAY,SAAU5R,GAOrB,MAJKA,GAAKqJ,YACTrJ,EAAKqJ,WAAWwI,cAGV7R,EAAK4R,YAAa,GAI1BE,MAAS,SAAU9R,GAKlB,IAAMA,EAAOA,EAAKyM,WAAYzM,EAAMA,EAAOA,EAAKsL,YAC/C,GAAKtL,EAAKyC,SAAW,EACpB,OAAO,CAGT,QAAO,GAGRuJ,OAAU,SAAUhM,GACnB,OAAQ0E,EAAKgC,QAAe,MAAG1G,IAIhC+R,OAAU,SAAU/R,GACnB,MAAO2H,GAAQ+B,KAAM1J,EAAKiD,WAG3BgK,MAAS,SAAUjN,GAClB,MAAO0H,GAAQgC,KAAM1J,EAAKiD,WAG3B+O,OAAU,SAAUhS,GACnB,GAAIgB,GAAOhB,EAAKiD,SAASC,aACzB,OAAgB,UAATlC,GAAkC,WAAdhB,EAAKkC,MAA8B,WAATlB,GAGtDqC,KAAQ,SAAUrD,GACjB,GAAImO,EACJ,OAAuC,UAAhCnO,EAAKiD,SAASC,eACN,SAAdlD,EAAKkC,OAImC,OAArCiM,EAAOnO,EAAK4J,aAAa,UAA2C,SAAvBuE,EAAKjL,gBAIvD9C,MAASqL,GAAuB,WAC/B,OAAS,KAGVnL,KAAQmL,GAAuB,SAAUE,EAAczM,GACtD,OAASA,EAAS,KAGnBmB,GAAMoL,GAAuB,SAAUE,EAAczM,EAAQwM,GAC5D,OAAoB,EAAXA,EAAeA,EAAWxM,EAASwM,KAG7CuG,KAAQxG,GAAuB,SAAUE,EAAczM,GAEtD,IADA,GAAIe,GAAI,EACIf,EAAJe,EAAYA,GAAK,EACxB0L,EAAajO,KAAMuC,EAEpB,OAAO0L,KAGRuG,IAAOzG,GAAuB,SAAUE,EAAczM,GAErD,IADA,GAAIe,GAAI,EACIf,EAAJe,EAAYA,GAAK,EACxB0L,EAAajO,KAAMuC,EAEpB,OAAO0L,KAGRwG,GAAM1G,GAAuB,SAAUE,EAAczM,EAAQwM,GAE5D,IADA,GAAIzL,GAAe,EAAXyL,EAAeA,EAAWxM,EAASwM,IACjCzL,GAAK,GACd0L,EAAajO,KAAMuC,EAEpB,OAAO0L,KAGRyG,GAAM3G,GAAuB,SAAUE,EAAczM,EAAQwM,GAE5D,IADA,GAAIzL,GAAe,EAAXyL,EAAeA,EAAWxM,EAASwM,IACjCzL,EAAIf,GACbyM,EAAajO,KAAMuC,EAEpB,OAAO0L,OAKVjH,EAAKgC,QAAa,IAAIhC,EAAKgC,QAAY,EAGvC,KAAMzG,KAAOoS,OAAO,EAAMC,UAAU,EAAMC,MAAM,EAAMC,UAAU,EAAMC,OAAO,GAC5E/N,EAAKgC,QAASzG,GAAMsL,GAAmBtL,EAExC,KAAMA,KAAOyS,QAAQ,EAAMC,OAAO,GACjCjO,EAAKgC,QAASzG,GAAMuL,GAAoBvL,EAIzC,SAASsQ,OACTA,GAAWxR,UAAY2F,EAAKkO,QAAUlO,EAAKgC,QAC3ChC,EAAK6L,WAAa,GAAIA,GAEtB,SAAS5G,IAAUvL,EAAUyU,GAC5B,GAAIpC,GAAS9H,EAAOmK,EAAQ5Q,EAC3B6Q,EAAOlK,EAAQmK,EACfC,EAASrN,EAAYxH,EAAW,IAEjC,IAAK6U,EACJ,MAAOJ,GAAY,EAAII,EAAOzV,MAAO,EAGtCuV,GAAQ3U,EACRyK,KACAmK,EAAatO,EAAK0K,SAElB,OAAQ2D,EAAQ,GAGTtC,IAAY9H,EAAQ/B,EAAOuC,KAAM4J,OACjCpK,IAEJoK,EAAQA,EAAMvV,MAAOmL,EAAM,GAAGzJ,SAAY6T,GAE3ClK,EAAOnL,KAAOoV,OAGfrC,GAAU,GAGJ9H,EAAQ9B,EAAasC,KAAM4J,MAChCtC,EAAU9H,EAAM6B,QAChBsI,EAAOpV,MACNyF,MAAOsN,EAEPvO,KAAMyG,EAAM,GAAG/G,QAASpD,EAAO,OAEhCuU,EAAQA,EAAMvV,MAAOiT,EAAQvR,QAI9B,KAAMgD,IAAQwC,GAAKmI,SACZlE,EAAQ1B,EAAW/E,GAAOiH,KAAM4J,KAAcC,EAAY9Q,MAC9DyG,EAAQqK,EAAY9Q,GAAQyG,MAC7B8H,EAAU9H,EAAM6B,QAChBsI,EAAOpV,MACNyF,MAAOsN,EACPvO,KAAMA,EACN8B,QAAS2E,IAEVoK,EAAQA,EAAMvV,MAAOiT,EAAQvR,QAI/B,KAAMuR,EACL,MAOF,MAAOoC,GACNE,EAAM7T,OACN6T,EACCtO,GAAO3C,MAAO1D,GAEdwH,EAAYxH,EAAUyK,GAASrL,MAAO,GAGzC,QAASsM,IAAYgJ,GAIpB,IAHA,GAAI7S,GAAI,EACPM,EAAMuS,EAAO5T,OACbd,EAAW,GACAmC,EAAJN,EAASA,IAChB7B,GAAY0U,EAAO7S,GAAGkD,KAEvB,OAAO/E,GAGR,QAAS8U,IAAevC,EAASwC,EAAYC,GAC5C,GAAIpE,GAAMmE,EAAWnE,IACpBqE,EAAmBD,GAAgB,eAARpE,EAC3BsE,EAAW7N,GAEZ,OAAO0N,GAAW/S,MAEjB,SAAUJ,EAAM3B,EAAS2R,GACxB,MAAShQ,EAAOA,EAAMgP,GACrB,GAAuB,IAAlBhP,EAAKyC,UAAkB4Q,EAC3B,MAAO1C,GAAS3Q,EAAM3B,EAAS2R,IAMlC,SAAUhQ,EAAM3B,EAAS2R,GACxB,GAAIuD,GAAUtD,EACbuD,GAAahO,EAAS8N,EAGvB,IAAKtD,GACJ,MAAShQ,EAAOA,EAAMgP,GACrB,IAAuB,IAAlBhP,EAAKyC,UAAkB4Q,IACtB1C,EAAS3Q,EAAM3B,EAAS2R,GAC5B,OAAO,MAKV,OAAShQ,EAAOA,EAAMgP,GACrB,GAAuB,IAAlBhP,EAAKyC,UAAkB4Q,EAAmB,CAE9C,GADApD,EAAajQ,EAAMyB,KAAczB,EAAMyB,QACjC8R,EAAWtD,EAAYjB,KAC5BuE,EAAU,KAAQ/N,GAAW+N,EAAU,KAAQD,EAG/C,MAAQE,GAAU,GAAMD,EAAU,EAMlC,IAHAtD,EAAYjB,GAAQwE,EAGdA,EAAU,GAAM7C,EAAS3Q,EAAM3B,EAAS2R,GAC7C,OAAO,IASf,QAASyD,IAAgBC,GACxB,MAAOA,GAASxU,OAAS,EACxB,SAAUc,EAAM3B,EAAS2R,GACxB,GAAI/P,GAAIyT,EAASxU,MACjB,OAAQe,IACP,IAAMyT,EAASzT,GAAID,EAAM3B,EAAS2R,GACjC,OAAO,CAGT,QAAO,GAER0D,EAAS,GAGX,QAASC,IAAU/C,EAAW7Q,EAAK8M,EAAQxO,EAAS2R,GAOnD,IANA,GAAIhQ,GACH4T,KACA3T,EAAI,EACJM,EAAMqQ,EAAU1R,OAChB2U,EAAgB,MAAP9T,EAEEQ,EAAJN,EAASA,KACVD,EAAO4Q,EAAU3Q,OAChB4M,GAAUA,EAAQ7M,EAAM3B,EAAS2R,MACtC4D,EAAalW,KAAMsC,GACd6T,GACJ9T,EAAIrC,KAAMuC,GAMd,OAAO2T,GAGR,QAASE,IAAY1E,EAAWhR,EAAUuS,EAASoD,EAAYC,EAAYC,GAO1E,MANKF,KAAeA,EAAYtS,KAC/BsS,EAAaD,GAAYC,IAErBC,IAAeA,EAAYvS,KAC/BuS,EAAaF,GAAYE,EAAYC,IAE/BxJ,GAAa,SAAU/B,EAAMlF,EAASnF,EAAS2R,GACrD,GAAIkE,GAAMjU,EAAGD,EACZmU,KACAC,KACAC,EAAc7Q,EAAQtE,OAGtBM,EAAQkJ,GAAQ4L,GAAkBlW,GAAY,IAAKC,EAAQoE,UAAapE,GAAYA,MAGpFkW,GAAYnF,IAAe1G,GAAStK,EAEnCoB,EADAmU,GAAUnU,EAAO2U,EAAQ/E,EAAW/Q,EAAS2R,GAG9CwE,EAAa7D,EAEZqD,IAAgBtL,EAAO0G,EAAYiF,GAAeN,MAMjDvQ,EACD+Q,CAQF,IALK5D,GACJA,EAAS4D,EAAWC,EAAYnW,EAAS2R,GAIrC+D,EAAa,CACjBG,EAAOP,GAAUa,EAAYJ,GAC7BL,EAAYG,KAAU7V,EAAS2R,GAG/B/P,EAAIiU,EAAKhV,MACT,OAAQe,KACDD,EAAOkU,EAAKjU,MACjBuU,EAAYJ,EAAQnU,MAASsU,EAAWH,EAAQnU,IAAOD,IAK1D,GAAK0I,GACJ,GAAKsL,GAAc5E,EAAY,CAC9B,GAAK4E,EAAa,CAEjBE,KACAjU,EAAIuU,EAAWtV,MACf,OAAQe,KACDD,EAAOwU,EAAWvU,KAEvBiU,EAAKxW,KAAO6W,EAAUtU,GAAKD,EAG7BgU,GAAY,KAAOQ,KAAkBN,EAAMlE,GAI5C/P,EAAIuU,EAAWtV,MACf,OAAQe,KACDD,EAAOwU,EAAWvU,MACtBiU,EAAOF,EAAarW,EAAQyB,KAAMsJ,EAAM1I,GAASmU,EAAOlU,IAAM,KAE/DyI,EAAKwL,KAAU1Q,EAAQ0Q,GAAQlU,SAOlCwU,GAAab,GACZa,IAAehR,EACdgR,EAAW7T,OAAQ0T,EAAaG,EAAWtV,QAC3CsV,GAEGR,EACJA,EAAY,KAAMxQ,EAASgR,EAAYxE,GAEvCtS,EAAKwC,MAAOsD,EAASgR,KAMzB,QAASC,IAAmB3B,GAqB3B,IApBA,GAAI4B,GAAc/D,EAASnQ,EAC1BD,EAAMuS,EAAO5T,OACbyV,EAAkBjQ,EAAKoK,SAAUgE,EAAO,GAAG5Q,MAC3C0S,EAAmBD,GAAmBjQ,EAAKoK,SAAS,KACpD7O,EAAI0U,EAAkB,EAAI,EAG1BE,EAAe3B,GAAe,SAAUlT,GACvC,MAAOA,KAAS0U,GACdE,GAAkB,GACrBE,EAAkB5B,GAAe,SAAUlT,GAC1C,MAAOrC,GAAQyB,KAAMsV,EAAc1U,GAAS,IAC1C4U,GAAkB,GACrBlB,GAAa,SAAU1T,EAAM3B,EAAS2R,GACrC,OAAU2E,IAAqB3E,GAAO3R,IAAYyG,MAChD4P,EAAerW,GAASoE,SACxBoS,EAAc7U,EAAM3B,EAAS2R,GAC7B8E,EAAiB9U,EAAM3B,EAAS2R,MAGxBzP,EAAJN,EAASA,IAChB,GAAM0Q,EAAUjM,EAAKoK,SAAUgE,EAAO7S,GAAGiC,MACxCwR,GAAaR,GAAcO,GAAgBC,GAAY/C,QACjD,CAIN,GAHAA,EAAUjM,EAAKmI,OAAQiG,EAAO7S,GAAGiC,MAAOhC,MAAO,KAAM4S,EAAO7S,GAAG+D,SAG1D2M,EAASlP,GAAY,CAGzB,IADAjB,IAAMP,EACMM,EAAJC,EAASA,IAChB,GAAKkE,EAAKoK,SAAUgE,EAAOtS,GAAG0B,MAC7B,KAGF,OAAO4R,IACN7T,EAAI,GAAKwT,GAAgBC,GACzBzT,EAAI,GAAK6J,GAERgJ,EAAOtV,MAAO,EAAGyC,EAAI,GAAIxC,QAAS0F,MAAgC,MAAzB2P,EAAQ7S,EAAI,GAAIiC,KAAe,IAAM,MAC7EN,QAASpD,EAAO,MAClBmS,EACInQ,EAAJP,GAASwU,GAAmB3B,EAAOtV,MAAOyC,EAAGO,IACzCD,EAAJC,GAAWiU,GAAoB3B,EAASA,EAAOtV,MAAOgD,IAClDD,EAAJC,GAAWsJ,GAAYgJ,IAGzBY,EAAShW,KAAMiT,GAIjB,MAAO8C,IAAgBC,GAGxB,QAASqB,IAA0BC,EAAiBC,GACnD,GAAIC,GAAQD,EAAY/V,OAAS,EAChCiW,EAAYH,EAAgB9V,OAAS,EACrCkW,EAAe,SAAU1M,EAAMrK,EAAS2R,EAAKxM,EAAS6R,GACrD,GAAIrV,GAAMQ,EAAGmQ,EACZ2E,EAAe,EACfrV,EAAI,IACJ2Q,EAAYlI,MACZ6M,KACAC,EAAgB1Q,EAEhBtF,EAAQkJ,GAAQyM,GAAazQ,EAAKkI,KAAU,IAAG,IAAKyI,GAEpDI,EAAiBjQ,GAA4B,MAAjBgQ,EAAwB,EAAI9T,KAAKC,UAAY,GACzEpB,EAAMf,EAAMN,MAUb,KARKmW,IACJvQ,EAAmBzG,IAAYpB,GAAYoB,GAOpC4B,IAAMM,GAA4B,OAApBP,EAAOR,EAAMS,IAAaA,IAAM,CACrD,GAAKkV,GAAanV,EAAO,CACxBQ,EAAI,CACJ,OAASmQ,EAAUqE,EAAgBxU,KAClC,GAAKmQ,EAAS3Q,EAAM3B,EAAS2R,GAAQ,CACpCxM,EAAQ9F,KAAMsC,EACd,OAGGqV,IACJ7P,EAAUiQ,GAKPP,KAEElV,GAAQ2Q,GAAW3Q,IACxBsV,IAII5M,GACJkI,EAAUlT,KAAMsC,IAOnB,GADAsV,GAAgBrV,EACXiV,GAASjV,IAAMqV,EAAe,CAClC9U,EAAI,CACJ,OAASmQ,EAAUsE,EAAYzU,KAC9BmQ,EAASC,EAAW2E,EAAYlX,EAAS2R,EAG1C,IAAKtH,EAAO,CAEX,GAAK4M,EAAe,EACnB,MAAQrV,IACA2Q,EAAU3Q,IAAMsV,EAAWtV,KACjCsV,EAAWtV,GAAKkG,EAAI/G,KAAMoE,GAM7B+R,GAAa5B,GAAU4B,GAIxB7X,EAAKwC,MAAOsD,EAAS+R,GAGhBF,IAAc3M,GAAQ6M,EAAWrW,OAAS,GAC5CoW,EAAeL,EAAY/V,OAAW,GAExCuF,GAAO6J,WAAY9K,GAUrB,MALK6R,KACJ7P,EAAUiQ,EACV3Q,EAAmB0Q,GAGb5E,EAGT,OAAOsE,GACNzK,GAAc2K,GACdA,EAGFvQ,EAAUJ,GAAOI,QAAU,SAAUzG,EAAUsX,GAC9C,GAAIzV,GACHgV,KACAD,KACA/B,EAASpN,EAAezH,EAAW,IAEpC,KAAM6U,EAAS,CAERyC,IACLA,EAAQ/L,GAAUvL,IAEnB6B,EAAIyV,EAAMxW,MACV,OAAQe,IACPgT,EAASwB,GAAmBiB,EAAMzV,IAC7BgT,EAAQxR,GACZwT,EAAYvX,KAAMuV,GAElB+B,EAAgBtX,KAAMuV,EAKxBA,GAASpN,EAAezH,EAAU2W,GAA0BC,EAAiBC,IAE9E,MAAOhC,GAGR,SAASqB,IAAkBlW,EAAUuX,EAAUnS,GAG9C,IAFA,GAAIvD,GAAI,EACPM,EAAMoV,EAASzW,OACJqB,EAAJN,EAASA,IAChBwE,GAAQrG,EAAUuX,EAAS1V,GAAIuD,EAEhC,OAAOA,GAGR,QAAS4G,IAAQhM,EAAUC,EAASmF,EAASkF,GAC5C,GAAIzI,GAAG6S,EAAQ8C,EAAO1T,EAAM0K,EAC3BjE,EAAQgB,GAAUvL,EAEnB,KAAMsK,GAEiB,IAAjBC,EAAMzJ,OAAe,CAIzB,GADA4T,EAASnK,EAAM,GAAKA,EAAM,GAAGnL,MAAO,GAC/BsV,EAAO5T,OAAS,GAAkC,QAA5B0W,EAAQ9C,EAAO,IAAI5Q,MAC5CjE,EAAQyO,SAAgC,IAArBrO,EAAQoE,UAAkB0C,GAC7CT,EAAKoK,SAAUgE,EAAO,GAAG5Q,MAAS,CAGnC,GADA7D,GAAYqG,EAAKkI,KAAS,GAAGgJ,EAAM5R,QAAQ,GAAGpC,QAAQoG,GAAWC,IAAY5J,QAAkB,IACzFA,EACL,MAAOmF,EAERpF,GAAWA,EAASZ,MAAOsV,EAAOtI,QAAQrH,MAAMjE,QAIjDe,EAAIgH,EAAwB,aAAEyC,KAAMtL,GAAa,EAAI0U,EAAO5T,MAC5D,OAAQe,IAAM,CAIb,GAHA2V,EAAQ9C,EAAO7S,GAGVyE,EAAKoK,SAAW5M,EAAO0T,EAAM1T,MACjC,KAED,KAAM0K,EAAOlI,EAAKkI,KAAM1K,MAEjBwG,EAAOkE,EACZgJ,EAAM5R,QAAQ,GAAGpC,QAASoG,GAAWC,IACrCH,EAAS4B,KAAMoJ,EAAO,GAAG5Q,OAAU6H,GAAa1L,EAAQgL,aAAgBhL,IACpE,CAKJ,GAFAyU,EAAOnS,OAAQV,EAAG,GAClB7B,EAAWsK,EAAKxJ,QAAU4K,GAAYgJ,IAChC1U,EAEL,MADAV,GAAKwC,MAAOsD,EAASkF,GACdlF,CAGR,SAgBL,MAPAqB,GAASzG,EAAUuK,GAClBD,EACArK,GACC8G,EACD3B,EACAsE,EAAS4B,KAAMtL,IAAc2L,GAAa1L,EAAQgL,aAAgBhL,GAE5DmF,EAkER,MA5DAvF,GAAQwQ,WAAahN,EAAQ+C,MAAM,IAAI9D,KAAMoF,GAAYkE,KAAK,MAAQvI,EAItExD,EAAQuQ,mBAAqBxJ,EAG7BC,IAIAhH,EAAQ2P,aAAelD,GAAO,SAAUmL,GAEvC,MAAuE,GAAhEA,EAAKrI,wBAAyBvQ,EAAS2N,cAAc,UAMvDF,GAAO,SAAUC,GAEtB,MADAA,GAAI6B,UAAY,mBAC+B,MAAxC7B,EAAI8B,WAAW7C,aAAa,WAEnCkB,GAAW,yBAA0B,SAAU9K,EAAMgB,EAAM4D,GAC1D,MAAMA,GAAN,OACQ5E,EAAK4J,aAAc5I,EAA6B,SAAvBA,EAAKkC,cAA2B,EAAI,KAOjEjF,EAAQwI,YAAeiE,GAAO,SAAUC,GAG7C,MAFAA,GAAI6B,UAAY,WAChB7B,EAAI8B,WAAW5C,aAAc,QAAS,IACY,KAA3Cc,EAAI8B,WAAW7C,aAAc,YAEpCkB,GAAW,QAAS,SAAU9K,EAAMgB,EAAM4D,GACzC,MAAMA,IAAyC,UAAhC5E,EAAKiD,SAASC,cAA7B,OACQlD,EAAK8V,eAOTpL,GAAO,SAAUC,GACtB,MAAuC,OAAhCA,EAAIf,aAAa,eAExBkB,GAAWzE,EAAU,SAAUrG,EAAMgB,EAAM4D,GAC1C,GAAIwJ,EACJ,OAAMxJ,GAAN,OACQ5E,EAAMgB,MAAW,EAAOA,EAAKkC,eACjCkL,EAAMpO,EAAK+M,iBAAkB/L,KAAWoN,EAAIC,UAC7CD,EAAIjL,MACL,OAKGsB,IAEHrH,EAIJe,GAAOyO,KAAOnI,EACdtG,EAAO8P,KAAOxJ,EAAOmK,UACrBzQ,EAAO8P,KAAK,KAAO9P,EAAO8P,KAAKvH,QAC/BvI,EAAO4X,OAAStR,EAAO6J,WACvBnQ,EAAOkF,KAAOoB,EAAOE,QACrBxG,EAAO6X,SAAWvR,EAAOG,MACzBzG,EAAOmH,SAAWb,EAAOa,QAIzB,IAAI2Q,GAAgB9X,EAAO8P,KAAKtF,MAAMlB,aAElCyO,EAAa,6BAIbC,EAAY,gBAGhB,SAASC,GAAQlI,EAAUmI,EAAW3F,GACrC,GAAKvS,EAAOkD,WAAYgV,GACvB,MAAOlY,GAAO0F,KAAMqK,EAAU,SAAUlO,EAAMC,GAE7C,QAASoW,EAAUjX,KAAMY,EAAMC,EAAGD,KAAW0Q,GAK/C,IAAK2F,EAAU5T,SACd,MAAOtE,GAAO0F,KAAMqK,EAAU,SAAUlO,GACvC,MAASA,KAASqW,IAAgB3F,GAKpC,IAA0B,gBAAd2F,GAAyB,CACpC,GAAKF,EAAUzM,KAAM2M,GACpB,MAAOlY,GAAO0O,OAAQwJ,EAAWnI,EAAUwC,EAG5C2F,GAAYlY,EAAO0O,OAAQwJ,EAAWnI,GAGvC,MAAO/P,GAAO0F,KAAMqK,EAAU,SAAUlO,GACvC,MAAS7B,GAAOuF,QAAS1D,EAAMqW,IAAe,IAAQ3F,IAIxDvS,EAAO0O,OAAS,SAAUoB,EAAMzO,EAAOkR,GACtC,GAAI1Q,GAAOR,EAAO,EAMlB,OAJKkR,KACJzC,EAAO,QAAUA,EAAO,KAGD,IAAjBzO,EAAMN,QAAkC,IAAlBc,EAAKyC,SACjCtE,EAAOyO,KAAKM,gBAAiBlN,EAAMiO,IAAWjO,MAC9C7B,EAAOyO,KAAK5I,QAASiK,EAAM9P,EAAO0F,KAAMrE,EAAO,SAAUQ,GACxD,MAAyB,KAAlBA,EAAKyC,aAIftE,EAAOG,GAAGsC,QACTgM,KAAM,SAAUxO,GACf,GAAI6B,GACHR,KACA6W,EAAOjZ,KACPkD,EAAM+V,EAAKpX,MAEZ,IAAyB,gBAAbd,GACX,MAAOf,MAAKkC,UAAWpB,EAAQC,GAAWyO,OAAO,WAChD,IAAM5M,EAAI,EAAOM,EAAJN,EAASA,IACrB,GAAK9B,EAAOmH,SAAUgR,EAAMrW,GAAK5C,MAChC,OAAO,IAMX,KAAM4C,EAAI,EAAOM,EAAJN,EAASA,IACrB9B,EAAOyO,KAAMxO,EAAUkY,EAAMrW,GAAKR,EAMnC,OAFAA,GAAMpC,KAAKkC,UAAWgB,EAAM,EAAIpC,EAAO4X,OAAQtW,GAAQA,GACvDA,EAAIrB,SAAWf,KAAKe,SAAWf,KAAKe,SAAW,IAAMA,EAAWA,EACzDqB,GAERoN,OAAQ,SAAUzO,GACjB,MAAOf,MAAKkC,UAAW6W,EAAO/Y,KAAMe,OAAgB,KAErDsS,IAAK,SAAUtS,GACd,MAAOf,MAAKkC,UAAW6W,EAAO/Y,KAAMe,OAAgB,KAErDmY,GAAI,SAAUnY,GACb,QAASgY,EACR/Y,KAIoB,gBAAbe,IAAyB6X,EAAcvM,KAAMtL,GACnDD,EAAQC,GACRA,OACD,GACCc,SASJ,IAAIsX,GAGHvZ,EAAWG,EAAOH,SAKlB4K,EAAa,sCAEbtJ,EAAOJ,EAAOG,GAAGC,KAAO,SAAUH,EAAUC,GAC3C,GAAIsK,GAAO3I,CAGX,KAAM5B,EACL,MAAOf,KAIR,IAAyB,gBAAbe,GAAwB,CAUnC,GAPCuK,EAF2B,MAAvBvK,EAASqY,OAAO,IAAyD,MAA3CrY,EAASqY,OAAQrY,EAASc,OAAS,IAAed,EAASc,QAAU,GAE7F,KAAMd,EAAU,MAGlByJ,EAAWsB,KAAM/K,IAIrBuK,IAAUA,EAAM,IAAOtK,EAsDrB,OAAMA,GAAWA,EAAQW,QACtBX,GAAWmY,GAAa5J,KAAMxO,GAKhCf,KAAK4B,YAAaZ,GAAUuO,KAAMxO,EAzDzC,IAAKuK,EAAM,GAAK,CAYf,GAXAtK,EAAUA,YAAmBF,GAASE,EAAQ,GAAKA,EAInDF,EAAOuB,MAAOrC,KAAMc,EAAOuY,UAC1B/N,EAAM,GACNtK,GAAWA,EAAQoE,SAAWpE,EAAQ6K,eAAiB7K,EAAUpB,GACjE,IAIIiZ,EAAWxM,KAAMf,EAAM,KAAQxK,EAAOmD,cAAejD,GACzD,IAAMsK,IAAStK,GAETF,EAAOkD,WAAYhE,KAAMsL,IAC7BtL,KAAMsL,GAAStK,EAASsK,IAIxBtL,KAAK8Q,KAAMxF,EAAOtK,EAASsK,GAK9B,OAAOtL,MAQP,GAJA2C,EAAO/C,EAASmM,eAAgBT,EAAM,IAIjC3I,GAAQA,EAAKqJ,WAAa,CAG9B,GAAKrJ,EAAKsJ,KAAOX,EAAM,GACtB,MAAO6N,GAAW5J,KAAMxO,EAIzBf,MAAK6B,OAAS,EACd7B,KAAK,GAAK2C,EAKX,MAFA3C,MAAKgB,QAAUpB,EACfI,KAAKe,SAAWA,EACTf,KAcH,MAAKe,GAASqE,UACpBpF,KAAKgB,QAAUhB,KAAK,GAAKe,EACzBf,KAAK6B,OAAS,EACP7B,MAIIc,EAAOkD,WAAYjD,GACK,mBAArBoY,GAAWG,MACxBH,EAAWG,MAAOvY,GAElBA,EAAUD,IAGeqD,SAAtBpD,EAASA,WACbf,KAAKe,SAAWA,EAASA,SACzBf,KAAKgB,QAAUD,EAASC,SAGlBF,EAAOmF,UAAWlF,EAAUf,OAIrCkB,GAAKQ,UAAYZ,EAAOG,GAGxBkY,EAAarY,EAAQlB,EAGrB,IAAI2Z,GAAe,iCAElBC,GACCC,UAAU,EACVC,UAAU,EACVC,MAAM,EACNC,MAAM,EAGR9Y,GAAOyC,QACNoO,IAAK,SAAUhP,EAAMgP,EAAKkI,GACzB,GAAIzG,MACHtF,EAAMnL,EAAMgP,EAEb,OAAQ7D,GAAwB,IAAjBA,EAAI1I,WAA6BjB,SAAV0V,GAAwC,IAAjB/L,EAAI1I,WAAmBtE,EAAQgN,GAAMoL,GAAIW,IAC/E,IAAjB/L,EAAI1I,UACRgO,EAAQ/S,KAAMyN,GAEfA,EAAMA,EAAI6D,EAEX,OAAOyB,IAGR0G,QAAS,SAAUC,EAAGpX,GAGrB,IAFA,GAAIqX,MAEID,EAAGA,EAAIA,EAAE9L,YACI,IAAf8L,EAAE3U,UAAkB2U,IAAMpX,GAC9BqX,EAAE3Z,KAAM0Z,EAIV,OAAOC,MAITlZ,EAAOG,GAAGsC,QACTiQ,IAAK,SAAU1P,GACd,GAAIlB,GACHqX,EAAUnZ,EAAQgD,EAAQ9D,MAC1BkD,EAAM+W,EAAQpY,MAEf,OAAO7B,MAAKwP,OAAO,WAClB,IAAM5M,EAAI,EAAOM,EAAJN,EAASA,IACrB,GAAK9B,EAAOmH,SAAUjI,KAAMia,EAAQrX,IACnC,OAAO,KAMXsX,QAAS,SAAU3I,EAAWvQ,GAS7B,IARA,GAAI8M,GACHlL,EAAI,EACJuX,EAAIna,KAAK6B,OACTuR,KACAgH,EAAMxB,EAAcvM,KAAMkF,IAAoC,gBAAdA,GAC/CzQ,EAAQyQ,EAAWvQ,GAAWhB,KAAKgB,SACnC,EAEUmZ,EAAJvX,EAAOA,IACd,IAAMkL,EAAM9N,KAAK4C,GAAIkL,GAAOA,IAAQ9M,EAAS8M,EAAMA,EAAI9B,WAEtD,GAAK8B,EAAI1I,SAAW,KAAOgV,EAC1BA,EAAIC,MAAMvM,GAAO,GAGA,IAAjBA,EAAI1I,UACHtE,EAAOyO,KAAKM,gBAAgB/B,EAAKyD,IAAc,CAEhD6B,EAAQ/S,KAAMyN,EACd,OAKH,MAAO9N,MAAKkC,UAAWkR,EAAQvR,OAAS,EAAIf,EAAO4X,OAAQtF,GAAYA,IAKxEiH,MAAO,SAAU1X,GAGhB,MAAMA,GAKe,gBAATA,GACJ7B,EAAOuF,QAASrG,KAAK,GAAIc,EAAQ6B,IAIlC7B,EAAOuF,QAEb1D,EAAKhB,OAASgB,EAAK,GAAKA,EAAM3C,MAXrBA,KAAK,IAAMA,KAAK,GAAGgM,WAAehM,KAAK+C,QAAQuX,UAAUzY,OAAS,IAc7E0Y,IAAK,SAAUxZ,EAAUC,GACxB,MAAOhB,MAAKkC,UACXpB,EAAO4X,OACN5X,EAAOuB,MAAOrC,KAAKgC,MAAOlB,EAAQC,EAAUC,OAK/CwZ,QAAS,SAAUzZ,GAClB,MAAOf,MAAKua,IAAiB,MAAZxZ,EAChBf,KAAKsC,WAAatC,KAAKsC,WAAWkN,OAAOzO,MAK5C,SAAS+Y,GAAShM,EAAK6D,GACtB,EACC7D,GAAMA,EAAK6D,SACF7D,GAAwB,IAAjBA,EAAI1I,SAErB,OAAO0I,GAGRhN,EAAOyB,MACNoM,OAAQ,SAAUhM,GACjB,GAAIgM,GAAShM,EAAKqJ,UAClB,OAAO2C,IAA8B,KAApBA,EAAOvJ,SAAkBuJ,EAAS,MAEpD8L,QAAS,SAAU9X,GAClB,MAAO7B,GAAO6Q,IAAKhP,EAAM,eAE1B+X,aAAc,SAAU/X,EAAMC,EAAGiX,GAChC,MAAO/Y,GAAO6Q,IAAKhP,EAAM,aAAckX,IAExCF,KAAM,SAAUhX,GACf,MAAOmX,GAASnX,EAAM,gBAEvBiX,KAAM,SAAUjX,GACf,MAAOmX,GAASnX,EAAM,oBAEvBgY,QAAS,SAAUhY,GAClB,MAAO7B,GAAO6Q,IAAKhP,EAAM,gBAE1B2X,QAAS,SAAU3X,GAClB,MAAO7B,GAAO6Q,IAAKhP,EAAM,oBAE1BiY,UAAW,SAAUjY,EAAMC,EAAGiX,GAC7B,MAAO/Y,GAAO6Q,IAAKhP,EAAM,cAAekX,IAEzCgB,UAAW,SAAUlY,EAAMC,EAAGiX,GAC7B,MAAO/Y,GAAO6Q,IAAKhP,EAAM,kBAAmBkX,IAE7CiB,SAAU,SAAUnY,GACnB,MAAO7B,GAAOgZ,SAAWnX,EAAKqJ,gBAAmBoD,WAAYzM,IAE9D8W,SAAU,SAAU9W,GACnB,MAAO7B,GAAOgZ,QAASnX,EAAKyM,aAE7BsK,SAAU,SAAU/W,GACnB,MAAO7B,GAAO8E,SAAUjD,EAAM,UAC7BA,EAAKoY,iBAAmBpY,EAAKqY,cAAcpb,SAC3CkB,EAAOuB,SAAWM,EAAKwI,cAEvB,SAAUxH,EAAM1C,GAClBH,EAAOG,GAAI0C,GAAS,SAAUkW,EAAO9Y,GACpC,GAAIqB,GAAMtB,EAAO4B,IAAK1C,KAAMiB,EAAI4Y,EAsBhC,OApB0B,UAArBlW,EAAKxD,MAAO,MAChBY,EAAW8Y,GAGP9Y,GAAgC,gBAAbA,KACvBqB,EAAMtB,EAAO0O,OAAQzO,EAAUqB,IAG3BpC,KAAK6B,OAAS,IAEZ2X,EAAkB7V,KACvBvB,EAAMtB,EAAO4X,OAAQtW,IAIjBmX,EAAalN,KAAM1I,KACvBvB,EAAMA,EAAI6Y,YAILjb,KAAKkC,UAAWE,KAGzB,IAAI8Y,GAAY,OAKZC,IAGJ,SAASC,GAAexX,GACvB,GAAIyX,GAASF,EAAcvX,KAI3B,OAHA9C,GAAOyB,KAAMqB,EAAQ0H,MAAO4P,OAAmB,SAAUrQ,EAAGyQ,GAC3DD,EAAQC,IAAS,IAEXD,EAyBRva,EAAOya,UAAY,SAAU3X,GAI5BA,EAA6B,gBAAZA,GACduX,EAAcvX,IAAawX,EAAexX,GAC5C9C,EAAOyC,UAAYK,EAEpB,IACC4X,GAEAC,EAEAC,EAEAC,EAEAC,EAEAC,EAEAC,KAEAC,GAASnY,EAAQoY,SAEjBC,EAAO,SAAUzW,GAOhB,IANAiW,EAAS7X,EAAQ6X,QAAUjW,EAC3BkW,GAAQ,EACRE,EAAcC,GAAe,EAC7BA,EAAc,EACdF,EAAeG,EAAKja,OACpB2Z,GAAS,EACDM,GAAsBH,EAAdC,EAA4BA,IAC3C,GAAKE,EAAMF,GAAc/Y,MAAO2C,EAAM,GAAKA,EAAM,OAAU,GAAS5B,EAAQsY,YAAc,CACzFT,GAAS,CACT,OAGFD,GAAS,EACJM,IACCC,EACCA,EAAMla,QACVoa,EAAMF,EAAM5O,SAEFsO,EACXK,KAEA7C,EAAKkD,YAKRlD,GAECsB,IAAK,WACJ,GAAKuB,EAAO,CAEX,GAAIhJ,GAAQgJ,EAAKja,QACjB,QAAU0Y,GAAK9X,GACd3B,EAAOyB,KAAME,EAAM,SAAUoI,EAAGhE,GAC/B,GAAIhC,GAAO/D,EAAO+D,KAAMgC,EACV,cAAThC,EACEjB,EAAQ8U,QAAWO,EAAKzF,IAAK3M,IAClCiV,EAAKzb,KAAMwG,GAEDA,GAAOA,EAAIhF,QAAmB,WAATgD,GAEhC0V,EAAK1T,MAGJ/D,WAGC0Y,EACJG,EAAeG,EAAKja,OAGT4Z,IACXI,EAAc/I,EACdmJ,EAAMR,IAGR,MAAOzb,OAGRoc,OAAQ,WAkBP,MAjBKN,IACJhb,EAAOyB,KAAMO,UAAW,SAAU+H,EAAGhE,GACpC,GAAIwT,EACJ,QAAUA,EAAQvZ,EAAOuF,QAASQ,EAAKiV,EAAMzB,IAAY,GACxDyB,EAAKxY,OAAQ+W,EAAO,GAEfmB,IACUG,GAATtB,GACJsB,IAEaC,GAATvB,GACJuB,OAME5b,MAIRwT,IAAK,SAAUvS,GACd,MAAOA,GAAKH,EAAOuF,QAASpF,EAAI6a,GAAS,MAASA,IAAQA,EAAKja,SAGhE4S,MAAO,WAGN,MAFAqH,MACAH,EAAe,EACR3b,MAGRmc,QAAS,WAER,MADAL,GAAOC,EAAQN,EAAStX,OACjBnE,MAGRqU,SAAU,WACT,OAAQyH,GAGTO,KAAM,WAKL,MAJAN,GAAQ5X,OACFsX,GACLxC,EAAKkD,UAECnc,MAGRsc,OAAQ,WACP,OAAQP,GAGTQ,SAAU,SAAUvb,EAASyB,GAU5B,OATKqZ,GAAWJ,IAASK,IACxBtZ,EAAOA,MACPA,GAASzB,EAASyB,EAAKtC,MAAQsC,EAAKtC,QAAUsC,GACzC+Y,EACJO,EAAM1b,KAAMoC,GAEZwZ,EAAMxZ,IAGDzC,MAGRic,KAAM,WAEL,MADAhD,GAAKsD,SAAUvc,KAAM8C,WACd9C,MAGR0b,MAAO,WACN,QAASA,GAIZ,OAAOzC,IAIRnY,EAAOyC,QAENiZ,SAAU,SAAUC,GACnB,GAAIC,KAEA,UAAW,OAAQ5b,EAAOya,UAAU,eAAgB,aACpD,SAAU,OAAQza,EAAOya,UAAU,eAAgB,aACnD,SAAU,WAAYza,EAAOya,UAAU,YAE1CoB,EAAQ,UACRC,GACCD,MAAO,WACN,MAAOA,IAERE,OAAQ,WAEP,MADAC,GAAS1U,KAAMtF,WAAYia,KAAMja,WAC1B9C,MAERgd,KAAM,WACL,GAAIC,GAAMna,SACV,OAAOhC,GAAO0b,SAAS,SAAUU,GAChCpc,EAAOyB,KAAMma,EAAQ,SAAU9Z,EAAGua,GACjC,GAAIlc,GAAKH,EAAOkD,WAAYiZ,EAAKra,KAASqa,EAAKra,EAE/Cka,GAAUK,EAAM,IAAK,WACpB,GAAIC,GAAWnc,GAAMA,EAAG4B,MAAO7C,KAAM8C,UAChCsa,IAAYtc,EAAOkD,WAAYoZ,EAASR,SAC5CQ,EAASR,UACPxU,KAAM8U,EAASG,SACfN,KAAMG,EAASI,QACfC,SAAUL,EAASM,QAErBN,EAAUC,EAAO,GAAM,QAAUnd,OAAS4c,EAAUM,EAASN,UAAY5c,KAAMiB,GAAOmc,GAAata,eAItGma,EAAM,OACJL,WAIJA,QAAS,SAAUhY,GAClB,MAAc,OAAPA,EAAc9D,EAAOyC,OAAQqB,EAAKgY,GAAYA,IAGvDE,IAwCD,OArCAF,GAAQa,KAAOb,EAAQI,KAGvBlc,EAAOyB,KAAMma,EAAQ,SAAU9Z,EAAGua,GACjC,GAAIrB,GAAOqB,EAAO,GACjBO,EAAcP,EAAO,EAGtBP,GAASO,EAAM,IAAOrB,EAAKvB,IAGtBmD,GACJ5B,EAAKvB,IAAI,WAERoC,EAAQe,GAGNhB,EAAY,EAAJ9Z,GAAS,GAAIuZ,QAASO,EAAQ,GAAK,GAAIL,MAInDS,EAAUK,EAAM,IAAO,WAEtB,MADAL,GAAUK,EAAM,GAAK,QAAUnd,OAAS8c,EAAWF,EAAU5c,KAAM8C,WAC5D9C,MAER8c,EAAUK,EAAM,GAAK,QAAWrB,EAAKS,WAItCK,EAAQA,QAASE,GAGZL,GACJA,EAAK1a,KAAM+a,EAAUA,GAIfA,GAIRa,KAAM,SAAUC,GACf,GAAIhb,GAAI,EACPib,EAAgB1d,EAAM4B,KAAMe,WAC5BjB,EAASgc,EAAchc,OAGvBic,EAAuB,IAAXjc,GAAkB+b,GAAe9c,EAAOkD,WAAY4Z,EAAYhB,SAAc/a,EAAS,EAGnGib,EAAyB,IAAdgB,EAAkBF,EAAc9c,EAAO0b,WAGlDuB,EAAa,SAAUnb,EAAG0V,EAAU0F,GACnC,MAAO,UAAUlY,GAChBwS,EAAU1V,GAAM5C,KAChBge,EAAQpb,GAAME,UAAUjB,OAAS,EAAI1B,EAAM4B,KAAMe,WAAcgD,EAC1DkY,IAAWC,EACfnB,EAASoB,WAAY5F,EAAU0F,KAEhBF,GACfhB,EAASqB,YAAa7F,EAAU0F,KAKnCC,EAAgBG,EAAkBC,CAGnC,IAAKxc,EAAS,EAIb,IAHAoc,EAAiB,GAAInZ,OAAOjD,GAC5Buc,EAAmB,GAAItZ,OAAOjD,GAC9Bwc,EAAkB,GAAIvZ,OAAOjD,GACjBA,EAAJe,EAAYA,IACdib,EAAejb,IAAO9B,EAAOkD,WAAY6Z,EAAejb,GAAIga,SAChEiB,EAAejb,GAAIga,UACjBxU,KAAM2V,EAAYnb,EAAGyb,EAAiBR,IACtCd,KAAMD,EAASQ,QACfC,SAAUQ,EAAYnb,EAAGwb,EAAkBH,MAE3CH,CAUL,OAJMA,IACLhB,EAASqB,YAAaE,EAAiBR,GAGjCf,EAASF,YAMlB,IAAI0B,EAEJxd,GAAOG,GAAGqY,MAAQ,SAAUrY,GAI3B,MAFAH,GAAOwY,MAAMsD,UAAUxU,KAAMnH,GAEtBjB,MAGRc,EAAOyC,QAENiB,SAAS,EAIT+Z,UAAW,EAGXC,UAAW,SAAUC,GACfA,EACJ3d,EAAOyd,YAEPzd,EAAOwY,OAAO,IAKhBA,MAAO,SAAUoF,GAGhB,GAAKA,KAAS,KAAS5d,EAAOyd,WAAYzd,EAAO0D,QAAjD,CAKA,IAAM5E,EAAS+e,KACd,MAAOC,YAAY9d,EAAOwY,MAI3BxY,GAAO0D,SAAU,EAGZka,KAAS,KAAU5d,EAAOyd,UAAY,IAK3CD,EAAUH,YAAave,GAAYkB,IAG9BA,EAAOG,GAAG4d,SACd/d,EAAQlB,GAAWif,QAAQ,SAASC,IAAI,aAQ3C,SAASC,KACHnf,EAASkP,kBACblP,EAASof,oBAAqB,mBAAoBC,GAAW,GAC7Dlf,EAAOif,oBAAqB,OAAQC,GAAW,KAG/Crf,EAASsf,YAAa,qBAAsBD,GAC5Clf,EAAOmf,YAAa,SAAUD,IAOhC,QAASA,MAEHrf,EAASkP,kBAAmC,SAAfqQ,MAAMta,MAA2C,aAAxBjF,EAASwf,cACnEL,IACAje,EAAOwY,SAITxY,EAAOwY,MAAMsD,QAAU,SAAUhY,GAChC,IAAM0Z,EAOL,GALAA,EAAYxd,EAAO0b,WAKU,aAAxB5c,EAASwf,WAEbR,WAAY9d,EAAOwY,WAGb,IAAK1Z,EAASkP,iBAEpBlP,EAASkP,iBAAkB,mBAAoBmQ,GAAW,GAG1Dlf,EAAO+O,iBAAkB,OAAQmQ,GAAW,OAGtC,CAENrf,EAASmP,YAAa,qBAAsBkQ,GAG5Clf,EAAOgP,YAAa,SAAUkQ,EAI9B,IAAIpQ,IAAM,CAEV,KACCA,EAA6B,MAAvB9O,EAAOsf,cAAwBzf,EAAS2O,gBAC7C,MAAMlJ,IAEHwJ,GAAOA,EAAIyQ,WACf,QAAUC,KACT,IAAMze,EAAO0D,QAAU,CAEtB,IAGCqK,EAAIyQ,SAAS,QACZ,MAAMja,GACP,MAAOuZ,YAAYW,EAAe,IAInCR,IAGAje,EAAOwY,YAMZ,MAAOgF,GAAU1B,QAAShY,GAI3B,IAAIgE,GAAe,YAMfhG,CACJ,KAAMA,IAAK9B,GAAQF,GAClB,KAEDA,GAAQ0E,QAAgB,MAAN1C,EAIlBhC,EAAQ4e,wBAAyB,EAEjC1e,EAAO,WAIN,GAAI2e,GAAWnS,EACdqR,EAAO/e,EAASsM,qBAAqB,QAAQ,EAExCyS,KAMNc,EAAY7f,EAAS2N,cAAe,OACpCkS,EAAUC,MAAMC,QAAU,gFAE1BrS,EAAM1N,EAAS2N,cAAe,OAC9BoR,EAAK1P,YAAawQ,GAAYxQ,YAAa3B,SAE/BA,GAAIoS,MAAME,OAAShX,IAK9B0E,EAAIoS,MAAMC,QAAU,iEAEd/e,EAAQ4e,uBAA+C,IAApBlS,EAAIuS,eAI5ClB,EAAKe,MAAME,KAAO,IAIpBjB,EAAKnR,YAAaiS,GAGlBA,EAAYnS,EAAM,QAMnB,WACC,GAAIA,GAAM1N,EAAS2N,cAAe,MAGlC,IAA6B,MAAzB3M,EAAQkf,cAAuB,CAElClf,EAAQkf,eAAgB,CACxB,WACQxS,GAAIjB,KACV,MAAOhH,GACRzE,EAAQkf,eAAgB,GAK1BxS,EAAM,QAOPxM,EAAOif,WAAa,SAAUpd,GAC7B,GAAIqd,GAASlf,EAAOkf,QAASrd,EAAKiD,SAAW,KAAKC,eACjDT,GAAYzC,EAAKyC,UAAY,CAG9B,OAAoB,KAAbA,GAA+B,IAAbA,GACxB,GAGC4a,GAAUA,KAAW,GAAQrd,EAAK4J,aAAa,aAAeyT,EAIjE,IAAIC,GAAS,gCACZC,EAAa,UAEd,SAASC,GAAUxd,EAAMwC,EAAKK,GAG7B,GAAcrB,SAATqB,GAAwC,IAAlB7C,EAAKyC,SAAiB,CAEhD,GAAIzB,GAAO,QAAUwB,EAAIZ,QAAS2b,EAAY,OAAQra,aAItD,IAFAL,EAAO7C,EAAK4J,aAAc5I,GAEL,gBAAT6B,GAAoB,CAC/B,IACCA,EAAgB,SAATA,GAAkB,EACf,UAATA,GAAmB,EACV,SAATA,EAAkB,MAEjBA,EAAO,KAAOA,GAAQA,EACvBya,EAAO5T,KAAM7G,GAAS1E,EAAOsf,UAAW5a,GACxCA,EACA,MAAOH,IAGTvE,EAAO0E,KAAM7C,EAAMwC,EAAKK,OAGxBA,GAAOrB,OAIT,MAAOqB,GAIR,QAAS6a,GAAmBzb,GAC3B,GAAIjB,EACJ,KAAMA,IAAQiB,GAGb,IAAc,SAATjB,IAAmB7C,EAAOoE,cAAeN,EAAIjB,MAGpC,WAATA,EACJ,OAAO,CAIT,QAAO,EAGR,QAAS2c,GAAc3d,EAAMgB,EAAM6B,EAAM+a,GACxC,GAAMzf,EAAOif,WAAYpd,GAAzB,CAIA,GAAIP,GAAKoe,EACRC,EAAc3f,EAAOsD,QAIrBsc,EAAS/d,EAAKyC,SAId6H,EAAQyT,EAAS5f,EAAOmM,MAAQtK,EAIhCsJ,EAAKyU,EAAS/d,EAAM8d,GAAgB9d,EAAM8d,IAAiBA,CAI5D,IAAOxU,GAAOgB,EAAMhB,KAASsU,GAAQtT,EAAMhB,GAAIzG,OAAmBrB,SAATqB,GAAsC,gBAAT7B,GAgEtF,MA5DMsI,KAIJA,EADIyU,EACC/d,EAAM8d,GAAgBvgB,EAAW4I,OAAShI,EAAOgG,OAEjD2Z,GAIDxT,EAAOhB,KAGZgB,EAAOhB,GAAOyU,MAAgBC,OAAQ7f,EAAO6D,QAKzB,gBAAThB,IAAqC,kBAATA,MAClC4c,EACJtT,EAAOhB,GAAOnL,EAAOyC,OAAQ0J,EAAOhB,GAAMtI,GAE1CsJ,EAAOhB,GAAKzG,KAAO1E,EAAOyC,OAAQ0J,EAAOhB,GAAKzG,KAAM7B,IAItD6c,EAAYvT,EAAOhB,GAKbsU,IACCC,EAAUhb,OACfgb,EAAUhb,SAGXgb,EAAYA,EAAUhb,MAGTrB,SAATqB,IACJgb,EAAW1f,EAAO4E,UAAW/B,IAAW6B,GAKpB,gBAAT7B,IAGXvB,EAAMoe,EAAW7c,GAGL,MAAPvB,IAGJA,EAAMoe,EAAW1f,EAAO4E,UAAW/B,MAGpCvB,EAAMoe,EAGApe;EAGR,QAASwe,GAAoBje,EAAMgB,EAAM4c,GACxC,GAAMzf,EAAOif,WAAYpd,GAAzB,CAIA,GAAI6d,GAAW5d,EACd8d,EAAS/d,EAAKyC,SAGd6H,EAAQyT,EAAS5f,EAAOmM,MAAQtK,EAChCsJ,EAAKyU,EAAS/d,EAAM7B,EAAOsD,SAAYtD,EAAOsD,OAI/C,IAAM6I,EAAOhB,GAAb,CAIA,GAAKtI,IAEJ6c,EAAYD,EAAMtT,EAAOhB,GAAOgB,EAAOhB,GAAKzG,MAE3B,CAGV1E,EAAOoD,QAASP,GAsBrBA,EAAOA,EAAKvD,OAAQU,EAAO4B,IAAKiB,EAAM7C,EAAO4E,YAnBxC/B,IAAQ6c,GACZ7c,GAASA,IAITA,EAAO7C,EAAO4E,UAAW/B,GAExBA,EADIA,IAAQ6c,IACH7c,GAEFA,EAAKwD,MAAM,MAarBvE,EAAIe,EAAK9B,MACT,OAAQe,UACA4d,GAAW7c,EAAKf,GAKxB,IAAK2d,GAAOF,EAAkBG,IAAc1f,EAAOoE,cAAcsb,GAChE,QAMGD,UACEtT,GAAOhB,GAAKzG,KAIb6a,EAAmBpT,EAAOhB,QAM5ByU,EACJ5f,EAAO+f,WAAale,IAAQ,GAIjB/B,EAAQkf,eAAiB7S,GAASA,EAAMlN,aAE5CkN,GAAOhB,GAIdgB,EAAOhB,GAAO,QAIhBnL,EAAOyC,QACN0J,SAIA+S,QACCc,WAAW,EACXC,UAAU,EAEVC,UAAW,8CAGZC,QAAS,SAAUte,GAElB,MADAA,GAAOA,EAAKyC,SAAWtE,EAAOmM,MAAOtK,EAAK7B,EAAOsD,UAAazB,EAAM7B,EAAOsD,WAClEzB,IAAS0d,EAAmB1d,IAGtC6C,KAAM,SAAU7C,EAAMgB,EAAM6B,GAC3B,MAAO8a,GAAc3d,EAAMgB,EAAM6B,IAGlC0b,WAAY,SAAUve,EAAMgB,GAC3B,MAAOid,GAAoBje,EAAMgB,IAIlCwd,MAAO,SAAUxe,EAAMgB,EAAM6B,GAC5B,MAAO8a,GAAc3d,EAAMgB,EAAM6B,GAAM,IAGxC4b,YAAa,SAAUze,EAAMgB,GAC5B,MAAOid,GAAoBje,EAAMgB,GAAM,MAIzC7C,EAAOG,GAAGsC,QACTiC,KAAM,SAAUL,EAAKW,GACpB,GAAIlD,GAAGe,EAAM6B,EACZ7C,EAAO3C,KAAK,GACZ0N,EAAQ/K,GAAQA,EAAKyG,UAMtB,IAAajF,SAARgB,EAAoB,CACxB,GAAKnF,KAAK6B,SACT2D,EAAO1E,EAAO0E,KAAM7C,GAEG,IAAlBA,EAAKyC,WAAmBtE,EAAOqgB,MAAOxe,EAAM,gBAAkB,CAClEC,EAAI8K,EAAM7L,MACV,OAAQe,IACPe,EAAO+J,EAAM9K,GAAGe,KAEe,IAA1BA,EAAKrD,QAAQ,WACjBqD,EAAO7C,EAAO4E,UAAW/B,EAAKxD,MAAM,IAEpCggB,EAAUxd,EAAMgB,EAAM6B,EAAM7B,IAG9B7C,GAAOqgB,MAAOxe,EAAM,eAAe,GAIrC,MAAO6C,GAIR,MAAoB,gBAARL,GACJnF,KAAKuC,KAAK,WAChBzB,EAAO0E,KAAMxF,KAAMmF,KAIdrC,UAAUjB,OAAS,EAGzB7B,KAAKuC,KAAK,WACTzB,EAAO0E,KAAMxF,KAAMmF,EAAKW,KAKzBnD,EAAOwd,EAAUxd,EAAMwC,EAAKrE,EAAO0E,KAAM7C,EAAMwC,IAAUhB,QAG3D+c,WAAY,SAAU/b,GACrB,MAAOnF,MAAKuC,KAAK,WAChBzB,EAAOogB,WAAYlhB,KAAMmF,QAM5BrE,EAAOyC,QACN8d,MAAO,SAAU1e,EAAMkC,EAAMW,GAC5B,GAAI6b,EAEJ,OAAK1e,IACJkC,GAASA,GAAQ,MAAS,QAC1Bwc,EAAQvgB,EAAOqgB,MAAOxe,EAAMkC,GAGvBW,KACE6b,GAASvgB,EAAOoD,QAAQsB,GAC7B6b,EAAQvgB,EAAOqgB,MAAOxe,EAAMkC,EAAM/D,EAAOmF,UAAUT,IAEnD6b,EAAMhhB,KAAMmF,IAGP6b,OAZR,QAgBDC,QAAS,SAAU3e,EAAMkC,GACxBA,EAAOA,GAAQ,IAEf,IAAIwc,GAAQvgB,EAAOugB,MAAO1e,EAAMkC,GAC/B0c,EAAcF,EAAMxf,OACpBZ,EAAKogB,EAAMlU,QACXqU,EAAQ1gB,EAAO2gB,YAAa9e,EAAMkC,GAClC8U,EAAO,WACN7Y,EAAOwgB,QAAS3e,EAAMkC,GAIZ,gBAAP5D,IACJA,EAAKogB,EAAMlU,QACXoU,KAGItgB,IAIU,OAAT4D,GACJwc,EAAM1Q,QAAS,oBAIT6Q,GAAME,KACbzgB,EAAGc,KAAMY,EAAMgX,EAAM6H,KAGhBD,GAAeC,GACpBA,EAAM/M,MAAMwH,QAKdwF,YAAa,SAAU9e,EAAMkC,GAC5B,GAAIM,GAAMN,EAAO,YACjB,OAAO/D,GAAOqgB,MAAOxe,EAAMwC,IAASrE,EAAOqgB,MAAOxe,EAAMwC,GACvDsP,MAAO3T,EAAOya,UAAU,eAAehB,IAAI,WAC1CzZ,EAAOsgB,YAAaze,EAAMkC,EAAO,SACjC/D,EAAOsgB,YAAaze,EAAMwC,UAM9BrE,EAAOG,GAAGsC,QACT8d,MAAO,SAAUxc,EAAMW,GACtB,GAAImc,GAAS,CAQb,OANqB,gBAAT9c,KACXW,EAAOX,EACPA,EAAO,KACP8c,KAGI7e,UAAUjB,OAAS8f,EAChB7gB,EAAOugB,MAAOrhB,KAAK,GAAI6E,GAGfV,SAATqB,EACNxF,KACAA,KAAKuC,KAAK,WACT,GAAI8e,GAAQvgB,EAAOugB,MAAOrhB,KAAM6E,EAAMW,EAGtC1E,GAAO2gB,YAAazhB,KAAM6E,GAEZ,OAATA,GAA8B,eAAbwc,EAAM,IAC3BvgB,EAAOwgB,QAASthB,KAAM6E,MAI1Byc,QAAS,SAAUzc,GAClB,MAAO7E,MAAKuC,KAAK,WAChBzB,EAAOwgB,QAASthB,KAAM6E,MAGxB+c,WAAY,SAAU/c,GACrB,MAAO7E,MAAKqhB,MAAOxc,GAAQ,UAI5B+X,QAAS,SAAU/X,EAAMD,GACxB,GAAIoC,GACH6a,EAAQ,EACRC,EAAQhhB,EAAO0b,WACf3L,EAAW7Q,KACX4C,EAAI5C,KAAK6B,OACTwb,EAAU,aACCwE,GACTC,EAAM3D,YAAatN,GAAYA,IAIb,iBAAThM,KACXD,EAAMC,EACNA,EAAOV,QAERU,EAAOA,GAAQ,IAEf,OAAQjC,IACPoE,EAAMlG,EAAOqgB,MAAOtQ,EAAUjO,GAAKiC,EAAO,cACrCmC,GAAOA,EAAIyN,QACfoN,IACA7a,EAAIyN,MAAM8F,IAAK8C,GAIjB,OADAA,KACOyE,EAAMlF,QAAShY,KAGxB,IAAImd,GAAO,sCAAwCC,OAE/CC,GAAc,MAAO,QAAS,SAAU,QAExCC,EAAW,SAAUvf,EAAMwf,GAI7B,MADAxf,GAAOwf,GAAMxf,EAC4B,SAAlC7B,EAAOshB,IAAKzf,EAAM,aAA2B7B,EAAOmH,SAAUtF,EAAKkJ,cAAelJ,IAOvF0f,EAASvhB,EAAOuhB,OAAS,SAAUlgB,EAAOlB,EAAIkE,EAAKW,EAAOwc,EAAWC,EAAUC,GAClF,GAAI5f,GAAI,EACPf,EAASM,EAAMN,OACf4gB,EAAc,MAAPtd,CAGR,IAA4B,WAAvBrE,EAAO+D,KAAMM,GAAqB,CACtCmd,GAAY,CACZ,KAAM1f,IAAKuC,GACVrE,EAAOuhB,OAAQlgB,EAAOlB,EAAI2B,EAAGuC,EAAIvC,IAAI,EAAM2f,EAAUC,OAIhD,IAAere,SAAV2B,IACXwc,GAAY,EAENxhB,EAAOkD,WAAY8B,KACxB0c,GAAM,GAGFC,IAECD,GACJvhB,EAAGc,KAAMI,EAAO2D,GAChB7E,EAAK,OAILwhB,EAAOxhB,EACPA,EAAK,SAAU0B,EAAMwC,EAAKW,GACzB,MAAO2c,GAAK1gB,KAAMjB,EAAQ6B,GAAQmD,MAKhC7E,GACJ,KAAYY,EAAJe,EAAYA,IACnB3B,EAAIkB,EAAMS,GAAIuC,EAAKqd,EAAM1c,EAAQA,EAAM/D,KAAMI,EAAMS,GAAIA,EAAG3B,EAAIkB,EAAMS,GAAIuC,IAK3E,OAAOmd,GACNngB,EAGAsgB,EACCxhB,EAAGc,KAAMI,GACTN,EAASZ,EAAIkB,EAAM,GAAIgD,GAAQod,GAE9BG,EAAiB,yBAIrB,WACC,GAAIC,GAAW/iB,EAASgjB,yBACvBtV,EAAM1N,EAAS2N,cAAc,OAC7BqC,EAAQhQ,EAAS2N,cAAc,QAuDhC,IApDAD,EAAId,aAAc,YAAa,KAC/Bc,EAAI6B,UAAY,6CAGhBvO,EAAQiiB,kBAAgD,IAA5BvV,EAAI8B,WAAWhK,SAI3CxE,EAAQkiB,OAASxV,EAAIpB,qBAAsB,SAAUrK,OAIrDjB,EAAQmiB,gBAAkBzV,EAAIpB,qBAAsB,QAASrK,OAI7DjB,EAAQoiB,WACyD,kBAAhEpjB,EAAS2N,cAAe,OAAQ0V,WAAW,GAAOC,UAInDtT,EAAM/K,KAAO,WACb+K,EAAM0E,SAAU,EAChBqO,EAAS1T,YAAaW,GACtBhP,EAAQuiB,cAAgBvT,EAAM0E,QAI9BhH,EAAI6B,UAAY,yBAChBvO,EAAQwiB,iBAAmB9V,EAAI2V,WAAW,GAAOjQ,UAAUyF,aAG3DkK,EAAS1T,YAAa3B,GACtBA,EAAI6B,UAAY,mDAIhBvO,EAAQyiB,WAAa/V,EAAI2V,WAAW,GAAOA,WAAW,GAAOjQ,UAAUsB,QAKvE1T,EAAQ0iB,cAAe,EAClBhW,EAAIyB,cACRzB,EAAIyB,YAAa,UAAW,WAC3BnO,EAAQ0iB,cAAe,IAGxBhW,EAAI2V,WAAW,GAAOM,SAIM,MAAzB3iB,EAAQkf,cAAuB,CAElClf,EAAQkf,eAAgB,CACxB,WACQxS,GAAIjB,KACV,MAAOhH,GACRzE,EAAQkf,eAAgB,GAK1B6C,EAAWrV,EAAMsC,EAAQ,QAI1B,WACC,GAAIhN,GAAG4gB,EACNlW,EAAM1N,EAAS2N,cAAe,MAG/B,KAAM3K,KAAOyS,QAAQ,EAAMoO,QAAQ,EAAMC,SAAS,GACjDF,EAAY,KAAO5gB,GAEZhC,EAASgC,EAAI,WAAc4gB,IAAazjB,MAE9CuN,EAAId,aAAcgX,EAAW,KAC7B5iB,EAASgC,EAAI,WAAc0K,EAAIlE,WAAYoa,GAAYpf,WAAY,EAKrEkJ,GAAM,OAIP,IAAIqW,GAAa,+BAChBC,EAAY,OACZC,EAAc,+BACdC,EAAc,kCACdC,GAAiB,sBAElB,SAASC,MACR,OAAO,EAGR,QAASC,MACR,OAAO,EAGR,QAASC,MACR,IACC,MAAOtkB,GAASoU,cACf,MAAQmQ,KAOXrjB,EAAOqe,OAEN3f,UAEA+a,IAAK,SAAU5X,EAAMyhB,EAAOzW,EAASnI,EAAMzE,GAC1C,GAAIiG,GAAKqd,EAAQC,EAAGC,EACnBC,EAASC,EAAaC,EACtBC,EAAU9f,EAAM+f,EAAYC,EAC5BC,EAAWhkB,EAAOqgB,MAAOxe,EAG1B,IAAMmiB,EAAN,CAKKnX,EAAQA,UACZ4W,EAAc5W,EACdA,EAAU4W,EAAY5W,QACtB5M,EAAWwjB,EAAYxjB,UAIlB4M,EAAQ7G,OACb6G,EAAQ7G,KAAOhG,EAAOgG,SAIhBud,EAASS,EAAST,UACxBA,EAASS,EAAST,YAEZI,EAAcK,EAASC,UAC7BN,EAAcK,EAASC,OAAS,SAAU1f,GAGzC,aAAcvE,KAAW8H,GAAkBvD,GAAKvE,EAAOqe,MAAM6F,YAAc3f,EAAER,KAE5EV,OADArD,EAAOqe,MAAM8F,SAASpiB,MAAO4hB,EAAY9hB,KAAMG,YAIjD2hB,EAAY9hB,KAAOA,GAIpByhB,GAAUA,GAAS,IAAK9Y,MAAO4P,KAAiB,IAChDoJ,EAAIF,EAAMviB,MACV,OAAQyiB,IACPtd,EAAM+c,GAAejY,KAAMsY,EAAME,QACjCzf,EAAOggB,EAAW7d,EAAI,GACtB4d,GAAe5d,EAAI,IAAM,IAAKG,MAAO,KAAM9D,OAGrCwB,IAKN2f,EAAU1jB,EAAOqe,MAAMqF,QAAS3f,OAGhCA,GAAS9D,EAAWyjB,EAAQU,aAAeV,EAAQW,WAActgB,EAGjE2f,EAAU1jB,EAAOqe,MAAMqF,QAAS3f,OAGhC6f,EAAY5jB,EAAOyC,QAClBsB,KAAMA,EACNggB,SAAUA,EACVrf,KAAMA,EACNmI,QAASA,EACT7G,KAAM6G,EAAQ7G,KACd/F,SAAUA,EACVqJ,aAAcrJ,GAAYD,EAAO8P,KAAKtF,MAAMlB,aAAaiC,KAAMtL,GAC/DqkB,UAAWR,EAAWjY,KAAK,MACzB4X,IAGII,EAAWN,EAAQxf,MACzB8f,EAAWN,EAAQxf,MACnB8f,EAASU,cAAgB,EAGnBb,EAAQc,OAASd,EAAQc,MAAMvjB,KAAMY,EAAM6C,EAAMof,EAAYH,MAAkB,IAE/E9hB,EAAKmM,iBACTnM,EAAKmM,iBAAkBjK,EAAM4f,GAAa,GAE/B9hB,EAAKoM,aAChBpM,EAAKoM,YAAa,KAAOlK,EAAM4f,KAK7BD,EAAQjK,MACZiK,EAAQjK,IAAIxY,KAAMY,EAAM+hB,GAElBA,EAAU/W,QAAQ7G,OACvB4d,EAAU/W,QAAQ7G,KAAO6G,EAAQ7G,OAK9B/F,EACJ4jB,EAASrhB,OAAQqhB,EAASU,gBAAiB,EAAGX,GAE9CC,EAAStkB,KAAMqkB,GAIhB5jB,EAAOqe,MAAM3f,OAAQqF,IAAS,EAI/BlC,GAAO,OAIRyZ,OAAQ,SAAUzZ,EAAMyhB,EAAOzW,EAAS5M,EAAUwkB,GACjD,GAAIpiB,GAAGuhB,EAAW1d,EACjBwe,EAAWlB,EAAGD,EACdG,EAASG,EAAU9f,EACnB+f,EAAYC,EACZC,EAAWhkB,EAAOmgB,QAASte,IAAU7B,EAAOqgB,MAAOxe,EAEpD,IAAMmiB,IAAcT,EAASS,EAAST,QAAtC,CAKAD,GAAUA,GAAS,IAAK9Y,MAAO4P,KAAiB,IAChDoJ,EAAIF,EAAMviB,MACV,OAAQyiB,IAMP,GALAtd,EAAM+c,GAAejY,KAAMsY,EAAME,QACjCzf,EAAOggB,EAAW7d,EAAI,GACtB4d,GAAe5d,EAAI,IAAM,IAAKG,MAAO,KAAM9D,OAGrCwB,EAAN,CAOA2f,EAAU1jB,EAAOqe,MAAMqF,QAAS3f,OAChCA,GAAS9D,EAAWyjB,EAAQU,aAAeV,EAAQW,WAActgB,EACjE8f,EAAWN,EAAQxf,OACnBmC,EAAMA,EAAI,IAAM,GAAIsC,QAAQ,UAAYsb,EAAWjY,KAAK,iBAAmB,WAG3E6Y,EAAYriB,EAAIwhB,EAAS9iB,MACzB,OAAQsB,IACPuhB,EAAYC,EAAUxhB,IAEfoiB,GAAeV,IAAaH,EAAUG,UACzClX,GAAWA,EAAQ7G,OAAS4d,EAAU5d,MACtCE,IAAOA,EAAIqF,KAAMqY,EAAUU,YAC3BrkB,GAAYA,IAAa2jB,EAAU3jB,WAAyB,OAAbA,IAAqB2jB,EAAU3jB,YACjF4jB,EAASrhB,OAAQH,EAAG,GAEfuhB,EAAU3jB,UACd4jB,EAASU,gBAELb,EAAQpI,QACZoI,EAAQpI,OAAOra,KAAMY,EAAM+hB,GAOzBc,KAAcb,EAAS9iB,SACrB2iB,EAAQiB,UAAYjB,EAAQiB,SAAS1jB,KAAMY,EAAMiiB,EAAYE,EAASC,WAAa,GACxFjkB,EAAO4kB,YAAa/iB,EAAMkC,EAAMigB,EAASC,cAGnCV,GAAQxf,QAtCf,KAAMA,IAAQwf,GACbvjB,EAAOqe,MAAM/C,OAAQzZ,EAAMkC,EAAOuf,EAAOE,GAAK3W,EAAS5M,GAAU,EA0C/DD,GAAOoE,cAAemf,WACnBS,GAASC,OAIhBjkB,EAAOsgB,YAAaze,EAAM,aAI5Bkc,QAAS,SAAUM,EAAO3Z,EAAM7C,EAAMgjB,GACrC,GAAIZ,GAAQa,EAAQ9X,EACnB+X,EAAYrB,EAASxd,EAAKpE,EAC1BkjB,GAAcnjB,GAAQ/C,GACtBiF,EAAOpE,EAAOsB,KAAMod,EAAO,QAAWA,EAAMta,KAAOsa,EACnDyF,EAAankB,EAAOsB,KAAMod,EAAO,aAAgBA,EAAMiG,UAAUje,MAAM,OAKxE,IAHA2G,EAAM9G,EAAMrE,EAAOA,GAAQ/C,EAGJ,IAAlB+C,EAAKyC,UAAoC,IAAlBzC,EAAKyC,WAK5B0e,EAAYzX,KAAMxH,EAAO/D,EAAOqe,MAAM6F,aAItCngB,EAAKvE,QAAQ,MAAQ,IAEzBskB,EAAa/f,EAAKsC,MAAM,KACxBtC,EAAO+f,EAAWzX,QAClByX,EAAWvhB,QAEZuiB,EAAS/gB,EAAKvE,QAAQ,KAAO,GAAK,KAAOuE,EAGzCsa,EAAQA,EAAOre,EAAOsD,SACrB+a,EACA,GAAIre,GAAOilB,MAAOlhB,EAAuB,gBAAVsa,IAAsBA,GAGtDA,EAAM6G,UAAYL,EAAe,EAAI,EACrCxG,EAAMiG,UAAYR,EAAWjY,KAAK,KAClCwS,EAAM8G,aAAe9G,EAAMiG,UAC1B,GAAI9b,QAAQ,UAAYsb,EAAWjY,KAAK,iBAAmB,WAC3D,KAGDwS,EAAM7M,OAASnO,OACTgb,EAAMrb,SACXqb,EAAMrb,OAASnB,GAIhB6C,EAAe,MAARA,GACJ2Z,GACFre,EAAOmF,UAAWT,GAAQ2Z,IAG3BqF,EAAU1jB,EAAOqe,MAAMqF,QAAS3f,OAC1B8gB,IAAgBnB,EAAQ3F,SAAW2F,EAAQ3F,QAAQhc,MAAOF,EAAM6C,MAAW,GAAjF,CAMA,IAAMmgB,IAAiBnB,EAAQ0B,WAAaplB,EAAOiE,SAAUpC,GAAS,CAMrE,IAJAkjB,EAAarB,EAAQU,cAAgBrgB,EAC/Bif,EAAYzX,KAAMwZ,EAAahhB,KACpCiJ,EAAMA,EAAI9B,YAEH8B,EAAKA,EAAMA,EAAI9B,WACtB8Z,EAAUzlB,KAAMyN,GAChB9G,EAAM8G,CAIF9G,MAASrE,EAAKkJ,eAAiBjM,IACnCkmB,EAAUzlB,KAAM2G,EAAI4H,aAAe5H,EAAImf,cAAgBpmB,GAKzD6C,EAAI,CACJ,QAASkL,EAAMgY,EAAUljB,QAAUuc,EAAMiH,uBAExCjH,EAAMta,KAAOjC,EAAI,EAChBijB,EACArB,EAAQW,UAAYtgB,EAGrBkgB,GAAWjkB,EAAOqgB,MAAOrT,EAAK,eAAoBqR,EAAMta,OAAU/D,EAAOqgB,MAAOrT,EAAK,UAChFiX,GACJA,EAAOliB,MAAOiL,EAAKtI,GAIpBuf,EAASa,GAAU9X,EAAK8X,GACnBb,GAAUA,EAAOliB,OAAS/B,EAAOif,WAAYjS,KACjDqR,EAAM7M,OAASyS,EAAOliB,MAAOiL,EAAKtI,GAC7B2Z,EAAM7M,UAAW,GACrB6M,EAAMkH,iBAOT,IAHAlH,EAAMta,KAAOA,GAGP8gB,IAAiBxG,EAAMmH,wBAErB9B,EAAQ+B,UAAY/B,EAAQ+B,SAAS1jB,MAAOijB,EAAUhd,MAAOtD,MAAW,IAC9E1E,EAAOif,WAAYpd,IAKdijB,GAAUjjB,EAAMkC,KAAW/D,EAAOiE,SAAUpC,GAAS,CAGzDqE,EAAMrE,EAAMijB,GAEP5e,IACJrE,EAAMijB,GAAW,MAIlB9kB,EAAOqe,MAAM6F,UAAYngB,CACzB,KACClC,EAAMkC,KACL,MAAQQ,IAIVvE,EAAOqe,MAAM6F,UAAY7gB,OAEpB6C,IACJrE,EAAMijB,GAAW5e,GAMrB,MAAOmY,GAAM7M,SAGd2S,SAAU,SAAU9F,GAGnBA,EAAQre,EAAOqe,MAAMqH,IAAKrH,EAE1B,IAAIvc,GAAGR,EAAKsiB,EAAWtR,EAASjQ,EAC/BsjB,KACAhkB,EAAOtC,EAAM4B,KAAMe,WACnB6hB,GAAa7jB,EAAOqgB,MAAOnhB,KAAM,eAAoBmf,EAAMta,UAC3D2f,EAAU1jB,EAAOqe,MAAMqF,QAASrF,EAAMta,SAOvC,IAJApC,EAAK,GAAK0c,EACVA,EAAMuH,eAAiB1mB,MAGlBwkB,EAAQmC,aAAenC,EAAQmC,YAAY5kB,KAAM/B,KAAMmf,MAAY,EAAxE,CAKAsH,EAAe3lB,EAAOqe,MAAMwF,SAAS5iB,KAAM/B,KAAMmf,EAAOwF,GAGxD/hB,EAAI,CACJ,QAASwQ,EAAUqT,EAAc7jB,QAAWuc,EAAMiH,uBAAyB,CAC1EjH,EAAMyH,cAAgBxT,EAAQzQ,KAE9BQ,EAAI,CACJ,QAASuhB,EAAYtR,EAAQuR,SAAUxhB,QAAWgc,EAAM0H,kCAIjD1H,EAAM8G,cAAgB9G,EAAM8G,aAAa5Z,KAAMqY,EAAUU,cAE9DjG,EAAMuF,UAAYA,EAClBvF,EAAM3Z,KAAOkf,EAAUlf,KAEvBpD,IAAStB,EAAOqe,MAAMqF,QAASE,EAAUG,eAAkBE,QAAUL,EAAU/W,SAC5E9K,MAAOuQ,EAAQzQ,KAAMF,GAEX0B,SAAR/B,IACE+c,EAAM7M,OAASlQ,MAAS,IAC7B+c,EAAMkH,iBACNlH,EAAM2H,oBAYX,MAJKtC,GAAQuC,cACZvC,EAAQuC,aAAahlB,KAAM/B,KAAMmf,GAG3BA,EAAM7M,SAGdqS,SAAU,SAAUxF,EAAOwF,GAC1B,GAAIqC,GAAKtC,EAAW/d,EAAS/D,EAC5B6jB,KACApB,EAAgBV,EAASU,cACzBvX,EAAMqR,EAAMrb,MAKb,IAAKuhB,GAAiBvX,EAAI1I,YAAc+Z,EAAMxK,QAAyB,UAAfwK,EAAMta,MAG7D,KAAQiJ,GAAO9N,KAAM8N,EAAMA,EAAI9B,YAAchM,KAK5C,GAAsB,IAAjB8N,EAAI1I,WAAmB0I,EAAIuG,YAAa,GAAuB,UAAf8K,EAAMta,MAAoB,CAE9E,IADA8B,KACM/D,EAAI,EAAOyiB,EAAJziB,EAAmBA,IAC/B8hB,EAAYC,EAAU/hB,GAGtBokB,EAAMtC,EAAU3jB,SAAW,IAEHoD,SAAnBwC,EAASqgB,KACbrgB,EAASqgB,GAAQtC,EAAUta,aAC1BtJ,EAAQkmB,EAAKhnB,MAAOqa,MAAOvM,IAAS,EACpChN,EAAOyO,KAAMyX,EAAKhnB,KAAM,MAAQ8N,IAAQjM,QAErC8E,EAASqgB,IACbrgB,EAAQtG,KAAMqkB,EAGX/d,GAAQ9E,QACZ4kB,EAAapmB,MAAOsC,KAAMmL,EAAK6W,SAAUhe,IAW7C,MAJK0e,GAAgBV,EAAS9iB,QAC7B4kB,EAAapmB,MAAOsC,KAAM3C,KAAM2kB,SAAUA,EAASxkB,MAAOklB,KAGpDoB,GAGRD,IAAK,SAAUrH,GACd,GAAKA,EAAOre,EAAOsD,SAClB,MAAO+a,EAIR,IAAIvc,GAAGqkB,EAAMvjB,EACZmB,EAAOsa,EAAMta,KACbqiB,EAAgB/H,EAChBgI,EAAUnnB,KAAKonB,SAAUviB,EAEpBsiB,KACLnnB,KAAKonB,SAAUviB,GAASsiB,EACvBtD,EAAYxX,KAAMxH,GAAS7E,KAAKqnB,WAChCzD,EAAUvX,KAAMxH,GAAS7E,KAAKsnB,aAGhC5jB,EAAOyjB,EAAQI,MAAQvnB,KAAKunB,MAAMnnB,OAAQ+mB,EAAQI,OAAUvnB,KAAKunB,MAEjEpI,EAAQ,GAAIre,GAAOilB,MAAOmB,GAE1BtkB,EAAIc,EAAK7B,MACT,OAAQe,IACPqkB,EAAOvjB,EAAMd,GACbuc,EAAO8H,GAASC,EAAeD,EAmBhC,OAdM9H,GAAMrb,SACXqb,EAAMrb,OAASojB,EAAcM,YAAc5nB,GAKb,IAA1Buf,EAAMrb,OAAOsB,WACjB+Z,EAAMrb,OAASqb,EAAMrb,OAAOkI,YAK7BmT,EAAMsI,UAAYtI,EAAMsI,QAEjBN,EAAQ3X,OAAS2X,EAAQ3X,OAAQ2P,EAAO+H,GAAkB/H,GAIlEoI,MAAO,wHAAwHpgB,MAAM,KAErIigB,YAEAE,UACCC,MAAO,4BAA4BpgB,MAAM,KACzCqI,OAAQ,SAAU2P,EAAOuI,GAOxB,MAJoB,OAAfvI,EAAMwI,QACVxI,EAAMwI,MAA6B,MAArBD,EAASE,SAAmBF,EAASE,SAAWF,EAASG,SAGjE1I,IAITkI,YACCE,MAAO,mGAAmGpgB,MAAM,KAChHqI,OAAQ,SAAU2P,EAAOuI,GACxB,GAAI/I,GAAMmJ,EAAUpZ,EACnBiG,EAAS+S,EAAS/S,OAClBoT,EAAcL,EAASK,WAuBxB,OApBoB,OAAf5I,EAAM6I,OAAqC,MAApBN,EAASO,UACpCH,EAAW3I,EAAMrb,OAAO+H,eAAiBjM,EACzC8O,EAAMoZ,EAASvZ,gBACfoQ,EAAOmJ,EAASnJ,KAEhBQ,EAAM6I,MAAQN,EAASO,SAAYvZ,GAAOA,EAAIwZ,YAAcvJ,GAAQA,EAAKuJ,YAAc,IAAQxZ,GAAOA,EAAIyZ,YAAcxJ,GAAQA,EAAKwJ,YAAc,GACnJhJ,EAAMiJ,MAAQV,EAASW,SAAY3Z,GAAOA,EAAI4Z,WAAc3J,GAAQA,EAAK2J,WAAc,IAAQ5Z,GAAOA,EAAI6Z,WAAc5J,GAAQA,EAAK4J,WAAc,KAI9IpJ,EAAMqJ,eAAiBT,IAC5B5I,EAAMqJ,cAAgBT,IAAgB5I,EAAMrb,OAAS4jB,EAASe,UAAYV,GAKrE5I,EAAMwI,OAAoBxjB,SAAXwQ,IACpBwK,EAAMwI,MAAmB,EAAThT,EAAa,EAAe,EAATA,EAAa,EAAe,EAATA,EAAa,EAAI,GAGjEwK,IAITqF,SACCkE,MAECxC,UAAU,GAEXnS,OAEC8K,QAAS,WACR,GAAK7e,OAASkkB,MAAuBlkB,KAAK+T,MACzC,IAEC,MADA/T,MAAK+T,SACE,EACN,MAAQ1O,MAOZ6f,aAAc,WAEfyD,MACC9J,QAAS,WACR,MAAK7e,QAASkkB,MAAuBlkB,KAAK2oB,MACzC3oB,KAAK2oB,QACE,GAFR,QAKDzD,aAAc,YAEf3B,OAEC1E,QAAS,WACR,MAAK/d,GAAO8E,SAAU5F,KAAM,UAA2B,aAAdA,KAAK6E,MAAuB7E,KAAKujB,OACzEvjB,KAAKujB,SACE,GAFR,QAODgD,SAAU,SAAUpH,GACnB,MAAOre,GAAO8E,SAAUuZ,EAAMrb,OAAQ,OAIxC8kB,cACC7B,aAAc,SAAU5H,GAGDhb,SAAjBgb,EAAM7M,SACV6M,EAAM+H,cAAc2B,YAAc1J,EAAM7M,WAM5CwW,SAAU,SAAUjkB,EAAMlC,EAAMwc,EAAO4J,GAItC,GAAI1jB,GAAIvE,EAAOyC,OACd,GAAIzC,GAAOilB,MACX5G,GAECta,KAAMA,EACNmkB,aAAa,EACb9B,kBAGG6B,GACJjoB,EAAOqe,MAAMN,QAASxZ,EAAG,KAAM1C,GAE/B7B,EAAOqe,MAAM8F,SAASljB,KAAMY,EAAM0C,GAE9BA,EAAEihB,sBACNnH,EAAMkH,mBAKTvlB,EAAO4kB,YAAc9lB,EAASof,oBAC7B,SAAUrc,EAAMkC,EAAMkgB,GAChBpiB,EAAKqc,qBACTrc,EAAKqc,oBAAqBna,EAAMkgB,GAAQ,IAG1C,SAAUpiB,EAAMkC,EAAMkgB,GACrB,GAAIphB,GAAO,KAAOkB,CAEblC,GAAKuc,oBAIGvc,GAAMgB,KAAWiF,IAC5BjG,EAAMgB,GAAS,MAGhBhB,EAAKuc,YAAavb,EAAMohB,KAI3BjkB,EAAOilB,MAAQ,SAAUviB,EAAK+jB,GAE7B,MAAOvnB,gBAAgBc,GAAOilB,OAKzBviB,GAAOA,EAAIqB,MACf7E,KAAKknB,cAAgB1jB,EACrBxD,KAAK6E,KAAOrB,EAAIqB,KAIhB7E,KAAKsmB,mBAAqB9iB,EAAIylB,kBACH9kB,SAAzBX,EAAIylB,mBAEJzlB,EAAIqlB,eAAgB,GAEpBrlB,EAAI0lB,mBAAqB1lB,EAAI0lB,qBAC9BlF,GACAC,IAIDjkB,KAAK6E,KAAOrB,EAIR+jB,GACJzmB,EAAOyC,OAAQvD,KAAMunB,GAItBvnB,KAAKmpB,UAAY3lB,GAAOA,EAAI2lB,WAAaroB,EAAOmG,WAGhDjH,KAAMc,EAAOsD,UAAY,IAjCjB,GAAItD,GAAOilB,MAAOviB,EAAK+jB,IAsChCzmB,EAAOilB,MAAMrkB,WACZ4kB,mBAAoBrC,GACpBmC,qBAAsBnC,GACtB4C,8BAA+B5C,GAE/BoC,eAAgB,WACf,GAAIhhB,GAAIrF,KAAKknB,aAEblnB,MAAKsmB,mBAAqBtC,GACpB3e,IAKDA,EAAEghB,eACNhhB,EAAEghB,iBAKFhhB,EAAEwjB,aAAc,IAGlB/B,gBAAiB,WAChB,GAAIzhB,GAAIrF,KAAKknB,aAEblnB,MAAKomB,qBAAuBpC,GACtB3e,IAIDA,EAAEyhB,iBACNzhB,EAAEyhB,kBAKHzhB,EAAE+jB,cAAe,IAElBC,yBAA0B,WACzBrpB,KAAK6mB,8BAAgC7C,GACrChkB,KAAK8mB,oBAKPhmB,EAAOyB,MACN+mB,WAAY,YACZC,WAAY,YACV,SAAUC,EAAMhD,GAClB1lB,EAAOqe,MAAMqF,QAASgF,IACrBtE,aAAcsB,EACdrB,SAAUqB,EAEVzB,OAAQ,SAAU5F,GACjB,GAAI/c,GACH0B,EAAS9D,KACTypB,EAAUtK,EAAMqJ,cAChB9D,EAAYvF,EAAMuF,SASnB,SALM+E,GAAYA,IAAY3lB,IAAWhD,EAAOmH,SAAUnE,EAAQ2lB,MACjEtK,EAAMta,KAAO6f,EAAUG,SACvBziB,EAAMsiB,EAAU/W,QAAQ9K,MAAO7C,KAAM8C,WACrCqc,EAAMta,KAAO2hB,GAEPpkB,MAMJxB,EAAQ8oB,gBAEb5oB,EAAOqe,MAAMqF,QAAQnP,QACpBiQ,MAAO,WAEN,MAAKxkB,GAAO8E,SAAU5F,KAAM,SACpB,MAIRc,GAAOqe,MAAM5E,IAAKva,KAAM,iCAAkC,SAAUqF,GAEnE,GAAI1C,GAAO0C,EAAEvB,OACZ6lB,EAAO7oB,EAAO8E,SAAUjD,EAAM,UAAa7B,EAAO8E,SAAUjD,EAAM,UAAaA,EAAKgnB,KAAOxlB,MACvFwlB,KAAS7oB,EAAOqgB,MAAOwI,EAAM,mBACjC7oB,EAAOqe,MAAM5E,IAAKoP,EAAM,iBAAkB,SAAUxK,GACnDA,EAAMyK,gBAAiB,IAExB9oB,EAAOqgB,MAAOwI,EAAM,iBAAiB,OAMxC5C,aAAc,SAAU5H,GAElBA,EAAMyK,uBACHzK,GAAMyK,eACR5pB,KAAKgM,aAAemT,EAAM6G,WAC9BllB,EAAOqe,MAAM2J,SAAU,SAAU9oB,KAAKgM,WAAYmT,GAAO,KAK5DsG,SAAU,WAET,MAAK3kB,GAAO8E,SAAU5F,KAAM,SACpB,MAIRc,GAAOqe,MAAM/C,OAAQpc,KAAM,eAMxBY,EAAQipB,gBAEb/oB,EAAOqe,MAAMqF,QAAQf,QAEpB6B,MAAO,WAEN,MAAK3B,GAAWtX,KAAMrM,KAAK4F,YAIP,aAAd5F,KAAK6E,MAAqC,UAAd7E,KAAK6E,QACrC/D,EAAOqe,MAAM5E,IAAKva,KAAM,yBAA0B,SAAUmf,GACjB,YAArCA,EAAM+H,cAAc4C,eACxB9pB,KAAK+pB,eAAgB,KAGvBjpB,EAAOqe,MAAM5E,IAAKva,KAAM,gBAAiB,SAAUmf,GAC7Cnf,KAAK+pB,gBAAkB5K,EAAM6G,YACjChmB,KAAK+pB,eAAgB,GAGtBjpB,EAAOqe,MAAM2J,SAAU,SAAU9oB,KAAMmf,GAAO,OAGzC,OAGRre,GAAOqe,MAAM5E,IAAKva,KAAM,yBAA0B,SAAUqF,GAC3D,GAAI1C,GAAO0C,EAAEvB,MAER6f,GAAWtX,KAAM1J,EAAKiD,YAAe9E,EAAOqgB,MAAOxe,EAAM,mBAC7D7B,EAAOqe,MAAM5E,IAAK5X,EAAM,iBAAkB,SAAUwc,IAC9Cnf,KAAKgM,YAAemT,EAAM6J,aAAgB7J,EAAM6G,WACpDllB,EAAOqe,MAAM2J,SAAU,SAAU9oB,KAAKgM,WAAYmT,GAAO,KAG3Dre,EAAOqgB,MAAOxe,EAAM,iBAAiB,OAKxCoiB,OAAQ,SAAU5F,GACjB,GAAIxc,GAAOwc,EAAMrb,MAGjB,OAAK9D,QAAS2C,GAAQwc,EAAM6J,aAAe7J,EAAM6G,WAA4B,UAAdrjB,EAAKkC,MAAkC,aAAdlC,EAAKkC,KACrFsa,EAAMuF,UAAU/W,QAAQ9K,MAAO7C,KAAM8C,WAD7C,QAKD2iB,SAAU,WAGT,MAFA3kB,GAAOqe,MAAM/C,OAAQpc,KAAM,aAEnB2jB,EAAWtX,KAAMrM,KAAK4F,aAM3BhF,EAAQopB,gBACblpB,EAAOyB,MAAOwR,MAAO,UAAW4U,KAAM,YAAc,SAAUa,EAAMhD,GAGnE,GAAI7Y,GAAU,SAAUwR,GACtBre,EAAOqe,MAAM2J,SAAUtC,EAAKrH,EAAMrb,OAAQhD,EAAOqe,MAAMqH,IAAKrH,IAAS,GAGvEre,GAAOqe,MAAMqF,QAASgC,IACrBlB,MAAO,WACN,GAAI5W,GAAM1O,KAAK6L,eAAiB7L,KAC/BiqB,EAAWnpB,EAAOqgB,MAAOzS,EAAK8X,EAEzByD,IACLvb,EAAII,iBAAkB0a,EAAM7b,GAAS,GAEtC7M,EAAOqgB,MAAOzS,EAAK8X,GAAOyD,GAAY,GAAM,IAE7CxE,SAAU,WACT,GAAI/W,GAAM1O,KAAK6L,eAAiB7L,KAC/BiqB,EAAWnpB,EAAOqgB,MAAOzS,EAAK8X,GAAQ,CAEjCyD,GAILnpB,EAAOqgB,MAAOzS,EAAK8X,EAAKyD,IAHxBvb,EAAIsQ,oBAAqBwK,EAAM7b,GAAS,GACxC7M,EAAOsgB,YAAa1S,EAAK8X,QAS9B1lB,EAAOG,GAAGsC,QAET2mB,GAAI,SAAU9F,EAAOrjB,EAAUyE,EAAMvE,EAAiBkpB,GACrD,GAAItlB,GAAMulB,CAGV,IAAsB,gBAAVhG,GAAqB,CAEP,gBAAbrjB,KAEXyE,EAAOA,GAAQzE,EACfA,EAAWoD,OAEZ,KAAMU,IAAQuf,GACbpkB,KAAKkqB,GAAIrlB,EAAM9D,EAAUyE,EAAM4e,EAAOvf,GAAQslB,EAE/C,OAAOnqB,MAmBR,GAhBa,MAARwF,GAAsB,MAANvE,GAEpBA,EAAKF,EACLyE,EAAOzE,EAAWoD,QACD,MAANlD,IACc,gBAAbF,IAEXE,EAAKuE,EACLA,EAAOrB,SAGPlD,EAAKuE,EACLA,EAAOzE,EACPA,EAAWoD,SAGRlD,KAAO,EACXA,EAAKgjB,OACC,KAAMhjB,EACZ,MAAOjB,KAaR,OAVa,KAARmqB,IACJC,EAASnpB,EACTA,EAAK,SAAUke,GAGd,MADAre,KAASge,IAAKK,GACPiL,EAAOvnB,MAAO7C,KAAM8C,YAG5B7B,EAAG6F,KAAOsjB,EAAOtjB,OAAUsjB,EAAOtjB,KAAOhG,EAAOgG,SAE1C9G,KAAKuC,KAAM,WACjBzB,EAAOqe,MAAM5E,IAAKva,KAAMokB,EAAOnjB,EAAIuE,EAAMzE,MAG3CopB,IAAK,SAAU/F,EAAOrjB,EAAUyE,EAAMvE,GACrC,MAAOjB,MAAKkqB,GAAI9F,EAAOrjB,EAAUyE,EAAMvE,EAAI,IAE5C6d,IAAK,SAAUsF,EAAOrjB,EAAUE,GAC/B,GAAIyjB,GAAW7f,CACf,IAAKuf,GAASA,EAAMiC,gBAAkBjC,EAAMM,UAQ3C,MANAA,GAAYN,EAAMM,UAClB5jB,EAAQsjB,EAAMsC,gBAAiB5H,IAC9B4F,EAAUU,UAAYV,EAAUG,SAAW,IAAMH,EAAUU,UAAYV,EAAUG,SACjFH,EAAU3jB,SACV2jB,EAAU/W,SAEJ3N,IAER,IAAsB,gBAAVokB,GAAqB,CAEhC,IAAMvf,IAAQuf,GACbpkB,KAAK8e,IAAKja,EAAM9D,EAAUqjB,EAAOvf,GAElC,OAAO7E,MAUR,OARKe,KAAa,GAA6B,kBAAbA,MAEjCE,EAAKF,EACLA,EAAWoD,QAEPlD,KAAO,IACXA,EAAKgjB,IAECjkB,KAAKuC,KAAK,WAChBzB,EAAOqe,MAAM/C,OAAQpc,KAAMokB,EAAOnjB,EAAIF,MAIxC8d,QAAS,SAAUha,EAAMW,GACxB,MAAOxF,MAAKuC,KAAK,WAChBzB,EAAOqe,MAAMN,QAASha,EAAMW,EAAMxF,SAGpCqqB,eAAgB,SAAUxlB,EAAMW,GAC/B,GAAI7C,GAAO3C,KAAK,EAChB,OAAK2C,GACG7B,EAAOqe,MAAMN,QAASha,EAAMW,EAAM7C,GAAM,GADhD,SAOF,SAAS2nB,IAAoB1qB,GAC5B,GAAIkc,GAAOyO,GAAUpjB,MAAO,KAC3BqjB,EAAW5qB,EAASgjB,wBAErB,IAAK4H,EAASjd,cACb,MAAQuO,EAAKja,OACZ2oB,EAASjd,cACRuO,EAAKhT,MAIR,OAAO0hB,GAGR,GAAID,IAAY,6JAEfE,GAAgB,6BAChBC,GAAe,GAAIphB,QAAO,OAASihB,GAAY,WAAY,KAC3DI,GAAqB,OACrBC,GAAY,0EACZC,GAAW,YACXC,GAAS,UACTC,GAAQ,YACRC,GAAe,0BAEfC,GAAW,oCACXC,GAAc,4BACdC,GAAoB,cACpBC,GAAe,2CAGfC,IACCC,QAAU,EAAG,+BAAgC,aAC7CC,QAAU,EAAG,aAAc,eAC3BC,MAAQ,EAAG,QAAS,UACpBC,OAAS,EAAG,WAAY,aACxBC,OAAS,EAAG,UAAW,YACvBC,IAAM,EAAG,iBAAkB,oBAC3BC,KAAO,EAAG,mCAAoC,uBAC9CC,IAAM,EAAG,qBAAsB,yBAI/BtF,SAAU3lB,EAAQmiB,eAAkB,EAAG,GAAI,KAAS,EAAG,SAAU,WAElE+I,GAAexB,GAAoB1qB,GACnCmsB,GAAcD,GAAa7c,YAAarP,EAAS2N,cAAc,OAEhE8d,IAAQW,SAAWX,GAAQC,OAC3BD,GAAQvI,MAAQuI,GAAQY,MAAQZ,GAAQa,SAAWb,GAAQc,QAAUd,GAAQK,MAC7EL,GAAQe,GAAKf,GAAQQ,EAErB,SAASQ,IAAQrrB,EAAS2O,GACzB,GAAIxN,GAAOQ,EACVC,EAAI,EACJ0pB,QAAetrB,GAAQkL,uBAAyBtD,EAAe5H,EAAQkL,qBAAsByD,GAAO,WAC5F3O,GAAQ4L,mBAAqBhE,EAAe5H,EAAQ4L,iBAAkB+C,GAAO,KACpFxL,MAEF,KAAMmoB,EACL,IAAMA,KAAYnqB,EAAQnB,EAAQmK,YAAcnK,EAA8B,OAApB2B,EAAOR,EAAMS,IAAaA,KAC7E+M,GAAO7O,EAAO8E,SAAUjD,EAAMgN,GACnC2c,EAAMjsB,KAAMsC,GAEZ7B,EAAOuB,MAAOiqB,EAAOD,GAAQ1pB,EAAMgN,GAKtC,OAAexL,UAARwL,GAAqBA,GAAO7O,EAAO8E,SAAU5E,EAAS2O,GAC5D7O,EAAOuB,OAASrB,GAAWsrB,GAC3BA,EAIF,QAASC,IAAmB5pB,GACtB+f,EAAerW,KAAM1J,EAAKkC,QAC9BlC,EAAK6pB,eAAiB7pB,EAAK2R,SAM7B,QAASmY,IAAoB9pB,EAAM+pB,GAClC,MAAO5rB,GAAO8E,SAAUjD,EAAM,UAC7B7B,EAAO8E,SAA+B,KAArB8mB,EAAQtnB,SAAkBsnB,EAAUA,EAAQtd,WAAY,MAEzEzM,EAAKuJ,qBAAqB,SAAS,IAClCvJ,EAAKsM,YAAatM,EAAKkJ,cAAc0B,cAAc,UACpD5K,EAIF,QAASgqB,IAAehqB,GAEvB,MADAA,GAAKkC,MAA6C,OAArC/D,EAAOyO,KAAKuB,KAAMnO,EAAM,SAAqB,IAAMA,EAAKkC,KAC9DlC,EAER,QAASiqB,IAAejqB,GACvB,GAAI2I,GAAQ6f,GAAkBrf,KAAMnJ,EAAKkC,KAMzC,OALKyG,GACJ3I,EAAKkC,KAAOyG,EAAM,GAElB3I,EAAKmK,gBAAgB,QAEfnK,EAIR,QAASkqB,IAAe1qB,EAAO2qB,GAG9B,IAFA,GAAInqB,GACHC,EAAI,EACwB,OAApBD,EAAOR,EAAMS,IAAaA,IAClC9B,EAAOqgB,MAAOxe,EAAM,cAAemqB,GAAehsB,EAAOqgB,MAAO2L,EAAYlqB,GAAI,eAIlF,QAASmqB,IAAgBvpB,EAAKwpB,GAE7B,GAAuB,IAAlBA,EAAK5nB,UAAmBtE,EAAOmgB,QAASzd,GAA7C,CAIA,GAAIqB,GAAMjC,EAAGuX,EACZ8S,EAAUnsB,EAAOqgB,MAAO3d,GACxB0pB,EAAUpsB,EAAOqgB,MAAO6L,EAAMC,GAC9B5I,EAAS4I,EAAQ5I,MAElB,IAAKA,EAAS,OACN6I,GAAQnI,OACfmI,EAAQ7I,SAER,KAAMxf,IAAQwf,GACb,IAAMzhB,EAAI,EAAGuX,EAAIkK,EAAQxf,GAAOhD,OAAYsY,EAAJvX,EAAOA,IAC9C9B,EAAOqe,MAAM5E,IAAKyS,EAAMnoB,EAAMwf,EAAQxf,GAAQjC,IAM5CsqB,EAAQ1nB,OACZ0nB,EAAQ1nB,KAAO1E,EAAOyC,UAAY2pB,EAAQ1nB,QAI5C,QAAS2nB,IAAoB3pB,EAAKwpB,GACjC,GAAIpnB,GAAUP,EAAGG,CAGjB,IAAuB,IAAlBwnB,EAAK5nB,SAAV,CAOA,GAHAQ,EAAWonB,EAAKpnB,SAASC,eAGnBjF,EAAQ0iB,cAAgB0J,EAAMlsB,EAAOsD,SAAY,CACtDoB,EAAO1E,EAAOqgB,MAAO6L,EAErB,KAAM3nB,IAAKG,GAAK6e,OACfvjB,EAAO4kB,YAAasH,EAAM3nB,EAAGG,EAAKuf,OAInCiI,GAAKlgB,gBAAiBhM,EAAOsD,SAIZ,WAAbwB,GAAyBonB,EAAKhnB,OAASxC,EAAIwC,MAC/C2mB,GAAeK,GAAOhnB,KAAOxC,EAAIwC,KACjC4mB,GAAeI,IAIS,WAAbpnB,GACNonB,EAAKhhB,aACTghB,EAAK9J,UAAY1f,EAAI0f,WAOjBtiB,EAAQoiB,YAAgBxf,EAAI2L,YAAcrO,EAAOH,KAAKqsB,EAAK7d,aAC/D6d,EAAK7d,UAAY3L,EAAI2L,YAGE,UAAbvJ,GAAwB8c,EAAerW,KAAM7I,EAAIqB,OAK5DmoB,EAAKR,eAAiBQ,EAAK1Y,QAAU9Q,EAAI8Q,QAIpC0Y,EAAKlnB,QAAUtC,EAAIsC,QACvBknB,EAAKlnB,MAAQtC,EAAIsC,QAKM,WAAbF,EACXonB,EAAKI,gBAAkBJ,EAAKzY,SAAW/Q,EAAI4pB,iBAInB,UAAbxnB,GAAqC,aAAbA,KACnConB,EAAKvU,aAAejV,EAAIiV,eAI1B3X,EAAOyC,QACNM,MAAO,SAAUlB,EAAM0qB,EAAeC,GACrC,GAAIC,GAAc/e,EAAM3K,EAAOjB,EAAG4qB,EACjCC,EAAS3sB,EAAOmH,SAAUtF,EAAKkJ,cAAelJ,EAW/C,IATK/B,EAAQoiB,YAAcliB,EAAO6X,SAAShW,KAAU+nB,GAAare,KAAM,IAAM1J,EAAKiD,SAAW,KAC7F/B,EAAQlB,EAAKsgB,WAAW,IAIxB8I,GAAY5c,UAAYxM,EAAKugB,UAC7B6I,GAAYve,YAAa3J,EAAQkoB,GAAY3c,eAGvCxO,EAAQ0iB,cAAiB1iB,EAAQwiB,gBACnB,IAAlBzgB,EAAKyC,UAAoC,KAAlBzC,EAAKyC,UAAqBtE,EAAO6X,SAAShW,IAOnE,IAJA4qB,EAAelB,GAAQxoB,GACvB2pB,EAAcnB,GAAQ1pB,GAGhBC,EAAI,EAA8B,OAA1B4L,EAAOgf,EAAY5qB,MAAeA,EAE1C2qB,EAAa3qB,IACjBuqB,GAAoB3e,EAAM+e,EAAa3qB,GAM1C,IAAKyqB,EACJ,GAAKC,EAIJ,IAHAE,EAAcA,GAAenB,GAAQ1pB,GACrC4qB,EAAeA,GAAgBlB,GAAQxoB,GAEjCjB,EAAI,EAA8B,OAA1B4L,EAAOgf,EAAY5qB,IAAaA,IAC7CmqB,GAAgBve,EAAM+e,EAAa3qB,QAGpCmqB,IAAgBpqB,EAAMkB,EAaxB,OARA0pB,GAAelB,GAAQxoB,EAAO,UACzB0pB,EAAa1rB,OAAS,GAC1BgrB,GAAeU,GAAeE,GAAUpB,GAAQ1pB,EAAM,WAGvD4qB,EAAeC,EAAchf,EAAO,KAG7B3K,GAGR6pB,cAAe,SAAUvrB,EAAOnB,EAAS2sB,EAASC,GAWjD,IAVA,GAAIzqB,GAAGR,EAAMsF,EACZjB,EAAK2I,EAAKmT,EAAO+K,EACjB1T,EAAIhY,EAAMN,OAGVisB,EAAOxD,GAAoBtpB,GAE3B+sB,KACAnrB,EAAI,EAEOuX,EAAJvX,EAAOA,IAGd,GAFAD,EAAOR,EAAOS,GAETD,GAAiB,IAATA,EAGZ,GAA6B,WAAxB7B,EAAO+D,KAAMlC,GACjB7B,EAAOuB,MAAO0rB,EAAOprB,EAAKyC,UAAazC,GAASA,OAG1C,IAAMooB,GAAM1e,KAAM1J,GAIlB,CACNqE,EAAMA,GAAO8mB,EAAK7e,YAAajO,EAAQuM,cAAc,QAGrDoC,GAAOkb,GAAS/e,KAAMnJ,KAAY,GAAI,KAAO,GAAIkD,cACjDgoB,EAAOxC,GAAS1b,IAAS0b,GAAQ9E,SAEjCvf,EAAImI,UAAY0e,EAAK,GAAKlrB,EAAK4B,QAASqmB,GAAW,aAAgBiD,EAAK,GAGxE1qB,EAAI0qB,EAAK,EACT,OAAQ1qB,IACP6D,EAAMA,EAAIgM,SASX,KALMpS,EAAQiiB,mBAAqB8H,GAAmBte,KAAM1J,IAC3DorB,EAAM1tB,KAAMW,EAAQgtB,eAAgBrD,GAAmB7e,KAAMnJ,GAAO,MAI/D/B,EAAQkiB,MAAQ,CAGrBngB,EAAe,UAARgN,GAAoBmb,GAAOze,KAAM1J,GAI3B,YAAZkrB,EAAK,IAAqB/C,GAAOze,KAAM1J,GAEtC,EADAqE,EAJDA,EAAIoI,WAOLjM,EAAIR,GAAQA,EAAKwI,WAAWtJ,MAC5B,OAAQsB,IACFrC,EAAO8E,SAAWkd,EAAQngB,EAAKwI,WAAWhI,GAAK,WAAc2f,EAAM3X,WAAWtJ,QAClFc,EAAK6K,YAAasV,GAKrBhiB,EAAOuB,MAAO0rB,EAAO/mB,EAAImE,YAGzBnE,EAAIqK,YAAc,EAGlB,OAAQrK,EAAIoI,WACXpI,EAAIwG,YAAaxG,EAAIoI,WAItBpI,GAAM8mB,EAAK9a,cAtDX+a,GAAM1tB,KAAMW,EAAQgtB,eAAgBrrB,GA4DlCqE,IACJ8mB,EAAKtgB,YAAaxG,GAKbpG,EAAQuiB,eACbriB,EAAO0F,KAAM6lB,GAAQ0B,EAAO,SAAWxB,IAGxC3pB,EAAI,CACJ,OAASD,EAAOorB,EAAOnrB,KAItB,KAAKgrB,GAAmD,KAAtC9sB,EAAOuF,QAAS1D,EAAMirB,MAIxC3lB,EAAWnH,EAAOmH,SAAUtF,EAAKkJ,cAAelJ,GAGhDqE,EAAMqlB,GAAQyB,EAAK7e,YAAatM,GAAQ,UAGnCsF,GACJ4kB,GAAe7lB,GAIX2mB,GAAU,CACdxqB,EAAI,CACJ,OAASR,EAAOqE,EAAK7D,KACf+nB,GAAY7e,KAAM1J,EAAKkC,MAAQ,KACnC8oB,EAAQttB,KAAMsC,GAQlB,MAFAqE,GAAM,KAEC8mB,GAGRjN,UAAW,SAAU1e,EAAsB4d,GAQ1C,IAPA,GAAIpd,GAAMkC,EAAMoH,EAAIzG,EACnB5C,EAAI,EACJ6d,EAAc3f,EAAOsD,QACrB6I,EAAQnM,EAAOmM,MACf6S,EAAgBlf,EAAQkf,cACxB0E,EAAU1jB,EAAOqe,MAAMqF,QAEK,OAApB7hB,EAAOR,EAAMS,IAAaA,IAClC,IAAKmd,GAAcjf,EAAOif,WAAYpd,MAErCsJ,EAAKtJ,EAAM8d,GACXjb,EAAOyG,GAAMgB,EAAOhB,IAER,CACX,GAAKzG,EAAK6e,OACT,IAAMxf,IAAQW,GAAK6e,OACbG,EAAS3f,GACb/D,EAAOqe,MAAM/C,OAAQzZ,EAAMkC,GAI3B/D,EAAO4kB,YAAa/iB,EAAMkC,EAAMW,EAAKuf,OAMnC9X,GAAOhB,WAEJgB,GAAOhB,GAKT6T,QACGnd,GAAM8d,SAEK9d,GAAKmK,kBAAoBlE,EAC3CjG,EAAKmK,gBAAiB2T,GAGtB9d,EAAM8d,GAAgB,KAGvBvgB,EAAWG,KAAM4L,QAQvBnL,EAAOG,GAAGsC,QACTyC,KAAM,SAAUF,GACf,MAAOuc,GAAQriB,KAAM,SAAU8F,GAC9B,MAAiB3B,UAAV2B,EACNhF,EAAOkF,KAAMhG,MACbA,KAAKyU,QAAQwZ,QAAUjuB,KAAK,IAAMA,KAAK,GAAG6L,eAAiBjM,GAAWouB,eAAgBloB,KACrF,KAAMA,EAAOhD,UAAUjB,SAG3BosB,OAAQ,WACP,MAAOjuB,MAAKkuB,SAAUprB,UAAW,SAAUH,GAC1C,GAAuB,IAAlB3C,KAAKoF,UAAoC,KAAlBpF,KAAKoF,UAAqC,IAAlBpF,KAAKoF,SAAiB,CACzE,GAAItB,GAAS2oB,GAAoBzsB,KAAM2C,EACvCmB,GAAOmL,YAAatM,OAKvBwrB,QAAS,WACR,MAAOnuB,MAAKkuB,SAAUprB,UAAW,SAAUH,GAC1C,GAAuB,IAAlB3C,KAAKoF,UAAoC,KAAlBpF,KAAKoF,UAAqC,IAAlBpF,KAAKoF,SAAiB,CACzE,GAAItB,GAAS2oB,GAAoBzsB,KAAM2C,EACvCmB,GAAOsqB,aAAczrB,EAAMmB,EAAOsL,gBAKrCif,OAAQ,WACP,MAAOruB,MAAKkuB,SAAUprB,UAAW,SAAUH,GACrC3C,KAAKgM,YACThM,KAAKgM,WAAWoiB,aAAczrB,EAAM3C,SAKvCsuB,MAAO,WACN,MAAOtuB,MAAKkuB,SAAUprB,UAAW,SAAUH,GACrC3C,KAAKgM,YACThM,KAAKgM,WAAWoiB,aAAczrB,EAAM3C,KAAKiO,gBAK5CmO,OAAQ,SAAUrb,EAAUwtB,GAK3B,IAJA,GAAI5rB,GACHR,EAAQpB,EAAWD,EAAO0O,OAAQzO,EAAUf,MAASA,KACrD4C,EAAI,EAEwB,OAApBD,EAAOR,EAAMS,IAAaA,IAE5B2rB,GAA8B,IAAlB5rB,EAAKyC,UACtBtE,EAAO+f,UAAWwL,GAAQ1pB,IAGtBA,EAAKqJ,aACJuiB,GAAYztB,EAAOmH,SAAUtF,EAAKkJ,cAAelJ,IACrDkqB,GAAeR,GAAQ1pB,EAAM,WAE9BA,EAAKqJ,WAAWwB,YAAa7K,GAI/B,OAAO3C,OAGRyU,MAAO,WAIN,IAHA,GAAI9R,GACHC,EAAI,EAEuB,OAAnBD,EAAO3C,KAAK4C,IAAaA,IAAM,CAEhB,IAAlBD,EAAKyC,UACTtE,EAAO+f,UAAWwL,GAAQ1pB,GAAM,GAIjC,OAAQA,EAAKyM,WACZzM,EAAK6K,YAAa7K,EAAKyM,WAKnBzM,GAAKiB,SAAW9C,EAAO8E,SAAUjD,EAAM,YAC3CA,EAAKiB,QAAQ/B,OAAS,GAIxB,MAAO7B,OAGR6D,MAAO,SAAUwpB,EAAeC,GAI/B,MAHAD,GAAiC,MAAjBA,GAAwB,EAAQA,EAChDC,EAAyC,MAArBA,EAA4BD,EAAgBC,EAEzDttB,KAAK0C,IAAI,WACf,MAAO5B,GAAO+C,MAAO7D,KAAMqtB,EAAeC,MAI5CkB,KAAM,SAAU1oB,GACf,MAAOuc,GAAQriB,KAAM,SAAU8F,GAC9B,GAAInD,GAAO3C,KAAM,OAChB4C,EAAI,EACJuX,EAAIna,KAAK6B,MAEV,IAAesC,SAAV2B,EACJ,MAAyB,KAAlBnD,EAAKyC,SACXzC,EAAKwM,UAAU5K,QAASkmB,GAAe,IACvCtmB,MAIF,MAAsB,gBAAV2B,IAAuBklB,GAAa3e,KAAMvG,KACnDlF,EAAQmiB,eAAkB2H,GAAare,KAAMvG,KAC7ClF,EAAQiiB,mBAAsB8H,GAAmBte,KAAMvG,IACxDulB,IAAUR,GAAS/e,KAAMhG,KAAa,GAAI,KAAO,GAAID,gBAAkB,CAExEC,EAAQA,EAAMvB,QAASqmB,GAAW,YAElC,KACC,KAAWzQ,EAAJvX,EAAOA,IAEbD,EAAO3C,KAAK4C,OACW,IAAlBD,EAAKyC,WACTtE,EAAO+f,UAAWwL,GAAQ1pB,GAAM,IAChCA,EAAKwM,UAAYrJ,EAInBnD,GAAO,EAGN,MAAM0C,KAGJ1C,GACJ3C,KAAKyU,QAAQwZ,OAAQnoB,IAEpB,KAAMA,EAAOhD,UAAUjB,SAG3B4sB,YAAa,WACZ,GAAI5nB,GAAM/D,UAAW,EAcrB,OAXA9C,MAAKkuB,SAAUprB,UAAW,SAAUH,GACnCkE,EAAM7G,KAAKgM,WAEXlL,EAAO+f,UAAWwL,GAAQrsB,OAErB6G,GACJA,EAAI6nB,aAAc/rB,EAAM3C,QAKnB6G,IAAQA,EAAIhF,QAAUgF,EAAIzB,UAAYpF,KAAOA,KAAKoc,UAG1D2C,OAAQ,SAAUhe,GACjB,MAAOf,MAAKoc,OAAQrb,GAAU,IAG/BmtB,SAAU,SAAUzrB,EAAMD,GAGzBC,EAAOrC,EAAOyC,SAAWJ,EAEzB,IAAIM,GAAOyL,EAAMmgB,EAChBhB,EAASjf,EAAKiU,EACd/f,EAAI,EACJuX,EAAIna,KAAK6B,OACT+sB,EAAM5uB,KACN6uB,EAAW1U,EAAI,EACfrU,EAAQrD,EAAK,GACbuB,EAAalD,EAAOkD,WAAY8B,EAGjC,IAAK9B,GACDmW,EAAI,GAAsB,gBAAVrU,KAChBlF,EAAQyiB,YAAc4H,GAAS5e,KAAMvG,GACxC,MAAO9F,MAAKuC,KAAK,SAAU8X,GAC1B,GAAIpB,GAAO2V,EAAI5rB,GAAIqX,EACdrW,KACJvB,EAAK,GAAKqD,EAAM/D,KAAM/B,KAAMqa,EAAOpB,EAAKuV,SAEzCvV,EAAKiV,SAAUzrB,EAAMD,IAIvB,IAAK2X,IACJwI,EAAW7hB,EAAO4sB,cAAejrB,EAAMzC,KAAM,GAAI6L,eAAe,EAAO7L,MACvE+C,EAAQ4f,EAASvT,WAEmB,IAA/BuT,EAASxX,WAAWtJ,SACxB8gB,EAAW5f,GAGPA,GAAQ,CAMZ,IALA4qB,EAAU7sB,EAAO4B,IAAK2pB,GAAQ1J,EAAU,UAAYgK,IACpDgC,EAAahB,EAAQ9rB,OAITsY,EAAJvX,EAAOA,IACd4L,EAAOmU,EAEF/f,IAAMisB,IACVrgB,EAAO1N,EAAO+C,MAAO2K,GAAM,GAAM,GAG5BmgB,GACJ7tB,EAAOuB,MAAOsrB,EAAStB,GAAQ7d,EAAM,YAIvChM,EAAST,KAAM/B,KAAK4C,GAAI4L,EAAM5L,EAG/B,IAAK+rB,EAOJ,IANAjgB,EAAMif,EAASA,EAAQ9rB,OAAS,GAAIgK,cAGpC/K,EAAO4B,IAAKirB,EAASf,IAGfhqB,EAAI,EAAO+rB,EAAJ/rB,EAAgBA,IAC5B4L,EAAOmf,EAAS/qB,GACXsoB,GAAY7e,KAAMmC,EAAK3J,MAAQ,MAClC/D,EAAOqgB,MAAO3S,EAAM,eAAkB1N,EAAOmH,SAAUyG,EAAKF,KAExDA,EAAKhL,IAEJ1C,EAAOguB,UACXhuB,EAAOguB,SAAUtgB,EAAKhL,KAGvB1C,EAAOyE,YAAciJ,EAAKxI,MAAQwI,EAAK6C,aAAe7C,EAAKW,WAAa,IAAK5K,QAAS6mB,GAAc,KAOxGzI,GAAW5f,EAAQ,KAIrB,MAAO/C,SAITc,EAAOyB,MACNwsB,SAAU,SACVC,UAAW,UACXZ,aAAc,SACda,YAAa,QACbC,WAAY,eACV,SAAUvrB,EAAM+jB,GAClB5mB,EAAOG,GAAI0C,GAAS,SAAU5C,GAO7B,IANA,GAAIoB,GACHS,EAAI,EACJR,KACA+sB,EAASruB,EAAQC,GACjBkC,EAAOksB,EAAOttB,OAAS,EAEXoB,GAALL,EAAWA,IAClBT,EAAQS,IAAMK,EAAOjD,KAAOA,KAAK6D,OAAM,GACvC/C,EAAQquB,EAAOvsB,IAAM8kB,GAAYvlB,GAGjC9B,EAAKwC,MAAOT,EAAKD,EAAMH,MAGxB,OAAOhC,MAAKkC,UAAWE,KAKzB,IAAIgtB,IACHC,KAQD,SAASC,IAAe3rB,EAAM+K,GAC7B,GAAI/L,GAAO7B,EAAQ4N,EAAInB,cAAe5J,IAASorB,SAAUrgB,EAAIiQ,MAG5D4Q,EAAUxvB,EAAOyvB,wBAIhBzvB,EAAOyvB,wBAAyB7sB,EAAM,IAAM4sB,QAAUzuB,EAAOshB,IAAKzf,EAAM,GAAK,UAM/E,OAFAA,GAAKoc,SAEEwQ,EAOR,QAASE,IAAgB7pB,GACxB,GAAI8I,GAAM9O,EACT2vB,EAAUF,GAAazpB,EA0BxB,OAxBM2pB,KACLA,EAAUD,GAAe1pB,EAAU8I,GAGlB,SAAZ6gB,GAAuBA,IAG3BH,IAAUA,IAAUtuB,EAAQ,mDAAoDiuB,SAAUrgB,EAAIH,iBAG9FG,GAAQ0gB,GAAQ,GAAIpU,eAAiBoU,GAAQ,GAAIrU,iBAAkBnb,SAGnE8O,EAAIghB,QACJhhB,EAAIihB,QAEJJ,EAAUD,GAAe1pB,EAAU8I,GACnC0gB,GAAOrQ,UAIRsQ,GAAazpB,GAAa2pB,GAGpBA,GAIR,WACC,GAAI7mB,GAAGknB,EACNtiB,EAAM1N,EAAS2N,cAAe,OAC9BsiB,EACC,6HAIFviB,GAAI6B,UAAY,qEAChBzG,EAAI4E,EAAIpB,qBAAsB,KAAO,GAErCxD,EAAEgX,MAAMC,QAAU,wBAKlB/e,EAAQkvB,QAAU,OAAOzjB,KAAM3D,EAAEgX,MAAMoQ,SAIvClvB,EAAQmvB,WAAarnB,EAAEgX,MAAMqQ,SAE7BziB,EAAIoS,MAAMsQ,eAAiB,cAC3B1iB,EAAI2V,WAAW,GAAOvD,MAAMsQ,eAAiB,GAC7CpvB,EAAQqvB,gBAA+C,gBAA7B3iB,EAAIoS,MAAMsQ,eAGpCtnB,EAAI4E,EAAM,KAEV1M,EAAQsvB,iBAAmB,WAC1B,GAAIvR,GAAMc,EAAWnS,EAAK6iB,CAE1B,IAA4B,MAAvBP,EAA8B,CAElC,GADAjR,EAAO/e,EAASsM,qBAAsB,QAAU,IAC1CyS,EAEL,MAGDwR,GAAkB,iEAClB1Q,EAAY7f,EAAS2N,cAAe,OACpCD,EAAM1N,EAAS2N,cAAe,OAE9BoR,EAAK1P,YAAawQ,GAAYxQ,YAAa3B,GAG3CsiB,GAAsB,QAEVtiB,GAAIoS,MAAME,OAAShX,IAG9B0E,EAAIoS,MAAMC,QAAUkQ,EAAW,gCAC/BviB,EAAI6B,UAAY,cAChB7B,EAAI8B,WAAWsQ,MAAM0Q,MAAQ,MAC7BR,EAA0C,IAApBtiB,EAAIuS,aAG3BlB,EAAKnR,YAAaiS,GAGlBd,EAAOc,EAAYnS,EAAM,KAG1B,MAAOsiB,MAIT,IAAIS,IAAU,UAEVC,GAAY,GAAIhnB,QAAQ,KAAOyY,EAAO,kBAAmB,KAIzDwO,GAAWC,GACdC,GAAY,2BAER1wB,GAAO2wB,kBACXH,GAAY,SAAU5tB,GACrB,MAAOA,GAAKkJ,cAAc+C,YAAY8hB,iBAAkB/tB,EAAM,OAG/D6tB,GAAS,SAAU7tB,EAAMgB,EAAMgtB,GAC9B,GAAIP,GAAOQ,EAAUC,EAAUzuB,EAC9Bsd,EAAQ/c,EAAK+c,KAqCd,OAnCAiR,GAAWA,GAAYJ,GAAW5tB,GAGlCP,EAAMuuB,EAAWA,EAASG,iBAAkBntB,IAAUgtB,EAAUhtB,GAASQ,OAEpEwsB,IAES,KAARvuB,GAAetB,EAAOmH,SAAUtF,EAAKkJ,cAAelJ,KACxDP,EAAMtB,EAAO4e,MAAO/c,EAAMgB,IAOtB2sB,GAAUjkB,KAAMjK,IAASiuB,GAAQhkB,KAAM1I,KAG3CysB,EAAQ1Q,EAAM0Q,MACdQ,EAAWlR,EAAMkR,SACjBC,EAAWnR,EAAMmR,SAGjBnR,EAAMkR,SAAWlR,EAAMmR,SAAWnR,EAAM0Q,MAAQhuB,EAChDA,EAAMuuB,EAASP,MAGf1Q,EAAM0Q,MAAQA,EACd1Q,EAAMkR,SAAWA,EACjBlR,EAAMmR,SAAWA,IAMJ1sB,SAAR/B,EACNA,EACAA,EAAM,KAEGxC,EAAS2O,gBAAgBwiB,eACpCR,GAAY,SAAU5tB,GACrB,MAAOA,GAAKouB,cAGbP,GAAS,SAAU7tB,EAAMgB,EAAMgtB,GAC9B,GAAIK,GAAMC,EAAIC,EAAQ9uB,EACrBsd,EAAQ/c,EAAK+c,KAyCd,OAvCAiR,GAAWA,GAAYJ,GAAW5tB,GAClCP,EAAMuuB,EAAWA,EAAUhtB,GAASQ,OAIxB,MAAP/B,GAAesd,GAASA,EAAO/b,KACnCvB,EAAMsd,EAAO/b,IAUT2sB,GAAUjkB,KAAMjK,KAAUquB,GAAUpkB,KAAM1I,KAG9CqtB,EAAOtR,EAAMsR,KACbC,EAAKtuB,EAAKwuB,aACVD,EAASD,GAAMA,EAAGD,KAGbE,IACJD,EAAGD,KAAOruB,EAAKouB,aAAaC,MAE7BtR,EAAMsR,KAAgB,aAATrtB,EAAsB,MAAQvB,EAC3CA,EAAMsd,EAAM0R,UAAY,KAGxB1R,EAAMsR,KAAOA,EACRE,IACJD,EAAGD,KAAOE,IAMG/sB,SAAR/B,EACNA,EACAA,EAAM,IAAM,QAOf,SAASivB,IAAcC,EAAaC,GAEnC,OACCvvB,IAAK,WACJ,GAAIwvB,GAAYF,GAEhB,IAAkB,MAAbE,EAML,MAAKA,cAIGxxB,MAAKgC,KAMLhC,KAAKgC,IAAMuvB,GAAQ1uB,MAAO7C,KAAM8C,cAM3C,WACC,GAAI4F,GAAG+oB,EAA0BC,EAAcC,EAC9CC,EAAkBC,EAClBvkB,EAAM1N,EAAS2N,cAAe,OAC9B4iB,EAAkB,iEAClBN,EACC,6HAIFviB,GAAI6B,UAAY,qEAChBzG,EAAI4E,EAAIpB,qBAAsB,KAAO,GAErCxD,EAAEgX,MAAMC,QAAU,wBAKlB/e,EAAQkvB,QAAU,OAAOzjB,KAAM3D,EAAEgX,MAAMoQ,SAIvClvB,EAAQmvB,WAAarnB,EAAEgX,MAAMqQ,SAE7BziB,EAAIoS,MAAMsQ,eAAiB,cAC3B1iB,EAAI2V,WAAW,GAAOvD,MAAMsQ,eAAiB,GAC7CpvB,EAAQqvB,gBAA+C,gBAA7B3iB,EAAIoS,MAAMsQ,eAGpCtnB,EAAI4E,EAAM,KAEVxM,EAAOyC,OAAO3C,GACbkxB,sBAAuB,WACtB,GAAiC,MAA5BL,EACJ,MAAOA,EAGR,IAAIhS,GAAWsS,EAAKC,EACnB1kB,EAAM1N,EAAS2N,cAAe,OAC9BoR,EAAO/e,EAASsM,qBAAsB,QAAU,EAEjD,IAAMyS,EAsCN,MAhCArR,GAAId,aAAc,YAAa,KAC/Bc,EAAI6B,UAAY,qEAEhBsQ,EAAY7f,EAAS2N,cAAe,OACpCkS,EAAUC,MAAMC,QAAUwQ,EAE1BxR,EAAK1P,YAAawQ,GAAYxQ,YAAa3B,GAS3CA,EAAI6B,UAAY,8CAChB4iB,EAAMzkB,EAAIpB,qBAAsB,MAChC6lB,EAAK,GAAIrS,MAAMC,QAAU,2CACzBqS,EAA0C,IAA1BD,EAAK,GAAIE,aAEzBF,EAAK,GAAIrS,MAAM6P,QAAU,GACzBwC,EAAK,GAAIrS,MAAM6P,QAAU,OAIzBkC,EAA2BO,GAA2C,IAA1BD,EAAK,GAAIE,aAErDtT,EAAKnR,YAAaiS,GAGlBnS,EAAMqR,EAAO,KAEN8S,GAGRS,UAAW,WAIV,MAHqB,OAAhBR,GACJS,IAEMT,GAGRU,kBAAmB,WAIlB,MAH6B,OAAxBT,GACJQ,IAEMR,GAGRU,cAAe,WAId,MAHyB,OAApBT,GACJO,IAEMP,GAGRU,oBAAqB,WACpB,GAAI3T,GAAMc,EAAWnS,EAAKilB,CAG1B,IAA+B,MAA1BV,GAAkC9xB,EAAO2wB,iBAAmB,CAEhE,GADA/R,EAAO/e,EAASsM,qBAAsB,QAAU,IAC1CyS,EAEL,MAGDc,GAAY7f,EAAS2N,cAAe,OACpCD,EAAM1N,EAAS2N,cAAe,OAC9BkS,EAAUC,MAAMC,QAAUwQ,EAE1BxR,EAAK1P,YAAawQ,GAAYxQ,YAAa3B,GAM3CilB,EAAYjlB,EAAI2B,YAAarP,EAAS2N,cAAe,QACrDglB,EAAU7S,MAAMC,QAAUrS,EAAIoS,MAAMC,QAAUkQ,EAC9C0C,EAAU7S,MAAM8S,YAAcD,EAAU7S,MAAM0Q,MAAQ,IACtD9iB,EAAIoS,MAAM0Q,MAAQ,MAElByB,GACE5sB,YAAclF,EAAO2wB,iBAAkB6B,EAAW,WAAeC,aAEnE7T,EAAKnR,YAAaiS,GAGnB,MAAOoS,KAIT,SAASM,KACR,GAAI1S,GAAWnS,EACdqR,EAAO/e,EAASsM,qBAAsB,QAAU,EAE3CyS,KAKNc,EAAY7f,EAAS2N,cAAe,OACpCD,EAAM1N,EAAS2N,cAAe,OAC9BkS,EAAUC,MAAMC,QAAUwQ,EAE1BxR,EAAK1P,YAAawQ,GAAYxQ,YAAa3B,GAE3CA,EAAIoS,MAAMC,QACT,uKAMD7e,EAAO2xB,KAAM9T,EAAyB,MAAnBA,EAAKe,MAAME,MAAiBA,KAAM,MAAU,WAC9D8R,EAAmC,IAApBpkB,EAAIuS,cAIpB8R,GAAuB,EACvBC,GAAmB,EACnBC,GAAyB,EAGpB9xB,EAAO2wB,mBACXkB,EAA0E,QAArD7xB,EAAO2wB,iBAAkBpjB,EAAK,WAAeuB,IAClE8iB,EACwE,SAArE5xB,EAAO2wB,iBAAkBpjB,EAAK,QAAY8iB,MAAO,QAAUA,OAG/DzR,EAAKnR,YAAaiS,GAGlBnS,EAAMqR,EAAO,UAOf7d,EAAO2xB,KAAO,SAAU9vB,EAAMiB,EAASpB,EAAUC,GAChD,GAAIL,GAAKuB,EACR8H,IAGD,KAAM9H,IAAQC,GACb6H,EAAK9H,GAAShB,EAAK+c,MAAO/b,GAC1BhB,EAAK+c,MAAO/b,GAASC,EAASD,EAG/BvB,GAAMI,EAASK,MAAOF,EAAMF,MAG5B,KAAMkB,IAAQC,GACbjB,EAAK+c,MAAO/b,GAAS8H,EAAK9H,EAG3B,OAAOvB,GAIR,IACEswB,IAAS,kBACVC,GAAW,wBAIXC,GAAe,4BACfC,GAAY,GAAIvpB,QAAQ,KAAOyY,EAAO,SAAU,KAChD+Q,GAAU,GAAIxpB,QAAQ,YAAcyY,EAAO,IAAK,KAEhDgR,IAAYC,SAAU,WAAYC,WAAY,SAAU1D,QAAS,SACjE2D,IACCC,cAAe,EACfC,WAAY,KAGbC,IAAgB,SAAU,IAAK,MAAO,KAIvC,SAASC,IAAgB5T,EAAO/b,GAG/B,GAAKA,IAAQ+b,GACZ,MAAO/b,EAIR,IAAI4vB,GAAU5vB,EAAKyV,OAAO,GAAG3X,cAAgBkC,EAAKxD,MAAM,GACvDqzB,EAAW7vB,EACXf,EAAIywB,GAAYxxB,MAEjB,OAAQe,IAEP,GADAe,EAAO0vB,GAAazwB,GAAM2wB,EACrB5vB,IAAQ+b,GACZ,MAAO/b,EAIT,OAAO6vB,GAGR,QAASC,IAAU5iB,EAAU6iB,GAM5B,IALA,GAAInE,GAAS5sB,EAAMgxB,EAClB3V,KACA3D,EAAQ,EACRxY,EAASgP,EAAShP,OAEHA,EAARwY,EAAgBA,IACvB1X,EAAOkO,EAAUwJ,GACX1X,EAAK+c,QAIX1B,EAAQ3D,GAAUvZ,EAAOqgB,MAAOxe,EAAM,cACtC4sB,EAAU5sB,EAAK+c,MAAM6P,QAChBmE,GAGE1V,EAAQ3D,IAAuB,SAAZkV,IACxB5sB,EAAK+c,MAAM6P,QAAU,IAMM,KAAvB5sB,EAAK+c,MAAM6P,SAAkBrN,EAAUvf,KAC3Cqb,EAAQ3D,GAAUvZ,EAAOqgB,MAAOxe,EAAM,aAAc8sB,GAAe9sB,EAAKiD,aAInEoY,EAAQ3D,KACbsZ,EAASzR,EAAUvf,IAEd4sB,GAAuB,SAAZA,IAAuBoE,IACtC7yB,EAAOqgB,MAAOxe,EAAM,aAAcgxB,EAASpE,EAAUzuB,EAAOshB,IAAKzf,EAAM,aAQ3E,KAAM0X,EAAQ,EAAWxY,EAARwY,EAAgBA,IAChC1X,EAAOkO,EAAUwJ,GACX1X,EAAK+c,QAGLgU,GAA+B,SAAvB/wB,EAAK+c,MAAM6P,SAA6C,KAAvB5sB,EAAK+c,MAAM6P,UACzD5sB,EAAK+c,MAAM6P,QAAUmE,EAAO1V,EAAQ3D,IAAW,GAAK,QAItD,OAAOxJ,GAGR,QAAS+iB,IAAmBjxB,EAAMmD,EAAO+tB,GACxC,GAAIltB,GAAUksB,GAAU/mB,KAAMhG,EAC9B,OAAOa,GAENtC,KAAKiC,IAAK,EAAGK,EAAS,IAAQktB,GAAY,KAAUltB,EAAS,IAAO,MACpEb,EAGF,QAASguB,IAAsBnxB,EAAMgB,EAAMowB,EAAOC,EAAaC,GAS9D,IARA,GAAIrxB,GAAImxB,KAAYC,EAAc,SAAW,WAE5C,EAES,UAATrwB,EAAmB,EAAI,EAEvBoN,EAAM,EAEK,EAAJnO,EAAOA,GAAK,EAEJ,WAAVmxB,IACJhjB,GAAOjQ,EAAOshB,IAAKzf,EAAMoxB,EAAQ9R,EAAWrf,IAAK,EAAMqxB,IAGnDD,GAEW,YAAVD,IACJhjB,GAAOjQ,EAAOshB,IAAKzf,EAAM,UAAYsf,EAAWrf,IAAK,EAAMqxB,IAI7C,WAAVF,IACJhjB,GAAOjQ,EAAOshB,IAAKzf,EAAM,SAAWsf,EAAWrf,GAAM,SAAS,EAAMqxB,MAIrEljB,GAAOjQ,EAAOshB,IAAKzf,EAAM,UAAYsf,EAAWrf,IAAK,EAAMqxB,GAG5C,YAAVF,IACJhjB,GAAOjQ,EAAOshB,IAAKzf,EAAM,SAAWsf,EAAWrf,GAAM,SAAS,EAAMqxB,IAKvE,OAAOljB,GAGR,QAASmjB,IAAkBvxB,EAAMgB,EAAMowB,GAGtC,GAAII,IAAmB,EACtBpjB,EAAe,UAATpN,EAAmBhB,EAAKkd,YAAcld,EAAKsvB,aACjDgC,EAAS1D,GAAW5tB,GACpBqxB,EAAcpzB,EAAQsxB,aAAkE,eAAnDpxB,EAAOshB,IAAKzf,EAAM,aAAa,EAAOsxB,EAK5E,IAAY,GAAPljB,GAAmB,MAAPA,EAAc,CAQ9B,GANAA,EAAMyf,GAAQ7tB,EAAMgB,EAAMswB,IACf,EAANljB,GAAkB,MAAPA,KACfA,EAAMpO,EAAK+c,MAAO/b,IAId2sB,GAAUjkB,KAAK0E,GACnB,MAAOA,EAKRojB,GAAmBH,IAAiBpzB,EAAQwxB,qBAAuBrhB,IAAQpO,EAAK+c,MAAO/b,IAGvFoN,EAAM9L,WAAY8L,IAAS,EAI5B,MAASA,GACR+iB,GACCnxB,EACAgB,EACAowB,IAAWC,EAAc,SAAW,WACpCG,EACAF,GAEE,KAGLnzB,EAAOyC,QAGN6wB,UACCtE,SACC9tB,IAAK,SAAUW,EAAMguB,GACpB,GAAKA,EAAW,CAEf,GAAIvuB,GAAMouB,GAAQ7tB,EAAM,UACxB,OAAe,KAARP,EAAa,IAAMA,MAO9BiyB,WACCC,aAAe,EACfC,aAAe,EACfnB,YAAc,EACdoB,YAAc,EACd1E,SAAW,EACX2E,OAAS,EACTC,SAAW,EACXC,QAAU,EACVC,QAAU,EACVhV,MAAQ,GAKTiV,UAECC,QAASl0B,EAAQmvB,SAAW,WAAa,cAI1CrQ,MAAO,SAAU/c,EAAMgB,EAAMmC,EAAOiuB,GAEnC,GAAMpxB,GAA0B,IAAlBA,EAAKyC,UAAoC,IAAlBzC,EAAKyC,UAAmBzC,EAAK+c,MAAlE,CAKA,GAAItd,GAAKyC,EAAM2c,EACdgS,EAAW1yB,EAAO4E,UAAW/B,GAC7B+b,EAAQ/c,EAAK+c,KASd,IAPA/b,EAAO7C,EAAO+zB,SAAUrB,KAAgB1yB,EAAO+zB,SAAUrB,GAAaF,GAAgB5T,EAAO8T,IAI7FhS,EAAQ1gB,EAAOszB,SAAUzwB,IAAU7C,EAAOszB,SAAUZ,GAGrCrvB,SAAV2B,EAyCJ,MAAK0b,IAAS,OAASA,IAAqDrd,UAA3C/B,EAAMof,EAAMxf,IAAKW,GAAM,EAAOoxB,IACvD3xB,EAIDsd,EAAO/b,EAnCd,IAVAkB,QAAciB,GAGA,WAATjB,IAAsBzC,EAAM0wB,GAAQhnB,KAAMhG,MAC9CA,GAAU1D,EAAI,GAAK,GAAMA,EAAI,GAAK6C,WAAYnE,EAAOshB,IAAKzf,EAAMgB,IAEhEkB,EAAO,UAIM,MAATiB,GAAiBA,IAAUA,IAKlB,WAATjB,GAAsB/D,EAAOuzB,UAAWb,KAC5C1tB,GAAS,MAKJlF,EAAQqvB,iBAA6B,KAAVnqB,GAA+C,IAA/BnC,EAAKrD,QAAQ,gBAC7Dof,EAAO/b,GAAS,aAIX6d,GAAW,OAASA,IAAwDrd,UAA7C2B,EAAQ0b,EAAMoN,IAAKjsB,EAAMmD,EAAOiuB,MAIpE,IAGCrU,EAAO/b,GAAS,GAChB+b,EAAO/b,GAASmC,EACf,MAAMT,OAcX+c,IAAK,SAAUzf,EAAMgB,EAAMowB,EAAOE,GACjC,GAAIhyB,GAAK8O,EAAKyQ,EACbgS,EAAW1yB,EAAO4E,UAAW/B,EAyB9B,OAtBAA,GAAO7C,EAAO+zB,SAAUrB,KAAgB1yB,EAAO+zB,SAAUrB,GAAaF,GAAgB3wB,EAAK+c,MAAO8T,IAIlGhS,EAAQ1gB,EAAOszB,SAAUzwB,IAAU7C,EAAOszB,SAAUZ,GAG/ChS,GAAS,OAASA,KACtBzQ,EAAMyQ,EAAMxf,IAAKW,GAAM,EAAMoxB,IAIjB5vB,SAAR4M,IACJA,EAAMyf,GAAQ7tB,EAAMgB,EAAMswB,IAId,WAARljB,GAAoBpN,IAAQuvB,MAChCniB,EAAMmiB,GAAoBvvB,IAIZ,KAAVowB,GAAgBA,GACpB9xB,EAAMgD,WAAY8L,GACXgjB,KAAU,GAAQjzB,EAAOkE,UAAW/C,GAAQA,GAAO,EAAI8O,GAExDA,KAITjQ,EAAOyB,MAAO,SAAU,SAAW,SAAUK,EAAGe,GAC/C7C,EAAOszB,SAAUzwB,IAChB3B,IAAK,SAAUW,EAAMguB,EAAUoD,GAC9B,MAAKpD,GAGwB,IAArBhuB,EAAKkd,aAAqB+S,GAAavmB,KAAMvL,EAAOshB,IAAKzf,EAAM,YACrE7B,EAAO2xB,KAAM9vB,EAAMowB,GAAS,WAC3B,MAAOmB,IAAkBvxB,EAAMgB,EAAMowB,KAEtCG,GAAkBvxB,EAAMgB,EAAMowB,GAPhC,QAWDnF,IAAK,SAAUjsB,EAAMmD,EAAOiuB,GAC3B,GAAIE,GAASF,GAASxD,GAAW5tB,EACjC,OAAOixB,IAAmBjxB,EAAMmD,EAAOiuB,EACtCD,GACCnxB,EACAgB,EACAowB,EACAnzB,EAAQsxB,aAAkE,eAAnDpxB,EAAOshB,IAAKzf,EAAM,aAAa,EAAOsxB,GAC7DA,GACG,OAMFrzB,EAAQkvB,UACbhvB,EAAOszB,SAAStE,SACf9tB,IAAK,SAAUW,EAAMguB,GAEpB,MAAOgC,IAAStmB,MAAOskB,GAAYhuB,EAAKouB,aAAepuB,EAAKouB,aAAavhB,OAAS7M,EAAK+c,MAAMlQ,SAAW,IACrG,IAAOvK,WAAYqE,OAAOyrB,IAAS,GACrCpE,EAAW,IAAM,IAGnB/B,IAAK,SAAUjsB,EAAMmD,GACpB,GAAI4Z,GAAQ/c,EAAK+c,MAChBqR,EAAepuB,EAAKouB,aACpBjB,EAAUhvB,EAAOkE,UAAWc,GAAU,iBAA2B,IAARA,EAAc,IAAM,GAC7E0J,EAASuhB,GAAgBA,EAAavhB,QAAUkQ,EAAMlQ,QAAU,EAIjEkQ,GAAME,KAAO,GAIN9Z,GAAS,GAAe,KAAVA,IAC6B,KAAhDhF,EAAOH,KAAM6O,EAAOjL,QAASmuB,GAAQ,MACrChT,EAAM5S,kBAKP4S,EAAM5S,gBAAiB,UAGR,KAAVhH,GAAgBirB,IAAiBA,EAAavhB,UAMpDkQ,EAAMlQ,OAASkjB,GAAOrmB,KAAMmD,GAC3BA,EAAOjL,QAASmuB,GAAQ5C,GACxBtgB,EAAS,IAAMsgB,MAKnBhvB,EAAOszB,SAAS5B,YAAcnB,GAAczwB,EAAQ0xB,oBACnD,SAAU3vB,EAAMguB,GACf,MAAKA,GAGG7vB,EAAO2xB,KAAM9vB,GAAQ4sB,QAAW,gBACtCiB,IAAU7tB,EAAM,gBAJlB,SAUF7B,EAAOyB,MACNyyB,OAAQ,GACRC,QAAS,GACTC,OAAQ,SACN,SAAUC,EAAQC,GACpBt0B,EAAOszB,SAAUe,EAASC,IACzBC,OAAQ,SAAUvvB,GAOjB,IANA,GAAIlD,GAAI,EACP0yB,KAGAC,EAAyB,gBAAVzvB,GAAqBA,EAAMqB,MAAM,MAASrB,GAE9C,EAAJlD,EAAOA,IACd0yB,EAAUH,EAASlT,EAAWrf,GAAMwyB,GACnCG,EAAO3yB,IAAO2yB,EAAO3yB,EAAI,IAAO2yB,EAAO,EAGzC,OAAOD,KAIHjF,GAAQhkB,KAAM8oB,KACnBr0B,EAAOszB,SAAUe,EAASC,GAASxG,IAAMgF,MAI3C9yB,EAAOG,GAAGsC,QACT6e,IAAK,SAAUze,EAAMmC,GACpB,MAAOuc,GAAQriB,KAAM,SAAU2C,EAAMgB,EAAMmC,GAC1C,GAAImuB,GAAQ/wB,EACXR,KACAE,EAAI,CAEL,IAAK9B,EAAOoD,QAASP,GAAS,CAI7B,IAHAswB,EAAS1D,GAAW5tB,GACpBO,EAAMS,EAAK9B,OAECqB,EAAJN,EAASA,IAChBF,EAAKiB,EAAMf,IAAQ9B,EAAOshB,IAAKzf,EAAMgB,EAAMf,IAAK,EAAOqxB,EAGxD,OAAOvxB,GAGR,MAAiByB,UAAV2B,EACNhF,EAAO4e,MAAO/c,EAAMgB,EAAMmC,GAC1BhF,EAAOshB,IAAKzf,EAAMgB;EACjBA,EAAMmC,EAAOhD,UAAUjB,OAAS,IAEpC6xB,KAAM,WACL,MAAOD,IAAUzzB,MAAM,IAExBw1B,KAAM,WACL,MAAO/B,IAAUzzB,OAElBy1B,OAAQ,SAAU9Y,GACjB,MAAsB,iBAAVA,GACJA,EAAQ3c,KAAK0zB,OAAS1zB,KAAKw1B,OAG5Bx1B,KAAKuC,KAAK,WACX2f,EAAUliB,MACdc,EAAQd,MAAO0zB,OAEf5yB,EAAQd,MAAOw1B,WAOnB,SAASE,IAAO/yB,EAAMiB,EAASqjB,EAAM7jB,EAAKuyB,GACzC,MAAO,IAAID,IAAMh0B,UAAUR,KAAMyB,EAAMiB,EAASqjB,EAAM7jB,EAAKuyB,GAE5D70B,EAAO40B,MAAQA,GAEfA,GAAMh0B,WACLE,YAAa8zB,GACbx0B,KAAM,SAAUyB,EAAMiB,EAASqjB,EAAM7jB,EAAKuyB,EAAQC,GACjD51B,KAAK2C,KAAOA,EACZ3C,KAAKinB,KAAOA,EACZjnB,KAAK21B,OAASA,GAAU,QACxB31B,KAAK4D,QAAUA,EACf5D,KAAK8S,MAAQ9S,KAAKiH,IAAMjH,KAAK8N,MAC7B9N,KAAKoD,IAAMA,EACXpD,KAAK41B,KAAOA,IAAU90B,EAAOuzB,UAAWpN,GAAS,GAAK,OAEvDnZ,IAAK,WACJ,GAAI0T,GAAQkU,GAAMG,UAAW71B,KAAKinB,KAElC,OAAOzF,IAASA,EAAMxf,IACrBwf,EAAMxf,IAAKhC,MACX01B,GAAMG,UAAUtP,SAASvkB,IAAKhC,OAEhC81B,IAAK,SAAUC,GACd,GAAIC,GACHxU,EAAQkU,GAAMG,UAAW71B,KAAKinB,KAoB/B,OAjBCjnB,MAAKoa,IAAM4b,EADPh2B,KAAK4D,QAAQqyB,SACEn1B,EAAO60B,OAAQ31B,KAAK21B,QACtCI,EAAS/1B,KAAK4D,QAAQqyB,SAAWF,EAAS,EAAG,EAAG/1B,KAAK4D,QAAQqyB,UAG3CF,EAEpB/1B,KAAKiH,KAAQjH,KAAKoD,IAAMpD,KAAK8S,OAAUkjB,EAAQh2B,KAAK8S,MAE/C9S,KAAK4D,QAAQsyB,MACjBl2B,KAAK4D,QAAQsyB,KAAKn0B,KAAM/B,KAAK2C,KAAM3C,KAAKiH,IAAKjH,MAGzCwhB,GAASA,EAAMoN,IACnBpN,EAAMoN,IAAK5uB,MAEX01B,GAAMG,UAAUtP,SAASqI,IAAK5uB,MAExBA,OAIT01B,GAAMh0B,UAAUR,KAAKQ,UAAYg0B,GAAMh0B,UAEvCg0B,GAAMG,WACLtP,UACCvkB,IAAK,SAAUm0B,GACd,GAAI7jB,EAEJ,OAAiC,OAA5B6jB,EAAMxzB,KAAMwzB,EAAMlP,OACpBkP,EAAMxzB,KAAK+c,OAA2C,MAAlCyW,EAAMxzB,KAAK+c,MAAOyW,EAAMlP,OAQ/C3U,EAASxR,EAAOshB,IAAK+T,EAAMxzB,KAAMwzB,EAAMlP,KAAM,IAErC3U,GAAqB,SAAXA,EAAwBA,EAAJ,GAT9B6jB,EAAMxzB,KAAMwzB,EAAMlP,OAW3B2H,IAAK,SAAUuH,GAGTr1B,EAAOs1B,GAAGF,KAAMC,EAAMlP,MAC1BnmB,EAAOs1B,GAAGF,KAAMC,EAAMlP,MAAQkP,GACnBA,EAAMxzB,KAAK+c,QAAgE,MAArDyW,EAAMxzB,KAAK+c,MAAO5e,EAAO+zB,SAAUsB,EAAMlP,QAAoBnmB,EAAOszB,SAAU+B,EAAMlP,OACrHnmB,EAAO4e,MAAOyW,EAAMxzB,KAAMwzB,EAAMlP,KAAMkP,EAAMlvB,IAAMkvB,EAAMP,MAExDO,EAAMxzB,KAAMwzB,EAAMlP,MAASkP,EAAMlvB,OASrCyuB,GAAMG,UAAUvN,UAAYoN,GAAMG,UAAU3N,YAC3C0G,IAAK,SAAUuH,GACTA,EAAMxzB,KAAKyC,UAAY+wB,EAAMxzB,KAAKqJ,aACtCmqB,EAAMxzB,KAAMwzB,EAAMlP,MAASkP,EAAMlvB,OAKpCnG,EAAO60B,QACNU,OAAQ,SAAUC,GACjB,MAAOA,IAERC,MAAO,SAAUD,GAChB,MAAO,GAAMjyB,KAAKmyB,IAAKF,EAAIjyB,KAAKoyB,IAAO,IAIzC31B,EAAOs1B,GAAKV,GAAMh0B,UAAUR,KAG5BJ,EAAOs1B,GAAGF,OAKV,IACCQ,IAAOC,GACPC,GAAW,yBACXC,GAAS,GAAIvtB,QAAQ,iBAAmByY,EAAO,cAAe,KAC9D+U,GAAO,cACPC,IAAwBC,IACxBC,IACCC,KAAO,SAAUjQ,EAAMnhB,GACtB,GAAIqwB,GAAQn2B,KAAKm3B,YAAalQ,EAAMnhB,GACnChC,EAASqyB,EAAMroB,MACfynB,EAAQsB,GAAO/qB,KAAMhG,GACrB8vB,EAAOL,GAASA,EAAO,KAASz0B,EAAOuzB,UAAWpN,GAAS,GAAK,MAGhEnU,GAAUhS,EAAOuzB,UAAWpN,IAAmB,OAAT2O,IAAkB9xB,IACvD+yB,GAAO/qB,KAAMhL,EAAOshB,IAAK+T,EAAMxzB,KAAMskB,IACtCmQ,EAAQ,EACRC,EAAgB,EAEjB,IAAKvkB,GAASA,EAAO,KAAQ8iB,EAAO,CAEnCA,EAAOA,GAAQ9iB,EAAO,GAGtByiB,EAAQA,MAGRziB,GAAShP,GAAU,CAEnB,GAGCszB,GAAQA,GAAS,KAGjBtkB,GAAgBskB,EAChBt2B,EAAO4e,MAAOyW,EAAMxzB,KAAMskB,EAAMnU,EAAQ8iB,SAI/BwB,KAAWA,EAAQjB,EAAMroB,MAAQhK,IAAqB,IAAVszB,KAAiBC,GAaxE,MATK9B,KACJziB,EAAQqjB,EAAMrjB,OAASA,IAAUhP,GAAU,EAC3CqyB,EAAMP,KAAOA,EAEbO,EAAM/yB,IAAMmyB,EAAO,GAClBziB,GAAUyiB,EAAO,GAAM,GAAMA,EAAO,IACnCA,EAAO,IAGHY,IAKV,SAASmB,MAIR,MAHA1Y,YAAW,WACV8X,GAAQvyB,SAEAuyB,GAAQ51B,EAAOmG,MAIzB,QAASswB,IAAO1yB,EAAM2yB,GACrB,GAAI7P,GACHja,GAAU+pB,OAAQ5yB,GAClBjC,EAAI,CAKL,KADA40B,EAAeA,EAAe,EAAI,EACtB,EAAJ50B,EAAQA,GAAK,EAAI40B,EACxB7P,EAAQ1F,EAAWrf,GACnB8K,EAAO,SAAWia,GAAUja,EAAO,UAAYia,GAAU9iB,CAO1D,OAJK2yB,KACJ9pB,EAAMoiB,QAAUpiB,EAAM0iB,MAAQvrB,GAGxB6I,EAGR,QAASypB,IAAarxB,EAAOmhB,EAAMyQ,GAKlC,IAJA,GAAIvB,GACHwB,GAAeV,GAAUhQ,QAAe7mB,OAAQ62B,GAAU,MAC1D5c,EAAQ,EACRxY,EAAS81B,EAAW91B,OACLA,EAARwY,EAAgBA,IACvB,GAAM8b,EAAQwB,EAAYtd,GAAQtY,KAAM21B,EAAWzQ,EAAMnhB,GAGxD,MAAOqwB,GAKV,QAASa,IAAkBr0B,EAAM4kB,EAAOqQ,GAEvC,GAAI3Q,GAAMnhB,EAAO2vB,EAAQU,EAAO3U,EAAOqW,EAAStI,EAASuI,EACxDC,EAAO/3B,KACPwpB,KACA9J,EAAQ/c,EAAK+c,MACbiU,EAAShxB,EAAKyC,UAAY8c,EAAUvf,GACpCq1B,EAAWl3B,EAAOqgB,MAAOxe,EAAM,SAG1Bi1B,GAAKvW,QACVG,EAAQ1gB,EAAO2gB,YAAa9e,EAAM,MACX,MAAlB6e,EAAMyW,WACVzW,EAAMyW,SAAW,EACjBJ,EAAUrW,EAAM/M,MAAMwH,KACtBuF,EAAM/M,MAAMwH,KAAO,WACZuF,EAAMyW,UACXJ,MAIHrW,EAAMyW,WAENF,EAAKlb,OAAO,WAGXkb,EAAKlb,OAAO,WACX2E,EAAMyW,WACAn3B,EAAOugB,MAAO1e,EAAM,MAAOd,QAChC2f,EAAM/M,MAAMwH,YAOO,IAAlBtZ,EAAKyC,WAAoB,UAAYmiB,IAAS,SAAWA,MAK7DqQ,EAAKM,UAAaxY,EAAMwY,SAAUxY,EAAMyY,UAAWzY,EAAM0Y,WAIzD7I,EAAUzuB,EAAOshB,IAAKzf,EAAM,WAC5Bm1B,EAAWrI,GAAgB9sB,EAAKiD,UACf,SAAZ2pB,IACJA,EAAUuI,GAEM,WAAZvI,GAC6B,SAAhCzuB,EAAOshB,IAAKzf,EAAM,WAIb/B,EAAQ4e,wBAAuC,WAAbsY,EAGvCpY,EAAME,KAAO,EAFbF,EAAM6P,QAAU,iBAOdqI,EAAKM,WACTxY,EAAMwY,SAAW,SACXt3B,EAAQsvB,oBACb6H,EAAKlb,OAAO,WACX6C,EAAMwY,SAAWN,EAAKM,SAAU,GAChCxY,EAAMyY,UAAYP,EAAKM,SAAU,GACjCxY,EAAM0Y,UAAYR,EAAKM,SAAU,KAMpC,KAAMjR,IAAQM,GAEb,GADAzhB,EAAQyhB,EAAON,GACV2P,GAAS9qB,KAAMhG,GAAU,CAG7B,SAFOyhB,GAAON,GACdwO,EAASA,GAAoB,WAAV3vB,EACdA,KAAY6tB,EAAS,OAAS,QAAW,CAG7C,GAAe,SAAV7tB,IAAoBkyB,GAAiC7zB,SAArB6zB,EAAU/Q,GAG9C,QAFA0M,IAAS,EAKXnK,EAAMvC,GAAS+Q,GAAYA,EAAU/Q,IAAUnmB,EAAO4e,MAAO/c,EAAMskB,GAIrE,IAAMnmB,EAAOoE,cAAeskB,GAAS,CAC/BwO,EACC,UAAYA,KAChBrE,EAASqE,EAASrE,QAGnBqE,EAAWl3B,EAAOqgB,MAAOxe,EAAM,aAI3B8yB,IACJuC,EAASrE,QAAUA,GAEfA,EACJ7yB,EAAQ6B,GAAO+wB,OAEfqE,EAAK3vB,KAAK,WACTtH,EAAQ6B,GAAO6yB,SAGjBuC,EAAK3vB,KAAK,WACT,GAAI6e,EACJnmB,GAAOsgB,YAAaze,EAAM,SAC1B,KAAMskB,IAAQuC,GACb1oB,EAAO4e,MAAO/c,EAAMskB,EAAMuC,EAAMvC,KAGlC,KAAMA,IAAQuC,GACb2M,EAAQgB,GAAaxD,EAASqE,EAAU/Q,GAAS,EAAGA,EAAM8Q,GAElD9Q,IAAQ+Q,KACfA,EAAU/Q,GAASkP,EAAMrjB,MACpB6gB,IACJwC,EAAM/yB,IAAM+yB,EAAMrjB,MAClBqjB,EAAMrjB,MAAiB,UAATmU,GAA6B,WAATA,EAAoB,EAAI,KAO/D,QAASoR,IAAY9Q,EAAO+Q,GAC3B,GAAIje,GAAO1W,EAAMgyB,EAAQ7vB,EAAO0b,CAGhC,KAAMnH,IAASkN,GAed,GAdA5jB,EAAO7C,EAAO4E,UAAW2U,GACzBsb,EAAS2C,EAAe30B,GACxBmC,EAAQyhB,EAAOlN,GACVvZ,EAAOoD,QAAS4B,KACpB6vB,EAAS7vB,EAAO,GAChBA,EAAQyhB,EAAOlN,GAAUvU,EAAO,IAG5BuU,IAAU1W,IACd4jB,EAAO5jB,GAASmC,QACTyhB,GAAOlN,IAGfmH,EAAQ1gB,EAAOszB,SAAUzwB,GACpB6d,GAAS,UAAYA,GAAQ,CACjC1b,EAAQ0b,EAAM6T,OAAQvvB,SACfyhB,GAAO5jB,EAId,KAAM0W,IAASvU,GACNuU,IAASkN,KAChBA,EAAOlN,GAAUvU,EAAOuU,GACxBie,EAAeje,GAAUsb,OAI3B2C,GAAe30B,GAASgyB,EAK3B,QAAS4C,IAAW51B,EAAM61B,EAAY50B,GACrC,GAAI0O,GACHmmB,EACApe,EAAQ,EACRxY,EAASk1B,GAAoBl1B,OAC7Bib,EAAWhc,EAAO0b,WAAWK,OAAQ,iBAE7B6b,GAAK/1B,OAEb+1B,EAAO,WACN,GAAKD,EACJ,OAAO,CAUR,KARA,GAAIE,GAAcjC,IAASY,KAC1BxZ,EAAYzZ,KAAKiC,IAAK,EAAGoxB,EAAUkB,UAAYlB,EAAUzB,SAAW0C,GAEpE9hB,EAAOiH,EAAY4Z,EAAUzB,UAAY,EACzCF,EAAU,EAAIlf,EACdwD,EAAQ,EACRxY,EAAS61B,EAAUmB,OAAOh3B,OAEXA,EAARwY,EAAiBA,IACxBqd,EAAUmB,OAAQxe,GAAQyb,IAAKC,EAKhC,OAFAjZ,GAASoB,WAAYvb,GAAQ+0B,EAAW3B,EAASjY,IAElC,EAAViY,GAAel0B,EACZic,GAEPhB,EAASqB,YAAaxb,GAAQ+0B,KACvB,IAGTA,EAAY5a,EAASF,SACpBja,KAAMA,EACN4kB,MAAOzmB,EAAOyC,UAAYi1B,GAC1BZ,KAAM92B,EAAOyC,QAAQ,GAAQ+0B,kBAAqB10B,GAClDk1B,mBAAoBN,EACpBO,gBAAiBn1B,EACjBg1B,UAAWlC,IAASY,KACpBrB,SAAUryB,EAAQqyB,SAClB4C,UACA1B,YAAa,SAAUlQ,EAAM7jB,GAC5B,GAAI+yB,GAAQr1B,EAAO40B,MAAO/yB,EAAM+0B,EAAUE,KAAM3Q,EAAM7jB,EACpDs0B,EAAUE,KAAKU,cAAerR,IAAUyQ,EAAUE,KAAKjC,OAEzD,OADA+B,GAAUmB,OAAOx4B,KAAM81B,GAChBA,GAERzU,KAAM,SAAUsX,GACf,GAAI3e,GAAQ,EAGXxY,EAASm3B,EAAUtB,EAAUmB,OAAOh3B,OAAS,CAC9C,IAAK42B,EACJ,MAAOz4B,KAGR,KADAy4B,GAAU,EACM52B,EAARwY,EAAiBA,IACxBqd,EAAUmB,OAAQxe,GAAQyb,IAAK,EAUhC,OALKkD,GACJlc,EAASqB,YAAaxb,GAAQ+0B,EAAWsB,IAEzClc,EAASmc,WAAYt2B,GAAQ+0B,EAAWsB,IAElCh5B,QAGTunB,EAAQmQ,EAAUnQ,KAInB,KAFA8Q,GAAY9Q,EAAOmQ,EAAUE,KAAKU,eAElBz2B,EAARwY,EAAiBA,IAExB,GADA/H,EAASykB,GAAqB1c,GAAQtY,KAAM21B,EAAW/0B,EAAM4kB,EAAOmQ,EAAUE,MAE7E,MAAOtlB,EAmBT,OAfAxR,GAAO4B,IAAK6kB,EAAO4P,GAAaO,GAE3B52B,EAAOkD,WAAY0zB,EAAUE,KAAK9kB,QACtC4kB,EAAUE,KAAK9kB,MAAM/Q,KAAMY,EAAM+0B,GAGlC52B,EAAOs1B,GAAG8C,MACTp4B,EAAOyC,OAAQm1B,GACd/1B,KAAMA,EACNo1B,KAAML,EACNrW,MAAOqW,EAAUE,KAAKvW,SAKjBqW,EAAUna,SAAUma,EAAUE,KAAKra,UACxCnV,KAAMsvB,EAAUE,KAAKxvB,KAAMsvB,EAAUE,KAAKuB,UAC1Cpc,KAAM2a,EAAUE,KAAK7a,MACrBF,OAAQ6a,EAAUE,KAAK/a,QAG1B/b,EAAOy3B,UAAYz3B,EAAOyC,OAAQg1B,IACjCa,QAAS,SAAU7R,EAAO/kB,GACpB1B,EAAOkD,WAAYujB,IACvB/kB,EAAW+kB,EACXA,GAAU,MAEVA,EAAQA,EAAMpgB,MAAM,IAOrB,KAJA,GAAI8f,GACH5M,EAAQ,EACRxY,EAAS0lB,EAAM1lB,OAEAA,EAARwY,EAAiBA,IACxB4M,EAAOM,EAAOlN,GACd4c,GAAUhQ,GAASgQ,GAAUhQ,OAC7BgQ,GAAUhQ,GAAOtW,QAASnO,IAI5B62B,UAAW,SAAU72B,EAAU2rB,GACzBA,EACJ4I,GAAoBpmB,QAASnO,GAE7Bu0B,GAAoB12B,KAAMmC,MAK7B1B,EAAOw4B,MAAQ,SAAUA,EAAO3D,EAAQ10B,GACvC,GAAIs4B,GAAMD,GAA0B,gBAAVA,GAAqBx4B,EAAOyC,UAAY+1B,IACjEH,SAAUl4B,IAAOA,GAAM00B,GACtB70B,EAAOkD,WAAYs1B,IAAWA,EAC/BrD,SAAUqD,EACV3D,OAAQ10B,GAAM00B,GAAUA,IAAW70B,EAAOkD,WAAY2xB,IAAYA,EAwBnE,OArBA4D,GAAItD,SAAWn1B,EAAOs1B,GAAGtX,IAAM,EAA4B,gBAAjBya,GAAItD,SAAwBsD,EAAItD,SACzEsD,EAAItD,WAAYn1B,GAAOs1B,GAAGoD,OAAS14B,EAAOs1B,GAAGoD,OAAQD,EAAItD,UAAan1B,EAAOs1B,GAAGoD,OAAOjT,UAGtE,MAAbgT,EAAIlY,OAAiBkY,EAAIlY,SAAU,KACvCkY,EAAIlY,MAAQ,MAIbkY,EAAI9tB,IAAM8tB,EAAIJ,SAEdI,EAAIJ,SAAW,WACTr4B,EAAOkD,WAAYu1B,EAAI9tB,MAC3B8tB,EAAI9tB,IAAI1J,KAAM/B,MAGVu5B,EAAIlY,OACRvgB,EAAOwgB,QAASthB,KAAMu5B,EAAIlY,QAIrBkY,GAGRz4B,EAAOG,GAAGsC,QACTk2B,OAAQ,SAAUH,EAAOI,EAAI/D,EAAQnzB,GAGpC,MAAOxC,MAAKwP,OAAQ0S,GAAWE,IAAK,UAAW,GAAIsR,OAGjDtwB,MAAMu2B,SAAU7J,QAAS4J,GAAMJ,EAAO3D,EAAQnzB,IAEjDm3B,QAAS,SAAU1S,EAAMqS,EAAO3D,EAAQnzB,GACvC,GAAIiS,GAAQ3T,EAAOoE,cAAe+hB,GACjC2S,EAAS94B,EAAOw4B,MAAOA,EAAO3D,EAAQnzB,GACtCq3B,EAAc,WAEb,GAAI9B,GAAOQ,GAAWv4B,KAAMc,EAAOyC,UAAY0jB,GAAQ2S,IAGlDnlB,GAAS3T,EAAOqgB,MAAOnhB,KAAM,YACjC+3B,EAAKrW,MAAM,GAKd,OAFCmY,GAAYC,OAASD,EAEfplB,GAASmlB,EAAOvY,SAAU,EAChCrhB,KAAKuC,KAAMs3B,GACX75B,KAAKqhB,MAAOuY,EAAOvY,MAAOwY,IAE5BnY,KAAM,SAAU7c,EAAM+c,EAAYoX,GACjC,GAAIe,GAAY,SAAUvY,GACzB,GAAIE,GAAOF,EAAME,WACVF,GAAME,KACbA,EAAMsX,GAYP,OATqB,gBAATn0B,KACXm0B,EAAUpX,EACVA,EAAa/c,EACbA,EAAOV,QAEHyd,GAAc/c,KAAS,GAC3B7E,KAAKqhB,MAAOxc,GAAQ,SAGd7E,KAAKuC,KAAK,WAChB,GAAI+e,IAAU,EACbjH,EAAgB,MAARxV,GAAgBA,EAAO,aAC/Bm1B,EAASl5B,EAAOk5B,OAChBx0B,EAAO1E,EAAOqgB,MAAOnhB,KAEtB,IAAKqa,EACC7U,EAAM6U,IAAW7U,EAAM6U,GAAQqH,MACnCqY,EAAWv0B,EAAM6U,QAGlB,KAAMA,IAAS7U,GACTA,EAAM6U,IAAW7U,EAAM6U,GAAQqH,MAAQoV,GAAKzqB,KAAMgO,IACtD0f,EAAWv0B,EAAM6U,GAKpB,KAAMA,EAAQ2f,EAAOn4B,OAAQwY,KACvB2f,EAAQ3f,GAAQ1X,OAAS3C,MAAiB,MAAR6E,GAAgBm1B,EAAQ3f,GAAQgH,QAAUxc,IAChFm1B,EAAQ3f,GAAQ0d,KAAKrW,KAAMsX,GAC3B1X,GAAU,EACV0Y,EAAO12B,OAAQ+W,EAAO,KAOnBiH,IAAY0X,IAChBl4B,EAAOwgB,QAASthB,KAAM6E,MAIzBi1B,OAAQ,SAAUj1B,GAIjB,MAHKA,MAAS,IACbA,EAAOA,GAAQ,MAET7E,KAAKuC,KAAK,WAChB,GAAI8X,GACH7U,EAAO1E,EAAOqgB,MAAOnhB,MACrBqhB,EAAQ7b,EAAMX,EAAO,SACrB2c,EAAQhc,EAAMX,EAAO,cACrBm1B,EAASl5B,EAAOk5B,OAChBn4B,EAASwf,EAAQA,EAAMxf,OAAS,CAajC,KAVA2D,EAAKs0B,QAAS,EAGdh5B,EAAOugB,MAAOrhB,KAAM6E,MAEf2c,GAASA,EAAME,MACnBF,EAAME,KAAK3f,KAAM/B,MAAM,GAIlBqa,EAAQ2f,EAAOn4B,OAAQwY,KACvB2f,EAAQ3f,GAAQ1X,OAAS3C,MAAQg6B,EAAQ3f,GAAQgH,QAAUxc,IAC/Dm1B,EAAQ3f,GAAQ0d,KAAKrW,MAAM,GAC3BsY,EAAO12B,OAAQ+W,EAAO,GAKxB,KAAMA,EAAQ,EAAWxY,EAARwY,EAAgBA,IAC3BgH,EAAOhH,IAAWgH,EAAOhH,GAAQyf,QACrCzY,EAAOhH,GAAQyf,OAAO/3B,KAAM/B,YAKvBwF,GAAKs0B,YAKfh5B,EAAOyB,MAAO,SAAU,OAAQ,QAAU,SAAUK,EAAGe,GACtD,GAAIs2B,GAAQn5B,EAAOG,GAAI0C,EACvB7C,GAAOG,GAAI0C,GAAS,SAAU21B,EAAO3D,EAAQnzB,GAC5C,MAAgB,OAAT82B,GAAkC,iBAAVA,GAC9BW,EAAMp3B,MAAO7C,KAAM8C,WACnB9C,KAAK25B,QAASpC,GAAO5zB,GAAM,GAAQ21B,EAAO3D,EAAQnzB,MAKrD1B,EAAOyB,MACN23B,UAAW3C,GAAM,QACjB4C,QAAS5C,GAAM,QACf6C,YAAa7C,GAAM,UACnB8C,QAAUvK,QAAS,QACnBwK,SAAWxK,QAAS,QACpByK,YAAczK,QAAS,WACrB,SAAUnsB,EAAM4jB,GAClBzmB,EAAOG,GAAI0C,GAAS,SAAU21B,EAAO3D,EAAQnzB,GAC5C,MAAOxC,MAAK25B,QAASpS,EAAO+R,EAAO3D,EAAQnzB,MAI7C1B,EAAOk5B,UACPl5B,EAAOs1B,GAAGsC,KAAO,WAChB,GAAIQ,GACHc,EAASl5B,EAAOk5B,OAChBp3B,EAAI,CAIL,KAFA8zB,GAAQ51B,EAAOmG,MAEPrE,EAAIo3B,EAAOn4B,OAAQe,IAC1Bs2B,EAAQc,EAAQp3B,GAEVs2B,KAAWc,EAAQp3B,KAAQs2B,GAChCc,EAAO12B,OAAQV,IAAK,EAIhBo3B,GAAOn4B,QACZf,EAAOs1B,GAAG1U,OAEXgV,GAAQvyB,QAGTrD,EAAOs1B,GAAG8C,MAAQ,SAAUA,GAC3Bp4B,EAAOk5B,OAAO35B,KAAM64B,GACfA,IACJp4B,EAAOs1B,GAAGtjB,QAEVhS,EAAOk5B,OAAOlxB,OAIhBhI,EAAOs1B,GAAGoE,SAAW,GAErB15B,EAAOs1B,GAAGtjB,MAAQ,WACX6jB,KACLA,GAAU8D,YAAa35B,EAAOs1B,GAAGsC,KAAM53B,EAAOs1B,GAAGoE,YAInD15B,EAAOs1B,GAAG1U,KAAO,WAChBgZ,cAAe/D,IACfA,GAAU,MAGX71B,EAAOs1B,GAAGoD,QACTmB,KAAM,IACNC,KAAM,IAENrU,SAAU,KAMXzlB,EAAOG,GAAG45B,MAAQ,SAAUC,EAAMj2B,GAIjC,MAHAi2B,GAAOh6B,EAAOs1B,GAAKt1B,EAAOs1B,GAAGoD,OAAQsB,IAAUA,EAAOA,EACtDj2B,EAAOA,GAAQ,KAER7E,KAAKqhB,MAAOxc,EAAM,SAAU8U,EAAM6H,GACxC,GAAIuZ,GAAUnc,WAAYjF,EAAMmhB,EAChCtZ,GAAME,KAAO,WACZsZ,aAAcD,OAMjB,WACC,GAAIryB,GAAGkH,EAAO7C,EAAQwsB,EACrBjsB,EAAM1N,EAAS2N,cAAc,MAG9BD,GAAId,aAAc,YAAa,KAC/Bc,EAAI6B,UAAY,qEAChBzG,EAAI4E,EAAIpB,qBAAqB,KAAM,GAGnCa,EAASnN,EAAS2N,cAAc,UAChCgsB,EAAMxsB,EAAOkC,YAAarP,EAAS2N,cAAc,WACjDqC,EAAQtC,EAAIpB,qBAAqB,SAAU,GAE3CxD,EAAEgX,MAAMC,QAAU,UAGlB/e,EAAQq6B,gBAAoC,MAAlB3tB,EAAI0B,UAI9BpO,EAAQ8e,MAAQ,MAAMrT,KAAM3D,EAAE6D,aAAa,UAI3C3L,EAAQs6B,eAA4C,OAA3BxyB,EAAE6D,aAAa,QAGxC3L,EAAQu6B,UAAYvrB,EAAM9J,MAI1BlF,EAAQw6B,YAAc7B,EAAIhlB,SAG1B3T,EAAQy6B,UAAYz7B,EAAS2N,cAAc,QAAQ8tB,QAInDtuB,EAAOsH,UAAW,EAClBzT,EAAQ06B,aAAe/B,EAAIllB,SAI3BzE,EAAQhQ,EAAS2N,cAAe,SAChCqC,EAAMpD,aAAc,QAAS,IAC7B5L,EAAQgP,MAA0C,KAAlCA,EAAMrD,aAAc,SAGpCqD,EAAM9J,MAAQ,IACd8J,EAAMpD,aAAc,OAAQ,SAC5B5L,EAAQ26B,WAA6B,MAAhB3rB,EAAM9J,MAG3B4C,EAAIkH,EAAQ7C,EAASwsB,EAAMjsB,EAAM,OAIlC,IAAIkuB,IAAU,KAEd16B,GAAOG,GAAGsC,QACTwN,IAAK,SAAUjL,GACd,GAAI0b,GAAOpf,EAAK4B,EACfrB,EAAO3C,KAAK,EAEb,EAAA,GAAM8C,UAAUjB,OAsBhB,MAFAmC,GAAalD,EAAOkD,WAAY8B,GAEzB9F,KAAKuC,KAAK,SAAUK,GAC1B,GAAImO,EAEmB,KAAlB/Q,KAAKoF,WAKT2L,EADI/M,EACE8B,EAAM/D,KAAM/B,KAAM4C,EAAG9B,EAAQd,MAAO+Q,OAEpCjL,EAIK,MAAPiL,EACJA,EAAM,GACoB,gBAARA,GAClBA,GAAO,GACIjQ,EAAOoD,QAAS6M,KAC3BA,EAAMjQ,EAAO4B,IAAKqO,EAAK,SAAUjL,GAChC,MAAgB,OAATA,EAAgB,GAAKA,EAAQ,MAItC0b,EAAQ1gB,EAAO26B,SAAUz7B,KAAK6E,OAAU/D,EAAO26B,SAAUz7B,KAAK4F,SAASC,eAGjE2b,GAAW,OAASA,IAA8Crd,SAApCqd,EAAMoN,IAAK5uB,KAAM+Q,EAAK,WACzD/Q,KAAK8F,MAAQiL,KAjDd,IAAKpO,EAGJ,MAFA6e,GAAQ1gB,EAAO26B,SAAU94B,EAAKkC,OAAU/D,EAAO26B,SAAU94B,EAAKiD,SAASC,eAElE2b,GAAS,OAASA,IAAgDrd,UAAtC/B,EAAMof,EAAMxf,IAAKW,EAAM,UAChDP,GAGRA,EAAMO,EAAKmD,MAEW,gBAAR1D,GAEbA,EAAImC,QAAQi3B,GAAS,IAEd,MAAPp5B,EAAc,GAAKA,OA0CxBtB,EAAOyC,QACNk4B,UACCnQ,QACCtpB,IAAK,SAAUW,GACd,GAAIoO,GAAMjQ,EAAOyO,KAAKuB,KAAMnO,EAAM,QAClC,OAAc,OAAPoO,EACNA,EACAjQ,EAAOkF,KAAMrD,KAGhBoK,QACC/K,IAAK,SAAUW,GAYd,IAXA,GAAImD,GAAOwlB,EACV1nB,EAAUjB,EAAKiB,QACfyW,EAAQ1X,EAAK6R,cACb2V,EAAoB,eAAdxnB,EAAKkC,MAAiC,EAARwV,EACpC2D,EAASmM,EAAM,QACf7jB,EAAM6jB,EAAM9P,EAAQ,EAAIzW,EAAQ/B,OAChCe,EAAY,EAARyX,EACH/T,EACA6jB,EAAM9P,EAAQ,EAGJ/T,EAAJ1D,EAASA,IAIhB,GAHA0oB,EAAS1nB,EAAShB,MAGX0oB,EAAO/W,UAAY3R,IAAMyX,IAE5BzZ,EAAQ06B,YAAehQ,EAAOjX,SAA+C,OAApCiX,EAAO/e,aAAa,cAC5D+e,EAAOtf,WAAWqI,UAAavT,EAAO8E,SAAU0lB,EAAOtf,WAAY,aAAiB,CAMxF,GAHAlG,EAAQhF,EAAQwqB,GAASva,MAGpBoZ,EACJ,MAAOrkB,EAIRkY,GAAO3d,KAAMyF,GAIf,MAAOkY,IAGR4Q,IAAK,SAAUjsB,EAAMmD,GACpB,GAAI41B,GAAWpQ,EACd1nB,EAAUjB,EAAKiB,QACfoa,EAASld,EAAOmF,UAAWH,GAC3BlD,EAAIgB,EAAQ/B,MAEb,OAAQe,IAGP,GAFA0oB,EAAS1nB,EAAShB,GAEb9B,EAAOuF,QAASvF,EAAO26B,SAASnQ,OAAOtpB,IAAKspB,GAAUtN,IAAY,EAMtE,IACCsN,EAAO/W,SAAWmnB,GAAY,EAE7B,MAAQ7wB,GAGTygB,EAAOqQ,iBAIRrQ,GAAO/W,UAAW,CASpB,OAJMmnB,KACL/4B,EAAK6R,cAAgB,IAGf5Q,OAOX9C,EAAOyB,MAAO,QAAS,YAAc,WACpCzB,EAAO26B,SAAUz7B,OAChB4uB,IAAK,SAAUjsB,EAAMmD,GACpB,MAAKhF,GAAOoD,QAAS4B,GACXnD,EAAK2R,QAAUxT,EAAOuF,QAASvF,EAAO6B,GAAMoO,MAAOjL,IAAW,EADxE,SAKIlF,EAAQu6B,UACbr6B,EAAO26B,SAAUz7B,MAAOgC,IAAM,SAAUW,GAGvC,MAAsC,QAA/BA,EAAK4J,aAAa,SAAoB,KAAO5J,EAAKmD,SAQ5D,IAAI81B,IAAUC,GACbjuB,GAAa9M,EAAO8P,KAAKhD,WACzBkuB,GAAc,0BACdb,GAAkBr6B,EAAQq6B,gBAC1Bc,GAAcn7B,EAAQgP,KAEvB9O,GAAOG,GAAGsC,QACTuN,KAAM,SAAUnN,EAAMmC,GACrB,MAAOuc,GAAQriB,KAAMc,EAAOgQ,KAAMnN,EAAMmC,EAAOhD,UAAUjB,OAAS,IAGnEm6B,WAAY,SAAUr4B,GACrB,MAAO3D,MAAKuC,KAAK,WAChBzB,EAAOk7B,WAAYh8B,KAAM2D,QAK5B7C,EAAOyC,QACNuN,KAAM,SAAUnO,EAAMgB,EAAMmC,GAC3B,GAAI0b,GAAOpf,EACV65B,EAAQt5B,EAAKyC,QAGd,IAAMzC,GAAkB,IAAVs5B,GAAyB,IAAVA,GAAyB,IAAVA,EAK5C,aAAYt5B,GAAK4J,eAAiB3D,EAC1B9H,EAAOmmB,KAAMtkB,EAAMgB,EAAMmC,IAKlB,IAAVm2B,GAAgBn7B,EAAO6X,SAAUhW,KACrCgB,EAAOA,EAAKkC,cACZ2b,EAAQ1gB,EAAOo7B,UAAWv4B,KACvB7C,EAAO8P,KAAKtF,MAAMnB,KAAKkC,KAAM1I,GAASk4B,GAAWD,KAGtCz3B,SAAV2B,EAaO0b,GAAS,OAASA,IAA6C,QAAnCpf,EAAMof,EAAMxf,IAAKW,EAAMgB,IACvDvB,GAGPA,EAAMtB,EAAOyO,KAAKuB,KAAMnO,EAAMgB,GAGhB,MAAPvB,EACN+B,OACA/B,GApBc,OAAV0D,EAGO0b,GAAS,OAASA,IAAoDrd,UAA1C/B,EAAMof,EAAMoN,IAAKjsB,EAAMmD,EAAOnC,IAC9DvB,GAGPO,EAAK6J,aAAc7I,EAAMmC,EAAQ,IAC1BA,OAPPhF,GAAOk7B,WAAYr5B,EAAMgB,KAuB5Bq4B,WAAY,SAAUr5B,EAAMmD,GAC3B,GAAInC,GAAMw4B,EACTv5B,EAAI,EACJw5B,EAAYt2B,GAASA,EAAMwF,MAAO4P,EAEnC,IAAKkhB,GAA+B,IAAlBz5B,EAAKyC,SACtB,MAASzB,EAAOy4B,EAAUx5B,KACzBu5B,EAAWr7B,EAAOu7B,QAAS14B,IAAUA,EAGhC7C,EAAO8P,KAAKtF,MAAMnB,KAAKkC,KAAM1I,GAE5Bo4B,IAAed,KAAoBa,GAAYzvB,KAAM1I,GACzDhB,EAAMw5B,IAAa,EAInBx5B,EAAM7B,EAAO4E,UAAW,WAAa/B,IACpChB,EAAMw5B,IAAa,EAKrBr7B,EAAOgQ,KAAMnO,EAAMgB,EAAM,IAG1BhB,EAAKmK,gBAAiBmuB,GAAkBt3B,EAAOw4B,IAKlDD,WACCr3B,MACC+pB,IAAK,SAAUjsB,EAAMmD,GACpB,IAAMlF,EAAQ26B,YAAwB,UAAVz1B,GAAqBhF,EAAO8E,SAASjD,EAAM,SAAW,CAGjF,GAAIoO,GAAMpO,EAAKmD,KAKf,OAJAnD,GAAK6J,aAAc,OAAQ1G,GACtBiL,IACJpO,EAAKmD,MAAQiL,GAEPjL,QAQZ+1B,IACCjN,IAAK,SAAUjsB,EAAMmD,EAAOnC,GAa3B,MAZKmC,MAAU,EAEdhF,EAAOk7B,WAAYr5B,EAAMgB,GACdo4B,IAAed,KAAoBa,GAAYzvB,KAAM1I,GAEhEhB,EAAK6J,cAAeyuB,IAAmBn6B,EAAOu7B,QAAS14B,IAAUA,EAAMA,GAIvEhB,EAAM7B,EAAO4E,UAAW,WAAa/B,IAAWhB,EAAMgB,IAAS,EAGzDA,IAKT7C,EAAOyB,KAAMzB,EAAO8P,KAAKtF,MAAMnB,KAAK6X,OAAO1W,MAAO,QAAU,SAAU1I,EAAGe,GAExE,GAAI24B,GAAS1uB,GAAYjK,IAAU7C,EAAOyO,KAAKuB,IAE/ClD,IAAYjK,GAASo4B,IAAed,KAAoBa,GAAYzvB,KAAM1I,GACzE,SAAUhB,EAAMgB,EAAM4D,GACrB,GAAInF,GAAK2iB,CAUT,OATMxd,KAELwd,EAASnX,GAAYjK,GACrBiK,GAAYjK,GAASvB,EACrBA,EAAqC,MAA/Bk6B,EAAQ35B,EAAMgB,EAAM4D,GACzB5D,EAAKkC,cACL,KACD+H,GAAYjK,GAASohB,GAEf3iB,GAER,SAAUO,EAAMgB,EAAM4D,GACrB,MAAMA,GAAN,OACQ5E,EAAM7B,EAAO4E,UAAW,WAAa/B,IAC3CA,EAAKkC,cACL,QAMCk2B,IAAgBd,KACrBn6B,EAAOo7B,UAAUp2B,OAChB8oB,IAAK,SAAUjsB,EAAMmD,EAAOnC,GAC3B,MAAK7C,GAAO8E,SAAUjD,EAAM,cAE3BA,EAAK8V,aAAe3S,GAGb81B,IAAYA,GAAShN,IAAKjsB,EAAMmD,EAAOnC,MAO5Cs3B,KAILW,IACChN,IAAK,SAAUjsB,EAAMmD,EAAOnC,GAE3B,GAAIvB,GAAMO,EAAK+M,iBAAkB/L,EAUjC,OATMvB,IACLO,EAAK45B,iBACHn6B,EAAMO,EAAKkJ,cAAc2wB,gBAAiB74B,IAI7CvB,EAAI0D,MAAQA,GAAS,GAGP,UAATnC,GAAoBmC,IAAUnD,EAAK4J,aAAc5I,GAC9CmC,EADR,SAOF8H,GAAW3B,GAAK2B,GAAWjK,KAAOiK,GAAW6uB,OAC5C,SAAU95B,EAAMgB,EAAM4D,GACrB,GAAInF,EACJ,OAAMmF,GAAN,QACSnF,EAAMO,EAAK+M,iBAAkB/L,KAAyB,KAAdvB,EAAI0D,MACnD1D,EAAI0D,MACJ,MAKJhF,EAAO26B,SAAS9mB,QACf3S,IAAK,SAAUW,EAAMgB,GACpB,GAAIvB,GAAMO,EAAK+M,iBAAkB/L,EACjC,OAAKvB,IAAOA,EAAI4O,UACR5O,EAAI0D,MADZ,QAID8oB,IAAKgN,GAAShN,KAKf9tB,EAAOo7B,UAAUQ,iBAChB9N,IAAK,SAAUjsB,EAAMmD,EAAOnC,GAC3Bi4B,GAAShN,IAAKjsB,EAAgB,KAAVmD,GAAe,EAAQA,EAAOnC,KAMpD7C,EAAOyB,MAAO,QAAS,UAAY,SAAUK,EAAGe,GAC/C7C,EAAOo7B,UAAWv4B,IACjBirB,IAAK,SAAUjsB,EAAMmD,GACpB,MAAe,KAAVA,GACJnD,EAAK6J,aAAc7I,EAAM,QAClBmC,GAFR,YASElF,EAAQ8e,QACb5e,EAAOo7B,UAAUxc,OAChB1d,IAAK,SAAUW,GAId,MAAOA,GAAK+c,MAAMC,SAAWxb,QAE9ByqB,IAAK,SAAUjsB,EAAMmD,GACpB,MAASnD,GAAK+c,MAAMC,QAAU7Z,EAAQ,KAQzC,IAAI62B,IAAa,6CAChBC,GAAa,eAEd97B,GAAOG,GAAGsC,QACT0jB,KAAM,SAAUtjB,EAAMmC,GACrB,MAAOuc,GAAQriB,KAAMc,EAAOmmB,KAAMtjB,EAAMmC,EAAOhD,UAAUjB,OAAS,IAGnEg7B,WAAY,SAAUl5B,GAErB,MADAA,GAAO7C,EAAOu7B,QAAS14B,IAAUA,EAC1B3D,KAAKuC,KAAK,WAEhB,IACCvC,KAAM2D,GAASQ,aACRnE,MAAM2D,GACZ,MAAO0B,UAKZvE,EAAOyC,QACN84B,SACCS,MAAO,UACPC,QAAS,aAGV9V,KAAM,SAAUtkB,EAAMgB,EAAMmC,GAC3B,GAAI1D,GAAKof,EAAOwb,EACff,EAAQt5B,EAAKyC,QAGd,IAAMzC,GAAkB,IAAVs5B,GAAyB,IAAVA,GAAyB,IAAVA,EAY5C,MARAe,GAAmB,IAAVf,IAAgBn7B,EAAO6X,SAAUhW,GAErCq6B,IAEJr5B,EAAO7C,EAAOu7B,QAAS14B,IAAUA,EACjC6d,EAAQ1gB,EAAO+0B,UAAWlyB,IAGZQ,SAAV2B,EACG0b,GAAS,OAASA,IAAoDrd,UAA1C/B,EAAMof,EAAMoN,IAAKjsB,EAAMmD,EAAOnC,IAChEvB,EACEO,EAAMgB,GAASmC,EAGX0b,GAAS,OAASA,IAA6C,QAAnCpf,EAAMof,EAAMxf,IAAKW,EAAMgB,IACzDvB,EACAO,EAAMgB,IAITkyB,WACC1hB,UACCnS,IAAK,SAAUW,GAId,GAAIs6B,GAAWn8B,EAAOyO,KAAKuB,KAAMnO,EAAM,WAEvC,OAAOs6B,GACNC,SAAUD,EAAU,IACpBN,GAAWtwB,KAAM1J,EAAKiD,WAAcg3B,GAAWvwB,KAAM1J,EAAKiD,WAAcjD,EAAKuR,KAC5E,EACA,QAQAtT,EAAQs6B,gBAEbp6B,EAAOyB,MAAO,OAAQ,OAAS,SAAUK,EAAGe,GAC3C7C,EAAO+0B,UAAWlyB,IACjB3B,IAAK,SAAUW,GACd,MAAOA,GAAK4J,aAAc5I,EAAM,OAS9B/C,EAAQw6B,cACbt6B,EAAO+0B,UAAUthB,UAChBvS,IAAK,SAAUW,GACd,GAAIgM,GAAShM,EAAKqJ,UAUlB,OARK2C,KACJA,EAAO6F,cAGF7F,EAAO3C,YACX2C,EAAO3C,WAAWwI,eAGb,QAKV1T,EAAOyB,MACN,WACA,WACA,YACA,cACA,cACA,UACA,UACA,SACA,cACA,mBACE,WACFzB,EAAOu7B,QAASr8B,KAAK6F,eAAkB7F,OAIlCY,EAAQy6B,UACbv6B,EAAOu7B,QAAQhB,QAAU,WAM1B,IAAI8B,IAAS,aAEbr8B,GAAOG,GAAGsC,QACT65B,SAAU,SAAUt3B,GACnB,GAAIu3B,GAAS16B,EAAMmL,EAAKwvB,EAAOn6B,EAAGo6B,EACjC36B,EAAI,EACJM,EAAMlD,KAAK6B,OACX27B,EAA2B,gBAAV13B,IAAsBA,CAExC,IAAKhF,EAAOkD,WAAY8B,GACvB,MAAO9F,MAAKuC,KAAK,SAAUY,GAC1BrC,EAAQd,MAAOo9B,SAAUt3B,EAAM/D,KAAM/B,KAAMmD,EAAGnD,KAAKgP,aAIrD,IAAKwuB,EAIJ,IAFAH,GAAYv3B,GAAS,IAAKwF,MAAO4P,OAErBhY,EAAJN,EAASA,IAOhB,GANAD,EAAO3C,KAAM4C,GACbkL,EAAwB,IAAlBnL,EAAKyC,WAAoBzC,EAAKqM,WACjC,IAAMrM,EAAKqM,UAAY,KAAMzK,QAAS44B,GAAQ,KAChD,KAGU,CACVh6B,EAAI,CACJ,OAASm6B,EAAQD,EAAQl6B,KACnB2K,EAAIxN,QAAS,IAAMg9B,EAAQ,KAAQ,IACvCxvB,GAAOwvB,EAAQ,IAKjBC,GAAaz8B,EAAOH,KAAMmN,GACrBnL,EAAKqM,YAAcuuB,IACvB56B,EAAKqM,UAAYuuB,GAMrB,MAAOv9B,OAGRy9B,YAAa,SAAU33B,GACtB,GAAIu3B,GAAS16B,EAAMmL,EAAKwvB,EAAOn6B,EAAGo6B,EACjC36B,EAAI,EACJM,EAAMlD,KAAK6B,OACX27B,EAA+B,IAArB16B,UAAUjB,QAAiC,gBAAViE,IAAsBA,CAElE,IAAKhF,EAAOkD,WAAY8B,GACvB,MAAO9F,MAAKuC,KAAK,SAAUY,GAC1BrC,EAAQd,MAAOy9B,YAAa33B,EAAM/D,KAAM/B,KAAMmD,EAAGnD,KAAKgP,aAGxD,IAAKwuB,EAGJ,IAFAH,GAAYv3B,GAAS,IAAKwF,MAAO4P,OAErBhY,EAAJN,EAASA,IAQhB,GAPAD,EAAO3C,KAAM4C,GAEbkL,EAAwB,IAAlBnL,EAAKyC,WAAoBzC,EAAKqM,WACjC,IAAMrM,EAAKqM,UAAY,KAAMzK,QAAS44B,GAAQ,KAChD,IAGU,CACVh6B,EAAI,CACJ,OAASm6B,EAAQD,EAAQl6B,KAExB,MAAQ2K,EAAIxN,QAAS,IAAMg9B,EAAQ,MAAS,EAC3CxvB,EAAMA,EAAIvJ,QAAS,IAAM+4B,EAAQ,IAAK,IAKxCC,GAAaz3B,EAAQhF,EAAOH,KAAMmN,GAAQ,GACrCnL,EAAKqM,YAAcuuB,IACvB56B,EAAKqM,UAAYuuB,GAMrB,MAAOv9B,OAGR09B,YAAa,SAAU53B,EAAO63B,GAC7B,GAAI94B,SAAciB,EAElB,OAAyB,iBAAb63B,IAAmC,WAAT94B,EAC9B84B,EAAW39B,KAAKo9B,SAAUt3B,GAAU9F,KAAKy9B,YAAa33B,GAItD9F,KAAKuC,KADRzB,EAAOkD,WAAY8B,GACN,SAAUlD,GAC1B9B,EAAQd,MAAO09B,YAAa53B,EAAM/D,KAAK/B,KAAM4C,EAAG5C,KAAKgP,UAAW2uB,GAAWA,IAI5D,WAChB,GAAc,WAAT94B,EAAoB,CAExB,GAAImK,GACHpM,EAAI,EACJqW,EAAOnY,EAAQd,MACf49B,EAAa93B,EAAMwF,MAAO4P,MAE3B,OAASlM,EAAY4uB,EAAYh7B,KAE3BqW,EAAK4kB,SAAU7uB,GACnBiK,EAAKwkB,YAAazuB,GAElBiK,EAAKmkB,SAAUpuB,QAKNnK,IAAS+D,GAAyB,YAAT/D,KAC/B7E,KAAKgP,WAETlO,EAAOqgB,MAAOnhB,KAAM,gBAAiBA,KAAKgP,WAO3ChP,KAAKgP,UAAYhP,KAAKgP,WAAalJ,KAAU,EAAQ,GAAKhF,EAAOqgB,MAAOnhB,KAAM,kBAAqB,OAKtG69B,SAAU,SAAU98B,GAInB,IAHA,GAAIiO,GAAY,IAAMjO,EAAW,IAChC6B,EAAI,EACJuX,EAAIna,KAAK6B,OACEsY,EAAJvX,EAAOA,IACd,GAA0B,IAArB5C,KAAK4C,GAAGwC,WAAmB,IAAMpF,KAAK4C,GAAGoM,UAAY,KAAKzK,QAAQ44B,GAAQ,KAAK78B,QAAS0O,IAAe,EAC3G,OAAO,CAIT,QAAO,KAUTlO,EAAOyB,KAAM,0MAEqD4E,MAAM,KAAM,SAAUvE,EAAGe,GAG1F7C,EAAOG,GAAI0C,GAAS,SAAU6B,EAAMvE,GACnC,MAAO6B,WAAUjB,OAAS,EACzB7B,KAAKkqB,GAAIvmB,EAAM,KAAM6B,EAAMvE,GAC3BjB,KAAK6e,QAASlb,MAIjB7C,EAAOG,GAAGsC,QACTu6B,MAAO,SAAUC,EAAQC,GACxB,MAAOh+B,MAAKspB,WAAYyU,GAASxU,WAAYyU,GAASD,IAGvDE,KAAM,SAAU7Z,EAAO5e,EAAMvE,GAC5B,MAAOjB,MAAKkqB,GAAI9F,EAAO,KAAM5e,EAAMvE,IAEpCi9B,OAAQ,SAAU9Z,EAAOnjB,GACxB,MAAOjB,MAAK8e,IAAKsF,EAAO,KAAMnjB,IAG/Bk9B,SAAU,SAAUp9B,EAAUqjB,EAAO5e,EAAMvE,GAC1C,MAAOjB,MAAKkqB,GAAI9F,EAAOrjB,EAAUyE,EAAMvE,IAExCm9B,WAAY,SAAUr9B,EAAUqjB,EAAOnjB,GAEtC,MAA4B,KAArB6B,UAAUjB,OAAe7B,KAAK8e,IAAK/d,EAAU,MAASf,KAAK8e,IAAKsF,EAAOrjB,GAAY,KAAME,KAKlG,IAAIo9B,IAAQv9B,EAAOmG,MAEfq3B,GAAS,KAITC,GAAe,kIAEnBz9B,GAAOsf,UAAY,SAAU5a,GAE5B,GAAKzF,EAAOy+B,MAAQz+B,EAAOy+B,KAAKC,MAG/B,MAAO1+B,GAAOy+B,KAAKC,MAAOj5B,EAAO,GAGlC,IAAIk5B,GACHC,EAAQ,KACRC,EAAM99B,EAAOH,KAAM6E,EAAO,GAI3B,OAAOo5B,KAAQ99B,EAAOH,KAAMi+B,EAAIr6B,QAASg6B,GAAc,SAAUhmB,EAAOsmB,EAAOC,EAAMnP,GAQpF,MALK+O,IAAmBG,IACvBF,EAAQ,GAIM,IAAVA,EACGpmB,GAIRmmB,EAAkBI,GAAQD,EAM1BF,IAAUhP,GAASmP,EAGZ,OAELC,SAAU,UAAYH,KACxB99B,EAAO2D,MAAO,iBAAmBe,IAKnC1E,EAAOk+B,SAAW,SAAUx5B,GAC3B,GAAImN,GAAK3L,CACT,KAAMxB,GAAwB,gBAATA,GACpB,MAAO,KAER,KACMzF,EAAOk/B,WACXj4B,EAAM,GAAIi4B,WACVtsB,EAAM3L,EAAIk4B,gBAAiB15B,EAAM,cAEjCmN,EAAM,GAAIwsB,eAAe,oBACzBxsB,EAAIysB,MAAQ,QACZzsB,EAAI0sB,QAAS75B,IAEb,MAAOH,GACRsN,EAAMxO,OAKP,MAHMwO,IAAQA,EAAIpE,kBAAmBoE,EAAIzG,qBAAsB,eAAgBrK,QAC9Ef,EAAO2D,MAAO,gBAAkBe,GAE1BmN,EAIR,IAEC2sB,IACAC,GAEAC,GAAQ,OACRC,GAAM,gBACNC,GAAW,gCAEXC,GAAiB,4DACjBC,GAAa,iBACbC,GAAY,QACZC,GAAO,4DAWPC,MAOAC,MAGAC,GAAW,KAAK7/B,OAAO,IAIxB,KACCm/B,GAAe1rB,SAASK,KACvB,MAAO7O,IAGRk6B,GAAe3/B,EAAS2N,cAAe,KACvCgyB,GAAarrB,KAAO,GACpBqrB,GAAeA,GAAarrB,KAI7BorB,GAAeQ,GAAKh0B,KAAMyzB,GAAa15B,kBAGvC,SAASq6B,IAA6BC,GAGrC,MAAO,UAAUC,EAAoB3jB,GAED,gBAAvB2jB,KACX3jB,EAAO2jB,EACPA,EAAqB,IAGtB,IAAIC,GACHz9B,EAAI,EACJ09B,EAAYF,EAAmBv6B,cAAcyF,MAAO4P,MAErD,IAAKpa,EAAOkD,WAAYyY,GAEvB,MAAS4jB,EAAWC,EAAU19B,KAEC,MAAzBy9B,EAASjnB,OAAQ,IACrBinB,EAAWA,EAASlgC,MAAO,IAAO,KACjCggC,EAAWE,GAAaF,EAAWE,QAAkB1vB,QAAS8L,KAI9D0jB,EAAWE,GAAaF,EAAWE,QAAkBhgC,KAAMoc,IAQjE,QAAS8jB,IAA+BJ,EAAWv8B,EAASm1B,EAAiByH,GAE5E,GAAIC,MACHC,EAAqBP,IAAcH,EAEpC,SAASW,GAASN,GACjB,GAAI9rB,EAYJ,OAXAksB,GAAWJ,IAAa,EACxBv/B,EAAOyB,KAAM49B,EAAWE,OAAkB,SAAUx1B,EAAG+1B,GACtD,GAAIC,GAAsBD,EAAoBh9B,EAASm1B,EAAiByH,EACxE,OAAoC,gBAAxBK,IAAqCH,GAAqBD,EAAWI,GAIrEH,IACDnsB,EAAWssB,GADf,QAHNj9B,EAAQ08B,UAAU3vB,QAASkwB,GAC3BF,EAASE,IACF,KAKFtsB,EAGR,MAAOosB,GAAS/8B,EAAQ08B,UAAW,MAAUG,EAAW,MAASE,EAAS,KAM3E,QAASG,IAAYh9B,EAAQN,GAC5B,GAAIO,GAAMoB,EACT47B,EAAcjgC,EAAOkgC,aAAaD,eAEnC,KAAM57B,IAAO3B,GACQW,SAAfX,EAAK2B,MACP47B,EAAa57B,GAAQrB,EAAWC,IAASA,OAAgBoB,GAAQ3B,EAAK2B,GAO1E,OAJKpB,IACJjD,EAAOyC,QAAQ,EAAMO,EAAQC,GAGvBD,EAOR,QAASm9B,IAAqBC,EAAGV,EAAOW,GACvC,GAAIC,GAAeC,EAAIC,EAAez8B,EACrC6U,EAAWwnB,EAAExnB,SACb4mB,EAAYY,EAAEZ,SAGf,OAA2B,MAAnBA,EAAW,GAClBA,EAAUnzB,QACEhJ,SAAPk9B,IACJA,EAAKH,EAAEK,UAAYf,EAAMgB,kBAAkB,gBAK7C,IAAKH,EACJ,IAAMx8B,IAAQ6U,GACb,GAAKA,EAAU7U,IAAU6U,EAAU7U,GAAOwH,KAAMg1B,GAAO,CACtDf,EAAU3vB,QAAS9L,EACnB,OAMH,GAAKy7B,EAAW,IAAOa,GACtBG,EAAgBhB,EAAW,OACrB,CAEN,IAAMz7B,IAAQs8B,GAAY,CACzB,IAAMb,EAAW,IAAOY,EAAEO,WAAY58B,EAAO,IAAMy7B,EAAU,IAAO,CACnEgB,EAAgBz8B,CAChB,OAEKu8B,IACLA,EAAgBv8B,GAIlBy8B,EAAgBA,GAAiBF,EAMlC,MAAKE,IACCA,IAAkBhB,EAAW,IACjCA,EAAU3vB,QAAS2wB,GAEbH,EAAWG,IAJnB,OAWD,QAASI,IAAaR,EAAGS,EAAUnB,EAAOoB,GACzC,GAAIC,GAAOC,EAASC,EAAM/6B,EAAK4S,EAC9B6nB,KAEAnB,EAAYY,EAAEZ,UAAUngC,OAGzB,IAAKmgC,EAAW,GACf,IAAMyB,IAAQb,GAAEO,WACfA,EAAYM,EAAKl8B,eAAkBq7B,EAAEO,WAAYM,EAInDD,GAAUxB,EAAUnzB,OAGpB,OAAQ20B,EAcP,GAZKZ,EAAEc,eAAgBF,KACtBtB,EAAOU,EAAEc,eAAgBF,IAAcH,IAIlC/nB,GAAQgoB,GAAaV,EAAEe,aAC5BN,EAAWT,EAAEe,WAAYN,EAAUT,EAAEb,WAGtCzmB,EAAOkoB,EACPA,EAAUxB,EAAUnzB,QAKnB,GAAiB,MAAZ20B,EAEJA,EAAUloB,MAGJ,IAAc,MAATA,GAAgBA,IAASkoB,EAAU,CAM9C,GAHAC,EAAON,EAAY7nB,EAAO,IAAMkoB,IAAaL,EAAY,KAAOK,IAG1DC,EACL,IAAMF,IAASJ,GAId,GADAz6B,EAAM66B,EAAM16B,MAAO,KACdH,EAAK,KAAQ86B,IAGjBC,EAAON,EAAY7nB,EAAO,IAAM5S,EAAK,KACpCy6B,EAAY,KAAOz6B,EAAK,KACb,CAEN+6B,KAAS,EACbA,EAAON,EAAYI,GAGRJ,EAAYI,MAAY,IACnCC,EAAU96B,EAAK,GACfs5B,EAAU3vB,QAAS3J,EAAK,IAEzB,OAOJ,GAAK+6B,KAAS,EAGb,GAAKA,GAAQb,EAAG,UACfS,EAAWI,EAAMJ,OAEjB,KACCA,EAAWI,EAAMJ,GAChB,MAAQt8B,GACT,OAASsX,MAAO,cAAelY,MAAOs9B,EAAO18B,EAAI,sBAAwBuU,EAAO,OAASkoB,IAQ/F,OAASnlB,MAAO,UAAWnX,KAAMm8B,GAGlC7gC,EAAOyC,QAGN2+B,OAAQ,EAGRC,gBACAC,QAEApB,cACCqB,IAAK9C,GACL16B,KAAM,MACNy9B,QAAS3C,GAAetzB,KAAMizB,GAAc,IAC5C9/B,QAAQ,EACR+iC,aAAa,EACbnD,OAAO,EACPoD,YAAa,mDAabC,SACCvL,IAAK+I,GACLj6B,KAAM,aACNwoB,KAAM,YACN7b,IAAK,4BACL+vB,KAAM,qCAGPhpB,UACC/G,IAAK,MACL6b,KAAM,OACNkU,KAAM,QAGPV,gBACCrvB,IAAK,cACL3M,KAAM,eACN08B,KAAM,gBAKPjB,YAGCkB,SAAU13B,OAGV23B,aAAa,EAGbC,YAAa/hC,EAAOsf,UAGpB0iB,WAAYhiC,EAAOk+B,UAOpB+B,aACCsB,KAAK,EACLrhC,SAAS,IAOX+hC,UAAW,SAAUj/B,EAAQk/B,GAC5B,MAAOA,GAGNlC,GAAYA,GAAYh9B,EAAQhD,EAAOkgC,cAAgBgC,GAGvDlC,GAAYhgC,EAAOkgC,aAAcl9B,IAGnCm/B,cAAe/C,GAA6BH,IAC5CmD,cAAehD,GAA6BF,IAG5CmD,KAAM,SAAUd,EAAKz+B,GAGA,gBAARy+B,KACXz+B,EAAUy+B,EACVA,EAAMl+B,QAIPP,EAAUA,KAEV,IACC2xB,GAEA3yB,EAEAwgC,EAEAC,EAEAC,EAGAC,EAEAC,EAEAC,EAEAvC,EAAIpgC,EAAOiiC,aAAen/B,GAE1B8/B,EAAkBxC,EAAElgC,SAAWkgC,EAE/ByC,EAAqBzC,EAAElgC,UAAa0iC,EAAgBt+B,UAAYs+B,EAAgB/hC,QAC/Eb,EAAQ4iC,GACR5iC,EAAOqe,MAERrC,EAAWhc,EAAO0b,WAClBonB,EAAmB9iC,EAAOya,UAAU,eAEpCsoB,EAAa3C,EAAE2C,eAEfC,KACAC,KAEApnB,EAAQ,EAERqnB,EAAW,WAEXxD,GACCphB,WAAY,EAGZoiB,kBAAmB,SAAUr8B,GAC5B,GAAImG,EACJ,IAAe,IAAVqR,EAAc,CAClB,IAAM8mB,EAAkB,CACvBA,IACA,OAASn4B,EAAQo0B,GAAS5zB,KAAMu3B,GAC/BI,EAAiBn4B,EAAM,GAAGzF,eAAkByF,EAAO,GAGrDA,EAAQm4B,EAAiBt+B,EAAIU,eAE9B,MAAgB,OAATyF,EAAgB,KAAOA,GAI/B24B,sBAAuB,WACtB,MAAiB,KAAVtnB,EAAc0mB,EAAwB,MAI9Ca,iBAAkB,SAAUvgC,EAAMmC,GACjC,GAAIq+B,GAAQxgC,EAAKkC,aAKjB,OAJM8W,KACLhZ,EAAOogC,EAAqBI,GAAUJ,EAAqBI,IAAWxgC,EACtEmgC,EAAgBngC,GAASmC,GAEnB9F,MAIRokC,iBAAkB,SAAUv/B,GAI3B,MAHM8X,KACLukB,EAAEK,SAAW18B,GAEP7E,MAIR6jC,WAAY,SAAUnhC,GACrB,GAAI2hC,EACJ,IAAK3hC,EACJ,GAAa,EAARia,EACJ,IAAM0nB,IAAQ3hC,GAEbmhC,EAAYQ,IAAWR,EAAYQ,GAAQ3hC,EAAK2hC,QAIjD7D,GAAM3jB,OAAQna,EAAK89B,EAAM8D,QAG3B,OAAOtkC,OAIRukC,MAAO,SAAUC,GAChB,GAAIC,GAAYD,GAAcR,CAK9B,OAJKR,IACJA,EAAUe,MAAOE,GAElBr8B,EAAM,EAAGq8B,GACFzkC,MAwCV,IAnCA8c,EAASF,QAAS4jB,GAAQrH,SAAWyK,EAAiBrpB,IACtDimB,EAAMkE,QAAUlE,EAAMp4B,KACtBo4B,EAAM/7B,MAAQ+7B,EAAMzjB,KAMpBmkB,EAAEmB,MAAUA,GAAOnB,EAAEmB,KAAO9C,IAAiB,IAAKh7B,QAASi7B,GAAO,IAAKj7B,QAASs7B,GAAWP,GAAc,GAAM,MAG/G4B,EAAEr8B,KAAOjB,EAAQ+gC,QAAU/gC,EAAQiB,MAAQq8B,EAAEyD,QAAUzD,EAAEr8B,KAGzDq8B,EAAEZ,UAAYx/B,EAAOH,KAAMugC,EAAEb,UAAY,KAAMx6B,cAAcyF,MAAO4P,KAAiB,IAG/D,MAAjBgmB,EAAE0D,cACNrP,EAAQuK,GAAKh0B,KAAMo1B,EAAEmB,IAAIx8B,eACzBq7B,EAAE0D,eAAkBrP,GACjBA,EAAO,KAAQ+J,GAAc,IAAO/J,EAAO,KAAQ+J,GAAc,KAChE/J,EAAO,KAAwB,UAAfA,EAAO,GAAkB,KAAO,WAC/C+J,GAAc,KAA+B,UAAtBA,GAAc,GAAkB,KAAO,UAK/D4B,EAAE17B,MAAQ07B,EAAEqB,aAAiC,gBAAXrB,GAAE17B,OACxC07B,EAAE17B,KAAO1E,EAAO2qB,MAAOyV,EAAE17B,KAAM07B,EAAE2D,cAIlCtE,GAA+BR,GAAYmB,EAAGt9B,EAAS48B,GAGxC,IAAV7jB,EACJ,MAAO6jB,EAIR+C,GAAcrC,EAAE1hC,OAGX+jC,GAAmC,IAApBziC,EAAOohC,UAC1BphC,EAAOqe,MAAMN,QAAQ,aAItBqiB,EAAEr8B,KAAOq8B,EAAEr8B,KAAKpD,cAGhBy/B,EAAE4D,YAAclF,GAAWvzB,KAAM60B,EAAEr8B,MAInCu+B,EAAWlC,EAAEmB,IAGPnB,EAAE4D,aAGF5D,EAAE17B,OACN49B,EAAalC,EAAEmB,MAAS/D,GAAOjyB,KAAM+2B,GAAa,IAAM,KAAQlC,EAAE17B,WAE3D07B,GAAE17B,MAIL07B,EAAEj0B,SAAU,IAChBi0B,EAAEmB,IAAM5C,GAAIpzB,KAAM+2B,GAGjBA,EAAS7+B,QAASk7B,GAAK,OAASpB,MAGhC+E,GAAa9E,GAAOjyB,KAAM+2B,GAAa,IAAM,KAAQ,KAAO/E,OAK1D6C,EAAE6D,aACDjkC,EAAOqhC,aAAciB,IACzB5C,EAAM0D,iBAAkB,oBAAqBpjC,EAAOqhC,aAAciB,IAE9DtiC,EAAOshC,KAAMgB,IACjB5C,EAAM0D,iBAAkB,gBAAiBpjC,EAAOshC,KAAMgB,MAKnDlC,EAAE17B,MAAQ07B,EAAE4D,YAAc5D,EAAEsB,eAAgB,GAAS5+B,EAAQ4+B,cACjEhC,EAAM0D,iBAAkB,eAAgBhD,EAAEsB,aAI3ChC,EAAM0D,iBACL,SACAhD,EAAEZ,UAAW,IAAOY,EAAEuB,QAASvB,EAAEZ,UAAU,IAC1CY,EAAEuB,QAASvB,EAAEZ,UAAU,KAA8B,MAArBY,EAAEZ,UAAW,GAAc,KAAOL,GAAW,WAAa,IAC1FiB,EAAEuB,QAAS,KAIb,KAAM7/B,IAAKs+B,GAAE8D,QACZxE,EAAM0D,iBAAkBthC,EAAGs+B,EAAE8D,QAASpiC,GAIvC,IAAKs+B,EAAE+D,aAAgB/D,EAAE+D,WAAWljC,KAAM2hC,EAAiBlD,EAAOU,MAAQ,GAAmB,IAAVvkB,GAElF,MAAO6jB,GAAM+D,OAIdP,GAAW,OAGX,KAAMphC,KAAO8hC,QAAS,EAAGjgC,MAAO,EAAG00B,SAAU,GAC5CqH,EAAO59B,GAAKs+B,EAAGt+B,GAOhB,IAHA4gC,EAAYjD,GAA+BP,GAAYkB,EAAGt9B,EAAS48B,GAK5D,CACNA,EAAMphB,WAAa,EAGdmkB,GACJI,EAAmB9kB,QAAS,YAAc2hB,EAAOU,IAG7CA,EAAE9B,OAAS8B,EAAEnG,QAAU,IAC3BuI,EAAe1kB,WAAW,WACzB4hB,EAAM+D,MAAM,YACVrD,EAAEnG,SAGN,KACCpe,EAAQ,EACR6mB,EAAU0B,KAAMpB,EAAgB17B,GAC/B,MAAQ/C,GAET,KAAa,EAARsX,GAIJ,KAAMtX,EAHN+C,GAAM,GAAI/C,QArBZ+C,GAAM,GAAI,eA8BX,SAASA,GAAMk8B,EAAQa,EAAkBhE,EAAW6D,GACnD,GAAIpD,GAAW8C,EAASjgC,EAAOk9B,EAAUyD,EACxCZ,EAAaW,CAGC,KAAVxoB,IAKLA,EAAQ,EAGH2mB,GACJtI,aAAcsI,GAKfE,EAAYr/B,OAGZk/B,EAAwB2B,GAAW,GAGnCxE,EAAMphB,WAAaklB,EAAS,EAAI,EAAI,EAGpC1C,EAAY0C,GAAU,KAAgB,IAATA,GAA2B,MAAXA,EAGxCnD,IACJQ,EAAWV,GAAqBC,EAAGV,EAAOW,IAI3CQ,EAAWD,GAAaR,EAAGS,EAAUnB,EAAOoB,GAGvCA,GAGCV,EAAE6D,aACNK,EAAW5E,EAAMgB,kBAAkB,iBAC9B4D,IACJtkC,EAAOqhC,aAAciB,GAAagC,GAEnCA,EAAW5E,EAAMgB,kBAAkB,QAC9B4D,IACJtkC,EAAOshC,KAAMgB,GAAagC,IAKZ,MAAXd,GAA6B,SAAXpD,EAAEr8B,KACxB2/B,EAAa,YAGS,MAAXF,EACXE,EAAa,eAIbA,EAAa7C,EAAShlB,MACtB+nB,EAAU/C,EAASn8B,KACnBf,EAAQk9B,EAASl9B,MACjBm9B,GAAan9B,KAKdA,EAAQ+/B,GACHF,IAAWE,KACfA,EAAa,QACC,EAATF,IACJA,EAAS,KAMZ9D,EAAM8D,OAASA,EACf9D,EAAMgE,YAAeW,GAAoBX,GAAe,GAGnD5C,EACJ9kB,EAASqB,YAAaulB,GAAmBgB,EAASF,EAAYhE,IAE9D1jB,EAASmc,WAAYyK,GAAmBlD,EAAOgE,EAAY//B,IAI5D+7B,EAAMqD,WAAYA,GAClBA,EAAa1/B,OAERo/B,GACJI,EAAmB9kB,QAAS+iB,EAAY,cAAgB,aACrDpB,EAAOU,EAAGU,EAAY8C,EAAUjgC,IAIpCm/B,EAAiBrnB,SAAUmnB,GAAmBlD,EAAOgE,IAEhDjB,IACJI,EAAmB9kB,QAAS,gBAAkB2hB,EAAOU,MAE3CpgC,EAAOohC,QAChBphC,EAAOqe,MAAMN,QAAQ,cAKxB,MAAO2hB,IAGR6E,QAAS,SAAUhD,EAAK78B,EAAMhD,GAC7B,MAAO1B,GAAOkB,IAAKqgC,EAAK78B,EAAMhD,EAAU,SAGzC8iC,UAAW,SAAUjD,EAAK7/B,GACzB,MAAO1B,GAAOkB,IAAKqgC,EAAKl+B,OAAW3B,EAAU,aAI/C1B,EAAOyB,MAAQ,MAAO,QAAU,SAAUK,EAAG+hC,GAC5C7jC,EAAQ6jC,GAAW,SAAUtC,EAAK78B,EAAMhD,EAAUqC,GAQjD,MANK/D,GAAOkD,WAAYwB,KACvBX,EAAOA,GAAQrC,EACfA,EAAWgD,EACXA,EAAOrB,QAGDrD,EAAOqiC,MACbd,IAAKA,EACLx9B,KAAM8/B,EACNtE,SAAUx7B,EACVW,KAAMA,EACNk/B,QAASliC,OAMZ1B,EAAOyB,MAAQ,YAAa,WAAY,eAAgB,YAAa,cAAe,YAAc,SAAUK,EAAGiC,GAC9G/D,EAAOG,GAAI4D,GAAS,SAAU5D,GAC7B,MAAOjB,MAAKkqB,GAAIrlB,EAAM5D,MAKxBH,EAAOguB,SAAW,SAAUuT,GAC3B,MAAOvhC,GAAOqiC,MACbd,IAAKA,EACLx9B,KAAM,MACNw7B,SAAU,SACVjB,OAAO,EACP5/B,QAAQ,EACR+lC,UAAU,KAKZzkC,EAAOG,GAAGsC,QACTiiC,QAAS,SAAUhX,GAClB,GAAK1tB,EAAOkD,WAAYwqB,GACvB,MAAOxuB,MAAKuC,KAAK,SAASK,GACzB9B,EAAOd,MAAMwlC,QAAShX,EAAKzsB,KAAK/B,KAAM4C,KAIxC,IAAK5C,KAAK,GAAK,CAEd,GAAI6tB,GAAO/sB,EAAQ0tB,EAAMxuB,KAAK,GAAG6L,eAAgB7I,GAAG,GAAGa,OAAM,EAExD7D,MAAK,GAAGgM,YACZ6hB,EAAKO,aAAcpuB,KAAK,IAGzB6tB,EAAKnrB,IAAI,WACR,GAAIC,GAAO3C,IAEX,OAAQ2C,EAAKyM,YAA2C,IAA7BzM,EAAKyM,WAAWhK,SAC1CzC,EAAOA,EAAKyM,UAGb,OAAOzM,KACLsrB,OAAQjuB,MAGZ,MAAOA,OAGRylC,UAAW,SAAUjX,GACpB,MACQxuB,MAAKuC,KADRzB,EAAOkD,WAAYwqB,GACN,SAAS5rB,GACzB9B,EAAOd,MAAMylC,UAAWjX,EAAKzsB,KAAK/B,KAAM4C,KAIzB,WAChB,GAAIqW,GAAOnY,EAAQd,MAClB0Z,EAAWT,EAAKS,UAEZA,GAAS7X,OACb6X,EAAS8rB,QAAShX,GAGlBvV,EAAKgV,OAAQO,MAKhBX,KAAM,SAAUW,GACf,GAAIxqB,GAAalD,EAAOkD,WAAYwqB,EAEpC,OAAOxuB,MAAKuC,KAAK,SAASK,GACzB9B,EAAQd,MAAOwlC,QAASxhC,EAAawqB,EAAKzsB,KAAK/B,KAAM4C,GAAK4rB,MAI5DkX,OAAQ,WACP,MAAO1lC,MAAK2O,SAASpM,KAAK,WACnBzB,EAAO8E,SAAU5F,KAAM,SAC5Bc,EAAQd,MAAOyuB,YAAazuB,KAAKmL,cAEhC/H,SAKLtC,EAAO8P,KAAK2E,QAAQoe,OAAS,SAAUhxB,GAGtC,MAAOA,GAAKkd,aAAe,GAAKld,EAAKsvB,cAAgB,IAClDrxB,EAAQkxB,yBACiE,UAAxEnvB,EAAK+c,OAAS/c,EAAK+c,MAAM6P,SAAYzuB,EAAOshB,IAAKzf,EAAM,aAG5D7B,EAAO8P,KAAK2E,QAAQowB,QAAU,SAAUhjC,GACvC,OAAQ7B,EAAO8P,KAAK2E,QAAQoe,OAAQhxB,GAMrC,IAAIijC,IAAM,OACTC,GAAW,QACXC,GAAQ,SACRC,GAAkB,wCAClBC,GAAe,oCAEhB,SAASC,IAAa9Q,EAAQvwB,EAAKigC,EAAatqB,GAC/C,GAAI5W,EAEJ,IAAK7C,EAAOoD,QAASU,GAEpB9D,EAAOyB,KAAMqC,EAAK,SAAUhC,EAAGsjC,GACzBrB,GAAegB,GAASx5B,KAAM8oB,GAElC5a,EAAK4a,EAAQ+Q,GAIbD,GAAa9Q,EAAS,KAAqB,gBAAN+Q,GAAiBtjC,EAAI,IAAO,IAAKsjC,EAAGrB,EAAatqB,SAIlF,IAAMsqB,GAAsC,WAAvB/jC,EAAO+D,KAAMD,GAQxC2V,EAAK4a,EAAQvwB,OANb,KAAMjB,IAAQiB,GACbqhC,GAAa9Q,EAAS,IAAMxxB,EAAO,IAAKiB,EAAKjB,GAAQkhC,EAAatqB,GAWrEzZ,EAAO2qB,MAAQ,SAAU/iB,EAAGm8B,GAC3B,GAAI1P,GACH+L,KACA3mB,EAAM,SAAUpV,EAAKW,GAEpBA,EAAQhF,EAAOkD,WAAY8B,GAAUA,IAAqB,MAATA,EAAgB,GAAKA,EACtEo7B,EAAGA,EAAEr/B,QAAWskC,mBAAoBhhC,GAAQ,IAAMghC,mBAAoBrgC,GASxE,IALqB3B,SAAhB0gC,IACJA,EAAc/jC,EAAOkgC,cAAgBlgC,EAAOkgC,aAAa6D,aAIrD/jC,EAAOoD,QAASwE,IAASA,EAAE/G,SAAWb,EAAOmD,cAAeyE,GAEhE5H,EAAOyB,KAAMmG,EAAG,WACf6R,EAAKva,KAAK2D,KAAM3D,KAAK8F,aAMtB,KAAMqvB,IAAUzsB,GACfu9B,GAAa9Q,EAAQzsB,EAAGysB,GAAU0P,EAAatqB,EAKjD,OAAO2mB,GAAEv0B,KAAM,KAAMpI,QAASqhC,GAAK,MAGpC9kC,EAAOG,GAAGsC,QACT6iC,UAAW,WACV,MAAOtlC,GAAO2qB,MAAOzrB,KAAKqmC,mBAE3BA,eAAgB,WACf,MAAOrmC,MAAK0C,IAAI,WAEf,GAAImO,GAAW/P,EAAOmmB,KAAMjnB,KAAM,WAClC,OAAO6Q,GAAW/P,EAAOmF,UAAW4K,GAAa7Q,OAEjDwP,OAAO,WACP,GAAI3K,GAAO7E,KAAK6E,IAEhB,OAAO7E,MAAK2D,OAAS7C,EAAQd,MAAOkZ,GAAI,cACvC8sB,GAAa35B,KAAMrM,KAAK4F,YAAemgC,GAAgB15B,KAAMxH,KAC3D7E,KAAKsU,UAAYoO,EAAerW,KAAMxH,MAEzCnC,IAAI,SAAUE,EAAGD,GACjB,GAAIoO,GAAMjQ,EAAQd,MAAO+Q,KAEzB,OAAc,OAAPA,EACN,KACAjQ,EAAOoD,QAAS6M,GACfjQ,EAAO4B,IAAKqO,EAAK,SAAUA,GAC1B,OAASpN,KAAMhB,EAAKgB,KAAMmC,MAAOiL,EAAIxM,QAASuhC,GAAO,YAEpDniC,KAAMhB,EAAKgB,KAAMmC,MAAOiL,EAAIxM,QAASuhC,GAAO,WAC9C9jC,SAOLlB,EAAOkgC,aAAasF,IAA+BniC,SAAzBpE,EAAOo/B,cAEhC,WAGC,OAAQn/B,KAAKsiC,SAQZ,wCAAwCj2B,KAAMrM,KAAK6E,OAEnD0hC,MAAuBC,MAGzBD,EAED,IAAIE,IAAQ,EACXC,MACAC,GAAe7lC,EAAOkgC,aAAasF,KAI/BvmC,GAAOo/B,eACXr+B,EAAQf,GAASmqB,GAAI,SAAU,WAC9B,IAAM,GAAI/kB,KAAOuhC,IAChBA,GAAcvhC,GAAOhB,QAAW,KAMnCvD,EAAQgmC,OAASD,IAAkB,mBAAqBA,IACxDA,GAAe/lC,EAAQuiC,OAASwD,GAG3BA,IAEJ7lC,EAAOoiC,cAAc,SAAUt/B,GAE9B,IAAMA,EAAQghC,aAAehkC,EAAQgmC,KAAO,CAE3C,GAAIpkC,EAEJ,QACC0iC,KAAM,SAAUF,EAAS7L,GACxB,GAAIv2B,GACH0jC,EAAM1iC,EAAQ0iC,MACdr6B,IAAOw6B,EAMR,IAHAH,EAAIxH,KAAMl7B,EAAQiB,KAAMjB,EAAQy+B,IAAKz+B,EAAQw7B,MAAOx7B,EAAQijC,SAAUjjC,EAAQuR,UAGzEvR,EAAQkjC,UACZ,IAAMlkC,IAAKgB,GAAQkjC,UAClBR,EAAK1jC,GAAMgB,EAAQkjC,UAAWlkC,EAK3BgB,GAAQ29B,UAAY+E,EAAIlC,kBAC5BkC,EAAIlC,iBAAkBxgC,EAAQ29B,UAQzB39B,EAAQghC,aAAgBI,EAAQ,sBACrCA,EAAQ,oBAAsB,iBAI/B,KAAMpiC,IAAKoiC,GAOY7gC,SAAjB6gC,EAASpiC,IACb0jC,EAAIpC,iBAAkBthC,EAAGoiC,EAASpiC,GAAM,GAO1C0jC,GAAIpB,KAAQthC,EAAQkhC,YAAclhC,EAAQ4B,MAAU,MAGpDhD,EAAW,SAAUqI,EAAGk8B,GACvB,GAAIzC,GAAQE,EAAYrD,CAGxB,IAAK3+B,IAAcukC,GAA8B,IAAnBT,EAAIlnB,YAOjC,SALOsnB,IAAcz6B,GACrBzJ,EAAW2B,OACXmiC,EAAIU,mBAAqBlmC,EAAO6D,KAG3BoiC,EACoB,IAAnBT,EAAIlnB,YACRknB,EAAI/B,YAEC,CACNpD,KACAmD,EAASgC,EAAIhC,OAKoB,gBAArBgC,GAAIW,eACf9F,EAAUn7B,KAAOsgC,EAAIW,aAKtB,KACCzC,EAAa8B,EAAI9B,WAChB,MAAOn/B,GAERm/B,EAAa,GAQRF,IAAU1gC,EAAQ0+B,SAAY1+B,EAAQghC,YAGrB,OAAXN,IACXA,EAAS,KAHTA,EAASnD,EAAUn7B,KAAO,IAAM,IAS9Bm7B,GACJhI,EAAUmL,EAAQE,EAAYrD,EAAWmF,EAAIrC,0BAIzCrgC,EAAQw7B,MAGiB,IAAnBkH,EAAIlnB,WAGfR,WAAYpc,GAGZ8jC,EAAIU,mBAAqBN,GAAcz6B,GAAOzJ,EAP9CA,KAWF+hC,MAAO,WACD/hC,GACJA,EAAU2B,QAAW,OAS3B,SAASoiC,MACR,IACC,MAAO,IAAIxmC,GAAOmnC,eACjB,MAAO7hC,KAGV,QAASmhC,MACR,IACC,MAAO,IAAIzmC,GAAOo/B,cAAe,qBAChC,MAAO95B,KAOVvE,EAAOiiC,WACNN,SACC0E,OAAQ,6FAETztB,UACCytB,OAAQ,uBAET1F,YACC2F,cAAe,SAAUphC,GAExB,MADAlF,GAAOyE,WAAYS,GACZA,MAMVlF,EAAOmiC,cAAe,SAAU,SAAU/B,GACxB/8B,SAAZ+8B,EAAEj0B,QACNi0B,EAAEj0B,OAAQ,GAENi0B,EAAE0D,cACN1D,EAAEr8B,KAAO,MACTq8B,EAAE1hC,QAAS,KAKbsB,EAAOoiC,cAAe,SAAU,SAAShC,GAGxC,GAAKA,EAAE0D,YAAc,CAEpB,GAAIuC,GACHE,EAAOznC,EAASynC,MAAQvmC,EAAO,QAAQ,IAAMlB,EAAS2O,eAEvD,QAEC22B,KAAM,SAAUr6B,EAAGrI,GAElB2kC,EAASvnC,EAAS2N,cAAc,UAEhC45B,EAAO/H,OAAQ,EAEV8B,EAAEoG,gBACNH,EAAOI,QAAUrG,EAAEoG,eAGpBH,EAAO3jC,IAAM09B,EAAEmB,IAGf8E,EAAOK,OAASL,EAAOH,mBAAqB,SAAUn8B,EAAGk8B,IAEnDA,IAAYI,EAAO/nB,YAAc,kBAAkB/S,KAAM86B,EAAO/nB,eAGpE+nB,EAAOK,OAASL,EAAOH,mBAAqB,KAGvCG,EAAOn7B,YACXm7B,EAAOn7B,WAAWwB,YAAa25B,GAIhCA,EAAS,KAGHJ,GACLvkC,EAAU,IAAK,aAOlB6kC,EAAKjZ,aAAc+Y,EAAQE,EAAKj4B,aAGjCm1B,MAAO,WACD4C,GACJA,EAAOK,OAAQrjC,QAAW,OAU/B,IAAIsjC,OACHC,GAAS,mBAGV5mC,GAAOiiC,WACN4E,MAAO,WACPC,cAAe,WACd,GAAIplC,GAAWilC,GAAa3+B,OAAWhI,EAAOsD,QAAU,IAAQi6B,IAEhE,OADAr+B,MAAMwC,IAAa,EACZA,KAKT1B,EAAOmiC,cAAe,aAAc,SAAU/B,EAAG2G,EAAkBrH,GAElE,GAAIsH,GAAcC,EAAaC,EAC9BC,EAAW/G,EAAEyG,SAAU,IAAWD,GAAOr7B,KAAM60B,EAAEmB,KAChD,MACkB,gBAAXnB,GAAE17B,QAAwB07B,EAAEsB,aAAe,IAAKliC,QAAQ,sCAAwConC,GAAOr7B,KAAM60B,EAAE17B,OAAU,OAIlI,OAAKyiC,IAAiC,UAArB/G,EAAEZ,UAAW,IAG7BwH,EAAe5G,EAAE0G,cAAgB9mC,EAAOkD,WAAYk9B,EAAE0G,eACrD1G,EAAE0G,gBACF1G,EAAE0G,cAGEK,EACJ/G,EAAG+G,GAAa/G,EAAG+G,GAAW1jC,QAASmjC,GAAQ,KAAOI,GAC3C5G,EAAEyG,SAAU,IACvBzG,EAAEmB,MAAS/D,GAAOjyB,KAAM60B,EAAEmB,KAAQ,IAAM,KAAQnB,EAAEyG,MAAQ,IAAMG,GAIjE5G,EAAEO,WAAW,eAAiB,WAI7B,MAHMuG,IACLlnC,EAAO2D,MAAOqjC,EAAe,mBAEvBE,EAAmB,IAI3B9G,EAAEZ,UAAW,GAAM,OAGnByH,EAAchoC,EAAQ+nC,GACtB/nC,EAAQ+nC,GAAiB,WACxBE,EAAoBllC,WAIrB09B,EAAM3jB,OAAO,WAEZ9c,EAAQ+nC,GAAiBC,EAGpB7G,EAAG4G,KAEP5G,EAAE0G,cAAgBC,EAAiBD,cAGnCH,GAAapnC,KAAMynC,IAIfE,GAAqBlnC,EAAOkD,WAAY+jC,IAC5CA,EAAaC,EAAmB,IAGjCA,EAAoBD,EAAc5jC,SAI5B,UAtDR,SAgEDrD,EAAOuY,UAAY,SAAU7T,EAAMxE,EAASknC,GAC3C,IAAM1iC,GAAwB,gBAATA,GACpB,MAAO,KAEgB,kBAAZxE,KACXknC,EAAclnC,EACdA,GAAU,GAEXA,EAAUA,GAAWpB,CAErB,IAAIuoC,GAAStvB,EAAW/M,KAAMtG,GAC7BmoB,GAAWua,KAGZ,OAAKC,IACKnnC,EAAQuM,cAAe46B,EAAO,MAGxCA,EAASrnC,EAAO4sB,eAAiBloB,GAAQxE,EAAS2sB,GAE7CA,GAAWA,EAAQ9rB,QACvBf,EAAQ6sB,GAAUvR,SAGZtb,EAAOuB,SAAW8lC,EAAOh9B,aAKjC,IAAIi9B,IAAQtnC,EAAOG,GAAGynB,IAKtB5nB,GAAOG,GAAGynB,KAAO,SAAU2Z,EAAKgG,EAAQ7lC,GACvC,GAAoB,gBAAR6/B,IAAoB+F,GAC/B,MAAOA,IAAMvlC,MAAO7C,KAAM8C,UAG3B,IAAI/B,GAAU4gC,EAAU98B,EACvBoU,EAAOjZ,KACP8e,EAAMujB,EAAI/hC,QAAQ,IA+CnB,OA7CKwe,IAAO,IACX/d,EAAWshC,EAAIliC,MAAO2e,EAAKujB,EAAIxgC,QAC/BwgC,EAAMA,EAAIliC,MAAO,EAAG2e,IAIhBhe,EAAOkD,WAAYqkC,IAGvB7lC,EAAW6lC,EACXA,EAASlkC,QAGEkkC,GAA4B,gBAAXA,KAC5BxjC,EAAO,QAIHoU,EAAKpX,OAAS,GAClBf,EAAOqiC,MACNd,IAAKA,EAGLx9B,KAAMA,EACNw7B,SAAU,OACV76B,KAAM6iC,IACJjgC,KAAK,SAAU6+B,GAGjBtF,EAAW7+B,UAEXmW,EAAKuV,KAAMztB,EAIVD,EAAO,SAASmtB,OAAQntB,EAAOuY,UAAW4tB,IAAiB13B,KAAMxO,GAGjEkmC,KAEC9N,SAAU32B,GAAY,SAAUg+B,EAAO8D,GACzCrrB,EAAK1W,KAAMC,EAAUm/B,IAAcnB,EAAMyG,aAAc3C,EAAQ9D,MAI1DxgC,MAMRc,EAAO8P,KAAK2E,QAAQ+yB,SAAW,SAAU3lC,GACxC,MAAO7B,GAAO0F,KAAK1F,EAAOk5B,OAAQ,SAAU/4B,GAC3C,MAAO0B,KAAS1B,EAAG0B,OACjBd,OAOJ,IAAIgG,IAAU9H,EAAOH,SAAS2O,eAK9B,SAASg6B,IAAW5lC,GACnB,MAAO7B,GAAOiE,SAAUpC,GACvBA,EACkB,IAAlBA,EAAKyC,SACJzC,EAAKiM,aAAejM,EAAKwjB,cACzB,EAGHrlB,EAAO0nC,QACNC,UAAW,SAAU9lC,EAAMiB,EAAShB,GACnC,GAAI8lC,GAAaC,EAASC,EAAWC,EAAQC,EAAWC,EAAYC,EACnEhW,EAAWlyB,EAAOshB,IAAKzf,EAAM,YAC7BsmC,EAAUnoC,EAAQ6B,GAClB4kB,IAGiB,YAAbyL,IACJrwB,EAAK+c,MAAMsT,SAAW,YAGvB8V,EAAYG,EAAQT,SACpBI,EAAY9nC,EAAOshB,IAAKzf,EAAM,OAC9BomC,EAAajoC,EAAOshB,IAAKzf,EAAM,QAC/BqmC,GAAmC,aAAbhW,GAAwC,UAAbA,IAChDlyB,EAAOuF,QAAQ,QAAUuiC,EAAWG,IAAiB,GAGjDC,GACJN,EAAcO,EAAQjW,WACtB6V,EAASH,EAAY75B,IACrB85B,EAAUD,EAAY1X,OAEtB6X,EAAS5jC,WAAY2jC,IAAe,EACpCD,EAAU1jC,WAAY8jC,IAAgB,GAGlCjoC,EAAOkD,WAAYJ,KACvBA,EAAUA,EAAQ7B,KAAMY,EAAMC,EAAGkmC,IAGd,MAAfllC,EAAQiL,MACZ0Y,EAAM1Y,IAAQjL,EAAQiL,IAAMi6B,EAAUj6B,IAAQg6B,GAE1B,MAAhBjlC,EAAQotB,OACZzJ,EAAMyJ,KAASptB,EAAQotB,KAAO8X,EAAU9X,KAAS2X,GAG7C,SAAW/kC,GACfA,EAAQslC,MAAMnnC,KAAMY,EAAM4kB,GAE1B0hB,EAAQ7mB,IAAKmF,KAKhBzmB,EAAOG,GAAGsC,QACTilC,OAAQ,SAAU5kC,GACjB,GAAKd,UAAUjB,OACd,MAAmBsC,UAAZP,EACN5D,KACAA,KAAKuC,KAAK,SAAUK,GACnB9B,EAAO0nC,OAAOC,UAAWzoC,KAAM4D,EAAShB,IAI3C,IAAIiF,GAASshC,EACZC,GAAQv6B,IAAK,EAAGmiB,KAAM,GACtBruB,EAAO3C,KAAM,GACb0O,EAAM/L,GAAQA,EAAKkJ,aAEpB,IAAM6C,EAON,MAHA7G,GAAU6G,EAAIH,gBAGRzN,EAAOmH,SAAUJ,EAASlF,UAMpBA,GAAK0mC,wBAA0BzgC,IAC1CwgC,EAAMzmC,EAAK0mC,yBAEZF,EAAMZ,GAAW75B,IAEhBG,IAAKu6B,EAAIv6B,KAASs6B,EAAIG,aAAezhC,EAAQygB,YAAiBzgB,EAAQ0gB,WAAc,GACpFyI,KAAMoY,EAAIpY,MAASmY,EAAII,aAAe1hC,EAAQqgB,aAAiBrgB,EAAQsgB,YAAc,KAX9EihB,GAeTpW,SAAU,WACT,GAAMhzB,KAAM,GAAZ,CAIA,GAAIwpC,GAAchB,EACjBiB,GAAiB56B,IAAK,EAAGmiB,KAAM,GAC/BruB,EAAO3C,KAAM,EAwBd,OArBwC,UAAnCc,EAAOshB,IAAKzf,EAAM,YAEtB6lC,EAAS7lC,EAAK0mC,yBAGdG,EAAexpC,KAAKwpC,eAGpBhB,EAASxoC,KAAKwoC,SACR1nC,EAAO8E,SAAU4jC,EAAc,GAAK,UACzCC,EAAeD,EAAahB,UAI7BiB,EAAa56B,KAAQ/N,EAAOshB,IAAKonB,EAAc,GAAK,kBAAkB,GACtEC,EAAazY,MAAQlwB,EAAOshB,IAAKonB,EAAc,GAAK,mBAAmB,KAOvE36B,IAAM25B,EAAO35B,IAAO46B,EAAa56B,IAAM/N,EAAOshB,IAAKzf,EAAM,aAAa,GACtEquB,KAAMwX,EAAOxX,KAAOyY,EAAazY,KAAOlwB,EAAOshB,IAAKzf,EAAM,cAAc,MAI1E6mC,aAAc,WACb,MAAOxpC,MAAK0C,IAAI,WACf,GAAI8mC,GAAexpC,KAAKwpC,cAAgB3hC,EAExC,OAAQ2hC,IAAmB1oC,EAAO8E,SAAU4jC,EAAc,SAAuD,WAA3C1oC,EAAOshB,IAAKonB,EAAc,YAC/FA,EAAeA,EAAaA,YAE7B,OAAOA,IAAgB3hC,QAM1B/G,EAAOyB,MAAQ2lB,WAAY,cAAeI,UAAW,eAAiB,SAAUqc,EAAQ1d,GACvF,GAAIpY,GAAM,IAAIxC,KAAM4a,EAEpBnmB,GAAOG,GAAI0jC,GAAW,SAAU5zB,GAC/B,MAAOsR,GAAQriB,KAAM,SAAU2C,EAAMgiC,EAAQ5zB,GAC5C,GAAIo4B,GAAMZ,GAAW5lC,EAErB,OAAawB,UAAR4M,EACGo4B,EAAOliB,IAAQkiB,GAAOA,EAAKliB,GACjCkiB,EAAIvpC,SAAS2O,gBAAiBo2B,GAC9BhiC,EAAMgiC,QAGHwE,EACJA,EAAIO,SACF76B,EAAY/N,EAAQqoC,GAAMjhB,aAApBnX,EACPlC,EAAMkC,EAAMjQ,EAAQqoC,GAAM7gB,aAI3B3lB,EAAMgiC,GAAW5zB,IAEhB4zB,EAAQ5zB,EAAKjO,UAAUjB,OAAQ,SAQpCf,EAAOyB,MAAQ,MAAO,QAAU,SAAUK,EAAGqkB,GAC5CnmB,EAAOszB,SAAUnN,GAASoK,GAAczwB,EAAQyxB,cAC/C,SAAU1vB,EAAMguB,GACf,MAAKA,IACJA,EAAWH,GAAQ7tB,EAAMskB,GAElBqJ,GAAUjkB,KAAMskB,GACtB7vB,EAAQ6B,GAAOqwB,WAAY/L,GAAS,KACpC0J,GALF,WAaH7vB,EAAOyB,MAAQonC,OAAQ,SAAUC,MAAO,SAAW,SAAUjmC,EAAMkB,GAClE/D,EAAOyB,MAAQ0yB,QAAS,QAAUtxB,EAAM+oB,QAAS7nB,EAAM,GAAI,QAAUlB,GAAQ,SAAUkmC,EAAcC,GAEpGhpC,EAAOG,GAAI6oC,GAAa,SAAU9U,EAAQlvB,GACzC,GAAIwc,GAAYxf,UAAUjB,SAAYgoC,GAAkC,iBAAX7U,IAC5DjB,EAAQ8V,IAAkB7U,KAAW,GAAQlvB,KAAU,EAAO,SAAW,SAE1E,OAAOuc,GAAQriB,KAAM,SAAU2C,EAAMkC,EAAMiB,GAC1C,GAAI4I,EAEJ,OAAK5N,GAAOiE,SAAUpC,GAIdA,EAAK/C,SAAS2O,gBAAiB,SAAW5K,GAI3B,IAAlBhB,EAAKyC,UACTsJ,EAAM/L,EAAK4L,gBAIJlK,KAAKiC,IACX3D,EAAKgc,KAAM,SAAWhb,GAAQ+K,EAAK,SAAW/K,GAC9ChB,EAAKgc,KAAM,SAAWhb,GAAQ+K,EAAK,SAAW/K,GAC9C+K,EAAK,SAAW/K,KAIDQ,SAAV2B,EAENhF,EAAOshB,IAAKzf,EAAMkC,EAAMkvB,GAGxBjzB,EAAO4e,MAAO/c,EAAMkC,EAAMiB,EAAOiuB,IAChClvB,EAAMyd,EAAY0S,EAAS7wB,OAAWme,EAAW,WAOvDxhB,EAAOG,GAAG8oC,KAAO,WAChB,MAAO/pC,MAAK6B,QAGbf,EAAOG,GAAG+oC,QAAUlpC,EAAOG,GAAGuZ,QAYP,kBAAXyvB,SAAyBA,OAAOC,KAC3CD,OAAQ,YAAc,WACrB,MAAOnpC,IAOT,IAECqpC,IAAUpqC,EAAOe,OAGjBspC,GAAKrqC,EAAOsqC,CAwBb,OAtBAvpC,GAAOwpC,WAAa,SAAUvmC,GAS7B,MARKhE,GAAOsqC,IAAMvpC,IACjBf,EAAOsqC,EAAID,IAGPrmC,GAAQhE,EAAOe,SAAWA,IAC9Bf,EAAOe,OAASqpC,IAGVrpC,SAMIb,KAAa2I,IACxB7I,EAAOe,OAASf,EAAOsqC,EAAIvpC,GAMrBA"} \ No newline at end of file diff --git a/views/default/js/jquery.min.js b/views/default/js/jquery.min.js new file mode 100644 index 0000000..73f33fb --- /dev/null +++ b/views/default/js/jquery.min.js @@ -0,0 +1,4 @@ +/*! jQuery v1.11.0 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */ +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k="".trim,l={},m="1.11.0",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(n.isPlainObject(c)||(b=n.isArray(c)))?(b?(b=!1,f=a&&n.isArray(a)?a:[]):f=a&&n.isPlainObject(a)?a:{},g[d]=n.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray||function(a){return"array"===n.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return a-parseFloat(a)>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(l.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&n.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:k&&!k.call("\ufeff\xa0")?function(a){return null==a?"":k.call(a)}:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),n.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||n.guid++,e):void 0},now:function(){return+new Date},support:l}),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s="sizzle"+-new Date,t=a.document,u=0,v=0,w=eb(),x=eb(),y=eb(),z=function(a,b){return a===b&&(j=!0),0},A="undefined",B=1<<31,C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=D.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",M=L.replace("w","w#"),N="\\["+K+"*("+L+")"+K+"*(?:([*^$|!~]?=)"+K+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+M+")|)|)"+K+"*\\]",O=":("+L+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+N.replace(3,8)+")*)|.*)\\)|)",P=new RegExp("^"+K+"+|((?:^|[^\\\\])(?:\\\\.)*)"+K+"+$","g"),Q=new RegExp("^"+K+"*,"+K+"*"),R=new RegExp("^"+K+"*([>+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(O),U=new RegExp("^"+M+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L.replace("w","w*")+")"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=/'|\\/g,ab=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),bb=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{G.apply(D=H.call(t.childNodes),t.childNodes),D[t.childNodes.length].nodeType}catch(cb){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function db(a,b,d,e){var f,g,h,i,j,m,p,q,u,v;if((b?b.ownerDocument||b:t)!==l&&k(b),b=b||l,d=d||[],!a||"string"!=typeof a)return d;if(1!==(i=b.nodeType)&&9!==i)return[];if(n&&!e){if(f=Z.exec(a))if(h=f[1]){if(9===i){if(g=b.getElementById(h),!g||!g.parentNode)return d;if(g.id===h)return d.push(g),d}else if(b.ownerDocument&&(g=b.ownerDocument.getElementById(h))&&r(b,g)&&g.id===h)return d.push(g),d}else{if(f[2])return G.apply(d,b.getElementsByTagName(a)),d;if((h=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(h)),d}if(c.qsa&&(!o||!o.test(a))){if(q=p=s,u=b,v=9===i&&a,1===i&&"object"!==b.nodeName.toLowerCase()){m=ob(a),(p=b.getAttribute("id"))?q=p.replace(_,"\\$&"):b.setAttribute("id",q),q="[id='"+q+"'] ",j=m.length;while(j--)m[j]=q+pb(m[j]);u=$.test(a)&&mb(b.parentNode)||b,v=m.join(",")}if(v)try{return G.apply(d,u.querySelectorAll(v)),d}catch(w){}finally{p||b.removeAttribute("id")}}}return xb(a.replace(P,"$1"),b,d,e)}function eb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function fb(a){return a[s]=!0,a}function gb(a){var b=l.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function hb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function ib(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||B)-(~a.sourceIndex||B);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function jb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function kb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function lb(a){return fb(function(b){return b=+b,fb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function mb(a){return a&&typeof a.getElementsByTagName!==A&&a}c=db.support={},f=db.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},k=db.setDocument=function(a){var b,e=a?a.ownerDocument||a:t,g=e.defaultView;return e!==l&&9===e.nodeType&&e.documentElement?(l=e,m=e.documentElement,n=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){k()},!1):g.attachEvent&&g.attachEvent("onunload",function(){k()})),c.attributes=gb(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=gb(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(e.getElementsByClassName)&&gb(function(a){return a.innerHTML="<div class='a'></div><div class='a i'></div>",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=gb(function(a){return m.appendChild(a).id=s,!e.getElementsByName||!e.getElementsByName(s).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==A&&n){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ab,bb);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ab,bb);return function(a){var c=typeof a.getAttributeNode!==A&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==A?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==A&&n?b.getElementsByClassName(a):void 0},p=[],o=[],(c.qsa=Y.test(e.querySelectorAll))&&(gb(function(a){a.innerHTML="<select t=''><option selected=''></option></select>",a.querySelectorAll("[t^='']").length&&o.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||o.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll(":checked").length||o.push(":checked")}),gb(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&o.push("name"+K+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||o.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),o.push(",.*:")})),(c.matchesSelector=Y.test(q=m.webkitMatchesSelector||m.mozMatchesSelector||m.oMatchesSelector||m.msMatchesSelector))&&gb(function(a){c.disconnectedMatch=q.call(a,"div"),q.call(a,"[s!='']:x"),p.push("!=",O)}),o=o.length&&new RegExp(o.join("|")),p=p.length&&new RegExp(p.join("|")),b=Y.test(m.compareDocumentPosition),r=b||Y.test(m.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},z=b?function(a,b){if(a===b)return j=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===t&&r(t,a)?-1:b===e||b.ownerDocument===t&&r(t,b)?1:i?I.call(i,a)-I.call(i,b):0:4&d?-1:1)}:function(a,b){if(a===b)return j=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],k=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:i?I.call(i,a)-I.call(i,b):0;if(f===g)return ib(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)k.unshift(c);while(h[d]===k[d])d++;return d?ib(h[d],k[d]):h[d]===t?-1:k[d]===t?1:0},e):l},db.matches=function(a,b){return db(a,null,null,b)},db.matchesSelector=function(a,b){if((a.ownerDocument||a)!==l&&k(a),b=b.replace(S,"='$1']"),!(!c.matchesSelector||!n||p&&p.test(b)||o&&o.test(b)))try{var d=q.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return db(b,l,null,[a]).length>0},db.contains=function(a,b){return(a.ownerDocument||a)!==l&&k(a),r(a,b)},db.attr=function(a,b){(a.ownerDocument||a)!==l&&k(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!n):void 0;return void 0!==f?f:c.attributes||!n?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},db.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},db.uniqueSort=function(a){var b,d=[],e=0,f=0;if(j=!c.detectDuplicates,i=!c.sortStable&&a.slice(0),a.sort(z),j){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return i=null,a},e=db.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=db.selectors={cacheLength:50,createPseudo:fb,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ab,bb),a[3]=(a[4]||a[5]||"").replace(ab,bb),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||db.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&db.error(a[0]),a},PSEUDO:function(a){var b,c=!a[5]&&a[2];return V.CHILD.test(a[0])?null:(a[3]&&void 0!==a[4]?a[2]=a[4]:c&&T.test(c)&&(b=ob(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ab,bb).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=w[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&w(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==A&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=db.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),t=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&t){k=q[s]||(q[s]={}),j=k[a]||[],n=j[0]===u&&j[1],m=j[0]===u&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[u,n,m];break}}else if(t&&(j=(b[s]||(b[s]={}))[a])&&j[0]===u)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(t&&((l[s]||(l[s]={}))[a]=[u,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||db.error("unsupported pseudo: "+a);return e[s]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?fb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:fb(function(a){var b=[],c=[],d=g(a.replace(P,"$1"));return d[s]?fb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:fb(function(a){return function(b){return db(a,b).length>0}}),contains:fb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:fb(function(a){return U.test(a||"")||db.error("unsupported lang: "+a),a=a.replace(ab,bb).toLowerCase(),function(b){var c;do if(c=n?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===m},focus:function(a){return a===l.activeElement&&(!l.hasFocus||l.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:lb(function(){return[0]}),last:lb(function(a,b){return[b-1]}),eq:lb(function(a,b,c){return[0>c?c+b:c]}),even:lb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:lb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:lb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:lb(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=jb(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=kb(b);function nb(){}nb.prototype=d.filters=d.pseudos,d.setFilters=new nb;function ob(a,b){var c,e,f,g,h,i,j,k=x[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){(!c||(e=Q.exec(h)))&&(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=R.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(P," ")}),h=h.slice(c.length));for(g in d.filter)!(e=V[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?db.error(a):x(a,i).slice(0)}function pb(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function qb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=v++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[u,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[s]||(b[s]={}),(h=i[d])&&h[0]===u&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function rb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function sb(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function tb(a,b,c,d,e,f){return d&&!d[s]&&(d=tb(d)),e&&!e[s]&&(e=tb(e,f)),fb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||wb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:sb(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=sb(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?I.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=sb(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ub(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],i=g||d.relative[" "],j=g?1:0,k=qb(function(a){return a===b},i,!0),l=qb(function(a){return I.call(b,a)>-1},i,!0),m=[function(a,c,d){return!g&&(d||c!==h)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>j;j++)if(c=d.relative[a[j].type])m=[qb(rb(m),c)];else{if(c=d.filter[a[j].type].apply(null,a[j].matches),c[s]){for(e=++j;f>e;e++)if(d.relative[a[e].type])break;return tb(j>1&&rb(m),j>1&&pb(a.slice(0,j-1).concat({value:" "===a[j-2].type?"*":""})).replace(P,"$1"),c,e>j&&ub(a.slice(j,e)),f>e&&ub(a=a.slice(e)),f>e&&pb(a))}m.push(c)}return rb(m)}function vb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,i,j,k){var m,n,o,p=0,q="0",r=f&&[],s=[],t=h,v=f||e&&d.find.TAG("*",k),w=u+=null==t?1:Math.random()||.1,x=v.length;for(k&&(h=g!==l&&g);q!==x&&null!=(m=v[q]);q++){if(e&&m){n=0;while(o=a[n++])if(o(m,g,i)){j.push(m);break}k&&(u=w)}c&&((m=!o&&m)&&p--,f&&r.push(m))}if(p+=q,c&&q!==p){n=0;while(o=b[n++])o(r,s,g,i);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=E.call(j));s=sb(s)}G.apply(j,s),k&&!f&&s.length>0&&p+b.length>1&&db.uniqueSort(j)}return k&&(u=w,h=t),r};return c?fb(f):f}g=db.compile=function(a,b){var c,d=[],e=[],f=y[a+" "];if(!f){b||(b=ob(a)),c=b.length;while(c--)f=ub(b[c]),f[s]?d.push(f):e.push(f);f=y(a,vb(e,d))}return f};function wb(a,b,c){for(var d=0,e=b.length;e>d;d++)db(a,b[d],c);return c}function xb(a,b,e,f){var h,i,j,k,l,m=ob(a);if(!f&&1===m.length){if(i=m[0]=m[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&c.getById&&9===b.nodeType&&n&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(ab,bb),b)||[])[0],!b)return e;a=a.slice(i.shift().value.length)}h=V.needsContext.test(a)?0:i.length;while(h--){if(j=i[h],d.relative[k=j.type])break;if((l=d.find[k])&&(f=l(j.matches[0].replace(ab,bb),$.test(i[0].type)&&mb(b.parentNode)||b))){if(i.splice(h,1),a=f.length&&pb(i),!a)return G.apply(e,f),e;break}}}return g(a,m)(f,b,!n,e,$.test(a)&&mb(b.parentNode)||b),e}return c.sortStable=s.split("").sort(z).join("")===s,c.detectDuplicates=!!j,k(),c.sortDetached=gb(function(a){return 1&a.compareDocumentPosition(l.createElement("div"))}),gb(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||hb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&gb(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||hb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),gb(function(a){return null==a.getAttribute("disabled")})||hb(J,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),db}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return n.inArray(a,b)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;e>b;b++)if(n.contains(d[b],this))return!0}));for(b=0;e>b;b++)n.find(a,d[b],c);return c=this.pushStack(e>1?n.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=a.document,A=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,B=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:A.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:z,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=z.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return y.find(a);this.length=1,this[0]=d}return this.context=z,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};B.prototype=n.fn,y=n(z);var C=/^(?:parents|prev(?:Until|All))/,D={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!n(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b,c=n(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(n.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?"string"==typeof a?n.inArray(this[0],n(a)):n.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function E(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return E(a,"nextSibling")},prev:function(a){return E(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return n.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(D[a]||(e=n.unique(e)),C.test(a)&&(e=e.reverse())),this.pushStack(e)}});var F=/\S+/g,G={};function H(a){var b=G[a]={};return n.each(a.match(F)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?G[a]||H(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&n.each(arguments,function(a,c){var d;while((d=n.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){if(a===!0?!--n.readyWait:!n.isReady){if(!z.body)return setTimeout(n.ready);n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(z,[n]),n.fn.trigger&&n(z).trigger("ready").off("ready"))}}});function J(){z.addEventListener?(z.removeEventListener("DOMContentLoaded",K,!1),a.removeEventListener("load",K,!1)):(z.detachEvent("onreadystatechange",K),a.detachEvent("onload",K))}function K(){(z.addEventListener||"load"===event.type||"complete"===z.readyState)&&(J(),n.ready())}n.ready.promise=function(b){if(!I)if(I=n.Deferred(),"complete"===z.readyState)setTimeout(n.ready);else if(z.addEventListener)z.addEventListener("DOMContentLoaded",K,!1),a.addEventListener("load",K,!1);else{z.attachEvent("onreadystatechange",K),a.attachEvent("onload",K);var c=!1;try{c=null==a.frameElement&&z.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!n.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}J(),n.ready()}}()}return I.promise(b)};var L="undefined",M;for(M in n(l))break;l.ownLast="0"!==M,l.inlineBlockNeedsLayout=!1,n(function(){var a,b,c=z.getElementsByTagName("body")[0];c&&(a=z.createElement("div"),a.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",b=z.createElement("div"),c.appendChild(a).appendChild(b),typeof b.style.zoom!==L&&(b.style.cssText="border:0;margin:0;width:1px;padding:1px;display:inline;zoom:1",(l.inlineBlockNeedsLayout=3===b.offsetWidth)&&(c.style.zoom=1)),c.removeChild(a),a=b=null)}),function(){var a=z.createElement("div");if(null==l.deleteExpando){l.deleteExpando=!0;try{delete a.test}catch(b){l.deleteExpando=!1}}a=null}(),n.acceptData=function(a){var b=n.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(O,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}n.data(a,b,c)}else c=void 0}return c}function Q(a){var b;for(b in a)if(("data"!==b||!n.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function R(a,b,d,e){if(n.acceptData(a)){var f,g,h=n.expando,i=a.nodeType,j=i?n.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||n.guid++:h),j[k]||(j[k]=i?{}:{toJSON:n.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=n.extend(j[k],b):j[k].data=n.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[n.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[n.camelCase(b)])):f=g,f +}}function S(a,b,c){if(n.acceptData(a)){var d,e,f=a.nodeType,g=f?n.cache:a,h=f?a[n.expando]:n.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){n.isArray(b)?b=b.concat(n.map(b,n.camelCase)):b in d?b=[b]:(b=n.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!Q(d):!n.isEmptyObject(d))return}(c||(delete g[h].data,Q(g[h])))&&(f?n.cleanData([a],!0):l.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}n.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?n.cache[a[n.expando]]:a[n.expando],!!a&&!Q(a)},data:function(a,b,c){return R(a,b,c)},removeData:function(a,b){return S(a,b)},_data:function(a,b,c){return R(a,b,c,!0)},_removeData:function(a,b){return S(a,b,!0)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=n.data(f),1===f.nodeType&&!n._data(f,"parsedAttrs"))){c=g.length;while(c--)d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d]));n._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){n.data(this,a)}):arguments.length>1?this.each(function(){n.data(this,a,b)}):f?P(f,a,n.data(f,a)):void 0},removeData:function(a){return this.each(function(){n.removeData(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=n._data(a,b),c&&(!d||n.isArray(c)?d=n._data(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return n._data(a,c)||n._data(a,c,{empty:n.Callbacks("once memory").add(function(){n._removeData(a,b+"queue"),n._removeData(a,c)})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?n.queue(this[0],a):void 0===b?this:this.each(function(){var c=n.queue(this,a,b);n._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&n.dequeue(this,a)})},dequeue:function(a){return this.each(function(){n.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=n.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=n._data(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var T=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,U=["Top","Right","Bottom","Left"],V=function(a,b){return a=b||a,"none"===n.css(a,"display")||!n.contains(a.ownerDocument,a)},W=n.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)n.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},X=/^(?:checkbox|radio)$/i;!function(){var a=z.createDocumentFragment(),b=z.createElement("div"),c=z.createElement("input");if(b.setAttribute("className","t"),b.innerHTML=" <link/><table></table><a href='/a'>a</a>",l.leadingWhitespace=3===b.firstChild.nodeType,l.tbody=!b.getElementsByTagName("tbody").length,l.htmlSerialize=!!b.getElementsByTagName("link").length,l.html5Clone="<:nav></:nav>"!==z.createElement("nav").cloneNode(!0).outerHTML,c.type="checkbox",c.checked=!0,a.appendChild(c),l.appendChecked=c.checked,b.innerHTML="<textarea>x</textarea>",l.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,a.appendChild(b),b.innerHTML="<input type='radio' checked='checked' name='t'/>",l.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,l.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){l.noCloneEvent=!1}),b.cloneNode(!0).click()),null==l.deleteExpando){l.deleteExpando=!0;try{delete b.test}catch(d){l.deleteExpando=!1}}a=b=c=null}(),function(){var b,c,d=z.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(l[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),l[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var Y=/^(?:input|select|textarea)$/i,Z=/^key/,$=/^(?:mouse|contextmenu)|click/,_=/^(?:focusinfocus|focusoutblur)$/,ab=/^([^.]*)(?:\.(.+)|)$/;function bb(){return!0}function cb(){return!1}function db(){try{return z.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=n.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof n===L||a&&n.event.triggered===a.type?void 0:n.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(F)||[""],h=b.length;while(h--)f=ab.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=n.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=n.event.special[o]||{},l=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},i),(m=g[o])||(m=g[o]=[],m.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,l):m.push(l),n.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n.hasData(a)&&n._data(a);if(r&&(k=r.events)){b=(b||"").match(F)||[""],j=b.length;while(j--)if(h=ab.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=m.length;while(f--)g=m[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(m.splice(f,1),g.selector&&m.delegateCount--,l.remove&&l.remove.call(a,g));i&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(k)&&(delete r.handle,n._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,m,o=[d||z],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||z,3!==d.nodeType&&8!==d.nodeType&&!_.test(p+n.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[n.expando]?b:new n.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),k=n.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!n.isWindow(d)){for(i=k.delegateType||p,_.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||z)&&o.push(l.defaultView||l.parentWindow||a)}m=0;while((h=o[m++])&&!b.isPropagationStopped())b.type=m>1?i:k.bindType||p,f=(n._data(h,"events")||{})[b.type]&&n._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&n.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&n.acceptData(d)&&g&&d[p]&&!n.isWindow(d)){l=d[g],l&&(d[g]=null),n.event.triggered=p;try{d[p]()}catch(r){}n.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(n._data(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((n.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?n(c,this).index(i)>=0:n.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},fix:function(a){if(a[n.expando])return a;var b,c,d,e=a.type,f=a,g=this.fixHooks[e];g||(this.fixHooks[e]=g=$.test(e)?this.mouseHooks:Z.test(e)?this.keyHooks:{}),d=g.props?this.props.concat(g.props):this.props,a=new n.Event(f),b=d.length;while(b--)c=d[b],a[c]=f[c];return a.target||(a.target=f.srcElement||z),3===a.target.nodeType&&(a.target=a.target.parentNode),a.metaKey=!!a.metaKey,g.filter?g.filter(a,f):a},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,d,e,f=b.button,g=b.fromElement;return null==a.pageX&&null!=b.clientX&&(d=a.target.ownerDocument||z,e=d.documentElement,c=d.body,a.pageX=b.clientX+(e&&e.scrollLeft||c&&c.scrollLeft||0)-(e&&e.clientLeft||c&&c.clientLeft||0),a.pageY=b.clientY+(e&&e.scrollTop||c&&c.scrollTop||0)-(e&&e.clientTop||c&&c.clientTop||0)),!a.relatedTarget&&g&&(a.relatedTarget=g===a.target?b.toElement:g),a.which||void 0===f||(a.which=1&f?1:2&f?3:4&f?2:0),a}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==db()&&this.focus)try{return this.focus(),!1}catch(a){}},delegateType:"focusin"},blur:{trigger:function(){return this===db()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return n.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):void 0},_default:function(a){return n.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c,d){var e=n.extend(new n.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?n.event.trigger(e,null,b):n.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},n.removeEvent=z.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){var d="on"+b;a.detachEvent&&(typeof a[d]===L&&(a[d]=null),a.detachEvent(d,c))},n.Event=function(a,b){return this instanceof n.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&(a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault())?bb:cb):this.type=a,b&&n.extend(this,b),this.timeStamp=a&&a.timeStamp||n.now(),void(this[n.expando]=!0)):new n.Event(a,b)},n.Event.prototype={isDefaultPrevented:cb,isPropagationStopped:cb,isImmediatePropagationStopped:cb,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=bb,a&&(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=bb,a&&(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=bb,this.stopPropagation()}},n.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){n.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return(!e||e!==d&&!n.contains(d,e))&&(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),l.submitBubbles||(n.event.special.submit={setup:function(){return n.nodeName(this,"form")?!1:void n.event.add(this,"click._submit keypress._submit",function(a){var b=a.target,c=n.nodeName(b,"input")||n.nodeName(b,"button")?b.form:void 0;c&&!n._data(c,"submitBubbles")&&(n.event.add(c,"submit._submit",function(a){a._submit_bubble=!0}),n._data(c,"submitBubbles",!0))})},postDispatch:function(a){a._submit_bubble&&(delete a._submit_bubble,this.parentNode&&!a.isTrigger&&n.event.simulate("submit",this.parentNode,a,!0))},teardown:function(){return n.nodeName(this,"form")?!1:void n.event.remove(this,"._submit")}}),l.changeBubbles||(n.event.special.change={setup:function(){return Y.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(n.event.add(this,"propertychange._change",function(a){"checked"===a.originalEvent.propertyName&&(this._just_changed=!0)}),n.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1),n.event.simulate("change",this,a,!0)})),!1):void n.event.add(this,"beforeactivate._change",function(a){var b=a.target;Y.test(b.nodeName)&&!n._data(b,"changeBubbles")&&(n.event.add(b,"change._change",function(a){!this.parentNode||a.isSimulated||a.isTrigger||n.event.simulate("change",this.parentNode,a,!0)}),n._data(b,"changeBubbles",!0))})},handle:function(a){var b=a.target;return this!==b||a.isSimulated||a.isTrigger||"radio"!==b.type&&"checkbox"!==b.type?a.handleObj.handler.apply(this,arguments):void 0},teardown:function(){return n.event.remove(this,"._change"),!Y.test(this.nodeName)}}),l.focusinBubbles||n.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){n.event.simulate(b,a.target,n.event.fix(a),!0)};n.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=n._data(d,b);e||d.addEventListener(a,c,!0),n._data(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=n._data(d,b)-1;e?n._data(d,b,e):(d.removeEventListener(a,c,!0),n._removeData(d,b))}}}),n.fn.extend({on:function(a,b,c,d,e){var f,g;if("object"==typeof a){"string"!=typeof b&&(c=c||b,b=void 0);for(f in a)this.on(f,b,c,a[f],e);return this}if(null==c&&null==d?(d=b,c=b=void 0):null==d&&("string"==typeof b?(d=c,c=void 0):(d=c,c=b,b=void 0)),d===!1)d=cb;else if(!d)return this;return 1===e&&(g=d,d=function(a){return n().off(a),g.apply(this,arguments)},d.guid=g.guid||(g.guid=n.guid++)),this.each(function(){n.event.add(this,a,d,c,b)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,n(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return(b===!1||"function"==typeof b)&&(c=b,b=void 0),c===!1&&(c=cb),this.each(function(){n.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){n.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?n.event.trigger(a,b,c,!0):void 0}});function eb(a){var b=fb.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}var fb="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",gb=/ jQuery\d+="(?:null|\d+)"/g,hb=new RegExp("<(?:"+fb+")[\\s/>]","i"),ib=/^\s+/,jb=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,kb=/<([\w:]+)/,lb=/<tbody/i,mb=/<|&#?\w+;/,nb=/<(?:script|style|link)/i,ob=/checked\s*(?:[^=]|=\s*.checked.)/i,pb=/^$|\/(?:java|ecma)script/i,qb=/^true\/(.*)/,rb=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,sb={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:l.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]},tb=eb(z),ub=tb.appendChild(z.createElement("div"));sb.optgroup=sb.option,sb.tbody=sb.tfoot=sb.colgroup=sb.caption=sb.thead,sb.th=sb.td;function vb(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==L?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==L?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||n.nodeName(d,b)?f.push(d):n.merge(f,vb(d,b));return void 0===b||b&&n.nodeName(a,b)?n.merge([a],f):f}function wb(a){X.test(a.type)&&(a.defaultChecked=a.checked)}function xb(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function yb(a){return a.type=(null!==n.find.attr(a,"type"))+"/"+a.type,a}function zb(a){var b=qb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Ab(a,b){for(var c,d=0;null!=(c=a[d]);d++)n._data(c,"globalEval",!b||n._data(b[d],"globalEval"))}function Bb(a,b){if(1===b.nodeType&&n.hasData(a)){var c,d,e,f=n._data(a),g=n._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)n.event.add(b,c,h[c][d])}g.data&&(g.data=n.extend({},g.data))}}function Cb(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!l.noCloneEvent&&b[n.expando]){e=n._data(b);for(d in e.events)n.removeEvent(b,d,e.handle);b.removeAttribute(n.expando)}"script"===c&&b.text!==a.text?(yb(b).text=a.text,zb(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),l.html5Clone&&a.innerHTML&&!n.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&X.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}n.extend({clone:function(a,b,c){var d,e,f,g,h,i=n.contains(a.ownerDocument,a);if(l.html5Clone||n.isXMLDoc(a)||!hb.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(ub.innerHTML=a.outerHTML,ub.removeChild(f=ub.firstChild)),!(l.noCloneEvent&&l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(d=vb(f),h=vb(a),g=0;null!=(e=h[g]);++g)d[g]&&Cb(e,d[g]);if(b)if(c)for(h=h||vb(a),d=d||vb(f),g=0;null!=(e=h[g]);g++)Bb(e,d[g]);else Bb(a,f);return d=vb(f,"script"),d.length>0&&Ab(d,!i&&vb(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k,m=a.length,o=eb(b),p=[],q=0;m>q;q++)if(f=a[q],f||0===f)if("object"===n.type(f))n.merge(p,f.nodeType?[f]:f);else if(mb.test(f)){h=h||o.appendChild(b.createElement("div")),i=(kb.exec(f)||["",""])[1].toLowerCase(),k=sb[i]||sb._default,h.innerHTML=k[1]+f.replace(jb,"<$1></$2>")+k[2],e=k[0];while(e--)h=h.lastChild;if(!l.leadingWhitespace&&ib.test(f)&&p.push(b.createTextNode(ib.exec(f)[0])),!l.tbody){f="table"!==i||lb.test(f)?"<table>"!==k[1]||lb.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)n.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}n.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),l.appendChecked||n.grep(vb(p,"input"),wb),q=0;while(f=p[q++])if((!d||-1===n.inArray(f,d))&&(g=n.contains(f.ownerDocument,f),h=vb(o.appendChild(f),"script"),g&&Ab(h),c)){e=0;while(f=h[e++])pb.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=n.expando,j=n.cache,k=l.deleteExpando,m=n.event.special;null!=(d=a[h]);h++)if((b||n.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)m[e]?n.event.remove(d,e):n.removeEvent(d,e,g.handle);j[f]&&(delete j[f],k?delete d[i]:typeof d.removeAttribute!==L?d.removeAttribute(i):d[i]=null,c.push(f))}}}),n.fn.extend({text:function(a){return W(this,function(a){return void 0===a?n.text(this):this.empty().append((this[0]&&this[0].ownerDocument||z).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=xb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=xb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(vb(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&Ab(vb(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&n.cleanData(vb(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&n.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return W(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(gb,""):void 0;if(!("string"!=typeof a||nb.test(a)||!l.htmlSerialize&&hb.test(a)||!l.leadingWhitespace&&ib.test(a)||sb[(kb.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(jb,"<$1></$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(vb(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(vb(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,k=this.length,m=this,o=k-1,p=a[0],q=n.isFunction(p);if(q||k>1&&"string"==typeof p&&!l.checkClone&&ob.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(k&&(i=n.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=n.map(vb(i,"script"),yb),f=g.length;k>j;j++)d=i,j!==o&&(d=n.clone(d,!0,!0),f&&n.merge(g,vb(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,n.map(g,zb),j=0;f>j;j++)d=g[j],pb.test(d.type||"")&&!n._data(d,"globalEval")&&n.contains(h,d)&&(d.src?n._evalUrl&&n._evalUrl(d.src):n.globalEval((d.text||d.textContent||d.innerHTML||"").replace(rb,"")));i=c=null}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=0,e=[],g=n(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),n(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Db,Eb={};function Fb(b,c){var d=n(c.createElement(b)).appendTo(c.body),e=a.getDefaultComputedStyle?a.getDefaultComputedStyle(d[0]).display:n.css(d[0],"display");return d.detach(),e}function Gb(a){var b=z,c=Eb[a];return c||(c=Fb(a,b),"none"!==c&&c||(Db=(Db||n("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=(Db[0].contentWindow||Db[0].contentDocument).document,b.write(),b.close(),c=Fb(a,b),Db.detach()),Eb[a]=c),c}!function(){var a,b,c=z.createElement("div"),d="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;padding:0;margin:0;border:0";c.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",a=c.getElementsByTagName("a")[0],a.style.cssText="float:left;opacity:.5",l.opacity=/^0.5/.test(a.style.opacity),l.cssFloat=!!a.style.cssFloat,c.style.backgroundClip="content-box",c.cloneNode(!0).style.backgroundClip="",l.clearCloneStyle="content-box"===c.style.backgroundClip,a=c=null,l.shrinkWrapBlocks=function(){var a,c,e,f;if(null==b){if(a=z.getElementsByTagName("body")[0],!a)return;f="border:0;width:0;height:0;position:absolute;top:0;left:-9999px",c=z.createElement("div"),e=z.createElement("div"),a.appendChild(c).appendChild(e),b=!1,typeof e.style.zoom!==L&&(e.style.cssText=d+";width:1px;padding:1px;zoom:1",e.innerHTML="<div></div>",e.firstChild.style.width="5px",b=3!==e.offsetWidth),a.removeChild(c),a=c=e=null}return b}}();var Hb=/^margin/,Ib=new RegExp("^("+T+")(?!px)[a-z%]+$","i"),Jb,Kb,Lb=/^(top|right|bottom|left)$/;a.getComputedStyle?(Jb=function(a){return a.ownerDocument.defaultView.getComputedStyle(a,null)},Kb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Jb(a),g=c?c.getPropertyValue(b)||c[b]:void 0,c&&(""!==g||n.contains(a.ownerDocument,a)||(g=n.style(a,b)),Ib.test(g)&&Hb.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0===g?g:g+""}):z.documentElement.currentStyle&&(Jb=function(a){return a.currentStyle},Kb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Jb(a),g=c?c[b]:void 0,null==g&&h&&h[b]&&(g=h[b]),Ib.test(g)&&!Lb.test(b)&&(d=h.left,e=a.runtimeStyle,f=e&&e.left,f&&(e.left=a.currentStyle.left),h.left="fontSize"===b?"1em":g,g=h.pixelLeft+"px",h.left=d,f&&(e.left=f)),void 0===g?g:g+""||"auto"});function Mb(a,b){return{get:function(){var c=a();if(null!=c)return c?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d,e,f,g,h=z.createElement("div"),i="border:0;width:0;height:0;position:absolute;top:0;left:-9999px",j="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;padding:0;margin:0;border:0";h.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",b=h.getElementsByTagName("a")[0],b.style.cssText="float:left;opacity:.5",l.opacity=/^0.5/.test(b.style.opacity),l.cssFloat=!!b.style.cssFloat,h.style.backgroundClip="content-box",h.cloneNode(!0).style.backgroundClip="",l.clearCloneStyle="content-box"===h.style.backgroundClip,b=h=null,n.extend(l,{reliableHiddenOffsets:function(){if(null!=c)return c;var a,b,d,e=z.createElement("div"),f=z.getElementsByTagName("body")[0];if(f)return e.setAttribute("className","t"),e.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",a=z.createElement("div"),a.style.cssText=i,f.appendChild(a).appendChild(e),e.innerHTML="<table><tr><td></td><td>t</td></tr></table>",b=e.getElementsByTagName("td"),b[0].style.cssText="padding:0;margin:0;border:0;display:none",d=0===b[0].offsetHeight,b[0].style.display="",b[1].style.display="none",c=d&&0===b[0].offsetHeight,f.removeChild(a),e=f=null,c},boxSizing:function(){return null==d&&k(),d},boxSizingReliable:function(){return null==e&&k(),e},pixelPosition:function(){return null==f&&k(),f},reliableMarginRight:function(){var b,c,d,e;if(null==g&&a.getComputedStyle){if(b=z.getElementsByTagName("body")[0],!b)return;c=z.createElement("div"),d=z.createElement("div"),c.style.cssText=i,b.appendChild(c).appendChild(d),e=d.appendChild(z.createElement("div")),e.style.cssText=d.style.cssText=j,e.style.marginRight=e.style.width="0",d.style.width="1px",g=!parseFloat((a.getComputedStyle(e,null)||{}).marginRight),b.removeChild(c)}return g}});function k(){var b,c,h=z.getElementsByTagName("body")[0];h&&(b=z.createElement("div"),c=z.createElement("div"),b.style.cssText=i,h.appendChild(b).appendChild(c),c.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;position:absolute;display:block;padding:1px;border:1px;width:4px;margin-top:1%;top:1%",n.swap(h,null!=h.style.zoom?{zoom:1}:{},function(){d=4===c.offsetWidth}),e=!0,f=!1,g=!0,a.getComputedStyle&&(f="1%"!==(a.getComputedStyle(c,null)||{}).top,e="4px"===(a.getComputedStyle(c,null)||{width:"4px"}).width),h.removeChild(b),c=h=null)}}(),n.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var Nb=/alpha\([^)]*\)/i,Ob=/opacity\s*=\s*([^)]*)/,Pb=/^(none|table(?!-c[ea]).+)/,Qb=new RegExp("^("+T+")(.*)$","i"),Rb=new RegExp("^([+-])=("+T+")","i"),Sb={position:"absolute",visibility:"hidden",display:"block"},Tb={letterSpacing:0,fontWeight:400},Ub=["Webkit","O","Moz","ms"];function Vb(a,b){if(b in a)return b;var c=b.charAt(0).toUpperCase()+b.slice(1),d=b,e=Ub.length;while(e--)if(b=Ub[e]+c,b in a)return b;return d}function Wb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=n._data(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&V(d)&&(f[g]=n._data(d,"olddisplay",Gb(d.nodeName)))):f[g]||(e=V(d),(c&&"none"!==c||!e)&&n._data(d,"olddisplay",e?c:n.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}function Xb(a,b,c){var d=Qb.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Yb(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=n.css(a,c+U[f],!0,e)),d?("content"===c&&(g-=n.css(a,"padding"+U[f],!0,e)),"margin"!==c&&(g-=n.css(a,"border"+U[f]+"Width",!0,e))):(g+=n.css(a,"padding"+U[f],!0,e),"padding"!==c&&(g+=n.css(a,"border"+U[f]+"Width",!0,e)));return g}function Zb(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=Jb(a),g=l.boxSizing()&&"border-box"===n.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=Kb(a,b,f),(0>e||null==e)&&(e=a.style[b]),Ib.test(e))return e;d=g&&(l.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Yb(a,b,c||(g?"border":"content"),d,f)+"px"}n.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Kb(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":l.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=n.camelCase(b),i=a.style;if(b=n.cssProps[h]||(n.cssProps[h]=Vb(i,h)),g=n.cssHooks[b]||n.cssHooks[h],void 0===c)return g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b];if(f=typeof c,"string"===f&&(e=Rb.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(n.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||n.cssNumber[h]||(c+="px"),l.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),!(g&&"set"in g&&void 0===(c=g.set(a,c,d)))))try{i[b]="",i[b]=c}catch(j){}}},css:function(a,b,c,d){var e,f,g,h=n.camelCase(b);return b=n.cssProps[h]||(n.cssProps[h]=Vb(a.style,h)),g=n.cssHooks[b]||n.cssHooks[h],g&&"get"in g&&(f=g.get(a,!0,c)),void 0===f&&(f=Kb(a,b,d)),"normal"===f&&b in Tb&&(f=Tb[b]),""===c||c?(e=parseFloat(f),c===!0||n.isNumeric(e)?e||0:f):f}}),n.each(["height","width"],function(a,b){n.cssHooks[b]={get:function(a,c,d){return c?0===a.offsetWidth&&Pb.test(n.css(a,"display"))?n.swap(a,Sb,function(){return Zb(a,b,d)}):Zb(a,b,d):void 0},set:function(a,c,d){var e=d&&Jb(a);return Xb(a,c,d?Yb(a,b,d,l.boxSizing()&&"border-box"===n.css(a,"boxSizing",!1,e),e):0)}}}),l.opacity||(n.cssHooks.opacity={get:function(a,b){return Ob.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=n.isNumeric(b)?"alpha(opacity="+100*b+")":"",f=d&&d.filter||c.filter||"";c.zoom=1,(b>=1||""===b)&&""===n.trim(f.replace(Nb,""))&&c.removeAttribute&&(c.removeAttribute("filter"),""===b||d&&!d.filter)||(c.filter=Nb.test(f)?f.replace(Nb,e):f+" "+e)}}),n.cssHooks.marginRight=Mb(l.reliableMarginRight,function(a,b){return b?n.swap(a,{display:"inline-block"},Kb,[a,"marginRight"]):void 0}),n.each({margin:"",padding:"",border:"Width"},function(a,b){n.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+U[d]+b]=f[d]||f[d-2]||f[0];return e}},Hb.test(a)||(n.cssHooks[a+b].set=Xb)}),n.fn.extend({css:function(a,b){return W(this,function(a,b,c){var d,e,f={},g=0;if(n.isArray(b)){for(d=Jb(a),e=b.length;e>g;g++)f[b[g]]=n.css(a,b[g],!1,d);return f}return void 0!==c?n.style(a,b,c):n.css(a,b) +},a,b,arguments.length>1)},show:function(){return Wb(this,!0)},hide:function(){return Wb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){V(this)?n(this).show():n(this).hide()})}});function $b(a,b,c,d,e){return new $b.prototype.init(a,b,c,d,e)}n.Tween=$b,$b.prototype={constructor:$b,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(n.cssNumber[c]?"":"px")},cur:function(){var a=$b.propHooks[this.prop];return a&&a.get?a.get(this):$b.propHooks._default.get(this)},run:function(a){var b,c=$b.propHooks[this.prop];return this.pos=b=this.options.duration?n.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):$b.propHooks._default.set(this),this}},$b.prototype.init.prototype=$b.prototype,$b.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=n.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){n.fx.step[a.prop]?n.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[n.cssProps[a.prop]]||n.cssHooks[a.prop])?n.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},$b.propHooks.scrollTop=$b.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},n.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},n.fx=$b.prototype.init,n.fx.step={};var _b,ac,bc=/^(?:toggle|show|hide)$/,cc=new RegExp("^(?:([+-])=|)("+T+")([a-z%]*)$","i"),dc=/queueHooks$/,ec=[jc],fc={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=cc.exec(b),f=e&&e[3]||(n.cssNumber[a]?"":"px"),g=(n.cssNumber[a]||"px"!==f&&+d)&&cc.exec(n.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,n.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function gc(){return setTimeout(function(){_b=void 0}),_b=n.now()}function hc(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=U[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function ic(a,b,c){for(var d,e=(fc[b]||[]).concat(fc["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function jc(a,b,c){var d,e,f,g,h,i,j,k,m=this,o={},p=a.style,q=a.nodeType&&V(a),r=n._data(a,"fxshow");c.queue||(h=n._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,m.always(function(){m.always(function(){h.unqueued--,n.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=n.css(a,"display"),k=Gb(a.nodeName),"none"===j&&(j=k),"inline"===j&&"none"===n.css(a,"float")&&(l.inlineBlockNeedsLayout&&"inline"!==k?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",l.shrinkWrapBlocks()||m.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],bc.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||n.style(a,d)}if(!n.isEmptyObject(o)){r?"hidden"in r&&(q=r.hidden):r=n._data(a,"fxshow",{}),f&&(r.hidden=!q),q?n(a).show():m.done(function(){n(a).hide()}),m.done(function(){var b;n._removeData(a,"fxshow");for(b in o)n.style(a,b,o[b])});for(d in o)g=ic(q?r[d]:0,d,m),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function kc(a,b){var c,d,e,f,g;for(c in a)if(d=n.camelCase(c),e=b[d],f=a[c],n.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=n.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function lc(a,b,c){var d,e,f=0,g=ec.length,h=n.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=_b||gc(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:n.extend({},b),opts:n.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:_b||gc(),duration:c.duration,tweens:[],createTween:function(b,c){var d=n.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(kc(k,j.opts.specialEasing);g>f;f++)if(d=ec[f].call(j,a,k,j.opts))return d;return n.map(k,ic,j),n.isFunction(j.opts.start)&&j.opts.start.call(a,j),n.fx.timer(n.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}n.Animation=n.extend(lc,{tweener:function(a,b){n.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],fc[c]=fc[c]||[],fc[c].unshift(b)},prefilter:function(a,b){b?ec.unshift(a):ec.push(a)}}),n.speed=function(a,b,c){var d=a&&"object"==typeof a?n.extend({},a):{complete:c||!c&&b||n.isFunction(a)&&a,duration:a,easing:c&&b||b&&!n.isFunction(b)&&b};return d.duration=n.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in n.fx.speeds?n.fx.speeds[d.duration]:n.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){n.isFunction(d.old)&&d.old.call(this),d.queue&&n.dequeue(this,d.queue)},d},n.fn.extend({fadeTo:function(a,b,c,d){return this.filter(V).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=n.isEmptyObject(a),f=n.speed(b,c,d),g=function(){var b=lc(this,n.extend({},a),f);(e||n._data(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=n.timers,g=n._data(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&dc.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&n.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=n._data(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=n.timers,g=d?d.length:0;for(c.finish=!0,n.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),n.each(["toggle","show","hide"],function(a,b){var c=n.fn[b];n.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(hc(b,!0),a,d,e)}}),n.each({slideDown:hc("show"),slideUp:hc("hide"),slideToggle:hc("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){n.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),n.timers=[],n.fx.tick=function(){var a,b=n.timers,c=0;for(_b=n.now();c<b.length;c++)a=b[c],a()||b[c]!==a||b.splice(c--,1);b.length||n.fx.stop(),_b=void 0},n.fx.timer=function(a){n.timers.push(a),a()?n.fx.start():n.timers.pop()},n.fx.interval=13,n.fx.start=function(){ac||(ac=setInterval(n.fx.tick,n.fx.interval))},n.fx.stop=function(){clearInterval(ac),ac=null},n.fx.speeds={slow:600,fast:200,_default:400},n.fn.delay=function(a,b){return a=n.fx?n.fx.speeds[a]||a:a,b=b||"fx",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},function(){var a,b,c,d,e=z.createElement("div");e.setAttribute("className","t"),e.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",a=e.getElementsByTagName("a")[0],c=z.createElement("select"),d=c.appendChild(z.createElement("option")),b=e.getElementsByTagName("input")[0],a.style.cssText="top:1px",l.getSetAttribute="t"!==e.className,l.style=/top/.test(a.getAttribute("style")),l.hrefNormalized="/a"===a.getAttribute("href"),l.checkOn=!!b.value,l.optSelected=d.selected,l.enctype=!!z.createElement("form").enctype,c.disabled=!0,l.optDisabled=!d.disabled,b=z.createElement("input"),b.setAttribute("value",""),l.input=""===b.getAttribute("value"),b.value="t",b.setAttribute("type","radio"),l.radioValue="t"===b.value,a=b=c=d=e=null}();var mc=/\r/g;n.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=n.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,n(this).val()):a,null==e?e="":"number"==typeof e?e+="":n.isArray(e)&&(e=n.map(e,function(a){return null==a?"":a+""})),b=n.valHooks[this.type]||n.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=n.valHooks[e.type]||n.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(mc,""):null==c?"":c)}}}),n.extend({valHooks:{option:{get:function(a){var b=n.find.attr(a,"value");return null!=b?b:n.text(a)}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(l.optDisabled?c.disabled:null!==c.getAttribute("disabled"))||c.parentNode.disabled&&n.nodeName(c.parentNode,"optgroup"))){if(b=n(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=n.makeArray(b),g=e.length;while(g--)if(d=e[g],n.inArray(n.valHooks.option.get(d),f)>=0)try{d.selected=c=!0}catch(h){d.scrollHeight}else d.selected=!1;return c||(a.selectedIndex=-1),e}}}}),n.each(["radio","checkbox"],function(){n.valHooks[this]={set:function(a,b){return n.isArray(b)?a.checked=n.inArray(n(a).val(),b)>=0:void 0}},l.checkOn||(n.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var nc,oc,pc=n.expr.attrHandle,qc=/^(?:checked|selected)$/i,rc=l.getSetAttribute,sc=l.input;n.fn.extend({attr:function(a,b){return W(this,n.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){n.removeAttr(this,a)})}}),n.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===L?n.prop(a,b,c):(1===f&&n.isXMLDoc(a)||(b=b.toLowerCase(),d=n.attrHooks[b]||(n.expr.match.bool.test(b)?oc:nc)),void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=n.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void n.removeAttr(a,b))},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(F);if(f&&1===a.nodeType)while(c=f[e++])d=n.propFix[c]||c,n.expr.match.bool.test(c)?sc&&rc||!qc.test(c)?a[d]=!1:a[n.camelCase("default-"+c)]=a[d]=!1:n.attr(a,c,""),a.removeAttribute(rc?c:d)},attrHooks:{type:{set:function(a,b){if(!l.radioValue&&"radio"===b&&n.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),oc={set:function(a,b,c){return b===!1?n.removeAttr(a,c):sc&&rc||!qc.test(c)?a.setAttribute(!rc&&n.propFix[c]||c,c):a[n.camelCase("default-"+c)]=a[c]=!0,c}},n.each(n.expr.match.bool.source.match(/\w+/g),function(a,b){var c=pc[b]||n.find.attr;pc[b]=sc&&rc||!qc.test(b)?function(a,b,d){var e,f;return d||(f=pc[b],pc[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,pc[b]=f),e}:function(a,b,c){return c?void 0:a[n.camelCase("default-"+b)]?b.toLowerCase():null}}),sc&&rc||(n.attrHooks.value={set:function(a,b,c){return n.nodeName(a,"input")?void(a.defaultValue=b):nc&&nc.set(a,b,c)}}),rc||(nc={set:function(a,b,c){var d=a.getAttributeNode(c);return d||a.setAttributeNode(d=a.ownerDocument.createAttribute(c)),d.value=b+="","value"===c||b===a.getAttribute(c)?b:void 0}},pc.id=pc.name=pc.coords=function(a,b,c){var d;return c?void 0:(d=a.getAttributeNode(b))&&""!==d.value?d.value:null},n.valHooks.button={get:function(a,b){var c=a.getAttributeNode(b);return c&&c.specified?c.value:void 0},set:nc.set},n.attrHooks.contenteditable={set:function(a,b,c){nc.set(a,""===b?!1:b,c)}},n.each(["width","height"],function(a,b){n.attrHooks[b]={set:function(a,c){return""===c?(a.setAttribute(b,"auto"),c):void 0}}})),l.style||(n.attrHooks.style={get:function(a){return a.style.cssText||void 0},set:function(a,b){return a.style.cssText=b+""}});var tc=/^(?:input|select|textarea|button|object)$/i,uc=/^(?:a|area)$/i;n.fn.extend({prop:function(a,b){return W(this,n.prop,a,b,arguments.length>1)},removeProp:function(a){return a=n.propFix[a]||a,this.each(function(){try{this[a]=void 0,delete this[a]}catch(b){}})}}),n.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!n.isXMLDoc(a),f&&(b=n.propFix[b]||b,e=n.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=n.find.attr(a,"tabindex");return b?parseInt(b,10):tc.test(a.nodeName)||uc.test(a.nodeName)&&a.href?0:-1}}}}),l.hrefNormalized||n.each(["href","src"],function(a,b){n.propHooks[b]={get:function(a){return a.getAttribute(b,4)}}}),l.optSelected||(n.propHooks.selected={get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null}}),n.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){n.propFix[this.toLowerCase()]=this}),l.enctype||(n.propFix.enctype="encoding");var vc=/[\t\r\n\f]/g;n.fn.extend({addClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j="string"==typeof a&&a;if(n.isFunction(a))return this.each(function(b){n(this).addClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(F)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(vc," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=n.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j=0===arguments.length||"string"==typeof a&&a;if(n.isFunction(a))return this.each(function(b){n(this).removeClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(F)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(vc," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?n.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):this.each(n.isFunction(a)?function(c){n(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=n(this),f=a.match(F)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===L||"boolean"===c)&&(this.className&&n._data(this,"__className__",this.className),this.className=this.className||a===!1?"":n._data(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(vc," ").indexOf(b)>=0)return!0;return!1}}),n.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){n.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),n.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var wc=n.now(),xc=/\?/,yc=/(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;n.parseJSON=function(b){if(a.JSON&&a.JSON.parse)return a.JSON.parse(b+"");var c,d=null,e=n.trim(b+"");return e&&!n.trim(e.replace(yc,function(a,b,e,f){return c&&b&&(d=0),0===d?a:(c=e||b,d+=!f-!e,"")}))?Function("return "+e)():n.error("Invalid JSON: "+b)},n.parseXML=function(b){var c,d;if(!b||"string"!=typeof b)return null;try{a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b))}catch(e){c=void 0}return c&&c.documentElement&&!c.getElementsByTagName("parsererror").length||n.error("Invalid XML: "+b),c};var zc,Ac,Bc=/#.*$/,Cc=/([?&])_=[^&]*/,Dc=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Ec=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Fc=/^(?:GET|HEAD)$/,Gc=/^\/\//,Hc=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,Ic={},Jc={},Kc="*/".concat("*");try{Ac=location.href}catch(Lc){Ac=z.createElement("a"),Ac.href="",Ac=Ac.href}zc=Hc.exec(Ac.toLowerCase())||[];function Mc(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(F)||[];if(n.isFunction(c))while(d=f[e++])"+"===d.charAt(0)?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Nc(a,b,c,d){var e={},f=a===Jc;function g(h){var i;return e[h]=!0,n.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Oc(a,b){var c,d,e=n.ajaxSettings.flatOptions||{};for(d in b)void 0!==b[d]&&((e[d]?a:c||(c={}))[d]=b[d]);return c&&n.extend(!0,a,c),a}function Pc(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===e&&(e=a.mimeType||b.getResponseHeader("Content-Type"));if(e)for(g in h)if(h[g]&&h[g].test(e)){i.unshift(g);break}if(i[0]in c)f=i[0];else{for(g in c){if(!i[0]||a.converters[g+" "+i[0]]){f=g;break}d||(d=g)}f=f||d}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Qc(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}n.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Ac,type:"GET",isLocal:Ec.test(zc[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Kc,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":n.parseJSON,"text xml":n.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Oc(Oc(a,n.ajaxSettings),b):Oc(n.ajaxSettings,a)},ajaxPrefilter:Mc(Ic),ajaxTransport:Mc(Jc),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=n.ajaxSetup({},b),l=k.context||k,m=k.context&&(l.nodeType||l.jquery)?n(l):n.event,o=n.Deferred(),p=n.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!j){j={};while(b=Dc.exec(f))j[b[1].toLowerCase()]=b[2]}b=j[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?f:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return i&&i.abort(b),x(0,b),this}};if(o.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||Ac)+"").replace(Bc,"").replace(Gc,zc[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=n.trim(k.dataType||"*").toLowerCase().match(F)||[""],null==k.crossDomain&&(c=Hc.exec(k.url.toLowerCase()),k.crossDomain=!(!c||c[1]===zc[1]&&c[2]===zc[2]&&(c[3]||("http:"===c[1]?"80":"443"))===(zc[3]||("http:"===zc[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=n.param(k.data,k.traditional)),Nc(Ic,k,b,v),2===t)return v;h=k.global,h&&0===n.active++&&n.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!Fc.test(k.type),e=k.url,k.hasContent||(k.data&&(e=k.url+=(xc.test(e)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=Cc.test(e)?e.replace(Cc,"$1_="+wc++):e+(xc.test(e)?"&":"?")+"_="+wc++)),k.ifModified&&(n.lastModified[e]&&v.setRequestHeader("If-Modified-Since",n.lastModified[e]),n.etag[e]&&v.setRequestHeader("If-None-Match",n.etag[e])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",k.contentType),v.setRequestHeader("Accept",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+("*"!==k.dataTypes[0]?", "+Kc+"; q=0.01":""):k.accepts["*"]);for(d in k.headers)v.setRequestHeader(d,k.headers[d]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(d in{success:1,error:1,complete:1})v[d](k[d]);if(i=Nc(Jc,k,b,v)){v.readyState=1,h&&m.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,i.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,c,d){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),i=void 0,f=d||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,c&&(u=Pc(k,v,c)),u=Qc(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(n.lastModified[e]=w),w=v.getResponseHeader("etag"),w&&(n.etag[e]=w)),204===a||"HEAD"===k.type?x="nocontent":304===a?x="notmodified":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x="error",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+"",j?o.resolveWith(l,[r,x,v]):o.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,h&&m.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),h&&(m.trigger("ajaxComplete",[v,k]),--n.active||n.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return n.get(a,b,c,"json")},getScript:function(a,b){return n.get(a,void 0,b,"script")}}),n.each(["get","post"],function(a,b){n[b]=function(a,c,d,e){return n.isFunction(c)&&(e=e||d,d=c,c=void 0),n.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),n.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){n.fn[b]=function(a){return this.on(b,a)}}),n._evalUrl=function(a){return n.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},n.fn.extend({wrapAll:function(a){if(n.isFunction(a))return this.each(function(b){n(this).wrapAll(a.call(this,b))});if(this[0]){var b=n(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&1===a.firstChild.nodeType)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return this.each(n.isFunction(a)?function(b){n(this).wrapInner(a.call(this,b))}:function(){var b=n(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=n.isFunction(a);return this.each(function(c){n(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){n.nodeName(this,"body")||n(this).replaceWith(this.childNodes)}).end()}}),n.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0||!l.reliableHiddenOffsets()&&"none"===(a.style&&a.style.display||n.css(a,"display"))},n.expr.filters.visible=function(a){return!n.expr.filters.hidden(a)};var Rc=/%20/g,Sc=/\[\]$/,Tc=/\r?\n/g,Uc=/^(?:submit|button|image|reset|file)$/i,Vc=/^(?:input|select|textarea|keygen)/i;function Wc(a,b,c,d){var e;if(n.isArray(b))n.each(b,function(b,e){c||Sc.test(a)?d(a,e):Wc(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==n.type(b))d(a,b);else for(e in b)Wc(a+"["+e+"]",b[e],c,d)}n.param=function(a,b){var c,d=[],e=function(a,b){b=n.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=n.ajaxSettings&&n.ajaxSettings.traditional),n.isArray(a)||a.jquery&&!n.isPlainObject(a))n.each(a,function(){e(this.name,this.value)});else for(c in a)Wc(c,a[c],b,e);return d.join("&").replace(Rc,"+")},n.fn.extend({serialize:function(){return n.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=n.prop(this,"elements");return a?n.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!n(this).is(":disabled")&&Vc.test(this.nodeName)&&!Uc.test(a)&&(this.checked||!X.test(a))}).map(function(a,b){var c=n(this).val();return null==c?null:n.isArray(c)?n.map(c,function(a){return{name:b.name,value:a.replace(Tc,"\r\n")}}):{name:b.name,value:c.replace(Tc,"\r\n")}}).get()}}),n.ajaxSettings.xhr=void 0!==a.ActiveXObject?function(){return!this.isLocal&&/^(get|post|head|put|delete|options)$/i.test(this.type)&&$c()||_c()}:$c;var Xc=0,Yc={},Zc=n.ajaxSettings.xhr();a.ActiveXObject&&n(a).on("unload",function(){for(var a in Yc)Yc[a](void 0,!0)}),l.cors=!!Zc&&"withCredentials"in Zc,Zc=l.ajax=!!Zc,Zc&&n.ajaxTransport(function(a){if(!a.crossDomain||l.cors){var b;return{send:function(c,d){var e,f=a.xhr(),g=++Xc;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)void 0!==c[e]&&f.setRequestHeader(e,c[e]+"");f.send(a.hasContent&&a.data||null),b=function(c,e){var h,i,j;if(b&&(e||4===f.readyState))if(delete Yc[g],b=void 0,f.onreadystatechange=n.noop,e)4!==f.readyState&&f.abort();else{j={},h=f.status,"string"==typeof f.responseText&&(j.text=f.responseText);try{i=f.statusText}catch(k){i=""}h||!a.isLocal||a.crossDomain?1223===h&&(h=204):h=j.text?200:404}j&&d(h,i,j,f.getAllResponseHeaders())},a.async?4===f.readyState?setTimeout(b):f.onreadystatechange=Yc[g]=b:b()},abort:function(){b&&b(void 0,!0)}}}});function $c(){try{return new a.XMLHttpRequest}catch(b){}}function _c(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}n.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return n.globalEval(a),a}}}),n.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),n.ajaxTransport("script",function(a){if(a.crossDomain){var b,c=z.head||n("head")[0]||z.documentElement;return{send:function(d,e){b=z.createElement("script"),b.async=!0,a.scriptCharset&&(b.charset=a.scriptCharset),b.src=a.url,b.onload=b.onreadystatechange=function(a,c){(c||!b.readyState||/loaded|complete/.test(b.readyState))&&(b.onload=b.onreadystatechange=null,b.parentNode&&b.parentNode.removeChild(b),b=null,c||e(200,"success"))},c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(void 0,!0)}}}});var ad=[],bd=/(=)\?(?=&|$)|\?\?/;n.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=ad.pop()||n.expando+"_"+wc++;return this[a]=!0,a}}),n.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(bd.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&bd.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=n.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(bd,"$1"+e):b.jsonp!==!1&&(b.url+=(xc.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||n.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,ad.push(e)),g&&n.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),n.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||z;var d=v.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=n.buildFragment([a],b,e),e&&e.length&&n(e).remove(),n.merge([],d.childNodes))};var cd=n.fn.load;n.fn.load=function(a,b,c){if("string"!=typeof a&&cd)return cd.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=a.slice(h,a.length),a=a.slice(0,h)),n.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(f="POST"),g.length>0&&n.ajax({url:a,type:f,dataType:"html",data:b}).done(function(a){e=arguments,g.html(d?n("<div>").append(n.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,e||[a.responseText,b,a])}),this},n.expr.filters.animated=function(a){return n.grep(n.timers,function(b){return a===b.elem}).length};var dd=a.document.documentElement;function ed(a){return n.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}n.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=n.css(a,"position"),l=n(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=n.css(a,"top"),i=n.css(a,"left"),j=("absolute"===k||"fixed"===k)&&n.inArray("auto",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),n.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},n.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){n.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,n.contains(b,e)?(typeof e.getBoundingClientRect!==L&&(d=e.getBoundingClientRect()),c=ed(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return"fixed"===n.css(d,"position")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),n.nodeName(a[0],"html")||(c=a.offset()),c.top+=n.css(a[0],"borderTopWidth",!0),c.left+=n.css(a[0],"borderLeftWidth",!0)),{top:b.top-c.top-n.css(d,"marginTop",!0),left:b.left-c.left-n.css(d,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||dd;while(a&&!n.nodeName(a,"html")&&"static"===n.css(a,"position"))a=a.offsetParent;return a||dd})}}),n.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c=/Y/.test(b);n.fn[a]=function(d){return W(this,function(a,d,e){var f=ed(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?n(f).scrollLeft():e,c?e:n(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),n.each(["top","left"],function(a,b){n.cssHooks[b]=Mb(l.pixelPosition,function(a,c){return c?(c=Kb(a,b),Ib.test(c)?n(a).position()[b]+"px":c):void 0})}),n.each({Height:"height",Width:"width"},function(a,b){n.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){n.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return W(this,function(b,c,d){var e;return n.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?n.css(b,c,g):n.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),n.fn.size=function(){return this.length},n.fn.andSelf=n.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return n});var fd=a.jQuery,gd=a.$;return n.noConflict=function(b){return a.$===n&&(a.$=gd),b&&a.jQuery===n&&(a.jQuery=fd),n},typeof b===L&&(a.jQuery=a.$=n),n}); diff --git a/views/default/js/npm.js b/views/default/js/npm.js new file mode 100644 index 0000000..bf6aa80 --- /dev/null +++ b/views/default/js/npm.js @@ -0,0 +1,13 @@ +// This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment. +require('../../js/transition.js') +require('../../js/alert.js') +require('../../js/button.js') +require('../../js/carousel.js') +require('../../js/collapse.js') +require('../../js/dropdown.js') +require('../../js/modal.js') +require('../../js/tooltip.js') +require('../../js/popover.js') +require('../../js/scrollspy.js') +require('../../js/tab.js') +require('../../js/affix.js') \ No newline at end of file diff --git a/views/default/login.php b/views/default/login.php new file mode 100644 index 0000000..26e6838 --- /dev/null +++ b/views/default/login.php @@ -0,0 +1,34 @@ +<?php include ROOT . TMPL . 'header.php'; ?> +<section> + <div class="container"> + <div class="row"> + <?php if(user::checkAuth() == false): ?> + <div class="col-sm-4 col-sm-offset-4 padding-right"> + <div class="signup-form"><!--sign up form--> + <h2>Вход на сайт</h2> + <form action="#" method="post"> + <input type="text" name="login" placeholder="login" value=""/> + <input type="password" name="password" placeholder="Пароль" value=""/> + <input type="submit" name="submit" class="btn btn-default" value="Вход" /> + </form> + </div><!--/sign up form--> + <br/> + <br/> + </div> + <?php else: ?> + <div class="col-sm-6 col-sm-offset-3 padding-right"> + <div class="panel panel-warning"> + <div class="panel-heading"> + <h3 class="panel-title">Warning!!!</h3> + </div> + <div class="panel-body text-center"> + <h3>Привет <?php echo $_SESSION['surname']; ?>. Вы уже авторизованы</h3> + <p>Хотите выйти?<a href="./logout">Да, хочу</a></p> + </div> + </div> + </div> + <?php endif; ?> + </div> + </div> +</section> +<?php include ROOT . TMPL . 'footer.php'; ?> \ No newline at end of file diff --git a/views/default/phonebook.php b/views/default/phonebook.php new file mode 100644 index 0000000..9b72fc7 --- /dev/null +++ b/views/default/phonebook.php @@ -0,0 +1,26 @@ +<?php include ROOT . TMPL . 'header.php'; ?> +<p class="text-center"> + <a href="save" class="btn btn-success btn-lg"><i class="glyphicon glyphicon-floppy-disk" aria-hidden="true"></i> Скачать в excel</a> +</p> +<div class = "table-responsive"> +<table class="table table-hover text-center" style="vertical-align: middle;"> + <thead> + </thead> + <tbody> + <?php foreach($list as $key => $value): ?> + <tr> + <th colspan="3" class="success"><?php echo $key ?></th> + </tr> + <?php for($i=0; count($value) > $i; $i++): ?> + <tr> + <td style="min-width: 200px; vertical-align: middle;"><?php echo $value[$i]['name']; ?></td> + <td><?php echo $value[$i]['number']; ?></td> + <td><?php echo $value[$i]['post']; ?></td> + </tr> + <?php endfor; ?> + <?php endforeach; ?> + </tbody> +</table> +</div> + +<?php include ROOT . TMPL . 'footer.php'; ?> \ No newline at end of file diff --git a/views/default/phonebook_admsearch.php b/views/default/phonebook_admsearch.php new file mode 100644 index 0000000..bace975 --- /dev/null +++ b/views/default/phonebook_admsearch.php @@ -0,0 +1,113 @@ +<?php include ROOT . TMPL . 'header.php'; ?> +<!-- HTML-код модального окна --> +<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true"> + <div class="modal-dialog" role="document"> + <div class="modal-content"> + <div class="modal-header"> + <button type="button" class="close" data-dismiss="modal" aria-label="Close"> + <span aria-hidden="true">&times;</span> + </button> + <h4 class="modal-title" id="exampleModalLabel">Редактирование записи</h4> + </div> + <div class="modal-body"> + <form action="update" method="post"> + <div class="form-group"> + <input type="hidden" class="form-control" name="id" id="id"> + + <label for="name" class="form-control-label">Имя:</label> + <input type="text" class="form-control" id="name" name="name"> + + <label for="post" class="form-control-label">Должность:</label> + <input type="text" class="form-control" id="post" name="post"> + + <label for="number" class="form-control-label">Телефон:</label> + <input type="text" class="form-control" id="number" name="number"> + + <label for="mac" class="form-control-label">Mac-адрес:</label> + <input type="text" class="form-control" id="mac" name="mac"> + + <label for="department" class="form-control-label">Отдел:</label> + <select class="form-control" name="department" id="department" name="department"> + <option selected>Отдел</option> + <?php foreach($departments as $dep): ?> + <option value="<?php echo $dep['id']; ?>"><?php echo $dep['department']; ?></option> + <?php endforeach; ?> + </select> + + <label for="parent_id" class="form-control-label">Руководитель:</label> + <select class="form-control" name="parent_id" id="parent_id" name="parent_id"> + <option selected value="0">Руководитель</option> + <?php foreach($parents as $parent): ?> + <option value="<?php echo $parent['id']; ?>"><?php echo $parent['name']; ?></option> + <?php endforeach; ?> + </select> + + <label for="subord" class="form-control-label">Ранг:</label> + <select class="form-control" name="subord" id="subord" name="subord"> + <option selected>Ранг</option> + <?php foreach($subardination as $subard): ?> + <option value="<?php echo $subard['id']; ?>"><?php echo $subard['subordination']; ?></option> + <?php endforeach; ?> + </select> + + <label for="login" class="form-control-label">Логин:</label> + <input type="text" class="form-control" id="login" name="login"> + + <div class="checkbox"><label><input type="checkbox" name="activ" id="activ"> Активный </label></div><br> + + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> + <button type="submit" class="btn btn-primary" name="save">Сохранить</button> + </div> + </form> + </div> + </div> + </div> + </div> + +<?php if($error == false): ?> + <form action="" method="post"> + <div class="row"> + <div class="col-xs-offset-2 col-xs-7"> + <input type="text" class="form-control" name="searching" placeholder="Напишите фамилию или номер телефона, можно часть..." <?php if(isset($_POST['searching'])) echo "value='".$_POST['searching']."'"; ?>> + </div> + <div class="col-xs-3"> + <button type="submit" name="submit" class="btn btn-primary">Выбрать</button> + </div> + </div> + </form> + <br /> + + <div class = "search_result table-responsive"> + <table class="table table-hover text-center" style="vertical-align: middle;"> + <tbody> + <?php for($i=0; count($list) > $i; $i++): ?> + <tr> + <!--<td><a href="<?php //DOMEN; ?>/phonebook/admedit/<?php //echo $list[$i]['id']; ?>" ><i class="fa fa-edit"></i></a></td>--> + <td><button type="button" class="btn btn-link" data-toggle="modal" data-target="#exampleModal" data-whatever='<?php echo json_encode(Phonebook::getElementByID($list[$i]['id'])); ?>'><i class="fa fa-cogs" aria-hidden="true"></i></button></td> + <td style="min-width: 200px; vertical-align: middle;"><?php echo $list[$i]['name']; ?></td> + <td style="vertical-align: middle;"><?php echo $list[$i]['number']; ?></td> + <td style="vertical-align: middle;"><?php echo $list[$i]['mac']; ?></td> + <td><?php echo $list[$i]['post']; ?></td> + <td><a href="<?php DOMEN; ?>/phonebook/admactiv/<?php echo $list[$i]['id']; ?>" > <i <?php echo ($list[$i]['activ'] == 0) ? 'class="fa fa-times" style="font-size:20px; color:#cc0000 "' : "class='fa fa-check'"; ?>></i></a></td> + </tr> + <?php endfor; ?> + </tbody> + </table> + </div> + + + +<?php else: ?> + <div class="panel panel-danger col-xs-offset-4 col-xs-4"> + <div class="panel-heading"> + <h3 class="panel-title">Error!!!</h3> + </div> + <div class="panel-body"> + Ошибка доступа + </div> + </div> +<?php endif; ?> +<?php include ROOT . TMPL . 'footer.php'; ?> + diff --git a/views/default/phonebook_edit.php b/views/default/phonebook_edit.php new file mode 100644 index 0000000..662e63e --- /dev/null +++ b/views/default/phonebook_edit.php @@ -0,0 +1,67 @@ +<?php include ROOT . TMPL . 'header.php'; ?> + + <div class="row"> + + <?php if($message != false): ?> + <?php if($message == "Good"): ?> + <!-- Сообщение об успешном выполнения действия --> + <div class="alert alert-success"> + <!-- Кнопка для закрытия сообщения, созданная с помощью элемента button --> + <button type="button" class="close" data-dismiss="alert">×</button> + Изменения сохранены. + </div> + + <?php else: ?> + <!-- Сообщение об ошибке --> + <div class="alert alert-danger"> + <!-- Кнопка для закрытия сообщения, созданная с помощью элемента a --> + <a href="#" class="close" data-dismiss="alert">×</a> + Неизвестная ошибка при передаче данных. + </div> + <?php endif; ?> + <?php endif; ?> + <form action="" method="post"> + <div class="row"> + <div class="col-md-4"> + <input type="hidden" name="id" value="<?php echo $info['id']; ?>"> + <input type="text" class="form-control" name="id" placeholder="id" value="<?php echo $info['id']; ?>" disabled=""><br> + <input type="text" class="form-control" name="name" placeholder="Name" value="<?php echo $info['name']; ?>"><br> + <input type="text" class="form-control" name="number" placeholder="#Unit" value="<?php echo $info['number']; ?>"><br> + <input type="text" class="form-control" name="mac" placeholder="Model" value="<?php echo $info['mac']; ?>"><br> + + </div> + <div class="col-md-4"> + <select class="form-control" name="parent_id" > + <option selected value="0">Руководитель</option> + <?php foreach($parents as $parent): ?> + <option value="<?php echo $parent['id']; ?>" <?php if($info['parent_id'] == $parent['id']) echo "selected"; ?>><?php echo $parent['name']; ?></option> + <?php endforeach; ?> + </select><br> + <select class="form-control" name="subord" > + <option selected>Ранг</option> + <?php foreach($subardination as $subard): ?> + <option value="<?php echo $subard['id']; ?>" <?php if($info['subordination'] == $subard['id']) echo "selected"; ?>><?php echo $subard['subordination']; ?></option> + <?php endforeach; ?> + </select><br> + <select class="form-control" name="department" > + <option selected>Отдел</option> + <?php foreach($departments as $dep): ?> + <option value="<?php echo $dep['id']; ?>" <?php if($info['department'] == $dep['id']) echo "selected"; ?>><?php echo $dep['department']; ?></option> + <?php endforeach; ?> + </select><br> + <input type="text" class="form-control" name="login" placeholder="login" value="<?php echo $info['login']; ?>"><br> + </div> + <div class="col-md-4"> + <textarea type="text" rows="5" class="form-control" name="post" placeholder="Должность"><?php echo $info['post']; ?></textarea><br> + <div class="checkbox"><label><input type="checkbox"name="activ" <?php if($info['activ'] == 1) echo "checked"; ?>> Активный </label></div><br> + </div> + </div> + <br> + <button type="submit" name="save" class="btn btn-primary">Сохранить</button> + </form> + </div> + + + <hr> + <br> +<?php include ROOT . TMPL . 'footer.php'; ?> \ No newline at end of file diff --git a/views/default/phonebook_search.php b/views/default/phonebook_search.php new file mode 100644 index 0000000..cc852e4 --- /dev/null +++ b/views/default/phonebook_search.php @@ -0,0 +1,51 @@ +<?php include ROOT . TMPL . 'header.php'; ?> +<form action="" method="post"> + <div class="row"> + <div class="col-xs-offset-2 col-xs-7"> + <input type="text" class="form-control" name="searching" placeholder="Напишите фамилию или номер телефона, можно часть..." <?php if(isset($_POST['searching'])) echo "value='".$_POST['searching']."'"; ?>> + </div> + <div class="col-xs-3"> + <button type="submit" name="submit" class="btn btn-primary">Выбрать</button> + </div> + </div> +</form> + <br /> + +<?php if(!isset($value)): ?> + <div class="panel panel-primary col-xs-offset-4 col-xs-4"> + <div class="panel-heading"> + <h3 class="panel-title">Внимание!</h3> + </div> + <div class="panel-body"> + Здесь появится результат поиска + </div> + </div> +<?php elseif(isset($value) && !empty($value)): ?> +<div class = "search_result table-responsive"> +<table class="table table-hover text-center" style="vertical-align: middle;"> + <tbody> + <?php for($i=0; count($value) > $i; $i++): ?> + <tr> + <td style="min-width: 200px; vertical-align: middle;"><?php echo $value[$i]['name']; ?></td> + <td><?php echo $value[$i]['number']; ?></td> + <td><?php echo $value[$i]['post']; ?></td> + <td><?php echo $value[$i]['department']; ?></td> + </tr> + <?php endfor; ?> + </tbody> +</table> +</div> +<?php else: ?> + <div class="panel panel-danger col-xs-offset-4 col-xs-4"> + <div class="panel-heading"> + <h3 class="panel-title">Error!!!</h3> + </div> + <div class="panel-body"> + По введенным параметрам ничего не найдено + </div> + </div> +<?php endif; ?> + + +<?php include ROOT . TMPL . 'footer.php'; ?> + diff --git a/views/default/printedit.html b/views/default/printedit.html new file mode 100644 index 0000000..1ab16ed --- /dev/null +++ b/views/default/printedit.html @@ -0,0 +1,129 @@ +<!DOCTYPE html> +<html lang="ru"> + <head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <title>Home</title> + + <!-- Bootstrap --> + <link href="css/bootstrap.css" rel="stylesheet"> + <link rel="stylesheet" href="css/font-awesome.css"> + <link href="css/bootstrap-responsive.css" rel="stylesheet"> + <link href="css/footer.css" rel="stylesheet"> + <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries --> + <!-- WARNING: Respond.js doesn't work if you view the page via file:// --> + <!--[if lt IE 9]> + <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> + <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script> + <![endif]--> + </head> + <body> + <div class="container"> + <header> + <nav role="navigation" class="navbar navbar-default"> + <!-- Brand and toggle get grouped for better mobile display --> + <div class="navbar-header"> + <button type="button" data-target="#navbarCollapse" data-toggle="collapse" class="navbar-toggle"> + <span class="sr-only">Toggle navigation</span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + <a href="#" class="navbar-brand">Бренд</a> + </div> + <!-- Collection of nav links, forms, and other content for toggling --> + <div id="navbarCollapse" class="collapse navbar-collapse"> + <ul class="nav navbar-nav"> + <li class="active"><a href="#">Главная</a></li> + <li class="dropdown"> + <a data-toggle="dropdown" class="dropdown-toggle" href="#"><i class="fa fa-paint-brush" aria-hidden="true"></i> Cartriges <b class="caret"></b></a> + <ul role="menu" class="dropdown-menu"> + <li><a href="#">add</a></li> + <li><a href="#">Remove</a></li> + <li><a href="#">order</a></li> + <li><a href="#">hestory</a></li> + </ul> + </li> + <li class="dropdown"> + <a data-toggle="dropdown" class="dropdown-toggle" href="#"><i class="fa fa-print" aria-hidden="true"></i> Prints <b class="caret"></b></a> + <ul role="menu" class="dropdown-menu"> + <li><a href="#">search</a></li> + <li><a href="#">add</a></li> + <li><a href="#">edit</a></li> + <li class="divider"></li> + <li><a href="#">delete</a></li> + </ul> + </li> + <li class="dropdown"> + <a data-toggle="dropdown" class="dropdown-toggle" href="#"><i class="fa fa-wrench" aria-hidden="true"></i> Unit <b class="caret"></b></a> + <ul role="menu" class="dropdown-menu"> + <li><a href="#">history requests</a></li> + <li><a href="#">history repairs</a></li> + <li><a href="#">create requests</a></li> + <li class="divider"></li> + <li><a href="#">doc stor</a></li> + </ul> + </li> + </ul> + <ul class="nav navbar-nav navbar-right"> + <li><a href="#"><i class="fa fa-lock" aria-hidden="true"></i> Войти / <i class="fa fa-sign-out" aria-hidden="true"></i></a></li> + </ul> + </div> + </nav> + +</header> +<main> + <table class="table table-hover"> + <thead> + <tr> + <th>№ п/п</th> + <th>Имя</th> + <th>Фамилия</th> + <th>E-mail</th> + + </tr> + </thead> + <table class="table table-hover"> + <thead> + <tr> + <th>№ п/п</th> + <th>Имя</th> + <th>Фамилия</th> + <th>E-mail</th> + + </tr> + </thead> + <tbody> + <tr onclick="window.location.href='edit/1'; return false"> + <td>1</td> + <td>Иван</td> + <td>Чмель</td> + <td>ivan@mail.ru</td> + </tr> + <tr> + <td>2</td> + <td>Петр</td> + <td>Щербаков</td> + <td>petr@mail.ru</td> + </tr> + <tr> + <td>3</td> + <td>Юрий</td> + <td>Голов</td> + <td>yuri@mail.ru</td> + </tr> + </tbody> +</table> + </main> + <!--Футер--> + <footer> + <p >info by IT Kursk</p> + </footer> +</div> + <!-- jQuery (necessary for Bootstrap's JavaScript plugins) --> + <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> + <!-- Include all compiled plugins (below), or include individual files as needed --> + <script src="js/bootstrap.js"></script> + </body> +</html> \ No newline at end of file diff --git a/views/default/printers.html b/views/default/printers.html new file mode 100644 index 0000000..1283a16 --- /dev/null +++ b/views/default/printers.html @@ -0,0 +1,194 @@ +<!DOCTYPE html> +<html lang="ru"> + <head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <title>Home</title> + + <!-- Bootstrap --> + <link href="css/bootstrap.css" rel="stylesheet"> + <link rel="stylesheet" href="css/font-awesome.css"> + <link href="css/bootstrap-responsive.css" rel="stylesheet"> + <link href="css/footer.css" rel="stylesheet"> + <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries --> + <!-- WARNING: Respond.js doesn't work if you view the page via file:// --> + <!--[if lt IE 9]> + <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> + <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script> + <![endif]--> + </head> + <body> + <div class="container"> + <header> + <nav role="navigation" class="navbar navbar-default"> + <!-- Brand and toggle get grouped for better mobile display --> + <div class="navbar-header"> + <button type="button" data-target="#navbarCollapse" data-toggle="collapse" class="navbar-toggle"> + <span class="sr-only">Toggle navigation</span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + <a href="#" class="navbar-brand">Бренд</a> + </div> + <!-- Collection of nav links, forms, and other content for toggling --> + <div id="navbarCollapse" class="collapse navbar-collapse"> + <ul class="nav navbar-nav"> + <li class="active"><a href="#">Главная</a></li> + <li class="dropdown"> + <a data-toggle="dropdown" class="dropdown-toggle" href="#"><i class="fa fa-paint-brush" aria-hidden="true"></i> Cartriges <b class="caret"></b></a> + <ul role="menu" class="dropdown-menu"> + <li><a href="#">add</a></li> + <li><a href="#">Remove</a></li> + <li><a href="#">order</a></li> + <li><a href="#">hestory</a></li> + </ul> + </li> + <li class="dropdown"> + <a data-toggle="dropdown" class="dropdown-toggle" href="#"><i class="fa fa-print" aria-hidden="true"></i> Prints <b class="caret"></b></a> + <ul role="menu" class="dropdown-menu"> + <li><a href="#">search</a></li> + <li><a href="#">add</a></li> + <li><a href="#">edit</a></li> + <li class="divider"></li> + <li><a href="#">delete</a></li> + </ul> + </li> + <li class="dropdown"> + <a data-toggle="dropdown" class="dropdown-toggle" href="#"><i class="fa fa-wrench" aria-hidden="true"></i> Unit <b class="caret"></b></a> + <ul role="menu" class="dropdown-menu"> + <li><a href="#">history requests</a></li> + <li><a href="#">history repairs</a></li> + <li><a href="#">create requests</a></li> + <li class="divider"></li> + <li><a href="#">doc stor</a></li> + </ul> + </li> + </ul> + <ul class="nav navbar-nav navbar-right"> + <li><a href="#"><i class="fa fa-lock" aria-hidden="true"></i> Войти / <i class="fa fa-sign-out" aria-hidden="true"></i></a></li> + </ul> + </div> + </nav> + +</header> +<main> + <form action=""> + <div class="row"> + <div class="col-xs-3"> + <input type="text" class="form-control" name="name" placeholder="Name print"> + </div> + <div class="col-xs-3"> + <select class="form-control input" name="floor"> + <option>Этаж 1</option> + <option>Этаж 2</option> + </select> + </div> + <div class="col-xs-3"> + <select class="form-control input" name="cartrige"> + <option>Картридж 1</option> + <option>Картридж 2</option> + </select> + </div> + </div> + <br> + <div class="row"> + <div class="col-xs-3"> + <input type="text" class="form-control" placeholder="# Unit" name="unit"> + </div> + <div class="col-xs-3"> + <select class="form-control input" name="department"> + <option value="1">Отдел 1</option> + <option value="2">Отдел 2</option> + </select> + </div> + <div class="col-xs-3"> + <select class="form-control input" name="status"> + <option value="1">Статус 1</option> + <option value="1">Статус 2</option> + </select> + </div> + <div class="col-xs-3"> + <button type="submit" class="btn btn-primary">Выбрать</button> + </div> + </div> + </form> + <hr> + <br> + <div class="row"> + <!-- 1 Изображение --> + <div class="col-sm-6 col-md-4"> + <div class="thumbnail"> + <img src="img/3030.jpg" alt="..."> + <div class="caption"> + <h3>Имя принтера</h3> + <p>Этаж <strong>1</strong></p> + <p>Отдел <strong>чвапвапыавпр</strong></p> + <p>Юнит <strong>0000-0000</strong></p> + <p>Картридж <strong>205</strong></p> + <p><a href="#" class="btn btn-primary" role="button">Button</a> <a href="#" class="btn btn-default" role="button">Button</a></p> + </div> + </div> + </div> + + <div class="col-sm-6 col-md-4"> + <div class="thumbnail"> + <img src="img/Samsung SCX_ds_4824FN.jpg" alt="..."> + <div class="caption"> + <h3>Заголовок...</h3> + <p>Контент...</p> + <p><a href="#" class="btn btn-primary" role="button">Button</a> <a href="#" class="btn btn-default" role="button">Button</a></p> + </div> + </div> + </div> + + <div class="col-sm-6 col-md-4"> + <div class="thumbnail"> + <img src="img/scx5637.jpeg" alt="..."> + <div class="caption"> + <h3>Заголовок...</h3> + <p>Контент...</p> + <p><a href="#" class="btn btn-primary" role="button">Button</a> <a href="#" class="btn btn-default" role="button">Button</a></p> + </div> + </div> + </div> + + <div class="col-sm-6 col-md-4"> + <div class="thumbnail"> + <img src="img/Samsung SCX_ds_4824FN.jpg" alt="..."> + <div class="caption"> + <h3>Заголовок...</h3> + <p>Контент...</p> + <p><a href="#" class="btn btn-primary" role="button">Button</a> <a href="#" class="btn btn-default" role="button">Button</a></p> + </div> + </div> + </div> + + <!--...--> + + <!-- 12 Изображение --> + <div class="col-sm-6 col-md-4"> + <div class="thumbnail"> + <img src="img/print.png" alt="..."> + <div class="caption"> + <h3>Заголовок...</h3> + <p>Контент...</p> + <p><a href="#" class="btn btn-primary" role="button">Button</a> <a href="#" class="btn btn-default" role="button">Button</a></p> + </div> + </div> + </div> + + </div> + </main> + <!--Футер--> + <footer> + <p >info by IT Kursk</p> + </footer> +</div> + <!-- jQuery (necessary for Bootstrap's JavaScript plugins) --> + <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> + <!-- Include all compiled plugins (below), or include individual files as needed --> + <script src="js/bootstrap.js"></script> + </body> +</html> \ No newline at end of file diff --git a/views/default/printers.php b/views/default/printers.php new file mode 100644 index 0000000..7cc00b9 --- /dev/null +++ b/views/default/printers.php @@ -0,0 +1,90 @@ +<?php include ROOT . TMPL . 'header.php'; ?> + <form action="" method="post"> + <div class="row"> + <div class="col-xs-3"> + <input type="text" class="form-control" name="name" placeholder="Name print" <?php if(isset($_POST['name'])) echo "value='".$_POST['name']."'"; ?>> + </div> + <div class="col-xs-3"> + <select class="form-control input" name="floor"> + <option value="" selected>Выберите этаж </option> + <?php foreach($floor as $fl): ?> + <option value="<?php echo $fl['id']; ?>" <?php if(isset($_POST['floor']) && $_POST['floor'] == $fl['id']) echo "selected"; ?>><?php echo $fl['name']; ?></option> + <?php endforeach; ?> + </select> + </div> + <div class="col-xs-3"> + <select class="form-control input" name="cartrige"> + <option value="" selected>Выберите Картридж</option> + <?php foreach($cartrige as $ct): ?> + <option value="<?php echo $ct['id']; ?>" <?php if(isset($_POST['cartrige']) && $_POST['cartrige'] == $ct['id']) echo "selected"; ?>><?php echo $ct['name']; ?></option> + <?php endforeach; ?> + </select> + </div> + </div> + <br> + <div class="row"> + <div class="col-xs-3"> + <input type="text" class="form-control" name="unit" placeholder="Number Unit" <?php if(isset($_POST['unit'])) echo "value='".$_POST['unit']."'"; ?>> + </div> + <div class="col-xs-3"> + <select class="form-control input" name="department"> + <option value="" selected>Выберите Отдел</option> + <?php foreach($department as $dp): ?> + <option value="<?php echo $dp['id']; ?>" <?php if(isset($_POST['department']) && $_POST['department'] == $dp['id']) echo "selected"; ?>><?php echo $dp['name']; ?></option> + <?php endforeach; ?> + </select> + </div> + <div class="col-xs-3"> + <select class="form-control input" name="status"> + <option value="" selected>Выберите Статус</option> + <?php foreach($status as $st): ?> + <option value="<?php echo $st['id']; ?>" <?php if(isset($_POST['status']) && $_POST['status'] == $st['id']) echo "selected"; ?>><?php echo $st['name']; ?></option> + <?php endforeach; ?> + </select> + </div> + <div class="col-xs-3"> + <button type="submit" name="submit" class="btn btn-primary">Выбрать</button> + </div> + </div> + </form> + <hr> + <br> + <p>Всего принтеров в работе: <?php echo count($printList); ?> шт.</p> + <div class="row"> + <!-- 1 Изображение --> + <?php if($printList == 0) : ?> + + <div class="panel panel-warning"> + <div class="panel-heading"> + <h3 class="panel-title">Warning!!!</h3> + </div> + <div class="panel-body text-center"> + <h3>Принтеров с введенными параментрами не найдено, извините </h3> + </div> + </div> + <?php else : ?> + <?php foreach ($printList as $print): ?> + <div class="col-sm-6 col-md-4"> + <div class="thumbnail"> + <?php if($print['img'] != ""): ?> + <img src="<?php echo $print['img']; ?>" alt="..."> + <?php else: ?> + <img src="img/not_img_print.png" alt="..."> + <?php endif; ?> + <div class="caption"> + <h3><?php echo $print['name']; ?></h3> + <p>Расположение <strong><?php echo $print['id_floor']; ?></strong></p> + <p>Отдел <strong><?php echo $print['id_department']; ?></strong></p> + <p>Юнит <strong><?php echo $print['unit']; ?></strong></p> + <p>Модель <strong><?php echo $print['model']; ?></strong></p> + <p><a href="/printer/<?php echo $print['id']; ?>" class="btn btn-primary" role="button">Подробнее</a> + <?php if(user::checkAdmin() == true): ?> + <a href="/printer/edit/<?php echo $print['id']; ?>" class="btn btn-default" role="button">Редактировать</a></p> + <?php endif; ?> + </div> + </div> + </div> + <?php endforeach; ?> + <?php endif; ?> + </div> +<?php include ROOT . TMPL . 'footer.php'; ?> \ No newline at end of file diff --git a/views/default/radio.php b/views/default/radio.php new file mode 100644 index 0000000..b80d0b6 --- /dev/null +++ b/views/default/radio.php @@ -0,0 +1,76 @@ +<?php include ROOT . TMPL . 'header.php'; ?> +<style> + #player4 { + //max-width: 35rem; + margin-left: auto; + margin-right: auto; + margin-bottom: 50px; +} + </style> +<div class="container col-xs-5"> + <div id="player4" class="aplayer"></div> +</div> +<div class="col-xs-offset-1 col-xs-5"> + + <div id="display"> + <table class="table"> + <tr> + <th>Название</th> + <th> Слушать </td> + <th>Слушателей<br>сейчас</th> + <th>Композиция</th> + </tr> + <?php foreach($statistic as $stat): ?> + <tr> + <td><?php echo $stat['stream']; ?></td> + <td><a target=_blanc href='http://dsk7681:8000<?php echo $stat['stream']; ?>m3u'><img border='0' width='24' src='http://dsk7681/frame/images/radio1.gif'></a></td> + <td><?php echo $stat['quantity_listens']; ?></td> + <td><?php echo $stat['title']; ?></td> + </tr> + <?php endforeach; ?> + </table> + </div> + + + </br> + <script> + function mode() + { + // Очищаем нужный элемент страницы + $.ajax({ + url: "http://<?php echo DOMEN ?>/radio/statistics/", + cache: false, + success: function(data) + { + $('#display').html(data); + } + }); + } + + var timeInterval = 5000; + setInterval(mode, timeInterval); + </script> +</di> +<script src="<?php echo LIB; ?>/player/APlayer.min.js"></script> +<script> + var ap4 = new APlayer({ + element: document.getElementById('player4'), + narrow: false, + autoplay: false, + showlrc: false, + theme: '#ad7a86', + music: [ + <?php foreach($radioList as $list): ?> + { + title: '<?php echo substr($list[0],1); ?>', + author: "<?php echo $list[3]; ?>", + url: "http://dsk7681:8000<?php echo $list[0]; ?>", + pic: 'http://dsk7681/player/img/<?php echo $list[0]; ?>.jpg' + }, + <?php endforeach; ?> + ] + }); + ap4.init(); +</script> + +<?php include ROOT . TMPL . 'footer.php'; ?> diff --git a/views/default/requests.php b/views/default/requests.php new file mode 100644 index 0000000..159baa8 --- /dev/null +++ b/views/default/requests.php @@ -0,0 +1,129 @@ +<?php include ROOT . TMPL . 'header.php'; ?> +<div class="panel-group" id="accordion"> +<table class="table"> + <thead> + <tr> + <th>id</th> + <th>дата создания</th> + <th>Имя пользователя</th> + <th>Имя принтера</th> + <th>номер UNIT</th> + <th>Статус</th> + <th>Дата закрытия</th> + <th>История...</th> + <th>Добавить</th> + </tr> + </thead> + <tbody> + + + <!-- 1 панель --> + +<?php foreach($requests as $request): ?> + +<tr> + <th scope="row"><?php echo $request['id']; ?></th> + <td><?php echo Date::changeLocaleDate(date("d F Y", $request['date_create'])); ?></td> + <td><?php echo $request['user']; ?></td> + <td><?php echo $request['printname']; ?></td> + <td><?php echo $request['unit']; ?></td> + <td><?php echo $request['status']; ?></td> + <td><?php echo Date::changeLocaleDate(date("d F Y", $request['date_close'])); ?></td> + + <td> + + <!-- Заголовок 1 панели --> + <div class="panel-heading"> + <h4 class="panel-title"> + <a data-toggle="collapse" data-parent="#accordion" href="#collapse<?php echo $request['id']; ?>">Посмотреть</a> + </h4> + </div> + </td> + <td> <a href="/unit/actionrequest/<?php echo $request['id']; ?>">+</a></td> +</tr> + <tr> + <td colspan="8"> + <div id="collapse<?php echo $request['id']; ?>" class="panel-collapse collapse"> + <!-- Содержимое 1 панели --> + <div class="panel-body"> + + <?php if($request['actions'] === NULL): ?> + <h5> Для заявки № <?php echo $request['id']; ?> истории нет</h5> + <?php else: ?> + <ul class="timeline"> + + + <!---["actions"]=> + array(1) { + [0]=> + array(7) { + ["id"]=> + string(1) "1" + ["request_id"]=> + string(2) "15" + ["action"]=> + string(31) "Создание запроса" + ["description"]=> + string(165) "fdsgs agsfdgsf gfg sfdgfdsgsfdgfds gfsjgfmgmfdsg gffgfg gmfmgfmg ,gffgfllfg. jgfdfjgjfdgj fgfg sfgfg/dsfgsdfgfsg fdsg/fsgsfd dsfg/fgsfdgl flkgflkgfgf.gfflgkfgdslfg " + ["date"]=> + string(10) "1508340265" + ["user"]=> + string(12) "azashchepkin" + ["doc_link"]=> + NULL + } ---> + <?php foreach($request['actions'] as $actions): ?> + <li><!---Time Line Element---> + + <!---<i class="fa fa-envelope-o" aria-hidden="true"> создание запроса + <i class="fa fa-envelope-open-o" aria-hidden="true"></i> подтверждение от юнита + <i class="fa fa-handshake-o" aria-hidden="true"></i> визит инжененра + <i class="fa fa-floppy-o" aria-hidden="true"></i> закрытине запроса + <i class="fa fa-thumbs-up"></i> + ---> + <div class="timeline-badge up"> + <?php if($actions['action_id'] == 1): ?> + <i class="fa fa-envelope-o" aria-hidden="true"></i> + <?php elseif($actions['action_id'] == 2): ?> + <i class="fa fa-envelope-open-o" aria-hidden="true"></i> + <?php elseif($actions['action_id'] == 3): ?> + <i class="fa fa-handshake-o" aria-hidden="true"></i> + <?php elseif($actions['action_id'] == 4): ?> + <i class="fa fa-floppy-o" aria-hidden="true"></i> + <?php else: ?> + <i class="fa fa-thumbs-up"></i> + <?php endif; ?> + </div> + <div class="timeline-panel"> + <div class="timeline-heading"> + <h4 class="timeline-title"><p><?php echo $actions['actname'] ?></p> + <small><strong>Дата:</strong> <em><?php echo date("d-m-Y", $actions['date']) ?></em></small> <small><strong>Пользователь:</strong> <em><?php echo $actions['user'] ?></em></small> </h4> + </div> + <div class="timeline-body"><!---Time Line Body&Content---> + <p><?php echo $actions['description'] ?></p> + </div> + </div> + </li> + <?php endforeach; ?> + </ul> + <?php endif; ?> + </div> + </div> + + </td> + + </tr> + + + + + +<?php endforeach; ?> +</tbody> +</table> + </div> + + +<?php echo $pagination->get(); ?> + +<?php include ROOT . TMPL . 'footer.php'; ?> \ No newline at end of file